论文笔记|A CNN-BiLSTM-AM method for stock price prediction

0 Abstract

近年来,随着经济的快速发展,越来越多的人开始投资股票市场。准确预测股票价格的变化,可以降低股票投资者的投资风险,有效提高投资收益。由于股票市场的波动特征,股票价格预测往往是非线性的时间序列预测。股票价格受到多种因素的影响。很难通过一个简单的模型进行预测。因此,本文提出了一种CNN - BiLSTM - AM方法来预测未来一天的股票收盘价。该方法由卷积神经网络( CNN )、双向长短期记忆网络( Bi LSTM )和注意力机制( AM )组成。CNN用于提取输入数据的特征。Bi LSTM利用提取的特征数据预测次日股票收盘价。AM用于捕捉过去不同时刻特征状态对股票收盘价的影响,以提高预测精度。为了证明本文方法的有效性,采用本文方法和其他7种方法对上证综指1000个交易日的次日股票收盘价进行预测。结果表明,该方法的性能最好,MAE和RMSE均为最小的(分别为21.952和31.694)。R2是最大的(其值为0.9804)。与其他方法相比,CNNBiLSTM - AM方法更适用于股票价格的预测,为投资者进行股票投资决策提供了可靠的途径。

1 Introduction

股票市场是股票可以转让、交易和流通的场所。它已有400多年的历史,可以作为企业筹集资金的渠道[ 1 ]。通过发行股票,大量资本流入股票市场。这促进了资本的集中,提高了企业资本的有机构成,极大地推动了商品经济的发展。因此,股票市场被视为一个国家或地区经济金融活动的晴雨表。中国股票市场起步晚于西方股票市场。中国股票市场建立于20世纪90年代初。虽然中国股票市场起步较晚,但中国股票市场的市场规模和组织结构与西方股票市场相当。随着中国经济的快速发展,股票市场的规模迅速扩大,越来越多的人进入其中,参与股票投资[ 3、4]。

股票市场中投资者最为关注的问题之一就是股票价格的变化趋势[ 5 ]。股票价格受多种因素的影响,如国家政策的变化、国内外经济环境、国际形势等。[ 6、7]。股票价格的变化往往是非线性的。提前预测股价变动一直是经济学家[ 8、9]关注的重要问题。对股票价格的变化做出合理准确的预测,可以大大降低投资者的投资风险。这样的预测可以让投资者将预测的股票价格纳入他们的投资策略,并帮助投资者最大化他们的投资收益。

为了更准确地预测股票价格,本文提出了一种基于CNN - BiLSTM - AM的方法来预测次日的股票收盘价。该模型由卷积神经网络( CNN )、双向长短期记忆网络( Bi LSTM )和注意力机制( AM )组成。CNN可以从输入的股票数据中提取特征。长短期记忆网络( LSTM )是对循环神经网络( RNN )的改进,避免了RNN带来的梯度消失和梯度爆炸问题。Bi LSTM可以充分发现股票时间序列数据的相互依赖关系。AM是一种能够获得较好结果的机制,能够捕捉到时间序列数据过去的特征状态对股票价格的影响。

本文的主要贡献如下:( 1 )通过分析股票价格数据的时序性和相关性,提出了一种新的深度学习方法CNNBiLSTM - AM来预测次日的股票收盘价。( 2 )根据过去特征状态对次日股票收盘价的影响程度,可以对AM进行加权计算过去特征状态,从而提高预测的准确性。( 3 )通过与其他七种机器学习方法预测股票价格进行对比,证明了CNN - BiLSTM - AM方法是最准确有效的,说明其更适用于预测股票价格。

2 Related work

3 CNN-BiLSTM-AM

3.1 CNN-BiLSTM-AM

CNN具有关注视线中最明显特征的特点,因此被广泛应用于特征工程中。Bi LSTM具有按时间序列扩展的特性,被广泛应用于时间序列分析。AM具有将时间序列数据的过去特征状态添加到输出结果中的重要神经计算和应用。在BiLSTM之后,它被更广泛地用于调整预测结果。根据CNN、BiLSTM和AM的特点,建立了基于CNN - BiLSTM - AM的股票预测模型。模型结构图如图1所示。主要结构为CNN、Bi LSTM和AM,包括输入层、CNN层(一维卷积层、池化层)、Bi LSTM层(正向LSTM层,反向LSTM层)、AM层和输出层。

3.2 CNN

CNN主要由卷积层、池化层、全连接层三部分组成[ 29 ]。每个卷积层包含多个卷积核,其计算如式( 1 )所示。经过卷积层的卷积操作后,提取数据的特征。然而,提取的特征维度非常高。所以为了解决这个问题,降低训练网络的成本,在卷积层之后加入池化层来降低特征维度

其中lt为卷积后的输出值,tanh为激活函数,xt为输入向量,kt为卷积核的权重,bt为卷积核的偏置

3.3 LSTM

LSTM是一种旨在解决RNN中长期存在的梯度爆炸和梯度消失问题的网络模型[ 32 ]。标准RNN只有一个重复模块,内部结构简单。它通常是一个tanh层。

3.4 AM

AM是由Treisman等人在1980年提出的[ 36 ]。通过计算注意力概率分布,从大量信息中筛选出关键信息,突出关键输入,对传统模型进行优化。AM的主要思想来源于人类的视觉注意过程。人类视觉可以快速找到关键区域,并在关键区域中添加注意力焦点,以获得所需的详细信息。同样,AM选择性地关注一些比较重要的信息,忽略不重要的信息,并分配信息的重要性。如图3所示,

AM的计算过程一般分为三个阶段:

( 1 )计算Query (输出特征)和Key (输入特征)之间的相似度或相关性,如式( 8 )所示:

( 2 )对第一阶段的得分进行归一化处理,采用softmax函数对注意力得分进行转换,如式( 9 )所示:

( 3 )根据权重系数,对值进行加权求和得到最终的注意力值,如式( 10 )所示:

3.5 CNN-BiLSTM-AM Training Process

CNN - BiLSTM - AM训练过程如图4所示:

主要步骤如下:1 .输入数据:CNN - BiLSTMAM训练所需的数据输入2。输入数据标准化:由于输入数据存在较大差距,为了更好地训练模型,采用z - score标准化方法对输入数据进行标准化处理,如式( 11 )所示:

其中yi为标准化值,xi为输入数据,x为输入数据的平均值,s为输入数据的标准差。

( 3 )网络初始化:对CNN - BiLSTM - AM的每一层的权值和偏置进行初始化。

( 4 ) CNN层计算:输入数据依次经过CNN层内的卷积层和池化层,对输入数据进行特征提取,得到输出值。

( 5 ) BiLSTM层计算:通过BiLSTM层的隐含层计算CNN层的输出数据,得到输出值。

( 6 ) AM层计算:将BiLSTM层的输出数据通过AM层计算,得到输出值。

( 7 )输出层计算:计算AM层的输出值,得到模型的输出值。

( 8 )计算误差:将输出层计算得到的输出值与该组数据的真实值进行比较,计算相应的误差。

( 9 )判断是否满足预测过程的结束条件:成功结束的条件是完成预定的循环次数,权重低于某一阈值,预测的错误率低于某一阈值。如果至少满足结束的其中一个条件,则训练完成。否则,训练将继续进行。

( 10 )误差反向传播:将计算出来的误差反向传播,更新每一层的权重和偏置,然后回到步骤( 4 )继续进行网络训练。

3.6 CNN-BiLSTM-AM Prediction Process

CNN - BiLSTM - AM预测的前提条件是CNN - BiLSTM - AM已经完成训练。CNNBiLSTM - AM预测流程如图5所示。

主要步骤如下:

( 1 )输入数据:输入预测所需的输入数据。

( 2 )输入数据标准化:根据公式( 11 )对输入数据进行标准化。

( 3 )预测:将标准化后的数据输入到训练好的CNN - BiLSTM - AM中,得到相应的输出值。

( 4 )数据标准化恢复:通过CNN - BiLSTM - AM得到的输出值即为标准化值。利用公式( 12 )将标准化值还原为原始值:

其中xi为标准化恢复值,yi为CNN - BiLSTM - AM的输出值,s为输入数据的标准差,x为输入数据的平均值。

( 5 )输出结果:输出恢复结果,完成预测过程。

4 Experiments

4.1 数据

本实验选取上证综合指数( 000、001)股票作为实验数据。从wind数据库中获取1991年7月1日至2020年6月30日共7083个交易日的日交易数据。每条数据包含8项:开盘价、最高价、最低价、收盘价、成交量、成交量、涨跌幅、变化幅度。部分数据如表1所示。本实验将前6083个交易日的数据作为训练集,后1000个交易日的数据作为测试集。

这里的开盘价是一个交易日(在证券交易所开业后)的首个成交股价。最高价是指一只股票从开盘到收盘的每个交易日的最高价。最低价是指某只股票从开盘到收盘的每个交易日的最低价。收盘价是指股票当日最后一次交易前1分钟每笔交易的加权平均交易量价格。成交量是指当日交易的股票总数。成交金额是指当天交易的所有股票的总股数。涨跌是指股票价格的变化量。变化是指当前交易日收盘价与前一交易日收盘价的值相比发生的变化;这个值一般用百分比表示。

4.2 模型

实现本实验CNN - Bi LSTM - AM模型的参数设置如表2所示。在本实验中,所有方法训练参数相同,历元为100,损失函数为MAE,优化器选择Adam,批大小为64,时间步长为5,学习率为0.001。这样做是为了提高方法的预测精度。

未来的研究工作将主要对模型中的参数进行调整,使结果更加准确。未来的研究工作还将研究该模型能否应用于更多的时间序列预测应用领域,如黄金价格预测、石油价格预测、天气预报、地震预测等。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 以下是一个基于TensorFlow框架的CNN-BILSTM-CRF实体识别Python代码示例: ``` import tensorflow as tf from tensorflow.keras import Model, Input from tensorflow.keras.layers import Embedding, Conv1D, LSTM, Bidirectional, TimeDistributed, Dense, Dropout from tensorflow.keras_contrib.layers import CRF # 定义模型 class NERModel(Model): def __init__(self, num_tags, vocab_size, embedding_size, conv_filters, lstm_units, dropout_rate): super(NERModel, self).__init__() self.embedding = Embedding(input_dim=vocab_size, output_dim=embedding_size, mask_zero=True) self.conv1d = Conv1D(filters=conv_filters, kernel_size=3, padding='same', activation='relu') self.bilstm = Bidirectional(LSTM(units=lstm_units, return_sequences=True)) self.dropout = Dropout(rate=dropout_rate) self.dense = TimeDistributed(Dense(units=num_tags)) self.crf = CRF(num_tags) def call(self, inputs): embeddings = self.embedding(inputs) conv_output = self.conv1d(embeddings) lstm_output = self.bilstm(conv_output) dropout_output = self.dropout(lstm_output) dense_output = self.dense(dropout_output) crf_output = self.crf(dense_output) return crf_output # 模型参数 num_tags = 5 vocab_size = 10000 embedding_size = 100 conv_filters = 128 lstm_units = 64 dropout_rate = 0.5 # 构建模型 input_layer = Input(shape=(None,)) ner_model = NERModel(num_tags=num_tags, vocab_size=vocab_size, embedding_size=embedding_size, conv_filters=conv_filters, lstm_units=lstm_units, dropout_rate=dropout_rate) output_layer = ner_model(input_layer) model = Model(inputs=input_layer, outputs=output_layer) # 编译模型 model.compile(optimizer='adam', loss=ner_model.crf.loss_function, metrics=[ner_model.crf.accuracy]) # 训练模型 model.fit(train_X, train_y, validation_data=(val_X, val_y), epochs=10, batch_size=32) # 预测模型 pred_y = model.predict(test_X) ``` 需要注意的是,这只是一个基本的模型代码示例,具体实现可能会因为数据集、特征等因素而有所不同。此外,代码还需要调整以适应你的数据和模型需求。 ### 回答2: 实体识别是自然语言处理中的重要任务,CNN-BILSTM-CRF模型是一种常用于实体识别的深度学习模型。以下是一个简单的使用Python编写的CNN-BILSTM-CRF实体识别代码示例: ``` import numpy as np import tensorflow as tf import keras from keras.models import Model from keras.layers import Dense, Embedding, Input, Dropout, Conv1D, Bidirectional, LSTM, TimeDistributed from keras_contrib.layers import CRF from keras_contrib.metrics import crf_accuracy from keras.preprocessing.sequence import pad_sequences from sklearn.model_selection import train_test_split # 准备数据 def prepare_data(sentences, labels, word_index, label_index, max_len): X = [] y = [] for sentence, label in zip(sentences, labels): # 转换句子和标签为索引序列 x = [word_index[word] for word in sentence] y = [label_index[label] for label in label] X.append(x) y.append(y) # 填充序列到相同长度 X = pad_sequences(X, maxlen=max_len) y = pad_sequences(y, maxlen=max_len) return X, y # 构建模型 def build_model(vocab_size, max_len, num_classes): input_layer = Input(shape=(max_len,)) embedding_layer = Embedding(vocab_size, 128, mask_zero=True)(input_layer) conv1d_layer = Conv1D(64, 3, activation='relu', padding='same')(embedding_layer) dropout_layer = Dropout(0.5)(conv1d_layer) bilstm_layer = Bidirectional(LSTM(128, return_sequences=True))(dropout_layer) dense_layer = Dense(num_classes, activation='softmax')(bilstm_layer) crf_layer = CRF(num_classes)(dense_layer) model = Model(inputs=input_layer, outputs=crf_layer) model.compile(optimizer='adam', loss=crf.loss_function, metrics=[crf.accuracy]) return model # 加载数据和标签 sentences = ['这 是 一个 实体 识别 例子', '这 是 另一个 实体 识别 例子'] labels = [['O', 'O', 'O', 'B-Entity', 'I-Entity', 'O'], ['O', 'O', 'B-Entity', 'I-Entity', 'O']] # 构建词汇表和标签表 words = set([word for sentence in sentences for word in sentence.split()]) word_index = {word: index + 1 for index, word in enumerate(words)} word_index['PAD'] = 0 labels = set([label for label_list in labels for label in label_list]) label_index = {label: index for index, label in enumerate(labels)} # 准备训练集和测试集 X, y = prepare_data(sentences, labels, word_index, label_index, max_len=10) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) # 构建模型 model = build_model(len(word_index), X.shape[1], len(label_index)) # 训练模型 model.fit(X_train, y_train, validation_data=(X_test, y_test), batch_size=16, epochs=10) # 预测样本 test_sentence = '这是一个实体识别测试样本' test_data = np.array([word_index[word] for word in test_sentence.split()]).reshape(1, -1) prediction = model.predict(test_data) predicted_labels = [label_index[label] for label in np.argmax(prediction, axis=-1)[0]] actual_labels = ['O'] * len(predicted_labels) # 输出预测结果 for word, label in zip(test_sentence.split(), predicted_labels): print(word, label) ``` 此代码使用Keras建立了一个CNN-BILSTM-CRF模型,并使用CRF作为输出层。首先根据训练数据准备好词汇表和标签表,然后对训练样本进行编码并将其填充到相同长度。接下来构建模型,编译并训练模型。训练完成后,可以用新的样本进行预测,并输出预测结果。请注意,此代码仅提供了一个简单的示例,实际应用中可能需要进一步优化网络结构和超参数。 ### 回答3: 为了回答这个问题,我将提供一个简单的CNN-BiLSTM-CRF实体识别的Python代码示例。在这个示例中,我们将使用Keras库来构建模型。 首先,我们需要导入所需的库: ```python import numpy as np from keras.models import Model from keras.layers import Input, Embedding, Conv1D, LSTM, TimeDistributed, Dense, Bidirectional, Dropout from keras_contrib.layers import CRF from keras.preprocessing.sequence import pad_sequences from keras_contrib.utils import save_load_utils ``` 接下来,我们定义一个函数来准备我们的数据集。这个函数将接受输入的句子列表和对应的实体标签列表,并将它们转换成适合模型输入的形式。 ```python def prepare_data(sentences, labels): word2idx = {w: i + 1 for i, w in enumerate(set([word for sentence in sentences for word in sentence]))} word2idx['PAD'] = 0 label2idx = {'O': 0, 'B': 1, 'I': 2} max_sequence_length = max([len(sentence) for sentence in sentences]) X = [[word2idx[word] for word in sentence] for sentence in sentences] y = [[label2idx[label] for label in sentence] for sentence in labels] X = pad_sequences(X, maxlen=max_sequence_length) y = pad_sequences(y, maxlen=max_sequence_length, value=label2idx['O']) y = np.eye(len(label2idx))[y] return X, y, word2idx, label2idx ``` 然后,我们定义CNN-BiLSTM-CRF模型: ```python def create_model(max_sequence_length, num_words, num_labels): input_text = Input(shape=(max_sequence_length,)) model = Embedding(input_dim=num_words, output_dim=100, input_length=max_sequence_length)(input_text) model = Dropout(0.2)(model) model = Conv1D(filters=100, kernel_size=3, padding='same', activation='relu')(model) model = Dropout(0.2)(model) model = Bidirectional(LSTM(units=100, return_sequences=True))(model) model = TimeDistributed(Dense(100, activation="relu"))(model) model = CRF(units=num_labels)(model) model = Model(input_text, model) model.compile(optimizer="rmsprop", loss=CRF.loss_function, metrics=[CRF.accuracy]) return model ``` 最后,我们准备数据并训练模型: ```python sentences = [['I', 'love', 'to', 'eat', 'pizza'], ['She', 'works', 'at', 'a', 'bank']] labels = [['O', 'O', 'O', 'O', 'B'], ['O', 'O', 'O', 'O', 'B']] X, y, word2idx, label2idx = prepare_data(sentences, labels) num_words = len(word2idx) num_labels = len(label2idx) model = create_model(X.shape[1], num_words, num_labels) model.fit(X, y, epochs=10, batch_size=1) save_load_utils.save_all_weights(model, 'entity_recognition_model.h5') ``` 以上是一个简单的CNN-BiLSTM-CRF实体识别的Python代码示例。请注意,这只是一个示例,具体的实现可能根据数据集的不同而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值