机器学习算法之决策树(python)
来源:互联网 发布:excel提取网页数据 编辑:程序博客网 时间:2024/04/30 05:39
决策树算法通过对历史数据进行测算实现对新数据进行分类和预测。决策树算法就是通过对已有明确结果的历史数据进行分析,寻找数据中的特征,并以此为依据对新产生的数据结果进行预测。决策树的3个主要部分分别为:决策节点,分支和叶子节点。其中决策树最顶部的决策节点是根决策节点,每一个分支都有一个新的决策节点,决策节点下面是叶子节点。每个决策节点表示一个待分类的数据类别或属性,每个叶子节点表示一种结果。整个决策的过程从根决策节点开始,从上到下。根据数据的分类在每个决策节点给出不同的结果。
划分数据集的最大原则是:使无序的数据变的有序。如果一个训练数据中有20个特征,那么选取哪个做划分依据?这就必须采用量化的方法来判断,量化划分方法有多重,其中一项就是“信息论度量信息分类”。基于信息论的决策树算法有ID3、CART和C4.5等算法,其中C4.5和CART两种算法从ID3算法中衍生而来。构造决策树的方法有很多种,ID3是其中的一种算法。ID3算法核心是“信息熵”。ID3算法认为“互信息”高的属性是好属性,通过计算历史数据中每个类别或属性的“信息熵”获得“互信息”,并选择“互信息”最高的类别或属性作为决策树中的决策节点,将类别或属性的值做为分支继续进行分裂。不断重复这个过程,直到生成一棵完整的决策树。
信息熵是衡量信息的不确定性或混乱程度的指标。信息的不确定性越大,熵越大。决定信息的不确定性或者说复杂程度主要因素是概率。决策树中使用的与熵有关的概念有三个:信息熵,条件熵和互信息。例如抛硬币,可能出现的结果有两个,分别是正面和反面。而每次抛硬币的结果是一个非常不确定的信息。因为根据我们的经验或者历史数据来看,一个均匀的硬币出现正面和反面的概率相等,都是50%。因此很难判断下一次出现的是正面还是反面。这时抛硬币这个事件的熵值也很高。而如果历史数据告诉我们这枚硬币在过去的100次试验中99次都是正面,也就是说这枚硬币的质量不均匀,出现正面结果的概率很高。那么我们就很容易判断下一次的结果了。这时的熵值很低,只有0.08。若待分类的事物可能划分在N类中,分别是x1,x2,……,xn,每一种取到的概率分别是P1,P2,……,Pn,那么X的熵就定义为:
python实现参照机器学习实战:
新建trees.py文件
from math import logdef calcShannonEnt(dataSet): #calculate the shannon value numEntries = len(dataSet) labelCounts = {} for featVec in dataSet: currentLabel = featVec[-1] 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 shannonEnt def createDataSet(): #create dataset dataSet=[[1,1,'yes'], [1,1,'yes'], [1,0,'no'], [0,1,'no'], [0,1,'no']] labels=['no surfacing','flippers'] return dataSet,labels
在shell里执行:
>>> reload(trees)<module 'trees' from 'trees.py'>>>> myDat,labels=trees.createDataSet()>>> myDat[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]>>> trees.calcShannonEnt(myDat)0.9709505944546686在trees.py文件中继续写入函数:
def splitDataSet(dataSet,axis,value): #splite dataset retDataSet=[] for featVec in dataSet: if featVec[axis]==value: reducedFeatVec=featVec[:axis] reducedFeatVec.extend(featVec[axis+1:]) retDataSet.append(reducedFeatVec) return retDataSetdef chooseBestFeatureToSplit(dataSet): #choose the best splite method by Shannon Value,choose the biggest 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] 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在shell中执行:
>>> reload(trees)<module 'trees' from 'trees.py'>>>> myDat,labels=trees.createDataSet()>>> trees.splitDataSet(myDat,0,1)[[1, 'yes'], [1, 'yes'], [0, 'no']]>>> trees.splitDataSet(myDat,0,0)[[1, 'no'], [1, 'no']]>>> trees.chooseBestFeatureToSplit(myDat)0执行结果表明:第0个特征更能适用于分类判断。
在trees.py文件中继续写入(首行添加一句:import operator):
def majorityCnt(classList): #return the feather which appear most 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): classList = [example[-1] for example in dataSet] # if the type is the same, stop classify if classList.count(classList[0]) == len(classList): return classList[0] # traversal all the features and choose the most frequent feature if (len(dataSet[0]) == 1): return majorityCnt(classList) bestFeat = chooseBestFeatureToSplit(dataSet) bestFeatLabel = labels[bestFeat] myTree = {bestFeatLabel:{}} del(labels[bestFeat]) #get the list which attain the whole properties 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
在shell中执行:
>>> myTree=trees.createTree(myDat,labels)>>> myTree{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}训练好的数据最终的目的是进行分类,在trees.py中继续写入:
def classify(inputTree, featLabels, testVec): #use to classify new feather firstStr = inputTree.keys()[0] secondDict = inputTree[firstStr] featIndex = featLabels.index(firstStr) for key in secondDict.keys(): if testVec[featIndex] == key: if type(secondDict[key]).__name__ == 'dict': classLabel = classify(secondDict[key], featLabels, testVec) else: classLabel = secondDict[key] return classLabel
在shell中执行:
>>> myDat,labels=trees.createDataSet()>>> labels['no surfacing', 'flippers']>>> trees.classify(myTree,labels,[1,0])'no'>>> trees.classify(myTree,labels,[1,1])'yes'
另外,在网上也能找到C++实现的决策树算法,见参考部分。
参考:
《机器学习实战》
http://www.tuicool.com/articles/fMvyeq (PYTHON)
http://blog.csdn.net/tianzhaixing2013/article/details/37053603 (PYTHON)
http://blog.sina.com.cn/s/blog_8095e51d01013chj.html
http://blog.csdn.net/czp11210/article/details/51161531
http://blog.csdn.net/yangliuy/article/details/7322015 (C++)
http://blog.csdn.net/zhoubl668/article/details/40828573 (C++)
http://www.voidcn.com/blog/zhaocj/article/p-4978286.html (Opencv)
- 机器学习算法之决策树(python)
- 机器学习之决策树算法python实现
- Python机器学习(三)--决策树算法
- Python机器学习(三)--决策树算法
- 机器学习之决策树实现(Python)
- 机器学习算法之决策树(二)
- 机器学习算法之决策树(三)
- 机器学习之决策树算法(1)
- 【机器学习算法】之决策树
- 机器学习算法之决策树
- 机器学习算法之决策树
- 机器学习之决策树算法
- 机器学习之决策树算法
- 机器学习之决策树(ID3)算法与Python实现
- 机器学习(三):分类算法之决策树算法
- 机器学习算法之决策树算法
- 用Python开始机器学习(2:决策树分类算法)
- 机器学习算法-决策树(续)Python实现
- jQuery+ajax+php实现注册登录功能
- 解决Package fuse was not found in the pkg-config search path.
- springold to springnew4
- Javascript 面向对象编程(一):封装
- Ibatis 缓存机制
- 机器学习算法之决策树(python)
- JS对象与数组
- java反射几个方法
- Android业务组件化之URL Scheme使用
- 并发 并行 同步 异步 多线程的区别
- linux利用sed去除中括号[]
- mysql实现类似伪列效果
- 捡到的苹果6plus怎么解id要多少钱
- Android 中生成普通二维码、中心Logo 二维码、以及扫描解析二维码