PCA:讓資料自己說出該用什麼座標軸
一句話:把尺轉到資料真正散開的方向。這一關每一步都是「一句話 + 一張會動的圖」, 看不懂的名詞就到 ② 名詞表查,那裡全部用白話寫。
① 這關在解什麼問題
- 手上有什麼:12 個人,每人兩個數字 —— 身高(公分)、體重(公斤)。
- 想問什麼:這群人之間,真正的差異在哪裡?
- 卡在哪:高的人幾乎都比較重。兩欄講的是同一件事,一起看會把它數兩遍。
- 答案的方向:問題不在資料,在座標軸。公分和公斤是量測儀器給的,不是這群人散開的方向。
-
STEP 1
只看一欄,量到的都是同一件事
- 把 12 個點壓到橫軸(=只看身高):從 153 到 185,很寬。
- 再壓到縱軸(=只看體重):從 41 到 74,也很寬。
- 但兩邊寬的是同一件事:「這個人整體多大隻」。
- 「壓到某根軸上」的正式說法叫投影:從點垂直畫一條線到那根軸,落點就是投影。
青點=12 個人。綠點是壓到橫軸的影子, 橘點是壓到縱軸的影子。
-
STEP 2
那就不要只看橫的直的 —— 讓資料自己選一個方向
- 拿一條線繞著這團點轉一圈,每個角度都量一次「往這個方向看過去,這群人攤得多開」。
- 綠色線段的長度就是那個量。線段越長=這個方向越散。
- 轉到 45.2° 時線段最長 —— 那就是這團資料自己的方向,叫主軸。
- PCA 一句話講完:把尺轉到那個方向,然後用它當新的軸。
線轉了一圈多(0° 一路轉到 225°),最後停在線段最長的那個角度。 紫箭頭 v₁ 就是主軸(v 是 vector=向量/箭頭的縮寫,讀「v one」)。 線段的半長取 1σ(一個標準差),所以它量的就是「攤開的寬度」。
-
STEP 3
找到主軸之後,把整把尺轉過去
方向找到了,就把整把尺轉過去:網格也跟著轉,資料點的相對位置沒變——點沒動,是換了一把斜的尺來量。
青點 = 12 個人。整片網格繞著重心(=12 個人的平均位置)往右上方轉 45°: 水平那排線轉到跟 紫箭頭 v₁ 對齊,垂直那排線剛好垂直於它。 點沒跟著轉——換了一把斜的尺來量。
- 04 關教你給一個矩陣、找出它的特徵向量,但那個矩陣是我隨手寫的。
- 真實世界不會有人遞矩陣給你,遞給你的是一張表。
- 這關把那把刀對準資料自己長出來的矩陣:共變異數矩陣。
- 順便拔掉 03 關的鉤子 —— 我說過「非對角線總有辦法變成 0」,這關現場做給你看。
② 先把名詞講完(看不懂隨時捲回來)
下面每一節都會冒出字母。你不用背,看到不認識的就回這裡查。
白話名詞
| 名詞 | 白話是什麼 |
|---|---|
| 資料表 | 一張表格。這一頁的表是 12 列 × 2 欄:一列一個人,兩欄是身高和體重。 |
| 列 / 欄 | 列=橫的一排(一個人)、欄=直的一排(一個項目)。這兩個字後面一直會用。 |
| 矩陣 | 數字排成的方格表,就這樣。2×2 矩陣=2 列 2 欄,四個數字。 |
| 向量 | 一串數字,也可以看成從原點指出去的一支箭頭。這一頁的向量都是兩個數字(左右多少、上下多少)。 |
| 分量 | 向量裡的其中一個數字。v₁ = (0.7042, 0.7100) 的 x 分量是 0.7042、y 分量是 0.7100。 |
| 平均 | 全部加起來除以個數。這 12 人的平均是身高 167、體重 59。 |
| 偏差 | 一個人減掉平均。身高 185 的人偏差是 +18。 |
| 重心 | 所有點的平均位置,也就是這團資料的正中間。這 12 人的重心在 (167, 59)。 |
| 去中心化 | 把每一欄都減掉自己的平均。等於把尺上的 0 搬到這群人的正中間(重心)。 |
| 變異數 | 散開程度:把每個人的偏差平方、加起來、除以 n−1。數字越大=這群人差越多。(平方過,所以單位也被平方了,絕對值不用細究,看比例就好。) |
| 標準差 σ | 變異數開根號,把單位開回來。σ 讀「sigma」。身高的 σ ≈ 10.3 公分。 |
| 共變異數 | 兩欄一起變動的程度。身高大的時候體重也大 → 正的;一大一小 → 負的;沒關係 → 0。 |
| 共變異數矩陣 | 把上面那幾個數字排成 2×2:對角線=每一欄自己有多散,非對角線=兩欄糾纏多深。 |
| 相關係數 r | 共變異數除掉單位之後的版本,一定落在 −1 到 +1 之間。這份資料 r = 0.92,超黏。 |
| 投影 | 從一個點垂直畫線到某根軸,落點就是它在那根軸上的位置。 |
| 內積 | 兩串數字對位相乘、再全部加起來,得到一個數字。投影、變異數、共變異數底下都是它(01 關)。 |
| 單位向量 | 長度剛好等於 1 的箭頭。只負責指方向,長度統一成 1,讀出來的數字才是純座標。 |
| 正交 | 就是互相垂直(夾角 90°)。兩根新軸一定正交。 |
| 主軸 / 次軸 | 主軸=資料最散開的方向;次軸=垂直於它的那根,也是最不散的方向。 |
| 特徵向量 | 一個矩陣「自然的方向」(04 關)。在這一頁它有更具體的身分:就是主軸與次軸。 |
| 特徵值 | 配著特徵向量的那個數字。在這一頁它就是那根軸上的變異數。 |
| 對稱矩陣 | 沿對角線翻過來長得一模一樣的矩陣。共變異數矩陣一定對稱,所以它的特徵值一定是實數、特徵向量一定互相垂直。 |
| 特徵分解 | 「把一個矩陣的特徵向量與特徵值全部算出來」這個動作的名字。這一頁 LAB.M.eig2(C) 做的就是它。 |
| 二次型 | uTCu 這種「方向丟進去、吐一個數字出來」的算式的名字。在這一頁那個數字就是「往 u 看過去有多散」(④ 的大字讀數)。 |
| 載荷 loading | 新軸是舊欄位的加權組合,那一組權重就叫載荷。數值上就是特徵向量的分量。 |
| 解釋比例 | 一根軸的 λ 佔全部 λ 加起來的百分比,讀成「這團資料的差異有幾成發生在這根軸上」。這份資料主軸是 96.05%。 |
| 維度 | 描述一個人要用幾個數字。身高+體重=2 維;砍到只剩一個數字=1 維,這個動作叫降維。 |
| 殘差 | 降維之後,「重建回來的位置」離「真實位置」還差的那一段。圖上就是那些紅線。 |
| 標準化 | 這一頁講的標準化就是下面那列的 z-score,也就是 ⑦ 第三顆按鈕在做的事。 |
| z-score | 每一欄各自減平均、再除以自己的標準差。做完每欄的變異數都變成 1,單位被消掉。 |
符號
| 符號 | 讀作 | 它是什麼 |
|---|---|---|
| n | n | 有幾筆資料。這一頁 n = 12 個人。 |
| X | 大寫 X | 整張資料表:12 列 × 2 欄,而且每一欄都已經去中心化。 |
| XT | X transpose(轉置) | 把表沿對角線翻過來:原本的列變成欄。純粹是為了讓乘法對得上位。 |
| C | C(來自 covariance) | 共變異數矩陣,2×2。就是 03 關造出來的那個。 |
| XTX / (n − 1) | X 轉置乘 X,再除以 n 減 1 | C 的算式,不是新東西。除 n − 1 是樣本變異數的慣例(02 關講過)。 |
| u | u | 你手上那根可以隨便轉的候選方向,長度固定為 1。④ 的滑桿轉的就是它。 |
| θ | theta(讀「西塔」) | u 的角度。0° 是正右邊(只看身高),90° 是正上方(只看體重)。 |
| uTCu | u 轉置、C、u | 一個吃方向、吐一個數字的算式,那個數字是:投影到 u 之後那串數字的變異數。 |
| v1 v2 | v one、v two | 兩根新軸的方向(各是一支長度 1 的箭頭)。v₁ 叫主軸、v₂ 叫次軸,兩根一定垂直。 |
| λ1 λ2 | lambda one、lambda two | 兩根軸上的變異數。這份資料 λ₁ = 205.55、λ₂ = 8.45。 |
| PC1 PC2 | PC one、PC two | 某一個人在新軸上的座標。留意差別:v 是軸(全體共用一根),PC 是分數(每人一個)。 |
| k | k | 你決定留幾根軸。k = 2 是原封不動換軸,k = 1 才是降維。 |
| SSE | Sum of Squared Errors | 降維後每個人「被搬動的距離」平方,全部加起來。0 = 完全沒損失。 |
| RMSE | Root Mean Squared Error | SSE 除以人數再開根號 →「平均每個人被搬了多遠」。單位跟原始座標一樣。 |
- 01 關的投影:一個點在某方向上的座標 = 內積。
- 02 關的變異數:一串數字散不散開。
- 03 關的共變異數矩陣:把「往哪散」整包裝進一個 2×2。
- 04 關的特徵向量:矩陣的自然方向。
- 把這四個接起來,就是這一關的全部。
③ 主實驗:PCA 的五個步驟
五步做完,這團斜的資料會被轉正,而共變異數矩陣的非對角線會從 98.55 掉到 0。 先看動畫看結果,再自己按按鈕走一遍。
-
STEP 1~5
五步在做的事,其實只有一件:把斜的資料轉正
- 1. 原始資料:12 個人畫成 12 個點。
- 2. 去中心化:每欄減掉自己的平均,把 0 搬到這群人的正中間。(點沒動,動的是 0 的位置。)
- 3. 做出共變異數矩陣 C:四個數字排成 2×2。右上角是 98.55,不是 0 → 兩欄糾纏。
- 4. 取 C 的特徵向量:拿到主軸 v₁ 與次軸 v₂。
- 5. 轉到新軸上:整團轉 45.24°。同一格掉到 0 → 糾纏被解開。
左右是同一批人,只是換了一組軸來描述。 下面那張 2×2 就是共變異數矩陣:對角線=各自多散、非對角線=糾纏多深。
- 按鈕:上面那排 1~5 就是五個步驟,按下去看畫面怎麼變。
- 可以拖:任何一顆青點都能用滑鼠拖(只有第 5 步旋轉檢視中不能拖)。
- 「+ 加一個怪咖」:塞一個違反趨勢的人進去,看主軸被拉歪。
- 盯著熱力圖右上角那一格:第 3 步是 98.55,第 5 步變 0。這就是整關的重點。
- 第 4 步起會多出:紫箭頭 v₁、桃箭頭 v₂、一圈紫色虛線橢圓 —— 它叫 1σ 輪廓,就是把「離重心一個標準差」的位置連成一圈,兩個半徑正好是 √λ₁ = 14.34 與 √λ₂ = 2.91。
- 資料是合成的,不是真人。想換成你自己的資料,改檔案裡
RAW這個陣列就行。
④ 為什麼是「特徵向量」?自己轉一圈找答案
③ 的第 4 步我直接說「取共變異數矩陣的特徵向量就是主軸」。憑什麼?這一節不用相信我,你自己轉。
-
STEP 1
轉一圈,把每個角度的散開程度畫成一條曲線
- 左圖:方向線從 0° 轉到 180°,綠點是每個人在那個方向上的位置(=投影)。
- 綠點攤得越開,代表這個方向的變異數越大。
- 右圖:把「這個角度量到的變異數」畫成一條曲線。橫軸是角度、縱軸是變異數。
- 左右兩張圖同一個時間軸:左邊線轉到哪,右邊綠點就在曲線上的哪。
- 結果:曲線最高點 205.55 在 45.2°、最低點 8.45 在 135.2°,兩者剛好差 90°。
- 那個最高點的角度,正好就是共變異數矩陣 C 的特徵向量 v1 的方向。三件事是同一件事。
曲線長成漂亮的正弦波不是巧合:uTCu 展開之後就是 「常數 + 常數 × cos 2θ + 常數 × sin 2θ」,必定是週期 180° 的波。 而波只有一個最高點和一個最低點 —— 這就是「主軸只有一根、次軸必定垂直於它」的原因。
- θ = 0°(正右邊)=只看身高那一欄 → 變異數 106.18,就是 C 左上角那一格。
- θ = 90°(正上方)=只看體重那一欄 → 變異數 107.82,就是 C 右下角那一格。
- θ = 45°(斜著看)→ 變異數暴衝到 205.55,比只看單一欄的任一個都大快一倍。
- 下面的滑桿只是把這件事從 3 個角度變成 360 個角度,一個都不漏而已。
- 滑桿控制方向 u 的角度;「自動掃一圈」讓它自己轉完;「跳到最佳角度」直接跳到答案。
- 你的任務只有一個:把右邊那個大數字(=投影後的變異數)轉到最大。
- 紫色虛線花瓣叫玫瑰圖,它上面一顆點都不是人:它把「每個角度的變異數」畫成離中心的距離。 離中心越遠的方向=資料在那個方向越散。
- 再下面那條曲線跟玫瑰圖是同一份計算的兩種畫法:玫瑰圖用距離表示大小,曲線用高度表示大小。
- 特徵向量不是憑空定義出來的東西,它就是「投影後最散開」那個方向的答案。
- 特徵值就是那個最大的散開程度。
- 你轉滑桿在做的事,寫成一行是:找單位向量 u 讓 uTCu 最大。
- 而這題的解,恰好就是 C 的最大特徵值對應的特徵向量 —— 這不是巧合,這是特徵向量的另一個等價定義。
- 誠實標記:上面這句是結論,不是證明。「為什麼最大值一定發生在特徵向量上」要用二次型的最大值定理來證,這一頁不證它; 你先用滑桿把 0°~180° 全部掃過一遍,親眼確認它是真的。
⑤ 兩根新軸各自代表什麼意思?
直球回答:新軸是舊欄位的加權組合,那組權重就叫載荷。所以新軸永遠讀得出意義 —— 只要你去看權重。
-
STEP 1
讀載荷只有兩條規則
- 權重同號(都正、或都負)→ 這根軸在講「一起變大」的共同因子。
- 權重一正一負 → 這根軸在講「此消彼長」的對比因子。
- 整節就靠這兩條讀完,維度再高也是同一招。
- 載荷在數值上就是特徵向量的分量。「讀載荷」和「讀特徵向量」是同一個動作,只是統計圈與線代圈的叫法不同。
條往右=權重是正的、往左=負的;長度=權重的大小。
-
STEP 2
一個人的兩個舊數字,換成兩個新數字
- 拿 L 這個人(185 公分 / 72 公斤)當例子。
- ① 先沿主軸走 21.91 —— 這是他的 PC1,讀成「他有多大隻」。
- ② 再垂直偏出 3.63 —— 這是他的 PC2,讀成「同身高下偏瘦還是偏壯」。
- 兩步走完剛好回到他原本的位置:(185, 72) 和 (21.91, 3.63) 是同一個人的兩種寫法。
- PC1 = 0.704 × (身高 − 167) + 0.710 × (體重 − 59),就是「拿權重去加權」而已。
紫箭頭=沿主軸走的那一段(PC1)、 桃箭頭=再垂直偏出去的那一段(PC2)。
- 點表格任何一列 → 那個人會在左圖被綠圈圈起來,並畫出他的 PC1 與 PC2。
- 左圖兩根穿過原點的虛線:紫=主軸 v₁、桃=次軸 v₂。
- 要看出什麼:PC1 與 PC2 這兩個數字完整取代原本的 (身高, 體重),而且各有意思 —— 舊的兩欄做不到,因為它們都混著大隻程度。
| 代號 | 身高 | 體重 | PC1 | PC2 | 怎麼讀 |
|---|
- 身高/體重是「主成分好解釋」的最佳案例,我故意挑它。
- 真實資料裡,主成分經常是一坨看不出所以然的加權組合。
- 那時候正確反應是「這個主成分我讀不出來」,不是硬掰一個故事。
⑥ 只留一根軸:降維與重建
主軸吃掉 96.05% 的散開程度。那第二根能不能丟?丟了會掉多少東西?
-
STEP 1
丟掉次軸 = 把每個人壓到主軸上
- 每個人垂直落到主軸,只保留他在主軸上的位置(PC1)。
- 每人從兩個數字變成一個數字 —— 這就是降維。
- 紅線=他被搬動的距離,也就是這次降維在他身上造成的誤差。
- 每一條紅線都垂直於主軸,所以丟掉的東西一點都不神祕:就是垂直於主軸的那點差異,在這份資料裡叫胖瘦。
- 12 條紅線平方相加 = 92.96,剛好等於 λ₂ × 11 = 8.4511 × 11。(11 = n − 1,就是算變異數時除掉的那個數字。)
青點=真正的位置、綠點=只用主軸重建回來的位置、 紅線=兩者的差。
- 兩顆按鈕切換 k(=留幾根軸):「只用 1 根軸」每人只剩 PC1;「用 2 根軸」兩個數字都留。
- k = 1:綠點全部落在紫色主軸上(只剩一維,就只能長成一條線)。
- k = 2:紅線全部消失、誤差歸零 —— 兩根軸就把平面填滿了。
- 所以:降維是選項,換軸才是 PCA 本體。
k = 1 時 SSE = 92.96,而 λ₂ × (n − 1) = 8.4511 × 11 = 92.96,一模一樣 —— 你丟掉的誤差總量,正好就是你丟掉那根軸的變異數(再乘回自由度)。 這就是為什麼「解釋比例」可以直接拿 λ 來算,不必真的去量每一條紅線。
- 丟掉的不是雜訊,是「同身高下偏壯還是偏瘦」。它真實存在,只是變異最小。
- 所以判斷能不能降維,問的不是「解釋比例夠不夠高」。
- 要問的是:你接下來要回答的問題,會不會剛好落在你丟掉的那個方向上。
- 要比體型大小 → 丟得掉;要挑健身教練 → 你丟掉的正是你要的。
多維時 PCA 在幹嘛:4 科成績 → 2 根軸
- 兩維只能給直覺,PCA 真正在用的地方是幾十、幾百維。
- 這裡放 12 個學生的 4 科成績(國英數物,一樣是合成資料),做 4 → 2 的降維。
- 讀法完全一樣:看權重的正負號。同號 → 共同因子;一正一負 → 對比因子。
- 4×4 對稱矩陣的特徵分解
LAB.M沒有,所以這節用檔案內自己寫的 Jacobi 旋轉法算(見jacobiEig),並印出殘差自我驗證。
再提醒一次:λ 的單位就是「變異數」。這份資料是考試分數,所以 λ 的單位是「分數的平方」; λ 越大=那根軸上的分數被拉得越開。
| 成分 | λ | 解釋比例 | 累積 |
|---|
| 科目 | PC1 權重 | PC2 權重 |
|---|
| 學生 | 國 | 英 | 數 | 物 | PC1 | PC2 | 怎麼讀 |
|---|
⑦ 要不要先標準化?這題會決定你算出什麼
PCA 追的是變異數,而變異數有單位。所以換個單位記錄,答案就會變。
-
STEP 1
同一批人、同一天量的,只是把公分改記成公釐
- 身高 185 公分 = 1850 公釐。一個人的資料都沒改。
- 但身高那一欄的變異數乘了 100 倍,於是它直接把主軸搶走。
- 主軸角度從 45.24° 倒到 5.31° —— 幾乎變成「身高」本人,體重被無視。
- PCA 沒算錯,它就是在追變異數最大的方向;是你餵給它的單位讓身高變成巨人。
- 解藥:先做 z-score(每欄減平均、再除以自己的標準差),單位就被消掉了。
畫面把整張圖等比縮小 10 倍才塞得下,所以看起來像「體重被壓扁」—— 形狀跟「身高被拉長 10 倍」完全一樣。
- 三顆按鈕不是三批資料,是同一批人的三種記法:cm/kg、把身高改記成 mm、以及先做 z-score。
- 下面那張表永遠四種模式都列出來,方便直接對照。
- 畫面會自動框住當前資料,但兩軸永遠共用同一個比例尺,所以你看到的形狀就是 PCA 看到的形狀。
- z-score 模式下兩軸的單位變成 σ(幾個標準差),沒有單位。
| 模式 | 主軸角度 | 載荷(身高, 體重) | 主軸解釋比例 | 主軸在講什麼 |
|---|
- cm/kg(45.238°、96.05%)和 z-score(45.000°、96.05%)解釋比例一模一樣。這是巧合,不是規律。
- 原因:這份資料兩欄的變異數剛好差不多大(106.18 vs 107.82,只差 1.5%),z-score 幾乎等於沒縮放。
- 反例就在同一張表:mm/kg 那一列解釋比例 99.85%,z-score 之後掉回 96.05%。
- 差的那 4 個百分點,正是「胖瘦」被單位吃掉又還回來的量。
- 各欄單位不同(公分 vs 公斤 vs 元 vs 次數)時,先做 z-score。
- 標準化之後每欄變異數都是 1,共變異數矩陣就退化成 相關係數矩陣。
- 這時候 PCA 吃的其實是相關係數,跟你用什麼單位記錄完全無關(上表兩種單位的 z-score 結果一模一樣)。
- 反過來:各欄本來就同一種單位、同一個量級(四科成績、16 顆同型號感測器)→ 不要標準化, 那時候「哪一欄變異比較大」是真實資訊。
⑧ 數學長怎樣
整個 PCA 裸寫出來就五行,而且每一行都是前面四關的東西:
const mean = LAB.M.centroid(data); // 1. 重心(02 關的平均)
const X = LAB.M.center(data); // 2. 去中心化:把 0 搬到重心
const C = LAB.M.covMatrix(X, 1); // 3. 共變異數矩陣(03 關,ddof=1)
const eg = LAB.M.eig2(C).pairs; // 4. 它的特徵向量 = 資料主軸(04 關)
const pc1 = LAB.M.scores(data, eg[0].vector, mean) // 5. 每個人在主軸上的座標(01 關的投影)
符號版。第一式是共變異數矩陣的定義:
XT = 把 X 沿對角線翻過來(列變欄),純粹是為了讓乘法對得上位。
XTX = 把「每一欄」兩兩做內積:對角線是同一欄跟自己(=平方和),非對角線是兩欄互相的內積。
n − 1 = 自由度。扣掉平均之後,12 個偏差裡只有 11 個是自由的(最後一個被「總和必須為 0」綁死)。
所以 C 的每一格都是一個內積 —— 這就是主線那句「變異數與共變異數其實都是內積」的收尾。
第二式是 04 關的老朋友,只是 A 換成了 C:
C v = 把這個方向餵進共變異數矩陣。若結果跟 v 同方向,v 就是特徵向量(04 關的定義)。
「矩陣乘一個向量」怎麼算?矩陣的每一列跟這個向量對位相乘再相加,一列算出一個數字,湊成新的向量 —— 也就是每一列各做一次內積。這個算法在 04 關從頭教過,這裡只是拿來用。
λ = 特徵值。在 C 是共變異數矩陣的場合,它的意思非常實在:資料投影到 v 之後的變異數。
vTCv = 讀成「往 v 這個方向看過去,這團資料有多散」。④ 轉滑桿看到的大數字就是它。
λ1 / (λ1 + λ2) = 主軸的解釋變異比例。
兩式合起來就是這關的一句話:把資料做成 C,C 的特徵向量就是資料的主軸,特徵值就是那根主軸上的變異數。
⑨ 工程師的「原來如此」
- 500 檔股票的日報酬 → 做成 500×500 共變異數矩陣 → 特徵分解。
- 第一主成分幾乎必然是大盤:載荷全部同號(=所有股票一起漲跌),通常吃掉三到四成總變異。
- 第二、第三主成分才長出產業結構(科技 vs 傳統、循環 vs 防禦,載荷一正一負)。
- 要對沖大盤風險,你對沖的其實就是第一主成分。
- 一張 64×64 的灰階人臉是 4096 個數字。
- 取前 50 個特徵向量(每一個本身就是一張「臉的模板」,這就是 eigenfaces 這名字的來源)。
- 任何一張臉都能寫成這 50 張模板的加權組合 —— 4096 個數字壓成 50 個,還認得出是誰。
- 今天的版本只是換了外皮:1536 維的文字 embedding 進向量資料庫前,常先 PCA 降到 128~256 維。
- 16 顆加速度計貼在同一台機器上量振動,真正的訊號源可能只有兩三個。
- 所以 16 條時序的變異幾乎全集中在前幾個主成分,尾巴那十幾個 λ 小到接近量測底噪。
- 做法:投影到前 k 個主成分、其餘歸零、再重建回 16 條 —— 訊號乾淨很多。
- 這跟 ⑥ 玩的「投影再重建」是同一段程式,差別只在那裡把丟掉的當資訊,這裡當雜訊。
⑩ 拿去用之前 —— 五件教科書不講、但上線就會咬人的事
前面九節在回答「PCA 是什麼」。這一節換一種問題:你真的要把它接進系統裡。
1. 這套算法到幾維還跑得動?
- 成本:建 C 是 O(n · d2)、特徵分解是 O(d3)。
- d = 1536(一個典型的文字 embedding)時,C 本身就是 236 萬個數字,用 float32 存也要 9 MB —— 而它只是中間產物。
- 怎麼做:跳過 C,直接對去中心化後的 X 做 SVD。X 的右奇異向量就是 C 的特徵向量, 奇異值平方除以 n − 1 就是特徵值。
- 數值上也穩得多:組 C 的時候每個數字都被平方過一次,小的特徵值容易被浮點誤差吃掉。
- 只要前 k 根軸的話,連完整 SVD 都不用做 —— randomized SVD 或 04 關那個「乘乘乘」只算你要的那幾根。
- 這也是為什麼 sklearn 的 PCA 底層走 SVD 而不是 eig。接口整理在 全景 01 關那條「SVD 捷徑」。
2. 那我 30 欄到底該砍到剩幾欄?
可操作的尺有四把,只有最後一把真的可靠。
拿本頁 ⑥ 那 4 科成績的四個 λ 當現場範例,畫成 scree 圖(長條由高到低,選 k 最常看的一張圖):
- scree 肘點:找長條「從陡然變平」的那一折,折點前面全留。上圖 PC2 → PC3 掉了快 15 倍,所以取 2 根。 毛病:真實資料常常沒有肘點,是一條平滑的滑梯 —— 兩個人看會看出兩個答案。
- 累積 90% / 95%:從上往下加,超過門檻就停。上圖累積到 PC2 是 97.46%,門檻設 90% 也是取 2 根。 毛病:門檻是你自己拍的,跟下游任務沒有任何關係。
- Kaiser 準則 λ > 1:留特徵值大於 1 的軸。 毛病:只有對相關係數矩陣(也就是先做過 z-score)才有意義。 直接套在上圖那四個 λ(單位是「分數平方」)上就是四根全留,等於沒篩。
- 下游任務的 cross-validation:把 k 當超參數,k = 1, 2, 5, 10… 各跑一次你真正要跑的模型,比驗證集分數。 這是唯一真正可靠的一把 —— 它問的正是你該問的那句話:「砍到這裡,我要做的事變差了嗎」。
3. 新資料進來怎麼辦?fit 和 transform 的區別
PCA 是 fit 出來的,有三組參數必須存下來:重心、每欄的標準差、特徵向量。 新資料只能拿舊參數 transform,不可以重新 fit。
- 為什麼:重新 fit 會算出不一樣的重心與軸,兩批資料的 PC1 根本是兩個不同的東西,放在一起比大小毫無意義。
- 這是 PCA 上線最常見的 bug,而且它不會報錯,只會讓你的數字慢慢失真。
- 怎麼做:
fit只在訓練資料上跑一次,把 mean / sd / V 存檔;新資料只做(x − mean) / sd再跟 V 做內積。 - 同源的坑叫資料洩漏:在全部資料上先 z-score 或先做完 PCA,然後才切 train / test —— test 那一半的平均、標準差、主軸方向都滲進參數裡了。順序永遠是「先切,再 fit」。
4. 主軸的正負號,明天重算會不會翻面?
會。正負號是任意的(坑 3 講過),所以你得自己釘一個符號規範,並且把它跟參數一起存起來。
- 什麼時候會翻:換 library、升版本、資料多進一筆、甚至換一顆 CPU —— 只要迭代法的起始向量不同。
- 數學上完全等價(同一根軸),但你存下來的 PC 分數會整欄變號,下游那條「PC2 > 0 就標成偏壯」的規則會全部反過來。
- 而且不會有任何錯誤訊息。
- 怎麼做:fit 完立刻做符號規範化,例如強迫絕對值最大的那個分量為正(本頁
jacobiEig就這樣做)。 選哪一種不重要,重要的是它跟參數一起被存下來,而且下次不准變。
5. PC1 = −17.67 的單位是什麼?能直接餵下游嗎?
PC 分數是「各欄的加權組合」,所以單位是混的。要餵給吃距離的模型之前,通常還得再標準化一次。
- PC1 = 0.704 × (身高 − 167) + 0.710 × (體重 − 59) —— 0.704 個公分加 0.710 個公斤,加出來的東西沒有名字。
- 所以 PC1 = −17.67 只能跟同一批人的其他 PC1 比大小,不能讀成「他矮了 17.67 公分」。
- 更會咬人的是尺度:PC1 和 PC2 的變異數差 24 倍(205.55 vs 8.45)。 直接丟進 kNN、k-means 這種吃歐氏距離的東西,PC1 會壓死 PC2。
- 這正是 02 關警告過的「大單位吃掉小單位」,只是換了個座標系又犯一次。
- 解法:把每根軸除以自己的 √λ(這個動作叫 whitening),讓每軸變異數都變成 1。 但 whitening 同時把「PC1 比 PC2 重要」這個資訊也抹掉了。
這五件事都不是數學問題 —— 特徵向量的定義解決不了任何一件。 它們是「數學懂了之後才會遇到的問題」。
⑪ 踩坑
- 沒扣平均就算 XTX,你量到的是「這團資料離原點多遠」,不是「它長什麼形狀」。
- 這份資料的重心在 (167, 59),離原點 177;而它自己只散開 10 左右。
- 結果:第一主成分會直接指向 (167, 59),解釋比例高到 99.9%,看起來超漂亮 —— 但它講的是「這些人都在畫面右上角」這種廢話。
- 單位大的欄位會霸佔主軸,而且它不會報錯。
- 你會得到一個看起來很正常、實際上只是在講「哪一欄的數字比較大」的主成分。
- 判斷方法很簡單:兩欄單位不同就先 z-score。細節在 ⑦。
- PCA 的目標裡完全沒有「可解釋性」這一項,它只管變異數最大。
- 身高體重好解釋是運氣(剛好一個共同因子 + 一個對比因子)。
- 特徵向量的正負號是任意的:(0.71, −0.70) 和 (−0.71, 0.70) 是同一根軸。
- 所以「PC2 高分代表偏瘦還是偏壯」不能背,要現場去看載荷的符號。
- 下面這團點明顯有結構(一個環),但它沿著任何一個直線方向的散開程度都差不多。
- 所以 PCA 給你兩個幾乎一樣大的特徵值、兩根隨便挑的軸,等於什麼都沒說。
- 馬蹄形、螺旋、分群資料都是同一類失手。這種時候要換工具(kernel PCA、t-SNE、UMAP、autoencoder), 不是把 PCA 的參數調來調去。
⑫ 這關回答了什麼
找出資料的特徵向量之後,那到底代表什麼意思?
代表你拿到了一組新的座標軸,而且這組軸是資料自己選的。
- 第一根指向資料最散開的方向;第二根垂直於它,指向剩下最散開的方向。
- (1) 讀意義:看每根軸的權重(載荷)由舊欄位怎麼組成,就知道它在講什麼事(⑤)。
- (2) 降維:把變異數很小的軸整根丟掉,維度直接砍下來(⑥)。
- (3) 解糾纏:換到新座標系之後,各欄之間的共變異數變成 0,原本互相污染的欄位變成互不相關的獨立座標(③ 的 step 5)。
二維資料算出來的兩個新軸,各自代表什麼?
用這份身高體重資料直接回答,因為答案是從權重讀出來的,不是我掰的:
- 主軸的權重 (+0.70 身高, +0.71 體重):兩個都正、而且差不多大 → 「身高和體重一起增加」。
- 所以主軸就是這個人整體多大隻,它吃掉 96% 的變異 —— 這群人的差異,96% 只是體型大小。
- 次軸的權重 (+0.71 身高, −0.70 體重):一正一負 → 「身高加分、體重扣分」。
- 所以次軸就是同樣身高之下偏瘦還是偏壯(分數高=偏瘦)。它只佔 4%,卻是唯一在講胖瘦的那根軸。
- 丟掉它,你就再也分不出這兩個人誰比較壯 —— 例如 F(165, 53) 與 E(163, 60): 只留主軸還分得出誰大隻(PC1 −5.67 vs −2.11),但「同身高下誰壯」這件事被抹平了(PC2 +2.80 vs −3.54,全部歸零)。
- 通則:權重同號 → 共同因子(一起變大);權重一正一負 → 對比因子(此消彼長)。
特徵向量是矩陣的還是資料集的?
只有矩陣才有特徵向量。
- 「資料集的特徵向量」是簡稱,真正的意思是「這份資料的共變異數矩陣的特徵向量」。
- 流程一定是:資料 →(去中心化)→ 做成共變異數矩陣 → 這個矩陣才有特徵向量。
- 少了中間那一步,「找資料的特徵向量」是沒有定義的操作。
- 同一份資料可以做成好幾種矩陣(共變異數矩陣、相關係數矩陣、圖的鄰接矩陣、Gram 矩陣),每一種的特徵向量講的是不同的事。
- 先問「是哪個矩陣」,再問「特徵向量是什麼意思」。整理在 全景 01 關的「矩陣 vs 資料」。
為什麼一定要先去中心化?
因為不扣平均的話,你量到的是位置,不是形狀。
- XTX 算的是「每個點到原點的距離結構」。
- 原點是 (0, 0),可是這群人在 (167, 59) 附近 —— 離原點 177,而他們彼此的差異只有 10 左右,差了 17 倍。
- 於是第一主成分會被「大家都在右上角」綁架,指向 (167, 59) 的方向。
- 扣掉平均之後,原點被搬到重心,XTX 量的就變成「彼此之間怎麼散開」,也就是形狀。
- 在 ③ 的 step 2 可以直接看到這一步在做什麼。
為什麼我們要 care 特徵向量?它到底解決了什麼問題?
它解決的是:你手上的座標軸是別人給的,而它們互相糾纏。
- 公分和公斤這兩根軸都混著「大隻程度」,所以你沒辦法乾淨地問「這群人差在哪」。
- 共變異數矩陣的非對角線 98.55 就是這個糾纏的量化值。
- 特徵向量給你一組新軸,讓非對角線變成 0 —— 糾纏被解開,每根軸各管一件事。
- 換句話說,它的用途是把一個「混在一起」的東西拆成「彼此獨立的幾個方向」。
- 04 關用它拆解「一個矩陣反覆作用會把向量帶去哪」;這關用它拆解「一份資料的變異由哪幾個獨立方向組成」。同一把刀,兩種用法。
降維之後丟掉的是什麼?什麼時候不該降?
丟掉的是垂直於保留軸的那些方向上的差異。
- 在這份資料裡,只留主軸就是丟掉「胖瘦」:體型大小完整保留,同身高下誰壯誰瘦被抹平 (⑥ 那些紅線全都垂直於主軸)。
- 不該降 (1):你要回答的問題剛好落在小變異方向上 —— 異常偵測、瑕疵檢測、罕見事件常藏在最後幾個主成分裡。
- 不該降 (2):資料結構不是線性的(環狀、螺旋、多群),PCA 找不到,見坑 4。
- 不該降 (3):你需要可解釋的原始欄位 —— 跟法務解釋「為什麼拒貸」時,你沒辦法說「因為他的 PC3 太低」。
- 判斷標準不是「解釋比例夠不夠高」,而是被丟掉的方向跟你的問題有沒有關係。
什麼時候要先做標準化?
各欄的單位不同(公分 vs 公斤 vs 元 vs 次數)時就要做。
- PCA 追的是變異數,而變異數帶單位:身高從 cm 改記成 mm,資料一個數字都沒變,主軸卻從 45.24° 倒到 5.31°。
- 反過來:各欄本來就同一種單位、同一個量級(四科成績、16 顆同型號感測器)→ 不要標準化, 那時候「哪一欄變異比較大」是真實資訊。
- 三顆按鈕自己按一遍就有感覺:⑦ 要不要先標準化。
- 注意那節表格的陷阱 —— cm 和 z-score 的解釋比例剛好一樣是巧合,不是規律。
內積 → 變異數其實是內積 → 共變異數也是內積 → 共變異數矩陣 C → C 的特徵向量就是資料主軸 → PCA。 線性代數 01 到 05 這五關串成的那條線,到這裡閉合。
接下來要往哪走,看你想解決哪個問題:
- 想知道 SVD 怎麼直接吃一張長方形的資料表(不必先組出 C 這張方形小表, 也就是 ⑩ 第 1 點那個「上到幾百維就不要組 C」的正解)→ 07 SVD:轉一下、拉一下、再轉一下。 如果想先把「正交矩陣」這個零件補齊再過去,順路先走 06 空間補完。
- 想把這一頁那顆 1σ 橢圓當成一把尺來用,回答「這個新來的人算不算離群」→ 機率統計 05 橢圓的真身:拿 C 當一把尺。 那一關會把 λ 和 v₁ 從「主軸」改讀成「量距離的單位」—— 同一顆橢圓,換一種用法。
想先確認自己真的懂了再往前,就去 全景 01 全景地圖與自我驗收 做一次費曼測試:用國中生聽得懂的話,把 PCA 講一遍。