决策树(Decision Tree)是一种基本的分类与回归方法,其模型呈树状结构,在分类问题中,表示基于特征对实例进行分类的过程。本质上,决策树模型就是一个定义在特征空间与类空间上的条件概率分布。决策树学习通常包括三个步骤:特征选择
、决策树的生成
和决策树的修剪
。
- 定义
分类决策树模型是一种描述对实例进行分类的树形结构,决策树由节点(node)和有向边(directed edge)组成。节点有两种类型:内部节点(internal node)和叶节点(leaf node)。内部节点表示一个特征或属性,叶节点表示一个类。
利用决策树进行分类,从根节点开始,对实例的某一特征进行测试,根据测试结果将实例分配到其子节点;这时,每一个子节点对应着该特征的一个取值。如此递归地对实例进行测试并分配,直至达到叶节点。最后将实例分到叶节点的类中。
决策树是给定特征条件下类的条件概率分布,这一条件概率分布定义在特征区间的一个划分(partiton)上。将特征空间划分为互不相交的单元(cell)或区域(region),并在每个单元定义一个类的概率分布就构成了一个条件概率分布。决策树的一条路径对应划分中的一个单元,决策树所表示的条件概率分布由各个单元给定条件下类的条件概率分布组成。假设X为表示特征的随机变量,Y为表示类的随机变量,那么这个条件概率分布可以表示成P(Y|X)。X取值于给定划分下单元的集合,Y取值于类的集合,各叶节点(单元)上的条件概率往往偏向于某一个类,即属于某一类的概率较大,决策树分类时将该节点的实例分到条件概率大的那一类去。也就以为着决策树学习的过程其实也就是由数据集估计条件概率模型的过程,这些基于特征区间划分的类的条件概率模型由无穷多个,在进行选择时,不仅要考虑模型的拟合能力还要考虑其泛化能力。
为了使模型兼顾模型的拟合和泛化能力,决策树学习使用正则化的极大似然函数来作为损失函数,以最小化损失函数为目标,寻找最优的模型。显然从所有可能的决策树中选取最优决策树是NP完全问题,所以在实际中通常采用启发式的方法,近似求解这一最优化问题:通过递归的选择最优特征,根据该特征对训练数据进行划分直到使得各个子数据集有一个最好的分类,最终生成特征树。当然,这样得到的决策树实际上是次最优(sub-optimal)的。进一步的,由于决策树的算法特性,为了防止模型过拟合,需要对已生成的决策树自下而上进行剪枝,将树变得更简单,提升模型的泛化能力。具体来说,就是去掉过于细分的叶节点,使其退回到父节点,甚至更高的节点,然后将父节点或更高的节点改为新的叶节点。如果数据集的特征较多,也可以在进行决策树学习之前,对数据集进行特征筛选。
由于决策树是一个条件概率分布,所以深浅不同的决策树对应着不同复杂度的概率模型,决策树的生成对应模型的局部选择,决策树的剪枝对应着模型的全局选择。
-
常用决策树算法
决策树算法 算法描述 ID3
其核心是在决策树的各级节点上,使用 信息增益
作为属性的选择标准,来帮助确定生成每个节点时所采用的合适属性。C4.5
C4.5决策树生成算法相对于ID3的重要改进是使用 信息增益率
来选择节点属性C4.5可以克服ID3的不足:ID3只使用于离散的描述属性,而从C4.5既可以处理离散的描述属性,也可以处理连续的描述CART
CART决策树是一种十分有效的非参数分类和回归方法,通过构建树、修剪树、评估树来构建一个二叉树。当终结点是连续变量时,该树为回归树;当终结点是分类变量,该树为分类树。 信息熵
熵(Entropy)
的概念最早起源于物理学,最初物理学家用这个概念度量一个热力学系统的无序程度。在1948年,克劳德·艾尔伍德·香农将热力学的熵,引入到信息论,因此它又被称为香农熵。在信息论中,熵是对不确定性的量度,在一条信息的熵越高则能传输越多的信息,反之,则意味着传输的信息越少。
如果有一枚理想的硬币,其出现正面和反面的机会相等,则抛硬币事件的熵等于其能够达到的最大值。我们无法知道下一个硬币抛掷的结果是什么,因此每一次抛硬币都是不可预测的。因此,使用一枚正常硬币进行若干次抛掷,这个事件的熵是一比特,因为结果不外乎两个——正面或者反面,可以表示为0, 1
编码,而且两个结果彼此之间相互独立。若进行n
次独立实验,则熵为n
,因为可以用长度为n
的比特流表示。但是如果一枚硬币的两面完全相同,那个这个系列抛硬币事件的熵等于零,因为结果能被准确预测
。现实世界里,我们收集到的数据的熵介于上面两种情况之间。
另一个稍微复杂的例子是假设一个随机变量X
,取三种可能值,概率分别为,那么编码平均比特长度是:。其熵为。因此<u>熵实际是对随机变量的比特量和顺次发生概率相乘再总和的</u>数学期望。
依据玻尔兹曼H定理,香农把随机变量X的熵定义为:
其中是随机变量X的信息量,当随机变量取自有限样本时,熵可以表示为:
若,则定义。
同理可以定义条件熵:
很容易看出,条件熵(conditional entropy)就是X给定条件下Y的条件概率分布的熵对X的数学期望。当熵和条件熵中的概率有极大似然估计得到时,所对应的熵和条件熵分别称为检验熵(empirical entropy)和经验条件熵(empirical conditional entropy).
熵越大,随机变量的不确定性就越大,从定义可以验证:
当底数时,熵的单位是;当时,熵的单位是;而当时,熵的单位是.
如英语有26个字母,假如每个字母在文章中出现的次数平均的话,每个字母的信息量为:
同理常用汉字2500有个,假设每个汉字在文章中出现的次数平均的话,每个汉字的信息量为:
事实上每个字母和汉字在文章中出现的次数并不平均,少见字母和罕见汉字具有相对较高的信息量,显然,由期望的定义,熵是整个消息系统的平均消息量。
玻尔兹曼H定理
物理量H由定义,即分子在时间下的能量分布,是拥有动能的数量,则:对于孤立理想气体(总能量和分子数量不变),函数在玻尔兹曼分布下有极小值,该函数代表分子随时间流逝因传递而改变的动能,用于描述物理量H在接近理想气体系统中的下降趋势。
ID3
熵可以用来表示数据集的不确定性,熵越大,则数据集的不确定性越大。因此使用划分前后数据集熵的差值量度使用当前特征对于数据集进行划分的效果(类似于深度学习的代价函数)。对于待划分的数据集,其划分前的数据集的熵是一定的,但是划分之后的熵是不定的,越小说明使用此特征划分得到的子集的不确定性越小(也就是纯度越高)。因此越大,说明使用当前特征划分数据集时,纯度上升的更快。而我们在构建最优的决策树的时候总希望能更快速到达纯度更高的数据子集,这一点可以参考优化算法中的梯度下降算法,每一步沿着负梯度方法最小化损失函数的原因就是负梯度方向是函数值减小最快的方向。同理:在决策树构建的过程中我们总是希望集合往最快到达纯度更高的子集合方向发展,因此我们总是选择使得信息增益最大的特征来划分当前数据集。
显然这种划分方式是存在弊端的,按信息增益准则的划分方式,当数据集的某个特征B取值较多时,依此特征进行划分更容易得到纯度更高的数据子集,使得偏小,信息增益会偏大,最终导致信息增益偏向取值较多的特征。
设是个数据样本的集合,假定类别属性具有个不同的值:,设是类中的样本数。对于一个给定样本,它的信息熵为:
其中,是任意样本属于的概率,一般可以用估计。
设一个属性A具有个不同的值,利用属性A将集合划分为个子集,其中包含了集合中属性取值的样本。若选择属性A为测试属性,则这些子集就是从集合的节点生长出来的新的叶节点。设是子集中类别为的样本数,则根据属性A划分样本的信息熵为:
其中,是子集中类别为的样本的概率。最后,用属性A划分样本子集后所得的信息增益(Gain)
为:
即,<u>属性A的信息增益=划分前数据的熵-按属性A划分后数据子集的熵</u>。信息增益(information gain)又称为互信息(matual information)表示得知特征X的信息而使得类Y的信息的不确定性减少的程度。信息增益显然越小,的值越大,说明选择测试属性A对于分类提供的信息越多,选择A之后对分类的不确定程度越小。
ID3算法流程:
- 对当前样本集合,计算所有属性的信息增益;
- 选择信息增益最大的属性作为测试属性,把测试属性取值相同的样本划分为同一个子样本集;
- 若子样本集的类别属性只含有单个属性,则分支为叶子结点,判断其属性值并标上相应符号,然后返回;反之,对子样本集递归调用ID3算法;
C4.5
经典算法ID3
使用的信息增益特征选择准则会使得划分更偏相遇取值更多的特征,为了避免这种情况。ID3的提出者J.Ross Quinlan
提出了C4.5
,它在ID3的基础上将特征选择准则由信息增益
改为了信息增益率
。在信息增益的基础之上乘上一个惩罚参数。特征个数较多时,惩罚参数较小;特征个数较少时,惩罚参数较大(类似于正则化)。这个惩罚参数就是分裂信息度量
的倒数。
分裂信息度量
用于考虑某种属性进行分裂时分支的数量信息和尺寸信息,我们把这些信息称为属性的内在信息(instrisic information)。
则信息增益率:
显然属性的重要性随着内在信息的增大而减小(也就是说,如果这个属性本身不确定性就很大,那我就越不倾向于选取它),这样算是对单纯用信息增益有所补偿。但是,新的问题也随之出现,按照信息增益率的特征选择准则,对于取值较少的特征C,其分裂信息度量较小,该特征的信息增益率会偏大,导致信息增益率会偏向于取值较少的特征。为了避免这种情况,在实际应用中通常不是直接选择信息增益率最大的特征,而是现在候选特征中找出信息增益高于平均水平的特征,然后在这些特征中再选择信息增益率最高的特征。
CART
不同于ID3
和C4.5
,CART
使用基尼不纯度来作为特征选择准则。基尼不纯度也叫基尼指数,表示在样本集合中一个随机选中的样本被分错的概率
则<u>基尼指数(基尼不纯度)= 样本被选中的概率 * 样本被分错的概率</u>。Gini指数越小表示集合中被选中的样本被分错的概率越小,也就是说集合的纯度越高,反之,集合越不纯。
表示选中的样本属于i类别的概率,则该样本被分错的概率为
样本集合中有m个类别,一个随机选中的样本可以属于这m个类别中的任意一个,因为对类别直接加和
当为二分类问题时,
样本集合的基尼指数:
样本集合有m个类别,表示第个类别的样本数量,则的Gini指数为:
基于某个特征划分样本集合S之后的基尼指数:
CART是一个二叉树,也就是当使用某个特征划分样本集合后,得到两个集合:a.等于给定的特征值的样本集合;b.不等于给定特征值的样本集合。实质上是对拥有多个取值的特征的二值处理。
example:假设现在有一个特征“学历”,此特征有三个取值:“本科”、“硕士”、“博士”,现在使用这个特征对样本集合进行划分,划分值有三个,因而有三种划分的可能集合,划分后的自己如下:
划分点为:"本科",划分后的子集:{本科},{硕士,博士}
划分点为:"硕士",划分后的子集:{硕士},{本科,博士}
划分点为:"博士",划分后的子集:{博士},{硕士,本科}
对于上述的每一种划分,都可以计算出基于划分特=某个特征值将样本集合划分为两个子集的纯度:
因而对于一个具有多个取值(超过2个)的特征,需要计算以每个取值为划分点,对样本集合划分后子集的纯度(表示特征的可能取值)然后从所有的划分可能中找出Gini指数最小的划分,这个划分的划分点,就是使用特征对样本集合进行划分的最佳划分点。
参考文献:
【机器学习】深入理解--信息熵(Information Entropy)
实例
为了便于理解,利用以下数据集分别使用三种方法进行分类:
拥有房产 | 婚姻情况 | 年收入 | 能否偿还债务 |
---|---|---|---|
是 | 单身 | 125 | 否 |
否 | 已婚 | 100 | 否 |
否 | 单身 | 70 | 否 |
是 | 已婚 | 120 | 否 |
否 | 离婚 | 95 | 是 |
否 | 已婚 | 60 | 否 |
是 | 离婚 | 220 | 否 |
否 | 单身 | 85 | 是 |
否 | 已婚 | 75 | 否 |
否 | 单身 | 90 | 是 |
在进行具体分析之前,考虑到收入是数值类型,要使用决策树算法,需要先对该属性进行离散化。
在机器学习算法中,一些分类算法(ID3、Apriori等)要求数据是分类属性形式,因此在处理分类问题时经常需要将一些连续属性变换为分类属性。一般来说,连续属性的离散化都是通过在数据集的值域内设定若干个离散的划分点,将值域划分为若干区间,然后用不同的符号或整数数值代表落在每个子区间中的数据值。所以,离散化最核心的两个问题是:如何确定分类数以及如何将连续属性映射到这些分类值。常用的离散化方法有等宽法
,等频法
以及一维聚类法
等。
- 等宽离散化
等宽离散化的核心思想是通过将属性的值域分成具有相同宽度的区间,然后用不同的符号或整数数值代表落在每个子区间中的数据值。以数据集的收入属性为例,值域为,如果想将该属性的值分为三个区间,则区间的宽度,得到三个区间,落入相应区间的数据值分别命名为低收入、中等收入、高收入。则使用等宽离法散化后的数据集如下:
拥有房产 | 婚姻情况 | 年收入 | 能否偿还债务 |
---|---|---|---|
是 | 单身 | 中等收入 | 否 |
否 | 已婚 | 低收入 | 否 |
否 | 单身 | 低收入 | 否 |
是 | 已婚 | 中等收入 | 否 |
否 | 离婚 | 低收入 | 是 |
否 | 已婚 | 低收入 | 否 |
是 | 离婚 | 高收入 | 否 |
否 | 单身 | 低收入 | 是 |
否 | 已婚 | 低收入 | 否 |
否 | 单身 | 低收入 | 是 |
在实际使用时往往使用Pandas的cut()
函数实现等宽离散化:
pd.cut(Income,3,labels=['低收入','中等收入','高收入'])
[中等收入, 低收入, 低收入, 中等收入, 低收入, 低收入, 高收入, 低收入, 低收入, 低收入]Categories (3, object): [低收入 < 中等收入 < 高收入]
可以看到与手工计算的离散化结果相同,需要注意的是,<u>等宽法对于离群点比较敏感,倾向于不均匀地把属性值分布到各个区间,导致某些区间数据较多,某些区间数据很少,这显然不利用决策模型的建立。</u>
- 等频率离散化
等频法是将相同数量的属性取值放进每个区间,同样以收入数据的离散化为例:参考箱线图的分位点的概念,因为需要将收入属性的数值分为三个离散取值,需要选取四个分位点作为区间端点对数据进行划分,则每个分位点之间的分位点间隔为:
相当于将一个长度为1的区间平均分为3个区间,于是得到四个分位点分别为:,对应收入属性的数据为:
w = [1.0*i/3 for i in range(4)]
w = pd.Series(Income).describe(percentiles=w)[4:9]
# 以这几个分为点为区间端点将区间划分为三个子区间
w = [w['0%'],w['33.3%'],w['66.7%'],w['100%']]
print(w)
[60.0, 85.0, 100.0, 220.0]
使用四个分位数作为边界点,对区间进行划分:
# pandas的cut()函数在取区间时取得是开区间,为避免数据集的最小值无法套入区间,取最小区间的左端点为略小于数据集最小值的值
w['0%'] = w['0%']*(1-1e-10)
pd.cut(Income,w,labels=['低收入','中等收入','高收入'])
[高收入, 中等收入, 低收入, 高收入, 中等收入, 低收入, 高收入, 低收入, 低收入, 中等收入] Categories (3, object): [低收入 < 中等收入 < 高收入]
使用等频率离散化后的数据集为:
拥有房产 | 婚姻情况 | 年收入 | 能否偿还债务 |
---|---|---|---|
是 | 单身 | 高收入 | 否 |
否 | 已婚 | 中等收入 | 否 |
否 | 单身 | 低收入 | 否 |
是 | 已婚 | 高收入 | 否 |
否 | 离婚 | 中等收入 | 是 |
否 | 已婚 | 低收入 | 否 |
是 | 离婚 | 高收入 | 否 |
否 | 单身 | 低收入 | 是 |
否 | 已婚 | 低收入 | 否 |
否 | 单身 | 中等收入 | 是 |
<u>等频率离散化虽然避免了等宽离散化的数据分布不均匀的问题,却可能将相同的数据值分到不同的区间以满足每个区间具有相同数量的属性取值的要求。</u>
- 基于一维聚类的离散化
一般来说,基于一维聚类的离散化方法首先将连续属性的值用聚类算法进行聚类,然后再对聚类后得到的簇进行处理,将合并到一个簇的连续属性值做同一标记,聚类分析的离散化也需要用户指定簇的个数,从而决定产生的区间数。
from sklearn.cluster import KMeans
model = KMeans(n_clusters=3,n_jobs=4)
model.fit(Income.reshape((-1,1)))
# 输出聚类中心并排序
c = pd.DataFrame(model.cluster_centers_).sort_values(by=0)
# 将相邻簇求中点,作为边界点
m = c.rolling(2).mean().iloc[1:]
# 将数据集的首末两个边界点加上,得到4个边界点,将数据集划分为三个子区间
n = [0]+list(m[0])+[Income.max()]
pd.cut(Income,n)
[(93.0, 165.0], (93.0, 165.0], (0.0, 93.0], (93.0, 165.0], (93.0, 165.0], (0.0, 93.0], (165.0, 220.0], (0.0, 93.0], (0.0, 93.0], (0.0, 93.0]] Categories (3, interval[float64]): [(0.0, 93.0] < (93.0, 165.0] < (165.0, 220.0]]
进一步对得到的簇做标记:
pd.cut(Income,n,labels=['低收入','中等收入','高收入'])
[中等收入, 中等收入, 低收入, 中等收入, 中等收入, 低收入, 高收入, 低收入, 低收入, 低收入] Categories (3, object): [低收入 < 中等收入 < 高收入]
使用一维聚类的离散化方法后得到数据集为:
拥有房产 | 婚姻情况 | 年收入 | 能否偿还债务 |
---|---|---|---|
是 | 单身 | 中等收入 | 否 |
否 | 已婚 | 中等收入 | 否 |
否 | 单身 | 低收入 | 否 |
是 | 已婚 | 中等收入 | 否 |
否 | 离婚 | 中等收入 | 是 |
否 | 已婚 | 低收入 | 否 |
是 | 离婚 | 高收入 | 否 |
否 | 单身 | 低收入 | 是 |
否 | 已婚 | 低收入 | 否 |
否 | 单身 | 低收入 | 是 |
- 计算对应特征选择准则
在本次实例中选择使用基于聚类的离散化方法后得到的数据集进行指标计算。为了预测客户能否偿还债务,使用A(拥有房产)、B(婚姻情况)、C(年收入)等属性来进行数据集的划分最终构建决策树。
-
信息增益
1)计算数据集总的信息熵,其中10个数据中,能否偿还债务为'是'数据有3,'否'数据有7,则总的信息熵:
2)对于A(拥有房产)属性,其属性值有'是'和'否'两种。其中,在A为'是'的前提下,能否偿还债务为'是'的有1、'否'的有2;在A为'否'的前提下,能否偿还债务为'是'的有3、为'否'的有4,则A属性的信息熵为:
3)对于B(婚姻情况)属性,其属性值有'单身'、'已婚'、'离婚'三种。在B为'单身'的前提下,能否偿还作为为'是'的有3,为'否'的有1;在B为'已婚'的前提下,能否偿还作为为'是'的有0,为'否'的有4(因为在已婚的情况下,已经完全确定不能偿还债务,故信息熵为0);在B为'离婚'的前提下,能否偿还作为为'是'的有1,为'否'的有1;则B属性的信息熵为:
4)对于C(年收入)属性,其属性值有'高收入'、'中等输入、'低收入'三种。在C为'高收入'的前提下,能否偿还作为为'是'的有0,为'否'的有1,故该信息熵为0;在C为'中等收入'的前提下,能否偿还作为为'是'的有2,为'否'的有2;在C为'低收入'的前提下,能否偿还作为为'是'的有2,为'否'的有3;则C属性的信息熵为:
5)最后分别计算三个属性的信息增益值:
由前文的讨论可知,信息增益值越大,则使用该属性进行数据集的划分时,其纯度上升最快,由于:
故使用B属性进行划分,它的三个属性值作为该根节点的三个分支。
根据第一轮的最优特征选择,使用婚姻情况对数据集进行划分,因为其有三种属性故得到三个子数据集:
单身:
拥有房产 | 婚姻情况 | 年收入 | 能否偿还债务 |
---|---|---|---|
是 | 单身 | 中等收入 | 是 |
否 | 单身 | 低收入 | 否 |
否 | 单身 | 低收入 | 是 |
否 | 单身 | 低收入 | 是 |
离婚:
拥有房产 | 婚姻情况 | 年收入 | 能否偿还债务 |
---|---|---|---|
否 | 离婚 | 中等收入 | 是 |
是 | 离婚 | 高收入 | 否 |
已婚:
拥有房产 | 婚姻情况 | 年收入 | 能否偿还债务 |
---|---|---|---|
否 | 已婚 | 中等收入 | 否 |
是 | 已婚 | 中等收入 | 否 |
否 | 已婚 | 低收入 | 否 |
否 | 已婚 | 低收入 | 否 |
显然,由B属性取值'已婚'划分得到的子数据集属于同一个叶节点,无法再进行分类。
接下来,对由B属性取值'单身'划分得到的子数据集再进行最优特征选择:
1)计算数据集总的信息熵,其中4个数据中,能否偿还债务为'是'数据有3,'否'数据有1,则总的信息熵:
2)对于A(拥有房产)属性,其属性值有'是'和'否'两种。其中,在A为'是'的前提下,能否偿还债务为'是'的有1、'否'的有0;在A为'否'的前提下,能否偿还债务为'是'的有2、为'否'的有1,则A属性的信息熵为:
3)对于B(婚姻情况)属性,由于已被确定,在这个数据子集信息熵为0
4)对于C(年收入)属性,其属性值有'中等输入'、'低收入'两种。在C为'中等收入'的前提下,能否偿还作为为'是'的有1,为'否'的有0;在C为'低收入'的前提下,能否偿还作为为'是'的有2,为'否'的有1;则C属性的信息熵为:
5)最后分别计算两个属性的信息增益值:
信息增益值相同,说明以两个属性对数据子集进行划分后决策树的纯度上升是相同的,此时任选其一成为叶节点即可。
同理,对数据子集进行最优特征选择,发现信息熵为0:
整理得到最终的决策树:
- 总结
ID3算法只考虑了树的生成,所以使用该算法生成的树容易产生过拟合。因此在C4.5和CART算法中加入了树的剪枝来提升模型的泛化能力,本文主要说明使用决策树进行分类,关于CART回归树的部分以及决策树的剪枝,请等待后续更新。