ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

决策树优缺点与实战调参:从可解释性到过拟合的全面指南

决策树优缺点与实战调参:从可解释性到过拟合的全面指南 先说实话市面上讲决策树的教程一抓一大把但大部分都在讲“怎么建树”——信息增益怎么算、基尼系数是什么、树怎么画出来。真正把它用在实际项目里你会发现最坑的不是不会建树而是不知道该什么时候用它、什么时候别用它、树长太深了怎么收、结果不稳定怎么排查。这一篇就把决策树的优缺点掰开揉碎聊清楚讲点教程里一般不写的东西。这篇内容适合刚学完决策树理论、准备上手做实战的人也适合已经在用 sklearn 做项目、但总觉得模型效果不够稳的数据分析师。我会先从决策树的基本机制说起因为优点缺点不是背出来的是机制决定出来的然后重点讲它到底好在哪、坏在哪以及这些优缺点在实战里怎么左右你的模型选型最后给出一套可落地的调参和排查方案包括在收入预测这类场景里的实操对比。1. 先把底子摸清决策树的三种经典算法与核心机制1.1 ID3、C4.5、CART三种算法的分歧指标在聊优缺点之前得先确认咱们说的是同一棵树。决策树这个家族里ID3、C4.5、CART是三个绕不开的祖师爷它们的核心区别就一句话用什么指标来决定“先拿哪个特征去分”。ID3用的是信息增益公式长这样[ Gain(D, A) Ent(D) - \sum_{v1}^{V} \frac{|D^v|}{|D|} Ent(D^v) ]这个公式的意思很直白拿特征 A 去切数据之前样本集 D 的混乱程度是 ( Ent(D) )信息熵切完之后每个子集的加权熵加起来比原来小了多少这个差值就是信息增益。增益越大说明这个特征越能“把混乱变整齐”就优先选它。但 ID3 有个毛病它天生偏爱取值特别多的特征。比如特征“身份证号”每个人都不一样拿它一切每个子集只有一个样本熵直接归零信息增益看起来大得吓人但这样的切分毫无泛化能力。C4.5 就是为了治这个毛病改用信息增益率用特征的固有值把信息增益归一化一下惩罚那些取值过多的特征。CART 则换了个思路用的就是大家最熟悉的基尼指数[ Gini(D) 1 - \sum_{k1}^{K} p_k^2 ]基尼指数算起来比信息熵快因为它没有对数运算。取值越小说明数据越“纯”。CART 还有两个硬性特点它生成的一定是二叉树而且既可以做分类也可以做回归。说实话到了 sklearn 时代你基本只用 CART因为 sklearn 的 DecisionTreeClassifier 和 DecisionTreeRegressor 底层全是 CART。但理解 ID3 和 C4.5 还是很有必要的——你去翻论文、看面试题、用其他框架写代码时这些概念经常冒出来。更重要的是理解了这些指标的选择逻辑你才能真正看懂后面要说的“为什么决策树容易过拟合”这个问题。1.2 从分裂过程理解决策树的行为模式三种算法虽然指标不同但核心机制一模一样递归地找最佳切分点把数据分成更纯的子集再对每个子集重复这个过程直到满足停止条件。这个过程有两个非常关键的行为模式它们是决策树全部优缺点的源头。第一个行为模式是“贪婪搜索”。决策树在每一步分裂时只考虑当前节点上“哪个特征、哪个阈值能让不纯度下降最多”它完全不会回头看——不会想“这一步分得可能不是最好但为了整体更优我可以让步”。这就是标准的贪心算法思路每一步取局部最优最终拼出全局结果。第二行为模式是“轴平行划分”。决策树每次只拿一个特征的某个阈值去切这相当于在特征空间里画一条垂直于坐标轴的线。两个特征的决策边界在二维平面上长什么样就是横一刀竖一刀的阶梯形折线。真实世界的数据边界很少恰好是这种形状这也就埋下了决策树表达能力的上限。把这两点先记在脑子里接下来聊优缺点就有了根。你看很多文章列优缺点优点写“易于理解”、缺点写“容易过拟合”但没告诉你这些结论是怎么推出来的。下面我一次讲透。2. 决策树的优点白盒模型在生产环境中的不可替代性2.1 可解释性拉满从“机器给答案”到“机器给依据”我做过不少风控类的项目信贷审批、反欺诈、异常交易检测都碰过。这类场景里业务方最常问的一句话是“这个样本为什么被判为高风险”你给业务方上一个神经网络对方看着黑盒只能干瞪眼最后还得你人工补解释报告费时费力还说不清楚。但你上决策树直接把路径打印出来就完事了。比如如果 “月收入 5000” 且 “历史逾期次数 3” 且 “近30天申请机构数 5”则风险等级高危。这就是决策树最硬的优点——它是白盒模型每一个预测结果都能精确回溯到完整的决策路径。同样的逻辑逻辑回归勉强可以靠着系数大小做解释但特征一多、涉及非线性交互项解释力度就大打折扣SVM 核函数一上你连系数都说不明白深度学习就更不用提了。而且这个可解释性不光是给业务看的也是给监管和审计看的。金融、医疗、法律这些强监管行业模型决策要能追溯、能合规审查决策树天然就满足这个要求。实测下来很多项目组宁可牺牲一点点精度也要换一个能跟监管讲清楚的模型这就是决策树的生存空间。2.2 预处理门槛低省掉标准化、哑变量这些麻烦事做特征工程做过的人都知道数据预处理有多烦归一化、标准化、缺失值填补、类别特征要转哑变量、连续特征要考虑能不能直接喂给模型……决策树在预处理这一步是真的省心。它对特征的量纲和分布完全无感因为分裂只看“小于某个阈值”还是“大于等于某个阈值”。你拿“收入按元计”还是“按千元计”喂进去树的阈值会跟着等比变化分裂结果完全一致。这意味着什么——你不用做标准化也不用做归一化省了一大堆事。类别特征也不一定要做哑变量。决策树可以直接对类别特征做“是否属于某个子集”的划分。比如城市特征它可以分出“北京、上海、深圳”这一类 vs “其他城市”另一类。换成逻辑回归或者 SVM你得先做 one-hot 编码维度瞬间爆炸。还有缺失值很多决策树实现比如 sklearn 的 CART在分裂时会自动用代理分裂或直接支持缺失值策略比线性模型对缺失值的容忍度高不少。我自己在实际项目里决策树跑数据时最大的感受就是“糙快猛”——数据稍微脏一点照样能出一个可用的基线模型。2.3 特征重要性零成本拿到一份排序清单决策树的另一个隐藏福利是特征重要性。它不需要额外计算树建完之后顺手就能算出来每个特征在分裂中带来的不纯度下降总量按特征聚合再归一化就是一份排序好的特征重要性列表。这个列表在项目初期非常有价值。你可以用它快速判断哪些特征是真正有区分度的哪些特征就是来凑数的从而指导后续的特征工程和维度压缩。我习惯的做法是先用决策树跑一遍基线拿到特征重要性之后再用重要特征去喂那些对特征更敏感的模型比如线性模型、神经网路。不过这里要提醒一句决策树的特征重要性是有偏的它会更偏向取值较多的特征这一点要结合后面的缺点去看不能盲信任。2.4 非线性切分能力轴平行划分虽然粗糙但有效前面提过决策树的决策边界是轴平行的阶梯形。虽然这个边界不够优雅但它的好处是——能拟合出非线性的决策边界。逻辑回归只能给出一个线性的超平面遇到真实边界是“弯的”数据就抓瞎必须靠人工做多项式特征扩展还得猜特征交互的方式。决策树不需要你猜它靠不断递归划分自己就能逼近复杂边界。你用一个中等深度的树就能在二维平面上拟出一个多边形一样的不规则决策区域。这在很多真实业务数据上非常够用因为它天然捕捉了特征之间的交互效应。比如“年轻人和高收入者都倾向于买某产品但中年人低收入者不买”这种逻辑用线性模型很难直接表达决策树几个分裂就搞定了。小结一下决策树的四大优点是可解释性强、预处理成本低、自带非线性拟合能力、顺手给你一份特征重要性。这四个优点决定了它是你做任何项目时都值得第一个试的模型。3. 决策树的缺点必须正视的几个硬伤3.1 过拟合是头号天敌深度、叶子、样本量之间的拉锯决策树最大的缺点就是容易过拟合这事儿圈里人都有共识。问题是它会过拟合到什么程度我拿个例子说。之前在收入预测数据集UCI Adult预测年收入是否超过5万美元上做过实验。用默认参数训练一棵决策树树能长到深度三十多层训练集准确率能到95%以上。但拿到测试集上一测准确率直接掉到80%上下。训练集和测试集差了15个百分点这就是教科书级的过拟合。为什么会这样因为默认情况下决策树会一直分裂下去直到所有叶子节点都是纯的。纯是纯了但它把每一个训练样本的细节都记下来了连噪声和异常值都背得滚瓜烂熟。你给它看新数据它还在用“背题”的方式来答题当然瞎蒙。过拟合的根源就是深度和纯度之间的拉锯深度越大、叶子越纯对训练集拟合越彻底但泛化能力反而越差。你需要在树“刚好能表达模式”和“还没开始背诵噪声”之间找到平衡点。这个平衡点就是后面要说的剪枝技术的核心目的。3.2 高方差与不稳定性数据抖一抖整棵树抖三抖决策树的第二个硬伤是不稳定学术点说就是方差大。数据有一点点扰动整棵树的结构可能完全变样。我有一个自己都觉得很夸张的实测经历同样一份收入预测数据随机抽 1 万条训练一棵树再换一批抽 1 万条训练另一棵树。两棵树的第一个分裂特征居然不一样。第一棵树的根节点用的是“年龄”第二棵树的根节点用的是“教育年限”。树内部的子结构差异就更大了。你觉得你训练了一棵稳定的决策树实际上它脆弱得像纸糊的。这个不稳定的根子在于贪心算法的连锁反应根节点的一次分裂选择变了下面整个子树全部跟着变。你换了一批抽样或者某个特征的值有微小波动就可能导致根节点选了另一个特征然后整棵树的结构天翻地覆。高方差带来的直接后果是模型的可复现性很差。你昨天训练得到一棵树今天数据稍微更新一点再训练结果可能完全对不上。这在生产环境里是致命的——业务每次拿到的新模型结果不一致就没人敢信任你的东西。这就是为什么实战里你很少单独用一棵决策树而是把很多棵树包起来用随机森林、梯度提升树。集成模型的核心价值之一就是压方差单棵树不稳定但几百棵树平均下来噪声互相抵消整体就稳了。3.3 轴平行划分的边界局限一条斜线就难住单棵树决策树的划分方式决定了它的决策边界只能由横线和竖线拼接而成。如果数据的真实边界是一条斜线比如 ( xy1 ) 这个很简单的规则决策树要表达这个边界就非常费劲。它只能用多段阶梯折线去逼近那条斜线。要逼近得足够好树就得足够深深度大了又回到过拟合问题。所以决策树在面对线性可分但边界是斜向的数据时表现会非常糟糕。同样的问题SVM 用线性核一脚就踢飞了逻辑回归一个系数也搞定了决策树却要在那吭哧吭哧画阶梯。这个缺点在特征维度高的时候表现得更严重。高维空间里的真实边界几乎不可能是轴平行的决策树的阶梯逼近需要大量分裂树越来越深、越来越复杂过拟合的风险跟着急剧上升。所以如果你观察到单棵决策树在测试集上表现很差而数据本身又是高维的、边界比较平滑的数据那它可能真不是这个问题的好选择。3.4 数据敏感项类别不平衡与噪声的杀伤力决策树对类别不平衡非常敏感。这个敏感和不平衡数据下准确率低是两件事——更关键的是树的分裂过程会被多数类牵着走。举个例子一个二分类数据 99% 是负类、1% 是正类。决策树在分裂时基尼指数或信息增益都会偏向“能把大量负类分出来的分裂”因为这种分裂能让整体不纯度下降最多。结果就是树倾向于把所有样本都分到负类里面去正类一个也捞不着。你去看它的准确率有 99%但真正关心的正类召回率是 0。噪声的影响就更直接了。决策树的每一次分裂都会严格按照当前节点的数据来决定阈值如果数据里混了几条标签错误或者特征值严重异常的点树会专门为它们分裂出节点。一个噪声点就可能让整棵树的局部结构变得非常扭曲。类别不平衡可以用 class_weight 参数缓解噪声数据只能在特征工程和清洗阶段下功夫。这两个问题叠加时更麻烦噪声点在多数类里往往看不出来但它们会持续拉偏树的划分方向。4. 实战中的选择单棵决策树还是集成模型4.1 什么时候用单棵决策树风控、医疗、合规、教学说完了优缺点最实际的问题来了那到底啥时候该用单棵决策树我的经验是四个字要讲道理。具体来说有这些场景金融风控和信贷审批要给客户和监管一个明确、可追溯的拒贷/放贷理由单棵决策树的规则可以直接落到业务系统里。医疗辅助诊断医生需要一个可以核对的推理过程决策树给出的规则路径比黑盒模型的概率值更容易建立信任。合规审计场景模型要接受审计每条预测都要能查证决策树天然适合。教学、demo、快速验证基线你要快速看看数据里有没有规律单棵决策树训练快、可解释几十行代码就能跑通。规则提取和业务梳理可以从训练好的决策树中抽取规则集用来校验业务经验或者厘清数据内在逻辑。在这些场景里牺牲一点点的精度换取可解释性和可控性是完全值得的。我经常建议的项目打法就是第一期先用决策树做规则引擎能上线跑通、业务认可了后面再考虑上复杂的模型。4.2 什么时候别用单棵决策树高维稀疏、复杂边界、追求精度反过来有些场景用单棵决策树就是自找麻烦特征维度高且稀疏的数据比如大量 one-hot 文本特征树的效率已经很低了还特别容易过拟合。数据真实边界复杂、特征间强相关比如图像、音频、高维向量单棵树的阶梯边界根本表达不来。你追求的是尽可能高的预测精度和稳定性模型可解释性不是硬需求那就直接上 XGBoost、LightGBM 或者神经网络。数据量特别大几百万行以上单棵决策树训练效率不如梯度提升树的分块计算效果也可能被吊打。说白了是选“讲道理的模型”还是“能打的模型”取决于业务优先级。既要解释又要高精度怎么办用集成模型加事后解释工具SHAP 这种但那已经是另一套话题了。4.3 集成模型如何对症下药随机森林治方差、梯度提升治偏差决策树的高方差不仅让单棵树不稳定也恰恰是它作为集成学习基模型的得天独厚之处——因为树之间差异足够大集成的效果才足够好。随机森林的做法就是“治方差”。它用 Bootstrap 采样生成多份不同的训练集每份训练集再随机选特征子集来分裂训练出很多棵“尽量不相关”的树然后投票取平均。每棵树可能都在乱猜但几百棵树的错加在一起会相互抵消总体方差明显下降。逼近真实的数据规律这部分交给“多棵树互相补充”。梯度提升树GBDT、XGBoost、LightGBM走的是另一条路——治偏差。它顺着残差的方向一棵一棵地建树每棵新树都是在纠正前面所有树的错误。最终的结果是单棵决策树“精度不够”的缺点被反复迭代补齐了模型精度可以做到很高。所以你看决策树的优缺点在集成模型里都变成了“有用的原材料”。优点是这些集成模型能真正跑出效果的基础高方差则成了随机森林能有效降低整体方差的条件。理解了这一层你能更清楚地知道你骂决策树的问题集成框架正是来治这些问题的你夸决策树的优点集成框架也全部继承。5. 实操中如何弥补缺点剪枝、交叉验证和调参思路5.1 预剪枝的四个常用参数和它们的作用如果你确实要用单棵决策树首要做的事情就是剪枝。剪枝分预剪枝和后剪枝两者思路不同预剪枝是边建树边限制差不多了就停后剪枝是先把树长满再把没用的枝杈剪掉。sklearn 的 DecisionTreeClassifier 里预剪枝主要靠四个参数max_depth树的最大深度。从根节点到叶子节点最多经过多少层。这是最直观、最常用也最好使的参数。min_samples_split内部节点再分裂需要的最少样本数。样本太少就不许再分。min_samples_leaf叶子节点上最少样本数。这个比上一个更狠它保证每个叶子的样本量不能太少防止叶子把个别样本“背”下来。max_leaf_nodes最多允许有多少个叶子节点。它是从整体上限制树的规模。这四个参数其实是在回答一个问题你愿意让树“为了记住几个特殊的样本”付出多大的结构复杂度实际操作时我一般建议的调参顺序是先定 max_depth再调 min_samples_leaf最后微调 min_samples_split。别一上来就同时调所有参数维度太多你很难判断每个参数到底起多大作用。5.2 后剪枝的代价复杂度剪枝CCPsklearn 里可以直接用预剪枝的局限是它“目光短浅”——树在某一层看似没有显著收益的分裂也许再分下去会有收益。后剪枝能弥补这一点但它计算量更大、实现更复杂。sklearn 从版本 0.22 之后内置了代价复杂度剪枝算法CCPCost Complexity Pruning用起来非常简单。核心思路是给整棵树的复杂度加上一个惩罚项目标变成“误差 α × 叶子节点数”最小化。 α 越大叶子越少的树越占优。实操步骤是先用训练好的全树上调用 cost_complexity_pruning_path 拿到一整串候选的 α 值和对应的剪枝路径然后对每个 α 训练一棵树用交叉验证挑出测试集效果最好的那一棵。代码大概是这样的from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split # 假设 X_train, X_test, y_train, y_test 已经准备好 clf DecisionTreeClassifier(random_state42) clf.fit(X_train, y_train) # 获取代价复杂度剪枝路径 path clf.cost_complexity_pruning_path(X_train, y_train) ccp_alphas path.ccp_alphas # 对每个 alpha 训练一棵树 clfs [] for alpha in ccp_alphas: clf DecisionTreeClassifier(random_state42, ccp_alphaalpha) clf.fit(X_train, y_train) clfs.append(clf) # 看测试集分数随 alpha 的变化挑最优的 test_scores [clf.score(X_test, y_test) for clf in clfs] best_index test_scores.index(max(test_scores)) best_alpha ccp_alphas[best_index]这里有个坑ccp_alphas 的数量可能非常多而且很多 alpha 会对应相同的树结构所以要先做去重。另外ccp_alpha 过大时树会被剪成只有一个根节点分数回升不代表模型好要看整体趋势判断。5.3 一个完整的实操对比有剪枝 vs 无剪枝的收入预测案例空讲参数没意思我来放一个实操对比。回到前面提到过的收入预测数据集它预测的是“年收入是否超过 5 万”列里有年龄、教育年限、职业、工作时间等特征。为了演示效果我只保留数值特征不做过多的特征工程。先是无剪枝的默认参数训练from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.3, random_state42) clf_default DecisionTreeClassifier(random_state42) clf_default.fit(X_train, y_train) train_score clf_default.score(X_train, y_train) test_score clf_default.score(X_test, y_test) print(f默认参数——训练集准确率: {train_score:.4f}, 测试集准确率: {test_score:.4f})实际跑出来大概是训练集 0.95测试集 0.80 上下。差 15 个百分点这不是好的泛化这就是在背题。加预剪枝限制clf_pruned DecisionTreeClassifier( max_depth5, min_samples_leaf20, min_samples_split50, random_state42 ) clf_pruned.fit(X_train, y_train) train_score clf_pruned.score(X_train, y_train) test_score clf_pruned.score(X_test, y_test) print(f预剪枝后——训练集准确率: {train_score:.4f}, 测试集准确率: {test_score:.4f})跑出来的结果训练集会掉到 0.83 左右但测试集反而能稳在 0.81 甚至 0.82。训练和测试的差距从 15 个百分点缩到 2 个百分点以内。这说明模型不再靠背样本拿高分而是真的抓到了一些可泛化的规律。再从可解释性角度看默认参数的树有几十层深你根本没法跟人讲清楚这个模型在干嘛。剪枝后的树只有 5 层你画个图从根到叶的每一条路都是人话。我试过把剪枝后的树直接放到项目文档里交给业务方看效果立竿见影——他们能指着树的某个分支提出具体的业务问题而这在以前的黑盒模型上是不可想象的。所以我的实操建议就是单棵决策树的调参一切围绕“把训练集和测试集的分数差距压到 3 个百分点以内”来干活。只要差距在 3 个点内大体上这棵树就没怎么过拟合。6. 常见问题与排查技巧实录6.1 决策树结果不稳定换一次训练集结构就变了这是最高频的问题。昨天跑出来的树今天重新跑一遍树完全两样怎么办先说清楚单棵决策树的方差就是这么高这是它的本质属性不要指望调参完全消除。你能做的事有两件一是在训练和评估时固定 random_state保证同一份数据至少可以复现。你在工程里部署模型一定要把随机种子固定住否则每次上线模型都“抽风”。二是如果业务真的需要稳定模型换个思路别死磕单棵树改用随机森林或梯度提升树。我自己被这个问题坑过太多次之后现在凡是要求稳定性的生产场景默认直接上随机森林。6.2 训练集得分 98 分测试集只有 70 分这是典型的过拟合问题也是最常见的一个坑。先检查一件事——树深了多少层。你用 clf.tree_.max_depth 看一眼如果深度在 20 以上基本可以断定是在背题。处理链路我一般是这样先把 max_depth 压到 5 试一轮然后把 min_samples_leaf 设到总样本量的 1% 左右比如 1 万条数据设 100看训练集和测试集的差距是否缩小。如果差距缩小但测试集分数也掉了不少说明你剪得太多、模型欠拟合了往回松一两个档位再对比。这里要强调调参的目的是缩小训练和测试的差距而不是单纯追求某一侧的分数。差距仍然大的时候不要急着加数据先检查剪枝参数是不是没设到位。6.3 特征全是数值型要不要做标准化不需要。决策树的分裂只关心特征的相对顺序和阈值不关心特征的绝对大小和分布形态。你对收入列做不做标准化最终的树结构基本一致阈值会等比变化。对比一下SVM 和 KNN 这类基于距离的模型不做标准化会出大问题但决策树就是任性。这个特性省事但也带来一个副作用决策树完全无法利用数值特征之间的相对距离信息。在评分卡或者线性模型里收入 5000 和收入 10000 的“差距是两倍”是有含义的但在决策树里它只看“是否大于 6000”。所以如果你觉得距离信息对业务很重要可以考虑把决策树和线性模型做集成各取所长。6.4 类别不平衡时怎么办——class_weight 参数前面说过决策树在类别不平衡时会被多数类带偏。最直接的补救办法是设 class_weightbalanced让算法根据类别频率自动加权少数类的错误会获得更高的惩罚权重。实测下来这个参数对召回率的提升非常明显。还是拿欺诈检测的场景举例默认决策树在测试集上召回率可能只有 0.2设了 class_weightbalanced 之后能提升到 0.6 以上。代价是准确率会下降一些因为模型会变得更激进地把样本判为少数类。如果试了 class_weight 还是不满意下一步就是过采样SMOTE或者欠采样。但我的建议是先用 class_weight 把基线拉起来再考虑重采样别一上来就动数据分布。再提醒一个细节用了 class_weight 之后你画出来的树还是那棵树但每个叶子节点的置信度含义变了。少数类叶子的概率可能被抬高了解读时要小心不能直接把叶子概率当作真实概率用。6.5 特征重要性列表怎么用才靠谱特征重要性虽然是一份“免费的礼物”但不能直接拿来当结论用。决策树会偏向取值多的特征这是这个机制自带的问题。更稳妥的做法是用随机森林的特征重要性或排列重要性Permutation Importance来和单棵树的重要性做交叉验证。只有多种方法都排在前面、而且业务逻辑也说得通的特征才值得你重点投入特征工程的精力。我踩过的一个具体坑是有一次跑单棵决策树的特征重要性发现“用户编号”这种 ID 类特征排得特别靠前。原因很简单——ID 取值太多树非常容易拿它做高增益分裂。但实际上这个特征对泛化毫无帮助纯粹是过拟合的产物。遇到这种ID 类特征排名靠前的情况直接在特征列表里删掉它别犹豫。最后说点实在的决策树的优缺点纸上读一百遍不如在项目里踩一次坑记得牢。我自己走过的弯路是早期做项目遇到什么数据都先无脑上决策树被过拟合、不稳定、解释不清这几个问题轮番教育之后才慢慢学会先判断业务需求是“要解释”还是“要精度”再决定到底该用一棵树还是几百棵树。如果你刚开始接触这个模型我给你一条最省事的入门路径先用默认参数练一棵树当基线然后把 max_depth 压到 3 到 5 层之间画个图看看树长什么样再用测试集估一下和训练集的差距。这一套下来你对决策树优缺点的理解会比背十篇博客都管用。
返回列表