13、数据分析--决策树

决策树可视化 库的下载和安装
https://www.jianshu.com/p/4f28335ee269

1.安装GraphViz
2.安装graphviz的python库

决策树简介

​ 计算机中树的数据结构,第一层的节点又叫根节点,最后最下面的一层叫叶节点,其他的是属性节点(内部节点)

​ 直观理解(决策树和KNN算法非常相似,所以也是能进行处理分类和回归的问题):

​ 决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支(上级分支到下级分支的过程)代表一个测试输出,每个叶节点代表一种类别。决策树是一种十分常用的分类回归方法。

​ 注:如果一些分支在分类的时候分出一个子节点能继续往下分,而另一个就已经到头得到答案了,那么这另一个节点就叫叶节点,而不是属性节点。

​ 实际案例:

​ 分类的情况下:

​ 凯特想在某征婚网站上寻找自己的另一半,但她发现在海量的信息中筛选出值得见面的人比较繁琐。因此,凯特想建立一个模型,让模型帮自己从众多候选者中筛选出自己有意愿见面的对象。

​ 做法:从网站里随机挑选了100个人,主要观察4个特征,并给出标记(是否见面)。然后凯特训练了一个决策树模型,通过模型对征婚网站上的人进行筛选

​ 回归的情况下(外标签换成了一定的分值形式,而不是分类标签):

​ 凯特想在某征婚网站上寻找自己的另一半,但她发现在海量的信息中筛选出值得见面的人比较繁琐。因此,凯特想建立一个模型,让模型帮自己从众多候选者中筛选出自己有意愿见面的对象。

​ 做法:从网站里随机挑选了100个人,主要观察4个特征,并给出标记(这个男生在自己心里的打分)。然后凯特训练了一个决策树模型,通过模型对征婚网站上的人进行筛选

​ 概述:

​ 决策树结构

​ 结点(node):内部结点和叶结点。内部结点=》特征;叶结点=》标签

​ 有向边

​ 分类决策树

​ 叶结点=》类别

​ 回归决策树

​ 叶结点=》实数

​ 使用:

​ 决策树的预测

​ 根结点开始,对实例的某一特征进行测试,根据测试结果将实例分配到其子结点,如此递归地对实例进

​ 行判断并分配,直至达到叶结点。

​ 叶结点对应什么?

​ 分类:输出得票最多的类(K选择一定样本后,把每个样本分到指定的叶节点中,出现概率最大的那类叶节点就是预测数据的结果)

​ 回归:输出样本标签的均值

​ 注:可以将决策树看成一个if-else规则的集合。每一个实例只被一条路径所覆盖

​ 起源介绍:

​ 从历史上来说,决策树的起源非常早,甚至在有机器学习之前就有决策树了,因为决策树模仿的是人类在做决策的过程。在医药、商业的应用里,如何让电脑模仿人类做决策是一个很早的人工智能问题

​ 决策树的构建包含了很多前人的巧思(启发式),但是为什么要这样做并没有什么理论保证,决策树的构建算法有上百种,没有人能说哪个好哪个不好,某些决策树算法流行起来,这些都是历史的选择。在Spark中实现了ID3算法和CART算法的决策树。

创建策略

​ 构建方式:

​ 第一步:确定评价决策树好坏的指标

​ 第二步:列举出所有可能的决策树,然后计算各自的指标,从而选出最优的一棵树

​ 注:决策树的根节点不同于KNN算法的根节点用来分界,而是要提前把大量不必要考量的数据给剔除,优化计算才是目的,从而需要有一种贪心策略

​ 贪心策略:

​ 贪心策略举例

​ 思想:确定贪心指标,在候选方案集合中执行一个让贪心指标最大的方案。不会从全局最优的角度思考问题,近似求解,这个解可能是次优解(sub-optimal)

​ 决策树的贪心指标

​ 信息增益

​ 候选方案集合(连续特征,离散特征)

​ 连续特征:比如年龄中<10岁,<20岁,<30岁等等都可以是划分点。假设:5种方案

​ 离散特征:

​ 多叉树:直接按照不同特征值划分即可,比如长相里的丑,中等,帅。1种方案

​ 二叉树:丑/中等帅,丑中等/帅,丑帅/中等,都是划分点。3种方案

​ 连续特征和离散特征划分点取并集,5+1或5+3种方案

​ 贪心指标设计:

​ 注:在每个结点上去选择最优划分点

​ 建树的方法论

​ 让叶结点尽早变得更纯(如分类标签中1占比非常高)

​ 不纯度指标:衡量不纯度的指标(纯度不能衡量时,可以衡量不纯的叶节点)

​ 树结点内样本标签不一致的程度(比如样本在根节点时大部分都能满足要求用1表示,不能满足的用0表示,如果再进行下一级节点筛选的时候,不能满足的样本增多了,所有样本未被多层节点筛选剔除的用1表示,这时每一层级的节点的总样本满足程度就不同,如果都是1所有样本都能通过最后一层筛选,那么就是最高的纯度了)

​ 纯度指标:衡量变纯程度的指标(信息增益)

​ 划分前的不纯度为a,比如划分后产生两个结点,它们的不纯度分别为b和c,可以对其加权为B和C,那信息增益=a-(B+C)

​ 建树过程

​ 遍历全体划分点候选集,选择信息增益最大的划分点构建决策树,递归执行

​ 度量指标(基尼指数和香农熵是度量分类的指标,均方误差是度量回归的指标):

基尼指数(分类):

​ 两次抽取,拿到两个不同类别实例的概率,如果结点中实例是纯的,那么基尼指数=0(越小越纯,如二分类中正反类型一样是达到阈值,在比例二分类两个类型比例一样都是0.5时,基尼指数也到最高值)

香农熵(分类):

​ 刻画不确定程度,如果结点中实例是纯的,那么香农熵=0

均方误差(回归):

​ 结点内的均方误差(图像最小值表示最纯)

信息增益(增益越大,通过两层间不纯度的差值比较越大,纯度也就越大,表示纯度的提升程度):

​ 信息增益 = 原来结点的不纯度 – 子结点不纯度的和

衡量结点不纯的指标(在度量指标的基础上的扩展出来的算法):

​ **ID3算法:**基于香农熵增益,缺点:会偏爱取值较多的特征(偏重特征某取值出现次数较多的那个值)

​ 香农熵增益 = 结点的香农熵 – 子结点香农熵的带权和

​ **C4.5算法:**基于香农熵增益比,缺点:计算复杂度高

​ 香农熵增益比 = 参数*香农熵增益 ps:某特征的特征值种类越多,那么参数越小。

​ **CART(分类和回归树的缩写)分类算法:**基于基尼指数增益

​ 基尼指数增益 = 结点的基尼指数 – 子结点的基尼指数的带权和

​ **CART回归算法:**基于方差增益

​ 方差增益 = 结点的方差 – 子结点的方差的带权和

​ 注:ID3和C4.5只能用来分类,CART能做分类和回归

ID3、C4.5、CART分类树算法总结

​ ID3和C4.5算法均只适合在小规模数据集上使用

​ ID3和C4.5算法都是单变量决策树(只能用来分类)

​ 当属性值取值比较多的时候,最好考虑C4.5算法,ID3得出的效果会比较差

​ 决策树分类一般情况只适合小数据量的情况(数据可以放内存)

​ CART算法是三种算法中最常用的一种决策树构建算法。

​ 三种算法的区别仅仅只是对于当前树的评价标准不同而已,ID3使用信息增益、C4.5使用信息增益率、CART使用基尼系数

​ CART算法构建的一定是二叉树,ID3和C4.5构建的不一定是二叉树(可能是多叉树)

​ 这个贪心指标怎么设计?

​ 第一步:设计衡量结点不纯度的指标

​ 第二步:设计衡量变纯程度的指标(信息增益,贪心指标)

​ 第三步:遍历全体划分点候选集,使用能让信息增益最大的划分点构建决策树。递归构建树,直到达到停止条件,完成整棵决策树的构建

候选集划分(选择怎样的分叉输出条件过程和选多少个分叉)

​ 注:选择分叉输出条件,往往都是通过信息提纯,看上级节点到下级节点不纯度的最大值来筛选的,选最大不纯度就是要在通过分叉来最大化的剔除样本,这样才能更具代表性的通过分叉来分出各种类型的下层节点

​ 划分类型:

​ 连续特征F1有10种取值:1、2、3、4、5、6、7、8、9、10

​ 离散特征F2有 4 种取值:A、B、C、D

​ 连续特征:

​ 如果是处理回归问题的话,候选集划分只能通过二叉树的形式分叉

​ 离散特征——多叉树:

​ ID3算法采用的是多叉树分法(应用的是逻辑回归的交叉熵)

​ 离散特征——二叉树:

​ CART树采用的二叉树分法(也是通过交叉熵和信息损失最少的时候,就是最优的候选集划分方式,这里用逆向思维理解,就是反例信息损失最少,肯定要正例概率最小,那么就可以理解正例保留的样本最少,传递到下一个层级的节点肯定是要最少的正例样本,那么这就是建立最优方式的过程)

​ 划分过程会把所有的可能类型都计算一遍,损失最少的就是最优的

构建流程(连续型的属性只能做成二叉树形式)

​ 演示建树过程:

​ 现有训练集如下,请使用ID3算法训练一个决策树模型,对未来的西瓜的优劣做预测

​ 在决策树开始学习时,根结点包含D中所有样例,|Y|=2,其中正例占p1=8/17,反例占p2=9/17。于是根节点的香农熵(算式和交叉熵相似)为:

​ 全体划分点候选集:{色泽=?,根蒂=?…,触感=?}

​ 思考:len(全体划分点候选集)=?

​ 先计算“色泽”,根据色泽可以将数据集D分为3个子集(由于色泽中不是以数值做属性的,所以分叉个数为不同属性的类型数目):

​ D1:{1,4,6,10,13,17}(正例p1=3/6,反例占p2=3/6)

​ D2:{2,3,7,8,9,15} (正例p1=4/6,反例占p2=2/6)

​ D3:{5,11,12,14,16}(正例p1=1/5,反例占p2=4/5)

    x1     x2     x3  label  score
0   青绿  0.697  0.460      0     71
1   乌黑  0.774  0.376      0     92
2   乌黑  0.634  0.264      0     86
3   青绿  0.608  0.318      0     79
4   浅白  0.556  0.215      0     91
5   青绿  0.403  0.237      0     88
6   乌黑  0.481  0.149      0     85
7   乌黑  0.437  0.211      0     94
8   乌黑  0.666  0.091      1     31
9   青绿  0.243  0.267      1     22

先求得根节点的不纯度(这里的香农熵增益可以用不纯度来理解,和交叉熵有相似)

#计算根结点中label=0的占比   f1好瓜概率
f1 = 1.0*df[df["label"]==0].shape[0]/df.shape[0]
##计算根结点中label=1的占比
f2 = 1 - f1
##计算根结点香农熵
ent = -1 * f1*log_safe(f1) - f2*log_safe(f2)
print('ent:', ent)

计算x1=青绿的样本集合下香农熵

##获取x1=青绿的样本集合
df1 = df[df["x1"]=="青绿"]
##计算x1=青绿的样本集合下label=0的占比
f1 = 1.0*df1[df1["label"]==0].shape[0]/df1.shape[0]
##计算x1=青绿的样本集合下label=1的占比
f2 = 1 - f1

ent1 = -1 * f1*log_safe(f1) - f2*log_safe(f2)
print('ent1:', ent1)

计算香农熵增益

需要用根节点减去子节点的左右分叉的增益(即父节点减所属的所有子节点)

IG = ent - 1.0*df1.shape[0]/df.shape[0] * ent1 - 1.0*df2.shape[0]/df.shape[0] * ent2 - 1.0*df3.shape[0]/df.shape[0] * ent3
print(IG)

​ 计算使用“色泽”划分数据集后的信息增益(根节点减去子节点的不纯度)

​ Gain(色泽)=Ent(D)—Ent(D)

​ 类似地,计算出使用其他属性划分数据集后的信息增益

​ 显然,选择“纹理”划分后信息增益最大,于是,通过“纹理”划分数据集

注:这里定义反例为纯度的标准,反例越多越纯,所以信息增益越大,证明在分叉过程引入的建树集合划分是越优的,同样是剔除最大的原理,不仅是单层的候选集划分要应用,多层的根节点或上级节点的选择都是要应用,都是要在前一步就要把能剔除的尽量都剔除掉。

​ 每次建树之后,按照特征值将样本分配到对应结点,重复,便可得到完整的决策树

from sklearn.tree import DecisionTreeRegressor
#回归决策树,最大深度只有1层,因为是连续型的属性
model = DecisionTreeRegressor(max_depth=1)
#只针对x2数据和score进行拟合处理
print(model.fit(df[["x2"]], df["score"]))

​ 构建伪代码(用代码来假设构建流程):

def buildTree:

初始化根结点

确定全体划分点候选集

for //反复建树

for (i<-splits){ //试探性结点分裂

按照特征将样本转移到对应子结点

记录划分点和对应的信息增益

}

选择信息增益最大的划分点

进行结点分裂

if 满足停止构造的条件

break

return 树

可视化实现决策树

from sklearn import tree
import pydotplus
# 输出图像, filled对旁边区域进行填充, rounded 环绕  , 节点中属性的显示special_characters
dot_data = tree.export_graphviz(model, out_file=None,
                                filled=True, rounded=True,
                                special_characters=True)
#通过节点方式,生成图像
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_pdf('1.pdf')
graph.write_png('1.png')

剪枝处理

​ 决策树的剪枝:

​ 宽泛来讲:机器学习模型都会有过拟合风险,在训练集上表现的过于优秀,而泛化能力差,因此机器学习模型都有对应的防止过拟合的策略,决策树的策略就是剪枝

​ 具体来讲:决策树生成算法会递归地建造决策树的分支,直到结点都很纯为止。这样产生的决策树往往对训练数据的分类很准确,但失去泛化能力,即发生过拟合了,因此,可通过主动去掉一些分支来降低过拟合的风险,提高模型泛化能力

​ 过拟合处理:

​ 如何判断模型是否过拟合?

​ 可以看训练误差和测试误差的关系,测试误差越小,说明模型泛化能力越强

​ 剪枝方法:

​ 预剪枝(使用的较多):在决策树生成过程中,考察该轮划分是否会提高泛化性能,如果不能提高泛化性能就不划分

​ 优点:性能开销小、速度快

​ 缺点:可能会欠拟合,错过最优解

​ 后剪枝:先训练一棵完整的树,然后自底向上地进行考察,如果删除该划分能提高泛化性能就删除

​ 优点:欠拟合风险小

​ 缺点:性能开销大、速度慢

​ Spark & sklearn

​ ①树的深度等于超参数maxDepth (根节点以下的层数,maxDepth是一层层的剪到剩下多少层的方式)

​ ②没有分裂点能带来大于minInfoGain的信息增益(minInfoGain不代表剪到某一层数,而是分叉不能达到指定增益就不能分叉出来)

​ ③没有分裂点能让划分后的结点上至少有minInstances个实例(minInstances方式规定了分叉点分类数不能少于指定类型数目,否则就被剪掉)

​ 效果:类似于剪枝

​ 优点:性能开销小,求解速度快

​ 缺点:可能会欠拟合

​ 决策树模型优缺点:

优点(相当高级的算法):

​ 易于解释

​ 处理类别特征,其他的技术往往要求数据属性的单一

​ 延展到多分类

​ 不需要特征放缩(也不需要独热编码的操作,还可以不单独使用决策树,用于集成模型进行集成学习,构造随机森林)

​ 能捕获非线性关系和特征间的交互关系

缺点:

​ 寻找最优的决策树是一个NP-hard的问题,只能通过启发式方法求次优解

​ 决策树会因为样本发生一点点的改动,就会导致树结构的剧烈改变

​ 如果某些离散特征的特征值种类多,生成决策树容易偏向于这些特征 ID3

​ 有些比较复杂的关系,决策树很难学习,比如异或

补充:from math import log2的2是以2为底,不带2要自行添加参数作底数

#方差var和协方差cov,在特征中的属性为连续值时,var用于CART回归算法
for i in range(1, df.shape[0]):  # 遍历所有划分点
df1 = df.iloc[:i, :]  # 获取左子树的样本
impurity1 = np.var(df1["score"])  # 计算左子树的不纯度(方差)

df2 = df.iloc[i:, :]  # 获取右子树的样本
impurity2 = np.var(df2["score"])  # 计算右子树的不纯度(方差)

#     计算方差增益
a = impurity - (df1.shape[0] / df.shape[0] * impurity1 + df2.shape[0] / df.shape[0] * impurity2)

#max_depth 最大深度 过拟合
#min_samples_split 最小分支节点数量 过拟合
#min_samples_leaf 叶节点最小样本数 过拟合

导包:from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

T o r

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值