Аннотация: Модель алгоритма основана на динамическом множественном скрытом слое LSTM RNN, Функция потерь использует максимальное значение потерь cross_entropy, входное измерение M и выходное измерение N. Код реализован на основе Python3.6.X и Tensorflow1.13.X.
1. Введение
Для продуктов в новой розничной торговле, финансах, цепочках поставок, онлайн-образовании, банковском деле, ценных бумагах и других отраслях анализ поведения пользователей на основе данных особенно важен. Целью анализа поведения пользователей является продвижение итерации продукта, достижение точного маркетинга, предоставление индивидуальных услуг и стимулирование принятия решений о продукте.
Начнем с нового бизнес-сценария розничной АЗС в качестве примера.Когда мы едем заправлять машину, мы сталкиваемся с тратой денег, а также сталкиваемся с неприятными пробками и трудоемкими проблемами, такими как очереди на заправку. Обычно мы можем ездить на заправку примерно раз в неделю, чтобы заправиться, и мы также можем зайти в круглосуточный магазин, чтобы купить что-то, не связанное с нефтью, или мы также можем зайти, чтобы помыть машину.
Анализ поведенческих событий, показанный на рисунке выше, основан на ключевых операционных индикаторах для анализа данных о транзакциях по топливным картам и событий, специфичных для пользователя. Отслеживая или записывая события поведения пользователей во временных рядах, вы можете быстро понять тенденцию событий и завершение заправки клиентов.
Прогнозирование недавних и будущих цен на акции также относится к категории анализа поведения торговли на основе временных рядов.Нам проще получить данные о торговле акциями, а также относительно очевидно сравнить результаты прогнозирования. В настоящее время в отрасли есть случаи, которые могут относиться к использованию алгоритма CNN + LSTM для анализа поведения и прогнозирования цен на акции. Из-за нехватки данных по новым розничным и другим предприятиям мы сначала используем данные о запасах для изучения модели алгоритма.
2. Анализ прогнозирования временных рядов, обзор алгоритма глубокого обучения LSTM
В глубоком обучении есть нейронная сеть, подходящая для обработки данных последовательности, то есть рекуррентная нейронная сеть RNN.Он широко используется в НЛП и имеет лучшие эффекты.Он также используется в финансовом количественном анализе, особенно в анализе поведения, курса акций анализ Есть также много приложений в прогнозировании. Здесь мы не углубляемся в модель алгоритма, а только представляем ключевое содержание с точки зрения приложения.
2.1 Обзор рекуррентной нейронной сети RNN
Rerrent Neural Network (RNN) появилась в 1980-х годах и относится к простой структуре нейронной сети, которая повторяет цикл с прохождением временных рядов и состоит из входного слоя, скрытого слоя и выходного слоя.Прогнозирующий анализ временных рядов заключается в использовании характеристик времени события в прошлом периоде времени для прогнозирования характеристик события в будущем периоде времени. Это относительно сложная задача прогнозного моделирования.В отличие от прогнозирования моделей регрессионного анализа, модели временных рядов зависят от последовательности событий, а результаты входной модели после изменения порядка значений одного и того же размера отличаются.
RNN учатся на последовательных данных, и, чтобы запомнить эти данные, RNN генерируют человеческие воспоминания о предыдущих событиях.
2.2. Обзор рекуррентной нейронной сети с долгой краткосрочной памятью LSTM
Обычный RNN как старый дедушка, иногда забывчивый, почему это? Обычная RNN для ввода информации с помощью программного обеспечения мобильного телефона требует большого пути, чтобы достичь последней временной точки. Затем мы получаем ошибку, и она на каждом шаге умножает собственный параметр W при передаче ошибки обратно. Если это W является числом меньше 1, после непрерывного умножения ошибки, ошибка будет числом, близким к нулю, когда она достигнет начальной временной точки, и ошибка эквивалентна исчезновению. Мы называем эту проблему исчезающим градиентом или дисперсией градиента. С другой стороны, если W — число больше 1, в конце оно становится бесконечным числом, что называется бритвенным взрывом. Вот почему обычные RNN не могут вспомнить далекие воспоминания.
LSTM был создан для решения этой проблемы.По сравнению с обычным RNN, LSTM имеет еще три контроллера: входной вентиль, выходной вентиль и забытый вентиль. На рисунке ниже показан обзор результатов внутри LSTM.
в,это дверь забвения,входные ворота,выходные ворота,состояние нейрона,— значения состояния скрытого слоя, а W и b — веса и смещения соответственно.
LSTM имеет дополнительную память, которая управляет всем миром.На рисунке мы представляем основную линию, которая эквивалентна основному сюжету в сценарии. Обычная система RNN представляет собой график с разделенными линиями. Давайте сначала посмотрим на входной подсюжет, который очень важен для конечного результата игры.Управление вводом запишет этот подсюжет в основной сюжет для анализа в соответствии с его важностью.Чтобы забыть, если подсюжет на этом время изменяет нашу предыдущую идею сюжета, то забывающий контроль забудет некоторые из предыдущих основных сюжетов и пропорционально заменит их текущими новыми сюжетами. LSTM похож на хорошее лекарство для замедления потери памяти и может привести к лучшим результатам.
Для модели алгоритма LSTM выходные состояния представляют собой кортеж, представляющийи,вОн равен выходу соответствующего последнего момента в выходах (т.е. последней ячейки).
3. Модель алгоритма LSTM для прогнозирования цен на акции.
3.1 Построить модель регрессии LSTM на основе Tensorflow1.13.X
Мы определяем основную структуру LSTM RNN в виде класса (класс MultiLSTM), этот RNN состоит из 3 компонентов (input_layer, cell, output_layer):
(1) Определите входной слой:
with tf.name_scope('inputs'):
self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs')
self.ys = tf.placeholder(tf.float32, [None, n_steps, output_size], name='ys')
self.batch_size = tf.placeholder(tf.int32, [], name='batch_size')
#节点不被dropout的概率
self.keep_prob = tf.placeholder(tf.float32, name='keep_prob')
Среди них входной слой дополнительно включает batch_size (размер пакета обучающих данных) и keep_prob (во избежание переобучения, вероятность не быть удаленным).
(2) Определите скрытый слой:
Создайте нейронную сеть с несколькими скрытыми слоями.
# 定义多层LSTM
def add_multi_cell(self):
cell_list = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)
with tf.name_scope('dropout'):
if self.is_training:
# 添加dropout.为了防止过拟合,在它的隐层添加了 dropout 正则
cell_list = tf.contrib.rnn.DropoutWrapper(cell_list, output_keep_prob=self.keep_prob)
tf.summary.scalar('dropout_keep_probability', self.keep_prob)
lstm_cell = [cell_list for _ in range(self.num_layers)]
lstm_cell = tf.contrib.rnn.MultiRNNCell(lstm_cell, state_is_tuple=True) #遗漏过?, state_is_tuple=True
with tf.name_scope('initial_state'):
self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(
lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
Когда отсев выполняется в RNN, отсев не выполняется для части RNN, а отсев выполняется только при передаче информации между многослойными ячейками в одно и то же время t.
Параметр time_major в tf.nn.dynamic_rnn(cell, inputs) будет иметь разные значения для разных форматов ввода:
- Если входные данные (партии, шаги, входные данные), то time_major=False; если входные данные
- For (шаги, пакеты, входы) соответствует time_major=True;
(3) Определите выходной слой:
Выходной слой реализует полное соединение без функции активации, то есть линейное.
# 定义输出全连接层
def add_output_layer(self):
l_out_x = tf.reshape(self.cell_outputs, [-1, self.cell_size], name='2_2D')
Ws_out = self._weight_variable([self.cell_size, self.output_size])
bs_out = self._bias_variable([self.output_size, ])
# shape = (batch * steps, output_size)
with tf.name_scope('Wx_plus_b'):
self.pred = tf.matmul(l_out_x, Ws_out) + bs_out
(4) Определить функцию потерь:
Используйте tf.contrib.legacy_seq2seq.sequence_loss_by_example, чтобы определить функцию потерь.Поскольку это модель с несколькими выходами, получение среднего значения повлияет на результат.Я использую схему максимального значения.
def compute_cost(self):
losses = tf.contrib.legacy_seq2seq.sequence_loss_by_example(
[tf.reshape(self.pred, [-1], name='reshape_pred')],
[tf.reshape(self.ys, [-1], name='reshape_target')],
[tf.ones([self.batch_size * self.n_steps*self.output_size], dtype=tf.float32)],
average_across_timesteps=True,
softmax_loss_function=self.ms_error,
name='losses'
)
with tf.name_scope('average_cost'):
# 取最大损失值
self.cost = tf.reduce_max(losses, name='average_cost')
'''
self.cost = tf.div(
tf.reduce_sum(losses, name='losses_sum'),
self.batch_size_,
name='average_cost')
'''
tf.summary.scalar('cost', self.cost)
print('self.cost shape is {}'.format(self.cost.shape))
(5) Общие проблемы и меры предосторожности при построении сети LSTM:
- «Многие ко многим» — самая классическая структура в RNN, и ее вход и выход представляют собой данные последовательности одинаковой длины;
- В Tensorflow1.x параметру batch_size должно быть присвоено неопределенное значение, чтобы не было необходимости конструировать batch_size, когда это удобно для тестирования и моделирования приложения;
- При выполнении потерь, например, в процессе среднеквадратичной ошибки, обратите внимание на количество данных batch_sizen_stepsвыход_размер;
- Из-за ограниченного размера набора данных, когда временной шаг слишком велик, а длина обучающего набора мала, результаты прогнозирования обученной модели будут показывать небольшие колебания и прямую линию.Рекомендуется сократить временной шаг.
На данный момент построена многоуровневая модель LSTM, и код интеграции выглядит следующим образом.
class MultiLSTM(object):
def __init__(self, n_steps, input_size, output_size, cell_size, batch_size,num_layers,is_training):
self.n_steps = n_steps
self.input_size = input_size
self.output_size = output_size
self.cell_size = cell_size # LSTM神经单元数
self.batch_size_ = batch_size # 输入batch_size大小
self.num_layers = num_layers # LSTM层数
#是否是训练状态
self.is_training = is_training
with tf.name_scope('inputs'):
self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs')
self.ys = tf.placeholder(tf.float32, [None, n_steps, output_size], name='ys')
self.batch_size = tf.placeholder(tf.int32, [], name='batch_size')
#节点不被dropout的概率
self.keep_prob = tf.placeholder(tf.float32, name='keep_prob')
with tf.variable_scope('in_hidden'):
self.add_input_layer()
with tf.variable_scope('Multi_LSTM'):
self.add_multi_cell()
with tf.variable_scope('out_hidden'):
self.add_output_layer()
with tf.name_scope('cost'):
self.compute_cost()
with tf.name_scope('train'):
self.train_op = tf.train.AdamOptimizer(LR).minimize(self.cost)
def add_input_layer(self,):
l_in_x = tf.reshape(self.xs, [-1, self.input_size], name='2_2D') # (batch*n_step, in_size)
Ws_in = self._weight_variable([self.input_size, self.cell_size])
bs_in = self._bias_variable([self.cell_size,])
with tf.name_scope('Wx_plus_b'):
l_in_y = tf.matmul(l_in_x, Ws_in) + bs_in
self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='2_3D')
# 定义多层LSTM
def add_multi_cell(self):
cell_list = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)
with tf.name_scope('dropout'):
if self.is_training:
# 添加dropout.为了防止过拟合,在它的隐层添加了 dropout 正则
cell_list = tf.contrib.rnn.DropoutWrapper(cell_list, output_keep_prob=self.keep_prob)
tf.summary.scalar('dropout_keep_probability', self.keep_prob)
lstm_cell = [cell_list for _ in range(self.num_layers)]
lstm_cell = tf.contrib.rnn.MultiRNNCell(lstm_cell, state_is_tuple=True) #遗漏过?, state_is_tuple=True
with tf.name_scope('initial_state'):
self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(
lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
# 定义输出全连接层
def add_output_layer(self):
l_out_x = tf.reshape(self.cell_outputs, [-1, self.cell_size], name='2_2D')
Ws_out = self._weight_variable([self.cell_size, self.output_size])
bs_out = self._bias_variable([self.output_size, ])
with tf.name_scope('Wx_plus_b'):
self.pred = tf.matmul(l_out_x, Ws_out) + bs_out
def compute_cost(self):
losses = tf.contrib.legacy_seq2seq.sequence_loss_by_example(
[tf.reshape(self.pred, [-1], name='reshape_pred')],
[tf.reshape(self.ys, [-1], name='reshape_target')],
[tf.ones([self.batch_size * self.n_steps*self.output_size], dtype=tf.float32)],
average_across_timesteps=True,
softmax_loss_function=self.ms_error,
name='losses'
)
with tf.name_scope('average_cost'):
self.cost = tf.reduce_max(losses, name='average_cost')
'''
self.cost = tf.div(
tf.reduce_sum(losses, name='losses_sum'),
self.batch_size_,
name='average_cost')
'''
tf.summary.scalar('cost', self.cost)
print('self.cost shape is {}'.format(self.cost.shape))
@staticmethod
def ms_error(labels, logits):
return tf.square(tf.subtract(labels, logits))
def _weight_variable(self, shape, name='weights'):
initializer = tf.random_normal_initializer(mean=0., stddev=1.,)
return tf.get_variable(shape=shape, initializer=initializer, name=name)
def _bias_variable(self, shape, name='biases'):
initializer = tf.constant_initializer(0.1)
return tf.get_variable(name=name, shape=shape, initializer=initializer)
Примечание: Справочник по прототипу кода Не беспокойтесь о коде, связанном с Python.LSTM-регрессия".
Существуют разные способы написания нескольких скрытых слоев.Официальная рекомендация такова:
# 官方推荐的写法,使用列表生成器:
num_units = [128, 64]
cells = [BasicLSTMCell(num_units=n) for n in num_units]
stacked_rnn_cell = MultiRNNCell(cells)
3.2 Набор данных о запасах
Данные об акциях поступают из Tushare, бесплатного пакета интерфейса финансовых данных Python с открытым исходным кодом. Я использую версию Pro, ее данные более стабильны и качество лучше, Pro по-прежнему является открытой бесплатной платформой, рекомендуется:Сообщество больших данных TushareПоделитесь этой ссылкой.
В этом практическом примере используются данные акции после повторного взвешивания, а также ввод Шанхайского композитного индекса, Шэньчжэньского композитного индекса, индекса Nasdaq, индекса Доу-Джонса и индекса Hang Seng (из-за проблем с производительностью компьютера). , зарезервированы только Shanghai Composite Index и Shenzhen Composite Index).Создайте набор обучающих данных и разделите цену акций на момент закрытия, объем торгов, Шанхайский составной индекс и Шэньчжэньский индекс компонентов в качестве выходных данных (OUTPUT_SIZE = 4). Начиная со времени , возьмите 15 наборов данных полного столбца один за другим в качестве входных данных и 15 наборов из 15 наборов из 4 столбцов в качестве выходных данных, то окончательный ввод представляет собой последнюю дату текущего набора данных минус 15 (PRED_SIZE=15).
Код для процесса разделения набора данных показан ниже, включая последние 15 наборов данных в качестве входных данных для прогнозирования следующих 15 дней (PRED_SIZE=15).
def get_train_data():
df = pd.read_csv('share20210302.csv')
return df
def get_test_data():
df = pd.read_csv('share20210302.csv')
#df = df.iloc[-(TIME_STEPS+1):] #由于要删除一行,需要多取一行(美国股市与中国差一天)
df = df.iloc[-TIME_STEPS:]
return df
def get_pred_data(y,z,sc):
yy = np.concatenate((y, z),axis=1)
y=sc.inverse_transform(yy)
return y
# 设置数据集
def set_datas(df,train=True,sc=None):
df['Year'] = df['trade_date'].apply(lambda x:int(str(x)[0:4]))
df['Month'] = df['trade_date'].apply(lambda x:int(str(x)[4:6]))
df['Day'] = df['trade_date'].apply(lambda x:int(str(x)[6:8]))
df['Week'] = df['trade_date'].apply(lambda x:datetime.datetime.strptime(str(x),'%Y%m%d').weekday())
#纳仕达克、道琼斯指数,需要下移一条记录
#shift_columns = ['open3','high3','close3','low3','change3','pct_chg3','open4','high4','close4','low4','change4','pct_chg4']
#df[shift_columns] = df[shift_columns].shift(1)
# 重排表的列,便于数据提取
##df = df.reindex(columns=col_name)
df = df.drop('trade_date',axis=1)
#df = df[1:].reset_index(drop=True) #删除第一行,从0开始
col_name = df.columns.tolist()
#列移动归集位置
col_name.remove('close1')
col_name.remove('close2')
col_name.remove('vol0')
#删除不重要的列
#del_list = ['high3','low3','change3','pct_chg3','high4','low4','change4','pct_chg4','high5','low5','change5','pct_chg5']
#for name in del_list:
# col_name.remove(name)
col_name.insert(0,'close1')
col_name.insert(1,'close2')
col_name.insert(2,'vol0')
df = df[col_name]
#sc = MinMaxScaler(feature_range= (0,1)) 预测值超过最大值?
if train:
sc = MinMaxScaler(feature_range= (0,1))
training_set = sc.fit_transform(df)
else:
# 测试集,也需要使用原Scaler归一化
training_set = sc.transform(df)
# 按时序长度构造数据集
def get_batch(train_x,train_y):
data_len = len(train_x) - TIME_STEPS
seq = []
res = []
for i in range(data_len):
seq.append(train_x[i:i + TIME_STEPS])
res.append(train_y[i:i + TIME_STEPS]) #取后5组数据
#res.append(train_y[i:i + TIME_STEPS])
seq ,res = np.array(seq),np.array(res)
return seq, res
if train:
seq, res = get_batch(training_set[:-PRED_SIZE], training_set[PRED_SIZE:][:,0:OUTPUT_SIZE]) #0:9
else:
seq, res = training_set, training_set[:,0:OUTPUT_SIZE]
seq, res = seq[np.newaxis,:,:], res[np.newaxis,:,:]
return seq, res, training_set[:,OUTPUT_SIZE:],sc,col_name,df
Меры предосторожности: После нормализации обучающего набора и тестового набора необходимо принять единый стандарт, то есть один fit_transform используется для MinMaxScaler, а затем преобразование можно использовать позже. (Легко перевернуться в этой маленькой речной канаве!)
3.3 Обучение модели и параметры
Во время обучения модели используйте итератор tf.data.Dataset.from_tensor_slices для получения пакетных данных. Данные журнала процесса обучения записываются в каталог «logs» и просматриваются с помощью инструмента tensorboard.
import tensorflow as tf
import numpy as np
import pandas as pd
import datetime
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt
BATCH_START = 0
TIME_STEPS = 15
BATCH_SIZE = 30
INPUT_SIZE = 25
OUTPUT_SIZE = 4
PRED_SIZE = 15 #预测输出15天序列数据
CELL_SIZE = 256
NUM_LAYERS = 3
LR = 0.00001
EPOSE = 40000
if __name__ == '__main__':
model = MultiLSTM(TIME_STEPS, INPUT_SIZE, OUTPUT_SIZE, CELL_SIZE, BATCH_SIZE, NUM_LAYERS,True)
sess = tf.Session()
merged = tf.summary.merge_all()
writer = tf.summary.FileWriter("logs", sess.graph)
# tf.initialize_all_variables() no long valid from
# 2017-03-02 if using tensorflow >= 0.12
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
init = tf.initialize_all_variables()
else:
init = tf.global_variables_initializer()
sess.run(init)
# relocate to the local dir and run this line to view it on Chrome (http://localhost:6006/):
# $ tensorboard --logdir logs
state = 0
xs = 0
df = get_train_data()
train_x,train_y,z,sc,col_name,df = set_datas(df,True)
# 使用from_tensor_slices将数据放入队列,使用batch和repeat划分数据批次,且让数据序列无限延续
dataset = tf.data.Dataset.from_tensor_slices((train_x,train_y))
dataset = dataset.batch(BATCH_SIZE).repeat()
# 使用生成器make_one_shot_iterator和get_next取数据
# 单次迭代器只能循环使用一次数据,而且单次迭代器不需要手动显示调用sess.run()进行初始化即可使用
#iterator = dataset.make_one_shot_iterator()
# 可初始化的迭代器可以重新初始化进行循环,但是需要手动显示调用sess.run()才能循环
iterator = dataset.make_initializable_iterator()
next_iterator = iterator.get_next()
losse = []
for i in range(EPOSE):
# 这是显示初始化,当我们的迭代器是dataset.make_initializable_iterator()的时候,才需要调用这个方法,否则不需要
sess.run(iterator.initializer)
seq, res = sess.run(next_iterator)
if i == 0:
feed_dict = {
model.xs: seq,
model.ys: res,
model.batch_size:BATCH_SIZE,
model.keep_prob:0.75,
# create initial state
}
else:
feed_dict = {
model.xs: seq,
model.ys: res,
model.batch_size:BATCH_SIZE,
model.keep_prob:0.75,
model.cell_init_state: state # use last state as the initial state for this run
}
_, cost, state, pred = sess.run(
[model.train_op, model.cost, model.cell_final_state, model.pred],
feed_dict=feed_dict)
losse.append(cost)
if i % 20 == 0:
#print(state)
print('cost: ', round(cost, 5))
result = sess.run(merged, feed_dict)
writer.add_summary(result, i)
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False
losse = np.array(losse)/max(losse)
plt.plot(losse, label='Training Loss')
plt.title('Training Loss')
plt.legend()
plt.show()
#训练结束
В окне командной строки перейдите в текущий каталог программы и используйте команду tensorboard --logdir logs. Схема расчета выглядит следующим образом:Процесс обучения выглядит следующим образом, а стоимость достигает 0,013X.
3.4 Результаты прогнозирования и анализ
Используя последние 15 записей набора данных в качестве входных данных для прогнозирования следующих 15 дней, результат выглядит следующим образом:
df = get_test_data()
seq,res,z,sc,col_name,df = set_datas(df,False,sc)
seq = seq.reshape(-1,TIME_STEPS,INPUT_SIZE)
share_close = df['close0'].values
share_vol = df['vol0'].values/10000
share_sh = df['close1'].values
share_sz = df['close2'].values
model.is_training = False
feed_dict = {
model.xs: seq,
model.batch_size:1,
model.keep_prob:1.0
}
#pred,state = sess.run([model.pred,model.cell_init_state], feed_dict=feed_dict)
pred = sess.run([model.pred], feed_dict=feed_dict)
#print(pred[0])
y=get_pred_data(pred[0].reshape(TIME_STEPS,OUTPUT_SIZE),z,sc)
df= pd.DataFrame(y,columns=col_name)
df.to_csv('y.csv')
share_close1 = df['close0'].values
share_vol1 = df['vol0'].values/10000
share_sh1 = df['close1'].values
share_sz1 = df['close2'].values
#合并预测移动移位PRED_SIZE
share_close1 = np.concatenate((share_close[:PRED_SIZE],share_close1),axis=0)
share_vol1 = np.concatenate((share_vol[:PRED_SIZE],share_vol1),axis=0)
share_sh1 = np.concatenate((share_sh[:PRED_SIZE],share_sh1),axis=0)
share_sz1 = np.concatenate((share_sz[:PRED_SIZE],share_sz1),axis=0)
plt.plot(share_sh, label='收盘沪指指数')
plt.plot(share_sh1, label='预测收盘沪指指数')
plt.plot(share_sz, label='收盘深证指数')
plt.plot(share_sz1, label='预测收盘深证指数')
plt.plot(share_close, label='收盘实际值')
plt.plot(share_vol, label='成交量实际值')
plt.plot(share_vol1, label='成交量预测值')
plt.plot(share_close1, label='收盘预测值')
plt.title('Test Loss')
plt.legend()
plt.show()
Результат прогноза начинается с оси абсцисс 14 на рисунке ниже, и прогноз продолжается в течение 15 дней. Во временном ряду входных данных в середине отмечаются китайские новогодние праздники, поэтому выбранный набор данных может оказаться неподходящим.
Примечание. Поскольку данные за первые 15 дней совпадают с входными, наложение на изображение делает линию немного темнее, а другую линию не видно.
4. Резюме
В последнее время наблюдение за тем, как акции продолжают падать, придало мне уверенности в том, что предварительные исследования для поведенческого анализа все еще имеют смысл.
Несколько скрытых слоев, несколько входных и выходных данных и модели прогнозирования LSTM с различными входными и выходными размерами по-прежнему практичны в анализе и прогнозировании поведения.Если в качестве входных данных использовать CNN или проектирование признаков, результаты будут лучше.
Для установки количества нейронов в ячейке RNN через несколько раундов тренировочной практики это обычно более чем в 10 раз превышает ввод, особенно когда количество наборов данных невелико, оно должно быть больше. Однако это повысит сложность тренировки, и цикл превратится в ситуацию.
Из-за ограниченного количества авторов обратная связь и обмен приветствуются.
Ссылаться на:
1".Что такое рекуррентная нейронная сеть LSTM》Не беспокойтесь о PYTHON, не беспокойтесь, ноябрь 2016 г.
2".Длина обучения и теста LSTM (batch_size) не совпадает с решением ошибки."Блог CSDN, Дэвид-Чоу, апрель 2019 г.
3."Подробное объяснение tf.nn.dynamic_rnn«Чжиху, Ин Чжун Ювэй, август 2018 г.
4."Исследование пользователей: как проводить анализ поведения пользователей?«Каждый является менеджером по продукту», Чжу Сюэминь, декабрь 2019 г.
5."Многомерное прогнозирование запасов временных рядов LSTM на основе Keras«Блог CSDN, Сяо Юнвэй, апрель 2020 г.
6."Использование LSTM в TensorFlow1.4» Блог 51CTO, mybabe0312, февраль 2019 г.
7."Расчет параметров в LSTM«Чжиху, Ичжэнь, декабрь 2018 г.