3. 决策树

监督学习:给定一堆样本,每个样本都有一组属性和一个类别,类别是事先已知的,利用样本学习得到一个分类器,这个分类器能够对新出现的实例给出正确的分类。这样的机器学习就是监督学习。
 
一、介绍
决策树(Decision Tree)是一种基本的分类与回归方法,本文主要讨论分类决策树。决策树模型呈树形结构,表示基于特征对实例进行分类的过程。是一种监管学习。
 
树模型和线性模型有什么区别? 树形模型是一个一个特征进行处理,线性模型是所有特征给予权重,相加得到一个新的值。
决策树与逻辑回归的分类区别,逻辑回归是将所有特征变换为概率后,大于某一概率阈值的划分为一类,小于某一概率阈值的为另一类;而决策树是对每一个特征做一个划分。另外逻辑回归只能找到线性分割(输入特征x与logit之间是线性的,除非对x进行多维映射),而决策树可以非线性分割。
树形模型更加接近人的思维方式,可以产生可视化的分类规则,产生的模型具有可解释性(可以抽取规则)。树模型拟合出来的函数其实是分区间的阶梯函数。
 
二、举例分析
简单判断水里的生物是不是鱼类。1. 不浮出水面能否生存。如果不能生存,则不是鱼类。如果能生存,2.是否有脚蹼,如果没有,则不是鱼类。如果有,则是鱼类。
以上判断过程,就是决策树进行决策的过程,树形图如下:
 
                                     
 
2.1. 组成:
    内部结点表示一个特征或属性
    结点: 表示一个分类
2.2. 基本流程:
    从根结点开始,对实例的某一个特征进行判断,根据判断结果,将实例分配到其子结点;每一个子结点对应该特征的一个取值。如此递归向下移动,直至达到叶结点,最后将实例分配到叶结点的类中。
 
三. 特征选择
    决策树算法的关键在于如何选择具有良好分类能力的特征,随着划分的不断进行,我们希望决策树的分支节点所包含的样本尽可能的属于同一类别。如果一个特征进行分类的结果与随机分类的结果没有很大差
    别,那特征是没有分类能力的。    
    为了找出最优特征,介绍一些信息论里面的概念。
    3.1 信息熵:度量样本集合纯度最常用的一种指标,假定当前样本集合D中第k类样本所占的比例为pk(k=1,2,...,|y|) ,则D的信息熵定义为:
                                               
                                                
      N代表了样本在某特征下分类的 类别数目,信息熵越小,样本纯度越高。
 
    3.2 信息增益:基于信息熵,对某个属性(特征)a定义“信息增益”
        假定离散属性a有V个可能的取值{a1,a2,...,aV},若使用a来对样本集D进行划分,则会产生V个分支节点,之中第v个节点包含了D中所有在属性a上取值为av的样本,记为Dv,我们可以计算出Dv的信息熵,在考虑到不同的分支节点包含的样本数的不同,给分支节点赋予权重|Dv|/|D|,
        信息增益:
                                           
    可记为Ent(av|a)表示特征属性a的条件下样本的条件熵,信息增益越大,则使用属性a来进行划分所获得的纯度越高,因此可以用来作为属性划分的依据 .
 
    3.3 信息增益率:基于信息增益定义信息增益率
    
                                          
    其中:
                                             
 
    IV(a)称为属性a的固有值,属性a的可能取值数目越多,则IV(a)的值通常会越大。增益率准则对取值数目较少的属性有所偏好。
 
    3.4 基尼指数:
    通过基尼值来度量数据集的纯度
    基尼值:      
                                                
    Gini(D)反映了从数据集D中取出两个样本,不为同一种类的概率,因此Gini(D)越小,数据集的纯度越高。
    基尼指数:
                                               
    在候选属性集合A中选择使那个划分后基尼指数最小的那个属性作为最优划分属性。
    特征选择:树根上以及树节点是哪个特征呢?这些特征是从最重要到次重要依次排序的,决策树方法是会把每个特征都试一遍,然后选取那个,能够使分类分的最好的特征,也就是说将A属性作为父节点,产生的纯度增益(GainA)要大于B属性作为父节点,则A作为优先选取的属性。
 
四、构造决策树
 ID3算法用的是信息增益,C4.5算法用信息增益率;CART算法使用基尼系数。
4.1 ID3算法:用于划分标称型数据集,没有剪枝的过程,为了去除过度数据匹配的问题,通过裁剪、合并相邻的无法产生大量信息增益的叶子节点(例如设置信息增益阀值)。
        4.1.1  缺点:1. 它偏向于具有大量值的属性。即在训练集中,某个属性所取的不同值的个数越多,那么越有可能拿它来作为分裂属性,而这样做有时候是没有意义的,
                   2. 不能处理连续分布的数据特征,CART算法也支持连续分布的数据特征。
        4.1.2 算法步骤:  
 1 输入:训练数据集D,特征集A,阈值
 2 输出:决策树T
 3 算法流程:
 4     1、 若D中所有实例属于同一类C,则T为单节点树,并将C作为该结点的类标记,返回T;
 5     2、 若A=空集,则T为单节点树,并将D中实例数最多的类C作为该结点的类标记,返回T;
 6     3、 否则,计算A中各特征对D的信息增益,选择信息增益最大的特征A1;
 7     4、 对A1的每一个取值,将D相应地分割成若干非空子集
 8     5、 以每一个子集重新作为根节点,重复上述过程,并依次递归进行
 9 
10 这样最终将会形成一个决策树。
        4.1.3 代码
 1 def chooseBestFeatureToSplitByID3(dataSet):
 2     '''
 3             选择最好的数据集划分方式
 4     :param dataSet:数据集
 5     :return: 划分结果
 6     '''
 7     numFeatures = len(dataSet[0]) - 1  # 最后一列yes分类标签,不属于特征向量
 8     baseEntropy = calcShannonEnt(dataSet)
 9     bestInfoGain = 0.0
10     bestFeature = -1
11     for i in range(numFeatures):  # 遍历所有特征
12         infoGain = calcInformationGain(dataSet, baseEntropy, i)     # 计算信息增益
13         if (infoGain > bestInfoGain):  # 选择最大的信息增益
14             bestInfoGain = infoGain
15             bestFeature = i
16     return bestFeature  # 返回最优特征对应的维度
17 
18 def majorityCnt(classList):
19     '''
20     采用多数表决的方法决定叶结点的分类
21     :param: 所有的类标签列表
22     :return: 出现次数最多的类
23     '''
24     classCount={}
25     for vote in classList:                  # 统计所有类标签的频数
26         if vote not in classCount.keys():
27             classCount[vote] = 0
28         classCount[vote] += 1
29     sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) # 排序
30     return sortedClassCount[0][0]
31 
32 def createTree(dataSet,labels):
33     '''
34     创建决策树
35     :param: dataSet:训练数据集
36     :return: labels:所有的类标签
37     '''
38     classList = [example[-1] for example in dataSet]
39     if classList.count(classList[0]) == len(classList): 
40         return classList[0]             # 第一个递归结束条件:所有的类标签完全相同
41     if len(dataSet[0]) == 1:        
42         return majorityCnt(classList)   # 第二个递归结束条件:用完了所有特征
43     bestFeat = chooseBestFeatureToSplitByID3(dataSet)   # 最优划分特征
44     bestFeatLabel = labels[bestFeat]
45     myTree = {bestFeatLabel:{}}         # 使用字典类型储存树的信息
46     del(labels[bestFeat])
47     featValues = [example[bestFeat] for example in dataSet]
48     uniqueVals = set(featValues)
49     for value in uniqueVals:
50         subLabels = labels[:]       # 复制所有类标签,保证每次递归调用时不改变原始列表的内容
51         myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
52     return myTree

 

4.2 C4.5算法
    4.2.1 
        优点:
        1) 克服了用信息增益选择属性时偏向取值多的属性,的不足;
        2) 在树构造过程中进行剪枝;
        3) 能够完成对连续属性的离散化处理
        4) 能够对不完整数据进行处理。
        缺点:
        1) 分类规则易于理解、准确率较高;但效率低,因树构造过程中,需要对数据集进行多次的顺序扫描和排序,只适合于能够驻留于内存的数据集
 
    4.2.2 算法步骤
        C4.5算法在结构与递归上与ID3完全相同,不同是,ID3算法是用信息增益来选择特征,而C4.5算法使用信息增益率来选择特征。
 
     4.2.3 代码
 1 def chooseBestFeatureToSplitByC45(dataSet):
 2     '''
 3             选择最好的数据集划分方式
 4     :param dataSet:
 5     :return: 划分结果
 6     '''
 7     numFeatures = len(dataSet[0]) - 1  # 最后一列yes分类标签,不属于特征变量
 8     baseEntropy = calcShannonEnt(dataSet)
 9     bestInfoGainRate = 0.0
10     bestFeature = -1
11     for i in range(numFeatures):  # 遍历所有维度特征
12         infoGainRate = calcInformationGainRatio(dataSet, baseEntropy, i)    # 计算信息增益比 
13         if (infoGainRate > bestInfoGainRate):  # 选择最大的信息增益比
14             bestInfoGainRate = infoGainRate
15             bestFeature = i
16     return bestFeature  # 返回最佳特征对应的维度
 
4.3 CART(classification and regression tree) 算法
     这个是最核心的决策树。因为以后使用到的random forest,gbdt, xgboost里面的base estimator 都是CART树。CART树既可以用于分类问题也可以用于回归问题。
    4.3.1 分类问题
        构造分类树,目标变量为离散变量。分类算法和上面介绍的ID3、C4.5是一样的,不同的是CART树用的是基尼指数来选择特征。比较基尼指数减少多少,减少的越多,则选取该分裂规则。
    4.3.2 回归问题
        构造回归树,目标变量为连续变量。比较阈值,高于某个阈值就属于某一类,低于某个阈值属于另一类。 
 
说明:在使用决策树寻找每一步的最优特征时,常用的是贪心算法,贪心算法有一个问题就是局部最优,而不是全局最优。
 
 
五、问题处理
 
5.1 过拟合处理
为了尽可能正确分类训练样本,结点划分过程不断重复,有时会造成决策树分支过多,导致过拟合。剪枝的基本策略有:预剪枝和后剪枝。
    5.1.1  预剪枝
    预剪枝是在决策树生成的过程中,对每个结点在划分前先进行预估,若当前结点的划分不能使决策树泛化性能提升,则停止划分并将当前结点标记为叶节点。
    5.1.2  后剪枝
    后剪枝是先从训练集中生成一颗完整的决策树,然后自底向上的对非叶子结点进行考察,若将该结点对应的子树替换为叶子结点能提高泛化能力,则进行替换。
 
5.2 连续值缺失值处理
由于连续属性的可能取值不再有限,因此不能直接根据连续属性的可能取值进行划分。我们可以使用离散化技术对其进行处理。
    5.2.1 二分法
    给定样本集D,和连续属性a,a在D上出现了n个不同的取值, 将其排序{a1,a2,...,an},然后基于划分点t将样本划分为Dt和D+t,Dt包括在属性a上取值小于t的样本,D+t反之。通常将划分点设为该属性在训练集中出现不大于中位点的最大值从而使得最终决策树使用的划分点都在训练集中出现过。
 
 
 
 
 
借鉴博文:

 

posted @ 2018-01-24 21:22  骄傲的糖糕  阅读(360)  评论(0编辑  收藏  举报