特徵工程:利用卡爾曼濾波器處理時間序列(快速入門+python實現)

卡爾曼濾波器

  • 英文kalman filter
  • 這裏介紹簡單的,只有一個狀態的濾波器
  • 卡爾曼濾波器經常用在控制系統中、機器人系統中,但是這裏主要講解如何用在AI的大數據分析預測中

爲什麼要用kalman filter處理時間序列

假設我們有100個時間點的數據,這個數據就是分別在100個點觀測出來的結果。

對於每一個時間點的數據,獲取的方法有兩個:

  • 第一個就是觀測,但是測量的結果不一定準確,可能受限於測量儀器的精度?
  • 第二個就是用這個時間點之前的所有數據,預測這個時間點的數據,當然,這個預測值也是不準的。
  • 可否利用這兩種方法,相互促進,預測的值更準,或者說讓觀測道德值更接近本質?Kalman Filter卡爾曼濾波器就這樣做的。

簡單講講kalman filter的過程

每一個觀測數據,嚴謹的說都應該會有一個偏差值。比方說,現在溫度計測量是26度,偏差值是0.5度,那麼真實的問題應該是在(25.5,26.5)之間,或者寫成26±0.526\pm0.5

這樣我們預測的值,和觀測的值,再加上這兩個各自的偏差,總共四個已知信息,來推測真實的、更本質的數據。

  • 預測的值:可以通過事先設定的公式,上一個時刻的真實的值算出來;
  • 觀測的值:直接讀取測量儀器的值。
  • 觀測的值的偏差:這個也是可以直接得到的;
  • 預測的值的偏差:這個是從上一個時間點的預測的值的偏差經過給定公式計算出來的。

下面的公式中,腳標k表示時間點,k-1是上一個時間點。大寫字母A,B,C表示常數,事先設定的;大寫字母H,是一個需要計算的。

  • 預測的值:xk=Axk1+Buk1x^{預測}_k=A*x_{k-1}^{真實}+B*u_{k-1}
  • 觀測的值:xkx^{觀測}_k
  • 觀測的值的偏差:pkp^{觀測}_k
  • 預測的值的偏差:pk=1Hpk1p^{預測}_k = \sqrt{(1-H)*p^{預測}_{k-1}}
  • kalman增益H:Hk=(pk)2(pk)2+(pk)2H_k=\frac{(p^{預測}_k)^2}{(p^{預測}_k)^2+(p^{觀測}_k)^2}
  • 真實的值:xk=Hkxk+1Hkxkx^{真實}_k=H_k*x^{觀測}_k+(1-H_k)*x^{預測}_k
    可以看出,這個kalman增益就是一個加權平均的權重,是觀測值更重要還是預測值更重要;兩者的重要性就由兩者的偏差大小決定,偏差小的更重要。

其中uk1u_{k-1}表示上一個時間點的控制信號,比方說一個機器人,機器人的狀態去覺得機器人自身的行爲,但是很多情況這個控制信號是不用考慮的。比方對股市的時間序列做kalman濾波,那麼並沒有什麼控制信號去控制,只是任由其自由發展。


舉一個例子,房間的溫度的例子:
總共有三個時刻,上午、下午和晚上(實際的話,時間點間隔應該會很短,這裏只是舉例),上午溫度是觀測值是23度,偏差是0.5,因爲上午是第一個時間點,所以沒有預測值;
下午,假設A=1,B=0,所以下午的預測值是23度,然後假設初始偏差時1;下午的觀測值是25度,觀測值的偏差時0.5,所以可以計算得到kalman增益H=1212+0.52=0.8H=\frac{1^2}{1^2+0.5^2}=0.8,所以下午的真實值是:0.825+10.823=24.60.8*25+(1-0.8)*23=24.6
晚上,晚上的預測值就是上一時刻的真實值,所以是24.6,偏差是(10.8)1=0.4472\sqrt{(1-0.8)*1}=0.4472;晚上的觀測值是20度,然後偏差時0.5,所以kalman增益增益H=0.447220.44722+0.52=0.4444H=\frac{0.4472^2}{0.4472^2+0.5^2}=0.4444,所以這個時刻的真實值是:0.444420+(10.4444)24.6=22.560.4444*20+(1-0.4444)*24.6=22.56

最後總結一下,其實我們只需要什麼呢?需要知道觀測的誤差是0.5,然後三個時間點的觀測數據:[23,25,20],然後用kalman濾波器之後,就變成[23,24,6,22,56]。其實起到了一個平滑的作用。

python怎麼實現呢?

from pykalman import KalmanFilter

def Kalman1D(observations,damping=1):
    # To return the smoothed time series data
    observation_covariance = damping
    initial_value_guess = observations[0]
    transition_matrix = 1
    transition_covariance = 0.1
    initial_value_guess
    kf = KalmanFilter(
            initial_state_mean=initial_value_guess,
            initial_state_covariance=observation_covariance,
            observation_covariance=observation_covariance,
            transition_covariance=transition_covariance,
            transition_matrices=transition_matrix
        )
    pred_state, state_cov = kf.smooth(observations)
    return pred_state

這裏面使用的是pykalman庫中的KalmanFilter,因爲上面講解的Kalman Filter是簡化的,繞靠了正統的解釋的正態分佈的知識,所以這裏的卡爾曼濾波器的參數可能無法與上面給出的卡爾曼公式中一一對應,會產生一定的脫節。

這裏講一下參數:

  • initial_state_mean和initial_state_covariance:在上面的公式中,一開始的初始值,就是第一個觀測值,但是在這個方法中,初始值並不是第一個觀測值,而是由一個正態分佈中隨機採樣出來的一個值,這個正太分佈就是以initial_state_mean爲均值,以initial_state_covariance爲方差的;
  • observation_covariance這個可以相當於觀測偏差;
  • transition_covariance這個就是預測偏差;
  • transition_matrices就是上面公式中的大寫字母A,爲1。

運行結果

從上面的那個函數中,可以看到transition_covariance是0.1,也就是預測偏差時0.1,所以假設觀測偏差很小,那麼可以想象,濾波器後的結果應該與觀測值非常接近,這裏選取觀測偏差爲0.001:
在這裏插入圖片描述
然後假設觀測誤差很大,那麼可以想想,平滑的力度會很大,結果就是:
在這裏插入圖片描述
最後看一下在某次比賽中的利用kalman濾波器來平滑數據的前後對比圖:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章