决策树
来源:互联网 发布:最新网络术语 编辑:程序博客网 时间:2024/06/05 18:46
一.创建分支的伪代码函数createBranch()如下所示:
If so return 类标签:Else 寻找划分数据集的最好特征 创分数据集 创建分支节点 for 每个划分的子集 调用函数createBranch()并增加返回结果到分支节点中 return 分支节点**其实createBranch是一个递归函数,在倒数第二行调用了自己**
二.信息论——信息增益
划分数据集的大原则是:将无序的数据变得更加有序。我们可以使用多种方法划分数据集。组织杂乱无章数据的一种方法就是使用信息论度量信息,信息论是量化处理信息的分支科学。我们可以在划分数据之前使用信息论量化度量信息的内容。
在划分数据集之前之后信息发生的变化称为信息增益,计算每个特征值划分数据集获得的信息增益,获得信息增益最高的特征就是最好的选择。 (划分的依据是取得获得信息增益最高的)
熵定义为信息的期望值,那么信息的定义又是什么:如果待分类的事务可能划分在多个分类之中,则信息的定义:x_{i}=-log_{2}p(x_{i}) 这里的 p(x_{i}) 指的是选择该类的概率
则熵:H=-\sum_{i=1}^{n}p(x_{i})log_{2}p(x_{i}),其中n代表的是选择的类别,即类别的总数
1.计算香农熵:
from math import log #导入对数函数def shanNonEnt(dataset): numentries=len(dataset) labelcounts={} #创建一个空字典 for featvec in dataset: #dataset是列表 currenlabel=featvec[-1] #将featvec的最后一个元素提取 if currenlabel not in labelcounts.keys(): labelcounts[currenlabel]=1 #若此时的label在labelcounts没有,则赋值为1 else: labelcounts[currenlabel] +=1 #如果有,则加1 shannonEnt=0.0 for key in labelcounts: prob=float(labelcounts[key])/numentries #计算概率 shannonEnt -=prob*log(prob,2) #计算香农 return shannonEntdef createdataset(): #自己弄个数据集呗 dataset=[[1,1,'yes'],[1,1,'yes'],[1,0,'no'],[0,1,'no'],[0,1,'no']] return dataset
结果输出为:
>>> import tree>>> reload(tree)<module 'tree' from 'tree.pyc'>>>> dataset=tree.createdataset()>>> tree.shanNonEnt(dataset)0.9709505944546686
如果我们不断的向产生的数据集里添加标签,情况会是怎么样呢,如下:
def createdataset(): dataset=[[1,1,'yes'],[1,1,'yes'],[1,0,'no'],[0,1,'no'],[0,1,'no'],[2,1,'maybe']] #多添加一个类别 return datasetoutput:1.4591479170272448def createdataset(): dataset=[[1,1,'yes'],[1,1,'yes'],[1,0,'no'],[0,1,'no'],[0,1,'no'],[2,1,'maybe'],[1,0,'haha']] return datasetoutput:1.8423709931771086
从上述可以看到,当数据集中的类别越多的时候,香农熵越来越大
2.划分数据集
分类算法除了需要测量信息熵,还需要划分数据集,度量划分数据集的熵,以便判断是否正确划分了数据集。我们将对每个特征划分数据集的结果计算一次信息熵,然后判断按照哪个特征划分数据集是最好的划分方式。程序如下:
def splitDataSet(dataset,axis,value):#待划分的数据集,划分数据集的特征、特征的返回值 retDataSet=[] for featVec in dataset: #取出一组数据的所有特征,是一个列表 if featVec[axis]==value: #当选中的那一个特征刚好等于我们指定的特征的时候 reducedFeatVec=featVec[:axis] #对axis前面的元素赋值给reducedFeatVec reducedFeatVec.extend(featVec[axis+1:]) #将axis后面的元素赋值给reducedFeatVec retDataSet.append(reducedFeatVec) return retDataSet
输出:
>>> import tree>>> reload(tree)<module 'tree' from 'tree.pyc'>>>> dataset=tree.createdataset()>>> tree.splitDataSet(dataset,1,1)[[1, 'yes'], [1, 'yes'], [0, 'no'], [0, 'no'], [2, 'maybe']]
在上述的例子中,我们需要注意的是list.append 和 list.extend这个俩个函数的区别:尽管在大多数情况下这俩个函数具有很相似的特征,但是对于俩个列表而言,却是不一样的:
>>> a=[1,2,3]>>> b=[2,3,4]>>> a.extend(b) #将列表b的元素拆开,逐个赋值给a>>> a[1, 2, 3, 2, 3, 4]>>> a=[1,2,3]>>> b=[2,3,4]>>> a.append(b)>>> a[1, 2, 3, [2, 3, 4]] #这里是将列表b当做一个元素赋值到a中
3.循环计算香农熵和splitDataSet()函数
def chooseBestFeatureToSplit(dataset): numfeature=len(dataset[0])-1 #所有特征类别的数目 baseEntropy=shanNonEnt(dataset) #计算香农熵,这里计算的香农熵是用最后一个标签来计算的 bestinfoGain=0.0;bestfeature=-1 for i in range(numfeature): #循环所有的特征 featList=[example[i] for example in dataset] #将同一类特征的所有取值放到一个list表中 uniqueval=set(featList) newEntropy=0.0 for value in uniqueval: #对于同一类特征中的不同取值 subdataset=splitDataSet(dataset,i,value) pro=len(subdataset)/float(len(dataset)) #取得该特征的概率 newEntropy +=pro*shanNonEnt(subdataset) #算出按照这个特征分类的香农熵 infoGain=baseEntropy-newEntropy #算出信息增益,香农熵的变化 if(infoGain>bestInforGain): #比较不同特征算出来的信息增益,信息增益大的较好,即为要求的特征 bestinfoGain=infoGain bestFeature=i return bestFeature
阅读全文
0 0
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- 决策树
- Python3 正则表达式
- Glog日志模块
- Linux必学命令-文件处理类命令
- Travis.ci
- poj 2763(树链剖分)边剖(树状数组版)
- 决策树
- POJ 2524--Ubiquitous Religious
- URAL 1002|Phone Numbers|动态规划
- codeforces 546E. Soldier and Traveling 网络流
- CorelDraw应该怎么样才能学好描图技巧看看这个就能懂
- 试题3:二维数组中的查找
- java中的访问权限
- Spark Streaming基于状态、窗口的实时数据流
- java中的多线程深入探究