文档章节

决策树的Python代码实现与分析

大海201506
 大海201506
发布于 2017/06/14 17:13
字数 1326
阅读 165
收藏 0

 1、 计算给定数据集的香农熵


def calcShannonEnt(dataSet):
    #calculate the shangnon value
    numEntries = len(dataSet)    #求dataset的元素个数,dataSet的类型是列表
    labelCounts = {}             # 创建空列表,存储每一类数量 
    for featVec in dataSet:      #对dataSet的每一类训练数据
        currentLabel = featVec[-1]   # 将dataSet的每一个元素的最后一个元素选择出来,dataSet的元素也是列表
        if currentLabel not in labelCounts.keys(): #返回一个字典所有的键。
            labelCounts[currentLabel] = 0 #若字典中不存在该类别标签,则使用字典的自动添加进行添加值为0的项
        labelCounts[currentLabel] += 1 #递增类别标签的值,labelCounts[currentLabel]主要是统计同一个label出现的次数
    shannonEnt = 0.0
    for key in labelCounts:    # 对每一分类,计算熵  
        prob = float(labelCounts[key])/numEntries  #计算某个标签的概率 P(x)  
        shannonEnt -= prob*math.log(prob,2)   #计算信息熵 P(x) * log(P(x))
    return shannonEnt

2. 创建数据的函数

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

3.划分数据集,按照给定的特征划分数据集

将满足X[aixs]==value的值(特征aixs对应的值)都划分到一起,返回一个划分好的集合(不包括用来划分的aixs属性,因为不需要)

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

说明: featVec[:axis] 返回的是一个列表,其元素是featVec这个列表的索引从0到axis - 1的 元素; featVec[axis + 1: ]返回的是一个列表,其元素是featVec这个列表的索引从axis + 1开始1. 的所有元素

4. 根据信息增益最大,选择最好的数据集划分特征

信息增益 = 信息熵InfoA(D) - 在特征A作用后的信息熵为InfoA(D)

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] #提取所有训练样本中第i个特征 --> list
        print("featList",featList)
        uniqueVals = set(featList) # 使用set去重,获得特征值的所有取值
        newEntropy = 0.0 #在特征作用下的信息熵
        for value in uniqueVals: #计算该特征值下的熵
            subDataSet = splitDataSet(dataSet,i,value) #按照特征i的值为value分割数据
            prob = len(subDataSet)/float(len(dataSet)) #特征i下,分别取不同特征值的概率p()
            newEntropy += prob * calcShannonEnt(subDataSet) #计算特征i的熵
        infoGain = baseEntropy - newEntropy # 特征值i的信息增益
        if(infoGain > bestInfoGain): # 取最大信息增益时的特征i  
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

5.递归创建树

因为我们递归构建决策树是根据属性的消耗进行计算的,所以可能会存在最后属性用完了,但是分类 还是没有算完,这时候就会采用多数表决的方式计算节点分类

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]  # 排序后返回出现次数最多的分类名称

6. 用于创建树的函数代码

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) #递归函数使得Tree不断创建分支,直到分类结束
    return myTree

7、根据训练决策树,判断测试向量testVec

def classify(inputTree, featLabels, testVec):  #tree为createTree()函数返回的决策树;label为特征的标签值;testVec为测试数据,即所有特征的具体值构成的向量  
    firstStr = list(inputTree.keys())[0]  #取出tree的第一个键
    secondDict = inputTree[firstStr]  #取出tree第一个键的值,即tree的第二个字典(包含关系)
    print("secondDict",secondDict) 
    featIndex = featLabels.index(firstStr)  #得到第一个特征firstFeat在标签label中的索引(树根节点 ---> 特征位置 ---> 测试向量位置)
    for key in secondDict.keys():  #遍历第二个字典的键
        if testVec[featIndex] == key:  #如果第一个特征的测试值与第二个字典的键相等时
            if type(secondDict[key]).__name__ == 'dict':  #如果第二个字典的值还是一个字典,说明分类还没结束,递归执行classify函数
                classLabel = classify(secondDict[key], featLabels, testVec)  #递归函数中只有输入的第一个参数不同,不断向字典内层渗入
            else: classLabel = secondDict[key]  #最后将得到的分类值赋给classLabel输出
    return classLabel
myDat, labels = createDataSet()  
myTree = createTree(myDat,labels)  
print("labels",labels);

print("result",classify(myTree,['no surfacing','flippers'],[0,1])) 

© 著作权归作者所有

下一篇: Log日志的写法
大海201506
粉丝 5
博文 96
码字总数 173986
作品 0
广州
程序员
私信 提问
统计学习方法第五章:决策树(decision tree),ID3算法,C4.5算法及python实现

统计学习方法第二章:感知机(perceptron)算法及python实现 统计学习方法第三章:k近邻法(k-NN),kd树及python实现 统计学习方法第四章:朴素贝叶斯法(naive Bayes),贝叶斯估计及python实现 ...

无限大的饿
02/17
0
0
[SQL Server玩转Python] 三.SQL Server存储过程实现Python鸢尾花决策树训练及预测

版权声明:本文为博主原创文章,转载请注明CSDN博客源地址!共同学习,一起进步~ https://blog.csdn.net/Eastmount/article/details/84066650 在开发项目过程中,更多的是通过Python访问SQL...

Eastmount
2018/11/14
0
0
统计学习方法第五章:决策树(decision tree),CART算法,剪枝及python实现

统计学习方法第二章:感知机(perceptron)算法及python实现 统计学习方法第三章:k近邻法(k-NN),kd树及python实现 统计学习方法第四章:朴素贝叶斯法(naive Bayes),贝叶斯估计及python实现 ...

无限大的饿
02/17
0
0
机器学习必备宝典-《统计学习方法》的python代码实现、电子书及课件

欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定! 对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴...

天善智能
2018/11/27
0
0
【python数据挖掘课程】二十三.时间序列金融数据预测及Pandas库详解

这是《Python数据挖掘课程》系列文章,也是我上课内容及书籍中的一个案例。本文主要讲述时间序列算法原理,Pandas扩展包基本用法以及Python调用statsmodels库的时间序列算法。由于作者数学比...

eastmount
2018/05/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
今天
6
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
6
0
Docker容器实战(七) - 容器中进程视野下的文件系统

前两文中,讲了Linux容器最基础的两种技术 Namespace 作用是“隔离”,它让应用进程只能看到该Namespace内的“世界” Cgroups 作用是“限制”,它给这个“世界”围上了一圈看不见的墙 这么一...

JavaEdge
今天
8
0
文件访问和共享的方法介绍

在上一篇文章中,你了解到文件有三个不同的权限集。拥有该文件的用户有一个集合,拥有该文件的组的成员有一个集合,然后最终一个集合适用于其他所有人。在长列表(ls -l)中这些权限使用符号...

老孟的Linux私房菜
今天
7
0
面试套路题目

作者:抱紧超越小姐姐 链接:https://www.nowcoder.com/discuss/309292?type=3 来源:牛客网 面试时候的潜台词 抱紧超越小姐姐 编辑于 2019-10-15 16:14:56APP内打开赞 3 | 收藏 4 | 回复24 ...

MtrS
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部