作者:Alex Honchar

机器之心编译

参与:陈韵竹、李泽南


跟着人工智能技能的遍及,用机器学习猜测市场价格动摇的办法最近层出不穷。本文中,Alex Honchar 介绍了运用概率编程和 Pyro 进行价格猜测的办法,相较于惯例神经网络,新办法关于数据的依靠程度更小,作用更精确。在试验中,作者挑选了最近盛行的虚拟钱银「以太币」作为实例进行价格猜测。


上一年我曾宣布过几篇有关运用神经网络进行金融价格猜测的教程,我以为其间有一部分作用至少还挺有意思,而且值得在实践买卖中加以运用。假如你阅览过这些文章,你必定注意到一个现象:当你企图将一些机器学习模型运用于「随机」数据并期望从中找到躲藏规律的时分,练习进程往往会发作严峻的过拟合。咱们曾运用不同的正则化技能和附加数据应对这个问题,可是这不只很费时,还有种盲目搜索的感觉。


今日,我想介绍一个稍微有些不同的办法对相同的算法进行拟合。运用概率的观念看待这个问题能够让咱们从数据自身学习正则化、估量猜测作用确实定性、运用更少的数据进行练习,还能在模型中引入额定的概率依靠联系。我不会过多深化贝叶斯模型或变分原理的数学、技能细节,而是会给出一些概述,也更多地将评论集中在运用场景傍边。文中所用的代码能够在以下链接中找到:https://github.com/Rachnog/Deep-Trading/tree/master/bayesian


与此同时,我也引荐大家查阅我此前发布的根据神经网络的财政猜测教程:


1. 简略时刻序列猜测(错误纠正完毕)

2. 正确一维时刻序列猜测+回测

3. 多元时刻序列猜测

4. 动摇猜测和自界说丢失

5. 多使命和多方式学习

6. 超参数优化

7. 用神经网络进行经典战略强化

为了更深化地了解概率规划、贝叶斯模型以及它们的运用,我引荐你在以下资源网站中检查:


  • 方式识别和机器学习

  • 黑客贝叶斯办法

  • 下面即将说到的库文件


别的,你还可能会用到下列 Python 库:


  • PyMC3 (https://github.com/pymc-devs/pymc3)

  • Edward (http://edwardlib.org/)

  • Pyro (http://pyro.ai/)


概率编程


这个「概率」指的是什么?咱们为什么称其为「编程」呢?首要,让咱们回想一下咱们所谓「正常的」神经网络指的是什么、以及咱们能从中得到什么。神经网络有着以矩阵方式表达的参数(权重),而其输出通常是一些标量或许向量(例如在分类问题的状况下)。当咱们用比如 SGD 的办法练习这个模型后,这些矩阵会取得固定值。与此同时,关于同一个输入样本,输出向量应该相同,就是这样!可是,假如咱们将一切的参数和输出视为彼此依靠的散布,会发作什么?神经网络的权重将与输出相同,是一个来自网络并取决于参数的样本——假如是这样,它能为咱们带来什么?


让咱们从根底讲起。假如咱们以为网络是一个取决于其他散布的数集,这首要就构成了联合概率散布 p(y, z|x),其间有着输出 y 和一些模型 z 的「内部」隐变量,它们都取决于输入 x(这与惯例的神经网络完全相同)。咱们感兴趣的是找到这样神经网络的散布,这样一来就能够对 y ~ p(y|x) 进行采样,并取得一个方式为散布的输出,该散布中抽取的样本的期望通常是输出,和标准差(对不确定性的估量)——尾部越大,则输出置信度越小。


这种设定可能不是很清晰,但咱们只需求记住:现在开端,模型中一切的参数、输入及输出都是散布,而且在练习时对这些散布进行拟合,以便在实践运用中取得更高的精确率。咱们也需求注意自己设定的参数散布的形状(例如,一切的初识权重 w 遵守正态散布 Normal(0,1),之后咱们将学习正确的均值和方差)。初始散布即所谓的先验知识,在练习集上练习过的散布即为后验知识。咱们运用后者进行抽样并得出作用。


图源:http://www.indiana.edu/~kruschke/BMLR/


模型要拟合到什么程度才有用?通用结构被称为变分推理(variational inference)。无需细想,咱们能够假定,咱们期望找到一个能够得到最大对数似然函数 p_w(z | x)的模型,其间 w 是模型的参数(散布参数),z 是咱们的隐变量(躲藏层的神经元输出,从参数 w 的散布采样得到),x 是输入数据样本。这就是咱们的模型了。咱们在 Pyro 中引入了一个实例来介绍这个模型,该简略实例包含一切隐变量 q_(z)的一些散布,其间 ф 被称为变分参数。这种散布有必要近似于练习最好的模型参数的「实践」散布。


练习方针是使得 [log(p_w(z|x))—log(q_ф(z))] 的期望值相关于有辅导的输入数据和样本最小化。在这儿咱们不讨论练习的细节,由于这儿面的知识量太大了,此处就先当它是一个能够优化的黑箱吧。


对了,为什么需求编程呢?由于咱们通常将这种概率模型(如神经网络)界说为变量彼此相关的有向图,这样咱们就能够直接显现变量间的依靠联系:


图源:http://kentonmurray.com/


而且,概率编程言语起初就被用于界说此类模型并在模型上做推理。


为什么挑选概率编程?


不同于在模型中运用 dropout 或 L1 正则化,你能够把它当作你数据中的隐变量。考虑到一切的权重其实是散布,你能够从中抽样 N 次得到输出的散布,经过核算该散布的标准差,你就知道能模型有多靠谱。作为作用,咱们能够只用少数的数据来练习这些模型,而且咱们能够灵敏地在变量之间增加不同的依靠联系。


概率编程的缺乏


我还没有太多关于贝叶斯建模的经历,可是我从 Pyro 和 PyMC3 中了解到,这类模型的练习进程十分绵长且很难界说正确的先验散布。而且,处理从散布中抽取的样本会导致误解和歧义。


数据预备


我现已从 http://bitinfocharts.com/ 抓取了每日 Ethereum(以太坊)的价格数据。其间包含典型的 OHLCV(高开低走),别的还有关于 Ethereum 的每日推特量。咱们将运用七日的价格、开盘及推特量数据来猜测次日的价格改变状况。


价格、推特数、大盘改变


上图是一些数据样本——蓝线对应价格改变,黄线对应推特数改变,绿色对应大盘改变。它们之间存在某种正相关(0.1—0.2)。因而咱们期望能运用好这些数据中的方式对模型进行练习。


贝叶斯线性回归


首要,我想验证简略线性分类器在使命中的体现作用(而且我想直接运用 Pyro tutorial——http://pyro.ai/examples/bayesian_regression.html——的作用)。咱们依照以下操作在 PyTorch 上界说咱们的模型(详情参看官方指南:http://pyro.ai/examples/bayesian_regression.html)。


class RegressionModel(nn.Module):     def __init__(self, p):         super(RegressionModel, self).__init__()         self.linear = nn.Linear(p, 1) def forward(self, x):         # x * w + b         return self.linear(x)


以上是咱们曾经用过的简略确定性模型,下面是用 Pyro 界说的概率模型:


def model(data):     # Create unit normal priors over the parameters     mu = Variable(torch.zeros(1, p)).type_as(data)     sigma = Variable(torch.ones(1, p)).type_as(data)     bias_mu = Variable(torch.zeros(1)).type_as(data)     bias_sigma = Variable(torch.ones(1)).type_as(data)     w_prior, b_prior = Normal(mu, sigma), Normal(bias_mu, bias_sigma)     priors = {'linear.weight': w_prior, 'linear.bias': b_prior}     lifted_module = pyro.random_module("module", regression_model, priors)     lifted_reg_model = lifted_module() with pyro.iarange("map", N, subsample=data):         x_data = data[:, :-1]         y_data = data[:, -1]         # run the regressor forward conditioned on inputs         prediction_mean = lifted_reg_model(x_data).squeeze()         pyro.sample("obs",                     Normal(prediction_mean, Variable(torch.ones(data.size(0))).type_as(data)),                     obs=y_data.squeeze())


从上面的代码可知,参数 W 和 b 均界说为一般线性回归模型散布,两者都遵守正态散布 Normal(0,1)。咱们称之为先验,创立 Pyro 的随机函数(在咱们的比如中是 PyTorch 中的 RegressionModel),为它增加先验 ({『linear.weight』: w_prior, 『linear.bias』: b_prior}),并根据输入数据 x 从这个模型 p(y|x) 中抽样。


这个模型的 guide 部分可能像下面这样:


 def guide(data):     w_mu = Variable(torch.randn(1, p).type_as(data.data), requires_grad=True)     w_log_sig = Variable(0.1 * torch.ones(1, p).type_as(data.data), requires_grad=True)     b_mu = Variable(torch.randn(1).type_as(data.data), requires_grad=True)     b_log_sig = Variable(0.1 * torch.ones(1).type_as(data.data), requires_grad=True)     mw_param = pyro.param("guide_mean_weight", w_mu)     sw_param = softplus(pyro.param("guide_log_sigma_weight", w_log_sig))     mb_param = pyro.param("guide_mean_bias", b_mu)     sb_param = softplus(pyro.param("guide_log_sigma_bias", b_log_sig))     w_dist = Normal(mw_param, sw_param)     b_dist = Normal(mb_param, sb_param)     dists = {'linear.weight': w_dist, 'linear.bias': b_dist}     lifted_module = pyro.random_module("module", regression_model, dists)     return lifted_module()


咱们界说了想要「练习」的散布的可变散布。如你所见,咱们为 W 和 b 界说了相同的散布,意图是让它们更接近实践状况(据咱们假定)。这个比如中,我让散布图更窄一些(遵守正态散布 Normal(0, 0.1))


然后,咱们用这种方式对模型进行练习:


    for j in range(3000):     epoch_loss = 0.0     perm = torch.randperm(N)     # shuffle data     data = data[perm]     # get indices of each batch     all_batches = get_batch_indices(N, 64)     for ix, batch_start in enumerate(all_batches[:-1]):         batch_end = all_batches[ix + 1]         batch_data = data[batch_start: batch_end]         epoch_loss += svi.step(batch_data)


在模型拟合后,咱们想从中抽样出 y。咱们循环 100 次并核算每一步的猜测值的均值和标准差(标准差越高,猜测置信度就越低)。


   preds = [] for i in range(100):     sampled_reg_model = guide(X_test)     pred = sampled_reg_model(X_test).data.numpy().flatten()     preds.append(pred)


现在有许多经典的经济猜测衡量办法,例如 MSE、MAE 或 MAPE,它们都可能会让人困惑——错误率低并不意味着你的模型体现得好,验证它在测验集上的体现也十分重要,而这就是咱们做的作业。


运用贝叶斯模型进行为期 30 天的猜测


从图中咱们能够看到,猜测作用并不够好。可是猜测图中最终的几个跳变的形状很不错,这给了咱们一线期望。持续加油!


惯例神经网络


在这个十分简略的模型进行试验后,咱们想要尝试一些更风趣的神经网络。首要让咱们运用 25 个带有线性激活的神经元的单隐层网络练习一个简略 MLP:


 def get_model(input_size):     main_input = Input(shape=(input_size, ), name='main_input')     x = Dense(25, activation='linear')(main_input)     output = Dense(1, activation = "linear", name = "out")(x)     final_model = Model(inputs=[main_input], outputs=[output])     final_model.compile(optimizer='adam',  loss='mse')     return final_model


练习 100 个 epoch:


model = get_model(len(X_train[0])) history = model.fit(X_train, Y_train,                epochs = 100,                batch_size = 64,                verbose=1,                validation_data=(X_test, Y_test),               callbacks=[reduce_lr, checkpointer],               shuffle=True)


其作用如下:


运用 Keras 神经网络进行为期 30 天的猜测


我觉得这比简略的贝叶斯回归作用更差,此外这个模型不能得到确定性的估量,更重要的是,这个模型乃至没有正则化。


贝叶斯神经网络


现在咱们用 PyTorch 来界说上文在 Keras 上练习的模型:


class Net(torch.nn.Module):     def __init__(self, n_feature, n_hidden):         super(Net, self).__init__()         self.hidden = torch.nn.Linear(n_feature, n_hidden)   # hidden layer         self.predict = torch.nn.Linear(n_hidden, 1)   # output layer def forward(self, x):         x = self.hidden(x)         x = self.predict(x)         return x


相比于贝叶斯回归模型,咱们现在有两个参数集(从输入层到躲藏层的参数和躲藏层到输出层的参数),所以咱们需求对散布和先验知识稍加改动,以适应咱们的模型:


priors = {'hidden.weight': w_prior,                'hidden.bias': b_prior,               'predict.weight': w_prior2,               'predict.bias': b_prior2}


以及 guide 部分:


dists = {'hidden.weight': w_dist,                'hidden.bias': b_dist,               'predict.weight': w_dist2,               'predict.bias': b_dist2}


请不要忘记为模型中的每一个散布起一个不同的名字,由于模型中不该存在任何歧义和重复。更多代码细节请拜见源代码:https://github.com/Rachnog/Deep-Trading/tree/master/bayesian


练习之后,让咱们看看最终的作用:


运用 Pyro 神经网络进行为期 30 天的猜测


它看起来比之前的作用都好得多!


比起惯例贝叶斯模型,考虑到贝叶斯模型所中习得的权重特征或正则化,我还期望看到权重的数据。我依照以下办法检查 Pyro 模型的参数:


for name in pyro.get_param_store().get_all_param_names():     print name, pyro.param(name).data.numpy()


这是我在 Keras 模型中所写的代码:


import tensorflow as tf sess = tf.Session() with sess.as_default():     tf.global_variables_initializer().run() dense_weights, out_weights = None, None with sess.as_default():     for layer in model.layers:         if len(layer.weights) > 0:             weights = layer.get_weights()             if 'dense' in layer.name:                 dense_weights = layer.weights[0].eval()             if 'out' in layer.name:                 out_weights = layer.weights[0].eval()


例如,Keras 模型最终一层的权重的均值和标准差分别为 -0.0025901748 和 0.30395043,Pyro 模型对应值为 0.0005974418 和 0.0005974418。数字小了许多,但作用真的不错!其实这就是 L2 或 Dropout 这种正则化算法要做的——把参数逼近到零,而咱们能够用变分推理来实现它!躲藏层的权重改变更风趣。咱们将一些权重向量绘制成图,蓝线是 Keras 模型的权重,橙线是 Pyro 模型的权重:


输入层与躲藏层之间的部分权重


真正有意思的不止是权重的均值与标准差变得小,还有一点是权重变得稀少,所以基本上在练习中完成了第一个权重集的稀少表明,以及第二个权重集的 L2 正则化,多么奇特!别忘了自己跑跑代码感受一下:https://github.com/Rachnog/Deep-Trading/tree/master/bayesian


小结


咱们在文中运用了新颖的办法对神经网络进行练习。不同于次序更新静态权重,咱们是更新的是权重的散布。因而,咱们可能取得风趣又有用的作用。我想着重的是,贝叶斯办法让咱们在调整神经网络时不需求手动增加正则化,了解模型的不确定性,并尽可能运用更少的数据来取得更好的作用。感谢阅览:) 


原文链接:https://medium.com/@alexrachnog/financial-forecasting-with-probabilistic-programming-and-pyro-db68ab1a1dba

(以上发布均为题目,为保证客户隐私,源代码绝不外泄!!)

代写计算机编程类/金融/高数/论文/英文



  u=199783060,2774173244&fm=58&s=188FA15AB1206D1108400056000040F6&bpow=121&bpoh=75.jpgalipay_pay_96px_533896_easyicon.net.pngpaypal_96px_533937_easyicon.net.pngchina_union_pay_96px_533911_easyicon.net.pngmastercard_pay_96px_533931_easyicon.net.pngasia_pay_96px_533902_easyicon.net.png

本网站支持淘宝 支付宝 微信支付  paypal等等交易。如果不放心可以用淘宝或者Upwork交易!

E-mail:850190831@qq.com   微信:BadGeniuscs  工作时间:无休息工作日-早上8点到凌晨3点


如果您用的手机请先保存二维码到手机里面,识别图中二维码。如果用电脑,直接掏出手机果断扫描。

qr.png


编程类代写

Python教程

2018-03-05


跟着人工智能技能的遍及,用机器学习猜测市场价格动摇的办法最近层出不穷。本文中,Alex Honchar 介绍了运用概率编程和 Pyro 进行价格猜测的办法,相较于惯例神经网络,新办法关于数