目录
一、基于 SVR 的锂电池剩余使用寿命预测
填坑:开始完成麻雀搜索算法优化SVR的前置工作及比较
支持向量回归(Support Vector Regression,SVR)是一种基于支持向量机(SVM)的回归算法。与传统的线性回归不同,SVR 是一种非线性回归算法,它适用于具有非线性关系的数据集。SVR 的主要思想是将数据映射到高维空间中,使得在该空间内可以将数据划分为不同的类型,并找到最佳的分界线,以在预测过程中能够最大化预测误差的间隔。
SVR模型对待训练数据有一定的依赖性,然而其损失函数会忽视在模型预测的内部间隔阈值之内的训练数据,这可能导致关键信息的缺失。
当应用SVR模型处理非线性可分离数据时,在输入空间里众多的回归问题可能会受影响,导致无法实现线性回归。这就需要利用核函数,它将数据样本点投射到高维特征空间,在高维空间中呈现线性可分的特征,进而获得额外的有价值信息。由于锂电池在容量退化趋势内展现的是非线性特性,主要研究数据中的非线性回归特征。
提示:具体可参考我发布的参考文献
二、构建 SVR 预测模型
1.流程细则
其预测精度和泛化能力受到惩罚因子C和核参数σ的影响,这两个参数对SVR算法预测效果的精确程度具有直接作用。
网格搜索需要穷举所有可能的参数组合,计算量会很大,训练时间也会很长,但实现简单明了。故选择了较为常用的网格搜索作为确定惩罚因子C和核参数的方法。
本文建立的预测方法流程如图所示,包括了数据预处理、划分数据、参数优化、训练模型和预测结果输出等步骤。这一流程旨在提高预测模型的准确性和可靠性,为进一步应用锂电池寿命预测模型提供了可行的方法和流程。
2.前置准备
首先打开Matlab,选择代码所在的文件夹,其中libsvm-3.24是我下载的版本,其余版本也行。
其实B站有些SVR Tool包也不错,可惜与我的MATLAB版本有点冲突,附一个
手把手教你用MATLAB写支持向量机回归(SVR)模型,小小白专用_哔哩哔哩_bilibili
数据读取部分,我当时为了偷懒,将电池型号数据在excel进行分割(其实可以进行优化,现在代码对非本次电池特性数据不具有普适性,需要人为选择),如步骤所示,读取了B5电池的特性参数进行训练
SVR代码如下:
%% 初始化程序
close all;
clear;
clc;
format compact;
addpath('libsvm-3.24')
%% 数据读取
data=xlsread('B5特征数据.xlsx','Sheet1','A1:B168'); %%数据为B5/6/7的数据,共168个样本
%输入输出数据
input=data(:,1); %data的第一列为特征指标
output=data(:,end); %data的最后面一列为输出的指标值
N=length(output); %全部样本数目
testNum=68; %设定测试样本数目
trainNum=N-testNum; %计算训练样本数目
%% 划分训练集、测试集
input_train = input(1:trainNum,:);
output_train =output(1:trainNum);
input_test =input(trainNum+1:trainNum+testNum,:);
output_test =output(trainNum+1:trainNum+testNum);
%% 数据预处理
% 数据预处理,将训练集和测试集归一化到[0,1]区间
[mtrain,ntrain] = size(input_train);
[mtest,ntest] = size(input_test);
dataset = [input_train;input_test];
% mapminmax为MATLAB自带的归一化函数
[dataset_scale,ps] = mapminmax(dataset',0,1);
dataset_scale = dataset_scale';
input_train = dataset_scale(1:mtrain,:);
input_test = dataset_scale( (mtrain+1):(mtrain+mtest),: );
%% SVR模型创建/训练
% 寻找最佳c参数/g参数——交叉验证方法
% SVM模型有两个非常重要的参数C与gamma。
% 其中 C是惩罚系数,即对误差的宽容度。
% c越高,说明越不能容忍出现误差,容易过拟合。C越小,容易欠拟合。C过大或过小,泛化能力变差
% gamma是选择RBF函数作为kernel后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,
% gamma越大,支持向量越少,gamma值越小,支持向量越多。支持向量的个数影响训练与预测的速度。
% 定义参数范围
C_range = (1:100); % C 参数范围:1 到 10^2
gamma_range = 10.^(-2:1); % γ 参数范围:10^-4 到 10^2
% 网格搜索
mse_min = Inf; % 初始化最小的均方误差
for i = 1:length(C_range)
for j = 1:length(gamma_range)
% 使用当前的 C 和 gamma 构建 SVR 模型
svr = fitrsvm(input_train,output_train,'KernelFunction','rbf','BoxConstraint',C_range(i),'KernelScale',gamma_range(j));
% 预测测试集
Ypred = predict(svr,input_test);
% 计算均方误差
mse = mean((output_test-Ypred).^2);
% 更新最小的均方误差和对应的 C 和 gamma
if mse < mse_min
mse_min = mse;
C_best = C_range(i);
g_best = gamma_range(j);
end
end
end
%输出最优的 C 和 gamma
fprintf('最优的 C 为 %f,最优的 gamma 为 %f,对应的均方误差为 %f。\n',C_best,g_best,mse_min);
%% 利用最佳的参数进行SVR网络训练
c=10,g=1;
cmd = ['-t 2',' -c ',num2str(c),' -g ',num2str(g),' -s 3 -p 0.01'];
model = libsvmtrain(output_train,input_train,cmd);
%% SVR预测
[test_simu,accuracy] = libsvmpredict(output_test,input_test,model);
error=test_simu-output_test; %预测值和真实值的误差
a = find(test_simu);
%% 结果分析
%%真实值与预测值误差比较
figure
plot(output)
hold on
plot(a+100,test_simu)
hline1 = yline(1.4, '--r', 'LineWidth', 2);
hline2 = xline(100, '--b', 'LineWidth', 2);
legend('期望值','SVR预测值','失效阈值','预测起点')
xlabel('测试循环周期'),ylabel('当前容量')
title('SVR测试集预测值和期望值的对比')
set(gca,'fontsize',12)
figure
plot(error,'ro-','linewidth',1.2)
xlabel('测试循环周期'),ylabel('容量预测偏差')
title('SVR测试集的预测误差')
set(gca,'fontsize',12)
%计算误差
[len,~]=size(output_test);
SSE1=sum(error.^2);
MAE1=sum(abs(error))/len;
MSE1=error'*error/len;
RMSE1=MSE1^(1/2);
MAPE1=mean(abs(error./output_test));
r=corrcoef(output_test,test_simu); %corrcoef计算相关系数矩阵,包括自相关和互相关系数
R1=r(1,2);
disp(' ')
disp('/')
disp('预测误差分析...')
disp(['平均绝对误差MAE为: ',num2str(MAE1)])
disp(['均方误差MSE为: ',num2str(MSE1)])
disp(['均方根误差RMSE为: ',num2str(RMSE1)])
disp(['平均百分比误差MAPE为: ',num2str(MAPE1*100),'%'])
disp(['相关系数R为: ',num2str(R1)])
%打印结果
disp(' ')
disp('/')
disp('打印测试集预测结果...')
disp([' 编号 实际值 预测值 误差'])
for i=1:len
disp([i,output_test(i),test_simu(i),error(i)])
end
3.结果分析

三、结束
填坑好累~·~~~