决策树是非常盛行的模型,支持分类和回归。
决策树是高度可阐明的,并为更繁芜的算法,例如随机森林供应了根本。

决定筹划树的高级概述_节点_决议计划树 智能写作

决策树的构造可以看作是一个有向无环图,是一个节点序列。
这个图形是单向的,没有工具可以是其自身的子代。

看看上面的DAG,我们可以看到它从根节点开始,最好的属性变成内部节点,即决策节点。
然后,内部节点检讨条件并实行决策,将样本空间分为两部分。
叶子节点代表一个分类,当记录到达叶子节点时,算法将相应的叶子分配标签。
这个过程称为样本空间的递归划分。
决策树的术语:

父节点-具有子节点的节点子节点-父节点的孩子节点根节点-表示将拆分为两个或多个集(子节点)的样本空间/总体决策节点-分为多个子节点的节点(子节点)叶节点-没有子节点的节点(子节点)分支-决策树的一个子部分剪枝-通过删除节点来减少决策树的大小拆分标准

决策树利用一些代价函数来选择最优分割。
我们试图找到在分类数据方面表现最好的最佳属性/特色。
这个过程一贯重复,直达到到一个叶节点,因此被称为递归二元分割。

当实行这个过程时,所有的值都被排成一行,树将测试不同的拆分,并选择一个返回最低本钱的拆分,这使得这是一个贪婪的方法。

须要把稳的是,由于该算法将数据重复划分为更小的子集,因此终极的子集(叶节点)由几个或只有一个数据点组成。
这使得算法具有低偏差和高方差。

熵与信息增益

一个广泛利用的决策树度量是熵。
喷鼻香农熵,以喷鼻香农的名字命名,为我们供应了不愿定性的度量。
当涉及到数据时,熵见告我们数据有多混乱。
高熵值表示预测能力较低,可以将特色的熵视为该特色中的信息量。

决策树可以在进行拆分时最大限度地提高类的纯度,从而使叶节点中的类更加清晰。
熵是在每次分割前后打算出来的。
如果熵增加,将考试测验另一次拆分。
如果熵减小,分割将保持不变。
打算全体数据集熵的公式:

式中,是簇的数目,()是属于第i个簇的概率。
假设我们有一个包含462个正(1)标签和438个负(0)标签的数据集。
我们可以通过以下方法打算数据集的熵:

class_1_count=462class_0_count=438prob_class_1=(class_1_count/(class_1_count+class_0_count))prob_class_0=(class_0_count/(class_1_count+class_0_count))entropy=(-prob_class_0)np.log2(prob_class_0)-prob_class_1np.log2(prob_class_1)#熵:0.9994869809508898

信息增益利用熵作为不纯度的度量。
它是分割前和分割后的熵之差,它会给我们一个不愿定性降落多少的数字。
这也是ID3分类树算法中利用的关键准则,公式如下。

基尼不纯度

在实行分类任务时,利用基尼指数函数。
这个函数见告我们树中的叶节点有多“纯净”。
基尼不纯度总是在0到0.5之间,值越高,簇越无序。
公式如下:

个中()是属于第i个簇的概率。
上面的公式表明,基尼系数的不愿定性是1减去每个分割中不同概率的总和。

决策树剪枝

当决策树通过递归进行演习时,我们还可以设置停滞树的参数。
决策树越繁芜,越随意马虎过拟合。
我们可以利用超参数修剪树:

max_depth-决定我们希望树有多深min_samples_leaf—每个叶节点中的最小演习样本数max_leaf_nodes-最大叶节点数min_impurity_decrease—阈值,以确定节点将分裂还是成为叶子

有更多可以变动的参数,有关列表和更详细的解释,请查看文档:https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

利用Scikit-learn的决策树

让我们用sklearn构建一个决策树分类器。
我将利用泰坦尼克号数据集,目标是Survived特色。
我正在加载的数据集之前已经被清理过。
有关数据集中特色的描述,请参阅下面的数据字典。

导入必要的库

%load_extautoreload%autoreload2importosimportsysmodule_path=os.path.abspath(os.path.join(os.pardir,os.pardir))ifmodule_pathnotinsys.path:sys.path.append(module_path)importpandasaspdimportnumpyasnpimportmatplotlib.pyplotaspltimportseabornassnsimportwarningswarnings.filterwarnings('ignore')fromsklearn.metricsimportconfusion_matrix,plot_confusion_matrix,accuracy_scorefromsklearn.treeimportDecisionTreeClassifierfromsklearn.model_selectionimporttrain_test_split,cross_val_scorefromsklearn.preprocessingimportOneHotEncoder,StandardScalerfromsklearnimporttree加载和预览数据集

df=pd.read_csv("titanic_cleaned.csv")df.head()

定义预测和目标特色,实行演习测试集分割,并对数据进行预处理

X=df.drop('Survived',axis=1)y=df.Survived#演习测试分割X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=42)#导入scaler和encoderfromsklearn.preprocessingimportStandardScaler,OneHotEncoder#在数据帧中定义数字和分类特色numerical=['Age','Fare']categorical=["Pclass","SibSp","Parch","male"]#定义演习和测试索引变量来转换数据帧中的数值X_train_index=X_train.indexX_test_index=X_test.index#实例化一个hotencoder并定义演习和测试ohe=OneHotEncoder()X_train_ohe=X_train[categorical]X_test_ohe=X_test[categorical]#拟合并转换X_train_encoded=ohe.fit_transform(X_train_ohe)X_test_encoded=ohe.transform(X_test_ohe)#实例化StandardScaler并定义连续变量ss=StandardScaler()X_train_cont=X_train[numerical].astype(float)X_test_cont=X_test[numerical].astype(float)#缩放连续特色并将结果转换为数据帧X_train_scaled=pd.DataFrame(ss.fit_transform(X_train_cont),columns=X_train_cont.columns,index=X_train_index)X_test_scaled=pd.DataFrame(ss.transform(X_test_cont),columns=X_test_cont.columns,index=X_test_index)#定义演习和测试的列train_columns=ohe.get_feature_names(input_features=X_train_ohe.columns)test_columns=ohe.get_feature_names(input_features=X_test_ohe.columns)#将已编码的X_train和X_test转换为数据帧X_train_processed=pd.DataFrame(X_train_encoded.todense(),columns=train_columns,index=X_train_index)X_test_processed=pd.DataFrame(X_test_encoded.todense(),columns=test_columns,index=X_test_index)#为预处理过的X_train和X_test组合编码和缩放的数据帧X_train=pd.concat([X_train_scaled,X_train_processed],axis=1)X_test=pd.concat([X_test_scaled,X_test_processed],axis=1)演习决策树分类器

#用熵函数实例化决策树分类器以获取信息增益dtree=DecisionTreeClassifier(criterion='entropy')#拟合dtree.fit(X_train,y_train)fsm_train_acc=dtree.score(X_train,y_train)fsm_test_acc=dtree.score(X_test,y_test)print('BASELINETRAINACCURACY:{}\nBASELINETESTACCURACY:{}'.format(fsm_train_acc,fsm_test_acc))

决策树分类器在演习集上的性能优于测试集,表明模型过拟合。
决策树随意马虎过拟合,由于递归分割过程将一贯持续到叶节点,从而导致模型过于繁芜。
在这里,我们将实行超参数调度和修剪以优化分类器。

绘制树

为了直不雅观地看到拆分,绘制树可能会有所帮助。
我们可以用几个额外的库来绘制这棵树。

fromsklearnimportexternalsfromsklearn.externals.siximportStringIOfromIPython.displayimportImagefromsklearn.treeimportexport_graphvizimportpydotplusdot_data=StringIO()export_graphviz(dtree,out_file=dot_data,filled=True,rounded=True,special_characters=True,feature_names=X_train.columns)graph=pydotplus.graph_from_dot_data(dot_data.getvalue())Image(graph.create_png())

特色主要性

如果我们想检讨模型的特色主要性,可以利用决策树分类器中的.feature_importances_属性。
特色主要性利用基尼打算。

#离散列的one-hotencoded特色与.get_feature_names方法ohe_cols=list(ohe.get_feature_names(input_features=categorical))#数值列feats=list(numerical)feats.extend(ohe_cols)#利用explain_weights_df函数按升序包含特色主要性feat_imp=eli5.explain_weights_df(dtree,feature_names=feats)feat_imp

用网格搜索优化决策树分类器

通过运行交叉验证的网格搜索,我们可以输入一个参数字典,个中包含决策树超参数的不同值。
我利用了上面提到的超参数和默认的5倍交叉验证。

param_grid=[{'criterion':['gini','entropy'],'max_leaf_nodes':list(range(1,15)),'max_depth':list(range(2,10)),'min_impurity_decrease':[0.00005,0.0001,0.0002,0.0005,0.001,0.0015,0.002,0.005,0.01],'min_samples_leaf':list(range(1,39))}]fromsklearn.model_selectionimportGridSearchCVsearch=GridSearchCV(DecisionTreeClassifier(),param_grid=param_grid,cv=5)search.fit(X_train,y_train)

#演习集均匀准确度得分train_acc=search.best_estimator_.score(X_train,y_train)#测试集的均匀准确度得分test_acc=search.best_estimator_.score(X_test,y_test)print('GRIDSEARCHBESTPARAMETERS:\n\n\t\t{}\n\n'.format(search.best_estimator_))print('TRAINACCURACY:{}\nTESTACCURACY:{}\n'.format(train_acc,test_acc))

通过运行交叉验证网格搜索,最佳参数改进了我们的偏差-方差权衡。
具有默认参数的第一个模型在演习集上的表现比测试集好20%,表明树中的低偏差和高方差。
调度后的决策树表明,演习集和测试集的方差减小了5%,精度低落了5%。

CART回归

实行回归任务的决策树也将样本划分为更小的凑集。
回归树的目标是递归地划分样本空间,直到一个大略的回归模型可以拟合。

回归树中的叶节点是分区。
大略回归模型去拟合每个分区,然后取分区因变量的均值,即用样本均值进行预测。

我们利用上面的熵作为不纯度的度量来进行分类。
对付回归,CART算法利用均方偏差作为不纯度的度量。

是节点中的演习子集是节点中的演习样本数是第i个样本的目标值̂是预测目标值,样本的均匀值

在评估模型的性能时,我们将关注均方根偏差(RMSE)。
这只是平方偏差均匀值的平方根。
通过平方根,我们可以丈量偏差的大小,它比均匀值对较大偏差的权重更大。
我们评估模型拟合程度的度量是R方。
R方见告我们因变量中方差的百分比。

利用Scikit-learn回归树

让我们连续用sklearn构建一个决策树回归器。
我将利用从kaggle检索到的Ames住房数据集。
在本教程中,我将只利用3个连续特色和目标特色。

加载到数据集中,定义预测和目标特色,并实行演习测试集分割

df=pd.read_csv('ames.csv')X=df.SalePricey=df[['LotArea','1stFlrSF','GrLivArea']]X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=42)演习决策树回归器

fromsklearn.treeimportDecisionTreeRegressorfromsklearn.metricsimportmean_squared_error#实例化DecisionTreeRegressordtree_reg=DecisionTreeRegressor()#拟合回归函数到演习集dtree_reg.fit(X_train,y_train)reg_train_r2=dtree_reg.score(X_train,y_train)reg_train_rmse=mean_squared_error(y_train,dtree_reg.predict(X_train),squared=False)reg_test_r2=dtree_reg.score(X_test,y_test)reg_test_rmse=mean_squared_error(y_test,dtree_reg.predict(X_test),squared=False)print('BASELINETRAINR-SQUARED:{}|BASELINETRAINRMSE{}\\nBASELINETESTR-SQUARED:{}|BASELINETESTRMSE{}'.format(reg_train_r2,reg_train_rmse,reg_test_r2,reg_test_rmse))

再一次,决策树对演习集的拟合度过高。
与分类类似,我们可以运行交叉验证的网格搜索来优化决策树。

用网格搜索cv优化决策树回归器

param_grid=[{'criterion':['mse','mae'],'max_features':['sqrt','log2',0.1],'max_leaf_nodes':list(range(2,15)),'max_depth':list(range(2,32)),'min_impurity_decrease':[0.00005,0.0001,0.0002,0.0005,0.001,0.0015,0.002,0.005,0.01],'min_samples_leaf':list(range(1,39))}]reg_search=GridSearchCV(DecisionTreeRegressor(),param_grid=param_grid,cv=5)reg_search.fit(X_train,y_train)

train_r2=reg_search.best_estimator_.score(X_train,y_train)grid_train_rmse=mean_squared_error(y_train,reg_search.best_estimator_.predict(X_train),squared=False)test_r2=reg_search.best_estimator_.score(X_test,y_test)grid_test_rmse=mean_squared_error(y_test,reg_search.best_estimator.predict(X_test),squared=False)print('REGRESSIONGRIDSEARCHBESTPARAMETERS:\n\n\t\t{}\n\n'.format(reg_search.best_estimator_))print('TRAINR-SQUARED:{}\nTESTR-SQUARED:{}\n'.format(train_r2,test_r2))print('\nTRAINRMSE:{}\nTESTRMSE:{}'.format(grid_train_rmse,grid_test_rmse))

通过利用决策树回归器运行交叉验证网格搜索,我们提高了测试集的性能。
利用网格搜索中的参数,我们将测试集上的r方从0.42增加到0.56。
r方为0.58见告我们模型没有对演习数据进行过拟合,并且在看不见的测试集上也会有类似的表现。

结论

决策树是一种很好的预测模型,可以用于分类和回归。
对付大量的机器学习问题,它们具有高度的可阐明性和强大的功能。
虽然分类和回归任务之间有许多相似之处,但理解每个任务利用的不同度量是很主要的。

决策树的超参数有助于战胜它们对演习数据的过拟合方向。
须要把稳的是,虽然实行网格搜索有助于为决策树找到最佳的超参数,但它们的打算本钱也非常高。
根据可能选择的参数,网格搜索可能会运行数小时乃至数天。

参考引用1.10. Decision Trees. (n.d.). Retrieved from https://scikit-learn.org/stable/modules/tree.html#Sklearn.tree.DecisionTreeClassifier. (n.d.). Retrieved from https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.htmlSklearn.tree.DecisionTreeRegressor. (n.d.). Retrieved from https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeRegressor.htmlRonaghan, S. (2019, November 01). The Mathematics of Decision Trees, Random Forest and Feature Importance in Scikit-learn and Spark. Retrieved from https://towardsdatascience.com/the-mathematics-of-decision-trees-random-forest-and-feature-importance-in-scikit-learn-and-spark-f2861df67e314.2 — Recursive Partitioning. (n.d.). Retrieved from https://online.stat.psu.edu/stat555/node/100/Brownlee, J. (2020, August 14). Classification And Regression Trees for Machine Learning. Retrieved from https://machinelearningmastery.com/classification-and-regression-trees-for-machine-learning/Frost, J., Lombardi, J., Hadero, M., Aksamitova, J., Lamessa, Laurie, . . . Dubey, D. (2020, November 03). How To Interpret R-squared in Regression Analysis. Retrieved from https://statisticsbyjim.com/regression/interpret-r-squared-regression/RMSE: Root Mean Square Error. (2020, July 06). Retrieved from https://www.statisticshowto.com/probability-and-statistics/regression-analysis/rmse-root-mean-square-error/Sklearn.metrics.mean_squared_error. (n.d.). Retrieved from https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.htmlTitanic — Machine Learning from Disaster. (n.d.). Retrieved from https://www.kaggle.com/c/titanicAmes Housing Data Summer 2018. (n.d.). Retrieved from https://www.kaggle.com/c/ames-housing-data-summer-2018/data