利用CNN对股票“图片”进行涨跌分类——一次尝试

深度学习
cnn
卷积神经网络
精选
标签: #<Tag:0x00007f75fd58a910> #<Tag:0x00007f75fd58a7d0> #<Tag:0x00007f75fd58a668> #<Tag:0x00007f75fd58a500>

(Arthas) #1

首先解释一下标题:
CNN:卷积神经网络(Convolutional Neural Network), 在图像处理方面有出色表现,不是被川普怒怼的那个新闻网站;
股票涨跌:大家都懂的,呵呵;
股票图片:既然使用CNN,那么如果输入数据是股票某个周期的K线图片就太好了。当然,本文中使用的图片并不是在看盘软件上一张一张截下来的,而是利用OHLC数据“画”出来的;
尝试:这个词委婉一点说就是“一个很好的想法^_^",比较直白的说法是“没啥效果T_T”。


进入正题:
首先是画出图片。本文目前是仿照柱线图画的。

大致的想法是:

  1. 对每个样本,将32time_steps×4features(OHLC)数据归一化处理,即所有取值均在[0,1]之间;
  2. 构建一个128×128像素的全0数组,将[0,1]区间等分为128份,分到每列的128个像素点上;
  3. 然后使用每四列构建一根K线(前三列画柱状线,第四列作为间隔行):第一列描绘开盘价,开盘价与该列的哪个像素点最近,那么这个像素点取值就由0变为1;第二列描绘高低价区间,将 最高价至 最低价 范围内的像素点取值由0变为1;第三列描绘收盘价,收盘价与该列的哪个像素点最近,那么这个像素点取值就由0变为1。

这样每个样本就构建了一张由32根K线组成,类似柱线图的“图片”,下面是一个样本画的一张图(为了便于观看,将0替换成空格,将1替换成圆点):


其实还蛮像柱线图的。

测试阶段:
原始数据:最终选择的数据是100只2005年以前上市的股票。1只股票数据太少,全部股票数据又太多,所以 股票三千,我只取一百;“上市时间前于2005年”这个条件 主要考虑在每只股票上取样数量不会太少。

生成样本:每只股票每32根K线生成一个样本,每隔8根K线取一次样。然后按照上述作图方法将其变成图片。标签:若未来五日收益为正,标签为[1,0],否则,标签为[0,1]。15年1月1日之前数据用作train和evaluate,之后数据用作test。

构建模型:本文所用模型共5层,先后顺序为 卷积层-池化层-卷积层-池化层-全连接层,中间还夹杂了两个Dropout和一个Flatten,用来防止过拟合和一维化数据,不过由于他们是无权重的,所以没将他们算作一层。

预测效果
在train和evaluate阶段,看起来还是不错的:

但是在test阶段:

第一个值是loss,第二个值是准确率,不要看反。。。呵呵

听说有一种很厉害的操作——去除label不明显的样本——可能会提高模型效果。所以本文又对训练样本进行了一次筛选,只保留了未来五日收益在最前30%和最后30%的样本。然后input到模型做训练。最终test集上效果:

有(mei)所(sha)改(xiao)善(guo)!

问题分析
目前发现的一个问题:一幅图中被标记的像素点太少了。下面两张图为train-evaluate样本和test样本中值为1的像素点占总像素点(128×128=16384)比重的分布。

值为1的像素点占总像素点比重平均不到5%,最大的比重也未超过10%。这说明在模型训练阶段有些像素点对应的weights仅仅被训练了很少的次数甚至未经训练,这影响了模型在test数据上的表现。之后可能会针对这一问题做一些改进,以增加每张图值为1的像素点占总像素点比例

代码部分
欢迎讨论!
https://i.bigquant.com/user/nsc/lab/share/CNN%20股票预测-share.ipynb?v=2


(stalkerggyy) #2

想法很好,但是切入的点不太合适。我觉得其实目前的各种技术指标,就是从图形中提取更有价值的特征,直接从图形学习来预测,可能还是有些太模糊了。


(shinefuture) #3

楼主可以尝试下 LSTM 模型,这个更适合股票


(Arthas) #4

嗯,目前来看处理时间序列数据LSTM确实比CNN好


(qqqxxx99) #5

的确是好想法! 赞


(xuqiang) #6

1.感谢楼主分享

2.个人想法(我知之甚少,权且供大家探讨)
如果把k线图,换为均线的频谱图(建议用小波包),做带通滤波的预处理,效果可能好一些


(Arthas) #7

嗯嗯,有很多可以修改的地方。
代码已分享,你可以克隆后进行多角度的修改和尝试,脑洞大开的时候到了~~~


(Miles) #8

赞,谢谢楼主!楼主,二次尝试是不是做个CNN + LSTM啊? 期待!


(xfcxfc0312) #9

楼主用CNN来预测的什么呀??输入输出是什么,然后用哪些原始数据经过什么计算得到的


(PAYNE) #10

简单粗暴…… 直接预测图形……

这个想法可以和分形理论结合还有hurst 函数加在一起做试试吧


(lu0817) #11

大神,很想请教下.怎么把走势数据做成图片数据


(mhzdlm) #12

我做过类似的思路。比你效果稍微好点。你这个实验的主要问题在,1、不应该用这么小的图片,基本数据信息都被压缩没了。2、不该用这么浅的cnn,基本提不出什么有效信息。当然还有很多可以改进的地方,但是最明显的问题显然是这两点。


(HYL25537) #13

可以请教一下,代码中
wholeinstruments = D.history_data(D.instruments(start_date=‘2017-07-03’, end_date=‘2017-07-03’) , start_date=‘2017-07-03’, end_date=‘2017-07-03’, fields=[‘list_date’])
这个D是引用的哪个包嘛,初学python,想先跑一下这套demo在慢慢吃透


(iQuant) #14

您好,可以参考文档板块:https://bigquant.com/docs/index.html


(YYIFAN) #15

请问df_to_picture这个函数里output_x生成的“图片”为什么不止128*128,而是有三个维度的呢?


(lymzzu) #16

我觉得方向没有问题,是不是还要考虑一些细节。我这正准备做这方面的尝试。