分类树(决策树)是一种十分常用的分类方法。他是一种监管学习,所谓监管学习就是给定一堆样本,每个样本都有一组属性和一个类别,这些类别是事先确定的,那么通过学习得到一个分类器,这个分类器能够对新出现的对象给出正确的分类。这样的机器学习就被称之为监督学习。
下面介绍用ID3算法构造决策树的过程(参考 http://blog.csdn.net/acdreamers/article/details/44661149)
ID3算法是决策树的一种,它是基于奥卡姆剃刀原理的,即用尽量用较少的东西做更多的事。ID3算法,
即Iterative Dichotomiser 3,迭代二叉树3代,是Ross Quinlan发明的一种决策树算法,这个
算法的基础就是上面提到的奥卡姆剃刀原理,越是小型的决策树越优于大的决策树,尽管如此,也不总
是生成最小的树型结构,而是一个启发式算法。
在信息论中,期望信息越小,那么信息增益就越大,从而纯度就越高。ID3算法的核心思想就是以信息
增益来度量属性的选择,选择分裂后信息增益最大的属性进行分裂。该算法采用自顶向下的贪婪搜索遍
历可能的决策空间。
3. 信息熵与信息增益
在信息增益中,重要性的衡量标准就是看特征能够为分类系统带来多少信息,带来的信息越多,该特征越
重要。在认识信息增益之前,先来看看信息熵的定义
熵这个概念最早起源于物理学,在物理学中是用来度量一个热力学系统的无序程度,而在信息学里面,熵
是对不确定性的度量。在1948年,香农引入了信息熵,将其定义为离散随机事件出现的概率,一个系统越
是有序,信息熵就越低,反之一个系统越是混乱,它的信息熵就越高。所以信息熵可以被认为是系统有序
化程度的一个度量。
假如一个随机变量的取值为
,每一种取到的概率分别是
,那么
的熵定义为
意思是一个变量的变化情况可能越多,那么它携带的信息量就越大。
对于分类系统来说,类别是变量,它的取值是
,而每一个类别出现的概率分别是
而这里的就是类别的总数,此时分类系统的熵就可以表示为
以上就是信息熵的定义,接下来介绍信息增益。
信息增益是针对一个一个特征而言的,就是看一个特征,系统有它和没有它时的信息量各是多少,两者
的差值就是这个特征给系统带来的信息量,即信息增益。
接下来以天气预报的例子来说明。下面是描述天气数据表,学习目标是play或者not play。
可以看出,一共14个样例,包括9个正例和5个负例。那么当前信息的熵计算如下
在决策树分类问题中,信息增益就是决策树在进行属性选择划分前和划分后信息的差值。假设利用
属性Outlook来分类,那么如下图
划分后,数据被分为三部分了,那么各个分支的信息熵计算如下
那么划分后的信息熵为
代表在特征属性
的条件下样本的条件熵。那么最终得到特征属性
带来的信息增益为
信息增益的计算公式如下
其中为全部样本集合,
是属性
所有取值的集合,
是
的其中一个属性值,
是
中属性
的值为
的样例集合,
为
中所含样例数。
在决策树的每一个非叶子结点划分之前,先计算每一个属性所带来的信息增益,选择最大信息增益的属性来划
分,因为信息增益越大,区分样本的能力就越强,越具有代表性,很显然这是一种自顶向下的贪心策略。以上
就是ID3算法的核心思想。
下面是Python使用sklearn库实现决策树的过程
数据集如下所示
RID | age | income | student | credit_rating | Class:buys_computer | |
1 | youth | high | no | fair | no | |
2 | youth | high | no | excellent | no | |
3 | middle_aged | high | no | fair | yes | |
4 | senior | medium | no | fair | yes | |
5 | senior | low | yes | fair | yes | |
6 | senior | low | yes | excellent | no | |
7 | middle_aged | low | yes | excellent | yes | |
8 | youth | medium | no | fair | no | |
9 | youth | low | yes | fair | yes | |
10 | senior | medium | yes | fair | yes | |
11 | youth | medium | yes | excellent | yes | |
12 | middle_aged | medium | no | excellent | yes | |
13 | middle_aged | high | yes | fair | yes | |
14 | senior | medium | no | excellent | no |
得出的决策树如下所示
代码如下
from sklearn.feature_extraction import DictVectorizer
import csv
from sklearn import preprocessing
from sklearn import tree
from sklearn.externals.six import StringIO
allElectronicsData=open(r'F:\pythontest\DecisionTree\testdata.csv') #导入数据集
reader=csv.reader(allElectronicsData)
headers=reader.next()
print(headers)
#将属性和结果分开
featureList=[]
labelList=[]
for row in reader:
labelList.append(row[len(row)-1])
rowDict={}
for i in range(1,len(row)-1):
rowDict[headers[i]]=row[i]
featureList.append(rowDict)
print(featureList)
vec=DictVectorizer()
dummyX=vec.fit_transform(featureList).toarray() #将属性集数字化
print("dummyX:"+str(dummyX))
print(vec.get_feature_names())
print("labelList:"+str(labelList))
lb=preprocessing.LabelBinarizer()
dummyY=lb.fit_transform(labelList) #将结果集数字化
print("dummyY:"+str(dummyY))
clf=tree.DecisionTreeClassifier(criterion="entropy") #建立决策树模型 entropy表示用ID3算法,默认是调用GINI算法
clf=clf.fit(dummyX,dummyY)
print("clf:"+str(clf))
#将建立的决策树图形化导出
with open("allElectronicInformationGainOri.dot",'w') as f:
f=tree.export_graphviz(clf,feature_names=vec.get_feature_names(),out_file=f)
oneRowX=dummyX[0,:]
print("oneRowX:"+str(oneRowX))
newRowX=oneRowX
newRowX[0]=1
newRowX[2]=0
print("newRowX:"+str(newRowX))
predictdY=clf.predict(newRowX)
print("predictedY:"+str(predictdY))