0.机器学习中分类和预测算法的评估:
准确率
速度
强壮行
可规模性
可解释性
1.决策树概念(decision tree)
决策树是一个类似于流程图的结构:其中,每个内部结点表示在一个属性上的测试,每个分支代表一个属性输出,而每个树叶结点代表类或类分布。树的最顶层是根结点。决策树是机器学习中分类方法中的一个重要算法。结点有两种类型:内部结点和叶结点,内部结点表示一个特征或属性,叶结点表示一个类。
2.构造决策树的基本算法。
2.1信息增益
熵:一条信息的信息量大小和它的不确定性有直接的关系,要搞清楚一件非常非常不确定的事情或者是我们一无所知的事情,需要了解大量信息→信息量的度量就等于不确定的多少。变量的不确定性越大,熵也就越大。
信息增益(Gain):表示得知特征X的信息而使得类Y的信息的不确定性减少的程度。特征A对训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差。即:
g(D,A)=H(D)-H(D|A)
根据信息增益准则的特征选择方法是:对训练数据集(或子集)D,计算其每个特征的信息增益,并比较它们的大小,选择信息增益最大的特征。
举例:计算下表年龄特征的信息增益:
(1)计算数据集的经验熵:
(2)计算年龄特征对数据集的经验条件熵:
(3)计算信息增益:
3.2决策树归纳算法(ID3)
还是以上图为例。我们已经计算出来age的信息增益为0.246bits。分别计算出Gain(incom)=0.029,Gain(student)=0.151,
Gain(credit_rating)=0.045。所以选择age作为第一个根节点。
以上可知,当middle_aged时,全为yes,可以作为叶节点。年龄为其他两个时有yes or no,所以应该进行分支。分别计算这时
incom、student、credit_rating的信息增益,选最大的作为结点。
算法:
(1)树以代表训练样本的单个结点开始(步骤1)
(2)如果样本都在同一个类,则该结点成为叶结点,并用该类标号。(步骤2,3)
(3)否则,算法使用信息增益原则,选择能够最好地将样本分类的属性(步骤6)。该属性成为该结点的“测试”或“判定”属性(步骤7)。在算法该版本中,所有的属性都是分类的,即离散值,连续属性必须离散化。
(4)对测试属性的每一个已知的值,创建一个分支,并据此划分样本(步骤8-10)
(5)算法使用同样的过程,递归地形成每个划分上的样本判定树。一旦一个属性出现在一个结点上,就不必该结点的任何后代上考虑它。(步骤11)
(6)递归划分步骤仅当下列条件之一成立停止:
a.给定结点的所有样本属于同一类(步骤2,3)
b.没有剩余属性可以用来进一步划分样本(步骤4)。在此情况下,用样本中多数所在的类标记它(步骤5)
c.分支
4.决策树的剪枝
避免overfitting。有两种剪枝方式:
(1)先剪枝:设置一定阈值分到一定程度就不继续增长树的大小。
(2)后剪枝:把树建好后根据一定标准剪掉一些枝叶。
5.决策树优点:
直观,便于理解,小规模数据集有效。
6.决策树缺点:
处理连续变量不好,类别较多时错误增加得比较快,可规模性一般。
7.代码:
# -*- coding: utf-8 -*-
from sklearn.feature_extraction import DictVectorizer
import csv
from sklearn import tree
from sklearn import preprocessing
from sklearn.externals.six import StringIO
allElectronicsData=open(r"F:\My Codes\python27\python\AllElectronics.csv",'rb')
reader=csv.reader(allElectronicsData) # 按行读内容取
headers=reader.next() #文件里第一行
print(headers)
#转换数据格式,搭建的矩阵要以0,1表示特征值。
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] #key是headers里取,value在row里取
featureList.append(rowDict)
print(featureList)
vec = DictVectorizer() #可以调用此模块将包含有字典的list里面的数据自动转换成0,1
dummyX = vec.fit_transform(featureList) .toarray() #调用fit_transform直接转换特征数据
print("dummyX:"+str(dummyX))
print(vec.get_feature_names())
print("lanelList:"+str(labelList))
lb=preprocessing.LabelBinarizer() #调用此模块对类直接进行标记
dummyY=lb.fit_transform(labelList)
print("dummyY="+str(dummyY))
clf=tree.DecisionTreeClassifier(criterion='entropy') #ID3
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) #把feature_names返回到以前的特征值,画决策树
oneRowX=dummyX[0,:]
print("oneRowX"+str(oneRowX))
newRowX=oneRowX
newRowX[0]=1
newRowX[2]=0
print('newRowX:'+str(newRowX))
predictedY = clf.predict(newRowX) #predict函数用来预测
print("predictedY: " + str(predictedY))