决策树算法讨论
1.题目的主要研究内容
1、主要研究了决策树算法的主要原理,讲解了ID3算法以及实现思想,信息熵、条件熵、信息增益的概念和决策树构造,以及案例手动实现,Python代码推演以及OCTAVE实现。
2、自己工作的主要描述
PPT制作以及讲解决策树前置概念,决策树概念和核心思想,以及一些小例子,决策树构造、决策树的分类步骤和决策树优缺点等。
2.题目研究的工作基础或实验条件
1、硬件环境
2、软件环境(pycharm)
3.决策树
这是一个“判断是否喜欢打篮球的人”的粒子,该例子通过“年龄”和“性别”两种属性,来区分“是否喜欢打篮球”,按照该图示,如果年龄<15岁,会产生两个分支,一个是Y分支,一个是N分支,我们可以看到,Y分支下,又会根据性别这个属性来再次判断,又会产生Y分支和N分支,最后我们发现可以判断出男性不喜欢打篮球,女性和大于15岁的人不喜欢打篮球,这一类,都是有唯一属性是不喜欢打篮球。
决策树是一种十分常用的分类方法,需要监管学习(有教师的Supervised Learning),监管学习就是给出一堆样本,每个样本都有一组属性和一个分类结果,也就是分类结果已知,那么通过学习这些样本得到一个决策树,这个决策树能够对新的数据给出正确的分类。这里通过一个简单的例子来说明决策树的构成思路:
决策树的生成主要分以下两步,这两步通常通过学习已经知道分类结果的样本来实现。
1. 节点的分裂:一般当一个节点所代表的属性无法给出判断时,则选择将这一节点分成2个子节点(如不是二叉树的情况会分成n个子节点)
2. 阈值的确定:选择适当的阈值使得分类错误率最小 (Training Error)。
比较常用的决策树有ID3,C4.5和CART(Classification And Regression Tree),CART的分类效果一般优于其他决策树。下面介绍具体步骤。
ID3: 由增熵(Entropy)原理来决定那个做父节点,那个节点需要分裂。对于一组数据,熵越小说明分类结果越好。熵定义如下:
Entropy=- sum [p(x_i) * log2(P(x_i) ]
其中p(x_i) 为x_i出现的概率。假如是2分类问题,当A类和B类各占50%的时候,Entropy = - (0.5*log_2( 0.5)+0.5*log_2( 0.5))= 1;当只有A类,或只有B类的时候,Entropy=-(1*log_2(1)+0)=0所以当Entropy最大为1的时候,是分类效果最差的状态,当它最小为0的时候,是完全分类的状态。因为熵等于零是理想状态,一般实际情况下,熵介于0和1之间。
熵的不断最小化,实际上就是提高分类正确率的过程。
4.代码及演示
#计算香农值
def calShanEnt(dataset,col):
tarset=set(dataset[col])
res=0
for i in tarset:
pi=np.sum(dataset[col] == i)/len(dataset)
res=res-pi* log(pi, 2)
return res
#分裂函数
def splitData(Data,fea,value):
res=Data[Data[fea]==value].copy()#获取去掉非单个属性的数据集
res=res.drop(fea,axis=1)
return res
#ID3树的计算函数
def ID3(value_set,dataset,fea):
baseEnt = calShanEnt(dataset, "target")#香农值
newEnt = 0
for v in value_set:
newEnt += np.sum(dataset[fea] == v) / len(dataset) * calShanEnt(dataset[dataset[fea] == v],"target")#条件熵
return baseEnt-newEnt #信息增益
#获取最大的信息增益
def chooseBestFea(dataset):
features=[i for i in dataset.columns if i!='target']#获取第一行的值
bestFet=features[0]
bestInfoGain=-1
for fea in features:
value_set=set(dataset[fea])
gain=ID3(value_set,dataset,fea)#这是调用ID3增益的函数,返回信息增益
if gain>bestInfoGain:
bestInfoGain=gain
bestFet=fea#获取最大的信息增益
return bestFet
def creatTree(dataset):
if len(set(dataset['target']))==1: #是否单一属性
#print(list(dataset['target']))
return list(dataset['target'])[0]
bestFea=chooseBestFea(dataset)#信息增量最大的树节点
myTree={bestFea:{}}
# print(set(dataset[bestFea]))
for i in set(dataset[bestFea]):
myTree[bestFea][i]=creatTree(splitData(dataset,bestFea,i))#递归创建树
# print(myTree)
return myTree
T=creatTree(dataset)
print(T)
#计算香农值
def calShanEnt(dataset,col):
tarset=set(dataset[col])
res=0
for i in tarset:
pi=np.sum(dataset[col] == i)/len(dataset)
res=res-pi* log(pi, 2)
return res
#分裂函数
def splitData(Data,fea,value):
res=Data[Data[fea]==value].copy()#获取去掉非单个属性的数据集
res=res.drop(fea,axis=1)
return res
#ID3树的计算函数
def ID3(value_set,dataset,fea):
baseEnt = calShanEnt(dataset, "target")#香农值
newEnt = 0
for v in value_set:
newEnt += np.sum(dataset[fea] == v) / len(dataset) * calShanEnt(dataset[dataset[fea] == v],"target")#条件熵
return baseEnt-newEnt #信息增益
#获取最大的信息增益
def chooseBestFea(dataset):
features=[i for i in dataset.columns if i!='target']#获取第一行的值
bestFet=features[0]
bestInfoGain=-1
for fea in features:
value_set=set(dataset[fea])
gain=ID3(value_set,dataset,fea)#这是调用ID3增益的函数,返回信息增益
if gain>bestInfoGain:
bestInfoGain=gain
bestFet=fea#获取最大的信息增益
return bestFet
def creatTree(dataset):
if len(set(dataset['target']))==1: #是否单一属性
#print(list(dataset['target']))
return list(dataset['target'])[0]
bestFea=chooseBestFea(dataset)#信息增量最大的树节点
myTree={bestFea:{}}
# print(set(dataset[bestFea]))
for i in set(dataset[bestFea]):
myTree[bestFea][i]=creatTree(splitData(dataset,bestFea,i))#递归创建树
# print(myTree)
return myTree
T=creatTree(dataset)
print(T)