分類演算法之決策樹(應用篇)

起步

在理論篇我們介紹了決策樹的構建和一些關於熵的計算方法,這篇文章將根據一個例子,用代碼上來實現決策樹。

實驗環境

  • 操作系統: 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 軟體,可以到官網: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 法求差別閾限的思路?
神經網路能否代替決策樹演算法?

TAG:决策树 | 机器学习 |