Как посчитать Confidence Interval в SQL

Закрепи формулу confidence interval в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать confidence interval в Telegram

Зачем Confidence Interval

«AOV в апреле — $50». Точечная оценка. Confidence Interval добавляет: «$50 ± $3» (95% CI). Это говорит: «истинный AOV скорее всего между $47 и $53». Без CI цифры — гадание.

Формула

CI = mean ± z × SE
SE = std / sqrt(n)

Для 95% CI: z = 1.96.

Для proportion:

CI = p ± z × sqrt(p(1-p) / n)

CI для means

WITH stats AS (
    SELECT
        AVG(total) AS mean_aov,
        STDDEV(total) AS std,
        COUNT(*) AS n
    FROM orders
    WHERE status = 'paid'
      AND created_at >= CURRENT_DATE - INTERVAL '30 days'
)
SELECT
    mean_aov,
    std,
    n,
    mean_aov - 1.96 * std / SQRT(n) AS ci_lower,
    mean_aov + 1.96 * std / SQRT(n) AS ci_upper,
    1.96 * std / SQRT(n) AS ci_radius
FROM stats;

CI для proportions

Для CR / conversion rate:

WITH stats AS (
    SELECT
        COUNT(*) AS n,
        COUNT(*) FILTER (WHERE event = 'purchase') AS conversions,
        COUNT(*) FILTER (WHERE event = 'purchase')::NUMERIC / NULLIF(COUNT(*), 0) AS p
    FROM funnel_events
    WHERE event_date >= CURRENT_DATE - INTERVAL '30 days'
)
SELECT
    p,
    n,
    p - 1.96 * SQRT(p * (1 - p) / n) AS ci_lower,
    p + 1.96 * SQRT(p * (1 - p) / n) AS ci_upper,
    1.96 * SQRT(p * (1 - p) / n) AS ci_radius
FROM stats;

Wilson CI лучше для маленьких samples / extreme p:

WITH stats AS (
    SELECT
        COUNT(*) AS n,
        COUNT(*) FILTER (WHERE event = 'purchase') AS k
    FROM funnel_events
    WHERE event_date >= CURRENT_DATE - INTERVAL '30 days'
)
SELECT
    k::NUMERIC / n AS p,
    (k + 1.96 * 1.96 / 2) / (n + 1.96 * 1.96)
        - 1.96 * SQRT((k::NUMERIC * (n - k) / n + 1.96 * 1.96 / 4) / (n + 1.96 * 1.96)) / (n + 1.96 * 1.96)
        AS wilson_lower,
    (k + 1.96 * 1.96 / 2) / (n + 1.96 * 1.96)
        + 1.96 * SQRT((k::NUMERIC * (n - k) / n + 1.96 * 1.96 / 4) / (n + 1.96 * 1.96)) / (n + 1.96 * 1.96)
        AS wilson_upper
FROM stats;
Закрепи формулу confidence interval в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать confidence interval в Telegram

Bootstrap альтернатива

Bootstrap не требует normality assumption. Создаём samples с repetition:

WITH samples AS (
    SELECT
        b AS bootstrap_id,
        AVG(total) AS resampled_mean
    FROM (
        SELECT total
        FROM orders
        WHERE status = 'paid'
          AND created_at >= CURRENT_DATE - INTERVAL '30 days'
    ) data
    CROSS JOIN generate_series(1, 1000) AS b
    -- SQL bootstrap упрощённо; в проде используйте Python/R
)
SELECT
    PERCENTILE_CONT(0.025) WITHIN GROUP (ORDER BY resampled_mean) AS ci_lower,
    PERCENTILE_CONT(0.975) WITHIN GROUP (ORDER BY resampled_mean) AS ci_upper
FROM samples
GROUP BY 1;

В SQL bootstrap сложно (no random with replacement). Чаще делают вне SQL.

Частые ошибки

Ошибка 1. Использовать normal CI на skewed data. Revenue per user имеет heavy tail. Normal CI не работает. Используйте bootstrap.

Ошибка 2. CI для small n. Если n < 30, лучше t-distribution (но в проде обычно используют normal с n ≥ 30).

Ошибка 3. Confidence vs Credible Interval. CI — frequentist. Credible — bayesian. Не путайте.

Ошибка 4. Игнорировать correlations. Если data correlated (time series), CI underestimates uncertainty.

Ошибка 5. CI для difference of means. SE формула другая: sqrt(SE1² + SE2²). Не просто CI каждой группы.

Связанные темы

FAQ

90% или 95% CI?

95% — стандарт. 90% — narrower (less confident). 99% — wider (more confident).

Что значит «95% CI»?

«Если повторим эксперимент 100 раз, в 95 случаях истинное значение окажется в этом интервале». НЕ «95% вероятность, что значение в интервале» (это credible interval).

CI не пересекаются — significant?

Грубо да, но точнее — z-test / t-test.

CI для медианы?

PERCENTILE_CONT 2.5% и 97.5% от bootstrap distribution.

CI narrow или wide — что лучше?

Narrow = больше certainty. Зависит от n и std: больше n → narrower CI.