Рубрики
Без рубрики

Применение методов обертки в Python для выбора объектов

Автор оригинала: Usman Malik.

Вступление

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

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

Методы обертки для выбора объектов

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

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

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

Шаг Вперед Выбор Функции

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

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

Давайте реализуем пошаговый выбор функций в Python. Мы будем использовать набор данных BNP Paribas Cardif Claims Management для этого раздела, как и в нашей предыдущей статье.

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

Предварительная обработка данных

Следующий сценарий импортирует набор данных и необходимые библиотеки, затем удаляет нечисловые столбцы из набора данных, а затем делит набор данных на обучающие и тестовые наборы. Наконец, все столбцы с корреляцией больше 0,8 удаляются. Взгляните на эту статью для подробного объяснения этого сценария:

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

paribas_data = pd.read_csv(r"E:\Datasets\paribas_data.csv", nrows=20000)
paribas_data.shape

num_colums = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
numerical_columns = list(paribas_data.select_dtypes(include=num_colums).columns)
paribas_data = paribas_data[numerical_columns]
paribas_data.shape

train_features, test_features, train_labels, test_labels = train_test_split(
    paribas_data.drop(labels=['target', 'ID'], axis=1),
    paribas_data['target'],
    test_size=0.2,
    random_state=41)

correlated_features = set()
correlation_matrix = paribas_data.corr()
for i in range(len(correlation_matrix .columns)):
    for j in range(i):
        if abs(correlation_matrix.iloc[i, j]) > 0.8:
            colname = correlation_matrix.columns[i]
            correlated_features.add(colname)


train_features.drop(labels=correlated_features, axis=1, inplace=True)
test_features.drop(labels=correlated_features, axis=1, inplace=True)

train_features.shape, test_features.shape
Реализация Пошагового выбора функций в Python

Для выбора наиболее оптимальных функций мы будем использовать функцию Sequential Feature Selector из библиотеки mlxtend . Библиотеку можно загрузить выполнив следующую команду в командной строке anaconda:

conda install -c conda-forge mlxtend

Мы будем использовать Random Классификатор лесов поиск наиболее оптимальных параметров. Используемые критерии оценки будут ROC-AUC . Следующий сценарий выбирает 15 объектов из нашего набора данных, которые дают наилучшую производительность для классификатора случайных лесов:

from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.metrics import roc_auc_score

from mlxtend.feature_selection import SequentialFeatureSelector

feature_selector = SequentialFeatureSelector(RandomForestClassifier(n_jobs=-1),
           k_features=15,
           forward=True,
           verbose=2,
           scoring='roc_auc',
           cv=4)

В приведенном выше скрипте мы передаем классификатор Случайного леса в качестве оценки функции Последовательного селектора признаков|/. Параметр k_features указывает количество объектов для выбора. Здесь вы можете установить любое количество функций. Параметр forward , если он установлен в True , выполняет шаг вперед выбора функции. Параметр verbose используется для регистрации хода выполнения селектора функций, параметр scoring определяет критерии оценки производительности и, наконец, cv относится к кросс-валидационным складкам.

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

features = feature_selector.fit(np.array(train_features.fillna(0)), train_labels)

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

filtered_features= train_features.columns[list(features.k_feature_idx_)]
filtered_features

В выходных данных вы должны увидеть следующие функции:

Index(['v4', 'v10', 'v14', 'v15', 'v18', 'v20', 'v23', 'v34', 'v38', 'v42',
       'v50', 'v51', 'v69', 'v72', 'v129'],
      dtype='object')

Теперь, чтобы увидеть эффективность классификации алгоритма случайного леса, использующего эти 15 функций, выполните следующий сценарий:

clf = RandomForestClassifier(n_estimators=100, random_state=41, max_depth=3)
clf.fit(train_features[filtered_features].fillna(0), train_labels)

train_pred = clf.predict_proba(train_features[filtered_features].fillna(0))
print('Accuracy on training set: {}'.format(roc_auc_score(train_labels, train_pred[:,1])))

test_pred = clf.predict_proba(test_features[filtered_features].fillna(0))
print('Accuracy on test set: {}'.format(roc_auc_score(test_labels, test_pred [:,1])))

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

Accuracy on training set: 0.7072327148174093
Accuracy on test set: 0.7096973252804142

Вы можете видеть, что точность на тренировочных и тестовых наборах довольно схожа, что означает, что наша модель не переоснащена.

Шаг Назад Выбор Функции

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

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

Шаг назад Выбор функций в Python

В этом разделе мы реализуем шаг назад выбор функции на BNP Paribas Cardif Claims Management . Шаг предварительной обработки останется таким же, как и в предыдущем разделе. Единственное изменение будет внесено в параметр forward класса Sequential Feature Selection . В случае выбора функции step backward мы установим этот параметр в False . Выполните следующий сценарий:

from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.metrics import roc_auc_score
from mlxtend.feature_selection import SequentialFeatureSelector

feature_selector = SequentialFeatureSelector(RandomForestClassifier(n_jobs=-1),
           k_features=15,
           forward=False,
           verbose=2,
           scoring='roc_auc',
           cv=4)

features = feature_selector.fit(np.array(train_features.fillna(0)), train_labels)

Чтобы увидеть объект, выбранный в результате исключения шага назад, выполните следующий сценарий:

filtered_features= train_features.columns[list(features.k_feature_idx_)]
filtered_features

Вывод выглядит следующим образом:

Index(['v7', 'v8', 'v10', 'v17', 'v34', 'v38', 'v45', 'v50', 'v51', 'v61',
       'v94', 'v99', 'v119', 'v120', 'v129'],
      dtype='object')

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

clf = RandomForestClassifier(n_estimators=100, random_state=41, max_depth=3)
clf.fit(train_features[filtered_features].fillna(0), train_labels)

train_pred = clf.predict_proba(train_features[filtered_features].fillna(0))
print('Accuracy on training set: {}'.format(roc_auc_score(train_labels, train_pred[:,1])))

test_pred = clf.predict_proba(test_features[filtered_features].fillna(0))
print('Accuracy on test set: {}'.format(roc_auc_score(test_labels, test_pred [:,1])))

Выход выглядит примерно так:

Accuracy on training set: 0.7095207938140247
Accuracy on test set: 0.7114624676445211

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

Исчерпывающий Выбор Функций

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

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

Исчерпывающий выбор функций в Python

В этом разделе мы реализуем шаг назад выбор функции на BNP Paribas Cardif Claims Management . Шаг предварительной обработки останется таким же, как и шаг вперед выбора объекта.

Для реализации исчерпывающего выбора функций мы будем использовать функцию Exclusive Feature Selector из mlxtend.feature_selection библиотека. Класс имеет атрибуты main_features и max_features , которые могут использоваться для указания минимального и максимального количества объектов в комбинации.

Выполните следующий сценарий:

from mlxtend.feature_selection import ExhaustiveFeatureSelector
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.metrics import roc_auc_score

feature_selector = ExhaustiveFeatureSelector(RandomForestClassifier(n_jobs=-1),
           min_features=2,
           max_features=4,
           scoring='roc_auc',
           print_progress=True,
           cv=2)

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

features = feature_selector.fit(np.array(train_features.fillna(0)), train_labels)

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

filtered_features= train_features.columns[list(features.k_feature_idx_)]
filtered_features

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

clf = RandomForestClassifier(n_estimators=100, random_state=41, max_depth=3)
clf.fit(train_features[filtered_features].fillna(0), train_labels)

train_pred = clf.predict_proba(train_features[filtered_features].fillna(0))
print('Accuracy on training set: {}'.format(roc_auc_score(train_labels, train_pred[:,1])))

test_pred = clf.predict_proba(test_features[filtered_features].fillna(0))
print('Accuracy on test set: {}'.format(roc_auc_score(test_labels, test_pred [:,1])))

Вывод

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

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