Что такое мультиколлинеарность
Коротко
Мультиколлинеарность — когда две или несколько фич (независимых переменных) в регрессии сильно коррелируют между собой.
Это ломает интерпретацию модели: вы не знаете, какая из коррелированных фич реально влияет на target.
Пример
Модель предсказывает зарплату аналитика:
years_of_experienceyears_since_graduation
Эти две фичи почти одинаковые (r=0.95). Модель не может разобрать, какая из них «настоящая причина».
Коэффициенты могут стать нестабильными:
- В одной выборке: experience = +10000, since_graduation = -5000.
- В другой: experience = -3000, since_graduation = +13000.
Сумма — одинаковая, но интерпретация каждого — мусор.
Почему это плохо
1. Нестабильные коэффициенты
Меняются с каждой выборкой. Нельзя доверять.
2. Огромные стандартные ошибки
Confidence interval коэффициента широкий → «значимость» плывёт.
3. Плохая интерпретация
«Experience влияет на зарплату на +X₽» — неверно, если есть since_graduation в модели.
4. Но predictions могут быть OK
Модель всё ещё предсказывает неплохо, просто коэффициенты врут. Для пониманияfeature importance — проблема.
Если хочется сразу закрепить тему на практике — открой тренажёр в Telegram. 10 минут в день — и синтаксис в пальцах.
Как обнаружить
1. Корреляционная матрица
corr = df.corr()
import seaborn as sns
sns.heatmap(corr, annot=True, cmap='coolwarm')Ищем пары с |r| > 0.7.
2. VIF (Variance Inflation Factor)
Более точный способ:
from statsmodels.stats.outliers_influence import variance_inflation_factor
X = df[features]
vif = pd.DataFrame()
vif['feature'] = X.columns
vif['VIF'] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
print(vif)Интерпретация:
- VIF = 1 — нет мультиколлинеарности.
- VIF < 5 — ОК.
- VIF 5-10 — подозрительно.
- VIF > 10 — серьёзная multicollinearity.
3. Condition Number
np.linalg.cond(X.values)30 — проблема. > 100 — серьёзная.
Как лечить
1. Удалить одну из коррелированных
Самое простое:
# Если experience и since_graduation коррелируют на 0.95 — оставить одну
features = ['experience', 'education', 'location'] # without since_graduation2. Объединить в одну
Сумма, среднее, главная компонента:
df['education_experience'] = df['experience'] + df['since_graduation']3. PCA (Principal Component Analysis)
Преобразовать коррелированные в независимые компоненты:
from sklearn.decomposition import PCA
pca = PCA(n_components=5)
X_pca = pca.fit_transform(X)Но интерпретация компонент теряется.
4. Ridge / Lasso регрессия
Регуляризация «гасит» коэффициенты коррелированных фич:
from sklearn.linear_model import Ridge, Lasso
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)5. Увеличить выборку
Больше данных → стабильнее коэффициенты. Но не всегда помогает.
Типичные источники
1. Дублирующие фичи
price_usd и price_rub с фиксированным курсом — жесткая колинеарность.
2. Связанные временные
year, month, day_of_year — если все включить, плохо.
3. One-hot encoding без dropping first
# ❌ Dummy trap: все колонки линейно зависимы
pd.get_dummies(df['color']) # red, blue, green
# ✅ Dropping first — убирает колинеарность
pd.get_dummies(df['color'], drop_first=True) # blue, green4. Сумма = total
Если a + b + c = total, и total тоже в модели — колинеарность.
Когда игнорировать
Если модель используется только для prediction (не интерпретации) — мультиколлинеарность не мешает.
В ML-моделях (XGBoost, Random Forest) — они внутри справляются.
В линейной / логистической регрессии — нужно лечить.
Чтобы не только читать теорию, но и решать реальные задачи — загляните в бот Карьерника. Там по каждой теме подборка вопросов с разборами.
Пример полного анализа
import pandas as pd
import numpy as np
from statsmodels.stats.outliers_influence import variance_inflation_factor
import statsmodels.api as sm
df = pd.read_csv('data.csv')
features = ['x1', 'x2', 'x3', 'x4', 'x5']
X = df[features]
y = df['target']
# Correlation matrix
print(X.corr())
# VIF
vif = pd.DataFrame()
vif['feature'] = X.columns
vif['VIF'] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
print(vif)
# Если VIF > 10 для x2 — удаляем
features_clean = ['x1', 'x3', 'x4', 'x5']
X_clean = df[features_clean]
# Fit регрессию
model = sm.OLS(y, sm.add_constant(X_clean)).fit()
print(model.summary())На собеседовании
Вопросы:
- «Что такое мультиколлинеарность?»
- «Как обнаружить?» (corr matrix, VIF).
- «Как решить?» (удалить, merge, PCA, Ridge).
- «Влияет на predictions?» (нет, на интерпретацию да).
Читайте также
FAQ
Насколько strong correlation ≠ problem?
0.7+ обычно считают проблемой. 0.5-0.7 — borderline.
VIF обязательно считать?
Для интерпретационных моделей — да. Для ML-predictions — нет.
Multicollinearity в ML?
В tree-based (XGBoost, RF) — неважно. В линейных — важно.
Можно ли игнорировать?
Если важны predictions, не интерпретация — да.