shiyi10871993 发表于 2019-4-23 17:41:49

关于决策树的小问题

最近在了解决策树,然后在ID3算法时,以下是关于决策树ID3算法时的完整代码。其中在createTree(代码中标了****)这个地方不是很理解。
按照代码来说classList=['男','男','女','女''女''女''女']
这里if的两个条件都不满足,所以并不会有返回值,直接执行bestFeat=chooseBestFeatureToSplit(dataSet),那么这一段代码是不是可以不用啊,但是我看解释是这样,有点懵,实在不太懂函数定义到 return majorityCnt(classList)这一段的意思,望大神指点
有问题的代码和相关解释
def createTree(dataSet,labels):
    classList= for example in dataSet]#返回所有的标签
    if classList.count(classList)==len(classList):#当类别完全相同时则停止继续划分,直接返回该类的标签
      return classList#stop splitting when all of the classes are equal
    if len(dataSet)==1:#遍历完所有的特征时,仍然不能将数据集划分成仅包含唯一类别的分组
      return majorityCnt(classList)#由于无法简单的返回唯一的类标签,这里就返回出现次数最多的类别作为返回值
    bestFeat=chooseBestFeatureToSplit(dataSet) #选择最优特征
    bestFeatLabel=labels#获取该特征的名称
    myTree={bestFeatLabel:{}} #分类结果以字典形式保存
    del(labels)
    featValues= for example in dataSet]
    uniqueVals=set(featValues)
    for value in uniqueVals:
      subLabels=labels[:]
      myTree=createTree(splitDataSet\
                            (dataSet,bestFeat,value),subLabels)
    return myTree

完整代码如下:
from math import log
import operator

def calcShannonEnt(dataSet):# 计算数据的熵(entropy)
    numEntries=len(dataSet)# 数据条数
    labelCounts={}
    for featVec in dataSet:
      currentLabel=featVec[-1] # 每行数据的最后一个字(类别)
      if currentLabel not in labelCounts.keys():
            labelCounts=0
      labelCounts+=1# 统计有多少个类以及每个类的数量
    shannonEnt=0
    for key in labelCounts:
      prob=float(labelCounts)/numEntries # 计算单个类的熵值
      shannonEnt-=prob*log(prob,2) # 累加每个类的熵值
    return shannonEnt

def createDataSet1():    # 创造示例数据
    dataSet = [['长', '粗', '男'],
               ['短', '粗', '男'],
               ['短', '粗', '男'],
               ['长', '细', '女'],
               ['短', '细', '女'],
               ['短', '粗', '女'],
               ['长', '粗', '女'],
               ['长', '粗', '女']]
    labels = ['头发','声音']#两个特征
    return dataSet,labels

def splitDataSet(dataSet,axis,value): # 按某个特征分类后的数据
    retDataSet=[]
    for featVec in dataSet:
      if featVec==value:
            reducedFeatVec =featVec[:axis]
            reducedFeatVec.extend(featVec)
            retDataSet.append(reducedFeatVec)
    return retDataSet

def chooseBestFeatureToSplit(dataSet):# 选择最优的分类特征
    numFeatures = len(dataSet)-1
    baseEntropy = calcShannonEnt(dataSet)# 原始的熵
    bestInfoGain = 0
    bestFeature = -1
    for i in range(numFeatures):
      featList = for example in dataSet]
      uniqueVals = set(featList)
      newEntropy = 0
      for value in uniqueVals:
            subDataSet = splitDataSet(dataSet,i,value)
            prob =len(subDataSet)/float(len(dataSet))
            newEntropy +=prob*calcShannonEnt(subDataSet)# 按特征分类后的熵
      infoGain = baseEntropy - newEntropy# 原始熵与按特征分类后的熵的差值
      if (infoGain>bestInfoGain):   # 若按某特征划分后,熵值减少的最大,则次特征为最优分类特征
            bestInfoGain=infoGain
            bestFeature = i
    return bestFeature

def majorityCnt(classList):    #按分类后类别数量排序,比如:最后分类为2男1女,则判定为男;
    classCount={}
    for vote in classList:
      if vote not in classCount.keys():
            classCount=0
      classCount+=1
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount

****def createTree(dataSet,labels):
    classList= for example in dataSet]# 类别:男或女
    if classList.count(classList)==len(classList):
      return classList
    if len(dataSet)==1:
      return majorityCnt(classList)
    bestFeat=chooseBestFeatureToSplit(dataSet) #选择最优特征
    bestFeatLabel=labels
    myTree={bestFeatLabel:{}} #分类结果以字典形式保存
    del(labels)
    featValues= for example in dataSet]
    uniqueVals=set(featValues)
    for value in uniqueVals:
      subLabels=labels[:]
      myTree=createTree(splitDataSet\
                            (dataSet,bestFeat,value),subLabels)
    return myTree


if __name__=='__main__':
    dataSet, labels=createDataSet1()# 创造示列数据
    print(createTree(dataSet, labels))# 输出决策树模型结果

pyxjy 发表于 2019-4-23 23:39:42

如果只想使用决策树算法的话,可以安装sklearn库调用里面的决策树算法,几行代码就可以实现。如果想自己实现的话,当我没说…因为我刚学的时候就走弯路了

shiyi10871993 发表于 2019-4-24 09:07:26

大神能不能提供关于sklearn的完整代码呢
页: [1]
查看完整版本: 关于决策树的小问题