iPAS AI 應用規劃師 中級 科目三 機器學習技術與應用

PCA 降噪失效,哪一段程式碼需要修改?

原題 46

在郵遞區號自動辨識的研究中,研究人員收集了一份手寫數字影像資料集(UCI sklearn digits, 8×8 灰階),共 1797 筆。研究人員把含有雜訊的手寫數字影像存放在變數 noisy 中,部分資料經視覺化後外觀如附圖所示。他們嘗試使用 PCA 進行降噪,並希望能保留影像的主要特徵,同時去除影像中的雜訊。

程式碼如下:
程式碼 A: import numpy as np; noisy = np.random.normal(digits.data, 4)
程式碼 B: from sklearn.decomposition import PCA; pca = PCA()
程式碼 C: pca.fit(noisy)
程式碼 D: components = pca.transform(noisy)
程式碼 E: filtered = pca.inverse_transform(components)

當程式執行後,觀察到影像仍然含有明顯的雜訊。研究人員懷疑是程式中某步驟的設定不正確,導致 PCA 沒有發揮降噪的作用,需要修改程式碼才能讓降噪有效。請問哪一段程式碼需要修改,才能讓 PCA 對 noisy 影像有效去噪?

白話

郵遞區號辨識專案的研究人員對手寫數字影像加了雜訊,然後試著用 PCA 來降噪。整個流程分為五段程式碼:A 加雜訊、B 建立 PCA 物件、C 訓練 PCA、D 轉換到 PCA 空間、E 轉換回原始空間。執行後,降噪效果完全沒有,影像雜訊依然明顯。

問你:五段程式碼中,哪一段有問題,導致 PCA 降噪完全無效?

點選你的答案。

01 總結

一句話總結

PCA 降噪失效的原因是程式碼 B:PCA() 沒有指定 n_components 參數,等於保留所有主成分,這樣 transform + inverse_transform 就是把資料原封不動轉一圈回來,雜訊完全沒有被去除

02 情境

先感受問題:PCA 為什麼能降噪,又為什麼失效?

郵遞區號辨識專案的研究人員拿到了 1,797 張 8×8 手寫數字影像,每張有 64 個像素特徵。他們人工加入標準差為 4 的高斯雜訊,想用 PCA 降噪:先把 64 維特徵壓縮到「最重要的前 K 個主成分」,再還原回來——還原時,次要主成分(包含雜訊的部分)就被丟掉了,影像變乾淨。

這個邏輯完全正確,但有一個關鍵前提:必須指定「保留幾個主成分(K)」。如果 PCA() 沒有指定 n_components,sklearn 預設保留所有 64 個主成分,等於沒有降維,transform 後再 inverse_transform 就是完整的資料還原,什麼雜訊都沒有去掉。

03 對照

PCA 降噪為什麼沒有效?五段程式碼逐一診斷

  1. 程式碼 A(加雜訊)正確:np.random.normal(digits.data, 4) 為每個像素值加入均值為 0、標準差為 4 的高斯雜訊,這是標準的雜訊模擬做法,沒有問題。
  2. 程式碼 B(建立 PCA 物件)有問題:PCA() 不指定 n_components,等於 n_components=None,sklearn 預設保留 min(樣本數, 特徵數) = min(1797, 64) = 64 個主成分,等於保留全部,沒有任何降維或降噪效果。
  3. 程式碼 C(訓練 PCA)正確:pca.fit(noisy) 對加了雜訊的資料學習主成分方向,這步沒有問題。
  4. 程式碼 D(轉換)正確:pca.transform(noisy) 把資料投影到主成分空間,邏輯正確。
  5. 程式碼 E(還原)正確:pca.inverse_transform(components) 從主成分空間還原到原始空間,邏輯正確。但因為 B 沒降維,D 和 E 就等於無意義的往返,雜訊沒有去除。
04 解法

修改 PCA(n_components=K),只保留前 K 個主成分

正確的修改方式是把程式碼 B 改成 pca = PCA(n_components=0.95)pca = PCA(n_components=32)

  • n_components=0.95:保留能解釋 95% 變異量的最少主成分數,sklearn 自動決定 K 的值(digits 資料集約需 20-30 個主成分)
  • n_components=32:明確保留前 32 個主成分,丟棄後 32 個(通常包含高頻雜訊)

保留主要主成分後,次要主成分(方差小、通常對應雜訊)在 inverse_transform 時不再還原,達到降噪效果。對 digits 資料集,保留約 20-30 個主成分通常就能有效去噪,同時保留數字的基本形狀。

這就是選項 B 講的:程式碼 B 需要修改,加上 n_components 參數

技術版:PCA 降噪原理與 n_components 參數

中級考試大概率會考程式碼跟公式,所以這部分你還是要學。但如果現在學起來很痛苦,可以先跳過,等讀完其他題目回頭再來。

Step 1 純故事版(不出現公式)

想像你有一張 64 格的樂高拼圖,每格代表一個像素。加了雜訊後,有些格子的顏色略微偏離了原本的樣子。

PCA 降噪的邏輯是:先把這 64 格「重新編碼」成幾個最重要的「主題風格」(例如「整體亮度」「左右對比」「上下對比」)。保留前幾個最重要的主題,丟掉後面的「細碎干擾」(雜訊通常集中在不重要的主題裡),再還原回來,影像就變乾淨了。

但如果你保留全部 64 個主題,等於什麼都沒有丟棄,拼圖還原後完全一樣,雜訊當然也回來了。這就是 PCA() 不指定 n_components 的問題。

Step 2 中文 ↔ 程式碼對照
白話說法程式碼
加高斯雜訊(標準差 4)noisy = np.random.normal(digits.data, 4)
建立 PCA(錯誤:保留全部)pca = PCA() ← 等於 PCA(n_components=None)
建立 PCA(正確:保留 95% 變異)pca = PCA(n_components=0.95)
訓練 PCA 找主成分方向pca.fit(noisy)
投影到主成分空間(降維)components = pca.transform(noisy)
還原到原始空間(降噪)filtered = pca.inverse_transform(components)
Step 3 符號角色表
n_components
PCA 保留的主成分數,可以是整數(保留 K 個)或 0-1 的浮點數(保留解釋 X% 變異量所需的最少成分)
explained_variance_ratio_
每個主成分解釋的變異比例,用 pca.explained_variance_ratio_.cumsum() 可看累積解釋量
transform
把原始資料投影到主成分空間,輸出維度 = n_components
inverse_transform
從主成分空間還原到原始空間,如果 n_components < 原始維度,還原的資料是近似值
雜訊集中在低方差成分
雜訊通常是隨機的、低相關的,對應方差小的主成分;訊號是有結構的,對應方差大的主成分
Step 4 完整公式對應
PCA 流程:
  1. fit(X):計算 X 的協方差矩陣,找出特徵向量(主成分方向)
     → 按特徵值(解釋變異量)由大到小排列

  2. transform(X):X 投影到前 K 個主成分
     X_pca = X · W_K^T      (W_K 是前 K 個主成分向量)
     X_pca.shape = (n_samples, K)

  3. inverse_transform(X_pca):從 K 維還原到原始維度
     X_rec = X_pca · W_K + μ   (μ 是訓練時的均值)
     X_rec.shape = (n_samples, 64)
     → K < 64 時,X_rec 是近似值,丟棄了後 64-K 個成分的資訊

程式碼 B 的問題:
  PCA()  → n_components = min(1797, 64) = 64(全部保留)
  transform + inverse_transform = 完美還原 = 雜訊也回來

修正後(n_components=0.95):
  sklearn 自動選 K ≈ 26 個成分(解釋 95% 變異)
  丟棄後 38 個成分,雜訊大量存在其中
  inverse_transform 的 X_rec 明顯比 noisy 乾淨
Step 5 自我複述
  1. 為什麼 PCA() 不指定 n_components 時,降噪效果是零?
  2. n_components=0.95 和 n_components=26 有什麼差異?各自適合什麼場景?
  3. 雜訊為什麼通常集中在「低方差的主成分」?
  4. 如果把 n_components 設得太小(例如 3),降噪後影像會有什麼問題?
  5. pca.fit(noisy) 和 pca.fit(clean_data) 之後用 transform(noisy),降噪效果有差嗎?
05 陷阱

為什麼其他選項是錯的

選項 A 程式碼 A

字面在說什麼:加雜訊的方式有問題,需要修改。

為什麼不對:np.random.normal(digits.data, 4) 是標準的高斯雜訊模擬:第一個參數是均值(用原始資料值),第二個參數是標準差(4),為每個像素獨立採樣雜訊。這是正確且常見的做法,對 PCA 降噪的後續步驟沒有影響。問題不在這裡。

誰會選錯:不熟悉 np.random.normal 的參數順序,以為「標準差 4 太大」或「參數填錯了」,懷疑雜訊本身加得有問題。

選項 C 程式碼 C

字面在說什麼:pca.fit(noisy) 用含雜訊的資料訓練 PCA 是錯誤的,應該用乾淨資料。

為什麼不對:用 noisy 資料訓練 PCA 是正確做法。降噪 PCA 的邏輯是:從含雜訊的資料中學習主要變異方向,訊號(數字形狀)的變異量遠大於隨機雜訊的變異量,所以前幾個主成分仍然主要捕捉訊號,後面的主成分才是雜訊。用乾淨資料訓練雖然理論上更好,但實務中通常沒有乾淨資料,用 noisy 資料是標準做法。

誰會選錯:直覺上覺得「訓練資料有雜訊,PCA 學到的主成分也會有雜訊污染」,但實際上訊號的方差仍遠大於雜訊,PCA 仍能找到正確方向。

選項 D 程式碼 D

字面在說什麼:pca.transform(noisy) 的用法有問題。

為什麼不對:pca.transform(noisy) 把含雜訊的影像投影到主成分空間,是標準的降噪流程。問題不在這裡,而在 B 沒有限制主成分數,所以 transform 保留了所有維度,後面的 inverse_transform 才能完整還原雜訊。D 的操作本身沒有錯。

誰會選錯:看到「把含雜訊的資料做 transform」就覺得哪裡怪怪的,其實這正是降噪的必要步驟,問題不在 D。

06 變形

同個考點下次怎麼變形

變形 1 n_components 如何選

直覺:怎麼知道應該保留幾個主成分來降噪?

答案:畫累積解釋變異量圖(Explained Variance Ratio 折線圖),找到「肘點」(elbow point):曲線從陡峭變平緩的地方。累積解釋 80-95% 變異量的主成分數通常是好的選擇。對 digits 資料集,約 20-30 個主成分就能解釋 95% 的變異。

變形 2 降噪 vs 降維

直覺:PCA 降噪(用 inverse_transform 還原)和 PCA 降維(直接使用壓縮後的特徵)有什麼差異?

答案:降噪是「壓縮後再還原」,輸出和輸入維度相同,但去除了低方差成分;降維是「壓縮後直接使用」,輸出維度小於輸入,用在機器學習的特徵工程中。兩者都用 transform,差異只在有沒有做 inverse_transform。

變形 3 雜訊強度影響

直覺:如果把程式碼 A 的標準差從 4 改成 20,同樣的 n_components=0.95 還有效嗎?

答案:效果會下降。雜訊越強,雜訊的方差越大,會混入前幾個主成分,n_components=0.95 保留的成分就會包含更多雜訊。此時需要降低 n_components(保留更少成分、更激進去噪),或調低 0.95 的門檻。降噪能力有上限,雜訊極強時 PCA 降噪不再適用。

變形 4 換資料集

直覺:同樣的 PCA 降噪流程,用在 MNIST(28×28 = 784 維)上,n_components 應設多少?

答案:MNIST 784 維中,通常 50-100 個主成分就能解釋 95% 以上的變異。可以用 `pca = PCA(n_components=0.95)` 讓 sklearn 自動決定,或先用全量 PCA 畫折線圖再手動選。維度更高意味著可以保留更多主成分而仍有降噪效果。

變形 5 重建誤差

直覺:怎麼量化 PCA 降噪的效果?

答案:計算降噪後影像和原始乾淨影像之間的均方誤差(MSE):`mse = np.mean((filtered - digits.data) ** 2)`。也可以用 SSIM(結構相似性指標)或 PSNR(峰值訊雜比)。同時計算 noisy 和 clean 的 MSE 作為基準,比較降噪前後的改善幅度。

07 延伸

想再往下看,這 5 個

出處

iPAS 經濟部產業人才能力鑑定 ・ 114 年第二梯次 iPAS AI 應用規劃師 中級 科目三 機器學習技術與應用 第 46 題

查看官方原文 PDF