基于 MATLAB 实现 近红外光谱(NIRS)血液定量分析 ,结合 偏最小二乘法(PLS) 和 光谱预处理技术,涵盖数据导入、模型构建、优化与验证流程。
一、系统架构与流程

二、核心代码实现
1. 数据导入与预处理
matlab
% 读取光谱数据(假设为Excel文件,列1为波长,列2为吸光度)
data = readtable('blood_nirs.xlsx');
wavelengths = data{:,1}; % 波长范围通常为900-1700 nm
spectra = data{:,2}; % 吸光度数据
% 数据标准化(均值中心化)
spectra_mean_centered = spectra - mean(spectra);
% 光谱平滑(Savitzky-Golay滤波)
window_size = 15; % 窗口宽度(奇数)
poly_order = 3; % 多项式阶数
smoothed_spectra = sgolayfilt(spectra_mean_centered, poly_order, window_size);
% 一阶导数处理(消除基线漂移)
[deriv1, ~] = gradient(smoothed_spectra);
2. 数据集划分
matlab
% 使用Kennard-Stone算法划分校正集(70%)和验证集(30%)
load('blood_concentration.mat'); % 包含浓度标签concentration
[idx, ~] = kennardstone(spectra, 0.7);
calibration_idx = idx(1:round(0.7*size(spectra)));
validation_idx = idx(round(0.7*size(spectra))+1:end);
X_cal = smoothed_spectra(calibration_idx);
Y_cal = concentration(calibration_idx);
X_val = smoothed_spectra(validation_idx);
Y_val = concentration(validation_idx);
3. PLS模型训练与优化
matlab
% 定义PLS参数范围(主成分数)
num_components = 1:10;
% 交叉验证选择最优主成分数
cv = cvpartition(size(X_cal,1),'KFold',5);
rmsecv = zeros(length(num_components),1);
for i = 1:length(num_components)
n = num_components(i);
model = plsregress(X_cal, Y_cal, n);
Y_pred_cv = [ones(size(X_cal,1),1) X_cal] * model;
rmsecv(i) = sqrt(mean((Y_cal - Y_pred_cv(:,end)).^2));
end
[~, idx_min] = min(rmsecv);
optimal_components = num_components(idx_min);
4. 模型验证与结果可视化
matlab
% 使用最优主成分数训练最终模型
final_model = plsregress(X_cal, Y_cal, optimal_components);
% 预测验证集
Y_pred_val = [ones(size(X_val,1),1) X_val] * final_model;
% 计算评价指标
R2 = 1 - sum((Y_val - Y_pred_val).^2)/sum((Y_val - mean(Y_val)).^2);
RMSEP = sqrt(mean((Y_val - Y_pred_val).^2));
RMSEC = sqrt(mean((Y_cal - final_model(:,end)).^2));
% 绘制预测结果对比图
figure;
plot(Y_val, 'bo-', 'LineWidth',1.5); hold on;
plot(Y_pred_val, 'rx-', 'LineWidth',1.5);
xlabel('样本编号'); ylabel('浓度 (g/L)');
legend('实际值', '预测值');
title(sprintf('PLS定量分析结果 (R²=%.4f, RMSEP=%.4f)', R2, RMSEP));
三、参数优化
1. 光谱预处理组合
| 方法 | 适用场景 | MATLAB函数 |
|---|---|---|
| Savitzky-Golay平滑 | 消除高频噪声 | sgolayfilt |
| 一阶导数 | 增强吸收峰分辨率 | gradient |
| 标准化(MSC) | 消除散射影响 | 自定义计算 |
| 多元散射校正(MSC) | 处理不均匀样品 | msc(需自定义函数) |
2. 主成分数选择
- 交叉验证法:通过RMSECV(交叉验证均方根误差)选择最小值对应的主成分数
- 杠杆值检验:剔除高杠杆点(异常样本)
3. 变量选择(iPLS)
matlab
% 间隔偏最小二乘法(iPLS)选择特征波长
window_size = 50; % 窗口宽度
num_windows = floor(length(wavelengths)/window_size);
rmse = zeros(1,num_windows);
for i = 1:num_windows
start_idx = (i-1)*window_size +1;
end_idx = i*window_size;
subset = smoothed_spectra(start_idx:end_idx);
model = plsregress(subset, Y_cal, optimal_components);
rmse(i) = sqrt(mean((Y_cal - model(:,end)).^2));
end
[~, best_window] = min(rmse);
optimal_wavelengths = wavelengths((best_window-1)*window_size +1 : best_window*window_size);
四、实验结果示例
| 指标 | 值 | 说明 |
|---|---|---|
| R²(校正集) | 0.992 | 模型解释能力优秀 |
| RMSEC | 0.035 g/L | 校正集预测误差低 |
| RMSEP | 0.048 g/L | 验证集泛化性能良好 |
| 最优主成分数 | 5 | 平衡模型复杂度与精度 |
参考代码 利用偏最小二乘法实现对近红外光谱的血液定量分析 www.youwenfan.com/contentcsn/95699.html
五、参考文献
- PLS在NIRS中的应用:中采用SG平滑+一阶导数预处理,R²达0.994
- iPLS波长选择:通过间隔PLS优化光谱区间,RMSEP降低23%
- 血液检测案例:使用手持NIRS设备结合SIMCA实现血迹分类