电池SOH估计和RUL预测,五个时间特征 + 基于GPR高斯过程回归的锂电池健康状态估计和剩余寿命预测

电池还剩多少寿命?五个时间特征 + 高斯过程回归的 SOH 与 RUL 预测

用 NASA 的 B0005 电池数据,把充放电曲线里"耗掉的时间"变成五个特征,再交给 GPR。测试集 R² 0.995,预测起点后第 7 个循环跌破 70% 失效线。

先看结果。

NASA 的 B0005 电池,清洗后剩 166 个有效循环。前 116 个做训练,后 50 个做测试。GPR 在测试集上的 R² 是 0.99545,RMSE 是 0.00131。

SOH 用 0 到 1 的小数表示,这个 RMSE 换算成百分比是 0.13 个百分点。

按 70% 的失效阈值算,预测起点之后第 7 个循环跌破阈值。翻回真实值,第 7 个点也确实跌破了。

模型不新,数据也是公开的。有意思的地方在于输入:不是容量,也不是整条充放电曲线,而是五个"时间段"。

这些时间段,BMS 和充电桩本来就在记。

01 研究背景:容量测不到,时间一直在记

SOH 衡量电池还剩多少健康度,工程上通常定义为实际可用容量与额定容量的比值。RUL 是剩下还能用多久。

麻烦在于容量。要测准容量,得把电池充满再放空,或者做一次完整的放电积分。车在跑、储能在并网,没人会为了估健康度专门做一次满充满放。

在线 BMS 手里真正有的,是电压、电流、温度、时间这些过程量。

电池老了,这些过程量的形状会变。恒流充电段变短,恒压充电段变长,放电时电压掉得更快。

把"某段电压区间花了多久"抽出来,就得到一组可在线测量的健康特征。

这也是这套代码的起点。

02 主要功能:四个脚本,一条流水线

脚本 作用 主要产物
main01_Split_data.m 读原始 B0005.mat,剔除 6 个重复或异常循环段,把 charge 与 discharge 拆开,用放电积分算 SOH 和 SOC B0005_charge_data.mat、B0005_discharge_data.mat
main02_SOH.m 批量读取 B0005、B0006、B0007、B0018,画四块电池的 SOH 衰减对比 四电池趋势图
main03_Feature.m 画电压、电流、IC 曲线,提取五个时间特征,算 Pearson 相关系数,存特征矩阵 B5_HF.mat,图 1 到图 8
main04_GPR.m 归一化、按时间切分训练测试、训练 GPR、算七项指标、定位 RUL、画雷达图和罗盘图 指标表,图 9 到图 11

主数据是 NASA PCoE 的 18650 电池。额定容量 2 Ah,充电先 1.5 A 恒流到 4.2 V,再恒压到电流降到 20 mA,放电是 2 A 恒流到 2.7 V。

四块电池里,B0005 被拿来做完整的特征提取和建模,另外三块只用来看衰减趋势的差异。

03 技术路线:从原始 .mat 到一条寿命曲线

整条链路可以压成一行:

原始循环数据 → 拆充放电段 → 容量积分得 SOH → 提五个时间特征 → 归一化 → GPR 训练与预测 → 指标与 RUL

具体到每一步:

阶段 输入 关键操作 输出
数据清洗 B0005.mat 的 cycle 结构体 去掉 6 个异常段,只保留采样点大于 100 的充电段 166 个充电循环、166 个放电循环
标签构造 放电段电压、电流、时间 找到首次低于 2.7 V 的位置,对电流积分 每个循环的 SOH
特征构造 充电段、放电段的时间序列 按电压、电流阈值截取区间,算时间差 5 维特征矩阵
数据划分 166 行特征矩阵 前 70% 训练,后 30% 测试,不打乱 116 行训练、50 行测试
回归建模 归一化后的 5 维输入 ARD 平方指数核,L-BFGS 优化超参 SOH 预测值与方差
寿命判定 测试段预测序列 找第一个低于 0.7 的点 RUL

训练集和测试集按时间顺序切,不随机打乱。电池老化是时间序列,随机打乱会让相邻循环同时出现在训练和测试里,指标会虚高。

这一点比模型本身更重要。

04 公式与特征

4.1 SOH 怎么算

放电过程可以看成容量在往外倒。对电流积分,再除以额定容量:

SOH=QdisQnom×100%,Qdis=13600∫0tcut∣I(t)∣dt SOH=\frac{Q_{\text{dis}}}{Q_{\text{nom}}}\times 100\%,\qquad Q_{\text{dis}}=\frac{1}{3600}\int_{0}^{t_{\text{cut}}}\left|I(t)\right|\mathrm{d}t SOH=QnomQdis×100%,Qdis=36001∫0tcut∣I(t)∣dt

tcutt_{\text{cut}}tcut 是电压首次低于 2.7 V 的时刻,Qnom=2Q_{\text{nom}}=2Qnom=2 Ah。

B0005 的首循环 SOH 是 0.9232,最低到 0.6437,最后几个循环又回升到 0.6625。这里的 100% 指 2 Ah 额定容量,不是首循环容量,所以曲线从 0.92 起步,不是从 1 起步。

曲线不单调,末端还有容量回升。GPR 能跟上这种局部波动,靠的是同一循环内的五个特征在同步变化。

这个细节会影响阈值。0.7 的失效线对应 1.4 Ah,而不是"首循环容量的 70%"。

4.2 IC 曲线:用来看,不用来喂模型

代码里还画了增量容量曲线。先对电流积分得到电量,再对电压求差分:

Q(t)=13600∫0tI(τ) dτ,dQdV≈Qk+1−QkVk+1−Vk Q(t)=\frac{1}{3600}\int_0^t I(\tau)\,\mathrm{d}\tau,\qquad \frac{\mathrm{d}Q}{\mathrm{d}V}\approx\frac{Q_{k+1}-Q_k}{V_{k+1}-V_k} Q(t)=36001∫0tI(τ)dτ,dVdQ≈Vk+1−VkQk+1−Qk

电压按 0.01 V 重采样,差分步长取 1 个点。原始差分噪声大,后面接了一维卡尔曼滤波:

x^k−=x^k−1,Pk−=Pk−1+q,Kk=Pk−Pk−+r \hat{x}k^-=\hat{x}{k-1},\quad P_k^-=P_{k-1}+q,\quad K_k=\frac{P_k^-}{P_k^-+r} x^k−=x^k−1,Pk−=Pk−1+q,Kk=Pk−+rPk−

x^k=x^k−+Kk(zk−x^k−),Pk=(1−Kk)Pk− \hat{x}_k=\hat{x}_k^-+K_k\left(z_k-\hat{x}_k^-\right),\quad P_k=(1-K_k)P_k^- x^k=x^k−+Kk(zk−x^k−),Pk=(1−Kk)Pk−

过程噪声 q=0.01q=0.01q=0.01,测量噪声 r=0.05r=0.05r=0.05,初始协方差 P0=0.001P_0=0.001P0=0.001。

IC 曲线能看出峰位的移动和峰高的衰减,这是老化在电化学层面的表现。但它只用于观察和佐证,真正的模型输入还是五个时间特征。

4.3 五个时间特征

特征 代码里的定义 物理含义
CCCT 充电开始到电压首次超过 4.2 V 的时间 恒流充电段长度
CCDT 放电段中,电流低于 -1.9 A 的持续时间 恒流放电窗口长度
CVCT 电压超过 4.2 V 到充电结束的时间 恒压充电段长度
CVRT 充电时电压从 3.8 V 升到 4.1 V 的时间 充电中段电压上升速度
CVDT 放电时电压从 4.0 V 降到 3.6 V 的时间 放电中段电压下降速度

五个特征随循环的变化趋势很一致。CCCT 从 3242 s 降到 1582 s,CVRT 从 2354 s 降到 1018 s。CVCT 反向,从 7274 s 升到 8630 s,中间最高到过 9240 s。

原因不复杂。活性物质少了,恒流段更快到达截止电压;内阻大了,恒压段要花更长时间才能把电充满。

4.4 相关性:谁最像 SOH

用 Pearson 系数衡量线性相关:

r=∑i=1n(xi−xˉ)(yi−yˉ)∑i=1n(xi−xˉ)2∑i=1n(yi−yˉ)2 r=\frac{\sum_{i=1}^{n}(x_i-\bar{x})(y_i-\bar{y})} {\sqrt{\sum_{i=1}^{n}(x_i-\bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} r=∑i=1n(xi−xˉ)2 ∑i=1n(yi−yˉ)2 ∑i=1n(xi−xˉ)(yi−yˉ)

B0005 上的结果:

特征 与 SOH 的 Pearson 系数
CCCT 0.99798
CCDT 0.99999
CVCT -0.91354
CVRT 0.99712
CVDT 0.99889

CVCT 的符号是负的,因为它随老化变长,而 SOH 随老化变短。其余四个都跟 SOH 同向。

CCDT 的 0.99999 需要单独说一句。恒流放电时,时间乘上 2 A 再除 3600,基本就是放电容量。它和 SOH 的高相关有算术上的必然性,不算模型的功劳。

真正有信息量的是充电侧那三个特征。它们和容量不是同一个量,却依然能跟踪老化。

4.5 共线性

五个特征彼此也高度相关。

对 GPR 来说,共线性不会让它失效,核矩阵里有噪声项兜底,通常仍可求逆。但 ARD 给每个维度单独的长度尺度,特征高度相关时,这些长度尺度会变得难以解释。

别把 ARD 的长度尺度直接当成特征重要性。它更像是一组让边际似然最大化的数值,不是因果解释。

05 GPR 原理与算法步骤

高斯过程回归做的事,是把函数本身当成随机变量:

f(x)∼GP(m(x),k(x,x′)) f(\mathbf{x})\sim\mathcal{GP}\left(m(\mathbf{x}),k(\mathbf{x},\mathbf{x}')\right) f(x)∼GP(m(x),k(x,x′))

代码用的是 ARD 平方指数核:

k(x,x′)=σf2exp⁡(−12∑d=15(xd−xd′)2ℓd2) k(\mathbf{x},\mathbf{x}')=\sigma_f^2 \exp\left(-\frac{1}{2}\sum_{d=1}^{5}\frac{(x_d-x_d')^2}{\ell_d^2}\right) k(x,x′)=σf2exp(−21d=1∑5ℓd2(xd−xd′)2)

五个输入维度各有自己的长度尺度 ℓd\ell_dℓd。观测带噪声:

y=f(x)+ε,ε∼N(0,σn2) y=f(\mathbf{x})+\varepsilon,\qquad \varepsilon\sim\mathcal{N}(0,\sigma_n^2) y=f(x)+ε,ε∼N(0,σn2)

给定训练集后,新样本的预测均值和方差是:

μ∗=k∗⊤(K+σn2I)−1y \mu_*=\mathbf{k}_*^{\top}\left(\mathbf{K}+\sigma_n^2\mathbf{I}\right)^{-1}\mathbf{y} μ∗=k∗⊤(K+σn2I)−1y

σ∗2=k(x∗,x∗)−k∗⊤(K+σn2I)−1k∗ \sigma_*^2=k(\mathbf{x}*,\mathbf{x}*)- \mathbf{k}*^{\top}\left(\mathbf{K}+\sigma_n^2\mathbf{I}\right)^{-1}\mathbf{k}* σ∗2=k(x∗,x∗)−k∗⊤(K+σn2I)−1k∗

超参数不靠交叉验证网格搜,而是最大化对数边际似然:

log⁡p(y∣X,θ)=−12y⊤(K+σn2I)−1y−12log⁡∣K+σn2I∣−n2log⁡2π \log p(\mathbf{y}\mid\mathbf{X},\theta)= -\frac{1}{2}\mathbf{y}^{\top}\left(\mathbf{K}+\sigma_n^2\mathbf{I}\right)^{-1}\mathbf{y} -\frac{1}{2}\log\left|\mathbf{K}+\sigma_n^2\mathbf{I}\right| -\frac{n}{2}\log 2\pi logp(y∣X,θ)=−21y⊤(K+σn2I)−1y−21log K+σn2I −2nlog2π

代码里的算法步骤是:

  1. 用训练集的 min 和 max 把输入和输出都压到 0,1,测试集复用同一组参数。
  2. 选 ardsquaredexponential 核,初始长度尺度 0.6,初始信号标准差 0.7,初始噪声标准差 30。
  3. 用 L-BFGS 最大化对数边际似然,同时估计核参数与噪声。
  4. 对训练集和测试集分别求后验均值,再反归一化回 SOH。
  5. 在测试段预测序列里找第一个低于 0.7 的位置,作为 RUL。

为什么用 GPR,而不是神经网络。训练样本只有 116 个,深度模型很难喂饱;GPR 在小样本上更稳,而且天然给出每个预测点的方差。

准确值告诉你"大概是多少",方差告诉你"这句话有多可信"。

06 参数设定

项目 取值 说明
数据 NASA PCoE B0005 18650,额定 2 Ah
有效样本 166 剔除异常段后的充放电循环数
训练/测试 116 / 50 按时间顺序 70% / 30% 切分
归一化 mapminmax 到 0,1 测试集复用训练集的 min、max
输入维度 5 CCCT、CCDT、CVCT、CVRT、CVDT
输出 SOH 范围 0.6437 到 0.9259
核函数 ardsquaredexponential 每维独立长度尺度
优化器 L-BFGS 最大化对数边际似然
核参数初值 σl=0.6\sigma_l=0.6σl=0.6(5 维),σf=0.7\sigma_f=0.7σf=0.7 调参后的优化起点
噪声初值 σn=30\sigma_n=30σn=30 只是起点,最终值由优化器估计
失效阈值 0.7 对应 1.4 Ah
IC 重采样 0.01 V 电压等间隔,便于差分
IC 差分步长 1 个点 兼顾平滑与峰形
卡尔曼参数 q=0.01q=0.01q=0.01,r=0.05r=0.05r=0.05,P0=0.001P_0=0.001P0=0.001 一维去噪
随机种子 rng(0) 固定随机性

有两点容易误读。

噪声初值 30 看起来大得离谱。归一化后的 SOH 残差尺度只有 0.1 左右,30 只是个宽松的起点。从训练集 RMSE 3.7×10⁻⁴ 看,优化器最后把噪声压得很低。

fitrgp 默认还会对输入做标准化,手写的 mapminmax 有部分重复。但统一到 0,1 后,核参数初值更好设,训练也更稳,多这一步不亏。

07 结果

指标 训练集 测试集
MAE 2.41×10⁻⁴ 1.16×10⁻³
MBE 3.11×10⁻¹³ 1.16×10⁻³
MSE 1.38×10⁻⁷ 1.73×10⁻⁶
RMSE 3.72×10⁻⁴ 1.31×10⁻³
R² 0.99997 0.99545
RPD 190.09 31.28
MAPE 2.76×10⁻⁴ 1.75×10⁻³

RMSE 0.00131 换成百分比是 0.131 个百分点。MAPE 0.175%。RPD 31.28,远高于工程上常用的 3 这个门槛。

测试集的 MBE 和 MAE 数值完全相等,都是 0.00116。说明测试段的残差全是同号,模型整体略微高估。训练集 MBE 接近 0,偏差只出现在测试段。

外推带来的小偏置,在这类时序切分里很常见。

RUL 的算法很直接:

RUL=min⁡{k≥1∣y^test(k)<0.7} RUL=\min\left\{k\ge 1 \mid \hat{y}_{\text{test}}(k)<0.7\right\} RUL=min{k≥1∣y^test(k)<0.7}

测试段从第 117 个循环开始,起点 SOH 是 0.7038。预测序列第 7 个点跌破 0.7,于是输出 7 个循环。

真实值也在第 7 个点跌破,数值 0.69835。这一次,预测与真实完全对齐。

08 这些数字该怎么读

指标很漂亮,但有几件事必须说清楚,否则容易把结论用错地方。

第一,这是单块电池、同一条老化轨迹上的切分。 训练和测试来自 B0005 的同一段衰减过程,模型更像在做"内插加短外推"。换一块电池、换一种充电策略,R² 大概率会掉。代码里另外三块电池只画了趋势,没有参与跨电池验证。

第二,五个特征和 SOH 绑得太紧。 CCDT 几乎是容量的另一种写法,CCCT、CVRT 也都是强代理。模型学到的更多是"这条曲线长什么样",而不是"老化机理是什么"。想验证特征本身的价值,得做消融,比如只留充电侧三个特征,看精度掉多少。

第三,RUL 等于 7 的说服力有限。 预测起点已经贴着 0.7,SOH 只有 0.7038,本来就没剩几个循环。而且测试窗口已经被观测,这是一次"阈值穿越定位",不是从早期循环往后递推的多步预测。真正难的场景,是在第 20 个循环就预测还剩多少寿命。

第四,时间特征依赖充电协议。 CVCT 尤其敏感,它取决于恒压截止电流。充电桩提前结束,或者换了快充策略,这个特征会失真。

第五,温度没进模型。 NASA 数据里有温度,但五个特征全是时间量。低温下充电变慢,时间特征会整体漂移。跨季节、跨地域部署时,这是一个明显的缺口。

第六,MAPE 是相对误差,SOH 基数在 0.7 附近时,百分比看起来会比绝对误差更小。 报告精度时,优先说"误差 0.13 个百分点",别只甩一个百分比。

09 运行环境

  • MATLAB R2021a 及以上。exportgraphics 需要 R2020a,tiledlayout 需要 R2019b,双引号字符串需要 R2017a。
  • Statistics and Machine Learning Toolbox,用于 fitrgp、plotregression、ploterrhist。
  • 雷达图依赖本地的 radarChart.m,不需要额外工具箱。
  • Windows、macOS、Linux 都可以跑。
  • 数据放在 data/,图片输出到 figures/,脚本按 main01 → main02 → main03 → main04 的顺序执行。
  • 计算量很小。166 个样本的精确 GPR,普通笔记本几秒到十几秒就能跑完,不需要 GPU。

10 应用场景

车端与云端 BMS。 充电时记录恒流段、恒压段的时间,配合历史数据估 SOH,不需要额外做满充满放。

二手车与质保。 SOH 曲线加上 GPR 的置信区间,比一个孤立的"健康度 92%"更能支撑残值评估。

储能电站。 成组电池的一致性分析,先看单体的时间特征有没有异常漂移,再决定是否检修。

换电与梯次利用。 分选时用它快速判断电池还能不能进下一梯队,避免只凭电压判断。

充电桩。 每次充电顺手完成一次健康体检,把结果回传给车主或运营方。

无人值守场景。 卫星、基站备电这类不方便人工检测的设备,时间特征可以在线取,GPR 的方差还能给出报警阈值。

结尾

这套流程真正值钱的地方,不是把 R² 刷到 0.995。

是 GPR 本来就有能力给每个预测点配一个方差。

这套代码目前只取了后验均值,方差还没画出来。工程上,这一块恰恰不能省。一个只会给点预测的模型,很难被信任;一个知道自己哪里不确定的模型,至少能在该报警的时候报警。

下一步可以做三件事。拿 B0006、B0007、B0018 做跨电池验证,看看换一块电池后精度掉多少;把温度加进特征,观察时间特征的漂移;把预测值递回模型,做真正的多步 RUL,而不是在测试段里找阈值穿越点。

再往前走一步,就是把 predict 的第二个输出取出来,把 95% 置信区间画到 SOH 曲线上。

SOH 估计解决的是"现在怎么样",RUL 解决的是"还能撑多久"。前者靠特征,后者靠外推。

外推这部分,才是真正难的地方。


数据来源:NASA Ames Prognostics Center of Excellence 电池数据集。本文的 MATLAB 实现与图表均来自本地复现,指标可在同一数据与同一随机种子下复现。

相关推荐
代码方舟1 小时前
零信任架构实战:基于天远企业二要素验证构建自动化小微快贷法人资质核验网关
运维·人工智能·架构·自动化
tellmewhoisi1 小时前
深度学习13:反向传播4:输出层Softmax-with-Loss
人工智能·深度学习
hahaha60161 小时前
Unsharp Masking算法综述
图像处理·人工智能·计算机视觉
武天旭1 小时前
AI安全--AI大模型的模型窃取攻击
人工智能·安全
注塑机数据采集联网1 小时前
中科晟达注塑机 MES 系统:从车间到数字化的智能制造实践
大数据·数据仓库·人工智能·物联网·制造·数据库架构
xierui1231231 小时前
视频Agent的声音编排:原声、TTS、ASR与背景音乐怎样分工
人工智能·音视频
lucas_AI1 小时前
花旗、安永、英伟达联手写的文档摄取系统报告:92% 的页面根本不需要 OCR
人工智能
七夜zippoe1 小时前
Spring AI + Ollama 本地模型:数据不出内网的合规方案(落地全流程)
java·人工智能·spring·ai·ollama