☰
递推最小二乘(RLS)算法深度解析:从原理推导到MATLAB实现与调参实战
2026/10/12 21:01:46 网站建设 项目流程

简介:面向需要掌握递推最小二乘算法的学习者和工程人员,这份资源将可运行代码与详细实验报告配套,可用于系统辨识、自适应滤波和在线参数估计等场景,也适合课程设计与实验报告参考。压缩包内文件总数3个,含1个Python程序、1个Word实验报告和1个txt说明,整体大小仅316KB,文件体积小巧但内容完整。Python程序按初始化、预测、更新、循环迭代的结构实现RLS核心流程,清晰呈现遗忘因子和逆协方差矩阵的推算过程;Word报告从算法背景、原理推导、代码解析到实验结果分析逐步展开,能帮助读者对照源码理解每个步骤的含义。txt说明补充了运行环境和关键参数设置,便于快速调试与复现。目前已有466人学习/下载,对希望将理论与实践结合、提升算法编程和数据分析能力的读者,是一份结构完整的学习资料。 递推最小二乘(RLS)算法,这名字对课程群里很多同学来说,通常意味着一个带.rar后缀的压缩包:里面有现成的程序代码,还有一份word版实验报告。下载、解压、改个名字、交作业,一气呵成,但算法本身往往被忽略了。这篇博文我想认真拆一下RLS:从它为什么诞生、递推公式怎么来的,到一份能直接跑起来的代码,再到word实验报告怎么写才能不流水账,最后把我实际调试中踩过的坑一并说出来。

先给不明所以的读者定个位:RLS是系统辨识、自适应滤波、自适应控制领域最基础的在线参数估计算法之一,目标就一句话——来一个新数据,就更新一次模型参数估计,不需要把历史数据全存下来重新算。工程里它就是实时估计系统未知参数的那把螺丝刀。适合谁看?正在做系统辨识课程设计的本科生、论文里要用RLS做在线估计的研究生、以及想把RLS落地到实时系统的工程师,这篇都值得往下读。

1. 算法思路:为什么非要从批处理改成递推

1.1 批处理最小二乘的短板在哪里

标准的批处理最小二乘大家都见过,对模型 y = Φθ + e,参数估计是 θ̂ = (ΦᵀΦ)⁻¹Φᵀy。这个公式极其简洁,但有一个致命前提:你得一次性拿到全部数据,才能算一次估计。离线处理一段历史数据当然没问题,可如果系统在实时运行,数据是一个点一个点进来的,或者模型参数本身会随着工况缓慢漂移,批处理就非常尴尬——总不能每来一个点,就把过去所有数据重新攒起来求一次逆吧。矩阵求逆的复杂度是O(n³),数据量一大,计算量直接爆炸,嵌入式设备根本扛不住。

所以RLS做的事情,核心就是改写这个计算结构:把"用全部历史数据估参数"变成"用上一次的参数估计值 + 新来的一个点做修正"。递推,本质上是一种渐进逼近的思路,不是每步都重头算,而是充分利用了上一步的信息。

1.2 递推公式是怎么来的

RLS的数学推导核心是矩阵求逆引理,也叫Woodbury恒等式。假设上一步的协方差矩阵是P(k-1),新数据来了要更新成P(k),直接推会得到一个带矩阵逆的表达式,用Woodbury恒等式把这个逆消掉,就能得到纯递推的三条核心公式:

θ̂(k) = θ̂(k-1) + K(k)·[y(k) - φᵀ(k)θ̂(k-1)]

K(k) = P(k-1)φ(k) / [λ + φᵀ(k)P(k-1)φ(k)]

P(k) = [I - K(k)φᵀ(k)]P(k-1) / λ

符号看着多,实际上每一步就干三件事:先算增益K(k),决定"新数据值多少信任";再用实际输出和模型预测输出的差值修正参数;最后更新P矩阵为下一步做准备。这里的φ(k)是回归向量,y(k)是当前输出,θ是待估参数向量,λ是遗忘因子。

这个结构有一个非常直观的理解方式:K(k)就是"对新数据的信任程度"。如果历史数据噪声大,或者之前估计得不准,K会大一些,让新数据多发挥修正作用;反之,如果模型已经收敛、新数据也没多少额外信息,K会自动变小,参数基本不动。RLS最迷人的地方就在这——它自带一种自适应调节的机制,不需要人干预就知道该不该更新、更新多少。

λ的作用也必须说清楚。λ=1表示所有历史数据权重一样,相当于"长记忆";λ<1时,越老的数据被指数级衰减,算法能追上参数的慢变。后面我会专门讲λ怎么选。

2. 可运行的代码:从零实现一个RLS估计器

2.1 MATLAB核心代码

课程设计最常用的语言是MATLAB,我这里给出一段精简但完整的核心代码。第一步是单步递推函数,封装好后可以反复调用:

function [theta, P] = rls_update(phi, y, theta, P, lambda) % RLS单步递推 % phi - 回归向量, n×1 % y - 当前输出标量 % theta - 当前参数估计, n×1 % P - 协方差矩阵, n×n % lambda- 遗忘因子, 0<lambda<=1 Pphi = P * phi; denom = lambda + phi' * Pphi; % 标量 K = Pphi / denom; % 增益向量 err = y - phi' * theta; % 预测误差 theta = theta + K * err; % 参数更新 P = (P - K * phi' * P) / lambda; % 协方差更新 end

这段代码核心就四行,但每行都有讲究。denom必须先算成标量,避免后续维度错误;P更新用的是"测量更新后再除以λ"的形式,λ=1时退化为标准RLS。实际工程里,我建议每次更新后顺手把P强制对称一下,比如 P = (P + P') / 2,防止长时间运行浮点误差把P的对称性破坏掉。

2.2 一个完整的仿真案例

光有递推函数不够,得跑一个有意义的例子。经典场景是一阶ARX模型的参数在线辨识:

y(k) = a·y(k-1) + b·u(k-1) + e(k)

待估参数θ = [a, b]ᵀ,回归向量φ(k) = [y(k-1), u(k-1)]ᵀ。我用MATLAB生成仿真数据,再用RLS做在线辨识,看它能不收敛到真值:

% 参数辨识仿真: y(k) = -0.8*y(k-1) + 0.4*u(k-1) + e(k) clear; clc; N = 1000; a_true = -0.8; b_true = 0.4; % 输入信号: 随机序列, 保证持续激励 u = randn(N, 1); y = zeros(N, 1); for k = 2:N y(k) = a_true*y(k-1) + b_true*u(k-1) + 0.05*randn; end % RLS初始化 theta = [0; 0]; % 初始参数估计 P = 100 * eye(2); % 初始协方差, 取较大值 lambda = 1.0; % 遗忘因子, 时不变系统取1即可 theta_rec = zeros(2, N); % 记录每步估计值 for k = 2:N phi = [y(k-1); u(k-1)]; [theta, P] = rls_update(phi, y(k), theta, P, lambda); theta_rec(:, k) = theta; end % 绘图 plot(1:N, theta_rec(1,:), 'b', 1:N, theta_rec(2,:), 'r'); hold on; plot(1:N, a_true*ones(1,N), 'b--', 1:N, b_true*ones(1,N), 'r--'); legend('a估计值', 'b估计值', 'a真值', 'b真值'); xlabel('采样点数 k'); ylabel('参数估计值');

跑完这个程序,你会看到参数大概在几十个采样点内从0收敛到真值附近。需要提醒的是:u(k)不能是常数或单频正弦,否则无法同时激励出两个参数。这一点是实验报告里很好的讨论素材,后面细说。

2.3 初始化P矩阵的讲究

代码里我特意把P的初值设为100·I,这不是随手拍的。P的物理含义可以理解成参数估计误差的协方差,初始值代表的是"你对初始参数估计有多少信任"。初值P越大,说明你越不相信初始的θ=0,算法会更快地修正参数;反过来,如果P初值设得太小,比如0.01·I,算法会表现出"过度自信",新数据对参数几乎不起修正作用,收敛慢得让人抓狂。

经验取值:参数完全未知时,用10⁴·I这种大数量级;有一定先验信息时,用1~10·I就够。这个细节在报告的"参数设置与讨论"部分非常加分,很多同学只会写"P=100*I",能讲清楚为什么这么取,评阅时印象分会明显不一样。

3. word版实验报告:结构与写作要点

3.1 报告章节怎么排

RLS实验报告最忌讳把代码一贴、图一摆就交差。这套课设报告我建议按下面这个结构来,既规范又不容易显得注水:

实验目的:写清楚三件事,掌握RLS的递推原理,实现在线参数辨识,理解遗忘因子对跟踪性能的影响。三句话足够。

实验原理:把模型、三条递推公式、每个符号含义捋清楚。重点提醒:公式必须用Word自带的公式编辑器排版,不要截图或贴图片,否则老师一眼看出是拼凑的。

实验步骤:按"生成仿真数据→编写RLS函数→运行辨识→画图分析"组织,每一步附核心代码片段。

实验结果:放参数收敛曲线图和预测误差变化曲线。图要横平竖直,坐标轴标注完整,图例清晰。

结果分析:这是报告精华所在,建议至少按三个方向展开:一是收敛速度与P初值的关系;二是λ=1和λ=0.95时对突变参数的跟踪效果对比;三是讨论输入信号的持续激励条件。把这三块写透,报告深度直接上一个档次。

3.2 图表数据的组织技巧

很多同学的实验报告里图是图、表是表,彼此不呼应。实际上,参数收敛过程除了画曲线,还可以在关键节点放一个表:比如分别记录k=50、100、200、500时的a、b估计值,再附一列相对误差。这样一个收敛过程表格配一组曲线图,两种视角互相印证,观察起来非常直观。

代码部分放核心代码即可,完整的可运行代码作为附录放在最后,或者和压缩包内的.m文件保持一致。这里有一个很多老师会验证的细节:word报告里的代码必须和实际跑的代码完全一致,不能报告里一段、源文件里另一段。

3.3 从评阅视角看的几个加分项

带课设这些年,我观察到实验报告拉开差距的往往不是代码复杂度,而是那几个"软"部分:实验原理里公式推导是否完整、结果分析里有没有对异常现象的解释、总结里是否写出了失败尝试和解决过程。这些都是真实做过实验才写得出来的内容,也是抄报告最容易露馅的地方。

建议你在报告里至少写一次"失败经历":比如最初P初值设置不当导致收敛过慢,分析原因后调整初值重做。这种细节一写,报告的可信度和区分度立刻不一样。用"批处理最小二乘和递推最小二乘的结果对比"作为延伸思考题,也是很多老师喜欢看到的内容。

4. 实操中的常见问题与排查技巧

4.1 数值发散:P矩阵非正定的坑

这是RLS工程应用里最大的坑。理论上P矩阵始终对称正定,但在计算机浮点运算下,长时间递归后P经常丢失正定性,导致增益K算出来是飞出去的,参数估计值也跟着发散。我第一次正式做RLS实验时,在迭代几万步后看到a估计值突然跳到-5.2还自己"拉回来",当时以为是算法错了,排查半天才发现是P矩阵数值出了毛病。

解决思路有三种,按优先级排:一是每步更新后强制对称化,P = (P + P') / 2;二是改用平方根RLS,用P的Cholesky因子递推,从根上保证半正定性;三是在参数更新后加一个合理范围判断,防止异常值污染后续估计。课程设计用方法一就够,做工程建议直接上平方根RLS或者Bierman算法,网上有现成实现,不必自己造轮子。

4.2 遗忘因子λ:时变参数跟踪的关键旋钮

固定参数系统用λ=1没问题,但对象参数漂移时,必须把λ调小。我实测下来,λ=0.99左右适合慢速漂移的跟踪,λ=0.95及以上适合较快的突变。λ太小是有代价的:算法"记忆"变短,等效于参与估计的数据点变少,噪声对参数估计的扰动会明显变大。

用一句话概括:λ是平衡跟踪速度与噪声抑制的旋钮。哪边指标不满足,就往另一个方向拧一点,直到两头都能接受。我在参数突变实验里把a_true在第500步从-0.8跳到-0.2,λ=1时估计值要一屏时间才缓缓追上去,λ=0.95时几十步就能跟上,但稳态方差明显变大。这组对比图放报告里,是"时变系统跟踪"小节的天然素材。

4.3 持续激励条件:输入信号没设计对,一切都白搭

要估计两个参数,输入信号就得"足够丰富",专业术语叫持续激励条件。用常数输入,模型只能看到静态工况,两个参数的组合效应无法区分;用单频正弦也不行,只有一个频率成分,信息量不够。我常用的做法是随机白噪声或者PRBS伪随机序列,课堂实验最省事的是randn,但如果你想在报告里体现理解深度,写一句"PRBS能在较宽频带内保证持续激励",评阅老师会注意到这里的差别。

4.4 常见问题速查表

把实操中最高频的几个问题整理成一张表,排查时直接对照:

现象可能原因处理方法
参数长期不收敛P初值太小增大P初值到10²·I量级以上
参数震荡剧烈、方差大λ太小,噪声放大调大λ,靠近0.98~1.0
参数跟踪不上突变λ=1长记忆导致设置λ=0.95~0.98
迭代后期参数突然发散P矩阵失去正定性强制对称化,或改用平方根RLS
两个参数无法同时辨识输入信号激励不充分换PRBS或白噪声输入

这张表本身就是你动手调参时最快能复用的工具,也建议直接做到你的实验报告"问题与讨论"章节里,比抄一段理论分析实在得多。

我个人在实际操作中的体会是:RLS这个算法代码量极小,三四个公式加一个循环就完了,但真正用好它,靠的是对初值、遗忘因子、激励信号这些"周边参数"的理解。如果你正在准备这门课设,与其到处找现成的.rar版本下载,不如花一个下午把这些参数都亲手试一遍,效果比看十份别人的报告都好。这个项目后续扩展也很顺手:往多变量模型推,换成平方根RLS应对长时运行,再加一个变遗忘因子逻辑,就能直接当自适应控制器的参数估计核心。递推最小二乘这层地基打好了,后面看卡尔曼滤波、置信传播这些同族的递推估计算法都会快很多。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询