MODULE 07 — Singular Value Decomposition

SVD:轉一下、拉一下、再轉一下

這一關只講一件事:不管那台搬點機長得多奇怪,它做的事都只是「先轉一轉、再沿著兩條軸拉一拉、最後轉回來」。 三個動作,就這樣。看懂之後,連 04 關那把刀啃不動的長方形資料表都拆得開。

先認識三個字母

這一節開始會一直出現 V、Σ、U 三個字母(還有 V 右上角的小 T)。 它們只是三個動作的代號,不是新的數學。

V 唸「vee」、Σ 唸「sigma」、U 唸「you」; V 右上角的小 T 唸「transpose」,中文叫轉置(把欄改寫成列)。 先不用管細節 —— 接下來一節講一個動作,字母就是那個動作的名字。

⓪ 第 1 節:三個動作的第一個「轉」—— Vᵀ 到底在乘什麼

這一節不用任何先備知識。先看 SVD 的公式長怎樣、三個動作各是什麼, 再從「一個點被搬走」一路走到 Vᵀ × X。六步,每步一句話配一張會動的圖。

先看全貌,再看細節

SVD 說的是一件事:任何一台「搬點機」A,都可以拆成「先轉一轉 → 沿兩根軸拉一拉 → 再轉回來」三步。 寫成公式就是這一行。

A = U · Σ · Vᵀ

A 是要拆的那台機器;右邊三個是拆出來的三個動作。

出發 一個圓、一個點

出發:一個半徑 1 的圓,加上圓上的一個點。 灰虛線圓之後一直留著當比例尺,讓你看得出東西被拉大了還是縮小了。

① Vᵀ 轉 圓還是圓,點換位置

① Vᵀ 轉(唸「V transpose」)—— 把座標軸轉到主軸上(主軸是什麼,STEP 3 講)。 圓還是圓:只換方向,一點都沒變大變小。 這一節 (1/3) 細講

② Σ 拉 圓被拉成橢圓

② Σ 拉(唸「sigma」,就是希臘字母的 S)—— 沿兩根新軸各拉一個倍數,這台 A 是一根拉 3 倍、一根拉 1 倍(1 倍=不動)。 三個動作裡只有這一步會改變大小。 (2/3) 細講 →

③ U 轉回 擺到最後的位置

③ U 轉回(唸「you」)—— 把拉好的形狀轉到最後該在的位置,這時候才等於「直接用 A 搬一次」。 形狀一樣沒變,只是換方向擺。 (3/3) 細講 →

同一個圓、同一個點,由左往右依序做完三個動作 —— 最右邊那格就等於「直接用 A 搬一次」。 每一格的灰虛線圓都是原本的圓,拿來比大小用。

輸入空間

原本的網格:橫線豎線整整齊齊,笑臉是正的。

坐標空間

先轉 45°、再橫向拉 3 倍(= ① Vᵀ + ② Σ):網格變成菱形,笑臉被拉扁。

輸出空間

直接用 A 搬一次(= ① Vᵀ + ② Σ + ③ U):網格變成斜的,笑臉斜著拉長。

這一張圖看的是整個空間被搬動:連網格線都在動,不是只有一個點。 動畫開始時,三格長得一模一樣(都是原本的網格):左格不動、留著當原本; 中格做完 ① Vᵀ(轉 45°)+ ② Σ(橫向拉 3 倍); 右格再多做 ③ U(轉回),等於直接用 A 搬一次。 一句話:左=原本的圖、中間=轉好拉好的圖、右=被 A 搬完的圖。

三個動作,一節講一個 —— 這是這三節的地圖
  • (1/3) 就是這一節:Vᵀ 先轉一轉。 (六步從頭講,一個名詞都不跳過。)
  • (2/3):Σ 沿兩根新軸各拉一個倍數,那兩個倍數叫 σ₁、σ₂ → Σ 那一節
  • (3/3):U 再轉回來,並且把三個動作接起來對帳,看它真的等於 A → U 那一節
  • 乘法從右邊做起:先 Vᵀ、再 Σ、最後 U。 (跟唸的順序剛好相反 —— 因為算 A×X 時,離 X 最近的 Vᵀ 先碰到它。)
  • 為什麼先講 Vᵀ?因為它是第一個碰到點的動作;後面兩個動作都建立在「軸已經轉好了」這件事上。
  1. STEP 1

    先講兩個字母:X 是一個點,A 是「對這個點做的事」

    • X=平面上一個點,也可以看成從原點指出去的一根箭頭;它就是兩個數字,這裡取 X = (2, 1)。 (資料表的一列也是這種一串數字,只是不只兩個。)
    • A=一台搬點機:一條固定規則,說「任何點該搬到哪」。規則全寫在四個數字裡。 (這種數字表叫矩陣;橫的一排叫列、直的一排叫欄。)
    • A × X=把 X 搬走的結果。算法只有一句:一列配一個點,對位相乘再相加。 (下面圖上寫成「第一列 · X」——「·」和「×」在這裡是同一個意思:乘。)
    • 算一次就懂:(2, 1) 被搬到 (5, 4)。 (原點 (0, 0) 永遠不動,乘出來還是 (0, 0)。)
    • 下面那張表怎麼看:X 行文寫成 (2, 1) 是橫著寫省位置,真的拿去乘的時候要立成直的一欄(2 在上、1 在下),才跟 A 的「列」對得上位。
    A = 2112 X = 21
    A(搬點的規則) X(一個點) A×X(搬到哪) 2 1 1 2 × 2 1 = 5 4 ① 第一列 · X 2×2 + 1×1 = 5 ② 第二列 · X 1×2 + 2×1 = 4 「矩陣 × 點」的規則就這樣,後面每一次乘法都是這一招。
    x y X = (2, 1) (5, 4) = A×X 原點不會動;A 只是把每個點照同一條規則搬走。

    左:A 的第一列配上 X 得到 5、第二列配上 X 得到 4。 右:同一件事在平面上 —— 青箭頭是 X, 綠點被搬到 (5, 4)。

  2. STEP 2

    想看清楚 A 在幹嘛?丟一個圓進去當試紙

    一個點只給你一個答案。圓上有各個方向的點,一次全丟進去,就看得出 A 對「每個方向」各做了什麼。

    出來永遠是橢圓 —— 某個方向被拉長、另一個方向被壓扁。 (橢圓是我們用來觀察 A 的工具,不是 A 的一部分。)

    橢圓好用的地方:它的長軸一眼就指出 A 最用力的方向。

    x y 圓上的 (1, 0) (2, 1) 圓上每一個點,都落在橢圓上。

    灰虛線=丟進去的圓(試紙);青色=出來的橢圓。 圓上的 (1, 0) 落到橢圓上的 (2, 1)。

  3. STEP 3

    橢圓被拉最長的那個方向,就叫主軸 v₁

    「主」的意思是這台 A 最用力的方向;v 是 vector(向量/箭頭)的縮寫,v₁ 唸「v one」。

    垂直於它的那根叫 v₂,是拉最少的方向。這台 A 的 v₁ 在 45°。

    x 長軸 45° v₁ v₂

    紫線是長軸,方向就是 v₁(45°); 桃箭頭是 v₂,一定垂直於它。

  4. STEP 4

    V 就是「兩根主軸排成一張表」

    • 兩根主軸各是兩個數字:v₁ = (0.71, 0.71)、v₂ = (−0.71, 0.71)。 (v₂ 為什麼往左上、帶負號?跟 v₁ 垂直的方向有兩個(左上、右下),習慣選逆時針轉 90° 的那個 —— 就是左上,所以第一個數字是負的。)
    • 把它們直的寫進一張 2×2 的表,一根佔一欄 —— 這張表就叫 V。
    • 欄=直的一排、列=橫的一排,這兩個字後面一直會用到。
    • 0.71 哪來的?v₁ 在 45°,而 45° 就是 y = x 那條線,線上的點長這樣:(1, 1)。當軸用的方向規定長度要是 1 —— 軸只負責指方向,長度統一成 1,讀出來的數字才是純座標。(1, 1) 的長度是 √(1² + 1²) = √2 ≈ 1.41(這就是畢氏定理:兩股各平方相加再開根號),兩個數字各除以它就變成 0.71。
    兩根主軸(長度都是 1) v₁ v₂ V(一根主軸佔一欄) 0.71 0.71 −0.71 0.71 v₁ 這一欄 v₂ 這一欄 兩欄合起來,就是 V。

    紫箭頭 v₁ 的兩個數字寫進第一欄、桃箭頭 v₂ 寫進第二欄。 灰虛線圓=半徑 1,提醒你這兩根箭頭的長度都剛好是 1。

  5. STEP 5

    把 V「翻一下」寫成 Vᵀ,才能拿去乘點

    從整條公式看這一步
    A = U · Σ · Vᵀ

    Vᵀ 是三個動作的第一個 —— 離 X 最近、第一個碰到點。這一節把「它在乘什麼」講完。

    • Vᵀ 唸「V transpose」,中文叫轉置:同一組數字,把「欄」改寫成「列」,沒有新東西。
    • 為什麼要翻?因為乘法是一列配一個點(STEP 1)。要問「這個點在 v₁ 上有多少」,v₁ 就得躺成一列。
    • 翻完的兩列就是兩根新軸:c₁(第一列=v₁)、c₂(第二列=v₂)。 (c₁ 就是躺下來的 v₁:同一根軸、同樣兩個數字,換個名字只是提醒你「這是拿來乘的那一列」。)
    • 所以座標變換就寫成:新座標 = Vᵀ × 舊座標。
    Vᵀ = 0.710.71−0.710.71
    V(主軸排成「欄」) Vᵀ(改成排成「列」) 0.71 −0.71 0.71 0.71 v₁ v₂ 轉置 c₁ c₂ 0.71 0.71 −0.71 0.71 第一欄(直的)v₁ → 第一列(橫的)c₁ 第二欄(直的)v₂ → 第二列(橫的)c₂ 數字一個都沒改,只是躺下來。
    畫面的橫向(不會動) c₁ =主軸 v₁ c₂

    左:V 的兩欄(直的)翻成 Vᵀ 的兩列(橫的),數字一個都沒變。 右:Vᵀ 做的事 —— 兩根軸一起轉 45°,c₁ 停在橢圓的長軸上; 灰虛線是畫面本身的橫直方向,它不會動。 這張是「軸轉、點不動」;下一步 STEP 6 的右圖反過來畫成「點轉、軸不動」—— 兩張圖是同一件事的兩種畫法。

  6. STEP 6 · 這一節的重點

    Vᵀ × X:跟 STEP 1 同一種乘法,只是把 A 換成 Vᵀ

    • 規則一模一樣:一列配一個點,對位相乘再相加。
    • 第一個新座標 = 第一列 c₁ · 點 —— 在問「這個點在 v₁ 方向上有多少?」
    • 第二個新座標 = 第二列 c₂ · 點 —— 同一句話問 v₂ 一次。
    • 差別只在:A 會把點搬走,Vᵀ 只換讀數、不改長度(2.24 進、2.24 出)。 (2.24 是這根箭頭的長度,一樣用畢氏定理算:√(2² + 1²) = √5 ≈ 2.24。)
    新座標 = (第一列 · 點, 第二列 · 點) x′ = 0.71×2 + 0.71×1 ≈ 2.12 · y′ = −0.71×2 + 0.71×1 = −0.71
    x′、y′ 那一撇代表新座標(舊的就寫 x、y)。0.71 是 1/√2 四捨五入來的,所以第一行寫 ≈ —— 用精確值算是 3/√2 ≈ 2.12。
    Vᵀ(兩列=兩根新軸) 點 X 新座標 0.71 0.71 −0.71 0.71 × 2 1 = 2.12 −0.71 ① 第一列 · 點 0.71×2 + 0.71×1 ≈ 2.12 ② 第二列 · 點 −0.71×2 + 0.71×1 = −0.71 兩列各算一次,就得到兩個新座標。
    c₁ 軸 c₂ 軸 (2, 1) 2.12 −0.71 灰虛線圓=長度 2.24,轉完還是 2.24。

    左:兩列分別跟 (2, 1) 逐項乘加,亮出 2.12 跟 −0.71 (0.71 是四捨五入過的,所以第一個寫 ≈ 2.12)。 右:同一件事在平面上 —— 點往右轉 45°、新軸擺正不動,轉完就在 c₁ 軸上讀到 2.12、在 c₂ 軸上讀到 −0.71(跟著點一起轉的那兩條灰線是舊軸,留著讓你對照)。 把軸往左轉 45°(STEP 5 那張),跟把點往右轉 45°(這張),讀出來的數字一模一樣 —— 這張圖選了轉點,因為新軸擺正比較好讀。

這一節的結論

Vᵀ × X 就是「先把座標軸轉到主軸上」—— SVD 的第一步。

下一節 (2/3) 就把 Σ 做完:轉好之後,沿著這兩根新軸各拉一個倍數(這台 A 是 3 倍跟 1 倍)。 Σ 裡面那兩個倍數,就寫成小寫的 σ₁、σ₂(唸「sigma one、sigma two」):σ₁ = 第一根軸 c₁ 拉幾倍、σ₂ = 第二根軸 c₂ 拉幾倍, 所以這台 A 是 σ₁ = 3、σ₂ = 1。 (3 跟 1 就是 STEP 2 那個橢圓的長、短半徑 —— 半徑 1 的圓被拉成長 3、短 1。)

接下來兩節把剩下兩個動作補完: ⓪ (2/3) Σ:沿兩根新軸各拉一個倍數, 然後 ⓪ (3/3) U:拉完轉回來,三個接起來就是 A。 (想先看整關的地圖,也可以直接往下走 ① 這關在解什麼問題; σ 跟 U 的進階版在 ④。)

c₁ c₂ ×3 σ₁ = 3、σ₂ = 1

預告:轉完之後,圓沿著 c₁ 被拉成 3 倍、沿 c₂ 不動。 圖右下的 σ₁ = 3 就讀成「第一根軸拉 3 倍」、σ₂ = 1 讀成「第二根軸拉 1 倍,也就是沒拉」。

⓪ 第 2 節:三個動作的第二個「拉」—— Σ 沿兩根新軸,各拉一個倍數

上一節把座標軸轉到主軸上了,圖形本身一點都還沒變大變小。 這一節做第二個動作:在新軸上把圖拉開。五步,每步一句話配一張會動的圖。

從整條公式看這一步
A = U · Σ · Vᵀ

Σ 是三個動作的第二個 —— 中間這一步,把形狀拉開。

這一節要回答的一句話

Σ 就是「把轉好的形狀,沿兩根新軸各拉一個倍數」 —— 三個動作裡只有這一步會改變大小,另外兩個都只是轉方向。

  1. STEP 1

    Σ 做的事:沿 c₁ 拉 3 倍、沿 c₂ 拉 1 倍

    • 畫面上這兩根軸就是上一節轉好的 c₁、c₂ (c₁ 是躺下來的主軸 v₁,上一節 STEP 5 講過)。
    • 丟進去的還是那個半徑 1 的圓(⓪ 的試紙)。
    • 拉法很死板:只沿著這兩根軸拉,不歪不斜,所以圓被拉成一個「正的」橢圓。
    • 1 倍就是不動 —— c₂ 那個方向乘 1,等於什麼都沒做。
    c₁ 軸 c₂ 軸 拉 3 倍 (3, 0) (0, 1) 沒動 —— 拉 1 倍 灰虛線圓=丟進去的圓(半徑 1) 沿 c₁ 拉 3 倍、沿 c₂ 拉 1 倍 —— 圓就變成一個「正的」橢圓。

    灰虛線=原本的圓;青色=拉完的橢圓。 右邊那顆點從 (1, 0) 被拉到 (3, 0);上面那顆點在 (0, 1),從頭到尾沒動。

  2. STEP 2

    那兩個倍數有名字:σ₁、σ₂(唸「sigma one、sigma two」)

    • 大寫 Σ 是那張表,小寫 σ 是表裡面的數字。 (同一個希臘字母的大小寫,就像 A 和 a。)
    • σ₁ = 第一根軸 c₁ 拉幾倍、σ₂ = 第二根軸 c₂ 拉幾倍。這台 A 是 σ₁ = 3、σ₂ = 1。
    • 正式名字叫奇異值。(「奇異」只是 singular 的直譯,跟「很奇怪」沒關係。)
    • 兩條規矩:不會是負的(負號可以丟給旁邊的轉,所以拉的部分一律取正)、 而且大的排前面(σ₁ ≥ σ₂)。
    「拉幾倍」畫成長條,一根軸一根 0 倍 1 倍 2 倍 3 倍 c₁ 軸 σ₁ = 3 c₂ 軸 σ₂ = 1 大的排前面:σ₁ ≥ σ₂ ≥ 0 —— 不會有負的倍數。

    紫條是 σ₁(c₁ 拉 3 倍)、桃條是 σ₂(c₂ 拉 1 倍)。 長條多長就是拉幾倍;σ₂ 只有一格,代表「乘 1 = 沒拉」。

  3. STEP 3

    Σ 寫成表:只有斜線上有數字,其他都是 0

    • 把 σ₁ 放左上、σ₂ 放右下,其他兩格填 0。
    • 那條「左上到右下」的斜線叫對角線;只有對角線有數字的表,叫對角矩陣。
    • 為什麼其他格是 0?因為兩根軸各拉各的、互不干擾 —— c₂ 的讀數不會跑去影響 c₁ 的結果。
    • (0 在這裡的意思是「這一格完全不參與」,不是「這裡沒東西」。)
    Σ = 3001
    Σ(一根軸一個倍數) 3 0 0 1 σ₁ 放這裡(c₁ 拉 3 倍) σ₂ 放這裡(c₂ 拉 1 倍) ↖ 這條斜線叫「對角線」 另外兩格是 0:兩根軸各拉各的,c₂ 不會影響 c₁。 只有對角線有數字的表,就叫「對角矩陣」。

    左上那格是 σ₁ = 3、右下那格是 σ₂ = 1, 斜線畫出來的就是對角線。另外兩個 0 是「這一格不參與」的意思。

  4. STEP 4 · 這一節的重點

    Σ × 新座標:還是「一列配一個點」那一招

    • 上一節算出來的新座標是 (2.12, −0.71),直接拿來乘。
    • 第一列 (3, 0) 配上點:3×2.12 + 0×(−0.71) —— 0 那一項直接消失。
    • 第二列 (0, 1) 配上點:0×2.12 + 1×(−0.71) —— 只剩下原本那個數字。
    • 所以乘一個對角矩陣,就是「每個座標各乘自己的倍數」,沒有別的。
    拉完 = (σ₁ × 第一個座標, σ₂ × 第二個座標) 3 × 2.12 ≈ 6.36 · 1 × (−0.71) = −0.71
    一樣提醒:2.12 是四捨五入過的,用精確值算是 9/√2 ≈ 6.36。
    Σ(兩列=兩個倍數) 上一節的新座標 拉完 3 0 0 1 × 2.12 −0.71 = 6.36 −0.71 ① 第一列 · 點 3×2.12 + 0×(−0.71) ≈ 6.36 ② 第二列 · 點 0×2.12 + 1×(−0.71) = −0.71 乘 0 的那一項直接消失 —— 這就是「互不干擾」的長相。

    跟 ⓪ STEP 6 完全同一種乘法,只是矩陣換成 Σ。 因為 Σ 有兩個 0,每一列其實只剩一項活著 —— 第一個座標乘 3、第二個座標乘 1,就這樣。

  5. STEP 5

    回頭看 ⓪ 那顆橢圓:長短半徑就是 σ₁ 和 σ₂

    • ⓪ STEP 2 把圓當試紙丟進 A,出來一顆斜的橢圓。
    • 現在拉出來的是一顆正的橢圓:長半徑 3、短半徑 1。
    • 這兩顆是同一顆橢圓 —— 只差最後那一轉(下一節的 U 做的事)。
    • 所以「橢圓被拉多長」這件事,答案一直都寫在 σ 裡: 長半徑 = σ₁、短半徑 = σ₂。
    c₁ 軸 c₂ 軸 長半徑 = σ₁ = 3 短半徑 = σ₂ = 1 淡的那顆是 ⓪ 的斜橢圓 —— 同一顆,還沒轉回去 ⓪ 丟圓進去出來的橢圓,長半徑 3、短半徑 1 —— 就是 σ₁ 和 σ₂。

    實線是這一節拉出來的「正橢圓」; 淡淡那顆斜的是 ⓪ STEP 2 直接用 A 搬出來的橢圓。 兩顆一樣胖一樣長,只差一個角度 —— 那個角度就是下一節 U 要補的。

這一節的結論

Σ 就是「沿兩根新軸各拉一個倍數」,那兩個倍數叫 σ₁、σ₂。 它是三個動作裡唯一會改變大小的一步,寫成表就是「只有對角線有數字」。

現在圖已經被拉開了,但它還躺在「新軸」的世界裡、還是正的。 下一節 (3/3) 用 U 把它轉到最後的位置,並且把三個動作接起來對帳一次 → ⓪ (3/3) U。

⓪ 第 3 節:三個動作的第三個「轉回來」—— U 拉完再轉回來,三個動作接起來就是 A

前兩節轉完也拉完了,但東西還擺在半路上。 這一節做最後一個動作,然後把三個動作接起來對帳一次 —— 看它是不是真的等於「直接用 A 搬一次」。

從整條公式看這一步
A = U · Σ · Vᵀ

U 是三個動作的最後一個 —— 把拉好的形狀轉到最終位置。

這一節要回答的一句話

U 就是「把拉好的形狀,轉到最後該在的位置」。 跟 Vᵀ 一樣只轉方向、不改大小 —— 但它不是把 Vᵀ 那一轉抵銷掉, 因為中間已經拉過了。

  1. STEP 1

    現在的處境:形狀對了,方向還差一個角度

    • 上一節拉出來的橢圓是正的:長軸躺在 c₁ 上。
    • 但 ⓪ STEP 2 直接用 A 搬出來的橢圓是斜的:長軸指在 45° 那個方向。
    • 兩顆一樣長、一樣胖,只差一個角度 —— 差的就是最後這一轉。
    • 所以 U 要做的事只有一件:把整個形狀轉到那個角度去。
    現在手上:正的橢圓 灰軸=兩顆共用的參考線 A 搬出來的:斜的 差 45° 一樣長、一樣胖,只差一個角度 —— 這就是 U 要補的那一轉。

    實線=上一節拉完的正橢圓;淡的那顆=⓪ 直接用 A 搬出來的斜橢圓。 兩顆的長短半徑完全一樣(3 和 1),差的只有角度。 (灰軸是兩顆共用的參考線:實線那顆的長軸躺在上一節那根 c₁ 上,淡的那顆是照原本的 x/y 軸畫的。 U 這一轉,就是把前者搬到後者。)

  2. STEP 2

    U 做的事:整個轉過去,剛好蓋住

    • 把正橢圓整個轉 45°,它就跟 A 搬出來的那顆完全重合。
    • 形狀一點都沒變 —— 轉不會把長的變短、也不會把胖的變瘦。
    • 轉完之後,橢圓的長軸指向哪,就叫 u₁ 那個方向。 (u 是 vector 的另一組名字,跟 v 一樣是「一根箭頭」。)
    • 到這裡三個動作全部做完,圖形就停在 A 該把它放的位置。
    淡的是目標:A 搬出來的橢圓 灰軸=兩顆共用的參考線 完全重合 ✓ 形狀沒變,只換了方向 u₁ 長軸指的方向

    青色實線那顆整個轉 45°,轉完剛好蓋住淡色那顆。 青點跟著一起走,證明是「整張圖一起轉」,不是重畫一顆。 轉完長軸指的方向就是 u₁。 (這個 45° 是照原本的 x/y 軸量的 —— u₁ 一直都是用原本那套軸講的方向。)

  3. STEP 3

    「轉出去又轉回來」不是白忙一場嗎?因為中間拉過了

    • 沒有中間那一拉:轉出去再轉回來,圖形一模一樣,等於什麼都沒發生 —— 那才叫白轉。
    • 有中間那一拉:轉出去是為了「把要拉的方向擺正」,拉完再轉回來,圖形真的變形了。
    • 順序不能換:先擺正、再拉、再擺回去。先拉再轉,拉的方向就錯了。
    • 還有一件事要講清楚:U 跟 Vᵀ 不保證是同一個轉法。 這台 A 剛好是對稱矩陣(沿「左上 → 右下」那條對角線翻過來一模一樣: 右上角和左下角都是 1;⑧ 那裡會再用到這個詞), U 才剛好把 Vᵀ 的角度轉回去;一般的 A,兩邊轉的角度完全可以不一樣。
    沒有中間那一拉 回到原樣:什麼都沒發生 有中間那一拉(Σ) 真的變形了:這才是 A 做的事 兩格前半段一樣:都先轉 45°(圓轉了還是圓,看青點)。差別只有中間那一拉。

    左邊沒有 Σ:先轉 45°、再轉回 45°,圓還是那個圓、青點也回到原位 —— 白轉。 右邊前半段一模一樣(也先轉 45°;圓轉了還是圓,所以只有青點看得出來轉過了), 只是中間多插一次「沿橫向拉 3 倍」,轉回來就變成一顆斜橢圓。 兩格唯一的差別就是中間那一拉。

  4. STEP 4

    U 寫成表:一根新方向佔一欄,跟 V 同一個規矩

    • u₁ = 轉完之後長軸指的方向,這台 A 是 45°,也就是 (0.71, 0.71)。
    • u₂ 垂直於它,是 (−0.71, 0.71)。(一樣選逆時針那個方向。)
    • 把兩根直的寫進一張 2×2 的表,一根佔一欄 —— 這張表就叫 U。
    • 這台 A 的 U 跟 V 剛好長得一模一樣,因為它是對稱矩陣 (沿「左上 → 右下」那條對角線翻過來一樣);一般的 A 不會這樣,U 和 V 是兩張不同的表。
    U = 0.71−0.710.710.71
    兩根新方向(長度都是 1) u₁ u₂ U(一根方向佔一欄) 0.71 0.71 −0.71 0.71 u₁ 這一欄 u₂ 這一欄 兩欄合起來,就是 U。

    淡色橢圓是轉完的結果,u₁ 就沿著它的長軸。 跟 STEP 4 的 V 一樣:一根方向寫成一欄,灰虛線圓提醒你兩根箭頭長度都是 1。 (⓪ STEP 1 那張表也用了這兩個顏色,但那裡標的是 A 的兩列。 顏色在每張圖裡只表示「第一個 / 第二個」,不代表跨圖是同一個東西。)

  5. STEP 5

    U 怎麼拿去乘:它不用翻,因為它做的是「組回來」

    • 先擋掉一個一定會卡住的問題:V 要翻成 Vᵀ 才能乘,U 為什麼不用翻成 Uᵀ?
    • Vᵀ 在問問題:「這個點在 v₁ 上有多少?」問一根方向,那根方向就得躺成一列 —— 所以 V 一定要翻(⓪ STEP 5、STEP 6 講過)。
    • U 在組東西:把「沿 u₁ 走 6.36、沿 u₂ 走 −0.71」這兩段接回一個點。 u₁、u₂ 本來就直立擺在 U 的欄裡,直接拿來當方向剛剛好,不用翻。
    • 同一件事兩種讀法,算出來一樣:照欄讀=兩根方向各按倍數走再相加; 照列讀=一列配一個點。下面的圖用「照列」那一種,跟前面每一次乘法同一招。
    • 負號一定要原樣寫進去:U 的第一列是 (0.71, −0.71),點的第二個數字也是 −0.71, 兩個負號相乘變成加 —— 這是最容易算錯的一格。
    • 「列」跟「欄」不要搞混:U 的第一列 (0.71, −0.71) 不是 u₁ —— u₁ 是 U 的第一欄 (0.71, 0.71)。(拿去乘的是「列」,方向本身是「欄」; 同一張表兩種讀法,STEP 4 那張圖標的是欄。)
    第一列 (0.71, −0.71) · (6.36, −0.71) = 0.71×6.36 + (−0.71)×(−0.71) = 4.516 + 0.504 = 5.020 ≈ 5.02
    第二列 (0.71, 0.71) · (6.36, −0.71) = 0.71×6.36 + 0.71×(−0.71) = 4.516 − 0.504 = 4.012 ≈ 4.01 中間那兩個數刻意不四捨五入,你才跟得上:0.71×6.36 = 4.5156 → 4.516、0.71×0.71 = 0.5041 → 0.504。 (如果中間只寫兩位,第二列會變成 4.52 − 0.50 = 4.02,跟答案 4.01 差一格,那是四捨五入的錯覺不是你算錯。)
    照欄讀是同一個答案:6.36 × u₁ + (−0.71) × u₂ = 6.36×(0.71, 0.71) + (−0.71)×(−0.71, 0.71) = (4.516, 4.516) + (0.504, −0.504) = (5.020, 4.012)。
    0.71 和 6.36 本身也是四捨五入過的;用精確值(1/√2、9/√2)算,剛好就是 5 跟 4。
    U(拿兩列去乘) 拉完的座標 轉回來 = A×X 0.71 −0.71 0.71 0.71 × 6.36 −0.71 = 5.02 4.01 精確值就是 (5, 4) 第一列 ≠ u₁(u₁ 是第一欄) ① 第一列 (0.71, −0.71) 配上點 (6.36, −0.71) 0.71×6.36 + (−0.71)×(−0.71) = 4.516 + 0.504 ≈ 5.02 ② 第二列 (0.71, 0.71) 配上點 (6.36, −0.71) 0.71×6.36 + 0.71×(−0.71) = 4.516 − 0.504 ≈ 4.01 兩個負號相乘變成「+」—— 這是最容易算錯的一格。 中間刻意留三位:只寫兩位會變成 4.52 − 0.50 = 4.02,跟答案差一格。

    跟 ⓪ STEP 6、(2/3) STEP 4 完全同一種乘法,只是矩陣換成 U。 第一列那兩個 −0.71 相乘是正的 0.504,所以第一列是「4.516 加 0.504」;第二列才是「4.516 減 0.504」。 (中間值留三位小數是故意的 —— 只寫兩位的話第二列會算成 4.52 − 0.50 = 4.02, 跟答案 4.01 差一格,那是四捨五入的錯覺,不是你算錯。 另外 紫/桃在這張圖裡標的是「第一列 / 第二列」, 跟 STEP 4 那張標「u₁ 欄 / u₂ 欄」的顏色不是同一件事。)

  6. STEP 6 · 這三節的高潮

    三個動作接起來,真的等於 A

    • 拿同一個點 X = (2, 1),照順序做三次乘法。
    • Vᵀ 轉:(2, 1) → (2.12, −0.71) (⓪ STEP 6 算過)
    • Σ 拉:(2.12, −0.71) → (6.36, −0.71) ((2/3) STEP 4 算過)
    • U 轉回:(6.36, −0.71) → (5, 4) (上一步 STEP 5 一格一格拆給你看過:5.02 和 4.01,用精確值剛好是 5 跟 4。)
    • 而 ⓪ STEP 1 直接算 A × X 就是 (5, 4) —— 一模一樣。 這就是 A = U · Σ · Vᵀ 在說的事。
    出發 X (2, 1) × Vᵀ ── 轉 (2.12, −0.71) × Σ ── 拉 (6.36, −0.71) × U ── 轉回 (5, 4) ⓪ STEP 1 直接用 A 搬一次,答案也是 (5, 4) ✓ 三個動作接起來 = A。這就是 A = U · Σ · Vᵀ 的意思。

    同一個點被三個動作依序處理:轉 → 拉 → 轉回。 最後落在 (5, 4),跟 ⓪ STEP 1「直接用 A 搬一次」的答案完全一樣。

這三節(⓪ 1/3 ~ 3/3)的總結論

A = U · Σ · Vᵀ 現在每一個字母你都認識了:

  • Vᵀ:把座標軸轉到主軸上(只轉方向)。
  • Σ:沿兩根新軸各拉 σ₁、σ₂ 倍(唯一會改變大小的一步)。
  • U:把拉好的形狀轉到最後的位置(只轉方向)。

接下來 ① 這關在解什麼問題 會告訴你「為什麼需要這個拆法」; ③ 讓你自己拉滑桿當那台機器; ④ 是把任何矩陣反過來拆開的完整版。

① 這關在解什麼問題

這一關只教一件事,而且結論現在就給你,後面才慢慢解釋為什麼:

整關的結論,先看這個

拿任何一個矩陣,把它想成一台會把圖形弄變形的機器。 不管那台機器多奇怪,它做的事都可以拆成下面這三個動作,照順序做完:

動作一 先轉一轉

把整張圖繞著原點轉一個角度。形狀完全沒變,只是換了個方向擺。

數學家寫成 Vᵀ · 白話:「轉」的那個矩陣
動作二 沿兩條軸拉一拉

橫向拉成幾倍、直向拉成幾倍,兩個方向各拉各的、互不干擾。只有這一步會改變大小。

數學家寫成 Σ · 白話:「拉」的那個矩陣
動作三 再轉回來

再繞著原點轉一個角度,把拉好的東西擺到最後該在的位置。形狀一樣沒變。

數學家寫成 U · 白話:「轉回來」的那個矩陣

把一個矩陣拆成這三個動作的作法,就叫 SVD (Singular Value Decomposition,中文譯「奇異值分解」; 「奇異」只是 singular 的直譯,跟「很奇怪」沒關係,不用被這個詞嚇到)。

如果你只想知道 SVD 是什麼,上面這樣就夠了。 接下來這一節要解釋的是另一個問題:已經有 04 關的特徵向量了,為什麼還需要它? (特徵向量:被矩陣搬完、方向不變的箭頭。) 答案是 04 關那把刀有三個地方會卡住。

卡點一:資料表通常是長方形的

你手上有一張表:200 個使用者 × 50 部電影的評分,共 10000 個數字。 你想問的問題很自然:

你真正想問的

「這 10000 個數字裡,真正的骨架是什麼?是不是其實只有三、四種『口味』在主導 —— 有人愛動作片、有人愛文藝片、有人只看新片 —— 剩下的都只是這幾種口味的加權組合,再加一點雜訊?」

A 200 列 × 50 欄,長方形 v:50 個數字 Av:200 個數字 =? 進去:v 有 50 格 出來:Av 有 200 格 兩邊長度不一樣 → 等號寫不出來

卡點一:A 吃 50 個數字、吐 200 個數字。把「進去」跟「出來」攤平比長度 —— 50 格 vs 200 格, A v = λ v 連寫都寫不出來。

卡點二:就算是正方形,也不保證拆得開

04 關那一節你已經玩過兩個反例 —— 正方形一樣會卡:

卡點三:05 關的 PCA 會先造一張你不想要的大表

欄數 = 1536 → C 是 1536 × 1536 = 2,359,296 個數字 你為了「找主軸」先造了一張 236 萬格的中間表 —— 這張表你根本不想要。
而且組 C 的過程中每個數字都被平方過一次,本來就很小的那些量會被電腦的小數點誤差直接吃掉。

SVD 一次解決這三個卡點

它吃任何形狀的矩陣(卡點一)、對任何矩陣都保證拆得開(卡點二)、 而且做 PCA 時不用把 C 造出來(卡點三)。

還有一件 06 關留下來的事

三個動作裡有兩個是「轉」。這種只會轉、絕對不改變任何長度、也不改變任何夾角的矩陣, 正式名字叫正交矩陣,就是 06 關那個東西 (書上常拿字母 Q 代表它,Q 就是「那個只會轉的矩陣」的代號,沒有別的意思)。 這一關的 U 和 Vᵀ 都是它。細節等到 ④ 再補。

另外,06 關結尾留了一句沒兌現的話:「秩」告訴你一個矩陣真正有幾層,卻沒告訴你每一層有多重要。 (秩 = 這個矩陣真正有幾層獨立的東西,06 關講過。) 這關就是來補這一刀的 —— 每一層有多重要,答案就藏在動作二的那些「拉幾倍」裡。

這一段的結論

04 關的特徵分解是正方形專用、而且可能會失敗的拆法; SVD 是任何形狀都成立、永遠不會失敗的拆法。 它把矩陣拆成「轉 → 拉 → 轉」三個動作,然後告訴你每個動作的細節。

② 從一個方塊被打歪開始

先把所有專有名詞放一邊,回到 04 關那個最樸素的觀念:

一句話版

矩陣就是一台「搬點機」。你給它一個點 (x, y),它照一條固定的規則把這個點搬到另一個位置。 一張圖上的每一個點都被同一台機器搬一次,整張圖就變形了。

那台機器的規則只有四個數字(2×2 的矩陣就四格), 而且它有三個「不管怎麼搬都不會壞掉」的性質:

下面就把一個正方形(裡面均勻放 25 個點)丟進去,看它被搬成什麼樣子。

這張圖在幹嘛

你會看到什麼:灰虛線=搬家前的正方形+內接的圓 (內接的圓=剛好塞在正方形裡、四邊中點都碰得到的圓;灰虛線整場不動,當比例尺=拿來對照搬了多遠); 青色=搬家後(外框、圓、25 個點); 綠色大點=右上角那點,盯著它就知道圖被翻去哪; 紫箭頭/桃箭頭=「往右一格」「往上一格」兩根基準箭頭被搬到哪。

你可以動什麼:七顆按鈕,各是一台不同的搬點機。 (想逐格微調那四個數字,去 ④ 那裡拉滑桿,改了這裡會跟著變 —— 兩節共用同一台機器。)

要看出什麼:不管按哪顆,青色外框永遠是平行四邊形、青色圈圈永遠是橢圓 (橢圓=被拉長又壓扁的圓)—— 不會變方形、心形、波浪。 (兩個看起來像例外的按鈕,其實是橢圓的兩個極端:按「只轉不拉」時兩個方向拉一樣多, 出來的圓就是「長軸短軸一樣長」的橢圓;按「壓扁成一條線」時有一個方向被拉 0 倍, 出來的線段就是「短軸被壓到沒有寬度」的橢圓。④ 那裡會用數字再講一次。)

符號怎麼唸、怎麼翻:e₁ 唸「e one」=往右一格 (1, 0); e₂ 唸「e two」=往上一格 (0, 1)。 矩陣第一欄=e₁ 被搬到哪、第二欄=e₂ 被搬到哪,沒有別的意思。

灰虛線=搬家前的正方形與圓(比例尺);青色=搬家後。 25 個點是均勻鋪在正方形裡的,搬完之後你可以看出它們被往哪個方向擠、往哪個方向拉開。
解讀

為什麼「一定是橢圓」這件事這麼重要

因為橢圓好描述到不行。要把一個(中心在原點的)橢圓講完,只要三樣資料:

0° ① 角度 30° ② 長軸多長 ③ 短軸多長(一定垂直) 一個角度 + 兩個長度 → 三樣資料,講完一個橢圓

一個橢圓,三樣資料講完:① 長軸朝哪個方向(一個角度)→ ② 長軸多長 → ③ 短軸多長 (一定跟長軸垂直,不用另外講)。知道這三樣,橢圓就完全確定了。

換句話說:一台搬點機對圓做的所有事情,都能用「一個角度 + 兩個長度」講完。 這就是為什麼「轉 → 拉 → 轉」這三個動作夠用了 ——

任何矩陣 = 轉一轉 → 沿兩條垂直的軸拉一拉 → 再轉回來 順序固定,不能換。中間那個「拉」只沿著兩根互相垂直的軸拉,不歪不斜 —— 所以圓被拉成的一定是一個「正的」橢圓(長軸躺在橫的、短軸站在直的),只是最後又被轉走了。
這一段的結論

「矩陣能做的事」比你想像的少很多:對一個圓,它只能轉 → 拉 → 轉。 下一節就讓你自己當那台機器,親手把這三個動作做一遍。

③ 主實驗:你自己當那台機器,三個動作組一個矩陣出來

拆東西之前,先學會組東西。這一節反過來做:不是拆矩陣,而是 自己決定三個動作,看它們合起來變成什麼矩陣。實驗品是同一個正方形(+內接的單位圓, 半徑 1)。(單位圓=半徑剛好是 1 的圓,拿來當「標準形狀」最方便,被拉幾倍一眼就看得出來。)

四根滑桿就是三個動作的全部參數:

出發:一個圓 轉 θ₁ 轉一轉:還是圓 拉 σ 拉一拉:變「正的」橢圓 轉 θ₂ 轉回來:斜的橢圓 = A 順序固定:轉 → 拉 → 轉,不能換

跟旁邊的組裝台互補:組裝台讓你自己調三個動作的數字, 這張圖告訴你順序是固定的 —— 一定是「先轉、再拉、最後轉回來」,換了順序就不是同一台機器。

這張圖在幹嘛

四格依序代表什麼:同一個正方形(+內接單位圓)依序做完三個動作 —— 格 1 出發 → 格 2 轉一轉 → 格 3 拉一拉 → 格 4 轉回來。

  • 青色外框與 25 個點=目前的形狀。
  • 綠色大點=右上角追蹤點,盯它就知道被轉到哪。
  • 紫線/箭頭與桃線/箭頭=原本的橫軸、直軸被搬到哪 (跟著整張圖一起被搬,所以動作一那格看得到「軸真的跟著轉了」)。
  • 灰虛線=出發時的正方形與圓,留著當比例尺;背景格線是畫面本身的橫直方向,不會動。

你可以動什麼:四根滑桿(轉角₁、橫向倍率、直向倍率、轉角₂);下面那排按鈕是值得一看的組合, 「▶ 播放三個動作」依序把四格點亮一次。

要看出什麼:格 1→2 形狀完全沒變、只是轉了;格 2→3 只有大小變、方向沒轉;格 3→4 又只是轉。 三個動作走完 =「直接用合成矩陣 M 一步搬到位」一模一樣(右邊讀數盤最下面三列就是現場對帳)。

  • 兩倍率不一樣:正方形變長方形、圓變「正的」橢圓;一樣=整體放大縮小、形狀不變;有一個是 0=壓成線段。 (每一格的圖說會跟著實際數字改寫,不會跟畫面說反話。)
  • 順帶看得到:紫線跟桃線本來垂直,被動作二拉完就不垂直了 —— 橫向拉 σ₁ 倍、直向拉 σ₂ 倍,斜著擺的東西當然被扯歪。 (那 SVD 憑什麼保證「進去垂直、出來還是垂直」?因為它專挑那兩根拉完仍垂直的方向 —— 就是 ④ 裡的 v₁、v₂。)

符號:σ(sigma)=「拉幾倍」,σ₁ 橫向、σ₂ 直向;θ(theta)=角度; M=三個動作合起來之後的那一台搬點機。

出發
動作一 / 轉一轉
動作二 / 拉一拉
動作三 / 轉回來
四格用同一個座標尺度畫(跟著最大的那個倍率自動調整),所以你看到的「變大」是真的變大。
動作一 —— 先轉一轉(形狀不變)
轉角 θ₁:先轉幾度30°
動作二 —— 沿兩條軸拉一拉(只有這一步會改變大小)
σ₁:橫向拉幾倍2.20
σ₂:直向拉幾倍0.80
動作三 —— 再轉回來(形狀不變)
轉角 θ₂:再轉幾度−15°
解讀

乘法要從右邊往左讀:一個點先碰到最右邊那個矩陣(動作一,也就是下面 ④ 講的 Vᵀ), 再碰到中間那個(動作二=Σ),最後碰到最左邊那個(動作三=U)。這跟上面四格的順序是同一件事 —— 只是寫法反過來而已。

動作一:轉一轉(把 θ₁ 拖來拖去,其他三根不要動)

先只玩最左邊那根滑桿,盯著第 2 格:

動手試

把 σ₁、σ₂ 都調成 1.0(等於「不拉」),然後只拖 θ₁。 你會看到四格圖從頭到尾都只是同一個正方形在轉 —— 大小、形狀、角度全都沒變。 這就是「轉的矩陣不會製造也不會消滅大小」這句話的意思。

動作二:拉一拉,而且兩個方向可以獨立拉

整關最關鍵的一步。做的事簡單到好笑:把每個點的橫座標乘上 σ₁、直座標乘上 σ₂。就這樣。

點 (x, y) → 點 (σ₁·x, σ₂·y) 橫座標只被 σ₁ 影響、直座標只被 σ₂ 影響,兩邊完全不互相干擾。 這就是「每個方向可以獨立拉伸」的字面意思。
也因為它們互不干擾,圓被拉出來的橢圓一定是「正的」—— 長軸躺在橫的、短軸站在直的,不會歪。
動手試:一次只調一個
  • 按「只拉橫向」(σ₂ 設成 1.0、σ₁ 是 2.4),再拖 σ₁:正方形只往左右長,高度一動不動,圓變躺著的橢圓。 (σ₂ 只是「設成」1.0,不是鎖住的 —— 還是能拖,但那就不是「一次只調一個」了。)
  • 按「只拉直向」(σ₁ 設成 1.0、σ₂ 是 2.4):只往上下長,左右不動。
  • 再把兩根都拉開:結果=前兩件事的疊加,橫照 σ₁、直照 σ₂,沒有第三件事發生。這就是「獨立」。

幾個一看就懂的特例,值得你親手拖到那個位置看一眼:

你把倍率設成圓會變成白話
σ₁ = σ₂ = 1還是原來的圓沒拉,等於什麼都沒做
σ₁ = σ₂ = 2半徑 2 的圓整體放大兩倍,形狀不變
σ₁ = 2.4,σ₂ = 1躺著的橢圓只有橫向被拉
σ₁ = 2.4,σ₂ = 0.4又扁又長的橢圓橫向拉長、直向壓扁
σ₂ = 0一條線段直向被壓成 0,整張圖被拍平在一條線上 —— 回不去了

最後那一列最重要:σ = 0 = 這個方向被整個壓掉,所有差異通通變成同一個值 0,回不去了 —— 這就是 06 關講的「壓扁之後回不去」,也就是「這個矩陣沒有逆矩陣」的幾何意義。 (逆矩陣=把搬點機的動作完全倒回去的那台機器;有方向被壓成 0,資訊沒了,就沒辦法倒回去。)

動作三:轉回來

拉完之後橢圓是「正的」(長軸躺橫軸上)。最終結果通常不長這樣 —— 最後再轉一次,把它擺到該在的角度。

動手試:三個動作合起來到底在幹嘛
  • 按「沿 45° 拉(三步全用)」:θ₁ = −45°、σ₁ = 2.6、σ₂ = 0.7、θ₂ = +45°。
  • 一格一格看:倒轉 45°(把 45° 方向轉到橫軸上)→ 橫向拉 2.6 倍 → 再轉回 +45°(擺回原角度)。
  • 結果:整張圖沿 45° 斜方向被拉長 2.6 倍。「沿斜方向拉」動作二自己做不到 —— 它只會橫著拉。 是三步湊起來才做得到,這就是為什麼需要三個動作,不是一個。

現場對帳:三個動作 vs 直接一步到位

右邊讀數盤最下面三列:拿右上角追蹤點(出發 (1, 1))當白老鼠,用兩條路線搬到終點再比對答案。

這一段的結論

你剛剛親手做的事情,就是 SVD 的反方向: 給三個動作,湊出一個矩陣。SVD 做的是正方向:給你一個矩陣,把三個動作反推出來。 而且它保證:不管那個矩陣多奇怪,這三個動作一定存在。下一節就來看它怎麼反推。

④ 反過來:任何矩陣都拆得回這三個動作

現在把 ② 那台被打歪的搬點機拿回來,讓 SVD 現場把它的三個動作算出來。

公式長這樣,只有五個符號 —— 每一個都是你剛剛在 ③ 親手拖過的東西:

A = U Σ VT A —— 你手上那台搬點機(m 列 × n 欄,長方形也行)。
VT(唸 V transpose)—— 最右邊,動作一「先轉一轉」的那個矩陣。
Σ(唸大寫 sigma)—— 中間,動作二「拉一拉」的那個矩陣,對角線上放著兩個倍率 σ₁、σ₂。
U —— 最左邊,動作三「轉回來」的那個矩陣。
記得從右邊往左讀:點先碰到 VT,再碰到 Σ,最後碰到 U。
這張圖在幹嘛

四格依序代表什麼:同一個單位圓被 A 吃掉的三個中間步驟 —— 格 1 出發 → 格 2 套 Vᵀ → 格 3 套 Σ → 格 4 套 U。

  • 青色輪廓/小點=目前的形狀(圓上 12 個等距記號)。
  • 綠色大點=追蹤點,看它跑到哪就知道形狀被轉了多少。
  • 紫箭頭 v₁=原圖上被拉最長的方向;桃箭頭 v₂=垂直於它的另一個方向。

你可以動什麼:四根滑桿是矩陣 A 的四個數字(左上、右上、左下、右下); 下面按鈕是幾台經典搬點機(跟 ② 同一組);「▶ 播放三步」依序點亮四格。

要看出什麼:格 1→2 圓還是圓(只轉),格 2→3 圓變成正的橢圓(只沿橫、直拉), 格 3→4 橢圓同樣胖瘦、只是轉了角度(只轉)。三步走完=直接算 A×圓(第 4 格綠虛線)完全重合。 (少數 A 的第 3 格不是橢圓:「只轉不拉」時 σ₁ = σ₂,圓拉完還是圓; 「壓扁成一條線」時 σ₂ = 0,圓被壓成線段 —— 每一格圖說會跟著實際數字改寫。)

符號:v₁/v₂(v one/v two)=進去端方向; u₁/u₂(u one/u two)=出來端方向;下標 1 是「拉最多」的那根。 (第 4 格裡 v₁ 轉完拉完再轉完,就落在 u₁ 上;u₁ = 那個橢圓的長軸方向。)

STEP 0 / 出發
STEP 1 / 套上 Vᵀ
STEP 2 / 再套上 Σ
STEP 3 / 再套上 U
四格用同一個座標尺度畫(跟著 σ₁ 自動調整),所以你看到的「變大」是真的變大。 格 2、3、4 裡的灰虛線圓是原本的單位圓,留著當比例尺。
矩陣 A 的四個數字 —— 第一欄是「往右一格」被搬到哪,第二欄是「往上一格」被搬到哪
a11(左上)1.60
a12(右上)1.10
a21(左下)0.30
a22(右下)1.40
解讀

三個矩陣現在長什麼樣子

上面滑桿動的時候,下面這三個矩陣就是 SVD 現場算出來的答案。 把它們照順序乘起來,要一個數字不差地變回 A —— 這個「不差」就是讀數盤最後那行「還原誤差」在講的事。

乘法從右邊開始讀:點先碰到 Vᵀ、再碰到 Σ、最後碰到 U。這跟上面四格的順序是同一件事。

用手算一次:一個你自己驗得動的整數例子

上面那些小數看久了會麻痺,所以這裡給一個全部都是整數、國中生拿紙筆就能驗算的例子。 按上面的「整數例 [[2,1],[1,2]]」按鈕,圖會切到這台機器:

A = [[2, 1], [1, 2]] 唸法:第一列是 2 和 1,第二列是 1 和 2。
這台機器把點 (x, y) 搬到 (2x + y, x + 2y)。(這剛好就是 04 關主實驗那個矩陣,你可以兩關對照著看。)

第一步:找「被拉最兇」的方向。怎麼找?回到 ② 那張圖: 把這個 A 按下去,看那個青色橢圓的長軸朝哪邊,那就是被拉最兇的方向 (② 的讀數盤直接印給你看:長軸朝哪個方向 = 45.00°)。 也可以用最土的方法:拿一圈半徑 1 的點一顆一顆送進 A,看哪一顆跑得最遠。

這個 A 的答案是右上 45° 那個方向。45° 上面最好算的點就是 (1, 1),拿它來代表。 把它送進機器:

(1, 1) → (2×1 + 1×1, 1×1 + 2×1) = (3, 3) 出來是 (3, 3)。方向沒變(還是右上 45°),長度變成 3 倍。 所以第一個倍率 σ₁ = 3。

第二步:找垂直於它的那個方向,也就是左上 135°,挑點 (−1, 1)。送進去:

(−1, 1) → (2×(−1) + 1×1, 1×(−1) + 2×1) = (−1, 1) 出來跟進去一模一樣。方向沒變、長度也沒變。所以第二個倍率 σ₂ = 1。

第三步:對答案。把按鈕按下去看讀數盤,σ₁ 應該顯示 3.0000、σ₂ 顯示 1.0000,v₁ 的方向 45.00°。 還可以再驗一條帳:

σ₁ × σ₂ = 3 × 1 = 3  而  det A = 2×2 − 1×1 = 3 兩個倍率乘起來 = 行列式的絕對值 = 面積被放大幾倍。 這很合理:橫向拉 3 倍、直向拉 1 倍,面積當然變 3 倍。

翻成三個動作就是:先把整張圖倒轉 45°(把那個「要被拉 3 倍」的方向轉到橫軸上) → 橫向拉 3 倍、直向拉 1 倍 → 再轉回 45°。 這正是你在 ③ 按「沿 45° 拉」時做過的事,只是倍率換成了 3 和 1。

三個矩陣各自的規矩

U 跟 Vᵀ:只轉,絕對不變形。

06 關的正交矩陣,用一句話複述: 它的每一根欄向量長度都是 1、而且兩兩垂直,所以它作用在任何東西上都不會改變長度、也不會改變夾角。 它能做的只有「把整個平面像一塊硬紙板一樣轉一個角度」(外加可能翻一次面,像照鏡子)。

兩個副作用你會一直用到:

Σ:只沿著座標軸拉。

「對角矩陣」就是「只有左上到右下那條斜線上有數字,其他格子全是 0」的矩陣。它作用起來蠢得可愛:

[[σ₁, 0], [0, σ₂]] × (x, y) = (σ₁x, σ₂y) 橫座標乘 σ₁ 倍、直座標乘 σ₂ 倍,各管各的,完全不互相干擾 —— 就是 ③ 動作二那件事。 這也是為什麼第 3 格的橢圓一定是「正的」。

那兩個倍率 σᵢ 到底是什麼

σᵢ = 第 i 個方向的拉伸倍率。講得精準一點: 把方向 vᵢ 送進 A,出來的東西會落在 uᵢ 這個方向上,長度變成原來的 σᵢ 倍。寫成一行就是:

A vi = σi ui 左邊唸「把 vᵢ 餵給機器 A」,右邊唸「u 這個方向的 σᵢ 倍」。
這跟 04 關的 Av = λv 只差一個字:右邊換成了另一根向量 u。 正因為進去和出來的方向可以不一樣,A 才可以是長方形的。
v₁ 單位圓上,v₁ 長度 = 1 A 作用 u₁ 方向 長度變成 σ₁ 倍(這裡 σ₁ ≈ 1.8) A·v₁ = σ₁·u₁

v₁(紫)是單位圓上被拉最長的那個方向,長度就是 1。 A 把它搬到 u₁ 方向,長度直接變成 σ₁ 倍(因為出發長度是 1,出來就剛好是 σ₁)—— 這就是 A v₁ = σ₁ u₁ 那一行公式在講的事。

兩個規定,記住就好:

跟 04 關的 λ 對比

特徵值 λ(04 關)奇異值 σ(這關)
定義式Av = λvAv = σu
進去 / 出來的方向必須同一根可以是兩根不同的
可以是負的嗎可以(負 = 方向翻過去)不行,一律 ≥ 0
可以是複數嗎可以(代表這動作在轉)不行,一律是實數
保證存在嗎不保證保證,任何矩陣都有
別搞混

σ 和 λ 是兩種不同的數字,只有在一種情況下會撞在一起:A 本身是對稱且半正定 (對稱=沿「左上 → 右下」那條對角線翻過來一模一樣;半正定=一種特別乖的對稱矩陣, 它不會把任何方向翻面,所以特徵值全部 ≥ 0 —— ⑧ 有嚴格定義)(例如共變異數矩陣 C)。 那時候 σᵢ = λᵢ —— 上面那個整數例 [[2,1],[1,2]] 剛好就是這種,所以它的 σ(3 和 1)跟 04 關算的 λ(3 和 1)長一樣。 其他時候它們沒有簡單關係:例如剪切矩陣 [[1, 1], [0, 1]] 的 λ 是 1 和 1,σ 卻是 1.618 和 0.618。 (按「推歪(剪切)」按鈕就看得到。)

本頁符號速查

這關會出現的符號就這些。看到不認識的翻回來對一下:

符號唸法白話叫它什麼它是什麼
AA那台搬點機你要拆的那個矩陣。這關的互動裡是 2×2(四根滑桿),實務上是 m×n 的資料表。
m, nm、n幾列、幾欄A 的列數與欄數。m×n 就是「m 列 n 欄」,例:1000 個人 × 20 個欄位。
VTV transpose「轉一轉」的矩陣動作一。V 的轉置(列欄互換)。因為 V 只會轉,VT 同時也是 V 的逆矩陣。
Σ大寫 sigma「拉一拉」的矩陣動作二。對角矩陣,只有對角線有值,放的是 σ₁, σ₂, …
UU「轉回來」的矩陣動作三。跟 V 一樣只會轉,不改變任何長度。
σi小寫 sigma i拉幾倍第 i 個奇異值=第 i 個方向的拉伸倍率,一律 ≥ 0,由大到小排。
VV進去端的兩根方向欄向量 v₁, v₂ 是「要被拉的那兩根方向」,長度都是 1、互相垂直。
ui, viu i、v i第幾根箭頭第 i 根左 / 右奇異向量。它是一整根向量,不是一個數字(2×2 的情況裡,每根裝兩個數字)。下標 i 就是「第幾根」。
QQ只會轉的矩陣正交矩陣的通用代號:欄向量兩兩垂直、每根長度 1,所以只會轉、不改變長度與夾角。這關的 U 和 V 都是這種。
detdeterminant / 行列式面積放大幾倍det A 是帶正負號的面積倍率;負號代表「還翻了一次面」。det = 0 就是被壓扁了。這關有 |det A| = σ₁ × σ₂。
|x|x 的長度那根箭頭多長兩根直槓包住一根向量=它的長度(用畢氏定理量),永遠 ≥ 0。包住一個數字時是「絕對值」(去掉負號)。
維維 / dimension裡面有幾個數字平面上的箭頭有 x、y 兩個數字 → 2 維;1536 維就是一根裡面裝 1536 個數字。
T(右上角)transpose / 轉置沿斜線翻一次把矩陣的列變成欄(直的變橫的)。兩個規矩:(AB)T = BTAT(順序倒過來)、對角矩陣轉置還是自己。
θtheta角度③ 那兩根轉角滑桿。正的是逆時針。
λlambda04 關的伸縮倍數04 關的特徵值。這關只在 ⑦ 拿來對照。
kk留幾層低秩近似時「保留幾層」的那個數字。k = 1 就是只留最重要的一層。
CC共變異數矩陣03 關那張表,C = XTX /(n−1)。
XX去中心化後的資料表每一列一個樣本,每一欄一個變數,而且每一欄的平均已經被減成 0。
II什麼都不做單位矩陣:對角線全 1、其他全 0,乘上去等於沒動。
rankrank / 秩真正有幾層06 關的秩:這個矩陣真正有幾層獨立的東西。= 不是 0 的 σ 有幾個。
這一段的結論

SVD 把一台搬點機的能耐切成三份:方向的資訊全在 U 和 V 裡,「拉幾倍」的資訊全在 Σ 裡。 而且因為 U、V 只會轉不會變形,這種切法不會有任何遺漏、也不會有任何重複算到。

⑤ 換個讀法:把矩陣看成一層一層疊起來的

A = σ₁ u₁v₁T + σ₂ u₂v₂T + … 把 A 寫成好幾張「薄片」疊起來,每一張薄片都是一個 uvT,前面配一個權重 σ。 σ 由大到小排,所以第一張薄片最重要,後面越來越不重要。
a(直的,左邊) b(橫的,上面) 2 1 3 1 3 2 2×1 2 2×3 6 2×2 4 1×1 1 1×3 3 1×2 2 3×1 3 3×3 9 3×2 6 一欄 × 一列 = 一整張表,這就是一層。

左邊那根直的是 a(2、1、3),上面那根橫的是 b(1、3、2)。 每一格都是「左邊那個 × 上面那個」,9 格填滿就是一整張 3×3 的表 —— 這張表只靠 a、b 這 6 個數字就決定了,這正是「一層」的意思。 (這張圖刻意用「一根裝 3 個數字」來畫,讓你看到表可以更大; 下面那個滑桿版是「一根裝 2 個數字」的 2×2 版,規則一模一樣,只是格子少一點。)

要看懂「A = σ₁u₁v₁ᵀ + …」這個寫法,只要先搞懂上面那張表在幹嘛 —— 也就是為什麼 u₁v₁ᵀ 是一整張表,不是一個數字。慢慢來。

先擋掉一個超容易搞混的地方

u₁ 不是一個數字,是一整根箭頭。上面那個式子裡的 u₁、v₁ 各是一整根向量(2×2 的情況下,每根裡面有兩個數字),下標 1 的意思是「第 1 根」,不是「第 1 個數字」。

所以 σ₁u₁v₁T 不是「三個數字相乘」,而是 「一個數字 σ₁」×「一整根 u₁」×「一整根放倒的 v₁」,結果是一整個矩陣。

正因為很容易混,下面練手的那張乘法表刻意改用別的字母:直立的那根叫 a(裡面兩個數字是 a₁、a₂),橫躺的那根叫 b(裡面兩個數字是 b₁、b₂)。 a、b 就是隨便兩根向量,跟 SVD 沒關係,純粹拿來練「直的 × 橫的」怎麼算。 學會之後再把 a 換成 u₁、b 換成 v₁ 就好。

先搞懂「直的 × 橫的」:其實就是小學的乘法表

你在 01 關學的內積,寫成矩陣是 aᵀb:橫躺的乘直立的, (1×2) × (2×1),結果是一個數字。

現在把順序倒過來,abᵀ:直立的乘橫躺的,(2×1) × (1×2), 結果是一整個 2×2 的矩陣。算法就是小學的九九乘法表 —— 左邊每一格,乘上上面每一格:

這張表在幹嘛

你會看到什麼:一張乘法表。左欄是 a 的兩個數字(直立擺), 上排是 b 的兩個數字(橫躺擺), 中間綠色四格就是 abᵀ 的四個數字,每一格都是「左邊那個 × 上面那個」。

你可以動什麼:四根滑桿,分別是 a₁、a₂、b₁、b₂ 這四個整數。

要看出什麼:不管你怎麼調,上下兩列一定「平行」 —— 也就是下面那一列剛好等於上面那一列乘上某個固定倍數(a₁ 不是 0 的時候,那個倍數就是 a₂ ÷ a₁; a₁ 是 0 的時候上面整列都是 0,兩列還是算平行)。 兩列平行 → 這個矩陣的秩是 1 → 它只有「一層」。 (唯一的例外:a 或 b 整根被拉成 0 —— 那整張表 4 格全是 0,一層都沒有,秩是 0。 所以嚴謹講是「秩最多 1」。)

符號怎麼唸、怎麼翻:aT 唸「a transpose」, 就是把直立的 a 放倒成橫躺的。所以 abT 唸「a 乘 b transpose」, 白話是「一根直的 × 一根橫的 = 一張乘法表」。 「秩」= 06 關那個「真正有幾層」; 「行列式」(det)= 這個矩陣把面積放大幾倍,是 0 就表示被壓扁了。

解讀

a₁(直立那根的上面那格)3
a₂(直立那根的下面那格)1
b₁(橫躺那根的左邊那格)2
b₂(橫躺那根的右邊那格)5
記住這一句

一張「直的 × 橫的」乘法表 = 秩 1 的矩陣 = 「一層」。 這裡練的是 abT,SVD 裡的每一層 uiviT 是一模一樣的算法,只差在 uᵢ、vᵢ 這兩根不是隨便挑的(長度都是 1,而且是 SVD 算出來的)。

一層明明攤開來有 m×n 格,卻只需要 m + n 個數字就能寫下來(直的那根 m 個、橫的那根 n 個)—— ⑥ 的省空間就是從這裡來的。

回到 A:疊上第二層

下面用的是 ④ 那個 A(同一台機器,改上面的滑桿這裡會跟著變)。 現在把它拆成兩層,讓你自己決定要疊幾層:

這張圖在幹嘛

你會看到什麼:單位圓被「目前保留的層數」作用之後的形狀。 紫=第一層 σ₁u₁v₁ᵀ 的貢獻方向、桃=第二層的貢獻方向、 綠虛線=完整的 A 的結果(當作標準答案對照)。

你可以動什麼:兩顆按鈕切「只留第一層」/「兩層都留」。右邊的矩陣數字會同步換。

要看出什麼:只留第一層時,整個圓被壓扁成一根線段(因為秩 1 的矩陣把整個平面壓到一條線上); 加上第二層,線段才長出寬度、變回橢圓、跟綠虛線重合。σ₂ 越小,第一層就越接近完整的 A。

符號怎麼唸、怎麼翻:σ₁u₁v₁T 唸「sigma one、u one、v one transpose」, 白話就是「第一層那張乘法表,再乘上它的權重」。

灰虛線圓=原本的單位圓(比例尺)。
解讀

這一段的結論

矩陣不是一團 m×n 個彼此無關的數字,它是幾張乘法表疊起來的東西, 而 SVD 告訴你這幾張表分別長什麼樣、以及誰比較重要。 「只留一個方向」的意思,就是只留一張乘法表 —— 整個平面被壓到一條線上。

⑥ 只留前面幾層:把小的 σ 丟掉,能省多少

只留 σ₁ 那一層 再疊上 σ₂ 再疊上 σ₃ k=1 份量約 60%(示意) k=2 份量約 88%(示意) k=3 份量約 99%(示意) 留下的份量 = 保留那幾層的 Σσ² 佔全部 Σσ² 的比例。 這三格只是示意疊層的效果,下面互動圖用的才是真實數字。

三格都是同一張圖(用同一套灰階方塊示意),差別只在疊了幾層:只留 σ₁ 只看得出模糊的輪廓, 加上 σ₂、σ₃ 之後對比越來越清楚。這裡的百分比是示意用,不是下面互動圖的真實數字。

這張圖在幹嘛

你會看到什麼:三張 12×12 的方格圖。左=原圖(青色越深數字越大)、 中=只用前 k 層重建出來的圖、右=誤差圖(紅色越深代表這一格差越多)。 下面那排橫條是 12 個倍率 σ₁…σ₁₂ 的大小,被保留的是青色、被丟掉的是灰色。

你可以動什麼:一根滑桿,決定保留幾層(k 從 1 到 12)。

要看出什麼:σ 掉得非常快 —— 前兩層就吃掉 95.7% 的份量。 k 拉到 4、5 圖幾乎一樣,但這張 12×12 太小已經省不到什麼。 同時看右邊那欄的帳:k 太大反而比原本更佔空間。

符號怎麼唸、怎麼翻:k 就是「留幾層」; 「份量」是 σ 的平方加起來(正式名字叫「能量」),白話是「這些層加起來佔了整張圖的多少」; RMSE 是「每一格平均差多少」。

為什麼要平方?因為 σ 只講「拉幾倍」,正負號、方向都跟它無關,直接加總會有大有小互相抵消; 平方之後全部變正數,加起來才代表「這一層真正貢獻了多少能量」——這跟 02 關算變異數要先平方是同一個理由。

這一節請換一個腦袋

前面 ③④ 都在講「拉」,這一節請改用「層」來想,不要用「拉」來想。 12×12 的圖案不是什麼形狀被拉歪 —— 它是12 張乘法表疊起來的一張圖, 而你在做的事是「只留前幾張、其他不要」。σ 在這裡的角色不是「拉幾倍」,是「這張表有多重要」。

原圖 12 × 12 = 144 個數字
只用前 k 層重建 
誤差 |重建 − 原圖|
保留層數 k3
12 個倍率 σ(橫條長度 = σᵢ,用同一個比例尺畫)
解讀

儲存成本怎麼算

這跟 05 關那筆帳是同一個算法:你不能只算「壓縮後的資料」, 還得把「還原時需要的參數」一起算進去,不然那堆數字根本還原不回來。

原本:m × n 個數字
保留 k 層:k × (m + n + 1) 個數字 每一層需要:一根 uᵢ(m 個數字)+ 一根 vᵢ(n 個數字)+ 一個 σᵢ(1 個數字)。 k 層就乘上 k。
m = n = 12 的時候:原本 144,每多留一層要多花 25 個 —— 所以 k ≥ 6 就虧本了。 12×12 太小,本來就不是拿來壓縮的尺寸。

壓縮率怎麼算:拿「保留 k 層要花的數字」除以「原本 m×n 個數字」, 數字越小代表省得越多。真正划算的是細長或巨大的矩陣。把 ① 那張評分表代進去看:

矩陣原本 m×nkk(m+n+1)剩下
資料表 1000 × 2020,00033,06315.3%
評分表 200 × 5010,00082,00820.1%
embedding 100萬 × 153615.36 億1281.28 億8.3%
這節的 12 × 12144410069.4%
這一段的結論

低秩近似省掉的不是「不重要的細節」,是排在後面的那幾層。 它們是不是真的「不重要」,取決於你接下來要問什麼問題 —— 這句話跟 05 關丟掉次軸那段是同一個道理。

⑦ SVD 跟 PCA、跟特徵分解到底什麼關係

先看差在哪

先把左欄那幾個符號講清楚,不然整張表看不懂:A = PDP⁻¹ 是 04 關那個對角化的寫法 —— P = 把特徵向量一根一根當欄排成的表 (=「換去骨架那套座標」的那張表)、D = 對角線上放特徵值 λ 的對角矩陣(=在骨架上各拉各的)、 P⁻¹ = P 的逆矩陣(把 P 的動作原封不動倒回去的那台機器,也就是「從骨架那套座標翻回原本的座標」)。

特徵分解 A = PDP⁻¹SVD A = UΣVᵀ
吃什麼形狀只吃正方形 n×n任何 m×n
保證存在嗎不保證(旋轉、剪切就爆)保證,永遠存在
兩組軸互相垂直嗎一般不垂直(A 對稱時才垂直)U、V 兩組都垂直
對角線上的值λ,可正可負可複數σ,一律實數且 ≥ 0
進去 / 出來同一組軸嗎同一組(P 和 P⁻¹)兩組不同(V 進、U 出)
數值穩定嗎P⁻¹ 可能病態(ill-conditioned:P 快要不可逆, 算它的逆矩陣時輸入端一點點小誤差會被放大成很大的誤差,答案不能信)只會轉的矩陣,逆矩陣就是轉置,很穩

一句話對照:特徵分解是「同一組軸進、同一組軸出」,只對正方形有效,還可能失敗; SVD 是「一組軸進、另一組軸出」,任何形狀都保證拆得開。

再看它們在哪裡接上:PCA 那個等式

C = XTX /(n − 1) n = 樣本數(幾個人),d = 變數個數(幾欄)。除以 n−1 是樣本版(02 關那個 ddof=1)。

現在對 X 直接做 SVD:X = UΣVT。把它代進去:

XTX = (UΣVT)T(UΣVT) = VΣUTUΣVT = V Σ2 VT 這裡用到三條規矩,都只是「規矩」,不用推導:
① 轉置會把乘法的順序倒過來:(ABC)T = CTBTAT。所以 (UΣVT)T 變成 VΣTUT。
② 對角矩陣轉置還是它自己:ΣT = Σ(沿斜線翻一次,斜線上的數字沒動,其他本來就是 0)。所以上面直接寫成 VΣUT。
③ 只會轉的矩陣,轉置乘自己等於「什麼都沒做」:UTU = I,所以中間那塊直接消失。
剩下 ΣΣ = Σ²(對角線上的數字各自平方)。所以 C = V (Σ²/(n−1)) VT,這正好就是 C 的特徵分解。
兩個結論,釘死

1. X 的右奇異向量 vᵢ,就是 C 的特徵向量(= 05 關的主軸)。

2. σᵢ² /(n−1) 就是 C 的特徵值 λᵢ(= 那根主軸上的變異數)。

這句話怎麼唸:「X 的奇異值平方、除以 n−1」就等於「XᵀX 對應的特徵值」—— 因為上面推出 C = XᵀX/(n−1) = V(Σ²/(n−1))Vᵀ,而 V(Σ²/(n−1))Vᵀ 這個寫法本身就是特徵分解的樣子, 所以對角線上那排 σᵢ²/(n−1) 一格一格對應著 C 的特徵值 λᵢ。

所以做 PCA 根本不用把 C 造出來,直接對去中心化的 X 做 SVD 就好 —— 這就是 ① 那個 236 萬格中間表可以直接跳過的原因,也是 sklearn 的 PCA 底層真的在做的事。

現場驗算:還是 05 關那 12 個人

這張圖在幹嘛

你會看到什麼:左邊是 05 關那 12 個人的身高體重散佈圖(青點), 紫箭頭是用 SVD 算出來的 v₁。右邊兩欄數字並排:左欄走 SVD、右欄走 eig(C), 同一列的兩個數字應該一模一樣。

你可以動什麼:兩顆按鈕,切換「有去中心化(正確做法)」和「忘了去中心化」。 切過去的時候鏡頭會拉遠,好讓座標原點進到畫面裡。

要看出什麼:有去中心化時,σ₁²/(n−1) = 205.55、主軸 45.24°, 跟 05 關算出來的 λ₁ 和角度一個小數點都不差。 忘了去中心化的話,v₁ 會整根倒向「原點到資料重心」那一側(算出來是 19.59°,而重心方向本身是 19.46°), 算出來的東西根本不是 PCA —— 而且沒有任何錯誤訊息。

為什麼去中心化會改變主軸?沒去中心化的 X,每一列除了「跟其他人比起來的差異」還多帶了「離原點多遠」這件事; 對 XᵀX 做分解時,這股「離原點的距離」會混進去、蓋過原本資料真正散開的方向 —— 所以 v₁ 不再指向「資料散得最開」的方向,而是被拉去指向「資料重心離原點的方向」。

符號怎麼唸、怎麼翻:n − 1 這裡是 12 − 1 = 11; σ₁²/(n−1) 唸「sigma one 平方除以 n 減 1」, 白話是「把拉伸倍率換算成 05 關那個『沿這根主軸散得多開』的數字」。

青點=12 個人(x = 身高 cm,y = 體重 kg)、 紫箭頭=v₁、桃箭頭=v₂(兩根的長度比 = σ₂/σ₁)、 綠點=資料重心。
切到「忘了去中心化」時鏡頭會自動拉遠,因為那時候箭頭是從座標原點 (0, 0) 出發的 —— 不拉遠你根本看不到起點在哪。
量走 SVD走 eig(C)
解讀

這一段的結論

PCA 和 SVD 不是兩件事,是同一件事的兩條路。 「對 X 做 SVD」和「對 C 做特徵分解」給你完全一樣的軸, 但前者不用先造出 C、數值上也穩得多。 05 關是繞路,07 關是直達車,終點站同一個。

⑧ 數學長怎樣:這關的 SVD 是怎麼算出來的(選讀,可跳過)

先說清楚

這一節超綱,第一次讀可以整節跳過,直接跳到 ⑨。 它回答的是「電腦到底怎麼把那三個動作算出來」,屬於實作細節; 不知道這件事,完全不影響你用 SVD。

白話一句:要拆 A,先造 AᵀA —— AᵀA 拆得開,A 就拆得開。 而拆 AᵀA 只需要一個你已經會的工具:特徵分解。四步,一步一行:

  1. 造 AᵀA(唸「A transpose A」=「A 轉置後,再乘 A」)= 把 A 先搬一次、再用搬法的反向搬回來。 意義:不管 A 長得多怪,造出來的東西一定是對稱矩陣 —— 沿「左上 → 右下」那條對角線左右一模一樣的方陣。
  2. 對 AᵀA 做特徵分解:因為它對稱,特徵向量保證兩兩垂直,這組垂直向量就是 V。 特徵分解=把方陣拆成「每根方向各被拉幾倍」的工具(04 關那台機器)。 為什麼 AᵀA 一定拆得開:實對稱矩陣一定可以正交對角化(譜定理,沒有例外)→ 這步永遠不會失敗。
  3. 拉伸倍率 = 特徵值開根號:σ = √λ。 λ(唸「lambda」)是特徵值=「沿某根方向,AᵀA 把那根方向拉 λ 倍」的那個倍率。 AᵀA 半正定(=任何向量 v 送進去,長度平方 vᵀAᵀAv = |Av|² ≥ 0,平方不可能是負的)→ λ 一定 ≥ 0 → 根號裡不會是負的。
  4. 反推 U:把 vᵢ 送進 A,再除以 σᵢ —— ui = A vi / σi。

第 4 步有個守衛(σᵢ = 0 的時候),不是選配:

符號版:

ATA = V Σ2 VT  →  σi = √λi(ATA) , ui = A vi / σi λᵢ(AᵀA) —— AᵀA 的第 i 個特徵值。V —— 它的特徵向量排成的矩陣。 Σ² —— 對角線上放 σᵢ² 的對角矩陣。
A 2 1 1 2 AᵀA AᵀA 5 4 4 5 √λ AᵀA 的 λ λ₁ = 9 λ₂ = 1 開根號 → σ ① A:一台搬點機 ② 先搬再搬回 → 對稱 ③ λ 開根號 → σ σ₁ = √λ₁ = √9 = 3   σ₂ = √λ₂ = √1 = 1

圖說:看三格怎麼接起來。① 是 A(一台搬點機);② AᵀA =「先搬一次、再用搬法的反向搬回來」,所以一定是對稱的,一定拆得開; ③ 拆出來的倍率 λ 開根號就是 σ。最後一行用本關整數例 [[2,1],[1,2]] 對帳: AᵀA = [[5,4],[4,5]] 的 λ₁ = 9、λ₂ = 1 → σ₁ = √9 = 3、σ₂ = √1 = 1,跟 ④ 那台 A 完全一致。

但是別在正式產品裡這樣寫

「造 AᵀA 再分解」在教學上最清楚,在數值上卻是最爛的做法之一: 平方一次,條件數就平方一次,小的 σ 會被浮點誤差直接吃掉。 真正的函式庫(LAPACK 的 dgesdd、numpy 的 np.linalg.svd)走的是 Golub–Kahan 雙對角化,全程不碰 AᵀA。
這一頁是教材,不是函式庫 —— 所以我用清楚的寫法,並且在頁面上印出還原誤差讓你自己檢查。 實測 2×2 的還原誤差在 1e−15 這個量級,教學用途完全夠。

這關的三段實作,都寫在這個檔案裡:

⑨ 工程師的「原來如此」

推薦系統的隱因子
  • 一百萬美金的題目:2006 年 Netflix 懸賞一百萬美金,要人把電影推薦的預測誤差降 10%;最後贏的那一套,核心就是這關的第二種寫法。
  • 隱因子:把「使用者 × 電影」的評分表當成 A,SVD 之後 A ≈ σ₁u₁v₁ᵀ + σ₂u₂v₂ᵀ + …,每一層有了具體意義: v₁ 是一組「電影的口味權重」,u₁ 是一組「使用者對這種口味的偏好強度」。 你沒告訴系統什麼叫動作片,但第一層自己長出來的 v₁ 就會在動作片上給高分 —— 「隱因子」(latent factor)=沒人標註,是從資料的骨架裡掉出來的。
  • 空格也能填:預測某人對某片的評分,就是把他的隱因子向量跟那部片的隱因子向量做內積。 200×50 的表壓成 8 層之後,你存的不是 10000 個評分,是 2008 個數字 —— 而且空格也能填了 (原表大部分是空的,你當然沒看過那部片;低秩結構會把它補出來)。 實務上因為空格太多,會用 ALS / SGD 只在有評分的格子上擬合,那叫 matrix factorization, 但骨架就是這裡的 uvᵀ 疊加。
語意分析與降噪:LSA
  • 文件 × 詞:把一堆文件做成「文件 × 詞」的次數表(1 萬篇 × 5 萬個詞),這張表大得離譜而且幾乎全是 0。 對它做 truncated SVD(truncated=截斷,只留前 k 層)留前 300 層,你會得到一件很妙的事: 「汽車」和「轎車」這兩個詞,在原表裡是完全不同的兩欄(內積 = 0),壓到 300 維之後卻靠得很近。
  • 為什麼會靠近:低秩近似的本質 —— 前 300 層是「所有文件共用的骨架」, 而「汽車」跟「轎車」出現在同一批文件裡,所以它們在骨架上的座標幾乎一樣; 被丟掉的後面幾萬層,才是「這篇剛好用了這個詞」的個別雜訊。
  • 同一招叫「降噪」:訊號有結構(低秩)、雜訊沒有(份量平均散在所有層)→ 砍掉小的 σ,砍掉的絕大部分是雜訊。 感測器陣列、金融因子模型、影像去雜訊都在用這一手。
  • 名詞追認:這套東西叫 LSA(Latent Semantic Analysis),是今天所有 embedding(=把文字變成數字向量,讓機器能比「像不像」)的老祖宗; sklearn 裡就叫 TruncatedSVD(專門處理稀疏矩陣,不需要去中心化)。 至於「拿 SVD 壓縮 JPG」那個經典教學例子 —— 它能跑,但沒人真的用, 因為 JPEG 的 DCT + 量化在同樣品質下小得多。SVD 在壓縮界的真實戰場是 「大模型權重矩陣的低秩壓縮」(LoRA 那一票)。

⑩ 踩坑

坑 1
  • 症狀:看到 σ 很小那幾層,直覺想砍掉 —— 以為「小 = 沒用」。
  • 為什麼:σ 衡量的是「這一層佔了多少份量」,不是「這一層有多少資訊價值」。 在異常偵測裡,訊號正好躲在最小的那幾層 —— 前面幾層是所有人都一樣的共同行為, 「這個帳號跟大家不一樣」這件事只會出現在剩下的那點殘渣裡; 05 關那個「同身高下偏壯偏瘦」也是躲在次軸。
  • 怎麼避:丟哪幾層,取決於你要問什麼,不是取決於 σ 的大小。
坑 2
  • 症狀:同一筆資料,換個函式庫、換個版本、換台機器,算出來的 v₁ 可能整根乘上 −1 —— 而且不會有任何錯誤訊息。
  • 為什麼:SVD 不唯一:如果 (uᵢ, vᵢ) 是一組解,那 (−uᵢ, −vᵢ) 也是 —— 兩個負號在 σᵢuᵢvᵢᵀ 裡乘掉了,A 一模一樣。 當 σ₁ ≈ σ₂(兩層一樣重)時更糟:那時候 v₁、v₂ 可以在它們張成的平面裡任意旋轉,不只是翻號 (④ 的「只轉不拉」按鈕就是這種情況,σ₁ = σ₂ = 1)。
  • 怎麼避:算完立刻做符號規範化(例如強迫某個指定分量為正),並且把它跟模型一起存起來 —— 跟 05 關講的一樣; 不然你存下來的隱因子分數整欄變號,下游那條「分數 > 0 就標成 A 類」的規則會全部反過來。
坑 3
  • 症狀:沒去中心化就做 PCA,主軸指錯方向 —— ⑦ 那個「忘了去中心化」按鈕按下去,主軸從 45.24° 倒到 19.59° (幾乎就是「原點 → 重心」那條線的方向 19.46°)。
  • 為什麼:「X 的右奇異向量 = C 的特徵向量」這個等式,前提是 X 每一欄的平均都是 0。 沒去中心化的話,XᵀX 裡混進了「重心離原點多遠」這件事,而且它通常大到把真正的主軸壓掉 —— v₁ 會直接指向重心方向。
  • 怎麼避:PCA 前先減掉每欄平均。唯一的反例是 LSA:處理稀疏的詞頻矩陣時故意不去中心化 (去了會把稀疏矩陣變稠密,1 萬 × 5 萬的表直接爆記憶體)—— 所以 sklearn 才要分成 PCA(會去中心化) 和 TruncatedSVD(不會)兩個類別,不是重複造輪子,是兩個不同的東西。
坑 4(選讀,跟正確性無關,只跟「跑不跑得動」有關)
  • 症狀:完整 SVD 在大矩陣上跑不動、存不下 —— m×n 的完整 SVD 大約要 O(mn·min(m,n)) 的運算量, 而且會吐出一個 m×m 的 U:100 萬列的資料表,那個 U 是 10¹² 個數字,你根本存不下。
  • 為什麼:你要的通常只有前 k 層,完整版卻把整個 m×m 的 U 也算出來、存起來。
  • 怎麼避:只算你要的那幾層: numpy.linalg.svd(A, full_matrices=False)(只算細長版)、 scipy.sparse.linalg.svds(A, k=50)(只算前 50 個)、 或 randomized SVD(先隨機投影到 k+p 維再做,快一個數量級)。 只想要第一層的話,04 關那個「乘乘乘」的 power iteration 幾十次迭代就給你了,最省。

⑪ 這關回答了什麼

一句話講,SVD 到底在幹嘛?

它把一個矩陣拆成三個動作:先轉一轉(Vᵀ)→ 沿兩條垂直的軸拉一拉(Σ)→ 再轉回來(U)。 任何矩陣都拆得出來。而且只要那些「拉幾倍」的數字兩兩都不一樣,拆法就只有這一種 (唯一的自由度是 uᵢ、vᵢ 可以整根一起翻正負號,A 不變 —— 見 坑 2)。 如果剛好有兩個倍率一樣大,那就不唯一了:它們對應的那兩根方向可以在自己那個平面裡任意轉, 隨便選一組都對(坑 2 後半段)。

為什麼只要三個動作就夠?因為 ② 那個事實: 矩陣對一個圓做的事,永遠只會做出一個橢圓。而橢圓用「一個角度 + 兩個長度」就講完了。

為什麼不能只用一個動作?直接拉不行嗎?

因為「拉」只會沿著橫的跟直的拉,它不會斜著拉。 可是你想拉的方向常常是斜的 —— 這時候就得先把那個方向轉到橫的位置,拉完再轉回去。

③ 的「沿 45° 拉」按鈕就是現場示範: θ₁ = −45° 把 45° 方向轉到橫軸 → 橫向拉 2.6 倍 → θ₂ = +45° 轉回去。 三步湊起來才做得到「沿斜線拉」這件事。

「每個方向可以獨立拉伸」是什麼意思?

字面意思:橫座標只被 σ₁ 影響、直座標只被 σ₂ 影響,兩邊互不干擾。 點 (x, y) 變成 (σ₁x, σ₂y),沒有第三件事發生。

親手驗證:③ 按「只拉橫向」,σ₂ 被設成 1.0,你拖 σ₁ 的時候 正方形只往左右長、上下高度一動也不動。再按「只拉直向」換過來看一次。 兩個看完之後再把兩根都拉開 —— 結果就是前兩件事直接疊加。

奇異值 σ 跟特徵值 λ 差在哪?

定義式差一個字:λ 是 Av = λv(進去出來同一根方向), σ 是 Av = σu(進去出來可以是不同方向)。就因為這一個字, σ 不需要 A 是正方形的。

性質上:λ 可以是負的、可以是複數、可能根本不存在;σ 一律是 ≥ 0 的實數,而且一定存在。 兩者只在「A 對稱且半正定」時會相等 (半正定=一種特別乖的對稱矩陣,不會把任何方向翻面,所以 λ 全部 ≥ 0; 嚴格定義在 ⑧)。完整對照看 ④ 那張表。

為什麼說「任何矩陣都有 SVD」?憑什麼這麼強?

因為它把難題轉嫁給了一個一定成立的定理。看 ⑧ 的算法: SVD 不直接處理 A,而是先造 AᵀA。不管 A 是什麼形狀、多歪多爛, AᵀA 一定是對稱的方陣((AᵀA)ᵀ = AᵀA,兩行就證完),而且半正定 (因為 vᵀAᵀAv = |Av|² ≥ 0,是個平方,不可能是負的)。

而「實對稱矩陣一定可以正交對角化、特徵值一定是實數」是譜定理保證的,沒有例外。 所以 V 一定存在、λ 一定 ≥ 0、σ = √λ 一定算得出來。 SVD 的「永遠成立」是從對稱矩陣借來的。

把矩陣拆成「一層一層」又是什麼意思?跟三個動作衝突嗎?

不衝突,是同一個等式的兩種讀法。三個動作是「A = UΣVᵀ」; 一層一層是把同一個等式攤開寫成 A = σ₁u₁v₁ᵀ + σ₂u₂v₂ᵀ + …。

每一層 uvT 就是一張小學乘法表, σ 由大到小告訴你哪張比較重要。 「只留第一層」= 只留一張乘法表 = 只沿一個方向拉,整個平面被壓成一條線。

低秩近似到底丟了什麼?

丟了「排在第 k 名之後的那幾層」,也就是那些 σ 比較小的 uvᵀ 薄片。 丟掉之後的誤差有個乾淨的公式:剩餘誤差的平方 = 被丟掉那些 σ 的平方和。 ⑥ 那張誤差圖畫的就是這個。

但「σ 小」只代表份量小,不代表沒價值。異常偵測、殘差分析要的正好是被丟掉的那部分 (坑 1)。判斷能不能丟的標準永遠是: 你接下來要回答的問題,會不會剛好落在你丟掉的那幾層上。

什麼時候該用 SVD,什麼時候用特徵分解?

一句話:不確定的時候用 SVD(它不會失敗);只有問題本身就是「方陣重複作用很多次會怎樣」時,才需要 λ。

  • 用 SVD:矩陣是長方形的(資料表、評分表、詞頻表);要做低秩近似 / 降維 / 降噪; 要算偽逆、最小平方、條件數;矩陣可能奇異或病態。
  • 用特徵分解:你要問的問題本身就是「這個方陣重複作用很多次會怎樣」—— 馬可夫鏈的穩態、微分方程、PageRank、矩陣冪(04 關那個乘乘乘), 因為要的就是「方向不變、只縮放」這件事,只有 λ 回答得了; 另外 A 是對稱矩陣時(共變異數矩陣、Gram 矩陣),特徵分解又快又穩,沒必要繞去 SVD。
SVD 跟 PCA 是同一件事嗎?

幾乎是,但差一個步驟:去中心化。 PCA = 先把每一欄減掉自己的平均,再對結果做 SVD,然後把右奇異向量當主軸。 少了「減平均」這一步,你算的就只是 SVD,不是 PCA(坑 3 那個 19.59° 就是現場示範)。

接上去之後兩者完全等價:X 的右奇異向量 vᵢ = C 的特徵向量、 σᵢ²/(n−1) = λᵢ。⑦ 拿 05 關那 12 個人現場驗算過: σ₁ = 47.5504 → 47.5504²/11 = 205.5489,跟 05 關的 λ₁ 一個小數點都不差。

實務上一律走 SVD 那條路:不用造 C(省掉 d×d 的中間表)、數值上穩得多, 這也是 sklearn PCA 底層真正在做的事。

U、Σ、V 的尺寸到底各是多少?(長方形的時候很容易搞混)

A 是 m×n 的話:U 是 m×m、Σ 是 m×n、V 是 n×n,這叫「完整 SVD」。 Σ 是長方形的對角矩陣 —— 對角線上有 min(m,n) 個 σ,其他全是 0。

但那些 0 對應的 U 欄向量乘出來也是 0,存了沒用。所以實務上都用「精簡 SVD」: U 是 m×r、Σ 是 r×r、V 是 n×r,r = min(m, n)。 1000×20 的表,完整版的 U 是 1000×1000(一百萬個數字),精簡版只有 1000×20。 numpy 裡就是 full_matrices=False 這個參數。

這關留下什麼洞 → 下一關補

到這裡,「一個矩陣把圓拉成什麼形狀的橢圓」你已經拆得乾乾淨淨了。 但整關我們都在看形狀 —— 從來沒把它拿來用。

下一關反過來:機率統計 05 關把共變異數矩陣 C 畫出來的那顆橢圓當成一把尺。 同樣是「離重心 3 公分」,在資料鋪得很開的方向上是家常便飯,在資料很緊的方向上就是異常。 這把尺叫馬氏距離,而它量出來的等距線,就是這關那顆橢圓。