讀古今文學網 > 機器學習實戰 > 3.3 測試和存儲分類器 >

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.close

def 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-近鄰算法就無法持久化分類器。我們可以預先提煉並存儲數據集中包含的知識信息,在需要對事物進行分類時再使用這些知識。下節我們將使用這些工具處理隱形眼鏡數據集。