g-h濾波--卡爾曼濾波(一)

本文是對(duì)Kalman-and-Bayesian-Filters-in-Python書(shū)里內(nèi)容的概括總結(jié),原文請(qǐng)參考:
Kalman-and-Bayesian-Filters-in-Python

一. 數(shù)據(jù)的取值

我們現(xiàn)在有兩臺(tái)體重秤A和B,但體重秤每次的測(cè)量都是不準(zhǔn)確的,假設(shè)兩次測(cè)量的體重分別為160和170斤,我該怎么選取體重值呢?

  • 相信第一次的值160
  • 相信第二次的值170
  • 選一個(gè)值比兩個(gè)值都大
  • 選一個(gè)值比兩個(gè)都小
  • 選一個(gè)值在兩者之間

前兩個(gè)選擇是可以的,但我們沒(méi)有理由偏向于一個(gè)。為什么我們選擇相信A而不是B?我們沒(méi)有理由相信這一點(diǎn)。第三和第四選擇是不合理的,體重秤當(dāng)然不是很準(zhǔn)確,但是根本沒(méi)有理由選擇超出兩者均測(cè)量范圍的數(shù)字。最后的選擇是唯一合理的選擇。如果兩個(gè)刻度都不正確,并且結(jié)果可能超過(guò)我的實(shí)際體重,也可能低于我的實(shí)際體重,那么答案通常是在A和B之間。

假設(shè)我們的兩臺(tái)體重秤有它各自的誤差范圍,A的誤差范圍是3,B的誤差范圍是9,如下圖所示:


圖1

我們的直覺(jué)告訴我們,選擇兩者重疊的部分是更合理的。兩臺(tái)傳感器,即使其中的一臺(tái)精確度不如另一臺(tái),兩臺(tái)也能提供更可靠的數(shù)據(jù)。我們不應(yīng)該丟棄任何數(shù)據(jù)?。?!

如果我只有一個(gè)體重秤,但可以多次稱重自己該怎么辦? 我們得出的結(jié)論是,如果我們有兩個(gè)精度相等的量表,則應(yīng)平均其測(cè)量結(jié)果。 如果我用一個(gè)秤稱量自己10,000次會(huì)怎樣? 我們會(huì)得到一個(gè)既不會(huì)太大也不會(huì)太小的數(shù)據(jù)。 不難證明大量權(quán)重的平均值將非常接近實(shí)際權(quán)重。就像下圖這樣:


圖2

我們?nèi)〉玫闹悼雌饋?lái)不錯(cuò),使用均值是合理的。

二. g-h模型

假設(shè)我們每隔一天使用這臺(tái)體重秤測(cè)試一次自己的體重,如果得到的數(shù)據(jù)是158.0, 164.2, 160.3, 159.9, 162.1, 164.6, 169.6, 167.4, 166.4, 171.0 。這些數(shù)據(jù)參差不齊,是測(cè)量的誤差嗎?但這些數(shù)字看起來(lái)又好像在增加,我們先采用平均值的方式,如下圖


圖3

使用平均值不合理,實(shí)際上我們不能畫(huà)一條水平線在所有測(cè)量的誤差內(nèi)。
現(xiàn)在我們假設(shè)體重一直在增加,通過(guò)工具,采用最小二乘法畫(huà)一條線,如圖:


圖4

這條線看起來(lái)好多了,覆蓋了所有測(cè)量,更合理。但事實(shí)一定是這樣嗎?我就不能一周增加13斤(最小值158,最大值171)?這可能嗎?

假設(shè)我們就認(rèn)為我每天增加1斤的體重(濾波器模型),第一次測(cè)量158,那么第二天我的體重就是159,讓我們看看體重秤的第二次讀數(shù)164.2。我們遇到了一個(gè)問(wèn)題,我們的預(yù)測(cè)和我們的測(cè)量不一致。 但是,這就是我們所期望的, 如果預(yù)測(cè)始終與測(cè)量完全相同,則它將無(wú)法向過(guò)濾器添加任何信息。 同樣,由于我們的預(yù)測(cè)是完美的,因此沒(méi)有理由進(jìn)行測(cè)量。我們需要將預(yù)測(cè)和測(cè)量以某種方式混合。

混合兩個(gè)值-聽(tīng)起來(lái)很像前面的兩個(gè)體重秤的問(wèn)題。我們不要丟棄任何信息,預(yù)測(cè)值和測(cè)量值都不能丟棄。使用與以前相同的推理,我們可以看到,唯一有意義的是在預(yù)測(cè)和測(cè)量之間選擇一個(gè)數(shù)字。估計(jì)值要介于測(cè)量和預(yù)測(cè)之間嗎?也許可以,總的來(lái)說(shuō),我們的預(yù)測(cè)值比測(cè)量值或多或少是準(zhǔn)確的(因?yàn)檎w趨勢(shì)上是上升的)。我們假設(shè)估計(jì)值是這樣取得的:

estimate = prediction + 4/10 x (measurement - prediction)

我們使預(yù)測(cè)模型的初始值為160,編碼如下:

from kf_book.book_plots import figsize
import matplotlib.pyplot as plt

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

def predict_using_gain_guess(estimated_weight, gain_rate, do_print=False):     
    # 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)

        # save and log
        estimates.append(estimated_weight)
        predictions.append(predicted_weight)
        if do_print:
            gh.print_results(estimates, predicted_weight, estimated_weight)

    return estimates, predictions

initial_estimate = 160.
estimates, predictions = predict_using_gain_guess(
    estimated_weight=initial_estimate, gain_rate=1, do_print=True)

執(zhí)行輸出得到

previous estimate: 160.00, prediction: 161.00, estimate 159.80
previous estimate: 159.80, prediction: 160.80, estimate 162.16
previous estimate: 162.16, prediction: 163.16, estimate 162.02
previous estimate: 162.02, prediction: 163.02, estimate 161.77
previous estimate: 161.77, prediction: 162.77, estimate 162.50
previous estimate: 162.50, prediction: 163.50, estimate 163.94
previous estimate: 163.94, prediction: 164.94, estimate 166.80
previous estimate: 166.80, prediction: 167.80, estimate 167.64
previous estimate: 167.64, prediction: 168.64, estimate 167.75
previous estimate: 167.75, prediction: 168.75, estimate 169.65
previous estimate: 169.65, prediction: 170.65, estimate 170.87
previous estimate: 170.87, prediction: 171.87, estimate 172.16

每次用估計(jì)的值進(jìn)行預(yù)測(cè),然后將預(yù)測(cè)的值與測(cè)量值按比例混合,得到新的估計(jì)值,不斷的迭代。請(qǐng)仔細(xì)查看代碼,確保清楚每一個(gè)值的計(jì)算過(guò)程。

我們將數(shù)據(jù)打印到圖表中,如下:


圖5

我們藍(lán)色曲線模擬的效果非常好,它比單一的測(cè)量和預(yù)測(cè)值都更符合實(shí)際。也許我們的預(yù)測(cè)模型剛好符合實(shí)際,那如果我們的預(yù)測(cè)模型是每天減少1斤呢?

e, p = predict_using_gain_guess(initial_estimate, -1.)
#打印
gh.plot_gh_results(weights, estimates, predictions, [160, 172]) 

如下圖所示:

圖6

濾波器沒(méi)有上次好,但是!濾波器在調(diào)整自己,只不過(guò)調(diào)整的速度有點(diǎn)慢。如果體重的增加或者減少也是從預(yù)測(cè)和測(cè)量中計(jì)算出來(lái)呢?我么現(xiàn)在第二天的預(yù)測(cè)值是
(160+1)+4 /10*(158-161) = 159.8
我們的測(cè)量值是164.2,增加了4.4(164.2-159.8=4.4)而不是1,我么是否可以利用這個(gè)信息呢? 我們不要丟棄任何信息,我們得預(yù)測(cè)的增量是1,而測(cè)量增量是4.4,我們是否可以混合這兩個(gè)值?這和前面的問(wèn)題是一樣的。我們假設(shè)增加值是這樣的:

new gain = old gain + 1/3 (measurement - predicted) / 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)
gh.plot_gh_results(weights, estimates, predictions, [160, 172])

打印數(shù)據(jù)如下:

圖7

Great! 這就是g-h濾波器 (這里4/10就是g, 3/10就是h)

該濾波器是包括Kalman濾波器在內(nèi)的眾多濾波器的基礎(chǔ)。換句話說(shuō),卡爾曼濾波器是g-h濾波器的一種形式??偨Y(jié)一下該算法(這里采用原文):

Initialization

  1. Initialize the state of the filter
  2. Initialize our belief in the state

Predict

  1. Use system behavior to predict state at the next time step
  2. Adjust belief to account for the uncertainty in prediction

Update

  1. Get a measurement and associated belief about its accuracy
  2. Compute residual between estimated state and measurement
  3. New estimate is somewhere on the residual line
圖8

三. g,h的選擇

g的取值代表我們對(duì)預(yù)測(cè)和測(cè)量的信任程度。


圖9

g越大濾波器更靠近測(cè)量值,越小越靠近預(yù)測(cè)值。

h反應(yīng)的是濾波器的變化速度,這里不詳細(xì)講述,請(qǐng)參考原文。


圖10

實(shí)際應(yīng)用中對(duì)g和h的選擇具體分析,這里不做討論,相關(guān)請(qǐng)查看原文,重在理解g-h濾波模型的思想。

本節(jié)講述了g-h濾波,是大部分濾波的核心思想,通過(guò)不斷的在模型基礎(chǔ)上預(yù)測(cè)和測(cè)量而得到估計(jì)值,筆者認(rèn)為,濾波器的本質(zhì)是得到可能的值,某一時(shí)刻的真實(shí)值是不知道的,但我們對(duì)濾波器的估計(jì)值有很高的信任度,就像文章開(kāi)頭我們使用兩次測(cè)量的中間值一樣。

實(shí)際的應(yīng)用中單點(diǎn)的真實(shí)值意義不大,估計(jì)值很多情況能滿足我們的需求。最后,不要丟棄任何數(shù)據(jù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容