Как работать с мультиколлинеарностью признаков при построении модели классификации?

Ответ

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

1. Выявление коррелирующих признаков:

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

# Расчет матрицы корреляций
corr_matrix = df.corr()

# Визуализация тепловой карты
plt.figure(figsize=(12, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Матрица корреляций признаков')
plt.show()

# Автоматический поиск сильно коррелирующих пар (порог > 0.85)
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.85:
            col_i = corr_matrix.columns[i]
            col_j = corr_matrix.columns[j]
            high_corr_pairs[(col_i, col_j)] = corr_matrix.iloc[i, j]
print("Сильно коррелирующие пары:", high_corr_pairs)

2. Методы устранения мультиколлинеарности:

  • Удаление одного из признаков: Самый простой способ. Удаляйте тот признак, который менее значим с предметной точки зрения или имеет более высокую корреляцию с другими признаками.
  • Метод главных компонент (PCA): Преобразует исходные коррелированные признаки в набор некоррелированных (ортогональных) компонент.

    from sklearn.decomposition import PCA
    from sklearn.preprocessing import StandardScaler
    
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)
    pca = PCA(n_components=0.95) # Оставить 95% дисперсии
    X_pca = pca.fit_transform(X_scaled)
  • Регуляризация: Добавление штрафа к коэффициентам модели (L1-лассо или L2-ридж) автоматически снижает влияние мультиколлинеарности.
    from sklearn.linear_model import LogisticRegression
    # L2-регуляризация по умолчанию помогает бороться с коллинеарностью
    model = LogisticRegression(penalty='l2', C=1.0, solver='lbfgs')

3. Выбор модели, устойчивой к коллинеарности:

  • Деревянные модели (Random Forest, Gradient Boosting): В основе лежит рекурсивное разбиение по одному признаку, поэтому они менее чувствительны к корреляциям. Однако интерпретация важности признаков может искажаться.
  • Линейные модели с регуляризацией: Всегда предпочтительнее обычной линейной регрессии/логистической регрессии при наличии корреляций.

Ответ 18+ 🔞

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

1. Сперва ищем этих засранцев, которые друг за друга держатся.

Код вот тебе, запускай и смотри, кто с кем не в меру любезен. Тепловая карта — это вообще пиздец как наглядно, сразу видно, где красная зона страсти.

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

# Расчет матрицы корреляций
corr_matrix = df.corr()

# Визуализация тепловой карты
plt.figure(figsize=(12, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Матрица корреляций признаков')
plt.show()

# Автоматический поиск сильно коррелирующих пар (порог > 0.85)
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.85:
            col_i = corr_matrix.columns[i]
            col_j = corr_matrix.columns[j]
            high_corr_pairs[(col_i, col_j)] = corr_matrix.iloc[i, j]
print("Сильно коррелирующие пары:", high_corr_pairs)

Если там вылезли парочки с цифрой 0.9 — это ёперный театр, они уже практически одно и то же. Доверия ебать ноль к таким близнецам.

2. Как с этим безобразием бороться?

  • Просто выкинуть одного. Самый простой и часто самый лучший способ. Смотришь на пару — один признак «площадь квартиры», другой «число комнат». Ну ясный пень, они связаны. Выбираешь, какой из них для задачи важнее, а второй — да похуй, в мусорку. Оставляешь сильнейшего, как в драке.

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

    from sklearn.decomposition import PCA
    from sklearn.preprocessing import StandardScaler
    
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)
    pca = PCA(n_components=0.95) # Оставить 95% дисперсии
    X_pca = pca.fit_transform(X_scaled)
  • Регуляризация. Это когда ты говоришь модели: «Слушай, дружок, не распускай свои коэффициенты как мартышлюшка, будь скромнее, а то накажу». L2-регуляризация (Ридж) как раз зажимает эти коэффициенты, не даёт им раздуваться из-за коллинеарности.

    from sklearn.linear_model import LogisticRegression
    # L2-регуляризация по умолчанию помогает бороться с коллинеарностью
    model = LogisticRegression(penalty='l2', C=1.0, solver='lbfgs')

3. А можно взять модель, которой похуй на эту вашу коллинеарность?

Можно, конечно.

  • Случайный лес или градиентный бустинг. Эти ребята — хитрая жопа. Они строят деревья, выбирая на каждом шаге один лучший признак. Им по барабану, что остальные с ним коррелируют, главное — разделить данные. Но тут засада другая: если у тебя есть два одинаково хороших коррелирующих признака, важность может распределиться между ними как попало, и интерпретация полетит в пизду.
  • Так что линейные модели с регуляризацией — часто самый вменяемый выбор. Они и устойчивее становятся, и коэффициенты ещё как-то можно попытаться понять. Главное — не забыть признаки нормализовать, а то регуляризация одного большого коэффициента накажет, а другого маленького — нет, и будет несправедливо, я тебя в сраку ебал.