Признаки (feature), используемые для обучения модели, оказывают большое влияние на качество результатов. Неинформативные или слабо информативные признаки могут существенно понизить эффективность модели.
В этой статье мы рассмотрим различные методы автоматизированного отбора признаков (feature selection), применяемые для подготовки данных. Примеры реализованы с помощью Python и библиотеки scikit-learn.
Отбор признаков
Отбор признаков – это процесс выбора признаков, имеющих наиболее тесные взаимосвязи с целевой переменной.
Присутствие в данных неинформативных признаков приводит к снижению точности многих моделей, особенно линейных, таких как линейная и логистическая регрессия.
Отбор признаков перед моделированием обеспечивает три следующих преимущества:
- Уменьшение переобучения. Чем меньше избыточных данных, тем меньше возможностей для модели принимать решения на основе «шума».
- Повышение точности. Чем меньше противоречивых данных, тем выше точность.
- Сокращение времени обучения. Чем меньше данных, тем быстрее обучается модель.
Подробное руководство по отбору признаков с помощью scikit-learn вы можете найти в документации к этой библиотеке в разделе Feature selection.
Методы отбора признаков
Итак, давайте рассмотрим 4 метода отбора признаков на Python. Демонстрационные примеры для каждого метода являются самостоятельными модулями, которые вы можете просто скопировать и использовать в своих проектах.
В наших примерах мы будем работать с набором данных, содержащим информацию о случаях сахарного диабета среди индейцев Пима (Pima Indians diabetes). Все признаки являются числовыми, а задача представляет собой двухклассовую классификацию.
- Одномерный отбор признаков
Признаки, имеющие наиболее выраженную взаимосвязь с целевой переменной, могут быть отобраны с помощью статистических критериев. Библиотека scikit-learn содержит класс SelectKBest, реализующий одномерный отбор признаков (univariate feature selection). Этот класс можно применять совместно с различными статистическими критериями для отбора заданного количества признаков.
В примере ниже используется критерий хи-квадрат (chi-squared test) для неотрицательных признаков, чтобы отобрать 4 лучших признака.
# Feature Extraction with Univariate Statistical Tests (Chi-squared for classification) import pandas import numpy from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 # load data url = "https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = pandas.read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] # feature extraction test = SelectKBest(score_func=chi2, k=4) fit = test.fit(X, Y) # summarize scores numpy.set_printoptions(precision=3) print(fit.scores_) features = fit.transform(X) # summarize selected features print(features[0:5,:])
Мы видим оценки для каждого признака и 4 отобранных признака (с наивысшими оценками): plas, test, mass и age.
[ 111.52 1411.887 17.605 53.108 2175.565 127.669 5.393 181.304] [[ 148. 0. 33.6 50. ] [ 85. 0. 26.6 31. ] [ 183. 0. 23.3 32. ] [ 89. 94. 28.1 21. ] [ 137. 168. 43.1 33. ]]
- Рекурсивное исключение признаков
Метод рекурсивного исключения признаков (recursive feature elimination, RFE) реализует следующий алгоритм: модель обучается на исходном наборе признаков и оценивает их значимость, затем исключается один или несколько наименее значимых признаков, модель обучается на оставшихся признаках, и так далее, пока не останется заданное количество лучших признаков. В документации scikit-learn вы можете подробнее прочитать о классе RFE.
В примере ниже метод RFE применяется в сочетании с логистической регрессией для отбора 3-х лучших признаков. Для совместного использования с RFE можно выбирать различные модели, важно лишь, чтобы они были достаточно эффективны и совместимы с RFE.
# Feature Extraction with RFE from pandas import read_csv from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression # load data url = "https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] # feature extraction model = LogisticRegression() rfe = RFE(model, 3) fit = rfe.fit(X, Y) print("Num Features: %d") % fit.n_features_ print("Selected Features: %s") % fit.support_ print("Feature Ranking: %s") % fit.ranking_
Мы видим, что в результате были отобраны 3 лучших признака: preg, mass, pedi. Отобранные признаки помечены значением «True» в массиве support_ и значением «1» в массиве ranking_.
Num Features: 3 Selected Features: [ True False False False False True True False] Feature Ranking: [1 2 3 5 6 1 1 4]
- Метод главных компонент
Метод главных компонент (principal component analysis, PCA) позволяет уменьшить размерность данных с помощью преобразования на основе линейной алгебры. Пользователь может задать требуемое количество измерений (главных компонент) в результирующих данных.
В примере ниже мы выделяем 3 главных компоненты с помощью PCA.
Подробная информация о классе PCA доступна в документации scikit-learn. Если вас заинтересовала математика PCA, обратитесь к статье в Википедии.
# Feature Extraction with PCA import numpy from pandas import read_csv from sklearn.decomposition import PCA # load data url = "https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] # feature extraction pca = PCA(n_components=3) fit = pca.fit(X) features = fit.transform(X) # summarize components print("Explained Variance: %s") % fit.explained_variance_ratio_ print(features[0:5,:])
Как видим, результат преобразования (3 главных компоненты) совсем не похож на исходные данные.
Explained Variance: [ 0.88854663 0.06159078 0.02579012] [[ -7.57146549e+01 3.59507826e+01 -7.26078895e+00] [ -8.23582676e+01 -2.89082132e+01 -5.49667139e+00] [ -7.46306434e+01 6.79064965e+01 1.94618081e+01] [ 1.10774227e+01 -3.48984859e+01 -5.30177923e-02] [ 8.97437881e+01 2.74693708e+00 2.52128586e+01]]\
- Отбор на основе важности признаков
Ансамблевые алгоритмы на основе деревьев решений, такие как случайный лес (random forest), позволяют оценить важность признаков.
В представленном ниже примере мы обучаем классификатор ExtraTreesClassifier, чтобы с его помощью определить важность признаков. Подробнее о классе ExtraTreesClassifier можно узнать из документации scikit-learn.
# Feature Importance with Extra Trees Classifier from pandas import read_csv from sklearn.ensemble import ExtraTreesClassifier # load data url = "https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] # feature extraction model = ExtraTreesClassifier() model.fit(X, Y) print(model.feature_importances_)
Мы получили оценки для каждого признака. Чем больше значение оценки, тем важнее признак. Таким образом, согласно данному методу отбора, тремя наиболее важными признаками являются: plas, age и mass.
[ 0.11070069 0.2213717 0.08824115 0.08068703 0.07281761 0.14548537 0.12654214 0.15415431]
Заключение
В этой статье мы рассмотрели 4 метода отбора признаков на Python с применением библиотеки scikit-learn:
- Одномерный отбор признаков.
- Рекурсивное исключение признаков.
- Метод главных компонент.
- Отбор на основе важности признаков.