高光譜成像,讓每個像素都有一條光譜

用真實開源資料 SpectroFood(蘋果·花椰菜·韭蔥·蘑菇),走一遍化學計量學三步:
PCA 看結構、分類辨食材、PLS 迴歸測乾物質。

1028真實樣本
141共同可見光波段
94.6%PCA 前 2 主成分
100%四食材分類準確率
0.84乾物質 PLS R²
為什麼是高光譜

影像 × 光譜:每個像素一條指紋

一般相機每個像素只有 RGB 三個數字;高光譜成像(Hyperspectral Imaging, HSI)讓每個像素都記錄一整條光譜—— 把影像(空間 x, y)和光譜(波長 λ)疊成一個「資料立方體」。在可見-近紅外(Vis-NIR)波段,這條光譜反映了水分、糖、色素等成分, 讓我們能不接觸、不破壞地一次看出整顆水果或整片葉菜的化學分布。

🧊

資料立方體

每個像素一條光譜,整張影像就是 (x, y, λ) 的三維資料——空間與光譜同時到手。
🌈

Vis-NIR 看成分

可見光看顏色/色素,近紅外看 O–H、C–H 等鍵結,對應水分與乾物質。
⚠️

但是…

每個樣本是上百個高度相關的數字,必須靠化學計量學(PCA / 分類 / PLS)才能解讀。
  食材 ──▶ 高光譜相機 ──▶ 資料立方體 (x, y, λ) ──▶ 取每個樣本平均光譜 ──▶ 整理成「樣本 × 波段」資料矩陣
🎬 教學影片 · 中文旁白約 4 分 · 完整工作流導覽 · YouTubeEnglish version
本課三步走: 先用 PCA(非監督)看資料結構,再用 SVM / 隨機森林(監督)分辨四種食材,最後用 PLS(迴歸)把光譜換算成乾物質含量。
資料集

SpectroFood:四種食材的真實光譜(開源)

資料來自 SpectroFood 開源資料集(Zenodo 8362947):蘋果、花椰菜、韭蔥、蘑菇的 Vis-NIR 反射光譜,並附實驗室量得的乾物質含量。 共 1028 個樣本,全部數字皆由 analysis/run_analysis.py 實際執行產生、可重現。

食材 food樣本數本課用途
蘋果 Apple240PCA 探索 · 分類
花椰菜 Broccoli250PCA 探索 · 分類
韭蔥 Leek288分類 · PLS 乾物質迴歸
蘑菇 Mushroom250PCA 探索 · 分類
關鍵設計: 四種食材用不同相機量測,波段範圍不一。為了公平比較與分類,只取四者共同的 141 個可見光波段(398–773 nm); 而乾物質迴歸改用韭蔥的完整光譜(421 波段,延伸到 1717 nm 近紅外)——因為成分資訊主要落在 NIR。

先看原始光譜,再做 SNV 前處理

不同樣本因表面散射、量測距離不同,整條光譜會上下平移或縮放。SNV(Standard Normal Variate,標準正態變量)逐樣本減平均、除標準差, 消除這種散射差異,讓真正的化學形狀浮現——這是光譜分析的標準前處理。

四種食材的原始光譜與 SNV 標準化後
左:四種食材的平均反射光譜(陰影為標準差),可見光與紅邊區已標出;右:SNV 標準化後消除散射差異,形狀差異更清楚。
方法一 · 非監督

PCA:把上百個波段壓成幾個方向

主成分分析(Principal Component Analysis)在資料最分散的方向上建立新座標軸:PC1 是變異最大的方向、PC2 與它垂直且次大…… 少數幾個主成分就能描述最重要的結構,把高維光譜畫成一張看得懂的散布圖。

$X \approx T\,P^{\top}$  —  分數 $T$ 是樣本位置、負荷量 $P$ 是波段如何組成新方向
PCA 解釋變異量與散布圖
左:PC1 解釋 71.6%、PC2 解釋 23.0%,前兩個主成分就累積 94.6%;右:散布圖上四種食材自然分成四群。
核心觀念: PCA 是非監督的——它沒看過「這是哪種食材」的標籤,只看光譜,卻能讓四種食材自己分群。它擅長探索、分群、找異常, 但不會直接告訴你「這是什麼」。
方法二 · 監督分類

分類:用光譜辨認是哪種食材

把 SNV 光譜切成訓練/測試集(75% / 25%),交給監督式分類器學「光譜 → 食材」的對應。 這裡用 SVM(支援向量機)隨機森林(Random Forest) 兩種模型,在獨立測試集上驗證。

SVM 分類混淆矩陣
SVM 在 257 個測試樣本上的混淆矩陣:對角線全中——四種食材沒有一個認錯

SVM 準確率

100%
RBF 核 + 標準化,測試集 257 樣本全對。

隨機森林

100%
300 棵樹,同樣達到滿分。

為什麼這麼準?

四種食材的光譜差異很大、樣本充足,SNV 後在高維空間幾乎線性可分。真實食品鑑別通常更難,別把 100% 當常態。
應用: 把「食材種類」換成別的標籤,同一套流程就是食品鑑別主力——產地溯源、品種鑑別、新鮮度分級、摻偽偵測
方法三 · 監督迴歸

PLS:把光譜換算成乾物質含量

分類給的是「類別」;很多時候我們要的是一個連續數值,例如乾物質、糖度、含水量。 偏最小二乘迴歸(PLS Regression)找出的潛在變量同時解釋光譜變異、又對齊目標數值,是光譜定量的標準方法。

$\max\ \operatorname{cov}(Xw,\ y)$  —  每個潛在變量最大化光譜 $X$ 與目標 $y$(乾物質)的共變異

這裡用韭蔥的完整光譜(421 波段,延伸到 1717 nm 近紅外)來預測乾物質——因為水分、有機物的吸收主要在 NIR, 只用可見光是不夠的。以 12 個潛在變量10 折交叉驗證誠實評估。

PLS 預測乾物質 vs 實際
288 個韭蔥樣本,預測 vs 實際乾物質:10 折交叉驗證 R²=0.84、RMSE=0.96%,點大致落在 1:1 線附近。
為什麼用近紅外: 分類只要看得出「不一樣」就好,可見光足夠;但要量出成分含量,得靠近紅外的鍵結吸收資訊。這也是為什麼乾物質迴歸要用韭蔥的完整 Vis-NIR 光譜。
怎麼算的

Python 程式(scikit-learn)

整套分析用 numpy / pandas / scikit-learn 完成、可重現,完整檔案見 analysis/run_analysis.py

前處理 — SNV(逐樣本標準化,消除散射)

def snv(a):
    """Standard Normal Variate:逐樣本減平均、除標準差。"""
    return (a - a.mean(1, keepdims=True)) / a.std(1, keepdims=True)

Xsnv = snv(Xc)          # Xc = 樣本 × 141 共同波段

PCA — 主成分分析

from sklearn.decomposition import PCA
pca = PCA(n_components=10).fit(Xsnv)
scores = pca.transform(Xsnv)              # 樣本在新軸上的位置
ev = pca.explained_variance_ratio_        # PC1=71.6%, PC2=23.0%, 前2累積=94.6%

分類 — SVM + 隨機森林(獨立測試集)

from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

Xtr, Xte, ytr, yte = train_test_split(Xsnv, food, test_size=0.25,
                                      random_state=42, stratify=food)
svm = make_pipeline(StandardScaler(), SVC(kernel="rbf", C=10)).fit(Xtr, ytr)
rf  = RandomForestClassifier(n_estimators=300, random_state=42).fit(Xtr, ytr)
# 測試集 257 樣本:SVM 100%、RF 100%

PLS 迴歸 — 韭蔥乾物質(10 折 CV)

from sklearn.cross_decomposition import PLSRegression
from sklearn.model_selection import cross_val_predict

pls = PLSRegression(n_components=12)
yhat = cross_val_predict(pls, snv(X_leek), dry_matter, cv=10)
# R² = 0.84, RMSE = 0.96%(韭蔥 421 波段,至 1717 nm)
▶ 如何在本機重跑
pip install numpy pandas scipy scikit-learn matplotlib spectral
cd analysis
python run_analysis.py     # 下載/讀取 SpectroFood、SNV、PCA、SVM/RF、PLS
# 圖輸出到 assets/images/,數字輸出到 results.json
不寫程式的版本

用 Orange Data Mining 親手拉一遍

課堂可用 Orange(搭配 Orange-Spectroscopy 外掛)的拖拉式 widget,不寫一行程式就重現上面的 PCA、分類與迴歸。 開啟 analysis/spectrofood_workflow.ows 即可。

          ┌─ Data Table              (檢視原始光譜)
          │
 File ────┼─ Preprocess Spectra (SNV) ─┬─ PCA ──▶ Scatter Plot         ← PCA 分群(Color = food)
(Spectro  │                            │
 Food)    │                            ├─ Test & Score ← SVM / Random Forest ──▶ Confusion Matrix   ← 分類
          │                            │
          └────────────────────────────┴─ PLS Regression ──▶ Predictions   ← 乾物質迴歸(韭蔥)
對應概念Python 圖Orange widget
光譜指紋(原始 / SNV)fig1File → Preprocess Spectra → Spectra
主成分散布圖fig2PCA → Scatter Plot(Color = food)
分類 + 混淆矩陣fig3SVM / Random Forest → Test & Score → Confusion Matrix
乾物質迴歸fig4PLS Regression → Predictions / Scatter Plot
總結

PCA、分類、PLS:一張表看懂

面向PCA分類(SVM/RF)PLS 迴歸
學習方式非監督監督(類別)監督(數值)
目的探索、分群、找異常辨認類別(食材/品種)預測連續量(乾物質)
本課結果前 2 PC = 94.6%,四群自分測試集 100% 準確率R²=0.84、RMSE=0.96%
關鍵圖散布圖(fig2)混淆矩陣(fig3)預測 vs 實際(fig4)
帶走兩句話: 高光譜把每個像素變成一條化學指紋;PCA 看結構、分類辨身分、PLS 量成分——同一套化學計量學,撐起非破壞食品檢測的大半江山。