Примечание
Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере через JupyterLite или Binder.
Деревья решений с многоклассовым AdaBoost
В этом примере показано, как бустинг может повысить точность предсказаний в задаче многометочной классификации. Он воспроизводит эксперимент, аналогичный представленному на рисунке 1 в работе Zhu et al [1].
Основной принцип AdaBoost (адаптивного бустинга) заключается в последовательном обучении слабых моделей (например, деревьев решений) на многократно пересэмплированных версиях данных. Каждому образцу назначается вес, который корректируется после каждого этапа обучения, так что неправильно классифицированные образцы получают более высокие веса. При пересэмплировании с возвращением учитываются веса, назначенные каждому образцу. Образцы с более высокими весами имеют больше шансов быть выбранными несколько раз в новый набор данных, а образцы с более низкими весами выбираются реже. Это гарантирует, что на последующих итерациях алгоритм сосредоточится на образцах, которые трудно классифицировать.
Список литературы
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause
Создание набора данных
Набор данных для классификации создаётся на основе десятимерного стандартного нормального распределения (\(x\) в \(R^{10}\)) и определения трёх классов, разделённых вложенными концентрическими десяти мерными сферами, так что в каждом классе оказывается примерно одинаковое число образцов (квантили распределения \(\chi^2\)).
from sklearn.datasets import make_gaussian_quantiles
X, y = make_gaussian_quantiles(
n_samples=2_000, n_features=10, n_classes=3, random_state=1
)
Мы разделяем набор данных на 2 части: 70 процентов образцов используются для обучения, а оставшиеся 30 процентов — для тестирования.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, train_size=0.7, random_state=42
)
Обучение AdaBoostClassifier
Мы обучаем AdaBoostClassifier. Оцениватель использует бустинг для повышения точности классификации. Бустинг — это метод обучения слабых моделей (то есть estimator), которые учатся на ошибках предыдущих моделей.
Здесь в качестве слабой модели мы определяем DecisionTreeClassifier и задаём максимальное число листьев равным 8. В реальных условиях этот параметр следует настраивать. Мы задаём довольно низкое значение, чтобы сократить время выполнения примера.
Затем встроенный в алгоритм SAMME AdaBoostClassifier использует правильные или неправильные предсказания текущей слабой модели для обновления весов образцов, применяемых при обучении следующих слабых моделей. Вес самой слабой модели также рассчитывается на основе точности классификации обучающих примеров. Вес слабой модели определяет её влияние на итоговое предсказание ансамбля.
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
weak_learner = DecisionTreeClassifier(max_leaf_nodes=8)
n_estimators = 300
adaboost_clf = AdaBoostClassifier(
estimator=weak_learner,
n_estimators=n_estimators,
random_state=42,
).fit(X_train, y_train)
Анализ
Сходимость AdaBoostClassifier
Чтобы продемонстрировать эффективность бустинга в повышении точности, мы оцениваем ошибку классификации бустированных деревьев и сравниваем её с двумя базовыми оценками. Первая базовая оценка — это misclassification_error, полученная с помощью одной слабой модели (то есть DecisionTreeClassifier), которая служит точкой отсчёта. Вторая базовая оценка получена с помощью DummyClassifier, который предсказывает наиболее часто встречающийся класс в наборе данных.
from sklearn.dummy import DummyClassifier
from sklearn.metrics import accuracy_score
dummy_clf = DummyClassifier()
def misclassification_error(y_true, y_pred):
return 1 - accuracy_score(y_true, y_pred)
weak_learners_misclassification_error = misclassification_error(
y_test, weak_learner.fit(X_train, y_train).predict(X_test)
)
dummy_classifiers_misclassification_error = misclassification_error(
y_test, dummy_clf.fit(X_train, y_train).predict(X_test)
)
print(
"DecisionTreeClassifier's misclassification_error: "
f"{weak_learners_misclassification_error:.3f}"
)
print(
"DummyClassifier's misclassification_error: "
f"{dummy_classifiers_misclassification_error:.3f}"
)
DecisionTreeClassifier's misclassification_error: 0.475 DummyClassifier's misclassification_error: 0.692
После обучения модели DecisionTreeClassifier достигнутая ошибка оказывается ниже ожидаемого значения, которое было бы получено при угадывании метки наиболее часто встречающегося класса, как это делает DummyClassifier.
Теперь мы вычислим misclassification_error, то есть 1 - accuracy аддитивной модели (DecisionTreeClassifier) на каждой итерации бустинга на тестовом наборе, чтобы оценить её качество.
Мы используем staged_predict, которая выполняет столько итераций, сколько обучено оценивателей (то есть соответствует n_estimators). На итерации n при предсказании AdaBoost использует только n первые слабые модели. Мы сравниваем эти предсказания с истинными метками y_test и таким образом определяем, полезно ли добавлять в последовательность новую слабую модель.
Построим график ошибки классификации для разных этапов:
import matplotlib.pyplot as plt
import pandas as pd
boosting_errors = pd.DataFrame(
{
"Number of trees": range(1, n_estimators + 1),
"AdaBoost": [
misclassification_error(y_test, y_pred)
for y_pred in adaboost_clf.staged_predict(X_test)
],
}
).set_index("Number of trees")
ax = boosting_errors.plot()
ax.set_ylabel("Misclassification error on test set")
ax.set_title("Convergence of AdaBoost algorithm")
plt.plot(
[boosting_errors.index.min(), boosting_errors.index.max()],
[weak_learners_misclassification_error, weak_learners_misclassification_error],
color="tab:orange",
linestyle="dashed",
)
plt.plot(
[boosting_errors.index.min(), boosting_errors.index.max()],
[
dummy_classifiers_misclassification_error,
dummy_classifiers_misclassification_error,
],
color="c",
linestyle="dotted",
)
plt.legend(["AdaBoost", "DecisionTreeClassifier", "DummyClassifier"], loc=1)
plt.show()

На графике показана ошибка классификации на тестовом наборе после каждой итерации бустинга. Видно, что после 50 итераций ошибка бустированных деревьев сходится примерно к 0,3, что указывает на существенно более высокую точность по сравнению с одним деревом, как показано пунктирной линией на графике.
Ошибка классификации колеблется, потому что алгоритм SAMME использует дискретные выходы слабых моделей для обучения бустированной модели.
На сходимость AdaBoostClassifier в основном влияют скорость обучения (то есть learning_rate), число используемых слабых моделей (n_estimators) и выразительная способность слабых моделей (например, max_leaf_nodes).
Ошибки и веса слабых моделей
Как упоминалось ранее, AdaBoost — это аддитивная модель с прямым пошаговым построением. Теперь мы рассмотрим взаимосвязь между назначенными слабым моделям весами и их статистическими характеристиками.
Для изучения этой взаимосвязи мы используем атрибуты estimator_errors_ и estimator_weights_ обученного AdaBoostClassifier.
weak_learners_info = pd.DataFrame(
{
"Number of trees": range(1, n_estimators + 1),
"Errors": adaboost_clf.estimator_errors_,
"Weights": adaboost_clf.estimator_weights_,
}
).set_index("Number of trees")
axs = weak_learners_info.plot(
subplots=True, layout=(1, 2), figsize=(10, 4), legend=False, color="tab:blue"
)
axs[0, 0].set_ylabel("Train error")
axs[0, 0].set_title("Weak learner's training error")
axs[0, 1].set_ylabel("Weight")
axs[0, 1].set_title("Weak learner's weight")
fig = axs[0, 0].get_figure()
fig.suptitle("Weak learner's errors and weights for the AdaBoostClassifier")
fig.tight_layout()

На левом графике показана взвешенная ошибка каждой слабой модели на перевзвешенном обучающем наборе на каждой итерации бустинга. На правом графике показаны веса, присвоенные каждой слабой модели и используемые впоследствии для предсказаний итоговой аддитивной модели.
Мы видим, что ошибка слабой модели обратно пропорциональна её весу. Это означает, что аддитивная модель больше доверяет слабой модели с меньшей ошибкой (на обучающем наборе), увеличивая её влияние на итоговое решение. Именно так в AdaBoost после каждой итерации обновляются веса базовых оценивателей.
Математические подробности
Вес слабой модели, обученной на этапе \(m\), обратно пропорционален её ошибке классификации:
где \(\alpha^{(m)}\) и \(err^{(m)}\) — соответственно вес и ошибка \(m\)-й слабой модели, а \(K\) — число классов в задаче классификации.
Ещё одно интересное наблюдение состоит в том, что первые слабые модели в последовательности допускают меньше ошибок, чем последующие.
Это можно объяснить следующим образом: из-за перевзвешивания образцов последующие классификаторы вынуждены пытаться классифицировать более сложные или зашумлённые образцы и игнорировать уже правильно классифицированные. Поэтому общая ошибка на обучающем наборе возрастает. Именно поэтому веса слабых моделей рассчитаны так, чтобы компенсировать более низкую эффективность слабых моделей.
Общее время выполнения скрипта: (0 минут 3.605 секунды)
Похожие примеры
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/ensemble/plot_adaboost_multiclass.html