Биномиальное распределение — просто о статистике
Коротко
Биномиальное распределение описывает количество «успехов» в серии независимых опытов с двумя исходами (да/нет, купил/не купил, кликнул/не кликнул). Два параметра: n (число опытов) и p (вероятность успеха). Аналитику биномиальное распределение нужно для моделирования конверсий, A/B-тестов, CTR и любых бинарных метрик. На собеседованиях спрашивают формулу, связь с нормальным распределением и применение.
Когда возникает
Биномиальное распределение применимо, когда:
- Фиксированное число опытов n
- Два исхода — успех (p) или неудача (1-p)
- Независимые опыты — результат одного не влияет на другие
- Одинаковая вероятность 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.0NumPy — генерация случайных данных
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 и загружайте результат. Или используйте нормальное приближение.
Как тренироваться
Задачи на распределения и теорию вероятностей — в тренажёре Карьерник. Больше вопросов — в разделе с примерами.