机器学习算法二——决策树(3)(测试和存储分类器)+(隐形眼镜示例)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wsf09/article/details/87865679

测试和存储分类器

这节重点学习如何利用决策树执行数据分类。我们将使用决策树构建分类器,以及实际应用中如何存储分类器。

1、测试算法:使用决策树执行分类
在执行数据分类时,需要决策树以及用于构造树的标签向量。然后,程序比较测试数据与决策树上的数值,递归执行该过程直到进入叶子节点;最后,将测试数据定义为叶子节点所属的类型。

#使用决策树的分类函数
def classify(inputTree,featLabels,testVec):
    firstStr = list(inputTree.keys())[0]
    secondDict = inputTree[firstStr]
    featIndex = featLabels.index(firstStr) #将标签字符串转换为索引,即firstStr在featLabels上的位置序号,此特征是第几个属性
    for key in secondDict.keys():
        if testVec[featIndex] == key:
            if type(secondDict[key]).__name__=='dict':
                classLabel = classify(secondDict[key],featLabels,testVec)
            else:
                classLabel = secondDict[key]
    return classLabel

上述函数是一个递归函数,由于在存储带有特征的数据时会面临无法确定特征在数据集中的位置的问题(比如,前面例子中用于划分数据集的特征是no surfacing属性,但它在实际数据集中存储在第一个还是第二个属性?)所以我们使用index方法找出firstStr在featLabels上的位置序号,即是第几个属性
然后,递归遍历整棵树,寻找与testVec变量中的值相等的树节点,遍历,若到达叶子节点,则返回当前节点的分类标签。

测试

#函数retrieveTree输出预先存储的树信息
def retrieveTree(i):
    listOfTrees = [{'no surfacing':{0:'no', 1:{'flippers':{0:'no',1:'yes'}}}},
                   {'no surfacing':{0:'no', 1:{'flippers':{0:{'head':{0:'no',1:'yes'}},1:'no'}}}}]
    return listOfTrees[i]

def main():
    data,labels = createDataSet()
    myTree = retrieveTree(0)
    print(classify(myTree,labels,[1,0]))
    print(classify(myTree,labels,[1,1]))
    print(classify(myTree,labels,[0]))
   
if __name__ == '__main__':
    main()

在这里插入图片描述
{‘no surfacing’:{0:‘no’, 1:{‘flippers’:{0:‘no’,1:‘yes’}}}}。可见之前绘制的树形图和此处代表树的数据结构完全相同。

由于每次使用分类器时,必须重新构造决策树,下面我们将介绍如何在硬盘上存储决策树分类器。

2、使用算法:决策树的存储
构造决策树是很耗时的,若数据集很大,将会耗费很多计算时间。为节省计算时间,最好能在每次执行分类时调用已经构造好的决策树。使用python模块pickle序列化对象,可以在磁盘上保存对象,并在需要的时候读取出来。

#使用pickle模块存储决策树
def storeTree(inputTree,filename):
    import pickle
    fw = open(filename,'wb')
    pickle.dump(inputTree,fw)
    fw.close()

def grabTree(filename):
    import pickle
    fr = open(filename,'rb')
    return pickle.load(fr)

注:python3中文件读写要将

fw = open(filename,'w')

改为

fw = open(filename,'wb')

fr = open(filename)

改为

fr = open(filename,'rb')

运行后可以发现,

>>>{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

且目录下多了文件
在这里插入图片描述

隐形眼镜示例
数据存储在lenses.txt文件中:

#创建隐形眼镜决策树并绘制树形图
from treePlotter import createPlot

def example():
    fr = open('lenses.txt')
    lenses = [inst.strip().split('\t') for inst in fr.readlines()]
    lensesLabels = ['age','prescript','astigmatic','tearRate']
    lensesTree = createTree(lenses,lensesLabels)
    print(lensesTree)
    #createPlot(lensesTree)
    return lensesTree

def main():
    lensesTree = example()
    createPlot(lensesTree)
    
if __name__ == '__main__':
    main()

运行可以得到隐形眼镜决策树的文本形式和树形图:

>>>{'tearRate': {'normal': {'astigmatic': {'no': {'age': {'young': 'soft', 'pre': 'soft', 'presbyopic': {'prescript': {'myope': 'no lenses', 'hyper': 'soft'}}}}, 'yes': {'prescript': {'myope': 'hard', 'hyper': {'age': {'young': 'hard', 'pre': 'no lenses', 'presbyopic': 'no lenses'}}}}}}, 'reduced': 'no lenses'}}

在这里插入图片描述
上图是由ID3算法产生的决策树。

沿着决策树的不同分支,我们可以得到不同患者需要佩戴的隐形眼镜类型。从上图也可看出,医生最多需要问四个问题就能确定患者需要佩戴哪种类型的隐形眼镜。

上图的决策树很好地匹配了实验数据,然而这些匹配选项可能太多了。我们将这种问题称之为过度匹配。为了减少过度匹配问题,可裁剪决策树,去掉一些不必要的叶子节点。如果叶子节点只能增加少许信息,则可以删除该节点,将它并入到其他叶子节点中。后面章节中会学习另一个决策树构造算法CART

本章使用的算法称为ID3,它是一个好的算法但并不完美。ID3算法无法直接处理数值型数据,尽管我们可以通过量化的方法将数值型数据转化为标称型数值,但是如果存在太多的特征划分,ID3算法仍会面临其他问题。

(1)相同根目录下,在trees.py文件中调用treePlotter.py文件中的函数:
方法一:

import treePlotter

def main():
    lensesTree = example()
    treePlotter.createPlot(lensesTree)

if __name__ == '__main__':
    main()

方法二:

from treePlotter import createPlot

def main():
    lensesTree = example()
    createPlot(lensesTree)

if __name__ == '__main__':
    main()

(2)ID3算法
ID3, 即Iterative Dichotomiser 3,迭代二叉树3代,是Ross Quinlan发明的一种决策树算法。它是基于奥卡姆剃刀原理的,即用尽量用较少的东西做更多的事。

在信息论中,期望信息越小,那么信息增益就越大,从而纯度就越高。ID3算法的核心思想就是以信息增益来度量属性的选择,选择分裂后信息增益最大的属性进行分裂。该算法采用自顶向下的贪婪搜索遍历可能的决策空间。

总结
决策树分类器就像带有终止块的流程图,终止块表示分类结果。
处理数据集时,首先需要测量集合中的数据熵,然后寻找最优方案以划分数据集,直到数据集中的所有数据属于同一分类。

1、 ID3算法可以用于划分标称型数据集。构建决策树时,我们通常采用递归的方法将数据集转化为决策树。
2、一般我们并不构造新的数据结构,而是使用Python语言内嵌的数据结构字典存储树节点信息。
3、使用matplotlib的注解功能,可以将存储的树结构转化为容易理解的图形。
4、对于过度匹配的问题,可以通过裁剪树的手段来消除。
5、还有其他的决策树算法,最流行的树C4.5和CART。无论是ID3还是C4.5最好在小数据集上使用,决策树分类一般只试用于小数据。当属性取值很多时最好选择C4.5算法,ID3得出的效果会非常差。

猜你喜欢

转载自blog.csdn.net/wsf09/article/details/87865679