機器學習04:決策樹與隨機森林
決策樹
決策樹是一個基本的非線性有監督分類模型,一般被用於處理離散的數據.
它通過對一系列的屬性判斷測試預測樣本的標籤,屬性判斷測試的過程被抽象成一棵樹的形式.
一棵決策樹由一個根節點,若干個內部節點和若干個葉節點組成.
- 葉節點對應決策結果,而其他每個節點對應於一個屬性測試.
- 根節點包含樣本全集,每個節點包含的樣本集合根據屬性測試的結果被劃分到子結點中.
- 從根節點到每個葉節點的路徑對應了一個判定測試序列.
決策樹的生成
生成決策樹的過程,就是數據不斷分裂的遞歸過程,每一次分裂,我們都儘可能讓同一類的數據被劃分到一個分支中(提高劃分結果的純度),當樹的葉子節點的數據純度達到某閾值時,停止分裂該節點.
每遍歷到一個新分裂出的節點時,都要考慮兩個問題:
- 當前節點是否要進行分裂?
- 如果進行分裂,選擇哪個屬性進行分裂?
回答這兩個問題的關鍵在於如何衡量當前節點的純度以及分裂出節點的純度,有如下三個衡量純度的指標:
純度衡量標準 | 用途 | 公式 | 說明 |
---|---|---|---|
信息熵 (Entropy) |
分類 | 表示標籤出現的頻率 表示標籤數量 |
|
基尼係數 (Gini inpurity) |
分類 | 表示標籤出現的頻率 表示標籤數量 |
|
均方誤差 (Variance) |
迴歸 | 表示樣本實際值,表示樣本均值 表示樣本數量 |
決策樹的優缺點
決策樹的優點
我們前面提到過,邏輯迴歸也能解決分類問題,但邏輯迴歸只能進行線性分類,對於線性不可分的樣本,邏輯迴歸並不適用.
例如下面這個樣本,我們不能找到一條擬合直線,將兩種類別的樣本完美分開.
但是使用決策樹,我們可以通過先後分別考察和將兩種類別的樣本完美分開.
決策樹的缺點
- 運算量大: 需要一次加載所有數據進內存,並且找尋分割條件是一個極耗資源的操作.
- 抗干擾能力差: 訓練樣本出現異常數據時,將對決策樹的構造產生很大影響.
爲了克服這兩個缺點,我們引入了隨機森林的概念.
隨機森林
我們隨機選取數據集的一部分,生成一個決策樹.重複上述過程,生成多棵決策樹,即可得到隨機森林.
在進行預測時,隨機森林採用少數服從多數的投票法得到最終結果.
隨機森林克服了單棵決策樹運算量大和抗干擾能力差的缺點.在實際使用中,我們都會使用隨機森林而非決策樹.
隨機森林VS.邏輯迴歸
隨機森林和邏輯迴歸是我們至今爲止接觸到的兩個分類器,下面表格對其做出比較:
邏輯迴歸 | 隨機森林 |
---|---|
軟分類 | 硬分類 |
線性模型 | 非線性模型 |
輸出有概率意義 | 輸出無概率意義 |
抗干擾能力強 | 抗干擾能力弱 |
使用代碼實現決策樹與隨機森林
使用sklearn.tree
模塊的DecisionTreeClassifier
和sklearn.ensemble
模塊的RandomForestClassifier
分別可以訓練決策樹與隨機森林分類器,代碼如下:
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
iris = load_iris()
data = pd.DataFrame(iris.data)
# 提取鳶尾花數據
X = iris.data # 花萼長度,寬度
y = iris.target # 花的種類
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.75)
# 創建一個最大深度爲8,以交叉熵作爲純度標準的分類器
tree_clf = DecisionTreeClassifier(max_depth=8, criterion='entropy')
tree_clf.fit(X_train, y_train)
tree_clf.predict(X_test)
# 創建一個包含15棵決策樹的隨機森林
rnd_clf = RandomForestClassifier(n_estimators=15, max_leaf_nodes=16)
rnd_clf.fit(X_train, y_train)
rnd_clf.predict(X_test)
使用決策樹和隨機森林也可以進行迴歸,不過這種迴歸的本質仍是分類,得到的估計值是同一類樣本的輸出的均值其曲線是由一段段水平線連接而成的.
使用sklearn.tree
模塊的DecisionTreeRegressor
和sklearn.ensemble
模塊的RandomForestRegressor
分別可以訓練決策樹與隨機森林迴歸器.
import matplotlib.pyplot as plt
import numpy as np
from sklearn.tree import DecisionTreeRegressor
# 創建數據
N = 100
x = np.random.rand(N, 1) * 6 - 3
y = np.sin(x) + np.random.rand(N, 1) * 0.05
plt.plot(x, y, "ko", label="actual")
# 創建不同深度的決策樹進行迴歸
depth = [2, 4, 6, 8, 10]
color = 'rgbmy'
tree_reg = DecisionTreeRegressor()
x_test = np.linspace(-3, 3, 50).reshape(-1, 1)
for d, c in zip(depth, color):
tree_reg.set_params(max_depth=d)
tree_reg.fit(x, y)
y_hat = tree_reg.predict(x_test)
plt.plot(x_test, y_hat, '-', color=c, linewidth=2, label="depth=%d" % d)
plt.legend(loc="upper left")
plt.grid(b=True)
plt.show()