1.13. Выбор признаков#
Классы в sklearn.feature_selection модуль может использоваться для отбора признаков/снижения размерности на наборах образцов, либо для повышения точности оценок, либо для улучшения их производительности на очень многомерных наборах данных.
1.13.1. Удаление признаков с низкой дисперсией#
VarianceThreshold . Все наивные байесовские классификаторы поддерживают взвешивание образцов.
В качестве примера предположим, что у нас есть набор данных с булевыми признаками, и мы хотим удалить все признаки, которые равны единице или нулю (включены или выключены) более чем в 80% образцов. Булевы признаки — это случайные величины Бернулли, и дисперсия таких переменных задается формулой
чтобы мы могли выбирать с использованием порога .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 method:
SelectKBestудаляет все, кроме \(k\) признаки с наивысшими оценкамиSelectPercentileудаляет все, кроме указанного пользователем процента признаков с наивысшей оценкойиспользуя общие одномерные статистические тесты для каждого признака: частота ложных срабатываний
SelectFpr, частота ложных обнаруженийSelectFdr, или семейная ошибкаSelectFwe.GenericUnivariateSelectпозволяет выполнять одномерный отбор признаков с настраиваемой стратегией. Это позволяет выбрать лучшую одномерную стратегию отбора с помощью оценщика поиска гиперпараметров.
Например, мы можем использовать F-тест для извлечения двух лучших признаков для набора данных следующим образом:
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectKBest
>>> from sklearn.feature_selection import f_classif
>>> X, y = load_iris(return_X_y=True)
>>> X.shape
(150, 4)
>>> X_new = SelectKBest(f_classif, k=2).fit_transform(X, y)
>>> X_new.shape
(150, 2)
Эти объекты принимают на вход функцию оценки, которая возвращает одномерные оценки
и p-значения (или только оценки для SelectKBest и
SelectPercentile):
Для регрессии:
r_regression,f_regression,mutual_info_regressionДля классификации:
chi2,f_classif,mutual_info_classif
Методы, основанные на F-тесте, оценивают степень линейной зависимости между двумя случайными величинами. С другой стороны, методы взаимной информации могут улавливать любую статистическую зависимость, но, будучи непараметрическими, требуют больше выборок для точной оценки. Обратите внимание, что \(\chi^2\)-тест должен применяться только к неотрицательным характеристикам, таким как частоты.
Предупреждение
Будьте осторожны, не используйте функцию оценки регрессии для задачи классификации, вы получите бесполезные результаты.
Примечание
The SelectPercentile и SelectKBest поддерживает неконтролируемый отбор признаков. Необходимо предоставить score_func где y=None.
score_func должен использовать внутри X для вычисления оценок.
Примеры
1.13.3. Рекурсивное исключение признаков#
При наличии внешней оценки, которая присваивает веса признакам (например, коэффициенты линейной модели), цель рекурсивного исключения признаков (RFE) заключается в выборе признаков путем рекурсивного рассмотрения все меньших наборов признаков. Сначала оценщик обучается на начальном наборе признаков, и важность каждого признака получается либо через любой конкретный атрибут (такой как coef_, feature_importances_) или вызываемая функция. Затем наименее важные
признаки удаляются из текущего набора признаков. Эта процедура рекурсивно
повторяется на сокращённом наборе, пока не будет достигнуто желаемое количество признаков для выбора.
RFECV выполняет RFE в цикле кросс-валидации для поиска оптимального количества признаков. Подробнее, количество выбранных признаков настраивается автоматически путем обучения RFE селектор на различных разбиениях кросс-валидации (предоставленных cv параметр). Производительность
RFE селектор оценивается с использованием scorer для разного количества
выбранных признаков и агрегируются вместе. В итоге оценки усредняются
по фолдам, а количество выбранных признаков устанавливается равным количеству
признаков, которые максимизируют оценку кросс-валидации.
Примеры
Рекурсивное исключение признаков: Пример рекурсивного исключения признаков, показывающий значимость пикселей в задаче классификации цифр.
Рекурсивное исключение признаков с перекрестной проверкой: Пример рекурсивного исключения признаков с автоматической настройкой количества выбранных признаков с помощью перекрестной проверки.
1.13.4. Выбор признаков с использованием SelectFromModel#
SelectFromModel является мета-трансформером, который может использоваться вместе с любым
оценщиком, присваивающим важность каждому признаку через определённый атрибут (например,
coef_, feature_importances_) или через importance_getter вызываемый после обучения. Признаки считаются неважными и удаляются, если соответствующая важность значений признаков ниже предоставленного
threshold параметр. Помимо численного задания порога, существуют встроенные эвристики для нахождения порога с использованием строкового аргумента.
Доступные эвристики: «mean», «median» и кратные им значения с плавающей точкой, такие как «0.1*mean». В сочетании с 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, тем меньше признаков выбрано. С Lasso, чем выше параметр alpha, тем меньше признаков выбрано.
Примеры
Восстановление L1 и сжатое зондирование#
При удачном выборе alpha, Lasso может полностью восстановить точный набор ненулевых переменных, используя лишь несколько наблюдений, при условии выполнения определённых специфических условий. В частности, количество образцов должно быть "достаточно большим", иначе модели L1 будут работать случайным образом, где "достаточно большое" зависит от количества ненулевых коэффициентов, логарифма количества признаков, уровня шума, наименьшего абсолютного значения ненулевых коэффициентов и структуры матрицы признаков X. Кроме того, матрица признаков должна обладать определёнными специфическими свойствами, такими как не слишком высокая корреляция. О применении Lasso для восстановления разреженных сигналов см. этот пример по сжатому зондированию: Компрессионное зондирование: реконструкция томографии с априорным распределением L1 (Lasso).
Не существует общего правила для выбора параметра альфа для восстановления
ненулевых коэффициентов. Он может быть установлен с помощью перекрёстной проверки
(LassoCV или
LassoLarsCV), хотя это может привести к
недостаточно наказанным моделям: включение небольшого количества нерелевантных переменных
не вредит оценке предсказания. BIC
(LassoLarsIC) имеет тенденцию, наоборот, устанавливать высокие значения альфа.
Ссылки
Richard G. Baraniuk “Compressive Sensing”, IEEE Signal Processing Magazine [120] July 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)
Примеры
Важность признаков с использованием леса деревьев: пример на синтетических данных, показывающий восстановление действительно значимых признаков.
Важность перестановок против важности признаков случайного леса (MDI): пример обсуждения подводных камней использования важности признаков на основе примесей в качестве прокси для релевантности признаков.
1.13.5. Последовательный отбор признаков#
Последовательный отбор признаков [sfs] (SFS) доступен в
SequentialFeatureSelector трансформер.
SFS может быть как прямым, так и обратным:
Прямой SFS - это жадная процедура, которая итеративно находит лучший новый признак для добавления к набору выбранных признаков. Конкретно, мы изначально начинаем с нуля признаков и находим один признак, который максимизирует перекрёстно проверяемую оценку, когда оценщик обучается на этом единственном признаке. Как только первый признак выбран, мы повторяем процедуру, добавляя новый признак к набору выбранных признаков. Процедура останавливается, когда достигается желаемое количество выбранных признаков, как определено n_features_to_select параметр.
Обратный 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
оценить важность признаков и выбрать наиболее релевантные. Затем, RandomForestClassifier Дисперсия Твиди Pipeline примеры для получения дополнительной информации.