分類演算法之決策樹(應用篇)
起步
在理論篇我們介紹了決策樹的構建和一些關於熵的計算方法,這篇文章將根據一個例子,用代碼上來實現決策樹。
實驗環境
- 操作系統: win10 64
- 編程語言: Python3.6
用到的第三方模塊有:
numpy (1.12.1+mkl)scikit-learn (0.19.1)
數據源
為了方便理解和架設,我們用理論篇中買電腦的例子:
將這些記錄保存成 csv
文件:
RID,age,income,student,credit_rating,class:buys_computer1,youth,hight,no,fair,no 2,youth,hight,no,excellent,no 3,middle_aged,hight,no,fair,yes4,senior,medium,no,fair,yes5,senior,low,yes,fair,yes6,senior,low,yes,excellent,no 7,middle_aged,low,yes,excellent,yes8,youth,medium,no,fair,no 9,youth,low,yes,fair,yes10,senior,medium,yes,fair,yes11,youth,medium,yes,excellent,yes12,middle_aged,medium,no,excellent,yes13,middle_aged,hight,yes,fair,yes14,senior,medium,no,excellent,no
這些數據就是這次應用的數據源。
數據整理
可以利用python標準庫中 csv
來對這個數據源進行讀取,要對原始數據集進行整理,隨機變數放在一個數組,分類結果放在另一個數組,形如:
future_list = [ { "age" : "youth", "income": "hight", ... } ...]answer_list = ["no", "no", "yes", ...]
按照這個思路我們構造一下:
data_file = open("computer_buy.csv", "r")reader = csv.reader(data_file)headers = next(reader)future_list = []label_list = []for row in reader: label_list.append(row[-1]) row_dict = {} for i in range(1, len(row) -1): row_dict[ headers[i] ] = row[i] future_list.append(row_dict)data_file.close()隨機變數向量化
在 sklearn
提供的庫中,對輸入的特徵有一定的要求,所有特徵和分類都要是數值型的值,不能是例子中的類別的值。
怎麼轉化呢?
比方說 age
這個特徵,它有三個值: youth
, middle_aged
, senior
。有一條記錄的 age=youth
針對這個特徵我們就變成:
那麼第一條記錄 youth,hight,no,fair
轉化為:
特徵向量化
from sklearn.feature_extraction import DictVectorizerdummy_x = vec.fit_transform(future_list).toarray()print("dummy_x:", dummy_x)print("vec.get_feature_names()", vec.get_feature_names())
分類結果向量化
from sklearn import preprocessinglb = preprocessing.LabelBinarizer()dummy_y = lb.fit_transform(label_list)
構造決策樹
在 sklearn
中提供了多種決策樹構建方法,這邊需要向其表明,是依據 信息增益
的方式來構造決策樹的,因此需要傳入一個參數 criterion=entropy
:
from sklearn import tree# 構造決策樹clf = tree.DecisionTreeClassifier(criterion=entropy)clf.fit(dummy_x, dummy_y)print("clf: ", clf)
保存模型
將訓練好的模型保存到文件里去:
# 保存模型 with open("result.dot", "w") as f: tree.export_graphviz(clf, feature_names=vec.get_feature_names(), out_file=f)
測試數據
接下來就是給它隨機變數,讓決策樹來進行分類。我們修改第一條記錄來進行測試:
# 測試數據first_row = dummy_x[0, :]new_row = list(first_row)new_row[0] = 1new_row[2] = 0predict = clf.predict([new_row])print("predict:", predict) # output: [1]
模型可視化
可視化用到了 Graphviz
軟體,可以到官網:http://www.graphviz.org/ 下載,我下載的是 zip 文件,解壓後將目錄加到環境變數中去。
轉化 dot
文件至 pdf
可視化決策樹的命令:
dot -Tpdf result.dot -o outpu.pdf
得到一個pdf文件,打開可以看到決策樹:
附錄
本次應用的全部代碼:
# coding: utf-8 import csvfrom sklearn.feature_extraction import DictVectorizerfrom sklearn import preprocessingfrom sklearn import treedata_file = open("computer_buy.csv", "r")reader = csv.reader(data_file)headers = next(reader)future_list = []label_list = []for row in reader: label_list.append(row[-1]) row_dict = {} for i in range(1, len(row) -1): row_dict[ headers[i] ] = row[i] future_list.append(row_dict)data_file.close()# 向量化 xvec = DictVectorizer()dummy_x = vec.fit_transform(future_list).toarray()print("dummy_x:", dummy_x)print("vec.get_feature_names()", vec.get_feature_names())# 向量化 ylb = preprocessing.LabelBinarizer()dummy_y = lb.fit_transform(label_list)# 構造決策樹clf = tree.DecisionTreeClassifier(criterion=entropy)clf.fit(dummy_x, dummy_y)print("clf: ", clf)# 保存模型 with open("result.dot", "w") as f: tree.export_graphviz(clf, feature_names=vec.get_feature_names(), out_file=f)# 測試數據first_row = dummy_x[0, :]new_row = list(first_row)new_row[0] = 1new_row[2] = 0predict = clf.predict([new_row])print("predict:", predict)
推薦閱讀:
※機器學習演算法實踐-決策樹(Decision Tree)
※quest 法求差別閾限的思路?
※神經網路能否代替決策樹演算法?