决策树建模完整流程

《老饼讲解机器学习》icon-default.png?t=N7T8https://www.bbbdata.com/ml/text/40


目录

一.数据处理

(一) 数据预处理

(二)训练、测试数据分割

二.试探建模极限

三.参数调优(预剪枝)

1.参数网络扫描

2.参数评估

3.待调优参数列表

四.后剪枝调优

(一) 打印决策树相关信息

(二) 剪枝

五.模型提取


决策树建模完整流程主要有五个:
1.数据处理
2.试探建模极限
3.参数调优
4.后剪枝
5.模型提取
本文只作流程介绍,完整代码见决策树建模完整代码

一.数据处理

(一) 数据预处理

1.缺失值填充:我们知道,决策树(CART)是不支持缺失值的,我们要把缺失数据按业务逻辑处理成非缺失值。
备注:也有人说决策树支持缺失值,其实说的是C4.5算法,sklearn用的是CART,不要搞混乱了
2.枚举变量转成数值变量:CART树的每个节点都是判断 变量在阈值的 左边还是右边,因此,它是不支持枚举变量的,需要处理成数值变量,处理方法不在此展开。

(二)训练、测试数据分割

决策树是一个易于过拟合的模型,因此,需要数据分割为两份:训练数据集(80%)、测试数据集(20%)。

train_X, test_X, train_y, test_y = train_test_split(all_X, all_y, test_size=0.2, random_state=0)

二.试探建模极限

我们建模结果并不总是一直顺利如意,模型的结果可能不理想,可能是数据问题,也可能是模型参数问题,
所以,我们要先试探一下用这批数据建模的极限在哪里。如果很差,那就没必要在模型参数上太纠结了,应往数据上找问题。
参数的调整,仅是让我们往这个极限上靠拢。所以,我们先试探一下最优模型,能让我们心里更有底。

决策树试探极限,只需要把参数调到极致(即用默认参数)就可以。

#--------模型极限试探-----------------------------------
clf = tree.DecisionTreeClassifier(max_depth=3,min_samples_leaf=8,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)

三.参数调优(预剪枝)

建模中,我们需要考虑模型的泛化能力,因此需要设置预剪枝参数。
预剪枝参数怎么设?可以采用《交叉验证方法》+《参数网格扫描》进行参数确定。

1.参数网络扫描

例如,我们要确定参数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种,然后对每组参数进行评估,最后选出最优的参数组数。

2.参数评估

参数评估方法:K折交叉验证评估方法。
例如5折交叉验证,就是把数据分为5份,训练5轮,每轮训练用一份数据验证,其余4份训练。这样最终每个样本都有预测值,最后把预测值的准确率(或其它指标)作为评估指标。
由于评估指标用的都是检验数据,所以评估的是泛化能力。

通过网络扫描后,即可得到最优的参数组合。

3.待调优参数列表

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

其它
(1)预剪枝参数:

min_samples_leaf            :叶子节点最小样本数。
min_samples_split           :节点分枝最小样本个数
max_depth                       :树分枝的最大深度
min_weight_fraction_leaf :叶子节点最小权重和
min_impurity_decrease   :节点分枝最小纯度增长量
max_leaf_nodes              :最大叶子节点数

(2)节点不纯度评估函数:
criterion:节点不纯度评估函数(gini,entropy)

#-------网格扫描最优训练参数---------------------------
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_)

四.后剪枝调优

为了进一步加强模型的泛化能力,和增加模型的合理性,在最后阶段,我们会人工干预,进行后剪枝调优。

(一) 打印决策树相关信息

(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.00167683 0.01384615 0.25871926 0.32988169]
impurities: [0.06073718      0.06241401 0.07626016 0.33497942 0.66486111]

它的意思是:
0<α <0.00167683时,树的不纯度为 0.06073718,
0.001676<\alphaα <0.013846时,树的不纯度为 0.06241,
0.013846<\alphaα <0.258719时,树的不纯度为 0.07626,
..... 

详细参考《sklearn决策树后剪枝

(二) 剪枝

CCP剪枝法: 参考CCP路径,我们选择一个可以接受的树不纯度,找到对应的alpha,对其剪枝。
例如,我们可接受的树不纯度为0.07626,则alpha可设为0.1(在0.01384与0.2587之间)对树进行剪树。

上面提供了多种信息,剪枝是最后的优化步骤,我们除了以上的信息,还要考虑实际业务的特性,对其灵活进行剪枝。

五.模型提取

模型建好后,需要布署到生产,生产环境可能是JAVA环境,PYTHON环境等,

主要思路是,只提取数据,再在生产环境写出通用预测代码(不是弄成一系列的if else)。

可以参考《sklearn提取决策树规则代码

相关文章

 《一个简单的决策树分类例子

sklearn决策树结果可视化

sklearn决策树参数详解