1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 《machine learning in action》机器学习 算法学习笔记 决策树模型

《machine learning in action》机器学习 算法学习笔记 决策树模型

时间:2018-05-21 05:37:35

相关推荐

《machine learning in action》机器学习 算法学习笔记 决策树模型

决策树模型

重要任务:是为了理解数据中所蕴含的知识信息,因此决策树可以使用不熟悉的数据集合,并从中提取出一系列规则,这些机器根据数据集创建规则的过程就是机器学习的过程。

优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。缺点:可能会产生过度匹配问题。

范例:专家系统。

如何构造决策树:

编写构造树的python代码度量算法成功率递归建立分类器Matplotlib绘制决策树图

利用信息论划分数据集,伪代码:

IF (整个数据集属于同一个类型) return 类标签Else 寻找划分数据集的最好特征划分数据集创建分支节点for 每个划分的子集递归继续划分return 分支节点

划分数据集的大原则是:将无序的数据变得更加有序。

信息增益

定义:在划分数据集之前之后的信息发生的变化称为信息增益。

可以用于评价一次信息划分的优劣。

集合信息的度量方式称为:香农熵

熵定义为信息的期望值。

如果待分类的事务可能划分在多个分类之中,则符号 x i x_i xi​的信息定义为:

l ( x i ) = − l o g 2 p ( x i ) l(x_i)=-log_2p(x_i) l(xi​)=−log2​p(xi​)

p ( x i ) p(x_i) p(xi​)是选择该分类的概率。

根据期望的公式,得

H = − ∑ i = 1 n p ( x i ) l o g 2 p ( x i ) H=-\sum^n_{i=1}p(x_i)log_2p(x_i) H=−i=1∑n​p(xi​)log2​p(xi​)

计算给定那个数据集的香农熵:

from math import logdef calcShannonEnt(dataSet):numEntries = len(dataSet)labelCounts = {}for featVec in dataSet:#统计每个标签出现的频次,利用统计数currentLabel = featVec[-1]if currentLabel not in labelCounts.keys():labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1ShannonEnt = 0.0for key in labelCounts:prob = float(labelCounts[key])/numEntries#求概率ShannonEnt -= prob *log(prob,2)#求期望return ShannonEnt

基尼不纯度:另一种度量集合无序程度的方法。

决策树的构建过程实际上就是降低香农熵(无序度量值)的过程。

对于一个特征集合我们可以选择的划分方式就是各个特征,选择哪个特征能够更加快的降低数据集的无序度?

我们只需要尝试按照每一种方式划分,看看哪种划分更快的降低无序度,那么便选择它,这也就是上面伪代码讲的如何划分。

如何理解以下这段代码(由于书中并没有对这段代码解释,以下属于笔者的猜测):

for value in uniqueVals:subDataSet = splitDataSet(dataSet, i, value)prob = len(subDataSet)/float(len(dataSet))newEntropy += prob * calcShannonEnt(subDataSet)

我们可以知道信息熵的定义是期望,我们想要得到的是按照某一特征划分之后整体的期望。

那么可以得到一个新的公式,根据期望的计算 E = ∑ i = 1 n p ( x i ) ∗ x i E=\sum_{i=1}^{n}p(x_i)*x_i E=∑i=1n​p(xi​)∗xi​​。​

其中 x i x_i xi​表示的便是划分后的第i个集合的香农熵的值, p ( x i ) p(x_i) p(xi​)​​表示选择该数据集的概率。

最终建立的树是用字典表示的,例如:

{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

若字典中的关键字的值对印的是类标签,则表示这是一个叶子结点,若为仍是字典,则表示这是一个判断结点。

利用matplotlib注释绘制属性图。

直接上结果吧

trees.py:

from math import logimport operator#------------计算给定数据集的香农熵-------------def calcShannonEnt(dataSet):numEntries = len(dataSet)labelCounts = {}for featVec in dataSet:#统计每个标签出现的频次,利用统计数currentLabel = featVec[-1]if currentLabel not in labelCounts.keys():labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1ShannonEnt = 0.0for key in labelCounts:prob = float(labelCounts[key])/numEntries#求概率ShannonEnt -= prob *log(prob,2)#求期望return ShannonEnt#-------------生成测试的数据集-----------------def createDataSet():dataSet = [[1,1,'maybe'],[1,1,'yes'],[1,0,'no'],[0,1,'no'],[0,1,'no']]labels = ['no surfacing','flippers']return dataSet,labels#-------------划分数据集------------------#代码思路就是将axis维的特征值为value的放到一个新的数据集中def splitDataSet(dataSet,axis,value):retDataSet = []for featVec in dataSet:if featVec[axis] == value:reducedFeatVec = featVec[:axis]reducedFeatVec.extend(featVec[axis+1:])#a.extend(b) [a,b]retDataSet.append(reducedFeatVec)#a.append(b) [a,[b]]return retDataSet#------------选择最好的数据集划分方式---------------def chooseBestFeatureToSplit(dataSet):numFeatures = len(dataSet[0]) - 1#the last column is used for the labelsbaseEntropy = calcShannonEnt(dataSet)bestInfoGain = 0.0; bestFeature = -1#找到的是使得香农熵减少最多的划分方式for i in range(numFeatures): #iterate over all the featuresfeatList = [example[i] for example in dataSet]#create a list of all the examples of this featureuniqueVals = set(featList) #get a set of unique valuesnewEntropy = 0.0for value in uniqueVals:subDataSet = splitDataSet(dataSet, i, value)prob = len(subDataSet)/float(len(dataSet))newEntropy += prob * calcShannonEnt(subDataSet)infoGain = baseEntropy - newEntropy#calculate the info gain; ie reduction in entropyif (infoGain > bestInfoGain): #compare this to the best gain so farbestInfoGain = infoGain #if better than current best, set to bestbestFeature = ireturn bestFeature #returns an integer#------------获取出现次数最多的分类名称--------------#代码实现,利用map先计数后排序def majorityCnt(classList):classCount={}for vote in classList:if vote not in classCount.keys(): classCount[vote] = 0classCount[vote] += 1sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)return sortedClassCount[0][0]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[:] #copy all of labels, so trees don't mess up existing labelsmyTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)return myTree

main.py

import treePlotterimport treesmyDat,labels=trees.createDataSet()print(myDat)print(trees.calcShannonEnt(myDat))print(trees.splitDataSet(myDat,0,1))print(trees.splitDataSet(myDat,1,1))print(trees.chooseBestFeatureToSplit(myDat))mytree=trees.createTree(myDat,labels)print(mytree)

结语:

决策树的工作原理就是将原本无序的数据集变得有序,并且这种有序是用树的方式呈现的,该模型的核心便是如何指导模型,使得数据集向有序变化。

决策树使用的无序度,尽量让每一次的划分都能最大化的降低整体的无序度,通过这种方式一步一步的走向有序。

同时,信息熵的概念同样让人着迷,尽管不知道为什么是 − l o g 2 ( p ( x ) ) -log_2(p(x)) −log2​(p(x)),但他确实好用,类似的还有交叉熵,等等,这些度量函数值得了解和学习。

今天也是的最后一天,在过去的一年,acm参加了七个赛站,最后以两铜结束,参加了数学建模没能完成论文,混了省一。高中初中小学,都有一点点的竞赛经验,但是都没有获奖,也不是十分重视,到了大学acm也算是圆了竞赛梦,尽管现实残酷。过去这一年的种种遗憾都将随时间流走,希望在新的一年里向着新的方向前行。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。