机器学习在金融比赛中的应用

 
  

 
  

原文:http://www.jianshu.com/p/af7e063ac9b3?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=qq

(有的图片漏了,还是看原文比较好)

上个星期,我花了一些时间参加了 Numerai 的机器学习金融比赛。这篇文章就是我对于比赛的一些笔记:我尝试过得一些方法,我做了什么工作以及什么工作我直接放弃不做。首先,让我们来介绍一下这个比赛和平台:

Numerai 是一家对冲基金,它利用比赛的形式来收集用户的策略,然后在内部对这些策略进行组合集成来交易。这个平台还有一个独一无二的地方是它对所有数据都会进行加密。每个星期,Numerai 都会重置比赛,然后公布一个新的数据集。然后经过一周短短的比赛,来评出第一名和第二名。这些名词不是单单利用比赛的分数来评定,还会有策略的原创性来考核。截止到这周末,我的策略的 log loss 在 0.68714。这个分数大约可以获得价值 $ 8.17 的比特币价值。

下面是训练数据的一个示例:

feature1    feature2    feature3    feature4    feature5    feature6    feature7    feature8    feature9    feature10   feature11   feature12   feature13   feature14   feature15   feature16   feature17   feature18   feature19   feature20   feature21   target
0.801620682063483   0.954026655642816   0.5705311667363 0.144232717229754   0.0500492688121434  0.0786789084265974  0.929508009336688   0.171077685785306   0.883034072289284   0.179369932130713   0.943269363053669   0.0288614434941082  0.1991065940751 0.968784322087461   0.064581284883459   0.916191480500131   0.238189399122635   0.0936556660484072  0.206537285119826   0.160288788368154   0.659444719296122   1
0.54007050183969    0.459006729530628   0.933131512414551   0.499801268888154   0.437992709228964   0.267235986043502   0.49719463349721    0.456020915709475   0.609753221442359   0.187454050581248   0.469354733168323   0.118559329564251   0.129507550533594   0.479953630810717   0.416888497364001   0.634561462124642   0.710520556134985   0.324297337296292   0.339857563207418   0.349509997045832   0.432920679407234   1
0.518214112985959   0.383788083593395   0.424871302717305   0.792762973770667   0.7742857173559 0.451385276234671   0.791400908677086   0.845301217143346   0.11862555750929    0.419257487945476   0.376741188540958   0.625610979113513   0.266524021808175   0.648017340815601   0.420797663214614   0.00431873269449817 0.992130143506543   0.718080611565518   0.992093533667718   0.134067138702938   0.0743077276110433  0
0.806453569351584   0.161343358248138   0.636975566410459   0.20171554254616    0.420537856699983   0.151818600989567   0.305146784581374   0.117884737420495   0.6108915265627 0.249714474623046   0.819308099139668   0.250770579717342   0.205248270449002   0.0862103305974124  0.532109927231077   0.790242340397417   0.198781520011354   0.274051362170583   0.192056729456156   0.0975874452607068  0.669890711788048   0
0.415003336362225   0.170186235034517   0.418823297694966   0.471830387551152   0.570765150255677   0.213788507104613   0.158155235117551   0.0117300575807448  0.418275738366933   0.558753991377777   0.179990534571358   0.436470111914978   0.506977165129181   0.300005858796116   0.742479443088257   0.206816619126046   0.814364270840413   0.331907239807323   0.0654237310678893  0.406143623934384   0.746499721419085   0
0.704449319534233   0.850338911254686   0.455998303770994   0.224563394324338   0.6995439084974 0.834721324063086   0.74728784556282    0.901345710496236   0.497415817686694   0.903353074258274   0.571234586425579   0.700451571955351   0.834000656317827   0.729095524732872   0.81078297616965    0.609452318787617   0.192694538456569   0.621665212601283   0.737860261408827   0.194185986803504   0.364996083433718   1
0.788055769180724   0.0545958246530098  0.200827379203853   0.0673784077815309  0.941077448055137   0.778947613783854   0.116750357635139   0.22800316108405    0.136388118235054   0.964284570466578   0.504061018335779   0.990569143158103   0.784283053374759   0.0393941086088943  0.933946479526913   0.669042714854619   0.138144590100865   0.918439009896414   0.880195626011122   0.0703418399004744  0.479384331357069   1
0.188297550227483   0.604074503040718   0.0183412656148252  0.81576618771192    0.518477669691875   0.803097540388692   0.711386433623059   0.652814191221587   0.0526464320116979  0.817774122488179   0.237459905042212   0.602959633090017   0.730338364463652   0.586008172371978   0.416888497364001   0.223150580662151   0.626276488264701   0.963008567409791   0.689730272299441   0.689253363243162   0.132085515045565   0
0.820315384108692   0.637408836538877   0.907437156607062   0.243122252397027   0.378765978591899   0.25798160900915    0.983337691578471   0.355088818872554   0.88329260758454    0.12352921389316    0.71346744394059    0.369877122677724   0.221232749108118   0.812421645851051   0.112857777466973   0.709823231860924   0.598130707018941   0.0413007685381965  0.50006278551784    0.266615825161751   0.735885538367622   1

验证

我在比赛中的第一步就是设计我们的验证集,以方便我们在本地测试我们的模型性能,从而可以对模型在排行榜上面的排名可以有一个预估。如果我们只是简单的对数据进行分割,那么验证结果并不能正确的反应在排行榜上面,所以在这里我采用的是 “对抗验证”。这个聪明的想法是 @fastml 中的一个想法,具体博客在这里。具体思想如下:

  1. 训练分类器,并且确定数据的来源,是来自训练集还是测试集;
  2. 按照测试数据集中的概率分布对训练数据进行排序;
  3. 选择与测试数据最相似的训练数据作为验证集;

按照这种方法设计的验证集,我们把相同的模型在公开排行榜上面进行测试的时候,得到的 log loss 误差大约在 0.001 左右。有趣的是,相对于训练数据,测试数据是不满足 IID 的条件。

基准模型

现在我们已经有了一个非常好的验证集,之后我们需要去设计一个模型,并且对这个模型进行验证和上传结果,这个模型就作为我们的基准模型了。作为起点,我就是用最简单的逻辑回归并且没有用任何的特征工程。这个模型在验证集上面得到了 0.69290 的结果,在公开的排行榜上面得到了 0.69162 的结果。这个结果并不好,但是我们的目的达到了,现在我们拥有了一个初始目标。为了进行比较,第一名目前的得分为 0.64669,所以我们最简单的基准分数与它之间的大约只有 6.5% 的差距。这也就意味着我们对于基准模型的任何改动,对最终的排名结果的影响都是非常小的。我们在对基准模型加上 1e-2 的 L2 正则化之后,这在排行榜上面达到了 0.69286 的正确率,比基准测试提高了 0.006 。

神经网络

在开始使用特征工程之前,我快速的浏览了一下神经网络算法。在理想的情况下,神经网络可以从足够多的原始数据中学习到特征,但不幸的是,我尝试过目前所有的神经网络架构,但是他们取得的效果都不能比简单的逻辑回归有很大的改进。此外,深度神经网络需要比逻辑回归更多的参数,所有我们需要去使用 L2 正则和批量归一化来规范参数,给模型加上 Dropout 也可以给架构带来性能的改进。

一个有效但是非常有意思的架构是使用一个非常宽的隐藏层(2048个神经元),拥有很高的 Dropout 值(达到 0.9),并且在开始训练的时候我们需要对初始化参数做一个固定设置。因为拥有很高的 Dropout ,所以这就造成了很多的集成模型。虽然这个模型能很好地工作,大约可以达到 0.689 的正确率,但是该模型太有个性,最终还是不打算采用这个模型。最后,神经网络没有在这个问题中得到比较好的结果,所以我们没有在神经网络的改进上花费更多的精力,而且本文我们主要分析我们的特征工程。

数据分析与特征工程

现在我们需要去挖掘我们的数据价值,先从一个简单的特征分布图开始吧。具体如下:

Violin plot of the distributions for each feature.

每个特征的分布都是非常相似的,那么特征之间的相关性如何呢?我们也画了一个图,如下:

Correlation matrix showing feature interactions.

从图中,我们可以看到很多的特征之间是强相关的。我们可以通过多项式关系在我们的模型中使用这一个特性。根据这个性质,我们在验证数据集上面取得了 0.69256 的成绩。

接下来,我们来做降维处理。我们采用的是 PCA 来把维度下降到二维,然后进行可视化操作,如下:

PCA dimensionality reduction over original features.

从图中我们得不到很多有用的信息,那么尝试一下多项式特征如何?如下图:

PCA dimensionality reduction over polynomial features.

多项式 PCA 通过将很多目标是 “1” 的值拉向边缘,并且把目标是 “0” 的值拉向中间,从图中看效果比前面一个好了很多。但是看起来还不是很好,所以我打算放弃使用 PCA,而使用别的方法。

我们将使用一种称为 t-SNE 的方法,t-SNE 通常用于高维数据的可视化,但是它拥有一个 PCA 没有的特性:t-SNE 是非线性的,并且根据两个点的概率来选择是否作为中心点的邻居。

t-SNE embedding over the features; clusters colored using [DBSCAN](http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html).

这里,t-SNE 获得了很好的的可视化结果。我将这些 2D 特征添加到我们的模型中,获得了目前最好的 log loss 成绩:0.68947,。我怀疑这个起作用的原因是局部特征,逻辑回归不能从数据中得到这些局部特征,但是这些局部特征对我们的分类是非常有效的。

由于 t-SNE 是随机的,我们每一次的运行结果都会产生不一样的结果。为了利用这一个特性,我们需要在不同的困惑度和维度(2D或者3D)上面,运行 t-SNE 五到六次,然后去分析这些额外的特征。最后,根据这个结果,我们的验证成绩达到了 0.68839 。

附加嵌入数据

由于 t-SNE 可以很好地工作,所以我又采用了集中其他的嵌入方法,包括自动编码器,去噪编码器和生成对抗网络。自动编码器可以对原始数据进行重新建模,而且建模的正确率可以高达 95% 的正确率,即使我们的数据中有噪音,但是这种嵌入表示并没有造成很大的影响。GAN,包括各种半监督的变体,他们的性能并没有超过简单的逻辑回归模型。我还是重点关注非线性降维犯法,比如内核PCA和等值线。但是这些方法很花费计算时间,减少了我迭代的次数,所以最终我还是把他们抛弃了。我没有尝试过 LargeVis 或者参数 t-SNE,但是他们都是非常值得研究的,因为它们可以保持一定的适应性,而不是将所有的学习样本一次输入。

Isomap embedding of the original features.

数据互动

其中一个集成模型是数据互动。基本上,从两个样本的特征可以直接看出,两个样本中哪个样本更大的可能性会被归类为 “1”。由于我们是对样本之间的交互进行建模,而不是对单个样本,因此根据这一个特性我们可以得到更多的数据。我们还可以根据我们的分类结果,从而从数据中学习到更有用的特征。

超参数搜索

现在我们有一些有用的特征和一些性能良好的模型,所以我想运行一个超参数模型,看看它是否可以胜过现有的模型。由于 scikit 包只能用 GridSearchCV 和 RandomSearchCV 进行探索超参数,而不是整个架构,所以我选择使用在两者之间的 tpot 包。我发现,使用随机 PCA 的性能由于 PCA,并且 L1 正则化(稀疏性)略由于 L2 正则化(平滑),特别是跟随机 PCA 进行配合使用。不幸的是,我们所发现的数据之间的关联性并没有用在最终的集成模型中:手工工程取得了胜利。

集成

我们已经完成了几个模型,是时候对这几个模型进行集成预测了。集成开发有很多的方式,我们这里采用的是最简单的基于几何平均值的简单平均值。

最后的集成模型我们采用了 4 个集成模型: logistic regression, gradient boosted trees, factorization machines 和 the pairwise model。我对每个模型都是使用相同的特征,特征由原始的 21 个特征组成,并且在 5,10,15,30 和 50 的困惑度下,在 2D 中运行 t-SNE 五次,以及在 3D 中运行 t-SNE 一次(困惑度 30)。这些特征与多项式特征相互结合,并且应用到模型中,这个集成模型最终得到的分数是 0.68714 。

结论

总体而言,这是一个非常有趣的比赛,它和 kaggle 最不同的地方是它的数据是加密的,而且它独特的奖金分配制度也是吸引我的一个地方,但是我更倾向于将奖励看做是积分,而不是货币,因为这使得竞争更加乐观。另一方面,现在我有了我的第一个比特币 :)

完整代码,可以点击 Github。



作者:chen_h
链接:http://www.jianshu.com/p/af7e063ac9b3
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(编程等)