機器學習 - 決策樹


決策樹(Decision Tree)

在本章中,我們將向您展示如何制作“決策樹”。決策樹是一種流程圖,可以幫助您根據以前的經驗進行決策。

在這個例子中,一個人將嘗試決定他/她是否應該參加喜劇節目。

幸運的是,我們的例中人物每次在鎮上舉辦喜劇節目時都進行注冊,并注冊一些關于喜劇演員的信息,并且還登記了他/她是否去過。

Age Experience Rank Nationality Go
36 10 9 UK NO
42 12 4 USA NO
23 4 6 N NO
52 4 4 USA NO
43 21 8 USA YES
44 14 5 UK NO
66 3 7 N YES
35 14 9 UK YES
52 13 7 N YES
35 5 9 N YES
24 3 5 USA NO
18 3 7 UK YES
45 9 9 UK YES

現在,基于此數據集,Python 可以創建決策樹,這個決策樹可用于決定是否值得參加任何新的演出。

工作原理

首先,導入所需的模塊,并使用 pandas 讀取數據集:

實例

讀取并打印數據集:

import pandas
from sklearn import tree
import pydotplus
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
import matplotlib.image as pltimg
df = pandas.read_csv("shows.csv")
print(df)

運行實例

如需制作決策樹,所有數據都必須是數字。

我們必須將非數字列 “Nationality” 和 “Go” 轉換為數值。

Pandas 有一個 map() 方法,該方法接受字典,其中包含有關如何轉換值的信息。

{'UK': 0, 'USA': 1, 'N': 2}

表示將值 'UK' 轉換為 0,將 'USA' 轉換為 1,將 'N' 轉換為 2。

實例

將字符串值更改為數值:

d = {'UK': 0, 'USA': 1, 'N': 2}
df['Nationality'] = df['Nationality'].map(d)
d = {'YES': 1, 'NO': 0}
df['Go'] = df['Go'].map(d)
print(df)

運行實例

然后,我們必須將特征列與目標列分開。

特征列是我們嘗試從中預測的列,目標列是具有我們嘗試預測的值的列。

實例

X 是特征列,y 是目標列:

features = ['Age', 'Experience', 'Rank', 'Nationality']
X = df[features]
y = df['Go']
print(X)
print(y)

運行實例

現在,我們可以創建實際的決策樹,使其適合我們的細節,然后在計算機上保存一個 .png 文件:

實例

創建一個決策樹,將其另存為圖像,然后顯示該圖像:

dtree = DecisionTreeClassifier()
dtree = dtree.fit(X, y)
data = tree.export_graphviz(dtree, out_file=None, feature_names=features)
graph = pydotplus.graph_from_dot_data(data)
graph.write_png('mydecisiontree.png')
img=pltimg.imread('mydecisiontree.png')
imgplot = plt.imshow(img)
plt.show()

運行實例

結果解釋

決策樹使用您先前的決策來計算您是否愿意去看喜劇演員的幾率。

讓我們閱讀決策樹的不同方面:


Rank

Rank <= 6.5 表示排名在 6.5 以下的喜劇演員將遵循 True 箭頭(向左),其余的則遵循 False 箭頭(向右)。

gini = 0.497 表示分割的質量,并且始終是 0.0 到 0.5 之間的數字,其中 0.0 表示所有樣本均得到相同的結果,而 0.5 表示分割完全在中間進行。

samples = 13 表示在決策的這一點上還剩下 13 位喜劇演員,因為這是第一步,所以他們全部都是喜劇演員。

value = [6, 7] 表示在這 13 位喜劇演員中,有 6 位將獲得 "NO",而 7 位將獲得 "GO"。

Gini

分割樣本的方法有很多,我們在本教程中使用 GINI 方法。

基尼方法使用以下公式:

Gini = 1 - (x/n)2 - (y/n)2

其中,x 是肯定答案的數量 ("GO"),n 是樣本數量,y 是否定答案的數量 ("NO"),使用以下公式進行計算:

1 - (7 / 13)2 - (6 / 13)2 = 0.497


下一步包含兩個框,其中一個框用于喜劇演員,其 'Rank' 為 6.5 或更低,其余為一個框。

True - 5 名喜劇演員在這里結束:

gini = 0.0 表示所有樣本均得到相同的結果。

samples = 5 表示該分支中還剩下 5 位喜劇演員(5 位的等級為 6.5 或更低的喜劇演員)。

value = [5, 0] 表示 5 得到 "NO" 而 0 得到 "GO"。

False - 8 位戲劇演員繼續:

Nationality(國籍)

Nationality <= 0.5 表示國籍值小于 0.5 的喜劇演員將遵循左箭頭(這表示來自英國的所有人),其余的將遵循右箭頭。

gini = 0.219 意味著大約 22% 的樣本將朝一個方向移動。

samples = 8 表示該分支中還剩下 8 個喜劇演員(8 個喜劇演員的等級高于 6.5)。

value = [1, 7] 表示在這 8 位喜劇演員中,1 位將獲得 "NO",而 7 位將獲得 "GO"。


True - 4 名戲劇演員繼續:

Age(年齡)

Age <= 35.5 表示年齡在 35.5 歲或以下的喜劇演員將遵循左箭頭,其余的將遵循右箭頭。

gini = 0.375 意味著大約 37.5% 的樣本將朝一個方向移動。

samples = 4 表示該分支中還剩下 4 位喜劇演員(來自英國的 4 位喜劇演員)。

value = [1, 3] 表示在這 4 位喜劇演員中,1 位將獲得 "NO",而 3 位將獲得 "GO"。

False - 4 名喜劇演員到這里結束:

gini = 0.0 表示所有樣本都得到相同的結果。

samples = 4 表示該分支中還剩下 4 位喜劇演員(來自英國的 4 位喜劇演員)。

value = [0, 4] 表示在這 4 位喜劇演員中,0 將獲得 "NO",而 4 將獲得 "GO"。


True - 2 名喜劇演員在這里結束:

gini = 0.0 表示所有樣本都得到相同的結果。

samples = 2 表示該分支中還剩下 2 名喜劇演員(2 名 35.5 歲或更年輕的喜劇演員)。

value = [0, 2] 表示在這 2 位喜劇演員中,0 將獲得 "NO",而 2 將獲得 "GO"。

False - 2 名戲劇演員繼續:

Experience(經驗)

Experience <= 9.5 表示具有 9.5 年或以上經驗的喜劇演員將遵循左側的箭頭,其余的將遵循右側的箭頭。

gini = 0.5 表示 50% 的樣本將朝一個方向移動。

samples = 2 表示此分支中還剩下 2 個喜劇演員(2 個年齡超過 35.5 的喜劇演員)。

value = [1, 1] 表示這兩個喜劇演員中,1 將獲得 "NO",而 1 將獲得 "GO"。


True - 1 名喜劇演員在這里結束:

gini = 0.0 表示所有樣本都得到相同的結果。

samples = 1 表示此分支中還剩下 1 名喜劇演員(1 名具有 9.5 年或以下經驗的喜劇演員)。

value = [0, 1] 表示 0 表示 "NO",1 表示 "GO"。

False - 1 名喜劇演員到這里為止:

gini = 0.0 表示所有樣本都得到相同的結果。

samples = 1 表示此分支中還剩下 1 位喜劇演員(其中 1 位具有超過 9.5 年經驗的喜劇演員)。

value = [1, 0] 表示 1 表示 "NO",0 表示 "GO"。

預測值

我們可以使用決策樹來預測新值。

例如:我是否應該去看一個由 40 歲的美國喜劇演員主演的節目,該喜劇演員有 10 年的經驗,喜劇排名為 7?

實例

使用 predict() 方法來預測新值:

print(dtree.predict([[40, 10, 7, 1]]))

運行實例

實例

如果喜劇等級為 6,答案是什么?

print(dtree.predict([[40, 10, 6, 1]]))

運行實例

不同的結果

如果運行足夠多次,即使您輸入的數據相同,決策樹也會為您提供不同的結果。

這是因為決策樹無法給我們 100% 的肯定答案。它基于結果的可能性,答案會有所不同。