TowardsDataScience 博客中文翻译 2020(八百二十一)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

该股票指标可能是预测 COVID 突破的最佳方式

原文:https://towardsdatascience.com/stock-indicators-may-be-the-best-way-to-predict-covid-breakouts-9b6939d9fc0c?source=collection_archive---------54-----------------------

MACD 等交易指标帮助交易员预测股票的技术方向。这些数学技术对于预测新冠肺炎病毒的爆发同样有用吗?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

美国 MACD 指标新冠肺炎新病例

随着 2020 年继续带来一个又一个全球性挑战,我们经常发现自己似乎与这些威胁无关,因为它们给人一种逐渐消失的错觉。不幸的是,我们面临的挑战没有确定的结束日期或完美的解决方案。与我们面临的其他问题不同,新冠肺炎不会简单地消失,一旦它对经济和生计“太长”或“太具破坏性”。换句话说,我们无法通过与病毒的交易或让步来立即解决这个问题。

由于这种动态,我们所能做的最好的事情是尝试执行缓解方法,如社会距离和戴口罩,直到病例的指数轨迹足够低,直到固体疫苗上市为止。这听起来直截了当,但正如我们在美国各地看到的那样,当病例数开始减少时,我们会产生一种错觉,以为我们没事了,只是在我们回到正常生活后不久,病例就会大量增加。那么,我们如何预测什么时候我们是安全的,什么时候我们又处于危险之中,而不是简单地用我们的后见之明来解释我们当前的处境呢?

世界各地的数据科学家正在研究这个问题,以预测下一次爆发。方法范围从简单的统计,图形网络,接触追踪,有时甚至涉及经典的方法扔在一个“神经网络”的问题。这些方法中有许多是为人群和病毒病例量身定制的,可以快速实施。与此同时,数据科学的一个领域(可能是最古老的)还没有被开发到可以提供帮助的水平。这当然是量化的股票交易或技术交易。近 100 年来,预测股票爆发的方法一直在不断改进,主要是因为用例是即时的,而金钱是一个相当普遍的动机。技术交易指标有一点比其他统计模型做得更好——它们使用当前的环境。这有助于提供更多的确定性,并允许人根据算法做出决定,而不是仅仅从屏幕上读取预测的数字。在众多指标中,有一个指标的工作本质上是指示股票的潜在突破,所以为什么不试一试,就像我们试图预测爆发一样。介绍 MACD。

MACD

移动平均收敛发散或 MACD 是技术交易中使用的二阶到三阶衍生指标,有助于了解短期动量变化和方向。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

指数移动平均线

MACD(EMA short-EMAlong)的工作原理是跟踪长期均线的短期指数移动平均线。通过这样做,我们能够看到短期趋势何时开始收敛或偏离长期趋势。如果我们开始看到短期移动平均线背离,我们可以推断一个潜在的突破正在进行中。另一方面,当这两个平均值接近时,我们开始看到盘整和表现不佳。总的来说,MACD 是动量的量度。

为了做出更精细的决策,还可以绘制一条信号线。信号线跟踪 MACD 的动量,所以另一个导数水平下降。这让我们可以看到 MACD 何时高于或低于均线。简而言之,当 MACD 穿过向上移动的信号时,我们认为这是一个“买入”信号,当它穿过向下移动时,我们认为这是一个“卖出”信号。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

TSLA 600 万的价格(上)MACD(下)—由 E*Trade Pro 精英会员提供

为了将此付诸实践,我们可以看看特斯拉股票最近突破(或爆发)的 MACD 是什么样子的。这里的红线是信号(MACD 的 9 日均线),白线是 MACD(12 日均线——26 日均线)。图表上的直方图是 MACD 和信号之间的差异的直观显示,我发现它对跟踪最有用。在大多数情况下,MACD 和信号是平坦的,几乎没有直方图的作用。在图表右侧附近,我们看到标记线,MACD 穿过信号,随后直方图快速增加。这是在大约 1 个月左右的时间里从大约 800 美元突破到 1700 美元的时候。事后很容易看出这是如何发生的,但重要的是要注意,当线交叉或接近交叉时,有非常微妙的运动。如果你仅仅根据 MACD 忠实地接受买入信号,你会在一两个月内赚到超过 100%的钱!我们可以看到,目前,MACD 已经脱离了巨大动量的信号。即使涨势放缓,我们也要记住,直到白线向下穿过红线,我们才应该认为涨势结束了。*免责声明:我不是在给股票建议。

通过理解 MACD 是如何在没有明显动作的情况下发出突破信号的,我意识到我们和新冠肺炎有着相同的目标。案例数据类似于股票价格(显然我们的希望是相反的)。考虑到这一点,我们也许能够在疾病爆发前发现潜在的疾病,并更加努力地阻止直方图失控。

MACD 代表新冠肺炎

正如所讨论的,通过将相同的 EMA 方程及其导数应用于 COVID 病例,我们可以更好地预测和应对在典型病例图中不可见的潜在爆发。为了解决这个问题,我从 https://covidtracking.com/data/download 下载了美国、我的家乡密歇根州和佛罗里达州的 COVID 病例数据。从这里开始,我在 Excel 中建立模型,并计算每个导数值。请注意,从住院到病例,任何情况都可以这样做,但为了简化这些示例,将使用病例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Excel 电子表格—由智力建设者 AI Research 提供

正如你所看到的,第一组 MACD 值只能开始 26 天的数据,而信号只能开始 35 天的数据。这显然会影响数据的长度,因为每个数据集只有大约 170 天的价值。为了对结果有个大概的了解,并与上面的图表相似,让我们来看看美国 MACD 的图表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

美国 MACD COVID 案例(1 月 26 日—7 月 12 日)—由 MindBuilder AI Research 提供

在接下来的两个例子中,我将更深入地介绍与 MACD 相比的案例数,如果您愿意,可以将此图表与美国的新案例进行交叉引用。我们在这里看到的是 2 月中旬的初始峰值。直到大约 3 月底,病例继续增长势头,直到最终稳定下来,并最终得到适度控制,此时势头减弱。只是提醒一下,此图表并不显示病例数,而是显示趋势,因此 y 轴值为零实质上意味着每天都有相同数量的病例增加,而低于 0 则意味着新病例在减少。这里的负面部分是关于各州何时开始重新开放的。不幸的是,在数据的第 112 天,我们看到 MACD 穿过了信号,这可能是人们开始感到舒适的时候。随着这一势头的增长,我们已经看到美国继续增加比以往更多的病例。如果这个信号被当作一个缓和的触发器,我们可能不会处于现在的状态。为了更细致地观察,让我们看看基于状态的数据,以及相对于病例数据,疫情是如何被缓解或忽略的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

佛罗里达州 MACD 的 COVID 病例(3 月 1 日-7 月 12 日)——由智力建设者 AI 研究公司提供

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

佛罗里达案例(3 月 1 日至 7 月 12 日)

众所周知,美国许多州都在努力应对新新冠肺炎病例的激增。其中一个州是佛罗里达。在今年的大部分时间里,佛罗里达州的 COVID 病例低于平均水平。不幸的是,这给了他们一种错觉,认为他们是清白的,这反过来又让他们可以推迟采取措施来缓解病毒。很明显,他们并不清楚,但在上图中爆发之前,这一点并不明显。让我们仔细看看,了解佛罗里达州可以看到 MACD。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

佛罗里达案例到第 77 天

想象我们生活在第 79 天。正如我们在上面看到的,直到第 79 天,病例几乎没有变化。这将导致大多数人认为病毒受到控制,无论规则和缓解措施如何变化,都不会有太大变化。MACD 在这一点上发现了一些微妙的信号,并讲述了一个不同的故事。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第 67 天 MACD 十字路口

让我们回顾一下第 67 天和第 79 天之间的病例数据。肉眼看起来,每天有 500-700 例的稳定增长,没有变化可担心,但是小的稳定增长显示在 MACD 图表上,变化不仅仅是细微的。在完整的图表中,我们看到这变成了病例的爆炸,昨天 7 月 12 日增加了 15,000 例。这表明,在原始数据之下,一定有更好的指标,可以预示和阻止如此可怕的疫情。在第 67-69 天的那一刻,没人能预测到我们看到的增长,但 1970 年的一个交易指标做到了。这些隐藏在众目睽睽之下的简单数字本可以拯救生命,并有望在未来拯救生命。

结束语

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

COVID cases 的密歇根 MACD(3 月 1 日-7 月 12 日)——由智力建设者 AI 研究公司提供

这是我的家乡密歇根州的图表。我们从一开始就受到了沉重的打击,但是正如我们从数据中看到的,我们的努力粉碎了势头,使短期均线大部分时间低于信号。从这个数据来源来看,早期的 COVID 没有一个时刻显示出 MACD 的爆炸性势头(这应该是在 2 月中旬)。不幸的是,有趣的夏季在第 79 天左右创造了一个适度倾斜的十字。幸运的是,案件数量还没有爆炸性增长。这一势头刚刚变得积极,似乎已经得到遏制。但是,图表显示的正是我们在佛罗里达看到的情况,这有点令人不安。积极的一面是,我们仍然有时间采取行动,创造我们都在等待的“卖出”信号(红色下面的白色十字)。如果我的状态戴着面具,负责任地社交,并着眼于没有 COVID 的生活的长期利益,而不是短期的快乐,我们可以创造“出售”信号,并很快发现我们的生活超越了 COVID。

有了 MACD 这样强大的指标,这不再是一场猜谜游戏。我们可以在病例出现之前看到势头的变化,这意味着我们可以采取行动拯救最脆弱人群的生命。这可能是我们对付病毒形式的敌人的唯一手段之一。我希望这种方法至少能为对抗 COVID 做出一点小小的贡献,并能帮助人们认识到,遵循数据永远是最佳选择。

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

LinkedInTwitter上与我连线继续对话。

看看我目前在 https://www.mindbuilderai.com 做什么

基于卷积神经网络的股票买卖预测

原文:https://towardsdatascience.com/stock-market-action-prediction-with-convnet-8689238feae3?source=collection_archive---------2-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

灵感来自题为“深度卷积神经网络的算法金融交易:时间序列到图像转换”的研究论文

这个项目大致基于一篇名为“ 深度卷积神经网络的算法金融交易:时间序列到图像转换方法 ”的研究论文。我说“不严格”是因为尽管我从论文中借用了核心思想,但我做的(或必须做的)一些事情与我们稍后将看到的不同。我上面分享的链接是论文的预印本。付费/主文可能会有更多的细节。这篇文章是我的上一篇关于股票价格预测的文章的一位读者建议的,它立即引起了我的注意。这里是 Githubrepo和主培训笔记本上 Kaggle 的链接。

有一件事我想让读者知道——我不是在这里宣称我有一个现成的交易模型(尽管我正在为我个人的使用进一步探索这个方法)。将传统的表格或时间序列数据转换为图像,并在此基础上训练分类模型的想法,似乎太令人兴奋了,以至于无法抗拒尝试并与社区共享。像我的 上一篇 这是一篇记述我与这个项目的经历。

1.研究论文怎么说?

在这一节中,我将解释论文中提出的观点。我将在下一节讨论代码和实现。

这个想法很简单:在你的交易数据中,每天用 15 个不同的周期长度(解释如下)计算 15 个技术指标。然后将 225 (15*15)的新特征转换成 15×15 的图像。根据文中提供的算法,将数据标记为买入/卖出/持有。然后像任何其他图像分类问题一样训练一个卷积神经网络。

如果你不知道什么是技术指标,我建议你查看上面的链接。我会用简单移动平均线(SMA) 来解释技术指标和时间周期的概念,因为它更简单。这应该足够让你理解这个想法了。

数字列表的移动平均值类似于算术平均值,但我们不是计算所有数字的平均值,而是计算前“n”个数字的平均值(n 是指窗口大小或时间段),然后将窗口移动(或滑动)1 个索引,从而排除第一个元素并包括 n+1 个元素,然后计算它们的平均值。这个过程还在继续。这里有一个例子来说明这一点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

excel 表中的 SMA 示例

这是一个窗口大小为 6 的 SMA 示例。前 6 个元素的形状记忆合金以橙色显示。现在把上面的第一列当作你选择的股票的收盘价。现在计算 sma_6 右侧连接的 14 个其他窗口尺寸(7 到 20)的收盘价 SMA。现在,数据集的每一行都有 15 个新要素。对其他 14 个技术指标重复这一过程,删除空行。

使用的一些指标是 SMA 的延伸。例如,WMA(加权移动平均线)是前“n”天的平均值,最近几天的权重较大。类似地,HMA(赫尔移动平均线)是 WMA 的延伸,有以下步骤:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:【Fidelity.com

现在你有 225 个新功能。如果你把这些数字重组为一个 15x15 的数组,你就有一个图像了!(虽然,在这一点上,它是一个单一的渠道。稍后将详细介绍)。不过,有一件事要记住。在构建这些图像时,我们应该保持相关技术指标在空间上接近。直觉是,当训练人脸识别时,如果一张照片的一只眼睛在鼻子下面,你不会把它标为人脸。相关像素应该在附近。为了简洁起见,我不公布计算所有指标的代码。您可以在 utils.py 文件中找到它们。

**标注:**现在剩下的就是标注这个数据集。为此,作者使用了以下算法:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用于将数据集标记为买入/卖出/持有的算法

乍一看,这似乎令人生畏,但它说的就是:在收盘价上使用 11 天的窗口。如果中间数是窗口内的最大值,则将中间日标记为“卖出”,或者,如果中间数是最小值,则将中间日标记为“买入”,否则标记为“持有”。像前面解释的那样滑动窗户,然后重复。这个想法是在任何 11 天的窗口期内,在波谷买入,在波峰卖出。这个算法的能力是一个不同的问题,我将在最后讨论这个问题。

**训练:**作者使用了滚动窗口训练,类似于我们上面看到的滑动窗口概念。如果您有 2000 年到 2019 年的股票历史数据,并且您决定对 5 年的数据进行训练,对 1 年的数据进行测试,那么,从数据集中分割 2000-2004 年的数据用于训练,2005 年的数据用于测试。根据这些数据训练和测试您的模型。接下来选择 2001–2005 作为训练数据,2006 作为测试数据。使用相同的模型对此数据进行重新训练。重复直到你到达终点。

**计算性能评估:**作者在论文中提供了两种类型的模型评估,计算和财务评估。计算评估包括混淆矩阵、F1 分数、类精度等。财务评估是通过将模型预测应用于真实世界交易并测量所获得的利润来完成的。我将只讨论计算评估。财务评估可以通过真实世界的交易或对持有的数据进行回溯测试来完成,我将在以后的文章中讨论这一点。

2.履行

正如本文开头提到的,我没有严格遵循研究论文,因为它没有产生预期的结果。当它们出现时,我会提到它们的不同之处。但是随着我所做的改变,结果与论文持平,在某些情况下甚至更好。

数据处理相关代码可以在 data_generator.py 中找到

**数据来源:**我通常从 Alpha Vantage 获取股票数据,该公司免费提供历史股票数据。我在之前的项目中也用过它。以下是下载数据的方法。

url = "[https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&outputsize=full&apikey=api_key&datatype=csv&symbol=company_code](https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&outputsize=full&apikey=api_key&datatype=csv&symbol=company_code)"
urllib.request.urlretrieve(url, path_to_save)

数据是这样的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**特色工程:**第一个偏离论文的是我用的技术指标。我找不到论文中提到的一些指标的库/实现,比如 PSI。有些指标就是不清楚;例如, PPO 是用周期 12 和 26 的 EMA 计算出来的。如何才能计算出不同时期的 PPO?我尝试使用论文中提到的大多数指标,我发现这些指标的开源实现可以避免任何编程错误。我已经实现了一些指标,如 WMA,HMA 等,虽然他们很慢,需要优化。因为我只需运行一次并保存数据,所以这对我来说不成问题。不过,你可以选择不同的指标。他们还用调整比率调整了价格(开盘价、最高价、最低价等)。但我没有遵循这一条,因为我找不到任何关于如何调整的参考资料。构建这些特性的所有函数都在 utils.py 文件中。

**标注数据:**对于这篇博客,我使用了作者们用过的原始标注算法。下面是它的一个直接实现:

要素构造和标注后的数据集如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**归一化:**我用的是 Sklearn 的 MinMaxScaler 对[0,1]范围内的数据进行归一化,虽然论文用的是[-1,1]范围(二次偏差)。这只是个人喜好。

**特征选择:**在计算了这些指标,根据它们的类型(动量、振荡器等)在图像中对它们进行分组,并训练了许多 CNN 架构之后,我意识到模型只是学习不够。也许功能不够好。因此,我决定采用许多其他指标,而不严格遵循用不同时期计算它们的规则。然后我使用特征选择技术选择了 225 个高质量的特征。事实上,我使用了两种特征选择方法 f_classif 和 mutual_info_classif,并从它们的结果中选择了共同的特征。原论文中没有提到特征选择,所以第三个偏差。

最后,我在排序索引列表时发现了 f_classif 和 mutual_info_classif 的交集。这是为了确保相关特征在图像中非常接近,因为我已经附加了相似类型的指示器。特征选择显著提高了模型的性能。

**将数据重塑为图像:**到目前为止,我们有一个包含 225 个特征的表格数据。我们需要把它转换成这样的图像:

这是图像的样子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练图像

**处理类别不平衡:这类问题难以解决的另一个原因是数据严重不平衡。“持有”操作的实例数量将总是比“买入/卖出”多得多的。事实上,论文中提出的标记算法产生了相当多的买/卖实例。任何其他现实世界的策略都会产生更少的实例。更复杂的是,“暂停”事件的分类并不简单(在最后会有更多介绍)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于模特来说,这真的很难学到任何有意义的东西。这篇论文只提到“重采样”是解决这个问题的一种方法。我尝试过过采样,合成数据生成(SMOTE,ADASYN),但没有一个给出任何满意的结果。最后,我满足于“样本权重”,其中你告诉模型更多地关注一些样本(第四个偏差)。这在处理阶级不平衡时很方便。以下是计算样品重量的方法:

然后将这个样本权重数组传递给 Keras 的“拟合”函数。您还可以查看“class_weights”参数。

***培训:*所有与培训相关的代码都可以在 stock_keras.ipynb 中找到。论文中提到的模型架构缺少一些要点。例如,他们没有提到他们使用的步幅。但是在 stride=1 和 padding=same 的情况下,我发现这个模型太大了,尤其是对 5 年的数据进行训练。无论我使用多么小的网络,我在滑动窗口训练中都没有任何运气。所以我用交叉验证的全训练数据训练(第五偏差)。但是我已经在项目中包含了滑动/滚动窗口训练的代码(在“train.py”文件中)。所以,我用了一个非常相似的模型,有一些小的不同,比如辍学等等。这是我用来训练的模型(我没有尝试过大范围的超参数调优):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Keras 模型训练是通过 EarlyStopping 和 ReduceLROnPlateau 回调完成的,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正如你在上面看到的,我用 F1 分数作为衡量标准。对于测试数据评估,我还使用了混淆矩阵、Sklearn 的加权 F1 分数和 Kappa(这是我最近才知道的,必须深入挖掘)。

在沃尔玛的数据上,上述模型给出了以下结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每次运行时,这个结果都会有些变化,这可能是由于 Keras 权重初始化造成的。这实际上是一个众所周知的行为,这里有一个很长的讨论线索。简而言之,你必须为 numpy 和 tensorflow 设置随机种子。我只为 numpy 设置了随机种子。所以我不确定它是否能解决这个问题。我会在这里更新,一旦我尝试了。但大多数时候,对于我尝试过的大多数其他 CNN 架构,0 类和 1 类(买入/卖出)的精度低于 2 类(0/1 类为 70)。

作者得到了以下结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

道琼斯 30 指数的结果在文件中提出

如果你注意到,“持有”类的分数明显比“买入/卖出”类的分数差,无论是在我们的结果中还是在论文中。我认为这个结果很有希望,因为模型可以识别大多数的买/卖实例。以下是作者对此的看法:

“然而,也产生了许多虚假的入境和出境点。这主要是由于“买入”和“卖出”点出现的频率比“持有”点少得多,神经网络不容易捕捉“很少”的进入点和退出点而不危及主导“持有”值的一般分布。换句话说,为了能够捕捉到大多数“买入”和“卖出”点(回忆),该模型通过为不存在的进入点和退出点(精度)生成错误警报来进行权衡。此外,持有点不像“买入”和“卖出”(山丘和山谷)那样清晰。神经网络很可能会将一些“持有”点与“买入”点和“卖出”点混淆,特别是当它们靠近滑动窗口上的山顶或谷底时。

3.进一步的改进

  • 在更好的网络架构和超参数调整方面,肯定有很大的空间。
  • 在其他数据集上使用具有相同架构的 CNN 并没有给出令人印象深刻的买卖精确度。但通过摆弄超参数,我们肯定可以将其提高到与沃尔玛相似的数字。
  • 虽然这些结果看起来足够好,但不能保证它会给你带来真实世界交易的利润,因为它会受到你选择标记数据的策略的限制。例如,我对上述交易策略进行了回溯测试(使用原始标签,而不是模型预测!)但是我没赚多少。但那取决于数据的标注。如果有人使用更好的策略来标记训练数据,它可能会表现得更好。
  • 探索其他技术指标可能会进一步改善结果。

4.结论

我带着怀疑的态度开始了这个项目。我不确定这些图像是否有足够的信息/模式供 ConvNet 查找。但由于结果似乎比随机预测好得多,这种方法似乎很有前途。我特别喜欢他们将时间序列问题转化为图像分类的方式。

UPDATE- 12/7/2020: 重大更新-标签创建出现 bug,将标签分配给窗口最后一天,而不是中间项。我也用新的结果更新了这篇文章。在“stock_keras.ipynb”中更新了新模型

GitHub 上也有代码修复。请注意,由于我已经转移到 PyTorch,我不再有一个工作 Tensorflow 环境,我在云上训练这个模型,并且必须复制粘贴修复。所以,我无法完全测试最终代码(训练部分)。

插入了由于我的 GitHub 账户的改变而丢失的代码。

UPDATE- 23/2/2020: 我刚刚在我的模型创建函数“create_model_cnn”中发现了一个 bug,在这里我使用下面的检查来添加 MaxPool 层:

*if params["conv2d_layers"]['conv2d_mp_1'] == 1
replace this with
if params["conv2d_layers"]['conv2d_mp_1'] >= 0*

对“conv2d_mp_2”也进行同样的操作。模型或程序本身没有任何问题,只是我一直在探索没有任何最大池的超参数搜索空间:-(。需要探索模型是否可以在 MaxPool 层中表现得更好。

更新- 09/02/2020 :增加了对“特性工程”章节中一些更复杂的技术指标的解释。

使用主成分分析进行股票市场分析

原文:https://towardsdatascience.com/stock-market-analytics-with-pca-d1c2318e3f0e?source=collection_archive---------6-----------------------

从主成分分析到资本资产定价

主成分分析(PCA)是一种强大的数据分析工具,用于机器学习的许多领域。然而,尽管它的多功能性和有效性,它在金融中的应用并没有被广泛讨论。

今天,我将谈论 PCA 如何用于股票市场,它如何与资本资产定价模型(CAPM)相关,以及我们如何使用 PCA 来分析 COVID19 的影响。

(你可以在这里找到完整的代码和其他资源

1.PCA 快速回顾

第一个主成分解释了数据中的大部分差异。

简而言之,主成分分析(PCA)将数据分解成许多称为主成分的向量,这些向量实质上“总结”了给定的数据。更具体地说,这些摘要是输入特征的线性组合,试图尽可能多地解释数据中的差异。按照惯例,这些主成分按照它们能够解释的方差大小排序,第一个主成分解释了大部分数据。

2.资本资产定价模型快速回顾

股票的收益可以分解为:(1)无风险资产的收益,(2)市场因素的收益,以及(3)股票的特殊收益。总的来说,市场因素是所有股票回报的主要驱动力。

资本资产定价模型(CAPM)是一个著名的资产(如股票)收益定价框架,与现代投资组合理论有许多有趣的联系,我将在以后的文章中讨论。

在深入 CAPM 的细节之前,理解无风险资产和市场因素的概念是很重要的。无风险资产本质上是一种能给你带来几乎无风险回报的资产(如政府债券)。相反,市场因素监测整个股票市场的整体状况,通常通过 S&P500 等指数来衡量。一般来说,整个市场比政府债券更不稳定/风险更大,但它也为投资者提供了更多的回报。

记住这些定义,让我们看看 CAPM 的证券市场线(SML)的概念。在实践中,SML 将一只股票的收益分解为三个主要因素:

  1. r_f :无风险回报
  2. *【beta _ I (r _ m-r _ f):市场因子回报
  3. :特质回归

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

证券市场线方程 —作者图片

这个等式背后的直觉是:

(1)一只股票的回报至少应该等于无风险资产的回报(否则为什么要冒额外的风险呢?)

(2)资产的收益也用市场因素来解释,市场因素用术语 (r_m-r_f) (衡量市场相对于无风险资产的超额收益)和*【β_ I】*(衡量资产受市场因素影响的程度)。

(3)股票的回报也受到特质因素的影响,特质因素是股票特有的因素(例如,股票的收益发布只影响该只股票,而不影响整体市场)。

从经验上来说,市场因素是股市回报的主要驱动力,因为它往往可以解释任何给定股票在任何给定日期的大部分回报。

3。PCA 和 CAPM 之间的联系

W 当将 PCA 应用于每日股票收益时,第一个主成分近似于市场因子。

让我们考虑 S&P500 指数中的 500 只股票,并计算它们的日回报率,如下图所示。

**rs = prices.apply(np.log).diff(1) 
rs.plot(title='Daily Returns of the Stocks in the S&P500')**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

S&P500 中股票的每日收益——图片由作者提供

**crs = rs.cumsum().apply(np.exp)
crs.plot(title='Cumulative Returns of the Stocks in the S&P500')**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

S&P500 中股票的累计收益—图片由作者提供

上图显示了自 2020 年初以来,S&P500 500 只股票的每日回报率和累计回报率。原始数据的数量可能看起来非常庞大,因此让我们通过 PCA 计算日收益率的第一个主成分来处理它们。下图显示了第一个主成分的值,它实际上是一个维数为 500 的向量,包含 500 只股票中每只股票的值。

**from sklearn.decomposition import PCApca = PCA(1).fit(rs.fillna(0))
pc1 = pd.Series(index=rs.columns, data=pca.components_[0])pc1.plot(xticks=[], title='First Principal Component of the S&P500')**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

S 的第一个主成分& P500 返回—作者图片

回想一下:( 1)第一个主成分代表解释大部分方差的输入数据的线性组合,以及(2)股票回报的主要驱动因素是整体市场因素。这意味着,如果我们通过将现金按比例分配到第一主成分(即输入数据的线性组合)来制定股票投资组合,我们可以近似复制 S&P500 的回报(即股票回报的主要驱动因素)。

**weights = abs(pc1)/sum(abs(pc1)) # l1norm = 1
myrs = (weights*rs).sum(1)rs_df = pd.concat([myrs, market_rs], 1)
rs_df.columns = ["PCA Portfolio", "S&P500"]crs_df = rs_df.cumsum().apply(np.exp)
crs_df.plot(subplots=True);**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用基于五氯苯甲醚的投资组合复制 S&P500—作者图片

如上图所示,我们的 PCA 投资组合可以作为市场因素的代理,市场因素是股票回报的主要驱动因素(因此解释了大部分差异!).请注意,虽然它们是相似的,但 PCA 组合并不完全复制 S&P500,因为 S&P500 是 500 只股票的市值加权平均值,而 PCA 组合中的权重受解释的方差的影响。

4.使用 PCA 分析 COVID19 的影响

使用主成分分析,我们可以将受 COVID19 疫情影响最大/最小的企业聚集在一起,而无需事先了解它们的基本面。

你可能知道,由于疫情飓风的影响,2020 年对股票市场来说是疯狂的一年。使用主成分分析,我们可以分析这个疫情如何影响个股。

例如,让我们看看第一个主成分,并选择具有最大和最小负 PCA 权重的股票,如下所示。

**fig, ax = plt.subplots(2,1)pc1.nsmallest(10).plot.bar(ax=ax[0], color='green', grid=True, title='Stocks with Most Negative PCA Weights')pc1.nlargest(10).plot.bar(ax=ax[1], color='blue', grid=True, title='Stocks with Least Negative PCA Weights')**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 PCA 权重分析股票—作者图片

请注意上图中最负面的股票是旅游和能源板块。这是有道理的,因为 COVID19 严重影响了旅游业务,以及为这些业务提供燃料的能源公司。另一方面,受影响最小的公司属于消费品行业,这也是有道理的,因为该行业受益于检疫措施带来的消费品销售增长。

因此,通过应用 PCA,我们能够将受 COVID19 疫情影响的最佳和最差企业聚集在一起,而无需事先了解它们的基本面!

此外,我们可以制定一个获胜的投资组合,即根据 PCA 权重排名前 10 位的公司。如下图所示,由此产生的投资组合的表现将明显好于市场,因为它投资于实际受益于疫情的公司。

请注意,该投资组合带有前瞻性偏差,其中投资组合权重是使用市场低迷时期不可用的未来数据计算的。因此,以这种方式使用的 PCA 是一种回顾性的分析工具。关于前瞻偏差以及如何避免它们的更多信息,请查看这篇文章

**myrs = rs[pc1.nlargest(10).index].mean(1)
mycrs = myrs.cumsum().apply(np.exp)
market_crs = market_rs.cumsum().apply(np.exp)mycrs.plot(title='PCA Portfolio vs. S&P500')
market_crs.plot()plt.legend(['PCA Selection', 'S&P500'])**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用 PCA 跑赢市场——作者图片

我希望你喜欢这篇文章!如果你想看更多这样的内容,请关注我。

此外,查看我的网站的完整代码和其他资源。

股票市场和比特币价格关系——Python 分析

原文:https://towardsdatascience.com/stock-market-and-bitcoin-price-relationship-python-analysis-f39f992201c7?source=collection_archive---------19-----------------------

股票市场和比特币(BTC)价格之间有关系吗?

通过对 Python 和 Pandas 的分析,我们将能够在本文中回答这个问题。首先我们将检索,使用一个免费的 API,过去几年的比特币和股票价格。然后,我们将计算股市和比特币价格之间的相关性。最后,我们将通过 相关性矩阵图 来结束绘制相关性的分析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Rick 在 Unsplash 上轻拍

比特币在经济中的作用

自从比特币的出现之后,我就一直想知道比特币在我们的经济中有什么作用。以下是三个潜在角色:

  • 比特币是否有类似黄金的作用?黄金被认为是安全的投资。也就是说,当经济步入衰退时,黄金价格往往会上涨,因为投资者会从股票转向黄金。这有助于投资者减少股市崩盘给他们的投资组合带来的潜在损失。如果比特币一直在投资界扮演安全天堂的角色,我们应该会看到股票和比特币价格之间的负相关关系。
  • 另一个可能的作用是比特币跟随金融市场的趋势。也就是说,如果股票价格正在上涨,这种实证主义会传染吗,因此,在比特币价格中也是可见的吗?
  • 我们分析的第三个潜在结果可能是,比特币价格与股市完全没有关系。

让我们用 Python 来了解一下吧!

用 Python 检索股票市场价格和比特币价格

为了获得数据来执行我们的分析,我将使用financialmodelingprepAPI 来检索比特币价格。他们还提供免费的股票数据,但为了向您展示两种不同的获取数据的方式,我将使用 Pandas DataReader 来检索股票数据。

作为我们市场数据的代理,我们将使用 S & P 500 指数标准普尔 500 指数是一个衡量在美国上市的 500 家最大公司股票表现的指数。我们将使用 Pandas DataReader 下载 SP500 价格和美联储经济数据(FRED) 作为来源。

如果你以前从未使用过Pandas**DataReaderPandas ,你将需要安装这些软件包。你可以通过使用 pip 命令来完成。

pip install pandas_datareader #Pandas data reader may not work with the latest Pandas version, therefore, I recommend you to install Pandas version 0.24: pip install pandas==0.24.2

太好了,现在我们可以用 Python 检索数据了。首先,我们将提取过去十年的 S&P500 股票价格。注意,通过使用 web,我们可以很容易地获得我们称之为 SP500 的熊猫系列中的数据。DataReader 并指定系列名称(即 sp500 )和供应商(即 fred )

pd.core.common.is_list_like = pd.api.types.is_list_likeimport pandas_datareader.data as web
import datetimestart = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2020, 2, 10)SP500 = web.DataReader(['sp500'], 'fred', start, end)
print(SP500)

上面的代码行将返回下面的标准普尔 500 熊猫系列,其中包含 S&P 过去 10 年的价格:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

标准普尔 500 价格

现在让我们检索比特币价格。为此,我们将使用financialmodelingprep API。我们将向 API 端点发出一个 http get 请求,该请求将返回一个包含历史 BTC 价格的字典:

import requests#BTCUSD contains a dictionary
BTCUSD = requests.get('[https://financialmodelingprep.com/api/v3/historical-price-full/crypto/BTCUSD'](https://financialmodelingprep.com/api/v3/historical-price-full/crypto/BTCUSD'))BTCUSD = BTCUSD.json()
BTCUSD = BTCUSD['historical']

我们解析包含在关键字名称历史中的字典。如果你不熟悉如何解析 API 响应,我推荐你阅读下面的文章

print(BTCUSD)[{'date': '2020-02-15',
  'open': 10315.651367,
  'high': 10341.555664,
  'low': 10226.138672,
  'close': 10244.959961,
  'adjClose': 10244.959961,
  'volume': 42347495424.0,
  'unadjustedVolume': 42347495424.0,
  'change': 70.69141,
  'changePercent': 0.685,
  'vwap': 10270.88477,
  'label': 'February 15, 20',
  'changeOverTime': 0.00685},
 {'date': '2020-02-14',
  'open': 10211....
    ....
    ...]}

现在,通过查看 BTCUSD 变量的内容,我们可以看到 BTCUSD 是一个字典列表,列表中的每个元素都是包含比特币价格的不同日期。BTC 价格存储在关闭键下。

例如,我们看到在 2 月 15 日,比特币的价格是 10244 美元。

我们需要将字典列表转换成熊猫数据框架。我们可以使用 pd 轻松做到这一点。DataFrame.from_dict() :

BTC = pd.DataFrame.from_dict(BTCUSD)
BTC.set_index('date',inplace=True)#Keep only the close column
BTC = BTC[['close']]#Rename the column name to BTC
BTC.columns = ['BTC']
BTC

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

BTC 价格

最后,我们在两只熊猫数据框中给出了 BTC 和标准普尔 500 的价格。现在,我们只需要将它们合并在一起。幸运的是,对于 Python 和熊猫来说,这很容易做到。

我们可以使用 pd.merge 来连接索引上的两个数据帧,因为索引包含了日期。因此,我们想在比赛日加入 S & P500 和 BTC 价格。

我们可以通过参数 right_indexleft_index 等于 True 来让 Pandas 知道我们想要使用该索引进行合并。更多细节见 Pandas 合并文档

SP500BTC = BTC.merge(SP500, how='inner',right_index = True, left_index=True)#Drop NA since we have nan values for weekends. S&P500 only trades business days
SP500BTC.dropna(inplace=True)print(SP500BTC)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

BTC 和标准普尔 500 的价格

比特币与标准普尔 500 价格的关系

太好了,我们已经为分析准备好数据了。现在,我们可以继续寻找股票和比特币价格之间的关系。

为此,我们可以使用 Pandasdata frame . corr()来查找 Pandas DataFrame 列的相关性:

correlation = SP500BTC.corr()
print(correlation)###Result:BTC     sp500
BTC    1.000000  0.834106
sp500  0.834106  1.000000

如何解读 BTC 和标准普尔 500 房价的相关性?

相关矩阵的值范围从-1 到 1。更接近+1 意味着两个变量紧密地在一起,并且向同一个方向移动。值 0 表示变量之间没有关系。而负相关表示变量朝不同方向移动。越接近-1,反比关系越强。

通过研究我们的结果,我们发现比特币价格和标准普尔 500 指数之间存在 0.83 的强正相关性。这意味着当股票市场的价格上涨时,我们可以预计比特币也会跟随趋势上涨。

我们也可以通过使用 matplotlibstatsmodels 来可视化这种相关性:

from statsmodels import api as sm
import matplotlib.pyplot as pltsm.graphics.plot_corr(correlation,xnames=list(correlation.columns))
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

BTC 和 S&P500 相关矩阵

图表中的红色意味着这种关系是牢固和积极的。我们还可以使用Lin regressivescipy.stats 来检查这种关系在统计上是否显著:

#statistically significant?from scipy.stats import linregress
linregress(SP500BTC['sp500'],SP500BTC['BTC'])#H0: BTC and Stock prices are not related#Results:
LinregressResult(slope=8.956910705798713, intercept=-18068.59091142212, rvalue=0.8341059841835341, pvalue=0.0, stderr=0.1673358700767462)

由于我们的 p 值低于 0.05,我们可以拒绝 H0,因此,我们可以从统计上说,比特币和股票价格正在一起移动。

包扎

使用 Python 和 Pandas,我们分析了股票市场和比特币价格之间的关系。根据我们的分析结果,我们可以说 BTC 和标准普尔 500 价格同向移动。

我们很想知道这种关系在衰退的商业周期中是否也成立。为了进行这样的分析,我们可能需要等待一段时间,因为在过去几年中,我们一直生活在一个扩张的经济中。

请参见下面的完整脚本:

import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_likeimport pandas_datareader.data as web
import datetimestart = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2020, 2, 10)
SP500 = web.DataReader(['sp500'], 'fred', start, end)import requests
BTCUSD = requests.get('[https://financialmodelingprep.com/api/v3/historical-price-full/crypto/BTCUSD'](https://financialmodelingprep.com/api/v3/historical-price-full/crypto/BTCUSD'))
BTCUSD = BTCUSD.json()
BTCUSD = BTCUSD['historical']BTC = pd.DataFrame.from_dict(BTCUSD)
BTC.set_index('date',inplace=True)
BTC = BTC[['close']]
BTC.columns = ['BTC']SP500BTC = BTC.merge(SP500,how='inner',right_index = True, left_index=True)
SP500BTC.dropna(inplace=True)correlation = SP500BTC.corr()
print(correlation)from statsmodels import api as sm
import matplotlib.pyplot as plt
sm.graphics.plot_corr(correlation,xnames=list(correlation.columns))
plt.show()#statistically significant?
from scipy.stats import linregress
linregress(SP500BTC['sp500'],SP500BTC['BTC'])

原载于 2020 年 2 月 15 日 https://codingandfun.com

股市灯实时跟踪器

原文:https://towardsdatascience.com/stock-market-lamp-real-time-tracker-b2d0562a71c3?source=collection_archive---------37-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如何使用 Python 实时跟踪自己的投资组合

不用说,在这个疫情,股票市场一直不稳定。由于我们大多数人都被困在家里,我决定建造一个很酷的彩灯来实时反映我的股票市场投资组合。这样,当股票市场开盘时,我的灯会打开,它的颜色会反映我的开仓头寸,并在一天内更新。这是一个很酷的小工具,我还没有看到购买,所以为什么不建立自己的。我不喜欢日内交易,因为很多原因,我坚信大多数人不应该日内交易。因此,灯与其说是焦虑的制造者,不如说是一个有趣的配件。

材料清单

这里是你需要建立你的股市灯实时追踪器。如果你已经拥有一个彩色灯泡,你可以检查是否有一个库或 API 来通过 http 发送命令。在这种情况下,我们使用一个 Yeelight,它有一个 Python 库。

黄色灯泡

灯泡球

基本上,你会有一个 Wi-fi 智能灯和它的颜色变化从你的 Python 代码。地球仪是一个外壳,使它看起来很漂亮。

Python 代码灯泡控件

创建新的 python 项目。安装我们将使用的两个主要库:

pip install yeelight investpy

安装 yeelight 手机 app,配置灯泡。在应用程序中,打开局域网控制。在灯泡->设置(右上角图标)->设备信息中获取灯泡的 IP 地址。检查灯泡是否工作。

from yeelight import Bulb, BulbException
BULB_IP = **'192.168.X.XXX'** bulb = Bulb(BULB_IP)
bulb.get_properties(requested_properties=[**'power'**, ])

Python 代码股票市场

接下来,您可以创建一个函数来确定股票的 PnL

def daily_pnl(stock):
    stock_data = investpy.get_stock_historical_data(stock, **'united states'**, from_date=(date.today() +
        timedelta(days=-1)).strftime(**"%d/%m/%Y"**), to_date=date.today().strftime(**"%d/%m/%Y"**))
    stock_data.index = stock_data.index + timedelta(days=1)
    ytd = stock_data.iloc[0].Close
    tdy = stock_data.iloc[1].Close
    return ((tdy-ytd)/ytd)*100

简单地通过一只股票,如“AAPL”应该返回前一天的利润或损失。

最后,你所要做的就是将 PnL 范围转换成 RGB 颜色。

def refresh_bulb_color(bulb):
    pnl_to_color = {-1.0: **'#ff1100'**,  *# <1%+ loss* -0.5: **'#ff6a00'**,
                    0.0: **'#ffffff'**,  *# neutral* 0.5: **'#8fb2ff'**,
                    1.0: **'#0004ff'**,}  *# >+0.5% gain* pnl = daily_pnl(**'AAPL'**)
    print(**"{:.2f}%"**.format(pnl))
    pnl_idx = np.searchsorted(list(pnl_to_color.keys()), pnl, **'left'**).clip(0,4)
    color = list(pnl_to_color.values())[pnl_idx]
    rgb = tuple(int(color.lstrip(**'#'**)[i:i+2], 16) for i in (0, 2, 4))

    try:
        bulb.set_rgb(rgb[0], rgb[1], rgb[2])
    except BulbException:
        logging.error(**'bulb disconnected'**)
        return False

    return True

创建无限循环并设置刷新间隔。你可以调整 PnL 函数来反映你自己的投资组合,而不是单一的股票。

就是这样!你有自己的实时彩灯跟踪器。

股票市场的结果目前是伯努利分布

原文:https://towardsdatascience.com/stock-market-outcomes-are-currently-bernoulli-distributed-c2fbde004745?source=collection_archive---------40-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

西蒙Unsplash 上的照片

这对股票风险意味着什么

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

我们目前正站在十字路口。刺激还是不刺激?有疫苗还是没有疫苗?COVID 和住院治疗的增长趋势还是快速平台期?

这些问题目前无法回答——每个人都有自己的看法,但没有人知道答案。

这种对未来的巨大不确定性是 VIX(衡量标准普尔 500 回报的预期远期波动性,也就是年化标准差)在股市徘徊在历史高点附近的情况下仍然顽固走高的原因。我以前写过这种现象:

[## VIX 怎么了?

了解 VIX 以及它想告诉我们什么

medium.com](https://medium.com/alpha-beta-blog/whats-up-with-the-vix-88b0a724d9fb)

什么是 VIX,我们为什么要关注它?

金融和数据科学有很多重叠之处。我会在之前的链接中详细介绍,但是让我们快速回顾一下 VIX 是什么。

VIX 是标准普尔 500 的隐含波动率。换句话说,是市场预期的标准普尔 500 指数(未来 30 天)收益的年化标准差。它是通过标准普尔 500 指数上一篮子期权的价格计算出来的(隐含波动率是期权价格的一个关键驱动因素,因此给定价格,我们可以取消隐含波动率)。

尽管它声称是前瞻性的,但从历史上看,VIX 看起来很像标准普尔 500 在过去 30 天的中的实际波动——所以它不是很有前瞻性:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

VIX 与过去 30 天实现的波动性(来源:Sharadar,图形由作者创建)

但这并不意味着它完全没有信号。包括我自己在内的许多投资者抱怨说,在潜在的灾难性经济背景下,市场最近表现得自满。

尽管原始股价并没有反映出太多的担忧,但隐含波动率却反映了。看下面这个散点图。它绘制了标准普尔 500 指数相对于其历史高点(x 轴)和 VIX (y 轴)的交易位置。它们之间有一个明显的负关系——这意味着当标准普尔 500 指数接近其历史高点或创下新高时,VIX 往往较低(当出现大幅下跌时,VIX 往往较高)。

****注:**VIX 水平比如说 50 可以解释为未来 30 天的预期年化波动率为 50%。这意味着预期的 30 天波动率为 50%/sqrt(12) = 14.4%。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

标准普尔 500 从之前的峰值下降对 VIX(来源:沙拉达尔,图形由作者创建)

蓝色圆点是 2020 年 8 月 1 日之前的所有交易日(从 2010 年 1 月 1 日到 2020 年 7 月 31 日),橙色圆点是 2020 年 8 月 1 日及以后的所有交易日。注意对于给定的水位降深(在 x 轴上),橙色点位于或超出蓝色点的顶部范围。

这意味着市场的行为有些反常——在股票市场水平的控制下,VIX 高于历史水平。

作为参考,今年 2 月,在所有的疯狂之前,SPY(一个受欢迎的标准普尔 500 ETF)的交易价格在 335 左右。与此同时,VIX 指数为 13.7(年化隐含波动率为 13.7%)。在我写这篇文章的时候,间谍的价值比二月份的时候高了 343,但是 VIX 的价值是 29——是以前的两倍多!换句话说,尽管股票价格已经完全恢复,但标准普尔 500 在未来一个月的波动性预计将增加一倍。

主要的实际影响是投资组合保险(VIX 看涨期权和标准普尔 500 看跌期权)今天比今年年初贵得多。这使得对冲股票风险变得更加困难。

为什么会出现这种情况?

新闻会说些老一套——选举不确定性、经济焦虑、软银收购大量科技股看涨期权,等等。

没错,这些都会对边际利润产生影响。但我觉得答案更简单。通常,当我们展望未来时,市场回报预计大致呈正态分布(如果你想了解细节,请参见下面的链接博客)。

* [## 股票收益是正态分布吗?

从概率分布中得出的预期与真实世界的股票回报匹配吗?

towardsdatascience.com](/are-stock-returns-normally-distributed-e0388d71267e)

如果你把所有的日收益率绘制在柱状图上,它应该看起来或多或少像一条钟形曲线,事实确实如此:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实际回报分布与理论回报分布(来源:Sharadar,图片由作者创作)

目前,市场收益不是正态分布的。下面,我绘制了标准普尔 500 过去两个月的每日收益分布图(橙色)和 COVID 市场崩盘前两个月的收益分布图(蓝色)。注意橙色分布看起来是双峰的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实际回报分布与理论回报分布(来源:Sharadar,图片由作者创作)

最近,市场行为可以被描述为——当市场参与者降低他们获得更多政府刺激的可能性时,市场下跌。当他们提高政府刺激的可能性时,市场就会上涨。

但最终,答案要么是肯定的,要么是否定的。要么是经济得到足够的刺激,在柯维德退出的同时启动它,要么是没有。换句话说,我们要么得到一个快乐的结果,要么得到一个悲伤的结果,没有中间的

那样的双峰结果可以用 伯努利分布 来建模。伯努利分布随机变量的一个例子是掷硬币——要么你得到概率为 p 的正面,要么得到概率为 1-p 的反面。

这就像现在的股票市场——要么事情变好(刺激、疫苗、经济复苏),要么事情变坏(刺激不够、疫苗不起作用、经济灾难)。

伯努利分布随机变量的标准差为:

**Standard deviation of Bernoulli random variable
  = p*(1 - p)**Where p is the probability of success.

让我们想出一些数字,并计算一个标准差。假设以下情况:

  • 事情有 75%的可能会好起来。
  • 如果情况好转,市场将上涨 20%。
  • 如果事情变得糟糕,市场将崩溃-50%。

我们可以计算股票市场的预期标准差如下:

stock market standard deviation**= (0.2-(-0.5)) * (0.75*(1-0.75))**0.5 = 30.3%
which implies of VIX of 30.3**** denotes exponent

这非常接近目前观测到的 VIX 水平 29.3。如果您想仔细检查上述计算,可以运行以下 Python 代码。它产生相同的答案。

import numpy as npresult = []
for i in range(100000):
    if np.random.random() > 0.75:
        result.append(0.2)
    else:
        result.append(-0.5)

np.std(result)

伯努利分布回报的风险更大

29.3 挺高的。作为参考,在过去十年中,标准普尔 500 的平均实现 30 天波动率为 16.5%。

我之前认为隐含波动率太高,因此期权溢价很高。我不再这么想了。抛硬币的结果很可怕,因为风险很大。你可能会对我在上面的计算中使用的输入数据提出异议,但很明显,如果健康和经济状况不能很快好转,情况将会变得更糟。美联储和 QE 能做的就这么多了。

为什么我说伯努利分布收益风险更大?想象两个游戏:

  1. 游戏 1: 你掷 100 枚硬币。对于每枚硬币,如果是正面,你就赢 1500 美元,如果是反面,你就输 1000 美元。第一场的结果将是正态分布的。**
  2. ***游戏二:*你只抛一枚硬币。如果是正面,你赢 15 万美元,如果是反面,你输 10 万美元。第二场比赛的结果将是伯努利分布。

这两款游戏的预期价值都是 25000 美元。但他们显然不平等。第二场比赛风险更大——要么你很富有,要么你损失了一大笔钱。我们可以用下面的代码模拟这两个游戏:

*# 100K simulations of  Game 1 - Flip 100 coins
all_results = []
for j in range(100000):
    result = 0
    for i in range(100):
        if np.random.random() > 0.5:
            result += 1500
        else:
            result += -1000
    all_results.append(result)

print('Game 1:', np.mean(all_results), np.std(all_results))# 100K simulations of  Game 2 - Flip 1 coin
result = []
for i in range(100000):
    if np.random.random() > 0.5:
        result.append(150000)
    else:
        result.append(-100000)

print('Game 2:', np.mean(result), np.std(result))*

从我的代码输出中,我可以看到第一场游戏(我们掷 100 枚硬币)的标准差是 12,500 美元。相比其 25,000 美元的预期价值,这已经相当不错了。

另一方面,游戏 2 的标准差为 125,000 美元!与预期值相比,这是一个巨大的数字。

我们可以用两个游戏模拟结果的直方图来形象化这一点。尽管预期收益相同,游戏 2 显然有更大的下跌风险。在第一场比赛中赔钱的可能性很小(即使这样,你也只输了一点点)。在第二场比赛中,你有 50%的概率会丢失大量的零钱。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

游戏 1 和游戏 2 的结果直方图(图形由作者创建)

虽然这个例子是程式化的,但它在精神上类似于当前的市场形势。在面临抛硬币时,股市参与者目前面临着前所未有的不确定性。虽然它可能没有被计入股市估值,但它被计入了 VIX,这与投资保险的价格相对应。大家小心!

更多真实故事

* [## iBuyers 为房地产市场带来便利和流动性

但是这些东西值得花几千块钱买吗?

medium.com](https://medium.com/alpha-beta-blog/ibuyers-bring-convenience-and-liquidity-to-the-real-estate-market-fb1c99f9fcd6) [## 了解线性回归

数据科学的主力

towardsdatascience.com](/understanding-linear-regression-94a6ab9595de)*

用 Python 进行股票新闻情绪分析!

原文:https://towardsdatascience.com/stock-news-sentiment-analysis-with-python-193d4b4378d4?source=collection_archive---------6-----------------------

对财经新闻进行秒级情感分析!

跟上金融和特定股票的新闻对你的交易策略非常有益,因为它通常会决定价格的变化。因此,我创建了这个算法,可以轻松快速地解析 FinViz 股票筛选程序,并计算任何输入股票的新闻标题的情绪。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 StockSnap 来自 Pixabay

FinViz 无疑是网络上最强大的股票筛选工具之一。它可以免费获取大量信息,包括交互式图表、70 多个基本比率、大型银行交易数据以及几乎任何股票的最新新闻标题。如果你以前从未使用过 FinViz,我在下面附上了苹果公司的数据截图,以及我们将在本文中收集的数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AAPL 的基本比率和互动图表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

FinViz 为 AAPL 提供内幕交易信息和最新新闻标题。

第二个屏幕截图中的蓝色信息是更新的新闻标题,这正是我们将要抓取和执行情感分析的内容。既然我们已经检查了我们将使用的数据,让我们进入代码!

导入和参数

要开始,首先导入以下模块,并根据您的喜好设置参数。变量 n 表示将为‘ticker’列表中的每个 ticker 显示的文章数量。代码的其余部分将不必手动更新,这些是您每次运行代码时必须更改的唯一参数。

从 FinViz 获取新闻数据

接下来,我们将使用模块 BeautifulSoup 和 requests 从 FinViz 网站获取新闻数据。该代码解析新闻 HTML 表的 URL,并遍历滚动条列表,收集每个滚动条最近的标题。对于每一只输入的股票,都会打印出“n”个最近的头条,以便于查看数据。

反复阅读新闻

为了执行情感分析,数据必须采用正确的格式,因此这段代码遍历收集到的新闻,并将其分类为一个列表,包括报价器、日期、时间和实际标题。

执行情感分析

使用功能强大的 nltk 模块,可以分析每个标题的极性分值,分值范围为-1 到 1,其中-1 表示高度负面,1 表示高度正面。

查看结果数据

最后,数据已经准备好以一种吸引人的方式进行操作和查看。对于输入列表中的每个跑马灯,将创建一个新的数据帧,包括其标题和各自的分数。最后,将创建一个最终的数据帧,其中包括每个报价器在所有最近解析的新闻中的平均情绪值。

解析算法的所有代码

上面的 GitHub 要点包含了这篇文章的所有代码。我希望这个算法将来对你有用。非常感谢您的阅读!

免责声明:本文材料纯属教育性质,不应作为专业投资建议。自行决定投资。

如果你喜欢这篇文章,可以看看下面我写的其他一些 Python for Finance 文章!

[## 使用 Python 在几分钟内解析数千份股票推荐!

了解如何在不到 3 分钟的时间内解析顶级分析师的数千条建议!

towardsdatascience.com](/parse-thousands-of-stock-recommendations-in-minutes-with-python-6e3e562f156d) [## 用 Python 制作股票筛选程序!

学习如何用 Python 制作一个基于 Mark Minervini 的趋势模板的强大的股票筛选工具。

towardsdatascience.com](/making-a-stock-screener-with-python-4f591b198261) [## 在 3 分钟内创建一个财务 Web 应用程序!

了解如何使用 Python 中的 Streamlit 创建技术分析应用程序!

towardsdatascience.com](/creating-a-finance-web-app-in-3-minutes-8273d56a39f8)

使用最先进的转换器和时间嵌入进行股票预测

原文:https://towardsdatascience.com/stock-predictions-with-state-of-the-art-transformer-and-time-embeddings-3a4485237de6?source=collection_archive---------0-----------------------

给交易机器人输入最新的股票预测

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由晨酿Unsplash 拍摄

在我之前的文章中,我分享了我第一次预测股票价格的研究结果,这些结果随后将被用作深度学习交易机器人的输入。在将我的数据集升级到数以千计的股票报价机,相当于几乎1tb 的股票价格历史和新闻文章的同时,我开始意识到我最初使用由LSTM(LONG-SshortTermM记忆模型和 CNN ( C 组成的神经网络的方法因此,为了克服这些限制,我必须实现一个专用于股票时间序列转换器**。**

近年来,变压器因其出色的性能而广受欢迎。将自我关注机制、并行化位置编码结合在一起,在处理需要语义特征提取和大型数据集的任务时,通常比经典的 LSTM 和 CNN 模型更具优势[1]。

由于我无法找到一个简单的转换器实现,它是为具有多种特征的时间序列定制的,例如,我们股票数据的(开盘、盘高、盘低、收盘、成交量)特征,所以我必须自己实现它。在这篇文章中,我将分享我对股票数据的转换架构,以及什么是时间嵌入,以及为什么必须将它们与时间序列结合使用。

数据

出于本文的解释目的,我们将使用 IBM 股票价格历史作为 1tb 股票数据集的简化版本。尽管如此,您可以轻松地将本文中的代码应用到更大的数据集。IBM 数据集从 1962 年 1 月 2 日开始,到 2020 年 5 月 24 日结束,总共包含 14699 个交易日。此外,每个交易日,我们都有 IBM 股票的开盘价高开低开收盘价以及交易量**、、**。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

IBM 的每日收盘价和成交量

数据准备

价格和交易量特征被转换成每日股票收益和每日交易量变化,应用最小-最大标准化,并且时间序列被分成训练、验证和测试集。将股票价格和交易量转换为每日变化率增加了数据集的稳定性。因此,模型从我们的数据集中获得的知识对未来预测具有更高的有效性。这里概述了转换后的数据是什么样子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

IBM 的每日收盘价回报和成交量变化

最后,训练集、验证集和测试集被分成长度为 128 天的单独序列。对于每个序列日,有 4 个价格特征(开盘价、盘高、盘低、收盘价)和交易量特征,每天有 5 个特征。在单个训练步骤中,我们的 Transformer 模型将接收 32 个序列 (batch_size = 32) ,它们是 128 天长的 (seq_len=128) ,并且每天有 5 个特征作为输入。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型输入矩阵的大小

时间嵌入

作为 Transformer 实现的第一步,我们必须考虑如何将隐藏在股票价格中的时间概念编码到我们的模型中。

在处理时间序列数据时,时间是一个基本特征。然而,当使用转换器处理时间序列/顺序数据时,序列通过转换器架构一次转发,这使得提取时间/顺序依赖性变得困难。因此,与自然语言数据结合使用的转换器倾向于利用位置编码为模型提供词序的概念。详细地说,位置编码是单词的值及其在句子中的位置的表示,允许转换器获得关于句子结构和单词相关性的知识。一个位置编码的例子可以在BERT**【2】模型的引擎盖下找到,该模型已经为许多语言任务实现了最先进的性能。**

类似地,一个转换器在处理我们的股票价格时需要一个时间概念**。如果没有时间嵌入,我们的转换器将不会收到任何关于股票价格时间顺序的信息。因此,2020 年的股票价格对未来价格预测的影响与 1990 年的**价格相同。当然,这将是可笑的。****

时间 2 向量

为了克服转换器的时间差异,我们将实现论文 Time2Vec:学习时间的向量表示【2】中描述的方法。论文作者提出了“一种与模型无关的时间向量表示,称为time 2 vec 你可以把向量表示想象成普通的嵌入层可以添加到神经网络架构中,以提高模型的性能。**

将这篇论文归结为它的要点,有两个主要观点需要考虑。首先,作者发现有意义的时间表示必须包括周期性和非周期性模式**。周期性模式的一个例子是随不同季节而变化的天气。相反,非周期性模式的一个例子是一种疾病,随着患者年龄的增长,这种疾病发生的概率很高。**

**其次,时间表示应具有对时间缩放的**不变性,意味着时间表示不受不同时间增量(如天、小时或秒)和长时间范围的影响。

结合周期和非周期模式的思想以及对时间缩放的不变性,我们由下面的数学定义给出。别担心,这比看起来容易,我会详细解释的。😉

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

时间向量的数学表示— Time2Vec:学习时间的向量表示[3]

时间向量/表示法***t2v***由两部分组成,其中***ωᵢτ + φᵢ***表示时间向量的非周期性/线性特征,***F(ωᵢτ + φᵢ)***表示时间向量的周期性特征。

用一种更简单的方式重写***t2v(τ) = ωᵢτ + φᵢ***,新版本***y = mᵢx + bᵢ*** 应该看起来很熟悉,因为它是你从高中就知道的线性函数的普通版本。***ωᵢτ + φᵢ***中的***ω***是定义我们的时间序列***τ***的斜率的矩阵,***φ*** 简单来说就是定义我们的时间序列***τ*** 与 y 轴的交点的矩阵。因此,***ωᵢτ + φᵢ***无非是一个线性函数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

非周期时间特征的 2D 表示

第二分量***F(ωᵢτ + φᵢ)***代表时间向量的周期性特征。就像之前我们又有了线性项***ωᵢτ + φᵢ***,然而,这次线性函数被包装在一个额外的函数***F()***中。作者试验了不同的函数来最好地描述周期关系(sigmoid、tanh、ReLU、mod、triangle 等。).最终,一个正弦函数取得了最好和最稳定的性能(余弦函数取得了类似的结果)。当组合线性函数***ωᵢτ + φᵢ***和正弦函数时,2D 表示如下。***φ*** 沿 x 轴移动正弦函数,***ω*** 决定正弦函数的波长。****

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

周期性时间特征的 2D 表示

让我们看一下 LSTM 网络的精度与时间向量(Time2vec)的不同非线性函数的组合是如何变化的。我们可以清楚地看到, ReLU 函数执行最差最差**,相比之下,正弦函数优于所有其他非线性函数。ReLU 函数具有如此不令人满意的结果的原因是,ReLU 函数对于时间缩放不是不变的。函数对时间缩放的不变量越高,性能越好。**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

非线性函数的性能比较— Time2Vec:学习时间的向量表示[3]

时间 2 矢量性能改进

在我们开始实现时间嵌入之前,让我们看看普通 LSTM 网络(蓝色)和 LSTM+Time2Vec 网络(红色)的性能差异。正如您所看到的,建议的时间向量不会导致多个数据集的性能下降,并且几乎总是会提高模型的性能。有了这些认识,我们就可以继续实现了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有和没有时间向量的 LSTM 网络的性能比较— Time2Vec:学习时间的向量表示[3]

Time2Vector Keras 实施

好了,我们已经讨论了时间向量的周期和非周期分量在理论上是如何工作的,现在我们将在代码中实现它们。为了使时间向量易于集成到任何种类的神经网络架构中,我们将向量定义为 Keras 层。我们定制的 Time2Vector 层有两个子函数def build():def call():。在def build():中我们初始化了 4 个矩阵,2 个为***ω*** 和 2 个为***φ*** 因为我们需要一个***ω******φ***的矩阵来兼顾非周期性(线性)和周期性(正弦)的特性。

seq_len = 128def build(input_shape):
   weights_linear = add_weight(shape=(seq_len), trainable=True)
   bias_linear = add_weight(shape=(seq_len), trainable=True) weights_periodic = add_weight(shape=(seq_len), trainable=True)
   bias_periodic = add_weight(shape=(seq_len), trainable=True)

启动 4 个矩阵后,我们定义一旦调用该层将执行的计算步骤,因此有了def call():函数。

将由 Time2Vector 层接收的输入具有以下形状(batch_size, seq_len, 5) → (32, 128, 5)batch_size定义了我们希望一次将多少股票价格序列输入模型/层。seq_len参数决定单个股票价格序列的长度。最后,数字5来源于这样一个事实,即我们有 IBM 每日股票记录的 5 个特征(开盘价、最高价、最低价、收盘价、成交量)。

第一个计算步骤排除了成交量,取开盘价、最高价、最低价和收盘价的平均值,得到形状(batch_size, seq_len)

x = tf.math.reduce_mean(x[:,:,:4], axis=-1)

接下来,我们计算非周期(线性)时间特征,并再次将维度扩展 1。(batch_size, seq_len, 1)

time_linear = weights_linear * x + bias_lineartime_linear = tf.expand_dims(time_linear, axis=-1)

对周期性时间特征重复相同的过程,也产生相同的矩阵形状。(batch_size, seq_len, 1)

time_periodic = tf.math.sin(tf.multiply(x, weights_periodic) + bias_periodic)time_periodic = tf.expand_dims(time_periodic, axis=-1)

结束时间矢量计算所需的最后一步是连接线性和周期性时间要素。(batch_size, seq_len, 2)

time_vector = tf.concat([time_linear, time_periodic], axis=-1)

时间 2 矢量层

将所有步骤组合成一个层函数,代码如下所示。

变压器

现在我们知道了提供时间的概念以及如何实现时间向量是很重要的,下一步将是转换器。转换器是一种神经网络架构,它使用自我关注机制,允许模型关注时间序列的相关部分**,以提高预测质量。自关注机构由单头关注多头关注层组成。自我关注机制能够立即将所有时序步骤相互连接,导致长期依赖理解的创建。最后,所有这些过程都在 Transformer 架构中被并行化,从而加速了学习过程。**

结合 IBM 数据和时间特性——为转换器提供信息

在实现了时间嵌入之后,我们将结合 IBM 的价格和数量特性使用时间向量作为转换器的输入。 Time2Vector 层接收IBMpricevolume 特征作为输入,并计算非周期性周期性** 时间特征。在随后的建模步骤中,计算出的时间特征与价格和数量特征连接在一起,形成一个形状为(32, 128, 7)的矩阵。**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

计算时间特性并与 IBM 价格和交易量连接

单头注意力

IBM 时间序列加上我们刚刚计算的时间特征形成第一单头注意层的初始输入。单头关注层总共取 3 个输入(查询,键,值)。对我们来说,每个查询、键和值输入都代表了 IBM 的价格、数量和时间特性。每个查询、键和值输入都通过单独的密集层接受单独的线性转换**。为密集层提供 96 个输出单元是个人的架构选择。**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

单头注意力-查询、键和值输入的线性转换

在初始的线性变换之后,我们将计算注意力得分/权重。注意力权重决定了在预测未来股价时,对单个时间序列步骤的关注程度。注意力权重通过取线性变换的查询和键输入的点积来计算,而变换的键输入已经被转置以使得点积乘法可行。然后点积除以先前密集层(96)的尺寸大小,以避免爆炸梯度。然后,被划分的点积通过 softmax 函数产生一组权重,其总和为 1** 。作为最后一步,计算出的确定每个时间步焦点的 softmax 矩阵与转换后的 v 矩阵相乘,得出单头注意机制。**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

单头注意力—在对查询、键和值输入进行线性转换后计算注意力权重

由于插图对于最初的学习来说是很好的,但缺乏实现方面,我为你们准备了一个干净的单注意力 Keras 层函数🙂。

多头注意力

为了进一步完善自我注意机制,论文作者提出了实施多头注意**【4】。多头注意力层的功能是 c ***n*** 单头注意力层注意力权重进行处理,然后对密集层应用非线性变换。下图显示了 3 个单头层的连接。**

拥有***n***单头层的输出允许将多个独立的单头层转换编码到模型中。因此,该模型能够同时关注多个时间序列步骤。增加注意力头的数量会积极地影响模型捕捉远距离依赖性的能力。[1]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

多头注意力层

同上,多头注意力层的干净实现。

变压器编码器层

单头和多头注意机制(自我注意)现在被聚合到一个 transformer 编码器层中。每个编码器层包含一个自关注子层和一个前馈子层。前馈子层由两个致密层组成,其间有 ReLU 激活。

另一方面,如果 Conv 层的核大小和步距为 1,则密集层可以用 1 维卷积层代替。具有所述配置的密集层和卷积层的数学是相同的。

每个子层之后是一个丢失层,丢失后,通过将初始查询输入添加到两个子层输出来形成剩余连接。结束每个子层,在剩余连接附加之后放置一个标准化层,以稳定和加速训练过程。

现在我们有了一个现成的 Transformer 层,它可以很容易地堆叠起来以提高模型的性能。由于我们不需要任何变压器解码器层,我们实现的变压器架构与 BERT [2]架构非常相似。尽管不同之处在于时间嵌入,我们的转换器可以处理三维时间序列,而不是简单的二维序列。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

变压器编码器层

如果您想深入研究代码,我们开始吧。

具有时间嵌入和转换器层的模型架构

总之,我们首先初始化时间嵌入层以及 3 个变换器编码器层。初始化之后,我们将一个回归头堆叠到最后一个 transformer 层上,训练过程开始。

结果

训练过程总共有 35 个时期。在训练之后,我们可以看到,我们的转换模型只是预测了一条位于每日股价变化之间的平坦线。当仅使用 IBM 股票历史时,即使是变压器模型也仅仅能够预测股票发展的线性趋势。得出的结论是,股票的历史价格和交易量数据只包含足够的线性趋势预测的解释价值。然而,当将数据集升级到数千个股票报价机(1tb 数据集)时,结果看起来完全不同🙂。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传****外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

验证和测试数据集+预测

将移动平均应用于股票数据—特征工程

如上所示,即使是最先进的模型架构也无法从历史股价和交易量中提取非线性股票预测。但是,当对数据应用简单的移动平均平滑效果时(窗口大小=10),模型能够提供明显更好的预测(绿线)。该模型也能够预测涨跌,而不是预测 IBM 股票的线性趋势。然而,当仔细观察时,您仍然可以看到该模型在具有极端日变化率的日子中具有较大的预测增量,因此我们可以得出结论,我们仍然存在异常值问题。

应用移动平均效果的缺点是新的数据集不再反映我们的原始数据。因此,具有移动平均线效应的预测不能用作我们的交易机器人的输入。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传****外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

移动平均特征-验证和测试数据集+预测

然而,由于移动平均效果的平滑化,可以在不应用移动平均的情况下实现性能的提高。我的最新研究表明,当将数据集扩展到大量股票时,可以获得相同的表现。

本文给出的所有代码都是可以端到端运行的笔记本的一部分。笔记本可以在 GitHub 上找到。

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

谢谢你,

一月

编辑于 2022 年 6 月 1 日:

在过去,我收到了一些反馈和请求,希望我的金融资产预测模型能够变得可用且易于使用。这将有助于人们回答以下问题:

有哪些好的资产可以投资?我应该把什么放入我的金融投资组合?

我给你介绍一下pink lionwww . pink lion . XYZ

** [## 粉色狮子

我们把你从乏味和令人沮丧的工作中解脱出来。没有更多的清洁数据和模型试验和…

www.pinklion.xyz](https://www.pinklion.xyz/)

PinkLion 是一款基于我的代码库之上的产品,它使成千上万只股票、基金/ETF 和加密货币的日常资产数据可用。此外,通过提供对基础预测模型的访问,它允许资产分析和投资组合的动态优化。

目前,注册人数仍然有限,因为单个计算需要大量的服务器资源。

请随意尝试并提供反馈。(目前还处于大致状态) www.pinklion.xyz**

放弃

本文中的任何内容都不构成任何特定证券、证券组合、交易或投资策略适合任何特定人士的建议。期货、股票和期权交易包含巨大的损失风险,并不适合每个投资者。期货、股票和期权的估值可能会波动,因此,客户的损失可能会超过他们的原始投资。

参考

[1]为什么要自我关注?神经机器翻译架构的目标评估https://arxiv.org/abs/1808.08946

**[2]伯特:语言理解深度双向转换器的预训练【https://arxiv.org/abs/1810.04805 **

**[3] Time2Vec:学习时间的向量表示法【https://arxiv.org/abs/1907.05321 **

[4]你所需要的只是关注https://arxiv.org/abs/1706.03762

基于深度学习的股票价格预测

原文:https://towardsdatascience.com/stock-price-prediction-based-on-deep-learning-3842ef697da0?source=collection_archive---------2-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由杰米街Unsplash

机器学习如何用于投资?

众所周知,如果人们能够破解咒语成功预测股票价格,股票市场就是一个可以发财的地方。尽管在大多数情况下不可能准确预测股票价格。所以,问题来了,如果人类可以估计并考虑所有因素来预测股票的走势或未来价值,为什么机器不能?或者,换句话说,我们如何让机器预测一只股票的价值?长期以来,全世界的科学家、分析师和研究人员一直在试图设计一种方法来回答这些问题。

在这篇文章中,我将尝试展示一种所谓的算法交易方法。这是一个完全基于研究目的的方法。请不要基于这种算法进行投资。那么,我们开始吧。

整个想法

股票价格可能取决于当前世界和股票市场中的几个因素。我们将尝试考虑两个主要因素的组合:

  1. 其他公司股价的影响和相关性,即其他公司股价的涨跌如何影响特定目标公司的股价
  2. 目标公司过去的业绩和记录

我看过几个博客,大多关注其中一个因素,主要是第二个因素。我认为,如果我们能设法将这两个因素都考虑进去,我们就能使我们的预测器更加可靠。

因此,我尝试使用三种深度学习模型的组合来实现这一点。首先,基于神经网络的回归模型考虑了其他公司对目标公司的影响。其次,一个递归神经网络模型来研究目标公司的过去行为并相应地给出结果。为此,我使用了 LSTM 层。最后,一个人工神经网络,接受他们的预测,并帮助达成一个坚定和稳健的结论。

资料组

在本文中,我们将使用标准普尔 500 公司数据库,尽管我只使用了 200 家公司的详细信息。我用网络清理从维基百科页面收集了 S&P 名单。我用这个作为一个来源,因为它是实时更新的。我在一些博客里看到过这个方法,所以我也用过。这似乎是一个可靠的来源。

import bs4 as bs
import pickle
import requestsdef save_tickers():
 resp=requests.get('[https://en.wikipedia.org/wiki/List_of_S%26P_500_companies'](https://en.wikipedia.org/wiki/List_of_S%26P_500_companies'))
 soup=bs.BeautifulSoup(resp.text)
 table=soup.find('table',{'class':'wikitable sortable'})
 tickers=[]
 for row in table.findAll('tr')[1:]:
  ticker=row.findAll('td')[0].text[:-1]
  tickers.append(ticker)with open("tickers.pickle",'wb') as f:
  pickle.dump(tickers, f)return tickerssave_tickers()

这个代码将帮助你放弃 500 强公司的股票。

然后我用熊猫网络数据阅读器从雅虎收集了他们的详细信息。

import bs4 as bs
import pickle
import requests
import datetime as dt
import os
import pandas as pd
import pandas_datareader.data as webdef fetch_data():
 with open("tickers.pickle",'rb') as f:
   tickers=pickle.load(f)if not os.path.exists('stock_details'):
  os.makedirs('stock_details')
 count=200start= dt.datetime(2010,1,1)
 end=dt.datetime(2020,6,22)
 count=0
 for ticker in tickers:
  if count==200:
   break
  count+=1
  print(ticker)

  try:
    df=web.DataReader(ticker, 'yahoo', start, end)
    df.to_csv('stock_details/{}.csv'.format(ticker))
  except:
    print("Error")
    continuefetch_data()

这段代码将有助于使用 web 阅读器从 Yahoo 收集数据。我保留了 200 个,因为我只想使用 200 个公司详细信息。在这 200 家公司中,我们将有一个目标公司和 199 家公司,这将有助于达成对我们的目标公司的预测。

该代码将生成一个“stock_details”文件夹,其中包含从 2010 年 1 月 1 日到 2020 年 6 月 22 日的 200 份公司详细信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

文件

每个细节文件都将被保存在它的股票代码中。我选择了亚马逊作为我的目标股票。因此,我将尝试预测亚马逊的股票价格。它的股票代码是 AMZN。

那么,让我们来看看细节文件的结构。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结构

这是结构。它将“日期”作为索引特征。“高”表示一天中的最高值。“低”表示最低。“开盘”是开盘价,“收盘”是当天的收盘价格。现在,有时公司会规定接近值。因此,最终值是“调整收盘”值,如果股票价格不受管制,它与“收盘”值相同。“交易量”是指该日该公司的股票交易量。

我们将把每只股票的这种“可调接近”价值视为每只股票对我们目标股票的贡献特征。因此,我们将把每只股票的 Adj Close 重命名为相应的股票代码,并将其包含在我们的特性集中。

import os
import pandas as pd
import pickledef compile():
 with open("tickers.pickle",'rb') as f:
   tickers=pickle.load(f)main_df=pd.DataFrame()for count,ticker in enumerate(tickers):
  if 'AMZN' in ticker:
   continue
  if not os.path.exists('stock_details/{}.csv'.format(ticker)):
   continue
  df=pd.read_csv('stock_details/{}.csv'.format(ticker))
  df.set_index('Date',inplace=True)df.rename(columns={'Adj Close': ticker}, inplace=True)
  df.drop(['Open','High','Low',"Close",'Volume'],axis=1,inplace=True)if main_df.empty:
   main_df=df
  else:
   main_df=main_df.join(df,how='outer')print(main_df.head())
 main_df.to_csv('Dataset_temp.csv')compile()

这个代码片段将帮助我们选择除了我们的目标股票 AMZN 之外的每只股票的调整后收盘列,将该列重命名为 ticker,并将其合并到我们的功能集中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特征文件的结构

它会产生一个这样的特性集。日期是索引,与日期相对应的是每个收报机的“Adj Close”值。现在,我们将看到最初有几个空列。这是因为这些公司在 2010 年还没有开始参与股市。这将给我们一个包含 199 个公司值和日期的 200 列的特性集。

现在,让我们关注我们的目标股票 AMZN 股票。如果我们开始可视化目标股票的每个给定列值,我们将获得这些值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分别调整近、低和高可视化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,让我们用蜡烛线符号来想象我们的股票。我用的是熊猫 0.24.2 版本。可能存在一个问题,因为在当前版本中,此模块已被折旧。

import datetime as dt
import matplotlib.pyplot as plt
from matplotlib import style
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mdates
import pandas as pd
df=pd.read_csv('stock_details/AMZN.csv',index_col=0,parse_dates=True)
df_ohlc= df['Adj Close'].resample('10D').ohlc()
df_volume=df['Volume'].resample('10D').sum()
df_ohlc.reset_index(inplace=True)
df_ohlc['Date']=df_ohlc['Date'].map(mdates.date2num)ax1=plt.subplot2grid((6,1), (0,0), rowspan=5, colspan=1)
ax2=plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1 , sharex=ax1)
ax1.xaxis_date()candlestick_ohlc(ax1,df_ohlc.values, width=2, colorup='g')
ax2.fill_between(df_volume.index.map(mdates.date2num),df_volume.values,0)plt.show()

这段代码将为我们提供烛台符号。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

亚马逊股票的蜡烛棒符号

现在,让我们设计一些特征来帮助我们预测我们的目标。

我们将计算 50 移动平均线。这个特性被很多交易者用来做预测。

df['Moving_av']= df['Adj Close'].rolling(window=50,min_periods=0).mean()

这个片段将帮助我们生成移动平均线。实际上,它是第 I 个指数的“Adj Close”值的 i-50 到 I 值的平均值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

移动平均图

现在,我们将尝试获得另外两个特征,即我们股票的成交量增长率和调整后收盘价增长率

i=1
rate_increase_in_vol=[0]
rate_increase_in_adj_close=[0]while i<len(df):
    rate_increase_in_vol.append(df.iloc[i]['Volume']-df.iloc[i-1]['Volume'])
    rate_increase_in_adj_close.append(df.iloc[i]['Adj Close']-df.iloc[i-1]['Adj Close'])
    i+=1

df['Increase_in_vol']=rate_increase_in_vol
df['Increase_in_adj_close']=rate_increase_in_adj_close

这个片段将帮助我们获得这些特性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

调整后收盘增长率和成交量增长率

现在,我们的目标股票的特征文件已经准备好了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

目标库存的特征文件结构

现在,我们将这两个特性文件合并成主特性集。

Index(['High', 'Low', 'Open', 'Close', 'Volume', 'Adj Close', 'Moving_av',
       'Increase_in_vol', 'Increase_in_adj_close', 'MMM',
       ...
       'FITB', 'FE', 'FRC', 'FISV', 'FLT', 'FLIR', 'FLS', 'FMC', 'F', 'Date'],
      dtype='object', length=207)

这些是我们主要特性集的列。

它有 207 列,其中 200 列来自其他公司列表,7 列来自我们的目标股票特性集,锚定在日期列上。所以,我们有 207 列。

回归

在这一部分,我们将研究其他股票对我们的目标股票的影响。我们将尝试预测亚马逊股票的最高价、最低价、开盘价和收盘价。

首先,让我们分析我们的数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

回归相关图。

在这里,我们可以看到我们已经发现了一些相关性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

回归直方图。

因此,从我们的图来看,很明显,我们的数据集中会有一些相关性。因此,接下来,我们从训练数据集中删除开盘、收盘、盘高和盘低值,并将它们用作目标标签或值集。我们还删除了数量和日期,因为它们没有相关性。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

我们把我们的组分成训练组和测试组。

from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error 
from sklearn.metrics import accuracy_scoredef model():
    mod=Sequential()
    mod.add(Dense(32, kernel_initializer='normal',input_dim = 200, activation='relu'))
    mod.add(Dense(64, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(128, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(256, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(4, kernel_initializer='normal',activation='linear'))

    mod.compile(loss='mean_absolute_error', optimizer='adam', metrics=['accuracy','mean_absolute_error'])
    mod.summary()

    return mod

这是我们将用于回归的模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

回归的模型摘要

可以使用以下代码片段运行它:

from tensorflow.keras.wrappers.scikit_learn import KerasRegressor
regressor = KerasRegressor(build_fn=model, batch_size=16,epochs=2000)
import tensorflow as tf
callback=tf.keras.callbacks.ModelCheckpoint(filepath='Regressor_model.h5',
                                           monitor='mean_absolute_error',
                                           verbose=0,
                                           save_best_only=True,
                                           save_weights_only=False,
                                           mode='auto')
results=regressor.fit(X_train,y_train,callbacks=[callback])

为此,我使用了 Keras 回归器。保存了最佳权重并使用了 2000 个纪元。平均绝对误差是我们的损失函数。删除列后,我们的输入为 200。我们将为每个输入获得四个值,高、低、开、闭。

y_pred= regressor.predict(X_test)
import numpy as np
y_pred_mod=[]
y_test_mod=[]for i in range(0,4):
    j=0
    y_pred_temp=[]
    y_test_temp=[]

    while(j<len(y_test)):
        y_pred_temp.append(y_pred[j][i])
        y_test_temp.append(y_test[j][i])
        j+=1

    y_pred_mod.append(np.array(y_pred_temp))
    y_test_mod.append(np.array(y_test_temp))

这给了我们测试集的预测值。这个代码片段有助于以解析的格式获取它们。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分别为高、低、开、闭的回归结果。

现在,我们可以看到我们的模型表现得相当好,考虑到大多数点位于回归线上,很少有异常值。

这里我们完成了回归部分。接下来,我们将移动到 RNN 部分。

递归神经网络

我们将使用 RNN 来分析我们的目标股票。所以我们将只使用目标库存特征文件。现在,这里我们将使用 LSTM 层的工作 RNN 原则,但工作在一个门控的方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Colah

LSTM 有助于 RNN 长时间保持记忆,解决渐变消失和爆炸问题。这里就不详细说了。详情你可以在这里找到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是我们 LSTM 的数据集。

现在,我们需要预测高,低,开放,关闭。因此,现在,我们将删除“日期”,因为它没有相关性。

High         Low        Open       Close    Volume   Adj Close  \
0  137.279999  134.520004  137.089996  134.520004   4523000  134.520004   
1  136.610001  133.139999  136.250000  133.899994   7599900  133.899994   
2  135.479996  131.809998  133.429993  134.690002   8851900  134.690002   
3  134.729996  131.649994  134.600006  132.250000   7178800  132.250000   
4  132.320007  128.800003  132.009995  130.000000  11030200  130.000000       Moving_av  Increase_in_vol  Increase_in_adj_close  
0  134.520004              0.0               0.000000  
1  134.209999        3076900.0              -0.620010  
2  134.370000        1252000.0               0.790009  
3  133.840000       -1673100.0              -2.440002

现在,我们的输入将是这个数据帧的值。因此,我们的输入将有 9 列,相应地,我们的输出将有 4 列,高,低,开放,关闭我们的目标股票。

我们需要为 LSTM 模型创建训练和测试集。

为此,我们将把长度为 2636 条记录的数据分成两部分。我们将使用 0–2200 条记录作为训练集,2200–2636 条记录作为测试集。我们从我们的训练集中选择包含 4 个目标列的目标集。

df_train=df_main[:2200]
df_target=df_train[['High','Low','Open','Close']]

现在,我们缩放数据以使我们的模型易于收敛,因为我们的数据集中有大量不同的值。

sc = MinMaxScaler(feature_range = (0, 1))
target_set=df_target.values
train_set=df_train.values
training_set_scaled = sc.fit_transform(train_set)
target_set_scaled = sc.fit_transform(target_set)

这样,我们就获得了 LSTM 模型的定标数据。

LSTM 模型接受系列数据并产生输出。我们的 LSTM 是多对多的 RNN 模式。所以,我们需要为此产生一系列数据。为此,我们从第 50 个索引开始,并移动到训练集的长度。我们在列表中添加了 0–49,即 50 个值。我们已经为我们所有的功能创建了这样的列表。

因此,我们的输入有(n x 50 x 9)维数据用于我们的训练集。我们有 9 个特性,每个特性都是 50 天的特性值列表。n 是从给定数据集获得的此类序列的数量。现在,我们的目标集是第 51 天目标列的值。

我们通过使用,

X_train = []
y_train = []
for i in range(50,len(train_set)):
    X_train.append(training_set_scaled[i-50:i,:])
    y_train.append(target_set_scaled[i,:])

X_train, y_train = np.array(X_train), np.array(y_train)

现在,让我们观察火车和目标组的形状。

print(X_train.shape)(2150, 50, 9)print(y_train.shape)(2150, 4)

让我们设计我们的模型。

from sklearn.metrics import accuracy_score
from tensorflow.keras.layers import BatchNormalization
import datetime as dt
from sklearn import model_selection
from sklearn.metrics import confusion_matrix
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import Dropoutdef model():
    mod=Sequential()
    mod.add(LSTM(units = 64, return_sequences = True, input_shape = (X_train.shape[1], 9)))
    mod.add(Dropout(0.2))
    mod.add(BatchNormalization())
    mod.add(LSTM(units = 64, return_sequences = True))
    mod.add(Dropout(0.1))
    mod.add(BatchNormalization())

    mod.add((LSTM(units = 64)))
    mod.add(Dropout(0.1))
    mod.add(BatchNormalization())
    mod.add((Dense(units = 16, activation='tanh')))
    mod.add(BatchNormalization())
    mod.add((Dense(units = 4, activation='tanh')))
    mod.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy','mean_squared_error'])
    mod.summary()

    return mod

这是我们的 LSTM 模型。我在这里用过 Keras 层。损失函数是均方误差。我们已经使用了亚当优化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LSTM 模型形状

为了训练我们的模型,我们将使用这个片段。

import tensorflow as tf
callback=tf.keras.callbacks.ModelCheckpoint(filepath='./RNN_model.h5',
                                           monitor='mean_squared_error',
                                           verbose=0,
                                           save_best_only=True,
                                           save_weights_only=False,
                                           mode='auto',
                                           save_freq='epoch')
RNN_model.fit(X_train, y_train, epochs = 2000, batch_size = 32,callbacks=[callback])

我们的模型现在已经训练好了。

让我们专注于测试部分。

我们的测试值有 2200 到 2636 条记录。因此,我们通过选择股票的开盘价、收盘价、最高价、最低价这四列来获得目标值。

df_test=df_main[2200:]
df_target_test=df_test[['High','Low','Open','Close']]
target_set_test=df_target_test.values
test_set=df_test.values

为了进行测试,我们还需要转换我们的测试特征数据集,并为该数据集形成一系列 50 个特征值,就像我们在训练集的情况下所做的那样。

predicted_stock_price = RNN_model.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
print(predicted_stock_price)

这个代码片段有助于获得我们想要的预测结果。

array([[1690.364 , 1610.5382, 1643.4277, 1643.8912],
       [1687.384 , 1607.5323, 1640.3225, 1640.7366],
       [1688.7346, 1608.965 , 1641.6777, 1642.0984],
       ...,
       [2567.6138, 2510.703 , 2522.8406, 2538.787 ],
       [2576.5056, 2519.5195, 2531.803 , 2547.9304],
       [2578.5886, 2521.65  , 2533.9177, 2550.0896]], dtype=float32)

结果就是这样获得的。

现在,如果我们用目标列的实际值相应地绘制它们,我们将获得下面的图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LSTM 取得了成果

如果我们观察,有 4 行,这是因为我们有 4 列作为目标。我们可以看到模型在大部分地方获得了曲线模式。

现在,如果我们分别绘制它们,我们将获得如下 4 幅图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

RNN 的高、低、开和关

因此,我们使用 LSTM,基于股票的过去价值来结束对单个目标股票的研究。现在,我们转到封面或结论部分。

覆盖人工神经网络

现在,这是结论部分。我们使用两个排他性模型研究了可能影响公司股票的两个不同领域,得出了两个不同的结果。现在,我们将尝试合并两个结果。我们将通过合并获得的结果并在整个过程中训练我们的人工神经网络来做到这一点。

对于上面讨论的两个模型,我们有 4 个目标列。对于最后的结论,我们将尝试只预测两列,我们的目标股票的高点和低点。

因此,为此,我们使用这两种模型来预测我们的完整数据集。回归模型产生 2636 个预测值。

代码片段和结果如下:

saved_model_regressor=tf.keras.models.load_model('Regressor_model.h5')
Regressor_prediction=saved_model_regressor(X)
import numpy as np
y_pred_mod=[]for i in range(0,4):
    j=0
    y_pred_temp=[]

    while(j<len(Regressor_prediction)):
        y_pred_temp.append(Regressor_prediction[j][i])

        j+=1

    y_pred_mod.append(np.array(y_pred_temp))
Y_pred=pd.DataFrame(list(zip(y_pred_mod[0],y_pred_mod[1],y_pred_mod[2],y_pred_mod[3])),columns=['High_regress','Low_regress','Open_regress','Close_regress'])

这是片段。它创建一个长度为 2636 的数据帧,包含四个预测值列。

Y_pred.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将其保存为 CSV 格式以备将来使用。

现在,类似地,我们为 LSTM 网络做这个。我们为前 50 个值获取一个值,因为前 50 个值是我们的第一个测试集。因此,除法是 0–49 获得第一个值,1–50 获得第二个值,依此类推。我们从 RNN 总共获得了 2586 个值。

片段:

saved_model_RNN=tf.keras.models.load_model('RNN_model.h5')
RNN_prediction=saved_model_RNN.predict(X_test)
import numpy as np
y_pred_mod=[]for i in range(0,4):
    j=0
    y_pred_temp=[]

    while(j<len(RNN_prediction)):
        y_pred_temp.append(RNN_prediction[j][i])

        j+=1

    y_pred_mod.append(np.array(y_pred_temp))
Y_pred=pd.DataFrame(list(zip(y_pred_mod[0],y_pred_mod[1],y_pred_mod[2],y_pred_mod[3])),columns=['High_RNN','Low_RNN','Open_RNN','Close_RNN'])

该代码片段使用目标值的 RNN 预测生成一个数据帧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们对两个模型的预测都准备好了。我们需要从回归预测中删除 0–50 指数,因为这些值没有 RNN 预测。我们现在准备合并结果。

因此,在合并结果之后,我们获得了具有 8 列的 2586 个值的数据帧。

df**=**pd.concat([df1,df2],axis**=**1)df.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是连接的结果。

整个事情将成为我们的人工神经网络模型的特征集。那么,我们的目标是什么?我们的目标集合将由原始数据集中亚马逊目标股票的原始高值和低值组成。

df1=pd.read_csv("dataset_target_2.csv")
target_high=[]
target_low=[]
i=50
while i<len(df1):
    target_high.append(df1.iloc[i]['High'])
    target_low.append(df1.iloc[i]['Low'])
    i+=1
df['Target_high']=target_high
df['Target_low']=target_lowdf.to_csv('feature.csv',index=False)

这个代码片段有助于合并我们特性集中的所有列。有 10 列。来自两个模型的 8 个特征列和目标股票的高低值作为目标值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的新特性集如下所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是我们的特征直方图。这里,我们也从图中得到了很好的相关性。现在让我们设计和训练我们的人工神经网络模型。

X_Df=df_main[['High_regress','Low_regress','Open_regress','Close_regress','High_RNN','Low_RNN','Open_RNN','Close_RNN']].values
y_Df=df_main[['Target_high','Target_low']].values
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_Df, y_Df, test_size=0.3)

现在,让我们看看我们的模型设计。

from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error 
from sklearn.metrics import accuracy_scoredef model():
    mod=Sequential()
    mod.add(Dense(32, kernel_initializer='normal',input_dim = 8, activation='relu'))
    mod.add(Dense(64, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(128, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(2, kernel_initializer='normal',activation='linear'))

    mod.compile(loss='mean_absolute_error', optimizer='adam', metrics=['accuracy','mean_absolute_error'])
    mod.summary()

    return mod

这是我们的人工神经网络模型。正如我们看到的,我们模型的输入维度是 8。这是因为我们输入了 8 个特征列,其中 4 列来自每个模型的输出。输出层有两个节点,分别用于目标股票的高低栏。

我使用损失函数作为平均绝对误差,优化器作为亚当的优化器。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以使用下面的代码片段运行模型:

import tensorflow as tf
model_ANN=model()
callback=tf.keras.callbacks.ModelCheckpoint(filepath='ANN_model.h5',
                                           monitor='mean_absolute_error',
                                           verbose=0,
                                           save_best_only=True,
                                           save_weights_only=False,
                                           mode='auto')
results=model_ANN.fit(X_train,y_train, epochs = 2000, batch_size = 32,callbacks=[callback])

在我们训练模型之后,我们将使用预测的模型来预测我们的测试集并检查性能。

y_pred=model_ANN.predict(X_test)
import numpy as np
y_pred_mod=[]
y_test_mod=[]for i in range(0,2):
    j=0
    y_pred_temp=[]
    y_test_temp=[]

    while(j<len(y_test)):
        y_pred_temp.append(y_pred[j][i])
        y_test_temp.append(y_test[j][i])
        j+=1

    y_pred_mod.append(np.array(y_pred_temp))
    y_test_mod.append(np.array(y_test_temp))
df_res=pd.DataFrame(list(zip(y_pred_mod[0],y_pred_mod[1],y_test_mod[0],y_test_mod[1])),columns=['Pred_high','Pred_low','Actual_high','Actual_low'])

我们的预测器为每个特征记录预测两个值。因此,这个代码片段有助于获得两列的预测值和测试值,并将它们表示为 Dataframe。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,让我们绘图并检查。

import matplotlib.pyplot as pltax1=plt.subplot2grid((4,1), (0,0), rowspan=5, colspan=1)ax1.plot(df_res_2.index, df_res_2['Pred_high'], label="Pred_high")
ax1.plot(df_res_2.index, df_res_2['Actual_high'], label="Actual_high")plt.legend(loc="upper left")
plt.xticks(rotation=90)plt.show()

这个片段有助于查看预测的和实际的变化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们目标设定变化的高低。

如果我们想检查我们的模特表演。我们可以通过使用下面的代码片段来做到这一点:

fig, ax = plt.subplots()
ax.scatter(y_test_mod[0], y_pred_mod[0])
ax.plot([y_test_mod[0].min(),y_test_mod[0].max()], [y_test_mod[0].min(), y_test_mod[0].max()], 'k--', lw=4)
ax.set_xlabel('Measured')
ax.set_ylabel('Predicted')
plt.show()

这将获得:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们模型的低柱和高柱。

这些线性图表明,我们的模型预测值和实际值之间存在线性关系。

因此,我们的复合模型在预测我们的目标亚马逊股票的高低列值方面做得相当好。因此,我们在这里结束了我们的整个目的。

结论

在本文中,我们看到了如何基于复合神经网络构建算法交易模型。希望这篇文章能有所帮助。

整个 Github 代码是:这里

请在这里找到关于这个主题的进一步任务:。

从新冠肺炎恢复的股票。机器学习来解释。

原文:https://towardsdatascience.com/stocks-that-recovered-from-covid-19-machine-learning-comes-to-explain-ba712f62456d?source=collection_archive---------61-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片凯文·卡登拍摄

亨尼投资

使用机器学习来识别新冠肺炎崩盘后恢复正常的股票中的共同因素。

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

在这篇文章中,我使用机器学习来研究像所有其他公司一样受到新冠肺炎打击的公司,这些公司现在已经恢复正常,而不像其他许多公司。为了更好地说明发生了什么,让我们来看看最近市场最动荡时期的标准普尔 500 指数。

这场新冠肺炎崩盘结束了长达十年的牛市,股价在 2020 年 2 月 20 日至 3 月 23 日之间下跌了 33%。虽然这次衰退对股票市场有整体的负面影响,但并不是所有的公司都受到同样的影响。以下是 1500+ 美国上市公司在此期间的股票市场回报率分布。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

源代码

在 X 轴上,我显示了 2020 年 2 月 20 日至 2020 年 3 月 23 日之间的价格增长。在 Y 轴上,我显示了报告增长的公司的百分比。

我们可以看到大多数公司出现负增长。分布看起来正态,平均值在 -33% 左右,在正回报范围内有一些异常值。一个的好机会出现在识别那些受到不公正打击的公司上。随着投资者开始恐慌并从市场上撤资,几乎所有公司的股价都下跌了。一旦恐慌结束,市场开始逐渐自我修正(一如既往),在新冠肺炎骚乱之前定价合理的公司开始回到它们最初的价格水平,把那些应该修正的公司留在后面。

下图描绘了新冠肺炎危机下降复苏阶段(截至 2020 年 5 月 1 日)的回报率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

源代码

直方图中的下降数据来自之前的图。恢复数据显示了 2020 年 3 月 23 日至 5 月 1 日市场触底后的回报率。与 2020 年 3 月 23 日相比,报告了恢复回报。这一点很重要,因为下降返回 -50%恢复返回 50% 是不一样的。例如,下降50%可能代表价格从二月份的 200 美元下降到三月份的 100 美元。在这种情况下,50%的回报率意味着从 3 月份的 100 美元涨到 5 月份的 150 美元,可以弥补一半的损失。

财务数据

在这项研究中,我使用的是来自 www.vhinny.com 的阿尔法数据集,它提供了 T42 的基本财务数据,包括过去八年的资产负债表、损益表和现金流量表。我还使用免费的 alpha vantage API 来访问每日股票价格。

问题陈述

在这项研究中,我希望找出那些在价格被新冠肺炎修正的压低迅速恢复的公司背后的驱动因素。了解这些驱动因素会为那些希望在未来保护自己并利用这一机会的投资者增加价值。更具体的问题陈述如下:

找出在 2020 年 2 月 20 日至 3 月 23 日期间股价下跌至少 25%,在 3 月 23 日至 5 月 1 日期间股价上涨至少 25%的公司。

方法学

有很多方法可以解决这个问题,从无监督聚类预测建模。我在这里使用的方法利用了预测建模的优势。我的目标不是训练一个预测未来衰退的模型。相反,我的目标是了解过去。带着这个目标,我发现简单的决策树分解是这项工作的最佳方法。

决策树因过度拟合训练数据而臭名昭著。由于这一特性,它们几乎从未用于预测建模,从而产生了随机森林XGBoost 。然而,与其他算法不同的是,决策树提供了对其决策过程的准确可见性,向研究人员展示了决策是如何做出的。

我把这个问题框定为一个分类任务,把那些价格下跌至少 25%的公司贴上标签,然后 T21 上涨至少 25%。数据中只有 10% 的公司符合这个条件。然后,我用以下参数拟合一个决策树:

  • 最大深度:10
  • 一片叶子上的最小样本数:5
  • 最大叶节点数:10

因为我的目标是解释过去而不是预测未来,所以我没有像在典型的预测机器学习问题中那样将数据分成训练和验证组。我使用的参数也不是区分正反例的最佳参数。相反,我为选择的参数将问题限制在易于解释的范围内。这样,稍微牺牲一下性能,我就可以确定并可视化数据中的基本趋势,这正是我所寻找的。

实施情况和结果

下图显示了一个决策树,适合识别在 2 月 20 日至 3 月 23 日期间股价下跌至少 25%且在 2020 年 3 月 23 日至 5 月 1 日期间股价上涨至少 25%的公司。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

源代码

这个决策树适合 1500 多家美国上市公司基本财务数据。每个节点都有一个标签(类),根据该节点上的大多数示例,将每个节点分类为正节点或负节点。我使用红-白-蓝的配色方案来帮助形象化每个节点上积极和消极的平衡。纯红色表示绝大多数例子都是正面的。纯蓝色表示大多数示例都是负面的。随着正面和负面例子的比例趋于相等,颜色变得更加淡化。如果正例的数量等于负例的数量,a 变成白色(全透明)。箭头表示基于节点本身记录的条件的分割。左箭头将符合条件的示例分开,不符合条件的示例留给右箭头

全球趋势

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

源代码

该模型确定的最重要的分割是市值。它的第一个决定是隔离市值≥1 . 2 亿美元的公司。值得注意的是,它没有进一步追踪中盘 中盘大盘股票,只留下了右盘的 990 个负面例子和 77 个正面例子(150 个中)。虽然模型已经决定在第一次分割时将 65%的数据标记为阴性,但这并不意味着没有办法正确地识别右边叶子上的那些 77 阳性样本。这意味着,考虑到我在决策树(参数)上设置的限制,识别它们并不是最佳选择。相反,给定左叶中的约束,它有更好的机会优化目标。

正叶

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

源代码

左分支有六(6)个正节点。这些节点中的每一个都有自己独特的路径(一组条件),投资者必须应用这些路径才能到达那里。通过阐述每条道路背后的故事,可以推断出总体趋势。

国际风险和资本负债的变化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

源代码

一旦公司被缩小到小盘股,汇率的效应就被确定为下一个分割点。鉴于数据的性质,汇率赚了多少钱损失了多少钱可能并不重要,重要的是一家公司是否在国际化经营,是否受到汇率的影响。在有汇率风险(国际化经营)并报告营运资本负债增加超过400 万美元的公司中,发现了小盘股中的正叶**。营运资本负债的变化是现金流量表营运现金流部分的一部分。它本身并不具有很强的指示性,因为它通常由算法未识别的运营资产的变化来平衡。从这里我唯一能得出的结论是公司的资产负债表上有些变化。**

债务

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

源代码

沿着上一节开始的道路,跟踪营运资本负债变化≤ 、400 万美元、的公司,我们发现自己处于评估公司债务偿还的节点。虽然在不知道一家公司有多少债务的情况下评估债务偿还具有挑战性,但是评估债务与股本比率更加简单。债转股节点有 11 家公司,11 家中有 6 家为正。在这些积极的公司中,有五(5) 家公司的资产负债率超过 5%。这是一个有些违反直觉的结论,因为好公司通常被描述为负债较少的公司。然而,5%可能好得令人难以置信,因为它表明该公司几乎完全由股权出资,或者在其报告中有不寻常的事情**。追求 5%+ 的负债权益比率,在这个节点上,我们得到了 6 个正面例子中的 5 个。**

超越破产

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

源代码

另一个正叶标识没有有形国际风险且具有负Z1破产分数的公司(例如,财务状况不佳)。在这种情况下,11 家库存增长至少达到 28 万美元的公司中,有 8 家被正确标记为积极。这一观察表明,投资者可能会将不断增长的库存视为新业务的迹象,尽管财务表现不佳,但仍会支持该公司。

另一个 leaf 列出了在上一个财政年度已经出售价值超过价值33 亿美元证券的公司。由于没有关于他们购买了什么的信息,因此很难合理解释它产生了什么样的净效应。鉴于这一条件正确地识别了 6 个正面例子中的 4 个,一种假设可能是这些公司在新冠肺炎让 T21 贬值之前抛售了证券,使得这些公司有足够的现金来获得投资者的信任。****

结论

在这篇文章中,我分析了 1500 多家美国上市公司的财务状况,这些公司在 2 月 20 日至 3 月 23 日期间股价至少下跌了 25%,在 2020 年 3 月 23 日至 5 月 1 日期间股价至少上涨了 25%。我的发现表明,在小盘股中可能会发现相对简单的关系**。小盘股中的无负债表现出违反直觉的关系,在 5%左右划出一个负债权益比的界限。几乎所有低于 5% 负债权益比的公司的股价都没有那些高于 5%负债权益比的公司恢复得快。尽管财务表现不佳,但在上一个财年增加库存的公司能够迅速恢复股价。从上一财年出售证券中获得有形收益的公司也表现出快速复苏。**

请在此找到支持本研究的代码。

感谢阅读我的文章!如果你喜欢,你可能想看看这个:

** [## 新冠肺炎在股票市场上横冲直撞。机器学习来解释。

使用机器学习来识别新冠肺炎期间受打击最大的股票中的共同因素。

towardsdatascience.com](/covid-19-rampage-on-the-stock-market-machine-learning-comes-to-explain-3332707954af)

我们连线吧!

我很高兴与和我有共同道路的人联系,这是对财务独立的追求。如果你也在寻求经济独立,或者你想和 T2 合作,交流想法,请随时联系我们!以下是一些可以找到我的地方:

  • 【www.vhinny.com——投资研究平台,为您自己的分析提供金融数据
  • https://www.linkedin.com/company/vhinny——加入我们在 LinkedIn 上的社区,在那里我和其他贡献者分享与投资相关的内容

干杯!**

“通用”数据科学生命周期

原文:https://towardsdatascience.com/stoend-to-end-data-science-life-cycle-6387523b5afc?source=collection_archive---------5-----------------------

逐步分析:从业务理解到模型监控

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

安特·罗泽茨基在 Unsplash 上的照片

为了使数据科学生命周期成功,很好地理解每个部分并区分所有不同的部分非常重要。具体来说,理解 开发阶段部署阶段 之间的区别非常重要,因为它们在业务方面有不同的需求需要满足。

大多数数据科学项目都有类似的工作流/结构,您可以使用它们来构建您的项目。下面的生命周期概述了数据科学项目通常经历的主要阶段。它从来都不是一个线性的过程,尽管它会反复运行多次,以试图获得尽可能好的结果,一个既能满足客户又能满足业务的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据科学生命周期(图片由作者提供)

水平线代表典型的机器学习生命周期看起来像是从数据收集开始,到特征工程到模型创建: 模型开发阶段 。左边的竖线代表任何类型项目的初始阶段:问题识别和业务理解,而右边的竖线代表 模型部署阶段 的所有方面。现在,事不宜迟,让我们去找出每个阶段。

问题识别:

像任何问题一样,首先要讨论的是所有业务场景的问题识别,这是我们:

  1. 通过识别真正的潜在问题,清楚地识别问题的根本原因。
  2. 制定详细的问题陈述,包括问题对目标客户/顾客的影响。

你是如何发现问题的?

我们通过收集信息,然后与利益相关者和行业专家交谈来确定问题的根本原因。接下来,合并现有的研究和来自利益相关者的信息可以提供一些对问题的洞察和可能的高级解决方案。考虑可以帮助您更清楚地定义问题的数据源。从做文献回顾开始,如有必要,在数据科学界进行调查。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

问题识别总结(图片由作者提供)

业务理解:

这是定义业务问题的地方,理解业务问题是提出一个好模型的关键,因为它使你理解业务目标。

例如,如果您是信用卡客户,您希望确保我承保可能付款的客户,或者另一个客户可能会发现欺诈客户,因此目的可以是降低风险,同时增加收入。

现在我们已经有了业务理解,我们可以定义 ML 项目的成功标准,成功标准可以基于我们当前正在做的事情。你需要看看这个项目从长远来看是否可行,它是否能给你带来业务优势,让你真正向前推进。

现在有一件事非常明显,但仍然非常重要的是,进入互联网市场的门槛很低,任何人都可以获得大量信息,从商业角度来看,这使得整个市场竞争非常激烈。我们每个人都面临着竞争,因此只有通过不断衡量和跟踪正确的指标,并思考如何移动这些指标来提高您的绩效,我们才能增加脱颖而出的机会。

这就是我们需要正确指标的地方:

KPI(关键绩效指标)

KPI 代表**关键绩效指标:**根据关键业务目标衡量您的绩效。企业利用这一点来衡量他们的业绩目标和整体健康的业务。为每个企业商定正确的 KPI 非常重要,不要陷入追逐看起来很棒但没有意义的虚荣指标的陷阱。

SLA(服务水平协议)

一份服务水平协议(SLA**)**定义了客户对供应商的期望服务水平,列出了衡量服务的标准。例如,如果您正在创建一个非常复杂的管道,您需要满足 100 毫秒的 SLA,并且您必须每秒处理 2000 个事务。您必须确保您将满足您的 SLA 和 KPI 需求,否则,该模型将不会对您有任何好处。

指标不一致会对交易定价、服务交付质量、客户体验、整体业务目标和声誉产生负面影响。最好的方法是监控这些 KPI 和 SLA,例如使用 KPI 仪表板来监控关键结果。

同样,需要记住的一个非常重要的区别是算法目标和业务目标之间的区别。大多数时候,他们可能会被混淆,商业目标必须简单明了。

不应该是:

“降低模型 ecc 的均方误差…”

相反,应该是:

“将我的收入提高 5%”

“吸引更多客户,并将客户数量减少 10%”

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

业务理解摘要(图片由作者提供)

数据采集

一旦我们了解了业务及其目标。我们需要了解数据和所有不同的需求。首先,我们去收集数据。后者可能已经被订购或集中,或者我们可能不得不去单独的源系统并收集我们的模型所需的数据。确定是否有足够的数据推进下一个建模步骤。同样,这个过程经常是迭代的。这是数据采集阶段。这通常是通过 ETL 管道完成的,ETL 代表提取、转换和加载。

抽取、转换、加载至目的端(extract-transform-load 的缩写)

在这一步中,数据被提取、处理并加载到数据仓库中,这通常是通过 ETL 管道完成的,ETL 代表提取、转换和加载。

ETL 是一个 3 步流程:

  • 从单个或多个数据源中提取 数据。
  • 按照业务逻辑转换 数据。转换本身是一个两步过程——数据清理和数据操作。
  • 之前转换的数据加载到目标数据源或数据仓库中。

在数据的转换部分,我们可能需要处理不同的问题,例如缺失值的插补。数据经常包含缺失值或空值,导致模型潜力降低。所以我们试图估算缺失的值。

  1. 对于连续值,我们根据需要使用平均值、众数或中位数填充空值。
  2. 对于分类值,我们使用最频繁出现的分类值。

此外,数据几乎从来没有正确的格式,因此预处理步骤总是必须的,所以识别这些预处理规则例如:日期-时间数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据采集和 ETL 总结(图片由作者提供)

EDA(探索性数据分析)

探索性数据分析部分是我们理解数据、模式等一切的部分…这是通过采用统计和数据可视化来完成的。在这里,我们研究如下信息:

  • 不同的变量是如何相互关联的,它们的分布是什么样的?
  • 变量之间的相关性是什么,寻找数据与目标变量有多好联系的证据?

统计数据

  1. 我们使用 描述性统计 来获得数据的更大图像,这基于数据的属性来描述数据。

描述性统计的四种主要类型是:

  • 测量频率
  • 集中趋势的度量
  • 离差或变化的度量
  • 位置测量

2.我们使用 推断统计 来验证数据集和模型输出的分布,最常用的方法有:

3.最后,我们采用 单变量和多变量分析 来识别从属和独立特征之间的相关性和趋势:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:https://crumplab.github.io/statistics/gifs.html

数据可视化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:靴板

数据可视化在数据科学生命周期中发挥着重要作用,它被用于从数据理解到部署,再到与利益相关者交流业务洞察力的每一个部分。

数据可视化能够生成所有方面的可见见解,只需在图表上绘制一个简单的模式,这使得模式和趋势的识别变得容易得多,而不是只查看电子表格上的数千行和只使用统计数据。

即使从统计数据中提取信息,如果没有良好和适当的可视化,来自没有可视化的数据的洞察力也很难交流,上图是不同类型的可视化的示例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

EDA 摘要(图片由作者提供)

特征工程:

特征工程是利用领域知识通过数据挖掘技术从原始数据中提取特征的过程。这些特征可以用来加强机器学习模型的性能。特征工程可以认为是应用机器学习本身。

“机器学习只占整个数据科学生命周期的 20%到 30 %”

最有意义的特征工程技术用于将数据转换为模型可以更好理解的形式,并处理数据和模式异常:

  • 数据变换技术: 对数变换、平方根变换、分类编码、幂函数和缩放。
  • 处理: S kewed 数据、偏差缓解、宁滨、异常值检测后者识别偏离数据集正常行为的数据点或观察值。异常值数据可以指示关键事件,如技术故障或潜在危险,因此需要相应地处理,否则会误导我们的最终模型。

在将数据转换为正确的格式并处理潜在的数据危险之后,大多数时候,特别是对于高维数据集,我们最终会得到许多特征,我们不能将所有特征输入到机器学习模型中,这不是它的工作方式,这将极大地过度拟合模型。相反,我们必须选择正确数量的功能。这在前面的步骤中,在数据分析或 EDA 中部分完成:然而,当研究变量的相关性时,有一种适当的方法可以做到这一点,这被称为特征选择。

这是三种主要方法:

  • 基于过滤方法: w e 指定一些度量并基于过滤特征,例如:C orrelation、卡方、ANOVA
  • 基于包装器的方法: 我们把一组特征的选择看作一个搜索问题,例如:递归特征消除,向前/向后选择
  • 嵌入方法: 我们使用内置特征选择方法的算法,例如拉索(L1)和岭(L2)回归

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特征工程总结(图片由作者提供)

模特培训

一旦首先准备好对特征进行建模,我们就创建一个基线模型,然后我们进行模型训练,然后我们不断增加模型的复杂性,增加各种算法的测试,看看这个特定的数据集如何响应这个算法,然后你进行超参数调整来设置模型的正确超参数,然后我们应用技术来防止过度拟合,例如交叉验证

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:奥雷利作者:爱丽丝郑

我们需要在数据集上评估训练模型的性能,这发生在测试集上,因为模型可能会过度拟合,不能很好地概括,所以我们必须确保我们消除了模型中的任何偏差,这就是为什么这一部分非常重要。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型训练总结(图片由作者提供)

模型部署

一旦我们训练了模型,模型部署就不是简单的了,我们需要提前考虑。

模型开发很难,但模型部署更难— Srivatsan Srinivasan

在部署之前,我们必须确保测试以下内容:

  • 部署的模型是否符合原始模型的预期。通过使用在开发阶段确定的测试输入集,产生经过验证的结果。
  • 确保数据是干净的,这样它就可以被下游的机器学习组件处理,这样我们就可以通过数据的一致性和质量来加强流程之间的预期和事务。
  • 正在部署的模型是否足够健壮,能够通过测试这些输出的极端值来接受不同范围的输入。

通过在将模型部署到生产环境之前进行持续的定期检查和运行测试,我们可以最大限度地降低和防止模型崩溃的风险,以及影响其下游消费者的风险。

将模型投入生产的不同方式

选择如何将预测模型部署到生产中是一个相当复杂的问题,有不同的方式来处理预测模型的生命周期管理,不同的格式和存储方式,多种方式来部署它们,以及非常广阔的技术前景可供选择。

通常有不同的方法将训练和服务器模型投入生产:

  • 训练:一次性、批量、实时
  • **服务:**批处理,实时(数据库触发器,发布/订阅,网络服务,inApp)

一次性培训

机器学习模型不一定需要不断地训练才能生产,它可以只是训练并推向生产,直到它的性能足够恶化,然后它们被刷新和重新训练。

这种类型的模型部署是进行原型开发和机器学习的数据科学家的首选,典型的模型格式有:

批量训练

批量训练允许具有基于最新训练的模型的不断更新版本。

实时训练

当实时部署这种类型的模型时,需要足够的支持和监控,因为模型可能对新数据和噪声敏感,并且需要不断监控模型性能,这种类型的培训可以通过“在线机器学习模型”来实现,具体来说:

  • k 均值(通过小批量)
  • 线性和逻辑回归(通过随机梯度下降)
  • 朴素贝叶斯分类器

批量 vs 实时预测

在预测/发球方面,在看是设置批量还是实时预测的时候,了解关键的区别是非常重要的。

批量预测的例子 :

批处理作业通常按照某种循环计划生成(例如每小时、每天)。这些预测然后被存储在数据库中,并可以提供给开发者或最终用户。批量推断有时可能会利用 Spark 等大数据技术来生成预测。这使得数据科学家和机器学习工程师可以利用可扩展的计算资源来一次生成许多预测。

实时预测或在线推理的例子:

每当用户通过该服务订购食品时,就会生成 UberEats 估计交付时间。不可能生成一批这样的评估,然后提供给用户。想象一下,在食物到达之后的之前,你不知道要多久才能收到你的订单。其他可以受益于在线推理的应用例子包括增强现实、虚拟现实、人机界面、自动驾驶汽车以及任何允许用户实时查询模型的面向消费者的应用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型部署摘要(图片由作者提供)

模型监控

一旦模型被部署,在一些极端的情况下,模型可能是非性能的,它可能只是抛出垃圾分数,这将影响业务目标等等,因此我们需要持续地监控模型,这部分经常被初学者忽略。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(图片由作者提供)

这里有两个重要的组成部分:

数据漂移分析:我们将来自真实世界的传入数据分布与被评分的数据分布进行比较,如果我们注意到它们之间的一些差异,我们需要选择一个阈值。但是,如果差异很大,则传入的数据会发生漂移。在这种情况下,我们需要回过头来分析差异。

模型漂移分析:我们将现实世界模型分布的分数与已评分的模型分布的分数进行比较,因此在这里,这被输入到一个系统中,该系统持续地向业务用户报告并给出输出。同样,业务部门不会理解准确性、召回率和精确度,如之前在业务理解部分中所述,因此这里的最佳指标是通常在仪表板中找到的 KPI:作为可视化和报告,它会说明例如我们获得了多少客户、我们赚了多少美元以及这在收入流中意味着什么等等。

就数据漂移而言,原因可能是:

  • 上游过程改变,例如传感器被更换,改变了测量单位,损坏的传感器读数总是 0。
  • 数据的自然漂移,如平均温度随季节变化。
  • 特征之间关系的变化。

如何介入?

  • 清除错误的标签
  • 重新训练/校准模型
  • 尽早发现并纠正上游数据问题

如果出现概念或数据漂移,并且您的机器学习模型变得陈旧,如下面左侧图表所示,我们可以在右侧看到,通过随着时间的推移刷新模型,我们可以防止模型随着时间的推移变得陈旧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

资料来源:数据报告

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型监控/警报摘要(图片由作者提供)

结论

这是对数据科学项目流程和整体组织结构及其交互的建议。显然,这个周期有许多变化——出于复杂性的考虑,我没有深入研究模型构建和评估的某些方面,因为这些方面在所有数据科学和 ML 平台中都经常讨论,所以我更喜欢坚持研究其他部分。总结一下:

当采用时,确保选择最适合您的问题的方法,理解具体的用例,并从业务角度出发选择正确的指标:KPI 和 SLA,这将有助于从开发到将 ML 模型部署到生产的正确方法。机器学习不是万能的,如果你可以用更简单的方式解决问题而不采用 Ml,你应该选择它,越简单的解决方案越好。希望你发现这篇文章内容丰富!感谢您的阅读!

你有什么想法?我错过了什么或者我可以改进的吗?请在下面随意评论。我欢迎任何反馈。

参考文献

[## 在生产中部署机器学习模型的不同方法概述

将模型投入生产的方法有很多种,不同的方法会带来不同的好处

www.kdnuggets.com](https://www.kdnuggets.com/2019/06/approaches-deploying-machine-learning-production.html) [## 什么是 KPI?定义、最佳实践和示例

根据关键业务目标衡量您的绩效。关键绩效指标是一个可衡量的值,它…

www.klipfolio.com](https://www.klipfolio.com/resources/articles/what-is-a-key-performance-indicator) [## 模型:从实验室到工厂——硅谷数据科学

在我们的行业中,很多重点放在开发分析模型,以回答关键的业务问题和预测…

www.svds.com](https://www.svds.com/models-lab-factory/) [## 批量推理与在线推理——生产中的 ML

过去几周你一直在训练一个新的机器学习模型。在与产品团队合作定义…

mlinproduction.com](https://mlinproduction.com/batch-inference-vs-online-inference/)

斯多葛派哲学——由算法构建

原文:https://towardsdatascience.com/stoic-philosophy-built-by-algorithms-9cff7b91dcbd?source=collection_archive---------10-----------------------

冥想计划

再现历史上最有权势的人之一所写的斯多葛派哲学

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

马尔科·奥雷里奥半身像——Saiko的“芝加哥艺术学院的古罗马雕塑”由 3.0CC 授权

使用机器学习来生成一个或几个古代文本风格的语言是那些经常给我留下深刻印象的常见应用之一。

马库斯·奥勒留的《沉思录》是斯多葛派哲学的巅峰之作,受到世界各地运动员、企业家和领导人的称赞。

向内看。不要让任何事物的特殊品质和价值逃离你。第六卷

令人难以置信的是,我们可以从像罗马皇帝马可·奥勒留这样的人的内心思想中阅读和学习这门古老的学科,他被广泛认为是有史以来最伟大的斯多葛派哲学家之一。

在写这篇文章的前几天,我读了几页这本书,这很快让我的思绪回到那些迷人的 ML 生成的古代文本的摘录。

与计算机生成雄辩的文本段落看似复杂的本质相反,这实际上是一个相当简单的过程。

我们将从包含在冥想中的所有书籍的在线文本格式开始。本语料库由麻省理工学院主持【1】

宇宙是变化的:生活是观点。第四卷

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

卡洛斯·伊瓦涅斯在 Unsplash 上的照片

数据

首先,我们必须导入并对《沉思》的原文做一些小的改动,例如:

  • 页眉和页脚部分
  • 装饰文字(如分册“— — —”)
  • 书名(“第一册”、“第二册”等)
  • 《末日》

我们用requests.get导入,用split / replace函数和一些小的正则表达式清理数据,如下所示:

char2idx

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

字符>索引>向量

计算机处理数字,而不是语言。

为了将冥想翻译成计算机可以理解的东西,我们必须将我们的语料库分解成更小的输入实体。其然后可以被转换成索引(并且稍后被转换成独热编码或向量)。

这通常在两个粒度级别上完成。级嵌入,或级嵌入。

在这两种情况下,所有单独的实体(单词或字符)被用来创建一个词汇表——语料库中包含的所有语言实体的集合。冥想的字符级词汇表如下:

['\n', ' ', '!', '"', "'", '(', ')', ',', '.', ':', ';', '?', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', ']', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

由此我们可以将每个独特的字符转换成一个索引。我们用char2idx字典来做这件事,反之亦然,使用idx2char数组:

然后我们可以将人类的思考转换成机器的思考:

我们看到的一切都是视角,不是真相。

16 61 44 57 64 59 47 48 53 46 1 62 44 1 58 44 44 1 48 58 1 40 1 55 44 57 58 55 44 42 59 48 61 44 7 1 53 54 59 1 59 47 44 1 59 57 60 59 47 8

就我个人而言,我更喜欢阅读《人类的沉思》。幸运的是,机器到人类冥想训练后的翻译将由我们的idx2char阵列负责。

无论理性和政治(社会)能力发现什么既不聪明也不社会,它正确地判断不如自己。第七卷

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

达里奥·维罗内西在 Unsplash 上拍摄的照片

配料和切片

我们使用SEQ_LEN为每个训练示例分配序列长度。更长的SEQ_LEN似乎以短期语言结构为代价改善了长期语言结构。例如:

SEQ _ LEN = 100——“与许多人在一起,更加安静或更加自由,不会损害灵魂中的元素本身”

SEQ _ LEN = 300——“来自我的世界;但是,让这种规定成为一种政治,而不是生活,记住你自己,然而,他们关心穷人,祝福社会。”

我们可以通过增加训练历元的数量来避免这种情况。从而产生更好的短期和长期语言结构——然而,平衡这一点与过度拟合可能会变得困难。

张量流数据集

我们使用以下方法将索引数据转换成一个 Tensorflow 数据集对象[2]:

这允许我们在数据集上执行有用的内置操作,比如.batch().shuffle()

因为我们打算预测序列的下一个字符,所以我们的目标值应该是向前移动一个字符的输入。例如,如果我们的输入“Hello worl” ,我们的目标将是 “ello world”

为此,每个序列必须包含SEQ_LEN + 1字符。我们使用.batch()将数据集分割成这个长度的序列:

现在我们有了长度SEQ_LEN + 1的序列,我们把它们分成输入/输出对:

现在,我们必须重组数据集并创建训练批次。注意,我们在这里再次使用了 batch。之前,我们使用.batch()将我们的 241’199 字符长的索引语料库分割成许多长度为SEQ_LEN + 1的序列。这一次,我们使用它将我们的序列分成 64 个一组(BATCH_SIZE=**64**)。

你的习惯性想法是什么,你的思想性格也将是什么;因为灵魂被思想所染。第六卷

定义模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

该模型非常简单,由嵌入层、GRU 层和致密层组成。

tf.keras.layers.**Embedding**()层是一个可训练的数组,我们用它将单个索引字符值转换成密集的浮点向量。这个过程叫做嵌入[4]。每个字符索引映射到该层中的特定向量。

下面的tf.keras.layers.**GRU**()层包含我们的递归神经网络(RNN)。由于在计算中增加了“时间”维度,rnn 是 NLP 应用中的常见选择。这意味着我们不仅根据输入的内容进行预测,还根据这些内容的顺序进行预测。以下列陈述为例:

【原文】:我们看到的一切都是一种视角,而不是真相

【重新排序】:我们看到的一切都是真相,而不是一个视角

一个不考虑顺序的方法看不出这两个语句有什么不同。显然,顺序在语言中特别重要。请参阅 Andrej Kaparthy 的“递归神经网络的不合理有效性”文章,了解更多关于 RNNs 的信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

RNN、GRU 和 LSTM 单位的比较。在 GRU 和 LSTM,消失梯度问题是通过信息门(绿色突出显示)解决的。

GRULSTM 单元都是对原始 RNN 的改编,旨在通过使用信息门控[6][7]来解决消失梯度问题。两者共享相似的架构和性能(在大多数情况下)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GRU 对 LSTM 的单个历元的训练时间——这在 128 个历元上产生了显著的差异

对于这个模型,我注意到两者之间没有明显的质量差异。因为 GRUs 需要更少的训练时间,我继续这样做。

最后,我发现dropout=0.1对提高泛化能力产生了巨大的影响。这随机屏蔽了 10%的输入。导致复制文本的大段显著减少,同时仍然保持正确的语言结构和可理解的陈述。

最后的tf.keras.layers.**Dense**()层产生我们的预测。GRU 输出被传递到一个密集连接的神经网络,该网络生成对 66 个字符中的一个的预测。

不再谈论一个好男人应该是什么样的人,而是成为这样的人。第十本书

培养

使用adam优化器和sparse_categorical_crossentropy损失函数编译该模型。

在训练过程中,我们用以下方式保存模型重量:

checkpoint然后在model.fit()期间被传递给callbacks自变量。在每个训练时期结束时,模型权重保存在./training_checkpoint目录中。

装货

训练后,我们可以从文件中加载训练好的模型权重,并使用它们来重建我们的模型。关键的区别在于,我们使用批量大小1而不是训练期间使用的64来重建模型。我们这样做是为了传递一个输入(例如"From")来产生一个输出。

这一切都是通过以下方式完成的:

我常常想,为什么每个人爱自己胜过爱所有的人,但却不重视自己对自己的看法,而重视别人的看法。第十二卷

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

尼尔斯在 Unsplash 拍摄的照片

文本生成

一旦加载了模型,我们就可以轻松地开始生成文本了:

我们从一些非常奇怪的文本开始——它真的很像字母e。不过,普通标点的用法很快就学会了:

"From eeeeereeeeeseeceeeeeeeceeeeeeee,eeieeeeee. Leeeeeeeeeedeeepeeeeeeeeeeeeeeeereee;,eveeeeeeeeeeceeeeeeceeeeeeeepenesneee,eeeee."

该模型在很少的训练期后很快就能计算出单词:

"For the veppering doul to shod. Bubeeg if not it discoreor theselly alo hace."

再过几个时代,我们就会得到真正的单词——到处都有一些错误:

"Thou art dods thee from the deadgh of impuety by habour of mecrating, and oter coused by doing with gaves indifected, if thou hass serdect to him at a think. The way only not ando, nothing is compousted the that happoness; and de to be exturn and I he another suchivisicis inforaition with its Iw all vellected with does at all things, how sefull: and kill not the beact?"

最终模型会产生一些可理解的陈述,这看起来非常酷:

"Eudaemonia (happiness) is a good daemon, or a good thing. What then dost thou think of him who ave in harmony with what is really good.""Constantly contemplate the whole morals of those who live with us and present themselves in abundance, as far as is possible. Wherefore we must keep them before us."

进一步训练,我们倾向于复制大部分几乎冥想文本的副本:

"Remember that as it is a shame to be surprised if the figtree produces figs, so it is to be surprised, if a man has a fever"

结论

通过训练一个简单的关于冥想的 RNN 建筑,产生了一些令人惊讶的精彩的文本部分。它设法精确地组织句子,正确地产生真实的单词,并把它们合并成大部分实际上可读的东西。

虽然结果很酷,但进一步发展这一点需要的不仅仅是冥想。在 ML 中,数据为王。在这个项目中,独自坚持冥想是最大的限制因素。简而言之,我们需要更多的数据。

我的思路是,随着更多数据的纳入,我们将建立更大的词汇量。从那以后,我们将有更多的词供我们使用,所以词级嵌入似乎是合乎逻辑的下一步。使我们能够维护由单词提供但在字符级嵌入过程中丢失的语义。

目前,我对构建偶尔看起来很有见地的东西是多么容易印象深刻。我期待着在未来用更多的数据、词向量和其他工具进行更多的试验。

让我留给你一些我最喜欢的算法思考。

“你忍受这一点是理所应当的;但另一个问题是,人们为了获得快乐而工作,这本身就是一种瘟疫,但无论如何,每个人的善与他为之忙碌的事情的价值是一样的。”

“所有的事情都是一样的,在经历中是熟悉的,在时间上是短暂的,在物质上是没有价值的。现在的一切就像过去一样,时间是一个点,物质在流动,感知是应该的,然后不要让你的欲望找到它的终点。”

请记住,理性这个词的本意是表示分散,或者分解成原子,或者湮灭,它要么消失,要么改变。

这里的代码是这里你可以找到一个 100K 长的输出这里

感谢阅读!

参考

[1] M. Aurelius,《沉思录》(公元前 170-180),麻省理工学院网络经典档案

[2] 文本生成与 RNN ,Tensorflow 核心教程

[3] td.data.Dataset ,TensorFlow 核心文档

[4] 单词嵌入,Tensorflow 核心教程

[5] A. Karpathy,递归神经网络的不合理有效性 (2015),Andrej Karpathy 博客

[6] S. Hochreiter,J. Schmidhuber,长短期记忆 (1997),神经计算 9(8):1735–1780

[7] S. Hochreiter,递归神经网络学习和消失梯度 (1998),国际不确定性、模糊性和基于知识的系统杂志 6(2):107–116

[8] J. Chung,C. Gulcehre,K. Cho,Y. Bengio,门控递归神经网络对序列建模的实证评估 (2014),NIPS 2014 深度学习和表征学习研讨会

如果你喜欢这篇文章,你可能会喜欢冥想项目的下一篇文章——我在那里介绍了使用多个竞争的 rnn 来产生更高质量的文本,请在这里查看:

[## 集成学习的增压预测

利用竞争神经网络提高文本生成质量

towardsdatascience.com](/recurrent-ensemble-learning-caffdcd94092)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值