機器學習(五):通俗易懂決策樹與隨機森林及代碼實踐

與SVM同樣,決策樹是通用的機器學習算法。隨機森林,顧名思義,將決策樹分類器集成到一塊兒就造成了更強大的機器學習算法。它們都是很基礎但很強大的機器學習工具,雖然咱們如今有更先進的算法工具來訓練模型,但決策樹與隨機森林因其簡單靈活依然廣受喜好,建議你們學習。算法

1、決策樹

1.1 什麼是決策樹

咱們能夠把決策樹想象成IF/ELSE判別式深度嵌套的二叉樹形結構。以咱們在《機器學習(三):理解邏輯迴歸及二分類、多分類代碼實踐》所舉的鳶尾花數據集爲例。 dom

咱們曾用seaborn繪製花瓣長度和寬度特徵對應鳶尾花種類的散點圖,以下: 機器學習

image

當花瓣長度小於2.45則爲山鳶尾(setosa),剩下的咱們判斷花瓣寬度小於1.75則爲變色鳶尾(versicolor)剩下的爲維吉尼亞鳶尾(virginica)。那麼我用導圖畫一下這種判別式的樹形結構以下: 工具

image

所以,當咱們面對任意鳶尾花的樣本,咱們只須要從根節點到葉子節點遍歷決策樹,就能夠獲得鳶尾花的分類結論。 學習

這就是決策樹。ui

1.2 決策樹代碼實踐

咱們導入數據集(你們不用在乎這個域名),並訓練模型:編碼

import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier

#引入數據集
df = pd.read_csv('https://blog.caiyongji.com/assets/iris.csv')

#決策樹模型
X = df[['petal_length','petal_width']].to_numpy() 
y = df['species']
tree_clf = DecisionTreeClassifier(max_depth=2, random_state=42)
tree_clf.fit(X, y)

咱們來可視化決策樹:spa

import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(12,8))
plot_tree(tree_clf,filled=True);

image

如上圖,咱們能夠看到根節點總實例數爲150時,由value = [50, 50, 50]可知,實際樣本分類爲50個山鳶尾花實例、50個變色鳶尾花實例、50個維吉尼亞鳶尾花實例。咱們再看最末尾右側的葉子節點(紫色),由value = [0, 1, 45]可知,實際樣本分類爲0個山鳶尾花實例、1個變色鳶尾花實例、45個維吉尼亞鳶尾花實例。 rest

那麼gini = 0.043是什麼意思呢?code

1.3 基尼不純度

顯然咱們進行分類時,每個類別實際混入其餘類的數量越少分類就越純粹,這種純度咱們經過以下公式表示:

$$ G_i = 1 - \sum_{k=1}^{n}{p^2_{i,k}} $$

咱們計算維吉尼亞鳶尾花節點(紫色)的gini係數1-((0/46)**2 + (1/46)**2 + (45/46)**2) = 0.04253308128544431 ≈0.043

咱們使用基尼(gini)不純度來衡量決策樹的好壞。那麼咱們經過最小化基尼不純度min(gini)來求解X[0],X[1](即,花瓣長度寬度特徵)邊界的過程就決策樹模型的訓練過程。

2、隨機森林

2.1 大數定理與隨機森林

其實隨機森林很簡單,咱們把決策樹隨機組合在一塊兒就是隨機森林,它比單個的決策樹更有效。

憑什麼?

假設咱們有一枚不均勻的硬幣,投擲它有51%的機率爲正面,49%的機率爲背面,那麼當投擲1000次時,「大多數爲正面"這件事的機率爲75%。投擲10000次時,「大多數爲正面"這件事的機率爲97%。這就是大數定理,它體現的是羣體智慧。質量不夠,數量來湊。由此可知,當前尋找最佳模型的方法不止是技巧的比拼,也一樣是算力的比拼。

2.2 隨機森林代碼實踐

2.2.1. 引入新的數據集

添加引用:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

導入數據集(你們不用在乎這個域名):

df = pd.read_csv("https://blog.caiyongji.com/assets/penguins_size.csv")
df = df.dropna()
df.head()
species island culmen_length_mm culmen_depth_mm flipper_length_mm body_mass_g sex
Adelie Torgersen 39.1 18.7 181 3750 MALE
Adelie Torgersen 39.5 17.4 186 3800 FEMALE
Adelie Torgersen 40.3 18 195 3250 FEMALE
Adelie Torgersen 36.7 19.3 193 3450 FEMALE
Adelie Torgersen 39.3 20.6 190 3650 MALE

企鵝數據集包含特徵和標籤以下:

  • 特徵:所在島嶼island、鳥喙長度culmen_length_mm、鳥喙深度culmen_depth_mm、腳蹼長度flipper_length_mm、體重(g)、性別
  • 標籤:物種species:Chinstrap, Adélie, or Gentoo

2.2.2 觀察數據

sns.pairplot(df,hue='species')

咱們經過pairplot方法繪製特徵兩兩之間的對應關係。

image

2.2.3 預處理

X = pd.get_dummies(df.drop('species',axis=1),drop_first=True)
y = df['species']
X.head()

注意,get_dummies方法將字符串屬性的列轉換成了數字屬性的多個列。如,島嶼island和性別sex分別轉換成了island_Dream、island_Torgersen和sex_FEMALE、sex_MALE。這是一種獨熱編碼的關係,好比sex_FEMALE與sex_MALE屬性獨立,在空間內沒有向量關係。

culmen_length_mm culmen_depth_mm flipper_length_mm body_mass_g island_Dream island_Torgersen sex_FEMALE sex_MALE
39.1 18.7 181 3750 0 1 0 1
39.5 17.4 186 3800 0 1 1 0
40.3 18 195 3250 0 1 1 0
36.7 19.3 193 3450 0 1 1 0
39.3 20.6 190 3650 0 1 0 1

2.2.4 訓練數據

#訓練
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=101)
model = RandomForestClassifier(n_estimators=10,max_features='auto',random_state=101)
model.fit(X_train,y_train)

#預測
from sklearn.metrics import accuracy_score
preds = model.predict(X_test)
accuracy_score(y_test,preds)

使用隨機森林分類器RandomForestClassifier訓練,獲得模型精度爲97%。

2.2.5 網格搜索與AdaBoost提高法(拓展)

咱們使用AdaBoostClassifier分類器集成數個決策樹分類器DecisionTreeClassifier進行分類。並使用網格搜索方法GridSearchCV來尋找最優參數。

from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import AdaBoostClassifier

ada_clf = AdaBoostClassifier(DecisionTreeClassifier(max_depth=1), random_state=101)
ada_clf.fit(X_train, y_train)
param_grid = {'n_estimators':[10,15,20,25,30,35,40], 'learning_rate':[0.01,0.1,0.5,1], 'algorithm':['SAMME', 'SAMME.R']}
grid = GridSearchCV(ada_clf,param_grid)
grid.fit(X_train,y_train)
print("grid.best_params_ = ",grid.best_params_,", grid.best_score_ =" ,grid.best_score_)

這是一種集成學習技術,輸出以下:

grid.best_params_ =  {'algorithm': 'SAMME', 'learning_rate': 1, 'n_estimators': 20} , grid.best_score_ = 0.9914893617021276

總結

二叉樹是決策樹的核心邏輯,隨機森林是大數定理的應用實現。這種基本思想即便不用數學公式也能夠很容易的解釋清楚,這也是我作這個系列課程(文章)的主要風格特色。我認爲,數學是對現實世界的解釋,但現實世界並不能被數學徹底解釋。像谷歌AI主管Laurence Moroney所說:

不少人懼怕數學,懼怕大量的深度的微積分知識。其實咱們能夠實現編碼而不考慮數學,咱們可使用TensorFlow中高(層)級的API,來解決問題,如天然語言處理,圖像分類,計算機視覺序列模型等而無需理解深入的數學。就像你使用JAVA卻不必定非要掌握它是如何編譯的。將來,AI只是每一個開發者技術棧(toolbox)中的一部分,就像HTML, CSS, JAVA。

但願那一天能夠早點到來吧……

往期文章:

相關文章
相關標籤/搜索