简介这是一本由杰森·布朗利撰写的Python集成学习速成指南面向已掌握Python基础与常见机器学习库的开发者帮助读者在七天内系统掌握机器学习中的高级集成方法。全书围绕集成学习的基本原理展开逐一讲解装袋集成、随机森林、AdaBoost、梯度提升、投票集成与堆叠集成六种主流技术每课配有可运行的代码示例便于边学边练。资源为单个PDF文档整体仅481KB便于离线阅读与查阅共1个文件内容结构清晰从概念到实战逐步递进。该资料已有108人学习下载适合希望在竞赛或真实项目中提升模型可靠性与准确率的读者。通过本书可快速理解如何组合多个模型来降低预测方差、获得更优性能并能直接借鉴其代码思路应用到自己的预测建模项目中。1. 集成学习为什么单模型不够用七天要过六种组合策略单模型调参调了一个月准确率卡在 0.86 上不去再往下调都是玄学——这是很多人在预测建模项目里遇到过的瓶颈。这时候换个思路不再追求把某一个模型调到极限而是把几个模型的预测结果组合起来用模型的“团队配合”把分数往上推。这条路就是集成学习算法也就是机器学习竞赛里 Top 选手最常用的一类方法。这份《Python 集成学习算法 7 天速成》PDF 就是为这种情况准备的。作者把集成学习拆成七天课程一天一个主题覆盖 Bagging、随机森林、AdaBoost、梯度提升、投票和堆叠六种主流算法每一课都有一套可直接运行的完整代码。资源里反复强调一个前提你不需要是数学天才也不需要是机器学习专家只要熟悉基础 Python、懂一点 NumPy 和 scikit-learn 就能跟下来。如果你是那种“知道怎么调库但不知道模型之间到底什么关系”的开发者这七天正好帮你把集成学习的骨架搭起来。每天 60 秒到 30 分钟照着示例跑一遍再做加分练习基本就能在自己的项目里判断什么时候该用哪种集成。2. 先跑通评估框架把速成课里反复出现的十行代码吃透翻完整份 PDF 你会发现一个有意思的现象七课里只有模型那一行在变剩下的评估代码几乎长得一模一样。也就是说只要先把这个评估框架吃透后面六种算法对你来说就是换 model 行的事。这也是这份资源设计上最省力的地方。2.1 最小环境Python 3、NumPy、scikit-learn 三个就够原文明确假设你已经有 Python 3 的 SciPy 环境并且至少装好了 NumPy。实际跑下来真正起作用的依赖就是 scikit-learn 和 NumPypandas 在这份资源里完全没用到。pip install numpy scikit-learn如果你用的是 Anaconda 或者虚拟环境建议单独建一个项目环境再装避免和系统 Python 打架。我一般会顺手确认一下版本避免踩到老版本缺类的坑。import sklearn print(sklearn.__version__)有一点需要提醒最后一天的堆叠集成用到了 StackingClassifier这个类在 scikit-learn 0.22 版本之前是不存在的。如果你电脑上的 scikit-learn 是 2019 年之前的版本照着一路跑到第七天会直接 ImportError当场翻车。装的时候尽量选新版本至少 0.22 以上。2.2 三件套拆解合成数据、分层重复交叉验证、得分统计第一课里那个 Bagging 示例就是整个框架的模板。我拆开给你看。from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.ensemble import BaggingClassifier # 生成合成分类数据集 X, y make_classification(random_state1) # 配置集成模型 model BaggingClassifier(n_estimators50) # 配置重采样方法10 折 3 次重复的分层交叉验证 cv RepeatedStratifiedKFold(n_splits10, n_repeats3, random_state1) # 用交叉验证评估集成模型 n_scores cross_val_score(model, X, y, scoringaccuracy, cvcv, n_jobs-1) # 报告性能均值与标准差 print(Mean Accuracy: %.3f (%.3f) % (mean(n_scores), std(n_scores)))这段代码背后的逻辑其实是三件事。先看数据make_classification(random_state1)生成一个二分类合成数据集默认 100 个样本、20 个特征random_state 固定是为了让每次运行得到同一份数据方便对照实验。然后是评估策略RepeatedStratifiedKFold(n_splits10, n_repeats3)的意思是做 10 折分层交叉验证并且完整重复 3 次每次用不同的随机划分。分层Stratified保证每一折里正负样本比例和原始数据一致这是分类问题里的标准做法。重复Repeated则是为了减少单次划分带来的偶然性让最终得分更稳定。cross_val_score则是负责执行整个流程把数据切 10 份轮流拿 9 份训练、1 份测试把 10 次的准确率收集起来外部再重复 3 轮最后得到一组 30 个分数。n_jobs-1表示用所有 CPU 核心并行合成数据量小的时候不明显数据量一大就能感觉到差距。这里有个关键的理解点交叉验证只是在评估模型模型本身在每一折里都是重新训练的。所以最后打印出来的Mean Accuracy是模型性能的期望估计括号里的标准差衡量的是模型在不同数据划分下的稳定程度。标准差越小说明模型对数据划分不敏感这是集成方法比起单模型更让人放心的地方。2.3 为什么换 model 行就能跑通所有课scikit-learn 的估计器统一实现了 fit 和 predict 接口cross_val_score并不关心你传进去的是决策树还是随机森林只要这个对象有 fit 方法就能跑。这份资源正是把这个特性用到了极致——七课代码只有在配置模型的那一行有区别其余部分一律复用。所以你看后面几章的代码时不要每段都从头读到尾重点只看三样东西换成了哪个模型类、设了哪些关键参数、默认值是什么。我建议第一次跑的时候不要改任何参数先把Mean Accuracy记下来之后再做“加分项”练习时一次只动一个参数对比前后分数变化。一次改两个参数出了问题你根本不知道是谁引起的。3. Bagging 与随机森林自助采样和特征抽样如何一降再降方差这一章讲资源里的前两种算法。Bagging 和随机森林关系极近随机森林就是 Bagging 加特征抽样。它们解决的是同一个问题——单棵决策树方差太大换个数据划分结果就变拿出去说话都不硬气。3.1 Bagging 的直觉让决策树在自助样本上“吵”起来Bagging 的正式名称是 Bootstrap Aggregating中文常译作装袋。它的做法是从训练数据里有放回地随机抽取样本也就是自助采样生成多个和原始数据集大小相同但内容略有差异的训练集然后在每个训练集上拟合一棵决策树。因为每个自助样本里的数据点不同树之间的预测就会产生差异。最后的预测用投票分类或平均回归把多棵树的结论合并起来。为什么要用决策树当基学习器因为 Bagging 的效果依赖于基学习器的“不稳定”属性。决策树恰好是那种对训练数据极其敏感的模型数据里删掉几行树的结构可能完全变了。这种不稳定在 Bagging 里反而成了优势树与树之间的差异够大投票起来方差才能被压下去。如果你换成线性回归这种低方差模型Bagging 几乎不会带来提升——“集成了个寂寞”。3.2 跑通 BaggingClassifiern_estimators 从 10 到 100代码模板和第二课的完全一样模型行换成 BaggingClassifier 就行。from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.ensemble import BaggingClassifier X, y make_classification(random_state1) # 50 棵决策树的 Bagging 集成 model BaggingClassifier(n_estimators50) cv RepeatedStratifiedKFold(n_splits10, n_repeats3, random_state1) n_scores cross_val_score(model, X, y, scoringaccuracy, cvcv, n_jobs-1) print(Mean Accuracy: %.3f (%.3f) % (mean(n_scores), std(n_scores)))n_estimators50是集成里决策树的数量。这个参数在 Bagging 里是最核心的旋钮树太少方差压不下去树太多训练时间线性增长但准确率在某个点之后基本走平。我在这个合成数据上把树的棵数从 10 依次加到 200真实趋势是这样的n_estimators训练耗时准确率趋势10极短偏保守方差明显50可忽略已经稳定涨得慢200稍长基本走平收益很小这个“边际收益递减”不是玄学是 Bagging 的固有特性。模型间的差异来源有限加树本质是在对同一个分布做多次采样平均采样次数多了之后平均值的方差下降速度会越来越慢。实际项目中我一般从 50 棵起步效果不够再往 100、200 加不推荐一上来就 500纯属浪费算力。3.3 随机森林在特征维度上再加一道抽样随机森林在 Bagging 干的事之外加了一道保险每一棵树在选择分割点时不允许看全部特征只能从随机抽出的一个特征子集里选。这个子集大小由max_features控制分类问题默认值是特征总数的平方根比如 20 个特征时默认每次考虑约 4.5 个特征。特征抽样的作用是进一步降低树之间的相关性。Bagging 让每棵树用不同的行来训练但所有树仍然可以在同一个强特征上做分割结果就是某些树长得还是像。随机森林连候选特征都限制住弱的特征在某些树里获得出场机会树之间的差异性更大平均之后方差压得更低。from sklearn.ensemble import RandomForestClassifier # 随机森林默认 max_features 为 sqrt(特征数) model RandomForestClassifier(n_estimators50) cv RepeatedStratifiedKFold(n_splits10, n_repeats3, random_state1) n_scores cross_val_score(model, X, y, scoringaccuracy, cvcv, n_jobs-1) print(Mean Accuracy: %.3f (%.3f) % (mean(n_scores), std(n_scores)))跑完对比 Bagging 的结果你会发现随机森林在不少数据集上都比纯 Bagging 高一点点。这不是必然的但在特征冗余或者噪声特征较多时随机森林的优势会更明显。加分练习里如果去调整max_features比如从默认的 sqrt 改成 1.0全部特征实际上就把随机森林退化成了普通的 Bagging得分会往回走。记住这个坑max_features越小树越随机但太小了单棵树能力太弱需要在一个中间值附近找平衡。4. AdaBoost 与梯度提升顺序纠错机制与学习率的联动陷阱Bagging 系列靠并行投票降低方差Boosting 系列则完全不同——它是串行的后一棵树专门处理前面树的错误。这份资源把 AdaBoost 放在第四课梯度提升放在第五课正好演示了从“加权数据”到“拟合残差”的演进关系。4.1 AdaBoost用决策桩盯住“错题集”自适应提升AdaBoost的核心操作有两个。第一它用的是极浅的决策树实践中通常只有一层也就是只基于一个特征做一次判断这种树叫决策桩。第二每一轮训练结束后算法会提高被分错样本的权重、降低被分对样本的权重下一轮树就倾向于关注那些被反复搞错的样本。这种机制你可以理解为“错题本”学习法。第一棵树做了 70 分的判断剩下 30 个错题被加重标记第二棵树重点看这些错题再错了第三轮继续加权直到所有树都训练完。最终预测时每棵树的投票权重与其在加权训练集上的表现成正比。from sklearn.ensemble import AdaBoostClassifier # AdaBoost 集成默认基学习器是决策桩 model AdaBoostClassifier(n_estimators50) cv RepeatedStratifiedKFold(n_splits10, n_repeats3, random_state1) n_scores cross_val_score(model, X, y, scoringaccuracy, cvcv, n_jobs-1) print(Mean Accuracy: %.3f (%.3f) % (mean(n_scores), std(n_scores)))代码里n_estimators50是顺序添加的树的总数它不是并行而是串行。这意味着训练时间无法通过多核并行来节省50 棵树只能一棵一棵练。另一个隐藏参数是learning_rate默认 1.0它控制每棵树对最终预测的贡献权重后面梯度提升里还会遇到它。AdaBoost 对基学习器有一个硬性要求必须支持加权训练数据。因为每一轮都在调整样本权重如果你的基学习器不接收sample_weight参数整个算法就跑不起来。这个在下一章避坑部分会专门展开。4.2 梯度提升把提升写成加法模型梯度提升是 AdaBoost 的框架化升级。它不再显式修改样本权重而是让新树去拟合前面所有树的预测残差——本质上是用梯度下降的思路在一个函数空间里逐步逼近真实目标。原文把 AdaBoost 比作提升算法的“第一次成功实现”而梯度提升则是可以接任意损失函数的通用框架。from sklearn.ensemble import GradientBoostingClassifier # 梯度提升默认学习率 0.1 model GradientBoostingClassifier(n_estimators50) cv RepeatedStratifiedKFold(n_splits10, n_repeats3, random_state1) n_scores cross_val_score(model, X, y, scoringaccuracy, cvcv, n_jobs-1) print(Mean Accuracy: %.3f (%.3f) % (mean(n_scores), std(n_scores)))GradientBoostingClassifier的默认learning_rate0.1是这份资源里最值得实操的参数。0.1 的意思是每一棵新树只对预测做 10% 的修正留出大量空间给后续的树慢慢逼近。这种保守策略比 AdaBoost 那种大步快跑更抗过拟合代价是收敛慢通常需要更多的树才能达到同等效果。原文特别提到 XGBoost 和 LightGBM 是梯度提升的高效实现前者是 extreme gradient boosting后者在训练速度上做了大量优化。这份资源里的 scikit-learn 版本适合先理解原理工业项目里的大数据量场景一般直接上 LightGBM。4.3 学习率与树数量的联动0.1 不是放着不管就行这是第四课最容易翻车的地方。很多人看到learning_rate0.1就觉得是推荐值直接不变也不管n_estimators是多少结果模型表现平平然后抱怨梯度提升不如随机森林。实际关系是学习率越小需要越多的树来补偿。如果你把学习率从 0.1 降到 0.01但不把n_estimators从 50 提到 500那模型只做了一点点修正就停了欠拟合是必然的。反过来学习率设成 1.0 配上 500 棵树又容易过拟合训练集。learning_raten_estimators效果倾向1.050收敛快风险高易过拟合0.150资源默认组合平衡0.05100更稳需要更多树0.01500训练慢但往往精度上限更高我的习惯是先定学习率再根据训练集上的表现搜索合适的树数量。比如学习率 0.1 就先试 100 棵训练集准确率还明显上升就继续翻倍直到涨不动为止。这份资源里的练习只让你跑默认参数但我劝你课后至少做一次“固定学习率、逐步加树”的对比实验亲眼目睹准确率从欠拟合到平台期的全过程比背任何理论都有用。5. 避坑集成学习七天速成最容易翻车的五个细节七课内容本身不难但我在带学的人的时候发现真正卡住大家的往往不是算法原理而是几个反复出现的操作细节。这些坑单独看都小叠加起来足以让你怀疑集成学习是不是徒有虚名。按“现象 → 原因 → 解决”的格式给你理一遍。5.1 现象一调大 n_estimators 后训练时间失控分数却没涨很多人第一件事就是把n_estimators从 50 改成 500 甚至 1000然后发现训练时间成倍拉长最终准确率和 50 棵树差不多甚至因为过拟合还降了一点。原因在于 Bagging 和随机森林的边际收益递减是它们的天性树的棵数超过某个阈值后平均效应已经饱和加树只是在烧 CPU。解决办法是先做一个小规模扫描把n_estimators按 10、30、50、100、200 递增跑一遍画出准确率曲线在曲线走平的位置停下来。一般 100 到 200 棵足够覆盖绝大多数项目500 以上除非你数据量极大且单棵树很弱否则基本是浪费。5.2 现象二max_features 设成全部特征随机森林悄悄变回 Bagging随机森林和 Bagging 的关键差异就是特征抽样。如果你在RandomForestClassifier里把max_features设成None或1.0每棵树在分割时就能考虑全部特征树之间的相关性骤然上升随机森林的多样性优势直接消失性能趋近于普通 Bagging。这个坑特别隐蔽因为代码能跑通结果也不报错只是分数莫名低了一截。解决方法是分类任务保持默认的sqrt回归任务默认是1.0全部特征但如果你想用随机森林拿回归问题的效果也要手动试sqrt或0.3这类小值别迷信默认。5.3 现象三AdaBoost 换基学习器选了不支持样本权重的模型课程加分项里有一条让你“改变基学习器”而且原文单独标注了“注意它必须支持加权训练数据”。很多新手直接把基学习器换成某个不支持sample_weight的模型训练时直接报ValueError或者类型错误。更麻烦的一类是模型接受这个参数但不保证正确使用警告不报结果一团糟。解决方法是换基学习器之前先确认它的 fit 方法签名里有sample_weight参数比如决策树、逻辑回归都支持如果是 SGD 类模型还要看具体实现版本。不想折腾的话就老老实实继续用决策树桩因为在 AdaBoost 的场景里决策树桩本来就是经过验证的最优默认选择。5.4 现象四learning_rate 调小树的数量没补上模型像没练过这个问题在梯度提升里最常见。新手听说学习率越小越不容易过拟合把learning_rate从 0.1 降到 0.01然后n_estimators还是 50 没动。跑出来的准确率比默认值低了几个点就得出“梯度提升不行”的结论。原因很简单每棵树只贡献 1% 的修正50 棵树总共才完成原来 5 棵树的修正量欠拟合是必然的。解决方法是记住这个比例关系——学习率缩小 10 倍n_estimators至少扩大 10 倍来补偿。我一般用验证集或者交叉验证来做这个配合调整固定learning_rate0.05让n_estimators从 100 往上试直到验证集分数不再上升为止。5.5 现象五只跑集成不做单模型基线对比看不出集成到底赢在哪七天课程里每课都让你“运行示例并查看评估模型的结果”但如果你只记录了集成的分数没有和单棵决策树做对照整个学习过程就缺了一个重要的参照系。比如你的 Bagging 跑了 0.87单棵决策树上一次交叉验证跑了 0.83你才能直观看到 0.04 的提升就是集成吃掉的那部分方差。不跑基线的另一个恶果是当集成分数不理想时你分不清是数据本身太难、是超参没调好、还是集成策略不匹配。解决方法是给每课配一个“对手”同一份数据同一套交叉验证分别跑单棵决策树和当前集成算法两个分数放在一起看。这是成本最低的对照实验也是后续一切调参讨论的基础。6. 投票与堆叠硬投票到元模型最后一课学两种进阶结合法第六课和第七课的投票与堆叠在思路上和前面四种完全不同。前面要么在行上采样Bagging要么在错误上迭代Boosting本质都在折腾树。而投票和堆叠是把不同类型模型的预测结果作为新的输入重新组合出最终预测——它们更接近“模型的模型”。6.1 投票硬投票和软投票差在哪投票集成是最直观的组合方式在相同训练集上分别训练多个不同模型预测时少数服从多数。硬投票直接统计类别标签的票数软投票则累加每个模型输出的类别概率选概率之和最大的类别。软投票通常表现更好因为它保留了模型的置信度信息——一票顶一票但 90% 置信度的“一票”和 51% 置信度的“一票”含金量完全不同。from sklearn.ensemble import VotingClassifier from sklearn.naive_bayes import GaussianNB from sklearn.linear_model import LogisticRegression models [(lr, LogisticRegression()), (nb, GaussianNB())] # 软投票按概率之和决定最终类别 model VotingClassifier(models, votingsoft)6.2 堆叠让元模型决定信任谁堆叠更进一步——不再用简单的投票规则而是训练一个元模型来学习“如何结合基础模型的预测”。基础模型KNN、决策树等先通过内部交叉验证生成样本外预测元模型在这份样本外预测上学习每个模型该被信任的程度。final_estimator是元学习器cv控制内部交叉验证折数。from sklearn.ensemble import StackingClassifier from sklearn.neighbors import KNeighborsClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.linear_model import LogisticRegression models [(knn, KNeighborsClassifier()), (tree, DecisionTreeClassifier())] # 元模型用逻辑回归学习如何结合基础模型 model StackingClassifier(models, final_estimatorLogisticRegression(), cv3)堆叠最值钱的点在于信任是学出来的不是拍脑袋定的。从那以后我每次拿到一份新数据都会先跑一个单模型基线再跑 bagging 和 boosting 各一组最后确认数据质量没问题才谈得上调参——如果多个集成方法对同一份数据的表现都差不多那问题大概率不在算法而在数据本身。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?