《老饼讲解机器学习》http://ml.bbbdata.com/teach#105
目录
一.数据处理
(一) 数据预处理
(二)训练、测试数据分割
二.试探建模极限
三.参数调优(预剪枝)
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)
建模中,我们需要考虑模型的泛化能力,因此需要设置预剪枝参数。
预剪枝参数怎么设?可以采用《交叉验证方法》+《参数网格扫描》进行参数确定。
例如,我们要确定参数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折交叉验证评估方法。
例如5折交叉验证,就是把数据分为5份,训练5轮,每轮训练用一份数据验证,其余4份训练。这样最终每个样本都有预测值,最后把预测值的准确率(或其它指标)作为评估指标。
由于评估指标用的都是检验数据,所以评估的是泛化能力。
通过网络扫描后,即可得到最优的参数组合。
一般调的参数有:
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决策树参数详解》