TowardsDataScience 博客中文翻译 2019(一百零一)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

使您的模型更好地工作的变量转换目录

原文:https://towardsdatascience.com/catalog-of-variable-transformations-to-make-your-model-works-better-7b506bf80b97?source=collection_archive---------3-----------------------

本书"赢得 KAGGLE 的数据分析技巧"

10 多个数字变量转换和 7 个分类变量转换

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

变量转换是使数据在模型中更好工作的一种方式。数据变量可以有两种形式:数字变量分类变量,它们的转换应该有不同的方式。

-数值变量转换 : 将一个数值变量转换成另一个数值变量。通常,这意味着通过某种“单调变换”来改变值的标度和/或将偏斜的数据分布调整为类似高斯的分布。

基于决策树的模型对比例和倾斜不太敏感,这些技术可能贡献不大,但对于其他模型(如神经网络、SVM、线性模型等。),它们可能会改变游戏规则,或者在某些情况下甚至是强制性的,例如在 L1/L2 规范中使用惩罚条款的情况。

-分类变量转换 : 将分类变量转换为数值变量。分类变量转换对于大多数机器学习模型是强制性的,因为它们只能处理数值。

它也被称为编码,或者在文本挖掘中,嵌入也是为了处理类似的情况,但是嵌入通常被认为是返回包含原始数据语义的数值。

分类变量变换对任何模型都很重要,分类变量变换的选择对模型性能有很大影响。

在这篇文章中,我将介绍转换数值变量和分类变量的基本到高级技术。

目录

1。关于变量变换的一般注意事项

2。数值变量转换

  • 2.1.标准化
  • 2.2.最小-最大缩放
  • 2.3.对数变换
  • 2.4.博克斯-考克斯变换
  • 2.5.约-约翰逊变换
  • 2.6.剪报
  • 2.7.扔掉
  • 2.8.军阶
  • 2.9.兰克高斯
  • 2.10.其他非线性变换

3。分类变量转换

  • 3.1.一键编码
  • 3.2.标签编码
  • 3.3.特征散列
  • 3.4.二进制编码和基本编码
  • 3.5.频率编码
  • 3.6.目标编码
  • 3.7.只有测试集中包含的水平时的特殊处理
  • 3.8.更多分类变量转换

4。结论

这是另一篇帖子接的一本新书中介绍的技巧*数据分析技巧赢 Kaggle *”,由三位高阶 Kaggle 作者执笔(不包括我自己)由此可见这不是个人推广!😃 )

关于这本书本身的完整目录,请参见我的其他帖子

1.对变量变换的普遍关注

有许多用于建模的转换技术,许多在 [scikit-learn](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.preprocessing)[categorical_encoders](https://contrib.scikit-learn.org/categorical-encoding/index.html)中实现。

其中使用参数的有很多,比如标签编码中标准化或换算表的均值和标准差。使用变量变换的一个常见错误是使用不同的参数分别变换训练集和测试集。训练数据和测试数据的转换应该使用相同的参数,并且它们通常单独从训练集中获得;否则,我们无法比较苹果之间的结果。scikit-learn转换器类可以通过使用fittransform函数来处理这个问题。

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

Do not encode test data separately!

有些人会更严格地声称,当使用交叉验证时,转换参数将仅从训练折叠中导出,然后验证折叠数据将由这些参数转换,而不是在交叉验证之前转换整个训练数据。当您预计褶皱之间的数据分布存在巨大差异时,这种方法可能是必要的。异常值的存在是给出不同参数的一个可能原因,特别是在对异常值敏感的变换技术中,如最小-最大缩放。

或者其他一些人可能声称,只要数据分布差异不大,在交叉验证之前转换整个训练数据就足够了,并且可以避免数据流水线的混乱。此外,我们的最终模型将基于整个训练数据,因此使用整个训练数据来转换数据可能是有意义的。

无论哪种方式,分析师总是要问自己,对于他们面对的数据,什么是最合理的方法。scikit-learn通过在[Pipeline](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html)中分配 scaler 函数,支持跨验证内转换。比较下面示例代码中的方法 1 和方法 2。

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

Photo by Matt Duncan on Unsplash

2.数字变量转换

2.1.标准化

最典型的数字变量转换是使用减法和除法将列值转换为另一组值,其中均值=0* 和标准差=1 ,这样:*

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

Formula for standardization

**标准化广泛应用于许多 ML 技术,如线性回归、SVM、神经网络等。一些 ML 模型在某种程度上要求它。默认情况下,许多分析工具甚至会自动执行此操作。如果是这种情况,您甚至不必编写代码来进行转换。我们需要注意什么是默认转换,以及它是否与您选择的方法相关。

scikit-learnpreprocessing模块的[StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html)可以处理标准化。

2.2.最小-最大缩放

**最小-最大缩放是简单数字变量转换的另一个常见疑点。使用最小-最大缩放,值将被转换为 0 到 1 之间的值。

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

Formula for min-max scaling.

*这种转换高度依赖于最大数和最小数,因此对异常值特别敏感。**如果值可能非常大,而许多值却不是,则标准化更为常见。*最小值-最大值缩放更常见于数值范围在固定区间内,且数据不太可能在区间内的特定子范围内聚集的情况;最常见于图像数据中,其中一个元素的 RGB 颜色值在 0 到 255 之间。

scikit-learn preprocessing模块的[MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html)可以处理最小-最大缩放。

2.3.对数变换

当价值分布具有长尾分布时(如个人收入、个人医疗费用等。), 对数变换可以将数据分布调整到更少的偏斜,希望是类似高斯的分布

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

Formula of log transformations

numpy有一个原生函数将 log(x+1)计算为[np.log1p(x)](https://docs.scipy.org/doc/numpy/reference/generated/numpy.log1p.html)

广义对数变换应该调整数据分布的参数λ,使其更接近正态分布。现在你要记住,你不应该如我在 "1 中所讨论的那样更改训练集和测试的参数。关于变量转换的一般注意事项见上文

2.4.博克斯-考克斯变换

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

Box-Cox transformation

Box-Cox 变换*是 log(x)变换和 x-1 变换之间的变换,取决于λ**的值。scikit-learn preprocessing中的[PowerTransformer](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PowerTransformer.html)模块可以处理这种转换,自动选择λ使数据最接近高斯。*

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

Box-Cox Transformation

2.5.约-约翰逊变换

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

Yeo-Johnson transformation.

**Yeo-Johnson 变换是允许负值作为初始值的变换,与 Box-Cox 变换不同。lambda=1 时,变换几乎是恒等变换。如下图所示,lambda 的变化会影响变换后的值。

以及 Box-Cox 变换,scikit-learn preprocessing模块中的[PowerTransformer](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PowerTransformer.html)可以处理这种变换,自动选择 lambda 使数据最像高斯

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

Yeo-Johnson Transformation.

2.6.剪报

**限幅是一种在特定值点限制或降低值的方法。这可以移除异常值,代价是可能丢失原始数据信息。

通过pandasnumpy clip功能可以轻松完成裁剪。以下代码剪辑了 1%平铺点和 99%平铺点的值。

2.7.扔掉

宁滨中,您将值分组到不同的区间,并将组索引用作分类变量。您可以将它用作有序分类变量或数值变量作为等级。作为分类变量,你也可以通过一键编码或其他分类变量转换来转换它(见下一章!)

宁滨区间的确定是参数选择,可以通过规则区间、百分点或基于数据领域知识的手动设置来确定。

宁滨可以通过pandas cut功能或numpy digitize功能来完成。

2.8.军阶

将原始数值转换为数值等级。通过除以记录数,等级还可以转换为 0 到 1 之间的值,这使得转换后的数量与记录数无关。

这本书介绍了一个有趣的例子:在分析一家商店的顾客数量时,假日的顾客数量很可能比工作日的顾客数量多很多。然后,使用原始的顾客数量可能会把假期看得太重。将数字转化为排名可以抵消客户绝对数量的影响。

pandas rank函数或numpy argsort函数可以处理这种转换。

2.9.兰克高斯

RankGauss 是一种先将数值转化为等级,再按照高斯分布将等级转化为另一个数值的方法(见下图。)这是用于 Porto Segro 的安全驾驶员预测第一名解决方案 为其神经网络模型。第一名得主 Michael Jahrer 声称对于他们的神经网络模型来说,这比标准化或最小-最大缩放更有效。**

sklearn.preprocessing中的[QuantileTransformer](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.QuantileTransformer.html)可以通过设置参数n-quantiles large 和output_distribution = ‘normal’来处理这种变换。

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

Comparison between original data and transformed data by RankGauss

2.10.其他非线性变换

书中还介绍了以下非线性变换:

  • 取绝对值
  • 求平方根
  • 平方或取 n 次方
  • 制作一个二进制变量,表示原始值的属性,如正或负、零或零等。
  • 取原始值的分数,如小数部分
  • 舍入,向上舍入,截断

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

Photo by Andrew Buchanan on Unsplash

3.分类变量转换

机器学习模型只能处理数值型变量。因此,如果一个列有分类变量,那么只有当它被编码为数字变量时,模型才会工作。如何编码是建模中的关键性能驱动因素之一。

3.1.一键编码

One-hot encoding 是一种将一个分类列转换为多个二进制(0 或 1)列的方法,其数量与原始列中不同级别的数量相同。如果分类变量有四个级别,one-hot 编码将创建四个新列,每个列都有 0 或 1,并表示原始列是否有级别。

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

Illustration of one-hot encoding (four-level column (A-D) creates four new columns)

one-hot 编码的一个明显缺点是列的数量很容易随着许多不同的级别而膨胀。一个可能的解决方案是根据领域知识对一些级别进行分组,或者将不常见的级别分组到“其他”级别中。

您可以使用pandas [get_dummies](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.get_dummies.html)功能或scikit-learn preprocessing模块的[OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html)进行一键编码。后一个可以返回带sparse=True参数的稀疏矩阵,在原列有很多级的情况下可以节省内存消耗。

一键编码看起来类似于传统统计建模中的虚拟变量*。一键编码和虚拟变量之间的区别在于,在使用虚拟变量时,通常会从生成的新列中删除一列,以避免线性相关性,并且可以稳定估计。这种差异的原因是在 ML 环境中,*

  • 有比统计建模多得多的变量,并且一个变量的影响被稀释了。
  • 由于各种原因,许多 ML 算法并不关心线性相关性,如使用正则化项,或者选择部分变量来训练模型,从而丢失了线性相关性。

3.2.标签编码

**标签编码是一种将等级转换为整数的方法,例如等级:['A ‘,’ B ‘,’ C ',…]转换为整数:[0,1,2,…]。

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

Illustration of label encoding

这种方法在大多数机器学习算法中并不合适,因为转换值的数量实际上与目标变量无关,基于决策树的模型除外,该模型可能能够通过分层树节点拆分来多次拆分转换后的数值列。此外,如果分类变量具有“序数”性质,例如 Cold<Warm<Hot<Very Hot*,标签编码可能比其他编码技术工作得更好。*

可以用scikit-learn preprocessing模块的[LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html#sklearn.preprocessing.LabelEncoder)实现标签编码。

3.3.特征散列

**特性散列是一种使用散列技巧将一个分类列转换为多个列的方法。您可以定义要转换到的新列的数量,该数量可以少于分类列中的级别数。不同于像一键编码那样分配 0 或 1,特性哈希使用两个以上的值(在下面的例子中是-1、0 或 1)。

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

Illustration of feature hashing (four distinct levels to three new columns)

这种标记可以掩盖一键编码在转换后产生过多列的缺点。然而,在最近的高级建模技术中,拥有太多的列不再是致命的问题,因此特征散列没有被广泛使用*。*

此外,在一个新列中有两个以上的可能值可能对某些模型不利。

您可以通过scikit-learn.feature_extraction模块的[FeatureHasher](https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.FeatureHasher.html#sklearn.feature_extraction.FeatureHasher)category_encoders.hashing模块的[HashingEncoder](https://contrib.scikit-learn.org/categorical-encoding/hashing.html)对特征散列进行编码。

3.4.二进制编码和基本编码

**二进制编码是一种将分类列转换为多个二进制列,同时最小化新列数量的方法。

首先,按照一定的顺序将分类值转换为整数(例如,按字母顺序或最上面一行的出现顺序)。接下来,将其转换为二进制数字,例如 1 到 1,2 到 10,5 到 101,等等。最后,将二进制数字拆分成单独的列,每一列都有一个数字。

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

Illustration of binary encoding

二进制编码可以将新列数减少到 log_2(级数)。正如你在上面的例子中看到的,其中一个新列在不同的原始级别中有 1,这不是一件好事*因为在同一列中有 1 的级别将被模型视为共享一些属性,而实际上它们在同一列中有 1 只是出于技术原因。*

[category_encoder](https://contrib.scikit-learn.org/categorical-encoding/index.html)模块的[BinaryEncoder](https://contrib.scikit-learn.org/categorical-encoding/binary.html)可以处理这些编码。

**BaseN 编码是二进制编码的推广,BaseN 不使用基数 2,而是使用任意数作为基数。

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

Illustration of Base N encoding when N = 3

随着 N 的增加,新列的数量越来越少,但这也意味着新列中的重叠信息比我们在二进制编码情况下看到的更多,这可能会使最终的模型变得更糟。如果 N 是无穷大,BaseN 编码和 label 编码完全一样。正如我上面所讨论的,标签编码对于大多数模型都是不合适的。

[category_encoder](https://contrib.scikit-learn.org/categorical-encoding/index.html)模块的[BaseNEncoder](https://contrib.scikit-learn.org/categorical-encoding/basen.html)可以处理这些编码。

3.5.频率编码

频率编码*是一种将分类列转换为新列的方法,新列中的整数表示原始列中**级别的频率。当水平的频率对目标变量有影响时,这可能很有效。*

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

Illustration of frequency encoding.

你也可以把频率变成等级,就像序列化频率编码和等级转换一样。请注意,级别的频率比原始数据的排名更有可能导致平局。

python 中没有支持这种编码的库,但这可以通过pandas.Series本机函数[value_counts()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.value_counts.html)轻松实现。

3.6.目标编码

目标编码*是一种基于目标变量的值将分类列转换为新的数字列的方法。***

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

Illustration of target encoding (in case target variable is binary (0 or 1)).

最典型的是,它采用每个级别的目标值的平均值来创建一个新列,但是它可以是您认为合理的任何值,比如当有异常值时的中值,或者当评估度量是 RMSLE 时的对数值的平均值。

目标编码可能会成为强有力的预测工具,但正如本书作者反复警告的那样,除非小心处理,否则它很容易导致数据泄露。

因为目标编码使用来自目标变量的信息,所以我们必须避免包含要编码的同一行。为此,我们应该k-folding(其中 k=4~10) 数据:训练折叠中目标值的平均值被指定为出折叠数据中的编码值。对每个折叠重复此操作,为整个训练数据生成编码值。测试数据通常使用整个训练数据进行编码。

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

Illustration of K-folding for target encoding (in case target variable is binary (0 or 1)).

[category_encoders](https://contrib.scikit-learn.org/categorical-encoding/targetencoder.html)模块有目标编码处理器TargetEncoder,但即使这样,你也必须自己完成 K-fold。

作者还声称你不应该使用(LOO)进行目标编码,因为这太有可能导致数据泄露**。

3.7.只有测试集中包含的水平时的特殊处理

当某些级别仅包含在测试数据中时,模型可能会返回错误,或者即使没有返回错误,预测也可能是错误的。

以下是处理这种情况方法:

  • 如果只是预测精度的问题,而不是返回一个技术错误,那么检查一下糟糕的预测对最终得分的影响有多大。如果它足够小,忽略它是一个可行的想法。
  • 用训练数据中包含的另一个级别替换,例如使用训练数据中最常用的级别。
  • 基于其他变量建立预测模型以预测一个水平来代替未知水平。
  • 在将分类变量编码为数值变量后,将其输入,例如,用目标编码变量的数据平均值进行输入。

3.8.更多分类变量转换

Baijayanta Roy 的这篇文章“关于分类变量编码的一切”涵盖了更多的编码技术。

另外,[categorical_encoders](https://contrib.scikit-learn.org/categorical-encoding/index.html) 模块涵盖了白加炎塔帖子中介绍的大部分技术的实现。您可以通过使用本模块中的功能来进一步学习。

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

Photo by Robert Katzki on Unsplash

4.结论

在这篇文章中,我们讨论了从基本方法到高级方法的 10 多个数字变量转换技术和 7 个分类变量。

虽然有些技术比其他技术更好,例如目标编码比其他编码技术有更好的跟踪记录,但没有一种方法总是在任何数据的每个模型中都工作良好。因此,研究什么样的编码在什么情况下工作良好是很重要的,当你面临一个新问题时,你可以使用本文中介绍的尽可能多的方法,直到你发现哪种方法工作得最好。**

CatBoost 去神秘化

原文:https://towardsdatascience.com/catboost-demystified-8b0b538bfa31?source=collection_archive---------17-----------------------

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

梯度推进算法已经成为几乎所有 ML 竞赛和实际项目中的面包和黄油。CatBoost 是梯度增强工具包家族的最新成员之一。它是由 Yandex 的 ML 团队开发的开源库。那么让我们来评估一下 CatBoost 与 XGBoost、LighGBM 和 H2O 相比有什么优势?

CatBoost 有两个非常独特的进步:有序提升的实现和处理分类特征的过程。这两种技术都有助于对抗由一种特殊的目标泄漏引起的预测偏移,这种目标泄漏存在于梯度增强算法的所有现有实现中。

有序升压:

在每个步骤中使用的梯度是使用当前模型所基于的相同数据点的目标值来估计的。这导致特征空间的任何域中的估计梯度的分布与该域中的真实梯度分布相比发生偏移,这导致过拟合(预测偏移)。

作为对预测偏移的解决方案,CatBoost 通过将当前模型应用于新的训练示例,在提升的每一步独立采样新的数据集,以获得未偏移的残差。对于具有 100 棵树的模型,为了使剩余的未移位,需要创建没有原始实例的(100–1 = 99)训练数据集。由于需要所有训练样本的无偏残差,因此没有样本可用于训练先前的模型。

实际上,由于数据有限,这似乎是不可能的。但是 CatBoost 维护了一组不同的模型,用于训练的例子各不相同。然后,为了计算一个示例的残差,CatBoost 使用了一个未经训练的模型。这是使用训练示例的随机排列σ来实现的。每个模型仅使用排列中的前 I 个示例来学习。在每一步,为了获得第 j 个样本的残差,CatBoost 使用 Mj 1 模型。这被称为命令增压

分类特征:

那么,为了从分类变量中提取最大的信息,你有多少次挣扎于处理分类变量的方法呢?当所有/大部分独立特征都是分类特征时,挑战变得更加严峻,如果它们具有高基数,挑战就更加严峻。下面是我最后处理分类变量的方法:

  • 独热编码
  • 标签编码
  • 目标编码
  • 将不同级别的变量组合成一个变量
  • 特征散列

计算分类特征中每个类别的目标统计数据并使用新的数字特征似乎是处理分类特征最有效的方法,同时信息损失最小。创建此功能的一个简单方法是估计具有相同类别的训练示例的 y 的平均值。现在有一个基本问题,即计算这种类型的贪婪目标统计的目标泄漏

为了绕开这个问题,CatBoost 使用了一种叫做有序目标统计的方法。每个示例的目标统计的值仅依赖于观察到的历史。为此,他们引入了人工时间,即训练样本的随机排列σ。因此,对于每个示例,所有可用的历史都用于计算其目标统计数据。此外,如果仅使用一个随机排列,则前面的示例将具有目标统计,其方差比后面的示例高得多。为了避免这种情况,CatBoost 对梯度增强的不同步骤使用不同的排列。

Few other interesting characteristics I find in CatBoost are:

功能组合:

CatBoost 的另一个重要细节是使用分类特征的组合作为捕获高阶的附加分类特征。CatBoost 以贪婪的方式构造组合。也就是说,对于树的每次分裂,CatBoost 将当前树中先前分裂已经使用的所有分类特征(及其组合)与数据集中的所有分类特征相结合(连接)。组合被动态转换为目标静态

SHAP 价值观:

在特征重要性函数中,你可以得到 SHAP 值,只需输入 type='ShapValues ’

对象重要性:

如果您可以从训练数据中知道哪些实例对学习模型的贡献最大,会怎么样?CatBoost 提供此功能来计算训练数据集中的实例对优化度量值的影响。

  • 正值反映优化指标增加
  • 负值反映出优化的指标降低
  • 与 0 的偏差越大,该实例对优化指标的影响就越大

该方法是在为梯度增强决策树论文中描述的方法的实现。

计算要素统计数据:

有了这一功能,我们可以直观地看到算法如何分割每个特征的数据,并评估目标统计数据。我们可以想象以下情况:

  • 每个时段(对于连续特征)或每个类别(对于分类特征)的平均实际目标值
  • 每个时段/类别的平均预测目标值
  • 每个存储桶中的实例数量
  • 通过改变特征值来平均预测值

在保持所有其他要素不变的情况下,所选要素的值会发生变化,以便落在每个桶/类别下。该模型预测这些新实例的目标值,并绘制给定存储桶/类别中预测值的平均值。

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

绘制单棵树:

您可以通过提供想要可视化的树的索引来绘制单个树。

模型训练的视觉化:

默认情况下,当模型被训练时,CatBoost 提供学习过程的可视化表示。

参考资料:

希望这篇博客能为您提供关于 CatBoost 的良好背景,并帮助您探索这种算法的使用。请在评论区告诉我你的想法。

这篇内容最初发表在我的个人博客网站:【http://datascienceninja.com/。点击此处查看并订阅即时接收最新博客更新。

如果你能抓住我:流数据中的异常检测

原文:https://towardsdatascience.com/catch-me-if-you-can-outlier-detection-taxi-trajectory-streams-1bb6df584db0?source=collection_archive---------24-----------------------

使用流数据(轨迹流)进行优步需求预测

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

Photo by Zhipeng Ya on Unsplash

离群点检测是一项有趣的数据挖掘任务,广泛用于检测数据中的异常。异常值是显示出与大多数点明显不同的属性的点。为此,离群点检测具有非常有趣的应用,例如信用卡欺诈检测(可疑交易)、交通管理(醉酒/鲁莽驾驶)或网络入侵(黑客攻击)等。由于这些应用的时间关键特性,需要可扩展的异常检测技术。

在这个项目中,我们的目标是检测出租车数据集(北京)中的异常值,使用一种仅使用时空特征来检测超大型数据集中的异常值的技术。我们将使用这些出租车上的地理坐标和 GPS 收集的时间戳。

数据集

对于这个项目,我们将使用 T-Drive 数据集。该数据集有 1500 万个点,覆盖北京总共 10,357 辆出租车的 900 万公里总距离。这是一个很好的样本数据集,因为它包含大量的点,模拟了我们上面讨论的真实场景。该数据集中的每一行都对应于出租车的地理坐标和时间戳。

算法

我们将在这个问题上使用的算法是大规模轨迹流上的异常值检测。为了实现这个算法,我们需要一些技术术语的背景信息。

轨迹

移动物体 O 的轨迹被定义为在时间元 t 1 ,t 2 产生的轨迹点序列…t j 表示为 Tri = {P 1i ,P 2i ,……纪

点邻居

如果两个轨迹点 P ij ,P ik 在同一时间点 T i 中,彼此的距离在 d 之内,其中 d 是距离阈值,那么这两个点被认为是彼此的点邻居。

轨迹邻居

在特定窗口 W c 中,当且仅当对于至少 thr 时间元,轨迹在这些时间元的每一个中共享点邻居时,轨迹被称为邻居轨迹。

轨迹异常值

如果至少在 thr 时间仓中,作为点邻居的点的数量少于 k 个,则轨迹 T ri 被认为是窗口 W c 中的异常值,其中 k 是邻居计数阈值。

这个定义试图抓住这样一个概念:如果一个轨迹是正常的,那么它应该在空间和时间上有相近的点。换句话说,这些轨迹需要表现得非常相似和一致,才能被归类为特定窗口中的内层。

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

Example Trajectories | Tr4 is an outlier

为了解释算法,让我们看一下上面的例子。我们将分析轨迹 Tr3 和 Tr4。虚线圆表示轨迹的相邻点。让我们取 thr=2K=3:

Tr4 至少具有 thr (2) 个仅与 Tr1 (t2,t4) & Tr3 (t2,T4)相邻的点。因为它只有少于 K 轨迹的 thr 点邻居(在这种情况下只有 2 个轨迹),所以它是异常值。

Tr3 与 Tr1 (t1,T2,t3,t4),Tr2 (t1,T2,t3) & Tr4 (t2,T4)至少有 thr (2) 个数的点邻居。由于它对于至少 K=3 轨迹(Tr1,Tr2,Tr4)具有 thr 点邻居,所以它是而不是异常值。更多信息,你可以阅读论文中的例子。

实施

加载数据

第一步包括加载数据集(*。txt)。因为数据集分为。txt 文件,我们需要读取 T-Drive 文件夹中的所有文件。

path = 'C:\\Users\\User\\Downloads\\T-drive Taxi Trajectories\\release\\taxi_log_2008_by_id\\*.txt'
files = glob.glob(path)for file in files: f = open(file,'r') #2nd element contains date(yyyy-mm-dd)            
            date = x[0].split(',')            #1st element contains time(HH:MM::SS) 
            time1 = x[1].split(',') lat = time1[1]  #Latitude
            lon = time1[2]  #Longitude

            day = date[1].split('-')[2]      #Day
            hour = time1[0].split(':')[0]    #HOUR
            min_ = time1[0].split(':')[1]    #MINS
            secs = time1[0].split(':')[2]    #SECS

我们还需要提取时间戳(月、日、小时、分钟)、纬度和经度的值。 Split() 是拆分每行中各个值的最快方法

数据准备

与任何数据任务一样,下一步是清理数据。快速浏览数据集可以发现数据集中出租车的采样速率不一致。一些出租车每分钟记录一次位置,而另一些则跳过几分钟。为了解决这个问题,我们将使用线性插值来填充缺失的值。下面的示例显示了时间戳(T 2 )的一个缺失值。缺失值的计算方法是,取 T1 和 T3 之间的平均差值,并将其加到 T1 上。

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

距离功能

如你所知,每个样本的位置标记都是地理坐标。但是,我们需要也需要计算两个坐标之间的距离来检查这些点是否是邻居( d 阈值)。为了解决这个问题,我们使用哈弗辛近似

def distance(lat1, lon1, lat2, lon2):R = 6373.0   #Radius of earth lat1 = radians(lat1)
    lon1 = radians(lon1)
    lat2 = radians(lat2)
    lon2 = radians(lon2) dlon = lon2 - lon1
    dlat = lat2 - lat1 a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a)) distance = R * c

    return distance*1000

异常值检测

看一下算法,很明显算法中最慢的部分是搜索查询。为了实现优化的性能,我们将使用 KD-tree 来处理多维点(在我们的例子中是 lat/long)。我们可以使用 Scipy 库来构建带有地理坐标的 kd 树。

from scipy import spatial
tree = spatial.KDTree(geocoordinates)def tree_once(tree,traj_arr): final = [] for i in range(0,len(traj_arr)):
    neighbors = tree.query_ball_point([traj_arr[i][0],traj_arr[i]    [1]], 0.0001)
    final.append(neighbors) return final

树构建完成后,我们将使用***query _ ball _ point()***函数来查找我们的 d 阈值内的邻居。

输出

T-Drive 数据集没有为我们提供基本的真实值。将结果可视化的一种方法是在谷歌地图上绘制出来。我使用了谷歌地图 API Web 服务的 Python 客户端库来绘制轨迹,如下所示。

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

Trajectory Outliers in a single window. The red lines represent trajectories that were identified as outliers where as blue lines represent normal trajectories. Most of the isolated trajectories, as shown, are correctly identified as outlying.

从图中可以看出,大多数拥塞轨迹都被正确识别为内点。时空不接近的轨迹被识别为异常值,存在一些误差,如地图所示。

结论&未来工作

该算法还可以用于其他场景,如信用卡欺诈检测或股票监控。例如,就像地理坐标一样,我们可以使用股价/成交量作为特征来确定一支股票的表现是好是坏。

其他工作包括使用分割和分区来改善离群点检测结果。在另一篇文章中,我将介绍如何使用多个内核在多个 CPU 之间分配工作负载,以实现更高的性能。

你可以在我的 Git:https://github . com/UsmanGohar/Trajectory-Outlier-Detection中找到完整的代码

抓住一个骗子:对信用卡违约者进行分类

原文:https://towardsdatascience.com/catching-a-welcher-classifying-a-credit-card-defaulter-f4b21547a618?source=collection_archive---------19-----------------------

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

Photo Credits

在我们开始之前,一如既往,我的项目代码可以在我的 github 上找到,如果你有任何关于这个项目的问题,请随时通过 linkedin 与我联系。

介绍

信用卡违约意味着什么(从信用卡用户的角度)

如果你不清楚拖欠信用卡是什么意思,要点如下:在你 180 天(或由你的信用卡公司决定)没有支付信用卡款项后,你的发卡机构认为你可能永远不会还款。此时,发卡行可以(通常会)关闭你的卡,将你的欠款作为坏账注销,并将你的账户出售给收款机构。

为什么重要?

现在你的信用卡发行人出局了。你的债务属于一个讨债人,你将开始接到大量要求你付账的电话。尽管你可以发出书面通知,要求他们停止给你打电话,而且 T4 法律限制讨债人联系你时的言行,但你仍然欠着债。如果你不处理好这件事,你可能会被起诉。

此外,违约将被报告给三大信用局(或更多,取决于你的国家)。你的信用评分会急剧下降,这个污点会留在你的信用报告上长达七年。

简而言之,拖欠信用卡账单会带来严重后果。你应该优先考虑尽快处理这件事。

从银行的角度来看,这意味着什么?

嗯,如果有人向你借钱,却从来不还你,这是一种类比(我把它看得过于简单了,但你明白)。你将会少 100 美元,而另一个人会多 100 美元(我真的需要在类比上多下功夫)。

因此,如果出现违约,银行的不良贷款会导致巨大的财务损失,因此需要在这个问题上采取重大的风险缓解措施。此外,银行贷款过程可能是一个相当手工和令人厌倦的任务,以确定谁可能是潜在的违约者。贷款过程也相当依赖于贷款处理者本身,留下了很多主观性,这可能在未来变成不良贷款。

但另一方面,银行也可以从真正还贷的人身上赚很多钱。此外,我们不希望拒绝那些真正可以用这笔钱让生活重回正轨或实现梦想的人(例如,创办他们一直想要的企业)。

那么,我们如何正确评估一个人是否会有信用风险呢?

一个人的行为有哪些迹象表明他/她是一个一贯的骗子?(是的,我知道我在引用城市词典)

项目目标

因此,该项目旨在利用数据驱动的方法,通过使用 的信用卡客户过去的数据,结合机器学习 ,来预测消费者是否会拖欠他们的信用卡,从而弥合这种不确定性的差距。

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

使用该模型的目的是实现两件事:

  • 提高贷款流程的一致性;
  • 调查潜在违约者背后的关键驱动因素

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

除了回答这些紧迫的问题,我个人也想关注学习过程;让数据科学项目工作流程变得更好/更高效,并进入我不熟悉的领域(因为我是机械工程出身,所以不太适应),走出我的舒适区。话虽如此,让我们深入研究如何着手一个分类器数据科学项目。

第一部分:数据

第 1.1 节:数据集描述

本分析中考虑的数据集是在 Creative Commons 的公共许可证下发布的*“信用卡客户违约”*数据集,可在 Kaggle 网站上获得。

该数据集包含来自一家银行(以及台湾的一家现金和信用卡发行商)的 25 个变量的 30000 个观察值。其中每个观察对应于一个特定的信用卡客户。在总共 30000 条观察中,6636 条观察(22.1%)是有违约付款的持卡人。

该数据集中的 25 个变量包括人口统计变量(性别、教育水平、婚姻状况和年龄)和从 2005 年 4 月到 2005 年 9 月的 6 个月付款数据的财务变量(给定信贷金额、每月还款状态、每月账单金额和每月先前付款金额)。下一节将详细说明每个变量的含义。

第 1.2 节:理解变量

ID :每个客户端的 ID

LIMIT_BAL :以新台币为单位的给定额度(包括个人和家庭/补充额度

性别:性别(1 =男性,2 =女性)

学历:(1 =研究生院,2 =大学,3 =高中,4 =其他,5 =未知,6 =未知)

婚姻:婚姻状况(1 =已婚,2 =单身,3 =其他)

年龄:以年为单位的年龄

— —

PAY _ 0:2005 年 9 月还款情况(-1 =按时还款,1 =延迟一个月还款,2 =延迟两个月还款,…8 =延迟八个月还款,9 =延迟九个月及以上还款)

PAY _ 2:2005 年 8 月还款情况(规模同上)

…;

PAY _ 6:2005 年 4 月还款情况(规模同上)

— —

BILL _ am t1:2005 年 9 月账单金额(新台币)

BILL _ am T2:2005 年 8 月账单金额(新台币)

…;

BILL _ AMT 6:2005 年 4 月账单金额(新台币)

— —

PAY_AMT1 :上次 2005 年 9 月付款金额(新台币)

PAY_AMT2 :上次 2005 年 8 月付款金额(新台币)

…;

PAY_AMT6 :上次 2005 年 4 月付款金额(新台币)

Default . payment . next . month:默认付款(1 =是,0 =否)

第 1.3 节:数据清理

有些专栏对我来说没有意义,所以我决定用更容易理解的术语重新命名它们。

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

我们还可以看到,这些列不包含空值——干净的数据框架总是非常受欢迎。

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

虽然在非空的邻域中一切都很好,但是在其他区域中事情就不那么顺利了(从来不会这样——这只是数据清理中的一个事实)。

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

我们从一个简单的df.describe().T中看出两件事很突出:教育和婚姻。

教育

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

结婚

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

根据数据集的,这些与变量分解不一致,因此我决定将奇怪的条目分组为“ others ”。

汇总数据预处理

这里是我们做的预处理操作的快速回顾。

  1. deault.payment.next.monthDEFAULT
  2. SEXGENDER
  3. PAY_0PAY_1
  4. 将未知的EDUCATION类别(0,5,6)分组并重新分配给 4(其他)
  5. 对未知的MARRIAGE类别(0)进行分组,并将它们重新分配给 3(其他)

第 2 部分:数据探索

第 2.1 节:映射目标

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

Pretty skewed data if you ask me

在进一步检查我们的数据集后,我们可以看到存在一些类别不平衡,在评估我们的模型的有效性时,我们必须记住这一点(即,我们不能使用准确性来衡量我们的模型的有效性)。此外,不平衡的类也会影响训练模型的性能。然而,有几种方法可以解决阶级不平衡的问题:

  1. 对数据集进行过采样
  2. SMOTE 数据集
  3. 对数据集欠采样
  4. 什么都不做(是的,你没听错。什么都不做。有时,它会给你比摆弄数据集更好的结果)

第 3 节:方法

第 3.1 节:使用的普通(未接触的)数据集和模型

既然我们已经准备好了数据集并最终确定了要素,我们就可以进行一些训练/交叉验证,以获得我们的模型如何处理数据的基本感觉。

我选择使用的型号有:

  1. 高斯朴素贝叶斯
  2. 逻辑回归
  3. k-最近邻
  4. 决策图表
  5. 随机森林
  6. 线性 SVC

第 3.2 节:模型评估指标

正如我们上面提到的, 准确性 不是一个准确的(双关语)度量标准,不能用来评估每个模型之间的表现。将使用 F1 分数来代替。

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

我选择根据 F1 分数来评估这些模型,因为它同时考虑了精确度和召回率。本质上,我们可以将 F1 分数作为精确度和召回率的调和平均值。

通俗地说, 罢免 ,在信用违约者的情况下是指:

在所有的缺省者(真阳性和假阴性)中,我们的模型实际上正确了多少?

精密 是指:

我们的模型基于它自己的预测(真阳性和假阳性)有多正确?

另外,在对违约者进行分类时,更重要,因为我们希望能够抓住尽可能多的潜在违约者,以免给银行带来损失。这将在下面的章节中更加清楚。**

第 3.3 节:初步模型测试—使用普通数据集获得基线性能

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

从我们在普通数据集上测试我们的模型得到的初步结果(没有对特征进行转换或缩放),我们可以看到 F1 分数非常低。

现在我们有了一个基线,我们可以继续努力提高 F1 的分数。

第 3.3 节:使用 F1 分数选择模型

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

Model train/5-fold cross-validation on various processing done on dataset

5 个模型中的每一个都在数据集的不同变化上进行训练;缩放和未缩放过采样、欠采样、SMOTE 和 vanilla 数据集。如前所述,有几种方法可以处理不平衡的数据集。在这个项目中应用了过采样、欠映射和 SMOTE。

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

Scaled Vanilla Dataset

**在完成所有训练/cv 测试后,给我们最高 F1 分数的数据集是缩放的香草数据集,高斯朴素贝叶斯在 **0.518 处领先。然而,这些模型都是根据它们的默认设置进行训练的。因此,我选择进一步超参数调整领先的两个最高 F1 得分模型( k-NN0.417RandomForest0.41 ),以获得比 0.518 更高的 F1 得分。

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

尽管对 k-NN 和 RandomForest 进行了超参数调整,但它们各自给出的 F1 分数仍低于高斯朴素贝叶斯的 0.51。因此,选择高斯朴素贝叶斯作为模型对违约者进行分类。

第 3.4 节:优化高斯朴素贝叶斯信用卡违约分类

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

Train/CV Split: Gaussian Naive Bayes Confusion Matrix (Threshold = 0.5)on scaled dataset

在绘制默认阈值为 0.5 的高斯朴素贝叶斯的混淆矩阵时(F1 值为 0.517),我们观察到它给出了非常差的召回分数。上面的矩阵告诉我们,该模型只抓住了所有违约者的 56%(1019 人中的 570 人)。也就是说 遗漏了 所有 的 44%。这对我们假设的银行来说绝对不是好消息(非常类似于信用卡欺诈),因为我们让许多不归还贷款的信用卡违约者未被发现。因此,需要进一步优化阈值来提高模型的召回率。

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

Train/CV Split: Gaussian Naive Bayes Confusion Matrix (Threshold = 0.25)on scaled dataset

在执行一些优化后,发现阈值为 0.25 给出了更好的****0.76(1019 中的 778)的召回分数,代价是精度降低(我们看到假阳性增加到 1847)。****

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

More false positives with threshold = 0.25

然而,我们必须明白这是一个不可避免的权衡。同一模型的较高召回率将导致较低的精确度(较高的误报),因为我们本质上只是调整了阈值,而没有改变模型本身。**

更高的假阳性意味着什么?

更高的假阳性意味着模型将更多的人归类为违约者,尽管他们不是实际违约者。从我们假设的银行的角度来看,这意味着我们将通过给人们贴上潜在的不归还贷款者的标签来给他们带来不便。

这里的关键考虑是——这种权衡是否合理?我们如何证明这是一个好的权衡?这实际上取决于您构建这个模型的业务目标,以及期望的精确度。

由于我们没有实际的企业倡导分数,我们将为自己决定一个假设的情况——我们希望比精确更能规避风险。因此,用更高的召回率来抓住更多的违约者超过了给更多人带来不便的成本(更低的精确度)。

第 4 部分:最终模型测试和结果解释

现在有了我们最终确定的排列,使用一个高斯朴素贝叶斯模型,在缩放数据集上使用一个阈值为 0.25 ,我们准备好通过在 80%的原始数据上训练我们的模型(我们对其进行了训练/交叉验证)并在另外 20%看不见的维持数据上进行测试来进行最终测试。

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

最终测试表明,我们的模型实际上在看不见的数据上表现得更好——给了我们更高的 召回 分数0.79**(1341 分中的 1058 分)。这意味着我们的模型能够准确地捕捉到大约 80% 的所有违约者。**

第 5 节:未来的工作

这个项目在两个星期内完成,每天从早上 8 点到下午 5 点上课。因此,当然,我们可以做更多的事情来改进我们的模型和对这个信用卡违约案例的分析。

如果有更多的时间和资源,我想做以下几方面的工作:

  • 特征工程;给定当前数据集,提出新的特征,这些特征可能是信用卡违约者的更好预测器
  • 超参数调整其他模型

第 6 部分:来自数据集的有趣见解

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

Feature Importance as plotted by Random Forest

从这张图表中,我们可以得出一些隐藏在违约者行为背后的有趣见解。告诉司机某人是否违约的三大因素可归结为:

  • 仅一个月内的还款状况( 这意味着只要看看某人在一个月内的还款有多晚,我们就可以知道他们是否会违约)
  • 年龄
  • 极限平衡

最后一部分:经验教训

特征操作

在这种情况下,像PAY_0、…、PAY_6MARRIAGEEDUCATION这样的分类列可能没有以最佳方式表示数据集。一个更好的方法可能是进行一次性编码(创建虚拟变量)。像 RandomForests 这样的分类器在分离像这样的列方面很棒,并且可以产生一个模型,该模型可以更好地预测信用卡违约者。

离别赠言

和往常一样,你可以在这里找到这个项目的代码,在这里找到我的 linkedin 。如果你对这个项目有任何问题,请随时给我留言。下次见!

范畴嵌入与迁移学习

原文:https://towardsdatascience.com/categorical-embedding-and-transfer-learning-dd3c4af6345d?source=collection_archive---------2-----------------------

深度学习的副产品比你想象的更有用。

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

Transferring the embedding matrix!

介绍

许多机器学习算法不能直接处理分类变量,除非它们被转换成数字。然而,问题是它们的性能会因这些分类变量编码成数字的方式而有很大差异。本文探讨了分类编码的问题,并简要介绍了新旧方法。

分类变量

一个 分类变量 是一个变量,它可以取一个可能的固定且大部分有限的值集合。它们与定性特征相关,因此无法测量。例如,星期几是一个分类变量,可以接受 7 个离散值。任何语言的单词/标记都是范畴变量。机器学习算法致力于处理数字,因此我们必须将这些分类变量转换为数字,以取悦算法。这个过程充满了陷阱,我们冒着丢失大量信息的风险。

让我们来看看将类别转换成数字的几种常见方法,以及与之相关的问题。

标签编码

在这个过程中,我们使用一些已定义的过程为每个唯一的类别分配一个离散的数字。例如,我们可以按照出现的次数对变量进行排序,并按照升序对它们进行编号。另一种方法是为每个独特的类别随机分配一个数字。

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

Simple Label Encoder

在上面的示例中,日期按照它们在数据中出现的顺序进行标记。这里的主要问题是

  1. 自然排序丢失了
  2. 类别之间的常见关系未被捕获。(例如,星期六和星期天一起构成周末,因此应该彼此更接近)

一个热/虚拟编码

在这个方案中,我们将分类变量分成单独的二进制变量(每个唯一的类别有一个变量),这样,当示例属于特定的类别时,每个新变量都被设置为 1,否则设置为 0。下面的例子将使事情变得清楚。

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

One Hot Encoding

这里的主要问题类似于标签编码。自然秩序丧失了,每个独特类别之间的关系也丧失了。

失去自然顺序的问题是,算法(线性模型)试图通过假设每个变量的顺序来进行归纳,而基于树的算法必须进行多次分裂才能克服错误的顺序。

嵌入向量

嵌入是分类变量的向量表示。例如,我们可以用 4 个浮点数来表示一周中的每一天。

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

在这里,星期一和星期二彼此非常相似,但都与星期日非常不同。这是一个玩具示例,但是我们在实践中得到类似的嵌入,它捕获了丰富的信息和类别之间的关系。

学习嵌入矩阵

嵌入矩阵是浮点数的 NxM 矩阵。这里 N 是唯一类别的数量 M 是嵌入维度。我们决定选择 M 的值,这里我通常设置 M 的值等于 N 的平方根 开始,然后根据需要增加或减少它。实际上,嵌入矩阵是向量的查找表。嵌入矩阵的每一行都是唯一类别的向量。

为了学习嵌入,我们创建一个任务,使用这些嵌入作为特征,并与其他特征交互,以学习一组示例。让我用开启嵌入时代的例子来解释这一点;词向量

单词向量是语言中每个单词的嵌入向量。单词向量的整体思想是,在一个句子中出现的更近的单词通常彼此更近。嵌入是 n 维向量 。每个维度捕捉每个单词的某些属性/特性,所以特性越接近,单词就越接近。为了学习单词向量,我们创建一组出现在一个小单词窗口(比如 5 个单词)内的单词对作为正例,并创建一组不出现在该窗口内的单词对作为负例。

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

Word2Vec Negative Sampling Architecture

当我们在足够大的数据集上训练上述神经网络时,模型会学习预测两个词是否相关。然而,这个模型的副产品是嵌入矩阵,它是词汇表中每个单词的信息丰富的向量表示。

范畴嵌入

上面的部分是一个引子,说明如果我们定义一个有意义的任务,神经网络可以学习分类变量的有意义的向量表示。然而,上面的例子并没有处理通常的分类数据集,所以让我们看一些表格数据。

Draup ,我们分析各种组织的职位描述(JD)。每个 JD 都有以下字段:-

  • 位置(大约 1000 个唯一值)
  • 工作角色(超过 600 个唯一值)
  • 公司(超过 4400 个唯一值)
  • 技能(大约 15000 个唯一值)

每个 JD 被标记为内部定义的 18 个业务功能之一。数据集类似于下表。

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

A snippet of the tabular data.

在上面的数据集中,所有列都有分类值,每个分类值都有许多唯一值。为了构建分类嵌入,我们需要两件事情

  1. 解决有意义任务的深度学习模型。
  2. 在上述任务中使用嵌入矩阵来表示分类变量。

我们建立了一个深度学习模型,使用其他 4 个变量(技能、位置、公司、工作角色)来预测 JD 的业务功能。

下图显示了为业务功能预测任务构建的模型。

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

Model to predict the Business Function of a JD.

我们在数百万个 JDs 上训练了上述模型,准确率达到 85%以上。然而,从模型中榨取最大的准确性并不是这个模型的意图(更不用说这个模型本身是非常有用的)。我们对这个模型的副产品更感兴趣。所有分类输入变量的嵌入。下图显示了模型使用 t-SNE 学习的工作角色嵌入。

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

Clusters formed by tSNE

为什么它会起作用?

我喜欢把这个过程想象成变量之间的相互信息交换。下面,我用一小部分数据进行讨论。

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

A subset of our Data

  1. 在第一个示例中,模型了解到脸书和机器学习工程师与 AI 相关联,而脸书和机器学习工程师是有关系的。
  2. 现在它了解到谷歌和数据科学家是有关联的,两者都与人工智能有关。正因如此,它试图将谷歌和脸书的嵌入彼此拉近。类似地,机器学习工程师和数据科学家的嵌入被拉近了。
  3. 接下来的几个例子再次证实了模型对公司和工作角色的了解。
  4. 现在它遇到了这样一个事实,脸书也与 NLP 工程师有关,两者都与人工智能有关。因此,该模型试图使 NLP 工程师更接近数据科学家和机器学习工程师。

上面的例子过于简单,只是为了带来一些直觉,因此应该有所保留。

迁移学习

迁移学习是一种技术,其中从一个任务/模型中收集的知识被用于类似性质的另一个任务。

迁移学习最明显的使用案例是当我们想要模拟任务 A,但是有一个小的数据集,然而我们有一个类似任务 b 的大数据集。

我们在拥有大量数据的情况下为任务建立模型,然后重用模型权重(在嵌入的情况下)或模型的子集(通常在计算机视觉问题和最近的 NLP 中看到)。

Draup 是一个人力资源技术平台。平台的部分显示了按不同工作角色划分的人口统计信息。

这项任务是预测每个特定地点从事某项工作的人数。

工作角色—地点 组合总计约 30 万个。然而,训练样本的数量在 10,000 左右。我们构建了深度学习模型, 重用了在业务功能 预测任务中学习到的嵌入。除了嵌入,我们还使用了一些其他的数字特征来训练模型。

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

Regression Model

该模型在转移嵌入方面表现得令人难以置信的好,并且获得了超过 0.9r2 得分

摘要

我们讨论了机器学习模型对数字变量驾轻就熟,但对分类变量却束手无策。处理分类变量的传统技术是可行的,但是限制了算法的能力。然而,在正确的情况下,我们可以使用从其他任务中学习到的分类嵌入或学习全新的嵌入来提高模型性能。类别嵌入通常表现得相当好,因为它们在自身之间有相似和相异的感觉,从而帮助模型更好地概括。

参考

使用标签编码和一次性编码器的分类编码

原文:https://towardsdatascience.com/categorical-encoding-using-label-encoding-and-one-hot-encoder-911ef77fb5bd?source=collection_archive---------0-----------------------

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

Photo by Patrick Fore on Unsplash

在许多机器学习或数据科学活动中,数据集可能包含文本或分类值(基本上是非数值)。例如,具有像红色、橙色、蓝色、白色等值的颜色特征。膳食计划包括早餐、午餐、小吃、晚餐、茶等。很少有算法(如 cat saw、决策树)能够很好地处理分类值,但大多数算法都希望数值能够达到最先进的结果。

在你学习人工智能和机器学习的过程中,有一点你会注意到,大多数算法在处理数字输入时效果更好。因此,分析师面临的主要挑战是将文本/分类数据转换为数字数据,并仍然制定算法/模型来理解这些数据。神经网络是深度学习的基础,它期望输入值是数字。

有许多方法可以将分类值转换成数值。每种方法都有自己的权衡和对特性集的影响。在此,我将重点介绍两种主要方法:一热编码和标签编码。这两个编码器都是 SciKit-learn 库(使用最广泛的 Python 库之一)的一部分,用于将文本或分类数据转换为模型期望的数值数据,并且可以更好地执行。

本文中的代码片段将是 Python 的,因为我更熟悉 Python。如果你需要 R(另一种广泛使用的机器学习语言),那么在评论中说出来。

标签编码

这种方法非常简单,它包括将一列中的每个值转换成一个数字。考虑一个桥梁数据集,该数据集具有一个名为 bridge-types 的列,该列具有以下值。尽管数据集中会有更多的列,但为了理解标签编码,我们将只关注一个分类列。

**BRIDGE-TYPE** Arch
Beam
Truss
Cantilever
Tied Arch
Suspension
Cable

我们选择通过为每个文本值放置一个运行序列来对文本值进行编码,如下所示:

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

这样,我们完成了可变桥类型的标签编码。这就是标签编码的全部内容。但是根据数据值和数据类型,标签编码引入了新的问题,因为它使用了数字排序。使用数字的问题在于它们引入了它们之间的联系/比较。显然,各种桥型之间没有关系,但当看数字时,人们可能会认为“缆索”桥型比“拱形”桥型优先。该算法可能会误解数据具有某种等级/顺序 0 < 1 < 2 … < 6,并可能在计算中给予“电缆”比“拱形”桥类型多 6 倍的权重。

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

让我们考虑另一个名为“安全级别”的列。对该列执行标签编码还会导致数字中的顺序/优先级,但方式是正确的。在这里,数字顺序看起来不是现成的,如果算法将安全顺序解释为 0 < 1 < 2 < 3 < 4,即无

Python 中的标签编码

使用类别代码方式:

这种方法要求 category 列的数据类型为“category”。默认情况下,非数字列属于“对象”类型。因此,在使用这种方法之前,您可能必须将类型更改为“category”。

# import required libraries
import pandas as pd
import numpy as np# creating initial dataframe
bridge_types = ('Arch','Beam','Truss','Cantilever','Tied Arch','Suspension','Cable')
bridge_df = pd.DataFrame(bridge_types, columns=['Bridge_Types'])# converting type of columns to 'category'
bridge_df['Bridge_Types'] = bridge_df['Bridge_Types'].astype('category')# Assigning numerical values and storing in another column
bridge_df['Bridge_Types_Cat'] = bridge_df['Bridge_Types'].cat.codes
bridge_df

利用 sci-kit 学习文库的方法:

许多数据分析师执行标签编码另一种常见方法是使用 SciKit 学习库。

import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder# creating initial dataframe
bridge_types = ('Arch','Beam','Truss','Cantilever','Tied Arch','Suspension','Cable')
bridge_df = pd.DataFrame(bridge_types, columns=['Bridge_Types'])# creating instance of labelencoder
labelencoder = LabelEncoder()# Assigning numerical values and storing in another column
bridge_df['Bridge_Types_Cat'] = labelencoder.fit_transform(bridge_df['Bridge_Types'])
bridge_df

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

bridge_df with categorical caolumn and label-encoded column values

一键编码器

虽然标签编码是直截了当的,但它的缺点是数值可能被算法误解为具有某种层次/顺序。这种排序问题在另一种称为“一键编码”的常见替代方法中得到解决。在这个策略中,每个类别值都被转换成一个新列,并为该列分配一个 1 或 0(表示真/假)值。让我们考虑一下之前的例子,使用一键编码的网桥类型和安全级别。

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

以上是分类列“桥型”的一键编码值。同样,让我们检查“安全级别”列。

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

具有第一列值(Arch/None)的行将具有‘1’(表示真),而其他值的列将具有‘0’(表示假)。类似地,对于值与列值匹配的其他行。

虽然这种方法消除了层次/顺序问题,但也有向数据集添加更多列的缺点。如果在一个类别列中有许多唯一值,这可能会导致列数大幅增加。在上面的例子中,这是可以管理的,但是当编码给出许多列时,管理起来将变得非常困难。

Python 中的一键编码

使用 sci-kit 学习库方法:

SciKit 库中的 OneHotEncoder 只接受数字分类值,因此任何字符串类型的值都应该在 hot 编码之前进行标签编码。因此,以前面示例中的数据帧为例,我们将对 Bridge_Types_Cat 列应用 OneHotEncoder。

import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder# creating instance of one-hot-encoder
enc = OneHotEncoder(handle_unknown='ignore')# passing bridge-types-cat column (label encoded values of bridge_types)
enc_df = pd.DataFrame(enc.fit_transform(bridge_df[['Bridge_Types_Cat']]).toarray())# merge with main df bridge_df on key values
bridge_df = bridge_df.join(enc_df)
bridge_df

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

Bridge_Type column encoded using SciKit OneHotEncoder

可以从数据框架中删除列“Bridge_Types_Cat”。

使用虚拟值方法:

这种方法更加灵活,因为它允许对任意多的类别列进行编码,并选择如何使用前缀来标记列。正确的命名会使剩下的分析变得简单一点。

import pandas as pd
import numpy as np# creating initial dataframe
bridge_types = ('Arch','Beam','Truss','Cantilever','Tied Arch','Suspension','Cable')
bridge_df = pd.DataFrame(bridge_types, columns=['Bridge_Types'])# generate binary values using get_dummies
dum_df = pd.get_dummies(bridge_df, columns=["Bridge_Types"], prefix=["Type_is"] )# merge with main df bridge_df on key values
bridge_df = bridge_df.join(dum_df)
bridge_df

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

Bridge_Type values encoded using dummies approach

结论

理解对分类变量进行编码各种选择是很重要的,因为每种方法都有自己的优缺点。在数据科学中,这是重要的一步,所以我真的鼓励你在处理分类变量时记住这些想法。对于本文中使用的代码的任何建议或更多细节,请随时发表评论。

对万维网进行分类

原文:https://towardsdatascience.com/categorizing-world-wide-web-c130abd9b717?source=collection_archive---------21-----------------------

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

互联网是世界上最大的图书馆。只是所有的书都在地板上。

约翰·艾伦·保罗斯

让我们扫扫地,试着把这些书堆在书架上。

通用爬网数据集

与其对开放的 web 进行爬网,不如使用现有的通用爬网数据集,这是一个对 29.5 亿个网页进行爬网的归档,总内容为 260。当然,它不是 web 的完整代表,但它给了我们一个很好的开始。

要对如此庞大的语料库进行分析和分类,我们需要强大的计算能力。因此,我们将在 Amazon Elastic MapReduce (EMR)上使用数百台运行 Apache Spark 的机器。好消息是,作为亚马逊公共数据集计划的一部分,通用抓取数据集已经存在于亚马逊 S3 上,因此我们应该能够有效地访问它。

从网页中提取文本

普通抓取 WARC 文件包含抓取的原始数据,包括它所接触的网站的 HTTP 响应。如果我们看一个这样的 HTML 文档

<!DOCTYPE html>
<html lang=”en-US”>
<head>
<meta charset=”UTF-8">
<meta name=”viewport” content=”width=device-width, initial-scale=1">
<link rel=”profile” href=”http://gmpg.org/xfn/11">
...
<div class=”cover”>
<img src=”https://images-eu.ssl-images-amazon.com/images/I/51Mp9K1v9IL.jpg" /></p>
</div>
<div>
<div id=”desc-B00UVA0J6E” class=”description”>
<p>By Richard S. Smith,Simon W. M. John,Patsy M. Nishina,John P. Sundberg</p>
<p>ISBN-10: 084930864X</p>
<p>ISBN-13: 9780849308642</p>
<div> finishing touch of the 1st section of the Human Genome venture has awarded scientists with a mountain of recent info.
...
<footer id=”colophon” class=”site-footer” role=”contentinfo”>
<div class=”site-info”>
...
</body>
</html>

如您所见,HTML 文档是非常复杂的代码,通常有多种格式。我们将使用 python 库——漂亮的汤——从这些文档中提取文本。

**def** get_text(html_content):
    soup = BeautifulSoup(html_content, **"lxml"**)

    *# strip all script and style elements* **for** script **in** soup([**"script"**, **"style"**]):
        script.decompose()

    **return** soup.get_text(**" "**, strip=**True**)

我们通过传递原始 HTML 内容创建了 BeautifulSoup 对象。它包含嵌套结构中的所有数据。所有文本数据都可以通过调用该对象上的 get_text 以编程方式提取。然而,除了文本之外,它还提取我们可能不需要的 javascript 和 CSS 代码,所以在提取之前,我们会删除它们。这应该会给我们想要的,只是文本—

Download e-book for iPad: Systematic Evaluation of the Mouse Eye: Anatomy, Pathology, by Richard S. Smith,Simon W. M. John,Patsy M. Nishina,John P. - Gdynia Design E-books...finishing touch of the 1st section of the Human Genome venture has awarded scientists with a mountain of recent info. the supply of all human genes and their destinations is fascinating, yet their mechanisms of motion and interplay with different genes ...the booklet then studies and illustrates nearby ocular pathology and correlates it with human eye disease.

分类

为了对这些文本进行分类,我们将使用 scikit-learn——一个用于机器学习的 python 库。我们将用 20 个新闻组数据集训练我们的分类器。它是大约 20,000 个新闻组文档的集合,平均分布在 20 个不同的新闻组中。我们将把这些新闻组分为以下八类。

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

**class** Classifier:

    *# train the model
* **def** __init__(self):
        newsgroups_train = fetch_20newsgroups(subset=**'train'**, remove = (**'headers'**, **'footers'**, **'quotes'**))
        self.target_names = newsgroups_train.target_names
        self.vectorizer = TfidfVectorizer(sublinear_tf=**True**, max_df=0.5, stop_words=**'english'**)
        vectors = self.vectorizer.fit_transform(newsgroups_train.data)
        self.clf = LinearSVC(penalty=**'l2'**, dual=**False**, tol=1e-3)
        self.clf.fit(vectors, newsgroups_train.target)

    **def** predict(self, document):
        x_test = self.vectorizer.transform([document])
        pred = self.clf.predict(x_test)
        **return** self.target_names[pred[0]]

fetch_20newsgroups 函数从原来的 20newsgroups 网站下载数据存档。我们正在对它进行配置,以分别删除标题、签名块和引用块,这与主题分类没有什么关系。我们将使用 TfidfVectorizer 将文本转换为数字值的向量,以便将它们提供给预测模型。现在,我们将使用线性支持向量分类(LinearSVC)来训练我们的模型,该模型在大型数据集上具有更好的扩展性。事实上,许多其他模型可以很容易地插入,如朴素贝叶斯、SGD 分类器、k-最近邻、决策树等。但是从经验上来说,我发现 SVM 在我们的案例中表现很好。现在,我们可以在模型上调用 predict 函数,将文档分类到八个类别之一。

分析预测

分类器似乎做得不错。这里有一些网页——

*Beautiful Kazak carpet of distinctive colours matches with the curtains add lively touch. ...**Carpet cleaning is something which can be done at home but you might damage your carpet instead of cleaning it. Often the colours of carpet run as soon as it comes in contact with water. ...**Carpet Repairing**If your carpet is torn or there is piece missing, AbeeRugs can help you fix that. We fix it in a way that we also complete the design no matter how intricate it is. ...*Classified as **E-Commerce**
--------------------------------*Make more time for the moments that matter. Get expertly-curated updates and medical education, instantly.**New to EasyWeb?**EasyWeb is a free service for United States Healthcare Professionals. ...**Specialty Anesthesiology: general Anesthesiology: adult cardiothoracic Anesthesiology: critical care Anesthesiology: pain Anesthesiology: pediatric Dermatology Emergency Medicine Family Medicine ...*Classified as **Medicines** --------------------------------*All Films & Events | Arab Film Festival 2014 ...**Watch Trailer Watch Trailer**A Stone’s Throw from Prison**Raquel Castells / Documentary / Palestine, Spain / 2013 / 65 mins**Growing up in the Occupied Palestinian Territory is not easy. When you leave home for school, your mother can't be sure of when you'll be back. Rami, Ahmed, Mohammed, three among thousands, this documentary is their story, but also that of courageous Israelis and Palestinians working to cut abuses, stop conflict ...*Classified as **Politics**

显然,通过分析更多的预测,可以注意到类别过于宽泛。

*Tanzania farmers adopts vegetable farming to improve nutrition**The farmers in Tanzania are encouraged to grow elite varieties of vegetables, enriched with high-value nutritional content, in order to fight malnutrition, hunger and double agricultural productivity and income of smallholders**The Africa RISING project focuses on the need to take urgent action in achieving Sustainable Development Goals (SDGs) which aim* ...Classified as **Medicines**

通过查看我们拥有的所有可能的类别,预测的类别似乎是正确的,但如果将其归类为农业会更好。此外,航空学更适合下面的例子。

*Schofields Flying Club - N1418V Flight Schedule**N1418V Flight Schedule**Cessna 172M**Perhaps the staple of general aviation flight training, and rightfully so. The 172 has been in production since 1956, with no end in sight! Our 172 is an ideal VFR training platform!! Because of its high wings, 18V provides a great view of the ground, ...*Classified as **Space**

有很多例子表明网页可以分为多个类别。例如,下面的示例也可以归类为电子商务。

*Recently Sold Vehicles**Here are some vehicles that we recently sold. It's just a sample of the variety and quality of our vehicle selection.**Please feel free to browse our Internet showroom and contact us to make an appointment if you would like to see any of our vehicles in person. ...*Classified as **Automobile**

也有相当多的样本,分类器似乎得到了错误的。

*... We all make mistakes. That is a dictum of life. It’s surprising how ignored it is and how discouraged one is to fail in the world. Then again current with this theme of artificial organizing is that the soul is now completely detached from the world it swims in. The title Greenberg centers around […]**To the dilettante the thing is the end, while to the professional as such it is the means; and only he who is directly interested in a thing, and occupies himself with it from love of it ...**Support Joseph A. Hazani on Patreon! ...*Misclassified as **Sports** --------------------------------... *Fast, Reliable Everytime**ABC Messenger Local Flower Hill NY Delivery Service**ABC Messenger & Transport, Inc. has the ability to offer rush and pre-scheduled Delivery Service at competitive prices and excellent Flower Hill NY service. Their Delivery Service is recognized as fast and dependable. Through highly experienced and skilled veteran Flower Hill NY dispatchers and seasoned couriers we are able to predict traffic patterns easily and avoid or overcome ...*Misclassified as **Medicines**

总之,它给出了我们可以依赖于我们的初始项目体面的预测。

语言检测

由于分类器是在英语数据集上训练的,我们将使用 langdetect 库来跳过非英语网页。

**from** langdetect **import** detectlang = detect(text)
**if** lang != **'en'**:
    *# skip non-English pages* **return**

亵渎过滤器

我们还将使用脏话过滤器来忽略成人内容。

**from** profanity_check **import** predict**if** predict([text])[0]:
    **# adult content**

亚马逊电子病历上的火花

如前所述,由于公共爬行数据集非常庞大,我们将在 Amazon EMR 上的 Spark 上运行我们的应用程序。我们将采用常见的抓取示例代码来处理 Spark 上的数据。

**class** WebClassifier(CCSparkJob):

    name = **"**WebClassifier**"
    def** __init__(self):
        CCSparkJob.__init__(self)
        self.output_schema = StructType([
            StructField(**"topic"**, StringType(), **True**),
            StructField(**"count"**, LongType(), **True**)
        ])
        self.classifier = Classifier() **def** process_record(self, record):
        *# html record* **if** self.is_html(record): 
            *# extract text from web page*
            text = self.get_text(record)
        **else**:
            **return** *# skip non-English pages**# filter profane content*

        topic = self.classifier.predict(text)
        **yield** topic, text

**if** __name__ == **'__main__'**:
    job = WebClassifier()
    job.run()

将对数据集中的每条记录调用 process_record 函数,我们将把它分类到前面列出的类别中。完整的源代码上传到这里

为了进一步加快速度,我们将使用湿文件代替 WARC,它包含提取的明文。此外,我们将加载预先训练的序列化分类器,以避免在每台机器上训练它。我使用了 100 个 ec2 实例,花了大约一个半小时来处理 1%的普通爬行语料库。它花了我大约 25 美元。这是我们得到的结果:

Web 类别

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

我们从大约 1%的普通抓取数据或大约 2560 万个网页开始。我们过滤了 140 万个网页,因为它们不包含足够的文本信息用于分类。后来我们跳过了大约 1320 万个非英文页面。我们能够对剩下的 1090 万页进行分类。显然,有大量的电子商务内容和大量的内容谈论计算机和电子,其次是政治,医药,宗教,汽车和空间。请注意,我们还过滤了大约 25 万个成人网页。

总之,我们做了一个温和的尝试来对网络的现状进行分类。我希望这也是进一步 web 分析的良好开端。

走秀:大规模服务机器学习模型

原文:https://towardsdatascience.com/catwalk-serving-machine-learning-models-at-scale-221d1100aa2b?source=collection_archive---------9-----------------------

本文首发于 2019 年 7 月 2 日 Grab 的工程博客 。它是与 Nutdanai Phansooksai,Juho Lee 和 Romain Basseville 合作编写的。

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

介绍

Grab 坚定不移的目标是成为东南亚最好的超级应用,为我们的客户增加日常价值。为了实现这一目标,每一次 Grab 服务的客户体验都必须完美无瑕。以我们经常使用的打车服务为例。我们希望为司机和乘客提供公平的价格、准确的 eta 估算、有效的欺诈行为检测,并确保客户的乘车安全。完善这些客户旅程的关键是人工智能(AI)。

Grab 拥有大量数据,我们可以利用这些数据来解决欺诈性用户活动等复杂问题,并为我们的客户提供个性化的产品体验。我们用来理解这些数据的工具之一是机器学习(ML)。

随着 Grab 在整个组织内越来越多地使用机器学习方面取得巨大进展,越来越多的团队正在为他们自己的用例有机地构建模型服务解决方案。不幸的是,这些模型服务解决方案需要数据科学家了解它们背后的基础设施。此外,在构建这些模型服务解决方案的工作中有很多重叠。

这就是为什么我们想出了 Catwalk:一个易于使用的,自助式的,机器学习模型服务平台,为 Grab 的每个人服务。

目标

为了确定我们希望 Catwalk 做什么,我们首先查看了我们的目标受众(Grab 的数据科学家)的典型工作流程:

  • 建立一个经过训练的模型来解决问题。
  • 将模型部署到他们项目的特定服务解决方案中。如果这涉及到写入数据库,那么数据科学家需要以编程方式获得输出,并将它们写入数据库。如果这涉及在服务器上运行模型,数据科学家需要深入了解服务器如何扩展和内部工作,以确保模型的行为符合预期。
  • 使用部署的模型为用户服务,获取用户交互数据等反馈。使用此数据重新训练模型,使其更加准确。
  • 将重新培训的模型部署为新版本。
  • 使用监控和日志记录来检查新版本的性能。如果新版本运行不正常,请恢复到旧版本,以便生产流量不受影响。否则,在新版本和旧版本之间运行 AB 测试。

我们发现了一个明显的痛点——部署模型的过程需要额外的努力和关注,这导致数据科学家无法专注于手头的问题。除此之外,让许多数据科学家构建和维护他们自己的服务解决方案意味着有许多重复的工作。随着 Grab 越来越多地采用机器学习,这种情况不能再继续下去了。

为了解决这些问题,我们设计了 Catwalk,目标是:

  1. 抽象出复杂性,并为数据科学家提供一个最小的接口
  2. 通过为 Grab 中的每个人创建一个 ML 模型服务平台来防止重复工作
  3. 创建一个高性能、高可用性、支持模型版本控制的 ML 模型服务平台,并将其与 Grab 现有的监控系统集成
  4. 通过自助式模型部署缩短上市时间

什么是走秀?

简而言之,Catwalk 是一个平台,我们在 Kubernetes 集群上运行 Tensorflow 服务容器,该集群集成了 Grab 上使用的 observability 堆栈。

在接下来的部分中,我们将解释 Catwalk 中的两个主要组件——tensor flow Serving 和 Kubernetes,以及它们如何帮助我们实现我们概述的目标。

Tensorflow 提供的是什么?

Tensorflow Serving 是 Google 的开源 ML 模型服务项目。用谷歌自己的话说,“Tensorflow Serving 是一个灵活的、高性能的机器学习模型服务系统,专为生产环境而设计。它使得部署新的算法和实验变得容易,同时保持相同的服务器架构和 API。Tensorflow 服务提供了与 Tensorflow 模型的现成集成,但可以轻松扩展以服务于其他类型的模型和数据。”

为什么 Tensorflow 服务?

现在市场上有许多 ML 模型服务平台。我们选择 Tensorflow 服务是因为这三个原因,按优先级排序:

  1. 高性能。据网站称,它已经证明了在谷歌每秒处理数千万次推理的性能。
  2. 高度可用。它有一个模型版本化系统,以确保在将新版本加载到内存中时,总是有一个健康的版本
  3. 由开发者社区积极维护并得到 Google 的支持

尽管默认情况下,Tensorflow 服务只支持用 Tensorflow 构建的模型,但这不是一个约束,因为 Grab 正在积极地向使用 Tensorflow 发展。

我们如何使用 Tensorflow 服务?

在本节中,我们将解释我们如何使用 Tensorflow 服务,以及它如何帮助数据科学家抽象出复杂性。

以下是展示我们如何使用 Tensorflow 服务于一个训练好的模型的步骤:

  1. 数据科学家使用 tf.saved_model API 导出模型,并将其放入 S3 模型桶。导出的模型是一个包含模型文件的文件夹,可以加载到 Tensorflow 服务器。
  2. 数据科学家被授予管理其文件夹的权限。
  3. 我们运行 Tensorflow 服务,并让它直接从 S3 模型桶中加载模型文件。Tensorflow 服务支持直接从 S3 开箱加载模型。模特服了!
  4. 数据科学家提出了一个重新训练的模型。他们导出并上传到他们的模型文件夹。
  5. 由于 Tensorflow 服务会持续监视新模型的 S3 模型桶,因此它会自动加载重新训练的模型并提供服务。根据模型配置的不同,它可以用更新的版本优雅地替换正在运行的模型版本,也可以同时服务于多个版本。

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

数据科学家的唯一界面是 S3 模型存储桶中模型文件夹的路径。为了更新他们的模型,他们将导出的模型上传到他们的文件夹中,模型将被自动提供。复杂性消失了。我们已经实现了其中一个目标!

嗯,不完全是…

假设您要运行 Tensorflow 来为云提供商的一个模型提供服务,这意味着您需要云提供商的计算资源来运行它。在一台机器上运行它不能提供高可用性,因此您需要另一台机器运行相同的模型。为了根据流量进行横向扩展,还需要自动扩展。在这些盒子的顶部有一个负载平衡器。负载平衡器将传入流量均匀地分布到所有机器,从而确保任何客户端都有一个入口点,可以从水平扩展中抽象出来。负载平衡器还向外部用户公开 HTTP 端点。因此,我们形成了一个 Tensorflow 服务集群,随时准备提供服务。

接下来,假设您有更多的模型要部署。你有三个选择

  1. 将模型加载到现有集群中,让一个集群服务于所有模型。
  2. 启动一个新的集群来为每个模型提供服务—有多个集群,一个集群为一个模型提供服务。
  3. 1 和 2 的组合—拥有多个集群,一个集群服务于几个型号。

第一个选项无法扩展,因为不可能将所有模型加载到一个集群中,因为集群的资源有限。

第二种选择肯定可行,但听起来不像是一个有效的过程,因为每次有新模型要部署时,您都需要创建一组资源。此外,您如何优化资源的使用,例如,您的集群中可能有未利用的资源,这些资源可能会被其他资源共享。

第三个选项看起来很有希望,您可以手动选择集群来部署每个新模型,以便所有集群的资源利用率都是最优的。问题是你必须手动管理它。使用 25 个集群管理 100 个模型可能是一项具有挑战性的任务。此外,在一个集群中运行多个模型也会导致问题,因为不同的模型通常具有不同的资源利用模式,并且会相互干扰。例如,一个型号可能会用完所有的 CPU,而另一个型号将无法再提供服务。

如果我们有一个根据资源利用模式自动编排模型部署并防止它们相互干扰的系统,不是更好吗?幸运的是,这正是 Kubernetes 想要做的!

那么什么是 Kubernetes 呢?

Kubernetes 将一个物理/虚拟主机集群(比如 EC2)抽象成一个逻辑主机集群(Kubernetes 术语中的 pod)。它提供了以容器为中心的管理环境。它代表用户工作负载协调计算、网络和存储基础架构。

让我们看看 Kubernetes 资源的一些定义

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

  • 集群—运行 Kubernetes 的节点集群。
  • 节点—群集中的节点。
  • 部署—指示 Kubernetes 应用程序所需状态的配置。它还负责推出更新(金丝雀、百分比展示等)、回滚和水平缩放。
  • Pod —单个处理单元。在我们的例子中,Tensorflow 服务将作为 pod 中的容器运行。Pod 可以定义 CPU/内存限制。
  • 服务——一个抽象层,它抽象出一组 pod,并将应用程序公开给客户端。
  • 入口—控制外部用户如何访问群集中运行的服务的路由规则集合。
  • 入口控制器—负责读取入口信息并相应处理该数据的控制器,例如创建云提供商负载平衡器或使用入口资源中定义的规则启动新的 pod 作为负载平衡器。

本质上,我们部署资源来指导 Kubernetes 我们的应用程序的期望状态,Kubernetes 将确保它总是如此。

我们如何使用 Kubernetes?

在本节中,我们将带您了解我们如何在 Kubernetes 集群中部署 Tensorflow 服务,以及它如何使管理模型部署变得非常方便。

我们使用托管的 Kubernetes 服务来创建 Kubernetes 集群,并手动将计算资源配置为节点。因此,我们有了一个 Kubernetes 集群,其中的节点可以随时运行应用程序。

服务于一个模型的应用程序包括

  1. 两个或更多 Tensorflow 服务单元,为带有自动缩放器的模型提供服务,以根据资源消耗来缩放单元
  2. 一个负载平衡器,用于将传入的流量均匀地分配给各个单元
  3. 向外部用户公开的 HTTP 端点

为了部署应用程序,我们需要

  1. 部署部署资源,指定
  2. Tensorflow 服务的豆荚数量
  3. 用于加载模型文件的 Tensorflow 的 S3 url
  4. 部署服务资源以公开它
  5. 部署入口资源以定义 HTTP 端点 url

然后,Kubernetes 根据部署资源中定义的值将 Tensorflow 服务单元分配到具有单元数量的集群。pod 可以分配给集群中的任何节点,Kubernetes 确保它将 pod 分配到的节点有足够的 pod 所需的资源。如果没有节点拥有足够的资源,我们可以通过添加新节点来轻松地扩展集群。

为了让 ingressresource 中定义的规则发挥作用,集群必须有一个正在运行的入口控制器,这就是我们选择负载平衡器的原因。入口控制器做的事情很简单:它不断检查 Ingres resource,创建负载平衡器,并根据 Ingres resource 中的规则定义规则。一旦配置了负载平衡器,它就能够将传入的请求重定向到 Tensorflow 服务单元。

就是这样!我们有一个可扩展的 Tensorflow 服务应用程序,它通过负载平衡器为模型提供服务!为了服务于另一个模型,我们需要做的就是部署相同的资源集,但是使用模型的 S3 url 和 HTTP 端点。

为了说明集群内部正在运行什么,让我们看看部署两个应用程序时的情况:一个用于服务定价模型,另一个用于服务欺诈检查模型。每个应用程序都配置有两个 Tensorflow 服务单元,暴露在/v1/models/model

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

有两个 Tensorflow 服务单元为欺诈检查模型提供服务,并通过负载平衡器公开。定价模型也是如此,唯一的区别是它所服务的模型和公开的 HTTP 端点 url。定价和欺诈检查模型的负载平衡器规则如下所示

如果转发到路径是/v1/models/pricing pod IP-1 pricing pod IP-2 路径是/v1/models/fraud-check fraud-check pod IP-1 fraud-check pod IP-2

统计和日志

最后一部分是统计和日志的工作原理。在此之前,我们需要介绍一下达蒙塞特。根据该文档,DaemonSet 确保所有(或一些)节点运行 pod 的副本。随着节点添加到集群中,单元也会添加到其中。随着节点从集群中移除,这些 pod 将被垃圾收集。删除 DaemonSet 将清理它创建的 pod。

我们将 datadog-agent 和 filebeat 部署为 DaemonSet。因此,我们在所有节点中始终有一个 datadog-agent pod 和一个 filebeat pod,并且可以从同一节点中的 Tensorflow 服务 pod 访问它们。Tensorflow 服务 pod 针对每个请求向其所在节点中的 datadog-agent pod 发出一个 stats 事件。

以下是 DataDog 统计数据的示例:

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

以及我们放置的日志:

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

从走秀中获得的好处

Catwalk 已经成为服务于机器学习模型的首选集中式系统。数据科学家不需要负责服务基础设施,因此他们可以专注于最重要的事情:提出解决客户问题的模型。他们只需要提供导出的模型文件和对预期流量的估计,以便准备足够的资源来运行他们的模型。作为回报,他们会得到一个端点来对他们的模型进行推理调用,以及所有必要的监控和调试工具。更新模型版本是自助的,模型改进周期比以前短了很多。我们过去以天计算,现在以分钟计算。

非 A/B 测试的因果推理:理论与实践指南

原文:https://towardsdatascience.com/causal-inference-thats-not-a-b-testing-theory-practical-guide-f3c824ac9ed2?source=collection_archive---------14-----------------------

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

https://conversionsciences.com/conversion-optimization-blog/

毫无疑问,随机实验(假设正确进行)是建立因果关系的最直接的方法(参考我之前的一篇关于 A/B 测试学习资源的文章!).然而,实际上,有些情况下实验并不是一个可行的选择:

  • 您正在处理没有控制或测试组分配的回顾性干预数据,这可能是由于实验的高成本
  • 干预是一个足够大的变化,你不能只向一半的目标受众展示(例如,主要产品发布、UI 改进等。)
  • 治疗是观察而不是分配的(例如吸烟者和非吸烟者之间的比较,社交媒体平台上的活动水平),也称为选择偏差
  • 还有更多…

上述案例经常被称为 观察性研究 ,其中自变量不在研究人员的控制之下。观察性研究揭示了衡量因果效应的一个基本问题——也就是说,我们在治疗组和非治疗组之间观察到的任何变化都是反事实,这意味着我们不知道如果治疗组的人没有接受治疗,他们会发生什么。

从众所周知的统计书籍、研究论文和课程讲义中提取理论,本文介绍了在非实验数据存在的情况下做出反事实推理的 5 种不同方法。还包括简单的代码示例和技术行业中的应用,以便您可以看到理论是如何付诸实践的。

特别感谢iris&Joe的灵感和知识分享,并感谢matt的点评。 关注我在 Medium.com 的 定期发表关于科技&商业相关话题的博客!📚😊❤️

方法 1:使用混杂变量的 OLS

您从整个用户群中收集数据,并希望回归新功能点击次数的参与指数。这是一个合理的方法吗?

理论: 最有可能的答案是否定的。在上面的案例中,我们试图衡量新功能的使用对用户整体参与度的影响(下图 I 中左侧的因果图)。

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

Plot 1: Causal Graphs with Confounding Variables

然而,有可能 混淆变量 被从模型中省略,并且对自变量和因变量都有影响。这种混淆变量可以包括用户的特征(例如,年龄、地区、行业等。).很有可能,这些用户特征决定了用户使用新特性的频率,以及他们在发布后的参与程度(见上面图 1 中的右因果图)。这些混淆的变量需要在模型中加以控制。

示例代码: 假设你有 10k MAU…

## Parameter setup
total_num_user = 10000
pre_engagement_level = rnorm(total_num_user)
new_feature_usage = .6 * pre_engagement_level + rnorm(total_num_user)
post_engagement_level = .4 * pre_engagement_level + .5 * new_feature_usage + rnorm(total_num_user)## Model without the confounder
summary(lm(post_engagement_level~new_feature_usage))## Model with the confounder
summary(lm(post_engagement_level~new_feature_usage+pre_engagement_level))

由于混杂因素对自变量和因变量的积极影响,第一次回归会导致系数估计值的向上偏差。

当这种方法不起作用时: 现在你可能想知道,控制混杂因素总是有效吗?不。它仅在满足以下假设时有效[1]:

  • a)治疗组和非治疗组是可比的(意味着没有不平衡或没有完全重叠)
  • b)观察所有能同时影响因变量和治疗变量的变量

当这些假设不成立时,我们将继续讨论其他方法。

方法 2:匹配/倾向分数匹配

理论: 当治疗组和非治疗组不可比时,即当混杂协变量的分布或范围在对照组和治疗组之间变化时,系数估计值有偏差[1]。匹配技术通过识别治疗组和非治疗组中相互接近的成对数据点来确保平衡分布,混杂协变量定义了成对数据点之间的距离。这些技术输出较小的数据集,其中每个治疗观察与最接近它的一个(或多个)非治疗观察相匹配。

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

Plot 2: Raw vs. Matched Control and Treatment Groups Using PSM

对于具有大量预处理变量的模型,匹配过程可能是昂贵的。倾向得分匹配(PSM) 通过计算每个观察值的单个得分来简化问题,然后该得分可用于识别匹配对(参见左边的示例,使用下面的示例代码生成)。

倾向得分通常使用标准模型(如逻辑回归)进行估计,其中治疗变量为因变量***【T】,混杂协变量【X】***为自变量。因此,它估计了一个人接受治疗的概率,以混杂协变量为条件。

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

Formula 1: PSM with Logistic Regression

行业应用: 作为 A/B 测试的替代方法,这种方法也被科技公司的研究人员所应用。例如, LinkedIn 在 2016 年发表了一篇论文,分享了在其移动应用采用分析中使用的准实验方法。移动应用程序 UI 的彻底改造以及基础设施的挑战使得 A/B 测试不可行。在历史发布数据的帮助下,他们证明了倾向评分技术如何减少采用偏差,并可用于衡量主要产品发布的影响[2]。

示例代码: R 的 Matchit 包提供了使用不同的距离定义、匹配技术等选择匹配对的多种方式。,我们将在下面的例子中说明它。在下面的代码示例中,我们使用了 2015 年 BRFSS 调查数据的样本,可通过弗吉尼亚大学图书馆访问。该样本有 5000 个记录和 7 个变量,在控制了种族、年龄、性别、体重和平均饮酒习惯协变量后,我们有兴趣了解吸烟对慢性阻塞性肺病(CODP)的影响。

## Read in data and identify matched pairs
library(MatchIt)
sample = read.csv("[http://static.lib.virginia.edu/statlab/materials/data/brfss_2015_sample.csv](http://static.lib.virginia.edu/statlab/materials/data/brfss_2015_sample.csv)")
match_result = matchit(SMOKE ~ RACE + AGE + SEX + WTLBS + AVEDRNK2, 
                       data = sample,
                       method = "nearest",
                       distancce = "logit")
par(family = "sans")
plot(match_result,  type = "hist", col = "#0099cc",lty="blank")
sample_match = match.data(match_result)## Models with imbalanced and balanced data distribution
sample$SMOKE = factor(sample$SMOKE, labels = c("No", "Yes"))
sample_match$SMOKE = factor(sample_match$SMOKE, labels = c("No", "Yes"))
mod_matching1 = glm(COPD ~ SMOKE + AGE + RACE + SEX + WTLBS + AVEDRNK2, data = sample, family = "binomial")
mod_matching2 = glm(COPD ~ SMOKE + AGE + RACE + SEX + WTLBS + AVEDRNK2, data = sample_match, family = "binomial")
summary(mod_matching1)
summary(mod_matching2)

方法 3:工具变量

理论 : 当假设 b)不满足,即存在无法观测到的混杂变量时,使用工具变量(IV) 可以减少遗漏变量偏倚。如果:1) Z 与 X 相关,则变量 Z 有资格作为工具变量;2) Z 不与任何对 Y 有影响的协变量(包括误差项)相关[3]。这些条件意味着 Z 仅通过其对 x 的影响来影响 Y。因此,Z 引起的 Y 的变化不会混淆,并可用于估计治疗效果。

例如,为了研究学校教育(如受教育年限)对收入的影响,“能力”是一个重要但难以衡量的变量,它对学生在学校的表现以及毕业后的收入都有影响。研究人员研究的一个工具变量是出生月份,它决定入学年份,从而决定受教育年限,但同时对收入没有影响(如图 3 所示)。

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

Plot 3: Using “Birth Month” as an Instrumental Variable

在实践中,通常使用两阶段最小二乘法来估计 IV。在第一阶段,IV 用于在 X 上回归以测量 X 之间的协方差& IV。在第二阶段,来自第一阶段的预测 X 和其他协变量一起用于回归 Y,从而集中于由 IV 引起的 Y 的变化。

这种方法最大的挑战是工具变量很难找到。一般来说,独立变量更广泛地应用于计量经济学和社会科学研究。因此,这里省略了行业应用和代码示例。

方法 4:差异中的差异

理论: 当 IVs 没有好的候选者时,我们需要一种替代的方式来说明未观测的协变量。差异中的差异(DiD) 方法通过比较对照组&治疗组的治疗后差异与治疗前差异进行工作,假设如果没有干预,两组的因变量将遵循相似的趋势。与试图识别彼此相似的数据点对的匹配/PSM 不同,DiD 估计器考虑了两组之间的任何初始异质性。

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

Source: What is difference-in-differences (https://stats.stackexchange.com/questions/564/what-is-difference-in-differences)

DiD 方法的关键 假设是对照组&治疗组的因变量遵循相同的趋势平行世界假设 ) 。这并不意味着它们需要具有相同的平均值,或者在预处理期间根本没有趋势[4]。参见左侧的示例图,其中控制&试验组在预处理期间具有相似的趋势。如果假设成立,治疗组的治疗后差异可以分解为对照组中类似观察到的差异和治疗本身引起的差异。DID 通常被实现为回归模型中时间和治疗组虚拟变量之间的交互项。

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

Formula 2: DiD in a Regression Model

有几种不同的方法来验证平行世界的假设。最简单的方法是进行目视检查。或者,您可以让治疗变量与时间虚拟变量相互作用,以查看两组之间的差异在治疗前期间是否不显著[5]。

行业应用: 类似于倾向得分匹配,这种方法一直受到希望在非实验性设置中研究用户行为的科技公司的青睐。例如,脸书在他们 2016 年的论文中应用 DiD 方法来研究贡献者的敬业度在被派往脸书前后是如何变化的。他们发现,在发布内容后,人们“更有内在动力更频繁地访问网站……”[6]。这是另一个很好的例子,发帖与否的行为不受研究者的控制,只能通过因果推理技术来分析。

示例代码: 这里我们来看看如何使用 DiD 来估计 1993 年 EITC(劳动所得税收抵免)对至少有一个孩子的妇女就业率的影响。感谢[7]&【8】的原创分析,下面的代码只是一个简单的版本来演示是如何工作的!

## Read in data and create dummy variables
library(dplyr)
library(ggplot2)
data_file = '../did.dat'
if (!file.exists(data_file)) {
    download.file(url = '[https://drive.google.com/uc?authuser=0&id=0B0iAUHM7ljQ1cUZvRWxjUmpfVXM&export=download'](https://drive.google.com/uc?authuser=0&id=0B0iAUHM7ljQ1cUZvRWxjUmpfVXM&export=download'), destfile = data_file)}
df = haven::read_dta(data_file)
df = df %>%
    mutate(time_dummy = ifelse(year >= 1994, 1, 0), 
           if_treatment = ifelse(children >= 1, 1, 0))## Visualize the trend to validate the parallel world assumption
ggplot(df, aes(year, work, color = as.factor(if_treatment))) +
    stat_summary(geom = 'line') +
    geom_vline(xintercept = 1994)## Two ways to estimate the DiD effect: shift in means & regression
var1 = mean( (df %>% filter(time_dummy==0 & if_treatment==0 ))$work)
var2 = mean( (df %>% filter(time_dummy==0 & if_treatment==1 ))$work)
var3 = mean( (df %>% filter(time_dummy==1 & if_treatment==0 ))$work)
var4 = mean( (df %>% filter(time_dummy==1 & if_treatment==1 ))$work)
(var4 - var3) - (var2 - var1)mod_did1 = lm(work~time_dummy*if_treatment, data = df)
summary(mod_did1)

方法 5:贝叶斯模型

尽管 DiD 是一种流行的因果推理方法,但它有一些局限性:

  • a)它假设影响没有时间演变;相反,我们只是分析前后的变化
  • b)它假设观察值是独立且同分布的,因此不适用于序列相关的数据点

最近一系列基于状态空间模型的研究,通过利用完全贝叶斯时间序列对效果进行估计,并对最佳综合控制进行模型平均,概括了更灵活的用例[9]。Google 出版物和相应的 R 包“CausalImpact”展示了这种状态空间模型背后的理论和实现,建议进一步阅读。

[## 因果影响

这个包是做什么的?这个 R 包实现了一种方法来估计因果效应的设计…

google.github.io](https://google.github.io/CausalImpact/CausalImpact.html)

参考资料:

[1]安德鲁·盖尔曼和珍妮弗·希尔。使用回归和多级/分层模型的数据分析(2007)

[2]用 A/B 和准 A/B 测试评估移动 app。https://dl.acm.org/citation.cfm?id=2939703

[3]珀尔,J. (2000 年)。因果关系:模型、推理和推论。纽约:剑桥大学出版社。

[4]讲稿:差异中的差异,实证方法http://finance . Wharton . upenn . edu/~ Mr Robert/resources/Teaching/CorpFinPhD/Dif-In-Dif-slides . pdf

[5]https://stats . stack exchange . com/questions/160359/difference-in-difference-method-how-to-test-of-assumption-of-common-trend-betw

[6]发布到脸书前后参与度的变化https://research . FB . com/publications/Changes-in-Engagement-Before-and-After-Posting-Facebook/

[7]https://thetarzan . WordPress . com/2011/06/20/差异估算中的差异-r-and-stata/

https://dhicks.github.io/2018-10-10-did/

[9]使用贝叶斯结构时间序列模型推断因果影响https://research.google/pubs/pub41854/

使用差异中的差异、因果影响和综合控制的因果推理

原文:https://towardsdatascience.com/causal-inference-using-difference-in-differences-causal-impact-and-synthetic-control-f8639c408268?source=collection_archive---------0-----------------------

相关性不是因果关系。那么什么是因果关系呢?如何衡量?

因果关系是衡量 x 对 Y 的实际影响,例如,广告活动对产品销售的影响是什么?

准确理解这些干预对受试者的因果影响至关重要。因果推理的主要威胁之一是来自其他变量的混杂效应。在广告活动的情况下,它可能是产品价格的降低,整体经济的变化或各种其他因素可能会导致销售的变化。那么,我们如何正确地将销售的变化归因于广告宣传呢?

有两种方法可以估计干预对受试者的真正因果影响。

随机实验:这是推断治疗的实际因果影响的最可靠方法,我们随机诱发过程中的变化,并测量结果变量的相应变化。然而,在大多数情况下,进行实验并控制整个系统真正随机是不可能的。

**计量经济学中的因果推断:**这种方法包括将统计程序应用于已经可用的数据,在控制混杂因素的同时得出因果估计。这种方法下的一些方法是我们将在这个分析中看到的。以下是一些方法:

  • 差异中的差异
  • 因果影响
  • 综合控制

将使用 巴斯克 数据集进行演示。利用这些数据,我们将在来自其他 17 个地区的数据的帮助下,估计恐怖主义冲突在西班牙自治区巴斯克地区的真实经济影响。让我们看看一些关于数据和实验设计的事实。

  • 该数据集包含 1955 年至 1997 年的信息
  • 关于西班牙 18 个地区的信息可用
    ——其中一个是西班牙全国的平均值(我们将删除它)
  • 治疗年份被认为是 1975 年
  • 治疗区域为“巴斯克地区(Pais Vasco)”
  • 经济影响衡量变量是人均国内生产总值(以千计)

分析是在 R 中完成的,源代码可以在我的 GitHub 中找到。我们将从提到的方法开始。

一阶差分估计

在讨论差异方法中的差异之前,让我们先看看第一个差异及其作用。我们的目标是量化巴斯克地区恐怖冲突前后 GDP 的影响。简单地说,我们实际上可以通过构建一阶差分回归并观察估计值来实现这一点。让我们看看巴斯克地区人均 GDP 的总体趋势。

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

从图表中,我们可以看到趋势是如何在恐怖主义干预后突然下降,然后又重新上升的。我们的目标是确定我们看到的暴跌幅度。第一个差异估计值将告诉我们治疗前后 GDP 的差异。让我们以 GDP 为因变量,前后指标为自变量,构造一个一阶差分方程。

f_did <- lm(data = basq_fdid, gdpcap ~ post)
stargazer(f_did, type=”text”)

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

后指标系数表明,后时期人均 GDP 增长了约 2.5 个单位,这并不是我们想要的,因为我们想要捕捉下降趋势。

这是因为有一个我们之前提到的预期问题。除了同时发生的恐怖主义冲突之外,GDP 的趋势可能会因为许多其他变量而发生改变,也就是所谓的混杂因素。这种情况下可能的混杂因素有:

  • 贸易法的通过会影响当地的商业和国内生产总值
  • 地方团体内部的兵变
  • 对腐败或功能失调的政府的看法

对此的解决方案是将趋势与未受恐怖主义冲突影响的控制区域进行比较。这种比较允许我们在干预期后去除混杂效应,并得出真正的因果影响。这就是差异方法的不同之处。

差异中的差异

差异中的差异(DD)设计的基本假设是,对照组的趋势提供了在没有治疗的治疗组中观察到的趋势的适当代表。因此,斜率变化的差异将是实际的处理效果。这里的假设是治疗组和对照组在前期必须遵循相同的趋势。

对于这一分析,控制区是通过发现每个地区和巴斯克地区之间多年来国内生产总值百分比差异变化最低的地区来确定的。或者,在可行的情况下,我们可以通过观察治疗组和对照组的 GDP 趋势来寻找控制区域。在这种情况下,加泰罗尼亚地区被认为是最好的控制地区。让我们看看下面测试和控制区域的 GDP 趋势:

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

加泰罗尼亚地区的国内生产总值趋势与巴斯克的国内生产总值齐头并进,但前几年除外。因此,将加泰罗尼亚视为我们的控制区应该没有问题。

让我们以 GDP 为因变量,以治疗指标和前后指标为自变量进行回归拟合。这里的关键方面是提供治疗和治疗前后指标之间的相互作用,因为我们希望估计值包含治疗和治疗后指标与未治疗和治疗前指标相比的影响。拟合之后,我们来看看下面的回归结果:

did <- lm(data = did_data, gdpcap ~ treat*post)
stargazer(did, type=”text”)

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

查看交互变量的估计表明,由于发生的恐怖主义干预,巴斯克地区的 GDP 减少了 0.85 个单位。现在,一阶差分法和 DD 法提供的估计值之间存在着明显的差异。从数量上来说,我们可以看到第一个差异估计看起来是多么的欺骗和天真。

如果你感兴趣,你可以在这里阅读更多关于差异的差异。现在,让我们转到其他因果推断方法。

因果影响

因果影响是谷歌开发的一种方法,用于评估治疗对被治疗群体的因果影响。官方文件可以在这里找到。

使用因果影响方法的动机是,差异中的差异在以下方面受到限制:

  • DD 传统上基于静态回归模型,该模型假设独立且同分布的数据,尽管事实上设计具有时间成分
  • 大多数 DD 分析只考虑两个时间点:干预前和干预后。在实践中,我们还必须考虑一个效应随时间演变的方式,尤其是它的开始和衰减结构

这里的想法是使用对照组中的趋势来预测治疗组中的趋势,如果治疗没有发生,这将是趋势。那么实际的因果估计将是我们预测的治疗组的实际趋势与反事实趋势之间的差异。因果影响使用贝叶斯结构时间序列模型来解释观察结果的时间演变。本质上,因果影响方法非常接近我们接下来要看到的综合控制方法。

在这种情况下,控制区域再次被认为是加泰罗尼亚。有了处理和控制地区的 GDP,让我们把它们输入到 R 中的因果影响函数,看看结果。

pre.period <- as.Date(c(“1955–01–01”, “1975–01–01”))
post.period <- as.Date(c(“1976–01–01”, “1997–01–01”))impact <- CausalImpact(basq_CI, pre.period, post.period)
summary(impact)

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

绝对效应是处理后的实际 GDP 与反事实 GDP 之差。从结果中,我们可以看到绝对影响给了我们-0.76 的值,这意味着人均 GDP 减少了 0.76 个单位,即 8.8%,因为在巴斯克地区发生了恐怖主义冲突。这几乎等于我们使用差异中的差异方法看到的估计。对于那些对因果影响感兴趣的人,该方法的作者给出了该方法的详尽解释,可以在这里 找到

综合控制

综合控制是一种与因果影响非常相似的技术,用于估计治疗的真实影响。这两种方法都是在对照组的帮助下构建一个治疗组的反事实,让我们知道如果治疗没有发生,趋势是什么。治疗组的反事实 GDP 将由对照组的 GDP 以及对照组中其他可能的协变量来预测。synth 算法通过为对照组中的回归变量分配权重来预测反事实,这有助于识别单个回归变量及其在预测中的影响。最终,真正的因果影响是实际 GDP 和反事实 GDP 之间的差异,如果治疗没有发生。

综合控制和因果影响之间的区别在于,综合控制仅使用治疗前变量进行匹配,而因果影响使用预测变量的全部治疗前和治疗后时间序列进行匹配。让我们看看数据中所有其他 17 个地区的 GDP 趋势图。

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

从上面的图中可以看出,所有控制区的 GDP 都有类似巴斯克地区前期的上升趋势。这表明巴斯克地区的 GDP 可以使用其他地区的数据相当准确地构建。

关于这个问题陈述的综合控制的实现已经在这里找到的包的官方文档中给出。执行之后,我们来看看实际 GDP 和反事实 GDP 之间的情节。

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

路径图显示了前期的合成趋势和实际趋势之间的平滑关系,以及一旦治疗发生,它如何逐渐偏离。后期趋势的差异就是我们的平均治疗效果。

发现实际和合成趋势的均方根误差为 0.57 个单位。我们可以得出结论,恐怖主义冲突对巴斯克地区的真正因果影响是使用合成控制方法计算的 GDP 减少了 0.57 个单位。

让我们来看看以下三种方法的结果对比:

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

这三种方法之间因果影响的大小只有很小的差别,而且没有一种方法能给我们“正确的答案”大多数时候,我们使用的方法会受到实验性质和我们试图解决的因果威胁的限制。

其他一些用于推断因果影响的技术有倾向分数匹配固定效应回归工具变量回归不连续性

使用综合控制的因果推理:最终指南

原文:https://towardsdatascience.com/causal-inference-using-synthetic-control-the-ultimate-guide-a622ad5cf827?source=collection_archive---------4-----------------------

实验和因果推理

我们可以只用一个治疗病例和少数对照病例进行因果推断吗?

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

Photo by Franki Chamaki on Unsplash

技术困境

在其他帖子中,我解释了什么是因果关系,以及如何使用准实验设计进行因果推断(做了做了RDD )。几乎所有的研究方法都必须满足两个前提条件,才能产生有意义的见解:

1.治疗组看起来与对照组相似(相似性可比性);

2.每组内足够多的观察值(大 n )。

这两个前提条件为因果推断奠定了基础。但是,如果我们只有一个治疗病例和几个对照病例,有可能做因果推断吗?更糟糕的是,如果没有与治疗病例有相似协变量的对照病例,我们该怎么办?

在这些情况下,基于回归的解决方案(例如,关键变量匹配或倾向得分匹配)表现不佳。此外,其他准实验设计,如 DID 方法,在治疗组和对照组之间需要相似的协变量,在这两种情况下会产生巨大的偏差。

在这篇文章中,我自豪地提出一个统计解决方案,即综合控制方法(SCM) ,它是由一群像我一样的政治科学家提出的。老实说,供应链管理有巨大的因果潜力,但目前仍未得到充分重视。随着面向消费者的公司希望了解模拟的消费者行为,它开始在行业中引起一些关注。

基础

SCM 使用来自“供体”池的多个病例的加权平均值来创建人工对照病例。

下面是一个简化的过程:

  1. 假设有 J + 1 个单位;
  2. j(1)是已治疗的病例(一个 注意 : 只有一个已治疗的病例);从 j(2)到 j(j+1)的单元是构成“ 供体池 ”的未曝光病例;
  3. 从捐献者那里收集并得到单位的加权平均值
  4. 选择使以下损失函数最小的加权值 W*:

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

(详细描述请参考 阿巴迪等人 2010 阿巴迪等人 2015 )。)

总之,SCM 通过提供正式的标准和程序引导我们通过生成控制案例的过程,这是 matching 或其他基于回归的方法无法实现的。

SCM 的另一个优点是,它能够使合成病例在关键指标方面看起来像治疗过的病例,如先前的协变量和其他事后结果预测(Abadie 等人,2010 年)。换句话说,供应链管理可以提供比较。

什么时候使用 SCM?

SCM 是以下两种情况的理想选择:

  1. 社会事件发生在总体层面,如县、州、省。
  2. 只有一个治疗病例和几个对照病例。

由于这两个特点,当涉及到大规模项目评估时,SCM 是一种可行的方法(例如,加州的烟草控制项目评估基于场所的犯罪干预)。说真的,业界真的应该把它添加到他们的 DS 工具包中。

优点

总的来说,供应链管理有三个优势。

  1. 它在 0 和 1 之间分配权重,因此避免了外推。外推意味着我们不将权重限制在 0 和 1 之间,但是如果权重保持在 100%之外,这是没有意义的。我是说怎么解读一个权重 200%?完全没有任何直觉。
  2. 它列出了选择标准,并解释了每个捐赠者的相对重要性。
  3. 合成对照病例与治疗病例非常相似,几乎相同。
  4. 合成对照的选择不依赖于干预后的结果,这使得不可能挑选可能影响结论的研究设计。

怎么用?

1。行业应用

  1. 程序评估。

2。犯罪研究

3。罕见事件

  • 潜在地,我们可以应用合成控制来为罕见事件生成更多的案例,因为罕见事件缺乏数据供应。请查看我的另一篇关于如何使用 5 个机器学习分类器对罕见事件进行分类的帖子。

[## 脖子上的痛:使用 5 种机器学习方法预测罕见事件

哪一种最适合不平衡数据?有什么权衡吗?

towardsdatascience.com](/classifying-rare-events-using-five-machine-learning-techniques-fab464573233)

2.r 实施

在这一节中,我将复制 Abadie (2003) 的结果,该结果研究了恐怖主义如何影响西班牙巴斯克地区的经济产出。我们将使用 R 包“Synth”进行分析,详细的数学解释和 R 指令请参考 Synth:比较案例研究中综合控制方法的 R 包

步骤 0:包、库和探索性数据分析

# install and load package
install.packages("Synth") 
library(Synth)# read the dataset "basque"
data("basque")#EDA
dim(basque) #774*17
basque[1:10,]

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

Table 1

从表 1 中,有 774 个观察值和 17 个变量(列)。

第 1–3 列:地区号、名称和年份(ID 信息)

DV: gdpcap(人均 GDP)

其他列:有 13 个预测变量。

第一步:数据准备

原始数据集“巴斯克”有一个传统的面板格式,为了使用 synth() ,我们需要以另一种形式读取它。

# set up different arguments
# foo: dataprep.out <- dataprep(foo = basque,
 predictors = c(“school.illit”, “school.prim”, “school.med”,
 “school.high”, “school.post.high”, “invest”),
 predictors.op = “mean”, **# the operator**
 time.predictors.prior = 1964:1969, **#the entire time frame from the #beginning to the end**
 special.predictors = list(
 list(“gdpcap”, 1960:1969, “mean”),
 list(“sec.agriculture”, seq(1961,1969,2),”mean”),
 list(“sec.energy”,seq(1961,1969,2),”mean”),
 list(“sec.industry”, seq(1961,1969,2),”mean”),
 list(“sec.construction”, seq(1961,1969,2),”mean”),
 list(“sec.services.venta”, seq(1961,1969,2),”mean”),
 list(“sec.services.nonventa”,seq(1961,1969,2),”mean”),
 list(“popdens”, 1969, “mean”)),
 dependent = “gdpcap”, **# dv**
 unit.variable = “regionno”,**#identifying unit numbers**
 unit.names.variable = “regionname”,**#identifying unit names**
 time.variable = “year”,**#time-periods**
 treatment.identifier = 17,**#the treated case**
 controls.identifier = c(2:16, 18),**#the control cases; all others #except number 17**
 time.optimize.ssr = 1960:1969,**#the time-period over which to optimize**
 time.plot = 1955:1997)**#the entire time period before/after the treatment**

dataprep.out 获得四个值(X1,X0,Z1,Z0 ),允许我们进行因果推断。

X1 :治疗前的对照病例

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

X0 :治疗后对照病例

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

Z1 :治疗前的治疗案例

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

Z0 :治疗后的治疗案例

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

第二步:运行 synth()

synth.out = synth(data.prep.obj = dataprep.out, method = “BFGS”)

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

要计算真实基本区域和合成控制之间的差异,如下所示:

gaps = dataprep.out$Y1plot — (dataprep.out$Y0plot 
                                     %*% synth.out$solution.w)
gaps[1:3,1]

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

为了提供一些汇总表,

synth.tables = synth.tab(dataprep.res = dataprep.out,
                         synth.res = synth.out)
names(synth.tables)
[1] "tab.pred" "tab.v"    "tab.w"    "tab.loss"

注: synth.tables$tab.pred 是一个比较处理单元、合成对照和样本中所有单元的预处理预测值的表格

synth.tables$tab.pred[1:13,]

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

老实说,我无法生成与原始论文相同的结果。原始代码(synth.tables$tab.pred[1:5,])查看了处理案例和合成案例之间的前 5 个协变量,发现它们非常相似。因此,我将代码扩展到包括 13 个协变量,并发现除了少数几个之外,其余变量都非常相似。

如上所述,SCM 允许我们检查每个单元的相对重要性。

synth.tables$tab.w[8:14, ]

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

如图所示,第 10 号单位 Cataluna 对该案件的贡献为 85.1%,第 14 号单位 Madrid (Comunidad De)对其余的 14.9%做出了贡献。所有其他对照案例都没有贡献。

# plot the changes before and after the treatment 
path.plot(synth.res=synth.out,dataprep.res = dataprep.out, 
          Ylab="real per-capita gdp (1986 USD, thousand)",Xlab="year",
          Ylim = c(0,12),Legend = c("Basque country", 
                                    "synthetic Basque country"),
          Legend.position = "bottomright")

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

gaps.plot(synth.res = synth.out, dataprep.res = dataprep.out,
 Ylab = “gap in real per-capita GDP (1986 USD, thousand)”, Xlab= “year”,
 Ylim = c(-1.5,1.5), Main = NA)

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

参考和更多资源

Medium 最近进化出了自己的 作家合伙人计划 ,支持像我这样的普通作家。如果你还不是订户,通过下面的链接注册,我会收到一部分会员费。

[## 阅读叶雷华博士研究员(以及其他成千上万的媒体作家)的每一个故事

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

leihua-ye.medium.com](https://leihua-ye.medium.com/membership)

延伸阅读:

[## 一个巨大的挑战:如何使用 5 种机器学习方法预测罕见事件

当结果变量高度不平衡时,哪种 ML 方法效果最好?有哪些权衡?

towardsdatascience.com](/classifying-rare-events-using-five-machine-learning-techniques-fab464573233) [## R 中 K-最近邻初学者指南:从零到英雄

使用各种度量标准在 R 中构建 KNN 模型的管道

towardsdatascience.com](/beginners-guide-to-k-nearest-neighbors-in-r-from-zero-to-hero-d92cd4074bdb) [## 如何使用决策树构建垃圾邮件分类器

简单的方法是更好的方法!

towardsdatascience.com](/how-to-build-a-spam-classifier-using-decision-tree-b75d0c7f25e)

喜欢读这本书吗?

请在 LinkedInYoutube 上找到我。

还有,看看我其他关于人工智能和机器学习的帖子。

因果推理与统计推理

原文:https://towardsdatascience.com/causal-vs-statistical-inference-3f2c3e617220?source=collection_archive---------3-----------------------

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

Photo by Steinar Engeland on Unsplash

为什么说相关性不够,或者说相关性足够?这个问题困扰了科学界一个世纪。关于这个主题的机器学习观点。

近年来,因果推理,或一般的因果关系问题,受到了很多关注。问题很简单,相关性是否足以进行推断?我将陈述如下,更有见识的无知的人将会提出一个类似这样的论点:

因果关系就是非常强的相关性

如果这是你的意见,我不想打断你,但不,它不是,它肯定不是。我可以看到,这是相对容易说服,但一旦我们开始思考一点,我们很容易意识到它不是。如果你在读完这篇文章后仍然不相信,请联系我进一步讨论,因为我对你的想法很感兴趣。

为了说明相关性不一定意味着因果关系,让我们来看看最简单的相关性公式,或者著名的皮尔逊相关系数:

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

For those wondering what the Greek letters stand for, μ is the mean of the respective variable and σ is the standard deviation. The E in the numerator denotes expectation, which is effectively a weighted average over different X-Y realizations, where the weights are their probability.

所以这个相关系数在-1 到 1 的范围内,告诉我们变量是负相关还是正相关。换句话说,当一个高于平均值,而另一个同时高于或低于平均值时。这个相关系数是以著名数学家卡尔·皮尔逊的名字命名的,我们非常感谢他。人们认为他是现代统计学的创始人,他还在伦敦大学学院建立了世界上第一个大学统计系。谢谢你,皮尔逊教授。但有一件事他并不热衷,那就是因果关系的论证。

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

Photo by Mike Enerio on Unsplash

请注意,相关公式直接存在一个问题,即没有方向感。尽管两个变量可能高度相关,但我们并不真正知道什么导致了什么。举个例子,以天气为例。如果下雨,你肯定有云。很自然,你会问自己这个问题,是什么导致了这场雨。以云和雨的相关性为例,你会注意到正相关。不错,但那又怎样?你真的能说是云导致了雨而不是雨导致了云吗?不,你不能,不能基于这个简单的相关系数。也许你会注意到一件事,很明显,云出现在雨之前。然后你会意识到,但是等等,如果我把一个时间方面引入到我的变量中,并计算出滞后相关性,那么我会意识到是云导致了雨,而不是相反。这是真的,但这引出了我的下一个论点。

诺贝尔奖得主巧克力上瘾的问题

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

Photo by Joanna Kosinska on Unsplash

有一项著名的研究表明,一个国家的巧克力消费量和来自这个国家的诺贝尔奖获得者的数量之间有很强的相关性。所以你会说巧克力消费导致一个人成为诺贝尔奖得主的概率更高,马上开始疯狂消费巧克力吗?我希望不是,我怀疑期望巧克力不会导致一个人成为诺贝尔奖获得者是合理的。所以让我们从这个陈述中提取两个变量。b——成为诺贝尔奖获得者,A——消费巧克力。这一陈述的因果图基本上如下所示:

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

箭头的意思是 A 引起 b,你可以看到,这是一个非常原始的因果图。现在我们可以进入正题,虽然我们在巧克力消费和获得诺贝尔奖之间有很强的相关性,我们可以问自己,是否有其他一些变量,C,比如国家的财富导致了诺贝尔奖和巧克力消费,或者是国家的教育制度导致了两者等等。让我们想象,事实也确实如此,两者有一个共同的原因。那么因果图看起来是这样的:

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

现在我们可以提到赖兴巴赫的共因原理,该原理指出,如果变量 A 和 B 有一个共因 C,那么当我们以 C 为条件时,这些变量之间的相关性被消除,这意味着以共因为条件的随机变量的条件分布变得独立。够好了。实际上,我们应该关注的因果图如下:

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

这就是因果关系的全部,确定没有一个共同的原因使 A 和 B 看起来像是 A 导致 B。这种做法已经在医学界以医学试验的形式建立起来,远在人们开始谈论因果推断之前。那么我们如何证明这一点呢?首先,我们将用一个更通用、更有用的名字来称呼一项医学试验。我们称之为对照实验。受控实验很好,我们可以直接作用于一个变量,看看我们的因果图中其他变量是如何变化的。在一项医学试验中,我们将 1 组和 2 组人分成两组,1 组服用安慰剂,2 组服用实际药物,观察结果。自然地,在医学试验中,我们希望这些人来自相同的分布,即相似。实际上,理想情况下,我们希望它们是相同的,这将是完美的医学试验,将消除任何其他潜在的共同原因,但这是不现实的期望,一个完美的控制实验。现在你观察各组的结果,并在一定的信心基础上确定药物是否能有效治愈疾病。

用因果语言来说,这叫做干预。如果我们可以把一个变量手动设置为一个值,而不改变其他任何东西。这基本上是说,我们在使用安慰剂和药物之前,让同样的人服用两种药物,看看疾病是否被药物或其他东西治愈了。一般来说,人们发现很难区分干预和将事件实现的概率设置为 1。不同之处在于,干预会导致两种不同的因果图,我们可以根据这两种因果图计算概率,并得出关于图中实际因果结构的结论。

幸运的是,我们要感谢朱迪亚·珀尔教授发明了因果演算,为此他获得了著名的图灵奖,并可能作为现代因果推理的创始人而闻名。我建议阅读他关于因果关系的书籍,以便更深入地探究这个话题:

1.为什么之书

2.因果关系:模型、推理和推论

3.统计学中的因果推断:初级读本

我个人认为,第一个对普通观众来说是好的,因为它也很好地展示了统计学和因果关系的历史,然后更深入地研究了因果推理背后的理论。

到目前为止,我们一直在谈论一些统计数据,但问题仍然是这如何实际反映在人工智能算法上,即机器学习算法。这种联系相当直接。我们目前使用的方法无法通过从数据中学习来区分因果,因为我们主要谈论的是机器学习和学习模型中的概率分布,这些模型基本上看到事情同时发生,并自动假设一个可以预测另一个。就个人而言,我无法想象这些模型能够或者将会安全地部署在现实世界中。特别是在这种情况下,如果我们想像 Schmidhueber 的人工科学家一样开发一些东西,我们需要能够区分因果和关于它们的原因。

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

Photo by Josh Riemer on Unsplash

在科学中,我们需要不断地接受或拒绝假说来得出结论。这就是为什么因果推理不仅仅是好的,如果我们想要得到有效的结论,它是必要的。有无数的例子表明,由于不能正确使用统计数据,研究得出了错误的结论,如这篇文章这篇文章所示。我相信这个领域将会在社会上引起一场科学复兴。作为这篇文章的一个收获,请记住以下您可能已经知道的内容:

相关性并不意味着因果关系

下次见!

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

Photo by Volkan Olmez on Unsplash

如何测量统计因果关系:金融应用的转移熵方法

原文:https://towardsdatascience.com/causality-931372313a1c?source=collection_archive---------3-----------------------

开源代码让你入门。

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

我们都听说过“相关性并不意味着因果关系”,但是我们如何量化因果关系呢?这是一项极其困难且经常误导的任务,尤其是当试图从观察数据中推断因果关系时,我们无法进行对照试验或 A/B 测试。

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

以图 4.1 中的二维系统为例。

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

Figure 4.1: Life is Random (or Nonlinear?)

乍一看,人们可能会说,随机变量 x₁和 x₂.之间没有明确的关系或因果关系然而,这个明显的随机系统呈现了由以下等式定义的非常简单的因果关系:

在 x₂和 x₁的关系中引入一个简单的非线性足以给系统带来复杂性,并潜在地误导一个天真的人。

幸运的是,我们可以利用统计学和信息论从观察数据中揭示复杂的因果关系(记住,这仍然是一项非常具有挑战性的任务)。

这一条的目标如下:

  • 介绍基于预测的因果关系定义及其使用向量自回归公式的实现。
  • 介绍因果关系的概率定义及其使用信息理论框架的实现。
  • 用建议的方法模拟线性和非线性系统并揭示因果联系。
  • 量化全球股票指数之间的信息流,进一步揭示哪些指数正在推动全球金融市场。
  • 讨论进一步的应用,包括金融和密码市场中社交媒体情绪的影响。

作为我们开源 Live Book Initiative 的一部分,我们还提供代码来复制结果。

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

统计因果关系的第一个定义

我们通过使用格兰杰(维纳 1956;Granger 1969),其中,如果 Y 的未来实现可以使用 X 和 Y 的过去信息而不是单独使用 Y 来更好地解释,则信号 X 被认为是 Y 的格兰杰原因。

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

Economist Clive Granger, who won the 2003 Nobel Prize in Economics.

格兰杰因果关系最常见的定义(G-因果关系)依赖于通过使用 X 和 Y 本身的过去值来预测变量 Y 的未来值。在那种形式中,如果 X 的使用提高了 Y 的预测,那么 X 被称为 G-cause Y。

在这两个模型中,函数 f₁(.)和 f₂(.)被选择来最小化损失函数的期望值。在大多数情况下,这些函数是用线性的,也可能是用非线性回归、神经网络等来检索的。g(.)是 l1 范数或 l2 范数。

我们现在可以在格兰杰因果概念下给出统计因果关系的第一个定义,如下所示:

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

标准格兰杰因果关系检验假设因果关系中的函数形式,并通过拟合自回归模型来实现(维纳 1956;格兰杰 1969)。

考虑线性向量自回归(VAR)方程:

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

其中 k 是考虑的滞后次数。或者,您可以选择适合该模型的 DL/SVM/RF/GLM 方法。

来自 Def。4.1,X 不 G-引起 Y 当且仅当 X 的预测误差在约束方程中。(4.1)和无限制回归模型方程。(4.2)是相等的(即,它们在统计上是不可区分的)。可以利用单向 ANOVA 测试来测试等式 1 和等式 2 的残差。(4.1)和(4.2)彼此显著不同。当测试一个以上的滞后 k 时,应应用多个假设测试的校正,例如错误发现率(FDR)或 Bonferroni 校正。

基于概率的定义

比 Def 更一般的定义。4.1 这不依赖于假设预测函数可以通过考虑条件概率来公式化。

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

净化 4.2 没有假定 X 和 y 之间耦合的任何函数形式。然而,它需要一种方法来评估它们的条件依赖性。在下一节中,我们将利用信息理论框架来实现这一目的。

转移熵和统计因果关系

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

Shannon, Claude. The concept of information entropy was introduced by Claude Shannon in his 1948 paper “A Mathematical Theory of Communication”.

为了计算 G-因果关系,我们使用转移熵的概念。自从它被提出(Schreiber 2000)以来,转移熵已经被认为是分析非线性系统因果关系的重要工具(Hlavackovaschindler 等人 2007)。它检测方向和动态信息(蒙塔尔托 2014 年),而不采取任何特定的功能形式来描述系统之间的相互作用。

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

净信息流

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

人们可以把这个量解释为信息流主导方向的量度。换句话说,一个积极的结果表明,与其他方向相比,从 X 到 Y 的信息流占主导地位,或者类似地,它表明哪个系统提供了关于其他系统的更多预测信息(Michalowicz、Nichols 和 Bucholtz,2013 年)。

格兰杰因果关系与转移熵的联系

已经证明(Barnett,Barrett 和 Seth 2009),如果所有过程都是联合高斯过程,那么线性 G-因果关系和转移熵是等价的。特别是,假设双变量情况下线性 G-因果关系的标准度量(L2-范数损失函数)如下:

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

可以证明以下几点(Barnett、Barrett 和 Seth 2009):

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

这个结果提供了转移熵和在标准 VAR 框架中实现的线性 G-因果关系之间的直接映射。因此,有可能估计一般形式的 te 和线性 G-因果关系的等价形式。

模拟系统上的信息流

在本节中,我们构建模拟系统,以因果方式耦合随机变量。然后,我们使用本文中研究的方法量化信息流。

我们首先假设一个线性系统,其中随机变量具有如下定义的线性关系:

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

我们用下面的代码模拟这个线性系统:

图 4.2 表示模拟线性系统的相关性。

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

Figure 4.2: Interactions between the variables of the simulated linear system.

我们首先定义一个函数,计算一个双变量的 G-因果关系的衡量标准,如等式。(4.4)如下:

我们使用 R 包R 变换中的函数calc_te和之前定义的函数Linear.GC来计算模拟变量之间的成对信息流,如下所示:

函数FApply.Pairwise是一个辅助函数,它简单地将给定函数D.Func应用于给定矩阵X中所有可能的列对,如下所示:

图 4.3 A)和 B)分别显示了系统变量之间的格兰杰因果关系和转移熵。单元格(x,y)表示从变量 y 到变量 x 的信息流。我们观察到格兰杰因果关系(线性)和转移熵(非线性)方法显示了类似的结果,即两种方法都类似地捕捉到了系统的依赖性。这一结果是预料之中的,因为系统是纯线性的,转移熵能够捕捉线性和非线性相互作用。

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

Fig. 4.3: Granger-Causality and Transfer Entropy for simulated linear system.

我们通过引入 x₁与变量 x₂和 x₅之间的非线性相互作用来定义第二个系统,如下:

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

我们用下面的代码模拟这个非线性系统:

图 4.5 表示模拟的非线性系统的相关性。

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

Figure 4.5: Interactions between the variables of the simulated nonlinear system.

我们计算模拟非线性系统的格兰杰因果关系和转移熵如下:

从图 4.6 A)和 B)中,我们观察到引入的非线性相互作用没有被格兰杰因果关系的线性公式所捕获。虽然所有的线性相互作用呈现相似的线性和非线性信息流,但是引入系统的两个非线性相互作用与线性公式相比呈现相对更高的非线性信息流。

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

Fig. 4.6: Granger-Causality and Transfer Entropy for simulated nonlinear system.

国际股票市场指数间的信息流

世界金融市场形成了一个复杂的动态网络,在这个网络中,各个市场相互影响。这种大量的相互作用会导致非常显著和意想不到的影响,因此准确理解世界各地的各种市场如何相互影响至关重要(Junior、Mullokandov 和 Kenett,2015)。

在这一节中,我们使用转移熵来识别国际股票市场指数之间的依赖关系。首先,我们选择一些主要全球指数进行分析,即标准普尔 500 指数、富时 100 指数、DAX 指数、泛欧 100 指数和 IBOVESPA 指数,它们分别跟踪以下市场:美国、英国、德国、欧洲和巴西。它们由以下代码定义:

tickers<-**c**("^GSPC", "^FTSE", "^GDAXI", "^N100", "^BVSP")

接下来,我们将加载所选指数的每日收盘调整价格的日志回报,如下所示(点击此处可访问该数据集):

**library**(xts)
dataset<-**as.xts**(**read.zoo**('./data/global_indices_returns.csv',
                  header=TRUE,
                  index.column=1, sep=","))
**head**(dataset)##                        X.GSPC   X.FTSE  X.GDAXI   X.N100   X.BVSP
## 2000-01-02 19:00:00  0.000000       NA  0.00000  0.00000  0.00000
## 2000-01-03 19:00:00 -0.039099  0.00000 -0.02456 -0.04179 -0.06585
## 2000-01-04 19:00:00  0.001920 -0.01969 -0.01297 -0.02726  0.02455
## 2000-01-05 19:00:00  0.000955 -0.01366 -0.00418 -0.00842 -0.00853
## 2000-01-06 19:00:00  0.026730  0.00889  0.04618  0.02296  0.01246
## 2000-01-09 19:00:00  0.011128  0.01570  0.02109  0.01716  0.04279

一个市场对另一个市场的影响是动态的。这里,我们将考虑从 2014 年 1 月 1 日到 2019 年 8 月 19 日的时间段,并且我们将使用包 IDPmisc 中的函数NARV.omit忽略由于数据缺失而导致无效退货的日期,如下所示:

**library**(IDPmisc)
dataset.post.crisis <- **NaRV.omit**(**as.data.frame**(dataset["2014-01-01/"]))

我们将在考虑的所有索引中计算成对转移熵,并构建一个矩阵,使得位置(I,j)中的每个值将包含从 ticker[I]到 ticker[j]的转移熵,如下所示:

*# Calculate pairwise Transfer Entropy among global indices*
TE.matrix<-**FApply.Pairwise**(dataset.post.crisis, calc_ete)
**rownames**(TE.matrix)<-**colnames**(TE.matrix)<-tickers

图 4.8 显示了由此产生的传递熵矩阵。我们通过将传递熵值除以矩阵中的最大值来归一化传递熵值,使得所有值的范围从 0 到 1。我们观察到,所研究的国际指数在分析期间高度相关,从美国市场到英国市场(^GSPC -> ^FTSE).)的信息流最多第二大信息流的流向相反,即从英国市场流向美国市场。这是我们预期的结果,因为从历史上看,美国和英国市场是紧密相连的。

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

Figure 4.8: Normalized Transfer Entropy among international stock market indices.

我们还通过计算转移熵矩阵中每一行的转移熵之和来计算每个市场对系统中总转移熵的边际贡献,我们还对转移熵矩阵进行归一化,使得所有值的范围从 0 到 1:

TE.marginal<-**apply**(TE.matrix, 1, sum)
TE.marginal.norm<-TE.marginal/**sum**(TE.marginal)
**print**(TE.marginal.norm)##  ^GSPC  ^FTSE ^GDAXI  ^N100  ^BVSP 
##  0.346  0.215  0.187  0.117  0.135

我们观察到,在所研究的时间段内,美国是最有影响力的市场,占总转移熵的 34.6%,其次是英国和德国,分别占 21.4%和 18.6%。日本和巴西是影响力最小的市场,标准化转移熵分别为 11.7%和 13.4%。

留给读者的一个实验是建立一个利用国际市场信息流的每日交易策略。提出的论点是,人们可以通过押注市场指数的期货来建立一个有利可图的策略,这些指数从观察到意外回报/运动的市场接收大量信息流。

有关使用更广泛的一组指数的扩展分析,请参见(Junior、Mullokandov 和 Kenett,2015)。作者使用信息理论框架开发了国际股票市场指数网络。他们使用不同国家的 83 个股票市场指数,以及它们的单日滞后值,在考虑不同的操作时间的情况下,探索相关性和从一个股票指数到另一个股票指数的信息流。他们发现转移熵是量化指数之间信息流的有效方法,滞后一天的指数之间的高度信息流与它们之间的当天相关性相一致。

其他应用

量化社交媒体和股票市场之间的信息流

投资者的决策不仅受到公司基本面的影响,还受到个人信念、同行影响以及新闻和互联网信息的影响。理性和非理性投资者的行为及其与市场效率假说(Fama 1970)的关系在经济学和金融文献(Shleifer 2000)中有很大争议。然而,直到最近,来自在线系统的大量数据的可用性才为大规模调查金融市场中投资者的集体行为铺平了道路。

一篇研究论文( Souza 和 Aste 2016)使用了本文研究的一些方法来揭示从社交媒体到股票市场的信息流,揭示了推文正通过非线性复杂的相互作用引起市场运动。作者提供的经验证据表明,社交媒体和股票市场之间存在非线性因果关系。他们利用了由与 DJIA 指数成分相关的社交媒体消息组成的大量数据集。通过使用信息理论的措施来应对社交媒体和股票市场之间可能的非线性因果关系,这项工作指出了关于线性耦合的结果中令人震惊的差异。得出两个主要结论:第一,社交媒体对股票收益的显著因果关系在大多数情况下是纯非线性的;第二,社交媒体主导了与股票市场的定向耦合,这种效应在线性模型中是观察不到的。在社会技术和金融系统的调查中,结果也作为模型充分性的经验指导。

图 4.9 显示了社交媒体和股票收益之间的显著因果关系,考虑了两种情况:非线性(转移熵)和线性 G-因果关系(线性 VAR 框架)。线性分析发现只有三只股票具有显著的因果关系:英特尔公司、耐克公司和华特迪士尼公司。非线性分析发现其他几只股票具有显著的因果关系。除了 3 只股票具有显著的线性因果关系外,其他 8 只股票呈现纯粹的非线性因果关系。

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

Figure 4.9: Demonstration that the causality between social media and stocks’ returns are mostly nonlinear. Linear causality test indicated that social media caused stock’s returns only for 3 stocks. Nonparametric analysis showed that almost 1/3 of the stocks rejected in the linear case have significant nonlinear causality. In the nonlinear case, Transfer Entropy was used to quantify causal inference between the systems with randomized permutations test for significance estimation. In the linear case, a standard linear G-causality test was performed with a F-test under a linear vector-autoregressive framework. A significant linear G-causality was accepted if its linear specification was not rejected by the BDS test. p-values are adjusted with the Bonferroni correction. Significance is given at p-value < 0.05.

在线性约束条件下获得的低水平因果关系与文献中类似研究的结果一致,其中发现股票回报显示出弱因果关系联系(Alanyali、Moat 和 Preis 2013、Antweiler 和 Frank (2004))和社交媒体情绪分析,至少在单独使用时,具有很小或没有预测能力(Ranco 2015),并且没有关于大多数股票运动的重要提前期信息(Zheludev、Smith 和 Aste 2014)。相反,非线性分析的结果揭示了更高层次的因果关系,表明线性约束可能忽略了社交媒体和股票市场之间的关系。

总之,( Souza 和 Aste 2016)是一个很好的例子,说明因果关系不仅复杂,而且会产生误导,从而进一步突出了选择用于量化因果关系的方法的重要性。

检测投资者情绪和加密货币价格之间的因果关系

在(Keskin 和 Aste 2019 年)中,作者使用本文中研究的信息论方法对社交媒体情绪和加密货币价格进行非线性因果检测。

使用这些技术对截至 2018 年 8 月的 48 个月期间的情绪和价格数据进行分析,对于四种主要的加密货币,即比特币(BTC)、ripple (XRP)、莱特币(LTC)和以太坊(ETH),作者在每小时的时间尺度上检测到情绪到价格和价格到情绪的重要信息转移。这项工作报告了非线性因果关系的规模比线性因果关系大一个数量级。

信息论研究在 BTC、长期资本成本和 XRP 发现了显著的非线性因果关系,在多个时间尺度上,在情绪对价格和价格对情绪两个方向上都是如此。对 BTC 和 LTC 的影响最强且最一致。图 4.10 显示了 BTC 情绪和 BTC 价格之间的转移熵结果。

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

Figure 4.10: Evidence that BTC sentiment and price are causally coupled in both directions in a non-linear way. Non-linear TE is calculated by multidimensional histograms with 6 quantile bins per dimension. Z-scores, calculated over 50 shuffles, show a high level of significance, especially during 2017 and 2018, in both directions.

本文的所有分析都是使用 Python 包(PyCausality)进行的,该包可从 https://github.com/ZacKeskin/PyCausality 的获得。

结论

理清因果关系可能极其困难。然而,统计工具可以帮助我们区分相关性和因果性。

在本文中,我们介绍了格兰杰因果关系的概念及其在线性向量自回归框架中的传统实现。然后,我们定义了信息论措施,以量化转移熵作为一种方法来估计非线性系统中的统计因果关系。

我们模拟了线性和非线性系统,进一步表明传统的线性 G-因果方法未能检测到系统中引入的简单非线性,而转移熵成功地检测到了这种关系。

最后,我们展示了如何转移熵可以用来量化全球股票指数之间的关系。我们还讨论了文献中的进一步应用,其中信息理论测量被用于量化投资者情绪和股票和密码市场运动之间的因果关系。

我们希望你喜欢这个偶然的因果旅程,并记住:负责任地量化因果关系。

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

模型解释和现实世界中的因果关系

原文:https://towardsdatascience.com/causality-in-model-explanations-and-in-the-real-world-9f57e17a9138?source=collection_archive---------26-----------------------

你不能总是改变一个人的输入来看输出。

在 Fiddler Labs,我们非常重视忠实于模型行为的模型解释。理想情况下,特征重要性解释应该浮出水面,并适当地量化所有且仅是那些对预测有因果关系的因素。如果我们希望解释符合法律规定,这一点尤为重要(例如, GDPR,第 13 条第 2f 款,人们有权*‘【了解】是否存在自动决策,包括特征分析)…和…关于所涉及的逻辑的有意义的信息’*),以及可操作的。即使在做出人类可以理解的后处理解释时,我们也必须保持对模型的忠实。

我们如何区分与结果相关的特征和导致结果的特征?换句话说,我们如何看待一个特性对一个模型输出或者一个现实世界任务的因果关系?让我们一个一个来。

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

解释模型中的因果关系很难

在解释模型预测时,我们希望量化每个(因果)特征对预测的贡献。

例如,在信用风险模型中,我们可能想知道收入或邮政编码对预测有多重要。

请注意,邮政编码可能是模型预测的因果关系(即,更改邮政编码可能会更改模型预测),即使它可能不是基础任务的因果关系(即,更改邮政编码可能不会更改是否发放贷款的决策)。然而,如果在现实世界的决策过程中使用该模型的输出,这两件事可能是相关的。

好消息是,因为我们可以访问模型的输入输出,所以我们可以用任意的输入来探测它。这允许检查反事实,不同于正在解释的预测的输入。这些反事实可能在数据集中的其他地方,也可能不在。

Shapley 值(博弈论的经典结果)提供了一种优雅的、公理化的方法来量化特征贡献。

一个挑战是,他们依赖于对大量反事实的探测,这些反事实大到无法计算。因此,有几篇关于近似 Shapley 值的论文,特别是对于特定类别的模型函数。

然而,一个更基本的挑战是,当特征相关时,并不是所有的反事实都是真实的。在如何解决这个问题上没有明确的共识,现有的方法在要考虑的一组确切的反事实上有所不同。

为了克服这些挑战,依靠观测数据是很有诱惑力的。例如,使用观察到的数据来定义应用 Shapley 值的反事实。或者更简单地说,用一个可解释的模型来模拟主模型的预测,然后用可解释的模型代替主模型进行解释。但是,这可能是危险的。

考虑一个信用风险模型,其特征包括申请人的收入和邮政编码。假设该模型在内部仅依赖于邮政编码(即 it 红线申请人)。基于观察数据的解释可能会揭示,由于申请人的收入与邮政编码相关,因此可以预测模型的输出。这可能会误导我们用申请人的收入来解释模型的输出。事实上,一个简单的解释算法会在两个完全相关的特征之间平分属性。

要了解更多,可以介入特性。一个改变邮政编码而不是收入的反事实将揭示邮政编码导致模型的预测改变。第二个反事实是改变收入但不改变邮政编码,它将揭示收入不变。这两个因素加在一起将使我们得出结论,邮政编码是模型预测的因果关系,而收入不是。

解释因果关系需要正确的反事实。

解释现实世界中的因果关系更加困难

上面我们概述了一种试图解释模型中因果关系的方法:研究当特征改变时会发生什么。要在现实世界中做到这一点,你必须能够应用干预。这通常被称为“随机对照试验”(当有两个变体时,也称为“ A/B 测试),尤其是在科技行业)。你将人群随机分成两组或更多组,并对每组应用不同的干预措施。随机化确保各组之间的唯一差异是您的干预。因此,你可以得出结论,你的干预导致了群体中可测量的差异。

将这种方法应用于现实任务的挑战在于,并非所有的干预措施都是可行的。你不能从道德上要求某人开始吸烟。在现实世界中,您可能无法获得正确检查因果关系所需的数据。

我们可以随意探测模型,但不能探测人。

自然实验可以为我们提供一个机会来研究我们通常不会干预的情况,比如流行病学和经济学。然而,这些为我们提供了一个有限的工具包,留下了这些领域的许多问题供讨论。

有一些关于和其他理论的提议,允许我们使用领域知识来区分相关性和因果关系。这些都是正在进行的辩论和研究的主题。

现在你知道为什么在模型中解释因果关系很难,而在现实世界中解释更难了。

要了解更多关于解释模型的信息,请发邮件至 info@fiddler.ai 。(图片鸣谢: pixabay 。)这篇文章是与 Ankur Taly 共同撰写的。

原载于 2019 年 7 月 31 日https://blog . fiddler . ai

CBNet:一种用于目标检测的新型复合主干网络体系结构综述

原文:https://towardsdatascience.com/cbnet-a-novel-composite-backbone-network-architecture-for-object-detection-review-ec98e8b7bc9b?source=collection_archive---------40-----------------------

截至目前,在 COCO 数据集上表现最好的对象检测网络是 CBNet,在 COCO 测试数据集上的平均精度为 53.3。

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

作者声称,结合更强大的主干可以提高对象检测器的性能。为此,他们提出了一种新的策略,通过相邻主链之间的复合连接来组装多个相同的主链。通过这样做,他们提出了一种更强大的主干网,称为复合主干网。

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

如上图所示,CBNet 由多个相同的主干网和相邻主干网之间的复合连接组成。从左至右,输出的每一个阶段,在一个助理骨干,这也可以被视为更高层次的功能。每个功能级别的输出通过复合连接作为输入的一部分流向后续主干的并行级。通过这样做,多个高级和低级特征被融合以生成更丰富的特征表示。

文章介绍了两种架构:双主干网(DB)三主干网(TB) 。从命名上可以猜到,DB 由两条相同的主链组成,TB 由三条相同的主链组成。性能差异将在本文稍后讨论。

为了合成来自主干的多路输出,本文引入了一个复合连接模块。该模块由一个 1x1 卷积和一个批处理归一化层组成。添加这些层是为了减少通道数量并执行上采样操作。

最终的主干(图中最右边的)被称为引导主干,用于对象检测。来自引导主干的输出特征被馈送到 RPN/检测头,而每个辅助主干的输出被馈送到其相邻主干。

复合样式

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

还有四种复合风格。

  • 相邻的较高级别组合是前面章节中解释的风格。使用复合连接块将来自辅助主干的每个输出特征馈入相邻主干。
  • 同级别合成是另一种简单的合成风格,它将前一个主干的相邻低级别阶段的输出反馈给后一个主干。如图所示,这种风格没有使用复合连接块。较低级别的主干中的特征会直接添加到相邻的主干中。
  • 相邻的低层成分与 AHLC 非常相似。唯一的区别是,来自前一个主干的较低级阶段的特征被传递到随后的主干。
  • 密集的更高层次构图的灵感来自 DenseNet 纸,其中每一层都连接到所有后续层,以在一个阶段中建立密集的连接。

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

上表是不同构图风格的对比。我们可以观察到 AHLC 风格优于其他复合风格。这背后的原因在论文中有很好的解释。作者声称,直接将前一个主干的较低级特征添加到后一个主干的较高级特征会损害后一个特征的语义信息。另一方面,将前一主干的较深特征添加到后一主干的较浅特征,增强了后一特征的语义信息。

结果

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

上表显示了在 MS-COCO 测试数据集上的检测结果。第 5–7 列显示对象检测结果,而第 8–10 列显示实例分割结果。它清楚地表明,利用更多的主干架构可以提升网络的性能。

结论

本文提出了一种新的体系结构,称为 CBNet。通过组成多个主干架构,所提出的网络将检测网络的准确度提高了约 1.5%至 3%。

值得进一步检查增加的参数大小和训练时间。

参考

[## CBNet:一种用于目标检测的新型复合骨干网络体系结构

在现有的基于 CNN 的检测器中,主干网络是基本特征提取的一个非常重要的组成部分。

arxiv.org](https://arxiv.org/abs/1909.03625) [## COCO 测试开发中用于对象检测的最先进的工作台

82 种方法的性能比较。

paperswithcode.com](https://paperswithcode.com/sota/object-detection-on-coco)

用 Keras 进行 CelebA 属性预测和聚类

原文:https://towardsdatascience.com/celeba-attribute-prediction-and-clustering-with-keras-3d148063098d?source=collection_archive---------11-----------------------

关于如何使用高效的基于 MobileNetV2 的模型检测和聚类多达 40 个面部属性的完整指南。

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

A synthetic face obtained from images of young smiling brown-haired women

在本文中,我们讨论面部属性预测。我们将检查数据集并指出它的弱点。此外,我们将构建和训练一个深度模型,并最终讨论总体结果。

介绍

面部属性预测是一项关于推断面部属性集的计算机视觉(CV)任务。示例属性有头发的颜色发型年龄性别等。

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

Some facial Attributes. Source.

一般来说,面部属性预测是一项具有挑战性的任务:它首先涉及面部定位,然后是属性预测。此外,人脸由于其复杂的外观而固有地难以分析。通过面部变化,面部的外观可以被改变,变得更加复杂。面部变化最常见的形式如下:

  • 遮挡: 发型妆容眼镜(尤其是太阳镜)、帽子等种类的物体可以隐藏模型检测人脸及其属性所需的有意义的像素。在极度遮挡的情况下,模型可能根本无法定位人脸!
  • **光照:**极端闪电或极端阴影会让检测算法的工作变得更加困难(如果不是不可能的话),就像遮挡一样。
  • 表情: 情绪可以改变一张脸正常出现的方式。如果检测系统在训练期间从未见过受情绪影响的人脸,它可能无法正确检测到它们。
  • **姿态:**根据滚动 (x 轴)偏转 (z 轴)e 俯仰 (y 轴)的高度旋转最终可以改变人脸的外观,并隐藏其面部特征。

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

Examples of challenging face variations.

因此,卷积模型在困难的人脸样本上进行训练非常重要,以便很好地推广到在野外捕获的人脸(在任何条件下捕获的人脸)。

面部属性预测不仅是一项学术挑战,也是改进现有应用的一种方法。例如,照片应用程序可以检测“微笑”属性,以便在给定的序列中确定哪张照片是最好的。

数据探索

一个很好的、广泛的、多样化的数据集是 CelebA 数据集 **。**它是一个大规模的人脸属性数据集,拥有超过 20 万张名人图片,涵盖了大量的变化,每张图片都有 40 个属性标注。

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

The complete list of facial attributes provided by CelebA.

所以,首先要做的是下载数据集。通过在终端中执行以下代码,可以在或 Kaggle 上找到:

# install kaggle first: 
$> **pip install kaggle**# set your Kaggle API key:
**os.**environ['**KAGGLE_USERNAME**'] = "YOUR_USERNAME"                       **os.**environ['**KAGGLE_KEY**'] = "YOUR_API_KEY"# then download: 
$> **kaggle datasets download -d jessicali9530/celeba-dataset**

下载并解压之后,我们可以将它加载到我们的 Python 环境或 Jupyter 笔记本中。为此,我准备了完成所有枯燥工作的CelebA类,将数据集加载到一个漂亮的熊猫DataFrame:

现在,加载数据集(我假设它的路径是celeba-dataset\)并最终选择面部属性的子集是小菜一碟。在示例代码中,我们删除了三个特性。

# load the dataset with 37 out of 40 features:
celeba = **CelebA**(drop_features=**[**
    '**Attractive**',
    '**Pale_Skin**',
    '**Blurry**',
**]**)

之后,我们可以展示一些随机样本来理解celeba数据帧的结构。

# shows five random samples
celeba.attributes.**sample**(5)

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

Random samples. Every attribute is binary: 0 means absent, 1 means present.

现在我们知道每个例子都关联到一个二进制标签的向量,其中每个属性可以是 01 。因此,知道一个属性属于多少个面是非常有用的(我省略了这一点,但是数据集的每个图像都描绘了一个面)。通过统计某个属性出现 1 的次数,就可以计算出它的绝对频率**(甚至是 相对频率 除以样本总数)。**

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

The relative frequency of every attribute.

在这里,我们可以清楚地观察到一个数据不平衡问题。面部属性的频率变化很大,而不是彼此大致相等。出现频率在 10%以下的有稀有属性 ( BaldMustacheDouble_Chin等),出现频率在 70%以上的有几个非常常见属性 ( No_BeardYoung)。

这展示了另一个问题:数据集对年轻人和没有胡子的人有偏见。

当数据不平衡时,模型很容易过拟合数据点。在这种情况下,它可以学习对每个常见属性总是输出一个 1 ,对稀有属性总是输出一个 0 :模型发现这个策略(预测 0 和 1)是好的(这是不成立的,因为它不学习模式)。按照这种方式,模型的输出预测将看起来像[1, 0, ..., 0, 1]向量,对每张图像都一样。

如果发生这种情况,产生的模型是相当愚蠢的:它只会浪费计算资源,因为它可以被简单的代码(例如,随机猜测,或一个常量值)所取代。

好消息是,可以通过使用适当的损失函数来缓解这个问题(下一节将详细介绍)。

最后,上图展示了一些摄自 CelebA 的图片:

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

Source: CelebA.

模型

我们将要构建的模型主要基于 MobileNetV2 架构,基本上是相同的模型,但是没有顶级分类层(MobileNetV2 构建为输出 1000 个类别概率)。

首先,该模型一次获取一个图像(3 个通道,大小为 224×224)作为输入,并输出一个大小为 n 的概率向量(通常,大小根据您想要检测的属性的多少而变化)。向量的第 i 个元素是一个介于 0 (属性 i 不存在)和 1 (属性 i 存在)之间的实数。

请注意,输出向量可以包含多个非零元素,这意味着多个属性可以属于一个面。

模型架构

为了定义模型架构,我们必须加载没有顶层的 MobileNetV2 架构,将输入大小设置为 224×224,并添加新的顶层。以下代码实现了所有需要的操作:

然后,要创建模型并显示其摘要(层、参数数量等),请运行以下代码:

model = **build_model**(num_features=**celeba.num_features**)
model.summary()

如您所见,创建模型很简单。在这里,我们将回顾新添加的顶层:

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

The model’s top layers. Image created with Netron.

  • **globaveragepool2d:**使用内核 big 作为最后卷积层的内核来产生 1×1 特征图。因此,如果最后的卷积层输出 n 个特征图,每个都是宽 w 和高 h ,全局平均池层将对每个特征图应用一个核( wh ,以获得 n 置信度得分。当核与特征图一样大时,结果是一个标量,或者等价地,一个 1×1 的特征图。这样做可以减少全连接(密集)层的数量(通常至少为 2 层,由于 GlobalAveragePooling,只需要一层),从而减少参数数量、训练时间和加速推理。GlobalAveragePooling 层是 GoogleLeNet 模型的关键创新之一。

请注意,如果没有 GlobalAveragePooling 图层,则需要一个展平图层。展平(w,h,n)要素地图会生成一个具有 w×h×n 个单位的图层,而不是通过应用全局平均池生成的 n 个单位(因此,参数的数量要少得多)。

  • **密集:**之后,我们使用一个激活了 1536 个单元 ReLU 的密集层,来执行置信度得分的非线性组合(这增加了模型的容量及其辨别能力)。
  • BatchNormalization: 模型基于非常深的架构,有几百层。为了加速训练并减少渐变消失或爆炸的机会,我们应用批量归一化,即 归一化缩放在应用激活函数之前移动 输入。批处理规范化通过学习四个附加参数来实现这一点。在某些情况下,批处理规范化具有正则化效果。
  • **退出:**根据一个概率 p 在训练中随机停用单位。以这种方式,一个神经元(单元)较少依赖于它的相邻单元。这迫使模型更好地概括。此外,dropout 可以被视为一种简单有效(但近似)的方法来训练许多神经网络的集合:在每次迭代中,不同的神经元被停用,从而产生不同的网络。当训练结束时,得到的网络大致表现为对训练期间获得的所有不同网络进行平均。
  • 密集:这是网络的输出层。这里我们使用 sigmoid 作为激活函数,因为它允许具有不互斥的类(属性)(对于 softmax 层,只有一个输出元素可以是 1),更重要的是,直接估计每个属性的概率。

最后,该模型创建起来非常简单,甚至很小:它只有 4.3M 的参数,重量轻,速度快,也适合移动和网络应用。

培养

有时,训练神经网络来解决给定数据集的某个任务,可以被视为试图使网络符合生成数据集和真实世界数据的真实底层概率分布(数据集只是整个数据的一部分)。通常,真实的概率分布是未知的,并且由于在训练期间使用了数据集,因此只能部分估计

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

Trying to capture the data distribution through training-data. Source.

训练数据的数量直接影响我们试图训练的网络的泛化能力。简而言之,泛化误差随着训练数据量的增加而下降。

坏消息是,通常,训练数据不能捕获整个概率分布,因为不可能有覆盖分布的特定情况的例子。

实际上,我们可以做的是稍微“编辑”训练数据,以便有意引入一些变化(例如,旋转、移位……)—我们假设真实世界的数据可能会有这样的变化。

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

Example of image augmentations.

数据扩充

数据扩充的实践是增加训练集规模的有效方法。增加训练示例允许网络在训练期间“看到”更多样化但仍有代表性的数据点。

下面的代码为训练集定义了一组扩展:旋转移动剪切翻转缩放

请注意,验证集和测试集都不能增加。

然后我们定义两个数据生成器:一个用于训练数据,另一个用于验证数据。

当我们处理不适合内存的大数据集时,我们必须找到一种方法只加载实际需要的数据。

一个数据生成器能够直接从源文件夹中加载所需数量的数据(一个小批量的图像),将它们转换成训练数据(馈送给模型)和训练目标(一个属性向量——监督信号)。

对于我的实验,我通常设置batch_size = 80。一般来说,介于 64 和 128 之间的值应该可以。通常,您希望根据计算资源和模型性能来增加/减少批量大小。

优化器、损失函数和指标

此时,我们选择具有默认值的adadelta优化器(adam 优化器也很好,但它的性能似乎稍差一些):与 adam 一样,adadelta 是一个几乎不需要调整的优化器,因为它能够自动调整学习速率(当出现问题时速度会变慢,或者朝着有希望的方向移动得更快)。

下一步,选择**损失函数:**负责监控模型的性能并指导优化过程。

我发现一个好的属性预测任务的损失函数,是一个能够区分属性向量的单个元素的函数,而不是将整个向量视为单个对象。我的意思是损耗一定要明白,向量[0, 1, 1, 0]和这个向量[1, 0, 0, 1]差很多(损耗要高);有意义的是 1 和 0 的数量,以及输入向量中单个元素的精确位置

像平均绝对误差(MAE)、均方误差(MSE)或均方根误差(RMSE)这样的损失函数不能进行这种区分:直觉上,它们只是对向量上的 1 进行计数,并对它们求平均值,因此丢失了关于位置的信息。

相反,像二元交叉熵余弦接近度这样的损失函数是理想的选择**。从经验上看,后者似乎表现稍好。**

最后一步,是选择我们的目标绩效指标。在这种情况下,我们关心的是最大化模型预测的二进制精度。

最后,我们可以编译我们的模型:

model**.compile**(loss='**cosine_proximity**',
              optimizer='**adadelta',
**              metrics='**binary_accuracy**')

适合的

在训练之前,模型有助于定义一个或多个回调。挺好用的一个,有:ModelCheckpointEarlyStopping

  • ModelCheckpoint: 当训练需要大量时间来达到一个好的结果时,通常需要多次迭代(或者一些代价高昂的迭代)。在这种情况下,最好只在改进度量的时期结束时保存最佳执行模型的副本
  • 提前停止:有时,在训练期间,我们可以注意到泛化差距(即训练和验证误差之间的差异)开始增加,而不是减少。这是过拟合的症状,可以用很多方法解决(减少模型容量增加训练数据数据增加正则化退出等)。通常,一个实用有效的解决方案是当泛化差距越来越大时停止训练

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

Early stopping. Source.

实际上,我只使用了 ModelCheckpoint 回调,因为不需要使用提前停止。无论如何,如果您想通过改变模型架构、超参数、损失和优化器来玩游戏,建议使用早期停止。

下面的代码将开始训练,将拟合信息收集到提供两条学习曲线的history变量中:一条是损失曲线,另一条是准确度曲线;两者都可以被绘制出来。

通常我把num_epochs设置在 1020 之间。注意,该模型在前两个时期达到大约 89%的准确度。但是需要更长的训练来保持在大约 91%的精确度(至少这是我得到的最大精确度)。

注意:每个历元花费大约 40 分钟来完成(在 Google Colab GPU 上)。

估价

为了评估数据集的测试分区上的模型,我们必须设置测试数据生成器,并让模型对每个测试数据进行预测:

我得到的测试精度大约是 90.95% 。具体而言,每个面部属性以以下准确度被检测:

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

Accuracy of each facial attribute. The model presented here is compared to a SOTA approach, which uses a combination of two kind of networks: LNet and ANet (more details here).

聚类和结果

一旦我们有了一个工作模型,我们就可以做类似集群这样的事情。对于此任务,聚类的目标是将图像分组为聚类,其中每个聚类在其包含的图像中共享最大可能数量的面部属性。

换句话说,我们希望对面部属性相似的图像进行分组,比如有一个 金发女郎群戴着帽子和眼镜的家伙 等。

例如,如果我们要对以下十个属性进行聚类:

'Wearing_Lipstick'
'Smiling'
'No_Beard'             
'Heavy_Makeup'
'Bald'
'Male'           
'Young'
'Eyeglasses'
'Blond_Hair'
'Wearing_Hat'

我们可能会得到这些集群:

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

**Top left: “**smiling” cluster. Top right: “blonde” cluster. Bottom left: “hat” cluster. Bottom right: “eyeglasses” cluster.

在这里,我们可以看到每个聚类在我们选择的属性中捕获了一个或多个面部属性。

注意:以上聚类是通过对模型的预测运行标准聚类算法(如 K-Means)获得的。

为了更好地理解集群捕获的属性,我们可以总结它,并观察集群的总结。

一个聚类可以通过提取其*【区别特征】*来概括。这可以通过计算描述集群的主成分(例如使用 PCA)来完成。在这种情况下,我们有脸的集群,所以我们可以尝试计算每个集群的特征脸,看看它看起来像什么…

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

Left: clusters. Right: eigenfaces of the corresponding clusters.

令人惊讶的是,一个聚类的特征脸能够通过产生一个合成脸(不属于该聚类)来概括整个聚类,该合成脸的面部属性是该聚类所捕获的。

这样,我们就能一眼看出一组图像中有哪些突出的面部属性,分组到同一个聚类中。

结论

总之,像 MobileNetV2(或 Inception 和 Resnet 模型)这样设计良好的通用模型,使得构建有效的特定于任务的模型成为可能。

为了理解数据集的结构、数据和最终的缺陷,分析数据集并观察它的一些样本总是一个好的做法。

属性预测是一项可以改进许多现有应用和领域(例如,安全、摄影等)的任务。

我省略了关于集群的代码,因为它有点长且复杂。无论如何,你可以在这个仓库找到所有的代码。

我推荐使用 Jupyter 笔记本版本的代码进行实验。

希望你喜欢它,并感谢阅读它!

参考

  • 面部属性预测和聚类的迁移学习。智慧城市与信息化国际会议。2019 年,新加坡施普林格。
  • 刘,,等,“野外深度学习人脸属性”IEEE 计算机视觉国际会议论文集*。2015.*
  • 麻省理工 6。S191:深度学习介绍
  • 古德菲勒、伊恩、约舒阿·本吉奥和亚伦·库维尔。深度学习。麻省理工学院出版社,2016 年。
  • 克里斯蒂安·塞格迪等着《用回旋深化》IEEE 计算机视觉和模式识别会议论文集。2015.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值