1. 递推最小二乘法概述
递推最小二乘法(Recursive Least Squares, RLS)是一种经典的自适应滤波算法,广泛应用于系统辨识、信号处理和自动控制等领域。与普通最小二乘法相比,RLS算法能够在线更新参数估计值,适用于实时性要求较高的场景。
我第一次接触RLS是在研究生阶段的系统辨识课程中。当时需要处理一个实时温度控制系统的参数辨识问题,批处理式的最小二乘法由于计算量大、无法实时更新,完全无法满足需求。导师建议尝试RLS算法,从此打开了新世界的大门。
2. 算法原理与推导
2.1 最小二乘法回顾
普通最小二乘法的目标是最小化误差平方和:
J(θ) = Σ(y(i) - φ(i)^Tθ)^2
其中θ为待估参数,φ(i)为回归向量,y(i)为观测输出。
其解析解为:
θ̂ = (Φ^TΦ)^(-1)Φ^TY
其中Φ为设计矩阵,Y为观测向量。
2.2 递推形式推导
RLS算法的核心思想是将上述批处理计算转化为递推形式。定义协方差矩阵P(k) = (Φ(k)^TΦ(k))^(-1),通过矩阵求逆引理可得递推公式:
-
增益向量计算:
K(k) = P(k-1)φ(k)/(λ + φ(k)^T P(k-1)φ(k)) -
参数更新:
θ̂(k) = θ̂(k-1) + K(k)(y(k) - φ(k)^Tθ̂(k-1)) -
协方差矩阵更新:
P(k) = (I - K(k)φ(k)^T)P(k-1)/λ
其中λ为遗忘因子(0<λ≤1),用于调节历史数据的权重。
注意:当λ=1时为普通RLS,λ<1时为带遗忘因子的RLS,适用于时变系统
3. 算法实现细节
3.1 初始化策略
良好的初始化对RLS算法至关重要。常见方案:
-
参数初始化:
θ̂(0) = 0 (零初始化)
或 θ̂(0) = θ₀ (若有先验知识) -
协方差矩阵初始化:
P(0) = δI,其中δ取较大值(如1e4~1e6)
这相当于初始阶段给予算法较大的调整自由度
3.2 数值稳定性处理
实际实现中需注意:
-
协方差矩阵正定性保持:
定期检查P(k)是否正定,必要时进行重置
或采用平方根滤波算法(更稳定但计算复杂) -
数据规范化:
对输入数据进行标准化处理(零均值、单位方差)
可显著改善数值条件数
3.3 计算复杂度优化
标准RLS计算复杂度为O(n²),对大系统可考虑:
-
快速RLS算法:
利用Toeplitz结构等特殊性质降复杂度 -
并行化实现:
将矩阵运算分解为多个并行任务
4. 典型应用场景
4.1 系统参数辨识
以二阶系统为例:
y(k) + a1y(k-1) + a2y(k-2) = b1u(k-1) + b2u(k-2) + e(k)
构建回归向量φ(k)=[-y(k-1) -y(k-2) u(k-1) u(k-2)]^T
待估参数θ=[a1 a2 b1 b2]^T
4.2 自适应滤波
在噪声消除中:
d(k) = x(k) + v(k) (含噪信号)
通过RLS估计噪声特性,实现实时滤波
4.3 实时控制
模型参考自适应控制中:
利用RLS在线更新被控对象模型参数
实现控制器参数的实时调整
5. 实际应用案例
5.1 温度控制系统辨识
在某恒温箱控制项目中,采用RLS进行热力学参数辨识:
- 采样周期:1秒
- 模型阶次:选择n=2(实验确定)
- 遗忘因子:λ=0.98
- 实现效果:
- 参数收敛时间约30秒
- 稳态误差<0.5℃
- 较批处理LS响应速度快5倍
5.2 机械臂动力学参数辨识
六自由度机械臂动力学模型:
τ = M(q)q̈ + C(q,q̇)q̇ + G(q)
通过RLS在线估计惯性矩阵M、科氏矩阵C和重力项G
关键技巧:
- 采用激励轨迹设计保证持续激励
- 参数化时将线性关系显式表达
- 使用变遗忘因子策略(λ从0.95渐增至0.99)
6. 常见问题与解决方案
6.1 参数发散问题
现象:估计参数剧烈波动或趋向无穷
可能原因:
- 持续激励不足
- 数值不稳定
- 模型阶次选择不当
解决方案:
- 检查输入信号频谱是否覆盖系统动态
- 改用UD分解或平方根滤波算法
- 通过AIC准则重新选择模型阶次
6.2 收敛速度慢
优化策略:
- 调整遗忘因子(减小λ加快收敛)
- 改进初始化(利用先验知识)
- 输入信号幅值优化(适当增大)
6.3 时变系统跟踪
应对方案:
- 采用变遗忘因子策略
- 结合变化检测算法(如卡方检验)
- 定期重置协方差矩阵
7. 进阶技巧与最新发展
7.1 正则化RLS
通过修改代价函数加入正则项:
J(θ) = Σ(y(i)-φ(i)^Tθ)^2 + α||θ||^2
改善病态问题下的数值稳定性
7.2 鲁棒RLS
采用H∞准则代替最小二乘:
提高对异常值的鲁棒性
代价是计算复杂度增加
7.3 深度RLS
结合神经网络:
用DNN生成回归向量
保持RLS的在线学习能力
同时具备深度特征提取优势
8. 代码实现示例(Python)
python复制import numpy as np
class RLS:
def __init__(self, n_params, lambda_=0.99):
self.n = n_params
self.lambda_ = lambda_
self.theta = np.zeros(n_params)
self.P = 1e4 * np.eye(n_params)
def update(self, phi, y):
# 计算增益向量
K = self.P @ phi / (self.lambda_ + phi.T @ self.P @ phi)
# 更新参数估计
error = y - phi.T @ self.theta
self.theta += K * error
# 更新协方差矩阵
self.P = (self.P - np.outer(K, phi.T) @ self.P) / self.lambda_
return self.theta
使用示例:
python复制# 二阶系统参数辨识
rls = RLS(4) # 4个参数
for k in range(1, len(data)):
phi = np.array([-y[k-1], -y[k-2], u[k-1], u[k-2]])
theta_hat = rls.update(phi, y[k])
9. 工程实践建议
-
数据采集阶段:
- 保证输入信号持续激励
- 采样频率至少5倍于系统带宽
- 记录足够长的动态过程数据
-
算法调试技巧:
- 先用仿真数据验证算法正确性
- 实时监测协方差矩阵条件数
- 保存中间结果便于问题诊断
-
性能评估指标:
- 参数收敛曲线
- 预测误差统计特性
- 计算耗时分析
在实际项目中,我发现RLS算法对初始条件比较敏感。一个实用的技巧是先用批处理LS得到初始估计,再切换到RLS进行在线更新,这样能显著改善初期收敛性能。另外,协方差矩阵的定期重置(如每1000次迭代)也能有效避免数值问题。
