金融量化:LSTM 预测股票次日最高价
发布时间
阅读量:
阅读量
该文本介绍了一种基于金融量化和LSTM序列预测的股票价格预测方法。主要步骤包括:1) 从CSV文件中加载股票历史数据;2) 定义LSTM超参数(如隐层单元数为10、输入大小为7);3) 编写gettraindata函数用于获取标准化后的训练数据集;4) 编写gettestdata函数用于获取标准化后的测试数据集;5) 构建LSTM模型并定义损失函数及优化器;6) 在主代码中调用train_lstm函数进行模型训练;7) 调用prediction函数进行测试并绘制结果图。
文章目录
- 金融量化
- LSTM 序列预测
金融量化
LSTM 序列预测
# encoding: utf-8
from __future__ import print_function
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
# 定义LSTM的超参数
# 根据股票历史数据中的最低价、最高价、开盘价、收盘价、交易量、交易额、跌涨幅等因素,对下一日股票最高价进行预测。
rnn_unit=10 # 隐含层数目
input_size=7
output_size=1
lr=0.0006 # 学习率
# 定义权重和偏置
weights={
'in':tf.Variable(tf.random_normal([input_size,rnn_unit])),
'out':tf.Variable(tf.random_normal([rnn_unit,1]))
}
biases={
'in':tf.Variable(tf.constant(0.1,shape=[rnn_unit,])),
'out':tf.Variable(tf.constant(0.1,shape=[1,]))
}
'''
函数功能:获取获取训练数据,从原始数据中整理出训练数据
@:param batch_size 批大小
@:param time_step 时间步
@:param train_begin 训练起始点
@:param train_end 训练终止点
@:return batch_index(批索引)、train_x(训练数据feature)train_y(训练数据label)
'''
def get_train_data(batch_size=60,time_step=20,train_begin=0,train_end=5800):
batch_index=[]
data_train=data[train_begin:train_end]
# 标准化
normalized_train_data=(data_train-np.mean(data_train,axis=0))/np.std(data_train,axis=0)
# 训练集
train_x,train_y=[],[]
# 此时normalized_train_data的shape是n*8
for i in range(len(normalized_train_data)-time_step): # i = 1~5785
# 生成batch_index:0,batch_size*1,batch_size*2
if i % batch_size==0:
batch_index.append(i)
x=normalized_train_data[i:i+time_step,:7] # x:shape 15*7
y=normalized_train_data[i:i+time_step,7,np.newaxis] # y:shape 15*1
train_x.append(x.tolist())
train_y.append(y.tolist())
batch_index.append((len(normalized_train_data)-time_step)) # batch_index 收尾
# train_x :n*15*7
# train_y :n*15*1
return batch_index,train_x,train_y
'''
函数功能:获取测试数据
@:param time_step 时间步
@:param test_begin 起始点
@:return 预测值、最终状态
'''
def get_test_data(time_step=20,test_begin=5800):
data_test=data[test_begin:] # 截取测试数据
mean=np.mean(data_test,axis=0) # 平均数
std=np.std(data_test,axis=0) # 方差
normalized_test_data=(data_test-mean)/std # 标准化
# 有size个sample
size=(len(normalized_test_data)+time_step-1)//time_step
test_x,test_y=[],[]
for i in range(size-1):
x=normalized_test_data[i*time_step:(i+1)*time_step,:7] # x shape 20*7
y=normalized_test_data[i*time_step:(i+1)*time_step,7] # y shape (20,)
test_x.append(x.tolist())
test_y.extend(y)
# 保存得到的x和y
test_x.append((normalized_test_data[(i+1)*time_step:,:7]).tolist()) # 本例中 16*20*7
test_y.extend((normalized_test_data[(i+1)*time_step:,7]).tolist()) # 本例中 309
return mean,std,test_x,test_y
'''
函数功能:构造LSTM网络模型
@:param X 数据的label shape = [None,time_step,input_size]
@:return 预测值、最终状态
'''
def lstm(X):
batch_size=tf.shape(X)[0] # 这行语句用于获取X的第一维的具体数据 获取batch_size值
time_step=tf.shape(X)[1] # 这行语句用于获取X的第一维的具体数据 获取time_step值
w_in=weights['in']
b_in=biases['in']
input=tf.reshape(X,[-1,input_size]) #需要将tensor转成2维进行计算,计算后的结果作为隐藏层的输入 系统的输入单元数为7,所以将输入数据shape为n行7列
input_rnn=tf.matmul(input,w_in)+b_in # 输入数据与输入权重相乘,得到输入数据对隐含层的影响
# 将tensor转成3维,作为lstm cell的输入
# 隐含层的cell接收的数据是3维的,即将n*10的数据shape为n*15*10的数据
input_rnn=tf.reshape(input_rnn,[-1,time_step,rnn_unit])
# 设置lstm的cell,BasicLSTMCell的入参有(self, num_units, forget_bias=1.0,state_is_tuple=True, activation=None, reuse=None)
# 此处只设置其隐含层数目为rnn_unit,即10,其他参数使用默认值
cell=tf.nn.rnn_cell.BasicLSTMCell(rnn_unit)
init_state=cell.zero_state(batch_size,dtype=tf.float32)
# output_rnn是记录LSTM每个输出节点的结果,final_states是最后一个cell的结果
output_rnn,final_states=tf.nn.dynamic_rnn(cell, input_rnn,initial_state=init_state, dtype=tf.float32)
# 将输出数据shape为n*10格式
output=tf.reshape(output_rnn,[-1,rnn_unit])
w_out=weights['out']
b_out=biases['out']
# cell输出经过与输出权重矩阵相乘并加入偏置后,得到最终输出
pred=tf.matmul(output,w_out)+b_out
return pred,final_states
'''
函数功能:训练模型
@:param batch_size 批大小
@:param time_step 时间步长度
@:param train_begin 训练起始
@:param train_end 训练截止
@:return 打印得分并将模型保存
'''
def train_lstm(batch_size=80,time_step=15,train_begin=2000,train_end=5800):
# X是训练数据中的feature Y是训练数据中的label
X=tf.placeholder(tf.float32, shape=[None,time_step,input_size])
Y=tf.placeholder(tf.float32, shape=[None,time_step,output_size])
# 获取训练数据 batch_index:80的等差序列 train_x:[3785*15] train_y:[3785*15] 15:time_step值
batch_index,train_x,train_y=get_train_data(batch_size,time_step,train_begin,train_end)
# 创建预测值获取的计算流程
with tf.variable_scope("sec_lstm"):
pred,_=lstm(X)
# 创建损失函数的计算流程
loss=tf.reduce_mean(tf.square(tf.reshape(pred,[-1])-tf.reshape(Y, [-1])))
# 定义优化函数(即训练使)
train_op=tf.train.AdamOptimizer(lr).minimize(loss)
# 将变量保存
saver=tf.train.Saver(tf.global_variables(),max_to_keep=15)
with tf.Session() as sess:
try:
module_file = tf.train.latest_checkpoint('.')
saver.restore(sess, module_file)
except:
sess.run(tf.global_variables_initializer())
# 重复训练10000次
for i in range(10):
# 按批次进行训练,每一批次80条数据
for step in range(len(batch_index)-1):
_,loss_=sess.run([train_op,loss],feed_dict={X:train_x[batch_index[step]:batch_index[step+1]],Y:train_y[batch_index[step]:batch_index[step+1]]})
print(i,loss_)
if i % 200==0:
print("保存模型:",saver.save(sess,'./stock2.model',global_step=i))
'''
函数功能:根据模型进行预测
@:param time_step 时间步长度
@:return 打印得分并将模型保存
'''
def prediction(time_step=20):
X=tf.placeholder(tf.float32, shape=[None,time_step,input_size])
#Y=tf.placeholder(tf.float32, shape=[None,time_step,output_size])
# 获取测试数据的“均值”、“方差”、feature和label
# test_x 16*20(最后一个长度为9) test_y:309
mean,std,test_x,test_y=get_test_data(time_step)
with tf.variable_scope("sec_lstm",reuse=True):
pred,_=lstm(X)
saver=tf.train.Saver(tf.global_variables())
with tf.Session() as sess:
#参数恢复
module_file = tf.train.latest_checkpoint('./')
saver.restore(sess, module_file)
test_predict=[]
for step in range(len(test_x)-1):
prob=sess.run(pred,feed_dict={X:[test_x[step]]}) # prob是长度为20的一维矩阵,也就是说,对于我们的模型,输入是15,输出是20
predict=prob.reshape((-1))
test_predict.extend(predict)
test_y=np.array(test_y)*std[7]+mean[7]
test_predict=np.array(test_predict)*std[7]+mean[7]
acc=np.average(np.abs(test_predict-test_y[:len(test_predict)])/test_y[:len(test_predict)]) #偏差
#以折线图表示结果
plt.figure()
plt.plot(list(range(len(test_predict))), test_predict, color='b')
plt.plot(list(range(len(test_y))), test_y, color='r')
plt.show()
# ========================================主代码==================================
# 导入数据
f=open('dataset/dataset_2.csv')
df=pd.read_csv(f) # 读入股票数据
data=df.iloc[:,2:10].values # 取第3-10列 data实际数据大小[6109 * 8]
# 内部调用了get_train_data函数,从data中获取了训练数据
# 获取训练数据 batch_index:80的等差序列 train_x:[3785*15] train_y:[3785*15] 15:time_step值
# 默认取2000~5800之间的数据作为训练数据,
train_lstm()
# 内部调用了get_test_data函数,从data中获取了测试函数
# 取5800往后的数据作为测试数据,一共309个数据
# test_x 16*20(最后一个长度为9) test_y:309
prediction()
AI助手
全部评论 (0)
还没有任何评论哟~
