机器学习之决策树

一、基础理论

1.1、简介

  • 决策树是一种基本的分类与回归方法。分类问题中,表示基于特征对实例进行分类的过程,它可以认为是if-then规则的集合,主要优点就是可读性强,分类速度快。学习时,利用训练数据,根据损失函数最小化的原则进行建立决策树模型。决策树学习通常包括三个步骤:特征选择、决策树的生成和决策树的剪枝。
  • 决策树类似于流程图的树结构,由一个根节点,一组内部节点和一组叶节点组成。每个内部节点(包括根节点)表示在一个特征值,每个分枝表示一个特征值输出,每个叶节点表示一个类,有时不同的叶节点可以表示相同的类。
  • 图中,从年龄开始分支,年龄含有3个阶段,因此分出三根树枝;41-50年龄段的类输出为c1,因此这个树枝直接输出类别c1;年龄段<=40的输出类别含有两个c1和c2,所以需要继续分支,按照公司员工分支的话,再分出两条支线是或否,公司职员为是的类别输出只有c1,因此该分支直接输出c1,公司职员为否的类别输出只有c2,因此该分支直接输出c2;信誉度原理相同。
    在这里插入图片描述
    看完这张图就会有疑问了,你为什么不选择收入为节点呢?下面就看看如何选择特征进行分支的吧。

1.2、特征选择

  • 特征选择在于选取对训练数据都具有分类能力的特征,这样可以提高决策树学习的效率。如果利用一个特征进行分类的结果与随即分类的结果没有很大差别,则称这个特征是没有分类能力的。经验上舍掉这种特征对决策树学习的精度影响不大。通过特征选择的准则是信息增益和信息增益比。下面通过一个例子说明特征选择的问题。
    在这里插入图片描述
    希望通过所给数据学习一个贷款申请的决策树,用以对未来的贷款申请进行分类,即当新客户提出贷款申请时,根据申请人的特征利用决策树判断是否批准贷款申请。
    从表可以知道数据含有4个特征,一个类别。

1.2.1、信息增益

  • :表示随机变量不确定性的度量,设X为一个取有无限个值得离散随机变量,其概率分布为 P ( X = x i ) = p i , i = 1 , 2 , 3 … , n P(X=x_i)=p_i,i=1,2,3…,n P(X=xi)=pi,i=1,2,3,n,那么随机变量X得熵为
    H ( X ) = − ∑ i = 1 n p i l o g p i H(X)=-\sum^n_{i=1}p_ilogp_i H(X)=i=1npilogpi
    明显熵值与X的值无关,但与X的分布密切相关。熵越大,随机变量的不确定性越大。熵值范围[0,1]。
  • 条件熵:表示再随机变量X的条件下随机变量Y的不确定性。设随机变量(X,Y),其联合分布为 P ( X = x i , Y = y j ) = p i j , i = 1 , 2 , … , n , j = 1 , 2 , … m P(X=x_i,Y=y_j)=p_{ij},i=1,2,…,n,j=1,2,…m P(X=xi,Y=yj)=piji=1,2,,nj=1,2,m,条件熵为
    H ( Y ∣ X ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) H(Y|X)=\sum^n_{i=1}p_iH(Y|X=x_i) H(YX)=i=1npiH(YX=xi)
    这里的 p i = P ( X = x i ) , i = 1 , 2 … n p_i=P(X=x_i),i=1,2…n pi=P(X=xi),i=1,2n
    当熵和条件熵中的概率由数据估计(特别是极大似然估计)得到时,所对应的熵与条件熵分别成为经验熵和条件经验熵。
  • 信息增益:表示得知特征X的信息使得类Y的信息的不确定性减少的程度。特征A对训练集D的信息增益g(D,A),定义为集合D的经验熵与特征A给定条件下D的经验条件熵H(D|A)之差,即:(信息增益越大,不确定性减少程度越大,因此选择信息增益大的作为特征。)
    g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)H(DA)

1.2.3、信息增益比

  • 以信息增益作为划分数据集的特征,存在偏向于取值较多的特征的问题。使用信息增益比可以对该问题进行校正。这是特征选择的另一个准则。
  • 信息增益比:特征A对训练集D的信息增益比 g R ( D , A ) g_R(D,A) gR(D,A),定义为其信息增益g(D,A)与数据集D关于特征A的值的熵 H A ( D ) H_A(D) HA(D)之比,即:
    g R ( D , A ) = g ( D , A ) H A ( D ) g_R(D,A)=\frac {g(D,A)} {H_A(D)} gR(D,A)=HA(D)g(D,A)
    其中 H A ( D ) = − ∑ i = 1 n ∣ D i ∣ ∣ D ∣ l o g 2 ∣ D i ∣ ∣ D ∣ , n H_A(D)=-\sum^n_{i=1}{\frac{|D_i|}{|D|}}{log_2\frac{|D_i|}{|D|}},n HA(D)=i=1nDDilog2DDin是特征A取值的个数。

1.3、决策树的生成

1.3.1、ID3

  • 核心:在决策树各个节点上应用信息增益准则选择特征,递归的构建决策树。相当于利用极大似然法进行概率模型的选择。
  • 步骤
    • 选择信息增益最大的作为节点特征,由该特征的不同值建立子节点;
    • 再对子节点递归的调用上述方法,构建决策树;
    • 直到所有特征的信息增益均很小或没有特征可以选为止,最后得到一棵决策树。
  • 缺点
    • ID3利用的是信息增益,因此它存在偏向于取值较多的特征的问题。例如,如果有一个属性为日期,那么将有大量取值,这个属性可能会有非常高的信息增益。假如它被选作树的根结点的决策属性则可能形成一颗非常宽的树,这棵树可以理想地分类训练数据,但是对于测试数据的分类性能可能会相当差。
    • ID3算法只能处理离散值的特征。
    • ID3算法增长树的每一个分支的深度,直到恰好能对训练样例完美地分类。当数据中有噪声或训练样例的数量太少时,产生的树会过拟合
    • ID3算法在搜索过程中不进行回溯。所以,它易受无回溯的爬山搜索中的常见风险影响:收敛到局部最优而不是全局最优。

1.3.2、C4.5

  • 与ID3算法相似,C4.5对ID3进行了算法改进,C4.5在特征选择中,用信息增益比选择特征。其余一样的步骤。
  • 改进之处
    • 用信息增益比选择特征,克服了用信息增益选择特征时偏向于选择取值多的特征的不足
    • 能够完成对连续特征的离散化处理
    • 可以处理具有缺少特征值的训练样本
    • 在树构造过程中或者构造完成之后,通过使用不同的修剪技术以避免树的过度拟合
    • K折交叉验证
  • C4.5处理连续属性值
    • 将训练数据集D中样本按连续特征A的值进行递增排序,一般采用快速排序法。
    • 按该顺序逐一将两个相邻值的平均值a作为分割点,分割点将D划分为两个子集,分别对应特征A小于等于a和大于a的两个子集,这样最多有n-1个分割点(n为特征A的取值个数)。
    • 分别计算每个分割点的信息增益比,选择具有最大信息增益比率的分割点。
  • lC4.5处理特征缺失值
    • 其处理方法是用最常用的值替代或者是将最常用的值分在同一类中
    • 具体采用概率的方法,依据特征已知的值,计算各特征不同值的出现概率。例如,给定一个特征A,A中包含6个已知A=1和4个A=0的实例,那么A(x)=1的概率是0.6,而A(x)=0的概率是0.4。于是,实例x60%被分配到A=1的分支,40%被分配到另一个分支,目的是计算信息增益比。
  • 缺点
    • C4.5算法采用的是分而治之的策略,搜索过程中不进行回溯,在构造树的内部结点的时候是局部最优的搜索方式,所以它所得到的最终结果尽管有很高的准确性,仍然可能达不到全局最优的结果。
    • C4.5算法用一边构造决策树一边进行评价的方法构造决策树,当决策树构造出来之后,很难再调整树的结构和内容,决策树性能的改善十分困难。
    • C4.5算法也会产生过度拟合问题。
    • ID3算法和C4.5算法都是在建树时将训练集一次性装载入内存的。但当面对有着上百万条数据时,就无法实际应用这些算法。

1.4、决策树的剪枝

决策树生成算法递归的产生决策树,直到不能继续下去为止。这样产生的决策树对训练数据的分类很准确,但对测试数据的分类没有那么准确,即出现过拟合现象。过拟合的原因在于学习时过多的考虑对训练数据的正确分类,从而构建出复杂的决策树。解决这个问题的办法就是对决策树进行剪枝,使决策树简化。决策树简化的过程就叫做剪枝。

  • 预剪枝(pre-pruning):预剪枝就是在构造决策树的过程中,先对每个结点在划分前进行估计,若果当前结点的划分不能带来决策树模型泛华性能的提升,则不对当前结点进行划分并且将当前结点标记为叶结点。预剪枝使得决策树的很多分支都不会展开,这不仅降低了过拟合的风险,还显著减少了决策树的训练时间和测试时间。采用了贪心的思想,适合大规模问题。但预剪枝可能提前停止生长,有可能存在欠拟合的风险。
  • 后剪枝(post-pruning):后剪枝就是先把整颗决策树构造完毕,然后自底向上的对非叶结点进行考察,若将该结点对应的子树换为叶结点能够带来泛华性能的提升,则把该子树替换为叶结点。可以最大限度的保留树的各个节点,避免了欠拟合的风险。相较于预剪枝的时间开销巨大。

关于剪枝的内容可以参考其他博主的这篇文章,他把剪枝的过程写的很详细,可以看看。我觉得还是挺全面的。
决策树(decision tree)(二)——剪枝

1.5、例子(ID3算法)

在这里插入图片描述
经验熵 H ( D ) = − ∑ i = 1 n p i l o g p i = − 6 15 l o g 6 15 − 9 15 l o g 9 15 = 0.971 H(D)=-\sum^n_{i=1}p_ilogp_i=-\frac{6} {15}log\frac{6}{15}-\frac{9} {15}log\frac{9}{15}=0.971 H(D)=i=1npilogpi=156log156159log159=0.971
计算各特征对数据集D的信息增益,分别以A1,A2,A3,A4表示年龄、有工作、有自己的房子和信贷情况4个特征,则经验条件熵分别为:(按照特征取值分为n个子集,再计算子集熵,按比例加起来)
H ( D ∣ A 1 ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) = 5 15 ∗ ( − 2 5 l o g 2 5 − 3 5 l o g 3 5 ) + 5 15 ∗ ( − 3 5 l o g 3 5 − 2 5 l o g 2 5 ) + 5 15 ∗ ( − 4 5 l o g 4 5 − 1 5 l o g 1 5 ) = 0.888 H(D|A_1)=\sum^n_{i=1}p_iH(Y|X=x_i)=\frac{5}{15}*(-\frac{2} {5}log\frac{2}{5}-\frac{3} {5}log\frac{3}{5})+\frac{5}{15}*(-\frac{3} {5}log\frac{3}{5}-\frac{2} {5}log\frac{2}{5})+\frac{5}{15}*(-\frac{4} {5}log\frac{4}{5}-\frac{1} {5}log\frac{1}{5})=0.888 H(DA1)=i=1npiH(YX=xi)=155(52log5253log53)+155(53log5352log52)+155(54log5451log51)=0.888

H ( D ∣ A 2 ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) = 5 15 ∗ ( − 5 5 l o g 5 5 − 0 5 l o g 0 5 ) + 10 15 ∗ ( − 4 10 l o g 4 10 − 6 10 l o g 6 10 ) = 0.647 H(D|A_2)=\sum^n_{i=1}p_iH(Y|X=x_i)=\frac{5}{15}*(-\frac{5} {5}log\frac{5}{5}-\frac{0} {5}log\frac{0}{5})+\frac{10}{15}*(-\frac{4} {10}log\frac{4}{10}-\frac{6} {10}log\frac{6}{10})=0.647 H(DA2)=i=1npiH(YX=xi)=155(55log5550log50)+1510(104log104106log106)=0.647

H ( D ∣ A 3 ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) = 6 15 ∗ ( − 6 6 l o g 6 6 − 0 6 l o g 0 6 ) + 9 15 ∗ ( − 3 9 l o g 3 9 − 6 9 l o g 6 9 ) = 0.551 H(D|A_3)=\sum^n_{i=1}p_iH(Y|X=x_i)=\frac{6}{15}*(-\frac{6} {6}log\frac{6}{6}-\frac{0} {6}log\frac{0}{6})+\frac{9}{15}*(-\frac{3} {9}log\frac{3}{9}-\frac{6} {9}log\frac{6}{9})=0.551 H(DA3)=i=1npiH(YX=xi)=156(66log6660log60)+159(93log9396log96)=0.551

H ( D ∣ A 4 ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) = 5 15 ∗ ( − 1 5 l o g 1 5 − 4 5 l o g 4 5 ) + 6 15 ∗ ( − 4 6 l o g 4 6 − 2 6 l o g 2 6 ) + 4 15 ∗ ( − 4 4 l o g 4 4 − 0 4 l o g 0 4 ) = 0.608 H(D|A_4)=\sum^n_{i=1}p_iH(Y|X=x_i)=\frac{5}{15}*(-\frac{1} {5}log\frac{1}{5}-\frac{4} {5}log\frac{4}{5})+\frac{6}{15}*(-\frac{4} {6}log\frac{4}{6}-\frac{2} {6}log\frac{2}{6})+\frac{4}{15}*(-\frac{4} {4}log\frac{4}{4}-\frac{0} {4}log\frac{0}{4})=0.608 H(DA4)=i=1npiH(YX=xi)=155(51log5154log54)+156(64log6462log62)+154(44log4440log40)=0.608
各特征的信息增益为:
g ( D , A 1 ) = H ( D ) − H ( D ∣ A 1 ) = 0.971 − 0.888 = 0.083 g(D,A_1)=H(D)-H(D|A_1)=0.971-0.888=0.083 g(D,A1)=H(D)H(DA1)=0.9710.888=0.083
g ( D , A 2 ) = H ( D ) − H ( D ∣ A 2 ) = 0.971 − 0.647 = 0.324 g(D,A_2)=H(D)-H(D|A_2)=0.971-0.647=0.324 g(D,A2)=H(D)H(DA2)=0.9710.647=0.324
g ( D , A 3 ) = H ( D ) − H ( D ∣ A 3 ) = 0.971 − 0.551 = 0.420 g(D,A_3)=H(D)-H(D|A_3)=0.971-0.551=0.420 g(D,A3)=H(D)H(DA3)=0.9710.551=0.420
g ( D , A 4 ) = H ( D ) − H ( D ∣ A 4 ) = 0.971 − 0.608 = 0.363 g(D,A_4)=H(D)-H(D|A_4)=0.971-0.608=0.363 g(D,A4)=H(D)H(DA4)=0.9710.608=0.363
最后,比较各特征的信息增益,由于A3即有自己的房子的信息增益最大,因此选择有自己的房子为最优特征。根节点为有自己的房子。

  • 有自己的房子特征值为是的类别输出都为是,因此左支结束分支,特征值为否的类别输出既有是也有否,因此需要找特征继续分支。这次的数据子集为有自己的房子的特征值为否的数据,即9条数据,记为数据集D2(A3=否)。
    对D2则需从A1.A2,A4中选择新的特征,计算各特征的信息增益:
    以A1为例,类别是有3个数据,否有6个数据,根据这个计算D2的熵H(D2);年龄含有3个取值,青年(共4条数据,输出类别是1条,否3条)、中年(2条数据,输出类别是2条)、老年(3条数据,输出类别是2条,否1条)。
    g ( D 2 , A 1 ) = H ( D 2 ) − H ( D 2 ∣ A 1 ) = ( − 3 9 l o g 3 9 − 6 9 l o g 6 9 ) − [ 4 9 ( − 3 4 l o g 3 4 − 1 4 l o g 1 4 ) + 2 9 ( − 2 2 l o g 2 2 − 0 2 l o g 0 2 ) + 3 9 ( − 2 3 l o g 2 3 − 1 3 o g 1 3 ) ] = 0.251 g(D_2,A_1)=H(D_2)-H(D_2|A_1)=(-\frac3 9log\frac3 9-\frac6 9log\frac6 9)-[\frac4 9(-\frac3 4log\frac3 4-\frac1 4log\frac1 4)+\frac2 9(-\frac2 2log\frac2 2-\frac0 2log\frac0 2 )+\frac 3 9(-\frac2 3log\frac2 3-\frac1 3og\frac1 3 )]=0.251 g(D2,A1)=H(D2)H(D2A1)=(93log9396log96)[94(43log4341log41)+92(22log2220log20)+93(32log3231og31)]=0.251
    同理: g ( D 2 , A 2 ) = 0.918 g(D_2,A_2)=0.918 g(D2,A2)=0.918 G ( D 2 , A 4 ) = 0.474 G(D_2,A_4)=0.474 G(D2,A4)=0.474
    信息增益最大的是A2(有工作),因此针对A1特征为否的数据集继续按照A2(有工作)进行划分,A2=是的类别输出都为是,不需要继续分支了;A2=否的类别输出都为否,也不需要继续分支了。这样就生成了决策树,仅仅用了两个特征就完成了决策树的生成。如下:
    在这里插入图片描述

二、python实战

2.1、重要参数

  • Criterion这个参数正是用来决定模型特征选择的计算方法的。sklearn提供了两种选择:
    输入”entropy“,使用信息熵(Entropy)
    输入”gini“,使用基尼系数(Gini Impurity)
  • random_state & splitter
    random_state用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会表现更明显。
    splitter也是用来控制决策树中的随机选项的,有两种输入值,输入”best",决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看),输入“random",决策树在分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合。
  • max_depth
    限制树的最大深度,超过设定深度的树枝全部剪掉。这是用得最广泛的剪枝参数,在高维度低样本量时非常有效。决策树多生长一层,对样本量的需求会增加一倍,所以限制树深度能够有效地限制过拟合
  • min_samples_leaf
    min_samples_leaf ,一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生,或者,分枝会朝着满足每个子节点都包含min_samples_leaf个样本的方向去发生。一般搭配max_depth使用,在回归树中有神奇的效果,可以让模型变得更加平滑。这个参数的数量设置得太小会引起过拟合,设置得太大就会阻止模型学习数据。

2.2、回归

import numpy as np
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.tree import DecisionTreeRegressor,plot_tree 
plt.rcParams['font.sans-serif'] =['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

# 构造数据集
x = np.array([1,2,3,4,5,6,7,8,9,10])
y = [4.5,4.75,4.91,5.34,5.80,7.05,7.90,8.23,8.70,9]
# 创建决策树回归实例,树的最大深度为2
DR = DecisionTreeRegressor(max_depth=2)
# 拟合 输入数据必须是二维数组 reshape(-1,1)将一维数组转化为二维数组
tree_DR = DR.fit(x.reshape(-1,1),y)
# 散点图
plt.scatter(x,y,color='r',marker='o')
# 决策树回归线
plt.plot(x,tree_DR3.predict(x.reshape(-1,1)),label='决策树回归')
plt.legend()
plt.show()

在这里插入图片描述

2.3、分类

import numpy as np
from sklearn.tree import DecisionTreeClassifier  # 决策树分类器
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.tree import plot_tree  # 决策树可视化
from sklearn.datasets import load_iris # 鸾尾花数据集
from sklearn.model_selection import train_test_split # 训练集测试集分割
from sklearn.metrics import accuracy_score  # 准确度

plt.rcParams['font.sans-serif'] =['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

x = load_iris().data  # 输入特征
y = load_iris().target # 输出类别
x_train,x_test,y_train,y_test= train_test_split(x,y,test_size=0.3,random_state=2022) # 按3:7分割测试集和训练集
destree = DecisionTreeClassifier(criterion='entropy',splitter='best',max_depth=3)# 利用信息熵准则生成决策树 最大深度为3
dd = destree.fit(x_train,y_train) # 训练数据
ytest_pre = destree.predict(x_test) # 预测测试集
ytrain_pre = destree.predict(x_train) # 预测训练集
print(f'训练集准确度:{accuracy_score(y_train,ytrain_pre)}')
print(f'测试集准确度:{accuracy_score(y_test,ytest_pre)}')

训练集准确度:0.9619047619047619
测试集准确度:0.9555555555555556

print(dd.feature_importances_)  # 四个特征的重要性 最重要的是特征3,其次是特征4,最后是特征2和特征1
[0.01950424 0.04832737 0.64638568 0.28578271]

plt.figure(figsize=(8,6))
plot_tree(dd) # 决策树可视化
plt.show()

在这里插入图片描述

  • 输入四个特征,根据信息增益准则首先选取了特征3(X[2])分支,左枝value[36,0,0]表示X[2]<=2.45的鸾尾花全部为类别1,不需要往下分支了;而右枝value=[0,35,34]说明x[2]>2.45的含有35条类别2的数据和34条类别3的数据,需要继续选择重要性第二的特征4(x[3])分支,以x[3]=1.75为分割点,……,最后还是含有value=[0,9,3]和[0,1,2]表明这类中还是含有混合类别的,但我们在创建决策树时定义了最大深度为3,因此没有分完也必须终止分支了。如果不指定最大深度,默认直至全部类别都划分开结束分支。

参考:
《统计学习方法 李航著》
课后ppt

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
决策树是常用的机器学习算法之一,通过对数据的分类和特征值计算来完成对未知数据的预测。本文将介绍使用Python实现决策树算法的相关步骤。 首先,需要导入决策树算法工具包,使用以下代码: ```python from sklearn import tree ``` 然后,导入训练数据和测试数据,并进行预处理。为了方便起见,在本文中采用生成随机数的方式来生成样本数据,使用以下代码: ```python from sklearn.datasets import make_classification X, y = make_classification(n_samples=100, n_features=4, n_classes=2, n_informative=2, n_redundant=0, random_state=0, shuffle=False) ``` 接下来,使用生成的样本数据进行模型训练。这里使用scikit-learn中的DecisionTreeClassifier()函数。 ```python clf = tree.DecisionTreeClassifier() clf = clf.fit(X, y) ``` 训练后,调用predict()方法进行对测试数据的预测,使用以下代码: ```python y_pred = clf.predict(X) ``` 最后,评估模型的准确率,使用以下代码: ```python from sklearn.metrics import accuracy_score print(accuracy_score(y, y_pred)) ``` 这就是使用Python实现决策树算法的基本过程。决策树可以根据数据中的不同特征进行分类,是一个简单且常用的分类算法。决策树算法也可用于回归问题,例如预测一个数的大小。与其他机器学习算法相比,决策树具有易于理解和可解释的优点,同时还可以处理非线性的分类问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值