预测编程语言的未来流行程度
堆栈溢出数据用于此分析。数据集是从堆栈交换数据浏览器下载的。处理后的文件也可以在这里下载。它被大卫·罗宾逊用于一个数据营项目。
每个堆栈溢出问题都有一个标签,标记一个问题来描述它的主题或技术。该数据对每一对标签和年份都有一个观察值,显示了该标签在该年提出的问题数量以及该年提出的问题总数。例如,有 54 个问题是关于。在 2008 年的 58390 个问题中。
我们不使用一年中每个标记问题的数量,而是计算和使用该年中每个标记问题和所有问题的分数。现在进行比较更方便。
随着时间的推移,流行的编程语言发生了怎样的变化?
看看顶级编程语言的流行程度会很有趣。具体而言,包括以下编程语言:
- Java 语言(一种计算机语言,尤用于创建网站)
- Java Script 语言
- c#
- c++
- 大蟒
- 服务器端编程语言(Professional Hypertext Preprocessor 的缩写)
- 红宝石
- r
用于此比较的每个标记问题(在一年的所有问题中)所占的比例。
我们可以看出,一些语言的受欢迎程度在上升,而另一些则在下降。特别是 javaScript、Java、c#、c++、ruby 正在衰落,而 python 和 R(用于分析的语言)正在崛起。虽然这是事实,但我们应该检查问题总数是否在显著增长。
很明显,自 2013 年以来,问题总数没有显著增长。因此,我们可以说,编程语言的趋势可能是显著的,尤其是从 2013 年开始。
预测编程语言的未来流行程度
预测编程语言未来的流行程度会很有趣。我将使用预测包来生成预测。特别是,我结合了主要预测方法的力量,&ARIMA指数平滑法。特别是对于每个时间序列(每种编程语言),使用 ARIMA* &指数平滑法**创建 2 个独立的模型,并选择最佳模型进行预测。**选择 MAPE(平均绝对百分误差)**对预测模型进行评估。
— ARIMA(自回归积分移动平均)是一种非常流行的时间序列建模技术。它描述了数据点之间的相关性,并考虑了值的差异。
—指数平滑法包括简单指数平滑法(较大的权重分配给最近的观测值,而不是遥远过去的观测值)、双指数平滑法或霍尔特线性趋势模型(也考虑序列的趋势)和三指数平滑法或 Host 的温特斯法(也考虑时间序列的趋势和季节性)
正如你在上面看到的,应用指数平滑法时,R & C++的预测比 ARIMA 更好。对于其余的编程语言,ARIMA 似乎是最好的方法。
下面是一个表格,其中使用了性能最佳的模型,对未来进行了预测
下面是一个对未来预测的图表
摘要
为了比较编程语言的受欢迎程度,我们使用了过去 10 年中每种语言所涉及的全部问题的分数(关于堆栈溢出)。到目前为止,栈溢出是计算机编程中最受欢迎的问题和答案平台。
当然,还有很多其他的指标可以用来衡量受欢迎程度。此外,像所有模型一样,预测模型并不完美,可能会比预测的偏差更大。但是,考虑到所有时间序列的 MAPE 相对较小(不到 9 %),这些预测应该是编程语言未来受欢迎程度的良好迹象。
总的来说,结果如下:
—分析编程语言 (Python & R) 将继续流行
— Java 将稍有增长,然后保持持续的流行
— JavaScript,C# & C++ 将失去显著的流行
— PHP & Ruby 可能会失去几乎所有的流行,并在未来 5 年内过时
最初发表于【https://www.manosantoniou.com】。
使用深度学习对澳大利亚证券交易所(ASX)的股票市场进行预测:使用技术指标和长短期记忆(LSTM)模型
最近,我开始着手建立一个预测模型的任务,该模型预测第二天在澳大利亚证券交易所 (ASX)的股票价格的变动。我写这篇文章是为了分享我发现一个更可靠的策略的旅程,这个策略基于一个长期短期记忆 (LSTM)模型,这个模型建立在大约 2.5 年的 ASX*(T7)【EOD】金融市场数据的基础上。Jupyter 笔记本可以从我的资源库这里下载。*
1。数据导出
第一项任务是将 EOD 数据转换成五个独立的时间序列数据帧;o 笔,h 高,l 低,c 输和量 (OHLCV)各一个。在每个数据框中,行按日期索引,列按股票代码索引。超过 883 天的观察有 2773 个跑马灯。
接下来,创建了三个额外的数据框架:退货、第二天退货和高/低(这些是在给我的任务中要求的)。这些指标是除 OHLCV 值之外的潜在特征。
2.探索性数据分析
2.1 假设、动机、方法和策略
截至 2019 年 11 月 22 日,根据 ASX 的网站,目前共有 2195 个独特的报价机上市。然而,数据集有 2773 个独特的跑马灯;这意味着它有已被摘牌公司的股票代码。
在分析覆盖率和质量之前,应该讨论这个任务的假设、范围、动机和策略。
假设:
- 根据研究[1-3],从特定股票(或公司)的 OHLCV 得出的技术指标模式对其未来走势具有预测能力。
- 此外,对综合指数有贡献的公司的技术指标,如 ASX 通用指数、S&P/ASX 50 指数等。可以用来预测它们所属的综合指数的走势。
范围:这项工作将其范围限制在假设 1,并做了扩展。
动机:这项工作扩展了假设 1,使其更加通用:与[1–3]中的假设不同,任何股票价格的未来运动都可以通过技术指标的运动和模式来预测;而同样的从运动和形态的预测可以适用于任何公司的股价。换句话说,机器学习模型可以仅基于技术指标中的内在模式被训练成不可知的。
根据研究[1–4],数据的时间序列性质建议使用神经网络的 LSTM 范式,该范式已被证明优于集成方法,如随机森林和其他分类技术,如支持向量机。
策略:策略是利用过去 60 个(交易)日的 OHLCV 数据和技术指标,建立一个通用的预测模型,从而能够预测任何一家公司的股价走势。请注意,这不包括在 ASX 上市的所有综合指数(因为这属于假设 2)。
为此,将使用训练、验证和测试数据来训练 LSTM 模型,以预测以下指标:向上或向下第二天股票价格的运动。
2.2.覆盖面和质量
现在,让我们首先基于下面的直方图来可视化非缺失值的数量分布。
上面的直方图显示,在收盘价中大约有 196 个报价器没有缺失值。
所有缺失的值都来自当天没有登记的价格。经过与 ASX 官网数据的交叉核对,发现这主要是因为该交易并未在当天发生,公司在 2015-01-02 之后上市,或者公司在 2018-06-29 之前退市。
由于干净的结果是至关重要的,有很多缺失值的 tickers 将被忽略。在这种情况下,只考虑具有超过 800 个非缺失值的报价机。
其次,对于良好的可预测性,重要的是只考虑与标签具有良好相关性的公司,在这种情况下,这是未来的回报运动。此外,由于综合指数不在假设的范围内,它们被删除了——在与 ASX 的网站核对后,它们是没有交易量信息的报价机。
根据上面的直方图,可以观察到很少有与未来回报有相对较好相关性的报价机。为了获得良好的可预测性,只使用具有预测能力的报价机。因此,这里考虑平均相关值大于第 75 百分位的跑马灯;他们有 150 人。
现在,丢失的值被处理。在交易没有发生的当天,有几种方法可以处理缺失值:
- 将交易量设置为 0,将开盘、盘高、盘低和收盘值设置为前一天的收盘值,并假设当天该股票没有交易。这种方法可能会在体积中引入异常值,从而在数据中引入噪声。
- 使用前一个和后一个可用值对数据 OHLCV 数据进行插值,以实现平滑过渡。另一种方法是将缺失值填入列的平均值和中值。另一方面,这引入了错误的信息。
这里,采用第一种方法,因为它在理论上更正确。
2.3.附加转换
在进行一些可视化和分析之前,先检查一些技术指标。文献中有许多这样的转换[1–3]。Borovkova 等人[1]的工作整合了一些关键技术指标,可用于其他转换。通常,它们可以分为四类:(1)动量;(2)趋势;(3)体积;以及(4)易变性。一些常用的指标是:
- 资金流动指数
- 相对强度指数
- 随机振荡器(%K)
- 威廉%R
- 指数移动平均线
- 移动平均收敛-发散
- 商品渠道指数
- 市目指示器
- 积累/分配指数
- 布林线
所有的转换都是使用开源 Python 包完成的[5]。
2.4.数据分析
在执行一些数据分析之前,数据被分为训练集、验证集和测试集,如下所示:
- 火车:2015 年 2 月 1 日至 2017 年 6 月 30 日
- 验证:2017 年 7 月 1 日至 2017 年 12 月 31 日
- 测试时间:2018 年 1 月 1 日至 2018 年 6 月 29 日
首先,所有数据帧之间的相关性,或者换句话说,特征之间的相关性被可视化。因为在一个数据帧中有许多分笔成交点,所以很难可视化所有分笔成交点的相关矩阵。因此,在这里,取平均相关值,并使用热图可视化相关。
除了相关矩阵热图之外,还绘制了数据的直方图来寻找异常值。在此之前,每个跑马灯的数据都从 0 到 1 进行了规范化,以便可以对它们进行可视化和适当的基准测试。
从上述相关热图和直方图中观察到的情况可总结如下:
- 开盘价、最高价、最低价和收盘价彼此高度相关。这是意料之中的,因为这些值彼此非常接近。由于技术指标是使用这些值计算的,并且本质上保留了其信息,因此可以从特征列表中删除开盘价、盘高和盘低值。
- 除了 h/l 和体积之外,上面的大多数分布要么是正态的,要么是均匀的。这表明这两个特征中会有大量的异常值。虽然具有正态分布的其他特征在尾部可能有异常值,但是它们可以被认为是可以忽略的。此外,观察相关矩阵,它们似乎与未来回报的相关性较低,这是我们将要预测的指标。因此,将 h/l 和 volume 从特性列表中删除是合理的。
- 同样,根据关联矩阵热图,一些值似乎与未来回报没有太大关联。它们是资金流动指数和积累/分配指数。为了保持预测模型简单,这些特征也可以被认为是无用的。
- 最后,随机振荡指标似乎与 William %R 高度相关。这是意料之中的,因为两个指标的数学表达式是相似的。在这里,威廉%R 将从功能列表中删除。
基于上面的讨论,最终的特征列表将是:收盘,回报,指数移动平均线,相对强度指数,随机振荡器,移动平均线收敛-发散,商品通道指数,Ichimoku 指标,上下布林线。
如前所述,策略是预测股票的涨跌。根据经验,与预测未来回报的(正或负)百分比变化相比,这是一个更好的策略,因为基于标签的业绩指标可能会产生误导。例如,建立了一个模型,使得均方误差最小化,这仍然不意味着运动的方向是正确的。如果实际移动是 0.1%,那么基于 0.5%预测的投资比-0.1%预测更好,尽管前者具有相对更高的误差值。
注册标签的另一个数据帧是用 1 和 0 创建的:1 表示向上,0 表示向下;并且绘制出值的分布。
根据上述分析,下降趋势似乎多于上升趋势。因此,在发送用于机器学习的数据之前,需要进行一些平衡。
3.预测
3.1.长短期记忆(LSTM)模型
预处理 :基于上一节的分析,本节建立 LSTM 神经网络模型,用于次日股价时刻的预测;不管是向上还是向下。
训练集和验证集将在 LSTM 网络训练中使用,而测试集将用于交易策略实施和最终模型的附加测试。
接下来,对数据进行预处理。使用 MinMaxScaler 将数据归一化为 0 到 1 之间的值。注意,最大值和最小值是针对每个列车数据帧中的每个跑马灯的。
然后,对数据进行缩放,使其具有平均值 0 和单位方差。这种缩放是通过使用整个标准化训练数据帧的数据来训练标准缩放器来完成的。这将用于转换训练集、验证集和测试集。
接下来,数据被排序。过去 60 天的数据按顺序用于所有训练、验证和测试数据集的第二天预测。
一旦测序完成,数据就平衡了。这是为了确保 LSTM 模型不偏向于下降趋势,正如之前在数据分析中观察到的那样。
构建和训练 LSTM 模型 :使用 64 个批次大小和 40 个历元的 LSTM 模型被编译(使用 Tensorflow 中的 Keras)。该模型的摘要如下:
Layer (type) Output Shape Param #
=================================================================
lstm_3 (LSTM) (None, 60, 128) 72192
_________________________________________________________________
dropout_4 (Dropout) (None, 60, 128) 0
_________________________________________________________________
batch_normalization_3 (Batch (None, 60, 128) 512
_________________________________________________________________
lstm_4 (LSTM) (None, 60, 128) 131584
_________________________________________________________________
dropout_5 (Dropout) (None, 60, 128) 0
_________________________________________________________________
batch_normalization_4 (Batch (None, 60, 128) 512
_________________________________________________________________
lstm_5 (LSTM) (None, 128) 131584
_________________________________________________________________
dropout_6 (Dropout) (None, 128) 0
_________________________________________________________________
batch_normalization_5 (Batch (None, 128) 512
_________________________________________________________________
dense_2 (Dense) (None, 32) 4128
_________________________________________________________________
dropout_7 (Dropout) (None, 32) 0
_________________________________________________________________
dense_3 (Dense) (None, 2) 66
=================================================================
Total params: 341,090
Trainable params: 340,322
Non-trainable params: 768
_________________________________________________________________
本质上,LSTM 模型将具有 3 个 LSTM 层和激活的密集层,最后是具有 softmax 激活函数的密集输出层,因为这是一个分类问题。softmax 激活函数将输出分类的概率。
为了避免过度拟合,增加了漏失层。作为额外的措施,如果认为有必要,也可以添加正则化,使得在训练期间优化的权重不会变得太大。然而,在这种情况下,它们是不必要的。
称为 Adam 的自适应一阶基于梯度的优化用于优化模型。另一个著名的优化器是被称为 SGD 的随机梯度下降。由于这是一个分类问题,使用稀疏分类交叉熵和损失函数计算的准确度被用作性能度量。
上面指定的所有指标都是该模型的超参数。可以使用批次大小、时期、单位值和优化方法的网格进行超参数搜索,但是由于硬件限制,仅使用这些初始超参数。
分析模型性能 :优化后的损失函数历史如下图所示。从该图中,我们可以看到来自训练和验证数据的损失函数被最小化,并且它们彼此非常接近。这表明模型没有过度拟合或拟合不足。然而,可以做出的一个改进是调整学习速率,使得跳跃更小。
下面的准确度图还显示了基于训练集和验证集的 LSTM 模型的改进。
还生成了基于测试数据集的精度,以及基于模型在训练期间从未见过的 2018 年数据的分类报告,如下所示。
Test loss: 0.6752472768227259
Test accuracy: 0.5605208333333334
Classification report:
precision recall f1-score support
0.0 0.72 0.50 0.59 6038
1.0 0.44 0.66 0.53 3562
avg / total 0.61 0.56 0.57 9600
基于测试集的准确度分数显示,结果与研究[4]一致,其中测试集的准确度低于训练和验证集的准确度。与下降趋势相比,上升趋势的预测精度较低,这意味着在预测上升趋势时会有更多的假阳性。通常,召回分数与精确度成反比。因此,最好的衡量标准是 f1 分数,这对于制定交易策略来说是可以接受的。
交易策略 :这里定义了一个简单的交易策略。在使用的所有 150 个报价机中,基于 LSTM 网络的预测运动,使用每个报价机 1 澳元建立头寸,并在第二天平仓。这意味着每天投资 150 澳元,第二天平仓。
请注意,由于 LSTM 网络需要过去 60 天的数据,因此交易是从 2018 年 3 月 27 日模拟的。将绘制累计损益 (PnL)图。
按照简单的策略,基于 64 天的交易和每天 150 澳元的投资,总利润约为 25 澳元。平均而言,这是 0.26%的每日投资回报率(ROI)。下图显示了基于 64 天回溯测试数据的 ROI 值分布。基于直方图,80%的信心,LSTM 模型将提供一个积极的每日投资回报率。
考虑到累积 PnL 的置信区间和线性趋势,这可以认为是一个 成功的策略 。
结论
澳大利亚证券交易所 (ASX)的所有公司的历史数据被给出,用于预测证券第二天的运动,并随后通过仅使用 2773 只股票的 883 天的当天结束信息来提出交易策略。
首先对数据进行提取、分析、清理和特征设计。随后,为具有良好可预测性的证券建立了一个长短期记忆 (LSTM)网络模型。
结果表明,LSTM 模型为 150 家澳大利亚公司股票价格的成功交易策略提供了合理的准确度,具有良好的预测性。此外,结果显示,在 80%的置信度下,基于测试数据,LSTM 模型提供了正的每日投资回报。
未来的改进
基于这种尝试,可以进行一些改进来进一步提高预测或交易性能。它们是:
- 更精细的分类。货币运动的标签可以分为三类。例如,在当前版本中,未来回报率为 0.00 的股票被归类为 0,这是一种向下的变动。也许它们可以被分为-1,0 和 1,并根据这些类别建立交易策略。
- 尝试解决假设 2 。第二个假设是综合指数依赖于它的成分证券。因此,这些证券可以用来预测综合指数的走势。
- 使用 LSTM 模型的概率。来自 LSTM 模型的 softmax 激活函数实际上输出了类别的概率。需要进一步调查以将可能性纳入交易策略。
- 使用卷积神经网络。研究[6–7]和[4]分别表明,使用 CNN 和 CNN-LSTM 混合方法可以提高预测精度。这可能是一个有趣的改进。
- 超参数搜索。随着计算能力的提高,可以部署超参数搜索来找到 LSTM 和模型的最佳参数。
- 新闻数据。其他类型的数据,如与证券相关的新闻,可以作为特征之一添加,如研究所示[2,8]。例如,[2]表明添加新闻信息(例如,情感)可以将预测准确度提高 10% (58%到70%)。
参考
[1] Borovkova S,Tsiamas I .一个用于高频股票市场分类的 LSTM 神经网络集成。预测杂志。2019;1–20.https://doi.org/10.1002/for.2585
[2]翟 Y,许 A,哈尔格木格 SK .在每日股价趋势预测中结合新闻和技术指标。计算机科学讲义。2007;https://link . springer . com/chapter/10.1007/978-3-540-72395-0 _ 132
[3]赫加齐 O,索利曼 OS,萨拉姆 MA。股票市场预测的机器学习模型。国际计算机科学与电信杂志。2013;17–23.https://www.ijcst.org/Volume4/Issue12/p4_4_12.pdf
[4]巴尔加斯先生、多斯安茹斯·CEM、比沙拉·GLG、埃夫苏科夫股份公司。使用技术指标和金融新闻文章进行股市预测的深度学习。2018;https://doi.org/10.1109/IJCNN.2018.8489208
[5]帕迪亚尔·DL。Python 中的技术分析库。2019;https://github.com/bukosabino/ta
[6]塞尔温 S,维纳雅库马尔 R,戈帕拉克里什南 E.A,梅农 VK,索曼 K.P .利用 LSTM,RNN 和 CNN 的股票价格预测-滑动窗口模型。2017 年国际计算、通信和信息学进展会议(ICACCI)。2017;https://doi.org/10.1109/ICACCI.2017.8126078
[7]陈,何.利用卷积神经网络进行股票预测.IOP 会议系列:材料科学与工程。2018;https://doi.org/10.1088/1757-899X/435/1/012026
[8]翁 B,陆 L,王 X,Megahed FM,Martinez W .使用集合方法和在线数据源预测短期股票价格。专家系统及其应用。2018;https://doi.org/10.1016/j.eswa.2018.06.016
使用随机森林预测亚马逊雨林的野火数量
之前,我们分析了巴西野火数据集。我们查看了数据集的特征,例如每个州野火的平均数量、每个州野火数量的标准偏差以及所有州野火数量的分布。我们还观察了每个州在特定月份的野火数量与全年的对比。
在这篇文章中,我们将建立一个机器学习模型,我们将使用它来预测任何给定年份一个州的野火数量。
构建我们的机器学习模型的工作流程如下:
- 数据准备和清理
- 功能选择和工程
- 型号选择
- 模型调整和测试
幸运的是,巴西数据集是结构化的,经过清理和标记的,因此我们基本上完成了第一步(在许多情况下,您将不得不处理非结构化和未标记的数据,这印证了一句谚语“数据科学家花费 80%的时间来寻找、清理和结构化数据”)。
现在让我们建立这个模型!
我们需要做的第一件事是导入必要的 python 包:
import numpy as np
import pandas as pd
from sklearn.metrics import mean_absolute_error
from sklearn.ensemble import RandomForestRegressor
接下来我们可以写一个函数来初始化我们的数据。您可以自由选择如何预处理数据。对于这个例子,我们将保持简单,说我们根据感兴趣的特定状态初始化数据。我们还设计了一个月类别功能,我们将在我们的模型中包括:
def initialize_data(state):
df = pd.read_csv("amazon.csv", encoding = "ISO-8859-1")
df['month_cat'] = df['month'].astype('category')
df['month_cat'] = df['month_cat'].cat.codes
df = df[df['state'] == state]
return df
接下来,我们定义一个函数,该函数允许我们分割数据用于训练和测试:
def train_test_split(year, df):
df_train = df[df['year'] < year]
df_test = df[df['year'] == year]
X_train = np.array(df_train[['year', 'month_cat']])
y_train = np.array(df_train['number'])
X_test = np.array(df_test[['year', 'month_cat']])
y_test = np.array(df_test['number'])
return X_train, X_test, y_train, y_test
函数“train_test_split”使用“year”来拆分模型训练和测试的数据。例如,如果“year”= 2015,则训练集被定义为 2015 年之前的所有 wildfire 数据,测试集被定义为 2015 年期间的所有 wildfire 数据。接下来,我们定义特征和目标变量,其中特征是年份和月份类别,输出是野火的数量。
我们现在定义一个函数,它指定随机森林算法的模型参数。该函数可用于在测试过程中优化模型参数,从而将误差降至最低。我们通过改变 N_ESTIMATORS 和 MAX_DEPTH 值来做到这一点,直到我们最小化误差度量。这个过程称为超参数调整:
def model_tuning(N_ESTIMATORS, MAX_DEPTH):
model = RandomForestRegressor(n_estimators = N_ESTIMATORS, max_depth = MAX_DEPTH, random_state = 42)
return model
我们接下来要做的是定义一个函数,使模型符合训练数据,并预测野火的数量:
def predict_fire(model, X_train, X_test, y_train, y_test):
model.fit(X_train, y_train)
y_pred = model.predict(X_test).astype(int)
mae = mean_absolute_error(y_pred, y_test)
print("Mean Absolute Error: ", mae)
df_results = pd.DataFrame({'Predicted': y_pred, 'Actual': y_test})
print(df_results.head())
最后,我们定义一个“主”函数,用不同的输入值来测试模型。下面,我们对“初始化数据”、“模型调整”和“预测火灾”函数进行了两次调用。我们对 2017 年的“Sergipe”和“Distrito Federal”州进行预测,并计算平均绝对误差(MAE):
def main():
df = initialize_data('Sergipe')
X_train, X_test, y_train, y_test = train_test_split(2017, df)
model = model_tuning(50, 50)
predict_fire(model, X_train, X_test, y_train, y_test)
df = initialize_data('Distrito Federal')
X_train, X_test, y_train, y_test = train_test_split(2017, df)
model = model_tuning(50, 50)
predict_fire(model, X_train, X_test, y_train, y_test)if __name__ == "__main__":
main()
输出是:
我们还可以分析模型在所有状态下的性能,如下所示:
def main():
df = pd.read_csv("amazon.csv", encoding = "ISO-8859-1")
for i in list(set(df['state'].values)):
df = initialize_data(i)
X_train, X_test, y_train, y_test = train_test_split(2017, df)
model = model_tuning(50, 50)
predict_fire(model, X_train, X_test, y_train, y_test)
print(i)if __name__ == "__main__":
main()
这将输出每个状态的预测值、实际值、状态名称和 MAE 值。可以通过超参数调整、尝试其他基于树的方法(XGBoost、lightgbm、catboost)和尝试神经网络时间序列模型( LSTM 、 RNN 、 CNN 、 WaveNet CNN )来改进模型。我鼓励你尝试一下这个模型,看看随机森林的 MAE 有多低。然后尝试应用我建议的一些其他方法,看看你是否在准确性上有所提高。所有的代码都可以在 GitHub 上找到。祝好运,机器学习快乐!
用数据预测奥斯卡奖
只有女强人的电影表现更差,获得奥斯卡最佳影片四项提名的可能性更大。
我和我的搭档都是奥斯卡的超级粉丝,我们也喜欢涉足数据可视化——去年我们在使用慈善数据的比赛中获得了三等奖。所以今晚的奥斯卡颁奖典礼,是时候把我们的注意力转向电影界的奥林匹克了。
就像其他人一样,我们想回答的问题是哪部最佳影片提名最有可能获奖,以及是否有某种预测它的公式。
神奇的四项提名
我们查看了过去 90 年的最佳影片获奖者,并分析了他们在那一年获得的其他奥斯卡奖项的提名数量(提名,而不是必要的奖项)。我们仔细分析了这些数字,得出了如下数据。
93%的最佳影片得主还获得了最佳导演提名
在我们的数据中,11 个奥斯卡图像的行用金色填充不同的百分比,即。这些显示了最佳影片获奖最多的提名类别的顺序。例如,93%的最佳影片获奖者也获得了最佳导演提名,而只有 14%的最佳影片获奖者获得了最佳视觉效果提名——这就解释了为什么我们没有看到许多夏季大片获奖。
左边圆点多的人更有可能获胜
下半部分的点,将今年的八部最佳影片与上面的奥斯卡奖项相对照。数据告诉我们,左边圆点多的人赢的可能性大得多。那些集导演、编剧、表演和剪辑于一身的人最有机会。
没有一部电影在没有这四项提名中的至少一项的情况下获奖
BlackKklansman 有五个点在一排,但最受欢迎的和副也有’神奇的四’。《罗马》只有四部中的三部(这是一部不需要大量剪辑的电影)。没有一部电影在没有这四项提名中的至少一项的情况下获奖——这对黑豹来说是个坏消息。
只有女演员提名的电影明显不太可能获奖
虽然获得表演提名是“四大奇迹”(包括男演员或女演员、配角或主角)之一,但当性别发挥作用时,情况就不同了。
只有 8%的电影获得了最佳女演员提名
48%的电影获得最佳影片提名,包括男演员和女演员两个类别,这反映了强大的全面演员阵容。但只有 8%的电影获得了最佳影片,只有女演员提名(相比之下,只有男演员提名的电影有 32%)。令人惊讶的是,没有男演员或女演员提名的最佳影片获奖者(12%)比只有女演员提名的更多。这告诉我们关于社会的什么,我将留给你来决定。
今晚,无论是《罗马的墨西哥女仆》还是《最受欢迎的英国女王》,都只有女演员提名,没有男演员提名。他们有机会成为继 1997 年的《泰坦尼克号》和 1965 年的《音乐之声》之后,第八部获得最佳女演员提名的电影。
我们如何创建我们的数据,即
我们从 datahub 和 Kaggle 下载了数据。然后,我们使用 React 对这些数据进行编码,以快速找到以前获奖图片的提名。有了这个,我们就可以计算出百分比,通过将其他最佳影片提名的数量除以该奖项类别一直有效的年份来相应地对它们进行加权。然后,我们使用矢量图形编辑器 Sketch 来设计数据,即
最佳影片获奖的可能性也可以通过许多其他方式来“预测”,例如在奥斯卡奖之前评论界的好评和颁奖典礼上的成功。但我们承认,我们也喜欢在晚上打开信封时受到巨大的冲击。
奥利弗·卡林顿
预测深度学习模型的性能
幂律标度解释了模型的性能如何随着我们输入更多的数据而改变
众所周知,深度学习最近的成功在很大程度上依赖于大量数据的可用性。视觉是第一个实现数字图书馆承诺的领域,这可能是因为大型数据集的可用性,如 ImageNet 。最近 RL 的模拟器的激增进一步说明,随着我们进一步将这些技术应用于现实世界的问题,数据稀缺很快成为瓶颈。
但是多少数据才够呢?
在商业环境中,这个问题经常出现。当时间和金钱岌岌可危时,能够对模型架构的改进如何与简单地收集更多数据相权衡做出一些具体的陈述将是有用的。我们应该付钱给一个工程师团队 6 个月来完善我们的模型,还是应该付钱给一个众包助手团队 6 个月来整理我们需要的数据?
我们无法轻松回答这个问题的事实反映了深度学习作为一个领域的不成熟,这一缺点导致阿里·拉希米在他的 2018 年 NIPS talk 中宣布‘机器学习已经成为炼金术’(他至少在某种意义上是错的;炼金术从未让任何人赚到钱,而深度学习却让一些人变得非常富有。Yann LeCunn 广为宣传的《脸书邮报》的回应发出了挑战:“如果你不满意我们对你日常使用的方法的理解,那就改正它”。
Ali Rahimi putting the cat amongst the pigeons by suggesting that deep learning is ‘alchemy’
来自百度的一篇名为“深度学习规模是可预测的,从经验上来看”的论文在一定程度上回答了这一挑战。如题所示,他们对这个问题的答案是经验的,而不是理论的。这篇论文附有一篇精彩的博文,我想让你参考这篇博文,以获得关于这些发现的更详细的讨论,我将在这里总结一下。
在我们深入研究之前,有一个小小的题外话:对标度律的研究已经让生物学家着迷了很长时间。这张图来自 Max Kleiber 于 1947 年绘制的图,显示了动物的新陈代谢率(每天产生的热量)与该动物的体重成对数比例关系(更多细节见下文)。
事实上,它似乎可以扩展为
这就是为什么红线比标有表面的线更陡的原因
但是比标有重量的要浅。有趣的是,没有人真正知道为什么这个定律成立,尽管它看起来非常强大。
回到百度和人工智能的世界,70 年后我们正在制作类似的情节:
从本质上来说,论文记录了数据的增加导致测试集损失的减少,具有相同的幂律关系,当在双对数标度上绘制时,最终为一条直线。有趣的是,这种关系的指数——线性标度上直线的斜率——对于你手头的任何一个架构来说都差不多。因此数据集本身定义了这个指数:模型仅仅改变了截距。为了强调这一点:在给定数据集的情况下,添加更多数据的效果对于任何模型本质上都是一样的。这太不寻常了。
他们没有为这篇论文提供任何代码,所以我在 PyTorch 中拼凑了一些实验来探索他们的结论。
代码
你可以在这里下载完整的 Jupyter 笔记本或者继续阅读一些要点。
我在 PyTorch 教程中提供的代码基础上构建了一个简单的 CNN 来测试 CIFAR 数据集(一个包含 10 个类的小型图像分类任务)。我用超参数字典配置它,因为最佳超参数对数据集大小非常敏感——正如我们将看到的,这对复制百度结果非常重要。
我将训练数据分为训练集和验证集,并按照论文中的建议对训练集进行子采样。
然后,我训练了 9 个模型,每个数据集大小一个,停止条件是通过连续 3 个时期增加验证误差来定义的(原始论文在验证的细节上有点模糊)。然后,我根据测试集对它们进行了评估。
如您所料,测试集的准确性随着训练集大小的增加而增加。此外,它看起来有点像权力法则。
损耗以类似的方式减少。
然而,无论是准确度还是损失的对数图看起来都不如百度论文中的那张可爱。实际上,它们各自都表现出某种模糊的对数形式,暗示着我们之间存在着次幂律关系。
原因很明显:我没有像他们那样在每个训练集上进行详尽的超参数搜索。因此,我们没有找到每个数据集大小的最佳模型。最有可能的是,我们的模型缺乏完全捕捉更大数据集的能力,因此我们没有充分利用数据。
添加超参数调谐
你会记得,在模型定义中,我们使用一个超参数字典来设置层的大小,这样就可以很容易地通过超参数调整来改变网络的形状。因此,对我们来说,实现一些随机搜索相对简单:
我们现在可以针对每个数据集大小重复训练循环,随机采样参数:
并使用它为每个数据集大小训练一组网络,保留在验证集上表现最好的网络。我是在没有 GPU 的 MacBook 上执行这一调优的,所以我限制自己对每个数据集大小进行 10 次搜索,希望我可以证明这一点,而无需请求 AWS 实例。
然后,我们可以再次寻找我们的幂律,果然,它们看起来更整洁了:
没有克莱伯的好,但也不错。
结论
原始论文在各种任务中测试了各种模型——这里执行的最接近的一个是带有 ResNets 的 ImageNet。令人高兴的是,这些结果很容易在不同的网络、不同的数据集上复制。
在他们的讨论中,作者指出:
我们还没有找到影响幂律指数的因素。随着数据集规模的增加,为了打破幂定律,模型需要用越来越少的数据学习更多的概念。
这正是你在人类身上看到的那种伸缩;你知道的越多,就越容易获得新知识。
我之前写过关于量化超智能进程的困难。似乎超越幂律指数的模型的出现——随着它们的学习,使**的数据效率更高——**可能是这条道路上一个重要的经验主义里程碑。
原载于 2019 年 4 月 14 日deberker.com。
预测 Instagram 帖子的受欢迎程度
使用混合输入神经网络实现对 Instagram 受欢迎程度的巨大预测。
在本文中,我们将讨论我们试图预测 Instagram 帖子受欢迎程度的方法和结果。首先,我们将描述我们的数据收集方法以及数据本身。然后,我们将描述我们用于图像和自然语言处理的技术。在这一步之后,我们使用一个 XGBoost 回归模型来获得一个基准均方根误差分数,我们将努力提高这个分数。最后一步,将使用混合输入神经网络,接受分类/数字数据和图像数据。
本文讨论的主题的所有代码都可以在这里找到:https://github.com/GuiZamorano/Instagram_Like_Predictor
动机
在现代,趋势和流行很大程度上是由社交媒体驱动的。如今 Instagram 上有超过 10 亿用户。这是一个大规模的市场,有潜力进行优化,以增加知名度,收视率,甚至收入。我们希望通过创建一个项目来利用这个市场,该项目可以确定关键变量,以增加一个帖子的点赞数与用户在一个帖子上获得的平均点赞数的比率。使用这些功能,我们希望能够对这一比率进行估计,以便优化帖子,为高知名度影响者和日常用户收集最多的曝光率。
收集数据
收集 Instagram 用户名:
为了预测 Instagram 帖子的受欢迎程度,我们首先需要大量数据来训练我们的模型。我们的第一项工作是收集 Instagram 用户名,我们可以使用这些用户名来收集帖子数据。幸运的是,我们找到了一个网站,上面列出了 Instagram 影响者的前 1000 名(不一定是拥有最多粉丝的人)。网站可以在这里找到:https://hypeauditor.com/en/top-instagram/.
使用 urllib 和 BeautifulSoup Python 包,我们浏览了该网站的页面,收集了 1000 个 Instagram 用户名。然而,我们仍然需要更多的数据,所以通过查看涉及 Instagram 用户的其他项目,我们能够将我们的列表增加到总共 1897 个用户名。所有这些用户都有各种各样的人气和追随者。
刮 Instagram 帖子:
现在我们已经有了一个很长的用户名列表,我们的下一个挑战是从他们的帖子中收集数据。我们的第一个想法是使用脸书的 Instagram Graph API。通过向这个 API 发出请求,您可以从一个概要文件和一篇文章中收集大部分信息。不幸的是,Instagram 的 Graph API 限制一年比一年严格。目前的限制是每小时 200 个请求。这种限制使得利用 Instagram Graph API 变得非常困难和乏味。因此,通过研究,我们创造了自己的铲运机,其工作原理如下:
- 向https://www.instagram.com/+{用户名}发出 URL 请求。
- 通过将响应转换成 JSON 对象,从响应中提取 Javascript 元数据。
- 使用 urllib 下载用户的个人资料图像和每个帖子图像。
使用这个直接调用用户 Instagram 页面的 scraper,可以为您提供每个用户的 12 个最新帖子。我们试图使用 Selenium 来加载整个页面,但是这样做只是将可视信息附加到页面的 HTML 中,而不是我们需要的元数据。因此,我们决定坚持每个用户(最多)发 12 篇帖子,并从我们的数据集中删除了最近的帖子,因为我们认为这可能是一个不准确的流行度显示,因为它是最近的。现在我们有了 1897 个 JSON 对象和一个包含所有图片的文件夹,我们准备构建一个数据集。
Figure 1: JSON of user profile data
Figure 2: Last key-value pair of JSON is array of posts
数据探索与可视化
在搜集现成可用的特性后,我们的第一个目标是看看我们是否能找到它们之间的任何关系。这包括寻找预期或假设以及意外的关系。除了原始刮刀数据之外,这种探索还包括我们自己生成的一些基本特征,稍后将更详细地讨论。我们首先探索了每个功能与我们最终试图预测的功能的相关性:帖子的点赞数除以帖子帐户的平均点赞数(number_of_likes_over_mean)。我们专注于与 number_of_likes_over_mean 最相关(或反向相关)的特征,以便进一步研究。下面描述了这些特征之间的相互关系。
Figure 3: Top features correlated with number_of_likes_over_mean
出于可解释的原因,一些特性与其他特性有相当大的相关性,例如 hr_of_day 或 hour buckets(例如(16,20),这意味着下午 4 点到 8 点)和 hr_sin,因为它们都处理小时间隔。下面列出了最重要的相关性,尽管相关性非常小。
Figure 4: Some of the most significant feature correlations
我们发现的一些关系是,在较晚清醒时间的帖子比深夜或清晨的帖子做得好一点。如图 5 所示,周中(周二、周三、周四)的帖子比一般的帖子稍差,我们发现视频帖子和带有禁用评论的帖子也是如此。
Figure 5: Each day, one-hot-encoded vs. number_of_likes_over_mean
我们还将我们的点赞数除以用户的平均点赞数可视化为分布图和散点图。散点图具有大约 1.6 的偏斜度和大约 6 的峰度。它有一个比正态曲线更大的倾向于分布右侧的尾部。
Figure 6: Distribution of likes divided by mean
Figure 6: Scatter plot of likes divided by mean
特征生成
在熟悉了我们的数据集之后,我们决定生成一些我们认为在预测给定帖子的表现时有用的特征。这些特征包括从帖子图像本身提取的特征,以更有用的方式描述原始文本数据(如标题)的 NLP 特征,以及可能有助于帖子成功的更一般的特征,如一天中的时间和一周中的日期。生成这些特征后,我们希望在开始训练最终模型时利用它们,并通过比较具有和不具有这些特征的基本回归模型的性能来确定它们的重要性。
一般特征:
从 Instagram 抓取数据后,我们有了大量的元数据,包括帐户关注者和关注,企业/类别信息,以及时间和日期信息。虽然有些元数据与账户相关,而不仅仅是帖子,但我们认为包含它将有助于为帖子提供上下文信息,并帮助我们获得更多特定于帖子本身的功能。
因此,除了从 Instagram 收集数据,我们还执行了一些基本的特征工程,以在进行更复杂的特征生成之前扩充数据集。我们认为用下面的一些内容来补充搜集到的数据可能是有用的。衡量一个账户的“活跃程度”可能代表一篇帖子的受欢迎程度,因此我们计算了两次帖子之间的时间,并将其作为一个特征添加到数据集。此外,我们计算了时间正弦和余弦特征,以编码时间的循环性质(即 11:55pm 应该接近 12:05am,但 23 小时离 00 小时非常远)。我们还将帖子分成时间段,例如从午夜到凌晨 4 点,凌晨 4 点到 8 点,等等,因为我们认为特定的每日时间段(不仅仅是时间)将有助于帖子的受欢迎程度。最后,因为在不了解用户的情况下很难衡量一篇帖子的点赞数,所以我们计算了相关账户的平均评论数和平均点赞数,为预测一篇帖子的相对受欢迎程度做准备。接下来,我们来看看更复杂的特征,比如图像和文本中的特征。
图像特征:
我们有很多关于图像以及如何对待它们的想法。我们最初的想法是,有人类主题的帖子比没有人类主题的帖子表现得更好。此外,我们假设有许多人在其中的图像,如团体照片,不会像只有一个清晰主题的图像那样获得很多喜欢。我们还想测试图片中的微笑是否会影响帖子的赞数。因此,我们决定创建一个模型来确定给定图像中的脸的数量和微笑的数量。该模型将应用于我们的数据集以生成这些特征。
经过一些初步的研究,我们决定利用 OpenCV 现有的面部识别分类器来完成这项任务。使用我们下载的图像,我们能够从 OpenCV 的文档中找到的 XML 文件中加载预先存在的面部和微笑检测器,这些文件是我们用来生成的。包含要添加到现有数据集中的新生成要素的 csv 文件。
自然语言处理功能:
数据集中有许多利用文本的不同要素,包括传记、标签、位置和标题。出于我们项目的目的,我们选择关注标题,因为我们正在分析独立的帖子,并希望尽可能多地使用关于帖子的信息,而不是海报。
NLP 的第一步是清理数据集。我们专注于单词本身,因此必须删除数字、标点符号、表情符号和空值。因为我们的数据集包括来自世界各地的热门 Instagram 用户,我们面临着处理的挑战,因为有太多不同的语言。我们决定使用谷歌翻译功能调用,以便将所有的文本翻译成英语,因为为了处理这似乎是最好的。将字幕翻译成英语后,我们删除了停用词,以消除诸如“the”或“is”之类的词,从而给其他词更多的权重。
在我们清理数据集之后,第一次分析是在文本情感上进行的。使用 TextBlob API,我们传递每个标题并接收一个情感分数。高达+1 的正分数表示正面单词,高达-1 的负分数表示负面单词。除了这个数字特征,我们把原始语言变成了一个分类变量,以观察不同的语言在喜欢率上是否有不同的波动。
我们尝试的另一种 NLP 方法利用了词袋。在这种方法中,我们创建了一个给定标题中所有单词的计数向量,并在所有标题中找到了 100 个最常用的单词。这些单词然后被转换成二元特征,1 表示它在字幕中,0 表示它不在字幕中。这种方法在很大程度上依赖于标题完全是英文的,因为拥有多种语言会产生不同的热门词,这些词在所有标题中并不常见。
现在我们已经生成了所有的特性,我们准备开始制作一个初始模型。
回归分析
我们建立模型的第一步是尝试各种回归模型,包括喜欢和评论的数量。显然,这些信息是我们试图预测的,但看看回归模型对这些数据的处理效果会给我们一个基准分数。我们最好的模型是 XGBoost 和梯度推进,所以我们决定坚持使用这些回归模型。他们获得了大约 0.032–0.034 的测试均方误差,即大约 0.18 的均方根误差。
Figure 7: Mean squared error scores for models already including the information we are attempting to predict
这给了我们一个目标,那就是获得比 0.18 均方根测试误差更好的分数。
现在,我们删除了图片发布前不可用的功能,如赞数和评论数,以继续测试我们的实际预测模型。均方误差急剧上升到大约 0.26–0.27,这是大约 0.52 的均方根误差。
Figure 8: Mean squared error scores for true model
我们的下一步是看看哪些生成的特性在 XGBoost 上工作得最好。我们决定在模型上尝试的生成特征是脸的数量、微笑的数量和自然语言特征。XGBoost 在添加了面数特征的原始特征下表现最佳。均方根误差为 0.51。
通过这种回归分析,我们能够确定使用具有多个面的原始特征通过 XGBoost 和梯度增强产生最佳预测。然而,即使在校准了我们的 XGBoost 回归器之后,这些新特性还是略微改进了模型。因此,我们的最后一步是用神经网络测试新功能。
Figure 9: Mean squared error scores after adding image and natural language features.
神经网络
因为 XGBoost 的表现远不如我们的目标 RMSE 分数 0.18 左右,所以我们决定尝试使用神经网络来解决我们的问题。这将允许我们直接使用我们最初下载的个人资料和帖子图片,并确定它们是否能在帖子的受欢迎程度中发挥作用。有趣的是,我们发现大多数神经网络都是用于分类问题,而不是回归。尽管如此,我们决定继续使用神经网络进行回归,即预测连续值。
我们的第一步是在神经网络中只使用分类数据和数值数据,看看它与 XGBoost 结果相比如何。接下来,我们在图像上使用卷积神经网络,包括侧面图像和背面图像。最后,我们将两者结合成一个双分支神经网络。所有的训练都是使用支持免费 GPU 的 Google Colab 完成的。
1。多层感知器(MLP):
多层感知器是一种深度的人工神经网络,由输入层、输出层和至少一个执行计算的隐藏层组成。与线性回归相比,隐藏层和激活函数为我们提供了一个更强大的模型。我们做的第一件事是使用 scikit-learn 的 MinMaxScaler 将我们的特征缩放到范围[0,1]。我们还将产出目标调整为[0,1],以缩小我们的产出预测范围。这大大改善了神经网络的结果。这是因为神经网络通过添加乘以学习速率的梯度向量来学习,并且如果特征的分布范围都不同,则该学习速率可能过度补偿(或补偿不足)其校正。我们使用的简单 MLP 架构如下所示,并为最终的密集层使用了线性激活函数。
Figure 10: MLP architecture
结果:这种 MLP 架构比以前的任何方法都要好得多!RMSE 比 XGBoost 低得多,我们能够达到并远远超过我们的基准分数 0.18。使用 Adam 优化器训练 30 个时期后的结果如下所述。
平均绝对百分比差异:55.40%
均方根误差:0.0807
Figure 11: Line of best fit by MLP model
2.卷积神经网络(CNN):
处理图像:
现在使用 CNN 让我们有能力把所有这些千兆字节的下载图像好好利用起来。然而,这确实带来了一些问题。
图像大小:下载的图像在大小上没有标准化,大多数对于理想的计算时间来说太大了。通过分析我们的图像形状,似乎大多数都在 960 像素 x 1200px 像素左右。理想情况下,我们会调整图像的大小以保持它们的纵横比,但这样它们的大小就会不同。我们的解决方案是将图像尺寸调整为 100 像素 x 128px 像素。这似乎比正方形图像更好地保持了图像特征,因为大多数图像都包含人脸或身体。此外,它不需要 CNN 学习不必要的信息,就像填充的情况一样。
两幅图像:我们处理的下一个问题是决定如何在 CNN 中处理我们的图像。每个数据条目由两张图片组成,一张个人资料图片和一张帖子图片。我们考虑了处理这个问题的两种选择。
- 使用两个 CNN,一个用于帖子图片,一个用于个人资料图片,并使用帖子的受欢迎程度作为每个图片的标签
- 创建一个并排的个人资料图像和文章图像的新图像。
第一个选择似乎是个糟糕的选择。首先,我们将有一个帖子图像和一个个人资料图像,它们共享同一个标签。第二,我们将有一个不同的标签为每一个单一的个人资料图片,因为受欢迎程度只有不同的职位。因此,这种选择可能会让 CNN 更难通过图片了解受欢迎程度。
出于许多原因,选项二似乎是理想的。人气的一大指标是发帖的人。想象一下在一家高级餐厅里的一盘食物的完全相同的图像。一个是我贴的,一个是金·卡戴珊贴的。你觉得哪个会得到更多的喜欢?因此,并排组合个人资料图像和帖子图像可以是帖子受欢迎程度的重要指标。此外,这允许 CNN 同时从个人资料和发布图像中学习特征。
Figure 12: Final image example input into CNN
CNN 架构:
构建 CNN 架构来自经验和数小时的修改。考虑到您试图解决的问题,没有黑盒方法可以为您的数据获得最佳架构。因此,我们花了很长时间测试不同的架构,包括不同数量的卷积层、最大池层和全连接层。我们还试验了批量标准化和退出。最后,我们决定了回归问题的最佳架构,如下所示。
Figure 13: CNN architecture
该架构是一个深度网络,由四个卷积层、四个最大池层和五个全连接层组成。使用这个架构,我们尝试了两种预测流行度的方法。
梯度增强 CNN :
最初,我们试图在输出之前获取 CNN 的最终特征层,并使用这些特征来训练我们的 XGBoost 模型。我们推断,由于这将包括图像特征以及我们的分类和数字数据,这将显著改善我们的结果。我们在“4”节点层和“25”节点层都尝试了这种方法,但没有发现任何明显的改进。RMSE 仍然在 0.52 左右,比我们在 MLP 的结果差得多。
影像回归:
回想一下,CNN 主要用于分类。为了使用 CNN 进行回归,只需用单个节点(具有线性激活函数)替换完全连接的 softmax 层。此外,确保您的误差度量是针对连续值的。例如,我们使用均方根误差。我们这样做了,并传递了并排的图像,以获得每个帖子的预测流行度值。结果优于 XGBoost,但次于 MLP。结果总结如下。正如你可以告诉线的最佳拟合恶化了很多相比,MLP。
平均绝对百分比差异:66.78%
均方根误差:0.0850
Figure 14: CNN results
3。二分支神经网络:混合数据:
我们最终的想法是将这两个神经网络结合在一起。这是一个混合数据的机器学习问题,我们的模型必须能够使用我们所有的数据(图像、分类、数字)来进行预测。混合数据仍然是机器学习研究的一个非常开放的领域,所以我们非常渴望尝试一下。我们一直将 Keras 用于我们的神经网络,Keras 模型可以处理多种输入。我们已经有了上面显示的两个模型,所以下一步是将它们组合成一个双分支神经网络。每个分支机构将接受每种类型数据的培训。在此之后,分支将被连接起来以进行最终预测。
Figure 15: How to combine mixed inputs
为了创建一个多输入神经网络,我们首先需要创建两个分支。每个分支将是我们在前两部分描述的神经网络:MLP 和 CNN。但是有一个变化,因为这两个模型将被连接,我们删除了每个模型的最终输出层。我们希望实际的回归最终由多分支神经网络计算,而不是由单个分支计算。最终的架构如下所示:
Figure 16: Mixed Input NN architecture
如您所见,两个分支(每个分支四个神经元)的组合输出是混合数据网络各层的输入。我们添加了另一个由四个神经元组成的密集层,最后在最后一个神经元上进行线性激活,这就是预测的流行度。这产生了误差最小的最佳模型。结果如下所述。
平均绝对百分比差异:55.22%
均方根误差:0.08021
该模型为我们提供了超过 60%的数据的实际流行度的 0.25 以内的流行度预测。最佳拟合线也显著改善。我们对最终的 RMSE 值 0.08021 非常满意。平均而言,我们的受欢迎度指标下降了 0.08,这是一个非常好的估计值。
Figure 17: Line of best fit of our mixed input model
下面是我们的一些预测。
Figure 18: Predictions of our mixed input model
总结与未来工作
对于这个项目,MLP 和两层神经网络提供了最好的结果。由此产生的 RMSE 明显好于 XGBoost 给出的基准分数,即使它知道一篇帖子上的赞数。通过结合上述所有方法,我们能够实现一个非常好的预测模型。尽管如此,仍有一些途径我们可以进一步探索,但由于时间限制,我们未能这样做。例如,将文本从各种其他语言翻译成英语会产生噪音。通过将我们对帖子的搜索限制在英语帖子,这种噪音可能会减少。我们可以采取的另一个减少数据可变性的措施是排除某些类型的账户,比如最受欢迎的账户。由于数据和特征的这种自然可变性,任何模型都很难准确地学习和预测帖子的受欢迎程度。最后,通过考虑帖子上的标签和提及,我们可以为 NLP 任务生成进一步的功能组合,以查看它们是否增加了帖子收到的赞数的可变性。
作者:迪伦·布雷、哈桑·楚格泰、努曼·吉拉尼、西蒙·谢、查理·杨和桂·萨莫拉诺
用 Python 中的随机森林预测肉类库存价格
在本帖中,我们将使用随机森林来预测 Beyond Meat 股票的价格。Beyond Meat 是一家植物性肉类替代品生产商,由伊森·布朗于 2009 年在洛杉矶创立。
我们可以做的第一件事是导入必要的库。我们将使用 yahoo finance API、seaborn、matplotlib、pandas、numpy 和 sklearn:
import yfinance as yf
import seaborn as sns
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
如果您没有安装用于 yahoo finance API 的 python 包装器,您可以在命令行中键入以下内容:
pip install yfinance
我们可以从 Yahoo finance 获取过去五个月的“BYND”股票数据,并打印前五行。我们将拉取 2019 年 5 月 5 日至 2019 年 11 月 2 日的数据:
data = yf.Ticker('BYND')
df = data.history(period="max", start="2019-05-01", end="2019-11-02")
print(df.head())
我们可以使用 seaborn 来绘制开盘价。我们还使用 matpltlib 来修改 seaborn 图。为了绘制时间序列,我们需要将日期字符串转换为日期时间对象:
sns.set()
df[‘timestamp’] = df.index
df[‘timestamp’] = pd.to_datetime(df[‘timestamp’])
sns.lineplot(df[‘timestamp’], df['Open'])
plt.ylabel("Open Price")
接下来,我们可以使用每日开盘价和收盘价计算每日回报率,并绘制结果图:
df[‘returns’] = (df[‘Close’]-df[‘Open’])/df[‘Open’]
sns.lineplot(df[‘timestamp’], df['returns'])
plt.ylabel("Returns")
接下来,我们定义一个变量来指定我们想要预测多远。让我们预测 3 天以后。我们还创建了一个新的预测列,它是向上移动了 3 天的目标变量。这里我们的目标变量是收盘价:
forecast_out = 3
df[‘prediction’] = df[[‘Close’]].shift(-forecast_out)
X = np.array(df['Close']).reshape(-1,1)
X = X[:-forecast_out]
y = np.array(df['prediction'])
y = y[:-forecast_out]
接下来,我们拆分用于训练和测试的数据,定义一个随机森林对象并训练我们的模型:
reg = RandomForestRegressor(n_estimators = 300, max_depth =300, random_state = 42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = 7)
reg.fit(X_train, y_train)
print("Performance (R^2): ", reg.score(X_test, y_test))
我们的模型 R = 0.84,还不算太差。感谢阅读,机器学习快乐!这篇文章的代码可以在 GitHub 上找到。
预测健康的社会决定因素
数据科学@HF
健康的社会决定因素——一个人的直接健康状况之外的因素,如就业、居住地和教育水平——至少决定了20%的健康结果。在第一保健,面临与这些决定因素相关的挑战的会员去医院的次数增加了 30%,住院时间延长了 2 天,医疗费用增加了 33%。问题是我们缺乏系统测量它们的数据。如果这些数据随时可用,我们将能够实现将人们与社会和环境服务联系起来的新方法,以帮助治疗、预防和治愈疾病,提高生活质量,并降低总体医疗成本。
作为一家拥有 140 万纽约人的保险公司(八分之一!),我们的数据科学和人口健康战略围绕着分析临床数据和预测健康行为和结果。会不会是我们遗漏了一些对理解我们的成员至关重要的东西?是的,肯定的。在一个十分之三的家庭生活在联邦贫困线以下的城市(FPL ),只有 1%的会员医疗索赔包含财务压力的指标,这似乎从表面上看是错误的。这就是为什么在你分析性地做任何事情之前,有先验是有好处的。
好消息是机器学习可以有所帮助。人们已经做了大量无人监管的工作来对社区进行分类,并创建风险指数。但是我们有标签数据!真正积极的标签来自那 1%的所谓的 Z 代码的声明,并且我们合理地确定我们真正的零(基于我们的先验,可能十分之一到三分之一会被误标)。统计学家会退缩,但深度学习对标签噪音是鲁棒的。单侧标签噪声略有不同,因为估计真实的类条件分布需要更严格的理论假设(我们将有一个关于这方面的博客!).利用我们对某个成员的所有了解(人口统计、邻里关系、疾病负担、利用率、药物),我们可以合理地预测哪些成员可能正在与标签集中的这些相同的社会因素进行斗争。我们建立了 10 个模型(每个模型对应一组诊断代码),并用它对我们的全体会员进行评分。有了这些新知识,我们的人口健康团队、照护管理师和提供者合作伙伴可以更容易地接触到那些可能正在与一个或多个社会因素作斗争的成员,并为他们提供有用的资源,如用于住房的 PATH 和用于食品不安全的 SNAP 。
这些风险评分本身就很有价值,也为进一步分析提供了丰富的新特征集。医疗保险行业还没有想出如何将它们纳入风险模型中,但这并不能阻止他们使用它们来影响临床结果。在我们的计划全因再入院模型中,财务和住房压力风险得分是第二重要的变量,仅次于“您过去是否被再入院?”事实上,所有 10 个评分的第一个主成分本身就像一个不错的再入院模型:AUC 为 0.68,Brier 评分为 0.19。我们的目标是将它们用作任何分析中的标准描述性特征,就像您对待年龄或种族一样。
这是我们已知社会决定地位成员的密度图
这里有根据我们的车型分类的所有会员,增加了 10 倍!
验证和影响
作为医疗服务提供者赞助的健康计划,我们很幸运拥有最终的验证数据集:在模型培训期间,数据科学家根本无法获得这些数据。我们有来自赞助医院的调查数据,试图捕捉挣扎于社会负担中的成员。他们在不知道我们正在建模的情况下进行调查,而我们在不知道他们将进行调查的情况下建立模型。结果:c 统计值为 0.71,Brier 评分为 0.16,这意味着我们是方向正确的(你几乎可以听到数据科学家的合唱,“所有的模型都是错误的,有些是有用的”)。
我们与成员进行的每一次临床互动都需要了解社会决定因素。如果我们注意到会员在艰难地支付食物费用(或者即使我们有很好的猜测),我们可以将他们与他们可能不知道的重要服务联系起来。
随着我们在更好地理解会员需求这一愿景上取得的进展,我们将提高供应商对这些情况的认识,并与更多的赞助商合作;这两者都给了我们更好的标签,从而产生更好的模型。我们一定要这么做。但是,我们也可以利用这里提出的想法立即影响我们的成员。这就是我去上班的原因。
用马尔可夫链预测天气
基于历史天气数据构建马尔可夫链
在我们的机器学习工具箱中,有从简单到复杂的各种工具。马尔可夫链处于光谱的简单一端。
我们将通过使用马尔可夫链来学习预测明天的天气。
根据维基百科,
马尔可夫链是描述一系列可能事件的随机模型,其中每个事件的概率仅取决于前一个事件达到的状态。
**翻译:**马尔可夫链有有限个可能的状态。每个时间段,它从一个状态跳到另一个状态(或同一个状态)。跳到特定状态的概率只取决于与我们当前状态相关的概率。
当我们在示例的上下文中查看它时,它会更有意义。
天气
在我们简化的宇宙中,天气只能有两种可能的状态,“晴天”或“雨天”。
(在马尔可夫链的背景下)问题是,明天是晴天还是雨天,取决于今天是晴天还是雨天。
我们将从过去的数据中推导出这些概率,并构建一个转移矩阵。
我已经生成了 7 天的历史数据来“训练”我们的马尔可夫链。日子是:[雨,太阳,雨,太阳,雨,雨,太阳]
R S R S R R S
现在计算紧接着雨天的晴天的百分比。
3/4 所以 75%。
现在计算紧接着晴天的雨天的百分比。
那是 2/2 所以 100%。
我们将利用这些信息构建我们的转换矩阵,从我们已经获得的信息中推断缺失百分比(雨后= 25%和太阳后= 0%)。
跃迁矩阵
我们也可以用图表显示上述信息。
马尔可夫链
R = rainy, S = sunny
这张图表说明了一个事实,即概率完全取决于当前状态,而不是昨天或前天的天气。
让我们做一些预测
例一:
前 3 天为【雨天、晴天、雨天】。明天下雨的概率有多大?
R, S, R
基于我们之前训练的模型。明天有 75%的机会出太阳,25%的机会下雨。
例二:
前 2 天是【雨天,雨天】。
R R
同样,明天有 75%的机会出太阳,25%的机会下雨。
例三:
前 3 天都是【晴、雨、晴】。
S R S
明天有 100%的可能下雨。太阳落山后的日子总是下雨…我知道这很悲伤…
记住,我们只考虑当天的天气,然后在转移矩阵中查找天气状态的转移概率。
太简单了?很有可能。
但有时最好的起点是一个简单的模型,它比随机猜测表现得更好。
预测 2019 年橄榄球世界杯的冠军
根据机器学习。
我喜欢橄榄球,也喜欢跳羚队。当我们看到我们最喜欢的球队在 6 周的时间里展示他们的技能,争夺威廉·韦伯-埃利斯奖杯时,这是一种特殊的感觉。心会破碎,心会愈合,心会飞翔,只是为了再次破碎。眼泪(主要是我的)会流下来,啤酒会被喝光,球迷和球员会以真正的橄榄球方式分享祝贺和和解的拥抱。
但我也喜欢编码。务实地说。过去,我曾试图用我所知道的统计学和机器学习来模拟各种每周橄榄球比赛的结果。所以我决定拂去目录上的灰尘,更新数据和模型,看看哪支队伍会在今年的比赛中获胜。
数据
首先,我需要数据。ESPN 有可爱的历史数据库,但我似乎找不到下载按钮。我需要刮它。他们每页只显示 50 个结果。
检查页面,更重要的是检查next page
按钮,我注意到有一个 href *“转到结果的第 2 页”*和一个 url。所以我可以使用这个和BeautifulSoup
来解析页面上的html
匹配数据,获得一个新的 url 并加载下一个页面。冲洗并重复。
此外,我想得到官方团队世界橄榄球排名,因为它应该是一个有用的功能。前往 World Ruby 的网站我们有可按年份配置的排名。我们再次在页面上添加了一个html
解析器,但是我需要每年的数据(我很懒)。
使用基本相同的技巧,我可以通过检查小部件 url [rankings/mru?date=2019-08-26&client=pulse](https://cmsapi.pulselive.com/rugby/rankings/mru?date=%s-11-05&client=pulse)
并简单地在字符串中递减年份来获得橄榄球排名的历史记录(*对于每场比赛,您可以获得比赛每天的排名,但目前我没有)。合并这些数据我得到以下基本结构:
Initial data used for analysis. home / away_pos & home / away_pts
are the world ranking positions and points respectively
将一个团队称为home
或away
团队在 WC 环境中并不适用,因为除了日本,所有团队都在外地,但是数据是这样组织的。所以我采用了命名约定(它击败了left_team
和right_team)
)。
当我在谷歌上搜索试图看看是否有其他人做过类似的事情时,我在 PYMC 文档中偶然发现了一个神奇的笔记本,作者是 Peadar Coyle,它使用层次贝叶斯模型来量化每个团队的进攻和防守实力。通过一点点复制意大利面和摆弄,我们可以扩展所有 WC 团队的 PYMC 模型以及估计每个赛季的参数。下面可以看到 2018**赛季的优势和劣势。
Team attacking (left) and defensive (right) statistics from Bayesian analysis
这些似乎都有道理。根据 PYMC 的文章:“我们期望我们的强队在进攻中有强烈的正面效应,在防守中有强烈的负面效应。”
结果也符合 2018 年的统计数据。威尔士被评为 2018 年最佳防守球队,紧随其后的是爱尔兰、新西兰和英格兰。在进攻方面,从我在 ESPNs stats 网站上看到的情况来看,这里最强的进攻球队和 2018 年得分最高的球队之间有着密切的一致(**请注意,上面情节中包括的比赛只适用于 2018 年,但是在最终的 PYMC 模型中,我们将 2019 年分为延长的 2018 赛季。据观察,来自缩短的 2019 年世界杯前赛季的小样本具有有偏差的参数)。
PYMC 是一个漂亮的分析工具。我们可以通过对每场比赛进行几(百)次模拟来进一步分析,并计算每场历史比赛的获胜概率以及对积分差异的估计(参见这篇精彩的博客了解更多)。
我们现在有了每场比赛的主要功能集——主队和客场队的贝叶斯进攻和防守实力、主队和客场队的世界橄榄球排名、主场获胜的贝叶斯概率以及 PYMC 预测的分差。
模型
最终数据包括自 2004 年以来所有国际橄榄球比赛的 2613 场比赛——我们对我们的球队、场地(为什么不)进行标记编码,并继续在数据集上运行分类器。为了让事情变得更简单,我把这个问题框定为一个二元问题,把主场胜利归类为 1(即home_score — away_score > 0
),否则归类为 0。
将数据放入我最喜欢的分类器 XGBoost 分类器——进行随机训练测试分割,并用 Hyperopt 进行超优化,得到以下结果:
Bayes Only F1: 0.82
XGB Train F1: 0.90
XGB Test F1: 0.87
结果和预测
最后,我们需要厕所设备。我们可以在这里下载完整的 csv 列表。我再次对结果进行假设以简化并忽略绘图。如果是主场胜利,分配home_team 4
分,否则away_team
得分。
小组赛的结果多少是可以预测的。新西兰预计将击败南非和 B 组头名,而威尔士预计将在 d 组排名第一。不出所料,英格兰和爱尔兰将在各自的小组中排名第一。这里没有预测到大的混乱。
Top 2 from each pool
下面最后阶段的结果用graphviz
和Networkx
绘制,颜色按获胜概率编码。爱尔兰 vs 南非 QF 看起来不那么决定性,预计南非获胜的概率为 51%。同样,在新西兰对威尔士的决赛中,我们没有观察到任何一个队有很大的可能性(55%对 45%支持威尔士)。
Wales is going to win the World Cup
模型诊断
我们可以探索模型,找出哪些是最重要的特征,以及为什么它会做出某些预测。下面的全球功能重要性图表明,贝叶斯数据(获胜概率和预测分差)是最重要的功能,其次是相关团队的世界排名。
Global Feature Importance
类似地,我们可以局部地理解每个单独游戏的预测。在大莱姆和 SHAP 的辩论中,我选择了 SHAP。没有真正的原因,我只是喜欢匀称的价值观的“去除效应”背后的想法。下面我们可以观察到哪些特征对每个四分之一决赛都很重要。
我们看到,主队的排名在所有 QF 预测以及贝叶斯概率数据中起着重要作用。强大的防守得分在决定谁将获胜时也有很大的影响。
没有一种模式是完美的。这是作为周末的一点乐趣来完成的。我希望你喜欢这个分析。
最后,加油博克!
感谢马克·拉莫托斯基、理查德·菲茨杰拉德和丹妮尔·费舍尔对我的纵容。
预测泰坦尼克号幸存者(卡格尔竞赛)
本案例研究的目的是记录我在第一次 Kaggle 竞赛中创建预测的过程,该竞赛名为 Titanic:机器从灾难中学习。对于外行人来说,Kaggle 是一个受欢迎的数据科学网站,拥有数千个公共数据集,提供课程,通常作为具有分析思维的社区中心。他们还举办各种目标的机器学习竞赛。这个特殊比赛的目标是建立一个分类模型,可以成功地确定泰坦尼克号乘客的生死。
Could our data science efforts have helped? We’ll find out!
我们开始吧!
1.0 导入数据
这个过程的第一步总是加载数据和必要的包。在我使用的编程语言 R 中,包是允许用户执行特定任务的算法集合。有创造美丽的情节,建立股票投资组合和几乎任何你能想象的东西的软件包。在这里,我加载了许多包,允许我利用一些强大的机器学习(ML)模型。
lapply(c(“caret”,
“h2o”,
“pROC”,
“randomForest”,
“readr”,
“tidyverse”,
“xgboost”),
library,
character.only = TRUE)
h2o.init()
h2o.no_progress()
set.seed(123)
train <- read_csv(“~/Downloads/train.csv”)
test <- read_csv(“~/Downloads/test.csv”)
竞争数据集来自两个文件:训练和测试。正如您可能猜到的,前者用于训练 ML 模型,而测试用于做出最终提交的预测。
2.0 探索数据
将我的数据放入 R 后,是时候探索数据的形状了。
train %>% glimpse()## Observations: 891
## Variables: 12
## $ PassengerId <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1…
## $ Survived <dbl> 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1…
## $ Pclass <dbl> 3, 1, 3, 1, 3, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 2…
## $ Name <chr> “Braund, Mr. Owen Harris”, “Cumings, Mrs. John Bradl…
## $ Sex <chr> “male”, “female”, “female”, “female”, “male”, “male”…
## $ Age <dbl> 22, 38, 26, 35, 35, NA, 54, 2, 27, 14, 4, 58, 20, 39…
## $ SibSp <dbl> 1, 1, 0, 1, 0, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 0…
## $ Parch <dbl> 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0…
## $ Ticket <chr> “A/5 21171”, “PC 17599”, “STON/O2\. 3101282”, “113803…
## $ Fare <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 8.4583, 51…
## $ Cabin <chr> NA, “C85”, NA, “C123”, NA, NA, “E46”, NA, NA, NA, “G…
## $ Embarked <chr> “S”, “C”, “S”, “S”, “S”, “Q”, “S”, “S”, “S”, “C”, “S…test %>% glimpse()## Observations: 418
## Variables: 11
## $ PassengerId <dbl> 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 90…
## $ Pclass <dbl> 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 1, 1, 2, 1, 2, 2, 3…
## $ Name <chr> “Kelly, Mr. James”, “Wilkes, Mrs. James (Ellen Needs…
## $ Sex <chr> “male”, “female”, “male”, “male”, “female”, “male”, …
## $ Age <dbl> 34.5, 47.0, 62.0, 27.0, 22.0, 14.0, 30.0, 26.0, 18.0…
## $ SibSp <dbl> 0, 1, 0, 0, 1, 0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 1, 0, 0…
## $ Parch <dbl> 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ Ticket <chr> “330911”, “363272”, “240276”, “315154”, “3101298”, “…
## $ Fare <dbl> 7.8292, 7.0000, 9.6875, 8.6625, 12.2875, 9.2250, 7.6…
## $ Cabin <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, “B45…
## $ Embarked <chr> “Q”, “S”, “Q”, “S”, “S”, “S”, “Q”, “S”, “C”, “S”, “S…
上面的代码说的是,训练数据有 891 行,包含 12 个不同的变量。这些变量包括乘客的姓名、性别和年龄、票价和上车地点等。这里最重要的变量是名为“Survived”的变量,这是一个由 1 和 0 组成的列表,分别表示乘客是死是活。测试数据包含 418 行,缺少“幸存”变量,因为这是竞争对手要求我们预测的。
虽然现在的数据中包含了大量信息,但并不是所有的信息都可以以当前的形式使用。为了提取尽可能多的有用信息,我必须转换其中的一些变量。
3.0 转换数据
我要查看的第一个变量是“名称”据我所知,击沉泰坦尼克号的冰山与任何乘客都没有私人恩怨,所以简单地使用乘客的全名不会提供任何有用的信息。然而,可能是乘客的头衔。像“先生”、“夫人”或“伯爵夫人”这样的头衔可以帮助我们确定乘客的社会地位(例如,他们是平民还是贵族?)对他们的生存有任何影响。
为了获得这些标题,我必须从“Name”中提取它们,下面的代码就是这样做的。
titles <- c(unique(str_extract(str_extract(train$Name, “\\,\\s[A-Za-z]+”), “[A-Za-z]+”)))
titles <- replace(titles, titles == “the”, “Countess”)
titles## [1] “Mr” “Mrs” “Miss” “Master” “Don” “Rev”
## [7] “Dr” “Mme” “Ms” “Major” “Lady” “Sir”
## [13] “Mlle” “Col” “Capt” “Countess” “Jonkheer”
如果你想知道,“Jonkheer”是荷兰贵族使用的尊称。泰坦尼克号上有一个叫约翰·乔治·罗克林的人,剧透一下,他死了。_(ツ)_/
除了使用这个标题列表来创建一个新变量之外,我还将从“Cabin”中提取 Deck 并创建一个名为“Family_Size”的变量,它只是“SibSp”和“Parch”的组合,前者是船上兄弟姐妹和配偶的计数,后者是船上父母和子女的计数。我还将清理一些其他变量,使它们更容易为 ML 模型所理解。
train <- train %>% mutate(Survived = factor(Survived), Sex = factor(recode(Sex,
male = 1, female = 0)), Pclass = factor(Pclass), Embarked = factor(Embarked),
Deck = factor(replace_na(substr(train$Cabin, 1, 1), “Unknown”)), Title = factor(str_extract(train$Name,
paste(titles, collapse = “|”))), Family_Size = SibSp + Parch) %>% select(-c(Cabin,
Name, Ticket))
test <- test %>% mutate(Sex = factor(recode(Sex, male = 1, female = 0)), Pclass = factor(Pclass),
Embarked = factor(Embarked), Deck = factor(replace_na(substr(test$Cabin,
1, 1), “Unknown”)), Title = factor(str_extract(test$Name, paste(titles,
collapse = “|”))), Family_Size = SibSp + Parch, Fare = ifelse(is.na(Fare),
mean(Fare, na.rm = TRUE), Fare)) %>% select(-c(Cabin, Name, Ticket))
3.1 预测乘客年龄
我之前检查数据时没有指出的一点是,有多少乘客的年龄没有被记录下来。在我们拥有数据的 1309 名乘客中,有 266 名没有年龄。丢失的信息以后会有问题,所以我觉得有必要用猜测来代替那些空值。
简而言之,下面的代码将训练和测试数据结合起来,提取出有年龄的记录,并拟合一个随机森林(RF)模型,该模型确定乘客年龄和其他变量之间的关系。最后,它会用对他们年龄的最佳猜测来填充所有缺失的年龄。
旁注:深入描述什么是 RF 模型将完全偏离本案例研究。如果你有兴趣了解更多关于射频模型及其工作原理的信息,请访问这个网站。
*# Combining the training and test data and selecting only the rows with ages*
age <- train %>% select(-Survived) %>% rbind(test) %>% filter(!is.na(Age)) %>%
filter(!is.na(Embarked))
*# Building a prediction model*
age_rf_model <- randomForest(Age ~ . — PassengerId, age, ntree = 5000, mtry = 9,
na.action = na.exclude)
*# Determining the accuracy of the model*
age %>% select(Age) %>% add_column(Pred = predict(age_rf_model, age)) %>% na.omit() %>%
mutate(Error = Age — Pred, Error_Pct = Error/Age) %>% summarize(RMSE = sqrt(mean(Error²)),
MAPE = mean(abs(Error_Pct)))## # A tibble: 1 x 2
## RMSE MAPE
## <dbl> <dbl>
## 1 7.30 0.302*# Using the model to predict passenger age*
train <- train %>% mutate(Age = ifelse(is.na(Age), round(predict(age_rf_model,
train)), Age))
test <- rbind(train[1, c(1, 3:12)], test)
test <- test[-1, ]
test <- test %>% mutate(Age = ifelse(is.na(Age), round(predict(age_rf_model,
test)), Age))
为了检查 RF 模型的预测有多准确,我计算了预测的均方根误差(RMSE)和平均绝对百分比误差(MAPE ),以衡量这些预测的质量。关于这两个指标的简要描述,请参阅我之前的文章。
长话短说:两种误差指标都很低。MAPE 告诉我,平均预测只有 0.3%的误差,所以虽然不完美,但我觉得对于我预测生存的最终目标来说,这是可以接受的。
4.0 训练模型
既然数据是干净的,是我开始用数据训练 ML 模型的时候了。因为我想确保我的模型在看不见的数据上表现良好,所以我将把我的训练数据分成一个较小的训练和测试数据集。这样,我可以在将模型带到 Kaggle 提供的实际测试数据之前评估模型的准确性(记住,我不能评估准确性,因为数据缺少“存活”变量)。
train_1 <- stratified(train, c(“Survived”, “Deck”, “Title”), size = 0.7, replace = FALSE)
train_2 <- setdiff(train, train_1)
我将使用四种不同的模型,每种模型都有自己的预测方式:线性模型,随机森林模型, XGBoost (极端梯度推进)模型和 H2O 的 AutoML 。同样,您可以随意点击超链接来了解这些模型是什么以及它们在做什么。
为了让下面发生的事情更容易理解,想象一下,我们想要赢得一场综合武术比赛,而不是预测泰坦尼克号的幸存者。在比赛开始前,我们只有足够的时间掌握一种武术,所以我们需要弄清楚我们应该学习哪一种才能最有机会获胜。我们知道竞争对手是谁(即我们的测试数据),但我们不确定哪种武术最适合我们。下面是我们正在进行的模拟,我们学习四种不同的武术(比如拳击、柔术、太极拳和跆拳道),看看我们如何应对与锦标赛中类似的竞争对手(即我们的训练数据)。
*# Linear Model — —*
glm_model <- glm(Survived ~ . — PassengerId, family = “binomial”, train_1)
*# Random Forest — —*
rf_model <- randomForest(Survived ~ . — PassengerId, train_1, ntree = 10000, mtry = 3, na.action = na.exclude)
*# XGBoost — —*
dummy_1 <- dummyVars(Survived ~ ., train_1[,2:12])
train_1_dummy <- predict(dummy_1, train_1)
dummy_2 <- dummyVars(Survived ~ ., train_2[,2:12])
train_2_dummy <- predict(dummy_2, train_2)
dtrain <- xgb.DMatrix(data = train_1_dummy, label = as.vector(train_1$Survived))
dtest <- xgb.DMatrix(data = train_2_dummy, label = as.vector(train_2$Survived))
watchlist <- list(train = dtrain, test = dtest)
xgb_model <- xgb.train(
data = dtrain,
watchlist = watchlist,
booster = “gbtree”,
max.depth = 3,
nthread = 2,
nrounds = 5000,
objective = “binary:logistic”,
early_stopping_rounds = 500,
print_every_n = 500
)
*# H2O — —*
train_1_h2o <- train_1 %>%
select(-PassengerId) %>%
mutate(Pclass = factor(Pclass, ordered = FALSE)) %>%
as.h2o
train_2_h2o <- train_2 %>%
select(-PassengerId) %>%
mutate(Pclass = factor(Pclass, ordered = FALSE)) %>%
as.h2o
y <- “Survived”
x <- setdiff(colnames(train_1_h2o), y)
split <- h2o.splitFrame(train_1_h2o, ratios = c(.70, .15))
t1 <- split[[1]]
t2 <- split[[2]]
t3 <- split[[3]]
h2o_model <- h2o.automl(
x = x,
y = y,
train = t1,
validation_frame = t2,
leaderboard_frame = t3,
nfolds = 5,
stopping_metric = “AUC”,
max_runtime_secs = 120
)
h2o_leader <- h2o_model@leader
5.0 模型比较
继续上面的比喻,没有一种武术能胜过所有的对手,所以我们要试着找到表现最好的一种。对于武术来说,衡量的标准可能是获胜的次数。对于《泰坦尼克号》的预测,我将精确地衡量它(主要是因为这是 Kaggle 用来给这场比赛打分的)。
为了确定这种准确性,我将生成一个所谓的置信矩阵。简单地说,这是一个 2x2 的盒子,沿着 x 轴显示实际值(在输出中称为“参考值”),沿着 y 轴显示预测值。这使您可以看到四个变量:
真阳性:预测= 1,实际= 1
真负数:预测= 0,实际= 0
误报:预测= 1,实际= 0
假阴性:预测= 0,实际= 1
准确性是对所有预测中有多少真阳性和真阴性的一种衡量。
compare_set <- train_2 %>% add_column(GLM_Pred = predict(glm_model, train_2,
type = “response”)) %>% add_column(RF_Pred = predict(rf_model, train_2)) %>%
add_column(XGB_Pred = predict(xgb_model, train_2_dummy)) %>% add_column(H2O_Pred = h2o.predict(h2o_leader,
newdata = train_2_h2o) %>% as_tibble() %>% pull(predict)) %>% mutate_at(vars(GLM_Pred,
XGB_Pred), list(~factor(as.numeric(. > 0.5))))
for (i in 13:16) {
conmat <- confusionMatrix(compare_set$Survived, compare_set[[i]], positive = “1”)
print(colnames(compare_set[, i]))
print(conmat$table)
print(conmat$overall[1])
}## [1] “GLM_Pred”
## Reference
## Prediction 0 1
## 0 141 21
## 1 23 75
## Accuracy
## 0.8307692
## [1] “RF_Pred”
## Reference
## Prediction 0 1
## 0 149 13
## 1 26 72
## Accuracy
## 0.85
## [1] “XGB_Pred”
## Reference
## Prediction 0 1
## 0 147 15
## 1 20 79
## Accuracy
## 0.8659004
## [1] “H2O_Pred”
## Reference
## Prediction 0 1
## 0 151 11
## 1 38 61
## Accuracy
## 0.8122605
正如你所看到的,就纯粹的准确性而言,XGBoost 模型的表现最好,它正确预测了训练数据中所有幸存者的 86.6%。然而,准确性并不总是最好的衡量标准。如果您查看 XGBoost 的置信度矩阵,您会看到有 15 个假阴性。RF 模型虽然在准确性方面表现不佳,但只有 13 个假阴性。为什么这可能很重要取决于具体情况。
假设你是一名医生,负责确定病人是否患有某种疾病。假设对没有患病的人进行治疗是无害的,但如果不进行治疗,患病的人肯定会死亡。鉴于上述数字,RF 模型比 XGBoost 模型多拯救了两条生命。这里的要点是,永远不要简单地看准确性,并在此基础上做出最终判断。
所以我不会在这里!
相反,我将使用 RF 和 XGBoost 模型进行预测。由于第三次提交参赛作品不花我一分钱,我也将使用线性模型进行预测,因为它的准确性不会远远落后于其他两个模型。
6.0 做出最终预测
既然我已经有了训练有素的模型(或者说战士,如果你喜欢这个比喻的话),是时候让它们发挥作用了。我将把它们用在测试数据上,这些数据是模型从未见过的。
*# XGBoost*
dummy_test <- dummyVars(PassengerId ~ ., test)
test_dummy <- predict(dummy_test, test)
submission_xgboost <- test %>% add_column(Survived = predict(xgb_model, test_dummy)) %>%
mutate(Survived = as.numeric(Survived > 0.5)) %>% select(PassengerId, Survived)
*# Random Forest*
submission_rf <- test %>% add_column(Survived = predict(rf_model, test)) %>%
select(PassengerId, Survived)
*# Linear Model*
submission_glm <- test %>% add_column(Survived = predict(glm_model, test)) %>%
mutate(Survived = as.numeric(Survived > 0.5)) %>% select(PassengerId, Survived)
让我们看看每个模型是如何预测测试数据中前 10 名乘客的存活率的。
submission_xgboost %>% left_join(submission_rf, by = “PassengerId”) %>% left_join(submission_glm,
by = “PassengerId”) %>% rename(XGBoost = Survived.x, RF = Survived.y, Linear = Survived) %>%
head(10)## # A tibble: 10 x 4
## PassengerId XGBoost RF Linear
## <dbl> <dbl> <fct> <dbl>
## 1 892 0 0 0
## 2 893 0 0 0
## 3 894 0 0 0
## 4 895 0 0 0
## 5 896 0 0 1
## 6 897 0 0 0
## 7 898 0 0 1
## 8 899 0 0 0
## 9 900 1 1 1
## 10 901 0 0 0
如你所见,三个模型都预测乘客 900 幸存。线性模型还预测乘客 896 和 898 幸存。
7.0 提交预测
现在我有了我的预测,是时候把它们提交给 Kaggle,看看它们做得如何。首先,我必须将这些预测导出到一个 CSV 文件中,这样我就可以上传它们。
write_csv(submission_xgboost, “~/Downloads/Submission XGBoost.csv”)
write_csv(submission_rf, “~/Downloads/Submission RF.csv”)
write_csv(submission_glm, “~/Downloads/Submission GLM.csv”)
上传 CSV 后,Kaggle 会生成我每次提交的最终分数。所以,让我们看看我做得怎么样。
哇!看那黑马胜利!完全出乎意料!尽管对训练数据执行了三个模型中的第三个,但线性模型实际上对测试数据执行了所有模型中最好的。我真的没想到会这样。这只是表明你可以做世界上所有的训练,有时胜利只是靠运气。
客观地说,78.9%的分数并不令人印象深刻,因为还有其他提交的作品获得了满分。但鉴于这是我的第一次比赛,我在 11098 名参赛者中名列第 3149 名(比其他参赛者的 71.6%要好),我觉得这是一次令人满意的努力。
感谢您的阅读。我希望在下一个案例研究中见到您。
预测明天的黄金价格
我们有市场优势吗?
介绍
世界各地的央行都持有黄金储备,以保证储户、外债债权人和货币持有者的资金安全。各国央行也将黄金储备作为控制通胀和增强本国金融地位的一种手段。此外,金融公司、全球机构、基金经理和个人投资者也使用黄金来对冲通胀风险,并使其投资组合多样化。作为一种贵金属,黄金是流行的首饰和装饰品。
鉴于黄金在当代世界的受欢迎程度,预测其价格是一个广泛探索的话题,也是多个全球机构和大小规模投资者感兴趣的话题。这也是一个复杂的问题,因为黄金的价格波动并不完全取决于供求关系,还取决于许多地缘政治和金融因素。
方法学
用于此分析的方法有三个步骤:数据收集/组装步骤、模型构建步骤和评估步骤。
数据收集和汇编
本分析考虑的独立变量包括经济和市场因素,如 S & P 500、道琼斯工业平均指数、富时 100 指数、国债利率、银行利率、美元指数;以及其他商品指标如银、铂、钯和原油价格。此外,黄金期货也被认为反映了市场对未来黄金价格的预期。作为这项工作的一部分,许多研究都考虑了类似的变量,但黄金期货除外。
为了控制本项目的范围,本分析未考虑黄金供应国和消费国的国际经济和市场指标,以及表明黄金买卖季节性的变量,尤其是与一些亚洲消费市场相关的变量。该项目收集的数据是 2000 年至 2018 年这些变量的每日收盘价。其他每日市场指标如开盘价、最高价、最低价和交易量没有在本次分析中使用,但可能对未来的工作有价值。
因变量,黄金价格,是从 kitco.com 网站上收集的,并基于伦敦黄金定价基准。顾名思义,这一黄金基准价格由一组参与的国际银行在伦敦每个工作日制定两次,用于为全球市场的大多数黄金衍生品和产品定价。每天设定的两个比率中的最高者用于该分析。本项目使用的黄金价格如下所示:
该数据库由多个市场数据源组装而成,并使用日期作为合并属性。一旦数据被“缝合”在一起,美国假期就从分析中删除了。此外,在探索性数据分析步骤中标记的任何缺失或不合理的数据都使用前一天的价格进行估算(向前填充)。
建模
作为模型构建练习的一部分,使用了线性回归和时间序列方法,如下所示。
模型构建过程经历了以下步骤,其中每个步骤根据需要经历多次迭代:
- 使用 2000 年到 2015 年的每日价格来训练线性回归模型。作为该步骤的一部分,测试的因变量包括:第二天的价格、下周的价格、下个月的价格和第二天价格的百分比变化。然后使用 2016 年至 2018 年的每日价格对这些模型进行了测试。这一步的结果是使用次日价格作为因变量,并且只使用一年而不是三年进行模型测试。在此步骤中,我们注意到,随着测试数据与训练数据之间的距离越来越远,模型的性能越来越差。
- 使用 2000 年到 2015 年的每日价格来训练线性回归模型,其中成本经过对数转换并缩放到零以上的中心。使用 2016 年的每日价格进行测试。
- 使用 2000 年到 2015 年的每日价格来训练单变量时间序列模型,该模型使用经过和没有经过对数变换的黄金价格。使用 2016 年的每日价格进行测试。
对于时间序列模型,只使用了自回归(AR)模型。对于研究的两种时间序列函数形式,在有和没有对数转换黄金价格的情况下,根据阿凯克信息标准(AIC),最佳顺序被确定为前 3 天。
模型评估
评估时间序列(如黄金价格)的模型性能的关键步骤是将结果与简单的解决方案进行比较。在像黄金价格这样的非季节性变量的情况下(与棉花价格或交通流量这样的季节性变量相反),天真的预测是明天的黄金价格与今天的相同。Naive solution 作为投资策略或决策工具的效用有限,但它为模型评估提供了一个基准解决方案。对于上一节中提到的模型构建步骤 1 到 3,在模型选择和与原始解决方案的比较中使用的度量是 R 平方值。
一旦选择了一个模型,该函数形式就被用于使用如下所示的扩展窗口概念来执行按时间顺序的训练/测试。从 2006 年到 2018 年,使用从 2000 年开始的前几年的数据训练的模型,对每一年的每日价格进行了时序训练/测试。对于这个时序测试,平均绝对误差(MAE)用于与原始解决方案进行比较。
结果
简单线性回归模型构建步骤的 2016 年测试结果如下所示。该模型使用 2000 年至 2015 年的每日黄金价格进行训练,并产生了与原始预测相比最佳的 R 平方值(0.9719 比 0.9715)。该模型很好地跟踪了 2016 年的实际黄金价格,如下所示:
预测的 2016 年金价与实际金价的散点图如下所示。
2006 年至 2012 年使用线性回归模型进行的按时间顺序的培训/测试评估如下所示。对于这一时间段内的每一年,预测都比天真的预测更接近实际。平均预测偏差使用平均绝对误差(MAE)来衡量。
2006 年至 2018 年按时间顺序排列的培训/测试结果如下所示。请注意,该模型未能捕捉到 2013 年黄金市场的变化趋势。
2013 年发生了什么?
从贵金属到股票的投资热潮导致 2013 年黄金价格下跌近 30%,结束了长达 12 年的牛市。这一下降主要与投资者猜测美联储削减债券购买量,消除了购买黄金以对冲美元和通货膨胀的需求有关。
使用 2000 年至 2012 年训练数据估计的模型无法完全捕捉股票、国债、美元、联邦货币政策和商品市场之间不断变化的市场条件。
结论
使用线性回归和时间序列对黄金价格建模的上述历史分析得出以下结论:
- 对于时间序列变量,无论有没有可能战胜它,都要和一个简单的解决方案进行比较。
- 检查你的模型能在多大程度上保持和扩展趋势。不是所有的模型都能完全概括一个像股票和商品市场这样高度复杂的系统。设定一个更小的时间框架,并经常更新你的模型。
- 拥有多种型号。即使时间序列不会比 2012 年之前的天真预测表现得更好,它也会比线性回归更好地捕捉到 2013 年的金价下跌,线性回归在对抗天真预测方面表现得相当好。
参考
原载于https://mlbhanuyerra . github . io。
零射击学习:用“视觉到语义”的迁移预测未知类。
融合各种感官输入如何帮助您在图像分类任务中做出更好的预测并掌握更多信息。
机器学习喜欢大数据,尤其是当它被贴上标签的时候。Google 和腾讯发布了由数百万和数千万训练样本组成的图像任务数据集。OpenAI 表明,只需将数据集和网络参数提高 10 倍,网络就能在新的水平上运行。
人脑不是这样工作的。我们不仅能够从几个例子中学习,还能够进行跨领域学习。如果有人向你解释什么是老虎,老虎长什么样,你会认出它,即使你以前从未见过它。我们甚至可以通过语言描述来辨别气味。
我如何预测以前未见过和未知的类?
生物大脑中存在跨领域的可解释性。这个抽象层次比每个感官通道都要深。
基于这种逻辑,我想出了一个制作神经网络的主意,这个网络将在一个跨感官的基础上运行。经过一些研究,我发现(显然)这不是一个新方法,它被用于所谓的 ZSL(零射击学习)。这允许在预测中有(几乎)无限数量的类。
建筑。
这个想法很简单——将图像分类网络中的图像嵌入映射到单词嵌入,在视觉和语义表示之间架起一座桥梁。
该桥理论上允许在训练期间解决有限类别数量的问题,因为现代单词嵌入(fastText 作为第一种)不限于词汇,而是能够在英语语言的完整字母数字空间上操作。
技术细节
为了测试这个想法,我遵循了以下协议:
- 使用 ResNet101 处理来自开放图像 V2 验证数据集的 42620 幅图像,在开放图像数据集中进行预训练,并为每幅图像提取嵌入向量(在 pool5 之后)。
- 每个图像对应的类名小写,用 fastText.wiki.en 模型得到嵌入向量[1x300d]。
- 使用 4 层全连接网络将图像嵌入映射到单词嵌入。以余弦距离作为损失函数对网络进行 2000 个历元的训练,并基于验证子集选择最佳检查点。
结果
为了让你对结果有一个大致的了解,让我给你几个精选的结果。每个图像用 ResNet101 和图像到语义的转换进行分类。为了使事情更加公平,我还提供了与类名最相似的向量的结果。
我试图得到的主要结果是,使用这种方法可以提取出关于图像的更丰富、更多样的“标签云”。因此,显示类名到相似词的映射和图像到语义的转换之间的本质区别是很重要的。
进一步的想法
这个简单的实验引发了许多进一步的想法和观点。一个逆字到图像转移怎么样?使用键入的文本通过 GAN 生成图像?这些很难训练,但是很容易理解。
但是我们可以在这里更进一步。思考这个架构如何与简洁的本质相关联。人类的认知功能大量处理跨领域的转移,通过比较“抽象嵌入”不断地双重检查现实的性质,以找到基础真理。我认为小说特斯拉的 FSD 以同样的方式工作——所有的神经网络合并成一个单一的地面真实向量,描述汽车周围的环境。
神经网络架构
class ImgToWordModel(nn.Module): def __init__(self): super(ImgToWordModel, self).__init__() def fc_block(in_filters, out_filters): block = [nn.Linear(in_filters, out_filters), nn.LeakyReLU(0.2, inplace=True), nn.Dropout(0.1)] return block self.model = nn.Sequential( *fc_block(2048, 2048*3), *fc_block(2048*3, 2048*2), *fc_block(2048*2, 1024), ) self.last_layer = nn.Sequential(nn.Linear(1024, 300)) def forward(self, img): out = self.model(img) word = self.last_layer(out) return word
其他一切都很明显。ResNet101 的推理代码取自开放图像,训练细节如下(2000 个纪元)
loss_fn = torch.nn.CosineEmbeddingLoss().to(device) optimizer = torch.optim.Adam(model.parameters(),1e-3) flags = Variable(torch.ones(256)).to(device)
我肯定会写另一个关于这个想法的哲学方面的出版物,保持联系!
原载于 2019 年 4 月 29 日【https://fridayexperiment.com】。
预测未知的未知
参考论文:减少网络恐惧症:https://arxiv.org/pdf/1811.04110.pd
对于许多领域和场景的分类模型,重要的是预测何时给予模型的输入不属于它被训练的类别。
对于计算机视觉/物体检测器模型,作者提供以下理由:
Object detectors have evolved over time from using feature-based detectors to sliding windows [34], region proposals [32], and, finally, to anchor boxes [31]. The majority of these approaches can be seen as having two parts, the proposal network and the classification network. During training, the classification network includes a background class to identify a proposal as not having an object of interest. However, even for the state-of-the-art systems it has been reported that the object proposals to the classifier “still contain a large proportion of background regions” and “the existence of many background samples makes the feature representation capture less intra-category variance and more inter-category variance (...) causing many false positives between ambiguous object categories” [41]. In a system that both detects and recognizes objects, the ability to handle unknown samples is crucial. Our goal is to improve the ability to classify correct classes while reducing the impact of unknown inputs.
这也是许多领域中需要解决的一个重要问题,包括医疗保健、机器人(不考虑视觉或 NLP)。
术语:
过去处理这一问题的方法依赖于两种基本方法:
- 给定一个输入,根据该输入与培训中看到的输入的接近程度提供不确定性得分。==> P (U | x)
- 给定输入 x,预测该输入属于训练该模型所有类别 Ci (i=1 到 n)的概率。然后,我们以最小概率为阈值,以最大概率拒绝集合外或未知的输入。
以下是一些相关方法的总结:
- 设定 Softmax 分数的阈值:这种方法假设来自未对网络进行训练的类别的样本将具有分布在所有已知类别中的概率分数,因此使得任何已知类别的最大 softmax 分数较低。因此,如果系统设定最高分数的阈值,它可以避免将这样的样本分类为已知类别之一。这是迄今为止最常见和最简单的技术,不需要任何模型再训练或额外的分布数据来应用它。然而,它很少工作得很好。主要是因为 softmax 已知会使概率偏向某个类,即使胜出类与其相邻类的 logit 值之间的差异很小。对此的一个解决方法是:
2.不确定性估计:2017 年,Lakshminarayanan 等人[20]介绍了一种使用 MNIST 数字训练的 MLP 系综及其对立示例来预测不确定性估计的方法。他们的方法不是逼近 P(u | x),而是专注于在 x ∈ Du 时减少 max(P(c | x)),他们使用网络系综解决了这个问题
3.开放集方法 OpenMax:在训练过程中不使用背景样本。OpenMax 旨在直接估计 P(U | x)。使用来自训练样本的深度特征,它建立不属于已知类的输入的每类概率模型,并在每个类概率的 OpenMax 估计中组合这些模型,包括 P(U | x)。虽然这种方法提供了正式解决深度网络的开集问题的第一步,但它是在网络已经被训练之后的离线解决方案。它没有改进特征表示来更好地检测未知类。
4.背景类:用背景类训练的系统使用来自 Db 的样本,希望这些样本足以代表 Du,以便在训练后系统正确地标记未知。它类似于 1 末尾所示的 soft max-alpha 修改方法。阈值 Softmax 以上,除了它使用背景类的例子在训练。
在此背景下,本文的主要贡献如下:
Our Contributions: In this paper, we make four major contributions: a) we derive a novel loss function, the Entropic Open-Set loss, which increases the entropy of the softmax scores for background training samples and improves the handling of background and unknown inputs, b) we extend that loss into the Objectosphere loss, which further increases softmax entropy and performance by minimizing the Euclidean length of deep representations of unknown samples, c) we propose a new evaluation metric for comparing the performance of different approaches under the presence of unknown samples, and d) we show that the new loss functions advance the state of the art for open-set image classification. Our code is publicly available
[http://github.com/Vastlab/Reducing-Network-Agnostophobia](http://github.com/Vastlab/Reducing-Network-Agnostophobia)
熵开集损失:
如果有 C 个已知类别,这里的想法是当给定属于背景(已知未知)的输入时,训练网络为每个已知类别生成 1/C 的概率。如果背景有足够的变化,希望这能转化为对未知的类似预测。请注意,这只是对典型交叉熵损失的一个微小修改。
设 Sc 为上述 softmax 分数,我们的熵开集损失 JE 定义为:
基于上述熵开集损失(EOS ),我们有以下直观推导:
引理 1 和引理 2 相当直观。
为了解释定理 1:直觉是如果我们想要 softmax 概率对于背景类是相等的,一种方法是馈送到网络最后一层的特征向量 F(x)为零。这是因为 logits = Wl * F(x)。对于背景类示例,如果 F(x)是 zeors,则 logits 将为零,因此 softmax 概率将相等。
目标大气损失:
这种损失的目的是迫使背景样本的 F(x)为低值,并将已知样本推入我们称之为对象圈的地方,在那里它们具有大的特征量。
**总结:**object sphere loss 易于实现,在未知的未知预测中帮助很大。
车辆碰撞和机器学习
用机器学习预测车祸死亡率。Python 中的演练。
Heatmap Wellington Vehicle Crashes
道路事故是我们世界各地社会的一个主要问题。世界卫生组织(世卫组织)估计,2010 年有 125 万人死于道路交通伤害。2016 年,仅美国就记录了 37,461 起与机动车碰撞相关的死亡,平均每天约 102 人。在欧洲,统计数据还表明,2017 年每分钟就有 50 人死于道路交通事故。机器学习能帮助我们理解车祸的原因和影响车祸严重程度的因素吗?
在本文中,我们将通过 API 获取数据,执行探索性数据分析,并将现实世界的问题公式化为机器学习模型,从而完成一个完整的机器学习管道。完整的代码和 Jupyter 笔记本可以在这个 Github Gist 中找到。整个过程是在 Google Colab 中使用免费的 GPU/TPU 环境进行的,所以你可以直接从 Github 打开笔记本,并在 Google Colab 中进行实验。
获取数据
碰撞分析系统(CAS)数据有不同的格式和 API。很容易通过 API 接口获取它们,而不是下载到您的本地机器。这是有益的,因为我们将在每次运行 Jupyter 笔记本时访问最新更新的数据。我发现车辆事故这一特殊问题与位置(地理)密切相关,因此我们将获取 Geojson 文件,而不是通常的 CSV 文件,以便我们可以执行地理数据分析,而无需根据纬度和经度创建几何图形,并处理坐标参考系统和投影。
我们将使用 Geopandas 库来读取数据。如果你熟悉熊猫图书馆,那么你应该有家的感觉,因为地质公园是建立在顶级熊猫之上的。Geopandas 是一个高级库,它使使用 Python 处理地理数据变得更加容易,因为它允许 pandas 功能和数据类型允许对地理几何进行空间操作。它与 Python 生态系统很好地集成在一起,并且非常依赖 pandas、Matplotlib 和 shapely 库进行几何运算。
# Get the data from url and request it as json file
url = '[https://opendata.arcgis.com/datasets/a163c5addf2c4b7f9079f08751bd2e1a_0.geojson'](https://opendata.arcgis.com/datasets/a163c5addf2c4b7f9079f08751bd2e1a_0.geojson')
geojson = requests.get(url).json()# Read the data as GeodataFrame in Geopandas
crs = {'init': 'epsg:3851'} # Coordinate reference system (CRS) for Newzealand
gdf = gpd.GeoDataFrame.from_features(geojson['features'], crs=crs)
探索性数据分析
在新西兰,自 2000 年至 2018 年,车祸死亡总人数为 6922 人。而车祸中重伤和轻伤的总数分别达到 45044 人、205895 人。尽管该数据集记录了所有向新西兰警方报告的车祸,但我们必须考虑到并非所有车祸都向新西兰警方报告,尤其是非致命车祸。大多数撞车事故是非伤害性的,而致命性的撞车事故最少。就死亡人数而言,大多数车祸的死亡率为零。
Left — Crash severity categories. Right — Fatality count in crash accidents
这些年来,总体统计数据显示,碰撞严重程度和死亡人数有所下降,但正如您从线图中看到的那样,从 2016 年开始,死亡人数似乎有所上升。另一方面,2017 年出现了重伤和轻伤的高峰。
The crash casualty from 2000 to 2018.
道路和其他相关属性也表明了碰撞的严重程度和死亡水平。那么让我们来探讨一下它们之间的关系。就死亡人数和道路上的车道数而言,双车道似乎比其他任何数字都要高。直路似乎与死亡事故不太相关,而大多数死亡事故与某种道路弯曲有关(容易、中等和严重)。
Right: Road curvature and crash fatality. Left: Number of lanes and crash fatality
让我们看看交通法规及其与车祸严重程度和死亡率的关系。限速是探索这种关系的一个很好的措施。时速 90 公里是最致命的限速,其次是 100 公里。
Speed limit and crash fatality count
探索天气还表明,雾和强风在死亡人数方面的百分比最高。雨、雪和霜的影响也很大。
Impact of weather in crash fatalities
地理数据探索
地理数据可视化清楚地显示了冲突发生的位置。正如你可能已经预料到的,大多数车祸发生在道路上,而且大多发生在城市里。
All vehicle crash points
让我们来看看奥克兰聚集在一起的车祸。
Some Clustered crash Points in Auckland, New Zealand.
机器学习
我们可以用不同的方式处理这个问题的建模部分。我们可以将其视为一个回归问题,并根据碰撞数据集的属性预测死亡人数。我们也可以把它作为一个分类问题来处理,并根据碰撞数据集来预测碰撞的严重程度。在这个例子中,我将把它作为一个回归问题来处理。如果您想尝试一下,可以随意构建一个分类模型。基本上是同样的方法。在这种情况下,我不会进行任何特征工程,我认为我们拥有的属性足以建立一个基线,我们可以随时重新访问它,并在以后进行特征工程,以提高我们的模型准确性。
我们首先需要将分类特征转换成数值。我们可以像这样使用 Sklearn 库:
# Label encoder
from sklearn.preprocessing import LabelEncoder
lblE = LabelEncoder()
for i in df:
if df[i].dtype == 'object':
lblE.fit(df[i])
df[i] = lblE.transform(df[i])
然后,我们将数据分为因变量和自变量以及训练和验证集,以便稍后评估我们的模型结果。
# Let us split our data into training and validation sets
X_train, X_test, y_train, y_test = train_test_split(df.drop('fatalCount', axis=1), df.fatalCount, test_size=0.33, random_state=42)
现在,我们准备将机器学习模型应用于我们的数据。我通常从随机森林开始,这是一种基于树的算法,在许多数据集上表现良好。
m = RandomForestRegressor(n_estimators=50)
m.fit(X_train, y_train)
print_score(m)Output:
RMSE Train:0.017368616661096157,
RMSE Valid:0.042981327685985046,
Accuracy Train: 0.977901052706869,
Accuracy Valid: 0.8636075084646185
正如您所看到的,简单随机森林模型在验证集上为我们提供了 86%的准确性,经过一些初始微调和使用特征重要性选择,该模型可以提高到 87%。我们可以更进一步,在我们的模型中做一些改进,创建新的特性或者使用一些其他算法来提高模型性能,但是现在,这对于本文的目的来说已经足够了。以下是我们的随机森林模型的一些最重要的特征。
Feature Importance
结论
我希望你喜欢阅读这篇文章。如果你想尝试和试验代码,它可以作为 GitHub Gist 获得,你可以直接在 Google Colab 中打开笔记本。
你可以在推特@shakasom 上找到我。
预测与解释
以及为什么数据科学需要更多的“半贝叶斯人”
A directed acyclic graph depicting the causal pathways to foetal alcohol spectrum disorders
认知科学中的文化战争
我最近无意中发现了这场关于自然语言处理的非常有趣的辩论,这场辩论发生在几年前,辩论双方是该领域的老守卫者,被认为是现代语言学之父的诺姆·乔姆斯基和新守卫者,谷歌研究总监的彼得·诺维格。当评论这个领域的走向时,乔姆斯基说了下面的话:
“假设有人说他想取消物理系,并以正确的方式去做。“正确的”方法是将视频之外发生的事情的无数录像带,输入最大、最快的计算机,数十亿字节的数据,进行复杂的统计分析——你知道,贝叶斯这个和那个——你会得到某种关于窗外接下来会发生什么的预测。事实上,你得到的预测比物理系给出的要好得多。好吧,如果成功被定义为得到大量混乱的未分析数据的合理近似值,那么这样做比物理学家做的方法好得多,你知道,没有关于无摩擦平面的思想实验等等。但你不会得到科学一直致力于的那种理解——你得到的只是正在发生的事情的近似值。”
乔姆斯基在其他地方反复强调了这种观点:当前对自然语言处理成功的定义——即预测准确性——并不科学。将“一些巨大的文本语料库”扔进“复杂的机器”仅仅是“近似未分析的数据”,或者“蝴蝶收集”,这不会导致对语言的“真正理解”。他认为,科学的主要目标是“发现一个系统实际上如何工作的解释原则”,而实现这一目标的“正确方法”是“让理论指导数据”:通过精心设计的实验,抽象出“不相关的干扰”,研究系统的基本性质——这是自伽利略以来现代科学一直采用的方法。用他自己简洁的话来说:“只是试图处理未经分析的混乱数据不太可能让你有所作为,就像它不会让伽利略有所作为一样。”
Norvig 推测乔姆斯基对“贝叶斯这个和那个”的蔑视实际上来自于 Leo Breiman 描述的统计建模中两种文化之间的分裂:1)T2 数据建模文化,它假设自然是一个变量随机关联的黑盒子,建模者的工作是识别最适合这些潜在关联的模型;2)算法建模文化假设黑盒中的关联太复杂,无法用简单的模型来描述,建模者的工作是使用能够最好地估计输入变量输出的算法,而不期望能够理解黑盒内变量的真正潜在关联。诺维格怀疑乔姆斯基并不讨厌概率模型(数据建模文化)本身,而是讨厌带有“千万亿个参数”的算法模型,这些模型不容易解释,因此对解决“为什么”的问题没有用处。Norvig 和 Breiman 属于阵营#2,他们认为像语言这样的系统太复杂,太随机,太偶然,不能用一小组参数来表示;抽象掉复杂性类似于“制造一个精确调谐到永恒领域的神秘设备”,这是不存在的,因此“忽略了语言是什么以及它是如何工作的要点。”在另一篇论文中,Norvig 在这一点上加倍努力,他认为“我们应该停止行动,好像我们的目标是创作极其优雅的理论,而是拥抱复杂性,并利用我们最好的盟友:数据的不合理的有效性。”他指出,在语音识别、机器翻译以及机器学习对网络数据的几乎所有应用中,像“n 元模型或基于数百万特定特征的线性分类器”这样的简单模型比试图发现一般规则的复杂模型表现得更好。
这场辩论最让我着迷的不是乔姆斯基和诺维格的分歧,而是他们的共识:他们都同意,在不了解变量的情况下,用统计学习方法分析大量数据,往往会比试图模拟变量之间相互关系的理论方法产生更好的预测。我不是唯一一个被这个问题难倒的人:我与之交谈过的许多具有数学和科学背景的人也发现这相当违反直觉:最擅长建模底层结构关系的方法难道不应该也具有最强的预测能力吗?或者,如果我们不知道事物是如何运作的,我们怎么能准确地预测任何事情呢?
预测与因果推理
即使在像经济学和其他社会科学这样的学术领域,预测能力和解释能力的概念也经常被混为一谈——表现出高解释能力的模型通常被认为是高度预测的。但是构建最佳预测模型的方法与构建最佳解释模型的方法完全不同,建模决策通常会导致两个目标之间的权衡。为了说明方法上的差异,下面是“统计学习介绍”中对预测和推理建模的简短总结(ISL)
预测建模
预测模型的基本原理相对简单:使用一组容易获得的输入 X 来估计 Y。如果 X 的误差项平均为零,则可以使用以下公式来预测 Y:
其中,是 x 提供的关于 y 的系统信息,在给定 x 的情况下,这将导致ŷ(y 的预测)。只要能准确预测 y,则的精确函数形式通常无关紧要,并且被视为“黑盒”
这类模型的精度可以分解为两部分:可约误差和不可约误差:
为了提高模型的预测精度,主要目标是通过使用最合适的统计学习技术来估计,从而最小化可约误差。
推理建模
当我们的目标是了解 X 和 Y 之间的关系,即 Y 如何作为 X 的函数而变化时,就不能将ф视为“黑箱”,因为在不知道ф的函数形式的情况下,我们无法确定 X 对 Y 的影响。
几乎总是这样,参数方法被用来估计建模推理时。参数指的是这种方法如何通过假设参数形式来简化估计,并通过假设的参数来估计。这种方法有两个一般步骤:
1.对的函数形式做一个假设。最常见的假设是,在 X 中是线性的:
2.使用数据来拟合模型,即找到β₀、β₁,…,βp 的参数值,使得:
拟合模型最常用的方法是普通最小二乘法(OLS)。
灵活性/可解释性权衡
你可能已经在想:我们如何知道是否有线性形式?因为不知道真实的形式,我们实际上不知道,如果我们选择的模型离真实的太远,我们的估计就会有偏差。那么我们为什么要首先做出如此强有力的假设呢?这是因为在模型的灵活性和可解释性之间有一种内在的平衡。灵活性是指模型可以产生的形状范围,以适应许多不同的可能函数形式,因此模型越灵活,它可以产生越好的拟合,从而提高其预测准确性。但是一个更灵活的模型通常更复杂,需要更多的参数来拟合,并且对的估计经常变得太复杂,以至于任何单个预测因子的关联都是不可解释的。另一方面,线性模型中的参数相对简单且可解释,尽管它在准确预测方面做得不是很好。这里是 ISL 中的一个很好的图表,它说明了不同统计学习模型中的这种权衡:
如你所见,支持向量机和 Boosting 方法等预测精度更好的更灵活的机器学习模型在可解释性上也很低。并且通过对函数形式作出强假设以使模型更易解释,推理建模在此过程中也放弃了预测准确性。
因果识别/反事实推理
但是等等!即使你使用一个高度可解释的非常适合的模型,你仍然不能使用这些统计数据作为因果关系的独立证据。这是因为老生常谈的“相关性不是因果关系”,这里有一个简洁的例子:假设你有 100 根旗杆的长度、它们阴影的长度和太阳位置的数据。您知道阴影的长度是由极点的长度和太阳的位置引起的,但是即使您将极点的长度设置为因变量,将阴影的长度设置为自变量,您的模型仍然会得到非常好的拟合,具有统计上显著的系数,等等。这就是为什么因果推断不能仅由统计模型做出,而需要背景知识——推断的因果关系必须由一些先前对关系的理论理解来证明。因此,因果推论的数据分析和统计建模通常在很大程度上受理论模型的指导。
…即使你有坚实的理论依据来证明 X 导致 Y,确定因果关系通常仍然非常棘手。这是因为估计因果效应涉及到识别在 X 没有发生的反事实世界中会发生什么,根据定义这是不可观察的。这里有另一个简洁的例子:假设你想确定维生素 C 对健康的影响。你有关于某人是否服用维生素的数据(如果服用,X = 1;否则为 0),以及一些二元健康结果(如果健康,Y = 1;否则为 0),看起来像这样:
Y₁代表服用维生素 c 的人的健康结果,Y₀代表不服用的人的健康结果。为了确定维生素 C 对健康的影响,我们将估计平均治疗效果:
𝛉 = E(Y₁)- E(Y₀)
但是为了做到这一点,我们需要知道服用维生素 c 的人如果没有服用任何维生素 c 会有什么样的健康结果,反之亦然(或者 E(Y₀|X = 1,E(Y₁|X = 0),这在表中用星号表示,代表不可观察的反事实结果。如果没有这些输入,平均治疗效果(𝛉)无法得到一致的估计。
更糟糕的是,现在想象已经健康的人倾向于服用维生素 C,而已经不健康的人倾向于不服用。在这种情况下,即使维生素 C 实际上对健康没有任何影响,估计也会显示出强烈的治疗效果。在这里,既往健康被称为影响维生素 c 摄入和健康(x 和 y)的混杂因素,这导致对𝛉.的有偏估计
对𝛉进行一致估计的最安全方法是通过实验对治疗进行随机化,使 x 独立于 y。当随机分配治疗时,平均而言,未治疗组的结果可作为治疗组反事实结果的无偏替代,并确保没有混杂因素。A/B 测试就是在这种洞察力的指导下进行的。但是随机实验并不总是可行的(或者说是合乎伦理的,比如说,如果我们想研究吸烟或吃太多巧克力饼干的健康影响),在这些情况下,因果关系必须通过通常非随机治疗的观察数据来估计。有许多统计技术通过构建反事实结果或模拟观察数据中的随机治疗分配来识别非实验环境中的因果关系,但正如您可以想象的那样,这些类型的分析结果通常不是非常稳健或可重复的。更重要的是,这些方法障碍不是为了提高模型的预测准确性,而是通过逻辑和统计推理的结合来提供因果关系的证据。
衡量预测模型的成功也比因果模型容易得多——虽然预测模型有标准的性能指标,但评估因果模型的相对成功更具挑战性,这可能会使它们在情感上更不令人满意。但是即使因果推论很难做出,这并不意味着我们应该停止尝试。这里的要点是,预测模型和因果模型服务于非常不同的目的,需要非常不同的数据和统计建模过程,通常我们需要两者都做。这个关于电影行业的例子说明了这一点:电影工作室使用预测模型来预测票房收入,以便预测影院上映的财务结果,评估其电影投资组合的财务风险/回报等。,但预测模型对于理解电影市场的结构和动态并为投资决策提供信息不是很有用;这是因为在电影制作过程的早期阶段(通常在发行日期之前数年),当做出投资决策时,可能结果的方差非常高,因此基于早期阶段输入的预测模型的准确性大大降低。预测模型在接近影院上映日期时是最准确的,此时大多数制作决策已经做出,即当预测不再特别可行时。另一方面,因果推理模型允许工作室了解不同的生产特征如何影响生产过程早期阶段的潜在收入,因此对通知他们的生产策略至关重要。
当前对预测的过分强调——乔姆斯基有道理吗?
从定量研究文献的现状来看,不难理解为什么乔姆斯基感到不安——预测模型现在正主导着学术界和工业界。这份对学术预印本的文本分析发现,在这十年中,发展最快的定量研究领域越来越关注预测。例如,在人工智能领域,提及“预测”相关术语的论文增长了>的 2 倍,而提及“推理”相关术语的论文自 2013 年以来下降了一半。今天的数据科学课程在很大程度上忽略了因果推理方法,数据科学行业大多希望从业者专注于预测模型。即使是像 Kaggle 和网飞奖这样备受瞩目的数据科学竞赛,也总是基于提高预测性能指标。
另一方面,仍有许多领域没有对经验预测给予足够的重视,并且可以受益于机器学习和预测建模的进步。但是,将目前的事态框定为“乔姆斯基团队”和“诺维格团队”之间的文化战争似乎是一个错误的选择——我们没有理由只能选择一个,而且两种文化之间有很多相互交流的机会。有许多的工作正在进行,以使机器学习模型更具可解释性,我个人尤其对斯坦福大学的苏珊·艾希所做的工作感到兴奋,他们将机器学习技术应用于因果推理方法论(我将在接下来的几周内撰写相关文章——敬请关注!).
除了宣传朱迪亚·珀尔的作品,我想不出更好的方式来结束这篇博客,让它更完整。珀尔在 20 世纪 80 年代领导了人工智能的研究工作,允许机器使用贝叶斯网络进行概率推理,但此后成为了人工智能对概率关联的唯一关注如何阻碍进步的最大批评者。与乔姆斯基的观点相呼应, Pearl 认为“深度学习的所有令人印象深刻的成就只不过是拟合数据的曲线,”而今天的人工智能却被困在做完全相同的事情(预测和诊断/分类),这些事情机器在 30 年前就已经知道如何做了——只是稍微好一点而已——然而预测和诊断“仅仅是人类智能的尖端。”他认为,制造像人类一样思考的真正智能的机器的关键是教会机器思考因果关系,这样机器就可以提出反事实的问题,规划实验,并找到科学问题的新答案。他在过去三十年的工作重点是为机器建立一种形式语言,以使因果推理成为可能,类似于他在贝叶斯网络上的工作,使机器能够进行概率关联。在他的一篇论文中,他声称:
“人类的大部分知识是围绕因果关系而不是概率关系组织的,概率演算的语法不足以捕捉这些关系……正是因为这个原因,我认为自己只是半个贝叶斯。”
看起来数据科学会因为有更多的半贝叶斯人而受益。
用深度学习预测费西合唱团接下来会放什么歌
Phish, Hampton 2018
费西合唱团——一个标志性的现场摇滚乐队,和机器学习的世界……他们可能有什么共同点?
像绝大多数音乐艺术家的现场表演一样,对费西合唱团来说,大多数活动都是没有计划的。从乐队踏上舞台的前几天到前几个小时,没有预先确定的节目单、歌曲选择或演出持续时间。每场演出,乐队和观众都开始了一个全新的旅程,由集体能量和精湛的即兴表演推动。
我和我的朋友们多年来一直在观看费西合唱团的演出,像社区中的许多人一样,我们经常在每场演出前玩一个游戏,看谁能猜出费西合唱团的 876 首歌曲中的哪一首将在某个晚上播放。我们的游戏版本包括每个人猜演出开场,演出期间播放三首歌,以及一首安可歌曲。考虑到你(在技术上)有大约 0.11%的成功机会,如果你预测中有一个是正确的,那通常是一个非常美好的夜晚。
在工业界做了几年数据科学家后,我开始揭示隐藏在费西合唱团歌曲选择中的统计模式,并建立了一个模型来预测接下来会有什么歌曲。
方法。
我决定将这个问题设计成一个连续的多类分类任务,类似于神经语言模型——即:
“给定一系列歌曲,我能准确预测下一首将播放的歌曲吗?”
在本文接下来的部分中,我将详细介绍我的数据收集/准备过程、建模练习、结果和改进计划——让我们来看看本质。
数据。
对我来说幸运的是,在 Phish.net 有一个很棒的团队,他们积极地维护和更新一个全面的数据库和费西合唱团的公共 API,包括:表演,节目列表,场地,歌曲等等。在编写了一个 Python API 包装器(与迈克·阿兰戈合作)之后,我能够检索自 1983 年以来所有 1752 场费西合唱团秀的历史数据。
Most recent 5 shows from Phish.net API with setlist data parsed and pipe delimited
创建训练数据集
有了语言建模方法,我通过首先丢弃不完整的集列表,然后将每个集列表按时间顺序连接到一个长列表中,并对数据进行编码(876 首独特歌曲中每首歌曲的歌曲到整数,加上所有集列表标识符)来生成训练数据。维护集合列表标识符(集合 1、集合 2、Encore 等。)提供了上下文,并且将允许模型学习到某些歌曲更有可能出现在第二集的开始部分与中间部分与再唱部分。
接下来,我创建了训练样本对,即与序列中的下一首歌曲(Y)配对的歌曲列表(X)。我将单个的连接列表分割成长度为 *L、*的 N 个样本,其中 L 成为建模的超参数。模型需要多长的序列才能准确预测下一首歌?我测试了长度为 25、50、100、150 和 250 的序列,稍后会有更多的测试。然后,我在大约 37,000 个样本上创建了一个 80/20 的训练/验证分割,以评估我的模型。
Example of one sample training pair
建模。
虽然有许多机器学习模型可以应用于这种情况,但我选择实现一种深度学习方法,因为它在我的语言建模隐喻任务中具有最先进的性能。具体来说,我选择测试了一个具有嵌入层和 LSTM(长短期记忆)细胞的序列 RNN(递归神经网络)的几种不同配置。RNN 氏症的循环性质使得跨时间步骤的信息共享成为可能,这使得所学的知识能够以“记忆”状态在网络中持续存在。出于这个原因,这个架构非常适合学习我们的集合列表建模问题的顺序性质。我的模型的其他组件是:
- 歌曲嵌入层 — 类似于 NLP 世界中的单词嵌入…我选择为 876 个类别中的每一个类别嵌入一个 N 维向量,希望该模型将学习关于每首歌曲的潜在因素,以提供用于后续预测层的更丰富的特征集。这里的嵌入大小成为另一个可探索的超参数。稍后将对此进行更多分析。
- LSTM 细胞——香草 RNN 细胞非常擅长学习和联想短期依赖性。如果我们的输入序列只有一个集合列表(~ 10–20 首歌曲),这是没问题的,但是因为我们需要监视和跟踪许多节目的长期依赖性,所以我们的输入序列有 50–250 首歌曲长。LSTM 单元引入了一个被称为“单元状态”的学习参数,该参数为网络提供了随时间选择性地“记住”或“忘记”重要或不重要的长期依赖性的选项。
- 退出 —在【相对】小数据集上应用神经网络的一个常见问题是过度拟合的诅咒。我在这里提出的深度学习架构有> 300,000 个学习参数,这意味着模型很容易从它看到的训练数据中“学习太多”,而不能很好地推广到新数据。为了防止这种情况发生,我实现了退出正则化,在训练期间随机“关闭”一些神经元的激活。这种有意阻碍模型学习的方法在防止过度拟合方面非常有效。
- 学习率探测器 —选择最佳学习率对于及时有效地训练神经网络至关重要。学习率太高,你的模型会发散;太低,你的模型将永远训练,损失很少改善。我加入了这个令人敬畏的 LR Finder Keras callback ,它绘制了几个小批量运行的学习率与损失的关系,以帮助您可视化最佳学习率。我还添加了一个平滑特性,采用指数移动平均来帮助清理视觉效果,以便于解释。最佳学习率对应于损失下降最大的*——如下图绿色所示。*
Example learning rate finder with smoothed plot (right)
- Adam 优化器 —Adam 通过结合每参数学习率(来自 AdaGrad)和动量(来自 RMSProp)的概念,改进了基本随机梯度下降(SGD)。简而言之,这种增强的优化器使您的模型能够更快地学习,并且已经成为该领域的一种“首选”技术。
有了这些模型和优化器组件,下面是用于实验的两种体系结构变体:
模型架构 1
Sequential model with Embedding Layer, Dropout Layer, LSTM Layer, Dropout Layer, and a Dense Layer
模型架构 2
Same model as above, but two stacked LSTM Layers for additional learned parameters
实验。
迭代 1 — “广撒网”
锁定模型组件后,我通过网格搜索以下超参数的各种设置,撒下一张大网:
- ***架构:*一层与两层 LSTM
- ***序列长度:*模型需要多长的序列来正确学习下一首歌曲?初始设置为 25、50、100、150 和 250 首歌曲。但是请记住,这里的权衡是序列越长,可用的训练示例数量越少…
- ***LSTM 单位数:*我在 50 和 100 之间切换。
- LSTM 之前辍学: 0%-70%(增量)
- LSTM 之后的退学率: 0%-70%(递增)
Validation Loss vs. Epoch from four trained models (The ~100 other trained models have been hidden for interpretability)
调查结果
- 辍学是至关重要的,但不要太多。看起来大约 50%的辍学允许适当的学习而不会过度适应。
- 正确的学习率确实能加快收敛。
- 用一个更大的模型来解决问题并不一定有帮助。更多的参数(即层、LSTM 单位)并不一定等同于更大的学习潜力,并使模型更容易过度拟合。
- 大约 50 的输入序列长度对于这个问题的建模是理想的。任何更短的时间,模型都无法学习某些依赖关系,任何更长的时间,模型都会失去焦点,并强调学习不太重要的长期依赖关系。
- 许多不同的超参数设置和模型尺寸似乎集中在相同的损失水平附近,对应于大约 18%到 20% 的 。
迭代 2 — “嵌入深潜”
有了这些知识,我开始理解嵌入表示对我的模型的影响,看看是否有改进的空间。首先,我将嵌入向量的大小从固定长度 50 切换到 100、150、200 和 250。很明显,较大的嵌入大小对整体分类准确度有轻微的改善(约 21%),因为它允许模型为每首歌曲学习更多细微的特征。
解读
这些习得的嵌入实际上代表了什么?
为了更好地理解模型所学到的东西,我提取了嵌入,执行了主成分分析(PCA)以将它们折叠成三维,并以 3D 形式绘制它们。
3D visualization of principle components from song embeddings — contextually similar songs to “Ghost” are highlighted in yellow
正如所料,该模型已经学会了将出现在相似背景下的歌曲联系起来。上图展示了 20 首与《人鬼情未了》最相似的歌曲——费西合唱团的粉丝们可以在这里找到明显的联系。请注意它们在 PCA 向量空间中出现得有多近…
看到这些学习向量确实有改进的空间,我通过单独创建自己的歌曲嵌入扩展了这个想法。通过训练一个名为 CBOW(连续词袋)的 Word2Vec 算法,我创建了包含双向上下文和神经网络只进上下文的向量。使用这些大大改进的歌曲向量之间的余弦相似性揭示了一些真正有趣的模式。**
Six Phish songs with most similar songs (sorted by descending cosine similarity)
上图显示了一首给定的歌曲,以及 Word2Vec 模型学习到的 9 首最相似的歌曲。在这个意义上,相似性意味着歌曲出现在相同的上下文中或者在集合列表中的位置。对于知道这些歌曲的潘,你会立即认同:
- 与大卫·鲍依有关的乐观、高能的“谷仓燃烧者”
- 像这样短小、快节奏的蓝调小曲闪耀着的光芒,在更突出的歌曲之间起到连接的作用
- 节奏较慢、旋律不连贯的音乐
- 老套而当之无愧的流行歌曲
在迁移学习的尝试中,我然后利用这些上下文丰富的嵌入作为我的神经网络嵌入层的初始化参数(而不是随机的)。在嵌入层冻结和不冻结的情况下训练网络;后者被证明更有效,允许我将 的准确度略微提高到 21.8% 。
把它包起来。
21.8%的准确率有多好?
首先,这比随机机遇好得多。非常令人惊讶的是,一个统计模型可以理解和解释我多年来内在化的一些微妙关系——特别是考虑到它对这些歌曲实际上听起来是什么样子一无所知。然而,现实情况是,模型(像我们人类一样)非常擅长学习出现在一些特定模式中的歌曲,而在其他模式中则相当糟糕。这些特殊的模式发生在歌曲出现的时候:
- 费西合唱团有几首歌曲几乎总是一首接一首地并排出现。我们的模型在很大程度上正确地处理了后续的歌曲。(例如。《麦克的歌》>《我是氢》>《weeka paug Groove》或《马》>《清晨无声》或《一扫而光》>《险峻》)
- 作为集合开启器/闭合器
- 作为安可
- 当猜测是休息/再来一次的时候
Songs that the model performs best on (sorted by F1 Score)
改进的余地
这种建模方法的一个巨大问题是,它只关注顺序数据……这意味着它没有围绕费西合唱团的分类和抽象知识的概念。例如,该模型不识别什么是[较新的] 3.0 歌曲,因此,不理解这些歌曲与[较旧/现在较罕见的] 1.0 歌曲相比更可能现在播放。一个巨大的改进将是纳入分类数据(时代,地点,年份,专辑等)。)与集合列表序列一起输入到神经网络中。**
另一种改进方法(或至少改进相关性)是排除前 10-15 年的数据。如下所示,费西合唱团在 90 年代早期表演了他们的大部分节目(1994 年有 128 场演出!)当他们播放的独特歌曲相对较少时(今天的 850 多首中的约 375 首),这意味着大多数我们的训练数据严重偏向于学习与这 375 首歌曲相关的模式(在费西合唱团 1.0 期间)。一个很好的例子就是《冷若冰霜》>《脆皮罗茜》>《冷若冰霜》;该剧在 1992-1995 年间上演了 46 次,此后只上演了 4 次。
让事情变得更复杂的是,费西合唱团当时定期播放某些歌曲,现在很少播放了。更不用说,自费西合唱团 1.0 以来推出的新歌[并继续出现]总体上播放频率更低,因此可供学习的模式也更少。因此,这是一个很难建模的问题。
集合列表生成
使用新训练的神经网络[巧妙地命名为 TrAI],我们可以递归地进行预测,根据最近播放的 50 首歌曲的输入,生成费西合唱团的下一个曲目列表。不再赘述,以下是 TrAI 对 2019 年 11 月 29 日在罗德岛普罗维登斯举行的秋季巡回赛揭幕战的预测:
TrAI’s predicted setlist for next show in Providence, RI on November 29th 2019
这个项目使用的工具有:Python、Keras、Tensorflow、Gensim、Jupyter、Anaconda、Tableau 和 Tensorboard。所有支持代码都可以在我的 Github repo 这里找到。
感谢阅读——拿骚见!
使用大数据分析预测漫威人物是善是恶。
Marvel Universe
摘要
本文利用统计方法、数据挖掘技术和 Python 来创建超级英雄角色对齐的预测模型。
首先,我们选择要利用的数据集,然后对其进行准备、处理和分析。然后,将清洗后的数据导入数据挖掘工具;Weka,创建一个可行的预测模型,可以根据字符的描述来预测排列。然后对这个结果进行测试和讨论,以描述不同的结果。
本文假设您对 Python 和 Pandas 有一定的了解,因此不会对这些主题进行过多的讨论。如果你有任何问题,请发邮件给我,地址:【vfrantzvaag@gmail.com】。
关键词:数据挖掘、python、统计学、分析学、超级英雄
数据采集
本项目中使用的数据集是在 kaggle.com 从用户 FiveThirtyEight 处获得的,由 Kaggle 维护,增强了其可信度。(https://www . ka ggle . com/fivethirtyeight/fivethirtyeight-comic-characters-dataset)。数据集包含两个 CSV 文件和一个描述数据文件中内容的自述文件,并于 2019 年 1 月 31 日下载。尽管数据集包含 DC 和漫威的数据,但我决定只使用漫威的数据,因为它们是最受欢迎的(Statista、Finder、Boxofficemojo ),而漫威数据集包含的行数是它的 2.3 倍。此外,这些宇宙是由不同的团队创建的,这意味着我们从一个宇宙中推断出的东西可能与另一个宇宙不相关。
数据集描述
漫威数据集包含了漫威维基百科中所有记录的字符的信息,更具体地说,大约有 16400 个不同的字符。下载数据集并使用 Pandas package for Python,我可以请求列表顶部的五个元素并检查 CSV 文件的格式,还可以请求行数和列数。
Checking out the dataset using the framework Pandas for Python. (The set_option method is just for printing all the columns in the terminal)
What is outputted in the terminal after the previously written Python code.
表中的列有:page_id、name、urlslug、id、align、eye、hair、sex、GSM、alive、appearances、first appearance 和 year,它们在数据集附带的自述文件中有所描述。
数据准备
准备数据集以供使用是确保质量的关键步骤,包括减少数据中的异常和冗余。此过程的第一步是删除对最终案例没有帮助的列;基于特征预测字符对齐。这可以用正常的逻辑来完成;删除不表达特征的列。与最终案例不相关的列是:
-
page_id: 维基百科页面的唯一标识符
-
Urlslug :角色的维基站点的 URL
GSM: 如果角色是性别或者性少数。会提供信息,但是只有 90 行的值可以用以下 python 代码进行验证:
Checking how many valid entries there are in the GSM column.
- 出场次数:漫画中的出场次数
——**第一次出场:**漫画中的第一次出场
- 年:漫画中的人物第一次出现
考虑到我发现这些列对我的目的来说无关紧要,我用 Python 将它们从数据集中删除。
Removing the insignificant values from the dataset.
由于这将是我的模型的训练集,因此“Align”列中必须有一个值,以便它能够使用数据进行训练,因此我删除了“Align”列中包含 NULL 的所有列,因为这不会提供任何信息。“Align”列当前有三个可能的值;好的,中立的,坏的。在这个项目中,我主要感兴趣的是弄清楚一个角色是否邪恶,并考虑到一些心理学家将“好”定义为“有移情和同情的能力”(史蒂夫·泰勒,2013),我将把“中性”和“好”列组合在一起。为了能够执行计算,为了简单起见,我还将列转换为数字;1 表示他们是邪恶的,0 表示他们是善良/中立的。
Python code for joining the neutral and good characters, as well as converting all columns to numeric values. Also calculating the amount of rows lost when dropping the null values.
现在,我可以从原始文件中减去新创建的文件中的行数,并看到通过删除“Align”列中的空值,总共丢失了 2812 行。
The outputted code for displaying how many rows we lost with the previous Python code.
现在对齐列已经准备好了,不重要的列已经被删除,我可以导入清理过的。CSV 文件导入统计工具;JMP 要做“模型检查”。我将目标变量设置为 Align,并选择其余的列作为模型效果,除了“name ”,因为它更像是一个标识列。这给了我一个整体模型测试的概述和一个效果总结。结果反映了显著性值为 0.95 的无效假设的总结,这意味着低于 0.05 的 p 值提供了足够的理由来抛弃无效假设,从而推断出另一个假设;这些属性有助于对齐。无效假设和替代假设如下所示:
H0 : β1 = β2 =… βg = 0
哈:βi ≠ 0
Here we are looking for P-values that stick out (being over 0.05). If we for example would’ve kept the attribute for the URL to the wiki site of the character, this probably would’ve given us a p-value higher than 0.05, signifying that we probably could remove that attribute.
查看汇总统计数据,可以注意到没有一个个体或整体模型的 p 值峰值超过 0.05;强调另一种假设,即有属性给出关于排列的信息,并且所有的单个属性都有贡献。
最后,我必须为我的数据挖掘工具准备文件;WEKA——一个。arff 文件是最合适的格式。由于 Weka 在解析 CSV 文件时遇到了问题,我无法使用内置转换器,只能选择外部转换器;伊利亚·库佐夫金【1】做的一个。然而,我在导入新创建的时仍然遇到了问题。arff 文件,因为在一些列中有特殊字符——我在 Sublime Text 中使用 find-all 搜索功能手动删除了这些字符。
【https://ikuz.eu/csv2arff/】
数据分析
形象化
为了进一步了解不同的列如何影响字符的对齐,我将清理后的数据集导入到一个数据可视化工具:Tableau 中。我的主要兴趣点是比较字符特征如何影响对齐列。
Tableau dashboard comparing the characteristics to alignment. (Remember that Align = 1 is evil and Align = 0 is good/neutral.
从对齐方面来看特征之间的差异,可以看到有许多共同的元素,但在某些方面有所不同。如果我要根据这些信息构建一个“刻板印象”的角色,一个邪恶的角色将没有头发,红眼睛,是一个男性角色,有一个秘密的身份,并且已经去世——而一个好的角色将有金发,蓝眼睛,是一个女性角色,有一个公共身份并且活着。这些角色在你看来是恶是善?对我来说是的。
数据挖掘技术
现在,数据已经准备好、清理和分析完毕,我可以将它导入数据挖掘工具“Weka”来创建预测模型。我们现在进入分类领域,目的是识别一个物体属于哪一类。分类是监督学习的一种形式,我们创建一个模型,将目标变量的值设置为特征的函数(Provost & Fawcett),监督意味着我们为算法提供一个带标签的数据集进行训练。
目的是通过使用分类来预测作为特征结果的比对列,但是有大量不同的分类算法,这意味着我必须找到最适合的一个。使用 Weka 中的“分类器”栏,我可以检查不同的预设选项:
Looking into what classification algorithms Weka offers us by default.
选择正确的算法至关重要,这样才能获得最佳结果,并确保尽可能高的模型精度。通过利用由 SciKit 创建的“算法备忘单”,一个显示算法的不同前提的流程图(标有绿色),我从下面他们的网站绘制了图中的路径:
Choosing our path from the SciKit-learn algorithm cheat-sheet (marked in red).
考虑到 SVC(支持向量机)在 Weka 中试用过,但没有在训练集上运行,合理的选择是使用“朴素贝叶斯”算法。
朴素贝叶斯模型的一个明显优势是它可以很好地处理缺失值,这对于包含一些空列行的漫威数据集非常有用。(Witten 等人)朴素贝叶斯的前提之一,或者更确切地说,为什么它是“朴素的”,是因为它在变量独立的假设下运行。使用模型时必须考虑到这一点;这些列之间没有相关性,或者它们互不影响。尽管这有点无效,但考虑到这是例如头发和眼睛颜色之间已证实的相关性(Lin 等人),这只是用于模型计算,我们可以使用当前的假设来建立有效的模型。
导入被净化的。arff 文件到 Weka 中,我首先在我的训练数据集上运行朴素贝叶斯模型,不改变任何参数,并且在所有模型测试中将交叉验证设置为标准值 10,其中数据被分成 10 份;一些用于测试,一些用于训练。(Witten 等人)我主要感兴趣的 KPI 是整体模型精度(正确分类的实例),目前是 65.7%。
Summary of running a standard Naïve Bayes algorithm on my training set.
以 65.7%作为我的基准利率,我寻求提高模型的准确性。经过反复试验,我发现使用核密度估计(KDE)可以将准确率提高近 2%至 67.03 %。KDE 没有假设模型的任何特定分布,这适合于这种情况,例如,具有这种数据的标准分布可能难以实现。在我看来,追求明显更高的比例是有问题的,因为不可能根据每个角色的特征对他们进行正确的分类——一个人即使没有头发和红眼睛也可以很好。
现在我已经找到了一个成功率可以接受的合适模型,我想在我自己的一些训练数据上测试这个模型的表现如何。从原始数据集中提取 10 个字符;其中五个是“好的/中性的”,五个是“坏的”,并用“?”替换对齐列。
Taking some famous characters and labeling the alignment column ‘?’, in order to test out how well our model does in practice.
使用这个作为训练集,我在我创建的模型上重新评估它,并得到以下输出:
Summary of running our model on the ten aforementioned characters. In the predicted column (red), 1:0 tells us that the character is good and 2:1 tells us that the character is bad. The blue column tells us how certain the model is about its prediction.
在“预测”列下,所有前五个实例都被正确分类(比对为零是好的/中性的),而在后五个实例中,五个实例中有三个(60%)被正确分类,在这个小训练集中总共有 80%的实例被正确分类。还可以注意到,在“错误预测”栏下,该模型在分类“好的/中性的”字符方面比“坏的”字符更确定。其原因可能是许多“坏角色”有多重身份/人格,在做邪恶的行为时会改变形态或外表——正如下面可以看到的,两个错误分类的例子;毁灭博士和瑞雯·达克霍姆有一种“变化的眼光”:
The shifting look of the incorrectly classified instances.
讨论
根据一个人的特征来预测他的婚姻有很多伦理问题。陆荣兴等人认为,保护隐私并以道德和匿名的方式处理数据对于捍卫我们的自由是必要的。在这篇论文中,我没有预测真实的人的排列,因此没有暴露于这些法律和伦理问题。然而,如果这个模型要应用到其他地方,也就是说,如果有人要用它来预测他们刚刚遇到的人是好是坏,就必须考虑这些问题。
你可以有很多种可能性来描述一个角色,数据集中有描述超级英雄更详细的信息(力量,起源等等)。).然而,一个人必须将自己限制在一个特定的阈值,一个模型才是可行的。即使更多的信息可以导致更准确的模型,这个模型背后的主要思想是基于短暂的一瞥或谣言来预测角色的排列。过多的信息或复杂性也会导致模型从数据中捕获过多的噪声,从而导致所谓的“过度拟合”(Witten 等人)。
参考
文章
1.《票房魔咒》创下全球票房纪录,更新于 2019 年 2 月 8 日
可在https://www . box office mojo . com/all time/world/world wide openings . htm找到
2.截至 2017 年 8 月,美国公众对漫威电影和 DC 漫画电影的偏好,Statista,15.08.2017
可在:https://www . statista . com/statistics/754142/marvel-DC-movie-preference/找到
3.超级英雄统计;DC 对漫威,发现者,2017 年 11 月 16 日
可在:https://www.finder.com/superhero-statistics找到
4.预测恐怖行为的准确率超过 90%,宾厄姆顿大学,2017 年 3 月 2 日
可在:https://www . science daily . com/releases/2017/03/170302115740 . htm找到
5.预测恐怖行为的准确率超过 90%,宾厄姆顿大学,2017 年 3 月 2 日
可登陆:https://www . science daily . com/releases/2017/03/170302115740 . htm
6.中国已经开始用令人毛骨悚然的“社会信用”系统对公民进行排名,亚历山德拉·马,2018 年 4 月 8 日
7.“善”和“恶”的真正含义,史蒂夫·泰勒,2013 年 8 月 26 日
可在以下网址找到:https://www . psychologytoday . com/us/blog/out-the-darkness/2013 08/the-real-meaning-good-and-evil
文学
8.关于超级英雄的起源:从生活大爆炸到动作漫画,克里斯·加瓦勒,2015
9.对恐怖主义有效预测市场的道德分析,Dan Weijers & Jennifer Richardson,2014 年
10.业务数据科学,Provost & Fawcett,2013 年
11.头发和眼睛颜色的遗传重叠;威廉森 G;阿卜德拉维 A;巴特尔斯 M;Ehli EA 戴维斯·葛;布姆斯马·迪和霍滕加·JJ,2016 年 12 月 19 日
12.数据挖掘;实用机器学习工具和技术,Ian WittenEibe Frank & Mark Hall,2011 年
13.走向大数据时代的高效和隐私保护计算——卢荣兴;朱晖;西盟刘;刘和,2016。
R 简介—合并和过滤数据—第 1 部分
通过对 2019 年澳网男子巡回赛数据的筛选和合并进行数据理解。
Photo by Christopher Burns on Unsplash
你知道当澳大利亚网球公开赛造访墨尔本的时候是夏天,每个人都为罗杰和塞丽娜的到来而兴奋。
问题
我有兴趣预测谁可能赢得 2019 年澳大利亚网球公开赛男子巡回赛。我希望他退役前是罗杰·费德勒。
资料组
我从网站http://www.tennis-data.co.uk/data.php选择了从 2000 年到 2019 年 1 月的男子网球锦标赛历史成绩,这些成绩以 CSV 文件的形式提供。
数据字典
网球数据附带的注释解释了由网球博彩提供的数据的属性:
Key to results data:
ATP = Tournament number (men)
WTA = Tournament number (women)
Location = Venue of tournament
Tournament = Name of tournament (including sponsor if relevant)
Data = Date of match (note: prior to 2003 the date shown for all matches played in a single tournament is the start date)
Series = Name of ATP tennis series (Grand Slam, Masters, International or International Gold)
Tier = Tier (tournament ranking) of WTA tennis series.
Court = Type of court (outdoors or indoors)
Surface = Type of surface (clay, hard, carpet or grass)
Round = Round of match
Best of = Maximum number of sets playable in match
Winner = Match winner
Loser = Match loser
WRank = ATP Entry ranking of the match winner as of the start of the tournament
LRank = ATP Entry ranking of the match loser as of the start of the tournament
WPts = ATP Entry points of the match winner as of the start of the tournament
LPts = ATP Entry points of the match loser as of the start of the tournament
W1 = Number of games won in 1st set by match winner
L1 = Number of games won in 1st set by match loser
W2 = Number of games won in 2nd set by match winner
L2 = Number of games won in 2nd set by match loser
W3 = Number of games won in 3rd set by match winner
L3 = Number of games won in 3rd set by match loser
W4 = Number of games won in 4th set by match winner
L4 = Number of games won in 4th set by match loser
W5 = Number of games won in 5th set by match winner
L5 = Number of games won in 5th set by match loser
Wsets = Number of sets won by match winner
Lsets = Number of sets won by match loser
Comment = Comment on the match (Completed, won through retirement of loser, or via Walkover)
在 Mac Book Pro 中将 csv 文件合并成一个数据文件
我在 Youtube 上看到了一个来自的 Trent Jessee 的教程,它帮助我在 Macbook Pro 上将 2000 年至 2019 年的多个 csv 文件合并成一个文件。
#打开终端会话,进入
cd 桌面
#输入 cd 和保存 csv 文件的文件夹名称
cd CSV
#用此命令合并文件
cat *。csv >合并. csv
将您的数据加载或导入 R
*# Set the working directory*
setwd("~/Desktop/ATP")
*# Read the dataframe into Rstudio as a csv file.*
tennis_data <- read.csv("merged.csv",stringsAsFactors = FALSE, header = TRUE)
*# Review the first 5 observations*
head(tennis_data)## ATP Location Tournament Date Series
## 1 1 Adelaide Australian Hardcourt Championships 1/3/00 International
## 2 1 Adelaide Australian Hardcourt Championships 1/3/00 International
## 3 1 Adelaide Australian Hardcourt Championships 1/3/00 International
## 4 1 Adelaide Australian Hardcourt Championships 1/3/00 International
## 5 1 Adelaide Australian Hardcourt Championships 1/3/00 International
## 6 1 Adelaide Australian Hardcourt Championships 1/3/00 International
## Court Surface Round Best.of Winner Loser WRank
## 1 Outdoor Hard 1st Round 3 Dosedel S. Ljubicic I. 63
## 2 Outdoor Hard 1st Round 3 Enqvist T. Clement A. 5
## 3 Outdoor Hard 1st Round 3 Escude N. Baccanello P. 40
## 4 Outdoor Hard 1st Round 3 Federer R. Knippschild J. 65
## 5 Outdoor Hard 1st Round 3 Fromberg R. Woodbridge T. 81
## 6 Outdoor Hard 1st Round 3 Gambill J.M. Arthurs W. 58
## LRank W1 L1 W2 L2 W3 L3 W4 L4 W5 L5 Wsets Lsets Comment X X.1 X.2 X.3
## 1 77 6 4 6 2 NA NA NA NA NA NA 2 0 Completed
## 2 56 6 3 6 3 NA NA NA NA NA NA 2 0 Completed
## 3 655 6 7 7 5 6 3 NA NA NA NA 2 1 Completed
## 4 87 6 1 6 4 NA NA NA NA NA NA 2 0 Completed
## 5 198 7 6 5 7 6 4 NA NA NA NA 2 1 Completed
## 6 105 3 6 7 6 6 4 NA NA NA NA 2 1 Completed
##根据 2000 年至 2019 年的数据预测谁将赢得 2019 年澳大利亚网球公开赛
#加载包
图书馆(dplyr)
#设置工作目录
setwd(" ~/桌面/ATP ")
#将数据帧作为 csv 文件读入 Rstudio。
tennis _ data
#回顾前 5 条观察结果。最佳实践是使用 tail()来查看最后 5 次观察。
主管(网球 _ 数据)
查看合并数据的结构
在 R 中,我们可以探索数据的结构,检查数据的属性,在预处理之前观察原始数据。
str(网球 _ 数据)
在合并的数据文件中有 52383 行和 83 列。
## 'data.frame': 52383 obs. of 83 variables:
## $ ATP : int 1 1 1 1 1 1 1 1 1 1 ...
## $ Location : chr "Adelaide" "Adelaide" "Adelaide" "Adelaide" ...
## $ Tournament: chr "Australian Hardcourt Championships" "Australian Hardcourt Championships" "Australian Hardcourt Championships" "Australian Hardcourt Championships" ...
## $ Date : chr "1/3/00" "1/3/00" "1/3/00" "1/3/00" ...
## $ Series : chr "International" "International" "International" "International" ...
## $ Court : chr "Outdoor" "Outdoor" "Outdoor" "Outdoor" ...
## $ Surface : chr "Hard" "Hard" "Hard" "Hard" ...
## $ Round : chr "1st Round" "1st Round" "1st Round" "1st Round" ...
## $ Best.of : int 3 3 3 3 3 3 3 3 3 3 ...
## $ Winner : chr "Dosedel S." "Enqvist T." "Escude N." "Federer R." ...
## $ Loser : chr "Ljubicic I." "Clement A." "Baccanello P." "Knippschild J." ...
## $ WRank : chr "63" "5" "40" "65" ...
## $ LRank : chr "77" "56" "655" "87" ...
## $ W1 : chr "6" "6" "6" "6" ...
## $ L1 : chr "4" "3" "7" "1" ...
## $ W2 : int 6 6 7 6 5 7 6 7 2 6 ...
## $ L2 : int 2 3 5 4 7 6 1 6 6 7 ...
## $ W3 : int NA NA 6 NA 6 6 NA NA 6 6 ...
## $ L3 : int NA NA 3 NA 4 4 NA NA 1 4 ...
## $ W4 : int NA NA NA NA NA NA NA NA NA NA ...
## $ L4 : int NA NA NA NA NA NA NA NA NA NA ...
## $ W5 : int NA NA NA NA NA NA NA NA NA NA ...
## $ L5 : int NA NA NA NA NA NA NA NA NA NA ...
## $ Wsets : int 2 2 2 2 2 2 2 2 2 2 ...
## $ Lsets : int 0 0 1 0 1 1 0 0 1 1 ...
## $ Comment : chr "Completed" "Completed" "Completed" "Completed" ...
数据框的尺寸
数据帧的尺寸包括-52383 行和 83 列。
dim(网球 _ 数据)
检查是否有丢失的值
有相当多的缺失值。评估后可能需要对缺失值进行插补。
is.na(网球 _ 数据)
过滤并子集化 R 中的数据
我需要过滤我的数据,以便更易于管理,我对分析 2000 年至 2019 年的澳大利亚网球公开赛很感兴趣。
#我们只想查看结果数据的前 26 列
姓名(网球 _ 数据)[1:26]
#我们想要过滤澳大利亚网球公开赛的数据,以便我们可以使用数据的子集:
aust _ Open
#查看仅与澳大利亚网球公开赛相关的数据子集的结构:
str(aust_open)
## 'data.frame': 2413 obs. of 26 variables:
## $ ATP : int 6 6 6 6 6 6 6 6 6 6 ...
## $ Location : chr "Melbourne" "Melbourne" "Melbourne" "Melbourne" ...
## $ Tournament: chr "Australian Open" "Australian Open" "Australian Open" "Australian Open" ...
## $ Date : chr "1/17/00" "1/17/00" "1/17/00" "1/17/00" ...
## $ Series : chr "Grand Slam" "Grand Slam" "Grand Slam" "Grand Slam" ...
## $ Court : chr "Outdoor" "Outdoor" "Outdoor" "Outdoor" ...
## $ Surface : chr "Hard" "Hard" "Hard" "Hard" ...
## $ Round : chr "1st Round" "1st Round" "1st Round" "1st Round" ...
## $ Best.of : int 5 5 5 5 5 5 5 5 5 5 ...
## $ Winner : chr "Agassi A." "Alami K." "Arazi H." "Behrend T." ...
## $ Loser : chr "Puerta M." "Manta L." "Alonso J." "Meligeni F." ...
## $ WRank : chr "1" "35" "41" "106" ...
## $ LRank : chr "112" "107" "111" "28" ...
## $ W1 : chr "6" "6" "6" "6" ...
## $ L1 : chr "2" "4" "3" "2" ...
## $ W2 : int 6 7 7 4 6 6 6 6 6 5 ...
## $ L2 : int 2 6 6 6 4 1 1 4 4 7 ...
## $ W3 : int 6 7 6 6 6 6 6 NA 6 6 ...
## $ L3 : int 3 5 2 7 4 4 4 NA 4 3 ...
## $ W4 : int NA NA NA 6 0 NA 7 NA NA 7 ...
## $ L4 : int NA NA NA 3 6 NA 6 NA NA 5 ...
## $ W5 : int NA NA NA 6 6 NA NA NA NA NA ...
## $ L5 : int NA NA NA 0 4 NA NA NA NA NA ...
## $ Wsets : int 3 3 3 3 3 3 3 2 3 3 ...
## $ Lsets : int 0 0 0 2 2 0 1 0 0 1 ...
## $ Comment : chr "Completed" "Completed" "Completed" "Completed" ...
编写并导出您的数据框架
现在,我对仅包含澳大利亚公开赛的数据感到满意,我将编写文件并将其导出为 csv 文件,这样我就可以用它来预处理我的数据以及在 R 和 Tableau 中可视化数据。
*# Save the dataframe to a csv file to write the csv file into R working folder:*write.csv(aust_open,file = "aust_open.csv", row.names = FALSE)
我的下一篇文章将包括:
- 预处理 R 中的数据
- R 中的数据可视化,查看数据的样子
- R 中数据的探索性数据分析
- 缺失数据的处理
感谢阅读,敬请关注,编码快乐!