Гетероскедастичность простыми словами
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Короткое объяснение
Гетероскедастичность (heteroskedasticity) — это когда разброс ошибок в регрессии неодинаковый для разных значений X.
Противоположное — гомоскедастичность (homoskedasticity) — одинаковый разброс. Это одно из требований классической линейной регрессии.
Аналогия
Представьте, что вы оцениваете зарплату по стажу.
- Стаж 1 год: зарплаты 40-80K (разброс небольшой)
- Стаж 5 лет: 80-150K (разброс средний)
- Стаж 15 лет: 100-500K (разброс огромный, от senior до CEO)
Разброс растёт со стажем → гетероскедастичность.
Если бы разброс всех зарплат был одинаковый по стажу — гомоскедастичность.
Почему это проблема
В классической линейной регрессии (OLS) коэффициенты остаются несмещёнными даже при гетероскедастичности, НО:
- Standard errors коэффициентов становятся неверными (обычно занижены)
- P-values неверны — говорим «значимо», когда на самом деле нет
- Доверительные интервалы уже, чем должны
- Тесты (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 → есть heteroskedasticityWhite 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 и что делать, если они нарушены?»
Ключевые предположения:
- Линейность
- Независимость ошибок
- Гомоскедастичность ← об этом речь
- Нормальность ошибок (для small n)
- Нет мультиколлинеарности
Если спросят про 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) — проблема.
Связанные темы
- Линейная регрессия
- Дисперсия vs стандартное отклонение
- T-test vs z-test
- Multicollinearity простыми словами
FAQ
Это только про регрессию?
В основном да, но концепция «неравномерного разброса» встречается в A/B (Welch's test), временных рядах, ANOVA.
Что делать проще всего?
Добавить robust standard errors (cov_type='HC3'). Коэффициенты те же, statistics корректные.
Как увидеть графически?
Scatter plot остатков vs предсказанных значений. «Воронка» = heteroskedasticity.
Нужно ли знать на собесе для junior?
Уметь объяснить словами — плюс. Для middle — обязательно.
Тренируйте статистику — откройте тренажёр с 1500+ вопросами для собесов.