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

Ансамбль/Классификация голосов в Python с помощью Scikit-Learn

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

Автор оригинала: Dan Nelson.

Вступление

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

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

Что такое Ансамблевые модели в машинном обучении?

Кредит: Pixabay

ансамбль

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

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

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

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

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

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

Подытожим:

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

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

Различные Методы Классификации Ансамблей

Упаковка в мешки

Кредит: Викисклад

ensemble_bagging

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

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

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

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

Стимулирование

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

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

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

Если вы хотите узнать больше о градиентном бустинге и теории, лежащей в его основе, мы уже говорили об этом в предыдущей статье.

Штабелирования

Кредит: Викисклад

ensemble_stacking

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

Примеры Реализаций

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

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

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

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

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

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

import pandas as pd
import numpy as np
import warnings

from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.metrics import accuracy_score, f1_score, log_loss
from sklearn.model_selection import train_test_split, KFold, cross_val_score

from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import VotingClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.ensemble import AdaBoostClassifier, RandomForestClassifier, ExtraTreesClassifier

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

training_data = pd.read_csv("train.csv")
testing_data = pd.read_csv("test.csv")

def get_nulls(training, testing):
    print("Training Data:")
    print(pd.isnull(training).sum())
    print("Testing Data:")
    print(pd.isnull(testing).sum())

get_nulls(training_data, testing_data)

Как это бывает, есть много пропущенных значений в категориях Возраст и Кабина .

Training Data:
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64
Testing Data:
PassengerId      0
Pclass           0
Name             0
Sex              0
Age             86
SibSp            0
Parch            0
Ticket           0
Fare             1
Cabin          327
Embarked         0
dtype: int64

Мы начнем с того, что отбросим некоторые столбцы, которые, скорее всего, будут бесполезны – столбец Кабина и столбец Билет . Столбец Cabin имеет слишком много пропущенных значений, а столбец Ticket просто состоит из слишком большого количества категорий, чтобы быть полезным.

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

# Drop the cabin column, as there are too many missing values
# Drop the ticket numbers too, as there are too many categories
# Drop names as they won't really help predict survivors

training_data.drop(labels=['Cabin', 'Ticket', 'Name'], axis=1, inplace=True)
testing_data.drop(labels=['Cabin', 'Ticket', 'Name'], axis=1, inplace=True)

# Taking the mean/average value would be impacted by the skew
# so we should use the median value to impute missing values

training_data["Age"].fillna(training_data["Age"].median(), inplace=True)
testing_data["Age"].fillna(testing_data["Age"].median(), inplace=True)
training_data["Embarked"].fillna("S", inplace=True)
testing_data["Fare"].fillna(testing_data["Fare"].median(), inplace=True)

get_nulls(training_data, testing_data)

Теперь мы видим, что больше нет пропущенных значений:

Training Data:
PassengerId    0
Survived       0
Pclass         0
Name           0
Sex            0
Age            0
SibSp          0
Parch          0
Fare           0
Embarked       0
dtype: int64
Testing Data:
PassengerId    0
Pclass         0
Name           0
Sex            0
Age            0
SibSp          0
Parch          0
Fare           0
Embarked       0
dtype: int64

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

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

encoder_1 = LabelEncoder()
# Fit the encoder on the data
encoder_1.fit(training_data["Sex"])

# Transform and replace training data
training_sex_encoded = encoder_1.transform(training_data["Sex"])
training_data["Sex"] = training_sex_encoded
test_sex_encoded = encoder_1.transform(testing_data["Sex"])
testing_data["Sex"] = test_sex_encoded

encoder_2 = LabelEncoder()
encoder_2.fit(training_data["Embarked"])

training_embarked_encoded = encoder_2.transform(training_data["Embarked"])
training_data["Embarked"] = training_embarked_encoded
testing_embarked_encoded = encoder_2.transform(testing_data["Embarked"])
testing_data["Embarked"] = testing_embarked_encoded

# Any value we want to reshape needs be turned into array first
ages_train = np.array(training_data["Age"]).reshape(-1, 1)
fares_train = np.array(training_data["Fare"]).reshape(-1, 1)
ages_test = np.array(testing_data["Age"]).reshape(-1, 1)
fares_test = np.array(testing_data["Fare"]).reshape(-1, 1)

# Scaler takes arrays
scaler = StandardScaler()

training_data["Age"] = scaler.fit_transform(ages_train)
training_data["Fare"] = scaler.fit_transform(fares_train)
testing_data["Age"] = scaler.fit_transform(ages_test)
testing_data["Fare"] = scaler.fit_transform(fares_test)

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

# Now to select our training/testing data
X_features = training_data.drop(labels=['PassengerId', 'Survived'], axis=1)
y_labels = training_data['Survived']

print(X_features.head(5))

# Make the train/test data from validation

X_train, X_val, y_train, y_val = train_test_split(X_features, y_labels, test_size=0.1, random_state=27)

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

Простой Подход К Усреднению

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

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

LogReg_clf = LogisticRegression()
DTree_clf = DecisionTreeClassifier()
SVC_clf = SVC()

LogReg_clf.fit(X_train, y_train)
DTree_clf.fit(X_train, y_train)
SVC_clf.fit(X_train, y_train)

LogReg_pred = LogReg_clf.predict(X_val)
DTree_pred = DTree_clf.predict(X_val)
SVC_pred = SVC_clf.predict(X_val)

averaged_preds = (LogReg_pred + DTree_pred + SVC_pred)//3
acc = accuracy_score(y_val, averaged_preds)
print(acc)

Вот точность, которую мы получили от этого метода:

0.8444444444444444

Пример классификации Голосования\Укладки

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

Классификатор Голосования принимает в качестве аргументов список различных оценок и метод голосования. Метод hard voting использует предсказанные метки и систему правил большинства, в то время как метод soft voting предсказывает метку на основе argmax/наибольшего предсказанного значения суммы предсказанных вероятностей.

После того как мы обеспечим желаемые классификаторы, нам нужно подогнать полученный ансамблевый объект классификатора. Затем мы можем получить прогнозы и использовать метрики точности:

voting_clf = VotingClassifier(estimators=[('SVC', SVC_clf), ('DTree', DTree_clf), ('LogReg', LogReg_clf)], voting='hard')
voting_clf.fit(X_train, y_train)
preds = voting_clf.predict(X_val)
acc = accuracy_score(y_val, preds)
l_loss = log_loss(y_val, preds)
f1 = f1_score(y_val, preds)

print("Accuracy is: " + str(acc))
print("Log Loss is: " + str(l_loss))
print("F1 Score is: " + str(f1))

Вот что метрики должны сказать о производительности Классификатора голосования :

Accuracy is: 0.8888888888888888
Log Loss is: 3.8376684749044165
F1 Score is: 0.8484848484848486

Пример классификации Мешков

Вот как мы можем реализовать классификацию мешков с помощью Scikit-Learn. Классификатор Склеарна Bagging Classifier принимает выбранную классификационную модель, а также количество оценок, которые вы хотите использовать – вы можете использовать такую модель, как Логистическая регрессия или Деревья решений.

Sklearn также предоставляет доступ к классификатору Random Forest и ExtraTreesClassifier , которые являются модификациями классификации дерева решений. Эти классификаторы также могут использоваться вместе с инструментом перекрестной проверки K-fold.

Здесь мы сравним несколько различных подходов к классификации мешков, распечатав средние результаты K-кратной перекрестной валидации:

logreg_bagging_model = BaggingClassifier(base_estimator=LogReg_clf, n_estimators=50, random_state=12)
dtree_bagging_model = BaggingClassifier(base_estimator=DTree_clf, n_estimators=50, random_state=12)
random_forest = RandomForestClassifier(n_estimators=100, random_state=12)
extra_trees = ExtraTreesClassifier(n_estimators=100, random_state=12)

def bagging_ensemble(model):
    k_folds = KFold(n_splits=20, random_state=12)
    results = cross_val_score(model, X_train, y_train, cv=k_folds)
    print(results.mean())

bagging_ensemble(logreg_bagging_model)
bagging_ensemble(dtree_bagging_model)
bagging_ensemble(random_forest)
bagging_ensemble(extra_trees)

Вот результаты, которые мы получили из объявлений:

0.7865853658536585
0.8102439024390244
0.8002439024390245
0.7902439024390244

Пример Классификации Форсирования

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

Scikit-Learn имеет встроенный классификатор AdaBoost , который принимает в качестве первого аргумента заданное количество оценок. Мы можем попробовать использовать цикл for, чтобы увидеть, как изменяется производительность классификации при различных значениях, а также объединить его с инструментом перекрестной проверки K-Foldes:

k_folds = KFold(n_splits=20, random_state=12)

num_estimators = [20, 40, 60, 80, 100]

for i in num_estimators:
    ada_boost = AdaBoostClassifier(n_estimators=i, random_state=12)
    results = cross_val_score(ada_boost, X_train, y_train, cv=k_folds)
    print("Results for {} estimators:".format(i))
    print(results.mean())

Вот результаты, которые мы получили:

Results for 20 estimators:
0.8015243902439024
Results for 40 estimators:
0.8052743902439025
Results for 60 estimators:
0.8053048780487805
Results for 80 estimators:
0.8040243902439024
Results for 100 estimators:
0.8027743902439024

Подведение Итогов

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

Scikit-Learn позволяет легко создавать экземпляры различных ансамблевых классификаторов. Эти объекты ансамбля могут быть объединены с другими инструментами Scikit-Learn, такими как перекрестная проверка K-Folds.

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