多类 AdaBoost 决策树

Machine LearningMachine LearningBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,我们将探讨提升算法如何提高多分类问题的预测准确率。我们将使用一个数据集,该数据集通过采用十维标准正态分布构建,并定义了由嵌套的同心十维球体分隔的三个类别,使得每个类别中的样本数量大致相等。

我们将比较 SAMME 和 SAMME.R 算法的性能。SAMME.R 使用概率估计来更新加法模型,而 SAMME 仅使用分类结果。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签页,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/CoreModelsandAlgorithmsGroup(["Core Models and Algorithms"]) sklearn(("Sklearn")) -.-> sklearn/ModelSelectionandEvaluationGroup(["Model Selection and Evaluation"]) sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/tree("Decision Trees") sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/ensemble("Ensemble Methods") sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/metrics("Metrics") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/datasets("Datasets") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/tree -.-> lab-49056{{"多类 AdaBoost 决策树"}} sklearn/ensemble -.-> lab-49056{{"多类 AdaBoost 决策树"}} sklearn/metrics -.-> lab-49056{{"多类 AdaBoost 决策树"}} sklearn/datasets -.-> lab-49056{{"多类 AdaBoost 决策树"}} ml/sklearn -.-> lab-49056{{"多类 AdaBoost 决策树"}} end

导入所需库

我们将首先导入所需的库,包括来自sklearn.datasetsmake_gaussian_quantilesaccuracy_score,来自sklearn.ensembleAdaBoostClassifierDecisionTreeClassifier,以及matplotlib.pyplot

import matplotlib.pyplot as plt
from sklearn.datasets import make_gaussian_quantiles
from sklearn.ensemble import AdaBoostClassifier
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier

加载数据集

我们将使用sklearn.datasets中的make_gaussian_quantiles函数来生成一个数据集。此函数生成各向同性高斯分布,并在类别之间添加分隔,以使问题更具挑战性。

X, y = make_gaussian_quantiles(
    n_samples=13000, n_features=10, n_classes=3, random_state=1
)

分割数据集

我们将把数据集分割为训练集和测试集,使用前 3000 个样本进行训练,其余样本用于测试。

n_split = 3000
X_train, X_test = X[:n_split], X[n_split:]
y_train, y_test = y[:n_split], y[n_split:]

创建并训练模型

我们将创建两个 AdaBoost 模型,一个使用 SAMME,另一个使用 SAMME.R。两个模型都将使用最大深度为 2 且有 300 个估计器的决策树分类器。

bdt_real = AdaBoostClassifier(
    DecisionTreeClassifier(max_depth=2), n_estimators=300, learning_rate=1
)

bdt_discrete = AdaBoostClassifier(
    DecisionTreeClassifier(max_depth=2),
    n_estimators=300,
    learning_rate=1.5,
    algorithm="SAMME",
)

bdt_real.fit(X_train, y_train)
bdt_discrete.fit(X_train, y_train)

测试模型

我们将测试模型,并在每次提升迭代后计算每个模型的测试误差。

real_test_errors = []
discrete_test_errors = []

for real_test_predict, discrete_test_predict in zip(
    bdt_real.staged_predict(X_test), bdt_discrete.staged_predict(X_test)
):
    real_test_errors.append(1.0 - accuracy_score(real_test_predict, y_test))
    discrete_test_errors.append(1.0 - accuracy_score(discrete_test_predict, y_test))

绘制结果

我们将绘制每个模型的测试误差、分类误差和提升权重。

n_trees_discrete = len(bdt_discrete)
n_trees_real = len(bdt_real)

## Boosting might terminate early, but the following arrays are always
## n_estimators long. We crop them to the actual number of trees here:
discrete_estimator_errors = bdt_discrete.estimator_errors_[:n_trees_discrete]
real_estimator_errors = bdt_real.estimator_errors_[:n_trees_real]
discrete_estimator_weights = bdt_discrete.estimator_weights_[:n_trees_discrete]

plt.figure(figsize=(15, 5))

plt.subplot(131)
plt.plot(range(1, n_trees_discrete + 1), discrete_test_errors, c="black", label="SAMME")
plt.plot(
    range(1, n_trees_real + 1),
    real_test_errors,
    c="black",
    linestyle="dashed",
    label="SAMME.R",
)
plt.legend()
plt.ylim(0.18, 0.62)
plt.ylabel("测试误差")
plt.xlabel("树的数量")

plt.subplot(132)
plt.plot(
    range(1, n_trees_discrete + 1),
    discrete_estimator_errors,
    "b",
    label="SAMME",
    alpha=0.5,
)
plt.plot(
    range(1, n_trees_real + 1), real_estimator_errors, "r", label="SAMME.R", alpha=0.5
)
plt.legend()
plt.ylabel("误差")
plt.xlabel("树的数量")
plt.ylim((0.2, max(real_estimator_errors.max(), discrete_estimator_errors.max()) * 1.2))
plt.xlim((-20, len(bdt_discrete) + 20))

plt.subplot(133)
plt.plot(range(1, n_trees_discrete + 1), discrete_estimator_weights, "b", label="SAMME")
plt.legend()
plt.ylabel("权重")
plt.xlabel("树的数量")
plt.ylim((0, discrete_estimator_weights.max() * 1.2))
plt.xlim((-20, n_trees_discrete + 20))

## 防止 y 轴标签重叠
plt.subplots_adjust(wspace=0.25)
plt.show()

总结

在本实验中,我们探究了提升算法如何提高多分类问题的预测准确率。我们使用了一个数据集,该数据集通过采用十维标准正态分布并定义由嵌套的同心十维球体分隔的三个类别来构建。我们比较了 SAMME 和 SAMME.R 算法的性能,并绘制了每个模型的测试误差、分类误差和提升权重。结果表明,SAMME.R 通常比 SAMME 收敛得更快,在较少的提升迭代次数下就能实现更低的测试误差。