Гетероскедастичность простыми словами

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

Короткое объяснение

Гетероскедастичность (heteroskedasticity) — это когда разброс ошибок в регрессии неодинаковый для разных значений X.

Противоположное — гомоскедастичность (homoskedasticity) — одинаковый разброс. Это одно из требований классической линейной регрессии.

Аналогия

Представьте, что вы оцениваете зарплату по стажу.

  • Стаж 1 год: зарплаты 40-80K (разброс небольшой)
  • Стаж 5 лет: 80-150K (разброс средний)
  • Стаж 15 лет: 100-500K (разброс огромный, от senior до CEO)

Разброс растёт со стажем → гетероскедастичность.

Если бы разброс всех зарплат был одинаковый по стажу — гомоскедастичность.

Почему это проблема

В классической линейной регрессии (OLS) коэффициенты остаются несмещёнными даже при гетероскедастичности, НО:

  1. Standard errors коэффициентов становятся неверными (обычно занижены)
  2. P-values неверны — говорим «значимо», когда на самом деле нет
  3. Доверительные интервалы уже, чем должны
  4. Тесты (t, F) ненадёжны

То есть статистические выводы могут быть ошибочными.

Как увидеть графически

Постройте график остатков vs предсказанные значения:

  • Гомоскедастичность: облако точек равномерное (прямоугольник)
  • Гетероскедастичность: облако расширяется или сужается (воронка)
import matplotlib.pyplot as plt
plt.scatter(y_pred, residuals)
plt.xlabel('Fitted values')
plt.ylabel('Residuals')
plt.axhline(0, color='red', linestyle='--')

Если видно «воронку» → heteroskedasticity.

Как проверить статистически

Breusch-Pagan test

from statsmodels.stats.diagnostic import het_breuschpagan

bp_test = het_breuschpagan(residuals, X)
p_value = bp_test[1]
# p < 0.05 → есть heteroskedasticity

White test

Более общий, не предполагает линейности.

from statsmodels.stats.diagnostic import het_white

Откуда берётся heteroskedasticity

Естественная структура данных

  • Зарплата растёт с возрастом, и разброс тоже растёт
  • Выручка клиентов: у маленьких — узкий разброс, у больших — большой
  • Любые «денежные» метрики с тяжёлым хвостом

Пропущенная переменная

Если в модели не учтён важный предиктор, его вариация «уходит» в ошибку → разброс неравномерный.

Неверная функциональная форма

Линейная модель поверх нелинейного процесса → ошибки растут на краях.

Как исправить

1. Log-трансформация

Самое простое для экономических данных:

y_log = np.log1p(y)
model = sm.OLS(y_log, X).fit()

Часто «сжимает» разброс, приводя к гомоскедастичности.

2. WLS (Weighted Least Squares)

Даём меньший вес наблюдениям с большей дисперсией:

weights = 1 / (fitted_variance)
model = sm.WLS(y, X, weights=weights).fit()

3. Robust standard errors

Не меняем коэффициенты, но получаем правильные standard errors.

model = sm.OLS(y, X).fit(cov_type='HC3')
# HC0, HC1, HC2, HC3 — разные estimators

Это самое популярное современное решение. Коэффициенты те же, но p-values корректны.

4. Box-Cox / Yeo-Johnson

Трансформации, которые «нормализуют» данные.

from scipy.stats import boxcox
y_transformed, _ = boxcox(y)

5. Другая модель

Иногда лучше использовать:

  • GLM (Generalized Linear Model) для неnormal ошибок
  • Quantile regression (меньше зависит от гомоскедастичности)

В A/B-тестах

Heteroskedasticity встречается в A/B:

  • Средний чек: у новых пользователей узкий разброс, у лояльных — большой
  • Time on site: короткие сессии однородны, длинные — с выбросами

Решения:

  • Welch's t-test (вместо Student's) — не требует равенства дисперсий
  • Mann-Whitney U — непараметрический
  • Bootstrap для доверительных интервалов

Подробнее: t-test vs z-test.

На собесе

Типичный вопрос: «Какие предположения OLS и что делать, если они нарушены?»

Ключевые предположения:

  1. Линейность
  2. Независимость ошибок
  3. Гомоскедастичность ← об этом речь
  4. Нормальность ошибок (для small n)
  5. Нет мультиколлинеарности

Если спросят про heteroskedasticity:

  • Объяснить словами («разброс ошибок разный»)
  • Как обнаружить (график residuals, Breusch-Pagan)
  • Как исправить (log, robust SE, WLS)

Гомоскедастичность в A/B

Student's t-test требует равенства дисперсий. Если нарушено — использовать Welch's t-test (в SciPy equal_var=False).

from scipy.stats import ttest_ind
stat, p = ttest_ind(a, b, equal_var=False)  # Welch's

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

Ошибка 1. Игнорировать

Просто гонять OLS на любых данных без проверки → в отчёт уходят неверные p-values.

Ошибка 2. Смотреть только R²

R² не говорит о heteroskedasticity. Нужен график остатков.

Ошибка 3. Путать heteroskedasticity с нелинейностью

Нелинейность — модель плохо аппроксимирует. Heteroskedasticity — ошибки неравномерны. Разные проблемы.

Ошибка 4. Заменять log-трансформацией всегда

Log не спасает, если разброс не связан с масштабом. И log(0) — проблема.

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

FAQ

Это только про регрессию?

В основном да, но концепция «неравномерного разброса» встречается в A/B (Welch's test), временных рядах, ANOVA.

Что делать проще всего?

Добавить robust standard errors (cov_type='HC3'). Коэффициенты те же, statistics корректные.

Как увидеть графически?

Scatter plot остатков vs предсказанных значений. «Воронка» = heteroskedasticity.

Нужно ли знать на собесе для junior?

Уметь объяснить словами — плюс. Для middle — обязательно.


Тренируйте статистику — откройте тренажёр с 1500+ вопросами для собесов.