决策树、集成学习与聚类:从入门到项目实战的完整梳理
把“决策树、集成学习、聚类”这三个词放到一起搜索满屏基本都是教程、课程作业、期末速成和面试高频题。这不奇怪它们几乎覆盖了机器学习入门阶段最核心的三类问题怎么让模型听懂 if-else 式的规则、怎么把“不太聪明”的模型组合成更稳的模型、怎么在没有答案的数据里自己找结构。我刚入行的时候也是从这三块开始啃的后来带学生、带新人发现最容易被绕进去的恰恰不是“某个算法难”而是三者的边界、联系和实际使用场景没打通。这篇文章我就按自己的学习路径和踩坑经验把决策树、集成学习、聚类完整梳理一遍同时把收入预测、鸢尾花分类、环境搭建、期末复习、面试题这些大家常搜的点全部串进去。这里不堆砌术语每个环节我都尽量说清楚“为什么要这么做”和“实际项目里怎么用”也方便你直接照着实操复现。1. 为什么把这三块放在一起梳理先搞清它们的定位1.1 决策树、集成学习、聚类分别解决什么问题很多自学材料习惯把算法一个一个单独讲导致不少人学完决策树不知道它跟随机森林什么关系学完聚类又搞不懂为什么前面的分类模型用不了。其实这三块按“能不能拿到标签”和“用几个模型”两个维度就能分得很清楚决策树是监督学习里非常经典的单个预测模型给一堆带标签的样本它学习出一套类似“收入 5000 且 学历 本科 → 高收入”的规则集成学习是“策略层”的东西它不限定具体用什么基础模型而是把许多弱模型合起来核心思想是“三个臭皮匠顶个诸葛亮”聚类则是无监督学习的主战场手里只有特征、没有标签的时候让算法自动把相似样本归成一堆。这三块在机器学习知识体系里正好卡住三条线单模型监督学习、组合模型监督学习、无监督学习。把这条主线打通后面再看 SVM、神经网络、降维、关联规则都会觉得顺很多。尤其是用决策树做集成学习的基础学习器本质上是从“一个人做决策”升级到“一群人投票/接力做决策”逻辑链条非常完整。1.2 这三者之间其实能配合使用还有一个容易被忽略的点这三块不是孤立的实际项目里经常混着用。最经典的组合是“决策树 集成学习”也就是随机森林、GBDT、XGBoost这些模型把决策树当积木搭成更大的结构聚类也常常在监督学习之前充当特征工程工具比如先用 K-Means 把用户分群再把“用户属于哪个簇”作为一个新特征喂给决策树反过来决策树也可以给聚类结果做解释聚类告诉你“这批客户是一类”但具体这类人有什么特征你可以再训练一棵浅层决策树把分群规则用 if-else 表达出来方便业务理解。我做过不少实际项目最深的感受是算法本身并不值钱值钱的是你知道在什么环节用什么工具。比如无监督聚类只负责给出分组但如果不去解释分组含义业务方根本没法采信又比如随机森林精度好但解释性弱报告里如果需要给非技术人员讲清楚我通常会再补一棵浅决策树做规则展示。所以这次梳理我不打算把三者完全拆开而是尽量讲清它们在项目流程中的真实位置。1.3 谁能从这份整理里真正受益这篇文章主要适合三类人第一类是刚开始学机器学习的学生尤其是被课程作业、头歌实训平台或期末复习逼着快速系统过一遍的人第二类是准备算法岗或数据分析岗面试的求职者需要把决策树剪枝、Boosting 与 Bagging、K-Means 与 DBSCAN 这些高频考点一次性理清第三类是已经会调库跑代码、但总感觉理解不够深入的开发者可以通过这里的“为什么”和“坑”补上经验断层。如果你已经熟练使用 scikit-learn、能独立完成一个分类或聚类项目那么可以直接跳到第 5 章和第 6 章看实操记录与面试速答。2. 决策树从 if-else 到可解释模型原理和实现都不难2.1 决策树的构建思路分裂到底是怎么回事决策树的核心原理可以一句话概括递归地把样本集合按特征划分成越来越纯的子集。所谓“纯”是指每个子集里的样本尽可能属于同一个类别。用人话说就是模型不像神经网络那样去算复杂的权重组合而是学出一串嵌套的条件语句如果年龄小于 30 再看职业如果职业是学生就预测低收入如果职业是程序员再看学历……从实现角度来看决策树构建过程包括三个关键部分特征选择、树的生成、剪枝。特征选择决定每一步该用哪个特征来分树的生成把选择过程递归重复下去直到满足停止条件剪枝则是为了防止树长得太深、把训练数据里的噪声都记住导致过拟合。这里也有一个新手容易忽略的点决策树做分类时输出的是叶子节点里多数类的标签做回归时输出的是叶子节点里目标变量的均值或中位数。所以决策树既能分类也能回归关键在于选什么样的分裂指标和损失函数。我实操时常把决策树类比成“做菜流程表”先看冰箱里有什么食材再按荤素、耐煮程度一步一步分最后落到一道具体的菜。每个分支都可以用大白话向家里长辈解释这也是决策树在风控、医疗、营销场景仍然受欢迎的原因——它天然自带可解释性。相比之下深度神经网络虽然精度可以很高但很难清楚说出一条样本为什么被判为正样本。2.2 信息增益、增益率、基尼指数怎么选别再只看一个公式决策树每一步节点分裂时都要回答一个问题当前这么多特征先用哪一个分早期 ID3 算法用的是信息增益它的计算依赖信息熵。信息熵 H(D) -Σ p_k log2(p_k)衡量的是数据集里的不确定性划分之后算加权平均的条件熵两者相减就是信息增益信息增益越大表示这个特征带来的“纯度提升”越明显。但信息增益有个很实际的毛病它天然偏好取值很多的属性。比如给身份证号建特征每个样本一个取值按它划分后每个子集只有一个样本纯度直接拉满信息增益最大可这个特征完全不具备泛化能力。C4.5 算法为了解决这个问题改用信息增益率也就是拿信息增益除以该特征本身的固有值相当于做了个归一化。不过也不能直接无脑选增益率最高的C4.5 的做法是先挑信息增益高于平均水平的候选特征再从中选增益率最大的这样既避开了“取值特别多”的坑也防止了增益率过头导致偏好取值少的属性。CART 树走的是另一条路线分类时用基尼指数Gini(D) 1 - Σ p_k²表示从数据集里随机抽两个样本、其类别不一致的概率。基尼指数越小数据集越纯。比起信息熵基尼系数算起来不用做对数计算速度更快所以 sklearn 里 DecisionTreeClassifier 默认就是 gini。而回归场景下的 CART 树用的是最小化平方误差即遍历每个特征的每个切分点找一个切分让左右两边的平方误差之和最小。这个思路其实就是“让左节点和右节点内部的目标值尽量一致”。实操中我的建议是中小型表格数据直接用 sklearn 决策树不用过度纠结 gini 和 entropy 的差别二者的精度差别通常很小但面试或考试时必须能说清 ID3、C4.5、CART 各自的指标和缺陷这是决策树三大必问题之一。2.3 剪枝是决策树的重头戏预剪枝还是后剪枝不剪枝的决策树很容易过拟合尤其是当树的深度不受限制时它几乎能把训练集的每个样本都记下来训练集精度接近 100%测试集一塌糊涂。剪枝就是主动砍掉一些分支用一点点训练精度换更强的泛化能力。预剪枝是在树生成的过程中提前停止分裂常用手段包括限制最大深度 max_depth、限制内部节点最小样本数 min_samples_split、限制叶子节点最小样本数 min_samples_leaf、限制分裂带来的增益必须超过某个阈值等。优点是训练时间短、树更简洁缺点也很明显它是“贪心式”的提前停止可能某个特征在当前节点看起来收益不大但再多一层之后会带来大幅提升所以预剪枝容易欠拟合。后剪枝则是等树完全长好之后再从下往上考察内部节点如果把以该节点为根的子树替换成叶节点验证集精度不下降甚至提高就把它剪掉。常见的剪枝方法有错误率降低剪枝 REP、悲观错误剪枝 PEP、代价复杂度剪枝 CCP 等sklearn 里的 DecisionTreeClassifier 通过 ccp_alpha 来控制代价复杂度剪枝。实际项目里我会先用 GridSearchCV 调几组 max_depth、min_samples_leaf 看看验证集表现再决定是否启用 ccp_alpha因为预剪枝参数更直观后剪枝让树裁剪得更“物尽其用”。面试时被问“预剪枝和后剪枝有什么区别”四个要点就能拿满分时机不同、效率不同、过拟合/欠拟合风险不同、验证集使用方式不同。2.4 连续值、缺失值和回归场景怎么办现实数据里很少有全离散的特征连续值的处理方式是决策树常见的隐藏考点。C4.5 的思路是二分法先把连续特征的所有取值排序然后取相邻两个值的中点作为候选切分点再按离散特征的方式计算每个切分点的信息增益选最优的。要注意的是同一个连续特征在一条从上到下的路径中可以多次参与分裂因为每次用不同切分值但离散特征通常不重复使用这也是连续特征更容易被优先选中的原因之一。缺失值处理是另一个容易被忽略的细节。实际场景中特征缺失太常见了直接丢掉一列往往太浪费。C4.5 给出的处理方式是对带缺失属性的样本先按“无缺失样本”子集计算信息增益再乘以无缺失样本所占比例做折扣样本进入下一层时如果某个特征缺失就按该特征各取值的权重把样本分到不同分支里去。sklearn 的决策树目前支持缺失值的方式是分到左右分支时寻找最佳路径但原理层面还是建议以 C4.5 的经典方案为准。回归树也顺便在这里提一句。CART 回归树不再用熵或基尼指数而是遍历所有特征和所有切分点把样本切成左右两堆然后让左右两堆的均方误差加权和最小。每个叶子节点输出该区域样本目标值的均值。只要理解了这个逻辑就很容易明白为什么决策树回归面对连续趋势数据时会有明显台阶状预测——它本质是分段常数函数所以在业务预测精度要求高时更常用随机森林回归或 GBDT。2.5 模糊决策树一个不太常提但有价值的变体如果你搜决策树相关热词会看到“模糊决策树”这个词。传统的决策树是硬划分一条样本要么走左分支要么走右分支非此即彼。模糊决策树则在节点分裂和推理时引入隶属度样本可以以不同概率同时进入多个分支最终预测时按隶属度加权汇总。这样做的好处是对噪声和边界样本更鲁棒缺点是计算复杂、解释性下降工业落地不如经典决策树广泛。模糊决策树在学术界有不少研究用的比较多的是模糊 ID3、Min-Ambiguity 等算法。对绝大多数学习者和面试者来说不必深究其代码实现但至少要知道它的存在它并不是“模糊了决策规则”而是把集合边界软化了。如果你做的数据本身有较强不确定性比如传感器噪声大、类别边界重叠严重可以考虑试试这个方向如果只是普通表格建模经典决策树和集成方法通常已经够用。3. 集成学习一群弱模型的“合议庭”为什么更可靠3.1 好而不同集成有效的前提条件集成学习的核心不是简单重复训练多个模型而是构建“好而不同”的个体学习器。所谓“好”是指个体模型精度不能太差至少要比随机猜测好一点所谓“不同”是指各模型之间要尽可能有差异能犯不同的错误。试想一个极端情况10 个模型完全一样投票结果等于一个模型集成毫无意义反过来如果每个模型都能在不同样本或不同特征上表现更好通过投票或加权融合它们之间的错误有可能互相抵消。从偏差-方差角度看Bagging 类方法主要靠降低方差来提升泛化能力Boosting 类方法主要靠降低偏差来提升拟合能力。这也是为什么随机森林面对高方差模型效果显著而 AdaBoost、GBDT 序列式训练不断纠正前一个模型的错误能把偏差压得很低。实际面试题里经常问“Bagging 和 Boosting 的区别”除了并行/串行之外如果能答到样本权重、降低偏差/方差、代表算法、对噪声敏感程度这几个维度就很完整了。3.2 Bagging 与随机森林样本扰动加特征扰动Bagging 的全称是 Bootstrap Aggregating思路非常朴素每次从原始训练集里有放回地抽出一批样本训练一个基学习器重复 T 次最后分类投票、回归取平均。因为有放回抽样每个基学习器看到的训练数据都不完全一样天然制造了“不同”。随机森林在 Bagging 基础上又加了一层扰动每次节点分裂时不是从全部特征里选最优而是先随机抽一个特征子集再从子集里找最优划分特征。这个改动看起来很小但效果很关键。它让树与树之间的相关性进一步降低尤其当数据集中存在某个特别强的特征时如果不限制候选特征几乎所有树都会优先用它分裂结果就是它们高度相似集成效果大打折扣。所以随机森林既能处理高维特征也能在模型层面给出特征重要性某个特征在所有树中被选作分裂点的次数越多、带来的纯度提升越大它的重要性分就越高。使用 sklearn 的 RandomForestClassifier 时有几个参数需要关注n_estimators 太大收益会越来越小且训练变慢通常在几百棵左右已经足够max_features 控制每次分裂的候选特征数分类任务里常用的经验值是 sqrt(n_features)回归任务用 n_features/3oob_scoreTrue 可以开启袋外样本评估相当于免费拿到一个验证集分数不需要额外切验证数据这个细节很多人没注意到。3.3 Boosting 与 AdaBoost、GBDT、XGBoost串行修正错误Boosting 的路线与 Bagging 完全相反它不是并行训练一批独立模型而是串行地训练一系列模型后者重点纠正前者犯过的错。AdaBoost 是最经典的实现之一初始给每个样本同样的权重每轮训练完一个弱分类器后提高被它分错样本的权重降低分对样本的权重下一轮模型就会更关注“难啃的骨头”。最终把所有弱分类器按各自权重加权投票。这个思路我当时理解了很久后来想明白了它本质上是在不断调整训练集的“注意力”让你更重视以前没做对的题目。GBDT 则换了个思路每轮不是调整样本权重而是让新决策树去拟合之前所有树的负梯度在回归问题里负梯度就是残差。比如要预测收入第一棵树预测 6000真实值是 8000残差是 2000第二棵树就去学这个 2000 的残差两棵树加起来就是更接近 8000 的预测。XGBoost 在 GBDT 基础上做了几项关键改造对损失函数做二阶泰勒展开利用一阶导和二阶导信息更精细地逼近在目标函数中加正则化项控制树的复杂度在分裂点搜索时用预排序和分位近似提升效率。这也是 XGBoost 在精度和速度上经常优于原生 GBDT 的重要原因。实际建模时如果你追求“省心且效果好”中小型结构化数据可以直接试 XGBoost 或 LightGBM如果只用 scikit-learn那 GradientBoostingClassifier 和 HistGradientBoostingClassifier 也是不错选择。但要注意XGBoost 参数多调参复杂新手容易过拟合建议先用默认参数建立基线再慢慢调 n_estimators、learning_rate、max_depth、subsample、colsample_bytree。3.4 随机森林 vs GBDT实际项目里怎么选作为一个经常被问到的问题同一份数据到底选随机森林还是 GBDT/XGBoost我的选择逻辑大致是数据量中等、特征噪声大、有较多缺失或异常值时优先随机森林。它对异常值更鲁棒训练可以并行调参压力小结果稳定性好。数据量比较大、特征与目标关系复杂、追求极致精度时优先 GBDT 系模型。它在结构化数据比赛里常年霸榜拟合能力强但超参数敏感需要更细心验证。需要快速给出可解释报告时优先随机森林加一棵浅层决策树做规则展示如果想用 SHAP 等解释工具XGBoost/LightGBM 也都有现成接口。训练时间紧张或部署环境资源有限时随机森林可以并行训练单机也能应付GBDT 串行训练稍慢但 LightGBM 的直方图算法已经大幅缓解这个问题。此外还要提一嘴“堆叠”Stacking把随机森林、XGBoost、逻辑回归等模型输出再作为新特征训练一个元模型通常还能提升一点精度。但堆叠的工程复杂度和过拟合风险也更高建议在基线模型已经调得比较扎实之后再尝试。4. 聚类没有标签时让数据自己开口说话4.1 K-Means最常用的聚类但要处理好三个细节K-Means 是上手最快、也最容易讲明白的聚类方法。它要做的就四步随机初始化 K 个簇中心把每个样本分给距离最近的簇中心重新计算各簇的均值作为新中心重复第二和第三步直到中心几乎不再变化。本质上它是在最小化所有样本到所属簇中心的距离平方和也叫“组内平方和”Within-Cluster Sum of Squares。用起来有三个地方最容易被坑。第一个坑是必须做标准化/归一化。如果特征的量纲不同比如年龄 0~100、收入 0~100000欧氏距离会被收入特征主导聚类结果基本等于只按收入切分。第二个坑是 K 怎么选。常用方法是肘部法则画不同 K 下的组内平方和曲线找拐点也可以用轮廓系数平均分来选但轮廓系数不是越大一定越好还得结合业务可解释性。第三个坑是初始中心的选择普通随机初始化可能陷入局部最优sklearn 默认的 k-means 会尽量让初始中心彼此远离明显更稳所以除非有特殊原因别去手动设 initrandom。用一个具体例子来感受如果要把电商用户按消费行为分群K-Means 能很快算出“高消费低频次”和“低消费高频次”等群体但它默认假设簇是凸的、球形的如果数据分布是环形、长条形K-Means 会把本属于同一类的点硬生生切开。这种场景下基于密度的 DBSCAN 反而更合适。4.2 层次聚类一种自带“谱系图”的方法层次聚类的最大特点是输出一棵树状谱系图dendrogram你可以从图中看到由细到粗的全部聚类过程而不像 K-Means 只能给出一个固定 K 的结果。层次聚类分两类聚合式AGNES从每个样本自己是一个簇开始逐轮合并最近的两个簇分裂式DIANA从整堆数据开始逐轮把最不相似的簇拆开。实际常用的是聚合式也就是自底向上。合并两个簇时簇间距离怎么算会极大影响结果。单链接single linkage取两个簇间最近的样本距离容易链式拉出细长簇全链接complete linkage取最远样本距离倾向生成紧凑球形簇平均链接average linkage取所有样本对距离的平均Ward 方法则最小化合并后组内平方和的增量效果通常比较均衡。sklearn 里的 AgglomerativeClustering 可以方便设置 linkage 参数。层次聚类还有一个好处是可以用热力图配合谱系图做可视化在生物学、客户细分等领域很常见。缺点是计算复杂度偏高暴力实现是 O(n³)优化后也常常到 O(n² log n)所以几万样本以上用层次聚类会比较吃力。我的习惯是先用层次聚类做小样本探索看大致能分成几群再用 K-Means 放到大样本上跑。4.3 DBSCAN能发现任意形状簇也能主动把噪声剔出去DBSCAN 的全称是 Density-Based Spatial Clustering of Applications with Noise它的思想是“物以类聚人以群分”的密度版本如果一个点周围足够密集它就向外扩展把所有密度相连的点都收进同一个簇。这样它不需要提前指定簇数 K也能发现任意形状的簇还能主动把离群点标成噪声。理解 DBSCAN 需要记住三个概念核心点、边界点、噪声点。如果某个点在半径 eps 范围内至少有 MinPts 个点包含自己它就是核心点落在核心点邻域内但自己不够密的点是边界点两者都不是的则是噪声点。参数 eps 和 MinPts 怎么设是个经典难题MinPts 太小会把噪声当成簇太大又会把稀疏簇丢掉eps 通常用 K-距离图来选也就是画每个点到第 MinPts 个最近邻居的距离曲线找曲线拐弯的位置。我踩过最典型的坑是 eps 对量纲极度敏感所以用 DBSCAN 前也必须做标准化。但即使标准化后如果各个簇的密度差异很大固定一组 eps/MinPts 也很难同时照顾好所有簇。此时可以试试 OPTICS它可看作 DBSCAN 的扩展对 eps 不敏感输出的是可达距离图。不过 OPTICS 在 sklearn 里速度偏慢小数据集上可以先体验。4.4 聚类效果怎么评估轮廓系数、RI 与 NMI聚类没有标签评估起来比监督学习麻烦得多但这不代表不能评估。如果真实标签存在只是训练时不用可以用外部指标调整兰德指数Adjusted Rand IndexARI和标准化互信息NMI都适合衡量聚类结果与真实类别的一致性取值范围越高越好且都做了随机性校正比直接用精度靠谱。如果没有真实标签就靠内部指标最常见的是轮廓系数对每个样本计算它与同簇其他样本的平均距离 a以及它到最近其他簇所有样本的平均距离 b轮廓系数 (b-a)/max(a,b)结果在 -1 到 1 之间越接近 1 说明簇内越紧凑、簇间越分离。需要特别小心的是轮廓系数高不代表聚类结果一定有业务意义。我见过有人用轮廓系数挑出 K6结果画出来会发现分群边界非常勉强。所以做聚类项目时我坚持“内部指标只做参考业务解释和可视化才是最终裁判”。把聚类结果投射到二维上用散点图看一眼再给每个簇统计特征画像比如各特征均值、占比、同比变化业务方才会觉得结果可用。5. 实操记录环境搭建、收入预测与聚类实验5.1 花十分钟把机器学习环境搭起来无论你要跑决策树、集成学习还是聚类第一步都是把 Python 环境准备好。这里我说一个最适合课程作业和快速验证的最小方案不需要折腾 GPU 或复杂的 conda 环境。如果你当前机器上已装上 Python 3.8 以上直接开终端执行pip install numpy pandas scikit-learn matplotlib jupyter如果没有 Python更省事的办法是直接装 Anaconda安装完自带 Jupyter Notebook、pandas、scikit-learn 等常用库。在 Jupyter 里写代码调试比较直观尤其是看决策树可视化和聚类散点图时体验很好。装好后可以用下面代码验证版本import sklearn import pandas as pd from sklearn.tree import DecisionTreeClassifier print(sklearn:, sklearn.__version__) print(pandas:, pd.__version__)如果是在学校实训平台或头歌这类网页环境里做题通常环境已经配好不需要你自己安装核心是把算法步骤和参数含义搞清楚。团队协作或正式项目里我建议再加一个 requirements.txt 锁定所有依赖版本避免别人复现时因为库版本不一致报错。5.2 用决策树做收入预测sklearn 版本的关键步骤收入预测这类任务常见的公开数据集是 Adult特征包括年龄、工种、教育程度、婚姻状况、职业、每周工时等目标是判断样本收入是否超过 50K。用决策树来做的完整流程包括导入数据、预处理、训练、评估、调参与可视化。这里给一个可直接运行的压缩示例示范关键代码是什么样的import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score # 示例数据字段实际数据请按自己下载的表格调整 df pd.read_csv(adult.csv) # 处理缺失值把 ? 变成 NaN 再删除或填充 df df.replace(?, pd.NA).dropna() # 用 LabelEncoder 把类别文本转数字 for col in df.select_dtypes(includeobject).columns: df[col] LabelEncoder().fit_transform(df[col].astype(str)) X df.drop(income, axis1) y df[income] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.25, random_state42 ) model DecisionTreeClassifier( max_depth6, min_samples_leaf5, max_featuressqrt, random_state42 ) model.fit(X_train, y_train) y_pred model.predict(X_test) print(测试集准确率: {:.4f}.format(accuracy_score(y_test, y_pred))) print(特征重要性:, dict(zip(X.columns, model.feature_importances_)))这里几个参数是经验值max_depth6 防止树太深min_samples_leaf5 保证叶子节点有足够样本max_featuressqrt 在分类场景中引入一点随机性避免总靠同一个特征分裂。真正跑 Adult 数据时基线决策树测试准确率通常在 0.80~0.83 左右比随机森林低一些但优势是能直接画出规则。如果实训平台要求的不是 Adult 而是类似字段的数据核心步骤都一样先清洗缺失值、编码类别特征、划分训练测试集再训练并评估。5.3 基于模型的调参与对比实验思路做完第一棵决策树后不要急着交作业可以做一个“对照实验”把决策树、随机森林、AdaBoost 放到同一份数据上对比。这个习惯帮我避开了很多“调参魔怔”问题也让报告看起来更有说服力。参考代码如下from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier from sklearn.tree import DecisionTreeClassifier models { DecisionTree: DecisionTreeClassifier(max_depth8, random_state42), RandomForest: RandomForestClassifier(n_estimators200, max_depth10, random_state42, n_jobs-1), AdaBoost: AdaBoostClassifier( estimatorDecisionTreeClassifier(max_depth3), n_estimators200, random_state42 ) } for name, model in models.items(): model.fit(X_train, y_train) acc model.score(X_test, y_test) print(f{name}: {acc:.4f})按照我的经验相同的 Adult 数据上决策树凭借调好的参数大概 0.82 上下随机森林普遍能到 0.85 左右AdaBoost 也在 0.85 附近GBDT/XGBoost 还能再往上一点点。这里有一个面试常考的点AdaBoost 如果基学习器是深度太大的树容易过拟合所以通常把 max_depth 限制到 2 或 3。看到代码里的 DecisionTreeClassifier(max_depth3)不要觉得奇怪那是因为 Boosting 依赖“弱学习器”太强的基学习器反而会降低集成效果。5.4 鸢尾花上的三种聚类方法对比收入预测是监督学习聚类实验则可以选经典的鸢尾花数据集因为它只有 150 条、4 个特征跑起来极快又自带三个类别标签方便事后用 ARI 评价。下面是一段直接能跑的对比from sklearn.datasets import load_iris from sklearn.cluster import KMeans, AgglomerativeClustering, DBSCAN from sklearn.metrics import adjusted_rand_score from sklearn.preprocessing import StandardScaler data load_iris() X StandardScaler().fit_transform(data.data) y_true data.target kmeans KMeans(n_clusters3, random_state42).fit(X) agg AgglomerativeClustering(n_clusters3).fit(X) db DBSCAN(eps0.6, min_samples5).fit(X) print(KMeans ARI, adjusted_rand_score(y_true, kmeans.labels_)) print(层次聚类 ARI, adjusted_rand_score(y_true, agg.labels_)) print(DBSCAN ARI, adjusted_rand_score(y_true, db.labels_))标准化在这段代码里是关键操作不做标准化的 K-Means 在鸢尾花原始特征上往往不那么稳定。DBSCAN 的 eps0.6 是我试出来的相对合理值如果设太小会把大量点标成噪声太大则把几类全融成一个簇。用 ARI 来评估是因为我们知道鸢尾花真实有三种但聚类算法并不知道标签ARI 能衡量聚类结果和真实结构的吻合程度。如果去掉标签只看内部效果则通常要结合轮廓系数。聚类结果的可视化也要补上。鸢尾花数据有 4 维直接画不出全貌可以取前两个特征或先用 PCA 降到 2 维再画散点图每个点按聚类标签着色中心点额外标出。这样放进报告里直观程度远胜于一个 ARI 数值。5.5 画特征重要性与决策树图让模型不再像黑箱决策树和集成学习项目里我最喜欢做的收尾工作是可视化。决策树本身可以直接用 matplotlib 画出树结构from sklearn.tree import plot_tree import matplotlib.pyplot as plt plt.figure(figsize(24, 14)) plot_tree( model, feature_namesX.columns.tolist(), class_names[50K, 50K], filledTrue, roundedTrue, fontsize9 ) plt.savefig(decision_tree.png, dpi150, bbox_inchestight)随机森林的特征重要性条形图同样重要它回答的是“到底哪些变量在影响收入预测”。对于收入预测数据通常年龄、教育程度、职业、每周工时这几个特征的重要性排在前列这个结论对于业务报告非常重要甚至比模型准确率本身更受非技术同事关注。实操中我习惯把特征重要性保存成 DataFrame再按数值降序画条形图方便直接复制到 PPT。聚类实验同样可以加可视化把 PCA 降维后的散点图与真实标签、聚类标签并排放在一起一眼就能看出算法把哪些样本分错了。很多实训平台和期末报告里图表一多分就上去了但它不是假的“美化”而是真正帮你理解和解释数据。6. 考试与面试高频点速查剪枝、集成、聚类“一页纸”6.1 决策树高频面试题速答这一节我把这些年见过的面试题和期末考题里最常出现的几个问题集中整理一下方便你直接当做复习提纲用。第一个必问题决策树如何处理过拟合答案核心就是剪枝。预剪枝通过提前停止分裂避免树过深后剪枝则让树完全生长后再自底向上替换或删除部分子树。判断标准都是看验证集精度是否上升。第二个必问题ID3、C4.5、CART 有什么区别信息增益偏好取值多的特征增益率缓解了这个问题但会偏好取值少的特征基尼指数计算简单且默认在 sklearn 中使用ID3 不支持连续值和缺失值C4.5 通过二分法处理连续值、通过权重处理缺失值CART 既可以分类也可以回归且生成的是二叉树。第三个必问题为什么决策树不需要做特征缩放因为树模型的分裂本质上是在比较特征的取值阈值不受特征大小范围影响所以不像 K-Means、SVM 那样必须做标准化。但如果你做集成学习或把树输出再接逻辑回归那是另一回事。还有一个实训和作业里容易考的操作题用决策树做收入预测时遇到“受教育年限”这种数值型特征和“职业”这种类别型特征怎么处理类别型需要编码数值型可以直接参与分裂如果类别型取值太多用 LabelEncoder 可能引入虚假的排序关系更稳妥的做法是用 OneHotEncoder 或把它当成 category 型让 sklearn 自动处理。6.2 集成学习高频问题速答面试中第二大类高频题围绕 Bagging 和 Boosting 展开。我建议你在纸上画一个两层表格左列写 Bagging右列写 Boosting然后按训练方式、样本使用、目标、代表算法、对噪声和异常值敏感性这五行填满基本就能应对大多数追问。训练方式上Bagging 可以并行Boosting 必须串行样本使用上Bagging 用有放回抽样每一轮的训练集相互独立Boosting 每一轮调整样本权重或拟合残差目标方面Bagging 主要降低方差Boosting 主要降低偏差代表性算法对应随机森林和 AdaBoost/GBDT/XGBoost噪声敏感性方面Bagging 更稳Boosting 容易在异常样本上反复纠错所以对噪声更敏感。还有一个容易被追问的细节随机森林如何评估特征重要性一种方式是看特征在所有树中作为分裂特征的次数加权和另一种是看用该特征分裂带来的纯度提升总量。sklearn 代码里 model.feature_importances_ 返回的就是归一化后的结果。6.3 聚类高频问题与避坑经验聚类部分的面试题通常集中在三个方向K-Means 怎么选 K、DBSCAN 怎么设参数、不同聚类算法的适用场景。选 K 我的标准回答是先画肘部曲线看组内平方和的拐点再结合轮廓系数与业务解释做最终决定。只靠自动指标选 K 很危险因为无监督任务的本质是发现问题结构而不是机械地最优化某个数字。DBSCAN 怎么设参数通常建议先用 K-距离图粗略估计 eps一般取曲线拐弯处的距离值MinPts 通常取大于等于数据维度数如果数据量大可以适当增大。如果数据不同区域密度差异太大DBSCAN 很难全局照顾这时要正视算法的局限而不是硬调参数。不同聚类算法的选择我给的快捷表是数据量大、簇近似球形且希望快用 K-Means想要多粒度结果、样本量小用层次聚类数据形状复杂、噪声明显、不知道 K用 DBSCAN。聚类前标准化这一步几乎不可省略这是我在实际项目里踩过最多的坑之一。最后再分享一个非常个人的经验学这三块内容时不要只盯公式和代码跑通试着每个模型都问自己三个问题——它解决什么问题它最怕遇到什么数据如果效果差我第一个该改什么参数这套思路比死记硬背任何教程都管用我从带新人和复习期末中反复验证过很多次。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →