ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

递推最小二乘(RLS)算法原理、MATLAB实现与实验报告全解析

2026/9/3 18:41:48 拓冰建站 浏览量
递推最小二乘(RLS)算法原理、MATLAB实现与实验报告全解析 简介面向动态系统参数估计与在线学习场景递推最小二乘算法RLS程序代码与Word实验报告打包在一起适合需要理解RLS原理并上手Python实现的算法学习者、数据分析和自动化控制方向学生。压缩包共3个文件包含一个Python脚本用于算法实现一个txt程序说明便于快速运行一个doc详细实验报告系统讲解算法背景、推导、代码解析与实验结果。包体仅316KB轻量实用。已有466人学习下载。读者可对照代码逐行理解初始化、预测、更新、遗忘因子设定等关键步骤再通过实验报告中的结果分析掌握RLS在实际数据上的表现与调参思路形成从理论到实践的完整闭环。由于报告和代码均来自真实实验整理尤其适合完成课程设计、复习算法或作为毕业设计参考。 这个文件名我太熟了。打开你手里的这份压缩包里面要么是一段能跑出参数收敛曲线的MATLAB或Python代码要么是一份排版规整的Word实验报告通常两个都有。递推最小二乘Recursive Least SquaresRLS是系统辨识、自适应控制和信号处理课程里绕不开的一块内容它解决的是“系统参数未知如何用实时采集的数据不断修正对参数的估计”这个问题。说人话就是你有一堆输入输出数据但不知道系统内部长什么样RLS能一边收数据一边把系统模型的参数猜出来而且每来一个新数据点就更新一次猜测结果。这套资源适合谁两类人最需要。一类是自动化、控制工程专业的学生课程设计和实验报告能直接用另一类是刚入门的工程师想在仿真环境里先验证RLS算法再往嵌入式或实时控制里移植。今天我写这篇文章不只是带你把这个压缩包里的代码跑通更重要的是把RLS的推导逻辑、程序实现、实验报告写法以及那些文档里不会写明白的调参细节一次性讲透。1. 压缩包里的RLS先搞明白这个算法解决什么问题1.1 从批量最小二乘到递推形式先回到最朴素的场景。假设你想辨识一个单输入单输出系统的参数用差分方程描述y(k) a1·y(k-1) b1·u(k-1) v(k)其中u是输入y是输出v是噪声a1、b1就是要辨识的参数。传统的最小二乘法很直接攒够N组数据把方程组写成矩阵形式Y Φ·θ然后用θ (ΦᵀΦ)⁻¹·ΦᵀY一次性求出参数估计值。这样做的缺点是显而易见的数据必须全部保存计算量随数据量增长而且系统参数一旦随时间变化旧数据反而变成干扰。RLS的思路就是把上面的批量计算拆成一步一步的迭代。每一时刻只用当前新数据修正上一次的参数估计值旧的估计结果不推翻重来而是顺着误差方向微调。用生活类比的话批量最小二乘就像期末考试一次把整本书都背完再答题RLS则是每节课后都复习一遍知识不断滚动更新。后者天然适合在线场景比如电机参数辨识、飞行器气动参数估计、自适应噪声对消这类场景要求算法在数据到达后立刻给出结果做不到把数据保存下来再统一处理。1.2 RLS的核心更新公式到底在算什么RLS的每一次迭代要算三件事预测误差、增益向量、协方差矩阵更新。公式如下预测误差e(k) y(k) - φᵀ(k)·θ(k-1)增益向量K(k) P(k-1)·φ(k) / (λ φᵀ(k)·P(k-1)·φ(k))参数更新θ(k) θ(k-1) K(k)·e(k)协方差矩阵更新P(k) (I - K(k)·φᵀ(k))·P(k-1) / λ这里的φ(k)是回归向量由过去输入输出构成θ是待辨识参数向量λ是遗忘因子取值在0到1之间。你能看到每个公式的角色预测误差衡量当前模型“猜得准不准”增益向量决定“这个误差该按多大比例修正参数”协方差矩阵则记录了参数估计的不确定度。很多人学到这里会被矩阵符号绕晕。我的理解方式是P矩阵其实承担了“学习率调度器”的角色。刚开始你对参数一无所知P初始值设得很大增益K就大数据对参数修正的步幅也大随着数据积累P逐渐变小增益收缩参数修正越来越精细。遗忘因子λ则控制“旧数据被遗忘的速度”λ越接近1算法越信任历史数据参数估计越平滑λ越小算法越重视近期数据跟踪时变参数的能力变强但对噪声也更敏感。1.3 这份“程序代码实验报告”资源包的原始价值下载这种压缩包的人多半不是要研究理论而是遇到了实际问题明天要交实验报告论文里需要仿真对比图或者项目里需要一个在线辨识模块。压缩包的价值在于它一次给了你两条线能跑的代码给你一个可以直接改的起点Word报告给你一个结构和写法上的参考。但我也要泼一盆冷水网上这类资源的质量参差不齐。有些代码写得草率没有加遗忘因子也不做信号激励设计跑出来的曲线根本不收敛有些报告数据是编的图和代码对不上。你下载之后第一件事不是打开Word看结论而是先跑代码把每一步运行结果和报告里的图对照一遍确认这份资源是不是自洽的。2. 原理深挖遗忘因子、协方差矩阵和参数收敛性2.1 为什么一定要加遗忘因子标准RLS推导中λ1也就是所有历史数据权重相同。这在参数恒定的系统里没问题可实际系统很难一直不变电机绕组温度升高导致电阻变化飞机飞行速度改变导致气动参数变化液压系统油温变化导致摩擦系数漂移。如果参数变了而算法还把所有历史数据一视同仁收敛结果就会被旧数据拖住响应跟不上变化。引入遗忘因子的本质是对误差函数里的历史项做指数加权。RLS极小化的准则函数是J(θ) Σ λ^(k-i)·e²(i)从i1到k求和。λ0.98时50步之前的数据权重衰减到约0.36100步前的数据只剩约0.13。这就像记笔记时每隔一段时间就擦掉旧内容给新内容留出空间。选λ的经验规则是系统参数变化快就取0.95~0.98变化慢或基本不变就取0.99~1。取太小的话参数估计容易跟着噪声抖成心电图。2.2 初始值P(0)和θ(0)的选取逻辑RLS启动时需要两个初始值θ(0)和P(0)。θ(0)好办没先验信息就设全零或者设一个粗略的估计值。P(0)则有个经验法则——设成一个大数乘以单位阵比如P(0) 1000·I甚至更大。为什么P(0)要大回到增益公式看P(0)大意味着K(1)大最初几步参数更新步幅大能把θ从“瞎猜”迅速拉到接近真值的区域。如果P(0)设太小比如设成0.1·I增益始终很小参数收敛会非常慢甚至看起来像不动了。我见过有人把P(0)设成0直接导致算法完全不更新排查半天才发现是初始协方差设置的问题。另外要注意P矩阵在在线运行中必须保持正定对称如果出现数值漂移导致P失去正定性整个递推会发散。实际工程中必要时可以定期检查P的最小特征值。2.3 输入信号激励与参数可辨识性RLS不是对任何数据都有效。如果输入信号u(k)一直是常数或者只有一个固定的幅值那么回归向量φ(k)的各维之间会高度相关ΦᵀΦ接近奇异P矩阵会急剧膨胀参数估计过程会出现剧烈震荡甚至发散。这种现象背后的理论叫“持续激励条件”。简单理解就是输入信号要足够丰富能把系统的各个模态都激发出来。最常用的方式是输入伪随机二进制序列PRBS或者叠加不同频率的正弦信号。做仿真和实验时我通常用MATLAB的idinput函数生成带幅值限制的PRBS信号这样既保证激励充分又不会让系统工作点跑出线性区间。这一点在实验报告里值得专门写一段因为评委或老师很容易问“为什么输入信号长这样”。3. 程序代码实操一份能直接跑出收敛曲线的实现3.1 仿真环境准备与数据生成下载的压缩包如果直接用最好如果没有或者代码有问题你就自己动手写一个完整demo。推荐用MATLAB因为系统辨识工具箱和处理曲线都方便如果用PythonNumPy足够完成核心计算Matplotlib负责画图。仿真对象用一个带噪的二阶差分方程y(k) 1.5·y(k-1) - 0.7·y(k-2) 0.5·u(k-1) 0.3·u(k-2) v(k)其中v(k)是均值为0、方差0.01的高斯白噪声。真参数向量θ [1.5, -0.7, 0.5, 0.3]。这样的系统模仿一个欠阻尼的二阶动态系统辨识难度适中能明显看到收敛过程又不至于收敛不了。数据长度取500步前200步让参数估计收敛后300步观察稳态精度。如果想测试遗忘因子的效果可以在第300步把真实参数突变一下比如a1从1.5改到1.2看算法能否跟上。3.2 核心代码逐段解读下面是MATLAB版本的RLS核心循环结构就是“数据生成—初始化—递推—画图”。Python版本原理相同稍后在3.3给出裁剪版% 参数设置 N 500; lambda 0.99; theta_true [1.5; -0.7; 0.5; 0.3]; % 信号生成 u idinput(N, prbs, [0 1/5], [-1 1]); % PRBS激励信号 v 0.1 * randn(N, 1); y zeros(N, 1); phi zeros(4, 1); theta_est zeros(4, N); P 1000 * eye(4); for k 3:N % 组装回归向量: [y(k-1), y(k-2), u(k-1), u(k-2)] phi [y(k-1); y(k-2); u(k-1); u(k-2)]; % 生成当前输出 y(k) phi * theta_true v(k); % RLS核心三件事 e y(k) - phi * theta_est(:, k-1); % 预测误差 K P * phi / (lambda phi * P * phi); % 增益向量 theta_est(:, k) theta_est(:, k-1) K * e; % 参数更新 P (eye(4) - K * phi) * P / lambda; % 协方差更新 end % 作图 t 1:N; plot(t, theta_est); legend(a1, a2, b1, b2);这段代码里最需要注意的循环顺序先用当前数据更新y(k)再用更新后的y(k)参与递推计算。如果顺序写反也就是用上一步的y值算回归向量那相当于引入了一步延迟收敛结果会有系统性偏差。另外P的更新公式里没有直接写成P P - K·φᵀ·P这种形式而是保留除法因子λ在遗忘因子不等于1时必须在除法里包含λ否则遗忘因子不会起到作用。3.3 Python版本NumPy实现的核心片段如果你更习惯Python核心计算部分几乎可以一行不差地翻译过来。import numpy as np import matplotlib.pyplot as plt N 500 lam 0.99 theta_true np.array([1.5, -0.7, 0.5, 0.3]) # PRBS可用随机二值信号近似 rng np.random.default_rng(42) u rng.choice([-1.0, 1.0], sizeN) v 0.1 * rng.standard_normal(N) y np.zeros(N) theta_est np.zeros((4, N)) P 1000 * np.eye(4) theta_hat np.zeros(4) for k in range(2, N): phi np.array([y[k-1], y[k-2], u[k-1], u[k-2]]) y[k] phi theta_true v[k] e y[k] - phi theta_hat K P phi / (lam phi P phi) theta_hat theta_hat K * e P (np.eye(4) - np.outer(K, phi)) P / lam theta_est[:, k] theta_hatPython版本注意两个细节K的计算要区分向量内积和矩阵乘向量公式里分母是标量分子是P·φ的列向量更新theta_est时要用theta_hat的副本避免浅拷贝导致历史值被覆盖。仿真跑下来前50步参数会快速逼近真值后面基本贴着真值上下波动波动幅度取决于噪声方差和遗忘因子的组合。4. 实验报告怎么写从实验目的到结果分析一条线4.1 报告结构框架与每个板块的写作重心打开资源包里的Word报告你会发现一个相对标准的实验报告模板。我见过太多学生把实验报告写成“操作说明书”目的写“熟悉RLS算法”原理抄一段公式步骤列几条结果贴两张图。这样的报告分数不会高。一份高质量的实验报告需要做到四件事问题定义清楚、推导链条完整、结果有对比、结论有解释。实验目的部分不是复述算法定义而是说明“在什么假设下、辨识什么系统、达到什么精度”。比如可以写成在输入信号满足持续激励、噪声为零均值白噪声的假设下采用带遗忘因子的递推最小二乘法对二阶带噪系统进行在线参数辨识分析收敛速度、稳态精度及遗忘因子对跟踪性能的影响。这样一句话把模型、方法、场景、指标全概括了。原理部分除了公式强烈建议写一小段推导说明RLS是“如何从批量最小二乘推导到递推形式的”通常的路径是写出最小二乘准则函数—求导得法方程—引入矩阵求逆引理—整理出递推三项公式。这个推导是老师最喜欢在答辩时提问的地方。4.2 结果呈现参数收敛曲线、误差曲线与指标表结果部分要有图有表三样东西最必要参数估计随时间变化的收敛曲线、模型输出的预测误差曲线、不同遗忘因子下的性能对比表。参数收敛曲线用折线图把真值用虚线画出来读者一眼就能看出估计值是否收敛到真值。预测误差曲线能反映模型精度变化误差应该在初始阶段偏大然后逐渐衰减到噪声水平。性能对比表可以列出不同λ值下的收敛步数、稳态均方误差直观展示遗忘因子对跟踪能力和噪声抑制能力的影响。这里有个经验之谈报告里的图不要只贴一张最终结果图。建议把λ0.95、0.99、1.0三组实验放在同一张图里对比这样“遗忘因子越小跟踪越快但波动越大”这个结论就能被直观展示出来。还有一个高频考点是“递推最小二乘与批量最小二乘的对比”如果实验报告能加一张对比表在相同数据集下比较两种方法的辨识精度和计算时间整份报告的价值会高一个档次。4.3 结论与心得说说“怎么看结果”而不是“做了什么”实验结论部分别写“本文实现了RLS算法”而要写“针对具有零均值噪声的二阶系统当遗忘因子λ0.99时RLS算法在约80步内实现参数收敛稳态误差低于噪声标准差当λ0.95时收敛速度提升至约40步但稳态波动增加约50%”。这种结论才是有信息量的。心得部分可以提几个真实操作中的点比如发现P(0)初始值对收敛速度极其敏感、PRBS激励信号相比正弦信号辨识效果更稳定、遗忘因子太小时参数估计几乎跟随噪声波动。这些细节能证明你不是把代码跑一遍就完事而是真正理解了算法的行为。5. 调试RLS最容易踩的坑基于实测的排查经验5.1 参数收敛但偏了检查数据生成顺序与噪声模型症状是参数曲线很平滑地收敛但收敛值跟真值差了一截。最常见的原因是数据生成时噪声被加到了闭环里或者回归向量里用了被噪声污染的y值但公式里没有对应处理。如果你的系统是“输出端加噪声”模型也就是y(k) φᵀθ v(k)那用普通RLS没问题因为噪声与回归向量不相关。但如果你把噪声加到了输入端u(k)上或者噪声是有色噪声参数估计就会出现偏置。这种场景应该改成增广最小二乘或辅助变量法。另一个容易忽略的点是PRBS信号的幅值。幅值太小时输出中的信号成分被噪声淹没信噪比过低参数估计的方差会很大。经验做法是先跑一次开环仿真算出输出信号的方差让噪声方差控制在信号方差的1%到10%之间。5.2 P矩阵发散或数值异常优先检查激励和λ如果运行中参数突然跳变到天文数字大概率是数值问题。第一个查P矩阵在发散前是否已经出现负特征值这通常由长期持续激励不足引起。第二个查λ是不是设得太小比如0.9以下协方差矩阵被不断放大数值容易爆炸。第三个查公式实现里是否在P更新时漏掉了除以λ这种低级错误会导致P指数式增长。实际调试时我的做法是在循环里加一个数NaN检查一旦theta_est或P出现非有限值马上打印当前k值、增益范数和P的迹定位是哪一步开始发散。这种检查代码非常短但在排查问题时能省下大量时间。5.3 参数能收敛但速度太慢调P(0)而不是调λ如果你发现参数要几百步才收敛到真值附近第一个该调的是P(0)的量级而不是λ。把P(0)从100·I改成10000·I收敛速度往往有成倍的提升。这是因为P(0)决定了最初的增益大小而λ影响的是整个时间区间内的“记忆长度”用λ去加速收敛会带来稳态波动增大的副作用性价比不高。如果参数初始偏差特别大也可以考虑分段式策略前100步用较大的P(0)和λ1快速逼近之后切换较小的P和λ1提高跟踪能力和抑制噪声。这种“粗调精调”的策略在现场调试中比固定参数更实用。6. 把这份资源用得更透后续扩展方向这个压缩包提供的RLS实现只能算一个起点实际项目里还有很多扩展方向。一个是把普通RLS改成带可变遗忘因子的版本根据预测误差的幅值实时调整λ误差大时减小λ提高跟踪速度误差小时增大λ降低波动这在目标跟踪和自适应控制里很有用。另一个是向非线性场景扩展比如用核函数把数据映射到高维特征空间做核递推最小二乘或者通过局部线性化来处理弱非线性系统。再一个就是工程化方向把算法用C语言实现并移植到嵌入式平台这时候需要注意矩阵运算库的选择和定点数处理这是另一个大的话题。最后再分享一个我在实际使用中的习惯下载这类资源包后我不会急着用而是先新建一个测试脚本把代码里的参数全部改成已知值跑通之后再换成真实数据。这一步看起来多余但能帮你分清“算法问题”和“数据问题”。很多人拿着下载的代码直接套自己的数据跑出来不收敛就怀疑算法有问题实际上大多数时候是初始参数、激励条件或者遗忘因子没有适配。先把仿真环境下标定参数再上真实数据这个习惯能避开掉进最常见的坑。本文还有配套的精品资源点击获取