[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GYCXVQCQAXZPBNHWVMZATA":3,"skill-same:01M6GYCXVQCQAXZPBNHWVMZATA":71},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":19,"publishedAt":29,"linkOnly":30,"markdownContent":31,"markdownBody":32,"frontMatter":33,"refName":34,"commitSha":35,"skillDirectory":36,"forksCount":37,"repositoryHtmlUrl":38,"repositoryHomepageUrl":6,"ownerHtmlUrl":39,"ownerBlogUrl":40,"ownerDescription":41,"updatedAt":42,"install":43,"resources":56},"01M6GYCXVQCQAXZPBNHWVMZATA","detect-simpsons-paradox-in-a-metric",null,"Use when an aggregate moves one way while its parts move the other. Checks for Simpson's paradox before trusting a pooled rate.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",81,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-detect-simpsons-paradox-in-a-metric\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-detect-simpsons-paradox-in-a-metric\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28],"detect","detect simpsons paradox in a metric","metric","use","move","for","rate","parts","when","2026-11-10 10:12:30",false,"---\nname: detect-simpsons-paradox-in-a-metric\ndescription: Use when an aggregate moves one way while its parts move the other. Checks for Simpson's paradox before trusting a pooled rate.\n---\n\n# Detect Simpson's Paradox in a Metric\n\nA pooled rate can fall while every subgroup rises, or rise while every subgroup falls, when the mix of groups changes. The aggregate is a weighted average and the weights are doing the talking.\n\n## Procedure\n\n1. Compute the metric pooled, then per strata for the obvious confounders: platform, channel, geography, account tier.\n2. Compare the two tables and look for a sign flip between pooled and per-stratum.\n3. Check whether the mix of strata changed between periods — that shift is the usual cause.\n4. Recompute by fixing the mix: standardise to a common weight vector and compare like for like:\n   ```python\n   grp = df.groupby(['segment','period'])['converted'].agg(['sum','count'])\n   rate = grp['sum']\u002Fgrp['count']\n   w = df[df.period=='prior'].groupby('segment').size(); w = w\u002Fw.sum()\n   print((rate.unstack('period') * w).sum())   # mix-adjusted rate per period\n   ```\n5. Report both the pooled and the mix-adjusted number, with the stratum breakdown, whenever they disagree.\n6. Take the unweighted mean of stratum rates only for diagnostics — never present it as the overall rate.\n\n## Pitfalls\n\n- A pooled ratio (sum over sum) is not the mean of ratios; averaging per-day rates distorts the total.\n- Mobile users quadrupling in share can drag a conversion rate down even as mobile and desktop both improve.\n- Small strata with extreme rates swing the unweighted mean; weight by volume.\n- Confounders are not only categorical — a continuous variable like account age can hide the same reversal.\n- Simpson's paradox is a warning about a lurking variable, not a licence to pick the subgroup with the nicer story.\n\n## Verification\n\n    python3 - \u003C\u003C'PY'\nimport pandas as pd\nd = pd.read_csv('conv.csv')\npooled = d.groupby('period').apply(lambda g: g['conv'].sum()\u002Fg['n'].sum())\nbyseg = d.groupby(['segment','period']).apply(lambda g: g['conv'].sum()\u002Fg['n'].sum()).unstack()\nprint(pooled.to_string()); print(byseg.to_string())\nPY\n\nReport: \"Pooled conversion fell 1.1pt while every segment rose; the mix shifted 60% toward low-converting mobile. Mix-adjusted change is +0.4pt — the fall was composition, not performance.\"\n","# Detect Simpson's Paradox in a Metric\n\nA pooled rate can fall while every subgroup rises, or rise while every subgroup falls, when the mix of groups changes. The aggregate is a weighted average and the weights are doing the talking.\n\n## Procedure\n\n1. Compute the metric pooled, then per strata for the obvious confounders: platform, channel, geography, account tier.\n2. Compare the two tables and look for a sign flip between pooled and per-stratum.\n3. Check whether the mix of strata changed between periods — that shift is the usual cause.\n4. Recompute by fixing the mix: standardise to a common weight vector and compare like for like:\n   ```python\n   grp = df.groupby(['segment','period'])['converted'].agg(['sum','count'])\n   rate = grp['sum']\u002Fgrp['count']\n   w = df[df.period=='prior'].groupby('segment').size(); w = w\u002Fw.sum()\n   print((rate.unstack('period') * w).sum())   # mix-adjusted rate per period\n   ```\n5. Report both the pooled and the mix-adjusted number, with the stratum breakdown, whenever they disagree.\n6. Take the unweighted mean of stratum rates only for diagnostics — never present it as the overall rate.\n\n## Pitfalls\n\n- A pooled ratio (sum over sum) is not the mean of ratios; averaging per-day rates distorts the total.\n- Mobile users quadrupling in share can drag a conversion rate down even as mobile and desktop both improve.\n- Small strata with extreme rates swing the unweighted mean; weight by volume.\n- Confounders are not only categorical — a continuous variable like account age can hide the same reversal.\n- Simpson's paradox is a warning about a lurking variable, not a licence to pick the subgroup with the nicer story.\n\n## Verification\n\n    python3 - \u003C\u003C'PY'\nimport pandas as pd\nd = pd.read_csv('conv.csv')\npooled = d.groupby('period').apply(lambda g: g['conv'].sum()\u002Fg['n'].sum())\nbyseg = d.groupby(['segment','period']).apply(lambda g: g['conv'].sum()\u002Fg['n'].sum()).unstack()\nprint(pooled.to_string()); print(byseg.to_string())\nPY\n\nReport: \"Pooled conversion fell 1.1pt while every segment rose; the mix shifted 60% toward low-converting mobile. Mix-adjusted change is +0.4pt — the fall was composition, not performance.\"\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-detect-simpsons-paradox-in-a-metric",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-12 02:28:42",{"source":8,"skillName":5,"commands":44,"prompt":54,"zipAvailable":55},[45,48,51],{"tool":46,"command":47},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill detect-simpsons-paradox-in-a-metric",{"tool":49,"command":50},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill detect-simpsons-paradox-in-a-metric",{"tool":52,"command":53},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill detect-simpsons-paradox-in-a-metric","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-detect-simpsons-paradox-in-a-metric\u002FSKILL.md",true,[57,61,67],{"path":58,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":60,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":62,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":65,"sourceHtmlUrl":66},"SOURCE.md","REFERENCE","参考文档",361,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-detect-simpsons-paradox-in-a-metric\u002FSOURCE.md",{"path":68,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":69,"sourceHtmlUrl":70},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-detect-simpsons-paradox-in-a-metric\u002FTRUST.auto.yaml",[72,100,122,140,153,163],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":76,"sourceHtmlUrl":77,"categories":78,"keywords":79,"publishedAt":29},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":101,"name":102,"nameZh":6,"description":103,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":105,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":29},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[109,110,111,112,113,114,115,116,117,118,25,119,120,121],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","api keys","maintenance","protobuf",{"skillNo":123,"name":124,"nameZh":6,"description":125,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":126,"sourceHtmlUrl":127,"categories":128,"keywords":129,"publishedAt":29},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[130,110,131,132,133,134,135,119,25,118,136,137,138,114,139,113,112],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":141,"name":142,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":144,"sourceHtmlUrl":145,"categories":146,"keywords":147,"publishedAt":29},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[148,149,111,150,151,120,25,152,117,116,114,113],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":154,"name":155,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":156,"sourceHtmlUrl":157,"categories":158,"keywords":159,"publishedAt":29},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[160,161,162],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":164,"name":165,"nameZh":6,"description":166,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":167,"sourceHtmlUrl":168,"categories":169,"keywords":170,"publishedAt":29},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[171,172,173,174,175,176,177,23,178,179,180],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]