從小白到大師:Get決策樹的分類與迴歸分析

全文共2573字,預計學習時長10分鐘或更長


從小白到大師:Get決策樹的分類與迴歸分析


一個決策的做出,需要考慮一系列盤根錯節的問題。圖片來源:pexels.com

決策樹是一個通過特徵學習決策規則,用於預測目標的監督機器學習模型。顧名思義,該模型通過提出一系列的問題將數據進行分解,從而做出決策。

下圖示例中用決策樹決定某一天的活動:


從小白到大師:Get決策樹的分類與迴歸分析


根據訓練集的特徵,決策樹模型學習一系列問題來推斷樣本的類標籤。從圖中可以看出,如果可解讀性是重要因素,決策樹模型是個不錯的選擇。

儘管上圖顯示了基於分類目標(分類)的決策樹的概念,但如果目標為實數,它也同樣使用(迴歸)。

本教程將討論如何使用Python的scikit-learn庫構建決策樹模型。其中將包括:

· 決策樹的基本概念

· 決策樹學習算法背後的計算

· 信息增益和不純性度量

· 分類樹

· 迴歸樹

讓我們開始吧!

本教程是參考Next Tech的Python機器學習系列而編寫的。該系列帶領學員通過Python瞭解機器學習和深度學習算法,實現從小白到大師的轉變。它包括一個瀏覽器模式的沙箱環境,裡頭預裝了所有必要的軟件和庫,還包括使用公共數據集的項目。

傳送門:https://c.next.tech/2E7k6Dy


從小白到大師:Get決策樹的分類與迴歸分析

決策樹的基本概念

決策樹是通過遞歸拆分構成的——先從根節點開始(也稱為父節點),將每個節點分為左右子節點。這些節點可以再進一步分裂成其他子節點。

比如說上圖中,根節點為Work to do?,然後根據是否有活動需要完成而分裂為子節點Stay in和Outlook。Outlook節點再繼續分裂為三個子節點。

那麼,如何確定各個節點的最佳分裂點呢?

從根節點開始,數據在能產生最大信息增益 (IG) 的特徵上產生分裂(下文將有更詳細的解釋)。在迭代過程中,該分裂過程將在每個子節點持續重複,直到所有的葉子達到純性為止,即每個節點的樣本都屬於同一類。

在實踐中,可能會形成節點過多的樹,導致過度擬合。因此,一般情況下會通過限制樹的最大深度來進行剪枝。


從小白到大師:Get決策樹的分類與迴歸分析

信息增益最大化

為了在最具信息的特徵分裂節點,首先必須定義一個目標函數,並通過樹學習算法對其進行優化。這裡,目標函數是在各個分裂點處實現最大化的信息增益,定義如下:


從小白到大師:Get決策樹的分類與迴歸分析


方程式中,f為執行分裂的特徵,Dp,Dleft和Dright分別為為父子節點的數據集。I為不純性度量,Np為父節點上樣本的總數,而Nleft和Nright為子節點的樣本數量。

在下面的例子中,本文將更詳細地討論用於分類和迴歸決策樹的不純性度量。但現在,只需理解信息增益簡單來說就是父節點不純性和子節點不純性之和之間的差值,子節點的不純性越低,則信息增益越大。

注意,上面的方程式只適用於二叉決策樹,即每個父節點只分裂為兩個子節點。若一個決策樹包含超過兩個節點,那麼只需求所有節點的不純性的總和即可。


從小白到大師:Get決策樹的分類與迴歸分析

分類樹

首先討論分類決策樹(也稱為分類樹)。下面的例子將使用費雪鳶尾花卉(iris)數據集,機器學習領域的經典數據集。它包含了來自三個不同物種的150朵鳶尾花的屬性,分別是Setosa, Versicolor和Virginica。這些將是本里的目標。本例旨在預測某個鳶尾花屬於哪一種類。將花瓣長度和寬度(以釐米為單位)儲存為列,也稱為該數據集的特徵。

數據集傳送門:https://archive.ics.uci.edu/ml/datasets/iris


首先導入數據集,並將特徵設為x,目標為y:

from sklearn import datasets

iris = datasets.load_iris() # Load iris dataset

X = iris.data[:, [2, 3]] # Assign matrix X
y = iris.target #Assign vector y

使用scikit-learn訓練一個最大深度為4的決策樹。代碼如下:

from sklearn.tree import DecisionTreeClassifier # Import decision tree classifier model

tree = DecisionTreeClassifier(criterion='entropy', # Initialize and fitclassifier
max_depth=4, random_state=1)
tree.fit(X, y)


注意,在這裡criterion被設為‘熵’。該標準被稱為不純性度量(上文有提到)。在分類中,熵是最常見的不純性度量或分裂標準。它的定義如下:


從小白到大師:Get決策樹的分類與迴歸分析


方程式中,p(i|t) 為一個特定節點t中屬於c類樣本的部分。因此,如果一個節點上的所有樣本都屬於同一類,則熵值為0;如果類型均勻分佈,則熵值最大。

為了能更直觀地瞭解熵,在此編寫類1概率範圍 [0,1] 的不純性指數。代碼如下:

import numpy as np
import matplotlib.pyplot as plt

def entropy(p):
return - p * np.log2(p) - (1- p) * np.log2(1 - p)
x = np.arange(0.0, 1.0, 0.01) # Create dummy data
e = [entropy(p) if p != 0 else None for p in x] # Calculate entropy
plt.plot(x, e, label='entropy', color='r') # Plot impurity indices
for y in [0.5, 1.0]:
plt.axhline(y=y, linewidth=1,color='k',linestyle='--')
plt.xlabel('p(i=1)')
plt.ylabel('Impurity Index')
plt.legend()
plt.show()


從小白到大師:Get決策樹的分類與迴歸分析


正如所見,當p(i=1|t)= 1時,熵值為0。而當所有類型均勻分佈,而p(i=1|t)= 0.5時,熵值為1.

現在回到iris的例子,本文將把訓練好的分類樹可視化,然後觀察熵值如何決定每次的分裂。

scikit-learn有一個很好的功能,它允許用戶在訓練之後將決策樹導出為.dot文件,然後可以使用GraphViz之類的軟件將其可視化。除了GraphViz之外,還將使用一個名為pydotplus的Python庫。它具有類似於GraphViz的功能,可將.dot數據文件轉換為決策樹圖像文件。

若要安裝pydotplus和graphviz,可在終端執行下列指令:

pip3 install pydotplus
apt install graphviz


下列代碼可以PNG格式創建本例的決策樹圖像:

from pydotplus.graphviz import graph_from_dot_data
from sklearn.tree import export_graphviz

dot_data = export_graphviz( # Create dot data
tree, filled=True, rounded=True,
class_names=['Setosa','Versicolor','Virginica'],
feature_names=['petallength', 'petal width'],
out_file=None
)

graph = graph_from_dot_data(dot_data) # Create graph from dot data
graph.write_png('tree.png') # Write graphto PNG image


從小白到大師:Get決策樹的分類與迴歸分析

tree.png


從存在圖像文件tree.png的決策樹圖中,可觀察到決策樹根據訓練數據中所進行的分裂點。在根節點處先從150個樣本開始,然後根據花瓣寬度是否≤1.75釐米為分裂點,分成兩個子節點,各有50和100個樣本。在第一次分裂後,可看出左子節點已達純性,只包含setosa類的樣本(熵值 = 0)。而右邊進一步分裂,將樣本分為versicolor和virginica類。

從最終熵值可看出深度為4的決策樹在對花進行分類方面表現得很好。


從小白到大師:Get決策樹的分類與迴歸分析

迴歸樹

迴歸樹的例子本文將使用波士頓房價(Boston Housing)數據集。這是另一個非常流行的數據集,包含了波士頓教區房屋的信息,共有506個樣本和14個屬性。出於簡化和可視化的考量,這裡將只使用兩個屬性,即MEDV(屋主自住房屋價值的中位數,單元為1000美元)為目標,LSTAT(地位較低的人口比率)為特徵。

數據集傳送門:

https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html


首先,將必需的屬性從scikit-learn導入到pandas 數據幀DataFrame中。

import pandas as pd
from sklearn import datasets

boston = datasets.load_boston() # Load Boston Dataset
df = pd.DataFrame(boston.data[:, 12]) # Create DataFrame using only the LSATfeature
df.columns = ['LSTAT']
df['MEDV'] = boston.target # Create new column with the targetMEDV
df.head()


從小白到大師:Get決策樹的分類與迴歸分析


使用scikit-learn中的工具DecisionTreeRegressor來訓練迴歸樹:

from sklearn.tree import DecisionTreeRegressor # Import decision tree regression model

X = df[['LSTAT']].values # Assign matrix X
y = df['MEDV'].values # Assign vector y

sort_idx = X.flatten().argsort() # Sort X and y by ascendingvalues of X
X = X[sort_idx]
y = y[sort_idx]

tree = DecisionTreeRegressor(criterion='mse', # Initialize and fit regressor
max_depth=3)
tree.fit(X, y)


注意,這裡的criterion與分類樹中所用的不同。在分類時,熵作為不純性度量是一個很有用的標準。然而,若將決策樹用於迴歸,則需要一個適合連續變量的不純性度量,因此這裡使用子節點的加權均方誤差 (MSE) 來定義不純性度量:


從小白到大師:Get決策樹的分類與迴歸分析


方程式中,Nt為節點t的訓練樣本數量,Dt為節點t的訓練子集,y(i)為真實目標值,而ŷt為預測目標值(樣本均值):


從小白到大師:Get決策樹的分類與迴歸分析


現在,將MEDV和LSTAT之間的關係進行建模,看看回歸樹的直線擬合是什麼樣的:

plt.figure(figsize=(16, 8))
plt.scatter(X, y, c='steelblue', # Plot actual target againstfeatures
edgecolor='white',s=70)
plt.plot(X, tree.predict(X), # Plot predicted targetagainst features
color='black', lw=2)
plt.xlabel('% lower status of the population [LSTAT]')
plt.ylabel('Price in $1000s [MEDV]')
plt.show()


從小白到大師:Get決策樹的分類與迴歸分析


從上圖可看出,深度為3的決策樹就能反映數據的總體趨勢。

本文討論了決策樹的基本概念,最小化不純性的算法,以及如何創建用於分類和迴歸的決策樹。

在實踐中,為樹選擇合適的深度是很重要的,以避免數據過度擬合或擬合不足。瞭解如何將決策樹結合成整體的隨機森林也是有益的,基於其隨機性,通常比單個決策樹具有更好的泛化性能。這有助於降低模型的方差。此外,它對數據集中的異常值不太敏感,不需要太多的參數調優。

從小白到大師:Get決策樹的分類與迴歸分析

留言 點贊 關注

我們一起分享AI學習與發展的乾貨

歡迎關注全平臺AI垂類自媒體 “讀芯術”

相關推薦

推薦中...