决策树的Python代码实现与分析
2017-06-14 00:00
543 查看
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]))
相关文章推荐
- 用70行代码实现日志分析程序-python
- 决策树的Python代码分析(二)
- 决策树ID3算法python实现代码及详细注释
- Python数据可视化正态分布简单分析及实现代码
- [置顶] 【二分-kMeans算法】二分K均值聚类分析与Python代码实现
- 决策树分类算法原理分析与代码实现
- 随机森林的原理分析及Python代码实现
- 决策树分类算法及python代码实现案例
- Holt-Winters模型原理分析及代码实现(python)
- 决策树笔算和python代码实现
- 分析并输出Python代码依赖的库的实现代码
- 机器学习之决策树(Decision Tree)及其Python代码实现
- 利用Spark-mllab进行聚类,分类,回归分析的代码实现(python)
- 决策树的python代码实现
- 《200行Python代码实现2048》分析
- 决策树(Decision Tree)--python实例代码分析(3)
- [深度学习]Python/Theano实现逻辑回归网络的代码分析
- 决策树原理及Python代码实现
- logistic回归算法详细分析与Python代码实现注释
- ID3决策树的Python代码实现