赞
踩
首先我们需要从sklearn中的dataseats模块构建一个分类数据集,为了方便数据集的展示,在此构建一个二分类,特征数为2的数据集代码如下:
from sklearn.datasets import make_classification as mc
clfdata=mc(n_samples=500, n_features=2, n_informative=2, n_redundant=0,\
n_repeated=0, n_classes=2, n_clusters_per_class=1, random_state=10)
data,target=clfdata
plt.figure(figsize=(10,7),dpi=450)
plt.scatter(data[:,0],data[:,1],c=target)
plt.show()
数据分布如图:
数据集构建完毕之后,我们就可以使用sklearn中的tree.DesitionTreeClassifier模块进行分类决策树的构建,代码如下:
from sklearn.tree import DecisionTreeClassifier as CLF from sklearn.model_selection import train_test_split from sklearn.datasets import make_classification as mc from sklearn.tree import export_graphviz as eg import graphviz clfdata=mc(n_samples=500, n_features=2, n_informative=2, n_redundant=0,\ n_repeated=0, n_classes=2, n_clusters_per_class=1, random_state=10) #print(clfdata) data,target=clfdata xtrain,xtest,ytrain,ytest=train_test_split(data,target,test_size=0.3,random_state=0,\ stratify=target) clf=CLF(random_state=0) clf.fit(xtrain,ytrain) dot_data=eg(clf,out_file=None,filled=True)#out_file=None必须有,不然报错 gragh = graphviz.Source(dot_data) gragh.view() print('训练集准确率:',clf.score(xtrain,ytrain)) print('测试集准确率:',clf.score(xtest,ytest)) print('feature_importances_:',clf.feature_importances_,'\nmax_features_:',clf.max_features_,\ '\nn_classes_:',clf.n_classes_,'\nn_outputs_',clf.n_outputs_) print('决策树参数:',clf.get_params())
在没有进行任何调优的情况下,最后在测试集上的准确率为:0.7933,其相关属性如下:
生成决策树结构如下:
上面我们简单的构建了一个分类决策树,最后模型在训练集上的准确率为1,在测试集上的准确率为0.7933,表现不佳,这是很明显的过拟合。接下来我们使用GridSearchCV(网格搜索交叉验证)对模型进行调优(网格搜索交叉验证、K折验证交叉验证),从上面我们知道数的最大深度为9,可以在调优中进行设置,代码如下:
from sklearn.tree import DecisionTreeClassifier as CLF from sklearn.model_selection import train_test_split import numpy as np import pandas as pd from sklearn.datasets import make_classification as mc import matplotlib.pyplot as plt from sklearn.tree import export_graphviz as eg import graphviz from sklearn.model_selection import GridSearchCV as GSCV clfdata=mc(n_samples=500, n_features=2, n_informative=2, n_redundant=0,\ n_repeated=0, n_classes=2, n_clusters_per_class=1, random_state=10) data,target=clfdata xtrain,xtest,ytrain,ytest=train_test_split(data,target,test_size=0.3,random_state=0,\ stratify=target) clf=CLF(random_state=0) param_grid ={'criterion': ['gini','entropy'], 'max_depth': range(2,10), 'min_samples_split': [2,3,4], 'min_samples_leaf': [1,2,3], 'max_features': [None,1,2] }#可以是字典或列表 grid = GSCV(clf,param_grid,cv = 7,n_jobs = -1)#可以使用不同的CV进行测试,本例经过测试7为最佳 grid.fit(xtrain,ytrain) print('best_params_:',grid.best_params_,'\nbest_estimator_:',grid.best_estimator_,'\nbest_score_:',grid.best_score_) score=grid.score(xtest,ytest)#此时使用的是最佳参数进行准确率评估 print('test_score:',score) means=grid.cv_results_['mean_test_score']#不同参数下交叉验证的平均精度 paramnum=range(1,len(means)+1)#2*8*3*3*3种参数组合 plt.figure(figsize=(10,7),dpi=450) plt.plot(paramnum,means) plt.show()
输出结果如下:
不同参数组合下的平均准确率如图所示:
使用最佳组合的参数,进行决策树绘制,结构图如下:
通过对比调优前后的分类决策树结构图,我们可以很直观的看出调优后的决策树结构精简许多,并且在测试集上的识别准确率得到了很大的提升,对分类决策树的调优总结如下:
1、决策树的深度很大的话,容易造成过拟合,所以我们需要进行相应的剪枝操作,即设置参数‘max_depth’值(预剪枝),控制在一个合适的值,不宜过大。
2、在进行数据生成、实例化模型对象时,一定要注意设置‘random_state’的值,使其自始至终保持一个常数,要不然每次训练的数据结构都会不一样。
3、使用交叉验证可以有效的防止过拟合发生
4、在数据量较小、超参数较小的的情况下,使用GridSearchCV可以快速有效的对模型进行调优。
我们使用sklearn.datastes经典的波士顿房价数据集进行回归决策树的测试,该数据集是已字典的形式进行保存,首先来看一下数据集的结构:
from sklearn.datasets import load_boston
import pandas as pd
import numpy as np
boston=load_boston()
print(boston.keys())
输出如下:
dict_keys([‘data’, ‘target’, ‘feature_names’, ‘DESCR’, ‘filename’])
分别是:数据、目标值、特征名称、介绍文档、文件路径
我们可以看一下数据及目标值:
from sklearn.datasets import load_boston
import pandas as pd
import numpy as np
boston=load_boston()
boston_data=pd.concat([pd.DataFrame(boston.data,columns=boston.feature_names),\
pd.DataFrame(boston.target,columns=['Value'])],axis=1)
print(boston_data)
输出如下:
我们也可以将数据保存到excel中进行展示:
from sklearn.datasets import load_boston
import pandas as pd
import numpy as np
boston=load_boston()
save_path=r'E:\评分卡逻辑\决策树\实例讲解\boston_data.xlsx'
columns=list(boston.feature_names)
columns.append('Value')
X,y=boston.data,boston.target.reshape(-1,1)
all_data=np.hstack((X,y))
datasave=pd.DataFrame(all_data,columns=columns)
datasave.to_excel(save_path,index=False)
excel表格部分数据如下:
从图中我们可以知道,波士顿房价数据集包含了13个特征,共506条数据,各特征之间的数值量级差距较大,有兴趣的可以去看一下文档,了解各个特征所代表的的实际含义。
数据集构建完毕之后,我们就可以使用sklearn中的tree.DesitionTreeClassifier模块进行分类决策树的构建,代码如下:
from sklearn.tree import DecisionTreeRegressor as DTR from sklearn.datasets import load_boston from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error as MSE#均方误差 from sklearn.metrics import mean_absolute_error as MAE#平均绝对误差 from sklearn.tree import export_graphviz as eg import graphviz boston=load_boston() data,target=boston.data,boston.target xtrain,xtest,ytrain,ytest=train_test_split(data,target,test_size=0.3,random_state=0) dtr=DTR(random_state=0) dtr.fit(xtrain,ytrain) pred=dtr.predict(xtest) dot_data=eg(dtr,out_file=None,filled=True)#out_file=None必须有,不然报错 gragh = graphviz.Source(dot_data) gragh.view() print('均方误差:',MSE(pred,ytest),'\n平均绝对误差:',MAE(pred,ytest))
输出:
均方误差: 26.663881578947368
平均绝对误差: 3.0914473684210524
生成决策树结构图如下:
我们可以看见生成的回归决策树要比分类决策树的结构要复杂很多。
我们还是按照分类树调优逻辑对回归树进行调优,但是由于波士顿房价数据集各特征的特征值量级相差较大,我们首先需要对数据集进行同一量纲,方法包括标准化、归一化、中心化等,可参考统一量纲方法,在此我们使用归一化方法处理数据,代码如下:
from sklearn.datasets import load_boston from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error as MSE#均方误差 from sklearn.metrics import mean_absolute_error as MAE#平均绝对误差 from sklearn.tree import export_graphviz as eg import graphviz import pandas as pd #from sklearn.preprocessing import StandardScaler#标准化 from sklearn.preprocessing import MinMaxScaler#归一化 boston=load_boston() data,target=boston.data,boston.target transfer = MinMaxScaler(feature_range=(0, 1))#实例化,将数据映射在[0,1]范围内 data=transfer.fit_transform(data) #transfer=StandardScaler() #data=transfer.fit_transform(data) trans_df=pd.DataFrame(data,columns=boston.feature_names) save_path=r'E:\评分卡逻辑\决策树\实例讲解\trans_data.xlsx' trans_df.to_excel(save_path,index=False) xtrain,xtest,ytrain,ytest=train_test_split(data,target,test_size=0.3,random_state=0) dtr=DTR(random_state=0) dtr.fit(xtrain,ytrain) pred=dtr.predict(xtest) print('均方误差:',MSE(pred,ytest),'\n平均绝对误差:',MAE(pred,ytest))
归一化数据如下所示:
输出如下:
均方误差: 26.61493421052631
平均绝对误差: 3.083552631578947
数据归一化后均方误差和平均绝对误差下降少许,接下来还是使用GridSearchCV(网格搜索交叉验证)对模型进行调优,此时我们需要注意的是,对于回归问题,我们需要使用均方误差等指标来衡量模型的好坏(GridSearchCV中参数scoring参数的选择可参考:机器学习-GridSearchCV scoring 参数设置!、学习gridsearchcv 参数以及输出+多scoring),代码如下:
from sklearn.tree import DecisionTreeRegressor as DTR from sklearn.datasets import load_boston from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error as MSE#均方误差 from sklearn.metrics import mean_absolute_error as MAE#平均绝对误差 from sklearn.tree import export_graphviz as eg import graphviz import pandas as pd #from sklearn.preprocessing import StandardScaler#标准化 from sklearn.preprocessing import MinMaxScaler#归一化 from sklearn.model_selection import GridSearchCV as GSCV boston=load_boston() data,target=boston.data,boston.target transfer = MinMaxScaler(feature_range=(0, 1))#实例化,将数据映射在[0,1]范围内 data=transfer.fit_transform(data) #transfer=StandardScaler() #data=transfer.fit_transform(data) param_grid ={'criterion':['squared_error', 'friedman_mse', 'absolute_error', 'poisson'], 'max_depth': range(2,10), 'min_samples_split': range(4,8), 'min_samples_leaf': range(3,7), 'max_features': [None,1,2] }#可以是字典或列表 xtrain,xtest,ytrain,ytest=train_test_split(data,target,test_size=0.3,random_state=0) dtr=DTR(random_state=0) #for c in range(4,20): grid = GSCV(dtr,param_grid,cv = 14,scoring='neg_mean_squared_error',n_jobs = -1)#可以使用不同的CV进行测试,本例经过测试7为最佳 grid.fit(xtrain,ytrain) print('best_params_:',grid.best_params_,'\nbest_estimator_:',grid.best_estimator_) pred=grid.predict(xtest)#此时使用的是最佳参数进行准确率评估 print('均方误差:',MSE(pred,ytest),'\n平均绝对误差:',MAE(pred,ytest)) #print(grid.cv_results_.keys())
输出如下:
此时均方误差降低了不少,平均绝对误差基本不变,最佳参数生成的决策树结构图如下:
通过对比调优前后的回归决策树结构图,我们可以很直观的看出调优后的决策树结构精简许多,并且在测试集上的均方误差下降了不少,除了分类树调优需要注意的点外,回归树还需要注意:
1、使用GridSearchCV进行模型调优时,需要设置scoring参数,可以使用均方误差、平均绝对误差等;
2、相较于分类树的效果,回归树的效果要逊色不少,所以决策树一般用作分类比较多。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。