机器学习算法-决策树原理分析和源代码详解
前言
上一篇文章我们介绍了KNN邻近算法,分析了这个算法的一些优缺点。这一篇,针对KNN无法理解数据内容的缺点,我们来介绍决策树。
源代码地址:决策树源代码地址
决策树理论分析
一、概念解释
决策树是将已有的数据,建立起来一个规则树。
举个例子吧,假如我们要开发一个垃圾邮件识别系统,我们来使用一个树状图来描述一下我们进行判断的过程:
当然,我们判断邮件是否是垃圾邮件的规则有很多,我这里只是随便写了一个,当作一个例子。
当收到邮件时,我们会先看发邮件的是不是自己通讯录里面的人,如果是的话,即判定该邮件不是垃圾邮件。
如果不是联系人发来的邮件,我们需要点进去查看邮件内容进行判断,如果内容带有广告,那么可以判定该邮件是垃圾邮件,否则判定为非垃圾邮件。
这个思考过程我们很容易理解,因为这个过程正是我们从小到大认识、辨别事物的思考过程。
想想小时候你父母如何教你辨认猫狗的,通过不同的特征一步一步进行判定,有一些特征是非常明显的,我们通过该特征一下就能辨别,比如叫声。但是有些特征那个不太明显,比如体型、毛色等。
好了,如果你能理解上面我举得例子,那么,恭喜你,决策树的理论你也就明白了:我们就是从数据集的属性出发,不断地找出辨识度高的属性,来一步一步构建我们的思考过程。
二、信息熵、信息量
上面我们说到,需要不断找出辨识度高的属性,那么,如何进行判定哪个属性的辨识度最高呢,也就是说哪个属性能够更好的区分数据呢?我们首先来了解两个概念熵和信息
一件事情对于某人而言属于哪个类别的不确定性被称为熵
能够消除某人对这件事情的不确定性的叫做信息
我们数据中的属性值,可以理解为信息,它用来帮助我们取判断数据的归属问题,可以解决我们对于数据归属的不确定性。
还是拿动物举例,当我们知道这个动物是狗的话,此时这件事的熵为0。当我们没有获得任何信息,可以认为这个动物属于猫还是属于狗的概率一样,都是50%,此时,熵值最大。随着我们不断获取这个动物的一些属性特征,我们对于判断这个动物属于猫还是属于狗的概率会发生变化。
接下来我们看一下信息熵公式:
P是变量x的概率值。
当我们没有获取任何信息时,可以认为变量x的概率值一样,此时H1的值最大。
当我们获取到了一些信息,变量x的概率值发生了变化,此时H2的值相对上一个H1的值要小
当我们了解了许多信息,已经判断出了X的归属问题,此时Px=1 那么,H3的值为0
三、决策树是实现过程
上面我们介绍了信息熵的概念,这个概念比较抽象,我收集了一些比较容易理解地资料放在文末,大家可以去详细了解一下,不过只要是明白上面我说地,对于这一个算法就够用了。
- 通过计算信息熵,找到辨识度最大地属性
- 划分数据集
- 创建分支节点,创建决策树
- 不断循环1、2、3,,直到属性使用完毕或者数据中只剩下一种类型
这个过程看的是有点抽象,没关系,下面使用代码进行详细解释
决策树源代码解析
一、加载数据
def loadData(dataseturl):
dataset = []
with open(dataseturl) as f:
dataall = f.readlines()
for data in dataall:
dataline = data.strip().split('\t')
dataset.append(dataline)
#age(年龄)、prescript(症状)、astigmatic(是否散光)、tearRate(流泪程度)
labels=['age','prescript','astigmatic','tearRate']#四个属性
return dataset,labels
这里我们使用了《机器学习实战》所给的数据集,是关于推荐隐形眼镜类型的一个数据集。一共有四个属性,代码中注释已经给出每个属性的意义。
二、计算数据的信息熵
def calShannonEnt(dataset):
numEntries = len(dataset)
labelCounts={
}
for data in dataset:
classlabel = data[-1]
if(classlabel not in labelCounts.keys()):
labelCounts[classlabel]=0
labelCounts[classlabel]+=1
shannonEnt=0.0
#print("labelCounts",labelCounts)
for key in labelCounts:
p = float(labelCounts[key])/numEntries
shannonEnt-= p*np.log2(p)
#print("shannoEnt:",shannonEnt)
return shannonEnt
计算信息熵公式上面咱们已经给出了,这里是以数据的所属分类作为计算事件,分类数量占比作为P概率值。