机器学习(三):分类算法之决策树算法

来源:互联网 发布:linux操作系统入门书籍 编辑:程序博客网 时间:2024/05/16 17:46

一、特点

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

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

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


二、原理与实现


根据某个特征,划分数据集。如果某个分支下的数据属于同一类型,则无需进一步分割;否则需要重复划分数据子集。而其中最重要的问题就是,选取哪个特征进行数据划分。

选取哪个特征进行划分?


划分数据集的最大原则是,将无序的数据变的更加有序。在划分数据集之后信息所发生的变化称为信息增益,计算每个特征值划分数据集获得的信息增益,获得信息增益最高的特征就是最好的选择。

如何计算信息增益?


集合信息的度量方式称为香农熵或者简称为熵。熵定义为信息的期望值。(没错,就是这么费解,但是多看看就还好)

1. 计算数据集合的熵的方法

一个数据集中,X是这个集合每个数据对应的类别(比如要不要出去玩、是不是鱼等等)。对于变量X,它可能的取值有n多种,分别是x1,x2,……,xn,每一种取到的概率分别是P1,P2,……,Pn,那么集合的熵(对于x而言)就定义为:

一个集合类别可能的变化越多(只和值的种类多少以及发生概率有关,与具体值是多少无关),它携带的信息量就越大

下面给出计算数据集香农熵的python代码:

from math import  log#伪造一些关于是否为鱼类的特征和标签def createDataSet():    dataSet= [                [1,1,'yes'],    #每个字段分别代表  在水下是否可以生存,  是否有脚蹼,   是否属于鱼类                [1,1,'yes'],                [1,0,'no'],                [0,1,'no'],                [0,1,'no']    ]    labels=['noSurfacing' , 'flippers']    return dataSet, labels   #计算香农熵   参数说明:  dataSet是一个数据集合,indexOfLabel是表明每条数据所属类别的下标def calcShannonEnt(dataSet, indexOfLabel):       entriesNum=len(dataSet)   #计算数据总条目数    labelCounts={}            #每个类别有多少个    for featVec in dataSet:        label = featVec[indexOfLabel]        if label not in labelCounts.keys():            labelCounts[label]=0        labelCounts[label] +=1    shannonEnt=0.0    for key in labelCounts:   #套用上方的计算式        prob=float(labelCounts[key])/entriesNum        shannonEnt -= prob* log(prob,2)    return shannonEnt        


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

计算按每个特征来划分之后的熵,与原数据集的熵做差,求出最好的信息增益
#根据给定特征划分数据集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 retDataSetdef chooseBestFeatToSplit(dataSet):    featureNum=len(dataSet[0])-1    baseEntropy = calcShannonEnt(dataSet,-1)  #原始香农熵    bestInfoGain=0.0 ; bestFeature=-1    for i in range(featureNum):        #创建唯一的分类标签列表        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,-1)        infoGain=baseEntropy-newEntropy        #计算最好的信息增益        if infoGain>bestInfoGain:            bestInfoGain=infoGain            bestFeature=i    return bestFeatureif __name__=="__main__":    dataset,labels=createDataSet()    print  chooseBestFeatToSplit(dataset)

跑出来的结果是 0 ,说明以第一个特征进行划分是最好的,也就是第一个特征是0的放在一组,是1的放在一组。 目测了一下,这的确是最好的划分方式。

3.递归创建决策树

#获取出现次数最多的类别def getMostType(typeList):    typeCounts={}            #每个类别有多少个    for type in typeList:        if type not in typeCounts.keys():            typeCounts[type]=0        typeCounts[type] +=1    mostCount=0; mostType='';    for type in typeCounts.keys():        if typeCounts[type] > mostCount:            mostCount=typeCounts[type]            mostType=type    return mostType#递归创建def createTree(dataSet,labels,indexOfType):    typeList=[example[-1] for example in dataSet]    #类别完全相同则停止划分    if typeList.count(typeList[0]) == len(typeList):        return typeList[0]    if len(dataSet[0]) ==1:        return getMostType(typeList)    bestFeat = chooseBestFeatToSplit(dataSet)    bestFeatLabel = labels[bestFeat]    myTree={bestFeatLabel:{}}    del(labels[bestFeat])    featValues=[example[bestFeat] for example in dataSet]    uniqueValues=set(featValues)    for value in uniqueValues:        subLabels = labels[:]        myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels,indexOfType)    return myTreeif __name__=="__main__":    dataset,labels=createDataSet()    print  createTree(dataset,labels,-1)

递归函数第一个停止的条件是所有类别完全相同,直接返回该类别。第二个停止条件是,所有的特征都用完之后,仍然不能将数据集划分为仅包含唯一类别的分组。


上述代码的输出为:

{'noSurfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

之后拿到新的数据,就可以利用这个结果来判断属于何种类别。可以将结果保存起来,达到一次计算,多次使用的效果。

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 天猫商城购买的家具要退换货怎么办 亚马逊美国站会员日前没销量怎么办 淘宝买的鞋子把脚磨坏了怎么办 拼多多下单 没货 没法发货怎么办 闲鱼退货物流弄坏了卖家拒收怎么办 客户说物流太慢了 要退货怎么办 京东退货物流系统不更新怎么办 把货交给物流但是物流丢货了怎么办 货还在物流就申请退款怎么办 荣耀4x返回键不管用怎么办 华为手机关不了机也开不了机怎么办 荣耀畅玩5x手机密码忘了怎么办 华为短信验证码失败其他错误怎么办 红米3x手机卡顿反应慢怎么办 华为手机不停的自动重启怎么办 华为荣耀4x卡在开机界面怎么办 华为荣耀8青春版密码忘了怎么办 华为手机内存满了开不起来怎么办 华为荣耀畅玩平板2比较卡怎么办 红米4x太卡了怎么办 魅蓝e移动卡只有2g网络怎么办 联通关闭2g网络双卡手机怎么办 小米6x手机插耳机音量大怎么办 音量键和亮度键盘拆了怎么办 荣耀v10锁屏密码忘了怎么办 荣耀9锁屏密码忘记了怎么办 华为荣耀v9锁屏密码忘记了怎么办 荣耀手机密码忘了怎么办数字锁 华为畅享5忘了开机密码怎么办 华为p9连接热点忘了密码怎么办 苹果手机用联通卡信号不好怎么办 魅族手机充电口松了怎么办 华为手机刷机失败开不了机怎么办 华为刷机失败开不了机怎么办 银行卡信息被盗密码被改该怎么办 全民k歌手机话筒有杂音怎么办 手机刷机清除数据需要密码怎么办 oppo手机屏锁密码忘了怎么办 华为手机摔了一下开不了机怎么办 华为v9手机删除隐私空间了怎么办 华为荣耀畅玩5x卡顿怎么办