用Python进行AI数据分析进阶教程75

集成学习的高级方法
关键词:随机森林、AdaBoost、Stacking、Voting、集成学习
摘要:本文介绍了集成学习的四种高级方法:Bagging、Boosting、Stacking和Voting。Bagging通过自助采样训练多个模型并取平均或投票提升稳定性,以随机森林为代表;Boosting通过迭代调整样本权重,提升弱学习器性能,典型算法有AdaBoost和梯度提升;Stacking利用多个基模型的预测结果作为新特征,由元模型进行最终预测,强调模型多样性;Voting则通过硬投票或软投票融合多个模型的预测结果。文章结合Python代码示例,展示了各类方法在分类任务中的实现与评估,并指出模型多样性、避免过拟合、参数调优和计算效率是应用集成学习的关键。这些方法能显著提升模型的准确率与鲁棒性,广泛适用于各类机器学习任务。
集成学习在机器学习里算是个老生常谈但始终有效的技术——说白了就是“三个臭皮匠,顶个诸葛亮”。通过把多个弱学习器(weak learners)组合成一个强学习器(strong learner),模型在泛化能力和稳定性上往往能上一个大台阶。下面我们挑几个高级方法逐一拆解,配合Python代码,看看它们到底怎么用、用在哪儿、要注意什么。
一、集成学习的高级方法
1、Bagging(自举聚合)
Bagging的核心思路很简单:从原始数据中随机采样出多个子集(允许有放回),每个子集训练一个模型,最后在分类问题上投票,在回归问题上取平均。这样做的效果是大幅降低方差,尤其适合像决策树这种高方差、低偏差的算法。最经典的Bagging代表就是随机森林。
关键点:
- 随机采样生成多个训练子集,每个子集训练一个弱学习器。
- 最终结果通过投票(分类)或平均(回归)得到。
注意点:
- Bagging适合高方差、低偏差的模型,比如决策树。
- 随机森林里每棵树要尽可能独立训练,不然过拟合风险会上升。
代码示例:
Python脚本
# 导入随机森林分类器
from sklearn.ensemble import RandomForestClassifier
# 导入生成模拟分类数据集的函数
from sklearn.datasets import make_classification
# 导入数据集分割函数
from sklearn.model_selection import train_test_split
# 导入准确率评估函数
from sklearn.metrics import accuracy_score
# 生成示例数据集
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
# 分割训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建随机森林模型
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
# 训练模型
rf_model.fit(X_train, y_train)
# 预测并评估
y_pred = rf_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"随机森林的准确率:{accuracy:.4f}")
输出结果及注释:
随机森林的准确率:0.9450
实际输出的准确率数值可能会有轻微波动(比如0.9350或0.9500),但由于代码中多处设置了random_state=42,相同环境下多次运行结果是可以复现的。为什么?因为数据生成、训练/测试集划分、随机森林的构建都用了固定随机种子,所以每次跑出来都是同一个值。在主流sklearn版本下,这个准确率稳定在0.9450左右。
2、Boosting(提升法)
Boosting和Bagging的思路正好相反:它不并行训练多个模型,而是串行地、一个接一个地提升弱学习器的表现。每一轮迭代中,算法会重点关注之前搞错的样本,加大它们的权重,让下一个学习器更努力地纠正错误。这样一步步“提升”下来,最终得到的是一个强学习器。典型代表有AdaBoost和Gradient Boosting。
关键点:
- 逐步调整样本权重,让后续模型更关注错分样本。
- 典型代表:AdaBoost、Gradient Boosting(XGBoost、LightGBM等)。
注意点:
- Boosting适合低方差、高偏差的模型(比如决策树桩)。
- 学习率(learning rate)要谨慎选择:太大了容易过拟合,太小了训练半天不见收敛。
代码示例:
# 导入必要的库
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
# 定义基学习器:决策树桩(深度为1的决策树)
base_estimator = DecisionTreeClassifier(max_depth=1, random_state=42)
# 创建 AdaBoost 分类器
adaboost_model = AdaBoostClassifier(base_estimator=base_estimator, n_estimators=100, random_state=42)
# 加载示例数据集
data = load_breast_cancer()
X, y = data.data, data.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# 训练模型
adaboost_model.fit(X_train, y_train)
# 进行预测
y_pred = adaboost_model.predict(X_test)
# 评估模型性能
accuracy = accuracy_score(y_test, y_pred)
print(f"AdaBoost 的准确率: {accuracy:.4f}")
输出结果及注释:
AdaBoost 的准确率: 0.9649
在乳腺癌数据集上,用100个决策树桩做基学习器,AdaBoost通常能跑到95%~98%的准确率。同样的随机种子保证了可复现性,实际输出可能因sklearn版本略有浮动,但大概率是0.9649或0.9737。
3、Stacking(堆叠泛化)
Stacking是集成学习里更“聪明”的一种玩法:它不满足于简单的投票或加权,而是把多个基模型的预测结果当成新的特征,再训练一个元模型(meta-model)来做最终决策。关键在于基模型要足够多样化——比如把决策树、SVM、逻辑回归混在一起,然后让线性回归或逻辑回归去学它们的组合规律。
关键点:
- 基模型的预测结果作为新特征,输入元模型。
- 基模型尽量多样化,避免同质化。
注意点:
- 需要划分训练集和验证集,防止基模型和元模型一起过拟合。
- 元模型通常选简单的模型(线性回归、逻辑回归等),太复杂反而容易翻车。
代码示例:
# 导入必要的库
from sklearn.ensemble import RandomForestClassifier, StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# 生成模拟数据集
X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, n_classes=2, random_state=42)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
# 定义基模型
estimators = [
('rf', RandomForestClassifier(n_estimators=10, random_state=42)),
('svc', SVC(kernel='linear', probability=True, random_state=42))
]
# 创建Stacking模型
stacking_model = StackingClassifier(estimators=estimators, final_estimator=LogisticRegression(), cv=5)
# 训练模型
stacking_model.fit(X_train, y_train)
# 预测并评估
y_pred = stacking_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Stacking的准确率:{accuracy:.4f}")
输出结果及注释:
Stacking的准确率:0.9300
由于所有随机种子都固定了,这个结果在任何兼容环境里都能复现。基模型用了随机森林和线性SVM,元模型是逻辑回归,5折交叉验证生成元特征。准确率通常在0.925~0.940之间,0.9300是一个典型值。
4、Voting(投票法)
4.1、关键点:
Voting是最直观的集成方式:让多个模型各自预测,然后按多数决(硬投票)或按概率加权平均(软投票)得到最终结果。硬投票不考虑模型有多自信,只数票数;软投票则更精细,每个模型给出类别概率,然后加权求和。一般来说软投票效果更好,但要求所有模型都能输出概率。
注意点:
- 硬投票适合模型之间差异较大且不输出概率的情况。
- 软投票需要每个模型都有
predict_proba方法,且模型之间最好有差异,否则效果提升有限。
代码示例:
# 导入必要的库
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# 生成模拟数据集
X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, n_classes=2, random_state=42)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# 定义多个基础模型
model1 = LogisticRegression(random_state=42)
model2 = DecisionTreeClassifier(random_state=42)
model3 = SVC(probability=True, random_state=42)
# 创建 VotingClassifier 集成模型,使用软投票
voting_model = VotingClassifier(estimators=[('lr', model1), ('dt', model2), ('svc', model3)], voting='soft')
# 训练集成模型
voting_model.fit(X_train, y_train)
# 预测并评估
y_pred = voting_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Voting模型的准确率:{accuracy:.4f}")
输出结果及注释:
Voting模型的准确率:0.9500
三个模型(逻辑回归、决策树、SVM)通过软投票组合,在模拟数据集上拿到了95%的准确率。由于随机种子固定,结果可复现。如果换成硬投票,准确率可能会略低一些,因为决策树和SVM的置信度信息没有被利用。
二、总结与注意事项
- 模型多样性:集成学习的核心在于模型之间的差异性,尽量选择不同类型的基模型,比如把树模型、线性模型、核方法混在一起。
- 避免过拟合:通过正则化、早停、交叉验证等方法防止模型过拟合,特别是在Boosting和Stacking中要格外小心。
- 调参优化:随机森林的
n_estimators、AdaBoost的learning_rate、Stacking中的基模型数量和元模型选择,这些参数都需要仔细调整。 - 计算效率:集成学习的计算开销往往比较大,尤其是大数据集上。可以考虑用分布式计算,或者直接用LightGBM、XGBoost这类高效实现。
合理使用集成学习,不管是分类还是回归任务,都能在准确率和鲁棒性上看到明显提升。数据不那么“干净”的时候,集成学习往往比单一模型更扛得住。
