设为首页 收藏本站
查看: 783|回复: 0

[经验分享] 决策树的python实现

[复制链接]

尚未签到

发表于 2015-4-23 06:35:25 | 显示全部楼层 |阅读模式
决策树

算法优缺点:



  • 优点:计算复杂度不高,输出结果易于理解,对中间值缺失不敏感,可以处理不相关的特征数据

  • 缺点:可能会产生过度匹配的问题

  • 适用数据类型:数值型和标称型

算法思想:

1.决策树构造的整体思想:

  决策树说白了就好像是if-else结构一样,它的结果就是你要生成这个一个可以从根开始不断判断选择到叶子节点的树,但是呢这里的if-else必然不会是让我们认为去设置的,我们要做的是提供一种方法,计算机可以根据这种方法得到我们所需要的决策树。这个方法的重点就在于如何从这么多的特征中选择出有价值的,并且按照最好的顺序由根到叶选择。完成了这个我们也就可以递归构造一个决策树了


2.信息增益

  划分数据集的最大原则是将无序的数据变得更加有序。既然这又牵涉到信息的有序无序问题,自然要想到想弄的信息熵了。这里我们计算用的也是信息熵(另一种方法是基尼不纯度)。公式如下:


数据需要满足的要求:

  1 数据必须是由列表元素组成的列表,而且所有的列白哦元素都要具有相同的数据长度
2 数据的最后一列或者每个实例的最后一个元素应是当前实例的类别标签


函数:

  calcShannonEnt(dataSet)
计算数据集的香农熵,分两步,第一步计算频率,第二部根据公式计算香农熵
splitDataSet(dataSet, aixs, value)
划分数据集,将满足X[aixs]==value的值都划分到一起,返回一个划分好的集合(不包括用来划分的aixs属性,因为不需要)
chooseBestFeature(dataSet)
选择最好的属性进行划分,思路很简单就是对每个属性都划分下,看哪个好。这里使用到了一个set来选取列表中唯一的元素,这是一中很快的方法
majorityCnt(classList)
因为我们递归构建决策树是根据属性的消耗进行计算的,所以可能会存在最后属性用完了,但是分类还是没有算完,这时候就会采用多数表决的方式计算节点分类
createTree(dataSet, labels)
基于递归构建决策树。这里的label更多是对于分类特征的名字,为了更好看和后面的理解。







  • 1 #coding=utf-8
    2 import operator
    3 from math import log
    4 import time
    5
    6 def createDataSet():
    7     dataSet=[[1,1,'yes'],
    8             [1,1,'yes'],
    9             [1,0,'no'],
    10             [0,1,'no'],
    11             [0,1,'no']]
    12     labels = ['no surfaceing','flippers']
    13     return dataSet, labels
    14
    15 #计算香农熵
    16 def calcShannonEnt(dataSet):
    17     numEntries = len(dataSet)
    18     labelCounts = {}
    19     for feaVec in dataSet:
    20         currentLabel = feaVec[-1]
    21         if currentLabel not in labelCounts:
    22             labelCounts[currentLabel] = 0
    23         labelCounts[currentLabel] += 1
    24     shannonEnt = 0.0
    25     for key in labelCounts:
    26         prob = float(labelCounts[key])/numEntries
    27         shannonEnt -= prob * log(prob, 2)
    28     return shannonEnt
    29
    30 def splitDataSet(dataSet, axis, value):
    31     retDataSet = []
    32     for featVec in dataSet:
    33         if featVec[axis] == value:
    34             reducedFeatVec = featVec[:axis]
    35             reducedFeatVec.extend(featVec[axis+1:])
    36             retDataSet.append(reducedFeatVec)
    37     return retDataSet
    38     
    39 def chooseBestFeatureToSplit(dataSet):
    40     numFeatures = len(dataSet[0]) - 1#因为数据集的最后一项是标签
    41     baseEntropy = calcShannonEnt(dataSet)
    42     bestInfoGain = 0.0
    43     bestFeature = -1
    44     for i in range(numFeatures):
    45         featList = [example for example in dataSet]
    46         uniqueVals = set(featList)
    47         newEntropy = 0.0
    48         for value in uniqueVals:
    49             subDataSet = splitDataSet(dataSet, i, value)
    50             prob = len(subDataSet) / float(len(dataSet))
    51             newEntropy += prob * calcShannonEnt(subDataSet)
    52         infoGain = baseEntropy -newEntropy
    53         if infoGain > bestInfoGain:
    54             bestInfoGain = infoGain
    55             bestFeature = i
    56     return bestFeature
    57            
    58 #因为我们递归构建决策树是根据属性的消耗进行计算的,所以可能会存在最后属性用完了,但是分类
    59 #还是没有算完,这时候就会采用多数表决的方式计算节点分类
    60 def majorityCnt(classList):
    61     classCount = {}
    62     for vote in classList:
    63         if vote not in classCount.keys():
    64             classCount[vote] = 0
    65         classCount[vote] += 1
    66     return max(classCount)         
    67     
    68 def createTree(dataSet, labels):
    69     classList = [example[-1] for example in dataSet]
    70     if classList.count(classList[0]) ==len(classList):#类别相同则停止划分
    71         return classList[0]
    72     if len(dataSet[0]) == 1:#所有特征已经用完
    73         return majorityCnt(classList)
    74     bestFeat = chooseBestFeatureToSplit(dataSet)
    75     bestFeatLabel = labels[bestFeat]
    76     myTree = {bestFeatLabel:{}}
    77     del(labels[bestFeat])
    78     featValues = [example[bestFeat] for example in dataSet]
    79     uniqueVals = set(featValues)
    80     for value in uniqueVals:
    81         subLabels = labels[:]#为了不改变原始列表的内容复制了一下
    82         myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet,
    83                                         bestFeat, value),subLabels)
    84     return myTree
    85     
    86 def main():
    87     data,label = createDataSet()
    88     t1 = time.clock()
    89     myTree = createTree(data,label)
    90     t2 = time.clock()
    91     print myTree
    92     print 'execute for ',t2-t1
    93 if __name__=='__main__':
    94     main()
      

    机器学习笔记索引


来自为知笔记(Wiz)  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-59727-1-1.html 上篇帖子: python设置windows桌面壁纸 下篇帖子: python——连接Oracle数据库
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表