关于决策树的小问题
最近在了解决策树,然后在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))# 输出决策树模型结果
如果只想使用决策树算法的话,可以安装sklearn库调用里面的决策树算法,几行代码就可以实现。如果想自己实现的话,当我没说…因为我刚学的时候就走弯路了 大神能不能提供关于sklearn的完整代码呢
页:
[1]