Tensorflow LMST預測股票

這個是我一直想做的。
其實去年我就開始學習了,可惜意志力不堅定。學理論總是學不完。
TS的demo,我其實都跑了蠻多遍了,官方文檔也是。
但是總是做到自己去預測那一步。然後最近,我改變了策略。
開始看那種偏向於實戰性的視頻。
強烈推薦 北大的ts筆記
棒呆了。完美符合我的預期。
本來是我是去啃youtube的版本的。不過這個,真的是棒呆了。
基礎理論雖然很多不懂,但是大致的思路出來了。

--------我是有趣的分割線--------------------------------------

其實TS做預測。真能賺錢嗎?講道理賺錢是很難的。因爲自己在做的過程中,是知道其中其實是數學公司推倒。畢竟以前看理論還是知道的。
其中有一個要素是
必須隱含一個公式。

但是股票預測作爲最難的層級來說,基本上做不到預測。

但是爲什麼要嘗試了。最近重讀《黑客與畫家》,已經不是大學給我的,
編程是開放,自由,民主,計算機使社會更加美好,用計算機創造美好。這些理念打動我了。

而是程序猿是一個畫家。白天打工求一份工生存。晚上做藝術創造。

所以面對非常難,甚至不可能的問題上。依舊充滿了動力。

並且雷軍大佬說“風來了,連豬都可以飛起來”。所以學習這個,萬一成了這頭豬了。哈哈哈哈。

這次代碼寫的很LOW,後續進行改進
代碼都是上面那個課程改過來的。當然其實你去看TS官方文檔也有。但是官方文檔,不會有一個特別完整的思路。

所以實名爲北大的大佬點贊。

這裏是tushare 獲取股票信息。但是記住這個接口快過期了。本來我是想替換的。
但是由於一些原因,我還在看關於卷積的問題。卷積很迷茫。所以代碼還沒調整。

import tushare as ts
import matplotlib.pyplot as plt

df1 = ts.get_k_data('000977', ktype='D', start='2019-01-01', end='2020-06-12')

datapath1 = "./000977.csv"
df1.to_csv(datapath1)

訓練模型

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dropout, Dense, LSTM
import matplotlib.pyplot as plt
import os
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
import math

maotai = pd.read_csv('./600584.csv')  # 讀取股票文件

training_set = maotai.iloc[0:350 - 60, 2:3].values  # 前(2426-300=2126)天的開盤價作爲訓練集,表格從0開始計數,2:3 是提取[2:3)列,前閉後開,故提取出C列開盤價
test_set = maotai.iloc[350 - 60:, 2:3].values  # 後300天的開盤價作爲測試集

# 歸一化
sc = MinMaxScaler(feature_range=(0, 1))  # 定義歸一化:歸一化到(01)之間
training_set_scaled = sc.fit_transform(training_set)  # 求得訓練集的最大值,最小值這些訓練集固有的屬性,並在訓練集上進行歸一化
test_set = sc.transform(test_set)  # 利用訓練集的屬性對測試集進行歸一化

x_train = []
y_train = []

x_test = []
y_test = []

# 測試集:csv表格中前2426-300=2126天數據
# 利用for循環,遍歷整個訓練集,提取訓練集中連續60天的開盤價作爲輸入特徵x_train,第61天的數據作爲標籤,for循環共構建2426-300-60=2066組數據。
for i in range(60, len(training_set_scaled)):
    x_train.append(training_set_scaled[i - 60:i, 0])
    y_train.append(training_set_scaled[i, 0])
# 對訓練集進行打亂
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
tf.random.set_seed(7)
# 將訓練集由list格式變爲array格式
x_train, y_train = np.array(x_train), np.array(y_train)

# 使x_train符合RNN輸入要求:[送入樣本數, 循環核時間展開步數, 每個時間步輸入特徵個數]。
# 此處整個數據集送入,送入樣本數爲x_train.shape[0]2066組數據;輸入60個開盤價,預測出第61天的開盤價,循環核時間展開步數爲60; 每個時間步送入的特徵是某一天的開盤價,只有1個數據,故每個時間步輸入特徵個數爲1
x_train = np.reshape(x_train, (x_train.shape[0], 60, 1))
# 測試集:csv表格中後300天數據
# 利用for循環,遍歷整個測試集,提取測試集中連續60天的開盤價作爲輸入特徵x_train,第61天的數據作爲標籤,for循環共構建300-60=240組數據。
for i in range(60, len(test_set)):
    x_test.append(test_set[i - 60:i, 0])
    y_test.append(test_set[i, 0])
# 測試集變array並reshape爲符合RNN輸入要求:[送入樣本數, 循環核時間展開步數, 每個時間步輸入特徵個數]
x_test, y_test = np.array(x_test), np.array(y_test)
x_test = np.reshape(x_test, (x_test.shape[0], 60, 1))

model = tf.keras.Sequential([
    LSTM(80, return_sequences=True),
    Dropout(0.2),
    LSTM(100),
    Dropout(0.2),
    Dense(1)
])

model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss='mean_squared_error')  # 損失函數用均方誤差
# 該應用只觀測loss數值,不觀測準確率,所以刪去metrics選項,一會在每個epoch迭代顯示時只顯示loss值

checkpoint_save_path = "./checkpoint/LSTM_600584_stock.ckpt"

if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    model.load_weights(checkpoint_save_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
                                                 save_weights_only=True,
                                                 save_best_only=True,
                                                 monitor='val_loss')

history = model.fit(x_train, y_train, batch_size=64, epochs=50, validation_data=(x_test, y_test), validation_freq=1,
                    callbacks=[cp_callback])

model.summary()

file = open('./weights.txt', 'w')  # 參數提取
for v in model.trainable_variables:
    file.write(str(v.name) + '\n')
    file.write(str(v.shape) + '\n')
    file.write(str(v.numpy()) + '\n')
file.close()

loss = history.history['loss']
val_loss = history.history['val_loss']

plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()

################## predict ######################
# 測試集輸入模型進行預測
predicted_stock_price = model.predict(x_test)
# 對預測數據還原---從(01)反歸一化到原始範圍
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
# 對真實數據還原---從(01)反歸一化到原始範圍
real_stock_price = sc.inverse_transform(test_set[60:])
# 畫出真實數據和預測數據的對比曲線
plt.plot(real_stock_price, color='red', label='MaoTai Stock Price')
plt.plot(predicted_stock_price, color='blue', label='Predicted MaoTai Stock Price')
plt.title('MaoTai Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('MaoTai Stock Price')
plt.legend()
plt.show()

##########evaluate##############
# calculate MSE 均方誤差 ---> E[(預測值-真實值)^2] (預測值減真實值求平方後求均值)
mse = mean_squared_error(predicted_stock_price, real_stock_price)
# calculate RMSE 均方根誤差--->sqrt[MSE]    (對均方誤差開方)
rmse = math.sqrt(mean_squared_error(predicted_stock_price, real_stock_price))
# calculate MAE 平均絕對誤差----->E[|預測值-真實值|](預測值減真實值求絕對值後求均值)
mae = mean_absolute_error(predicted_stock_price, real_stock_price)
print('均方誤差: %.6f' % mse)
print('均方根誤差: %.6f' % rmse)
print('平均絕對誤差: %.6f' % mae)

是用模型進行預測

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dropout, Dense, LSTM
import matplotlib.pyplot as plt
import os
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
import math

maotai = pd.read_csv('./600584.csv')  # 讀取股票文件

training_set = maotai.iloc[0:350 - 60, 2:3].values  # 前(2426-300=2126)天的開盤價作爲訓練集,表格從0開始計數,2:3 是提取[2:3)列,前閉後開,故提取出C列開盤價
test_set = maotai.iloc[350 - 60:, 2:3].values  # 後300天的開盤價作爲測試集

# 歸一化
sc = MinMaxScaler(feature_range=(0, 1))  # 定義歸一化:歸一化到(01)之間
training_set_scaled = sc.fit_transform(training_set)  # 求得訓練集的最大值,最小值這些訓練集固有的屬性,並在訓練集上進行歸一化
test_set = sc.transform(test_set)  # 利用訓練集的屬性對測試集進行歸一化


x_test = []


# 測試集:csv表格中後300天數據
# 利用for循環,遍歷整個測試集,提取測試集中連續60天的開盤價作爲輸入特徵x_train,第61天的數據作爲標籤,for循環共構建300-60=240組數據。
for i in range(60, len(test_set)):
    x_test.append(test_set[i - 60:i, 0])

#x_test.append(test_set[len(test_set), 0])
# 測試集變array並reshape爲符合RNN輸入要求:[送入樣本數, 循環核時間展開步數, 每個時間步輸入特徵個數]
x_test = np.array(x_test)
x_test = np.reshape(x_test, (x_test.shape[0], 60, 1))

model = tf.keras.Sequential([
    LSTM(80, return_sequences=True),
    Dropout(0.2),
    LSTM(100),
    Dropout(0.2),
    Dense(1)
])

model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss='mean_squared_error')  # 損失函數用均方誤差
# 該應用只觀測loss數值,不觀測準確率,所以刪去metrics選項,一會在每個epoch迭代顯示時只顯示loss值

checkpoint_save_path = "./checkpoint/LSTM_600584_stock.ckpt"

if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    model.load_weights(checkpoint_save_path)



################## predict ######################
# 測試集輸入模型進行預測
predicted_stock_price = model.predict(x_test)
# 對預測數據還原---從(01)反歸一化到原始範圍
predicted_stock_price = sc.inverse_transform(predicted_stock_price)

print(predicted_stock_price)

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