机器学习——决策树(四)后剪枝

观前提示 :这是本人决策树相关的第四篇博文,前3篇的内容如下:

1、建造训练集的决策树【完成结点类编写和建树过程】

2、用验证集评估模型、选出泛化较好的数据划分方式训练模型

3、预剪枝

读者可根据需要从上方《机器学习》专栏中查阅对应文章

第四章是后剪枝的内容,用到了许多前文相关的代码

完整代码 都被集成到了colab的notebook当中,读者可以直接 运行。

指路:DrawPixel/decisionTree.ipynb at main · ndsoi/DrawPixel (github.com)

目录

1、后剪枝的理论部分

2、编程实践

1、划分训练集和验证集

​编辑2、生成训练集完整的决策树

3、收集所有的非叶结点

4、处理分支结点:划分or剪枝?


1、后剪枝的理论部分

作用:减少分支,提高模型的泛化能力

对比预剪枝:优势:防止训练不充分导致欠拟合;劣势:开销较大、时间较长

算法过程:

  1. 后剪枝先从训练集生成一棵完整决策树
  2. 从完整的决策树底层的非叶子结点出发,由下至上,对每一个分支结点(非叶子结点)考虑:
    1. 如果划分:验证集精度=a
    2. 如果不划分,令当前结点的label=1,class=max,验证集精度=b 比较a和b的大小:
      1. 如果a>b 则划分,令当前结点label = 0
      2. 如果a<=b 则不划分,令当前结点的label=1

2、编程实践

1、划分训练集和验证集

python 复制代码
train_data = D[0:3]+D[5:7]+[D[9]]+D[13:]
val_data = D[3:5]+[D[7]]+D[8:13]
print("训练集")
show(train_data)
print("验证集")
show(val_data)

2、生成训练集完整的决策树

python 复制代码
root_v5 = TreeGenerate(train_data,Attr)
drawTree(root_v5)

drawTree显示:

手绘更明确:

3、收集所有的非叶结点

python 复制代码
def collectAllNoLeaf(root):
  NoLeafQ = queue.Queue()
  NoLeafS = []
  if root.label == 1:
    # 根结点本身是叶子,那就没有讨论空间了
    print(f"根结点本身是叶子")
    return NoLeafS
  
  NoLeafQ.put(root)
  NoLeafS.append(root)

  while NoLeafQ.empty() == False:
    # 当前层的结点数目
    n = NoLeafQ.qsize()
    for i in range(n):
      cur = NoLeafQ.get()
      # cur结点的子结点的数目
      for value,node in cur.subDs.items():
        if node.label != 1:
          # 子结点不是叶子结点
          
          NoLeafS.append(node)
          NoLeafQ.put(node)
  return NoLeafS
NoLeafnodes = collectAllNoLeaf(root_v5) 

按层遍历了决策树,所有越底层的分支结点越在NoLeafnodes列表的后面

4、处理分支结点:划分or剪枝?

python 复制代码
# 倒叙遍历
def train_v5(NoLeafnodes,root,val_data):
  n = len(NoLeafnodes)

  for i in range(n):

    cur = NoLeafnodes[n-1-i]
    # 沿用predict_v4 精度计算方法
    res_o,acc_o = predict_v4(root,val_data)
    print(f"划分的预测序列{res_o}")
    # 假如当前不划分
    cur.label = 1
    cur.Class = cur.max
    # 计算精度
    res_d,acc_d = predict_v4(root,val_data)
    print(f"不划分的预测序列{res_d}")
    if acc_o > acc_d:
      # 划分的精度更高
      print(f"划分的精度更高,划分了以后{acc_o}\t不划分{acc_d}")
      cur.label = 0
    else:
      print(f"不划分的精度更高,划分了以后{acc_o}\t不划分{acc_d}")
  return root

r = train_v5(NoLeafnodes,root_v5,val_data)
drawTree(r)

结果:

剪枝后的决策树为:

从最后打印的信息可以看到,虽然剪枝后决策树的分类精度还是0.875 ,但模型得到了简化

相关推荐
IT古董1 小时前
【人工智能】Python在机器学习与人工智能中的应用
开发语言·人工智能·python·机器学习
机器人虎哥2 小时前
【8210A-TX2】Ubuntu18.04 + ROS_ Melodic + TM-16多线激光 雷达评测
人工智能·机器学习
罗小罗同学4 小时前
医工交叉入门书籍分享:Transformer模型在机器学习领域的应用|个人观点·24-11-22
深度学习·机器学习·transformer
孤独且没人爱的纸鹤4 小时前
【深度学习】:从人工神经网络的基础原理到循环神经网络的先进技术,跨越智能算法的关键发展阶段及其未来趋势,探索技术进步与应用挑战
人工智能·python·深度学习·机器学习·ai
羊小猪~~4 小时前
tensorflow案例7--数据增强与测试集, 训练集, 验证集的构建
人工智能·python·深度学习·机器学习·cnn·tensorflow·neo4j
不去幼儿园6 小时前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
无脑敲代码,bug漫天飞7 小时前
COR 损失函数
人工智能·机器学习
HPC_fac130520678168 小时前
以科学计算为切入点:剖析英伟达服务器过热难题
服务器·人工智能·深度学习·机器学习·计算机视觉·数据挖掘·gpu算力
老艾的AI世界16 小时前
AI翻唱神器,一键用你喜欢的歌手翻唱他人的曲目(附下载链接)
人工智能·深度学习·神经网络·机器学习·ai·ai翻唱·ai唱歌·ai歌曲
DK2215116 小时前
机器学习系列----关联分析
人工智能·机器学习