Olive Oil Multi-block:多儀器資料融合與食品認證
這一章使用 Olive oils multi-block dataset。你不再只看一種 NIR 光譜,而是同時處理 UV–vis、NIR、e-tongue、e-nose 等多個資料 block,用 data fusion 做 PDO / 產地或真偽認證。
樣本
橄欖油樣本,用於 Chianti Classico PDO authentication。
資料 blocks
UV–vis、NIR、e-tongue、e-nose。
核心挑戰
樣本少、變數多,必須嚴格驗證避免 overfitting。
multi-blockblock scalinglow-level fusionmid-level fusion
真實食品認證常常不是單一儀器能完成
入門與中階的資料都是單一矩陣 X;進階資料變成多個 blocks。每個 block 描述食品的不同面向:光學吸收、揮發性氣味、味覺感測或其他化學指紋。
| Block | 變數數 | 可能提供的資訊 |
|---|---|---|
| UV–vis | 441 | 色素、氧化與吸收特徵 |
| NIR | 1126 | 油脂、O–H / C–H 相關吸收 |
| e-tongue | 3945 | 味覺 / 電化學指紋 |
| e-nose | 46 | 揮發性氣味指紋 |
先分開分析每個 block
進階分析的第一步不是把所有變數直接合併,而是先理解每個 block 自己能提供多少分類資訊。
blocks = {
"uvvis": X_uvvis,
"nir": X_nir,
"enose": X_enose,
"etongue": X_etongue,
}
for name, Xb in blocks.items():
Xbs = StandardScaler().fit_transform(Xb)
T = PCA(n_components=2).fit_transform(Xbs)
# plot T[:,0], T[:,1], colored by PDO / non-PDO
| 你要比較 | 問題 |
|---|---|
| PCA 分群 | 哪個 block 最能自然分開類別? |
| 單一 block 分類 | NIR only、e-nose only、e-tongue only 哪個表現最好? |
| 變數數量 | 變數多的 block 是否容易 overfit? |
不同 blocks 變數數量差很多,不能直接粗暴合併
如果直接把 3945 個 e-tongue 變數和 46 個 e-nose 變數合併,變數多的 block 可能主導模型。Block scaling 的目的是讓每個 block 在融合前有比較公平的權重。
import numpy as np
from sklearn.preprocessing import StandardScaler
def block_scale(X):
Xs = StandardScaler().fit_transform(X)
norm = np.linalg.norm(Xs, ord="fro")
return Xs / norm if norm > 0 else Xs
scaled_blocks = {name: block_scale(Xb) for name, Xb in blocks.items()}Low-level fusion vs Mid-level fusion
Low-level fusion
先前處理與 block scaling,再直接合併所有原始變數。
X_low = np.hstack([
scaled_blocks["uvvis"],
scaled_blocks["nir"],
scaled_blocks["enose"],
scaled_blocks["etongue"],
])Mid-level fusion
每個 block 先 PCA 降維,再合併各 block 的 scores。
from sklearn.decomposition import PCA
scores = []
for name, Xb in scaled_blocks.items():
Tb = PCA(n_components=5).fit_transform(Xb)
scores.append(Tb)
X_mid = np.hstack(scores)| 融合方式 | 優點 | 風險 |
|---|---|---|
| Low-level | 保留最多原始資訊,概念簡單 | 維度非常高,容易 overfit |
| Mid-level | 降維後更穩定,適合小樣本 | PCA 可能丟掉和分類有關但變異小的訊號 |
進階課最重要的是誠實驗證
Multi-block 資料通常樣本少、變數多。任何前處理、PCA、特徵選擇都必須放在 cross-validation 的訓練折內,否則測試表現會被高估。
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
model = Pipeline([
("scaler", StandardScaler()),
("svm", SVC(kernel="linear", C=1))
])
scores = cross_val_score(model, X_mid, y_class, cv=cv, scoring="balanced_accuracy")
print(scores.mean(), scores.std())最後要回答:融合是否真的有幫助?
| 模型 | 輸入 | 要報告 |
|---|---|---|
| NIR only | NIR block | balanced accuracy、confusion matrix |
| e-nose only | e-nose block | 是否提供互補氣味資訊 |
| Low-level fusion | 所有 block 原始變數 | 是否提升,是否過擬合 |
| Mid-level fusion | 各 block PCA scores | 是否較穩定、較可解釋 |
如果 fusion 只比最佳 single-block 好一點點,而且變異很大,不能直接宣稱融合比較好。你需要用 repeated CV、外部測試集或 permutation test 支持結論。
Orange 建議從 Python 輸出的 fusion CSV 開始
Python:
read blocks → autoscale → block scaling
→ PCA per block for mid-level fusion
→ export olive_oil_midlevel_fusion.csv
Orange:
File → Select Columns
→ PCA / Scatter Plot
→ Test and Score ← SVM / Random Forest / Logistic Regression
→ Confusion Matrix你已完成從成分定量到資料融合的學習路徑
這三個頁面形成一條完整路徑:Tecator 肉品成分預測 → Coffee–Barley 摻偽分析 → Olive Oil 多儀器融合認證。