决策树 - 算法基本实现
来源:互联网 发布:长安app软件下载 编辑:程序博客网 时间:2024/06/06 03:09
# -*- coding: utf-8 -*-from math import logimport operatordef createDataSet(): dataSet = [[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']] labels = ['no surfacing','flippers'] return dataSet, labels# 计算熵def calcShannonEnt(dataSet): # 数据的数目 numEntries = len(dataSet) # 创建字典 labelCounts = {} for featVec in dataSet: # 取数据集中每组测试数据的最后一个特征值 currentLabel = featVec[-1] # 如果labelCounts中没有这个特征, 那么添加这个特征, 初始值为0 if currentLabel not in labelCounts.keys(): labelCounts[currentLabel] = 0 # 对应的特征计数器加一 labelCounts[currentLabel] += 1 shannonEnt = 0.0 # 循环属性值, 计算熵 for key in labelCounts: # 每个属性的概率值 prob = float(labelCounts[key])/numEntries shannonEnt -= prob * log(prob,2) return shannonEntd, l = createDataSet()# print calcShannonEnt(d)# 划分数据集# dataSet:数据集# axis:划分数据集的特征# value: 该特征的值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# 选择最好的数据集划分方式def chooseBestFeatureToSplit(dataSet): # 每组元素去掉结果值之后的特征数目 numFeatures = len(dataSet[0]) - 1 # 原始的熵值 baseEntropy = calcShannonEnt(dataSet) # 初始化信息增益 bestInfoGain = 0.0 # 最好的划分特征 bestFeature = -1 for i in range(numFeatures): # 当前的特征集合 # example是dataSet的每一组数据, example[i]是每一组数据的第i个元素 # [example[i] for example in dataSet]就是 每一组数据的第i个元素的集合 featList = [example[i] for example in dataSet] # set去重 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) # 计算信息增益 infoGain = baseEntropy - newEntropy # 找出信息增益最大的值,并记录这个特征的索引值 if (infoGain > bestInfoGain): bestInfoGain = infoGain bestFeature = i return bestFeature# print chooseBestFeatureToSplit(d) # 返回出现次数最多的分类名称def majorityCnt(classList): classCount={} for vote in classList: if vote not in classCount.keys(): classCount[vote] = 0 classCount[vote] += 1 sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0]# 创建树def createTree(dataSet,labels): # dataSet里面每一组数据的最后一个元素的集合 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) return myTree print createTree(d,l)# 调用决策树做预测# inputTree:决策树# featLabels:测试数据标签# testVec: 测试数据值def classify(inputTree,featLabels,testVec): firstStr = inputTree.keys()[0] secondDict = inputTree[firstStr] featIndex = featLabels.index(firstStr) key = testVec[featIndex] valueOfFeat = secondDict[key] if isinstance(valueOfFeat, dict): classLabel = classify(valueOfFeat, featLabels, testVec) else: classLabel = valueOfFeat return classLabeldataSet, featLabels = createDataSet()inputTree = createTree(dataSet, featLabels)dataSet, featLabels = createDataSet()testVec = [0,1]print classify(inputTree,featLabels,testVec)# 因为构建决策树耗时严重, 因此构建成功将决策树保存,然后测试时从文件中直接读取使用# 将构建的决策树写入文件def storeTree(inputTree,filename): import pickle fw = open(filename,'w') pickle.dump(inputTree,fw) fw.close()# 从文件中读取决策树def grabTree(filename): import pickle fr = open(filename) return pickle.load(fr)
0 0
- 决策树 - 算法基本实现
- 基于python的sklearn库的决策树算法基本实现
- ID3 算法实现决策树
- 决策树算法的实现
- Python实现决策树算法
- 决策树算法实现
- 决策树算法实现(一)
- 决策树算法实现(二)
- 决策树算法--python实现
- 决策树算法及实现
- 决策树算法实现
- python3实现决策树算法
- 决策树算法实现
- 决策树算法 python实现
- 分类算法--决策树基本算法--决策树生成算法
- 决策树算法Java实现示例
- 决策树ID3算法C++实现
- 决策树算法实现(python)
- 为什么 Laravel 5 这么好一个框架国内开发者都不去用?
- PC端自适应布局
- Oracle数据库表分区
- bzoj4025 二分图
- TCP-IP协议族(二) HTTP报文头解析
- 决策树 - 算法基本实现
- 2017 cocoapods 安装 1.2.0
- 解决android 两次调用DatePickerDialog.onDateSet()的方法
- 简单工厂的设计模式
- Android Studio 使用海马玩模拟器运行项目
- [Leetcode] #46#47 Permutations I & II
- 在linux下执行定时任务运行一个java程序
- 咖啡杯
- Ajax 应用程序中的流程