内容简介:相信大家这几天或多或少的都开始关注到股市了,虽然我还不是很懂里面的一些套路,但是从最近各个公众号的推送里面,我也看到最近的股市确实是形势大好。对很多人来说,股票就和房价一样,他的升与降牵动着众多人的心。这几天很多qq群、微信群都开始讨论起股票了,各位坊间大神也纷纷开始预测各种股票走势了。股票价格是典型的时间序列数据(简称时序数据),会受到经济环境、政府政策、人为操作多种复杂因素的影响,所以说股票价格预测是一件非常唬人的事情。但是基于历史数据,以股票价格为例,介绍如何对时序数据进行预测,仍然值得一做。不过今天
相信大家这几天或多或少的都开始关注到股市了,虽然我还不是很懂里面的一些套路,但是从最近各个公众号的推送里面,我也看到最近的股市确实是形势大好。对很多人来说,股票就和房价一样,他的升与降牵动着众多人的心。这几天很多qq群、微信群都开始讨论起股票了,各位坊间大神也纷纷开始预测各种股票走势了。
股票价格是典型的时间序列数据(简称时序数据),会受到经济环境、政府政策、人为操作多种复杂因素的影响,所以说股票价格预测是一件非常唬人的事情。但是基于历史数据,以股票价格为例,介绍如何对时序数据进行预测,仍然值得一做。
不过今天我们不聊股市,因为我也不是很懂,今天我们来聊聊我们知道的东西。如今深度学习在金融市场的应用越来越广泛,我们能否利用已有的历史数据通过深度学习的方式来进行预测呢?
准备工作
答案自然是可以的,虽然我们无法非常准确的进行预测,但是作为一个深度学习入手的项目是完完全全可以的。
实验环境
老样子,以免出现因环境导致的问题,先将实验环境列出:
- MacOS 10.14.3
- Python 3.6.8(Anaconda)
- Jupyter Notebook
- 使用的包有:
- TensorFlow
- Keras
- matplotlib
- pandas
数据
此次实验,我们采用 STATWORX 的 S&P 500
股价数据,该数据集爬取自Google Finance API,已经进行过缺失值处理。他们的官方网站是:www.statworx.com/。
数据集可在微信公众号:「01二进制」后台回复:「股市数据集」获取
数据预览
在这里我们还是使用pandas,主要用于数据清洗和整理
import pandas as pd data=pd.read_csv('data/data_stocks.csv') data.info() 复制代码
执行 data.info()
可以查看特征的概要:
<class 'pandas.core.frame.DataFrame'> RangeIndex: 41266 entries, 0 to 41265 Columns: 502 entries, DATE to NYSE.ZTS dtypes: float64(501), int64(1) memory usage: 158.0 MB 复制代码
从上述结果可知:该数据集数据共502列,41266行,502列分别为:
DATE SP500
查看数据的前五行
data.head() 复制代码
绘制大盘趋势折线图
plt.plot(data['SP500']) 复制代码
结果如下:
Tips:此次实验的调试环境为Jupyter Notebook,我们最好在开头导入 matplotlib
包的时候在加一行 %matplotlib inline
,这样就可以在Jupyter Notebook中内嵌绘图,并且省略掉plt.show()这一步。
数据整理
在这里,我们需要将数据集分为训练和测试数据。分配比为8:2,即训练数据包含总数据集的80%。当然在这之前我们需要先将 DATE
这个无关变量舍去。
data.drop('DATE', axis=1, inplace=True) data_train = data.iloc[:int(data.shape[0] * 0.8), :] data_test = data.iloc[int(data.shape[0] * 0.8):, :] 复制代码
我们来查看一下训练集和测试集的 shape
:
数据归一化
将属性缩放到一个指定的最大和最小值(通常是(-1,1))之间,这可以通过 sklearn.preprocessing.MinMaxScaler
类实现。
使用这种方法的目的包括:
-
对于方差非常小的属性可以增强其稳定性。
-
维持稀疏矩阵中为0的条目。
scaler = MinMaxScaler(feature_range=(-1, 1)) scaler.fit(data_train) data_train = scaler.transform(data_train) data_test = scaler.transform(data_test) 复制代码
预测
在此次预测过程中,我采用TensorFlow这个深度学习框架,它是目前领先的深度学习和神经网络计算框架。这一部分推荐 有基础的人 阅读,在这推荐我还在整理的TensorFlow系列,有兴趣的可以了解下。
这里我们需要解决的问题是: 使用当前时刻的500支个股股价,预测当前时刻的大盘指数 。即一个回归问题, 输入共500维特征,输出一维 ,即 [None, 500] => [None, 1]
设置X与Y
X_train = data_train[:, 1:] y_train = data_train[:, 0] X_test = data_test[:, 1:] y_test = data_test[:, 0] 复制代码
这里的x和y是已经分类好的数据集,只是用X和Y两个变量表示,可以理解为函数里面的X和Y。
设置超参数
input_dim = X_train.shape[1] output_dim = 1 hidden_1 = 1024 hidden_2 = 512 hidden_3 = 256 hidden_4 = 128 batch_size = 256 epochs = 10 复制代码
这里我们设置了几个超参数, input_dim
表示输入数据的维度,即500。 output_dim
表示输出数据的维度,即1。在该模型中设置了4层隐藏层,第一层包含1024个神经元,略大于输入大小的两倍。 后续的隐藏层总是前一层的一半大小,即分别为512,256和128个神经元。 每个后续层的神经元数量的减少压缩了网络在先前层中识别的信息。 当然,其他网络架构和神经元配置也是可能的,只是由于本文只是一个入门的项目所以并未深究。
在机器学习中, 超参数 是在开始学习过程之前设置值的参数,而不是通过训练得到的参数数据。通常情况下,需要对超参数进行优化,给学习机选择一组最优超参数,以提高学习的性能和效果。
设置占位符(placeholder)
X = tf.placeholder(shape=[None, input_dim], dtype=tf.float32) Y = tf.placeholder(shape=[None], dtype=tf.float32) 复制代码
为了适应我们的模型,我们需要两个占位符:X(神经网络的输入)和Y(神经网络的输出)。
设置神经网络
根据之前设置好的超参数进行神经网络的配置,其中 w 为权重, b 为偏置值
# 第一层 W1 = tf.get_variable('W1', [input_dim, hidden_1], initializer=tf.contrib.layers.xavier_initializer(seed=1)) b1 = tf.get_variable('b1', [hidden_1], initializer=tf.zeros_initializer()) # 第二层 W2 = tf.get_variable('W2', [hidden_1, hidden_2], initializer=tf.contrib.layers.xavier_initializer(seed=1)) b2 = tf.get_variable('b2', [hidden_2], initializer=tf.zeros_initializer()) # 第三层 W3 = tf.get_variable('W3', [hidden_2, hidden_3], initializer=tf.contrib.layers.xavier_initializer(seed=1)) b3 = tf.get_variable('b3', [hidden_3], initializer=tf.zeros_initializer()) # 第四层 W4 = tf.get_variable('W4', [hidden_3, hidden_4], initializer=tf.contrib.layers.xavier_initializer(seed=1)) b4 = tf.get_variable('b4', [hidden_4], initializer=tf.zeros_initializer()) # 输出层 W5 = tf.get_variable('W5', [hidden_4, output_dim], initializer=tf.contrib.layers.xavier_initializer(seed=1)) b5 = tf.get_variable('b5', [output_dim], initializer=tf.zeros_initializer()) 复制代码
了解输入层,隐藏层和输出层之间所需的变量尺寸非常重要。作为多层感知器(MLP,这里使用的网络类型)的一个经验法则,前一层的第二维是当前层中权重矩阵的第一维。这可能听起来很复杂,但实质上只是每个图层都将其输出作为输入传递到下一图层。偏差维度等于当前图层的权重矩阵的第二维度,其对应于该层中的神经元的数量。
设置网络体系结构
在定义所需的权重和偏置变量后,需要指定网络拓扑结构和网络结构。因此,占位符(数据)和变量(权重和偏置)需要组合成一个连续矩阵乘法系统。
h1 = tf.nn.relu(tf.add(tf.matmul(X, W1), b1)) h2 = tf.nn.relu(tf.add(tf.matmul(h1, W2), b2)) h3 = tf.nn.relu(tf.add(tf.matmul(h2, W3), b3)) h4 = tf.nn.relu(tf.add(tf.matmul(h3, W4), b4)) out = tf.transpose(tf.add(tf.matmul(h4, W5), b5)) 复制代码
此外,网络的隐藏层需要被激活函数激活。激活函数是网络体系结构的重要组成部分,因为它们将非线性引入到系统中。这里采用最常见的ReLU激活函数。
下图说明了网络架构。 该模型由三个主要构建块组成。 输入层,隐藏层和输出层。 该体系结构称为前馈网络。 前馈表示该批数据仅从左向右流动。 其他网络架构,例如递归神经网络,也允许数据在网络中“向后”流动。
设置损失函数(loss function)和优化器(Optimizer)
loss = tf.reduce_mean(tf.squared_difference(out, Y)) optimizer = tf.train.AdamOptimizer().minimize(loss) 复制代码
这一部分没啥好说的,记住这么写就可以了,想了解的话可以去我的TensorFlow中了解下。
执行训练过程
在定义好神经网络的占位符,结构,损失函数函数和优化器之后,我们就可以开始对模型进行训练了。训练数据集分为n / batch_size批次,这些批次按顺序送入网络。 此时占位符X和Y开始起作用。 它们存储输入和目标数据,并将它们作为输入和目标呈现给网络。
数据X分批次流经网络,直到到达输出层。 在那里,TensorFlow将模型预测与当前批次中实际观察到的目标Y进行比较。 之后,TensorFlow进行优化步骤并更新与所选学习方案相对应的网络参数。 更新了权重和偏差后,对下一批进行采样,并重复该过程。 该过程将继续,直到所有批次都已呈现给网络。对所有数据进行一次全面扫描被称为一个 epoch(轮) 。
一旦达到了最大数量的epochs或用户定义的另一个停止标准,网络的训练就会停止。
with tf.Session() as sess: # 初始化所有变量 sess.run(tf.global_variables_initializer()) for e in range(epochs): # 将数据打乱 shuffle_indices = np.random.permutation(np.arange(y_train.shape[0])) X_train = X_train[shuffle_indices] y_train = y_train[shuffle_indices] for i in range(y_train.shape[0] // batch_size): start = i * batch_size batch_x = X_train[start : start + batch_size] batch_y = y_train[start : start + batch_size] sess.run(optimizer, feed_dict={X: batch_x, Y: batch_y}) if i % 50 == 0: print('MSE Train:', sess.run(loss, feed_dict={X: X_train, Y: y_train})) print('MSE Test:', sess.run(loss, feed_dict={X: X_test, Y: y_test})) y_pred = sess.run(out, feed_dict={X: X_test}) y_pred = np.squeeze(y_pred) plt.plot(y_test, label='test') plt.plot(y_pred, label='pred') plt.title('Epoch ' + str(e) + ', Batch ' + str(i)) plt.legend() plt.show() 复制代码
运行结果为:
MSE Train: 9.56518e-05 MSE Test: 0.0025863606 MSE Train: 6.0618047e-05 MSE Test: 0.0025002975 MSE Train: 0.00014856807 MSE Test: 0.0017371146 MSE Train: 0.00016200903 MSE Test: 0.0025396077 MSE Train: 0.00010259051 MSE Test: 0.0030134947 MSE Train: 7.979905e-05 MSE Test: 0.0023832247 MSE Train: 5.92488e-05 MSE Test: 0.0032762515 MSE Train: 8.747634e-05 MSE Test: 0.004848172 MSE Train: 8.5051965e-05 MSE Test: 0.0032768336 复制代码
最后测试集的loss在0.003左右,可以说是比较精确了。
可视化训练结果:
有很多方法可以进一步改善这一结果:增加隐藏层和改进神经元的设计,选择不同的初始化和激活方案,提前停止等等。 此外,不同类型的深度学习模型,例如循环神经网络,可以在此任务上实现更好的性能。 但是,这不是这篇介绍性文章的范围。有兴趣的小伙伴可以自行查找资料。
结论
正如开头所说,股票的价格会受到经济环境、政府政策、人为操作多种复杂因素的影响,真正想要预测股市走向单靠这篇文章里面所叙述的远远不够,本文旨在结合时下热点进行一次有关TensorFlow的技术推荐。
TensorFlow的发布是深度学习研究中的一个里程碑事件。作为一个学生,笔者也在积极的学习中,有兴趣学习的小伙伴可以在公众号后台(就是文末的那个公众号)回复「 TensorFlow视频 」获取一份质量较高的TensorFlow视频,也可以添加我的微信一起交流进步。
完整源码可在微信公众号:「01二进制」后台回复:「股市分析」获取
参考资料
“万水千山都是情,给个关注行不行:point_down:”
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 用Python做股市数据分析
- 用代码说话!机器学习能预测股市吗?
- 股市风起云涌,我用Python分析周期之道
- 一棵韭菜的自我修养:用Python分析下股市,练练手
- 驰骋股市!手把手教你如何用Python和数据科学赚钱?
- 沈向洋:从深度学习到深度理解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Metasploit渗透测试魔鬼训练营
诸葛建伟、陈力波、田繁、孙松柏、等 / 机械工业出版社 / 2013-9-1 / 89.00元
首本中文原创Metasploit渗透测试著作,国内信息安全领域布道者和资深Metasploit渗透测试专家领衔撰写,极具权威性。以实践为导向,既详细讲解了Metasploit渗透测试的技术、流程、方法和技巧,又深刻阐释了渗透测试平台背后蕴含的思想。 本书是Metasploit渗透测试领域难得的经典佳作,由国内信息安全领域的资深Metasploit渗透测试专家领衔撰写。内容系统、广泛、有深度,......一起来看看 《Metasploit渗透测试魔鬼训练营》 这本书的介绍吧!