Ансамблевые методы - это мощный инструмент для построения моделей машинного обучения. Команды, которые используют их в соревнованиях на kaggle, занимают победные места. Ансамбли позволяют увеличить точность модели до 90+, при этом они довольно просты в понимании.
Поэтому я решил осветить эту тему в данной статье и показать реализацию ансамблей с помощью scikit-learn.
Что такое ансамбль?
Метод машинного обучения, где несколько моделей обучаются для решения одной и той же проблемы и объединяются для получения лучших результатов называется ансамблевым методом. Основная предпосылка заключается в том, что результат работы нескольких моделей будет более точен, чем результат только одной модели.
Когда говорится об ансамблях, то вводится понятие слабого ученика(обычные модели вроде линейной регрессии или дерева решений). Множество слабых учеников являются строительными блоками для более сложных моделей. Объединение слабых учеников для улучшения качества модели, уменьшения смещения или разброса, называется сильным учеником.
Виды ансамблевых методов
Наиболее популярными ансамблевыми методами являются: стекинг, бэггинг, бустинг.
Стекинг. Используется несколько разнородных слабых учеников. Их обучают и объединяют для построения прогноза, основанного на результатах различных слабых моделей.
Бэггинг. В этом случае однородные модели обучают на разных наборах данных и объединяют. Получают прогноз путём усреднения. Если использовать в качестве слабого ученика деревья решений, то получится случайный лес RandomForestClassifier / RandomForestRegressor.
Бустинг. При использовании данного метода несколько однородных моделей последовательно обучаются, исправляя ошибки друг друга.
Стекинг
Работа этого типа ансамблей довольно проста. На вход всех слабых прогнозаторов подаётся обучающий набор, каждый прогноз идёт к финальной модели, которая называется смеситель, мета-ученик или мета-модель, после чего та вырабатывает финальный прогноз.
![Обучение мета-модели Обучение мета-модели](https://habrastorage.org/getpro/habr/upload_files/139/8cd/1c9/1398cd1c90c6e69f7e50e3b1fc783c35.png)
При обучении мета-модели используется приём удерживаемого набора. Сначала набор разделяется на 2 части. Слабые ученики обучаются на первой половине обучающего набора, затем на второй. Затем создаётся новый обучающий набор на основе прогнозов, сделанных на прогнозах первой и второй части набора. Таким образом, на каждый образец из входного набора приходится столько прогнозов, сколько слабых учеников в ансамбле (в примере на картинке три). Мета-модель учится прогнозировать значения на основе нового набора.
Код на Python
from sklearn.ensemble import StackingClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
data, target = load_breast_cancer(return_X_y=True)
estimators = [('lr', LogisticRegression()), ('dt', DecisionTreeClassifier())]
modelClf = StackingClassifier(estimators=estimators, final_estimator=SVC())
X_train, X_valid, y_train, y_valid = train_test_split(data, target, test_size=0.3, random_state=12)
modelClf.fit(X_train, y_train)
print(modelClf.score(X_valid, y_valid))
Вывод:
0.9415204678362573
Ссылка на документацию: Классификатор / Регрессор.
Бэггинг
Основная идея бэггинга заключается в том, чтобы обучить несколько одинаковых моделей на разных образцах. Распределение выборки неизвестно, поэтому модели получатся разными.
Для начала генерируется несколько бутстрэп-выборок. Бутстрэп - это случайный выбор данных из датасета и представление их в модель, затем данные возвращаются в датасет и процесс повторяется. После модели делают свои прогнозы на основе бутстрэп-выборок. В случае регрессии прогнозы просто усредняются. В случае же классификации применяется голосование.
![](https://habrastorage.org/getpro/habr/upload_files/e69/3c2/2c7/e693c22c75565b0a4a0bc38220ab5a6b.png)
Если класс предсказывает большинство слабых моделей, то он получает больше голосов и данный класс является результатом предсказывания ансамбля. Это пример жёсткого голосования. При мягком голосовании рассматриваются вероятности предсказывания каждого класса, затем вероятности усредняются и результатом является класс с большой вероятностью.
Код на Python
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.ensemble import BaggingClassifier
data, target = load_breast_cancer(return_X_y=True)
modelClf = BaggingClassifier(base_estimator=LogisticRegression(), n_estimators=50, random_state=12)
X_train, X_valid, y_train, y_valid = train_test_split(data, target, test_size=0.3, random_state=12)
modelClf.fit(X_train, y_train)
print(modelClf.score(X_valid, y_valid))
Вывод:
0.9239766081871345
Ссылка на документацию: Классификатор / Регрессор.
Бустинг
Метод бустинга в чём то схож с методом бэггинга: берётся множество одинаковых моделей и объединяется, чтобы получить сильного ученика. Но разница заключается в том, что модели приспосабливаются к данным последовательно, то есть каждая модель будет исправлять ошибки предыдущей.
Базовые модели для бустинга - это модели с низким разбросом и высоким смещением. Например неглубокие деревья решений. Одна из причин такого выбора моделей - они требуют меньше вычислительных затрат. Ещё бустинг (в отличии от бэггинга) нельзя распараллелить.
Существует два наиболее распространённых алгоритма бустинга - адаптивный бустинг и градиентный бустинг. О них речь пойдёт ниже.
Адаптивный бустинг (AdaBoost)
Данный алгоритм сначала обучает первую базовую модель(допустим деревья решений) на тренировочном наборе. Относительный вес некорректно предсказанных значений увеличивается. На вход второй базовой модели подаются обновлённые веса и модель обучается, после чего вырабатываются прогнозы и цикл повторяется.
Результат работы AdaBoost - это средневзвешенная сумма каждой модели. Спрогнозированным значением ансамбля будет тот, который получает большинство взвешенный голосов
![C - результат работы ансамбля, W - вес, X - значение прогнозатора C - результат работы ансамбля, W - вес, X - значение прогнозатора](https://habrastorage.org/getpro/habr/upload_files/15e/7a4/9d1/15e7a49d1d3aa6f73f26436d24a4285a.png)
Adaboost обновляет веса объектов на каждой итерации. Веса хорошо классифицированных объектов уменьшаются относительно весов неправильно классифицированных объектов. Модели, которые работают лучше, имеют больший вес в окончательной модели ансамбля.
При адаптивном бустинге используется итеративный метод (добавляем слабых учеников одного за другим, просматривая каждую итерацию, чтобы найти наилучшую возможную пару (коэффициент, слабый ученик) для добавления к текущей модели ансамбля) изменения весов. Он работает быстрее, чем аналитический метод.
Код на Python:
from sklearn.datasets import load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier
data, target = load_breast_cancer(return_X_y=True)
modelClf = AdaBoostClassifier(base_estimator=DecisionTreeClassifier(max_depth=2), n_estimators=100, random_state=12)
X_train, X_valid, y_train, y_valid = train_test_split(data, target, test_size=0.3, random_state=12)
modelClf.fit(X_train, y_train)
print(modelClf.score(X_valid, y_valid))
Вывод:
0.9590643274853801
Ссылка на документацию: Классификатор / Регрессор.
Градиентный бустинг
Градиентный бустинг обучает слабые модели последовательно, исправляя ошибки предыдущих. Результатом градиентного бустинга также является средневзвешенная сумма результатов моделей. Принципиальное отличие от Adaboost это способ изменения весов. Адаптивный бустинг использует итеративный метод оптимизации. Градиентный бустинг оптимизируется с помощью градиентного спуска.
Таким образом градиентный бустинг - обобщение адаптивного бустинга для дифференцируемых функций.
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
data, target = load_breast_cancer(return_X_y=True)
modelClf = GradientBoostingClassifier(max_depth=2, n_estimators=150,
random_state=12, learning_rate=1)
X_train, X_valid, y_train, y_valid = train_test_split(data, target,
test_size=0.3, random_state=12)
modelClf.fit(X_train, y_train)
print(modelClf.score(X_valid, y_valid))
Вывод:
0.935672514619883
Ссылка на документацию: Классификатор / Регрессор.
Вывод
Ансамблевые модели являются мощным инструментом для анализа данных. Идея об объединении простых моделей, позволила делать лучшие прогнозы. Но всё же для построения прогнозов сначала необходимо применять более простые модели, потому что используя их можно добиться нужной точности. Если же результаты вас не устраивают, то можно применять ансамбли.
Помимо библиотеки scikit-learn в python есть библиотека XGBoost, которая предоставляет более обширный набор ансамблевых моделей с более точной реализацией.