Гистограмма: сколько брать бинов

Число бинов — не косметика: им можно превратить одно распределение в совсем другое.

Гистограмма делит диапазон значений на интервалы (бины) и показывает, сколько наблюдений попало в каждый. Ширина бина — главный параметр: слишком широкие сглаживают структуру, слишком узкие добавляют шум.

Почему это важно

Гистограмма с 5 бинами и та же выборка с 50 бинами могут выглядеть как два разных распределения: на грубой исчезнет бимодальность, на слишком мелкой появятся ложные «зубцы» от случайных колебаний. Поэтому выбор числа бинов — это научное решение, а не настройка по умолчанию. Существуют формулы, которые дают разумную отправную точку.

Три правила выбора

ПравилоФормулаКогда
Корня$k = \lceil\sqrt{n}\rceil$ биновбыстрая прикидка
Стёрджеса$k = \lceil\log_2 n\rceil + 1$ биновмалые $n$, ~нормальные данные
Фридмана–Дайкониса$h = 2\,\dfrac{\text{IQR}}{n^{1/3}}$ (ширина бина)устойчиво к выбросам

Правило Стёрджеса предполагает близость к нормальному распределению и недооценивает число бинов для больших выборок. Правило Фридмана–Дайкониса задаёт ширину бина через межквартильный размах $\text{IQR}$ — оно устойчиво к выбросам, потому что IQR их игнорирует, и обычно даёт лучший результат на реальных данных.

Считаем число бинов сами

Реализуем все три правила на stdlib и применим к выборке.

import math, statistics as st

data = [4,5,5,6,6,6,7,7,7,7,8,8,8,9,9,10,11,12,5,6,7,8,7,6,5,9,8,7,6,7]
n = len(data)

# правило корня
k_sqrt = math.ceil(math.sqrt(n))
# правило Стёрджеса
k_sturges = math.ceil(math.log2(n)) + 1
# Фридман-Дайконис: ширина бина -> число бинов
q = st.quantiles(data, n=4)        # [Q1, Q2, Q3]
iqr = q[2] - q[0]
h_fd = 2 * iqr / (n ** (1/3))
k_fd = math.ceil((max(data) - min(data)) / h_fd)

print("n =", n)
print("корень   :", k_sqrt, "бинов")
print("Стёрджес :", k_sturges, "бинов")
print("Фр.-Дайк.: ширина", round(h_fd, 2), "->", k_fd, "бинов")

Вывод:

n = 30
корень   : 6 бинов
Стёрджес : 6 бинов
Фр.-Дайк.: ширина 1.29 -> 7 бинов

Биннинг своими руками

Чтобы понять, что гистограмма — это просто подсчёт по интервалам, посчитаем её сами на чистом Python.

data = [4,5,5,6,6,6,7,7,7,7,8,8,8,9,9,10,11,12]
k = 4
lo, hi = min(data), max(data)
width = (hi - lo) / k
counts = [0] * k
for v in data:
    idx = min(int((v - lo) / width), k - 1)   # последний бин включает hi
    counts[idx] += 1

for i, c in enumerate(counts):
    a = lo + i * width
    b = a + width
    print(f"[{a:.1f}; {b:.1f}) : {'#' * c} ({c})")

Вывод:

[4.0; 6.0) : ### (3)
[6.0; 8.0) : ####### (7)
[8.0; 10.0) : ##### (5)
[10.0; 12.0) : ### (3)

Как работает под капотом

Гистограмма — это грубая оценка плотности распределения. Высота столбца пропорциональна числу точек в интервале; если разделить на $n$ и на ширину бина, получим оценку плотности, площадь под которой равна 1 (об этом в уроке про нормировку). Выбор ширины — это компромисс смещение–дисперсия: широкие бины дают гладкую, но смещённую оценку (теряют детали), узкие — детальную, но шумную. Формулы выше минимизируют этот компромисс при разных предположениях.

Смещение–дисперсия наглядно

Выбор ширины бина — это конкретное проявление фундаментального компромисса смещение–дисперсия, который пронизывает всю статистику и машинное обучение. Широкий бин усредняет по большому интервалу: оценка устойчива (мало меняется от выборки к выборке — низкая дисперсия), но грубая, она «размазывает» детали и может скрыть две близкие моды (высокое смещение). Узкий бин чувствителен к каждой точке: он ловит тонкую структуру (низкое смещение), но шумен — случайные колебания выборки порождают ложные пики (высокая дисперсия).

Формулы вроде Фридмана–Дайкониса как раз ищут точку баланса: они учитывают и размер выборки $n$ (больше данных — можно позволить более узкие бины), и разброс данных (через IQR). Но ни одна формула не знает вашу задачу. Если вы подозреваете бимодальность, стоит сознательно взять бины поуже и проверить; если важна общая форма — пошире. Поэтому профессиональный приём — посмотреть распределение при нескольких значениях ширины, а не доверять единственному «правильному» числу.

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

  • Бины по умолчанию без проверки — 10 бинов из коробки могут скрыть или выдумать структуру.
  • Один взгляд при одном числе бинов — всегда смотрите 2–3 варианта, прежде чем делать вывод о форме.
  • Слишком узкие бины на малой выборке — каждый столбик из 1–2 точек, сплошной шум.
  • Неравные бины без нормировки плотности — высоты становятся несравнимыми.

Итог

  • Число бинов кардинально меняет вид гистограммы.
  • Стёрджес — для малых ~нормальных выборок; Фридман–Дайконис — устойчивее.
  • Гистограмма — это подсчёт точек по интервалам.
  • Смотрите несколько вариантов ширины бина.
Проверьте себя
1. Почему число бинов гистограммы — важное научное решение?
AОно влияет только на цвет
BСлишком широкие бины скрывают структуру, слишком узкие добавляют ложный шум
CОно меняет размер файла
DЧисло бинов ни на что не влияет
2. Чем правило Фридмана–Дайкониса устойчивее правила Стёрджеса?
AОно всегда даёт больше бинов
BОно задаёт ширину через IQR, который игнорирует выбросы
CОно не требует данных
DОно работает только для нормальных данных
3. Что по сути представляет собой гистограмма?
AТочную плотность распределения
BГрубую оценку плотности через подсчёт точек по интервалам
CЛинию тренда
DКорреляционную матрицу