本文主要介绍了python机器学习中的决策树分类,具有一定的参考价值。感兴趣的朋友可以参考一下。
决策树分类和上一篇博客K近邻分类最大的区别是K近邻分类没有训练过程,而决策树是通过分析训练数据来构建决策树,通过决策树对测试数据进行分类,这也属于监督学习的范畴。决策树的结果类似于下图:
图中的方框代表叶节点,带圆边的方框代表决策节点。决策节点和叶子节点的区别在于,决策节点需要通过判断节点的状态来进一步分类。
那么如何通过训练数据得到这样的决策树呢?
这就涉及到信息论中非常重要的信息度量方法——香农熵。信息增益可以通过香农熵来计算。
香农熵计算如下:
P(xi)表示数据被归入I类的概率,可以通过计算数据集中I类的个数与数据总个数的比值得到。计算香农熵的python代码如下:
从数学导入日志
def calcShannonEnt(数据集):
numEntries=len(数据集)
labelCounts={}
对于数据集中的featVec:
currentLabel=featVec[-1]
如果当前标签不在labelCounts.keys()中:
label counts[当前标签]=0
label counts[当前标签]=1
shannonEnt=0.0
对于标签帐户中的密钥:
prob=float(label counts[key])/numEntries
shannonEnt-=prob*log(prob,2)
返回shannonEnt
一般来说,在一个数据集中,不同的类别越多,也就是信息越多,熵就越大。通过计算熵,可以知道哪个特征最能分离数据,这个特征就是一个决策节点。
接下来,可以根据训练数据构建决策树。
首先,编写一个根据给定特征划分数据集的函数:
#划分数据集,返回以数值为轴的数据集。
def splitDataSet(数据集,轴,值):
retDataSet=[]
对于数据集中的featVec:
if featVec[轴]==值:
reducedFeatVec=featVec[:]
del(reducedFeatVec[轴])
ret dataset . append(reducedFeatVec)
返回retDataSet
让我们找出数据集中哪个特征最能划分数据。其原理是计算数据除以各特征轴的信息增益。信息增益越大,用这个特征轴划分数据越好。
#选择分割数据集的最佳方式并返回最佳轴
def chooseBestFeatureToSplit(数据集):
numFeatures=len(dataset[0])-1
baseEntrypy=calcShannonEnt(数据集)
bestInfoGain=0.0
bestFeature=-1
对于范围内的I(num features):
featList=[example[i]数据集中的示例]
uniqueVals=set(featList)
newEntrypy=0.0
对于唯一值:
subDataSet=splitDataSet(数据集,I,值)
prob=len(子数据集)/float(len(数据集))
newEntrypy=prob * calcShannonEnt(子数据集)
Gain=baseentrypy-newentrypy #计算信息增益,最大信息增益为最佳划分。
如果infoGainbestInfoGain:
bestInfoGain=信息增益
bestFeature=i
返回最佳功能
在找到最优划分轴后,可以通过递归建立决策树。递归有两个终止条件。第一是程序遍历所有分区数据集的特征轴,第二是每个分支下的所有实例都有相同的分类。那么,这里就出现了一个问题,就是在遍历所有数据集的时候,分离出来的数据并不在同一个范畴。在这种情况下,通常选择类别最多的类别作为叶节点的类别。
首先,编写一个在类别向量中找到最多类别的类别:
#计算类型列表中类型最多的类型。
def majorityCnt(类别列表):
classCount={}
对于类别列表中的投票:
如果vote不在classCount.keys()中:
classCount[vote]=0
classCount[vote]=1
sortedClassCount=sorted(class count . ITER items(),key=operator.itemgetter(1),reverse=True)
返回sortedClassCount[0][0]
创建递归决策树:
#根据训练数据创建树
定义创建树(数据集,标签):
myLabels=labels[:]
Class=[example [-1]例如在数据集中] # category
class list . count(class list[0])==len(class list):#所有数据集都是同一种。
返回类列表[0]
Len (dataset [0])==1: #训练集中只有一个数据
返回majorityCnt(classList)
best feat=chooseBestFeatureToSplit(数据集)
bestFeatLabel=myLabels[bestFeat]
myTree={bestFeatLabel:{}}
戴尔(myLabels[bestFeat])
featValue=[example[bestFeat]数据集中的示例]
uniqueVal=set(featValue)
对于uniqueVal中的值:
subLabels=myLabels[:]
myTree[bestFeatLabel][value]=create tree(split dataSet(dataSet,bestFeat,value),子标签)
返回我的树
将上述代码保存在tree.py中,并在命令窗口中输入以下代码:
数据集=[[1,1,'是'],
[1,1,'是'],
[1,0,'否'],
[0,1,'否'],
[0,1,'否']]
标签=['无表面','脚蹼']
tree.createTree(数据集,标签)
{'no sufacing': {0: 'no ',1: {'flippers': {0: 'no ',1: 'yes'}}}
得到决策树的结构,并可以画出树的结构图
以上数据的实际意义是通过生物学特征判断是否属于鱼类。在第一列数据中,1代表能在水中生存,0代表不能在水中生存。在第二列中,1代表鳍状肢,0代表没有鳍状肢。是的是鱼,不不是鱼。标签是训练数据中每一列的含义。然后,通过训练数据,我们构建了一个决策树。从图中可以看出,我们可以先根据第一列特征做出第一个判断,即是否能在水中生存。肯定不是鱼活不下去。什么能活下来取决于有没有鳍,有鳍的就是鱼。
不难看出,决策树最大的优势在于其数据形式简单易懂,分类方法直观。
对决策树进行训练后,我们就可以根据决策树对新的测试数据进行分类。
分类代码如下:
#根据决策树分类
定义分类(输入树,特征标签,测试向量):
firstStr=inputTree.keys()[0]
secondDict=inputTree[firstStr]
feat index=feat labels . index(first str)
对于secondDict.keys()中的key:
if testVec[featIndex]==key:
if类型(secondDict[key])。__name__=='dict ':
class label=classify(second dict[key],featLabels,testVec)
否则:
classLabel=secondDict[key]
返回classLabel
下面是一个用决策数算法分类的例子。眼科医生如何判断患者需要佩戴的隐形眼镜类型?
判断结果有三种:材质硬、材质软、不适合佩戴。
训练数据是来自UCI数据库的隐形眼镜数据集。包含了很多患者眼部情况的观察情况和医生推荐的眼镜类型。
数据集如下:
测试代码如下:
def示例():
fr=open('lenses.txt ')
lenses=[inst.strip()。split(' \ t ')for inst in fr . readlines()]
lensesLabels=['年龄','处方','散光','撕裂率']
lensesTree=createTree(透镜,透镜标签)
返回lensesTree
结果:
决策树的结构如下:
这样医生就可以一步一步的观察,最终知道患者适合什么样的隐形眼镜。
这就是本文的全部内容。希望对大家的学习有帮助,支持我们。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。