Вступление
Модели классификации ансамблей могут быть мощными инструментами машинного обучения, способными достигать превосходной производительности и хорошо обобщать новые, невидимые наборы данных.
Ценность ансамблевого классификатора заключается в том, что, объединяя предсказания нескольких классификаторов, он может исправлять ошибки, сделанные любым отдельным классификатором, что приводит к повышению точности в целом. Давайте рассмотрим различные методы классификации ансамблей и посмотрим, как эти классификаторы могут быть реализованы в Scikit-Learn.
Что такое Ансамблевые модели в машинном обучении?
Кредит: Pixabay
Ансамблевые модели-это метод ансамблевого обучения , который объединяет различные алгоритмы вместе. В этом смысле это мета-алгоритм, а не сам алгоритм. Методы ансамблевого обучения ценны тем, что они могут улучшить производительность прогностической модели.
Методы ансамблевого обучения основаны на идее, что связывание предсказаний нескольких классификаторов вместе приведет к повышению производительности либо за счет повышения точности предсказания, либо за счет уменьшения таких аспектов, как смещение и дисперсия.
В общем случае ансамблевая модель попадает в одну из двух категорий: последовательные подходы и параллельные подходы .
Модель последовательного ансамбля оперирует тем, что базовые учащиеся/модели генерируются последовательно. Последовательные методы ансамбля обычно используются для повышения общей производительности, поскольку модель ансамбля может компенсировать неточные предсказания путем повторного взвешивания примеров, которые ранее были неправильно классифицированы. Примечательным примером этого является AdaBoost .
Параллельная модель-это, как вы можете догадаться, методы, основанные на параллельном создании и обучении базовых учащихся. Параллельные методы направлены на снижение частоты ошибок путем параллельного обучения многих моделей и усреднения результатов. Примечательным примером параллельного метода является классификатор случайных лесов .
Другой способ думать об этом-это различие между однородными и гетерогенными учащимися. В то время как большинство методов ансамблевого обучения используют однородных базовых учащихся (многие из тех же типов учащихся), некоторые методы ансамбля используют гетерогенных учащихся (различные алгоритмы обучения, объединенные вместе).
Подытожим:
- Последовательные модели пытаются повысить производительность путем повторного взвешивания примеров, и модели генерируются последовательно.
- Параллельные модели работают путем усреднения результатов после обучения многих моделей одновременно.
Теперь мы рассмотрим различные методы использования этих моделей для решения задач классификации машинного обучения.
Различные Методы Классификации Ансамблей
Упаковка в мешки
Кредит: Викисклад
Bagging , также известный как bootstrap aggregating , представляет собой метод классификации, который направлен на уменьшение дисперсии оценок путем усреднения нескольких оценок вместе. Пакетирование создает подмножества из основного набора данных, на котором обучаются учащиеся.
Для агрегирования прогнозов различных классификаторов используется либо усреднение для регрессии, либо подход голосования для классификации (основанный на решении большинства).
Одним из примеров метода классификации мешков является классификатор случайных лесов . В случае классификатора случайных лесов все отдельные деревья обучаются на другой выборке набора данных.
Дерево также обучается с использованием случайных выборок объектов. Когда результаты усредняются вместе, общая дисперсия уменьшается, и в результате модель работает лучше.
Стимулирование
Алгоритмы бустинга способны брать слабые, неэффективные модели и преобразовывать их в сильные модели. Идея алгоритмов повышения эффективности заключается в том, что вы присваиваете наборам данных множество слабых моделей обучения, а затем веса для неправильно классифицированных примеров корректируются во время последующих раундов обучения.
Предсказания классификаторов агрегируются, а затем окончательные предсказания делаются с помощью взвешенной суммы (в случае регрессий) или взвешенного большинства голосов (в случае классификации).
AdaBoost является одним из примеров метода повышающего классификатора, как и Градиентный бустинг, который был получен из вышеупомянутого алгоритма.
Если вы хотите узнать больше о градиентном бустинге и теории, лежащей в его основе, мы уже говорили об этом в предыдущей статье.
Штабелирования
Кредит: Викисклад
Алгоритмы укладки представляют собой ансамблевый метод обучения, который сочетает в себе решение различных регрессионных или классификационных алгоритмов. Компонентные модели обучаются на всем обучающем наборе данных. После того, как эти модели компонентов обучены, метамодель собирается из различных моделей, а затем обучается на выходах моделей компонентов. Этот подход обычно создает гетерогенный ансамбль, поскольку компонентные модели обычно представляют собой различные алгоритмы.
Примеры Реализаций
Теперь, когда мы изучили различные методы, которые мы можем использовать для создания ансамблевых моделей, давайте посмотрим, как мы могли бы реализовать классификатор, используя различные методы.
Однако, прежде чем мы сможем рассмотреть различные способы реализации ансамблевых классификаторов, нам нужно выбрать набор данных для использования и выполнить некоторую предварительную обработку набора данных.
Мы будем использовать набор данных 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.
Если вы хотите узнать больше о подходящем использовании ансамблевых классификаторов и теориях, лежащих в их основе, я предлагаю проверить ссылки, найденные здесь или здесь .!