决策树的创建与使用决策树进行分类

目录

决策树

什么是决策树

决策树优缺点

创建分支的伪代码CreateBranch()

决策树一般流程   

信息增益

信息定义

熵的计算

划分数据集

按照给定特征划分数据集

选择最好的数据集划分方式

 递归构建决策树

创建决策树

实例

数据集

创建决策树

使用决策树分类


决策树

什么是决策树

分类决策树模型是一种描述对实例进行分类的树形结构。
决策树由 结点 有向边 组成。结点有两种类型: 内部结点 叶节点 。内部结点表示一个特征或属性,叶节点表示一个类。
决策树学习的目的是为了产生一棵 泛化能力强 处理未见示例能力强的决策树

决策树优缺点

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

创建分支的伪代码CreateBranch()

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

        if so return 类标签

        else

                寻找划分数据集的最好特征

                划分数据集

                创建分支节点

                        for 每个划分的子集

                                调用函数CreateBranch()并增加返回结果到分支节点中

                return 分支节点 

决策树一般流程   

1.收集数据

2.准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化。

3.分析数据:构造树完成后,我们应该检查图形是否符和预期

4.训练算法:构造树的数据结构

5.测试算法:使用经验树计算错误率

6.使用算法

信息增益

在划分数据集之前之后信息发生的变化称为信息增益。

在可以评测哪种数据划分方式是最好的数据划分之前,我们必须学习如何计算信息增益。

集合信息的度量方式称为香农熵或者简称为

信息定义

符号{x_{i}}的信息定义为l\left ( {x_{i}} \right )=- log_{2}p\left ( {x_{i}} \right ),其中p(Xi)是选择该分类的概率。

熵的计算

计算所有类别所有可能值包含的信息期望值,n是分类的数目。

H=-\sum _{i=1}^{n} p\left ( {x_{i}} \right ) log_{2} \cdot p\left ( {x_{i}} \right )

#计算给定数据集的香农熵
def calcShannonEnt(dataSet):
    numEntires = len(dataSet)
    labelCounts = {}
    #为所有可能分类创建字典
    for featVec in dataSet:
        currentLabel = featVec[-1]
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key]) / numEntires
        #以2为底求对数
        shannonEnt -= prob * log(prob, 2) 
    return shannonEnt

划分数据集

我们除了需要测量信息熵,还需要划分数据集,度量划分数据集的熵,以便判断当前是否正确地划分了数据集。

按照给定特征划分数据集

#按照给定特征划分数据集
def splitDataSet(dataSet, axis, value):
    retDataSet = []         #创建新的list对象
    for featVec in dataSet:
        if featVec[axis] == value:
            #抽取符合特征的数据
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis + 1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet

选择最好的数据集划分方式

#选择最好的数据集划分方式
def chooseBestFeatureToSplit(dataSet):
    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
        print("第%d个特征的增益为%.3f" % (i, infoGain))
        #计算最好的信息增益
        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
    #利用operator操作键值排序字典
    sortedClassCount = sorted(classCount.items(), 
        key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]  # 返回classList中出现次数最多的元素

创建决策树

#创建决策树
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)
    #获取最好特征
    bestFeat = chooseBestFeatureToSplit(dataSet)
    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

实例

根据学生获奖情况(0表示没有,1表示省级,2表示国家级),刷笔试题和面试题情况,和实习经历,来判断是否能找到工作(N表示不能,Y表示能)。

数据集

获奖情况 刷题情况 实习经历 工作

1

0 1 Y
1 0 0 N
2 1 1 Y
2 0 0 Y
0 1 1 Y
1 1 0 N
2 0 1 Y
0 0 1 N
2 1 0 Y
2 1 1 Y
def createDataSet():
    dataSet = [[1, 0, 1,'Y'],
            [0, 0, 0, 'N'],
            [2, 1, 1, 'Y'],
            [2, 0, 0, 'Y'],
            [0, 1, 1, 'Y'],
            [1, 1, 0, 'N'],
            [2, 0, 1, 'Y'],
            [0, 0, 1, 'N'],
            [2, 1, 0, 'Y'],
            [2, 1, 1, 'Y'],]
    labels=['获奖情况','刷题情况','实习经历']
    featlabels=['获奖情况','刷题情况','实习经历']
    return dataSet,labels,featlabels

创建决策树

if __name__ == '__main__':
    dataSet, labels,featlabels = createDataSet()
    myTree = createTree(dataSet, labels)
    print(myTree)

决策树的创建与使用决策树进行分类_第1张图片

使用决策树分类

  #使用决策树分类
def classify(inputTree, featLabels, testVec):
    firstStr = next(iter(inputTree))  
    secondDict = inputTree[firstStr]
    featIndex = featLabels.index(firstStr)  
    for key in secondDict.keys():  
        if testVec[featIndex] == key:
            if type(secondDict[key]).__name__ == 'dict':
                classLabel = classify(secondDict[key], featLabels, testVec)
            else:
                classLabel = secondDict[key] 
    return classLabel

决策树的创建与使用决策树进行分类_第2张图片

 

你可能感兴趣的:(决策树,分类)