基于 MATLAB 实现 近红外光谱(NIRS)血液定量分析

基于 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

五、参考文献

  1. PLS在NIRS中的应用:中采用SG平滑+一阶导数预处理,R²达0.994
  2. iPLS波长选择:通过间隔PLS优化光谱区间,RMSEP降低23%
  3. 血液检测案例:使用手持NIRS设备结合SIMCA实现血迹分类
相关推荐
cici158745 小时前
MATLAB中实现图像超分辨率
开发语言·matlab
爱装代码的小瓶子5 小时前
【c++进阶】在c++11之前的编译器的努力
开发语言·c++·vscode·visualstudio·编辑器·vim
蜗牛love天空5 小时前
智能指针的值传递和引用传递
开发语言·c++
☆cwlulu5 小时前
C语言关键字详解
开发语言
2301_797312265 小时前
学习Java26天
java·开发语言
cike_y5 小时前
JSP原理详解
java·开发语言·jsp
爱装代码的小瓶子6 小时前
【cpp进阶】c++11的新特性(概述版)
开发语言·c++
_OP_CHEN6 小时前
【从零开始的Qt开发指南】(十一)Qt常用控件之多元素控件与容器类控件深度解析
开发语言·qt·前端开发·多元素控件·gui开发·qt常用控件·容器类控件
Robot侠6 小时前
视觉语言导航从入门到精通(二)
开发语言·人工智能·python·llm·vln