决策树

决策树

  • 优点: 计算复杂度不高, 输出结果易于理解, 对中间值的缺失不敏感,可以处理不相关特征数据。
  • 缺点: 可能会造成过度匹配问题。
  • 适用数据类型: 数值型和标称型

  在构造决策树时, 需要解决的第一个问题就是, 当前数据集上哪个特征在划分数据分类时起决定性作用。为了找到决定性的特征,划分出最好的结果,必须评估每个特征。

完成测试之后, 原始数据集就被划分为几个数据子集。这些数据子集会分布再第一个决策点的所有分支上。如果摸个分支下的数据属于同一类型,则当前已经正确地划分数据分类,无需进一步对数据集进行分割。如果数据子集内的数据不属于同一类型,则需要重复划分数据子集的过程。划分数据子集的算法和划分原始数据集的算法相同。持续整个过程知道所有具有相同类型的数据均在一个数据子集内。

创建分支的伪代码如下

1 检测数据集中的每个子项是否属于同一分类
2

if 属于同一匪类: return 类标签

3

else:

4   寻找划分数据集的最好要特征
5   划分数据集
6   创建分支节点
7

  for 每个划分的子集:

    递归调用函数,并增加返回结果到分支节点中

8 return 分支节点

决策树的一般流程

1 收集数据 可以使用任何方法
2 准备数据 树构造算法只适用于标称型数据,因此数值型数据必须离散化
3 分析数据 可以使用任何方法,构造树完成之后,我们应该检查图形是否符合预期
4 训练算法 构造树的数据结构
5 测试算法 使用经验树计算错误率
6 使用算法 此步骤可以适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义

  一些决策树算法采用二分法划分数据。

信息增益

  划分数据集的大原则是,将无序的数据变得更加有序。我们可以使用多种方法划分数据集,但是每种方法都有各自的优缺点。组织杂乱无章的数据的一种方法就是使用信息论度量信息,信息论是量化处理信息的分支科学。我们可以在划分数据前后使用信息论量化度量信息的内容。

  在划分数据集之前之后信息发生的变化称为信息增益, 知道如何计算信息增益, 我们就可以计算每个特征值划分数据集获得的信息增益,获得信息增益最高的特征就是最好的选择。

  集合信息的度量方式称为熵(entropy)。熵定义为信息的期望值。 

  信息的定义为: 如果待分类的事务可能华丰在多个分类中,则符号xi 的信息定义为: l(xi) = - log2p(xi), 其中p(xi)是选择该分类的概率。

  为了计算熵,我们需要计算所有类别所有可能值包含的信息期望值: H = -Σni=1p(xi)log2p(xi),其中n使分类数目。

  计算信息熵的python代码如下:  

from math import log

def calcShannonEnt(dataSet):
    numEntries = len(dataSet)
    labelCounts = {}
    for featVec in dataSet:
        currentLabel = feateVec[-1]
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
            labelCounts[currentLabel] += 1
        shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numEntries
        shannonEnt -= prob * log(prob, 2)
    return shannonEnt

  熵越高,混合的数据也越多,我们可以在数据集中添加更多的分类,观察熵使如何变化的。

  另一个度量集合无序的方法使基尼不纯度(Gini impurity),简单地说就是从一个数据集中随机选取子项,度量其被错误分类到其他分组里的概率。

划分数据集

  按照给定特征划分数据集:

 def splitDataSet(dataSet, axis, value):
    retDataSet = []
    for featVec in dataSet:
         if featVec[axis] == value:
             reducedFeatVec = featVec[: axis]
             reducedFeatVec.extend(featVec[axis+1:])
             retDataSet.append(reducedFeatVec)
    return retDataSet

  接下来我们将遍历整个数据集, 循环计算熵和splitDataSet()函数,找到最好的特征划分方式。熵计算会告诉我们如何划分数据集使最好的数据组织方式:

def chooseBestFeatureToSplit(dateSet):
    numFeatures = len(dataSet[0]) - 1
    baseEntropy = calcShannonEnt(dataSet)
    bestInfoGain = 0.0
    bestFeature = -1
    for i in range(numFeatures):
        featList = [example[i] for example in dataSet]
        uniqueVals = set(featList)
        newEntropy = 0.0
        for value in uniqueVals: 
            subDataSet = splitDataSet(dataSet, i, value)
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob * calcShannonEnt(subDataSet)
        infoGain = baseEntropy - newEntropy
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

递归简历决策树

  从数据集构造决策树算法所需要的子功能模块,其工作原理如下: 得到原始数据集,然后基于最好的属性值划分数据集,由于特征值可能多余两个,因此可能存在大鱼两个分支的数据集划分。第一次划分之后,数据将被向下传递到书分支的下一个节点,在这个节点上,我们可以再次划分数据。因此我们可以采用递归原则处理数据集。递归结束的条件是,程序遍历完所有划分数据集的属性,或者每个分之下的所有实例都具有相同的分类。如果所有实例具有相同的分类,则得到一个叶子节点或者终止块。任何到达叶子节点的数据必然属于叶子节点的分类。

  第一个结束条件是的算法可以终止,我们甚至可以设置算法可以划分的最大分组数目。分类的python代码如下:

def majorityCnt(classList):
    classCount ={}
    for vote in classList:
        if vote not in classCount.keys():  classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(classCount.iteritems(), key = operator.itemgetter(1), reverse=True)
    return  sortedClassCount[0][0]

创建树的代码如下:

def createTree(dataSet, labels):
    classList = [example[-1] for example in dataSet]
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    if len(dataSet[0]) == 1:
        return majorityCnt(classList)
    bestFeatLabel = labels[bestFeat]
    myTree = {bestFeatLabel:{}}
    del(labels[bestFeat])
    featValues = [example[bestFeat] for example in dataSet]
    uniqueVals = set(featValues)
    for value in uniqueVals:
        subLabels = labels[:]
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels)
    return myTree

 

  

posted on 2016-04-13 22:02  DrawToy  阅读(257)  评论(0)    收藏  举报

导航