Food Analysis Lab · W12
← → / Space to change slide · F fullscreen · Tap either side to turn pages
Food Analysis Lab · W12

Principal Component Analysis PCA: Classifying Edible Oils

Principal Component Analysis — Classifying Edible Oils by Spectra
Food Analysis Lab · 4-hour session
Six edible oils × Raman 785 nm / each group's NIR · Orange PCA (Data→Scatter, Components→Spectra) · Colab / R
PCA scores/loadingsmean-centeringno autoscalingscree plotOrange PCA
Before we start, watch three factory videos
A mislabeled “olive oil”:
can you tell from the spectrum?

Olive oil line (12:20–13:44, extra virgin grading, prone to adulteration) ↗ Canola oil line (12:02–13:31, deodorizing and refining / acid value / peroxide value) ↗ Soybean oil line (08:00–09:28, hexane extraction) ↗

A note from the videos: beyond sensory evaluation, grading extra virgin olive oil (EVOO) legally also requires indices such as K232/K270, and it is easily adulterated or mislabeled — which is exactly today's question.

Today's question: if a bottle of oil is mislabeled (say, labeled “extra virgin olive oil” but actually blended with refined olive oil or another oil), can spectra + PCA reveal it? (We'll come back to this at the score plot — but you'll also see that PCA can sometimes be fooled by a single outlier.)

W12 / PCA COURSE TOUR

Edible-oil PCA: from clusters to evidence

Full narration and captions; original simulated course spectra. Player and downloads · Interactive lab

W12 / PREDICT · OBSERVE · EXPLAIN

Six acts: projection, PCA, and outlier refitting

Today’s learning goals

After W12 you should be able to…

  • Know that spectral data is simply a table of numbers, samples × wavenumbers; PCA looks for the direction of greatest variance in the data, and PC1 ⟂ PC2
  • Know that a score is a weighted sum of the loadings — and tell apart what scores (where the samples sit) and loadings (which wavelengths drive it) each answer
  • Work through mean-centering and autoscaling by hand once, and explain why spectral data usually gets only the former
  • Understand how the eigenvalue and the explained variance are calculated, and say where the elbow of the scree plot is
  • In Orange, connect PCA's Data output (not Transformed Data) to Scatter Plot to color by class, and Components to Spectra to view the loadings
  • Read a score plot for replicate consistency and outlier samples, and know that a single outlier can hijack an entire PC — when you find one, go back to the spectrum, record the reason, and redo the PCA
Data table X

One row = one spectrum, one column = one wavenumber

Sample900 cm⁻¹915 cm⁻¹931 cm⁻¹946 cm⁻¹961 cm⁻¹…
EVOO_r10.0050.013-0.0110.0040.004…
COC_r10.0150.048-0.002-0.0210.048…
SOY_r1-0.018-0.041-0.0460.007-0.016…
PEA_r30.0840.073-0.0260.0770.095…
…(18 spectra in total)…(60 wavenumber columns in total)
  • Today's data: 18 spectra × 60 wavenumbers = 1080 numbers (6 oils × 3 replicates; 60 points taken from each spectrum between 900 and 1800 cm⁻¹)
  • Each spectrum = one row of the table; each wavenumber = one column; each sample is really a point in 60-dimensional space
  • Our eyes and screens can only handle 2–3 dimensions — what PCA does is project this 60-dimensional point cloud onto a few of the “most representative” directions

The table values come from the same CSV used in Colab NB10 (nb10_demo_spectra.csv), not made up separately.

Data · a small example

Look at two wavenumbers together: they vary together

  • Plot just 1655 cm⁻¹ against 1265 cm⁻¹ (both related to unsaturation): coconut oil is low on both, soybean oil is high on both
  • The 18 points line up almost on a diagonal: correlation coefficient r ≈ 0.99 (calculated as in W04 ↗, only here the two quantities are wavenumbers)
  • Because the two wavenumbers vary together (are correlated), PCA can describe both with a single direction — that direction is “degree of unsaturation”, i.e., PC1

Values are taken from column 50 (1647 cm⁻¹) and column 25 (1266 cm⁻¹) of the same spectral dataset, not invented.

Principle

What PCA looks for: the direction of greatest variance

PCA looks for the direction of “greatest variance” in the data Intensity at original wavenumber 1 → ↑ Intensity at original wavenumber 2 PC1 (direction of greatest variance) PC2 (perpendicular to PC1, next-greatest variance) Each point = one spectrum; PCA never looks at the labels and finds directions from the variance in the spectra alone (unsupervised)
  • PC1: the direction of greatest variance in the data; PC2: the direction perpendicular to PC1 with the next-greatest variance — the two are orthogonal to each other (⟂)
  • PCA is an unsupervised method — it has no idea which oil a sample is and separates samples using only the variance in the spectra
  • So if different oils really separate on the score plot, it means the input spectra differ; but whether the difference truly comes from chemical composition still has to be confirmed with the loadings, the raw spectra and the measurement conditions — and you'll shortly see that the difference can also be misled by a single outlier
Principle

Score = weighted sum of the loadings

t = p₁(x₁−x̄₁) + p₂(x₂−x̄₂) + p₃(x₃−x̄₃) + …

t = the sample's score on this PC; pⱼ = the loading (weight) of wavelength j; xⱼ−x̄ⱼ = the mean-centered value at that wavelength

p=[0.6, 0.6, 0.53], centered x=[0.5, 0.4, 0.3]
t = 0.6×0.5 + 0.6×0.4 + 0.53×0.3 = 0.30+0.24+0.159 ≈ 0.70
  • Loading: the “weight” of each wavelength on this PC — it determines “why” the samples separate
  • Score: multiply each wavelength's (mean-centered) signal by its weight and add them up — this is the sample's coordinate on the plot
  • The larger the loading (positive or negative), the more that wavelength influences this PC; a loading near 0 means that wavelength barely affects this PC
Mini-game ①Should this question look at scores or loadings?0 / 8
Sort the 8 questions below into “questions answered by scores” or “questions answered by loadings”.
Preprocessing · work one out

Work through mean-centering and autoscaling once

WavelengthRaw value xx − x̄ (mean-centered)÷ SD (autoscaled)
Signal wavelength0.8 / 1.0 / 1.2−0.2 / 0 / 0.2−1 / 0 / 1
Noise wavelength1.001 / 0.999 / 1.0000.001 / −0.001 / 01 / −1 / 0

Both rows use the sample standard deviation (SD) (calculated as in W01 ↗; signal row SD=0.2, noise row SD=0.001).

  • Mean-centering: subtract each row's own mean (1.0) from its three values — so PCA looks for variance “relative to the mean spectrum”; this preprocessing is almost always required
  • Autoscaling: divide by each row's own standard deviation after centering — the signal wavelength and the noise wavelength both end up on the same −1/0/1 scale
  • Here is the problem: the noise wavelength originally had a tiny signal (SD=0.001), yet after dividing it looks just as “prominent” as the signal wavelength — the noise has been amplified, which is why spectral data usually skips autoscaling
Preprocessing options

SNV / derivatives: whether to apply them before PCA

📐
SNV (standard normal variate)
Do an SNV first (see W11 ↗): it removes the intercept/slope differences caused by particle-size scattering, so the variance PCA finds is closer to real chemical differences
📉
First / second derivative
Do a derivative first (see W11 ↗): it removes baseline drift, but also amplifies high-frequency noise — think twice before using it
🧪
Today's demo: mean-centering only
Today's score plot and loadings come from PCA on the raw intensities with mean-centering only — no SNV or derivatives; we leave that comparison for the assignment
This demo uses mean-centering only, no autoscaling; in the Orange PCA widget, remember to uncheck “Normalize variables” (it is on by default).
Principle

Eigenvalue and explained variance

λₐ = variance of the scores on the a-th PC (eigenvalue)
Explained variance % = λₐ / Σλᵢ × 100%

The larger λₐ is, the more spread out the samples are along the a-th PC — and the more “important” that PC is.

  • Today's six-oil data: PC1 ≈ 46.3%, PC2 ≈ 28.3%, PC3 ≈ 23.0%, and everything from PC4 on adds up to only 0.53%
  • Scree plot: a bar chart of the explained variance of each PC, used to decide “how many PCs are enough to look at”
  • ⚠️ Don’t confuse this λ with the λ (smoothness parameter) in W11 ↗ ALS baseline correction — they are two completely different things that just happen to share the Greek letter λ
Data · Scree

Scree plot: explained variance falls with each PC

Data come from the actual PCA of the same NB10 spectra. The first 3 PCs together explain 97.7%, PC4 only 0.53% (<1%): the elbow is clearly after PC3.
Score plot

PC1 vs PC2: score plot of six oils

  • PC1 (46.3%): driven mainly by 1655/1265 cm⁻¹ (unsaturation-related) — coconut oil (the most saturated) sits at the most negative end
  • PC2 (28.3%): it looks as if extra virgin olive oil separates, but a sum-of-squares check shows that 74% of the PC2 variance comes from one single point, peanut oil replicate 3; its loading peak near 1159 cm⁻¹ is an artifact left by a measurement anomaly, not a clean chemical signal
  • QC: the replicates of five oils cluster tightly; one peanut oil replicate sits far at the top — suspect the measurement first (air bubble? alignment?), and don't rush to say “peanut oil forms its own group”
  • Back to the opening question: whether PCA can catch a mislabeled oil depends first on making sure the PC you are looking at is not hijacked by a single outlier — on the next page we remove this point and redo the analysis

The data come from the same simulated Raman spectra used in Colab NB10 (nb10_demo_spectra.csv); the PCA was computed live when this page was built, so the numbers are guaranteed to match NB10. Point color = oil; three points of the same color = three replicates.

Hands-on: redo it

Redo the PCA after removing PEA-3

  • With peanut oil replicate 3 removed: PC1 = 63.5%, PC2 = 33.2% (higher than the 28.3% before removal — an increase, not a decrease), PC3 is down to just 0.74% — the 74% of PC2 sum of squares that PEA-3 alone had propped up is gone, and the remaining variance re-concentrates into one clean direction
  • Now the highest PC2 loading is near 1525 cm⁻¹ = the carotenoid band: extra virgin olive oil (EVOO) has a mean PC2 score of 0.99, while all the other oils lie between −0.39 and 0.03 — this is the “clean” carotenoid separation
  • Lesson: a single outlier can hijack an entire PC. When you find an outlier sample, first go back to the raw spectrum and record the reason (see W08 ↗), then redo the PCA to check whether the story changes
  • NB10 preview: this point’s Hotelling T² = 12.7, above the 95% limit of 7.7 — the formal definitions of T² / Q residual (SPE) are left for W14 ↗

Same data, with that one spectrum removed and PCA rerun live (Colab NB10 sections 3 and 7 have the full version).

Data · Loadings

PC1 loading: which wavenumbers drive this principal component

The PC1 loading has positive peaks near 1655 cm⁻¹ (C=C stretching) and near 1265 cm⁻¹ (=C–H bending) — both are Raman bands related to unsaturation, which also explains why coconut oil (highly saturated) is farthest away on PC1. Treat band assignments as approximate; real samples still need to be confirmed against standards or literature spectra.
What the signs mean: for a band with a positive loading, samples with higher intensity there also have higher scores on this PC; for a negative loading, a stronger signal gives a lower score. What if two groups overlap: look at PC3, or try a different preprocessing (such as the second derivative).
Orange OR12 step by step

How to click from spectra to score plot and loadings

See also tools.html: Orange workflow OR12 ↗

Orange workflow

From spectra to score plot and loadings

The Colab / R code below is an advanced option — you can finish today's analysis with the Orange steps on the previous page, no coding needed.

Orange workflow (OR12) File Import spectra; oil = target PCA mean-centering built in; leave Normalize unchecked Data output raw data + PC scores + class Components output = loadings Scatter Plot Color by oil class = score plot Data Table Select suspicious points, check raw values Spectra (Loadings) loading vs wavenumber (wavelength) Key pitfalls: ① Connect Scatter Plot to “Data”, not “Transformed Data” ② Remember to uncheck “Normalize variables” in PCA

Advanced: Colab (scikit-learn, 5 lines):

from sklearn.decomposition import PCA import numpy as np X = np.loadtxt("oils_X.csv", delimiter=",") # one spectrum (one sample) per row pca = PCA(n_components=5).fit(X - X.mean(axis=0)) scores = pca.transform(X - X.mean(axis=0)) # scores[:, :2] -> score plot

Advanced: R (prcomp):

X <- as.matrix(read.csv("oils_X.csv", header=FALSE)) pca <- prcomp(X, center=TRUE, scale.=FALSE) scores <- pca$x[, 1:2] loadings <- pca$rotation[, 1] summary(pca)$importance[2, ] # proportion of variance explained by each PC

Colab NB10: Open NB10 in Colab ↗. Backup dataset: Five-sugar NIR backup dataset (chemometrics-teaching) →

Samples, instruments and safety

Six edible oils × Raman 785 + each group's NIR

  • Six oils: extra virgin olive oil, refined olive oil, soybean oil, canola oil, coconut oil, peanut oil — every group measures all of them, each with 3 replicates (re-loaded / re-sampled)
  • Raman 785 nm (rotating station): extra virgin olive oil gives strong fluorescence interference at 532 nm — remember the lesson from W10; today we use 785 nm throughout
  • Each group's NIR: depending on your group, use one of Avantes (300–1100 / 900–1650 nm; 600–1100 nm awaiting delivery), InnoSpectra NIR-S-G1 / T1 / T11 / R14, NeoSpectra Scanner / Micro Dev Kit / fiber-optic module, or Spectral Engines NIRONE S2.0 / S2.2 / S2.5
  • Coconut oil: it solidifies at room temperature (below about 24°C), so warm it gently until melted into a liquid before measuring
🔴
Raman laser (532/785 nm)
Never look directly at the light source or aim the beam at anyone's eyes; wear appropriate eye protection as instructed for the instrument
🔥🛢️
Hot oil and slippery floors
Warm coconut oil only gently, just until liquid — do not overheat; wipe up any oil spill right away to avoid slipping
4-hour lab schedule

Measure spectra → preprocessing → PCA → cross-instrument comparison

TimeContents
0:00–0:45Lecture: data table, scores/loadings, mean-centering / autoscaling, explained variance, how a single outlier hijacks a PC
0:45–2:05Six oils × 3 replicates: Raman 785 rotating-station measurement + each group's NIR measurement (melt coconut oil first)
2:05–2:30Preprocess in SpectraView (SNV / derivatives optional) and export an X matrix with one sample per row
2:30–3:30Run PCA in Orange: score plot (colored by oil), loadings (vs wavenumber), explained variance; if you find an outlier, first check the raw spectrum and the measurement log, confirm the anomaly and record the reason, then remove or re-measure it and redo the PCA
3:30–4:00Groups swap data and compare whether the score plots from different instruments (NIR) agree
Mini-game ②Order the PCA workflow— / 6
Use ▲▼ to put the 6 steps from spectra to PCA results in the correct order.
Mini-game ③PCA concepts: live quiz0 / 5
Mini-game ④Does this preprocessing decision affect the PCA result?0 / 6
Sort the 6 decisions into “affects the PCA result” or “does not affect the PCA result”.
Mini-game ⑤Decision challenge: reading the score plot0 / 5
Mini-game ⑥Calculation challenge: PC1+PC2 explained variance (%)Unanswered
The eigenvalues of 5 principal components are 8.2, 3.1, 0.9, 0.5, 0.3. What percentage of the total variance do PC1 and PC2 explain together? Formula: (λ₁+λ₂)/Σλᵢ×100%.
%
Homework

Colab NB10

📊
Score plot + interpretation
Attach your group's PC1 vs PC2 score plot; explain which oils separate, which overlap, and whether there are outliers
🧬
Loading plot + chemical assignment
Attach the loading plot, point out 1–2 bands and try to assign a functional group (remember to write “approximately”)
🚩
Outlier exercise
Following today's PEA-3: find one outlier sample (or deliberately flag one), remove it and redo the PCA, then compare how the explained variance and loadings change
📡
Cross-instrument comparison
Swap score plots with another group, compare whether results from different NIR instruments agree, and discuss possible reasons

Colab NB10: Open NB10 in Colab ↗ · Beginner (no coding): Orange workflow OR12 ↗. Backup dataset: Five-sugar NIR backup dataset (chemometrics-teaching) →

Self-check

By the end of today you should be able to…

Tap to tick — make sure you really can do it.

中文