📚 总体步骤概览
| 步骤 | 内容 | 说明 |
|---|---|---|
| 1 | 数据预处理 | 光谱平滑、去噪、一阶/二阶导数、标准正态变量变换(SNV)、MSC等 |
| 2 | 特征选择 | 主成分分析(PCA)、变量重要性分析、选取波段 |
| 3 | 建立分类模型 | LDA/SVM/Random Forest/PCA-LDA等 |
| 4 | 建立回归模型 | PLSR(偏最小二乘回归)或SVR |
| 5 | 模型评估 | 交叉验证、独立测试集评估、混淆矩阵、回归指标 |
| 6 | 结果解释和绘图 | 可视化建模结果,分析模型性能 |
NIR_Project/
│
├── data/ % 存放原始数据(如 .mat, .spa等)
│ ├── spectra/
│ └── labels/
│
├── functions/ % 存放功能函数
│ ├── read_data.m
│ ├── preprocess_data.m
│ ├── pca_reduction.m
│ ├── svm_classify.m
│ ├── pls_regression.m
│
├── results/ % 保存结果(图表、模型文件等)
│
├── scripts/ % 存放脚本
│ ├── main_analysis.m
│
└── README.md % 工程说明(可选)
详细步骤
📍1. 数据准备与读取

✅ 用自己写的read_spa函数读取光谱,整理成矩阵 X(样本数 × 波数点数),并提取标签 Y。
-
X: 135 × 采样点数(比如1200) -
Y1: 样品类型标签(H1-3983,糖料,异戊酸异戊酯) -
Y2: 合格样本的生产批次标签 -
Y3: 稀释样本的稀释浓度标签(85%、88%等) -
Y4: 掺假样本的掺假比例标签(85%、88%等)
➔ 示例代码(读取+初步整理)
matlab
复制编辑
clc; clear all; close all; %% 读取数据 dataFolder = '你的数据文件夹路径'; fileList = dir(fullfile(dataFolder, '*.spa')); numSamples = length(fileList); X = []; sampleTypeLabels = {}; batchLabels = {}; concentrationLabels = {}; adulterationLabels = {}; for i = 1:numSamples filePath = fullfile(fileList(i).folder, fileList(i).name); [wavenumber, absorbance] = read_spa(filePath); % 你要准备 read_spa 函数! X = [X; absorbance']; % 每行是一个样本 filename = fileList(i).name; % 分析文件名提取标签 parts = split(filename, '_'); sampleType = parts{1}; % H1-3983、糖料、异戊酸异戊酯 status = parts{2}; % 合格、稀释、掺假 batchOrConc = split(parts{3}, '.'); % 去掉后缀 sampleTypeLabels{i,1} = sampleType; if strcmp(status, '合格') batchLabels{i,1} = batchOrConc{1}; % 生产日期 elseif strcmp(status, '稀释') concentrationLabels{i,1} = batchOrConc{1}; % 稀释浓度 elseif strcmp(status, '掺假') adulterationLabels{i,1} = batchOrConc{1}; % 掺假比例 end end
📍2. 数据预处理(非常重要)
光谱预处理技术可以去除光谱中的背景干扰、散射影响、基线漂移等。
常用预处理方法包括:
-
平滑(如Savitzky-Golay)
-
一阶导数、二阶导数
-
标准正态变量变换(SNV)
-
多元散射校正(MSC)
➡️ 一般组合使用,比如 SG平滑 + 一阶导数 + SNV
➔ 示例代码(预处理)
matlab
复制编辑
% 参数设定 sgolayWindow = 15; % 例如15个点 sgolayOrder = 2; % 二阶多项式 % SG平滑 X_smooth = sgolayfilt(X', sgolayOrder, sgolayWindow)'; % 一阶导数 X_deriv1 = diff(X_smooth,1,2); % 对列做差 wavenumber = wavenumber(1:end-1); % 补偿波数长度 % SNV标准化 X_snv = (X_deriv1 - mean(X_deriv1,2)) ./ std(X_deriv1,0,2); % 现在 X_snv 就是预处理后的数据,可以用于建模!
📍3. 特征选择(PCA降维 or 选波段)
原始数据维度很高,要降维处理:
-
PCA(主成分分析):保留90%以上累计方差的主成分。
-
或者基于经验选取重要波段区间,比如 5000--7000 cm⁻¹区间。
➔ 示例代码(PCA)
matlab
复制编辑
[coeff, score, latent, tsquared, explained] = pca(X_snv); cumExplained = cumsum(explained); numPCs = find(cumExplained > 90, 1); X_pca = score(:,1:numPCs); % 取前numPCs个主成分
📍4. 模型建立
任务1:区分三种物质 ➔ 分类
-
模型选择:SVM、Random Forest、PCA+LDA等
-
分类标签:样品种类(H1-3983、糖料、异戊酸异戊酯)
➔ 示例SVM分类
matlab
复制编辑
SVMModel = fitcecoc(X_pca, sampleTypeLabels); % 交叉验证 CVSVMModel = crossval(SVMModel, 'KFold', 5); loss = kfoldLoss(CVSVMModel); disp(['五折交叉验证错误率: ', num2str(loss)]);
任务2:合格样品生产批次分类 ➔ 多分类
-
输入合格样本的
X_pca -
标签为不同日期(20240111、20241012等)
➡️ 用 SVM、Random Forest、或 KNN都可以。
任务3、4:稀释浓度 / 掺假浓度 ➔ 回归
-
用 PLSR(偏最小二乘回归)建模
-
输入稀释/掺假样本的
X_pca -
目标输出是浓度值(例如85、88等)
➔ 示例PLS回归建模
matlab
复制编辑
% 训练PLSR模型 [XL,yl,XS,YS,beta,PCTVAR] = plsregress(X_pca, concentrationValues, 10); % 预测 yfit = [ones(size(X_pca,1),1) X_pca] * beta; % 绘制回归图 figure; plot(concentrationValues, yfit, 'o'); xlabel('真实浓度'); ylabel('预测浓度'); title('稀释浓度回归预测'); grid on;
📍5. 模型验证
分类模型验证指标:
-
混淆矩阵(confusion matrix)
-
准确率(accuracy)
-
精确率(precision)、召回率(recall)、F1-score
回归模型验证指标:
-
RMSE(均方根误差)
-
R²(决定系数)
📍6. 可视化
分类可视化:
-
PCA散点图
-
分类决策边界
回归可视化:
-
真实值 vs 预测值的拟合直线
-
残差分析
✨ 总结一版工作流程表
| 阶段 | 内容 |
|---|---|
| 1 | 光谱读取整理(X矩阵+各类标签提取) |
| 2 | 光谱预处理(平滑、导数、标准化) |
| 3 | PCA特征降维 |
| 4 | 根据任务类型选择合适模型(分类or回归) |
| 5 | 模型训练+交叉验证 |
| 6 | 绘图和结果分析 |
