一、前述
决策树是一种非线性有监督分类模型,随机森林是一种非线性有监督分类模型。线性分类模型比如说逻辑回归,可能会存在不可分问题,但是非线性分类就不存在。
二、具体原理
ID3算法
1、相关术语
根节点:最顶层的分类条件
叶节点:代表每一个类别号
中间节点:中间分类条件
分枝:代表每一个条件的输出
二叉树:每一个节点上有两个分枝
多叉树:每一个节点上至少有两个分枝
2、决策树的生成:
数据不断分裂的递归过程,每一次分裂,尽可能让类别一样的数据在树的一边,当树的叶子节点的数据都是一类的时候,则停止分类。(if else 语句)
思考:既然决策树的作用是将类别一样的数据放在树的一边,那么 如果数据的类别越多,决策树的分类过程就越复杂,如果数据的类别越少,决策树的分类过程就越简单。那么怎么评价数据的类别的多少,我们用熵来衡量信息混乱程度指标。
3,熵的介绍
先看看数据的纯粹度
举例:
箱子1:100个红球
箱子2:50个红球 50个黑球
箱子3:10个红球 30个蓝球 60绿球
箱子4:各个颜色均10个球
凭人的直觉感受,箱子1是最纯粹的,箱子4是最混乱的,如何把人的直觉感受进行量化呢?
将这种纯粹度用数据进行量化,计算机才能读懂
举例:
度量信息混乱程度的指标
熵的介绍
熵的公式举例:
熵代表不确定性,不确定性越大,熵越大。内部的混乱程度越大。
比如两个集合 A有5个类别 每个类别2个值 则每个概率是0.2
比如B有两个类别,每个类别5个 ,则每个概率是0.5
显然0.5大于0.2所以熵大,混乱程度比较大。
信息熵H(X):信息熵是香农在1948年提出来量化信息的信息量的。熵的定义如下
n代表种类,每一个类别中,p1代表某个种类的概率*log当前种类的概率,然后将各个类别计算结果累加。
以上例子车祸的信息熵是 -(4/9log4/9+5/9log5/9)
条件熵:H(X|Y)类似于条件概率,在知道X的情况下(X,Y发生的熵),Y的不确定性(Y的熵)。
以上例子在知道温度的情况下,求车祸的概率。
hot 是3个,其中两个没有车祸,一个车祸,则-3/9(2/3log2/3+1/3log1/3)。
mild是2个,其中一个车祸,一个没有车祸,则-2/9(1/2log1/2+1/2log1/2)
cool是4个,其中三个车祸,一个没有车祸,则-4/9(3/4log3/4+1/4log1/4)。
以上相加即为已知温度的情况下,车祸的条件熵。
信息增益:代表熵的变化程度,
特征Y对训练集D的信息增益 g(D,Y)= H(X) - H(X,Y)
上个例子的信息熵 - 已知温度的条件熵 = 信息增益
信息增益表示的是特征X使得类Y的不确定性减少的程度
(分类后的转移性,希望分类后的结果是同类的在一起 所起的作用)
信息增益越大,熵的变化程度就越大,分的就越干脆,越彻底。不确定性越小。说白了决策树也就是让数据的熵越来越小的一个过程。
在构建决策树的时候就是选择信息增益最大的属性作为分裂条件(ID3)是的在每个非叶子节点熵进行测试时,都能获得最大的分类增益,是分类后数据集的熵最小,这样的处理方法是的决策树的平均深度较小,从而有效的提高了分类效率。
C 4.5 算法
有时候给个特征,他会分的特别多,但是完全分对了,比如在训练集里面的编号信息增益特别大的,都甚至等于根节点了,那肯定是不合适的了,问题在于行编号的数目太多了,分类太多意味着这个特征的本身的熵就很大,达到快要是整个的H(X),为了避免这样的情况发生,我们不是用信息增益本身,而是用信息增益除以这个特征本身的熵值,看看除以之后是多大,! 这就是信息增益率,,,如果用信息增益率就是 C4.5
CART算法:
CART使用的是GINI系数,相比ID3和C4.5,CART应用要多一些,既可以用于分类也可以用于回归。
CART假设决策时是二叉树,内部节点的特征取值是“是”和“否”·。左分支是取值为“是”的分支。右分支是取值为“左”的分支,。这样的决策树等价于递归的二分每个特征。将输入空间即特征空间划分为每一个有限单元,并在这些单元上确定预测的概率分布。也就是在输入给定的条件下输出条件概率分布。
CART算法由一下两步组成:
- 决策树的生成:基于训练数据集生成决策树,生成的决策树要尽量的大;
- 用验证数据集对已生成的树进行剪枝并选择最优子树,这时候损失函数最小作为剪枝的标准。
CART决策树的生成就是递归的构建二叉树的过程。CART决策树即可以用于分类也可以用于回归,本文仅讨论用于分类的CART。对于分类而言,CART用Gini系数最小化准则来进行特征选择,生成二叉树。GINI系数其实是用直线段代替曲线段的近似。GINI系数就是上的一阶近似。
公式如下:
比如两个集合 A有5个类别 每个类别2个值 则每个概率是0.2
比如B有两个类别,每个类别5个 ,则每个概率是0.5
假设C有一个类别,则基尼系数是0 ,类别越多,基尼系数越接近于1,所以
我们希望基尼系数越小越好
CART 生成算法方法如下:
输入:训练数据集, 停止计算的条件:
输出:CART决策树。
过程:
损失函数: 在以上构建好以后 ,评价函数如下:
(希望它越小越好,类似损失函数了)
三: 解决过拟合问题
1,背景
叶子节点的个数作为加权,叶子结点的熵乘以加权的加和就是评价函数,,,这就是损失函数。这个损失函数肯定是越小越好的。
如何评价?
用训练数据来计算损失函数,决策树不断的生成的时候,看看测试数据损失函数是不是变得越低了,这就是交互式的做调参的工作。因为我们可能需要做一些决策树叶子节点的剪枝,因为并不是数越高越好,因为树如果非常高的话,可能就过拟合了。
2:解决过拟合的两种方法
剪枝
随机森林
3,解决过拟合方法之剪枝
为什么要剪枝:决策树过拟合的风险很大,理论上完全可以把数据完全分开,(想象一下,如果输足够庞大,每个叶子结点不就是一个数据了吗)
剪枝策略:预剪枝,后剪枝
预剪枝:便建立决策树边进行剪枝的操作(更实用)
后剪枝:当建立完决策树后再进行剪枝操作。
预剪枝(用的多)
边生成熟的时候变剪枝,限制深度,叶子节点个数,叶子节点样本个数,信息增益量等 树的高度,每个叶节点包含的样本最小个数,每个叶节点分裂的时候包含的样本最小个数,每个叶节点最小的熵值等 max_depth min_sample_split min_sample_leaf min_weight_fraction_leaf,max_leaf_nodes max_features,增加min_超参 减小max_超参
后剪枝
叶子节点个数越多,损失越大。
还是生成一棵树后再去剪枝,alpha 值给定就行。
后剪枝举例:
4 , 解决过拟合方法 之 随机森林
思想 Bagging 的策略:
从样本集 中 重采样(有可能存在重复)选出n个样本在所有属性上,对这n个样本建立分类器(ID3、C4.5、CART、SVM、Logistic回归等)
重复上面两步 m 次,产生m个分类器将待预测数据放到这个m个分类器上,最后根据这个m个分类器的投票结果,决定带预测数据属于哪一类(就是少数服从多数的原则)
在Bagging策略的基础上进行修改后的一种算法,
- 从样本集 中用重采样(Bootstrap) 采样出n个样本;
- 从所有属性中随机选取 k个属性,选择出最佳分割属性作为节点创建决策树;
- 重复以上两步m次。即建立m棵CART决策树;
这m个CART决策树形成随机森林(样本随机,属性随机)通过投票决定数据属于哪一类。
当数据集很大的时候,我们随机选取数据集的一部分,生成一棵树,重复上述过程,我们可以生成一对形态各异的树,这些树在一起就叫做随机森林。
样本不平衡的常用处理方法;
如果样本数目 A类比B类多,且严重不平衡,
方法:
A类欠采样Undersampling
- 随机欠采样
- A类分成若干子类,分别于B类进入ML模型
- 基于聚类的A类分割
B类过采样 Oversampling
- 避免欠采样造成的信息丢失
B类数据合成Snthetic Data Generation
- 随机插值得到新样本
- SMOTE
代价敏感学习
- 降低A类权值,提高B类权值。
随机森林的思考:
在随机森林的构建过程中,由于各棵树之间是没有关系的,相对独立的;在构建
的过程中,构建第m棵子树的时候,不会考虑前面的m-1棵树。因此引出提升的算法,对分错的样本加权。
提升是一种机器学习技术,可以用于回归和分类的问题,它每一步产生弱预测模型(如决策树),并加权累加到总模型中;如果每一步的弱预测模型的生成都是依
据损失函数的梯度方式的,那么就称为梯度提升(Gradient boosting)提升技术的意义:如果一个问题存在弱预测模型,那么可以通过提升技术的办法得到一个强预测模型。
代码部分:
1 使用Sklearn构建决策树
官方英文文档地址:http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
sklearn.tree模块提供了决策树模型,用于解决分类问题和回归问题。使用方法如下图所示:
本次实战内容使用的是DecisionTreeClassifier和export_graphviz,前者用于决策树构建,后者用于决策树可视化。
2.1 DecisionTreeClassifier构建决策树
让我们先看下DecisionTreeClassifier这个函数,一共有12个参数:
参数说明如下:
- criterion:特征选择标准,可选参数,默认是gini,可以设置为entropy。gini是基尼不纯度,是将来自集合的某种结果随机应用于某一数据项的预期误差率,是一种基于统计的思想。entropy是香农熵,是一种基于信息论的思想。Sklearn把gini设为默认参数,应该也是做了相应的斟酌的,精度也许更高些?ID3算法使用的是entropy,CART算法使用的则是gini。
- splitter:特征划分点选择标准,可选参数,默认是
best
,可以设置为random
。每个结点的选择策略。best
参数是根据算法选择最佳的切分特征,例如gini
、entropy
。random
随机的在部分划分点中找局部最优的划分点。默认的”best”适合样本量不大的时候,而如果样本数据量非常大,此时决策树构建推荐”random”。 - max_features:划分时考虑的最大特征数,可选参数,默认是None。寻找最佳切分时考虑的最大特征数(n_features为总共的特征数),有如下6种情况:
- 如果max_features是整型的数,则考虑max_features个特征;
- 如果max_features是浮点型的数,则考虑int(max_features * n_features)个特征;
- 如果max_features设为
auto
,那么max_features = sqrt(n_features); - 如果max_features设为
sqrt
,那么max_featrues = sqrt(n_features),跟auto
一样; - 如果max_features设为
log2
,那么max_features = log2(n_features); - 如果max_features设为
None
,那么max_features = n_features,也就是所有特征都用。 - 一般来说,如果样本特征数不多,比如小于50,我们用默认的”None”就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。
- max_depth:决策树最大深,可选参数,默认是
None
。这个参数是这是树的层数的。层数的概念就是,比如在贷款的例子中,决策树的层数是2层。如果这个参数设置为None
,那么决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。或者如果设置了min_samples_slipt
参数,那么直到少于min_smaples_split
个样本为止。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。
- min_samples_split:内部节点再划分所需最小样本数,可选参数,默认是2。这个值限制了子树继续划分的条件。如果
min_samples_split
为整数,那么在切分内部结点的时候,min_samples_split
作为最小的样本数,也就是说,如果样本已经少于min_samples_split
个样本,则停止继续切分。如果min_samples_split
为浮点数,那么min_samples_split
就是一个百分比,ceil(min_samples_split * n_samples),数是向上取整的。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。
- min_weight_fraction_leaf:叶子节点最小的样本权重和,可选参数,默认是0。这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。
- max_leaf_nodes:最大叶子节点数,可选参数,默认是
None
。通过限制最大叶子节点数,可以防止过拟合。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。
- class_weight:类别权重,可选参数,默认是
None
,也可以字典、字典列表、balanced
。指定样本各类别的的权重,主要是为了防止训练集某些类别的样本过多,导致训练的决策树过于偏向这些类别。类别的权重可以通过{class_label:weight}
这样的格式给出,这里可以自己指定各个样本的权重,或者用balanced
,如果使用balanced
,则算法会自己计算权重,样本量少的类别所对应的样本权重会高。当然,如果你的样本类别分布没有明显的偏倚,则可以不管这个参数,选择默认的None
。
- random_state:可选参数,默认是
None
。随机数种子。如果是证书,那么random_state
会作为随机数生成器的随机数种子。随机数种子,如果没有设置随机数,随机出来的数与当前系统时间有关,每个时刻都是不同的。如果设置了随机数种子,那么相同随机数种子,不同时刻产生的随机数也是相同的。如果是RandomState instance
,那么random_state
是随机数生成器。如果为None
,则随机数生成器使用np.random。
- min_impurity_split:节点划分最小不纯度,可选参数,默认是1e-7。这是个阈值,这个值限制了决策树的增长,如果某节点的不纯度(基尼系数,信息增益,均方差,绝对差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。
- presort:数据是否预排序,可选参数,默认为
False
,这个值是布尔值,默认是False不排序。一般来说,如果样本量少或者限制了一个深度很小的决策树,设置为true可以让划分点选择更加快,决策树建立的更加快。如果样本量太大的话,反而没有什么好处。问题是样本量少的时候,我速度本来就不慢。所以这个值一般懒得理它就可以了。
除了这些参数要注意以外,其他在调参时的注意点有:
- 当样本数量少但是样本特征非常多的时候,决策树很容易过拟合,一般来说,样本数比特征数多一些会比较容易建立健壮的模型
- 如果样本数量少但是样本特征非常多,在拟合决策树模型前,推荐先做维度规约,比如主成分分析(PCA),特征选择(Losso)或者独立成分分析(ICA)。这样特征的维度会大大减小。再来拟合决策树模型效果会好。
- 推荐多用决策树的可视化,同时先限制决策树的深度,这样可以先观察下生成的决策树里数据的初步拟合情况,然后再决定是否要增加深度。
- 在训练模型时,注意观察样本的类别情况(主要指分类树),如果类别分布非常不均匀,就要考虑用class_weight来限制模型过于偏向样本多的类别。
- 决策树的数组使用的是numpy的float32类型,如果训练数据不是这样的格式,算法会先做copy再运行。
- 如果输入的样本矩阵是稀疏的,推荐在拟合前调用csc_matrix稀疏化,在预测前调用csr_matrix稀疏化。
sklearn.tree.DecisionTreeClassifier()提供了一些方法供我们使用,如下图所示:
具体使用方法见:https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
参考:
https://www.cnblogs.com/LHWorldBlog/p/8656608.html