首页 » 机器学习实战 » 机器学习实战全文在线阅读

《机器学习实战》3.3 测试和存储分类器

关灯直达底部

本书第一部分主要讲解机器学习的分类算法,然而到目前为止,本章学习的主要内容是如何从原始数据集中创建决策树,并使用Python函数库绘制树形图,方便我们了解数据的真实含义,下面我们将把重点转移到如何利用决策树执行数据分类上。

本节我们将使用决策树构建分类器,以及实际应用中如何存储分类器。下一节我们将在真实数据上使用决策树分类算法,验证它是否可以正确预测出患者应该使用的隐形眼镜类型。

3.3.1 测试算法:使用决策树执行分类

依靠训练数据构造了决策树之后,我们可以将它用于实际数据的分类。在执行数据分类时,需要决策树以及用于构造树的标签向量。然后,程序比较测试数据与决策树上的数值,递归执行该过程直到进入叶子节点;最后将测试数据定义为叶子节点所属的类型。

为了验证算法的实际效果,打开文本编辑器,将程序清单3-8包含的代码添加到文件trees.py中。

程序清单3-8 使用决策树的分类函数

def classify(inputTree,featLabels,testVec):    firstStr = inputTree.keys[0]    secondDict = inputTree[firstStr]    #❶将标签字符串转换为索引    featIndex = featLabels.index(firstStr)    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  

程序清单3-8定义的函数也是一个递归函数,在存储带有特征的数据会面临一个问题:程序无法确定特征在数据集中的位置,例如前面例子的第一个用于划分数据集的特征是no surfacing属性,但是在实际数据集中该属性存储在哪个位置?是第一个属性还是第二个属性?特征标签列表将帮助程序处理这个问题。使用index方法查找当前列表中第一个匹配firstStr变量的元素❶。然后代码递归遍历整棵树,比较testVec变量中的值与树节点的值,如果到达叶子节点,则返回当前节点的分类标签。

将程序清单3-8包含的代码添加到文件trees.py之后,打开Python命令提示符,输入下列命令:

>>> myDat,labels=trees.createDataSet>>> labels[/'no surfacing/', /'flippers/']>>> myTree=treePlotter.retrieveTree (0)>>> myTree{/'no surfacing/': {0: /'no/', 1: {/'flippers/': {0: /'no/', 1: /'yes/'}}}}>>> trees.classify(myTree,labels,[1,0])/'no/'>>> trees.classify(myTree,labels,[1,1])/'yes/'     

与图3-6比较上述输出结果。第一节点名为no surfacing,它有两个子节点:一个是名字为0的叶子节点,类标签为no;另一个是名为flippers的判断节点,此处进入递归调用,flippers节点有两个子节点。以前绘制的树形图和此处代表树的数据结构完全相同。

现在我们已经创建了使用决策树的分类器,但是每次使用分类器时,必须重新构造决策树,下一节我们将介绍如何在硬盘上存储决策树分类器。

3.3.2 使用算法:决策树的存储

构造决策树是很耗时的任务,即使处理很小的数据集,如前面的样本数据,也要花费几秒的时间,如果数据集很大,将会耗费很多计算时间。然而用创建好的决策树解决分类问题,则可以很快完成。因此,为了节省计算时间,最好能够在每次执行分类时调用已经构造好的决策树。为了解决这个问题,需要使用Python模块pickle序列化对象,参见程序清单3-9。序列化对象可以在磁盘上保存对象,并在需要的时候读取出来。任何对象都可以执行序列化操作,字典对象也不例外。

程序清单3-9 使用pickle模块存储决策树

def storeTree(in    putTree,filename):    import pickle    fw = open(filename,/'w/')    pickle.dump(inputTree,fw)    fw.closedef grabTree(filename):    import pickle    fr = open(filename)    return pickle.load(fr)     

在Python命令提示符中输入下列命令验证上述代码的效果:

>>> trees.storeTree(myTree,/'classifierStorage.txt/')>>> trees.grabTree(/'classifierStorage.txt/'){/'no surfacing/': {0: /'no/', 1: {/'flippers/': {0: /'no/', 1: /'yes/'}}}}  

通过上面的代码,我们可以将分类器存储在硬盘上,而不用每次对数据分类时重新学习一遍,这也是决策树的优点之一,像第2章介绍了k-近邻算法就无法持久化分类器。我们可以预先提炼并存储数据集中包含的知识信息,在需要对事物进行分类时再使用这些知识。下节我们将使用这些工具处理隐形眼镜数据集。