← Назад к вопросам

Что такое мультиколлинеарность?

2.0 Middle🔥 162 комментариев
#Машинное обучение#Статистика и A/B тестирование

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Мультиколлинеарность в машинном обучении

Мультиколлинеарность — это ситуация, когда две или более независимых переменных (признаков) в модели сильно коррелируют друг с другом. Это означает, что один признак можно предсказать из другого с высокой точностью.

Проблемы, которые вызывает мультиколлинеарность

  1. Нестабильные коэффициенты: малые изменения в данных приводят к большим изменениям в коэффициентах регрессии
  2. Переобучение: модель запоминает случайный шум вместо закономерностей
  3. Низкая интерпретируемость: сложно понять, какой признак действительно важен
  4. Проблемы с инверсией матриц: в линейной регрессии матрица может стать сингулярной (необратимой)
  5. Завышенные стандартные ошибки: доверительные интервалы становятся очень широкими

Типы мультиколлинеарности

1. Совершенная (Perfect) мультиколлинеарность

# Пример: одна переменная — линейная комбинация другой
X_age = [25, 30, 35, 40, 45]
X_birth_year = [1999, 1994, 1989, 1984, 1979]  # 2024 - age = birth_year
# Эти переменные идеально коррелируют: r = -1

2. Высокая (High) мультиколлинеарность

# Переменные сильно, но не идеально коррелируют
X1 = [1, 2, 3, 4, 5]
X2 = [2.1, 4.0, 6.1, 7.9, 10.1]  # примерно 2*X1, но не совсем
# Корреляция высокая, но не 1.0

Выявление мультиколлинеарности

1. Матрица корреляции

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

# Создание данных с мультиколлинеарностью
df = pd.DataFrame({
    age: [25, 30, 35, 40, 45],
    experience: [1, 3, 8, 12, 15],  # сильно коррелирует с age
    salary: [30000, 45000, 65000, 85000, 100000],
    education_years: [16, 18, 18, 20, 20]
})

# Матрица корреляции
corr_matrix = df.corr()
print(corr_matrix)

# Визуализация
sns.heatmap(corr_matrix, annot=True, cmap=coolwarm, vmin=-1, vmax=1)
plt.show()

# Вывод: age и experience имеют корреляцию близкую к 1

2. Variance Inflation Factor (VIF)

from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant

# Добавляем константу
X = df[[age, experience, education_years]].copy()
X = add_constant(X)

# Вычисляем VIF для каждого признака
vif_data = pd.DataFrame()
vif_data["Feature"] = X.columns
vif_data["VIF"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]

print(vif_data)
# VIF < 5: нет мультиколлинеарности
# VIF 5-10: умеренная мультиколлинеарность
# VIF > 10: высокая мультиколлинеарность

3. Число обусловленности (Condition Number)

from numpy.linalg import cond

X_features = df[[age, experience, education_years]].values

# Число обусловленности
cond_number = cond(X_features.T @ X_features)
print(f"Condition Number: {cond_number}")

# Интерпретация:
# < 30: нет проблем
# 30-100: умеренная мультиколлинеарность
# > 100: серьёзная мультиколлинеарность

Способы борьбы с мультиколлинеарностью

1. Удаление одного из коррелирующих признаков

# Находим признаки с высокой корреляцией
high_corr_pairs = []
for i in range(len(corr_matrix.columns)):
    for j in range(i+1, len(corr_matrix.columns)):
        if abs(corr_matrix.iloc[i, j]) > 0.8:  # порог корреляции
            high_corr_pairs.append((corr_matrix.columns[i], corr_matrix.columns[j]))

print(high_corr_pairs)  # [(age, experience)]

# Удаляем один из них
df_clean = df.drop(experience, axis=1)
print(df_clean)

2. Principal Component Analysis (PCA)

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

# Стандартизация
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df[[age, experience, education_years]])

# PCA
pca = PCA(n_components=2)  # из 3 признаков делаем 2
X_pca = pca.fit_transform(X_scaled)

print(f"Explained variance ratio: {pca.explained_variance_ratio_}")
# Новые признаки некоррелированы!
df_pca = pd.DataFrame(X_pca, columns=[PC1, PC2])
print(df_pca.corr())  # близко к 0

3. Ridge Regression (L2 регуляризация)

from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split

X = df[[age, experience, education_years]]
y = df[salary]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Ridge с параметром alpha (регуляризация)
ridge = Ridge(alpha=1.0)  # alpha > 0 штрафует большие коэффициенты
ridge.fit(X_train, y_train)

print(f"R² Score: {ridge.score(X_test, y_test)}")
print(f"Коэффициенты: {ridge.coef_}")

4. Lasso Regression (L1 регуляризация)

from sklearn.linear_model import Lasso

lasso = Lasso(alpha=0.1)  # может обнулить коэффициенты
lasso.fit(X_train, y_train)

print(f"R² Score: {lasso.score(X_test, y_test)}")
print(f"Коэффициенты: {lasso.coef_}")
# Некоторые коэффициенты могут быть равны 0 (отбор признаков)

5. ElasticNet (комбинация Ridge и Lasso)

from sklearn.linear_model import ElasticNet

elastic = ElasticNet(alpha=0.1, l1_ratio=0.5)  # комбинация L1 и L2
elastic.fit(X_train, y_train)
print(f"R² Score: {elastic.score(X_test, y_test)}")

6. Feature Engineering

# Вместо двух коррелирующих признаков создаём один новый
df[total_experience] = df[age] - 22  # примерный возраст начала карьеры
df[experience_ratio] = df[experience] / df[total_experience]

# Теперь используем новые признаки вместо старых

Практический пример: полная диагностика

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Ridge
from statsmodels.stats.outliers_influence import variance_inflation_factor

# 1. Проверка корреляции
print("Матрица корреляции:")
print(df.corr())

# 2. Вычисление VIF
from statsmodels.tools.tools import add_constant
X = add_constant(df[[age, experience, education_years]])
vif_data = pd.DataFrame()
vif_data["Feature"] = X.columns
vif_data["VIF"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
print("\nVIF значения:")
print(vif_data)

# 3. Если VIF > 5: используем Ridge Regression
if vif_data[vif_data[VIF] > 5].shape[0] > 0:
    print("\nОбнаружена мультиколлинеарность, применяем Ridge Regression")
    ridge = Ridge(alpha=10)
    ridge.fit(df[[age, experience, education_years]], df[salary])
    print(f"Коэффициенты Ridge: {ridge.coef_}")

Когда НЕ нужно беспокоиться о мультиколлинеарности

  • Деревья решений: устойчивы к мультиколлинеарности
  • Random Forest, XGBoost: также не страдают
  • Для предсказаний: если модель хорошо предсказывает, мультиколлинеарность не критична
  • Для интерпретации коэффициентов: это проблема, но для самого предсказания нет

Мультиколлинеарность — важная проблема при построении линейных моделей и интерпретации их коэффициентов, поэтому опытные датасайентисты всегда проверяют корреляции и VIF перед моделированием.

Что такое мультиколлинеарность? | PrepBro