4、参数辨识数学基础:最小二乘法(LS)原理、递推最小二乘(RLS)、带遗忘因子的递推最小二乘(FFRLS)
做电池模型参数辨识,说白了就是给电池的等效电路模型「找参数」。R0、R1、C1 这些值到底是多少?你不能拍脑袋猜,得用数据说话。而最小二乘法,就是最经典、最基础的那把尺子。
我个人习惯把最小二乘法比作「找一条最贴近所有数据点的线」。你有一堆测量数据,想用一个模型去拟合它,让误差的平方和最小。嗯,这就是最小二乘的核心思想。
核心思想: 让模型输出与真实测量值之间的误差平方和最小。
4.1 最小二乘法(LS)原理
先看一个最简单的场景。假设我们有一个线性模型:
y = θ₁ * x₁ + θ₂ * x₂ + ... + θₙ * xₙ
其中 θ 是我们要辨识的参数,x 是输入,y 是输出。写成矩阵形式:
Y = X * Θ
那么最小二乘的解就是:
Θ = (XᵀX)⁻¹ Xᵀ Y
这个公式看起来简单,但我在项目中遇到过一个问题——当数据量特别大时,直接求逆矩阵非常慢,而且容易数值不稳定。你想想看,如果一次采集了 10 万组数据,X 矩阵就是 10 万行,求逆的复杂度是 O(n³),计算机会直接卡死。
我的经验: 离线辨识用 LS 没问题,但数据量超过 1 万组时,建议用后面讲的递推方法。
4.2 递推最小二乘(RLS)
为什么需要递推?因为电池是时变的。温度一变、SOC 一变,参数就变了。你总不能每次都把历史数据全部重算一遍吧?
RLS 的思路很简单:每次来一个新数据,就在旧参数的基础上「微调」一下。公式如下:
K(k) = P(k-1) * φ(k) / [1 + φᵀ(k) * P(k-1) * φ(k)]
θ(k) = θ(k-1) + K(k) * [y(k) - φᵀ(k) * θ(k-1)]
P(k) = [I - K(k) * φᵀ(k)] * P(k-1)
其中:
- K(k) 是增益矩阵,决定新数据对参数更新的影响程度
- P(k) 是协方差矩阵,代表参数估计的不确定性
- φ(k) 是当前时刻的输入向量
我曾经在调试 RLS 时踩过一个坑:初始值 P(0) 设得太小,导致算法几乎不更新参数。后来我习惯把 P(0) 设成 1000 * I,让算法一开始有足够的「学习空间」。
注意: RLS 对所有历史数据一视同仁。如果电池参数缓慢变化,旧数据会「拖后腿」,导致跟踪速度变慢。
4.3 带遗忘因子的递推最小二乘(FFRLS)
RLS 的问题在于「记性太好」。电池参数明明已经变了,它还在参考 100 步之前的数据。怎么办?加一个遗忘因子 λ。
FFRLS 的公式只比 RLS 多了一个 λ:
K(k) = P(k-1) * φ(k) / [λ + φᵀ(k) * P(k-1) * φ(k)]
θ(k) = θ(k-1) + K(k) * [y(k) - φᵀ(k) * θ(k-1)]
P(k) = [I - K(k) * φᵀ(k)] * P(k-1) / λ
λ 的取值范围是 0 到 1。λ 越小,遗忘越快;λ 越大,记忆越长。我个人习惯:
- 电池参数变化快(如大倍率充放电):λ = 0.95 ~ 0.97
- 电池参数变化慢(如静置或小电流):λ = 0.98 ~ 0.995
说白了,λ 就是控制算法「记忆力」的旋钮。你拧得越小,它越健忘,但跟踪越快;拧得越大,它越念旧,但估计越稳。
避坑指南: 我曾经把 λ 设成 0.9,结果参数估计值剧烈抖动,因为遗忘太快,算法被噪声带偏了。后来我改成 0.98,效果好了很多。
4.4 三种方法对比
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| LS | 离线辨识、数据量小 | 简单、全局最优 | 计算量大、不能在线更新 |
| RLS | 在线辨识、参数缓慢变化 | 递推计算、适合实时 | 对旧数据无遗忘 |
| FFRLS | 在线辨识、参数时变 | 跟踪能力强、灵活 | λ 需要调参 |
4.5 知识体系框架图
下面这张图帮你理清三种方法的关系和演进路径:
4.6 代码示例:FFRLS 核心实现
下面是我在实际项目中用过的 FFRLS 代码片段,去掉了业务逻辑,只保留核心:
function [theta, P] = ffirls_update(theta_old, P_old, phi, y, lambda)
% theta_old: 上一时刻参数向量
% P_old: 上一时刻协方差矩阵
% phi: 当前输入向量
% y: 当前测量值
% lambda: 遗忘因子 (0.95 ~ 0.995)
% 1. 计算增益
K = P_old * phi / (lambda + phi' * P_old * phi);
% 2. 更新参数
error = y - phi' * theta_old;
theta = theta_old + K * error;
% 3. 更新协方差矩阵
P = (eye(length(theta)) - K * phi') * P_old / lambda;
end
小技巧: 实际调试时,我会把 error 值打印出来。如果 error 一直很大,说明模型结构有问题,或者 λ 设得太小了。
嗯,到这里三种方法就讲完了。从 LS 到 RLS 再到 FFRLS,其实就是一个从「离线」到「在线」、从「无遗忘」到「有遗忘」的演进过程。你想想看,电池参数辨识的本质,就是跟时间赛跑——既要算得快,又要跟得准。
我个人建议:刚开始做项目时,先用 LS 跑一遍离线数据,看看参数的大致范围。然后再上 FFRLS 做在线辨识,把 λ 从 0.98 开始调。这样既稳又准,不容易翻车。