Привет! На связи Кристина Желтова, директор по разработке моделей в Газпромбанке и преподаватель курса «Инженер машинного обучения» 👋🏻
Представьте, что вы обучаете ML-модель на датасете из 50-ти признаков с точностью 87%. Добавили еще 20 признаков и качество упало до 83% — разве больше данных не значит лучше? Нет, если данные некачественные. Чем больше бесполезных признаков, тем быстрее модель переобучается и хуже обобщается на новые данные.
В этой ситуации на помощь приходит отбор признаков (feature selection) — одна из самых недооценённых техник классического ML. Во многих моделях есть «встроенные» способы отбора признаков — например, для случайного леса можно оценить важности признаков простым способом за 30 секунд:
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1000, n_features=50, n_informative=10, random_state=42)
# Обучили модель
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X, y)
# Посмотрели важность признаков
importances = rf.feature_importances_
top_features = sorted(range(len(importances)), key=lambda i: importances[i], reverse=True)[:10]
print(f"Топ-10 признаков: {top_features}")
Почему это работает? Потому что случайный лес рассчитывает, насколько каждый признак уменьшает ошибку на каждом шаге построения каждого дерева решений. Если признак не помогает, он не будет использоваться часто.
Однако этот метод не лишён недостатков, поэтому на практике есть большое количество алгоритмов отбора признаков, которые можно разделить на три группы:
1️⃣ Filter-методы (фильтруем признаки по статистике)
Это самый быстрый способ. Мы смотрим на каждый признак отдельно без построения модели: например, удаляем признаки с низкой дисперсией (по сути делаем предположение, что раз они не очень разнообразны, то и не очень полезны).
from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold(threshold=0.01)
X_filtered = selector.fit_transform(X)
Отличный вариант на случай, если у вас очень много признаков и нужно быстро сократить их количество.
2️⃣ Wrapper-методы (обёртки)
Более медленные, но умные методы — тренируем модель много раз, удаляя или добавляя признаки.
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
# RFE (recursive feature elimination): обучаем модель, удаляем худший признак, повторяем
estimator = LogisticRegression(random_state=42, max_iter=1000)
rfe = RFE(estimator, n_features_to_select=10, step=1)
X_rfe = rfe.fit_transform(X, y)
print(f"Выбранные признаки: {rfe.support_}")
Отличный баланс скорости и качества, когда признаков не слишком много, и есть время подождать.
3️⃣ Embedded-методы (встроенные в модель)
Как раз к ним относятся
feature_importances_ из случайного леса. Быстро, но зависит от конкретной модели.Эти методы в совокупности помогут вам отобрать лучшие признаки для своих моделей и быстро улучшить качество.
Ставьте 🔥, если интересно!