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

Что такое выбор функций?

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

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

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

Вы не только сокращаете время обучения и оценки, но и избавляетесь от лишних забот!

Разработка функций против выбора функций:

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

Выбор функций против извлечения функций:

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

Важность выбора функций в машинном обучении

В большинстве случаев победителей в области науки о данных отличает 2 вещи: создание функций и выбор функций.

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

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

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

Способы выбора функций:

В основном есть 3 способа выбора функций:

  1. Методы фильтрации (которые мы увидим в этом блоге)
  2. Метод обертки (прямое, обратное исключение)
  3. Встроенные методы (регрессия Lasso-L1, Ridge-L2)

Метод фильтрации для выбора функции

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

Выбор фильтра Выберите независимые функции с помощью:

  • Нет постоянных переменных
  • Нет / меньше квадратичных постоянных переменных
  • Нет повторяющихся строк
  • Высокая корреляция с целевой переменной
  • Низкая корреляция с другой независимой переменной
  • Более высокий информационный прирост или взаимная информация независимой переменной.

Преимущества методов фильтрации

  • Методы фильтрации не зависят от модели (совместимы)
  • Полностью полагайтесь на функции в наборе данных
  • В вычислительном отношении очень быстро
  • На основе разных статистических методов

Недостаток фильтровальных методов

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

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

Давайте начнем. Вы можете найти мой полный код и наборы данных здесь: https://github.com/shelvi31/Feature-Selection

Импорт набора данных и библиотеки

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

data = pd.read_csv(r"Standard Customer Data.csv", nrows=40000)    #Taking only 40K rows from the start
data.shape
(40000, 371)

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

Разделение данных на обучающие и тестовые наборы

train_x, test_x, train_y, test_y= train_test_split(data.drop("TARGET",axis=1),data.TARGET,test_size=0.2,random_state=41)

#Here, X = data.drop("TARGET",axis=1), Y = data.Target

Шаг: 1 Удаление постоянных функций

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

Удаление постоянных элементов с помощью VarianceThreshold

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

from sklearn.feature_selection import VarianceThreshold
constant_filter = VarianceThreshold(threshold=0)

#Fit and transforming on train data
data_constant = constant_filter.fit_transform(train_x)
print(data_constant.shape)

#Extracting all constant columns using get support function of our filter
constant_columns = [column for column in train_x.columns
                    if column not in train_x.columns[constant_filter.get_support()]]

#No. of constant columns
print(len(constant_columns))

#Constant columns names:
for column in constant_columns:
    print(column)
Output:
(32000, 320)
50
ind_var2_0
ind_var2
ind_var18_0.... coloumn names

Удаление указанных выше постоянных столбцов из нашей базы данных:

data_cons = data.drop(constant_columns,axis=1)
data_cons.shape
(40000, 321)

Раньше длина была 371. Теперь - 320. Чтобы увидеть имена постоянных столбцов:

Шаг 2: Удаление квазипостоянных функций

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

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

Таким образом, вместо того, чтобы передавать 0 в качестве значения для параметра порога, мы передадим 0,01, что означает, что если дисперсия значений в столбце меньше 0,01, удалите этот столбец. Другими словами, удалите столбец функций, в котором примерно 99% значений аналогичны.

qcons_filter = VarianceThreshold(threshold=0.01)

#Fit and transforming on train data
data_qcons = qcons_filter.fit_transform(train_x)
print(data_qcons.shape)

#Extracting all Quasi constant columns using get support function of our filter
qcons_columns = [column for column in train_x.columns
                    if column not in train_x.columns[qcons_filter.get_support()]]

#No. of Quasi constant columns
print(len(qcons_columns))

#Quasi Constant columns names:
for column in qcons_columns:
    print(column)
Output:
(32000, 265)
105
ind_var1
ind_var2_0
ind_var2
ind_var6_0... coloumn names 

Мы получили 105 квазиконстант. Раньше мы получали 50, когда дисперсия равнялась 0. Это, безусловно, лучший результат. Порог, который нужно удерживать, зависит от нас.

Удаление указанных выше квазиконстантных столбцов из нашей базы данных:

data_qcons = data.drop(qcons_columns,axis=1)
data_qcons.shape
(40000, 266)

оставшаяся форма наших данных такова: у нас осталось 266 столбцов!

Шаг 3 Удаление повторяющихся столбцов

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

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

Транспонирование нашего «квазипостоянного» модифицированного набора данных.

data_qcons_t = data_qcons.T
data_qcons_t.shape
(266, 40000)

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

print(data_qcons_t.duplicated().sum())
21

Таким образом, даже после удаления квазипостоянных столбцов у нас есть еще 21 столбец, который нужно удалить, и они дублируются.

Наконец, мы можем удалить повторяющиеся строки с помощью метода drop_duplicates (). Если вы сначала передадите строковое значение параметру keep метода drop_duplicates (), все повторяющиеся строки будут удалены, кроме первой копии. Затем мы перенесем обратно наши новые данные.

Удаление дублированного метода с использованием drop_duplicates ()

data_cons_dup = data_qcons_t.drop_duplicates(keep='first').T
data_cons_dup.shape
(40000, 245)

Теперь у нас есть улучшенный обучающий набор с 245 столбцами.

Шаг: 4 Корреляция характеристик с целевой переменной

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

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

Импорт и обработка базы данных

cardata = pd.read_csv("mpg.csv")
cardata.dropna()
cardata.shape
cardata.columns
Index(['mpg', 'cylinders', 'displacement', 'horsepower', 'weight',
       'acceleration', 'model_year', 'origin', 'name'],
      dtype='object')
# cardata.info()

Обработка категориальной переменной:

Есть 3 категориальные переменные, о которых можно сказать, просмотрев столбцы dtype.

#Updating the horsepower feature to int
cardata["horsepower"]= pd.to_numeric(cardata["horsepower"])

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

# Label Encoding:
    
from sklearn.preprocessing import LabelEncoder
labelencoder = LabelEncoder()
X_en= cardata.iloc[:, 8].values
X_en = labelencoder.fit_transform(X_en)
cardata = cardata.drop(["name","origin"],axis=1)
cardata["name"] = X_en

Создание входных объектов X и целевой переменной y

y= cardata["mpg"]
X = cardata.iloc[:,1:8]
X.head(2)

y.head(2)
0    18.0
1    15.0
Name: mpg, dtype: float64
#Create a data set copy with all the input features after converting them to numeric including target variable
full_data= X.copy()
full_data["mpg"]= y
print(full_data.head(2))

Нахождение корреляции с целевой переменной независимых предикторов:

imp = full_data.drop("mpg", axis=1).apply(lambda x: x.corr(full_data.mpg))
print(imp)
indices = np.argsort(imp)
print(indices)
print(imp[indices])     #Sorted in ascending order

Построение графиков для визуализации

import matplotlib.pyplot as plt

names=['cylinders','displacement','horsepower','weight','acceleration','model year', 'name']
plt.title('Miles Per Gallon')

#Plotting horizontal bar graph
plt.barh(range(len(indices)), imp[indices], color='g', align='center')
plt.yticks(range(len(indices)), [names[i] for i in indices])
plt.xlabel('Relative Importance')
plt.show()

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

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

Пороговое значение корреляции для определения сильно коллинеарных переменных должно составлять ± 0,50 или около этого. Примет абсолютное значение, поскольку имеет значение как отрицательная, так и положительная корреляция.

for i in range(0, len(indices)):
    if np.abs(imp[i])>0.4:
        print(names[i])
cylinders
displacement
horsepower
weight
acceleration
model year

То есть название автомобиля может быть исключено из нашего набора данных согласно нашим наблюдениям на основе взаимосвязи предикторов с целью.

X.drop("name",axis=1);

Шаг 5: корреляция с другими переменными

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

for i in range(0,len(X.columns)):
    for j in  range(0,len(X.columns)):
        if i!=j:
            corr_1=np.abs(X[X.columns[i]].corr(X[X.columns[j]]))
            if corr_1 <0.3:
                print( X.columns[i] , " is not correlated  with ", X.columns[j])
            elif corr_1>0.75:
                print( X.columns[i] , " is highly  correlated  with ", X.columns[j])
cylinders  is highly  correlated  with  displacement
cylinders  is highly  correlated  with  horsepower
cylinders  is highly  correlated  with  weight... and so on 

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

X= X.drop(["cylinders","weight","displacement"],axis=1);

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

Шаг: 6 Обнаружение взаимной информации или получения информации

Согласно Википедии, в теории вероятностей и теории информации взаимная информация (MI) двух случайных величин является мерой взаимной зависимости между двумя переменными. Более конкретно, он количественно определяет «количество информации», полученное об одной случайной величине посредством наблюдения за другой случайной величиной.

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

Мы найдем прирост информации или взаимную информацию независимой переменной по отношению к целевой переменной.

X.info()
X.shape
y.isnull()
y.shape
(398,)
from sklearn.feature_selection import mutual_info_regression
mi = mutual_info_regression(X, y);

Возврат: оценка взаимной информации между каждой функцией и целью.

# Plotting the mutual information

mi = pd.Series(mi)
mi.index = X.columns
mi.sort_values(ascending=False)
mi.sort_values(ascending=False).plot.bar(figsize=(10, 4))

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

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

Разница между методами Filter и Wrapper

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

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

Вот руководство, которое я нашел полезным для других методов выбора функций: https://www.analyticsvidhya.com/blog/2016/12/introduction-to-feature-selection-methods-with-an-example-or-how-to -выбрать-правые-переменные /

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

Ваше здоровье!

Использованная литература:

  1. Https://stackabuse.com/applying-filter-methods-in-python-for-feature-selection
  2. Https://www.analyticsvidhya.com/blog/2016/12/introduction-to-feature-selection-methods-with-an-example-or-how-to-select-the-right-variables/
  3. Https://towardsdatascience.com/feature-selection-in-python-using-filter-method-7ae5cbc4ee05
  4. Http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.VarianceThreshold.html
  5. Https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.mutual_info_regression.html