To the eye, all four are fine white powders that look identical. But measure one spectrum and the shape never lies.
Today’s task: use the pure-compound spectra the whole class measured in W10 to build a small spectral library, then identify the TA’s blind samples and commercial sugar substitutes — and finally compare whose matching scores are the most convincing.
Full narration and captions; simulated spectra, not measured fingerprints. Player and downloads · Interactive lab
Preprocessing tool: this lesson uses SpectraView (GitHub) ↗ (user guide ↗) for SG smoothing, baseline, SNV/MSC, derivatives, peak picking and .speclib library matching; as an easy start you can also use the Orange workflow OR11 ↗: File → Preprocess Spectra (ALS baseline subtraction → vector normalization) → Distances (Pearson) → Distance Matrix + Hierarchical Clustering, which only does qualitative identification (“which one is it most similar to”) — NNLS quantification of mixtures still needs Colab NB09.
Each wavelength/wavenumber is just one “column” and each intensity just one “cell” — the illustrative spectra in this lesson have 71 data points (one every 20 cm⁻¹), so one spectrum = 71 numbers in a row. Preprocessing (spike removal, baseline, SNV…) simply means “apply the same operation to every row”.
| Raman shift (cm⁻¹) | 400 | 420 | 440 | 460 | 480 |
|---|---|---|---|---|---|
| Intensity (a.u.) | 0.431 | 0.448 | 0.457 | 1.355 | 0.466 |
In Excel: one row = one spectrum, 71 columns = 71 wavenumbers; applying the same formula (e.g. SNV) across a whole row is “preprocessing”; 71 samples × 71 columns is the data table X used from W12 on.
First use a “median filter” to estimate what each point should look like nearby, then see how far each point deviates from that estimate. The deviation is measured with a “robust standard deviation”, MAD (median absolute deviation), converted into a “modified z-score”; a deviation of more than 6 robust SDs is judged a spike and replaced with the median-filter value.
| Position | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| Raw value | 0.30 | 0.31 | 0.29 | 2.10 | 0.32 | 0.30 | 0.29 |
| 7-pt median filter | 0.30 | 0.30 | 0.30 | 0.30 | 0.30 | 0.29 | 0.29 |
| Modified z-score | 0.0 | 0.7 | -0.7 | 121.4 | 1.3 | 0.7 | 0.0 |
| Corrected | 0.30 | 0.31 | 0.29 | 0.30 | 0.32 | 0.30 | 0.29 |
Point 4 is 2.10, z ≈ 121 (far above 6) → judged a cosmic-ray spike → replaced with the median-filter estimate 0.30. A window that is too wide may flag even real narrow peaks as spikes and delete them; too narrow may miss spikes — NB09/OR11 both use a 7-point window, z>6.
The defaults in NB09 / Orange OR11 are both λ=10⁶, p=0.01 — the common standard for this course. Orange path: Preprocess Spectra → ALS.
Formula: y′=(y−ȳ)/s, where ȳ = the mean of this spectrum itself and s = the standard deviation of this spectrum itself (population SD, dividing by n, not n−1).
| Pt 1 | Pt 2 | Pt 3 | Pt 4 | Pt 5 | |
|---|---|---|---|---|---|
| y | 0.2 | 0.4 | 0.9 | 0.5 | 0.3 |
| y′ (after SNV) | -1.08 | -0.25 | 1.82 | 0.17 | -0.66 |
ȳ=0.46, s=0.242 (population SD). Replace each y with “how many standard deviations from the mean” and you get y′. Try replacing y with 2y+0.1 (intensity doubled, then shifted) and run SNV again: the result is exactly the same — that is why SNV is insensitive to both shift and scaling.
Excel: =(B2-AVERAGE($B2:$F2))/STDEV.P($B2:$F2) (note: use STDEV.P, not STDEV.S). MSC is conceptually the same; the difference is that it regresses against a reference spectrum (usually the mean spectrum), y=a+b·y_ref, then corrects with (y−a)/b.
Intensity differences can also be handled by vector normalization (divide by vector length) or area normalization (divide by the area under the spectrum) — used in the next section.
1st derivative = the difference between neighboring points; 2nd derivative = the difference of differences.
| Spectrum y | 1st derivative (difference) | 2nd derivative (difference again) |
|---|---|---|
| [1, 2, 4, 7] | [1, 2, 3] | [1, 1] |
Add a constant to the whole spectrum (a uniform baseline shift, e.g. [6, 7, 9, 12]) and the 1st derivative is completely unchanged — differencing cancels the constant; a linear slope (the whole spectrum rising steadily in one direction) is also removed in the 2nd derivative. The cost: noise (random point-to-point jitter) changes quickly, and differencing amplifies it, so derivatives are often used together with smoothing (e.g. SG).
| Metric | Formula | Sensitive to intensity magnitude? |
|---|---|---|
| Pearson r | How strongly the “shapes” of two spectra correlate (covered in W04 ↗) | Not sensitive (unaffected by shift or scaling) |
| cosine | Treat spectra as vectors; cosθ=(x·y)/(‖x‖‖y‖) | Insensitive to scaling, but sensitive to shift |
| SAM (spectral angle) | SAM = arccos(cosine) × 180/π (converted to “degrees”) | Same as cosine — the smaller the angle, the more alike |
| Euclidean | ‖x−y‖, a direct numerical difference | Very sensitive — always normalize before matching |
Unknown U=[0.10,0.35,0.90,0.40,0.15], candidate C=[0.12,0.32,0.95,0.38,0.22] (shape slightly different from U, but the absolute values are very close to U).
| Metric | U vs C |
|---|---|
| cosine | 0.9968 |
| SAM | 4.59° |
| Pearson r | 0.9911 |
| Euclidean (raw, not normalized) | 0.095 |
| Euclidean (after vector normalization) | 0.080 |
Compare with the “truly correct” candidate: raw Euclidean d(U, truly correct)=0.510 is larger than the 0.095 of C above — raw distance wrongly judges C to be closer! After normalization, d(U, truly correct)=0.048 is smaller than C’s 0.080, so the judgment is correct. Pearson r, cosine and SAM are insensitive to intensity by design, so they never made this mistake. (Which candidate is truly correct? Work it out yourself in Calculation Challenge ⑥ later.)
| Candidate compound ⇅ | Pearson r ⇅ | cosine ⇅ | SAM (°) ⇅ | Rank ⇅ |
|---|
File loads the library + unknown samples → Preprocess Spectra: ALS baseline subtraction (λ=10⁶, p=0.01) → vector normalization — use exactly the same settings for the library and the unknownsDistances: choose Pearson; Orange converts the correlation coefficient to a distance = (1−r)/2 — the closer r is to 1 (more alike), the closer the distance is to 0Distance Matrix: find the row of the unknown sample; the library sample at the cell with the smallest number is the most similar answerHierarchical Clustering: a dendrogram of the same set of spectra — the shorter the branch joining two samples, the more similar they are| Time | Contents |
|---|---|
| 0:00–0:50 | Lecture: the three “can’t compare directly” problems, spike removal, ALS baseline, SNV/MSC/SG, four similarity metrics |
| 0:50–1:40 | SpectraView preprocessing practice: try different parameters (λ, p, SG window/order) on the same spectrum and record your reasons for each choice |
| 1:40–2:35 | Build the class spectral library from the W10 pure-compound spectra (or use Orange OR11) and match the TA’s blind samples |
| 2:35–3:30 | Measure commercial sugar substitutes (Raman 785 nm + each group’s NIR) and match against the library |
| 3:30–4:00 | Each group reports its top-3 results and similarity scores |
Colab NB09: Open NB09 in Colab ↗ · Easy start (no coding): Orange workflow OR11 ↗. The report must include: a library matching table (top-3), the overlay, a false-positive/ambiguous-match discussion, and your reasons for the preprocessing parameters.
Tap to tick.