决策树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了决策树相关的知识,希望对你有一定的参考价值。

构建决策树需要解决的第一个问题就是:当前数据集上哪个特征在划分数据分类时起决定性作用。

下面的例子使用的是ID3算法解决上面的问题,对数据进行分类。

计算给定数据集的香农熵

def calculateEntropy(dataSet):
    numberEntries = len(dataSet)
    labelCounts = {}
    for featVector in dataSet:
        currentLabel = featVector[-1]  # 取每行数据的类别 --> 最后一列
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numberEntries  # 计算每个类别出现的概率
        shannonEnt -= prob * log(prob,2)              # 计算香农熵
    return shannonEnt

 下面是例子中用到的数据集,相对简单,但已经满足要求。

def createDataSet():
    dataSet = [
        [1, 1, ‘yes‘],
        [1, 1, ‘yes‘],
        [1, 0, ‘no‘],
        [0, 1, ‘no‘],
        [0, 1, ‘no‘]
    ]
    labels = [‘no surfacing‘, ‘flippers‘]
    return  dataSet, labels

 按照给定特征划分数据集

def splitDataSet(dataSet,axis,value): # dataSet给定数据集 axis给定特征(索引)  axis给定特征的值
    returnDataSet = []
    for featureVec in dataSet:
        if featureVec[axis] == value:
            reducedFeatVec = featureVec[:axis]
            reducedFeatVec.extend(featureVec[axis + 1:])
            returnDataSet.append(reducedFeatVec)
    return returnDataSet

 遍历整个数据集,循环计算香农熵,找到最好的特征划分方式

def chooseBestFeatureToSplit(dataSet):
    numberFeatures = len(dataSet[0]) - 1
    baseEntropy = calculateEntropy(dataSet)
    bestInfoGain = 0.0
    bestFeature = -1
    for i in range(numberFeatures):  # 按照第i个特征进行划分的情况
        # 使用列表推导式创建新的列表  保存第i个特征所有的特征值
        featureList = [example[i] for example in dataSet]
        uniqueVals = set(featureList) # 去除重复值
        newEntropy = 0.0
        for value in uniqueVals:  #第i个特征所有的特征值
            subDataSet = splitDataSet(dataSet, i, value)
            prob = len(subDataSet)/len(dataSet)
            newEntropy += prob * calculateEntropy(subDataSet)
        infoGain = baseEntropy - newEntropy
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

 如果数据集已经处理了所有的特征,但类标签并不是唯一的情况下,进行多数表决的方法决定该节点的分类,定义函数和代码如下:

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

 下面是创建树的代码(递归):

# 创建决策树
def createTree(dataSet,labels):  # 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)  # 遍历完所有特征时返回出现次数最多的类别
    bestFeat = chooseBestFeatureToSplit(dataSet)
    bestFeatLabel = labels[bestFeat]
    myTree = {bestFeatLabel:{}}
    del(labels[bestFeat])   # 将已经用过的特征从labels中删除
    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

 

以上是关于决策树的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中绘制回归树

sklearn决策树算法DecisionTreeClassifier(API)的使用以及决策树代码实例 - 莺尾花分类

机器学习:通俗易懂决策树与随机森林及代码实践

决策树的几种类型差异及Spark 2.0-MLlibScikit代码分析

机器学习_决策树Python代码详解

Chapter3 绘制决策树