SVM支持向量机+SHAP特征选择和贡献度计算,Matlab代码实现,作者:机器学习之心
效果一览
基本介绍
-
引言
在正向渗透(Forward Osmosis, FO)过程中,水通量的精准预测对于优化膜分离工艺和提升系统效率具有重要工程意义。然而,传统机理模型常受限于复杂的传质动力学方程,难以兼顾预测精度与可解释性。本研究提出一种融合SVM支持向量机与SHapley加性解释(SHAP)的混合建模框架,旨在构建高精度且可解释的回归模型,以解析操作参数对水通量的非线性影响机制。该模型以膜面积、进料/汲取液流速及浓度等关键操作参数为输入特征,通过五折交叉验证确保泛化能力,并借助SHAP方法量化特征贡献,为工艺优化提供透明化决策支持。 -
方法论
2.1 数据准备与预处理
实验数据采集自FO工艺数据库,包含六维参数(5输入特征,1输出目标)。输入特征涵盖膜面积(7–63 m²)、进料流速(7–25 L/h)、汲取液流速(5–15 L/h)、进料浓度(10,000–30,000 ppm)及汲取液浓度(70,000–150,000 ppm)。数据经归一化处理,映射至[−1,1]区间以消除量纲差异。
2.2 SVM支持向量机模型构建与训练
采用MATLAB R2023a实现SVM支持向量机。为抑制过拟合,采用五折交叉验证(5-Fold CV)策略,将数据集随机划分为5个子集,迭代训练中确保每折测试集独立。
2.3 SHAP可解释性分析
SHAP值基于合作博弈论中的Shapley值理论,量化特征对模型预测的边际贡献。
- 结论
本研究成功构建了基于SVM支持向量机与SHAP的可解释回归模型,实现了FO水通量的高精度预测与特征贡献解析。方法学创新体现于:
通过五折交叉验证与超参数优化平衡模型复杂度与泛化能力;
引入SHAP方法打破黑箱限制,提供全局及局部双重解释视角。
数据集
程序设计
- 完整程序和数据下载私信博主回复SVM支持向量机+SHAP特征选择和贡献度计算,Matlab代码实现。
% 清除工作区变量、命令行窗口,并关闭所有图形窗口
clear
clc
close all
% 从Excel文件读取数据,数据包含6列
data = xlsread('data.xlsx');
% 提取前5列作为输入特征(x)
x = data(:, 1:5);
% 提取第6列作为输出目标(y,真实水通量)
y = data(:, 6);
% ------------------ 数据归一化处理 ------------------
% 对输入数据x进行归一化(默认范围[-1,1]),x_settings保存归一化参数
[x_norm, x_settings] = mapminmax(x'); % 输入需要转置(mapminmax按行处理)
% 对输出数据y进行归一化,y_settings保存参数
[y_norm, y_settings] = mapminmax(y');
% 保存输入和输出的归一化参数到.mat文件,供后续使用
save('normalization_x.mat', 'x_settings');
save('normalization_y.mat', 'y_settings');
% 将归一化后的数据转置回原始维度(行表示样本,列表示特征)
x_norm_t = x_norm';
y_norm_t = y_norm';
% ------------------ 交叉验证设置 ------------------
numFolds = 5; % 定义5折交叉验证
cv = cvpartition(size(x_norm_t, 1), 'KFold', numFolds); % 创建交叉验证分区对象
% 初始化存储评估指标的数组
rmse_fold = zeros(numFolds, 1);
r_squared_fold = zeros(numFolds, 1);
% ------------------ 交叉验证训练与评估 ------------------
for fold = 1:numFolds
% 获取当前fold的训练和测试索引
trainIndices = training(cv, fold);
testIndices = test(cv, fold);
% 划分训练集和测试集
trainData = x_norm_t(trainIndices, :);
trainLabels = y_norm_t(trainIndices);
testData = x_norm_t(testIndices, :);
testLabels = y_norm_t(testIndices);
% ------------------ 模型预测与反归一化 ------------------
% ------------------ 评估指标计算 ------------------
% 计算RMSE
rmse = sqrt(mean((testLabels_inv - predictions_inv').^2));
% 计算相关系数R和R²
corr_matrix = corrcoef(predictions_inv, testLabels_inv);
corr_coefficient = corr_matrix(1, 2);
r_squared = corr_coefficient^2;
% 存储当前fold的评估结果
rmse_fold(fold) = rmse;
r_squared_fold(fold) = r_squared;
end
% ------------------ 可视化交叉验证结果 ------------------
figure;
% 绘制RMSE变化
subplot(2,1,1);
plot(1:numFolds, rmse_fold, '-o', 'LineWidth', 2);
xlabel('Fold Number');
ylabel('RMSE');
title('RMSE for Each Fold');
grid on;
% 绘制R²变化
subplot(2,1,2);
plot(1:numFolds, r_squared_fold, '-o', 'LineWidth', 2);
xlabel('Fold Number');
ylabel('R²');
title('R² for Each Fold');
grid on;
% 输出平均评估指标
disp(['Average RMSE: ', num2str(mean(rmse_fold))]);
disp(['Average R²: ', num2str(mean(r_squared_fold))]);
% ------------------ 训练集预测与评估 ------------------
predictions_train_inv = mapminmax('reverse', predictions_train, y_settings);
rmse_train = sqrt(mean((trainLabels_inv - predictions_train_inv').^2));
% 注意:此处代码可能存在错误,corr_matrix_train未正确使用
corr_matrix_train = corrcoef(predictions_train_inv, trainLabels_inv);
r_squared_train = corr_matrix_train(1,2)^2; % 修正后的R²计算
% ------------------ 合成数据生成 ------------------
numSamples = 100;
% 定义各特征范围
areaRange = [7, 63]; % 膜面积
QfRange = [7, 25]; % 进料流量
QdRange = [5, 15]; % 汲取液流量
CfRange = [10000, 30000]; % 进料浓度
CdRange = [70000, 150000]; % 汲取液浓度
% 生成均匀分布的随机数据
rng('default'); % 固定随机种子保证可重复性
syntheticData = [
rand(numSamples,1)*(areaRange(2)-areaRange(1)) + areaRange(1), ...
rand(numSamples,1)*(QfRange(2)-QfRange(1)) + QfRange(1), ...
rand(numSamples,1)*(QdRange(2)-QdRange(1)) + QdRange(1), ...
rand(numSamples,1)*(CfRange(2)-CfRange(1)) + CfRange(1), ...
rand(numSamples,1)*(CdRange(2)-CdRange(1)) + CdRange(1)
];
writematrix(syntheticData, 'synthetic_data.csv');
% ------------------ SHAP值计算 ------------------
% 读取合成数据并归一化
data_shap = readmatrix('synthetic_data.csv');
x_norm_shap = mapminmax('apply', data_shap', x_settings)'; % 直接应用已有归一化参数
% 初始化SHAP值矩阵
参考资料
[1] https://blog.csdn.net/kjm13182345320/article/details/128163536?spm=1001.2014.3001.5502
[2] https://blog.csdn.net/kjm13182345320/article/details/128151206?spm=1001.2014.3001.5502