卡爾曼預測股票(Tensorflow)

Tensorflow實現卡爾曼濾波

前言

  前幾篇文章裏的矩陣運算都是基於numpy實現的,這裏也展示的是使用python進行矩陣運算時常用的一個庫——Tensorflow。Tensorflow算是目前最火的一個三方庫,在此之前雄踞榜首的三方庫一直是JS。
在這裏插入圖片描述
  本文將使用Tensorflow實現一個Kalman預測模型,用於預測股票的變化。內核仍然採用Tensorflow實現,留給用戶的接口,仍然採用Numpy。K實現Kalman並不困難,只要寫好初始化,預測和糾正三個接口函數,用戶就能夠通過Kalman進行數據預測。Kalman在慣性系統的預測和濾波中具有重要地位。
  使用Tensorflow實現Kalman的類

import tensorflow as tf
import numpy as np
​
class KalmanFilter(object):
    def __init__(self, x=None, A=None, P=None, B=None, H=None, Q=None):
        m = self._m = H.shape[0]
        n = self._n = x.shape[0]
        l = self._l = B.shape[1]
        self._x = tf.Variable(x, dtype=tf.float32, name="x")
        self._A = tf.constant(A, dtype=tf.float32, name="A")
        self._P = tf.Variable(P, dtype=tf.float32, name="P")
        self._B = tf.constant(B, dtype=tf.float32, name="B")
        self._Q = tf.constant(Q, dtype=tf.float32, name="Q")
        self._H = tf.constant(H, dtype=tf.float32, name="H")
        self._u = tf.placeholder(dtype=tf.float32, shape=[l, 1], name="u")
        self._z = tf.placeholder(dtype=tf.float32, shape=[m, 1], name="z")
        self._R = tf.placeholder(dtype=tf.float32, shape=[m, m], name="R")def predict(self):
        x = self._x
        A = self._A
        P = self._P
        B = self._B
        Q = self._Q
        u = self._u
        x_pred = x.assign(tf.matmul(A, x) + tf.matmul(B, u))
        p_pred = P.assign(tf.matmul(A, tf.matmul(P, A, transpose_b=True)) + Q)
        return x_pred, p_pred
       
    
    def correct(self):
        x = self._x
        P = self._P
        H = self._H
        z = self._z
        R = self._R
        K = tf.matmul(P, tf.matmul(tf.transpose(H), tf.matrix_inverse(tf.matmul(H, tf.matmul(P, H, transpose_b=True)) + R)))
        x_corr = x.assign(x + tf.matmul(K, z - tf.matmul(H, x)))
        P_corr = P.assign(tf.matmul((1 - tf.matmul(K, H)), P))
        return K, x_corr, P_corr

  讀取數據並且實現它


import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import xlrd
from plugin import kalman

rnd = np.random.RandomState(0)

'''
數據讀取
'''
workbook = xlrd.open_workbook("data.xlsx")
sheet = workbook.sheet_by_name("Sheet1")

n_timesteps = 200
observations = []
x_axis = []
for i in range(1,n_timesteps+1):
    observations.append(float(sheet.cell(i,2).value))
    x_axis.append(float(i))
print(observations)
x_axis = np.array(x_axis,dtype = np.float)
observations = np.array(observations)

n = 1
m = 1
l = 1
x = np.ones([1, 1])
A = np.ones([1, 1])
B = np.zeros([1, 1])
P = np.ones([1, 1])
Q = np.array([[0.005]])
H = np.ones([1, 1])
u = np.zeros([1, 1])
R = np.array([[0.05]])
predictions = []
with tf.Session() as sess:
    kf = kalman.KalmanFilter(x=x, A=A, B=B, P=P, Q=Q, H=H)
    predict = kf.predict()
    correct = kf.correct()
    tf.global_variables_initializer().run()
    for i in range(0, n_timesteps):
        x_pred, _ = sess.run(predict, feed_dict={kf._u: u})
        predictions.append(x_pred[0, 0])
        sess.run(correct, feed_dict={kf._z:np.array([[observations[i]]]), kf._R:R})

# 支持中文t
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負號
plt.figure(figsize=(16, 6))
obs_scatter = plt.scatter(x_axis, observations, marker='x', color='b',
                         label='實際值')
position_line = plt.plot(x_axis, np.array(predictions),
                        linestyle='-', marker='o', color='r',
                        label='預測值')

plt.legend(loc='lower right')
plt.xlim(xmin=0, xmax=x_axis.max())
plt.xlabel('time')
plt.show()

  最終的預測效果
在這裏插入圖片描述
  紅色點爲預測值,藍色點爲真實值,第0個紅色點的值由用戶給出,此後的任意第N個點都是將前N-1個真實點的值作爲訓練集,然後預測得出。在驗證需要大量矩陣運算的算法時,Tensorflow會是比numpy更加方便且好用的一個庫。Tensorflow基於數據流圖實現,相比實現傳統的複雜邏輯而言,數據流圖會更好實現。矩陣運算本來就是數據的流動,採用邏輯來爲矩陣運算做出規劃,反而顯得格格不入。

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