大俠幸會,在下全網同名「演算法金」 0 基礎轉 AI 上岸,多個演算法賽 Top 「日更萬日,讓更多人享受智慧樂趣」
1. 引言
今天我們嘮嘮 吳恩達:機器學習的六個核心演算法! 之決策樹演算法。
決策樹是一種用於分類和迴歸的機器學習演算法。它透過一系列的決策規則將資料逐步劃分,最終形成一個類似於樹狀結構的模型。
決策樹因其直觀、易於解釋和高效的特點,被廣泛應用於分類和迴歸問題中。它可以處理連續和離散的資料,並且能夠處理多種型別的特徵,因而在醫學診斷、市場分析、金融預測等領域得到了廣泛的應用。
必 須 拿 下 !!!
2. 決策樹的基本概念
2.1 什麼是決策樹
決策樹是一種樹形結構的模型,它透過一系列的決策規則將資料逐步劃分,從而實現分類或迴歸的目的。決策樹由節點和分支組成,根節點代表整個資料集,每個內部節點代表一個特徵,每個分支代表一個決策規則,每個葉子節點表示一個最終的預測結果。
決策樹演算法最早可以追溯到 20 世紀 60 年代。1975 年,J. Ross Quinlan 提出了 ID3 演算法,隨後又發展出了 C4.5 和 C5.0 演算法。1993 年,Leo Breiman 等人提出了 CART(Classification and Regression Trees)演算法,這些演算法奠定了現代決策樹的基礎。
(假設一個相親決策樹,By 三點水)
(另一顆相親決策樹,人類的疑惑行為)
2.2 決策樹的基本結構
- 根節點(Root Node): 決策樹的起始點,包含所有資料。
- 內部節點(Internal Node): 透過特徵劃分資料的節點,每個節點代表一個特徵。
- 分支(Branch): 從節點分裂出來的路徑,表示特徵的不同取值。
- 葉子節點(Leaf Node): 最終的分類或迴歸結果。
2.3 決策樹的工作原理
決策樹透過遞迴地選擇最優特徵來劃分資料。具體步驟如下:
- 特徵選擇: 在當前節點選擇能夠最好地劃分資料的特徵。
- 資料劃分: 根據選擇的特徵將資料劃分成子集。
- 遞迴構建: 對每個子集重複上述過程,直到滿足停止條件(如節點純度達到一定水平或節點包含的樣本數過少)。
2.4 決策樹的優缺點
優點:
- 直觀易懂,易於解釋。
- 處理分類和迴歸問題。
- 適用於處理數值型和類別型特徵。
缺點:
- 容易過擬合,尤其是深度較大的樹。
- 對於類別較多的特徵,資訊增益偏向於取值多的特徵。
- 對資料中的噪聲和異常值較敏感。
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
import numpy as np
# 生成武俠風格的資料,確保所有特徵值為正數
X, y = make_classification(n_samples=200, n_features=2, n_redundant=0, n_informative=2,
n_clusters_per_class=1, random_state=42)
X += np.abs(X.min()) # 平移資料確保為正
# 將資料集分為訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 建立決策樹模型,並設定最大深度為3
dt = DecisionTreeClassifier(max_depth=3)
# 訓練模型
dt.fit(X_train, y_train)
# 繪製資料點和決策邊界
def plot_decision_boundary(model, X, y):
# 設定最小和最大值,以及增量
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
np.arange(y_min, y_max, 0.01))
# 預測整個網格的值
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 繪製決策邊界
plt.contourf(xx, yy, Z, alpha=0.4)
# 繪製不同類別的樣本點
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], c='red', marker='x', label='普通武者')
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], c='blue', marker='o', label='武林高手')
plt.xlabel('功力值')
plt.ylabel('內功心法')
plt.title('武俠世界中的武者分類圖')
plt.legend()
# 繪製決策邊界和資料點
plot_decision_boundary(dt, X, y)
plt.show()
3. 決策樹的構建
3.1 特徵選擇
特徵選擇是決策樹構建的關鍵步驟。常用的特徵選擇標準包括資訊增益、增益比和基尼指數。
- 資訊增益(Information Gain): 衡量特徵對資料集資訊熵的減少程度,資訊增益越大,特徵的區分能力越強。
- 增益比(Gain Ratio): 是對資訊增益的改進,考慮了特徵的取值數目。
- 基尼指數(Gini Index): 衡量資料集的不純度,基尼指數越小,資料集越純。
3.2 樹的分裂準則
分裂準則決定了如何在每個節點處劃分資料。不同的決策樹演算法使用不同的分裂準則:
- ID3演算法: 使用資訊增益作為分裂準則。
- C4.5演算法: 使用增益比作為分裂準則。
- CART演算法: 使用基尼指數作為分裂準則。
3.3 樹的生長和剪枝
- 樹的生長: 決策樹從根節點開始,不斷選擇最優特徵進行分裂,直到所有葉子節點都達到純度或滿足停止條件。
- 剪枝: 為了防止過擬合,可以對決策樹進行剪枝。剪枝分為預剪枝和後剪枝。預剪枝是在樹生長過程中停止分裂,後剪枝是在樹完全生長後去掉一些葉子節點。
示例程式碼
下面是一個詳細展示如何構建和最佳化決策樹的例子。
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.model_selection import train_test_split
from sklearn import metrics
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
# 構造武俠元素資料集
data = {
'武功': ['高', '中', '低', '高', '中', '低', '高', '中'],
'輕功': ['強', '強', '弱', '弱', '強', '強', '弱', '弱'],
'身份': ['正派', '邪派', '正派', '邪派', '正派', '邪派', '正派', '邪派'],
'是否獲勝': ['是', '是', '否', '否', '是', '否', '是', '否']
}
# 轉換為DataFrame
df = pd.DataFrame(data)
# 特徵和標籤
X = pd.get_dummies(df.drop('是否獲勝', axis=1))
y = df['是否獲勝'].apply(lambda x: 1 if x == '是' else 0)
# 劃分資料集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 建立決策樹分類器
clf = DecisionTreeClassifier(criterion='entropy', max_depth=3)
clf = clf.fit(X_train, y_train)
# 預測
y_pred = clf.predict(X_test)
# 模型評估
print("準確率:", metrics.accuracy_score(y_test, y_pred))
# 決策樹視覺化
plt.figure(figsize=(12, 8))
plot_tree(clf, filled=True, feature_names=X.columns, class_names=['否', '是'])
plt.show()
# 顯示決策樹的規則
tree_rules = export_text(clf, feature_names=list(X.columns))
print(tree_rules)
4. 決策樹的演算法實現
4.1 ID3演算法
ID3演算法(Iterative Dichotomiser 3)是由 J. Ross Quinlan 在 1986 年提出的一種決策樹演算法。它使用資訊增益作為特徵選擇的標準,遞迴地構建決策樹。
資訊熵(Entropy)表示資料集的純度,計算公式為:
ID3演算法的步驟
- 計算當前特徵的資訊增益。
- 選擇資訊增益最大的特徵進行資料劃分。
- 對每個子集遞迴地呼叫上述過程,直到所有資料屬於同一類別或沒有更多特徵可供選擇。
示例程式碼
from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.model_selection import train_test_split
from sklearn import metrics
# 使用 ID3 演算法
clf_id3 = DecisionTreeClassifier(criterion='entropy')
clf_id3 = clf_id3.fit(X_train, y_train)
# 預測
y_pred_id3 = clf_id3.predict(X_test)
# 模型評估
print("ID3 準確率:", metrics.accuracy_score(y_test, y_pred_id3))
# 顯示決策樹的規則
tree_rules_id3 = export_text(clf_id3, feature_names=list(X.columns))
print(tree_rules_id3)
4.2 C4.5演算法
C4.5演算法是對ID3演算法的改進,主要改進點在於使用增益比(Gain Ratio)來進行特徵選擇,克服了資訊增益偏向於多值特徵的問題。
C4.5演算法的步驟
- 計算當前特徵的資訊增益比。
- 選擇資訊增益比最大的特徵進行資料劃分。
- 對每個子集遞迴地呼叫上述過程,直到所有資料屬於同一類別或沒有更多特徵可供選擇。
4.3 CART演算法
CART演算法(Classification and Regression Trees)由 Leo Breiman 等人在 1984 年提出,它使用基尼指數作為特徵選擇標準。CART 演算法可以用於分類和迴歸任務。計算公式為:
CART演算法的步驟
- 計算當前特徵的基尼指數。
- 選擇基尼指數最小的特徵進行資料劃分。
- 對每個子集遞迴地呼叫上述過程,直到所有資料屬於同一類別或沒有更多特徵可供選擇。
示例程式碼
# 使用 CART 演算法
clf_cart = DecisionTreeClassifier(criterion='gini')
4.4 決策樹的視覺化
決策樹的視覺化可以幫助我們更直觀地理解模型的決策過程。
示例程式碼
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
# 視覺化 ID3 決策樹
plt.figure(figsize=(12, 8))
plot_tree(clf_id3, filled=True, feature_names=X.columns, class_names=['否', '是'])
plt.title("ID3 決策樹")
plt.show()
# 視覺化 CART 決策樹
plt.figure(figsize=(12, 8))
plot_tree(clf_cart, filled=True, feature_names=X.columns, class_names=['否', '是'])
plt.title("CART 決策樹")
plt.show()
透過上述程式碼,我們可以構建不同的決策樹模型,並對其進行視覺化和評估。
決策樹的視覺化除了使用 scikit-learn 自帶的 plot_tree 方法之外,還有其他專門的庫可以用於更加專業和美觀的視覺化。以下是幾個常用的方法和庫:
- 使用 Graphviz 和 pydotplus
Graphviz 是一個開源的圖形視覺化軟體,可以用來生成決策樹的影像。配合 pydotplus 庫,可以很方便地將 scikit-learn 的決策樹模型轉換為 Graphviz 的格式並進行視覺化。
pip install graphviz pydotplus
from sklearn.tree import export_graphviz
import pydotplus
from IPython.display import Image
# 匯出決策樹為 DOT 格式的資料
dot_data = export_graphviz(clf, out_file=None,
feature_names=X.columns,
class_names=['否', '是'],
filled=True, rounded=True,
special_characters=True)
# 使用 pydotplus 將 DOT 資料轉換為影像
graph = pydotplus.graph_from_dot_data(dot_data)
Image(graph.create_png())
- 使用 dtreeviz
dtreeviz 是一個專門用於決策樹視覺化的庫,可以生成非常美觀和詳細的決策樹圖。
pip install dtreeviz
from dtreeviz.trees import dtreeviz
# 使用 dtreeviz 視覺化決策樹
viz = dtreeviz(clf, X_train, y_train,
target_name='是否獲勝',
feature_names=X.columns,
class_names=['否', '是'])
# 展示決策樹
viz.view()
- 使用 plotly 和 dash
plotly 和 dash 是強大的視覺化庫,可以用來建立互動式的決策樹圖表。
pip install plotly dash
import plotly.graph_objs as go
from dash import Dash, dcc, html
# 建立決策樹圖表
fig = go.Figure(go.Sunburst(
labels=["根節點", "節點1", "節點2", "節點3", "節點4"],
parents=["", "根節點", "根節點", "節點1", "節點1"],
values=[1, 2, 3, 4, 5],
))
# 建立 Dash 應用
app = Dash(__name__)
app.layout = html.Div([
dcc.Graph(id='tree', figure=fig)
])
if __name__ == '__main__':
app.run_server(debug=True)
- 使用 yellowbrick
yellowbrick 是一個用於模型視覺化的庫,可以方便地視覺化決策樹。
pip install yellowbrick
from yellowbrick.model_selection import ValidationCurve
from sklearn.tree import DecisionTreeClassifier
# 建立決策樹分類器
model = DecisionTreeClassifier()
# 使用 ValidationCurve 視覺化決策樹
viz = ValidationCurve(
model, param_name="max_depth",
param_range=np.arange(1, 11), cv=10, scoring="accuracy"
)
viz.fit(X_train, y_train)
viz.show()
這些方法和庫提供了豐富的視覺化選項,可以根據需要選擇適合的工具進行決策樹的視覺化。
5. 決策樹的最佳化
5.1 特徵選擇的重要性
特徵選擇是構建高效決策樹的關鍵步驟。選擇合適的特徵不僅可以提高模型的準確性,還可以減少模型的複雜度,避免過擬合。
特徵選擇的主要方法包括:
- 過濾法:使用統計方法選擇特徵,如方差分析、卡方檢驗等。
- 包裹法:使用機器學習演算法評估特徵,如遞迴特徵消除(RFE)。
- 嵌入法:在模型訓練過程中選擇特徵,如決策樹的特徵重要性。
示例程式碼
from sklearn.feature_selection import SelectKBest, chi2
# 使用卡方檢驗選擇最佳特徵
X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
5.2 剪枝技術的應用
剪枝技術用於防止決策樹過擬合。主要包括預剪枝和後剪枝:
- 預剪枝:在樹的構建過程中提前停止,如限制樹的深度。
- 後剪枝:先構建完整的樹,再去除不必要的節點。
示例程式碼
# 預剪枝:限制最大深度
clf_preprune = DecisionTreeClassifier(max_depth=3)
clf_preprune.fit(X_train, y_train)
# 後剪枝:使用 cost complexity pruning
path = clf_preprune.cost_complexity_pruning_path(X_train, y_train)
ccp_alphas = path.ccp_alphas
# 選擇最佳的 alpha 值進行剪枝
clf_postprune = DecisionTreeClassifier(ccp_alpha=ccp_alphas[-1])
clf_postprune.fit(X_train, y_train)
5.3 整合方法:隨機森林
隨機森林透過構建多棵決策樹並將它們的結果進行投票,來提高模型的泛化能力和準確性。
示例程式碼
from sklearn.ensemble import RandomForestClassifier
# 建立隨機森林分類器
clf_rf = RandomForestClassifier(n_estimators=100)
clf_rf.fit(X_train, y_train)
# 預測
y_pred_rf = clf_rf.predict(X_test)
# 模型評估
print("隨機森林準確率:", metrics.accuracy_score(y_test, y_pred_rf))
5.4 整合方法:梯度提升樹
梯度提升樹透過逐步構建決策樹,每棵新樹都是為了糾正前一棵樹的誤差,從而提高模型的準確性。
示例程式碼
from sklearn.ensemble import GradientBoostingClassifier
# 建立梯度提升分類器
clf_gb = GradientBoostingClassifier(n_estimators=100)
clf_gb.fit(X_train, y_train)
# 預測
y_pred_gb = clf_gb.predict(X_test)
# 模型評估
print("梯度提升樹準確率:", metrics.accuracy_score(y_test, y_pred_gb))
6. 決策樹的變體
6.1 隨機森林
隨機森林(Random Forest)是一種整合學習方法,透過構建多個決策樹並將它們的預測結果進行投票或平均,來提高模型的準確性和穩定性。每棵樹在訓練時使用了不同的子集和特徵子集,這種隨機性使得隨機森林對噪聲和過擬合有較強的抵抗能力。
具體的,可以留言,想看的讀者多的話,專門開一篇詳細展開
6.2 極端隨機樹
極端隨機樹(Extra Trees 或 Extremely Randomized Trees)是另一種整合方法,與隨機森林類似,但在構建每棵樹時,它對特徵的選擇和分割點的選擇更加隨機。這種極端隨機化減少了方差,但可能會增加偏差,使得模型更加簡單和快速。
6.3 梯度提升樹
梯度提升樹(Gradient Boosting Trees)是一種提升方法,透過逐步構建一系列的決策樹,每棵新樹都是為了糾正前一棵樹的錯誤。它透過逐步最佳化損失函式,使得模型的預測結果越來越好。梯度提升樹在處理迴歸和分類問題時表現出色,特別是在處理複雜資料集時。
6.4 XGBoost
XGBoost(Extreme Gradient Boosting)是一種高效的梯度提升實現,具有很高的計算效率和預測效能。XGBoost 引入了正則化項以防止過擬合,並透過使用分散式計算加速訓練過程。它在許多機器學習競賽中表現優異,成為資料科學家的常用工具。
還有 CatBoost,LGB
具體的,可以留言,想看的讀者多的話,專門詳細展開,這個可以寫好幾篇
[ 抱個拳,總個結 ]
決策樹是一種簡單而強大的機器學習演算法,廣泛應用於分類和迴歸問題,必須拿下。透過最佳化特徵選擇、應用剪枝技術和使用整合方法,可以進一步提高決策樹的效能。在實際應用中,掌握決策樹的常見問題及解決方法,對於構建高效、穩定的模型至關重要。
[ 演算法金,碎碎念 ]
全網同名,日更萬日,讓更多人享受智慧樂趣
煩請大俠多多 分享、在看、點贊,助力演算法金又猛又持久、很黃很 BL 的日更下去;
同時邀請大俠 關注、星標 演算法金,圍觀日更萬日,助你功力大增、笑傲江湖