回歸
決策樹也可以用於執行回歸任務。我們首先用sk-learn的DecisionTreeRegressor類構造一顆回歸決策樹,並在一個帶噪聲的二次方數據集上進行訓練,指定max_depth=2:
import numpy as np # Quadratic training set + noise np.random.seed(42) m = 200 X = np.random.rand(m, 1) y = 4 * (X - 0.5) ** 2 y = y + np.random.randn(m, 1) / 10 from sklearn.tree import DecisionTreeRegressor tree_reg = DecisionTreeRegressor(max_depth=2, random_state=42) tree_reg.fit(X, y)
下圖是這棵樹的結果:
這棵樹看起來與之前構造的分類樹類似。主要的區別是:在每個節點中,預測的不是一個類別,而是一個值。例如,假設我們想為一個新的實例x1=0.6做預測。我們會先從根節點遍歷樹,最終到達預測value=0.111的葉子節點。這個預測值是與這個葉子節點關聯的110條訓練數據的平均值,並且它在這110條數據上的均方誤差等於0.015。
這個模型的預測在如下左圖中進行表示。如果設置max_depth=3,則得到如下右圖。需要注意的是:每個區域的預測值,都是當前區域中所有目標值的平均值。算法在分割區域時,會以一種讓大部分訓練數據盡可能地靠近預測的值的方式進行分割。
CART算法在這與之前提到的原理基本類似,除了在分割訓練集時,之前是找到一種分割讓不純度最小;現在是找到一種分割讓MSE最小。下面是算法要最小化的損失函數:
與分類任務一樣,在處理回歸任務時,決策樹也會傾向於過擬合。如果沒有任何的正則(例如使用的是默認的參數),則我們會得到下面左圖的(在訓練集上)預測的結果。很明顯這些預測在訓練集上是過擬合的。在僅設置min_samples_leaf=10 后,我們可以得到一個更合理的模型,如下右圖所示:
不穩定性
到目前為止,我們已經了解了決策樹的基本特點:易於理解與表示、上手簡單並且功能強大。不過,它們仍有一些局限性。首先,大家可能已經注意到過,決策樹喜歡直角的決策邊界(所有的分割都是與一個軸垂直的),這個會讓決策樹對訓練數據的旋轉非常敏感。例如,下圖是一個簡單的線性可分數據集:在左邊,一個決策樹可以很容易地將它們分割;但是對於右邊的圖,在數據集旋轉了45°之后,決策邊界看起來復雜了一些(但是這種復雜很沒有必要)。盡管兩個決策樹都能完美地擬合訓練集,但是很大可能右邊的模型的泛化性能不會太好。其中一個緩解這個問題的辦法是使用主成成分分析(Principal Component Analysis),使用它后,基本可以讓訓練數據有一個更好的方向(角度)。
不過在決策樹中最常見也最主要的問題是:它們對訓練集中的微小變化都非常敏感。例如,假設我們僅僅是從iris訓練集中移除掉最寬的Iris versicolor(這條數據的length=4.8 cm,width=1.8cm) ,然后重新訓練一個新的決策樹,我們可能會得到下面的模型:
從這模型里我們可以看到,它與之前訓練的決策樹模型差別非常大。不過實際上由於sk-learn是隨機的(它會隨機選擇一組特征,在每個節點中進行評估),所以即使是在同樣的訓練數據上,每次訓練出來的模型可能都是差別比較大的(除非設置了random_state 超參數)。
隨機森林可以限制這種不穩定性,通過在多個樹上取平均預測,我們之后會介紹。