2026/5/21 17:43:11
网站建设
项目流程
高端网站网站设计,上海制作网页的公司有哪些,wordpress 创建文集,微信提示WordPress登录【精选优质专栏推荐】 《AI 技术前沿》 —— 紧跟 AI 最新趋势与应用《网络安全新手快速入门(附漏洞挖掘案例)》 —— 零基础安全入门必看《BurpSuite 入门教程(附实战图文)》 —— 渗透测试必备工具详解《网安渗透工具使用教程(全)》 —— 一站式工具手册《CTF 新手入门实战教…【精选优质专栏推荐】《AI 技术前沿》—— 紧跟 AI 最新趋势与应用《网络安全新手快速入门(附漏洞挖掘案例)》—— 零基础安全入门必看《BurpSuite 入门教程(附实战图文)》—— 渗透测试必备工具详解《网安渗透工具使用教程(全)》—— 一站式工具手册《CTF 新手入门实战教程》—— 从题目讲解到实战技巧《前后端项目开发(新手必知必会)》—— 实战驱动快速上手每个专栏均配有案例与图文讲解循序渐进适合新手与进阶学习者欢迎订阅。文章目录前言1. 过拟合记住数据而非从数据中学习2. 欠拟合树太简单而无法良好工作3. 误导性的训练特征引起干扰总结前言在本文中你将了解决策树在实践中有时会失败的原因以及如何用简单有效的技术纠正常见问题。我们将涵盖的主题包括如何发现并减少决策树的过拟合。如何通过调整模型容量识别并修复欠拟合。噪声或冗余特征如何误导决策树以及特征选择如何提供帮助。基于决策树的预测型机器学习模型如分类和回归无疑具有很多优势——例如它们能够捕捉特征之间的非线性关系以及其直观的可解释性使得追踪决策变得容易。然而它们并非完美尤其是在中等到高复杂度的数据集上训练时容易出现过拟合、欠拟合或对噪声特征敏感等问题。在本文中我们将探讨训练好的决策树模型可能失败的三种常见原因并概述应对这些问题的简单而有效的策略。文中附有可供您自己尝试的 Python 示例。1. 过拟合记住数据而非从数据中学习Scikit-learn 在构建机器学习模型方面的简便性和直观性可能让人产生“默认构建模型就能得到满意结果”的想法。然而许多机器学习模型的一个常见问题是过拟合即模型从数据中学习得过多以至于几乎记住了所有接触过的数据样本。结果是当训练好的模型遇到新的、未见过的数据时它会难以正确预测输出。下面的示例在流行的公开 California Housing 数据集上训练决策树该数据集为中等复杂度和规模的回归任务常用数据集目标是基于人口统计特征和该地区的房屋平均特征预测加州某地区的房屋中位价。fromsklearn.datasetsimportfetch_california_housingfromsklearn.model_selectionimporttrain_test_splitfromsklearn.treeimportDecisionTreeRegressorfromsklearn.metricsimportmean_squared_errorimportnumpyasnp# 加载数据集并拆分为训练集和测试集X,yfetch_california_housing(return_X_yTrue,as_frameTrue)X_train,X_test,y_train,y_testtrain_test_split(X,y,random_state42)# 构建不限制最大深度的决策树overfit_treeDecisionTreeRegressor(random_state42)overfit_tree.fit(X_train,y_train)print(Train RMSE:,np.sqrt(mean_squared_error(y_train,overfit_tree.predict(X_train))))print(Test RMSE:,np.sqrt(mean_squared_error(y_test,overfit_tree.predict(X_test))))注意这里我们训练了一个基于决策树的回归器但没有指定任何超参数包括对树的形状和规模的约束。是的这会产生影响即训练样本的误差几乎为零如下的科学计数法 e-16 所示而测试集上的误差则远高于训练集。这是过拟合的明显标志。输出结果Train RMSE: 3.013481908235909e-16 Test RMSE: 0.7269954649985176为了解决过拟合问题一个常用策略是正则化即简化模型的复杂度。对于其他模型这通常涉及较复杂的数学方法而对于 scikit-learn 中的决策树则只需限制树的最大深度或叶节点的最小样本数等方面这两个超参数的设计旨在控制并防止树过度生长。pruned_treeDecisionTreeRegressor(max_depth6,min_samples_leaf20,random_state42)pruned_tree.fit(X_train,y_train)print(Train RMSE:,np.sqrt(mean_squared_error(y_train,pruned_tree.predict(X_train))))print(Test RMSE:,np.sqrt(mean_squared_error(y_test,pruned_tree.predict(X_test))))输出Train RMSE: 0.6617348643931361 Test RMSE: 0.6940789988854102总体而言第二棵树优于第一棵树尽管训练集的误差有所增加。关键在于测试数据上的误差这通常是模型在现实世界中表现的更好指标而这个误差相较于第一棵树确实有所下降。2. 欠拟合树太简单而无法良好工作与过拟合相反我们有欠拟合问题本质上是模型从训练数据中学习不足即便在训练数据上评估其表现也低于预期。过拟合的树通常过于庞大且很深而欠拟合通常与浅层树结构相关。解决欠拟合的一种方法是适度增加模型复杂度同时注意不要过度复杂从而引发前面讲过的过拟合问题。示例如下可在 Colab 或类似环境中尝试fromsklearn.datasetsimportfetch_openmlfromsklearn.treeimportDecisionTreeRegressorfromsklearn.model_selectionimporttrain_test_splitfromsklearn.metricsimportmean_squared_errorimportnumpyasnp winefetch_openml(namewine-quality-red,version1,as_frameTrue)X,ywine.data,wine.target.astype(float)X_train,X_test,y_train,y_testtrain_test_split(X,y,random_state42)# 树太浅深度为2可能导致欠拟合shallow_treeDecisionTreeRegressor(max_depth2,random_state42)shallow_tree.fit(X_train,y_train)print(Train RMSE:,np.sqrt(mean_squared_error(y_train,shallow_tree.predict(X_train))))print(Test RMSE:,np.sqrt(mean_squared_error(y_test,shallow_tree.predict(X_test))))增加深度以减少误差并缓解欠拟合的版本better_treeDecisionTreeRegressor(max_depth5,random_state42)better_tree.fit(X_train,y_train)print(Train RMSE:,np.sqrt(mean_squared_error(y_train,better_tree.predict(X_train))))print(Test RMSE:,np.sqrt(mean_squared_error(y_test,better_tree.predict(X_test))))3. 误导性的训练特征引起干扰决策树对不相关或冗余特征也非常敏感尤其是在与其他特征一起使用时。这与“信噪比”相关换句话说数据中有更多有价值的预测信息信号而噪声越少模型性能越好。举个例子一个游客在京都站附近迷路想去几公里外的清水寺。如果有人告诉她“乘坐 EX101 公交在五条坂下车然后沿着上坡的街道走”她很可能顺利到达目的地但如果给出的指示是“沿着街道走转很多弯记住各种街道名称”她可能再次迷路。这比喻了像决策树这样的模型中的“信噪比”问题。谨慎且有策略的特征选择通常是解决此类问题的有效方法。下面这个稍微复杂一些的示例展示了基线树模型、故意在数据集中加入人工噪声以模拟低质量训练数据以及随后通过特征选择提升模型性能之间的对比。fromsklearn.datasetsimportfetch_openmlfromsklearn.model_selectionimporttrain_test_splitfromsklearn.treeimportDecisionTreeClassifierfromsklearn.preprocessingimportOneHotEncoderfromsklearn.composeimportColumnTransformerfromsklearn.pipelineimportPipelinefromsklearn.feature_selectionimportSelectKBest,mutual_info_classiffromsklearn.metricsimportaccuracy_scoreimportnumpyasnp,pandasaspd,matplotlib.pyplotasplt adultfetch_openml(adult,version2,as_frameTrue)X,yadult.data,(adult.target50K).astype(int)cat,numX.select_dtypes(category).columns,X.select_dtypes(excludecategory).columns Xtr,Xte,ytr,ytetrain_test_split(X,y,stratifyy,random_state42)defmake_preprocessor(df):returnColumnTransformer([(num,passthrough,df.select_dtypes(excludecategory).columns),(cat,OneHotEncoder(handle_unknownignore),df.select_dtypes(category).columns)])# 基线模型basePipeline([(prep,make_preprocessor(X)),(clf,DecisionTreeClassifier(max_depthNone,random_state42))]).fit(Xtr,ytr)print(Baseline acc:,round(accuracy_score(yte,base.predict(Xte)),3))# 添加300个噪声特征模拟因噪声训练导致的低性能模型rngnp.random.RandomState(42)noisepd.DataFrame(rng.normal(size(len(X),300)),indexX.index,columns[fnoise_{i}foriinrange(300)])X_noisypd.concat([X,noise],axis1)Xtr,Xte,ytr,ytetrain_test_split(X_noisy,y,stratifyy,random_state42)noisyPipeline([(prep,make_preprocessor(X_noisy)),(clf,DecisionTreeClassifier(max_depthNone,random_state42))]).fit(Xtr,ytr)print(With noise acc:,round(accuracy_score(yte,noisy.predict(Xte)),3))# 解决方案在管道中使用 SelectKBest() 进行特征选择selPipeline([(prep,make_preprocessor(X_noisy)),(select,SelectKBest(mutual_info_classif,k20)),(clf,DecisionTreeClassifier(max_depthNone,random_state42))]).fit(Xtr,ytr)print(After selection acc:,round(accuracy_score(yte,sel.predict(Xte)),3))# 绘制特征重要性importancesnoisy.named_steps[clf].feature_importances_ namesnoisy.named_steps[prep].get_feature_names_out()pd.Series(importances,indexnames).nlargest(20).plot(kindbarh)plt.title(Top 20 Feature Importances (Noisy Model))plt.gca().invert_yaxis()plt.show()如果一切顺利经过特征选择后的模型应该产生最佳结果。可以尝试调整特征选择中的 k 值示例中设为20观察是否能进一步提升最后模型的性能。总结本文中我们探讨并演示了三种常见问题这些问题可能导致训练好的决策树模型表现不佳从欠拟合、过拟合到无关特征。同时我们展示了应对这些问题的简单而有效的策略。