Какие методы отбора признаков (feature selection) вы знаете?

Ответ

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

Три основных подхода:

1. Методы-фильтры (Filter Methods) Оценивают значимость признаков независимо от модели, на основе статистических мер.

  • Корреляция: Удаление сильно коррелирующих признаков (мультиколлинеарность).
    corr_matrix = X.corr().abs()
    upper_tri = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(bool))
    to_drop = [column for column in upper_tri.columns if any(upper_tri[column] > 0.85)]
    X_filtered = X.drop(to_drop, axis=1)
  • Взаимная информация (Mutual Information): Измеряет нелинейную зависимость между признаком и целевой переменной.
    from sklearn.feature_selection import mutual_info_classif
    mi_scores = mutual_info_classif(X, y)
  • ANOVA F-test: Оценивает различия между группами для категориальных целей.

2. Встроенные методы (Embedded Methods) Отбор происходит в процессе обучения модели.

  • Важность признаков в деревьях: Модели на основе деревьев (Random Forest, XGBoost) вычисляют feature_importances_.
    from sklearn.ensemble import RandomForestClassifier
    rf = RandomForestClassifier()
    rf.fit(X, y)
    importances = rf.feature_importances_
    # Выбираем топ-N признаков
    indices = np.argsort(importances)[-10:]
  • L1-регуляризация (Lasso): Штрафует абсолютные значения весов, обнуляя неважные.
    from sklearn.linear_model import LassoCV
    lasso = LassoCV().fit(X, y)
    selected_features = X.columns[lasso.coef_ != 0]

3. Методы-обертки (Wrapper Methods) Используют производительность модели как критерий отбора. Точны, но требуют больших вычислений.

  • Рекурсивное исключение признаков (RFE): Последовательно удаляет наименее важные признаки.
    from sklearn.feature_selection import RFE
    from sklearn.svm import SVC
    estimator = SVC(kernel="linear")
    selector = RFE(estimator, n_features_to_select=5, step=1)
    selector = selector.fit(X, y)
    X_rfe = X.loc[:, selector.support_]
  • Последовательный отбор (Forward/Backward Selection): Пошаговое добавление или удаление признаков.

Дополнительно: Методы на основе дисперсии (удаление константных и квази-константных признаков) и методы уменьшения размерности (PCA, t-SNE), которые не отбирают, а преобразуют признаки.

Ответ 18+ 🔞

А, ну это про отбор признаков, да? Ёпта, классика жанра, без этого никуда. Сидишь такой, а у тебя признаков — овердохуища, как будто кто-то датасет с помойки собрал. И модель на них учится, как мартышлюшка, которая в каждую дырку суёт пальцы, лишь бы чем-то занять себя. А потом удивляешься, почему она нихуя не предсказывает, кроме как на трейне.

Так вот, есть три основных подхода, чтобы эту кашу в голове привести в порядок.

1. Методы-фильтры (Filter Methods) Это когда ты на признаки смотришь как начальник цеха — со стороны, не вникая в детали производства. Оцениваешь их по каким-то своим, простым меркам.

  • Корреляция: Самый понятный способ. Смотришь, какие признаки друг на друга похожи, как братья-близнецы. Если два признака друг друга копируют, зачем нам оба? Один — в утиль. Берёшь матрицу, ищешь, где корреляция выше порога (скажем, 0.85) — и один из пары нахуй.
    corr_matrix = X.corr().abs()
    upper_tri = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(bool))
    to_drop = [column for column in upper_tri.columns if any(upper_tri[column] > 0.85)]
    X_filtered = X.drop(to_drop, axis=1)
  • Взаимная информация (Mutual Information): А это уже поинтереснее. Она ловит не только прямые связи, но и всякие хитрожопые нелинейные зависимости. Если признак и целевая переменная как будто не связаны, а на самом деле у них там тайный роман — mutual information это вычислит.
    from sklearn.feature_selection import mutual_info_classif
    mi_scores = mutual_info_classif(X, y)
  • ANOVA F-test: Ну, это для случаев, когда у тебя целевая переменная — категории. Проверяет, а сильно ли признаки отличаются между этими группами. Если нет — зачем он тебе?

2. Встроенные методы (Embedded Methods) А вот это уже умнее. Ты не отдельно отбор делаешь, а модель сама в процессе обучения решает, кто ей друг, а кто — хуй с горы. Удобно, быстро.

  • Важность признаков в деревьях: Берёшь Random Forest или XGBoost, обучаешь, а потом спрашиваешь: «Ну что, пацаны, кто из вас самый важный?». А они тебе выдают feature_importances_. Те, у кого важность околонулевая — мудя, их можно смело выкидывать, они просто балласт.
    from sklearn.ensemble import RandomForestClassifier
    rf = RandomForestClassifier()
    rf.fit(X, y)
    importances = rf.feature_importances_
    # Выбираем топ-N признаков
    indices = np.argsort(importances)[-10:]
  • L1-регуляризация (Lasso): Вообще красота. Ты ставишь модель, которая сама обнуляет веса у бесполезных признаков. Стоит ей сказать «штрафуй за сложность», она такие веса поставит на ненужные фичи, что они просто в ноль уйдут. Элегантно, блядь.

3. Методы-обертки (Wrapper Methods) А это уже для перфекционистов, у которых терпения — ноль ебать, а вычислительных ресурсов — завались. Тут ты модель заставляешь пробовать разные комбинации признаков и смотреть, от какой ей лучше.

  • Рекурсивное исключение признаков (RFE): Жестокий, но эффективный метод. Берёшь модель, обучаешь на всех признаках, смотришь — какой признак самый беспонтовый. Выкидываешь его. Обучаешь заново. И так по кругу, пока не останется горстка самых жирных и нужных. Точность обычно максимальная, но времени жрёт — ядрёна вошь.
    from sklearn.feature_selection import RFE
    from sklearn.svm import SVC
    estimator = SVC(kernel="linear")
    selector = RFE(estimator, n_features_to_select=5, step=1)
    selector = selector.fit(X, y)
    X_rfe = X.loc[:, selector.support_]
  • Последовательный отбор (Forward/Backward Selection): Похожая история. Либо с нуля начинаешь и по одному добавляешь признаки, которые дают самый большой прирост. Либо наоборот — со всех начинаешь и по одному убираешь, пока качество не просядет.

Ну и по мелочи: Ещё можно выкинуть признаки, которые вообще не меняются (константные) или меняются раз в год по обещанию (квази-константные). А если совсем припекло, можно пойти на крайние меры — PCA или t-SNE. Это когда ты не отбираешь старые признаки, а создаёшь из них новые, сжатые. Но тут уже надо понимать, что новые фичи — это как хуй в пальто, нихуя не интерпретируемые. Модель может работать лучше, но объяснить, почему — уже никак.