🗺️ AI 學習與考證地圖
中級科目三程式實戰 · 非監督分群

一個特徵霸佔了 99.77% 的變異:
分群之前,為什麼要先 StandardScaler?

K-means 量「誰離誰近」、DBSCAN 量「誰在誰的鄰域裡」——兩個都是靠距離吃飯的演算法。而距離這種東西,只要有一欄的數字特別大,它就只聽那一欄的話。本頁用 Wine 資料實跑給你看:未縮放時分群「其實只用一欄」,而且連同類的兩瓶酒都會被量成天涯海角。

閱讀模式

00題目

同一批數值特徵的量尺差異很大,研究者將縮放與 K-means 放在同一 Pipeline;若末端改為以距離判定鄰域的 DBSCAN,也有相同的尺度考量。此處在分群前使用 StandardScaler 的主要理由為何?

from sklearn.cluster import KMeans                     # 拿出 K-means 分群工具
from sklearn.pipeline import make_pipeline             # 拿出「串管線」的快速寫法
from sklearn.preprocessing import StandardScaler       # 拿出標準化工具
cluster_pipe = make_pipeline(                          # 組管線:先縮放、再分群
    StandardScaler(),                                  # 第一站:把每欄調成同一量尺
    KMeans(n_clusters=3, random_state=42, n_init=10)  # 第二站:分 3 群(起點試 10 次)
)                                                      # 管線組裝完成
labels = cluster_pipe.fit_predict(X)                   # 一口氣:學縮放 → 轉換 → 分群,回傳群號

先說「距離為什麼在乎量尺」

想像你要判斷「哪些人條件相近」,手上兩欄資料:身高(公尺,1.5~1.9)年薪(元,300,000~1,600,000)。把兩欄直接代進距離公式,身高差 0.3 跟年薪差 300,000 加在一起——身高連小數點都排不上,「像不像」完全由薪水說了算。這不是薪水比較重要,只是它的數字比較大

本題的 Wine 資料一模一樣:13 個化學檢測值裡,proline(脯胺酸)的量尺是 278~1680,其他欄多半在 0.1~5 之間。量尺差了兩三個數量級,距離公式裡誰說話,根本不用比。

StandardScaler 做的事一句話:把每一欄各自「減掉自己的平均、除以自己的標準差」,變成z 分數——每欄的平均變 0、標準差變 1,大家站上同一個量尺。之後距離公式裡,每個特徵才有平等的發言權。這跟「重要性」無關——它不判斷誰重要,只是拆掉「單位大聲」這個不公平的麥克風

先點開看:歐氏距離怎麼算?StandardScaler 是什麼?分群跟分類差在哪?

不熟 AI 專有名詞?你需要先認識下列名詞

點擊後出現漸進式說明:白話說明 → 說清楚一點 → 常見錯誤與考點。

分群這件事
分群 clustering非監督學習群號不是標籤ARI 怎麼量分群好壞
兩個靠距離吃飯的演算法
K-means質心 centroidinertian_initDBSCANeps 與 min_samples
量尺與距離
歐氏距離量尺 scaleproline 那一欄
縮放工具箱
StandardScalerz 分數MinMaxScaler 對照離群值與縮放
管線與流程
Pipelinemake_pipelinefit_predict縮放為什麼進 PipelineWine 資料集

不熟 Python?你需要先認識下列名詞

點擊後出現漸進式說明

把工具拿進來
importfrom模組 module
存東西、設數值
= 指派變數與命名關鍵字引數3、42、10 整數
括號、排版與呼叫
( ) 呼叫括號為什麼可以換行寫行尾的逗號. 點運算子方法 method

01逐行拆解:第 1 行到第 8 行

八行,一行一行走完。右上角的「看位置」可以把這一行放回完整程式裡看。

第 1 行拿出 K-means 分群工具
from sklearn.cluster import KMeans   # 從「分群」抽屜拿出 K-means

sklearn.cluster分群演算法的抽屜:KMeans、DBSCAN、AgglomerativeClustering(階層分群)都住這裡。K-means 的玩法:先猜 k 個「群中心」,把每筆資料分給距離最近的中心,再把中心移到自己群員的平均位置,反覆到穩定。

注意「距離最近」四個字——它的每一步都在算距離。這就是整題的伏筆:距離一被某欄綁架,K-means 就跟著被綁架。

相關名詞:K-means質心分群

第 2 行拿出「串管線」的快速寫法
from sklearn.pipeline import make_pipeline   # 把好幾站串成一條生產線的工具

make_pipelinePipeline 的快速版:把幾個步驟依序丟進去,它自動串成一條「生產線」並自動取好每一站的名字(用類別名的小寫:本題兩站叫 standardscalerkmeans——實跑確認)。

跟正式版 Pipeline([("scaler", ...), ("km", ...)]) 的差別只在「要不要自己命名」。功能一模一樣:對管線做的每個動作,會依序流過每一站

相關名詞:make_pipelinePipeline

第 3 行拿出標準化工具
from sklearn.preprocessing import StandardScaler   # 每欄減均值、除標準差的縮放器

sklearn.preprocessing前處理抽屜。StandardScaler每一欄各自做兩件事:減掉這欄的平均、除以這欄的標準差——輸出就是 z 分數:「這個值比平均高/低幾個標準差」。

本站實跑(Wine):標準化後每一欄的平均都是 0、標準差都是 1;proline 欄的值域從「278~1680」變成「−1.49 ~ +2.97」——跟其他欄站上同一個量尺,但彼此的相對大小完全沒變(誰高誰低、高多少個標準差,原封不動)。

相關名詞:StandardScalerz 分數MinMaxScaler 對照

第 4 行開始組管線
cluster_pipe = make_pipeline(   # 組生產線,取名 cluster_pipe(括號先不關)

呼叫 make_pipeline(...),把成品貼上 cluster_pipe 的名牌。括號沒關——第 4 到 7 行是同一句話。放進去的順序就是生產線的順序:資料會先流過第 5 行那站,再流到第 6 行那站。

相關名詞:= 指派為什麼可以換行

第 5 行第一站:標準化——本題的靈魂
    StandardScaler(),   # 第一站:先把 13 欄調成同一量尺

生產線的第一站。它排在 KMeans 前面,所以 KMeans 看到的永遠是「已經站上同一量尺」的資料——距離公式裡 13 個特徵平權發言

為什麼要放進管線、而不是自己先轉換好再丟給 KMeans?因為管線會把「怎麼轉換」記住(每欄的平均與標準差都存在這一站裡)——之後拿新資料來 predict,會自動用同一套轉換,不會忘記、也不會拿新資料重算。這正是上一系列 Pipeline 頁講的紀律,分群版。

相關名詞:縮放為什麼進 PipelineStandardScaler

第 6–7 行第二站:K-means,分 3 群
    KMeans(n_clusters=3, random_state=42, n_init=10)   # 第二站:分 3 群、起點試 10 次
)                                                     # 括號關上,管線組裝完成

三個設定:n_clusters=3 要分成 3 群(k 就是這個 3);random_state=42 固定亂數;n_init=10「隨機起點試 10 次、留下最好的一次」——K-means 的結果會受初始中心影響,多試幾個起點、取群內距離平方和(inertia)最小的那次,是標準保險。

為什麼 n_init 要明寫?因為 sklearn 新版把預設值改成 "auto",明寫 10 可以讓行為固定、老程式不噴警告——考題照抄實務寫法。

相關名詞:n_initinertiaK-means

第 8 行fit_predict:一口氣做完,拿回群號
labels = cluster_pipe.fit_predict(X)   # 學縮放 → 轉換 → 分群,回傳每筆的群號

fit_predict 是「訓練+回答」二合一:管線先讓 Scaler 學會每欄的平均與標準差並轉換資料,再讓 KMeans 在轉換後的資料上分群,最後回傳每一筆資料的群號(0、1、2 的一排數字)。

群號不是「標籤」。0/1/2 只是「第幾群」的任意編號——哪群叫 0 純看演算法先碰到誰,換個 random_state 連編號都會洗牌。本站實跑:真實品種前 10 瓶都是「品種 0」,分群給的群號卻都是「2」——群分得對,編號本來就對不上。這是選項 A 的死因預告。

注意分群沒有 y——fit_predict(X) 裡只有 X。沒有人給答案,演算法只憑「誰跟誰近」自己把資料分堆,這就是非監督學習。

相關名詞:fit_predict群號不是標籤非監督學習

02量尺解剖:一個特徵獨佔 99.77% 的變異

題目說「數值特徵的量尺差異很大」。Wine 有多大?把 13 欄的標準差攤開:proline 的標準差 314,第二名 magnesium 只有 14,其他 11 欄全部不到 3.5。換算成「各欄佔總變異的比例」更嚇人:

互動實驗室:量尺放大鏡切換原始/標準化,看發言權怎麼分配
本站實跑:原始尺度下 proline 一欄獨佔總變異的 99.77%、加上 magnesium 就是 99.98%——其餘 11 個特徵合計拿不到 0.02% 的發言權。標準化後 13 欄各佔 1/13 ≈ 7.7%,回到平權。注意這跟「proline 重不重要」毫無關係——它只是用了比較大的單位(脯胺酸以 mg/L 計、其他多是比值),純粹的單位霸凌。

03距離被誰綁架:兩瓶酒的距離解剖

K-means 與 DBSCAN 用的都是歐氏距離

\[ d(a,b) \;=\; \sqrt{\sum_{j=1}^{13} (a_j - b_j)^2 } \]

公式對 13 個特徵一視同仁——但誰的差值平方大,誰就主導總和。把實際的兩瓶酒拆開看:

互動實驗室:距離解剖器挑一對酒,看距離是誰貢獻的
兩瓶的距離
356.3
原始單位
最大單欄貢獻
99.3%
proline
其餘 12 欄合計
0.7%
距離平方的佔比
最傷的證據是第三組:同品種的兩瓶酒。它們只是 proline 差比較多,原始距離就飆到 655——比跨品種那兩對(356、115)都遠!標準化後回到 2.60,反而是三對裡最近的。未縮放的距離量出來的不是「像不像」,是「proline 差多少」——把這種距離餵給任何演算法,結果都不能用。

相關名詞:歐氏距離proline 那一欄量尺

04K-means 對照實跑:未縮放=「只用一欄分群」

把兩個版本都跑出來,跟真實品種(釀酒葡萄的三個品種)對答案,用 ARI 打分:

未縮放 K-means 的 ARI
0.371
跟真實品種對不太起來
標準化後的 ARI
0.897
三群純度 100%/94%/95%
未縮放 vs「只用 proline 一欄」
1.000
兩者的分群完全相同
右邊那張卡是全題最狠的一句話:把其他 12 欄全部丟掉、只用 proline 一欄跑 K-means,得到的分群跟「未縮放用全部 13 欄」一模一樣(ARI = 1.000)。你以為你用了 13 個特徵,其實距離只聽 proline 的——另外 12 欄等於沒進場。這就是選項 B 說的「大尺度特徵不當地主導結果」的極端版。
互動實驗室:分群對照散點同一批酒、三種著色,看誰分得像
座標=標準化資料的 PCA 前兩軸(保留 55.4% 變異,僅供視覺化)

05DBSCAN 也一樣:eps 被單位綁架

題目特別補一句「末端改為以距離判定鄰域的 DBSCAN,也有相同的尺度考量」。DBSCAN 的核心參數 eps 是「鄰域半徑」——半徑是一個帶單位的長度:在原始尺度上,這個單位實質上就是 proline 的單位,其他特徵的差異在半徑裡根本量不出來。實跑掃一輪:

互動實驗室:DBSCAN eps 之旅原始尺度怎麼調都不對勁
分出幾群
4
噪點不算群
噪點(離群)筆數
20
共 178 瓶
ARI(對真實品種)
0.274
1 為完美、0 為隨機
兩個尺度的病徵不同但同源:原始尺度下 eps 從 10 掃到 400——不是碎成一地噪點,就是全部黏成一團,中間「看起來能分」的 eps=30 其實只是照 proline 切段;標準化後 eps 至少變成有意義的旋鈕(2.3 附近有結構)。同時誠實說:Wine 這種橢圓雲資料本來就不是 DBSCAN 的主場(它擅長不規則形狀與抓噪點),所以縮放後 ARI 也只有 0.384——縮放是必要條件,不是萬靈丹。題目只考「尺度考量相同」這一層,這一層是鐵的。

相關名詞:DBSCANeps 與 min_samples

06為什麼包成 Pipeline?

把 Scaler 跟分群器串進同一條管線,買到三件事: 順序不會忘——每次都是「先縮放、再分群」; 轉換參數被記住——每欄的平均與標準差存在 scaler 站裡,之後新資料 predict 自動用同一套轉換; 若要搭配交叉驗證或網格搜尋(例如掃 n_clusters),縮放會只在訓練折上學——跟本系列第一頁(Pipeline 防洩漏)同一條紀律。

實跑小抄:make_pipeline 自動把兩站命名為 standardscalerkmeans(類別名小寫);KMeans 的 n_init=10 在這份資料上 10 次起點都收斂到同一組中心(inertia 1277.9)——它是保險絲,資料難的時候才看得出差別。

07四個選項一句話收工

A讓每個樣本自動取得正確的人工標籤概念錯置

分群是非監督學習——從頭到尾沒有「正確標籤」這種東西,fit_predict 回傳的 0/1/2 只是任意群號(實跑:品種 0 的酒拿到的群號是 2)。縮放器更不可能生出標籤,它只是改量尺。

BK-means 與 DBSCAN 都依賴距離,未縮放時大尺度特徵可能不當地主導結果正確

實跑全套佐證:proline 獨佔 99.77% 變異、兩瓶酒的距離 99% 由它決定、同品種的距離比跨品種還遠、未縮放 K-means 與「只用 proline 一欄」完全等價(ARI 1.000)、標準化後 ARI 0.371 → 0.897;DBSCAN 的 eps 在原始尺度下失去意義。距離導向演算法 + 量尺懸殊 = 必須先縮放。

C保證 K-means 與 DBSCAN 對任何資料都產生相同群集不可能的保證

兩個演算法的原理根本不同(切球形 vs 依密度長形狀),縮放只是讓它們「都拿到公平的距離」,不會讓它們答案一致——實跑同一份標準化資料:K-means ARI 0.897、DBSCAN 最好 0.384。看到「保證」「任何資料」這種絕對句,先懷疑。

D將所有特徵轉成只有 0 與 1,從而完全消除離群值張冠李戴

三重錯誤:StandardScaler 輸出是連續的 z 分數(實跑 proline 欄變 −1.49~+2.97,不是 0/1);「壓到 [0,1] 區間」是 MinMaxScaler、「只剩 0 與 1」是 Binarizer/OneHot——別家的事;而且標準化不消除離群值(實跑:把一瓶 proline 乘 10,標準化後 z = 12.9,還是巨大離群)。

回到題目:現在再作答一次

再看一次同一段程式。這次你知道 StandardScaler 那一站在守什麼了。

同一批數值特徵的量尺差異很大,研究者將縮放與 K-means 放在同一 Pipeline;若末端改為以距離判定鄰域的 DBSCAN,也有相同的尺度考量。此處在分群前使用 StandardScaler 的主要理由為何?

cluster_pipe = make_pipeline(                          # 組管線
    StandardScaler(),                                  # 先把 13 欄調成同一量尺
    KMeans(n_clusters=3, random_state=42, n_init=10)  # 再用距離分 3 群
)                                                      # 組裝完成
labels = cluster_pipe.fit_predict(X)                   # 回傳群號(不是標籤)

08自我檢測

八題,全部都是本題的延伸。答錯會直接告訴你錯在哪。

09重點整理

  1. 第 4 到 7 行是同一句話(括號沒關就能換行);make_pipeline 自動幫兩站取名 standardscalerkmeansfit_predict(X)只有 X 沒有 y——分群是非監督學習。
  2. StandardScaler 對每欄各自「減平均、除標準差」,輸出 z 分數:每欄平均 0、標準差 1,相對大小原封不動
  3. K-means 與 DBSCAN 都靠距離吃飯:K-means 把點分給最近的質心,DBSCAN 用 eps 半徑判定鄰域——距離被綁架,兩個都跟著被綁架。
  4. 量尺懸殊的實跑長相:Wine 的 proline 標準差 314、其他欄多在 3.5 以下;proline 獨佔總變異 99.77%
  5. 距離解剖:兩瓶酒的距離平方 99% 來自 proline;同品種兩瓶的原始距離(655)比跨品種(356、115)還遠——未縮放的距離量的是「proline 差多少」,不是「像不像」。
  6. 未縮放 K-means =「只用 proline 一欄分群」(ARI 1.000 完全等價):你以為用了 13 個特徵,其實 12 個沒進場。與真實品種的 ARI 僅 0.371;標準化後升到 0.897(三群純度 100%/94%/95%)。
  7. DBSCAN 的 eps 是帶單位的半徑:原始尺度掃 10~400 不是碎成噪點就是黏成一團;標準化後 eps 才變成有意義的旋鈕。同時誠實記:Wine 不是 DBSCAN 的主場(最好 ARI 0.384)——縮放是必要條件,不是萬靈丹
  8. 群號不是標籤(A 的死因):0/1/2 是任意編號,換 random_state 連編號都洗牌;實跑品種 0 的酒拿到群號 2。
  9. 縮放不保證不同演算法同結果(C 的死因):同一份標準化資料,K-means 0.897 vs DBSCAN 0.384——原理不同,答案本來就不同。
  10. StandardScaler ≠ 0/1、≠ 消除離群值(D 的死因):輸出是連續 z 分數(−1.49~+2.97);[0,1] 是 MinMaxScaler、0/1 是 Binarizer;人造離群值 ×10 標準化後 z=12.9 依然巨大。
  11. 包成 Pipeline 的三個好處:順序固定、轉換參數被記住(新資料自動同一套轉換)、搭配 CV/網格時只在訓練折學縮放(防洩漏,同系列第一頁的紀律)。
  12. 正確答案 BK-means 與 DBSCAN 都依賴距離,未縮放時大尺度特徵可能不當地主導結果——每個字都有實跑數字對應。
完整程式碼