滤波器入门-01(不要丢弃信息)

回顾:在滤波器入门-00中,说明了设计滤波器的意义——在复杂多变的外部noise下,使得我们对整个系统状态有着相对准确的估计。并用几个生活中的小例子辅助理解,上一篇中的最后一句话我们的原则是不要丢弃信息-将会在此篇中更进一步的验证。Are you ready? Ok,go,来吧来吧

The fundamental idea is to blend somewhat inaccurate measurements with somewhat inaccurate models of how the systems behaves to get a filtered estimate that is better than either information source by itself.

首先明确几个名词的含义:

系统system ):the object that we want to estimate

状态state):the actual value of the system, This value is usually hidden to us. 测量值是observable

测量measurement):the measured value of the system,由于传感器存在误差,大概率与系统状态不一致

估计estimate):对state的估计

Any estimation problem consists of forming an estimate of a hidden state via observable measurements.(任何估计问题都包括通过可观察的测量形成对隐藏状态的估计)

先举个小例子热热身:

依然是称体重,不过这次我们有两个称,倒霉的是这两个称的精度都不怎么样,误差在±8kg左右(例子有点极端了,不过假设这是人类历史上第一次有这种工具,精度有待提升),然后我们分别在称A和称B上得到了自己体重的测量值为160kg,170kg。很明显对于我们的真实体重的估计值,有以下5种选择:

  1. 只相信称A,将160kg作为我们体重的估计值
  2. 只相信称B,将170kg作为我们体重的估计值
  3. 在160-170kg之间选一个值
  4. 选一个大于2者的值
  5. 选一个小于2者的值

1,2的选择相比4,5来说是更合理的,但是我们没有理由更偏爱单独一个称得到的测量值。Why would we choose to believe A instead of B?We have no reason for such a belief. 因此3是唯一合理的选择,这个概念在数学上被形式化为期望值。

此时可能有的人会想到,万一两个称测量得到的体重刚好都低于或高于我们真实的体重呢?

确实,在多次测量中两个称的读数在数轴上有可能落到真实值的同一侧,也可能真实值位于二者之间。对于前者,3的选择至少可以帮助我们减轻最差测量的影响,对于后者3的选择则是理所当然的。We will deal with this more formally later, but for now I hope it is clear that our best estimate is the average of A and B.

对于两个相同精度的称,可视化某两次测量值和对应精度范围如下图所示:

在上面这种图中我们还无法获得更好的重量估计,有用的信息就是两条误差线之间的交集162-168kg是我们真实体重所在的范围。它比使用单一的一个称来说减少了误差的范围。

对于两个不同精度的称(假设称A精度提高3倍),情况就变得更好玩了,可视化某两次测量值和对应精度范围如下图所示:

从上图我们可以明显看出,我们体重只能是161kg。尽管依靠两个相对不准确的传感器,我们依然可以推断出极其准确的结果。

So two sensors, even if one is less accurate than the other, is better than one.We never throw information away, no matter how poor it is.This insight of using all measurements regardless of accuracy will play a large role later, so don't forget it.

实际生活中,一般人也不会买两个称对比称,我们更可能是买一个称每天称。每次测量得到的值和误差线,对应上面提到的两个精度一致的称的情况。不过上面的讨论我们忽略了传感器自身的特性,即测量值更可能是靠近真实值的值,与真实值偏离越远的值测量得到概率越小,这一点将在此后讨论。

先来看一组3天的测量数据吧,绿色虚线表示在此组测量下我们体重的几种变化情况,实际上有无数种情况。

那么哪一种才是最符合真实的变化情况呢?

The behavior of the physical system we are measuring should influence how we interpret the measurements.

目前我们讨论的是人的体重,常人在没有截肢身体正常的情况下,自身体重短时间内不会有很大的波动。而对于一个靠雨水补给的蓄水池将可能会有较大的波动,对于一块石头则完全可以归结为噪声的影响。

让我们再看一组数据,158.0, 164.2, 160.3, 159.9, 162.1, 164.6, 169.6, 167.4, 166.4, 171.0。

首先假设体重没有变化,对所有量取平均后可视化自身体重变化趋势如下:

很明显,这个假设不太有说服力,至少在此组测量数据上的所有误差线内,我们没有可以绘制的水平线。

使用最小二乘法拟合出来一条趋势线,可视化如下:

看起来合理多了,至少每天的估计值和测量值之间的误差之和最小。但这是我们自身体重的真实变化趋势吗?

现在我们可以假设自己的体重每天大约增加1kg,初始体重为158kg,接下来探讨另一种估计自身体重的方法。

此时我们再次测量得到自身的体重为164.2kg,很明显,该测量值和我们预测值存在较大差异,这也是我们所希望的,因为如果测量值和预测值完全一致,那么我们将无法向滤波器添加任何信息,因为只靠预测就可以了,不需要测量。

So what do we do?

If we only form estimates from the measurement then the prediction will not affect the result.If we only form estimates from the prediction then the measurement will be ignore.If this is to work we need to take some kind of blend of the prediction and measurement.

混合测量值和估计值,听起来和刚才两个称的问题有点类似。确实,此刻只不过是将基于人体生理特征得到的预测值替换了称B得到的测量值,对于数学来说这两个值没什么区别。One more time, this is so important. 当出现两个有误差的值时,我们应该在二者之间形成一个估计值。

对比前文,此刻我们更相信自身预测值的准确性,同理,尝试随机选择一个比例0.4用来计算我们的估计值,

estimate=prediction+0.4*(measurementprediction)

测量值和预测值之间的差值称为残差,由图中的黑色垂直线表示。它是测量值与滤波器输出之间差异的精确度量,残差越小,性能越好。

体重预测值和更新值的计算公式,如下代码所示

weights = [158.0, 164.2, 160.3, 159.9, 162.1, 164.6, 
           169.6, 167.4, 166.4, 171.0, 171.2, 172.6]

time_step = 1.0  # day
scale_factor = 4.0/10
initial_estimate = 160.

def predict_using_gain_guess(estimated_weight=initial_estimate, gain_rategain_rate=1):     
    # storage for the filtered results
    estimates, predictions = [estimated_weight], []

    # most filter literature uses 'z' for measurements
    for z in weights: 
        # predict new position
        predicted_weight = estimated_weight + gain_rate * time_step

        # update filter 
        estimated_weight = predicted_weight + scale_factor * (z - predicted_weight)
	return estimates, predictions

将滤波输出结果可视化如下所示:

从图中不难看出随着时间的推移,滤波器输出的估计值似乎越来越贴合此前我们最小二乘拟合得到变化趋势,而且其数据变化趋势相比测量值也更加有规律。

但当我们的对自身体重变化趋势估计错的时候,会发生什么呢?将gain_rategain_rate设置为-1,即每天减少1kg,可视化滤波器输出如下:

结果很明显不是很好,估计值很快就偏离了测量值,这说明这个滤波器的准确性非常依靠我们猜测变化率的准确度,即使最初的变化率猜测的是对的,一旦发生变化,滤波器也会失效。但是,从图中可以看出它正在调整,即使初始估计每天将减少1kg,输出的估计值依然在攀升!只是调整的不够快。

那么,如果我们将初始的体重变化率实时更新呢,即根据当前时刻的测量值和估计值变化率的残差来更新它,情况会变得怎么样呢?

这种想法是很有道理的,毕竟当前时刻测量值源于我们的真实体重,而当前时刻的估计值则是基于数据对我们真实体重的最优估计,利用二者变化率的残差更新最初盲目猜测的变化率无疑更加准确。Data is better than a guess, even if it is noisy.

现在我们又有了两个有差异的值,初始猜测的变化率(或者是基于估计得到的变化率)与基于测量得到的变化率

同样的思路,这次我们选择1/3作为二者差异的比例,新的变化率计算公式如下:

new gain=old gain+1/3*((measurement - predicted weight)/1 day)

weight = 160.  # initial guess
gain_rate = -1.0  # initial guess

time_step = 1.
weight_scale = 4./10
gain_scale = 1./3
estimates = [weight]
predictions = []

for z in weights:
    # prediction step
    weight = weight + gain_rate*time_step
    gain_rate = gain_rate
    predictions.append(weight)
    
    # update step    
    residual = z - weight
    
    gain_rate = gain_rate + gain_scale   * (residual/time_step)
    weight    = weight    + weight_scale * residual
  
    estimates.append(weight)

在上述代码的第13行,貌似没有意义,可以删去。确实,但在预测步骤中我们理应对所有变量的下一个值进行预测(在此场景中包括变化率和体重),此时我们暂时仅考虑体重的变化,但当算法推广时应该注意。

按照更新后的公式,滤波器输出的估计值如下图所示:

从图中不难看出,即使初始对自身体重的变化趋势估计不准确,但只需要经过几天测量值的调整,该过滤器输出的估计值就可以准确的反应体重的变化趋势。但是,0.4和1/3的比例因子,需要我们人为设置,除此之外其他的运算都遵循合理的假设。下节将推广本节提到滤波器,名为g-h滤波器,并探讨这两个比例因子对滤波器性能的影响。

学习链接:https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python

全部评论

相关推荐

点赞 1 评论
分享
牛客网
牛客企业服务