Python实战:序贯最小二乘与卡尔曼滤波的核心差异可视化解析

在数据处理领域,当面对静态参数校准和动态状态估计两类不同需求时,序贯最小二乘平差(Sequential Least Squares Adjustment)和卡尔曼滤波(Kalman Filter)是两种常被提及的算法。许多初学者容易混淆它们的适用场景,本文将用Python代码实现这两种算法,并通过同一组传感器数据的处理结果对比,揭示它们本质的区别。

1. 算法原理与适用场景

1.1 序贯最小二乘的本质

序贯最小二乘是传统最小二乘法的递推版本,其核心假设是待估参数在观测期间保持不变。想象一下测量房间温度的场景:虽然每次测量值可能不同,但我们假设真实温度是恒定的。这种情况下,序贯最小二乘会逐步"消化"新数据,不断优化对同一组参数的估计。

关键特性

  • 参数被视为确定量(非随机变量)
  • 不需要参数的先验统计信息
  • 适用于静态系统参数估计
  • 计算效率高,适合大规模数据分批处理
import numpy as np

class SequentialLeastSquares:
    def __init__(self, n_params):
        self.P = np.eye(n_params) * 1e6  # 初始协方差矩阵
        self.x = np.zeros(n_params)      # 参数估计
        
    def update(self, H, z, R):
        # H: 设计矩阵,z: 观测值,R: 观测噪声协方差
        K = self.P @ H.T @ np.linalg.inv(H @ self.P @ H.T + R)
        self.x += K @ (z - H @ self.x)
        self.P = (np.eye(len(self.x)) - K @ H) @ self.P

1.2 卡尔曼滤波的动态哲学

卡尔曼滤波则专为动态系统设计。以跟踪无人机位置为例,位置、速度等状态量随时间变化,且系统受到过程噪声影响。卡尔曼滤波通过状态方程描述这种动态变化,并利用观测数据不断修正状态估计。

动态系统特征

  • 状态量被视为随机变量,具有统计特性
  • 需要状态转移模型和过程噪声统计
  • 包含预测(基于模型)和更新(基于观测)两个阶段
  • 能够处理时变系统的状态估计问题
class KalmanFilter:
    def __init__(self, F, Q, H, R, x0, P0):
        self.F = F  # 状态转移矩阵
        self.Q = Q  # 过程噪声协方差
        self.H = H  # 观测矩阵
        self.R = R  # 观测噪声协方差
        self.x = x0 # 初始状态估计
        self.P = P0 # 初始估计协方差
        
    def predict(self):
        self.x = self.F @ self.x
        self.P = self.F @ self.P @ self.F.T + self.Q
        
    def update(self, z):
        K = self.P @ self.H.T @ np.linalg.inv(self.H @ self.P @ self.H.T + self.R)
        self.x += K @ (z - self.H @ self.x)
        self.P = (np.eye(len(self.x)) - K @ self.H) @ self.P

1.3 关键区别对比表

特性 序贯最小二乘 卡尔曼滤波
参数性质 非随机参数 随机状态变量
时间特性 静态系统 动态系统
先验信息 不需要 需要初始估计和协方差
计算复杂度 较低 中等
适用场景 仪器校准、参数标定 目标跟踪、导航定位
对过程噪声的处理 不考虑 显式建模

2. 实战数据准备与问题设定

2.1 模拟传感器数据生成

为了直观比较两种算法,我们模拟一个包含静态参数和动态状态的混合场景。假设我们有一个温度传感器系统:

  • 静态参数:传感器偏置(不随时间变化)
  • 动态状态:环境温度(随时间缓慢变化)
np.random.seed(42)

# 时间序列
t = np.linspace(0, 10, 100)
dt = t[1] - t[0]

# 真实值
true_bias = 2.5  # 静态偏置
true_temp = 25 + np.sin(0.5*t)  # 动态温度

# 观测数据 (带噪声)
obs_noise = np.random.normal(0, 0.5, len(t))
observations = true_temp + true_bias + obs_noise

2.2 问题建模

我们需要同时估计:

  1. 传感器偏置(静态参数)
  2. 环境温度(动态状态)

这将展示两种算法如何处理不同类型的参数:

  • 序贯最小二乘:将所有参数视为静态
  • 卡尔曼滤波:区分静态参数和动态状态

3. 算法实现与结果对比

3.1 序贯最小二乘实现

将温度和偏置都作为静态参数处理:

# 设计矩阵:每次观测都关联两个参数
H_seq = np.ones((1, 2))  # [1, 1] 因为观测值是温度+偏置

sls = SequentialLeastSquares(2)  # 两个参数

estimates_seq = []
for z in observations:
    sls.update(H_seq, np.array([z]), np.eye(1)*0.25)  # R=0.25
    estimates_seq.append(sls.x.copy())
    
estimates_seq = np.array(estimates_seq)

3.2 卡尔曼滤波实现

建立状态空间模型,区分静态和动态分量:

# 状态向量: [温度, 温度变化率, 偏置]
F = np.array([[1, dt, 0],  # 温度动态模型
              [0, 1, 0],    # 变化率模型
              [0, 0, 1]])   # 偏置不变

Q = np.diag([0.01, 0.1, 0])  # 过程噪声(偏置无噪声)
H_kf = np.array([[1, 0, 1]])  # 观测模型: 温度 + 偏置
R_kf = np.eye(1) * 0.25       # 观测噪声

kf = KalmanFilter(F, Q, H_kf, R_kf, 
                  x0=np.array([25, 0, 0]),  # 初始猜测
                  P0=np.diag([10, 5, 10]))  # 初始不确定性

estimates_kf = []
for z in observations:
    kf.predict()
    kf.update(np.array([z]))
    estimates_kf.append(kf.x.copy())
    
estimates_kf = np.array(estimates_kf)

3.3 结果可视化与分析

使用Matplotlib绘制估计结果对比:

import matplotlib.pyplot as plt

plt.figure(figsize=(12, 8))

# 温度估计对比
plt.subplot(2, 1, 1)
plt.plot(t, true_temp, 'k--', label='真实温度')
plt.plot(t, estimates_seq[:,0], 'r-', label='序贯最小二乘')
plt.plot(t, estimates_kf[:,0], 'b-', label='卡尔曼滤波')
plt.ylabel('温度 (°C)')
plt.legend()

# 偏置估计对比
plt.subplot(2, 1, 2)
plt.axhline(true_bias, color='k', linestyle='--', label='真实偏置')
plt.plot(t, estimates_seq[:,1], 'r-', label='序贯最小二乘')
plt.plot(t, estimates_kf[:,2], 'b-', label='卡尔曼滤波')
plt.ylabel('传感器偏置')
plt.xlabel('时间 (s)')
plt.legend()

plt.tight_layout()
plt.show()

关键观察

  1. 对静态偏置的估计:

    • 两种算法最终都收敛到真实值附近
    • 序贯最小二乘收敛更快,但对动态温度跟踪不佳
  2. 对动态温度的跟踪:

    • 卡尔曼滤波能很好地跟随温度变化
    • 序贯最小二乘将温度视为静态,导致滞后

4. 工程实践中的选择建议

4.1 何时选择序贯最小二乘

典型场景

  • 传感器标定与校准
  • 离线处理静态系统参数
  • 计算资源有限的大型平差问题
  • 参数先验统计信息未知的情况

提示:当处理GNSS接收机天线相位中心校准这类纯静态问题时,序贯最小二乘通常是更简单有效的选择。

4.2 何时选择卡尔曼滤波

适用条件

  • 系统状态随时间演变
  • 具备可靠的状态转移模型
  • 需要实时处理数据流
  • 过程噪声统计特性已知或可估计

实际经验 :在组合导航系统中,IMU的误差参数(如零偏)通常用序贯最小二乘标定,而位置/姿态估计则必须用卡尔曼滤波。

4.3 混合策略与进阶思考

在某些复杂系统中,可以组合使用两种方法:

  1. 用序贯最小二乘标定静态参数
  2. 将标定结果作为卡尔曼滤波的初始条件
  3. 用卡尔曼滤波进行动态状态估计

性能优化技巧

  • 对于准静态系统,可定期用序贯最小二乘重新标定
  • 在卡尔曼滤波中,对静态参数设置极小的过程噪声
  • 使用自适应算法动态调整噪声统计特性

更多推荐