AI 互動教室 · 機器學習
下載 .py 單獨開啟實驗場 ↗
DECISION TREE · 決策樹

把混亂
切成秩序

下面是一群混在一起的資料點。決策樹做的事只有一件: 一次問一個問題,一刀一刀把它們切開。你來試試——

加權 Gini

三刀之後,每個區域幾乎只剩一種顏色,Gini 不純度從 0.5 掉到接近 0—— 這一頁接下來的所有內容,都在回答一個問題:機器怎麼自己找到「該在哪裡切」?

右邊的實驗場是真的 Python(在你的瀏覽器裡跑,不用安裝任何東西)。 首次載入約需 30–60 秒,正好夠你讀完第 1 節。每一格程式碼都能改、能重跑, 改壞了重新整理就復原——這是你的沙盒,盡量玩。

01 · 直覺

決策樹就是「猜猜看」遊戲

你一定玩過:我心裡想一個動物,你用「是非題」猜——「會飛嗎?」「比人大嗎?」 好的提問者不會亂問,每一題都挑最能砍掉一半可能性的問題。

決策樹把這個遊戲玩在資料上:每個內部節點是一道是非題(「花瓣長度 ≤ 2.45 cm 嗎?」), 每個葉節點是一個答案(「這是 setosa」)。訓練一棵樹 = 學會該問哪些問題、按什麼順序問

它可能是最誠實的機器學習模型:預測時你可以從根到葉把路徑唸出來, 每一步都是人話。這也是它至今仍被大量使用的原因—— 以及它的進化型(隨機森林、梯度提升樹)稱霸表格資料的起點。

02 · 資料

先認識今天的主角:鳶尾花

Iris 是統計學家 Fisher 在 1936 年整理的經典資料集:150 朵鳶尾花、 3 個品種、每朵花 4 個測量值。它小到一眼看得完,又剛好複雜到能教會你決策樹的一切。

特徵(cm)意思品種(各 50 朵)
sepal length/width花萼長 / 寬● setosa
petal length/width花瓣長 / 寬● versicolor
● virginica

這三個顏色會貫穿整堂課——左邊圖裡的藍橘綠,跟右邊程式畫出來的藍橘綠,永遠指同三個品種

右邊的表格可以排序、搜尋、看每欄的分布直方圖。找找看:哪一欄的三色分得最開?

03 · 觀察

先用你的眼睛當一次分類器

在寫任何模型之前,先做人肉版:右邊的散佈圖可以任選兩個特徵當 X、Y 軸。 你的任務——找出讓三種顏色最不重疊的特徵組合

劇透一半:花萼(sepal)組合會讓你很挫折,花瓣(petal)組合會讓你覺得「這也太簡單」。 記住這個手感,等一下你會看到決策樹自己發現同一件事。

04 · 核心

好問題的數學標準:Gini 不純度

「這一刀切得好不好」需要一個分數。決策樹(預設)用 Gini 不純度衡量一組資料有多「混」:

Gini = 1 − Σk pk² pk = 第 k 類的占比。全部同類 → 0(最純);三類各⅓ → 0.667(最混)

切一刀會把資料分成左右兩組,各算一個 Gini,再按人數加權平均。 決策樹在每個節點做的事:掃過所有特徵 × 所有切點,挑加權 Gini 最小的那一刀。就這樣,沒有魔法。

拖拖看下面的紅線,感受一下同一刀切在不同位置,分數差多少:

左組 Gini 右組 Gini 加權 Gini

找到讓加權 Gini 最低的位置了嗎?恭喜,你剛剛手動執行了一次決策樹演算法的核心迴圈。 現在到右邊,對真實的 150 朵花做同一件事:

挑戰:在右邊選 petal length,把加權 Gini 壓到 0.333 以下。 你找到的那個切點,待會兒會在真正訓練出的樹的根節點再次出現。

05 · 訓練

讓演算法自己把樹長出來

手動找一刀就夠累了,而決策樹要遞迴地做:切完的每一半,再各自找最好的一刀, 一直切到夠純(或被你喊停)為止。sklearn 一行就能訓練:

DecisionTreeClassifier(max_depth=3,
  min_samples_leaf=1).fit(X_train, y_train)

兩個「喊停」的旋鈕,也是你在右邊要玩的滑桿:

  • max_depth——最多問幾層問題。層數是樹的表達力,也是它闖禍的本錢。
  • min_samples_leaf——每片葉子至少幾個樣本。防止樹為了一兩朵怪花特設規則。

這是 iris 上深度 2 的真實結果(數字都是真的,不是示意):

petal length ≤ 2.45 ? 150 朵 · gini 0.667 · [50, 50, 50] setosa ✓ 50 朵 · gini 0 —— 一刀就全純 petal width ≤ 1.75 ? 100 朵 · gini 0.5 · [0, 50, 50] versicolor 54 朵 · gini 0.168 virginica 46 朵 · gini 0.043
根節點的 petal length ≤ 2.45——正是你剛剛在第 04 節手動找到的那一刀。 藍色葉子 gini = 0:setosa 一刀就被完美分出來。

讀樹小抄:每個節點四行字 = 切分條件 / gini / 樣本數 / 各類數量。 先把 max_depth 拉到 1 看「一刀樹」,再一層層加深,注意訓練與測試準確率怎麼分家。

06 · 視角

樹眼中的世界:橫平豎直的格子

每道是非題都長這樣:「某一個特徵 ≤ 某個值?」——所以每一刀都平行於座標軸。 把樹的所有預測塗在平面上,你會看到決策邊界永遠是矩形拼貼, 不會是斜線、不會是曲線。

這是決策樹的口音,一眼就能認出來。它也解釋了兩件事: 為什麼樹處理「特徵各自有意義」的表格資料特別強; 為什麼遇到斜向的分界時,它得用很多刀去階梯狀逼近。

07 · 陷阱

深度的代價:把雜訊背下來

樹每深一層,訓練準確率幾乎必漲——極端情況下每朵花自己一片葉子,訓練 100% 全對。 但那不是學習,是背答案:連量錯的、長歪的花都被寫成了規則。

max_depth → 準確率 甜蜜點 訓練集 ↗ 一路漲 測試集:先升後掉
我們真正在乎的是測試集(模型沒看過的花)。兩條線分岔的地方,就是模型開始背答案的地方。

右邊的實驗會把每個深度都訓練一次、畫出這張圖的真實版。 找到 iris 的甜蜜點之後想一想:為什麼「更多層」買不到「更準」?

08 · 實戰

換你動手

右邊最後一格是留給你的實驗區,三個挑戰由易到難:

LEVEL 1

criterion 改成 "entropy"(用資訊增益取代 Gini)。準確率變了嗎?樹長得一樣嗎?——體會「評分標準不同,結論常常相同」。

LEVEL 2

只用 sepal 兩個特徵訓練,看測試準確率掉到多少。這會用數字證實你在第 03 節「用眼睛」得到的結論。

LEVEL 3

把資料換成 load_wine()(13 個特徵、3 種酒)。同一套流程還能用嗎?哪些特徵被樹選進了前兩層?

09 · 帶走

把這棵樹帶回家

右上角的「下載 .py」會給你整個 notebook 的原始檔——它同時是一個普通的 Python 腳本。 在自己電腦上這樣繼續:

uvx marimo edit lesson.py

下一步往哪走:

  • 隨機森林——一棵樹會背答案,就種一百棵各看部分資料的樹投票。
  • 梯度提升樹(XGBoost / LightGBM)——讓每棵新樹專門修前面的錯,表格資料的常勝軍。
  • 它們的基本單位,都是你今天親手切過的這棵樹。
右側 Python 由 marimo + Pyodide (WebAssembly) 驅動,完全在你的瀏覽器內執行; 本頁不收集任何資料,你的修改只存在你的分頁裡。 圖中藍 / 橘 / 綠恆指 setosa / versicolor / virginica 三品種。
Python 環境載入中(首次約 30–60 秒)…讀完左邊第 1 節它就好了