作者在自学机器学习的过程中,尝试开发了一个基于机器学习的A股选股工具。本文是在赤兔的“数据挖掘”小组分享的此次开发过程和心得体会的整理。
股票价格的可预测性——工具的意义
关于股票价格的可预测性,我想引入有效市场假说(EMH)。大致的意思就是像股市这样的系统,所有的信息都应该反映在价格变化里面了。
基于此,因为基本面、政策面信息已经囊括在价格变化里面了,单纯从技术面做分析理论上是可行的。不过目前确实还没有任何一种工具或者技术能完全预测和战胜市场。
就选股工具而言,因为股票的数目众多,每天都有新的变化,其目的主要是替代一部分人工重复劳动,节约成本。没有“砖家”可以完全预测股价,虽然工具也不太可能,但是只要做到和人一样好,甚至更好,就有价值。
A股选股器开发过程
数据来源
就财经类的数据而言,现在各大门户网站都有专门的频道,信息很多,如果对实时要求高,通过爬虫取其中有用的部分应该是一个办法。
另外,通过搜索引擎,可以发现前辈们总结出的一些public的接口,也可以取到一些数据。我在开发这个工具的时候用的是叫做tushare的一个python接口。它是免费的,提供结构化的数据,感觉每天更新也挺快。
预处理
拿到数据后第一步是做预处理。我认为股票的数据主要是做归一化,使得不同股票具有可比性。比如涨幅百分比,复权等等。
“复权”的意思是:股票除权、除息之后,股价会发生较大幅度的跃变,这种看似价格变化,实际持股成本并不变化。复权就是对股价和成交量进行权息修复。
数据拿到后,因为只会有1张表,因此选择了一个NoSQL数据库来存储。大概8年2000多只股票,有300万条数据左右。
传统算法建模
建模的第一步尝试是基于传统的算法。首先是选取和计算特征值,涨幅,交易量,boll指标,横盘状态等等。关于这些指标的含义,有兴趣的朋友可以去搜索一下,都不太难,用基本的统计学知识就可以计算。
这些特征值都有以后,可以基于人为经验设计一些基本的过滤器,比如PPT中的图片就描述了一种可能的筛选条件。
我相信证券专业人士一定有更好的基于经验的筛选条件,希望也可以分享出来我学习下。但是在我的实验中,基于人的经验来设计过滤器,准确率并不高,50%多一点,也就是比随机的选股稍微好一点。
机器学习建模
接下来考虑选取合适的机器学习算法。机器学习的算法很多,对于算法选取,我的考虑主要是这样的。
线性回归模型偏简单,而股市不应该是线性的。
因为非线性,支持向量机(SVM)的核函数和参数的选取也会比较难。
对于神经网络,确实是在财经领域用的很多的算法,当初没有选择因为自己的计算资源有限,担心训练的难度较大。
最终选择用决策树的原因是模型算法都比较成熟,训练的计算复杂度也在自己可接受范围内。
对算法有研究的朋友欢迎评论本文,一起探讨下。
决策树建模
对决策树算法,我沿用了传统算法的特征值,也就是对于描述模型的数据指标,和传统算法是一样的。
样本训练用了WEKA这个工具,具体算法选择的是C4.5。决策树的算法确实也有多种选择,C4.5是其中一种比较成熟的算法。
上面截图里面是训练出的其中一棵决策树,python描述的,代码有60000多行。
验证模型
先说准确率。某一个交易日的准确率等于,工具预测的股票在下一个交易日确实上涨的个数占总的推荐股票个数的比例。对若干个交易日的准确率取一个平均,可以得到模型的准确率。
而召回率在这里是工具预测的股票在下一个交易日确实上涨的个数占整个股市中股票上涨个数的比例。应该不难理解,对于选股工具我们应该更关心准确率。
改进模型
为了提高准确率,在开发过程中,我做了下面这些改进尝试:
一个是扩大样本。最初是用了最近3年的数据,后来考虑到A股从2007年到2015年恰好走过了一个上涨到下降再到上涨的完整周期,因此扩大到了8年的数据。
再是对算法的改进,我尝试引入了“推荐指数”的概念。因为本来决策树只做分类,而利用推荐指数可以看得出来哪些更好,哪些是一般好。
还有是考虑对样本进行分类训练,比如按照板块,行业等等,因为有理由认为同一类股票的价格变化规律会更为接近。
请大家先看看上图右边的表格的黑色字体部分。大部分交易日的准确率在80%以上。因此相比于传统算法,效果确实好了一些。
然后可以注意一下表格红色字体的日期。其实这些红色的日期,有相当一部分是股灾日。股灾日经常是“千股跌停”,上涨的股票太少了…可以看出在这些“股灾日”的时候,模型也不太准确,出现了失真。
总结与心得
选股工具利用机器学习算法,一般情况下比传统的算法(或者人为经验)的准确率高。
推荐的股票虽然不一定都会上涨,但是其实人工再去看的话,也会发现他们的曲线和指标看起来是确实不错的(尽管谁都不确定下一个交易日是涨还是跌)。
所以我认为,本工具帮助人每天去海量的筛选股票应该是可行的,短线操作人员可以基于本工具的推荐再做进一步的综合决策。
最后是一些心得体会分享给大家:
第一,我觉得建模的特征值选取其实挺关键的,如果以后要做进一步的改进或者开发别的系统,我会花更多时间来做这个。
第二,股灾日的模型失真与数据颗粒度的关系。本工具旨在做短线推荐,即推荐下一交易日上涨概率较大的股票。
我的数据都是以交易日为单位的,所以很难体现较短时间内的信号变化,比如突然的跟风抛售会造成放量下跌。如果提高颗粒度到小时或者分钟,也许会更好些,不过那样数据量也会multiply。
第三,股票每天都有新的数据进来,如何使用这些增量数据而不用重新训练,这个可能是未来需要考虑的问题。
我以前看到过有增量的决策树以及增量学习的神经网络,有可能更加适用。
第四,开发过程中碰到了python的解析器的局限,读取决策树的时候程序crash,后来想办法绕开了。
由于是工作之余做的,我能够花在整个项目的时间还是很有限。边学边写,比较仓促。