滤波器入门-02(g-h滤波器)
回顾:在滤波器入门-01中,我们明确了几个常见名词的含义,系统、状态、测量和估计,并针对测量体重的实际案例设计了一个简单的滤波器,可以在经过几天测量数据修正后,快速跟上实际体重的变化。但是其中涉及到两个比例因子,一个是测量值与估计值残差的比例,用于更新估计值;另一个是二者变化率的比率,用于更新估计值的变化率。接下来我们将扩展此滤波器使其具备通用性,并探讨各个参数对滤波器性能的影响。The g-h filter is not one filter - it is a classification for a family of filters.
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.
首先明确下几个术语的含义:
g:反映了测量值对当前时刻估计值的影响比例,该值越大,当前时刻估计值就会越靠近测量值,偏离按照上一时刻估计的系统变化率得到的估计值. The scaling we used for the measurement (weight in our example)
h:反映了测量值对下一时刻估计值变化率的影响比例,该值越大,下一时刻估计值的变化率就越贴近测量值相对上一时刻输出估计值的变化率,越偏离实现上一时刻估计的系统变化率,The scaling for the change in measurement over time (kg/day in our example)
process model:The process model does not model or otherwise account for the sensors.在之前的例子中是新体重=旧体重*(1+体重变化率)
system error or process error:过程模型存在的一些误差,即建立的模型无法完全替代真实物理世界中的研究对象。
system propagation:使用 process model 形成的新的状态估计,由于process error 的存在,该估计并不完美。Assuming we are tracking data over time, we say we propagate the state into the future. Some texts call this the evolution.
measurement update:依据测量值对估计系统状态量的更新
epoch:One iteration of the system propagation and measurement update.
Initialization:
- Initialize the state of the filter
- Initialize our belief in the state
Predict:
- Use system behavior to predict state at the next time step
- Adjust belief to account for the uncertainty in prediction
Update:
- Get a measurement and associated belief about its accuracy
- Compute residual between estimated state and measurement
- New estimate is somewhere on the residual line
def g_h_filter(data, x0, dx, g, h, dt=1.): x_est = x0 results = [] for z in data: # prediction step x_pred = x_est + (dx*dt) dx = dx # update step residual = z - x_pred dx = dx + h * (residual) / dt x_est = x_pred + g * residual results.append(x_est) return np.array(results)
data代表测量值,x0代表初始估计,dx代表估计值的变化率,dx代表连续两个测量值之间的时间间隔,g,h如前所述,分别代表测量值对估计值和估计值变化率的影响比例。
为了验证滤波器各参数对其性能的影响,我们需要生成一组带有随机白噪声的数据,其代码如下:
from numpy.random import randn def gen_data(x0, dx, count, noise_factor): return [x0 + dx*i + randn()*noise_factor for i in range(count)]
实验一:不合适的初始条件对其性能的影响,现在编写代码,使用 gen_data 和 g_h_filter 过滤 100 个数据点,这些数据点从 5 开始,导数为 2,噪声缩放因子为 10,并使用 g=0.2 和 h=0.02。将 x 的初始猜测设置为 100。
zs = gen_data(x0=5., dx=2., count=100, noise_factor=10) data = g_h_filter(data=zs, x0=100., dx=2., dt=1., g=0.2, h=0.02)
从图中可以看出由于初始值的猜测错误,滤波器输出的估计出现了振铃效应,'Ringing' means that the signal overshoots and undershoots the data in a sinusoidal type pattern. 这是滤波器中非常常见的现象,滤波器的设计中大量工作都致力于最大限度地减少此现象。
实验二:极端噪音对其性能的影响,重新运行相同的测试,但此次生成噪音数据时系数设置为100,将初始条件修改为5来消除振铃效应。
zs = gen_data(x0=5., dx=2., count=100, noise_factor=100) data = g_h_filter(data=zs, x0=5., dx=2., g=0.2, h=0.02)
从图中可以看出尽管滤波器的输出减小了噪声的影响,但它的变化趋势依然和直线相差很远。而且似乎依然出现了局部的振铃效应。
实验三:系统中加速等非线性因素对其性能的影响,重新设计数据生成函数,添加恒定的加速因子。
def gen_data(x0, dx, count, noise_factor, accel=0.): zs = [] for i in range(count): zs.append(x0 + accel * (i**2) / 2 + dx*i + randn()*noise_factor) dx += accel return zs zs = gen_data(x0=10., dx=0., count=20, noise_factor=0, accel=9.) data = g_h_filter(data=zs, x0=10., dx=0., g=0.2, h=0.02)
从图中可以看到,每一个滤波器输出的估计值都滞后真实值。这是合理的,因为我们在建立过程模型的时候假设时匀速的,此种情况我们很难通过调整滤波器的参数改善性能。This is called the lag error or systemic error of the system.It is a fundamental property of g-h filters.The filter is only as good as the mathematical model used to express the system.
实验四:参数g 对其性能的影响,代码同实验二,调整g 参数,出图效果如下
很明显g 的值越大,估计值就更靠近测量值,也就更容易受到噪声的影响。因此我们可以得出结论,g应该设置很小以便最大限度的抑制噪声,但真实情况是这样的吗?如果测量值的变化不是由于噪声导致的,而是系统自身变化情况导致的呢?
上图我们可以看到较小的g 导致滤波器,在抑制噪声的同时过滤掉了系统真实的变化情况。
实验五:参数h 对其性能的影响,代码同实验一,调整h 参数,在无噪声时针对不同初始值的反应
从图中可以看出,较大的h 使得滤波器的输出对测量值调节更为迅速(但注意调节的速度不要超过系统变化的速度,否则依然得不到很好的效果),具体表现为,绿色和黄色的对比,h 较小时,输出调节的频率低,振铃幅度大。h 增大后,滤波器输出的估计值调节频率高,振铃幅度小,也比黄色的稍微稳定快些。
综上,Different filters choose g and h in different ways depending on the mathematical properties of the problem.There is a trade off here between responding quickly and accurately to changes in behavior and producing ideal output for when the system is in a steady state that you have.
一些调参忠告:
A filter that ignores measurements is useless.(Never set both g and h to zero).
I know you would never set both g and h to zero as that takes a special kind of genius that only I possess, but I promise that if you are not careful you will set them lower than they should be.You can always make great looking results from test data. When you try your filter on different data you will be disappointed in the results because you finely tuned the constants for a specific data set. g and h must reflect the real world behavior of the system you are filtering, not the behavior of one specific data set.
此节简单的探讨了g-h滤波器的参数对其性能的影响,接下来将学习离散贝叶斯滤波器。
学习链接:https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python