1.13. Выбор признаков

Классы в sklearn.feature_selection модуле могут использоваться для выбора признаков / уменьшения размерности на выборочных наборах, либо для улучшения показателей точности оценщиков, либо для повышения их производительности на очень многомерных наборах данных.

1.13.1. Удаление функций с низкой дисперсией

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

В качестве примера предположим, что у нас есть набор данных с логическими функциями, и мы хотим удалить все функции, которые равны единице или нулю (включены или выключены) в более чем 80% выборок. Булевы функции — это случайные величины Бернулли, а дисперсия таких переменных определяется выражением
$$\mathrm{Var}[X] = p(1 — p)$$

поэтому мы можем выбрать с помощью порога .8 * (1 - .8):

>>> from sklearn.feature_selection import VarianceThreshold
>>> X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
>>> sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
>>> sel.fit_transform(X)
array([[0, 1],
       [1, 0],
       [0, 0],
       [1, 1],
       [1, 0],
       [1, 1]])

Как и ожидалось, VarianceThreshold удален первый столбец, вероятность которого $p = 5/6 > .8$ содержащего ноль.

1.13.2. Одномерный выбор функций

Одномерный выбор функций работает путем выбора лучших функций на основе одномерных статистических тестов. Это можно рассматривать как этап предварительной обработки оценщика. Scikit-learn предоставляет процедуры выбора функций как объекты, реализующие transform метод:

  • SelectKBest удаляет все, кроме $k$ функции с наивысшими оценками
  • SelectPercentile удаляет все функции, кроме указанного пользователем самого высокого процента баллов
  • использование общих одномерных статистических тестов для каждой функции: частота ложных срабатываний, частота SelectFpr ложных обнаружений SelectFdr или семейная ошибка SelectFwe.
  • GenericUnivariateSelect позволяет выполнять одномерный выбор функций с настраиваемой стратегией. Это позволяет выбрать лучшую одномерную стратегию выбора с помощью гиперпараметрического поискового оценщика.

Например, мы можем выполнить $\chi^2$ протестируйте образцы, чтобы получить только две лучшие характеристики, как показано ниже:

>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectKBest
>>> from sklearn.feature_selection import chi2
>>> X, y = load_iris(return_X_y=True)
>>> X.shape
(150, 4)
>>> X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
>>> X_new.shape
(150, 2)

Эти объекты принимают в качестве входных данных функцию оценки, которая возвращает одномерные оценки и p-значения (или только оценки для SelectKBest и SelectPercentile):

Методы, основанные на F-тесте, оценивают степень линейной зависимости между двумя случайными величинами. С другой стороны, методы взаимной информации могут фиксировать любой вид статистической зависимости, но, будучи непараметрическими, они требуют большего количества выборок для точной оценки.

Выбор функций с разреженными данными

При использовании разреженных данных (то есть данные , представленные в виде разреженных матриц), chi2mutual_info_regressionmutual_info_classif будет иметь дело с данными , не делая его плотным.

Предупреждение

Остерегайтесь использовать функцию оценки регрессии с проблемой классификации, вы получите бесполезные результаты.

1.13.3. Рекурсивное устранение признаков

При наличии внешнего оценщика, который присваивает веса характеристикам (например, коэффициентам линейной модели), цель рекурсивного исключения признаков (RFE) состоит в том, чтобы выбрать признаки путем рекурсивного рассмотрения все меньших и меньших наборов признаков. Во-первых, оценщик обучается на начальном наборе функций, и важность каждой функции определяется либо через какой-либо конкретный атрибут (например coef_feature_importances_), либо через вызываемый. Затем наименее важные функции удаляются из текущего набора функций. Эта процедура рекурсивно повторяется для сокращенного набора до тех пор, пока в конечном итоге не будет достигнуто желаемое количество функций для выбора.

RFECV выполняет RFE в цикле перекрестной проверки, чтобы найти оптимальное количество функций.

Примеры

1.13.4. Выбор функции с помощью SelectFromModel

SelectFromModel— это мета-преобразователь, который можно использовать вместе с любым оценщиком, который назначает важность каждой функции через определенный атрибут (например coef_feature_importances_) или через importance_getter вызываемый объект после подгонки. Функции считаются неважными и удаляются, если соответствующая важность значений функций ниже указанного threshold параметра. Помимо числового указания порога, существуют встроенные эвристики для поиска порога с использованием строкового аргумента. Доступные эвристики: «среднее», «среднее» и числа с плавающей запятой, такие как «0,1 * среднее». В сочетании с threshold критериями можно использовать max_features параметр, чтобы установить ограничение на количество выбираемых функций.

Примеры использования см. В разделах ниже.

1.13.4.1. Выбор функций на основе L1

Линейные модели, наказанные нормой L1, имеют разреженные решения: многие из их оценочных коэффициентов равны нулю. Когда цель состоит в том, чтобы уменьшить размерность данных для использования с другим классификатором, их можно использовать вместе с SelectFromModel для выбора ненулевых коэффициентов. В частности, для этой цели полезны разреженные оценки, используемые для Lasso регрессии, LogisticRegression а также LinearSVC для классификации:

>>> from sklearn.svm import LinearSVC
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectFromModel
>>> X, y = load_iris(return_X_y=True)
>>> X.shape
(150, 4)
>>> lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y)
>>> model = SelectFromModel(lsvc, prefit=True)
>>> X_new = model.transform(X)
>>> X_new.shape
(150, 3)

С SVM и логистической регрессией параметр C контролирует разреженность: чем меньше C, тем меньше выбирается функций. При использовании лассо, чем выше альфа-параметр, тем меньше объектов выбирается.

Примеры

L1-восстановление и сжатие

Для правильного выбора альфа-канала лассо может полностью восстановить точный набор ненулевых переменных, используя только несколько наблюдений, при соблюдении определенных конкретных условий. В частности, количество выборок должно быть «достаточно большим», иначе модели L1 будут работать случайным образом, где «достаточно большое» зависит от количества ненулевых коэффициентов, логарифма количества функций, количества шума, наименьшее абсолютное значение ненулевых коэффициентов и структура матрицы плана X. Кроме того, матрица плана должна отображать определенные специфические свойства, такие как отсутствие слишком сильной корреляции.
Не существует общего правила выбора альфа-параметра для восстановления ненулевых коэффициентов. Его можно установить путем перекрестной проверки ( LassoCV или LassoLarsCV), хотя это может привести к модели с недостаточным количеством штрафов: включение небольшого количества нерелевантных переменных не повлияет на оценку прогноза. BIC ( LassoLarsIC), напротив, имеет тенденцию устанавливать высокие значения альфа.
Ссылка Ричард Г. Баранюк «Compressive Sensing», журнал IEEE Signal Processing Magazine [120] июль 2007 г. http://users.isr.ist.utl.pt/~aguiar/CS_notes.pdf

1.13.4.2. Выбор функций на основе дерева

Оценщики на основе деревьев (см. sklearn.tree Модуль и лес деревьев в sklearn.ensemble модуле) могут использоваться для вычисления значимости свойств на основе примесей, которые, в свою очередь, могут использоваться для отбрасывания нерелевантных функций (в сочетании с SelectFromModel метатрансформатором):

>>> from sklearn.ensemble import ExtraTreesClassifier
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectFromModel
>>> X, y = load_iris(return_X_y=True)
>>> X.shape
(150, 4)
>>> clf = ExtraTreesClassifier(n_estimators=50)
>>> clf = clf.fit(X, y)
>>> clf.feature_importances_  
array([ 0.04...,  0.05...,  0.4...,  0.4...])
>>> model = SelectFromModel(clf, prefit=True)
>>> X_new = model.transform(X)
>>> X_new.shape               
(150, 2)

Примеры

1.13.5. Последовательный выбор функций

Последовательный выбор функций [sfs] (SFS) доступен в SequentialFeatureSelector трансформаторе. SFS может быть как вперед, так и назад:

Forward-SFS — это жадная процедура, которая итеративно находит лучшую новую функцию для добавления к набору выбранных функций. Конкретно, мы сначала начинаем с нулевой функции и находим одну функцию, которая максимизирует перекрестно проверенный балл, когда оценщик обучается на этой единственной функции. Как только эта первая функция выбрана, мы повторяем процедуру, добавляя новую функцию к набору выбранных функций. Процедура останавливается, когда достигается желаемое количество выбранных функций, как определено n_features_to_select параметром.

Backward-SFS следует той же идее, но работает в противоположном направлении: вместо того, чтобы начинать без функции и жадно добавлять функции, мы начинаем со всех функций и жадно удаляем функции из набора. В direction параметр управляет будь то вперед или назад SFS используется.

Как правило, прямой и обратный отбор не дают одинаковых результатов. Кроме того, один может быть намного быстрее другого в зависимости от запрошенного количества выбранных функций: если у нас есть 10 функций и мы запрашиваем 7 выбранных функций, для прямого выбора потребуется выполнить 7 итераций, а для обратного выбора потребуется выполнить только 3.

SFS отличается от RFE и SelectFromModel тем, что не требует, чтобы базовая модель предоставляла атрибут coef_ или feature_importances_. Однако это может быть медленнее, учитывая необходимость оценки большего числа моделей по сравнению с другими подходами. Например, при обратном выборе итерация, переходящая от m функций к m — 1 функциям с использованием перекрестной проверки в k-кратном порядке, требует подгонки m * k моделей, в то время как RFE потребует только единственной подгонки и SelectFromModel всегда только единственной подгонки и не требует итераций.

1.13.6. Выбор функции как часть конвейера

Выбор функций обычно используется как этап предварительной обработки перед фактическим обучением. Рекомендуемый способ сделать это в scikit-learn — использовать Pipeline:

clf = Pipeline([
  ('feature_selection', SelectFromModel(LinearSVC(penalty="l1"))),
  ('classification', RandomForestClassifier())
])
clf.fit(X, y)

В этом фрагменте мы используем LinearSVC сочетание с, SelectFromModel чтобы оценить важность функций и выбрать наиболее подходящие функции. Затем a RandomForestClassifier обучается на преобразованном выходе, т. е. с использованием только релевантных функций. Вы можете выполнять аналогичные операции с другими методами выбора функций, а также с классификаторами, которые, конечно же, предоставляют способ оценки важности функций. См. Pipeline примеры для более подробной информации.