使用Scikit-learn训练AdaBoost分类器
一、引言
在机器学习中,集成学习方法通过组合多个基学习器来提升整体性能,而AdaBoost(Adaptive Boosting,自适应增强)正是其中最经典的算法之一。AdaBoost由Freund和Schapire于1996年提出,是第一个成功的Boosting算法实现。本文将从理论到实践,详细介绍如何使用Scikit-learn库训练AdaBoost分类器。
二、AdaBoost算法原理
AdaBoost的核心思想是通过迭代训练一系列弱学习器,并根据每个分类器的表现调整样本权重,最终组合成一个强分类器。
具体流程如下:
- 首先在原始数据集上训练第一个弱分类器;
- 找出被错误分类的样本,为这些样本增加权重;
- 在调整权重后的数据集上训练下一个弱分类器;
- 重复上述过程,直到达到预设的迭代次数。
AdaBoost之所以被称为“自适应”,是因为它能根据弱假设的误差率自适应地调整权重——每个弱假设的权重是其准确性的函数。最终,所有弱分类器通过加权投票的方式做出预测,表现更好的分类器获得更大的投票权重。
三、Scikit-learn中的AdaBoostClassifier
Scikit-learn在sklearn.ensemble模块中提供了AdaBoostClassifier类,用于实现AdaBoost分类算法。它是一个元估计器(meta-estimator),首先在原始数据集上拟合一个分类器,然后不断在调整权重后的数据副本上拟合更多分类器,使后续分类器更关注难分类的样本。
3.1 核心参数
AdaBoostClassifier的主要参数如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
estimator |
None |
基估计器(弱学习器)。如果为None,默认使用max_depth=1的决策树(决策树桩) |
n_estimators |
50 |
弱学习器的最大数量。若达到完美拟合则提前停止 |
learning_rate |
1.0 |
每个分类器的权重贡献。学习率与n_estimators之间存在权衡关系 |
algorithm |
'SAMME.R' |
AdaBoost算法实现,可选'SAMME'或'SAMME.R'。SAMME.R使用概率估计,通常效果更好 |
random_state |
None |
随机种子,用于结果可复现 |
注意:在Scikit-learn 1.2版本中,
base_estimator参数已重命名为estimator。
3.2 主要属性
训练完成后,AdaBoostClassifier提供以下重要属性:
estimators_:所有已拟合的子估计器列表estimator_weights_:每个估计器的权重estimator_errors_:每个估计器的分类误差classes_:类别标签feature_importances_:基于 impurity 的特征重要性
四、完整实战示例
下面我们使用Scikit-learn内置的乳腺癌数据集(包含569个样本和30个特征)来演示AdaBoost分类器的完整训练流程。
4.1 环境准备与数据加载
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.model_selection import GridSearchCV
# 加载数据
data = load_breast_cancer()
X = data.data
y = data.target
print(f"样本数量: {X.shape[0]}, 特征数量: {X.shape[1]}")
print(f"类别分布: {np.bincount(y)}")
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
4.2 基础AdaBoost模型训练
# 方式一:使用默认的决策树桩作为弱学习器
ada_default = AdaBoostClassifier(
n_estimators=50,
learning_rate=1.0,
random_state=42
)
ada_default.fit(X_train, y_train)
# 方式二:自定义弱学习器(深度为1的决策树)
base_estimator = DecisionTreeClassifier(max_depth=1)
ada_custom = AdaBoostClassifier(
estimator=base_estimator, # 注意:1.2版本后使用estimator
n_estimators=50,
learning_rate=1.0,
random_state=42
)
ada_custom.fit(X_train, y_train)
# 预测与评估
y_pred = ada_custom.predict(X_test)
print(f"准确率: {accuracy_score(y_test, y_pred):.4f}")
print("\n分类报告:")
print(classification_report(y_test, y_pred))
4.3 决策边界可视化(二分类示例)
以下示例使用Scikit-learn官方示例,在二维数据集上展示AdaBoost的决策边界:
from sklearn.datasets import make_gaussian_quantiles
from sklearn.inspection import DecisionBoundaryDisplay
# 构造非线性可分的二分类数据集
X1, y1 = make_gaussian_quantiles(cov=2.0, n_samples=200, n_features=2, n_classes=2, random_state=1)
X2, y2 = make_gaussian_quantiles(mean=(3, 3), cov=1.5, n_samples=300, n_features=2, n_classes=2, random_state=1)
X = np.concatenate((X1, X2))
y = np.concatenate((y1, -y2 + 1))
# 训练AdaBoost(200个决策树桩)
bdt = AdaBoostClassifier(
DecisionTreeClassifier(max_depth=1),
n_estimators=200,
random_state=42
)
bdt.fit(X, y)
# 绘制决策边界
DecisionBoundaryDisplay.from_estimator(
bdt, X, cmap=plt.cm.Paired,
response_method="predict",
xlabel="Feature 1", ylabel="Feature 2"
)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolor='k', s=20)
plt.title("AdaBoost Decision Boundary")
plt.show()
五、超参数调优
AdaBoost的性能受多个超参数影响,通过网格搜索可以找到最优组合。
# 定义参数网格
param_grid = {
'n_estimators': [50, 100, 200],
'learning_rate': [0.1, 0.5, 1.0, 2.0],
'algorithm': ['SAMME', 'SAMME.R']
}
# 网格搜索
ada = AdaBoostClassifier(
estimator=DecisionTreeClassifier(max_depth=1),
random_state=42
)
grid_search = GridSearchCV(
ada, param_grid, cv=5, scoring='accuracy', n_jobs=-1
)
grid_search.fit(X_train, y_train)
print(f"最佳参数: {grid_search.best_params_}")
print(f"最佳交叉验证得分: {grid_search.best_score_:.4f}")
# 使用最佳参数评估测试集
best_ada = grid_search.best_estimator_
y_pred_best = best_ada.predict(X_test)
print(f"测试集准确率: {accuracy_score(y_test, y_pred_best):.4f}")
超参数调优建议
n_estimators(树的数量) :增加树的数量通常能提升性能,但边际收益递减。实践中可以从50开始尝试。learning_rate(学习率) :学习率与树的数量存在权衡——学习率越小,需要的树越多。estimator(弱学习器) :默认的决策树桩(max_depth=1)是经典选择,但也可尝试更深或不同类型的基学习器。
六、模型评估与解释
# 混淆矩阵
cm = confusion_matrix(y_test, y_pred_best)
print("混淆矩阵:")
print(cm)
# 特征重要性
feature_importance = best_ada.feature_importances_
feature_names = data.feature_names
# 可视化Top 10重要特征
indices = np.argsort(feature_importance)[::-1][:10]
plt.figure(figsize=(10, 6))
plt.bar(range(10), feature_importance[indices])
plt.xticks(range(10), [feature_names[i] for i in indices], rotation=45)
plt.title("Top 10 Feature Importances")
plt.tight_layout()
plt.show()
- 点赞
- 收藏
- 关注作者
评论(0)