來源: AI全球動態(tài)
簡介 這篇文章主要介紹了必看!最簡單的Python時(shí)間序列預(yù)測模型以及相關(guān)的經(jīng)驗(yàn)技巧,文章約10533字,瀏覽量554,點(diǎn)贊數(shù)9,值得推薦!
獲得數(shù)據(jù)
芝加哥期權(quán)交易所波動率指數(shù)(CBOE Volatility Index,簡稱VIX)是衡量標(biāo)普500指數(shù)期權(quán)隱含的股市波動預(yù)期的常用指標(biāo),它是由芝加哥期權(quán)交易所(CBOE)實(shí)時(shí)計(jì)算和傳播的。
本文設(shè)置的標(biāo)普500指數(shù)(SP500)日期范圍是從2011年2月11日到2019年2月11日。我們的目的是使用ANN和LSTM預(yù)測波動性標(biāo)普500指數(shù)時(shí)間序列。
首先,我們需要導(dǎo)入以下內(nèi)容到庫:
import pandas as pd import numpy as np %matplotlib inline import matplotlib.pyplot as plt from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import r2_score from keras.models import Sequential from keras.layers import Dense from keras.callbacks import EarlyStopping from keras.optimizers import Adam from keras.layers import LSTM
然后,將數(shù)據(jù)加載到Pandas數(shù)據(jù)幀中:
df = pd.read_csv("vix_2011_2019.csv")
我們可以快速瀏覽一下前幾行,
print(df.head())
接下來,我們刪除不需要的列,然后將“日期”列轉(zhuǎn)換為datatime數(shù)據(jù)類型,并將“日期”列設(shè)置為索引。
df.drop(['Open', 'High', 'Low', 'Close', 'Volume'], axis=1, inplace=True) df['Date'] = pd.to_datetime(df['Date']) df = df.set_index(['Date'], drop=True) df.head(10)
以上步驟
完成后,我們再來繪制一張時(shí)間序列線圖。
plt.figure(figsize=(10, 6)) df['Adj Close'].plot();
可以看出,“Adj Close”數(shù)據(jù)非常不穩(wěn)定,既沒有上升趨勢也沒有下降趨勢。
接下來,以“2018-01-01”為分界將數(shù)據(jù)拆分訓(xùn)練和測試數(shù)據(jù)。也就是說,此日期之前的數(shù)據(jù)是訓(xùn)練數(shù)據(jù),之后的數(shù)據(jù)是測試數(shù)據(jù),然后再次對其進(jìn)行可視化。
split_date = pd.Timestamp('2018-01-01') df = df['Adj Close'] train = df.loc[:split_date] test = df.loc[split_date:] plt.figure(figsize=(10, 6)) ax = train.plot() test.plot(ax=ax) plt.legend(['train', 'test']);
然后將訓(xùn)練和測試數(shù)據(jù)擴(kuò)展到[- 1,1]。
scaler = MinMaxScaler(feature_range=(-1, 1)) train_sc = scaler.fit_transform(train) test_sc = scaler.transform(test)
最后,獲取訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)。
X_train = train_sc[:-1] y_train = train_sc[1:] X_test = test_sc[:-1] y_test = test_sc[1:]
創(chuàng)建用于時(shí)間序列預(yù)測的簡單ANN
創(chuàng)建一個(gè)順序模型。。
通過Add()方法添加層。
將input_dim參數(shù)傳遞給第一層。
經(jīng)過整流線性單元Relu激活函數(shù)。
通過compile語法配置學(xué)習(xí)過程。
損失函數(shù)是mean_squared_error,而優(yōu)化器是adam。
當(dāng)監(jiān)測到損失不再提高時(shí),停止訓(xùn)練。
patience=2表示沒有改善空間,之后將停止訓(xùn)練。
ANN被訓(xùn)練100個(gè)周期,使用的批量大小為1。
nn_model = Sequential() nn_model.add(Dense(12, input_dim=1, activation='relu')) nn_model.add(Dense(1)) nn_model.compile(loss='mean_squared_error', optimizer='adam') early_stop = EarlyStopping(monitor='loss', patience=2, verbose=1) history = nn_model.fit(X_train, y_train, epochs=100, batch_size=1, verbose=1, callbacks=[early_stop], shuffle=False)
這里沒有顯示全部輸出,但我們可以看到它在第19個(gè)周期就停止了。
y_pred_test_nn = nn_model.predict(X_test) y_train_pred_nn = nn_model.predict(X_train) print("The R2 score on the Train set is: {:0.3f}".format(r2_score(y_train, y_train_pred_nn))) print("The R2 score on the Test set is: {:0.3f}".format(r2_score(y_test, y_pred_test_nn)))
LSTM
在創(chuàng)建LSTM時(shí),我們將使用pandas中的shift函數(shù)將整列移動1.在下面的代碼片段中,我們將列向下移動1.然后我們需要將所有輸入變量轉(zhuǎn)換為以3D矢量形式表示。
train_sc_df = pd.DataFrame(train_sc, columns=['Y'], index=train.index) test_sc_df = pd.DataFrame(test_sc, columns=['Y'], index=test.index) for s in range(1,2): train_sc_df['X_{}'.format(s)] = train_sc_df['Y'].shift(s) test_sc_df['X_{}'.format(s)] = test_sc_df['Y'].shift(s) X_train = train_sc_df.dropna().drop('Y', axis=1) y_train = train_sc_df.dropna().drop('X_1', axis=1) X_test = test_sc_df.dropna().drop('Y', axis=1) y_test = test_sc_df.dropna().drop('X_1', axis=1) X_train = X_train.as_matrix() y_train = y_train.as_matrix() X_test = X_test.as_matrix() y_test = y_test.as_matrix() X_train_lmse = X_train.reshape(X_train.shape[0], X_train.shape[1], 1) X_test_lmse = X_test.reshape(X_test.shape[0], X_test.shape[1], 1) print('Train shape: ', X_train_lmse.shape) print('Test shape: ', X_test_lmse.shape)
LSTM網(wǎng)絡(luò)的創(chuàng)建和模型編譯與ANN的類似。
LSTM具有帶有1個(gè)輸入的可見層。
一個(gè)含有7個(gè)LSTM神經(jīng)元的隱藏層。
一個(gè)只做單值預(yù)測的輸出層。
LSTM神經(jīng)元采用relu激活函數(shù)。
LSTM經(jīng)過100個(gè)周期的訓(xùn)練,使用的批量大小為1。
lstm_model = Sequential() lstm_model.add(LSTM(7, input_shape=(1, X_train_lmse.shape[1]), activation='relu', kernel_initializer='lecun_uniform', return_sequences=False)) lstm_model.add(Dense(1)) lstm_model.compile(loss='mean_squared_error', optimizer='adam') early_stop = EarlyStopping(monitor='loss', patience=2, verbose=1) history_lstm_model = lstm_model.fit(X_train_lmse, y_train, epochs=100, batch_size=1, verbose=1, shuffle=False, callbacks=[early_stop])
如圖所示,它在第10個(gè)周期停止了。
y_pred_test_lstm = lstm_model.predict(X_test_lmse) y_train_pred_lstm = lstm_model.predict(X_train_lmse) print("The R2 score on the Train set is: {:0.3f}".format(r2_score(y_train, y_train_pred_lstm))) print("The R2 score on the Test set is: {:0.3f}".format(r2_score(y_test, y_pred_test_lstm)))
可以看出,LSTM模型的訓(xùn)練和測試R^2均優(yōu)于ANN模型。
比較模型
接下來,我們比較兩種模型的測試MSE。
nn_test_mse = nn_model.evaluate(X_test, y_test, batch_size=1) lstm_test_mse = lstm_model.evaluate(X_test_lmse, y_test, batch_size=1) print('NN: %f'%nn_test_mse) print('LSTM: %f'%lstm_test_mse)
做出預(yù)測
nn_y_pred_test = nn_model.predict(X_test) lstm_y_pred_test = lstm_model.predict(X_test_lmse) plt.figure(figsize=(10, 6)) plt.plot(y_test, label='True') plt.plot(y_pred_test_nn, label='NN') plt.title("NN's Prediction") plt.xlabel('Observation') plt.ylabel('Adj Close Scaled') plt.legend() plt.show();
plt.figure(figsize=(10, 6)) plt.plot(y_test, label='True') plt.plot(y_pred_test_lstm, label='LSTM') plt.title("LSTM's Prediction") plt.xlabel('Observation') plt.ylabel('Adj Close scaled') plt.legend() plt.show();
這樣,我們就知道了如何利用Keras深度學(xué)習(xí)網(wǎng)絡(luò),在Python中開發(fā)用于時(shí)間序列預(yù)測的ANN和LSTM模型,以及如何利用它們更好地預(yù)測時(shí)間序列數(shù)據(jù)。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。