线性回归的直观入门
走向稳健估计
…或者说,这意味着什么?
估计器ŷ穷尽了预测器 x₁ 和 x₂的可用信息
介绍
线性回归,或最小二乘回归,是机器学习最简单的应用,也可以说是最重要的。许多人每天都在应用方法,却没有意识到。无论何时计算算术平均值,我们都有一个线性回归的特例——也就是说,响应变量的最佳预测值是响应本身的偏差(或平均值)!
最小二乘法的核心思想是最小化“误差”的平方和,即调整未知参数,使观测值和计算值之差的平方和最小化。
关于线性回归,已经有很多关于它的文章了,为什么还要再写一篇呢?我的目的不是“展示它是如何做到的”,而是说明线性回归是一个更基本概念的方便和实用的例子——估计——并为读者开发一种对机制的直觉。
基础知识
“线性模型”中的“线性”一词不是指模型的单个项,例如它们是否是平方的,或者有平方根,等等。许多人惊讶地发现,预测变量可以应用各种非线性变换,和经常被应用以创建有效的线性模型。相反,“线性”是指模型的整体行为:线性模型是预测变量的线性组合产生响应变量的预测。这意味着
是一个线性模型,其中 x₁ 可能是(使用我们数据中的一些示例“测量”值):
游戏规则
我发现许多人都反对我们可以随心所欲地操纵变量。但是为什么我们首先接受预测变量的线性组合是进行预测的有效方法呢?最小二乘回归的唯一规则是残差的均值必须为零,不相关,并且是同方差的(这是一个有趣的词,表示残差的方差必须是常数)。我们可以做任何事情,而且事实上必须经常做很多事情,为了满足这三条规则!
为了推广,我们必须介绍一些线性代数。我们也可以用向量符号将我们的模型写成:
其中预测变量以列向量的形式给出:
在这种形式下,我们可以开始更好地理解本文顶部的几何表示的图像。显而易见,我们把预测看作是向量的和,但是什么是*(*)的残差呢?是 X₁ 和 X₂ 不包含的所有信息的总和,并且与两者正交!这里我们有截距,或偏差项,开始发挥作用。当我们扩展到更高维度时,“截距”的概念实际上并没有太多的直观意义,因为我们无法在一个图上可视化所有变量。相反,这是我们为了“把我们的拇指放在秤上”而添加的一个偏差项,可以说,是为了使我们的预测比我们只使用预测变量时更准确。如果我们重新绘制包含偏差项的图,我们会得到如下结果:
添加偏差项以将残差的平均值设置为零
而且我们看到,偏置项, b ,降低了残差的大小。(注意:这并不完全准确,因为残差应该与和 X₂ 和b正交,但可惜我们仅限于三个空间维度)。当然,我们只查看对应于和 X₂ 的单个值的单个预测,而实际的线性模型会对和*【x₂的每个值进行预测。偏差项计算为将所有残差的平均值设置为零的值。***
推广回归方程
让我们进一步用回归方程来说明如何确定系数。首先,我们可以从用向量写模型转移到矩阵符号。我们先把x₀x₁和 X₂ 组合成一个矩阵:
然后简化我们的回归方程:
这里,由于我们已经讨论过残差是,我们添加了残差项,因为我们知道它们也必须包括在内,以获得响应变量的实际测量值。请记住,残差与所有预测变量和响应变量的预测正交,这意味着它们包含无法解释的偏差,这些偏差可能存在于我们没有观测到的其他预测变量中。
我们不去研究解的推导,但是如果我们求解方程的值,我们得到:**
如果你需要一些可视化矩阵乘法的帮助,我们有:
平均值是特殊的
在最简单的情况下,……即位置参数的估计,……这当然是通过样本均值来实现的。
现在,让我们考虑一个线性回归的特例,其中我们只有——也就是说,我们只有一个单位列向量。这将先前的矩阵乘法减少到:**
代入回归方程,我们得到:
希望你认识到这一点!它说的是,只有一个响应变量的线性模型的最佳预测值是响应变量本身的平均值!
为什么这很重要?这表明最小二乘回归所需的假设 也适用于平均值的计算。这些是:
- 残差具有均值为零的高斯分布。正如我们在上文中了解到的,当我们计算偏差项时,回归行为本身满足了这一点。
- 残差在所有预测值中具有恒定的方差(同方差)。
- 残差是独立同分布的。不存在时间序列数据中常见的相关性或自相关性。
因为我们只处理一个单一的响应变量,所以第二点和第三点可以看作是在谈论变量本身。如果我们的抽样很差,与其他范围相比,在特定范围的值中存在过度代表性,或者如果样本完全相关(即值相互依赖),则平均值是变量的最佳估计值 而不是 。
众所周知,如果真实分布稍微偏离假设的正态分布,样本均值可能会有灾难性的不良表现。
如果我们从平均值反向回到线性模型,我们也可以说最小二乘回归是 而不是 对于不满足我们规则的问题的最佳回归方法。
那又怎样?
最小二乘回归并不总是有效,但我们可以尝试许多其他的机器学习技术,对吗?好吧,在我们把神经网络扔向一堵墙,看看有什么粘在一起之前,让我们考虑一下我们能对这个缺点做些什么。我不是统计学家,所以在我批评整个统计学领域的基础之前。),让我引用一位在 1964 年调查过这个问题的统计学家的话:
有趣的是回顾估计理论的起源,即高斯和他的最小二乘理论。高斯充分意识到,他假设基础正态分布和二次函数的主要原因是数学上的,即计算上的便利。在后来的时代,这一点经常被遗忘,部分原因是因为中心极限定理。但是,如果要说实话,中心极限定理最多能解释为什么实践中出现的很多分布都是近似正态的。重音在“大约”这个词上。
胡伯,P. J. 1964。位置参数的稳健估计。
数理统计年鉴 35(1):73–101。https://doi.org/10.1214/aoms/1177703732
Huber 被认为是 稳健估计 研究领域的创造者之一,并且是贯穿本文的各种引文的来源。他的目标是创建最小二乘估计的替代估计,能够更好地处理异常值或其他偏离最小二乘估计规则的情况。正如他指出的,在所有其他选择中选择最小二乘法的主要动机之一是为了方便解析解。对于早于 20 世纪末的任何历史时期来说,这都是一个巨大的便利。然而现在,对于我们人类对时间的感知来说,解决回归问题的数值方法通常和解析解一样快。存在更好的评估者。
后续步骤
人们很自然会问,是否可以通过最小化另一个误差函数而不是它们的平方和来获得更高的鲁棒性。
让我们把估计量的概念简化为“距离的度量”。我们通常会想到欧几里德距离, a + b + … ,但这只是测量距离的无限方式之一。如果你在曼哈顿的城市网格上,这是一个几乎无用的测量来确定你和你试图到达的角落餐馆之间的距离。
到午餐的最短距离是多少?
绿线,欧几里德距离,是最短的…但也是不可能达到的。事实证明,红色、蓝色和黄色的线,也就是俗称的“出租车距离”,长度都是一样的。如果你想知道仅仅根据距离你应该如何到达某个地方,计算机不能为你计算出最短的路线。然而,这也意味着最短路线的解决方案是健壮的**:如果发生了灾难性的错误(用 Huber 的话说),很容易找到替代路线。在下一篇文章中,我们将讨论这些替代方案,了解它们的特性,并在这样做时,扩展回归以处理比最小二乘法更复杂的情况。**
这使我们更接近准确的估计的目标。
什么是卷积神经网络?
基本 CNN 的模板
卷积神经网络基本元素的可视化
可视化是理解丰富概念的一个很好的工具,特别是对于该领域的初学者。在本文中,我们将使用视觉辅助工具来浏览卷积神经网络的基本元素。本文首先为一个具有不同构件的基本 CNN 提供一个模板(可视化的),然后讨论每个构件最常用的元素。
基本 CNN 模板:
一个基本的 CNN 由三种层组成。输入、隐藏和输出如下所示。数据通过输入层进入 CNN,并在到达输出层之前通过各种隐藏层。输出层是网络的预测。根据损失或误差,将网络的输出与实际标签进行比较。对于要学习的网络,计算该损失相对于可训练权重的偏导数,并且通过使用反向传播的各种方法之一来更新权重。
基本 CNN 的完整视觉模板可以在下面看到。
基本 CNN 的模板
CNN 的隐藏层
网络中的隐藏层提供了转换数据的基本构件(输入层或先前隐藏层的输出)。大多数常用的隐藏层(不是全部)都遵循一个模式。它首先将一个函数应用到它的输入,然后转移到池化、规范化,最后在它可以作为输入提供给下一层之前应用激活。因此,每一层可以分解成以下 4 个子功能
- **层功能:**卷积或全连接层等基本变换功能。
- **池化:**用于改变特征图的空间大小,增加(上采样)或减少(最常见的)它。例如最大池化、平均池化和取消池化。
- **归一化:**该子函数将数据归一化,使其均值和单位方差为零。这有助于处理消失梯度、内部协变量移位等问题。(更多信息)。最常用的两种标准化技术是局部响应标准化和批量标准化。
- **激活:**应用非线性并限制输出过高或过低。
我们将逐一介绍每个子功能,解释它们最常见的例子。
还有更复杂的 CNN 架构,有各种其他层和相当复杂的架构。不是所有的 CNN 架构都遵循这个模板。
1.层功能
最常用的层函数是全连接、卷积和转置卷积(错误地称为解卷积)层。
a.完全连接的层:
这些层由输入和输出之间的线性函数组成。对于 i 输入节点和 j 输出节点,可训练权值为 wij 和 bj。左图说明了 3 个输入节点和 2 个输出节点之间的全连接层是如何工作的。
b.卷积层:
这些图层应用于 2D(和 3D)输入要素地图。可训练权重是一个 2D(或 3D)核/过滤器,它在输入要素地图上移动,与输入要素地图的重叠区域生成点积。以下是用于定义卷积层的 3 个参数
- 内核大小 K: 滑动内核或过滤器的大小。
- 步长 S: 定义在执行点积生成输出像素之前内核滑动了多少
- 填充 P: 输入特征图周围插入的零的帧大小。
下面的 4 幅图直观地解释了大小为( i ) 5x5 的输入上的卷积层,其中内核大小( k )为 3x3,步长( s )和填充( p )
动画卷积层(来源:Aqeel Anwar)
步幅和填充与输入特征图一起控制输出特征图的大小。输出大小由下式给出
c.转置卷积(反卷积)层:
通常用于增加输出特征图的大小(上采样)。转置卷积层背后的想法是撤消(不完全)卷积层。正如卷积层一样,它也是由步长和填充定义的。如果我们对输出应用所提供的步幅和填充,并应用所提供大小的卷积核,它将生成输入。
转置卷积层(来源:Aqeel Anwar)
要生成输出,需要执行两件事情
- 零插入( z ):在原始输入的行和列之间插入的零的数量
- padding(p’):输入特征图周围插入的零的帧大小。
下面的 4 幅图直观地解释了在不同大小( i )的输入上的转置卷积层,对于 3x3 的内核大小( k )和不同步长( s )以及填充( p )而输出 (o) 固定为 5×5
动画转置卷积层(来源:Aqeel Anwar)
关于转置卷积层的深入细节可以在下面找到
通过动画 gif 和 python 代码解释。
towardsdatascience.com](/what-is-transposed-convolutional-layer-40e5e6e31c11)
2.联营
最常用的池是最大、平均池和最大平均取消池。
最大/平均池:
基于选择由内核定义的感受域中的最大值/平均值,不可训练层用于减小输入层的空间大小。核以给定的步幅滑过输入特征图。对于每个位置,输入特征图中与核重叠的部分的最大值/平均值就是相应的输出像素。
动画最大池层(来源:Aqeel Anwar)
取消轮询:
基于将输入像素放置在由内核定义的输出的感受域中的某个索引处,不可训练层用于增加输入层的空间大小。对于一个非池层,在网络的早期需要有一个相应的池层。来自相应池层的最大/平均值的索引被保存并在非池层中使用。在非池化图层中,每个输入像素被放置在输出中池化图层中出现最大值/平均值的索引处,而其他像素被设置为零
3.正常化
通常在激活函数之前使用归一化来限制无限制激活将输出图层值增加得过高。通常使用两种类型的标准化技术
a.LRN 当地反应正常化:
LRN 是一个不可训练层,它在局部邻域内对特征图中的像素值进行平方归一化。基于邻域定义,有两种类型的 LRN:通道间和通道内,如下图所示。
**左:**通道内 LRN … 右:通道间 LRN
b.批量标准化 BN:
另一方面,BN 是一种可训练的标准化数据的方法。在批量标准化中,隐藏神经元的输出在被馈送到激活函数之前以下面的方式被处理。
- 将整批 B 标准化为零均值和单位方差
- 计算整个小批量产量的平均值: u_B
- 计算整个小批量产量的方差:s igma_B
- 通过减去平均值并除以方差来标准化小批量
2.引入两个可训练参数( Gamma: scale_variable 和 Beta: shift_variable)来缩放和移动标准化小批量输出
3.将该缩放和移位的标准化小批量馈送到激活功能。
下面是这两种标准化技术的总结
关于这些标准化技术的详细文章可以在 这里 找到
4.激活
激活函数的主要目的是引入非线性,因此 CNN 可以有效地映射输入和输出之间的非线性复映射。根据基本要求,可以使用多种激活功能。
- **非参数/静态函数:**线性,ReLU
- 参数函数: ELU,双曲正切,sigmoid,Leaky ReLU
- 有界函数: tanh,sigmoid
下面的 gif 形象地解释了最常用的激活函数的本质。
动画激活功能(来源:Aqeel Anwar)
最常用的激活函数是 ReLU。当涉及到更深的神经网络时,诸如 tanh 和 sigmoid 的有界激活函数遭受消失梯度的问题,并且通常被避免。
5.损失计算:
一旦定义了 CNN,就需要选择一个损失函数来量化 CNN 预测与实际标签的差距。然后,在梯度下降法中使用这种损失来训练网络变量。像激活函数一样,损失函数有多种选择。
回归损失函数
- 平均绝对误差:估计值和标签是实数
- 均方差:估计值和标签是实数
- 胡伯损失:估计值和标签是实数
分类损失函数
- 交叉熵:估计值和标签是概率(0,1)
- 铰链损耗:估计值和标签是实数
这些损失函数的细节可以在下图中看到
动画 ML 损失函数(来源:Aqeel Anwar)
6.反向传播
反向传播不是 CNN 的结构元素,而是我们通过在梯度变化(梯度下降)的相反方向上更新权重来学习潜在问题的方法。关于不同梯度下降算法的深入细节可以在这里找到。
总结:
在这篇文章中,介绍了一个基本 CNN 的不同元素的动画可视化,这将有助于更好地理解它们的功能。
奖金:
可以在下面的链接中找到这个主题和机器学习中许多其他重要主题的紧凑备忘单
ML 面试的视觉备忘单(www.cheatsheets.aqeel-anwar.com)
medium.com](https://medium.com/swlh/cheat-sheets-for-machine-learning-interview-topics-51c2bc2bab4f)
如果这篇文章对你有帮助,欢迎鼓掌、分享和回复。如果你想了解更多关于机器学习和数据科学的知识,请关注我@Aqeel an war或者在LinkedIn上与我联系。
通过可视化备忘单浏览机器学习中的不平衡类
什么是不平衡的训练数据,以及如何通过精确度、召回率和 f1 分数来解决它。
许多详细的文章解释了不平衡训练样本的问题以及如何应对它。在这篇文章中,我把对问题的理解总结成一张可视化的小抄。我经常发现它很有用,因为每当我不得不回到基本定义时(或者我有一个面试安排),它就派上了用场。
下面的备忘单从为什么准确性并不总是给出与您的分类算法相关的正确见解的背景开始,然后继续定义其他有意义的性能指标。然后,备忘单提供了一个示例,展示了如何为一个三类分类问题计算这些指标。一旦通过适当的指标确定了问题,备忘单就会解释许多可能的解决方案来克服不平衡的训练数据问题。
奖金:
可以在下面的链接中找到这个主题和机器学习中许多其他重要主题的紧凑备忘单
ML 面试的视觉备忘单(www.cheatsheets.aqeel-anwar.com)
medium.com](https://medium.com/swlh/cheat-sheets-for-machine-learning-interview-topics-51c2bc2bab4f)
如果这篇文章对你有帮助,欢迎鼓掌、分享和回复。如果你想了解更多关于机器学习和数据科学的知识,请关注我@Aqeel an war或者在LinkedIn上与我联系。
编写更好的函数的演练
从例子中学习如何编写更好的、可重用的函数
介绍
我看到很多初学者在编程时不使用函数。当我强迫他们写一个时,他们只是将一堆代码复制粘贴到一个函数中,然后称之为完成。
该函数将没有参数,没有各种数据结构的灵活性,也没有可重用性。变量将在函数内部声明。各种地方会用数字代替变量。也不会有类型检查,不会有测试来看它是否会崩溃。这样的例子不胜枚举。该功能将为他们的特定任务工作,就是这样。
在本文中,我将尝试向您介绍一个代码示例以及编写更好的函数背后的思考过程。我希望看到这个例子并尝试其中的一些想法会让您对如何为将来编写更好的函数有一个直观的感觉。
示例代码
最近,我在做一个计算机视觉作业,要求我们从头开始写卷积。我会仔细阅读这些代码。
技巧 1:当编写一个函数时,要记住的第一点是让他们做一件事,而且只做一件事。
这个技巧将帮助你保持你的函数简短。不要把所有东西都放进去。让我们来看看我们写的读取图像文件的函数。
我们从这样的事情开始:
我们读取一个图像,将其转换为灰度,将其转换为一个 numpy 数组,然后将其返回。这是一个简洁的函数,但是不够灵活。
改进 1:我们不总是想要灰度图像。因此我们包含了一个论点。这是我们的下一个提示。
技巧 2:在我们的函数中,我们使用库。我们传递给这些库的参数也为我们的函数提供了很好的参数。
这是一个非常有用的提示。特别是如果你使用 matplotlib 这样的东西,并且你不知道一个函数需要的所有参数,只需要包含一个**kwargs
作为你的函数的参数,并愉快地将它传递给 matplotlib。
我们可能想要改变的另一件事是到 numpy 数组的转换。如果用户不需要 numpy 数组,而只需要一个 PIL 图像,那该怎么办?给他这个选择。
提示 3:给用户很多选择,让用户在不同的方向使用你的函数输出。
我们的功能现在非常灵活,可以在许多其他地方重用。即使不是同一个,但有微小的变化。例如,通过更改默认参数来重用它。这提醒了我,我们需要明智地对待我们的违约。在我们当前的例子中,mode = None.
然而,就像我之前提到的,我们只需要灰度图像。因此,我们应该将其初始化为"L"
,而不是我们不想做的None.
:
然而,我们也不想做:
因此我们可以创建另一个函数,如下所示:
看看我们的功能建立得多好。您可以做的另一件事是,不要手动传递图像文件的名称,而是使用代码检索它们。
家庭作业:
谷歌如何获得所有图像扩展?谷歌如何使用全球图书馆检索所有文件与某些扩展名。然后马上自己编码。
提示 4:让你的代码为多种数据结构工作
最后一个技巧是在适用的地方为不同的数据结构包含不同的行为。重点是不要破坏代码,让它为大多数事情工作。
结论
这就是本文的全部内容。我希望这篇文章能帮助你在将来写出更好的代码。你可以看到,与我们开始的地方相比,现在read_image
函数几乎可以在任何地方使用。你不会从最好的函数开始。但是不断重构你的代码,你会改进很多。
在结束之前,我想指出的一点是,尽管你已经学会了所有这些技巧,但不要过度使用。保持你的功能简约但超级有用。
~快乐学习
在 GitHub Profile 上扩展您的网络的方法
简单解释一下如何在 GitHub 上链接你的社交媒体页面
介绍
建立你的关系网和分享你的作品可能是让你的名字出现在社区的最好方式。
你们中的一些人可能已经知道,GitHub 最近增加了一个隐藏的功能,可以让你自定义你的 GitHub 个人资料页面。下面是如何解锁隐藏功能的教程。
关于如何定制 GitHub 个人资料页面的简单说明
towardsdatascience.com](/unlocking-githubs-hidden-feature-in-3-minutes-2c21c8e47a20)
GitHub 个人资料页面是 GitHub 的门面,你想让它尽可能吸引人。我个人认为,你应该尽可能简单地提供尽可能多的信息——提供你的项目、网站或社交媒体的链接。通过这样做,你可以很容易地与查看你的 GitHub 的人分享你的作品,你也有机会与他们联系。
在这篇文章中,我想演示如何简单地将你的社交媒体页面与 GitHub 上的标志链接起来。
社交媒体品牌指南
首先,你需要了解并遵循品牌指南,以便使用他们的标志。下面是每个品牌的指导方针,我将使用这些标志。
YouTube
YouTube 的使命是给每个人一个声音,向他们展示这个世界。了解我们的品牌、社区、职业和…
www.youtube.com](https://www.youtube.com/about/brand-resources/#logos-icons-colors)
中等
中等设计](https://medium.design/logos-and-brand-guidelines-f1a01a733592)
推特
从推文处理到徽标和社交图标,我们的模板和工具将帮助您使用 Twitter 内容和我们的…
about.twitter.com](https://about.twitter.com/en_us/company/brand-resources.html)
领英
为了确保我们的标志清晰可辨,并保持其完整性,保持其周围的区域没有其他元素…
brand.linkedin.com](https://brand.linkedin.com/downloads)
卡格尔
[## Kaggle 品牌指南
关于如何以及何时利用 Kaggle 品牌的指南
www.kaggle.com](https://www.kaggle.com/brand-guidelines)
下载和上传徽标
一旦你理解了他们的指导方针,你就想下载徽标,并把它们上传到任何可以获得图像 URL 的平台上。我将使用 Cloudinary 来上传它们并获取 URL。你也可以使用 Google Drive 或 Dropbox。
使用 HTML 代码将徽标与您的社交媒体链接结合起来
一旦你解锁了 GitHub 的隐藏特性并初始化了 README 文件,你就可以用 HTML 来编辑它了。
使用 HTML 代码,我们可以将您的社交媒体链接和您上传的徽标结合起来。
访问您的社交媒体链接的 HTML 代码
<a href="[https://www.youtube.com/c/ImportData1](https://www.youtube.com/c/ImportData1)">
访问社交媒体徽标的 HTML 代码
<img src="[https://res.cloudinary.com/importdata/image/upload/v1595012354/yt_logo_jjgys4.png](https://res.cloudinary.com/importdata/image/upload/v1595012354/yt_logo_jjgys4.png)" alt="drawing" width="100"/>
您可以通过调整**【宽度】**来改变图像尺寸
你要把上面的代码一个挨着一个地放在一起,以充分地把标志和链接结合起来。
<a href="[https://www.youtube.com/c/ImportData1](https://www.youtube.com/c/ImportData1)"><img src="[https://res.cloudinary.com/importdata/image/upload/v1595012354/yt_logo_jjgys4.png](https://res.cloudinary.com/importdata/image/upload/v1595012354/yt_logo_jjgys4.png)" alt="drawing" width="100"/>
可以把**放在 ;**如果您想在标志之间添加空格。
<a href="[https://www.youtube.com/c/ImportData1](https://www.youtube.com/c/ImportData1)"><img src="[https://res.cloudinary.com/importdata/image/upload/v1595012354/yt_logo_jjgys4.png](https://res.cloudinary.com/importdata/image/upload/v1595012354/yt_logo_jjgys4.png)" alt="drawing" width="100"/>** **<a href="[https://medium.com/@importdata](https://medium.com/@importdata)"><img src="[https://res.cloudinary.com/importdata/image/upload/v1595012354/medium_mono_hoz0z5.png](https://res.cloudinary.com/importdata/image/upload/v1595012354/medium_mono_hoz0z5.png)" alt="drawing" width="35"/>
就是这个!非常感谢你阅读这篇文章,希望你觉得有用!
在这些平台上与我联系:
🔗 YouTube
🔗推特
🔗 LinkedIn
🔗GitHub🔗卡格尔
一个全新的人工智能世界
疫情之后人工智能的兴起
约书亚·厄尔在 Unsplash 上的照片
人工智能将在未来 10-15 年对工作世界产生什么影响?
今天的世界正在快速变化,我们希望在未来十年看到令人难以置信的变化,这要归功于人工智能。我们不要忘记,疫情的一个积极影响是,人们越来越依赖技术,正在学习在线生活,不再羞于使用技术。这种情况本身导致更多的人使用并最终信任技术。雇主也在经历这样的心理变化。这是他们有生以来第一次,他们的生意陷入停顿!
在未来几年,人工智能不一定会取代整个工作,但它会接管特定的任务。它已经开始取代这些任务,并且在未来几年将继续加速。根据世界经济论坛,在 5 年内,自动化将占现有任务的 50%以上。我们认为有四种可能的情况需要考虑:
- 一些工作,如护理职业(护士、医生和其他人),创意产业(演员、音乐家和其他人),不会受到人工智能的太大影响,因为人工智能仍然不太擅长这些任务。
- 其他工作将被淘汰。这些人包括司机(因为自动驾驶汽车的兴起)、工厂工人(因为自动化)和许多其他人。
- 许多新的工作将会出现。这些工作甚至不是我们发明的。它可能包括像器官创造者这样的服务,通过这些服务,人们可以设计新的器官(如新的心脏、肾脏或肝脏)来替代有缺陷的器官。
- 大多数现有的工作将会改变,因为人工智能技术将会增加他们的基本任务。这将产生巨大的影响。它可能小到帮助超市的堆垛机使用增强现实识别过期产品,大到在手术中协助外科医生。
AI 未来会消灭还是增加工作岗位?
很难得出一个关于人工智能会减少还是增加工作岗位的大概数字。人工智能专家声称,在未来十年内,它将会淘汰目前存在的 40%以上的职位。如果我们考虑到疫情的影响,这个数字很可能是一个保守的估计。另一方面,世界经济论坛预测,AI 将创造至少 1.33 亿个新角色。这些都是新的工作,今天甚至不存在。
此外,我们不要忘记,IT 行业并不是孤立运作的,它需要许多辅助角色,如视觉艺术家、文案和其他一些角色。因此,要达到这个正确的数字,这个数额至少应该翻两番。如果我们把所有事情都加在一起,官方估计表明,人工智能创造的就业机会很可能比它杀死的多 45%。因此,总的来说,未来看起来确实是光明的。这种前景并不意味着一切都会一帆风顺。许多人仍然需要接受再培训和再技能培训,才能在新的就业市场中茁壮成长,但在人工智能工具的帮助下,这将比以前简单得多。
工作的未来会是什么样子?
我们知道工作会逐渐改变。对自动化的依赖将呈指数增长,我们将忘记过去发生的事情。只要想想智能手机;它取代了固定电话、电话答录机、照相机、闹钟、卫星导航系统、扫描仪、音乐播放器、计算器、电视和其他东西。年轻人可能从来没有见过这些旧设备,除非他们参观了古董博物馆。同样的事情也会发生在 AI 身上。我们的软件将注入能够处理大量数据的人工智能特性。计算机将变得无所不在;不再装在一个小盒子里,而是可以从一个地方的任何地方访问。该界面对任何人来说都更容易,允许无缝的类似人类的语音交互。因此,工作将从信息的采集、处理和呈现转向人工智能服务的管理,人工智能服务将代表我们接管大多数这些任务。随着先进机器人的出现,即使是手工任务也将转向半手工任务。自动化也将使许多手动过程变得多余。在不可能的情况下,外骨骼将帮助人类搬运重物,而不会危及他们的健康。
专家们为什么要担心人工智能?
专业化一直是人类的领域,因为要实现它;一个人需要多年的学习和经验。然而,现在情况发生了变化。互联网包含大量信息,因此允许人工智能系统处理这些信息并从中学习。这个过程相当于一个人随着时间的推移不断学习和积累经验。唯一不同的是,对于机器来说,这发生在几个小时或几天内。如果我们只看一个例子,2018 年,一个由 20 名专攻公司法的律师组成的团队与一个人工智能展开了对抗。他们每个人都有五份保密协议,他们必须找出任何错误。律师们平均花费一个半小时来完成这项任务,并且达到了 85%的准确率。另一方面,合法的人工智能在 26 秒内获得了 94%的准确率。差异是巨大的,它表明每一份工作,即使是高薪工作,都将受到人工智能的影响。当然,我们不会很快看到机器人律师在法庭上辩论,但人工智能系统将开始协助律师完成日常任务。
管理者能做些什么来跟上时代?
马尔科姆·Ⅹ曾经说过,“未来属于今天为它做准备的人”。有些人已经在梦想和设计明天的解决方案。技术已经成熟,我们拥有处理能力,终于有了拥抱人工智能革命的政治意愿。它接管只是时间问题。所以管理者需要迈出第一步,学习人工智能。如果有疑问,他们应该寻求人工智能专家,他们可能会惊讶于人工智能可以为他们的组织带来的巨大节约。这个过程本身也相当简单,它遵循一些明确定义的步骤。首先,重要的是开始教育人们什么是人工智能。教育过程必须从最高层开始,向下到组织层级的所有级别。第二,组织进行人工智能准备审计,以确定组织在采用人工智能方面的状态。然后,与所有利益相关者进行协商,以确定潜在的人工智能案例研究。然后,根据可行性、所需投资和潜在回报,与管理层一起订购这些案例研究。然后,管理层简单地决定实施哪些项目。它们是在内部实施还是外包,实际上取决于复杂性和组织中可用的专业知识。人工智能专家将在那里监督项目的运行。完成后,选择并执行另一个更有雄心的项目。如此循环下去,直到组织设法用人工智能来增强其流程。
人工智能将会或不会做什么?
人工智能非常擅长以令人难以置信的速度和惊人的精度处理重复的任务。正因为如此,它可以很容易地取代几乎任何具有这些特征的任务。试想一辆自动驾驶汽车,驾驶员必须观察周围发生的事情(重复性工作),他必须立即注意到任何异常(以不可思议的速度),并采取果断行动(以惊人的精度)。通过观察这些特征,人们可以快速确定某项工作是否存在风险。
另一方面,AI 还是不善于处理人。当人们交流时,他们不仅通过言语,还通过社会规范。像话轮转换、打手势、表现出同理心和其他许多不成文的规则。这些是我们在社区中成长时学到的东西。但是对于一台机器来说,这些事情是不自然的,因为它缺乏社会背景,必须有人教它们。在过去的十年里,人机交互取得了巨大的进步,但是我们仍然远远没有达到人类交流的自然程度。人们不能指望让机器人来照顾人类病人,因为它无法处理这种情况,当然不是医疗方面,而是人的方面。
我们今天拥有的最令人印象深刻的 AI 是什么?
今天最令人印象深刻的人工智能无疑是计算机视觉。这是人工智能的一个子领域,在这个领域中,计算机设法持续击败人类水平。无论是识别医学图像中的癌细胞,还是识别视频中的物体或人,或者只是为自动驾驶汽车解释道路,计算机视觉在过去十年中都取得了巨大的飞跃。毫无疑问,如果没有深度学习算法的进步,这是不可能的。然而,这些算法将很快达到它们的极限,因此,研究人员总是在寻找可能的改进。毫无疑问,量子计算是一项非常有前途的独特技术,它将使这些算法超越我们的想象。仅举一个例子来说明它的巨大威力,谷歌设法将量子计算用于一个特殊的数学问题。系统设法在 3 分钟多一点的时间内解决了这个问题。考虑到当今最强大的超级计算机完成同样的任务大约需要 10,000 年,这个结果是一个巨大的进步!
人工智能会超越人类智慧吗?
智力是一种很难定义的属性。以至于我们没有一个一致的定义,然而我们人类非常擅长给智慧生物贴标签。通常,我们会将任务与人类可以完成的任务联系起来,如果另一种动物或机器可以复制这些动作,那么我们就将它们称为智能。
如果你执行个别任务,如下棋、分析视频和许多其他任务,人工智能不仅比人类更好,而且在某些情况下,它还达到了超人的水平。这个概念被称为狭义人工智能,因为它能够非常好地处理近距离任务。然而,如果你让一位人工智能国际象棋大师讲述纽约的当前天气,系统会惨败,因为这个请求超出了它的设计功能。
要超越人类智能,需要人工通用智能。这种智能类似于人的智能,可以同时处理多个不同的请求。虽然在过去的几十年里有很多研究,但现实是我们仍然非常遥远。当然,随着量子计算等新算法和技术的兴起,这一切都可能改变。
人工智能会有感知能力吗?
感知是感知或感觉事物的能力。这是一个我们人类很好理解的概念,但我们发现很难定义我们如何做到这一点。想象一下疼痛,以其原始的形式,它是一个信号,从我们身体的一部分发送到我们的大脑,大脑为我们解释它。这难道不类似于通过电线向机器的中央处理器发送电子信息吗?
当然,疼痛是我们非常了解的东西,但其他感觉很难复制,因为我们还没有完全了解它们。因此,最终,人工智能将变得有知觉。然而,最大的问题是,人工智能是否和人类一样。有些人会争辩说,它不是,也永远不会是。这种说法可能是正确的,但即使不同,也不一定是劣等的。试想一架飞机,它不是一只鸟,运作方式不同,但它能飞,它能携带巨大的负荷,并达到令人难以置信的速度。潜艇也一样,它不是鱼,工作方式不同;然而,它可以游到难以想象的深度。所以,是的,我相信人工智能最终会达到感知,但它可能是不同的一种。
这篇文章最初发表在 https://www.businesstoday.com.mt上请在下面留下你的想法,如果你喜欢这篇文章,请随时关注我🐦推特,🔗 LinkedIn 或者😊脸书。
关于马耳他及其如何成为世界上人工智能排名前 10 位的国家的案例研究
towardsdatascience.com](/how-to-create-a-world-class-ai-national-strategy-in-10-steps-eec5bc1f91fd) [## 人为的不人道
几个月前,菲利普·拉雷神父出版了一本名为《人造人类》的书。它讨论了对…的需求
towardsdatascience.com](/artificial-inhumanity-a8d3c9ea142c)
阿列克谢·丁力教授 是马耳他大学的 AI 教授。二十多年来,他一直在人工智能领域进行研究和工作,协助不同的公司实施人工智能解决方案。他的工作被国际专家评为世界级,并赢得了几个当地和国际奖项(如欧洲航天局、世界知识产权组织和联合国等)。他出版了几本同行评审的出版物,并且是马耳他的一部分。由马耳他政府成立的人工智能工作组,旨在使马耳他成为世界上人工智能水平最高的国家之一。
Word2Vec 实现
如何使用 numpy 和 python 实现 Word2Vec
本文是关于一种非常流行的单词嵌入技术 Word2Vec 的实现。它是由谷歌的托马斯·米科洛夫实现的。
内容:
概念
- 目标
- 介绍
- 核心理念
- 体系结构
B —实施
- 数据准备
- 模特培训
- 模型推理和分析
目标
本文的目的是使用 numpy 展示 python 中 Word2Vec 的内部工作方式。我不会为此使用任何其他库。这个实现不是一个有效的实现,因为这里的目的是理解它背后的机制。你可以在这里找到官方报纸。
介绍
计算机只理解数字语言。我们将文本数据编码成数字的方式对结果影响很大。一般来说,有 3 种技术可以用来完成这项任务。
其中,word2vec 在 NLP 任务中表现得非常好。这个概念背后的核心思想非常简单,但却能产生惊人的效果。
核心理念
“看一个人交的朋友就知道他是谁”
― 伊索
这是一句众所周知的谚语。word2vec 也主要基于这个想法。一言既出,驷马难追。这听起来如此奇怪和有趣,但它给出了惊人的结果。让我们试着多理解一点。
一些例句:
- 你在花园里辛勤劳动的回报显而易见。
- 保持我的房间整洁是一件困难的工作。
- 艰苦的工作开始对他产生影响。
在这里,我们可以很容易地看到,“努力”和“工作”这两个词出现的位置非常接近。作为人类来说,这似乎很容易观察到,但对于计算机来说,这是一项非常困难的任务。因此,当我们将这些单词矢量化(将单词转化为数字)时,它们作为数字的表示应该是相似或接近的,这似乎是显而易见的。这正是 word2vec 所要实现的,并且取得了非常好的结果。说够了,现在是我们动手的时候了!
体系结构
因此,在理解了核心思想之后,我们知道该算法是基于识别彼此邻近的单词。换句话说,我们可以说,如果计算机试图学习单词“hard”和“work”在彼此附近出现,那么它将据此学习向量。
如果我们说我们的“目标”单词是“硬的”,我们需要学习一个好的向量,我们向计算机提供它的邻近单词或“上下文”单词,在这种情况下是“工作”,在“the,began,is 等”中。
有两种主要的架构试图了解上述内容。跳过 gram 和 CBOW
:这样我们就了解了目标词和语境词的概念。该模型试图学习每个目标单词的上下文单词。
图 1:跳过 gram 架构。演职员表
直觉:
正文:[‘成功的最佳途径是努力工作和坚持’]
因此,对于该模型,我们的输入如下:
- 目标词:最好。上下文词:(方式)。
- 目标词:方式。现在我们有两个词,一个在前面,一个在后面。所以在这个场景中,我们的上下文单词将是: (Best,to) 。
- 目标词:到。现在我们也有两个词,一个在 I 之前,一个在 I 之后,即(成功之路)。但如果我们再想一想,那么“to”和“is”可以在彼此相邻的句子中找到。比如“他要去市场”。因此,如果我们将单词“is”包含在上下文单词列表中,这是一个好主意。但现在我们可以争论“最好”或“通过”。于是就有了“窗口大小的概念。窗口大小是我们决定要考虑多少邻近单词的数字。因此,如果窗口大小为 1,那么我们的上下文单词列表就变成了 (way,success) 。并且如果窗口大小是 2,那么我们的上下文单词列表变成*(最佳,方式,成功,是)**。*
- 类似地,我们可以列出其余的单词
我们看到这里有一个输入层、一个隐藏层和一个输出层。我们还可以看到有两组权重(W,W `)。
CBOW: 语境包词。从概念上来说,这与 skip-gram 正好相反。这里我们试图从上下文单词列表中预测目标单词。因此,对于我们的示例,我们将输入为*(最佳、方式、成功、是),我们需要从中预测到**。*
图 2: Cbow 模型架构
我们可以看到,这与跳格模型正好相反。
实现进程
在本文中,我将实现跳格模型。
数据准备
为了训练一个模型来学习单词的良好向量,我们需要大量的数据。但是在本文中,我将尝试展示一个非常小的数据集的工作原理。数据集由取自维基百科的杰弗里·阿彻各种故事的情节组成。
步骤 1:从文件中读取数据
解释:
- 第 2–4 行:将文本文件的内容读取到列表中
- 第 7–8 行:只保留字母,删除每行中的其他内容
- 第 9–17 行:重复句子中的每个单词,如果指定了停用词,则删除停用词
第二步:生成变量
我们将需要一些变量,这些变量将在后面的章节中派上用场。
*word_to_index : A dictionary mapping each word to an integer value {‘modern’: 0, ‘humans’: 1} index_to_word : A dictionary mapping each integer value to a word {0: ‘modern’, 1: ‘humans’}corpus : The entire data consisting of all the words vocab_size : Number of unique words in the corpus*
解释:
- 第 10 行:将每个单词转换成小写
- 第 12–15 行:用这个单词更新字典,如果这个单词还没有出现在字典中,就进行计数
该代码的输出将给出:
*text = ['Best way to success is through hardwork and persistence']Number of unique words: 9word_to_index : {'best': 0, 'way': 1, 'to': 2, 'success': 3, 'is': 4, 'through': 5, 'hardwork': 6, 'and': 7, 'persistence': 8}index_to_word : {0: 'best', 1: 'way', 2: 'to', 3: 'success', 4: 'is', 5: 'through', 6: 'hardwork', 7: 'and', 8: 'persistence'}corpus: ['best', 'way', 'to', 'success', 'is', 'through', 'hardwork', 'and', 'persistence']Length of corpus : 9*
第三步:生成训练数据
在看代码之前,让我们先了解一些概念。
- One-hot-vector:基本上这是一种用 0 和 1 对数据进行编码的方法。因此,我们的 one-hot-vector 的大小将为 2,因为我们有两个单词,我们将有两个单独的向量,一个用于 hi,一个用于 john。例如:(word: hi,one-hot-vector: [1,0]),(word: john,one-hot-vector: [0,1]
以下代码为我们的数据生成一个热向量:
解释:
*text = ['Best way to success is through hardwork and persistence']Window size = 2, Vocab size = 9 We will set the indices as 1 according to the word_to_index dict i.e best : 0, so we set the 0th index as 1 to denote naturalTarget word = best
Context words = (way,to)
Target_word_one_hot_vector = [1, 0, 0, 0, 0, 0, 0, 0, 0]
Context_word_one_hot_vector = [0, 1, 1, 0, 0, 0, 0, 0, 0]Target word = way
Context words = (best,to,success)
Target_word_one_hot_vector = [0, 1, 0, 0, 0, 0, 0, 0, 0]
Context_word_one_hot_vector= [1, 0, 1, 1, 0, 0, 0, 0, 0]*
有一种替代方法来生成上下文 _ 单词 _ 一个 _ 热 _ 向量。
*Target word = best
Context words = (way,to)
Target_word_one_hot_vector = [1, 0, 0, 0, 0, 0, 0, 0, 0]
Context_word_one_hot_vector = [0, 1, 0, 0, 0, 0, 0, 0, 0],[0, 0, 1, 0, 0, 0, 0, 0, 0]*
我们有两个不同的列表,而不是在一个列表中显示索引。但这种方法的问题是,如果我们的数据量增加,它将占用大量空间。我已经用 python 脚本说明了这一点。参考代码查看不同之处。
现在我们有了为目标单词和上下文单词生成的向量。为了训练模型,我们需要(X,Y)形式的数据,即(目标单词,上下文单词)。
这是通过以下代码实现的:
解释:
*text = ['Best way to success is through hardwork and persistence']*
- 第 7 行:迭代语料库
- 第 9 行:将第 I 个单词设置为目标单词
- 第 14,21,27 行:检查第 9 行的第 I 个单词是(first :Best),(middle : way)还是(last : persistence)单词的条件。
- 第 17 行:如果是第一个单词,获取接下来的 2 个(window_size =2)单词,并将它们设置为上下文单词
- 第 21 行:如果是最后一个单词,获取前面的 2 个(window_size =2)单词,并将其设置为上下文单词
- 第 30,37 行:如果我们的第 I 个单词是中间单词,那么我们需要在第 I 个单词之前获取 2 个(window_size =2)单词,在第 I 个单词之后获取 2 个(window_size =2)单词,并将所有 4 个单词都设置为上下文单词。如果在第 I 个单词之前或之后只有 1 个单词,我们只能得到 1 个单词。
示例:
***************************************************
Target word:best . Target vector: [1\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0.]
Context word:['way', 'to'] .
Context vector: [0\. 1\. 1\. 0\. 0\. 0\. 0\. 0\. 0.]
**************************************************
Target word:way . Target vector: [0\. 1\. 0\. 0\. 0\. 0\. 0\. 0\. 0.]
Context word:['best', 'to', 'success'] .
Context vector: [1\. 0\. 1\. 1\. 0\. 0\. 0\. 0\. 0.]
**************************************************
Target word:hardwork . Target vector: [0\. 0\. 0\. 0\. 0\. 0\. 1\. 0\. 0.]
Context word:['through', 'is', 'and', 'persistence'] .
Context vector: [0\. 0\. 0\. 0\. 1\. 1\. 0\. 1\. 1.]
**************************************************
Target word:and . Target vector: [0\. 0\. 0\. 0\. 0\. 0\. 0\. 1\. 0.]
Context word:['hardwork', 'through', 'persistence'] .
Context vector: [0\. 0\. 0\. 0\. 0\. 1\. 1\. 0\. 1.]
**************************************************
Target word:persistence . Target vector: [0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 1.]
Context word:['and', 'hardwork'] .
Context vector: [0\. 0\. 0\. 0\. 0\. 0\. 1\. 1\. 0.]*
模特培训
图 3:跳跃图的训练
上图显示了一个神经网络是如何被训练的,在这个例子中是一个 skip-gram 模型。这里我们可以看到只有一个隐藏层。当我们在深度学习中训练一个神经网络时,我们往往会有几个隐藏层。这就是这个跳过程序工作得如此好的地方。尽管只有一个隐藏层,但这是一个最先进的算法。
正向传播
这里我们有以下参数:
- 输入:我们给模型的输入。我们场景中的目标词
- W_1 或 weight_inp_hidden:第一组权重与输入相乘得到隐藏层。
- W_2 或 weight_hidden_output:第二组权重乘以隐藏层。
- Softmax 层:这是在 0 和 1 之间挤压输出概率的最后一层。关于 softmax 函数的一个很好的解释可以在这里找到。
训练错误:
现在,一旦我们完成了一轮前向传播,我们就会得到一些输出值。所以很明显,和初始值相比,我们的预测会有一些误差。
解释:这是反向传播,以更新下一次迭代的权重
*Example: below if we have 2 context words. These are not actual values.These are just for showing how the error is calculatedcontext_words = [1 0 0 1 0]y_pred = [9 6 5 4 2]So if we break the context_word vector : [1 0 0 0 0] and [0 0 0 1 0] . 1 at index 0 and 3The error should be calculated as :diff_1 = y_pred - context_word_vector_1 =
[9 6 5 4 2] - [1 0 0 0 0] = [8 6 5 4 2]diff_2 = y_pred - context_word_vector_2 =
[9 6 5 4 2] - [0 0 0 1 0] = [9 6 5 3 2]Total_error = diff_1 + diff_2(column_wise) = [17 12 10 7 4]Since our context vector has only 1 array , we implement the above as:index_of_1_in_context_words -> **Line (6,7)**
A dictionary which has the index of 1's in the context_word_vector -> {0: 'yes', 3: 'yes'}number_of_1_in_context_vector -> A count for the above -> 2We loop the y_pred array and do the calculations as:for i,value in enumerate(y_p):**Line(13,14)** if the ith index of y_pred has a 1 in context_word_vector:
total_error[i] -> i:0 . y_pred[i]:9\. -> (9-1) + (1*9)
->error_calculated: 17
total_error[i] -> i:3 . y_pred[i]:4\. -> (4-1) + (1*4)
->error_calculated: 7**Line(15,16)** else:
total_error[i] -> i:1 . y_pred[i]:6\. -> 6*2
->error_calculated: 12
total_error[i] -> i:2 . y_pred[i]:5\. -> 5*2
->error_calculated: 10
total_error[i] -> i:4 . y_pred[i]:2\. -> 2*2
-> error_calculated: 4total_error -> [17 12 10 7 4]*
反向传播
利用上面计算的误差,我们需要更新权重(w1 和 w2 ),以便我们的网络尝试纠正该误差。
这里的是一个很好的链接,解释了反向传播的导数方程。
最后损失计算
损失计算如下:
图 4:损失函数。学分
如果我们稍微深入地观察损失函数 E,我们会发现,在给定 WI(输入单词)的情况下,我们正试图优化找到正确上下文单词 p(WO,1,WO,2,,WO,C)的概率。因此,当我们更接近为每个给定的目标单词找到正确的上下文单词的分布时,损失将会减少。
解释:
损失函数由两部分组成。
- 第一部分:我们取一个负值,其中上下文单词的值为 1
- 第二部分:我们取一个 u 的 exp,这是我们用隐藏层乘以第二组权重后得到的输出。
*u : [ 0.3831286 0.89608496 2.69426738 -1.60230182 0.45482701 0.73644591 1.10365796 1.1675781 -0.78555069]context: [0, 1, 1, 0, 0, 0, 0, 0, 0]sum_1 = -(0.89608496 + 2.69426738)sum_2 = number_of_context_words * np.log(np.sum(np.exp(u)))total_loss = sum_1 + sum_2*
超参数
到目前为止,我们可以看到在这个过程中涉及到许多变量。所以训练的一个很大的部分是找到给出最佳结果的正确的变量集。我们将逐一讨论这些变量。
- 窗口大小:这是我们为每个目标单词准备的上下文单词的数量。
- 学习率:如果我们看到反向传播代码,我们会看到权重与学习率相乘。这是称为梯度下降的优化过程的一部分。一个好的学习率定义了我们的模型多快达到它的最优值。
- 纪元:假设我们有 100 个训练例子。因此,当我们对每 100 个记录执行上述整个过程时,这被计为 1 个时期。
- 维度:当我们的最终模型准备好了,我们得到了每个单词的向量。该向量可以具有范围从 50 到 300 各种维数。
- 停用词:这些词像 a,an,the。它们本身没有任何意义,因此我们可以检查模型在有和没有它们的情况下是如何工作的。
在保持学习率为 0.01 的情况下,我做了一些有趣的实验,包括窗口大小、时期、尺寸、停用词
模型推理和分析
为了获得每个单词的单词向量,在最终训练之后,使用第一组权重,即 weight_1 来检索每个单词的向量。
为了找到相似的单词集,使用余弦相似度。这是一种度量标准,用来衡量多维空间中两个向量的相似程度。基本上,它测量两个向量之间的角度,以确定它们有多相似。很好的解释可以在这里找到。
现在我使用了两组不同的数据,一组是单行文本,另一组是文本语料库。
用单行文本作为输入进行推理
*Text : [‘best way to success is through hardwork and persistence’]*
下面显示的散点图是二维的。这是通过降维实现的。我已经为它使用了 T-SNE 。下图并没有给出一个确切的图像,因为我们把几个维度压缩成了 2 个。
不同维度的散点图:
图 5:变暗
我们可以在这里看到“最佳”和“方式”是多么接近。即使一行文字对于一个模型来说是非常稀缺的,但是它可以学习很好的嵌入。
不同窗口大小的散点图:
图 6:不同的窗口大小
用相对较大的语料库进行推理
为了了解这个模型的效果,我打印了一个相似度矩阵,用于一些拥有更大语料库的单词
变化尺寸:
**
图 7:变维相似矩阵
这里要注意的一件事是,对于更高的维度,相似性的数字很低。这背后的原因是语料库非常小,只有大约 700 个独特的单词。所以要学习更高维度的嵌入,需要一个庞大的语料库。word2vec 算法是在数百万规模的语料库上训练的。
停用词:
**
图 8:停用词效应
该模型在没有停用词的情况下似乎表现得更好,因为每个时期的损失曲线都更好。为了更好地理解它,我们需要在更大的语料库上进行尝试。
上面的散点图可以在我的 github 链接这里找到。
进一步改进:
word2vec 的训练是一个计算量非常大的过程。由于有数百万字,训练可能要花很多时间。对抗这种情况的一些方法是负采样和分级 softmax。理解这两者的好链接可以在这里找到。
完整的代码可以在我的 github 资源库中找到:
https://github . com/Rahul 1728 jha/Word 2 vec _ Implementation/blob/master/Word _ 2 _ vec . ipynb
请留下任何澄清或问题的评论。
快乐学习😃
如何用 GatsbyJS、GitHub 和 Netlify 创建和部署一个超快的网站
完整的指南,以建立和部署一个非常快速和现代化的网站免费(自定义域)。
伊戈尔·米斯克在 Unsplash 上的照片
我创建了一个个人博客网站,展示我的一些创意项目。这是一个相当坎坷的学习曲线,因为我一路上有很多问题和考虑。不幸的是,我找到的大部分教程都是零散的,所以我想我应该写一个详细的教程。如果你不是 web 开发人员,但有一些编码知识,并且想免费建立一个现代化的个人网站(没有 Wordpress 或网站建设者),这篇文章就是为你准备的!
这篇文章的目的是一步一步地向你展示如何创建、部署和配置一个简单的博客/作品集网站,并使用你自己的自定义域名。我们开始吧!
我的攻击计划(即工具设置)
一开始,我在我的小博客/作品集网站的几个选项中来来回回:
- 从头开始编写我的网站
- 使用静态站点生成器
- 使用 Wordpress/其他 CMS。
下面是我在搜索了这么多帖子和网站后创建的一个概述。我在以下几个方面对它们进行比较: (1)灵活性&自由度,(2)性能,(3)需要的知识和技能,(4)安全性,(5)可扩展性和维护 。这将有望帮助你回答这个百万美元的问题:选择什么:
建立投资组合网站的选择。来源:作者。
在分析了这些选择的利弊之后,我决定选择静态站点生成器(SSG)。这是因为我可以编码,并希望对我的网站的底层内容有更多的控制。此外,我只是想要一个简单整洁的博客网站,所以安装大量的 Wordpress 插件对我来说听起来不是很有吸引力。
具体来说,我使用了 GatsbyJS ,因为我对 JavaScript 和 React 更加熟悉和熟悉,这是 Gatsby 所基于的语言。此外,它是一个已经成熟的 SSG,拥有强大的功能和插件生态系统。如果你有兴趣了解更多关于其他 SSG 的信息,这里有一个目前顶级 SSG 的比较。
什么是静态站点生成器?
静态站点生成器是一个应用程序,它获取内容(通常用 Markdown 编写),将其应用于模板,并生成一组纯静态的 HTML 文件,准备交付给访问者。
接下来,我们还需要解决网站的其他问题,即域名、托管和部署。以下是我的设置:
工具安装。来源:作者。
如果你想让数据库操作更加用户友好(例如,当你的网站落入非技术用户手中,他们将很难浏览代码仓库),你可以考虑将你的 SSG 与无头 CMS 配对,例如 Contentful 。但是这是可选的,没有它你也可以做得很好。
设置您的开发环境
在构建您的第一个 Gatsby 站点之前,您需要进行一些安装。
#1.节点. js
由于 Gatsby 是用 Node.js 构建的,我们需要安装它才能使用 Gatsby。如果你使用的是 Windows 操作系统,你可以简单地下载并安装到你的机器上。
#2.饭桶
我们将需要 Git 来下载 Gatsby“starter”(带有一些默认配置的部分构建的站点),并在稍后使用版本控制+托管我们的项目。如果你还没有它,你可以在这里为 Windows 安装它。
#3.盖茨比 CLI
Gatsby CLI 工具允许您快速创建新的 Gatsby 支持的站点,并运行命令来开发 Gatsby 站点。您可以使用 npm 进行全局安装。打开您的终端并运行以下命令:
npm install -g gatsby-cli
您还可以查看可用于 Gatsby CLI 的命令:
gatsby --help
开始建立你的网站
Gatsby 提供了许多(免费的)预建启动器供您选择,以满足您网站的目的,包括博客网站、在线商店或简单的投资组合网站。假设你想使用这个虚构的博客主题,它是开源的,你可以简单地进入终端,将目录切换到你想要存储你的网站的文件夹,并从 Git 下载代码(注意,你可以给你的网站文件夹起任何名字,而不是mynewwebsite
):
gatsby new mynewwebsite [https://github.com/dvzrd/gatsby-sfiction](https://github.com/dvzrd/gatsby-sfiction)
下载完成后,您可以使用本地主机为站点提供服务:
gatsby develop
现在,如果你在 http://localhost:8000/ 打开你的网页浏览器,你应该会在那里看到这个网站。
接下来,您可能想要更改gatsby-config.js
文件中的默认值,以适合您的个人资料信息。你应该看到一个文件夹,里面有 markdown 文件(.md
)中的所有帖子,在那里你可以开始创建自己的帖子!如果您更熟悉 React、HTML 和 CSS,您还可以深入 React 组件并调整它们的外观,以及添加新的动态功能。
gatsby 文档和教程为你理解和开始操作 Gatsby 启动器提供了一个很好的基础。
此外,在 markdown 中写帖子相当容易。这里有 markdown 语法文档供你参考。
上传到 Github
一旦你对新网站的配置和基本功能感到满意,我们就进入有趣的部分——托管和部署你的网站。
在 Github 上创建一个存储库,并上传您的网站文件夹。由于您的 Gatsby 网站文件夹包含几个子文件夹,使用 Github 网站并尝试将您的文件夹拖放到 Git repo 中可能行不通。因此,最简单的方法是使用 Git Bash。首先,您将光盘放入您的网站文件夹,然后键入以下内容:
git commit -am "Uploading files"
git remote add origin [https://github.com/yourUsername/yourRepository.git](https://github.com/yourUsername/yourRepository.git)
git push -u origin master
git push origin master
现在,您的所有文件都应该上传到您的 Git repo。我们现在准备部署我们的网站!
部署到网络
在这一节中,我将解释如何使用 Netlify 免费部署您的个人网站。
Netlify 与 Github 页面
注意,另一个免费选项是使用 Github 页面,事实上,许多人都将其用于个人网站。这也是一个很好的选择——简单直接地让你的网站开始运行。然而,从长远来看,使用 Netlify 可能会更好,因为它提供了额外的功能。此外,如果您需要在未来扩大您的网站,有付费计划供您选择。
下面是 Netlify 做的一个比较(可能有点偏,但只是给你一个思路):
Github Pages vs. Netlify。来源:https://www.netlify.com/github-pages-vs-netlify/
实际上,我见过一些专业开发人员和精通编码的人在他们的博客中使用 Netlify(这里的和这里的)。对我来说,这是另一个证明,它是静态页面的一个很好的选择。
什么是网络生活
它是一家云计算公司,为 web 应用程序和静态网站提供托管和无服务器后端服务。根据项目的规模,他们为网站托管提供了几种方案。对于个人网站,使用免费选项就可以了。
从 Github 部署您的站点
首先,你需要用你的 Github 账户在 Netlify 网站上注册。这将连接您的 Netlify 帐户和 Github。
你可以按照这个一步一步的教程从 Github 部署你的站点。一旦你完成了,你应该有这样一个概述:
概述网络生活网站。来源:作者。
注意,这里我已经有了一个自定义域名(。com)。在你的情况下,很可能你的网站在这个阶段仍然有一个random-name.netlify.app
域名。你可能暂时还能接受这个域名,但是如果你已经拥有一个域名,你当然可以配置它来连接到你的网站。
使用自定义域
要自定义您的域名,请进入设置>域管理>添加域别名。
在 Netlify 上配置自定义域。来源:作者。
一旦你添加了你的自定义域名,接下来要做的就是去你的域名注册商那里配置你的域名。不同的主要注册商有不同的具体说明,但一般来说,您需要配置以下内容:
- A 主机:104.198.14.52(这是网络服务器 IP 地址)
- CNAME :【你的网站名称】. netlify.app(比如我的情况就是 thuhienvu.netlify.app)
- 名称服务器:
dns1.p01.nsone.net
dns2.p01.nsone.net
dns3.p01.nsone.net
dns4.p01.nsone.net
确保你保存了所有东西。到目前为止,您应该能够看到您的网站与您的自定义域生活!恭喜你!😃
但是等等,你可能会在浏览器上看到一些奇怪的东西:
来源:https://www . digicert . com/blog/not-secure-warning-what-to-do/
这是因为您的站点仍在使用 HTTP 协议,该协议无法提供安全连接。如今,互联网上的所有网站都必须使用 HTTPS 协议,数据在互联网上传输时都要加密(“S”代表“安全”)。传统上,你必须为你的网站购买一个 SSL 证书。然而,Netlify(还有 Github Pages)现在提供免费的 SSL/TLS 证书。
向下滚动到 HTTPS 部分(设置>域名管理> HTTPS )。现在,您只需点击一下鼠标,即可为您的网站提供 SSL/TLS 证书。很简单,不是吗?
如果您看到出现某种错误,很可能是因为证书实际工作需要一些时间。与此同时,你可以喝杯咖啡,你的网站应该很快就能正常工作了。
更新您的网站
在本地对您的网站进行更改时,您可以通过运行以下命令来查看网站在本地的外观(在 http://localhost:8000/ ):
gatsby develop
要将您的更改推送到您的网站,首先,您需要将更改提交并推送到您的 Git repo。之后,在 Netlify 网站上,进入Deploys
选项卡,点击触发部署>部署站点按钮,如下所示:
在 Netlify 上部署。来源:作者。
几分钟后,您的网站应该会有新的变化。您还可以看到部署日志在站点部署时展开。如果你想了解更多的细节,这里有一个完整的教程。
祝贺和最后的想法
我想首先祝贺你得到你的网站生活!
在这篇文章中,你学会了如何:
- 使用入门工具创建一个盖茨比网站
- 使用 Github 托管和版本控制您的站点
- 使用 Netlify 从 Github 部署您的站点
你现在有了自己的网站,用 Git 控制版本,有了自己的域名。全部免费托管!最棒的是,你可以完全控制你的网站,包括代码、外观和所有附加功能。
希望这个帖子有用。我很想在评论区听到你的想法,以及你是如何建立个人网站的。
带精灵的 A-Z Julia 端点
关于使用 Julia、Genie 和 Lathe 部署端点的介绍。
(茱莉亚标志 src =http://julialang.org)
任何有抱负的数据科学家应该能够完成的最重要的任务之一是创建和部署一个端点。端点是现代机器学习的主干,也是将模型转化为真实生产环境的最简单方法。为了在端点部署模型,您首先需要选择一个 web 框架来创建该端点。对于 Python 和 R 来说,选择是非常明显的,并且很容易找到一个合适的 web 框架来满足您的需求。
但是朱莉娅呢?
尽管 Julia 的生态系统肯定没有 Python 或 R 的那么成熟,但是 Julia 确实有一些有趣的选项来部署您的模型。首先,你总是可以依靠 PyCall。这将允许您使用像 Flask 和 Django 这样的 Python 库来进行部署,而不必担心使用与这两个选项相比仍然相对年轻的 Julia 项目。但是对于那些渴望更高性能的人,我介绍
Genie.jl。
当然,与其他 web 框架相比,Genie 还很年轻,但是在我看来,它带来了更多有趣的想法,使得部署模型成为一项休闲活动。Genie 仍在 0.31.1 版本中,但你可能会惊讶于这项技术已经有多强大。今天,我将带你了解 Genie 的一切,从建立虚拟环境到序列化模型和在 Ubuntu 上部署基于 Genie 的 API。
建立模型
举个例子来说,关于一个模型没有什么是真正重要的。无论如何,我们将使用 Lathe 来创建我们的模型,因为与许多其他选项不同,Lathe 模型非常容易序列化和部署。对于今天的例子,我们将使用车床 0.1.2,但语法应该保持不变,直到至少车床 1.0 的发布。第一件事是首先,让我们找到一些数据!
二手车和摩托车数据
www.kaggle.com](https://www.kaggle.com/nehalbirla/vehicle-dataset-from-cardekho/data#)
我选定的数据集是来自 Kaggle 的“车辆数据集”。我选择这个主要是因为我对汽车感兴趣。此外,我对它们感到特别兴奋,因为下周我就要去买一幅德尔·索尔的画了。对于汽车人,我只想说一件事:
双收费 B20 交换。
回到数据科学的世界,我下载了我们的新数据集,现在我们可以读取它了。我们将使用 CSV.jl:
using CSV
df = CSV.read("car data.csv")
朱莉娅的趣事:虽然 DataFrames.jl 是 CSV.jl 的依赖项,但是每当我们导入 CSV 时,它都不会被预编译。换句话说,df 的类型是 DataFrame,它来自 DataFrames.jl,但是我们不能使用与此类型相关的任何方法,直到我们也导入 DataFrames。
using DataFrames
虽然肯定有其他方法可以删除你丢失的值,但这是一个有效的方法:
df = collect(skipmissing(eachrow(df)))
使用这种方法的一个优点是 collect()和 skipmissing()都是 Julia 语言中的基本方法。这意味着它们可以应用于任何类型,如果显式导入,甚至可以应用于您自己的类型。Eachrow()来自数据帧,只是用来把我们的 df 转换成可以迭代的东西。这样做的缺点是,我们将得到一个 DataFrame 行数组作为返回。
我们可以通过断言该数据的 DataFrame 类型来缓解这一问题。
df = DataFrame(df)
跳过这一步,我们不打算考虑统计测试,因为我们并不关心这个例子的准确性,所以接下来我们将继续分割我们的数据。为此,我们将使用来自 Lathe.preprocess 的 TrainTestSplit。在 Lathe 的不稳定版本中,我们需要设置 at 参数(float 设置为 75%),但在任何稳定版本中,情况都不是这样。
接下来,我们需要确定目标和特性。我认为比较 Kms_Driven 和 Selling_Price 是一个很酷的主意。然后我想也许这一年也会很酷,所以为什么不两个都做呢?
target = :Present_Price
feature1 = :Year
feature2 = :Kms_Driven
现在,让我们插入这些内容,以便从数据帧中获取实际阵列:
trainy = train[!,target]
testy = test[!,target]
trainX1 = train[!,feature1]
trainX2 = train[!,feature2]
testX1 = test[!,feature1]
testX2 = test[!,feature2]
现在我们将安装两个独立的车床模型:
using Lathe.models
model1 = LinearRegression(trainX1,trainy)
model2 = LinearRegression(trainX2,trainy)
得到两个预测:
yhat1 = model1.predict(testX1)
yhat2 = model2.predict(testX2)
现在我们将一起和单独测试它们的准确性。对于我们的验证指标,我们将使用平均绝对误差:
还不错!
让我们看看如果我们把两者结合起来会发生什么。我们将通过对 zip 循环中的所有预测进行平均来将两者结合起来:
yhati = [mean([pred1,pred2]) for (pred1,pred2) in zip(yhat1,yhat2)]
现在我们将比较所有的精度:
正如您可能已经预料到的,我们的新功能稍微降低了我们的准确性,因为这个模型没有对使用哪个值或对哪个值进行优先级排序做出任何逻辑决策。因此,我们将只使用第一个模型,因为它具有最好的准确性。为了序列化这个模型,我们将使用 JLD2。使用 JLD2,我们可以使用@save 宏将我们的模型保存为序列化的 JLD2 格式。
using JLD2
[@save](http://twitter.com/save) "mdl.jld2" model1
创建我们的端点
现在,我们将获取 JLD2 文件,并将其移动到一个新目录中。我将在 Bash 中这样做,但是当然,您也可以按照自己的意愿这样做:
mkdir CarPrice
mv mdl.jld2 ./CarPrice
现在,我们将为我们的端点创建一个目录。
mkdir endp
cd endp
现在我们将初始化一个 Genie 项目。为此,我们将输入朱莉娅·REPL,导入精灵,然后最后是 newapp_webservice()方法:
julia
using Genie
Genie**.**newapp_webservice("CarPricePredictor")
这将实例化一个新的 Pkg 环境,并为我们的 Genie 端点创建一个新的目录系统。它还将启动一个服务器,因此您可以继续访问您的本地主机(默认为 http://127.0.0.1:8000/ )并检查您的服务器!默认情况下,无法写入这些文件,因此您需要调整权限才能编辑它们。之后,我将我们的模型文件移动到端点的目录中,然后将它放在自己的名为 models 的文件夹中。现在,我们只需在由 Genie 生成的 routes.jl 文件中使用 JLD2 重新加载它:
using Genie.Routerroute("/") do
mdl = [@load](http://twitter.com/load) "models/mdl.jld2"
end
接下来,我们将从请求中请求一个参数实参,我们可以这样做:
using Genie.Routerroute("/") do
mdl = [@load](http://twitter.com/load) "models/mdl.jld2"
year = haskey([@params](http://twitter.com/params), :year)
end
现在,我们将根据数据进行预测,并返回结果。
using Genie.Routerroute("/") do
mdl = [@load](http://twitter.com/load) "models/mdl.jld2"
year = haskey([@params](http://twitter.com/params), :year)
return(mdl.predict(year))end
部署
为了部署这个模型,我们首先要把我们的文件放到我们的服务器上。为此,您可以使用 FTP、HTTP(通过 Git 或 Wget)或 STP。通常在这种情况下,您会使用 STP,但是因为我已经将我的文件提交给 Github,所以我会将它复制到我的服务器上的/var/www 目录中。
ssh emmett@(this_is_my_ip)
cd /var/www
git clone [https://github.com/emmettgb/CarPricePredictor](https://github.com/emmettgb/CarPricePredictor)
现在我们有两件事情要设置:
- 网络服务器
- 主管
对于我的网络服务器,我将使用 NGINX。我几乎什么都用 NGINX,因为它比 Apache 有一些优势,主要是它通常有更好的响应时间。如果你需要做出决定,我建议你选择你熟悉的那个。如果你对两者都不熟悉,那就用 NGINX 吧,因为它的配置更简单,而且以我的主观观点(以及许多指标)来看,它更好。使用 Apache 当然有优势,但是我不认为至少从尝试 NGINX 开始你会错过很多。
我们要在 NGINX 配置中做的是创建一个代理传递到我们的服务器将要运行的端口上,默认情况下是 8000。如果你在 VPS 上运行多个网络服务器,那么你可能需要使用更高的端口,比如 8001 或 8002。配置文件存储在/etc/nginx/conf.d 中,所以让我们创建一个新的配置:
sudo dnf/apt/pacman/man install nginx
sudo nano /etc/nginx/conf.d/carpredictor.conf
以下是从端口 80(默认 HTTP 协议端口)到端口 8000 的代理传递的配置示例:
**server** {
**listen** 80;
**server_name** your domain;
**location** / {
**proxy_pass** http://127.0.0.1:8000;
**proxy_set_header** Host $host;
**proxy_set_header** X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
如果这是你的第一台 NGINX 服务器,你必须解除 NGINX 默认站点的链接:
sudo unlink /etc/nginx/sites-enabled/default
接下来,我们需要设置一个主管。和 NGINX 一样,supervisor 的配置文件。我的服务器在 Ubuntu 上,尽管我痴迷于 RHEL,所以安装 supervisor 就像
sudo apt-get install supervisor
现在我们将创建一个新的配置。
sudo nano /etc/supervisor/conf.d/flask_app.conf
以下是我的主管配置:
[program:genieapp]
directory=/var/www/CarPricePredictor
command=. bin/server
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stderr_logfile=/var/log/appname/lognameerr.log
stdout_logfile=/var/log/appname/lognamestdout.log
命令和目录是您应该在这里查看的两个参数。我们将把 SH 文件放在我们的 Genie 端点附带的 bin/server 中,这将自动启动一个我们可以使用的 Genie 服务器。我们还需要运行上述命令的目录,差不多就是这样。现在我们只需要重新加载我们的服务:
sudo nginx -s reload
sudo service supervisor reload
现在我们的端点已经部署好了!
结论
Julia 部署并不太难,最近已经变得更容易了。每当我第一次进入 Genie 时,文档是绝对糟糕的。幸运的是,随着时间的推移,这种情况已经发生了变化,现在这个工具比以往任何时候都更容易使用。车床模型也是我认为非常酷的一个方面。或者,您也可以使用车床部署管道。以下是为老版本的车床部署管道的教程:
旧版本和新版本的区别在于,现在管道只接受一个参数:
台阶。
所以为了做一个管道,你只需要做:
using Lathe.preprocess
scaler = Normalizer(xt)
using Lathe.models
mdl = LinearRegression(trainX,trainy)
pipl = Pipeline([scaler, mdl])
yhat = pipl.predict(xt)
很酷,对吧?
所以管道部署肯定是可行的,而且在 Julia 中使用车床也很酷。我很兴奋地看到这种方法能够在这方面使用车床进行机器学习到什么程度,因为管道肯定是 DS 生态系统的重要组成部分。
10 分钟内探索性数据分析的 A-Z
数据以各种形式出现,数量巨大。图片来自 Pixabay 佳能-eos
EDA 是迈向数据科学的第一步。
探索性数据分析 (EDA)无论是回归还是分类,都是任何模型最关键的阶段,但往往被轻描淡写或忽略。EDA 清楚地显示了数据以及不同特性或不同数据特性组合对输出的依赖性。
我去维基百科寻找更多信息,下面是它的定义:
探索性数据分析 (EDA)是一种分析数据集以总结其主要特征的方法,通常采用可视化方法。统计模型可以使用,也可以不使用,但 EDA 主要是为了查看数据在正式建模或假设检验任务之外能告诉我们什么。
现在,问题是如何执行 EDA。下面是使用一个例子来执行 EDA 的简单方法。
下面是帖子的流程,
- 数据集简介
- 查看数据
- 单变量分析
- 概率密度函数
- 累积密度函数
- 箱形图
- 小提琴情节
4.双变量分析
- 散点图
- 配对图
5.多变量分析
- 等值线图表
让我们开始吧!!
- 数据集介绍
先说几个常用术语:
- 数据集是所用数据的集合(通常是一张表)
- 数据点是数据集(如行)中的每个观察值
- 目标,也叫因变量或输出变量,是要预测或分析的变量。
- **特征,也叫-**输入变量或自变量是用来确定因变量的一个变量或变量的集合。
让我们用从 Kaggle 设置的 Haberman 的生存数据来探索 EDA。
接受乳腺癌手术患者的存活率
www.kaggle.com](https://www.kaggle.com/gilsousa/habermans-survival-data-set)
属性信息:
1。手术时患者的年龄(数值)
2。患者手术年份(年份— 1900,数字)
3。检测到的阳性腋窝淋巴结数(数值)
4。存活状态(类别属性)1 表示患者存活了 5 年或更长时间,2 表示患者在 5 年内死亡
目的:
2。调查数据
import pandas as pd
data = pd.read_csv('haberman_data.csv')
导入熊猫来读取数据。使用 pandas 将 Kaggle 中的 CSV(逗号分隔值)文件分配到数据框中。
data.shape
输出:(305,4)
数据集有 305 个数据点,4 个特征
让我们看看数据如何,
data.head()
数据集中的前 5 个元素
这里,数据集没有任何标题(列名)。第一个数据点被作为标题。因此,我们需要添加一个头。
header_list=['age','op_year','axil_nodes','surv_status']
haberman_data = pd.read_csv('haberman_data.csv',names=header_list)
添加要素名称并将数据加载到数据框中。
haberman_data.head()
添加特征名称后数据集的前 5 个元素
现在,数据已经有了特征名称。
haberman_data['surv_status'].value_counts()
输出:
1 225
2 81
Name:surv _ status,dtype: int64
该数据是不平衡数据,这意味着“surv_status”的每个类别中的数据点数量不相似。
现在我们有了数据的图片,让我们开始进一步分析它。
3。单变量分析
单变量分析,顾名思义,就是简单的用一个变量进行分析。这种分析给出了变量出现的频率/计数,并让我们了解该变量在不同值下的分布。
3.1。概率密度函数(PDF) :
在 PDF 绘图中,X 轴是进行分析的要素,Y 轴是数据中特定 X 轴值出现的次数/频率。因此在 PDF 中出现了术语**“密度”**。
import seaborn as sns
sns.set_style("whitegrid")
Seaborn 是一个提供各种类型的分析图的库。
sns.FacetGrid(haberman_data,hue='surv_status',height=5).map(sns.distplot,'age').add_legend()
输出:
时代的 PDF
观察结果:
- 主要的重叠被观察到,所以我们不能清楚地说年龄对生存的依赖性。
- 粗略估计,20-50 岁的患者存活率稍高,75-90 岁的患者存活率较低。
- 年龄可以被认为是一个因变量。
sns.FacetGrid(haberman_data,hue='surv_status',height=5).map(sns.distplot,'op_year').add_legend()
输出:
运营年份的 PDF
观察结果:
- 重叠是巨大的。
- 运营年份本身并不是一个高度相关的变量。
sns.FacetGrid(haberman_data,hue='surv_status',height=5).map(sns.distplot,'axil_nodes').add_legend()
输出:
腋窝淋巴结的 PDF
观察结果:
- 0 淋巴结的患者生存概率高。
- 腋淋巴结可以作为因变量。
PDF 的缺点:在 PDF 中,我们无法准确说出有多少个数据点在某个范围内/低于某个值/高于某个特定值。
3.2。累积密度函数(CDF) :
要知道低于/高于特定值的数据点的数量,CDF 非常有用。
让我们从根据存活率的类别来分离数据开始。
survival_yes = haberman_data[haberman_data['surv_status']==1]
survival_no = haberman_data[haberman_data['surv_status']==2]
现在,让我们分析这些分离的数据集。
import numpy as np
import matplotlib.pyplot as plt
count, bin_edges = np.histogram(survival_no['age'], bins=10, density = True)
#count : the number of data points at that particular age value
#bin_edges :the seperation values of the X-axis (the feature under analysis)
#bins = the number of buckets of seperation
pdf = count/sum(count)
print(pdf)
# To get cdf, we want cumulative values of the count. In numpy, cumsum() does cumulative sum
cdf = np.cumsum(pdf)
print(cdf)count, bin_edges = np.histogram(survival_yes['age'], bins=10, density = True)
pdf2 = count/sum(count)
cdf2 = np.cumsum(pdf2)plt.plot(bin_edges[1:],pdf,label='yes')
plt.plot(bin_edges[1:], cdf,label='yes')
plt.plot(bin_edges[1:],pdf2,label='no')
plt.plot(bin_edges[1:], cdf2,label='no')
plt.legend()
#adding labels
plt.xlabel("AGE")
plt.ylabel("FREQUENCY")
输出:
[0.03703704 0.12345679 0.19753086 0.19753086 0.13580247 0.12345679
0.09876543 0.04938272 0.02469136 0.01234568]
[0.03703704 0.16049383 0.35802469 0.55555556 0.69135802 0.81481481
0.91358025 0.96296296 0.98765432 1\. ]Text(0, 0.5, 'FREQUENCY')
关于年龄的分离数据
观察结果:
- 大约 80%的数据点的年龄值小于或等于 60 岁
count, bin_edges = np.histogram(survival_no['axil_nodes'], bins=10, density = True)
pdf = count/sum(count)
print(pdf)cdf = np.cumsum(pdf)
print(cdf)count, bin_edges = np.histogram(survival_yes['axil_nodes'], bins=10, density = True)
pdf2 = count/sum(count)
cdf2 = np.cumsum(pdf2)plt.plot(bin_edges[1:],pdf,label='yes')
plt.plot(bin_edges[1:], cdf,label='yes')
plt.plot(bin_edges[1:],pdf2,label='no')
plt.plot(bin_edges[1:], cdf2,label='no')
plt.legend()
plt.xlabel("AXIL_NODES")
plt.ylabel("FREQUENCY")
输出:
[0.56790123 0.14814815 0.13580247 0.04938272 0.07407407 0.
0.01234568 0\. 0\. 0.01234568]
[0.56790123 0.71604938 0.85185185 0.90123457 0.97530864 0.97530864
0.98765432 0.98765432 0.98765432 1\. ]Text(0, 0.5, 'FREQUENCY')
腋窝淋巴结分离数据的 CDF,PDF
观察结果:
- 大约 90%的数据点具有小于或等于 10 的 axil_node 值
3.3。箱线图
在探索箱线图之前,一些常用统计术语是:
- median(第 50 个四分位数)是排序数据的中间值
- 第 25 个四分位数是排序数据中的值,其中 25%的数据小于它,75%的数据大于它
- 第 75 个四分位数是排序数据中的值,其中 75%的数据小于它,25%的数据大于它。
在箱线图中,下面的线代表第 25 个四分位数,中间的线代表中位数/第 50 个四分位数,上面的线代表第 75 个四分位数。晶须代表大多数图中的最小值和最大值或一些复杂的统计值。使用 seaborn 时,胡须不是最小值和最大值。
sns.boxplot(x='surv_status',y='age', data=haberman_data)
sns.boxplot(x='surv_status',y='axil_nodes', data=haberman_data)
sns.boxplot(x='surv_status',y='op_year', data=haberman_data)
输出:
<matplotlib.axes._subplots.AxesSubplot at 0x1795943de08><matplotlib.axes._subplots.AxesSubplot at 0x179594b4948>
<matplotlib.axes._subplots.AxesSubplot at 0x1795b18ac88>
年龄、腋窝淋巴结、手术年份的箱线图
3.4。小提琴剧情:
小提琴图是箱线图和密度函数的组合。
- 白点代表中间值。
- 较粗的黑线的边缘代表四分位数。
- 小提琴形结构的边缘代表最小值和最大值
- 形状的宽度表示该值处数据点的密度/频率。
sns.violinplot(x='surv_status',y='age', data=haberman_data)
plt.show()sns.violinplot(x='surv_status',y='op_year', data=haberman_data)
plt.show()sns.violinplot(x='surv_status',y='axil_nodes', data=haberman_data)
plt.show()
年龄,手术年份,腋窝淋巴结的小提琴图
观察结果:
- 75-90 岁的患者不太可能存活,30-40 岁的患者更有可能存活。
- 运营年度似乎没有给出确切的信息,因为它几乎平均分布在给定的几年中。
- 淋巴结值低的患者更有可能存活。
4。双变量分析:
在本节中,我们将一次使用两个独立变量来分析数据。
4。1.散点图:
散点图广泛用于比较两个变量,并帮助我们分析目标变量如何依赖于它们的组合。
在散点图中,X 轴代表一个自变量,Y 轴代表另一个自变量。
通过将目标变量赋予 seaborn 提供的面网格函数中的色调参数,可以用颜色编码来表示目标变量。
sns.FacetGrid(haberman_data, hue="surv_status", height=8) \
.map(plt.scatter, "age", "op_year") \
.add_legend();
输出:
年龄和操作年份散点图
sns.FacetGrid(haberman_data, hue="surv_status", height=8) \
.map(plt.scatter, "age", "axil_nodes") \
.add_legend();
输出:
年龄和腋窝淋巴结散点图
sns.FacetGrid(haberman_data, hue="surv_status", height=8) \
.map(plt.scatter, "axil_nodes", "op_year") \
.add_legend();
输出:
腋窝淋巴结散点图和手术年份
4.2。配对图:
结对图有助于用一行代码将所有变量相互比较。这可以被认为是所有可能的散点图。当特征数量较少时,可使用配对图。在这个有 3 个独立变量的例子中,配对图的数量是 9(3X3)。因此,对于任何具有 10 个特征的数据,配对图的数量将是 100。因此,当特征数量较少(~7)时,通常使用配对图。
这是一行代码:
sns.pairplot(haberman_data, hue="surv_status", height=5)
年龄、手术年份、腋窝淋巴结配对图
5。多变量分析:
在本节中,我们将使用多个变量来分析数据的分布。
5.1。等高线图:
等高线图是一种图形技术,通过在二维格式上绘制称为等高线的恒定 z 切片来表示三维表面。
import seaborn as sns
g=sns.jointplot(x = 'op_year', y = 'age', data = haberman_data, kind = 'kde')
输出:
年龄和手术年份等高线图
此处,手术年份、年龄是两个参数,而为图提供蓝色阴影的 3D 参数是患者手术年份和年龄组合的计数。
观察结果:
大量的手术是在 60-64 岁和 45-55 岁之间进行的
结论:
- 40 岁以下的患者可能有较高的存活率,75 岁以上的患者可能有较低的存活率。
- 腋窝淋巴结越低,生存机会越高。
- 然而,年龄、手术年份或腋窝淋巴结这三个变量中的任何一个都不足以准确决定患者的生存率,而且数据集是不平衡的。因此,分类是困难的。
谢谢你的阅读。我也将在未来写更多初学者友好的帖子。请在媒体上关注我,以便了解他们。我欢迎反馈,可以通过 LinkedIn RamyaVidiyala 联系
AAAI 2020:无监督的深度学习和可以推理的人工智能
AAAI 第三十四届年会刚刚在纽约闭幕。不出所料,这是一次有数千名人工智能研究人员和实践者参加的大型会议。一大亮点是 2018 年 ACM 图灵奖获奖者 Geoffrey Hinton、Yann LeCun 和 Yoshua Bengio 的演讲,以及与丹尼尔·卡内曼的小组讨论。
我也有机会与扬·勒村和丹尼尔·卡内曼交谈。我还确保捕捉了一些照片。
图灵三人组又名深度学习教父
Yoshua Bengio、Geoffrey Hinton 和 Yann LeCun 因概念和工程突破而获得 2018 年 ACM A.M .图灵奖,这些突破使深度神经网络成为计算的关键组成部分。ACM A.M .图灵奖也被称为“计算机科学界的诺贝尔计算奖”。深度学习已经成功应用于语音识别、机器翻译、推荐系统以及自动驾驶汽车等多个领域。深度学习有各种各样的应用,目前许多大型技术公司都是围绕这种方法建立的。可以说,深度神经网络是近期最重要的计算进步的原因。然而,这些模型有它们的缺点,例如它们的决策难以解释,它们(被监督的)需要大量高质量的数据点,以及它们甚至不能进行基本的推理。在个别谈话中,他们每个人都谈到了当前的挑战,未来的方向,以及他们实验室最近的研究,以推动当前深度学习模型的局限性。
杰弗里·e·辛顿:使用自动编码器的胶囊网络
唐·辛顿的演讲是关于 CNN 的局限性以及如何克服这些局限性。在他看来,CNN 和我们识别物体的方式不同。当人们感知形状时,他们使用坐标框架并总是分配固有坐标框架——这是人类感知的一个重要方面。相比之下,CNN 依赖于重合——等式两边的值之间的重合,以及使得高维过滤器识别图像的重合。
我们希望神经网络毫不费力地推广到新的视点,只有当它们能够像处理视点转换一样处理好旋转和缩放时,这才会发生。
他最近一直在开发胶囊网络。想法是使用一组神经元来表示给定图像的片段,然后使用这些学习到的子表示来表示图像,以识别图像。他首先在 NIPS 2017 和最近的 NeurIPS 2019 中介绍了胶囊网络。
当前版本的胶囊网络是无人监管的,与前两个完全不同。它们被称为堆叠胶囊自动编码器,基于创成式建模技术。
Yann LeCun:革命将会自我监督
Don LeCun 在他的演讲中首先定义了深度学习,并指出监督学习的所有限制有时被错误地视为 DL 的内在限制。在他看来,当我们拥有大量数据或可以模拟环境进行太多尝试以学习任何东西时,监督学习和强化学习确实会分别嵌套。然而,在现实世界的场景中,获得良好的标记数据也是一个问题,因为我们无法以比实时更快的速度运行现实世界来尝试各种场景——很多时候,任务看起来很简单,但一个小错误也会杀死我们。
为了实现这种智能水平的预测,我们需要想出方法来解决深度学习面前的三个主要挑战。他在脸书和 NYU 的研究小组正在研究自我监督学习来克服这一挑战。预测是智能的本质,我们人类通过预测来自其他部分的部分输入,来自过去的未来,来自可见的掩蔽部分,以及来自所有可用部分的任何被遮挡部分来学习世界的模型。
在 2016 年的一篇教程中,他对基于能量的模型进行了如下描述:基于能量的模型(EBM)通过将标量能量与变量的每个配置相关联来捕捉变量之间的依赖关系。推理包括钳制观察变量的值,并找到剩余变量的配置,使能量最小化。学习包括寻找一个能量函数,其中观察到的变量配置比未观察到的配置具有更低的能量。
EBM 对适当的规范化没有要求,这个问题自然就被回避了。EBM 可以被视为非概率因素图的一种形式,与概率方法相比,它们在架构和训练标准的设计方面提供了更大的灵活性。
我们可以在一篇完整的笔记中更多地讨论他讨论的塑造基于能量的函数的七个策略以及他的研究团队中的其他 SSL 工作。
Yoshua Bengio:意识优先和世界模型
Yoshua 谈到了他在实现人类级别的 AI 方面所做的努力。用他的话说,“没有完全通用的智能——这些总是一些归纳的基础和先验。”越简单越少的先验越有可能被发现,并且可以被结合起来理解更广泛的背景。
他谈到了开发世界(或世界事件)模型并让神经网络学习它的可能性。这可以帮助深度学习根据系统 1 学习系统 2。系统 1 和系统 2 的概念来自丹尼尔·卡内曼。在《思考,快与慢》一书中,丹尼尔·卡内曼将系统 1 描述为快速、自动、频繁、情绪化、刻板、无意识,锚定在人类的感官知觉中,而系统 2 描述为缓慢、努力、不频繁、有逻辑、精于计算、有意识。理性的,有序的,可以用语言表达的。
系统 1 自动且快速地运行,很少或没有努力,并且没有自主控制的感觉。与此同时,系统 2 将注意力分配给需要它的费力的脑力活动,包括复杂的计算。系统 2 的运作通常与代理、选择和集中的主观体验有关。
某种层面的深度学习可以做到像系统 1 一样的自动感知,挑战在于如何将 DL 从系统 1 扩展到系统 2。如果我们需要一些先验意识来表示高级概念,并使用 DL 来预测各种先验的值?如果这些先验能以某种方式结合起来做一些真正人类水平的推理和理解?
从很多方面来说,这是一次积极的、前瞻性的谈话。他们回答了围绕深度学习及其局限性的各种问题。对他们来说,获得他们项目的录取是多么困难,以及大学教育的重要性。用 Gefforry Hinton 的话来说——无论大型科技公司拥有多少资源,好想法都会来自一个在这个问题上花了足够时间的研究生。
Hinton,LeCun,Bengio 都同意 AI 需要有推理能力。虽然不清楚推理应该使用神经网络还是神经网络应该学习推理。
复杂问题回答的推理
我们在语言理解方面取得了巨大进步,像 Siri、Alexa 和谷歌助手这样的问答系统已经成为我们生活中无处不在的一部分。然而,这些最先进的解决方案仍然无法进行基本的推理,也无法回答任何复杂的问题。即使我们不谈论大规模生产就绪的解决方案,也没有具体的研究工作解决方案可以进行推理和解释任何情况。他们很肤浅,研究信息检索的原理;给定一个查询和一个故事,他们试图找到最佳回答用户查询的跨度长度。在 AAAI 有一个全天的研讨会,试图讨论复杂问题回答中的挑战和成功。
这个研讨会做了很好的工作,将研究工作引入到克服这个缺点,开发故事理解的解决方案,并回答复杂的问题。现在,这篇文章将详细描述一些我觉得更有趣的演讲。
Ray Mooney 教授讨论了逻辑和基于向量的方法的局限性,以及如何整合它们。它可以帮助我们获得更好的因果解释,并对“为什么”问题有更深的理解。他描述了如何使用彗星模型来构建给定事件的因果图,并使用它来更好地了解基于计划的理解,在这些因果图中应用马尔可夫链看起来很有前途。它显示了神经符号方法的潜力和保持这一研究方向新发展的关键的原因。
来自的纳斯林展示了他们在常识推理和叙事理解方面的工作。他们一直致力于开发儿童书籍的心智模型,并将它们融入最先进的语言理解模型中。
任何孩子都可以很容易地理解这个故事,可能是通过对所讨论的场景建立一个心理模型。如何让一个深度模型理解它?
目前人工智能的进步是显著的,但我们仍然无法推理或解释儿童故事书中提到的简单场景。在这个方向上已经有了一些工作,Atomic 是这个方向上最令人兴奋和最新的工作。在这里,纳斯林在葡萄糖方面领先一步。他们将故事解释的因果心理模型定义为 10 维空间、5 个原因和 5 个原因维度。
葡萄糖框架
这对我来说是一个更令人兴奋的演示,因为我一直在研究 Atomic 和 Comet,并且刚刚开始了一个类似方向的新项目。葡萄糖不仅通过添加更多的因果维度扩展了原子,而且还基于给定故事细节的各种推断因果创建了逻辑推理的推理规则。
葡萄糖:统计和实例
她提供的关于从零开始训练编码器-解码器模型的另一个有见地的信息比从零开始训练基于转换器的模型给出了更好的性能。不过,微调基于变压器的模型可以获得最佳精度。
我真的很兴奋,期待几个月后能读到这篇论文。他们已经向 ACL 提交了他们的工作,正在等待接受。
我也喜欢 Sameer Singh 教授关于 T2 评估和测试问题回答能力的演讲,以及 T4 Dan Roth 教授关于为什么(以及如何)我们应该学习问题回答的演讲。
Sameer 谈到了我们最先进的 NLU 模型的脆弱性,他的各个研究小组正在进行调查,以对 QA 系统进行更彻底的评估。
脆弱的质量保证系统
他的团队正在研究干扰数据集中实例的自动化技术,这些实例可以识别问答过程中的漏洞和捷径,包括语义对手和通用触发器。
丹以约翰·麦卡锡在《纽约时报》的故事为例开始了他的演讲。
约翰·麦卡锡的纽约时报的例子
我们任何一个人都可以从上面的文章中推断出的事情
1976 年,麦卡锡在谈到不良贷款及其引发的问题时,举了一个简单的例子,即《纽约时报》的一个故事,讲述了一名推销员被推下电梯井的故事,以及我们如何回答各种问题,即使在今天,也没有自动化模型能够回答这些问题。
一个好的系统应该很容易回答这些问题
回答这些高级自然语言理解问题仍然超出了我们的能力,部分原因是这些任务中的大多数是稀疏的,并且我们当前为其生成监督信号的方法没有扩展。Dan 提到了一些最近的工作,包括使用语义图来回答这些高级推理问题,以及一些最近的时态常识数据集,作为前进的方向。
总之,问答是人类理解语言和世界的方式,也是一种诱导表达的方式,有助于我们做得更好。
还有很多我喜欢的其他演讲和海报。我会试着把它们列一个清单,并简单描述一下(也许在下一篇文章中)。这是一次学习的经历——我认识了几个来自 UT-Austin 的同事,我前雇主的同事,还交了几个新朋友。
不幸的是,由于冠状病毒的流行,许多研究人员无法展示他们的工作。我希望我们能很快找到治疗冠状病毒的方法。
参考资料:
以上大部分材料是基于我对演示文稿的理解、我拍摄的照片以及来自演示者的共享幻灯片和相关论文。其中一些列举如下:
- https://aaai.org/Conferences/AAAI-20/
- https://awards.acm.org/about/2018-turing
- 堆叠胶囊自动编码器
- 自我监督学习:Yann、LeCun 分享的幻灯片
- 基于能量的方法教程
- 思维快与慢
- Yoshua Bengio 的《意识优先》
- 复杂问题回答的推理
- 原子
- 彗星
AAMAS-20:自主代理和多代理系统自由会议
多智能体系统越来越重要。这里有一个免费的资源来学习前沿研究!
智能体,可以与其环境或其他智能体进行交互的实体,是人工智能中一个越来越重要的领域。代理可以学习,推理他人,采用规范,并在虚拟和物理环境中与人类互动。该领域包括对人工智能许多领域的贡献,包括博弈论、机器学习、机器人、人机交互、建模和社会选择。虽然大部分工作是基于实验室实验的学术研究,但也有越来越多的实际部署对政府和商业组织产生了直接影响。国际 AAMAS 会议,现在是第 19 届,在网上举行,出席是免费的**,而注册费通常超过 700 美元。**
本次会议于 5 月 9 日周六开始,为期两天的研讨会和辅导。5 月 11 日星期一至 5 月 13 日星期三有 300 多场论文报告和主题演讲,主讲人包括卡拉·戈麦斯、艾莉森·赫本斯塔尔、谢尔盖·莱文和托雷·格雷佩尔。ACM SIGAI 自主智能体研究奖演讲将由穆尼德尔·p·辛格发表,而张秀坤·皮特斯将为维克托·莱瑟博士论文颁奖。
虽然所有视频都将在 2020 年底之前在 underline.io 上异步观看,但 underline.io 也将支持活动期间的现场问答环节。会议记录将一如既往地在网上免费提供。
如果你有兴趣了解更多关于自主代理和多代理系统的令人兴奋的领域,我们希望你能加入我们!
-马修·泰勒,代表奥玛组织 20 名主席 Amal El Fallah Seghrouchni 和 Gita Sukthankar
附加细节
自主代理和多代理系统(AAMAS)会议系列聚集了来自世界各地的研究人员,分享该领域的最新进展。它是研究自主代理和多代理系统的理论和实践的首要论坛。第一届 AAMAS 2002 在博洛尼亚举行,随后是墨尔本(2003 年)、纽约(2004 年)、乌特勒支(2005 年)、函馆(2006 年)、檀香山(2007 年)、埃斯托里尔(2008 年)、布达佩斯(2009 年)、多伦多(2010 年)、台北(2011 年)、巴伦西亚(2012 年)、圣保罗(2013 年)、巴黎(2014 年)、伊斯坦布尔(2015 年)、新加坡(2016 年)。本卷是 AAMAS 2020 系列会议中的第 19 次会议,将于 2020 年 5 月在奥克兰举行。
AAMAS 2020 邀请提交一般轨道、蓝天想法轨道和展示 JAAMAS(自治代理和多代理系统杂志)论文的轨道,这些论文以前没有在主要会议上展示过。蓝天创意赛道由 Alessandro Ricci 和 Juan Antonio Rodriguez 主持。Rym Zalila-Wenkstern 和 Pı nar Yolum 从过去 12 个月中在 JAAMAS 上发表的论文中征集论文,用于 JAAMAS 演讲。
选出了一组地区主席(AC)来帮助监督主要路线的审查过程。ACs 对提交的文件进行了初步检查,并建议立即拒绝那些不符合 AAMAS 范围、提交或格式说明的文件。
十个地区的主席与计划主席共同负责任命高级计划委员会(SPC)成员,而高级计划委员会成员反过来又帮助确定了一组强大而多样化的计划委员会(PC)成员。PC 可以审查多个领域。每篇论文都由至少三名 PC 成员审阅,并由一名 SPC 成员监督,确保审阅内容清晰、信息丰富。在作者有机会对评审者做出回应后,SPC 成员主持了一场讨论,在讨论中评审者考虑了彼此以及作者的意见。区域主席反过来与项目主席合作,对论文的接受做出最终决定,以确保一致的高质量。
AAMAS 2020 吸引了大量高质量的提交材料:完整论文的总体接受率为 23%(808 份经审查的提交材料中有 186 份被接受)。
虽然所有被接受的论文都是高质量的,但从主流中选出的几篇论文被提名为最佳论文奖和 Pragnesh Jay Modi 最佳学生论文奖。最佳论文奖在会上颁发给最佳论文,Pragnesh Jay Modi 最佳学生论文奖颁发给主要由学生撰写的其余最佳论文。最佳学生论文奖是由斯普林格赞助的。这些奖项的提名名单如下,按第一作者姓氏的字母顺序排列;主要由学生撰写的论文标有星号(*)。这些论文还被提名为《人工智能研究杂志》(JAIR)的加速审查。
- Harshavardhan Kamarthi、Priyesh Vijayan、Bryan Wilder、Balaraman Ravindran 和 Milind Tambe。未知社会网络中的影响力最大化:有效图形采样的学习策略
- Divya Ramesh、Anthony Z. Liu、Andres J .、Jean Y. Song、Nicholas R. Waytowich 和 Walter S. Lasecki。昨天的奖励是今天的惩罚:人类对强化学习代理反馈的对比效果
- Klaus Weber、Kathrin Janowski、Niklas Rach、Katharina Weitz、Wolfang Minker、Stefan Ultes 和 Elisabeth André。使用双极加权论证图预测多模态行为适应的说服效果
- 尚同·张、温德林·贝默和西蒙·怀特森。深度残余强化学习
此外,IFAAMAS 影响力论文奖将在会议上颁发给以下两篇论文:
- Ariel D. Procaccia 和 Moshe Tennenholtz。无钱近似机制设计。《第十届 ACM 电子商务会议论文集》,第 177–186 页,2009 年。
- 科特·m·德雷斯纳和皮特·斯通。自主交叉口管理的多智能体方法。《人工智能研究杂志》,第 31 卷,第 591–656 页,2008 年。
Aaron Mayer:授权工程师建设更美好的世界
技术创新者系列
对 Impact Labs 联合创始人的采访
技术进步正以指数速度增长。数据素养正在成为许多行业的先决条件,许多热门的、新的和高薪的工作都在大型科技巨头那里。现在,比以往任何时候都更加明显的是,这种增长带来了责任——以及围绕可持续技术增长的光明未来的潜力。一个组织站在这场运动的最前沿,让技术人员能够利用他们的技能造福社会。
图片由 Aaron Mayer 提供
Impact Labs 在技术和社会公益之间架起了一座桥梁。他们将学生与经验丰富的社会企业家联系起来,同时在可持续技术领域创造有意义的机会。
“我意识到,就像很多人一样,技术有巨大的能力来影响世界的变化。”
亚伦·梅尔在布朗大学的宿舍里创建了 Impact Labs。虽然布朗大学约 20%的本科生专注于计算机科学,但这些学生中的大多数最终都在知名科技公司工作。面对这种“看似有限的”职业机会,亚伦开始增加工作的可见性,让学生能够创造积极的社会变革,而不牺牲他们的薪水。为了探索是什么激励他在技术和社会公益的交叉点上进行建设和创新,我和 Aaron 谈论了他的旅程。
图片由 Impact Labs 提供
Amber: 你能告诉我们一些你的背景吗?
伦:确定!我从小就是一个笨拙的书呆子,喜欢 STEM,但却选择了人文学科。后来才知道,那些探究的分支其实差别挺小的。在上大学之前,我利用间隔年去了 15 个国家,那是我第一次亲眼目睹贫富之间的严重不平等。
当我终于上学的时候,我学的是哲学,重点是伦理学。后来,我回到了我最初对科学和技术的热爱,我一直在思考,我们认为理所当然的技术工具是如何对那些没有分享我们好运的人的生活产生如此巨大的影响的。我想这最终导致了冲击实验室的建立。
Impact Labs 在技术和社会公益之间架起了一座桥梁。
你一直都知道在科技领域工作是你想做的吗?
AM: 创办公司绝对不在计划之内!如果你在大学问我想做什么,我可能会说我想成为一名科学老师或者一名记者。对我来说,技术和创业文化如影随形,就像他们经常做的那样,但这在很大程度上是偶然的。我记得我在布朗大学期间去过我的校园创业中心,纯粹是因为他们总是在活动中提供免费的印度食物。在大学的这个领域逗留了足够长的时间并结识了新朋友之后,我像许多人一样意识到,技术具有巨大的能力来影响世界的变化。这并不是说,我认为教育和立法等事情不能同样改变世界,但我认为我是被降低的准入门槛所逼:毕竟,任何人都可以创办公司或开发一个应用程序,可以想象这一天可以覆盖数十亿人,这种规模在其他地方真的不存在。
图片由 Aaron Mayer 提供
AT: 在您的 TEDx 演讲“我们时代的超级英雄”中,您描述了年轻的理想主义技术专家对构建更加公平和可持续的未来的需求。为什么你认为今天的技术人员在职业生涯中考虑公平、道德和可持续性很重要?简而言之,如果我们不做,就没有人会做。当你听到“科技”这个词时,你可能会想到世界上的微软和 IBM。这些可能是令人敬畏的公司,但解决气候变化、教育不普及、性别不平等、被忽视的热带疾病和贫困的科技公司在哪里?如果工程师代表了我们这一代最优秀、最聪明的头脑,难道他们不应该致力于解决我们作为一个物种所面临的最大、最根深蒂固的挑战吗?
我要补充的是,许多改变世界的公司通常会付出巨大的环境和社会成本。看看苹果和亚马逊的劳工行为,或者谷歌和脸书的侵犯隐私行为,不要让我开始谈论国防工业。我相信,为这些公司制造产品和服务的工程师和技术人员拥有坚强的道德品质和坚定不移的正直是至关重要的:如果他们拒绝制造有害的工具,那么有害的工具就不会被制造出来。
当然,不一定要像在 Snapchat 罢工那么戏剧化。软件工程师、UX 设计师、数据科学家等。都可以尽自己的一份力量,通过大声说出他们工作的公司潜在的有害方面,来降低他们所创造的技术的负面影响。
图片由 Impact Labs 提供
AT: Impact Labs 旨在“激励和授权年轻的工程师去建设一个更美好的世界”。Impact Labs 是如何实现这一使命的?
**上午:**我们在 Impact Labs 开展了一系列计划,这些计划都是根据我们的使命设计的。我们主持的第一个节目叫做影响力奖学金。一年一度的伙伴计划即将进入第四个年头,它聚集了对社会公益事业充满热情的高素质工程师,他们将在为期两周的时间里作为一个社区一起学习、建设和成长。我们还举办现场活动,例如我们的年度影响力峰会,在这里,年轻的技术专家和早期企业家可以聆听演讲者的演讲,并向社会创业领域的研讨会领导者学习,他们正在利用技术建立一个更加公平、可持续的社会。此外,我们还开展了一项名为 The Impact Coalition 的招聘计划,这基本上是高影响力组织的常用应用程序:一名工程师提交一份申请,然后我们会在我们投资组合中的数十家公司中为他们找到与他们的技能和兴趣最匹配的工作。此外,如果我可以自夸的话,我们有一个精彩的双周刊时事通讯,它汇集了社会影响世界技术中的机会和新闻更新,发给 5000 多名年轻工程师,所以我对此非常自豪。在不久的将来,我们一直在探索直接与大学合作的方法,让他们在计算机科学课程中实施道德要求。顺便说一句,所有这些项目都是 20 位不可思议的队友贡献的直接结果,如果没有他们的奉献和承诺,Impact Labs 就不会有今天的成就。我喜欢与他们合作,在一个我们都相信的项目上一起工作是一种快乐!
图片由 Aaron Mayer 提供
AT: 你认为下一代有抱负的技术人员面临的最大挑战是什么,目前在行业中的数据科学家可以做些什么来帮助他们?
AM: 目前,我认为最大的挑战是有悖常理的经济激励。请原谅我戴上马克思主义的帽子,众所周知,大多数公司都有基于利润的生存和发展动机,这也是我之前提到的有害副作用的最常见原因。然而,因为科技公司如此富有,他们可以支付(高得离谱的)高薪给数据科学家、机器学习专家和其他保持引擎运转的工程师。太多聪明、理想主义的技术专家被六位数的薪水所诱惑,我有太多的朋友向我承认,如果不是为了钱,他们根本不可能在帕兰蒂尔或高盛这样的机构工作。
这就是为什么我们在 Impact Labs 尽最大努力向那些通过行善而获得成功的公司展示通向有意义职业生涯的道路。当你为一家社会创业公司工作时,这并不是说你将自己托付给了贫困的生活,以我自己的经验来看,为你真正支持的使命工作的感觉是无价的。
AT: 对于其他有志于发展职业生涯并在行业中产生积极社会影响的技术专家和工程师,你有什么建议?
AM: 开始点什么!说真的,我知道这是老生常谈,但你通过自己尝试和失败学到的东西比做任何其他事情都多。
如果你完全确定成为一名创始人不是你想要的(我会再次确认这种确定性,因为成为一名创始人可能非常有趣!),那么我的建议是这样的:从你的理想职业向后工作。如果你想成为白宫的首席技术官,那么今天就开始采取措施,你有证据表明这些措施会让你在未来走上这个职位的轨道。谷歌一下那些拥有你梦想工作的人,试着模仿他们的传记——更好的是,直接联系他们!如果你带着强烈的好奇心和爱去接近他们,你会惊讶于人们是多么的容易接受!
“许多改变世界的公司往往以巨大的环境和社会成本为代价.”
AT: 我们的读者如何参与 Impact Labs?
AM: 很多方法!第一件也是最简单的事情就是在这里注册订阅我们的时事通讯!你也可以关注我们的脸书页面和推特,并加入我们的脸书群!我们将在今年 8 月举办下一次峰会,它将完全在线,所有人都可以访问,所以你应该完全参与!详情及在impactlabs.io/summit报名!
最后,虽然 Impact Labs 并没有明确加入有效利他主义运动,但如果你还不熟悉的话,你绝对应该去看看 EA。我们在 Impact Labs 所做的大部分工作都明确遵循 EA 的原则,如果你对改变你的职业感兴趣,这是一个很好的方式来开始问自己一些基本的问题,关于你如何才能做到最好。
图片由 Impact Labs 提供
Impact Labs 在技术和社会公益的核心领域引领可持续创新。Impact Labs 不仅将热情的学生与利用技术产生社会影响的领导者联系起来,还建立了一个聚焦全球发展未来的社区。
特别感谢 Aaron Mayer 允许我为这个系列采访他,也非常感谢 TDS 编辑团队对这个项目的支持。
你认识一位鼓舞人心的技术专家,你希望他出现在这个系列中吗?你是否正在从事任何你希望我写的很酷的数据科学和技术项目?欢迎给我发电子邮件,向 angelamarieteng@gmail.com 寻求意见和建议。感谢阅读!
[1]https://www . brownalumnimagazine . com/articles/2019-09-09/hi-tech-ethics
【2】https://www.youtube.com/watch?v=zrjNBWMY8qM
参考文献:
"恩尼格玛福音传道者和 Impact Labs 创始人在普林斯顿——新泽西州技术周刊发表演讲."n.d .于 2020 年 5 月 26 日获得。https://njtechweekly . com/enigma-evangelist-and-impact-labs-founder-speaks-in-Princeton/。
“影响实验室——联盟。”n.d .于 2020 年 5 月 26 日获得。https://www.impactlabs.io/coalition/.
“影响实验室—峰会”n.d .于 2020 年 5 月 26 日获得。【https://www.impactlabs.io/summit/.
“影响实验室——伙伴关系。”n.d .于 2020 年 5 月 26 日获得。https://www.impactlabs.io/fellowship/.
"可持续技术发展的问题—影响实验室—中等."n.d .于 2020 年 5 月 26 日获得。https://medium . com/impact-labs/the-question-of-sustainable-technology-growth-aaea 7 B3 B4 f 4。
"见艾伦·梅尔(Enigma,Impact Labs)在普林斯顿的初创公司 Grind . "n.d .于 2020 年 5 月 26 日获得。https://www . startup grind . com/events/details/startup-grind-Princeton-presents-aaron-Mayer-enigma-impact-labs/。
"高科技伦理|布朗校友杂志."n.d .于 2020 年 5 月 26 日获得。https://www . brownalumnimagazine . com/articles/2019-09-09/hi-tech-ethics。
“(340)我们这个时代的超级英雄|亚伦·梅尔| TEDxBrownU——YouTube。”n.d .于 2020 年 5 月 26 日获得。https://www.youtube.com/watch?v=zrjNBWMY8qM.
“冲击实验室”n.d .于 2020 年 5 月 26 日获得。https://www.impactlabs.io/.
社交网络中的 AB 测试挑战
脸书和他的同事如何在 AB 测试中克服互联用户的挑战
AB 测试的概念听起来很简单:将用户随机分配到控制组或治疗组,并检查治疗组的用户与控制组相比,是否表现出想要的行为变化(或任何变化)。但是,如果用户之间相互作用,以至于在控制组和治疗组之间画一条直线变得几乎不可能,会发生什么呢?
脸书、谷歌和 LinkedIn 等公司因其 AB 测试工作而广为人知。但是,考虑到他们产品的高度互联性,他们都面临上述问题,这可能会在实验结果中产生偏差,甚至更糟的是损害他们用户的体验。那么这些公司是如何解决这些问题的呢?
社交网络中 AB 测试的挑战
在进行 AB 测试时,人们通常假设每个人在测试中的反应只取决于自己的任务,而不取决于其他人的任务。这就是所谓的稳定单位治疗值假设(SUTVA) 。
但让我们假设一个大型社交网络平台,如 LinkedIn 或脸书,测试一种改进的算法,使其订阅源与用户更相关,目标是增加内容的参与度。如果用户 A 在治疗组中,并且与控制组中的用户 B 相联系,则用户 A 的行为变化可能会影响用户 B 的行为。用户 A 可能表现出对订阅源上的改进内容的参与度增加,从而开始共享更多的帖子、图片和文章。这将最终对用户 B 产生影响,用户 B 可能在没有接触到新体验的情况下就开始做同样的事情。
治疗的成功以治疗组和对照组之间平均结果的差异来衡量。例如,可以检查转换率的差异。这就是所谓的平均治疗效果 (ATE)。溢出效应,就像在社会网络中发现的那样,会使平均治疗效果产生偏差,因为治疗组中引入的变化带来的好处再也无法准确捕捉。在新闻反馈的新算法的情况下,溢出效应可能不仅会导致治疗组的参与度增加,也会导致对照组的参与度增加。这是因为控制组中的用户也可能被鼓励更多地参与他们的提要。然而,这冲淡了治疗的积极效果,当在社交网络中使用标准 AB 测试方法时,最终会导致错误的结论。
除了偏向统计结果的风险,社交网络或协作应用中的 AB 测试也可能带来一些 UX 挑战。例如,在视频聊天应用程序或高度协作应用程序(如 Google Docs)中测试新功能时。如果正在进行视频通话或正在协作处理同一文档的用户没有相同的功能,这可能会导致混乱并恶化用户体验,从而引发诸如*“您没有看到右下角新的黄色按钮吗?”*。
AB 测试的经典方法可能会由于有偏见的统计结果而误导业务决策,同时严重损害用户体验。
巢式抽样法
集群抽样,又称网络分桶,是处理溢出效应的常用方法。我们的目标是将用户分为治疗组和控制组,这样各组之间的交互就尽可能少。当进行 AB 测试时,用户通常被随机分配到不同的变体,这导致了前面提到的溢出效应。取而代之的是集群抽样,随机化是在用户集群级别上进行的。换句话说,如果用户是控制组的一部分,他们的直接网络连接的重要部分也被分配给控制组。
(社会)网络中的整群抽样(自有图形)。
以最小化它们之间的信息流的方式分割这些组是一个复杂的挑战,其中可以使用各种各样的聚类算法来实现这个目标。一种叫做 e-net 的方法基于以下想法:
- 找到 k 个节点作为聚类中心,它们之间的距离大于特定阈值
- 将剩余节点随机分配到它们最近的中心
在协作应用中,例如谷歌云平台,可以使用更确定的方法来创建这些集群。相互交流的用户数量受到他们一起工作的项目数量的限制。因此,可以创建在相同项目上工作的用户群,从而将群之间的溢出效应降低到接近 0(如果用户加入不同群中的用户所拥有的新项目,溢出效应仍然会发生)。
聚集一个实验小组有其自身的挑战。例如,在网络中的集群大小和集群数量之间存在权衡。一方面,为了实现 AB 检验的高统计功效,优选具有尽可能多的单位。另一方面,用户组中不同集群的数量越多,这些集群就越不孤立。例如,如果只有一个或两个集群,溢出效应将远远小于有 100 个或更多集群的情况。在处理组之间具有相等的集群大小是另一个要求,这有助于减少方差和增加测试的功效。
AB 测试集群
一旦实验组被组织成组,这些组可以被分配给控制或处理单元。然后在集群上进行测试。首先在聚类水平上计算转化率等指标,然后在治疗组水平上再次进行平均。最终,这些结果可用于计算平均治疗效果。
这种方法也可以用来证明网络效应的普遍存在。例如,当运行一个实验时,一个在用户级别随机化的 AB 测试可以与另一个在集群级别随机化的测试并行运行。如果两种设置的平均治疗效果有显著差异,这可以被视为网络效应存在的证据。
进一步的挑战
在一个集群上而不是在一个用户层面上进行随机化,只能解决在社交网络中进行 AB 测试时出现的部分问题。另一个需要考虑的挑战是,在将用户划分为集群时,用户之间连接的强度和方向。与脸书或 LinkedIn 相比,Instagram 和 Twitter 等网络的结构非常不同。在这些网络中扮演重要角色的影响者是一个相对较小的用户群体,他们能够对许多用户产生巨大的影响。与此同时,这些联系大多是单向的:影响者可以对其追随者产生影响,但反之则不然。
想象一个极端的情况,其中一个用户非常有名,网络中的所有其他用户都追随他。该用户可以影响所有这些用户,无论网络如何划分。但是,在不太极端的情况下,溢出效应可能无法通过简单地将用户聚集到关系最密切的群体中来减少。解决这一挑战的可能方法是使用影响者作为初始聚类中心,并通过多数投票将剩余用户分配给这些聚类。
结论
一般来说,AB 测试是一个被广泛使用和深入研究的领域。与此同时,社交网络中的 AB 测试所带来的挑战还远未解决,仍有待深入研究。无论是找到正确的聚类方法还是平均治疗效果的理想估计值,仍然有许多挑战需要克服。但由于 AB 测试是脸书和 Twitter 等大型科技公司所有产品开发活动的核心,人们可以放心,克服这些非常有趣的挑战的新方法和方法论将会发展。
参考
对本文有帮助并提供更详细概述的论文和文章:
更多关于 AB 测试的文章:
像 Optimizely 这样的实验平台是如何忽略 AB 测试中最基本的原则之一的
towardsdatascience.com](/unlocking-peeking-in-ab-tests-7847b9c2f6bb) [## AB 测试:利润和社会责任之间的权衡?
产品开发中最重要的工具之一的副作用几乎没有人想到
medium.com](https://medium.com/swlh/ab-testing-a-trade-off-between-profit-and-social-responsibility-5d6394dc9eea)
A/B 测试:Python 中的分步指南
从实验设计到假设检验
作者图片
在这篇文章中,我们将回顾分析 A/B 实验的过程,从制定假设,测试它,最后解释结果。对于我们的数据,我们将使用来自 Kaggle 的一个数据集,它包含对一个网站页面的两种不同设计(旧页面与新页面)进行 A/B 测试的结果。如果你想了解我使用的代码,请随意在我的 GitHub 页面下载 jupyter 笔记本。
这是我们要做的:
为了更现实一点,这里有一个潜在的场景供我们研究:
让我们想象一下,你在一家中型在线电子商务企业的产品团队工作。UX 的设计师非常努力地设计了新版本的产品页面,希望它能带来更高的转化率。产品经理(PM)告诉您,当前的转换率全年平均约为 13% ,团队会对 2% 的增长感到满意,这意味着如果新设计将转换率提高到 15%,则认为新设计是成功的。
在推出变更之前,团队更愿意在少量用户身上测试它,看看它的表现如何,所以你建议在你的用户群用户的子集上运行 A/B 测试。
1.设计我们的实验
阐明一个假设
首先,我们要确保在项目开始时制定一个假设。这将确保我们对结果的解释既正确又严谨。
假设我们不知道新设计的表现会更好还是更差(还是一样?)作为我们目前的设计,我们将选择一个 双尾检验 :
Hₒ: p = p ₒ
hₐ:p≦pₒ
其中 p 和 p ₒ 分别代表新旧设计的转换率。我们还将置信度设为 95% :
α = 0.05
α 值是我们设定的一个阈值,通过这个阈值我们说“如果观察到一个结果为极值或更大的概率(p-值)低于 α ,那么我们拒绝零假设”。由于我们的 α=0.05 (表示 5%概率),我们的置信度(1 — α )是 95%。
如果您不熟悉以上内容,请不要担心,所有这些实际上意味着,无论我们在测试中观察到新设计的转换率是多少,在我们决定拒绝零假设 Hₒ.之前,我们都希望有 95%的把握认为它在统计上不同于旧设计的转换率
选择变量
对于我们的测试,我们需要两个组:
- 一个小组——他们将被展示旧的设计
- 一个
treatment
(或实验)组——他们将被展示新的设计
这将是我们的自变量。尽管我们知道基准转换率,但我们之所以有两组,是因为我们希望控制可能对我们的结果产生影响的其他变量,如季节性:通过有一个control
组,我们可以直接将他们的结果与treatment
组进行比较,因为两组之间唯一的系统差异是产品页面的设计,因此我们可以将结果中的任何差异归因于设计。
对于我们的因变量(即我们试图测量的东西),我们感兴趣的是捕捉conversion rate
。我们可以用一个二进制变量对每个用户会话进行编码:
0
-用户在本次用户会话中没有购买产品1
-用户在本次用户会话中购买了产品
这样,我们可以很容易地计算出每组的平均值,从而得到每个设计的转化率。
选择样本大小
值得注意的是,由于我们不会测试整个用户群(我们的人口,我们得到的转换率将不可避免地只是真实转换率的估计值。
我们决定在每个组中捕获的人数(或用户会话)将对我们估计的转化率的精确度产生影响:样本量越大,我们的估计就越精确(即,我们的置信区间越小),在两组中发现差异的机会就越高,如果存在差异的话。
另一方面,我们的样本越大,我们的研究就变得越昂贵(和不切实际)。
那么每组应该有多少人呢?
我们需要的样本大小是通过所谓的 功效分析 来估计的,它取决于几个因素:
- 检验的功效 (1 — β) —这表示当差异实际存在时,在我们的检验中发现组间统计差异的概率。按照惯例,这通常设置为 0.8(如果你好奇,这里有更多关于统计能力的信息)
- α值 (α) —我们之前设置的临界值为 0.05
- 效应大小——我们预期转换率之间的差异有多大
由于我们的团队对 2%的差异感到满意,我们可以使用 13%和 15%来计算我们预期的效果大小。
幸运的是, Python 为我们处理了所有这些计算:
# Packages imports
import numpy as np
import pandas as pd
import scipy.stats as stats
import statsmodels.stats.api as sms
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
from math import ceil
%matplotlib inline
# Some plot styling preferences
plt.style.use('seaborn-whitegrid')
font = {'family' : 'Helvetica',
'weight' : 'bold',
'size' : 14}
mpl.rc('font', **font)effect_size = sms.proportion_effectsize(0.13, 0.15) # Calculating effect size based on our expected rates
required_n = sms.NormalIndPower().solve_power(
effect_size,
power=0.8,
alpha=0.05,
ratio=1
) # Calculating sample size needed
required_n = ceil(required_n) # Rounding up to next whole number
print(required_n)
4720
我们需要每组至少 4720 次观察。
在实践中将power
参数设置为 0.8 意味着,如果我们的设计之间的转换率存在实际差异,假设该差异是我们估计的差异(13%对 15%),我们有大约 80%的机会在使用我们计算的样本量进行的测试中将其检测为具有统计显著性。
2.收集和准备数据
很棒的东西!现在我们有了所需的样本量,我们需要收集数据。通常在这一点上,你会和你的团队一起建立实验,可能是在工程团队的帮助下,并确保根据所需的样本大小收集足够的数据。
但是,由于我们将使用我们在网上找到的数据集,为了模拟这种情况,我们将:
- 从 Kaggle 下载数据集
- 将数据读入熊猫数据框
- 根据需要检查和清理数据
- 从每个组的数据帧中随机抽取
n=4720
行*
- 注:正常情况下,我们不需要执行步骤 4,这只是为了练习
因为我已经下载了数据集,我将直接进入第二个问题。
df = pd.read_csv('ab_data.csv')
df.head()
df.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 294478 entries, 0 to 294477
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 user_id 294478 non-null int64
1 timestamp 294478 non-null object
2 group 294478 non-null object
3 landing_page 294478 non-null object
4 converted 294478 non-null int64
dtypes: int64(2), object(3)
memory usage: 11.2+ MB# To make sure all the control group are seeing the old page and viceversa
pd.crosstab(df['group'], df['landing_page'])
数据帧中有 294478 行,每一行代表一个用户会话,还有 5 列:
user_id
-每个会话的用户 IDtimestamp
-会话的时间戳group
-用户在该会话中被分配到哪个组{control
,treatment
}landing_page
-每个用户在该会话中看到哪个设计{old_page
,new_page
}converted
-会话是否以转换结束(二进制,0
=未转换,1
=已转换)
我们实际上将只使用group
和converted
列进行分析。
在我们继续对数据进行采样以获得我们的子集之前,让我们确保没有被采样多次的用户。
session_counts = df['user_id'].value_counts(ascending=False)
multi_users = session_counts[session_counts > 1].count()
print(f'There are {multi_users} users that appear multiple times in the dataset')
There are 3894 users that appear multiple times in the dataset
事实上,有 3894 个用户不止一次出现。由于这个数字非常低,我们将继续从数据帧中删除它们,以避免对相同的用户进行两次采样。
users_to_drop = session_counts[session_counts > 1].index
df = df[~df['user_id'].isin(users_to_drop)]
print(f'The updated dataset now has {df.shape[0]} entries')
The updated dataset now has 286690 entries
抽样
现在我们的数据框架已经很好很干净了,我们可以继续对每个组的n=4720
条目进行采样。我们可以使用 pandas 的DataFrame.sample()
方法来做到这一点,它将为我们执行简单的随机抽样。
注意:我已经设置了random_state=22
,这样如果你想在你自己的笔记本上跟随,结果是可重复的:只要在你的函数中使用random_state=22
,你应该得到和我一样的样本。
control_sample = df[df['group'] == 'control'].sample(n=required_n, random_state=22)
treatment_sample = df[df['group'] == 'treatment'].sample(n=required_n, random_state=22)
ab_test = pd.concat([control_sample, treatment_sample], axis=0)
ab_test.reset_index(drop=True, inplace=True)ab_test
ab_test.info()
`<class ‘pandas.core.frame.DataFrame’>
RangeIndex: 9440 entries, 0 to 9439
Data columns (total 5 columns):Column Non-Null Count Dtype
0 user_id 9440 non-null int64
1 timestamp 9440 non-null object
2 group 9440 non-null object
3 landing_page 9440 non-null object
4 converted 9440 non-null int64
dtypes: int64(2), object(3)
memory usage: 368.9+ KB`
ab_test['group'].value_counts()
control 4720 treatment 4720 Name: group, dtype: int64
很好,看起来一切都按计划进行,我们现在可以分析我们的结果了。
3.可视化结果
我们可以做的第一件事是计算一些基本的统计数据来了解我们的样本是什么样的。
conversion_rates = ab_test.groupby('group')['converted']
std_p = lambda x: np.std(x, ddof=0) # Std. deviation of the proportion
se_p = lambda x: stats.sem(x, ddof=0) # Std. error of the proportion (std / sqrt(n))
conversion_rates = conversion_rates.agg([np.mean, std_p, se_p])
conversion_rates.columns = ['conversion_rate', 'std_deviation', 'std_error']
conversion_rates.style.format('{:.3f}')
从上面的数据来看,我们的两个设计看起来确实很相似**,我们的新设计表现略好,大约。 12.3%对 12.6%的转化率。**
绘制数据将使这些结果更容易掌握:
plt.figure(figsize=(8,6))
sns.barplot(x=ab_test['group'], y=ab_test['converted'], ci=False)
plt.ylim(0, 0.17)
plt.title('Conversion rate by group', pad=20)
plt.xlabel('Group', labelpad=15)
plt.ylabel('Converted (proportion)', labelpad=15);
我们组的转化率确实非常接近。还要注意的是,根据我们对平均转化率的了解,第control
组的转化率低于我们的预期。转化率(12.3%对 13%)。这表明,从总体中取样时,结果会有一些变化。
所以……这个treatment
组的价值更高。这种差异有统计学意义 吗?
4.检验假设
我们分析的最后一步是检验我们的假设。由于我们有一个非常大的样本,我们可以使用正态近似值来计算我们的p-值(即 z 检验)。
同样,Python 使得所有的计算变得非常简单。我们可以使用statsmodels.stats.proportion
模块来获得p-值和置信区间:
from statsmodels.stats.proportion import proportions_ztest, proportion_confintcontrol_results = ab_test[ab_test['group'] == 'control']['converted']
treatment_results = ab_test[ab_test['group'] == 'treatment']['converted']n_con = control_results.count()
n_treat = treatment_results.count()
successes = [control_results.sum(), treatment_results.sum()]
nobs = [n_con, n_treat]
z_stat, pval = proportions_ztest(successes, nobs=nobs)
(lower_con, lower_treat), (upper_con, upper_treat) = proportion_confint(successes, nobs=nobs, alpha=0.05)
print(f'z statistic: {z_stat:.2f}')
print(f'p-value: {pval:.3f}')
print(f'ci 95% for control group: [{lower_con:.3f}, {upper_con:.3f}]')
print(f'ci 95% for treatment group: [{lower_treat:.3f}, {upper_treat:.3f}]')
z statistic: -0.34 p-value: 0.732 ci 95% for control group: [0.114, 0.133] ci 95% for treatment group: [0.116, 0.135]
5.得出结论
由于我们的p-值=0.732 远远高于我们的α=0.05** 阈值,我们不能拒绝零假设 Hₒ,这意味着**我们的新设计与旧设计相比并没有显著的不同(更不用说更好了)😦****
此外,如果我们观察treatment
组的置信区间([0.116,0.135],或 11.6-13.5%),我们注意到:
- 它包括我们 13%转化率的基线值
- 它不包括我们的目标值 15%(我们的目标是提高 2%)
这意味着新设计的真实转换率更有可能与我们的基线相似,而不是我们希望的 15%的目标。这进一步证明了我们的新设计不可能比我们的旧设计有所改进,不幸的是我们又回到了起点!
你喜欢我的故事吗?请让我知道!
请随意在我的 GitHub 页面下载 jupyter 笔记本。