估计、滤波、拟合等

一、什么是参数估计

参数通常用来表示一个量,可以是标量也可以是有值向量。按照时间变化,也可以分为时常参数时变参数。对于时常参数的估计称为参数估计。对于时变的参数估计称为状态估计,本文不研究。参数估计的包括两个主要的模型以及四个基本估计方法,如下图所示:

贝叶斯学派和频率学派最大的不同、根上的不同,就是在于模型 y=wx+b 其中的 w 和 b 两个参数,频率学派认为参数是固定的、也就是上面的非随机模型,只要通过不停的采样、不停的观测训练,就能够估算参数 w 和 b,因为它们是固定不变的;而贝叶斯学派相反,他们认为这些参数是变量,它们是服从一定的分布的,也就是上面的随机模型,这是它最根本的差别。通常上面两种也被称为点估计和区间估计。

滤波估计的发展:最小二乘、维纳(wiener)滤波、卡尔曼(kalman)滤波、鲁棒滤波、粒子滤波。

二、四种基本的估计方法

来自《雷达数据处理及应用》
2.1 最大似然估计

2.2 最小二乘估计

2.3 最大后验估计

2.4 最小均方误差估计

三、最大似然估计和最小二乘估计的对比

当模型是高斯分布时,最大似然估计和最小二乘估计是等价的。

四、基础知识

均方误差,MSE(mean squared error),是预测值与真实值之差的平方和的平均值,即:

在这里插入图片描述

均方误差可用来作为衡量预测结果的一个指标

均方差,也叫标准差(Standard Deviation),是方差的算术平方根。而方差是样本实际值与实际值的总体平均值之差的平方和的平均值。

方差: 在这里插入图片描述

均方差: 在这里插入图片描述

五、卡尔曼滤波

简单来说,卡尔曼滤波器是一个“optimal recursive data processing algorithm(最优化自回归数据处理算法)”。卡尔曼滤波的本质是参数化的贝叶斯模型,通过对下一时刻系统的初步状态估计(即状态的先验估计)以及测量得出的反馈相结合,最终得到改时刻较为准确的的状态估计(即状态的后验估计),其核心思想即为预测+测量反馈,而这两者是通过一个变化的权值相联系使得最后的状态后验估计无限逼近系统准确的状态真值,这个权值即为大名鼎鼎的卡尔曼增益。可以说,卡尔曼滤波并不与传统的在频域的滤波相似,而是一种在时域的状态预测器,这就省去了时域频域的变换的步骤,而这种状态预测器不仅仅在工程上有很广的应用,在金融方面例如股票的走势等等方面也可以有很多的应用。

卡尔曼滤波(KF)与扩展卡尔曼滤波(EKF)的一种理解思路及相应推导(1)

例子:


上面的例子我真没对应上,还看了下面的例子才理解了的(含程序)。
非线性最小二乘和卡尔曼滤波拟合直线对比

#include "ceres/ceres.h"
#include <opencv2/core/core.hpp>
#include<opencv2/opencv.hpp>
using namespace std;
int main(int argc, char** argv)
{
  double a=1.0, b=0.0;         // 真实参数值
  int N=100;                          // 数据点
  double w_sigma=0.1;                 // 噪声Sigma值
  cv::RNG rng;                        // OpenCV随机数产生器
  double ab[1] = {0};            // abc参数的估计值

  vector<double> x_data, y_data;      // 数据
  cout<<"generating data: "<<endl;
  for ( int i=0; i<N; i++ )
  {
      double x = i/100.0;
      x_data.push_back ( x );
      y_data.push_back (a*x + b + rng.gaussian ( w_sigma ));
     // cout<<x_data[i]<<" "<<y_data[i]<<endl;
  }
  // Build the problem.
 double x_hat=0.01;
 double x_bar=0.01;
 double u_k=0;

 double P_bar=0;
 double P_hat=0;
 double R=w_sigma;
 double Q=w_sigma;

 double F=1;
 double H=x_bar;
 double K=0;
 for ( int i=0; i<N; i++ )
 {
     //1.predict
     x_bar=F*x_hat+u_k;
     P_bar=F*P_hat*F+R;
     //2.update
     H=x_bar;
     K=P_bar*H/(H*P_bar*H+Q);
     x_hat=x_bar+K*(y_data[i]-H*x_data[i]);
     P_hat=(1-K*H)*P_bar;
     std::cout<<"res_k"<<x_hat<<std::endl;
 }
 return 0;
}

目前,卡尔曼滤波已经有很多不同的实现.卡尔曼最初提出的形式现在一般称为简单卡尔曼滤波器。除此以外,还有施密特扩展滤波器、信息滤波器以及很多Bierman, Thornton 开发的平方根滤波器的变种。也许最常见的卡尔曼滤波器是锁相环,它在收音机、计算机和几乎任何视频或通讯设备中广泛存在。
  对传统卡尔曼滤波的改进算法:平方根滤波、UD分解滤波、奇异值分解滤波、H鲁棒滤波、联邦滤波等。

六、改进卡尔曼滤波

作为线性的解码器,Kalman Filter确实能找到观测变量和测量变量之间的关系,并用观测变量去纠正当前测量变量中的误差。但是涉及到非线性关系的时候,Kalman Filter的线性假设就不成立了。这时有两种优化的方法:

1、如果已知这种非线性关系的公式,例如加速度和位置的关系等,那么可以把上述转换模型和观测模型换成已知的非线性模型,增加解码准确率。这种方法就是扩展卡尔曼滤波(Extend Kalman Filter)。这种方法的优点在于拟合更加准确,但是缺点也很明显。首先是计算量增加,如果非线性拟合涉及很复杂的模型,那么计算量比Kalman Filter增加很多。然后是非线性模型,并不是任何时候,这种模型都是已知的,如果不是已知的,那就需要进行非线性拟合,找到最合适的拟合模型,例如指数模型,高阶模型等,再次增加计算量。
2、如果不知道这种非线性关系的公式,那么我们可以进行非线性拟合或者直接假设一个公式。但是我们观察Kalman Filter的计算过程,整个估计过程中,用到了当前时刻的值,以及协方差。而这两个量,我们是能通过采样的方式得到的,即,可以不需要直接计算非线性模型的协方差矩阵,直接通过采样估计,类似蒙特卡洛的方法。但是采样的计算量会更大,因为需要大样本才能得到准确的估计。目前有另外一种办法,能够用很少的采样点(几个)就得到准确的估计,这种方法是无迹变换(Unscented Transform),结合到Kalman Filter中,就是无迹卡尔曼滤波(Unscented Kalman Filter)。

无迹卡尔曼滤波(Unscented Kalman Filter)。无迹卡尔曼滤波是对卡尔曼滤波的一种改进。这种改进主要是针对非线性的信号。因为在卡尔曼滤波中,预测模型以及测量空间对应的转换矩阵都是都是线性转换。但是在面对非线性信号时,会出现无法拟合的情况。所以就有了无迹卡尔曼滤波。这种方法的主要改进在于,不再用线性的模型去计算预测模型以及转换矩阵,而是通过采样和计算均值方法的方式,去估计样本的方差和均值。

参考文献

卡尔曼滤波系列——(一)标准卡尔曼滤波
卡尔曼滤波系列——(二)扩展卡尔曼滤波
卡尔曼滤波系列——(三)粒子滤波
卡尔曼滤波系列——(四)无损卡尔曼滤波
卡尔曼滤波系列——(五)奇异值鲁棒的卡尔曼滤波算法
卡尔曼滤波系列——(六)卡尔曼平滑

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MATLAB中的卡尔曼滤波可以用于估计线性或非线性系统状态的最优值,也可以用于拟合曲线。下面是一个使用卡尔曼滤波进行曲线拟合的示例代码: ```matlab % 生成模拟数据 t = 0:0.1:10; y = sin(t) + randn(size(t))*0.1; % 初始化状态量和协方差矩阵 x = [y(1); 0]; % 初始状态为 y(1),速度为 0 P = eye(2); % 定义状态转移矩阵和测量矩阵 A = [1, 0.1; 0, 1]; % 状态转移矩阵 H = [1, 0]; % 测量矩阵 % 定义过程噪声和测量噪声的协方差矩阵 Q = [0.01, 0; 0, 0.1]; % 过程噪声的协方差矩阵 R = 0.1; % 测量噪声的协方差矩阵 % 使用卡尔曼滤波拟合曲线 for i = 2:length(t) % 预测状态量和协方差矩阵 x_pred = A * x(:,i-1); P_pred = A * P * A' + Q; % 计算卡尔曼增益 K = P_pred * H' / (H * P_pred * H' + R); % 更新状态量和协方差矩阵 x(:,i) = x_pred + K * (y(i) - H * x_pred); P = (eye(2) - K * H) * P_pred; end % 绘制原始数据和拟合曲线 plot(t, y, '.', t, x(1,:), '-'); legend('原始数据', '拟合曲线'); ``` 这段代码中,我们使用了一些卡尔曼滤波的基本概念,如状态转移矩阵、测量矩阵、过程噪声、测量噪声、卡尔曼增益等。具体来说,我们将数据看作一维的状态量,包括当前位置和速度两个变量。然后我们定义了状态转移矩阵 `A`,它描述了系统在每次迭代中如何从当前状态到达下一个状态。我们还定义了测量矩阵 `H`,它将状态量映射到实际测量值上。过程噪声 `Q` 和测量噪声 `R` 描述了系统中存在的不确定性。 在代码中,我们首先初始化了状态量 `x` 和协方差矩阵 `P`。然后,我们使用卡尔曼滤波算法进行迭代,在每次迭代中使用当前状态量和协方差矩阵来预测下一个状态,并使用实际测量值来更新状态量和协方差矩阵。 最后,我们将拟合曲线绘制出来,与原始数据进行比较。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值