Как выполнить ранжирование признаков (feature ranking)?

Ответ

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

1. Встроенные важности из ансамблевых моделей (Model-based)

from sklearn.ensemble import RandomForestRegressor
import pandas as pd
import numpy as np

# Обучаем модель
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)

# Извлекаем важность признаков (на основе среднего уменьшения примеси Gini/ MSE)
importances = rf.feature_importances_
feature_ranking = pd.DataFrame({'feature': X_train.columns, 'importance': importances})
feature_ranking = feature_ranking.sort_values('importance', ascending=False)

2. Перестановочная важность (Permutation Importance) Более надежный метод, который не смещён в сторону высокоразмерных или категориальных признаков. Он измеряет, насколько падает качество модели, если значения признака случайно перемешаны.

from sklearn.inspection import permutation_importance

perm_result = permutation_importance(rf, X_val, y_val, n_repeats=10, random_state=42)
sorted_idx = perm_result.importances_mean.argsort()[::-1]
# Ранжированные признаки: X_train.columns[sorted_idx]

3. Статистические методы для фильтрации

  • Для регрессии: Коэффициент корреляции Пирсона или Спирмена между признаком и целевой переменной.
  • Для классификации: F-статистика (ANOVA) или взаимная информация (mutual information).

4. Коэффициенты линейных моделей с L1-регуляризацией (Lasso) Lasso обнуляет веса неважных признаков, выполняя отбор автоматически.

from sklearn.linear_model import LassoCV
lasso = LassoCV(cv=5).fit(X_scaled, y)
# Ненулевые коэффициенты: np.where(lasso.coef_ != 0)[0]

Мой практический workflow:

  1. Использую перестановочную важность на валидационной выборке как основной устойчивый метод.
  2. Сравниваю результат с важностью из RandomForest/Gradient Boosting.
  3. Для линейных зависимостей дополнительно смотрю на коэффициенты Lasso или взаимную информацию.
  4. Принимаю решение об отборе признаков, ориентируясь на консенсус среди топ-фич по разным методам. Это позволяет избежать зависимости от артефактов одного конкретного алгоритма.

Ответ 18+ 🔞

Слушай, а вот ранжирование признаков — это вообще отдельная песня, пиздец как важно. Если хочешь понять, что в твоих данных реально работает, а что просто шум, и не утонуть в этой хуйне размерности, тут без комбинации методов — нихуя не выйдет. Я обычно несколько подходов в кучу собираю, чтобы оценка была, блядь, устойчивая.

1. Важности прямо из моделей-тяжеловесов (Model-based) Ну, тут всё просто, как три копейки. Берёшь какую-нибудь ансамблевую модель — она тебе на блюдечке выдает, какие фичи рулят. Типа, в среднем насколько каждая фича уменьшает беспорядок (импурность) в деревьях.

from sklearn.ensemble import RandomForestRegressor
import pandas as pd
import numpy as np

# Гоняешь модель
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)

# Вытаскиваешь эту самую важность
importances = rf.feature_importances_
feature_ranking = pd.DataFrame({'feature': X_train.columns, 'importance': importances})
feature_ranking = feature_ranking.sort_values('importance', ascending=False)

Но тут, чувак, есть подвох: метод может завышать важность для признаков с большим количеством категорий или просто высокоразмерных. Так что на слово верить — доверия ебать ноль.

2. Перестановочная важность (Permutation Importance) Вот это, ёпта, уже серьёзнее. Суть — ебашим значения в одном столбце в случайном порядке и смотрим, насколько модель обосрётся. Если качество просело сильно — признак важный. Если всё похуй — значит, фигня это всё.

from sklearn.inspection import permutation_importance

perm_result = permutation_importance(rf, X_val, y_val, n_repeats=10, random_state=42)
sorted_idx = perm_result.importances_mean.argsort()[::-1]
# Вот они, красавчики, по порядку: X_train.columns[sorted_idx]

Этот метод куда надёжнее, потому что он оценивает реальный вклад в предсказательную силу, а не внутреннюю кухню алгоритма.

3. Старорежимные статистические методы (фильтрация) Иногда надо просто быстро отсеять мусор.

  • Для регрессии: Глянь на обычную корреляцию (Пирсон) или, если связь нелинейная, на Спирмена.
  • Для классификации: F-статистика (ANOVA) или, что ещё круче, взаимная информация (mutual info). Она даже нелинейные зависимости ловит.

4. Коэффициенты линейных моделей с L1 (Lasso) Тут магия регуляризации. Lasso — он как строгий отец: неважные признаки обнуляет нахуй, оставляя только самых стойких.

from sklearn.linear_model import LassoCV
lasso = LassoCV(cv=5).fit(X_scaled, y)
# Смотри, какие выжили: np.where(lasso.coef_ != 0)[0]

Отлично работает, когда у тебя зависимость более-менее линейная. Если нет — можешь нихуя не увидеть.

Как я это всё собираю в кучу (мой воркфлоу):

  1. За основу беру перестановочную важность. Это мой главный аргумент, потому что она честная и на валидации считается.
  2. Сверяю с тем, что выдал RandomForest или Gradient Boosting. Если они солидарны в топе — хорошо. Если какой-то признак только у лесничего в топе, а перестановка его не уважает — подозрение ебать чувствую, возможно, артефакт.
  3. Для подстраховки гляжу на Lasso или mutual information. Особенно если подозреваю линейные связи.
  4. Принимаю решение по консенсусу. Если признак стабильно в топе у всех методов — царь и бог, оставляем. Если только один метод его пиарит — скорее всего, это хитрая жопа, и его можно нахуй послать. Такой подход спасает от слепой веры в один алгоритм, который мог просто сойти с ума.