Биномиальное распределение — просто о статистике

Коротко

Биномиальное распределение описывает количество «успехов» в серии независимых опытов с двумя исходами (да/нет, купил/не купил, кликнул/не кликнул). Два параметра: n (число опытов) и p (вероятность успеха). Аналитику биномиальное распределение нужно для моделирования конверсий, A/B-тестов, CTR и любых бинарных метрик. На собеседованиях спрашивают формулу, связь с нормальным распределением и применение.

Когда возникает

Биномиальное распределение применимо, когда:

  1. Фиксированное число опытов n
  2. Два исхода — успех (p) или неудача (1-p)
  3. Независимые опыты — результат одного не влияет на другие
  4. Одинаковая вероятность p в каждом опыте

Примеры:

  • 1000 посетителей сайта, конверсия 5% → сколько купят?
  • 500 отправленных email, open rate 20% → сколько откроют?
  • 50 вопросов на собеседовании, вероятность правильного ответа 70% → сколько правильных?

Параметры и формула

X ~ Binomial(n, p) — случайная величина X подчиняется биномиальному распределению с параметрами:

  • n — число опытов (trials)
  • p — вероятность успеха в одном опыте

Формула:

P(X = k) = C(n, k) × p^k × (1-p)^(n-k)

Где C(n, k) = n! / (k! × (n-k)!) — число сочетаний.

Среднее: μ = n × p Дисперсия: σ² = n × p × (1-p) Стандартное отклонение: σ = √(n × p × (1-p))

# Пример: 1000 посетителей, конверсия 5%
n, p = 1000, 0.05

mean = n * p                        # 50 покупок в среднем
std = (n * p * (1 - p)) ** 0.5      # ≈ 6.9
print(f'Ожидаемых покупок: {mean} ± {std:.1f}')
# Ожидаемых покупок: 50.0 ± 6.9

Расчёт в Python

scipy.stats

from scipy import stats

# X ~ Binomial(n=100, p=0.3)
binom = stats.binom(n=100, p=0.3)

# Вероятность ровно 30 успехов
binom.pmf(30)              # 0.0868 (8.7%)

# Вероятность ≤ 25 успехов
binom.cdf(25)              # 0.1631 (16.3%)

# Вероятность > 35 успехов
1 - binom.cdf(35)          # 0.0991 (9.9%)

# Среднее и дисперсия
binom.mean()               # 30.0
binom.var()                # 21.0
binom.std()                # 4.58

# Квантиль: при каком k вероятность ≤ 5%?
binom.ppf(0.05)            # 22.0

NumPy — генерация случайных данных

import numpy as np

# Симуляция: 1000 дней, каждый день 500 посетителей, конверсия 3%
daily_purchases = np.random.binomial(n=500, p=0.03, size=1000)
print(f'Среднее покупок/день: {daily_purchases.mean():.1f}')
print(f'Стандартное отклонение: {daily_purchases.std():.1f}')

Примеры задач

Задача 1: Конверсия сайта

На сайт пришли 200 посетителей. Конверсия — 10%. Какова вероятность, что купят ровно 25 человек?

from scipy import stats

p = stats.binom.pmf(25, n=200, p=0.10)
print(f'P(X = 25) = {p:.4f}')  # 0.0446 (4.5%)

А вероятность, что купят 15 или меньше?

p = stats.binom.cdf(15, n=200, p=0.10)
print(f'P(X ≤ 15) = {p:.4f}')  # 0.1049 (10.5%)

Задача 2: A/B-тест

Контрольная группа: 1000 пользователей, 50 конверсий (5%). Тестовая: 1000 пользователей, 65 конверсий (6.5%). Могли ли мы получить 65 конверсий случайно при истинной конверсии 5%?

from scipy import stats

# Вероятность 65+ конверсий при p=0.05
p_value = 1 - stats.binom.cdf(64, n=1000, p=0.05)
print(f'p-value = {p_value:.4f}')  # 0.0156

# p-value < 0.05 → различие статистически значимо

Подробнее о p-value и A/B-тестировании.

Задача 3: Контроль качества

Из партии в 50 товаров 5% бракованных. Какова вероятность найти 0 бракованных?

p = stats.binom.pmf(0, n=50, p=0.05)
print(f'P(0 бракованных) = {p:.4f}')  # 0.0769 (7.7%)

Связь с другими распределениями

Биномиальное → нормальное

При большом n биномиальное распределение приближается к нормальному (ЦПТ):

Если n × p ≥ 5 и n × (1-p) ≥ 5, можно аппроксимировать:

X ~ N(μ = np, σ² = np(1-p))

from scipy import stats

# Биномиальное: n=1000, p=0.3
binom = stats.binom(n=1000, p=0.3)

# Нормальное приближение
normal = stats.norm(loc=300, scale=(1000 * 0.3 * 0.7) ** 0.5)

# P(X ≤ 280)
print(binom.cdf(280))    # 0.0887
print(normal.cdf(280))   # 0.0852 — близко!

Именно поэтому для A/B-тестов с большой выборкой используют z-тест (нормальное приближение), а не точный биномиальный тест.

Биномиальное → Пуассоново

При большом n и маленьком p биномиальное приближается к распределению Пуассона с λ = np:

# n=10000, p=0.0005 (редкое событие)
binom = stats.binom(n=10000, p=0.0005)
poisson = stats.poisson(mu=5)  # λ = np = 5

# P(X = 3)
print(binom.pmf(3))     # 0.1403
print(poisson.pmf(3))   # 0.1404 — почти идентично

Визуализация

import matplotlib.pyplot as plt
from scipy import stats
import numpy as np

n, p = 50, 0.3
x = np.arange(0, n + 1)

plt.bar(x, stats.binom.pmf(x, n, p), color='steelblue', alpha=0.7)
plt.xlabel('Число успехов')
plt.ylabel('Вероятность')
plt.title(f'Биномиальное распределение (n={n}, p={p})')
plt.axvline(x=n*p, color='red', linestyle='--', label=f'μ = {n*p}')
plt.legend()
plt.show()

Типичные ошибки

Путают с геометрическим распределением. Биномиальное — «сколько успехов в n опытах». Геометрическое — «через сколько опытов первый успех».

Применяют при зависимых опытах. Если клик на рекламу зависит от предыдущего клика (например, ретаргетинг), биномиальное распределение некорректно.

Забывают про приближение к нормальному. При n > 30 и np > 5 проще считать через нормальное приближение, чем через точную биномиальную формулу.

Вопросы с собеседований

-- Что такое биномиальное распределение? -- Распределение числа успехов в n независимых опытах с вероятностью успеха p. Параметры: n и p. Среднее = np, дисперсия = np(1-p).

-- Когда биномиальное приближается к нормальному? -- При np ≥ 5 и n(1-p) ≥ 5. Это следствие ЦПТ. Практически — при n > 30.

-- Конверсия сайта 3%. 1000 посетителей. Какова вероятность менее 20 покупок? -- P(X < 20) = P(X ≤ 19) = binom.cdf(19, 1000, 0.03) ≈ 0.048. Около 5% — необычно мало, стоит проверить, не упала ли конверсия.

-- Почему для A/B-тестов конверсии используют z-тест, а не биномиальный? -- При больших выборках (np ≥ 5) биномиальное приближается к нормальному. Z-тест вычислительно проще и даёт тот же результат. Для малых выборок — точный тест Фишера или биномиальный тест.


Потренируйтесь решать задачи — откройте тренажёр с 1500+ вопросами для подготовки к собеседованиям аналитиков.

FAQ

Биномиальное vs распределение Бернулли?

Бернулли — частный случай биномиального при n=1. Один опыт с двумя исходами: 0 или 1. Биномиальное — сумма n независимых Бернулли.

Когда использовать биномиальный тест?

Для проверки, отличается ли наблюдаемая доля от ожидаемой. Например: «конверсия 7% при обещанных 5% — это значимо?» scipy.stats.binom_test(70, 1000, 0.05).

Биномиальное распределение в SQL?

В SQL нет встроенных функций для биномиального распределения. Считайте в Python и загружайте результат. Или используйте нормальное приближение.

Как тренироваться

Задачи на распределения и теорию вероятностей — в тренажёре Карьерник. Больше вопросов — в разделе с примерами.