Распределения: Бернулли, биномиальное, нормальное
Распределение — это «закон», по которому случайная величина раздаёт свои вероятности; три из них встречаются в ML на каждом шагу.
Распределение вероятностей описывает, с какой вероятностью случайная величина принимает каждое из возможных значений.
Бернулли: один бросок с двумя исходами
Самое простое распределение. Бернулли — один эксперимент с двумя исходами: успех (1) с вероятностью p или неудача (0) с вероятностью 1−p. Подбрасывание монеты, «кликнул/не кликнул», «спам/не спам». Матожидание равно p, дисперсия — p·(1−p) (максимальна при p = 0.5 — наибольшая неопределённость).
# Бернулли: E[X] = p, Var[X] = p(1-p)
for p in [0.1, 0.5, 0.9]:
E = p
Var = p * (1 - p)
print(f"p={p}: E[X]={E}, Var[X]={round(Var, 4)}")
Вывод:
p=0.1: E[X]=0.1, Var[X]=0.09 p=0.5: E[X]=0.5, Var[X]=0.25 p=0.9: E[X]=0.9, Var[X]=0.09
Биномиальное: сколько успехов в n попытках
Биномиальное распределение считает число успехов в n независимых испытаниях Бернулли. «Сколько орлов в 10 бросках?», «сколько кликов из 1000 показов?». Вероятность ровно k успехов: C(n,k)·p^k·(1−p)^(n−k), где C(n,k) — число сочетаний. Посчитаем распределение для 10 бросков честной монеты.
from math import comb
def binom_pmf(k, n, p):
return comb(n, k) * p**k * (1 - p)**(n - k)
n, p = 10, 0.5
print("Число орлов в 10 бросках:")
for k in range(n + 1):
bar = "#" * round(binom_pmf(k, n, p) * 100)
print(f"k={k:2}: P={round(binom_pmf(k, n, p), 4):6} {bar}")
print("Сумма всех вероятностей =", round(sum(binom_pmf(k, n, p) for k in range(n+1)), 4))
Вывод:
Число орлов в 10 бросках: k= 0: P= 0.001 k= 1: P=0.0098 # k= 2: P=0.0439 #### k= 3: P=0.1172 ############ k= 4: P=0.2051 ##################### k= 5: P=0.2461 ######################### k= 6: P=0.2051 ##################### k= 7: P=0.1172 ############ k= 8: P=0.0439 #### k= 9: P=0.0098 # k=10: P= 0.001 Сумма всех вероятностей = 1.0
Получился симметричный «колокол» с пиком на 5 — самом ожидаемом числе орлов. Это не случайно: при росте n биномиальное распределение становится всё больше похоже на нормальное.
Нормальное: колокол, который везде
Нормальное (гауссово) распределение — знаменитый симметричный колокол. Им описывают рост, ошибки измерений, шум. Оно задаётся двумя параметрами: матожиданием μ (центр) и стандартным отклонением σ (ширина). Главное свойство — правило 68–95–99.7: в пределах одного σ от центра лежит ~68% значений, двух σ — ~95%, трёх σ — ~99.7%.
import math
def normal_pdf(x, mu=0, sigma=1):
coef = 1 / (sigma * math.sqrt(2 * math.pi))
return coef * math.exp(-0.5 * ((x - mu) / sigma) ** 2)
# Плотность стандартного нормального N(0,1)
for x in [-2, -1, 0, 1, 2]:
print(f"x={x:2}: плотность = {round(normal_pdf(x), 4)}")
# Симуляция: доля значений в пределах 1 сигмы
import random
random.seed(3)
sample = [random.gauss(0, 1) for _ in range(100000)]
within_1 = sum(1 for v in sample if -1 < v < 1) / len(sample)
print("Доля в пределах 1 сигмы =", round(within_1, 4), "(ожидаем ~0.68)")
Вывод:
x=-2: плотность = 0.054 x=-1: плотность = 0.242 x= 0: плотность = 0.3989 x= 1: плотность = 0.242 x= 2: плотность = 0.054 Доля в пределах 1 сигмы = 0.6815 (ожидаем ~0.68)
Сравнение
| Распределение | Что описывает | Пример в ML |
| Бернулли | один да/нет исход | бинарная метка (спам/не спам) |
| Биномиальное | число успехов в n попытках | число кликов из n показов |
| Нормальное | непрерывный колокол | шум, инициализация весов, признаки |
Итог
- Бернулли — один бросок с двумя исходами: E = p, Var = p(1−p).
- Биномиальное — число успехов в n испытаниях Бернулли; вероятность через сочетания C(n,k).
- Нормальное — колокол с центром μ и шириной σ; правило 68–95–99.7.
- Все три — рабочие лошадки ML: от бинарных меток до шума и инициализации весов.