机器学习-专题详述

【流程】决策树建模完整流程

作者 : 老饼 发表日期 : 2022-06-26 09:51:05 更新日期 : 2024-06-30 19:50:58
本站原创文章,转载请说明来自《老饼讲解-机器学习》www.bbbdata.com




在决策树的实际应用中,我们并不是简单地调用一下sklearn构建一棵决策树,

而是需要一套完整的建模流程,包括数据处理、参数调优、剪枝等等操作,

本文讲述一个决策树建模的完整流程,具体代码实现在《决策树建模完整代码》




  01. 决策树建模-完整流程概述  






     决策树建模-完整流程概述     


决策树建模完整流程主要有五个:
 
1. 数据处理                                                                     
 对数据进行初步处理,使数据符合决策树模型的要求 
2. 试探建模极限                                                             
               试探性建模,粗略估计决策树模型的效果,以及训练误差的极限
3. 参数调优                                                                   
    对模型进行参数调优,得到泛化能力较好的决策树模型
也可以认为这部分是对决策进行预剪枝            

 4. 后剪枝                                                                      
           对构建好的决策树进行后剪枝,进一步加强模型的泛化能力
 5. 模型提取                                                                   
          对决策树进行可视化,以及提取模型的结构,以便线上布署





   02. 决策树-数据处理   






   决策树建模-数据预处理   


在决策树建模前,需要先将数据处理成符合决策树要求的数据,然后将数据分割为训练、测试数据
一、数据适配预处理
1. 缺失值填充                                                                                                                 

决策树(CART)不支持缺失值,在建模前需要把缺失数据按业务逻辑处理成非缺失值
       备注:有人说决策树支持缺失值,其实说的是C4.5算法,sklearn用的是CART,不要搞混乱了
 
  2. 枚举变量转成数值变量                                                                                                    
CART树的每个节点都是判断 变量在阈值的 左边还是右边                                         
因此,它是不支持枚举变量的,需要处理成数值变量,处理方法不在此展开               
 二、训练、测试数据分割   
决策树是一个易于过拟合的模型,需要数据分割为两份:
1. 训练数据集(80%) :用于构建决策树                                
2. 测试数据集(20%):用于评估决策树的预测效果                
  在python中可以使用下述语句对数据进行分割:
train_X,test_X,train_y,test_y = train_test_split(X,y,test_size=0.2,random_state=0)






   03. 决策树建模-试探建模极限   





      决策树建模-试探模型极限      


为什么要试探模型极限
我们建模结果并不总是一直顺利如意,模型的结果可能不理想
效果不理想的原因,可能是数据问题,也可能是模型参数问题
所以,我们要先试探一下用这批数据建模的极限在哪里
如果很差,那就没必要在模型参数上太纠结了,应往数据上找问题
因为参数的调整,仅是让我们往这个极限上靠拢
所以,先试探一下最优模型,能让之后的建模过程心里更有底
试探决策树建模极限的方法  
决策树试探极限,我们这里采取的方法是把树分裂到极致,也就是把参数调到极致(即用默认参数)
#--------模型极限试探-----------------------------------
clf = tree.DecisionTreeClassifier(random_state=20)
clf         = clf.fit(all_X, all_y)  
total_socre      = clf.score(all_X,all_y)
clf         = clf.fit(train_X, train_y)  
train_socre      = clf.score(train_X,train_y)
print("\n========模型试探============")
print("全量数据建模准确率:",total_socre)
print("训练数据建模准确率:",train_socre)





   04. 决策树建模-参数调优(预剪枝)   





   预剪枝的实际操作方案   


建模中,我们需要考虑模型的泛化能力,因此需要设置预剪枝参数,
预剪枝参数怎么设?我这们里采用《参数网格扫描》+《交叉验证方法》进行参数确定
 什么是参数网格扫描  
例如,我们要确定参数max_depth和min_samples_leaf
预设max_depth扫描[3,5,7,9,11,13,15]7个值,min_samples_leaf扫描[1,3,5,7,9]5个值
那么它们的组合共有 5*7=35 种,然后对每组参数进行评估,最后选出最优的参数组合
  什么是K折交叉验证评估方法  
 
由于需要评估不同参数下的模型效果,不妨采用《K折交叉验证评估方法》来评估模型效果
  K折交叉验证评估方法思想如下:
例如5折交叉验证,则把数据分为5份,训练5轮,每轮训练用1份数据验证,其余4份训练

 这样最终每个样本都有预测值,最后把预测值的准确率(或其它指标)作为评估指标
"K折交叉验证评估方法"中评估指标时用的是检验数据,所以它评估的是泛化能力





      预剪枝时需要调优的参数    


预剪枝时一般调的参数有:
 
min_samples_leaf  :叶子节点最小样本数。
max_depth         :树分枝的最大深度          
random_state :随机种子                          

 其它不太常用的预剪枝参数则有
 
min_samples_leaf      :叶子节点最小样本数。              
min_samples_split      :节点分枝最小样本个数            
max_depth         :树分枝的最大深度                           
min_weight_fraction_leaf :叶子节点最小权重和         
min_impurity_decrease  :节点分枝最小纯度增长量    
max_leaf_nodes       :最大叶子节点数                        
 
criterion:节点不纯度评估函数(gini,entropy)          





   预剪枝的代码实现   


在sklearn中可用GridSearchCV进行K折交叉验证+网络扫描,
 主体代码如下
#-------网格扫描最优训练参数---------------------------
clf = tree.DecisionTreeClassifier(random_state=0)
param_test = {
             'max_depth':range(3,15,3)              # 最大深度
             ,'min_samples_leaf':range(5,20,3)
             ,'random_state':range(0,100,10)
             # ,'min_samples_split':range(5,20,3)
             # ,'splitter':('best','random')    
             # ,'criterion':('gini','entropy')      # 基尼信息熵
}
gsearch= GridSearchCV(estimator=clf,                # 对应模型
                param_grid=param_test,              # 要找最优的参数
                scoring=None,                       # 准确度评估标准 
                n_jobs=-1,                          # 并行数个数,-1:跟CPU核数一致
                cv = 5,                             # 交叉验证 5折
                verbose=0                           # 输出训练过程
                )
gsearch.fit(train_X,train_y)
print("\n========最优参数扫描结果============")
print("模型最佳评分:",gsearch.best_score_)
print("模型最佳参数:",gsearch.best_params_)






   05. 决策树建模-后剪枝调优   






     决策树建模-后剪枝调优     


为了进一步加强模型的泛化能力,和增加模型的合理性,
在最后阶段,我们会人工干预,进行后剪枝调优。
 打印决策树相关信息  
我们先打印出树结构信息、错误样本分布、树拓扑图、CCP路径等信息
 1.决策树结构信息                                                
 
    ====决策树信息=================                      
    叶子个数: 5                                                                       
    树的深度: 3                                                                       
    特征权重: [0.00277564 0.         0.54604969 0.45117467] 

2.错误样本在叶子节点的分布情况                                 
 
   leaf_node  num   is_err    err_rate                                      
        4              9        1       0.111111                                     


 3.决策树可视图                                                 
                                            

4.打印CCP路径                                                    

 
  ====CCP路径=================                                 
  ccp_alphas: [0.            0.0016   0.0138   0.2587   0.3298]        
   impurities : [0.0607    0.0624   0.0762   0.3349   0.6648]         

它的意思是:
 
 时,树的不纯度为 0.060737,
 
时,树的不纯度为 0.062414,
 
时,树的不纯度为 0.076260,
.....

 后剪枝  
参考CCP路径,我们选择一个可以接受的树不纯度,
找到对应的alpha,使用新的alpha重新训练模型,达到后剪枝效果
  例如,我们可接受的树不纯度为0.07626,
则可将alpha设为0.1(在0.01384与0.2587之间)重新训练模型,达到后剪枝效果

后剪枝是最后的优化步骤,我们需要参考以上信息,结合实际业务的特性,对其灵活进行剪枝





   05. 模型提取与布署   




     决策树模型提取与布署     


模型建好后,需要布署到生产,生产环境可能是JAVA环境,PYTHON环境等,
往往不能直接调用sklearn的模型对象(或者调用很麻烦),需要我们把决策树模型规则纯粹的提取出来

 提取决策树规则
提取决策树模型,只需要将描述模型的树结构、节点信息提取出来即可(即模型描述数据),
具体提取方法可参考《sklearn提取决策树规则代码》
 生产布署决策树
将模型描述数据发布到生产,
在生产环境上,加载模型描述数据,再使用决策树的通用预测代码对新样本预测即可









 End 





联系老饼