决策树
目标:
根据给定的训练数据集构建一个决策树模型,可以根据这个模型对实例进行正确的分类。决策树本质上是从训练数据集中归纳出一组分类规则。能对训练数据进行正确的分类的决策树可能有多个,可能没有。在选择决策树时,应该选择一个与训练数据矛盾较小的决策树,同事具有很好的泛化能力,选择的条件概率模型应该不仅对训练数据有很好的拟合而且对未知数据有很好的预测能力。
原理:
通常是选择最优特征,并根据该特征对训练数据进行分割,使得对各子数据有一个最好的分类的过程。包括特征的选择,决策树的生成和决策树的剪枝过程。任何给定的信息都存在冗余,那么冗余信息占有用信息的百分比就是一种混乱程度状态,在物理分子状态中,这种冗余可以形容在分子状态下所有分子的混乱程度。基于这一原理实现决策树算法定义。
信息增益:
在概率论和信息论中,信息增益是非对称的,用以度量两种概率分布P和Q 的差异。信息增益描述了当使用Q 进行编码时,再使用P进行编码的差异。通常P代表样本或者观察值得分布,也有可能是精确计算的理论分布。Q代表一种理论,模型,描述或者对P的近似。在信息增益中,衡量标准是看特征能够为分类系统带来多少信息,带来的信息越多,该特征越重要。对一个特征而言,系统有它和没它时信息量将发生变化,而前后信息量的差值就是这个特征给系统带来的信息量。所谓信息量,就是熵【shang】。信息增益最大的问题在于它只能考察特征对整个系统的贡献,而不能具体到某个类别上,这就使得它只适合用来做所谓“全局”的特征选择(指所有的类都使用相同的特征集合),而无法做“本地”的特征选择(每个类别有自己的特征集合,因为有的词,对这个类别很有区分度,对另一个类别则无足轻重)。
# name: kenny adelaide
# email: kenny13141314@163.com
# time : 17-11-8
# description
## 决策树
###优点: 计算的复杂不不高,输出的结果容易理解,对中间值得缺失不敏感,可以处理不相关特征数据
###缺点: 可能会产生过度匹配的问题
###适用数据类型:数值型,标称型
#创建分支的伪数据集代码函数 createBranch(), 这是一个递归函数,在倒数第二行直接调用自己
# ID3 算法 划分数据集 每次划分数据集我们只选取一个特征值属性,如果存在多个特征值,我们选取哪一个特征值属性划分?
#****计算增益计算:
# entropy 信息的期望值
# the function be for information calculate about entropy-- 这个函数是计算信息度量的 entropy
from math import log
import matplotlib.pyplot as plt
#import treePlotter
# create the set of training data - 创建训练数据集
def createDataSet():
dataSet =[ # 创建训练数据
[1,1,2,'yes'],
[1,1,3,'yes'],
[1,0,4,'no'],
[0,1,5,'no'],
[0,1,6,'no']
]
labels=['no surfacing','flippers'] # 创建分类标签
return dataSet,labels
def calcShannonEnt(dataSet):
numEntries=len(dataSet)
lableCounts={}
for featVec in dataSet:
currentLabel=featVec[-1] # 取每个训练数据的最后一个特征值
if currentLabel not in lableCounts.keys():
lableCounts[currentLabel]=0
lableCounts[currentLabel]+=1
shannonEnt=0.0
for key in lableCounts:
prob = float(lableCounts[key])/numEntries # 计算每个分类出现的概率
shannonEnt -= prob *log(prob,2) # log 2 位底的log 函数 其对数是好多
return shannonEnt
#calcShannonEnt(createDataSet()[0])
#按照给定的特征值划分数据集
# 讲无序的数据集 有序的划分,[祛除非特征值列的所有列组成矩阵]
def splitDataset(dataSet,axis,value):
recDataset=[]
for featVec in dataSet:
if featVec[axis]==value:
reducedFeatVec=featVec[:axis] # 取特征值之前的值
#print('reducedFeatVec:%s'%reducedFeatVec)
reducedFeatVec.extend(featVec[axis+1:])# 取非特征值的其他特征值数据,跳过特征值
#print(reducedFeatVec)
recDataset.append(reducedFeatVec)
print('recDataset:%s'%recDataset)
#print('------------------------------')
return recDataset
#splitDataset(createDataSet()[0],1,1);
# 选择最好的数据集划分方式
def chooseBestFeatureToSplit(dataset):
#print(dataset[0])
numFeatures=len(dataset[0])-1 #计算新的特征值数量
#print(numFeatures)
baseEntropy=calcShannonEnt(dataset)
#print('未划分前的信息度量值:%f'%baseEntropy) # 计算数据集的信息度量值
#print('--------------------------')
baseInfoGain=0.0 # 计算前信息度量值
bestFeature=-1 #最好的特征值 为-1
for i in range(numFeatures): # numfeature=2
featList=[example[i] for example in dataset] # 得到非类别划分的所有特征值 本列子就是 yes 或者no
print(dataset)
print(featList)
uniqueVals=set(featList) # 在set中除去重复的特征值 ,这里为去除每一列的重复值
print(uniqueVals)
newEntropy=0.0
for value in uniqueVals:
print('trail:%d , value:%d' % (i,value))
subDataset=splitDataset(dataset,i,value) #获取剩余矩阵
print('subDataset:%s,len=%d,dataset-len:%d'%(subDataset,len(subDataset),len(dataset)))
prob=len(subDataset)/float(len(dataset))
print('计算改特征值分类的概率:%f'%(prob))
newEntropy+=prob* calcShannonEnt(subDataset) # 计算按每个数据特征来划分的数据集的熵[信息化度量]
print('计算按每个数据特征来划分的数据集的熵:%f'%newEntropy)
#print('----------------------------------')
infoGain=baseEntropy-newEntropy
#print('划分后的信息度量值:%f, 信息度量差值:%f'%(newEntropy,infoGain))
if(infoGain>baseInfoGain): # 判断出哪种划分方式得到最大的信息增益,且得出该划分方式所选择的特征
baseInfoGain=infoGain
bestFeature=i
print('------------------------------')
return bestFeature
chooseBestFeatureToSplit(createDataSet()[0])
在信息增益的计算中是通过数据的矩阵计算来实现,通过条件概率原理【分子状态的混乱程度】上实现的
1 1 1 1 yes
2 2 2 2 no
3 3 3 3 yes
在这样一个矩阵中,首先求出分类标签的混乱程度【也就是分类特征值的概率分布】
{yes:2,no:1} p(yes)=2/3 p(no)=1/3 则p(i)=0-2/3log(2/3)-1/3log(1/3) =E(i) 其中E(i) 就是baseEntropy
以第1列特征值为例:
{1,2,3}只有这三种值,那么对应的{value,class,number}:{1,yes,1} ,{2,no,1},{3,yes,1} 对与这三种情况分别求出信息熵:
eg1:p(1)=E(i),p(2)=E(2),p(3)=E(3)
求出之后再求条件概率【在整个分子状态中的混乱程度】=E(1)*1/3 +E(2)*1/3+E(3)*1/3=H 那么H就是newEntropy
那么baseEntropy 和newEntropy 之间的 差值为信息增益。
循环每个特征值,求出在整个分子状态的混乱程度,计算信息熵的差值。我们可以更好的选择分类标准,概率期望值越小,那么所携带的信息差别量越大,也就更好的作为分类的标准。