深度学习训练中噪声减小吗_【机器学习 155】DoubleEnsemble

深度学习训练中噪声减小吗_【机器学习 155】DoubleEnsemble_第1张图片

更新:根据大家评论区和私信的反馈,我们把文章重新更新了一版在 arxiv 上。这次更新主要修改了方法部分的叙述和其他一些typos。欢迎大家围观~


相信关注我专栏的也有很多对于金融感兴趣的同学,这里给大家带来一个我们将要发表在 ICDM-20(CCF-B)上的一篇关于金融预测模型的文章。本文介绍了一种新的预测模型 DoubleEnsemble,该模型在我们实际的应用(不仅仅是金融方面)中有较好的效果。

原文传送门

DoubleEnsemble: A New Ensemble Method Based on Sample Reweighting and Feature Selection for Financial Data Analysis. Chuhang Zhang, Yuanqi Li, Xi Chen, Yifei Jin, Pingzhong Tang, Jian Li. The IEEE International Conference on Data Mining (ICDM 2020).

特色

金融上的问题具有高噪声、可预测性较弱等特点,因此很多目前在图像、自然语言等方面效果较好的方法在金融数据的分析和预测上都很难取得令人满意的效果。我们从机器学习的角度,提出使用集成模型方法(ensemble)解决这样的问题。在机器学习领域,集成模型的方法具有对于噪声稳定、不易于过拟合、相对于基模型有更强的模型容量等特点。我们的模型是基于金融中的多因子模型,该模型比较贴近机器学习里面的有监督学习(即,抽取大量的特征和标签,然后拟合训练数据集);现在业界很多公司都自己做了大量的因子,其中包含很有效的因子,当然也包含大量无效的因子。

我们为啥给模型起名叫做 DoubleEnsemble 呢?把输入数据 X 看做一个矩阵,其每一行代表一个样本,每一列代表一个特征。以往的一些集成模型方法有在这两个维度上来采样或者加权来构建每个子模型:比如 bagging 类方法会在构建子模型的时候随机采样若干“行”;而 GBDT 类模型在构建子模型的时候会随机采样若干“列”(比如 XGBoost 里面的 colsample_byxxx)。我们的集成模型在构建每个子模型的时候不仅给不同的“行”分配不同的权重,并且也随机筛选出不同的“列”;并且,我们的筛选/加权是基于各个特征/样本在训练中的表现来进行的,这种方式能够更有效地保留重要的特征/减小噪声样本的权重。

我们文章中的实验包含了在股票市场上的一个日/周频预测问题和在数字货币市场上的一个高频预测问题。根据我们的回测结果,我们的模型在股票市场中年化和夏普分别能达到 51.37% 和 4.941;在数字货币市场中未来 20s 方向预测在平均约 30s 出一个信号的情况下,准确性能达到 62.87%。值得一提的是,我们的股票回测系统是经过实盘实战检验的,在日频交易下能够很好地贴近实盘结果。

内容

一、金融预测中面临的问题

  • 问题本身难预测:金融里面有一个很著名的有效市场假说,讲的就是市场上的价格已经综合反映了各方面的信息,不可能找到一个投资策略持续地比市场平均水平表现得好。可以对比一下机器学习的其他领域,比如图像和自然语言领域,人类(已经有非常高的智能了)很快就能得到准确的结果;但在金融领域,市场上很多有经验的交易员仍然也较难对于金融市场有准确的预测。这暗示着金融里面的预测,本身就是比目前机器学习所面临问题更困难的问题。不过我们相信,市场上仍然存在着系统性不有效定价,即仍然存在着预测和盈利的空间。
  • 高噪声、高波动:可以从两个角度来看到噪声问题:一方面,市场的参与者鱼龙混杂,大家都有不一样的背景,因此可能做出各种各样的行为来影响市场;另外一方面,我们传递给模型的信息并十分全面,有一些隐含的能够影响价格的信息我们并没有囊括进来,因此在模型看来,这些隐变量所带来的影响也是不可预测的噪声。对于后一个方面,也应该尽量努力去把更多的因素囊括进入模型中来;在多因子模型中,这是“造因子”的工作,不在本文的讨论范围内。
  • 大量可能无效的因子:多因子模型中的因子,就等价于有监督学习模型中的特征。虽然本文不讨论如何造出有效的因子,但是目前在工业界中,各个公司都有大量的因子,这都是研究员们常年累月积累下来的。因子的数量一般少则成百、多则上千。这些因子中会有大量的无效因子,尽管因子被加入因子库的时候都有证据表明他们可能是有效的;这也意味在在市场环境发生变化的时候,它们可能又重新起到相应的效果,因此我们也不太好直接把它们删去。

二、模型

集成模型

首先,我们的目标是训练一个等权的集成模型

86e33ee8e656b29e04eef3a974a53182.png

第 k 个子模型的训练都会基于输入数据

,标签
,权重
和相应筛选出来的特征
。子模型可以为深度学习模型(这里用的 MLP),也可以是决策树模型(这里用的 GBDT/XGBoost)。每个子模型的样本权重和特征会基于数据在前面子模型中的训练情况,我们用训练中的 loss curve
和总体 loss
来表征其训练情况,其中
表示在加上第 k 个子模型后,集成模型在第 i 个样本上的损失函数值;
表示在第 k 个子模型训练过程中,第 i 个样本的 loss curve (即,训练了 T 轮)。

我们的模型大致框架如下图所示:对于第一个子模型,我们用相等权重的样本和所有的特征;对于后续的子模型,我们会基于前一个子模型的训练来分配新的样本权重(sample reweighting,SR)和筛选特征(feature selection,FS)。

深度学习训练中噪声减小吗_【机器学习 155】DoubleEnsemble_第2张图片

Sample Reweighting

样本重赋权的方法这里用 pythonic 的伪代码写出来,更具体的数学定义可以参考原文。

def SR(C, L, k, alpha1=1, alpha2=1, B=10, gamma=0.9, EPS=0.1):
    # coefficients: alpha1, alpha2
    # #bins: B
    # self-paced factor: gamma

    # pandas style rank, with axis=0, ascending=True, pct=True
    # C.shape = (N, T)
    C = rank(C) 
    # L.shape = (N, 1)
    L = rank(L) 
    # h.shape = (N, 1)
    h = alpha1 * (-L) + alpha2 * 
        rank(mean(C[-int(T/10):, :], axis=1) / mean(C[:int(T/10), :], axis=1))
    h = rank(h)
    # h_bin_values.shape = (B, ); h_bin_indices.shape = (N, )
    h_bin_values, h_bin_indices = bin(h)

    w = empty(shape=(N, ))
    for i in range(N):
        w[i] = 1 / ( gamma ** k * h_bin_values[h_bin_indices[i]] + EPS)
    return w

那么为什么要这样做呢?

大致思想是想通过对于样本重新赋权,尽可能减小噪声样本的权重,并且增大比较困难样本的权重。噪声样本指的是标签比较随机的样本;困难的样本指的是特别贴近决策面的样本,如果决策面没有拟合地特别好,这些样本就可能被分到错误的类别里面,因而容易产生较大的损失。降低噪声样本权重能够帮助提高模型稳定性;增大困难样本权重能够帮助模型去学习更”深层次“的规律,从而提高整体预测正确率。但是这两者又很难被分开(因为一般都产生较大的 loss);我们观察到这两类样本的训练 loss curve 有着不一样的特征,因此设计了这样的算法把它们区分开。它们的训练特征可以通过下面这个例子看到。

深度学习训练中噪声减小吗_【机器学习 155】DoubleEnsemble_第3张图片

Feature Selection

筛选特征的方法用 pythonic 伪代码可以如下写出,具体的准确数学表达形式请大家参考原文。

def FS(Mbar, X, y, D=5, r=[0.8, 0.7, 0.6, 0.5, 0.4]):
    # previous ensemble model: Mbar
    # training data: (X, y)
    # #bins: D
    # sample ratio for each bin: r

    y_pred = Mbar(X)
    # L.shape = (N, )
    L = loss(y_pred, y)

    g = empty(shape=(F, ))
    for f in range(F):
        # shuffle the value of the f-th column in X
        Xf = shuffle(X, column=f)
        y_pred = Mbar(Xf)
        Lf = loss(y_pred, y)
        g[f] = mean(Lf - L) / std(Lf - L)

    # g_bin_values.shape = (D, ); g_bin_indices.shape = (F, )
    g_bin_values, g_bin_indices = bin(g)

    features = []
    for d in range(D):
        # see also docs for numpy argwhere and choice
        indices = argwhere(g_bin_indices == d)
        nums = len(indices)
        features.append(choice(indices, int(nums * r[d])))

    return features

那么为什么要这样做呢?

这里的目标是以更高的概率筛选出来对于模型准确率贡献较高的特征。这个目标要求我们不能只是对于每个特征来单独衡量其有效性,而是要衡量特征对于集成模型整体的有效性;整体有效性的衡量最直接的形式是“剔除”,然而对于已经训练好的模型来说,没有办法直接把某个特征去掉(比如,深度学习模型训练好之后就只能接收固定维度的数据输入了,如果输入维度减小,压根没办法输入模型)。考虑到这个问题,一个简单的解决方法是对于要“剔除”的特征各个全部置零,但是这种操作使得模型很大程度上直接崩溃(因为训练的时候可能压根没见过这个维度上为零的数据,这种分布的不匹配可能使得模型直接失效)。我们这里采用了一个比较巧妙的办法:把要“剔除”的这个特征的各个维度随机打乱,这样既保留了相应的分布,但是又“隐藏”了这个特征所能提供的信息量。这样算出来的 g 反映了相应特征对于模型贡献的显著性,接下来我们根据其显著性来筛选因子,即显著性高的因子尽可能多地采样。

同时,我们观察到,在 SR 过程中,我们计算了 h;在 FS 过程中,我们计算了 g。接下来,我们都对其进行了离散化到不同的 bin 后再处理;实验中我们发现这种方法能够有效减小 outlier 和 noise 的不良影响。毕竟,在金融应用中,我们写模型的时候头脑中得时时刻刻都需要想到:要 robust 要 robust = =。

三、实验

数字货币预测

  • 交易所:OKEx
  • 交易特征:24 小时不间断
  • 标的:ETC/BTC, ETH/BTC, GAS/BTC and LTC/BTC
  • 数据频率:每 0.3 秒一个市场快照
  • 训练数据集:10 天(约 3M 个样本点)
  • 测试数据集:训练数据其后的 5 天
  • 特征:常见的公开因子(比如 OFI、RSI 等)
  • 衡量指标:ACC(precision when top 1% retrieved), AUC, F1, PCT (backtest result: average profit in one trading day)
  • 手续费和滑点:千分之二(数字货币交易所手续费通常比股票市场更低)

深度学习训练中噪声减小吗_【机器学习 155】DoubleEnsemble_第4张图片

股票预测

  • 股票池:A 股市场
  • 交易频率:日频和周频
  • 交易策略:每天做多前 20 支(日频)或者 10 支(周频)股票;这里为了贴近中国市场行情,没有做空策略
  • 持仓股票数:大多是时刻持仓 20 支(日频)或者 50 支(周频)
  • 持仓方式:等权
  • 因子池:两组不同的私有因子池,分别适用于日频和周频,因子数量分别为 182 和 254;因子包括价量因子和基本面因子
  • 回测形式:滚动训练,即每周使用最近 500 个交易日(两年)的数据重新训练模型
  • 衡量指标:年化收益、夏普比率、最大回撤、信息比率
  • 手续费和滑点:千分之三

深度学习训练中噪声减小吗_【机器学习 155】DoubleEnsemble_第5张图片

深度学习训练中噪声减小吗_【机器学习 155】DoubleEnsemble_第6张图片

在实际应用中,在除了金融以外的其他领域我们也在使用这个模型,并且也取得了不错的效果。

你可能感兴趣的:(深度学习训练中噪声减小吗)