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

Основные причины использовать выбор функций:

  • Чтобы быстрее обучить модель машинного обучения.
  • Для повышения точности модели, если выбрано оптимизированное подмножество.
  • Чтобы уменьшить сложность модели.
  • Чтобы уменьшить переобучение и облегчить интерпретацию.

Методы выбора функций, которые просты в использовании и также дают хорошие результаты:

A) Методы фильтрации

  1. Удаление постоянных функций
  2. Одномерный выбор
  3. Важность функции
  4. Матрица корреляции с тепловой картой

Отказ от постоянных функций

В этом фильтре мы можем удалить функции с постоянными значениями, которые на самом деле не важны для решения задачи.

В Python код для применения этого с использованием функции Sklearn VarianceThreshhold выглядит следующим образом:

from sklearn.feature_selection import VarianceThreshold
var_thres=VarianceThreshold(threshold=0)
var_thres.fit(data)
data.columns[var_thres.get_support()]
constant_columns = [column for column in data.columns
if column not in data.columns[var_thres.get_support()]]
data.drop(constant_columns,axis=1)

Одномерный выбор

В этом типе выбора статистические тесты используются для выбора тех переменных / характеристик, которые имеют наиболее сильную связь с переменной результата / выхода.

Библиотека scikit-learn предоставляет класс SelectKBest, который можно использовать с набором различных статистических тестов для выбора определенного количества функций.

  • Коэффициент корреляции Пирсона: f_regression ()
  • ANOVA: f_classif ()
  • Хи-квадрат: chi2 ()

В приведенном ниже примере используется статистический тест хи-квадрат (хи²) для неотрицательных характеристик, чтобы выбрать 10 лучших функций из набора данных прогнозирования диапазона цен для мобильных устройств.

Чтобы понять Chi2, нам нужно понять несколько терминов, как показано ниже:

Степени свободы означает максимальное количество логически независимых значений, которые могут изменяться. Проще говоря, его можно определить как общее количество наблюдений за вычетом количества независимых ограничений, наложенных на наблюдения.

Тест хи-квадрат используется в статистике для проверки независимости двух событий. Учитывая данные двух переменных, мы можем получить наблюдаемое число O и ожидаемое число E. Хи-квадрат измеряет, как ожидаемое число E и наблюдаемое число O отклоняются друг от друга.

Xc2= ∑(Oi — Ei )2 / Ei

Где:

c = степень свободы,

O = наблюдаемое значение (я)

E = ожидаемое значение (я)

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

В Python этот тип фильтрации можно выполнить с помощью библиотеки SelectKBest и chi2 из sklearn, как показано в следующем коде:

import pandas as pd
import numpy as np
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
data = pd.read_csv("train.csv")
X = data.iloc[:,0:20]  #independent columns
y = data.iloc[:,-1]    #target column i.e price range

 #apply SelectKBest class to extract top 10 best features 
bestfeatures = SelectKBest(score_func=chi2, k=10) 
fit = bestfeatures.fit(X,y)
dfscores = pd.DataFrame(fit.scores_)
dfcolumns = pd.DataFrame(X.columns)

 #concat two dataframes for better visualization 
featureScores = pd.concat([dfcolumns,dfscores],axis=1) featureScores.columns = ['Specs','Score'] #naming the dataframe columns
featureScores
print(featureScores.nlargest(10,'Score'))  #print 10 best features

Важность функции

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

Вы можете получить важность каждого объекта в вашем наборе данных, используя свойство важности объекта модели.

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

В Python это можно сделать с помощью следующего кода:

from sklearn.ensemble import ExtraTreesClassifier 
import matplotlib.pyplot as plt 
model = ExtraTreesClassifier() 
model.fit(X,y)
print(model.feature_importances_) #use inbuilt class feature_importances of tree based classifiers
#plot graph of feature importances for better visualization feat_importances = pd.Series(model.feature_importances_, index=X.columns) 
feat_importances.nlargest(10).plot(kind='barh') plt.show()

Матрица корреляции с тепловой картой

Корреляция устанавливает связь между переменными и выходной или целевой переменной.

Корреляция может быть положительной (прямо пропорциональной) или отрицательной (обратно пропорциональной).

Тепловая карта позволяет легко определить, какие функции больше всего связаны с целевой переменной, мы построим тепловую карту коррелированных функций, используя библиотеку seaborn.

В Python это можно сделать с помощью следующего кода.

import seaborn as sns
#get correlations of each features in dataset
corrmat = data.corr()
top_corr_features = corrmat.index
plt.figure(figsize=(20,20))
#plot heat map
g=sns.heatmap(data[top_corr_features].corr(),annot=True , cmap=plt.cm.CMRmap_r)
plt.show()

Темный цвет указывает на более высокую корреляцию.

Б) Методы оболочки

Вот некоторые распространенные примеры методов-оберток:

1) Прямой выбор функции

2) Устранение обратной особенности

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

1: Прямой выбор. Прямой выбор - это итерационный метод оптимизации выбора признаков, при котором мы начинаем с отсутствия каких-либо признаков в модели. На каждой итерации мы продолжаем добавлять функцию, которая лучше всего улучшает нашу модель, пока добавление новой переменной не улучшит производительность модели.

В python это можно реализовать как:

1. # step forward feature selection
2.  
3. from sklearn.model_selection import train_test_split
4. from sklearn.ensemble import RandomForestRegressor
5. from sklearn.metrics import r2_score
6. from mlxtend.feature_selection import SequentialFeatureSelector as SFS
7. # select numerical columns:
8.  
9. numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
10. numerical_vars = list(data.select_dtypes(include=numerics).columns)
11. data = data[numerical_vars]
12. # separate train and test sets
13. X_train, X_test, y_train, y_test = train_test_split(
14.  X,Y, test_size=0.3, random_state=0)
15. # find and remove correlated features
16. def correlation(dataset, threshold):
17.  col_corr = set() # Set of all the names of correlated columns
18.  corr_matrix = dataset.corr()
19.  for i in range(len(corr_matrix.columns)):
20.  for j in range(i):
21.  if abs(corr_matrix.iloc[i, j]) > threshold: # we are interested in absolute coeff value
22.  colname = corr_matrix.columns[i] # getting the name of column
23.  col_corr.add(colname)
24.  return col_corr
25.  
26. corr_features = correlation(X_train, 0.8)
27. print('correlated features: ', len(set(corr_features)) )
28. # removed correlated features
29. X_train.drop(labels=corr_features, axis=1, inplace=True)
30. X_test.drop(labels=corr_features, axis=1, inplace=True)
31. X_train.fillna(0, inplace=True)
32.  
33.  
34. # step forward feature selection
35.  
36. from mlxtend.feature_selection import SequentialFeatureSelector as SFS
37.  
38. sfs1 = SFS(RandomForestRegressor(), 
39.  k_features=10, 
40.  forward=True, 
41.  floating=False, 
42.  verbose=2,
43.  scoring='r2',
44.  cv=3)
45.  
46. sfs1 = sfs1.fit(np.array(X_train), y_train)
47. X_train.columns[list(sfs1.k_feature_idx_)]
48. sfs1.k_feature_idx_

2: Обратное исключение: при обратном исключении мы начинаем со всех функций и удаляем самые незначительные особенности на каждой итерации, что улучшает производительность модели. Мы повторяем это до тех пор, пока не будет наблюдаться никаких улучшений при удалении функций.

В python это можно реализовать как:

49. # step backward feature elimination
50.  
51. sfs1 = SFS(RandomForestRegressor(), 
52.  k_features=10, 
53.  forward=False, 
54.  floating=False, 
55.  verbose=2,
56.  scoring='r2',
57.  cv=3)
58.  
59. sfs1 = sfs1.fit(np.array(X_train), y_train)
60. X_train.columns[list(sfs1.k_feature_idx_)]
61. sfs1.k_feature_idx_

3: Рекурсивное исключение функций. Это наиболее «жадный» алгоритм оптимизации, который направлен на поиск наиболее эффективного подмножества функций.

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

В python это можно реализовать как:

from sklearn.svm import SVC
from sklearn.datasets import load_digits
from sklearn.feature_selection import RFE
import matplotlib.pyplot as plt
 
# Load the digits dataset
digits = load_digits()
X = digits.images.reshape((len(digits.images), -1))
y = digits.target
 
# Create the RFE object and rank each pixel
svc = SVC(kernel="linear", C=1)
rfe = RFE(estimator=svc, n_features_to_select=1, step=1)
rfe.fit(X, y)

В) Встроенные методы

1: Регрессия LASSO

Регрессия лассо выполняет регуляризацию L1, которая фактически добавляет штраф, равный абсолютному значению величины коэффициентов.

Регуляризация означает добавление штрафа или наказания к различным параметрам модели машинного обучения, чтобы уменьшить свободу модели и избежать переобучения. При регуляризации линейной модели штраф применяется к коэффициентам, которые умножают каждое из прогнозных значений. Из различных типов регуляризации, Lasso или l1 имеет свойство, позволяющее сводить многие коэффициенты к нулю. Следовательно, эту функцию можно удалить из модели.

В Python это реализовано как:

#load libraries
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Lasso
from sklearn.feature_selection import SelectFromModel
from sklearn.preprocessing import StandardScaler
# different scales, so it helps the regression to scale them
# separate train and test sets
X_train, X_test, y_train, y_test = train_test_split(
X,Y, test_size=0.3,
 random_state=0)
 
scaler = StandardScaler()
scaler.fit(X_train.fillna(0))
# to force the algorithm to shrink some coefficients
 
sel_ = SelectFromModel(Lasso(alpha=100))
sel_.fit(scaler.transform(X_train.fillna(0)), y_train)
# make a list with the selected features and print the outputs
selected_feat = X_train.columns[(sel_.get_support())]

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

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

2: Техники случайного леса / ансамбля

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

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

При классификации мы измеряем примеси либо по коэффициенту Джини, либо по приросту информации / энтропии. В регрессии мы измеряем примеси как дисперсию. Когда мы обучаем дерево, можно вычислить, насколько каждая функция уменьшает примеси. Какая бы особенность ни уменьшала примесь, тем она важнее. В случайных лесах уменьшение примесей от каждой особенности может определить окончательную важность этой особенности.

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

В python это можно реализовать как:

# Import libraries
from sklearn import preprocessing
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
# Encode categorical variables
X = pd.get_dummies(X, prefix_sep='_')
y = LabelEncoder().fit_transform(y)
# Normalize feature vector
X2 = StandardScaler().fit_transform(X)
# Split the dataset
X_train, X_test, y_train, y_test = train_test_split(X2, y, test_size = 0.30, random_state = 0)
# instantiate the classifier with n_estimators = 100
clf = RandomForestClassifier(n_estimators=100, random_state=0)
# fit the classifier to the training set
clf.fit(X_train, y_train)
# predict on the test set
y_pred = clf.predict(X_test)

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

Спасибо за прочтение!

Первоначально опубликовано на https://www.numpyninja.com 14 октября 2020 г.