返回文章列表

決策樹與整合學習模型應用

本文探討決策樹、隨機森林和梯度提升樹等機器學習演算法,並解析基尼不純度、資訊增益和熵等關鍵概念在模型建構中的應用。同時,文章也涵蓋了特徵重要性計算、超引數調優以及 PySpark 程式碼實作等實務技巧,並延伸討論了支援向量機和神經網路等相關演算法。

機器學習 演算法

決策樹是一種常用的機器學習演算法,適用於分類別和迴歸任務。基尼不純度、資訊增益和熵是用於評估分割品質的指標,協助決策樹選擇最佳分割特徵和分割點。隨機森林和梯度提升樹是根據決策樹的整合學習方法,能有效提升模型效能並降低過擬合風險。隨機森林透過隨機抽樣和特徵子集構建多棵決策樹,並整合其預測結果。梯度提升樹則以迭代方式訓練多棵樹,每棵樹學習前一棵樹的殘差,逐步提升模型精確度。理解這些演算法的原理和應用,能幫助我們更好地解決實際問題。

熵與資訊增益在決策樹中的應用

在機器學習中,熵(Entropy)是用來衡量資料隨機程度的指標。熵的計算公式為:

Entropy = -∑(p(x) * log2(p(x)))

其中,p(x) 代表事件 x 發生的機率。熵的範圍在 0 到 1 之間。當熵為 0 時,表示資料沒有隨機性;當熵為 1 時,表示資料完全隨機。

熵的計算範例

假設有兩個袋子,第一個袋子中有 4 個藍球,沒有紅球;第二個袋子中有 2 個藍球和 2 個紅球。計算這兩個袋子的熵:

袋子 1 的熵

  • 藍球的機率 = 4/4 = 1
  • 紅球的機率 = 0/4 = 0
  • 熵 = - (1 * log2(1) + 0 * log2(0)) = 0

袋子 2 的熵

  • 藍球的機率 = 2/4 = 0.5
  • 紅球的機率 = 2/4 = 0.5
  • 熵 = - (0.5 * log2(0.5) + 0.5 * log2(0.5)) = 1

由此可見,第一個袋子的熵為 0,表示結果是確定的;第二個袋子的熵為 1,表示結果是完全隨機的。

在信用核准資料集上的應用

給定一個信用核准的資料集,如表 5-4 所示,我們可以計算熵來決定決策樹的分割點。

表 5-4:信用核准資料集

年齡性別核准/未核准
30未核准
25核准
45核准
57未核准
27核准
54核准
35未核准

首先,將年齡變數分為兩部分:大於等於 30 和小於 30。

父節點的熵(目標變數:核准/未核准)

  • 核准的機率 = 4/7 = 0.57
  • 未核准的機率 = 3/7 = 0.43
  • 父節點的熵 = - (0.57 * log2(0.57) + 0.43 * log2(0.43)) = 0.99

年齡變數的熵

  • 當年齡 >= 30 時,核准的機率 = 2/5 = 0.4,未核准的機率 = 3/5 = 0.6,熵 = - (0.4 * log2(0.4) + 0.6 * log2(0.6)) = 0.97
  • 當年齡 < 30 時,核准的機率 = 2/2 = 1,未核准的機率 = 0,熵 = - (1 * log2(1) + 0 * log2(0)) = 0

性別變數的熵

  • 當性別為女性時,核准的機率 = 2/4 = 0.5,未核准的機率 = 2/4 = 0.5,熵 = - (0.5 * log2(0.5) + 0.5 * log2(0.5)) = 1
  • 當性別為男性時,核准的機率 = 2/3 = 0.67,未核准的機率 = 1/3 = 0.33,熵 = - (0.67 * log2(0.67) + 0.33 * log2(0.33)) = 0.92

資訊增益的計算

資訊增益(Information Gain, IG)用來衡量每次分割所獲得的知識。公式如下:

IG = 父節點的熵 - ∑(子節點的熵 * 子節點樣本比例)

年齡變數的資訊增益

IG(年齡) = 0.99 - (0.97 * 5/7 + 0 * 2/7) = 0.29

性別變數的資訊增益

IG(性別) = 0.99 - (1 * 4/7 + 0.92 * 3/7) = 0.02

由於年齡變數的資訊增益(0.29)高於性別變數(0.02),因此選擇年齡作為根節點。

Gini 不純度

Gini 不純度是另一種衡量資料分割純度的指標,其公式為:

Gini = 1 - ∑(p(x)^2)

Gini 不純度的範圍在 0 到 0.5 之間。當 Gini = 0 時,表示分割是純淨的;當 Gini = 0.5 時,表示分割是完全隨機的。

Gini 不純度的應用

在決策樹中,Gini 不純度可以用來替代熵進行節點分割。兩者的主要區別在於計算方式和對不同類別分佈的敏感度。

決策樹中的基尼不純度與變異數

決策樹是一種廣泛應用於分類別和迴歸任務的監督學習演算法。在決策樹的建構過程中,基尼不純度和變異數是兩個重要的概念,用於衡量資料的純度和決定最佳分割點。

基尼不純度

基尼不純度(Gini Impurity)是衡量一個節點中類別雜亂程度的指標。它的計算公式為: [ Gini = 1 - \sum_{i=1}^{n} p_i^2 ] 其中,( p_i ) 是屬於類別 ( i ) 的樣本比例。

基尼不純度的計算範例

考慮一個包含藍色和紅色球的袋子範例:

  • 袋子1:4個藍球,0個紅球

    • 藍球的機率 = 4/4 = 1
    • 紅球的機率 = 0/4 = 0
    • 基尼不純度 = 1 - (11 + 00) = 0
  • 袋子2:2個藍球,2個紅球

    • 藍球的機率 = 2/4 = 0.5
    • 紅球的機率 = 2/4 = 0.5
    • 基尼不純度 = 1 - (0.50.5 + 0.50.5) = 0.5
  • 空袋子

    • 藍球的機率 = 0
    • 紅球的機率 = 0
    • 基尼不純度 = 1 - 0 = 1

基尼不純度越低,表示節點中的樣本越純淨。

使用基尼不純度建立決策樹

在建立決策樹時,會根據基尼不純度來選擇最佳的分割特徵和分割點。計算每個可能的分割點的基尼不純度,並選擇使得基尼不純度降低最多的分割點。

程式碼範例:使用 PySpark 建立基尼不純度決策樹

from pyspark.ml.classification import DecisionTreeClassifier

# 建立決策樹分類別器,使用基尼不純度
clf = DecisionTreeClassifier(featuresCol='features', labelCol='y', impurity='gini')
clf_model = clf.fit(binary_df)

# 檢視特徵重要性
print(clf_model.featureImportances)

變異數

變異數(Variance)是用於迴歸任務的指標,衡量目標變數的離散程度。它的計算公式為: [ Variance = \frac{1}{n} \sum_{i=1}^{n} (x_i - \bar{x})^2 ] 其中,( x_i ) 是樣本值,( \bar{x} ) 是樣本均值。

使用變異數建立迴歸樹

在迴歸任務中,會根據變異數來選擇最佳的分割特徵和分割點,以最小化變異數。

程式碼範例:使用 PySpark 建立變異數迴歸樹

from pyspark.ml.regression import DecisionTreeRegressor

# 建立決策樹迴歸器,使用變異數
reg = DecisionTreeRegressor(featuresCol='features', labelCol='balance', impurity='variance')
reg_model = reg.fit(continuous_df)

# 檢視特徵重要性
print(reg_model.featureImportances)

特徵重要性計算

決策樹可以用來計算特徵的重要性。特徵重要性的計算公式為: [ f_i = \sum_{j:node,j,splits,on,feature,i} \frac{n_j}{n} G_j ] 其中,( n_j ) 是節點 ( j ) 中的樣本數,( G_j ) 是節點 ( j ) 的基尼不純度或變異數。

程式碼範例:檢視決策樹規則

# 檢視決策樹規則
print(clf_model.toDebugString)
print(reg_model.toDebugString)

這些規則可以用 Graphviz、pydot 或 networkx 等套件視覺化。

圖表翻譯:

此圖示呈現了決策樹的結構和規則,包括每個節點的分割條件和葉節點的預測結果。

決策樹與隨機森林:特徵重要性與整合學習

在機器學習領域,決策樹是一種基礎且重要的演算法。它不僅能夠進行分類別和迴歸任務,還能夠提供特徵重要性的評估。在本章中,我們將探討決策樹、隨機森林以及梯度提升樹等相關技術。

決策樹中的特徵重要性

決策樹透過計算每個節點的Gini不純度,並將其乘以透過該節點的樣本數來評估特徵的重要性。如果一個變數在決策樹中出現多次,則將每個節點的輸出相加以獲得該變數的最終特徵重要性。最後,所有變數的特徵重要性被歸一化,使它們的總和為1。

最終特徵重要性的計算公式如下:

[ f_{i}^{final} = \frac{f_{i}}{f_{1} + f_{2} + … + f_{n}} ]

其中,( f_{i} ) 表示第 ( i ) 個變數的特徵重要性,( n ) 表示特徵的總數。

需要注意的是,特徵重要性是根據訓練資料集計算的,因此在模型過擬合時可能會出現偏差。為了克服這一問題,可以使用適當的驗證技術或排列重要性來計算特徵重要性。

隨機森林

隨機森林是一種整合學習模型,根據Bagging(Bootstrap Aggregation)的概念。它透過構建多個決策樹並聚合它們的結果來獲得最終預測。

隨機森林的工作原理

  1. 選擇隨機特徵:子集特徵(featureSubsetStrategy)。
  2. 選擇隨機樣本(有放回或無放回抽樣):子集行(subsamplingRate)。
  3. 根據子集特徵和行形成子集資料
  4. 根據子集資料構建決策樹
  5. 重複步驟1-4以構建使用者指定的樹數量。PySpark預設的樹數量為20(numTrees)。
  6. 將資料透過所有單獨的樹,取得每棵樹的預測結果。
  7. 對於分類別問題,計算每個類別的投票數。選擇投票數最多的類別作為最終輸出。
  8. 對於迴歸問題,平均所有單獨樹的輸出(預測)以獲得最終輸出

超引數調優

透過調整featureSubsetStrategysubsamplingRate引數,可以提高模型效能和訓練過程的速度。

  • featureSubsetStrategy:可選"auto"、“all”、“sqrt”、“log2”、“onethird”。
  • subsamplingRate:介於0和1之間的任意值。當值設為1時,使用整個資料集。

使用隨機森林計算特徵重要性

在隨機森林中,特徵重要性的計算方式與決策樹類別似,但有一點不同:在歸一化之前,計算變數的平均特徵重要性。

[ average_f_{i} = \frac{\sum f_{i}}{number\ of\ trees\ with\ feature} ]

所有變數的( average_f_{i} )用於計算最終特徵重要性( f_{i}^{final} )。

為什麼選擇隨機森林?

  • 隨機森林比單一決策樹更穩健,能夠限制過擬合。
  • 透過在每次樹訓練過程中隨機選擇特徵,消除了特徵選擇偏差。
  • 隨機森林使用鄰近矩陣,可以用來填充缺失值。

梯度提升樹

梯度提升樹是另一種根據決策樹的變體。梯度提升是一種整合學習模型,根據Boosting的概念。它使用弱學習器來構建樹,是一種加法建模技術,也被稱為順序學習,因為當前樹從前一棵樹的錯誤中學習。

梯度提升學習過程

  • 模型訓練從構建初始決策樹開始。使用這棵樹進行預測。
  • 根據預測輸出建立樣本權重列。當預測錯誤時,樣本被賦予更大的權重;當預測準確時,樣本被賦予較小的權重。
  • 根據樣本權重列建立新的訓練資料集。這是為了確保錯誤樣本在新建立的訓練資料中獲得更多的優先權。

PySpark程式碼範例

分類別

from pyspark.ml.classification import RandomForestClassifier

clf = RandomForestClassifier(featuresCol='features', labelCol='y')
clf_model = clf.fit(binary_df)
print(clf_model.featureImportances)
print(clf_model.toDebugString)

迴歸

from pyspark.ml.regression import RandomForestRegressor

reg = RandomForestRegressor(featuresCol='features', labelCol='balance')
reg_model = reg.fit(continuous_df)
print(reg_model.featureImportances)
print(reg_model.toDebugString)

程式碼解密:

在上述PySpark程式碼中,我們使用了RandomForestClassifierRandomForestRegressor來進行分類別和迴歸任務。featuresCol引數指定了特徵列的名稱,而labelCol引數指定了標籤列的名稱。透過呼叫fit方法,我們對模型進行訓練,並使用featureImportances屬性來取得特徵重要性。toDebugString方法提供了模型的詳細除錯資訊。

梯度提升(Gradient Boosting)深度解析

梯度提升是一種強大的整合學習技術,透過逐步建構多個弱學習器來形成強學習器。其核心優勢在於能夠有效處理分類別和迴歸問題,並且在多個領域展現出卓越的效能。

梯度提升的工作原理

  1. 初始模型建立:首先使用一個簡單的模型進行初始預測。
  2. 殘差計算:計算實際值與預測值之間的殘差。
  3. 新樹建構:建立新的決策樹來擬合這些殘差。
  4. 迭代訓練:重複步驟2和3,直到達到使用者指定的樹數量(numTrees)。

PySpark程式碼實作

# 分類別任務
from pyspark.ml.classification import GBTClassifier
clf = GBTClassifier(featuresCol='features', labelCol='y')
clf_model = clf.fit(binary_df)
print(clf_model.featureImportances)
print(clf_model.toDebugString)

# 迴歸任務
from pyspark.ml.regression import GBTRegressor
reg = GBTRegressor(featuresCol='features', labelCol='balance')
reg_model = reg.fit(continuous_df)
print(reg_model.featureImportances)
print(reg_model.toDebugString)

內容解密:

  • GBTClassifierGBTRegressor 分別用於分類別和迴歸任務。
  • featuresCol 指定特徵欄位,labelCol 指定目標變數欄位。
  • featureImportances 用於評估各特徵的重要性。
  • toDebugString 提供模型的詳細資訊。

為何選擇梯度提升?

  • 適用於不平衡資料集:梯度提升在處理類別不平衡的資料時表現出色。
  • 降低預測偏差:相比隨機森林和決策樹,梯度提升建構的樹通常較淺,因此能有效降低預測偏差。

支援向量機(Support Vector Machine, SVM)

支援向量機是一種強大的監督式學習演算法,主要用於分類別任務。其目標是找到一個最佳的超平面來分隔不同類別的資料點。

SVM的工作原理

  1. 超平面選擇:SVM使用超平面來分隔資料。對於非線性資料,可以使用核函式(如多項式核或徑向基函式核)將資料對映到高維空間進行線性分隔。
  2. 邊界最大化:SVM不僅要正確分類別資料,還要最大化不同類別之間的邊界,以提高模型的泛化能力。

PySpark程式碼實作

from pyspark.ml.classification import LinearSVC
clf = LinearSVC(featuresCol='features', labelCol='y')
clf_model = clf.fit(binary_df)
print(binary_df.intercept, clf_model.coefficients)

內容解密:

  • LinearSVC 用於建立線性SVM分類別器。
  • featuresCollabelCol 分別指定特徵和標籤欄位。
  • interceptcoefficients 提供模型的截距和係數。

SVM的誤差函式

SVM的總誤差由分類別誤差和邊界誤差兩部分組成:

  • 分類別誤差:衡量模型在訓練資料上的錯誤率。
  • 邊界誤差:與邊界的寬度相關,寬度越大,誤差越小。

神經網路(Neural Networks)

神經網路是一種模仿人類大腦神經元結構的機器學習模型。它由輸入層、隱藏層和輸出層組成,能夠學習複雜的非線性關係。

神經網路架構要點

  • 感知機(Perceptron):最簡單的神經網路結構,由輸入層和輸出層組成,可用於建立線性或邏輯迴歸模型。
  • 隱藏層:增加隱藏層可使模型學習更複雜的模式。隱藏層中的單元稱為隱藏單元。
  • 啟動函式:用於控制隱藏單元的輸出。常見的啟動函式包括ReLU和TanH。

神經網路的優點

  • 能夠學習複雜的非線性關係。
  • 透過增加隱藏層的數量和寬度,可以構建深度或寬度神經網路,以應對不同的任務需求。

Plantuml神經網路基本架構

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 決策樹與整合學習演算法架構

package "分割指標" {
    component [熵 (Entropy)] as entropy
    component [基尼不純度] as gini
    component [資訊增益] as ig
}

package "決策樹" {
    component [分割條件] as split
    component [遞迴建構] as recursive
    component [葉節點預測] as leaf
}

package "整合學習" {
    component [隨機森林] as rf
    component [梯度提升樹] as gbt
    component [Bagging] as bag
}

package "進階演算法" {
    component [支援向量機] as svm
    component [神經網路] as nn
    component [特徵重要性] as importance
}

entropy --> ig : 計算增益
gini --> split : 純度衡量
ig --> split : 最佳分割

split --> recursive : 子節點
recursive --> leaf : 預測結果

rf --> bag : 隨機抽樣
gbt --> bag : 殘差學習
bag --> importance : 變數貢獻

rf --> svm : 比較
gbt --> nn : 比較

note right of ig
  IG = 父熵 - 子熵加權和
  選擇最大 IG 分割
end note

note bottom of gbt
  迭代訓練
  逐步提升精確度
end note

skinparam dummy {
}
    package "資料處理" {
        component [資料收集] as collect
        component [資料清洗] as clean
        component [特徵工程] as feature
    }

    package "模型訓練" {
        component [模型選擇] as select
        component [超參數調優] as tune
        component [交叉驗證] as cv
    }

    package "評估部署" {
        component [模型評估] as eval
        component [模型部署] as deploy
        component [監控維護] as monitor
    }
}

collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型

note right of feature
  特徵工程包含:
  - 特徵選擇
  - 特徵轉換
  - 降維處理
end note

note right of eval
  評估指標:
  - 準確率/召回率
  - F1 Score
  - AUC-ROC
end note

@enduml

圖表翻譯: 此圖示展示了一個基本神經網路的架構,包括輸入層、隱藏層和輸出層。輸入層接收原始資料,隱藏層進行特徵學習,輸出層產生最終預測結果。神經網路透過多層結構能夠學習複雜的非線性關係,使其在多個領域有廣泛的應用。