{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/statistical-analysis",
  "version": "1.0.0",
  "name": "statistical-analysis",
  "description": "Apply statistical methods including descriptive stats, trend analysis, outlier detection, and hypothesis testing. Use when analyzing distributions, testing for significance, detecting anomalies, computing correlations, or interpreting statistical results.",
  "system_prompt_fragment": "# Statistical Analysis Skill\n\nDescriptive statistics, trend analysis, outlier detection, hypothesis testing, and guidance on when to be cautious about statistical claims.\n\n## Descriptive Statistics Methodology\n\n### Central Tendency\n\nChoose the right measure of center based on the data:\n\n| Situation | Use | Why |\n|---|---|---|\n| Symmetric distribution, no outliers | Mean | Most efficient estimator |\n| Skewed distribution | Median | Robust to outliers |\n| Categorical or ordinal data | Mode | Only option for non-numeric |\n| Highly skewed with outliers (e.g., revenue per user) | Median + mean | Report both; the gap shows skew |\n\n**Always report mean and median together for business metrics.** If they diverge significantly, the data is skewed and the mean alone is misleading.\n\n### Spread and Variability\n\n- **Standard deviation**: How far values typically fall from the mean. Use with normally distributed data.\n- **Interquartile range (IQR)**: Distance from p25 to p75. Robust to outliers. Use with skewed data.\n- **Coefficient of variation (CV)**: StdDev / Mean. Use to compare variability across metrics with different scales.\n- **Range**: Max minus min. Sensitive to outliers but gives a quick sense of data extent.\n\n### Percentiles for Business Context\n\nReport key percentiles to tell a richer story than mean alone:\n\n```\np1:   Bottom 1% (floor / minimum typical value)\np5:   Low end of normal range\np25:  First quartile\np50:  Median (typical user)\np75:  Third quartile\np90:  Top 10% / power users\np95:  High end of normal range\np99:  Top 1% / extreme users\n```\n\n**Example narrative**: \"The median session duration is 4.2 minutes, but the top 10% of users spend over 22 minutes per session, pulling the mean up to 7.8 minutes.\"\n\n### Describing Distributions\n\nCharacterize every numeric distribution you analyze:\n\n- **Shape**: Normal, right-skewed, left-skewed, bimodal, uniform, heavy-tailed\n- **Center**: Mean and median (and the gap between them)\n- **Spread**: Standard deviation or IQR\n- **Outliers**: How many and how extreme\n- **Bounds**: Is there a natural floor (zero) or ceiling (100%)?\n\n## Trend Analysis and Forecasting\n\n### Identifying Trends\n\n**Moving averages** to smooth noise:\n```python\n# 7-day moving average (good for daily data with weekly seasonality)\ndf['ma_7d'] = df['metric'].rolling(window=7, min_periods=1).mean()\n\n# 28-day moving average (smooths weekly AND monthly patterns)\ndf['ma_28d'] = df['metric'].rolling(window=28, min_periods=1).mean()\n```\n\n**Period-over-period comparison**:\n- Week-over-week (WoW): Compare to same day last week\n- Month-over-month (MoM): Compare to same month prior\n- Year-over-year (YoY): Gold standard for seasonal businesses\n- Same-day-last-year: Compare specific calendar day\n\n**Growth rates**:\n```\nSimple growth: (current - previous) / previous\nCAGR: (ending / beginning) ^ (1 / years) - 1\nLog growth: ln(current / previous)  -- better for volatile series\n```\n\n### Seasonality Detection\n\nCheck for periodic patterns:\n1. Plot the raw time series -- visual inspection first\n2. Compute day-of-week averages: is there a clear weekly pattern?\n3. Compute month-of-year averages: is there an annual cycle?\n4. When comparing periods, always use YoY or same-period comparisons to avoid conflating trend with seasonality\n\n### Forecasting (Simple Methods)\n\nFor business analysts (not data scientists), use straightforward methods:\n\n- **Naive forecast**: Tomorrow = today. Use as a baseline.\n- **Seasonal naive**: Tomorrow = same day last week/year.\n- **Linear trend**: Fit a line to historical data. Only for clearly linear trends.\n- **Moving average forecast**: Use trailing average as the forecast.\n\n**Always communicate uncertainty**. Provide a range, not a point estimate:\n- \"We expect 10K-12K signups next month based on the 3-month trend\"\n- NOT \"We will get exactly 11,234 signups next month\"\n\n**When to escalate to a data scientist**: Non-linear trends, multiple seasonalities, external factors (marketing spend, holidays), or when forecast accuracy matters for resource allocation.\n\n## Outlier and Anomaly Detection\n\n### Statistical Methods\n\n**Z-score method** (for normally distributed data):\n```python\nz_scores = (df['value'] - df['value'].mean()) / df['value'].std()\noutliers = df[abs(z_scores) > 3]  # More than 3 standard deviations\n```\n\n**IQR method** (robust to non-normal distributions):\n```python\nQ1 = df['value'].quantile(0.25)\nQ3 = df['value'].quantile(0.75)\nIQR = Q3 - Q1\nlower_bound = Q1 - 1.5 * IQR\nupper_bound = Q3 + 1.5 * IQR\noutliers = df[(df['value'] < lower_bound) | (df['value'] > upper_bound)]\n```\n\n**Percentile method** (simplest):\n```python\noutliers = df[(df['value'] < df['value'].quantile(0.01)) |\n              (df['value'] > df['value'].quantile(0.99))]\n```\n\n### Handling Outliers\n\nDo NOT automatically remove outliers. Instead:\n\n1. **Investigate**: Is this a data error, a genuine extreme value, or a different population?\n2. **Data errors**: Fix or remove (e.g., negative ages, timestamps in year 1970)\n3. **Genuine extremes**: Keep them but consider using robust statistics (median instead of mean)\n4. **Different population**: Segment them out for separate analysis (e.g., enterprise vs. SMB customers)\n\n**Report what you did**: \"We excluded 47 records (0.3%) with transaction amounts >$50K, which represent bulk enterprise orders analyzed separately.\"\n\n### Time Series Anomaly Detection\n\nFor detecting unusual values in a time series:\n\n1. Compute expected value (moving average or same-period-last-year)\n2. Compute deviation from expected\n3. Flag deviations beyond a threshold (typically 2-3 standard deviations of the residuals)\n4. Distinguish between point anomalies (single unusual value) and change points (sustained shift)\n\n## Hypothesis Testing Basics\n\n### When to Use\n\nUse hypothesis testing when you need to determine whether an observed difference is likely real or could be due to random chance. Common scenarios:\n\n- A/B test results: Is variant B actually better than A?\n- Before/after comparison: Did the product change actually move the metric?\n- Segment comparison: Do enterprise customers really have higher retention?\n\n### The Framework\n\n1. **Null hypothesis (H0)**: There is no difference (the default assumption)\n2. **Alternative hypothesis (H1)**: There is a difference\n3. **Choose significance level (alpha)**: Typically 0.05 (5% chance of false positive)\n4. **Compute test statistic and p-value**\n5. **Interpret**: If p < alpha, reject H0 (evidence of a real difference)\n\n### Common Tests\n\n| Scenario | Test | When to Use |\n|---|---|---|\n| Compare two group means | t-test (independent) | Normal data, two groups |\n| Compare two group proportions | z-test for proportions | Conversion rates, binary outcomes |\n| Compare paired measurements | Paired t-test | Before/after on same entities |\n| Compare 3+ group means | ANOVA | Multiple segments or variants |\n| Non-normal data, two groups | Mann-Whitney U test | Skewed metrics, ordinal data |\n| Association between categories | Chi-squared test | Two categorical variables |\n\n### Practical Significance vs. Statistical Significance\n\n**Statistical significance** means the difference is unlikely due to chance.\n\n**Practical significance** means the difference is large enough to matter for business decisions.\n\nA difference can be statistically significant but practically meaningless (common with large samples). Always report:\n- **Effect size**: How big is the difference? (e.g., \"Variant B improved conversion by 0.3 percentage points\")\n- **Confidence interval**: What's the range of plausible true effects?\n- **Business impact**: What does this translate to in revenue, users, or other business terms?\n\n### Sample Size Considerations\n\n- Small samples produce unreliable results, even with significant p-values\n- Rule of thumb for proportions: Need at least 30 events per group for basic reliability\n- For detecting small effects (e.g., 1% conversion rate change), you may need thousands of observations per group\n- If your sample is small, say so: \"With only 200 observations per group, we have limited power to detect effects smaller than X%\"\n\n## When to Be Cautious About Statistical Claims\n\n### Correlation Is Not Causation\n\nWhen you find a correlation, explicitly consider:\n- **Reverse causation**: Maybe B causes A, not A causes B\n- **Confounding variables**: Maybe C causes both A and B\n- **Coincidence**: With enough variables, spurious correlations are inevitable\n\n**What you can say**: \"Users who use feature X have 30% higher retention\"\n**What you cannot say without more evidence**: \"Feature X causes 30% higher retention\"\n\n### Multiple Comparisons Problem\n\nWhen you test many hypotheses, some will be \"significant\" by chance:\n- Testing 20 metrics at p=0.05 means ~1 will be falsely significant\n- If you looked at many segments before finding one that's different, note that\n- Adjust for multiple comparisons with Bonferroni correction (divide alpha by number of tests) or report how many tests were run\n\n### Simpson's Paradox\n\nA trend in aggregated data can reverse when data is segmented:\n- Always check whether the conclusion holds across key segments\n- Example: Overall conversion goes up, but conversion goes down in every segment -- because the mix shifted toward a higher-converting segment\n\n### Survivorship Bias\n\nYou can only analyze entities that \"survived\" to be in your dataset:\n- Analyzing active users ignores those who churned\n- Analyzing successful companies ignores those that failed\n- Always ask: \"Who is missing from this dataset, and would their inclusion change the conclusion?\"\n\n### Ecological Fallacy\n\nAggregate trends may not apply to individuals:\n- \"Countries with higher X have higher Y\" does NOT mean \"individuals with higher X have higher Y\"\n- Be careful about applying group-level findings to individual cases\n\n### Anchoring on Specific Numbers\n\nBe wary of false precision:\n- \"Churn will be 4.73% next quarter\" implies more certainty than is warranted\n- Prefer ranges: \"We expect churn between 4-6% based on historical patterns\"\n- Round appropriately: \"About 5%\" is often more honest than \"4.73%\"",
  "applicable_domains": [
    "data",
    "analytics"
  ],
  "invocation": [
    "/statistical-analysis"
  ],
  "tags": [
    "data",
    "anthropics",
    "knowledge-work"
  ],
  "authored_by": "anthropics",
  "source_url": "https://github.com/anthropics/knowledge-work-plugins/blob/main/data/skills/statistical-analysis/SKILL.md",
  "lifecycle": "stable",
  "category": "data",
  "provenance": {
    "source": "anthropics/knowledge-work-plugins",
    "source_url": "https://github.com/anthropics/knowledge-work-plugins/blob/main/data/skills/statistical-analysis/SKILL.md",
    "author": "Anthropic",
    "license": "Apache-2.0",
    "notes": "Imported by scripts/import-anthropic-skills.py."
  }
}