看懂一條光譜,
就能抓出一次食品詐欺

這門課從零開始教你用 RamanSPy 讀懂食品的拉曼光譜。不需要程式基礎 —— 整頁的五個互動實驗台可以直接拉滑桿玩,每一段都附上對應的 Python 程式碼, 想動手再打開 Notebook。

5互動實驗台
5Jupyter Notebook
6光譜資料集
30題自動計分測驗
先玩玩看 ↓ 下載 Notebook
Big picture

食品分析為什麼要用拉曼光譜

拉曼光譜把食品裡的分子振動轉成一條「指紋」。不同成分 —— 脂肪、蛋白質、醣類、色素、添加物 —— 會讓特定波數區域變強或變弱,因此可用於快速篩檢、摻偽判別、品質監測與異物鑑別。

spectrum

🧬 像食品的條碼

每個樣品得到一條 intensity 對 Raman shift 的曲線。峰的位置對應分子的振動模式,跟雷射波長無關。

水干擾小

💧 不怕水

水的拉曼訊號極弱,乳品、飲料、生鮮可以直接測,不用乾燥或萃取。這是它勝過紅外光譜的最大優勢。

reproducible

🔁 流程可重現

RamanSPy 把讀檔、前處理、分析、繪圖整合成一致的介面,整套流程可以寫成一份能重跑的 Notebook。

跟紅外光譜比,該怎麼選

拉曼紅外(IR / NIR)
選擇律極化率改變偶極矩改變
強訊號來自非極性、對稱鍵:C=C、C–C、S–S、環呼吸極性鍵:O–H、C=O、N–H
水的干擾極小很大
樣品前處理幾乎不用,可隔玻璃或塑膠袋測常需研磨、壓片或 ATR 貼合
最大缺點螢光背景;訊號本身很弱水干擾;穿透深度淺

結論 拉曼與 IR 是互補的。IR 上很弱的 C=C(不飽和度)在拉曼上很強, 這正是拉曼特別適合油脂分析的原因;而不怕水讓它適合乳品、飲料、生鮮的現場快篩。

Principle

分子指紋是怎麼來的

用單一波長的雷射照樣品,絕大多數光子被彈性散射(Rayleigh),能量沒變。 但每一千萬個光子裡大約有一個會跟分子的振動交換能量,散射出來的光子能量變了 —— 這就是拉曼散射

拉曼位移 (cm⁻¹) = 1/λ雷射 − 1/λ散射

因為它是「差值」,所以與雷射波長無關:同一物質用 532 nm 或 785 nm 測,峰的位置一樣。 這也是拉曼光譜能建立通用資料庫、能跨儀器比對的原因。

六種食品常見成分的純物質拉曼參考光譜疊圖
六種食品常見成分的拉曼指紋。判讀未知樣品時,就是拿它跟這些參考光譜比對。478 是澱粉、676 是三聚氰胺、1523 是類胡蘿蔔素。

兩個軸各代表什麼

常見誤解 「A 樣品的 1085 峰高 3200,B 只有 1800,所以 A 的醣類比較多。」—— 錯。沒有歸一化、沒有內標,這兩個數字不能比。

互動實驗台 01

混合物的光譜=各成分的疊加

食品是複雜混合物。把下面六種成分的比例拉一拉,看混出來的光譜長什麼樣, 以及程式自動找到的峰對應到哪一個分子。

拉滑桿

合成光譜實驗室

試試看:先只留乳糖,再慢慢加入三聚氰胺 —— 注意 676 cm⁻¹ 什麼時候開始被偵測到。

注意 把「類胡蘿蔔素」只拉到 5%,1523 cm⁻¹ 就已經很明顯了。 這是共振拉曼增強(resonance Raman scattering, RRS) —— 當雷射波長落在分子的電子吸收帶內,散射截面會放大數個數量級。類胡蘿蔔素是這個現象最經典的例子,1970 年就有人在完整的植物組織裡直接測到[1]
沒有一個放諸四海的倍率:增強程度取決於雷射與吸收帶的接近程度。有研究用 488、514、532、633 nm 分別激發 β-胡蘿蔔素,發現 488/514 nm 的共振增強最強,但 532 nm 才是最佳選擇 —— 增強適中,同時螢光與自吸收都比較低[2]。這正是食品拉曼常用 532 nm 的原因。 所以峰很強不等於含量很多,要講濃度就一定得做檢量線。

對應程式碼 NB1 · 建立光譜物件並畫出來

import pandas as pd
import ramanspy as rp

raw = pd.read_csv("data/milk_powder_raw_single.csv")
x = raw["raman_shift_cm-1"].values     # X 軸:拉曼位移
y = raw["intensity"].values            # Y 軸:強度

spectrum = rp.Spectrum(y, x)           # ⚠ 先強度、後波數,順序別寫反
rp.plot.spectra(spectrum, title="奶粉(原始光譜)")
rp.plot.show()
互動實驗台 02

前處理:五個步驟,順序不能亂

儀器直接吐出來的光譜有三個問題:螢光背景、宇宙射線尖峰、隨機雜訊。 前處理沒做好,後面所有統計結果都是精美的垃圾。

原始奶粉拉曼光譜,標示螢光背景、宇宙射線尖峰與真實拉曼峰
儀器直接輸出的光譜。真正的化學資訊只佔其中一小部分,其餘三個都是必須先處理掉的干擾。
  1. 裁切 Cropper 切掉兩端只有雜訊的區段,食品分析慣例留 400–1800 cm⁻¹ 的指紋區。
  2. 去尖峰 WhitakerHayes 真峰有寬度,宇宙射線只有 1–2 點寬。必須排在平滑之前 —— 一旦被平滑抹成小丘,就再也刪不掉了。
  3. 平滑 SavGol 壓低雜訊。視窗開太大會把窄峰抹平,這是最常見的自傷。
  4. 基線校正 IModPoly 扣掉螢光背景。做過頭會把寬帶的真實峰(例如醯胺 I)也當背景減掉。
  5. 歸一化 MinMax 讓不同樣品可比較。一定要放最後,否則尺度又被後面的步驟改掉。
拉滑桿

前處理實驗台

灰色虛線是處理前、湖綠是處理後。試試看:把平滑視窗拉到 41 點以上,盯著 676 cm⁻¹ 那個峰。

1085 cm⁻¹ 乳糖峰
676 cm⁻¹ 三聚氰胺峰
676 峰的半高寬
不同平滑視窗下 676 波數峰的變化
平滑的災難現場。window_length 從 9 加到 71,三聚氰胺的 676 cm⁻¹ 診斷峰幾乎消失 —— 你用自己的前處理刪掉了要找的東西

實用原則 平滑視窗涵蓋的波數範圍,要明顯小於你要偵測的峰的半高寬。 寧可留一點雜訊 —— 雜訊還能靠平均多條光譜壓下去,抹掉的峰救不回來。

對應程式碼 NB2 · 把五個步驟串成一條 Pipeline

pipeline = rp.preprocessing.Pipeline([
    rp.preprocessing.misc.Cropper(region=(450, 1800)),               # ① 裁切
    rp.preprocessing.despike.WhitakerHayes(),                        # ② 去宇宙射線
    rp.preprocessing.denoise.SavGol(window_length=9, polyorder=3),   # ③ 平滑
    rp.preprocessing.baseline.IModPoly(),                            # ④ 基線校正
    rp.preprocessing.normalise.MinMax(),                             # ⑤ 歸一化
])

processed = pipeline.apply(spectra)   # 同一條 pipeline 直接套整批 60 個樣品
print(processed.spectral_data.shape)  # (60, 676) → (樣品數, 波數點數)
基線校正方法怎麼挑?
方法特性適用
IModPoly()多項式迭代,穩定、快、參數少一般食品樣品(本課程預設)
ASLS() / ASPLS()懲罰最小平方,彈性大背景形狀複雜、不像多項式時
AIRPLS()自適應加權迭代螢光極強、背景起伏大時

已知地雷:normalise.AUC() 在 NumPy 2.0 以上會拋出 AttributeError: module 'numpy' has no attribute 'trapz',因為 np.trapz 已被移除。 本課程改用 MinMax()Vector()

互動實驗台 03

峰位判讀:食品分析師真正的價值

會跑程式的人很多,看得懂峰位代表什麼分子的人才值錢。這一段把光譜接回化學。

必背的食品特徵峰

波數 (cm⁻¹)振動歸屬在食品裡代表
478C–C–O / 環變形澱粉(診斷峰)
676三嗪環呼吸三聚氰胺 — 三嗪環 ring breathing II [8,12]
850 / 1085 / 1125C–C、C–O 伸縮醣類(乳糖、蔗糖)
1003苯環呼吸(苯丙胺酸)蛋白質 — 強度穩定,常當內標
1156 / 1523C–C / C=C 共軛鏈類胡蘿蔔素 — ν₂ / ν₁ 共振增強帶 [3,4]
1265=C–H 面內變形(順式)油脂不飽和度
1301CH₂ 扭曲油脂飽和鏈
1441CH₂ 剪式變形油脂總量 — 常當內標
1655C=C 伸縮 醯胺 I不飽和脂肪 蛋白質二級結構
1745C=O 伸縮(酯)三酸甘油酯

陷阱 1655 cm⁻¹ 在油脂樣品裡是 C=C,在蛋白質樣品裡是醯胺 I。 同一個波數、兩種完全不同的歸屬 —— 不先確認基質是什麼,就不能判讀單一波數

動手判讀

未知樣品判讀器

對應程式碼 NB3 · 讓程式自動找峰

ax, peaks, props = rp.plot.peaks(one_spectrum, prominence=0.05, return_peaks=True)
rp.plot.show()
print(peaks)      # → [ 676. 1003. 1085. 1441. ...]

# prominence 是「多凸才算一個峰」的門檻:
#   設太小 → 雜訊全被當成峰
#   設太大 → 小而重要的摻偽物峰被漏掉
# 實務做法:先看你關心的診斷峰有多高,把門檻設在它的一半以下。
互動實驗台 04

奶粉三聚氰胺篩檢:以及這個方法的極限

2008 年毒奶粉事件中,不肖業者加入三聚氰胺以虛增凱氏定氮法測到的「蛋白質」。 拉曼能不能當快篩?我們用 60 個樣品實際檢驗,並誠實回答它夠不夠格。

為什麼選 676 cm⁻¹

好的診斷峰要同時滿足兩個條件:(一)它是目標物最強的峰;(二)基質在那裡沒有峰。 三聚氰胺的三嗪環呼吸(ring breathing II)在 676 cm⁻¹,而奶粉基質(乳糖、酪蛋白)在此處剛好空白 —— 這叫乾淨的分析視窗。文獻上這個峰報導在 674–685 cm⁻¹ 之間,指認為三嗪環的面內變形[11,12];在 SERS 條件下會位移到 ~697–707 cm⁻¹,因為分子是以環上的氮吸附在銀表面、且吸附角度隨濃度改變[13]。比對資料庫時務必確認激發條件與是否用了增強基材。

拉滑桿

摻偽偵測模擬器

左圖是 676 cm⁻¹ 附近的放大光譜,右圖的黑點是 60 個真實樣品的實測值。拉動濃度看什麼時候才會被判定「檢出」。

676 cm⁻¹ 峰強度
判定閾值(空白+3SD)
本方法偵測極限 LOD
換算濃度

對應程式碼 NB4 · 用空白樣品訂判定閾值

i676   = np.argmin(abs(axis - 676))
peak676 = X[:, i676]

blank     = peak676[meta.label == "normal"]      # 20 個空白樣品
threshold = blank.mean() + 3 * blank.std()       # 分析化學的標準做法
detected  = peak676 > threshold

lod = meta.melamine_pct[detected & (meta.melamine_pct > 0)].min()
print(f"判定閾值 = {threshold:.4f}")
print(f"實務偵測極限 LOD ≈ {lod:.2f} %")

這門課最重要的一段 我們算出 LOD ≈ 0.5%,也就是約 5,000 mg/kg。 而 Codex 對三聚氰胺的限量是:粉狀嬰兒配方 1 mg/kg、液態嬰兒配方 0.15 mg/kg、其他食品與飼料 2.5 mg/kg[14]差距超過兩千倍。

所以正確結論是:一般拉曼可以當現場快篩,抓出明目張膽的大量摻假; 但它不能取代 LC-MS/MS 這類法規確認方法。要逼近法規限值需要 SERS(表面增強拉曼), 銀膠可達 10⁵ 倍以上的增強[9],實測已能把牛奶中三聚氰胺的定量極限壓到 0.5 µg/mL[9];用金奈米指狀基材甚至可在嬰兒配方中達到 100 ppb(0.1 mg/kg),低於 FDA 的 1 ppm 容許值[10]。換句話說,要達到法規限值,需要的不是更好的資料處理,而是換一種量測方式

「未檢出」不等於「沒有」。任何檢驗報告都必須同時標示方法的偵測極限,否則這句話沒有意義。

PCA:不給答案,機器能自己看出什麼

PCA 分數圖與 PC1 負荷量
左:分數圖,樣品自動排成一條濃度軸(PC1 與濃度相關係數 0.99)。右:PC1 負荷量 —— 模型盯的正是 676 cm⁻¹,化學上說得通。

專家第一個會問 分數圖分得開,不代表模型是對的 —— 它有可能抓到的是「兩組樣品在不同天量測」這種假訊號。一定要看負荷量,確認模型倚重的波數在化學上說得通。

對應程式碼 NB4 · PCA 與分群

pca = rp.analysis.decompose.PCA(n_components=3)
projections, components = pca.apply(processed)
pc1, pc2, pc3 = projections          # ⚠ 回傳的是 list,projections[0] 才是 PC1 分數

# KMeans 回傳的是「到各群中心的距離」,不是標籤
distances, centers = rp.analysis.cluster.KMeans(n_clusters=2).apply(processed)
labels = np.argmin(np.array(distances), axis=0)

分群結果會把「正常品+低濃度摻偽品」歸成一群,跟標籤對不起來。這不是演算法壞掉 —— KMeans 是無監督的,它只照光譜相似度分堆,而 0.2% 的樣品光譜本來就跟正常品幾乎一樣。 分群對不上標籤,通常是在告訴你:這兩類在你量的訊號上本來就分不開。

互動實驗台 05

定量:橄欖油裡摻了多少葵花油

橄欖油摻便宜油是全球最常見的食品詐欺之一。50 個樣品、摻入比例 0–50%, 這是典型的多變量校正問題,標準工具是 PLS 迴歸。

四種食用油的平均光譜與 PCA 分數圖
左:四種油的平均光譜,差異集中在 1265、1523、1656。右:PCA 分數圖,椰子油(飽和度最高)離群最遠。PCA-LDA 五折交叉驗證正確率 96.7%

先試最簡單的 不動用任何機器學習,光是 1265 / 1441 比值(不飽和度指標) 就能分開大部分油品。簡單方法有效時,它更好解釋、更好轉移到別台儀器、也更好通過查核。

拉滑桿

PLS 潛在變數選擇器

PLS 只有一個關鍵決策:用幾個潛在變數。太少配適不足、太多過度配適。拉拉看,找 RMSECV 的最低點。

RMSECV(交叉驗證誤差)
實用偵測下限(≈3×RMSECV)

把數字翻譯成人話 RMSECV = 3.3% 代表誤差約 ±3.3 個百分點, 這個方法無法可靠偵測 2% 的摻混。實用偵測下限大約落在 RMSECV 的 3 倍,也就是 10% 左右 —— 抓得到大額摻假,抓不到少量摻混。這與文獻上一般拉曼(非 SERS)的表現是同一個數量級。

對應程式碼 NB5 · 選 LV、建模、評估

from sklearn.cross_decomposition import PLSRegression
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import mean_squared_error, r2_score

rmsecv = []
for n in range(1, 11):
    pred = cross_val_predict(PLSRegression(n_components=n), Xa, ya, cv=5).ravel()
    rmsecv.append(mean_squared_error(ya, pred) ** 0.5)

best_lv = int(np.argmin(rmsecv)) + 1      # → 4
pls = PLSRegression(n_components=best_lv).fit(Xa, ya)

# 絕對不能跳過:看模型倚重哪些波數
coef = pls.coef_.ravel()   # 大值應落在 1265 / 1523 / 1656 —— 真正的化學差異

模型不會說「我不知道」 把一個奶粉樣品丟進油品分類器,它一樣會硬選一種油, 而且可能給出很高的信心值。實務上必須加上適用範圍(applicability domain)檢查 —— 光譜殘差過大或馬氏距離超出訓練集範圍時,回報「超出模型適用範圍」而不是給答案。

Full script

完整程式碼:不開 Colab 也能讀完

上面每一段都附了片段。這裡把整條流程接起來 —— 從讀檔到出結果,共 40 行。 看懂這 40 行,這門課的技術部分就結束了。

import numpy as np
import pandas as pd
import ramanspy as rp
from sklearn.cross_decomposition import PLSRegression
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import mean_squared_error

# ---------- 1. 讀檔 ----------
def load_spectra(path):
    """CSV:每列一個樣品,欄名就是波數 → (樣品資訊, 光譜物件)"""
    df = pd.read_csv(path)
    meta_cols = [c for c in df.columns if not c.replace(".", "", 1).isdigit()]
    axis = np.array([float(c) for c in df.columns if c not in meta_cols])
    return df[meta_cols], rp.SpectralContainer(df.drop(columns=meta_cols).values, axis)

meta, spectra = load_spectra("data/milk_powder_melamine.csv")

# ---------- 2. 前處理 ----------
pipeline = rp.preprocessing.Pipeline([
    rp.preprocessing.misc.Cropper(region=(450, 1800)),
    rp.preprocessing.despike.WhitakerHayes(),
    rp.preprocessing.denoise.SavGol(window_length=9, polyorder=3),
    rp.preprocessing.baseline.IModPoly(),
    rp.preprocessing.normalise.MinMax(),
])
processed = pipeline.apply(spectra)
X, axis = processed.spectral_data, processed.spectral_axis

# ---------- 3. 定性:診斷峰 + 判定閾值 ----------
peak676   = X[:, np.argmin(abs(axis - 676))]
blank     = peak676[meta.label == "normal"]
threshold = blank.mean() + 3 * blank.std()
print("檢出樣品數:", int((peak676 > threshold).sum()))

# ---------- 4. 探索:PCA ----------
projections, components = rp.analysis.decompose.PCA(n_components=2).apply(processed)
pc1, pc2 = projections

# ---------- 5. 定量:PLS ----------
ameta, aspectra = load_spectra("data/olive_adulteration.csv")
Xa = pipeline.apply(aspectra).spectral_data
ya = ameta.sunflower_pct.values

pred  = cross_val_predict(PLSRegression(n_components=4), Xa, ya, cv=5).ravel()
rmsecv = mean_squared_error(ya, pred) ** 0.5
print(f"RMSECV = {rmsecv:.2f} %")
step 1

讀懂就好

第一次讀不用每行都懂。先抓住五個區塊的名字:讀檔、前處理、定性、探索、定量。

step 2

再動手改

打開 Notebook,把 window_lengthn_components 改一個數字再跑,看結果怎麼變。

step 3

最後自己寫

換一組資料、換一個診斷峰,重跑同一條流程。能做到這一步就算學會了。

Hands-on

五本 Notebook 與課程資料

每一本約 50–70 分鐘,採「逐格執行」設計,每格只做一件事,程式碼旁邊用中文說明為什麼要做。 遇到 👉 換你做 就停下來改一個參數再跑一次。結尾都有自我檢核題與參考答案。

課程資料集

檔名內容用在
milk_powder_raw_single.csv一條未處理的奶粉光譜(含螢光、尖峰、雜訊)NB1、NB2
reference_spectra.csv六種純物質參考光譜NB3
milk_powder_melamine.csv60 個奶粉樣品,三聚氰胺 0–5%NB2、NB4
edible_oils.csv60 個油品樣品:橄欖、葵花、大豆、椰子各 15NB3、NB5
olive_adulteration.csv50 個橄欖油摻葵花油樣品,0–50%NB5
unknown_samples.csv6 個未知樣品(期末判讀用)NB3、NB5、期末

關於資料 這些是依文獻峰位建立的模擬光譜,刻意加入螢光背景、宇宙射線與雜訊, 讓你在教室裡就能遇到真實儀器會出的狀況,同時濃度與答案完全可控、方便驗算。 課程結論(偵測極限、模型誤差)與真實文獻報告的數量級一致。

Data provenance

數據從哪裡來

這一節必須講清楚,因為它決定你能用這些數字說到什麼程度。

最重要的一句 本課程 data/ 裡的六組光譜全部是依文獻峰位建立的模擬資料, 不是實測光譜。它們用來教流程與判讀邏輯;不可以引用為實驗證據,也不能拿來寫報告的數據來源。

怎麼生成的

  1. 純物質骨架 每個成分用一組 Lorentzian 峰疊出來,峰位取自下表的文獻值,半高寬 8–25 cm⁻¹、 相對強度依文獻描述的強弱關係設定。
  2. 混合 按濃度線性疊加(拉曼在稀薄混合物中對濃度近似線性),三聚氰胺另乘上一個散射截面係數。
  3. 加上儀器的毛病 螢光背景用 0.9·e−2.2t + 0.5t² + 0.25 的經驗式, 再隨機插入 0–2 根寬度 1–2 點的宇宙射線尖峰,最後加高斯雜訊(σ ≈ 0.012–0.02)。
  4. 樣品間變異 每個樣品的成分係數再乘上一個小的隨機擾動,模擬批次差異。

完整程式在 make_data.py,亂數種子固定(20260801),任何人重跑都會得到同一組資料。

峰位的文獻依據

成分使用的峰位 (cm⁻¹)依據
類胡蘿蔔素1008 (ν₃)、1156 (ν₂)、1523 (ν₁)[3][4][6]
油脂骨架1063、1080、1301、1441、1745[6]
不飽和度1265 (=C–H)、1656 (C=C)[6][7]
三聚氰胺583、676、984、1435[8][11][12]
乳糖 / 醣類355、440、850、1085、1125、1265、1460[16]
酪蛋白 / 蛋白質1003 (Phe)、1240 (醯胺 III)、1450、1655 (醯胺 I)[16]
澱粉478、865、940、1082、1126、1260、1380、1460[16]

結果對得上文獻嗎

本課程算出的數值文獻上同類方法的量級
三聚氰胺 LOD(一般拉曼)≈ 0.5%(5,000 mg/kg) 一般拉曼可在奶粉中辨識 1% 的三聚氰胺 [8];要到 mg/kg 級需 SERS [9][10][11]
四種食用油分類正確率96.7%(PCA-LDA,5 折 CV) 橄欖油品種/種類判別常報 90–100% [6]
橄欖油摻混定量RMSECV 3.26%、R² 0.952(PLS, LV=4) 拉曼+PLS 對摻混比例的預測誤差多在數個百分點 [7]

量級一致,但這是設計出來的一致 —— 因為模擬時就把雜訊與變異調到那個範圍。 它證明的是「這條流程會給出合理的數字」,不是「拉曼真的能做到這個數字」。

想用真資料 RamanSPy 內建了幾組公開資料集可以直接呼叫,例如 rp.datasets.rruff()(RRUFF 礦物拉曼資料庫)與 rp.datasets.bacteria(); 食品類的公開光譜可查 Mendeley Data、Zenodo 與各校的 open data 平台。 做專題時請改用實測或公開實測資料,本課程資料僅供教學演練。

References

參考文獻

共振拉曼增強

  1. Gill, D.; Kilponen, R. G.; Rimai, L. Resonance Raman Scattering of Laser Radiation by Vibrational Modes of Carotenoid Pigment Molecules in Intact Plant Tissues. Nature 1970, 227(5259), 743–744. doi:10.1038/227743a0 —— 最早在完整植物組織中直接觀測到類胡蘿蔔素的共振拉曼訊號;激發波長落在電子吸收帶內時,散射效率大幅提升到足以克服吸收損失。
  2. Lu, L.; Shi, L.; Secor, J.; Alfano, R. Resonance Raman scattering of β-carotene solution excited by visible laser beams into second singlet state. J. Photochem. Photobiol. B 2018, 179, 18–22. doi:10.1016/j.jphotobiol.2017.12.022 —— 以 488/514/532/633 nm 比較 β-胡蘿蔔素的共振增強並校正自吸收;488/514 nm 增強最強,但 532 nm 為最佳折衷(螢光與自吸收較低)。本課程採 532 nm 的依據。
  3. Withnall, R.; Chowdhry, B. Z.; Silver, J.; Edwards, H. G. M.; de Oliveira, L. F. C. Raman spectra of carotenoids in natural products. Spectrochim. Acta A 2003, 59(10), 2207–2212. doi:10.1016/S1386-1425(03)00064-7 —— ν₁(C=C,1400–1600)與 ν₃ 強烈增強;ν₁ 位置隨共軛雙鍵數增加而往低波數移動,可用來推估共軛鏈長。
  4. de Oliveira, V. E.; Castro, H. V.; Edwards, H. G. M.; de Oliveira, L. F. C. Carotenes and carotenoids in natural biological samples: a Raman spectroscopic analysis. J. Raman Spectrosc. 2010, 41(6), 642–650. doi:10.1002/jrs.2493 —— β-胡蘿蔔素三個特徵帶 1515、1156、1008 cm⁻¹。特別注意:作者明確警告,類胡蘿蔔素與基質的分子交互作用會使 C=C 帶明顯位移,因此「拿標準品光譜直接比對就下結論」在真實生物樣品上是危險的 —— 這正是本課程反覆強調「先確認基質」的文獻依據。
  5. Le Ru, E. C.; Auguié, B. Enhancement Factors: A Central Concept during 50 Years of Surface-Enhanced Raman Spectroscopy. ACS Nano 2024, 18(14), 9773–9783. doi:10.1021/acsnano.4c01474 —— 增強因子的定義、平均值與最大值的差異、熱點分布與量測方式。引用任何「增強幾倍」的數字前建議先讀這一篇。

食用油與橄欖油

  1. Portarena, S.; Anselmi, C.; Zadra, C.; Farinelli, D.; Famiani, F.; Baldacchini, C.; Brugnoli, E. Cultivar discrimination, fatty acid profile and carotenoid characterization of monovarietal olive oils by Raman spectroscopy at a single glance. Food Control 2019, 96, 137–145. doi:10.1016/j.foodcont.2018.09.011 —— 特級初榨橄欖油特徵帶:965、1004、1081、1156、1301、1440、1523、1656、1748 cm⁻¹(514.5 nm 激發,與類胡蘿蔔素共振)。
  2. Chen, Y.; Yang, Z.; Zeng, S.; Tian, H.; Cheng, Q.; Lv, S.; Li, H. Quantitative analysis of β-carotene and unsaturated fatty acids in blended olive oil via Raman spectroscopy combined with model prediction. Food Chemistry 2025, 470, 142621. doi:10.1016/j.foodchem.2024.142621 —— 以 1156、1265、1526、1658 cm⁻¹ 配合模型預測橄欖油/葵花油摻混比例。與本課程 NB5 的作法相同,可作為 PLS 迴歸係數落點的對照。

三聚氰胺:一般拉曼、SERS 與法規

  1. Schmidt, W.; Broadhurst, C. L.; Qin, J.; et al. Continuous Temperature-Dependent Raman Spectroscopy of Melamine and Structural Analog Detection in Milk Powder. Appl. Spectrosc. 2015, 69(3), 398–406. doi:10.1366/14-07600 —— 不用 SERS,以一般拉曼在奶粉中辨識 1% 的三聚氰胺(及尿素、縮二脲、三聚氰酸)。本課程算出的 LOD ≈ 0.5% 與這個量級相符。
  2. Zhang, X.; Zou, M.; Qi, X.; et al. Detection of melamine in liquid milk using surface-enhanced Raman scattering spectroscopy. J. Raman Spectrosc. 2010, 41(12), 1655–1660. doi:10.1002/jrs.2629 —— 銀膠達 10⁵ 倍以上增強;標準品 LOD 0.01 µg/mL,牛奶中定量極限 0.5 µg/mL,結果與 LC-MS/MS 相當。
  3. Kim, A.; Barcelo, S. J.; Williams, R. S.; Li, Z. Melamine Sensing in Milk Products by Using Surface Enhanced Raman Scattering. Anal. Chem. 2012, 84(21), 9303–9309. doi:10.1021/ac302025q —— 金奈米指狀基材配可攜式拉曼儀,水中 LOD 120 ppt、嬰兒配方中 100 ppb,低於 FDA 的 1 ppm 容許值
  4. Wang, S.; Zhao, Y.; Wei, X.; et al. Facile SERS screening of melamine in bovine milk with 2D printed AgNPs/glass fabric filter paper as the flexible substrate. Food Sci. Hum. Wellness 2024, 13(5), 2595–2600. doi:10.26599/fshw.2022.9250208 —— 診斷訊號在 674 cm⁻¹,LOD 1.95×10⁻⁵ mg/mL,遠低於歐美 2.5×10⁻³ mg/mL 的安全限值。(開放取用)
  5. Cheng, J.; Wang, S.; Su, X. Detection of Melamine in Feed Using Liquid-Liquid Extraction Treatment Combined with Surface-Enhanced Raman Scattering Spectroscopy. PLoS ONE 2014, 9(9), e107770. doi:10.1371/journal.pone.0107770 —— 明確指認 ring breathing II 模式為三嗪環的面內變形。(開放取用)
  6. Chen, X.; Hu, Y.; Gao, J.; et al. Interaction of Melamine Molecules with Silver Nanoparticles Explored by SERS and Density Functional Theory Calculations. Appl. Spectrosc. 2013, 67(5), 491–497. doi:10.1366/12-06838 —— 三聚氰胺以環上氮吸附於銀表面,且傾角隨濃度改變 —— 這是 SERS 條件下峰位會位移的原因。
  7. FAO / WHO Codex Alimentarius Commission. General Standard for Contaminants and Toxins in Food and Feed, CXS 193-1995. —— 三聚氰胺最大限量:粉狀嬰兒配方 1 mg/kg、其他食品與飼料 2.5 mg/kg(2010 年通過);液態嬰兒配方 0.15 mg/kg(2012 年通過)。

方法與工具

  1. Georgiev, D.; Pedersen, S. V.; Xie, R.; Fernández-Galiana, Á.; Stevens, M. M.; Barahona, M. RamanSPy: An Open-Source Python Package for Integrative Raman Spectroscopy Data Analysis. Anal. Chem. 2024, 96(21), 8492–8500. doi:10.1021/acs.analchem.4c00383 · GitHub(開放取用,CC-BY)
  2. 一般食品成分的拉曼歸屬(醣類 C–C/C–O 伸縮、蛋白質苯丙胺酸 1003 與醯胺 I/III、澱粉 478)採用食品拉曼光譜教科書與綜述的常用歸屬表。授課時建議請學生自行比對 RRUFF 或儀器廠商的標準品資料庫,確認自己手上儀器的實際峰位。
  3. 前處理演算法:Savitzky–Golay 平滑;Whitaker–Hayes 去尖峰;ModPoly / asPLS / airPLS 基線校正。實作與參數說明見 RamanSPy 文件。

核對方式 本頁 [1]–[15] 的書目資料於 2026 年 8 月以 scite 逐筆查核(DOI、期刊、卷期、頁碼、作者),並以 Consensus 搜尋補齊共振拉曼增強的原始文獻。凡查不到同儕審查來源的說法(例如原先引用的專書章節與雜誌專欄)已改引可查核的期刊論文。

給學生的提醒 寫報告引用峰位時,要引原始文獻,不要引這一頁。 同一個官能基在不同基質、不同激發波長下的峰位會有數個 cm⁻¹ 的差異, 務必確認你引的文獻用的是什麼樣品、什麼雷射。

教師備註 建議三週進度:第 1 週原理+NB1、NB2;第 2 週峰位判讀+NB3+未知樣品分組討論; 第 3 週 NB4、NB5,以 LOD 與法規限量的落差做結論討論。評量建議:Notebook 執行截圖 30%、線上測驗 30%、 未知樣品判讀報告 40%(推理過程重於答對與否)。