公號:碼農充電站pro
主頁:https://codeshellme.github.iohtml
上篇文章介紹了決策樹算法的理論篇,本節來介紹如何用決策樹解決實際問題。node
決策樹是經常使用的機器學習算法之一,決策樹模型的決策過程很是相似人類作判斷的過程,比較好理解。python
決策樹可用於不少場景,好比金融風險評估,房屋價格評估,醫療輔助診斷等。git
要使用決策樹算法,咱們先來介紹一下 scikit-learn 。github
scikit-learn 是基於Python 的一個機器學習庫,簡稱爲sklearn,其中實現了不少機器學習算法。咱們能夠經過sklearn 官方手冊 來學習如何使用它。算法
sklearn 自帶數據集shell
要進行數據挖掘,首先得有數據。sklearn 庫的datasets 模塊中自帶了一些數據集,能夠方便咱們使用。數組
sklearn 自帶數據集:dom
冒號後邊是每一個數據集對應的函數,可使用相應的函數來導入數據。機器學習
好比咱們用以下代碼導入鳶尾花數據集:
from sklearn.datasets import load_iris iris = load_iris()
使用dir(iris)
查看iris
中包含哪些屬性:
>>> dir(iris) ['DESCR', 'data', 'feature_names', 'filename', 'frame', 'target', 'target_names']
sklearn 庫的tree 模塊實現了兩種決策樹:
sklearn.tree.DecisionTreeClassifier
類:分類樹的實現。sklearn.tree.DecisionTreeRegressor
類:迴歸樹的實現。分類樹用於預測離散型數值,迴歸樹用於預測連續性數值。
sklearn 只實現了預剪枝,沒有實現後剪枝。
DecisionTreeClassifier
類的構造函數
def __init__(self, *, criterion="gini", splitter="best", max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0., max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0., min_impurity_split=None, class_weight=None, ccp_alpha=0.0):
DecisionTreeClassifier
類的構造函數中的criterion
參數有2 個取值:
entropy
:表示使用 ID3 算法(信息增益)構造決策樹。gini
:表示使用CART 算法(基尼係數)構造決策樹,爲默認值。其它參數可以使用默認值。
sklearn 庫中的決策分類樹只實現了ID3 算法和CART 算法。
DecisionTreeRegressor
類的構造函數
def __init__(self, *, criterion="mse", splitter="best", max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0., max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0., min_impurity_split=None, ccp_alpha=0.0):
DecisionTreeRegressor
類的構造函數中的criterion
參數有4 個取值:
mse
:表示均方偏差算法,爲默認值。friedman_mse
:表示費爾德曼均方偏差算法。mae
:表示平均偏差算法。poisson
:表示泊松誤差算法。其它參數可以使用默認值。
咱們使用 sklearn.datasets
模塊中自帶的鳶尾花數據集 構造一顆決策樹。
鳶尾花數據集目的是經過花瓣的長度和寬度,及花萼的長度和寬度,預測出花的品種。
這個數據集包含150條數據,將鳶尾花分紅了三類(每類是50條數據),分別是:
setosa
,用數字0
表示。versicolor
,用數字1
表示。virginica
,用數字2
表示。咱們抽出3 條數據以下:
5.1,3.5,1.4,0.2,0 6.9,3.1,4.9,1.5,1 5.9,3.0,5.1,1.8,2
數據的含義:
特徵值
,最後1列稱爲目標值
。咱們的目的就是用特徵值預測出目標值。將上面3 條數據,用表格表示就是:
花萼長度 | 花萼寬度 | 花瓣長度 | 花瓣寬度 | 花的品種 |
---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | 0 |
6.9 | 3.1 | 4.9 | 1.5 | 1 |
5.9 | 3.0 | 5.1 | 1.8 | 2 |
首先導入必要的類和函數:
from sklearn.tree import DecisionTreeClassifier from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score
其中:
DecisionTreeClassifier
類用於構造決策樹。load_iris()
函數用於導入數據。train_test_split()
函數用於將數據集拆分紅訓練集與測試集。accuracy_score()
函數用於爲模型的準確度進行評分。導入數據集:
iris = load_iris() # 準備數據集 features = iris.data # 獲取特徵集 labels = iris.target # 獲取目標集
將數據分紅訓練集和測試集,訓練集用於訓練模型,測試集用於測試模型的準確度。
train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size=0.33, random_state=0)
咱們向train_test_split()
函數中傳遞了4 個參數,分別是:
該函數返回4 個值,分別是:
接下來構造決策樹:
# 用CART 算法構建分類樹(你也可使用ID3 算法構建) clf = DecisionTreeClassifier(criterion='gini') # 用訓練集擬合構造CART分類樹 clf = clf.fit(train_features, train_labels)
上面兩句代碼已經在註釋中說明,最終咱們獲得了決策樹clf
(classifier
的縮寫)。
用clf
預測測試集數據,test_predict
爲預測結果:
test_predict = clf.predict(test_features)
計算預測結果的準確率:
score = accuracy_score(test_labels, test_predict) score2 = clf.score(test_features, test_labels) print(score, score2)
最終得出,sorce
和 score2
都爲 0.96,意思就是咱們訓練出的模型的準確率爲96%。
函數accuracy_score()
和 clf.score()
均可以計算模型的準確率,但注意這兩個函數的參數不一樣。
爲了清楚的知道,咱們構造出的這個決策樹cfl
究竟是什麼樣子,可以使用 graphviz
模塊將決策樹畫出來。
代碼以下:
from sklearn.tree import export_graphviz import graphviz # clf 爲決策樹對象 dot_data = export_graphviz(clf) graph = graphviz.Source(dot_data) # 生成 Source.gv.pdf 文件,並打開 graph.view()
爲了畫出決策樹,除了須要安裝相應的 Python 模塊外,還須要安裝Graphviz 軟件。
由上面的代碼,咱們獲得的決策樹圖以下:
咱們以根節點爲例,來解釋一下每一個方框裏的四行數據(葉子節點是三行數據)都是什麼意思。
四行數據所表明的含義:
X[3]<=0.75
:鳶尾花數據集的特徵集有4 個屬性,因此對於X[n]
中的n
的取值範圍爲0<=n<=3
,X[0]
表示第1個屬性,X[3]
表示第4 個屬性。X[3]<=0.75
的意思就是當X[3]
屬性的值小於等於0.75 的時候,走左子樹,不然走右子樹。
gini=0.666
,表示當前的gini
係數值。samples=100
,samples
表示當前的樣本數。咱們知道整個數據集有150 條數據,咱們選擇了0.33 百分比做爲測試集,那麼訓練集的數據就佔0.67,也就是100 條數據。根節點包含全部樣本集,因此根節點的samples
值爲100。value
:value
表示屬於該節點的每一個類別的樣本個數,value
是一個數組,數組中的元素之和爲samples
值。咱們知道該數據集的目標集中共有3 個類別,分別爲:setosa
,versicolor
和 virginica
。因此:
value[0]
表示該節點中setosa
種類的數據量,即34。value[1]
表示該節點中versicolor
種類的數據量,即31。value[2]
表示該節點中virginica
種類的數據量,即35。咱們構造出來的決策樹對象clf
中,有一個feature_importances_
屬性,以下:
>>> clf.feature_importances_ array([0, 0.02252929, 0.88894654, 0.08852417])
clf.feature_importances_
是一個數組類型,裏邊的元素分別表明對應特徵的重要性,全部元素之和爲1
。元素的值越大,則對應的特徵越重要。
因此,從這個數組,咱們能夠知道,四個特徵的重要性排序爲:
咱們可使用下面這個函數,將該數組畫成柱狀圖:
import matplotlib.pyplot as plt import numpy as np # mode 是咱們訓練出的模型,即決策樹對象 # data 是原始數據集 def plot_feature_importances(model, data): n_features = data.data.shape[1] plt.barh(range(n_features), model.feature_importances_, align='center') plt.yticks(np.arange(n_features), data.feature_names) plt.xlabel("Feature importance") plt.ylabel("Feature") plt.show() plot_feature_importances(clf, iris)
下圖是用plot_feature_importances()
函數生成的柱狀圖(紅字是我添加的
),從圖中能夠清楚的看出每一個特種的重要性。
從該圖中也能夠看出,爲何決策樹的根節點的特徵是X[3]
。
咱們已經用鳶尾花數據集構造了一棵分類樹,下面咱們用波士頓房價數據集構造一顆迴歸樹。
來看幾條數據:
首先,咱們認爲房價是有不少因素影響的,在這個數據集中,影響房價的因素有13 個:
數據中的最後一列的數據是房價:
由於房價是一個連續值,而不是離散值,因此須要構建一棵迴歸樹。
下面對數據進行建模,構造迴歸樹使用DecisionTreeRegressor
類:
from sklearn.tree import DecisionTreeRegressor from sklearn.datasets import load_boston from sklearn.model_selection import train_test_split from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error # 準備數據集 boston = load_boston() # 獲取特徵集和房價 features = boston.data prices = boston.target # 隨機抽取33% 的數據做爲測試集,其他爲訓練集 train_features, test_features, train_price, test_price = train_test_split(features, prices, test_size=0.33) # 建立CART迴歸樹 dtr = DecisionTreeRegressor() # 擬合構造CART迴歸樹 dtr.fit(train_features, train_price) # 預測測試集中的房價 predict_price = dtr.predict(test_features) # 測試集的結果評價 print('迴歸樹準確率:', dtr.score(test_features, test_price)) print('迴歸樹r2_score:', r2_score(test_price, predict_price)) print('迴歸樹二乘誤差均值:', mean_squared_error(test_price, predict_price)) print('迴歸樹絕對值誤差均值:', mean_absolute_error(test_price, predict_price))
最後四行代碼是計算模型的準確度,這裏用了4 種方法,輸出以下:
迴歸樹準確率: 0.7030833400349499 迴歸樹r2_score: 0.7030833400349499 迴歸樹二乘誤差均值: 28.40730538922156 迴歸樹絕對值誤差均值: 3.6275449101796404
須要注意,迴歸樹與分類樹預測準確度的方法不同:
dtr.score
():與分類樹相似,很少說。r2_score
():表示R 方偏差,結果與 dtr.score
() 同樣,取值範圍是0 到1。mean_squared_error
():表示均方偏差,數值越小,表明準確度越高。mean_absolute_error
():表示平均絕對偏差,數值越小,表明準確度越高。能夠用下面代碼,將構建好的決策樹畫成圖:
from sklearn.tree import export_graphviz import graphviz # dtr 爲決策樹對象 dot_data = export_graphviz(dtr) graph = graphviz.Source(dot_data) # 生成 Source.gv.pdf 文件,並打開 graph.view()
這棵二叉樹比較大,你能夠本身生成看一下。
再來執行下面代碼,看下特徵重要性:
import matplotlib.pyplot as plt import numpy as np # mode 是咱們訓練出的模型,即決策樹對象 # data 是原始數據集 def plot_feature_importances(model, data): n_features = data.data.shape[1] plt.barh(range(n_features), model.feature_importances_, align='center') plt.yticks(np.arange(n_features), data.feature_names) plt.xlabel("Feature importance") plt.ylabel("Feature") plt.show() plot_feature_importances(dtr, boston)
從生成的柱狀圖,能夠看到LSTAT 對房價的影響最大:
本文中用到的數據是sklearn 中自帶的數據,數據完整性比較好,因此咱們沒有對數據進行預處理。實際項目中,可能數據比較雜亂,因此在構建模型以前,先要對數據進行預處理。
要對數據有個清楚的認識,每一個特徵的含義。若是有特別明顯的特徵對咱們要預測的目標集沒有影響,則要將這些數據從訓練集中刪除。
若是某些特徵有數據缺失,須要對數據進行補全,可使用著名的 Pandas 模塊對數據進行預處理。若是某特徵的數據缺失嚴重,則應該將其從訓練集中刪除。對於須要補全的值:
若是某些特徵的值是字符串類型數據,則須要將這些數據轉爲數值型數據。
sklearn.feature_extraction
模塊中的 DictVectorizer
類來處理(轉換成數字0/1
)。在測試模型的準確率時,若是測試集中只有特徵值沒有目標值,就很差對測試結果進行驗證。此時有兩種方法來測試模型準確率:
train_test_split
() 函數將原始數據集(含有目標集)拆分紅訓練集和測試集。sklearn.model_selection
模塊中的 cross_val_score
函數進行K 折交叉驗證來計算準確率。K 折交叉驗證原理很簡單:
- 將數據集平均分紅K 個等份,
K
通常取10
。- 使用K 份中的1 份做爲測試數據,其他爲訓練數據,而後進行準確率計算。
- 進行屢次以上步驟,求平均值。
本篇文章介紹瞭如何用決策樹來處理實際問題。主要介紹瞭如下知識點:
sklearn
是基於 Python
的一個機器學習庫。sklearn.datasets
模塊中有一些自帶數據集供咱們使用。sklearn.tree
中的兩個類來構建分類樹和迴歸樹:
DecisionTreeClassifier
類:構造決策分類樹,用於預測離散值。DecisionTreeRegressor
類:構造決策迴歸樹,用於預測連續值。criterion
參數的含義。train_test_split
() 函數用於拆分數據集。o.fit
() 用於擬合決策樹。(o
表示決策樹對象)o.predict
() 用於預測數據。o.score
() 用於給模型的準確度評分。accuracy_score
() 函數用於給分類樹模型評分。r2_score
() 函數用於給迴歸樹模型評分。mean_squared_error
() 函數用於給迴歸樹模型評分。mean_absolute_error
() 函數用於給迴歸樹模型評分。(本節完。)
推薦閱讀:
歡迎關注做者公衆號,獲取更多技術乾貨。