TowardsDataScience-博客中文翻译-2016-2018-二十三-
TowardsDataScience 博客中文翻译 2016~2018(二十三)
原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
自省引擎:斯诺登的移动安全解决方案
原文:https://towardsdatascience.com/introspection-engine-snowdens-mobile-security-solution-e680e8ab4092?source=collection_archive---------1-----------------------
爱德华·斯诺登介绍了一种新的移动安全解决方案,并提醒说数据保护可以拯救生命
爱德华·斯诺登可能是一个有争议的人物,但不可否认的是,在 it、网络和移动安全方面,他是一名专家。在成为 NSA 告密者后,他现在住在莫斯科郊区,通过设计网络安全解决方案让自己忙碌起来。在麻省理工学院媒体实验室的活动中,斯诺登与同为黑客的安德鲁·黄(Andrew 'Bunnie' Huang)合作,展示了一个可以阻止未经授权的数据访问的智能手机保护套概念。在马萨诸塞州剑桥举行的活动中,斯诺登从俄罗斯通过视频链接讨论了他的产品。
被禁止的研究着眼于伦理方面,与技术、网络和移动安全相关的法律法规,以及这些是否会改善或阻碍社会的健康和可持续发展。由于人工智能、机器学习和数据经常引发社会、道德和法律问题,因此重要的是要研究它们,看看是否有一种解决方案既能造福世界,又能带来创新。
斯诺登和黄表达了他们对移动设备越来越多的未经授权的访问和攻击的担忧,并讨论了他们的产品和研究,将其命名为“硬件自省引擎”。智能手机外壳将能够在无线电信号传输时提醒用户。斯诺登说,即使智能手机用户将他们的设备设置为飞行模式,关闭手机的蜂窝和 WiFi 连接,GPS 仍然会保持活动状态。这款新的外壳状产品可以连接到智能手机,监控发送到内部天线的电信号,警告和阻止未经授权的访问尝试,提供额外的电池电源,并覆盖后置摄像头。然而,该设备仍处于项目阶段,近期还没有大规模生产的明确计划。
这个概念可能听起来像詹姆斯·邦德电影中的情节,但对小工具安全性的担忧正在上升。在马克·扎克伯格最近的一篇帖子中,精明的用户发现这位企业家的 Macbook 前置摄像头和麦克风被胶带覆盖,这在社交媒体上引发了一系列问题。屡获殊荣的网络安全专家格雷厄姆·克莱利随后评论道:“我认为扎克伯格采取这些预防措施是明智的。”
然而,不仅仅是高知名度的人的计算机和移动设备受到威胁。当黑客扫描开放的网络和移动摄像头时,可能出于各种动机,从偷窥到勒索。根据非营利组织数字公民联盟的报告,未经授权的访问问题正在增长,年轻女性被视为主要目标之一。
斯诺登和黄提出智能手机保护套想法的主要原因之一是记者及其材料的脆弱性。斯诺登说:“不幸的是,记者会被他们自己的工具出卖。”早在 2012 年,美国记者玛丽·科尔文在报道叙利亚内战时被杀,一项诉讼称她是在卫星电话通信被事先追踪到她的位置的情况下被暗杀的。
《新闻自由报》称,如果原型被证明是成功的,该组织可能会寻求必要的资金来开发和维护它。这将使记者在生命受到威胁的情况下更加安全。在麻省理工学院的演讲中,斯诺登补充道:“一名优秀的记者在正确的时间出现在正确的地点,可以改变历史。一个优秀的记者可以在选举中左右局势。一个位置合适的记者可以影响一场战争的结果。
考虑到斯诺登项目的敏感性和自愿资助的事实,大规模生产可能是不可能的。移动和网络安全问题仍然令人担忧,但像麻省理工学院媒体实验室禁止研究这样的事件,可以进一步鼓励观众更加谨慎地使用他们的移动设备,并帮助他们了解数据的脆弱性。
主成分背后的直觉
原文:https://towardsdatascience.com/intuition-behind-principal-components-849d3ef9d616?source=collection_archive---------9-----------------------
PCA 一直困扰着我。这是那些我已经记了很多遍,但在我的潜意识中却无法正确理解的概念之一。这是在我完全理解线性代数的细微差别之前。
如果你理解矩阵的特征值、特征向量和协方差,那么你最终会在这篇博客中找到 PCA 的平静。如果这些概念有点生疏,不要担心,你可以在继续之前快速修改它们 这里 和 这里 。
假设我们为 5 个不同的个体测量了 9 个不同的变量/属性,并将数据放入一个 9 乘 5 的矩阵中。
Matrix A : 9x5dimensional
同样假设,我们也对这个数据应用了我们可爱的标准化,因此每一行的平均值为零。所以在上面的矩阵中,均值(行 1)=均值(行 2)..平均值(第 9 行)= 0
让我们称这个矩阵为 A,我在行中有变量/属性,在列中有观察值。
现在在我跳到主成分及其解释之前,首先让我们计算 a 的协方差矩阵。
A 的协方差矩阵将是 S = AAt/(n-1 ),其中 At =矩阵 A 的转置,n 是观测值的数量= 5
现在,为了确保我们对矩阵 S 的维数是正确的,AAt 的维数应该是(9x5)乘以(5x9) = (9x9)
因此,基本上,由于我们已经将变量(m=9)放在行中,所以协方差矩阵的维数将是 9x9。
这是我已经计算过的矩阵 S——
Matrix A : 9x5
Matrix B = At (A transpose) : 5x9
Covariance Matrix S : AAt/(n-1) : 9x9
现在,是时候让事情真正热起来,并计算上述矩阵的一些性质
S 的特征值个数:
首先,看起来 9×9 维矩阵 S 的特征值总数等于 9,然而这不是真的。矩阵 AAt 和 AtA 的特征值个数必须相同(证明 此处 )
因此,AtA 矩阵将具有 5x5 的维度(检查!)并因此将具有最多 5 个非零特征值,矩阵 AAt 也是如此。
然而,矩阵 A 的所有列都不是独立的(记得我们将所有行居中,所以 A 的所有列的总和将为零),因此,矩阵 AAt 的非零特征值将仅为 4。
即 S 的特征值的数量:4
我们把 A 的 4 个奇异值(奇异值分解)称为:
因此,S 的特征值= A 的信号值的平方=
Eigenvalues of S
上述特征值是直接从矩阵 S 的值通过编程计算出来的。
注意,S 的特征值之和也等于 S ~1756.7 的对角元素之和
Sum of Eigenvalues of S = 1756.7
Sum of diagonals elements of S = 1752.91
现在,让我们也计算矩阵 a 的每一行(属性)的方差。(因为我们对每一行的均值是零,方差只是每个值的平方和除以 4)
Last Column is variance of each row of matrix A
一旦个体方差在这里,我们可以计算:
矩阵 A 的属性总方差=所有属性方差之和= 1753.39
请注意,协方差矩阵 S 的特征值之和几乎与原始数据矩阵 a 的总方差之和相同。这是一个重要的性质。
因此,我们的 4 个特征值涵盖了数据中的所有方差,注意第一个特征值是最大的,然后它继续下降。
矩阵 S 的每个特征值与其特征向量相关联。在我们的例子中,我们有 4 个特征向量
其中每个特征向量相互垂直,并根据它们各自的特征值计算
最大特征值具有特征向量(u1 ),我们称之为第一主分量,因为该主分量能够解释其方向上的最大方差(1753.39 中的 1323.9)
第二大特征值具有特征向量(u2 ),该特征向量也称为第二主分量,并解释了(在其垂直于第一主分量方向上的总共 1753.39 个方差中的 397.2 个方差)
类似地,第三和第四特征向量解释了总方差相对较小的部分,但这是我们停止的地方。如果我们对前两个特征值求和,我们将得到 98%的总方差,仅由两个特征向量解释,这基本上意味着 u1 和 u2 包含关于矩阵 A 中数据的最大信息,因此我们只需要两个向量,而不是 A 的所有列。这也是我们所说的 PCA 中的降维。
上面的例子是有意将 5 维减少到 2 维,然而,很难想象这样的例子
现在让我们举一个更简单的例子,当我们对这个方法有些熟悉的时候,让它永远在我们的脑海中具体化
我们有两个属性年龄和身高为 6 人,如下所示矩阵格式[2x6],年龄和身高行以零为中心。
Matrix A: 2x6 with Mean(row1) = Mean(row2) = 0
Plotted points in 2-D
二维数据也可以如上所示绘制,X 为年龄,y 为身高
有了矩阵 A 中的数据,我们来计算它的协方差矩阵 S = AAt/(n-1)
回想一下,我们的协方差矩阵是 2x2
现在,我们计算 S 的特征值,可以找到 57 和 3(回想一下,S 的特征值之和是 diagnol = 60 上的元素之和,这意味着到目前为止我们是好的。
现在,我们找到矩阵 A 属性的总方差
所以总方差= 20 + 40 = 60
回想一下矩阵 A 中方差=协方差矩阵 S 的特征值之和= 60
所以,第一个特征值 57 解释了我们数据中 60 个变量中的 57 个。如果我们找到它的特征向量,它就是向量
u1 = [0.6 0.8]
这在理论上可以解释最大方差。
当我们在二维空间中绘制这个向量时,我们会得到红线,它基本上只是二维空间中的点在一维空间中的表示。这里,特征向量 u1 是第一主分量,包含关于矩阵 a 的最大信息。
我希望现在有意义的是如何将一个矩阵简化为一组正交的特征向量,这些特征向量通过它们的特征值来解释总方差的最大分数。并且如果我们有总共 q 个特征向量(或主成分),那么我们只选择最上面的 r 个特征向量(r
干杯!
卡尔曼滤波器对自动驾驶汽车应用的直觉
原文:https://towardsdatascience.com/intuition-of-kalman-filter-for-self-driving-car-applications-749b356e19db?source=collection_archive---------0-----------------------
这是我关于卡尔曼滤波器的讲稿。这篇笔记试图欣赏和捕捉 Sebastian Trun 在他关于卡尔曼滤波器的讲座中分享的丰富直觉。我还参考了其他一些资料,如为什么你应该使用卡尔曼滤波器教程——口袋妖怪示例
增强直觉是塞巴斯蒂安讲课的特点。这是他天赋的一部分。因此,我个人非常喜欢上他的课。所以我想做笔记来捕捉它们,并确保我完全理解它们。我也希望笔记能使对话的流畅更具体,从而为进一步欣赏直觉提供另一种选择。这也是我理解直觉并确认我是否真正理解直觉的方法。
卡尔曼滤波器是一种通过组合具有不确定性的多个测量或估计源来估计信号的方案。
在自动驾驶汽车的情况下,信号是物体的位置。
首先,主要测量是来自激光雷达或雷达的物体的位置。第二个估计是基于对物体速度的理解对物体运动的预测。
这两个测量/估计源被交替使用,以组合和提高物体位置估计的精度。组合的过程如下:
- 胡乱猜测物体的位置(初始化);
- 使用位置的测量来提高精度(通过测量更新);
- 使用运动预测并基于步骤 2 中对象位置的更新估计来进一步预测/改进对象位置的估计(通过独立运动估计预测);
- 使用步骤 3 的结果作为对象位置的新估计,从步骤 2 开始重复迭代。
使用步骤 2,可以提高物体位置估计的准确性/确定性,因为测量是相关的观察事件。
使用目标运动预测的步骤 3,独立于目标位置的测量,添加目标的观察值。这将进一步降低步骤 2 中物体位置测量的准确性或可用性的依赖性。
在第 2 步和第 3 步中,测量的确定性和运动预测被建模为高斯分布。高斯分布的平均值是估计值,而方差是测量/预测的确定性的表示。高斯分布很好地代表了一种直觉,即估计值在均值附近具有对称性和高可能性。接近均值的程度就是确定性的程度。
对于步骤 2,基于相关测量的更新估计将是先前平均值的加权平均值,以及新测量的平均值。特别值得注意的是,这是一个交叉加权平均值,以前估计的方差是新测量的权重,而当前测量的方差是以前估计的权重。如果新的测量具有更小的方差,即更确定,这将有利于新的测量。
对于步骤 3,由于它是一个独立的估计,新的均值和方差将是先前估计值(均值、方差)和预测值的总和。虽然这可能不会提高位置的总体估计的确定性,但是它可能有助于添加来自物体位置的独立源的更多信息。当测量不可用或不总是可信时,这将特别有帮助。实际上,这可能有助于提高物体位置估计的准确性。
感谢您的阅读,请纠正和提高我的理解。
对 L1 和 L2 正则化的直觉
原文:https://towardsdatascience.com/intuitions-on-l1-and-l2-regularisation-235f2db4c261?source=collection_archive---------0-----------------------
Photo by rawpixel on Unsplash
解释 L1 和 L2 如何使用梯度下降法
(右跳 此处 跳过引见。)
2020 年 3 月 27 日:在 2-norm 和 p-norm 中的术语中添加了 absolute。感谢 里卡多 N 桑托斯 指出这一点。
O 过度拟合是一种机器学习或统计模型针对特定数据集定制,无法推广到其他数据集时发生的现象。这通常发生在复杂的模型中,比如深度神经网络。
规则化是引入额外信息以防止过度拟合的过程。本文的重点是 L1 和 L2 的正规化。
有很多解释,但老实说,它们有点太抽象了,我可能会忘记它们,并最终访问这些页面,结果又忘记了。在这篇文章中,我将与你分享一些直觉,为什么 L1 和 L2 使用梯度下降进行解释。梯度下降是一种简单的方法,通过使用梯度值的迭代更新来找到“正确的”系数。(这篇文章展示了如何在简单的线性回归中使用梯度下降。)
内容
- 什么是 L1 和 L2?
- 模型
- 损失函数
- 梯度下降
- 如何防止过拟合?
我们走吧!
0)什么是 L1 和 L2?
L1 和 L2 的正规化分别归功于 L1 和 L2 规范的一个向量、T42、w。这里有一个关于规范的初级读本:
1-norm (also known as L1 norm)
2-norm (also known as L2 norm or Euclidean norm)
p-norm
实现 L1 范数正则化的线性回归模型称为套索回归,实现(平方)L2 范数正则化的线性回归模型称为岭回归。要实现这两个,请注意线性回归模型保持不变:
但是损失函数的计算包括这些正则化项:
Loss function with no regularisation
Loss function with L1 regularisation
Loss function with L2 regularisation
注:严格来说,最后一个方程(岭回归)是一个权重为 平方 L2 范数的损失函数(注意没有平方根)。(感谢Max Pechyonkin强调这一点!)
除了必须最小化真实 y 和预测 ŷ 之间的误差之外,正则化项是优化算法在最小化损失函数时必须“遵守”的“约束”。
1)型号
让我们定义一个模型来看看 L1 和 L2 是如何工作的。为简单起见,我们定义一个简单的线性回归模型 ŷ 与一个独立变量。
在这里,我使用了深度学习约定 w (“权重”)和 b (“偏差”)。
在实践中,简单的线性回归模型不容易过度拟合。正如引言中所提到的,深度学习模型由于其模型的复杂性,更容易受到此类问题的影响。
因此,请注意,本文中使用的表达式很容易扩展到更复杂的模型,而不仅限于线性回归。
2)损失函数
为了证明 L1 和 L2 正则化的效果,让我们使用 3 种不同的损失函数/目标来拟合我们的线性回归模型:
- L
- 腰神经 2
- L2
我们的目标是尽量减少这些不同的损失。
2.1)无正则化的损失函数
我们将损失函数 l 定义为平方误差,其中误差是 y (真实值)和 ŷ (预测值)之差。
让我们假设使用这个损失函数,我们的模型会过度拟合。
2.2)L1 正则化损失函数
基于上述损失函数,添加一个 L1 正则化项,如下所示:
其中调整参数λ0 是手动调整的。让我们称这个损失函数为 L1。注意| w| 处处可微,除了当 w =0 时,如下图。我们以后会需要这个。
2.3)L2 正则化损失函数
类似地,将 L2 正则化项添加到 L 看起来像这样:
这里又,λ0。
3)梯度下降
现在,让我们基于上述定义的 3 个损失函数,使用梯度下降优化求解线性回归模型。回想一下,在梯度下降中更新参数 w 如下:
让我们用 L 、 L1 和 L2 w.r.t. w. 的梯度来代替上式中的最后一项
l:
L1:
L2:
4)如何防止过度拟合?
从这里开始,让我们对上面的等式进行以下替换(为了更好的可读性):
- η = 1,
- H = 2x ( wx+b-y )
这给了我们
l:
L1:
L2:
4.1)有无正规化
观察有正则化参数 λ 和没有正则化参数的重量更新之间的差异。以下是一些直觉。
直觉 A:
让我们用等式 0 来说,计算 w-H 给出了导致过拟合的 w 值。然后,直观地,等式{1.1、1.2 和 2}将减少过拟合的机会,因为引入 λ 使我们将从上一句中导致过拟合问题的 w 处移开。
直觉 B:
假设一个过度拟合的模型意味着我们有一个 w 值,它对于我们的模型来说是完美的。“完美”意味着如果我们将数据( x )代入模型,我们的预测 ŷ 将非常非常接近真实的 y 。当然,这很好,但我们不想要完美。为什么?因为这意味着我们的模型只适用于我们训练的数据集。这意味着我们的模型将产生与其他数据集的真实值相差甚远的预测。因此,我们满足于不太完美的,希望我们的模型也能得到与其他数据接近的预测。为此,我们用惩罚项 λ“玷污”等式 0 中的这个完美的 w 。这给了我们等式{1.1,1.2 和 2}。
直觉 C:
注意, H (此处定义为)是依赖于型号( w 和 b )和数据( x 和 y )。仅基于模型和等式 0 中的数据更新权重会导致过度拟合,从而导致泛化能力差。另一方面,在等式{1.1、1.2 和 2}中, w 的最终值不仅受模型和数据的影响,而且还受独立于模型和数据的的预定义参数 λ 的影响。因此,如果我们设置一个合适的值 λ ,我们可以防止过拟合,尽管太大的值会导致模型严重欠拟合。******
直觉 D:
Edden Gerber (谢谢!)提供了一个关于我们的解决方案正在转向的方向的直觉。在评论里看看:https://medium . com/@ edden . gerber/thanks-for-the-article-1003 ad 7478 B2
4.2) L1 对 L2
我们现在将注意力集中到 L1 和 L2,并通过重新排列它们的 λ 和 H 项来重写方程{1.1、1.2 和 2},如下所示:
L1:
L2:
比较上面每个等式的第二项。除了 H 之外, w 的变化取决于 λ 项或 -2 λ w 项,这突出了以下的影响:
- 电流的符号 w (L1,L2)
- 电流大小 w (L2)
- 正则化参数加倍(L2)
使用 L1 的权重更新受第一点的影响,而来自 L2 的权重更新受所有三个点的影响。虽然我只是基于迭代方程更新进行了比较,但请注意,这并不意味着一个比另一个“更好”。
现在,让我们看看下面如何通过当前的 w. 符号获得来自 L1 的正则化效果
4.3) L1 效应向 0 推进(稀疏度)
看看方程 3.1 中的 L1。如果 w 为正,正则化参数λ0 将通过从 w 中减去 λ 来推动 w 为负。相反地,在等式 3.2 中,如果 w 为负,那么 λ 将被加到 w 上,使其变得更小。因此,这具有将 w 推向 0 的效果。
这在一元线性回归模型中当然是无意义的,但将证明它在多元回归模型中“去除”无用变量的能力。你也可以把 L1 想成是减少了模型中特性数量的 T52。这里有一个 L1 试图在多元线性回归模型中“推动”一些变量的任意例子:
那么,在 L1 正则化中,将 w 推向 0 如何帮助过度拟合呢?如上所述,当 w 变为零时,我们通过降低变量重要性来减少特征的数量。在上式中,我们看到 x_2 、 x_4 和 x_5 几乎是“无用”的,因为它们的系数很小,因此我们可以将它们从等式中移除。这反过来降低了模型的复杂性,使得我们的模型更加简单。更简单的模型可以减少过度拟合的机会。
注
虽然 L1 有将权重推向 0 的影响力,而 L2 没有,但这并不意味着由于 L2,权重不能接近 0。
如果你发现文章的任何部分令人困惑,请随意突出显示并留下回复。此外,如果有任何反馈或建议如何改进这篇文章,请在下面留下评论!
参考
常模(数学)(wikipedia.org)
拉索(统计)(wikipedia.org)
套索和山脊正规化【medium.com
特别感谢【任杰】 、丹尼尔 德里克 对本文的观点、建议和修正。也感谢C Gam指出导数中的错误。
关注我上Twitter@ remykarem 或者LinkedIn。你也可以通过 raimi.bkarim@gmail.com 联系我。欢迎访问我的网站remykarem . github . io。**
以梯度推进为研究案例的直观集成学习指南
原文:https://towardsdatascience.com/intuitive-ensemble-learning-guide-with-gradient-boosting-as-a-study-case-9a3bc1ba1e09?source=collection_archive---------8-----------------------
使用单一的机器学习模型可能不总是适合数据。优化其参数也可能于事无补。一种解决方案是将多个模型结合在一起以适应数据。本教程以梯度推进为研究案例,讨论集成学习的重要性。
简介
机器学习(ML)管道中的一个关键步骤是选择适合数据的最佳算法。基于来自数据的一些统计和可视化,ML 工程师将选择最佳算法。让我们将其应用于一个回归示例,其数据如图 1 所示。
Figure 1. Regression input-output simple data.
通过根据图 2 可视化数据,似乎线性回归模型将是合适的。
Figure 2. Data visualization.
一个只有一个输入和一个输出的回归模型将根据图 3 中的等式进行公式化。
Figure 3. Linear regression model
其中 a 和 b 是方程的参数。
因为我们不知道适合数据的最佳参数,所以我们可以从初始值开始。我们可以将 a 设置为 1.0,b 设置为 0.0,并如图 4 所示可视化模型。
Figure 4. Initial regression model.
该模型似乎不符合基于参数初始值的数据。
预计从第一次试验开始,一切可能都不成功。问题是如何在这种情况下提高结果?换句话说,如何最大化分类精度或者最小化回归误差?做那件事有不同的方法。
一个简单的方法是尝试改变先前选择的参数。经过多次试验后,模型将知道最佳参数是 a=2 和 b=1。在这种情况下,模型将符合数据,如图 5 所示。非常好。
Figure 5. Linear regression model
但是在某些情况下,改变模型参数不会使模型符合数据。会有一些错误的预测。假设数据有一个新点(x=2,y=2)。根据图 6,不可能找到使模型完全适合每个数据点的参数。
Figure 6. Impossible to fit the data by changing model parameters.
有人可能会说,拟合 4 个点,缺少一个点是可以接受的。但是,如果有更多的点不符合直线,如图 7 所示,该怎么办呢?因此,模型会做出比正确预测更多的错误预测。没有一条线可以容纳全部数据。该模型对线上各点的预测能力较强,但对其他点的预测能力较弱。
Figure 7. More false predictions.
合奏学习
因为单个回归模型无法拟合全部数据,所以另一种解决方案是使用多个回归模型。每个回归模型都能够很好地拟合一部分数据。所有模型的组合将减少整个数据的总误差,并产生一个通常很强的模型。在一个问题中使用多个模型称为集成学习。使用多个模型的重要性如图 8 所示。图 8(a)显示,预测样本结果时误差很大。根据图 8(b ),当存在多个模型(例如,三个模型)时,它们的结果的平均值将能够做出比以前更准确的预测。
Figure 8. Single vs. multiple models
当应用于图 7 中的前一个问题时,拟合数据的 4 个回归模型的集合如图 9 所示。
Figure 9. Ensemble of 4 regression models
这就留下了另一个问题。如果有多个模型来拟合数据,如何得到单个预测?有两种方法可以组合多个回归模型来返回一个结果。他们是装袋和助推(这是本教程的重点)。
在 bagging 中,每个模型将返回其结果,并且通过汇总所有这些结果将返回最终结果。一种方法是对所有结果进行平均。装袋是并行的,因为所有模型同时工作。
相比之下,增压被认为是连续的,因为一个模型的结果是下一个模型的输入。boosting 的思想是使用弱学习器来拟合数据。因为它是弱的,它将不能正确地拟合数据。这样一个学习者的弱点会被另一个弱学习者所弥补。如果一些弱点仍然存在,那么将使用另一个弱学习者来修复它们。这个链条不断延伸,直到最终从多个弱学习者中产生一个强学习者。
接下来是解释梯度增强是如何工作的。
梯度增强(GB)
下面是基于一个简单示例的梯度增强工作原理:
假设要建立一个回归模型,数据只有一个输出,其中第一个样本有一个输出 15。如图 10 所示。目标是建立一个回归模型,正确预测这样一个样本的输出。
Figure 10
第一个弱模型预测第一个样本的输出是 9,而不是图 11 所示的 15。
Figure 11. Prediction of 9/15 with residual equal to 6.
为了测量预测中的损失量,需要计算其残差。残差是期望输出和预测输出之间的差值。它是根据以下公式计算的:
期望—预测 1 =剩余 1
其中预测 1 和残差 1 分别是第一弱模型的预测输出和残差。
通过用期望输出和预测输出的值代替,残差将是 6:
15–9 = 6
对于预测输出和期望输出之间的残差 1 =6,我们可以创建第二个弱模型,其目标是预测与第一个模型的残差相等的输出。因此,第二种模式将弥补第一种模式的不足。根据下式,两个模型的输出之和等于所需输出:
期望=预测 1 +预测 2(剩余 1)
如果第二弱模型能够正确预测残差 1 ,那么期望输出将等于所有弱模型的预测,如下所示:
期望=预测 1 +预测 2(剩余 1) = 9 + 6 = 15
但是如果第二弱模型未能正确预测残差 1 的值,并且例如仅返回 4,那么第二弱学习器也将具有非零残差,计算如下:
剩余 2 =预测 1 —预测 2 = 6–3 = 3
这如图 12 所示。
Figure 12. Prediction of 3/6 with residual equal to 3.
为了修复第二个弱模型的弱点,将创建第三个弱模型。它的目标是预测第二个弱模型的残差。因此它的目标是 3。因此,我们样本的期望输出将等于所有弱模型的预测,如下所示:
期望=预测 1 +预测 2(剩余 1) +预测 3(剩余 2)
如果第三弱模型预测是 2,即它不能预测第二弱模型的残差,那么对于这样的第三模型将有一个残差等于如下:
剩余 3 =预测 2 —预测 3 = 3–2 = 1
这如图 13 所示。
Figure 13. Prediction of 2/3 with residual equal to 1.
结果,将创建第四弱模型来预测等于 1 的第三弱模型的残差。期望输出将等于所有弱模型的预测,如下所示:
期望=预测 1 +预测 2(剩余 1) +预测 3(剩余 2) +预测 4(剩余 3)
如果第四个弱模型正确地预测了它的目标(即残差 3),那么使用总共四个弱模型已经达到了期望的输出 15,如图 14 所示。
Figure 14. Prediction of 1/1 with residual equal to 0.
这是梯度推进算法的核心思想。使用前一个模型的残差作为下一个模型的目标。
国标概述
总的来说,梯度推进从一个弱模型开始进行预测。这种模型的目标是问题的期望输出。训练好模型后,计算其残差。如果残差不等于零,则创建另一个弱模型来修复前一个模型的弱点。但是这种新模型的目标不是期望的输出,而是先前模型的残差。也就是说,如果给定样本的期望输出是 T,则第一模型的目标是 T。在对其进行训练之后,对于这样的样本,可能存在 R 的残差。要创建的新模型将把它的目标设置为 R,而不是 t。这是因为新模型填补了以前模型的空白。
梯度推进类似于由多个虚弱的人将一个重金属抬上几级楼梯。没有一个虚弱的人能把这块金属抬上所有的楼梯。每个人只能把它抬起一步。第一个弱的人会把金属抬一步,之后就累了。另一个虚弱的人将把金属再抬一步,以此类推,直到把金属抬上所有的楼梯。
原文可在 LinkedIn 本页面查看:https://www . LinkedIn . com/pulse/intuitive-ensemble-learning-guide-gradient-boosting-study-Ahmed-gad
联系作者:
领英:【https://linkedin.com/in/ahmedfgad
电子邮件:ahmed.f.gad@gmail.com
联结主义时间分类的直观解释
原文:https://towardsdatascience.com/intuitively-understanding-connectionist-temporal-classification-3797e43a86c?source=collection_archive---------0-----------------------
使用连接主义时间分类(CTC)丢失和解码操作的文本识别
如果你想让计算机识别文本,神经网络(NN)是一个很好的选择,因为它们目前优于所有其他方法。这种用例的神经网络通常由提取特征序列的卷积层(CNN) 和通过该序列传播信息的递归层(RNN) 组成。它输出每个序列元素的字符分数,简单地用一个矩阵表示。现在,我们想对这个矩阵做两件事:
- 训练:计算损失值来训练神经网络
- 推断:解码矩阵以获得输入图像中包含的文本
这两项任务都由 CTC 操作完成。图 1 示出了手写识别系统的概况。
让我们仔细看看 CTC 操作并讨论它是如何工作的,而不隐藏复杂公式背后基于的巧妙想法。最后,如果您感兴趣的话,我将向您介绍可以找到 Python 代码和(不太复杂的)公式的参考资料。
Fig. 1: Overview of a NN for handwriting recognition.
为什么我们要使用 CTC
当然,我们可以创建具有文本行图像的数据集,然后为图像的每个水平位置指定相应的字符,如图 2 所示。然后,我们可以训练一个神经网络来输出每个水平位置的字符分数。然而,这种天真的解决方案有两个问题:
- 在字符级别上注释数据集是非常耗时的(也是令人厌烦的)。
- 我们只得到字符分数,因此需要一些进一步的处理来从中获得最终的文本。单个字符可以跨越多个水平位置,例如,我们可以得到“ttooo ”,因为“o”是一个宽字符,如图 2 所示。我们必须删除所有重复的“t”和“o”。但是如果识别的文本是“too”呢?那么删除所有重复的“o”会得到错误的结果。这个怎么处理?
Fig. 2: Annotation for each horizontal position of the image.
CTC 为我们解决了这两个问题:
- 我们只需要告诉 CTC 损失函数图像中出现的文本。因此,我们忽略图像中字符的位置和宽度。
- 不需要对识别的文本进行进一步处理。
反恐委员会如何工作
正如已经讨论过的,我们不想在每个水平位置注释图像(从现在开始我们称之为时间步长)。NN 培训将由 CTC 损失职能部门指导。我们只将神经网络的输出矩阵和相应的地面实况(GT)文本馈送给 CTC 损失函数。但是它如何知道每个字符出现在哪里呢?它不知道。相反,它会尝试图像中 GT 文本的所有可能对齐方式,并计算所有得分的总和。这样,如果比对分数的总和具有高值,则 GT 文本的分数高。
对文本编码
还有如何对重复字符进行编码的问题(还记得我们说过的“too”这个词吗?).它是通过引入伪字符(称为空白,但不要与“真正的”空白(即空白字符)混淆)来解决的。在下文中,这个特殊字符将被表示为“-”。我们使用一个聪明的编码模式来解决重复字符问题:在对文本进行编码时,我们可以在任何位置插入任意多个空格,在解码时这些空格将被删除。但是,我们必须在重复的字符之间插入一个空格,就像在“he ll o”中一样。此外,我们可以随心所欲地重复每个字符。
让我们看一些例子:
- " to" → " - ttttttooo ",或"-t-o-",或" to "
- "太"→ " - ttttto-o ",或者"-t-o-o-",或者" to-o ",但是不是"太"
正如您所看到的,这个模式还允许我们轻松地创建相同文本的不同对齐方式,例如“t-o”和“too”以及“-to”都表示相同的文本(“to”),但是对图像有不同的对齐方式。训练神经网络以输出编码文本(在神经网络输出矩阵中编码)。
损失计算
我们需要计算训练样本(成对的图像和 GT 文本)的损失值来训练神经网络。你已经知道,神经网络输出一个矩阵,其中包含每个字符在每个时间步的分数。图 3 示出了一个极简矩阵:有两个时间步长(t0,t1)和三个字符(“a”、“b”和空白“-”)。对于每个时间步长,字符得分总计为 1。
Fig. 3: Output matrix of NN. The character-probability is color-coded and is also printed next to each matrix entry. Thin lines are paths representing the text “a”, while the thick dashed line is the only path representing the text “”.
此外,您已经知道,损失是通过对 GT 文本的所有可能对齐的所有分数求和来计算的,这样,文本出现在图像中的什么位置并不重要。
一次比对(或文献中通常称之为路径)的分数通过将相应的字符分数相乘来计算。在上面显示的示例中,路径“aa”的得分是 0.4±0.4 = 0.16,而“a-”的得分是 0.4±0.6 = 0.24,而“-a”的得分是 0.6±0.4 = 0.24。为了得到给定 GT 文本的分数,我们对与该文本对应的所有路径的分数求和。让我们假设例子中的 GT 文本是“a”:我们必须计算长度为 2 的所有可能路径(因为矩阵有 2 个时间步长),它们是:“aa”,“a-”和“-a”。我们已经计算了这些路径的分数,所以我们只需对它们求和,得到 0.4 0.4+0.4 0.6+0.6 0.4=0.64。如果假设 GT 文本为“”,我们看到对应的路径只有一条,即“-”,得出的综合得分为 0.6 0.6=0.36。
我们现在能够计算训练样本的 GT 文本的概率,给定由 NN 产生的输出矩阵。目标是训练 NN,使其输出正确分类的高概率(理想值为 1)。因此,我们最大化训练数据集的正确分类概率的乘积。出于技术原因,我们重新表述为一个等价的问题:最小化训练数据集的损失,其中损失是对数概率的负和。如果您需要单个样本的损失值,只需计算概率,取对数,并在结果前面加一个减号。为了训练 NN,损失相对于 NN 参数(例如卷积核的权重)的梯度被计算并用于更新参数。
解码
当我们有一个训练好的神经网络时,我们通常想用它来识别以前看不见的图像中的文本。或者用更专业的术语来说:我们希望在给定神经网络输出矩阵的情况下计算最可能的文本。你已经知道了一种计算给定文本分数的方法。但这一次,我们没有得到任何文本,事实上,它正是我们要寻找的文本。如果只有很少的时间步长和字符,尝试每一个可能的文本都是可行的,但是对于实际的用例,这是不可行的。
一个简单且非常快速的算法是由两个步骤组成的最佳路径解码:
- 它通过每个时间步取最可能的字符来计算最佳路径。
- 它通过首先删除重复字符,然后删除路径中的所有空格来撤消编码。剩下的代表已识别的文本。
图 4 中示出了一个例子。字符为“a”、“b”和“-”(空白)。有 5 个时间步长。让我们将最佳路径解码器应用于这个矩阵:t0 最可能的字符是“a”,这同样适用于 t1 和 t2。空白字符在 t3 时得分最高。最后,“b”最有可能在 t4。这给了我们路径“aaa-b”。我们删除重复的字符,得到“a-b ”,然后我们从剩余的路径中删除任何空白,得到文本“ab ”,我们将它作为识别的文本输出。
Fig. 4: Output matrix of NN. The thick dashed line represents the best path.
当然,最佳路径解码只是一种近似。很容易构造出给出错误结果的例子:如果你解码图 3 中的矩阵,你会得到""作为识别的文本。但是我们已经知道,“”的概率只有 0.36,而“a”的概率是 0.64。然而,近似算法在实际情况下经常给出好的结果。还有更高级的解码器,如波束搜索解码、前缀搜索解码或令牌传递,它们也使用关于语言结构的信息来改善结果。
结论和进一步阅读
首先,我们看了一个简单的神经网络解决方案所产生的问题。然后,我们看到反恐委员会如何能够解决这些问题。然后,我们通过查看 CTC 如何编码文本、如何进行损失计算以及如何解码经过 CTC 训练的神经网络的输出,来研究 CTC 是如何工作的。
例如,当您在 TensorFlow 中调用 ctc_loss 或 ctc_greedy_decoder 之类的函数时,这会让您很好地理解幕后发生的事情。但是,当你想自己实现 CTC 的时候,你需要知道更多的一些细节,尤其是要让它快速运行。Graves 等人[1]介绍了 CTC 操作,文中还展示了所有相关的数学。如果你对如何提高解码感兴趣,可以看看关于波束搜索解码的文章[2][3]。我用 Python 和 C++实现了一些解码器和 loss 函数,你可以在 github [4][5]上找到。最后,如果你想更全面地了解如何识别(手写)文本,可以看看我写的关于如何构建手写文本识别系统的文章[6]。
[1] 原纸包含所有数学
【2】香草束搜索解码
【3】字束搜索解码
【4】Python 实现的解码器
【5】实现的字束搜索解码
【6】文本识别系统
最后,概述一下我的其他媒体文章。
直观理解用于深度学习的卷积
原文:https://towardsdatascience.com/intuitively-understanding-convolutions-for-deep-learning-1f6f42faee1?source=collection_archive---------0-----------------------
探索让它们工作的强大的视觉层次
近年来,强大而通用的深度学习框架的出现,使得在深度学习模型中实现卷积层成为可能这是一项极其简单的任务,通常只需一行代码即可实现。
然而,理解卷积,尤其是第一次理解时,常常会感到有点紧张,因为像内核、过滤器、通道等术语都是相互叠加的。然而,卷积作为一个概念是非常强大和高度可扩展的,在这篇文章中,我们将一步一步地分解卷积运算的机制,将其与标准的全连接网络相关联,并探索它们如何建立强大的视觉层次,使它们成为图像的强大特征提取器。
2D 卷积:手术
2D 卷积本质上是一个相当简单的操作:你从一个核开始,它只是一个小的权重矩阵。这个内核在 2D 输入数据上“滑动”,对它当前所在的输入部分执行元素级乘法,然后将结果相加到单个输出像素中。
A standard convolution[1]
内核对它滑过的每个位置重复这个过程,将 2D 特征矩阵转换成另一个 2D 特征矩阵。输出要素实质上是输入要素的加权和(权重为核本身的值),这些输入要素大致位于输入图层上输出像素的相同位置。
一个输入特性是否属于这个“大致相同的位置”,直接取决于它是否在生成输出的内核区域。这意味着核的大小直接决定了在生成新的输出要素时有多少(或几个)输入要素被组合在一起。
这与完全连接的层形成了鲜明的对比。在上例中,我们有 5×5=25 个输入要素,3×3=9 个输出要素。如果这是一个标准的全连接图层,您将拥有一个 25×9 = 225 个参数的权重矩阵,其中每个输出要素都是每个单个输入要素的的加权和。卷积允许我们只使用 9 个参数对每个输出特征进行这种变换,而不是“查看”每个输入特征,只“查看”来自大致相同位置的输入特征。请务必记下这一点,因为这对我们以后的讨论至关重要。
一些常用的技术
在我们继续之前,绝对有必要了解卷积层中常见的两种技术:填充和步长。
- 填充:如果您看到上面的动画,请注意在滑动过程中,边缘基本上被“修剪掉”,将 5×5 的特征矩阵转换为 3×3 的特征矩阵。边缘上的像素永远不会在内核的中心,因为内核没有任何东西可以延伸到边缘之外。这并不理想,因为我们经常希望输出的大小等于输入。
Same padding[1]
填充做了一些非常聪明的事情来解决这个问题:用额外的“假”像素填充边缘(通常值为 0,因此经常使用术语“零填充”)。这样,滑动时的内核可以允许原始边缘像素位于其中心,同时扩展到边缘以外的伪像素中,产生与输入大小相同的输出。
- 跨越:通常在运行卷积层时,您希望输出比输入小。这在卷积神经网络中是常见的,其中当增加通道数量时,空间维度的大小减小。实现这一点的一种方法是使用池层(例如,取每个 2×2 网格的平均值/最大值,以将每个空间维度减半)。还有一种方法是使用步幅:
A stride 2 convolution[1]
stride 的想法是跳过内核的一些滑动位置。步长为 1 表示以一个像素为间隔选取幻灯片,因此基本上每一张幻灯片都充当标准卷积。步幅为 2 意味着选取相隔 2 个像素的幻灯片,在此过程中每隔一张幻灯片跳过一次,尺寸缩小大约 2 倍,步幅为 3 意味着每隔 2 张幻灯片跳过一次,尺寸缩小大约 3 倍,以此类推。
更现代的网络,如 ResNet 体系结构,完全放弃了其内部层中的池层,而在需要减少其输出大小时,支持步长卷积。
多通道版本
当然,上面的图表只处理图像只有一个输入通道的情况。实际上,大多数输入图像有 3 个通道,这个数字只会随着你进入网络的深度而增加。一般来说,我们很容易把通道看作是图像整体的“视图”,强调某些方面,弱化其他方面。
Most of the time, we deal with RGB images with three channels. (Credit: Andre Mouton)
A filter: A collection of kernels
这就是术语之间的关键区别:然而在单通道情况下,术语滤波器和内核是可互换的,在一般情况下,它们实际上是非常不同的。每个滤波器实际上都是内核、、的集合,对于该层的每个输入通道都有一个内核,并且每个内核都是唯一的。
卷积层中的每个滤波器产生一个且仅一个输出通道,它们的工作方式如下:
滤波器的每个内核在它们各自的输入通道上“滑动”,产生每个内核的处理版本。一些内核可能比其他内核具有更强的权重,以给予某些输入通道比其他通道更多的强调(例如,滤波器可能具有比其他通道具有更强权重的红色内核通道,因此,比其他通道对红色通道特征的差异响应更多)。
每个每通道处理的版本然后被加在一起以形成一个通道。滤波器的每个内核产生每个声道的一个版本,并且滤波器作为一个整体产生一个总输出声道。
最后,还有偏差项。偏置项的工作原理是,每个输出滤波器都有一个偏置项。到目前为止,偏置被添加到输出通道,以产生最终输出通道。
单个滤波器的情况下,任何数量的滤波器的情况都是相同的:每个滤波器使用其自己的不同核集合和标量偏差来处理输入,产生单个输出通道。然后将它们连接在一起,产生总输出,输出通道的数量等于滤波器的数量。然后,通常在将其作为输入传递到另一个卷积层之前应用非线性,然后该卷积层重复该过程。
2D 卷积:直觉
卷积仍然是线性变换
即使放下卷积层的机制,仍然很难将它与标准的前馈网络联系起来,并且它仍然没有解释为什么卷积可以扩展到图像数据,并且对图像数据的处理更好。
假设我们有一个 4×4 的输入,我们想把它转换成 2×2 的网格。如果我们使用前馈网络,我们会将 4×4 输入整形为长度为 16 的向量,并将其通过具有 16 个输入和 4 个输出的密集连接层。人们可以想象一个层的权重矩阵 W :
All in all, some 64 parameters
而且虽然卷积核运算乍一看可能有点奇怪,但它仍然是一个线性变换,有一个等价的变换矩阵。如果我们要对整形后的 4×4 输入使用大小为 3 的核 K 来获得 2×2 输出,则等效变换矩阵将是:
There’s really just 9 parameters here.
(注意:虽然上面的矩阵是一个等价的变换矩阵,但是实际的操作通常被实现为一个非常不同的矩阵乘法[2] )
卷积总体上仍然是线性变换,但同时也是一种截然不同的变换。对于一个有 64 个元素的矩阵,只有 9 个参数可以重复使用几次。每个输出节点只能看到选定数量的输入(内核内部的输入)。没有与任何其他输入的交互,因为它们的权重被设置为 0。
将卷积运算视为权重矩阵上的硬先验是很有用的。在这种情况下,我所说的先验是指预定义的网络参数。例如,当您使用预训练模型进行图像分类时,您使用预训练网络参数作为您的先验,作为您最终密集连接层的特征提取器。
从这个意义上说,两者为何如此高效(与它们的替代品相比)有着直接的直觉。与随机初始化相比,迁移学习的效率提高了几个数量级,因为您只需要优化最终全连接层的参数,这意味着您可以在每个类只有几十个图像的情况下获得出色的性能。
在这里,您不需要优化所有 64 个参数,因为我们将它们中的大多数设置为零(并且它们将保持这种状态),其余的我们转换为共享参数,结果只有 9 个实际参数需要优化。这种效率很重要,因为当你从 MNIST 的 784 个输入转到现实世界的 224×224×3 图像时,那就超过了 15 万个输入。试图将输入减半为 75,000 个输入的密集层仍然需要超过 10 亿个参数。相比之下,ResNet-50 的整体有大约 2500 万个参数。
因此,将一些参数固定为 0,并绑定参数可以提高效率,但与迁移学习的情况不同,在迁移学习的情况下,我们知道先验是好的,因为它对一组大型图像有效,我们如何知道这个是好的呢?
答案在于先验引导参数学习的特征组合。
位置
在本文前面,我们讨论了:
- 内核仅组合来自小的局部区域的像素来形成输出。也就是说,输出要素仅“看到”小范围局部区域的输入要素。
- 核被全局地应用于整个图像以产生输出矩阵。
因此,随着反向传播从网络的分类节点一路传来,核有了学习权重的有趣任务,以便仅从一组局部输入中产生特征。此外,因为内核本身应用于整个图像,所以内核学习的特征必须足够通用,以来自图像的任何部分。
如果这是任何其他类型的数据,例如应用程序安装的分类数据,这将是一场灾难,因为仅仅因为你的应用程序安装数量和应用程序类型列相邻,并不意味着它们与应用程序安装日期和使用时间有任何共同的“本地共享功能”。当然,这四个可能有一个潜在的更高层次的特征(例如,人们最想要的应用程序),但这让我们没有理由相信前两个的参数与后两个的参数完全相同。这四个可以有任何(一致的)顺序,仍然有效!
然而,像素总是以一致的顺序出现,并且附近的像素会影响一个像素,例如,如果所有附近的像素都是红色的,则该像素很可能也是红色的。如果存在偏差,这是一个有趣的异常,可以转换为一个特征,所有这些都可以通过将一个像素与其邻居以及其位置上的其他像素进行比较来检测。
这种想法正是许多早期计算机视觉特征提取方法的基础。例如,对于边缘检测,可以使用 Sobel 边缘检测滤波器,这是一种具有固定参数的内核,操作方式与标准单通道卷积类似:
Applying a vertical edge detector kernel
对于不包含边缘的网格(如背景天空),大多数像素都是相同的值,因此在该点内核的总输出为 0。对于具有垂直边缘的网格,边缘左侧和右侧的像素之间存在差异,内核将该差异计算为非零,从而激活和显示边缘。内核一次只能运行 3×3 个网格,检测局部范围内的异常,但当应用于整个图像时,足以检测全局范围内图像中任何位置的某个特征!
所以我们与深度学习的关键区别是问这个问题:有用的内核能被学习吗?对于在原始像素上操作的早期层,我们可以合理地期待相当低级别特征的特征检测器,如边缘、线等。
深度学习研究有一个完整的分支,专注于使神经网络模型可以解释。由此产生的最强大的工具之一是使用优化[3] 的特征可视化。核心思想很简单:优化图像(通常用随机噪声初始化)以尽可能强地激活滤镜。这确实有直观的意义:如果优化的图像完全充满了边缘,这就是过滤器本身正在寻找并被激活的有力证据。使用这个,我们可以看到学习过的过滤器,结果是惊人的:
Feature visualization for 3 different channels from the 1st convolution layer of GoogLeNet[3]. Notice that while they detect different types of edges, they’re still low-level edge detectors.
Feature Visualization of channel 12 from the 2nd and 3rd convolutions[3]
这里需要注意的一点是卷积图像是静止图像。来自图像左上角的小像素网格的输出仍然在左上角。因此,您可以在另一个卷积层(如左边的两个)上运行另一个卷积层,以提取更深层次的特征,我们将这些特征可视化。
然而,无论我们的特征检测器有多深,如果没有任何进一步的改变,它们仍将在图像的非常小的区域上操作。无论你的探测器有多深,你都无法从一个 3×3 的网格中探测到人脸。这就是感受野概念的由来。
感受野
任何 CNN 架构的一个基本设计选择是,从网络的开始到结束,输入大小越来越小,而通道的数量越来越多。如前所述,这通常是通过跨越或合并层来实现的。局部性决定了输出可以看到前一层的哪些输入。感受野决定了整个网络的原始输入的哪个区域是输出可以看到的。
步长卷积的思想是我们只处理相隔固定距离的幻灯片,跳过中间的幻灯片。从不同的角度来看,我们只保持输出相隔固定的距离,并删除其余的[1]。
3×3 convolution, stride 2
然后,我们对输出进行非线性处理,通常,在顶部叠加另一个新的卷积层。这就是事情变得有趣的地方。即使我们将具有相同局部面积的相同大小(3×3)的核应用于步长卷积的输出,该核也将具有更大的有效感受野:
这是因为条纹层的输出仍然表示相同的图像。与其说是裁剪,不如说是调整大小,唯一的问题是输出中的每个像素都是来自原始输入的相同粗略位置的更大区域(其其他像素已被丢弃)的“代表”。因此,当下一层的内核对输出进行操作时,它对从更大区域收集的像素进行操作。
(注意:如果你熟悉扩张回旋,请注意以上是而不是扩张回旋。两者都是增加感受野的方法,但是扩张卷积是单层的,而这发生在步长卷积之后的规则卷积上,其间有非线性)
Feature visualization of channels from each of the major collections of convolution blocks, showing a progressive increase in complexity[3]
感受野的这种扩展允许卷积层将低级特征(线、边缘)组合成高级特征(曲线、纹理),正如我们在 mixed3a 层中看到的。
接着是池化/跨步层,网络继续为更高层次的特征(零件、模式)创建检测器,正如我们在 mixed4a 中看到的。
与 224×224 的输入相比,网络上图像大小的反复减小导致卷积上的第 5 个块的输入大小仅为 7×7。此时,每个单个像素代表一个 32×32 像素的网格,规模巨大。
与早期的激活意味着检测边缘的图层相比,在这里,在微小的 7×7 网格上的激活是用于非常高级别的特征,例如鸟类。
网络作为一个整体从检测低级特征的少量过滤器(在 GoogLeNet 的情况下为 64 个)发展到非常大量的过滤器(在最后的卷积中为 1024 个),每个过滤器寻找一个非常具体的高级特征。接下来是最终的合并层,它将每个 7×7 的网格折叠成一个像素,每个通道都是一个特征检测器,其感受域相当于整个图像。
与标准前馈网络相比,这里的输出确实令人惊叹。标准的前馈网络会从图像中每一个像素的组合中产生抽象的特征向量,需要大量的数据来训练。
具有强加于其上的先验的 CNN,通过学习非常低级的特征检测器开始,并且随着其感受域的扩展而跨层,学习将那些低级特征组合成逐渐更高级的特征;不是每一个像素的抽象组合,而是概念的强烈的视觉层次。
通过检测低级别特征,并使用它们来检测更高级别的特征,随着它在视觉层次上的进步,它最终能够检测整个视觉概念,如脸、鸟、树等,这就是为什么它们如此强大,但对图像数据有效。
关于对抗性攻击的最后一点说明
根据 CNN 建立的视觉层级,假设他们的视觉系统与人类相似是相当合理的。它们对真实世界的图像非常好,但它们也失败了,这强烈表明它们的视觉系统不完全像人类。最主要的问题:对抗性例子【4】,经过专门修改来忽悠模型的例子。
To a human, both images are obviously pandas. To the model, not so much.[4]
如果导致模型失败的唯一被篡改的例子是那些甚至人类都会注意到的例子,那么对立的例子就不是问题。问题是,模型很容易受到样本的攻击,这些样本只是被稍微篡改了一下,显然骗不了任何人。这为模型悄无声息地失败打开了大门,这对从无人驾驶汽车到医疗保健的广泛应用来说是非常危险的。
对抗敌对攻击的鲁棒性目前是一个非常活跃的研究领域,是许多论文甚至竞赛的主题,解决方案肯定会改进 CNN 架构,使其变得更安全、更可靠。
结论
CNN 是允许计算机视觉从简单应用扩展到复杂产品和服务的模型,从照片库中的人脸检测到更好的医疗诊断。它们可能是计算机视觉向前发展的关键方法,或者其他一些新的突破可能就在眼前。不管怎样,有一件事是肯定的:它们是惊人的,是当今许多创新应用的核心,并且非常值得深入了解。
参考
- 深度学习卷积算法指南
- 用于视觉识别的 CS231n 卷积神经网络—卷积神经网络
- 特征可视化——神经网络如何建立对图像的理解(注意:这里的特征可视化是由 Lucid 库产生的,这是这篇期刊文章中技术的开源实现)
- 用对立的例子攻击机器学习
更多资源
- fast . ai——第三课:改进你的图像分类器
- Conv 篮网:模块化视角
- 使用非常少的数据构建强大的图像分类模型
希望你喜欢这篇文章!如果你想保持联系,你可以在 Twitter 这里 找到我。如有疑问,欢迎评论!—我发现它们对我自己的学习过程也很有用。
直观理解变型自动编码器
原文:https://towardsdatascience.com/intuitively-understanding-variational-autoencoders-1bfe67eb5daf?source=collection_archive---------0-----------------------
A Standard Variational Autoencoder
以及为什么它们在创造你自己的文本、艺术甚至音乐时如此有用
与神经网络作为回归器或分类器的更标准用途相反,变分自动编码器(VAEs)是强大的生成模型,现在具有从生成假人脸到制作纯合成音乐的各种应用。
这篇文章将探讨什么是 VAE,为什么它如此有效背后的直觉,以及它作为各种媒体的强大生成工具的用途。
但首先,为什么是维斯?
Exploring a specific variation of input data[1]
当使用创成式模型时,您可以简单地生成一个随机的、新的输出,它看起来类似于训练数据,并且您当然也可以使用 VAEs 来实现这一点。但是更多的时候,你想要改变,或者探索你已经拥有的的数据的变化,而且不仅仅是以随机的方式,而是以期望的、特定的方向。这就是 VAEs 比目前可用的任何其他方法更好的地方。
解码标准自动编码器
自动编码器网络实际上是一对两个相连的网络,一个编码器和一个解码器。编码器网络接收输入,并将其转换为更小、更密集的表示形式,解码器网络可以使用该表示形式将其转换回原始输入。
如果你不熟悉编码器网络,但熟悉卷积神经网络(CNN),那么你可能已经知道编码器是做什么的了。
The encoder inside of a CNN[a]
任何 CNN 的卷积层接收大图像(例如大小为 299x299x3 的秩 3 张量),并将其转换为更紧凑、更密集的表示(例如大小为 1000 的秩 1 张量)。然后,全连接分类器网络使用这种密集表示对图像进行分类。
编码器与此类似,它只是一个网络,接收输入并产生一个更小的表示(编码)(T7),其中包含足够的信息供网络的下一部分将其处理成所需的输出格式。典型地,编码器与网络的其他部分一起被训练,通过反向传播被优化,以产生对于手边的任务特别有用的编码。在 CNN 中,产生的 1000 维编码对分类特别有用。
自动编码器采纳了这一想法,并通过让编码器生成对重建自己的输入特别有用的编码,稍微颠倒了一下。
A standard Autoencoder
整个网络通常作为一个整体来训练。损失函数通常是输出和输入之间的均方误差或交叉熵,称为重构损失,其惩罚网络产生不同于输入的输出。
由于编码(只是中间隐藏层的输出)的单元远少于输入,编码器必须选择丢弃信息。编码器学习在有限的编码中尽可能多地保留相关信息,并智能地丢弃不相关的部分。解码器学习采用编码并正确地将其重构为完整的图像。它们共同构成了一个自动编码器。
标准自动编码器的问题是
标准的自动编码器学会生成紧凑的表示并很好地重建它们的输入,但是除了像去噪自动编码器这样的一些应用之外,它们相当有限。
对于生成来说,自动编码器的基本问题是它们将输入转换到的潜在空间以及它们的编码向量所在的位置可能不连续,或者不允许简单的插值。
Optimizing purely for reconstruction loss
例如,在 MNIST 数据集上训练自动编码器,并可视化来自 2D 潜在空间的编码,揭示了不同簇的形成。这是有意义的,因为每种图像类型的不同编码使解码器更容易解码它们。如果你只是复制相同的图像,这没问题。
但是当你在建立一个生成型模型的时候,你不想准备复制你放进去的同一个形象。您希望从潜在空间中随机取样,或者从连续的潜在空间中生成输入图像的变化。
如果空间具有不连续性(例如,簇之间的间隙),并且您从那里采样/生成变化,解码器将简单地生成不切实际的输出,因为解码器不知道如何处理潜在空间的该区域。在训练期间,它从未看到来自潜在空间区域的编码向量。
可变自动编码器
变分自动编码器(vae)有一个从根本上区别于普通自动编码器的独特属性,正是这个属性使它们对生成式建模如此有用:它们的潜在空间通过设计、是连续的,允许简单的随机采样和插值。
它通过做一些乍一看似乎相当令人惊讶的事情来实现这一点:让它的编码器不输出大小为 n、的编码向量,而是输出大小为 n 的两个向量:一个均值向量、μ 和另一个标准差向量、σ 。
Variational Autoencoder
它们形成长度为 n 的随机变量向量的参数,其中第 i 个元素为 μ 和 σ 是第 i 个随机变量的平均值和标准偏差, X i,我们从中进行采样,以获得采样编码,并将其向前传递给解码器:
Stochastically generating encoding vectors
这种随机生成意味着,即使对于相同的输入,虽然平均值和标准偏差保持不变,但实际的编码在每次通过时都会有所不同,这仅仅是因为采样。
直观地说,均值向量控制着输入的编码应该集中在哪里,而标准差控制着“区域”,即编码可以偏离均值多少。由于编码是从“圆”(分布)内的任何地方随机生成的,解码器了解到不仅潜在空间中的单个点引用该类的样本,所有附近的点也引用相同的样本。这允许解码器不仅解码潜在空间中的单个特定编码(使可解码潜在空间不连续),而且还解码稍微变化的编码,因为解码器在训练期间暴露于相同输入的编码的变化范围。在代码中:
code for sampling mean and stddev
现在,通过改变一个样本的编码,该模型暴露于一定程度的局部变化,从而在局部尺度上,即对于相似的样本,产生平滑的潜在空间。理想情况下,我们希望不太相似的样本之间有重叠,以便在类之间插入。然而,由于对于向量μ和 σ 可以取什么值没有限制* ,编码器可以学习为不同的类生成非常不同的 μ ,将它们分簇,并最小化 σ ,确保编码本身对于同一样本不会有太大变化(也就是说,解码器的不确定性更小)。这允许解码器有效地重构训练数据。*****
我们理想中想要的是编码,所有的尽可能地彼此接近,同时仍然是不同的,允许平滑的插值,并且能够构造新的样本。
为了迫使这一点,我们将 kull back-lei bler 散度(KL 散度【2】)引入损失函数。两个概率分布之间的 KL 偏离简单地测量了它们彼此偏离的程度。这里最小化 KL 散度意味着优化概率分布参数 (μ 和 σ) 以非常类似于目标分布。
对于 VAEs,KL 损失相当于 X 中的分量XI~N(μI,σ i )与标准常态【3】之间所有 KL 偏差的之和。当μ i = 0,σ i = 1 时最小。
直观上,这种损失促使编码器将所有编码(对于所有类型的输入,例如所有 MNIST 数)均匀地分布在潜在空间的中心周围。如果它试图通过将它们聚集到远离原点的特定区域来“作弊”,它将受到惩罚。
现在,使用纯 KL 损失导致潜在空间,导致编码密集地随机放置在潜在空间的中心附近,很少考虑附近编码之间的相似性。解码器发现不可能从这个空间中解码出任何有意义的东西,原因很简单,因为这里真的没有任何意义。
Optimizing using pure KL divergence loss
然而,一起优化这两者导致潜在空间的生成,该潜在空间通过聚类在局部尺度上保持附近编码的相似性,然而在全局上,在潜在空间原点附近非常密集地打包(将轴与原始轴进行比较)。
Optimizing using both reconstruction loss and KL divergence loss
直观上,这是重建损失的群集形成性质和 KL 损失的密集打包性质达到的平衡,形成解码器可以解码的不同群集。这很棒,因为这意味着当随机生成时,如果你从编码向量的相同先验分布中采样一个向量, N ( 0 , I ),解码器将成功解码它。如果你在插值,簇之间没有突然的间隙,而是解码器可以理解的特征的平滑混合。
The final loss function
向量运算
那么我们实际上是如何产生我们所说的平滑插值的呢?从这里开始,它是潜在空间中简单的向量运算。
Interpolating between samples
例如,如果您希望在两个样本之间的中途生成一个新样本,只需找到它们的均值( μ )向量之间的差,并将该差的一半加到原始样本上,然后简单解码即可。
Adding new features to samples
生成特定特征怎么样,比如在一张脸上生成眼镜?找到两个样本,一个带眼镜,一个不带,从编码器获得它们的编码向量,并保存差异。将这个新的“眼镜”向量添加到任何其他人脸图像中,并对其进行解码。
从这里去哪里?
在变分自动编码器的基础上还可以做很多进一步的改进。事实上,你可以用卷积反卷积编码器-解码器对来取代标准的全连接密集编码器-解码器,比如这个项目【4】,来制作出色的合成人脸照片。
Generating celebrity-lookalike photos
您甚至可以使用 LSTM 编码器-解码器对(使用 seq2seq 架构的修改版本)来训练自动编码器处理顺序的、离散的数据(使用 GANs 等方法是不可能的),以产生合成文本,甚至在 MIDI 样本之间进行插值,如 Google Brain 的 Magenta 的 music vae【5】:
vae 可以处理各种不同类型的数据,顺序的或非顺序的,连续的或离散的,甚至有标签的或完全无标签的,这使它们成为非常强大的生成工具。我希望你现在理解了 VAEs 是如何工作的,并且你也能够在你自己的生产努力中使用它们。
如果你觉得这篇文章有用,并且相信其他人也会觉得有用,请留下你的掌声!如果你想保持联系,你可以在 Twitter 这里 找到我。
注意事项
[1] 潜在约束:无条件生成模型的条件生成
[2] 库尔贝克-莱布勒分歧解释
[3] 两个单变量高斯函数之间的 KL 散度
【4】深度特征一致变分自动编码器
[5] 分级变分音乐自动编码器
延伸阅读:
- 变型自动编码器
- 教程—什么是变分自动编码器?
- 变型自动编码器教程
实施:
- 在 Keras 中构建自动编码器
- Keras 中的卷积反卷积自动编码器
利用机器学习监测入侵物种
原文:https://towardsdatascience.com/invasive-species-monitoring-using-machine-learning-9a7b29d565f?source=collection_archive---------4-----------------------
Invasive Species Monitoring using Machine Learning
最近,Kaggle 推出了一项竞赛,ka ggle 人面临的挑战是开发算法,以更准确地识别森林和树叶的图像是否包含入侵的绣球花。因此,简而言之,我们可以看着一幅图像,判断它是否有入侵性绣球(class = 0)或没有入侵性绣球(class = 1)。这告诉我们,这是一个分类问题,因为我们的输入是图像,这将是一个计算机视觉问题。
在这里,我将解释我们使用机器学习来解决这个问题的分步步骤。
影像探索
我们有自己的数据集,我们想做的第一件事是看看我们的图像看起来怎么样。为什么要看图像?因为它将帮助我们识别数据集中各种图像的特征、维数,找出图像是否有眩光以及需要采取什么步骤进行预处理。
在查看图像后,我们发现,如果一个人看到来自数据集的图像,并询问绣球花的存在,他将主要根据花和叶子的类型和颜色做出决定。另一件事,我们发现我们的数据集包含较小尺寸的矩形图像。我们的数据集包含 1400 个入侵物种和 867 个非入侵类的图像。
根据以上观察,我们得出以下结论:
- 我们的数据集很小而且不平衡(3:2)。(当数据集中存在的类不具有相同数量的样本时,该数据集称为不平衡的。)
- 我们的图像是矩形的;因此,如果我们决定使用卷积神经网络(我们计划使用 CNN),我们可能需要制作正方形格式的图像。
- 图像尺寸很小,因此很难识别特征。
- 数据集中的一些图像对比度较低。
预处理数据集
对比拉伸
由于我们的图像对比度越来越低,我们需要找到一种方法来增强图像的对比度。这对我们来说很重要,因为对比度有助于区分图像的不同特征,而这些特征在低对比度图像中可能无法表现出来。为了实现这一点,我们应用了一种简单的图像增强技术,称为对比度拉伸,顾名思义,它试图通过“拉伸”图像包含的亮度值范围来跨越所需的值范围,从而提高图像的对比度。
Contrast Stretching
数据扩充
我们用于训练模型的样本数量较少,由于缺乏训练数据,我们的模型可能无法为测试集提供良好的预测。为了解决这个问题,我们将使用数据扩充,这基本上意味着从现有的训练数据集人工生成数据。数据扩充中的一种流行技术是变换(这包括移位、缩放、旋转、翻转等。).我们将应用垂直翻转从训练集中生成更多样本,这将有助于加强模型。
Data Augmentation using Vertical Flip
填料
我们的图像尺寸很小,如果我们提供它来训练我们的模型,我们可能会失去一些功能。为了解决这个问题,我们需要调整图像的大小。我们的图像是矩形尺寸,因此在图像顶部应用 resize 将导致图像拉伸或扭曲,这将为模型提供错误的特征。最好将图像转换为正方形格式,这可以通过对图像进行切片或在图像周围添加白色或黑色空间(填充)使其成为正方形来实现。切片将导致信息丢失,我们可能会失去一些重要的功能,因此我们将使用填充。
调整大小
正如我前面提到的,图像的尺寸很小,我们将使用线性插值来调整图像的大小。这将有助于网络识别尺寸较小但对分类很重要的特征,例如绣球花的存在。
模型生成
我们使用的是一个的 11 层 与 ReLU 的激活函数。
Convolution Neural Network
我喜欢 CNN 在这里的解释方式。
请点击在 AlexNet 上找到论文。
结果
我们生成的模型在测试数据集上提供了 95%的准确率。在 Github 上找到代码库。
参考文献
对于数据集,请转到 Kaggle 竞赛
与杰鲁巴尔·约翰·卢克和库纳尔·萨卡尔合作撰写。
逆向强化学习
原文:https://towardsdatascience.com/inverse-reinforcement-learning-6453b7cdc90d?source=collection_archive---------3-----------------------
导言和主要问题
本文根据约翰尼斯·海德克的作品****雅各布·斯坦哈特 ,奥万·埃文斯 乔丹·亚历山大普拉桑特·奥纳库坦 ,我用他们的话来帮助人们理解 IRL。****
逆强化学习是最近发展起来的一种机器学习框架,可以解决强化学习的逆问题。
基本上,IRL 是关于向人类学习的。
逆强化学习 (IRL) 是通过观察智能体的行为来学习其目标、价值观或奖励的领域。
约翰内斯·海德克说:“我们可能会观察人类在某些特定任务中的行为,并了解人类试图实现的环境状态以及具体的目标可能是什么。”(来源)
“IRL 是一个依赖于马尔可夫决策过程(MDPs)的范例,其中学徒代理的目标是从专家演示中找到一个可以解释专家行为的奖励函数。”比拉尔·皮奥特、马蒂厄·艾斯特和奥利弗·皮特奎因,弥合了模仿学习和逆向强化学习之间的差距
如果有一天某些人工智能达到了超人的能力,IRL 可能是理解人类想要什么并有望朝着这些目标努力的一种方法。
奖励函数
乔丹·亚历山大说:“我们的目标是学习一种决策过程,以产生最大化某种预先定义的奖励函数的行为。基本上,目标是从代理的观察行为中提取奖励函数。
例如,考虑自动驾驶的任务。一种方法是创建一个奖励函数,捕捉驾驶员的期望行为,如红灯停车、避开行人等。然而,这需要一份我们想要考虑的所有行为的详尽清单,以及一份描述每个行为重要性的权重清单。"(来源)
人工智能研究员 Prasanth Omanakuttan 表示,“然而,通过 IRL,任务是获取一组人类生成的驾驶数据,并提取人类对该任务的奖励函数的近似值。尽管如此,解决一个问题所需的大部分信息都是在真实回报函数的近似值中获得的。一旦我们有了正确的奖励函数,问题就简化为寻找正确的政策,并且可以用标准的强化学习方法来解决。”(来源
Source
“将复杂的任务转化为简单的奖励函数的主要问题是一个给定的政策对于许多不同的奖励函数来说可能是最优的。也就是说,即使我们有专家的行动,也存在许多不同的奖励函数,专家可能试图最大化这些函数。”乔丹·亚历山大,斯坦福大学,向人类学习:什么是逆向强化学习?
比拉尔·皮奥特、马蒂厄·艾斯特和奥利维尔·皮特奎因说过:“换句话说,我们的目标是模拟一个在给定环境中采取行动的主体。因此,我们假设我们有一个状态空间 S(代理和环境可以处于的状态集合),一个动作空间 A(代理可以采取的动作集合),以及一个转移函数T(S′| S,A),它给出了当采取动作 A 时从状态 S 移动到状态 S′的概率。例如,对于一个学习控制汽车的 AI, 状态空间将是汽车的可能位置和方向,动作空间将是 AI 可以发送给汽车的一组控制信号,转移函数将是汽车的动力学模型。 (s,a,t)的元组称为 MDP∖R,它是一个没有报酬函数的马尔可夫决策过程。(MDP∖R 将有一个已知的地平线或贴现率γ,但为了简单起见,我们将这些略去。)
Source
IRL 的推理问题是在给定一个最优策略π∫:s→a 的情况下推理一个奖励函数 r。对于 MDP∖R.,我们从状态的样本(s,a)中学习策略π∫,并根据π∫(可能是随机的)学习相应的动作。通常,这些样本来自一个轨迹,该轨迹记录了单个事件中代理的状态和动作的完整历史:
在汽车的例子中,这将对应于正在演示期望的驾驶行为的专业人类驾驶员所采取的动作(其中这些动作将被记录为给方向盘、刹车等的信号。).
给定 MDP∖R 和观察到的轨迹,目标是推断回报函数 r。在贝叶斯框架中,如果我们指定 r 的先验,我们有:
似然性 P(ai|si,R)恰好是πR(s)[ai],其中πR 是奖励函数 R 下的最优策略。注意,在给定奖励的情况下计算最优策略通常是非平凡的;除了在简单的情况下,我们通常使用强化学习来近似策略。由于指定先验、计算最优策略和整合奖励函数的挑战,IRL 中的大部分工作使用某种近似的贝叶斯目标。"( )来源 )
奖励信号
约翰内斯·海德克说:“在大多数强化学习任务中,没有奖励信号的自然来源。相反,它必须是手工制作和精心设计的,以准确地代表任务。
通常,有必要手动调整 RL 代理的奖励,直到观察到期望的行为。为某些目标找到合适的奖励函数的更好的方法可能是观察执行任务的(人类)专家,以便从这些观察中自动提取相应的奖励。"(来源)
IRL 的最大动机是为一项任务手动指定一个奖励函数通常非常困难。
数据中的人类行为
Johannes Steinhardt 说“IRL 是一种很有前途的学习人类价值观的方法,部分原因是数据容易获得。对于监督学习,人类需要产生许多专门用于某项任务的标记实例。相比之下,IRL 是一种无监督/半监督的方法,其中任何人类行为记录都是潜在的数据源。脸书的用户行为日志,YouTube 视频等。提供了许多关于人类行为的数据。
然而,虽然有大量关于人类偏好的现有数据,但利用这些数据进行 IRL 在当前技术下是困难的。"(来源)
精选数据
Johannes Steinhardt 提到的另一个因素是关于数据的问题。他说“书籍和视频中的人类行为记录对于 IRL 算法来说很难使用。然而,来自脸书的数据似乎很有希望:我们可以存储状态和每个人类动作(点击和滚动)。
虽然这涵盖了广泛的任务,但有明显的局限性。人类的某些偏好似乎很难从计算机的行为中了解。"
信息和偏见
人类的行为取决于他们的偏好和信仰。
Owain Evans 和 Johannes Steinhardt 说“信念,就像偏好一样,从来不会被直接观察到。对于狭窄的任务(例如,人们从显示器中选择他们最喜欢的照片),我们可以模拟人类对状态的完全了解。但是对于大多数现实世界的任务,人类的信息是有限的,并且他们的信息会随着时间而变化。如果 IRL 假设人类拥有全部的信息,那么这个模型就是错误的,概括人类在其他情况下的偏好可能是错误的。以下是一些例子:
- 有人从家来到一家已经打烊的餐馆。如果假设他们有完整的知识,那么 IRL 会推断出另一种偏好(例如去散步),而不是去吃东西。
- 假设一个 IRL 算法正在从一个人笔记本电脑上的按键推断他的目标。这个人经常忘记他们的登录密码,不得不重新设置。这种行为很难用 POMDP 风格的模型来捕捉:人类会忘记一些字符串,但不会忘记其他字符串。IRL 可能推断这个人想要重复重置他们的密码。**
上述情况源于人类遗忘信息——即使信息只是一小段字符串。这是人类系统地偏离理性贝叶斯代理的一种方式。"(来源)
长期计划
Owain Evans 和 Johannes Steinhardt 给出的另一个要素是长期计划。事实上,他们说“为了实现一个长期目标,代理人通常会采取一系列长时间的行动,这些行动会在瞬间产生负面效用。出于几个原因,这样的长期计划会使 IRL 变得更加困难。让我们关注两点:
- IRL 系统可能无法访问正确类型的数据来学习长期目标。
- 需要预测长的动作序列会使算法在面对模型错误设定时更加脆弱。
为了根据长期计划做出推论,拥有单个代理人在很长一段时间内的行动的一致数据将是有帮助的。但在实践中,我们可能会有更多的数据,包括大量不同代理的简短快照(因为许多网站或在线服务已经记录了用户交互,但即使一个人离线,也很少有人在很长一段时间内被彻底跟踪和记录)。
另一方面,有一些服务确实拥有长期的个人用户的大量数据。然而,这些数据还有另一个问题:它在非常系统的方面是不完整的(因为它只跟踪在线行为)。例如,有人可能大部分时间都在网上阅读课程笔记和维基百科;这是可能被记录的数据。然而,不太可能会有一个人参加期末考试、通过课程、然后根据他们的课堂表现获得实习的记录。当然,这个序列的一些片段可以根据一些人的电子邮件记录等推断出来。,但相对于维基百科的使用记录,它可能在数据中没有得到充分的体现。无论是哪种情况,都需要一定程度的推理来理解这些数据。
接下来,我们讨论另一个潜在的问题——模型设定错误的脆弱性。
假设有人花了 99 天做一件无聊的事情,在第 100 天完成了一个重要的目标。一个只试图正确预测行动的系统,如果它预测这个人天生喜欢无聊的任务,那么它在 99%的时间里都是正确的。当然,一个理解目标以及任务如何导致目标的系统在 100%的时间里都是正确的,但是即使是理解中的小错误也会使准确率回到 99%以下。
基本上,代理人模型的大变化可能只会导致模型预测准确性的小变化,并且实现目标的时间范围越长,这种情况可能越多。这意味着,即使模型中轻微的错误设定也可能使天平向(非常)不正确的奖励函数倾斜。一个解决方案是识别那些看起来与回报函数紧密相关的“重要”预测,并特别关注那些正确的预测。"(来源)
即使是轻微的模型不规范,“正确的”模型在典型的度量标准(如预测准确性)下实际上可能表现得更差。因此,可能需要更仔细的方法来构建模型。
人工智能研究员约翰内斯·海德克(Johannes Heidecke)说:“在 IRL 中,我们被给予一些代理人的政策或行为历史,我们试图找到一个解释给定行为的奖励函数。假设我们的代理人采取最优行动,即总是为其奖励函数选择最佳可能的行动,我们试图估计可能导致这种行为的奖励函数。”(来源
IRL 的问题
如何找到一个奖励函数,在这个函数下观察到的行为是最优的。这带来了两个主要问题:
- 对于大多数行为观察,有许多合适的奖励函数。解集往往包含许多退化解,即给所有状态分配零奖励。
- IRL 算法假设观察到的行为是最佳的。这是一个强有力的假设,当我们谈到人类的示范时,可以说是太强了。
重要的 : IRL 寻找“解释”演示的奖励函数。不要将此与学徒学习(AL)相混淆,在学徒学习中,主要兴趣是能够产生可见示范的政策。****
比拉尔·皮奥特、马蒂厄·艾斯特和奥利弗·皮特奎因认为,“IRL 依赖于这样的假设,即专家的政策对于未知的报酬函数是最优的。在这种情况下,学徒的第一个目标是学习一个奖励函数来解释观察到的专家行为。然后,使用直接强化学习,它根据这个奖励优化它的策略,并希望表现得和专家一样好。学习奖励比立即学习政策有一些优势。首先,可以对奖励进行分析,以便更好地了解专家的行为。第二,它允许适应环境动态的扰动。
换句话说,它可以转移到其他环境中。第三,它允许通过真实的交互随着时间的推移而改进,而不需要新的演示。然而,一个主要的问题是必须解决 MDP 以获得关于学习奖励的最优策略。另一个问题是,IRL 问题是不适定的,因为每个政策对于零回报(显然不是人们所寻求的回报)都是最优的。"(来源)
想了解更多,我推荐这几篇: -https://thinking wires . com/posts/2018-02-13-IRL-tutorial-1 . html
-https://www . less wrong . com/posts/cn C2 rmwegigpjv 8 go/model-mis-specification-and-inverse-reinforcement-learning
-http://www.lifl.fr/~pietquin/pdf/TNNLS_2016_BPMGOP.pdf
-https
世界杯点球大战中损失厌恶的研究
原文:https://towardsdatascience.com/investigating-loss-aversion-in-world-cup-penalty-shoot-outs-8bd2ba48ce86?source=collection_archive---------8-----------------------
From Markus Unger
我最近在读一本名为《思考,快与慢》的书,这本书向我介绍了规避损失的概念。这是一种心理效应,在这种效应下,人们会更加努力地避免感知到的损失,而不是获得同等的收益。例如,你自己的钱损失了 5 英镑,感觉比赚了 5 英镑还要糟糕。
这本书讨论了这在体育运动中的影响,其中有一项关于职业高尔夫的研究。在一场高尔夫比赛结束时,只有击球总数才算数。然而,这项研究表明,高尔夫球手在标准杆推杆(失误意味着在该洞失去一杆)方面比小鸟(在该洞获得一杆)更好。理论是,正是对损失的厌恶使他们下意识地更加关注标准杆推杆,因此他们在推杆上更加成功。
随着最近世界杯的举行,英格兰队卷入了与哥伦比亚队的点球大战,我想知道厌恶损失是否会产生影响。
点球决胜用于决定在淘汰赛阶段正常比赛的加时赛后仍然平局的比赛。有五轮比赛,球队轮流射门,如果之后仍然是平局,可能还有额外的几轮“突然死亡”点球。开始时要掷硬币来决定谁先开球。
就像高尔夫球一样,只有你在决赛中的总分才算数,但是由于处罚是在回合中进行的,所以可能会出现锚定数字效应,就像上面的高尔夫球例子一样。鉴于大多数点球都是得分的,在一轮比赛中第一个踢球的球员的“标准杆”就是得分——因为错过很可能意味着该轮比赛的负结果。然而,对于第二个踢球者来说,“par”是可变的。如果第一个踢球者得分,那么“标准杆”对他来说是一样的,但如果第一个踢球者错过了…突然“标准杆”也不见了,得分就是“小鸟球”,因为这将是这一轮的收获。
会不会是职业足球运动员肩负着国家的希望,在某些情况下没有尽最大努力?
为了测试这一点,我首先需要一组点球结果的数据。那么,如果厌恶损失有效果,我希望看到以下结果:
- 每一轮中第一次踢腿的得分可能性不受前一次踢腿的影响,因为那是在前一轮中,所以在不同的参考系中。例如,从下面的图表可以看出,kick 2a 不受 1b 的影响,3a 不受 2b 的影响,依此类推。
- 如果一轮中的第一脚踢不中,第二脚踢(“b”脚踢)的得分可能性将会下降。
- 考虑到这种影响,先踢的队更有可能获胜。
Penalties kicking order
创建世界杯点球数据集
当我去寻找这方面的数据集时,我很惊讶,我找不到预先存在的数据集。有大量关于处罚事实的文章,但没有一篇包括他们使用的数据。幸运的是,维基百科有一个表格记录了 1982 年第一次点球大战的所有结果。
How hard could it be to scrape data already in a table?
我听说 80%的数据科学工作是数据清理,但出于某种原因,我不认为这适用于我。数据已经在一个表中了,这能有多难?…男孩,我错了。几乎每个列都需要自己的特殊处理,这占用了这个项目的大部分时间。我也努力将数据重新格式化成每列一个变量的“整齐数据格式。我在最近参加的 Udacity 数据分析师课程中发现了整齐的数据,这将使以后的处理更加容易。
完成的 tidy 数据集是一个 csv 文件,还有我用来创建和分析它的 python 工作簿,在我的 github 上。它包含了 30 场不同的点球大战和 279 次个人踢球的数据。
损失厌恶分析
一旦收集和整理了数据,分析就相对容易了。
先踢有优势吗?
我测量的第一件事是先踢的队获胜的概率。一个对点球大战的批评是一线队赢的可能性更大,但这在数据中看到了吗?
不要!在这个数据中,如果先踢的队会赢,那么就没有优势了。(随着时间的推移,这已经发生了很大的变化,我在最后的一个注释中给出了更多的细节。)看个人点球,一线队的点球成功几率略高。
一轮中的第一次踢腿会受到前一次踢腿的影响吗?
他们的成功率没有区别,所以不,前面的踢腿并不影响该队在回合中先踢腿。
因为这是与前一轮的比较,第一轮的踢腿不包括在这个测试中。
一轮比赛的第二次踢腿会受到前一次踢腿的影响吗?
也许!根据第一次踢球的结果,得分的可能性有 6%的差异。即使这些测量显示了差异,重要的问题是:这是一个显著的差异吗?****
对结果显著性的信心
测量的差异实际上可能只是随机噪声,因为可能没有足够的样本来确信差异确实存在。因为这是分类数据,所以我将用卡方检验来检验这一点的独立性。这将输出一个 p 值,如果它低于我选择的显著性水平,只有这样我才能声称有显著性差异。
无效假设是一轮的第一脚踢不影响第二轮的结果,另一个假设是它会影响。
我选择的显著性水平为 0.10,也就是说,有 10%的可能性,我会认为测量的差异是显著的,而实际上不是。我选择了 10%,因为我想相当确定这是有影响的,但我不太担心会出错。如果我错误地指责世界顶级足球运动员不够努力,我肯定不是第一个;我相信他们会克服的。😝
测试的输出是:
p 值= 0.5107
结论:未能拒绝零假设
Awww …仅仅 0.51 的 p 值与所需的 0.1 相差甚远,因此可以确信测得的差异实际上不仅仅是随机噪声。我无法拒绝无效假设,所以结论是一轮比赛的第一次踢腿的结果不会影响第二轮比赛的结果。
那是为了第二轮比赛。对于一轮比赛的第一次踢腿,我根本不需要做测试,因为前一次踢腿得分或失误的结果之间几乎没有可测量的差异。所以我可以总结出点球,无论是一轮比赛中的第一脚还是第二脚,都不会受到前一脚结果的影响(在这个数据集中)。
包裹
令人失望的是,我不能证明损失厌恶在起作用,但研究这个很有趣。如果有人想进一步研究这个问题,维基百科页面上有更多关于欧洲锦标赛的点球大战数据。这个数据和世界杯点球数据的表格非常相似,所以可能需要对我为其制作的脚本做一些小的修改。
关于踢第一优势的注意事项
我在上面说过,如果第一个踢球的队赢了,那就是五五开。现在这是真的,但随着时间的推移,它已经发生了很大的变化。在 80 年代,90 年代初和 2010 年,踢腿是一个劣势,但从 90 年代中期到 2010 年,成为一个巨大的红利。这一时期很可能是点球大战偏向于球队先踢的观点的来源。
由于这里的样本量较小,每场锦标赛只有几场淘汰赛,所以你可以预期不同的锦标赛之间会有很大的差异。有趣的是这种趋势:在一些比赛中很低,然后很高,然后又很低。
世界象棋锦标赛决赛方差的研究
原文:https://towardsdatascience.com/investigating-the-variance-of-the-world-chess-championship-final-b8bb7626cc26?source=collection_archive---------12-----------------------
卡尔森决赛方法的统计分析
Credit: GR stocks on unsplash
当 FIDE 世界象棋锦标赛正在进行时,我发现了以下问题:
假设其中一个玩家比他的对手强,他赢了 20%的比赛,输了 15%的比赛,65%的比赛是平局。这场比赛的胜利值 1 分,每位玩家得半分,输 0 分。在 12 场比赛中,第一个得分 6.5 分的选手获胜。
更好的选手赢得 12 场比赛的机会有多大?为了让更好的玩家有 75%的机会赢得比赛,一场比赛要进行多少场?90%的可能性?99%的可能性?
现在,比赛结束不到一个月了,所有的分析都来自于卡尔森 3-0 横扫对手的激烈的 12 场平局比赛,我发现提出的问题非常相关,因为毕竟球员们在所有 12 场常规比赛中都打成了平局。卡尔森的策略是抽长得多的常规比赛(第 1 场比赛 7 小时,第 12 场比赛 3 小时),以便在短得多的决胜局中压倒他的对手,而众所周知他在决胜局中是无与伦比的,这是否是比赢得常规比赛更安全的选择?
在本文中,我打算实现一个简单的 Python 脚本,试图模拟在什么情况下(每场比赛的游戏数)最好的玩家几乎总是会赢。
我提议用我喜欢的东西来解决这个问题:取样。
我将假设两个不知疲倦的代理人 A 和 B 将相互进行 10,000 次 n 场 比赛,n 是每场比赛的比赛数。按照标准的国际象棋规则,赢一场得 1 分,平一场得 0.5 分,输一场得 0 分。
如果一个玩家达到(n/2)+0.5 点,他就赢得了一场 n 局比赛。例如,在 12 场比赛中,如果一名球员达到 6.5 分,他就赢了。独立地重复 10,000 次,你将得到代理 A 获胜的匹配百分比和代理 B 获胜的匹配百分比。
函数 sample(n),返回 n 场比赛的结果,其中 1 表示代理 A 赢了,-1 表示代理 B 赢了,0 表示那场比赛平局。我们假设代理人 A 是更好的代理人,它赢了 20%的游戏,输了 15%的游戏给 B,抽取剩下的 65%。
以下脚本尝试了不同的比赛规模(n ),并打印了较好的玩家赢的比赛的百分比、最差的玩家赢的比赛的百分比以及和棋的百分比。
输出:
Percentage of times the better agent wins, loses and draws.
正如我们所看到的,为了让更好的代理有 99%的机会参加比赛,需要一场比赛包含大约 768 场比赛。要有 75%的胜算,只需要少于 96 场比赛。
在目前的 12 场比赛中,即使胜算很大,特工 A 也只赢了大约 51.66%的比赛。为什么?嗯,因为类似于卡尔森和卡鲁阿纳之间的决赛,拥有这种匹配技能的球员/经纪人往往会抽很多,不管是不是故意的。
为了评估卡尔森的策略,我们需要知道比赛的规模,以确保卡尔森和卡鲁阿纳之间更好的球员获胜。
在国际象棋中,一个玩家的相对技能可以通过他们的“Elo 等级”来评估。卡尔森在比赛前的 Elo 是 2835,卡鲁阿纳的 Elo 是 2832。根据他们的 Elo 得分,并根据这个网站,卡尔森有 19.2812559%的机会赢得一场比赛。卡鲁阿纳有 18.4434925%的几率赢一局,有 62.2752516%的几率平一局。
通过更新示例(n) 函数来反映这些值,并再次运行脚本,我们得到以下输出:
这将需要由大约 10,000 场比赛组成的比赛,以便给卡尔森 90%的获胜机会。因此,我相信他试图扳平比赛以进入短得多的决胜局(众所周知他是最致命的)的策略是一个好策略,尤其是因为它奏效了!
承认
标斜为发表前阅读文章。
投资者影响力网络
原文:https://towardsdatascience.com/investor-network-of-influence-f80f2a1af43f?source=collection_archive---------5-----------------------
通过风险投资生态系统的社会网络分析按影响力对投资者进行排序。
这是在 Crunchbase 数据集上应用机器学习来预测创业公司成功的更大工作的一部分。投资者影响力成为模型中最相关的预测因素。
Investor network of influence. Investor blue has influenced investor green three times and investor yellow once. Investor green has influenced investor blue one time.
为了这个任务,我挑选了可以描述公司发展的数据——我指的是有时间维度的数据——主要是资助历史和状态从运营到退出(成功)或关闭(失败)的变化。每轮融资记录告知日期、融资金额,如果是风险融资,则告知系列信函(如果是风险融资)、参与的投资者以及主要投资者(如果有)。
你可以想象,在一家公司的生活中,有如此多的社会、经济和技术变量在发挥作用,数据集超出了预测公司命运的范围。希望我们可以扭曲数据集,以传达投资者的决策:他们在投资一家公司之前确实会分析这些变量。这背后的想法是,由熟练投资者支持的公司有更多的成功机会。
如何确定哪些投资者是熟练的?这个决定再一次代表了投资者的利益。让我重申这个问题:哪些是投资者尊敬的投资者?投资者影响力是构建投资者网络并使用卡茨中心性测度来衡量网络中每个投资者影响力的相对程度的结果。
Modes of influence within a company. An investor influences all investors from posterior funding rounds (upper and middle). Within the same funding round, the lead investor if any, influences the rest of the participants (lower, lead investor in red).
该网络是一个有向图,其中节点是投资者,而连接从受影响的投资者(箭头尾部)对着有影响力的投资者(箭头头部)。
每当投资者投资同一家公司时,投资者之间就会建立起一种联系——或者如果这种联系已经存在,这种联系就会得到加强。这种联系是直接的,因为正在考虑事件的因果关系。我认为投资一家其他人投资过的公司会受到其他人的影响。当然,这不一定成立,但是联系越紧密,相关性就越强。
The top 500 with additional investor features, out of a total of 25 thousands investors. Aggregated from Q1 2014 to Q1 2017.
中心性测量被明确设计为产生一个允许指示最重要节点的排名;一般来说,它们不是用来衡量节点的影响的。
排名仅根据重要性对节点进行排序,它没有量化不同级别排名之间的重要性差异。(正确地)识别给定网络中最重要节点的特征不一定推广到其余节点;对于大多数其他网络节点来说,排名可能没有意义。
投资者活动特征时间
在计算投资者影响力时,只考虑投资者最近 3 年的行为。这样,影响不会永远积累,而是随着时间的推移而增加或减少。接下来我解释为什么我选择这个特征时间来分割投资数据。
半衰期顾名思义,是一个量减少到初始值一半所需的时间。
我将投资者活动时间定义为从投资者进行第一笔投资到最后一笔投资的时间间隔,换句话说,它变得不活跃。我们希望获得中值活动时间:大约一半投资者不活动的时间长度。
Investor activity time of all available investors since year 2001 onwards (normalized histogram).
观察剧情,半衰期约为 3 年。这意味着普通投资者在这段时间内收集并投资全部资本。
源代码
https://github.com/matiasbattocchia/crunchbase-ml
源数据 Crunchbase 每日 CSV 导出 (2017/05/15)
物联网开发:编排的游戏
原文:https://towardsdatascience.com/iot-development-a-game-of-orchestration-2ad18d048d61?source=collection_archive---------6-----------------------
想象一个场景,一个在构建传统软件方面有丰富经验的软件工程团队被赋予了处理物联网项目软件的设计和架构的任务。
你认为团队必须提升自身技能才能成功交付项目吗?
答案是肯定的。虽然发展的支柱保持不变,但物联网软件设计的错综复杂程度远远高于电子商务、游戏、社交媒体等传统软件。
一个全功能的物联网软件在其生命周期中有 4 个主要元素——嵌入式、前端、后端、数据科学。
1。嵌入式
这形成了任何物联网项目的骨架,因为它形成了设备(也称为“东西”)和互联网之间的第一层交互。以前,在大多数 M2M 应用中,来自硬件的信息是在本地主机上收集、存储和计算的,而有了物联网,信息被转移到云中。除了将数据汇集、排队和发送到互联网,开发人员还需要确保信息始终安全。
因此,该团队必须设计嵌入式软件,使设备能够在保持最高安全级别的情况下连接和传输信息。
2。后端
如果说嵌入式构成了骨架,那么后端开发则构成了任何物联网软件项目的“主干”。随着越来越多的设备/事物连接到互联网,系统和设备之间的交互水平成倍增加。当软件被设计成具有与多个微服务、多个客户端和多个设备通信的功能时,物联网项目的价值被最大化。
为了达到期望的动态水平,后端开发团队应该开发软件,以便无缝集成和内部连接成为可能。虽然 HTTP 是传统后端开发中最常用的通信协议,但团队应该训练自己使用特定于物联网的协议,如 MQTT、CoAP 等。
3。前端
虽然脊椎骨和骨骼形成了核心,但它是外观,也就是 UI/ UX,是人们购买物联网软件并从中获得价值的基础。因此,前端开发对于创建用户高度参与的软件是至关重要的。大多数行业级物联网应用将与各种现有软件集成,如 SCM、PLM、CRM、ERP 等。取而代之的是,设计前端变得非常重要,这样可以覆盖多个用例,最终用户可以获得“惊喜”因素。用户界面的各种元素,如图形、图表、表格、按钮、导航等。应考虑特定物联网应用将解决的特定业务用例来开发。虽然有些特性可能是通用的,并适用于各种行业,但大多数特性是根据特定公司的使用情况定制的。
实时响应度也是设计过程中需要考虑的一个非常重要的因素。
4。数据科学
这构成了物联网应用的大脑。分析模块需要集成到物联网系统中,以便能够处理设备传输的大量高速信息,并将其合成为有用的信息。虽然处理庞大的数据集是任何数据科学模块的核心,但在物联网中,处理需要以最小的延迟“实时”完成。
为了达到上述要求,数据科学家必须了解 Apache Spark、Flex、斯珀等工具。处理时间序列数据。
简而言之,开发一个强大的物联网软件在开始时似乎有点势不可挡,但通过清楚地了解软件的最终目标,并为团队配备所需的技能,开发之旅可以变得顺利。
在 EnrichAI,我们每天都在努力提升自己的技能,为多个行业的客户提供强大的软件服务。
请联系我们的专家团队,他们可以帮助您制作一个健壮的应用程序。
物联网+机器学习将改变世界
原文:https://towardsdatascience.com/iot-machine-learning-is-going-to-change-the-world-7c4e0cd7ac32?source=collection_archive---------4-----------------------
这将会很棒
物联网正在慢慢渗透到我们生活的方方面面。如果你还没有物联网设备,你肯定听说过它们。
从智能恒温器到智能咖啡机,物联网设备正在缓慢但稳步地获得的主流采用。此外,虚拟助手(如 Siri、Cortana 和 Alexa) 只是让这项技术更容易被采用。
但是,这些设备远非完美。目前,实现最佳功能需要大量的手动输入——内置的智能并不多。你必须设置你的闹钟,告诉你的咖啡机什么时候开始煮咖啡,手动设置你的恒温器的时间表,所有这些都是独立而精确的。
这些机器很少相互通信,你只能扮演指挥大师的角色,这是一项劳动密集型的工作。
Your devices talk to you, not each other
这提供了一个巨大的机会。创造出能够学习你的喜好的设备,使用机器智能和相互通信,以最佳的方式增强你周围的世界,这是一种幻想…或者是吗?
新范式
让我们考虑一下早上醒来的场景(像我这样的讨厌早晨的人每天都必须经历的一个重复出现的噩梦)。这通常不是一个愉快的过程。让我们看看常规物联网和智能物联网如何帮助改变这种状况:
场景 1 —没有智能的物联网:
- 上午 7:30 分:我的闹钟响了,我打了贪睡
- 上午 7:45:闹钟又响了,我醒来后冲了个澡,我的智能咖啡机在设定的时间开始冲我的早餐咖啡
- 上午 8:10:洗完澡,我很快赶完了最重要的隔夜社交媒体通知,试图在出发前不要浪费太多时间
- 上午 8:20:我喝了一杯热咖啡,跳进冰冷的车里,启动它,一边选择合适的播客,一边等待它变得足够热,可以开车了
- 上午 8:30:车里很暖和,我出发了,听着我精心挑选的播客,我的恒温器处于待机状态,以节省电能,直到我晚上回来
好的,还不错。然而,与我的精确程序的小偏差会抵消使用自动化的效果。多睡一会儿会让我喝冷咖啡,我很容易迷失在通知中,忘记时间。这些设备的有效性取决于我,但这并不总是行得通的。
但是,让我们看看智能互联设备如何让这个系统变得更好。
场景 2:智能物联网:
- 我的闹钟响了,我打了个盹
- 上午 7:45 分:闹钟再次响起,我醒来,我的智能淋浴开始运行,在我进去之前预热到完美的温度。我的智能咖啡机知道我刚开始洗澡并开始冲咖啡
- 上午 8:10:淋浴完毕。当我刷牙和穿衣服的时候,我的智能镜子会显示一个最重要的通知的高效列表(它从我的浏览模式中理解)。它甚至会根据天气预报推荐一些衣服
- 上午 8 点 15 分:我开始喝一杯非常温暖的咖啡。我的车知道这一点,并在我上车前 5 分钟开始加热
- 上午 8:20:从我上车下车的那一刻起,车里就很温暖,我听着精心挑选的播客。我的自动调温器处于待机状态以省电,直到我晚上回来
你听到了吗?有些差异是微妙的,有些是相当明显的。
首先,不管我什么时候起床,我的淋浴和咖啡都准备好了,没有机会浪费水或变冷。内容的智能管理可以防止社交媒体等干扰让我迟到,我的车在我需要的时候很好,很温暖,而不是在之前或之后。以前连续的任务现在可以并行化。
这增加了系统的健壮性,可以防止人为错误。由于时间安排灵活,我的早晨再也不会被我自己的错误破坏了。相互通信的智能设备:
- 被智能地优化以完成他们特定的 T21 任务
- 通过互通帮助优化整个流程
我觉得这很酷。
最好的情况
晨间活动并不是唯一变好的事情。事实上,单人优化只是冰山一角——小组设置是下一步。
想象一下,一家餐厅拥有灵活的照明和音乐选择,经过优化以适应客户的偏好,公共交通也是如此,城市电网通过与自动驾驶汽车对话来优化交通流量。这个清单还在继续。
这项技术将减少我们花在交通上的时间,帮助我们获得更好的睡眠,并最终帮助拯救生命,所有这些都无需任何人工努力。我们正在建设一个更智能、更安全的世界。
这就是智能互联机器的力量。一个不受人为错误影响的世界。
然而,没有什么是完美的。
风险
如果我说只有好的一面,那我是在撒谎。
网络安全是一个迷人而广阔的研究领域,但它远非完美。任何连接到互联网的东西在某种程度上都是易受攻击的。以下是全智能物联网世界可能出现的三大问题。
- 数据隐私:随着社交媒体带来的个人数据爆炸式增长,一个越来越热门的话题,防止个人数据滥用的隐私法变得更加重要。然而,物联网数据可能会为个人数据提供全新的粒度。社交媒体只能到此为止;总的来说,这些设备比你自己更了解你。必须采取措施从这些数据中分离出任何唯一的个人标识符,因为它肯定会被用于身份盗窃、欺诈和其他恶意攻击。
- 物理攻击:虽然黑客完全控制你的 Roomba 最糟糕的结果可能是踢你的脚趾,但世界越是一体化,我们就越容易受到更有创意的物理攻击。例如:你的车可能会被黑客攻击,让你任由控制它的人摆布。随着越来越强大的网络物理系统被整合,我们就越需要小心。从某种意义上说,卫星、供水服务和发电厂将很快变得比以往任何时候都更加脆弱。
- 电网崩溃:这些设备都需要一样东西——电力。在电源故障的情况下,必须有适当的安全措施来保证这些设备的协调继续进行。从智能交通网络获得指令的公共交通和自动驾驶汽车必须能够在没有智能交通网络的情况下导航。网络必须构建得尽可能健壮,以抵御其他节点的崩溃,甚至是整个网格的崩溃。这种情况不太可能发生,而且对于这个例子来说过于简单了,但是考虑系统范围内故障的故障保护绝对是很重要的。
是的,这些理由看起来很可怕。这些问题需要仔细规划和实施。一个完全连接的世界不会在一夜之间出现,我们将在问题出现时发现并纠正它们。
Don’t be scared
结论
有风险吗?当然可以。与任何新技术一样,我们承诺接受主流采用带来的潜在利益和风险。
我乐观地认为,一个智能、互联的世界的好处将远远大于坏处。迟早,我们可能会看到一个虚幻的世界,不仅我们的设备,而且我们周围的实际物理世界都得到优化,为我们带来更安全、更高效的体验。因此,我们可以花时间追求我们真正认为重要的事情,而不是花时间等待淋浴变暖,或者在早上忘记手机。
感谢阅读!
脚注: 回到 2017 年末的 crypto 热潮中,我最喜欢的项目是 IOTA 。简单地说,他们的愿景是,机器最终将相互通信,并将需要一种通用的“货币”进行交换,以便相互借用资源。我一直认为这是一个革命性的概念,并鼓励你去看看。至少,你可能会得到一个鼓舞人心的更智能的世界的图片,有一天它可能会成为现实。
物联网变得简单:ESP-MicroPython-MQTT-thing speak
原文:https://towardsdatascience.com/iot-made-easy-esp-micropython-mqtt-thingspeak-ce05eea27814?source=collection_archive---------3-----------------------
使用 MQTT 协议,我们将从传感器获取捕获的数据,并将它们记录到物联网服务 ThingSpeak.com 和移动应用 Thingsview。
1.介绍
在我的上一篇文章MicroPython on ESP using Jupyter中,我们学习了如何在 ESP 设备上安装和运行 MicroPython。使用 Jupyter Notebook 作为我们的开发环境,我们还学习了如何使用多种通信协议和方法从传感器读取数据(温度、湿度和亮度),例如:模拟、数字、1 线和 I2C,后者用于在有机发光二极管显示器上显示我们捕获的数据。
现在,在这篇文章中,使用 MQTT 协议,我们将获得所有捕获的数据,将它们发送到物联网服务,【ThingSpeak.com】和移动应用, Thingsview ,在那里可以记录和播放它们。
以下是对我们的项目进行重新升级的概述:
2.硬件
将要使用的硬件基本上与之前的项目相同:使用 Jupyter 的 ESP 上的 Micropython。请参考它的详细硬件解释(例外是伺服,这将不会在这个项目中使用)。
上面你可以看到完整的硬件。如图所示连接设备。
3.Micropython,REPL 和 Jupyter 笔记本
此时,您应该在您的 ESP 设备上加载了一个 Micropython 解释器,因此可以使用任何可用的 ide 对其进行编程,比如:
- REPL /Ampy
- Jupyter 笔记本(*)
- 希腊字母表中第十二个字母
- ESPCut(仅适用于 Windows)
- …等等
在我的文章Micropython on ESP Using Jupyter中,我详细介绍了如何下载和安装 Micropython 解释器、ESPTool 来管理 ESP 设备,以及如何使用 Jupyter Notebook 作为开发环境。您可以随意使用更舒适的产品。
(*)我一般都是在 Jupyter Notebook 上做所有开发,一旦得到最终代码,就把它们复制到 Geany,保存为 python 脚本。使用 Ampy 将脚本上传到 ESP 上。我发现这种方法非常容易创建更复杂和专业的项目。
4.传感器
让我们安装库,定义 GPIOs,分别为所有传感器创建对象和函数:
A. DHT(温度和湿度)
安装 DHT 库并创建一个对象:
from dht import DHT22
from machine import Pin
dht22 = DHT22(Pin(12))
创建一个函数来读取 DHT 传感器:
def readDht():
dht22.measure()
return dht22.temperature(), dht22.humidity()
测试 DHT 功能:
print (readDht())
结果应该是如下所示的元组:
(17.7, 43.4)
B. DS18B20(外部温度)
安装库并创建一个对象:
import onewire, ds18x20
import time# Define the pin to be used with 1-wire bus ==> pin 2 (D4)
dat = Pin(2)# create the onewire object
ds = ds18x20.DS18X20(onewire.OneWire(dat))
扫描总线上的设备
sensors = ds.scan()
print('found devices:', sensors)
打印结果并不重要,我们需要的是第一个检测到的传感器:传感器[0] 。现在,我们可以构建一个函数来读取传感器数据:
def readDs():
ds.convert_temp()
time.sleep_ms(750)
return ds.read_temp(sensors[0])
使用创建的函数测试传感器总是很重要的
print(readDs())
如果你得到一个温度值,你的代码是正确的:
17.5
LDR(光度)
LDR 将使用我们的 ESP 的模拟引脚(在 ESP8266 的情况下只有一个,在 ESP32 中有几个)。
与之前相同:
# import library
from machine import ADC# Define object
adc = ADC(0)
一个简单的函数: adc.read() 可以用来读取 adc 值。但请记住,内部 ADC 会将 0 到 3.3V 之间的电压转换为相应的数字值,范围从 0 到 1023。一旦我们对“光度”感兴趣,我们就会认为最大光是传感器捕捉到的最大值(在我的例子中是 900),最小光是 40。有了这些值,我们就可以将亮度值从[40 到 900]映射到[0 到 100%]。为此,我们将创建一个新函数:
def readLdr():
lumPerct = (adc.read()-40)*(10/86)
return round(lumPerct)
你应该使用 print (readLDR()) 来测试这个函数。结果应该是 0 到 100 之间的整数。
D .按钮(数字输入)
这里我们使用一个按钮作为“数字传感器”,但它可能是一个执行器的“回声”(例如,一个开/关的泵)。
# define pin 13 as an input and activate an internal Pull-up resistor:
button = Pin(13, Pin.IN, Pin.PULL_UP)# Function to read button state:
def readBut():
return button.value()
您可以使用功能 print(readBut()) 测试按钮。如果不按,结果应该是“1”。按下按钮,结果应该是“0”。
5.捕获并在本地显示所有传感器数据
现在我们已经为每个传感器创建了一个函数,让我们创建另一个函数,负责同时读取所有传感器:
def colectData():
temp, hum, = readDht()
extTemp = readDs()
lum = readLdr()
butSts = readBut()
return temp, hum, extTemp, lum, butSts
现在,使用:
print(colectData())
将产生一个元组,其中包括从传感器捕获的所有数据:
(17.4, 45.2, 17.3125, 103, 1)
我们还可以选择在本地显示器上显示这些数据:
# import library and create object i2c
from machine import I2C
i2c = I2C(scl=Pin(5), sda=Pin(4))# import library and create object oled
import ssd1306
i2c = I2C(scl=Pin(5), sda=Pin(4))
oled = ssd1306.SSD1306_I2C(128, 64, i2c, 0x3c)# create a function:
def displayData(temp, hum, extTemp, lum, butSts):
oled.fill(0)
oled.text("Temp: " + str(temp) + "oC", 0, 4)
oled.text("Hum: " + str(hum) + "%",0, 16)
oled.text("ExtTemp: " + str(extTemp) + "oC", 0, 29)
oled.text("Lumin: " + str(lum) + "%", 0, 43)
oled.text("Button: " + str(butSts), 0, 57
oled.show()# display data using the function
displayData(temp, hum, extTemp, lum, butSts)
作为一个选项,我们可以使用 LED 在开始读取传感器时打开,在数据显示后关闭。这将有助于确认当我们将 ESP 与 PC 断开连接并自动运行时,该程序正在运行。
所以,“主要功能是:
def main():
led.on()
temp, hum, extTemp, lum, butSts = colectData()
displayData(temp, hum, extTemp, lum, butSts)
led.off()
因此,执行 main(),我们将获得显示在有机发光二极管上的传感器数据,如最后一张图片所示。
6.在 ESP 启动时运行本地站代码
如果您已经使用 Jupyter Notebook 创建和测试了这些功能,那么现在是时候让我们的 ESP 自动执行到目前为止在单个文件脚本上开发的所有功能了。
让我们打开任何文本编辑器并在上面粘贴所有代码(我喜欢使用 Geany):
from machine import Pin
import time# LED
led = Pin(0, Pin.OUT)# DHT
from dht import DHT22
dht22 = DHT22(Pin(12))
def readDht():
dht22.measure()
return dht22.temperature(), dht22.humidity()# DS18B20
import onewire, ds18x20
dat = Pin(2)
ds = ds18x20.DS18X20(onewire.OneWire(dat))
sensors = ds.scan()
def readDs():
ds.convert_temp()
time.sleep_ms(750)
return round(ds.read_temp(sensors[0]), 1)# LDR
from machine import ADC
adc = ADC(0)
def readLdr():
lumPerct = (adc.read()-40)*(10/86)
return round(lumPerct)# Push Button
button = Pin(13, Pin.IN, Pin.PULL_UP)
def readBut():
return button.value()# Read all data:
def colectData():
temp, hum, = readDht()
extTemp = readDs()
lum = readLdr()
butSts = readBut()
return temp, hum, extTemp, lum, butSts# I2C / OLED
from machine import I2C
import ssd1306
i2c = I2C(scl=Pin(5), sda=Pin(4))
oled = ssd1306.SSD1306_I2C(128, 64, i2c, 0x3c)
def displayData(temp, hum, extTemp, lum, butSts):
oled.fill(0)
oled.text("Temp: " + str(temp) + "oC", 0, 4)
oled.text("Hum: " + str(hum) + "%",0, 16)
oled.text("ExtTemp: " + str(extTemp) + "oC", 0, 29)
oled.text("Lumin: " + str(lum) + "%", 0, 43)
oled.text("Button: " + str(butSts), 0, 57)
oled.show()# Main function
def main():
led.on()
temp, hum, extTemp, lum, butSts = colectData()
displayData(temp, hum, extTemp, lum, butSts)
led.off()'''------ run main function --------'''
main()
将其保存,例如保存为 localData.py.
要在您的终端上直接运行这段代码,您需要 Ampy。
首先,在终端上,让我们通知 Ampy 我们的串行端口:
export AMPY_PORT=/dev/tty.SLAB_USBtoUART
现在,我们可以看到 ESP 根目录中的文件:
ampy ls
作为响应,我们将得到 boot.py ,这是将在系统中运行的第一个文件。
现在,让我们使用 Ampy 将 python 脚本 LocalData.py 加载为/main.py,这样我们的脚本将在启动后立即运行:
ampy put localData.py /main.py
如果我们现在使用命令 amp ls ,您将在 ESP 中看到两个文件: boot.py 和 main.py
重置 ESP 将使程序 localData.py(上传为/main.py)自动运行,并在显示屏上显示传感器数据。
上面的终端打印屏幕显示了我们所做的事情。
使用上面的代码,显示将只显示一次,但是我们可以在 main() 函数上定义一个循环,它将在每个定义的时间间隔(PUB_TIME_SEC)显示数据,例如,直到我们按下按钮:
# loop getting data until button is pressed
while button.value():
led.on()
temp, hum, extTemp, lum, butSts = colectData()
displayData(temp, hum, extTemp, lum, butSts)
led.off()
time.sleep(PUB_TIME_SEC)
变量 PUB_TIME_SEC 必须在你想要你的样本的时候声明。
为了增强我们的代码,最好通知我们将退出循环,因为我们将定义 2 个新的通用函数,一个用于清除显示,另一个用于使 LED 闪烁一定次数。
# Clear display :
def displayClear():
oled.fill(0)
oled.show()# create a blink function
def blinkLed(num):
for i in range(0, num):
led.on()
sleep(0.5)
led.off()
sleep(0.5)
所以,我们现在可以,重写我们的 main()函数:
while button.value():
led.on()
temp, hum, extTemp, lum, butSts = colectData()
displayData(temp, hum, extTemp, lum, butSts)
led.off()
time.sleep(PUB_TIME_SEC)
blinkLed(3)
displayClear()
最终代码可以从我的 GitHub: localData.py 下载,也可以从用于开发完整代码的 Jupyter 笔记本:Jupyter Local Data development . ipynb下载。
7:将 ESP 连接到本地 WiFi
网络模块用于配置 WiFi 连接。有两个 WiFi 接口,一个用于工作站(当 ESP8266 连接到路由器时),一个用于接入点(供其他设备连接到 ESP8266)。在这里,我们的 ESP 将通过路由器连接到本地网络。让我们调用库并定义我们的网络凭证:
import network
WiFi_SSID = "YOUR SSID"
WiFi_PASS = "YOUR PASSWORD"
以下功能可用于将 ESP 连接到您的本地网络:
def do_connect():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect(WiFi_SSID, WiFi_SSID)
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
运行该函数,您可以获得 IP 地址的结果:
do_connect()
结果将是:
网络配置:(10.0.1.2、255.255.255.0、10.0.1.1、10.0.1.1)
在我的例子中,10.0.1.2 是 ESP 的 IP 地址。
8.说话的东西
至此,我们已经学会了如何从所有传感器获取数据,并将其显示在我们的有机发光二极管上。现在,是时候看看如何将这些数据发送到物联网平台ThingSpeak.com了。
"ThingSpeak 是一款开源 物联网 (IoT)应用,使用 REST 和 MQTT APIs 存储和检索物联网数据。ThingSpeak 支持创建传感器日志应用程序、位置跟踪应用程序和带有状态更新的社交网络”
我们开始吧!
首先,你必须在 ThinkSpeak.com 有一个账户。接下来,按照说明创建一个通道,并记下您的通道 ID 和写入 API 密钥。
上面你可以看到我们的渠道将使用的 5 个领域。
9.MQTT 协议和 ThingSpeak 连接
MQTT 是一种发布/订阅架构,主要用于通过无线网络连接带宽和功率受限的设备。它是一个简单的轻量级协议,运行在 TCP/IP 套接字或 web 套接字上。WebSockets 上的 MQTT 可以用 SSL 保护。发布/订阅体系结构使得消息能够被推送到客户端设备,而无需设备持续轮询服务器。
MQTT 代理是通信的中心点,它负责在发送者和合法接收者之间分发所有消息。客户机是连接到代理的任何设备,可以发布或订阅主题以访问信息。主题包含代理的路由信息。每个想要发送消息的客户端将消息发布到某个主题,每个想要接收消息的客户端订阅某个主题。代理将带有匹配主题的所有消息传递给适当的客户端。
ThingSpeak 在 URLmqtt.thingspeak.com和端口 1883 有一个 MQTT 代理。ThingSpeak 代理支持 MQTT 发布和 MQTT 订阅。
在我们的例子中,我们将使用: MQTT Publish。
上图描述了主题结构。发布需要写入 API 密钥。代理用 CONNACK 确认正确的连接请求。
Micropython 的内置库中支持 MQTT 协议。该协议可用于通过 WIFI 将数据从您的 ESP8266 发送到免费的云数据库。
我们将使用 umqtt.simple 库:
from umqtt.simple import MQTTClient
知道了我们的服务器 ID,就有可能创建我们的 MQTT 客户机对象:
SERVER = "mqtt.thingspeak.com"
client = MQTTClient("umqtt_client", SERVER)
现在,准备好你的 ThingSpeak 证书:
CHANNEL_ID = "YOUR CHANNEL ID"
WRITE_API_KEY = "YOUR KEY HERE"
让我们创建我们的 MQTT“主题”:
topic = "channels/" + CHANNEL_ID + "/publish/" + WRITE_API_KEY
使用创建的函数获取要发送给 ThingSpeak 物联网服务的数据,并将其响应与特定数据变量相关联:
temp, hum, extTemp, lum, butSts = colectData()
更新这些变量后,我们可以创建我们的“MQTT 有效负载”:
payload "field1="+str(temp)+"&field2="+str(hum)+"&field3="+str(extTemp)+"&field4="+str(lum)+"&field5="+str(butSts)
就是这样!我们已经准备好向 ThinsSpeak 发送数据,只需使用下面的 3 行代码:
client.connect()
client.publish(topic, payload)
client.disconnect()
现在,如果您进入您的渠道页面(如下图所示),您会看到 5 个字段中的每一个都有与您的传感器相关的数据。
10.传感器数据记录器
现在,我们知道只需几行代码就可以将数据上传到物联网服务,让我们创建一个循环函数,以固定的时间间隔自动完成这项工作(类似于我们对“本地数据”所做的工作)。
使用之前声明的相同变量(PUB_TIME_SEC ),可以创建一个简单的 main()函数来连续捕获数据,并将它们记录在我们的通道中:
while True:
temp, hum, extTemp, lum, butSts = colectData()
payload = "field1="+str(temp)+"&field2="+str(hum)+"&field3="+str(extTemp)+"&field4="+str(lum)+"&field5="+str(butSts)
client.connect()
client.publish(topic, payload)
client.disconnect()
time.sleep(PUB_TIME_SEC)
请注意,只有“有效负载”必须更新,因为“主题”与我们的渠道凭证相关,不会改变。
寻找你的 ThingSpeak 频道页面,你会发现数据会不断地加载到每个字段。
盖上 LDR,把手放在温度/嗡嗡声传感器上,按下按钮,等等。并查看通道如何自动“记录”这些数据以供将来分析。
通常,对于数据记录,我们应该尽量少用电,因此,我们不会使用 LED 或本地显示器。此外,对于 ESP 设备来说,让它们进入“深度睡眠”是很常见的,在这种情况下,微处理器将保持其最低能量状态,直到捕捉数据并将其发送到物联网平台的时间。
但是,一旦这里的想法是学习,让我们也包括显示器和 LED 像我们以前做的。这样,我们的“日志”功能将是:
while button.value():
led.on()
temp, hum, extTemp, lum, butSts = colectData()
displayData(temp, hum, extTemp, lum, butSts)
led.off()
payload = "field1="+str(temp)+"&field2="+str(hum)+"&field3="+str(extTemp)+"&field4="+str(lum)+"&field5="+str(butSts)
client.connect()
client.publish(topic, payload)
client.disconnect()
time.sleep(PUB_TIME_SEC)blinkLed(3)
displayClear()
完整的 microPython 脚本可以在这里找到:Data loggers _ ext . py和用于开发的 Jupyter 笔记本也可以在这里找到:物联网 ThingSpeak 数据记录器 EXT.ipynb 。
要在 ESP 上上传脚本,请在您的终端上使用以下命令:
ampy put dataLoggerTS.py /main.py
并按下 ESP 复位按钮。
您将让电潜泵捕捉数据并记录在 ThingSpeak.com 上,直到底部被按住(等待 LED 闪烁 3 次,有机发光二极管关闭)。
11.ThingView 应用程序
记录的数据可以直接在 ThingSpeak.com 网站上查看,也可以通过应用程序查看,例如 ThingsView!
ThingView 是由 CINETICA 开发的一款应用程序,它使你能够以一种简单的方式可视化你的 ThingSpeak 频道,只需输入频道 ID,你就可以开始了。
对于公共频道,应用程序将尊重您的 windows 设置:颜色,时间刻度,图表类型和结果的数量。当前版本支持折线图和柱形图,样条图显示为折线图。
对于私有通道,数据将使用默认设置显示,因为无法仅使用 API 键读取私有窗口设置。
ThingView 应用可以为安卓和 IPHONE 下载。
12:结论
一如既往,我希望这个项目可以帮助其他人找到进入令人兴奋的电子世界的方法!
详情和最终代码请访问我的 GitHub 仓库: IoT_TS_MQTT
更多项目,请访问我的博客:MJRoBot.org
来自世界南部的 Saludos!
我的下一篇文章再见!
谢谢你,
马塞洛
鸢尾属分类|DeepCognition| Azure ML studio
原文:https://towardsdatascience.com/iris-genus-classification-deepcognition-azure-ml-studio-4b930f54435a?source=collection_archive---------6-----------------------
source : Google
界:植物界 分支 : 被子植物目:天冬目科:鸢尾科亚科:环烯醚萜族族:鸢尾科属: 鸢尾属
鸢尾 是开花植物的属260-300 个种的一种,花艳丽。它的名字来自希腊语中的一词,意为彩虹,也是希腊彩虹女神 Iris 的名字。
在本文中,我们将讨论如何使用 Deepcognition.ai 和微软 Azure Machine Learning Studio 将鸢尾属分为 3 类( Versicolor 、 Sestosa 、 Viginica )。[来源:谷歌]
使用 Deepcognition.ai
创建新项目 IRIS
进入项目,点击“ + ”按钮,给你的项目命名,然后继续。
导入数据
Data Tab
虹膜数据集在 Deepcognition 上公开。从数据集选项卡中选择' iris-public '数据集。这个数据集有 150 行。列的行显示每一列的名称及其下的值。要将每列指定为输入/输出,请分别选择 InputPort/OutputPort。OutputPort 指定已训练模型的输出。
模型的架构
您可以通过在主板上拖放来使用这些层。核心层中存在致密层。
所用各类型层的描述:
Input_1:指定输入数据及其尺寸。
Dense_3:密集连接层或隐藏层指定激活单元的数量。您可以通过单击该层来选择激活功能。这里我选择了‘96’隐藏单元和 relu 作为激活函数。
脱落:脱落层用于防止模型过拟合。它随机切换一些隐藏单元开/关,迫使神经网络找到不同的输出路径,从而防止过拟合。
Dense_21:另一个隐藏层,有 32 个隐藏单元。
Dense_26:最终隐藏层,其隐藏单元数等于要传递给输出层的类别数。
Output_3: 模型的最终输出。
您可以尝试不同的模型架构,找出最适合的。
超参数:
该选项卡用于为我们的模型选择超参数。我们有不同的超参数,例如:
- 损失函数(类别交叉熵)
- 学习率(最重要)(0.001)
- 优化器
- 批量大小和时期数..(32,20)
- 不同优化器的不同参数,例如 RMSprop 的ε和ρ。
只需调整其中任何一个并开始训练,以检查哪些超参数效果最好。该选项卡非常有用,因为它节省了大量处理超参数的时间。尝试不同的参数!
训练
difference after using ‘load previous weights’ 84% to 93.75% accuracy
要开始训练,按下“开始训练按钮,您的模型将开始使用提供的数据进行训练。我们可以看到,我们的模型获得了 93.75% 的验证准确率。如图所示,我们的最佳精确度是在第 15 纪元。
损失曲线用于确定我们的损失是否随着时间的推移而减少。如果损失没有减少,你可能需要降低学习率(在上面的超参数中讨论)。
准确度曲线显示当前准确度(图像中禁用)、验证准确度和平均准确度。尝试不同的超参数以获得最佳精度。
运行名称用于为每个已训练的模型命名,以保存其权重和结构,从而可以选择最佳模型,也可以用于恢复模型。
加载之前的重量非常有用。从以前的模型加载重量后,精确度从 84%更改为 93.75% 。
结果
Loss and accuracy for each time when model was trained.
由此,您可以看到哪个模型执行得最好,并可以开始改进它。您可以从模型部分恢复任何保存的模型的架构和权重。
部署模型
这是您可以为真实世界部署模型的地方。单击“部署”将生成一个 url,即一个 webApp!您可以用它来传递用户数据以获得如下所示的输出。
Generated App url! and web App
形成推论
for the given values, it is a iris virginica plant.
在形式推理部分,您可以传递萼片宽度、萼片高度、花瓣宽度和花瓣高度的任何有效值。点击“开始推断”将生成它属于特定类别的概率。
下载你的模型
要下载您的模型,请选择模型名称(训练跑步),然后单击下载。
数据集推断
数据集推断用于查看我们的训练数据的模型输出。图像中只有 2 行可见(其余部分被裁剪)。
哟!我们学会了创建和部署我们的 IRIS webAPP,而无需编写任何代码!
让我们看看使用 Azure ML Studio 进行虹膜分类
创建实验
点击空白实验创建一个新实验,将出现一个对话框,给出实验的名称。
从实验选项卡打开您的实验。
第一步是导入虹膜数据。我们将让 Azure 从网站下载数据。在搜索栏中搜索“导入数据”,然后在工作区中拖动该层。现在点击它并传递数据源 url。
http://archive . ics . UCI . edu/ml/机器学习数据库/iris/iris.data
模型架构
类似于拖动导入数据层,可以在搜索框中找到所有层。要在两层之间建立连接,请将一层的连接点拖向另一层。
拆分数据:该层用于将数据拆分为测试集和训练集,其比率作为参数传递(见右窗格)。
这里我选择了多类逻辑回归模型来对数据进行分类。
训练模型:这一层负责启动模型的训练。要开始训练模型,点击运行按钮。在您的模型完成训练后,您最终可以可视化结果。
Evaluate model layer and its results
要可视化结果,右键单击评估层并选择评估结果->可视化数据,您将看到类似右图的内容。
甚至混淆矩阵也是为我们的数据自动创建的。
在对结果进行评估后,我们的模型最终获得了 93.3%的准确率。几乎和我们用 deepcognition.ai 得到的一样
所以耶!您最终学会了如何使用 Deepcognition.ai 和 Microsoft Azure ML Studio 找到给定的鸢尾植物,而无需编写任何代码。
感谢阅读。
机器学习快乐!
非理性人工智能
原文:https://towardsdatascience.com/irrational-ai-6f0b6d25af8f?source=collection_archive---------10-----------------------
机器是理性的,人类是非理性的,对吧?不对。人类和机器都是非理性的,原因惊人地相似。在这篇博客中,我会告诉你为什么,以及为什么它不一定是一件坏事。
首先,我说的理性是什么意思?
基于数据的逻辑决策是理性决策。理想情况下,为了做出最合理的决定,你需要一个完美的数据集。一个完整、准确和公正的数据集。您希望逻辑地处理这些数据,用每条新数据更新每个结果的概率。
那么,为什么人类会有偏见呢?
我们人类的大脑进化了几千年,来吃饭、睡觉、繁殖和保护自己免受威胁,偶尔需要使用一些更高级的推理来从别人那里偷食物并保护自己的食物不被抢走。社会、语言和复杂的发明在我们的进化中是最近的事情,期望我们的大脑如此快速地适应抽象或高度数学化的思想来做出理性的决定是不公平的。
做出合理的决策需要准确和完整的数据集,以及纯粹的数学决策。我们的大脑无法做到这一点。为了利用他们可用的处理能力,并且在我们的行动所要求的时间限制内,我们已经进化到进行大量的近似——这就是我们发现偏差的地方。
即使我们有一个完美的数据集,人类也很难做出理性的决定。想象一下,你进行了一次广谱血液检测,你的医生告诉你,你的一种非常罕见的疾病检测呈阳性,这种疾病的发病率为 1/1000。测试本身有 97%的准确率。那么,你得这种病的可能性有多大?
许多人会立即跳到 97%的测试准确率,并认为这是 97%的可能性。事实上,这种可能性只有 3%。原因是它实际上只影响 1/1000 人,如果你测试 1000 人,你会期望 3%的人得到假阳性,因为测试是 3%不准确的。因此,我们将有 30 个测试呈阳性,但实际上只有一个人患有这种疾病,因此,在一次测试后,你患这种疾病的可能性大约为 3%。
Eliezer Yudkowski 举了一个很好的例子来说明时间限制是如何发挥作用的——他谈到了一只老虎。当我们看到老虎时,我们不会想‘嗯,那个动物是黄色的,有条纹的。其他黄色和条纹的生物在过去被描述为老虎,我被告知老虎有很高的概率“啊啊啊啊啊啊啊啊”。相反,我们看到黄色的闪光,粗略的形状粗略的形状,我们的大脑完成了模式,我们跑了。
正如埃利泽所说,偏见不是我们在纯粹理性的头脑上加上的东西,它是我们整个决策过程。
那么,为什么 AI 是非理性的?
理论上,人工智能具有理性决策的潜力。在人脑有我们可能永远无法克服的硬件限制的地方,给计算机增加更多的处理能力是相对容易的。一旦我们发现了正确的算法来做出决定(我并不是说人类擅长做出公平公正的算法,但科学方法应该会给我们带来一些希望),我们就可以确信自动化系统将永远遵循这些指令和规则,每次都不会失败。
然而实际上,人工智能不太可能是理性的。理性所需要的完整、准确和公正的数据集?它不存在。巨大的处理能力,可以根据该数据集或我们能想到的最佳数据集进行接收和决策?它是昂贵的。我们实现任何接近理性人工智能或自动化系统的唯一方式是通过蛮力,而蛮力将是缓慢且非常昂贵的。
企业首先受利润驱动。如果人工智能或自动化正在被考虑取代历史上由人工操作的流程,那么采用该技术的商业案例将从根本上关乎它如何提高利润。即使是决心做出理性和无偏见的人工智能的善意的人,也必须说服他们的同行,整理出一个看起来很可能类似于“消费者在道德产品上的支出正在增加,通过确保我们的自动化促进平等(说真的,阅读弗吉尼亚·尤班克斯的《自动化不平等》)我们可以增加销售和利润”的商业案例。如果我发现世界上有些企业愿意违法,我不会感到惊讶,因为他们的违法行为使他们获得的利润超过了罚款。无论哪种方式,对盈利能力的争论只会增加一个理性的或无偏见的产品成功的机会。
如果我们开始超越更标准的自动化,走向人工通用智能,我们知道我们面前的项目将是富有挑战性和昂贵的。一个经常被提出的通往 AGI 的路径依赖于“加速回报法则”你从建立一个狭窄的智能开始。在某项特定任务中,可能比人做得更好或至少更划算的东西。使用它带来的力量——无论是狭义人工智能能够进行的推理类型,还是你可以从中获得的资源,来构建第二个更高级的人工智能。冲洗和重复,直到你有自己的 AGI。这里的问题是,我们将被鼓励在这些阶段做出非理性的人工智能。由于我们在早期阶段受到资源、数据和智能的限制,开发人员将需要走捷径,找到有时优雅、有时不那么优雅的概括问题的方法,以进入下一次迭代。如果我们看到加速回报定律导致人工智能快速而艰难的起飞,那么当我们意识到它不再受我们控制,不是一个真正理性的存在时,可能为时已晚。
一个简单的解决方案是让企业放慢脚步,但这个问题类似于囚徒困境,特别是如果我们开始考虑人工智能的话。对社会最有益的结果是开发安全的、价值一致的人工智能。我可能可以控制我正在开发的系统,但我对我的同行或竞争对手正在做的事情几乎没有控制权。如果我不能信任他们的行为,我可能会放松我的安全标准,决定即使我像我的竞争对手一样偷工减料,我相信我更值得信赖,可能会偷工减料。否则,我可能会采取稍微更具破坏性的方法,假设一个无法控制的 AGI 将导致人类的末日,如果有人比我更近,他们比我更强大,如果我不能打败他们,我也可能加入他们。
我们真的想要一个真正理性的人工智能吗?
如果我们主要着眼于人工通用智能(AGI)和人工超级智能(ASI),我们会听到围绕价值调整、控制和伦理的对话。所有这些都是远离理性和偏向的一步,这是一件好事。
第一,价值对齐。这里我们的意思是明确地将人工智能的目标和价值观与人类的目标和价值观相一致。我们今天可能无法准确知道这些价值是什么,或者它们是否会在今后的任何时间内保持不变,但它确实积极地推动了对人类所重视的东西的偏见,而不是地球上其他生物所重视的东西,或者对人工智能本身更直接有益的东西。这并不意味着人工智能会忽视宇宙中的所有其他生命,因为人类可能会珍视其他生命(无论我们表现得多么糟糕!).
伦理学也很有趣。我不认为人工智能能够以某种方式发现任何普遍的“先验”伦理。相反,我认为道德是人类创造并赋予其意义的东西,它是一群人对与错的平均标准。由于这个原因,随着我们的需求和优先事项的改变,人们认为道德的东西在整个人类历史中不断发展。
那么,为什么要自动化呢?
仅仅因为这个系统不完美,并不意味着它没有用。让我们不要忘记人类也是有偏见的。如果我们要建立一个比人类快 10 倍的系统,并且减少 95%的偏差输出,那么我们就减少了世界上偏差的数量和比例——我们只需要在这里做一个假设,我们可以盈利;否则我们不可能卖出很多。
同样重要的是,我们要摆脱责备他人的欲望。如果我们今天能够推出一款与人类司机一样安全的无人驾驶汽车,如果在转换的第一天有 3000 人死亡,公众仍会强烈抗议。即使这个数字是 2000 人,即使第一天就有 100 人死亡,人们的反应无疑也会是负面的。事实上,人类每天在道路上造成 3000 多人死亡。如果我们的动机确实是减少错误输出和限制死亡,我们应该自动化。
我们不要忘记不到理性推理所能带来的效用。创造有用的输出,而不是完美的输出,但为时已晚。我们必须有意识地实现自动化,找到我们既能减少有偏差的产出又能提高盈利能力的实例,并在我们被完全推向速度、远离公平而违背自己最佳判断的情况下保持谨慎。
一家中国餐馆的名字能预示它的质量吗?
原文:https://towardsdatascience.com/is-a-chinese-restaurants-name-predictive-of-its-quality-594d9f0cc0f2?source=collection_archive---------13-----------------------
我经常路过一家叫华龙的中国餐馆。这就是华龙的样子。
住在纽约,我们都知道这家餐厅。过于复杂的菜单。看起来像是在 70 年代拍摄的普通食物照片。但对我来说,我可以通过这个名字来感受一下。“华龙”就是听起来不好。因此,自然而然地,我决定建立一个快速模型,看看一家中国餐馆的名字能否预测它的质量。
我用 Yelp 的 API 抓取了纽约 1000 家中餐馆的数据(一些报道称纽约总共有 ~6000 家中餐馆)。为了简单起见,我们来定义一个“好”的餐馆,它有超过 10 个评论和至少 4 星的评级。使用这个定义,我们数据集中大约 40%的餐馆是“好”的。
用的最多的词是什么?
纽约中餐馆名称中最常见的单词是:
餐厅:194
中餐:145
厨房:100
新:71
花园:69
在我们的数据集中,近 20%的中国餐馆直接在标题中包含“餐馆”一词。如果说中国人有什么不同的话,那就是他们说到点子上了。其他一些熟悉的词也在这里,像“花园”和“黄金”。
让我们也来看看最热门的两个单词短语(如果你喜欢,也可以称之为双字母组合):
中餐厅:79
中厨房:17
港:16
xi 安:13
名吃:13
这个数据稍微稀疏一点,而且也在挑选知名品牌,比如西安名吃。为了简单起见,我们不会在模型中包含二元模型。
训练模型
我们现在有了训练预测模型所需的组件:目标(如果一家餐馆是“好”的,即二进制分类)和特征(一个单词在餐馆名称中的出现)。作为最后一个转换步骤,我们将对名称应用一个 tf-idf 转换。这增加了一点权重,应该有助于提高性能,特别是通过降低总出现次数很多的单词的等级。最后,我们将在数据上拟合一个支持向量机(SVM) ,一个文本分类问题的标准模型。
Python 的sklearn
库中方便的Pipeline
类使这变得非常简单:
X_train, X_test, y_train, y_test = train_test_split(data.name, data.is_good, test_size=0.2, random_state=42) clf = Pipeline([ (‘vect’, CountVectorizer()), (‘tfidf’, TfidfTransformer()), (‘clf’, SGDClassifier(random_state=42)) ]) clf.fit(X_train, y_train)
评估预测模型有效性的常用指标是 AUC 得分。该模型的 AUC 值为 0.60,这并不惊人,但也不可怕。这意味着,如果模型按照从最差到最差的顺序排列所有餐馆,那么一家真正好的餐馆往往会排在一家真正差的餐馆之前。
有哪些具体的词具有预测性?
像 SVM 这样的线性模型的好处在于它们是可以解释的。我们可以检查模型应用于每个单词的权重,以感受每个单词的“预测”程度。
“好”中餐馆最具预测性的词汇(过滤掉出现过的词汇<10 times) are:
美食
饺子
孔
亚洲
炒锅
最消极的预测词是:
g olden
wah
餐厅
北京
lee
我想“烹饪”比“餐馆”更有品位。我知道“黄金”是垃圾!
什么是好名字?
最后,为了好玩,我构建了一个小脚本,它随机生成中国餐馆名称(使用我们在训练集中构建的词汇),并返回模型预测的第一个好餐馆名称。剧本找到的我的最爱?
超级卡西
黄门
周大叔
大胖子
哪天带我去 Great Fatt 。
回到华龙,我经常路过的餐馆…它在 Yelp 上有 3.5 的评分和 20 条评论。模特是怎么想的?
>> model.predict(model_vect.transform(['hua long']))[0] False
mlforthewin
笔记本在 github 上。
一张图抵得上千言万语吗?
原文:https://towardsdatascience.com/is-a-picture-worth-a-thousand-words-d640425c0029?source=collection_archive---------18-----------------------
Source: Dark Reading
背景
我们的项目受到杰米·瑞安·基罗斯的启发,他创建了一个经过 1400 万段浪漫故事训练的模型,为单个图像输入生成一个简短的浪漫故事。同样,我们项目的最终目标是为孩子们输出一个小故事。
“神经说书人是一个循环神经网络,产生关于图像的小故事”——杰米·瑞安·基罗斯
参考:【https://github.com/ryankiros/neural-storyteller
项目目标
- 将代码从 Python 2 更新到 Python 3+
- 重建原来的项目,这是对浪漫小说的训练
- 拼凑儿童故事
- 通过 RNN 对儿童故事训练跳跃思维解码器,以创建风格偏差数据
- 从 Microsoft Azure Vision API 收集图像标签和标题
- 基于单个图像的输入为儿童输出一个小故事
- 比较浪漫和儿童故事类型的输出
数据采集
最初的计划是从 SmashWords 中抓取儿童书籍(PDF 格式)(正如 Jamie 所推荐的),但是我们面临着让 Python 库 textract 和 PyPDF2 从给定的 PDF 中提取所有单词的挑战。相反,我们专注于抓取那些有 HTML 文本格式的现成故事的网站。通过 Google Chrome 使用 Web Scraper 扩展,我们能够从多个来源搜集儿童故事。这里有一个我们用来浏览网站网页的选择器图形的例子:
Example: Web Scraper selector graph
一旦我们将数据聚合到一个文件中,我们就用 nltk 将数据解析成句子。这种方法将我们的数据集规模增加到近 45,000 个句子。以下网站是我们数据收集过程的一部分:
- 童话故事:https://www.storyberries.com/category/10-min-stories/
- 美国文学:https://americanliterature.com/short-stories-for-children
- 英国学生:https://www.studentuk.com/category/bedtime-stories/
- 今晚的睡前故事:【http://www.tonightsbedtimestory.com/stories/】T2
资源
我们能够通过遵循 Amulya Aankul 的教程来设置 Jupyter Notebook 的谷歌云实例。
注意:在 10 GB 磁盘出现内存泄漏后,我们将磁盘映像大小增加到了 100GB。
型号设置
为了使新模型输出儿童短篇故事,我们根据儿童故事训练了递归神经网络(RNN)解码器。与杰米的模型略有不同的是,每个句子都被映射到一个跳过思维向量,然后这个向量生成几个句子,RNN 根据跳过思维向量对这些句子进行了调整。在杰米的爱情小说训练模型中,她使用了段落,但鉴于我们的数据集非常小,我们将段落分解成句子,以增加我们的数据集。
Source: Google Blog
在模型设置期间,我们在训练上下文中的通用对象(COCO) 图像和标题时面临挑战。上图详细描述了 Vision Deep CNN 如何在最终图层中使用语言生成 RNN 来生成字幕。鉴于我们对这个项目的时间限制,我们决定使用微软 Azure 的 Vision API ,它生成了几个图像标签和一个标题。然后,我们将图像标签连接成一个标题,这样我们就可以输入两个标题。我们在这篇文章的后面提供了两个例子。在 Jamie 的模型中,COCO 数据集提供了五个标题。我们假设标题数量的差异影响了我们的模型为儿童故事开发更好的语法和更合适的风格的能力。
上面引用的函数允许我们将来自 Vision API 的标题连接到模型生成的短篇故事。该公式是使用三种不同的向量构建的:
- X =图像标题
- C =“标题样式”向量
- B =《书风》矢
正如杰米在她的项目中所详述的,跳过思维向量对以下因素敏感:
- 长度——在我们的例子中,我们的短句(与段落相比)影响了短篇故事的长度。一般来说,儿童故事输出的字数大约是一个生成的浪漫故事的三分之一。
- 标点符号 —我们注意到标点符号(对于两种模型)仅限于句号、逗号和问号。这可能是不同数据集如何被解析成段落/句子的巧合。
- 词汇——我们假设,考虑到爱情故事和儿童故事的目标受众非常不同,词汇会有明显的差异。在下面的例子中,很明显浪漫故事中使用的词汇更加成熟
- 句法风格——类似地,句法风格很大程度上基于用于训练模型的段落/句子。在我们的测试中,爱情故事和儿童故事在风格上没有任何明显的区别。
工作流程
最后,我们能够将所有组件打包到一个模型中。
- 向微软 Azure Vision API 提交图像
- Microsoft Azure Vision API 输出图像标签和标题:在这一步,我们将图像标签连接起来,这样它们将作为标题呈现给模型
- 将图像标签&标题提交到模型:有两个标题,一个由 Vision API 提供,另一个由图像标签连接,我们将它们与样式(或本项目中的故事类型)一起提交到模型
- 模型输出短篇故事
结果
总的来说,浪漫故事(由模型生成)的内容量比儿童短篇小说多得多。《老友记》演员和比萨饼的图片作为我们测试的一部分被提交。请参见下面的输出:
Source: The Independent
好友:串联图片标签&标题
[‘人人团摆姿势合影’站在窗前的女人男人拿着西装蛋糕美食桌’,‘马特·勒布朗,丽莎·库卓,柯特妮·考克斯,大卫·史温默,詹妮弗·安妮斯顿摆姿势合影’]
老友记:浪漫故事
杰斯在想这永远不会是我的错,她笑了笑,让凯特再次触摸她的情绪,然后她转过头,让他走进浴室,她让他一碰她,安娜很快就把她的注意力转回到我身上,知道他可能是一次之前,她走进我的顶楼套房,让丽芙再次脸红。我要想多少次我妈为什么要嫁给他?不要因为她是我最喜欢的珠宝而激动。照片照片相册很完美,但感觉很完美。她用食指指着我,用食指指着我的嘴唇。不要换我的西装。我见过的唯一一个女人和婚礼上的另外两个男性成员一样性感。还有我的母亲,纳特,梅尔·米勒,她似乎相信自己选择了一个完美的黑发女人。
朋友:儿童故事
但是,如果我曾经告诉她的母亲告诉他真相,如果她失去了理智,这个年轻人,他从来没有照顾过她的父亲,他有义务照顾她的父亲,为了她的父亲,他有义务照顾她的父亲,我永远不会看到她吃了她的眼睛,为了国王的女儿,她有义务照顾她的父亲,谁没有离开她的脾气,
Source: Expert Photography
披萨:串联图片标签&标题
['照片披萨食物不同的坐盒桌子黑色情侣盘各种肉类配料放在平底锅上紫色','坐在平底锅上的披萨']
披萨:浪漫故事
披萨一杯酒下肚,我发现自己抱得有点太紧了,根本不在乎我认为该轮到我把自己拼起来,就像她天生就该穿一样。黑色的头发落在一只眼睛上,让我觉得更恶心。我坐在一张放在枕头上的桌子旁,把它整齐地叠放在床头柜上。有了戏剧性的变化,我根本没打算露面。我不会成为一对非常可爱的年轻夫妇。我当时只有九个月大,我讨厌承认这一点。与此同时,我拿着平底锅把它放在枕头上,然后用它指着平躺在我床头柜上的可爱小猫。我们再也看不懂对方,很快我就咬下嘴唇。
披萨:儿童故事
有几分钟,我不得不坐在木头上,给了他一把剪刀,让他用我的床做饮料,我会给你一点水,让你用壶做饮料,还有一点酒,我不得不吃了一片面包,所以我要吃她的嘴唇,
挑战
- 找到合适的训练数据量。回想起来,我们应该选择一个有大量数据的故事类型
- 整理数据(删除空行、编码等。)
- 设置 Google 云实例
- 从几个来源寻找和搜集儿童故事
- 匹配数据集的编码
- 用较新的版本重新创建原始项目
- 设置 Google 云实例
- 训练模型
- 原始项目使用 COCO 图像字幕来生成图像的字幕
外卖
- 在确定一个流派之前,探索数据来源。在我们的案例中,我们认为我们能够找到重要的数据来训练儿童故事的模型,但是只有这么多免费的网站可以收集
- 数据越多越好(模型)。杰米的原始模型是在 1400 万篇文章上训练的,而我们的模型依赖于 48k 个句子。
- GPU 超过 CPU。我们花了大量的时间在本地机器上设置我们的模型,而在项目的早期我们可以从 Google Cloud 实例开始。
未来工作
经过思考,我们讨论了几种改进模型的可能性。首先,我们的教授 Alex Dimakis 博士提出了一个有趣的补充,即确保作为输入(在标题中)的每个单词都将包含在生成的短篇故事中。另一个需要考虑的是模型训练的顺序。假设最初的模型是根据浪漫故事训练的,首先,我们假设如果我们最后训练浪漫故事,那么短篇故事输出的语法和风格将更接近儿童故事。这也可能是因为数据集大小的巨大差异。如前所述,浪漫小说数据集包含超过 1400 万篇文章,而我们的儿童故事数据集有 48,000 个句子。同时,为更好的字幕寻找另一个来源也是值得的。
我们当前的模型将图像标签连接起来作为输入的标题,但是我们发现这种方法会影响短篇故事输出的语法和样式。我们相信这是事实,因为我们的连接标题只是一组名词。总的来说,我们喜欢学习原始项目并完成我们的项目目标。你可以在这里找到我们的代码库。
参考文献
没有互联网的伟大人们,我们不可能完成这个项目。请为您的下一个数据科学项目查阅以下资源:
- https://ai . Google blog . com/2014/11/a-picture-is-worth-仟-coherent.html
- https://towards data science . com/running-jupyter-notebook-in-Google-cloud-platform-in-15-min-61e 16 da 34d 52
- https://medium . freecodecamp . org/building-an-image-caption-generator-with-deep-learning-in-tensor flow-a 142722 e 9 B1 f
- https://www . aaai . org/OCS/index . PHP/AAAI/aaai 16/paper/download/11966/12271
- https://github.com/ryankiros/neural-storyteller
- https://arxiv.org/abs/1508.06576
由阿布希拉莎·卡尼特卡、阿努加·斯里瓦斯塔瓦和穆罕默德·恩多耶拍摄
AI 在这里是取代人类老师还是老师的助手?
原文:https://towardsdatascience.com/is-ai-here-to-replace-human-teachers-or-is-it-a-teachers-assistant-2db6bd624a45?source=collection_archive---------6-----------------------
三年前,联合国教科文组织通过了《2030 年可持续发展议程》,其中一个关键目标是确保全球平等获得优质教育。但是快节奏的技术发展重塑了教师向年轻一代传授知识的角色。许多人担心人工智能机器人将很快完全取代人类教师。那么,这有什么根据吗?
人工智能黄金时代的教师角色
正如亚马逊首席执行官杰夫·贝索斯所说,我们正在见证人工智能技术的复兴。如果不触及问题的核心,机器在很大程度上接管人类的任务可能看起来令人担忧。人工智能已经减少了对从事日常工作的工人的需求,提高了离职标准,并使人类能够解决复杂的医疗保健、物流和安全任务,这些任务需要做出明智的决策。那就更好了。
人工智能不是潘多拉的盒子。相反,预计创造的就业机会将超过它将要消除的。但是许多职业,比如教师,无疑需要人类的头脑,而不是人造的。因此,思想领袖、知识分子和受过人机交流训练的精明专业人士将成为最受欢迎的专家。
当老师需要 AI 助手
老师的工作量经常超出合理水平。一个好的充满激情的老师应该在一个教室里管理多达 30 名学生,让他们认真学习,停止咯咯笑和玩小玩意,监督学生的学习成绩,批改作业,准备教案等等。这些挑战令人望而生畏,更不用说教师的工资了。教师职业太累,而且报酬往往太低,因此越来越不受欢迎,这导致了世界范围内的教师短缺。然而,正如我们今天所知,技术革命正在改变教学和学习。
AI 的使命是在计划、个性化、可视化和促进学习过程方面提供帮助。让我们深入研究以下人工智能驱动的创新,这些创新不仅可以帮助教师让学生更聪明,还可以让学习过程更智能。
推动课堂限制
传统的教室、黑板和手册已经成为对学习过程逆向理解的一部分。利用技术,教师和学生可以超越以前看似可能的边界。希望不久以后,教育领域剩下的唯一限制将是一个人或另一个人对自我发展的渴望。
使用人工智能驱动的工具能够创造全球教室。它为有视觉或听觉障碍的学生和讲其他语言的人带来了新的学习机会,允许教师考虑不同的学习风格(使视觉、听觉学习者等更容易)。)并尽可能个性化学习,提高学习成绩。
举个例子,一个免费的 PowerPoint 插件演示翻译器以实时模式创建字幕。Azure 认知服务、人工智能语音识别和翻译等技术允许学生以最方便的方式跟随老师。
Source
1.人工智能推动自动语音识别,自然语言处理生成脚本。
2.机器翻译为说不同语言的学习者改编文本。
3.学生可以听或读老师屏幕上显示的文本,或者通过个人设备加入对话。
这个解决方案提供的能力不能被夸大,因为最终的个性化学习及其全球可访问性是每个人都渴望的。
没有孤立学习的机器人
全世界有如此多的学生由于长期患病而无法上学。但人工智能是为了实现智能远程学习机会。机器人可以在教室里代替学生,确保实时在场,即使这在物理上是不可能的,并消除学生与同学和老师的隔离。这项技术允许学生离开病床,使用平板电脑控制周围发生的事情。这种机器人与微软 Azure 物联网中心连接,为学生提供所有视频和音频连接,并允许参与课堂讨论。
教育机器人市场正在增长,其目标是提供负担得起的教育硬件和软件解决方案。然而,对这项技术的需求受到限制,因为这在很大程度上取决于教师是否愿意将机器人纳入学习过程。
教师助理
作为数字化转型的一部分,日常活动的自动化是当今的趋势。教育领域也不例外。老师花多少时间批改作业和准备报告?数量惊人。他们会重新计划他们的时间来利用新的机会并把他们的学生带到新的高度吗?当然,如果他们有机会把需要很少智力资源的任务委托给别人就好了。
利用微软 Azure 和机器学习,像 Gradescope 这样的教育软件可以帮助给学生作品或提交的作品评分,生成并分享详细的分析。人工智能助手可以帮助教师根据不同学生的需求量身定制学习计划。例如,世纪科技收集每个学生的学习进度数据。通过分析每个学生的微粒数据,人工智能考虑到了人类教师可能注意不到或收集不到的细节。人工智能能够提供基于数据的对学生成功或失败的预测,识别知识差距,突出优势和弱点,并建议额外辅导会有所帮助。全知是人工智能的真正力量。
今天的学生将在人工智能将成为日常现实的未来生活和工作。纸质手册和黑板的时代已经过去了:是时候让学生接触已经在学校的尖端技术了。现代学习过程需要更多的交互性和个性化,以使知识在世界各地更容易获取,而不管一个人的居住地、语言、健康障碍或学习能力如何。
人工智能可以很容易地成为学生和老师的最好的朋友,在需要的时候提供个性化的辅导和帮助。但 AI 做不到的是成为学习的灵感来源,不像人类老师。同理心在学习过程中的重要性比看起来要高。这是人工智能驱动的教育解决方案的主要缺点,也是人工智能不可能完全取代人类教师的原因。
喜欢这篇文章吗?在这里找到更多故事:https://indatalabs.com/blog
挖掘数据科学的力量!
Airbnb 是在把当地人从市中心赶走吗?对 k 近邻的研究
原文:https://towardsdatascience.com/is-airbnb-pushing-away-locals-a-study-with-k-nearest-neighbours-a3ae22a07b0f?source=collection_archive---------11-----------------------
短期与长期租赁:什么更方便?
简介
我在九月初搬到了斯德哥尔摩,这个城市无疑提供了一些额外的好处。其中,我们可能包括:公园,公园里的松鼠,公园旁边有尖顶的浅色建筑,以及自由和幸福的普遍感觉。显而易见,我们可能没有包括的温暖。
我和我的女朋友决定在圣诞节前飞往雅典几天,我们选择住在 Exarhia 的一家 Airbnb,这是一个离旅游中心不远的又酷又另类的地区。预订一完成,我就被两个问题困扰了。第一个:我们得到了公平的价格吗?(简单回答:我们当然是,Airbnb 使用类似于我接下来将要展示的算法来向主机建议最优价格)第二:我们正在为 Exarhia 的中产阶级化做出贡献吗?换句话说,在我们过去之后,当地人还能负担得起在那里生活吗?
要回答这些问题,我只需要一袋数据和一些技巧。没过多久就遇到了 insideAirbnb 团队拼凑的优秀数据集。我对分析旅游业如何改变住房动态很感兴趣,不仅是在希腊,而是在整个世界。在这个集合的 44 个城市中,我选择了 16 个作为样本。
雅典事件
关于雅典的文件包含 5000 多个列表。每个列表都带有你通常会在 Airbnb 主页上找到的所有信息,包括房屋描述、客人评论、用户评级等等。在我的分析中,我决定将特征缩小到以下集合:价格、住宿类型(房间还是整个公寓?),它可以容纳的人数,房间数,床位数,浴室数,纬度,经度,平均评分和评论数。
正如我所说的,我的主要目的是想知道我支付的每晚 22 欧元是否是一个公平的价格。为了实现这一点,我经历了以下步骤 : 1)我将数据集上传到 Pandas 数据框架中,将列表分配给行,将特性分配给列。2)我用标准分数对列进行了标准化。3)我从我选择的 Airbnb 上输入数据。4)我计算了我的 Airbnb 和所有其他 Airbnb 之间的欧几里德距离,将每个列表视为 n 维空间中的一个点,其中 n 是被考虑的特征的数量。5)我在参数空间中选择 5 个最近的邻居,并取它们价格的平均值。
结果,算法返回的价格是 23 欧元,相当惊人的结果。在下面的地图中,我标出了我的物品的位置(在空间中)以及它的邻居。
In blue: my Airbnb in Athens. In red: 5-nearest.
测试模型
为单个列表获得正确的数字是非常令人欣慰的,但这并不意味着该算法将在更广泛的意义上工作。为了测试我的预测器的准确性,我将我的数据一分为二,使用训练集(总数的 3/4)来预测测试集(1/4)中每个列表的价格。结果不是很好。
在 30%的任意误差范围内,我能够正确预测略高于 53%的房源的价格。如果误差幅度增加到 1 个均方根偏差——在雅典的例子中,平均价格为 51€,误差幅度约为 36 欧元——准确率就上升到 86%。阿姆斯特丹的情况看起来类似,在这种情况下,我能够正确预测 67%的价格,误差在 30%以内,83%的价格在 1 rmse 以内。
大局
下一步,我想用我的预测器来确定你一个月能从 Airbnb 房子里赚多少钱,以及这与常规租金相比如何。
在公布我的分数之前,我测试了不同 k 值的算法,即选择不同数量的邻居来计算平均值。通常的 k=5 给出了最小的 rmse,我认为这是一个好兆头。在计算到目标的距离时,我还想看看这 7 个参数的相对权重。我选择了一个 Airbnb 基准房产(两个人的工作室,有一间卧室、一间浴室、一张床,评论数和评论分数为给定城市的平均值),我绘制了一个热图,其中每个矩形代表基准房屋的参数和其五个最近邻居的平均值之间的差异。
事实证明,在 k = 5 时,预测器已经正确地过滤掉了前五个特征,并且基于评论数量和评论分数来选择邻居。快速相关性检查显示,价格与前五个特征(r 值~0.5)的相关性高于后两个特征(r 值~0.01),这是一个好消息,该算法正专注于重要的事情。
加载所有数据并运行程序,我获得了一个包含 1 天、1 个月的 Airbnb 预测价格的表格,并将它与类似房屋和平均工资的常规 1 个月租金进行了比较。入住率来自 insideAirbnb 网站,而固定租金和薪水来自 Numbeo 。
All figures are expressed in Euro.
表格的前两列以条形图显示,如下所示:
事实证明,在大多数城市,将一室公寓出租给愿意支付更高费用的当地人还是很方便的。这在拥有大量高薪专业人士的城市尤其明显,如旧金山、悉尼、温哥华和香港。
在从大量游客中获利(或受损)的城市,情况看起来有所不同,Airbnb 可以保证更高的收入,如威尼斯、巴塞罗那和……雅典。
嗯,我想这就是问题的关键。经过两天的工作,我可以有把握地说:我现在感到内疚是对的。
就是这样。所有代码照常在我的 GitHub repo 上可用,还有一个 Jupyter 笔记本。如果你喜欢,请在下面评论。
人工智能是种族歧视吗?(以及其他问题)
原文:https://towardsdatascience.com/is-artificial-intelligence-racist-and-other-concerns-817fa60d75e9?source=collection_archive---------14-----------------------
当我们想到对人工智能的担忧时,两个主要的明显联系是失业和致命自主武器。虽然杀手机器人可能是未来的实际威胁,但自动化的后果是一个复杂的现象,专家们仍在积极分析。很有可能,就像任何重大工业革命一样,市场会逐渐稳定下来。技术的进步将创造新的工作类型,这在当时是不可想象的,但随后会被新的重大技术接管所破坏。在现代历史上,我们已经多次看到这种情况,我们可能还会再次看到这种情况。
第三个主要关注领域是人工智能的伦理影响。问题来了:人工智能是种族主义者吗?
嗯,简而言之..没有简答。
长回答呢?谷歌、海豹和大猩猩的故事
为了回答这个问题,我们首先需要定义什么是种族主义。
种族主义:认为每个种族的所有成员都拥有该种族特有的特征、能力或品质,特别是为了区别于其他种族或种族的劣等或优等。 ~ 牛津词典
种族主义是指对一个种族的所有成员概括具体的特征。泛化是机器学习中的一个关键概念,在分类算法中尤其如此。归纳学习与从具体例子中获得一般概念有关。监督学习中的大多数技术都试图逼近函数,以尽可能高的精度预测输入值的类别。
过于符合我们的训练集的函数会产生过拟合。实际上,给定不同的输入,它不能导出一个适当的通用函数。另一方面,与数据集不匹配的函数会导致与不匹配。因此,生成的模型过于简单,无法产生重要而可靠的结果。
该领域的专家知道,分类就是寻找过度适应和欠适应之间的平衡。事实上,该模型需要从特定的训练集中导出一般规则。这显然导致了一个重大问题:如果用来训练模型的数据有偏差,那么模型就会产生有偏差的结果。
一个显示有偏见的数据的后果的著名案例是两个非裔美国年轻人的错误标签。Google Photos 最近实现了自动图像标记,将这两个青少年归类为“大猩猩”(所有参考资料都在页面末尾)。谷歌遭到了严厉的批评,有人开始怀疑一台机器是否可以被训练成故意的种族主义者。
谷歌团队立即道歉,一名发言人在推特上写道:“直到最近,[谷歌照片]还在把白人面孔与狗和海豹混为一谈。机器学习很难”。
然而,错误分类的实际原因根本不是因为种族主义。这个错误的原因在于训练集。
超人、犯罪和种族主义
为了理解我们刚刚讨论的内容,让我们看一个简单的分类错误的例子。
假设我们想预测克拉克·肯特是不是罪犯。这是我们的数据集:
Dataset containing 5 elements
我们的训练集代表 5 个人,属于三个不同的种族:氪星人,人类和机器人。
我们将训练一个决策树分类器来预测克拉克·肯特,一个 31 岁的氪星男性,是否会被归类为罪犯。
首先,我们训练模型:
clf = tree.DecisionTreeClassifier()
X_train = data[['Sex', 'Age', 'Race']]
Y_train = data[['Criminal']]
clf.fit(X_train, Y_train)
然后,我们根据训练好的模型预测“罪犯”类别:
# 1 -> Male
# 31 -> Age
# 1 -> Kryptonian
pred = clf.predict([[1, 31, 1]])
print('Is Clark Kent a criminal? Prediction: ',pred[0])
正如我们所看到的,克拉克·肯特被归类为罪犯。让我们检查特征的重要性,以便理解变量如何影响分类器的最终输出。
在这里。根据我们用来训练模型的数据集,最重要的特征是可变种族。
计算机视觉中的偏见
这个简单的例子显示了数据收集和数据组织的重要性。当这两种行为表现不佳时,伦理和文化偏见可能会被编码到机器学习模型中。据《自然》杂志的一篇文章报道,计算机视觉中 45%最常用的图像数据库来自美国。占世界人口 36%的中国和印度,在 ImageNet 数据集中仅占 3%的数据。这种不平衡无意中产生了偏见,并解释了为什么计算机视觉算法将一张北印度新娘的照片贴上“行为艺术”的标签。
麻省理工学院的研究员 Joy Buolamwini 几年前就提出了用于训练计算机视觉算法的数据缺乏多样性的问题。她注意到,尽管麻省理工学院最著名的面部识别系统能够正确分类几乎所有白人的性别,但随着肤色变深,准确率会大幅下降。最低的准确率与深色皮肤的女性有关,错误率为 34%。
微软如何在 24 小时内破坏一个机器人
偏见和错误不仅仅发生在图像分类任务中。自然语言处理是专注于人类语言处理的人工智能领域。许多 NLP 算法共有的一种通用方法是将单词映射到几何向量。这种技术将文档视为向量的集合,允许单词之间的计算。Bolukbasi 和他的同事在他们的论文《男人对于电脑程序员就像女人对于家庭主妇?消除单词嵌入的偏见”,展示了一个基于谷歌新闻文章训练的简单类比算法如何展示女性/男性性别刻板印象。正如他们所报告的那样,该模型表明'男子对'医生'而'女子'对'护士。
这让人想起了一个类似的争议:2016 年,微软部署了 TayTweets,这是一个通过 Twitter 上的随意对话训练的 Twitter 机器人。这个想法非常有前途,因为 Twitter 上每秒钟都有大量的文本数据。反正不用说,经纪人不到 24 小时就开始发厌女症和种族主义言论了。谁能想到呢?
Racist bots and where to find them
TL;速度三角形定位法(dead reckoning)
最后,我们的分析到此结束。这篇文章的全部观点是提出一个经常被忽视的与人工智能相关的伦理问题。虽然科学家、工程师和数据科学家需要解决训练集中的不平衡,但用户和非专家需要理解人工智能是以数学为基础的。众所周知,数学可能非常复杂。用于图像分类的神经网络被认为是“黑盒”。他们给出的结果是基于极高维度的计算,并且无法完全控制——即使公司正在付出巨大努力来理解中间输出,并取得惊人的结果(查看我关于神经传递风格的文章,基于这一概念)。
不过,我们还有最后一个问题要回答,希望能在下面的评论中讨论。AI 是种族主义者吗?
感谢阅读。对于任何意见或建议,不要犹豫留下评论!
你可以在 maurocomi.com 找到更多关于我和我的项目的信息。你也可以在 Linkedin 上找到我,或者直接发邮件给我。我总是乐于聊天,或者合作新的令人惊奇的项目。
参考资料:
[## 谷歌照片通过面部识别软件将两名非裔美国人标记为大猩猩
当土生土长的布鲁克林人杰基·阿尔辛在周日晚上登录照片时,他震惊地发现了一本名为…
www.forbes.com](https://www.forbes.com/sites/mzhang/2015/07/01/google-photos-tags-two-african-americans-as-gorillas-through-facial-recognition-software/#5fb16d5c713d) [## 人工智能可能是性别歧视和种族主义者——是时候让它变得公平了
当谷歌翻译把用西班牙语写的新闻文章翻译成英语时,涉及女性的短语经常变成…
www.nature.com](https://www.nature.com/articles/d41586-018-05707-8) [## 种族主义、性别歧视的人工智能可能是比失业更大的问题
Joy Buolamwini 在麻省理工学院进行关于计算机如何识别人脸的研究时,她开始经历…
www.forbes.com](https://www.forbes.com/sites/parmyolson/2018/02/26/artificial-intelligence-ai-bias-google/#7a16bdda1a01)
https://www . the verge . com/2016/3/24/11297050/tay-微软-聊天机器人-种族主义者
并发真的能提高性能吗?
原文:https://towardsdatascience.com/is-concurrency-really-increases-the-performance-8cd06dd762f6?source=collection_archive---------4-----------------------
如果您想提高程序的性能,一个可能的解决方案是添加并发编程技术。基本上,在并发执行中,同一个程序的多个线程同时执行。这类似于添加更多的工人来完成一项工作。
“并行”是另一个经常与并发性一起使用的词。并行是并发的一个子集。并发性是指试图同时做多件事情,而并行性是指同时做多件事情。
即使在单核处理器上,也可以通过在线程间切换来实现并发。在某个时刻,一个线程被执行。然而,通过在线程间切换并作为一个整体前进,许多事情正在发生。
并行发生在多核处理器上。由于有多个内核,因此一次可以执行多个线程。在单核处理器上,实际并行是不可能的。然而,它试图通过在线程之间快速切换来归档并行性。
并行解决一个问题似乎会大大减少计算时间。然而,任何事情都是有代价的。尽管我们认为一次做很多事情会加快速度,但由于线程之间的通信以及确保它们不会崩溃或产生错误的输出,这是有成本的。并发编程必须非常小心,它会导致不可避免的编程开销。
- 初始化时间
- 时间最终确定
- 外部库导致的开销
- 线程间通信的开销
通常,外部库(例如 pThreads,OpenMP)将在编写并发程序时使用。加载这些库会有开销。此外,将使用并发编程构建块,如信号量、互斥体、锁,它们将花费初始化和最终确定的时间。
其中最大的开销是由线程间的相互通信引起的。在并行设计中,产生错误结果的可能性很高,并且需要处理互斥,以避免死锁或饥饿场景。
为了满足上述所有条件,需要大量的同步和信令,这将增加计算时间。这些开销是不可避免的,因此要求设计程序时尽可能减少开销。
下面的例子展示了与串行执行相比,使用不同机制的并发编程的强大功能。这里使用一个链表来执行插入、删除和成员操作。测量执行时间来比较性能。
在包含不同数量的插入、删除和成员操作的 LinkedList 上执行 1000 次操作。所有的任务都是串行和并行执行的。并行执行再次使用互斥锁和锁来实现。
下面是使用 pThreads 库用 C 语言实现该程序的代码段。
串行程序
使用互斥体的并行程序
使用锁的并行程序
以下是观察到的结果
代码被执行并采集了 100 个样本,以确保结果在 95%的置信区间内。
案例 1:
- 插入操作:5
- 删除操作:5
- 会员运营:990
案例二:
- 插入操作:50
- 删除操作:50
- 会员运营:900 家
案例三:
- 插入操作:250
- 删除操作:250
- 会员运营:500 人
如图 1 和 2 所示,当使用一个线程时,使用互斥和读/写锁比顺序编程有更长的处理时间。出现这种情况的主要原因是,当互斥体和读/写锁操作执行时,需要额外的时间来获取和释放锁或互斥体。但是在顺序编程中,不存在获取或释放锁或互斥体的情况。然而,在图 3 中,对于一个线程,顺序编程方法和并行编程方法存在滑动偏差。可能的原因是操作中分数的变化。
根据图 1 和图 2,对于任何数量的线程,使用读/写锁都比使用互斥锁表现出明显更高的性能。这是因为读/写锁允许执行读操作的线程同时访问临界区。但是在互斥的情况下,它只允许一个线程访问临界区一次,而不考虑操作类型。这种机制降低了互斥锁的速度,而不是读/写锁。
与情况 1、2、3 相比,执行读/写操作所需的时间增加了。出现这种情况的可能原因是,在案例 3 中,成员操作正在减少。因此,并发读取操作减少,而插入和删除操作增加,这导致总处理时间增加。
在图 1 中,在有多个线程情况下,与互斥和顺序方法相比,执行读/写操作所需的时间大大减少了。这是因为在这种情况下,有更多的读操作会导致读/写锁中的并发读。这展示了实际的并行性,并显示了读/写执行的低平均执行时间。
结论
根据结果,并行执行明显地显示出显著的改进。但是这里我们需要考虑一些事情。
不应该使用并发方法来加速小型计算问题。原因是初始化和完成库、互斥、信号量等所需的时间对输出有很大影响。
另一方面,对于大型计算问题,即使有额外的开销,整体性能也会提高。
另一个重要的设计决策是选择正确的构建模块(信号量、监视器、互斥体)来实现程序。即使在上面的例子中,我们也可以看到锁的性能比互斥锁好。为此,我们应该对基础知识有适当的了解,以便正确应用。
使用并发编程可以获得相当大的加速。天气预报系统、视频渲染程序、模拟程序都利用了并发编程的巨大优势。但是,需要了解适用性以及正确的设计和实现才能享受性能
数据科学是真正的科学吗?
原文:https://towardsdatascience.com/is-data-science-a-real-science-2920bb2529aa?source=collection_archive---------0-----------------------
当我听到关于数据科学不科学的批评时,我想澄清什么是科学,并展示数据科学家如何回答这些关于他们领域的常见批评。
Photo by Donald Giannatti
什么是科学?
科学是寻求对世界的合理解释的过程。正如大卫·多伊奇在他的书《T2:无限的开始》中指出的,一个好的解释是清晰、精确且难以改变的。
什么是数据科学?
数据科学是一个新兴的科学领域,致力于从数据中提取意义并增进理解。它代表了从统计、数据分析、BI 等其他分析领域的发展。
今天,由于互联网提供的数据爆炸,更先进的技术提高了计算能力,计算机科学和机器学习算法的发展,数据科学应运而生。
Jeff Hammerbacher 和 DJ Patil 首先使用数据科学家这个术语来描述一个新的职位。他们寻找拥有一套新的关键技能的人,如数学、统计学、计算机科学、机器学习和商业知识。
为什么数据科学可能永远不是“真正的”科学?
批评:“大数据分析主要是:垃圾进,垃圾出……那么,你如何认证你的数据和结果的质量呢?”。的确,我们的海量数据可能充满了错误和差错。但是,这种批评也适用于中小型数据集。重要的是我们如何收集数据,以及如何处理数据。在这个过程中,我们会犯一些错误,但是对于大多数错误,数据科学可以处理数据质量的问题;像其他分析领域一样。
批评:“数据科学可以在大量数据中发现任何东西。通过子集化数据和构建新的功能,他们可以证明任何事情。正如罗纳德·h·科斯(Ronald H. Coase)所说:“如果你对数据折磨的时间足够长,它就会招供。另一个大问题是可以克服的。当然,数据科学家必须小心不要太快下结论。再一次,就像其他任何试图寻求真相的人一样。在数据科学中,我们有几十种严谨的方法来处理数据。例如,交叉验证和正则化有助于避免过度拟合一个人的预测。此外,我们可以发布我们的代码,其他科学家可以从头到尾准确地跟踪我们对数据做了什么。
批评:“数据科学家只能建立观察性研究。他们可能会发现一些相关性,但不能说任何潜在的原因。“
随机样本和对照组的对照实验更好地评估因果关系。但在很多情况下,他们是昂贵的,不道德的,甚至是不可能领导的。为了正确地研究不同的现象,科学需要两者:控制实验和观察研究。
批评:“对数据科学来说还行…但是,业务数据科学永远不会是真正的科学。科学在商业中是不可能的,因为公司追求的是金钱,而不是科学真理。 "
即使在这里进行区分是有意义的,在企业工作的数据科学家也可以被视为科学的,就像许多其他经常在研发部门工作的研究人员一样。事实上,对现实和真相的承诺可以为企业带来持久的竞争优势,科学发现可以带来巨大的好处。
即使这些批评需要被任何试图使用数据获得知识的数据科学家考虑在内,他们也不会谴责他们是失败的科学家。此外,这些批评往往没有抓住要点,因为它们来自那些不太了解我们处理大量数据的方法的人。
能否一下子判断出整个数据科学领域?
上述批评的主要错误在于,在没有真正理解的情况下,立刻对整个数据科学领域做出判断。这在任何科学领域都行不通:
有的医生根本不懂统计学;这是否意味着医学界不科学?而我们说医学注定不科学吗?
2015 年,许多失败的实验复制严重伤害了心理学。我们是否得出结论,所有的心理学家都不是科学的,而且永远不会是科学的?
我们不能马上对整个科学领域做出判断,因为他们在更科学的领域中包括了许多不科学的人。
一些数据科学家是受经济利益驱使的计算机极客。其他一些人努力确认任何先前的直觉。数据科学不得不处理这个问题,并在一些地方背负了坏名声。
但是,数据科学领域在生物学、金融、市场营销和经济学方面也取得了许多成功。此外,更多的发现将来自我们利用机器学习算法或计算统计学来理解大量数据的新方法。
数据科学家是真正的科学家吗?
“科学是一种思维方式,而不仅仅是一种知识体系。”——卡尔·萨根。
为了找到关于世界的更好的解释,科学家们为纠正他们以前知识中的错误创造了空间。他们寻找清晰、合理且可检验的解释。
数据科学家需要坚持这些科学原则,还需要接受科学价值观,如开放思想、批评和尊重他人的理性意见。
所以下次你想知道某个领域是否是科学的,深入到个人层面,看看那个人有多尊重科学的认识论、价值观和方法。例如,你可以问,她想达到什么目的?她是如何质疑自己的知识的?她信仰的主要来源是什么?
数据科学真的是“科学”吗?
原文:https://towardsdatascience.com/is-data-science-really-a-science-9c2249ee2ce4?source=collection_archive---------4-----------------------
为什么数据科学可能是一个严格的领域,不同于它的前辈
我继续看到关于数据科学是否真的是一门“科学”以及这个领域是否是“新”的讨论。不久前,我绞尽脑汁想出了支持数据科学既是“科学”又是“新”的好论点。我不能声称对这些观点有 100%的结论,但数据科学有一些明确独特的方面,我在下面描述了这些方面,摘自 像数据科学家一样思考 。
数据作为研究对象
近年来,关于 数据科学 的领域是否仅仅是结合了软件工程和数据分析的许多更古老领域的转世或分支——在大数据时代,有一个似乎永无止境的讨论:例如运筹学、决策科学、分析学、数据挖掘、数学建模或应用统计学。就像任何时髦的术语或话题一样,只有当这个术语的流行度下降时,关于它的定义和概念的讨论才会停止。我不认为我能比许多在我之前定义数据科学的人做得更好,所以让我转述维基百科中的定义就足够了:
数据科学是从数据中提取知识。
很简单,但这种描述并没有将数据科学与许多其他类似的术语区分开来,除了可能声称数据科学是所有术语的总称。另一方面,这个数据科学时代有一个前所未有的属性,对我来说,这是一个相当令人信服的理由,可以用一个新术语来描述数据科学家所做的事情,而以前的应用统计学家和面向数据的软件工程师没有这样做。
电脑和互联网的用户成为了数据的生产者
纵观近代历史,计算机在计算能力、存储和一般能力方面取得了令人难以置信的进步,以完成以前闻所未闻的任务。自近一个世纪前现代计算机发明以来,每一代人都目睹了不断缩小的机器,它们比上一代最强大的超级计算机强大几个数量级。从二十世纪下半叶到二十一世纪初,包括今天,这一时期通常被称为信息时代。信息时代的特点是计算机和互联网无处不在,可以分为几个与数据分析相关的较小的转变。
首先,早期的计算机主要用于计算,这在以前要花费不合理的时间。破解军事密码、导航船只以及在应用物理中进行模拟都是早期计算机执行的计算密集型任务。
第二个,人们开始使用电脑交流,互联网在规模和容量上都有所发展。数据和结果可以很容易地远距离传送。这使得数据分析师能够在一个地方收集更大、更多样的数据集进行研究。20 世纪 90 年代,发达国家普通人的互联网接入大幅增加,使数亿人能够获得已发布的信息和数据。
第三,尽管早期大众对互联网的使用主要包括消费出版内容和与其他人交流,但很快许多网站和应用程序的所有者意识到,他们用户行为的集合为他们自己产品的成功提供了有价值的洞察,有时甚至是对人类行为的洞察。这些网站开始以点击、键入文本、网站访问和用户可能采取的任何其他行动的形式收集用户数据。用户开始产生比他们消耗的更多的数据。
第四,连接到互联网的移动设备和智能手机的出现,使得收集用户数据的数量和具体性方面的巨大进步成为可能。在任何给定的时刻,您的移动设备都能够记录和传输其传感器可以收集的每一点信息(位置、移动、相机图像和视频、声音等),以及您在使用设备时故意采取的每一个动作。如果您启用或允许收集信息,这可能是一个巨大的信息量。
第五个——尽管这不一定是在个人移动设备出现之后——是数据收集和互联网连接几乎包含在所有电子产品中。通常被称为 物联网 (物联网),这些可以包括从你的汽车到你的手表到你办公楼顶部的天气传感器的所有东西。当然,从设备上收集和传输信息早在 21 世纪之前就已经开始了,但它的普遍存在是相对较新的,因为在互联网上可以获得各种形式的数据,处理过的或原始的,免费的或出售的。
通过计算设备和互联网的这些发展阶段,网络世界不仅仅是一个消费信息的地方,它本身也是一个数据收集工具。上世纪 90 年代末,我的一个高中朋友建立了一个网站,提供电子贺卡,作为收集电子邮件地址的幌子。他以几十万美元的价格出售了数百万个电子邮件地址的结果列表。这是用户数据价值的一个原始例子,其目的与网站本身完全无关,也是一个完美的例子,说明我很遗憾在年轻时错过了一些东西。到 21 世纪初,类似规模的电子邮件地址集合不再值这么多钱,但其他类型的用户数据变得非常受欢迎,同样可以卖得高价。
数据本身
随着人们和企业意识到用户数据可以被卖到相当可观的价格,他们开始不加选择地收集数据。
大量数据开始堆积在各地的数据存储中。在线零售商开始不仅存储你购买的所有东西,还存储你浏览的每一件商品和你点击的每一个链接。视频游戏存储了你的虚拟角色走过的每一步,以及它打败了哪些对手。
各种社交网络储存了你和你朋友做过的所有事情。收集所有这些数据的目的并不总是为了出售,尽管这种情况经常发生。因为几乎每个主要网站和应用程序都使用自己的数据来优化用户的体验和有效性,所以网站和应用程序发布者通常会在数据作为可以出售的东西的价值和数据在内部持有和使用时的价值之间徘徊。许多出版商害怕出售他们的数据,因为这为其他人找到有利可图的东西打开了方便之门。他们中的许多人把数据留给自己,囤积起来以备将来之需,因为他们应该有足够的时间从中挖掘出所有的价值。
互联网巨头脸书和亚马逊每天每分钟都在收集大量数据,但据我估计,他们拥有的数据大部分都没有被利用。脸书专注于营销和广告收入,他们拥有世界上最大的人类行为数据集之一。如果产品设计师、营销人员、社会工程师和社会学家能够获得脸书的数据,他们可能会在学术和工业领域取得巨大进步。反过来,亚马逊拥有的数据如果交给学术机构,可能会颠覆许多受人喜爱的经济原则,并创造出几个新的原则。或者,它可能会改变整个行业的零售、制造和物流工作方式。
这些互联网巨头知道他们的数据是有价值的,他们相信没有其他人拥有类似的数据集,无论在哪里都接近相同的大小或质量。无数公司都乐意为获取数据支付高价,但我猜测,脸书和亚马逊也有充分利用数据的愿望,因此不希望其他任何人攫取由此产生的利润。如果这些公司有无限的资源,他们肯定会试图从每一个字节的数据中榨取每一块钱。但是,无论他们有多么庞大和强大,他们的资源仍然有限,他们被迫专注于最直接影响其底线的数据使用,而排除了一些其他有价值的工作。
另一方面,一些公司选择提供对他们数据的访问。Twitter 是一个显著的例子。付费后,你可以访问 Twitter 平台上的全部数据流,并在你自己的项目中使用。一个完整的产业已经围绕着数据买卖的中介发展起来,以获取利润。一个突出的例子是来自各大证券交易所的数据市场,这些数据长期以来一直可供购买。
学术和非营利组织经常公开和免费提供数据集,但在如何使用它们方面可能会有限制。由于即使在一个单一的科学领域内数据集的差异,已经出现了数据集的位置和格式合并的趋势。几个主要领域已经创建了一些组织,它们的唯一目的是维护包含尽可能多的来自该领域的数据集的数据库。通常要求科学文章的作者在发表他们的作品之前将他们的数据提交给这些规范的数据仓库之一。
无论哪种形式,数据现在无处不在,而不仅仅是分析师用来得出结论的工具,它已经成为自己的目的。公司现在似乎将收集数据作为一种目的,而不是一种手段,尽管他们中的许多人声称计划在未来使用这些数据。独立于信息时代的其他定义特征,数据获得了自己的角色、自己的组织和自己的价值。
作为探险家的数据科学家
在 21 世纪,数据正以前所未有的速度被收集,并且在许多情况下,收集数据并不是为了特定的目的。无论是私有的、公共的、免费的、出售的、结构化的、非结构化的、大型的、正常规模的、社交的、科学的、被动的、主动的或任何其他类型的数据集都在到处积累。几个世纪以来,数据分析师收集他们自己的数据或获得数据集进行工作,而历史上第一次,许多行业的许多人首先收集数据,然后问:“我可以用这些数据做什么?”还有一些人在问,“已经存在可以解决我的问题的数据吗?”
通过这种方式,数据——任何地方的所有数据,作为一个假设的集合——已经成为一个值得研究和探索的实体。在过去的几年里,数据集通常是有意收集的,因此它们代表了对现实世界的一些有意测量。但最近,互联网、无处不在的电子设备,以及对错过数据中隐藏价值的潜在恐惧,让我们尽可能多地收集数据,通常是在一个宽松的前提下,即我们可能会在以后使用它。
图 3.2 显示了对计算历史上四种主要创新类型的解释:计算能力本身、计算机之间的联网和通信、大数据的收集和使用以及对大数据的严格统计分析。我所说的大数据仅仅是指最近捕获、组织和使用任何和所有可能的数据的运动。每一项计算创新都始于一个亟待解决的问题,然后经历四个发展阶段,这一过程类似于 Carlota Perez 的技术激增周期(技术革命和
金融资本,埃德华·埃尔加出版社,2002 年),但重点是计算创新及其对计算机用户和公众的影响。
对于图中包含的每个创新,有五个阶段:
- 问题 —有一个问题,计算机可以用某种方式解决。
- 发明——能够解决那个问题的计算技术被创造出来。
- 证明/认可 —某人以一种有意义的方式使用计算技术,其价值被证明或至少被一些专家认可。
- 采用——这项新证明的技术在工业上得到广泛应用。
- 细化 —人们开发新的版本,更多的功能,更高的效率,与其他工具的集成,等等。
因为我们目前正处于大数据收集的细化阶段和该数据的统计分析的广泛采用阶段,所以我们创建了一个完整的数据生态系统,其中提取的知识只是包含的总知识的一小部分。不仅许多知识还没有被提取出来,而且在许多情况下,除了建立系统的几个软件工程师之外,没有人理解数据集的全部范围和属性;唯一可能理解数据中包含的内容的人可能是那些太忙或太专业而无法利用它的人。对我来说,所有这些未被充分利用或了解甚少的数据的集合就像一个全新的大陆,有许多未被发现的植物和动物物种,一些完全陌生的生物,可能还有一些很久以前离开的文明留下的遗留结构。
这种描述也有例外。谷歌、亚马逊、脸书和
推特是走在时代前列的公司的好例子。在某些情况下,他们的行为符合创新的后期阶段。例如,通过允许访问其整个数据集(通常是收费的),Twitter 似乎正在大数据收集和使用的细化阶段运作。各地的人们都在试图从用户的推文中榨出最后一点知识。同样,谷歌似乎在以严格的统计方式分析数据方面做得很好。它在图片搜索、谷歌分析、甚至基本文本搜索方面的工作都是大规模可靠统计的好例子。然而,人们很容易认为谷歌还有很长的路要走。如果说今天的数据生态系统就像一块尚未开发的大陆,那么数据科学家就是这块大陆的探索者。就像早期欧洲著名的美洲或太平洋岛屿探险家一样,一个好的探险家擅长几件事:
- 访问有趣的区域
- 认识新的有趣的事物
- 意识到一些有趣的事情可能即将发生的迹象
- 处理新的、不熟悉的或敏感的事物
- 评价新的和不熟悉的事物
- 在熟悉的事物和不熟悉的事物之间建立联系
- 避免陷阱
一个南美丛林的探险者可能用大砍刀砍过丛林灌木丛,偶然发现了几块松散切割的石头,推断出附近有一座千年古寺,找到了这座寺庙,然后从废墟中了解到了古代部落的宗教仪式。
数据科学家可能会编写一个脚本,从公共 API 中提取一些社交网络数据,认识到一些人构成了社交活动的主要枢纽,发现这些人经常在社交网络上的帖子中提到一个新的照片共享应用程序,从照片共享应用程序的公共 API 中提取更多数据,并通过结合两个数据集和一些统计分析来了解在线社区中网络影响者的行为。
这两个案例都得出了以前不为人知的关于社会如何运作的信息。
像探险家一样,现代数据科学家通常必须调查地形,仔细观察周围环境,四处游荡,潜入一些不熟悉的领域,看看会发生什么。当他们发现一些有趣的东西时,他们必须检查它,弄清楚它能做什么,从中学习,并能够在未来应用这些知识。虽然分析数据不是一个新领域,但数据无处不在的存在——通常不管是否有人在使用它——使我们能够应用科学方法来发现和分析预先存在的数据世界。对我来说,这是数据科学与其前身之间的区别。数据太多了,没有人能完全理解,所以我们把它当作一个独立的世界,值得探索。
这种将数据视为荒野的想法是使用术语“数据科学”而不是任何对应术语的最有说服力的理由之一。为了从数据中获得真实的真相和有用的答案,我们必须使用科学方法,或者在我们的情况下,使用数据科学方法:
- 问个问题。
- 陈述一个关于问题答案的假设。
- 做一个可测试的预测,如果正确的话,提供支持假设的证据。
- 通过包含数据的实验来测试预测。
- 通过对实验结果的分析,得出相应的结论。
通过这种方式,数据科学家只是在做科学家几个世纪以来一直在做的事情,尽管是在数字世界。今天,我们一些最伟大的探险家把他们的时间花在虚拟世界中,我们可以在不离开电脑的情况下获得强大的知识。
Brian Godsey 博士,是一名数学家、企业家、投资者和数据科学家,他的书 像数据科学家一样思考 现在有印刷版和电子书。——briangodsey.com
要了解更多信息,请下载免费的第一章 像数据科学家 一样思考,并查看此 幻灯片演示文稿 了解更多信息和折扣代码。
如果您喜欢,请点击💚。
[## 数据科学的过程被低估了
编码和统计很重要,但是选择先做什么和下一步做什么也很重要
towardsdatascience.com](/the-process-of-data-science-is-underrated-87ea58d5f70c) [## 检查您对数据的假设
没有人喜欢糟糕的假设
towardsdatascience.com](/check-your-assumptions-about-your-data-20be250c143)
数据是农业的第四次革命吗?
原文:https://towardsdatascience.com/is-data-the-fourth-revolution-for-agriculture-fd62a2cdaa0e?source=collection_archive---------0-----------------------
农业的数字化转型
看看你能想到的每一个行业,你会发现它正在受到技术的影响。现在,传感器被嵌入各级设备、装置和供应链中,以测量性能并提高运营效率。
这种对有价值的实时信息的新兴访问为能够改变整个行业的创新技术和商业模式打开了大门。
农业就是这样一个行业,有可能因数据而引发大规模破坏。
这一事实在大型农业企业中并未被忽视。2013 年孟山都公司以 9.3 亿美元收购 Climate Corp 表明了一些公司对农业数据的重视。
农业数字基金会
全球定位卫星(GPS)使数据的地理参照成为可能,为所有随后的作物生产信息奠定了基础。将数据用于特定地点的作物投入最早始于 20 世纪 80 年代,当时明尼苏达大学使用土壤样本数据来改变石灰的应用。
1992 年,由领导开发的带 GPS 定位的谷物产量监测器的出现,提供了更好地了解作物性能和整个田地可变性所需的反馈。
随着 BEELINE Technologies 于 1997 年推出 GPS 免提转向系统,该领域的创新继续蓬勃发展。自那以后,各种其他创新技术、控制器和传感器应运而生,为农民经营的各个方面提供了大量数据。
精准农业
这项技术与观察、测量和响应田间变异性的能力相结合,被称为精准农业。访问空间参考数据和管理固有可变性的能力是提高大规模作物生产效率的有力工具。
由此产生的数据可以转化为可操作的见解,如种子、化学品和肥料的可变速率应用(VRA)。一旦了解了整个油田的空间变异性,就可以通过优化分配这些投入来实现显著的经济优势。
前三圈
自 20 世纪初以来,农业发生了三次革命——机械革命、化学革命和生物遗传革命。
1)机械
滑铁卢汽油发动机公司于 1893 年推出了第一台汽油动力拖拉机,这引发了第一次革命。这项技术显著提高了马和犁的效率。
2)化学
下一次革命以化学科学突破的形式出现,带来了更好的营养和作物保护产品。通过了解如何更好地喂养作物并保护其免受环境威胁,产量可以获得可观的收益。
3)生物遗传
尽管在许多领域存在很大争议,但抗某些害虫和疾病的转基因作物的引入已经导致产量的进一步增加。这场革命给农民带来的另一个有意义的好处是风险管理的改善和生产的确定性。
这三次革命的结合极大地提高了农业生产率,如今玉米的平均产量是 20 世纪 30 年代的五倍。
第四次革命
农业机械远程信息处理、无线宽带、云计算和移动设备方面的最新进展为自动化和简化精准农业的大部分复杂性提供了重大机遇。AgDNA 等新一代创新农业科技公司正在结合这些技术,自动收集、处理和交付有价值的农业信息和预测见解。
精准农业为作物生产者提供了最大限度发挥前三次农业革命潜力所必需的信息。
欢迎来到“第四次革命”。
投资回报最大化
数据已经为前三次革命带来了宝贵的经济回报。这在种植者当前的购买行为和他们不断发展的耕作方式中显而易见。
随着一些粮食商品价格目前处于 10 年来的最低水平,而农作物投入处于创纪录的高位,经营一家盈利的农业企业是很困难的。然而,尽管收入下降对大型资本购买产生了负面影响,但数据分析和相关服务的采用正在快速增长。
由于利润率如此之低,种植者转向创新软件提供商,以帮助他们优化农业运营的各个方面,并最大限度地提高盈利能力。
以下是 AgDNA 等下一代数据管理平台如何提高以往变革的投资回报的几个例子:
机械革命
通过对设备通过田地时的油耗进行空间分析,种植者和机械经销商能够优化机具与拖拉机马力的匹配。
一位加拿大种植者把他的种植机从 60 英尺增加到 90 英尺,却没有增加拖拉机的马力。由于额外的覆盖效率,数据显示他能够在播种期间将总燃料消耗减半。
化学革命
田纳西州的一位种植者使用空间数据来评估该季节各种化学应用的效果。他能够确定一种特殊的杀真菌剂在高粱上的应用,由于雨季的结果,使低洼地的产量增加了 24 bu/ac。
然而,数据分析也强调了同样的应用在高地仅实现了 3 bu/ac 的产量增加。产量的增加不足以支付施用的费用。因此,种植者能够决定在哪些地区施用杀菌剂,以获得来年的最大经济回报。
生物遗传革命
随着种子遗传学的出现,以及现在可用的各种不同的品种和杂交品种,知道哪一种最适合你的农业经营是一项艰巨的任务。通过存储数百万英亩的产量结果,并了解特定商品的相应土壤特性和其他空间属性,可以应用大数据分析技术。
现在,可以对大量数据集进行基准分析,以确定给定土壤类型和其他属性的最佳种子品种。对于种植者来说,这是非常宝贵的信息,不仅可以让他们了解什么最适合他们的农场,还可以让他们根据选择参与标杆管理服务的其他种植者的经验获得洞察力。
当这些例子结合在一块田地的适用区域中时,每英亩将返回超过 100 美元。
第五次革命
第四次革命仍处于起步阶段,我们对农业数据分析领域的可能性还只是皮毛。最近的 AgFunder 对 2016 年 AgTech 投资的审查显示,去年有 32 亿美元投资于该领域。总计 3.63 亿美元投资于农场管理软件、传感和物联网私营部门。
学术部门也在研究数据驱动的解决方案,他们正在实施创新的方法来与私营企业合作。新奥尔良的杜兰大学正在采取一种值得注意的方法,他们正在举办耗资 100 万美元的杜兰氮减排挑战赛。该竞赛旨在检验针对墨西哥湾和其他地区持续缺氧死区问题的真实商业解决方案。
在某一点上,我们将会看到第五次革命,然而最大化第四次革命的机会和巨大规模将会让这个行业在未来相当长的一段时间内保持忙碌。我将把我对第五次革命的推测留到以后的文章中。
与此同时,让我们继续拥抱数据驱动的解决方案,最大限度地提高农场盈利能力,庆祝农业第四次革命已经到来。
没有编程的深度学习可能吗?
原文:https://towardsdatascience.com/is-deep-learning-without-programming-possible-be1312df9b4a?source=collection_archive---------4-----------------------
我知道这一定是你看完标题的第一反应。
但是,当你阅读这篇文章时,我的开发人员、从业人员和爱好者的 AI 社区,你将体验到一种新的设计、部署和训练深度学习模型的方法,无需编程,通过一个免费的软件平台,免费的,免费的!!!!(是的,你没看错)
自从我开始在深度学习领域的旅程以来,我曾经在 Quora 上看到过很多问题,比如“如果我不是一名优秀的程序员,我是否仍然可以开始深度学习或找到复杂问题的解决方案”,或者“我是否可以学习 AI(人工智能),没有编程的深度学习”,大多数时候答案都以一个大粗体“ NO ”结束。我知道如果有人问我同样的问题,我的答案是"是的"这可能通过最简单的深度学习平台" 深度学习工作室 "由一家名为 深度认知 的公司创建。
Deep Learning Studio 是自 2017 年 1 月开始生产的第一个稳健的深度学习平台,有两个版本(云和桌面),具有可视化界面。该平台为数据接收、模型开发、培训、部署和管理提供了全面的解决方案。通过使用 Deep Learning Studio,从开发人员到工程师或研究人员,任何人都将通过与 TensorFlow、MXNet 和 Keras 的强大集成,获得快速开发和部署深度学习解决方案的能力。
好了,现在在向大家介绍了深度学习工作室之后,是时候展示这个软件平台实际上是如何工作的了。正如人们所说的“你应该实践你所说的”,所以出于同样的目的,Deep Cognition,Inc .的首席执行官和联合创始人 Mandeep Kumar,通过 Kaggle 帖子展示了使用 Deep Learning Studio 在 CT 扫描数据集上应用 3d 卷积神经网络的实践,其一步一步的实现如下所示。
步骤 1:获取访问权限
注册并访问深度学习工作室,网址为
[## 深度认知——今天就成为一个人工智能驱动的组织
无需编码即可设计、训练和部署深度学习模型。深度学习工作室简化并加速了…
deepcognition.ai](http://deepcognition.ai/)
[ 超级重要的一点:一旦你在 Deep Cognition 网站注册了一个免费账户,你还将获得 2 小时的免费 NVIDIA GPU 培训时间,这就是我所说的非常迷人。]
步骤 2:启用缓存数据集
然后,他通过上传从他 Kaggle 帐户下载的两个小文件,在他的帐户中启用缓存的数据集,上传这些文件确保他可以访问 Kaggle 数据集(遵循标记 1 到 4)
Figure 1
步骤 3:创建并打开一个新项目
然后,他创建了一个新项目,方法是转到左边的项目菜单,点击+按钮。
Figure 2
他给自己的项目起了一个名字和描述,然后点击项目栏上的方框+箭头图标打开项目。
Figure 3
步骤 4:选择数据集并进行训练/验证集划分
他用 1200 个样本进行了训练,并用 197 个样本进行了验证。
Figure 4
步骤 5:构建模型
选择数据集后,他点击“模型”标签,并开始建立如下所示的模型,从左侧菜单栏拖动层到画布上,并连接这些层块。
Figure 5
下面显示的代码块反映了由Mandeep Kumar**使用深度学习工作室构建的整个模型的实际生成的源代码,可以在图 5 中看到。**
def get_model():
Input_1 = Input(shape=(256, 512, 512, 1))
MaxPooling3D_27 = MaxPooling3D(pool_size= (1,3,3))(Input_1)
Convolution3D_1 = Convolution3D(kernel_dim1= 4,nb_filter= 10,activation= 'relu' ,kernel_dim3= 4,kernel_dim2= 4)(MaxPooling3D_27)
Convolution3D_7 = Convolution3D(kernel_dim1= 4,nb_filter= 10,activation= 'relu' ,kernel_dim3= 4,kernel_dim2= 4)(Convolution3D_1)
BatchNormalization_28 = BatchNormalization()(Convolution3D_7)
MaxPooling3D_12 = MaxPooling3D(pool_size= (2,2,2))(BatchNormalization_28)
SpatialDropout3D_1 = SpatialDropout3D(p= 0.5)(MaxPooling3D_12)
Convolution3D_9 = Convolution3D(kernel_dim1= 2,nb_filter= 20,activation= 'relu' ,kernel_dim3= 2,kernel_dim2= 2)(SpatialDropout3D_1)
Convolution3D_11 = Convolution3D(kernel_dim1= 2,nb_filter= 20,activation= 'relu' ,kernel_dim3= 2,kernel_dim2= 2)(Convolution3D_9)
BatchNormalization_9 = BatchNormalization()(Convolution3D_11)
MaxPooling3D_14 = MaxPooling3D(pool_size= (2,2,2))(BatchNormalization_9)
SpatialDropout3D_4 = SpatialDropout3D(p= 0.5)(MaxPooling3D_14)
Convolution3D_12 = Convolution3D(kernel_dim1= 2,nb_filter= 40,activation= 'relu' ,kernel_dim3= 2,kernel_dim2= 2)(SpatialDropout3D_4)
Convolution3D_13 = Convolution3D(kernel_dim1= 2,nb_filter= 40,activation= 'relu' ,kernel_dim3= 2,kernel_dim2= 2)(Convolution3D_12)
MaxPooling3D_23 = MaxPooling3D(pool_size= (2,2,2))(Convolution3D_13)
BatchNormalization_23 = BatchNormalization()(MaxPooling3D_23)
SpatialDropout3D_5 = SpatialDropout3D(p= 0.5)(BatchNormalization_23)
GlobalMaxPooling3D_1 = GlobalMaxPooling3D()(SpatialDropout3D_5)
Dense_1 = Dense(activation= 'relu' ,output_dim= 10)(GlobalMaxPooling3D_1)
Dropout_14 = Dropout(p= 0.3)(Dense_1)
Dense_6 = Dense(activation= 'relu' ,output_dim= 10)(Dropout_14)
Dense_2 = Dense(activation= 'softmax' ,output_dim= 2)(Dense_6)
return Model([Input_1],[Dense_2])
因此,我的读者朋友们,现在你明白了如何在 Deep Learning Studio 软件平台中使用简单的拖放 GUI,你也可以在没有编程的情况下构建一个模型,嗯,这并不是所有的“超参数”的培训和调整都可以在没有编程的情况下完成,只需看看下面的后续步骤,并用你自己的眼睛感到惊讶。
第六步:培训和结果
然后,他点击“超参数”选项卡,并确保批量设置为 1。这一点很重要,因为任何更大的东西都不适合 GPU 内存,训练也会失败。
Figure 6
最后他转到了“培训”选项卡。选择 GPU-K80 作为实例,点击“启动实例”。一旦实例启动,他就点击开始训练。请注意,由于数据集的庞大规模和所需的计算,训练将会非常缓慢。
在尝试了 2 个时期之后,他能够在验证集上得到大约 0.58 的损失。
Figure 7
在制作模型之前,他还对 CT 扫描数据集做了一些预处理,因此关于他建立的模型的直觉和关于他采取的预处理步骤的全部信息可以在这里找到。
因此,这标志着我让你们了解市场上这种新软件平台的旅程的结束,这种平台通过拖放 GUI 简化并加速了深度学习的过程,并允许你们所有人设计、训练和部署深度学习模型,而不涉及编码。但是不要忘了看一下参考资料部分,里面有其他令人兴奋的资源供您参考。
参考资料:
- 为了了解更多关于深度学习的知识,可以查看这里。
- 如果你想看一下由 Deep Cognition,Inc .主办的网络研讨会“深度学习简介”,他们邀请了法维奥·巴斯克斯做一次演讲,你可以点击这里查看。
- 如果你想阅读其他基于使用深度学习工作室建立深度学习模型的文章,你可以在这里查看。
- 最后但同样重要的是,你可以在这里查看使用深度学习工作室开发不同模型的 YouTube 视频。
感谢您的关注
你用你的时间来阅读我的工作对我来说意味着一切。我完全是这个意思。
如果你喜欢这个故事,疯狂鼓掌吧👏 ) 按钮!这将有助于其他人找到我的工作。
还有,跟我上** 中Linkedin如果你想!我很乐意。******
数字讲故事是数据科学的未来吗…
原文:https://towardsdatascience.com/is-digital-storytelling-the-future-of-data-science-af55e26c23e3?source=collection_archive---------11-----------------------
..或者仅仅是商业交流中的一时风尚?
视频技术的最新发展在很大程度上推动了大数据的兴起——到今年年底,在线视频将占全球互联网流量的 80%。在我们关于数字转型的课程中,我们强调视频图像在数据科学的现在和未来中的重要性。我们一直在使用在线视频创作平台 Moovly 来帮助我们的学生和教师实践我们在介绍他们的案例研究、课程和项目时所宣扬的内容。让我们花一些时间来探讨数字讲故事的概念,视频的细节,我们自己对 Moovly 的使用,以及我们对为什么视频在未来几个月将在企业数字战略中占据越来越大的位置的看法。
数字故事讲述是围绕数据集构建故事的实践,有助于以强有力和引人注目的方式传达数据的含义。正如 iRobot 数据科学主管安吉拉巴萨(Angela Bassa)所指出的那样,“数据科学的很大一部分是在试图[传达]分析结果时进行沟通或说服”。很久以前,Claude Lévi-Strauss 和 Vladimir Propp 等人类学家证明了我们讲述的故事的结构的重要性——故事的意义来自于故事是如何组织起来的,而不是数据本身。最近对传统和商业故事的研究证明了这些叙事结构的普遍性。[iii] 人类的交流既受到我们如何处理经验的制约,也受到冷酷无情的事实的制约。
BAI Summer School on Data Science for Management
摄像是指在电子媒体上捕捉活动图像的制作过程。它在许多方面不同于传统的电影制作。首先,数字技术的进步塑造了这个领域:今天许多摄像师完全在电脑、平板电脑或电话上制作他们的作品,从来没有涉及到成像设备。专为社交媒体渠道设计的视频迎合了特定的消费模式。从商业角度来看,公司越来越依赖数字财产来获取和影响用户体验。他们认为需要制作越来越多的视频,因此青睐低成本、灵活和接近实时的视频制作流程。这表明该行业仍处于起步阶段,因为对数据叙事有效性的担忧仍是例外,而非普遍现象。
出于所有这些原因,Moovly 已经被证明是我们教学方法的一个极好的选择。由布兰登·格鲁内瓦尔德和吉尔特·科彭斯创建的 Moovly 是一个基于云的数字媒体和内容创作平台,它极大地促进了动画视频和演示文稿的创作。在课堂内外,我们的学生和教师一直在使用该软件制作视频案例研究、课程简历和项目描述。该应用程序的界面提供了一个实时编辑工作室,该工作室在多媒体混搭的制作中得到了很好的应用,用于构建预告、动画序列和信息叠加。由于有大量的模板、模型和示例,学习曲线被证明是非常短的。Moovly 的直观性使我们能够将大部分课堂时间集中在启发式、格式塔原则、数据故事和视觉交流的讨论上。
“Un problème de communication”
为什么在数据科学的研究中包括摄像?改善决策所需的数据不仅仅在屏幕后面,还存在于你的客户和同事的头脑和经历中。视觉传达解决了我们如何处理数据的更大问题。从生物学上来说,大脑皮层中的梭形面部区域是人类视觉系统的一部分,它允许我们将我们看到的数据与我们自己的经历联系起来。视觉和听觉线索通过增加信任和接近的感觉,给每个故事增加了人情味。非语言交流在很大程度上是普遍的——快乐、愤怒、惊讶和期待的表达在不同的文化中都是一样的。移动增加观众的注意力,摄像机移动有助于增强每个场景:增加戏剧性,跟随动作,引导观众的注意力,揭示关键细节。
“BAI Data Storytelling Syllabus”
视频是否将商业数据带入生活?根据 Mayer 和 Anderson 的研究,观众视觉和听觉的刺激增加了他们对研究主题 74%的理解。马特·杨认为,观众在观看视频时能记住 95%的信息,相比之下,在阅读文本时只能记住 10%。商务视频在网络上越来越受欢迎;《福布斯洞察》显示,75%的企业高管每周至少观看一次与工作相关的视频。最后,Troy Anderson 认为,视频在社交媒体营销中的使用将社交媒体访问者购买产品、服务或想法的可能性提高了 64%。【VI】数据科学团队的成功不是由他们的技术悟性来衡量,而是由他们影响管理决策的能力来衡量。
将数据转化为有效的行动是商业分析研究所的核心和灵魂。我们 2018 年的 白暑期项目 将探索利用数据科学提高管理决策的关键技能。这个独特的夏季会议将为来自五大洲的四十多名参与者提供对使用分析实践的坚实理解,包括如何评估手头的数据,如何将适当的方法应用于特定类型的个人和专业挑战,以及如何利用数据改善管理决策。
Lee Schlenker 是商业分析和数字化转型教授,也是 http://baieurope.com商业分析研究所的负责人。他的 LinkedIn 个人资料可以在www.linkedin.com/in/leeschlenker查看。你可以在 https://twitter.com/DSign4Analytics 的推特上关注我们
【我】思科,(2017) 思科视觉联网指数
【ii】s woyer,S. (2017),通过大量数据讲述故事,加深理解
【iii】例如,见 Hogan,P.C. (2003 年)。心灵和它的。故事:叙事共性和人类情感。纽约:剑桥大学
【iv】【福布斯洞察】(2010 年)高管们拥抱非文本网络
【v】Young,m .(2016),看事实——为什么视频内容留存率最高
【VI】t . Anderson,(2016),什么使得视频营销策略值得拥有?
谷歌 Duplex 是否符合伦理道德?
原文:https://towardsdatascience.com/is-google-duplex-ethical-and-moral-f66a23637640?source=collection_archive---------8-----------------------
昨天,在 Google IO 期间,一个名为 Duplex 的项目通过电话在对 Google 助手的请求和真实世界中的真实业务之间建立了接口。
你可以在这里看到令人印象深刻的演示:
AI 社区的许多人立即欢呼这是这些技术结合的巨大进步。
然而,有一些担忧:
虽然我总是有点怀疑对一项没有被用来做坏事的技术的任何普遍和直接的反弹,但关于这一点有非常好的观点应该讨论。
这合乎道德吗?
上周,我开始了微软 edX 的在线课程,名为“数据和分析中的道德和法律我最感兴趣的是他们看待伦理价值的一个非常简单的框架。
它分为两个价值集:1)基于他人福祉的价值(在这种情况下是在公司接到电话的人)和 2)基于我自己福祉的价值(谷歌和我的混合物)。关于他人的幸福,它包括:不痛苦、自主、平等。我自己的幸福集中在优秀的品格和信任上。
让我们逐一了解这些值:
- 无痛苦——在这种情况下,接听电话的人似乎不会以某种方式遭受痛苦。如果有什么不同的话,我敢打赌,这部机器会以一种一致的方式更加礼貌,并且直奔主题,这样人们就不会没完没了地打电话。
- 自主性——接听电话的人仍然可以做出他们认为合适的反应,他们可以问他们需要的问题,他们甚至可以拒绝接听电话。
- 平等 —有一种可能性是缺乏平等,因为我使用这样的服务来节省我的时间,但不尊重接收者的时间。一个很好的问题是,对于那些不尊重我通过支持自动化系统在时间上平等的愿望的企业,我们如何权衡这一点?
- 人品卓越 —如果它确实宣布这是代表我的助理预订,我看不出这对我的人品卓越有什么损害。
- 信任 —这是最有问题的价值观。随着越来越多这样的电话被拨打,人们会相信 Duplex 或任何他们自称的呼叫者吗?
道德吗?
谷歌有这项服务道德吗?可能吗?我不认为他们试图用这项技术来“作恶”。
有人使用这项服务道德吗?大概?这是基于他们的道德准则,他们也持有自己。不幸的是,我们都倾向于在不同时间持有不同道德的大杂烩。
在社会中,我们确实试图从道德上思考自己,但这实际上是法律强制执行的问题,因为除了 Twitter 上的人群呼喊之外,没有道德法庭。
合法吗?
根据我对 robocalls 的了解,是的,这是合法的。例如,对于“大量收件人”来说,它不是“不相关或不适当的”
然而,我不确定企业是否可以从技术上完全拒绝这类电话。
这是否意味着我们应该监管这些技术?大概吧。尽管如此,魔鬼绝对存在于细节之中…
虽然这是一个伟大的点,关于如何规范类比不是 100%。我们为天然气这样做不是因为这是道德/伦理的事情,而是因为它是危险的。
我最大的担忧是,当涉及到州强制规定时,它们只会让谷歌的地位更加稳固。他们有资金/时间/人员来支持采用这些标准。较小的公司由于资源有限,没有竞争力。
是以人为中心吗?
我发现这个问题更容易回答,我打赌这就是谷歌创造 Duplex 的原因。这对圈内的每个人都有帮助。
对于想要预订的人来说,他们可以节省打电话和与商家谈判的时间。这就是像无缝这样的服务如此受欢迎的原因。
对于接到电话的人来说,他们正在为一家不想以某种方式允许自动预订的公司工作。这是系统与之交互的最简单的方式。只是刚好是语音。
一个很大的问题是,企业是否应该选择退出这种类型的界面。当然,这可能会引起客户的敌意,但这是他们经营业务的选择。
有人问过在企业工作的人是否会介意吗?他们会在乎吗?
坏人呢?
大多数人关心的是其他人可能利用这项技术作恶的方式。例如,我们可以想象你可能开始接到机器人的电话,这些机器人专注于向你出售分时度假,通过要求虚假付款来欺骗你,以及一般的数据捕获。
一项技术的所有不好的使用是否意味着我们不应该拥有这项技术?事实显然并非如此。这方面的一个稻草人将是用于恐怖袭击的汽车是否应该被禁止。当然,汽车带来的好处超过了这个非常小的案例。
细微差别
如果有的话,这是一个棘手的话题。需要对上下文进行细微的区分。
这将会引起很多愤怒和偏袒。
我们应该进行这些讨论,我们应该谈谈,在我们生活的这个混乱的世界里,相信我们所相信的东西意味着什么。
我很想听听你的想法。
关于克里斯·巴特勒
我帮助团队理解他们应该用以人工智能为中心的解决方案解决的真正的商业问题。我们工作的团队通常被要求用他们拥有的数据“做一些有趣的事情”。我们通过偶发事件相关性帮助他们避免局部极值,并专注于解决巨大的业务问题。我的背景包括在微软、KAYAK 和 Waze 等公司超过 18 年的产品和业务开发经验。在 Philosophie,我创造了像机器的移情映射和困惑映射这样的技术,以便在构建人工智能产品时创建跨团队的一致性。如果你想了解更多或通过、、LinkedIn 或访问、http://philosophie.is/human-centered-ai与联系。
Google Tensorflow 物体检测 API 是实现图像识别最简单的方法吗?
原文:https://towardsdatascience.com/is-google-tensorflow-object-detection-api-the-easiest-way-to-implement-image-recognition-a8bd1f500ea0?source=collection_archive---------1-----------------------
用数据做酷事!
有许多不同的方法来进行图像识别。谷歌最近发布了一个新的 Tensorflow 对象检测 API,以推动计算机视觉无处不在。谷歌提供的任何服务都不能掉以轻心,所以我决定尝试一下这个新的 API,并在 you tube 的视频上使用它:)参见下面的结果:
Object Detection from Tensorflow API
你可以在我的 Github repo 上找到完整的代码
我为这个项目添加了第二个阶段,在这个阶段,我在自定义数据集上使用 Tensorflow 对象检测 API 来构建我自己的玩具飞机检测器。你可以查看我的文章
https://medium . com/@ Priya . DWI vedi/building-a-toy-detector-with-tensor flow-object-detection-API-63c 0 fdf 2 AC 95
那么这种体验是什么样的呢?首先让我们理解 API。
了解 API
API 已经在 COCO 数据集(上下文中的公共对象)上进行了训练。这是一个包含 90 个最常见物体的 30 万张图片的数据集。对象的示例包括:
Some of the object categories in COCO datset
该 API 提供了 5 种不同的模型,这些模型在执行速度和放置边界框的准确性之间提供了一种平衡。请参见下表:
这里 mAP(平均精度)是检测包围盒的精度和召回率的乘积。这是一个很好的综合措施,可以衡量网络对感兴趣的对象有多敏感,以及它如何避免错误警报。mAP 得分越高,网络越精确,但这是以执行速度为代价的。
您可以通过此链接获得关于这些型号的更多信息
使用 API
我决定试试最轻量级的型号(ssd_mobilenet)。主要步骤是:
- 下载冻结模型(。pb — protobuf )并将其加载到内存中
- 使用内置的帮助器代码来加载标签、类别、可视化工具等。
- 打开一个新会话,并在映像上运行模型
总的来说,这是一套相当简单的步骤。API 文档还提供了一个方便的 Jupyter 笔记本来完成主要步骤。
该模型在样本图像上具有相当好的性能(见下文):
在视频上跑步
接下来我决定在一些视频上尝试这个 API。为了做到这一点,我使用了 Python moviepy 库。主要步骤是:
- 使用 VideoFileClip 功能从视频中提取图像
- fl_image 函数是一个很棒的函数,它可以获取一个图像并用修改后的图像替换它。我用这个对从视频中提取的每张图像进行物体检测
- 最后将所有修改后的剪辑图像组合成一个新的视频
对于一个 3-4 秒的片段,这段代码需要一点时间来运行(大约 1 分钟)。但由于我们使用的是加载到内存中的冻结模型,所有这些都可以在没有 GPU 的计算机上完成。
印象非常深刻!只需一点点代码,您就可以在大量常见的对象上以相当高的精度检测并绘制边界框。
在有些情况下,我觉得表演还可以更好。参见下面的例子。这段视频中根本没有检测到鸟类。
后续步骤
关于进一步探索这个 API 的一些额外想法
- 尝试更精确但开销大的模型,看看它们能带来多大的不同
- 找出加速 API 的方法,以便它可以用于移动设备上的实时对象检测
- Google 还提供了使用这些模型进行迁移学习的能力,即加载冻结的模型并添加另一个具有不同图像类别的输出层
给我一个❤️,如果你喜欢这个职位:)希望你拉代码,并尝试自己。
我有自己的深度学习咨询公司,喜欢研究有趣的问题。我已经帮助许多初创公司部署了基于人工智能的创新解决方案。请到 http://deeplearninganalytics.org/的来看看我们吧。
你也可以在https://medium.com/@priya.dwivedi看到我的其他作品
如果你有一个我们可以合作的项目,请通过我的网站或 info@deeplearninganalytics.org 联系我
参考文献:
- Google Tensorflow 物体检测 Github
- COCO 数据集
高级人工智能的创新是天启吗?
原文:https://towardsdatascience.com/is-innovation-in-advanced-ai-the-apocalypse-adcada6a5518?source=collection_archive---------7-----------------------
如果你设想未来,它是暗淡的。世界正面临巨大的政治、经济和环境压力。真的很难知道最怕什么。甚至人类的存在都是不确定的。威胁来自许多潜在的方向:全球变暖,小行星撞击,一种新的疾病,或者机器把一切都变成灰尘。
人工智能是另一个巨大的威胁。“全人工智能的发展可能会导致人类的终结……它会自己起飞,并以越来越快的速度重新设计自己。人类受到缓慢的生物进化的限制,无法竞争,并将被取代”告诉斯蒂芬·霍金接受 BBC 采访。去年,他补充道“人工智能可能是发生在人类身上最好或最糟糕的事情”。
此外,包括比尔盖茨、埃隆马斯克和史蒂夫沃兹尼亚克在内的科技巨头的高管也对人工智能做出了类似的预测。然而,数十亿美元投资于人工智能研究。并且取得了巨大的进步。2016 年 3 月,“有史以来最不可思议的比赛之一”, AlphaGo 程序在最后一场比赛中战胜韩国围棋大师李·塞多尔,以 4 比 1 赢得系列赛。在许多其他领域,从在地面上驾驶汽车到赢得空中格斗,计算机开始取代人类。
霍金的恐惧围绕着技术奇点的概念。这是机器智能开始起飞的时间点,一个新的更聪明的物种开始居住在地球上。我们可以将技术奇点的概念追溯到许多不同的思想家,包括计算机的创始人之一约翰·冯·诺依曼和科幻小说作家弗诺·文奇。这个想法与人工智能本身的研究年代大致相同。1958 年,数学家斯塔尼斯瓦夫·乌拉姆写了一篇赞颂冯·诺依曼的文章,其中他回忆道:“一次谈话集中在技术的不断加速进步和人类生活方式的变化上,这似乎接近了某种本质上的奇点……超过这一点,我们所知道的人类事务就无法继续下去了”(《美国数学学会公报》,第 64 卷,第 1 页)。
最近,雷·库兹韦尔(Ray Kurzweil)和尼克·博斯特罗姆(Nick Bostrom )提出了技术奇点的概念,他们预测奇点将在 2045 年左右发生,并就其后果写了一本畅销书。有几个理由担心机器在智力上超越我们。人类之所以成为这个星球上的主导物种,很大程度上是因为我们非常聪明。许多动物比我们更大、更快或更强壮。但是我们用我们的智慧发明了工具、农业和令人惊叹的技术,如蒸汽机、电动机和智能手机。这些改变了我们的生活,让我们能够主宰这个星球。
因此,毫不奇怪,会思考的机器——甚至可能比我们思考得更好——可能会篡夺我们的权利。正如大象、海豚和熊猫依靠我们的善意才能继续生存;反过来,我们的命运可能取决于这些高级思维机器的决定。
智能爆炸的想法,即机器递归地提高它们的智能,从而迅速超过人类的智能,并不是一个特别疯狂的想法。计算领域从许多类似的指数趋势中获益匪浅。摩尔定律预测,集成电路上的晶体管数量每两年就会翻一番,几十年来几乎都是如此。因此,假设人工智能也将经历指数增长并不是不合理的。
就像我在人工智能领域的许多熟人一样,我预测,人工智能距离实现超人智能只有 30 或 40 年的时间。但有几个强有力的理由说明技术奇点不可能出现。
“智力极限”的争论
宇宙中有许多基本的限制。有些是物理上的:你无法加速超过光速,无法完全准确地知道位置和动量,也无法知道放射性原子何时会衰变。我们建造的任何思维机器都会受到这些物理定律的限制。当然,如果那台机器本质上是电子的,甚至是量子的,那么这些极限很可能会超出我们人类大脑的生物和化学极限。然而,人工智能很可能会遇到一些根本性的限制。其中一些可能是由于自然界固有的不确定性。无论我们多么努力地思考一个问题,我们决策的质量都是有限的。在预测下一次欧洲百万乐透的结果方面,即使是超人的智慧也不会比你强多少。
关于“思维敏捷的狗”的争论
硅比我们大脑的湿件具有显著的速度优势,根据摩尔定律,这种优势大约每两年翻一倍。但是速度本身并不能增加智力。即使我能让我的狗思考得更快,它仍然不太可能下棋。它没有必要的心理结构、语言和抽象概念。史蒂芬·平克雄辩地阐述了这一观点:“纯粹的处理能力并不能神奇地解决你所有的问题。”
智慧不仅仅是比别人思考问题更快或更久。当然,摩尔定律帮助了 AI。我们现在学得更快,提供了更大的数据集。更快的计算机肯定会帮助我们建立人工智能。但是,至少对人类来说,智力取决于许多其他因素,包括多年的经验和训练。我们还不清楚是否可以简单地通过提高时钟速度或增加更多的内存来缩短这一过程。
“计算复杂性”的争论
最后,计算机科学已经有了解决不同问题的难度的成熟理论。有许多计算问题,即使是指数级的改进也不足以帮助我们实际解决它们。计算机无法分析某些代码并确定它是否会停止——这就是“停止问题”。计算和人工智能之父艾伦·图灵(Alan Turing)著名地证明了这样一个问题通常是不可计算的,无论我们让计算机分析代码有多快或多聪明。转而使用量子计算机等其他类型的设备会有所帮助。但是这些只能提供超越经典计算机的指数级改进,不足以解决像图灵停顿问题这样的问题。有假想的超级计算机可能会突破这种计算障碍。然而,这种装置是否存在仍有争议。
未来
因此,有很多原因可以解释为什么我们可能永远不会见证一个技术奇点。但是,即使没有智能爆炸,我们也可能最终拥有表现出超人智能的机器。我们可能不得不自己痛苦地编写大部分程序。如果是这样的话,人工智能对我们的经济和社会的影响可能不会像霍金等人担心的那样迅速发生。然而,我们应该开始为这种影响做准备。
即使没有技术奇点,人工智能也可能对工作性质产生巨大影响。许多工作,像出租车和卡车司机,可能会在未来十年或二十年消失。这将进一步增加我们今天在社会上看到的不平等。即使相当有限的人工智能也可能对战争的性质产生很大的影响。机器人将使战争工业化,降低战争壁垒,破坏当前的世界秩序。他们将被恐怖分子和流氓国家用来对付我们。如果我们不想和终结者同归于尽,我们最好尽快在战场上禁止机器人。如果我们做对了,人工智能将帮助我们变得更健康、更富有、更快乐。如果我们弄错了,人工智能很可能是我们犯过的最严重的错误之一。
跟着我:
推特 : @Deepakv_raj
脸书 : deepakamirraj
LinkedIn:deepakaraj
是数据科学荒还是领导力荒?
原文:https://towardsdatascience.com/is-it-a-data-science-shortage-or-a-leadership-shortage-a07ad9484f55?source=collection_archive---------12-----------------------
我有时觉得自己好像在电影《土拨鼠日》里。除了公司如何运行他们的数据科学实践。一家公司雇佣了一些能够很好地编码的聪明人,他们把钥匙交给这个人去“构建未来”几个月或几年后,工作变得一团糟,因为没有在最后期限前完成而被指指点点。发生了什么事?该公司没有考虑到他们需要一个数据领导者,而不仅仅是数据科学家。
如今,似乎每家公司都有一名数据科学家。甚至一些位于美国中西部玉米地里的公司也有一名数据科学家。然而,这些公司中的大多数都未能让这些数据科学家为公司生产出任何实质性的东西。有些人相信数据科学家会神奇地发现如何在没有任何真正的指导或领导的情况下运行一个高效的业务团队。然后他们就像我知道的一家公司一样,已经做了 4 年的定价模型,但仍然没有任何截止日期。为什么?没有真正的领导者管理团队。
数据科学或数据领导力
我经常和招聘人员交谈,他们要么希望我加入他们客户的团队,要么让我帮他们找人。我很乐意交谈。当谈到高层时,我们谈论的角色通常会有“他们想要一个亲力亲为的领导者”的说法。我不得不经常问,这意味着什么?如果我得到的回答是“会编码的人”,我会礼貌地告诉他们,他们想要的不是一个领导者,而是一个高级数据科学家,这和数据领导者是不一样的。
如果你希望有人编码,那很好,但是说实话,你需要一个编码员。一个领导不做太多编码。不是因为这个人不能,而是因为有很多其他的事情需要去做,而且通常领导是唯一能做的人。谁在管理专利战略、法律战略、P&L、环境要求、人员配备要求、业务案例一致性、公司战略一致性、路线图(真正的路线图,不是 sprint 计划,有些人称之为路线图)。通常,员工中没有人对数据有足够的了解来承担这些任务,但随着时间的推移,它们变得越来越重要。那么,为什么你会希望有人整天编码,这样你就可以有麻烦,因为你没有做专利搜索,以确保你没有侵犯现有的专利?或者也许你真的希望在这个月违反 GDPR?或者你想要一个编码器,这样就没有人真正关注你为什么要在第一时间编码?这里差别很大。一个许多公司艰难地发现的问题。
成立一个数据实践而非数据科学团队
大多数公司仍在努力理解数据。他们可能理解软件、硬件、实物,但这通常不会转化为理解数据和数据语言。为什么相关性如此重要?什么是过滤气泡?关于数据的异托邦怎么样?大多数高管无法回答这些问题,大多数数据科学家也无法在不查找的情况下回答这些问题。更少有人能真正将这些概念用于推动业务增长。除此之外,数据实践是关于改变一个组织的文化,这需要数学和编码之外的技能,很多数学和编码之外的技能。如果您的团队没有实现目标,那是因为您没有数据领导者。
数据领导者就是要建立正确的数据文化。一种侧重于业务对象,通过使用数据来改善客户体验(b2B 和 B2C)。这涉及到的不仅仅是编码,事实上我认为编码是最简单也是最不重要的问题。你将面临法律和合规问题。确保团队在开发算法时不违反专利、客户隐私或任何法规是这项工作非常重要的一部分。如果你只是编码,你就做不到这一点。数据领导者需要能够审查代码和模型,但需要花费大量时间审查专利和监管问题,而大多数数据科学家花在这方面的时间为零。
数据领导者需要关注数据流和性能。我认识很多数据科学家,他们认为自己了解这一部分,但实际上这是一种工程实践。数据领导者需要了解这一点,并每天围绕购买还是构建做出决策。关注平台的性能以及它在所构建的数据产品生命周期中的可行性。我有很多数据科学家告诉我,他们可以做这项工作,但转身承认他们已经超出了自己的能力范围。事实上,有一次,有人想要我们的 AWS,并告诉我每月只需 1600 美元。结果账单是那个的 15 倍,因为他不知道如何询问实际工作的成本。幸运的是,我们在事情发生前阻止了它。
数据领导者需要创造一种学习文化。同样,许多数据科学家说他们知道如何做到这一点,对于他们自己,我同意,他们确实知道。但是你不能创造一个受过教育的团队。你需要一种学习者的文化。建立一个允许学习和不断提高个人技能的结构是数据领导者的一个关键角色。
数据领导者需要建立适合团队发展的流程。随着团队的成长和承担更多的责任,他们必须从一个刚起步的团队成长为一个更成熟的团队。如何市场响应他们的产品也在变化,一个好的数据领导者了解这个生命周期,并为团队的各个阶段建立可靠的流程。我见过许多数据科学家大失败,因为他们不明白他们需要引导他们的团队通过的成长阶段。
数据领导者明白数据团队不仅仅是工程师和数据科学家。我经常看到这种情况,一个团队建立了一个推荐者,但他们的团队中没有任何来自 UX 的人。他们不会使用人物角色,即使他们使用了,他们也不会真正欣赏他们。大错特错。我的基础数据团队总是有 UX,而我的更复杂的已建立的团队有社会科学技能、商业技能、法律技能、离线团队成员技能等……为什么?数据通常是人类活动的一种表现形式。没有对人类的理解,你就不会真正了解你的数据。
数据领导者对于数据科学实践的成功非常重要,然而大多数公司都没有雇佣数据领导者,只是雇佣会编码的数据科学家。去年,我看到几项研究表明,80–90%的数据项目无法满足业务目标。这是为什么呢?在我看来,他们没有一个数据领导者来管理团队。如果你想在数据实践中取得成功,就找一个数据领导者。差别是巨大的。这里有一个例子:
我为一个客户工作,他花了两年时间开发一个数据产品。他们有很多数据科学家,很多都有博士学位。然而,该项目没有交付,花费了 1000 万美元,不知道该项目何时才能完成。我被叫去了。我立刻以流水作业的方式组织了团队。我们根据团队的能力设定期限。审查代码是为了确保它不会违反任何专利或法律。测试环境被简化,以便在不牺牲必要测试的情况下,尽可能快地从生命验证阶段进入生产阶段。并且建立了财务预测和业务目标。
六个月后,该产品上市了。需要进行少量的返工,今年将再损失 1000 万美元的成本,现在的目标是今年实现 1.55 亿美元的收入,投资回报率良好。这就是一个优秀的数据领导者为公司所做的事情。
想了解更多,随时联系我。
好吃吗?我喜欢好的东西
原文:https://towardsdatascience.com/is-it-good-i-like-whats-good-2f01212c6e9d?source=collection_archive---------6-----------------------
RecSys Week 2:一种基于项目相似度的推荐系统预测方法。
正如我们可以在推荐系统上下文中搜索相似的用户、评级一样,也可以找到相似的项目。与基于用户的协同过滤(CF)中的推理相同,相似的用户会喜欢相似的项目,用户会喜欢与他们已经喜欢的项目相似的项目。
有不同的函数来计算项目之间的相似性,一些函数完全集中在项目上,而另一些函数考虑了用户的评级行为。在我们得到每对项目之间的相似性之后,可以通过加权求和、线性回归或其他方法来预测新的评级。
由于项目在数量和动态性上通常远不如用户,这种方法的一个好处是可以预先计算相似性。新项目的添加不影响之前的计算,之前的计算可以定期更新,以纳入收集的新评级信息。
这无疑是对基于用户的 CF 所需要的改进,但仍然是项目总数的二次量。在这种方法中,我们还可以仅跟踪具有最高相似性的项目,这些项目在生成预测时具有最重的权重,并且减少丢弃其他项目所使用的大小。
但是我们能减少多少预先计算的数据呢?在作者做的实验中(见结尾),使用所有相似性的 96%的准确性是通过仅使用 1.9%的项目实现的,这是在准确性略有损失的情况下在记忆方面的巨大进步。
那表演呢?与传统的基于用户的 CF 相比,基于项目的方法的误差总是低于 200 个邻居(这是记录的结果)。所以这种方法在各方面看起来都更好。
Source: http://www.huffingtonpost.kr/2016/01/18/story_n_9013402.html
但是我认为这个实验有一个很大的缺陷,它只是一个电影数据库。我认为,尽管有些人可能更喜欢动作片或喜剧片,但电影的好坏总有一个相似之处。所以,通常情况下,好电影会有好的收视率,而坏电影,收视率很差。由此,我认为由该推荐系统完成的工作非常方便,因为它具有该方法假设的特征。
我并不认为这种方法不能使用,它确实在实验中使用了一个大而真实的数据集,但我认为所提出的算法,只考虑项目排名,不会在更异构的任务中工作。例如,预测 Amazon.com 的产品评级,有大量的类别和大量不同的购物者。
最后,我想重申,论文中提出的算法当然有用例,但除了从评级中寻找其他考虑项目特征的相似性函数,可能有更广泛的用途,并且仍然具有作者发现并建立在他们提出的方法上的好处。
感谢你的阅读,我将感激地接受任何更正、评论或相关阅读。这篇文章是对 Badrul Sarwar,George Karypis,Joseph Konstan 和 John Riedl 撰写的论文 基于项目的协同过滤推荐算法(2001)的评论。这是智利天主教大学推荐系统课程(IIC3633)的每周帖子。
现在是数据民主化的时候了吗?
原文:https://towardsdatascience.com/is-it-high-time-for-data-democratization-2e4e16a5356e?source=collection_archive---------12-----------------------
获得竞争优势的方法之一是让数据变得越来越容易访问。这与数据分析师和科学家是唯一有能力理解公司数据的人相反。归根结底,这些专家并不便宜。
正如所料,数据民主化有利也有弊。这些将在下面讨论。
反对数据民主化的论点
很长一段时间以来,许多人对数据管理持保守观点,认为数据的严格分析应该留给数字分析师和数据科学家。严格的治理也将适用于数据的收集、解释和传播。通过这种方式,负责处理数据的数据科学小组将承担责任。
人们有各种各样的理由相信获取信息应该受到限制。例如,他们可能认为这将确保更严格地控制潜在的风险数据,如档案、机密记录和给公司带来明显声誉或竞争优势的信息。此外,由于数据专家使用先进的建模技术和多个数据集来分析问题,因此人们认为限制可以确保在提出建议时进行更严格的审查。
数据民主化允许访问多个数据源和数据消费群体,从而呈现多个版本的“真相”,这是一个可能导致信心丧失和建议减少的因素。公司内不同团队的个人访问数据也会导致昂贵的冗余功能。隐私问题也出现了,因为较少的治理可能会导致侵犯隐私以及监管控制。
数据民主化的论据
然而,在最近的过去,公司已经意识到对数据采取协作和整体方法的重要性。这意味着,组织中的每个人都应该对数据有足够的了解,以便做出深思熟虑的决策。此外,数据民主化的支持者认为,责任在于数据的用户。
数据管理和访问方面的进步(如数据民主化)提高了用户管理、转换和解释数据的能力。那些有权访问所述数据的人也有机会添加他们的输入,为不同的分析和商业智能平台提供消费和分析。此外,向不同工作团队中的个人分发信息促进了创业精神,对中小企业尤其有利,因为它们比大企业更灵活,受管制更少。
民主化还可以帮助中小企业中精通数据的利益相关者减少对集中式分析团队的依赖。通过访问数据,中小型企业还可以发现他们可能错过的潜在盈利业务机会。此外,通过利用数据有效地消除猜测,他们可以降低获取客户的成本,并做出基于事实的投资决策。
有助于推动数据民主化的创新
为了让非专业人士更好地理解数据,技术上已经有了许多进步。这些创新也有助于提高大数据的可管理性。这里,我们讨论的是云存储、数据联合软件和数据可视化软件。
云存储是帮助适应数据民主化的工具之一。有了一个可在线访问的中心位置,所有授权用户都可以使用存储在那里的数据做出明智的决策。尽管存在与云服务相关的安全风险,但可以通过加密协议将其降至最低。
数据联邦软件也极大地促进了数据民主化。该软件有助于将不同来源的数据组合起来,并将其存储在虚拟数据库中。然后,这些数据可以用于商业智能分析和其他分析。不是在虚拟数据库中创建数据,而是有关于数据及其位置的元数据。
不了解技术细节的个人可以使用数据可视化软件来检索和操作数据。它将文本和数字数据转换成表格、图形和可视化图表。例如,企业可以使用该软件来展示访问者的活动。
总结
组织内的决策直接受到手头数据的影响。多年来,让业务分析师、营销人员和高管以及其他员工通过数据专家已经成为一种常态。事实上,有些人认为什么都不应该改变,而其他人认为是时候提高数据的可访问性了。在所有推动数据民主化的软件解决方案中,后者极有可能胜出。
LDA 是降维技术还是分类器算法?
原文:https://towardsdatascience.com/is-lda-a-dimensionality-reduction-technique-or-a-classifier-algorithm-eeed4de9953a?source=collection_archive---------0-----------------------
介绍
在我的上一篇帖子中,我开始了一个关于维数减少的讨论,这是在执行分类任务(https://meigarom.github.io/blog/pca.html)之前使用主成分分析(PCA)对结果的真正影响。在这篇文章中,我将继续讨论这个主题,但现在,谈论线性判别分析(LDA)算法。LDA 被作者定义为一种降维技术,然而一些来源解释说 LDA 实际上作为线性分类器工作。
为了更好地理解这些定义,我在这里提出了一个简单的测试:我将对同一个数据集应用 LDA 两次,每次使用不同角色的 LDA。通过这两种方法来衡量准确性,我们可以清楚地了解哪种角色最适合 LDA。因此,让我们开始吧。
关于 LDA 的一点点
LDA 背后的想法很简单。从数学上来说,我们需要找到一个新的特征空间来投影数据,以最大化类的可分性。显然,第一步是找到一种方法来测量每个新的候选特征空间的分离能力。每个类的投影平均值之间的距离可以是度量之一,但是只有这个距离不是一个很好的度量,因为它没有考虑数据的分布。1988 年,一位名叫罗纳德·费雪的统计学家提出了以下解决方案:最大化代表均值之间差异的函数,通过对类内变异性的测量进行标准化。Fisher 的建议基本上是最大化每个类的平均值之间的距离,并最小化类本身内的分布。因此,我们提出了两个衡量标准:阶级内部和阶级之间。然而,只有当我们假设数据集具有正态分布时,这种公式才是可能的。这种假设可能会带来一个缺点,因为如果数据的分布显著非高斯,LDA 可能不会表现得很好。在接下来的帖子中,我将深入研究 LDA 算法的代码,展示它的实现,在这里我关心的是找到最初问题的答案。LDA 是线性分类器还是降维技术?。
实验的细节
本文中提出的实验包括对公共数据集的分类任务。基本上,该数据集包含来自 3 种不同类型车辆的 846 个观察值和 18 个特征。这些特征对应于这些车辆形状的物理度量,例如紧密度、圆形度和半径。可以在这里查看数据集:https://archive . ics . UCI . edu/ml/datasets/Statlog+(Vehicle+Silhouettes。原始数据集带来了对 4 种车辆的观察,为了能够绘制新的特征空间,我将只从 3 个类别中选取示例。
LDA 作为一种分类算法
正如我在开始时提到的,我将对同一个数据集应用 LDA 两次,每次使用不同的角色。在第一种方法中,LDA 将作为分类器工作,之后它将降低数据集的维度,神经网络将执行分类任务,之后将比较两种方法的结果。
在 R 语言中,LDA 作为分类器非常简单,如下所示:
**library**( dplyr )*# Load dataset*
data_raw = read.csv( "../dataset/vehicle.csv", stringsAsFactor = FALSE )data = data_raw %>% filter( class == "bus" | class == "opel" | class == "van" )*# Scale dataset*
maxs = apply( data[,1:18], 2, max )
mins = apply( data[,1:18], 2, min )
dataset = as.data.frame( scale( data[,1:18], center = mins, scale = maxs - mins ) )
dataset = cbind( dataset, "class" = data$class )*# Split dataset*
index = sample( 1:nrow( dataset ), round( nrow( dataset )*0.6 ), replace = FALSE )
X_train = dataset[ index, ]
test = dataset[ -index, ]
首先,我加载了数据集,只过滤了 bus、open 和 van 类中的行。后来,我使用标准技术缩放数据集,然后我将数据集分为训练集和测试集,分别包含 60%和 40%的示例。准备好数据集后,我们可以对训练数据集应用 LDA。
*# Model Discriminant Analysis*
**library**( MASS )
model = lda( class ~ ., data = X_train )*# Ploting LDA Model*
projected_data = as.matrix( X_train[, 1:18] ) %*% model$scaling
plot( projected_data, col = X_train[,19], pch = 19 )
LDA 使用 MASS R 库建模,它带来了一对模型参数,如组的先验概率、组均值和线性判别系数。这里最重要的结果是系数,它们是描述数据将被投影到的新特征空间的值。LDA 将维数从原始特征数减少到 C-1 个特征,其中 C 是类别数。在这种情况下,我们有 3 个类,因此新的特征空间将只有 2 个特征。上图是仅有两个要素的新要素空间的绘图,我们可以看到数据的新位置,三个类之间有一些点重叠,但总的来说,数据集是相当可分的。在训练阶段之后,我们需要测量所获得的模型的准确性。
*# Model Testing*
X_test = test[, !( names( test ) %in% c( "class" ) ) ]
model.results = predict( model, X_test )*# Results - Confusion Matrix*
**library**( caret )
t = table( model.results$class, test$class )
print( confusionMatrix( t ) )## Confusion Matrix and Statistics
##
##
## bus opel van
## bus 87 5 0
## opel 2 75 0
## van 0 5 78
##
## Overall Statistics
##
## Accuracy : 0.952381
## 95% CI : (0.9182971, 0.9751557)
## No Information Rate : 0.3531746
## P-Value [Acc > NIR] : < 0.00000000000000022204
##
## Kappa : 0.9285056
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: bus Class: opel Class: van
## Sensitivity 0.9775281 0.8823529 1.0000000
## Specificity 0.9693252 0.9880240 0.9712644
## Pos Pred Value 0.9456522 0.9740260 0.9397590
## Neg Pred Value 0.9875000 0.9428571 1.0000000
## Prevalence 0.3531746 0.3373016 0.3095238
## Detection Rate 0.3452381 0.2976190 0.3095238
## Detection Prevalence 0.3650794 0.3055556 0.3293651
## Balanced Accuracy 0.9734266 0.9351884 0.9856322
第一种方法的最后一部分是在模型中应用测试数据集,并测量其结果。正如我们所看到的,LDA 作为一个分类器达到了大约 95%的准确率,这是一个非常好的结果。LDA 基本上将数据投影到新的线性特征空间中,显然,如果数据是线性可分的,分类器将达到高精度。现在我们已经知道了 LDA 像分类器一样工作的准确性,让我们检查第二种方法。
LDA 作为一种降维算法
线性判别分析也作为一种降维算法工作,这意味着它将维数从原始的减少到 C-1 个特征,其中 C 是类的数目。在这个例子中,我们有 3 个类和 18 个特征,LDA 将从 18 个特征减少到只有 2 个特征。约简后,神经网络模型将应用于分类任务。这里的程序与上一个几乎相同。看一看它。
*# New Dataset*
new_X_train = as.matrix( X_train[,1:18] ) %*% model$scaling
new_X_train = as.data.frame( new_X_train )
new_X_train$class = X_train$class
我将使用在先前的训练阶段中已经定义的线性判别式的系数来将训练数据集投影到新的特征空间中,这个新的空间将是新的训练数据集。
*# Multi-Class -> Transforming The Labels*
new_X_train = cbind( new_X_train, opel = new_X_train$class == "opel" )
new_X_train = cbind( new_X_train, van = new_X_train$class == "van" )
new_X_train = cbind( new_X_train, bus = new_X_train$class == "bus" )
new_X_train = new_X_train[, !( names( new_X_train ) %in% c( "class" ) ) ]
在建模之前,我们需要转换数据集,以便能够将神经网络模型用作多类分类问题。修改包括为每个标签创建具有值“真”或“假”新列。例如,所有来自“opel”的示例将在“opel”列下获得“True”值,在其他标签列中获得“False”值。因此,数据集可以用于多类模型。
*# Model Neural Network*
**library**( neuralnet )
n = names( new_X_train )
f = as.formula( "opel+van+bus ~ LD1+LD2" )
nn = neuralnet( f, new_X_train, hidden = 3, linear.output = FALSE, lifesign = "full",
threshold = 0.02, stepmax = 1e6 )## hidden: 3 thresh: 0.02 rep: 1/1 steps: 1000 min thresh: 0.7307363799
## 2000 min thresh: 0.7307363799
## 3000 min thresh: 0.7307363799
## 4000 min thresh: 0.6448965006
## 5000 min thresh: 0.4485495524
## 6000 min thresh: 0.3650681285
## 7000 min thresh: 0.2756491212
## 8000 min thresh: 0.2137706548
## 9000 min thresh: 0.1995287711
## 10000 min thresh: 0.173313487
## 11000 min thresh: 0.173313487
## 12000 min thresh: 0.173313487
## 13000 min thresh: 0.173313487
## 14000 min thresh: 0.1420902136
## 15000 min thresh: 0.08689029484
## 16000 min thresh: 0.08255271673
## 17000 min thresh: 0.0690402594
## 18000 min thresh: 0.04721150014
## 19000 min thresh: 0.02719626607
## 19149 error: 11.92918 time: 4.03 secs
神经网络模型开始非常简单,只有 3 个隐藏层,0.02 的均方误差阈值和 1e6 最大历元。这里的想法是在新的数据集上应用神经网络,并检查我们是否可以达到更好的结果。测试数据集将与前面方法中使用的相同。
*# Testing*
X_test = as.matrix( test[,1:18] ) %*% model$scaling
nn.results = compute( nn, X_test )*# Results*
print( "... resulting ..." )## [1] "... resulting ..."idx = apply( nn.results$net.result, c(1), **function**( x ){ which( x == max( x ) ) } )
predictions = c( "opel", "van", "bus")[idx]*# Confusion Matrix*
**library**( caret )
t = table( predictions, test$class )
print( confusionMatrix( t ) )## Confusion Matrix and Statistics
##
##
## predictions bus opel van
## bus 84 3 1
## opel 4 81 3
## van 1 1 74
##
## Overall Statistics
##
## Accuracy : 0.9484127
## 95% CI : (0.9133996, 0.9722494)
## No Information Rate : 0.3531746
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.9224872
## Mcnemar's Test P-Value : 0.7667396
##
## Statistics by Class:
##
## Class: bus Class: opel Class: van
## Sensitivity 0.9438202 0.9529412 0.9487179
## Specificity 0.9754601 0.9580838 0.9885057
## Pos Pred Value 0.9545455 0.9204545 0.9736842
## Neg Pred Value 0.9695122 0.9756098 0.9772727
## Prevalence 0.3531746 0.3373016 0.3095238
## Detection Rate 0.3333333 0.3214286 0.2936508
## Detection Prevalence 0.3492063 0.3492063 0.3015873
## Balanced Accuracy 0.9596402 0.9555125 0.9686118
神经网络模型在应用于具有降维的数据集时达到了大约 93%的准确度。这个结果非常非常接近第一种方法的结果。这是 LDA 最佳工作模式的重要线索。
两种方法的结果
嗯,我想我们完成了实验。奇怪的是,两个结果非常接近,就准确性而言,这表明 LDA 在两种模式下都能很好地工作。比较实现的难度,第一种方法比第二种方法更简单,LDA 模型自己提供分类结果,而在第二种方法中,我们有更多的代码,因为 LDA 只是降低维度,而神经网络模型负责执行分类任务。
结论
写这篇文章的动机问题是:LDA 是一种降维技术还是一种分类器?在我看来,基于实现的结果和努力,答案是 LDA 在两种模式下都工作得很好,在分类器模式和降维模式下也是如此,我会给你支持这个结论的论据。
首先,您正在处理的数据集的特征将指导您决定是应用 LDA 作为分类器还是降维算法来执行分类任务。线性判别分析的主要内容基本上是将类别的独立样本线性移动到不同的特征空间,因此,如果您的数据集是线性可分的,只应用 LDA 作为分类器,您将获得很好的结果。然而,如果数据集不是线性可分的,LDA 将尝试在另一个空间中尽可能最大程度地组织数据集的线性可分性,但由于数据的非线性特征,它仍然是类之间重叠的例子。在这种情况下,您将需要使用另一种分类模型来处理非线性数据,如具有多个隐藏层的神经网络、具有径向基函数的神经网络或具有非线性核的 SVM。
总之,LDA 模式的决定将取决于您手中的数据集,如果它是线性可分的,LDA 作为分类器是一种快速的解决方案,具有很好的结果,但如果数据集的特征是非线性的,LDA 将是应用于数据集的额外工具,以便尝试“使事情变得更好”或促进后分类器的工作。
我看过一些这方面的作品,作者将 PCA 和 LDA 结合起来,都是为了降维。首先,主成分分析通过其方差进行特征约简,然后 LDA 应用线性维数约简,最后在这个修改的数据集上执行分类器模型。为了改善分类任务的结果,这绝对是一个要遵循的路线图。
谢谢!
完整的代码可以在我的 git hub 仓库和数据集上找到。
感谢你花时间阅读这篇文章。我真的很感激,随时欢迎反馈。
回头再聊。
学习率在人工神经网络中有用吗?
原文:https://towardsdatascience.com/is-learning-rate-useful-in-artificial-neural-networks-84ee5b6976d6?source=collection_archive---------2-----------------------
本文将帮助您理解为什么我们需要学习率,以及它对于训练人工神经网络是否有用。对单层感知器使用一个非常简单的 Python 代码,学习率值将被改变以捕捉它的想法。
简介
人工神经网络新手的一个障碍是学习速度。有人多次问我,在人工神经网络(ann)的训练中,学习速度的作用是什么。为什么我们使用学习率?学习率的最佳值是多少?在本文中,我将通过提供一个例子来说明学习率对于训练一个人工神经网络是多么有用,从而使事情变得简单。在处理学习率之前,我将首先用 Python 代码解释我们的例子。
举例
一个非常非常简单的例子是用来让我们摆脱复杂性,让我们只关注学习率。单个数字输入将被应用到单层感知器。如果输入等于或小于 250,其值将作为网络的输出返回。如果输入大于 250,那么它将被裁剪为 250。图 1 显示了用于训练的 6 个样本的表格。
Figure 1. Training samples.
安架构
所用人工神经网络的架构如图 2 所示。只有输入层和输出层。输入层只有一个神经元用于我们的单一输入。输出层只有一个神经元来产生输出。输出层神经元负责将输入映射到正确的输出。还有一个偏置应用于输出层神经元,权重 b ,值 +1 。还有一个用于输入的权重 W 。
Figure 2. Network architecture.
激活功能
本例中使用的激活函数的方程和图形如图 3 所示。当输入小于或等于 250 时,输出将与输入相同。否则会被剪辑到 250。
Figure 3. Activation function.
用 Python 实现
实现整个网络的 Python 代码如下所示。我们将讨论所有这一切,直到尽可能使它变得简单,然后集中于改变学习率,找出它如何影响网络训练。
1\. import numpy
2\.
3\. def activation_function(inpt):
4\. if(inpt > 250):
5\. return 250 # clip the result to 250
6\. else:
7\. return inpt # just return the input
8\.
9\. def prediction_error(desired, expected):
10\. return numpy.abs(numpy.mean(desired-expected)) # absolute error
11\.
12\. def update_weights(weights, predicted, idx):
13\. weights = weights + .00001*(desired_output[idx] - predicted)*inputs[idx] # updating weights
14\. return weights # new updated weights
15\.
16\. weights = numpy.array([0.05, .1]) #bias & weight of input
17\. inputs = numpy.array([60, 40, 100, 300, -50, 310]) # training inputs
18\. desired_output = numpy.array([60, 40, 150, 250, -50, 250]) # training outputs
19\.
20\. def training_loop(inpt, weights):
21\. error = 1
22\. idx = 0 # start by the first training sample
23\. iteration = 0 #loop iteration variable
24\. while(iteration < 2000 or error >= 0.01): #while(error >= 0.1):
25\. predicted = activation_function(weights[0]*1+weights[1]*inputs[idx])
26\. error = prediction_error(desired_output[idx], predicted)
27\. weights = update_weights(weights, predicted, idx)
28\. idx = idx + 1 # go to the next sample
29\. idx = idx % inputs.shape[0] # restricts the index to the range of our samples
30\. iteration = iteration + 1 # next iteration
31\. return error, weights
32\.
33\. error, new_weights = training_loop(inputs, weights)
34\. print('--------------Final Results----------------')
35\. print('Learned Weights : ', new_weights)
36\. new_inputs = numpy.array([10, 240, 550, -160])
37\. new_outputs = numpy.array([10, 240, 250, -160])
38\. for i in range(new_inputs.shape[0]):
39\. print('Sample ', i+1, '. Expected = ', new_outputs[i], ' , Predicted = ', activation_function(new_weights[0]*1+new_weights[1]*new_inputs[i]))
第 17 行和第 18 行负责创建两个数组(inputs 和 desired_output ),用于保存上表中给出的训练输入和输出数据。根据所使用的激活功能,每个输入将有一个输出。
第 16 行创建了一个网络权重数组。只有两个权重:一个用于输入,另一个用于偏差。它们被随机初始化为 0.05 的偏置和 0.1 的输入。
第 3 行到第 7 行使用 activation_function(inpt)方法实现激活函数本身。它接受作为输入的单个参数,并返回作为预期输出的单个值。
因为预测中可能存在误差,所以我们需要测量该误差,以知道我们离正确的预测有多远。出于这个原因,第 9 行到第 10 行实现了一个名为 prediction_error(desired,expected)的方法,该方法接受两个输入:期望的输出和期望的输出。该方法只是计算每个期望输出和期望输出之间的绝对差值。任何误差的最佳值肯定是 0。这是最佳值。
如果有预测误差呢?在这种情况下,我们必须对网络进行更改。但是到底要改变什么呢?这是网络权重。为了更新网络权重,在第 13 行到第 14 行定义了一个名为 update_weights(weights,predicted,idx)的方法。它接受三个输入:旧权重、预测输出和具有错误预测的输入的索引。用于更新权重的等式如图 4 所示。
Figure 4. Weights update equation using learning rate.
该等式使用当前步骤(n)的权重来生成下一步骤(n+1)的权重。这个等式是我们用来了解学习速度如何影响学习过程的。
最后,我们需要将所有这些连接在一起,使网络能够学习。这是使用从第 20 行到第 31 行定义的 training_loop(inpt,weights)方法完成的。它进入一个训练循环。该循环用于以最小的可能预测误差将输入映射到它们的输出。
该循环执行三项操作:
- 产量预测。
- 错误计算。
- 更新权重。
了解了这个例子及其 Python 代码之后,让我们开始展示学习率对于获得最佳结果是如何有用的。
学习率
在前面讨论的例子中,第 13 行有权重更新等式,其中使用了学习率。首先,我们假设我们没有完全使用学习率。该等式将如下:
weights = weights + (desired_output[idx] — predicted)*inputs[idx]
让我们看看去掉学习率的效果。在训练循环的迭代中,网络具有以下输入(b=0.05,W=0.1,输入=60,期望输出= 60)。
第 25 行中激活函数的预期输出将是 activation _ function(0.05(+1)+0.1(60))。预测产量将为 6.05。
在第 26 行,预测误差将通过得到期望输出和预测输出之间的差来计算。误差将是 ABS(60–6.05)= 53.95。
然后,在第 27 行,权重将根据上面的等式进行更新。新的权重将是[0.05,0.1] + (53.95)*60 = [0.05,0.1] + 3237 = [3237.05,3237.1]。
似乎新的权重与以前的权重相差太大。每个重量增加了 3237 磅,这太大了。但是让我们继续做下一个预测。
在下一次迭代中,网络将应用这些输入:(b=3237.05,W=3237.1,输入=40,期望输出= 40)。预期输出将是 activation _ function((3237.05+3237.1(40))= 250。预测误差将为 ABS(40–250)= 210。误差非常大。它比前一个误差大。因此,我们必须再次更新权重。根据上面的等式,新的权重将是[3237.05,3237.1] + (-210)*40 = [3237.05,3237.1] + -8400 = [-5162.95,-5162.9]。
图 5 中的表格总结了前三次迭代的结果。
Figure 5. Summary of results of the first three iterations.
随着我们进行更多的迭代,结果会变得更糟。权重的大小变化很快,有时还会改变符号。它们正从很大的正值变为很大的负值。我们怎样才能阻止这种巨大而突然的重量变化呢?如何缩小权重更新的值?
如果我们从上表中查看重量的变化值,该值似乎非常大。这意味着网络以很大的速度改变它的权重。这就像一个人在很短的时间内做了很大的动作。曾经,这个人在远东,过了很短的时间,这个人将在遥远的西方。我们只需要让它慢下来。
如果我们能够缩小这个值,让它变得更小,那么一切都会好的。但是怎么做呢?
回到生成该值的代码部分,看起来是更新等式生成了该值。特别是这部分:
(desired_output[idx] — predicted)*inputs[idx]
我们可以通过将其乘以一个小值(如 0.1)来缩放该部分。因此,在第一次迭代中,不是生成 3237.0 作为更新值,而是减少到 323.7。我们甚至可以通过将比例值减小到 0.001 来将该值缩小。使用 0.001,该值将仅为 3.327。
我们现在可以抓住它了。这个比例值就是学习率。为学习率选择小的值使得权重更新的速率更小,并且避免突然的变化。值越大,变化越快,结果越差。
但是学习率的最佳值是多少呢?
我们不能说这是学习率的最佳值。学习率是一个超参数。超参数的值由实验确定。我们尝试不同的值,并使用给出最佳结果的值。有一些方法可以帮助你选择超参数的值。
检测网
对于我们的问题,我推断值 0.00001 就可以了。用那个学习率训练完网络,就可以做个测试了。图 6 中的表格显示了 4 个新测试样本的预测结果。使用学习率后,现在的结果似乎好了很多。
Figure 6. Test samples prediction results.
原文可在 LinkedIn 在此链接:https://www . LinkedIn . com/pulse/learning-rate-useful-artificial-neural-networks-Ahmed-gad/
在本页面 KDnuggets 也有分享:https://www . kdnugges . com/2018/01/learning-rate-useful-neural-network . html
这篇文章于 2018 年 6 月 28 日在 TDS 上再次分享。
联系作者
艾哈迈德·法齐·加德
LinkedIn:https://linkedin.com/in/ahmedfgad
电子邮件:ahmed.f.gad@gmail.com
机器学习是开放式的吗?
原文:https://towardsdatascience.com/is-machine-learning-open-ended-75128deaf6af?source=collection_archive---------4-----------------------
Fractal patterns are open-ended because they can be calculated infinitely many times upon zooming in, although their approximations in nature are finite like this romanesco cabbage.
近年来,机器学习取得了一些令人难以置信的成就,特别是通过利用人工神经网络的技术(例如 [Go](http://b. https://deepmind.com/research/alphago/) )。此外,尽管神经网络技术[是出了名的喜怒无常](http://f. http://www.turingfinance.com/misconceptions-about-neural-networks/),但人们对连接主义范式将继续取得胜利充满信心。然而,人工智能社区中有一种越来越强的声音,质疑当前技术的力量,以在一系列任务中引领类似人类一般智能的目标。[渐进式神经网络](http://b. https://arxiv.org/pdf/1606.04671.pdf)可能会对这个问题有所启发,但仍处于起步阶段。在这里,我认为只有一种算法是已知的,可以导致广义智能所必需的那种开放性——自然选择。为了问机器学习是否是开放式的,我因此比较了自然选择和机器学习的逻辑,以开发有助于磨练未来研究的洞察力。
开放式进化的基础
在生物学理论中,只有一种创造性的“力量”能够产生无限进化——自然选择(NS)。(如果你对这种说法的来源感兴趣,我已经在别处[充实了这一观点背后的论点。)尽管](http://a. https://medium.com/@philmadgwick/how-to-solve-a-problem-or-the-foundations-of-evolutionary-epistemology-6b42e41bbb81)达尔文最初对 ns 的描述明确提到了现代生物学的特征,如有机体、世代、性别等等,但是普遍达尔文主义已经开始将 NS 视为底物中性(例如 Dawkins 1976,Dennett 1995 等)。因此,NS 可以被认为是一种性能优化算法。
这样,用于描述 NS 的数学可以等效地模拟真实的学习(Plotkin 1995)。虽然 NS 通常被用来指发生在代与代之间的基因进化变化,但选择也可以描述发生在个体内部模因中的学习过程。这里有三个限定性的陈述:I)模因不一定是复制体,因为它们的存在可以被限制在一个单一的头脑中(例如 Munz 1994),ii)模因可能很少像基因,但这并不改变 NS 的适用性(例如 Barkow 等人 1992),以及 iii)并不是所有的行为变化都是学习,因为指令可塑性可以简化为潜在基因的反应规范(例如棘手点所以[见](http://4. https://medium.com/@philmadgwick/the-biology-of-problem-solving-a-universal-darwinism-or-lamarckism-d3bba8b84aa4))。只有迷因提供了通往真正学习的途径,因为它们是独立的遗传对象。因此,通常被认为是迷因遗传的生物仅限于人类、特选的类人猿,或许还有一些其他分布的鸦类和鲸类物种。
这些年来,人们一直在激烈辩论 NS 的品质,这些品质使它能够导致基因或迷因的开放式进化。根本的问题是 NS 同样适用于化学进化,就像它适用于生物一样,所以生物对象必须有一些特殊的特征,允许它们的 NS 具有开放的可能性(例如 Cairns-Smith 1985)。换句话说,在 NS 的算法中没有找到开放式进化的基础。进化生物学界已经认识到这个问题,现在[正在重大转变框架](http://b. http://devosoft.org/whats-holding-artificial-life-back-from-open-ended-evolution/)的指导下进行研究。
主要转变框架可以被认为是解决生物复杂性问题的一种尝试。当 Williams (1966)和 Dawkins (1976)引入自私基因理论时,他们强调了生物组织是多么荒谬。如果每个基因都是自私的,为什么它们会生活在基因组中基因的社会里?基因预计会遇到合作问题,如囚徒困境,这使得基因社会容易受到内部冲突的破坏,导致公地悲剧。然而,梅纳德·史密斯和 Szathmary 指出,生物组织似乎完全是不可逆的。他们提出,基因社会的扩张是通过少数重大转变事件来实现的,这些转变事件克服了合作问题,并为逆转创造了障碍。结果是一个类似棘轮的过程,增加了生物的复杂性。
因此,进化理论将开放式进化与生物物体经历重大转变的能力联系起来。重大转变仍然是一个热门的研究领域,这个问题还没有达成一致的答案。我以前曾试图将主要转变的过程解释为 NS 的主体和客体之间的反身进化过程。主体就像有机体一样是适应性最大化的代理,而客体就像基因一样是遗传的单位。主体产生于客体的集体行为,这意味着主体是相互冲突的自私利益的妥协。反过来,主体与环境相互作用,以使其对象恢复健康。然而,主体的任务是模糊的,因为它可能与其他主体共享对象,因此与其他人共享共同感兴趣的程度。
关键问题是,一个主体如何知道如何回报利益给它的客体?由于其他主体可能包含与自身相同的对象,纯粹的利己主义将失败,因为它将导致通过其他主体损害其对象健康的行为。与此同时,纯粹的利他主义也会失败,因为这会助长他人的利己行为。形成明确的组通常是一个好主意,因为这将问题限制在一小部分人身上,他们可以更容易地对共享对象做出决定。当强制群体形成的好处(例如劳动分工)超过在群体之外的代价变得太不利时,正是这个群体可以经历重大转变。结果是主体扩展为群体,因此,每个主体的对象数量和交互的复杂性增加。
虽然我的描述必然是不完整的,需要进一步的阐释,但关键的信息是,主要的转变取决于主体和客体之间的分裂。这如何转化为机器学习算法?
机器学习有主体和客体吗?
如果我们要描述网络中主体和客体之间的划分概念,我们可以把单个节点描述为客体,把主体描述为网络中相对不同的模块。一个主体会有许多强有力的内部连接,有少量的节点连接到网络的其他部分。然而,尽管这种解释很直观,但当使用选择性算法而不是机器学习算法时,它将非常有意义。逻辑可以归结为四点:
1。原则上,NS 和许多机器学习算法没有什么不同
NS 和许多机器学习算法都是优化技术。给定一个恒定的环境,两者都经历了向某种最佳状态的变化。一些进化生物学家和计算机科学家认为,群体优化方法是 NS 启发的算法所独有的。在我看来,我看不出为什么人口的统计特性不能以一种去除人口成分的方式来建模。事实上,有 NS 的进化模型就是这样做的。因此,我认为更重要的是认识到 NS 和优化之间没有什么真正的不同。但是,它们的实现方式可能会有所不同。
2。在 NS 下,对象适应度最大化,但是节点没有最大化任何东西
在一个有机体中,一个基因可以说是自私的,因为它被选择来最大化其适应性,即使它是通过与其他基因相互作用而获得这种适应性的。这可能导致基因与基因组中的其他基因发生冲突,但这种冲突表现为基因组中特定基因座的等位基因之间的竞争。可以说,位点是基因组中的一个座位,能改变的只是谁坐在这个座位上。例如,当第一个基因座的突变基因进化时,为了自己的私利而损害了基因组的其余部分(例如,一个绿胡子),这就选择了另一个基因座的修饰等位基因,以抑制这种变化。预计第一个基因座的基因库不会针对该基因座进行选择。通过这种方式,一个基因网络被一只看不见的手组织起来,基因按照自己的利益行事,并附带地有益于基因组的其他部分。
人工神经网络不是通过一只看不见的手来运作的。没有理由认为一个节点可以最大化任何东西。相反,网络作为一个整体最大化其任务性能。问题不在于节点的属性是由整个网络如何与环境(即游戏等)交互决定的,因为这也是主体在自然界中所做的,而是节点是固定架构的一部分。在自然界中,如果有害的突变被 ns 所偏爱,一个基因座可能变得无功能,但是在人工神经网络中这不会发生。事实上,有一整套选择网络约束的艺术,包括节点的数量、层中节点的排列等等,都需要预先考虑。这与盲目的选择过程完全不同。
3。机器学习网络中的节点对对象进行编码,但本身不是对象
网络对物体进行编码的想法很复杂。让我们考虑一下基因。基因由位于线性字符串上的 DNA 编码,但它们通过复杂的表达网络相互作用来创建功能,这些表达网络不映射到线性编码结构上。同样,网络不一定要映射到学习的对象上。这个问题在新兴的迷因科学中遇到过,迷因的物理基础由某人大脑中一组特殊的神经连接来表示。这些神经连结,以及许多其他的神经连结组态,编码了迷因对象。同样,机器学习网络中的节点不是对象,而是对对象进行编码。
4。机器学习网络是低效的对象编码器
在目前处于起步阶段的渐进式神经网络中,单个网络可以从玩一个游戏中获得“直觉”,然后将这种直觉应用于另一个游戏,以提高性能优化的速度。然而,网络以一种可塑性的形式做到了这一点,因为在学习玩新游戏的过程中,现有的任务表现受到了损害。这是值得关注的,因为这意味着网络中的对象非常少,因此玩新游戏必然意味着覆盖为先前任务选择的对象。这种重写显然与类人的一般智力非常不同,在类人的一般智力中,玩家可以独立地在多个游戏中保持能力。此外,在不发生这种重写的情况下,整个过程被“硬编码”以避免“遗忘”。这里还有很长的路要走。
开放式机器学习?
作为一名进化生物学家,我对当前机器学习技术可能达到的极限感到担忧。显然,采取更受 NS 启发的方法是否有益取决于你的目标。如果你想让一台机器很好地播放 Atari,我认为 DeepMind 已经非常明确地展示了超人的能力。然而,如果你想要一台具有某种生物“通用”智能的机器,那么我认为明智的做法是考虑 I)许多生物“智能”对于它们特定的小生境是多么有限,以及 ii)开放式学习的罕见情况的显著特征(在开放式进化普遍性的更广泛背景下)。对于未来的研究,我有两个试探性的建议。首先,放宽技术以允许网络体系结构更加灵活可能会使网络更具创造性;移除层结构以允许节点之间的任何类型的连接,允许节点的创建/消失,并允许内部选择网络常数。第二,如果节点被制成在选择性环境中最大化某些东西的明确对象,这可能会改善网络功能。是否会是这样,我还不确定,但不管怎样,它会让我们更有信心,技术正在走向开放式学习,因为 NS 在本质上已经实现了开放式学习。此外,有大量关于看不见的手的自组织特性的经济学、物理学和生物学文献,这些文献有助于描述在“黑匣子”中发现的结构的特征,从而可能解释它们。
感谢阅读!如果你有任何意见,我将很高兴听到他们,因为这是一个问题,我觉得不得不写下没有任何明确的答案。我认为很难说机器学习是否能够进行开放式学习(如定义的那样),但我怀疑现有的方法是不够的。开放式技术的挑战似乎开始被重视,而不是被假设,导致了一些 T2 式的创新方法。总的来说,未来看起来令人兴奋!
机器学习准备好规模化了吗?
原文:https://towardsdatascience.com/is-machine-learning-ready-to-scale-8548f5b06c4a?source=collection_archive---------5-----------------------
我们的大脑中有一个动态的世界模型,帮助我们在识别出一些相似的特征后,识别出熟悉的模式。“我们假设大脑将世界建模为动力系统的层级或级联,这些动力系统在感觉中枢中编码因果结构。感知等同于这些内部模型的优化或反演,以解释感官数据。”几年前,分析脑成像数据以及大脑如何工作的计算模型的技术先驱卡尔·弗里斯顿和斯蒂芬·基贝尔在他们的开创性论文中写道。
这意味着当我们看着一只猫时,我们实际上并没有看到真实世界中的猫。我们看到一个由我们大脑的神经网络生成的猫的模型,它基于通过感官输入传递给我们大脑的真实猫的一些猫的特定细节。我们不需要处理来自真实世界的猫的完整图像来将它归类为猫并生成它的模型,因为我们的大脑可以概括。它有一个存储在内存中的猫的通用模型——一种模板,每当它在感官输入中识别出猫的模式时,它就可以将它上传到它的动态世界模型中。
随着我们的大脑不断接收关于现实世界中的猫的更多信息的感官输入,它会继续自动将通过输入获得的新信息与生成的模型进行比较。如果新的输入符合模型的模式,或者换句话说,根据模型,这是非常可能的,大脑将其归类为猫的另一个特征,并使我们的猫的模型更加详细。这种持续的模式丰富是我们大脑的背景活动,不会改变我们大脑的处理负荷。这实际上不是一个学习过程。这是模型的微调。
我们不断扫描现实世界的主要原因是寻找意外事件和低概率输入。如果你看到另一匹马,对大脑来说就不那么重要了。马可以有不同的颜色或大小,但它仍然只是一匹马。你的大脑会定期接受特定特征的输入,并将它们添加到你正在看的真实世界的马的动态生成模型中。你的大脑已经知道哪一匹马的颜色和尺寸最有可能,因为它已经在记忆中保存了类似马的模板(或广义模型)的东西。
然而,如果你突然看到马的前额有一只角,你的大脑活动会发生巨大的变化。你的大脑会对这一事件的处理负荷做出夸张的反应,你的大脑会立即意识到这是极不可能的。大脑活动的增加将持续下去,直到大脑选择了一个犀牛、独角兽或者只是一匹长着假角的马的模型。如果我们的大脑面对全新的和意想不到的东西,因此非常不可能,可能需要生成一个全新的模板(广义模型)。
我们需要世界模型及其模板来更好地压缩我们收到的数据,因为数据是神圣的——我们不能失去它,但我们的记忆不是无限的。它们还帮助我们缩短对现实世界情况的反应时间,这些情况可能需要对我们的生存至关重要的立即行动。
如果你的大脑必须在它的内存中筛选数百万张图片来识别一匹与你在现实世界中看到的棕色马相似的棕色马的图片,这可能需要几个小时或几年,取决于存储的数据量,因为我们的大脑处理数据的速度比现代计算机芯片慢得多。
人类通过搜索最不可能的数据来学习。这扩展了我们的概括能力。已经有理论假设和实践证明当我们对抗难以预测的刺激时,我们大脑的处理负荷会增加。
机器通过搜索最可能的数据来学习。这缩小了他们归纳的能力。此外,他们不能实时调整现实世界物体的模型。正如谷歌 DeepMind 的研究人员所说如今,计算机程序无法自适应地实时学习数据最有前途的人工智能技术——深度神经网络(DNNs)——最近在封闭领域(非常狭窄的特定小生境)的许多识别和分类任务中展示了出色的结果。这使得许多研究人员认为成功的 DNNs 模型可以推广。然而,这个问题仍然没有答案。
由麻省理工学院的张领导的一组研究人员最近认为成功的 DNNs 只是记忆了整个训练数据集,可以在没有任何泛化的情况下做出准确的分类。“我们进行的实验强调,几个成功的神经网络架构的有效容量足够大,足以粉碎训练数据。因此,这些模型在原则上足够丰富,可以记忆训练数据……我们的实验得出的另一个结论是,即使得到的模型不能一般化,根据经验优化仍然很容易。”
来自华盛顿大学电气工程系网络安全实验室的 Hossein Hosseini 和 Radha Poovendran 在他们的论文中显示,“尽管 DNNs 在常规数据上的表现令人印象深刻,但它们在负面图像上的准确性处于随机分类的水平。这个观察表明,简单地在原始数据上训练的 dnn 不能识别对象的语义,并且可能仅仅记住输入。无法识别转换后的输入显示了当前训练方法的缺点,即学习模型无法进行语义概括。”
正如研究人员所说,“已经证明,神经网络的有效容量足以记忆整个训练数据集。结果,DNN 分类器通常以非常高的置信度正确地分类训练样本。此外,网络损失函数在输入样本周围平滑变化,即随机扰动样本很可能与常规样本归为同一类。此外,由于测试样本通常是从与训练样本相同的分布中收集的,因此测试数据点大多出现在训练点附近。因此,随着大型数据集的可用性,网络很可能可以将每个测试样本与来自同一类的一个或几个训练样本相关联,从而实现高测试准确度。
然而,由于转换后的样本可能远离原始样本,网络无法正确地对其进行分类。然而,对于特定的转换,我们也可以在转换后的数据上训练 DNN,以获得高精度,依靠大型和多样化的数据集,涵盖测试数据中可能的新奇事物的所有方面,似乎对机器学习系统提出了一个基本问题。这导致模型需要大量数据来理解每一个特性,这显然不适合真实世界的应用。"
特别是,Hosseini 和 Poovendran 在他们的实验中表明,经过良好训练以识别路标的 DNN 根本不能识别负面路标,即与训练时相同但亮度相反的路标。
与此同时,百度硅谷人工智能实验室系统研究主管格雷格·迪亚莫斯在福布斯上撰文称,“为了实现人工智能的又一次重大突破,我们需要改变我们的软件。”这篇文章是由百度前首席科学家吴恩达在脸书和推特上分享的,他评论了 Greg 思想的重要性。
迪亚莫斯提出的突破是调整现有的人工智能算法,使它们更好地利用局部性。事实上,正如丹尼尔·格林菲尔德在他 2010 年的论文中所说:“自从微处理器诞生以来,晶体管变得越来越便宜、越来越快、越来越节能,而全球的线路几乎没有变化。与此同时,我们正朝着在一个芯片上集成数千个处理内核的方向发展,软件分布在这些内核上。这个以通信为主导的计算新时代的标志是,内核上的本地计算很便宜,但内核间的全局通信和外部存储器很贵。因此,软件的物理空间位置开始变得重要。事实上,已经证明,除非利用通信中的物理位置,否则随着技术的发展,成本变得难以承受
因此,当对已经定型的技术进行规模化推广时,本地化就变得至关重要。如果你的自动驾驶汽车不能识别亮度相反的让路或停车标志,这会是一个根本性的问题吗?当前的机器学习系统准备好进行扩展了吗?还是仍然有一个根本问题使它们不可扩展?下注吧。
我的 Spotify 音乐很无聊吗?涉及音乐、数据和机器学习的分析
原文:https://towardsdatascience.com/is-my-spotify-music-boring-an-analysis-involving-music-data-and-machine-learning-47550ae931de?source=collection_archive---------1-----------------------
几天前,我一边听着 Spotify 保存的歌曲,一边和一个朋友聊天。唱了几首歌后,她打断了谈话告诉我:“你的音乐品味很有趣……你的播放列表里有很多综艺、器乐歌曲,其中一些是无聊”。
我对这个评论一笑置之,因为这已经不是我第一次听到了。我承认我的音乐品味可能有点奇怪——例如,我可以以听肯德里克·拉马尔的音乐开始新的一天,然后转到《盗梦空间》的配乐,接着是西班牙萨尔萨舞曲。
然而,她的评论给了我一个好主意:让我们看看数据是怎么说的。
因此,我做了一个实验。
在这篇文章中,我将分享这个实验的发现,在这个实验中,我分析了我的 Spotify 歌曲,看看它们是否确实多样化、工具化和无聊。而且,为了让问题更有意思,我把这三个特点都和我朋友的歌做了对比。最后,我训练了一个机器学习模型,目的是预测一首歌是否更适合我或她的播放列表。
工具
这个项目中使用的主要工具是 Spotify API 服务的音频功能组件。这些音频特征代表了一首歌曲的特征,例如声音有多强,T21 有多响。稍后我会对这些特性进行更详细的解释。
Python 用于使用库 Spotipy 获取数据,使用 scikit-learn 训练机器学习模型。数据分析在 R 中完成。
数据
音乐数据是使用我编写的 Python 脚本获取的,该脚本获取用户的所有播放列表,以及特定播放列表中的所有歌曲。一旦我有了歌曲的基本信息,包括它们的 Spotify ID,我就能够使用相同的脚本获得它们的音频特征。
产生的数据集由 15 列和 1074 首歌曲组成,其中 563 首来自我的播放列表,511 首来自她的(从现在起我将称我的朋友为她或她的)。
在数据集的所有 15 列中,仅使用了与音频特征相关的那些列。在下面的列表中,我将介绍它们,并解释它们的含义(在某些情况下,我只是从 Spotify 复制/粘贴描述)。注意:所有特性的值都在 0.0 -1.0 的范围内。
- 乐器性:这个值代表歌曲中的声音量。越接近 1.0,歌曲的器乐性越强。
- 声学:这个值描述了一首歌曲的声学程度。1.0 分意味着这首歌最有可能是一首原声歌曲。
- Liveness:这个值描述了歌曲被现场观众录制的概率。根据官方文档",高于 0.8 的值表示该曲目很有可能是直播的"。
- 语速:语速检测音轨中是否存在口语单词。如果一首歌曲的语音度高于 0.66,它可能是由口语词组成的,0.33 到 0.66 之间的分数是一首可能同时包含音乐和词的歌曲,而低于 0.33 的分数意味着这首歌曲没有任何语音。
- 能量:“(能量)代表强度和活动的感知测量。通常,充满活力的曲目让人感觉快速、响亮、嘈杂。
- 可跳舞性:"可跳舞性描述了一首曲目在音乐元素组合的基础上适合跳舞的程度,包括速度、节奏稳定性、节拍强度和整体规律性。值 0.0 最不适合跳舞,1.0 最适合跳舞。
- 效价:"从 0.0 到 1.0 的量度,描述音轨所传达的音乐积极性。高价的音轨听起来更积极(例如,快乐、愉悦、欣快),而低价的音轨听起来更消极(例如,悲伤、沮丧、愤怒)。
数据分析
这篇报道的前提或者说假设是——据一个朋友说——我的歌是多种多样的,器乐化的,无聊的。所以,我调查了这三个属性,来测试她是否正确。在这一部分,我将描述我的发现。
我将首先展示两个播放列表的所有音频特征的平均值的两个图,这样我们可以了解每个数据集的主要特征,并熟悉它。
第一个图显示了我的播放列表的普遍特征是乐器性,代表她的播放列表的第二个图显示了可跳舞性是她的。但是,这些数值的差别有多大呢?下面的图表是从我的特征中减去她的每个特征的平均值后的结果。
我们可以清楚地看到乐器性和一致性(蓝色条)是我的播放列表的显著特征,相差 0.53 和 0.1。在她这边, danceability 和 valence ,这两个特征都以 0.19 的数值高居榜首。
这个结局可以这样解读。
- 我的歌好像少了些人声,多了些器乐。
- 她的歌曲更生动。
所以,看到这些结果后,我们都同意“我的播放列表有用吗?”是确定的是。
多样化
我要回答的下一个问题是:我的播放列表有多多样?
为了回答这个问题,我调查了每个播放列表中的歌曲有多相似或不相似。例如,非常多样的播放列表意味着用户有许多来自不同流派的歌曲。与此相反,低变化播放列表是一个几乎所有歌曲都属于同一流派的列表。
我用来检查我们的播放列表有多不同的技术,是简单地查看音频特征的标准偏差。以下是情节。
通过查看图表,很难确定哪个播放列表的变化更大,但是如果将所有值相加,并计算平均值,我们会发现我的播放列表的所有标准偏差的平均值是 0.244 ,而所有单个值的总和是 1.713 。关于她的播放列表,分别是 0.174 ,和 1.218 。
这意味着什么?高标准偏差表示我的歌曲的音频特征的分数不是那么相似,这意味着,例如,我可能有许多乐器性值非常高的歌曲,同时也有相同值非常低的歌曲。
结论:我的播放列表至少比她的更多样。
乏味的
寻找问题“我的播放列表有多无聊?”是这部作品中最有趣的部分之一,因为,到底是一首无聊的歌。对我来说无聊的事情对你们中的一些人来说可能是最好的事情。所以我解决这个问题的方法是想象自己在一个派对上,并思考我想在派对上听到什么样的音乐。所以我想出了一个简单的等式,它包括能量,和可跳舞性特征,加上我还没有介绍的两个特征:速度,和响度。我之所以选择这些,是因为在派对上,我喜欢响亮的音乐,节奏优美,能激发我(和其他人)的能量,让我有心情跳舞。
这是等式:
boringness = loudness + tempo + (energy*100) + (danceability*100)
而且按照它的说法,分数越低的歌越无聊,分数越高的歌越好玩。此外,请注意,能量和可跳舞性乘以 100,因为响度和速度值不在 0.0-1.0 的范围内,我想让一切或多或少地保持在同一范围内。
这些是结果:
上面的图像是一个直方图,它显示了无聊分数在每个数据集之间的分布情况。人们可能注意到的第一件事是,代表她的播放列表的粉红色区域的峰值高于蓝色区域,这意味着在该范围内有许多值。此外,与蓝色区域相比,粉红色区域在右侧更密集(这被称为左偏),这意味着她的播放列表的大多数无聊值都比我的大。
为了补充这个直方图,计算了无聊度的平均值,我的值是 201.735 ,她是 233.284 。下面的情节说明了这一点。
因此,我们可以得出结论,根据我自己的等式,我的播放列表比她的更无聊,我讨厌在聚会上听到我自己的音乐。
这首歌是她的还是我的?机器学习方法
这个实验的最后一个目标是研究是否有可能使用机器学习来预测一首歌是属于我的播放列表还是她的播放列表。
对于那些完全不知道什么是机器学习的人,我将给出一个非常简单的解释,这基本上是从我的另一份工作中复制/粘贴的。
我喜欢将机器学习,特别是监督学习的子领域(我将在这里应用)定义为使用系统来学习数据集模式的任务。在这个学习过程中,该算法寻找一个最佳的数学函数,或者一种能够解释数据特征(即音频特征)之间关系的方式、、,以及被称为数据的标签或类别的东西(即播放列表的所有者,我或她)。因此,当系统已经学习了数据时,它应该能够使用它在学习步骤期间学习的知识来推断或预测一组新特征的类别。
在这项工作的情况下,这意味着我们将有一个用上一部分中使用的数据集训练的机器学习系统。所述系统应该能够确定一组新的音频特征是否用于更可能出现在我或她的播放列表中的歌曲。
在所有现有的机器学习模型中,我使用了一种叫做逻辑回归的模型。为了保持这篇文章简单友好,我不会解释逻辑回归是如何工作的。相反,我只想说这是一个数学等式,其中目标变量,称为因变量,或我们想要预测的东西(在这种情况下,它是播放列表的所有者),取决于一个或几个自变量(音频特性),加上一些魔法。大概是这样的:
dependent_variable = magic(independent_variable_1 + independent_variable_2 + …)
因变量的值是一个介于 0 和 1 之间的数字,在这种情况下,该值表示一首歌属于我的播放列表或她的播放列表的概率——如果该值小于某个阈值 X,则这首歌属于我,否则它属于她。
在展示结果之前,我想为对该主题有所了解的读者描述一下培训设置。使用 网格搜索和交叉验证 获得模型参数 alpha 和迭代次数。找到的最佳配置如下:
- 处罚:弹力网,
- 阿尔法值:0.001
- 迭代次数:50
以下代码片段(Python)是用于训练模型的代码。
parameters = {‘alpha’: (0.001, 0.0001, 0.00001, 0.000001),‘penalty’: (‘l2’, ‘elasticnet’,),‘n_iter’: (10, 50, 100),‘loss’: (‘log’,)}# Perform a grid search with cross validation to search for the best parameters.grid_search = GridSearchCV(SGDClassifier(), parameters, n_jobs=-1, verbose=1, cv=5, scoring=’accuracy’)grid_search.fit(data, labels)
结果出奇的好!在几个训练和测试部分中,平均准确率为 82% ,换句话说,模型能够预测这首歌属于谁的播放列表的次数为 10 次中的 8 次。
一旦模型被训练,它就用两首在训练中没有遇到的歌曲进行测试。第一首歌名为一个更好的开始,来自视频游戏 Mass Effect Andromeda,预测是“我”,而蕾哈娜的第二首歌 Love On The Brain 是“她”。相当准确。
结论
在这篇文章中,我展示了一个关于我的音乐的愚蠢的评论或观点是如何变成一个实验的。通过使用 Spotify 的 audio features API 组件,我能够发现,正如我的朋友所说,我的播放列表是多种多样的,充满了器乐,而且有些无聊。为了补充这种分析,训练了机器学习模型逻辑回归,目的是根据歌曲的音频特征预测歌曲是否更适合我或她的播放列表。该模型的准确率为 82%,相当不错。
所有用到的代码都可以在https://github . com/Juan des/Spotify-audio-features-data-experiment获得。这包括用于获取数据和训练机器学习模型的 Python 脚本,以及用于分析的 R 脚本。
关于 Spotify 音频功能的更多信息,请查看 https://developer.spotify.com/web-api/get-audio-features/的官方文档,关于逻辑回归的介绍,我推荐以下文章:机器学习的逻辑回归
如果任何人发现任何打字错误,不一致,或想问或说些什么,请做评论:)
感谢阅读。
在线教育是未来的发展方向吗?
原文:https://towardsdatascience.com/is-online-education-the-way-forward-a91ed4bb204c?source=collection_archive---------19-----------------------
由于教育成本不断上升,与传统教学方法相比,世界正朝着 MOOCs 的方向发展。他们能成为合适的替代者吗?(第一部分)
今年早些时候,我偶然看到一篇关于美国教育债务危机的文章,这促使我看一看替代方案,在线教育似乎已经成为试图解决这一问题的一颗新星。但这真的是前进的方向吗?
Infographic Credits: Niall McCarthy
我很难相信它们能成为合适的替代品。那么,这只是一种时尚吗?还是有帮助?让我们来了解一下!
我拿起一个数据集,它给出了两个领先机构——麻省理工学院和哈佛大学——提供的 MOOC 数据。(2012–2016)
探索:
被审核的 v/s 认证参与者的百分比是多少?
性别、年龄统计数据
可能的挑战和有趣的见解
MOOC 的参与和认证总数是如何随着时间的推移而增长的?
MOOC 用户中有百分之多少的人获得证书?
一些有趣的见解:
MOOCs 的发展和随后的学生参与
Number of courses as well students have gradually been rising over the years
毫无疑问,它从一开始就很受欢迎,每年增长近 2 倍。绘制过去四年的“总参与者”图显示,仅去年的注册人数有所下降,从 160 万下降到 120 万。我将 Harvardx/MITx 课程在第四年的平均参与者/课程和总注册人数中的下降归因于 MOOC 平台、选项和更简单的课程形式的更多竞争。Harvardx/MITx 趋势可能不代表整体趋势,因此,这并不意味着在线学习的下降。
然而,在这四年中,有 240 万独立用户参加了一门或多门 MITx 或 HarvardX 开放式在线课程,245,000 名学员在成功完成一门课程后获得了证书,这使得我们的完成率接近 10%,并且在四年中平均每天有 1,554 名新的独立参与者注册。
我认为,如果来自其他 mooc 的数据附加到这个 Harvardx/MITx 数据集,我们可能会看到 mooc 的受欢迎程度有所增长,而不是下降。
向“技术”的转变
Computer Science seems to be leading the pack in terms of student participation
- 计算机科学课程是最大的(例如,在科学、历史、健康和其他学科中),并且将更多的参与者引导到其他学科领域,而不是他们所接受的领域。
- 我们注意到,2014 年麻省理工学院参与者的下降是因为哈佛大学的两门计算机科学课程变得流行。除此之外,参与率稳步上升,而认证在下半年有所放缓。这可以归功于 2016 年初停止的免费认证的取消。
- 此外,对课程的细分显示,CS 课程最受欢迎,CS 课程在
视频时间方面最密集,这主要归功于 MITx(著名的编程入门课程!)
MOOC“课堂”的参与者背景和意图各不相同。
- 一门典型的课程认证 500 名学员,其中 7,900 名学员在注册后可访问部分课程内容,约 1,500 名学员选择探索一半或更多的课程内容。
- 值得注意的人口统计数据包括 29 岁的中位学习者年龄,2 比 1 的男女比例(67%的男性,33%的女性),以及来自其他国家的学习者的大量参与(71%来自国际,29%来自美国)。
整个 viz 可以在这里找到——很乐意听到你的反馈!
如果要考虑完成率..
Credits: http://www.katyjordan.com/MOOCproject.html
HarvardX 和 MITx 最近报告称,只有 5.5%注册了他们的开放在线课程的人获得了证书。如果从广义上看,这些数字接近 15%,但这似乎是唯一等待解决的挑战。
虽然这一初步探索确实令人兴奋,但我希望在第 2 部分中更深入地挖掘——敬请期待!
接下来是什么?
探索:
了解行为模式(群组 v/s 自定进度)
我想做什么?与运行各种代码学校的人交谈,了解什么是秘方和前进的道路(所以如果你们中的任何人能够将我连接到相关的人,那将是令人敬畏的!)
发现数据支持的成功案例
如果你对改变在线教育的未来有一点点兴趣和/或想抓住一些(虚拟!)咖啡,打我一下!
[## your product guy(@ MotwaniSuhas)| Twitter
yourproductguy 的最新推文(@MotwaniSuhas)。# just keep experimenting | Ed-tech/CPG | Hmu 如果我能帮忙…
twitter.com](https://twitter.com/MotwaniSuhas)
乙状结肠后的 ReLU 不好吗?
原文:https://towardsdatascience.com/is-relu-after-sigmoid-bad-661fda45f7a2?source=collection_archive---------4-----------------------
最近有一篇关于深度学习的心理模型的博客文章,从光学角度进行了类比。我们对一些模型都有直觉,但很难用语言表达出来,我相信有必要为这个心智模型共同努力。
Sigmoid graph from wikipedia
最近我和 Rajasekhar(为一个 KWoC 项目)正在分析不同的激活函数之间如何相互作用,我们发现在最后两层的 sigmoid 之后使用 relu 会恶化模型的性能。我们使用 MNIST 数据集和一个四层全连接网络,第一层是 784 维的输入层,然后第二层是 500 维的隐藏层,之后是另一个具有 256 维的隐藏层,最后是 10 维的输出层。除了输入层,我们对每一层的输出使用非线性。由于我们将研究限制在四个激活函数( ReLU,Sigmoid,Tanh,卢瑟),我们可以通过激活函数的不同组合构建 64 个不同的模型。我们在所有模型中使用随机梯度下降,学习率为 0.01,动量为 0.5。我们在所有实验中使用交叉熵损失和 32 的批量大小。我们对每个模型进行了 9 次实验,精确度的平均值和标准偏差显示在[ nishnik/sherlocked 的表格中。我在这里简单总结一下:
- 如果第一层有 relu 激活,第二层和第三层有除(sigmoid,relu)之外的(relu,tanh,sigmoid,relu)的任意组合,则平均测试精度大于 85% 。对于( relu,sigmoid,relu ),我们得到的平均测试精度为 34.91%
- 如果第一层有 tanh 激活,第二层和第三层有除(sigmoid,relu)之外的(relu,tanh,sigmoid,relu)的任意组合,则平均测试精度大于 86% 。对于( tanh,sigmoid,relu ),我们得到的平均测试精度为 51.57%
- 如果第一层有 sigmoid 激活,第二层和第三层有除(sigmoid,relu)之外的(relu,tanh,sigmoid,relu)的任意组合,则平均测试精度大于 76% 。对于( sigmoid,sigmoid,relu ),我们得到的平均测试精度为 16.03%
- 如果第一层有卢瑟激活,第二层和第三层有除(sigmoid,relu)之外的(relu,tanh,sigmoid,relu)的任意组合,那么平均测试精度大于 91% 。对于(卢瑟,sigmoid,relu )我们得到的平均测试准确率为 75.16%
- 如果最后两层具有( sigmoid,relu )的话,精确度的变化也很大
我们也在 CIFAR-10 上进行了实验,结果是相似的[ 链接 ](抱歉格式错误)。在最后两次激活为( sigmoid,relu )的每种情况下,准确度为 10% ,否则准确度≥ 50%。
然后,我们在每一层中使用批规范进行实验。和其他组合一样,精确度也有了很大的提高。[MNIST 的结果 ]。同样,在最后一层使用 batchnorm 就像 charm 一样让模型学习。
因此,对于最后两层中的( sigmoid,relu )来说,模型不能学习,即梯度不能很好地反向传播。(sigmoid(output_2)* weigh _ 3+bias _ 3)<大多数情况下为 0,或者 sigmoid(output _ 2)正在达到极值(消失梯度)。这两个我还在做实验。在twitter.com/nishantiam给我一些建议,或者在[nish Nik/Sherlock上制造一个问题。
圣诞老人是真的吗?
原文:https://towardsdatascience.com/is-santa-claus-real-9b7b9839776c?source=collection_archive---------1-----------------------
我的团队非常重视圣诞节和我们收到的礼物。所以,我们想追踪圣诞老人,知道他什么时候给我们送礼物。我们决定在烟囱里放一个摄像头,找到他。最近我们看到了这个帖子关于如何为你自己的数据集训练 Tensorflow 的对象检测 API,这说服我们把我们的手放在这个很酷的东西上,并试图找到圣诞老人。
代码可在这个 github repo 获得。从这段代码生成的模型可以扩展到寻找其他角色,无论是动画还是现实生活中的角色。
这是圣诞老人发现者的行动。🎅🏻
收集数据
和任何机器学习模型一样,最重要的方面是数据。因为我们想找到不同类型的圣诞老人、动画、泥塑、装扮成圣诞老人的人,所以我们的训练数据必须多样化。为了收集数据,我们编写了一个流处理器,它使用 VLC 从任何在线来源传输视频并从中捕获帧。流处理器捕获视频中的帧,而不必等待视频加载,即,如果当前播放的视频在 2 秒标记处,则流处理器将从 4 或 5 秒标记处捕获帧。作为奖励,你可以用 ASCII 码观看视频,这是最酷的观看视频的方式🤓。使用流处理器的指令可在这里获得。
Video of Santa Claus surfing in ASCII
这里是我们收集的不同类型的圣诞老人图像的一个小集合。所有这些图片都是从 YouTube 上收集的。如你所见,这里有不同种类的动画和真人圣诞老人的图像。
Different type of Santas
标注数据
下一步是标记数据,即围绕圣诞老人的脸画一个边框。标记图像的一个常见选择是使用 labelimg 工具,但是我们使用了一个从这篇文章引用的自定义脚本。
要给图像加标签,先点击人物脸部的左上角,然后点击其脸部的右下角。如果图像中没有字符,双击同一点删除图像。该脚本的代码可从这里获得。
创建张量流记录文件
将边界框信息存储在 csv 文件中后,下一步是将 csv 文件和图像转换为 TF 记录文件,这是 tensorflow 的对象检测 API 使用的文件格式。将 csv 文件转换成 TF 记录的脚本可以在这里找到。
还需要一个 protobuf 文本文件,用于将标签名转换为数字 id。对于我们来说,它只是一个类。
item {
id: 1
Name: santa
}
创建配置文件
为了训练,我们使用 faster_rcnn_inception_resnet 配置文件作为基础。我们将配置文件中的类的数量参数更改为 1,因为我们只有一个类——“Santa”,并将输入路径参数更改为指向我们在上一步中创建的 TFrecord。我们使用了 faster _ rcnn _ inception _ resnet 的预训练检查点。我们使用这个模型是因为模型精度比模型训练速度更重要。还有其他模型提供不同的训练速度和准确性,可以在这里找到。
训练
训练代码在我们的本地机器上运行,以检查一切是否正常,一旦正常,它就被部署到谷歌云平台的 ML 引擎。该模型被训练了超过 100,000 步。
Animation
该模型在动画和现实生活中表现都很好。
Real Life
导出模型
训练完成后,模型被导出,用于在不同的图像上进行测试。为了导出模型,我们选择了从训练作业中获得的最新检查点,并将其导出到冻结的推理图中。将检查点转换为冻结推理图的脚本可以在这里找到。
我们还为我们的模型构建了一个网页,它从 google 搜索中提取图像,并试图在返回的图像中找到圣诞老人。该网页上的结果被过滤以显示置信度超过 60%的边界框。这是网页的快照。
We Found Santa Claus!!
后续步骤
当训练作业运行时,我们注意到 TotalLoss 很快下降到 1 以下,这意味着模型在寻找圣诞老人方面做得很好。
TotalLoss
我们知道我们的模型不会完美。虽然模型在相当准确地找到圣诞老人方面做得很好,但我们也有假阳性。在这种情况下,假阳性是没有圣诞老人的图像,但模型预测有。
False Positive
在使预测更加准确和减少假阳性的数量方面,还有很大的改进空间。
接下来的步骤是了解更多关于配置文件中不同参数的信息,并更好地了解它们如何影响模型的定型及其预测。
结论
我们希望您现在可以为自己的数据集训练对象检测器。在这一点上,我要感谢希瓦吉·什罗夫和 T2·乔希·库尔茨,他们在项目建设中发挥了同等的作用。
感谢你的阅读,希望你喜欢这篇文章。如果您有任何问题或建议,请随时通过 LinkedIn 联系我们,地址是 Varun Vohra 和 Shivangi Shroff 。我们非常乐意收到任何反馈。
食品配送时间预测介绍
原文:https://towardsdatascience.com/is-the-food-here-yet-f13a7bb0cd20?source=collection_archive---------1-----------------------
提示:不仅仅是谷歌地图
Prepare yourself for food. — Photo by Dan Gold on Unsplash
配送时间预测长期以来一直是城市物流的一部分,但最近精确化对于 Deliveroo、Foodpanda 和 Uber Eats 等按需配送食品的服务变得非常重要。
这些服务和类似的服务必须在收到订单后 30 分钟内送达,以安抚用户。在这些情况下,+/- 5 分钟可能会产生很大的差异,因此,初始预测的高度准确性以及任何延迟的有效沟通对于客户满意度非常重要。
It’s a real problem. Credit: @bustle.
在本文中,我将讨论我为一家食品配送初创公司构建(真实世界)配送时间预测模型的经验,以及它是如何给出比我们训练有素的运营团队更好的预测的。
本文将涉及机器学习的技术主题,同时重点关注创建功能良好的预测模型所需的业务知识。为了你的阅读乐趣,也将包括进一步阅读的外部资源的链接。
我们的路线图:
- 📝问题陈述
- 🔢数据
- ⚒️工具包
- 📈模型结构
- 🤔改进估计
问题陈述
首先,让我们制定一个我们可以使用的问题陈述。这将有助于我们专注于目标。
我们希望建立一个模型,它将把有关食品交付的数据作为输入,然后输出所需的提货时间,以传达给司机。
其他一些需要注意的事项:
- 交货量很大,可以假定需要汽车。
- 供应商(或多个供应商)的范围从餐馆到餐饮供应商,可以有非常不同的特点。
- 可以假设司机在指定的接车时间准时到达供应商处。在现实中,这并不总是正确的,但是如果有足够数量的驱动程序,这可以保持在最小的数量。
- 食物不应该送得太晚,因为顾客会等待和生气,也不应该送得太早,因为在顾客准备吃之前,食物必须放在外面。
Late deliveries = melted ice cream; every child and sugar-loving colleague’s worst nightmare. Photo credit The Food Passionates/Corbis.
数据
作为我们模型的输入,我们有三类典型的此类问题的数据:
- 点餐:人们在点什么?他们向哪个供应商订购?什么时候送货?
- 顾客:谁在点菜?它们位于哪里?
- 交付结果:对于之前的交付,我们的表现如何?每一步花了多长时间?
交货可用数据的一个例子是:
Delivery Team : Deliveries 'R' Us
Order_ID : 12345
Agent_Name : Bob Driver
Supplier : Delicious Donuts
Customer : Big Corporation Inc.
Pickup_Address : Shop 1, Busy Street, 23456, Hong Kong
Delivery_Address : Level 9, Skyscraper, 34567, Hong Kong
Delivery_Time : 29/05/2016 08:00:00
Order_Size : $500
由于我们有大量的文本,我们需要首先处理数据,使其成为机器可用的格式。
可以使用正则表达式处理这些地址,以获得更多结构化信息。重点是:楼层、楼栋、邮编、地区、国家。
经过上述处理后,可以将建筑物、邮政编码、区域和邮政编码与其他变量组合起来进行一次热编码。一个热编码将为每个可能的文本创建许多二进制变量。这些数字变量可以输入到我们的模型中。你可以在这里阅读更多关于一次热编码的介绍。
培养
为了训练模型,我们将使用以前交货的数据,这包括预测交货时间和实际交货时间(我们练习的目标变量)。出于本文的目的,我们将使用大约 1000 个数据点。
工具包
在深入研究之前,我们应该考虑什么模型最适合解决我们所面临的这类问题。Scikit-Learn 文档中的下图给出了一个决定应该使用哪种算法的好方法。
Who said Machine Learning is a tough discipline? Credit: Scikit-Learn Documentation.
让我们看看我们对我们的问题有什么了解:
- 如前所述,我们有 1000 多个数据点用于训练。
- 模型的输出应该是一个数值。
- 由于一次性编码,我们剩下了相当多的二进制变量,这意味着许多特性可能是重要的。
考虑到这一点,我们可以按照上面的图表来实现岭回归和具有线性核的 SVR。为了简单起见,我们将只使用岭回归,并添加一个随机森林回归器,以查看它对数据的不同表现。
如果您对更多的背景感兴趣,您可以阅读 Scikit-Learn 文档中相应页面上的算法:岭回归、 SVR(支持向量回归)和随机森林回归。
性能指标
我们还应该注意我们将用来判断模型有效性的指标。
我们可以用平均绝对误差( MAE )来快速了解我们的性能。这告诉我们我们的交付时间估计和实际交付时间之间的平均差异。
更进一步,我们可以定义另外两个特定于领域的指标:
- 基本准时(< 5 mins late)
- OK, we’re a 少晚(<晚 10 分钟)
这两个指标告诉我们让用户不高兴的频率。如果我们迟到 15 分钟或 25 分钟,对用户来说并不重要,我们只是真的迟到了。MAE 没有意识到这一点,会认为一个比另一个差,但就业务而言,这实际上是一回事,我们的模型理解这一点很重要。
注意:我们实际上将使用这些指标的倒数(即延迟 5 分钟以上的交付),因为它们更容易使用。
因此,快速回顾一下:我们知道我们需要做什么,我们知道我们必须用什么数据来做这件事,我们也知道我们将要做的方式,所以让我们开始做吧!
模型结构
Thankfully data science doesn’t require so many hands. Photo credit: Rand Faith.
让我们想一想送餐都涉及哪些内容。我们可以把它分成三个主要部分:
- 从供应商那里拿食物。
- 从供应商到客户。
- 把食物交给顾客。
我们可以预测每个组件所需的时间,然后将这些时间加在一起,得到最终的交付时间。
Delivery Time = Pick-up Time + Point-to-Point Time + Drop-off Time
或者,我们可以训练一个模型来预测整个交付时间。我们应该打破这个的原因是创造专业模型,它将比一个通用模型有更好的能力。如果我们用人来代替模型,这就说得通了。在你的业务开发团队中,你会有一个非常了解供应商以及他们可能需要多长时间交货的人。在你的客户服务团队中,你会有一个非常了解每个客户的人,他可以根据他们的位置和建筑来预测送货可能需要多长时间。我们在构建我们的流程时考虑到了这一点。
现在我们有了三个阶段,让我们深入其中并构建我们的模型。
供应商提货
当司机到达一个目的地时,他被要求找到一个停车场,拿起食物并回到车上。让我们探讨一下在这个过程中可能出现的潜在并发症。
- 没有公园:对于位于市中心的餐馆来说,与位于居民区的餐馆相比,这要困难得多。为了获取这些信息,我们可以使用邮政编码或纬度/经度信息。我发现邮政编码特别有价值,因为它们的特殊结构捕获了高级通用信息。
- 难以进入:餐馆往往很容易进入,因为它们依赖于此来为顾客服务,但餐饮服务提供商可能位于工业区,而且没有明显的入口,这使得进入变得更加困难。与上面类似,我们可以在添加供应商类别时使用位置信息。
- 食物未准备好:由于订单量可能很大,食物未准备好的情况并不少见。为了解决这一问题,可以在取餐当天联系餐饮服务商,检查食物是否会按时准备好。对这些信息的回应将是理解我们时机的有用标志。特定供应商是否有历史记录也是有用的输入。最后,订单大小是一个很好的指标;准备少量食物时不会出什么问题,但如果是 100 人份的食物,就更有可能出问题。
- 订单中缺少一些东西:司机应该在到达时检查订单,在某些情况下,他们可能会发现订单中缺少一些东西。这意味着他们必须等待额外的食物准备好。同样,这可能取决于供应商以及他们提货时的繁忙程度。
对于这部分问题,我们将使用以下数据点:
Supplier : Delicious Donuts
Customer : Big Corporation Inc.
Pickup_Address : Shop 1, Busy Street, 23456, Hong Kong
Delivery_Time : 29/05/2016 08:00:00
Order_Size : $500
执行上述处理后,可将数据输入我们的 Scikit-Learn 模型,结果如下:
Baseline Results:
Mean Absolute Error: 544 seconds
Greater than 5 mins late: 55%
Greater than 10 mins late: 19%
Random Forest Results:
Mean Absolute Error: 575 seconds
Greater than 5 mins late: 42%
Greater than 10 mins late: 22%
Linear Regressor Results:
Mean Absolute Error: 550 seconds
Greater than 5 mins late: 44%
Greater than 10 mins late: 17%
Ensemble Results:
Mean Absolute Error: 549 seconds
Greater than 5 mins late: 45%
Greater than 10 mins late: 17%
可以看出,如果我们使用平均绝对误差(MAE)的基本度量,所有模型的表现都比基线模型差。然而,如果我们看一下与食品配送业务更相关的指标,我们会发现每种模式都有其优势。
随机森林模型将延迟超过 5 分钟的订单减少了近 25%。线性回归器在减少延迟 10 分钟的订单方面做得最好,大约 10%。有趣的是,集合模型在两个指标上都做得相当好,但值得注意的是,它在三个模型中具有最小的 MAE。
当选择正确的模型时,业务目标是第一位的,它决定了我们对重要指标的选择,从而决定了正确的模型。有了这个动机,我们将坚持整体模型。
点对点
出于多种原因,估计目的地之间的旅行时间是一项棘手的任务;有成千上万的路线可供选择,不断变化的交通状况,道路封闭和事故;所有这些都为您创建的任何模型提供了如此多的不可预测性。
幸运的是,有一群人对这个问题进行了长时间的思考,并收集了数百万个数据点来帮助更好地了解环境。谷歌进来了。
Our friend (and potential future overlord). Credit: Wikimedia.
为了预测点到点的旅行时间,我们将使用已知的上车点和下车点调用 Google Maps API。返回的结果包括考虑交通和最坏情况场景的参数,我们可以将这些参数用作模型的输入。对 API 的调用非常简单,看起来像这样:
gmaps = googlemaps.Client(key='MY_API_KEY')params = {'mode': 'driving',
'alternatives': False,
'avoid': 'tolls',
'language': 'en',
'units': 'metric',
'region': country}directions_result = gmaps.directions(pick_up_location,
drop_off_location,
arrival_time=arrival_time,
**params)
有了这个,我们就可以对一个已经深思熟虑过的问题得到一个高度准确的结果。重要的是不要重做工作,
如果你的问题已经有了足够好的解决方案,就不要多此一举了。
在实施这一模式之前,我们的组织使用公共的谷歌地图界面来预测送货时间。因此,我们的新模型在这部分旅程中的性能与基线完全相同。因此,我们不会在这里计算任何比较。
一个重要的旁注是地址的格式并不总是正确的!当查询谷歌地图时,总有可能他们会说“嗯……我不知道”,对此我们必须有一个答案。这是人类和机器必须如何合作的一个很好的例子。每当地址格式不正确时,操作员都有可能介入并澄清地址,甚至给客户打电话澄清信息。
这样,我们就可以继续我们模型的第三部分了。
顾客下车
一旦司机到达地点,他们必须找到一个公园,把食物送到正确的人那里,并得到最后的签字。这一过程中的潜在问题包括:
- 停车场有高度限制:这很简单,但许多送货都是在货车上进行的,在这种情况下,可能会有高度限制,阻止司机使用主入口。
- 建筑没有停车场:这是显而易见的。没有停车场意味着司机在送货时必须花时间开车四处寻找停车的地方。
- 大楼安全问题:大多数现代办公大楼都需要安全卡才能进入。在最好的情况下,司机可以简单地刷卡通过,但在最坏的情况下,司机可能被要求去一个单独的位置,注册一张卡,然后使用后门。
- 高楼层或棘手位置的客户:这听起来可能很荒谬,但有些办公楼很难通过不同楼层的不同电梯,对于较小的公司来说,它们可能隐藏在迷宫般的走廊中。
有了所有这些,邮政编码是一个很好的指标,因为它告诉我们,如果我们可以期待一个商业区或住宅区。我们还可以进一步深入地址。例如,如果我们有 40 级,很明显,交付是在一个大的塔块,可能会有一个复杂的安全程序。
对于这部分问题,我们将使用以下数据点。
Customer : Big Corporation Inc.
Delivery_Address : Level 9, Skyscraper, 34567, Hong Kong
Delivery_Time : 29/05/2016 08:00:00
Order_Size : $500
在执行典型的处理和运行我们的模型之后,我们看到以下内容:
Baseline Results:
Mean Absolute Error: 351 seconds
Greater than 5 mins late: 35%
Greater than 10 mins late: 0%
Random Forest Results:
Mean Absolute Error: 296 seconds
Greater than 5 mins late: 15%
Greater than 10 mins late: 7%
Linear Regressor Results:
Mean Absolute Error: 300 seconds
Greater than 5 mins late: 14%
Greater than 10 mins late: 5%
Ensemble Results:
Mean Absolute Error: 293 seconds
Greater than 5 mins late: 13%
Greater than 10 mins late: 6%
在这里,我们可以看到 MAE 减少了 17%,比以前好得多。类似地,我们看到超过 5 分钟的订单减少了 63%。另一方面,该模型确实将延迟订单数从 0%增加到 6%。同样,我们面临着各种模式之间的权衡,这两种模式各有千秋,我们必须让我们的业务 KPI 成为决定性因素。
把所有的放在一起
我们现在可以用下面的公式将我们的模型结合在一起:
Delivery Time = Pick-up Time + Point-to-Point Time + Drop-off Time
+ Hyperparamater
注意这次增加了一个超参数。我们将加入这一点,以考虑到我们在数据中看到的任何其他奇怪的影响,例如接站时间总是提前 5 分钟,以满足司机的期望。我们将设置该参数,以便在计算组合结果后最小化最终误差指标。
综上所述,我们得到了最终结果:
Baseline Results:
Mean Absolute Error: 1429 seconds
Greater than 5 mins late: 60%
Greater than 10 mins late: 19%
Ensemble Results:
Mean Absolute Error: 1263 seconds
Greater than 5 mins late: 41%
Greater than 10 mins late: 12%
因此,我们的最终模型在所有指标上都比基线模型有了显著的改进——我们做到了!
That feeling when your food finally arrives! Photo credit: Sander Dalhuisen.
最重要的是,我们发现延迟 10 分钟以上的订单减少了近 40%!我们能够实现这一目标,是因为我们开发了三个独立的模型,这些模型针对各自特定的业务问题进行了优化。将它们结合起来,并在最后阶段进行微调,确保我们生产出的模型达到了专业人员的水平。
做出更好的估计(不改进你的模型)
拥有一个更加精确的模型当然很好,但是由于收益递减法则,这也需要付出更多的努力。相反,如果我们多考虑商业案例,少考虑机器学习,就会有其他解决方案。
迟到和早退
你可能一开始就记得,这个模型是针对餐饮配送的,也就是说我们提前知道配送时间。避免延迟交付的一个简单方法是获取模型输出的任何值并增加它,以确保我们足够早。
这不是一个很好的解决方案,因为太早也有一个问题,食物可能会变坏或没有准备好。但是,它确实提出了一个观点,即我们应该考虑''和''提前量的分布。也许早 10 分钟比晚 5 分钟更好。到目前为止,我们还没有针对这种情况进行优化,因此我们可以重新考虑这一点并进行相应的优化。**
交付窗口
另一件要考虑的事情是模型如何呈现给用户。如果用户被告知你会在下午 2 点到达,而你没有,他们会很沮丧。如果你告诉某人你会在下午 1:45-2 点到达那里,那么你可以在下午 1:50 到达,如果你晚了一点,你还有余地。
将机器学习问题作为实际现实世界问题的解决方案来考虑总是很重要的——这种背景通常可以导致“改进”,否则从模型本身是不可能的。
供应商反馈
这种模式的一个关键优势是能够有效区分供应商不同的准备时间。这告诉我们,供应商必须有非常不同的表现。
深入调查后发现,司机在一些供应商处花费的时间是他们的 3 倍。有了这些信息,回到商业领域,就有可能与供应商进行讨论并确定问题,从而减少在这些供应商处花费的时间,并通过减少变化来提高模型的整体性能。
包扎
我们从预测食物配送时间的问题陈述开始。我们决定使用什么样的数据以及应该做什么样的处理。我们思考什么是解决我们特殊问题的最佳模式。然后,我们将我们的问题分解为三个部分,以构建目标模型,最后将它们组合在一起,创建一个全功能的预测模型。然而,我们并没有止步于此,我们利用我们的业务知识来提高我们模型的有效性。
这导致延迟 10 分钟以上的订单减少了 40%,这可以直接转化为退款节省的资金。它还有助于减轻运营团队的负担,这意味着他们可以专注于更有意义的任务,如提高供应商效率。
如上所述,这是可用于应用机器学习来解决业务问题的一般程序。这种方法确保在以后为额外的几个百分点的改进进行优化之前,先把基础做好。这是我成功使用过的一个方法,我希望你也能成功。
如果你喜欢读这篇文章,请不要忘记留下一两下掌声,或者三下……👏👏👏🔄
如果你想了解为什么使用高科技(比如这篇文章)并不总是最好的解决方案,请看这里:
** [## 业务自动化,简单的方法
在我们这个以技术为中心的世界里,将外包作为自动化可以节省您的时间和金钱
medium.com](https://medium.com/@jyesawtellrickson/business-automation-the-easy-way-5f9bbc896bcc)**
未来是人类还是机器人?
原文:https://towardsdatascience.com/is-the-future-human-or-robot-1eace17c3b25?source=collection_archive---------2-----------------------
这篇文章是关于做人的。最后有一些关于与技术共存的注释。我希望你读了这两部分。
那么未来是人还是机器人?
没有。
是电子人。实际上它不在未来,它已经在这里了。已经有一万年了。也许它已经在这里 10 万年了。
什么是电子人?半人半机器人?
看看你现在的样子。你怎么看这个?你在使用技术,对吗?
你正在利用你天生的技术能力,使你不仅仅是人类。
对吗?
或者这让你成为了一个普通人。
和其他一些与我们共享这个世界的生物一样,我们也是工具使用者。我们曾经使用的每一个工具都是技术。
是什么让我们变成这样?我们不是唯一的。乌鸦会这么做。其他灵长类动物。头足类使用工具(鱿鱼:我在谷歌上查了属)。这并不需要太多,但这一点点差别就是一百万英里。
这种差异与记忆有关。
召回至关重要。即使我们只能回忆起一点点,那么我们意识到一个过去。我们记得过去的一个自己。
这种记忆发生在现在,它不存在于过去,所以你可以说这是一个故事。一个关于我们过去的故事。一个猜想。
这种对过去的记忆,即使是短暂的过去,也是自我的叙述。我的故事。
这是关键。我们周围的故事。如果我们能讲述一个关于我们过去的故事,一个在现在的经历中得到证实并且有意义的故事,我们就内在地感觉到一个随后的现在。
这暗示着未来。在未来,我们可以对自己进行类似的描述。这些想法是故事,是我们不断告诉自己的故事,是一连串的文字、感觉和图片。
自我的分离或客观化也是其中的一部分。如果我从我的环境中分离出来,是其中的一个东西,如果你愿意,那么我就是在我的环境中识别事物。我的自我就是这些对象中的一个。
随着物体被识别为独立的东西,我可以开始创造一个幻想,将它们视为我的故事的一部分。
一旦一个物体在故事中获得了一个角色,它就获得了一个本质,一个故事的目的。它获得了一个概念生命,它的过去和未来与我们分享的现在融为一体;它成为我们自我概念的一部分,也许带有精神或迷信的成分,也许主要是实际的。最受欢迎的工具既有感性的概念部分,也有实用的概念部分。
这可能是你最喜欢的珠宝,一份特别的礼物,标志着充满感情的记忆,一辆车,一栋房子,你最喜欢的领带,等等..
如果你是一个游戏玩家,你会在每一轮游戏中参与这个最古老的仪式。在不认为这个过程有什么神奇之处的情况下,游戏制作者把一些东西放在你的环境中让你探索,作为在游戏中帮助你的工具,你把它们放在你的虚拟工具包里,你的记忆库,在需要的时候使用。
我看着我的父亲渐渐患上了痴呆症。随着他回忆能力的丧失,他对自己是谁的感觉以及对未来的任何猜测能力也丧失了。记忆是他能够识别自己的关键。
和许多患者一样,即使在接近尾声时,对漫长过去的回忆也更加生动。有一次,他把我的妻子误认为一位著名的女演员,并向她背诵了一个小时完美的俄罗斯诗歌,这让我们非常开心,回忆起 60 年前他是商船队的一名信号官。
所以记忆创造了一种对过去的感觉,一个故事,而故事可以是关于任何事情的,包括未来。
在未来,我们可能会使用一种工具来使事情变得更好。
我们作为人类的标志是我们的自我叙述,这是技术的起源。
Crow 工具用户也在做同样的事情。对过去的记忆对于制定改善未来的策略至关重要。在信息技术中识别有意义的物体是电子人的行为。一些乌鸦是有思想的,可以从其环境中的物体中分离出意义和目的,并可以思考未来。
技术是我们在环境中创造性使用的每一种工具。故事是概念工具,绘画是概念工具,衣服和斧头和耕作更实用,时尚和美化更有创意。
技术在许多可能的方面有所帮助;生产力、利润、生存、友谊、快乐和愉悦。它们很容易让人上瘾,它们被到处复制,因为对自己过去和未来的相同推测被称为学习。
当依附于情感驱动时,它就变成了学习的动力。
自从我们第一次像人类一样思考,我们就与科技共同创造了我们的世界。从字面上看,它像山一样古老,但实际上却很年轻,这是我们的标志。
电子人创造技术,并利用它来发挥他们的自然能力。
电子人利用科技将他们带离狭隘,走向普遍。
我们是电子人,我们一直都是;这不是什么新鲜事。葬盆、农业、时尚、无线电、火箭技术和机器人技术;只需向前几步;每一步都是一场革命。
医学进步已经在这里了。它们无处不在,导致了生活质量和寿命的革命。当然,有一些问题,但是问问大多数髋关节置换的人,他们对不再疼痛的金属或陶瓷关节感觉如何。
使用机器人技术来增强我们在非本地环境中的生存能力是非常自然的一步。坐在火箭里是同样的事情,我看不出使用宇宙飞船,用我的声音或手在手持设备上搜索谷歌,以及植入这种能力之间有什么区别。
所以我想知道你对人工智能、机器学习、机器人、增强现实、虚拟现实等有什么感觉?已经到了。
周围有很多担忧,关于失业,失去目标,机器人接管人类的想法。
我认为这是一种错误的思考方式。对于今天的年轻人来说,我们周围的技术只是正常的环境。所有的父母都知道他们会立刻收养它。
他们天生就是电子人。自从我们第一次想到一个更好的未来的策略,我们都成了电子人。机器人只是技术,只是工具。
直到机器人或人工智能对他们的环境做出情感反应,他们才会在早上带着对日出的喜悦醒来,并梦想他们今天可能会做什么。
我们将一如既往地使用技术,不管是好是坏,但不要担心机器人会接管,至少在你准备好放下自己的智能手机、拒绝服用头痛药或微波午餐之前不会。
所以我们在这里,电子人,情感生物通过技术增强我们的可能性。我们是战略性的——技术填满了我们的梦想,也填满了我们的噩梦。
你是你自己的故事的作者。
你有控制权,因为你是叙述者。你是你自己的领袖,你可以把自己置身于自己的故事中。
最平凡的是,你在正确的时间采取正确的步骤,准时开始工作;钱,钥匙,电话,我走了。
也许,今天早上,看到这个平凡的梦想是战略思维的奇迹,它真的是。你可以现在就重写你的故事,决定今天谁将是你自己的英雄,你将持有什么原则和价值观,你将如何管理你的感情、希望和担忧,你今天将取得什么成就;你将成为什么样的人。
我会说不要担心外面的其他机器人。如果你改变,他们也必须改变。但是他们保留他们的选择,这只是你故事中的反馈,你总是可以用新的选择来回应,并希望升级而不是失去生命。
做一个战略性的小机器人,在你的下一章中,给你自己一个正确的方向。你只需要抬起头,考虑各种可能性,反思(梦想家!)然后挑一个你觉得更好的新的。然后穿上你的新鞋重新走出来。
如何在机器人的世界里生存
机器人、聊天机器人、人工智能和其他都是工具,就像你的衣服和化妆品一样。
不要害怕充满机器人的未来。
- 因为未来就是现在
- 因为这些工具比以往任何时候都更能利用人的能力。
因此,将有很多事情要做,直到机器人今天饿着肚子、快乐地醒来并想去海滩,它们将仍然是我们使用的工具,而不是相反。
在机器人的世界里生存的方法是投入并使用工具。这可能需要一些练习和挑战,就像你学会开车或使用笔记本电脑一样。
为了在机器人的世界中生存,你需要与其他人竞争,利用技术来发挥他们的能力。就像平常一样。你已经这么做了,对吧?你,已经是一个电子人了,你一直都是,所以冷静点,伸手去拿开瓶器。
国家的财富或教育支出与其学生在 PISA 中的表现有关系吗?
原文:https://towardsdatascience.com/is-there-a-relationship-between-countries-wealth-or-spending-on-schooling-and-its-students-a9feb669be8c?source=collection_archive---------2-----------------------
Photo by Vasily Koloda on Unsplash
介绍
公立学校在古代就已为人所知,许多社会发展了多年,最终在 19 世纪形成了强制性的公共机构。世界各地的社区都很重视教育年轻一代,为他们提供更好的未来,因为教育不仅对相关的个人,而且对整个社会都有很多好处。国家之间的竞争也不是一个新概念,教育只是进行跨国比较时要考虑的众多因素之一。尽管如此,现在人们似乎不仅在本地,而且在国际上比以往任何时候都更激烈地竞争工作,教育是获得优势的最重要的手段之一。想知道什么能帮助学生为进一步的学习、职业和生活做好准备,可能有许多因素应该被考虑进去。我们可能会问的一个问题是,我们能说出国家财富或教育支出与学生表现之间的关系吗?我们试着用一些开放的数据集,Python 语言,回归分析来回答这个问题。对于那些喜欢 Jupyter 笔记本形式的人,这里有一个到我的 github 的链接,里面有一个完整的项目库。
PISA 是什么?
你首先需要问自己的是如何衡量表现,也就是说如何判断一个国家总体上比另一个国家做得更好?经济合作与发展组织(OECD)投入了大量的资源来设计一个合适的比较方法。从 2000 年开始,他们每三年进行一次复杂的研究。国际学生评估项目(PISA)评估 15 岁学生在义务教育结束时获得的全面参与现代社会所必需的关键知识和技能的程度。评估的重点是学校的核心科目科学、阅读和数学。评估不仅仅是确定学生是否能够复制知识;它还考察了学生如何从他们所学的知识中进行推断,并在学校内外的陌生环境中应用这些知识。这种方法反映了这样一个事实,即现代经济奖励个人的不是他们所知道的,而是他们能用他们所知道的做什么。PISA 的调查结果使世界各地的政策制定者能够将本国学生的知识和技能与其他国家的学生进行比较,根据其他教育系统实现的可衡量目标制定政策目标,并学习其他地方的政策和做法。
最新的 2015 年报告中最有趣的发现是:
- 新加坡在科学领域的表现优于所有其他参与国家/经济体。日本、爱沙尼亚、芬兰和加拿大是经合组织中表现最好的四个国家。
- 平均而言,经合组织国家近 20%的学生没有达到阅读能力的基线水平。自 2009 年以来,这一比例一直保持稳定[1,第 3-4 页]。
提取 PISA 数据集
现在,我们对性能度量有了更好的理解,我们可以开始提取 PISA 数据集了。该分析基于熊猫的数据框架。 Pandas 是一个 Python 包,提供快速灵活的方法来进行实际的、真实的数据分析。
让我们首先为整个项目导入必要的库。
接下来,我们将读入包含 2000 年至 2015 年测试结果的 csv 文件。我们看到有 3 个独立的文件,分别是科学、阅读和数学成绩,这是它们在 OECD 数据库中的显示方式。为了一次了解所有文件的含义,我们将把它们作为一个字典来读取,字典中有考试名称的关键字和包含结果的数据帧的值。
我们看到原始数据帧由许多不相关的要素组成,因此让我们通过删除一些列并重命名现有列来执行必要的清理。
最新的 PISA 结果是在 2015 年收集的,因此我们可以使用过滤器来提取这些行。下一步我们将摆脱字典形式,因为我们大大减少了数据量。我们现在可以将所有的数据框合并成一个,这样我们就可以在一行中得到每个国家的数学、阅读和科学的结果。
all_pisa_2015.head()
当查看此数据框时,每个国家的名称并不总是显而易见的,因此为了提高清晰度,让我们在表中包括国家的名称。要构建从国家字母 3 代码到国家名称的转换图,你可以使用 pycountry 库。该字典需要一些调整,以便与分析中稍后使用的其他数据源兼容。事实证明,不同数据库中国家的官方名称差异很大。顺便问一下,你听说过捷克吗?
#add column with country name
name_code_dict = create_name_code_dict()
code_name_dict = reverse_dict(name_code_dict)
add_country_name(all_pisa_2015, code_name_dict)all_pisa_2015.head()
很高兴看到不同测试对象之间的所有数据分布,但对于基本分析来说,计算每个国家的平均结果似乎是正确的。包含每个考试部分之间的关系可能会导致过度绘制和不必要地扩展回归分析。
提取 GDP 数据集
现在我们有了 PISA 结果,我们可以进入下一步,提取 GDP 数据。多年来,我们接受 GDP 作为衡量一个国家整体经济表现的诚实标准,因此我们将使用人均 GDP 指标来回答一个问题——在评估中,较富裕的国家表现更好吗?
首先,让我们为有测试结果的国家生成一个代码列表。我们将在下一个函数中使用它作为参数。
然后,由于世界银行 API 和 Python wbdata wrapper,我们可以轻松地将所需数据直接加载到 Python shell 中,知道我们对哪些指标感兴趣。要了解这个有用工具的更多信息,请访问这个博客帖子。
使用一个国家的国内生产总值指标,你会发现它有很多版本,你必须决定哪一个适合你的目的。我决定以人均 GDP购买力平价为基础,因为它能更好地比较国家间的财富。如果你不熟悉名义 GDP 和购买力平价 GDP 的区别,我建议你阅读这篇文章。
同样,我们的数据框架需要一些争论。让我们首先过滤与 PISA 结果相同年份的所有行,即 2015 年。如你所见,GDP 数据是一个多指数数据框架。我们可以将索引重置为简单的整数,并使用列标签来执行各种操作。最后,我们将添加一个带有国家代码的列,以便稍后进行合并。
PISA 平均成绩与人均 GDP 的回归分析
回归分析应该能够产生一个方程,该方程将使用一个或多个自变量(人均国内生产总值)来预测因变量(平均 PISA 结果)。仅仅使用一个独立变量似乎不足以解释因变量的所有可变性,但是我们仍然可以试图理解它本身如何影响结果。运行回归时,您试图发现自变量上的系数是否真的与 0 不同(因此自变量对因变量有真正的影响),或者与 0 的任何明显差异是否只是随机的。零(默认)假设总是每个独立变量绝对没有影响(系数为 0),你正在寻找拒绝这一理论的理由[6]。我们将使用普通最小二乘法( OLS )建立 PISA 结果和人均 GDP 之间的关系模型。
在执行回归之前,我们需要快速查看一下我们清理过的数据,以便预先检查关系。让我们使用 alpha3 代码值合并两个数据帧,然后查看散点图。
我们可以看到,图中的点不一定形成一条直线,这提醒我们应该采用 GDP 数据的对数来进行线性回归分析。这有助于使我们的分布不那么偏斜。
现在我们的数据形成了类似直线的东西,但仍然有一个点似乎是线性模型的异常值——它是卢森堡。这个国家最近很多年都被认为是世界上第二富裕的国家。卢森堡是一个人均收入相对较高的地方,根据 Business Insider 的报告,这是因为有大量的人在这个小国工作,而生活在周围的法国、德国和比利时(甚至可能是整个人口的四分之一,这些人没有包括在 GDP 计算中[7])。将卢森堡排除在回归之外似乎是一个好主意,这就是为什么我们将在两个版本中执行分析以比较结果。
在第一个版本中,R 平方值表明人均国内生产总值和 PISA 平均测试结果之间有 0.62 的相关性。当我们将卢森堡排除在数据集之外时,由线性模型解释的变量的百分比增加到 0.70,这仍然是适中的。
解释我们的模型系数,我们可以说,人均 GDP 增加 1%后,PISA 的平均结果应该上升 0.68 点。回归输出的其他重要特征是:
- 标准误差,是对系数的标准偏差的估计,它在不同情况下的变化量,
- p 值,有助于确定结果的显著性。通过将变量的 t 统计量(系数除以其标准误差)与学生的 t 分布中的值进行比较,可以得到该值
- 置信区间,它告诉我们大多数变量分布在哪里
我们的标准误差在+/- 7 点左右波动。我们有一个非常小的 p 值,这表明反对零假设的有力证据。这意味着我们可以拒绝零假设,即人均 GDP 对 PISA 结果没有任何影响。换句话说,假设您的模型被正确地指定,您可以 100%正确地说变量正在产生一些影响。考察置信区间,我们看到可以 95%确信“真实”人均 GDP 系数在 0.53 到 0.82 点之间。
让我们看看使用回归系数拟合到数据中的曲线。
总结第一部分,我们可以非常肯定地说,国家的人均 GDP 对 PISA 测试的平均结果有一定的影响。不幸的是,即使相关率高于 70%,也无法证实这种关系是因果关系,这意味着仍然很难说,国家的财富是学生在评估中表现优异的原因,还是相反。
提取每个学生的政府教育费用
分析的前一部分表明,有理由相信较富裕国家的学生在评估中得分较高,这意味着他们为全面参与社会做了更好的准备。影响结果的因素可能有很多,但让我们更深入地看看另一个因素——政府的教育支出。我们可以问一个问题,更高的公共开支对考试成绩有正面影响吗?
让我们假设,在每个学生 15 岁参加 PISA 测试之前,他或她可能已经花了 12 年时间在各种形式和机构中学习。从幼儿园开始,我们可以根据另一个假设计算每个学生的费用,即每个学生在学前教育机构度过 3 年,在小学度过 6 年,然后在初中度过 3 年。这样,我们将在评估之前计算每个学生的教育总成本。让我们首先使用两个指标来计算每个教育层次上每个学生的年支出:
- 来自联合国教科文组织数据库的政府教育支出(按购买力平价计算)
- 官方年龄人口(男女)来自世界银行 API
gov_edu_expenses.head()
让我们打扫卫生吧。首先,我们需要只过滤我们感兴趣的 3 个教育水平的费用行。然后我们将删除几个不相关的列。
basic_edu_exp.head()
为了获得带有每个教育水平标签的列,我们将旋转表格。我们得到了一个附带多索引的数据框,但是我们可以在下一步中轻松地重置索引。最后,我们将重新安排栏目顺序,并添加带有国家代码的新栏目,以提高可读性。
basic_edu_exp.head()
一旦我们有了全球的教育支出,让我们来看看某一年各个层次的学生人数。我们将使用人口这一官方年龄指标,因为它告诉我们在给定的一年里有多少孩子适合每一级的教育。这只是入学学生真实人数的近似值,但由于缺乏其他数据,它仍然具有很大的信息量。
basic_student_pop.head()
同样,我们需要执行一些小的清理,比如重置多索引或统一标签。
basic_student_pop.head()
为了最终获得每个学生的政府开支,我们需要转换“时间”列数据类型,以便进一步合并。我们将使用“正确”的方法合并框架,因为我们希望只保留 2003 年至 2014 年的数据。
edu_data_joined.head()
之后,我们做除法,清理我们的数据框架。
edu_data_per_student.head()
正如我们看到的,NaN 值开始出现和使用。isnull()方法,我们可以检查在整个数据框中是否有更多的。有几种方法可以解决这些不足,但是在这种情况下,使用 Python 内置的函数 interpolate 似乎是合理的。为了不填补空白,当我们没有足够的信息时,让我们做一个假设。对于数据集中的每个国家,首先检查我们感兴趣的给定时间段内的 NaN 数量,例如 2003-2005 年的学前教育。如果出现任何缺失,检查给定教育水平的整个列。如果 NaN 的比率低于 50%,我们将对整个列进行插值,在其他情况下,我们将删除该国家。
由于我们的假设,我们不得不从原始数据集中去掉 10 个国家。
PISA 平均成绩与政府人均教育支出的回归分析
我们的最后一步是回归分析,以检查两个变量之间是否存在相关关系。让我们先合并数据帧并检查散点图。
正如我们看到的,我们将需要我们以前的技巧,使数据更加“线性回归友好”。让我们首先记录费用值,并绘制另一个图表。
这一次,除了卢森堡之外,似乎还有一个例外——那就是巴西。对于一个教育支出如此巨大的国家来说,它的 PISA 成绩相对较低。这可能是教育系统效率低下的一个迹象,但我们不要过分解读。
数据中的所有调整再次导致相关值增加——从 0.31 增加到 0.68 点。解释我们的模型系数,我们可以说,在每个学生的政府支出增加 1%后,PISA 的平均成绩应该上升 0.68 分。
我们看到,在排除了一些国家之后,我们的数据非常符合计算结果。关于这个图还有另一个具体的事情,似乎我们有一组国家集中在这个点周围,有 500 个 PISA 点和 11.5 英镑的支出,而其他支出较少的国家形成一条线。这就提出了一个问题,有没有可能在达到每个学生的费用的某个点后,我们看不到评估分数有太大的差异?
摘要
总结所有的结论,我们可以说,PISA 成绩和国家人均国内生产总值之间存在适度的正相关关系。这不仅仅是一个潜在的 matmat mater,因为分析真实的教育支出给了我们同样的结论。即使较富裕的国家和那些在教育上分配更多资源的国家得分较高,仍然不可能说明这种关系的方向。这可能是国家的财富是高分的原因,也可能是这种情况,一个有效的教育系统产生了聪明的人,他们追求增加他们的国家收入。文中分析的样本也不够大,不足以对这种关系得出强有力的结论。教育有效性本身可以用不同的方式来衡量。
这个分析留给我们的问题多于答案,这也是我决定写第二部分的原因之一。在 PISA 的表现中,可能有许多因素值得分析。我们可以尝试一些使用聚类方法的无监督学习来识别其他关系,这可能看起来不那么明显。我们可以检查它们中许多的相关强度,并只选择最相关的。然后,我们可以尝试拟合不同次数的多项式,并对它们进行交叉验证,以检查测试模型的预测能力。我希望你喜欢我的工作,我期待着尽快描述结果!
Github 项目库:https://github.com/mklajnerok/PISA/tree/master/pisa_basic
Jupyter 笔记本来源:https://github . com/mklajnerok/PISA/blob/master/PISA _ basic/notebooks/PISA _ project _ part 1 . ipynb
来源:
- [1]http://www.oecd.org/pisa/pisa-2015-results-in-focus.pdf
- [2]https://data . OECD . org/pisa/Reading-performance-PISA . htm # indicator-chartOECD(2017),阅读表现(PISA)(指标)。doi: 10.1787/79913c69-en(于 2017 年 9 月 11 日获取)
- [3]https://data . OECD . org/pisa/Mathematics-performance-PISA . htm # indicator-chartOECD(2017),数学成绩(PISA)(指标)。doi: 10.1787/04711c74-en(于 2017 年 9 月 11 日获取)
- [4]https://data . OECD . org/PISA/Science-performance-PISA . htm # indicator-chartOECD(2017),Science performance (PISA)(指标)。doi: 10.1787/91952204-en(于 2017 年 9 月 11 日获取)
- [5]https://data help desk . world bank . org/knowledge base/articles/889392-API-documentation
- [6]http://DSS . Princeton . edu/online _ help/analysis/interpreting _ regression . htm
- [7]http://www . business insider . com/the-23-世界上最富有的国家-2015-7?IR=T
- http://data.uis.unesco.org/
北欧人有智慧吗?—人工智能的现状(第二部分)
原文:https://towardsdatascience.com/is-there-intelligence-in-the-nordics-the-current-state-of-artificial-intelligence-part-2-a3d145abd3a9?source=collection_archive---------2-----------------------
在一篇由两部分组成的博客中,我们看看人工智能是什么,它的影响,然后探索人工智能在北欧的状态。这是第二部分,关于北欧人。
在我们之前的博客中,我们深入探讨了人工智能以及人工智能世界正在发生的事情,尤其是在美国。然后我们继续我们在北欧的人工智能之旅,并对我们发现的和没有发现的东西感到有点惊讶。那么,北欧人有智慧吗?是的,但是人造的那种呢?简而言之,答案也是肯定的,但各种人工智能计划散落在各处,通常在不同于“人工智能”的标题下,没有明确的议程,只有大学、老牌企业或政治家的部分兴趣。然而,人工智能正在创业社区和学生中蓬勃发展。
提问
我们想回答几个问题。北欧学术界、人工智能研究领域发生了什么?谁是领先的学者?AI 领域活跃着哪些投资人、公司、创业者?北欧哪些是领先的人工智能热点?北欧人和领先的人工智能国家相比如何?
我们与很多人交谈,研究了北欧的 129 家公司。我们把这个博客分成两个部分:首先是学术界、研究机构和科学组织,其次是商业和技术界;公司、投资者、企业家和热点。由于人工智能是一个研究密集的领域,让我们从学术开始。
学术界、研究机构和科学组织
从瑞典开始,我们求助于斯德哥尔摩皇家理工学院( KTH )计算机视觉和主动感知系(机器人感知和学习,RPL)的机器人感知教授。Stefan 对 AI 的定义最简单;“它做人类做的事情”。
斯蒂芬·卡尔松描绘了一幅艾在瑞典的凄凉景象。“传统的老牌企业和初创企业之间有很大的区别,”他表示。“我一直收到斯德哥尔摩人工智能初创公司和见面会的邀请。”
他认为,与此同时,老牌公司对此兴趣不大。也许他们专注于当前的业务,以及传统行业的生产力。我们很少看到瑞典大公司对我们的能力或雇佣我们的学生提出要求。解释可能是,人工智能的应用对新的创业公司和软件公司来说更自然。然而,随着对自动驾驶汽车的更多关注,沃尔沃和斯堪尼亚也越来越关注 KTH 的研究和学生。也有一些新的公司,如 Context Vision、Tobii 和 Electronic Arts,一直在接触。"
“与学生感兴趣的东西相比,这是一个惊人的差异”,他继续说道。“这真的是人工智能课程的热潮和巨大的兴趣。原因可能是学生们正在考虑 40 年以上的技术和工程职业生涯,并希望进入面向未来的领域。他们似乎对爱立信和 ABB 这样的老公司不感兴趣。”
这意味着我们可能会在未来几年看到许多新的人工智能创业公司,由有才华的学生创办或加入,他们希望在现有企业之外探索人工智能的机会。但是大学里的实际研究呢?
“在瑞典,人工智能研究的融资并不多。不过也有一些突破性的领域,比如计算机视觉、自然语言识别和机器人技术。但总的来说,学术界和传统企业似乎都需要很长时间才能实现转型,这并没有真正发生。相比之下,谷歌、苹果和脸书在人工智能方面的转变非常迅速。在研究领域,资金周期很长,项目需要 5 年时间,而且资金往往流向已经存在的领域,而不是新的领域。欧洲正在落后于美国,这是一个普遍问题。”
其余的北欧国家呢?斯特凡·卡尔松认为挪威、芬兰和丹麦的情况可能一样糟糕。人工智能的大推进似乎不会发生在北欧的任何地方。
为了进一步探索,我们求助于林雪平大学计算机科学副教授、WASPWallenberg 自治系统项目研究生院主任、 SAIS 瑞典人工智能协会主席 Fredrik Heintz 。WASP 是瑞典最大的个人研究计划,十年内拨款 18 亿 SEK,支持自主系统和软件开发的战略基础研究。
其目标是“将瑞典推进到这两个领域的国际公认的领先地位。”听起来像是一个令人惊叹的人工智能项目,但它真的是关于人工智能的吗?“不明确”,弗雷德里克说,“我认为这是不幸的。WASP 中很少有研究人员具有人工智能背景,因此人工智能的结果有被遗漏的风险。与此同时,许多研究可能会触及与人工智能相关的问题,例如机器学习。”
Fredrik 证实,AI 在瑞典不是一个统一的研究领域,而是跨越几个主题,如自然语言处理、信息检索、机器学习、多代理系统和计算机视觉。弗雷德里克说:“这是很多活动,但并不总是贴上人工智能研究的标签。”。
此外,“人工智能不是一个非常流行的术语”,弗雷德里克说。“一个原因是,在 80 年代,所谓的专家系统引起了强烈的反对。这些系统试图对专家知识进行编码,以提供决策支持,这些支持本应彻底改变医疗保健等行业,但却没有达到夸大的预期。今天,类似的系统经常被有效地使用,但是没有人工智能的标签。现代版本通常被称为决策支持工具或问答系统,最著名的例子是 IBM Watson。这种被认为的失败玷污了瑞典的人工智能一词。
“人工智能在瑞典发展缓慢的另一个原因是,传统的瑞典工业为学术研究设定了议程,他们普遍没有看到对人工智能的重大需求。瑞典政府还把重点放在了可以雇佣数千名员工的行业,而不是员工数量明显较少的高科技公司,如 Spotify 和 Klarna。
“对更传统行业的关注也导致了大学对电气工程的重视超过了对计算机科学的重视。然而,随着电子工程和计算机科学的融合,这种情况正在改变。如果人工智能能够成为这种统一的驱动力,那就太好了。”
正如 KTH 一样,在林雪平大学,现在人工智能蓬勃发展,超过 200 名学生正在学习一门人工智能课程和几门与机器学习相关的新课程。
人工智能看起来更像是一个联合了各个领域的交叉学科,而不是它自己的领域。所以,总的来说,有很多正在发生的事情,但是没有一把通用的雨伞来保护所有的人工智能。弗雷德里克总结道:“也可能是因为在美国,他们更擅长谈论人工智能,而我们实际上更擅长做这件事。”。“我们在大学和研究机构有能力,有了正确的方向,我们可以很容易地成为一个拥有正确激励和适当资金的领先国家”。
此外,他说,请关注 2018 年在斯德哥尔摩举行的三个主要人工智能国际会议;国际机器学习会议( ICML )、自主智能体和多智能体系统会议( AAMAS )和国际人工智能联合会议( IJCAI )。
在芬兰,我们求助于 Ville Kyrki,他是阿尔托大学电气工程学院的副教授。他是智能机器人研究小组的负责人。“芬兰可能是北欧最(人工)聪明的国家之一”,维尔说。"机器人学是一个很强的领域,机器学习有很长的历史."例如,Teuvo Kohonen 教授是人工神经网络和自组织地图的先驱,有时也被称为 Kohonen 地图。Ville 还可以看到几家使用机器学习工具的衍生公司,大多数都处于创业阶段。关于机器人的智能,有一家令人兴奋的公司叫 Zen Robotics,它正处于规模化阶段。维尔指出有两种研究。一个是自主系统、机器和车辆(这不是人工智能本身,而是使用人工智能工具和机器人)。这个领域已经相当成熟了。另一个是机器人公司,还有一些较小的机器人公司,如通用智能机器公司(GIM)。阿尔托大学的研究集中在两个领域;1)自主机器/车辆,以及 2)服务机器人,尤其是在医疗保健领域。总的来说,有很多研究是针对传统行业的,如汽车、采矿自动化和林业自动化,典型的北欧企业。
还有一些其他著名的北欧学者,以各种方式活跃在人工智能、机器人和机器学习领域:
- Finn Verner Jensen ,丹麦奥尔堡大学计算机科学系名誉教授
- Agnar Aamodt ,挪威 NTNU 挪威科技大学计算机科学和人工智能教授兼副系主任
- Erik Sandewall ,瑞典林雪平大学计算机科学教授
- 瑞典皇家理工学院(KTH)计算机科学与通信学院教授丹妮卡·克拉吉·詹斯费尔特
- 德夫达特·杜巴什,瑞典查尔姆斯理工大学计算机科学与工程系教授
- Teuvo Kohonen ,杰出的芬兰学者和研究员,现任芬兰科学院荣誉退休教授。
在瑞典,有许多组织在瑞典组织科学研究以及与商业和企业的互动:
- 瑞典皇家工程科学院( IVA )是一个独立的组织,旨在促进瑞典和国际上商业、研究和政府之间的交流。
- Vinnova 是瑞典的创新机构,资助需求驱动的研究,促进公司、大学、研究机构和公共部门之间的合作。
- 瑞典研究委员会(vetenskapsrdet)是教育和研究部下属的一个公共机构,目的是发展最高科学质量的瑞典研究,为社会发展做出贡献。
- 瑞典战略研究基金会 (SSF) ,支持科学、工程和医学领域的研究,目的是加强瑞典未来的竞争力。
- 瑞典研究所(Research Institutes of Sweden)是一个与学术界、企业和社会进行全球合作的研究和技术组织团体。
- SICS 瑞典 ICT ( SICS )由瑞典政府所有,是一家领先的应用信息和通信技术研究机构。
我们联系了这些组织,询问在人工智能领域是否有任何具体的项目。似乎有许多活动与计算机科学、人工智能和机器学习有关,然而它很少被贴上“人工智能”的标签,正如弗雷德里克·海因茨早先指出的那样。
来自 SICS 的 Niklas Rudemo 说,他们在人工智能领域的工作主要涉及人工智能在工业环境中的实际应用。虽然人工智能背后的理论很复杂,但理解哪种问题适合特定的技术就更复杂了。通过与瑞典工业客户和国际研究伙伴的合作,SICS 在这一领域积累了大量的人才和经验。
最后,这似乎根本不是来自政治方面的推动。瑞典政府已经启动了类似“智能产业”的项目和各种各样的通用数字计划,但在人工智能方面却一无所获。原因是,在瑞典,政府不想推广任何特定的技术,这取决于企业。但也许他们应该。人工智能的强大优势可能会迅速转化为国家优势。
公司、投资者、企业家和热点
Slush 是北欧和世界上最大的科技会议之一,聚集了成千上万的企业家、投资者和初创公司。根据他们的数据库,Slush 有 241 家人工智能创业公司,其中 113 家来自北欧。搜索行业数据库 Nordic Tech List ( NTL ),目前有 56 家公司被贴上“人工智能”的标签。Crunchbase 列出了 33 家人工智能类别的北欧公司。综合这些名单,加上我们自己的研究,我们推断出了 129 家公司的名单。你可以在这里找到名单。我们学到了什么?
我们的印象是,真的有两种人工智能公司。“纯人工智能”初创公司依赖于长期研究、获取大量数据和先进技术。他们通常以人工智能公司的形式成立,在广阔的人工智能领域中探索某个领域。另一种我们可以称之为“想要人工智能”的创业公司。他们可能从更基础的软件公司开始,然后增加了智能功能和更多数据,或者他们只是利用人工智能的繁荣来提高公关。在任何情况下,我们都没有真正区分这两者,任何自称为“人工智能”的公司都在名单上(然而,我们已经删除了一些与我们认为的人工智能公司毫不相关的案例)。
这些公司的总部在哪里?瑞典和芬兰占据了很大的优势(合计 84%)。这可能是因为我们使用了芬兰的数据库(Slush)和瑞典的数据库(NTL),但我们也与国际数据库进行了交叉检查,以消除任何偏见。然而,这里有数据:
- 57 家人工智能公司来自芬兰(44%)
- 51 人来自瑞典(40%)
- 11 人来自丹麦(8%)
- 10 名来自挪威(8%)
他们的基地在哪些城市?芬兰(赫尔辛基)和瑞典(斯德哥尔摩)也是这里的主要枢纽,排名前四的北欧城市是:
- 34 家人工智能公司总部位于赫尔辛基
- 32 个在斯德哥尔摩
- 9 个在哥本哈根
- 8 个在哥德堡
投资呢?Atomico 的最新报告“The State of European Tech 2016”分析了 2011 年至 2016 年在“深度技术”(一个包括人工智能、物联网、虚拟和增强现实以及前沿硬件等许多先进技术类别的术语)方面达成的交易。该报告发现,近年来(2014 年至 2016 年),欧洲有 950 家深度科技初创公司,而美国有 1252 家。看看人工智能公司,其中 43%得到了资助,相比之下,美国人工智能公司得到资助的比例为 53%。自 2015 年初以来,欧洲共有 23 亿美元投资于深度科技公司。在北欧投资了多少?瑞典在 2011 年至 2016 年期间对 Deep Tech 的投资总额为 1.98 亿美元,其次是芬兰(1.37 亿美元),然后是挪威(5600 万美元)。没有丹麦的数据。
我给斯德哥尔摩的一些主要投资者打了一轮电话,给人的印象是对人工智能的投资并不多。Industrifonden 对 Now Interact 进行了人工智能相关的投资。Creandum 投资了一家德国人工智能公司。也有一些收购,例如 Ebay 收购了 ExpertMaker。
Bjarke Staun-Olsen ,居住在斯德哥尔摩的丹麦人,风险投资公司 Creandum 的投资经理,专注于人工智能和金融科技领域。拥有机器学习背景的 Bjarke 在成为投资者之前是一名企业家,并建立了一家人工智能初创公司 Alipes Capital,该公司使用机器学习来预测金融市场。那么他从投资角度怎么看待 AI 呢?
他说,“这项技术本身前途无量”。“与一年前相比,发生了巨大的变化。然而,这对一家初创公司来说并不明显,因为一家成功的人工智能公司需要大量数据,而竞争对手(谷歌和其他公司)通常拥有这些数据。谷歌和其他数字巨头有强大的动力来提供开源算法和促进创新,因为真正的价值在于数据和你可以用它做什么,而不是算法。创建机器学习初创公司的方法是找到一个竞争有限的非常狭窄的垂直市场,在那里你可以获得独特的数据集和数据优势。算法本身还不够,但很有必要。”
那么对人工智能的投资呢?和其他地方一样,北欧在人工智能领域的投资与其他领域的投资比例可能是一样的。Bjarke 看不到其他国家在人工智能上的投资比例。而且,他无论如何也想不出有哪家 AI 公司筹到了巨额资金。然而,有一些大型科技初创公司获得了大量资本,它们依赖人工智能,但不是人工智能公司。例如,Spotify 依靠人工智能作为推荐引擎,Klarna 利用人工智能检测欺诈和信用评估,优步拥有预测物流的算法。他们受益于人工智能,因为他们有数据。
最后,就热点而言,比亚克认为,斯德哥尔摩、哥本哈根和赫尔辛基等北欧主要科技中心在人工智能方面的排名可能与纽约或柏林不相上下。然而,它们都在世界上两个主要的人工智能中心——美国的旧金山和欧洲的伦敦——的背后。因此,我们转向北欧人工智能的另一个关键影响者。
Roelof Pieters 是 KTH 大学计算机科学与通信系的学者和博士,后来成为企业家。他曾在 Vionlabs 担任研发部门的技术总监,现在已经创办了自己的公司 Creative.ai
他表示,瑞典和北欧的人工智能市场非常分散,学生通常也与创业人群分开。想做某事的人会搬到其他地方。如果你是学生,对 AI 领域的创业公司感兴趣,欧洲最好的地方是英国。他证实,伦敦是当今欧洲人工智能开发最强大的技术中心。北欧大学的顶尖人才(大部分来自亚洲、俄罗斯、中国和印度)被谷歌、微软、IBM 和其他公司挖走,这些公司花费大量资金招募和吸引学生,并将他们带往国外。学生通常通过他们的期末论文来确定,任何与人工智能有关的东西都会引起招聘人员的注意,他们会给出很好的提议。Roelof 说,加拿大是一个有趣的例子,现在多伦多有一个人工智能研究实验室。早些时候,加拿大的人才大多被美国吸收,但现在学生留下来了,研究得到了政府的大量资助。
AI-创业公司和投资呢?Roelof 认为很少有公司实际上是以人工智能公司起家的(正如我们前面指出的)。这是一个过程,软件公司开始做基本的东西,然后随着数据的增长,逐渐添加更多的智能算法。他认为投资者缺乏人工智能方面的专业知识,并认为北欧人通常更厌恶风险,这就是为什么我们在北欧很少投资人工智能的原因。人工智能初创公司的主要问题是获得资金。
Roelof 帮助组织了斯德哥尔摩的人工智能社区,首先是发起了斯德哥尔摩深度学习会议,然后合并到新成立的 Stockholm.ai,它是 Nordic.ai 的一部分(由 Corti Labs 的 Pia Elle elme gard 运营),而后者又隶属于国际city . AIinitiative,这是一个应用人工智能的全球社区。Roelof 是斯德哥尔摩人工智能大使。还有一个马尔默。人工智能和城市。人工智能运动现在正蔓延到奥斯陆和赫尔辛基。聚会的目的是将对人工智能感兴趣的学生、研究人员、技术人员、商人、投资者和初创公司聚集在一起。
艾现在也引起了斯德哥尔摩市的注意。斯德哥尔摩的创业和技术负责人 Joseph Michael 最近写了一篇关于斯德哥尔摩的人工智能的博文。
在芬兰,我们在 Headai 会见了 Marko Laiho(首席执行官、联合创始人)和 Eero Hammais(产品经理)。Headai 的创始人是 Harri Ketamo ,一位独立研究员和初创企业家,在学习科学、数据挖掘和人工智能方面拥有超过 15 年的经验。他是图尔库大学的高级研究员和坦佩雷技术大学的兼职教授。
Headai 是一家成立于 2015 年的令人兴奋的公司,基于十年的开创性研究学习科学、数据挖掘和人工智能,正在开发可教的软件机器人(bot),以自动化各种日常智力工作。这些机器人是快速学习者,互动和可靠的助手。它们可以促进数据发现,帮助做出更好的数据决策,自动化复杂的业务流程等等。Headai 的解决方案是语义神经计算和遵循人类行为的学习算法的结合。机器人使用非结构化或给定的数据来创建语义神经网络,与传统本体(即语言结构)相比,它可以提供高达 1000 倍的深度洞察力。
Headai 的重点主要是语义神经计算,分析文本、单词和单词如何连接的海量数据集,以及句子的上下文。机器人可以开始阅读任何语言,通过理解单词之间的联系和语义。该机器人创建了一个语言图像,用于阅读新闻,找到类似的新闻,并与周围世界的文本 DNA 进行比较。Headai 的愿景是,公司和个人可以拥有自己的个性化终身机器人,不断学习和帮助我们。
为了理解这一点的实际意义,我们询问了一个当前的热门话题:Headai 能帮助脸书识别假新闻和其他用于破坏民主的虚假信息吗?“是的,绝对是,”马尔科·莱霍说。Headai 将在网站上创建一个文本的 DNA(一个“新闻指纹”),将其与全球主 DNA 进行比较,并显示如果它在其他任何地方都没有找到类似的 DNA,则该新闻是假的可能性。文本的主要 DNA 是大数据(世界上所有的新闻),而不是一个小的、特定的文本 DNA(一条关于脸书的假新闻,例如“教皇支持川普”)。
那么,北欧的人工智能创业公司情况如何?Marko Laiho 认为在芬兰只有 3-5 家“真正的”人工智能公司,在北欧的其他地方也很少。Headai 的业务没有北欧竞争,大多数竞争对手都在美国,有些在英国。大多数都是早期阶段。
看起来赫尔辛基将进一步建立他们在北欧地区作为一个令人兴奋的技术中心的地位,特别是在人工智能和医疗保健的交叉领域。我们会见了 IBM 芬兰公司的 Juha Teljo(商业智能和预测分析销售主管)和 Mirva Antila(医疗保健、公共和金融服务企业销售部门总监),他们谈到了 IBM 新的赫尔辛基开发中心。
Tekes,芬兰创新资助机构(Tekes)和 IBM 有一个宣布的合作伙伴关系,这将使芬兰能够利用沃森 (IBM 的主要人工智能倡议)认知计算来帮助医生改善医疗保健,并在健康和福祉领域加强和发展芬兰的创新和商业生态系统。IBM 还将在芬兰建立 Watson Health Center of Excellence,这是第一个北欧医疗保健能力中心,也是美国以外的第一个此类中心。这些中心预计将在未来几年雇用 150 人
芬兰是医疗保健领域的创新者,Mirva Antila 指出了 IBM 将新的欧洲中心搬到这里的几个原因:政府的医疗保健改革,芬兰可以作为试验台的相当少的人口,医疗保健行业数字化的几项举措,以及许多活跃在人工智能领域的公司,最后,社会安全号码的独特使用提供了对大数据的访问。总是和数据有关。
很明显,如果有意愿,有明确需求的大型部门,政府改革,创新和资助机构,创业公司,研究和全球科技公司之间的合作可以开始加速人工智能的区域发展。
智能结论
综上所述,我们对北欧的人工智能有什么结论?当然,正如我们所料,北欧是一个领先的技术地区,这方面发生了很多事情,但我们需要在这方面做得更多,以免落后于领先的地区、中心和国家。我们有点担心,世界可能会分成传统的、缺乏数据的工业国家,以及另一方面数据丰富的软件国家。短期内北欧人不太可能在人工智能领域占据主导地位,因为一些基本原因。简而言之,我们缺乏:
- 海量全球数据(与美国和中国相比)
- 大量风险资本和企业资本(与美国和中国相比)
- 给予人工智能强有力推动的政治意愿(与其他部门相比)
- 鼓励投资人工智能的软件巨头(我们的经济由传统产业主导)
然而,我们认为我们现在可以做一些重要的事情,以便在更长的时间里成为人工智能的赢家:
- 为特定人工智能相关领域的研究分配更多资金
- 对人工智能直言不讳的政治关注,因为它是我们这个时代的定义性技术之一
- 为人工智能初创公司提供更多专门的、愿意承担风险的资本,这些公司通常处于早期阶段,由研究驱动
- 关注所有的人工智能活动,创业和研究,这些实际上是在北欧进行的,让它更加可见。为什么不在瑞典设立第一个人工智能教授职位来专注于人工智能的研究和开发呢?
我们在北欧人工智能中看到了一个非常具体和令人兴奋的机会。正如我们在早先的博客中所展示的,北欧拥有强大的创新企业软件公司基础,在全球利基市场上成功竞争。他们通常拥有扎实的行业专业知识、深厚的技术能力以及对行业垂直领域独特数据的访问权。通过注入更多的人工智能并与研究人员和人工智能初创公司合作,显然有机会进一步发展这些成熟的公司和技术。我们相信我们在北欧有足够数量的人工智能,现在我们只需要开始滚雪球。
这是玉米卷吗?自定义视觉的机器学习实验
原文:https://towardsdatascience.com/is-this-a-taco-a-machine-learning-experiment-with-custom-vision-d33291a36b9c?source=collection_archive---------9-----------------------
Can machine see this as a taco?
想知道如何获得机器学习(ML)吗?那么,现在你可以通过云端提供的机器学习服务,称为功能即服务(FaaS)。
在我研究机器学习是怎么一回事的时候,我有机会了解了自定义视觉。
Custom Vision 是一种基于云的机器学习服务,允许用户提供自定义图像集来训练算法识别图像的某些特征。
FaaS 可以让曼梯·里更接近我们
过去,我玩过一些应用程序,这些应用程序对我上传的图片提供反馈,比如面部表情的情绪。
虽然这些应用程序提供了某些商业价值,但是现成的解决方案可能无法满足特定的需求。
Custom Vision by Microsoft
所以当我了解到我可以控制识别什么的自定义视觉时,我很兴奋。
我绝不是数据科学方面的专家,我更愿意走一条简单的路去体验机器学习的世界。
使用自定义视觉,我只需上传训练集并相应地标记它们,我就可以根据我的测试图像集快速测试算法。
没有比和他们一起玩更简单的了。
训练集
当我们在办公室吃墨西哥玉米卷作为午餐时,我决定对手工制作的玉米卷的照片进行自定义视觉测试。
测试是这样的:
1.上传并标记六张按照我们人类标准“正确”的玉米卷照片,并将它们标记为“玉米卷”和“食物”
2。上传了五张办公室周围不是玉米卷的食物的照片,并将它们标记为“食物”。运行培训流程
4。通过上传玉米饼和其他食物的照片来测试算法
Uploaded images with associated tags
正如你所看到的,训练数据集是最小的,他们是快速和肮脏的,无论我能在 15 分钟内抓住什么。
它与数据科学相去甚远,但请不要离开我,我们将在下面测试该算法并评估其性能。
测试集
我们先从一个我们知道肯定不是玉米卷的图像开始。
Neither food nor taco
好吧,我们继续,先吃带壳的玉米卷怎么样?
A food but not a taco
有趣的是,在 87.5% 的预测中,它确实将玉米卷壳识别为一种食物,但它并不完全符合玉米卷的标准。
让我们继续下一个,我们在贝壳里放一些牛肉怎么样?
A food and a taco
现在,我们有相当高的信心,这是一个玉米卷在 90.5% 预测。
这很有趣,因为训练集并没有必要把牛肉放在它出现的最前面。
记住这一点,让我们跳到完成的玉米卷。
A food and a taco
这张玉米卷的照片明显类似于一个完整的玉米卷,算法也同样拾取了它。
在图片中,牛肉甚至不可见,所以它可能是在看形状而不是色调。
让我们用去结构化的玉米卷来测试,从某种意义上来说,配料在每个玉米卷的外面。
Pretty close to be a taco
Definitely a taco
Definitely a taco
正如你在上面的结果中所看到的,看起来仅仅是玉米卷的形状可能也不是决定性因素。
同样,一组位置相近的配料是否能达到墨西哥玉米卷的质量也是有争议的。
我们扔一些看起来像墨西哥玉米卷的临时演员怎么样
Some similarity to a taco
Definitely not a taco
上面的测试可能会给我们一个提示,质地可能在决定玉米卷中发挥更大的作用。
我们对预测有多少把握?
说一张照片是 99% taco 是一回事,但是我们对这个预测本身有多少信心呢?
毕竟,我只提供了 11 张照片来判断什么是玉米卷。
在“性能”选项卡中,Custom Vision 确实为您提供了精确度和召回率的测量方法。
一般来说,更高的精确度和召回率将导致对该服务更准确的预测。
在这种情况下,这种精确度对于墨西哥卷饼来说是可靠的,但并不总是可信的。
我们如何利用测试之外的服务?
Custom Vision 和类似的工具提供了 API 端点,您可以在这里发布一个图像,以使用用户输入训练数据集或获得给定图像的预测。
这就是为什么它们被称为功能即服务,它只是你的应用程序可以利用的云中的一个功能,而不是扩展现有的后端功能。
如果你想了解更多关于定制视觉的信息,去他们的网站开始测试吧。
裁决
像 Custom Vision 这样的基于云的服务使机器学习更接近我们这些不是数据科学家的人。
虽然仍然需要数据科学家的知识和批判性思维技能来判断算法的准确性,但这可能是一种与应用程序集成的绝佳方式。
我是 Fresh Consulting 的前端开发主管。我写有影响力的技术领导()和最新的技术实验。
跟我上 中 和 推特
你的大数据是不是在逆向思维?
原文:https://towardsdatascience.com/is-your-big-data-thinking-backwards-e4176413a801?source=collection_archive---------7-----------------------
采用客户驱动的数据流作为核心业务策略的指南。
忘记通过增加客户价值的计划来扩展你的公司。考虑通过一些计划来扩展你的公司,这些计划将给你数据 告诉你如何以无人想象的方式为你的客户服务。这是必须得到认可才能成功将大数据作为企业战略文化的范例。
本文是系列文章的第二部分,从:大数据分析:你能为你的组织做的最好的颠覆性的事情 n
大数据不仅仅是一个技术问题
Krotov (2017)用一个类比解释了这一现象:
“1875 年 3 月,当时默默无闻的发明家亚历山大·格雷厄姆·贝尔向西部联合电报公司总裁威廉·奥顿提供了贝尔电话发明的专利,价格为 10 万美元,大约相当于今天的 200 万美元(Carlson,1994)。威廉·奥顿拒绝了这个提议。接下来发生的就是历史了。在贝尔提出收购时,西联汇款是美国最具主导地位的电信公司。几年后,较小的公司开始使用贝尔的电话发明来分割西联汇款的市场份额。为了迎头赶上,奥顿试图开发西联公司自己的电话。然而,这太少了,也太迟了。西部联盟再也无法回到它曾经达到的显赫地位。。。西联汇款的故事经常在商业文本中被用作一个轶事证据,证明盲目的商业领袖如何与技术的未来潜力相关 (Christensen,Anthony,& Roth,2004)。。。Carlson (1994 年,第 161 页)解释了[领导者中]的这种偏见:
“历史学家和公众通常都认为一项新技术的‘最终用途’是包含在技术本身之中的。假设一旦一个设备被发明出来,它将如何被使用以及被谁使用就很清楚了。。。相反。。。技术的“最终用途”是由技术企业中的各种参与者创造或构建的。。."【1】
这个世界已经不是大多数当代管理理论形成时的那个世界了。正如 Braganza、Brooks、Nepelski、Ali 和 Moro (2017 年)所提到的,技术的发展速度远远超过管理思维的发展速度,他们指出:
“对正在制作的数据的来源和数量的各种估计包括思科的估计”到 2020 年,每两分钟就会有相当于所有电影的千兆字节(GB)通过全球互联网”(思科视觉网络指数,2016 年,第 4 页)。。。大数据催生了新的技术、方法、数据采集应用、可视化技术和数据聚合能力。借助成熟的商业智能、数据挖掘和分析实践,大数据方法催生了新一代算法,并重新激发了人们对数学、统计和定量分析的兴趣。。。学者们认识到大数据不仅仅是一个技术问题,为了充分发挥作用,大数据需要成为组织结构的一部分 (Davenport,Barth,& Bean,2012)。应将大数据纳入营销和新产品开发等战略活动(徐,Frankwick,& Ramirez,2016)。其他人认识到大数据影响组织文化,因为决策变得更加基于证据 (Erevelles 等人,2016 年,伊拉尼,2010 年)。”【2】
最赚钱的公司正在想办法让他们的客户创造驱动核心业务流程的数据流。Pigni、Poccoli 和 Watson (2016 年)报告称:
“数字数据流的出现正在为现有公司创造战略机遇,并促成新企业的形成。这种巨大变化的催化剂是大量生成的实时结构化和非结构化数据流,组织可以利用这些数据流进行决策和运营变化。这些新企业的象征是优步,世界上最大的“出租车”公司,市值高达 500 亿美元。(1)优步没有汽车,但利用其司机汽车的实时数字数据流,并将其与实时乘车需求相匹配。现有组织也在成功利用“大数据”的实时流动来创造新的价值。想想旧金山的 SFPark 吧,它是旧金山市政运输局(SFMTA)的一个公私合作项目。通过在城市的每个收费停车位安装磁力计来检测车辆,SFMTA 创建了实时停车数据流。通过这样做,它提供了可用停车位的实时可见性,减少了驾车者寻找停车位的平均时间(43%)、街道停车的平均费用(4%)和车库费用(12%)。此外,该市还能够通过引入需求反应定价来获得一些创造的价值。。。其结果是,停车位使用率目标更经常地达到 31 %,温室气体排放减少了 30 %,这是因为驾驶员为了停车而绕行的英里数减少了" [3]
想想谷歌、亚马逊、脸书、推特、Instagram、Pinterest、优步和领英等公司创造的数据流。作为其核心业务战略的一部分,这些公司依靠客户创造的数据流繁荣发展。
From Pigni, F., Piccoli, G., & Watson, R. (2016)
利用客户驱动的数据流作为核心业务战略
亚马逊创建了一个全球市场 [4] ,允许他们的客户上传他们自己的产品,并利用亚马逊的平台和市场向全球受众销售。从某种程度上说,他们的公司战略创造了一种自助式商业模式,在这种模式下,客户能够挑选他们想要使用的产品和功能,利用公司提供的工具和数据管理流程来满足他们自己的需求,并提供数据,使亚马逊能够更好地为其他客户提供更好的服务,并拓展到新的市场。马泽伊&诺贝尔(2017)这样说:
“亚马逊提供了一个公司如何应用数据和分析进行战略发展的标志性例子。。。作为一家专注于图书的电子商务公司,亚马逊能够获得信息,并对查看其图书库存的消费者的鼠标点击进行分析。该公司获取了浏览历史,包括搜索词、购买的书籍、未购买的书籍、放在愿望清单上的书籍以及项目被浏览的时间长度。这导致了更多的选择,改善了目标市场营销,并最终通过电子零售商扩展到更多的细分市场。亚马逊现在在电子商务网站上销售几乎任何产品,包括电子产品、运动器材、服装,甚至建筑材料。改进的分析能力有助于增强大数据的力量,使亚马逊作为云计算服务提供商进入一个新兴行业。亚马逊网络服务(AWS)现在是一项价值 50 亿美元的业务,引领云计算和分析基础设施市场,为各种规模的公司提供灵活而全面的服务(Novet,2015)。”
通过分析在其网站上搜索书籍和产品的用户的搜索查询和流量行为,亚马逊是否可能意识到他们有机会开拓新市场的下一个大领域是云计算和网络服务?想想吧。为什么像亚马逊这样的公司会进入一个在很多方面对他们来说完全陌生的市场?这样的举动不是一步到位的冲动决定;相反,它需要在一段时间内仔细规划。亚马逊的第一次大数据收购发生在 1998 年,当时收购了 Junglee corp .【6】,这是一家 XML 数据挖掘公司,它提取在线产品价格,允许网络购物者比较数百万种产品的价格【7】。当我们回顾亚马逊的决定时,很明显,它们朝着正确的方向前进;由于他们的选择,他们已经成为这个新的自助式 web 服务技术市场的主要领导者。谷歌是自助式商业模式的另一个主要例子。谷歌的产品在由客户创造的数据流生态系统中茁壮成长,包括维护网站和网络应用的组织,以及在这些组织中搜索内容的个人【8】。根据 Davenport,t .,Barth,p .,& Bean,r .(2012)【9】的说法,早在 2012 年,仅谷歌一家每天就处理大约 24pb(或 24,000)的数据。马泽伊&诺布尔(2017)还举了 Progressive Insurance 的例子,该公司利用实时分析以新颖的方式推动其核心业务流程,而没有实质性地改变其市场焦点:
“Progressive Insurance 正在使用来自车载电信设备的实时分析来监控驾驶活动,通过识别危险行为来创造竞争优势。这使得该公司能够根据每个司机的实际驾驶习惯更准确地对他们进行评级,同时也鼓励其消费者的驾驶行为发生积极的变化(全国保险专员协会,2015 年)。”【5】
因此,即使一家公司不适合一头扎进一个完全陌生的市场,也可以循序渐进地实现数据驱动。随着渐进式保险开始利用实时数据来更准确地评估司机的实际驾驶习惯,其他保险市场开始出现,如驾驶付费(PAYD)、驾驶付费(PHYD)和现收现付(PAYG)。这些仍然是允许流数据驱动市场决策的例子,允许公司在许多情况下创建新的市场,以更好的方式满足客户需求。
大数据不是一个独立的流程或技术
现在,组织认为大数据只是一种独立影响组织并增加价值的技术或流程是错误的。许多大数据计划正是因为这个原因而失败【12】,但是将大数据贯穿于其组织和业务流程的组织正是那些从其投资中获得最大价值和收益的组织【13】。然而,将大数据集成到现有业务流程中可能需要逆转许多流程,并彻底转变决策方面的管理视角。如果您的组织已经引入了大数据,但您的决策流程并未发生实质性变化,那么您就错失了机会,并给组织的绩效带来了瓶颈。马泽伊&宣布:**
“有许多有远见的高管致力于构建数据资源,使他们的公司能够开发结合传统和现代战略思想的彻底创新的商业模式。本质上,这些领导者将数据视为其组织战略的核心,并选择专注于数据流而非数据存量*** (Davenport et al .,2012)。这些公司根据他们能够积累的数据开发出专注于其产品和服务的生态系统。。。随着这些学习型组织基于通过数据分析发现的趋势而动态发展,许多传统的扩张和多样化约束被贬低了。这些公司创造了杠杆——由于它们能够获得从过去和当前收入来源获得的数据、知识和资源——这使得传统的竞争壁垒(例如,买方/供应商的议价能力、进入壁垒)在许多情况下变得毫无意义 (Porter & Heppelmann,2014)。围绕这些公司的扩张和多样化的主要问题是 (1)他们现有的数据收集和分析是否提供了新的机会;(2)探索允许更丰富、更有洞察力的数据收集和分析;或者(3)扩展工作改善了组织的数据生态系统,其中最终客户被视为一个活生生的数据源。这些组织认为数据汇编本身就是创造价值的来源。他们不需要立即将数据货币化,因为如果他们捕获了足够多的数据,就可以在未来以无数的方式——也许是目前尚未实现的方式——利用这些数据,作为他们动态能力和数字生态系统发展的一部分,拓宽和导航新行业。。。在这里提到的公司中,有许多收购或产品线扩张乍一看似乎是被误导的,除非你把数据流想象成公司寻求的产出。公司。。。以战略身份查看数据的公司能够在没有直接盈利需求的情况下试验他们的产品(例如,脸书进入虚拟现实,苹果进入汽车,Alphabet 进入太空旅行和自动驾驶汽车),因此他们可以不断创新,学习他们不知道的东西。从战略上讲,这是一个与数据作为工具截然不同的概念,因为数据流和新知识成为战略政策和决策制定的驱动力。。。(这些类型的公司)不断将其平台发展成广阔的生态系统,渗透到消费者的生活中,建立数据库存,并增加数据流的数量,这些数据流将通过后来的产品和技术货币化,而这些产品和技术又可能继续增加数据流。【5】***
当我们考虑这种可能看起来像是传统管理理论的彻底转变的新视角时,重要的是要记住,这个世界与大多数当代管理理论发展时截然不同,那些没有赶上潮流的企业将被甩在后面。
您最近的业务决策是如何由数据驱动的?
回想一下你最近做的几个商业决策。这些决策中有多少是主要是根据你从另一个项目中发现的数据做出的?如果做出真正的数据驱动决策的过程还没有成为你企业文化的一部分,你就落后了。公司不再适合在利用数据之前做出决策。马泽伊(2017)是这样表述的:****
“【数据驱动】组织的勘探和开采决策不仅仅是基于盈利能力;相反,这些公司关心的是增强数据流,,目的是开发创新的服务模块,这些模块可以轻松地与现有平台结合,以执行不断提高的服务水平* (Morabito,2015)。。。在大多数当代战略管理理论形成的时候,我们没有短信、聊天、电子邮件、基本免费的长途电话接入、视频会议、数码照片和电影、几乎无限的数据存储,以及现在被视为理所当然的无数其他数字工具。相反,交易是通过传真、面对面的会议、打字机和“蜗牛”邮件来完成的。数据处理是一项漫长、昂贵而艰巨的任务。。。[数据驱动的]公司如何选择探索新市场不是通过传统的战略规划来完成的,而是通过机会识别来发展的,这些机会识别主要基于从持续分析更多更丰富的数据流中收集的信息。。。据预测,仅在美国,大数据、数字化和自动化将在 10-20 年内消除 47%的现有工作岗位 (Frey & Osborne,2013)【15】***
想象一下,如果 47%的员工被大数据、数字化和自动化所取代,你的公司会是什么样子。想想谁会留下,谁会被取代。思考哪些类型的角色可能会被取代。认识到这个行业正在发生的事情很重要,因为如果你还没有接受它,这个行业和你的竞争对手会替你接受它,而你可能会成为被取代的 47%中的一员。
您的数据是否已经决定了您的业务战略?
From Mazzei, M. J., & Noble, D. (2017)
全球对数据的看法正在发生变化,数据作为一种战略优先事项变得越来越重要。让我们从博弈的角度来思考一下策略。在各种游戏中,你可能会使用策略,通过做出某些选择来观察你的对手将如何反应,以便你可以估计他们的计划。你可能用策略来探索某些机会或决定,以收集更多关于回报或风险的信息。你可能已经使用策略来利用你的资源来获得竞争或位置优势。现在,在这些情况中,有多少是你的选择或信心受到你所拥有的可用信息数量的限制?想象一下,如果你有十倍于你正在考虑的决定的信息。你能看出它是如何在有利的选择和致命的选择之间做出区别的吗?Brandenburger 和 Nalebuff (2002)指出,“成功的商业战略是积极塑造你玩的游戏,而不仅仅是玩你发现的游戏。” [19] 当竞争对手奋力追赶时,将数据流作为战略重点的公司正在积极地塑造他们的市场并创造新的市场。然而,并非所有现有的业务流程都符合这种将数据放在第一位的现代范式,因此许多公司需要认真地重新审视他们的假设、优先级和思维。Massi & Nobel (2017)也表示:**
"访问海量数据和提升分析能力需要重新审视之前的假设。。。一家公司的业务层面战略决定了它如何使用数据来开拓当前市场,还是从一家公司的定位中产生的数据流在多样化和公司战略的发展中发挥了更重要的作用?尽管战略管理领域的传统观点认为,选择的战略决定了价值的衡量标准和数据的选择或适用性,但我们认为许多公司已经改变了这种方法。我们的观察表明,在某些情况下,收集和分析的数据对企业战略有着巨大的影响,而不是企业战略决定了应该收集和分析哪些数据(见图 1)。拥抱大数据带来的创新和探索机遇的公司正在实现新的价值创造和提高公司绩效* (Lavalle,Lesser,Shockley,Hopkins,& Kruschwitz,2011),,并且正在以前所未有的规模实现。我们见证了一场实践运动,这场运动通过剔除传统价值链和竞争力,开始解开过去 40 年来发展的许多已知战略管理理论(Evans,2013)。数据的用途正在发生变化,因为收集的数据有助于确定要探索的市场以及消费者趋势如何变化,并且数据可以实时推动这些决定。我们看到企业进入非传统市场,利用他们的数据和分析资源——结合大量的人力和金融资本——颠覆传统的进入壁垒。大数据推动者和创新者的最终目标是构建更丰富的知识和动态能力并应用大数据分析的优势,通过发展多样化的生态系统和数据流来创造独特和可持续的竞争优势。”【5】***
将数据放在第一位—大数据应该如何影响战略
你的公司最近一次启动面向客户的计划是在什么时候,当时认为该计划不会直接提供额外的收入,而是会提供数据,让执行管理层获得所需的洞察力,以确定他们是否应该进入一个他们以前没有考虑过的新市场?你的公司上一次冒着失去底线的风险启动一个项目是什么时候?这个项目纯粹是为了获得数据,向你展示你的客户是否会对获得某些潜在的高影响力的新产品功能而不是其他功能更感兴趣?你的公司上一次创建一个有争议的“高风险”项目(乍一看甚至可能被误导)来决定公司是否应该冒险进入一个全新的市场是什么时候,这个市场要么刚刚兴起,要么他们目前没有经验?如果这些都不适合你,那么你的公司就落后了。过于专注于实现眼前收入目标的公司将会错过获得最大长期收入收益的机会和市场机会,而这些机会只能通过从实验性数据收集工作中获得的洞察力来获得。Shah、Soriano 和 Coutroubis (2017 年)报告称:
"大数据项目通常会失败,因为组织[努力]在技术及其能力上,而不是商业机会上* [9]。采取创新方法并给予探索机会的公司,正在创造新的价值并达到[加速的]绩效[25]。根据[15],的说法,一个常见的错误是将大数据视为一个限定时间的项目,而不是一个持续的探索练习【17】***
将大数据作为核心战略优先事项意味着它不能孤立地完成。利用数据不能只由公司内一个孤立的专家小组来处理,即使是一个有影响力的专家小组。它必须成为一种系统的组织实践,渗透到管理思维和决策制定的各个方面。正如 Fleming,Fountaine,Henke 和 Saleh (2018)所述,如果大数据分析没有成为整个组织管理思想的一部分,即使是拥有集中式大数据分析业务的公司也很难从分析工作中创造价值:
“与任何重大商业计划一样, analytics 应该有自己的战略方向。。。我们观察到,拥有成功分析计划的组织将分析能力嵌入到其核心业务中。那些努力通过分析创造价值的组织倾向于孤立地开发分析能力,要么集中在远离业务的地方,要么分散在协调性差的孤岛中。这两种组织模式都是无效的。”【18】**
尚未在全公司范围内采用分析的公司可能需要进行重大变革,以完全由数据驱动,但第一个重要步骤是扭转我们的思维,将数据置于战略规划之前。
【1】克罗托夫,V. (2017)。物联网与新商机。业务视野, 60 (6),831–841。加粗补充道。检索自https://Fardapaper . IR/mohavaha/uploads/2018/03/Fardapaper-The-Internet of-Things-and-new-business-opportunities . pdf**
【2】brag anza,a .,Brooks,l .,Nepelski,d .,Ali,m .,& Moro,R. (2017)。大数据计划中的资源管理:流程和动态能力。商业研究杂志,70,328–337 页。加粗补充道。检索自https://www . science direct . com/science/article/pii/s 0148296316304933 # f 0005
【3】皮格尼,f .,皮考利,g .&沃森,R. (2016)。数字数据流:从大数据的实时流中创造价值。加州管理评论, 58 (3),5–25。加粗补充道。从 https://dds.cct.lsu.edu/ddslab/pdf/digitalDataStream.pdf取回**
【4】陈,l,Mislove,a,&威尔逊,C. (2016,4 月)。亚马逊市场算法定价的实证分析。在第 25 届万维网国际会议记录(第 1339-1349 页)。国际万维网会议指导委员会。从 https://mislove.org/publications/Amazon-WWW.pdf取回**
【5】马泽伊,m . j .&诺布尔,D. (2017)。大数据梦想:企业战略框架。商业视野, 60 (3),405–414。加粗补充道。检索自http://irana rze . IR/WP-content/uploads/2018/01/e 5723-irana rze . pdf**
【6】亚马逊公司(1998)。Amazon.com 收购两家领先的互联网公司[新闻稿]。检索自:http://phx.corporate-ir.net/phoenix.zhtml?c=97664&p = irol-news article&ID = 233831&highlight=
拉杰加塔,C. (1998 年)。Junglee 男孩在网上淘金。检索自https://web . archive . org/web/20131217162934/http://expression dia . Indian express . com/ie/daily/1998 08 14/22650774 . html检索于 2018 年 8 月 11 日。
【8】佩奇、l、布林、s、莫特瓦尼、r、&威诺格拉、T. (1999)。PageRank 引用排名:给网络带来秩序。斯坦福信息实验室。从 http://ilpubs.stanford.edu:8090/422/1/1999-66.pdf取回
【9】达文波特,T. H .,巴斯,p .,&比恩,R. (2012)。“大数据”有何不同。麻省理工学院斯隆管理评论。检索自https://pdfs . semantic scholar . org/eb3d/ECE 257 cc a2 e 8 ce 6 EAF 73 FD 98 C1 fdcbdc 5522 . pdf**
【11】husn JAK,s .、Perakovi,d .、Forenbacher,I .、& Mumdziev,M. (2015)。基于使用的汽车保险中的远程信息系统。 Procedia 工程, 100 ,816–825。从 https://core.ac.uk/download/pdf/82469016.pdf取回
Grover,v .,蒋,R. H .,梁,T. P .,&张,D. (2018)。从大数据分析中创造战略商业价值:一个研究框架。管理信息系统杂志, 35 (2),388–423。检索自https://www . tandfonline . com/doi/ABS/10.1080/07421222.2018 . 1451951****
【13】达文波特,T. H .,&戴奇,J. (2013)。大公司的大数据。国际分析研究所, 3 。检索自http://datascienceassn . org/sites/default/files/Big % 20 data % 20 in % 20 Big % 20 companies % 20-% 20 Tom % 20 aven port . pdf**
【15】马泽伊,m . j .&诺布尔,D. (2017 年 1 月)。不仅仅是一种资源?大数据现象的理论基础。载于《管理学院学报》(2017 年第 1 卷第 17546 页)。荆棘崖庄园,纽约 10510:管理学院。加粗补充道。检索自https://www . researchgate . net/profile/David _ noble 8/project/The-Digital-Economy-Big-Data-and-Strategy-Implications/attachment/595707 c 282999 C3 ee 923 cd7e/AS:51136483246080 @ 1498875842970/download/2017+AoM+Meeting+paper . docx?context = projectUpdateDetail
【17】Shah,s .,Soriano,c . b .&Coutroubis,A. D. (2017,12 月)。大数据是面向所有人的吗?中小企业采用大数据的挑战。在工业工程与工程管理(IEEM),2017 IEEE 国际会议上(第 803–807 页)。IEEE。加粗补充道。从 https://core.ac.uk/download/pdf/96675234.pdf取回**
【18】佛莱明,奥,方丹,t,亨克,n .&萨利赫,T. (2018)。十个危险信号表明你的分析程序将会失败。麦肯锡分析公司。加粗补充道。检索自https://www . McKinsey . com/business-functions/McKinsey-analytics/our-insights/ten-red-flags-signaling-your-analytics-program-will-fail
布兰登伯格,a . m .&纳勒布夫,B. J. (2002)。用博弈论来塑造战略。战略:对商业和管理的关键观点, 4 ,260。检索自http://faculty . som . Yale . edu/barrynalebuff/right game _ HBR 1995 . pdf**
您的数据科学团队是否增加了您的网络曝光率?
原文:https://towardsdatascience.com/is-your-data-science-team-increasing-your-cyber-exposure-8a24dbe789d1?source=collection_archive---------15-----------------------
随着网络攻击和数据泄露几乎每周都成为头条新闻,令人惊讶的是,科技公司仍然准备不足。许多此类违规都是由于安全措施不力和/或人为错误造成的:系统更新不够快,敏感数据没有加密,或者使用容易被破解的算法加密。威瑞森每年都会发布一份报告,分析他们的客户遭受的网络攻击。2018 年版反映了超过 2,200 起此类违规事件,其中许多本来是可以轻松避免的。你可以在这里阅读完整报告。
如果问题始于糟糕的 IT 实践,它肯定不会就此结束。网络钓鱼和勒索活动使用欺骗和社会工程方法,以不知情的员工为目标。一些公司投资了培训。但是这些知识仍然相对抽象,大多数员工没有将这些知识应用到他们的日常工作和生活中。例如,他们通过电子邮件交换 excel 电子表格中的数据,而没有对数据进行加密,也不关心其中包含的敏感信息。
现在,考虑一下您的数据科学团队。他们的日常活动要求他们处理大量数据。这些数据通常存储在由您的 IT 组织管理的系统中。数据科学团队要么直接访问它,要么以文本文件的形式导出它。在这两种情况下,数据都是为建模准备的,最终以未加密的形式保存在某个文件系统中,没有任何 IT 控制或安全措施。更糟糕的是,这些数据有时会通过未加密的电子邮件发送。
为了改变这种可悲的状况,公司需要创造一种文化,让每个人都意识到网络暴露,并知道每天要做些什么来减轻它。
保护您的 IT 基础设施
也许是时候改变你对安全的看法了。传统的外围安全模型依赖网络分段作为保护敏感资源的主要机制:防火墙内的设备应该比防火墙外的设备更受信任。
在 2009 年下半年极光行动发生后,包括谷歌在内的十几个组织成为目标,谷歌开发了一个名为 BeyondCorp 的零信任网络。在这种新模式中,所有应用程序都部署到互联网上,没有任何连接会因为位于防火墙定义的更安全区域而更受信任。访问权限在用户和设备级别进行管理,无论它们在哪里。
用它来决定文件应该存储在哪里,并确定最佳加密解决方案
就建模数据集的存储位置与 IT 部门达成一致是更好地管理网络风险的第一步。It 部门不可能保护他们甚至不知道存在的数据。
删除任何敏感信息
员工需要了解不同类型的敏感信息,并明白应该根据其敏感性对其进行不同的处理。主要的有:
个人身份信息 (PII)是指可单独使用或与其他信息一起使用的信息,用于识别、联系或查找个人,或在上下文中识别个人。
根据美国法律,受保护健康信息 (PHI)是指由承保实体(或承保实体的业务伙伴)创建或收集的、与特定个人相关的任何有关健康状况、医疗保健提供或医疗保健付款的信息。这种解释相当宽泛,包括患者病历或支付历史的任何部分。
支付卡信息 (PCI)是与支付卡相关的信息,如信用卡。
公司通常拥有更专业的敏感信息,并需要向员工公开这些信息。这些信息需要限制访问,并且永远不应该存储在未加密的数据库或文件中。
确保您的建模数据集以加密格式存储
即使所有敏感信息都已删除且数据已匿名,加密数据和任何中间产品以防止未经授权的访问也是一种良好的做法。
避免通过电子邮件发送数据
电子邮件是一种非常不安全的协议,使黑客很容易拦截消息或伪造电子邮件,并且永远不应该用于交换未加密的数据。
如果你交换数据的唯一方式是通过电子邮件,你应该总是使用高度安全的加密工具。有一些安全的解决方案可以让你对信息和附件进行加密和签名,比如 GPG 工具,一个开源产品。您应该向您的 IT 部门了解贵公司的最佳实践。
实施这些非常简单的步骤将大大降低公司面临的网络风险。安全是每个人的责任,不应该掉以轻心。
夏羽是Prometheus Ax的创始人& CEO,这家公司帮助 CEO 们优化数据科学项目的成功率和投资回报率。
您的组织为高级分析做好准备了吗?
原文:https://towardsdatascience.com/is-your-organization-ready-for-advanced-analytics-581edd5d2045?source=collection_archive---------6-----------------------
如何判断您已经准备好进行高级分析?
老板们认为网站流量分析只是为极客准备的。经过激烈的努力,你说服他们,这些数据有助于确保在线成功。现在,你终于将 Google Analytics 添加到了你的网站页面上,并且已经开始运行了。高层已经意识到分析数据的价值。他们了解游客来自哪里,停留多久以及其他有用的信息。这些知识揭示了你可以使网站更有吸引力的方法。但获得更高级的分析也有助于衡量改进如何促进游客和降低跳出率。
预见主要市场趋势
高级分析远远超出了简单的流量分析。它使您能够为网站优化和预测未来趋势建立模型。在线营销策略师用它来探索一系列可能的情况。例如,假设您的组织每月发行一期新闻稿。目前,该网站 20%的访问者订阅了它。你想知道对于每两周发行一次的时事通讯,这个比率是否会提高。高级分析能够评估访问者的反应。通过这种方式,你可以制定更有可能提高网站评级和促进销售的策略。
赢得管理层的支持
在基本版本运行并证明其价值后,是考虑高级分析的好时机。然而,决策者可能仍然怀疑是否需要更深入的数据挖掘。你如何推销这个想法?
从简单的概念解释开始,尽量少用专业术语。关注高级分析如何推进在线业务目标。展示一个与您的组织相关的典型场景。例如,假设你正在计划一项重大活动,并希望最大限度地提高出勤率。对游客偏好的深入了解有助于你决定项目和地点。
解释在谷歌上配置高级分析的实用性。例如,向他们展示配置报告以满足您的特定需求是多么容易。描述仪表板定制如何过滤掉最相关的网站数据。没有必要列出所涉及的每一个步骤。旨在展示基础和高级分析实践之间的平稳过渡。
组建专业的高级分析团队
招募高级分析专家的需求可能更难推销,但它确实有所不同。一个顶级团队必须包括准备数据的人和知道如何分析原始数据的统计学家。你还需要一个从商业角度理解这些结果意味着什么的人。正如 Carsten Bange 指出的那样,拥有一个知道如何向管理者展示结果的“数据艺术家”也是至关重要的。
在一些组织中,所需的技能存在于现有员工中。否则,他们将需要招聘员工或聘请代理服务。没错,这需要成本,但附加值证明了投资的合理性。信息是可用的,但是如果没有高级分析团队,就无法获得。高级分析不是水晶球,但如果你问了正确的问题,它会显示前进的方向。专业团队帮助你知道该问什么,他们“让分析为你服务”提供最佳答案。
最大化数据相关性
高级分析非常受欢迎。高德纳的研究主管吉姆·黑尔写道在过去的十年里,信息技术如何改变了商业面貌。如今,对于那些想要“扰乱现有市场并击败现有企业——无论是卖书、租电影、借钱,还是组建一支职业运动队——的新企业来说,这已经变得至关重要
说服高层可能需要一些努力,但结果会说明一切。如果你想为你的组织提取最相关的网站数据,这是你必须走的路。
使用我们的免费 excel 模板跟踪您的努力。
你的标准误差稳健吗?
原文:https://towardsdatascience.com/is-your-standard-error-robust-ae9376c0a882?source=collection_archive---------6-----------------------
选择正确规格的实用指南
行动纲要
- 问题:Stata、R 和 Python 报告的默认标准误差(SE)只有在非常有限的情况下才是正确的。具体来说,这些程序假设你的回归误差是独立同分布的。实际上,情况并非如此——这会导致假设检验中出现严重的第一类和第二类错误。
- 治疗 1: 如果你在管理 OLS,你必须在两个维度上对系统工程师进行聚类:个人年度。
- 治疗 2: 如果你在运行 FE(固定效果),你必须只在一个维度上聚集 SE:个体。
- 代码: 这里的是实现 SE 集群的 Stata、R、SAS 代码的链接。
如果你对这个问题感到好奇,请继续读下去。不然下次再见:)
为一天做计划
在这篇文章中,我将把一篇关于稳健标准误差的 69 页论文合并成一张备忘单。这篇由米切尔·彼得森教授于 2009 年发表的论文,截至今日已累计被引用超过 7879 次。它仍然是选择正确鲁棒标准误差的圣经。
问题是
惯例
在任何 Stats 101 课程中,你的教授可能已经教过你在 Stata 或 R 中键入“reg Y X ”:
Where i denote an individual; t denote timestamp t
你继续用报告的点估计值和标准误差来检验你的假设。但是 99%的情况下,这是错误的。
陷阱
为了让 OLS 给出无偏且一致的估计,我们需要误差项ε独立且同分布:
独立意味着不允许序列或交叉相关:
- 序列相关:对于同一个体,不同时间段的残差是相关的;
- 交叉相关:不同的个体残差在周期内和/或跨周期相关。
相同意味着所有残差具有相同的方差(也称为同方差)。
将问题可视化
让我们用方差-协方差矩阵来形象化独立同分布假设。
- 无序列相关性:红色气泡中的所有非对角线条目需要为 0;
- 无互相关:所有对角线上的条目需要相同——绿色矩形中的所有条目需要为 0;
- 同方差:对角线上的条目需要是相同的常数。
如果使用默认 se 而没有 I.I.D .错误,会有什么问题?
推导 SE 表达式:
默认标准误差是(3)中的最后一行。但是为了让我们从第一行到最后一行,我们需要做额外的假设:
- 我们需要独立性假设将我们从(3)中的第一行移到第二行。从视觉上看,绿色矩形中的所有条目和红色气泡中的所有非对角线条目都为 0。
- 我们需要同分布假设将我们从第二行移到第三行。从视觉上看,所有对角线上的条目完全相同。
默认 SE 在非常有限的情况下是对的!
犯错的代价
我们不知道报告的 SE 是否会高估或低估真实 SE。因此,我们最终可能会得到:
- 当实际上没有影响时,统计上的显著结果。结果,软件和产品团队可能不得不在一些对公司底线没有任何影响的原型上花费时间。
- 统计上无关紧要的结果,实际上却有重大影响。这对你来说可能是个好机会。错失良机。可惜:(
现实中,假阳性的可能性更大。不乏新手机器学习学生宣称他们已经找到了击败市场的一些模式/信号。然而,一旦部署,他们的模型表现灾难性。部分原因是他们从未考虑过残差的序列或互相关。
当这种情况发生时,默认的标准误差可能比真实的标准误差小 11 倍,从而导致信号的统计显著性被严重高估。
稳健的标准误差来拯救!
一个正确指定的稳健标准误差将消除偏差,或者至少改善偏差。有了稳健的标准误差,您就可以安全地进入推理阶段。
存在许多稳健的标准误差。选择错误的补救措施可能会加剧问题!
我应该使用哪种稳健的标准误差?
这取决于方差-协方差结构。问问你自己,你的残差是互相关、序列相关还是两者都有?回想一下:
- 交叉相关:在同一时间段内,不同的个体残差可能相关;
- 序列相关:对于同一个人,不同时间段的残差可能是相关的。
情况 1:误差项具有单独的特定成分
假设这是世界的真实状态:
假设个体之间是独立的,正确的标准误差是:
与(3)相比,我们有额外的术语,用红色圈出。所报告的 OLS 标准误差是超过还是低估了真实的标准误差,取决于相关系数的符号,其随后被时间段 t 的数量放大
实用指南在哪里?
基于更多的理论和模拟结果,Petersen 表明:
你不应该用:
- Fama-MacBeth 标准误差:它是为了处理序列相关性而设计的,而不是单个公司之间的交叉相关性。
- 纽威-韦斯特标准误差:它是为了说明单一时间序列的残差中未知形式的序列相关性而设计的。
你应该用:
- 聚类标准误差:具体来说,你应该对公司的标准误差进行聚类。代码请参考博客文章的结尾。
情况 2:误差项具有特定于时间的分量
假设这是世界的真实状态:
正确的标准误差本质上和(7)一样,一旦你把 N 和 t 互换。
你应该用:
- 标准错误:因为这就是它的构造目的。有关 Stata 代码,请参阅博客文章的结尾。
案例 3:误差项具有固定和时间效应
假设这是世界的真实状态:
你应该用:
- 聚类标准误差:聚类应在两个维度上进行——按年度确定。请注意,这不是真正的标准误差,它只是产生更少偏差的标准误差。当一个维度上只有少数几个簇时,这种偏差就更加明显。
编码
Petersen 详细的 Stata、R 和 SAS 指令和测试数据可以在这里找到。为了我自己的记录,我在这里编译 Stata 代码列表:
案例 1:一维聚类
回归因变量自变量稳健聚类(聚类变量)
案例二:法玛-麦克白
tsset firm_identifier 时间标识符
因变量自变量,byfm(by 变量)
案例 3:二维聚类
cluster2 因变量自变量,f cluster(cluster _ variable _ one)t cluster(cluster _ variable _ two)
案例四:固定效应+聚类
xtreg 因变量独立变量,健壮群集(cluster_variable_one)
享受你新发现的强健世界吧!
Photo Credit: Good News Philippines
直到下次:)
运行回归只需要一行代码
原文:https://towardsdatascience.com/it-only-takes-one-line-of-code-to-run-regression-24c5a36a9b43?source=collection_archive---------9-----------------------
我花了两年才发现这个!
我是一名普通的印度二级工程学院的 IT 毕业生。(这是不是让我的读者翻了一倍!?😁).像平常的学生一样,我过去常常阅读足够的课程材料,以免期末考试不及格。我是那种相信“大学让你为现实世界做好准备”的女孩。这样不对,我知道!由于我的信念,我在大学期间没有学到什么实质性的东西。但我总是想从人群中脱颖而出,总是想成为害群之马,因此开始了我变得相关的旅程。
我将努力成为相关的
和事件的参与者
我将申请 GSoC
并提交代码块
我将付出我的百分之
并继续相关
我开始尝试其他的事情,比如参加一个关于并行编程的课程,注册 HackerEarth,使用 Java 构建应用程序,学习 android 和创建应用程序,在 NLP 中使用 SVM 进行词义消歧项目,写关于 GCD 电路的论文,参加黑客马拉松。唷!任何事任何事。你猜对了,我哪儿也不去。
Source
在这一切之中,我被安排在班加罗尔的博物馆。这些家伙给了惊人的预安置讲话,他们确保我们知道这来自 HBR。这灌输到我的脑海中,我喜欢我开始玩数据的方式。我换了工作,与不同的客户、不同的数据源和不同的团队一起工作,但是有一个不变的东西,数据!
当你在以数据为中心的公司工作时,你会不断听到先进的机器学习技术。让你着迷,让你害怕的术语。回归是我的 Pennywise!以至于我从来不敢用谷歌去了解它。尽管我在大学里读过几乎每种机器学习技术背后的理论,但我从未实现过其中任何一种。我以为这是最酷的东西了。我一直认为这需要大量的学习、编码和理解。但是我必须从某个地方开始。我必须学会如何让数据讲述自己的故事。
我回来参加在线课程。我从 Coursera 上吴恩达的机器学习开始,是的,你猜对了。这对我来说有点太多了,我迷失了几个月。在我偶然发现 edX 上的分析优势之前,我不得不把自己拉回来,开始了另一门课程和其他一些课程。课程大纲说“通过鼓舞人心的例子和故事,发现数据的力量,并利用分析为你的职业和生活提供优势”。这门课程打破了我多年来的许多误解。这正是我开始探索数据和分析力量的原因。从那以后,
我学到了在对数据运行算法之前理解数据是多么重要,在获得洞察力之前了解背景和行业是多么重要,制作模型是多么容易,但让它们为你工作却是多么困难,最后,在数据集上运行线性回归只需要一行代码
下面是我的流言终结者。在数据中寻找线性模式的一行程序
*#Build the model on training data -* lmMod <- **lm**(DependentVariable ~ IndependentVariable, data=trainingData) *#Run prediction on test data -* testPred <- **predict**(lmMod, testData)
在我杀了我的 Pennywise 之后,学习其他的事情就容易多了。我完成了那门课程,注册了的另一门,参加了 Kaggle 比赛,玩了 Twitter 数据,创建了文字云,制作了聊天机器人,并且从未停止探索。我终于变得相关了!如果不是为了世界,也是为了我自己。如果我停止学习,我就不再相关。
如果你害怕做你一直认为是地球上最酷的事情,让我告诉你一件事,埃隆·马斯克的火星任务是目前最酷的事情,你可能只是害怕你的回归模型。出去,与人交谈,回来,利用互联网,学习,创造,展示。
希望这篇文章能帮助你开始做你最酷的事情。在下面的评论里告诉我更多关于你的小聪明,我们可以一起把他饿死!
有一段时间了
原文:https://towardsdatascience.com/it-s-been-a-while-b8e4e0ccf1bd?source=collection_archive---------2-----------------------
过去的三年过得真快。对我来说,是时候回到我的根本,开始写更多的博客了,就像我以前做的那样。
我上一篇帖子是关于 Strata 2013 的。在这段时间里,我正从全职工作中抽出时间来完成一篇博士论文,这是我在前两个职位期间所忽视的。我得到了惨痛的教训,如果你想在合理的时间内获得博士学位,就不要在外面工作!在这段间隙,我很快就从引言到前 65 页开始写起了我的论文。然后我收到了脸书的邀请。我准备搬到硅谷,享受我羡慕了这么多年的一切:额外津贴、创新和智慧文化,以及技术社区。这是一个我不能错过的机会,论文又被搁置了两年,因为我醒着的大部分时间都花在了工作上,无论是在工作日、周末还是节假日……疯狂地写论文。我期待着生活在一个我沉迷于技术和数据生态系统的世界里。但是…
另一边的草不会更绿
The cow tries to get the greener grass.
技术社区肯定在那里,而且显然非常强大,但它不是我想象的那样。由于这个行业的庞大规模,与我在洛杉矶地区所习惯的相比,聚会和其他活动非常没有人情味。此外,似乎大部分最初的硅谷创业能量都转移到了旧金山。为了参加聚会,我会花几个小时坐班车、Caltrain、BART 和 Muni 去 SoMa,然后对频繁的公司宣传感到失望,而不是讨论实际的科学和技术。并不是所有的小组都是这样,因为我参加了很多技术性的会议,激起了我学习更多的欲望。当然,还有一个问题是我是否能让加入meetup。我参加的大多数 meetup 小组会在几个小时内就挤满了一个热门话题或引人入胜的演讲者,等候名单有时长达 100 到 200 人。最后的打击是,我的出席假设我可以从工作中的项目中脱身,但我真的不能。我的技术社区最终成为了公司的其他人,这可能对我的工作有所帮助,但给了我一个比我想要的更窄的关注点,这只是让我继续工作的又一个因素。然而,聚会并不是技术社区中唯一重要的事情。我确实参加了一些会议,如 ACM SIGCIKM 、 BayLearn 、 Strata 2014 (但为了招聘),我还在 PyData 在脸书举行的时候发表了演讲。为了完全沉浸在技术社区和体验中,似乎现在需要住在旧金山,旧金山对我来说绝对不是一个城市——我更像是硅谷郊区类型的人,但活力不一样。
当我说我醒着的大部分时间都在工作时,我并不孤单。因为我是为了工作才搬到那里的,我在那里没有任何根、朋友或家人,所以我认为我这样做是有意义的。但是,以这样的速度工作对我的身体、精神和情绪都产生了影响。虽然在旧金山湾区有很多事情可以做,但由于工作文化的原因,真的没有时间去做。出于同样的原因,人们似乎没有时间陪我。这并不是对每个人都适用,但我发现在湾区比我生活过的其他地方更适用。除了长时间的工作之外,这不是我第一次成为生活中的“超额完成者”——这是我从高中(90 年代)开始就一直困扰的事情。
不仅有长时间工作和缺乏任何外部世界的压力,湾区也极其昂贵——没有人反对这一点。我在山景城的 850 平方英尺的一居室公寓现在以每月 4200 美元的价格出售。买房子对于初出茅庐或处于职业生涯中期的工程师来说通常是不现实的,除非他们已经在一家大公司工作了一段时间,或者从一家初创公司获得了一大笔薪酬,或者愿意从硅谷以外的地方通勤更长时间。在山景城和帕洛阿尔托,一套一居室的小房子很容易标价超过 100 万美元。接下来,将会有其他的竞标者也想要这栋房子。在帕洛阿尔托,价格已经高得离谱的房子以远高于挂牌价的价格出售,这种情况非常普遍。如果你是单身,你将需要注销税款,否则你将在纳税时大吃一惊。这种生活方式从长远来看是不可持续的。对我来说,这个问题并没有让我太想念这个地区。
另一方面,湾区的许多地方绝对美丽。从圣克鲁斯上方的绿色森林,到蒙特利北部的原始海岸线,圣何塞和东湾的绿色丘陵,到海湾沿岸奇异的异世界沼泽。这是一个干旱的两年,所以天气与洛杉矶没有太大的不同。
我学到了宝贵的一课。另一边的草不会更绿是真的。你可以给一个人提供免费餐、免费乘车和其他额外待遇(我甚至忘了它们是什么……它们最终变得不重要了),但它所做的只是让你继续工作,让你只专注于生活中的那一部分。你的“朋友”最后都在公司,在这样一个竞争激烈的环境里最后都成了坏事。像现场医生、牙医和理疗师这样的额外津贴听起来可能不错,但它们没有达到我在其他地方得到的服务的水平,而且也只是让你继续工作的方法。这些东西都是噱头。它们有利于吸引人们,有利于让生活变得便利,但它们真的只是让你继续工作、降低工资的方法。
筋疲力尽:是时候反思和放慢脚步了
当我回到洛杉矶时,我沿着太平洋海岸公路开车,眺望大海。冬日橘黄色的阳光透过窗户照射在我的脸上,我简直不敢相信已经两年没开车了。这不像我。我喜欢海滩的氛围,以及它带给我的放松感。那一刻,我意识到我要让自己的“神经”慢下来——不仅是回到原来的水平,甚至更慢。我想抽出时间给自己,不仅是为了完成我的研究,也是为了享受生活,想想作为一个人和一个专业人士,什么让我快乐。我意识到在那两年里,我失去了自我,随着每一个孤独的日子,我失去了对自己兴趣的热情,除了工作,我没有太多的爱好。
在过去的十年里,我在东部山区呆了很长时间,但是远远不够。我终于能够在 Mammoth 买一栋度假别墅,现在有时间享受它了。在过去的几个月里,我徒步旅行,骑山地自行车,穿雪鞋,驾车穿越一些大自然最美丽的地方。荒野的孤独和阴谋是非常洁净和有益于灵魂的。自从离开免费餐并变得如此活跃后,我也瘦了不少。我一直走得很快,并且总是更喜欢用我的腿而不是我的轮子,但这是自大学以来我第一次例行公事地做剧烈的心脏跳动活动。当我回首往事时,我意识到不仅仅是过去的三年让我精疲力竭。这是我成年后的全部生活方式。
事情已经改变了
在这篇文章中,我没有关闭任何一扇门,但我已经学会了重视一个健康的工作环境和工作时间,而不是额外津贴和纯粹的报酬。我的意图不是专注于薪酬和在“热门”公司工作,而是做对我的利益有益的工作,同时为我提供生活、退休的手段,并为我自己的爱好和副业项目提供资金。只有一件事我不会妥协(好吧,两件):我必须能穿短裤,我必须能有灵活的时间。现在,是否接受一个职位比看一家公司的基础产品以及在工作要求/描述中包含编码、机器学习和统计要复杂得多。我不想花 1%的时间使用一些基本模型(如朴素贝叶斯或逻辑回归)进行机器学习,而花 99%的时间进行数十亿次观察。相反,我希望能够在机器学习方面进行更多的探索,并学习预测和分类的新算法和方法。这并不意味着我完全想远离系统工程的东西,但这将真正取决于的产品和团队,而不仅仅是公司。
目前,我为一家初创公司提供咨询和指导。我可能会继续以此为职业,也可能不会。我有几个创业想法,我可能会去追求,但也可能不会。谁知道呢,也许我会回到湾区(在我前面提到的约束条件下),也可能不会。我可能会像以前一样在社区中更加活跃,但我已经意识到在博客圈、推特圈和这些数千美元的会议中有很多噪音、炒作和自我。只是做好自己的事情就有话说了。也许我刚刚成长为一名职业球员,我不知道。我只知道这些东西要半信半疑。
转换领域?
经过大量反思,我想看看“纯技术”之外的一些其他领域,包括但不限于:
- 环境和活动地理空间数据。在山区生活后,我对环境数据非常感兴趣,尤其是使用时间序列、GPS 遥测和地理空间分析。我对这一领域的兴趣有着广泛的应用,从为搜救行动有效放置雪地车,到运动和智能活动,甚至导航。
- 金融。金融曾经在我的“永远不要”清单上从我在创业公司和硅谷的时光中了解了更多关于经济学和华尔街的知识后,我也对金融方面的一些应用感兴趣。机器学习显然对自动化投资非常有用,但数据可视化对我来说在人工交易中已经被证明是有用的。
- 教育。我最初对统计学感兴趣的是心理测量学和教育评估的发展。我正在考虑回到这个方向。我还对教育技术领域感兴趣,它能改善教育材料的交付和学习评估。当然,我可能会去教书,最有可能是在大学水平,或作为某种类型的培训顾问。
- 航空:客机和无人机。了解我的人都知道我热爱机场、航空公司和飞行。航空使用许多不同的数据科学技术。无人机是一项新兴技术,在空中为无人机导航已经成为各公司正在努力解决的一项挑战。无人机和客机的路由都使用地理空间/地图数据和网络/图形数据,并考虑了影响飞行、空域拥堵和机场/地面资源使用的许多变量。等待时间和排队论对跑道运行也很重要。航班的定价和调度涉及到大量的博弈论、网络分析和其他数据科学。所有这些挑战对我来说都很有趣。
- “物联网”令我恼火的是,新兴的嵌入式系统领域、它们的开发和数据处理已经变成了另一个廉价的时髦词汇,就像“大数据”或“数据科学”的误用一样 Raspberry Pi、Arduino 和定制印刷电路板等设备允许大众创建新的数据收集设备,这些设备不引人注目地适合任何需要记录数据的地方。虽然数据本身很有趣,但在这种特殊情况下,我实际上对硬件和纯工程方面比数据科学方面更感兴趣。
- 安全是一个指数级增长的领域,不仅对国家安全,而且对隐私都变得至关重要。安全是我非常感兴趣的一个领域,但我对此知之甚少,因此是一个更具雄心的领域变化的选项。我可以看到这是一个领域,我对它了解得越多,我就会越有热情。安全对我来说是未知的领域,但我不认为它是一个会很快消失的领域。
在把这份清单打出来并重读一遍后,我意识到我仍然保持着和以前一样的热情,也许我的灵魂需要暂时专注于别的事情。现在我只需要做出选择,哪些是最有价值的,哪些为我提供了最好的机会。在任何工作面试中,总会有“你对我/我们有什么问题吗?”在过去的几年里,我整理了一份长长的问题清单。如果我不喜欢这个答案,或者如果我知道面试官在撒谎,那就放弃!额外津贴和名人并不是幸福或更充实生活的关键——成为一个更好的人和能够享受生活的过程才是。
要看我家附近的一些图片,请看 原帖 !
最初发表于www.bytemining.com。
项目反应模型和神经网络?
原文:https://towardsdatascience.com/item-response-model-and-neural-networks-bae4415b37bc?source=collection_archive---------5-----------------------
我必须承认的一点是,虽然多年来我一直断断续续地在我的一些工作中使用项目反应理论,但我认为我从未完全理解它的所有活动部分。
项目反应模型是用于通过测试评估“能力”的大型模型集的一部分。一个测试“项目”(即一个问题),无论其结构如何,必然有两种可能的结果:应试者要么答对了,要么答错了。正确的概率是能力的函数。因此,换句话说,该模型将测试者的“能力”作为答对问题的预测指标。由于“测试”将包含大量的项目,考生的能力基本上是作为许多项目的加权平均值来衡量的。“能力”被转化为答对一个问题的概率的函数形式被假定为逻辑函数的形式,这多少有些武断。
总体思路应该会提醒你神经网络是如何工作的,即使 IRM 的工作方式并不完全相似(相差甚远)。人们可能会认为每个测试问题都是一种模式,它被“激活”以将潜在的“能力”(我们想要测量的)和观察到的结果联系起来——无论应试者的问题是对还是错。给问题分配权重类似于反向传播。(也许这并不令人震惊:作为一个概念,神经网络毕竟是认知心理学家的作品,他们也熟悉 IRM 背后的逻辑)。
IRM 潜在的更有趣的地方是它如何对待问题本身,除了它们是否被激活以及它们在多大程度上有助于获得“正确”的答案。它估计了每个问题的一些参数。由于这种媒介对插入方程不友好,为此我需要从维基百科复制并粘贴一张图片:
这是 IRM 三参数逻辑变量的函数形式。与“项目”相关的参数是 a、b 和 c,而θ是与应试者“能力”相关的参数给定相同的(假定的)能力水平,问题本身具有 3 个不同的特征。参数 b 捕捉“难度”,即对于给定能力的应试者来说,答对的难易程度。参数 c 捕捉“噪音”,即高能力考生得到“错误”答案或低能力考生得到“正确”答案的难易程度
然而,我之前没有想到的是参数 a,判别参数。在给定应试者的能力水平的情况下,通过调整激活函数的斜率(以及 P(正确|85+a)和 P(正确|85-a)之间的差异),这捕获了该项目能够区分应试者能力(比如 85+a 和 85-a)的可能性。因此,IRM 的承诺是,通过利用基于参数 a 和 b 选择的问题的明智组合,可以构建一个侧重于特定能力范围的测试。
在某种意义上,将 IRM 直觉应用于 ML 问题比在测试环境中更容易。在测试问题中,“能力”是未知的。它们需要根据测试结果进行估计,并且使用能力估计值作为起点来估计单个测试项目的参数。在最大似然问题中,我们清楚地知道输入是什么。在每个分类问题(和神经网络应用)中,我们“知道”这些输入通过一些逻辑函数(或类似的函数)转化为结果,我们通过我们拥有的样本估计其参数:在纯逻辑模型中,我们估计“平均”数据、增强模型的参数,我们估计补充“主要”逻辑函数的附加模型/公式以解决分类误差,在神经网络中,我们估计一整串逻辑函数(作为各种节点的激活函数),并根据每个逻辑函数对误差的贡献大小等迭代地对它们赋予权重。基于神经网络的模型更接近 IRM,至少在某种意义上,它估计了激活函数本身的一些参数,但它仍然有点幼稚,因为据我所知,它们是对整个样本(验证集)估计的参数。然而,似乎更合理的是,每个节点的辨别能力和相关的激活函数应该被概念化为输入的函数,并且用于特定组成的数据集的节点集合应该在此基础上被有策略地选择。让 IRM 适应 ML 环境指出了前进的方向——假设人们还没有这样做。
*大多数人把这个框架称为项目反应理论,缩写为 IRT。因为它只是一个概念框架,一个模型,而不是一个“理论”,称它为 IRM 似乎更合适一些,我坚持它。
基于采样的迭代初始质心搜索 k 均值聚类算法
原文:https://towardsdatascience.com/iterative-initial-centroid-search-via-sampling-for-k-means-clustering-2b505119ae37?source=collection_archive---------5-----------------------
“Black Night Sky” by Shlomo Shalev on Unsplash
在这篇文章中,我们将着眼于使用迭代方法来搜索 k-means 聚类的一组更好的初始质心,并且将通过在我们的完整数据集的样本上执行这个过程来实现。
我们说的“更好”是什么意思由于 k-均值聚类旨在通过连续迭代收敛于聚类中心(质心)和基于距这些质心的距离的聚类成员的最优集合,直观地,这些初始质心的定位越最优,收敛所需的 k-均值聚类算法的迭代次数就越少。因此,考虑寻找一组更好的初始质心位置是优化 k-means 聚类过程的有效方法。
具体来说,我们要做的是从我们的完整数据集中提取一个数据样本,并对其运行 k-means 聚类算法的短期运行(不收敛),短期运行将包括质心初始化过程,这是不必要的。我们将使用多个随机初始化的质心重复这些短时间运行,并将跟踪度量标准(类内平方和)的改进,以确定类成员的优度(或者至少是度量这种优度的有效度量标准之一)。与提供最低惯性的随机质心初始化迭代过程相关联的最终质心是质心集,我们将把该质心集带入我们的完整数据集聚类过程。
希望这项前期工作将为我们的完整聚类过程带来一组更好的初始质心,从而减少 k-means 聚类迭代次数,并最终减少完全聚类数据集所需的时间。
这显然不是优化质心初始化的唯一方法。在过去,我们已经讨论了朴素分片质心初始化方法,一种用于最优质心初始化的确定性方法。对 k-means 聚类算法的其他形式的修改也采用了不同的方法来解决这个问题(参见 k-means++ 进行比较)。
本帖将按如下方式处理我们的任务:
- 准备数据
- 准备我们的样品
- 执行质心初始化搜索迭代,以确定初始质心的“最佳”集合
- 使用结果对整个数据集执行聚类
为了更全面地理解实现的实用性,以后的文章将对质心初始化的各种方法的结果进行比较并报告。然而,现在让我们介绍和探索这种质心初始化的特殊方法。
准备数据
对于这个概述,我们将使用 3D 道路网络数据集。
由于这个特定的数据集没有缺失值,也没有类标签,我们的数据准备将主要包括归一化,同时删除一列来标识额外 3 列测量值来自的地理位置,这对我们的任务没有用处。更多详情参见数据集描述。
import numpy as np
import pandas as pd
from sklearn import preprocessing# Read dataset
data = pd.read_csv('3D_spatial_network.csv', header=None)# Drop first column (not required)
data.drop(labels=0, axis=1, inplace=True)# Normalize data (min/max scaling)
data_arr = data.values
sc = preprocessing.MinMaxScaler()
data_sc = sc.fit_transform(data_arr)
data = pd.DataFrame(data_sc)
让我们来看看我们的数据样本:
data.sample(10)
准备样品
接下来,我们将提取用于寻找“最佳”初始质心的样本。让我们明确一下我们到底在做什么:首先,我们从数据集中抽取一组样本;然后,我们将对此样本数据执行连续的 k-means 聚类,每次迭代将:
- 随机初始化 k 个质心并执行 n 次 k 均值聚类算法迭代
- 将记录每个质心的初始惯性(聚类内平方和),以及其最终惯性,并且在 n 次迭代中提供最大惯性增量的初始质心将被选为我们用于完整数据集聚类的初始质心
最后,我们将使用上一步中找到的初始聚类对整个数据集执行完整的 k-means 聚类。
2 个要点:
- 为什么不使用惯性最大下降?(希望这一领域最初的势头能够持续下去。)。)这样做也是一个值得探索的有效选择(更改一行代码就可以做到这一点)。一个任意的初始实验选择,一个可能需要更多调查的选择。然而,对多个样本的重复执行和比较最初表明,惯性的最低值和最大下降值在大部分时间是一致的,因此决定可能实际上是任意的,但在实践中也是无关紧要的。
- 特别澄清的是,我们没有从我们的数据集中多次采样(例如,质心初始化的每次迭代从我们的数据集中采样一次)。对于单个质心初始化搜索的所有迭代,我们采样一次。一个样本,我们将从中多次随机获取初始质心。与重复采样的想法形成对比,每次质心初始化迭代一次。
下面,我们设置:
- 样本量占整个数据集的比例
- 再现性的随机状态
- 数据集的聚类数(k)
- k-means 算法的迭代次数(n)
- 在样本数据集上进行聚类时,尝试寻找最佳机会初始质心的次数
然后我们设置样本数据
# Some variables
SAMPLE_SIZE = 0.1
RANDOM_STATE = 42
NUM_CLUSTERS = 10 # k
NUM_ITER = 3 # n
NUM_ATTEMPTS = 5 # mdata_sample = data.sample(frac=SAMPLE_SIZE, random_state=RANDOM_STATE, replace=False)
data_sample.shape
现在,当我们有了数据样本(data_sample
)时,我们准备好执行质心初始化的迭代以进行比较和选择。
样本数据聚类
因为 Scikit-learn 的 k-means 聚类实现不允许在聚类迭代之间容易地获得质心,所以我们必须对工作流进行一些修改。虽然verbose
选项确实会将这方面的一些有用信息直接输出到 screen,并且重定向该输出,然后对其进行后解析,这将是获取我们所需要的信息的一种方法,但是我们要做的是编写我们自己的外部迭代循环来控制我们自己的 n 变量。
这意味着在每个聚类步骤运行之后,我们需要计算迭代次数,并在这些迭代之间捕获我们需要的内容。然后,我们将聚类迭代循环包装在质心初始化循环中,这将从我们的样本数据 m 次初始化 k 个质心。这是特定于我们的 k 均值质心初始化过程的特定实例化的超参数,超出了“常规”k 均值。
给定我们的上述参数,我们将我们的数据集聚类成 10 个聚类(NUM_CLUSTERS,或 k ),我们将运行我们的质心搜索 3 次迭代(NUM_ITER,或 n ),我们将尝试使用 5 个随机初始质心(NUM_ATTEMPTS,或 m ),之后我们将确定我们的“最佳”质心集,以初始化完整的聚类(在我们的情况下,度量是类内最小的平方和,或惯性)。
然而,在任何聚类之前,让我们看看在任何聚类迭代之前,我们的 k-means 的单个初始化是什么样的。
from sklearn.cluster import KMeanskm = KMeans(n_clusters=NUM_CLUSTERS, init='random', max_iter=1, n_init=1)#, verbose=1)
km.fit(data_sample)print('Pre-clustering metrics')
print('----------------------')
print('Inertia:', km.inertia_)
print('Centroids:', km.cluster_centers_)Pre-clustering metrics
----------------------
Inertia: 898.5527121490726
Centroids: [[0.42360342 0.20208702 0.26294088]
[0.56835267 0.34756347 0.14179924]
[0.66005691 0.73147524 0.38203476]
[0.23935675 0.08942105 0.11727529]
[0.58630271 0.23417288 0.45793108]
[0.1982982 0.11219503 0.23924021]
[0.79313864 0.52773534 0.1334036 ]
[0.54442269 0.60599501 0.17600424]
[0.14588389 0.29821987 0.18053109]
[0.73877864 0.8379479 0.12567452]]
在下面的代码中,请注意,我们必须在每次迭代开始和结束时手动跟踪我们的质心,因为我们自己正在管理这些连续的迭代。然后,我们将这些末端质心作为初始质心送入下一次循环迭代,并运行一次迭代。有点乏味,而且令人恼火的是,我们不能直接从 Scikit-learn 的实现中得到这一点,但这并不困难。
final_cents = []
final_inert = []
for sample in range(NUM_ATTEMPTS):
print('\nCentroid attempt: ', sample)
km = KMeans(n_clusters=NUM_CLUSTERS, init='random', max_iter=1, n_init=1)#, verbose=1)
km.fit(data_sample)
inertia_start = km.inertia_
intertia_end = 0
cents = km.cluster_centers_
for iter in range(NUM_ITER):
km = KMeans(n_clusters=NUM_CLUSTERS, init=cents, max_iter=1, n_init=1)
km.fit(data_sample)
print('Iteration: ', iter)
print('Inertia:', km.inertia_)
print('Centroids:', km.cluster_centers_)
inertia_end = km.inertia_
cents = km.cluster_centers_ final_cents.append(cents)
final_inert.append(inertia_end)
print('Difference between initial and final inertia: ', inertia_start-inertia_end)Centroid attempt: 0
Iteration: 0
Inertia: 885.1279991728289
Centroids: [[0.67629991 0.54950506 0.14924545]
[0.78911957 0.97469266 0.09090362]
[0.61465665 0.32348368 0.11496346]
[0.73784495 0.83111278 0.11263995]
[0.34518925 0.37622882 0.1508636 ]
[0.18220657 0.18489484 0.19303869]
[0.55688642 0.35810877 0.32704852]
[0.6884195 0.65798194 0.48258798]
[0.62945726 0.73950354 0.21866185]
[0.52282355 0.12252092 0.36251485]]
Iteration: 1
Inertia: 861.7158412685387
Centroids: [[0.67039882 0.55769658 0.15204125]
[0.78156936 0.96504069 0.09821352]
[0.61009844 0.33444322 0.11527662]
[0.75151713 0.79798919 0.1225065 ]
[0.33091899 0.39011157 0.14788905]
[0.18246521 0.18602087 0.19239602]
[0.55246091 0.3507018 0.33212609]
[0.68998302 0.65595219 0.48521344]
[0.60291234 0.73999001 0.23322449]
[0.51953015 0.12140833 0.34820443]]
Iteration: 2
Inertia: 839.2470653106332
Centroids: [[0.65447477 0.55594052 0.15747416]
[0.77412386 0.952986 0.10887517]
[0.60761544 0.34326727 0.11544127]
[0.77183027 0.76936972 0.12249837]
[0.32151587 0.39281244 0.14797103]
[0.18240552 0.18375276 0.19278224]
[0.55052636 0.34639191 0.33667632]
[0.691699 0.65507199 0.48648245]
[0.59408317 0.73763362 0.23387334]
[0.51879974 0.11982321 0.34035345]]
Difference between initial and final inertia: 99.6102464383905...
完成之后,让我们看看我们在质心搜索中做得怎么样。首先,我们检查最终惰性的列表(或组内平方和),寻找最低值。然后,我们将相关的质心设置为下一步的初始质心。
# Get best centroids to use for full clustering
best_cents = final_cents[final_inert.index(min(final_inert))]
best_cents
这是这些质心的样子:
array([[0.55053207, 0.16588572, 0.44981164],
[0.78661867, 0.77450779, 0.11764745],
[0.656176 , 0.55398196, 0.4748823 ],
[0.17621429, 0.13463117, 0.17132811],
[0.63702675, 0.14021011, 0.18632431],
[0.60838757, 0.39809226, 0.14491584],
[0.43593405, 0.49377153, 0.14018223],
[0.16800744, 0.34174697, 0.19503396],
[0.40169376, 0.15386471, 0.23633233],
[0.62151433, 0.72434071, 0.25946183]])
运行全 k 均值聚类
现在,有了我们最好的初始质心,我们可以在我们的完整数据集上运行 k-means 聚类。由于 Scikit-learn 允许我们传入一组初始质心,我们可以通过下面比较简单的代码来利用这一点。
km_full = KMeans(n_clusters=NUM_CLUSTERS, init=best_cents, max_iter=100, verbose=1, n_init=1)
km_full.fit(data)
这种特殊的 k 均值运行在 13 次迭代中收敛:
...start iteration
done sorting
end inner loop
Iteration 13, inertia 7492.170210199639
center shift 1.475641e-03 within tolerance 4.019354e-06
为了比较,这里有一个完整的 k 均值聚类运行,只使用随机初始化的质心(“常规”k 均值):
km_naive = KMeans(n_clusters=NUM_CLUSTERS, init='random', max_iter=100, verbose=1, n_init=1)
km_naive.fit(data)
这次运行花费了 39 次迭代,具有几乎相同的惯性:
...start iteration
done sorting
end inner loop
Iteration 39, inertia 7473.495361902045
center shift 1.948248e-03 within tolerance 4.019354e-06
我将寻找 13 次迭代和 39 次迭代(或类似的)之间的执行时间差异留给读者。不用说,从长远来看,提前几个周期吃掉一个数据样本(在我们的例子中,是整个数据集的 10%)节省了相当多的周期,而不会牺牲我们的总体集群度量。
当然,在得出任何概括之前进行额外的测试是有保证的,在未来的帖子中,我将在各种数据集上对许多质心初始化方法进行一些实验,并与一些额外的度量进行比较,希望能够更清楚地了解如何优化无监督学习工作流。
这篇文章最初发表在 KDnuggets 上。
它还活着!构建通用人工智能是未来
原文:https://towardsdatascience.com/its-alive-building-general-ai-is-the-future-ddd8f75d09dc?source=collection_archive---------5-----------------------
我的朋友们一次又一次地听到我这样说。人工智能正在走向超越人类自动化的认知“生活”。计算机(真的是人工智能)将开始采取主动,有目的地行动,而不是成为那个"快速的白痴"我们在过去几十年的计算机架构中已经非常了解这一点。我将在 7 月提交两篇关于这个主题的论文。一个关于无监督学习,另一个关于计算机视觉。两者都是关于人工智能主动远离人类。
这是一个大的想法:我们可以使用人工智能来为我们思考,就像一个帮助我们的伙伴一样。我们正朝着一个方向前进,在这个方向上,执行任务的认知压力将被人工智能人才的不断上升所抵消。具体来说,我们可以将人工智能作为一种工具来提高我们的生产力,从自动驾驶汽车(强化学习)到寻找屏幕错误信息的解决方案(监督或无监督学习)。
后一个例子是最近这些论文的主题。我和我的合作者开发了一种只使用屏幕图像来观察计算机屏幕的人工智能,并通过观察用户的行为来学习帮助用户。帮助以可点击按钮的形式提供。单击按钮会执行广告的操作。例如,查找与屏幕上的编译器错误信息相关的堆栈交换页面。人工智能将很快从任务自动化(帮助人类)的低级角色中爬出来,直接进入自我指导的活动。乍一看,这似乎是一件坏事,但放大来看,这可能会是一件好事。
An AI system that offers to help users perform actions with the click of a button.
一个自我激励的人工智能会是什么样子?我们来玩创世纪吧。它需要有一些像眼睛一样的感知能力。那将是一个或多个卷积神经网络(CNN)。它需要一些内部系统来根据过去预测未来。也许这将是一个 LSTM 系统。它将需要某种方法来学习基于经验的规则,比如用策略网络来指导信息系统开发的强化学习。它还可能有一个生成性对抗网络(GaN)来与自己对抗并模拟行动的结果。关系网络(RN)和视觉互动网络(VIN)也可以帮助推理。它将需要效应器和传感器与世界互动,我相信这些将是互联网接入,音频输入/输出,投影仪和/或屏幕。我不认为实际的机器人技术是人工智能的逻辑步骤。为什么要有身体?这只会让出行变得更加缓慢。我们不应该把 AI 拟人化。这是新的东西。
从这里到自我激励的人工智能的路径是模糊的,但不是不可能看到的。我不相信会是一些偶然发现的侥幸给我们带来自我激励的人工智能,就像一个股票市场机器人失控。不,这将是研究人员有意为之。在科学领域,当某件事看似可能时,书呆子们就会去工作。我们快速行动,打破常规,最终展示一个演示。
不过,这是件好事。我不是一个煽动对人工智能恐惧的人。我认为看到人类是否能接受人工智能将是令人兴奋的。到目前为止,我们的社会在接受持续自动化和语音人工智能方面做得非常好。这最后一步——产生有自我意识的生物——可能是我们做过的最伟大的事情。我是作为三个孩子的父亲说这番话的;不是为了夸张。
不是所有的反超级智能,但未来看起来是光明的。是的,我们有道德和社会问题要解决。也许我们需要一个全民基本收入。也许我们需要重新思考资本主义,转向星际迷航式的治理模式。谁知道呢。但至少现在,让我们坐下来欣赏这场表演。我们没有被卡住。进展非常快。
我很期待接下来会发生什么。
编码快乐!
-丹尼尔
丹尼尔@lemay.ai ←打个招呼。
LEMAY . AI
1(855)LEMAY-AI
您可能喜欢的其他文章:
- 人工智能和不良数据
- 人工智能:超参数
- 人工智能:让你的用户给你的数据贴上标签
这是魔术:M19 的趋势
原文:https://towardsdatascience.com/its-magic-data-science-lab-project-bbf73f2b6eef?source=collection_archive---------20-----------------------
分析万智牌甲板模式并根据过去的草稿预测起草顺序
一、背景
该项目由丹尼·沃、特洛伊·斯蒂德、帕特里克·朱、亚伦·李、塞缪尔·张打造。我们项目的代码可以在这个 repo 中找到。对于我们的项目,我们选择寻找万智牌(MTG)领域的问题,因为我们的小组拥有一些领域知识,并且有可能将我们的爱好与数据探索问题/优化问题结合起来。
背景:你可以通过这个链接更正式的了解 MTG 的 Booster 草案格式。快速概述,MTG 的助推器包有 15 个独特的卡。在助推器草案期间,每个球员有 3 个助推器包。每个玩家将打开他们的第一个包,并选择一张卡片。然后他们会把剩下的牌传给下一个玩家,再选一张牌。这种情况一直持续到所有的牌都被挑完,剩下的牌包将在用完前一包中原来的 15 张牌后被打开。玩家将以 45 张牌结束选秀,他们将用这些牌组成他们的锦标赛牌组。
此外,一个重要的注意事项是,升压包来自特定的卡组。一些例子集是“终极大师”,“核心集 2019”等。升压包可能包含许多卡片。因此,在一个典型的助推器草案起草阶段,所有三个包将来自同一套。
目标:我们的目标是使用我们的数据,看看我们是否可以训练一个(些)模型来生成甲板原型,并为 MTG 的增强草案格式提出选秀建议。
二。数据
我们的数据集来自一个名为 Top8Draft 的网站,该网站使用机器学习对模拟草稿进行评分。我们联系了网站的所有者,他慷慨地给了我们 280,421 个模拟甲板的数据,用于我们的模型建筑。图 1 显示了一个样本面板(JSON 格式)。
Figure 1: Each deck from Top8Draft has a set of a card IDs (which refers to a unique card from MTG) along with the frequency of the card in the specific deck.
我们使用一个名为 Scryfall 的公开可用的 MTG 卡片 API 将我们起草的卡片组分成各自的组。对于剩余的建模/数据探索,我们选择使用“核心集 2019”集(通常缩写为 M19)来限制可变性,使我们更容易生成可用的结果。
注意:我们最初试图在所有甲板上运行我们的模型(没有分成组),我们得到的原型(将在后面解释)没有意义,因为甲板原型来自各种组,而不是单个组。
三。排名卡协同
为了探索我们的数据集,我们决定处理数据,尝试排名卡协同作用。利用用户草案是合理选择的假设,我们能够为 M19 集生成顶卡协同效应。我们通过计算一张卡片与其他卡片出现的频率来对卡片进行成对排序,然后通过卡片之间各自的计数来确定它们的排序。我们的发现如图 2 所示。
观察:起初,我们注意到我们的原始协同得分严重偏向普通卡片,因为它们更经常出现在包中。为了解决这个问题,我们通过将分数除以每副牌的数量来“标准化”数据。这可能会使我们的数据偏向更稀有的卡片,但无论如何这是一个更好的解决方案,因为它们固有的卡片价值。理想情况下,如果我们有更多功能的数据,我们可以根据卡片的价值对其进行排序,但考虑到我们的数据限制,这是一个令人满意的解决方法。
Figure 2: A “heatmap” representation of our synergy scores between cards. As you can probably see, there are blocks of high synergies along the main diagonal. This is expected because cards of the same color, or “card type,” are given IDs in sequential order. (made with Seaborn)
我们还以卡片形式收录了一些表现最佳的协同组合:
Figure 3: This was our highest synergy pair with a Rare card, Sai, and a common card. It’ s interesting to note that both of their abilities result in a 1/1 Thopter artifact creature.
Figure 4: Our next highest ranking pair has a similar construct of a Rare, Goblin Trashmaster, and a common, Goblin Instigator.
四。生成原型
方法论:我们使用了一个潜在的狄利克雷分配(LDA)模型来生成 M19 集合的“原型”。我们希望这将产生符合普通起草策略的特色套牌,并可能揭示一些关于起草的“隐藏”见解。我们这种方法的灵感来自于这款笔记本,它以前是《海岸巫师》的特色。
更多关于 LDA 的正式解释可以通过维基百科和 TowardsDataScience 找到(其中包括一些例子)。LDA 是自然语言处理中常用的主题建模算法。我们选择了 LDA,因为它似乎是一种有趣的方式,可能产生 MTG 原型,或共同的甲板身份,给定类似于“文件”的甲板结构。
出于我们的目的,我们将卡片视为“文档”,将卡片本身视为“单词”,希望找到我们的“主题”,也就是我们的原型。我们使用 gensim ,一个主题建模库,用于我们的 LDA 模型。
对于狄利克雷参数,我们在【1.0/原型】原型之前设置我们的 alpha,在【1.0/原型】* unique_cards* 之前设置我们的 beta。(我们确信我们的每个文档都包含一个原型,这就是为什么 alpha 等于 1。对于我们的测试版,我们希望测试版随着独特卡的数量而扩展)。
对于我们的 M19 草案,我们在我们想要生成的原型数量上做了大量的尝试,发现当我们生成 30 个原型,每个原型有 45 张卡时,我们的结果是最好的。
下面以卡片的形式展示了一些产生的原型。为了可读性,我们只包括了每个原型大约 10 张卡片。原型的完整 PDF 可以在报告中找到,或者通过链接找到。
Figure 5: Archetype #1 is a white/black deck strategy built around the Uncommon card, Regal Bloodlord, which can be used as both white and black.
Figure 6: Archetype #2 is a Artifact Deck with some red/blue cards sprinkled in.
Figure 7: Archetype #4 appears to be a red/green deck which is built around the Legendary, Vaevictic Asmadi, and/or the Uncommon, Draconic Disciple.
注意:PDF 中的卡片是按照它们出现在每个原型中的概率排序的。
首先要注意的是,原型通常不超过两种原色(可能还有第三种或第四种第二色)。万智牌的每种颜色通常都有一些相关的属性。比如,抽牌通常和蓝色联系在一起,法术伤害通常和红色联系在一起。扩展集是为某些颜色设计的,以便与其他颜色很好地协同,因为草稿甲板通常是两种或三种颜色。
这些元素显示在上面的示例 LDA 原型中。即使有两种以上的颜色,像原型#4,第三和第四种颜色表现得很轻。
原型的另一个可能的焦点是卡片类型。如原型#2 所示,这些牌围绕着神器牌类型同生。魔法中的许多神器都是无色的,但即使是这个原型中的有色卡也会奖励玩家使用神器。
动词 (verb 的缩写)建议选秀权
起初,我们希望使用我们的原型结果来建议选秀,但是结果不会非常有用,因为原型没有明确说明卡的协同作用或卡的强度,这可能会迫使算法选择较弱的卡来尝试匹配特定的原型,而不是选择最好的。此外,该算法不需要任何机器学习,这对类本身没有太大帮助。
相反,我们尝试使用 XGBoost 多标签分类器来预测每回合使用哪张牌。我们的功能旨在存储当前棋盘和玩家手牌的“状态”。每一行都有玩家当前手里的牌(二进制—包括或不包括)以及当前牌包中的可用牌。我们基于从顶部 8 草稿刮取的 4000 份草稿日志来训练我们的模型。
注意:起初我们有 25565 个从 Top8Draft 刮来的草图日志,然而因为每个草图包含 45 个“转弯”,我们有超过 110 万个可用的特征行。我们遇到了数据帧的内存限制,因此我们必须限制用于模型训练/测试的日志数量。虽然有 4,000 个草案日志,但我们仍有近 180,000 行数据。
假设:我们假设用户选秀是最佳选择,即使一般的 MTG 球员可能并不总是最佳选择。例如,玩家经常因为个人偏好特定的牌而打草稿,或者新手玩家可能不熟悉牌之间的协同作用。我们希望草稿的数量会减少次优草稿的影响,但是我们关于最优性的假设可能会直接降低我们的准确性。
调优后,我们实现了大约 35,000 行的大约 63%的测试精度。相比之下,简单的猜测会产生大约 22%的正确率,我们的结果有非常显著的 p 值(μ:. 22;σ: .415;n: 35,532 个样本)。
我们的模型无法达到我们希望达到的 80%的正确率,但对于一个玩家来说,每 15 张牌中选择大约 9 张“最优”牌大约是一个普通 MTG 玩家的水平。随着更多的数据和可能更多的关于草稿质量的分析,该模型肯定可以改进以获得更好的准确性。
动词 (verb 的缩写)走向
将来,我们希望重新训练该模型以优化其建议,并探索其他 MTG 集。由于内存限制,我们只使用了 25,565 个草稿日志中的 4,000 个。然而,我们相信随着数据的增多,模型的准确性会显著提高。我们还希望将我们的卡片协同效应和卡片组原型发现与建议模型相结合。另一种选择是尝试神经网络方法,这也可以提高准确性或揭示关于数据集的新见解。虽然有许多路线继续这个项目,MTG 是一个复杂的游戏,我们只探讨了其中一个格式的一套。我们的技术可以重复使用,以探索游戏的其他方面,并可能向社区揭示新的、有见地的信息。
不仅仅是从事机器人工作的工程师
原文:https://towardsdatascience.com/its-not-only-engineers-who-work-in-robotics-8c65259247b5?source=collection_archive---------0-----------------------
Occupational Therapist Rosalie Wang investigates how intelligent haptic robotic systems can benefit people recovering from upper limb disability due to stroke. Photo courtesy IATSL (Intelligent Assistive Technology and Systems Lab) at Toronto Rehab, University of Toronto.
机器人技术一直是一个跨学科的领域,它整合了计算机科学、机械、电子、控制和其他工程领域的知识。但是,随着机器人走出工厂和研究实验室,进入我们的家庭和工作场所,另一种机器人专家正在出现——工程或计算机科学学位不一定是他们简历的一部分。
从职业治疗到康复机器人
Rosalie Wang 是智能辅助技术和系统实验室的助理教授,这是一个多学科研究小组,由工程师、计算机科学家、康复和医学研究人员组成,他们利用人工智能和机器人技术开发智能辅助和治疗设备。IATSL 研究涵盖所有领域,包括电动轮椅的避障和导航系统、跌倒检测解决方案、中风康复的智能触觉系统、帮助就地老龄化的个人机器人、痴呆症患者的辅助机器人等等。
但王的职业生涯始于职业治疗师,为长期护理的客户提供支持。她的热情是帮助老年人,在一家养老院工作时,她发现自己在摆弄客户的轮椅。“我会带着满是油脂的指甲回到家,把轮椅拆开又组装起来,以便更好地满足我客户的需求。”一件事接着一件事,很快她发现自己正在攻读电动轮椅防撞技术的博士学位。
将技术转化为实践
寻找“人的问题”的技术解决方案是一种特殊的技能,需要对最终用户及其环境有深刻的了解,并有能力与工程师和计算机科学家密切合作,以了解技术的可能性和局限性。
王说,电动轮椅的一个常见问题是,对于有身体和/或认知障碍的人来说,它们很难控制;因为它们是电动的,它们也可能比手动轮椅更危险,尤其是对那些健康状况已经很脆弱的人来说——这也是一些养老院完全禁止使用电动轮椅的原因之一。此外还有伦理方面的问题:“一旦你给了某人一个电动轮椅,你就很难把它从他那里拿走。我们希望实现移动性,我们希望保护人们的安全,我们希望以尊重客户的方式来做到这一点,”王说。
王还指出,仅仅拥有在特定条件下可以工作的技术并不意味着它会在实践中被采用;技术本身之外的许多环境因素会成为障碍。例如,大多数跌倒检测监控服务倾向于使用基于订阅的商业模式,类似于家庭监控。但王发现,许多客户更喜欢让他们的个人护理监控服务触发对家庭成员的警告呼叫,而不是呼叫中心——即使这种解决方案不太可能被行业合作伙伴采用。“在设计系统时,你必须着眼于全局。客户觉得干扰呼叫中心是一种耻辱。”
将技术开发成可以实际部署到现实世界场景中的系统和产品是一项挑战,了解客户的个人偏好、他们的身体和认知能力以及背景因素(如养老院架构、常规和法规、家庭和护理人员需求、道德等)非常重要。这就是为什么 IATSL 研究的一个关键部分也是为在疗养院和家中应用智能辅助技术开发框架、指南和方法。
Rosalie Wang speaks about her career path from Occupational Therapist to rehab robotics researcher at the Women in Robotics lecture series, hosted by Get Your Bot On and Women Engineers TO in Toronto, Canada. Photo via Nicole Proulx.
对于王来说,在机器人和人工智能领域担任职业治疗师的好处是双向的:她可以以用户为中心的视角来设计技术,但“机器人和人工智能也可以帮助加强职业治疗师的工作,推动整个领域的发展,”她说。王的研究还包括临床评估上肢中风康复机器人和帮助老年痴呆症患者的辅助机器人。她上个月刚刚发表的最新论文调查了患有阿尔茨海默氏症的老年人和他们的护理人员对使用机器人帮助他们完成家庭任务的感受,这是少数几项对该问题进行深入研究的研究之一。
从职业治疗师的角度来看,使用机器人和人工智能的一个关键好处是,它可以为循证治疗提供数据。“过去,我们只能通过非常粗略的快照来衡量治疗效果……客户要么可以完成一项任务,要么无法完成。这种反馈可能会使客户非常沮丧,并使治疗师更难察觉和记录进展中的微小变化……现在我们可以收集连续的数据,这让我们可以设计更完善的治疗,并让客户对进展有更好的感觉。治疗机器人可以给你连续的临床数据,即使你无法感知。”
当被问及是否想过有一天会从事机器人领域的工作时,王给出了一个响亮的答案:“不会。”她也不愿意将自己描述为机器人专家。尽管如此,鉴于智能辅助技术和系统实验室正在开展的广泛的项目,很明显,需要一个拥有各种专业知识的跨学科团队来将机器人和人工智能转化为实际的医疗保健解决方案。
IATSL 团队成员的背景包括职业治疗、神经科学、工业设计、生物学、临床心理学、实验心理学、康复科学和护理。
数据中的故事:伙计们,表演时间到了!
原文:https://towardsdatascience.com/its-showtime-folks-d9fd274810c8?source=collection_archive---------10-----------------------
想到电影你会想到什么?关于故事情节、人物、对话、美丽的人和激动人心的地点?我也是。但由于沉浸在我碰巧从事的职业中,我也想到了那些不太明显的故事,那些关于电影业务的丰富数据可以揭示的故事,那些与电影院大厅内发生的事情一样引人入胜的故事!
在之前的 帖子 中,我谈到了数据分析本质上是一门艺术(是的,我知道,这也涉及到许多科学和技术),即发现并讲述隐藏在数据中的故事。为了说明我的意思,我想举一个恰当的例子。因为我碰巧是一个狂热的电影爱好者,有什么比电影院更好的地方开始。
序幕
在我开始之前,分享一些关于我所使用的数据和我所采取的广泛方法的初步笔记是很重要的。关于电影有相当数量的可用数据(我这里指的是免费提供的数据),但是其中很多都不是很全面。我挑选了两个数据集,都可以在 StatCrunch(一个现在由 Pearson 拥有的统计分析工具)上找到。
- 第一个数据集是从 IMDB 电影数据库创建的。它包括自 1920 年以来制作的大约 58,000 部电影。它有关于电影的基本信息,如名称,发行年份,类型,电影长度等。,以及一些客户评级信息(主要是投票数和平均。评级)。
- 第二个数据集包括近几十年来制作的大约 4,500 部电影,其中包含电影何时上映、制作成本以及票房收入等信息。
为了像一个真正的分析项目那样做,我还将列举一些分析的局限性:
- 如上所述,这些数据集不是完整的,而是样本。因此,它们可能存在一定的采样偏差。
- 在进行任何分析之前,我所做的数据清理仅限于删除重复记录和缺少关键数据字段的记录。当然,还可以做更多的事情来提高数据完整性,但是对于我的目的来说,这已经足够了。
- 最后,请记住,本练习的目的是从较高的层面说明数据如何讲述有力的故事。所以,如果你想用这个来计划你的下一部大片,那么你要自担风险!
说完这些,让我们直接进入我们的故事。所以坐好,嚼点爆米花,想象一下…
第 1 章:设定
(i) 电影数量:曾几何时,准确地说是回到 20 世纪 20 年代,制作的电影屈指可数。随着技术的飞跃(如 20 世纪 20 年代中期有声电影的引入)和电影作为一种有吸引力的经济主张的出现,这种情况迅速发生了变化。在过去的 80 年里,每年制作的电影数量几乎增长了 25 到 30 倍。
(二) 类型:围绕电影的类型或类型也出现了有趣的趋势。例如,在电影制作的最初几十年,几乎没有任何动作电影被制作,而自 20 世纪 70 年代以来,动作电影的数量一直在稳步增长,这是以所有其他类型的电影为代价的。另一个有趣的现象是 20 世纪 30 年代和 40 年代喜剧电影的兴起。这是世界经历最艰难的时期(大萧条,第二次世界大战)。尽管这似乎有悖常理,但它符合一个众所周知的事实,即在大萧条最糟糕的几年里,当失业率达到创纪录高位时,数百万人仍然涌向剧院,可能是为了逃避现实。
(iii) 电影长度:动作片在作为最长的电影类型开始后,已经在 90 分钟的甜蜜点上安顿下来。戏剧和爱情也是如此。一般来说,喜剧通常要短一点。电影的长度随着时间的推移而演变,通常从较短开始,随着时间的推移而增加,最后逐渐减少到今天的长度。
在大约 58,000 部电影中,只有 245 部(即 0.4%)超过了 200 分钟(即 3 小时 20 分钟,换句话说,loooong!).这种长电影的频率一直在稳步下降,其中很多是非英语电影。
Image 1: Distribution over time of movie length by genre (# of Minutes)
第二章:给我钱!
就像一个好的故事在搭建好舞台后会变得更有趣一样,我们在这里也会这样做。还有比金钱话题更有趣的,所以让我们直接开始吧。(注意:这种特殊的分析是基于约 4500 部电影的较小样本数据集,其中成本和收入数据是可用的)。
预算:制作一部电影的费用一直在稳步增长。这当然是意料之中的——毕竟,做任何事情所需要的钱都在增加(这叫做通货膨胀,废话!).然而,它仍然是有趣的,因为这种增长已经远远超过了仅仅由通货膨胀所能解释的。其他可能导致这种情况的因素包括更大的技术游戏、名人文化(即大人物的高薪)、从工作室/布景拍摄到现实生活场景的范式转变等。
Image 2: Scatter chart for movie budgets over time (in USD Millions)
如果你像我一样好奇的话,右上角的那个点就是《阿凡达》(2009 年,预算 4.25 亿美元)。紧随其后的是几部大预算电影,如《星球大战》Ep。VII:《原力觉醒》(2015 年,3.06 亿美元预算)、《加勒比海盗:在世界的尽头》(2007 年,3 亿美元预算)和《幽灵党》(2015 年,3 亿美元预算)。
毫不奇怪,如果我们在预算中应用一个类型过滤器,最惊人的增长是动作和动画电影。
(ii) Returns :先不说成本,现在让我们来谈谈收入。让我写下数据揭示的一些重要信息:
- 在现有的数据集中,有 281 部电影取得了超正常的回报(即大于 1000%)。其中 242 部(86%)是在不到 2000 万美元的低预算下制作的。唯一一部有如此回报的大预算电影是《泰坦尼克号》(预算:2 亿美元,全球总票房:22 亿美元;1004%的回报)。
- 另有 384 部电影取得了非常高的收益(在 500%到 1000%之间)。许多大预算电影都落在这个桶里,例如八部哈利波特电影中的七部,阿凡达,侏罗纪公园,复仇者联盟,冰雪奇缘,星球大战 Ep VII,四部饥饿游戏电影中的两部等。
- 很大一部分人(几乎三分之一)在海外收藏中赚的钱比美国国内收藏多。175 部电影海外票房是国内票房的 10 倍以上。
这里有一个奖励——历史上获得最大回报的电影是 1972 年的《深喉》(惊喜!).制作预算为 25,000 美元,据说其全球收藏约为。4500 万美元(有人估计甚至更多)——这是 179,900%的回报率。这意味着,如果你在这部电影的制作中投资 1000 美元,你会从中赚到 180 万美元——客观地说,这比你在苹果公司刚上市时投资苹果股票的回报要高得多!
关于回报的话题,另一个有趣的观察是关于时机。即使在 5 月和 12 月等几个月,看电影的总支出较高,但 6 月的回报最高,明显高于其他月份。这是因为低预算电影在 6 月上映还是因为它们更成功,这需要进一步的探索,我还没有做过。无论如何,对你来说,最重要的当然是在六月上映你一直想看的电影!
Image 3: Average %age Return by Month
(三) 一败涂地:既然我们已经谈论了电影业务的成本和回报,那么我们来仔细看看那些没有真正抓住观众兴趣或金钱的电影怎么样。
- 破产电影的总损失高达 150 亿美元(仅在我们的小样本数据中)。
- 榜单中最大的输家是耗资 2.75 亿美元的《独行侠》(2013)。它勉强收回成本。这个故事的寓意——约翰尼·德普不是所有问题的答案(尽管,如果我们完全诚实的话,通常他肯定是!)
- 1980 年后,赔钱的电影数量显著增加。显然,对此的简单解释是,正在制作的电影总数本身显著增加。
- 数据显示,随着电影上映日期向月末移动,失败电影的分布要高得多,超过 40%的失败电影在当月 21 日至 31 日之间上映。
第三章:只有文字……
数据分析最有趣的方面之一是对非结构化文本数据的分析。使用各种技术来实现这一点,包括复杂的自然语言处理(NLP)元素。不过,为了我今天故事的目的,我坚持一些相对简单的分析,希望能展示单词调查的力量。
(一) 文本元素:对电影名字的基本参数的研究揭示了一些好奇的事情。让我们来看看:
- 电影名字开头最常见的字母是 T 。它远远高于其他字母,这要感谢所有以“the”开头的电影。不过 T 之后最常见的字母依次是SMB和 A 。
- 如果电影名称以 Z 开头,则电影翻牌的概率最高。在我们的数据集中,以字母 Z 开头的电影有 40%失败了,而整个数据集中的失败率为 27%。
- 另一方面,如果电影名称以 X , N , Q 或一个数字开头(最后数据支持命理学!).一些例子——大人物拿破仑(2004 年,11,431%的回报率)、诺丁山(1999 年,766%的回报率)、老无所依(2007 年,556%的回报率)、四重奏(2012 年,411%的回报率)、x 战警(2000 年,295%的回报率)、xXx (2002 年,282%的回报率)等。
- 电影标题的字数和获得高回报的概率之间似乎存在直接的关联。
Image 4: %age of movies with greater than 100% return on budget by # of words in movie title
例如,在我们的数据集中,75%的片名为 10 个单词的电影都非常成功。以下是一些名字:
- 《指环王:王者归来》(1114%)
- 《指环王:魔戒相交》(714%)
- 加勒比海盗:黑珍珠号的诅咒(408%)
- 亚历山大和可怕的,可怕的,不好的,非常糟糕的一天(262%)
- 忍者神龟 2:软泥的秘密(215%)
- 纳尼亚传奇:黎明踏浪号的航行(170%)
(ii)****有一种 NLP 技术叫做 【单词袋】 。不严格地说,单词包模型将对文本字段中不同单词的出现次数进行数字计数,以便从中进行推断。我在我们的数据集上做了一个粗略的版本,就像任何文本分析通常的情况一样,即使是这个简单的探索也揭示了一些有趣的事情。
- 如果你忽略了一些常用词(如‘The’,‘A’,‘An’,‘In’,‘To’等)。),在电影片名中出现次数最多的词是——lo and look——‘Man’。** 谈生活在男权社会!不仅如此,这也是一个好词,因为几乎 70%的以“男人”为片名的电影都赚了大钱。**
- 另一方面,很少(很多很多)电影在标题中有 【女人】 这个词。对于阅读这篇文章的女性来说,唯一的安慰是,几乎所有这些都带来了极高的回报。
- 其他非常常见的词还有 【电影】【爱情】【最后】【天】【死亡】 等等。
- 标题中的颜色名称做得很好,尤其是‘黑色’。****
- 所有片名中有日名的电影都做得极其好(> 100%回头率),尤其是‘星期五’。****
后记:
总之,如果你打算拍一部电影,请记住这些提示,所有这些都深深扎根于实际数据中,因此纯粹从概率上来说,会给你更高的成功机会:
用相对较低的预算制作一部电影(< $20 Million), release it in the first part of June, make sure the movie name starts with an N, X or Q. Put in 10 or more words in the title and include the words MAN, BLACK and FRIDAY for some additional magic. (And then don’t forget to come and tell me how it went — if you are making a hit movie, I’m pretty sure I want to know you!)
End Note:我要重申,对于任何可能已经结束在这里,并可能在这一点上沸腾和愤怒的纯粹主义者,我在这里的意图主要是展示分析的深度和各种各样的见解,当一个人开始涉足数据世界时,这些都是可能的。在这里,我仅仅触及了表面,而且是在有限的数据集上——随着更多的数据、更多的时间和更复杂的科学,更多的事情是可能的。
如果你对电影行业有一些有趣的数据支持的见解,我很想听听你的看法。请在评论中告诉我。
一月版:自动驾驶汽车
原文:https://towardsdatascience.com/january-edition-self-driving-cars-ab4e59fbd7b5?source=collection_archive---------7-----------------------
10 篇必读文章
了解 SSD 多盒子——深度学习中的实时对象检测
由埃迪·弗森 — 11 分钟阅读。
自从 AlexNet 在 2012 ImageNet 大规模视觉识别挑战赛(ILSVRC)上席卷研究界以来,深度学习已经成为图像识别任务的首选方法,远远超过了文献中使用的更传统的计算机视觉方法。
自动驾驶汽车,自…赛格威以来最受关注的东西?
由郭晓非 — 8 分钟读完。
有了这样的头条新闻,很难不为自主和自动驾驶汽车感到兴奋。毕竟,我们看过《少数派报告》、《全面召回》和《iRobot》中的汽车,并对自己说:“我们什么时候才能最终进入那些汽车?”
车辆检测与跟踪
由伊万·卡萨科夫 — 7 分钟读完。
这是 Udacity 的自动驾驶汽车工程师纳米学位项目 第一学期的最终项目。源代码和技术上更详细的文章可以在 GitHub 获得
深度学习的车道检测
迈克尔处女座 9 分钟阅读。
即使在各种各样的条件下,人们也可以相当容易地找到道路上的车道线。除非有雪覆盖地面,降雨量非常大,道路非常脏或年久失修,我们可以告诉我们应该去哪里,假设这些线实际上是有标记的。
为高速公路上的自动驾驶汽车规划路径
由 Priya Dwivedi — 6 分钟阅读。
路径规划是自动驾驶汽车的大脑。这个模块试图复制我们人类在驾驶时的思维和决策——阅读地图,分析我们的环境(其他车辆和行人),并根据安全、速度和交通规则决定最佳行动。
ConvNets 系列。空间变压器网络
到 Kirill Danilyuk — 11 分钟读完。
空间转换器是不同模块集合中的另一个乐高积木。它通过应用可学习的仿射变换然后进行插值来消除图像的空间不变性。
车辆检测与跟踪:Udacity 的自动驾驶汽车 Nanodegree
由 Dhanoop Karunakaran — 10 分钟读取。
在自动驾驶技术中,车辆检测和跟踪对于汽车的安全行驶至关重要。在这个项目中,目标是编写一个软件管道来检测视频中的车辆。
如何训练你的自动驾驶汽车转向
由诺曼迪帕洛 — 5 分钟阅读。
神经网络,特别是深度学习研究,最近在计算机视觉领域和计算机科学的其他重要领域取得了许多突破。
机器人也错了——最坏情况下的混乱映射
由克里斯·巴特勒 — 8 分钟读出。
上一次计算器不按你的意愿工作是什么时候?一个人最后一次这样做是什么时候?从确定性的角度来看,像机器学习这样的算法介于这两者之间。
用 Tensorflow 对象检测 API 构建玩具检测器
由 Priya Dwivedi — 5 分钟阅读。
这个项目是我的热门项目的第二阶段-Google tensor flow 对象检测 API 是实现图像识别最简单的方法吗?在最初的文章中,我使用 Tensorflow 提供的模型来检测 youtube 视频中的常见对象。
我们也感谢最近加入我们的所有伟大的新作家, Chuong Do , Savina van der Straten ,马可·布拉姆贝拉, Christopher Gill , Aravind Srinivasan , Max Lawnboy , Simeon Kostadinov , An Luong , Ethan Arsht , Danny 纳希德·阿拉姆、哈默尔·侯赛因、铃木健太、詹妮弗·马利、本·谢弗、鲍里斯·斯莫斯、埃利斯·布朗、萨加尔·豪瓦尔、乔希·亚兹曼、因德拉·登·巴克等等。 我们邀请你看看他们的简介,看看他们的工作。
Javascript- Currying VS 部分应用程序
原文:https://towardsdatascience.com/javascript-currying-vs-partial-application-4db5b2442be8?source=collection_archive---------0-----------------------
许多人在涂抹和部分涂抹之间感到困惑,我们中的许多人不知道应该在何时何地使用它们。所以这篇文章将涵盖它们的实际用法和区别。
所以让我们从定义开始。
Currying
Photo by Caroline Attwood on Unsplash
是一种将带有 N 个参数的函数调用转换成 N 个函数调用链的技术,每个函数调用只有一个参数?
Currying 总是返回另一个只有一个参数的函数,直到所有的参数都被应用。所以,我们一直调用返回的函数,直到我们用尽了所有的参数,最终的值被返回。
// Normal function
function addition(x, y) {
return x + y;
}// Curried function
function addition(x) {
return function(y) {
return x + y;
}
}
注意:Curry 取二元函数,返回一元函数,返回一元函数。它的 JavaScript 代码是
function curry(f) {
return function(x) {
return function(y) {
return f(x, y);
}
}
}
注意:一个 curried 函数有一个内置的迭代器行为。一次应用一个参数,然后返回给调用函数,用于下一步。在这里阅读关于迭代器的。
习惯
- 定制函数的常见用例是函数组合,例如
p(x) = q(r(x))
。即通过传递参数从旧函数构建新函数。函数q
将返回值作为函数r
的参数。因为函数只能返回一个值,所以应用于返回值的函数必须是一元的。 - Curried function 也可以在项目的基础设施设置时使用,在该项目中,有许多可能性来创建通用函数,从而可以轻松地配置和重用小部分,而不会出现混乱。
- Ramda.js lib。函数是自动执行的,lodash 有一个名为 curry 的函数,可用于形成 curry 函数。
- 记忆化 是 curry 函数的另一个好用例。
- 处理错误出错后立即抛出函数并退出。
- 捕捉多个错误,并将其用作 API 和客户端代码的验证器。
- 可以创建第一类函数,这意味着我们可以使用函数作为参数和返回值。例如:
const func1 = () => console.log ('Hey Medium.');
const firstClassfunc1 = argsFunc => argsFunc();
const firstClassfunc2 = () => func1;
firstClassfunc1 (firstClassfunc2()); // Hey Medium.
注意:一定要看完这个视频,你会知道更多关于为什么,什么时候和用法。
咖喱工厂法(ES6)
const **compose** = (...**fns**) =>
**fns.reduce**((**f**, **g**) => (...**args**) => **f**(**g**(...**args**)));
这里的是一篇关于如何使用 ES5 创建我们自己的 curry 函数工厂方法的好文章。
注意:如果处理不当,Javascript 中的 Currying 会导致更复杂的堆栈跟踪,这对调试是不利的。
局部应用
是一种将多个参数固定到一个函数上,产生另一个更小参数的函数的技术,即随着函数链的发展,将值绑定到一个或多个参数上。
function add1(x) {
return 1 + x;
}
JavaScript 有内置的方法.bind
,它可以处理任意数量的参数,并且可以绑定任意数量的参数。它的调用具有以下语法。
*function*.bind(*thisValue*, [*arg1*], [*arg2*], ...)
它将函数变成一个新函数,它的隐式参数是这个值,并且它的初始参数总是给定的。
function addition(x, y) {
return x + y;
}const plus5 = addition.bind(null, 5)
plus5(10) // output -> 15
注意:
this
值对于(非方法)函数加法无关紧要,这就是为什么它在上面是 null 的原因。
当使用下划线或 lodash 时,你可以使用部分函数,它比原始的绑定方法好得多。
这里是关于局部应用和左、右局部应用功能实现的详细帖子。
差异
- Currying always 产生嵌套的一元(1 元)函数。转换后的函数在很大程度上仍与原始函数相同。
- 部分应用产生任意数量参数的函数。转换后的函数不同于原始函数,它需要的参数更少。
- Currying 不是局部应用。它可以使用部分应用程序来实现。你不能创建一个接受任意数量参数的函数,(除非你固定参数的数量)。
优势
更容易重用更抽象的函数,从而产生干净的代码,降低复杂性,提高代码的表达能力和可维护性。
这篇文章的一些资源
[## 库里还是局部申请?
部分应用和咖喱的区别
medium.com](https://medium.com/javascript-scene/curry-or-partial-application-8150044c78b8) [## Currying 与部分应用程序(使用 JavaScript 代码)
Currying 和局部应用是将一个功能转换为另一个功能的两种方式,通常具有更小的…
2ality.com](https://2ality.com/2011/09/currying-vs-part-eval.html) [## 咖喱与功能组合
注意:这是学习函数式编程和组合软件的“组合软件”系列的一部分…
medium.com](https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983)
如果您想被添加到我的电子邮件列表中,请考虑在这里输入您的电子邮件地址 和关注我的 medium 阅读更多关于 javascript 的文章,并关注github查看我的疯狂代码。如果有什么不清楚或者你想指出什么,请在下面评论。
你可能也会喜欢我的其他文章
- Javascript 执行上下文和提升
- Javascript —生成器-产出/下一个&异步-等待🤔
- 理解 Javascript‘this’关键字(上下文)。
- Javascript 数据结构与映射、归约、过滤
- Javascript- Currying VS 部分应用
- Javascript ES6 —可迭代程序和迭代器
- Javascript —代理
- Javascript —作用域
如果你喜欢这篇文章,请随意分享,以帮助他人找到它!
谢谢!
Javascript ES6 —可迭代程序和迭代器
原文:https://towardsdatascience.com/javascript-es6-iterables-and-iterators-de18b54f4d4?source=collection_archive---------5-----------------------
Photo by Samuel Zeller on Unsplash
可重复的
iterable 是一个接口,它指定如果一个对象实现了一个关键的方法,那么这个对象就是可访问的。
使用 iterable 的一些内置数据结构有:
- 数组
- 用线串
- 地图
- 集合等。
为什么在 ES6 中增加了 iterable?
如果没有 iterable,就很难管理各种类型数据结构的数据迭代,即数组迭代不同于对象迭代。
此外,ES6 引入了新的数据结构,如集合和映射,因此按照迭代的数据结构编写逻辑将变得更加复杂。
这就是 iterable 接口诞生的地方。
这里有两件事需要注意
- 数据消费者— 迭代如何发生,如使用循环、扩展操作符、array.from 方法、通过数组模式进行析构等
- 数据源 —我们选择什么样的数据结构,比如数组、映射、字符串等等来迭代。
迭代器
对象,该对象知道如何一次访问集合中的一个项,同时跟踪它在该序列中的当前位置。
iterable 接口返回的对象也是迭代器对象。
迭代器对象有一个返回序列中下一个项目的next()
方法。该方法返回一个具有两个属性的对象:done
和value
,当next()
调用到达序列末尾时,将done
属性设置为true
,否则保持false
。
所以迭代器的下一个返回:
{value:'迭代的当前值',done:'真/假' }
现在,既然我们清楚了这个理论,让我们来看一些例子
简单数组示例
Array iterator
这里,我们有一个带有一些值的数组arr
,然后我们创建了一个迭代器对象,我们可以在上面调用next()
,直到我们调用了true
注意:数组中已经有符号.迭代器键作为函数,在上面的例子中,符号.迭代器代表
*iter*
对象的属性,当我们调用它时,构造一个迭代器实例,通过 next 使用该对象的值。
我们可以创建自己的 iterable 和 iterator 对象,让我们看一个例子。
自定义迭代器对象示例
注意:要在上面运行,我们将使用 for..的循环,你可以阅读这里了解更多细节。
这就是我们如何迭代我们的 customIterable 对象。
for (const x of customIterable) {
console.log(x);
}
// output 1,2,3,4,5,undefined
代码执行五个步骤,每次运行时counter
递增。首先,我们返回值1
,然后是值2
等等,直到5
,然后我们指示已经到达迭代的末尾,并且返回值undefined
。每个项目都包装在一个具有以下属性的对象中:
value
保存实际项目和done
这是一个布尔标志,指示是否已经到达终点。
注意:如果需要,最后一步可以返回值,我们也可以手动中断..如果需要,使用 break 关键字。break 关键字将向迭代器发送一个信号,表明消费代码已完成,不会再从中提取任何值,因此无论如何都会调用它。一旦我们完成迭代,它将返回{done:true},但我们也可以手动调用它。
带生成器的迭代器功能强大,可能会改变我们编写代码的方式。
如果您想加入我的电子邮件列表,请考虑在这里输入您的电子邮件地址 和关注我在medium阅读更多关于 javascript 的文章,并在github上查看我的疯狂代码。如果有什么不清楚或者你想指出什么,请在下面评论。
你可能也会喜欢我的其他文章
- Javascript 执行上下文和提升
- Javascript —生成器-产出/下一个&异步-等待🤔
- 理解 Javascript‘this’关键字(上下文)。
- Javascript 数据结构与映射、归约、过滤
- Javascript- Currying VS 部分应用
- Javascript —代理, Javascript —作用域
如果这篇文章有帮助,请随意分享并帮助他人找到它!
谢谢你!
Javascript 性能测试——针对每个 vs 的 vs(映射、归约、过滤、查找)。
原文:https://towardsdatascience.com/javascript-performance-test-for-vs-for-each-vs-map-reduce-filter-find-32c1113f19d7?source=collection_archive---------1-----------------------
Photo by Alex Holyoake on Unsplash
我们都知道 for 循环比 each 或 javascript 函数要快,因为在 javascript 函数的掩护下,可能会使用 for 循环或其他我不确定的东西。我用一组对象做了一个简单的测试,通过 for 循环 / for each / javascript 函数做了一些操作,并观察了执行所花费的时间。
这些结果来自小的例子,并且可能根据所执行的操作、执行环境的选择而变化。和虚拟机的选择。
1.减少 for 循环 vs foreach 的 vs
// calculated the sum of upVotes
const posts = [
{id: 1, upVotes: 2},
{id: 2, upVotes: 18},
{id: 3, upVotes: 1},
{id: 4, upVotes: 30},
{id: 5, upVotes: 50}
];let sum = 0;
console.time('reduce');
sum = posts.reduce((s, p)=> s+=p.upVotes,0);
console.timeEnd('reduce')sum = 0;
console.time('for loop');
for(let i=0; i<posts.length; i++) {
sum += posts[i].upVotes;
}
console.timeEnd('for loop');sum = 0;
console.time('for each');
posts.forEach(element => {
sum += element.upVotes;
});console.timeEnd('for each');
注:下面是结果列表,代码可以在 这里找到 。
所有的结果都清楚地表明 对于循环比对于每一个都更精通于映射/归约/过滤/查找。
映射/减少/过滤/查找速度慢有很多原因,其中一些原因是
- 他们有一个回调来执行,所以这是一个开销。
- javascript 函数会考虑很多极端情况,比如 getters、稀疏数组以及检查传递的参数是否是数组,这些都会增加开销。
我找到了一个lib。它重新实现了几个常见的内置原生 JavaScript 函数。
但是使用方式的选择不仅仅取决于性能,还需要考虑更多因素,其中包括:
- 代码可读性和可维护性
- 轻松代码
- 快速编码
- 实施与优化
- 个人选择
就我个人而言,我喜欢地图,减少,过滤,查找,并且我已经用了很长时间了。他们帮助我写出干净、精确、快速且切中要点的代码,这些代码符合我的思维过程。当我别无选择时,我使用 for 循环。
就优化而言,映射/减少/过滤/查找替换应该是最后一个选项,或者不是一个选项,这取决于所需的优化级别。
注意:如果你正在使用循环,总是习惯性地使用它们,因为编译器现在足够聪明来正确地优化习惯性循环
更新:在这里你可以找到大数据集和繁重计算的结果。
我写了一些关于overflowjs.com的文章,这篇文章的第 2 部分比较了 ramada 内联缓存热缓存和一些 GC 的东西。所以,别忘了继续关注 overflowjs.com 的
如果您想加入我的电子邮件列表,请考虑在此输入您的电子邮件地址****关注我在medium上阅读更多关于 javascript 的文章,并在github上查看我的疯狂代码。如果有什么不清楚或者你想指出什么,请在下面评论。
- Javascript 执行上下文和提升
- Javascript-生成器-产出/下一个&异步-等待🤔
- 理解 Javascript 'this '关键字(上下文)。
- Javascript 数据结构与映射、归约、过滤
- Javascript- Currying VS 部分应用
- Javascript ES6 —可迭代程序和迭代器
- Javascript 性能测试—针对 vs 针对每个 vs (map,reduce,filter,find)。
- Javascript —代理
- Javascript —作用域
- 用 Tensorflow-js 进行图像目标检测🤔
- Nodejs 应用程序结构——构建高度可扩展的架构。
- Node.js 10.0.0,作为后端开发人员/安全爱好者有什么期待?
- 图像处理——在 React.js 中制作自定义图像滤镜
- 谷歌印度面试问题
谢谢!
招聘启事——一个谜…
原文:https://towardsdatascience.com/job-postings-a-riddle-86f77ac610d5?source=collection_archive---------8-----------------------
上周,我深入探讨了为什么你应该广撒网来获得你的第一份数据科学工作。职称可能会非常误导人,数据科学不仅对不同的组织意味着不同的东西,甚至在同一组织内也是如此!
It’s easy to get lost in a sea of applications…
让我用来自同一家 公司的三个不同头衔的神秘职位的要求来说明。
所有这些位置看起来都很相似,是吗?
他们是,在需求和责任上有非常细微的差别。
两个 我这里要提的主要观点:
- 即使在同一个组织中,不同头衔的职位所服务的功能也非常相似。这类似于一家公司的地质学家或地球物理学家是另一家公司的地球科学家。
- 作为地球科学家,我们根据以往在石油和天然气行业的经验来满足大部分要求。请注意,我在每个工作描述中都增加了重点。这就是我认为,作为地球科学家,我们可以利用我们的经验,以独特的方式满足这些要求。
在这些要求中,几乎所有处于职业生涯中期的地球科学家都符合其中的大部分要求。主要的例外是必须增强编码技能(见第 2 集我是如何做到这一点的)。
首选需求是大多数企业称为“最好拥有”的需求的大杂烩。然而,我们仍然满足了这些要求中的许多,如果不是大部分的话。
我不会详细讨论如何解决每个问题。不过,我还是从自己的经历来举个例子。
将这一要求放在第一个位置:
体验 数据可视化和呈现,将复杂的分析转变为洞察力
对我来说,解释价值的创造性方法是:
“成功地与使用数据可视化的工程师合作,并整合了各种学科的见解,以优化井眼轨迹目标。”
这只是许多例子中的一个,但是让你感受一下地球科学家如何满足这些要求。
求职者的一个常见错误是认为他们必须“检查”所有的要求。许多雇主复制/粘贴招聘信息的要求,而招聘信息似乎要求所有的东西和厨房水槽。
不要陷入只申请那些你能满足 90-100%要求的工作的陷阱。申请任何听起来有趣的职位,你会很适合。如何确定呢?这是一个滑动比例。我申请的工作中,我巧妙地满足了 50%的要求,这让我觉得很有趣。有时它会导致自动拒绝,但正如韦恩·格雷兹基的名言,“你错过了 100%你不拍的镜头。”
今天有了复杂的算法(耶,数据科学),我们的简历经常会因为我们“非传统”的背景而被过滤掉。
随着创造性地改写简历,以登陆石油和天然气之外的世界,希望它会给一个开明的招聘人员足够的时间停下来给你打电话。
不过,冷冰冰地发送简历总是存在风险。有推荐人的人比没有推荐人的人更有可能接到招聘人员的筛选电话。虽然冷启动时有人跟注并非不可能,但你正在打一场硬仗。
这是我再次敦促的地方,网络!许多公司提供推荐项目(亚马逊、脸书、谷歌等)。结识他人,重新联系高中、大学等学校的朋友。让你的名字在那里!
那些没有很好的 Meetup 场景或者已经建立的联系较少的人呢?
LinkedIn 是一个很好的来源。与和你有相似目标或相似职位的人交往。给他们发一封电子邮件(是的,你需要保险费,但我发现它真的很有用,很值得)。邀请他们喝杯咖啡,聊聊职业生涯。我在 LinkedIn 上遇到了一些非常可爱的人,无论是在求职方面还是在顾问方面。
这一系列的下一步将是关于面试过程。我们中的许多人在同一个行业工作多年,对面试技巧生疏了。我将介绍数据科学中的典型流程,以及如何为预期做好充分准备。这是一个与石油和天然气行业不同的行业,知道会发生什么是成功的一半!
对于那些走到这一步的人…
今天谜题的答案是:
职位#1 — 数据科学家
职位#2 — 业务数据分析师
职位#3 — 商业智能工程师
公司——每个人都知道并喜爱的大公司…
这是记录和分享我从地球科学职业转向数据科学的故事系列的第 4 集。如果你是新人,可以在这里补上:为什么地球科学家造就伟大的数据科学家、强化技能、取景狩猎。
继续前进到面试流程、我为什么选择咨询、我的第一个咨询项目和行动号召。
python 和 NLTK 中的职称分析
原文:https://towardsdatascience.com/job-title-analysis-in-python-and-nltk-8c7ba4fe4ec6?source=collection_archive---------2-----------------------
Photo by Scott Graham on Unsplash
职称表明了一个人的角色和职责。它说如果他们管理一个团队,如果他们控制预算,和他们的专业化水平。
了解这一点在自动化业务开发或客户拓展时非常有用。例如,一家销售语音识别软件的公司可能希望将消息发送给:
- CTO 和技术主管告知他们使用语音识别软件的价格和好处。
- 潜在投资者或顾问邀请他们了解公司潜在市场规模的信息。
- 创始人和工程师指导他们如何使用软件。
训练一个软件对职称进行分类是一个多文本的文本分类问题。对于这个任务,我们可以使用 Python 自然语言工具包(NLTK)和贝叶斯分类。
概念化
首先,让我们概念化一下职称代表什么。对于某个部门,每项工作都有一级职责。
职责包括清洁地板等维护任务,团队领导等管理任务,或决定预算等战略任务。
部门包括基于增长的部门,如业务开发和营销部门,基于合规的部门,如财务和法律部门,或基于执行的部门,如产品开发和运营部门。
职责和部门被编码成许多职称,如下所示:
我们希望将每个工作描述归入这些职责和部门中的一个。
执行
数据采集
第一步是得到一份职位列表。在 CareerBuilder 上有一个大约 800 个职位的列表。
职位名称是有页码的,所以唯一的方法就是点击每一页。
培训数据创建
导入职位名称后,我们可以描述这些职位的职责和部门。
数据格式编排
对于这个项目,我们需要自然语言工具包 (NLTK)。它包含文本处理资源、机器学习工具等等。
我们将使用贝叶斯多类分类器和自然语言工具包对这些职位进行分类。
像这样导入 NLTK:
import re
import nltk
from nltk.corpus import stopwords
import pandas as pd
stop_words = set(stopwords.words('english'))
停用词是常见的词,如 a 、和、 the ,这些词对我们的职称没有什么意义。NLTK 提供了一个英语停用词列表,我们将从每个职位中过滤掉。
当我们在网上获取职位头衔时,例如从 LinkedIn 或会议上,他们有时会包含多个职位头衔,用逗号、破折号、冒号或其他字符分隔。为简单起见,我将展示如何提取第一个职位:
def get_first_title(title):
# keep "co-founder, co-ceo, etc"
title = re.sub(r"[Cc]o[\-\ ]","", title)
split_titles = re.split(r"\,|\-|\||\&|\:|\/|and", title)
return split_titles[0].strip()
贝叶斯分类器将需要一个特征列表——在这种情况下,哪个单词出现在哪个职位描述中。我还把第一个词和最后一个词加到了特写中,因为有时候第一个词或最后一个词对职位有重要意义。例如,营销总监和营销总监是不同的角色。
def get_title_features(title):
features = {}
word_tokens = nltk.word_tokenize(title)
filtered_words = [w for w in word_tokens if not w in stop_words]
for word in filtered_words:
features['contains({})'.format(word.lower())] = True
if len(filtered_words) > 0:
first_key = 'first({})'.format(filtered_words[0].lower())
last_key = 'last({})'.format(filtered_words[-1].lower())
features[first_key] = True
features[last_key] = True
return features
这将产生一个职位名称的单词列表,包括第一个和最后一个单词,例如职位名称,全球运营总监:
{
"contains(director)": True,
"contains(global)": True,
"contains(operations)": True,
"first(director)": True,
"last(operations)": True
}
现在我们需要为分类器清理和准备职位、职责和部门的列表。
假设我们的原始职位数据格式如下:
raw_job_titles = [
{
"title": "Business Development",
"responsibility": "Strategy",
"department": "Business Development"
},
{
"title": "Inside Sales Consultant",
"responsibility": "Execution",
"department": "Sales"
},
...
]
分类器训练
接下来,我们可以在这些数据集上训练贝叶斯分类器。我们通过对每个职位的特征进行分类来做到这一点。
# Responsibilities
responsibilities_features = [
(
get_title_features(job_title["title"]),
job_title["responsibility"]
)
for job_title in raw_job_titles
if job_title["responsibility"] is not None
]# Departments
departments_features = [
(
get_title_features(job_title["title"]),
job_title["department"]
)
for job_title in raw_job_titles
if job_title["department"] is not None
]
我们可以分割特征,以便我们可以使用一些特征来训练分类器,并使用其余的特征来测试分类器。
# Responsibilities
r_size = int(len(responsibilities_features) * 0.5)
r_train_set = responsibilities_features[r_size:]
r_test_set = responsibilities_features[:r_size]
responsibilities_classifier = nltk.NaiveBayesClassifier.train(
r_train_set
)
print("Responsibility classification accuracy: {}".format(
nltk.classify.accuracy(
responsibilities_classifier,
r_test_set
)
))# Departments
d_size = int(len(departments_features) * 0.5)
d_train_set = departments_features[d_size:]
d_test_set = departments_features[:d_size]
departments_classifier = nltk.NaiveBayesClassifier.train(
d_train_set
)
print("Department classification accuracy: {}".format(
nltk.classify.accuracy(
departments_classifier,
d_test_set
)
))
输出应该如下所示:
Responsibility classification accuracy: 0.80588235294117646
Department classification accuracy: 0.80526315789473684
数据分类
如果你对结果满意,你可以给新的职位分类。
title = "Director of Communications"
responsibility = responsibilities_classifier.classify(
get_title_features(title)
)
department = departments_classifier.classify(
get_title_features(title)
)
print("Job title: '{}'".format(title))
print("Responsibility: '{}'".format(responsibility))
print("Department: '{}'".format(department))
这将产生以下输出:
Job title: 'Director of Communications'
Responsibility: 'Strategist'
Department: 'Marketing'
一个限制是分类器将为每个职位分配一个部门和责任,不管职位有多模糊。这导致了应该保持不分类或由人审查的职称的分类。
为了克服这一点,我们可以揭示分类器对其解释的信心,以便我们可以选择是否接受它。
# Responsibility
responsibility_probability = \
responsibilities_classifier.prob_classify(
get_title_features(title)
)
responsibility_probability = 100 * responsibility_probability.prob(
responsibility_probability.max()
)
print("Responsibility confidence: {}%".format(
round(responsibility_probability)
))# Department
department_probability = \
departments_classifier.prob_classify(
get_title_features(title)
)
department_probability = 100 * department_probability.prob(
department_probability.max()
)
print("Department confidence: {}%".format(
round(department_probability)
))
结果是这样的:
Responsibility confidence: 86%
Department confidence: 79%
源代码可以在 Github 上找到。我期待听到任何反馈或问题。
男孩(和女孩)的工作
原文:https://towardsdatascience.com/jobs-for-the-boys-and-girls-d69345ed22b8?source=collection_archive---------3-----------------------
在 200 多家 ASX 上市公司中,女性和男性的比例分别为 45%和 55%。有趣的是,这种情况似乎合乎逻辑。我们很多人都认识一些女性,她们会停止工作一段时间来照看孩子或照顾家人。45%的员工由女性组成,这可能看起来合理、公平,甚至很高。我的意思是,这是非常接近一半,对不对?
然而,如果我们进一步挖掘数据,就会发现性别不平等仍然是大多数组织的组成部分。无论是工作的行业类型、人们所担任的角色,还是他们的就业状况,有时性别不平衡远远超过这一接近甚至 45%对 55%的比例。
这可能是一个很好的观点,说明性别平等不仅仅是让更多的妇女工作,或者让更多的妇女留在劳动力队伍中。这是关于解决一种性别占主导地位的就业领域的性别失衡问题。这是关于认识到男性和女性的经验对所有行业都很重要。重要的是,人们有选择满意职业的自由,这种职业不依赖于被认为是“性别合适”的角色。这意味着让更多的男性进入卫生或教育领域,就像让更多的女性进入科学或 it 领域一样重要。
工业
当将结果汇总到一个行业级别时,大多数结果显示性别不平衡。只有三个行业显示男女分布平等。其余的男女比例不平衡,大多数人倾向于男性就业。
Gender Split Distributions for Industries
考察绝对比率,结果更加明显。90%以上从事卫生和社会援助工作的人是妇女。相反,80%以上受雇于建筑业和采矿业的人是男性。
Gender ratios across industry classification.
虽然男性和女性在劳动力中的广泛分布接近相等,但行业分类之间存在很大差异。这可能会对长期职业参与产生负面影响;女性和男性可能会感到“被定型”,更有可能追求似乎更符合他们性别的职业,而不是他们的兴趣或优势。这可能会导致生产率下降。
数据源和详细信息
本帖探究 2014/15 年度调查结果。他们调查了 213 个组织的性别平等状况。这 213 家组织只是 2014/15 年向 WGEA 报告的 4670 家公司中的一小部分,但这 213 家组织都在 ASX 上市,因此有可能探索性别平等和 ASX 绩效之间是否存在任何联系。这篇文章探讨了不同行业分类的性别平等调查结果。我开展的其他工作侧重于男性和女性的职位和工作状况,以及股东总回报(TSR)和性别平等之间的关系。
WGEA 每年收集数据,他们是数据的来源和所有者。我从他们的主要数据集中提取了 213 家 ASX 上市公司的一个较小的集合,上面所有的结果都反映了这个较小的数据集合。
加入#人人爱行动
原文:https://towardsdatascience.com/join-the-aiforeveryone-initiative-86bae2dfc13a?source=collection_archive---------9-----------------------
My first time presenting “A Gentle Introduction to Machine Learning” at UC Irvine.
更新: 你也可以在 西班牙语 中阅读这篇文章
人工智能(AI)领域的领军人物之一吴恩达最近将人工智能称为“新电力”。这当然是一个大胆的声明,坦率地说,我完全同意他的观点!
就像 100 年前的电力一样,人工智能正在改变我们世界的几乎每个方面;从我们检索信息和浏览世界的方式到医生用来检测和治疗疾病的技术。
许多研究人员已经转向人工智能来寻找许多全球性问题的解决方案,例如解决水危机和战胜饥饿。毫无疑问,人工智能具有巨大的潜力,这就是为什么研究人员不应该是唯一有机会获得这些知识/技术的人。像微软和谷歌这样的公司都有这种信念,这也反映在他们为人工智能民主化所做的巨大努力中。毫不奇怪,他们的计划已经在推动创新。我最喜欢的一个故事是来自芝加哥的一个名叫阿布的高中生,他使用谷歌的开源机器学习库——tensor flow,建立了一个早期检测乳腺癌肿瘤的系统。
Abu’s Story
但重要的是要认识到,这不仅仅是让机器学习工具可供他人使用,有时我们需要的是一位导师,这可以是一位朋友,一位老师,甚至是一位陌生人,他们分享他们的知识,并帮助我们认识到人工智能如何被用来解决实际问题。
出于这个原因,我想鼓励你们每个人都参与到“人人爱你”的行动中来。
大约两个月前,我决定访问不同的学校,通过举办关于机器学习、人工神经网络和 TensorFlow 等主题的讲座/研讨会来传播 AI。
我绝不是人工智能方面的专家(至少现在还不是),但我已经能够通过上课和参与项目,对机器学习和自然语言处理的许多领域建立坚实的理解;足以向学生们介绍这些话题,并引导他们走向正确的方向。
现在,你不一定要参加这个项目的讲座或研讨会,一个简单的一对一的讨论可以为这个领域的新手做很多事情。不管你决定怎么做,我认为我们都应该遵守 3 条简单的规则:
1.不要胡说。
你能做的最糟糕的事情就是试图让自己听起来很聪明,并传播错误信息。我有学生就我不太了解的话题问我问题,我经常克制自己不做任何评论,以免让他们更加困惑。如果你不知道这一切,不要难过,这就是谷歌的作用!
2.把它作为一个学习自己的机会
我甚至不能简单地通过试图以容易消化的方式解释困难的概念来表达我对人工智能的了解有多少。记住,通过分享你所知道的,你不仅是在帮助别人,也是在帮助你自己。
3.确保他们向前支付它
回馈他人最重要的部分是鼓励他们也这样做。记住阿布的一句话,“帮助别人总会回到你身边”。
如果你准备好加入这一倡议,那么不要忘记使用标签 #AIforEveryone 分享你是如何参与其中的。
此外,如果你有任何问题,请随时联系我,并通过评论和分享这篇文章 😃 来表达对 ♥ 的爱
加入我们,成为一名志愿编辑助理
原文:https://towardsdatascience.com/join-us-as-an-editorial-associate-of-towards-data-science-766cdd74d13e?source=collection_archive---------0-----------------------
【2022 年 12 月更新
我们公开的志愿者编辑助理职位现在已经招满了。
Photo by Thought Catalog on Unsplash
走向数据科学为成千上万的人提供了一个交流思想和扩展我们对数据科学的理解的平台。我们的受众是多样化的,包括对该主题完全陌生的读者和希望分享他们的项目和发现的专业人士。
我们致力于为我们的数据科学社区提供有趣和可靠的内容。我们的 TDS 团队会仔细审查我们从作者那里收到的每一篇帖子。我们经常联系我们的志愿编辑同事,他们是各自领域的专家,了解他们的观点。
随着越来越多的投稿涵盖了不断扩大的主题范围,我们邀请申请三个公开志愿编辑助理职位。
如果你对此感兴趣,请继续阅读!
我们在找什么?
目前,我们特别寻找在以下领域拥有丰富经验和知识的志愿编辑助理:
- 计算机视觉
- 生物学/生物信息学/医学
- 高级机器学习/深度学习
- 数据/人工智能伦理
我们总是欣赏具有强大的统计和/或数学专业知识的申请人。
申请人应该能够每周投入 1 小时。评论在周一至周五分配,我们更喜欢在 2-3 天内完成的评论,因为这有助于我们快速评估并向作者返回决定。由于我们是一个完全分散的团队,我们欢迎全球范围内的申请人。
我们将优先考虑具有丰富的 TDS 写作组合和相关行业或研究经验的申请人。你不必是一个活跃的媒体成员申请,因为我们会为你提供一个成员。
我们对你有什么期望?
随着我们将 TDS 打造成为面向初学者和专业人士的领先在线数据科学社区,我们正在寻找充满热情且有主见的主题专家,他们希望在保持我们出版物的质量方面发挥关键作用。
你的职责将包括每周花1 小时与我们的编辑一起审查与数据科学领域相关的内容,以及机器学习、人工智能、伦理和编程等相关主题。
这将涉及:
- 就一篇文章是否对我们的读者有价值提供反馈;基于您的专业知识,我们特别想听听您对材料整体准确性的看法。
- 向我们的作者提供反馈和建议,这些可以通过我们的编辑或你自己在帖子上的私人注释与作者分享。
如何申请
要成为一名志愿编辑助理,请将您的简历或 LinkedIn 个人资料、专业领域以及是否有空通过电子邮件发送至我们的 TDS 编辑团队。请使用您的专业或学术电子邮件地址,因为这有助于我们验证您的个人资料和简历。
强烈鼓励你附上你以前的写作或提供你的媒体简介的例子!我们期待您的回复。
祝一切顺利,
佐科威内阁改组传闻
原文:https://towardsdatascience.com/jokowis-cabinet-reshuffle-buzz-a9baa8c19619?source=collection_archive---------7-----------------------
背景
佐科·维多多总统于 2016 年 7 月 27 日宣布内阁改组。旨在提高其内阁效率的举措。这件事在网民中引起了不同的反应。有些是优点,有些是缺点。了解人们对重组的看法看起来很有趣。因此,我通过追踪关键词“# reshuffle”来分析人们在 twitter 上谈论的关于改组的话题,然后从中提取信息。
数据
我收集了从 2016 年 7 月 27 日到 2016 年 8 月 3 日的数据,总共有 15,290 条推文包含标签#reshuffle(当然,实际上比关于#reshuffle 的推文数量多)。我使用 Jeff Gentry 的“twitteR”包来抓取推文。
分析
推文类型
让我们从了解#reshuffle 关键字的 tweet 行为开始分析。
Type of Tweets
似乎网民更喜欢转发人们的推文(55.4%),而不是表达自己的想法(推文,42.5%)。他们中很少有人(2.07%)会通过回复推特来做进一步的讨论。
Time distribution by hour
这张图显示了网民在 twitter 上活跃的时间分布。看起来网民更喜欢在早上而不是晚上活跃在推特上。高峰时间是早上 8 点。
网红
现在,我们将找出是谁在 twitter 上发布了关于#改组的推文。给你。
Top 5 Influencers
在此期间,共有 6081 个独立用户发布了关于#改组的帖子,总共获得了 837,660,066 次展示。上图显示了发帖最多的前 10 个 twitter 账户。
艺术家是谁?
以下是参与此次内阁改组的部长们的受欢迎程度分布。让我们看看在改组问题上谁是最受欢迎的部长。
Top 10 most mentioned people
Woa!Anies baswedan 是最受欢迎的大臣。紧随其后的是维兰托、斯里·穆利亚尼和伊格纳修斯·约南。
网友是怎么想的?
好的,在上面我们已经知道了在网民中受欢迎的部长。那么,他们是怎么看待他们的呢?他们说好的感觉还是相反?
让 wordcloud 来回答你的问题。下面是网民提及最多的 4 位最受欢迎的部长的聚类。
Clustered wordcloud over top 4 popular ministers.
维兰托
Wiranto 与法律问题有关,因为他周围出现最多术语是' kejahatan ',' dakwaan '和' ham '。
安尼斯巴斯维丹
Anies Baswedan 似乎得到了网民的积极印象。他们感谢安妮斯的表现,网民们也对他的替代者表示不满。
斯里·穆亚尼
人们欢迎 Sri Mulyani 回来,他们希望她能治愈印尼经济。
伊格内修斯·乔南
伊格内修斯·乔南,从网民那里得到了复杂的感觉。一些人同意他替换,另一些人对他的替换感到失望,因为他们认为 Jonan 的表现足够好。
从机器学习到深度学习的旅程
原文:https://towardsdatascience.com/journey-from-machine-learning-to-deep-learning-8a807e8f3c1c?source=collection_archive---------7-----------------------
我们都知道,机器学习和深度学习肯定会继续存在。从健康诊断到金融技术,许多初创公司都在这些基础上构建应用程序,而老牌企业则试图升级他们的技术堆栈,将这些技术用于业务分析。越来越多的企业需要智能分析来保持竞争优势。这绝对是为了未来收益而投资的两项技术。
在短短两年内,英伟达在深度学习方面合作的公司数量增长了近 35 倍,达到 3400 多家。
医疗保健、生命科学、能源、金融服务、汽车、制造和娱乐等行业将受益于从海量数据中推断出的洞察力。这些分析已经被杰出的玩家用来在游戏中保持领先。
Intelligence is desired by every enterprise to achieve optimality in every aspect of an organization.
我们每个人在日常生活中都听过这两个词。但是,这两者之间的确切区别是什么,以及我们的业务用例何时需要使用其中之一。深度学习显然已经显示了从计算机视觉到 NLP 分析的大量应用,并且已经超过了它的前身机器学习模型。但是,到目前为止,商业分析仍然主要由机器学习和决策树、随机森林等传统算法控制。仍然是可靠的方法。
在本文中,让我们探索这两个领域的基本区别,并对这两个领域进行评价。考虑到这两个领域的重要性,最好是温习一下基础知识,并对这两个领域有一个基本的不同理解。
深度学习是机器学习的子集,机器学习是 AI 的子集,AI 是任何做一些智能事情的计算机程序的总称。换句话说,所有的机器学习都是 AI,但不是所有的 AI 都是机器学习。例如,专家系统可能不使用任何机器学习,而只是利用由专家编码到其中的领域知识。
Open For Discussion In Response Section : Can we really call a machine mimicking intelligent behavior really intelligent ? Refer, Chinese Room Problem for example.
什么是机器学习?
机器学习捕捉系统的动态,并且不需要人为干预来进行某些改变。这使它变得强大,减少了对人类专家的依赖。也许,汤姆·米切尔最流行的定义会提供更多的见解。
如果一个计算机程序在 T 中的任务上的性能(如 P 所测量的)随着经验 E 而提高,则称该计算机程序从关于某类任务 T 和性能测量 P 的经验 E 中学习。
让我们借助一个例子来探讨这个定义。考虑一个场景,其中您有兴趣找出雇主满意度和雇主工资之间关系。所以,我们已经定义了我们的任务。让我们用线性模型来拟合我们的数据,损失函数是距离最佳拟合线的欧几里得距离之和。对于最佳拟合,我们的目标是将其最小化。
With number of more iterations i.e. increased experience E our model’s performance P does increases with reduction in loss and much better fitted curve for better predictions.
显然,这是一个让计算机无需显式编程就能学习的研究领域。
什么是深度学习?
深度人工神经网络是一组算法,在许多重要问题上,如图像识别、声音识别、推荐系统等,它们在准确性方面创造了新的记录。术语'深'指的是神经网络中不止一个隐藏层。这些隐藏层用于学习一个问题的不同特征图。考虑下面的定义。
深度学习通过学习将问题表示为嵌套的概念层次结构来实现强大的功能和灵活性,每个概念都是相对于更简单的概念来定义的,而更抽象的表示是根据不太抽象的概念来计算的。
让我们通过与自动编码器(机器学习中的标准前馈神经网络)进行比较来培养对深度学习模型的欣赏。
征途:从机器学习中欣赏深度学习
深度学习模型在性能和达到最先进的结果方面超出了预期。但是,它们与机器学习中使用的人工神经网络或自动编码器有什么不同?使他们的工作更出色以取得更好结果的根本区别是什么?
考虑以[汽车、公共汽车、纪念碑、花卉]作为输出类别的多类别分类问题的情况。在机器学习中,最基本的方法是利用我们训练好的模型,如模式识别,在大量的特征集中找出分类对象的准确出现。
这种方法效率很低。但是,为什么呢?分类器需要做太多不必要的分析。像天空和水的蓝色在物体检测的图像中是不重要的。此外,对象的颜色在图像中并不重要。这将不必要地增加功能的数量。让我们应用特征工程,用边缘检测过滤器,用有限的重要特征达到更好的结果。具有计算出边缘的能力的模型将能够更好地构造出完整的对象,并且仅学习最相关的特征。
它肯定会比以前的方法给出更好的结果。但是,现在我们也可以使用专门设计的过滤器来检测像 SIFT 或 HOG 这样的对象。这将有助于给出以上问题的最新结果。
所有的特征工程过程都是在一些领域知识和静态特征提取技术的帮助下完成的。在绘制这些特征图时,他们没有学习。这是数据科学家需要做的预处理工作。深度学习需要从上述场景中回答的主要问题是…
除了学习分类器的权重,我们还可以学习多个有意义的核吗?
Yes, We can !!
简单地通过将这些核作为参数,并且通过反向传播算法除了学习分类器的权重之外还学习它们。你可能已经知道,用于这个过程的网络被称为卷积神经网络。因为,我们什么也不做,只是在图像上应用这些过滤器时执行卷积运算。
但是,它与以前机器学习中存在的前馈神经网络有什么不同呢?
常规的前馈神经网络是密集的,使得一个密集的网络从所有 16 个输入神经元中取贡献值来对 h11 的计算作出贡献。此外,最重要是大多数连接都是冗余的。****
多余!!但是,我认为这些密集的连接会捕捉到最多的信息。让我们看看 CNN 是如何解决这些问题的。
Assume a 16 pixel input
显然,只有少数局部神经元参与了 h11 的计算。例如,只有像素 1、2、5、6 对 h11 有贡献。随着参数数量的减少,连接更加稀疏,使得复杂性降低,从而减少了计算。
这些稀疏的连接是否合理?我们不是在丢失信息吗?
这些稀疏的连接表明,相邻像素之间的相互作用比其他像素更重要。此外,考虑 x1 和 x5 它们在第 1 层中不交互。但是它们间接有助于 g3 的计算,因此间接相互作用。考虑到假设两个不同的邻域可能表示对象的相同特征。这将被上面的连接和更高的权重所考虑。
CNN 的另一个重要特性是重量共享。自动编码器将为图像的不同部分赋予不同的内核。
Do we want the kernel weights to be different for different portions of the image?
想象一下,我们正在尝试学习一个检测边缘的内核/过滤器。难道我们不应该在图像的所有部分应用相同的内核吗?因为,图像的像素可能只是平移。此外,我们可以用多个不同的内核学习图像的不同特征来增强我们的特征学习过程。
嗯,我希望通过上面的例子可以清楚地看到,与机器学习相比,深度学习模型具有更强的泛化能力和能力。所有的智能工作都由你创造的神经网络架构来完成。让我们在下一篇文章中看看并欣赏架构。
比较圈地:那么,为什么要用 ML?
最后,让我们在不同的用例参数上比较这两个领域,这些领域算法在这些用例参数上会表现得更好。深度学习没有成为行业标准,留下了优秀的旧 ML,这肯定有原因。
第一个感兴趣的参数是可使用的数据量和数据放大时模型的性能。随着数据的增加,参数会得到很好的调整,模型中的偏差会减少。但是,相反,假设我们想分析每天的数据,例如股票市场的日交易者。在数据量较小的情况下,机器学习模型的性能会更好。
Data dependencies of domains
此外,在应用任何模型时,数据类型都非常重要。深度学习模型在关系数据上表现不佳是众所周知的。因为,没有像我们在 CNN 上看到的那样的社区房产。
Relational Data with no neighborhood relations 😉
数据无疑是模型的燃料,是决定使用哪种模型类型的主要因素。
对于硬件要求,深度学习模型严重依赖于具有大量 GPU 能力的高端机器,因为它涉及大量矩阵乘法,这些乘法可以用强大的 GPU 能力并行执行。其中,机器学习模型训练起来相对非常快,即使没有 GPU 计算也能很好地工作。
如上所述,它们在特征工程过程方面也不同。机器学习需要手工编码的规则和领域知识来提取特征信息。它的性能将取决于在深度学习算法从数据中学习特征时,特征提取得有多好。CNN 将尝试学习低层次的特征,如早期图层中的边缘和线条,然后是人脸的部分,然后是人脸的高层次表示。
与机器学习算法相比,深度学习模型的训练时间要长得多,因为这些模型中涉及的参数数量要大得多。但是测试时间更短,因为它执行操作的速度更快,运行时间更少。k 近邻等机器学习算法在测试过程中速度较慢。
重复性和可解释性是许多行业仍在考虑将深度学习模型用作标准程序的主要原因。由模型获得的结果是不可重复的,因为它涉及大量的参数,这些高参数的不确定性仍然存在。精确的结果可能无法重现,需要取平均值。
此外,我们不知道特定的神经元在深度学习模型中以精确量化的方式做什么。我们可以找出哪个神经元在什么时候活跃,但我们不知道这些神经元应该模拟什么,以及这些神经元层集体在做什么。而像决策树这样的机器学习算法给出了清晰的规则,svm 用其超平面给出了清晰的界限,这更容易解释。
我希望这次对话能够明确深度学习和机器学习之间的区别,并了解何时从机器学习过渡到深度学习。感谢阅读!!
机器学习之旅第 1 部分:简介、动机和路线图
原文:https://towardsdatascience.com/journey-to-machine-learning-part-1-introductions-motivations-and-roadmap-35a438f1e126?source=collection_archive---------4-----------------------
介绍
如果你一直在关注新闻,你很可能已经看到了关于机器学习人才需求量的头条新闻。在最近的 LinkedIn 经济图表报告中,“机器学习工程师”和“数据科学家”是 2017 年增长最快的两个职位(分别增长 9.8 倍和 6.5 倍)。媒体本身充斥着教程、软件评论,以及有趣应用的故事。尽管有明显的需求,但与软件工程其他领域可用的资源相比,作为局外人实际进入这个领域的资源似乎很少。这就是我写这个系列的原因:作为我从非 CS 背景成为机器学习工程师的旅程的文档。
“但是马特”,你一定会说,“这一点也不奇怪,很多人从其他领域进入机器学习。”
确实有很多非 CS 专业的人进入这个领域。然而,我在大学里并没有申报统计学、数学、物理或电气工程专业。我的背景是分子生物学,你们中的一些人可能已经注意到了,这在 STEM 领域的例子列表中经常被忽略。
Credit to Randall Munroe and XKCD (had a tough time deciding between this comic and this one)
虽然我在本科期间比大多数生物专业的学生更专注于统计学和计算机科学,但与物理学家进入该领域相比,这仍然是一条不寻常的道路(正如 Nathan Yau 的 FlowingData 的这篇可爱的帖子所示)。
背景
从高中开始,我就对衰老疾病有一种近乎专一的痴迷。我对机器学习的大量接触是在我本科从事这一领域的研究期间。这是在一个实验室里,将离散的果蝇死亡数据拟合到连续方程,如 gompertz 和 weibull 分布,并使用图像跟踪来测量所述果蝇的身体活动量。在这项研究之外,我还参与了一些项目,比如谷歌学术刮刀,以加快文献综述论文的搜索速度。当时,机器学习似乎只是应用于生物医学研究的另一个有用工具。像其他人一样,我最终意识到这将变得更大,成为未来十年日常生活中不可或缺的技术。我知道我必须认真对待,尽可能熟练地掌握这方面的技能。
但是为什么要完全摆脱衰老呢?为了回答这个问题,我想播放一下我看过的哈佛医学院的 David Sinclair 博士的演讲。在开始谈论他的实验室令人兴奋的研究进展之前,他描述了衰老领域的一场共同斗争。许多实验室专注于该过程的狭窄方面,无论是特定的酶活性、营养信号、基因变化,还是其他无数领域。辛克莱博士提出了盲人和大象的类比,这是因为许多研究人员只关注衰老的狭隘方面,而没有花太多时间来认识整体和部分之间的差异。我觉得现实略有不同(这更像是视力正常的人试图在黑暗中用激光笔而不是手电筒识别一头大象),但结论仍然是正确的:我们需要更好的工具和方法来解决老龄化等问题。
这一点,再加上其他几个因素,让我意识到单独使用生物科学的湿实验室方法是非常低效的。在治愈和治疗的搜索空间中,许多唾手可得的果实在很久以前就被获得了。仍然存在的挑战包括可能需要大量数据才能诊断的疾病和状况,更不用说治疗了(例如,基因多样的癌症,快速变异的病毒,如艾滋病毒)。是的,我同意许多其他人的观点,衰老肯定是一种疾病,但它也是一种定义模糊的疾病,以各种不同的方式影响着人们。
我决定,如果我要在这个领域或我决定进入的任何其他领域做出巨大贡献,最有效的方法将是致力于增强和自动化数据分析的工具。至少在不久的将来,我必须专注于确保我在机器学习方面的基础是坚实的,然后我才能将重点放在像衰老这样的具体案例上。
“那么……这个系列到底是关于什么的?”
在过去的一年里,我已经从学习机器学习和自学转向实际上为机器学习项目工作而获得报酬。机器学习工程仍然相对较新,所以我觉得我迄今为止的经验可能对其他试图进入这一领域的人有用。虽然有大量关于特定机器学习技术的列表和视频教程,但没有像网络或移动开发人员那样的职业指南式支持。这就是为什么这篇文章不仅仅是罗列我用来学习的资源。我还将记录我发现的创建投资组合项目的最佳实践,寻找该领域的短期和长期工作,并跟上快速变化的研究前景。我也将从我采访过的比我走得更远的人那里收集智慧的建议。
写这个系列时,我有两个目标:
如果我永久进入机器学习工程的长期目标最终成功,我希望这可以作为其他试图进入该领域的人(以及试图进入斯坦福大学计算机科学硕士或博士学位以下的人)的路线图。在这种情况下,成功的衡量标准包括在一家拥有大型 R&D 部门的顶级技术公司或一家快速增长的初创公司获得一份全职工作(并在几年的时间尺度内为该初创公司的快速增长做出贡献)。如果我能从一个非计算机科学背景的人那里获得成功,那么我提供的资源很可能会让一个有计算机科学背景的人获得更大的成功。
你需要表现出来的技术能力水平并没有降低,在你没有学历背景的情况下甚至更高,但这是完全可能的。
— Dario Amodei,博士,OpenAI 研究员, 在没有机器学习博士学位的情况下进入该领域
如果我最终没有成功(由某种经验证据来定义,即我试图做的事情是不可能的,或者我离这个领域太远),我希望这可以作为一个记录,其他人可以指出应该避免什么。这种结果不太可能发生,因为我已经开始为做机器学习工作获得报酬了(这些帖子赶上现在可能还需要一段时间),但还有更高的目标要爬。我不想过早庆祝。
记住这一点,下面是本系列其余部分的暂定路线图:
- 介绍和动机(即你现在正在阅读的内容)
- 机器学习工程技能清单
- 提高生产力和学习的习惯
- 软件和硬件资源
- 寻找导师和沉浸感
- 阅读研究论文(和一些每个人都应该知道的)
- 解决问题的方法和工作流程
- 作为机器学习工程师的自由职业者
- 人工智能和机器学习工作联合集的实际考虑
- 你应该熟悉的团体和人
- 机器学习工程师职位面试
这些帖子的大部分内容已经写好了,尽管这些帖子的顺序和数量可能会改变。请继续关注更多更新,并随时回复您想看的内容的建议。
深入探讨多标签分类..!(附有详细的案例研究)
原文:https://towardsdatascience.com/journey-to-the-center-of-multi-label-classification-384c40229bff?source=collection_archive---------0-----------------------
有毒-评论分类。
Fig-1: Multi-Label Classification to finde genre based on plot summary.
随着可用数据的持续增加,迫切需要对其进行组织,并且现代分类问题通常涉及同时与单个实例相关联的多个标签的预测。
被称为多标签分类,它是一个这样的任务,在许多现实世界的问题中无所不在。
在这个项目中,以 Kaggle 问题为例,我们探索了多标签分类的不同方面。
数据来源免责声明: 数据集包含可能被认为亵渎、低俗或冒犯的文字。
项目鸟瞰图:
- 第 1 部分:多标签分类概述。
- 第二部分:问题定义&评估指标。
- Part-3: 探索性数据分析 (EDA) 。
- 第四部分:数据预处理。
- 第五部分:多标签分类技术。
第 1 部分:多标签分类概述:
- 多标签分类起源于对文本分类问题的研究,其中每个文档可能同时属于几个预定义的主题。
- 文本数据的多标签分类是一个重要的问题。例子从新闻文章到电子邮件。例如,这可以用来根据电影情节的概要找到电影所属的类型。
Fig-2: Multi-label classification to find genres based on movie posters.
- 或者基于电影海报的流派多标签分类。(这就进入了计算机视觉的领域。)
- 在多标签分类中,训练集由与一组标签相关联的实例组成,任务是通过分析具有已知标签集的训练实例来预测未知实例的标签集。
- 多类分类的区别&多标签分类在于,在多类问题中,类是互斥的,而对于多标签问题,每个标签代表不同的分类任务,但这些任务在某种程度上是相关的。
- 例如,多类分类假设每个样本被分配给一个且仅一个标签:水果可以是苹果或梨,但不能同时是两者。然而,多标签分类的一个例子可以是,一个文本可能同时涉及宗教、政治、金融或教育中的任何一个,或者这些都不涉及。
第 2 部分:问题定义和评估标准:
问题定义:
- 有毒评论分类是一个高度不平衡数据集的多标签文本分类问题。
- 我们面临的挑战是建立一个多标签模型,能够检测不同类型的毒性,如威胁,淫秽,侮辱和基于身份的仇恨。我们需要创建一个模型来预测每条评论的每种毒性的概率。
- 这个问题的 Kaggle 链接可以在 这里 找到。
评估指标:
注:ka ggle 挑战赛最初的评估指标是 Log-Loss ,后来改为 AUC 。但是在这篇文章中,我们也揭示了其他评估指标。
- 单标签的评估方法通常不同于多标签的评估方法。这里,在单标签分类中,我们使用简单的度量标准,如精确度、召回率、准确度等。比方说,在单标签分类中,准确度只是:
Fig-3: Accuracy in single-label classification
- 在多标签分类中,错误分类不再是绝对的对错。包含实际类别的子集的预测应该被认为比不包含任何类别的预测更好,即,正确预测三个标签中的两个这比根本不预测标签更好。
微平均 & M 宏平均(基于标签的测量):
- 为了测量一个多类分类器,我们必须以某种方式对这些类进行平均。有两种不同的方法可以做到这一点,分别称为微平均和宏平均。
- 在微平均中,对每个类别的所有 TPs、TNs、FPs 和 FNs 求和,然后取平均值。
Fig-4: Micro-Averaging
- 在微平均方法中,您将系统对于不同集合的单个真阳性、假阳性和假阴性相加并加以应用。并且微观平均 F1 分数将简单地是上述两个方程的调和平均值。
- 宏平均非常简单。我们只是取不同集合上系统的精度和召回率的平均值。
Fig-5: Macro-Averaging
- 当您想要了解系统在数据集上的整体表现时,可以使用宏平均方法。你不应该用这个平均数做出任何具体的决定。另一方面,当数据集大小不同时,微平均是一个有用的方法。
汉明损失(基于示例的测量):
- 用最简单的术语来说,汉明损失是被错误预测的标签的分数,即错误标签占标签总数的分数。
Fig-6: Hamming-Loss
精确匹配率(子集准确度):
- 这是最严格的指标,表示所有标签都被正确分类的样本的百分比。
Fig-7: Exact Match Ratio
- 这种方法的缺点是多类分类问题有部分正确的机会,但这里我们忽略了那些部分正确的匹配。
- 在 scikit-learn 中有一个实现子集精度的函数,叫做 accuracy_score。
注意:我们将使用 accuracy_score 函数来评估我们在这个项目中的所有模型。
第 3 部分:探索性数据分析(EDA):
探索性数据分析是数据分析过程中的重要步骤之一。在这里,重点是理解手头的数据——比如制定向数据集提问的正确问题,如何操作数据源以获得所需的答案,等等。
- 首先让我们导入必要的库。
import os
import csv
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
- 接下来,我们将 csv 文件中的数据加载到 pandas 数据帧中,并检查其属性。
data_path = "/Users/kartik/Desktop/AAIC/Projects/jigsaw-toxic-comment-classification-challenge/data/train.csv"data_raw = pd.read_csv(data_path)print("Number of rows in data =",data_raw.shape[0])
print("Number of columns in data =",data_raw.shape[1])
print("\n")
print("**Sample data:**")
data_raw.head()
Fig-8: Data Attributes
- 现在我们统计每个标签下的评论数量。(详细代码请参考本项目的 GitHub 链接。)
categories = list(data_raw.columns.values)
sns.set(font_scale = 2)
plt.figure(figsize=(15,8))ax= sns.barplot(categories, data_raw.iloc[:,2:].sum().values)plt.title("Comments in each category", fontsize=24)
plt.ylabel('Number of comments', fontsize=18)
plt.xlabel('Comment Type ', fontsize=18)#adding the text labels
rects = ax.patches
labels = data_raw.iloc[:,2:].sum().values
for rect, label in zip(rects, labels):
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width()/2, height + 5, label, ha='center', va='bottom', fontsize=18)plt.show()
Fig-9: Count of comments under each label
- 计算具有多个标签的评论的数量。
rowSums = data_raw.iloc[:,2:].sum(axis=1)
multiLabel_counts = rowSums.value_counts()
multiLabel_counts = multiLabel_counts.iloc[1:]sns.set(font_scale = 2)
plt.figure(figsize=(15,8))ax = sns.barplot(multiLabel_counts.index, multiLabel_counts.values)plt.title("Comments having multiple labels ")
plt.ylabel('Number of comments', fontsize=18)
plt.xlabel('Number of labels', fontsize=18)#adding the text labels
rects = ax.patches
labels = multiLabel_counts.values
for rect, label in zip(rects, labels):
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width()/2, height + 5, label, ha='center', va='bottom')plt.show()
Fig-10: Count of comments with multiple labels.
- 每一类评论中最常用词的 WordCloud 表示。
from wordcloud import WordCloud,STOPWORDSplt.figure(figsize=(40,25))# clean
subset = data_raw[data_raw.clean==True]
text = subset.comment_text.values
cloud_toxic = WordCloud(
stopwords=STOPWORDS,
background_color='black',
collocations=False,
width=2500,
height=1800
).generate(" ".join(text))
plt.axis('off')
plt.title("Clean",fontsize=40)
plt.imshow(cloud_clean)# Same code can be used to generate wordclouds of other categories.
Fig-1: Word-cloud Representation of Clean Comments
第 4 部分:数据预处理:
- 我们首先将注释转换成小写,然后使用定制的函数从注释中删除 html 标签、标点符号和非字母字符。
import nltk
from nltk.corpus import stopwords
from nltk.stem.snowball import SnowballStemmer
import re
import sys
import warningsdata = data_rawif not sys.warnoptions:
warnings.simplefilter("ignore")def cleanHtml(sentence):
cleanr = re.compile('<.*?>')
cleantext = re.sub(cleanr, ' ', str(sentence))
return cleantextdef cleanPunc(sentence): #function to clean the word of any punctuation or special characters
cleaned = re.sub(r'[?|!|\'|"|#]',r'',sentence)
cleaned = re.sub(r'[.|,|)|(|\|/]',r' ',cleaned)
cleaned = cleaned.strip()
cleaned = cleaned.replace("\n"," ")
return cleaneddef keepAlpha(sentence):
alpha_sent = ""
for word in sentence.split():
alpha_word = re.sub('[^a-z A-Z]+', ' ', word)
alpha_sent += alpha_word
alpha_sent += " "
alpha_sent = alpha_sent.strip()
return alpha_sentdata['comment_text'] = data['comment_text'].str.lower()
data['comment_text'] = data['comment_text'].apply(cleanHtml)
data['comment_text'] = data['comment_text'].apply(cleanPunc)
data['comment_text'] = data['comment_text'].apply(keepAlpha)
- 接下来,我们使用可以从 NLTK 库中下载的默认停用词集合,删除注释中出现的所有 停用词 。我们还在标准列表中添加了一些停用词。
- 停用词基本上是任何语言中的一组常用词,不仅仅是英语。停用词对许多应用程序至关重要的原因是,如果我们删除给定语言中非常常用的词,我们就可以专注于重要的词。
stop_words = set(stopwords.words('english'))
stop_words.update(['zero','one','two','three','four','five','six','seven','eight','nine','ten','may','also','across','among','beside','however','yet','within'])
re_stop_words = re.compile(r"\b(" + "|".join(stop_words) + ")\\W", re.I)
def removeStopWords(sentence):
global re_stop_words
return re_stop_words.sub(" ", sentence)data['comment_text'] = data['comment_text'].apply(removeStopWords)
- 接下来我们做 词干 。存在不同种类的词干,它们基本上将语义大致相同的单词转换成一种标准形式。例如,对于逗乐、娱乐和逗乐,词干应该是 amus。
stemmer = SnowballStemmer("english")
def stemming(sentence):
stemSentence = ""
for word in sentence.split():
stem = stemmer.stem(word)
stemSentence += stem
stemSentence += " "
stemSentence = stemSentence.strip()
return stemSentencedata['comment_text'] = data['comment_text'].apply(stemming)
- 在将数据集分成训练集和测试集之后,我们想要总结我们的注释,并将它们转换成数字向量。
- 一个技巧是挑选最频繁出现的术语(具有高 术语频率 或 tf 的词)。然而,最频繁出现的单词是一个不太有用的度量,因为像' this '、' a '这样的单词在所有文档中出现得非常频繁。
- 因此,我们还希望衡量一个单词的独特性,即该单词在所有文档中出现的频率(In 反转文档频率 或 idf )。
- 因此,一个单词的 TF & IDF(TF-IDF)的乘积给出了该单词在文档中的出现频率乘以该单词在整个文档语料库中的独特性的乘积。
- 文档中具有高 tfidf 分数的单词在文档中频繁出现,并且提供关于该特定文档的最多信息。
from sklearn.model_selection import train_test_splittrain, test = train_test_split(data, random_state=42, test_size=0.30, shuffle=True)from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(strip_accents='unicode', analyzer='word', ngram_range=(1,3), norm='l2')
vectorizer.fit(train_text)
vectorizer.fit(test_text)x_train = vectorizer.transform(train_text)
y_train = train.drop(labels = ['id','comment_text'], axis=1)x_test = vectorizer.transform(test_text)
y_test = test.drop(labels = ['id','comment_text'], axis=1)
- TF-IDF 易于计算,但其缺点是不能捕捉文本中的位置、语义、在不同文档中的共现等。
第 5 部分:多标签分类技术;
大多数传统的学习算法是针对单标签分类问题开发的。因此,文献中的许多方法将多标签问题转化为多个单标签问题,从而可以使用现有的单标签算法。
1.OneVsRest
- 通过限制每个实例只有一个标签,传统的两类和多类问题都可以转化为多标签问题。另一方面,多标签问题的通用性不可避免地增加了学习的难度。解决多标签问题的直观方法是将其分解为多个独立的二分类问题(每个类别一个)。
- 在“一对多”策略中,可以建立多个独立的分类器,并且对于一个看不见的实例,选择置信度最大化的类别。
- 这里的主要假设是标签是互斥的。在这个方法中,您不考虑类之间的任何潜在相关性。
- 例如,它更像是问一些简单的问题,比如,“评论是否有毒”、“评论是否具有威胁性?等。此外,这里可能有一个广泛的过度拟合的情况,因为大多数注释是未标记的,也就是说,大多数注释是干净的注释。
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score
from sklearn.multiclass import OneVsRestClassifier# Using pipeline for applying logistic regression and one vs rest classifier
LogReg_pipeline = Pipeline([
('clf', OneVsRestClassifier(LogisticRegression(solver='sag'), n_jobs=-1)),
])for category in categories:
print('**Processing {} comments...**'.format(category))
# Training logistic regression model on train data
LogReg_pipeline.fit(x_train, train[category])
# calculating test accuracy
prediction = LogReg_pipeline.predict(x_test)
print('Test accuracy is {}'.format(accuracy_score(test[category], prediction)))
print("\n")
Fig-12: OneVsRest
2.二元相关性
- 在这种情况下,训练单标签二元分类器的集合,每个类别一个。每个分类器预测一个类的成员或非成员。所有被预测的类的并集被作为多标签输出。这种方法很受欢迎,因为它易于实现,但是它也忽略了类标签之间可能的相关性。
- 换句话说,如果有 q 个标签,二元相关性方法从图像中创建 q 个新数据集,每个标签一个,并在每个新数据集上训练单标签分类器。一个分类器可能对“它包含树吗?”这个问题回答是/否,从而“二元关联”中的“二元”。这是一种简单的方法,但是当标签之间存在依赖关系时,这种方法就不好用了。
- OneVsRest &二元关联性看起来非常相像。如果 OneVsRest 中的多个分类器回答“是”,那么您将回到二元相关性场景。
# using binary relevance
from skmultilearn.problem_transform import BinaryRelevance
from sklearn.naive_bayes import GaussianNB# initialize binary relevance multi-label classifier
# with a gaussian naive bayes base classifier
classifier = BinaryRelevance(GaussianNB())# train
classifier.fit(x_train, y_train)# predict
predictions = classifier.predict(x_test)# accuracy
print("Accuracy = ",accuracy_score(y_test,predictions)) ***Output:****Accuracy = 0.856666666667*
3.分类器链
- 一串二元分类器 C0,C1。。。,Cn,其中分类器 Ci 使用所有分类器 Cj 的预测,其中 j < i. This way the method, also called classifier chains (CC), can take into account label correlations.
- The total number of classifiers needed for this approach is equal to the number of classes, but the training of the classifiers is more involved.
- Following is an illustrated example with a classification problem of three categories {C1, C2, C3} chained in that order.
Fig-13: Classifier Chains
# using classifier chains
from skmultilearn.problem_transform import ClassifierChain
from sklearn.linear_model import LogisticRegression# initialize classifier chains multi-label classifier
classifier = ClassifierChain(LogisticRegression())# Training logistic regression model on train data
classifier.fit(x_train, y_train)# predict
predictions = classifier.predict(x_test)# accuracy
print("Accuracy = ",accuracy_score(y_test,predictions))
print("\n")***Output:****Accuracy = 0.893333333333*
4. Label Powerset
- This approach does take possible correlations between class labels into account. More commonly this approach is called the label-powerset method, because it considers each member of the power set of labels in the training set as a single label.
- This method needs worst case (2^|C|) classifiers, and has a high computational complexity.
- However when the number of classes increases the number of distinct label combinations can grow exponentially. This easily leads to combinatorial explosion and thus computational infeasibility. Furthermore, some label combinations will have very few positive examples.
# using Label Powerset
from skmultilearn.problem_transform import LabelPowerset# initialize label powerset multi-label classifier
classifier = LabelPowerset(LogisticRegression())# train
classifier.fit(x_train, y_train)# predict
predictions = classifier.predict(x_test)# accuracy
print("Accuracy = ",accuracy_score(y_test,predictions))
print("\n")***Output:****Accuracy = 0.893333333333*
5. Adapted Algorithm
- Algorithm adaptation methods for multi-label classification concentrate on adapting single-label classification algorithms to the multi-label case usually by changes in cost/decision functions.
- Here we use a multi-label lazy learning approach named ML-KNN 是从传统的 K-最近邻(KNN)算法得到的。
[**skmultilearn.adapt**](http://scikit.ml/api/api/skmultilearn.adapt.html#module-skmultilearn.adapt)
模块实现多标签分类的算法自适应方法,包括但不限于 ML-KNN。
from skmultilearn.adapt import MLkNN
from scipy.sparse import csr_matrix, lil_matrixclassifier_new = MLkNN(k=10)# Note that this classifier can throw up errors when handling sparse matrices.x_train = lil_matrix(x_train).toarray()
y_train = lil_matrix(y_train).toarray()
x_test = lil_matrix(x_test).toarray()# train
classifier_new.fit(x_train, y_train)# predict
predictions_new = classifier_new.predict(x_test)# accuracy
print("Accuracy = ",accuracy_score(y_test,predictions_new))
print("\n")***Output:****Accuracy = 0.88166666667*
结论:
结果:
- 解决多标签分类问题主要有两种方法:问题转化方法和算法自适应方法。
- 问题转换方法将多标签问题转换成一组二元分类问题,然后可以使用单类分类器来处理这些问题。
- 而算法适应方法使算法适应直接执行多标签分类。换句话说,他们不是试图将问题转化为更简单的问题,而是试图解决问题的全部形式。
- 在与其他方法的广泛比较中,label-powerset 方法得分最高,其次是 one-against-all 方法。
- 在这个数据集上运行时,ML-KNN 和 label-powerset 都需要相当长的时间,所以实验是在训练数据的随机样本上进行的。
进一步改进:
- 在深度学习中使用 LSTMs 可以解决同样的问题。
- 为了更快的速度,我们可以使用决策树,为了在速度和准确性之间进行合理的权衡,我们也可以选择集合模型。
- 诸如 MEKA 的其他框架可以用于处理多标签分类问题。
GitHub 项目的 链接 。LinkedIn 简介。
希望你喜欢这个教程。感谢阅读..!
直观理解贝叶斯定理之旅
原文:https://towardsdatascience.com/journey-to-understand-bayes-theorem-visually-80b9fbf9f4f5?source=collection_archive---------10-----------------------
Photo by Riho Kroll on Unsplash
对于机器学习工程师或数据科学专业人员来说,理解概率的概念是必须的。许多数据科学挑战性问题的解决方案本质上往往是概率性的。因此,更好地理解概率将有助于你更有效地理解和实现这些算法。
每当我阅读任何概率书籍或研究论文时,大多数时候我都发现这些书籍中的文献过于理论化。根据社会科学研究网的数据,65%的人是视觉学习者。用图解法理解定理和证明是可视化信息和数据的有效方法,不仅如此,这种以可视化方式呈现数据的方法在很长一段时间内都被证明是有效的。所以通过这个博客,我想以一种视觉的方式展示概率的概念。
目录
- 什么是条件概率?
- 全概率定律
- 贝叶斯定理
- 贝叶斯定理的应用
首先让我们详细了解条件概率。
什么是条件概率?
根据维基百科 的说法,条件概率是在假设(通过假设、推测、断言或证据)另一事件已经发生的情况下,对一个事件(一些特定情况发生)的概率的度量。如果感兴趣的事件是 A 且事件 B 已知或假设已经发生,“给定 B 的情况下 A 的条件概率”,或“条件 B 下 A 的概率”,通常写成P(A|B,有时也写成P
Source: giphy.com
这和我第一次读这本书时的反应是一样的。你们中的一些人一定已经通过维恩图方法理解了它。所以现在让我们尝试用一种新的方法来直观地解释它。
Conditional Probability Diagram
假设我们在从开始的时间线内开始观察。在我们开始观察时间线之后,事件 A 有可能发生。在 A 之后还有另一个事件 B 发生的可能性,其概率用 P(B|A) 表示。
由于两个事件相继发生,整个时间线发生的概率(即 A 和 B 都发生并且 B 发生在 A 之后)为
P(A)⋅港口
由于我们考虑 A 和 B 都发生的概率,它也可以解释为 P(A ∩ B)
Intersection Rule (A ∩ B)
因此,
P(A ∩ B) = P(A)⋅ P(B|A)
这里 P(B|A)被称为条件概率,因此可以简化为
P(B|A) = P(A ∩ B)/P(A),假设 P(A) ≠ 0
请注意,只有当事件相继发生并且相互依赖时,上述情况才有效。也有可能 A 不影响 B,如果是这样,那么这些事件是相互独立的,称为独立事件
Independent Events
因此,在独立事件的情况下,A 发生的几率不会影响 B 发生的几率。
P(B|A) = P(B)
全概率定律
全概率法则将计算分成不同的部分。它用于确定一个事件的概率,该事件与前一个事件之前发生的两个或多个事件相关。
太抽象?让我们试试视觉方法
Total Probability Diagram
设 B 是一个事件,它可以发生在任何“ n ”事件(A1,A2,A3,…)之后..安)。如上定义 P(Ai ∩ B) = P(Ai)⋅P(B|Ai) ∀ i ∈[1,n]
自从事件 A1,A2,A3,…an 是互斥的,不能同时出现,我们可以通过 A1 或 A2 或 A3 或……或 An 到达 B。因此,求和规则规定
P(B)= P(A1∩B)+P(A2∩B)+P(A3∩B)+…..+ P(An ∩ B)
P(A1)⋅ P(B|A1) + P(A2)⋅ P(B|A2) + …..+ P(An)⋅ P(B|An)
上述表达式称为全概率法则或全概率法则。这也可以用文氏图来解释。
贝叶斯定理
贝叶斯定理是一种基于某些概率的先验知识来预测起源或来源的方法
我们已经知道 P(B|A) = P(A ∩ B)/P(A) ,假设两个相互依存的事件 P(A) ≠ 0。有没有想过什么 P(A|B) =?,语义上没有任何意义,因为 B 发生在 A 之后,并且时间线不能反转(即我们不能从 B 向上移动到开始
根据条件概率,数学上我们知道
P(A|B) = P(B ∩ A)/P(B),假设 P(B) ≠ 0
P(A|B) = P(A ∩ B)/P(B),as P(A ∩ B) = P(B ∩ A)
我们知道这一点
P(A ∩ B) = P(B|A)⋅ P(A)
替换我们得到的值
p(a | b)=p(b|a)⋅p(a)/p(b)
这是贝叶斯定理的最简单形式。
现在,假设 B 相互依赖于在它之前发生的多个事件。将全概率规则应用于上述表达式,我们得到
p(ai | b)=p(b|ai)⋅p(ai)/(p(a1)⋅p(b | a1)+…..+ P(An)⋅ P(B|An))
这是我们通常在各种现实世界应用中使用的贝叶斯定理的形式。
贝叶斯定理的应用
由于它的预测性质,我们使用贝叶斯定理来推导朴素贝叶斯,这是一个流行的机器学习分类器
如您所知,贝叶斯定理基于可能与事件相关的因素的先验知识来定义事件的概率。
现在,基本上对于一个数据点 xi,我们必须预测当前输出 Y 属于哪一类。假设总共有“j”个类用于输出。
然后,
P(y = c1 | x = xi)——>告诉我们,对于给定的输入 Xi,y 是 C1 的概率是多少。
P(y = c2 | x = xi)——>告诉我们,对于给定的输入 Xi,y 是 C2 的概率是多少。
以此类推直到 cj。
在所有这些概率计算中,y 属于具有最大概率的特定类别。
我们将使用贝叶斯定理来做这些概率计算。
这为我们提供了数据点(xi)的当前值的输出属于第 j 类的概率。
因为对于所有的类 1,2,…,j,分母将具有相同的值,所以我们在进行比较时可以忽略这一点。因此,我们得到了计算概率的公式。
为什么叫幼稚?还是天真的假设
我们之所以称之为幼稚,是因为我们做了一个简单的假设,即一个类中特定特性的存在与任何其他特性的存在无关,这意味着每个特性都是相互独立的。
概率 P(y=cj)的估计可以直接从训练点的数量来完成。
假设有 100 个训练点和 3 个输出类别,10 个属于类别 c1,40 个属于类别 C2,剩余的 50 个属于类别 C3。
类别概率的估计值将为:
P(y = C1)= 10/100 = 0.1
P(y = C2)= 40/100 = 0.4
P(y = C3)= 50/100 = 0.5
为了对 P(x=xi|y=cj)进行概率估计,朴素贝叶斯分类算法假设所有特征都是独立的。因此,对于第 j 个类的输出,我们可以通过分别乘以所有这些特征获得的概率(假设特征是独立的)来计算这一点。
P(x = Xi | y = CJ)= P(x = Xi(1)| y = CJ)P(x = Xi(2)| y = CJ)…。P(x=xi(n)|y=cj)
这里,xi(1)表示第 I 个数据点的第 1 特征的值,x=xi(n)表示第 I 个数据点的第 n 特征的值。
在接受了天真的假设后,我们可以很容易地计算出个体的概率,然后简单地将结果相乘,计算出最终的概率 P’。
使用上面的公式,对于给定的第 I 个数据点,我们可以计算输出 y 属于第 j 类的概率。
这是贝叶斯定理在现实世界中的一个主要应用
Source: giphy.com
根据封面判断一本书..!
原文:https://towardsdatascience.com/judging-a-book-by-its-cover-1365d001ef50?source=collection_archive---------6-----------------------
项目的 GitHub 链接。LinkedIn 简介。
与流行的谚语“不要根据封面来判断一本书”相反,一本书的封面实际上可以用来获得关于这本书的各种信息。一本书的封面通常是第一次互动,它会给读者留下印象。它开始与潜在的读者对话,并开始画一个故事,揭示里面的内容。但是,书的封面上写了什么?
如果光是书的封面就能告诉我们选择这本书作为下一次阅读的所有信息,无论是平均评分、有用的评论、书的页数、作者的详细信息,还是对这本书的更好的总结,会怎么样?如果所有这些信息都是从无数的网站上收集来的,使得信息更加真实,那会怎么样呢?
延伸我对书籍的痴迷,这个项目在计算机视觉和机器学习的帮助下解决了上述问题。
项目鸟瞰图:
这个项目是一个临时版本的 CBIR ( 基于内容的图像检索)系统。一旦用户实时点击书籍封面的图片,我们使用一个三级匹配系统来检索书籍封面的最接近匹配,并根据检索到的书籍封面显示从 Goodreads 和 Amazon 等网站获得的关于书籍各个方面的总结信息。
三级匹配系统:
- 一级: RGB 颜色直方图。
- 第二级:结构相似性指数度量(SSIM)。
- Level-3: 使用 SIFT 特征的 FLANN 匹配。
- 这个三级匹配系统的基本思想是通过在每一级消除不相关的匹配来缩小精确匹配的范围。随着级别的增加,匹配器产生的结果的准确性增加,并且它用于匹配的时间也增加。
- 如果我们在初始级别消除更多的匹配,那么匹配器在下一级别所花费的时间将会减少,但同时潜在的匹配可能已经在前一级别被消除,因此降低了整个系统的准确性。
- 如果我们在初始级别消除非常少的匹配,从而将更多的匹配传递给下一级匹配器,则系统的时间会急剧增加,但系统的准确性不会受到损害。
- 因此,我们减少了每个级别的潜在匹配的数量,但不是通过消除太多的匹配,因此我们在速度和准确性之间进行了微调。
十步流程:
- 第一步:建立一个包含所有可用书籍封面及其各自的 ISBN 号的存储库。
- 第二步:为库中所有的书籍封面图像计算 RGB 颜色直方图。
- 步骤 3: 读入查询书籍封面并计算其颜色直方图。
- 步骤 4: 基于直方图之间的相关性在图像库中搜索查询书封面的最接近匹配。(一级匹配器)。
- 第五步:使用 SSIM 从第四步得到的匹配中搜索与查询书封面最接近的匹配。(二级匹配器)。
- 第六步:使用 FLANN 从第五步得到的匹配中搜索与查询书封面最接近的匹配。(三级匹配器)。
- 步骤 7: 显示 3 级匹配后得到的前 4 个匹配。还显示前 4 个检索图像中匹配的 SIFT 特征的数量。
- 步骤 8: 绘制查询书封面图像与顶部匹配的匹配。
- 第 9 步:创建一个网络爬虫从 Goodreads 和 Amazon 收集信息。
- 步骤-10: 使用顶级匹配的 ISBN 和在步骤-9 中设计的爬虫程序,检索额外的图书信息,如评级数、平均评级、有用评论、图书页数、作者详细信息等。并最终显示所获得信息的汇总版本。
此项目中使用的库:
- OpenCV: 开源计算机视觉是一个主要针对实时计算机视觉的编程函数库。该库拥有超过 2500 种优化算法,包括一套全面的经典和最先进的计算机视觉和机器学习算法。
- Numpy 的主要目标是大型、高效、多维数组表示。这个项目处理大量的图像,每个图像被表示为一个 numpy 数组。将图像表示为 NumPy 数组不仅计算和资源效率高,而且许多其他图像处理和机器学习库也使用 NumPy 数组表示。
- Scikit-image:It是图像处理的算法集合。它包括分割、几何变换、色彩空间处理、分析、过滤、特征检测等算法。它旨在与 Python 数字和科学库 NumPy 和 SciPy 进行互操作。
- Matplotlib: Matplotlib 是一个绘图库。当分析图像时,我们将利用 matplotlib,无论是绘制搜索系统的整体准确性还是简单地查看图像本身,matplotlib 都是您工具箱中的一个伟大工具。
- Imutils: 这个包包含了一系列 OpenCV 和便利函数,执行基本任务,比如平移、旋转、调整大小和骨骼化。这是一个由Adrian rose Brock**开源的精彩而高效的包。**
- ****美汤:是一个从 HTML 和 XML 文件中抽取数据的 Python 库。它与您喜欢的解析器一起工作,提供导航、搜索和修改解析树的惯用方式。BeautifulSoup 的优点是,它可以像解析简单的 XML 一样解析 HTML,并毫不费力地将所需的值(文本)返回给我们。
实施:
****注:本代码中有某些超参数,可根据个人需求进行微调。我对它们进行了调整,在速度和准确性之间找到了一个最佳平衡点。
# Hyper-Parameter for comparing histograms
correl_threshold = 0.9# Hyper-Parameters for SSIM comparision
similarity_index_threshold = 0.0
ssim_matches_limit = 100# Hyper-Parameters for SIFT comparison
sift_features_limit = 1000
lowe_ratio = 0.75
predictions_count = 4# Hyper-Parameters to display results
query_image_number = 2
amazon_reviews_count = 3
第一步:
- 封面数据集可以从 这个 链接下载。该数据集包含来自亚马逊的 207,572 本书。但都是 2017 年之前发行的书。
- 它包含一个 shell 脚本,将 csv 文件作为输入传递给 python 代码。csv 文件包含图书的 ISBN 号,python 代码将根据这些 ISBN 号逐一下载图书封面,并以 ISBN 号作为图像名称保存。
- 亚马逊不允许使用这种脚本高速下载其数据。下载速度会很少,35kbps 左右。按照这种速度,下载所有的书的封面需要将近 2 天的时间。下载失败可能有几个原因,主要原因是亚马逊阻止了这样的脚本。
Figure 1: Download Complete
Figure 2: Download Failed
- 这个问题的快速解决方法是将包含 ISBN 号的 csv 文件(book32-listing . csv)拆分成几个部分,然后在所有这些零碎的 CSV 文件上并行运行 shell 脚本。这样我们可以在几个小时内下载完整的图书封面图片。即使在这种方法中,很少下载会失败,但是我们可以简单地只重新运行该特定片段的 shell 脚本来重试下载。
Figure 3: Parallel download of book covers
第二步:
- 基于内容的图像检索(CBIR)是一种利用视觉属性(如颜色、纹理、形状)来搜索图像的技术。在大型图像数据库中,颜色属性被认为是图像搜索中最常用的低级特征。
- 颜色直方图是一个简单的直方图,显示每个单独的 RGB 颜色通道的颜色级别。由于我们处理的是 RGB 色彩空间,这里的像素值将在 0–255 的范围内。如果您在不同的色彩空间中工作,像素范围可能会有所不同。
- 绘制直方图时,X 轴充当我们的“箱”。如果我们构建一个有 256 个面元的直方图,那么我们可以有效地计算每个像素值出现的次数。然后,在 Y 轴上绘制被装箱到 X 轴值的像素数。在我们的程序中,我们使用的是 RGB 8-bin 颜色直方图。
- 首先让我们导入必要的库。
import os
import cv2
import imutils
import pickle
import numpy as np
注意: Pickle 是一个库,它可以用来序列化或反序列化一个 python 对象,比如一个列表到文本中,并保存到磁盘或从磁盘中检索。通常它们被保存为 pickle 文件。pkl”作为扩展名。
- 接下来,我们将所有下载的书籍封面的路径列表放入一个名为“ train_paths”的 python 列表中。
train_paths = []train_path = "/Users/kartik/Desktop/Projects/Book_Covers_Data/amazon_book_cover_images"for root, dirs, files in os.walk(train_path):
for file in files:
train_paths.append((os.path.join(root, file)))
- 现在,我们遍历书籍封面图像的所有路径,并使用 openCV 逐一读入图像。openCV 的问题在于,它无法读取太阳下的每一种图像格式,例如,它无法读取 gif 图像。即使它不能读取图像, openCV 也不会抛出错误,而是返回一个 NoneType 对象。所以我们需要在计算颜色直方图之前移除所有这样的非类型对象。
- openCV 有很好的内置函数来计算颜色直方图,卡尔奇斯特。默认情况下, openCV 读取的是" BGR" 格式的图像,因此在将图像传递给 calcHist 函数之前,我们将图像的颜色方案从 BGR 转换为 RGB。****
- 我们定义了另一个列表" hist_train" ,它将存储特定书籍封面图像的路径及其相应的颜色直方图。
**hist_train = []for path in train_paths:
image = cv2.imread(path)
if image is None:
continueimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# extract a RGB color histogram from the image,
# using 8 bins per channel, normalize, and update
# the index
hist = cv2.calcHist([image], [0, 1, 2], None, [8, 8, 8],[0, 256, 0, 256, 0, 256])
hist = cv2.normalize(hist, None)
hist_train.append((path,hist))**
- 在计算完所有图像的颜色直方图后,我们可以将这些数据作为 pickle 文件保存到磁盘上。
**# Saving the train data histograms to a pickle filewith open('train_hist_data.pkl', 'wb') as f:
pickle.dump(hist_train, f)**
- 我们可以在以后的任何时候简单地从磁盘加载颜色直方图数据,而不用再次计算所有的直方图。
**# Loading the train data histograms from pickle filewith open('train_hist_data.pkl', 'rb') as f:
hist_train = pickle.load(f)**
注:如果处理器性能相当好,计算所有 207K 图像的直方图将需要相当长的时间。我在一个 16GB 内存的 i7 处理器上花了大约 1 小时 20 分钟。
- 图像的 RGB 颜色直方图可以使用 matplot 库可视化。对于下面的样本书籍封面,其颜色直方图可以如下获得:
**import matplotlib.pyplot as pltimg_path = "/Users/kartik/Desktop/Projects/S_Images/9781501171383.jpg"
img = cv2.imread(img_path)
color = ('b','g','r')
plt.figure(figsize=(15,10))for i,col in enumerate(color):
histr = cv2.calcHist([img],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.show()**
Figure 5: RGB Colour Histogram
第三步:
- 我从这些 207k 图像中创建了一组查询/测试图像,通过随机选取一组图像并对这些图像应用仿射变换并添加一些剪切。完成这些变换是为了紧密模仿从移动设备拍摄的实时图像。**
Figure 6: Images before and after applying Affine Transformation with Shear = 0.1
- 类似于步骤 2 中的程序,我们读入所有查询书籍封面,并计算它们的 RGB 颜色直方图。**
**query_path = "/Users/kartik/Desktop/Projects/Book_Covers_Data/Test_Images"
query_paths = imlist(query_path)hist_query = []
for path in query_paths:
image = cv2.imread(path)
if image is None:
continue
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# extract a RGB color histogram from the image,
# using 8 bins per channel, normalize, and update the index
hist = cv2.calcHist([image], [0, 1, 2], None, [8, 8, 8],[0, 256, 0, 256, 0, 256])
hist = cv2.normalize(hist, None)
hist_query.append((path,hist))**
第 4 步(一级匹配器):
- 在步骤 2 中,我们已经索引了整本书封面的所有颜色直方图。并且在步骤 3 中,我们已经计算了查询书籍封面的颜色直方图。现在,我们必须将这些查询书封面直方图与我们的训练数据库中的直方图进行比较,我们必须找出最接近的直方图。****
- openCV 中内置了 函数 来比较直方图,但是有几个比较度量可以选择。*相关、卡方、交集、巴特查亚距离、海灵格距离。*
注:比较指标也是一个超参数,可以根据正在处理的数据及其应用进行微调。
- 对于本项目,使用来自 openCV 的相关性作为比较指标。使用相关性作为比较度量的 cv2 直方图比较函数的输出值将给出 0 到 1 范围内的值。越接近 1 的值是越相似的直方图。**
- 在比较直方图之后,我已经按照返回的相关值的非递减顺序对结果进行了排序,并且仅将相关值高于"相关阈值"的匹配视为潜在匹配,并且丢弃了其他匹配。**
- "相关性阈值"是一个超参数,可以根据个人需求进行微调。基于对该书封面数据的几次试验,较高的相关阈值消除了大多数非潜在匹配。但是,过高的值也会消除潜在的匹配,从而降低匹配器的准确性。**
- 由于我正在处理一个 207K 图像的数据集,所以我将“相关性阈值”的值设置为 0.9。如果数据集中的图像数量很少,比如大约 3k,那么作为相关阈值的值 0.5 将产生更好的结果。****
*hist_matches = []for i in range(len(hist_query)):
matches = []
for j in range(len(hist_train)):
cmp = cv2.compareHist(hist_query[i][1], hist_train[j][1], cv2.HISTCMP_CORREL)
if cmp > correl_threshold:
matches.append((cmp,hist_train[j][0]))
matches.sort(key=lambda x : x[0] , reverse = True)
hist_matches.append((hist_query[i][0],matches))*
- 基本上,这里我们将查询书籍封面的直方图与数据库中 207k 书籍封面的所有 207k 直方图进行比较。在这一步的最后,我们过滤掉大约 800 到 1000 个潜在的匹配。在该步骤结束时获得的潜在匹配的数量主要取决于相关阈值。这些过滤后的 1k 结果被传递到下一级。**
步骤 5(二级匹配器):
- 比较图像的另一个重要的图像描述符是图像的纹理。在比较图像时,均方差(MSE)虽然易于实现,但并不能很好地表明感知的相似性。结构相似性旨在通过考虑纹理来解决这一缺点。SSIM 试图模拟图像结构信息的感知变化。
- 比较两幅图像时,结构相似性指数(SSIM)返回的值介于-1 到 1 之间。指数越接近值 1,表示两幅图像非常相似。
- 现在,我们将查询 book-cover 与上一步获得的 1k 左右的潜在匹配进行比较,并根据获得的相似性指数的非降序对结果进行排序。**
- 相似性指数也是一个超参数,我已经将其设置为 0。我认为任何具有正值相似性指数的匹配都是潜在的匹配,我会将该匹配传递到下一级进行进一步匹配。**
*from skimage.measure import compare_ssim as ssimdef similarity_index(q_path,m_path):
q_i = cv2.imread(q_path,0)
q_i = cv2.resize(q_i,(8,8))
m_i = cv2.imread(m_path,0)
m_i = cv2.resize(m_i,(8,8))
return ssim(q_i,m_i)ssim_matches = []for i in range(len(hist_matches)):
query_image_path = hist_matches[i][0]
matches = []
for j in range(len(hist_matches[i][1])):
match_image_path = hist_matches[i][1][j][1]
si = similarity_index(query_image_path,match_image_path)
if si > similarity_index_threshold:
matches.append((si,match_image_path))
matches.sort(key=lambda x : x[0] , reverse = True)
ssim_matches.append((query_image_path,matches[:ssim_matches_limit]))*
- 我还使用超级参数 ssim-matches-limit 来限制获得的匹配数。我将值设置为 100 作为限制,因此只将这一步中获得的前 100 个匹配传递到下一级匹配。
第六步(三级匹配器):
- 匹配不同图像的特征是计算机视觉中的一个常见问题。当所有图像在性质上相似(相同的比例、方向等)时,简单的角点检测器可以工作。但是当你有不同尺度和旋转的图像时,你需要使用尺度不变特征变换(SIFT)。**
- 我们想要与图像的“部分”相对应的特征,在比原始像素更整体的水平上。我们想要的功能是不敏感的图像分辨率,比例,旋转,照明变化(如灯的位置)的变化。SIFT 算法会做到这一点。
- 在将图像传递给 openCV 的 SIFT 函数时,它会返回关键点:我们所有感兴趣点的 x、y 和八度音程位置,以及方向。关键点具有比例不变性和旋转不变性。它还为每个关键点生成描述符,不使用原始亮度值,而是通过计算每个像素的梯度。**
- 生成的 SIFT 关键点的数量也是一个超参数。它可以根据计算能力和可用的内存资源进行微调。我已经为生成的 SIFT 特征设置了 1000 个关键点的限制。**
*def gen_sift_features(image):
sift = cv2.xfeatures2d.SIFT_create(sift_features_limit)
# kp is the keypoints
#
# desc is the SIFT descriptors, they're 128-dimensional vectors
# that we can use for our final features
kp, desc = sift.detectAndCompute(image, None)
return kp, desc*
- 我们为在步骤-5(二级匹配器)之后获得的每个潜在匹配生成 SIFT 关键点&描述符,并将它们与查询图书封面的 SIFT 关键点&描述符进行比较。使用FLANN-Matcher完成关键点的比较。FLANN 是一个用于在高维空间中执行快速近似最近邻搜索的库。**
*# FLANN matcher
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50) # or pass empty dictionary
flann = cv2.FlannBasedMatcher(index_params,search_params)*
- " FLANN-Matcher" 将返回两幅图像的关键点之间的匹配数量。这里的“劳氏比”是另一个超参数,过滤掉 FLANN-Matcher 结果中的弱关键点匹配。理想比值在 0.75 左右。现在,我们按照关键点匹配计数的非递减顺序对潜在匹配进行排序。**
*predictions = []
for i in range(len(ssim_matches)):
matches_flann = []
# Reading query image
q_path = ssim_matches[i][0]
q_img = cv2.imread(q_path)
if q_img is None:
continue
q_img = cv2.cvtColor(q_img, cv2.COLOR_BGR2RGB)
# Generating SIFT features for query image
q_kp,q_des = gen_sift_features(q_img)
if q_des is None:
continue
for j in range(len(ssim_matches[i][1])):
matches_count = 0
m_path = ssim_matches[i][1][j][1]
m_img = cv2.imread(m_path)
if m_img is None:
continue
m_img = cv2.cvtColor(m_img, cv2.COLOR_BGR2RGB)
# Generating SIFT features for predicted ssim images
m_kp,m_des = gen_sift_features(m_img)
if m_des is None:
continue
# Calculating number of feature matches using FLANN
matches = flann.knnMatch(q_des,m_des,k=2)
#ratio query as per Lowe's paper
matches_count = 0
for x,(m,n) in enumerate(matches):
if m.distance < lowe_ratio*n.distance:
matches_count += 1
matches_flann.append((matches_count,m_path))
matches_flann.sort(key=lambda x : x[0] , reverse = True)
predictions.append((q_path,matches_flann[:predictions_count]))*
第七步:
- 现在,我们从在步骤 6(3 级匹配器)中获得的预测中,为给定的查询图书封面挑选出前 4 个预测图书封面,并将它们与关键点匹配的计数一起绘制出来。**
Figure 7: Top-4 Predictions
第八步:
- 我们选择最有可能与我们的查询书封面相同的顶部预测图像,并且我们可以绘制精确的 SIFT 关键点匹配。
Figure 8: SIFT keypoint matches
第九步:
注:以下刮刀仅用于教育目的。
- 现在我们使用 python 抓取框架创建一个网络爬虫,比如 BeautifulSoup。我们创建了两个独立的 scrappers,一个用于 Goodreads,另一个用于 Amazon。这些刮削器将图书的 ISBN 号作为输入,并根据它刮削页面。
Goodreads Scrapper
*def book_details_goodreads(isbn):
# Goodreads Scraping
goodreads_base_url = "[https://www.goodreads.com/book/isbn/](https://www.goodreads.com/book/isbn/)"
goodreads_url = goodreads_base_url + isbn
req = Request(goodreads_url, headers={'User-Agent': 'Mozilla/5.0'})
page = urlopen(req).read().decode("utf-8")
soup = BeautifulSoup(page, 'html.parser')
# Book Title
book_name = soup.find(itemprop="name")
book_name = str(book_name)
book_name = remove_tags(book_name)
book_name = book_name.strip()
book_name_list = book_name.split(" ")
# Author Names
author_names = soup.find_all("span",itemprop="name")
author_names = str(author_names)
author_names = author_names.split(",")
author_name = author_names[0]
author_name = author_name.split(">")[1].split("<")[0]
for i in range(len(author_names)):
author_names[i] = author_names[i].split(">")[1].split("<")[0]
author_names_text = ""
for i in range(len(author_names)):
author_names_text += str(author_names[i])
author_names_text += ", "
# Number of Ratings
rating_count = soup.find(itemprop="ratingCount")
rating_count = str(rating_count)
rating_count = rating_count.split('"')[1]# Average Rating
rating_val = soup.find(itemprop="ratingValue")
rating_val = str(rating_val)
rating_val = remove_tags(rating_val)
# Number of pages in book
pg_count = soup.find("meta", property="books:page_count")
pg_count = str(pg_count)
pg_count = pg_count.split('"')[1]
# Book Description
desc = soup.find("div", id="description")
if desc is not None:
desc = desc.find_all("span",style="display:none")
if desc is not None:
desc = str(desc)
desc = remove_tags(desc)
description = desc.strip("[]")
description = description.strip()
else:
description = "No description found"
else:
description = "No description found"# Printing book details from Goodreads
printmd('**Book Details from Goodreads\n**')
#print("Book Details from Goodreads\n")
print("Book Title: ",book_name.splitlines()[0])
#print("\n")
print("Authors: ",author_names_text)
#print("\n")
print("Average Rating: ",rating_val)
#print("\n")
print("Number of ratings: ",rating_count)
#print("\n")
print("Number of pages in book: ",pg_count)
print("\n")
print("Book Description:")
print("\n")
print(description)*
亚马逊废品店
*def book_details_amazon(isbn):
# Amazon Scraping
amazon_base_url = "[https://www.amazon.com/dp/](https://www.amazon.com/dp/)"
amazon_url = amazon_base_url + isbn
req = Request(amazon_url, headers={'User-Agent': 'Mozilla/5.0'})
page = urlopen(req).read().decode("utf-8")
soup = BeautifulSoup(page, 'html.parser')
# Book title
a_title = soup.find_all("span",id="productTitle")
a_title = str(a_title)
a_title = remove_tags(a_title)
a_title = a_title.strip("[]")
a_title = a_title.strip()
# Book details
book_info = []
for li in soup.select('table#productDetailsTable div.content ul li'):
try:
title = li.b
key = title.text.strip().rstrip(':')
value = title.next_sibling.strip()
value = value.strip("()")
book_info.append((key,value))
except AttributeError:
break
# Amazon reviews scraping
amazon_review_base_url = "[https://www.amazon.com/product-reviews/](https://www.amazon.com/product-reviews/)"
amazon_review_url = amazon_review_base_url + isbn + "/ref=cm_cr_getr_d_paging_btm_2?pageNumber="
req = Request(amazon_review_url, headers={'User-Agent': 'Mozilla/5.0'})
page = urlopen(req).read().decode("utf-8")
soup = BeautifulSoup(page, 'html.parser')
# List of book reviews in Amazon
reviews_list = []
reviews_list_final = []
for pg in range(1,5):
amazon_review_url = amazon_review_base_url + isbn + "/ref=cm_cr_getr_d_paging_btm_2?pageNumber=" + str(pg)
req = Request(amazon_review_url, headers={'User-Agent': 'Mozilla/5.0'})
page = urlopen(req).read().decode("utf-8")
soup = BeautifulSoup(page, 'html.parser')txt = soup.find("div", id="cm_cr-review_list")
try:
for rawreview in txt.find_all('span', {'class' : 'a-size-base review-text'}):
text = rawreview.parent.parent.parent.text
startindex = text.index('5 stars') + 7
endindex = text.index('Was this review helpful to you?')
text = text[startindex:endindex]
text = text.split("Verified Purchase")[1]
rText = text.split(".")[:-1]
review_text = ""
for i in range(len(rText)):
review_text += rText[i]
review_text += "."
if review_text is not "":
if "|" not in review_text:
reviews_list.append(review_text)
else:
rText = text.split(".")[:-2]
review_text = ""
for x in range(len(rText)):
review_text += rText[x]
review_text += "."
reviews_list.append(review_text)
except AttributeError:
review_text = "No reviews found."
if amazon_reviews_count < len(reviews_list):
reviews_list_final = reviews_list[:amazon_reviews_count]
else:
reviews_list_final = reviews_list
# Printing book details from Amazon
printmd('**Book Details from Amazon\n**')
#print("Book Details from Amazon\n")
print("Book Title: ",a_title)
#print("\n")
for i in range(len(book_info)):
print(f"{book_info[i][0]} : {book_info[i][1]}")
#print("\n")
print("\n")
if len(reviews_list_final) == 0:
print(review_text)
print("\n")
else:
print(f"Displaying top {amazon_reviews_count} book reviews:\n")
for i in range(len(reviews_list_final)):
review_txt_list = reviews_list_final[i].split(".")[:3]
review_txt = ""
for j in range(len(review_txt_list)):
review_txt += review_txt_list[j]
review_txt += "."
review_txt += ".."
print(review_txt)
print("\n")*
第十步:
- 我们将在第 7 步结束时获得的最佳匹配的 ISBN 号作为输入传递给上面的 Goodreads 和 Amazon scrappers,并显示获得的信息。**
*isbn = predictions[query_image_number][1][0][1].split("/")[-1].split(".")[0]book_details_goodreads(isbn)*
*book_details_amazon(isbn)*
结论:
结果:
- 基于对超参数的微调,该系统给出了大约 90%的准确率,并且检索单个查询书籍封面的结果所花费的平均时间大约为 20 秒。这里总是在速度和准确性之间进行权衡。当我们试图减少周转时间时,精度也会降低。**
进一步改进:
- 在建立所有书籍封面的颜色直方图储存库时,可以添加诸如 K-Means 的聚类算法。
- 我们可以用 CNN 代替 SIFT 从图像中提取特征。
- 图像库可以在爬虫的帮助下更新,从亚马逊和 Goodreads 抓取最新的书籍封面。
- 相同的项目可以扩展到移动应用程序,但是复杂的计算在服务器端完成。
希望你喜欢这个教程。感谢阅读..!
Julia 及其在数据科学中的用途
原文:https://towardsdatascience.com/julia-and-its-usefulness-in-data-science-6e9181504ff4?source=collection_archive---------0-----------------------
作者:扎卡里亚斯·沃尔加里斯
Julia 是一种相对较新的编程语言,由麻省理工学院的一组研究人员为数据科学开发。不像其他擅长利基用例的编程语言,Julia 是一种面向各种应用程序和更多受众的多用途语言。最近,随着越来越多的包进入 Julia 生态系统,它在数据科学中的有用性变得更加明显。
Julia 是一种很好的通用编程语言,因为它有六个要点。首先,它轻便高效。为了运行相对复杂的 Julia 脚本,您不需要拥有最先进的机器。事实上,在一些用例中,Julia 使用了非常轻量级的计算机,比如微型计算机,来实时执行计算密集型操作。这在新数据科学和数据工程中特别有用,因为它允许更好地利用现有资源。
Julia 的另一个优势是可伸缩性。很难高估这种优势的价值,尤其是。在当今的大规模数据世界中。Julia 不需要大数据框架来扩大规模。向运行 Julia 的系统添加更多的资源,并在 Julia 内核上运行必要的命令,可以让您的脚本以相当直接的方式进行扩展。不用说,这对数据科学至关重要。
Julia 也是一种多调度语言。这允许它有更直观的函数名,可以处理多个任务,这取决于您给它们的输入。因此,您可以拥有一个可以处理所有变量的函数,而不是拥有一堆相同函数的不同变体,每个变体都专用于一组特定的参数,Julia 可以选择最适合您提供给该函数的参数的方法。这使得函数池更容易理解和记忆,可以在数据科学项目中使用。
与其他一些语言不同,Julia 与开发人员和数据科学家中流行的现有编程语言集成得很好。比如你可以通过 Julia 调用一个 C,Python,R 脚本。这使得将 Julia 集成到您的工作流中变得更加容易,促进了整个数据科学管道。
此外,Julia 是一种高级语言,使得理解和管理 Julia 脚本更加容易(即使您不是这种语言的专家)。这与这种语言的另一个优势联系得很好,那就是它的易学性。如果您的团队中有数据科学家需要为某个特定项目学习它,这一点尤其重要,一般来说,完成这一任务不需要花费太多时间或资源。
正如我们之前提到的,Julia 是一种高性能语言。在相应的图形中可以看到,其性能与计算机科学中使用多年的低级语言 C 和 Fortran 不相上下。这一点怎么强调都不为过。Julia 与难以编写代码的语言不相上下(这通常是那些学习编程多年的软件开发人员所做的事情)。然而,用这种语言创建原型是相当容易的。因此,Julia 解决了两种语言的问题,当涉及到数据科学应用程序时,您可以使用一种语言(通常是 Python 或 R)创建 PoC,而使用另一种语言(通常是 C++或 Java)在生产中实现它。
朱莉娅吸引了科学界和工业界的许多人。这导致了包和库的开发,它们与用低级语言编写的包和库一样高效。因此,毫不奇怪,Julia 社区正在迅速发展,它已经成为跨不同行业的灵活工具。它会成为下一个数据科学语言吗?很有可能。你会从中受益吗?嗯,那主要取决于你。
如果你正在寻找一种直接的方法来学习如何在数据科学中使用 Julia,我教了一门 8 周 50 小时的课程。点击此处查看更多详情。
七月版:深入 ML 应用
原文:https://towardsdatascience.com/july-edition-taking-a-deep-dive-into-ml-applications-258c8f0c07d2?source=collection_archive---------5-----------------------
探索当今 ML 应用的 5 篇文章
读者们——新的一个月又开始了。上个月,我们一直在关注如何做,以及关于可视化和指南的有用文章。这个月,我们决定研究机器学习的一些令人惊叹的应用。
从天气,到医学和房地产,再到游戏建议,这里有一些关于人工智能应用的新文章!
通过智能游戏推荐提高用户参与度
Andre Tan 讲述了在 Playphone 等手机游戏发行公司构建推荐引擎的过程。他解决了非主动用户的问题,以及建议用户尝试相关游戏的方法如何对游戏商店的成功至关重要。
AI 如何做你的营养师,预防糖尿病
糖尿病是一种主要的健康负担,影响着全球 8.5%的成年人口,其并发症包括中风、心脏病发作、肾衰竭和视力丧失等。餐后血糖反应- PPGR -是 2 型糖尿病的主要危险因素,并且在个体之间差异很大。仍然没有现有的方法可以准确预测 PPGR,目前的模型仍然依赖于碳水化合物计数,这不能提供良好的预测。在本文中,关朝聪利用机器学习解决了这个问题。
房地产摇钱树
利用轻松获取关于位置、我们如何移动、我们停留多久、我们支付多少以及我们的感受的数据, Easy Atlas 通过三个案例场景:1) 在巴黎开一家咖啡馆,2) 在上海投资住宅房地产,以及 3) 在纽约市开设一家夜总会,来展示数据如何帮助我们做出这些决定。
挖掘社交媒体通知雾霾应对
为了应对森林和泥炭地火灾或烟雾事件,灾害管理机构需要火灾热点信息以及基线信息,例如受影响人口的估计和可用设施的数据。Jakarta Pulse Lab与卡塞尔大学的研究人员合作,测试社交媒体帮助应对雾霾的潜力。
Stock2Vec —从 ML 到 P/E
在本文中,Jon Perl 使用机器学习算法 Word2Vec 尝试对股票市场中的类似公司进行分组。
我们也感谢最近加入我们的所有伟大的新作家埃文·贝克、那华·康、马尼什·沙布拉尼、米歇尔·格林、普拉那瓦西亚尼 G 、奥菲尔·萨姆森、安德鲁·皮尔诺、杰罗姆·萨姆森、李·施伦克、马库斯·奥贾拉 杰森·科瓦尔、罗布·托马斯、阿瑟·格雷顿、肯尼·琼斯、李·罗布、埃里克森、越武、约翰内斯·里克、拉维·谢哈尔、阿尼什·辛格·瓦利娅等众多。
Inês Teixeira。
七月版:文本理解
原文:https://towardsdatascience.com/july-edition-text-understanding-adaaff0bbd63?source=collection_archive---------4-----------------------
8 篇必读文章
自然语言处理从业者指南
由迪潘然(DJ)萨卡尔 — 31 分钟阅读。
非结构化数据,尤其是文本、图像和视频包含了丰富的信息。然而,由于处理和分析这些数据的固有复杂性,人们通常不会花费额外的时间和精力从结构化数据集冒险出来分析这些非结构化数据源,这可能是一座潜在的金矿。
如何用深度学习为任意对象创建自然语言语义搜索
通过哈默尔侯赛因 — 13 分钟读取。
现代搜索引擎的力量是不可否认的:你可以随时从互联网上获取知识。不幸的是,这种超级力量并非无处不在。在许多情况下,搜索被归为严格的关键字搜索,或者当对象不是文本时,搜索可能不可用。
使用 Scikit-Learn 进行多类文本分类
由苏珊李 — 11 分钟读完。
文本分类在商业领域有很多应用。例如,新闻故事通常是按主题组织的;内容或产品通常按类别进行标记;用户可以根据他们在网上谈论产品或品牌的方式进行分类…
将机器学习模型嵌入 Web 应用
由查敏·娜琳达 — 12 分钟读完。
学习数据科学的最佳方式是实践,没有其他选择。在这篇文章中,我将反映我如何开发一个可以将电影评论分为正面或负面的机器学习模型,以及如何将该模型嵌入到 Python Flask web 应用程序中。
谁在椭圆形办公室发推特?
由格雷格·拉弗蒂——18 分钟读完。
我开发了一个推特机器人@ who sintheval,它转发唐纳德·特朗普的每一条推文,并预测这条推文是由特朗普本人还是他的一名助手写的。请务必在 Twitter 上关注这个机器人,并继续阅读以了解我是如何构建这个模型的!
川普,用他自己的话说
由亚历克斯·p·米勒 — 5 分钟阅读。
唐纳德·特朗普(Donald Trump)在 2016 年总统竞选过程中的优先事项发生了怎样的变化?随着竞选的临近,他在移民问题上变得更强硬了吗?还是他把重心转移到了经济上?他什么时候开始谈论希拉里的邮件的?
变型自动编码器作为双人游戏
通过最大 Frenzel — 17 分钟读取。
本系列文章的目的是使可变自动编码器和自然语言编码背后的基本思想尽可能容易理解,并鼓励已经熟悉它们的人从新的角度来看待它们。
LDA2vec:主题模型中的单词嵌入
由 Lars Hulstaert — 11 分钟读取。
主题模型的一般目标是产生可解释的文档表示,这些表示可用于发现未标记文档集合中的主题或结构。这种可解释文档表示的一个例子是:文档 X 20%是主题 a,40%是主题 b,40%是主题 c。
利用研究助教奖学金进入微软
原文:https://towardsdatascience.com/jump-start-into-ms-with-research-assistantship-1f9a792590ff?source=collection_archive---------9-----------------------
来到机会之地:美国,已经一个月了。到目前为止,这是一次美妙的旅程,我很喜欢。所以,回到印度后,我有两个选择,是去达索系统公司做一名 R&D 的助理开发工程师,还是去锡拉丘兹大学信息研究学院攻读应用数据科学硕士。正如你从标题中理解的那样,你知道我做了哪个选择。如果你不知道,让我告诉你,《美国新闻》将锡拉丘兹大学信息学院的信息项目列为全美第二。为抵达美国做准备是一段艰难的时光,但我享受其中的每一刻。我于 2018 年 8 月 6 日抵达美国纽约锡拉丘兹的汉考克国际机场。这里的天气不可预测,但相对凉爽。到目前为止,美国没有让我失望,因为它是一种不同的文化,人们更加友好和外向,但我想念我的家人,朋友和最后但并非最不重要的“假期”。大学有一个巨大的校园,占地 700 多英亩,位于城市环境中,拥有最先进的基础设施和设备。
闲话少说,让我开门见山:我是如何从第一学期就获得研究助教奖学金的?我说“助教奖学金”了吗?对不起,我指的是“助教奖学金”:让我带你看一下整个过程。
我什么时候接触过老师了?
我在 2018 年 5 月中旬完成了我的本科学业,在家里无所事事。许多人告诉我,你通常不会在第一学期获得助教奖学金,但这总是值得一试。我最初在大学网站上浏览了教员的研究概况。每所大学都有教师网页,在那里你可以找到教授们目前参与的所有有趣的东西。我列出了与我的研究兴趣有交集的五位教授的候选名单,并在 5 月底之前发送了关于我对他们工作的兴趣的电子邮件。
我在那些邮件里写了什么?
教授们确实会收到很多关于他们实验室工作的电子邮件,同时他们也非常忙。你的电子邮件中应该有一个能引起教授注意的钩子。钩子?伙计,你说的钩子是什么意思?等等,我在解释。实际上,你的电子邮件有两个主要的吸引读者的地方。主题:人们习惯写各种各样的主题,比如“未来的研究助理——2018 年秋季”,“你实验室的 RA/GA/TA”等等,但是它包含教授感兴趣的东西吗?没有。他/她为什么会打开你的邮箱?在这个繁忙的时刻,教授们已经收到了很多类似的电子邮件。这就是为什么第一个钩子是主题行。对我有用的是:对你教授的研究做适当的功课,找到你研究兴趣的交叉点。然后,你可以把主题简单地写成“[研究兴趣] —在你的实验室工作”。这是不是太简单了,但它确实有效;
)2。开篇:这是大多数学生犯的一个错误,他们介绍了自己,并对自己说了很多废话。如果教授打开你的电子邮件,他很少有机会阅读你的第二段,因为你在第一段吹嘘自己,浪费了这个机会。第一段应该基于你对教授做的家庭作业:谈论他的项目、论文、兴趣。这是人类的一种倾向,他们喜欢听到关于他们自己的事情。它不应该超过 3-4 行,然后巧妙地将它与你觉得这些东西有趣的原因联系起来。我确实用一句话把它和我过去做过的一个项目联系起来。现在,教授知道你值得他/她的时间,因为你自己已经研究过他/她的兴趣和工作。现在你们两个都有共同的兴趣,他/她可能会看第二段,在那里你简要介绍自己,并描述与教授相关的所有工作。如果你想要一个很长的第二段,或者分成 4-4 行的段落,总共最多 3 段关于你自己和你的工作,这完全取决于你。确保一切都与你想做的工作类型相关。
你认为你现在都准备好了吗?啊哈。一定要写下结束语,直截了当地问你想要什么。你可以礼貌地问“我想知道你的实验室是否有一个为你的研究做贡献的空缺职位”,并以注明你已经放在邮件中供教授参考的所有附件结束这一段。你在说什么依恋,伙计?你至少应该附上你的简历,但你可以添加更多像实习信,论文(即使是未发表的,因为它是你的学术写作样本的例子)和项目报告。
嗯……就这些?不,还有更多。15 天后,如果你没有收到任何回复,你可以发一封提醒邮件,因为他们有时会因为忙碌而错过邮件。让我们回到我的故事,我说到哪里了?是的,我告诉你我在五月底给五位教授发了电子邮件。第一天,第二天,第三天,第四天,我得到了一位教授的第一次回复,他说我的背景非常适合他/她的研究,并要求我在来锡拉丘兹之前阅读一些技术。哦,那是积极的。在发出提醒邮件后,我又收到了两封回复,其中一封说他/她想在我到达锡拉丘兹大学后和我面谈,猜猜那个教授是我最优先考虑的。
我在八月初到达锡拉丘兹,然后给他们发电子邮件告知我的到达。他们很忙,面试被安排在八月的第三周。与此同时,我知道系里有一个门户网站,上面贴出了所有学院研究助理的职位空缺,找到一个好职位后,我就去申请了。就在一天之内,我得到了一个面试的机会,面试是在接到通知的第二天,因为教授在那之后几周都不在城里。关于面试,确保你知道你写在简历上的所有内容,并准备好回答深层次的概念性问题。我在第一次面试中被盘问,除了我的简历之外,还问了一些关于优化模式匹配算法、微积分和数学的问题。不要犹豫地说“你不知道”,不要试图愚弄教授,因为他们是你所用技术的大师。最终,我完成了对不同教授的三次面试,幸运的是,他们都给了我一份工作,让我在他们各自的实验室做研究助理。我的假新闻检测项目(听起来很棒?但这是美国著名的研究课题)和在印度人类住区研究所的实习经历在面试中发挥了至关重要的作用。
In-front of School of Visual and Performing Arts, Syracuse University
这是一种幸福的结局,对不对?我最终决定与 Jennifer Stromer-Galley 教授合作进行启发性项目,开发机器学习算法和自然语言处理技术,以跟踪脸书和推特上大约 1100 名 2018 年联邦选举的候选人。该项目得到了奈特基金会、哥伦比亚大学数字新闻 Tow 中心、锡拉丘兹大学信息研究学院计算和数据科学中心以及 BITS 实验室的支持。那都是乡亲们!在 gmail dot com 的[我的名字][我的名字]或我的LinkedIn上提问。关于这项工作的更新即将推出。
六月版:概率、统计和机器学习
原文:https://towardsdatascience.com/june-edition-probability-statistics-machine-learning-fab82bbe36b2?source=collection_archive---------5-----------------------
10 篇必读文章
解释概率概念(介绍、最大似然估计、参数估计的贝叶斯推断)。
琼尼·布鲁克斯-巴特利特——30 分钟阅读
这些年来,我阅读了许多关于概率论不同方面的文本和文章,每一篇似乎都需要不同程度的先决知识来理解正在发生的事情。我绝不是这一领域的专家,但我觉得我可以通过写一系列通俗易懂的文章来解释概率中的各种概念。
数据科学家需要掌握的 10 项统计技术
由詹姆斯·勒 — 15 分钟读完
不管你站在数据科学性感的立场上,都不可能忽视数据的持续重要性,以及我们分析、组织和联系数据的能力。
对匆忙人群的统计
凯西·科济尔科夫(Cassie Kozyrkov)—8 分钟阅读
曾经希望有人能告诉你统计学的要点是什么,术语用简单的英语表达是什么意思吗?让我试着帮你实现这个愿望吧!我将在 8 分钟内快速浏览统计学中所有最重要的观点!或者只有 1 分钟,如果你坚持使用大字体的话。
你需要知道的数据科学概念!
迈克尔·巴伯 — 27 分钟阅读
这一系列帖子旨在介绍并快速发展数据科学和数据分析中的一些核心概念,并特别关注我觉得在其他材料中被忽略或简单处理的领域。
超越准确度:精确度和召回率
由威廉·科尔森 — 11 分钟阅读
你会相信一个声称完全在大脑中创造了一个模型的人以超过 99%的准确率识别试图登机的恐怖分子吗?
陌生事物:分析和交流数据的五堂课
到乔丹·德沃金 — 8 分钟阅读
作为一名统计领域的研究生,我很快意识到,不与数据打交道的人对统计这个词通常会有两种反应:“哦,我讨厌那门课!”和“你一定很喜欢数学!”
如何在数据科学面试中胜出:统计学
由卡森·福特 — 9 分钟阅读
对于从事或试图从事数据科学工作的人来说,统计学可能是你需要发展的最大和最令人生畏的知识领域。这篇文章的目标是把你需要知道的东西减少到有限数量的具体想法、技术和方程式。
平均而言,您使用了错误的平均值
丹尼尔·麦克尼克 — 19 分钟阅读
你有一堆数字。你想用更少的数字来概括它们,最好是单个数字。所以你把所有的数字加起来,然后除以数字的总数。嘣:看“平均值”,对吧?
主成分分析的一站式商店
通过哑光 Brems — 15 分钟读取
主成分分析(PCA)是统计学和数据科学领域中需要理解的一项重要技术……但是在为我的学生组织课程时,我发现网上的资源技术性太强,没有完全满足我们的需求,并且/或者提供了相互矛盾的信息。
解释机器学习模型
作者拉尔斯·赫尔斯特 — 8 分钟阅读
不管您的数据科学解决方案的最终目标是什么,最终用户总是更喜欢可解释和可理解的解决方案。
6 月版:自动驾驶汽车
原文:https://towardsdatascience.com/june-edition-self-driving-cars-79566d11fbf0?source=collection_archive---------7-----------------------
你必须阅读的 6 篇关于自动驾驶汽车的文章。
卡尔曼滤波器:直觉和离散情况推导
由 Vivek Yadav — 6 分钟阅读。
在这篇文章中,我们将回顾离散卡尔曼滤波器的推导过程。我们将首先建立由离散动态控制的系统的方程,然后表达近似系统,计算误差协方差并计算最小化误差协方差的更新规则。由于经由卡尔曼滤波的估计涉及连续的测量和状态传播,所以在离散实现的情况下它们更容易理解。
车辆检测与跟踪
由伊万·卡萨科夫 — 7 分钟读完。
这是 Udacity 的自动驾驶汽车工程师纳米学位项目第一学期的最后一个项目。源代码和更详细的技术文章可以在 GitHub 上找到
自动驾驶汽车如何转向
由 Priya Dwivedi — 5 分钟阅读。
典型的自动驾驶汽车从感知系统开始,该系统估计周围环境的状态,包括地标、车辆和行人。
帮助无人驾驶汽车自我定位
由 Priya Dwivedi — 4 分钟阅读。
定位,或者说知道“我在哪里”对于自动驾驶汽车来说至关重要。每时每刻它都需要知道自己在世界的哪个角落。当我们开车时,我们使用 GPS 和地图应用程序来知道我们的车在哪里。但是 GPS 的精度是 1-3 米,有时更高。这不适用于自动驾驶汽车,因为这是车道的宽度。
用深度学习进行车道检测(第一部分 & 第二部分
由迈克尔处女座 — 10 & 9 分钟阅读。
即使在各种各样的条件下,人们也可以相当容易地找到道路上的车道线。除非有雪覆盖地面,降雨量非常大,道路非常脏或年久失修,我们可以告诉我们应该去哪里,假设这些线实际上是有标记的。
需要视觉
由 Harish Vadlamani — 13 分钟阅读。
嗯,我做到了!我终于完成了 Udacity 自动驾驶汽车 Nanodegree 的第一学期。至少可以说,过去的三个月是一段坎坷的旅程,我已经成功地克服了这段时间所面临的障碍,无论是实际上还是象征性的!
我们也感谢最近加入我们的所有伟大的新作家彼得·斯威尼、马丁·施密茨、博士、关朝聪、约翰尼·邓恩、狄奥尼索斯·鲍威尔、阿比吉特·勃拉姆斯、萨纳坦·米什拉、迈克尔·何、埃里克·兰根伯格、伊万·卡萨科夫、 胡安.马特奥斯-加西亚、科伦廷·杜古埃、泰勒·基利安、布伦丹·贝利、克里斯·文泰歇尔、巴拉兹·凯格尔、犹他工程、亨里克·林德伯格等众多。
tmux 和 ssh 中的 Jupyter 和 tensorboard
原文:https://towardsdatascience.com/jupyter-and-tensorboard-in-tmux-5e5d202a4fb6?source=collection_archive---------4-----------------------
在最近的帖子中,我描述了如何设置你的个人深度学习工作站以及如何打开并远程访问它。
在这篇短文中,我解释了我通常如何用 tmux 设置我的远程工作环境,并在我的手机上检查我的计算进度。
tmux 是一个终端复用器,允许用户在单个终端窗口或远程终端会话中访问多个独立的终端会话。
首先,将以下几行添加到您笔记本电脑上的.ssh/config
中。看这里,如果你想要更详细的关于如何远程访问你的电脑的指导。
Host workstation
HostName <hostname>
User <username>
Port <port>
LocalForward 8888 localhost:8888
LocalForward 6006 localhost:6006
现在输入ssh workstation
就可以登录了。键入tmux new -s <sessionname>
来启动 tmux。我通常通过键入Ctrl-b %
垂直分割屏幕,然后通过键入Ctrl-b "
水平分割屏幕。使用Ctrl-b o
可以导航到下一个窗格。我通常会打开右上方的窗格,用source active <name>
启动我的虚拟环境,然后通过键入jupyter-notebook
启动一个 jupyter 笔记本。将链接复制到笔记本电脑的浏览器中。接下来,我们开始 tensorboard。键入Ctrl-b o
将光标移动到 tmux 中的下一个窗格。通过键入tensorboard --logdir=<log directory>
激活虚拟环境并启动 tensorboard。在笔记本电脑的浏览器中打开一个新标签,然后进入 http://localhost:6006 。现在 tensorboard 应该也在运行(如果它不工作,确保 tensorboard 真的像我的情况一样使用端口 6006)。
现在最精彩的部分来了:当你停止工作时,只需输入Ctrl-b d
就可以从 tmux 会话中脱离,当你想继续工作时,输入tmux attach -t <sessionname>
就可以回到你离开的地方!
不幸的是,我不认为有一种方法可以关闭 jupyter 笔记本,同时它继续在后台运行,以后再回来。我经常做的是,当我想留下一些计算的东西过夜时,通过键入jupyter-nbconvert --to script <name>.ipynb
将它转换成 python。现在,只需运行.py
,脱离 tmux 会话,第二天再回来查看输出。如果有人知道更好的方法,请留下评论,我会很高兴知道。
以下是 tmux 的一些非常有用的快捷方式:
# session management
tmux ls (or tmux list-sessions)
tmux new -s session-name
Ctrl-b d Detach from session
tmux attach -t [session name]
tmux kill-session -t session-nameCtrl-b c Create new window
Ctrl-b d Detach current client
Ctrl-b l Move to previously selected window
Ctrl-b n Move to the next window
Ctrl-b p Move to the previous window
Ctrl-b & Kill the current window
Ctrl-b , Rename the current window
Ctrl-b q Show pane numbers (used to switch between panes)
Ctrl-b o Switch to the next pane
Ctrl-b ? List all keybindings# moving between windows
Ctrl-b n (Move to the next window)
Ctrl-b p (Move to the previous window)
Ctrl-b l (Move to the previously selected window)
Ctrl-b w (List all windows / window numbers)
Ctrl-b window number (Move to the specified window number, the
default bindings are from 0 -- 9)# Tiling commands
Ctrl-b % (Split the window vertically)
CTRL-b " (Split window horizontally)
Ctrl-b o (Goto next pane)
Ctrl-b q (Show pane numbers, when the numbers show up type the key to go to that pane)
Ctrl-b { (Move the current pane left)
Ctrl-b } (Move the current pane right)
Ctrl-b x kill current pane# Make a pane its own window
Ctrl-b : "break-pane"
另一个有用的提示:如果你使用 hyperdash ,你可以在手机上追踪你的模特的表现,而不必登录你的电脑:
hyperdash run -n "DQN Breakout" python DQN.py
希望这能为你节省不少时间:)玩得开心!
Jupyter 数据科学堆栈+ Docker 在 15 分钟内完成
原文:https://towardsdatascience.com/jupyter-data-science-stack-docker-in-under-15-minutes-19d8f822bd45?source=collection_archive---------0-----------------------
动机 :假设你想使用 Python 或 R 中一些很酷的数据科学库,但你不想花费 小时 来安装 Python 或 R,找出你需要的库,安装每一个库,然后在你的 Linux/Windows/OSX/OS9 版本上无聊地工作——这就是 Docker 的用处!有了 Docker,我们可以立即建立并运行 Jupyter“数据科学”笔记本堆栈。我们开始吧!
Docker 允许我们在所谓的 容器 中运行“准备就绪”的 Jupyter 数据科学堆栈:
容器映像是一个轻量级的、独立的、可执行的软件包,包含了运行它所需的一切:代码、运行时、系统工具、系统库、设置。基于 Linux 和 Windows 的应用程序都可以使用容器化软件,无论环境如何,容器化软件都可以运行。容器将软件从其周围环境中隔离出来,例如开发和阶段环境之间的差异,并有助于减少在同一基础设施上运行不同软件的团队之间的冲突。
那么容器和虚拟机有什么区别呢?
容器和虚拟机具有类似的资源隔离和分配优势,但功能不同,因为容器虚拟化的是操作系统而不是硬件,容器更具可移植性和效率。
要开始使用 Docker,您需要安装 Docker 社区版。在此下载适合您环境的安装程序。一旦你安装了 Docker,重启你的机器,我们就可以开始安装 Jupyter 容器了。当运行一个容器时,你需要告诉 Docker 这个容器的基本映像是什么。
那么什么是 图像 以及它如何与 容器 相关联呢?
Docker 图像是由一系列层构建而成的。每一层代表图像 docker 文件中的一条指令。除了最后一层,每一层都是只读的。
一个 容器 就是一个 图像 的运行实例。使用 Docker 真正节省时间的是,其他人已经构建了一个映像,其中包含了我们开始使用全套 Jupyter 数据科学堆栈所需的一切!我们所需要做的就是告诉 Docker 根据预定义的图像启动一个容器。为此,我们将以 Docker compose 文件的形式编写一个简单的配方。将下面的文件作为 docker-compose.yml 保存到您的工作目录中:
保存文件后,用您最喜欢的编辑器打开它,并更改以下部分:
/Absolute/Path/To/Where/Your/Notebook/Files/Will/Be/Saved
本地机器上保存您的工作的路径。确保路径确实存在,也就是说,已经创建了所有目录。如果不这样做,当你试图启动你的容器时会导致错误,更糟糕的是,你将不能保存你在容器中做的任何工作!
很好,我们已经准备好了 Docker compose 文件,现在我们可以使用 docker-compose 命令来启动我们的容器。打开终端或命令提示符,进入您的工作目录并运行以下命令:
docker-compose up
您应该在终端/命令提示符下看到类似下面的输出(为了简洁起见,我省略了一些输出):
$ **docker-compose up**Creating network “jupyternotebook_default” with the default driverCreating datascience-notebook-container …Creating datascience-notebook-container … doneAttaching to datascience-notebook-containerdatascience-notebook-container | Execute the command: jupyter notebook.
.
.datascience-notebook-container | [I 11:37:37.993 NotebookApp] The Jupyter Notebook is running at: [http://[all ip addresses on your system]:8888/?token=123456789123456789123456789123456789](http://localhost:8888/?token=123456789123456789123456789123456789)datascience-notebook-container | [I 11:37:37.993 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).datascience-notebook-container | [C 11:37:37.994 NotebookApp]datascience-notebook-container |datascience-notebook-container | Copy/paste this URL into your browser when you connect for the first time,datascience-notebook-container | to login with a token:datascience-notebook-container | [http://localhost:8888/?token=123456789123456789123456789123456789](http://localhost:8888/?token=123456789123456789123456789123456789)
最后一行是一个 URL,我们需要将其复制并粘贴到我们的浏览器中,以访问我们的新 Jupyter 堆栈:
[http://localhost:8888/?token=123456789123456789123456789123456789](http://localhost:8888/?token=123456789123456789123456789123456789)
一旦你做到了这一点,你应该迎接你自己的集装箱 Jupyter 服务!您可以访问此链接了解 Jupyter 数据科学堆栈为您提供的更多信息。
要创建您的第一个笔记本,请进入工作目录,然后单击右侧的“新建”按钮,并选择“Python 3”来创建一个基于 Python 3 的新笔记本。一旦你这样做了,检查你的路径,你选择保存你的工作到本地,你应该看到你的新笔记本的。ipynb 文件已保存!
要在完成工作后关闭容器,只需在终端/命令提示符下按 Ctrl-C。您的工作将全部保存在您的实际机器上,路径是我们在 Docker compose 文件中设置的。这就是你开始使用 Jupyter 笔记本和 Docker 魔力的简单快捷的方法。
我希望这篇文章对你有所帮助,请在下面留下你的反馈或评论。黑客快乐!
使用 SQL 的 Jupyter Magics
原文:https://towardsdatascience.com/jupyter-magics-with-sql-921370099589?source=collection_archive---------5-----------------------
Jupyter/IPython 笔记本可用于在关系数据库上使用 SQL 进行交互式数据分析。这融合了使用 Jupyter(一个成熟的数据分析平台)的优势、SQL 的易用性和 SQL 引擎的性能。
Jupyter 的神奇功能允许你用更简洁的代码片段替换样板代码片段。让我们探索 Jupyter SQL 的魔力,它允许我们与 Presto 或任何其他关系数据库进行交互。
什么是神奇功能?
魔术函数是 Jupyter 内核中执行所提供命令的预定义函数(“魔术”)。有两种面向行和面向单元的魔法,分别以%
和%%
开头。
为了看出区别,我们开始比较使用和不使用 magics 函数的代码示例。最终,两条语句达到了相同的结果。
让我们开始创建与 SQLAchemy 的连接,以获取最后执行的查询并将其放入数据框。
如果我们启用了 SQL 魔法函数,我们将这样做。
入门指南
这些示例使用 Prestodb 作为 SQL 引擎。然而,该方法可以扩展到任何与 Python SQLAlchemy 兼容并且具有实现 Python DB 2.0 规范的驱动程序的引擎。为了实现这种魔力,我们需要一个 ipython-sql 库。此外,这些例子大多来自 ipython-sql 官方知识库。
pip install pandas
pip install sqlalchemy # ORM for databases
pip install ipython-sql # SQL magic function
要使用 Prestodb,我们需要 PyHive 库。幕后的 SQLAlchemy 将使用该库建立连接并提交 SQL 查询。对于其他引擎,您需要安装合适的驱动程序,即PostgreSQL、 MySQL 。
pip install pyhive[presto] # DB driver library
使用
ipython-sql 库使用%load_ext iPython 扩展语法加载,并指向连接对象,如下所示:
%load_ext sql
%config SqlMagic.autocommit=False # for engines that do not support autommit
请注意,对于普雷斯托,黑斑羚和其他一些引擎,你需要禁用autocommit
功能。这是通过 SqlMagic config 属性完成的。列出您可以在单元中运行的所有配置选项:%config SqlMagic
关系
要连接到数据库,您需要将 SQLAlchemy 格式的连接字符串传递给%sql
函数。
%sql presto://user@localhost:8080/system
如果没有提供连接字符串并且还没有建立连接,ipython-sql
试图从DATABASE_URL
环境变量中获取连接信息。如果您的连接信息是静态的,您可以在~/.bashrc
中导出环境变量DATABASE_URL
。%env 是另一个设置环境变量的神奇函数。
%env DATABASE_URL=presto://user@localhost:8080/system
%sql SELECT 1 as "Test"
在多个 SQL 引擎的情况下,如果您想要组合来自它们的数据,您可以在单元模式下将连接字符串与神奇函数的每个查询一起传递。
%%sql user@jmx
SHOW SCHEMAS
绑定变量
参数替换是一个方便的特性,它允许在查询运行时定义 SQL 查询参数。它使代码不那么脆弱,也不那么富于表现力。该参数需要在本地范围内定义,并以冒号为前缀,即:parameter
变量赋值
普通的 IPython 赋值适用于单行%sql
查询:
result = %sql select query_id, state from runtime.queries limit 1
对于多行查询,您需要使用<<
语法。
%%sql result_set <<
SELECT query_id, state, query
FROM runtime.queries
LIMIT 2
熊猫
SQL magic 与 pandas 库有很好的集成。SQL 查询的结果可以通过DataFrame
调用转换成常规的 pandas 数据帧。
结论
你也应该考虑阅读一下内置的神奇功能,它可以让你完成更多的工作,减少输入!你也可以看看满笔记本贴上的例子。
[## saty bald/ipython-笔记本
IPython-笔记本-IPython 笔记本的集合
github.com](https://github.com/satybald/ipython-notebooks/blob/master/MagicsSQL.ipynb)
Jupyter 笔记本备忘单
原文:https://towardsdatascience.com/jupyter-notebook-cheat-sheet-e4aa632018c2?source=collection_archive---------6-----------------------
您可能已经非常了解 Jupyter 笔记本,它可能是 Jupyter 生态系统中最知名的部分之一!如果你还没有探索过这个生态系统,或者你只是想了解更多,请不要犹豫,点击这里去探索它吧!。
对于那些不熟悉 Project Jupyter 的人来说,Jupyter Notebook 应用程序可以生成包含可执行代码、文本元素甚至 HTML 的混合文档,这使得它成为汇集分析描述及其结果以及实时执行数据分析的理想场所。这一点,加上其许多有用的功能,解释了为什么 Jupyter 笔记本电脑是数据科学家的首选开发环境之一,它允许交互式、可重复的数据科学分析、计算和通信。
Jupyter 笔记本的另一个优点是什么?
它们非常容易上手!当你阅读 DataCamp 的Jupyter 笔记本权威指南时,你可能已经注意到了这一点。然而,当您第一次进入应用程序时,您可能需要在呈现给您的各种功能中找到自己的方式:从保存您当前的笔记本到在笔记本中添加或移动单元格,或者在笔记本中嵌入当前的小部件——毫无疑问,当您第一次开始使用时,有很多东西需要发现!
这就是为什么 DataCamp 为那些刚刚起步并希望获得一些帮助来找到出路的人制作了一个 Jupyter 笔记本备忘单。
请注意Jupyter 笔记本应用程序有一个方便的“帮助”菜单,包括一个完整的用户界面浏览!—别担心,我们也在备忘单中包含了这一点:)
请点击这里查看:
点击 这里 看小抄。
简而言之,这份备忘单将帮助你启动你的数据科学项目,无论它们是大是小:通过一些截图和解释,你很快就会成为 Jupyter 笔记本专家!
你还在等什么?是时候开始了!
原载于。
Jupyter 笔记本扩展
原文:https://towardsdatascience.com/jupyter-notebook-extensions-517fa69d2231?source=collection_archive---------0-----------------------
(Source)
如何在笔记本电脑环境中提高工作效率
Jupyter 笔记本是一个很好的教学、探索和读写编程环境,但是开箱即用的笔记本众所周知缺乏特性。幸运的是,有许多方法,包括 Jupyter 笔记本扩展,来改进这个无价的工具。
极其简洁的版本
在命令提示符下运行以下命令:
pip install jupyter_contrib_nbextensions && jupyter contrib nbextension install
启动 Jupyter 笔记本并导航到新的 Nbextensions 选项卡:
Jupyter Notebook Extensions Tab
启用您想要的扩展并享受工作效率优势。
(如果您没有看到选项卡,请打开笔记本并点击编辑> nbextensions 配置)
可以在笔记本的工具栏中看到启用的扩展:
稍长的版本
如果这还不够让你满意,下面是一些关于 Jupyter 笔记本扩展的细节。我还列出了我的前 5 条建议来帮助你开始。
什么是笔记本扩展?
Jupyter 笔记本扩展是扩展笔记本环境基本功能的简单附件。用 JavaScript 编写,他们做的事情有自动格式化你的代码或者当一个单元格完成时发送一个浏览器通知。扩展目前只适用于 Jupyter 笔记本(不适用于 Jupyter 实验室)。
为什么要使用这些扩展?Jupyter 笔记本是教学、学习、原型制作、探索和尝试新方法的绝佳工具(甚至在网飞的生产中也是如此)。然而,普通笔记本的功能有限,这使得在笔记本上工作令人沮丧。虽然 Jupyter 笔记本扩展没有完全解决问题,但它们确实增加了一些好处,使您的工作更加轻松。
使用哪个
以下是我最常用的 5 款 Jupyter 笔记本扩展:
1.目录:更简单的导航
一旦你开始在一个 Jupyter 笔记本上放几十个电池,就很难把它们都记录下来。目录通过添加可放置在页面任何位置的链接目录解决了这个问题:
Table of Contents
您还可以使用该扩展在笔记本顶部添加一个链接的目录。这甚至显示哪个单元被选中,哪个单元正在运行:
Table of Contents in Notebook
2.Autopep8:一键完成简洁的代码
我们都应该编写符合 pep8 的代码,但有时你会陷入分析中,很难坚持最佳实践。当你写完这个惊人的情节时,这个扩展允许你简单地点击木槌,自动格式化你混乱的代码。
Autopep8 your code.
像最好的附加组件一样,这一个只需简单的点击就能完成耗时而乏味的任务,让你专注于思考问题。
3.变量检查器:跟踪你的工作空间
变量检查器显示您在笔记本中创建的所有变量的名称,以及它们的类型、大小、形状和值。
Variable inspector
对于从 RStudio 迁移过来的数据科学家来说,或者如果你不想继续打印df.shape
或者想不起x
的type
的话,这个工具是非常宝贵的。
4.ExecuteTime:显示单元运行的时间和时长
我经常发现自己试图弄清楚一个单元运行需要多长时间,或者我最后一次运行打开了几天的笔记本是什么时候。ExecuteTime 通过显示一个单元完成的时间和花费的时间来处理这两个问题。
ExecuteTime extension output
有更好的方法来计时(例如[%%timeit](https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-timeit)
单元格魔术)但是这很容易实现并且覆盖了笔记本中的所有单元格。
5.隐藏代码输入:隐藏工作显示结果
虽然我们中的一些人喜欢看到进入分析的艰苦工作,一些人只是喜欢看到结果。Hide input all 扩展允许您在保留输出的同时立即隐藏笔记本中的所有代码。
Hide all code
下一次有人说他们只想看到结果,你有一个单击解决方案。(尽管您应该经常检查代码)。
这些只是我发现自己最常使用的扩展,你并不局限于五个。安装扩展并打开一个笔记本(这里显示的笔记本在 GitHub 上)来检查整个列表!(如果您愿意,您甚至可以编写自己的扩展。文档很少,但是这里是基本结构。)
结论
安装 Jupyter 笔记本扩展,花点时间搞清楚哪些对你有用,提高你的生产力。虽然没有一个能改变生活,但它们都增加了足够的价值,累积起来节省了您几个小时的宝贵开发时间。
尽管如果你正在编写生产代码(我喜欢而不是代码),你可能想花一些时间在学习 IDE ,Jupyter 笔记本仍然是数据科学工作流程中不可或缺的一部分。如果您打算使用这种环境,那么您最好充分利用您的工具。
一如既往,我欢迎反馈和建设性的批评。可以通过 Twitter @koehrsen_will 或者通过我的个人网站 willk.online 找到我。
初学者 Jupyter 笔记本:教程
原文:https://towardsdatascience.com/jupyter-notebook-for-beginners-a-tutorial-f55b57c23ada?source=collection_archive---------4-----------------------
Photo by Harish Sharma on Pixabay
Jupyter Notebook 是一个非常强大的交互式开发和展示数据科学项目的工具。笔记本将代码及其输出集成到一个文档中,该文档结合了可视化、叙述性文本、数学方程和其他富媒体。直观的工作流促进了迭代和快速开发,使笔记本电脑成为当代数据科学、分析以及越来越普遍的科学的核心中越来越受欢迎的选择。最棒的是,作为开源项目 Jupyter 的一部分,它们是完全免费的。
Jupyter 项目是早期 IPython 笔记本的继任者,该笔记本于 2010 年作为原型首次发布。尽管在 Jupyter 笔记本中可以使用许多不同的编程语言,但本文将重点讨论 Python,因为它是最常见的用例。
为了从本教程中获得最大收益,你应该熟悉编程,特别是 Python 和熊猫。也就是说,如果你有使用另一种语言的经验,本文中的 Python 不应该太神秘,pandas 应该是可解释的。Jupyter 笔记本也可以作为一个灵活的平台来掌握 pandas 甚至 Python,这一点在本文中会变得很明显。
我们将:
- 涵盖安装 Jupyter 和创建您的第一台笔记本的基础知识
- 深入钻研,学习所有重要的术语
- 探索在线共享和发布笔记本有多容易。的确,这篇文章是一本 Jupyter 笔记本!这里的所有内容都是在 Jupyter 笔记本环境中编写的,您正在以只读形式查看它。
Jupyter 笔记本中的示例数据分析
我们将通过一个示例分析来回答一个现实生活中的问题,这样您就可以看到笔记本的流程如何让任务直观地通过我们自己来完成,以及当我们与他人分享时让他人理解。
假设你是一名数据分析师,你的任务是找出美国最大公司的利润历史变化。你会发现一组财富 500 强公司的数据,从 1955 年第一次发布到现在已经超过 50 年了,这些数据来自财富的公共档案库。我们已经创建了一个 CSV 格式的数据,您可以在这里使用。
正如我们将要展示的,Jupyter 笔记本非常适合这项调查。首先,让我们继续安装 Jupyter。
装置
初学者开始使用 Jupyter 笔记本最简单的方法是安装 Anaconda 。Anaconda 是数据科学中使用最广泛的 Python 发行版,预装了所有最流行的库和工具。除了 Jupyter,Anaconda 中一些最大的 Python 库包括 NumPy 、 pandas 和 Matplotlib ,尽管完整的 1000+列表已经很详尽了。这使您可以在自己的全面储备的数据科学研讨会中立即投入运行,而不会有管理无数安装的麻烦,也不会担心依赖关系和特定于操作系统(即特定于 Windows)的安装问题。
要得到 Anaconda,很简单:
- 下载Python 3 的 Anaconda 最新版本(忽略 Python 2.7)。
- 按照下载页面和/或可执行文件中的说明安装 Anaconda。
如果您是已经安装了 Python 的高级用户,并且喜欢手动管理您的包,那么您可以只使用 pip:
创建您的第一个笔记本
在本节中,我们将了解如何运行和保存笔记本,熟悉它们的结构,并理解界面。我们将熟悉一些核心术语,引导您实际理解如何自己使用 Jupyter 笔记本电脑,并为下一部分做好准备,这一部分将逐步介绍一个示例数据分析,并将我们在此学到的一切融入生活。
跑步 Jupyter
在 Windows 上,您可以通过 Anaconda 添加到开始菜单的快捷方式来运行 Jupyter,这将在您的默认 web 浏览器中打开一个新的选项卡,看起来应该类似于下面的截图。
这还不是一个笔记本,但不要惊慌!没什么大不了的。这是笔记本仪表盘,专门用于管理您的 Jupyter 笔记本。将它视为探索、编辑和创建笔记本的发射台。
请注意,仪表板将只允许您访问 Jupyter 启动目录中包含的文件和子文件夹;但是,启动目录可以更改。也可以在任何系统上通过命令提示符(或 Unix 系统上的终端)输入命令jupyter notebook
来启动仪表板;在这种情况下,当前工作目录将是启动目录。
敏锐的读者可能已经注意到仪表板的 URL 类似于http://localhost:8888/tree
。Localhost 不是一个网站,但它表明内容是从您的本地机器(您自己的计算机)提供的。Jupyter 的笔记本和仪表板是 web 应用程序,Jupyter 启动了一个本地 Python 服务器来为您的 web 浏览器提供这些应用程序,使其基本上独立于平台,并打开了更容易在 web 上共享的大门。
仪表板的界面基本上是不言自明的——尽管我们稍后会简单地回到它。那么我们还在等什么呢?浏览到您想要创建第一个笔记本的文件夹,单击右上角的“新建”下拉按钮,然后选择“Python 3”(或您选择的版本)。
嘿,很快,我们到了!您的第一个 Jupyter 笔记本将在新选项卡中打开,每个笔记本都使用自己的选项卡,因为您可以同时打开多个笔记本。如果你切换回仪表板,你会看到新的文件Untitled.ipynb
,你应该会看到一些绿色的文字,告诉你你的笔记本正在运行。
什么是 ipynb 文件?
理解这个文件到底是什么会很有用。每个.ipynb
文件都是一个文本文件,以一种叫做 JSON 的格式描述你笔记本的内容。每个单元格及其内容,包括已经转换为文本字符串的图像附件,与一些元数据一起列在其中。如果你知道你在做什么,你可以自己编辑它!—从笔记本的菜单栏中选择“编辑>编辑笔记本元数据”。
也可以从仪表盘上的控件中选择“编辑”来查看笔记本文件的内容,但这里的关键词是“可以”;除非你真的知道自己在做什么,否则除了好奇没有别的原因。
笔记本界面
现在你面前有一个打开的笔记本,它的界面看起来不会完全陌生;毕竟,Jupyter 本质上只是一个高级的文字处理器。为什么不四处看看呢?检查一下菜单,感受一下,特别是花一些时间向下滚动命令面板中的命令列表,命令面板是带有键盘图标的小按钮(或Ctrl + Shift + P
)。
你应该注意到两个相当突出的术语,它们可能对你来说是新的:细胞和内核是理解 Jupyter 的关键,也是它不仅仅是一个文字处理器的关键。好在这些概念并不难理解。
- 内核是一个“计算引擎”,它执行笔记本文档中包含的代码。
- 单元是显示在笔记本中的文本或由笔记本内核执行的代码的容器。
细胞
稍后我们将回到内核,但首先让我们来了解一下细胞。细胞构成了笔记本的主体。在上一节中新笔记本的屏幕截图中,带有绿色轮廓的框是一个空单元格。我们将介绍两种主要的细胞类型:
- 一个代码单元包含要在内核中执行的代码,并在下面显示其输出。
- Markdown 单元格包含使用 Markdown 格式化的文本,并在运行时就地显示其输出。
新笔记本中的第一个单元格总是代码单元格。让我们用一个经典的 hello world 例子来测试一下。在单元格中输入print('Hello World!')
,点击上方工具栏中的运行按钮或按下Ctrl + Enter
。
结果应该是这样的:
Hello World!
当您运行该单元时,其输出将显示在下方,其左侧的标签将从In [ ]
变为In [1]
。代码单元的输出也构成了文档的一部分,这就是为什么您可以在本文中看到它。您总是可以区分代码单元格和降价单元格,因为代码单元格的标签在左边,而降价单元格没有。标签的“In”部分是“Input”的简称,而标签号表示单元在内核上执行的时间——在这种情况下,单元首先被执行。再次运行该单元,标签将变为In [2]
,因为现在该单元是第二个在内核上运行的单元。当我们更仔细地研究内核时,会更清楚为什么这是如此有用。
从菜单栏中,点击插入并选择在下方插入单元格,在第一个单元格下方创建一个新的代码单元格,并尝试以下代码,看看会发生什么。你注意到什么不同了吗?
这个单元格不产生任何输出,但是它确实需要三秒钟来执行。请注意 Jupyter 是如何通过将标签更改为In [*]
来表示该单元当前正在运行的。
一般来说,单元格的输出来自于在单元格执行期间专门打印的任何文本数据,以及单元格中最后一行的值,无论是单独的变量、函数调用还是其他。例如:
'Hello, Tim!'
您会发现自己在自己的项目中几乎经常使用这种方法,以后我们会看到更多。
快捷键
运行单元格时,您可能观察到的最后一件事是,它们的边框变成了蓝色,而在编辑时它是绿色的。总是有一个“活动”单元格用边框高亮显示,边框的颜色表示其当前模式,其中绿色表示“编辑模式”,蓝色表示“命令模式”
到目前为止,我们已经看到了如何使用Ctrl + Enter
运行单元,但是还有更多。键盘快捷键是 Jupyter 环境中非常流行的一个方面,因为它们促进了基于单元格的快速工作流。其中许多操作是您可以在活动单元格处于命令模式时执行的。
下面,你会发现一些 Jupyter 的键盘快捷键列表。你不需要马上去做,但是这个列表会让你知道什么是可能的。
- 分别用
Esc
和Enter
在编辑和命令模式之间切换。
一旦进入命令模式:
- 用
Up
和Down
键上下滚动单元格。 - 按下
A
或B
在当前单元格的上方或下方插入一个新单元格。 M
将当前单元格转换为降价单元格。Y
将当前单元格设置为代码单元格。D + D
(D
两次)将删除当前单元格。Z
将撤消单元格删除。- 按住
Shift
并按下Up
或Down
一次选择多个单元格。
选择多个单元格:
Shift + M
将合并您的选择。Ctrl + Shift + -
,在编辑模式下,将光标处的活动单元格拆分。- 您也可以点击单元格左边的空白处的和
Shift + Click
来选择它们。
继续在你自己的笔记本上尝试这些。一旦你有了一个剧本,创建一个新的降价单元,我们将学习如何在我们的笔记本上设置文本格式。
降价
Markdown 是一种轻量级的、易于学习的标记语言,用于格式化纯文本。它的语法与 HTML 标签一一对应,所以这里的一些先验知识会有所帮助,但绝对不是先决条件。请记住,这篇文章是在 Jupyter 笔记本上写的,所以到目前为止,您看到的所有叙述性文本和图像都是在 Markdown 中实现的。让我们用一个简单的例子来介绍一下基础知识。
# This is a level 1 heading
## This is a level 2 heading
This is some plain text that forms a paragraph.
Add emphasis via **bold** and __bold__, or *italic* and _italic_.Paragraphs must be separated by an empty line.* Sometimes we want to include lists.
* Which can be indented.1\. Lists can also be numbered.
2\. For ordered lists.[It is possible to include hyperlinks]([https://www.example.com](https://www.example.com))Inline code uses single backticks: `foo()`, and code blocks use triple backticks:```
bar()
Or can be intented by 4 spaces:
foo()
And finally, adding images is easy:
附加图像时,您有三种选择:
* 使用网络上图像的 URL。
* 使用一个本地 URL 链接到您将与笔记本一起保存的图像,比如在同一个 git repo 中。
* 通过“编辑>插入图像”添加附件;这将把图像转换成一个字符串并存储在你的笔记本`.ipynb`文件中。
* 请注意,这将使您的`.ipynb`文件更大!
Markdown 还有很多细节,特别是关于超链接,也可以简单地包含普通的 HTML。一旦你发现自己正在挑战上述基础知识的极限,你可以参考创作者约翰·格鲁伯在其网站上提供的官方指南。
# 核
每台笔记本背后都运行着一个内核。当您运行一个代码单元时,该代码在内核中执行,任何输出都返回到该单元进行显示。内核的状态会随着时间的推移在单元格之间持续存在——它属于整个文档,而不是单个单元格。
例如,如果您在一个单元格中导入库或声明变量,它们将在另一个单元格中可用。通过这种方式,您可以认为笔记本文档有点类似于脚本文件,只是它是多媒体的。让我们试试这个来感受一下。首先,我们将导入一个 Python 包并定义一个函数。
一旦我们执行了上面的单元格,我们可以在任何其他单元格中引用`np`和`square`。
1 squared is 1
不管笔记本中单元格的顺序如何,这都将有效。你可以自己试试,我们再把变量打印出来。
Is 1 squared is 1?
这里没有惊喜!但是现在让我们改变`y`。
如果我们再次运行包含我们的`print`语句的单元格,您认为会发生什么?我们会得到输出`Is 4 squared is 10?`!
大多数情况下,笔记本中的流程是自上而下的,但经常会回头进行修改。在这种情况下,每个单元格左边的执行顺序,比如`In [6]`,将让您知道是否有任何单元格有过时的输出。如果你想重新设置,内核菜单中有几个非常有用的选项:
* 重启:重启内核,从而清除所有已定义的变量等。
* 重新启动并清除输出:同上,但也会清除代码单元格下方显示的输出。
* 重启并运行全部:同上,但也将从第一个到最后一个顺序运行所有单元格。
如果您的内核卡在一个计算上,并且您希望停止它,您可以选择 Interupt 选项。
## 选择内核
你可能注意到了,Jupyter 给了你改变内核的选项,事实上有很多不同的选项可供选择。当您通过选择 Python 版本从仪表板创建新笔记本时,您实际上是在选择使用哪个内核。
不仅有不同版本 Python 的内核,还有超过 100 种语言的[内核,包括 Java,C,甚至 Fortran。数据科学家可能对](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels) [R](https://irkernel.github.io/) 和 [Julia](https://github.com/JuliaLang/IJulia.jl) 的内核,以及 [imatlab](https://github.com/imatlab/imatlab) 和 [Calysto MATLAB 的内核](https://github.com/calysto/matlab_kernel)特别感兴趣。 [SoS 内核](https://github.com/vatlab/SOS)在一台笔记本电脑中提供多语言支持。每个内核都有自己的安装说明,但可能需要您在计算机上运行一些命令。
# 实例分析
现在我们已经看了什么是 Jupyter 笔记本,是时候看看它们在实践中是如何使用的,这会让你更清楚地了解为什么它们如此受欢迎。终于到了开始使用前面提到的财富 500 强数据集的时候了。请记住,我们的目标是找出美国最大的公司的利润是如何历史变化的。
值得注意的是,每个人都将发展自己的喜好和风格,但一般原则仍然适用,如果你愿意,你可以在自己的笔记本上跟随这一部分,这给了你发挥的空间。
# 命名您的笔记本
在开始编写项目之前,您可能希望给它起一个有意义的名称。可能有些令人困惑的是,你不能从笔记本应用程序本身命名或重命名你的笔记本,而是必须使用仪表板或你的文件浏览器来重命名`.ipynb`文件。我们将返回到仪表板来重命名您之前创建的文件,它将具有默认的笔记本文件名`Untitled.ipynb`。
您不能在笔记本运行时对其进行重命名,因此您必须先将其关闭。最简单的方法是从笔记本菜单中选择“文件>关闭并暂停”。但是,您也可以关闭内核,方法是在笔记本应用程序中进入“内核>关闭”,或者在仪表板中选择笔记本,然后单击“关闭”(见下图)。

然后,您可以选择您的笔记本电脑,并单击仪表板控件中的“重命名”。

请注意,关闭浏览器中的“笔记本”选项卡将**而不是**“关闭”您的笔记本,就像在传统应用程序中关闭文档一样。笔记本的内核将继续在后台运行,并且需要在它真正“关闭”之前关闭——尽管如果你不小心关闭了标签或浏览器,这是非常方便的!如果内核关闭,您可以关闭标签页,而不用担心它是否还在运行。
一旦你命名了你的笔记本,打开它,我们就可以开始了。
# 设置
通常从专门用于导入和设置的代码单元开始,这样,如果您选择添加或更改任何内容,您可以简单地编辑并重新运行该单元,而不会导致任何副作用。
我们导入[熊猫](https://pandas.pydata.org/)来处理我们的数据, [Matplotlib](https://matplotlib.org/) 来绘制图表,以及 [Seaborn](https://seaborn.pydata.org/) 来使我们的图表更漂亮。导入 [NumPy](http://www.numpy.org/) 也很常见,但是在这种情况下,虽然我们通过 pandas 使用它,但是我们不需要显式地导入。第一行不是 Python 命令,而是使用一种叫做 line magic 的东西来指示 Jupyter 捕获 Matplotlib 图并在单元格输出中呈现它们;这是超出本文范围的一系列高级特性之一。
让我们继续加载我们的数据。
明智的做法是在单个单元格中也这样做,以防我们需要在任何时候重新加载它。
# 保存和检查点
现在我们已经开始了,定期储蓄是最好的做法。按下`Ctrl + S`会通过调用“保存和检查点”命令来保存你的笔记本,但是这个检查点是什么东西呢?
每次创建新笔记本时,都会创建一个检查点文件以及您的笔记本文件;它将位于保存位置的一个隐藏子目录中,名为`.ipynb_checkpoints`,也是一个`.ipynb`文件。默认情况下,Jupyter 会每隔 120 秒自动将您的笔记本保存到该检查点文件,而不会改变您的主笔记本文件。当您“保存并检查”时,笔记本和检查点文件都会更新。因此,检查点使您能够在出现意外问题时恢复未保存的工作。您可以通过“文件>恢复到检查点”从菜单恢复到检查点
# 调查我们的数据集
现在我们真的开始了!我们的笔记本被安全保存,我们已经将数据集`df`加载到最常用的 pandas 数据结构中,该结构被称为`DataFrame`,基本上看起来像一个表。我们的看起来像什么?
看起来不错。我们有我们需要的列,每一行对应于一年中的一家公司。
让我们重新命名这些列,以便以后引用它们。
接下来,我们需要探索我们的数据集。完成了吗?熊猫如预期的读了吗?是否缺少任何值?
25500
好的,看起来不错——从 1955 年到 2005 年,每年都有 500 行。
让我们检查一下我们的数据集是否像我们期望的那样被导入了。一个简单的检查是查看数据类型(或 dtypes)是否被正确解释。
year int64
rank int64
company object
revenue float64
profit object
dtype: object
啊哦。看起来利润栏有问题——我们希望它像收入栏一样是一个`float64`。这表明它很可能包含一些非整数值,所以我们来看看。
正如我们所怀疑的!有些值是字符串,用于指示丢失的数据。有没有其他的价值观已经悄然进入?
{'N.A.'}
这很容易解释,但是我们应该怎么做呢?嗯,那要看少了多少个值。
369
这只是我们数据集的一小部分,尽管并非完全无关紧要,因为它仍然在 1.5%左右。如果包含`N.A.`的行在这些年中大致均匀分布,最简单的解决方法就是删除它们。所以让我们快速看一下分布情况。

一眼看去,我们可以看到一年中最无效的值少于 25,并且由于每年有 500 个数据点,删除这些值将占最差年份数据的不到 4%。事实上,除了 90 年代左右的飙升,大多数年份都不到峰值的一半。出于我们的目的,假设这是可以接受的,并继续删除这些行。
我们应该检查一下是否有效。
25131
year int64
rank int64
company object
revenue float64
profit float64
dtype: object
太好了!我们已经完成了数据集设置。
如果您要将笔记本显示为报告,您可以去掉我们创建的调查单元格(此处包含这些单元格是为了演示使用笔记本的流程),并合并相关单元格(请参阅下面的高级功能部分了解更多信息)以创建单个数据集设置单元格。这意味着,如果我们在其他地方弄乱了数据集,我们可以重新运行 setup 单元来恢复它。
# 使用 matplotlib 绘图
接下来,我们可以通过绘制每年的平均利润来解决手头的问题。我们也可以绘制收入图,所以首先我们可以定义一些变量和一个减少代码的方法。
现在我们来策划!

哇,这看起来像一个指数,但它有一些巨大的下降。它们必须与 20 世纪 90 年代初的衰退和 T2 的网络泡沫相对应。在数据中看到这一点很有趣。但是,每次衰退之后,利润是如何恢复到更高水平的呢?
也许收入能告诉我们更多。

这增加了故事的另一面。收入没有受到如此严重的打击,这是财务部门的一些伟大的会计工作。
通过栈溢出的一点点帮助[,我们可以用+/-它们的标准偏差叠加这些图。](https://stackoverflow.com/a/47582329/604687)

这是惊人的,标准差是巨大的。一些财富 500 强公司赚了数十亿美元,而另一些公司却损失了数十亿美元,而且随着这些年利润的增加,风险也在增加。也许有些公司比其他公司表现更好;前 10%的利润比后 10%的利润波动更大还是更小?
接下来我们可以研究很多问题,很容易看出在笔记本上工作的流程是如何与一个人自己的思维过程相匹配的,所以现在是时候结束这个例子了。这个流程帮助我们轻松地在一个地方调查我们的数据集,而无需在应用程序之间切换上下文,并且我们的工作可以立即共享和重现。如果我们希望为特定的受众创建更简洁的报告,我们可以通过合并单元格和删除中间代码来快速重构我们的工作。
# 共享您的笔记本
当人们谈论共享他们的笔记本时,他们通常会考虑两种模式。大多数情况下,个人分享他们工作的最终结果,很像这篇文章本身,这意味着分享他们笔记本的非交互、预渲染版本;然而,也有可能在笔记本上与 aid 版本控制系统协作,例如 [Git](https://git-scm.com/) 。
也就是说,有一些[T4 的](https://mybinder.org/)[新兴公司](https://kyso.io/)出现在网络上,提供在云中运行交互式 Jupyter 笔记本的能力。
# 在分享之前
共享笔记本将完全按照导出或保存时的状态显示,包括任何代码单元格的输出。因此,为了确保您的笔记本可以共享,您应该在共享前采取以下几个步骤:
1. 单击“单元格>所有输出>清除”
2. 点击“内核>重启并全部运行”
3. 等待您的代码单元完成执行,并检查它们是否按预期执行
这将确保您的笔记本不包含中间输出,没有过时状态,并在共享时按顺序执行。
# 导出您的笔记本
Jupyter 内置了对导出为 HTML 和 PDF 以及其他几种格式的支持,你可以在“文件>下载为”下的菜单中找到如果您希望与一个小型私人团体共享您的笔记本电脑,此功能可能正是您所需要的。事实上,由于学术机构的许多研究人员都获得了一些公共或内部网络空间,并且因为您可以将笔记本导出为 HTML 文件,Jupyter 笔记本可以成为他们与同行分享成果的一种特别方便的方式。
但是如果共享导出的文件对你来说还不够,还有一些非常流行的方法可以更直接地在网上共享`.ipynb`文件。
# 开源代码库
随着 GitHub 上的[公共笔记本数量在 2018 年初超过 180 万,它无疑是最受欢迎的与世界分享 Jupyter 项目的独立平台。GitHub 已经集成了对直接在存储库和网站上的 gists 中呈现`.ipynb`文件的支持。如果你还不知道的话,](https://github.com/parente/nbestimate) [GitHub](https://github.com/) 是一个代码托管平台,用于版本控制和使用 [Git](https://git-scm.com/) 创建的存储库的协作。你需要一个帐户来使用他们的服务,但标准帐户是免费的。
一旦你有了 GitHub 账户,在 GitHub 上分享笔记本最简单的方法实际上根本不需要 Git。自 2008 年以来,GitHub 提供了 Gist 服务来托管和共享代码片段,每个代码片段都有自己的存储库。要使用 Gists 共享笔记本:
1. 登录并浏览至[gist.github.com](https://gist.github.com/)。
2. 在一个文本编辑器中打开你的`.ipynb`文件,选择全部并复制里面的 JSON。
3. 将笔记本 JSON 粘贴到要点中。
4. 给你的要点一个文件名,记住要加上`.ipynb`,否则就没用了。
5. 点按“创建秘密要点”或“创建公开要点”
这应该类似于以下内容:

如果你创建了一个公共 Gist,你现在可以和任何人分享它的 URL,其他人也可以[复制你的作品。](https://help.github.com/articles/forking-and-cloning-gists/)
创建自己的 Git 库并在 GitHub 上共享超出了本教程的范围,但是 [GitHub 提供了大量的指南](https://guides.github.com/)让你自己开始。
对于那些使用 git 的人来说,一个额外的提示是[为 Jupyter 创建的那些隐藏的`.ipynb_checkpoints`目录添加一个例外](https://stackoverflow.com/q/35916658/604687)到你的`.gitignore`中,这样就不会不必要地提交检查点文件到你的 repo 中。
# Nbviewer
到 2015 年,NBViewer 已经发展到每周渲染[数十万台](https://blog.jupyter.org/rendering-notebooks-on-github-f7ac8736d686)笔记本,是网络上最受欢迎的笔记本渲染器。如果你已经有一个地方可以在线存放你的 Jupyter 笔记本,无论是 GitHub 还是其他地方,NBViewer 都会呈现你的笔记本并提供一个可共享的 URL。作为 Jupyter 项目的一部分,它是免费提供的,可在[nbviewer.jupyter.org](https://nbviewer.jupyter.org/)获得。
NBViewer 最初是在 GitHub 的 Jupyter 笔记本集成之前开发的,它允许任何人输入 URL、Gist ID 或 GitHub 用户名/repo/file,它会将笔记本呈现为网页。Gist 的 ID 是其 URL 末尾的唯一数字;比如`https://gist.github.com/username/50896401c23e0bf417e89cd57e89e1de`中最后一个反斜杠后的字符串。如果您输入 GitHub 用户名或用户名/回购,您将看到一个最小的文件浏览器,让您浏览用户的回购及其内容。
显示笔记本时,NBViewer 显示的 URL 是一个常数,基于它所渲染的笔记本的 URL,因此您可以与任何人共享它,只要原始文件保持在线,它就可以工作-nb viewer 不会缓存文件很长时间。
# 最后的想法
从基础开始,我们已经掌握了 Jupyter 笔记本的自然工作流程,深入研究了 IPython 更高级的功能,并最终学会了如何与朋友、同事和世界分享我们的工作。我们从一台笔记本电脑上完成了这一切!
应该清楚笔记本如何通过减少上下文切换和模仿项目过程中思维的自然发展来促进高效的工作体验。Jupyter 笔记本的强大之处应该也是显而易见的,我们介绍了大量线索,让您开始探索自己项目中更高级的功能。
如果你想为你自己的笔记本获得更多灵感,Jupyter 已经收集了[一系列有趣的 Jupyter 笔记本](https://github.com/jupyter/jupyter/wiki/A-gallery-of-interesting-Jupyter-Notebooks),你可能会觉得有帮助,并且[NBC viewer 主页](https://nbviewer.jupyter.org/)链接到一些真正高档的优质笔记本。也来看看我们的 [Jupyter 笔记本提示](https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/)列表。
> 想了解更多关于 Jupyter 笔记本的信息?我们有[一个引导项目](https://www.dataquest.io/m/207/guided-project%3A-using-jupyter-notebook)你可能会感兴趣。
# 提高 Jupyter 笔记本电脑的工作效率
> 原文:<https://towardsdatascience.com/jupyter-notebook-hints-1f26b08429ad?source=collection_archive---------1----------------------->
# Jupyter (IPython)笔记本特性
首先,我想指出,它是创建可读分析非常灵活的工具,因为人们可以将代码、图像、注释、公式和图表放在一起:

Jupyter 具有很强的可扩展性,支持其他编程语言,几乎可以在任何服务器上轻松托管——您只需要通过 ssh 或 http 访问服务器。而且是完全免费的。
# 基础
热键列表显示在**帮助>键盘快捷键**中(列表会不时扩展,所以不要犹豫再看一遍)。
这给了你一个如何与笔记本互动的想法。如果你经常使用笔记本,你当然会学到大部分的内容。特别是:
* `Esc + F`查找和替换仅搜索代码,不搜索输出
* `Esc + O`切换单元格输出
* 您可以选择一行中的多个单元格,然后删除/复制/剪切/粘贴它们。当您需要移动笔记本的部件时,这很有帮助

# 共享笔记本
最简单的方法是共享笔记本文件。ipynb),但并不是所有人都在用笔记本,所以选项有
* 将笔记本转换为 html 文件
* 分享给正在渲染笔记本的 gists。
* 将您的笔记本存放在 dropbox 中,并将链接放入 [nbviewer](http://nbviewer.jupyter.org/) 中。nbviewer 将渲染笔记本
* github 渲染笔记本(有一些限制,但在大多数情况下是可以的),这使得保持你的研究历史非常有用(如果研究是公开的)
# 在笔记本中绘图
有许多绘图选项:
* matplotlib(事实上的标准),用`%matplotlib inline`激活
* `%matplotlib notebook`是交互式模式,但是非常慢,因为渲染是在服务器端完成的。
* mpld3 为 matplotlib 代码提供了可选的渲染器(使用 d3)。很好,虽然不完整
* 散景是构建交互式地块的更好选择
* plot.ly 可以生成很好的图,但是会让你花钱

# 魔法
魔术师正在把简单的 python 变成*神奇的 python* 。魔法是 ipython 力量的关键。
在[1]中:
# list available python magics
%lsmagic
Out[1]:
Available line magics:
%alias %alias_magic %autocall %automagic %autosave %bookmark %cat %cd %clear %colors %config %connect_info %cp %debug %dhist %dirs %doctest_mode %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %lf %lk %ll %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %lx %macro %magic %man %matplotlib %mkdir %more %mv %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %popd %pprint %precision %profile %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %rep %rerun %reset %reset_selective %rm %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmodeAvailable cell magics:
%%! %%HTML %%SVG %%bash %%capture %%debug %%file %%html %%javascript %%js %%latex %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefileAutomagic is ON, % prefix IS NOT needed for line magics.
# %环境
您可以管理笔记本的环境变量,而无需重新启动 jupyter 服务器进程。一些库(比如 theano)使用环境变量来控制行为,%env 是最方便的方法。
在[2]中:
# %env - without arguments lists environmental variables
%env OMP_NUM_THREADS=4env: OMP_NUM_THREADS=4
# 执行 shell 命令
您可以调用任何 shell 命令。这对于管理您的虚拟环境特别有用。
在[3]中:
!pip install numpy
!pip list | grep TheanoRequirement already satisfied (use --upgrade to upgrade): numpy in /Users/axelr/.venvs/rep/lib/python2.7/site-packages
Theano (0.8.2)
# 抑制最后一行的输出
有时不需要输出,所以我们可以在新行上使用`pass`指令,或者在末尾使用分号
在[4]中:
%matplotlib inline
from matplotlib import pyplot as plt
import numpy
在[5]中:
# if you don't put semicolon at the end, you'll have output of function printed
plt.hist(numpy.linspace(0, 1, 1000)******1.5);
# 看 python 函数/类/什么的源码带问号(?, ??)
在[6]中:
from sklearn.cross_validation import train_test_split
# show the sources of train_test_split function in the pop-up window
train_test_split??
在[7]中:
# you can use ? to get details about magics, for instance:
%pycat?
将在弹出窗口中输出:
Show a syntax-highlighted file through a pager.This magic is similar to the cat utility, but it will assume the file
to be Python source and will show it with syntax highlighting.This magic command can either take a local filename, an url,
an history range (see %history) or a macro as argument ::%pycat myscript.py
%pycat 7-27
%pycat myMacro
%pycat http://www.example.com/myscript.py
# %run 执行 python 代码
%run 可以从执行 python 代码。py 文件—这是一种有据可查的行为。
但它也可以执行其他 jupyter 笔记本!有时候还是挺有用的。
NB。%run 与导入 python 模块不同。
在[8]中:
# this will execute all the code cells from different notebooks
%run ./2015-09-29-NumpyTipsAndTricks1.ipynb[49 34 49 41 59 45 30 33 34 57]
[172 177 209 197 171 176 209 208 166 151]
[30 33 34 34 41 45 49 49 57 59]
[209 208 177 166 197 176 172 209 151 171]
[1 0 4 8 6 5 2 9 7 3]
['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j']
['b' 'a' 'e' 'i' 'g' 'f' 'c' 'j' 'h' 'd']
['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j']
[1 0 6 9 2 5 4 8 3 7]
[1 0 6 9 2 5 4 8 3 7]
[ 0.93551212 0.75079687 0.87495146 0.3344709 0.99628591 0.34355057
0.90019059 0.88272132 0.67272068 0.24679158]
[8 4 5 1 9 2 7 6 3 0][-5 -4 -3 -2 -1 0 1 2 3 4]
[0 0 0 0 0 0 1 2 3 4]
['eh' 'cl' 'ah' ..., 'ab' 'bm' 'ab']
['ab' 'ac' 'ad' 'ae' 'af' 'ag' 'ah' 'ai' 'aj' 'ak' 'al' 'am' 'an' 'bc' 'bd'
'be' 'bf' 'bg' 'bh' 'bi' 'bj' 'bk' 'bl' 'bm' 'bn' 'cd' 'ce' 'cf' 'cg' 'ch'
'ci' 'cj' 'ck' 'cl' 'cm' 'cn' 'de' 'df' 'dg' 'dh' 'di' 'dj' 'dk' 'dl' 'dm'
'dn' 'ef' 'eg' 'eh' 'ei' 'ej' 'ek' 'el' 'em' 'en' 'fg' 'fh' 'fi' 'fj' 'fk'
'fl' 'fm' 'fn' 'gh' 'gi' 'gj' 'gk' 'gl' 'gm' 'gn' 'hi' 'hj' 'hk' 'hl' 'hm'
'hn' 'ij' 'ik' 'il' 'im' 'in' 'jk' 'jl' 'jm' 'jn' 'kl' 'km' 'kn' 'lm' 'ln'
'mn']
[48 33 6 ..., 0 23 0]
['eh' 'cl' 'ah' ..., 'ab' 'bm' 'ab']
['eh' 'cl' 'ah' ..., 'ab' 'bm' 'ab']
['bf' 'cl' 'dn' ..., 'dm' 'cn' 'dj']
['bf' 'cl' 'dn' ..., 'dm' 'cn' 'dj'][ 2.29711325 1.82679746 2.65173344 ..., 2.15286813 2.308737 2.15286813]
1000 loops, best of 3: 1.09 ms per loop
The slowest run took 8.44 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 21.5 µs per loop0.416
0.416
# %负载
将代码直接加载到单元格中。您可以选择本地文件或网上文件。
在取消下面代码的注释并执行后,它将用文件的内容替换单元格的内容。
在[9]中:
# %load http://matplotlib.org/mpl_examples/pylab_examples/contour_demo.py
# %store:在笔记本电脑之间传递数据时偷懒
在[10]中:
data = 'this is the string I want to pass to different notebook'
%store data
del data # deleted variableStored 'data' (str)
在[11]中:
# in second notebook I will use:
%store -r data
print datathis is the string I want to pass to different notebook
# %who:分析全局范围的变量
在[12]中:
# pring names of string variables
%who strdata
# 时机
当您需要测量花费的时间或找到代码中的瓶颈时,ipython 可以帮上忙。
在[13]中:
%%time
import time
time.sleep(2) # sleep for two secondsCPU times: user 1.23 ms, sys: 4.82 ms, total: 6.05 ms
Wall time: 2 s
在[14]中:
# measure small code snippets with timeit !
import numpy
%timeit numpy.random.normal(size=100)The slowest run took 13.85 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 6.35 µs per loop
在[15]中:
%%writefile pythoncode.pyimport numpy
def append_if_not_exists(arr, x):
if x not in arr:
arr.append(x)
def some_useless_slow_function():
arr = list()
for i in range(10000):
x = numpy.random.randint(0, 10000)
append_if_not_exists(arr, x)Overwriting pythoncode.py
在[16]中:
# shows highlighted source of the newly-created file
%pycat pythoncode.py
在[17]中:
from pythoncode import some_useless_slow_function, append_if_not_exists
# 分析:%prun,%lprun,%mprun
在[18]中:
# shows how much time program spent in each function
%prun some_useless_slow_function()
输出示例:
26338 function calls in 0.713 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function)
10000 0.684 0.000 0.685 0.000 pythoncode.py:3(append_if_not_exists)
10000 0.014 0.000 0.014 0.000 {method 'randint' of 'mtrand.RandomState' objects}
1 0.011 0.011 0.713 0.713 pythoncode.py:7(some_useless_slow_function)
1 0.003 0.003 0.003 0.003 {range}
6334 0.001 0.000 0.001 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.713 0.713
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
在[19]中:
%load_ext memory_profiler
在[20]中:
# tracking memory consumption (show in the pop-up)
%mprun -f append_if_not_exists some_useless_slow_function()('',)
输出示例:
Line # Mem usage Increment Line Contents
3 20.6 MiB 0.0 MiB def append_if_not_exists(arr, x):
4 20.6 MiB 0.0 MiB if x not in arr:
5 20.6 MiB 0.0 MiB arr.append(x)
**%lprun** 是行剖析,但它似乎在最新的 IPython 版本中被打破了,所以这次我们将不用魔法来管理:
在[21]中:
import line_profiler
lp = line_profiler.LineProfiler()
lp.add_function(some_useless_slow_function)
lp.runctx('some_useless_slow_function()', locals=locals(), globals=globals())
lp.print_stats()Timer unit: 1e-06 sTotal time: 1.27826 s
File: pythoncode.py
Function: some_useless_slow_function at line 7Line # Hits Time Per Hit % Time Line Contents
7 def some_useless_slow_function():
8 1 5 5.0 0.0 arr = list()
9 10001 17838 1.8 1.4 for i in range(10000):
10 10000 38254 3.8 3.0 x = numpy.random.randint(0, 10000)
11 10000 1222162 122.2 95.6 append_if_not_exists(arr, x)
# 使用%debug 调试
Jupyter 有自己的接口用于 [ipdb](https://docs.python.org/2/library/pdb.html) 。使得进入函数内部并研究那里发生的事情成为可能。
这不是 pycharm,需要很多时间来适应,但是在服务器上调试时,这可能是唯一的选择(或者从终端使用 pdb)。
在[22]中:
#%%debug filename:line_number_for_breakpoint
# Here some code that fails. This will activate interactive context for debugging
一个简单一点的选项是`%pdb`,它在异常出现时激活调试器:
在[23]中:
# %pdb**# def pick_and_take():
# picked = numpy.random.randint(0, 1000)
# raise NotImplementedError()
# pick_and_take()
# 用乳胶写配方
markdown 单元格使用 MathJax 渲染 latex。
p(a∣b)=p(b∣a)p(a)p(b)p(a∣b)=p(b∣a)p(a)p(b)
Markdown 是笔记本的重要组成部分,别忘了利用它的表现力!
# 在一个笔记本中使用不同的语言
如果你错过了很多,使用其他计算内核:
* %%python2
* %%python3
* % %红宝石
* %%perl
* %%bash
* %%R
是可能的,但是显然您需要首先设置相应的内核。
在[24]中:
%%ruby
puts 'Hi, this is ruby.'Hi, this is ruby.
在[25]中:
%%bash
echo 'Hi, this is bash.'Hi, this is bash.
# 大数据分析
许多解决方案可用于查询/处理大型数据样本:
* [ipyparallel(以前的 ipython cluster)](https://github.com/ipython/ipyparallel) 对于 python 中的简单 map-reduce 操作来说是一个很好的选择。我们在 rep 中使用它来并行训练许多机器学习模型
* [pyspark](http://www.cloudera.com/documentation/enterprise/5-5-x/topics/spark_ipython.html)
* spark-sql magic [%%sql](https://github.com/jupyter-incubator/sparkmagic)
# 让其他人不用安装任何东西就能玩你的代码
像 mybinder 这样的服务可以让用户访问装有 jupyter 笔记本的机器,上面安装了所有的库,这样用户就可以在只有浏览器的情况下玩半个小时。
你可以用 [jupyterhub](https://github.com/jupyterhub/jupyterhub) 设置自己的系统,这在你组织小型课程或研讨会而没有时间关心学生机器时非常方便。
# 其他语言的书写功能
有时候 numpy 的速度不够,我需要写一些快速代码。原则上,你可以在动态库中编译函数并编写 python 包装器…
但是当这个无聊的部分为你做的时候会好很多,对吗?
您可以用 cython 或 fortran 编写函数,并直接从 python 代码中使用它们。
首先,您需要安装:
!pip install cython fortran-magic
在[26]中:
%load_ext Cython
在[27]中:
%%cython
def myltiply_by_2(float x):
return 2.0 ***** x
在[28]中:
myltiply_by_2(23.)
Out[28]:
46.0
就我个人而言,我更喜欢使用 fortran,我发现它对于编写数字运算函数非常方便。
在[29]中:
%load_ext fortranmagic/Users/axelr/.venvs/rep/lib/python2.7/site-packages/IPython/utils/path.py:265: UserWarning: get_ipython_cache_dir has moved to the IPython.paths module
warn("get_ipython_cache_dir has moved to the IPython.paths module")
在[30]中:
%%fortran
subroutine compute_fortran(x, y, z)
real, intent(in) :: x(😃, y(😃
real, intent(out) :: z(size(x, 1)) z = sin(x + y)end subroutine compute_fortran
在[31]中:
compute_fortran([1, 2, 3], [4, 5, 6])
Out[31]:
array([-0.95892429, 0.65698659, 0.41211849], dtype=float32)
我还应该提到,有不同的抖动系统可以加速你的 python 代码。
# 多个光标
因为最近 jupyter 支持多个光标(在一个单元格中),就像 sublime ot intelliJ!

Gif 取自 http://swanintelligence.com/multi-cursor-in-jupyter.html
# [Jupyter-contrib 扩展](https://github.com/ipython-contrib/jupyter_contrib_nbextensions)
安装有
!pip install https://github.com/ipython-contrib/jupyter_contrib_nbextensions/tarball/master
!pip install jupyter_nbextensions_configurator
!jupyter contrib nbextension install --user
!jupyter nbextensions_configurator enable --user

这是一系列不同的扩展,包括例如 **jupyter 拼写检查器和代码格式化器**,它们在 jupyter 中是缺省的。
# [崛起](https://github.com/damianavila/RISE):用笔记本做演示
Damian Avila 的扩展使笔记本电脑作为演示展示成为可能。此类演示的示例:[http://bollwyvl.github.io/live_reveal/#/7](http://bollwyvl.github.io/live_reveal/#/7)
当你教别人使用图书馆时,这是非常有用的。
# Jupyter 输出系统
笔记本显示为 HTML,单元格输出可以是 HTML,因此您可以返回几乎任何内容:视频/音频/图像。
在本例中,我扫描了存储库中包含图像的文件夹,并显示了前五个图像:
在[32]中:
import os
from IPython.display import display, Image
names = [f for f in os.listdir('../images/ml_demonstrations/') if f.endswith('.png')]
for name in names[:5]:
display(Image('../images/ml_demonstrations/' + name, width=300))
# 我可以用 bash 命令获取相同的列表
因为 magics 和 bash 调用返回 python 变量:
在[33]中:
names = !ls ../images/ml_demonstrations/*.png
names[:5]
Out[33]:
['../images/ml_demonstrations/colah_embeddings.png',
'../images/ml_demonstrations/convnetjs.png',
'../images/ml_demonstrations/decision_tree.png',
'../images/ml_demonstrations/decision_tree_in_course.png',
'../images/ml_demonstrations/dream_mnist.png']
# 重新连接到内核
很久以前,当您开始某个耗时的过程,并且在某个时刻您与 ipython 服务器的连接断开时,您完全失去了跟踪计算过程的能力(除非您将这些信息写入文件)。因此,要么中断内核并潜在地丢失一些进程,要么等到它完成而不知道发生了什么。
选项现在可以在不中断计算的情况下再次连接到正在运行的内核,并显示新的输出(但是部分输出已经丢失)。
# 在笔记本上写下你的帖子
比如这个。使用 nbconvert 将它们导出到 html。
# 有用的链接
* IPython [内置魔法](https://ipython.org/ipython-doc/3/interactive/magics.html)
* Ben Zaitlen 关于 jupyter 的精彩互动演示
* 高级笔记本[第一部分:魔法](https://blog.dominodatalab.com/lesser-known-ways-of-using-notebooks/)和[第二部分:小工具](https://blog.dominodatalab.com/interactive-dashboards-in-jupyter/)
* [使用 jupyter 在 python 中进行剖析](http://pynash.org/2013/03/06/timing-and-profiling/)
* [扩展笔记本的 4 种方式](http://mindtrove.info/4-ways-to-extend-jupyter-notebook/)
* [IPython 笔记本小技巧](https://www.quora.com/What-are-your-favorite-tricks-for-IPython-Notebook)
* [Jupyter vs Zeppelin 争夺大数据](https://www.linkedin.com/pulse/comprehensive-comparison-jupyter-vs-zeppelin-hoc-q-phan-mba-)
# Jupyter 笔记本毫无特色——使用 Jupyter 实验室
> 原文:<https://towardsdatascience.com/jupyter-notebooks-are-breathtakingly-featureless-use-jupyter-lab-be858a67b59d?source=collection_archive---------4----------------------->
我们喜欢 Jupyter 笔记本,笔记本格式是构建数据叙事的有效方式。但是浏览器内置集成开发环境只是简单的免费功能,很难提供 Atom、VS Code、Sublime 甚至 RStudio 那种不可思议的编辑能力。因此,从工作流的角度来看,数据科学和数据工程之间的差距仍然很大。让我们缩短这个差距。

Jupyter Notebook
让我们来看看典型的数据科学家工作流程。他们打开笔记本,导入一些数据,做一些探索性分析,然后建立一个模型。如果他们发现了新的东西,他们可能希望在生产中实现它。
*解决方案的当前笔记本表现与生产实施有多接近?*远得不可思议。
笔记本的某些部分是可重用的,可视化的部分我们可能会省去,希望一些功能已经定义。但这正是 Jupyter 笔记本的局限性真正开始显现的地方。
*我的文件树*在哪里?如果我的文件树不容易看到,就很难保持一个干净的、可管理的存储库。不用说,我们也希望一些基本的跳转功能,一次打开多个文档。*如何将我的代码快速转移到 python 脚本中?* *我的终端在哪里?*我知道我可以通过导入和显示熊猫来查看原始数据,但让我们面对现实吧,这与 RStudio 的文件查看器相比相形见绌——我的*合法 csv 查看器在哪里?*和* w *我的 Jupyter 笔记本左右两边浪费的空间是什么?**
正是由于 Python 作为一种语言的优势,以及笔记本文档作为一种呈现叙事的手段,Jupyter 笔记本一直保持着与 RStudio 的竞争力——**而不是 Jupyter 的实际特性**。
当然,所有这些事情都可以通过额外的窗口来解决。但是我们不会对我们的编辑器和 IDE 做出这样的妥协。Atom 为您提供了跳转功能、广泛的热键灵活性、文件树(可以关闭),以及几乎任何您可以在编辑器中想象到的东西。
[Jupyter Lab](https://github.com/jupyterlab/jupyterlab) 在其 *Alpha* 产品中提供了这些对功能的基本期望;尽管产品仍在开发中,但它的功能已经让最初的 Jupyter 笔记本黯然失色。

Jupyter Lab
在 Jupyter Lab 上的 PyData Seattle 演讲中,作者演示了打开 1 万亿行乘 1 万亿列的 csv(并毫不费力地在各列之间左右滚动),以及使用 Jupyter Lab Google Drive 扩展、OOTB 维加和 GeoJSON 兼容性以及许多其他令人难以置信的功能进行实时协作。
Jupyter 实验室和 Jupyter 笔记本有两个不变量。
1. 笔记本文档是相同的(您的旧文档仍然有效)。
2. 笔记本电脑服务器是相同的(您的集成仍然有效)。
我写这篇文章是因为我最近向我的几个同事演示了 Jupyter 实验室。他们的反应?*“我怎么没听说过这个?”*这些功能早就应该出现了,我认为是时候做出改变了,让我们的日常数据科学离生产代码更近一步。
# Jupyter 笔记本,如 Light、Percent 或 Sphinx 脚本
> 原文:<https://towardsdatascience.com/jupyter-notebooks-as-light-percent-or-sphinx-scripts-efca8bc3aa44?source=collection_archive---------18----------------------->
几周前,我们[发布了](/introducing-jupytext-9234fdff6c57) Jupytext,这是 Jupyter 的一个插件,可以像脚本一样读写 Jupyter 笔记本。将 Jupyter 笔记本表示为文本文件大大简化了笔记本的使用。笔记本作为脚本很容易编辑、重构,甚至可以在专门的 ide 中执行。Jupyter 笔记本作为脚本的版本控制产生了有意义的差异。最后,在笔记本的文本表示上合并多个贡献并不比在标准脚本上合并贡献更难,这为在 Jupyter 笔记本上更容易的协作开辟了道路。
Jupytext 的最初版本为笔记本引入了`light`格式作为脚本。从那以后,我们继续探索如何最好地将 Jupyter 笔记本表现为文本文件。我们与 Spyder、Hydrogen 和 Matplotlib 团队进行了有趣的交流,除了`light`格式之外,他们还发现了两种将 Jupyter 笔记本表示为 Python 脚本的现有的流行格式:`percent`和`sphinx`格式。
下面,我们简要回顾一下这三种格式,并回忆一下如何在 Jupyter 笔记本和这三种格式之间来回转换。

# `light`格式
当我们准备 Jupytext 的初始版本时,我们在设计`light`格式时考虑了以下目标:
* 将任意脚本作为笔记本打开,带有有意义的单元格,
* 将笔记本表示为带有少量单元格标记的脚本,如果可能的话,不要标记,
* 在往返转换时保留笔记本的脚本和输入。
普通脚本没有单元格标记。所以我们决定代码段应该是自然细胞。后跟缩进行的空行以及属于多行注释的空行不被视为单元格分隔符。完全注释的段落被理解为标记单元格。
在 Jupytext 中,我们关心的是往返转换——我们不想弄乱你的笔记本!因此,我们必须找到一种方法来明确地识别在 Jupyter 笔记本中包含不止一个代码段的代码单元。为此,我们使用`# +`作为单元开始标记,使用`# -`作为单元结束标记。
对于所有类型的单元格,`light`格式完全支持单元格元数据。包含元数据的单元格有一个显式的头`# + {JSON}`,其中元数据以 JSON 格式表示。
此处提供了`light`格式的笔记本样本[。](https://github.com/mwouts/jupytext/blob/master/demo/World%20population.lgt.py)
`light`格式已经在 Python 脚本上进行了广泛的测试。Jupytext 也为 R、Julia、Scheme、C++实现了那种格式,如果这里没有列出你最喜欢的语言,欢迎询问!
# `percent`格式
受 Matlab 启发的`percent`格式是 Spyder 在五年前推出的。现在支持该格式的有:
* [Spyder IDE,](https://docs.spyder-ide.org/editor.html#defining-code-cells)
* [氢,](https://atom.io/packages/hydrogen)基于原子的笔记本编辑器,
* [VS 代码](https://code.visualstudio.com/)使用 [vscodeJupyter](https://marketplace.visualstudio.com/items?itemName=donjayamanne.jupyter) 扩展时,
* [Visual Studio 的 Python 工具](https://github.com/Microsoft/PTVS),
* [PyCharm 专业](https://www.jetbrains.com/pycharm/)。
Jupytext 也实现了`percent`格式。为了实现 Jupyter 笔记本到`percent`脚本的无损往返转换,我们扩展了格式以支持 markdown 和 raw 单元格,以及单元格元数据。我们实现的单元头是:
%% Optional cell title [cell type]
其中单元格类型要么省略(代码单元格),要么`[markdown]`或`[raw]`。显然,markdown 和 raw 单元格的内容在`percent`脚本中被注释掉了!
这里有`percent`格式的笔记本样品[。](https://github.com/mwouts/jupytext/blob/master/demo/World%20population.pct.py)
格式不限于 Python。 [Hydrogen](https://atom.io/packages/hydrogen) 已经将`percent`格式推广到所有的 Jupyter 语言:Julia、Python、R、Javascript 等等!Jupytext 目前实现了 Julia、Python、R、Scheme 和 C++的`percent`格式。再说一次,你可以要求更多。
上面列出的所有编辑器都可以识别单元格,并允许执行它们的内容。Hydrogen 甚至在输入电池的正下方显示输出,就像 Jupyter 笔记本一样。并且 [Matplotlib](https://gist.githubusercontent.com/mwouts/91f3e1262871cdaa6d35394cd14f9bdc/raw/3e2dde646d66207e132fba30d7c407a5917c0371/percent_format_matplotlib.png) 和 [Plotly](https://gist.githubusercontent.com/mwouts/91f3e1262871cdaa6d35394cd14f9bdc/raw/3e2dde646d66207e132fba30d7c407a5917c0371/percent_format_plotly.png) 两个图都很好的集成在编辑器中。

# 狮身人面像画廊格式
这是 Matplotlib 用来生成其[图库](https://matplotlib.org/gallery.html)的格式。文本单元格表示为三重引号字符串或注释文本块,以带有许多散列符号的行开始。连续的代码单元用空字符串分隔。
Jupytext 实现了 Jupyter 笔记本的`sphinx`格式,这里给出了一个笔记本示例[。如果你想为你的斯芬克斯画廊设计新的例子,使用这种格式,或者反过来,如果你想使用](https://github.com/mwouts/jupytext/blob/master/demo/World%20population.spx.py) [mybinder](http://mybinder.org/) 和 [Jupytext](https://github.com/mwouts/jupytext/blob/master/README.md#sphinx-gallery-scripts) 作为 Jupyter 笔记本访问你的斯芬克斯画廊。
# 使用 Jupytext
使用升级 Jupytext
pip install jupytext --upgrade
Jupytext 为 Jupyter 提供了一个插件,允许你在 Jupyter 中将脚本作为笔记本打开,并与配对的笔记本一起工作(下面将详细介绍)。将 Jupytext 的内容管理器添加到您的 Jupyter 配置文件`.jupyter/jupyter_notebook_config.py`:
c.NotebookApp.contents_manager_class="jupytext.TextFileContentsManager"
通过将`"jupytext": {"formats": "ipynb,py:percent"},`添加到笔记本元数据,将脚本或笔记本转换为配对笔记本。然后,Jupyter 将你的笔记本保存为传统的`.ipynb`文件和补充的`percent`格式的`.py`文件。正如[公告](/introducing-jupytext-9234fdff6c57)中所述,您可以编辑`.py`文件,并刷新 Jupyter 以获得更新的输入单元格(通过在单元格中运行`%autosave 0`关闭 Jupyter 的自动保存)。
或者,使用[命令行转换器](https://github.com/mwouts/jupytext/blob/master/README.md#command-line-conversion)将 Jupyter 笔记本转换为`percent`脚本,然后再转换回来:
create notebook.py with '# %%'-cells
jupytext --to py:percent notebook.ipynb# update input cells in notebook.ipynb
jupytext --to ipynb --update notebook.py
使用以下命令将`light`脚本转换为`percent`脚本:
Convert light.py to percent.py
jupytext --from py:light --to py:percent --output percent.py light.py# In place conversion! Handle with care.
jupytext --from py:light --to py:percent notebook.py
# 所有格式一览

# 结论
将笔记本表示为文本文件可以方便地重构、共享和版本控制 Jupyter 笔记本。作为文本文件的笔记本不包括输出单元格,因此当[将](https://github.com/mwouts/jupytext/blob/master/README.md#paired-notebooks)与传统的`.ipynb`笔记本配对时,它们工作得最好。
Jupyter 笔记本可以用各种文本格式表示。除了 [Markdown](https://github.com/mwouts/jupytext/blob/master/demo/World%20population.md) 和 [R Markdown](https://github.com/mwouts/jupytext/blob/master/demo/World%20population.Rmd) 之外,Jupytext 还将 Jupyter 笔记本实现为`light`和`percent`脚本。使用`light`格式(由 Jupytext 提供)打开任意脚本作为笔记本,并以离散单元格格式保存笔记本。或者用 Spyder 五年前贡献的`percent`格式,现在很多编辑都支持。这四种格式是语言不可知的,已经在 Python、Julia、R、Scheme 和 C++笔记本上进行了测试。
你愿意投稿吗?我们想使格式规范坚如磐石,请让我们知道你是否能帮忙。我们也对向`light`和`percent`格式添加[更多语言](https://github.com/mwouts/jupytext/blob/master/README.md#extending-the-light-and-percent-formats-to-more-languages)的贡献感兴趣。一个能够编辑元数据的[笔记本扩展](https://github.com/mwouts/jupytext/issues/86)将会改善用户体验。
# Jupyter 笔记本让我变成了一个懒惰的程序员…
> 原文:<https://towardsdatascience.com/jupyter-notebooks-made-me-a-lazy-programmer-bef237c310bf?source=collection_archive---------11----------------------->

Don’t try this at home.
## …而且方式不对
像大多数数据科学家和机器学习实践者一样,我使用 Jupyter 笔记本进行原型设计、执行数据分析,并将我的结果传达给其他团队成员、上层管理人员、客户和利益相关者。Jupyter 在这方面很棒,然而不知何故,在几乎专门在笔记本上编码一段时间后,我发现我的编码能力开始下降。过了一段时间,我发现自己染上了坏习惯。
很多时候,我会发现自己在复制和粘贴可以轻松重用的大代码块,或者在需要的地方随意导入代码。如果你只是拼凑一些东西,这没什么问题,但当需要展示你的代码或组装成完整的演示或解决方案时,你不得不争先恐后地将你的片段组装成类似于所谓的机器学习“专家”开发的复杂预测模型的东西。
> 如果把 X 改成 Y 运行,结果会怎么样?
我们都听说过。在自豪地宣称您可以在他们眼前动态运行您的模型并生成结果后,您正在进行现场演示!不要介意你刚刚花了 6 个小时润色你的图表、表格和其他可视化的东西来有效地传达你的结果。因为你已经在笔记本上设计了你的模型,代码很可能是支离破碎的,不能很好地概括来处理这个问题。有时这是不可避免的,但我发现我已经不止一次遇到这种情况,结果是可信度降低。我们都去过那里(…对吗?)
我不是对笔记本有意见,绝对不是。笔记本摇滚。我回想起当初为什么开始用笔记本。听我说,这一切都是有意义的。
我在一台机器上工作,这台机器充当了我团队的 YARN 集群和我在其上开发的其他虚拟机的网关。在我早期的职业生涯中,我使用了许多不同的 ide 和文本编辑器来开发我的代码和模型。现在我在一个充满挑战的环境中工作。我很快就和维姆成为了好朋友。Vim 无处不在,它比大多数人意识到的要强大得多。

vim — it actually doesn’t suck.
这是一个完全不同的问题。我很快开始成为 vim 超级用户,并发现自己比以前更有效率了!我的编码能力提高了,很快我发现自己一直在制造新的算法,能够从一个系统跳到另一个系统,而不必每次都重新配置我的开发环境。我势不可挡…
…至少我是这么认为的。尽管我可以编写大量的脚本和代码来生成可视化效果、表格或写入我们的数据库,而不会有在演示过程中被要求编码的尴尬。即便如此,我还是被迫在编码前思考——在写之前设计我的模型。这留下了大量可重用的设计模式,我可以用它们来构建有效的模型。这极大地增强了我的能力,我将这些代码汇编成库,可以随时调用。现在,我的剧本仅仅是一口袋的台词,然而却能让我领悟到在过去曾让我领悟了数百次的东西。掌握 vim 让我变得懒惰——以一种好的方式!我已经到达了数据科学的天堂,但是我仍然缺少一些东西。
不知何故,一切都太死板了。此外,我只在远程机器上工作。将 matplotlib 可视化中导出的图像复制回我的根计算机以查看结果,挑剔的 X-forwarding,或者依赖于更大的基础设施和 It 限制,这真的很烦人。不,我想要再次自由。我想让我的代码感觉我又一次在一台机器上工作,当我完成或想继续程序执行时,我可以弹出一个绘图窗口并关闭它。此外,我希望向我们的最终用户公开一些我已经编入我的宝贵库中的数据争论和算法功能,其中一些用户本身就是数据科学家。
进入 Jupyter。哇,当我建立了我的第一个 Jupyter 环境并通过代理运行时,我就被迷住了。我可以从任何网关机器上访问它。现在,我甚至可以从任何机器上直接登录到我的环境中,并运行交互式代码。我甚至可以在利益相关者的机器上这样做,并向他们展示我在用他们的数据做什么。感觉棒极了。很快,我的团队让 Jupyter hub 在我们的环境中运行。我仍然可以通过使用我的老朋友 vim 在我们的虚拟机上开发我的结构化代码和库,但是可以使用 Jupyter 快速原型化新算法。什么会出错?
嗯,就像我们大多数人在某个时候发生的一样,我换了工作。我现在正在研究新机器。我的旧代码?不可接近,在我以前的同事手里,对我来说完全看不见。哦,好吧,去做更大更好的事情吧!
我从以前的工作中学到了很多,我想用我学到的知识前进。我立即着手开发一个新的模型,这次我从 Jupyter 笔记本开始。很快,我发现自己的代码杂乱无章,笔记本支离破碎。别让我开始讨论范围问题!然后人们开始要求我和他们分享我的作品。啊哦,人们都会看到我的代码!很快,我发现自己抄近路,走捷径,让事情运行简单,但至少我又有效率了。我的笔记本自给自足,能够从头到尾完整地解释我的过程和模型。
> 你为什么一直滚动这么多代码?我只想看到结果。
有可能,如果你在听到这个之前已经在笔记本上演示过,或者至少是类似的东西。他们是对的——大多数人不关心你的代码,所以虽然展示代码对数据科学家来说很好,但对客户来说就不那么好了,你知道,那些帮你赚钱的人?
进入 reveal.js 这改变了我写笔记本的方式!我可以点击一个小标签,在演示中隐藏我的代码。想展示我的代码吗?打开和关闭非常简单。

我仍然发现自己退回到糟糕的编码习惯。我无法在良好的编码实践和编写可重用性以及 Jupyter 提供的敏捷性之间找到平衡。本质上,因为我没有被强迫去想清楚,所以我没有。我已经变成了一个懒惰的程序员。当然,我是有效的,但是我仍然为我的代码感到尴尬。有时候难看的代码很重要——我们数据科学家有时候需要粗制滥造一个模型,让代码的美丽见鬼去吧。如果有一种方法可以让笔记本快速原型化,并且在共享我的笔记本时隐藏我的代码就好了。我想拥有可演示的笔记本,而不需要旋转一堆旋钮和隐藏代码来让它看起来像样。我需要别的东西。我需要…
…JupyterLab!JupyterLab 就像是上帝给我的礼物。我不仅可以快速组装笔记本,还可以在同一个基于 web 的环境中直接将我的类和函数复制粘贴到文本文件中。这让我重新开始计划。不知何故,让文本文件和笔记本一起编辑让一切都不同了。不仅仅是编辑。实验室能让你接触到终端。但是等等,还有呢!

我找回了我的活力。嗯,部分原因。它至少拥有多年来成为肌肉记忆的相同键绑定。当然,我一直带着它,但是现在我把它放在我心爱的笔记本旁边。但是仍然缺少一些东西。我讨厌轻松的主题。笔记本默认是浅色的,只有通过安装第三方扩展,你才能切换到深色的。这没什么不对的,除非你无法访问你正在使用的 Jupyter 笔记本服务器。JupyterLab 的文本编辑器有多个深色主题,Lab 整体有一个深色主题。

太美了。我已经决定(现在!)是我快速迭代的工作流。如果我发现自己写的东西在演示中没有用武之地,我会把它藏到别处,并从我的笔记本中引用文件或库。这比我以前做的感觉好多了,我只是在这里抓了一点皮毛。如果你喜欢笔记本电脑,但发现自己陷入了和我类似的陷阱,给 JupyterLab 一针——我打赌你会喜欢它。
总而言之:
* 保持你的*真实*代码与你的笔记本分开,除非你在写编码教程。这会让你的笔记本更整洁,养成把东西分开的习惯会让你更有效率。将来你会感谢你的。
* 动笔之前先思考。这将避免不得不当场拼凑一些东西来回答一个问题。能当场跑位是 Jupyter 的一部分实力,用起来!
* 使用 JupyterLab。说真的,太神奇了。
* 玩得开心!
*本文表达的观点为本人观点,不一定与本人雇主相同。
# 提高生产力的 Jupyter 工具
> 原文:<https://towardsdatascience.com/jupyter-tools-to-increase-productivity-7b3c6b90be09?source=collection_archive---------1----------------------->

Photo by [Philip Swinburn](https://unsplash.com/photos/vS7LVkPyXJU?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/search/photos/tools?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)
> *“如果你唯一的工具是一把锤子,你会把所有的问题都看成钉子。”*
>
> *亚伯拉罕·马斯洛*
像许多其他数据科学家一样,Jupyter notebook 是我的数据科学工具包中不可或缺的一部分。它易于使用,功能强大得令人难以置信。在这篇文章中,我将记录一些可用的扩展和特性,我认为每个使用 Jupyter 的人都应该熟悉它们。
但是等等,这难道不是旧东西吗?既然 JupyterLab 刚刚出现,我们现在应该对它感到满意吗?
JupyterLab 是 Jupyter 笔记本电脑的发展,引入了一些期待已久的功能,然而它目前处于测试阶段,当我试用它时,发现许多为 JupyterLab 开发的很酷的扩展由于版本兼容性问题不能很好地工作。所以我想,即使 JupyterLab 是未来,至少在不久的将来,我还是会坚持使用经典笔记本几个月。
# Jupyter contrib nbextensions
你知道 Jupyter 笔记本有扩展吗!确实有,而且非常有用!
*安装*
[官方 github repo](https://github.com/ipython-contrib/jupyter_contrib_nbextensions) 有安装的所有细节,所以我不会重复这些。但是,如果你懒得去过,这里是 TLDR 版本的基本步骤:
pip install jupyter_contrib_nbextensionspip install https://github.com/ipython-contrib/jupyter_contrib_nbextensions/tarball/masterjupyter contrib nbextension install --user
还要安装扩展配置器,以便轻松切换扩展:
pip install jupyter_nbextensions_configuratorjupyter nbextensions_configurator enable --user
你完了!
刷新 Jupyter 主页,您应该能够看到类似这样的内容:

nbextensions tab
以下是一些我认为有用的 nbextensions,并简要描述了它们的功能:
1. *目录(2)* :根据笔记本的表头单元格自动创建一个目录。`Display Table of Contents as a sidebar`选项创建了一个 TOC 作为侧边栏,有助于保持上下文和浏览笔记本。

Table of contents
*2。可折叠的标题*:这个和 toc2 一起可以很好的卷起笔记本中你不想在特定时间关注的部分。

Collapsible heading
*3。代码折叠*:您可以通过折叠函数定义和长代码块来减小单元格的大小。

codefolding
*4。execute time*:`%%time`单元格魔术函数对于检查运行时非常有用。但是有了 ExecuteTime,所有代码单元格的运行时都显示在左下角,所以你不需要记得使用单元格魔术。

execute time
*5。Gist-it* :非常适合在 Github 上创建 Gist。为什么是 gist?实验时可以在不同状态下保存同一个笔记本的不同版本。此外,gists 更容易共享和引用。
*6。隐藏所有输入*:当你需要编码来生成和输出,但是不需要显示代码的时候(为了简洁),这对于整理一个笔记本来演示是很棒的。
# Jupyter 魔法函数
Jupyter 中有很多神奇的功能。对于 Ipython 内核,这里是到文档的[链接。](http://ipython.readthedocs.io/en/stable/interactive/magics.html)
以下是一些我认为特别有用的线条魔术功能:
1. `%cd <path>`:在笔记本中切换工作目录的快捷方式。
2. `%autoreload`:在每个使用脚本/项目的笔记本上使用。您对它们所做的更改将自动重新加载到 jupyter 上下文中。
%reload_ext autoreload
%autoreload 2
1. `%timeit`:多次运行代码行,并打印代码运行时的度量。
2. `%lprun and %mprun`:python 的行分析器和内存分析器。非常适合优化代码:

line profiler in action
要使用 line_profiler,请使用 pip 安装它:
pip install line-profiler
pip install memory_profiler
然后加载扩展:
%load_ext line_profiler
%load_ext memory_profiler
1. `!`或`%%bash` : Bash 命令在终端上很容易使用,但是如果你有一系列需要重复运行的命令,那么把它们放在笔记本上就更好了!一行之前的`!`将在 bash 中执行该行。例如:
!ls -lht
如果您使用 AWS 之类的云服务,并且您有多个 cli 命令,将它们放在一个笔记本中会使事情变得容易得多,因为您有可搜索的命令历史和结果。
注意:由于某种原因,我发现使用单元格魔术`%%bash`会在执行完成后打印输出*。这对于大多数用例来说是好的,但是假设您正在检查 docker 日志,您可能很想检查进度。*
# 临时演员
Jupyter 还可以做很多其他很酷的事情,但我无法一一列举,只能列出一个简短的列表:
1. *Jupyter 小部件:* Jupyter 支持小部件,也支持有用的[交互](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html)甚至很酷的[可视化](http://jupyter.org/widgets)。交互小部件对于创建交互式笔记本来说是很棒的,我想如果你安装了 JupyterHub,它们会更棒,这样你就可以在笔记本上协作了。
2. *跨语言支持:*事实证明,Jupyter 实际上是一个缩写——Julia Python R,并且有许多不同语言的内核。。
3. *调试:【Jupyter 笔记本有很多调试选项,哪一个最有效很大程度上取决于你如何编写代码。对我来说,由于我将大部分代码放在了`.py`文件中,所以我使用 ipython 调试器来调试代码:*
from IPython.core.debugger import set_tracedef func(x):
x = x+2
set_trace()
x = x-2
return xfunc(2)
这将弹出一个交互框来检查笔记本中的变量。
还有更容易使用的选项:
出现异常时打开调试器界面的`%%pdb`单元魔术。
或者你可以在出现异常后立即运行`%debug`行来检查堆栈。
4.Jupyter 笔记本预览与 Vistual 工作室代码
所以笔记本很棒,当你更有条理的时候,你可以用它做更多的事情。但是,笔记本的版本化仍然是个问题。这意味着你可能会为一个项目制作几十个笔记本,如果你想找到一些你在项目早期写的代码,你必须一个接一个地打开它们,或者试着记住 grep 的相关关键词。除了使用命名约定和利用文件夹结构之外,我没有解决版本控制问题的干净的解决方案,但是,对我来说,如果我可以预览笔记本而不必启动内核并等待它加载(特别是如果笔记本很大的话),这是有帮助的。拯救的 Visual Studio 代码!这个方便的文本编辑器与 Sublime Text 非常相似,并且有一个方便的插件`vscode-nbpreviewer`,它允许你在不启动内核的情况下打开笔记本,加载速度非常快。
使用 Visual Studio 代码的另一个好处是:spyder 喜欢脚本中的代码单元,因此您可以将代码从脚本发送到编辑器
此外,它是 Anaconda 的可选安装!
这是我目前所有的。随着我发现更多有用的东西,我会继续更新。感谢阅读!
# JupyterLab 是我们一直在寻找的数据科学用户界面
> 原文:<https://towardsdatascience.com/jupyterlab-you-should-try-this-data-science-ui-for-jupyter-right-now-a799f8914bb3?source=collection_archive---------1----------------------->
Jupyter 项目(正式名称为 IPython)是一个多语言、基于网络的开源数据科学工具。通过[笔记本](http://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/what_is_jupyter.html#notebook-document)的想法,它支持跨[多种编程语言](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels)(所谓的[内核](http://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/what_is_jupyter.html#kernel))的交互式数据科学和[科学计算](https://github.com/jupyter/jupyter/wiki/A-gallery-of-interesting-Jupyter-Notebooks)。
Jupyter 与语言无关的行为使它成为一个可能的游戏规则改变者,因为它将多个开源社区团结在同一个工具周围。它现在有一个很大的社区,并且发展得非常快,导致 Github 上出现了许多扩展——包括一个由 SAS 自己维护的用于 SAS 的[内核,一个用于](https://github.com/sassoftware/sas_kernel) [SPARQL 查询](https://github.com/paulovn/sparql-kernel)的内核,多个[小部件](http://jupyter.org/widgets.html)等等。

Jupyter 目前默认的笔记本界面(上图)已经相当不错了,但它可能已经找到了继任者:JupyterLab。JupyterLab 正在成为 Project Jupyter 的下一代 UI,因为它为用户提供了类似 IDE 的体验(如下图)。JupyterLab 不需要用户处理分散的工具,而是将数据科学家需要的大部分工具放在一起,允许窗口停靠/组合和按需创建动态仪表板。这种可定制的灵活环境无疑会提高工作效率,并可能改变用户对笔记本电脑的看法。

JupyterLab Demo (own)
除了提供像文件浏览器、终端、图像浏览器、控制台、代码/文本编辑器等工具之外。在同一个屏幕上,JupyterLab 允许使用第三方扩展。这种扩展可能不仅与笔记本本身有关,还与整个公共数据科学生态系统有关。作为一个很好的例子,在下面的视频中,我们可以看到一个扩展,允许用户在编辑笔记本时(通过 Google Drive)实时**协作**,以及第二个 UI 优化的扩展,允许用户打开包含(字面上)数万亿行的海量 CSV 文件并与之交互。
你可以在项目的[库](https://github.com/jupyter/jupyterlab)找到更多关于如何安装 JupyterLab 的细节。现在,这里是安装基础:
**如果用康达:**
conda install -c conda-forge jupyterlab
**如果使用画中画:**
pip install jupyterlab
jupyter serverextension enable --py jupyterlab --sys-prefix
**如果你有一个**[**JupyterHub**](https://github.com/jupyterhub/jupyterhub)**环境:**
//Install JupyterLab and then install this extension
jupyter labextension install @jupyterlab/hub-extension//Edit "jupyterhub_config.py" and add/edit the following line c.Spawner.default_url = '/lab'//This issue may be useful for troubleshooting
# **号外:**
下面的演讲(由@[**SylvainCorlay**](https://twitter.com/SylvainCorlay)**在 PlotCon)是一个了解 ipywidgets 和其他基于 Jupyter 构建的流行小部件库提供的大多数特性和功能的好机会。在视频中,您可以看到 JupyterLab 如何通过在嵌套布局中组装简单的控件和可视化小部件来支持仪表板的创作。**
# 只是另一个试图预测股市的人工智能:第 1 部分
> 原文:<https://towardsdatascience.com/just-another-ai-trying-to-predict-the-stock-market-part-1-d0663673a30e?source=collection_archive---------2----------------------->

学习如何建立机器学习模型既不是一件简单的事情,也不是一件容易的事情。我花了一个月左右的时间学习神经网络如何详细工作,以及是什么让某些模型比其他模型表现得更好。
现在我决定将我的知识付诸实践,实现一个相当简单的例子——使用 GRU 网络预测 S&P500 指数的股票价格。
**你可以将这些系列作为你机器学习之旅的起点,所以不要犹豫,毫无准备地投入进去吧。**如果有任何问题,请在评论区与我分享。
## #1.准备数据
我们应该做的第一件事就是获取数据来训练我们的模型。雅虎财经是一个寻找任何公司新数据的好地方。因此,我们将使用从 1950 年 1 月 1 日到今天这段时间的 [S & P500 数据集](https://finance.yahoo.com/quote/%5EGSPC/history?p=%5EGSPC)。只需点击*下载数据*即可。
出于这个例子的目的,我们将只使用一个 python 文件,没有面向对象的模式或任何花哨的结构。让我们将文件命名为 *sp_rnn_prediction.py* 并加载数据。
这些库的目的如下:
* [numpy](http://www.numpy.org/) —用于轻松进行矩阵计算和数学运算,这对于任何 ML 模型都是必不可少的
* [熊猫](https://pandas.pydata.org/) —用于为你的训练数据定义一个好的数据结构
* [sklearn](http://scikit-learn.org/stable/) —用于数据分析的工具(例如标准化或聚类数据)
* [matplotlib](https://matplotlib.org/) —用于显示我们的数据
* [tensorflow](https://www.tensorflow.org/) — Google 的开源库,用于以简单优雅的方式构建 ML 图
数据集应分为训练/验证/测试部分,每个部分都相互独立。我选择将数据分成 80%的训练、10%的验证和 10%的测试。
最后,我用*熊猫*来装载*。csv* 文件,并将其存储到一个数据框架中。我们将在后面看到如何使用它。
## #2.操纵数据
我们的下一步是以某种方式改革数据,使其可用于训练。
首先,我们需要规范化它,这基本上意味着将每个特征缩放到一个给定的范围,在我们的例子中,这个范围在 0 和 1 之间。正常化通过以下方式实现:
我们使用`sklearn.preprocessing.MinMaxScaler()`和`fit_transform`将*开盘价、最高价、最低价和收盘价*中的每个值拟合到 0-1 的范围内,并将这些矩阵转换为(-1,1)的形状。用(-1,1)整形意味着我们希望,例如,`df['open'].values`成为形状(k,1)的矩阵,其中 k 未知,由 numpy 决定。在这种情况下,k 将等于不同价格的数量。
然后,我们需要将数据分为训练、验证和测试。如上所述,80%是培训,10%是验证,10%是测试。
在上面的代码片段中有 3 个主要步骤:
1. 将数据分割成长度相同的不同数组`seq_len`。
2. 根据项目数量确定训练/验证和测试数据的长度。
3. 按照正确的比例划分数据。
## #3.显示数据
最后,我们需要显示规范化的数据。这对于模型性能来说并不重要,但是在调试代码时非常有用。因此,应该养成经常可视化数据集的习惯。
在绘制数据之前,我们需要使用上面定义的方法。
首先,我们复制数据帧并删除未使用的参数(本例中为“Volume”),然后对其他值进行规范化。之后,我们只需要使用 matplotlib 库来绘制它:
* 第 14 行:初始化图像帧。
* 第 15–18 行:绘制不同的值。
* 第 19–23 行:添加符号并显示图形。

S&P500 price visualization (normalized)
## 在下一部分
我们以上面的可视化来结束第一部分。在[第 2 部分](/just-another-ai-trying-to-predict-the-stock-market-part-2-88605f9d8e45)中,我们将重点关注使用价格训练模型。我们将大量使用 TensorFlow,因此您可以看到这个优秀的库在实践中是如何工作的。
## 谢谢你的阅读。如果你喜欢这篇文章,给它一些掌声👏。希望你有一个伟大的一天!
# 只是另一个试图预测股市的人工智能:第二部分
> 原文:<https://towardsdatascience.com/just-another-ai-trying-to-predict-the-stock-market-part-2-88605f9d8e45?source=collection_archive---------3----------------------->

在本节中,我将向您展示如何使用来自[第 1 部分](/just-another-ai-trying-to-predict-the-stock-market-part-1-d0663673a30e)的数据训练模型。我们挑选了一份过去 50 年中每天的标准普尔 500 指数价格清单,并对其做了一些修改。**现在我们要训练我们的模型**,让它尽可能准确地预测未来价格。
在上一部分中,我们使用`load_data`函数和定义为`df_stock`矩阵的价格值将数据分为训练/验证/测试。它是按如下方式完成的:
`x_train, y_train, x_valid, y_valid, x_test, y_test = load_data(df_stock, seq_len)`在哪里`seq_len = 20`。如果你从[我的上一篇文章](/just-another-ai-trying-to-predict-the-stock-market-part-1-d0663673a30e)中考察`load_data`的实现,你会对`seq_len`有更好的理解。基本上,它将数据分成更大的 20 个元素的块。
## #1.定义超参数
当建立机器学习模型时,需要定义一组直接反映模型性能的参数。当你自己做的时候,你可能会发现自己花了太多的时间在调整正确的组合和评估基于你的选择的模型上。在本例中,我们将浏览预定义的,但可以随意更改它们并进行实验。
* `n_steps = seq_len-1`:输入(训练)数据的第一维度。
* `n_inputs = 4`:输入(训练)数据的第二维——不同种类的价格(“开盘价”、“收盘价”、“最高价”、“最低价”)。
* `n_neurons = 200`:用于表示我们 GRU 单元格中隐藏状态的维度。使用隐藏层的数量和输入数据的大小来确定维度。想了解更多信息,我推荐参考这个 Quora 回答。
* `n_outputs = 4`:神经网络输出层的维度。
* `n_layers = 2`:我们希望我们的网络由多少个 GRU 细胞组成。
* `learning_rate = 0.001`:当我们使用梯度下降(或另一个优化器)来最小化损失函数以校正权重和偏差时,使用该比率。
* 通常,在训练时,一次使用全部数据是低效的。这就是为什么我们迭代一组长度为 50 的批处理。
* `n_epochs = 100`:帮助确定训练迭代的次数,每个迭代使用不同的批次。
* `train_set_size = x_train.shape[0]`:也有助于确定训练迭代的次数。
## #2.设置图表
我们的下一步是使用上面的一些参数来建立训练图。但这意味着什么呢?术语“图形”来自张量流的构造方式。基本上,用 Tensorflow 建立模型时,首先需要建立架构(图),然后使用适当的训练数据运行它。
首先是 GRU 层:
* 第 1 行:重置图形堆栈,为新的初始化做准备。
* 第 3–4 行:初始化输入和输出的张量流占位符。
* 第 6 行:使用张量流 GRU 单元格,我们将几个单元格(基于 n_layers 参数)组合成一个列表。GRU 单元用`num_units`和激活函数初始化,在这种情况下激活函数是`leaky_relu`。如上所述,`num_units`是隐藏状态的维度。[激活功能](/activation-functions-neural-networks-1cbd9f8d91d6)应用于结果值。
* 第 8–9 行:将 GRU 细胞堆叠成一个`multi_layer_cell`并运行 [tf.nn.dynamic_rnn](https://www.tensorflow.org/api_docs/python/tf/nn/dynamic_rnn) 来使用输入数据 x 创建递归神经网络
* 第 11 行:重塑网络输出。
现在我们需要添加输出层并设置损失函数:
使用`tf.layers.dense`添加最后一层,该层在对(输入*权重+偏差)应用激活函数后返回输出。
您可以从第 7–9 行看到优化器是如何使用学习率初始化的(我们使用 AdamOptimizer 而不是梯度下降)。然后,我们只需最小化损失函数,在这种情况下,就是均方误差。
如果你觉得有点困惑,把上面的方程看成一个黑盒,我会推荐你略读我之前关于[递归神经网络](/learn-how-recurrent-neural-networks-work-84e975feaaf7)的文章。如果你还有任何问题,就在评论区留下,我会跳出来讨论。
## #3.开始训练
现在最有趣的部分来了——训练模型。一般来说,如果你想得到一组可以做出准确预测的权重和偏差,你至少需要等几个小时。训练的速度取决于上面定义的超参数。
首先,我们将定义一个简单的函数`get_next_batch`,它将使用训练数据生成一批给定大小的数据:
* 第 1–3 行:从每批数据集中定义初始索引,并用 0 到`x_train.shape[0]-1`的值填充一个排列数组。
* 第 6 行:在已经声明的变量前使用 python 关键字`global`将允许我们从函数内部修改以反映全局范围。
* 最后,我们从`x_train`和`y_train`返回大小为`batch_size`的集合。
现在让我们运行图表来训练模型:
* 第 1 行:我们使用 Tensorflow 会话,它用于运行 Tensorflow 操作。
* 第 2 行:用`tf.global_variables_initializer()`我们初始化任何被声明的 Tensorflow 变量。在我们的例子中,我们没有任何。
* 第 3–11 行:我们通过多次迭代来训练模型——通过运行`training_op`,我们最小化了损失函数。第 8-11 行用于通知我们关于 out 培训的进度。
* 第 13、14、15 行:我们根据优化器模型计算输出。在第 3 部分,我们将比较`y_valid_pred`和`y_valid`以及`y_test_pred`和`y_test`,看看我们的模型表现如何。
## 在下一部分
通过以上培训,我们完成了系列的第 2 部分。在[的最后一部分](https://medium.com/p/ee2d419e00c3/edit),我们将使用我们的模型进行预测,看看我们是否能够破解股票市场😄。
## 谢谢你的阅读。如果你喜欢这篇文章,给它一些掌声👏。希望你有一个伟大的一天!
# 只是另一个试图预测股市的人工智能:第 3 部分
> 原文:<https://towardsdatascience.com/just-another-ai-trying-to-predict-the-stock-market-part-3-ee2d419e00c3?source=collection_archive---------7----------------------->

这是我的如何使用递归神经网络预测股票市场系列的最后一部分,我们将进行实际预测。在[第一部分](/just-another-ai-trying-to-predict-the-stock-market-part-1-d0663673a30e)中,我们准备了我们的数据(S & P500 价格),在[第二部分](/just-another-ai-trying-to-predict-the-stock-market-part-2-88605f9d8e45)中,我们训练了我们的模型。现在我将向你展示如何做最后的预测。
## #1.获取预测值
让我们复习一下上一部分的内容。优化我们的模型后,我们获得了预测值(第 13–15 行):
## #2.可视化结果
为了将实际结果与我们的预测进行比较,我们将绘制两者的曲线图,并清楚地看到差异。
首先让我们定义一个新的变量`price = 0`,它将决定价格类型的指数(在这种情况下,我们看开盘价;收盘价为 1,最高价为 2,最低价为 3)
* 绘制训练数据的结果:
在我们图表的 X 轴上,我们将有从 0 到训练数据大小的数字。在 Y 轴上,我们将绘制实际结果和预测结果。
* 绘制验证数据的结果:
在图表的 X 轴上,我们将把从训练数据末尾到验证数据末尾的数字相加。在 Y 轴上,我们将绘制实际结果和预测结果。
* 测试数据的绘图结果:
在我们图表的 X 轴上,我们将把从验证数据末尾到测试数据末尾的数字相加。在 Y 轴上,我们将绘制实际结果和预测结果。
最后,我们需要显示图表的图例:
使用第 2 部分中的 S&P500 数据和超参数,最终的图像应该与此类似:

当然,你的可能会不同,所以我建议用一组参数进行实验,看看什么时候模型会产生最好的结果。
## 最后的想法
我希望这个实现对您有用。如果你有任何问题,请在评论区留言,我们可以一起讨论。
## 谢谢你的阅读。如果你喜欢这篇文章,给它一些掌声👏。希望你有一个伟大的一天!
# 只是“一堆东西”和人工智能的魔力
> 原文:<https://towardsdatascience.com/just-pile-of-stuff-and-magic-of-ai-8bd651428b9d?source=collection_archive---------11----------------------->

*Pile of Stuff*
有多少次你逛商店,告诉他们,你需要一条裙子。但不是所有的裙子,你需要一条长及膝盖的裙子,看起来非常宽松,但没有很多褶皱,而且超级宽松。
等等,这不是真正的裙子,这是一种裤子,看起来像裙子,但不像裙子…
…或者类似的事情。
*你真的不知道。*
但是等等,如果你知道呢?知道它叫“裙裤”。
只需上网,寻找[裙裤](https://www.google.co.in/search?q=buy+culottes&rlz=1C5CHFA_enIN749IN749&oq=buy+culottes&aqs=chrome..69i57j0l5.3185j0j9&sourceid=chrome&ie=UTF-8),瞧,你就可以挑选了。
或者你仍然继续寻找,但你至少知道你在寻找什么。:)

这就是[小队](https://www.squadplatform.com/)正在做的事情。不仅仅是映射正确的东西,或者定义它,或者给它标签,而是让用户能够从一堆东西中找到正确的东西。
想象你开了一个购物平台,你需要一些下装。第一页向你展示了什么是下装,并询问你是在找裤子、运动裤还是裙子。
如果你决定买一条裙子,它会向你展示裙子的几种选择。你知道铅笔裙和紧身衣有多么不同,你挑选它,选择合适的长度,选择合适的颜色,然后把它放到你的购物车里,瞧!世界感觉稍微好了一点,一切尽在你的指尖。
现在,想象一下上面的场景,仅仅好 10 倍,不仅是裙子,还有裤子,上衣,内衣,民族服装,以及所有其他种类的服装。
所有你曾经想到的,但现在更容易找到。
我知道你现在可能在想,这可能吗?你如何去每一家商店,告诉他们对你的“一堆东西”使用相同的定义?
甚至不同的网上购物平台都有自己喜欢的类别,在不同的建筑中寻找特定的商品就像在煤窖中寻找黑猫一样。

但是等等,你听说过一个叫艾的镇上的魔术师吗?只要一眨眼的功夫,它就能帮你找到你正在寻找的那条裙子,因为我们为魔鬼提供了类别和属性的详尽映射。
这就是我们在过去几个月里所做的。在我们的领域专家 Deepika Sai Chitkara 的帮助下,我们创建了一个详尽的类别和属性列表。
我们首先定义了女装,并创建了一个八级深度分类树。
**为什么有女装分类树?**
在 Squad,我们对来自不同客户的产品清单进行[内容审核和质量检查](https://www.squadplatform.com/blog/content-moderation-humans-ai/)。每个客户都有自己的分类来安排产品目录。根据我们的经验,我们观察到没有全球标准可循,至少在时尚领域是如此(在不同客户的分类法中)。相同产品的信息在不同客户之间不一致,例如*客户 A* 认为是裤子*客户 B* 认为是七分裤。
这让我们开始探索一个可以代表时尚行业标准的分类树。但令我们惊讶的是,我们没有发现任何这样的服装行业现有的标准化流程。这就是为什么我们开始研究一个分类树,它可以作为映射不同客户分类的标准。
**分类树中的前 5 个目标**
当我们开始构建女装的品类树和属性列表时,我们有以下目标。
1. 以聚合和标准化客户端上多个数据点。
2. 解决时尚的内容审核用例,并建议适当的类别。
3. 使用丰富和标准的概念,共同解决分类和归属的自动化问题。
4. 在联合模型的帮助下获得自动生成的描述。
5. 为基于搜索相关性和排名的用例创建更好的机器学习模型。
**我们的分类体系树快照&属性模板**
经过我们小型求解团队近一个月的努力,我们为女装建立了一个标准的分类树。以表格形式找到我们的标准分类树的快照。下表仅描述了我们的分类分类树中 218 个节点(女装概念)的 178 个唯一路径中的几个路径。

我们还创建了一个属性模板,其中包含不同客户的所有独特属性的值和指导原则。
在下面找到归因模板的快照,以及视觉相似性的“难度等级”。下表仅描述了我们属性模板中 5 种不同属性类型和 175 个唯一值中的少数属性和值。

**使用分类树和属性模板进行数据标准化和聚合**
我们的分类分类树和属性模板不仅有助于映射视觉上相似的概念并实现标准化,还能帮助我们消除数据集中的不一致。
一个详尽的 8 级深度树帮助我们聚集和标准化了不同客户的近 50–60%的数据点,并使女装分类和属性数据点的数量分别达到 130 万卢比和 40 万卢比,顶级概念下有 15000 多点。使用标准树,我们增加了每个类别的样本数量。因此,这有助于我们学习属性和分类的通用模型,以实现审核和质量检查的自动化。
为您提供一些关于它如何帮助我们消除数据稀疏性的统计数据:下面是一些产品在不同客户中不一致命名的分布表快照,以及使用我们的分类法的最终类别和数量。

我们使用干净和丰富的数据来执行各种实验,以正确分类和检索服装图像,而不使用边界框或丰富的注释来进行归因。我们一直在不断努力进一步改善我们的[基础设施](https://medium.com/@om.vedvasu/evolution-of-kernel-the-backbone-of-squadai-7c605ec64b28),以便我们可以展示 Squad 的人工智能算法的炼金术,用于解决最复杂的消费者对消费者(C2C)内容调节问题,如时尚等用例。

Results using our categorisation pipeline without using bounding boxes or rich annotation on few leaf nodes of our Women’s Apparel Taxonomy Tree. Rows 1–4 are Blouses, Cardigans, Dresses, and Jackets.
**游戏规则改变者**
我们相信,我们现在是印度极少数成功打破女装分类的公司之一。结合我们已经到位的归因指导方针,我们可以成为新一代时尚商业的答案。
由于服装行业没有现成的标准化流程,这样的分类树可以作为 [ISO 61.020](https://www.iso.org/ics/61.020/x/) 未来项目书籍的垫脚石,包括内衣、睡衣、针织品、军装、针织品等。以及它们的标签和尺寸编码方案。我们的分类法也符合 Euratex 的标准,因此对欧洲组织很有用。
再次感谢我们的领域专家 Deepika Sai Chitkara、我们崭露头角的 MLE 实习生 Priyank Jain 和我们的运营团队为这个博客做出的重要贡献。
**对于不知道什么是“一堆东西”的人来说**
米兰达·普里斯特利:【*米兰达和几个助手正在为一套服装挑选两条相似的腰带。安迪窃笑,因为她认为他们看起来一模一样*有什么好笑的吗?
[安迪·萨克斯](http://www.imdb.com/name/nm0004266/?ref_=tt_trv_qu):不,不,不。没什么……你知道,只是这两条皮带在我看来完全一样。你知道,我还在学习这些东西,嗯…
米兰达·普里斯特利:‘这……东西’?哦。好吧。我明白了。你以为这跟你没关系。你走进你的衣橱,选择了……我不知道……那件凹凸不平的蓝色毛衣,比如说,因为你试图告诉世界,你太把自己当回事了,以至于不在乎你背上穿的是什么。但你不知道的是,那件毛衣不只是蓝色,也不是青绿色。不是青金石。其实是天蓝色的。你可能还不知道,2002 年,奥斯卡·德拉伦塔设计了一系列天蓝色礼服。然后我想是伊夫圣罗兰…不是他展示了天蓝色的军用夹克吗?我想我们需要一件夹克。然后天蓝色很快出现在八个不同设计师的作品中。然后它,呃,通过百货商店渗透下来,然后慢慢流到某个悲惨的休闲角落,毫无疑问,你是在那里从某个清仓垃圾箱里找到它的。然而,这种蓝色代表着数百万美元和无数的工作机会,你觉得自己做了一个让你远离时尚行业的选择,这有点滑稽,事实上,你穿着的毛衣是这个房间里的人从一堆东西中为你挑选的。
# Jupyter 笔记本快捷方式
> 原文:<https://towardsdatascience.com/jypyter-notebook-shortcuts-bf0101a98330?source=collection_archive---------1----------------------->

# 什么是 *Jupyter 笔记本*?
*Jupyter 笔记本*广泛用于数据分析。我在 2-3 个月前开始学习 ***数据科学*** 并且我用这个工具探索了一些数据集(数据的集合)。太牛逼了!
让我们看看文档中的定义。
> **笔记本文档**是由 *Jupyter 笔记本 App* 生成的文档,**既可以包含代码**(如 **Python** )也可以包含富文本元素(**段落、等式、链接等)..**)。
>
> ***Jupyter 笔记本应用*** 是一个客户端-服务器**应用**,允许**通过**浏览器**编辑和运行笔记本文档**。
在这里你可以找到更详细的信息,如果你想的话。
# 快捷指令
作为一名开发人员,我喜欢尽可能多地使用快捷方式和代码片段。它们只是让编写代码变得更加容易和快速。我喜欢遵循一条规则:
> 如果你开始用鼠标做一些动作,停下来想一想是否有捷径。如果有一个-使用它。
当我开始使用 *Jupyter Notebook* 时,我不知道这个工具有快捷方式。好几次,我把我的**单元格类型**从 ***代码*** 更改为 ***markdown*** 并且我不知道如何更改。正如你能猜到的,这让我很头疼。有一天我刚好看到菜单栏里有一个`Help > Keyboard Shortcuts`链接。令我惊讶的是,原来 *Jupyter 笔记本*有**一吨的快捷方式**。
在这篇文章中,我将向你展示我最喜欢的几个。请注意,这些快捷方式是针对`Windows`和`Linux`用户的。无论如何,对于`Mac`用户来说,它们是`Ctrl`、`Shift`和`Alt`的不同按钮:
* `Ctrl`:命令键`⌘`
* `Shift`:换挡`⇧`
* `Alt`:选项`⌥`
首先我们要知道它们是 *Jupyter 笔记本 App* 中的 **2 模式**:**命令模式**和**编辑模式**。我将从两种模式之间共享的快捷方式开始。
两种模式下的快捷键:
* `Shift + Enter`运行当前单元格,选择下图
* `Ctrl + Enter`运行选定的单元格
* `Alt + Enter`运行当前单元格,在下面插入
* `Ctrl + S`保存和检查点
在命令模式下(按下`Esc`激活):
* `Enter`进入编辑模式
* `H`显示所有快捷方式
* `Up`选择上面的单元格
* `Down`选择下面的单元格
* `Shift + Up`扩展上面选中的单元格
* `Shift + Down`扩展下面选中的单元格
* `A`在上面插入单元格
* `B`在下方插入单元格
* `X`剪切选中的细胞
* `C`复制选中的单元格
* `V`粘贴单元格下方
* `Shift + V`粘贴单元格上方
* `D, D (press the key twice)`删除选中的单元格
* `Z`撤消单元格删除
* `S`保存和检查点
* `Y`将单元类型更改为*代码*
* `M`将单元格类型更改为*降价*
* `P`打开命令调色板。
该对话框帮助你**运行任何名为**的命令。如果你不知道一些快捷方式,或者当你没有想要的命令的快捷方式时,这真的很有用。

Command Palette
* `Shift + Space`向上滚动笔记本
* `Space`向下滚动笔记本
在编辑模式下(按`Enter`激活)
* `Esc`带你进入命令模式
* `Tab`代码完成或缩进
* `Shift + Tab`工具提示
* 缩进
* `Ctrl + [`德登
* `Ctrl + A`全选
* `Ctrl + Z`撤销
* `Ctrl + Shift + Z`或`Ctrl + Y`重做
* `Ctrl + Home`转到单元格开始
* `Ctrl + End`转到单元格末尾
* 向左走一个单词
* `Ctrl + Right`向右移动一个单词
* `Ctrl + Shift + P`打开命令调板
* `Down`向下移动光标
* `Up`向上移动光标
这些是我在日常工作中使用的捷径。如果你还需要这里没有提到的东西,你可以在快捷键对话框中找到(`H`)。您也可以从菜单栏中的`Help > Edit Keyboard Shortcuts`链接**编辑现有的**或**添加更多的**快捷方式**。单击该链接将打开一个对话框。在它的底部有添加或编辑快捷方式的规则。你需要用连字符`-`来代表应该同时按下的键。**
**例如,我为*重启内核并运行所有单元*命令添加了一个快捷方式`Ctrl-R`。**
# **我的其他博客文章**
* **[数据科学的 Python 基础知识](/python-basics-for-data-science-6a6c987f2755)**
* **[Python 数据科学:Matplotlib 数据可视化简介](/data-science-with-python-intro-to-data-visualization-and-matplotlib-5f799b7c6d82)**
* **[使用 Python 的数据科学:使用 pandas 加载和子集化/过滤数据简介](/data-science-with-python-intro-to-loading-and-subsetting-data-with-pandas-9f26895ddd7f)**
* **[文本自然语言处理介绍](/introduction-to-natural-language-processing-for-text-df845750fb63)**
# **商务化人际关系网**
**如果你想和我联系,这是我的 LinkedIn 个人资料。**
# **时事通讯**
**如果你想在我发表新的博客文章时得到通知,你可以订阅我的时事通讯。**
# **最后的话**
**谢谢你的阅读,如果你喜欢这篇文章,请按住按钮。另外,我很乐意分享您的反馈。**
# 一个深度学习分类器!
> 原文:<https://towardsdatascience.com/k-as-in-keras-simple-classification-model-a9d2d23d5b5a?source=collection_archive---------8----------------------->

希望你知道这篇文章是关于什么的,是的,你是对的!它是关于使用 Keras API 构建一个简单的分类模型。众所周知,Keras 是目前最简单、用户友好和最受欢迎的深度学习库之一,它运行在 TensorFlow/Theano 之上。Keras 上完整的文档是 [**这里**](https://keras.io/) 。Kears 受欢迎是因为以下指导原则。
**模块化**:一个模型可以单独理解为一个序列或者一个图。
极简主义:它提供了足够的可读性。
**Python:** 一切都是原生 Python。
酷,让我们开始使用这个简单的框架构建一个简单的分类器。完整的代码在 [**GitHub**](https://github.com/Msanjayds/Keras/blob/master/Classification_Model_using_Keras.ipynb) 中。
**步骤 1:安装所需的库**
我已经用 [**GoogleColab**](https://colab.research.google.com/notebooks/welcome.ipynb) (感谢谷歌)建立了这个模型。因为所有需要的库都是预安装的,所以我们不需要担心安装它们。只是导入了如下所需的库和函数。

**第二步:加载并拆分数据**(训练并测试/验证)。
对于这个例子,我使用了 Pima Indianas 发病糖尿病数据集。它描述患者病历数据,并告知患者是否患有糖尿病(1:是,0:否)。所有的输入变量都是数值型的,所以我们可以很容易地直接在模型中使用它,而不需要太多的预处理。正如我们在下面看到的,我们有 8 个输入特征和一个输出/目标变量(糖尿病-1 或 0)。

我已经将输入特征和输出分成 x & y 变量。我使用 scikitlearn 的 train_test_split 函数将数据分成训练集和测试集(90:10)。拥有一个验证集对于通过检查我们的模型是否欠拟合、过拟合或泛化来调整模型更有用。

**第三步:** **定义模型**
我们使用的是一个**序列**模型,这是一个简单的线性层叠。我们可以通过向构造器一次传递一个层实例列表来创建这个模型,直到我们对网络拓扑满意为止。

在这个例子中,我使用了一个全连接的 3 层结构(2 个隐藏层,每个层有 100 个节点,1 个输出层有一个节点,不包括输入层)。使用**密集**类定义完全连接的层。层数和节点数是随机选择的。理想情况下,我们需要一个足够大的网络来学习/捕捉数据的趋势/结构。
在第一个隐藏层中,我们需要使用 **input_dim** 参数来指定输入维度的数量(在我们的例子中是 8 个特征)。对于每一层,我们需要指定激活函数(非线性)。我对隐藏层使用了“ **relu** ,因为它提供了比“tanh”更好的性能,对输出层使用了“ **sigmoid** ,因为这是一个二进制分类。
由于我们的训练集只有 691 个观察值,我们的模型很可能会过拟合,因此我对隐藏层应用了 **L2 调节**。权重正则化是一种减少深度学习神经网络模型对训练数据的过拟合并提高测试数据性能的方法。Keras 提供了 3 个**kernel _ regulator**实例(L1,L2,L1L2),它们为损失函数增加了一个权重大小的惩罚,从而在一定程度上降低了它的预测能力,这反过来有助于防止过拟合。
我还使用了**辍学**正规化技术。在这种技术中,在训练过程中,一些随机选择的神经元被忽略,即“退出”。这里我使用了 0.3,即在每次迭代中,我们在给定的层中随机丢弃 30%的神经元。如果需要,我们可以为每个层设置不同的辍学率。由于丢失,它们对下游神经元激活的贡献被暂时取消,并且在向后传递期间没有权重更新被应用于那些神经元。
*如果神经元在训练过程中被随机丢弃,那么其他神经元必须介入并处理对丢失的神经元进行预测所需的表示。这导致所有神经元更好地学习,因此网络对神经元的特定权重变得不太敏感,因此泛化能力更好,不太可能过度拟合。*
**第四步:** **编译模型**
这里,我们需要让模型知道使用什么损失函数来计算损失,使用哪个优化器来减少损失/找到最佳权重/偏差值,以及使用什么指标来评估模型性能。

我们使用**‘二元交叉熵**(负对数损失)’作为我们的损失函数,因为我们只有两个目标类。如果我们的类多于两个,我们可以选择范畴交叉熵。
接下来是模型训练最重要的超参数,**优化器,**在我们的例子中,我们使用了“**亚当**”(自适应矩估计)。其他优化器在整个训练过程中保持单一的学习速率,其中 Adam 随着训练的进行采用学习速率(自适应学习速率)。Adam 结合了 SGD(随机梯度下降)的其他两个扩展的优点,即均方根传播(RMSProp)和自适应梯度算法(AdaGrad)。它利用了 RMSProp 的最大优点,并将它们与动量优化的思想相结合。结果是一个允许快速有效优化的策略。下图显示了不同优化器在迭代过程中训练成本的下降。Adam 提供了最佳性能,收敛速度很快。

下一个参数是“**指标**,用于判断我们模型的性能。其类似于损失函数,除了在训练模型时不使用评估度量的结果。我们使用准确性(**ACC**’)作为我们的度量,它返回一个单一的张量值,代表所有数据点的平均值。
从下面的模型总结中,我们可以看到我们模型的可训练参数细节。(请忽略单词 dense 旁边的数字,如 dense_89、dense_90 等。)
第一层总共有 900 个参数((100 * 8)权重+ (100 * 1)偏差)
第二层有 10100 个参数((100 * 100)权重+ (100 * 1)偏差= 10100)。总的来说,这个模型有 11,101 个可训练参数。

**第五步:训练模型**
编译后,我们可以使用' **fit** '方法训练模型。我们使用训练集(x_train,y_train)来训练模型。我已经用 20 的 batch_size 运行了 500 个**时期**的模型。 **Batch_size** 也是一个随机数(理想值为 10 到 124 ),取决于我们拥有的数据量,它决定了一次迭代中使用的训练样本的数量。因此,在一个给定的时期,我们将有许多迭代。Verbose 可以设置为 0 或 1,它打开/关闭每个时期的日志输出。我们可以使用 **validation_data** 参数提供用于评估损失的 validation_data 和每个时期结束时的任何模型指标,模型将**不会根据该验证数据进行**训练。

with verbose = 1
正如我们在上面看到的,来自最后一个历元的训练精度大约是 75.55,验证精度是 76.62。所有时期的平均训练精度约为 73.03%,平均验证精度为 76.45%。我想这还算可以😉。下图显示了各时期训练和测试数据的准确性和损失。

使用' **predict** '方法对测试数据进行预测,并得出混淆度量。这表明在 77 个测试样本中,我们错分了 12 个样本。我们的准确率达到了 85.7%。

这就是这篇文章的全部内容,非常感谢你阅读到这里。非常欢迎你的评论/建议/纠正。如果你喜欢这个帖子,请👏。下次博客再见。
# k-means——营销组合建模的一个步骤
> 原文:<https://towardsdatascience.com/k-means-a-step-towards-market-mix-modeling-d3feca510d21?source=collection_archive---------7----------------------->

Source: [www.mstecker.com/](http://www.mstecker.com/pages/chfmcflosIMG_2046a1.htm)
聚类是一种无监督的技术,它将某些对象分类成称为簇的组,使得一个簇中的对象与其他簇中的对象相比具有相似的模式和不同的模式。
使用聚类分析的市场细分有助于根据客户行为和其他方面的相似性或独特性将各种市场划分为小的类别。一些特征包括不同品牌的价格点、品牌的市场份额、人口统计(年龄、性别、收入)、行为(使用、频率、忠诚度)、地理、倾向、媒体习惯等。
在本文中,我将介绍一个小型案例研究,说明如何应用 k-means 对各种市场进行聚类,以及从结果中可以获得什么样的见解。
假设一个国家有 20 个市场。我们有每个市场的以下变量的数据:
> 主要品牌的市场份额
>
> 市场份额——您自己的品牌
>
> 市场份额增长—您自己的品牌
>
> 平均价格(主要品牌)
我们需要根据上述特征对市场进行细分,找到 5-6 个集群。因此,每个集群都有相似的特征市场。这将有助于为每个集群制定营销战略,而不是将重点放在所有 20 个市场上。
使用 k-means 算法,市场被划分为 6 类。
采取以下步骤来执行 k 均值:
> I .数据清理和缺失值检查
>
> 二。数据标准化(所有变量有不同的单位)
>
> 三。运行 k = 5 或 6 的 k 均值算法(此处 k 为聚类数)
>
> 四。使用肘方法找到正确的集群数量(您可以使用其他方法,如平均轮廓和间隙统计)
你一定想知道为什么我选择了 5-6 个集群。这就是领域知识发挥作用的地方。通过取 6 个集群,我们假设我们可以将一个国家的市场分成 6 个集群。每个集群中的市场将具有相似的特征。假设或直觉来自领域知识。
基于上述方法,市场被分为 6 类,分析揭示了以下内容:

你可能想知道这些集群是如何形成的,什么是组件 1 和组件 2。在引擎盖下,五氯苯甲醚正在发挥作用。我们也可以用 t-SNE 来表示更高维度的星团。
因此,通过主成分分析,我们知道以下两个变量解释了模型中 80.9%的方差:
> 一、主要品牌市场份额:49.2%
>
> 二。自有品牌市场份额:31.7%
在降维技术中,我们忽略了不能解释太多差异的特征向量/分量,从而减少了变量的数量。在这里,我们不会忽略或删除任何变量,相反,我们的目标是看看哪些变量是集群形成的关键。
**那么,有哪些见解呢?**
> 重申一下,我们有 6 个集群。
>
> 每个集群代表相似的市场
>
> 市场份额是一个变量,基于这个变量可以推断市场的独特性或相似性(记住通过 PCA 得出的方差 80.91!!)
**营销组合建模的链接**
公司通常对了解多个市场的营销组合感兴趣。但是他们可能不会执行这种分析,因为:
> 有限的预算
>
> 时间限制
>
> 由于帕累托原则:80 %的收入来自 20%的市场,他们很少有市场在他们的雷达上。
因此,市场细分拯救了他们。他们可以从每个集群中挑选高潜力市场,并专注于在那里获得正确的营销组合,而不是建立 50 个模型。
*有句谚语说:“不要只看到树木而忽略了森林!!!"*
营销语境中的 k 意味着帮助营销人员“不要只见树木不见森林”

Source: [Max and Dee Bernt/flickr](https://www.flickr.com/photos/lhanaphotography/17313962841)
如果你喜欢我的文章,给它一些掌声,或者更好地与你的朋友或同事分享。
**附注**:最近,很多人问我是否做市场组合建模/营销分析方面的咨询。
您可以将您的咨询问题发布到:[https://www.arymalabs.com/](https://www.arymalabs.com/)
领英:[https://www.linkedin.com/in/ridhima-kumar7/](https://www.linkedin.com/in/ridhima-kumar7/)
推特: [@kumar_ridhima](https://twitter.com/kumar_ridhima)
**版权所有 2018**[**www.ridhimakumar.com**](http://www.ridhimakumar.com)**版权所有。**
# k-均值聚类:算法、应用、评价方法和缺点
> 原文:<https://towardsdatascience.com/k-means-clustering-algorithm-applications-evaluation-methods-and-drawbacks-aa03e644b48a?source=collection_archive---------0----------------------->

# 使聚集
**聚类**是最常见的探索性数据分析技术之一,用于获得关于数据结构的直觉。它可以被定义为识别数据中的子组的任务,使得同一子组(聚类)中的数据点非常相似,而不同聚类中的数据点非常不同。换句话说,我们试图在数据中找到同质的子组,使得每个聚类中的数据点根据相似性度量(例如基于欧几里德的距离或基于相关性的距离)尽可能相似。使用哪种相似性度量的决定是特定于应用的。
聚类分析可以在特征的基础上进行,我们试图根据特征找到样本的子组,或者在样本的基础上进行,我们试图根据样本找到特征的子组。我们将在这里讨论基于特征的聚类。聚类用于市场细分;我们试图找到在行为或属性、图像分割/压缩方面彼此相似的客户;其中我们尝试将相似的区域分组在一起,基于主题的文档聚类等。
与监督学习不同,聚类被认为是一种非监督学习方法,因为我们没有将聚类算法的输出与真实标签进行比较以评估其性能的基本事实。我们只想通过将数据点分组到不同的子组来研究数据的结构。
在本帖中,我们将只讨论 **Kmeans** ,由于其简单性,它被认为是最常用的聚类算法之一。
# Kmeans 算法
**Kmeans** 算法是一种迭代算法,试图将数据集划分为 *K* 个预定义的不同非重叠子组(聚类),其中每个数据点仅属于**一个组**。它试图使簇内数据点尽可能相似,同时保持簇尽可能不同(远)。它将数据点分配给一个聚类,使得数据点和聚类质心(属于该聚类的所有数据点的算术平均值)之间的平方距离之和最小。聚类中的差异越小,同一聚类中的数据点就越相似。
kmeans 算法的工作方式如下:
1. 指定集群数量 *K* 。
2. 通过首先混洗数据集,然后为质心随机选择 *K* 个数据点来初始化质心,而无需替换。
3. 继续迭代,直到质心没有变化。也就是说,数据点到聚类的分配没有改变。
* 计算数据点和所有质心之间距离的平方和。
* 将每个数据点分配给最近的聚类(质心)。
* 通过取属于每个聚类的所有数据点的平均值来计算聚类的质心。
kmeans 解决问题的方法叫做**期望最大化**。E 步骤是将数据点分配给最近的聚类。M 步骤是计算每个聚类的质心。下面是我们如何用数学方法解决它的分解(随意跳过)。
目标函数是:

其中,如果数据点 xi 属于聚类 *k* ,则 wik = 1;否则,wik=0。另外,μk 是 xi 星系团的质心。
这是两部分的最小化问题。我们首先最小化 J . w . r . t . wik,并处理μk 固定。然后我们最小化 J . w . r . t .μk 并处理 wik 固定。从技术上讲,我们首先区分 J w.r.t. wik 并更新集群分配( *E-step* )。然后,我们对 J . w . r . t .μk 进行微分,并在上一步进行聚类分配后重新计算质心( *M 步*)。因此,电子步骤是:

换句话说,将数据点 xi 分配给根据其与聚类质心的距离平方和判断的最近的聚类。
而 M-step 是:

这转化为重新计算每个聚类的质心以反映新的分配。
这里需要注意几件事:
* 由于包括 kmeans 在内的聚类算法使用基于距离的测量来确定数据点之间的相似性,因此建议将数据标准化为平均值为零且标准差为一,因为任何数据集中的要素几乎总是具有不同的测量单位,例如年龄与收入。
* 给定 kmeans 的迭代性质和算法开始时质心的随机初始化,不同的初始化可能导致不同的聚类,因为 kmeans 算法可能*陷入局部最优,并且可能不会收敛到全局最优*。因此,建议使用不同的质心初始化来运行该算法,并选择产生较小距离平方和的运行结果。
* 示例分配不变与组内变化不变是一回事:

# 履行
这里我们将使用 kmeans 的简单实现来说明一些概念。然后,我们将使用更有效的`sklearn`实现来为我们处理许多事情。
# 应用程序
kmeans 算法是一种非常流行的算法,广泛应用于市场分割、文档聚类、图像分割和图像压缩等领域。我们进行聚类分析的目标通常是:
1. 对我们正在处理的数据结构有一个有意义的直觉。
2. 如果我们认为不同子群的行为有很大的差异,那么聚类然后预测不同子群将在哪里建立不同的模型。一个例子是将患者分成不同的小组,并为每个小组建立一个模型来预测心脏病发作的风险概率。
在本文中,我们将在两种情况下应用聚类:
* 间歇泉喷发分割(2D 数据集)。
* 图像压缩。
# 间歇泉喷发分段的方法
我们将首先在 2D 数据集上实现 kmeans 算法,看看它是如何工作的。该数据集有 272 个观测值和 2 个要素。这些数据涵盖了美国怀俄明州黄石国家公园老忠实间歇泉的喷发间隔时间和喷发持续时间。我们将尝试在数据点中找到 *K* 子群,并相应地对它们进行分组。以下是对这些功能的描述:
* 喷发(浮动):以分钟为单位的喷发时间。
* 等待(int):等待下一次喷发的时间。
让我们先绘制数据:

我们将使用该数据,因为它是一个二维数据集,很容易绘制和直观地发现聚类。很明显,我们有两个集群。让我们首先对数据进行标准化,并对 K=2 的标准化数据运行 kmeans 算法。

上图显示了数据的散点图,这些数据由它们所属的聚类进行着色。在这个例子中,我们选择 K=2。符号 **'*'** 是每个簇的质心。我们可以认为这两个星团在不同的场景下有不同的行为。
接下来,我们将展示不同的质心初始化可能会产生不同的结果。我将使用 9 个不同的`random_state`来改变质心的初始化并绘制结果。每个图的标题将是每个初始化的平方距离之和。
作为一个旁注,这个数据集被认为是非常容易的,收敛不到 10 次迭代。因此,为了查看随机初始化对收敛的影响,我将使用 3 次迭代来说明这个概念。然而,在现实世界的应用程序中,数据集一点也不干净漂亮!

如上图所示,基于不同的初始化,我们最终只有两种不同的聚类方式。我们会选择距离平方和最小的一个。
# 图像压缩方法
在这一部分,我们将实现 kmeans 来压缩图像。我们将要处理的图像是 396 x 396 x 3。因此,对于每个像素位置,我们将有 3 个 8 位整数来指定红色、绿色和蓝色强度值。我们的目标是将颜色数量减少到 30 种,并且只使用这 30 种颜色来表示(压缩)照片。为了挑选要使用的颜色,我们将对图像使用 kmeans 算法,并将每个像素视为一个数据点。这意味着将图像从高 x 宽 x 通道重塑为(高*宽)x 通道,也就是说,我们在三维空间中将有 396 x 396 = 156,816 个数据点,这是 RGB 的强度。这样做将允许我们使用每个像素的 30 个质心来表示图像,并将图像的大小显著减小到 1/6。原始图像大小为 396 x 396 x 24 = 3,763,584 位;但是,新的压缩图像将是 30 x 24 + 396 x 396 x 4 = 627,984 位。巨大的差异来自于这样一个事实,我们将使用质心作为像素颜色的查找,这将把每个像素位置的大小减少到 4 位而不是 8 位。
从现在开始,我们将使用 kmeans 的`sklearn`实现。这里需要注意几件事:
* `n_init`是运行不同质心初始化的 kmeans 的次数。最佳结果将会公布。
* `tol`是用于宣告收敛的类内变异度量。
* `init`的缺省值是 **k-means++** ,这应该比随机初始化质心产生更好的结果。

我们可以看到原始图像和压缩图像之间的对比。压缩图像看起来接近原始图像,这意味着我们能够保留原始图像的大部分特征。使用较少的聚类数,我们会以牺牲图像质量为代价获得较高的压缩率。顺便说一下,这种图像压缩方法被称为*有损数据压缩*,因为我们无法从压缩图像中重建原始图像。
# 评估方法
与监督学习相反,在监督学习中,我们有基础事实来评估模型的性能,聚类分析没有可靠的评估度量,我们可以使用它来评估不同聚类算法的结果。此外,由于 kmeans 需要 *k* 作为输入,并且不从数据中学习它,所以就我们在任何问题中应该拥有的集群数量而言,没有正确的答案。有时领域知识和直觉可能会有所帮助,但通常情况并非如此。在聚类预测方法中,我们可以基于不同的 *K* 聚类来评估模型的性能,因为聚类用于下游建模。
在本帖中,我们将讨论两个指标,它们可能会给我们一些关于 *k* 的直觉:
* 肘法
* 轮廓分析
# 肘法
**Elbow** 方法给了我们一个概念,即基于数据点和它们所分配的聚类质心之间的平方距离(SSE)之和,聚类的数量应该是多少。我们在 SSE 开始变平并形成弯头的地方选择 k。我们将使用 geyser 数据集,针对不同的 *k* 值评估 SSE,并查看曲线可能在何处形成肘部并变平。

上图显示 k=2 是个不错的选择。有时仍然很难确定要使用的聚类的数量,因为曲线是单调递减的,可能不会显示任何弯头,或者在曲线开始变平的地方有一个明显的点。
# 轮廓分析
**侧影分析**可用于确定聚类之间的分离程度。对于每个样品:
* 计算同一聚类中所有数据点的平均距离(ai)。
* 计算最近聚类中所有数据点的平均距离(bi)。
* 计算系数:

该系数可以取区间[-1,1]内的值。
* 如果为 0 –>样本非常接近相邻的簇。
* 如果是 1 –>样本远离相邻的聚类。
* 如果是-1 –>样本被分配到错误的簇。
因此,我们希望系数尽可能大,并接近 1,以获得良好的聚类。我们将在这里再次使用间歇泉数据集,因为它运行剪影分析更便宜,实际上很明显,最有可能只有两组数据点。

如上图所示,`n_clusters=2`的平均轮廓分数最好,约为 0.75,所有聚类都高于平均值,这表明它实际上是一个不错的选择。此外,轮廓图的厚度给出了每个簇有多大的指示。该图显示,聚类 1 的样本几乎是聚类 2 的两倍。然而,随着我们将`n_clusters`增加到 3 和 4,平均轮廓分数分别急剧下降到 0.48 和 0.39 左右。此外,轮廓图的厚度开始出现大幅波动。底线是:好的`n_clusters`将有一个远高于 0.5 的剪影平均分,以及所有的集群都高于平均分。
# 缺点
如果聚类具有类似球形的形状,Kmeans 算法在捕获数据结构方面是很好的。它总是试图围绕质心构造一个漂亮的球形。这意味着,当聚类具有复杂的几何形状时,kmeans 在数据聚类方面表现不佳。我们将举例说明 kmeans 表现不佳的三种情况。
首先,kmeans 算法不会让彼此远离的数据点共享同一个聚类,即使它们显然属于同一个聚类。下面是两条不同水平线上的数据点示例,说明了 kmeans 如何尝试将每条水平线上的一半数据点组合在一起。

Kmeans 认为点“B”比点“C”更接近点“A ”,因为它们具有非球形形状。因此,点‘A’和‘B’将在同一聚类中,但是点‘C’将在不同的聚类中。注意**单链**层次聚类方法得到了正确的结果,因为它没有分离相似的点)。
其次,我们将从具有不同均值和标准差的多元正态分布中生成数据。因此,我们将有 3 组数据,每组数据都是从不同的多元正态分布(不同的均值/标准差)中生成的。一个组的数据点将比另外两个组的总和多得多。接下来,我们将对 K=3 的数据运行 kmeans,看看它是否能够正确地对数据进行聚类。为了便于比较,我将首先根据数据来自的分布情况对数据进行着色。然后,我将绘制相同的数据,但现在根据它们被分配到的分类进行着色。

看起来 kmeans 不能正确地计算出聚类。因为它试图最小化类内的变化,所以它给予较大的类比较小的类更多的权重。换句话说,较小聚类中的数据点可以远离质心,以便更多地集中在较大的聚类上。
最后,我们将生成具有复杂几何形状的数据,例如相互重叠的月亮和圆圈,并在两个数据集上测试 kmeans。

正如所料,kmeans 无法找出两个数据集的正确聚类。然而,如果我们使用内核方法,我们可以帮助 kmeans 完美地聚类这些类型的数据集。这个想法是我们转换到更高维的表示,使数据线性分离(同样的想法,我们用在支持向量机)。不同种类的算法在诸如`SpectralClustering`的场景中工作得非常好,见下文:

# 结论
Kmeans 聚类是最流行的聚类算法之一,通常是从业者在解决聚类任务时首先应用的,以了解数据集的结构。kmeans 的目标是将数据点分组到不同的非重叠子组中。当集群有一种球形时,它做得非常好。然而,由于团簇的几何形状偏离球形,它受到了影响。此外,它也无法从数据中获知集群的数量,并且需要预先定义。作为一名优秀的实践者,了解算法/方法背后的假设是很好的,这样你就可以很好地了解每种方法的优缺点。这将帮助您决定何时以及在何种情况下使用每种方法。在这篇文章中,我们讨论了与 kmeans 相关的优点、缺点和一些评估方法。
以下是主要的收获:
* 应用 kmeans 算法时,对数据进行缩放/标准化。
* 选择聚类数的肘方法通常不起作用,因为对于所有的 *k* s,误差函数是单调递减的。
* Kmeans 给予更大的集群更多的权重。
* Kmeans 采用球形的簇形状(半径等于质心和最远数据点之间的距离),当簇的形状不同时,例如椭圆形簇,Kmeans 就不能很好地工作。
* 如果聚类之间存在重叠,则 kman 没有固有的不确定性度量,因为示例属于重叠区域,无法确定为哪个聚类分配每个数据点。
* 即使数据不能被聚类,比如来自*均匀分布*的数据,kman 仍然可以对数据进行聚类。
创建此帖子的笔记本可以在这里找到[。](https://github.com/ImadDabbura/blog-posts/blob/master/notebooks/Kmeans-Clustering.ipynb)
*原载于 2018 年 9 月 17 日*[*imaddababura . github . io*](https://imaddabbura.github.io/posts/clustering/Kmeans-Clustering.html)*。*
# k-均值聚类:从 A 到 Z
> 原文:<https://towardsdatascience.com/k-means-clustering-from-a-to-z-f6242a314e9a?source=collection_archive---------3----------------------->
## 关于 K-均值聚类你需要知道的一切

[Picture by Radu Marcusu](https://unsplash.com/@radu_marcusu) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)
D ata 对于数据科学来说是必不可少的(好像这个名字还不够有启发性)。由于每毫秒都会生成大量数据,因此这些数据中的大部分都没有标记也就不足为奇了。但这没关系,因为有不同的技术可以用来处理未标记的数据集。事实上,有一个完整的机器学习领域叫做“无监督学习”,处理未标记的数据。
有时我们只想看看数据是如何组织的,这就是集群发挥作用的地方。尽管它主要用于未标记的数据,但是它也适用于有标记的数据。“群集”这个词的意思是把相似的东西组合在一起。最常用的聚类方法是 K-Means(因为它很简单)。
这篇文章解释了 K-Means 聚类如何工作(深入),如何测量聚类的质量,选择最佳的 K 数,并提到了其他聚类算法。
# 这个概念
想象你正在开一家小书店。你有一堆不同的书和三个书架。你的目标是把相似的书放在一个书架上。你要做的是拿起 3 本书,每个书架一本,为每个书架设定一个主题。这些书现在将决定剩下的书放在哪个书架上。

每次你从书架上拿起一本新书,你会把它和前三本书进行比较,然后把这本新书放在有类似书的书架上。你可以重复这个过程,直到所有的书都放好。
完成后,你可能会注意到,改变书架的数量,为这些书架挑选不同的初始书籍(改变每个书架的主题)会增加你对书籍的分组效果。所以,你重复这个过程,希望得到更好的结果。
K-Means 算法的工作原理[大概就是这样。](https://www.youtube.com/watch?v=FM7MFYoylVs)
# 该算法
K-means 聚类是开始探索未标记数据集的好地方。K-Means 中的 K 表示聚类数。这个算法一定会在一些迭代之后收敛到一个解。它有 4 个基本步骤:
1. 初始化群集质心(选择这 3 本书开始)
2. 将数据点分配给集群(将剩余的书籍逐一放置)
3. 更新群集质心(从 3 本不同的书开始)
4. 重复步骤 2–3,直到满足停止条件。
您不必一开始就从 3 个集群开始,但是 2-3 个集群通常是一个很好的起点,以后再进行更新。

[Clustering with K=3](https://sandipanweb.wordpress.com/category/uncategorized/)
## 1.初始化 K 形心
作为起点,您告诉您的模型它应该生成多少个集群。首先,模型从数据集中选取 K 个(让 K = 3)数据点。这些数据点被称为簇形心。
现在有不同的方法来初始化质心,你可以随机选择它们,或者对数据集进行排序,将其分成 K 个部分,并从每个部分中选取一个数据点作为质心。
## 2.将聚类分配给数据点
从现在开始,模型自己执行计算,并为每个数据点分配一个聚类。您的模型将计算数据点和所有质心之间的距离,并将被分配给具有最近质心的簇。同样,有不同的方法可以计算这个距离;各有利弊。通常我们使用 L2 距离。
下图显示了如何计算中心体和数据点之间的 L2 距离。每次一个数据点被分配给一个集群时,都要遵循以下步骤。

L2 or Euclidean distance
## 3.更新质心
因为初始质心是任意选择的,所以模型会用新的聚类值更新它们。新值可能出现在数据集中,也可能不出现在数据集中,事实上,如果出现,也只是巧合。这是因为更新的聚类 centorid 是该聚类内所有数据点的平均值。

Updating cluster centroids
现在,如果使用其他算法,如 K-Mode 或 K-Median,而不是取平均值,将分别取 Mode 和 Median。
## 4.停止准则
由于第 2 步和第 3 步会迭代执行,如果我们不设置停止标准,它将永远继续下去。停止标准告诉我们的算法何时停止更新聚类。值得注意的是,设置一个停止标准不一定会返回最好的集群,但是为了确保它返回相当好的集群,更重要的是至少**返回**一些集群,我们**需要**有一个停止标准。
像其他事情一样,有不同的方法来设置停止标准。您甚至可以设置多个条件,如果满足这些条件,就会停止迭代并返回结果。一些停止条件是:
1. 分配给特定集群的数据点保持不变(花费太多时间)
2. 质心保持不变(耗时)
3. 数据点距其质心的距离最小(您设置的阈值)
4. 已经达到固定的迭代次数(迭代次数不足→结果不佳,明智地选择最大迭代次数)
# 评估集群质量
这里的目标不仅仅是制造集群,而是制造好的、有意义的集群。质量聚类是指一个聚类中的数据点靠得很近,而与其他聚类相距较远。
测量群集质量的两种方法如下所述:
1. **惯性:**直觉上,惯性告诉我们一个星团内的点有多远。因此,小惯性是目标。惯性值的范围从零开始上升。
2. **轮廓分数:**轮廓分数表示一个聚类中的数据点与另一个聚类中的数据点的距离。轮廓分数的范围是从-1 到 1。分数应该更接近于 1 而不是-1。
# 有多少个集群?
您必须指定想要创建的集群数量。有几种方法可以选择 k 的最佳值。直接的方法是绘制数据点,看看它是否能给你提示。如下图所示,创建 3 个集群似乎是个不错的选择。

K=3 seems like a good choice
另一种方法是使用惯性值。好的聚类背后的思想是具有小的惯性值和少量的聚类。
惯性值随着簇数量的增加而减小。所以,这是一个权衡。经验法则:惯性图中的肘点是一个很好的选择,因为在那之后惯性值的变化就不显著了。

K=3 is the optimal choice
## 命名集群
当你形成一个集群时,你给它一个名字,集群中的所有数据点都被赋予这个名字作为它们的标签。现在你的数据集有标签了!您可以使用这些标签进行测试。为了深入了解您的数据,您可以查看一个聚类中的数据点有什么相似性,以及它与其他聚类有什么不同。
## 将聚类分配给新的数据点
一旦您最终确定了您的模型,它现在可以将一个集群分配给一个新的数据点。分配聚类的方法保持不变,即,将其分配给质心最近的聚类。
# ⚠️警告!
在执行 K-Means 之前对数据进行预处理是很重要的。如果您的数据集还没有转换成数值,那么您必须将它转换成数值,以便可以执行计算。此外,应用特征约简技术将会加速该过程,并且还会改善结果。这些步骤很重要,因为 K-Means 对异常值很敏感,就像其他使用平均值的算法一样。遵循这些步骤可以缓解这些问题。
我过去常常被聚类和任何非监督算法吓倒,因为我对此知之甚少。我记得我第一次不得不使用 K-Means 来开发音乐推荐引擎时,我一直在想,如果没有标签,我该如何测试最终的模型。在这篇文章中,我试图把 K-Means 的每一个重要的东西打包,并提到了替代方法。我希望这篇文章能帮助你,如果你曾经发现自己处于我的处境。

如果你觉得这篇文章有帮助,请鼓掌👏拍手可以让更多的人看到一个帖子。🐦
> 数据科学新手?给[这篇文章](https://blog.goodaudience.com/data-science-a-piece-of-cake-92a70232e71f)读一读!📖
> 如果您有任何问题或建议,请随时在下面发表。你也可以在 [**Linkedin**](https://www.linkedin.com/in/azika-amelia/) 和我联系。💼
>
> 直到那时和平结束。✌
# k 表示聚类:在陌生人的世界里识别出 F.R.I.E.N.D
> 原文:<https://towardsdatascience.com/k-means-clustering-identifying-f-r-i-e-n-d-s-in-the-world-of-strangers-695537505d?source=collection_archive---------6----------------------->

***Quickie 竞猜时间*** *:* *是什么把某人定义为某人的朋友?你如何在混乱中认出那个人?你如何交朋友?*
嗯,最常见的答案是,两个人之间必须有一些基本的协调,意见的联盟,思想的联盟和喜欢才能形成友谊的纽带。最小的差异会导致亲密和更强的牢不可破的忠诚纽带。交朋友有无数种方式,因人而异,因情况而异。
* 就是这样!!就这些了…!鉴于上述背景,你将更容易联系和理解接下来出现在银盘上的类似类比。事不宜迟,让我们直接进入今天最重要的讨论主题-***【K-均值聚类】*** 。
我知道这听起来有点像带有 *K-means* 的沉重的数据科学行话?!还有*聚类*?!但没必要惊慌,因为这只是科学家口袋里的另一个花哨术语。所以要理解背后的直觉,我们就来“*”。*【分裂()】“这个术语,尽量”。*描述()*“每一个令牌以及随之而来的问题。
我们开始吧..?!..大声说“是”会有帮助..!!..是啊。..酷…蹬踏板!
> **什么是聚类?**-这是一种无监督的机器学习技术,将数据分成不同的组,以便每个组内的观察结果都是相似的。这里每个组都被称为簇。
>
> **什么是无监督机器学习?**-输出未知的机器学习类型。我们试图从给定的输入数据中学习关系、结构和潜在模式。
>
> **什么是 K?**-是你要从数据中形成多少个聚类的数目。它的“手段”部分将在后面更详细地解释。
>
> **那么 K-means 聚类最终是什么呢?**-这是一种无监督的机器学习算法,它将尝试在您的数据中将相似的聚类分组在一起。
既然我们有了基本的想法,让我们进入主题的实质。
# k 均值算法;
研究表明,图形信息比文本信息更容易记忆。所以让我们用图片来学习,因为它们更好*回忆*!

好了,这里我们有一个散点图。假设我们有两个变量从数据集中沿 X 轴和 Y 轴绘制(在 K 均值图之前)。问题是我们能否在变量中识别出某些群体,以及我们如何去做。我们如何识别组的数量?
因此,K-means 为您所做的是,它减少了决策过程的复杂性,并允许您轻松地从数据集中识别那些数据点集群(在 K-means 图之后)。就这样,我们有三个集群(红色,蓝色,绿色)。这是一个非常简单的例子,这里我们只有两个变量,所以是二维的,但请注意,K-means 可以处理多维数据。
# 工作原理:
我将用简单的逐步格式来分解它。
**步骤 1** :选择集群的数量 K——我们将在下一节看到如何选择最佳的集群数量。但是现在我们假设我们选择 K。它可以是任何数字(3、5 或 2 等)。
**第二步**:随机选择 K 个点,质心(不一定来自你的数据集)——质心就是聚类的中心点。您可以从第一个散点图中选择任意两个点,它们可以是任意随机的 X 和 Y 值,前提是您选择的质心数量等于步骤 1 中选择的聚类数量。
**步骤 3** :将每个数据点分配到形成 K 聚类的最近的质心>——现在理解最近是这里的模糊术语。这取决于你测量的是哪种距离,这将由业务问题来定义。最常遵循的是欧几里德距离。当数据包含大值时,曼哈顿距离将是一个很好的选择,如果数据集充满了分类变量,则首选余弦距离。
**步骤 4** :计算并放置每个聚类的新质心。——这在我们研究一个例子的时候会更加清晰。
**步骤 5** :将每个数据点重新分配给新的最近质心。如果发生了任何重新分配,则转到步骤 4,否则停止,这显然是步骤 4 和 5 的迭代过程。
我知道这可能看起来有点复杂,但让我们通过一个视觉示例,以便我们在非常直观的水平上理解这一点,稍后您可以参考这些步骤来挖掘后台发生的事情。

STEP 1: Choose Number K of Clusters: K=2
这里,我们的数据集中有观察值。它们是针对两个变量绘制的,现在的第一个问题是,你能否直观地识别出我们最终将得到的最终集群。那很难,不是吗!这只是两个变量,想象一下,如果我们有三个变量和五个变量,会有什么挑战。我们无法绘制这样的五维散点图。这就是 K-means 算法出现并简化过程的原因。现在让我们看看它是如何进行。在这种情况下,我们将手动执行 K-means 聚类算法,并查看它是如何工作的。通常由 python、R 等工具完成的工作
好吧,假设我们以某种方式确定了最佳聚类数等于 2。我们将再次讨论如何进一步找到最佳集群数量,但目前我们同意只有 2 个集群。

STEP 2: Select at random K points,the centroids(not necessarily from your dataset)
在这一步,我们选择了数据集外的两个随机点,蓝色正方形和红色正方形作为我们的质心。

**STEP 3**: Assign each data point to the closest centroid >That forms K Cluster. (Fig.1b)
对于第 3 步,基本上我们必须检查数据集中的每个数据点,确定两个质心(蓝色或红色)中哪个最近。这一点我们将通过刷新我们的几何知识来确定。我们要做的是用直线连接这些质心,然后用垂线(用绿色虚线标出)平分这条线。绿线上的任何一点与两个质心的距离都是相等的。位于该线上方的点属于蓝色聚类质心,同样,位于该线下方的点属于红色聚类质心。为了简单起见,它们所属的簇的点将被涂上相同的颜色。在我们继续之前,我想提一下“最近”是一个模糊的术语。因为当你在散点图上想象事物时,最近的距离是非常直接的,这意味着我们所看到的距离。根据散点图,我们可以很好地得出结论,点 x 更接近集群 A,点 y 更接近集群 b。*(距离度量的类型:* [*欧几里得*](https://en.wikipedia.org/wiki/Euclidean_distance) *,* [*曼哈顿*](https://www.quora.com/What-is-the-difference-between-Manhattan-and-Euclidean-distance-measures) *,* [*余弦*](https://en.wikipedia.org/wiki/Cosine_similarity) *等。)*

**STEP 4**: Compute and place the new centroid of each cluster.(Fig.1a)
请记住这一点,继续进行第 4 步。想象每个数据点都有一定的权重。所以你需要找到质心,并在散点图上精确定位(用虚线方块表示)。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.1a)
这基本上是通过计算属于特定聚类的数据点的平均值来实现的。在我们的例子中,让我们看看蓝色的聚类点,取每个聚类点的 y 坐标和 x 坐标,分别进行平均,并绘制出平均点。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.1b)
太好了!现在我们进入第五步。在绘制绿线后,我们可以看到有三个点由于以前的隶属关系而被错误分类。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.1c)
因此,我们将移动它们,并根据聚类的质心对它们重新着色。由于重新分配了数据点,我们将返回到步骤 4。

**STEP 4**: Compute and place the new centroid of each cluster.(Fig. 2a)
基于重新分配,我们重新计算质心,并为每个聚类放置质心。

**STEP 4**: Compute and place the new centroid of each cluster.(Fig. 2b)
确定每个簇的新质心,用虚线方块表示,并在这些位置移动质心。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.2b)
重复步骤 5。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.2a)
注意绿线上方的红色数据点(见步骤 5 的图 2a)被重新分配给蓝色聚类。

**STEP 4**: Compute and place the new centroid of each cluster.(Fig. 3a)
重复步骤 4。正如我们所见,这是一个迭代过程。我们继续这样做,直到算法收敛。

**STEP 4**: Compute and place the new centroid of each cluster.(Fig. 3b)
第三次迭代的步骤 4。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.3a)
第五步第三次迭代。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.3b)
你可以再次看到等距的绿线。

**HSTEP 4**: Compute and place the new centroid of each cluster.(Fig. 4a)
第四次迭代的步骤 4。

**STEP 4**: Compute and place the new centroid of each cluster.(Fig. 5a)
在步骤 5 中,将每个数据点重新分配给新的最近质心。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.4a)
第五次迭代的第四步。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.5a)
我们非常接近我们集群的最终成员。

**STEP 4**: Compute and place the new centroid of each cluster.(Fig. 6a)
第六次重复步骤 4。

**STEP 4**: Compute and place the new centroid of each cluster.(Fig. 6b)
计算并在每个簇中放置新的质心。

**STEP 5**: Reassign each data point to the new closest centroid. If any reassignment took place,go to STEP 4, otherwise stop.(Fig.6a)
现在,当我们第六次运行步骤 5 时,请注意集群成员没有变化。比较步骤 5 的图 5a 和图 6a。因此,我们可以安全地得出结论,我们的 K-means 算法已经收敛,最终模型准备就绪。

Finally !!!
这是我们用 K-means 算法建议的两个聚类。希望我已经用简单的术语成功地揭开了算法的神秘面纱。
> [**这里的**](http://nbviewer.jupyter.org/github/PBPatil/K-means-Clustering/blob/master/K-means_clustering_1.ipynb) 是在 Iris 数据集上尝试 K-means 聚类的实际例子。
# 选择最佳 K 值-
K 均值聚类的一个严重缺点是 K 值。
现在,为了便于理解,举例来说,如果在上述场景中有 2 个集群会更好,或者有 10 个集群会更好。我们需要一定的度量。我们需要一种方法来评估特定数量的群集如何比不同的群集表现得更好,并且该指标最好是可量化的。那么,我们对聚类算法施加什么样的度量,会告诉我们一些关于最终结果的信息呢?
对此的补救措施是簇内变异**。**
组内变异在数学上表示为误差平方和(WCSS/SSE)。它也被称为“肘法”。

乍一看,这个公式似乎很复杂,但实际上非常简单。根据我们的使命,化繁为简,让我们把它分解开来。

基本上我们在这里做的是…
聚类 1 中的每个数据点(聚类 1 中的 Pi),测量 Pi 数据点和聚类 1 的 C1 质心之间的差{距离(Pi,C1)}并将它们相加(大的“E”符号称为 sigma,它表示相加)
其他集群也是如此。
如果你把 K 对着上证指数作图,你会看到误差随着 K 变大而减小;这是因为当集群数量增加时,它们应该更小,因此失真也更小。
肘法的思路是选择 SSE 突然下降的 K。
这在图中产生了“肘效应”。
> 在这里 我已经接触了肘方法的概念和其他一些概念。
**参考文献**:
[](https://www.udemy.com/machinelearning/) [## 机器学习 A-Z:数据科学中的 Python & R 实践
### 向两位数据科学专家学习用 Python 和 R 创建机器学习算法。包括代码模板。
www.udemy.com](https://www.udemy.com/machinelearning/) [](https://www.udemy.com/python-for-data-science-and-machine-learning-bootcamp) [## Python 用于数据科学和机器学习训练营
### 了解如何使用 NumPy、Pandas、Seaborn、Matplotlib、Plotly、Scikit-Learn、机器学习、Tensorflow 等等!
www.udemy.com](https://www.udemy.com/python-for-data-science-and-machine-learning-bootcamp) [](http://www-bcf.usc.edu/~gareth/ISL/) [## 统计学习导论
### 作为一名前数据科学家,我最常被问到的问题莫过于“学习统计学的最佳方法是什么?”?“我……
www-bcf.usc.edu](http://www-bcf.usc.edu/~gareth/ISL/)
从 1 到哈姆雷特,你有多优柔寡断?好吧,有一个巧妙的方法可以解决生活中令人烦恼的困境,我们下次再见时再看 **!**
**阅读我发表的其他文章**—
1. [如何使用 Python 从 Excel 创建 PDF 报告](https://medium.com/@theprasadpatil/how-to-create-a-pdf-report-from-excel-using-python-b882c725fcf6)
2. [什么是探索性数据分析?](/exploratory-data-analysis-8fc1cb20fd15)
3. [最后一分钟修订:第一部分—机器学习&统计](https://medium.com/@theprasadpatil/last-minute-revision-part-i-machine-learning-statistics-8de23a377987)
# 潜入 K-Means…
> 原文:<https://towardsdatascience.com/k-means-clustering-implementation-2018-ac5cd1e51d0a?source=collection_archive---------7----------------------->
我们已经在上一篇 [***这里***](https://medium.com/@diti.modi/linear-regression-model-899558ba0fc4) 完成了我们的第一个基本监督学习模型,即线性回归模型。因此,在这篇文章中,我们从最基本的无监督学习算法开始- **K 均值聚类**。事不宜迟,我们开始吧!
## **背景:**
顾名思义,K-means 聚类是一种聚类算法,没有预先确定的标签,就像我们对线性回归模型一样,因此被称为无监督学习算法。
## **逻辑与工作:**
> *K-means 简单地将给定数据集划分成具有不同特征的各种聚类(组)。*
**到底如何?**
k 是指在整个数据集中定义的聚类总数。有一个为给定聚类类型选择的质心,用于计算给定数据点的距离。距离本质上表示数据点的特征与聚类类型的相似性。
> 我们可以以校车为例来说明这一点。如果我们有来自特定区域(集群)的许多学生(数据点)通过校车前往学校,学校声明一个中心汽车站(质心),来自附近地区的所有学生可以在此集合登上校车(集群过程)。
**约束:**
只能使用**数值数据**。一般来说,k-means 最适合二维数值数据。在 2d 或 3d 数据中可视化是可能的。但实际上,一次总有多个特征需要考虑。
因此,可以使用多维数据,但是在将数据用于 k-均值之前,必须对数据进行降维。
*选择 K:*
没有确切的方法来确定 K(用于划分的总聚类数)的理想值。我们必须对给定的数据集尝试不同的 K 值,并比较由此获得的结果。
## 为什么要用 K-means?
> 使用 k-means,在分析数据之后对数据进行聚类,而不是基于预定义的标签将其原始地定义在一个组下。每个质心都是本质上代表其所属聚类类型的特征的集合。因此,质心可以用来解释所形成的集群的类型。
## 现实生活应用:
1. 客户零售细分分为不同数据分析应用的聚类,例如了解忠诚客户、分析客户的消费行为或特定类型客户的需求。
2. 网络犯罪欺诈的欺诈检测。
3. MP3 文件、手机是使用这种技术的一般领域。英语中大约有 40 种不同的声音。
# TL;速度三角形定位法(dead reckoning)
在这里,我们执行整个机器学习过程,而不仅仅是算法实现。
> 注意:我们在这里从头开始实现 K-means。“scikit-learn”库,Python 中的机器学习库内置了 K-means 方法,可以直接使用。
## 为机器学习方法执行的步骤是:
1. 数据预处理
2. 数据分析
3. 模型实现
## k-means 算法的基本步骤:
步骤 1:从数据集中的值中选择 k 个质心的随机值(这里 k=2)
步骤 2:计算每个质心的每个点的欧几里德距离
步骤 3:比较距离并分配聚类
第四步:取平均值,重复直到误差为零
4.结果可视化
## **实施:**
> 1.数据预处理
在使用现有数据之前,我们必须对其进行预处理,以获得准确的结果。预处理包括数据清洗、数据争论、特征提取、数据归约等。这些根据数据和要求而变化。
这里我们导入 numpy、pandas、matplotlib 库,分别用于数组处理、数据帧使用和数据可视化。数据被读取并存储在名为“data”的数据帧中。这里的编码被指定为“ISO-8859–1 ”,因为我们的 csv 文件是“utf-8”格式的,以便于阅读。data.head()显示整个数据集的前 5 行。

我们通过(total_rows,total_columns)格式的 data.shape 找到数据帧的大小。数据清理是为了清除空值或缺失值。为此,我们需要使用 data.isnull()知道数据中空值的数量。sum()。它在每个属性列中提供总的空值。我们可以使用“data.drop.na()”删除所有空值条目。
因为我们在这里只想使用数字数据来表示 K-means,而且属性中没有空值,所以我们可以让数据保持原样。

特征提取在数据分析部分进一步完成。
> 2.数据分析
我们用 data.describe()存储在“summary”变量中获得数据的摘要。我们转置它来交换行和列。summary.head()显示摘要。

可以进行数据可视化,以可视化该列中的分布,无论它是否倾斜,绘制直方图、箱线图、散点图。这里绘制了“销售额”、“订购数量”和“价格”的直方图。我们可以使用“SALES”和“QUANTITYORDERED”来根据产品的销售额和订购数量形成集群。

现在我们绘制一个散点图。“x”仅用于保存我们需要的“数据”中的 2 列,以及所有行条目。接下来,我们绘制散点图,将图形大小设置为 16x9,样式设置为 ggplot,这样就形成了一个网格。plt.scatter()用黑色圆点绘制 x 数据帧的第 0 列和第 1 列,大小为 7。

我们的初始数据看起来像这样,没有分组:

我们的数据中有异常值。离群值只是远离其他数据点的值,它们不适合我们的数据,可能会妨碍我们的准确性。
正如我们看到的,在我们的数据中有许多异常值,我们通过计算 z-score 来删除这些异常值。zscore()是 python 的 scipy 库中的内置函数。
Z score 使我们的数据正常化。在这里,我们得到的 z 得分的绝对值在-3 到 3 的范围内,所有点都存储回 x 中,所有其他行都被删除。
正如我们注意到的,x 的形状从最初的行数变化到更少的行数,因为删除的行数更少。

> 3.k-均值实现
因此,现在我们终于在获得最终数据后开始实际的算法实现。我们只是在这里导入复制库和其他基本库。deepcopy 用于将一个数组复制到另一个数组中。我们用它来存储质心的历史,可以用来提前计算误差。
我们定义一个函数“欧几里得”来计算两点“a”和“b”之间的距离。np.linalg.norm()是 numpy 库中的内置函数,它在这里计算 a 和 b 的欧氏距离。

接下来我们定义 main()函数。这里我们应用所有的 k 均值算法步骤。
K-Means 的第一步:选择随机质心
因此,第一步是从数据集本身选择随机质心。Numpy 具有内置函数 np.random.choice(),其参数为 x.shape[0],给出了总行数和 2 列数,即聚类数,replace 设置为 false,即 x 不被这些值替换。

我们可以打印出质心的随机值,然后我们定义所有的变量以备将来使用。我们将“total”变量定义为 x 的形状值。“ditance_1”和“distance_2”分别定义为从数据中的每个点到质心 1 和质心 2 的距离,我们用大小为 total[0]的零对其进行初始化。因此,这些是 x 中总行数的 1D 数组
“belongs_to”用于存储数据点所属的簇的值。它通过索引对应于 x 中的每个数据点。它还被初始化为零和 total[0]的大小,以便存储每个数据点的逐行的簇号(这里是-0,1 编号的簇)。“c_old”存储质心的旧值。这里它被初始化为零,并且是“形心”的形状。
“误差”用于存储当前质心和旧质心的欧几里德距离,即如果两个质心值相同,误差变为零。“mean”用于存储新的质心。因此,它是“质心”的大小,并被初始化为零。“np.zeros()”是 Numpy 中的内置函数,它通过将大小作为参数传递来将给定数组初始化为零。最后“iterator”计算执行的迭代总数。目前为零。

**K-Means 的第二步:计算欧氏距离**
接下来,我们执行步骤 2,计算每个质心的每个数据点的欧几里德距离。循环条件是误差不等于零,如果误差变为零,那么计算的质心与前一个相同,所以循环将在那里停止。我们打印出迭代次数,并开始 for 循环来计算欧几里得距离。

**K-Means 的步骤 3:比较距离**
因此,步骤 3 将这些距离相互比较,并相应地分配聚类。因此,“if”条件为第一组分配 0,为第二组分配 1。“属于”值根据每个数据点与第一个和第二个质心的距离而变化。

**K 均值第 4 步:取均值,重复**
最后一步现在通过分别对聚类 1 数据点和聚类 2 数据点取平均值来计算新的质心。我们使用“deepcopy”复制 c_old 中旧质心的值。for 循环一直进行到 belongs_to 的范围,为第一个聚类分配每列的平均值。“np.mean()”是用于计算平均值的内置 Numpy 函数。现在我们知道为什么我们在 Python 中如此广泛地使用 Numpy 了!:P
为了清楚起见,我在这里使用了单独的“均值”变量。我们可以替换“质心”变量并在这里重新使用它。

我们对聚类 2 的平均值进行相同的循环,其中 belongs_to()值为 1,而聚类 1 的平均值为 0。

然后,我们将平均值分配给质心,并计算旧质心和新质心的误差。迭代器加 1,条件错误检查在这里完成。如果误差为 0,则传送相同质心值的消息,然后循环停止。

> 4.结果可视化
最后,我们执行机器学习过程的最后一步,可视化我们的聚类点。我们使用和以前一样的情节。唯一改变的是每个簇的颜色。我们用红色‘r’和绿色‘g’来代表每个聚类。我们将“点”指定为 x 的数组,该数组位于其所属行的范围内,其中“所属行”的值为 0 或 1。我们只是将红色点(颜色[0])分散到聚类 1(属于 _ 属于[]=0),将绿色点(颜色[1])分散到聚类 2(属于 _ 属于[]=1)。我们指定星号(*)标记,用黑色标出最终质心。
最后,我们调用主函数来执行模型。

完整的代码和数据集可在[这里](https://github.com/ditsme/Machine-Learning/tree/master/100-Days-Of-ML-Code/Day-06-07-k-means)获得。我还添加了运动员数据的另一个实现,这可以使数据清理部分变得清晰,因为我们删除了那里的重复值和空值。
## **输出:**
我得到的输出如下:
> 注意:这里的输出可能会有所不同,因为我们最初是随机选择质心的。这里仅执行 2 次迭代,直到误差变为零。

聚类:
绘制散点图时考虑最终迭代质心和聚类。

对于任何疑问或评论,请在下面评论,让我知道你是否喜欢这个博客!;)
# k-均值聚类—机器学习算法简介
> 原文:<https://towardsdatascience.com/k-means-clustering-introduction-to-machine-learning-algorithms-c96bf0d5d57a?source=collection_archive---------0----------------------->
## 最简单的聚类算法—代码和解释

## 简介—无监督学习
在机器学习中,我们并不总是被提供一个目标来优化,我们也不总是被提供一个目标标签来对输入数据点进行分类。在人工智能领域中,没有目标或标签可供我们分类的问题被称为无监督学习问题。在无监督学习问题中,我们试图对数据中存在的潜在结构化信息进行建模。聚类是一种无监督学习问题,我们试图根据相似数据的底层结构将它们分组到群组/聚类中。K-means 算法是一种广泛使用的著名聚类算法。k 代表我们要将数据点分类到的聚类数。
## K-Means 伪代码
K-Means Clustering 1. Choose the number of clusters(K) and obtain the data points
2. Place the centroids c_1, c_2, ..... c_k randomly
3. Repeat steps 4 and 5 until convergence or until the end of a fixed number of iterations
4. for each data point x_i:
- find the nearest centroid(c_1, c_2 .. c_k)
- assign the point to that cluster
5. for each cluster j = 1..k
- new centroid = mean of all points assigned to that cluster
6. End
下面的模拟将提供对 K-means 算法的更好理解。

K — Means Algorithm
## 怎么选 K??
在某些情况下,我们不知道集群的数量。那么,我们如何选择 K 的值呢???有一种方法叫肘法。在这种方法中,选择不同数量的簇,并开始绘制簇内到质心的距离。图表如下所示。

Elbow method
从上图中我们可以推断出,在 k=4 时,该图达到最佳最小值。即使类内距离在 4 之后减少,我们也会做更多的计算。这类似于收益递减定律。因此,我们选择值 4 作为聚类的最佳数量。之所以称之为肘关节法,是因为最佳聚类数代表一个肘关节!
## K-均值聚类算法的应用
* 行为细分
* 异常检测
* 社会网络分析
* 市场细分
只有几个应用聚类算法(如 K-means)的例子。
## 让我们写一些代码
我们将使用[虹膜数据集](https://www.kaggle.com/jchen2186/machine-learning-with-iris-dataset/data)来构建我们的算法。即使虹膜数据集有标签,我们也将丢弃它们,只使用特征点对数据进行聚类。我们知道有 3 个聚类(“鸢尾-海滨鸢尾”、“鸢尾-刚毛鸢尾”、“鸢尾-杂色”)。因此,在我们的例子中 k=3。
我们加载数据集并删除目标值。我们将特征点转换成一个 numpy 数组,并将其分成训练和测试数据。
我们实现了上面显示的伪代码,我们可以发现我们的算法在 6 次迭代后收敛。我们现在可以输入一个测试数据点,找到它最接近的质心,并将该点分配给相应的聚类。
Scikit-learn 库通过提供一个我们可以用来实现算法的抽象层次对象,再一次使我们免于编写这么多行代码。
## 结论
K-means 是聚类技术的入门算法,也是最简单的算法。你可能已经注意到了,这里没有目标/损失函数。因此,不需要偏导数,并且消除了复杂的数学运算。K-means 是一种易于实现的简便算法。
## 参考
[](https://www.datascience.com/blog/k-means-clustering) [## K-均值聚类简介
### 具体话题经验:新手职业经验:无行业经验机器知识…
www.datascience.com](https://www.datascience.com/blog/k-means-clustering)
# k-means 聚类:MATLAB、R 和 Python 代码——你所要做的只是准备数据集(非常简单、容易和实用)
> 原文:<https://towardsdatascience.com/k-means-clustering-matlab-r-and-python-codes-all-you-have-to-do-is-just-preparing-data-set-very-151002d1f8ca?source=collection_archive---------2----------------------->

我发布 k-means 聚类的 MATLAB,R 和 Python 代码。它们非常容易使用。你准备数据集,然后运行代码!然后,可以执行 AP 聚类。非常简单容易!
你可以从下面的网址购买每一个代码。
## 矩阵实验室
[https://gum.co/Lowcz](https://gum.co/Lowcz)
请从下面的网址下载补充压缩文件(这是免费的)来运行 k-means 代码。
[http://univproblog . html . xdomain . jp/code/MATLAB _ scripts _ functions . zip](http://univprofblog.html.xdomain.jp/code/MATLAB_scripts_functions.zip)
## 稀有
[https://gum.co/YdBm](https://gum.co/YdBm)
请从下面的网址下载补充压缩文件(这是免费的)来运行 k-means 代码。
[http://univproblog . html . xdomain . jp/code/R _ scripts _ functions . zip](http://univprofblog.html.xdomain.jp/code/R_scripts_functions.zip)
## 计算机编程语言
[https://gum.co/EYGPR](https://gum.co/EYGPR)
请从下面的网址下载补充压缩文件(这是免费的)来运行 k-means 代码。
[http://univprovblog . html . xdomain . jp/code/supporting functions . zip](http://univprofblog.html.xdomain.jp/code/supportingfunctions.zip)
# k-means 在 MATLAB 中的程序,R 和 Python 代码
为了执行适当的 k-means,加载数据集后,MATLAB、R 和 Python 代码遵循以下程序。
**1。决定集群的数量**
**2。自动缩放解释变量(X)(如有必要)**
自动缩放意味着居中和缩放。通过从居中的变量中减去每个变量的平均值,每个变量的平均值变为零。通过将每个变量的标准偏差除以换算中的变量,每个变量的标准偏差变为 1。
**3。运行 k-means**
**4。可视化聚类结果**
例如通过 PCA 进行数据可视化。通过改变散点图中不同聚类的颜色,可以很容易地看到聚类。
# 如何进行 k-means?
## 1.购买代码并解压文件
**MATLAB**:[https://gum.co/Lowcz](https://gum.co/Lowcz)
**R**:[https://gum.co/YdBm](https://gum.co/YdBm)
**蟒蛇**:【https://gum.co/EYGPR】T2
## 2.下载并解压缩补充 zip 文件(这是免费的)
**MATLAB**:[http://univprovblog . html . xdomain . jp/code/MATLAB _ scripts _ functions . zip](http://univprofblog.html.xdomain.jp/code/MATLAB_scripts_functions.zip)
**R**:[http://univprovblog . html . xdomain . jp/code/R _ scripts _ functions . zip](http://univprofblog.html.xdomain.jp/code/R_scripts_functions.zip)
**Python**:[http://univprovblog . html . xdomain . jp/code/supporting functions . zip](http://univprofblog.html.xdomain.jp/code/supportingfunctions.zip)
## 3.将补充文件放在与 k-means 代码相同的目录或文件夹中。
## 4.准备数据集。有关数据格式,请参见下面的文章。
[https://medium . com/@ univprovblog 1/data-format-for-MATLAB-r-and-python-codes-of-data-analysis-and-sample-data-set-9 b0f 845 b 565 a # . 3 ibr PHS 4h](https://medium.com/@univprofblog1/data-format-for-matlab-r-and-python-codes-of-data-analysis-and-sample-data-set-9b0f845b565a#.3ibrphs4h)
## 5.运行代码!
每个样本的聚类数保存在“ClusterNum.csv”中。
# 必需的设置
请看下面的文章。
[https://medium . com/@ uniprofblog1/settings-for-running-my-MATLAB-r-and-python-codes-136 B9 e 5637 a 1 #、paer8scqy](https://medium.com/@univprofblog1/settings-for-running-my-matlab-r-and-python-codes-136b9e5637a1#.paer8scqy)
# 执行结果的示例

# 葡萄酒数据的 k-均值聚类
> 原文:<https://towardsdatascience.com/k-means-clustering-of-wine-data-95bac074baae?source=collection_archive---------8----------------------->
我们在这篇文章中要分析的数据集是对意大利某个特定地区的葡萄酒进行化学分析的结果,这些葡萄酒来自三个不同的品种。这项分析确定了三种葡萄酒中 13 种成分的含量。属性有:*酒精、苹果酸、灰分、灰分的碱度、镁、总酚、类黄酮、非类黄酮酚、原花青素、颜色强度、色调、稀释酒的 OD280/OD315、*和*脯氨酸*。数据集有 178 个观察值,没有缺失值。可以在这里下载[。](https://archive.ics.uci.edu/ml/datasets/wine)
我们的目标是尝试将相似的观察结果分组在一起,并确定可能的聚类数(可能不是 3)。这将有助于我们进行预测并降低维数。第一步是将数据集分成训练集(2/3)和测试集(1/3)。包 *caTools* 中的函数 *sample.split* 做得很好,它在训练集和测试集中处理了 3 个品种大致相同的分布。

下面是数据集的摘要。注意到这些属性不在同一个尺度上是非常重要的;因此,我们稍后将缩放数据。

让我们确定将要使用的集群数量。根据肘方法,我们可以使用 3 个集群,因为从这一点开始,总 WCSS ( *在集群平方和*内)不会显著降低。

# 原始数据和欧几里德距离
首先,我们要处理原始的、未经处理的、未经润色的数据。这不是最好的方法,但我们对结果感兴趣。我们用 100 种不同的种子创建了一个包含 100 种可能的聚类方式的列表(名为 L1)。这考虑到了再现性。在这 100 个结果中,我们选择具有最小总 WCSS 的结果,并且在这些结果中,我们选择 L1[[3]],因为原始类名“1”、“2”、“3”匹配聚类类名“1”、“2”、“3”。这不是必须的,但是解释结果更容易。

我们看到,该算法在训练集上表现不错(准确率为 70.3%),但在测试集上表现更好,准确率为 73.3%(这一点更重要,因为我们更喜欢在之前尚未“看到”的数据上测试该算法)。我们希望将这些结果可视化——“抖动”图可能是个好主意。

我们注意到 SSE 相当高,因为我们处理的是未缩放的数据。这就是为什么我们可能看不到抖动图上的所有数据。
# 原始数据和曼哈顿距离
这次我们用的是 k-means 算法中的曼哈顿距离,在不同维度没有可比性的情况下可能更有用。下面是原始数据的结果—我们选择了具有最小总 WCSS 的聚类。

训练集的准确率为 83/118 = 70.3%,测试集的准确率为 44/60 = 73.3%。下面给出了训练集和测试集的抖动图。

# 缩放数据和欧几里德距离
接下来,让我们看看缩放后的数据会发生什么。请注意,测试集是用用于缩放训练集的相同参数来缩放的。我们得到了以下结果:

显然,与未缩放的数据相比,精确度有所提高。对于训练集,准确率为 110/118 = 93.2%,对于测试集,准确率为 58/60 = 96.7%。但是我们需要小心——太接近 100%并不总是好的,因为我们可能会有过度拟合的问题。
训练集和测试集的抖动图如下所示:

# 缩放数据和曼哈顿距离
对于缩放数据和曼哈顿距离,最佳聚类是:

我们注意到,与使用欧几里德距离对缩放数据进行聚类相比,测试集上的聚类没有改进,但在训练集上有所改进。现在,训练集的准确率为 112/118 = 94.5%,测试集的准确率为 58/60 = 96.7%。抖动曲线如下所示。

# 主成分分析
主成分分析在这一点上可能会有所帮助。我们的目标是提取预测变量的线性组合,解释数据中最大的方差。函数 *prcomp* 用于进行分析,以下是结果汇总。

如果我们观察累积比例,我们会发现前两个主成分解释了数据中 60.9%的方差,而前三个主成分解释了数据中大约 69.6%的方差。下面的 scree 图显示了方差的衰减。

我们决定保留前两个主成分,因为我们将能够看到结果。训练数据包含矩阵 A1$x 的前两个 PC,但是测试数据应该使用相同的变换进行变换。运行 k-means 算法后,我们发现最佳聚类如下:

训练数据的准确率为 112/118 = 94.9%,测试数据的准确率为 57/60 = 95%。测试数据的准确性仅比 PCA 之前的缩放测试数据的准确性差 1.7%,但是我们显著降低了维度(从 13 个变量减少到仅 2 个变量)。下面给出了训练和测试数据的抖动图。

包 *clusterSim* 中的函数 *clusplot* 允许我们显示聚类:

聚类的问题发生在交叉区域——这是我们得到错误分类的数据点的地方。成对图也有助于了解前两台 PC 在群集时的表现。第一台电脑本身做得很好(我们通过观察行/列 PC1 可以看出这一点),第二台电脑稍差一些。其他的很糟糕,因为颜色混在一起了。前两台电脑(位于交叉点)在集群时表现出色。

前三个 PC 甚至更高效,来自包*散点图 3d* 的函数*散点图 3d* 表明这确实是真的:

# 独立成分分析
与 PCA 不同,ICA 的目标是产生 13 个统计上独立的成分,没有特定的顺序,然后使用这些成分对数据进行聚类。我们使用来自包*脱字符*的函数*预处理*来转换训练数据,并且相同的转换已经被应用到测试数据。我们在下面看到,当对数据进行聚类时,组件 ICA6 做得很好,而其他 12 个组件单独地不能很好地对数据进行聚类。

下面是第六个独立成分与自身的对比图——事实上,它可以非常准确地分离数据。

k-means 算法还需要一个组件——如果我们仔细观察获得的成对图,我们可以看到组件 6 和 8 可以保留用于聚类。下面是聚类的结果。

对于训练集,聚类准确率为 91/118 = 77.1%,对于测试集,聚类准确率为 46/60 = 76.7%。精度尚可,但维度从 13 降到只有 2!下面给出了训练集和测试集的抖动图。

# 我们的结果总结
下表提供了关于所获得的聚类结果的结论。

PCA 做的最好!它在测试集上的表现比缩放数据稍差,但维度已经减少。
完整的 R 代码,请访问我的 GitHub 简介[这里](https://github.com/dinajankovic/K-Means-Clustering-Wine-Data)。
# k-均值数据聚类
> 原文:<https://towardsdatascience.com/k-means-data-clustering-bce3335d2203?source=collection_archive---------5----------------------->
在当今世界,随着互联网使用的增加,产生的数据量惊人地庞大。即使单个数据的性质很简单,但要处理的数据量之大,甚至连计算机都难以处理。
我们需要大数据分析工具来处理这样的流程。数据挖掘算法和技术以及机器学习为我们提供了以可理解的方式解释大数据的方法。k-means 是一种数据聚类算法,可用于无监督的机器学习。它能够将相似的未标记数据分组到预定数量的簇(k)中。需要注意的是,我们需要事先知道数据中的自然聚类数,尽管可以对代码进行轻微的修改,以计算为代价找到最优的聚类数。

Source: [https://i.stack.imgur.com/cIDB3.png](https://i.stack.imgur.com/cIDB3.png)
K-means 聚类问题可以正式表述为*“给定一个整数 k 和 R^d 中的一组 n 个数据点,目标是选择 k 个中心,以最小化每个数据点与其最近中心之间的总平方距离”*。精确地解决这个问题是 NP 难的,但是有算法可以局部搜索它的解。标准算法是由 Stuart Lloyd 在 1957 年首先提出的,它依赖于迭代改进。
首先,必须确定聚类中心的初始集合。这可以随机分配。但是这不能保证准确性。这可以在 python 中完成,如下所示:
datapoints is a 2D array initialized with the points to be clustered
centroids = []
for i in range(1,k+1):
uniqueNumber = False
while(uniqueNumber==False):
a = randint(0, len(dataPoints)-1)
if (dataPoints[a] not in centroids):
uniqueNumber = True
centroids.append(dataPoints[a])
那么算法通过在两个步骤之间交替进行。
**步骤 1:** (分配步骤)将每个数据点分配给根据欧几里德距离具有最接近该数据点的中心的聚类。
**步骤 2:** (更新步骤)使用每个聚类的所有成员重新计算每个聚类的质心。
保证每个点与其最近的中心之间的总平方距离单调递减,以便配置不会重复。此外,由于只有 k^n 可能的集群,该过程将总是终止。由于该算法是局部搜索,不能保证全局最优解,初始种子在很大程度上影响结果。取决于初始种子的质量,聚类可能是任意差的。有一些选择初始种子的方法可以增加找到全局最优解的概率。
选择初始中心后,数据点可以聚类为:
closestCluster = [0,euclidean_distance(point,centroids[0])]
for i in range(1,k):
dist = euclidean_distance(point,centroids[i])
if (dist<closestCluster[1]):
closestCluster=[i,dist] clusters[closestCluster[0]].append(point)
在第一次聚类之后,使用如下聚类来找到新的质心:
np is numpy
newCentroids = []
for i in range(k):
newCentroids.append(np.mean(clusters[i],axis=0).tolist())
然后,我们比较以前的聚类中心和新的质心,如果有任何变化,我们回到分配步骤。如果质心没有变化,我们就终止循环。
请务必访问我的回购在[https://github.com/niruhan/k-means-clustering](https://github.com/niruhan/k-means-clustering)的完整代码。标准算法有许多改进,有望提高性能。有些是 k-means++,k-means#。此外,标准算法是一个批处理算法,这意味着我们应该在开始处理之前拥有所有的数据点。但实际上,数据是以流的形式到达处理引擎的,需要进行实时分析。k-means 算法有在线版本,可以对流数据集进行聚类。顺序 k-means 是一种标准算法。还有小批量 k-means,以及使用衰减率处理非平稳数据的方法。
**参考文献:**
1. *“k-means ++小心播种的好处”——大卫·亚瑟和谢尔盖·瓦西里维茨基*
2. *“k 均值聚类”在 https://en.wikipedia.org/wiki/K-means_clustering*
# K-Means++在 Python 和 Spark 中的实现
> 原文:<https://towardsdatascience.com/k-means-implementation-in-python-and-spark-856e7eb5fe9b?source=collection_archive---------4----------------------->

对于本教程,我们将使用 PySpark,Apache Spark 的 Python 包装器。虽然 PySpark 有一个很好的 K-Means++实现,但我们将从头开始编写自己的实现。
# 配置 PySpark 笔记本
如果你在 Jupyter 笔记本上没有 PySpark,我觉得这个教程很有用:
[](https://blog.sicara.com/get-started-pyspark-jupyter-guide-tutorial-ae2fe84f594f) [## 3 分钟内开始使用 PySpark 和 Jupyter 笔记本
### Apache Spark 是大数据爱好者的必备品。简而言之,Spark 是一个快速而强大的框架,它提供了一个…
blog.sicara.com](https://blog.sicara.com/get-started-pyspark-jupyter-guide-tutorial-ae2fe84f594f)
# 将数据集作为 RDD 加载
开始前,请确保您可以访问气象站数据集:
[https://github . com/yoavfreund/UCSD _ BigData _ 2016/tree/master/Data/Weather](https://github.com/yoavfreund/UCSD_BigData_2016/tree/master/Data/Weather)
def parse_data(row):
'''
Parse each pandas row into a tuple of
(station_name, feature_vec),`l
where feature_vec is the concatenation of the projection vectors
of TAVG, TRANGE, and SNWD.
'''
return (row[0],
np.concatenate([row[1], row[2], row[3]]))## Read data
data = pickle.load(open("stations_projections.pickle", "rb"))
rdd = sc.parallelize([parse_data(row[1])
for row in data.iterrows()])
让我们看看第一行:
rdd.take(1)

气象站的名称是 **USC00044534** ,其余的是我们将用于聚类的不同天气信息。
# 导入库
import numpy as np
import pickle
import sys
import time
from numpy.linalg import norm
from matplotlib import pyplot as plt
# 定义全局参数
# Number of centroids K = 5 # Number of K-means runs that are executed in parallel. Equivalently, number of sets of initial points RUNS = 25 # For reproducability of results
RANDOM_SEED = 60295531 *# The K-means algorithm is terminated when the change in the
location of the centroids is smaller than 0.1* converge_dist = 0.1
# 效用函数
随着我们的发展,以下功能将会派上用场:
def print_log(s):
'''
Print progress logs
'''
sys.stdout.write(s + "\n")
sys.stdout.flush() def compute_entropy(d):
'''
Compute the entropy given the frequency vector d
'''
d = np.array(d)
d = 1.0 * d / d.sum()
return -np.sum(d * np.log2(d))
def choice(p):
'''
Generates a random sample from [0, len(p)),
where p[i] is the probability associated with i.
'''
random = np.random.random()
r = 0.0
for idx in range(len(p)):
r = r + p[idx]
if r > random:
return idx
assert(False)
# 质心的初始化
对于 K-Means++来说,我们希望在初始化时质心尽可能的分开。这个想法是让质心在初始化时更接近不同的聚类中心,从而更快地达到收敛。
def kmeans_init(rdd, K, RUNS, seed):
'''
Select RUNS
sets of initial points for K
-means++
'''
# the centers
variable is what we want to return
n_data = rdd.count()
shape = rdd.take(1)[0][1].shape[0]
centers = np.zeros((RUNS, K, shape)) def update_dist(vec, dist, k):
new_dist = norm(vec - centers[:, k], axis=1)2
return np.min([dist, new_dist], axis=0) # The second element dist
in the tuple below is the
# closest distance from each data point to the selected
# points in the initial set, where dist[i]
is the
# closest distance to the points in the i-th initial set
data = (rdd
.map(lambda** p: (p, [np.inf] * RUNS))
.cache()) # Collect the feature vectors of all data points
# beforehand, might be useful in the following
# for-loop
local_data = (rdd
.map(lambda (name, vec): vec)
.collect()) # Randomly select the first point for every run of
# k-means++, i.e. randomly select RUNS
points
# and add it to the centers
variable
sample = [local_data[k] for k in
np.random.randint(0, len(local_data), RUNS)]
centers[:, 0] = sample for idx in range(K - 1):
########################################################
# In each iteration, you need to select one point for
# each set of initial points (so select RUNS
points
# in total). For each data point x, let D_i(x) be the
# distance between x and the nearest center that has
# already been added to the i-th set. Choose a new
# data point for i-th set using a weighted probability
# where point x is chosen with probability proportional
# to D_i(x)^2 . Repeat each data point by 25 times
# (for each RUN) to get 12140x25
######################################################## #Update distance
data = (data
.map(lambda ((name,vec),dist):
((name,vec),update_dist(vec,dist,idx)))
.cache()) #Calculate sum of D_i(x)^2
d1 = data.map(lambda ((name,vec),dist): (1,dist))
d2 = d1.reduceByKey(lambda x,y: np.sum([x,y], axis=0))
total = d2.collect()[0][1] #Normalize each distance to get the probabilities and
#reshapte to 12140x25
prob = (data
.map(lambda ((name,vec),dist):
np.divide(dist,total))
.collect())
prob = np.reshape(prob,(len(local_data), RUNS)) #K'th centroid for each run
data_id = [choice(prob[:,i]) for i in xrange(RUNS)]
sample = [local_data[i] for i in data_id]
centers[:, idx+1] = sample return centers # The second element dist
in the tuple below is the
# closest distance from each data point to the selected
# points in the initial set, where dist[i]
is the
# closest distance to the points in the i-th initial set
data = (rdd
.map(lambda p: (p, [np.inf] * RUNS))
.cache()) # Collect the feature vectors of all data points
# beforehand, might be useful in the following
# for-loop
local_data = (rdd
.map(lambda (name, vec): vec)
.collect()) # Randomly select the first point for every run of
# k-means++, i.e. randomly select RUNS
points
# and add it to the centers
variable
sample = [local_data[k] for k in np.random.randint(0, len(local_data), RUNS)]
centers[:, 0] = sample for idx in range(K - 1):
########################################################
# In each iteration, you need to select one point for
# each set of initial points (so select RUNS
points
# in total). For each data point x, let D_i(x) be the
# distance between x and the nearest center that has
# already been added to the i-th set. Choose a new
# data point for i-th set using a weighted probability
# where point x is chosen with probability proportional
# to D_i(x)^2 . Repeat each data point by 25 times
# (for each RUN) to get 12140x25
######################################################## #Update distance
data = (data
.map(lambda ((name,vec),dist):
((name,vec),update_dist(vec,dist,idx)))
.cache()) #Calculate sum of D_i(x)^2
d1 = data.map(lambda ((name,vec),dist): (1,dist))
d2 = d1.reduceByKey(lambda x,y: np.sum([x,y], axis=0))
total = d2.collect()[0][1] #Normalize each distance to get the probabilities and
# reshape to 12140x25
prob = (data
.map(lambda ((name,vec),dist):
np.divide(dist,total))
.collect())
prob = np.reshape(prob,(len(local_data), RUNS)) #K'th centroid for each run
data_id = [choice(prob[:,i]) for i in xrange(RUNS)]
sample = [local_data[i] for i in data_id]
centers[:, idx+1] = sample return centers
# K-Means++实现
现在我们有了初始化函数,我们可以用它来实现 K-Means++算法。
def get_closest(p, centers):
'''
Return the indices the nearest centroids of p
.
centers
contains sets of centroids, where centers[i]
is
the i-th set of centroids.
'''
best = [0] * len(centers)
closest = [np.inf] * len(centers)
for idx in range(len(centers)):
for j in range(len(centers[0])):
temp_dist = norm(p - centers[idx][j])
if temp_dist < closest[idx]:
closest[idx] = temp_dist
best[idx] = j
return best
def kmeans(rdd, K, RUNS, converge_dist, seed):
'''
Run K-means++ algorithm on rdd
, where RUNS
is the number of
initial sets to use.
'''
k_points = kmeans_init(rdd, K, RUNS, seed)
print_log("Initialized.")
temp_dist = 1.0
iters = 0
st = time.time() **while** temp_dist > converge_dist:
*# Update all `RUNS` sets of centroids using standard k-means
# algorithm*
*# Outline:*
*# - For each point x, select its nearest centroid in i-th
# centroids set*
*# - Average all points that are assigned to the same
# centroid*
*# - Update the centroid with the average of all points
# that are assigned to it*
temp_dist = np.max([
np.sum([norm(k_points[idx][j] - new_points[(idx,
j)]) **for** idx,j **in** new_points.keys()])
])
iters = iters + 1
**if** iters % 5 == 0:
print_log("Iteration **%d** max shift: **%.2f** (time: **%.2f**)" %
(iters, temp_dist, time.time() - st))
st = time.time()
*# update old centroids*
*# You modify this for-loop to meet your need*
**for** ((idx, j), p) **in** new_points.items():
k_points[idx][j] = p
**return** k_points
# 基准测试
K-Means++优于 K-Means 之处在于它的初始化算法带来的收敛速度。此外,Spark 被用来尽可能地并行化这个算法。因此,让我们对这个实现进行基准测试。
st = time.time()
np.random.seed(RANDOM_SEED)
centroids = kmeans(rdd, K, RUNS, converge_dist,
np.random.randint(1000))
group = rdd.mapValues(lambda p: get_closest(p, centroids))
.collect()
print "Time takes to converge:", time.time() - st

根据处理器内核的数量、为每个执行器设置的内核内存以及使用的执行器数量,这个结果会有所不同。
# 价值函数
为了验证模型的准确性,我们需要选择一个成本函数,并尝试使用该模型将其最小化。最终的成本函数会给我们一个准确性的概念。对于 K-Means,我们查看数据点和最近的质心之间的距离。
def get_cost(rdd, centers):
'''
Compute the square of l2 norm from each data point in rdd
to the centroids in centers
'''
def _get_cost(p, centers):
best = [0] * len(centers)
closest = [np.inf] * len(centers)
for idx in range(len(centers)):
for j in range(len(centers[0])):
temp_dist = norm(p - centers[idx][j])
if temp_dist < closest[idx]:
closest[idx] = temp_dist
best[idx] = j
return np.array(closest)**2
cost = rdd.map(**lambda** (name, v): _get_cost(v,
centroids)).collect()
**return** np.array(cost).sum(axis=0)
cost = get_cost(rdd, centroids)
log2 = np.log2print "Min Cost:\t"+str(log2(np.max(cost)))
print "Max Cost:\t"+str(log2(np.min(cost)))
print "Mean Cost:\t"+str(log2(np.mean(cost)))
最小成本:33.7575332525
最大成本:33.8254902123
平均成本:33.2533332335
# 决赛成绩
以下是最终结果:
print 'entropy=',entropybest = np.argmin(cost)
print 'best_centers=',list(centroids[best])

# 现实生活中的 K-Means:聚类锻炼时段
> 原文:<https://towardsdatascience.com/k-means-in-real-life-clustering-workout-sessions-119946f9e8dd?source=collection_archive---------3----------------------->

K -means 聚类是一种非常流行的无监督学习算法。在这篇文章中,我想提供一些关于它的背景知识,并展示我们如何在真实生活中使用它。
[K 均值聚类](https://en.wikipedia.org/wiki/K-means_clustering)是一种算法,给定一个数据集,它将识别哪些数据点属于 *k* 个聚类中的每一个。它获取你的数据,并学习如何对其进行分组。
通过一系列迭代,该算法创建多组数据点(称为聚类),这些数据点具有相似的方差,并最小化特定的成本函数:类内平方和。

***Within-Cluster Sum of Squares*:** where C_i is a cluster and "mu_i" is the mean of the data points in cluster C_i
通过使用组内平方和作为成本函数,相同组中的数据点将*彼此相似*,而不同组中的数据点将具有较低水平的相似性。
K-Means 聚类是一组名为 [*无监督学习*](https://en.wikipedia.org/wiki/Unsupervised_learning) 的学习算法的一部分。在这种类型的学习模型中,没有对每个数据点的标签/类/类别的明确标识。
数据集中的每个数据点都是一个属性向量,也就是说,没有特定标注的要素可以将其分配给特定的聚类或类。然后,该算法将自行学习如何对具有相似特征的数据点进行分组,并*将它们聚集在一起*。
关于 K-Means 聚类的一个重要细节是,即使它确定哪个数据点应该属于哪个聚类,您也必须指定参数 *K,*来表示您想要用来“分布”您的数据的聚类总数。
你最喜欢的锻炼是慢跑,因为你非常喜欢数据,所以你要确保记录你的表现。所以你最终会编译一个类似这样的数据集

它包括您慢跑的日期、总跑步距离(公里)、持续时间(分钟)和自上次锻炼以来的天数。数据集中的每一行都包含每个健身程序的*属性*或*功能*。
## 最终,你想要回答的问题是:“我如何识别相似的锻炼时段?”
通过识别彼此相似的锻炼时段,您可以更好地了解自己的整体表现,并获得如何改进的新想法。
像 **K-Means 聚类**这样的聚类算法可以帮助您将数据分组到不同的组中,保证每个组中的数据点彼此相似。
数据科学和分析的一个良好实践是,在进行任何分析之前,首先要对数据集有很好的理解。
对数据集进行探索性观察,首先绘制一个**对图**,以便更好地了解不同特征之间的相关性。

对角线上的图对应于每个特征的分布,而其他图是每对特征的散点图。
一个有趣的图是距离对持续时间,它显示了线性相关性。

然而,当我们将距离和持续时间与自上次锻炼以来的天数进行比较时,它们之间没有明显的相关性。

现在你已经对*你的数据集如何看起来像*有了一个很好的想法,是时候使用 **K-Means** 并查看单个会话是如何分组的。你可以从把你的数据集分成两个不同的组开始。

在该图中,与 pair 图一样,我们看到了距离和锻炼持续时间之间的关系,但现在每个数据点都有其聚类的颜色。
快速浏览一下这个散点图,我们可以看到,例如,所有 25 分钟以下的锻炼都在一个簇中。
## 我们如何知道使用哪个 K 值?
根据数据集和您正在解决的问题,您可能知道如何对数据进行聚类。也许你想看到数据分成 3 组,5 组,10 组…
如果不是这样,我们如何确定使用哪个 K 值呢?
> 像算法中的任何参数一样,它需要一些实验,即调整。
为了试验不同的 K 值,您还需要一个*决定因素*或度量,您将使用它来决定哪个 K 值提供最佳结果。

上图是对健身数据集运行 K 均值聚类的结果,K 值介于 2 和 43 之间,对应于数据集的大小。K 的每个值与各自的失真值相对应。
y 轴上的失真对应于我们的成本函数:每个数据点和质心(即聚类中心)之间的平方差之和。
随着 K 的增加,相应的失真值将趋于零,因为最终每个聚类只有一个数据点。由于每个聚类中只有一个数据点,质心就是数据点本身,因此失真将等于零。
对于该数据集,曲线的*弯头大约为 K= 5。对于大于 5 的 K 值,失真值开始稳定衰减。*
回到原始数据集,用新找到的 K 重新运行 K-Means,就可以把数据聚类成 5 个不同的组!

至此,K-Means 聚类的工作已经完成,您的数据分析工作开始了😀🤓
下一步需要人工干预,以便解释结果并获得额外的洞察力。
简单回顾一下,这些是**使用 K-Means 的优势:**
* 易于实施
* 相对快速和高效
* 只有一个参数需要调整,您可以很容易地看到调整参数 K 值的直接影响
*感谢阅读!*
# R 中的 k-最近邻算法及实例(简单解释 knn)
> 原文:<https://towardsdatascience.com/k-nearest-neighbors-algorithm-with-examples-in-r-simply-explained-knn-1f2c88da405c?source=collection_archive---------0----------------------->

在这篇文章中,我将举例说明什么是 k-最近邻算法,以及它如何帮助我们。但是在我们继续之前,我们意识到我的目标受众是那些希望对概念有直观理解而不是非常深入理解的人,这就是为什么我避免对这个话题过于迂腐,对理论概念关注较少。让我们开始吧。
假设我们有一定数量的物体,每个物体都有自己独特的属性,例如,你有 5 把椅子,10 张床和 15 张桌子,我们知道每个物体的长度、宽度和高度。现在,如果有人给我们一个具有新属性的新对象,并要求我们预测该新对象属于哪个类别,这意味着我们获得了维度,并要求我们预测它是椅子、床还是桌子,那么我们必须使用 knn 算法来确定这一点。
因此,属性意味着每个对象的属性,每个对象可以被认为是一个类别。我们的工作是检查新对象的属性与任何一个已知类别的关系有多密切。现在,我将向你们展示多种场景,并尽可能简单地解释这些场景。
当我们得到属性时,我们试着把它们画在图上。这些属性的图形表示将帮助我们计算新值和已知值之间的欧几里德距离。通过这样做,我们可以确定新对象最接近哪个类别。
# 欧几里得距离
不要被这个名字吓倒,它只是简单地表示平面上两点之间的距离。通过简单地使用这个公式,你可以计算两点之间的距离,不管你有多少属性,比如高度,宽度,宽度,重量等等,直到 n,其中 n 可以是你拥有的物体的最后一个属性。公式为√( x2 x1)+(y2 y1)+(z2 Z1)……(N2-n1)
# 两类一属性(1D)
我们分为男性和女性两类,下表给出了他们各自的身高。然后,如果出现一名新成员,并要求您在已知他/她的身高的情况下确定他/她的性别,那么您可以在 1D 平面上绘制该身高,并检查该新身高与其他已绘制身高的接近度。理想情况下,我们将计算该图上的欧几里德距离,以确定新成员高度的最近高度。我们看到,如果我们绘制 180 厘米的身高图,它更接近男性身高,而不是女性身高。这就是我们如何确定它是一个男性。(a)显示表格(b)显示图表上的表示(c)显示新成员的引入(d)显示男性的预测值。

# 两类两属性(2D)
假设我们提出一个名为 weight 的新属性,它也可以描述男性和女性的特征,如下表所示。现在我们创建一个 2D 平面,并按照同样的程序计算新物体与旧物体的距离,它越接近其中一个类别,就被认为是它自己的类别。在下面的例子中,我们可以看到身高 169cm、体重 68kg 的新成员与女性的亲密度高于男性。因此,我们预测新成员是女性。

# 两个类别和两个以上属性(> 3D)
大多数情况下,你会有很多与你的分类对象相关的属性,它们不能简单地画在白板上的 2D 或 1D 平面上。然而,只要你理解了它的功能,你就可以开始了。假设你有 5 个属性,即。性别、身高、体重、颜色、头发长度和音调,然后你只需使用上述欧几里德公式来计算新出现的物体与已有物体的距离。取(sex 1-sex 2)+(height 1-height 2)+(weight 1—weight 2)+(color 1—color 2)+(hair _ length 1—hair _ length 2)+(voice _ pitch 1)—(voice _ pitch 2)的平方根,其中 1 表示已经绘制的数据点,2 表示要确定其类别的新数据点。请记住,上面的这个公式将用于每一个可用的数据点,也就是说,只要数据集中有多少行,它就会运行多少次。
# R 中的示例
在我们继续在 R 中实现它们之前,请注意以下几点:
1-您要检查的最近邻将被称为由值“k”定义。如果 k 是 5,那么您将检查 5 个最近的邻居以确定类别。如果大多数邻居属于这五个最近邻居中的某个类别,那么它将被选为即将到来的对象的类别。如下图所示。

2-不同的变量有不同的比例单位,如体重以千克为单位,身高以厘米为单位。那我们如何在欧几里德公式中使用它们呢?我们用公式(x-min(x))/(min(x)-max(x))对每个变量进行归一化,在下面的例子中也会看到。现在,如果你有一个 200 公斤的变量和一个 50 公斤的变量,归一化后,两者都将由 0 和 1 之间的值表示。假设您已经创建了一个只能容纳 0 到 1 范围内的内容的盒子,但是因为您已经使用了规范化公式将所有内容转换为 0 到 1 之间的值,所以您可以很好地使用这个盒子。注意:那个方框是你的图。
knn 算法适用于数值变量,这并不是说它不能适用于分类变量,只是如果你混合了分类变量和数值变量作为预测变量,那么它需要一点点不同的方法。但是如果所有的预测值都是数字,那么 knn 是最好的,因为我们处理的是距离,因此我们需要硬数字。
4-当我们将数据分成训练集和测试集时,数据应该已经被规范化了。这意味着我们首先将数据标准化,然后将其拆分。
knn 算法不适用于 R 中的有序因子,而是适用于因子。我们将在下面的代码中看到这一点。
6-K-均值算法不同于 K-最近邻算法。K-mean 用于聚类,是一种非监督学习算法,而 Knn 是一种监督学习算法,用于处理分类问题。
df <- data(iris) ##load data
head(iris) ## see the studcture## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa##Generate a random number that is 90% of the total number of rows in dataset.
ran <- sample(1:nrow(iris), 0.9 * nrow(iris))
the normalization function is created
nor <-function(x) { (x -min(x))/(max(x)-min(x)) }
Run nomalization on first 4 coulumns of dataset because they are the predictors
iris_norm <- as.data.frame(lapply(iris[,c(1,2,3,4)], nor))
summary(iris_norm)## Sepal.Length Sepal.Width Petal.Length Petal.Width
Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.00
1st Qu.:0.2222 1st Qu.:0.3333 1st Qu.:0.1017 1st Qu.:0.08
Median :0.4167 Median :0.4167 Median :0.5678 Median :0.50
Mean :0.4287 Mean :0.4406 Mean :0.4675 Mean :0.45
3rd Qu.:0.5833 3rd Qu.:0.5417 3rd Qu.:0.6949 3rd Qu.:0.70
Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.00##extract training set
iris_train <- iris_norm[ran,] ##extract testing set
iris_test <- iris_norm[-ran,] ##extract 5th column of train dataset because it will be used as 'cl' argument in knn function.
iris_target_category <- iris[ran,5] ##extract 5th column if test dataset to measure the accuracy
iris_test_category <- iris[-ran,5]##load the package class
library(class) ##run knn function
pr <- knn(iris_train,iris_test,cl=iris_target_category,k=13)
create confusion matrix
tab <- table(pr,iris_test_category)
this function divides the correct predictions by total number of predictions that tell us how accurate teh model is.
accuracy <- function(x){sum(diag(x)/(sum(rowSums(x)))) * 100}
accuracy(tab)## [1] 80
在 R 中已经可用的虹膜数据集中,我运行了 k-最近邻算法,得到了 80%的准确结果。首先,我将数据标准化,将 petal.length、sepal.length、petal.width 和 sepal.length 转换为标准化的 0 到 1 形式,以便我们可以将它们放入一个框(一个图)中,还因为我们的主要目标是预测一朵花是 virginica、Versicolor 还是 setosa,这就是为什么我排除了列 5,并将其存储到另一个名为 iris_target_category 的变量中。然后,我将规范化的值分成训练和测试数据集。想象一下,首先在图上绘制来自训练数据集的值,在我们使用所有必要的参数运行 knn 函数后,我们将测试数据集的值引入图中,并计算图中每个已存储点的欧几里德距离。现在,虽然我们知道它是测试数据集中的哪一朵花,但我们仍然预测这些值,并将它们存储在名为“pr”的变量中,以便我们可以将预测值与原始测试数据集的值进行比较。通过这种方式,我们可以了解我们模型的准确性,如果我们将来要获得新的 50 个值,并且要求我们预测这 50 个值的类别,我们可以使用该模型进行预测。
because diamonds dataset is in ggplot2 package
library(ggplot2)##load data
data(diamonds)
store it as data frame
dia <- data.frame(diamonds)
create a random number equal 90% of total number of rows
ran <- sample(1:nrow(dia),0.9 * nrow(dia))
the normalization function is created
nor <-function(x) { (x -min(x))/(max(x)-min(x)) }
normalization function is created
dia_nor <- as.data.frame(lapply(dia[,c(1,5,6,7,8,9,10)], nor))
training dataset extracted
dia_train <- dia_nor[ran,]
test dataset extracted
dia_test <- dia_nor[-ran,]##the 2nd column of training dataset because that is what we need to predict about testing dataset
also convert ordered factor to normal factor
dia_target <- as.factor(dia[ran,2])
the actual values of 2nd couln of testing dataset to compaire it with values that will be predicted
also convert ordered factor to normal factor
test_target <- as.factor(dia[-ran,2])
run knn function
library(class)
pr <- knn(dia_train,dia_test,cl=dia_target,k=20)
create the confucion matrix
tb <- table(pr,test_target)
check the accuracy
accuracy <- function(x){sum(diag(x)/(sum(rowSums(x)))) * 100}
accuracy(tb)## [1] 71.09752
在这个模型中,我试图预测“切割”变量,因为它是一个分类变量,我们知道 knn 更适合分类问题。我没有考虑第 3 列和第 4 列,因为它们也是绝对的,并且会引起歧义,因为其他预测变量是整数。注意,有一些方法可以对分类变量和整数变量的混合运行 knn,但是我们在这里不讨论它。其余的过程与 iris 数据集相同,最终我们获得了 71%的准确结果。
# 参考
匿名。(2015 年 3 月 9 日)。“R-kNN-k 最近邻(第 1 部分)”。 [*贾莱尔书院*](https://www.youtube.com/channel/UCTprjveyeUA-pn6b7KbGhmQ) *。*[https://www.youtube.com/watch?v=GtgJEVxl7DY](https://www.youtube.com/watch?v=GtgJEVxl7DY)
库马尔,s .(2017 年 10 月 8 日)。" R 中的 kNN(k-最近邻)算法"。RSTUDIO。[https://r studio-pubs-static . S3 . Amazon AWS . com/316172 _ a 857 ca 788d 1441 F8 be 1 BC D1 e 31 f 0 e 875 . html](https://rstudio-pubs-static.s3.amazonaws.com/316172_a857ca788d1441f8be1bcd1e31f0e875.html)
d . bhal la(2017 年 12 月 18 日)。《K 近邻:循序渐进教程》。*红色记录器。*[https://www . r-bloggers . com/k-nearest-neighbor-step-by-step-tutorial/](https://www.r-bloggers.com/k-nearest-neighbor-step-by-step-tutorial/)
[](https://homedecoration.nu/galleries/black-people-christmas-village-clip-art.html) [## 黑人圣诞村剪贴画
### 声明:所有图片均由 BING 使用 BING 图片搜索 API 提供。所有图片仅供个人使用,我们从不…
homedecoration.nu](https://homedecoration.nu/galleries/black-people-christmas-village-clip-art.html)
# k 最近邻,它的用途和如何使用它
> 原文:<https://towardsdatascience.com/k-nearest-neighbors-its-purpose-and-how-to-use-it-36fa927acc64?source=collection_archive---------3----------------------->
对于那些不知道 k 最近邻是什么的人来说,这是一个预测模型。它的目的是什么,为什么使用它?这些是我们将在这篇文章中深入探讨的问题。
为了让这个模型工作,数据必须有一个距离的概念。用外行人的话来说,我们需要能够用图表表示我们的数据。
这个模型将是非线性的,可以用在课堂上。我所说的类是指它可以帮助确定一个数据点是属于一个类还是另一个类。一个很好的例子是根据收入和年龄来决定某人是共和党人还是民主党人。该模型将被证明是有用的,因为本质上它查看邻近的数据点来确定这个新数据点将落入什么样的位置。
现在我们知道了为什么这是有用的,让我们给出一个用 python 来做这件事的例子。
这个例子将使用花瓣宽度、花瓣长度、萼片长度和萼片宽度来尝试确定花的分类
import pandas as pd
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
col_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']
iris = pd.read_csv(url, header=None, names=col_names)
首先,我导入 pandas(一个 python 库),然后读入我的数据集并设置列名。这将我的数据放入一个很好的数据框架中,可以很容易地进行分析。
from matplotlib.colors import ListedColormap
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF']
上面的代码块引入了颜色绘图能力。
iris["Species_number"] = iris.species.map({'Iris-setosa':0,'Iris-versicolor':1,'Iris-virginica':2 })
然后,我制作了一个新的列,将每个物种映射到不同的 bin,bin 为 0、1 或 2。
iris.plot(kind = 'scatter', x = "petal_length", y = "petal_width", c ="Species_number" ,colormap= cmap_bold )

这显示踏板宽度和花瓣长度,以确定物种。每个物种都有不同的颜色。
feature_cols = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
X = iris[feature_cols]
y = iris.Species_number
这使得我们的 X 是萼片长度,萼片宽度,花瓣长度,花瓣宽度。我们的 Y 是有三个箱的物种栏。我们试图使用 X 特征来确定 Y
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)
对于任何一个好的模型,你都需要做一个训练测试来避免过度拟合你的模型。这是把你的数据分成一个训练集,然后是一个测试集来测试你的模型有多好。k 最近邻(也称为 KNN)是一个懒惰模型,这意味着它不使用训练数据点来做任何*泛化。所以*我们不打算训练一个模特。你可能会问,为什么要进行列车试运行?因为我们仍然需要那个测试集来测试这 70%,看看我们的 X 变量是否是好的预测器。
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics
# make an instance of a KNeighborsClassifier object
knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X_train, y_train)
然后我们从 sklearn.neighbors 导入,以便能够使用我们的 KNN 模型。使用 KNeighborsClassifier,然后使用里面的参数确定您希望您的数据点查看多少个最近邻。没有经验法则告诉你应该看多少个邻居。确定要查看多少个相邻要素的最佳方法是测试一系列相邻要素,并确定哪一个具有最佳精度。
y_pred_class = knn.predict(X_test) print metrics.accuracy_score(y_test, y_pred_class)
这将让您看到准确性分数,因为我们只有 1 个最近邻要检查,所以我们的分数最终是 1(也称为 100%),这有可能被过度拟合。
def length(X, y):
empty_list = []
for n in range(1,100):
X_train, X_test, y_train, y_test = train_test_split(X, y)
knn = KNeighborsClassifier(n_neighbors=(n))
knn.fit(X_train, y_train)
y_pred_class = knn.predict(X_test)
empty_list.append(metrics.accuracy_score(y_test, y_pred_class))
return empty_list
该函数将测试 1-100 个最近邻,并返回每个最近邻的精度。这将有助于您为您的模型寻找最佳数量的邻居
一旦您确定了最佳邻居,您就可以在其他数据点上使用您的模型,将它们放入一个类中。
这就是你使用 KNN 的方式,我希望这能帮助那些对预测数据点将属于哪一类感兴趣的人
# k 近邻—机器学习算法简介
> 原文:<https://towardsdatascience.com/k-nearest-neighbours-introduction-to-machine-learning-algorithms-18e7ce3d802a?source=collection_archive---------4----------------------->
## 另一种分类算法

## 介绍
我们发现分类算法非常重要而回归算法不太重要的原因是因为我们日常工作中面临的许多问题都属于分类任务。例如,我们想知道肿瘤是恶性的还是良性的,我们想知道消费者对我们出售的产品的反应是积极的还是消极的,等等。k 近邻是另一种分类算法,也是非常简单的一种。如果你在 K 意味着算法之后阅读这篇文章,不要混淆,因为它们属于不同的学习领域。K 均值是一种聚类/无监督算法,而 K 最近邻是一种分类/监督学习算法。
## K 是什么??
在 K 均值算法中,对于每个测试数据点,我们将查看 K 个最近的训练数据点,并选取最频繁出现的类,并将该类分配给测试数据。因此,K 表示位于测试数据点附近的训练数据点的数量,我们将使用该测试数据点来找到类。
## k 最近邻—伪代码
1. Load the training and test data
2. Choose the value of K
3. For each point in test data:
- find the Euclidean distance to all training data points
- store the Euclidean distances in a list and sort it
- choose the first k points
- assign a class to the test point based on the majority of classes present in the chosen points
4. End

K Nearest Neighbours
## KNN 电码
我们将使用[虹膜数据集](https://www.kaggle.com/jchen2186/machine-learning-with-iris-dataset/data)来说明 KNN 算法。虹膜数据集有四个特征,我们将只使用其中的两个(萼片长度,花瓣长度)。这有助于我们更好地可视化数据点。
我们加载 Iris 数据集,获取目标值并将其存储在一个数组中。我们从数据框中删除目标值和两个不需要的要素。
通过绘制基于这两个特征的数据点,我们获得了如下所示的散点图。

Iris data — Scatter plot
我们将字符串类型中的类转换成整数类型。我们将数据混洗并分成训练和测试数据,90%的数据用于训练,而剩余的 10%用于测试。
我们使用 Scikit-learn 库来实现我们的 KNN 算法。我们取 K 值的范围,从 1 到 20,并根据不同的 K 值绘制我们的 KNN 模型的精确度

K vs accuracy plot
您可以看到,在 K = 3 时,我们能够实现 100%的精度,并且对于更大的 K 值,精度保持不变。现在,我们已经使用 Scikit-learn 库实现了该算法,让我们尝试在不使用 Scikit-learn 的情况下实现 KNN 算法。这将为我们提供对算法如何工作的更好的直观理解。
我们基于上述伪代码实现了该算法。我们使用 K = 3 的值。该模型的准确度也是 100%。
## 结论
k 近邻算法是一种简单的分类算法,具有广泛的应用。了解它的工作原理肯定会有帮助:)
# k-NN —了解你最近的邻居
> 原文:<https://towardsdatascience.com/k-nn-getting-to-know-your-nearest-neighbors-b60399dc0f32?source=collection_archive---------6----------------------->

Evolving Science
*本文是探索 10 种基本机器学习算法的 BAI 系列文章的一部分**
在一系列客户会议之后,这是明年某个时候的傍晚,在纽约市的高架线上。你在一个户外酒吧停下来,喝了第一杯酒,吃了点东西。坐在你的饮料旁边,你开始想你最近的邻居。你忍不住掏出手机来试试它新的面部识别技术。这款应用近乎实时地识别出你周围的人、他们的工作经历、他们的朋友和共同兴趣。除了隐私问题,k-NN 是什么,它是如何工作的,它在数据科学中的使用场景是什么,以及它如何促进面部识别技术的创新?
k-NN 是一种机器学习算法,自 20 世纪 70 年代以来被广泛用于在监督学习环境中分析数据。它的流行源于它的易用性和清晰易懂的结果。k-NN 中的“k”是指用于分类或预测数据集中结果的最近邻的数量。每个新观察值的分类或预测是基于加权平均值关于指定的距离(即最近邻)计算的。k-NN 分析是一个合理的选择,当很少有先验知识的观察分布的数据。

An example of k-NN classification — Adi Bronshtein
当我们被给定一个训练观察的标记数据集,并且目标是捕获每个观察之间的关系时,我们使用 k-NN。这种相似性关系被表示为数据点之间的距离度量。观察值之间的间隔被测量为欧几里德、曼哈顿、切比雪夫、汉明距离或甚至余弦相似性。k-NN 是一种非参数算法,因为它对关系的函数形式没有明确的假设。它也是基于实例学习的一个例子,因为它直接关注训练实例,而不是应用特定的数据模型。
k-NN 算法处理整个数据集,而不是训练数据的子集。最近邻的数量(k)是一个超参数,超过了数据科学家为了获得数据集的最佳拟合而选择的参数。当数量 k 较小时,我们限制了预测的区域,并使分类器对整体分布不太敏感。对于分类问题,这可能是最常见的类值。对于回归问题,这可能是平均输出变量。
你什么时候会用 k-NN?该算法被部署在概念搜索中,在概念搜索中,数据科学家在语义上搜索相似的文档。Discovery 是另一个使用场景,其中该算法可用于查找所有电子邮件、简报、合同等。与给定问题相关。推荐系统通常集成了 k-NN,因为如果你知道一个顾客喜欢某个特定的商品,你就可以向他们推荐类似的商品。最后,k-NN 通常用作更复杂分类器的基准,如人工神经网络(ANN)和支持向量机(SVM)。[【1】](#_ftn1)

A k-NN classifier example using the CIIFAR 10 dataset — — Andrej Karpathy
他的算法有什么局限?当超参数 k 较高时,预测对异常值更有弹性。如果一类观察值在数据中非常频繁,K-NN 也会受到偏斜类分布的影响。k-NN 的易用性是以内存和计算为代价的,因为使用 k-NN 需要处理整个数据集而不是一个样本。由于所有这些原因,k-NN 算法在工业环境中可能不实用。
有几种技术可以提高算法的针对性。重新调整数据可以使距离度量更有意义。改变距离度量的性质可以帮助提高分类/预测的准确性(例如用汉明或曼哈顿代替欧几里德距离)。像 PCA 这样的降维技术可以在应用 k-NN 之前执行,以提供更易管理的结果。最后,使用类似 k-d 树的近似最近邻技术来存储训练观察值可以用来减少测试时间。
回到面部识别和高线上的酒吧,k-NN 在像 Herta Security 这样的应用程序中起着重要作用。[【2】](#_ftn2)考虑到应用程序的性质,为城市中的每个人训练一个单独的分类器既具有挑战性又成本高昂。Herta 的数据科学家开发了深度学习算法,来生成代表人脸的特征向量。该应用程序然后使用 k-NN 来识别个人,将他们的脸与观察列表进行比较。一旦确定了一个引用,就可以将它链接到任何可用的数据库。当你啜饮第二杯葡萄酒时,你可能会思考面部识别的道德问题,因为知道你最近的邻居就在你的手边。[【3】](#_ftn3)
李施伦克博士,[商业分析研究所](http://baieurope.com./),2018 年 9 月 20 日
* *之前在白系列中发表的关于基本机器学习算法的文章包括* [*贝叶斯定理——熟能生巧*](https://medium.com/p/1ec7d4bcdb1d?source=your_stories_page---------------------------) *和* [*鲨鱼攻击——解释泊松回归的用法*](https://medium.com/p/449739bf96da?source=your_stories_page---------------------------)
Lee Schlenker 是商业分析和社区管理教授,也是 http://baieurope.com 商业分析研究所的负责人。可以在[查看他的 LinkedIn 个人资料](http://www.linkedin.com/in/leeschlenker.)可以在[的 Twitter 上关注白](https://twitter.com/DSign4Analytics)
*****
[【1】](http://file///C:/Users/Lee/Dropbox/Business%20Analytics%20Insitute/Nearest%20Neighbors.docx#_ftnref1)凯文·扎克卡,(2016),[K 近邻完全指南](https://kevinzakka.github.io/2016/07/13/k-nearest-neighbor/)
[【2】](http://file///C:/Users/Lee/Dropbox/Business%20Analytics%20Insitute/Nearest%20Neighbors.docx#_ftnref2)赫塔安全,[技术](http://www.hertasecurity.com/en/technology)
[【3】](http://file///C:/Users/Lee/Dropbox/Business%20Analytics%20Insitute/Nearest%20Neighbors.docx#_ftnref3)Jon Christian,(2018),[面部识别如何将我们撕裂](https://medium.com/s/futurehuman/how-facial-recognition-tech-could-tear-us-apart-c4486c1ee9c4),
# 卡夫卡-Python 用 10 行代码解释
> 原文:<https://towardsdatascience.com/kafka-python-explained-in-10-lines-of-code-800e3e07dad1?source=collection_archive---------0----------------------->
虽然它不是 Python 提供的最新库,但很难找到关于如何将 Apache Kafka 与 Python 结合使用的全面教程。通过大约十行代码,我将解释**Kafka 的基础以及它与 Kafka-Python** 的交互。

# 设置环境
首先你要在你的机器上安装**卡夫卡和动物园管理员**。对于 Windows 来说,有一个由 Shahrukh Aslam 编写的优秀指南,它们肯定也适用于其他操作系统。
接下来**安装 Kafka-Python** 。如果您使用的是 Anaconda 发行版,那么您可以使用 pip 或 conda 来实现这一点。
pip install kafka-pythonconda install -c conda-forge kafka-python
在执行下面的示例代码之前,不要忘记启动 Zookeeper 服务器和 Kafka broker 。在这个例子中,我们假设 Zookeeper 在 *localhost:2181* 上运行 default,在 *localhost:9092* 上运行 Kafka。
我们还使用了一个名为 *numtest* 的主题。在本例中,您可以**创建一个新主题**,方法是打开一个新的命令提示符,导航到 *…/kafka/bin/windows* 并执行:
kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic numtest
# 卡夫卡是什么?
简而言之,Kafka 是一个分布式发布-订阅消息系统,它以分区和复制的主题维护消息提要。最简单的说,Kafka 生态系统中有三个参与者:生产者、主题(由经纪人管理)和消费者。
制作人根据他们选择的主题制作信息。可以给每个消息附加一个密钥,在这种情况下,生产者保证所有具有相同密钥的消息将到达相同的分区。
主题是日志,它从生产者那里接收数据,并将它们存储在它们的分区中。生产者总是在日志的末尾写新的消息。在我们的例子中,我们可以对分区进行抽象,因为我们在本地工作。
消费者按照自己的节奏阅读他们选择的主题的一组分区的信息。如果消费者是消费者组的一部分,即订阅相同主题的一组消费者,他们可以提交他们的补偿。如果您希望与不同的使用者并行使用一个主题,这可能很重要。

source: [https://www.cloudera.com/documentation/kafka/1-2-x/topics/kafka.html](https://www.cloudera.com/documentation/kafka/1-2-x/topics/kafka.html)
**偏移量是日志中消费者最后消费或读取消息的位置**。然后,用户可以提交该偏移量,使读数成为“官方”读数。偏移量提交可以在后台自动完成,也可以显式完成。在我们的示例中,我们将在后台自动提交。

source: [https://www.confluent.io/blog/tutorial-getting-started-with-the-new-apache-kafka-0-9-consumer-client/](https://www.confluent.io/blog/tutorial-getting-started-with-the-new-apache-kafka-0-9-consumer-client/)
# 让我们编码
在我们的例子中,我们将创建一个**生产者**,它发出从 1 到 1000 的数字,并将它们发送给我们的 Kafka **经纪人**。然后**消费者**将从**代理**读取数据,并将它们存储在 MongoDb 集合中。
使用卡夫卡的好处在于,如果我们的消费者崩溃了,新的或固定的消费者会从上一个消费者停止阅读的地方继续阅读。这是一个很好的方法来确保所有的数据都输入到数据库中,没有重复或丢失的数据。
创建一个名为 *producer.py* 的新 Python 脚本,从我们全新的 Kafka-Python 库中导入 *json* 、 *time.sleep* 和 *KafkaProducer* 开始。
from time import sleep
from json import dumps
from kafka import KafkaProducer
然后**初始化一个新的卡夫卡制作人**。请注意以下参数:
* *bootstrap _ servers =[' localhost:9092 ']*:设置生产者应该联系的主机和端口,以引导初始集群元数据。没有必要在这里设置,因为默认设置是 *localhost:9092* 。
* *value _ serializer = lambda x:dumps(x)。encode('utf-8')* :数据在发送到代理之前应该如何序列化的函数。这里,我们将数据转换为 json 文件,并将其编码为 utf-8。
producer = KafkaProducer(bootstrap_servers=['localhost:9092'],
value_serializer=lambda x:
dumps(x).encode('utf-8'))
现在,我们想生成从 1 到 1000 的数字。这可以通过一个 for 循环来实现,我们将每个数字作为值输入到一个只有一个键的字典中: *number* 。这不是话题键,只是我们数据的一个键。在同一个循环中,我们还将把数据发送给一个代理。
这可以通过**调用生成器**上的 send 方法并指定主题和数据来完成。请注意,我们的值序列化程序将自动转换和编码数据。为了结束我们的迭代,我们休息 5 秒钟。如果您想确保消息被代理收到,建议包含一个回调。
for e in range(1000):
data = {'number' : e}
producer.send('numtest', value=data)
sleep(5)
如果您想测试代码,建议创建一个新主题并将数据发送到这个新主题。这样,当我们稍后一起测试生产者和消费者时,您将避免在 *numtest* 主题中的重复和可能的混淆。
# 消费数据
在我们开始编码我们的消费者之前,创建一个新文件 *consumer.py* 并从 *pymongo* 导入 *json.loads* 、 *KafkaConsumer* 类和 *MongoClient* 。我不会深入研究 PyMongo 代码,因为这超出了本文的范围。
此外,您可以用任何其他代码替换 mongo 代码。这可以是将数据输入到另一个数据库的代码,处理数据的代码或者任何你能想到的代码。关于 *PyMongo* 和 MongoDb 的更多信息,请查阅[文档](https://api.mongodb.com/python/current/)。
from kafka import KafkaConsumer
from pymongo import MongoClient
from json import loads
让我们**创造我们的 KafkaConsumer** 并仔细看看这些论点。
* 第一个参数是主题,在我们的例子中是 *numtest* 。
* *bootstrap _ servers =[' localhost:9092 ']*:与我们的生产者相同
* *auto _ offset _ reset = ' earliest '*:最重要的参数之一。它处理消费者在故障或关闭后重新开始阅读的位置,并且可以设置为最早*最早*或最晚*最晚*。当设置为*最新*时,用户从日志末尾开始读取。当设置为*最早*时,消费者从最新提交的偏移开始读取。这正是我们想要的。
* *enable _ auto _ commit = True*:确保消费者每隔一段时间提交一次读取偏移量。
* *auto _ commit _ interval _ ms = 1000 ms*:设置两次提交的时间间隔。因为每五秒钟就有一条消息进来,所以每秒钟提交一次似乎是公平的。
* *group_id='counters'* :消费者所属的消费群。请记住,在介绍中,消费者需要成为消费者组的一部分,以使自动提交工作。
* 值反序列化器将数据反序列化为一种通用的 json 格式,与我们的值序列化器所做的相反。
consumer = KafkaConsumer(
'numtest',
bootstrap_servers=['localhost:9092'],
auto_offset_reset='earliest',
enable_auto_commit=True,
group_id='my-group',
value_deserializer=lambda x: loads(x.decode('utf-8')))
下面的代码连接到我们的 MongoDb 数据库的 *numtest* 集合(集合类似于关系数据库中的表)。
client = MongoClient('localhost:27017')
collection = client.numtest.numtest
我们可以通过循环从消费者那里提取数据(消费者是可迭代的)。消费者会一直听下去,直到代理不再响应。可以使用 value 属性访问消息的值。这里,我们用消息值覆盖消息。
下一行将数据插入我们的数据库集合。最后一行打印了一条确认消息,表明该消息已被添加到我们的集合中。注意,可以在这个循环中为所有动作添加回调。
for message in consumer:
message = message.value
collection.insert_one(message)
print('{} added to {}'.format(message, collection))
# 测试
让我们测试我们的两个脚本。打开命令提示符,转到保存 *producer.py* 和 *consumer.py* 的目录。执行 *producer.py* ,打开一个新的命令提示符。启动 *consumer.py* ,看看它如何读取所有消息,包括新消息。
现在中断消费者,记住它是哪个号码(或者在数据库中检查它)并重新启动消费者。请注意,消费者会拾取所有错过的消息,然后继续收听新消息。
请注意,如果您在阅读消息后 1 秒钟内关闭消费者,消息将在重新启动时再次被检索。为什么?因为我们的 *auto_commit_interval* 被设置为 1 秒,记住如果偏移量没有被提交,消费者将再次读取消息(如果 *auto_offset_reset* 被设置为最早)。
—请随时在评论中或私信中向我指出任何不一致或错误。—
# 承认
本文绝不是 Kafka 或 Kafka-Python 的完整指南,而是一个全面的介绍,它将使您熟悉 Kafka 的基本概念以及如何用有用的 Python 代码来转换这些概念。
对于更高级的主题,建议阅读文档。如果你想部署代码,看看 Russell Jurney 的 *Confluent-Kafka* 和[这篇文章](https://blog.datasyndrome.com/a-tale-of-two-kafka-clients-c613efab49df)可能是个好主意。
# 来源
[Kafka-Python 文档](https://kafka-python.readthedocs.io/en/master/index.html)
[使用 Kafka-Python 的反序列化器消费来自 Kafka 的 JSON 消息](https://medium.com/@mukeshkumar_46704/consume-json-messages-from-kafka-using-kafka-pythons-deserializer-859f5d39e02c)
[阿帕奇卡夫卡文档](https://kafka.apache.org/documentation/)
[Cloudera Kafka 文档](https://www.cloudera.com/documentation/kafka/1-2-x/topics/kafka.html)
[使用 Apache Kafka:构建流媒体平台实用指南](https://www.confluent.io/blog/stream-data-platform-1/)
[介绍 Kafka 消费者:开始使用新的 Apache Kafka 0.9 消费者客户端](https://www.confluent.io/blog/tutorial-getting-started-with-the-new-apache-kafka-0-9-consumer-client/)
# 环游世界
> 原文:<https://towardsdatascience.com/kaggle-around-the-world-ccea741b2de2?source=collection_archive---------10----------------------->

The World Clock at Alexanderplatz, Berlin
不言而喻,数据科学家、机器学习工程师和 AI 研究人员的数量在全球并不是平均分布的。有各种各样的指标可以用来了解国家和大陆之间的机器学习差距有多大。例如,来自深度学习 Indaba 的人们使用神经信息处理系统年度会议(NeurIPS 以前的 NIPS)上被接受的论文数量来观察[当代机器学习景观中缺失了两个完整的大陆:南美和非洲](https://goo.gl/yec14p)。
我们可以通过查看关于 [**Kaggle**](https://www.kaggle.com) 的现有数据来做类似的工作。如果你不知道,Kaggle 是一个在线平台,用户可以在那里找到并发布数据集。它还举办不同的机器学习比赛,吸引了一千多个团队和个人。由于 Kaggle 在数据科学人士中非常受欢迎,因此将其作为每个国家的数据科学社区的代理并不为过。我们想在这里解决的主要问题如下:*我们能看到来自不同大陆的机器学习/数据科学社区之间的明显差异吗?这些差异仅与绩效相关吗?还是仅仅是社会经济差异,反映了国家和大陆之间现存的不平等?*
为了回答这些问题,我们将使用两个来源:
* **排名用户数据集**:由爬虫获取并由 [Norconsult](http://kagglerank.azurewebsites.net/) 智能显示的 Kaggle 用户数据。
* **Kaggle 第二次年度机器学习和数据科学调查** [**(ML & DS 调查)**](https://www.kaggle.com/kaggle/kaggle-survey-2018):ka ggle 进行的一项调查,共有来自不同国家的 23859 人参与。
第一个数据集将帮助我们了解每个大陆*在 Kaggle 中的表现*;第二个将引导我们看到不同 ML/DS 社区的*相关特征*。本分析中使用的所有代码和数据均可在[这里](https://www.kaggle.com/felsal/kaggle-around-the-world)找到。
# 衡量绩效
排名用户数据集是通过从 Kaggle 的网站上抓取位置数据获得的。Kaggle 有不同类别的专业知识。我们将只与其中一个合作:*竞争。*在这个类别中有五个表现等级:新手、贡献者、专家、大师和特级大师。*分级用户是专家级或更高级别的用户*。
查看数据,我们可以看到每一行代表一个排名用户。栏目有:*报名日期*、*当前积分*、*当前排名*、*最高排名*、*国家*和*洲。*在 Kaggle 中,积分和排名会随着时间而变化。所以,这里代表的所有位置只对应一个特定的时间点(2018 年 8 月左右)。
## 全球排名用户

需要注意的是,这些地块并不完整,总排名用户(1267 个用户)中有 **26.6%** 没有公开他们的位置。
看着**情节 1** 很明显,美国是排名用户最多的国家,遥遥领先。如果你把美国从这里列出的国家名单中去掉,差距就没那么大了。
**剧情二**显示有两组截然不同的大陆:一边是北美、亚洲和欧洲(**第一组**);另一边,大洋洲,南美,非洲,中美洲(**第二组**)。第一组负责 Kaggle 所有排名用户的 **69.1%** ,因此第二组仅保留排名用户的 **4.3%** 。
使用每个用户的注册日期,我们可以看到世界上不同地区在 Kaggle 内部是如何发展的:

我们也可以看到每个国家的演变:

**剧情 3** 清晰地展现了两组大陆的差异。这里需要注意的一点是,尽管欧洲一直主导着亚洲,但在 2016 年,后者开始缩小它们之间的差距,从 2017 年开始,亚洲的排名用户开始超过欧洲。
**图 4–10**显示了每个区域的动态。在北美、亚洲、大洋洲、南美和非洲,我们可以清楚地看到一个国家统治着其他国家:分别是美国、俄罗斯、澳大利亚、巴西和南非。中美洲国家拥有相同数量的用户(每个国家只有一个)。在欧洲,我们可以看到法国、英国和德国争夺第一的位置。
## 点数和等级
Kaggle 有一个积分系统。它们被设计成随着时间的推移而衰减。所以它们只反映了收集数据时的卡格尔地貌。将特定国家的每个用户的积分相加,我们得到了以下图表:

**剧情 11** 展示了一个与**剧情 1** 相似的场景,这里唯一大的不同是巴西的出现(把澳洲排除在名单之外)。这是来自这个国家的一些高排名用户的影响(在收集数据时,第一名属于一个巴西用户)。
在**第 12 集**中可以看出的一点是,亚洲和欧洲的分数都比北美高。记住我们在**剧情 2** 中看到的,北美是排名用户最多的大陆。点衰减解释了**图 2** 和**图 12** 之间的差异。当我们分析排名信息时,这一点就会变得清楚。
在该数据中,我们有每个排名用户的*当前排名*以及他/她曾经达到的*最高排名*。为了比较国家和大洲,我们可以使用以下得分函数:

Figure 1: score function
该函数返回一个分数,最高等级的用户得到 1 分,最低等级的用户得到 0 分,对于两者之间的任何人,它返回一个区间(0,1)内的实数。
将各大洲的得分相加,我们得到:

如果我们比较**图 13** 和**图 14** 的差异,我们会看到以下情况:北美呈现最高的*最高排名分数*,因为来自该大陆的许多排名用户在过去的*中取得了不错的排名,但是当我们查看*当前排名分数*时,亚洲和欧洲的表现更好。同样,当我们查看第 2 组时,我们可以看到南美洲拥有*目前*该组大陆中的最佳成绩,大洋洲位居第二。*
*这里的关键事实是,在某个时间点,来自亚洲和欧洲的用户在机器学习竞赛中变得更好,并取代了北美的位置。根据这些数据,我们不能说确切的时间。但是转变是明显的。*
# 仔细观察每个社区
通过提出各种有趣的问题,ML & DS 调查对每个国家的机器学习社区进行了丰富的描述。为了简洁起见,我们只把重点放在一些具体问题上。所选问题反映的被试者的地域差异通常更为突出:*年龄*,*正规教育*,*年使用机器学习*,*年报酬*和*使用技术*。
## ML & DS 调查的地理分布

与**图 1** 和**图 2** 相比,**图 15** 和**图 16** 显示了不同的分布。我们可以看到,有大量来自印度的参与者,使亚洲成为调查中最具代表性的大陆。请注意*这里没有中美洲国家的代表*。与已排名的用户数据相比,我们没有公开其位置的用户百分比更低:参与者的 6%**(1430)。**
## 将响应作为分布进行分析
参与者被问及一系列选择题(我们没有分析调查中的开放式问题)。在这里,我们将按大洲显示一些答案,为了有助于形象化,我们将打破显示第**组 1** (亚洲、北美和欧洲)和第**组 2** (南美、非洲和大洋洲)的大洲的图表。
当我们按洲汇总多个答案时,我们在这些答案上构建了一个*分布*。比较大陆之间差异的一种方法是比较它们各自分布之间的差异。为此,我们将利用[库尔贝克-莱布勒散度](https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence):

当 p 与 q 同分布时,DKL(p || q)的值为 0,当它们不同时,DKL(p || q) > 0。DKL(p || q)的值随着 p 和 q 之间的散度的增加而增加。我们可以在 DKL(p || q)之上定义一个距离度量*如下:*
distance k1(p,q) = DKL(p || q) + DKL(q || p)
因此,对于每个问题,我们可以构建一个距离矩阵来观察每个大陆之间的差异。
问:“你的年龄是多少岁?”

从图 17–19 中可以看出,本次调查中的绝大多数年轻人来自亚洲(大部分来自印度)。客观地看,来自印度的自称 18 到 21 岁的人数(1225)比来自南美的所有参与者的人数(1140)都多。
另一个值得注意的事实是,据报道 40 岁或以上的人很少来自非洲(在 40 岁以上的人群中,只有 1.8%来自非洲)。当我们观察第 20 幅图时,我们可以看到大洋洲和亚洲在年龄上的巨大差异。前者比后者拥有更多的老年 Kaggle 用户。
**问:“你已经达到或计划在未来两年内达到的最高正规教育水平是什么?”**

在**图 21–23**中,最引人注目的事实是来自欧洲的 Kaggle 用户中拥有或计划拥有研究生学位的人数。欧洲集中了大部分拥有博士学位的用户(1083),而 **77.5%** 的欧洲用户已经或计划拥有硕士或博士学位。正如**图 24** 所示,欧洲与几乎所有大陆都有很大差异(北美是唯一的例外)。
问:“你使用机器学习方法(在工作中或在学校)有多少年了?”

**图 25–27**显示了与图 17–19 中呈现的场景相似的场景:亚洲集中了大量的 ML 新手用户,主要是由于印度;北美和欧洲拥有最多的经验用户(在所有拥有 5 年以上 ML 经验的人中,**39.7%**在北美, **36.6%** 在欧洲);而非洲只有 1.2%的 ML 老兵。我们在**剧情 24** 中首次发现的欧洲和非洲之间的差异再次出现在**剧情 28** 中。这可以用正规教育和使用机器学习的年数之间的正相关来解释。
问:“你目前的年薪是多少(大约美元)?”

当我们看到薪酬的差异时,各大洲之间的差距就非常明显了。**图 33** 显示了整个内核中 KL 距离的最高值!北美明显不同于世界其他地区。从这个具体答案的 KL 距离上,我们也可以看到两个遥远的群体:一边是北美、欧洲、大洋洲;另一边是南美、亚洲和非洲。另一种方法是看数字。一个极端是,高薪工作集中在北美,收入超过 125,000 英镑的人中有 68.8%来自美国。另一方面,南美洲、亚洲和非洲总共集中了 **75.9%** 报告年度薪酬最低的所有用户。
## 问:在过去 5 年中,您在工作或学校中使用过以下哪些云计算服务?

对技术的获取塑造了每个 ML/DS 社区的潜力。幸运的是,关于云计算服务的数量,我们在世界各地看到了相同的模式( **Plots 34** 和 **35** )。我们可以观察到的唯一显著差异是,亚洲使用的服务类型有很小的差异,报告使用阿里云服务的绝大多数用户来自亚洲( **Plots 36** 和 **37** )。
## 问:在过去的 5 年里,你使用过哪些机器学习框架?

与**图 34–37**中呈现的结果类似,**图 38–41**中传达的信息是,就机器学习框架的使用而言,各大洲之间存在微小差异。
# 最后的想法
根据我们的分析,出现了两个不同的大陆群:**第 1 群**(亚洲、北美和欧洲)和**第 2 群**(南美、非洲、大洋洲和中美洲)。这种区分是基于*用户数量*、*点数*和*排名位置*(一种*基于业绩的*区分)。但是,正如 ML & DS 调查所显示的,这些群体的大陆之间没有社会经济的统一。如果我们采用 KL 距离度量,我们可以定义另外两个更一致的组:**组 3** (北美、欧洲和大洋洲)和**组 4** (非洲、亚洲、南美洲和中美洲)。

KL distance table by continent groups
这不应该被视为意外,当我们按人均国内生产总值对各大洲进行排名时,第 3 组和第 4 组也出现了。看起来 ML & DS 调查是世界现实的反映,就像它应该的那样。
幸运的是,我们还可以推导出一些*非平凡的结论*。
第一个是,亚洲目前在 Kaggle ( **Plots 12** 和 **14** )中扮演着核心角色,正如 ML & DS 调查显示的那样,*它在未来将继续扮演重要角色。一大群年轻数据科学家属于这个大陆,大部分来自印度。虽然印度在调查中有很好的代表性,但它不应该被高估。正如图 11 所示,与印度相比,俄罗斯、日本和中国目前在比赛中表现更好。*
第二个是*技术的使用在不同的 ML/DS 社区中非常相似*。虽然电力、计算机和互联网的接入因洲而异,但我们没有发现云服务和机器学习框架的数量和类型存在巨大差距(**Plots 34–41**)。看起来这些技术的使用已经相当大众化了,至少在 Kaggle 用户中是这样。
回到启发我们分析的博文(来自深度学习 Indaba 的那篇),我们看到了关于南美和非洲的更光明的前景。这些大陆并没有在 Kaggle 景观中消失(唯一真正消失的是中美洲)。*他们在场,他们竞争*,南美领先**第 3 组** ( **第 12 地块**和**第 14 地块**)。但是他们仍然有很多问题(因为我来自巴西,这些问题切中要害)。南美洲是一个经济规模可观的大洲(该洲的人均 GDP 大于亚洲),然而*来自该洲的排名用户数量与来自荷兰的排名用户数量相同* (64)。这是一个令人震惊的小数字。非洲仍然面临许多困难。当我们看一些重要的社会经济特征时,如正规教育、从事机器学习的年限和每年的薪酬,*最高的 KL 距离是在* ***组 3*** *的一个大陆和非洲* ( **地块 24** 、 **28** 和 **33** )。
归根结底,我们面临的最大挑战不是最新的 Kaggle 竞赛,而是我们社区的改善和培育。
# Kaggle Avito 需求挑战:第 18 名解决方案—神经网络
> 原文:<https://towardsdatascience.com/kaggle-avito-demand-challenge-18th-place-solution-neural-network-ac19efd6e183?source=collection_archive---------3----------------------->

前几天刚和队友在俄罗斯广告公司 Avito 主办的一场 Kaggle 比赛中获得银牌,以第 18 名结束。这项挑战的目标是根据他们提供的数据预测在线分类广告的需求。在这篇文章中,我将说明我的方法,我专门研究的神经网络(NN)(我的队友主要负责基于树和其他线性模型)。然后,我将谈谈我从顶级赢家的解决方案中学到的经验。
# 我的方法

NN Structure
如上图所示,我的神经网络模型由 4 个不同的模块组成,这些模块使用组织者提供的所有数据,图像、分类、连续和文本数据。我将在下面的段落中解释每一部分。
## 连续的
这是最不令人惊讶的部分。连续特征的输入张量直接与其他模块连接。需要注意的一点是处理空值。对于缺失的连续数据,我要么填 0,要么填平均值。
## 绝对的
对于分类数据,嵌入层用于学习这些离散值的潜在表示。我知道这可能不是一个新的想法,但这是我第一次使用分类嵌入,因为我从来没有使用 NN 来处理结构化/表格数据。范畴嵌入的概念类似于单词嵌入。类别值被映射到可学习的嵌入向量上,使得这些向量包含潜在空间中的含义。这有助于避免一次性编码分类特征的稀疏性,提高模型的性能。
## 文本
我的神经网络的文本部分比其他顶级赢家的方法相对简单。没有复杂的递归单元或卷积层,也没有使用预先训练的嵌入。我不知道为什么,但它们都不适合我的神经网络模型。这里唯一的技巧是使用一个共享的嵌入层,受 Mercari 挑战赛中第二名解决方案的启发。基于相同的嵌入矩阵嵌入两个文本条目,标题和描述。它不仅有助于加快神经网络的训练,而且还导致更快的收敛和更低的损失。
## 图像
我对图像数据的第一种方法是使用预先训练的 ImageNet 模型来提取有或没有这些模型头部的特征。我试过 ResNet50 和 InceptionV3 不幸的是,它们都不起作用。在比赛还有 2 周的时候,有人在论坛上说他的模型包括几个卷积层来训练原始图像和其他特征。因此,我开始重写我的代码,以便它利用一个生成器来读取图像和表格数据,因为不可能将所有图像数据加载到 RAM 中。在尝试了一些结构后,我发现 1 个 InceptionV3 单元+几个卷积层最适合我(因为我在 GCP 上只有一个 K80 GPU,所以需要很长时间来验证几次实验的结果)。
# 从顶级解决方案中吸取的经验教训
1. 第一位置 NN 解决方案也遇到了从大多数预先训练的 ImageNet 模型中提取的特征的较差性能。他们最终使用了 VGG 顶层+ ResNet50 中间层。他们的方法与我之前的方法最大的不同是,在提取的图像特征与其他条目连接之前,他们应用了平均池并添加了密集层。
2. 类别特征交互:连接两个类别特征,并将其视为一个新特征。
3. 无监督学习:使用自动编码器从分类数据中提取向量。
4. 验证策略:注意每个折叠之间的重叠特征值应该类似于训练/测试分割的特征值。(特别是本次比赛中的用户 id)
5. 损失函数:所有前 3 名的解决方案都使用二元交叉熵作为损失函数,而我在整个比赛中使用 MSE。我应该尝试更多的损失函数,如 BCE 和 Huber 损失。
6. 堆叠:我们在比赛结束前一周开始堆叠,所以我们只有几个浅堆叠的基础模型。几乎所有的顶级解决方案都使用了大量的模型进行更宽更深的堆叠(第二名获奖者使用了 6 层…)
我在这场比赛中玩得很开心。我要感谢我的队友,所有公开分享他们想法/解决方案的人。我从你身上学到了很多!我也要感谢 Kaggle 和主办方举办了这样一场伟大的比赛。没有你,我就无法提高我的机器学习技能。
如果想了解更多我的解决方案,可以参考这个 [Github repo](https://github.com/khuangaf/Kaggle-Avito-NN) 。
# Kaggle 竞赛—图像分类
> 原文:<https://towardsdatascience.com/kaggle-competition-image-classification-676dee6c0f23?source=collection_archive---------15----------------------->
## 如何使用迁移学习建立一个可以预测输入图像分类的 CNN 模型

**第一个误区** — [Kaggle](https://www.kaggle.com/) 是一个举办机器学习竞赛的网站。我相信这种误解让很多数据科学初学者——包括我——认为 Kaggle 只适合数据专业人士或有多年经验的专家。事实上,Kaggle 提供的不仅仅是竞赛!
Kaggle 上有如此多的[开放数据集,我们可以简单地从玩我们选择的数据集开始,并在过程中学习。如果你是一个对数据科学毫无经验的初学者,并且可能想在加入之前参加更多的在线课程,请三思!Kaggle 甚至为你提供一些基础而实用的](https://www.kaggle.com/datasets)[编程和数据科学课程](https://www.kaggle.com/learn/overview)。此外,您可以随时在 [Kaggle 讨论](https://www.kaggle.com/discussion)中提出您的问题,以便向活跃的数据科学社区寻求建议或澄清任何数据科学问题。
脸书创始人兼首席执行官马克·扎克伯格在哈佛毕业典礼上的演讲中分享了一段真正启发了我的话
> 你只需要开始。
>
> —马克·扎克伯格
开始并迈出第一步一直是做任何事情之前最难的部分,更不用说取得进展或提高了。
有很多在线资源可以帮助我们开始使用 Kaggle,我将在这里列出一些我认为非常有用的资源:
1. [使用 Kaggle 开始(并指导)您的 ML/数据科学之旅——为什么以及如何进行](/use-kaggle-to-start-and-guide-your-ml-data-science-journey-f09154baba35)
2.[机器学习从零到英雄](/machine-learning-zero-to-hero-everything-you-need-in-order-to-compete-on-kaggle-for-the-first-time-18644e701cf1)
3.[数据科学 A-Z 从零到 Kaggle 内核大师](/data-science-from-zero-to-kaggle-kernels-master-f9115eadbb3)
在接下来的部分,我希望与你分享一个初学者在他的第一次 Kaggle 比赛中的旅程(和他的团队成员一起)以及一些错误和教训。你可以[在这里](https://www.kaggle.com/chloekexin/da-machine)查看代码。这些部分分布如下:
1. 竞争的背景和数据
2. 方法
3. 结果
4. 最后的想法
让我们开始吧,我希望你会喜欢它!
# 竞争背景和数据
在我的第一篇关于 Medium 的帖子——[我从物理到数据科学的旅程](/my-journey-from-physics-into-data-science-5d578d0f9aa6)中,我提到了我和我的团队成员——[**罗伟鸿**](https://www.linkedin.com/in/lowweihong/) **、** [**崇科信**](https://www.linkedin.com/in/kexinchong/) **、**和[**Onn**一起参加了由****](https://www.linkedin.com/in/ling-wei-onn-452957147/) ****[Shopee](https://shopee.sg/) 和(IET)工程技术学院举办的[首届 Kaggle 机器学习竞赛](https://www.kaggle.com/c/shopee-iet-machine-learning-competition)我们在旅途中玩得很开心,我确实从他们身上学到了很多!!****
Shopee 给了我们 18 个类别的商品图像,我们的目标是建立一个模型,可以预测输入图像到不同类别的分类。
太好了。现在我们已经了解了上下文。让我们继续我们的图像分类预测方法——这是 ***有趣(我是说最难)*** 的部分!
## 用于分类的一些图像

Different Images for Classification
正如您从图像中看到的,一些图像中存在一些噪声(不同的背景、描述或裁剪的文字),这使得图像预处理和模型建立更加困难。
在下一节中,我将讨论我们解决这个问题的方法,直到构建我们定制的 CNN 模型。
# 方法

[(Source)](https://unsplash.com/photos/oVpn10bqxkc)
每当人们谈论图像分类时,**卷积神经网络(CNN)** 就会自然而然地出现在他们的脑海中——毫不奇怪——我们也不例外。
我第一次接触 CNN 时,知识和经验都很少, **Google** 是我最好的老师,我不得不强烈推荐这本由[阿迪特·德什潘德](https://www.linkedin.com/in/aditdeshpande/)撰写的简明而全面的 CNN 简介。高水平的解释打破了 CNN 一度令人生畏的结构,变成了我能理解的简单术语。
## 图像预处理
图像预处理也可以称为[数据增强](https://keras.io/preprocessing/image/)。

Generate batches of tensor image data with real-time data augmentation that will be looped over in batches
在将图像输入模型之前,数据扩充步骤是必要的,特别是对于给定的 [不平衡且有限的数据集](https://medium.com/nanonets/how-to-use-deep-learning-when-you-have-limited-data-part-2-data-augmentation-c26971dc8ced)。通过对图像进行不同的变换、缩放和剪切范围来人为扩展我们的数据集,我们增加了训练数据的数量。
## —第一个错误—
我相信每一种方法都来自于背后的多次尝试和错误。因此,在展示我们的最终方法之前,让我们先谈谈我们的第一个错误。
**我们开始尝试从零开始构建我们的 CNN 模型**(没错,就是这样!)来查看 CNN 模型基于训练和测试图像的表现。我们不知道大多数人很少从零开始训练 CNN 模型,原因如下:
1. 数据集不足(训练图像)
2. CNN 模型很复杂,通常需要几周甚至几个月来训练,尽管我们有集群机器和高性能 GPU。
3. 成本和时间不能保证和证明模型的性能
幸好[转学](https://machinelearningmastery.com/transfer-learning-for-deep-learning/)来救我们了。
## 迁移学习
那么……迁移学习到底是什么?
[**迁移学习**](https://machinelearningmastery.com/transfer-learning-for-deep-learning/) 是一种机器学习方法,其中为一个任务开发的模型被重新用作第二个任务的模型的起点。在我们的例子中,这是一种[方法](https://adeshpande3.github.io/adeshpande3.github.io/A-Beginner's-Guide-To-Understanding-Convolutional-Neural-Networks-Part-2/),采用预先训练好的模型(之前已经在大型数据集上训练过的网络的权重和参数),并用我们自己的数据集对模型进行“微调”。
太好了。由于 Keras 中有如此多的预训练模型可用,我们决定分别尝试不同的预训练模型***(vgg 16、VGG19、ResNet50、InceptionV3、DenseNet 等。)**并选出最佳型号。*
**
*[Inception V3 Google Research](https://medium.com/@14prakash/transfer-learning-using-keras-d804b2e04ef8)*
*最终我们选择了 [**InceptionV3 模型**](https://keras.io/applications/#inceptionv3) ,权重在 [ImageNet](http://image-net.org/) 上预训练,准确率最高。*
**
*为无休止的评论道歉,因为我们想确保每一行都是正确的。*
*乍一看,这些代码可能有点令人困惑。让我们通过下面解释的逻辑来进行分解,使事情变得更清楚:*
1. *我们首先使用之前导入的预训练的 InceptionV3 模型创建了一个基础模型。为了以后的定制目的,在神经网络的顶部移除了完全连接的最后一层。*
2. *然后我们添加了一个 [**全局空间平均池层**](https://alexisbcook.github.io/2017/global-average-pooling-layers-for-object-localization/) ,原因可以在这里找到[。](https://www.quora.com/What-is-global-average-pooling)*
3. *之后,我们创建了一个新的**全连接输出层**,接着是一个**脱落层**用于正则化目的。*
4. *最后,我们为 18 个类别(18 类图像)添加了一个 **softmax 层**,并且**将基础模型与创建的新输出层**相结合。*
**
*在这个阶段,我们冻结了基础模型的所有层,只训练新的输出层。*
*这就是迁移学习的美妙之处,因为我们不需要重新训练整个组合模型,因为基础模型已经被训练过了。*
## *微调组合模型*
*一旦顶层训练好了,我们就微调内层的一部分。*
**
*可选地,通过选择和训练顶部的 2 个先启块(组合模型中 249 层之后的所有剩余层)来实现微调过程。训练过程与以前相同,只是包括的层数不同。*
*是的,我们结束了!*
# *结果*
***最终准确率为 78.96%。***
*我们尝试了不同的方法来微调超参数,但无济于事。*
*当所有的结果和方法在比赛结束后揭晓时,我们发现了我们的第二个错误…*
## *—第二个错误—*
***我们没有使用叠加法的集合模型。***
*所有顶级团队的共同点是他们都使用集合模型。*
*相反,我们分别训练不同的预训练模型,只选择最佳模型。这种方法间接使得我们的模型在只使用一个模型测试数据时不够健壮,并且容易过度拟合。*
# *最后的想法*
**
*[(Source)](https://unsplash.com/photos/JSF-PcnsFx8)*
*尽管比赛时间很短,但我从我的团队成员和其他团队那里学到了很多东西——从理解 CNN 模型,应用迁移学习,制定我们学习其他团队使用的其他方法的方法。*
*这个过程并不容易。学习曲线很陡。学习之旅充满挑战,但同时也很有收获。我非常期待另一场比赛!😄*
*感谢您的阅读。*
*一如既往,如果您有任何问题或意见,请随时在下面留下您的反馈,或者您可以随时通过 [LinkedIn](https://www.linkedin.com/in/admond1994/) 联系我。在那之前,下一篇文章再见!😄*
## *关于作者*
*[**阿德蒙德·李**](https://www.linkedin.com/in/admond1994/) 目前是东南亚排名第一的商业银行 API 平台 [**Staq**](https://www.trystaq.com) **—** 的联合创始人/首席技术官。*
*想要获得免费的每周数据科学和创业见解吗?*
*你可以在 [LinkedIn](https://www.linkedin.com/in/admond1994/) 、 [Medium](https://medium.com/@admond1994) 、 [Twitter](https://twitter.com/admond1994) 、[脸书](https://www.facebook.com/admond1994)上和他联系。*
*[](https://www.admondlee.com/) [## 阿德蒙德·李
### 让每个人都能接触到数据科学。Admond 正在通过先进的社交分析和机器学习,利用可操作的见解帮助公司和数字营销机构实现营销投资回报。
www.admondlee.com](https://www.admondlee.com/)*
# Kaggle 竞赛:英特尔和 MobileODT 宫颈癌筛查
> 原文:<https://towardsdatascience.com/kaggle-competition-intel-mobileodt-cervical-cancer-screening-8a594a54d5ca?source=collection_archive---------1----------------------->
我开始看 Kaggle 比赛来练习我的机器学习技能。当前正在进行的竞赛之一被框架化为图像分类问题。英特尔与 MobileODT 合作,开始了一场 [Kaggle 比赛,以开发一种基于图像识别女性子宫颈类型的算法](https://www.kaggle.com/c/intel-mobileodt-cervical-cancer-screening)。
训练集包含分成三种类型的 1481 幅图像。Kagglers 可以使用 6734 额外的图像。其中一些来自重复的病人。一些附加图像质量较低。比赛的两个阶段的测试集是可用的,kagglers 必须提交一组预测概率,3 个类别中的每一个,测试集的每个图像。总奖金为 100,000 美元。
我试图以一种天真的方式来解决这个问题:只需获得一个预训练的 Inception V3 图像分类模型,并在这个数据集上对其进行微调。
**数据**
Philipp Schmidt 出版了[子宫颈 EDA](https://www.kaggle.com/philschmidt/intel-mobileodt-cervical-cancer-screening/cervix-eda/notebook) 笔记本:研究数据集的基本属性。
我加载了所有带标签的图像,并将它们的大小调整为 224x224 的形状,这在 Inception V3 中使用。以 80/20 的比例混合并分成训练集和开发集。
**型号**
使用 Keras 加载在 ImageNet 数据集上预先训练的 Inception V3 模型和权重。移除了顶部分类层,在顶部添加了一个新的带有 dropout 的密集层和一个 softmax 层。我冻结了所有的初始层,首先训练新的密集层。然后《盗梦空间》的最后两个卷积块被解冻,我也对它们进行了微调。该模型在 80%的标记数据上进行训练,在 20%上进行验证。
**结果**
不太好。验证损失不会低于 0.95。该模型过拟合很快。我在验证集上得到 54.5%的准确率。
我的代码在[这里](https://github.com/surmenok/Kaggle-MobileODT/blob/master/MobileODT_CNN.ipynb)可用。
正如你在关于 Kaggle ( [1](https://www.kaggle.com/c/intel-mobileodt-cervical-cancer-screening/discussion/30401) 、 [2](https://www.kaggle.com/c/intel-mobileodt-cervical-cancer-screening/discussion/30312) 、 [3](https://www.kaggle.com/c/intel-mobileodt-cervical-cancer-screening/discussion/30342) 的讨论中所看到的,一个未经训练的人很难对这些图像进行分类。参见 visoft 的[如何(人工)识别子宫颈类型的简短教程](https://www.kaggle.com/c/intel-mobileodt-cervical-cancer-screening/discussion/30471)。
低画质更难。另一个挑战是数据集的规模较小。
看起来最好的前进方式是将问题一分为二:图像分割以在图像中找到子宫颈,然后进行图像分类。图像分割问题需要人工审查训练样本,以找到包围盒。[光照校正](https://www.kaggle.com/c/intel-mobileodt-cervical-cancer-screening/discussion/31163)可以另当别论去尝试。数据扩充(旋转、翻转)有助于增加训练样本的数量。
在这一步,我想我对处理图像分类问题有了很好的感觉。这个对我来说太难了,我现在无法竞争,计算机视觉也不是我关注的领域。我去查查其他比赛。这个看起来很有趣:[两个适马连接:租赁列表查询](https://www.kaggle.com/c/two-sigma-connect-rental-listing-inquiries)。这是一个分类问题。数据集包括结构化数据、文本和图像。
*文章原载于*[*http://Pavel . surmenok . com/2017/04/09/ka ggle-competition-Intel-mobile ODT-宫颈癌-筛查/*](http://pavel.surmenok.com/2017/04/09/kaggle-competition-intel-mobileodt-cervical-cancer-screening/)
# Kaggle 星球大赛:如何登陆前 4%
> 原文:<https://towardsdatascience.com/kaggle-planet-competition-how-to-land-in-top-4-a679ff0013ba?source=collection_archive---------2----------------------->

在这篇博文中,我们将学习如何在著名的 Kaggle 竞赛“[星球:从太空了解亚马逊](https://www.kaggle.com/c/planet-understanding-the-amazon-from-space)”中取得世界级的成绩。
*博客中使用的技术是通用的,可以应用于任何其他需要物体检测的问题。这些技巧都在*[***fast . ai deep learning MOOC***](http://forums.fast.ai/t/unofficial-release-of-part-1-v2/9285)*中有所教授。在本教程中,我们将使用基于 PyTorch 构建的*[*fastai*](https://github.com/fastai/fastai)*deep learning 库。*
# 下载比赛数据
让我们开始吧,登录 Kaggle 账号,前往[竞赛页面](https://www.kaggle.com/c/planet-understanding-the-amazon-from-space),接受竞赛规则,前往*数据*标签,下载以下文件。
* *sample _ submission _ v2 . CSV . zip*
* *test-jpg-additional . tar . 7z*
* *test-jpg.tar.7z*
* *train-jpg.tar.7z*
* *train_v2.csv.zip*
我们可以使用***k***[***aggle-cl***](https://github.com/floydwch/kaggle-cli)***I***下载文件,这在你使用 AWS、Paperspace 等云 VM 实例时很有用。要使用 ***kaggle-cli*** 下载文件,请使用以下命令。
$ kg download -u
其中`planet-understanding-the-amazon-from-space`是比赛名称,你可以在比赛 URL 的末尾 `/c/` 部分`[https://www.kaggle.com/c/planet-understanding-the-amazon-from-spac](https://www.kaggle.com/c/planet-understanding-the-amazon-from-space)e`后找到比赛名称。还有另一个很棒的 Chrome 扩展****Curl Widget***下载云实例上的数据。你可以在这里[查看](http://Builds a command line for 'curl/wget' tools to enable the download of data on a console only session.)。*
*文件下载完成后,我们可以使用以下命令提取文件。*
#To extract .7z files
7z x -so <file_name>.7z | tar xf -#To extract.zip files
unzip <file_name>.zip
*一旦提取完成,将所有文件从文件夹`test-jpg-additional`移动到`test-jpg`。*
*我们的数据准备好了。让我们开始构建模型。*
# *初始模型*
**注意:只有重要的代码片段显示在这篇博文中,完整的笔记本在这里*[](https://github.com/irshadqemu/Kaggle-Competitions/blob/master/Planet_amazon_resnet34.ipynb)**。***
* **如果你看了比赛的评价标准,你会知道它是基于 [f2 分数](https://clusteval.sdu.dk/1/clustering_quality_measures/5)。我们相应地为模型定义度量。我们将使用由微软公布的[深度剩余模型 **renet34** 的预训练实现。](https://arxiv.org/pdf/1512.03385.pdf)**
****
**获取 20%的可用训练数据作为验证数据,并加载预训练模型。**
****
## **寻找学习率**
**学习率是该模型最重要的超参数之一。它决定了模型学习的快慢。如果 LR 太高,模型将试图学习得太快,损失函数将不收敛。如果 LR 太低,模型将需要太长时间才能收敛。**
**使用 fastai 库找到一个好的学习率非常容易,只需运行下面两行代码。(*它有助于使用研究论文* [*中介绍的技术找到 LR,用于训练神经网络*](https://arxiv.org/abs/1608.03983) 的循环学习率)**
****
**这将绘制 LR 对损失函数的曲线图。LR 的一个好值是损失函数斜率最高的地方。正如我们所见,斜率在 0.1 左右最高,您可以使用任何接近它的值。用 0.1 左右的几个值进行实验,以找到 LR 的最佳值,这将是一个好主意。在尝试了几个值之后,0.2 似乎对我最有效。**
****
## **训练模型**
**比赛中的芯片总尺寸为 256X256,我们开始用 64x64 来训练我们的模型,并将随着训练的进展逐渐增加图像的尺寸*。这是避免过度拟合的非常好的技术。***
****
**输出具有以下格式**
**`[ <epoch_number> <train loss> <val loss> <val set f2 score>]`**
**让我们试着轻描淡写一下`fit function`。在训练模型时 *fastai* 实现了一种叫做*带重启的随机梯度下降(SGDR)的技术(* [*论文链接*](https://arxiv.org/abs/1608.03983) *)。*它在循环中训练模型,其中每个循环由一个或多个时期组成。对于每个周期,它从给定的 LR 值开始,并将随着训练的进行而指数地降低 LR ( *指数学习速率表*)。拟合中的第二个参数表示循环总数。一个循环中的总次数由以下两个参数`cycle_len`和`cycle_mult`控制。**
**`epochs in first cycle = cycle_len
epochs in second cycle = epochs in previous(first) cycle x cycle_mult
epochs in third cycle = epochs in previous(second) cycle x cycle_mult`
这是显示每个周期 LR 变化的图表。**
****
****解冻所有图层,并为图层设置不同的学习速率****
**默认情况下,`fastai`将冻结所有图层的权重,除了最后几个图层和它添加的用于微调给定数据集模型的图层。(*有 Keras 背景的数据科学家会欣赏这个,不需要* `*model.pop*` *、* `*model.add*` *、*`*model.layers[index].trainable=False*`*`*model.compile*`……)***
**所以在上述时代,所有的学习都是由那些解冻的最后一层完成的。
接下来,我们将解冻所有层的权重,以提高模型的准确性。**
****
**如果你给 *fastai* 一个 3 元素的数组,它会把层分成 3 组,【<初始卷积层>,<剩余卷积层>,<最后完全连接层>。对于每个集合,它将使用数组中相应的值。**
**在 CNN 的初始层学习寻找简单的特征(如边缘,颜色渐变,角落),这些特征对行星数据集同样有帮助。因此,我们对它们使用最低的 LR。CNN 的更高层学习寻找复杂的特征(像几何图案、脸、特定物体等)。更高层的 LR 值的增加将有助于它们更快地适应给定的数据集。**
**正如您从输出中看到的,我们的模型已经开始过度适应。我将在这里停止训练,并将训练图像大小增加到 128x128。**
****
**同样,通过将图像大小增加到 256x256 来训练模型。这将结束模型的训练阶段。**
****
***fastai* 还有一个非常好的特性叫做**测试时间增强(TTA)** 。这个想法很简单;对每个测试图像应用简单的增强以生成它的五个副本,然后对每个副本进行预测。您可以对这些预测进行平均,以显著降低误差(1–2%)。正如您在下面的代码中看到的,使用 TTA,F2 分数从 0.928 增加到 0.930。这是一个很好的分数。**
****
# ****第一次提交给 Kaggle****
**在提交文件中,我们需要对每个图像放置预测标签。每个图像可以属于多个类别。**
**`file_10770,agriculture clear cultivation primary road test_26732,agriculture clear cultivation haze primary`**
**如果您查看我们的验证集(下图)中的预测示例,您会看到我们的原始标签是 1 和 0 的形式,但我们的预测是浮点数。因此,我们需要为提交文件中包含的预测选择一个阈值(0.66 对于下面的例子是理想的)。**
****
**`op_th` 函数在给定范围内尝试多个阈值,并返回使 F2 分数最大化的阈值。**
****
**现在我们有了最佳阈值,让我们生成一个提交文件**
****
**这是 Kaggle 的提交结果。**
****
**私人得分 0.92997 将使我们在 938 名中排名第 65 位。这款最初的车型本应排在**前 7%。这是相当大的成就。让我们进一步改进它。****
****
**Private leader board of Kaggle planet competition.**
# **组装**
**我的下一个目标是进入前 5%。我训练了 5 个 resnet34 模型。每个模型的训练集由 90%的可用训练数据和剩余的 10 %数据组成,作为验证集。我还对每个模型的训练集应用了略有不同的数据扩充。这是所有模特的 F2 分数。**
f2 Score: 0.9285756738073999
f2 Score: 0.9325735931488134
f2 Score: 0.9345646226806884
f2 Score: 0.9331467241762751
f2 Score: 0.9349772800026489
**看到这一点后,我对职位的提高充满了希望。我准备了提交文件,并提交给 Kaggle。这是结果。**
****
**Kaggle submission result for ensemble**
**这里是 Kaggle 的私人领袖板。**
****
****0.93078 的个人得分将使我们在 938 分中排在第 35 位**。这是最高的 3.7%。**
## **所以我们进入了前 4%。目标实现**
***代码为合奏可以在* [*这里找到*](https://github.com/irshadqemu/Kaggle-Competitions/blob/master/Planet_amazon_resnet34.ipynb) *或者便签本底部。***
# **如何进一步提高**
**我将给你留下进一步改进的建议。**
* ****找到阈值的更好方法:**在准备提交文件时,我使用了大约 0.2 的阈值来为所有测试图像选择类别,但理想情况下,每个测试图像都应该有一个独立的阈值,具体取决于模型的预测值。我尝试训练一个 ML 模型来寻找更好的阈值,但没有成功。(*代码在笔记本***
* ****找出模型预测错误的类别:**从验证集预测中,您可以找出模型预测最不正确的类别。您可以在训练集中引入这些类的多个稍微扩充的副本。**
* ****用 tiff 代替 jpg:** 对于相同数量的图像,tiff 格式的训练数据集大小为 12.87 GB,而 jpg 格式的大小仅为 600MB,因此很明显 tiff 数据比 jpg 包含更多的信息。这必将有助于进一步改进模型。**
* ****尝试其他架构:**我只用过 resnet34 型号,它们是很多其他高级型号,比如 resnet50,resent101。你可以尝试这些。**
* ****减少过拟合:**如果你在笔记本上看集合训练的输出,你会知道我的一些模型在训练时开始过拟合。您可以尝试提前停止或退出,以减少过度拟合。**
* ****训练多个 CNN 架构的系综:**在准备系综的时候,我只用过 resnet34 的系综。您可以准备一个包括多种架构的系综,如 resnet50、resnet101 等。**
**如果你喜欢读这篇文章,请鼓掌。:-)**
**[](https://github.com/irshadqemu/Kaggle-Competitions/blob/master/Planet_amazon_resnet34.ipynb) [## irshadqemu/ka ggle-竞赛
### Kaggle-竞赛-我的 ka ggle 竞赛笔记本
github.com](https://github.com/irshadqemu/Kaggle-Competitions/blob/master/Planet_amazon_resnet34.ipynb)**
# Kaggle : Python : DataQuest
> 原文:<https://towardsdatascience.com/kaggle-python-dataquest-85ab1994fcdf?source=collection_archive---------1----------------------->

Kaggle.com
## 第二部分:[卡格比赛](https://www.kaggle.com/c/titanic)和[数据任务教程](https://www.dataquest.io/course/kaggle-competitions)在这句话中连在一起。在处理完第 1 部分之后。我回来接受更多的惩罚。
我正在使用 Cloud9 IDE,它有 ubantu,我从 Python2 开始,但我可能会以 python 3 结束。我仍然使用 DataQuest 作为我的指南,所以我们开始吧!请记住,到目前为止,我的代码如下所示:
`import pandas
import numpy as np
from sklearn import cross_validation
from sklearn.linear_model import LogisticRegression
titanic = pandas.read_csv(“train.csv”)
predictors = [“Pclass”, “Sex”, “Age”, “SibSp”, “Parch”, “Fare”, “Embarked”]
alg = LogisticRegression(random_state = 1)
kf = cross_validation.KFold(titanic.shape[0], n_folds=3, random_state=1)
predictions = []
fillage = titanic[“Age”].median()
titanic[‘Age’] = titanic[‘Age’].fillna(fillage)
titanic.loc[titanic[“Sex”] == “male”, “Sex”] = 0
titanic.loc[titanic[“Sex”] == “female”, “Sex”] = 1
titanic[“Embarked”] = titanic[“Embarked”].fillna(‘S’)
titanic.loc[titanic[“Embarked”] == “S”, “Embarked”] = 0
titanic.loc[titanic[“Embarked”] == “C”, “Embarked”] = 1
titanic.loc[titanic[“Embarked”] == “Q”, “Embarked”] = 2
for train, test in kf:
train_predictors = (titanic[predictors].iloc[train,:])
train_target = titanic[“Survived”].iloc[train]
alg.fit(train_predictors, train_target)
test_predictions = alg.predict(titanic[predictors].iloc[test,:])
predictions.append(test_predictions)
predictions = np.concatenate(predictions, axis=0)
predictions[predictions > .5] = 1
predictions[predictions <=.5] = 0
num = len(predictions)`
`i=0
count = 0.0
#print(count)
for prediction in predictions:
if predictions[i] == titanic[“Survived”][i]:
count = count + 1
i = i+1`
`accuracy = float(count/num)
scores = cross_validation.cross_val_score(alg, titanic[predictors], titanic[“Survived”], cv=3)`
`titanic_test = pandas.read_csv(“test.csv”)
fillFare = titanic_test[‘Fare’].median()
fillAge = titanic_test[‘Age’].median() +1
titanic_test[‘Fare’] = titanic_test[‘Fare’].fillna(fillFare)
titanic_test[‘Age’] = titanic_test[‘Age’].fillna(fillAge)
titanic_test[‘Embarked’] = titanic_test[‘Embarked’].fillna(‘S’)
titanic_test.loc[titanic_test[‘Sex’] == ‘male’, ‘Sex’] = 0
titanic_test.loc[titanic_test[“Sex”] == “female”, ‘Sex’] = 1
titanic_test.loc[titanic_test[‘Embarked’] == ‘S’, ‘Embarked’] = 0
titanic_test.loc[titanic_test[‘Embarked’] == ‘C’, ‘Embarked’] = 1
titanic_test.loc[titanic_test[‘Embarked’] == ‘Q’, ‘Embarked’] = 2`
`alg.fit(titanic[predictors], titanic[“Survived”])
predictions = alg.predict(titanic_test[predictors])
submission = pandas.DataFrame({
“Survived”: predictions
},index= titanic_test[“PassengerId”])`
`submission.to_csv(‘Kaggle.csv’)
#print(titanic.describe())`
注意:*现在 python 2 不喜欢“准确性”这一行*叹*所以我换了 python 3。在 c9 中,当你在一个工作空间中时,你可以按 settings 菜单,在 python 2 和 3 之间切换。记住,你必须下载你正在使用的新版本的所有软件包。*
计划的第二部分是提高我们的提交分数。第一个实用模块是关于一个叫做随机森林的东西。一棵树就像我们在小学看到的流程图。

有“是”或“否”的输入来导致决定或最终答案(有点像玩 20 个问题)。这些统计学上的答案叫做终端节点。这允许机器通过将关系简化为一系列线性关系来理解可能不是线性的关系。对于你们这些书呆子来说,在微积分中,不管函数有多复杂,随着你看到的区间变小,它会变成一条直线,然后变成一个点(一般来说)。你可以把一个复杂的问题变成一系列简单的问题。
现在,如果你做多棵树,你会有一个森林。当你用随机的初始起点从数据中创建其他的树时,你可以很好的观察数据告诉你什么。取森林的平均值,就可以开始做预测了。如果树木不是随机的,这种技术就叫做“套袋”。
Sklearn 可以用来实现一个森林。Sklearn 有一个名为[的随机森林分类器](http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html)的模块,在集成模块下完成这项工作。创建的森林将有十棵树。我们将使用泰坦尼克号的测试数据来做这件事。
在我做任何事情之前,我会删除打印语句和导出语句,因为它们是不需要的。
Dataquest 明确写出了许多参数,但是根据文档,它们使用的值与默认值相同。
`algForest = RandomForestClassifier(random_state=1, n_estimators=10, min_samples_split=2, min_samples_leaf=1)`
以上代码由 Dataquest 提供:
1)n_estimators = >森林中树木的数量;默认值= 10
2)min_samples_split = >分割 3)内部节点所需的最小样本数;默认值= 2
4)min_samples_leaf= >作为叶节点所需的最小样本数;默认值= 1
现在,我们可以使用这种新算法,并以与基于日志的算法相同的方式实现它。
首先我们做一个交叉验证。这将模拟我们之前代码中定义“score”的行,并为 cv(交叉验证)参数传递 kf 变量。我的看起来像这样:
> `*from sklearn import cross_validation
> from sklearn.ensemble import RandomForestClassifier titanic=pandas.read_csv(“train.csv”)
> predictors = [“Pclass”, “Sex”, “Age”, “SibSp”, “Parch”, “Fare”, “Embarked”] algForest = RandomForestClassifier(random_state=1, n_estimators=10, min_samples_split=2, min_samples_leaf=4)
> kf = cross_validation.KFold(titanic.shape[0], n_folds=3, random_state=1) scores_forest = cross_validation.cross_val_score(algForest, titanic[predictors], titanic[‘Survived’], cv=kf)*`
>
> `*print(scores.mean())*`
现在,是时候生成一些新特性了。我以前在处理一些计算物理问题时用过熊猫。但是我从来没有在数据帧上真正使用过它。
我使用 pandas apply()函数和 lambda 函数。apply()函数从我们实现的 lambda 函数中推断出一个 pandas 系列。
我们将使用简单的加法来计算家庭规模和名字的长度(名字越长,等级越高…理论上)。
Dataquest 写出了这些行,我将它们添加到测试集和训练集中。
`titanic[‘FamilySize’] = titanic[‘SibSp’] + titanic[‘Parch’]
titanic[‘NameLength’] = titanic[‘Name’].apply(lambda x: len(x))`
现在我应该得到每个乘客的头衔,在我看来,这比名字的长度更能反映身份。
对于这一个,我需要构建一个函数来完成这项工作。我将在不同的文件中创建这个类,并将它导入到原始文件中。
我准备用一个正则表达式(大家的最爱)来搜索名字。
`‘([A-Za-z]+)\.’`
这意味着 reg ex 搜索将从 A 到 Z 查找一个大写字母,后跟一串字母,并以句点结尾。
当我使用 re.search()函数进行搜索时,我需要首先检查我是否找到了匹配项,如果是,我需要得到搜索找到的内容。为了实现前者,我使用了一个简单的 if 语句。为了实现后者,我需要使用 group 函数。Group 采用 reg ex 给定的子组的编号。这意味着组(1)将返回由`[A-Za-z]`表示的内容。
然后,我使用 pandas apply()将查找标题的函数映射到数据集的 Name 列:
> `def get_titles(name):
> title_search = re.search(‘ ([A-Za-z]+)\.’, name)
> if title_search:
> return title_search.group(1)
> return “”`
>
> `titles = titanic[“Name”].apply(get_titles)`
此外,我可以使用 pandas.value_counts 对每个输出进行计数。
遍历 pandas.value_counts 中的键/值对,使用标题作为键,计数作为值来创建数据集:
> `title_mapping = {“Mr”: 1, “Miss”: 2, “Mrs”: 3, “Master”: 4, “Dr”: 5, “Rev”: 6,
> “Major”: 7, “Col”: 7, “Mlle”: 8, “Mme”: 8, “Don”: 9, “Lady”: 10, “Countess”: 10,“Jonkheer”: 10, “Sir”: 9, “Capt”: 7, “Ms”: 2}`
>
> `for k,v in title_mapping.items():
> titles[titles == k] = v`
现在我把我的注意力转向看我能不能搞清楚家庭团体。当谈到生存能力时,这是一个很好的选择。什么规模的家庭存活几率更大?
首先我们导入[操作符模块](https://docs.python.org/2/library/operator.html)。这个模块很难用语言来解释。为了简化,它采用运算(+、-、x 等)并将它们转换成可以提供参数的函数。因此`operator.add(x,y)`在功能上与`x+y`相同。
导入之后,正如我对标题所做的那样,我们需要定义一个映射字典。但是这一次,字典将是空的(最初)。
然后,当给定一行时,我创建一个函数来获取 id。在该函数中,首先我们获得姓氏,然后我使用 reg ex `“{0}{1}”`创建一个 id,并将其与姓氏相关联。这样做之后,我创建一个条件:如果系列 id 不在我们之前创建的系列映射字典中,那么我向字典中添加一个全新的系列,如果 id 确实存在,那么我向该系列 id 添加 1:
> `def get_family_ids(row):
> last_name = row[‘Name’].split(“,”)[0]
> family_id = “{0}{1}”.format(last_name, row[“FamilySize”])
> if family_id not in family_id_mapping:
> if len(family_id_mapping) == 0:
> current_id = 1
> else:
> current_id = (max(family_id_mapping.items(), key=operator.itemgetter(1))[1] + 1)
> family_id_mapping[family_id] = current_id
> return family_id_mapping[family_id]`
在函数外部,我使用 pandas.apply 方法定义了 family _ ids。参数是我们创建的函数,用于获取系列 id 和轴=1。
DataQuest 让我把所有少于三人的家庭压缩成一个代码。我说…不。我们看看会发生什么。
最后,我们将该列添加到我们的数据集,然后打印出来。
> `family_ids = titanic.apply(get_family_ids, axis=1)
> titanic[“FamilyId”] = family_ids`
这些代码的大部分是由 DataQuest 编写的,我花了一些时间来分析它并弄清楚发生了什么。看了很多文件!
不管怎样,我要去寻找预测的最佳特征了。我的森林里有哪些问题通常能让我得到正确答案?
接下来我将使用一个叫做[的东西,单变量特征选择](http://scikit-learn.org/stable/auto_examples/feature_selection/plot_feature_selection.html)。那是一口。我需要从 scikitlearn 导入更多的模块; [SelectKBest](http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.SelectKBest.html) ,f_classif。
然后,我需要将我创建的新参数(头衔和家庭规模)添加到预测列表中。
我把一个叫做选择器的变量等同于以 f_classif 和 k=5 为参数的函数 selectBest。I 将选择器与巨大的预测器和幸存的参数列相匹配。
我使用 numpy.log10 和 p 值计算每个预测值的得分。根据[这篇文章](http://blog.minitab.com/blog/adventures-in-statistics-2/how-to-correctly-interpret-p-values):
> p 值评估样本数据在多大程度上支持“魔鬼代言人”的论点,即零假设为真。它衡量你的数据与零假设的符合程度。如果零假设为真,在样本数据中观察到这种效应的可能性有多大?
>
> 高 P 值:您的数据可能为真空值。
>
> 低 P 值:您的数据不太可能为真空值。
然后我用 matplotlib.pylot 将结果图形化,有了这个,我就能算出什么是最好的预测器(“Pclass”、“Sex”、“Fare”、“Title”)。然后,我使用我们为随机森林创建的算法来重新定义分数,并打印出平均值。为了便于阅读,我将这个新的分数称为 scores_graph。
> `predictors = [“Pclass”, “Sex”, “Age”, “SibSp”, “Parch”, “Fare”, “Embarked”, “FamilySize”, “Title”, “FamilyId”, “NameLength”]
> selector = SelectKBest(f_classif, k=5)
> selector.fit(titanic[predictors], titanic[“Survived”])
> algForest.fit(titanic[predictors], titanic[‘Survived’])
> scores_graph = -np.log10(selector.pvalues_)
> plt.bar(range(len(predictors)), scores_graph)`
>
> `plt.xticks(range(len(predictors)), predictors, rotation=’vertical’)
> plt.show()`
在这一点上,我遇到了 c9 的障碍。它不会显示图表。*她哭泣*所以我问了我的老朋友谷歌先生,我得到了[这里](http://stackoverflow.com/questions/15089174/support-for-cloud9-ide-and-matplotlib-or-other-graphical-tool-for-python)。我需要与进口和 matplotlib 的工作方式。
`import matplotlib
matplotlib.use(‘Agg’)`
* 注意,这些行应该在导入 matplotlib.pyplot 之前插入。
所以在你画出图后,你加上这两条线:
`fig = plt.figure()`
`fig.savefig(filename)`
它应该在程序所在的目录下创建一个你选择的格式的文件。
在这一点上,下一个模块是关于梯度增强,这是一种增强我们从随机森林中获得的预测的方法。但是,我不知道它是如何工作的,所以我查了一下,找到了这个视频。哈佛大学的统计学教授特雷弗·哈斯蒂谈到了这个话题(我不得不查一些术语)。
Boosting Trees 获取树,并像以前一样找到平均值,但这一次,它将根据是否得到好的结果来加权每棵树。它会增加森林中表现不佳的部分的权重,并尝试修复错误。这可能会导致过度拟合,当我们准备好预测时,这会导致各种各样的问题,但对于我们的目的来说,这是可以的。
在梯度增强之后是关于集合的部分。这是将不同的分类器(如线性、对数、随机森林或装袋)放在一起的行为。就像科学怪人的统计数据。为了充分利用这一点,分类器需要具有不同的类型,并且具有相似的等级(具有相似的)误差值。DataQuest 让我使用带有梯度提升树的对数分类器。
从 scikitLearn 中,我导入了梯度推进分类器模块,并给它一个随机状态 1,估计数量为 25,每棵树只有 3 个分支(两个是二进制选择:是或否问题,它们被称为树桩)。
然后,我创建了一个名为“ens”的数组,它将两个算法作为嵌套数组的元素。一个数组中有梯度增强分类器和预测器,另一个数组中有对数回归和预测器(不同的)。设置好之后,我在训练数据集中使用它。
然后,因为梯度提升比对数回归更准确,所以我们将权重添加到提升中(三倍于对数):
> `predictions = []
> predictors = [“Pclass”, “Sex”, “Age”, “Fare”, “Embarked”, “FamilySize”, “Title”, “FamilyId”]
> ens = [[alg_gradient , predictors],[alg ,[“Pclass”, “Sex”, “Fare”, “FamilySize”, “Title”, “Age”, “Embarked”]]]
> for train, test in kf:
> train_target = titanic[‘Survived’].iloc[train]
> full_test_predictions = []
> for alg, predictors in ens:
> alg.fit(titanic[predictors].iloc[train,:], train_target)
> test_predictions = alg.predict_proba(titanic[predictors].iloc[test,:].astype(float))[:,1]
> full_test_predictions.append(test_predictions)
> test_predictions = (full_test_predictions[0] + full_test_predictions[1]) / 2
> test_predictions[test_predictions <= .5] = 0
> test_predictions[test_predictions > .5] = 1
> predictions.append(test_predictions)
> predictions = np.concatenate(predictions,axis=0)`
>
> `accuracy = sum(predictions[predictions == titanic[“Survived”]]) / len(predictions)`
因为这不是公主新娘,所以某人不可能“大部分”死亡,所以我们可以继续进行测试 _ 预测枯萎 0 或 1(幸存与否)。
在此之后,我将我们对训练数据所做的预测应用到完整的数据集。为此,我首先将整个数据集与训练数据进行拟合。然后使用 [alg.predict_proba()](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression.predict_proba) 函数填写预测值:
> `alg_ens = [
> [GradientBoostingClassifier(random_state=1, n_estimators=25, max_depth=3), predictors],
> [LogisticRegression(random_state=1), [“Pclass”, “Sex”, “Fare”, “FamilySize”, “Title”, “Age”, “Embarked”]]
> ]
> full_predictions =[]
> for alg, predictors in alg_ens:
> alg.fit(titanic[predictors], titanic[“Survived”])
> predictions = alg.predict_proba(titanic_test[predictors].astype(float))[:,1]
> full_predictions.append(predictions)
> predictions = (full_predictions[0] * 3 + full_predictions[1]) / 4
> predictions[predictions <= .5] = 0
> predictions[predictions > .5] = 1`
我再次使用本教程第一部分中的提交术语:
`submission = pandas.DataFrame({
“PassengerId”: titanic[“PassengerId”],
“Survived”: predictions
}).astype(int)
submission.to_csv(‘Kaggle.csv’)`
在上一篇文章中,我不得不进入我的 google drive,手动删除索引栏(像个傻瓜一样)。然后我做了一些研究,当我在做另一个项目时,我意识到当你使用熊猫导出到 csv 时,你可以关闭索引。你只需要写下:
`submission.to_csv(‘Kaggle.csv’,index=False)`
嘣!完成了。
对于 Python 版本,唯一的区别是“准确性”行必须用 2 注释掉。它与熊猫有关。
我这里的代码是。我要去睡觉了。
# Kaggle 盐识别挑战或如何分割图像
> 原文:<https://towardsdatascience.com/kaggle-salt-identification-challenge-7fc502d1c3c3?source=collection_archive---------19----------------------->
几周前,我在 Kaggle 上完成了 TGS 盐鉴定挑战赛,这是一个流行的数据科学竞赛平台。任务是在地震图像上准确识别地下目标是否为盐层。
我们的团队: [Insaf Ashrapov](https://www.linkedin.com/in/iashrapov/) , [Mikhail Karchevskiy](https://www.linkedin.com/in/mikhail-karchevskiy-aa46245a/) , [Leonid Kozinkin](https://www.linkedin.com/in/lkozinkin/)
我们获得了前 1%第 28 名,并希望分享我们的最终解决方案,该方案基于一个采用 hflip TTA(测试时间增加)的单一 5 重模型。
看看我的机器和深度学习博客[https://diyago.github.io/](https://diyago.github.io/)
# **输入**

Input image and mask as ground truth binary image
最初,我们有尺寸为 101*101 的灰度 1 通道输入图像。为了使其可用于预训练的编码器,我们将它们调整为 128x128,第一个通道通过填充作为源图像,第二个通道使用相对深度:
> *相对深度=(当前深度-最小深度)/(最大深度-最小深度)*
在第三个通道上,我们应用了[coord conv](https://eng.uber.com/coordconv/)【1】。我们尝试了更高的分辨率,但学习和收敛速度慢得多,没有任何改进,但其他一些参与者报告了显著的改进。
# **增强功能**
我们使用了来自伟大的[albumination](https://github.com/albu/albumentations)库中的增强功能:亮度、模糊、hflip、缩放、旋转和对比度。这里重要的是不要使用对所提供的数据集来说不自然或物理上不可能的图像增强,例如,垂直翻转只会产生负面影响。此外,这些增强不是太重,否则,我们会遭受较低的分割质量,甚至训练速度。
# **基本型号**
我们最终的模型是基于 Unet [2]的,和其他人一样做了一些微妙的修改。
SE-ResNeXt-50 [3](其性能优于所有 resnet 和更复杂的 SE-ResNeXt-101)作为获取初始特征图的编码器。然而,我们修改了第一层。首先,我们在没有最大池的情况下使用它,然后通过返回最大池,在 stride = 1 的情况下使用它。上述两种修改都允许使用 128*128 的图像,否则需要更高的图像分辨率。在我看来,缩放图像会给图像和蒙版带来一些不必要的伪影。
ScSE(空间通道压缩&激发)【4】编码器和解码器,超列【5】。
令我们惊讶的是,我们已经清除了所有辍学者。这是实质性的,因为加速了训练,提高了最终结果。我们甚至试图只用 16 个过滤器,但最终用了 32 个。似乎是增加和 5 倍平均足以避免过度拟合。
# **训练**
出于学习目的,我们使用了这样的参数和方法:
批量大小 20(适合 GPU 存储器的最大大小),Adam [6],循环学习速率[7],参数 mode =‘triangular 2’,baslr = 1e-4,maxlr=3e-4,step_size=1500,重快照集合[8](以指数递减的权重对最后 10 个最佳模型进行平均)。使用快照集合会产生无用的混合模型,或者对于这样的 lb 分数较低的模型不会给出任何提升。
对于前 80 个时期,我们使用 BCE(二进制交叉熵)损失进行训练,然后其他多达 420 个时期使用 0.1 BCE + 0.9 Lovasz 作为损失函数[9]。然而,几乎每次训练都被*ealystop*停止。只使用 Lovasz 效果也很好,但是 BCE 加快了初始训练。
我们用 1080ti 和 1070ti 配合 pytorch 进行训练。不幸的是,Keras 不太方便尝试新事物,而且 Pytorch 预训练的编码器库更丰富。
# **后处理**
通过使用[cv2 . connectedcomponentswithstats](https://docs.opencv.org/3.0-beta/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html)(形态学没有那么好)
更高(0.40+)的阈值移除小的遮罩和小的独立遮罩(黑色和白色)在私有 LB 上给了我们更好的分数,但是对于公共 LB,更小的阈值显示了相同的结果。拼图游戏[10]没有对本地验证进行改进,所以我们没有在最终提交中使用它。其他参与者仅在公共排行榜上报告了较高的改进:

Puzzle created by Arthur Kuzin (red-train masks, green-predicted test masks)
在上面的图片中,你可以看到一些垂直的面具,这些有点奇怪。此外,比赛结束后,组织者透露,我们寻找所谓的盐丘,这是封面石油。这就是为什么没有任何全尺寸的面具。
# **还有什么**
我们没有尝试两件大有希望的事情,这两件事可以帮助我们:
1)伪标签。然后,您在训练中使用具有高置信度的预测测试图像[10]。第一名把这个方法作为主要方法,这提高了他的分数。
2)深度半监督学习【12】。这种方法旨在使用标记和未标记的图像。这里,我们应该为不同的视图训练多个深度神经网络,并利用对立的例子来鼓励视图差异,以防止网络相互崩溃。结果,共同训练的网络提供了关于数据的不同的和互补的信息,这对于共同训练框架实现良好的结果是必要的。

Mean teachers are better role models: Weight-averaged consistency targets improve semi-supervised deep learning results. Image provided by Heng CherKeng
# **出版**
为了向更广泛的受众传播我们的解决方案,我们最近在 [arvix](https://arxiv.org/abs/1812.01429) 上发表了文章,并在 [Github](https://github.com/K-Mike/Automatic-salt-deposits-segmentation) 上发布了我们的解决方案。
# **参考文献**
1. Liu,r .、Lehman,j .、Molino,p .、suther,F.P .、Frank,e .、a .、Yosinski,j .:卷积神经网络和 coordconv 解的一个有趣的失败。arXiv 预印本 arXiv:1807.03247 (2018)
2. Ronneberger,o .,Fischer,p .,Brox,T.: U-Net:生物医学图像分割的卷积网络。医学图像计算和计算机辅助介入。第 234–241 页(2015 年)。
3. 胡,j,等:压缩和激发网络。arXiv:1709.01507 (2017 年)
4. [Abhijit G](https://arxiv.org/search/cs?searchtype=author&query=Roy%2C+A+G) 。纳西尔 N。、 [Wachinger](https://arxiv.org/search/cs?searchtype=author&query=Wachinger%2C+C) C .全卷积网络中的并发空间和信道压缩&激励 arXiv:1803.02579 (2018)
5. B.Hariharan、P. Arbeĺ aez、R. Girshick 和 J. Malik。用于对象分割和细粒度定位的超圆柱。InCVPR,2015 年。
6. D.P. Kingma 和 J. Ba,“Adam:随机优化方法”,arXiv 预印本 arXiv:1412.6980,2014 年。
7. 莱斯利·史密斯。训练神经网络的循环学习率。《计算机视觉应用》(WACV),2017 年 IEEE 冬季会议论文集,第 464–472 页。IEEE,2017 年
8. 黄高、黎一萱、杰夫·普莱斯、刘庄、约翰·E·霍普克罗夫特和基利安·Q·温伯格。2017.快照合集:火车 1,免费获得 M。arXiv 预印本 arXiv:1704.00109 (2017)。
9. Berman,m .,Rannen Triki,A .,Blaschko,m . b .:lovasz-soft max 损失:神经网络中交集-并集度量优化的易处理替代。在:CVPR (2018 年)
10. D.金,赵迪,刘迪,还有郭怡广。通过完成受损拼图学习图像表征。2018 年在 WACV。
11. 李东贤。伪标签:简单高效的
深度神经网络半监督学习方法。2013 年,在 ICML 举办的关于表征学习挑战的研讨会。
12. A.瓦尔波拉·塔尔瓦伊宁。均值老师是更好的榜样:加权平均一致性目标提高半监督深度学习结果 arXiv:1703.01780 (2017)。
# Kaggle Tensorflow 语音识别挑战
> 原文:<https://towardsdatascience.com/kaggle-tensorflow-speech-recognition-challenge-b46a3bca2501?source=collection_archive---------6----------------------->
## 我的方法概述

从 2017 年 11 月到 2018 年 1 月,谷歌大脑团队在 [Kaggle](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge#) 上举办了一场语音识别挑战赛。这项挑战的目标是编写一个程序,能够正确识别一秒钟长的音频文件中 10 个单词中的一个。刚刚下定决心开始认真学习数据科学,目标是在我的职业生涯中开辟一个新的角落,我决定将此作为我的第一个严峻的 kaggle 挑战。
在这篇文章中,我将谈论 ResNets,RNNs,1D 和 2D 卷积,连接主义者的时间分类等等。我们走吧!
## 探索性数据分析
Google Brain 提供的训练数据由 ca。6 万个 1 秒长的。32 个目录中的 wav 文件,这些目录由文件中的单词命名。其中只有 10 个是你需要识别的类别,其他的应该归入“未知”或“沉默”类别。您可以做几件事情来掌握您正在处理的数据。这个数据集并没有完全清理干净。例如,有些文件的长度不正好是 1 秒。也没有这样的“沉默”文件。你得到的是一些带有“背景”噪音的较长的录音,你可以自己把它们分成 1 秒钟的片段。你也可以在 word 文件中混合背景噪音,为你的声音在训练中提供不同的“环境”。
你需要做的一件重要的事情是清理数据,这在*的一个讨论*中提到:有相当多的文件音量极低。这些中的一些被破坏并且仅包含噪声,而一些基本上是没有任何口语单词的背景噪声。要删除或正确标记这些文件,有助于根据输出音量的动态范围对所有文件进行分类,然后检查是否存在最低声音级别阈值,低于该阈值,所有文件基本上都是无声的。事实证明,输出音量本身不足以将损坏/静音与良好的文件区分开来,所以我最终通过收听可疑文件和查看大量频谱图(见下文)来进行一些手动清理。
## 预处理
当您对音频进行分类时,您可以使用原始 wav 数据本身,也可以将音频转换为频谱图。声谱图是声音的直观表示,具有时间轴和频率轴,以及表示声音在该时刻和该频率的振幅或能量的像素强度。在制作频谱图时,有许多参数可供选择,这些参数会影响从频域或时域提取的信息量。关于深度学习的适用性,我还没有对所有这些参数进行详尽的分析,因为这需要花费很长时间。相反,我为不同的单词绘制了一系列不同维度和强度范围等的光谱图,并选择了看起来最容易在视觉上归类为不同单词的单词。

有人说“是”的音频源的一些不同的可视化。我选择了右下方的声谱图作为我的大多数网络的输入。与原始 wav 数据相比,使用 spectrograms 的优势在于,您可以将其视为一个图像分类问题,这是我们大多数人已经非常熟悉的。我尝试了两种方法。
为了加速网络的最终训练,我决定单独进行大部分预处理,并将单独的训练集和验证集保存为。npy 文件。数据量很小,可以在我的家用电脑上完成。Google Brain 建议您根据他们提供的“validation.txt”和“test.txt”文件中的文件名,将数据拆分为“train”、“validation”和“test”。因为他们还在 Kaggle 上提供了一个用于排行榜评分的测试集,所以我决定将“验证”和“测试”文本文件合并成一个验证集。预处理包括创建光谱图,围绕零进行归一化,为 10 个主要类别加上“沉默”和“未知”创建整数为 0-11 的“标签”或“Y”数组。对于 CTC 模型,我没有使用“未知”标签。所有 32 个班级都被平等对待。
因为我将这个挑战作为深度学习训练练习,所以我实现了一堆不同的网络设计。得到这样的实际训练真是太棒了。我从这个项目中学到的东西比我之前开始的十个 MOOCs 都多。(好吧,我稍微夸张一点)。我将讨论几个我的设计尝试以及实现时需要注意的事项。
## 原始 wav 文件,1D 卷积
使用 spectrograms,您可以使用特定的算法从 wav 文件中提取特征,但您必须微调一系列参数。一个设计良好的神经网络应该能够自己从原始 wav 文件中学习特征,并可能获得比从光谱图中获得的信息更多的特征。这第一个模型就是一个尝试。最初的设计很大程度上受到了用户 ttagu99 的一个 [Kaggle 讨论帖子](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/44283#256644)的启发。这是 6 层 1D 卷积网络的早期尝试的结果。

验证集上的网络分数。上图:sklearn 分类报告。下图:sklearn 混淆矩阵。
还不是很有效。它犯的一些错误很容易理解。它经常混淆“不”和“去”,“关”和“上”。这些单词有非常相似的元音,所以可能会混淆。有些错误不太明显:它真的认为‘右’是‘左’16 次吗?也许是结尾的 t?此图还说明了如果将所有的“额外”类合并到一个“未知”类中(大约 500 个样本对大约 8300 个样本),这些类是多么不平衡。我通过在 Keras fit 函数中使用“class_weight”参数来处理这个问题。此参数接受将类映射到权重浮点的字典,并通过更严厉地惩罚未充分代表的类的错误分类来“重新平衡”训练集。更好地平衡训练集的另一种方法是通过从每个类中创建等量样本的批次。我假设人们会在随后的时代使用剩余的“未知”样本,但我自己没有尝试过。我不知道哪种平衡技巧最好。在对 Conv1D 模型进行了一些调整后,我在 Kaggle 排行榜上的得分达到了 83%左右。还不是很好,但现在我不想在这个模型上做更多的调整,而是想尝试一些其他的网络架构。
## 雷斯内特
残差神经网络,或 [ResNet](/an-overview-of-resnet-and-its-variants-5281e2f56035) ,基本上是一个有快捷方式的深度卷积神经网络。每隔几层,就有一个身份连接回到上一层。这些快捷连接被认为有助于网络更好地推广。这绝对有效:我不再需要任何辍学层。实际情况是,网络深度默认使用尽可能多的快捷连接。这使网络保持较小,因此有助于泛化。快捷方式之间的剩余层仅在需要时更新。

具有两个快捷连接的 ResNet 模型的小子集
具有 BatchNormalization 和 ReLu activation 的两个 Conv2D 层的块由一个连接层分隔,该连接层将先前的连接层添加到块的输出中。然后,每三个这样的模块进一步由跨距为 2 的 Conv2D 层分隔,以便学习更大规模的特征。在 Keras 中,我是这样实现的:
这个模型表现得非常好。它在验证集上达到了近 98%的准确率,在 kaggle 排行榜上达到了 85%。验证集和测试集之间的这种差异令人担忧,我将在下面更深入地讨论这一点,但它与测试集有关,测试集包含许多在训练集中没有给我们的单词。所谓的*未知的未知*。我研究的下一个改进模型的架构是递归神经网络。
## 返回 RNN
声谱图的一个轴代表声音文件的频率,另一个轴代表时间维度。在卷积神经网络中,不能将这两个维度视为相等,这是有道理的。递归神经网络或 RNNs 用于建模序列,例如预测接下来应该发生什么。在我们的例子中,它们可以用来记录先发生了什么,以及之后发生了什么,这是 ResNet 所不能做到的。我的意思是,一个正常的卷积网络可能会认为“yes”和“yes”是同一个词,因为它不知道声音的顺序。我试图做的是添加一个 RNN 层到我的表现非常好的 ResNet 的末尾,并对其进行处理。正如您在上面的代码中看到的,有一个 MaxPooling 层和两个跨距为 2 的 Conv2D 层,它们将网络末端的输入大小从(61,75,1)减少到(8,10,128)。这里的第一维(8)表示时间维,但是 rnn 采用 3D 输入,而(包括批处理)我们的 ResNet 采用 4D。因此,从最终的剩余+快捷方式层到 RNN 层,我们必须使用 Keras 的整形层。你可以这样做:
我们将第二维和第三维组合成一个大向量,产生 8 个时间点,1280 个数字描述卷积的频率分布。需要时间分布式包装层来使 RNN 层(在这种情况下是 LSTM)使用 8 个时间行作为顺序输入。经过几次调整和迭代,一个组合的 ResNet RNN 模型在 Kaggle 排行榜上给出了 87%的准确率。我尽了最大努力,在 1300 名左右中排在第 200 名左右。我认为这对于我的第一个 Kaggle 项目来说相当不错。但我仍然想尝试一些东西,学习更多的深度学习技巧。
## 连接主义时间分类(语音到文本)
在 Kaggle 挑战赛提交截止日期前后,吴恩达 Coursera [深度学习 python 课程](https://www.coursera.org/learn/nlp-sequence-models/home/welcome)关于序列模型的最终模块向公众开放。我在上面的组合模型中应用了一些 RNN 层,但是我并不知道它是如何工作的,所以我参加了这个课程来学习所有关于 RNNs 的知识。这篇文章不是对这门课的回顾,但我想说的是,我会把它推荐给每个对 RNNs 的数学原理感兴趣的人。除了基本的和不太基本的 RNNs 之外,我特别感兴趣的是一种语音转文本的方法,Andrew 提到了这种方法,但没有真正深入研究,这种方法被称为 Connectionist 时态分类,或 CTC。我对此感到非常兴奋,因为我脑海中有一个关于语音到文本的项目的想法已经有一段时间了,但它仍然非常抽象,我根本不知道从哪里开始。但是现在有人给了我一个非常具体的开始。
语音转文本模型以声谱图(或原始 wav 数据)为输入,输出字母或单词。这样一个网络需要做的是识别每个 RNN 输入中所谓的*音素*,将它们翻译成字母,并将字母组合成正确的单词。

因此,对于英语口语单词,您希望网络输出每个时间点长度为 28(字母表加上“空格”和“空白”)的单热点向量,然后以某种方式确定预测的“错误”程度,以便我们可以进行反向预测。这就是反恐委员会的工作。例如,它以输出“_ _ _ Y _ EEEE _ SSS _ _”为例,通过折叠多个字母的连接并忽略不同字母之间的“空白”来将其简化为“是”。如果输出在两个相同的字母(“E _ E”)之间给出一个“空白”,则认为它是两个单独的字母。“空白”不应该与“空格”混淆,但我不必担心这一点,因为我所有的输入都是单个单词。
使用 Keras,您可以使用后端函数 *ctc_batch_cost()* 来实现,但它需要四个参数(y_true、y_pred、input_length 和 label_length),而不是只有 y_true 和 y_pred,这意味着您不能将它用作常规的损失函数,并将其插入到您的编译语句中。我在 github 上找到了一个 [repo,它是百度的 DeepSpeech 模型的一个工作 Keras 实现,使用了 CTC,并取走了我自己需要的部分。](https://github.com/mlrobsmt/KerasDeepSpeech)
这里 *y_pred* 是长度为 28 (output_dim)的独热码向量的 RNN 的时间分布输出。与其他三个参数一起,它被提供给包装在 Lambda 层中的 *ctc_batch_cost* 函数,然后我创建了一个用于训练的模型(“*模型”*)和一个用于测试/验证的模型(“*测试 _ 模型”*),其中不包括 Lambda 层。当你运行*模式时。Compile()* 它需要一个损失函数,所以你给它一个以 *y_true* 和 *y_pred* 为参数,简单返回 *y_pred* 的哑函数。然后,训练你给的模型*。fit()* 函数一列四个输入:
1. 训练集,
2. 具有标签的字母索引的数组 *y_true* ,用“空白”索引填充到所有样本的共同长度([25,5,19,27,27,27,27,27]表示“是”),
3. 一个一维数组 *input_length* ,包含每个样本的“字母表”长度(len(Y_train) 28 作为一个向量),以及
4. 一维数组 *label_length* 的长度是 *y_true* vectors(对我来说是 8)len(Y _ train)的倍。
*输出*的*参数。fit()* 函数采用长度为 len(Y_train)的零数组,我们的虚拟损失函数对此不做任何处理。我认为我能做到这一点是非常令人兴奋的。使用该模型的原始输出(上游层是 Conv1D 和两个双向 LSTMs)在 Kaggle LB 上达到 83%的分数,但是这是在没有尝试对预测的单词运行某种拼写检查或语言模型的情况下。我看到了很多“*叶*”的和“ *riget* ”的等等。我将更多地使用它,看看我还能从中得到什么。
## 离群点检测
正如我在上面提到的,测试集包含了大量的单词和声音,这些都不在训练集中。这意味着为了得到一个真正好的分数,你的模型必须学习未知的未知的特征。从我在截止日期后的 Kaggle 论坛上读到的内容来看,大多数顶尖的得分者使用了大量的特征工程来创造更多的“未知”样本。例如,您可以剪切和粘贴单词片段来创建新单词,或者您可以使用音高移动或反转样本。我尝试了一下,但不太成功。另一件事,我看到许多得分最高的人做的是在测试集上的无监督训练,以了解什么样的特征存在于那里,而不是在训练集中。这似乎给了分数很大的提高,但对我来说感觉有点像作弊。我自己花了相当多的时间尝试不同形式的异常值或异常检测。这意味着试图让网络拒绝它以前没有听到过的声音,并将它们放在“未知”类别中。我尝试在 10 个主要类别上训练自动编码器和变型自动编码器,但这些模型在解码看不见的光谱图方面总是保持同样好,就像它们在解码我训练的输入时一样。我尝试过[开集识别](https://arxiv.org/pdf/1511.06233.pdf),但是在尝试了几个星期去理解他们到底是怎么做的之后,我放弃了。最后,如果这些技术能改善我的模型就好了,但如果排行榜上没有一个超级分数,学习这些确实给了我很多新的知识和经验,所以我很高兴我做到了。
## 结论
我离开大学已经 15 年了。在这么短的时间内又学到这么多东西,真是太有趣了。除了更好地了解如何进行语音识别之外,我还学到了更多关于 Kaggle 挑战以及如何获得高分的知识。当我开始的时候,我认为如果我发现了一些其他参与者没有的技巧,那么我会比他们得分更高,但现在我更好地认识到了高分真正需要什么。那些家伙肯定比我知道更多的把戏!
*最初发表于*[](https://dinantdatascientist.blogspot.dk/2018/02/kaggle-tensorflow-speech-recognition.html)**。**
**ResNet 和 CTC 模型在*[*https://github.com/chrisdinant/speech*](https://github.com/chrisdinant/speech)的实施*
# Kaggle 泰坦尼克号:机器学习模型(前 7%)
> 原文:<https://towardsdatascience.com/kaggle-titanic-machine-learning-model-top-7-fa4523b7c40?source=collection_archive---------5----------------------->

这场 K [aggle 竞赛](https://www.kaggle.com/c/titanic)的目的是根据给定的特征预测给定乘客的生死。这个机器学习模型是使用 scikit-learn 和 fastai 库构建的(感谢[杰里米·霍华德](https://www.linkedin.com/authwall?trk=gf&trkInfo=AQH1NsDUgQbJAwAAAWbiRqbIwGLhcSbGKZ7zOi_usSDEtKTqOv4iVuPDGE3g5jP79Eg3F9l5aIlaLaKsUjjhCllbKY2z1XAvTFQ9UMKh9LR9PJcCiaVsqANQ3ttHlLm60UCyUMU=&originalReferer=https://www.google.co.in/&sessionRedirect=https%3A%2F%2Fwww.linkedin.com%2Fin%2Fhowardjeremy)和[瑞秋·托马斯](https://www.linkedin.com/in/rachel-thomas-942a7923))。对该模型使用集成技术(RandomForestClassifer 算法)。我尝试了其他算法,如逻辑回归,梯度推进分类器与不同的超参数。但是我用这个 RandomFortestClassifer 得到了更好的结果(前 7%)。
完整代码的 Github 链接是[这里是](https://github.com/Msanjayds/Kaggle_Titanic-Survival-Challenge/blob/master/Titanic_Final_to_git.ipynb)。
下面是测试数据集中提供的功能。
* 乘客身份证:发给船上每个乘客的身份证
* 乘客舱:乘客舱。它有三个可能的值:1、2、3(一等、二等和三等)
* 乘客的姓名
* 性
* 年龄
* SibSp:与乘客同行的兄弟姐妹和配偶的数量
* Parch:与乘客同行的父母和子女人数
* 机票号码
* 票价
* 机舱号
* 登船。这描述了泰坦尼克号上三个可能的区域。三个可能的值 S,C,Q
**探索性数据分析**:以下是我在数据分析过程中的发现,以及我处理这些发现的方法。
从下表中我们可以看到,在测试数据集中的 891 个观察值中,只有 714 个记录填充了年龄,即大约 177 个值缺失。我们需要用一些值来估算,我们稍后会看到。

Numerical feature statistics — we can see the number of missing/non-missing
下面的图表显示,男性乘客死亡人数多于女性(性别歧视:-))

Visualization of Survival based on the Gender
我们还可以看到 20 到 40 岁的男性比年长的男性存活的更多,如绿色直方图所示。另一方面,女性比男性活得更久,在所有年龄组都相对较好。

Correlation of Age with the Survival
当我们绘制幸存/死亡乘客的票价时,我们可以看到票价较便宜的乘客更有可能死亡。也就是说,拥有昂贵车票(可能是更重要的社会地位)的乘客似乎被优先营救。x 轴:票价,Y 轴:乘客人数。

Ticket Fare vs Survival rate
下面是一张图,显示了年龄和费用与存活率的关系。x 轴=年龄,Y 轴=车票 _ 票价,绿点=存活,红点=死亡
x=0 和 x=10 之间的小绿点:幸存的孩子
x=10 & x=45 之间的小红点:死亡的成年人(来自下层阶级)
x=20 & x=45 之间的大绿点:票价较高的成年人幸存下来。

> **现在是特征工程:**
我将训练和测试数据结合起来,对两者都进行了转换。完成后,我分离测试和训练数据,用测试数据训练模型,用验证集(训练数据的小子集)验证模型,评估和调整参数。最后在完整的训练数据上训练模型。然后在测试数据上做预测,提交给 Kaggle。
**处理家庭:**根据家庭的大小创建了一些新的特性(家庭大小,单个,小家庭,大家庭)。这是基于一个假设,即大家庭通常被组织在一起并得到支持,因此他们比那些独自旅行的人更有可能获救。

**Process abowed**:用训练集中最频繁的一个“S”填充缺失的装载,并使用 get_dummies 方法对电子标记列进行一键编码。

**Process Cabin:** 用 U(表示未知)替换缺失的 cabinet,取 cabinet 的第一个字母,用 get_dummies 方法进行虚拟编码。

**从名称**中提取乘客标题:通过解析名称并将标题映射到定义的类别,创建了一个新功能“标题”。

**流程年龄**:正如我们之前看到的,年龄变量有 177 个缺失值,这在 891 个值中是一个巨大的数字。仅仅用平均/中间年龄来代替可能不是最佳解决方案,因为年龄可能因乘客的群体和类别而不同。头衔也有助于计算年龄。首先,我取了按性别、乘客、阶级和头衔分组的平均年龄。

然后,对于所有缺少年龄的记录,基于它们的性别、标题和类别,我们指定年龄。如果完全没有“头衔”,只根据性别和阶级来指定年龄。

**流程名称**:删除 Name 列,在 Title 列做一个虚拟变量编码。标题列值编码后,数据将如下所示。

**构建和训练模型:**正如我前面提到的,我将训练集分成训练和验证集(60 个用于验证),并使用了 RandomForestClassifier。最初,我将树的数量(n_estimators)设置为 20,最终设置为 180,并将分割节点所需的最小样本数设置为 3(min_samples_leaf)。并且还使用 max_features 作为 0.5(在寻找最佳分割时随机考虑 50%的特征)。利用这些参数,该模型在测试数据上获得了 **0.933** 的分数。

**模型评估**:在验证集上达到 86.67 左右,下面是混淆矩阵和分类报告。

**特性重要性检查**:基于树的评估器可以用来计算特性的重要性,之后我们可以丢弃不相关的特性。以下是最重要的十大特性列表。

从上表中我们可以看出,头衔、性别、票价、乘客身份、年龄、阶级和家庭规模是更重要的特征。不确定乘客 Id 如何影响预测。下面是相同的图形表示。

最后,为了最后一次对整个训练数据再次训练模型,我只包括了重要性超过 0.01 的特征。训练后我可以看到分数略有提高,这次是 **0.938** 。

然后我在测试数据上运行模型,提取预测并提交给 Kaggle。它获得了 **0.8133** 的分数,位于**前 7%。**

当然,这种模式有很大的改进和修正余地。非常感谢您的阅读,如果您有任何意见、想法和建议,请告诉我。
# 数据科学竞赛平台——ka ggle vs 天池
> 原文:<https://towardsdatascience.com/kaggle-vs-tianchi-shuju-fb31403fefeb?source=collection_archive---------5----------------------->
KDD 杯是最负盛名的年度数据挖掘比赛,与 ACM SIGKDD 知识发现和数据挖掘会议同时举行。每年都会征集提案,并根据不同的因素选择组织者。阿里云团队被选中组织 2017 年 KDD 杯。
过去,这些竞赛在 **Kaggle** 上举办,这已经成为数据科学竞赛的同义词。但出于显而易见的原因,阿里巴巴团队选择天池平台举办 2017 年的比赛。但感觉平台还没准备好,缺了很多东西。
* 参与者在下载数据集时遇到困难。必须进行多次尝试才能下载。
* 在 Kaggle 中如此受欢迎的内核在 Tiachi 上却不见了。
* 布局和导航虽然受到 Kaggle 的启发,但看起来毫无创意且半生不熟。例如比较论坛的布局:

**Kaggle**

[**Tianchi.shuju**](https://tianchi.shuju.aliyun.com/competition/new_globalForum.htm)
在天池,我们甚至看不到讨论的完整标题,而且很多讨论都是用中文进行的,而 KDD 杯比赛规则明确提到讨论应该用英文。
* 最后,但并非最不重要的是,该网站非常非常慢。速度可能很快,但一般来说很慢。*举例来说,打开* ***论坛*** *页面有时需要长达 19 分钟。*

Wait, Wait, Wait…
*例如,在论坛中提问可能需要等待 20 秒以上。*

大多数时候,响应是如此之慢,以至于打开一个页面需要很长时间。当您使用开发工具 ***检查*** 时,它的状态为**待定**(如下图*)*。

pending, pending, pending….
看看它如何发展会很有趣。但是第一印象并不好。
# 卡尔曼滤波器:一种理解融合传感器洞察力的算法
> 原文:<https://towardsdatascience.com/kalman-filter-an-algorithm-for-making-sense-from-the-insights-of-various-sensors-fused-together-ddf67597f35e?source=collection_archive---------0----------------------->
你正开车穿过隧道。GPS 信号消失了。然而,你可能想得到通知,你应该在隧道的出口。我们应该如何在隧道内驾驶一辆汽车,只给它最后的位置,它应该知道它现在在哪里?

# 关于传感器的简短说明
全球定位系统接收器通过分析它们从卫星接收的信号来计算它们的位置。这些信号不会穿过固体。车辆中的 GPS 可能有一个外部天线,或者它可以从空气中拾取足够的反射信号来工作。如果隧道中的信号太弱,GPS 可能仍会工作,这取决于其质量和功能。

The table explains the pros and cons of each some of the sensors.
> 一种合并车辆传感器的方法可以计算位置。
## 来自传感器的测量值
假设我们在隧道入口,并且我们以 50 公里/小时的速度行驶,那么导航确实可以精确地计算出 1 分钟(t =时间)后我们将在哪里(x =位置)。
两个传感器都有随机误差,传输路径有干扰,CAN 总线或者模数转换器的分辨率都会造成简单语句“速度”的很多不准确。
例如,速度信号看起来像这样:

The Velocity is considered to be with a variance on both the axes. ([image source](https://github.com/sharathsrini/Self-Driving-Car/blob/master/Kalman_Filter.ipynb))
平均而言,测得的速度中加入了一些“噪音”,这使它们与地面的真实情况有所不同。如果计算确定的速度的直方图,可以看到确定的值近似服从正态分布。

This is the histogram representation of the velocity measurements. ([image-source](https://github.com/sharathsrini/Self-Driving-Car/blob/master/Kalman_Filter.ipynb))
所以有一个,而且真的只有一个,最大值(单峰)和价差(方差)。如果是这种情况,我们仍然可以用一个技巧很好地计算。
# **一维卡尔曼滤波的思想**
我想先解释一下只有一维的卡尔曼滤波器(根据 [Rudolf Emil Kalman](http://en.wikipedia.org/wiki/Rudolf_E._Kalman) )的想法。以下解释借用了*巴斯蒂安·特龙教授*的[*Udacity CS373* 课程](https://www.udacity.com/course/cs373)。
## **计算噪声有助于**
为了在测量噪声的情况下最佳地执行计算,必须知道*“强度”*参数。这个“*有多强”*是用正态分布的方差来表示的。对于正在使用的传感器,这被确定一次,然后仅使用该“不确定性”进行计算。
在下文中,不再用绝对值来计算,而是用正态分布的平均值(μ)和方差σ来计算。正态分布的平均值是我们想要计算的值。方差表示置信水平。正态分布越窄(低方差),传感器对测量结果越有信心。
> 精确测量 100%的传感器的方差为σ = 0(不存在)。
我们假设 GPS 信号刚刚丢失,导航系统完全不清楚你在哪里。方差高,对应的曲线确实平坦。有一个不确定性。
方差= 20 且均值= 0 的正态分布

The Uncertainty is High, as the variance is in a large magnitude.([image-source](https://github.com/sharathsrini/Self-Driving-Car/blob/master/Kalman_Filter.ipynb))
现在来自传感器的速度测量值也是“不准确的”,具有适当的方差。这两种不确定性现在必须联系在一起。借助于贝叶斯规则,执行两个高斯函数的相加。Thrun 教授在 Udacity CS373 课程中非常清楚地解释了这一点。
这两条信息(一条用于当前位置,一条用于传感器的测量不确定性)实际上给出了更好的结果!。正态分布越窄,结果越有把握。运动恶化了估计。
当然,车辆也会移动,这不利地影响了位置确定的精度。例如,传感器可以确定车轮的旋转,并假设车轮的半径,还可以得出行驶距离的结论,但这总是有些不准确。这种运动的不精确性也可以用正态分布来描述。这一次,使用当前估计值进行计算的方式略有不同,因为“运动”也可以称为“预测”。你可以在计算后估计,你下一次(测量)时间会在哪里。
在我们的例子中,μ就是 v * dt,它是我们在计算时间内走过的距离。
一个简单的实现是:
def predict(mean1, var1, mean2, var2):
new_mean = mean1 +mean2
new_var = var1 + var2
return [new_mean, new_var]
# 测量和更新:卡尔曼滤波器
卡尔曼滤波器只是反复计算这两个函数。

The filter loop that goes on and on.
过滤器循环覆盖结果的平均值和方差。只要读数不偏离预测值太多,过滤器将始终确信其位置。
> *一项新的测量提高了估计值*
> 由于测量值(在更新中)与预测值(通过预测)相对较好地吻合,所以滤波器逐步改进以确保它是正确的(正态分布变得更窄和更高),即使值是有噪声的。
def update(mean1, var1, mean2, var2):
sum = var1+var2
pr_s = mean1var2 + mean2var1
print(pr_s)
new_mean =1/(sum) * pr_s
product = var1*var2
new_var = product/sum
return [new_mean, new_var]
> 没有矩阵,你只能在一个维度上计数,这不足以…
# 多维卡尔曼滤波器

The Picture Illustrates the Kalman Filter ‘s Predition step in various time-stages. ([Image Source](https://www.wikiwand.com/en/Kalman_filter))
我想用一辆带导航装置的汽车进入隧道的例子来再次解释这个过程。最后已知的位置是在失去 GPS 信号之前。之后,只有车辆的速度信息(车轮速度和横摆率)可作为正常分布的噪声测量变量。从这里开始,计算速度。
我们现在转向更复杂的部分。因此,提到的将平均值和方差相乘或相加的过程仅在一维情况下有效。在多维问题中,我们将在一个矩阵中得到均值和方差,所有的运算都在这个矩阵中进行。也就是说,当你想要测量的状态只需要一个变量就可以完全描述。开始时提到的确定车辆在隧道中位置的例子,已经不能完全用变量来描述了。虽然只对位置感兴趣,但这已经是平面上的二维问题了。另外,只能测速度,不能直接测位置。这导致卡尔曼滤波器具有以下状态变量。

The state matrix consists of position and velocity in the x and y coordinates.
# 初始条件/初始化
## 系统状态 X
开始时,我们必须初始化一个初始状态。在一维情况下,状态是一个矢量。

如果什么都不知道,你可以简单地在这里输入零。如果一些边界条件是已知的,它们可以被传送给过滤器。以下协方差矩阵的选择控制滤波器收敛到正确(测量)值的速度
## 协方差矩阵 P
必须给初始状态一个不确定性。在一维情况下,方差是一个向量,但现在是所有状态的不确定性矩阵。以下是所有四种状态的示例。

The covariance matrix consists of uncertainty in the position and the velocity in the x and y coordinates.
该矩阵最有可能在过滤过程中被改变。它在预测和校正步骤中都被改变。可以基于传感器精度来初始化矩阵。如果传感器非常精确,这里应该使用小值。如果传感器相对不精确,这里应该使用较大的值,以允许滤波器相对快速地收敛。如果传感器非常精确,这里应该使用小值。
## 动态矩阵 A
然而,过滤器的核心是下面的定义,我们应该在充分理解物理环境的情况下建立这个定义。这对于很多真题来说并不容易。对于我们这个简单的例子(面内运动),其背后的物理原理来自于平滑运动。对于上面所示的状态矩阵,矩阵符号中的动态如下:

The Dynamic matrix helps us in defining the equations for predicting the Vehicle Motion Model.
这说明了状态向量从一个计算步骤移动到下一个步骤的“位置”。在我们的例子中,这种动态模型是“恒速”模型,因为它假设速度在滤波器的计算步骤( *dt* )中保持恒定。

This is the prediction step for the State matrix.
这只是反映了匀速运动的物理关系。更高的形式是恒定加速度模型,它是一个 6-D 滤波器,仍然包括状态向量中的加速度。原则上,这里可以指定其他动力学。

[*(Image Source)*](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSjDfiW3kwdlflT4g4Y-ROtNavKqMiq03ge-sv2QgtjIeVHCeju)
## 过程噪声协方差矩阵 Q
由于车辆的运动(在叠加的正态分布噪声的意义上)也可能受到干扰,这就是引入过程噪声协方差矩阵的地方。这个矩阵告诉我们滤波器,以及系统状态如何从一个步骤“跳到”下一个步骤。想象一下自动驾驶的车辆。它可以被一阵风或道路颠簸扰乱,这就产生了力的效应。驾驶员的速度变化也是作用在车辆上的加速度。如果加速度现在影响系统状态,则其物理相关性为 q。该矩阵是一个包含以下元素的协方差矩阵:

The Process Noise Co-variance matrix consist of the errors caused in the process.
通过放置向量,然后乘以加速度的假设标准偏差,很容易计算出来。

The Equations to set the Q matrix appropriately.
## 控制矩阵 B 和控制输入 u
外部控制变量(如:转向、制动、加速等。)是可能的。u 矩阵将包含系统的机器人输入,可以是瞬时加速度或系统从 IMU 或里程表传感器行进的距离。
## 测量矩阵 H
还必须告诉滤波器测量的是什么以及它与状态向量的关系。在车辆的例子中,汽车进入隧道,在第一点仅测量位置,仅测量速度!这些值可以用系数 1.0 直接测量(即速度直接用正确的单位测量),这就是为什么在中只有 1.0 被设置到适当的位置。

The H-matrix.
> 如果传感器以不同的单位或尺寸进行测量,测量矩阵中的关系必须映射到公式中。
## 测量噪声协方差矩阵 R
与一维情况下的方差一样,测量不确定性也必须在这里说明。

这种测量不确定性表明人们对传感器测量值的信任程度。因为我们测量位置和速度,这是一个 2 × 2 矩阵。如果传感器非常精确,这里应该使用小值。如果传感器相对不准确,这里应该使用较大的值。
## 单位矩阵 I
最后但并非最不重要的是,一个单位矩阵是必要的,这将用于简化卡尔曼方程。
# 过滤步骤预测/预测
卡尔曼滤波器的这一部分现在敢于预测系统未来的状态。另外,在一定条件下,可以用它计算出一个不可测量的状态!太不可思议了,但这正是我们所需要的。我们无法测量车辆的位置,因为导航设备的 GPS 在隧道中没有接收信号。然而,通过用位置初始化状态向量并测量速度,动力学仍然被用于做出关于位置的最佳预测。

还必须重新计算协方差。在预测步骤中,系统状态的不确定性增加,正如我们在一维情况中所看到的。在多维情况下,测量不确定性增加,因此不确定性变得越来越大。
> P=A⋅P⋅A'+Q
就是这样。卡尔曼滤波器对未来或即将到来的时间步中的预期系统状态做出了预测声明。滤波器现在将测量/校正并检查系统状态的预测是否与新的测量值很好地吻合。
被滤波器选择为较小的协方差说明了确定性,如果不是,那么一定有问题,这使得滤波器更加不确定。
# 过滤步骤测量/校正
> 注:以下数学计算不需要推导。
来自传感器的当前测量值,利用该测量值,通过使用测量值、具有测量矩阵的状态向量来获得新息因子(y)。
> y=Z−(H⋅x)
然后,查看可以进一步计算的方差。为此,不确定度和测量矩阵和测量不确定度是必需的。
> s=(h⋅p⋅h′+r)
这决定了所谓的卡尔曼增益。它说明了应该更熟悉读数还是系统动力学。
> k =p⋅·h
> 如果读数(测量值)与预测的系统状态匹配,卡尔曼增益将降低。如果测量值与此相反,矩阵 K 的元素会变大。
该信息现在用于更新系统状态。
> x = x + ( K⋅ y)
并且还为即将到来的预测步骤确定了新的协方差。
> p = p-(k⋅·惠普)
也就是说,
> ⋅·p
现在回到步预测。图形看起来是这样的:

The Kalman filter could be understood as a loop ([image source](http://www.argos-system.org/manual/3-location/32_principle.htm))
> 只要有测量值输入,该过滤器就会永久运行。它也可以是开环的,因此如果没有可用的测量值,则只执行预测步骤。然后不确定性越来越大。
# 工作中的过滤器
当我们驶入隧道时,GPS 会记录下我们最后知道的位置。卡尔曼滤波器仍然可以预测车辆的位置,尽管它不是一直被测量。
现在假设通过 [CAN 总线](https://www.wikiwand.com/en/CAN_bus)可获得大约每 20 米/秒的车速,6 次迭代仅需 0.1 秒。滤波器收敛相对较快,这取决于初始条件的选择。例如,在 100 次迭代(相当于车辆上的 2s)之后,方差已经非常低,因此滤波器对其估计和更新状态有信心。我实现的[线性卡尔曼滤波器](https://github.com/sharathsrini/Self-Driving-Car/blob/master/Kalman_Filter.ipynb)可以在这里找到。结果是:

The First Image depicts the Estimated Value of each estimated value of the velocity in the X and Y co-ordinates. The Second Image Illustrates the Kalman gain for each of the parameter in the State Matrix. The Uncertainty Matrix containing the variance in each parameter of the State Matrix. ([https://github.com/sharathsrini/Self-Driving-Car/blob/master/Kalman_Filter.ipynb](https://github.com/sharathsrini/Self-Driving-Car/blob/master/Kalman_Filter.ipynb))

The First Image Plots the position of the vehicle in both X and Y Coordinate. The Second and Third Image Tells us the relationship between the estimated and the actual velocity in the X and Y Co-ordinates. ([https://github.com/sharathsrini/Self-Driving-Car/blob/master/Kalman_Filter.ipynb](https://github.com/sharathsrini/Self-Driving-Car/blob/master/Kalman_Filter.ipynb))
# 卡尔曼滤波器的 Python 实现
def Kalman_Filter() :
for n in range(measurements):
x = Ax+Bu[n]
P = APA.T + Q
Measurement Update (Correction)
===============================
Compute the Kalman Gain
S = H*P*H.T + R
K = (P*H.T) * np.linalg.pinv(S)# Update the estimate via z
Z = mx[n]
y = Z — (H*x) # Innovation or Residual
x = x + (K*y)
Update the error covariance
P = (I — (K*H))*P
# 滤波器设计:我如何选择 Q 和 R?
总的来说,不管数值有多大,而是比例有多大。如果选择的值大十倍,这几乎不会影响滤波器。**价值观的比例至关重要。**正确的选择将直接关系到滤波器的性能,并构成滤波器设计的基本问题。
这个非此即彼的问题只能在特定应用的基础上决定。在某些情况下:
1. 我们只想为相对稳定的过程过滤测量不佳的传感器。例如,我们可以实现卡尔曼滤波器来优化火箭炉或化学炉中温度控制器。
2. 我们还想合并几个传感器,并应保持动态。因此,应该选择矩阵。当然,可选地,过滤器可以被设计成在操作期间自动适应。
## 卡尔曼滤波器与递归最小二乘法有何不同?

flowchart of adaptive filtering techniques [(image)](https://ai2-s2-public.s3.amazonaws.com/figures/2017-08-08/ae261153face27a228b0ff2697919a3311e3962d/1-Figure1-1.png).
**卡尔曼滤波器**作用于用于线性和时变或时不变系统的预测校正模型。预测模型涉及实际系统和过程噪声。更新模型包括用观测噪声更新预测值或估计值。基于 RLS 算法计算卡尔曼增益,以便在更少的时间内达到最优值。
**递归最小二乘法**基于加权最小二乘法,其中考虑了以前的值以确定未来值。每个权重被指数分配给实际系统的每个先前值。权重基于内存递归更新。
**显著差异:**

Computational Time complexity of RLS

Computational Time complexity of Kalman Filter
1. RLS 比卡尔曼滤波器快。
2. 卡尔曼滤波器精度高。
3. 卡尔曼滤波器是基于状态空间模型的,我们需要对整个系统建模以达到最优值。
## 卡尔曼滤波器和多项式回归

examples of polynomial regression([1](https://www.statsdirect.com/help/resources/images/polynomialcurve.gif))([2](https://www.google.co.in/search?q=polynomial+regression&rlz=1C1CHBF_enIN785IN785&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjn7ZXc7qzaAhUFRo8KHaqPDyEQ_AUICygC&biw=1366&bih=672#imgrc=kCBKN7NVSLkg-M:))
多项式回归是一种函数逼近的方法。我们有一个数据集,我们必须确定函数关系,这通常通过估计概率密度 p(z|x)来表示。在假设这个概率是高斯分布的情况下,我们得到最小二乘解作为最大似然估计量。
由于线性动态系统是状态空间模型,我们假设我们观察到的数据是通过应用线性变换产生的。我们得到的模型是一个时间序列的概率。然后,该过程预测时间序列的下一个值。
> 多项式回归做函数逼近,卡尔曼滤波做时间序列预测。
时间序列预测是函数逼近的特例。这两个模型都是基于他们观察到的数据的不同假设而建模的。
# 结论
卡尔曼滤波器相对快速且易于实现,并且在某些条件下为正态分布的噪声传感器值提供了条件的最佳估计。卡尔曼先生对他的算法深信不疑,以至于他能够启发美国宇航局的一位友好的工程师。因此,这个过滤器第一次帮助了登月的阿波罗导航计算机。
## 有用的链接:

(I[mage source](http://www.columbia.edu/cu/lweb/img/assets/3841/reference.logo.jpg))
1. [罗杰·拉布](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python)的 Jupyter 笔记本收藏。
2. 米歇尔·范·比森的惊人视频系列
3. [画面中的卡尔曼滤波器](http://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/)。
4. Vivek Yadav 的[博文](/kalman-filter-intuition-and-discrete-case-derivation-2188f789ec3a)。
5. 由[大卫·西尔弗](https://medium.com/u/8190c86ea791?source=post_page-----ddf67597f35e--------------------------------)撰写的[惊人帖子](https://medium.com/self-driving-cars/all-about-kalman-filters-8924abe3aa88)。
# 卡尔曼滤波面试
> 原文:<https://towardsdatascience.com/kalman-filter-interview-bdc39f3e6cf3?source=collection_archive---------1----------------------->
我目前进入了我的自动驾驶汽车 Nanodegree 的第二学期。最近,我遇到了我的一位同事 Larry,他是一名年轻的开发人员,非常兴奋能够成为自动驾驶汽车行业的一员。他问我对卡尔曼滤波的理解。对话开始了。
拉里:什么是卡尔曼滤波器?
我:卡尔曼滤波器是一种帮助预测数值的工具。
拉里:那太酷了!意味着它是某种占星家?
我:嗯,不完全是。这是一个迭代数学过程,使用一组等式和连续数据输入来快速估计我们感兴趣的与对象**相关的值。基本上都是速算!**
拉里:我的数学没那么好!也许这对我来说听起来有点荒谬。你能继续吗?我:首先,卡尔曼滤波器适用于高斯分布或正态分布。
拉里:正态分布?
Me:在一个连续的图形中,数据可以以不同的方式展开:要么向左展开,要么向右展开,要么杂乱无章地向上展开。

Figure 1\. Example of left skewed and right skewed distribution ([image source](https://en.wikivet.net/Data_description))
但是在许多情况下,数据趋向于围绕一个中心值,没有左右偏差,产生的分布称为正态分布、高斯分布或钟形曲线。

Figure 2\. Example of a normal distribution, looks like a bell hence bell curve. ([image source](https://en.wikivet.net/Data_description))
拉里:知道了!正如你指出的,这是一条连续曲线,而不是离散值。我怎么知道掷骰子得到 5 的概率?我:嗯,好问题,但是为了表示像得到骰子的概率这样的分布,我们使用二项式分布,因为它是离散值的。在正态分布中,你需要定义一个范围。说一下,4.5 到 5.5 厘米之间的降雨概率是多少。在这种情况下,我们有一个正态分布,我们标记这些点,并计算这些点下的面积,这就给出了概率。
拉里:哦!所以完全图的面积是 1,因为概率的最大值是 1?
Me:完全正确,另外在这种分布的情况下,均值、中位数、众数都是相等的。
拉里:但是你没有用数学术语来表示高斯?
我:所以,要定义高斯,我们基本上有两样东西——均值和方差。
均值( *μ)* 你显然知道,方差(σ)基本上讲的是数字散开了多少,离均值有多远。标准差(σ)就是方差(σ)的平方根,由公式给出:

拉里:那么高斯和卡尔曼滤波器有什么关系呢?
我:嗯!卡尔曼滤波器中的高斯表示预测值,在我们的预测中有噪声/误差/不确定性,通常称为方差。预测值以平均值为中心,高斯宽度表示我们的值的不确定性。基本上,它告诉我们有多少把握某个值是真实的。高斯曲线的宽度越大,表示不确定性越大。
拉里:哦!你在这里玩了一点多态性游戏。你之前提到这是一个迭代的过程?我:是的,这基本上是一个两步的过程。预测
2。更新
在预测中,我们只是根据初始值预测称为**预测值**的新值,然后根据系统中存在的各种过程噪声预测我们预测中的不确定性/误差/方差。
在更新中,我们考虑了来自设备的实际测量值,我们称之为**测量值**。这里,我们计算预测值和测量值之间的差异,然后通过计算卡尔曼增益来决定保留哪个值。然后,我们基于由卡尔曼增益做出的决定来计算新的值和新的不确定性/误差/方差。这些计算值将最终成为我们的卡尔曼滤波器在迭代 1 中所做的预测。
更新步骤的输出再次馈入预测状态,循环继续,直到我们的预测值和实际值之间的误差/不确定性趋于零。
赖瑞:嗯,那真是太快了。你能以任何例子或流程图来解释吗?
我:好的,那么从现在开始就按照这些记法来:
> x ->均值
> P - >方差

Figure 3\. A Rough Flowchart for Kalman Filter
拉里:似乎很直观!但是卡尔曼增益是什么鬼?
Me:卡尔曼增益是决定预测值和测量值应占多大权重的参数。它是决定我们的实际值是接近预测值还是实测值的参数。
拉里:但是它怎么知道如何相信预测值或实际值呢?
我:它检查不确定性/错误我的朋友。
> K =预测误差/(预测误差+测量误差)
K 的值范围从 0 到 1。如果我们有一个很大的测量误差,K 更接近 0,这意味着我们的预测值接近实际值。如果我们的预测误差很大,K 更接近 1,这意味着我们的测量值更接近实际值。
拉里:好的,同意!我现在开始兴奋了。你现在能详细说明这些方程式吗?
我:当然。对于预测和更新步骤,我会以不同的方式写下来。记住这些方程是 2D 空间的。

Figure 4\. Equations for Predict Step

Figure 5\. Equations for Update Step
拉里:到了这一步,也许我们应该结束讨论了。什么是 F,B,H?还有各种各样的变量被打乱了。你说这就是卡尔曼滤波器,我理解它的功能,但为什么现在有这些未知的东西?
我:别慌。我现在将详细解释一切。
假设我们想要根据来自不同传感器的测量结果预测汽车的位置和速度。
> x ->包含位置和速度的平均状态向量。
> P - >协方差矩阵(表示误差)。

x vector
# 预测步骤
> 等式 1:
>
> **x′= f . x+b .μ+ν**
>
> x′-->预测值
> F - >状态转移矩阵
> B - >控制输入矩阵
> μ - >控制向量
> ν - >过程噪声
## f 矩阵
f 是将矩阵从一种形式转换成另一种形式所需的状态转移矩阵或适应性矩阵。例如,假设我们有一个模型,在这个模型中,我们预测了没有加速的物体的位置和速度。因此,在这种情况下,时间δt 后的新 p 和 v 为:
p′= p+vδt
v′= v
因此,在这种情况下,F 矩阵将为:

F Matrix
## b 矩阵
b 是控制输入矩阵,表示由于内部或任何外力引起的对象状态变化。例如,重力或物体的摩擦力。
## 为什么 B.μ = 0?
大多数情况下,在自动驾驶汽车的情况下,控制产品向量的值等于零,因为我们无法模拟作用于汽车上物体的外力。
## ν
这是过程中的噪音。我们添加了信道中可能存在的随机噪声,以使我们的预测稍微正确一些。
> 等式 2:
>
> **p′=fpfᵀ+q**
>
> p′-->预测协方差
> Fᵀ - >状态转移矩阵的转置
> Q - >噪声
## q 矩阵
我们假设物体改变了方向,或者加速或减速。因此,在时间δt 之后,我们的不确定性增加了 Q 倍,这也是噪声。*所以我们在技术上把噪音加到噪音里。*
所以在预测步骤中,我们得到两个预测值 x’和 P’。
# 更新步骤
> 等式 1:
>
> **y = z-h . x′**
>
> z ->实际测量
> H - >状态转移矩阵
> x′->预测值
> y - >测量值与实际值之差
## z
这是来自传感器的实际**测量值**。
## H
这又是一个状态转移矩阵。有了 H,我们可以从状态变量中丢弃我们不需要的信息。从技术上讲,H 做的工作和 F 在预测步骤中做的工作是一样的。
> 等式 2:
>
> **s =hp′hᵀ+r
> k =p′hᵀs⁻**
>
> R ->测量噪声
> K - >卡尔曼增益
> S- >总误差
> s⁻->s 的逆
## 稀有
r 表示测量中的噪声。*什么?所以那些设备不是 100%准确?*是的,在这个世界上没有什么是完美的,甚至测量价值的设备也是如此。所有设备都带有由制造商给定的 R 参数预定义值,该值在整个周期内始终保持不变。
## K
我们这里有一个复杂的等式,但它非常简单。我们正在计算卡尔曼增益 K,其公式已在前面给出。
## S
这是系统的总误差。我们预测的误差加上测量的误差。
*那么,为什么对于 K 来说如此复杂的方程在早先的公式中却是简单的呢?* 这是因为我们对于矩阵没有除法的概念。因此,我们选择首先计算总误差,然后将预测中的误差乘以总误差的倒数。
> 等式 3:
>
> x = x′+k . y
> P =(I-KH)P′
## 最后一步
这是最后一步,我们根据卡尔曼增益的计算来更新 x 和 P。注意-在 LHS 上,我们有 x 和 P,而没有 x’和 P’,因为我们现在为下一个预测步骤设置 x 和 P,因此我们需要找到它们的值。
赖瑞:嗯,这需要一些时间来消化!为了完全理解它,我必须通过哪些额外的资源?
我:宇宙感谢[米歇尔·范·比曾](https://www.youtube.com/channel/UCiGxYawhEp4QyFcX0R60YdQ)通过他的 YouTube 频道对卡尔曼滤波器的精彩贡献。观看他的视频,了解更多示例和见解。
总结所有等式:

Figure 6\. Taken from Udacity Nanodegree
> 未完待续…(商店里的 EKF 和 UKF)
给读者的提示——如果你注意到这篇文章中有任何错误,请不吝赐教或留下私信。
> 更新 1- [扩展卡尔曼滤波器](https://medium.com/@harveen54/extended-kalman-filter-43e52b16757d)
>
> 更新 2- [无味卡尔曼滤波器](https://medium.com/@harveen54/the-unscented-kalman-filter-anything-ekf-can-do-i-can-do-it-better-ce7c773cf88d)
# 卡尔曼滤波器:直觉和离散情况推导
> 原文:<https://towardsdatascience.com/kalman-filter-intuition-and-discrete-case-derivation-2188f789ec3a?source=collection_archive---------1----------------------->
# 介绍
在这篇文章中,我们将回顾离散卡尔曼滤波器的推导过程。我们将首先建立由离散动态控制的系统的方程,然后表达近似系统,计算误差协方差并计算最小化误差协方差的更新规则。由于经由卡尔曼滤波的估计涉及连续的测量和状态传播,所以在离散实现的情况下它们更容易理解。
这部分是我在石溪大学开发的高级控制系统课程的一部分。随着时间的推移,我会继续在 medium 上添加额外的注释,但如果你感兴趣,可以在这里找到完整的注释。相关概率概念的细节可以在介绍性的[课](https://mec560sbu.github.io/2016/10/14/Uncertainity/)中找到。首先,我们将讨论模型可能具有的不确定性类型。

综上所述,根据不确定性的类型,对模型的影响可能会有所不同。由于我们不知道真正的不确定性及其结构,一个安全的做法是假设潜在的误差是零中心高斯过程。这种假设没有错,因为在大多数情况下,我们至少能够使用系统识别方法近似地模拟系统。作为一个例子,考虑这样一种情况,我们得到状态和状态的导数,并对数据拟合一个线性模型。这给了我们一个近似的模型,我们可以假设任何与这个理想化模型的偏离都遵循高斯分布。
**卡尔曼滤波直觉-I**
下面的动画展示了卡尔曼滤波器背后的直觉。状态按照系统动力学传播。因为我们不知道状态的真实值,所以我们基于测量来估计它们。由于这些测量是在不连续的时间进行的,所以真实的状态可能是什么是不确定的。然而,我们知道状态必须遵循一些近似的动力学。在下面的动画中,一个点以恒定的速度移动,因为位置、速度或加速度并不精确。

由于不知道确切的位置、速度和加速度,红点的可能位置在一段时间后会发生偏离。这导致真实状态下的估计误差。当一个新的测量值到来时,我们可以使用这个信息来丢弃一些不太可能的值。在进一步描述之前,让我们澄清一些术语,
* **状态传播**是指在测量到来之前,我们允许系统跟随其动态并计算近似状态值的过程。
* **先验估计值**是在考虑新测量值之前,使用状态传播计算的值。
* **后验估计值**是考虑新测量值后计算出的值。
* 误差协方差是真实状态和估计值之间的误差。
使用上面的术语,我们在测量可用之后执行状态传播。我们使用状态传播来计算状态概率分布的先验估计。一旦有了新的度量,我们就执行贝叶斯规则更新以获得更好的概率估计。下面给出了概率贝叶斯规则。这些摘自我关于[不确定性](https://mec560sbu.github.io/2016/10/14/Uncertainity/)的高级控制系统笔记。

执行这个步骤给出了位置和速度的更好的估计,尽管事实上我们只有位置的估计。
**卡尔曼滤波直觉-II**
我们将通过另一个例子来更好地理解卡尔曼滤波器如何将一个状态的测量值和系统动态结合起来,从而对测量状态和不测量状态给出更好的估计。
卡尔曼滤波器在两个主要步骤中执行状态估计。第一步涉及系统动力学的传播,以获得状态的先验概率,一旦获得测量值,就使用贝叶斯理论更新状态变量。下面的例子说明了这一点。考虑一辆汽车以固定速度沿直线行驶的情况。此外,假设我们只有位置的测量,而没有速度。开始时,传感器只知道位置,因此机器人状态可能所在的区域如下图所示,即机器人位于位置 0,但速度可以是沿垂直线的任何值。

现在考虑机器人移动 1 秒后的场景。当我们移动了 1 s,新的位置就是之前的位置加上速度。所以匀速运动 1 秒后的概率分布就是下图的红点给出的。

假设机器人以 1 的速度移动,下一个位置估计在 1 左右。通过在该点执行第二次测量,我们得到蓝色区域作为位置估计的可能值。

因此,从系统动力学来看,我们期望新的位置在红色区域,从传感器来看,我们期望状态在蓝色区域。这两个分布之间的重叠区域非常小,我们可以说粒子的真实状态将位于这个区域。贝叶斯定理可以用来估计多元状态分布概率。沿着 x 轴和 y 轴呈现速度和位置的相应概率分布。将系统动态与状态测量相结合的过程是卡尔曼滤波器的基本原理。卡尔曼滤波器提供了良好的估计特性,在过程和测量服从高斯分布的特殊情况下是最优的。

一些更直观的解释:
* s 是反过来衡量测量误差的灵敏度矩阵。因此,如果传感器噪声过大,R 中的相应条目将会较高,通过求逆,来自该传感器的测量值将会减少。
* 如果 Q 很高,即我们不知道真实的模型,并且我们的近似模型具有大的偏差,则先验协方差估计将会很大,这具有直观意义。
* 对于线性系统,增益项 K 充当来自先验预测的状态估计和基于测量的校正之间的加权因子。
**添加**
**NIS,收敛**
**道歉**
我很抱歉从我的笔记中复制粘贴屏幕截图。我还没有想出一个好的方法来合并介质中的方程。
**参考文献:**
上面所有的截图都来自我在石溪大学开发的一门高级控制系统课程。完整课程的链接是[https://mec560sbu.github.io/](https://mec560sbu.github.io/)。
# 保持冷静,多做测试!
> 原文:<https://towardsdatascience.com/keep-calm-and-do-more-testing-42c6678707ee?source=collection_archive---------15----------------------->
作为数据科学家,我们都很熟悉流程、包或应用程序中断时会发生什么。我们饶有兴趣地深入其中,试图诊断意外错误发生在哪里。原始数据中是否发生了意想不到的事情?我们的代码没有预料到特定的输入排列吗?
由于令人沮丧的调试和重写,修复问题的过程可能从简单的调整到几天的揪头发和敲打头部。
最近,我开始接触 R 语言的测试,对它的直观性感到惊喜。当我们开发一个过程、包或应用程序时,在工作流程中增加测试并不需要花费太多的精力,但是在调试方面的好处是巨大的。

Debugging can be a nightmare — do yourself a favor and set up a testing workflow
## R 中的测试基础设施
R 中支持平滑、自动化测试的关键包是`testthat`。在您的 R 项目中,您可以通过一个简单的命令来初始化测试基础设施
devtools::use_testthat()
这个命令将在您的项目中创建一个名为`tests/testthat`的目录,您可以在其中放置执行测试的 R 脚本。
如果您的测试需要在本地设置环境变量,例如数据库凭证,您可以通过使用
usethis::edit_r_environ("project")
这将在 RStudio 中打开一个可编辑的文件,您可以在其中输入特定项目的变量名和值。
为了编写测试本身,您可以创建包含测试代码的 R 脚本,并将它们放在新的`tests/testthat`子目录中。这些脚本就像任何其他的 R 代码,除了它们使用方便的包装和为测试设计的`testthat`函数。关键函数是`testthat::test_that()` ,它有两个参数:
1. `desc`,字符串形式的测试描述,如`"Test that I have all the cat data I expect"`
2. `code`,代码执行您需要的计算,然后测试这些计算是否返回预期值,包含在`{}`中。
通常情况下,`code`会以某种形式的比较函数结束。`testthat`包含多个比较功能,例如:
* `testthat::expect_equal()`测试两个参数是否相等。
* `testthat::expect_gte()`测试第一个参数是否大于或等于第二个参数
* `testthat::expect_s3_class()`测试第一个参数是否具有第二个参数中给出的 S3 类
* `testthat::expect_true()`测试包含在参数中的语句评估为`TRUE`
一旦您编写了测试脚本,您就可以使用简单的命令`devtools::test()`自动运行所有的测试并查看性能摘要。
## 测试代码的示例
这里有几个非常简单的例子。假设我们有一个进程,它通过`mtcars`数据集中的`cyl`生成平均值`mpg`,并将其写入名为`mpg_by_cyl`的数据库表中。
现在,作为一名优秀的 R 公民,您非常了解您的`mtcars`数据集,并且您知道有三个`cyl`值,因此您会期望您的`mpg_by_cyl`数据库表有三行。因此,在您的测试脚本中,您可以从数据库中获取`mpg_by_cyl`,并且您可以编写以下简单的测试:
testthat::test_that("mpg_by_cyl has expected number of rows", {
mpg_by_cyl %>%
nrow() %>%
testthat::expect_equal(3)})
当您运行您的测试时,如果`mpg_by_cyl`确实有三行,您将从`devtools::test()`那里得到一个好的`Woot!`或者类似的鼓励话语。如果它没有像预期的那样返回,您将会被警告失败的条件,并得到一条像`Nobody`s perfect!`这样的安慰信息,然后您就会知道与`mpg_by_cyl`相关的事情没有像预期的那样发生。
这是另一个例子。假设您有一个脚本,它生成一个对象`date`,该对象包含一个表示格式`"%d %B %Y"`的最近日期的字符串,例如`"14 December 2017"`,您的流程将这个字符串写入某个数据库。您希望测试是否确实生成了有意义的日期并将其写入数据库。一种方法是检查字符串是否包含`" 20"`,这是您对任何最近日期的预期格式。因此,您可以让您的测试文件从它被写入的数据库中获取`date`,然后编写下面的测试:
testthat::test_that("date contains a recent date", {
testthat::expect_true(grepl(" 20", date))})
这将评估写入数据库的内容是否包含预期的字符串,如果失败,您就知道这个过程出错了。(当然,这并不能完全验证预期日期已被写入,但数据科学家将确定如何编写特定的测试,以提供他们所需的确定程度)。
就个人而言,我发现 R 中的测试基础设施非常直观,我建议您养成为所有的包、过程和应用程序编写测试的习惯。你可以以后再谢我!
*关于 R 中测试的更多信息,查看 Hadley Wickham 的开卷* [*这里*](http://r-pkgs.had.co.nz/tests.html) *。*
最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在[*LinkedIn*](https://www.linkedin.com/in/keith-mcnulty/)*或*[*Twitter*](https://twitter.com/dr_keithmcnulty)*上找我。*
# 保持简单!!—如何简化对梯度下降等算法的理解
> 原文:<https://towardsdatascience.com/keep-it-simple-how-to-simplify-understanding-of-algorithms-like-gradient-descent-19cb418d4276?source=collection_archive---------3----------------------->

Source: dilbert.com
当我第一次开始学习机器学习算法时,获得算法正在做什么的直觉是一项相当艰巨的任务。不仅仅是因为它很难理解所有的数学理论和符号,而且也很无聊。当我转向在线教程寻求答案时,我再次只能看到方程或高级解释,而没有浏览大多数情况下的细节。
就在那时,我的一位数据科学同事向我介绍了在 excel 表格中计算算法的概念。这对我产生了奇迹。任何新的算法,我都试着在 excel 中小规模地学习,相信我,它能奇迹般地增强你的理解,帮助你充分欣赏算法的美。
让我用一个例子来解释以上内容。
大多数数据科学算法都是优化问题,最常用的算法之一是梯度下降算法。
现在,对于初学者来说,梯度下降算法这个名字听起来可能有点吓人,但是,希望在看完这篇文章之后,这种情况会有所改变。
让我们以从住房数据预测新价格的价格为例。
给定**历史住房数据,**任务是创建一个模型,在给定房子大小的情况下预测新房子的价格。

任务——对于一栋新房子,给定它的大小(X ),它的价格(Y)是多少?
让我们从绘制历史住房数据开始:

现在,我们将使用一个简单的线性模型,其中我们在历史数据上拟合一条线,以预测给定其大小(X)的新房子的价格(Ypred)

在上图中,红线给出了给定房屋面积(X)的预测房价(Ypred)。Ypred = a+bX
蓝线给出了历史数据中的实际房价(Yactual)
Yactual 和 Ypred 之间的差异(由黄色虚线给出)是预测误差(E)
因此,我们需要找到一条具有最佳值 a、b(称为权重)的线,通过减少预测误差来最佳拟合历史数据。
因此,我们的目标是找到最优的 **a,b** ,使房价的实际值和预测值之间的误差最小化:
**误差平方和(SSE) = ∑(实际房价-预测房价)**
**= ∑** ( **Y — Ypred)**
(请注意,还有其他测量误差的方法。上交所只是其中之一。)
这就是梯度下降的由来。梯度下降是一种优化算法,它找到减少预测误差的最佳权重(a,b)。
现在让我们一步步来理解**梯度下降算法:**
**步骤 1:用随机值初始化权重(a & b)并计算误差(SSE)**
**步骤 2:计算梯度,即当权重(a & b)从其原始随机初始化值改变一个非常小的值时 SSE 的变化。这有助于我们将 a & b 的值向 SSE 最小化的方向移动。**
**步骤 3:用梯度调整权重,向 SSE 最小的最优值移动**
**步骤 4:使用新的权重进行预测,并计算新的 SSE**
**第 5 步:重复第 2 步和第 3 步,直到对权重的进一步调整没有显著减少误差**
我们现在将详细讨论每个步骤(我已经在 excel 中完成了上面的步骤,粘贴在下面)。但在此之前,我们必须将数据标准化,因为这可以加快优化过程。

**步骤 1:** 拟合直线 Ypred = a + b X,从 a 和 b 的随机值开始,计算预测误差(SSE)

**步骤 2:** 根据权重计算误差梯度
∂SSE/∂a =-(Y-YP)
∂SSE/∂b =-(Y-YP)X
这里,SSE= (Y-YP) = (Y-(a+bX))
这里有一点微积分,但仅此而已!!
∂SSE/∂a 和∂SSE/∂b 是**梯度**,它们给出了 a,b w.r.t 向 SSE 移动的方向。

**步骤 3:** 用梯度调整权重,以达到 SSE 最小的最佳值

我们需要更新 a,b 的随机值,使我们朝着最优 a,b 的方向前进。
更新规则:
①一个-∂SSE/∂a
2)-∂sse/∂b
所以,更新规则:
1. 新的 a = a-r ***∂sse/∂a =**0.45–0.01 * 3.300 = 0.42
2. 新的 b = b-r ***∂sse/∂b****=**0.75–0.01 * 1.545 = 0.73
这里,r 是学习率= 0.01,这是对权重的调整速度。
**步骤 4:** 使用新的 a 和 b 进行预测,并计算新的总 SSE

你可以看到,随着新的预测,总上证指数已经下降(0.677 至 0.553)。这意味着预测的准确性提高了。
**第 5 步:**重复第 3 步和第 4 步,直到对 a、b 的进一步调整不会显著减小误差。这时候,我们已经到达了预测精度最高的最优 a,b。
这是梯度下降算法。这种优化算法及其变体形成了许多机器学习算法的核心,如神经网络甚至深度学习。
喜欢你读的书吗?要以类似的简化方式学习其他算法,请在[www.deeplearningtrack.com](http://www.deeplearningtrack.com)注册为期 8 周的数据科学课程。通过访问 www.deeplearningtrack.com[***注册参加 2017 年 4 月 22 日的免费演示会***](http://www.deeplearningtrack.com)
***Jahnavi*** 是一位机器学习和深度学习的爱好者,在过去的 13 年里,他在美国运通领导了多个机器学习团队。她是 Deeplearningtrack 的联合创始人,这是一个在线讲师指导的数据科学培训平台—[www.deeplearningtrack.com](http://www.deeplearningtrack.com)
# 保持简单愚蠢:模型选择的教训
> 原文:<https://towardsdatascience.com/keep-it-simple-stupid-lesson-in-model-selection-5fd1193009d?source=collection_archive---------5----------------------->
我在大会上接受了一个项目,在那里我得到了乳房肿瘤的物理数据,并被要求预测肿瘤是恶性还是良性。在这次作业中,我被特别要求比较两种不同的建模技术,并解释为什么我选择了一种而不是另一种。我开始使用的两种技术是逻辑回归和随机森林。在这种情况下,逻辑回归是最终的赢家,因为随机森林最终没有提供任何更多的预测能力,并且向模拟客户端解释推论会更加困难。
**模型创建**

在对数据进行缩放后,我创建了一个热图,它显示了我在逻辑回归的特征选择上几乎没有回旋的余地。几乎所有的东西都是高度相关的,除了几个变量,使用大多数变量会弄乱结果。我最终选择了三个变量(半径平均值、凹度最差和对称性最差),并添加了一个交互项。结果如下:
***物流培训设置结果***
**准确率:** 96%
**灵敏度:** 94%
**特异性:** 97%
***逻辑测试集结果***
**准确率:** 94%
**灵敏度:** 89%
**特异性:** 97%
我对这些结果非常满意,但是需要根据作业尝试另一个模型。随机森林是我经常使用的算法,我不必担心变量之间的独立性,所以我尝试了一下。训练集的结果稍好,但测试集的结果与逻辑回归的结果相匹配:
***随机森林训练设置结果***
**准确率:** 98%
**灵敏度:** 95%
**特异性:** 99%
***随机森林测试集结果***
**准确率:** 94%
**灵敏度:** 89%
**特异性:** 96%
**型号选择**
在这种情况下,逻辑回归是明显的赢家,因为它在以下方面更简单:
**1。** **逻辑回归是一种更简单的算法**
大多数对数据科学了解有限的人都知道,线性回归就是在数据集上画一条线。那么,解释逻辑回归是相同的事情,除了目标被 0 和 1 限制,结果是记录是您试图预测的目标类的概率,这并不是一个飞跃。
这与随机森林相反,随机森林是一种集合方法。我认为大多数人能够理解单一决策树的概念。但是解释为什么你要创建多棵树来防止过度拟合,以及它们是如何组合的就有点困难了。在这两种算法中,我更愿意向客户解释逻辑回归。
**2。** **逻辑回归提供了更简单的推论**
就像线性回归一样,你可以从逻辑回归中得到系数。我们可以看到,凹度的增加导致肿瘤恶性的可能性更高。

*注意:我知道半径平均值和交互作用项并不显著,但是去掉它们会影响逻辑回归的预测能力。*
这与随机森林不同,在随机森林中,您只能提取重要的特征。你不能说它们是如何与目标相关联的,因为一棵树上的变量分裂可能与另一棵树上的分裂相矛盾。
在如今神经网络和其他复杂算法大行其道的世界里,保持简单愚蠢是需要记住的重要一课。虽然它们可能很强大,但如果用更简单的方法也能达到同样的效果,你可能会得到额外的好处,能够更容易地向客户解释它和它的结果。
如果你想看与这个项目相关的 jupyter 笔记本,请查看我的[作品集页面](https://brendanbailey.github.io/Blog/GABreast_Cancer/GA_Breast_Cancer_Project.html)。
# 保持收益
> 原文:<https://towardsdatascience.com/keeping-the-gains-1249d1a8b1d5?source=collection_archive---------7----------------------->

为了确保您的客户获得您的模型的全部优势,请使用六适马和生产质量保证的常用工具之一来预测问题。
一旦你[让客户相信一个预测模型](/selling-your-data-science-project-7e3e06f91ec6)将解决他们的问题,并且[做出了一个可解释的模型](/dont-get-called-a-charlatan-building-credible-models-4f4709eb760c)让他们相信你已经为他们建立了那个模型,你最不需要的就是糟糕的实施或者环境中不可预见的变化来破坏你的模型的效力。
虽然这个问题在针对数据科学家的文献中可能没有受到足够的关注,但它在其他领域受到了很多关注,特别是制造业,他们已经开发了许多方法来预测和防止不良结果的发生。
困难在于该模型是在有限的数据集上开发的,该数据集具有某些特征。当您实现您的模型并开始使用预测时,您正在做一个隐含的假设,即那些条件继续成立。如果输入开始超出在训练阶段应用的范围,则输出可能是错误的,或者有时根本没有输出(例如,取决于所使用的算法)。请注意,后者可能是更好的情况,因为期望输出的用户会告诉你是否没有输出,但不会意识到输出是否继续但却是错误的。
考虑一个信用风险模型,其中收入是输入变量之一。如果收入普遍提高,或者更糟糕的是,收入的提高不成比例地影响到高收入者或低收入者,那么这个规则就可能被破坏。同样,使用车辆属性作为输入的汽车保险风险模型可能会受到影响,如果发生广泛变化,为了避免这种情况,需要对重要输入及其通常分布有很强的理解,并结合合理的实施后监控水平。为了检测这两种情况中的任何一种,监控传入数据的分布都是必不可少的。
有一种结构化的方法可以解决这个问题,这种方法已经在汽车制造业得到了发展,但是已经扩展到了其他领域,包括软件工程。这被称为 FMEA,代表故障模式和影响分析。FMEA 的目的是识别对良好流程结果的可能威胁,并确定最需要关注的优先级。
在制造环境中,FMEA 可能是为稳态流程(如装配零件)准备的,也可能是为项目准备的。将这一理念应用于生产中的预测模型的概念,该过程将被应用于生产中的预测模型,并且独立于更新现有模型或发布新模型的任务。在每种情况下,都会有特定的风险,尤其是在新模型或更新模型的情况下,不正确的数据流可能会进入评分流,或者可能会应用不正确的数据准备。
FMEA 的过程简单而直观,并且有许多针对制造环境的操作说明。在接下来的内容中,将概述该过程,并提供一些提示,说明如何将其从传统上下文中转换为适合于预测模型的实现和顺利使用的内容。
一群持有不同观点的人集思广益,讨论流程正常运行的可能危害。在预测模型的情况下,这将最小化创建模型的数据分析师和负责实现 ETL 过程的数据工程师或数据仓库人员,该 ETL 过程将数据交付给生产中的模型评分引擎。
小组集体讨论与特定实施或正在进行的过程相关的潜在失败。FMEA 手册通常包括单词列表,作为应用于手边工艺的提示,通常非常面向制造。就输入流是数据的预测模型而言,提示词可能包括“训练范围之外的数据”、“缺失”、“错误类型”(例如,期望整数、获取浮点)、“新记录太多/太少”等。
对于过程的结果方面也有提示词,即“效果”。预测建模特定提示可包括“无预测”、“不可能或无意义的预测”、“预测随机不正确”、“预测向上/向下/偏向特定类别”。
FMEA 进程的下一步是为每一个风险分配一个优先级,这决定了应该采取什么措施来防止负面结果。传统的风险优先级计算考虑了严重性、发生率和检测机会,给每一项打分(满分 10 分),并将三者相乘得到最终分数,称为风险优先级数(RPN)。这个数字用于指导决定在消除或控制已识别的问题上花费多少努力。
然后,最后一步是针对每种故障模式提出建议采取的措施。根据 RPN 和采取行动的难度或成本,范围可能从完全消除问题到建立预警系统到做出明智的选择不采取行动。
在一些具有相对正式文化的公司——以及维护这种文化的资源——FMEA 的行动被记录在控制计划中。在其他公司,他们可能会被添加到项目的实施过程中。文档的级别需要适合你的组织的文化——但仍然足以确保行动被实际采取。
多年来,FMEA 过程一直是制造业和其他领域质量保证的核心工具之一。它试图预测和减轻实际允许的尽可能多的潜在故障的哲学,显然不仅在数据科学,而且在更广泛的软件工程领域都有广泛的应用。对于一个分析师来说,努力说服客户允许对他们的数据进行分析,与他们一起开发一个合理的模型来解决他们的业务问题,然后由于一个可预见的数据错误或编码事故而在最后一个障碍中失败,当工具存在来阻止这种情况发生时,这将是真正的悲剧。
# 保持用户的信任
> 原文:<https://towardsdatascience.com/keeping-your-customers-faith-7ebbf2bb2610?source=collection_archive---------10----------------------->

*不要因为设定不切实际的期望而失去用户的好感*
我之前讨论过[维护客户和用户信誉的重要性](/dont-get-called-a-charlatan-building-credible-models-4f4709eb760c),尽可能广泛地使用这些术语。在之前的讨论中,我写了通过建立尽可能透明的模型——最容易理解的模型——来维护可信度。这还有另一个方面,虽然与你建立的模型不太直接相关,但也同样有可能破坏你在客户眼中的信誉,那就是提供对项目时间的合理估计,也就是所谓的“信守承诺”。
像生活中的许多事情一样,这个建议比任何人都更容易给出,主要是因为它保证了有人会想知道你什么时候会完成某件事——活动越复杂,因此越难以准确估计,他们就越渴望听到你的估计。
企业家埃隆·马斯克(Elon Musk)为这个问题提供了一些很好的例子。举个小例子,马斯克依赖他人的资本来完成他雄心勃勃的一系列项目,包括以他宣称的生产水平将 Telsa 3 推向市场。
我在我工作过的地方看到过这种情况,未能兑现承诺导致可信度下降,但马斯克出现在公众面前提供了两个机会。一个是他在公众视野里,不认识我,我不能因为谈论他而失去任何朋友。另一个原因是,凭借在公众眼中的地位和马斯克自己对各种媒体报道他的方式的分析,我们可以追踪这种情绪已经发生变化的方式。
马斯克就是马斯克,这种可信度的相对损失至少有可能不会产生进一步的后果。然而,我确信,如果我以这种方式拿我的信誉冒险,我会失去支持者。如果由我来管理特斯拉,这可能意味着投资者要么退出,要么停止出资。在撰写本文时,特斯拉的现金流并不乐观,这可能会影响该公司的生存能力。
在数据科学项目的背景下,风险可能是要么你当前的项目被冻结,要么你的下一个提案被否决。
有两种方法可以进入这种情况。第一个原因是完成项目的时间太少,第二个原因是未能有效地管理项目。正如这里报道的,例如,有许多人认为马斯克属于前一种人,这是我们现在要看的方面。过多的项目管理框架和项目管理建议本身就是一个行业——关于估计完成项目所需时间的方法的讨论相当少见。
与此同时,缺乏对完成项目所需时间的评估——或者至少是对公众讨论的关注——是缺乏做事情所需时间的数据。对于许多工程项目,有标准的成本工程方法,包括首次切割时间估计和清单,以确定增加额外时间的必要性(在这种情况下,我们指的是现实世界的项目,因此这些是像难以进入现场,或材料可能会被延迟之类的事情)。
在数据挖掘的背景下,缺乏关于事情需要多长时间的研究和良好数据,即使这与火星旅行的程度不同。一种方法, [DMCoMo](https://pdfs.semanticscholar.org/a66d/1bf2c6d8ad5272a31485193062395fee30bf.pdf) 提供了考虑的开端,但是[被批评在狭窄的操作范围内缺乏实用性](http://sistemas.unla.edu.ar/sistemas/gisi/papers/LNBIP-139-pag-58-74.pdf)。
一个可能的解决方案是开始收集您自己的数据,使用 DMCoMo 或类似文件建议的潜在成本驱动因素列表作为指南,指导您考虑哪些因素以及收集哪些数据。您仍然可以使用该框架,根据您已完成的项目、它们涉及的内容以及投入的工时来估算开始时间。
DMCoMo 集团是
1. 源数据,例如数量、质量
2. 数据挖掘模型,例如数量、类型
3. 开发平台
4. 工具,如现有员工获得的培训水平
5. 项目,例如涉及的不同部门的数量
6. 项目人员,例如领域知识水平。
如果你是唯一一个记录这些信息的人,突然之间,你将会把你演讲中的一个造成可信度差距的弱点变成一个相对于其他提出项目的人的优势。如果你有最大的可信度,你就有优势,这将帮助你越过难以说服的利益相关者,而不是遇到垃圾桶,你的项目将看到绿灯。
罗伯特·德格拉夫是 LeanPub 出版的新书《懒惰的数据科学家》的作者,也是同名博客的作者。他最近在媒体上的报道是“喜鹊数据科学”。
# 保持您的数据科学技能准备就绪并不断提高
> 原文:<https://towardsdatascience.com/keeping-your-data-science-skills-primed-ready-and-growing-dc6977a4f32a?source=collection_archive---------8----------------------->
## 为什么偶尔给自己设置一些随机挑战可以帮助你作为兼职数据科学家的生活——一个使用苏格兰橄榄球冠军和动画条形图的例子…

Photo by [Jordan Sanchez](https://unsplash.com/photos/Vbzx-yy5FoA?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/search/photos/practice?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)
数据科学不像骑自行车。反正对我来说不是。如果我不继续使用它,我就会失去它。我需要在这些小灰色细胞忘记他们花时间学习的重要的 R 函数或语法之前,让它们保持活跃。
我发现这特别困难,因为我研究范围如此之广。我可能会每三到四周建立一个快速的 ML 模型,基本的数据争论,EDA,数据可视化和一些回归一周几次,每两周进行一些无监督的学习,可能每两个月进行一次情感分析或地理绘图项目。我不介意承认我确实忘记了一些事情。
> 想要了解营销与数据科学结合领域的新闻,请关注 Chris 的 [Twitter](https://twitter.com/chrisBowdata)
也有很多天,我根本不花时间使用 R 或做任何可能被称为数据科学的事情。作为一名数字营销人员,我的工作描述涵盖了很多领域,其中大部分不是数据科学。当你每周增加几天休息时间时,掌握一门语言会变得有点棘手。
为了防止人才流失,也为了迫使自己走出舒适区,我时常喜欢给自己设置一个小挑战:让我稍微思考一下如何着手完成 r 中的一些小事。这种技术不时会有用。
## 使用 ggplot2 和 magick 制作动画图
这个周末,我一直在考虑写一篇关于使用 gganimate 包在 R 中制作动画的短文。考虑到我可能想要绘制什么,我开始考虑一个简单的线图,显示随着时间的推移,我的 Heriot 的球队在苏格兰橄榄球联盟中对阵他们的死敌 Watsonians 的比赛中的最终位置。
然而,我越想越觉得这可能太容易了。所有会发生的是,我最终会从一些手动数据挖掘中手动创建一些结束位置的向量,并从其他地方复制和粘贴代码,并修改它以适应我的数据。那有什么好玩的?
因此,挑战变成了动画条形图——按年份,而不是在零和最终值之间插值——显示顶级联赛由赢得它的球队赢得的次数。这是一个稍微不同的挑战,但最终成为了一个很好的实践!
虽然这对于所有的普通用户来说可能看起来过于简单,但是像这样的一两个小时的快速练习对我们这些做兼职编码的人来说是再合适不过了。有趣的是,这个练习最终在代码方面没有挑战性,而是过程。一旦我脑子里有了我想如何完成事情的想法,编码可能只需要 15 分钟左右。我想这一切都要回到 [PPPPPP](https://en.wikipedia.org/wiki/List_of_U.S._government_and_military_acronyms#PPPPPPP)
## 获取数据
第一步是获取数据。这是从维基百科关于苏格兰超级联赛的页面收集来的。虽然我可以手动输入赢家的向量,但这并不是一个真正可扩展的解决方案,也不会强化我以前的 rvest 学习,所以让我们来代替它。非常感谢这里方便的 [SelectorGadget](https://selectorgadget.com/) 的帮助。
scrape Scottish top tier rugby winners from Wikipedia
library(rvest)scot_prem_page <- read_html("https://en.wikipedia.org/wiki/Scottish_Premiership_(rugby)")winners <- scot_prem_page %>%
html_node(".column-width") %>%
html_text()
这只是给了我们一个恼人的单字符字符串,所以下一步是打破它:
convert single string of text into list of winners
library(stringr)winners_2 <-
str_split(winners, "\n")winners_3 <- unlist(winners_2)winners_4 <- winners_3[-1]
随着获胜团队向量的创建,是时候将它转化为我们需要处理的数据框架了。
## 构建数据框架
我们已经有了赢家的向量,现在我们需要一个年份向量来匹配他们:
create vector of years
year <- 1974:2018
现在,我们可以开始用我们的年份、获奖者来构建数据框架,我们将重命名我们的获奖者列,因为它变得有点难看:
build dataframe of winners
winners_df <- data.frame(year, winners_4)# rename winners_4 column as winner
library(dplyr)
winners_df <- rename(winners_df, winner = winners_4)
我计划这样做的方式是创建一个数据框架,其中有一列对应于每个赢得冠军的俱乐部,我可以用它来累积获胜总数。首先,我们需要一个冠军俱乐部的载体:
create vector of clubs who have won
winning_clubs <- as.character(unique(winners_df$winner))
然后,我们可以使用该向量将列添加到数据帧中。让我们借此机会将它转变为一个新的数据框架,这样,如果我们搞砸了,我们就有机会重新开始:
create new column for each winning club, initialise with 0
winners_df[ ,winning_clubs] <- 0# create new version of dataframe to guard against complete balls up
winners_df2 <- winners_df
新创建的列,我想把它转换成一个整齐的格式,这样我就可以利用 tidyverse 的便利功能。为此,我想使用来自`tidyr`的`gather()`函数将我的多个“俱乐部”列转换成一个俱乐部列,展示每年的每个俱乐部:
create long (tidy) version of dataframe
library(tidyr)
winners_df2 <- winners_df2 %>%
gather(club, win, -year, -winner)
构建完成后,当`club`列中的俱乐部与`winner`列中的俱乐部匹配时,我可以使用`mutate`调用在 win 列中添加 1,然后我可以按俱乐部分组,并使用另一个 mutate 调用来构建累积获胜的列:
alter win column to reflect if won that year
winners_df2 <- winners_df2 %>%
mutate(win = ifelse(club == winner, 1, 0))# create column for cumulutive wins
winners_df2 <-
winners_df2 %>%
arrange(year) %>%
group_by(club) %>%
mutate(wins = cumsum(win))# change club variable to factor
winners_df2\(club <- as.factor(winners_df2\)club)
## 制作动画
数据帧完成后,是时候构建情节和动画了。非常感谢弗龙肯斯汀[这篇博文](https://fronkonstin.com/2017/03/07/frankenstein/)帮助我制作了这个过程的动画片段。
首先,我使用一年的数据和 ggplot2 创建了一个测试地块,以构建我正在寻找的地块类型。完成后,我准备为数据集中的每一年构建一个图,并将其保存到我的项目文件夹中。如果你不是 for 循环的粉丝,现在把目光移开:
create plot for each year
for (yr in year) {
filename <- paste0("champion", yr,".jpeg")
win_plot <-
winners_df2 %>%
filter(year == yr) %>%
ggplot(aes(x = fct_reorder(club, wins), y = wins)) +
geom_col() +
coord_flip() +
labs(title = "Scottish Rugby Championships by Club 1974 - 2018",
caption = paste0("Year: ", yr),
x = "Club",
y ="Number of wins") +
ylim(0, 14) + # constrain y limits to prevent scale change over time
scale_y_continuous(breaks = c(2, 4, 6, 8, 10, 12)) +
theme_minimal()
name = paste0("winners_", yr,".jpeg")
ggsave(filename = name,
plot = win_plot,
device = "jpeg",
width = 6, height = 4,
units = "in")
}
一个装满情节的文件夹之后,我们可以使用 [magick](https://cran.r-project.org/web/packages/magick/vignettes/intro.html) 包中的`image_animate()`功能将各个图像组合成我们的动画。gif:
create animation
library(magick)
frames = c()
images = list.files(pattern = "jpeg")
for (i in length(images):1) {
x = image_read(images[i])
x = image_scale(x, "300")
c(x, frames) -> frames
}animation = image_animate(frames, fps = 4)image_write(animation, "championship_winners.gif")

## 总结
这是我为这个数据集选择的 dataviz 类型吗?大概不会。我是说,这取决于观众。对于一个注意力跨度有限的社交媒体设置来说,它可能会工作,但标准的条形图会更清楚地显示最终的获胜数字,GitHub commits 风格的热图结合行尾总数可能会更容易看到最终的数字以及何时赢得冠军,但这不是重点。
这个练习的目的是给自己设定一个日常工作中不会出现的挑战,并尝试解决它。而且,虽然还有一些调整我可能会做(颜色编码酒吧的俱乐部颜色也许?),我觉得一个慵懒的星期天也不算太差。嘿,反正电视上也没什么…
本文使用的代码可以在这里的 GitHub 上找到[。](https://github.com/chrisBow/scottish-rugby-premiership-winners/blob/master/prem_winners.R)
# 保持您的生产模式新鲜
> 原文:<https://towardsdatascience.com/keeping-your-production-model-fresh-9cf91e785630?source=collection_archive---------9----------------------->

Somebody enjoying fresh air
一个伟大的模特需要爱和关注,如果它想在一生中像第一天一样有用的话。
随着时间的推移,随着关系的改变,任何统计或机器学习模型都会经历性能损失。有时这种情况发生得非常突然,就像 GFC 危机期间许多信用违约模型发生的情况一样。其他时候,退化发生在一个较长的时期,并且几乎可以由观察趋势的人来预测。
是什么导致了退化?首先,不管你有多小心,在某种程度上,你的模型符合噪音或潜在因素,也就是说,它一开始就是错误的,你的一些准确性是由于随机的机会。
下一个问题是事情确实会变。考虑一个汽车保险模型,它有与车辆规格相关的变量。其中一些变量将是有效的风险指标,因为它们与高风险驾驶员的购买选择相关,但随着购买偏好的变化,例如随着燃料价格的变化,更喜欢或多或少省油的汽车,相关性也会发生变化。类似地,在良好的经济条件下训练出来的信用违约模型,很容易漏掉在糟糕的经济条件下增加违约几率的因素。
从这两个例子中可以直观地看出,依赖于人类行为的模型可能特别容易退化,而在某种意义上与物理过程更密切相关的模型可能具有某种额外的稳定性。接下来,了解这对于您的模型的风险有多大以及在什么时间范围内将成为您的主题专家的关键盟友,并且在大多数情况下,将制定模型审查和再培训的定期计划。
同时,您可能希望使用数据告诉您的信息,因此您需要一些方法来确定新到达的输入数据是否已经更改。对于快速变化的环境尤其如此。
在数据点具有高度独立性的输入变量的情况下,统计过程控制中使用的控制图可用于检测过程的变化。
这些图表的使用有很多印刷版和网络版的指南,它们已经被成功使用了很多年。它们的共同之处在于,来自一个过程的测量值被顺序绘制在一个图表上,图表的中心线位于平均值(或其他适当的过程平均值)处,上下线代表通常的过程范围。因此,很容易确定过程何时改变了其范围或其平均结果。
但是,特别是对于属性或分类数据,为相对较小的数据开发的方法在用于大量数据时会产生有问题的结果。
R 中的 [qicharts 包](https://cran.r-project.org/web/packages/qicharts/vignettes/controlcharts.html)实现了这个问题的一个解决方案 David Laney 开发的‘质数’图表,当使用大的子组时,它继续给出精确的结果。这个包包含一个全面的质量控制图表,所以你将能够找到一个适合你的需要。
在设置连续数据的采样方案时仍需小心谨慎-请注意,没有必要使用每天收集的完整数据来检查输入变量的过程是否保持了模型实施时的特征,只要它足够大以具有代表性即可。
当然,有必要平衡对变化做出反应的努力和收益,特别是在有大量输入的模型中。如果您已经[完成了您的模型](/keeping-the-gains-1249d1a8b1d5)的 FMEA,例如在第一次实施时,您将已经感觉到不同输入的相对重要性,以及特定变量的变化对整体模型性能的影响。在某些情况下,可能没有必要采取任何行动;其他变化可能需要立即采取行动,以防止做出糟糕的决策。
合理的模型监督与精心设计的模型检查计划相结合,对于保持一个优秀的产品模型是至关重要的。优先检查关键变量,并在发生变化时发出警告,这将确保您永远不会因环境变化而措手不及,使您的模型失去效力。
*在* [*leanpub 上查看我!*](https://leanpub.com/thelazydatascientist)
# kegra:基于 Keras 的知识图深度学习
> 原文:<https://towardsdatascience.com/kegra-deep-learning-on-knowledge-graphs-with-keras-98e340488b93?source=collection_archive---------1----------------------->

你好。我在[过去的文章](/machine-learning-use-small-words-5cc8f34a5964)中提到过,我正在紧张地研究企业数据集的认知计算。这是那个。
这篇文章需要对深度学习有所了解,但是你应该能够理解数据科学的最基本知识。
我一直致力于用 GPU 上的深度学习来检测图形中的模式。托马斯·基普夫[写了一个不错的库](https://github.com/tkipf/keras-gcn?files=1),用 Keras 对图节点进行分类。本文基于他的工作“[图卷积网络半监督分类](https://arxiv.org/abs/1609.02907)”。让我们看一看。
首先,什么是图?
嗯,我在工作中关注知识图表。这些图将“白宫”和“唐纳德·特朗普”这样的实体表示为节点,而“工作地点”这样的关系表示为边。我们如何建立这些图表是另一个时代的故事。在这篇文章中,我正在研究交易数据,以训练一个识别欺诈交易的分类器。如果你更喜欢顶点和弧而不是节点和边,那么[阅读这篇文章](https://math.stackexchange.com/questions/31207/graph-terminology-vertex-node-edge-arc)。
在图形的怪异世界里,我感觉就像在家里一样。我对图形的研究可以追溯到我的硕士论文。在那项工作中,我对在有向无环图中寻找公共元素(凸子图)感兴趣。我正在根据处理器运行的软件来确定向处理器添加什么样的定制指令。我用整数线性规划来解决这个问题。对于大型图形,求解程序可能需要几个小时甚至几天。
该研究领域的链接:
* [嵌入式人工神经网络软硬件协同设计案例研究](https://link.springer.com/chapter/10.1007/978-3-642-28305-5_18?lipi=urn%3Ali%3Apage%3Ad_flagship3_profile_view_base%3BHLJC%2BSj0TH%2BaHNjsoTOlrw%3D%3D)
* [可调指令集扩展标识](https://ruor.uottawa.ca/handle/10393/20716?lipi=urn%3Ali%3Apage%3Ad_flagship3_profile_view_base%3BHLJC%2BSj0TH%2BaHNjsoTOlrw%3D%3D)
* [人工神经网络专用集成电路](http://ieeexplore.ieee.org/document/5873060/?arnumber=5873060&lipi=urn:li:page:d_flagship3_profile_view_base;HLJC%2BSj0TH%2BaHNjsoTOlrw%3D%3D)
* [使用自定义指令在 FPGA 上加速人工神经网络](http://ieeexplore.ieee.org/document/6030491/?arnumber=6030491&searchWithin=%22Authors%22:.QT.Daniel%20Shapiro.QT.&newsearch=true&lipi=urn:li:page:d_flagship3_profile_view_base;HLJC%2BSj0TH%2BaHNjsoTOlrw%3D%3D)
* [在硬件限制下改进 ISE 识别](https://ruor.uottawa.ca/handle/10393/19799)
* [并行指令集扩展标识](http://ieeexplore.ieee.org/document/5662163/?arnumber=5662163&lipi=urn:li:page:d_flagship3_profile_view_base;HLJC%2BSj0TH%2BaHNjsoTOlrw%3D%3D)
* [可配置多处理器的静态任务调度](https://ruor.uottawa.ca/handle/10393/12896?lipi=urn%3Ali%3Apage%3Ad_flagship3_profile_view_base%3BHLJC%2BSj0TH%2BaHNjsoTOlrw%3D%3D)
* [多处理器片上系统软硬件协同设计工具链指令集扩展识别的设计与实现](https://search.proquest.com/docview/305138347?lipi=urn%3Ali%3Apage%3Ad_flagship3_profile_view_base%3BHLJC%2BSj0TH%2BaHNjsoTOlrw%3D%3D)
* [SING:多处理器片上系统设计和系统生成工具](https://ruor.uottawa.ca/handle/10393/12898)
下面是 OrientDB 中知识图本体的一个例子:

Source: [OrientDB demo page](https://orientdb.com/docs/3.0.x/gettingstarted/demodb/queries/DemoDB-Queries-Shortest-Paths.html)
**第二,什么是我们能察觉到的模式?**
我们想要标记节点。图中的每个实体都有一些我们想要分类的特征,我们只有一些节点的标签。我们可以预测简单的[布尔](https://english.stackexchange.com/questions/4481/should-the-word-boolean-be-capitalized)标签,如“人”或“不是人”,以及更有趣的标签,如将节点分类到几个类别中的一个。然后,我们可以进行更复杂的回归,比如根据我们从图表中获得的实体数据来预测实体带来的风险。这包括节点到其他节点的连接。为了简单起见,让我们继续讨论本文中的布尔节点标记/分类问题。我们希望将大约 4000 个银行账户的 594643 笔交易标记为可疑或不可疑。我们希望在不到一分钟的时间内完成。不是几小时或几天。
**第三,如何定义一个 kegra 看得懂的图?**
我们需要指定两个文件。第一个包含节点描述的节点 id,第二个描述节点如何连接。在 kegra 提供的 cora 示例中,有 2708 个节点的描述和标签,5429 条边(节点对)定义了节点之间的连接。
以下是每个文件的几行视图:

Links between nodes

Each node ID is followed by features (mostly 0s) and finally there is a node label (e.g. Neural_Networks, Case_Based). The features are mostly 0s and wrap around for many lines in the screenshot above. Each feature represents the use in the document (node) of a certain word. More info in the [kegra README here](https://github.com/tkipf/keras-gcn/blob/master/kegra/data/cora/README).
让我们试一试吧
首先,您需要 Keras 2,所以这样做:
pip install keras --upgrade
假设你安装了 Keras 和 TensorFlow,keras-gcn 依赖于 gcn,那我们就 git 克隆,一个一个安装。
install gcn
git clone https://github.com/tkipf/gcn.git
cd gcn/
python setup.py install
cd ..#install keras-gcn
git clone https://github.com/tkipf/keras-gcn.git
cd keras-gcn/
python setup.py install
首先让我们在一个现成的例子[上运行代码,这个例子提供了名为 cora](https://github.com/tkipf/keras-gcn/tree/master/kegra/data/cora) 的 kegra。我们在输出中看到,cora 从原始数据中检测并打印出了预期的节点和边的数量。

Training run on the cora dataset: 36% accuracy and rising.

Testing result on the cora dataset: 77.6% accuracy.
我们现在对 kegra 理解输入文件的方式做了一点小小的改变,只是为了让名字更好听。在 github 上的当前版本中,输入文件是“*”。引用"来描述节点之间的弧,并引用" *。内容”来描述节点。相反,我把 kegra 改成了“*”。链接"和" *。节点”文件。您的数据文件夹现在应该是这样的:
~/kegra/keras-gcn/kegra$ ls -l data/cora/
total 7720
-rwxrwxr-x 1 ubuntu ubuntu 69928 Dec 3 02:52 cora.link (was cora.cites)
-rwxrwxr-x 1 ubuntu ubuntu 7823427 Dec 3 02:52 cora.node (was cora.content)
-rwxrwxr-x 1 ubuntu ubuntu 1560 Dec 3 02:52 README
~/kegra/keras-gcn/kegra$ ls -l data/customerTx/
total 7720
-rwxrwxr-x 1 ubuntu ubuntu 7823427 Dec 3 05:20 customerTx.node
-rwxrwxr-x 1 ubuntu ubuntu 1560 Dec 3 05:20 README
-rwxrwxr-x 1 ubuntu ubuntu 69928 Dec 3 05:20 customerTx.link
现在让我们用交易数据填充 **customerTx.node** 和 **customerTx.link** 。第一个文件是银行客户及其特征的列表。格式是:

Quick view of some transaction records. In this scenario, there is a sender and recipient of money, and a record of the amount sent (amount column), and the label applied by a human analyst that reviewed the transaction (fraud column). We can ignore the first two columns (the index and step columns).

The edges file (**customerTx.link**) records who the two parties are in each transaction.

The nodes file (**customerTx.node**) records information on each node in the graph as a sender of funds on each transaction. The **txCount** column lists the number of transactions (edges) leaving the node. The **amountMean** column specifies the mean transaction size. The **fraudMean** column is the mean of flagged transactions on the sender account during the period this data covers. Note that the vast majority of transactions are OK and not FRAUD, which is a [dataset imbalance](https://machinelearningmastery.com/tactics-to-combat-imbalanced-classes-in-your-machine-learning-dataset/).

There are 4112 nodes in the graph. On average 2.3% have been flagged as problematic by an analyst.
我们现在可以使用 kegra 以不同的分析师准确度来分析图表。
如果一个完美的分析师对系统进行数据训练,它应该能够完美地学习如何分析图表。然而,如果人类分析师有 20%的时间是错误的,那么 kegra 模型的预测能力同样应该被限制在 80%。为了验证这一点,我在图表标签中添加了不同数量的随机噪声,以观察随着训练数据的质量越来越差,kegra 会如何表现。
以下是表格和图表形式的结果:

Raw results for the transaction labeling experiments, using deep learning on knowledge graphs

This is the same data as the table above, but in an easier to understand graphic
这里有很多东西需要消化。首先,我们看到,随着数据(蓝色)中的噪声增加,早期停止(x 轴上的标签)在训练中越来越早地出现。这告诉我们,特征的数量如此之少(几列)会导致训练数据的过度拟合。第二,我们看到测试精度普遍低于训练精度。这是意料之中的,因为分类器熟悉训练数据,而测试数据不熟悉。第三,测试精度不为零。很好!这意味着分类器可以仅使用图和每个节点的特征(txCount、amountMean 和 fraudMean)来重新生成 OK/FRAUD 标签。第四,分类器(橙色)的精度随着注入噪声(蓝色)的增加而下降。这意味着结果不是随机的。第五,我们看到,训练精度(红色)加上添加的噪声(蓝色)加起来约为 100%,这意味着分类器与标记数据集的分析师一样好/差,但不会差太多。
综上所述,kegra 在知识图分类上表现非常好。与他们论文中的结果相比,这些结果可能太好了。我将检查交易文件中的欺诈标签列是否太具解释性,并使用更难从更广泛的数据集中预测的功能来替换它,如原产国、城市、邮政编码和更多列。
我的下一个动作是从包含更多列的源文件中重新生成事务数据集,看看 kegra 的性能是否仍然如此之好。在 cora 数据集上没有提前停止,因此我怀疑交易数据对 kegra 来说没有挑战性,原因之一我在上面提到过。也许如果我在生成的图中嵌入更多的语义特征…接下来我可以做很多有趣的事情。
特别感谢[托马斯·基普夫](https://github.com/tkipf)在发表前审阅了这篇文章。与我通常的高水平文章相比,这是一篇准备(和阅读)非常复杂的文章。如果你喜欢这篇关于图形深度学习的文章,那么请让我知道写更多像这样的[研究](https://en.wiktionary.org/wiki/researchy)内容。我也很高兴在评论中听到你的反馈。你怎么想呢?
试用**拍手工具**。轻点那个。跟着我们走。分享这篇文章的链接。去吧。
编码快乐!
——丹尼尔
[丹尼尔@lemay.ai](mailto:daniel@lemay.ai) ←这个其实*管用*。打个招呼。
LEMAY . AI
1(855)LEMAY-AI
您可能喜欢的其他文章:
* [人工智能和不良数据](/artificial-intelligence-and-bad-data-fbf2564c541a)
* [人工智能:超参数](/artificial-intelligence-hyperparameters-48fa29daa516)
* [人工智能:让你的用户给你的数据贴上标签](https://medium.com/towards-data-science/artificial-intelligence-get-your-users-to-label-your-data-b5fa7c0c9e00)
# keras:R 中的深度学习
> 原文:<https://towardsdatascience.com/keras-deep-learning-in-r-b0be9dc726ff?source=collection_archive---------1----------------------->
正如你现在所知道的,机器学习是计算机科学(CS)中的一个子领域。深度学习是机器学习的一个子领域,它是一套受大脑结构和功能启发的算法,通常被称为人工神经网络(ANN)。深度学习是当下机器学习最热门的趋势之一,有很多问题是深度学习大放异彩的,比如机器人、图像识别、人工智能(AI)。
今天的教程将带着`keras`包用 Keras 简单介绍一下 R 中的深度学习:
* 您将从 R 中的[深度学习包的简短概述开始,并且](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#overview)
* 你将读到更多关于 Keras、 `[kerasR](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#differences)` [和](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#differences) `[keras](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#differences)`包之间的[差异,以及当一个包是另一个包的接口时意味着什么;](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#differences)
* 然后,您将真正开始使用 RStudio 的`keras`包:您将学习如何首先[准备您的工作空间](https://www.datacamp.com/community/tutorials/prep)并[加载](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#data)内置数据集、虚拟数据和来自 CSV 的数据;
* 接下来,您将看到如何[探索](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#explore)和[预处理您从 CSV 文件中加载的数据](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#prep):您将标准化数据并将其分成训练集和测试集。
* 在这之后,你就准备好[构建你的深度学习模型](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#model);在这种情况下,您将为多类分类构建一个多层感知器(MLP)。
* 您将学习如何[编译和拟合](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#compile)模型以适应您的数据,如何[可视化培训历史](https://www.datacamp.com/community/tutorials/viz),以及
* 你将[根据测试数据预测目标值](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#predict);
* 最后,您将[评估您的模型](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#evaluate),解释结果并[微调您的模型](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#finetune),使其性能更好:您将学习如何添加层和隐藏层,并了解如何调整优化参数以实现更好的结果。
* 此外,您可能希望[保存您的(优化的)模型,或者在其他时间将其加载回](https://www.datacamp.com/community/tutorials/keras-r-deep-learning#save)。您将在本教程的最后一节看到这是如何完成的!
想进一步了解感知机、多层感知机(MLPs)等深度学习中的原始 Keras 或关键概念吗?考虑或参加 DataCamp 的[Python 深度学习](https://www.datacamp.com/courses/deep-learning-in-python)课程或参加 [Keras 教程:Python 深度学习](https://www.datacamp.com/community/tutorials/deep-learning-python)。
**提示**:在这里找到我们的 Keras 备忘单[。](https://www.datacamp.com/community/blog/keras-cheat-sheet)
# R 中的深度学习:包的简短概述
随着深度学习受欢迎程度的上升,CRAN 已经丰富了更多的 R 深度学习包;下面你可以看到这些包的概述,取自[机器学习和统计学习 CRAN 任务视图](https://cran.r-project.org/view=MachineLearning)。“百分位数”栏表示在[文件](https://www.datacamp.com/community/tutorials/www.rdocumentation.org)中找到的百分位数:
[参见[原文](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)中的概述]
**提示**:关于 R 中深度学习包的比较,请阅读[这篇博文](http://www.rblog.uni-freiburg.de/2017/02/07/deep-learning-in-r/)。有关 RDocumentation 中排名和分数的更多信息,请查看这篇博文。
在 RDocumentation.org 上没有找到`deepr`和`MXNetR`,所以这两个包的百分比是未知的。
# 喀拉斯、`keras`和`kerasR`
最近,两个新的软件包进入了 R 社区:由 Taylor Arnold 创作的`[kerasR](https://github.com/statsmaths/kerasR)` [软件包](https://github.com/statsmaths/kerasR)和【RStudio】的 `[keras](https://github.com/rstudio/keras)` [软件包](https://github.com/rstudio/keras)。
这两个包都提供了 Python 深度学习包 Keras 的 R 接口,您可能已经听说过或者可能已经使用过它了!对于那些不知道 Keras 包必须为 Python 用户提供什么的人来说,它是“一种高级神经网络 API,用 Python 编写,能够在 TensorFlow、微软认知工具包(CNTK)或 Theano 上运行”。
你看,开始使用 Keras 是熟悉 Python 深度学习的最简单的方法之一,这也解释了为什么`kerasR`和`keras`包为 R 用户提供了这个奇妙包的接口。
在这种情况下,当一个包(比如 R `keras`)是另一个包(Python Keras)的“接口”时,理解它的确切含义是有好处的。简单地说,这意味着带有接口的`keras` R 包允许您享受 R 编程的好处,同时访问 Python Keras 包的功能。
**注意**这并不是一种不常见的做法:例如,`h2o`包也提供了一个接口,但是在这种情况下——正如它的名字所暗示的那样——提供给 H2O,一个用于大数据的开源数学引擎,你可以用它来计算并行分布式机器学习算法。其他你可能知道的提供接口的包有`RWeka`(Weka 的 R 接口)`tensorflow`(tensor flow 的 R 接口)`openml-r`(OpenML 的 R 接口)……可以继续说下去!
现在您已经知道了所有这些,您可能会先问自己以下问题:您如何比较原始的 Python 包和 R 包?
本质上,你不会发现 R 包和原来的 Python 包有太多的区别,多半是因为函数名几乎都一样;您注意到的唯一区别主要在于编程语言本身(变量赋值、库加载等等),但最重要的是要注意 R 包中包含了多少原始功能。
**注意**这个备注不仅对`keras`库有效,对上面提到的`tensorflow`、`openml-r`、…等接口包也有效!
其次,你可能也想知道这两个 R 包之间有什么区别。好吧,如果你想考虑两者的区别,你可能要考虑以下几点:
* `keras`包使用管道操作符(`%>%`)将函数或操作连接在一起,而在`kerasR`中你不会发现这一点:例如,用`kerasR`制作你的模型,你会发现你需要使用`$`操作符。管道操作符的使用通常会提高代码的可读性,如果你以前使用过 [Tidyverse 包](http://tidyverse.org/),你肯定已经见过这个操作符了。
* 您将会看到`kerasR`包含了一些函数,它们的命名方式与最初的 Keras 包相似,但并不完全相同。比如原来的(Python) `compile()`函数叫做`keras_compile()`;这同样适用于其他功能,例如`fit()`,它变成了`keras_fit()`,或者`predict()`,当您使用`kerasR`包时,它是`keras_predict`。这些都是自定义包装。
* 你可以争辩 RStudio 的`keras`包的安装比`kerasR`包的安装容易;要安装后者,您需要首先确保配置使用哪个 Python 版本,如果您在安装了多个环境或 Python 版本的 pc 上工作,这可能会变得很棘手。但我会让你决定这一点:)

现在您已经收集了一些背景知识,是时候真正开始使用 R 中的 Keras 了。正如您将在本教程的介绍中读到的,您将首先检查您的工作区的设置。然后,您将加载一些数据,经过一个简短的数据探索和预处理步骤,您将能够开始构建您的 MLP!
让我们继续吧!
# 安装`keras`包
和往常一样,开始使用任何包的第一步是设置您的工作空间:将库安装并加载到 RStudio 或您正在工作的任何环境中。
不用担心,对于[原创教程](https://www.datacamp.com/community/tutorials/keras-r-deep-learning),包会帮你加载进去!
首先,确保您安装了`keras`:您可以通过在您的控制台中运行`devtools::install_github("rstudio/keras")`来轻松完成此操作。接下来,您可以加载包并安装 TensorFlow:
Load in the keras package
library(keras) # Install TensorFlow
install_tensorflow()
当你做完这些,你就可以走了!很快,对吧?
**提示**:关于安装过程的更多信息,请查看[软件包网站](https://rstudio.github.io/keras/)。
# 加载数据
现在安装过程已经清楚了,您的工作空间也准备好了,您可以开始加载数据了!此时,当涉及到您的数据时,您有三个大的选择:您可以选择使用`keras`包自带的一个内置数据集,您可以从例如 CSV 文件加载您自己的数据集,或者您可以创建一些虚拟数据。
无论您处于哪种情况,您都会看到您能够快速开始使用该软件包。本节将快速浏览三个选项,并解释如何加载(或创建)您需要开始的数据!
如果你以前使用过 Python 中的 Keras 包,你可能已经使用函数`mnist.load_data()`、`cifar10.load_data()`或`imdb.load_data()`访问过 [Keras 内置数据集](https://github.com/fchollet/keras/tree/master/keras/datasets)。
以下是一些使用`keras`包加载 MNIST、CIFAR10 和 IMDB 数据的示例:
Read in MNIST
data mnist <- dataset_mnist() # Read in CIFAR10 data
cifar10 <- dataset_cifar10() # Read in IMDB data
imdb <- dataset_imdb()
**注意**用`keras`载入内置数据集中的所有函数遵循相同的模式;对于 MNIST 数据,您将使用`dataset_mnist()`功能加载您的数据。
或者,你也可以快速制作一些虚拟数据来开始。要了解如何轻松使用`matrix()`函数来实现这一点,请访问[原始文章](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)。
**注意**检查你的数据的数据结构绝对是个好主意;了解您正在处理的数据非常重要,因为这对您需要采取的后续步骤非常重要。在本教程的后面部分,您将了解到更多关于这方面的内容!
除了内置数据集之外,您还可以从文件中加载数据。在本教程中,您将重点关注从 CSV 文件中加载数据,但是如果您想了解更多关于在 R 中导入文件的信息,请考虑 DataCamp 的 [R 数据导入教程](https://www.datacamp.com/community/tutorials/r-data-import-tutorial)。
让我们使用`read.table`包中的`read.csv()`函数加载来自 [UCI 机器学习库](http://archive.ics.uci.edu/ml/index.php)的数据集。你可以在这里找到这个练习[的代码。](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)
检查您的数据导入是否成功总是一个好主意。你通常使用像上面 DataCamp Light chunk 中的`head()`、`str()`和`dim()`这样的函数来快速完成这项工作。
这三个函数的结果不会立即指出任何异常;通过查看`str()`函数的输出,可以看到`Species`列的字符串是作为因子读入的。这没有问题,但是对于接下来的步骤来说,知道您将在哪里探索和预处理数据绝对是件好事。
# 数据探索
在本教程中,您将继续使用通过`read.csv()`函数导入的著名的`iris`数据集。
对于那些不具备处理这些数据所需的生物学知识的人,这里有一些背景信息:所有的花都有一个萼片和一个花瓣。萼片包围花瓣,通常是绿色的叶状,而花瓣通常是彩色的叶子。对于鸢尾花来说,这只是有一点点不同,如下图所示:

您可能已经在上一节中看到过,在导入之后,`iris`数据框没有任何列名。现在,对于本教程的剩余部分,这并不太重要:即使`read.csv()`函数将`data.frame`中的数据返回给你,你需要传递给`fit()`函数的数据需要是一个矩阵或数组。
关于刚刚提到的这两种数据结构,需要记住一些事情:—矩阵和数组没有列名;—矩阵是单一数据类型的二维对象;—数组是单一数据类型的多维对象;
**提示**:如果你想回顾一下 R!
**注意**另一方面,数据帧是一种特殊的命名列表,其中所有元素都具有相同的长度。它是一个多维对象,可以包含多种数据类型。当您检查前一节中的`iris`数据帧的结构时,您已经看到了这一点。了解这一点并考虑到您将需要处理一个二维或多维的单数据类型的对象,您应该在开始构建您的神经网络之前准备好做一些预处理!
现在,列名可以方便地用于探索目的,它们肯定会帮助您理解数据,所以让我们借助`names()`函数添加一些列名。接下来,您可以立即在您的数据探索中使用`iris`变量!例如,画出花瓣长度和花瓣宽度如何与`plot()`函数相关联。你可以在这里找到练习。
**注意**您使用`unclass()`函数将物种名称,即“setosa,versicolor”和“virginica”转换为数字 1、2 和 3。
现在仔细看看绘图函数的结果:

该图显示了不同种类鸢尾花的`Petal.Length`和`Petal.Width`之间的正相关关系。然而,这可能是您想用`cor()`函数测试的东西,它将给出数据集中包含的所有属性之间的整体相关性。你可以在这里找到代码。
此外,您可以结合使用`corrplot`包和`cor()`函数来绘制数据属性之间的相关性;在这种情况下,您将计算`iris`数据框所有属性的总体相关性。您将计算结果存储在变量`M`中,并将其传递给`corrplot()`函数。
此外,不要忘记指定一个`method`参数来指示您希望如何绘制数据!
您可以在原文章的[中进一步尝试 DataCamp Light chunk 中的可视化方法。](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)

利用 R 控制台进一步探索您的数据。
如果你想用`ggvis`包,也就是图形的交互语法,为这些数据制作情节,可以看看 DataCamp 的《R 中的[机器学习》新手教程](https://www.datacamp.com/community/tutorials/machine-learning-in-r)或者上 DataCamp 的 [ggvis 课程](https://www.datacamp.com/courses/ggvis-data-visualization-r-tutorial/)。
# 数据预处理
在构建模型之前,您还需要确保您的数据已被清理、规范化(如果适用)并被划分为训练集和测试集。由于数据集来自 UCI 机器学习知识库,您可以预期它已经有些干净了,但是让我们再次检查您的数据质量。
乍一看,你用`head()`检查数据的时候,并没有真的看出什么异常,对吧?让我们利用`summary()`和`str()`来简单回顾一下您在检查数据导入是否成功时所学到的内容。
既然您已经确定数据足够干净,那么您可以开始检查对于您在本教程中使用的任何数据是否有必要进行规范化。
从上面 DataCamp Light 块中的`summary()`函数的结果中,您可以看到虹膜数据集不需要进行规范化:`Sepal.Length`属性的值从`4.3`到`7.9`并且`Sepal.Width`包含从`2`到`4.4`的值,而`Petal.Length`的值范围从`1`到`6.9`并且`Petal.Width`从`0.1`到`2.5`。换句话说,虹膜数据集所有属性的所有值都包含在`0.1`和`7.9`的范围内,你可以认为是可以接受的。
但是,研究规范化对数据的影响仍然是一个好主意;您甚至可以将规范化的数据传递到您的模型中,看看是否有任何影响。这超出了本教程的范围,但是您可以自己尝试一下!代码都在本教程中:)
你可以自己制作函数来归一化虹膜数据;在这种情况下,这是一个最小-最大归一化函数,它将您的数据线性转换为函数 *(x-min)/(max-min)* 。从这个角度来看,将这个公式转换成 R 非常简单:创建一个函数,向其传递`x`或一些数据。然后,您将计算第一次减法 *x-min* 的结果,并将结果存储在`num`中。接下来,您还要计算 *max-min* 并将结果存储在`denom`中。你的`normalize()`函数的结果应该会返回`num`除以`max`的结果。
要对您的`iris`数据(不包括目标值)应用这个用户定义的函数,您不仅需要使用`normalize`,还需要使用`lapply()`函数来归一化数据,就像本练习中的[一样。](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)
**提示**使用 R 控制台中的`hist()`功能,研究归一化前(`iris`)和归一化后(`iris_norm`)的虹膜数据分布。
要使用`keras`包中的`normalize()`函数,您首先需要确保您正在使用一个矩阵。您可能还记得,矩阵的特征是矩阵数据元素具有相同的基本类型;在这种情况下,您有 factor 类型的目标值,而其余的都是数字。
这首先需要改变。
您可以使用`as.numeric()`功能将数据转换成数字。在这里找到代码。
数字数据框是可以的,但是如果你想使用`keras`包,你需要将数据转换成数组或矩阵。您可以通过`as.matrix()`功能轻松实现这一点;不要忘记在这里将`dimnames`设置为`NULL`。
正如您可能已经在上一节中读到的,归一化虹膜数据是没有必要的。尽管如此,研究规范化及其效果仍然是一个好主意,看看如何不仅通过 UDF,而且通过内置的`normalize()`函数来实现。
将数据转换成矩阵后,您确实可以使用`keras`包来研究数据标准化的效果。点击查看练习[。](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)
**注意**这里使用`dimnames()`将`iris`的 dimnames 设置为`NULL`。这可以确保数据中没有列名。
现在,您已经检查了数据的质量,并且知道没有必要对数据进行规范化,您可以继续使用原始数据,并将其分为定型集和测试集,以便最终准备好开始构建模型。通过这样做,您可以确保事后对预测模型的性能进行诚实的评估。
在将数据分成训练集和测试集之前,最好先设定一个种子。用`set.seed()`可以很容易地做到这一点:使用这个函数并传递一个随机整数给它。种子是一个数 R 的随机数发生器。设置种子的主要优点是,无论何时在随机数生成器中提供相同的种子,您都可以获得相同的随机数序列。
这对于代码的可复制性来说非常好!
您使用`sample()`函数获取一个样本,其大小设置为虹膜数据集的行数,即 150。使用替换进行采样:从两个元素的向量中进行选择,并将 1 或 2 分配给虹膜数据集的 150 行。元素的分配受制于`0.67`和`0.33`的概率权重。
要查看代码、练习和答案,请点击这里。
`sample()`函数的`replace`参数被设置为`TRUE`,这意味着你将一个`1`或者一个`2`赋值给某一行,然后将`2`的向量重置为原来的状态。
换句话说,对于数据集中的下一行,每次都可以分配一个`1`或`2`。选择`1`或`2`的概率不应该与剩余物品的权重成比例,所以你指定概率权重。
*补充说明:*例如,如果您使用了带有特定`dataset_imdb()`函数的内置数据集,那么您的数据可以通过使用`$`运算符轻松拆分:
x_train <- imdb\(train\)x
y_train <- imdb\(train\)y
x_test <- imdb\(test\)x
y_test <- imdb\(test\)y
您已经成功分割了数据,但是还需要完成一个步骤才能开始构建模型。你能猜出是哪个吗?
当您希望使用神经网络对多类分类问题进行建模时,通常最好确保将目标属性从包含每个类值的向量转换为包含每个类值的布尔值的矩阵,无论给定实例是否具有该类值。
这是一个热门编码(OHE)的松散解释。听起来很复杂,不是吗?
幸运的是,`keras`包有一个`to_categorical()`函数可以帮你完成所有这些;将`iris.trainingtarget`和`iris.testtarget`传入该函数,并将结果存储在`iris.trainLabels`和`iris.testLabels.`中
在[原教程](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)里看看这是怎么做到的。
现在,您已经正式到达了本教程中探索和预处理步骤的末尾。你现在可以继续用`keras`构建你的神经网络了!
# 构建模型
要开始构建模型,您应该首先在`keras_model_sequential()`功能的帮助下初始化一个顺序模型。然后,你就可以开始建模了。
然而,在你开始之前,最好重温一下你最初关于这个数据集的问题:你能预测某种鸢尾花的种类吗?使用数字数据更容易,您已经对数据进行了预处理,并对目标变量的值进行了热编码:一朵花的类型是 versicolor、setosa 或 virginica,这反映在二进制值`1`和`0`中。
在这种问题上表现良好的一种网络是多层感知器。这种类型的神经网络通常是完全连接的。这意味着您正在寻求构建一个完全连接的层的相当简单的堆栈来解决这个问题。至于你会用到的激活函数,出于熟悉 Keras 和神经网络的目的,这里最好用一个最常见的,就是 relu 激活函数。这个整流器激活功能用于隐藏层,一般来说这是一个好的做法。
此外,您还可以看到 softmax 激活函数用于输出层。这样做是因为您希望确保输出值在 0 和 1 的范围内,并且可以用作预测概率。
在这里尝试互动练习。
**注意**输出层如何创建 3 个输出值,每个值对应一个虹膜类别(versicolor、virginica 或 setosa)。另一方面,包含 8 个隐藏音符的第一层的`input_shape`为 4。这是因为你的训练数据`iris.training`有 4 列。
您可以使用以下功能进一步检查您的模型:
* 您可以使用`summary()`功能来打印您的模型的概要表示;
* `get_config()`将返回一个包含该型号配置的列表;
* `get_layer()`将返回图层配置。
* `layers`属性可用于检索模型图层的展平列表;
* 要列出输入张量,可以使用`inputs`属性;和
* 最后,为了检索输出张量,您可以利用`outputs`属性。
你可以在这里找到练习。
现在您已经建立了模型的架构,是时候编译并使模型适合数据了。为了编译您的模型,您用`adam`优化器和`categorical_crossentropy`损失函数配置模型。此外,您还可以通过将`'accuracy'`传递给 metrics 参数来监控训练过程中的准确性。你可以在[这个页面](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)找到代码。
如果要编译模型,优化器和损失是两个必需的参数。
使用的一些最流行的优化算法是随机梯度下降(SGD)、ADAM 和 RMSprop。根据您选择的算法,您需要调整某些参数,比如学习率或动量。损失函数的选择取决于您手头的任务:例如,对于回归问题,您通常使用均方误差(MSE)。
正如您在本例中所看到的,您使用了`categorical_crossentropy`损失函数来解决多类分类问题,即确定虹膜是属于杂色鸢尾、海滨鸢尾还是刚毛鸢尾。但是,请注意,如果您遇到了二元类分类问题,您应该使用`binary_crossentropy`损失函数。
接下来,您还可以让模型适合您的数据;在这种情况下,您在`iris.training`和`iris.trainLabels`中的所有样本上训练模型 200 个时期或迭代,每批 5 个样本。在这里查看代码。
**提示**如果你愿意,你也可以在`fit()`函数中指定详细参数。通过将该参数设置为`1`,表明您希望看到进度条日志记录。
您使用上面的代码所做的是针对指定数量的历元或对训练数据集的暴露来训练模型。一个时期是对整个训练集的一次遍历,随后是对验证集的测试。您在上面的代码中指定的批处理大小定义了将通过网络传播的样本数。此外,通过这样做,您可以优化效率,因为您确保不会同时将太多的输入模式加载到内存中。
# 可视化模型训练历史
此外,如果您将上面的 DataCamp Light 块中的代码行分配给一个变量,您也可以可视化拟合,这是一件好事。然后你可以将变量传递给`plot()`函数,就像你在[中看到的这个特殊的代码块](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)!
一定要更详细地研究这个情节。

乍一看,这一切看起来有点乱并不奇怪。你可能不完全知道你在看什么,对吗?
需要知道的一件事是,`loss`和`acc`表示训练数据的模型损失和准确性,而`val_loss`和`val_acc`是测试或验证数据的相同度量、损失和准确性。
但是,即使你知道这一点,也不容易解释这两个图表。让我们试着把它分成几个部分,这样你可能更容易理解!您将拆分这两个图,并制作两个单独的图:一个用于模型损失,另一个用于模型精度。幸运的是,您可以轻松地使用`$`操作符来访问数据并一步一步地绘制出来。
查看[这个 DataCamp 灯箱](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)来看看你如何做到这一点:

在第一个图中,您绘制了模型在训练和测试数据上的损失。现在也是[做同样的事情](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)的时候了,但是接下来为了模型的准确性:

以下是一些需要记住的事情:
* 如果您的训练数据准确性不断提高,而您的验证数据准确性却越来越差,那么您可能会过度拟合:您的模型开始只是记忆数据,而不是从中学习。
* 如果两个数据集的准确性趋势在过去几个时期仍在上升,您可以清楚地看到模型尚未过度学习训练数据集。
# 预测新数据的标签
既然您的模型已经被创建、编译并适合数据,那么是时候实际使用您的模型来预测您的测试集`iris.test`的标签了。如您所料,您可以使用`predict()`函数来完成这项工作。之后,您可以打印出混淆矩阵,在`table()`函数的帮助下检查`iris.test`数据的预测和真实标签。在这里看看是怎么做的[。](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)
你认为结果如何?乍一看,你创建的这个模型做出了正确的预测吗?
# 评估您的模型
尽管通过查看`iris.test`的预测标签,您已经对您的模型的表现有了一点了解,但花时间评估您的模型仍然很重要。使用`evaluate()`函数来完成:传入测试数据`iris.test`,测试标签`iris.testLabels`并定义批量大小。将结果存储在变量`score`中,如[中的代码示例](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)。
通过打印`score`,您将获得损失值和度量值(在本例中为`'accuracy'`)。
# 微调您的模型
微调您的模型可能是您要做的很多事情,尤其是在开始的时候,因为并不是所有的分类和回归问题都像您在本教程的第一部分中看到的那样简单。当你读上面的时候,已经有两个关键的决定你可能想要调整:你要使用多少层和你要为每个层选择多少个“隐藏单元”。
一开始,这真的会是一段很长的旅程。
除了调整历元数或批量大小之外,还有其他方法可以调整模型,希望它能有更好的表现:增加层,增加隐藏单元的数量,将你自己的优化参数传递给`compile()`函数。本节将讨论这三个选项。
如果你在你的模型中添加另一层会发生什么?如果它看起来像这样呢?
**请注意**您还可以看到这种新模型的损失和准确性指标!在[原教程](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)中尝试两个练习。

除了添加层和玩隐藏单元,你也可以试着调整你给`compile()`函数的优化算法的参数。到目前为止,您总是将一个带有字符串的向量`adam`传递给`optimizer`参数。
但那并不总是需要这样!
此外,尝试尝试其他优化算法,如随机梯度下降(SGD)。例如,尝试使用`optimizer_sgd()`功能调整学习率`lr`。你注意到效果了吗?
除了使用另一个优化器,你也可以尝试使用较小的学习率来训练你的网络。这是最常见的微调技术之一;一种常见的做法是将初始学习率设置为比您之前用来训练模型的学习率小 10 倍。
让我们再一次可视化训练历史,看看这个小调整的效果;在这里看练习[。](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)

# 保存、加载或导出您的模型
在使用`keras`包的过程中,还有最后一件事要做,那就是保存或导出您的模型,以便您可以在另一个时刻重新加载它。
* 首先,您可以很容易地使用`save_model_hdf5()`和`load_model_hdf5()`功能来保存和加载您的模型到您的工作空间:
save_model_hdf5(model, "my_model.h5")
model <- load_model_hdf5("my_model.h5")
* 此外,您还可以使用`save_model_weights_hdf5()`和`load_model_weights_hdf5()`功能保存和加载模型重量:
save_model_weights_hdf5("my_model_weights.h5")
model %>% load_model_weights_hdf5("my_model_weights.h5")
* 最后,很高兴知道您还可以将模型配置导出到 JSON 或 YAML。在这里,功能`model_to_json()`和`model_to_yaml()`将帮助你。要将配置加载回您的工作区,您只需使用`model_from_json()`和`model_from yaml()`功能:
json_string <- model_to_json(model)
model <- model_from_json(json_string) yaml_string <- model_to_yaml(model)
model <- model_from_yaml(yaml_string)

恭喜你。你已经用`keras`在 R 中完成了这个深度学习教程。这篇教程只是你深入学习 R 的旅程中的一小步;还有更多的内容要介绍!如果你还没有参加 DataCamp 的 Python 深度学习课程,你可以考虑参加。
与此同时,如果您还没有查看过 [Keras 文档](https://keras.io/)和 RStudio `[keras](https://rstudio.github.io/keras/)`文档[的话,请务必查看一下。你会找到更多关于所有函数、参数、更多层等的例子和信息…也可以看看 Franç ois Chollet 的书](https://rstudio.github.io/keras/)[“Python 深度学习”](https://www.manning.com/books/deep-learning-with-python)。所有这些资源在学习如何在 R!
*最初发表于*[*【www.datacamp.com】*](https://www.datacamp.com/community/tutorials/keras-r-deep-learning)*。*
# 使用 Hyperas 在 Google Colab 中调整 Keras 超参数
> 原文:<https://towardsdatascience.com/keras-hyperparameter-tuning-in-google-colab-using-hyperas-624fa4bbf673?source=collection_archive---------11----------------------->

Tuning Hyperparameters for your neural network can be tricky (Photo by [Anthony Roberts](https://unsplash.com/@aroberts1228?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral))
超参数调整是创建深度学习网络时计算量最大的任务之一。幸运的是,你可以使用 Google Colab 来大大加快这个过程。在这篇文章中,我将向您展示如何使用 Hyperas 调整现有 keras 模型的超参数,并在 Google Colab 笔记本中运行一切。
## 创建新笔记本并启用 GPU 运行时

Dialog to change the runtime to GPU
首先,您需要创建一个新笔记本。打开你的 [Colab 控制台](https://colab.research.google.com)并选择**新的 Python 3 笔记本。**在笔记本中,从菜单中选择**运行时**,然后**改变运行时类型。**选择硬件加速器:GPU,点击保存。这将大大加快你在笔记本上做的每一个计算。
## 安装软件包
您可以使用 *pip* 来安装新的软件包。在这种情况下,我们需要 [hyperas](https://github.com/maxpumperla/hyperas) 和[hyperpt](https://github.com/hyperopt/hyperopt)。将以下内容复制并粘贴到笔记本的第一个单元格中:
!pip install hyperas
!pip install hyperopt
当您运行单元时,您将看到 pip 正在下载和安装依赖项。
# **获取数据并创建模型**
在这篇文章中,我将使用来自 [hyperas github 页面](https://github.com/maxpumperla/hyperas)的例子。你可以在这里找到成品的 Colab 笔记本。
## **数据功能**
你需要一个数据函数来加载你的数据。它需要返回你的 X_train,Y_train,X_test 和 Y_test 值。以下是一个数据函数的示例:
> **注意:**你的数据函数需要完全按照这个顺序返回值:X_train,Y_train,X_test,Y_test。如果你使用 scikit learns[train _ test _ split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html)要小心,因为这会以不同的顺序返回值
## **模型功能**
模型函数是定义模型的地方。您可以使用所有可用的 keras 函数和层。要添加用于调优的超参数,可以使用 **{{uniform()}}** 和 **{{choice()}}** 关键字。
假设您想为您的 *batch_size* 尝试不同的值。您可以简单地编写 *batch_size={{choice([32,64,128])}}* 并且在每次试验期间,将选择并试验其中一个值。关于如何定义要调整的参数的更深入的解释可以在 [Hyperas Github 页面](https://github.com/maxpumperla/hyperas)上找到,或者你可以看看例子:
> **注意:**你的模型函数必须返回一个带有丢失键和状态键的 python 字典
# Colab 的问题
如果您现在尝试运行此示例,试验将会失败,因为 Hyperas 将无法找到您的笔记本。你需要复制你的笔记本并再次上传到你的 google drive 文件夹。幸运的是,你可以在你的笔记本里这样做,正如这个 [stackoverflow 回答](https://stackoverflow.com/questions/49920031/get-the-path-of-the-notebook-on-google-colab)中所描述的。
> **注意:**在第 16 行和第 18 行,您需要将 *HyperasMediumExample* 改为您自己的笔记本的名称
运行此单元后,系统会提示您在浏览器中打开一个网站,并将代码复制粘贴回笔记本:

The Output after you run the cell above
点击链接,用你的谷歌账户登录,将代码复制粘贴回笔记本。如果你打开左侧边栏的**文件**标签,你应该会看到一个名为< YourNotebook >的文件。ipynb
## 开始试验
现在你可以开始试验了。请注意,您必须将参数 *notebook_name* 设置为您笔记本的名称。否则试验将会失败:
运行此单元后,扫描开始,您可以在单元的输出中看到结果。
# **故障排除**
如果您在执行此操作时遇到任何问题,我建议您执行以下操作:
1. 在左侧栏中,打开**文件。**会有一个名为< YourNotebook > .ipynb 的文件,删除那个文件
2. 在菜单中选择**运行时**,然后选择**重启运行时**。
3. 重新加载页面
在您的运行时再次连接后,您可以通过从上到下运行每个单元来重新开始
# 结论
只需稍作调整,您就可以使用 Google colab 来调整 keras 网络的超参数。同样,完整的例子可以在这里找到[。](https://colab.research.google.com/drive/184Tas98M-pPQanCfTbOHRBRUeE9dtdM9#scrollTo=rdo3mScvBHF4)
# 使用 Keras 中的迁移学习为初学者提供深度学习
> 原文:<https://towardsdatascience.com/keras-transfer-learning-for-beginners-6c9b8b7143e?source=collection_archive---------0----------------------->
***本博客由三部分组成:***
1. 什么是迁移学习?
2. 为什么迁移学习效果这么好?
3. 使用迁移学习编写您的第一个图像识别器。
[***直奔 Github 上的代码。***](https://github.com/aditya9898/transfer-learning)

“galaxy with starry night” by [Bryan Goff](https://unsplash.com/@bryangoffphoto?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)
## 什么是迁移学习?
如果不是为了**迁移学习**,机器学习对于一个绝对的初学者来说是一件相当艰难的事情。在最底层,机器学习包括计算一个函数,该函数将一些输入映射到它们相应的输出。虽然函数本身只是一堆加法和乘法运算,但当通过非线性激活函数并将这些层堆叠在一起时,**函数可以用来学习任何东西**,只要有足够的数据可以学习,以及巨大的计算能力。
***欢迎来到深度学习。***
当在足够多的数据上训练时,卷积神经网络可以学习极其复杂的映射函数。我们还不能理解卷积网络是如何学习如此复杂的函数的。
在基本水平上,CNN(卷积神经网络)的权重由**过滤器**组成。把过滤器想象成一个由特定数字组成的( ***n*n)*** 矩阵。现在这个过滤器是**回旋(滑动和乘)**通过提供的图像。假设输入图像的大小为(10,10 ),滤波器的大小为(3,3 ),首先将滤波器与输入图像左上角的 9 个像素相乘,该乘法产生另一个(3,3)矩阵。该矩阵的 9 个像素值相加,该值成为 CNN**layer _ 2**左上角的单个像素值。

representation of convolutional networks
基本上,CNN 的训练包括在每个滤波器上找到正确的值,使得输入图像在通过多个层时,激活最后一层的某些神经元,从而预测正确的类别。
虽然从头开始训练 CNN 对于小项目来说是可能的,但是大多数应用程序需要训练非常大的 CNN,正如你所猜测的,这需要极其大量的处理数据和计算能力。这两者现在都不容易找到了。
这就是迁移学习发挥作用的地方。在迁移学习中,我们采用已经训练好的模型的预训练权重(该模型已经在几天内在几个高功率 GPU 上对属于 1000 个类别的数百万幅图像进行了训练),并使用这些已经学习的特征来预测新的类别。
***迁移学习的优势在于:***
***1:不需要特别大的训练数据集。***
***2:不需要太多计算能力。因为我们使用预先训练的权重,并且只需要学习最后几层的权重。***
有几个模型已经在 image net 数据集上进行了训练,并且是开源的。
比如 VGG 16,VGG 19,盗梦空间 V3 等等。有关这些型号的更多详细信息,请阅读 keras 官方文档[此处](https://keras.io/applications/)。
## 为什么迁移学习效果这么好?
为了了解为什么迁移学习如此有效,我们必须首先看看卷积神经网络的不同层真正在学习什么。
当我们在图像数据集上训练深度卷积神经网络时,在训练过程中,通过在每层的图像上应用几个过滤器,图像穿过网络。滤波器矩阵的值与每层图像的激活相乘。来自最终层的激活用于找出图像属于哪一类。
当我们训练一个深度网络时,我们的目标是找到每个滤波器矩阵的最优值,这样当一个图像通过网络传播时,输出激活可以用来准确地找到图像所属的类别。用于找到这些滤波器矩阵值的过程是梯度下降。
当我们在 imagenet 数据集上训练一个 conv 网络,然后看看 conv 网络每一层上的过滤器已经学会识别什么,或者每个过滤器被什么激活时,我们能够看到一些真正有趣的事情。

conv 网前几层的过滤器学会识别颜色和某些水平线和垂直线。
接下来的几层慢慢学会使用前几层学到的线条和颜色来识别微小的形状。
然后下一层学习识别纹理,然后像腿,眼睛,鼻子等物体的一部分。
最后,最后一层的过滤器被整个物体激活,比如狗、汽车等等。

现在让我们开始转移学习。它工作得如此好的原因是,我们使用了一个在 imagenet 数据集上预先训练的网络,这个网络已经学会了在其初始层中识别不同对象的微小形状和小部分。通过使用预训练网络进行迁移学习,我们只需在预训练网络的末端添加几个密集层,并了解这些已学习特征的组合有助于识别新数据集中的对象。
因此,我们只训练几个密集层。此外,我们正在使用这些已经学习的琐碎特征的组合来识别新的对象。所有这些有助于使训练过程非常快,并且与从头开始训练 conv 网络相比,需要非常少的训练数据。
# 现在让我们使用 Keras 中的迁移学习建立一个实际的图像识别模型。
我们将在这里使用的模型是 MobileNet。
移动网是一种给出相当好的图像网分类精度并且占用非常少空间的模型。(根据 keras 文档显示为 17 MB)。
**所需依赖关系:**
* Keras(带 tensorflow 后端)
* Numpy
* Matplotlib
* 熊猫
**数据要求:**
* 训练数据必须以特定的格式存储,以便输入网络进行训练。我们将使用 keras 中提供的 ImageDataGenerator 来根据可用数据训练我们的模型。这样,这个过程在代码方面就变得简单多了。
* 必须有一个主数据文件夹,在该数据文件夹中,必须有一个包含相应图像的每类数据的文件夹。文件夹的名称必须是它们各自的类名。
**模型的建立分三步走:**
1. 导入预训练模型并添加密集层。
2. 正在将列车数据加载到 ImageDataGenerators 中。
3. 培训和评估模型。
**<开始编码/ >**
首先加载依赖项。
然后导入预先训练好的 MobileNet 模型。Mobilenet(在 imagenet 数据集上训练了一千个类)将具有由 1000 个神经元组成的最后一层(每个类一个)。我们希望在网络的最后一层有多少神经元,就有多少我们希望识别的类别。因此,我们放弃了 1000 个神经元层,并为网络添加了我们自己的最后一层。
这可以通过在导入模型时设置( *IncludeTop=False* )来实现。
因此,假设你想训练一个狗品种分类器来识别 120 个不同的品种,我们需要在最后一层有 120 个神经元。这可以使用下面的代码来完成。
*这是* ***流程的第 1 步*** *。导入和构建所需的模型。*
我们导入没有最后一层的 MobileNet 模型,并添加一些密集层,以便我们的模型可以学习更复杂的函数。密集层必须具有 relu 激活功能,并且最后一层必须具有 softmax 激活,该层包含与类的数量一样多的神经元。
接下来,我们根据我们提供的架构制作一个模型。
为了检查我们模型的架构,我们只需要使用下面给出的这行代码。
现在我们有了模型,因为我们将使用预训练的权重,我们的模型已经在其上训练过(imagenet 数据集),我们必须将所有权重设置为不可训练的。我们将只训练我们以前制作的最后的密集层。下面给出了执行此操作的代码。
现在我们进入流程的 ***步骤 2*** ,将训练数据加载到 ImageDataGenerator 中。
ImageDataGenerators 内置在 keras 中,帮助我们训练模型。我们只需指定训练数据的路径,它就会自动批量发送训练数据。这使得代码更加简单。
为此,我们需要博客前面提到的特定格式的训练数据。
接下来我们进入 ***步骤 3*** ,在数据集上训练模型。
为此,我们首先编译我们制作的模型,然后用我们的生成器训练我们的模型。这可以使用下面的代码来完成。
有了这个,我们就训练出了一个模型。然后,通过使用 model.predict(new_image ),训练好的模型可用于预测新的看不见的图像属于哪一类。
[***获取 Github 上的代码。***](https://github.com/aditya9898/transfer-learning)
一如既往,快乐学习。
# Keras 教程:Python 中的深度学习
> 原文:<https://towardsdatascience.com/keras-tutorial-deep-learning-in-python-2caf497f8ca1?source=collection_archive---------4----------------------->
*原载于*[*https://www . data camp . com/community/tutorials/deep-learning-python*](https://www.datacamp.com/community/tutorials/deep-learning-python)
现在,你可能已经知道机器学习,这是计算机科学的一个分支,研究可以学习的算法的设计。今天,你们将关注深度学习,这是机器学习的一个子领域,是一套受大脑结构和功能启发的算法。这些算法通常被称为人工神经网络(ANN)。深度学习是数据科学中最热门的领域之一,在机器人、图像识别和人工智能(AI)方面有许多案例研究,取得了令人惊叹的成果。
一些你可能已经知道的成功故事是自动驾驶汽车、自动玩游戏(想想玩棋盘游戏围棋的 [AlphaGo](https://deepmind.com/research/alphago/) )、手写生成、…
用于开发和评估深度学习模型的最强大和易用的 Python 库之一是 Keras 它包装了高效的数值计算库 ano 和 TensorFlow。这样做的好处主要是,你可以用一种简单有趣的方式开始学习神经网络。
今天的 Keras 初学者教程将向您介绍 Python 深度学习的基础:一步一步地,该教程将向您展示如何使用 Python 及其库来探索您的数据,为分类和回归任务建立多层感知器,编译数据并使其符合这些模型,预测目标值并验证您已经建立的模型。
你想参加关于 Keras 和 Python 深度学习的课程吗?可以考虑上 DataCamp 的[深度学习中的 Python](https://www.datacamp.com/courses/deep-learning-in-python) 课程!
此外,不要错过我们的 [Keras 备忘单](https://www.datacamp.com/community/blog/keras-cheat-sheet),它通过代码示例向您展示了用 Python 构建神经网络需要经历的六个步骤!
在深入研究 Keras 以及如何使用它开始 Python 深度学习之前,您可能应该对神经网络略知一二。正如您在上一节中简要阅读的那样,神经网络找到了它们的灵感和生物学,其中术语“神经网络”也可以用于神经元。人脑就是这种神经网络的一个例子,它由许多神经元组成。
众所周知,大脑能够进行非常复杂的计算,这也是人工神经网络的灵感来源。网络作为一个整体是一个强大的建模工具。
最简单的神经网络是“感知器”,其最简单的形式是由单个神经元组成。非常像具有树突和轴突的生物神经元,单个人工神经元是简单的树形结构,其具有输入节点和连接到每个输入节点的单个输出节点。以下是两者的直观对比:

从图中可以看出,人工神经元有六个组成部分。从左到右,它们是:
1. **输入节点**。碰巧的是,每个输入节点都与一个数值相关联,这个数值可以是任何实数。记住实数构成了所有的数字:它们可以是正数或负数,整数或小数。
2. **人脉**。类似地,每个离开输入节点的连接都具有与之相关联的权重,并且这也可以是任何实数。
3. 接下来,输入节点的所有值和连接的权重被集合在一起:它们被用作一个**加权和** : y = f(sum_{i=1}^{D} w_i*x_i)的输入,或者换句话说,y = f(w_1*x_1 + w_2*x_2 + … w_D*x_D)。
4. 该结果将作为**转移或激活功能**的输入。在最简单但平凡的情况下,这个传递函数是一个恒等函数,f(x)=x,或者换句话说,y=x。在这种情况下,\(x\)是输入节点和连接的加权和。然而,就像生物神经元只有在超过某个阈值时才会触发一样,人工神经元也只有在输入的总和超过某个阈值时才会触发,比如说 0。这是你在标识函数中找不到的东西!人们能想到的最直观的方法是设计一个如下的系统:f(x) = 0 如果 x<0;如果 x=0,f(x)= 0.5;如果 x > 0,f(x) = 1。
5. 当然,你已经可以想象输出不会是一条平滑的线:它将是一个不连续的函数。因为这会在数学处理中引起问题,所以经常使用连续变量,即 sigmoid 函数。你可能已经知道的 sigmoid 函数的一个例子是逻辑函数。使用这个函数会产生更平滑的结果!
6. 因此,您有了**输出节点**,它与输入节点的加权和的函数(如 sigmoid 函数)相关联。注意,sigmoid 函数是一个数学函数,它会产生一条“S”形曲线;稍后你会读到更多相关内容。
7. 最后,感知器可能是一个额外的参数,称为**偏差**,实际上您可以将它视为与永久设置为 1 的额外输入节点相关联的权重。偏差值很重要,因为它允许你将激活函数向左或向右移动,这可以决定你学习的成功与否。
请注意,这个模型的逻辑结果是,感知器只处理数字数据。这意味着您应该将任何名义数据转换成数字格式。
既然您已经知道感知器与阈值一起工作,那么将它们用于分类目的的步骤就不远了:感知器可以同意,高于某个阈值的任何输出都表明一个实例属于一个类,而低于阈值的输出可能导致输入成为另一个类的成员。输出等于阈值的直线就是两个类之间的边界。

感知器的网络是多层感知器,这是本教程将在 Keras 的帮助下用 Python 实现的!多层感知器也被称为“前馈神经网络”。正如你现在已经猜到的,这些是比感知器更复杂的网络,因为它们由多层组织的多个神经元组成。层数通常限制在两三层,但理论上是没有限制的!
这些层的行为非常像你在上面读到的生物神经元:一层的输出作为下一层的输入。
在这些层中,您可以区分输入层、隐藏层和输出层。多层感知器通常是全连接的。这意味着某一层中的每个感知器与下一层中的每个感知器之间存在连接。即使连通性不是必需的,这也是典型的情况。
请注意,虽然感知器只能表示类之间的线性分离,但多层感知器克服了这一限制,还可以表示更复杂的决策边界。
对于本教程,您将使用葡萄酒质量数据集,您可以在 UCI 机器学习知识库的葡萄酒质量数据集中找到该数据集。理想情况下,您在较大的数据集上执行深度学习,但出于本教程的目的,您将利用较小的数据集。这主要是因为目标是让您开始使用这个库,并熟悉神经网络的工作方式。
你可能已经知道这个数据集,因为它是开始学习如何解决机器学习问题的最流行的数据集之一。在这种情况下,它将为您使用 Keras 开始深度学习 Python 提供服务。
我们现在就开始吧!
然而,在开始加载数据之前,检查一下您对葡萄酒的了解程度可能是个好主意(当然是与数据集相关的)。你们大多数人都知道,一般来说,有两种非常受欢迎的葡萄酒:红葡萄酒和白葡萄酒。
(我确信还有很多其他的,但为了简单起见,也因为我对葡萄酒的了解有限,我就只说这些了。如果让你们当中真正的鉴赏家失望了,我很抱歉:)。
知道这些已经是一件事了,但是如果你想分析这些数据,你需要知道更多一点。
首先,检查数据描述文件夹,查看包含了哪些变量。这通常是理解数据的第一步。前往[本页](http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality.names)查看描述或继续阅读以更好地了解您的数据。
该数据由两个数据集组成,分别与葡萄牙“Vinho Verde”葡萄酒的红色和白色变种相关。如描述中所述,你只会发现物理化学和感官变量包含在这个数据集中。数据描述文件仅列出了数据中包含的 12 个变量,但对于像我一样不是真正的化学专家的人,这里有每个变量的简短描述:
1. *固定酸度*:酸是葡萄酒的主要特性,对葡萄酒的味道有很大的贡献。通常,总酸度分为两组:挥发性酸和非挥发性或固定酸。葡萄酒中的固定酸有以下几种:酒石酸、苹果酸、柠檬酸和琥珀酸。该变量在数据集中以 g(酒石酸)/dm 表示。
2. *挥发酸度*:挥发酸度基本上就是酒变成醋的过程。在美国,红餐酒和白餐酒的挥发性酸度法定上限分别为 1.2 克/升和 1.1 克/升。在这些数据集中,挥发性酸度以 g(乙酸)/dm 表示。
3. 柠檬酸是葡萄酒中的一种固定酸。在两个数据集中用 g/dm 表示。
4. *残糖*一般指发酵停止后剩余的糖,或被停止。在`red`和`white`数据中用 g/dm 表示。
5. 氯化物是葡萄酒中咸味的主要来源。在这里,你会看到它是用 g(氯化钠)/dm 表示的。
6. *游离二氧化硫*:添加到葡萄酒中并流失到其中的那部分二氧化硫称为结合态,而活性部分则称为游离态。酿酒师总是试图获得最高比例的游离硫来结合。该变量在数据中以 mg/dm 表示。
7. *总二氧化硫*是结合态和游离态二氧化硫(SO2)的总和。在这里,它是用毫克/分米表示的。葡萄酒中的硫含量有法律限制:在欧盟,红葡萄酒只能有 160 毫克/升,而白葡萄酒和玫瑰葡萄酒可以有大约 210 毫克/升。甜葡萄酒允许有 400 毫克/升。在美国,法律限制是 350 毫克/升,在澳大利亚,这是 250 毫克/升
8. *密度*通常用于衡量糖向酒精的转化。这里,用 g/cm 表示。
9. *pH* 或氢的潜力是一个数字标度,用来表示葡萄酒的酸度或碱度。你可能知道,pH 值小于 7 的溶液是酸性的,而 pH 值大于 7 的溶液是碱性的。pH 值为 7 的纯水是中性的。大多数葡萄酒的 pH 值在 2.9 到 3.9 之间,因此是酸性的。
10. 硫酸盐对于葡萄酒就像面筋对于食物一样。你可能已经知道亚硫酸盐会引起头痛。它们是世界各地酿酒的常规部分,被认为是必不可少的。在这种情况下,它们用 g(硫酸钾)/dm 表示。
11. 酒精:葡萄酒是一种酒精饮料,正如你所知道的,酒精含量会因酒而异。这个变量包含在数据集中,并以% vol 表示,这并不奇怪。
12. *品质*:葡萄酒专家给葡萄酒质量打分,在 0(非常差)到 10(非常优秀)之间。最终的数字是由相同的葡萄酒专家做出的至少三个评价的中间值。
当然,这都是一些非常基本的信息,你可能需要知道开始。如果你是一个真正的葡萄酒鉴赏家,你可能知道所有这些,甚至更多!
现在,tt 是时候得到你的数据了!
这可以通过 Python 数据操作库 Pandas 轻松完成。您遵循导入惯例,在别名`pd`下导入包。
接下来,使用`read_csv()`函数读入存储数据的 CSV 文件。此外,使用`sep`参数指定本例中的分隔符是分号,而不是普通的逗号。
你可以在[这个 DataCamp Light chunk](https://www.datacamp.com/community/tutorials/deep-learning-python) 里试试。
厉害!那不是小菜一碟,不是吗?
到目前为止,你可能已经这样做了一百万次,但是这总是开始的必要步骤。现在,您完全可以开始探索、操作和建模您的数据了!
有了手头的数据,你很容易对这些酒有更多的了解!在本练习中,你可能想做的第一件事就是快速浏览你的两个数据帧。
现在是检查您的导入是否成功的时候了:仔细检查数据是否包含 UCI 机器学习存储库的数据描述文件向您承诺的所有变量。除了变量的数量,还要检查导入的质量:数据类型是否正确?所有的行都通过了吗?当你清理数据的时候,有什么空值需要考虑的吗?
除了`info()`之外,您可能还想检查您的数据。你可以在[这个练习](https://www.datacamp.com/community/tutorials/deep-learning-python)中完成。
简要回顾一下所有这些熊猫功能:你会发现`head()`、`tail()`和`sample()`非常棒,因为它们为你提供了一种快速检查数据的方式,没有任何麻烦。
接下来,`describe()`提供了一些关于您的数据的汇总统计,可以帮助您评估您的数据质量。你可以看到一些变量的`min`和`max`值有很大的不同。这是您稍后要处理的事情,但是此时,意识到这一点非常重要。
最后,在`isnull()`的帮助下,您已经仔细检查了`red`中是否存在空值。当你在阅读了`info()`的结果后仍有疑问时,这个函数总是能派上用场。
**提示**:还要检查葡萄酒数据是否包含空值。您可以通过使用 DataCamp Light chunk 的 IPython shell 来实现这一点,正如您在上面看到的。
既然您已经检查了您的数据以查看导入是否成功和正确,那么是时候更深入一点了。
一种方法是查看数据集变量的分布,并制作散点图来查看可能的相关性。当然,如果您将这些数据用于您自己的项目,您可以将这一切提升到一个更高的水平。
乍一看,你可能会觉得有趣的一个变量是`alcohol`。当你检查一个葡萄酒数据集时,这可能是最先引起你注意的事情之一。您可以使用任何数据可视化库来可视化分布,但是在这种情况下,本教程使用`matplotlib`来快速绘制分布。你可以在这里找到代码。
正如你在下图中看到的,你会发现红葡萄酒和白葡萄酒的酒精含量基本相同:它们的酒精含量都在 9%左右。当然,也有相当数量的观测值具有 10%或 11%的酒精百分比。

注意,如果您使用`numpy`包中的`histogram()`函数来计算`white`和`red`数据的直方图,您可以仔细检查这一点。你可以在这里找到代码。
如果你对`matplotlib`教程感兴趣,请务必查看 DataCamp 的 [Matplotlib](https://www.datacamp.com/community/tutorials/matplotlib-tutorial-python) 初学者教程和[查看 3D 体积数据](https://www.datacamp.com/community/tutorials/matplotlib-3d-volumetric-data)教程,它们向你展示了如何使用 Matplotlib 的事件处理程序 API。
接下来,我感兴趣的一件事是硫酸盐和葡萄酒质量之间的关系。正如你在上面读到的,硫酸盐会让人头疼,我想知道这是否会影响葡萄酒的质量。更有甚者,我经常听说女人特别不愿意喝酒正是因为它会引起头痛。也许这影响了红酒的收视率?
我们来看看:这里可以找到代码[。](https://www.datacamp.com/community/tutorials/deep-learning-python)
正如你在下图中看到的,红葡萄酒似乎比白葡萄酒含有更多的硫酸盐,白葡萄酒含有的硫酸盐少于 1 克/分米。对于白葡萄酒来说,似乎只有几个例外略高于 1 g/\(dm \ ),而对于红葡萄酒来说,这肯定更多。这也许可以解释为什么人们普遍认为红酒会让人头疼,但是红酒的质量如何呢?
你可以清楚地看到,有一种硫酸盐含量相对较低的白葡萄酒得到了 9 分,但对于其他葡萄酒,在这一点上很难正确解读数据。
当然,你需要考虑到观察结果的差异也会影响图表以及你可能如何解读它们。

除了硫酸盐,酸度是葡萄酒的主要和重要的特征之一,是获得优质葡萄酒的必要条件。好的葡萄酒通常能平衡酸度、单宁、酒精和甜味。更多的研究告诉我,0.2 到 0.4 克/升的挥发性酸度不会影响葡萄酒的质量。然而,在更高的浓度下,挥发性的酸度会给葡萄酒带来强烈的酸味。极度易挥发的酸度表明葡萄酒有严重缺陷。
让我们对数据进行测试,并制作一个散点图,绘制酒精与挥发性酸度的关系。数据点应根据其等级或`quality`标签进行着色。你可以在这里找到代码和练习。
请注意,该图像中的颜色是在 NumPy `random`模块的帮助下随机选择的。您总是可以通过向`redcolors`或`whitecolors`变量传递一个列表来改变这一点。确保它们是相同的(除了 1,因为白葡萄酒数据比红葡萄酒数据多一个唯一的`quality`值),否则你的图例就不匹配了!
点击此处查看完整图表:

在上图中,你可以看到你在上面读到的水平尤其适用于白葡萄酒:大多数标签为 8 的葡萄酒具有 0.5 或更低的挥发性酸度水平,但它是否对质量有影响很难说,因为所有的数据点都非常密集地集中在图表的一侧。
这只是一个快速的数据探索。如果您有兴趣在自己的项目中详细阐述这一步骤,请考虑 DataCamp 的数据探索帖子,如 [Python 探索性数据分析](https://www.datacamp.com/community/tutorials/exploratory-data-analysis-python)和 [Python 数据剖析](https://www.datacamp.com/community/tutorials/python-data-profiling)教程,它们将指导您了解 EDA 的基础知识。
这可能需要消化很多内容,所以稍微回顾一下您在 EDA 过程中所看到的内容永远不会太晚,这对本教程的后续课程可能很重要:
* 数据集的一些变量的值相差很大。您可以在本教程的下一部分中处理这个问题。
* 您有一个理想的场景:数据集中没有空值。
* 数据集中包含的大多数葡萄酒的酒精含量在 9%左右。
* 红葡萄酒似乎比白葡萄酒含有更多的硫酸盐,白葡萄酒的硫酸盐含量低于 1 克/干重。
* 你看到大多数葡萄酒的波动酸度在 0.5 及以下。目前,这与葡萄酒的质量没有直接关系。
到目前为止,您已经分别查看了白葡萄酒和红葡萄酒的数据。当你近距离观察一些变量时,这两者似乎有些不同,而在其他情况下,这两者似乎非常相似。你认为有没有一种方法可以根据变量将条目分为白葡萄酒或红葡萄酒?
只有一种方法可以找到答案:对数据进行预处理,并以这样的方式建模,以便您可以看到会发生什么!
既然您已经探索了您的数据,是时候根据您获得的见解采取行动了!让我们对数据进行预处理,以便您可以开始构建自己的神经网络!
要看代码,去[原教程](https://www.datacamp.com/community/tutorials/deep-learning-python)。
在这种情况下,您将`ignore_index`设置为`True`,因为您不希望在将数据追加到`red`时保留`white`的索引标签:您希望标签从它们在`red`中停止的地方继续,而不是将两个数据集连接在一起的重复索引标签。
现在你有了完整的数据集,做一个快速的数据探索是一个好主意;通过分别查看这两个数据集,您已经知道了一些东西,现在是时候收集一些更可靠的见解了。
由于解释图表可能有些困难,所以绘制相关矩阵也是一个好主意。这将更快地给出关于哪些变量相关的见解。你可以在这里找到代码。
如你所料,有一些变量是相关的,比如`density`和`residual sugar`。此外,`volatile acidity`和`type`的联系比你最初通过分别查看这两个数据集所能猜到的更加紧密,而且`free sulfur dioxide`和`total sulfur dioxide`会有关联也是意料之中的事情。

很有意思!
不平衡数据通常指的是分类问题,其中类别没有被平等地表示。大多数分类数据集在每个类中的实例数量并不完全相等,但是微小的差异通常并不重要。因此,您需要确保所有两类葡萄酒都出现在训练模型中。此外,所有两种葡萄酒类型的实例数量需要大致相等,这样您就不会在预测中偏向某一类。
在这种情况下,似乎有一个不平衡,但你会暂时这样做。之后,您可以评估模型,如果它表现不佳,您可以求助于欠采样或过采样来掩盖观察结果的差异。
现在,从`sklearn.model_selection`导入`train_test_split`,并将数据和目标标签分配给变量`X`和`y`。您将看到,您需要展平目标标签的数组,以便完全准备好使用`X`和`y`变量作为`train_test_split()`函数的输入。开始工作,从[这个数据营的小块](https://www.datacamp.com/community/tutorials/deep-learning-python)开始。
你已经在建立你的第一个神经网络的路上了,但是还有一件事你需要注意!你还知道你在查看`white`和`red`数据集的摘要时发现了什么吗?
事实上,有些价值观相差甚远。在这里做一些标准化可能是有意义的。
标准化是处理这些相距甚远的价值观的一种方式。scikit-learn 包为您提供了一种快速标准化数据的方法:从`sklearn.preprocessing`导入`StandardScaler`模块,您就可以缩放您的训练和测试数据了!
Import StandardScaler
from sklearn.preprocessing
from sklearn.preprocessing import StandardScaler # Define the scaler
scaler = StandardScaler().fit(X_train) # Scale the train set
X_train = scaler.transform(X_train) # Scale the test set
X_test = scaler.transform(X_test)
既然您的数据已经过预处理,那么您可以继续进行真正的工作:构建您自己的神经网络来对葡萄酒进行分类。
在你开始建模之前,回到你最初的问题:你能通过观察葡萄酒的化学性质,如挥发性酸度或硫酸盐,来预测它是红还是白吗?
因为你只有两个类,即白色和红色,你要做一个二进制分类。你可以想象,“二进制”意味着 0 或 1,是或否,由于神经网络只能处理数值数据,所以你已经将红色编码为 1,白色编码为 0。
在这种问题上表现良好的一种网络是多层感知器。正如你在本教程开始时所读到的,这种类型的神经网络通常是完全连接的。这意味着您正在寻求构建一个完全连接的层的相当简单的堆栈来解决这个问题。至于你会用到的激活函数,出于熟悉 Keras 和神经网络的目的,这里最好用一个最常见的,就是 relu 激活函数。
现在你如何开始建立你的多层感知器?快速入门的方法是使用 Keras 顺序模型:它是层的线性堆栈。您可以通过向构造函数传递一个层实例列表来轻松地创建模型,这是通过运行`model = Sequential()`来设置的。
接下来,最好回想一下多层感知器的结构,就像你在本教程开始时读到的那样:你有一个输入层,一些隐藏层和一个输出层。当你制作模型时,考虑到你的第一层需要使输入形状清晰是很重要的。模型需要知道预期的输入形状,这就是为什么在这些层的文档和这些层的实际示例中,您总是会找到`input_shape`、`input_dim`、`input_length`或`batch_size`参数。
在这种情况下,你将不得不使用一个`Dense`层,这是一个完全连接的层。密集层实现如下操作:`output = activation(dot(input, kernel) + bias)`。请注意,如果没有激活函数,您的稠密层将只包含两个线性操作:点积和加法。
在第一层中,`activation`参数取值为`relu`。接下来,您还会看到`input_shape`已经被定义。这是您刚刚看到的操作的`input`:模型将形状`(12,)`或`(*, 12)`作为输入数组。最后,您会看到第一层将`12`作为`Dense()`的`units`参数的第一个值,这是输出空间的维度,实际上是 12 个隐藏单元。这意味着模型将输出形状为`(*, 12)`的数组:这是输出空间的维度。如果您现在还没有完全理解,请不要担心,稍后您会读到更多相关内容!
`units`实际上代表上述公式的`kernel`或层创建的权重矩阵,由给予所有输入节点的所有权重组成。请注意,在下面的示例中,您没有包含任何偏差,因为您没有包含`use_bias`参数并将其设置为`TRUE`,这也是一种可能性。
中间层也使用`relu`激活功能。这一层的输出将是形状`(*,8)`的数组。
您将使用大小为 1 的`Dense`层结束网络。最后一层也将使用一个 sigmoid 激活函数,这样你的输出实际上是一个概率;这意味着这将产生一个介于 0 和 1 之间的分数,表明样品具有目标“1”的可能性有多大,或者葡萄酒是红色的可能性有多大。
你可以在这里找到代码和练习[。](https://www.datacamp.com/community/tutorials/deep-learning-python)
总之,您会看到,在构建模型时,您需要做出两个关键的架构决策:您将使用多少层,以及您将为每层选择多少个“隐藏单元”。
在这种情况下,你为模型的第一层选择了`12`个隐藏单元:正如你在上面读到的,这是输出空间的维度。换句话说,当网络学习表示法时,你设置了你允许网络拥有的自由度。如果您允许更多的隐藏单元,您的网络将能够学习更复杂的表示,但这也将是一个更昂贵的操作,容易过度拟合。
请记住,当模型过于复杂时,过度拟合就会发生:它将描述随机误差或噪声,而不是它需要描述的基本关系。换句话说,训练数据建模得太好了!
请注意,当您没有那么多可用的训练数据时,您应该更喜欢使用具有很少隐藏层的小型网络(通常只有一个,就像上面的示例)。
如果你想获得一些关于你刚刚创建的模型的信息,你可以使用属性化的`output_shape`或者`summary()`函数,等等。下面列出了一些最基本的方法。
试着运行它们,看看你到底得到了什么结果,以及它们告诉了你关于你刚刚创建的模型的什么信息。点击进入练习[。](https://www.datacamp.com/community/tutorials/deep-learning-python)
接下来,是时候编译你的模型并使模型符合数据了:再一次,利用`compile()`和`fit()`来完成这项工作。
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, y_train,epochs=20, batch_size=1, verbose=1)
在编译中,用`adam`优化器和`binary_crossentropy`损失函数配置模型。此外,您还可以通过将`['accuracy']`传递给`metrics`参数来监控训练过程中的准确性。
`optimizer`和`loss`是编译模型时需要的两个参数。使用的一些最流行的优化算法是随机梯度下降(SGD)、ADAM 和 RMSprop。根据您选择的算法,您需要调整某些参数,比如学习率或动量。损失函数的选择取决于您手头的任务:例如,对于回归问题,您通常使用均方误差(MSE)。正如你在这个例子中看到的,你使用了`binary_crossentropy`来解决二元分类问题,即确定一款葡萄酒是红葡萄酒还是白葡萄酒。最后,通过多类分类,您将利用`categorical_crossentropy`。
之后,您可以在`X_train`和`y_train`中的所有样本上训练模型 20 个历元或迭代,每批 1 个样本。您也可以指定`verbose`参数。通过将它设置为`1`,表明您希望看到进度条日志记录。
换句话说,您必须针对特定数量的历元或对训练数据集的暴露来训练模型。一个时期是对整个训练集的一次遍历,随后是对验证集的测试。您在上面的代码中指定的批处理大小定义了将通过网络传播的样本数。此外,通过这样做,您可以优化效率,因为您确保不会同时将太多的输入模式加载到内存中。
让我们使用您的模型吧!你可以用它来预测测试集的标签。只需使用`predict()`并将测试集传递给它,以预测数据的标签。在这种情况下,结果存储在`y_pred`中:
y_pred = model.predict(X_test)
在你去评估你的模型之前,你已经可以通过检查`y_pred`和`y_test`的比较来快速了解精确度:
y_pred[:5]
array([[0], [1], [0], [0], [0]], dtype=int32)
y_test[:5]
array([0, 1, 0, 0, 0])
你可以看到这些值似乎加起来了,但是如果没有一些硬数字,所有这些又是什么呢?
现在,您已经构建了模型,并使用它对模型尚未看到的数据进行预测,是时候评估它的性能了。您可以直观地将预测与实际测试标签进行比较(`y_test`),或者您可以使用所有类型的指标来确定实际性能。在这种情况下,您将使用`evaluate()`来完成这项工作。传入测试数据和测试标签,如果需要,将`verbose`参数设为 1。当你这样做的时候,你会看到更多的日志出现。
score = model.evaluate(X_test, y_test,verbose=1)
print(score)
[0.025217213829228164, 0.99487179487179489]
分数是一个包含损失和准确性的列表。在这种情况下,你会发现两者似乎都很好,但在这种情况下,最好记住你的数据有些不平衡:你观察到的白葡萄酒比红葡萄酒多。精确度可能只是反映了数据的类别分布,因为它只是预测`white`,因为这些观察值大量存在!
在您开始重新安排数据并以不同的方式将其放在一起之前,尝试不同的评估指标总是一个好主意。为此,您可以依赖 scikit-learn(您将其导入为`sklearn`,就像之前您创建训练集和测试集一样)。
在这种情况下,您将测试一些基本的分类评估技术,例如:
* 混淆矩阵,将预测分解成一个表格,显示正确的预测和错误预测的类型。理想情况下,你只会看到对角线上的数字,这意味着你所有的预测都是正确的!
* 精度是对分类器准确性的度量。精度越高,分类器就越准确。
* 召回是对分类器完整性的一种度量。召回率越高,分类器覆盖的案例就越多。
* F1 分数或 F 分数是精确度和召回率的加权平均值。
* Kappa 或 Cohen's kappa 是通过数据中类别的不平衡进行标准化的分类准确度。
Import the modules from sklearn.metrics
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, cohen_kappa_score # Confusion matrix
confusion_matrix(y_test, y_pred)
array([[1585, 3], [ 8, 549]]) # Precision
precision_score(y_test, y_pred)
0.994565217391 # Recall
recall_score(y_test, y_pred)
0.98563734290843807 # F1 score
f1_score(y_test,y_pred)
0.99008115419296661 # Cohen's kappa
cohen_kappa_score(y_test, y_pred)
0.98662321692498967
这些成绩都很不错!尽管事实上你有相当多的白葡萄酒类型的行,你还是做了一个相当精确的模型。
干得好!
您已经成功地构建了您的第一个模型,但是您可以使用这个模型走得更远。为什么不试试下面这些东西,看看它们的效果如何?正如您在上面读到的,您需要做出的两个关键架构决策涉及到层和隐藏节点。这些都是很好的起点:
* 您使用了 1 个隐藏层。尽量用 2、3 个隐藏层;
* 使用隐藏单元较多或较少的图层;
* 将`quality`列作为目标标签,其余的数据(包括编码后的`type`列!)作为你的数据。你现在有一个多类分类问题!
但是为什么不试着改变激活函数呢?代替 relu,尝试使用 tanh 激活函数,看看结果是什么!

您的分类模型在第一次运行时表现完美!
但是除了更上一层楼,尝试比多层感知器更复杂的结构之外,你还可以做更多的事情。为什么不试着做一个神经网络来预测酒的质量呢?
在这种情况下,本教程假设`quality`是一个连续变量:那么这个任务就不是一个二元分类任务,而是一个有序回归任务。这是一种用于预测序数变量的回归类型:`quality`值存在于任意尺度上,其中不同的`quality`值之间的相对排序是显著的。在这个等级中,质量等级 0-10 代表“非常差”到“非常好”就是这样一个例子。
请注意,您也可以将这类问题视为分类问题,并将质量标签视为固定类别标签。
**要了解如何使用神经网络解决回归问题,请访问** [**原始教程**](https://www.datacamp.com/community/tutorials/deep-learning-python) **。**
本教程只是您深入学习 Python 和 Keras 之旅的开始。还有很多要讲,为什么不上 DataCamp 的[深度学习用 Python](https://www.datacamp.com/courses/deep-learning-in-python) 的课程呢?同时,如果您还没有查看过 [Keras 文档](https://keras.io/),请务必查看。你会找到更多关于所有函数、参数、更多层等的例子和信息。当你学习如何在 Python 中使用神经网络时,这无疑是一个不可或缺的资源!
*原载于*[*www.datacamp.com*](https://www.datacamp.com/community/tutorials/deep-learning-python)*。*
# 核函数
> 原文:<https://towardsdatascience.com/kernel-function-6f1d2be6091?source=collection_archive---------0----------------------->

最近,我读了一些关于机器学习的资料,而内核恰好是分类问题的一个有趣部分,在我继续之前,这个主题是由[艾伦](https://medium.com/u/1d2f805e8419?source=post_page-----6f1d2be6091--------------------------------)、[自己动手为机器人开发者做 NLP](https://medium.com/lastmile-conversations/do-it-yourself-nlp-for-bot-developers-2e2da2817f3d#.smuhw16q3)写的一篇文章启发的。谢谢 a。
# 什么是核函数?
要说内核,我们需要了解类似[**SVM**](https://en.wikipedia.org/wiki/Support_vector_machine) (支持向量机)——**分类** - **监督学习** - **机器学习**-等等等等等等。这么多术语,对吗?,但不要因此而气馁(在 DIY 练习之前,我对这些一无所知)。让我们一起走进去吧
*那么到底什么是“机器学习(ML)”*?事实证明,ML 实际上是一大堆东西,但最重要的主题可以用阿瑟·塞缪尔早在 1959 年就说过的一句话来概括:
*“机器学习(Machine Learning)是在没有被* ***明确*** *编程的情况下,赋予计算机学习能力的研究领域。”*
> *一个计算机程序被说成是从* ***经验中学习*** *E 关于某些* ***任务*** *T 和某些* ***性能度量*** *P,如果它在 T 上的性能,如由 P 所度量的,随着经验 E 而提高”——汤姆·米切尔,卡内基梅隆大学*
因此,如果你希望你的程序预测,例如,一个繁忙的十字路口的交通模式(任务 T),你可以通过一个机器学习算法来运行它,该算法具有关于过去交通模式的数据(经验 E),如果它已经成功“学习”,那么它将在预测未来交通模式方面做得更好(性能指标 P)。
在不同类型的 ML 任务中,我们称之为**监督学习(SL)。**在这种情况下,你可以输入一些你已经知道答案的数据(例如,为了预测一只狗是否是一个特定的品种,我们输入了数百万条狗的信息/属性,如类型、身高、肤色、体毛长度等。在 ML 行话中,这些属性被称为“特性”。这些特征列表中的单个条目是一个数据实例,而所有内容的集合是训练数据,这些数据形成了你预测的基础,即如果你知道特定狗的肤色、体毛长度、身高等,那么你就可以预测它可能属于哪个品种。
> 在我们进入内核之前,我们需要理解什么是支持向量机。支持向量机或 SVM 是具有相关学习[算法](https://en.wikipedia.org/wiki/Algorithm)的监督学习模型,分析数据进行分类(分类意味着知道什么属于什么,例如“苹果”属于“水果”类,而“狗”属于“动物”类——见图 1)

Fig. 1
在支持向量机中,它看起来有点像下面的图 2:),它将蓝色的球与红色的球分开。
> SVM 是一个由分离超平面正式定义**的**分类器**。超平面是比它的**周围空间**小一个**维度**的子空间。数学空间(或对象)的**维度**被非正式地定义为指定其中任何点(如每个蓝色和红色点)所需的最小坐标数(x,y,z 轴),而周围空间是数学对象周围的空间。**数学对象**是数学中出现的抽象对象**抽象对象**是不存在于任何特定时间或地点的对象,而是作为一种类型的事物存在,即思想或抽象(维基百科)。**
因此,下面的二维空间的超平面(图 2)是划分红色和蓝色点的一维线。

Fig. 2
从上面试图预测一只特定狗的品种的例子来看,它是这样的
数据(所有品种的狗)→特征(肤色、毛发等)→学习算法
# 那么为什么是内核呢?
考虑下面的图 3

Fig. 3
你能试着像图 2 那样线性地解决上面的问题吗?
不要!
红色和蓝色的球不能被一条直线分开,因为它们是随机分布的,这就是现实生活中大多数问题数据的随机分布。
在机器学习中,“内核”通常用于指内核技巧,即使用线性分类器来解决非线性问题的方法。它需要将线性不可分的数据(如图 3)转换成线性可分的数据(如图 2)。核函数是应用于每个数据实例的函数,用于将原始非线性观察值映射到高维空间,在该空间中它们变得可分离。
再次使用狗品种预测的例子,内核提供了一个更好的选择。你不用定义一系列的特征,而是定义一个单一的核函数来计算不同品种狗之间的相似度。你把这个内核,连同数据和标签一起提供给学习算法,就产生了一个分类器。
# 它是如何工作的?
为了更好地理解内核是如何工作的,让我们使用姜黎黎的数学[图](https://www.quora.com/What-are-Kernels-in-Machine-Learning-and-SVM/answer/Lili-Jiang?srid=oOgT)
> **数学定义** : K(x,y) = < f(x),f(y) >。这里 K 是核函数,x,y 是 n 维输入。f 是从 n 维到 m 维空间的映射。< x,y >表示点积。通常 m 比 n 大很多。
>
> **直觉**:正常计算< f(x),f(y) >需要我们先计算 f(x),f(y),然后做点积。这两个计算步骤可能相当昂贵,因为它们涉及 m 维空间中的操作,其中 m 可以是大的数字。但是在经历了所有去高维空间的麻烦之后,点积的结果真的是标量:我们又回到一维空间了!现在,我们的问题是:我们真的需要大费周章去得到这个数字吗?我们真的要去 m 维空间吗?答案是否定的,如果你找到一个聪明的内核。
>
> **简单例子:** x = (x1,x2,x3);y = (y1,y2,y3)。那么对于函数 f(x) = (x1x1,x1x2,x1x3,x2x1,x2x2,x2x3,x3x1,x3x2,x3x3),核就是 K(x,y ) = ( < x,y >)。
>
> 让我们插入一些数字,让这个更直观:假设 x = (1,2,3);y = (4,5,6)。然后:
> f(x) = (1,2,3,2,4,6,3,6,9)
> f(y) = (16,20,24,20,25,30,24,30,36)
> < f(x),f(y)>= 16+40+72+40+100+180+72+180+324 = 1024
>
> 代数很多,主要是因为 f 是 3 维到 9 维空间的映射。
>
> 现在让我们用核来代替:
> K(x,y) = (4 + 10 + 18 ) ^2 = 32 = 1024
> 同样的结果,但是这个计算简单多了。
内核大概就是这样。干得好!你刚刚迈出了成为机器学习专家的第一步:)
***额外说明:*** *了解更多,可以查看* [*我是如何在 Numerai ml 预测股市的*](https://medium.com/@Yettie/how-i-predicted-the-stock-market-at-numerai-ml-tournament-6f74e1c8809e#.x456mngmw) *和* [*机器学习中有哪些内核以及*](https://www.quora.com/What-are-Kernels-in-Machine-Learning-and-SVM) *。*
[*Pelumi Aboluwarin*](https://medium.com/u/db00622f19c5?source=post_page-----6f1d2be6091--------------------------------)*在阅读草案和建议这个主题方面做得非常出色。谢谢大家!*
如果你像我喜欢写这篇文章一样喜欢读它,你知道该怎么做;)给它一些爱,如果你对你想让我写的话题有什么建议,请写在下面的评论区。感谢阅读:)
* **所有图片均来自网络***
额外阅读
1. [https://en.wikipedia.org/wiki/Statistical_classification](https://en.wikipedia.org/wiki/Statistical_classification)
2. [https://en.wikipedia.org/wiki/Supervised_learning](https://en.wikipedia.org/wiki/Supervised_learning)
# 核机器学习——kernel ml——广义机器学习算法
> 原文:<https://towardsdatascience.com/kernel-machine-learning-kernelml-generalized-machine-learning-algorithm-4800a4e05a33?source=collection_archive---------7----------------------->

制作这种算法的动机是为分析师和数据科学家提供一种针对复杂损失函数和非线性系数的通用机器学习算法。优化器使用简单的机器学习和概率模拟的组合,使用损失函数、输入和输出矩阵以及(可选的)随机采样器来搜索最佳参数。
**示例用例:**
聚类方法(如 K-means)使用欧几里得距离来比较观察值。然而,经度和纬度数据点之间的欧几里德距离并不直接映射到哈弗森距离,即球体周围的距离。如果坐标在 0 和 1 之间标准化,则距离将不会在聚类分析模型中准确表示。一种可能的解决方案是找到纬度和经度的投影,使得到数据点质心的哈弗斯距离等于欧几里德空间中投影的纬度和经度的哈弗斯距离。

此坐标变换的结果允许您将相对于中心的哈弗线距离表示为欧几里德距离,该距离可以在聚类解决方案中进行缩放和使用。
另一个更简单的问题是找到非线性系数的最佳值,即最小平方线性模型中的幂变换。这样做的原因很简单:整数幂变换很少能捕捉到最合适的变换。通过允许幂变换为任何实数,精确度将提高,并且模型将更好地概括验证数据。

为了阐明功率变换的含义,上面提供了模型的公式。
**算法:**
kernelml 背后的想法很简单。使用机器学习模型中的参数更新历史来决定如何更新下一个参数集。使用机器学习模型作为后端会导致偏差方差问题,具体来说,参数更新在每次迭代中变得更有偏差。这个问题可以通过在每次迭代之后在最佳记录参数集周围包括蒙特卡罗模拟来解决。
**衔接问题:**
该模型在每次迭代后保存最佳参数和用户定义的损失。该模型还记录所有参数更新的历史。问题是如何使用这些数据来定义收敛。一个可能的解决方案是:
该公式使用最后 10 个参数和最佳参数创建 Z 值。如果所有参数的 Z 分数都小于 1,则可以说该算法已经收敛。当存在理论上的最佳参数集时,这种收敛解决方案工作良好。当使用该算法进行聚类时,这是一个问题。请参见下面的示例。

**图 1:用 kernelml 聚类,二维多元正态分布(蓝色),聚类解决方案(其他颜色)**
我们不会讨论集群解决方案的质量,因为它显然不能代表数据。聚类解决方案最小化了多维直方图和 6 个正态分布(每个轴 3 个)的平均概率之间的差异。在这里,分布可以很容易地“交换”数据点,这可能会增加收敛时间。为什么不直接拟合 3 个多元正态分布?模拟分布参数有一个问题,因为有些参数有约束。协方差矩阵需要是正的,半正定的,并且需要有逆矩阵存在。正态分布中的标准偏差必须大于 0。该模型中使用的解决方案通过对每个单独的参数进行定制模拟来结合参数约束。我仍在寻找如何有效模拟多元正态分布的协方差矩阵的好公式。
**为什么用 kernelml 代替期望最大化?**
非正态分布(如泊松分布)可能不太适合多元正态聚类分析解决方案中的其他维度。此外,随着维数的增加,一个聚类是唯一具有非零值特征的聚类的概率也会增加。这给 em 算法提出了一个问题,因为它试图更新协变矩阵。唯一特征和其他维度之间的协方差将为零,或者另一个聚类接受具有该非零值的观测值的概率为零。
**概率优化器优势:**
参数的概率模拟比完全参数化的模型有更大的好处。首先,正则化包含在先验随机模拟中。例如,如果参数的先验随机模拟在-1 和 1 之间,则可以推断出参数将以同等的重要性更新。此外,当算法收敛时,每次迭代产生一组在全局或局部最小损失附近采样的参数。这样做有两个主要好处:1)可以为每个参数建立置信区间;2)每个参数集的预测输出可以是统一模型中的有用特征。KernelML 并不严格地从概率分布中生成样本。相反,它通过在引导绑定的小批量上更新参数来生成参数的分布。
集群示例的代码、其他示例和文档可以在 github 的[中找到。](https://github.com/Freedomtowin/kernelml)
# Tensorflow/sklearn 中的核 PCA vs PCA vs ICA
> 原文:<https://towardsdatascience.com/kernel-pca-vs-pca-vs-ica-in-tensorflow-sklearn-60e17eb15a64?source=collection_archive---------9----------------------->

GIF from this [website](https://giphy.com/gifs/trapcode-xponentialdesign-trapcodetao-UOqSr1m4isHaE)
主成分分析对给定的数据执行线性变换,然而,许多真实世界的数据不是线性可分的。那么,我们能否利用更高维度的优势,同时又不大幅增加所需的计算能力呢?
> **请注意,这个帖子是给未来的自己看的,用来回顾和复习这个帖子上的材料。**(还有自学)
**讲座:内核主成分分析**
PPT from this [website](http://www.cs.haifa.ac.il/~rita/uml_course/lectures/KPCA.pdf)
根据上面的 PPT,我会做一些对我有帮助的简短笔记。

[VAP Nik–Chervonenkis theor](https://en.wikipedia.org/wiki/Vapnik%E2%80%93Chervonenkis_theory)y 告诉我们,如果我们将数据投影到一个更高维的空间,它会为我们提供更好的分类能力。(左图示例。)这可能类似于神经网络总体所做的,随着深度的增加,更多的抽象特征被提取,并且具有更好的特征来执行分类。

内核技巧,一种在不牺牲太多计算时间的情况下将原始数据投影到更高维度的方法。(非线性特征映射)。和矩阵形式来归一化特征空间。

有效使用 KPCA 的例子,见上文。
**KPCA 的不同使用案例**
Paper from this [website](https://bmcbioinformatics.biomedcentral.com/articles/10.1186/1471-2105-15-137)
Paper from this [website](https://www.frontiersin.org/articles/10.3389/fnsys.2012.00074/full)
在第一篇论文中,作者使用 KPCA 作为预处理步骤,作为特征变换的手段,并与最小二乘支持向量机配对,对 DNA 微阵列进行分类。(微阵列数据具有高维度,因此在执行分类之前执行维度缩减技术是一个好主意。)在第二篇论文中,使用 KPCA 从功能性磁共振图像(fMRI)中提取特征,以对注意力缺陷多动障碍(ADHD)执行自动诊断。
**tensor flow 中的 KPCA (RBF)层**

可以像上面那样实现一个简单的前馈操作,在撰写本文时,我不会对输入数据实现反向传播。
**KPCA vs PCA vs ICA**

让我们从简单的开始,我们有一个线性不可分的 2D 数据点,现在为了验证我们的实现正在工作,让我们使用每个 KPCA、PCA 和 ICA 将我们的数据投影到二维空间中。

**左图** →使用 KPCA 的投影
**中图** →使用 PCA 的投影
**右图→** 使用 ICA 的投影
从上面的例子我们可以看到,我们的实现工作正常,我们的数据现在是线性可分的。但是为了让事情变得更有趣,让我们看看这些方法在组织病理学图像上的效果。我正在使用来自[骨髓活检组织病理学数据(HistBMP)的数据集。](https://zenodo.org/record/1205024#.W5bbVOhKiUk)

如上所述,每幅图像都是 28*28 的灰度图像,我们将通过将 1000 幅图像压缩成 100 幅来找到特征图像。

**左图** →使用 KPCA
的投影**中图** →使用 PCA
的投影**右图→** 使用 ICA 的投影
总的来说,我们可以看到 PCA 试图捕捉全局变化,ICA 试图捕捉局部变化。但 KPCA 似乎首先捕捉到了全球变化,但当我们到达特征图像的下部时,我们可以看到它正在捕捉局部变化。
**代码**

*对于 Google Colab,您需要一个 Google 帐户来查看代码,而且您不能在 Google Colab 中运行只读脚本,因此请在您的操场上创建一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!*
要访问这篇文章的代码,请点击[这里](https://colab.research.google.com/drive/1n-RW3kPHKExZNS_d7imsbjuwzr06qclU)。
**遗言**
请注意,对于距离矩阵,我从这个[网站](https://medium.com/dataholiks-distillery/l2-distance-matrix-vectorization-trick-26aa3247ac6c)借用了非循环形式,整体实现从 Sebastian Raschka 的“[核技巧和通过 RBF 核 PCA 的非线性维度缩减](https://sebastianraschka.com/Articles/2014_kernel_pca.html)”借用。
我一直想知道如何绘制每个特征值的方差,这是一篇很好的文章[解释了其中的诀窍。](https://sebastianraschka.com/Articles/2015_pca_in_3_steps.html)

Image from this [website](https://sebastianraschka.com/Articles/2015_pca_in_3_steps.html)
这也是我发现的一个有趣的视频。
video from this [website](https://www.youtube.com/watch?v=3k9hwRCcT30)
最后,有趣的是,主成分分析/ KPCA 受到方差膨胀和缺乏可推广性的影响,下面的论文提出了一个解决问题的方法。
Paper from this [website](http://jmlr.csail.mit.edu/papers/v12/abrahamsen11a.html)
如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请在这里查看我的网站。
同时,在我的 twitter 上关注我[这里](https://twitter.com/JaeDukSeo),访问[我的网站](https://jaedukseo.me/),或者我的 [Youtube 频道](https://www.youtube.com/c/JaeDukSeo)了解更多内容。我还实现了[广残网,请点击这里查看博文](https://medium.com/@SeoJaeDuk/wide-residual-networks-with-interactive-code-5e190f8f25ec) t。
**参考**
1. 主成分分析。(2015).塞巴斯蒂安·拉什卡博士。2018 年 9 月 7 日检索,来自[https://sebastianraschka . com/Articles/2015 _ PCA _ in _ 3 _ steps . html](https://sebastianraschka.com/Articles/2015_pca_in_3_steps.html)
2. 关于特征缩放和规范化。(2014).塞巴斯蒂安·拉什卡博士。检索于 2018 年 9 月 7 日,来自[https://sebastianraschka . com/Articles/2014 _ about _ feature _ scaling . html](https://sebastianraschka.com/Articles/2014_about_feature_scaling.html)
3. 关于特征缩放和规范化。(2014).塞巴斯蒂安·拉什卡博士。检索于 2018 年 9 月 7 日,来自[https://sebastianraschka . com/Articles/2014 _ about _ feature _ scaling . html](https://sebastianraschka.com/Articles/2014_about_feature_scaling.html)
4. 实施主成分分析(PCA)。(2014).塞巴斯蒂安·拉什卡博士。2018 年 9 月 7 日检索,来自[https://sebastianraschka . com/Articles/2014 _ PCA _ step _ by _ step . html](https://sebastianraschka.com/Articles/2014_pca_step_by_step.html)
5. tf.ones | TensorFlow。(2018).张量流。检索于 2018 年 9 月 10 日,来自[https://www.tensorflow.org/api_docs/python/tf/ones](https://www.tensorflow.org/api_docs/python/tf/ones)
6. 距离矩阵矢量化技巧-流形博客-中。(2016).中等。检索于 2018 年 9 月 10 日,来自[https://medium . com/data holiks-distillery/L2-distance-matrix-vectorization-trick-26aa 3247 ac6c](https://medium.com/dataholiks-distillery/l2-distance-matrix-vectorization-trick-26aa3247ac6c)
7. matplotlib,P. (2018 年)。用 matplotlib 同时绘制两个直方图。堆栈溢出。检索于 2018 年 9 月 10 日,来自[https://stack overflow . com/questions/6871201/plot-two-histograms-at-same-time-with-matplotlib](https://stackoverflow.com/questions/6871201/plot-two-histograms-at-the-same-time-with-matplotlib)
8. tf.self _ 共轭 _eig | TensorFlow。(2018).张量流。检索于 2018 年 9 月 10 日,来自[https://www . tensor flow . org/API _ docs/python/TF/self _ agreement _ EIG](https://www.tensorflow.org/api_docs/python/tf/self_adjoint_eig)
9. 核技巧和基于 RBF 核 PCA 的非线性降维。(2014).塞巴斯蒂安·拉什卡博士。检索于 2018 年 9 月 10 日,来自 https://sebastianraschka.com/Articles/2014_kernel_pca.html
10. VAP Nik-Chervonenkis 理论。(2018).En.wikipedia.org。检索于 2018 年 9 月 10 日,来自[https://en . Wikipedia . org/wiki/VAP Nik % E2 % 80% 93c hervonenkis _ theory](https://en.wikipedia.org/wiki/Vapnik%E2%80%93Chervonenkis_theory)
11. Sidhu、n . as garian、r . Greiner 和 m . Brown(2012 年)。核主成分分析在基于 fMRI 的 ADHD 诊断中的降维作用。系统神经科学前沿,6。doi:10.3389/fnsys
12. m .托马斯、k .布拉班特和 b .穆尔(2014 年)。核主成分分析的新带宽选择准则:降维和分类问题的方法。BMC 生物信息学,15(1),137。doi:10.1186/1471–2105–15–137
13. t .亚伯拉罕森和 l .汉森(2011 年)。高维核主成分分析中方差膨胀的一种解决方法。机器学习研究杂志,12 期(6 月),2027–2044。从 http://jmlr.csail.mit.edu/papers/v12/abrahamsen11a.html[取回](http://jmlr.csail.mit.edu/papers/v12/abrahamsen11a.html)
14. j . tomczak(2018 年)。骨髓活检(HistBMP)的组织病理学数据。芝诺多。检索于 2018 年 9 月 10 日,来自[https://zenodo.org/record/1205024#.W5bcCOhKiUm](https://zenodo.org/record/1205024#.W5bcCOhKiUm)
# Kickstarter 项目演练 Python 中的简单数据探索
> 原文:<https://towardsdatascience.com/kickstarter-projects-walk-through-simple-data-exploration-in-python-c2302a997789?source=collection_archive---------7----------------------->

这篇文章分析了大约 380.000 个 Kickstarter 项目的数据集。我将带领您通过 Python 进行简单的数据探索,揭示 Kickstarter 项目中有趣的见解,以及在检查某个项目的成功(或失败)时哪些属性是重要的。总的来说,我们将看看 Python 的基本数据可视化和特征工程。
# 1.一般想法和想法
Kickstarter 是最著名的推广(主要是)创造性的、聪明的和有远见的想法和概念的平台之一。每个项目都寻求 Kickstarter 人群能够提供的资金,如果他们支持这个想法并希望看到它成功的话。然而,有许多项目失败了,即使最初的想法可能是令人信服的。这是为什么呢?本文试图深入研究与每个项目相关的属性,并揭示与 Kickstarter 项目相关的模式、见解和任何感兴趣的东西。
# 2.初始数据集和属性
该数据集包含来自 Kickstarter 的 378.661 个项目以及与每个项目相关的 12 个初始属性。让我们看看我们从每个项目中获得了哪些信息:
1. **名**
挺明显的,各自项目的名称。例如“日常冲泡咖啡”
2. **main_category** 项目所属的主类别。例如“诗歌”、“美食”、“音乐”等等
3. **类别**
对主要类别的更精确的描述。基本上,main_category 的一个子群(参见 2。).例如“饮料”,它是 main_category 属性中“食物”的子组。
4. **货币**
项目的货币(如美元或英镑)
5. **启动**
项目的启动日期。当我们稍后分析时间框架时,这将非常重要
6. **截止日期**
项目的截止日期。正如上市日期一样,截止日期将变得和上市日期一样重要
7. **美元 _ 质押 _ 真实**
项目在截止日期实现的美元金额
8. **usd_goal_real**
项目最初要求的美元金额
9. **支持者**
实际投资该项目的支持者人数
10. **国别**项目原产国
11. **ID** 项目 ID
12. **状态**
项目最后成功了吗?*状态*是一个分类变量,分为成功*、失败、有效、取消、未定义*和暂停*等级别*。为了清楚起见,我们将只看一个项目是*成功*还是*失败*(因此,我们将删除未被归类为两者之一的所有项目)。失败或成功的项目约占所有项目的 88%。
让我们快速移除所有没有*失败*或*成功*作为其*状态*的项目。
return only successful and failed projects. This makes things more clear later on**data_kick = data_kick.loc[data_kick['state'].isin(
['successful', 'failed'])]**
让我们先来看看所有属性的数据类型,以便更好地理解数据,看看是否一切正常。
data_kick.info()ID 378661 non-null int64
name 378657 non-null object
category 378661 non-null object
main_category 378661 non-null object
currency 378661 non-null object
deadline 378661 non-null object
goal 378661 non-null float64
launched 378661 non-null object
pledged 378661 non-null float64
state 378661 non-null object
backers 378661 non-null int64
country 378661 non-null object
usd pledged 374864 non-null float64
usd_pledged_real 378661 non-null float64
usd_goal_real 378661 non-null float64
可以看出,所有属性都倾向于采用精确的数据格式——要么是浮点型(因此是数字型),要么是对象型(因此是分类型)。唯一两个不符合期望格式的属性是我们的两个时间属性:*发起*和*截止日期*。我们一会儿会处理这些。但是,让我们首先通过分析承诺的金额*与项目的最初目标*来了解数据集。
# 3.目标与承诺
让我们来看看一个项目的目标和实际承诺金额之间的关系。很明显,如果
**承诺金额≥目标**则一个项目被标记为*成功*,如果**承诺金额<目标则被标记为*不成功*。** 下图显示了每个项目的目标和承诺金额以及项目的单个状态(仅显示了*失败的*和*成功的*项目)。
define colors (darkgreen for successful projects and darkred for failed onescolors = ('darkgreen','darkred')#create a plot using seaborn, adjust data to millionsax = sns.scatterplot(data_kick.usd_pledged_real/1e6, data_kick.usd_goal_real/1e6, hue=data_kick.state, palette=colors)#add blue line to better visualize the border between failed and successful projectssns.lineplot(x=(0,50), y=(0,50), color='darkblue')#set the axes from -1 to their maximum (-1 looks better than 0 actually)ax.set(ylim=(-1,None), xlim=(-1,None))#set labels and titleax.set(xlabel='Amount Pledged in Millions', ylabel='Goal in Millions', title= 'Goal vs. Pledged')

直观地看,承诺超过/达到其目标的项目是*成功的*,显示为绿色,而*失败的*项目被标记为红色。看看与原点相交的蓝线:*成功的*项目总是在这条线的下面,而*失败的*项目在这条线的上面。这很有道理,不是吗?顺便说一句,你可以观察到,承诺金额最高的项目募集了大约 2000 万美元,目标最高的项目寻求超过 1.6 亿美元(但失败了)。是时候近距离观察了。
让我们放大一点,通过将两个轴的范围从 0 到 2000 万来更好地理解:
we are using the same code as above expect for the axis limits, that are set from 0 Millions (-1 in the code) to 20 Millionsax.set(ylim=(-1,20), xlim=(-1,20)

这种放大允许更直观的方法:蓝线现在以 45°角与原点相交,因为我们相应地将轴调整到相同的范围。如前所述,线下的每个数据点(即项目)都成功了,而线上的每个数据点都失败了。
有趣的是,该图表明,不成功的项目通常没有接近目标就失败了,这意味着它们“没有水平移动到蓝线,而是停留在 x~0”。由此得出结论,Kickstarter 是一个“要么全有,要么全无”的平台。如果你没有成功,你可能根本就没有成功。另一方面,许多成功的项目远远超过了他们的既定目标,并保证是他们最初目标的数倍。
随着时间的推移,承诺金额和目标之间的关系是如何发展的?让我们看看按年份分组的整个时间框架内目标和承诺的发展情况。我们使用下面的代码来获得每年目标和承诺的累计金额。
we choose the desired grouping intervall ('launched year') and the two variables pledge and goal that we are interested in and sum them up over the years.data_kick_groupby_year = data_kick.groupby('launched_year')['usd_pledged_real', 'usd_goal_real'].sum()#let's use this variable to plot the data over time:ax = sns.lineplot(x=data_kick_groupby_year_sum.index, y= data_kick_groupby_year_sum.usd_pledged_real/1e9, linewidth= 4, label= 'USD Pledged', color= 'darkgreen')****sns.lineplot(x=data_kick_groupby_year_sum.index, y= data_kick_groupby_year_sum.usd_goal_real/1e9, linewidth= 4,label='USD Goal', color= 'darkred')#set labels and titleax.set(xlabel='Launch Year', ylabel='USD in Billion', title='Comparison Pledged vs Goal over Time')
我们得到了这个图表:

该图显示了各年度所有项目的目标和承诺的累计金额。例如,2013 年,所有已启动项目的财务目标总和略高于 10 亿美元。
可以看出,总目标的累积金额在 2013 年急剧增加,在 2015 年达到峰值,然后缓慢下降。另一方面,每年的累计认捐额稳步下降,但呈线性下降。实际上从 2015 年到 2017 年略有下降。
目标值剧增的原因是相当明显的,不是吗?项目数量急剧增加,如下图所示:
data_kick['launched_year'].value_counts()2015 65272
2014 59306
2016 49292
2017 43419
2013 41101
2012 38478
2011 24048
2010 9577
2009 1179
更多的项目,更多的目标。然而,这只是促成累积目标增加的一个因素。这些年来,不仅启动了更多的项目,而且每个项目的平均目标也在增加,如下所示:
we group again. This time we take the average though:data_kick_groupby_year_avg = data_kick.groupby('launched_year')['usd_pledged_real', 'usd_goal_real'].mean()****print(data_kick_groupby_year_avg)launched_year usd_pledged_real usd_goal_real
2009 2375.535335 6799.507430
2010 3041.302897 13270.062647
2011 4256.161398 9715.957062
2012 8247.532875 17862.738838
2013 11326.171820 24946.164929
2014 8466.032884 47346.942048
2015 10058.201943 70094.513735
2016 12847.626664 52879.135752
2017 13564.594251 39073.175276
平均目标随着时间的推移而增加(从大约。2011 年向 ca 支付 10,000 美元。2016 年为 53,000 美元,随后在 2017 年大幅下降)。因此,不仅项目数量增加了,每个项目的平均目标也增加了。随着时间的推移,这些因素的结合增加了累积目标图。现在,时间够了。让我们看看名字!
# 4.名字的作用
另一个可能影响项目结果的方面是它的名字。我们希望更短、更简洁的名字比冗长、模糊的短语更能吸引(潜在)投资者。
例如,一个像“Circa Vitae 要求群众基金会录制我们的全长专辑…到乙烯基!!!"不如“第 X 天”吸引人(第一个项目确实失败了,后者成功了)。数据支持这个假设吗?让我们做一点特性工程,创建一个包含项目名称的字符串长度的新列。
data_kick['name_length'] = data_kick['name'].str.len()
我们现在将每个项目名称的字符串长度保存在 *name_length 中。*让我们看看这个栏目是什么样子的。
data_kick.loc[:,['name','name_length']].head(5)name name_length
0 The Songs of Adelaide & Abullah 31.0
1 Greeting From Earth: ZGAC Arts Capsule For ET 45.0
2 Where is Hank? 14.0
3 ToshiCapital Rekordz Needs Help to Complete Album 49.0
4 Community Film Project: The Art of Neighborhoo... 58.0
让我们创建一个散点图来显示 *name_length* 和*USD _ pleated _ real*之间的关系。
create scatterplot for pledged amount and name lengthax = sns.scatterplot(data_kick.usd_pledged_real/1e6, data_kick.name_length, hue=data_kick.state, palette=colors)#set labels accordinglyax.set(xlabel='Amount Pledged in Millions', ylabel='Character Length of Project Name', title= 'The Importance of Choosing the Right Name')

有趣的是,如果一个项目的名称超过 60 个字符,承诺的金额将分布在 0 附近,并且(或多或少)所有项目似乎都会失败。让我们来看看这些项目的目标与<60 projects and check the following hypothesis:
* Could it be that >相比,60 个角色的项目确实有明确的高目标值,他们的目标是收集?为了验证这个假设,让我们来看看 *name_length* ≥60 的平均*目标*与 *name_length* < 60 的平均*目标*。
让我们来看看这个项目分组,根据它们的*目标*大小和它们的项目*状态*有超过 60 个字符:
create a variable for all data points above a name length of 60data_kick_60_up = data_kick.loc[data_kick.name_length >= 60, ['state','usd_goal_real']]#create a variable for the data points below a name length of 60data_kick_60_down = data_kick.loc[data_kick.name_length < 60, ['state','usd_goal_real']]#compare the median of both groups. We see that the above 60 group actually has a higher median than the below 60 group.print(data_kick_60_up['usd_goal_real'].median() > data_kick_60_down['usd_goal_real'].median())****True
我们可以看到,对于≥60 岁的群体,他们的目标中值(以及均值)更高(布尔返回“真”)。因此,我们不能得出名称长度≥60 的项目仅仅具有较低的*目标*值的结论。相反,他们实际上比那些名字平均为 60 个字符的项目有更高的目标。这可能是他们失败的原因。那不是很了不起吗!
如前所述,基于项目名称长度的“成功细分”最直观的解释是,长名称有听起来不专业、不切题和不投入的倾向(显然这只是个人观点)。因此,他们承诺的少了,失败了。
# 5.探索时间
如前所述,除了时间变量,所有变量都是正确的类型。幸运的是,Pandas 允许我们快速地将日期变量更改为实际日期:
data_kick['launched'] = pd.to_datetime(data_kick['launched'],
format='%Y-%m-%d %H:%M:%S')data_kick['deadline'] = pd.to_datetime(data_kick['deadline'],
format='%Y-%m-%d %H:%M:%S')
如果您现在检查 *data_kick.info()* ,您将看到*已启动*和*截止日期*具有正确的数据类型。现在我们已经将时间变量转换成了正确的格式,让我们更仔细地看看它们。特别是,我们有两个有趣的时间栏:项目在*启动的确切日期*以及每个项目的*截止日期*。现在怎么办?
也许项目启动的日期会影响它的成功,也许启动和截止日期之间的时间也会影响项目的结果。有人可能会说,上市和截止日期之间的时间间隔越长,就有越多的时间被关注和赚钱。因此,跨度越长,成功的机会就越大。此外,项目启动的月份(甚至时间)可能会影响其结果。但是数据支持这些假设吗?让我们先看看发射时间。
我们可以通过以下代码提取项目启动的时间:
data_kick['launched_hour'] =
data_kick.launched.apply(lambda x: x.hour)****data_kick['launched_month'] =
data_kick.launched.apply(lambda x: x.month)
我们刚刚创建了两个新列,分别包含项目启动的月份和时间。让我们看看这些新属性是否包含帮助我们理解项目是否成功的模式。让我们想象一下这一天的时刻和项目的成功:
extract launched hour and state for all states 'successful' and append the same for all states 'failed'.**data_kick = data_kick.loc[data_kick.state == 'successful',['launched_hour', 'state']]
.append(data_kick.loc[data_kick.state == 'failed', ['launched_hour', 'state']])#plot the dataax = sns.countplot(x=extracted_levels_hour.launched_hour,
hue = extracted_levels_hour.state)#set labels and titleax.set(xlabel='Launched Hour', ylabel='Number of Projects', title= 'Hour the Project was Launched')**

这里有一些有趣的事情需要注意:
1. 一般来说,与早上 7 点到下午 3 点之间的时间相比,在清晨(0 点到 6 点之间)和傍晚(下午 4 点到 23 点之间)启动的项目更多。
2. 成功和失败项目之间的比率在一天中的不同时间有所不同。我们可以看到,对于在下午 2 点到 3 点之间启动的项目,失败和成功项目的比率几乎是 1(实际上有点小)。相反,在晚上 8 点以后启动的项目的比率要差得多(换句话说:失败的项目远远多于成功的项目)。
让我们看看项目启动的那个月是否揭示了它的状态:
plot the data**sns.countplot(x=data_kick.launched_hour,
hue = data_kick.state)**#set labels and title**ax.set(xlabel='Month of the Year', ylabel='Number of Projects', title= 'Month the Project was Launched')**

与一天中的某个时刻相比,月份似乎并没有显示出任何令人惊讶的见解。但是,请注意,与所有其他月份相比,12 月启动的项目要少得多。
最后,让我们看看*推出*和*截止*之间的跨度。通过从 deadline 中减去 launched,我们可以很容易地获得这个跨度(这是我们之前完成的 *date_time* 转换的一个有用特性)。在下面的代码中,我们取 launched 和 deadline 之间的差值,并立即提取日期(' timedelta64[D]'):
data_kick['project_time'] =
(data_kick['deadline'] -data_kick['launched']).astype('timedelta64[D]').astype(int)****data_kick['project_time'].head(5)0 58
1 59
2 44
3 29
4 55
您可以看到,我们的新列 project_time 以天为单位来度量启动和截止日期之间的时间跨度。例如,数据集中的第一个项目([0])在 Kickstarter 上呆了将近两个月(58 天)。在我们想象一个项目的跨度之前,让我们先看看结果。*data _ kick[' project _ time ']*的最大值是 91,因此我们可以按周对数据进行分类,以获得更直观的概览,而不是获得 91 个不同的结果。让我们首先编写一个允许我们有效绑定数据的函数:
def discretizer(data, binning_values, labels):
** *"""
Input: data series that should be discretized
bininningvalues: enter numerical array of binning cuts
labels: enter string array of names for binsOutput: gives you a list of binned data
"""
*data = pd.cut(data, bins=binning_values, labels=labels)
return data
让我们解析 *project_time* 并按周绑定它:
save the binned data as new column
data_kick["project_time_weeks"] =#call the discretizer funtion
discretizer(#first thing we pass is the column we want to be discretized, project_time in this casedata_kick['project_time'],#next, we create a list with the different binning intervals (starting at 0 and then going in steps of 7 until the maximum value of project_time (+7)list(range(0,max(data_kick['project_time'])+7,7)),#last but not least, we need to label the bins. We number them by creating a list from 1 (first week) to the last week depending on the maximum value of project_timelist(range(1,max(list(range(0,max(data_kick['project_time'])//7+2))))))
那么新列 project_time_weeks 是什么样子的呢?
print first 5 rows of both columns:data_kick[['project_time', 'project_time_weeks']].head(5)#resulting in:**project_time project_time_weeks
34 5
19 3
29 5
27 4
14 2**
我们可以看到日子被成功地分成了几个星期。例如,19 天转换为第 3 周。现在,最后,让我们看看*发布*和*截止日期*之间的时间是否会影响项目的成功:
plot the data
sns.countplot(x=data_kick.project_time_discret,
hue = data_reduced.state, palette=colors)

我们立刻注意到,大多数项目在 Kickstarter 上放了大约 5 周,几乎所有项目都在 1 到 9 周之间(所以比 2 个月多一点)。
成功和失败项目的比例随着时间的推移而变化:运行时间短(1-4 周)的项目比运行时间中长(5-13 周)的项目更容易成功。这种见解可以支持这样一种假设,即项目存在的时间越长,成功的可能性就越大,正如人们可能事先假设的那样(->项目存在的时间越长,人们有更多的机会看到它,它就越有可能成功。这似乎不是真的)。
# 6.支持者的角色
现在我们来看看支持每个项目的支持者的角色。总的来说,我们期望大量的支持者对特定项目成功的可能性做出积极的贡献。但事实真的是这样吗?
让我们想象一下支持者的数量、承诺的金额和项目的状态。
ax = sns.scatterplot(x=data_kick.backers, y=data_kick.usd_pledged_real/1e6, hue=data_kick.state, palette=colors)#we set the xlim to 100,000 backers to get a better overview
ax.set(ylim=(-1,None), xlim=(-1,100000))#set labels and titleax.set(xlabel='Number of Backers', ylabel='USD Pledged in Million', title= 'Backer vs Pledge')
该代码会生成下图:

这个结果并不令人惊讶,是吗?我们可以清楚地看到,支持者的数量与项目的成功相关。大多数失败的项目也有相对较少的支持者。然而,让我们更进一步:不仅每个项目支持者的绝对数量是有趣的,而且每个项目每个支持者花费的平均金额也是有趣的。为了得到这个属性,我们需要将质押的金额除以实际支持者的数量。让我们快点做那件事。
divide usd_pledged_real by number of backers (note that a Zerodivisionerror will occur if we divide by zero resulting in a NaN. We replace these with 0data_kick['backer_ratio'] = (data_kick['usd_pledged_real']//data_kick['backers']).fillna(0)#set label and titleax.set(xlabel='Pledge/Backer Ratio (funding per backer)', ylabel='USD Pledged in Million', title= 'Backer Ratio vs Pledge')

看一下资助者比率(即认捐总额除以资助者总数),我们可以看到大多数成功项目的资助者比率相对较低,这意味着每个资助者贡献的金额相对较小。根据图表,该金额在略高于 0 美元到大约 700 美元之间变化。我们可以看到,大多数支持者比率相对较高(< 2000 美元)的项目都失败了。
既然我们已经看了时间框架、名称、支持者和许多其他细节,是时候停止我们的小演练了。仍然有许多可能的见解和模式要揭示,但我把这个留给你;-)
6.结论
这篇关于 Python 中基本数据可视化的介绍性文章揭示了一些关于 Kickstarter 项目的有趣事实。我们总结一下:
1. 失败的项目,大多数时候都是惨败。如第三部分所述,他们“不能向蓝线移动”。要么全有,要么全无;-).
2. 随着时间的推移,项目的数量和平均目标急剧增加(至少到 2015 年),而提供的承诺仅缓慢增加。
3. 名字起着很大的作用。如果你想启动一个项目,确保它的名字准确而简短。“顽固的独家斯科特·托尔森叔叔 Argh NOIR Mini Qee”听起来可能很好笑(实际上并不好笑),但不会让你去任何地方。
4. 尝试在下午 12 点到 4 点之间启动你的项目,不要在 12 月启动(好吧,我不是 100%认真的)。
我希望你喜欢这本书。我感谢任何形式的反馈,(建设性的)批评或其他建议。谢谢!
# 用于分类的 k 均值聚类
> 原文:<https://towardsdatascience.com/kmeans-clustering-for-classification-74b992405d0a?source=collection_archive---------2----------------------->

# 背景
聚类作为一种在观察值中寻找子群的方法,广泛应用于市场细分等应用中,在这些应用中,我们试图在数据中找到一些结构。虽然是一种无监督的机器学习技术,但聚类可以用作有监督的机器学习模型中的特征。
> 聚类是一种无监督的机器学习,其目的是找到同质的子组,使得同一组(聚类)中的对象彼此比其他对象更相似。
KMeans 是一种聚类算法,它将观察值分成 k 个聚类。因为我们可以指定聚类的数量,所以它可以很容易地用于分类,在分类中,我们将数据分成等于或大于类数量的聚类。
我将使用 scikit learn 附带的 MNIST 数据集,它是一个带标签的手写数字的集合,并使用 KMeans 在数据集中查找聚类,并测试它作为一个特征有多好。
# 履行
为此,我创建了一个名为 clust 的[类](http://nbviewer.jupyter.org/github/mudassirkhan19/cluster-classification/blob/master/Kmeans_classification.ipynb),它在初始化时接收一个 sklearn 数据集,并将其分为训练和测试数据集。
函数 KMeans 将 KMeans 聚类应用于训练数据,将类的数量作为要形成的聚类的数量,并为训练和测试数据创建标签。参数输出控制我们希望如何使用这些新标签,“添加”将标签作为特征添加到数据集中,“替换”将使用标签而不是训练和测试数据集来训练我们的分类模型。
# 结果
在第一次尝试中,仅使用 KMeans 找到的聚类来训练分类模型。仅这些聚类就给出了准确度为 78.33%的像样的模型。让我们将其与开箱即用的逻辑回归模型进行比较。

在这种情况下,我只使用特征(灰度强度值)来训练逻辑回归模型。其结果是具有 95.37%准确度的好得多的模型。让我们将分类添加为一个特征(列)并训练相同的逻辑回归模型。

在我们的最后一次迭代中,我们使用聚类作为特征,结果显示比我们以前的模型有所改进。

# 外卖食品
聚类除了是一种无监督的机器学习之外,还可以用于创建聚类作为改进分类模型的特征。结果显示,它们本身不足以进行分类。但是当用作特征时,它们提高了模型的准确性。
你可以[使用我创建的类](http://nbviewer.jupyter.org/github/mudassirkhan19/cluster-classification/blob/master/Kmeans_classification.ipynb)来调整和测试不同的模型,例如测试一个随机的森林分类器,分享一些我在评论中没有找到的东西。
# kMeans 对地图数据进行哈希搜索
> 原文:<https://towardsdatascience.com/kmeans-hash-search-map-search-in-o-n%C2%B2lgn-33743ece434f?source=collection_archive---------11----------------------->
kMeans 聚类算法因其作为“无监督人工智能”学习算法的分类而非常受欢迎。这种聚类的工作原理是将数据集的要素组合在一起,以区分实体。实体可以是地理上的一个地方,例如加利福尼亚的旧金山。
当你长时间使用谷歌地图 API 处理街道数据时,你会产生一种新的语感。纬度/液化天然气坐标系统是观察庞大社会的一种不可思议的方式。您甚至可以立即认出下图中的 JSON 坐标是在美国还是在英国。
{ lat: 36.778, lng: -119.4179 }
当我们试图理解像旧金山湾区这样的大规模道路网络时,(如下图)。我们意识到我们需要开发二维(lat/lng)空间的搜索算法。

San Francisco Road Map
旧金山有很多很酷的地方可以看,初创公司也有很多机会找到很酷的办公场所并招募他们的团队。然而,对于我们当前的算法来说,搜索给定半径内的地点并计算最短路径并不容易。
从计算复杂性的角度来看,使用地图数据和创建地图用户界面的问题在于这些数据的巨大复杂性。以运行在 O(n log n)中的 mergsort 等传统排序算法为例。这个算法只适用于一维向量空间。而使用某种径向基函数将 lat / lng 映射到一维坐标平面可能是一种有效的解决方案。本文将讨论开发一种搜索算法,同时保持更自然的二维 lat/lng 数据集。
在现代计算机系统中对道路网络数据建模的标准是图形数据库。图被表示为 n×n 矩阵,其中 n[i][j]处的值包含节点之间的距离。然而,典型的道路数据被编码为一个非常精细的矩阵,lat/lng 十进制值跟踪到 7 位。L1/曼哈顿纬度/液化天然气距离将唐人街(SF)和恩巴卡德罗路(SF)区分为. 000008,这并不罕见。
由于这个原因,在将 lat/lng 全部乘以大约 10,000,000 后,在我们的数据集中开始编码可能是有用的。这样,在使用图形数据库搜索道路地图的几何图形之后,我们可以很容易地用“500 英尺”来表示距离。
怎样才能用拓扑几何加速空间查询?
旅行商问题可以说是计算机科学中最著名的 NP 难问题。此问题计算通过迷宫(如道路网络)并到达最终目的地所需的最短时间。
正如许多旅行者所知,在一个大城市的道路网络中导航以计划最终的假期是非常困难的。
以旧金山为例:
第一天:{观景廊/渔人码头/日本广场/小意大利/唐人街/甲骨文球馆/美国电话电报公司球馆/金门公园}
这些令人惊叹的旅游目的地都可以组织成一系列
{ lat: (float), lng: (float) }
使用地图需要大量的数据工程和管道来帮助纠正维度失衡和填充缺失的数据点。
数据工程:将 XML 转换成 JSON。我们的大部分处理都是在 csv 文件和 JSON 文件上完成的,前者在 Python 中容易阅读,后者在 JavaScript 中容易阅读。JavaScript 特别有用,因为它可以连接前端、后端和数据库逻辑,构建强大的 web 应用程序。
研究地理边界数据时,您可能会发现 XML 格式的数据,如下所示:
我们需要编写一个 python 脚本来将它转换成一个字符串列表,我们可以将它硬编码成 JavaScript 来概括这些状态。
var MinnesotaCoords = [
{lat: 36.9971, lng: -109.0448 },
{lat: 31.3337, lng: -109.0489 },
{lat: 31.3349, lng: -108.2140 },
{lat: 31.7795, lng: -108.2071 },
{lat: 31.7830, lng: -106.5317 },
{lat: 32.0034, lng: -106.6223 },
{lat: 31.9999, lng: -103.0696 },
{lat: 36.9982, lng: -103.0023 },
{lat: 36.9982, lng: -109.0475 },
];
一旦你有了这些,你将能够使用 kMeans 算法来组织地理信息,比如下面用 Python 写的大量代码块。
pointSet = [["Arizona (AZ)", 34.054455, -111.293573], ["Arkansas (AR)", 35.201050, -91.831833],
["California (CA)", 36.778261, -119.417932], ["Colorado (CO)", 39.550051, -105.782067],
["Connecticut (CT)", 41.603221, -73.087749], ["Florida (FL)", 27.664827, -81.515754],
["Georgia (GA)", 32.165622, -82.900075], ["Illinois (IL)", 40.633125, -89.398528],
["Maryland (MD)", 39.045755, -76.641271], ["Michigan (MI)", 44.314844, -85.602364] ];
cluster1 = []
cluster2 = []
cluster3 = []
cluster4 = []
cluster5 = []
def calculateDistance(a,b):
return (abs(a[1] - b[1]) + abs(a[2] - b[2]))
def getMeanValue(pointSet):
xSum = 0
ySum = 0
for i in range(len(pointSet)):
xSum += pointSet[i][1]
ySum += pointSet[i][2]
xAvg = 0
yAvg = 0
if (len(pointSet) != 0):
xAvg = xSum / len(pointSet)
yAvg = ySum / len(pointSet)
return ["DimensionFill", xAvg, yAvg]
def initializeCentroids(pointSet):
mean = getMeanValue(pointSet)
centroid1 = ["DimensionFill", mean[1] + 10, mean[2] + 10]
centroid2 = ["DimensionFill", mean[1] + 5, mean[2] - 5]
centroid3 = ["DimensionFill", mean[1], mean[2]]
centroid4 = ["DimensionFill", mean[1] - 5, mean[2] - 5]
centroid5 = ["DimensionFill", mean[1] - 10, mean[2] - 10]
return [centroid1, centroid2, centroid3, centroid4, centroid5]
centroids = initializeCentroids(pointSet)
centroid1 = centroids[0]
centroid2 = centroids[1]
centroid3 = centroids[2]
centroid4 = centroids[3]
centroid5 = centroids[4]
j = 1
for i in range(len(pointSet)):
dist1 = calculateDistance(pointSet[i], centroid1)
dist2 = calculateDistance(pointSet[i], centroid2)
dist3 = calculateDistance(pointSet[i], centroid3)
dist4 = calculateDistance(pointSet[i], centroid4)
dist5 = calculateDistance(pointSet[i], centroid5)
if (dist1 < dist2 and dist1 < dist3 and dist1 < dist4 and dist1 < dist5):
cluster1.append(pointSet[i])
elif (dist2 < dist1 and dist2 < dist3 and dist2 < dist4 and dist2 < dist5):
cluster2.append(pointSet[i])
elif (dist3 < dist1 and dist3 < dist2 and dist3 < dist4 and dist3 < dist5):
cluster3.append(pointSet[i])
elif (dist4 < dist1 and dist4 < dist2 and dist4 < dist3 and dist4 < dist5):
cluster4.append(pointSet[i])
else:
cluster5.append(pointSet[i])
# j is number of iterations for kMeans
j = 5
while (j > 0):
newCluster1 = []
newCluster2 = []
newCluster3 = []
newCluster4 = []
newCluster5 = []
for k in range(len(cluster1)):
dist1 = calculateDistance(cluster1[k], centroid1)
dist2 = calculateDistance(cluster1[k], centroid2)
dist3 = calculateDistance(cluster1[k], centroid3)
dist4 = calculateDistance(cluster1[k], centroid4)
dist5 = calculateDistance(cluster1[k], centroid5)
if (dist1 < dist2 and dist1 < dist3 and dist1 < dist4 and dist1 < dist5):
newCluster1.append(cluster1[k])
elif (dist2 < dist1 and dist2 < dist3 and dist2 < dist4 and dist2 < dist5):
newCluster2.append(cluster1[k])
elif (dist3 < dist1 and dist3 < dist2 and dist3 < dist4 and dist3 < dist5):
newCluster3.append(cluster1[k])
elif (dist4 < dist1 and dist4 < dist2 and dist4 < dist3 and dist4 < dist5):
newCluster4.append(cluster1[k])
else:
newCluster5.append(cluster1[k])
for k in range(len(cluster2)):
dist1 = calculateDistance(cluster2[k], centroid1)
dist2 = calculateDistance(cluster2[k], centroid2)
dist3 = calculateDistance(cluster2[k], centroid3)
dist4 = calculateDistance(cluster2[k], centroid4)
dist5 = calculateDistance(cluster2[k], centroid5)
if (dist1 < dist2 and dist1 < dist3 and dist1 < dist4 and dist1 < dist5):
newCluster1.append(cluster2[k])
elif (dist2 < dist1 and dist2 < dist3 and dist2 < dist4 and dist2 < dist5):
newCluster2.append(cluster2[k])
elif (dist3 < dist1 and dist3 < dist2 and dist3 < dist4 and dist3 < dist5):
newCluster3.append(cluster2[k])
elif (dist4 < dist1 and dist4 < dist2 and dist4 < dist3 and dist4 < dist5):
newCluster4.append(cluster2[k])
else:
newCluster5.append(cluster2[k])
for k in range(len(cluster3)):
dist1 = calculateDistance(cluster3[k], centroid1)
dist2 = calculateDistance(cluster3[k], centroid2)
dist3 = calculateDistance(cluster3[k], centroid3)
dist4 = calculateDistance(cluster3[k], centroid4)
dist5 = calculateDistance(cluster3[k], centroid5)
if (dist1 < dist2 and dist1 < dist3 and dist1 < dist4 and dist1 < dist5):
newCluster1.append(cluster3[k])
elif (dist2 < dist1 and dist2 < dist3 and dist2 < dist4 and dist2 < dist5):
newCluster2.append(cluster3[k])
elif (dist3 < dist1 and dist3 < dist2 and dist3 < dist4 and dist3 < dist5):
newCluster3.append(cluster3[k])
elif (dist4 < dist1 and dist4 < dist2 and dist4 < dist3 and dist4 < dist5):
newCluster4.append(cluster3[k])
else:
newCluster5.push(cluster3[k])
for k in range(len(cluster4)):
dist1 = calculateDistance(cluster4[k], centroid1)
dist2 = calculateDistance(cluster4[k], centroid2)
dist3 = calculateDistance(cluster4[k], centroid3)
dist4 = calculateDistance(cluster4[k], centroid4)
dist5 = calculateDistance(cluster4[k], centroid5)
if (dist1 < dist2 and dist1 < dist3 and dist1 < dist4 and dist1 < dist5):
newCluster1.append(cluster4[k])
elif (dist2 < dist1 and dist2 < dist3 and dist2 < dist4 and dist2 < dist5):
newCluster2.append(cluster4[k])
elif (dist3 < dist1 and dist3 < dist2 and dist3 < dist4 and dist3 < dist5):
newCluster3.append(cluster4[k])
elif (dist4 < dist1 and dist4 < dist2 and dist4 < dist3 and dist4 < dist5):
newCluster4.append(cluster4[k])
else:
newCluster5.push(cluster4[k])
for k in range(len(cluster5)):
dist1 = calculateDistance(cluster5[k], centroid1)
dist2 = calculateDistance(cluster5[k], centroid2)
dist3 = calculateDistance(cluster5[k], centroid3)
dist4 = calculateDistance(cluster5[k], centroid4)
dist5 = calculateDistance(cluster5[k], centroid5)
if (dist1 < dist2 and dist1 < dist3 and dist1 < dist4 and dist1 < dist5):
newCluster1.append(cluster5[k])
elif (dist2 < dist1 and dist2 < dist3 and dist2 < dist4 and dist2 < dist5):
newCluster2.append(cluster5[k])
elif (dist3 < dist1 and dist3 < dist2 and dist3 < dist4 and dist3 < dist5):
newCluster3.append(cluster5[k])
elif (dist4 < dist1 and dist4 < dist2 and dist4 < dist3 and dist4 < dist5):
newCluster4.append(cluster5[k])
else:
newCluster5.append(cluster5[k])
cluster1 = newCluster1
cluster2 = newCluster2
cluster3 = newCluster3
cluster4 = newCluster4
cluster5 = newCluster5
centroid1 = getMeanValue(cluster1)
centroid2 = getMeanValue(cluster2)
centroid3 = getMeanValue(cluster3)
centroid4 = getMeanValue(cluster4)
centroid5 = getMeanValue(cluster5)
j -= 1print("Cluster1")
print(cluster1)
print("Cluster2")
print(cluster2)
print("Cluster3")
print(cluster3)
print("Cluster4")
print(cluster4)
print("Cluster5")
print(cluster5)
print("Centroid 1")
print(centroid1)
print("Centroid 2")
print(centroid2)
print("Centroid 3")
print(centroid3)
print("Centroid 4")
print(centroid4)
print("Centroid 5")
print(centroid5)
如果你觉得这段代码有用,请查看我的开源 Github 库和我参与的其他代码项目:https://github.com/CShorten
另外,请在媒体上关注我,获取更多类似的文章,发表在值得关注的。
CShorten
是佛罗里达大西洋大学的计算机科学学生。对软件经济学、深度学习和软件工程感兴趣。请关注我的频道,获取这些领域的更多文章。
KNN # 3——编码我们的乳腺癌分类器
原文:https://towardsdatascience.com/knn-3-coding-our-breast-cancer-classifier-503b804988f8?source=collection_archive---------9-----------------------
给我看看代码!
为了开始这个项目,我们需要数据,让我们下载在之前的文章中看到的乳腺癌威斯康星州数据集。
阅读上一篇文章,您可以知道如何下载数据文件
在我们开始之前的一些观察,在我找到那个数据集之后,我在那里做了一些非常简单的修改:
- 我删除了 ID 列,因为它不能帮助我们对癌症类型进行分类;
- 我把班级列的位置改到了最后一列;
下载后,您有两个选择:
—通过此链接下载我修改的一个数据集,方便 KNN 开发;
或者
—按部就班地执行,并使代码适应数据集;
好了,我们开始吧!首先,本教程的完整代码在 github 的这个链接上。
当您有了数据集后,让我们在项目文件夹中创建一个名为“datas”的文件夹,并将所有数据集放在那里。
在根文件夹中,我们将创建名为 main.go 的文件
我使用 VS 代码编辑器来开发这个算法,但是你可以使用任何你想要的其他文本/代码编辑器。
让我们定义包名并创建主函数。
为了开始我们的项目,我们需要将数据集加载到内存中,所以让我们创建一个方法来读取 csv 并返回一个数组给我们。
现在,我们的整个数据集都在变量" records "
中,如果我在终端中打印变量的值,我们将得到以下输出。
fmt.Println(records)…[7.76 24.54 47.92 181 0.05263 0.04362 0 0 0.1587 0.05884 0.3857 1.428 2.548 19.15 0.007189 0.00466 0 0 0.02676 0.002783 9.456 30.37 59.16 268.6 0.08996 0.06444 0 0 0.2871 B]]
然后我们有我们的数据集,我们将进行几次迭代,并应用我们在文章# 1 中看到的所有理论。
得到数据集后的下一步,将把它分割成 2 部分,第一部分是训练数据,第二部分是测试数据。
训练数据:这是已经分类的数据,我们将用它来训练我们的算法;
测试数据:是我们用来验证我们算法准确性的分类数据;
让我们将数据集划分如下,对于每个类,我们将获得 70%的数据训练,每个类的剩余部分(30%)用于测试。
首先让我们从数据集中提取唯一的类,为此我们将使用以下逻辑;
-
从我们的数据集(记录)中提取包含类值的列;
->Make distinct()清除重复值从而得到我们唯一的类;
【getcolum(…)】
getCollum 方法接收一个矩阵和一个列索引作为参数,所以我们使用 column index 变量进入矩阵的列索引,并且对于该列中的每一行,我们将它添加到一个我们将要返回的新数组中。
【独特(……)】
通过 getcolum 返回,我们将把这个值传递给 distict()方法,该方法接收一个数组作为参数,并且对于这个数组的每个元素:
-
验证这个相同的元素是否在“en centred”映射(字典)
-
中,如果它不存在,它将把这个元素添加到“en centred”映射变量
-
中,如果它存在,什么也不做;最后,我们将把地图放回没有重复分类的地方。
当我们打印值“classes”时 fmt。Println (classes) 我们将拥有一个包含两个值的数组【M,B】
让我们遍历这些类,从每个类中获取 70%的数据用于训练,30%的数据用于测试。
让我们用 70%和 30%的数据创建我们的训练矩阵和测试矩阵;
getValuesByClass()方法接收一个数组和一个类,所以我们将过滤我们的数组以获得特定的类数据。
在第一次迭代中,数组中的值对应于单个类,例如:m。
在第二次类循环迭代中,变量“values”将包含对应于类:b 的数据。
在我们仅过滤了对应于某个类的数据后,我们需要将它划分为训练数据和测试数据,我们将在以下代码中执行此操作:
当我们将测试和训练数据放入循环的范围时,让我们将数组放入循环范围之外。
我知道,用一个循环来连接一个数组/片并不是最好的方法,但是请记住,我是以我所能做到的最有启发性的方式来编码的,所以请随意修改它。
分离数据后,我们来测试一下!
让我们对测试数据集中的每一行进行排序,并统计我们命中了多少行,错过了多少行。
最后我们可以打印一些小东西:
fmt.Println(“Total de dados: “, len(records))
fmt.Println(“Total de treinamento: “, len(train))
fmt.Println(“Total de testes: “, len(test))
fmt.Println(“Total de acertos: “, hits)
fmt.Println(“Porcentagem de acertos: “, (100 * hits / len(test)), “%”)
最后,当我们在终端中运行“go run main.go”时,我们将得到以下结果:
Total de dados: 569
Total de treinamento: 513
Total de testes: 513
Total de acertos: 484
Porcentagem de acertos: 94 %
在这种情况下,人们对哈林 22 岁以下的孩子进行了分类:
如果你想看看你的算法的命中和错误数据,我们可以通过取消注释上面要点的第 22 行来打印测试数据的分类:
//fmt.Println(“tumor: “, test[i][columnIndex], “ classificado como:
e .泰雷莫斯·塞吉特·萨伊达:
我们将得到以下输出:
tumor: M classificado como: B
tumor: M classificado como: M
tumor: M classificado como: M
tumor: M classificado como: M
tumor: M classificado como: M
tumor: M classificado como: M
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
Total de dados: 569
Total de treinamento: 513
Total de testes: 513
Total de acertos: 479
Porcentagem de acertos: 93 %
感谢阅读所有内容,希望你觉得很有用。
蟒蛇皮 KNN
原文:https://towardsdatascience.com/knn-in-python-835643e2fb53?source=collection_archive---------7-----------------------
Photo by <a href=”https://stocksnap.io/author/11667">Henry Lorenzatto from <a href=”https://stocksnap.io">StockSnap
摘要
在这篇文章中,你将了解到一个非常简单的但强大的算法,叫做 KNN 或K-最近邻。第一部分将包含该算法的详细而清晰的解释。在本文的最后,你可以找到一个使用 KNN(用 python 实现)的例子。
KNN 解释道
KNN 是一种非常流行的算法,它是十大人工智能算法之一(参见十大人工智能算法)。它的流行源于这样一个事实,即它非常容易理解和解释,但很多时候它的准确性与其他更复杂的算法相当,甚至更好。
KNN 是一种监督算法(这意味着训练数据被标记,参见监督和非监督算法),它是非参数和懒惰(基于实例)。
为什么是懒?因为它不显式学习模型,但它保存所有训练数据并使用整个训练集进行分类或预测。这与其他技术形成对比,如 SVM,你可以毫无问题地丢弃所有非支持向量。
这意味着训练过程非常快,它只是保存数据集中的所有值。真正的问题是巨大的内存消耗(因为我们必须存储所有的数据)和在测试时间的时间复杂度(因为给定的观察分类需要运行整个数据集)。但总的来说,在小数据集的情况下(或者如果你有大量的时间和内存)或出于教育目的,这是一个非常有用的算法。
另一个重要的假设是,该算法要求数据在度量空间中。这意味着我们可以定义 度量来计算数据点之间的距离。定义距离度量可能是一个真正的挑战(参见最近邻分类和检索)。一个有趣的想法是使用机器学习来寻找距离度量(主要是通过将数据转换到向量空间,将对象之间的差异表示为向量之间的距离并学习那些差异,但这是另一个主题,我们稍后会谈到这一点)。
最常用的距离度量是:
- 欧几里德距离:
这是我们在日常生活中使用的几何距离。它的计算方法是两个感兴趣点的平方差之和的平方根。
公式在 2D 空间中:
- 曼哈顿距离:
使用绝对差的和计算实向量之间的距离。也叫城市街区距离。你可以把这想象成在一个组织成矩阵的城市中行走(或者在曼哈顿行走)。街道是矩阵中小方块的边缘。如果你想从方块 A 到方块 B,你必须走在小方块的边缘。这比欧几里得距离要长,因为你不是从 A 到 B 一直走,而是之字形。
公式在 2D 空间中:
- 闵可夫斯基距离:欧几里德距离和曼哈顿距离的推广。计算 N 维距离的通用公式(见闵可夫斯基距离)。
- 汉明距离:计算二元向量之间的距离(参见汉明距离)。
KNN 用于分类
非正式的分类意味着我们有一些标记的示例(训练数据),对于新的未标记的示例(测试集)我们希望基于训练集的经验教训分配标签。
正如我前面所说,KNN 算法是懒惰的,在训练阶段没有学习或推广。实际工作是在分类或预测时完成的。
KNN 算法的步骤是(形式伪代码):
- 为来自训练集的所有 i 数据点初始化 selectedi = 0
- 选择一个距离度量(假设我们使用欧几里德距离)
- 对于每个训练集数据点 i 计算distance ei=新数据点与训练点 i 之间的距离
- 选择算法的 K 参数( K =考虑的邻居数量),通常是奇数,这样可以避免多数投票中出现平局
- 对于 j = 1 到 K 循环通过所有的训练集数据点,并在每一步中选择与新观测值具有最小距离的点(最小 距离 )
- 对于每个现有类别计算 K 个选定数据点中有多少是该类别的一部分(投票****
- 将具有最大计数(最高票数)的班级分配给新的观察——这是多数投票。****
好吧,可能上面的正式伪代码有点难以理解,所以我们来看看非正式解释。
主要思想是,对于新的观察,我们搜索 K 个最近点(具有最小距离)。这些点将通过多数表决来定义新观察的类别。
例如,如果我们有两个类,红色和绿色,在计算距离并获得 3 个最近的点之后,其中 2 个是红色,1 个是绿色,那么通过多数投票选择的类是红色(2 > 1)。
如果我们不得不面对以下情况:
我们有两个班,红色和绿色和一个新的观察,黑色的星星。我们选择 K = 3,因此我们将考虑距离新观测值最小的 3 个点。该恒星接近 3 个红点,因此很明显,这个新观测结果将被归类为红点。
在上面的图片中,我把星星移近了绿点。在这种情况下,我们选择了 2 个红色点和 1 个绿色点。因为 2 > 1,所以这颗星仍然被归类为红色。
随着我们越来越靠近绿点,选择红色作为标签的信心下降,直到新的观察结果将被分类为绿色。这是红色阶级和绿色阶级的界限,不同国家的情况也是如此。所以从不同的角度来看,我们可以说用这个算法我们建立了类的边界。边界由 K 值控制。小 K 将导致清晰的边界,而大 K 将导致平滑的边界。最有趣也是最重要的部分,就是在你的特定数据集的背景下,如何选择 K 的最佳值。在下面几节中,我们将看到如何选择 k 的最佳值。****
我在上面描述的并不一定意味着KNN 算法将总是线性比较测试样本和训练数据,就好像它是一个列表一样。训练数据可以用不同的结构表示,如 K-D 树或球树。
另一个改进是我们可以为分类中更重要的属性分配权重。这样,如果我们知道在我们的数据集中有一些重要的属性需要考虑,我们可以给它们分配更高的权重。这将导致它们在给新的观察分配标签时具有更大的影响。权重可以是统一的(所有邻居的同等优势)或与邻居到测试样本的距离成反比。你也可以设计自己的权重分配算法(例如使用另一种人工智能算法来寻找最重要的属性,并给它们分配更高的权重)。****
KNN 预测
KNN 算法也可用于预测新值。最常见的例子是用 KNN 预测某物(房子、汽车等)的价格。)基于训练数据。为了预测新值,KNN 算法几乎是相同的。在预测的情况下,我们计算 K 个最相似的点(相似性的度量必须由用户定义),并且基于这些点,我们可以使用公式预测新的值,例如平均、加权平均等。所以思路是一样的,定义度量计算距离(这里是相似度),选择 K 个最相似的点然后使用一个公式基于选择的 K 个点预测新值。****
计算的复杂性
为了计算 KNN 的计算复杂度,让我们考虑一个 d 维空间, k 是邻居的数量, n 是训练数据点的总数。
要了解我们如何计算这个算法的复杂度,请看看正式的伪代码!每次距离计算都需要 O(d) 运行时,所以第三步需要 O(nd) 工作。对于第五步中的每次迭代,我们通过循环训练集观察来执行 O(n) 工作,因此整个步骤需要 O(nk) 工作。第一步只需要 O(n) 工作,所以我们得到一个 O(nd + kn) 运行时。如果我们使用快速选择算法来选择具有最小距离的 K 个点,我们可以将这个运行时间复杂度降低到 O(nd) 。
如何为你的数据集选择最好的 K
您可能想知道,如何找到 K 的最佳值来最大化分类或预测的准确性。首先我必须提到的是, K 是一个 超参数,这意味着这个参数是由你,开发者选择的。我前面说过,你可以把 K 想象成控制决策边界的参数。例如:
正如你所看到的,如果 K=1,边界非常尖锐,呈之字形,但在 K = 7 的情况下,边界更平滑。因此,随着 K 值的增加,边界变得更加平滑。如果 K 是无穷大,那么所有的东西都是蓝色或红色的,基于总多数。
****训练误差率和验证误差率是我们在选择正确的 k 时需要考虑的两个参数,如果训练误差很低但测试误差很高,那么我们就要讨论关于过拟合的问题了。
过拟合发生在模型学习训练数据中的细节 和噪声到了对模型在新数据上的性能产生负面影响的程度。这意味着训练数据中的噪声或随机波动被模型拾取并学习为概念。
比较过度拟合和常规边界:
绿色 线代表过拟合 **模型**黑色** 线代表规则化模型。虽然绿线最符合训练数据,但它过于依赖该数据,并且与黑线相比,它可能对新的、看不见的数据具有更高的错误率。**
****欠拟合是指既不能对训练数据建模,也不能推广到新数据的模型。例如,对非线性数据使用线性算法将会有很差的性能。
我们必须找到中庸之道,有一个模型,可以很好地推广到新的数据,但不是太好,避免学习噪音和避免过度拟合。
如果我们表示训练错误率和测试错误率,我们将得到如下一些图表:
如您所见,当 K=1 时,训练误差为 0,因为任何训练数据点的接近点都是其自身。如果我们看看测试误差,当 K=1 时,误差非常高,这是正常的,因为我们有过拟合。随着 K 值的增加,测试误差率下降,直到达到最小值,之后误差开始再次增加。所以基本上寻找最佳 K 的问题是一个最优化问题,在曲线上寻找最小值。这种叫做弯头T42 的方法,因为测试误差曲线看起来像一个弯头。
结论是为了找到最佳 K 值,使用肘形法并在曲线上找到最小值。这可以通过蛮力很容易地完成,通过多次运行模型,每次增加 K 的值。找到最佳 K 的有效方法是使用 K-Fold 交叉验证,但我们将在最后一章(提升 AI 算法)中讨论这一点。
使用 Python 的 KNN 示例
在本例中,我们将使用 Social_Networks_Ads.csv 文件,该文件包含有关用户的信息,如性别、年龄、工资。购买栏包含用户的标签。这是一个二元分类(我们有两个类)。如果标签为 1** 则意味着用户已经购买了产品 X ,而 0 则意味着用户还没有购买该特定产品。**
这里可以下载文件:社交 _ 网络 _ 广告。
在这个例子中,我们将使用以下库: numpy、pandas、sklearn 和 motplotlib。
第一步是导出数据集。
# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd# Importing the dataset
dataset = pd.read_csv('Social_Network_Ads.csv')
X = dataset.iloc[:, [2, 3]].values
y = dataset.iloc[:, 4].values
这是一个简单的任务,因为 pandas 库包含了 read_csv 方法,该方法读取我们的数据并将其保存在一个名为 DataFrame 的数据结构中。
来自 sklearn 库的大多数算法要求属性和标签在单独的变量中,所以我们必须解析我们的数据。
在本例中(因为我们想用二维图表表示数据),我们将只使用年龄和工资来训练我们的模型。如果打开文件,可以看到前两列是用户的 ID 和性别。我们不想考虑这些属性。
****X 包含属性。因为我们不想考虑前两列,所以我们将只复制第 2 列和第 3 列(见第 8 行)。
****标签在第 4 列,所以我们将把这一列复制到变量 y 中(见第 9 行)。
下一步是将我们的数据分成两个不同的块,一个将用于训练我们的数据,另一个将用于测试我们模型的结果(测试属性将是新的观察结果,预测标签将与测试集中的标签进行比较)。
# Splitting the dataset into the Training set and Test set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)
这是另一个简单的任务,因为 sklearn 有一个名为 train_test_split 的方法,它将拆分我们的数据集,返回 4 个值,即火车属性(X_train)、测试属性(X_test)、火车标签(y_train)和测试标签(y_test)。通常的设置是将数据集的 25%用于测试,75%用于训练。如果您愿意,可以使用其他设置。
现在再看一遍数据集。您可以观察到“薪水”列中的值比“年龄”列中的值高得多。这可能是个问题,因为薪水栏的影响会高得多。你想想看,如果你有 10000 和 9000 这两个非常接近的工资,计算它们之间的距离,结果是 10000–9000 = 1000。现在,如果您将年龄列的值设为 10 和 9,则差值为 10–9 = 1,影响较小(与 1000 相比,10 非常小,就像您有加权属性一样)。
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
为了解决这个量级问题,我们必须缩放属性。为此我们使用了 sklearn 的standard scaler。****
下一步是训练模型:
**# Fitting classifier to the Training set
from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier(n_neighbors = 2)
classifier.fit(X_train, y_train)**
我们从 sklearn 导入KNeighborsClassifier。这需要多个参数。最重要的 参数有:
- n _ neighbors:k 的值,考虑的邻居数量
- 权重:如果您想使用加权属性,您可以在这里配置权重。这需要像统一、距离(到新点的反距离)或可调用这样的值,这些值应该由用户定义。默认值是统一的。
- 算法:如果你想要一个不同的数据表示,这里你可以使用 ball_tree,kd_tree 或者 brute 这样的值,默认为 auto,试图自动选择当前数据集的最佳表示。
- 度量:距离度量(欧几里德、曼哈顿等),默认为欧几里德。
我们保留所有默认参数,但对于 n_neighbors,我们将使用 2(默认值为 5)。
如果您想要预测新观察值的类别,您可以使用以下代码:
**# Predicting the Test set results
y_pred = classifier.predict(X_test)**
下一步是评估我们的模型。为此,我们将使用混淆矩阵。
**# Making the Confusion Matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)**
混淆矩阵的结果是:
正如你所看到的,我们只有 5 个假阳性和 7 个假阴性,这是一个非常好的结果(这里的准确率是 80%)。
最后一步是可视化决策边界。让我们从训练集的决策边界开始。
**# Visualising the Training set results
from matplotlib.colors import ListedColormap
X_set, y_set = X_train, y_train
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01),
np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))
plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
alpha = 0.75, cmap = ListedColormap(('red', 'green')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
c = ListedColormap(('red', 'green'))(i), label = j)
plt.title('Classifier (Training set)')
plt.xlabel('Age')
plt.ylabel('Estimated Salary')
plt.legend()
plt.show()**
meshgrid 函数用一个 x 值数组和一个 y 值数组创建一个矩形网格(这里 x = X1,y = X2)。****
contourf 方法绘制填充轮廓,所以我们用这个方法用与之相关的类的颜色填充背景。诀窍在于,对于每个像素 ,我们进行预测,并用与预测类别相关的颜色对该像素进行着色。这里我们有两个类,我们用红色和绿色表示 0 和 1。****
在行 10 和 12 a 之间,我们循环所有训练数据点,我们预测它们的标签,如果预测值为 0,将它们涂成红色,如果预测值为 1,将它们涂成绿色。
这段代码的结果是:
为了可视化测试集的边界,我们使用相同的代码,但是将 X_set,y_set 改为 X_test,y_test。运行代码来可视化测试集的边界的结果是:
正如你在上图中看到的,我们有一个非常好的模型,只有几个点被错误分类。
结论
- KNN 算法非常直观和易于理解
- 训练时间最短,模型实际上不学习或推广
- 测试时间可能会很长,因为算法在整个训练数据集上循环并计算距离(基于距离度量的类型和数据集的类型,距离计算可能是一项艰巨的工作)
- 对于小 K 值,算法可能对噪声敏感并且容易过拟合
- 数据集应该是数字的或一个距离度量应该存在以计算点之间的距离****
- 在不平衡数据上表现不佳
我真的很喜欢咖啡,因为它给了我写更多文章的能量。
如果你喜欢这篇文章,那么你可以请我喝杯咖啡来表达你的欣赏和支持!
成为媒介上的作家:【https://czakozoltan08.medium.com/membership】T2
参考
- KNearestNeighbors 解释
- KNN 完整指南
- 机器学习中的过拟合和欠拟合
- KNN 详细介绍
- Udemy —从 A 到 Z 的机器学习
- KNN 计算复杂度
如果你喜欢这篇文章,并且你想为免费学习更多有趣的 AI 算法,请订阅!
KNN (K 近邻)#1
原文:https://towardsdatascience.com/knn-k-nearest-neighbors-1-a4707b24bd1d?source=collection_archive---------1-----------------------
它是如何工作的
KNN 是什么?
KNN(K-最近邻)是数据挖掘和机器学习中使用的许多(监督学习)算法之一,它是一种分类器算法,学习基于数据(向量)与其他数据(向量)的“相似程度”。
它是如何工作的?
KNN 非常简单,假设你有一个关于彩球的数据:
- 紫球;
- 黄色的球;
- 还有一个球,你不知道它是紫色还是黄色,但是你有这个颜色的所有数据(除了颜色标签)。
那么,你怎么知道球的颜色呢?想象你喜欢一台只有球的特征(数据),没有最终标签的机器。你想知道球的颜色(最终标签/你的班级)吗?
Obs:让我们假设编号为 1(和标签 R)的数据指的是紫色的球,编号为 2(和标签 A)的数据指的是黄色的球,这只是为了使解释更容易,在以后的文章中我们将使用真实的数据。
每行表示一个球,每列表示一个球的特征,最后一列是每个球的类别(颜色):
- R - >紫色;
- 一种 - >黄色
我们有 5 个球(5 行),每个球都有你的分类,你可以尝试用 N 种方法来发现新球的颜色(在这种情况下是类别),这 N 种方法中的一种是将这个新球的特征与所有其他球进行比较,看看它看起来最像什么,如果这个新球(你不知道正确的类别)的数据(特征)与黄色球的数据相似, 那么新球的颜色是黄色,如果新球中的数据更类似于紫色然后是黄色的数据,那么新球的颜色是紫色,看起来很简单,这几乎就是 knn 所做的,但以最复杂的方式。
在 KNN 的例子中,实际上它并不“比较”新的(未分类的)数据和所有其他的,实际上他执行一个数学计算来测量数据之间的距离来进行分类,(那几乎是同样的事情)。我所说的这个计算可以是测量两点之间距离的任何其他计算,例如:欧几里得、曼哈顿、闵可夫斯基、加权...
KNN 的步骤是:
1 —接收未分类的数据;
2-测量新数据与所有其他已分类数据之间的距离(欧几里德距离、曼哈顿距离、闵可夫斯基距离或加权距离);
3-获取 K(K 是您定义的参数)较小的距离;
4-检查具有最短距离的类别列表,并计算出现的每个类别的数量;
5-将出现次数最多的类别视为正确类别;
6-用您在步骤 5 中采用的类对新数据进行分类;
下面我们有一张图片,上面是我们在本文中讨论的所有过程,您有一个未分类的数据(红色)和所有其他已分类的数据(黄色和紫色),每个数据都属于您的类别(A 或 B)。因此,您计算新数据与所有其他数据的距离,以了解哪些数据具有最小的距离,因此您获得 3(或 6)个最接近的数据,并检查哪个类出现得最多,在下图的情况下,与新数据最接近的数据是在第一个圆圈内(圆圈内)的数据,在这个圆圈内有 3 个其他数据(已经用黄色分类), 我们将检查哪个是主要的类,看,它是紫色的,因为有两个紫色的球,只有一个黄色的,所以这个以前没有分类的新数据,现在将被分类为紫色。
计算距离:
计算两点(您的新样本和数据集中的所有数据)之间的距离非常简单,如前所述,有几种方法可以获得该值,在本文中我们将使用欧几里德距离。
欧几里德距离的公式如下图所示:
等等,不要担心,它并没有听起来那么复杂,读完这篇文章并继续发现它很复杂,当我们进入代码时,你会看到它是多么简单。
使用此公式,您将检查数据集中 1 个点(您的未分类样本)和 1 个其他点(1 个其他已分类数据)之间的距离,在您的所有数据集中,一个接一个,计算结果越小,这两个数据之间最相似。是的,你将运行这个计算很多次,直到你已经在所有数据中运行它,当你这样做时,你将有一个数组(让我们用一个数组作为例子)你的未分类数据到另一个已经分类的数据的结果。
好,我们开始吧!这很简单,但慢慢读,基本上你会:
- 从数据集中获取每个特征;
- 减去每一个,例,(第 1 行,第 5 列)—(第 1 行,第 5 列)= X …(第 1 行,第 13 列)—(第 1 行,第 13 列)= Z;
- 在得到所有列的减法后,你将得到所有的结果,并将其 X+Y +Z 相加…
- 所以你会得到总和的平方根。
让我们使用前面工作表中的示例,但现在有 1 个未分类数据,这是我们想要发现的信息。
在这个例子中,我们有 5 个数据(行),每个样本(数据/行)都有你的属性(特征),让我们想象所有这些都是图像,每一行都是图像,每一列都是图像的像素。
所以让我们从上面解释混乱开始。
让我们取第一行,这是我们要分类的数据,让我们测量到第二行的欧几里德距离
1 —减法
让我们用第 2 行的属性减去第 1 行的每个属性(列),例如:
(1–2) = -1
2 —取幂:
从第 1 行减去第 1 列,从第 2 行减去第 1 列,我们将得到平方根,因此结果数字始终为正数,例如:
(1–2)² = (-1)²(-1)² = 1
3 —总和
完成第 2 步后,对于第 1 行的所有列和第 2 行的所有列,我们将对所有这些结果进行求和,让我们使用电子表格的列图像做一个示例,我们将得到以下结果:
(1–2)² + (1–2)² + (1–2)² + (1–2)² + (1–2)² + (1–2)² + (1–2)² +
(1–2)² = 8
请注意,我们在第 1 行和第 2 行都有 8 个属性列,我们为每个数据集的属性执行了第 2 步,因此最终结果是 8,但为什么是 8 呢?因为每次我们运行第 2 步,结果都是 1,出于“巧合”,我们在所有列中都有相同的数据,并且(1–2)的结果等于 1,所以我在这里使用这些值来简化数学,但是不,这个属性并不需要总是相同的数字,以后我们将在使用此算法实现代码时看到这一点。
4—平方根:
在执行了第 3 步之后,我们将得到减法的和的平方根。在第 3 步中,结果是 8,所以让我们取数字 8 的平方根:
√8 = 2,83 ou 8^(½) = 2,83
太棒了。现在你有了从第 1 行到第 2 行的欧几里得距离,看,它并没有那么难,你可以在一张简单的纸上完成!
现在,您只需要为数据集的所有行(从第 1 行到所有其他行)创建这些,在执行此操作时,您将获得第 1 行到所有其他行的欧几里德距离,然后您将对其进行排序以获得“k”(例如,k = 3)最小距离,因此您将检查哪个是出现最多的类,出现最多的类将是用于对第 1 行进行分类的类(以前没有对其进行分类)。
简单对吧。在接下来的文章中,我们将开始在 GO 中实现这个算法!不过不用担心,Go 的语法非常简单,您可以按照教程的内容,用自己的语言来应用它。
TKS!
KNN (K 近邻)#2
原文:https://towardsdatascience.com/knn-k-nearest-neighbors-2-169d667bcee5?source=collection_archive---------10-----------------------
获取数据集
如果你还没有阅读,或者不知道 KNN 是如何工作的,我建议你在继续阅读这篇文章之前,先阅读这篇[帖子](http://post antigo),这样你会发现没有代码的算法解释。
从何说起?
开始吧!首先,我们需要数据,因为没有数据,世界上就没有有效的人工智能!(如果存在,请在评论中发表)
我从哪里得到这些数据?
如果你没有阅读这篇文章来在你工作的公司实施它(你可以做到的!),你很可能没有任何数据,而且就像我之前说的,没有数据,就没有机器学习。
但是不用担心!我们有一个解决方案,数据是当今最容易获得的东西(取决于数据类型),我们将在本文中使用的格式是其中最容易的,在互联网的世界中有一个神奇的地方,那里有 N 个大小的 N 个数据集,这个地方就是 UCI 机器学习库,当我写这篇文章时,UCI 在那里维护着 425 个数据集,下载它吧!
我如何选择数据集?我对 UCI 界面一点也不了解
不要担心,这非常简单,在初始页面上,您会看到一些数据集,我将向您介绍一点平台,其余的您可以随意浏览。
在上图中,用红色标记的是 UCI 的主要储藏室,为什么它们是主要储藏室?因为它们是最容易工作的数据集,没有丢失的数据,数据分布对于机器学习等非常有用。好了,让我们进入我们将在 KNN 实现中处理的数据集,乳腺癌威斯康星州(诊断)包含乳腺癌活检诊断数据。
打开链接,你会看到一些数据集的信息,像上面的图片,如实例数(行),数据集有多少属性(列),如果有丢失的数据,数据连接到哪个区域,等等。
在同一页上,你还会发现数据集的描述,引用该数据集的论文,它包含的列,等等。
在下图中,我们有乳腺癌数据集列。
正如你所看到的(或者没有看到),我们有我们将要工作的列描述。
我们有 id(在我们的分类场景中没有用)、诊断(我们的分类数据)、半径、纹理、周长等,这些其他数据是我们将用于进行肿瘤分类的属性,无论它是恶性还是良性。
但是在哪里可以下载这些数据呢?
在数据集名称旁边,你将有两个链接,数据文件夹,数据集描述
从左边开始,数据集描述基本上是关于数据集的信息,通常是纯文本格式,数据文件夹链接是数据集本身所在的位置。
红色选项是要下载的正确文件。
如果你一步一步地阅读这个关于 knn 的系列文章,我建议你不要下载 uci 库中包含的文件,在下一集里,我们将对这个数据进行一些处理,我将为我们的 knn 提供一个准备好的数据集。
机器学习— KNN 使用 scikit-learn
原文:https://towardsdatascience.com/knn-using-scikit-learn-c6bed765be75?source=collection_archive---------1-----------------------
KNN(K-最近邻)是一种简单的监督分类算法,我们可以使用它来为新的数据点分配类别。它也可以用于回归,KNN 没有对数据分布做任何假设,因此它是非参数的。它保留所有训练数据,通过计算输入样本和每个训练实例之间的相似性来进行未来预测。
KNN 可以概括如下:
- 计算每个训练示例的新数据点之间的距离。
- 为了计算距离,将使用欧几里德距离、汉明距离或曼哈顿距离等距离度量。
- 模型在数据库中挑选 K 个最接近新数据点的条目。
- 然后,它进行多数表决,即这 K 个条目中最常见的类别/标签将是新数据点的类别。
With K=3, Class B will be assigned, with K=6 Class A will be assigned
关于 KNN 的详细文件可以在这里找到。
以下示例显示了使用 scikit-learn 库在 iris 数据集上实现 KNN。Iris 数据集对每种不同的鸢尾花有 50 个样本(总共 150 个)。对于每个样本,我们有萼片长度、宽度、花瓣长度和宽度以及物种名称(类别/标签)。
Iris flower: sepal length, sepal width, petal length and width
- 150 观察
- 4 特征(萼片长度、萼片宽度、花瓣长度、花瓣宽度)
- 响应变量是鸢尾物种
- 分类问题,因为响应是分类的。
我们的任务是建立一个 KNN 模型,根据萼片和花瓣的测量结果对新物种进行分类。Iris 数据集在 scikit-learn 中可用,我们可以利用它来构建我们的 KNN。
完整的代码可以在 Git Repo 中找到。
第一步:导入所需数据并检查特征。
从 scikit-learn datasets 模块导入 load_iris 函数,并创建一个 iris Bunch 对象(Bunch 是 scikitlearn 用于存储数据集及其属性的特殊对象类型)。
每次观察代表一朵花,4 列代表 4 次测量。我们可以在“数据”属性下看到特征(测量值),而在“特征名称”下看到标签。正如我们在下面看到的,标签/响应被编码为 0、1 和 2。因为对于 scikit-learn 模型,特征和静止应该是数字的(Numpy 数组),并且它们应该具有特定的形状。
第二步:拆分数据,训练模型。
对相同的数据进行训练和测试并不是一种最佳的方法,所以我们将数据分成两部分,训练集和测试集。我们使用‘train _ test _ split’函数来拆分数据。可选参数“测试大小”决定了分割百分比。“random_state”参数使数据在每次运行时以相同的方式分割。由于我们是在不同的数据集上进行训练和测试,因此得到的测试精度将更好地估计模型在看不见的数据上的表现。
Scikit-learn 被仔细地组织成模块,这样我们就可以很容易地导入相关的类。从“NeighborsClassifer”模块导入类“KNeighborsClassifer”并实例化估计器(“估计器”是 scikit-learn 对模型的术语)。我们称模型为估计器,因为它们的主要作用是估计未知量。
在我们的示例中,我们创建了一个“KNeighborsClassifer”类的实例(“knn”),换句话说,我们创建了一个名为“knn”的对象,它知道在我们提供数据后如何进行 KNN 分类。参数“n_neighbors”是调整参数/超级参数(k)。所有其他参数都设置为默认值。
“拟合”方法用于根据训练数据(X_train,y_train)训练模型,而“预测”方法用于根据测试数据(X_test)进行测试。选择 K 的最佳值至关重要,因此我们使用 for 循环来拟合和测试不同 K 值(从 1 到 25)的模型,并在变量(分数)中记录 KNN 的测试精度。
使用 matplotlib 库绘制 K 值与相应测试精度之间的关系。正如我们所看到的,精确度有升有降,这在用精确度检查模型复杂性时非常典型。一般来说,随着 K 值的增加,精度似乎会提高,但又会下降。
一般来说,训练精度随着模型复杂性的增加而提高,对于 KNN,模型复杂性由 K 值决定。K 值越大,决策边界越平滑(模型越不复杂)。较小的 K 导致更复杂的模型(可能导致过度拟合)。测试准确性会对过于复杂(过度拟合)或不够复杂(拟合不足)的模型造成不利影响。当模型具有适当的复杂程度时,我们得到最大的测试精确度,在我们的例子中,我们可以看到,对于 3 到 19 的 K 值,我们的模型精确度是 96.6%。
对于我们的最终模型,我们可以选择 K 的最佳值为 5(介于 3 和 19 之间),并用所有可用的数据重新训练该模型。这将是我们最终的模型,可以做预测了。
感谢您的阅读,如果您有任何建议/修改,请告诉我们。
了解你的对手:理解对手的例子(第 1/2 部分)
原文:https://towardsdatascience.com/know-your-adversary-understanding-adversarial-examples-part-1-2-63af4c2f5830?source=collection_archive---------0-----------------------
这可能只是一个不可避免的焦点偏差:任何你盯着看足够长时间的问题都会因为你的关注而变得更有兴趣和意义。但是,也就是说,在过去的一周里,我花了很多时间研究对立的例子,我开始将它们视为机器学习世界核心问题的迷人症结:将学到的知识映射到人类概念的困难,一个人的训练集带来的内在限制,以及对在安全化设置中用原则理解换取数字优化的担忧。
我对这一主题的探索是由一个关键问题引发的:对立的例子仅仅是研究人员的一个有趣的玩具问题,还是我们的模型中更深层和更长期的弱点的一个例子?然而,要以任何连贯的方式回答这个问题,首先需要建立一些背景知识。这篇文章是两篇文章中的第一篇,致力于建立对这些攻击如何以及为什么起作用的直觉;第二篇文章将在本周晚些时候发表,重点是思考防御和实际攻击场景。
对立的例子是如何制作的?
曾几何时,在 2013 年的太平日子里,早在 Batch Norm 和 ResNets 和 GANs 之前,谷歌的一个小组发表了“神经网络的有趣特性”,其中作者发现了他们正在试验的模型的一个令人担忧的事实:你经常可以诱导网络改变标签的预测类别,而不改变人类对图像的感知方式。
And in the right-hand column we have: entirely giraffes. According to the network, at least.
让这些例子具有对抗性的特殊因素是,只需要施加很少的扰动,就可以让网络改变对正确分类的想法。一般来说,训练有素的模型的一个特点是,它们对少量的噪声相对不变。而且,当涉及到随机噪声时,事实上通常是这样的——实验通常已经证实,向图像添加真正的“白噪声”通常不会影响性能良好的模型的预测。但是,当涉及到非随机噪声,即专门设计来“愚弄”网络的噪声时,这种噪声的数量少得惊人,远远小于人眼可察觉的数量,可以有意义地改变网络的最终输出。
在过去的四年中,新的攻击技术被添加到文献中,每种技术都有自己的细微差别、权衡和怪癖。但所有对立的例子都有一个基本的概念基础:使用(可能是近似的)模型内部状态的知识来寻找输入像素的小修改,这将导致模型有最大的错误机会。
如前所述,使一个例子具有对抗性的关键特征,至少在通俗的说法中,是人类对变化的不易察觉性。显然,当你自动创建示例时,让一个人陷入循环的代价是惊人的,所以研究人员不得不开发“难以察觉的差异”的代理,基于捕捉原始图像和它的扰动邪恶双胞胎之间的差异的度量。
- L⁰距离:图像 x 和图像 z 之间数值不同的像素总数是多少?
- L 距离:图像 X 和图像 Z 的总和绝对值差是多少?
(对于每个像素,计算差值的绝对值,并对所有像素求和) - L 距离:图像 X 和图像 Z 的平方差是多少?(对于每个像素,取图像 X 和 Z 之间的距离,将其平方,并对所有像素求和)
- L^infinity 距离:图像 x 和图像 z 的最大像素差是多少?如果你通读了这篇文章链接的一些论文,你会听到这被称为“最大常态”。
(对于每个像素,取 X 和 Z 之间的绝对值差,并返回在所有像素上找到的最大距离)
你会注意到所有这些距离都用 L 和一个数字来表示。理解这个数字背后的精确数学逻辑是不必要的,但一个有用的启发是,数字越高,距离受异常值的影响就越大。在 L⁰距离中,变化 0.001 的像素与变化 10 的像素的影响一样大,因为该度量仅考虑有任何变化的像素总数。相比之下,在 L-infinity 距离中,唯一重要的是具有最大变化量的像素,而不考虑可能已经被修改的其他像素的数量。L-infinity 或最大范数距离是最常用的,但其他距离偶尔也会出现。有了这些直觉,我们可以继续讨论一些攻击方法。
最早也是最简单的技术叫做快速梯度符号法。在这个攻击中,第一步是计算你的成本相对于输入像素的梯度。起初,这可能是一个有点奇怪的概念,因为在反向传播中,我们通常根据模型参数来考虑梯度:如果我们修改这个权重或那个权重,这种变化会对总损失产生多大影响?但是网络的输出是其输入像素的函数,也是其参数的函数;我们通常只考虑修改后者,因为数据是固定的,我们正在更新参数以适应它。但是,如果我们想象一个已经训练好的模型,我们可以翻转问题:不是优化参数来减少损失,保持图像不变,我们可以优化图像像素来增加损失,保持参数不变。
一旦我们获得了输出相对于像素的梯度,我们将最终得到一个像素矩阵(或张量),其大小与输入图像相对应,填充有指示如果像素值更新一个单位,损失会改变多少的值。然后,FGSM 取梯度矩阵,并取它的符号。也就是说:它减少了浮点值的矩阵,使得它完全包含-1(对于所有负值)或+1(对于所有正值)。一旦你有了符号矩阵 S,这个方法选择某个值ε,并将两者相乘,这样你就有了一个充满+ε或-ε的矩阵。然后,你把这个矩阵加到输入像素矩阵中,你就有了一个对立的例子。
这个解释有点复杂,但我认为对这种攻击有一个过于清晰的理解有助于为其他人建立直觉,所有这些都有一个广泛的概念方法,即“使用内部模型参数的知识,以一种明确优化的方式干扰您的更新,以降低正确分类的可能性”。已经开发的一些其他攻击包括:
- 应用 FGSM,但是多次执行计算梯度的步骤,这样我们在恶化模型的方向上采取多个“步骤”。通常,完成此操作后,总的可能距离是有上限的,因此即使您采取了多个步骤,您与输入的 L-infinity 距离也不会超过一个固定值。
- Deep Fool ,其迭代地“线性化”输入点处的损失函数(取该点处损失函数的正切值),并且如果该线性近似是正确的,则应用切换类所必需的最小扰动。它多次执行该过程,每次使用先前的输入+先前的扰动作为输入,直到网络选择的类别切换。(对于倾向于线性代数的人来说,线性情况下的“最小必要扰动”相当于将输入向量投影到局部线性化模型的“决策边界”上)
- Carlini 的攻击,一种在样本被原模型误分类的约束下,直接优化与原样本距离最小的方法。这是一种代价更高的攻击,因为它涉及到解决一个重要的优化问题,即使使用 Carlini 在论文中建议的松弛方法。然而,这是非常有效的,包括对防御,阻止早期品种的对抗性的例子。据我所知,这是目前的重量级攻击冠军。
令人惊讶的罪魁祸首:模型线性
有了对什么是机械的、对立的例子的清晰理解,你就可以进入真正有趣的问题:它们为什么存在?如果有的话,它们的存在对现代模型的质量和稳定性说明了什么?
我试图回答这些问题,我是如何了解到一些关于对立例子的真正令人惊讶的事情的:当前研究人员的共识是,对立例子不是过度拟合的产物,而是高维输入和现代模型的内部线性的产物。
这个断言的一些部分很奇怪,不直观有点轻描淡写,但让我们从对立的例子与高维线性相关的评估开始。出现这种情况的基本逻辑是:线性模型进行推断,在训练数据集中的区域之外,它们的行为可能非常病态。这种外推是由以下事实引起的:根据线性模型的线性定义,每个要素都具有相同的部分斜率,而不管其值或其他要素的值如何。也就是说:模型不会因为到达了从未看到训练数据的区域而变平。如果您设法在与决策边界完全一致的方向上将您的输入从训练数据区域推开,您可以到达决策空间的一部分,该部分模型非常确定对应于不同的类别。
In the example above, if we move in a direction perpendicular to the decision boundary, we can, with a relatively small-magnitude vector, push ourselves to a place where the model is very confident in the wrong direction
此外,在高维空间中,每个单独的像素可能仅增加非常小的量,但是这些小的差异导致权重*输入点积的显著差异,因为所有这些小的差异都乘以权重,然后求和在一起。Andrej Karpathy 关于主题的博客文章进一步阐述了这种直觉,并证实了用单层线性逻辑分类器观察对立例子的可能性。
Seems legit
现在,让我们把注意力转向这句话的另一个令人惊讶的部分:断言深度模型的问题是它们太线性了。乍一看,这似乎很荒谬:深度网络从定义上来说是非线性的。如果深度网络没有非线性激活函数,它们不会比单层线性函数更复杂,也没有希望学习它们实际学习的函数。此外,深度网络需要非线性才能工作,这是正确的。但是,在可能的非线性激活函数的空间内,现代深度网络实际上已经确定了一个非常接近线性的激活函数:ReLu。
The fault is not in our stars, but in our activation functions, for they are linear
由于 ReLu 具有相当大的置零区域,因此可以称之为非线性,但它也有很大的空间,对于大于 0 的输入,它实际上只是作为线性函数工作。与 sigmoid 或 tanh 激活相比,它们在高激活时会简单地饱和到一个上限值,使用前面部分概述的逻辑,可以将 ReLu 激活推到任意高的值。
关于激活的选择,一个有趣的问题是在可训练性和对抗攻击的鲁棒性之间的权衡。tanh 和 logistic 函数难以训练的一个关键原因是,尾部的饱和区域,激活的斜率(以及梯度值)可能会“卡”在非常接近 0 的位置。这将使网络中来自后面点的任何梯度归零,并使网络的前面位没有任何信号可供学习。当用 tanh 和 sigmoid 训练时,游戏的名字是试图以某种方式保持你的激活在激活的中间区域,在那里梯度大致是线性的,所以你保持你的梯度活着。
相比之下,ReLu 在 0 右侧的任何地方都有非零梯度,这使得它的训练更加稳定和快速。计算起来也更容易,因为您只需要计算一个“检查符号”操作,并根据该操作的结果用 0 或激活的当前值来响应。
然而,从对立例子的角度来看,tanh 和 logistic 的饱和的有益副作用是激活被非线性地限制,使得更难以激发在线性激活中看到的病理性高水平的置信度。
详细引用 Ian Goodfellow 关于主题的关键论文:
使用设计成足够线性的网络——无论是 ReLU 或 maxout 网络、LSTM 还是经过精心配置不会过度饱和的 sigmoid 网络——我们都能够解决我们关心的大多数问题,至少在训练集上是如此。对立例子的存在表明,能够解释训练数据,甚至能够正确标记测试数据,并不意味着我们的模型真正理解我们要求它们执行的任务。相反,他们的线性响应在数据分布中不存在的点上过于自信,而这些自信的预测往往是非常不正确的。…人们也可能得出结论,我们使用的模型族存在固有缺陷。优化的简易性是以模型容易被误导为代价的。
在这种框架中,对立的例子呈现出一种奇怪的悲剧叙事:它们是隐藏在一种技术中的意想不到的弱点,而这种技术至少目前是现代网络的基本必需品。那么,这个数学上的致命弱点有多严重呢?有没有任何现有的防御措施成功地使模型变得健壮?哪种攻击场景或威胁模型最有可能或最有效?我们怎么能想象这种数字漏洞会在现实世界中被利用呢?这些是我将在本系列的下一篇文章中重点讨论的问题。
了解您的数据|第 1 部分
原文:https://towardsdatascience.com/know-your-data-part-1-c6bd56553ae8?source=collection_archive---------12-----------------------
在我之前的文章中,我们讨论了大数据和机器学习之间的化学反应。我们还得出这样一个事实:为了建立一个好的学习模型,我们首先需要很好地理解我们的数据。
下图代表了机器学习和数据挖掘的一般过程。数据清理和特征提取是最繁琐的工作,但你需要擅长它,使你的模型更加准确。
什么是数据或数据集?
数据对象及其属性的集合。属性捕获对象的基本特征。让我们检查一下著名的泰坦尼克号数据集,这里有。它表示乘客信息及其生存状态的列表(survived=0/1)。
每行代表一个乘客对象,列基本上是该乘客的特征,也称为属性。属性值是数字或一些类别。Ex Age 是数字,但 Pclass 基本上代表乘客级别(1 表示头等舱,2 表示二等舱……)
属性类型?
要理解数据,首先需要理解不同类型的属性。属性的类型取决于它拥有以下哪些属性:
清晰度:=,!=
订单:< >
追加:+ -
乘法: /*
Nominal
遵循 distinctness 属性,例如:ID 号、眼睛颜色、邮政编码。
最终的结果
遵循独特性和顺序,例如:等级(例如,从 1-10 分制的薯片味道)、级别、身高(高、中、矮)
间隔
遵循区别,顺序和附加,例子:日历日期,摄氏或华氏温度。
比率
遵循所有四个属性,例如:开尔文温度,长度,时间,计数
根据属性值,我们可以说属性有两种类型。
离散属性: 它会有有限或可数无限的值集合,邮政编码、Pclass 都是这方面的完美例子。二进制属性是离散属性的特殊形式(大数据集中的幸存属性就是二进制属性的一个例子)
连续属性: 它会有实数作为值,例如:泰坦尼克号数据集中的票价。
数据集的类型?
- 记录数据集:由具有固定属性集的记录集合组成,也称为结构化数据。下面是几个记录数据集的例子。
Data Matrix
Document Data
Transaction Data
- 图表数据集:
World Wide Web
Molecular Structures
- 有序数据集:
Sequential Data
Temporal Data
在本文中,我们了解了不同类型的数据集、数据对象和属性。在我的下一篇文章中,我们将了解与数据集相关的问题,以及如何识别和处理它。我们还将通过一个例子演示如何在 Titanic 数据集上进行特征提取。
感谢您的阅读,请在评论中分享您的想法、反馈和想法。你也可以通过 twitter 上的@ simplykk87 和 linkedin 上的联系我。
参考文献
数据挖掘导论,庞-谭宁,密歇根州立大学,
迈克尔·斯坦巴克,明尼苏达大学维平·库马尔,明尼苏达大学
利用神经网络挖掘黑暗知识——知识提炼
原文:https://towardsdatascience.com/knowledge-distillation-and-the-concept-of-dark-knowledge-8b7aed8014ac?source=collection_archive---------5-----------------------
动机:任何 ML/AI 模型的主要目标都取决于它对未知数据的概括能力,而不是它对训练数据的表现。如果我们更仔细地观察这个目标,那么为了训练和推理的目的,最好有不同的模型适应。在训练期间,我们需要深度和复杂的模型,以便在大量训练数据上进行训练,但在推理期间,我们只需要一个较轻的模型,它可以很好地概括任何看不见的数据。在生产中,较轻的模型显然在推理时间具有良好的性能。因此,本文的背景设置是要看看是否有一种有效的方法来将这些一般化的知识提取到一个更轻量级的模型中,以便两全其美。
注意:神经网络和 MNIST 数字识别任务在本文中被用作参考来说明知识提炼的概念,但是相同的概念可扩展到任何 ML/AI 模型。
【https://arxiv.org/abs/1503.02531】参考:这里所说的想法和概念都出自这篇参考文章: 参考:
Keras 中这篇文章的完整代码:https://tinyurl.com/yb4en6e3
迁移学习的区别&知识提炼:迁移学习和知识提炼的目的有很大不同。在迁移学习中,权重从预训练的网络转移到新的网络,并且预训练的网络应该精确地匹配新的网络架构。这意味着新的网络本质上和预先训练的网络一样深入和复杂。
然而,知识提炼的目的是不同的。目标不是转移权重,而是将复杂模型的一般化转移到更轻的模型。但是等等…我们知道权重是如何转移的…但是我们如何转移一般化呢?如何量化一个复杂网络的一般化?进入师生网的术语,softmax 激活中的 concept of temperature,暗知和软化概率……让我们一个一个来了解这其中的每一个。
师生模型:参考下图 1。在本例中,教师是一个深度神经网络,它已经用足够好的正则化对大量数据进行了训练(或者它可以是任何其他集成模型),因此它的主要目标是可以对看不见的数据进行很好的概括。学生网络是一个浅浅的网络,将由老师训练,其主要目标是——学习大多数老师的概括,并且仍然更浅。考虑到严格的生产限制,更轻的模型显然在生产中更受欢迎,因为它可以快速预测。在掌握了剩余术语后,我们将回到这个主题。
Fig : 1, Teacher-Student architecture for knowledge distillation — image credits Ravindra Kompella, Dhee Yantra solutions
soft max 激活中的温度概念:
使用 softmax 的主要优势是输出概率范围。输出概率的范围将从 0 到 1 ,所有概率的总和将是等于 1。它返回每个类的概率,目标类将具有最高的概率。
Fig 2a : Regular Softmax function
该公式计算给定输入值的指数(e 次方)以及输入中所有值的指数值之和。那么输入值的指数与指数值之和的比值就是 softmax 函数的输出。
Fig 2b : High temperature softmax
当我们将输入—‘z’(在神经网络中也称为 logit)除以‘T’(温度)时,获得高温 softmax 激活函数。
为了说明温度对 softmax 激活的影响,考虑下面图 3 中的曲线。正如可以观察到的,预测数字‘7’的概率变得软化,并且随着温度的升高而软化。我们所说的软化概率是什么意思?
如果您沿着绿线(在更高的温度=7 时绘制)并仔细观察概率值,您可以看到该模型清楚地显示出一个事实,即它预测的数字“7”看起来更像 9 或 1,而不是 6(6 的预测概率小于 0.01,而 1 的预测概率约为 0.075)。
如果您沿着橙色/蓝色线(在较低温度下绘制)并仔细观察概率值,您可以看到模型预测数字“7”的可信度非常高,但无法区分预测的数字 7 更接近 1 还是 6(它们都具有“非常接近零”的概率)。
Probability prediction for the number ‘7’ digit at varied temperatures, Image credits Ravindra Kompella, Dhee Yantra solutions
黑暗知识:我们可以通过查看手写数字“7”(如下图所示)来很好地关联我们自己的猜测,并判断它是否与 1 相似——这很像这个模型,它在高温下预测数字“7”时输出“1”的概率更高。
number one
number seven..oh wait..or is it number 1 ?
唯一的区别是,我们人类无法量化“7”看起来有多接近 1,而高温模型却可以很准确地做到这一点。因此,高温模型被认为具有黑暗知识——即,除了预测数字“7”之外,它还存储了数字“7”与数字“1”有多相似的信息。
低温模型(我们在 softmax 中通常遇到的没有温度的模型)通常擅长硬预测,我们会失去这些黑暗的知识。知识提炼背后的主要思想是将这种黑暗的知识从训练有素的教师转移到更轻松的学生模型中。
师生培训:现在我们已经理解了上下文和所有其他重要术语,让我们回到师生模型中我们离开的地方。将这些概括传递给学生的工作原理非常简单,如图 1 所示。在训练学生时,不是将一次性编码值作为硬目标,而是将这些软化概率(通过应用高温 softmax 收集的输出)作为目标。我们还可以定制知识提取损失函数(参见图 1 ),将知识提取损失计算为软目标+硬目标的连接向量的相应分量之间对数损失的加权平均值。
结果表明,以这种方式从老师那里训练的学生(观察到精度提高了 1%到 2%)能够比在相同数据上训练的独立学生更好地对看不见的数据进行概括。这里有几个重要的注意事项—
- 学生在和老师一样的高温下接受训练
- 学生模型中的推论将通过通常的 softmax 激活来完成(即没有温度)。
https://tinyurl.com/yb4en6e3:的这篇文章的全部代码
知识提炼的优势:可以看出,这种知识提炼过程有几个优势:
- 使用较轻的型号
- 在严格的生产限制下,降低计算要求并提供卓越的性能
- 比独立模型精度更高
- 即使学生模型的可用训练数据较少,也可以使用。有一个训练有素的老师就足够了。
科尔莫戈罗夫-斯米尔诺夫试验
原文:https://towardsdatascience.com/kolmogorov-smirnov-test-84c92fb4158d?source=collection_archive---------0-----------------------
数据科学工具箱中的必备工具
最近,在工作中,我们不得不做许多无人监督的分类。我们基本上必须从样本人群中区分出 N 个类别。我们大概知道有多少个类别,但没有什么是确定的,我们发现了Kolmogorov-Smirnov 测试这是一种非常有效的方法,可以确定两个样本之间是否存在显著差异。
我将向您介绍一下 Kolmogorov-Smirnov 测试的背景,并向您介绍我们用它解决的一个问题。
在 coffeeanddata.ca 上的原始帖子
一点理论
拒绝零假设。这听起来像是大学统计课上的痛苦回忆,但实际上这正是我们想要做的。我们要排除两个样本来自完全相同的分布的可能性。让我们来看看一些可用测试的非常高层次、非数学的概述。如果你想很好地理解所有这些测试背后的数学原理,可以使用所有章节中提供的维基百科链接。
学生的 T 检验
学生的 T 检验可能是最广为人知的拒绝零假设的方法。该测试计算一个样本相对于正常总体或另一个样本的 P 值。结果 P 值告诉您这些样本来自完全相同的分布的可能性。
当获得 P 值时,可以将其与统计显著性阈值(例如. 05)进行比较,如果 P 值更小,我们可以拒绝零假设。
学生的 T 检验有问题,样本必须是正态的(正态分布)。这对我们来说是一个问题,因为我们做了很多泊松分布的工作。
科尔莫戈罗夫-斯米尔诺夫试验
Kolmogorov-Smirnov 测试 (KS 测试)稍微复杂一点,可以让你检测出用学生的 T 测试无法检测出的模式。
来自维基百科:
“Kolmogorov–Smirnov 统计量量化样本的 经验分布函数 与参考分布的 累积分布函数 之间的距离,或者两个样本的经验分布函数之间的距离。”
这里有一个例子来说明学生的 T 检验和 KS 检验之间的区别。
stackexchange.com
因为样本均值和标准差非常相似,所以学生的 T 检验给出了非常高的 p 值。KS 检验可以检测方差。在这种情况下,红色分布具有 KS 检测到的略微二项式分布。换句话说:
- 学生的 T 检验表明,两个样本有 79.3% 的几率来自同一分布。
- KS 检验表明有 1.6% 的几率两个样本来自同一个分布。
其他测试
有许多其他测试和算法来做这类工作。夏皮罗-维尔克测试 和 安德森-达林测试 是被认为比 KS 测试更强大的两种测试。这两种测试有一个主要的缺点,它们不允许你比较两个样本,它们总是比较一个样本和一个标准分布。
编辑:我的一位同事向我展示了 Anderson-Darling 也可以用于双向测试(比较样本)。
“双样本 K–S 检验是比较两个样本的最有用和最通用的非参数方法之一”——维基百科。
检测设备用户
对于这个特定的任务,我们必须检测哪个用户正在使用特定的设备。每个设备由一个或多个不同的用户使用,我们必须想出一种技术来识别是否有一个或多个用户。在多个用户的情况下,我们希望确定哪个用户使用了哪些内容。
我们的策略
我们决定混合使用图网络和 KS 测试来识别潜在的集群。这个演示背后的想法是想象一个图形网络,其中每个节点(样本)都与其他每个节点(样本)相连。这些节点之间的顶点或链接将进行测试,换句话说,这两个节点有多近。因此,具有低 KS P 值的两个节点会很近,而具有高 P 值的两个节点会很远。这有望创建可区分的集群。
数据集
以下是我们的数据:
正如你所看到的,我们所有的样本看起来像一个标准偏差非常低的正态分布。我们已经对该设备的所有 82 个不同使用时段进行了采样。
从这张照片中我们可以看到不同的图案。所有的样本不具有相同的直方图分布。这是一个非常好的开端。在此之后,我们看了明显的分布集群。
为了做到这一点,我们做了 KS 矩阵,它由每个样本分布与每隔一个样本的 KS 双向检验组成。快速查看 KS Matrix 热图并不能发现明显的结果(如您在右图中所见)。
经过这样的层次聚类,我们已经得到了一些较好的结果。(如下图所示。)
在这两个树状图可视化中,我们可以看到一些潜在的(3)集群。经过审查,这些集群是无关紧要的。
网络图
在不成功的树状图聚类之后,我们尝试了所提出的图方法。如前所述,这里的目标是绘制所有可能的节点和顶点。顶点长度是 KS 测试值。我们不得不移除自我参照(它总是 0(显然你和你自己非常相似)。
然后我们得到了一个网络图,其中每个人都与其他人相连,这不是特别有用。
下一步是只保留重要链接(低于某个阈值)
正如我们在这张图片上看到的,我们得到了一个非常令人兴奋的结果。我们可以清楚地看到两个不同的集群和三个异常值。
这完全符合我们的模型,大集群必须是主要用户,第二个集群可以是替代用户。
在有效性验证之后,我们发现集群在集群 1 和集群 2 的使用之间发现了一些差异,但不是我们要找的那个。换句话说,它没有解决我们的问题,但它实际上找到了另一种模式,在另一种情况下可能有用。
结论
经过这项工作,我们得出结论,KS 检验是自动区分不同分布的样本的一种非常有效的方法。它并没有完全解决我们的问题,但它确实表明它可以很容易地用在数据科学环境中。
今天我向你展示了我们用 KS 测试解决的一个问题,但我们也用它来解决其他问题。KS 测试真的成为我们数据科学瑞士刀里的好测试了。
想要阅读更多内容
在我的博客上关注我: coffeeanddata.ca
韩国的生育率暴跌——这意味着什么?
原文:https://towardsdatascience.com/koreas-tanking-fertility-rate-what-does-it-mean-380a2477b4d6?source=collection_archive---------8-----------------------
今年,韩国的生育率预计将降至 1.00 以下。
这是一个相当了不起的统计数字。首先,低于 1.00 的平均生育率从数学上证明韩国有许多育龄妇女不会生育。第二,近在五十年前,生育率几乎为 5.00,在此之前甚至更高。下降幅度很大——50 年内下降了 80%,而全球平均下降幅度约为 50%。
This is becoming a less frequent sight in Seoul
为什么会出现这种情况?
虽然它还不是生育率最低的国家(这一荣誉属于新加坡),但在如此大规模下降的背景下,人们很自然会问为什么会出现这种情况。大多数专家认为,这种下降的原因是经济、社会和文化因素的结合,主要有以下几个方面:
- 韩国的成本一直在快速增长。以首尔为例,这里居住着 20%的韩国人口,的房价每年上涨约 5%。
- 这些成本,加上居高不下的年轻人失业率,导致与父母同住的成年人数量大幅增长——这一群体被命名为“袋鼠部落”。在 1985 年到 2010 年间,至少有一个 25 岁以上未婚子女的家庭比例从 9%激增到 25%。
- 在韩国,工作场所对怀孕的态度阻碍女性生孩子,许多报道称女性因休产假和工作受到威胁而感到内疚。
生育率低不好吗?
是的,它是。低生育率导致经济衰退。这种观点可能有悖常理,因为最贫穷的国家往往出生率最高。然而,如果我们停下来想一想,问题是什么就变得非常清楚了。
低生育率意味着人口会随着时间的推移而下降。根据经合组织的说法:“假设没有净移民和死亡率不变,每个妇女 2.1 个孩子的总生育率确保了人口的大体稳定。”韩国人口增长率从 1960 年的 3.2%下降到 2016 年的 0.4%。假设生产率稳定,低人口增长的后果就是低经济增长。
低生育率导致年龄失衡,这一问题因人们寿命延长而加剧。随着人口中老年人比例的增加,这导致了医疗保健和社会护理相关成本的增加,以及养老金结构的不平衡。简而言之,越来越少的年轻人需要为越来越多的老年人提供资金。
数据怎么说?
为了让自己放心,我做了一个快速分析,以确定生育率和经济增长之间的联系强度。
我的第一站是精彩的经合组织数据门户,在那里我下载了 2006 年至 2016 年间所有可用国家生育率的 csv 文件,以及 2015 年至 2030 年实际 GDP 预测的 csv 文件。
我用 R 编程语言做了一些非常简单的计算,并创建了一个图表,向我展示了生育率和实际 GDP 增长之间的关系。首先,我加载了两个数据集,并使用dplyr
软件包计算了 2016 年至 2030 年间实际 GDP 的 CAGR(复合年增长率):
gdp <- read.csv("GDP.csv")
fertility <- read.csv("fertility.csv")gdp_by_country <- gdp %>% dplyr::group_by(LOCATION) %>% dplyr::summarise(cagr = (tail(Value, n = 1)/head(Value, n = 1))^(1/15) - 1)
这给了我一个 49 个国家和他们的实际 GDP CAGR 的列表。接下来,我计算了生育率数据集中的国家在 2006 年至 2016 年之间的平均生育率,并将其加入到 GDP 数据集,这样我就有了真实的 GDP 统计数据和各国的生育率统计数据。
fertility_by_country <- fertility %>% dplyr::group_by(LOCATION) %>% dplyr::summarise(avg_rate = mean(Value))full_data <- dplyr::inner_join(gdp_by_country, fertility_by_country)
不是所有的国家都匹配,所以在我的最后一组中,我总共有 46 个国家。现在我想绘制 GDP 增长与生育率的关系图,并确定两者之间的关系。在 R 中计算线性模型非常容易,我保存它是为了以后绘图:
fit <- lm(cagr~avg_rate, data = full_data)
现在,我将在我最喜欢的绘图包plotly
中绘制一个散点图,并将线性模型覆盖在上面:
# plot basic scatter
plotly::plot_ly(data = full_data, x = ~avg_rate, y = ~cagr,
type = 'scatter', name = "OECD countries") %>% # add country labels to markers
plotly::add_annotations(data = full_data, x = ~avg_rate,
y = ~cagr,
text = ~LOCATION,
showarrow = FALSE, xanchor = 'right',
yanchor = 'center') %>% # add linear model
plotly::add_lines(y = ~fitted(fit), name = "Linear Model") %>% # label axes and title
plotly::layout(xaxis = list(title = "Average fertility rate 2006-16"),
yaxis = list(title = "Real GDP CAGR 2015-30"),
title = "Fertility Rate vs Real GDP Growth for OECD countries")
这证实了近期生育率和未来经济增长之间的关系。报告还显示,在样本国家中,韩国的近期生育率最低,尽管其经济增长预计不会像生育率数据让人相信的那样令人沮丧。
最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在LinkedIn或Twitter上找我。
科特林和数据科学:一个萌芽的爱情故事
原文:https://towardsdatascience.com/kotlin-data-science-a-budding-love-story-ad366a633213?source=collection_archive---------12-----------------------
Kotlin 于 2011 年首次出现,并席卷了编码界——我第一次听说这种语言是在一年前,巧合的是在谷歌宣布 Kotlin 是官方 Android 语言之后不久。自那以后,又发生了几次“大爆炸”,目前的预测预测全球使用量将继续增加。下面是今年 Github 库的语言分类:
Credit & thanks to: Rachel Stephens for extracting rankings from GitHub data and rendering the grid & Stephen O’ Grady for presenting RedMonk findings on Programming Language Rankings
由圣彼得堡的一个小型 JetBrains 团队开发的 Kotlin 是一种静态类型语言,它:
- 在 JVM 上运行
- 可与 Java 互操作
- 表示面向对象和函数范例之间的流动性
我一直认为自己是一个有着必要背景的程序员,我永远不会达到功能性编程的地位。当然,总有这样一个笑话:如果你真正理解了函数式编程,你就无法向别人解释它。我从来没有想象过一种语言可以允许流动性和变形为两个世界的一个实用和兼容的版本。
结果是在一个努力理解两个世界的社区中有明显更多的用户。机构支持有助于承担为爆炸式增长的社区提供支持的重担并且有助于在大型软件 系统中使用 Kotlin 赢得行业信心,这些公司包括:
- 格雷尔
- 优步
- 枢轴
- 亚特兰蒂斯
今年我有幸参加了 KotlinConf,但我感到兴奋的不是我自己的内容。随着我参加的每一次演讲,我一点一点地意识到因为 Kotlin 是一种如此强大的语言,人们已经能够开始并超越以前在计算机科学中设定的限制。
也许是来自不断增长的社区的越来越多的嗡嗡声:也许从 KotlinConf 内容的演变中可以明显看出这一点——但我有种悄悄的感觉 Kotlin 可能是下一个数据科学栈。
我很遗憾地说,不得不在我能参加的讲座之间做出选择是非常痛苦的(幸运的是,所有的讲座都被记录了下来)。
Kevin Most 发现,与注释处理器不同,编写自己的编译器插件允许你在运行时修改现有代码。
Thomas Nield 找到了解决调度问题的方法:通过在达到局部最小值后重新加热温度,在优化和贪婪算法之间切换。
Roman Elizarov 展示了新的 Kotlin 1.3 特性协程如何帮助管理现实生活中的并发和调度问题。
FP 帮助维护可扩展的软件
函数式编程(FP)的优势在于为规模和复杂性不断增长的软件创建更稳定的数据堆栈:
- 纯函数容易测试。因为纯函数可能独立于其他纯函数,所以为算法编写单元测试比以往任何时候都更容易。
- 由于函数式编程的确定性,它适合于并发和分布式编程。这些功能对机器学习也很有用!
静态类型和空安全增加了运行时的稳定性
类型安全和空安全对于大型企业级应用程序尤其重要。作为一种静态类型的语言,Kotlin 已经有了一个用于类型检查的编译器,这让位于更稳定的系统。编译语言让位于更好的性能以及处理大型数据系统。
Kotlin 也有 null-safety,这是 Java 至今仍在经历的一个十亿美元的错误,NPE 会导致运行时崩溃。
安全带?检查。头盔?检查。
Kotlin 致力于并发性和并行性
并发性和并行性对于大型软件系统中的数据健康和效率都是至关重要的。并发性描述了一个可以同时处理多个线程的系统,以及它无序执行功能并期待相同输入的能力。
一年前,我可能会傻傻地看着人们争取独占val
而不是var
的想法——但是不变性可以使处理并发线程更容易维护。
假设你在一次长途飞行中,你必须和其他的机组人员和乘客共用洗手间。通常情况下,一个洗手间的规则是一次只能有一个人在洗手间。或许去洗手。
Flickr/veganstraightedge
你不会希望别人撞见你使用洗手间。一些程序员可能用 TDD 管理并发性(洗手间有人吗?)。其他人可能使用锁(门锁)或信号量(VACANT
/ IN USE
)告诉人们是否尝试开门来处理访问单个资源的多个线程或人员。
同样,如果两个线程访问同一个可变的资源,资源可能会被修改,导致访问不再可用的内容失败,对相同的输入获得不同的结果,甚至在计算中遇到越界异常。
并发性与并行性并不完全相同:虽然并发性与确定性有关,但是并行性与如何同时完成多个任务有关。
Kotlin 闪亮的新特性协程有助于在异步环境中管理并行性。协同程序通过自动调度优化来管理并行性。他们还可以用作用域构造并发性。常规线程的线程数量有限,因此它们可能会在没有调度的情况下被阻塞。有了协程,我们就不必担心共享的可变状态和同步,并且您可以根据需要派生出任意多的协程。
那么下一步是什么?
如果你碰巧好奇,Kotlin 中有一个流行的库和框架的列表,你可以在这里探索任何你感兴趣的东西。
Flickr/Adrian Scottow
事实上,程序员们正着手用科特林解决不可能的事情,这绝非巧合。我们还没有完全准备好称自己为数据堆栈,但是 Kotlin 已经开始处理处理大型数据系统所需的健壮和稳定的软件的必要组件。我不知道一年后 Kotlin 会在哪里,但我当然期待继续与社区一起成长,尽我所能做出贡献!
Kotlin:现代(元)编程的下一个前沿
原文:https://towardsdatascience.com/kotlin-the-next-frontier-in-modern-meta-programming-8c0ac2babfaa?source=collection_archive---------12-----------------------
今天,我为我的 KotlinConf 演讲写一篇关于 Kotlin、TornadoFX 和元编程的后续文章。在这次演讲中,我总结了横切的广义定义,并探讨了元编程的常见形式。我们研究了用 Kotlin 编写的 TornadoFX 特性,以检验该语言的功能特性。回想起来,我希望我能更专注于谈论我的应用研究,所以我在这里谈谈我已经走过的路和我将要去的地方!
简要回顾
元编程有三种常见形式:
- 向导 —也被称为“猴子补丁”,向导通常是用户生成的输入,仅限于 HTML 或 XML 等标记语言。Android Studio 的设计功能是向导的一个很好的例子。向导容易导致用户输入错误,这使得它成为元编程的最低级形式。
- 面向方面编程 — AOP 是一种思想,在这种思想中,你将关注点提取出来,放到一个更高的抽象层次,以便将其他关注点编织成一个更兼容的共存。 AOP 通常局限于报告元数据,缺乏动态属性。
- 特定领域语言 —传统的 DSL 是一种完成特定任务的语言,但放弃了任何与特定类别无关的东西。您可以用 SQL 操作数据集,但不能用它们创建整个应用程序。因为 DSL 通常不同于 Java、C、Kotlin 等通用语言。所以结果是 DSL 通常存储在不同的文件或字符串中,产生了大量的开销。
巧合的是,Kotlin 包含了所有三种形式的能力,甚至改进了每种类型当前的缺点,作为一个功能范例。通过内部 DSL 和具体化的泛型,Kotlin 找到了一种方法来克服 JVM 堆栈中的限制,这些限制会阻止像函数这样的功能支柱成为一等公民。
Kotlin 在函数式和面向对象的范例之间不断变化,但是作为一种静态类型的语言,在尝试完成其他静态类型语言无法完成的真正的元编程方面存在一些挑战。
- 真正的元编程不考虑封装。
- 真正的元编程不需要编译就能生成代码,所以不需要类型检查。
话虽如此,我尝试了一些我不确定是真的真的勇敢还是真的真的愚蠢的事情。
这可能并不愚蠢。
开发中的测试
软件质量保证包括监控软件工程过程的手段和用于确保质量的方法。当然,这个过程的一部分是为编写的代码编写测试,并确保产品从用户的角度来看是按预期工作的。
当我意识到我需要 UI 测试时,我有点惭愧,在 JUnit 测试之后,我从来没有接受过自我测试的培训。但是我也意识到,有许多其他的工程师也避免测试,并且在实践中,许多策略对于回归测试来说更加麻烦。
大约一年前,我为销售人员编写了一个程序向导,为潜在客户生成现场演示,因为我很懒。巧合的是,这个项目是一种猴子补丁!
TornadoFX-Dnd-TilesFX is open source here
我最终编写了自己的拖放功能,因为我不知道如何序列化我的自定义对象;问题是我在调试我的微管理事件时遇到了困难,我意识到我需要测试 UI。另一个问题?我不知道如何编写 UI 测试。我想——如果我使用元编程来为我生成这些测试会怎么样?
所以我开始询问其他开发人员和 QA 工程师:
- 什么是好的测试?
- 什么是糟糕的测试?
我收到了数百个答案——从不同的框架到不同的策略到不同的风格。
龙卷风套件:不仅仅是应用研究
TornadoFX-Suite 从简单地生成 TornadoFX UI 测试开始。但事实远不止如此。如果这个项目可以被多个人用于多种框架——我们可以收集这些数据并使用机器学习来找到这些答案吗?
让我们看看这个项目现在的样子,看看它做了什么。
TornadoFX-Suite is open source and can be found here
您会注意到这个应用程序检测 UI 输入——从那里, kscripting 将被实现来生成那些测试。
检测用户界面输入
到目前为止,这是项目中最难克服的困难。使用 Kotlin 编译器的包装器 kastree ,我能够将我扫描的 Kotlin 文件分解成抽象语法树(AST)。我选择 ASTs 的原因是我们能够保持代码分析的不可知论,以便在未来的框架中使用。在创建所需的映射时,我遇到了现实生活中的元编程挑战——在语法分析中,当您的静态系统关心您必须转换的类型时,很难递归地映射潜在的无限树(无论是高度还是宽度)。
Finally bumped into an identified challenge where true metaprogramming and statically-typed languages like @kotlin don’t play where together — being able to inspect AST breakdowns recursively without caring about the type system.
特别是,分解 Kotlin 语言的属性被证明是困难的。属性可以是集合、变量、独立于类的函数或成员。这些项目中的每一个都可以在访问级别、类型方面有进一步的分类,并且可以在那些属性中包含额外的属性。
我不是说这是最好的解决方案。我不是说这是一个好的。但是我找到了一个!将这些 ast 转换成 JSON 对象/数组使得造型更容易以更不可知的方式递归:
性能差吗?地狱是的,它是。这个实现烂不烂?当然有。 但是这管用吗?如果行得通,那就不傻。
所以我们有这些故障。我如何知道我应该关心哪些元素?这很容易用 Kotlin 枚举类为每个框架定制:
enum class INPUTS {
Form, TextField, DateField, Button, Action,
RadioButton, ToggleButton, ComboButton, Checkbox,
Item, Paginator, PasswordField
}
好吧,我们有要注意的关键词。我们可以使用具体化的泛型,通过枚举类遍历我们的控件属性集合:
这是我们可以在任何框架中检测所需控制的概念验证。我们正在努力创建一个不可知论的解析系统,最终,当它成长到足以处理这样的责任时,让它存在于自己的库中。
下一步是什么?
行动是影响环境的东西。
这就是测试的作用。
测试是一个探索环境的主动过程,确定它如何响应各种条件。
测试人员从这些交互中学习。
因此,如果我们在谈论一个生成型机器学习工具来“做测试”,根据定义,它必须学习。它必须通过采取行动并能够处理这些行动的反馈来做到这一点。我们可以从创建生成的用户输入的排列开始,这些排列可以覆盖人类可能永远没有能力覆盖的情况,但我们会增加测试许多东西所需的时间。如果我们把这些排列缩短成有价值的测试会怎么样?
元编程的自然发展是机器学习。
我们可以从用户那里收集数据——为什么生成了什么测试,最初通过/失败了什么测试,有多少用户参与了项目?从那里,有可能检测出已知有问题的组件,并为此提供更智能的测试。我们甚至可以找到数据来说明什么是好的 UI/UX。我甚至不认为我在这里抓到表面。
你有兴趣投稿吗?我经常放松自己,当然,我也可以在推特和 github 上联系。项目可以在这里找到。
库尔、喀拉斯和张量流
原文:https://towardsdatascience.com/kur-keras-and-tensorflow-f895c1d1c9e7?source=collection_archive---------6-----------------------
代码可在 GitHub 上获得
用三个机器学习框架 Kur,Keras,Tensorflow 写的同一个模型的简单概述。用 TFRecords 探索张量流的数据管道。
大约一年前 Tensorflow 问世时,我和许多其他人一样,下载了它,并试图开始构建令人难以置信的机器学习模型,却发现这实际上是一件有点困难的事情。
事实证明,构建节点应用程序和构建 ML 模型的难度并不完全相同,但是围绕 ML 的工具似乎变得更容易使用,上周我又做了一次尝试。
我找到了 Kur ,由 DeepGram 的人构建,它提供了比 Keras 更高级别的 api,并且可以使用 Tensorflow 作为后端。我经常发现自上而下的学习更容易,Kur 的 yaml 模型定义看起来是如此的平易近人。
从 Kur,我挖到 Keras,然后 Tensorflow 建立了两个密集层的相同简单模型。
Keras Sine Wave Model
目标是建立一个模型来预测给定点是在正弦波之上还是之下。这很琐碎,但是知道每一行代码是什么是一个足够小的问题。这是数据的可视化,其中红色点属于正弦波的上方,蓝色点属于正弦波的下方。
Visualizing the data
库尔
Kur 的模型定义出现在一个 yaml 文件中。上面的模型是这样的:
Kur model Definition
培训、测试和评估都非常简单,他们网站上的教程非常精彩。这个框架真的不妨碍你快速训练和测试一个想法。如果需要的话,你总是可以用一个 kur 模型并在一个较低层次的 api 中对它进行编码,但是这似乎是我开始下一个项目的地方。
Keras
Keras 的 api 也很简单,但是您不需要在 yaml 文件中指定模型,而是编写普通的 python。Keras 中的相同模型定义如下所示:
Keras model definition
它的编码也很简单,并且在 Tensorflow 的 Tensorboard 中也有一些很好的挂钩(你可以在 GitHub 上找到它的实现),这让你不费吹灰之力就能得到清晰的损耗和准确度图表。
Accuracy from Tensorboard. over 98%!
张量流
我在 Tensorflow 中遇到的最大问题是将数据正确地输入到模型中。Tensorflow 自己的数据管道使用 TFRecords,这有很多好处,但也比将 numpy 数组塞进模型中更复杂。
TFRecords 的一个好处是,一旦你正确地设置了阅读器,它们可以被批量处理,并自动随机化。当数据集达到一定大小时,试图一次加载整个数据集会耗尽内存。
一旦管道建立起来,将数据塞进模型是一件痛苦的事情。我到处扔重塑的东西。当然,这部分是因为我对 python 缺乏经验,但是其他两个框架帮我解决了这个问题,真是太好了。
另一件要注意的事情是,Tensorflow 模型的准确性比其他两个框架差。这显然是我的一个错误,但是我对从 tf 记录中读取数据感到满意。这个问题阻止了我继续上一次的讨论,下一个项目可以更关注模型本身,解决一个更有趣的问题。
查看 GitHub 上的代码,希望它能为你节省一些设置数据管道的时间!
用于深度学习任务的 Kuzushiji-MNIST -日本文献备选数据集
原文:https://towardsdatascience.com/kuzushiji-mnist-japanese-literature-alternative-dataset-for-deep-learning-tasks-d48ae3f5395b?source=collection_archive---------17-----------------------
加上我们的 VGG-雷斯内特系综模型与国家的艺术成果
MNIST 是一个拥有 70,000 张手写数字标记图像的数据集,二十多年来一直是图像处理和分类中最受欢迎的数据集之一。尽管它很受欢迎,但当代深度学习算法很容易处理它,经常超过 99.5%的准确率结果。一篇新的论文介绍了库祖什基-MNIST,一个比 MNIST 更难的备选数据集,同时还介绍了两个更难的库祖什基数据集。
有趣的是,Kuzushiji 数据集也可能有助于恢复一种几乎失传的语言——草书 Kuzushiji。草书 Kuzushiji 是一种使用了 1000 多年的日本文字,没有共同的标准,有时同一个词会有几十种风格和格式。在 19 世纪,日本改革了其官方语言和书写系统,并使其标准化,随着时间的推移,《文库世纪》灭绝了,导致数百万份日本文化和历史文件无法为大多数人所用。
数据集
Source: Clanuwat et al
数据集
日语可以分为两种体系:
- 标识系统,其中每个字符代表一个单词或一个短语(有数千个字符)。一个突出的标识系统是汉字,它是基于中文系统。
- 音节符号系统,其中单词由音节构成(类似于字母表)。一个突出的音节系统是具有 49 个字符的平假名(Kuzushiji-49),在 Kuzushiji 标准化之前,每个平假名字符有几种表示。
Kuzushiji 数据集包括汉字和平假名字符,基于 18 世纪 35 本书的预处理字符图像。它包括 3 个部分:
《字谜 MNIST》在格式上与原版《MNIST》相似,但由于每个汉字都有多种变化,分类难度更大。其他数据集包括更多的类,并基于人物在书中出现的频率,有些类只包括几个样本。
Source: Clanuwat et al
数据集可以从这里下载。作者计划扩大数据集并添加更多样本。
结果
Kuzushiji-MNIST 数据集的创建者通过训练一些分类算法并将其与 MNIST 进行比较,创建了一个基线。最好的算法(PreActResNet-18)在 MNIST 上达到了 99.56%,而在 Kuzushiji-MNIST 和 Kuzushiji-49 上分别只有 98.83%和 97.33%。
附加分析
为了评估 Kuzishiji-MNIST,我们比较了几种架构——VGG、ResNet-18、胶囊网络以及这些架构的组合。最好的结果是用 VGG 和雷斯内特的组合获得的——在测试集上有 98.9%的准确率,这是在新数据集上的最新结果
代码可以在这里找到。
结论
Kuzushiji 数据集可以作为分类算法的新基准系统,比传统的 MNIST 更具挑战性。如图所示,诸如 ResNet 和 VGG 等算法可以在库祖什基-MNIST 数据集上取得优异的结果,但在其他数据集上仍有改进的空间。最后,对库祖什基数据集的研究也可能有助于从这种失传的语言中恢复数百万本书籍。
L1 和 L2 正则化方法
原文:https://towardsdatascience.com/l1-and-l2-regularization-methods-ce25e7fc831c?source=collection_archive---------0-----------------------
机器学习
在我的上一篇文章中,我介绍了监督学习模型中的正则化。在这篇文章中,让我们回顾一些广泛使用的正则化技术以及它们之间的主要区别。
当数据集中有大量要素时,为了创建不太复杂(简洁)的模型,一些用于解决过度拟合和要素选择的正则化技术包括:
-
L1 正规化
-
L2 正规化
使用 L1 正则化技术的回归模型被称为 套索回归 ,使用 L2 的模型被称为 岭回归 。
这两者的主要区别在于刑罚期限。
岭回归将系数的平方值作为惩罚项添加到损失函数中。这里高亮显示的部分代表 L2 正规化元素。
Cost function
这里,如果λ是零,那么你可以想象我们回到了 OLS。然而,如果λ非常大,那么它将增加太多的重量,并且将导致装配不足。话虽如此,如何选择λ很重要。这种技术可以很好地避免过度拟合的问题。
Lasso 回归(最小绝对收缩和选择算子)将系数的大小的绝对值作为惩罚项添加到损失函数中。
Cost function
同样,如果λ为零,那么我们将得到 OLS,而非常大的值将使系数为零,因此它将欠拟合。
这些技术之间的关键区别是套索将不太重要的特征的系数缩小到零,从而完全删除了一些特征。因此,在我们有大量特征的情况下,这对于特征选择很有用。
交叉验证、逐步回归等处理过度拟合和执行特征选择的传统方法适用于小的特征集,但当我们处理大的特征集时,这些技术是很好的替代方法。
洛杉矶地铁自行车共享数据第 1 部分—纸浆线性优化
原文:https://towardsdatascience.com/la-metro-bike-share-data-part-1-linear-optimization-with-pulp-bc8ed4c85cd2?source=collection_archive---------10-----------------------
使用 Python 中的线性规划推导总收益最大化的定价方案
二次优化的第二部分 这里 。
随着 Bird 和 Lime 最近的大规模筹款活动,滑板车和自行车为城市交通增添了新的维度。
然而,在这些初创企业的宠儿到来之前,许多城市已经有了根深蒂固的自行车共享系统。其中最著名的包括花旗自行车纽约,Divvy,和资本自行车份额。
这个生态系统中的一个小得多的参与者是洛杉矶地铁自行车公司,该公司始于 2016 年,已记录了 58 万次骑行。之前他们因每 30 分钟 3.5 美元的价格而受到批评,最近他们因调整定价结构而成为头条新闻。
在这种新的结构下,每半小时的价格降低了 50%,为 1.75 美元。此外,基于时间的通行证现在也更便宜了。
虽然这一价格变化相当剧烈,但是否有更好的定价选择?Python 中的优化模型能对此有所帮助吗?我和 Shreenath Bhanderi 开始回答这些问题。
我们首先从洛杉矶地铁数据网站提取一年的自行车共享数据。然而,在我们开始优化 PuLP 之前,我们要经历通常的数据清理过程。
数据清理
我们看到,在过去的 4 个季度中,有超过 286,000 次乘坐。这些数据还为我们提供了关于使用了哪些自行车、起点和终点的位置以及每次骑行的长度的信息。
与大多数数据集一样,日期在读入时是字符串。我们运行一个快速的 pd.to_datetime 函数,将 start_time 和 end_time 列转换为 datetime 对象。
我们使用 missingno 包来检查数据帧中的 NA 值。由于缺失值的数量与观察值的总数相比几乎可以忽略不计,因此我们删除了这些行。
删除了大约 4849 行,占全部行的 1.7%。
填写自行车起止站数据
我们需要更多关于自行车站的详细信息,如码头数量和地址。为此,我们从洛杉矶地铁下载 json 文件,其中包括不同自行车站的地址和容量。
解析出相关字段后,我们获得 kiosk_id 来标识主数据帧中的站点、地址信息以及每个站点的停靠站数量。
然后,我们将该站数据与主数据帧合并两次,一次用于起点站,一次用于终点站。
再次快速查看 missingno 表明,大约有 20%的记录缺少电台信息。由于这是数据集的一个相当大的部分,我们可以仔细看看如何处理这些丢失的值。
由于填写车站的所有信息可能是一项繁琐的工作,所以让我们首先仔细看看车站周围的描述性统计数据。
最常见的起点站出现在 11,437 次乘坐中,而最不常见的起点站仅出现在 6 次乘坐中。我们应该只填充高于 2269 计数平均值的站点吗?
中值为 1544,看起来 2269 计数可能太高了。因此,我们将使用中位数 1544 来代替。只有高于 1544 计数的站点才会填入信息。
看一下码头的平均数和中位数,它们都在 22 左右,我们可以合理地用 22 来填充缺失的码头值。
通过创建一个掩码和快速过滤器,我们获得了一个可用于填充数据帧的站点 id 列表。
通过手动搜索和 Google API 的结合,我们获得了以下关于一些缺失站点的信息。
用 DataFrame 填充额外的站信息。在这里,我们再看一下 missingno 矩阵。
在删除最后的空值后,我们获得了一个包含 250,513 条记录的数据帧。在填写一些地址细节后,我们获得了大约 25,000 个额外的值。
活动自行车
另一个值得注意的话题是洛杉矶地铁自行车车队的利用。
虽然所有的自行车在过去的一年里都是活跃的,但大约 1259 辆或大约 86%的自行车在过去的一个月里至少使用过一次。这似乎是一个相对健康的数字,但是实际的利用率和库存分析将在本系列的下一部分进行。
现在,我们确定在过去 6 个月中闲置的自行车,并在另一列中将其编码为 0。上个月活跃的自行车得到 1 分。
虚拟变量
数据集还包括多个分类变量。稍后可能特别感兴趣的两个是护照持有者类型和旅行类别。
在这里,我们为两者创建虚拟变量列,并将它们连接到主数据集。
30 分钟时间段的计数
鉴于洛杉矶地铁自行车的定价系统是基于用户在自行车上花费了多少 30 分钟的时间,将编码一个额外的列来计算每个乘客在一次旅行中花费的 30 分钟时间。
鉴于通行证持有者在乘车的前 30 分钟是免费的,他们将比无电梯乘车者少付费一个时间段。
随着数据集在很大程度上得到清理并添加了额外的功能,我们可以开始解决优化问题。
定价计划优化
定义优化目标和限制
这一优化的目标是使洛杉矶地铁自行车的总收入最大化。对于这种线性优化,我们将利用纸浆库。
收入的两个主要来源是:
- 所有乘坐的总票价
- 通行证销售总额(每日、每月、每年)
洛杉矶地铁可以通过改变定价结构或改变提供的计划来增加总收入。
洛杉矶地铁自行车最近实施了如下新的价格结构。以前的计划和现在的计划如下:
为了得出适当的价格与需求关系,必须对进一步的需求模型进行估计。然而,要在优化中考虑价格和数量的关系,需要一个二次公式。这将在下一篇文章中通过 SciPy 和 CVXOPT 来完成。
对于简单的线性模型,我们试图回答两个关键问题:
- 洛杉矶地铁是否应该维持现有的每日、每月和年度计划体系,以实现收入最大化?
- 在以前和新的价格结构中,这种情况如何变化?
估算每种通行证类型的售出通行证数量
我们将要求估算每种通行证类型的售出数量,以估算总收入。我们首先看一下一些聚合指标:
由于我们没有针对通行证持有人的唯一标识符,我们参考洛杉矶地铁自行车的数据页面来了解已经售出了多少通行证。
自 2016 年 7 月成立以来,已经完成了约 575,281 次行程,售出了 42,870 张通行证,预计在长达一年的分析期间,将售出约 20,000 张通行证。
我们将从盈亏平衡的角度估计每种通行证的销售额。支付一张通行证的价格平均需要多少次旅行?
由于大多数行程(> 60%)是从地铁站出发的“最后一英里”行程,行程的中位持续时间为 12 分钟,我们对 30 分钟以下的行程进行了以下盈亏平衡分析。
通过使用当前和以前的票价和通行证费用的平均值,我们得出以下结果:
Rides per day required for daily pass: 2.0
Rides per month required for monthly pass: 5.714285714285714
Rides per year required for annual pass: 22.857142857142858
看看保本所需的乘车次数并评估这些数字,这些数字似乎偏低。
如果购买每日通行证,每日通行证持有者可能会进行多次往返旅行。
月票持有者可能是偶尔的通勤者,即使是保守的每周 2 次乘车上班,一个月也要 8 次。
How often do you bike to work?
由于上一个定价计划中弹性点的价格为 40 美元,因此年度通行证持有者最难衡量。目前,它们将被缩放到与日和月票号码相同的因子。
将每日乘车次数提高到保守的 3 次乘车次数会增加 50%,而将每月乘车次数提高到保守的 8 次乘车次数会增加 40%。对于保守的估计,我们将这三个估计值按 40%的公共因子进行缩放。
Rides per day required for daily pass (scaled): 2.8
Rides per month required for monthly pass (scaled): 8.0
Rides per year required for annual pass (scaled): 32.0
因此,通过将每种票类型中的总乘车次数除以达到盈亏平衡所需的平均乘车次数来计算估计售出的票,得出以下结果:
Estimated passes sold for daily pass: 5229
Estimated passes sold for monthly pass: 18317
Estimated passes sold for annual pass: 287
Total passes sold: 23833
在此期间售出的入场券总数估计约为 23 833 张。这与我们先前估计的 20,000 人大致相符。
现在让我们为这个优化模型公式化目标函数,以最大化来自通行证销售和乘坐的总收入。
总收入可分为以下几部分:
- 来自无预约用户的总收入= 30 分钟使用价格*无预约用户的 30 分钟总块数
- 日通票、月通票用户的总收入= 30 分钟的使用价格*前 30 分钟免费后的 30 分钟总时长
- 销售门票的总收入=相应门票的价格*相应门票类型中售出的门票总数
现在可以进行一个快速计算,看看我们当前的总收入是多少,以及过去一年售出的门票的估计数量。
这里使用旧的定价方案来估算价格。在这里,年卡持有者每年支付 40 美元购买年卡,每半小时支付 1.75 美元。前半小时不是免费的。
Total revenue: $ 961,924.5
现在我们可以用纸浆来表示这个目标函数。
纸浆线性优化
在 PuLP 中,一个易于遵循的线性规划框架如下:
- 引发纸浆问题
- 定义决策变量
- 形式目标函数
- 表单约束
- 解答和解释
为了回答我们之前提出的两个关键问题,我们需要两个独立的纸浆模型。一个包含以前的定价结构,另一个包含当前的定价结构。
1。引发纸浆问题
这里,我们在 PuLP 中创建一个 LpProblem,并用 pulp.LpMaximize 将其设置为一个最大化问题。
2。定义决策变量
为总共 6 个二元变量创建 3 对决策变量。每一对表示是否实现一个传递类型的“是”和“否”决定。
例如,month_yes 表示应该出售月票,month_no 表示不应该出售月票。
3。表单目标函数
现在我们需要为这个优化模型制定关于总收入的目标函数。
我们当前总收入的细分如下:
- 按半小时收费的无电梯总收入。
- 每个套票类别的游乐设施总收入。如果我们取消特定的传递类型,则值为 0。
- 如果取消套票,每个套票类别的替代定价总收入。如果我们维护特定的通行证类型,则值为 0。
- 出售门票的总收入。如果我们取消传递类型,则值为 0。
关于取消通票类型的替代定价,我们假设乘车将按无电梯收费。
鉴于乘客已经在抱怨每小时 3.50 美元的轮挡费用,在过去的定价方案中,任何通行证的减少都会导致乘客数量的急剧下降。此外,鉴于自行车和滑板车共享领域的激烈竞争,某些通行证的掉落可能会导致车手转向其他竞争者。
我们假设每个类别的基线磨损为 30%,并在运行模型时调整参数。
用 Python 表示每个收入流,我们得到了以下结果:
然后,我们将其添加到纸浆模型中。
4。形式约束
然后,我们必须定义额外的约束,使得每个二进制对中只有一个决策变量可以并且必须是真的。
例如,二进制变量 month_yes 和 month_no 可以表示 0 或 1。这两个变量的总和不能是 0 或 2,因为这意味着不可能同时实施和不实施月度计划。
我们通过将总和设置为 1 来实施这个约束。
5 .解析
让我们看看我们的模型现在是什么样子:
Revenue Maximization Previous:
MAXIMIZE
26602.1*annual_no + 30481.5*annual_yes + 94366.65*day_no + 78387.75*day_yes + 405700.39999999997*month_no + 399696.75*month_yes + 626132.5
SUBJECT TO
_C1: day_no + day_yes = 1
_C2: month_no + month_yes = 1
_C3: annual_no + annual_yes = 1
VARIABLES
0 <= annual_no <= 1 Integer
0 <= annual_yes <= 1 Integer
0 <= day_no <= 1 Integer
0 <= day_yes <= 1 Integer
0 <= month_no <= 1 Integer
0 <= month_yes <= 1 Integer
使用 model.solve()求解模型,我们得到了以下解:
Status: Optimal
Optimal Solution to the problem: 1156681.05
Individual decision_variables:
annual_no = 0.0
annual_yes = 1.0
day_no = 1.0
day_yes = 0.0
month_no = 1.0
month_yes = 0.0
上述解决方案可以这样理解:
- 取消日票和月票。
- 维护年度通行证。
- 总收入将为 1,156,681.05 美元
如果任何通行证被取消,减员率为 30%,即得出了这一结论。事实是,不同通行证的流失率会有所不同。
例如,那些持有年度通行证的人不太可能磨损,因为他们可能是最需要使用自行车的人。
在调整了一些参数和损耗率后,我们得出以下结论:
- 如果取消计划的自然减员率高于 41%,则应保留日间计划。
- 如果取消计划的流失率高于 31%,则应保留每月计划。
- 如果取消计划的自然减员率高于 19%,则应保留年度计划。
按照这些边际损耗率计算的总收入为我们带来了优化的 1,136,357 美元总收入。
由于洛杉矶地铁此前一直收取 3.50 美元的高价,这些高流失率是有道理的。如果假设自然减员率为 30%,且洛杉矶地铁取消了月度计划,他们将能够通过向剩余的 70%的乘客收取步行费率来获得收入。
现在让我们对当前的定价重复同样的方案,费率减半。
由于新的年度定价方案与以前的年度(flex)通行证完全不同,并且在数据中单独列出,我们保持 40 美元的年度通行证价格。目前 150 美元的价格被考虑到以后的优化中。
我们得到了以下解决方案:
Status: Optimal
Optimal Solution to the problem: 1053249.14
Individual decision_variables:
annual_no = 1.0
annual_yes = 0.0
day_no = 0.0
day_yes = 1.0
month_no = 0.0
month_yes = 1.0
考虑到将半小时费率减半至 1.75 美元的严厉措施,如果任何计划被取消,自然减员也不太可能如此之高。
此外,当前的最佳解决方案表明,即使没有损耗,我们可以按加价向每个通行证持有者收费,也应该保留每日和每月通行证。
另一方面,年度计划只有在超过 25%的年票持有者因计划取消而流失的情况下才能保留。考虑到年卡持有者最不容易发生摩擦,因为如果他们支付了年卡费用,他们可能确实需要通勤服务,洛杉矶地铁最近决定取消这一年度(弹性)计划很可能是正确的举措。
虽然 PuLP 只能处理简单的线性优化,但是还有许多其他强大的库,比如 CVXPY、IPOPT 和 SciPy。
在下一篇文章中,我用一些需求曲线估计来解决二次优化问题,看看洛杉矶地铁自行车的其他定价方案。
感谢您的阅读,您可以在 Github 上查看笔记本,并在 LinkedIn 上联系!
洛杉矶地铁自行车共享数据第 2 部分—使用 SciPy 进行二次优化
原文:https://towardsdatascience.com/la-metro-bike-share-data-part-2-quadratic-optimization-with-scipy-394ab69dbc00?source=collection_archive---------11-----------------------
使用 SciPy 分析最近的价格变化并找到最佳价格组合
在第 1 部分中,我们清理了数据集,并通过 pulp 运行了一个简单的线性优化模型。正是在撰写第一部分的最后,洛杉矶地铁自行车的 2018 年第三季度数据公布。
这可能只是一个额外的数据点,但我们现在可以拟合一个基本的线性需求曲线,用于模型约束,以允许价格和需求波动。
在我们得到这些曲线之前,我们先确定一些用于后续分析的常数。
竞争基准
其他多家运营商最近也进入了自行车/滑板车共享市场。像 Bird、Lime 和 Jump 这样的名字应该是生活在洛杉矶地区的大多数人所熟悉的。
从竞争对手的角度来看,定价方案有多种构建方式。我们可以实施和比较的一些选项如下:
- 每分钟可变利率
- 按时间间隔可变费率(目前洛杉矶地铁为 30 分钟)
- 任何乘坐的固定费用
- 在实施可变费率之前的一段时间间隔内的固定费用
- 涵盖特定时间内所有游乐设施的周票、月票。此后可变利率
为了与其他自行车和踏板车运营商的定价进行比较,让我们为所有运营商绘制不同的定价曲线。
纵观洛杉矶自行车和踏板车运营商的不同定价方案,洛杉矶地铁刚刚颁布的当前定价绝对是最便宜的,一小时的自行车骑行价格为 3.50 美元。
下一个最便宜的选择是 Lime 踏板自行车,它比洛杉矶地铁的 walk on riders 便宜,骑行时间不到 15 分钟,骑行时间在 30 到 50 分钟之间。
因此,我们将设置价格上限,并在优化模型中将其用作常数:
- 无通行证每分钟可变费率设置在 0.05 美元和 0.15 美元这两个最常见价格的平均值之下:
无通行证每分钟可变费率<= 0.10 美元 - 有计划的每分钟可变费率设置在洛杉矶地铁当前的 0.06 美元和 Jump 的 0.07 美元的平均值之下:
有通行证的每分钟可变费率<= 0.065 美元 - 每 30 分钟变化率设置在最近的竞争对手(石灰踏板)下:
每 30 分钟变化率< = $2.5
总需求曲线
2018 年 Q2 是价格变化前的最后一个数据点,2018 年第三季度是之后的第一个数据点。我们将 y 设为每 30 分钟乘车的价格,x 设为该季度乘车的总次数。
使用简单的斜率估计,我们得到以下结果:
The linear function from two data points is:
y = -9.762356353899364e-05 x + 11.05186600468593
Where y = price for half hour block
x = rides in fiscal quarter
按客户细分的需求曲线
如果我们按客户细分细分需求会怎么样?
我们首先创建 2018 年 Q2 和 2018 年第三季度的分组表格。
Left: 2018 Q2 figures, Right: 2018 Q3 figures
我们可以看到新的年度通行证还没有完全流行起来,在通行证季度仅售出 12 张通行证。150 美元的价位可能有点高。
有趣的是,价格下降并没有真正影响到任何通票持有者,但却使无电梯乘客的数量增加了一倍。
让我们看看其他需求曲线是什么样的。
Walk up demand function estimate
The linear function from two data points is:
y = -9.159905783826223e-05 x + 5.871041612143418
Daily pass demand function estimate
The linear function from two data points is:
y = 0.006183745583038869 x + -27.542402826855124
Monthly pass demand function estimate
The linear function from two data points is:
y = 0.026923076923076925 x + -1181.9769230769232Annual(Flex) pass demand function estimate
The linear function from two data points is:
y = 0.0020759193357058124 x + -1.5237247924080664
有趣的是,一条典型的负斜率需求曲线只出现在步行骑车者身上。鉴于费率从 3.50 美元大幅降至 1.75 美元,似乎许多乘客只是开始成为无电梯乘客,而不是购买通行证。由于通行证价格的下降与半小时费率的下降不成比例,因此放弃通行证变得更加经济。
基本二次优化模型
我们从定义目标函数开始,就像在纸浆中一样。
当我们在 PuLP 中将所有模型组件“添加”到一个问题中以创建模型时,SciPy optimize 只需要为目标函数和各种约束创建函数,然后将它们作为参数传递给 minimize 函数。
由于二次优化问题自然是一个极小化问题,所以我们将总收入返回为带负号的'-total_revenue ',以获得最大值。
还要注意的是,目标函数中只有一个参数,你初始化的每个变量都是从这个列表中传递过来的。
约束同样被定义为单个变量具有相同索引的单个函数。
然后创建一个字典来标记约束的类型并列出所有单独的约束。
界限由元组表示。例如,b1 将代表收费率的上限和下限。1.5 代表速率的下限,2.5 代表速率的上限。
b2 代表总乘坐次数的范围。上限为 140,000,鉴于目前的市场形势,总乘坐次数翻倍似乎不现实。
然后将边界添加到一个元组中,作为函数参数传递给 minimize 函数。
x0 指的是你对变量的最初猜测。在这里,我们选择当前的定价和总乘坐价值作为我们的初步猜测。
一旦创建了所有函数参数,我们就可以将它们传递给 optimize 中的 minimize()函数。
fun: -1623030.3308773183
jac: array([-5.59883906e+04, -1.65781250e+01])
message: 'Optimization terminated successfully.'
nfev: 41
nit: 10
njev: 10
status: 0
success: True
x: array([1.50000000e+00, 9.78438571e+04])
根据这一优化,当价格设置为每半小时 1.50 美元时,收入似乎得到了优化。这将使总乘坐次数增加到 97,844 次。
总收入将增加到 1 623 030 美元。
似乎负需求斜率意味着将价格降至下限是最有效的收益最大化策略。
如果我们调整变量的界限呢?如果允许最低价格进一步降至 1 美元以下会怎样?如果竞争比预期更激烈,最大乘坐增长限制在 100,000 次以下,会怎么样?
我们将下列界限添加到灵敏度分析中:
循环上述价格和附加条款范围的所有组合,我们获得以下总收入数字:
Total rev | Rate | Total riders | Rate range | Rider range
1678530 1.0 102966.0 (1, 2.5) (50000, 140000)
1678530 1.0 102966.0 (1, 2.5) (50000, 120000)
1651146 1.0 100405.0 (1.25, 2.5) (50000, 140000)
1651146 1.0 100405.0 (1.25, 2.5) (50000, 120000)
1646752 1.0 100000.0 (1.25, 2.5) (50000, 100000)
1646752 1.0 100000.0 (1, 2.5) (50000, 100000)
1623030 2.0 97844.0 (1.5, 2.5) (50000, 140000)
1623030 2.0 97844.0 (1.5, 2.5) (50000, 120000)
1623030 2.0 97844.0 (1.5, 2.5) (50000, 100000)
1594182 2.0 95283.0 (1.75, 2.5) (50000, 140000)
1594182 2.0 95283.0 (1.75, 2.5) (50000, 120000)
1594182 2.0 95283.0 (1.75, 2.5) (50000, 100000)
1372815 2.0 80000.0 (1.75, 2.5) (50000, 80000)
1372815 2.0 80000.0 (1.5, 2.5) (50000, 80000)
1372815 2.0 80000.0 (1.25, 2.5) (50000, 80000)
1372815 2.0 80000.0 (1, 2.5) (50000, 80000)
根据给定的需求曲线,似乎采用 1 美元的最低可能价格会导致最多 102,966 次乘坐。它还会产生最高收入 1,678,530 美元。
总的来说,似乎只要我们能够吸引 10 万次以上的乘坐,策略应该是降低价格。鉴于我们在这里看到的,也许从以前的定价方案大幅下降 50%是合理的。
如果我们创建一个基于分段需求曲线的新模型会怎么样?公式化的约束如下所示:
由于之前的年票/灵活票被取消,年票的需求曲线可能不再相关。
重新制定目标和解决这个新的方程产生了一个较低的无电梯乘车的最优价格和一个接近价格上限的其他组的价格。
但是,对于每次迭代,我们都会获得以下消息:
message: 'Positive directional derivative for linesearch'
success: False
看起来,使用我们当前的公式,优化器无法找到一个下降方向来足够快地降低目标函数。最终,这意味着结果不可能是最佳的。
鉴于每种通行证类型的粗略需求估计,等待更多新价格数据出来以适应不同细分市场的更好需求模型将是有益的。
此外,模型公式的改进可以帮助我们整合其他可变数据,如我们上面确定的基于分钟的定价。
Maybe for the next project.
在下一部分中,我们将从清理后的数据集中查看更多基于地理的数据和库存。感谢阅读!笔记本可以在 Github 上找到,也可以在 LinkedIn 上随意连接!
用谷歌视觉 API 标记 instagram 照片
原文:https://towardsdatascience.com/labelling-instagram-photos-with-google-vision-api-fca4c4b54fa4?source=collection_archive---------16-----------------------
今天我将使用谷歌云视觉分析 instagram 图片
方法
主要涉及两个技术步骤:
- 使用 instaR 包从我的 Instagram 账户中删除照片
- 通过谷歌视觉用谷歌视觉 API 在 R 中给照片加标签
由于关于 RoogleVision 和 instaR 的操作方法已经在这里和这里介绍过了,这两者都涉及到设置开发者账户和认证,所以我将重点介绍使用它们的体验和结果。
观察结果
我学到的一件事是,instagram 只允许在沙盒模式下抓取 20 张最新照片,除非你提交应用程序进行审查。此外,如果你使用的是“轮播”模式,在一篇文章中汇集几张照片,instaR 将只下载封面图片。由于我不经常发 instagram,这就涵盖了过去 3 个月的照片,也让我对我发布的内容有了更好的理解。
结果
labelled instagrams
一些观察结果:
- 该 api 正确地标记了大多数照片,除了非常抽象的照片,如沙滩上的沙子(标记为纹理)。谷歌视觉 API 更关注标签、颜色组合等,似乎不提供字幕
- 标签检测算法将返回几个最高概率的排序结果。具有预支配色块的图片更多地被标记为颜色而不是物体,即,穿红色衣服的人被标记为“红色”作为第一标签,而“面部表情”作为第二标签
- 还有一张复杂的照片没有标注。这张照片包含一幅 3D 壁画和食物。壁画似乎很难让图像识别 api 理解
- 我想量化我通常拍摄更多的主题,但是考虑到 20 张照片的限制,我只能说我有关于花和天空的重复帖子
这是我关于数据科学和视觉故事的# 100 日项目的第 45 天。我的 github 上的全部代码。感谢阅读。欢迎新主题的建议和反馈。
基于深度学习的土地利用/土地覆盖分类
原文:https://towardsdatascience.com/land-use-land-cover-classification-with-deep-learning-9a5041095ddb?source=collection_archive---------4-----------------------
Land use classes
在环境监测和许多其他子领域中,识别地球表面的物理方面(土地覆盖)以及我们如何开发土地(土地利用)是一个具有挑战性的问题。这可以通过实地调查或分析卫星图像(遥感)来完成。虽然进行实地调查更加全面和权威,但这是一个昂贵的项目,而且大多需要很长时间来更新。
随着最近航天工业的发展和卫星图像(免费和商业)可用性的增加,深度学习和卷积神经网络在土地利用分类方面显示了有希望的结果。
在这个项目中,我使用了免费提供的 Sentinel-2 卫星图像对 9 个土地利用类别和 24000 张带标签的图像进行了分类(图 2)。原始数据集包含 10 个类和 27000 个带标签的图像,可从这里获得。
Figure 2— Land use classes
这里有一些不同土地利用类型的可视化图像。
Figure 2- Visualization
Sentinel-2 的数据是多光谱的,在可见光、近红外和短波红外光谱中有 13 个波段。这些波段具有不同的空间分辨率,从 10 米到 60 米不等,因此图像可被归类为高-中分辨率。虽然有其他分辨率更高的卫星可用(1 米至 0.5 厘米),但 Sentinel-2 的数据是免费的,重访时间长(5 天),这使它成为监测土地利用的最佳选择。
Sentinel-2 Bands, Wavelength, and Resolution
数据预处理
虽然一些深度学习架构可以将所有 13 个波段作为输入,但有必要对数据进行预处理。这些图像是 TIFF 格式的,我尝试的一些架构不能适应它。我选择使用 GDAL 和 Rasterio,这是我最喜欢的工具,也是我最熟悉的工具,将它们转换成 JPG 格式并选择乐队。gdal_translate 成功了。
gdal_translate -of GTiff -b 1 -b 10 -b 13 input_sentinel_13_band.tif output_RGB.tif
这些是我尝试过的一些乐队组合:
- 所有 13 个乐队
- 红、绿、蓝(RGB)波段
- 短波红外线(SWIR)
- 高分辨率波段(10-20 米波段)
- 特殊波段组合——遥感领域的知识很有帮助。一些波段组合可以引出农业、植被、水或土地。
- 使用不同组合的数据增强(即具有特殊波段的 RGB)
建模
我用 Fastai 库的迁移学习(Resnet50)来训练我的模型。感谢 Fastai 团队令人惊叹的深度学习课程,这里使用的技术来自深度学习课程材料。我训练模型的步骤是:
- 训练最后一层
- 试试数据扩充
- 冻结所有层并从头开始重新训练
建模中使用的技术包括:学习率查找器、带重启的随机梯度下降和退火。
结果
正如在预处理部分提到的,我已经试验了不同的波段组合。我的模型的最高精度为 0.94,虽然这低于原始论文中报告的数据集的精度(0.98),但对于我的项目及其目标来说,这是相对较高的。我所有实验的结果都在下表中(对关键要点的思考部分):
+------------------------+-----------------------------+
| Bands | Result(Accuracy) |
+------------------------+-----------------------------+
| All Bands | 0.83 |
| RGB | 0.84 |
| High Resolution Bands | 0.81 |
| **Special Bands** | **0.94 ** |
| RGB+Special Bands | 0.80 |
+------------------------+-----------------------------+
模型发现难以区分的一些类别是森林和海湖,如混淆矩阵所示(图 3)。仔细观察这两类的图像,人们可以推断,即使是人眼也很难清楚地区分。
Figure 3 — Confusion Matrix
关键要点:
波段组合的领域知识有助于改进这一特定模型。我在土地利用/土地覆被分类的深度学习应用中看到的所有文献都使用相同的波段作为所有的类输入(即 RGB 或 SWIR)。我的方法让我提高了将近 10%的准确率。
虽然我假设更多的波段肯定会改善我的模型,但我发现事实并非如此。使用所有 13 个波段效果不佳。这可归因于包含了低分辨率波段。但同样,仅使用高分辨率波段的精度最低(0.81)。
另一个实验是通过将 RGB 图像和特殊波段组合添加到同一个文件夹中来增加数据集,从而使可用于训练的图像数量翻倍。这个精度最低(0.80)。笔记本在这里可用。
利用深度学习进行车道检测(第一部分)
原文:https://towardsdatascience.com/lane-detection-with-deep-learning-part-1-9e096f3320b7?source=collection_archive---------0-----------------------
这是我的车道检测深度学习解决方案的第一部分,涵盖了我之前方法的局限性以及使用的初步数据。第二部分可以在这里找到!它讨论了我创建的各种模型和我的最终方法。这里和后面帖子中提到的代码和数据可以在我的Github repo中找到。
即使在各种各样的条件下,人们也可以相当容易地找到道路上的车道线。除非有雪覆盖地面,降雨量非常大,道路非常脏或年久失修,我们可以告诉我们应该去哪里,假设这些线实际上是有标记的。虽然你们中的一些人可能已经想挑战其他司机是否真的成功地保持在线内(特别是当你想超越他们的时候),即使没有任何驾驶经验,你也知道那些黄线和白线是什么。
另一方面,计算机发现这并不容易。阴影、眩光、道路颜色的微小变化、线路的轻微阻塞……所有这些人们通常仍然可以处理,但计算机可能会与之进行激烈的斗争。这当然是一个有趣的问题,以至于在 Udacity 的无人驾驶汽车纳米学位的第一期,他们将五个项目中的两个集中到了这个问题上。第一个是一个很好的介绍,用来向学生介绍一些基本的计算机视觉技术,如 Canny 边缘检测。
Canny Edge Detection
第二次,在学期的第四个项目中,我们做得更深入一点。这一次,我们使用了一个叫做透视变换的概念,它将图像中的某些点(在这种情况下,是车道线的“拐角”,从图像的底部,车道在汽车下方延伸到地平线附近的某个地方,这些线在远处会聚)延伸到目的地点,对于道路来说,这使你看起来像是一只在头顶上飞行的鸟。
Perspective Transformation of an Image
在透视变换之前,可以使用梯度(当您穿过图像时像素值的变化,如黑暗的道路变为亮线的地方)和颜色阈值来返回二进制图像,只有当这些值高于您给定的阈值时,才会激活该图像。透视变换后,可在线上运行滑动窗口,以计算车道线曲线的多项式拟合线。
The ‘S’ channel, or Saturation, with binary activation
A few more thresholds (left) for activation, with the resulting perspective transformation
Sliding windows and a decent-looking result
这看起来一开始还不错,但是有一些很大的限制。首先,透视变换对于摄像机(在变换之前也需要单独保持不失真)、摄像机的安装,甚至汽车所在道路的倾斜都是相当特定的。其次,各种渐变和颜色阈值仅在一小部分条件下起作用——我在开始时提到的计算机在查看车道线时遇到的所有问题在这里变得非常明显。最后,这种技术很慢——我用来将预测的车道检测返回到视频的技术只能以大约每秒 4.5 帧(fps)的速度运行,而来自汽车的视频可能会以大约每秒 30 帧或更高的速度运行。
When Lane Detection Goes Wrong
SDCND 第一学期的其他两个项目专注于深度学习,在这些情况下,用于交通标志分类和行为克隆(让虚拟汽车根据输入的图像以特定角度转向,在训练它时复制你的行为)。五个项目中的最后一个也可能通过深度学习来实现,尽管主要方法使用了不同的机器学习技术。我实际上一直在推迟我的独立机器学习纳米学位的顶点项目,特别是为了尝试在车道检测上使用深度学习方法,现在我已经完成了所有这些项目,包括车道检测和深度学习,这似乎是尝试我的顶点的完美时间。
数据
我的第一个决定,也许是最关键的(不幸的是,也许也是最耗时的),是决定创建我自己的数据集。尽管有很多数据集被用于训练潜在的无人驾驶汽车(几乎每天都在增加),但它们大多没有根据汽车自己的车道进行标记。此外,我认为创建一个足够精确的数据集来训练深度神经网络将是一个有趣而有益的挑战。
收集数据很容易。我住在加州圣何塞,有很多地方我可以开车去。我从我以前的深度学习项目中知道大型数据集有多重要,但也许更重要的是,拥有一个平衡的数据集有多重要。晚上,在雨里,我沿着山坡上非常弯曲的道路,在高速公路和岔路上行驶,到达一个最喜欢的徒步旅行点(幸运的是,当我去收集这些数据时,加利福尼亚的干旱完全逆转了)。虽然听起来可能不多,但我最终用了近 12 分钟的驾驶时间,相当于 21,000 多张单独的图像帧,全部来自我的智能手机。
在找到提取图像帧的好方法后,我几乎立刻就注意到了一个问题。虽然我在明亮条件下驾驶较慢的视频主要由高质量的图像组成,但夜间高速公路驾驶和在雨中驾驶有大量模糊的图像(我将夜间高速公路驾驶问题归咎于圣何塞高速公路的颠簸,正如我的手机在黑暗中的问题一样)。我必须逐个浏览每一张图片,否则我的神经网络可能永远也学不会任何东西。我突然减少到 14,000 张图像,仍然故意留下一些稍微模糊的图像,希望能够在未来进行更强大的检测。
An example of poor data obtained and removed. The trained model, that never saw this image, actually did okay in later predicting the lane for this frame!
为了真正标记我的数据集,我计划仍然使用我的旧的基于计算机视觉的技术。这意味着通过我的旧算法运行图像,而不是输出顶部绘制有预测车道的原始图像,而是输出六个多项式系数,或者每条车道线三个(即方程 ax +bx+c 中的 a、b 和 c)。当然,如果我只是打算在标记中纯粹使用我的旧算法,我只是打算训练我的神经网络来解决与旧模型相同的问题,并且我希望它更健壮。我决定用单色手动重新绘制真实车道线(我选择了红色),这样我可以使用红色通道阈值来更好地检测车道线。在短暂的疯狂时刻,我原本以为我会为 14,000 张图片这样做,但很快意识到这将花费太长时间(除非我像 comma.ai 一样幸运/人脉广泛,可以众包我的标签)。相反,考虑到时间对数据的影响(如果我低速输入几帧内的图像,模型可能会“窥视”自己的验证集,因为预计变化很小),我决定只对十分之一的图像进行这一过程,从而创建了一个由 1,400 幅训练图像组成的早期集。
Drawing over some blurry lines. Given the final model’s ability to still detect lines even in blurry night images, it appears this method did assist in robustness.
此时,我创建了一个程序,可以在道路图像上使用我的旧的基于 CV 的模型,检测线多项式,并使用多项式重新绘制线,类似于我在以前的项目中所做的。这保存了每个生成的图像,所以我可以检查哪些是不够的标签。我注意到了一个直接的问题——尽管我给老款车提供了大量弯曲的道路,但它几乎无法正确检测所有这些道路上的线条。我输入的 1400 张照片中,有近 450 张无法使用,其中大部分是曲线。
然而,我意识到这是由于原始方法本身的性质,由于其滑动窗口的工作方式。如果车道线偏离了图像的一侧,原始的滑动窗口将继续在图像上垂直向上,导致算法认为这条线也应该朝着那个方向绘制。这是通过检查窗口框是否接触到图像的侧面来解决的——如果是,并且窗口已经在图像上前进了一点点(防止模型在开始时完全失败,如果窗口一开始就靠近侧面的话),那么滑动窗口就会停止。**
The original sliding windows on a curvy road, versus cutting the window search at the edge (also more windows)
成功了!我将失败率减半,从最初的 450 张图像减少到 225 张。他们仍然有很多极端的曲线在这里失败,所以我想检查一下标签的实际分布情况。我这样做是通过使用直方图实际检查六个系数中每一个的分布。我又一次失望了。数据仍然过于偏向直线。我甚至回去添加了额外的图片,这些图片来自我拍摄的弯道视频。当我看这些照片时,问题仍然很明显——即使在非常弯曲的道路上,大多数车道仍然相当直。
The original distribution of one of the lane line coefficients — too heavily centered around straight lines
在我的独立交通标志分类项目中,一个很大的不同之处是,通过对数据中几乎没有表示的任何交通标志类别添加原始图像集的小旋转,创建了“假”数据。再次使用这种方法,对于某个分布范围之外的任何系数标签(我迭代了大约外部 400、100 和 30 个图像,这意味着最外部实际上经历了过程 3X),图像稍微旋转,同时保持相同的标签。
The more well-distributed data for a single line coefficient after adding image rotations for the curvier data
经过这一过程后,每个系数的数据分布终于稍微均匀了一些。我还为我的图像和标签使用了一些其他的快速预处理项目。训练图像从最初的 720 x 1280 重新调整了大小(我最终尝试了缩小 4 倍、8 倍和 16 倍的不同版本)并进行归一化(这有助于模型的最终收敛)。我还使用 sklearn 的 StandardScaler 标准化了标签(如果你这样做,请确保保存了 scaler** ,这样你就可以在你的模型结束时反转它了!).这种标签的标准化可能会欺骗你一点,因为训练中的损失会自动降低,但我发现当绘制到图像上时,最终结果也更加令人印象深刻。**
我终于准备好创建和训练一个模型。
准备好第二部分了吗?在这里 阅读关于我的车道检测模型 。
基于深度学习的车道检测(下)
原文:https://towardsdatascience.com/lane-detection-with-deep-learning-part-2-3ba559b5c5af?source=collection_archive---------1-----------------------
这是我的车道检测深度学习解决方案的第二部分,涵盖了我在寻找问题的最终解决方法时创建的实际模型,以及一些潜在的改进。请务必阅读第一部分,了解我之前方法的局限性以及在我做出以下更改之前使用的初步数据。这里和之前帖子中提到的代码和数据可以在我的Github repo中找到。
创建了一个不错的数据集,我准备好制作我的第一个使用深度学习来检测车道线的模型。
透视变换模型
你可能会问,“等等,我还以为你是想摆脱透视变换呢?”这是事实。然而,为了创建一个初始的模型架构,我想检查一下,在数据集有些有限的情况下,深度学习是否可以学习做与基于 CV 的模型相同的事情。因此,这里的输入是透视变换的道路图像,由此神经网络学习系数似乎更容易,这似乎是合乎逻辑的。
我在这里使用了一个与我之前在行为克隆项目中使用的类似的模型架构,包括一个批量标准化层,接着是一些卷积层、一个汇集层、扁平化层和一些全连接层。对于要预测的车道线系数的数量,最终全连接图层的输出大小为 6。我还使用了 Keras 的 ImageDataGenerator 来尝试使模型变得健壮(主要是额外的旋转、高度移动和垂直翻转——水平翻转让我担心,因为标签真的需要更改才能准确描绘线条信息)。经过一点微调(模型架构、参数和输入图像大小),模型产生了一个良好的结果,但是它非常严格地依赖于输入和输出的透视变换——它根本不能很好地概括。
道路图像模型
在发现深度学习可以与我的数据集一起工作后,我接着着手创建了一个模型,它可以在没有任何透视变换的情况下接收道路图像。我使用了与之前完全相同的架构,除了添加了一个裁剪层来剪切图像的上三分之一。我的预期是,任何给定道路图像的顶部三分之一很少包含检测车道所需的信息。该模型很容易收敛到与透视变换模型相似的结果,所以我知道我可以抛弃对输入到模型的原始图像进行透视变换的需要。
在这一点上,我想使用不同于我自己手机的相机给我的模型一些额外的数据(考虑到不同的相机失真),所以我给了它一些来自我之前项目的 uda city常规项目视频的帧。然而,这里的问题是为这些数据创建新的标签——我为标记我自己的数据所使用的透视变换与这个单独视频的不同。这也让我意识到我最初如何处理这个问题的一个巨大问题——从鸟瞰的角度来看,标签本身是多项式系数,这意味着在预测和绘制车道之后,车道仍然需要逆变换回原始图像的角度。
这导致了一个似乎很难概括的模型,但通过查看我自己的一个视频中产生的结果,我意识到,也许该模型仍然正确地检测到线条,只是由于预测后仍在使用透视变换,所以无法再现良好的视觉结果。model 看起来似乎在视角不同的地方遇到了麻烦(在单独的 Udacity 视频和我自己的视频中的更多丘陵地带)。但是,如果它真的学会了检测这些线条,如果我能直接观察这些层本身的活动,又会怎样呢?然后,我可能会在原始视频的顶部显示层的激活。
使用 keras-vis 的激活图
我很快发现了 keras-vis 的巨大知识库,这正是我所需要的。在此之前,我找到了一些关于相同概念的研究论文,但是我找不到重现结果所需的实际代码。keras-vis 库非常棒,因为它允许您将训练好的模型输入到函数中,并返回所需层的激活图,这在技术上是为典型分类神经网络中的每个“类”制作的,但在这种情况下是为我的每个多项式系数制作的。
Activation maps of the first few layers (note that the layers have been cropped by the top third)
这是一种非常有趣的方式,可以确切地看到我的卷积神经网络在我的道路图像中看到了什么。虽然上面的图片在第一层看起来很好,当然,这种方法有更多的问题。
首先,在我的许多弯曲道路图像中,模型实际上只看了一条的线条。我的模型已经知道了线之间的关系,这是因为-在大多数情况下,车道线将是平行的,所以如果你只看一条线(假设它总是两条线中的同一条),你就可以大致了解另一条线的位置。但这并没有帮助我,因为我希望能够显示两条线或车道本身的位置。此外,如果你在上面注意到,可能由于我的图像在模型的生成器中翻转,激活也大量发生在天空中——模型正在学习根据天空在图像中的位置确定自己的方向,所以如果我想在我的原始视频上显示它,我必须以某种方式删除这个激活区域。
Deeper layers visualized
第二个问题更加令人困惑。弯曲的道路倾向于在单条线和天空上激活,而直的道路在图像底部的汽车本身以及汽车本身正前方的空间上激活,而在附近的线本身上不被激活。在图像的上方,这些线条有时会被激活。如果曲线和直线之间的激活没有任何一致性,这种方法就无法工作。
迁移学习
我试图挽救 keras-vis 方法的最后一招是使用迁移学习。我已经完全忘记了我的行为克隆项目,在这个项目中,一辆模拟汽车已经学会了根据提交给它自己训练过的神经网络的图像来驾驶自己。等等——我用超过 20,000 张图片训练了一个模型,让它在路上行驶——它是在看什么来做到这一点的?
One of the simulated car’s input images
答案实际上是整条道路本身(在 Udacity 的模拟器中没有单独的车道),但我想知道我是否可以使用迁移学习来更好地集中模型的注意力。有了一个大得多的数据集来开始训练,我就可以用特定于我的车道检测的新数据添加一点额外的训练,希望有更好的激活层。使用 model.pop()从该项目加载训练好的模型后,我从其中删除了最终输出层(对于转向角,它是一个单一输出),并用我的系数标签的六个输出来替换它。请注意,如果你是自己用一个模型来匹配输入图像的大小,或者它不会工作。
它工作得稍微好一点,因为模型在用我自己的数据进行一些额外的训练后,开始查看车道线而不是整条道路来激活。然而,仍然有很大的一致性问题,图像的哪些部分被激活,它们被激活的程度如何,等等。
完全卷积的方法
感觉自己正处于失败的边缘,我开始寻找一种新的方法。我最近看到几个不同的小组对来自汽车摄像头的图像进行处理的一个领域是图像分割——将给定的图像分成几类,如道路、汽车、人行道、建筑物等。SegNet 是我感兴趣的图像分割技术之一,他们甚至发布了他们的通用模型架构,该架构使用卷积层(批量归一化和 ReLU 激活)结合下行时的池层,以及从中点到分割图像的上采样(本质上是非池化)和去卷积层。这种方法跳过了所有完全连接的层,形成了一个完全卷积的神经网络。
这似乎是一个潜在的解决方案,可以解决车道可能在错误的角度重新绘制的问题——为什么不直接让神经网络自己重新绘制预测的车道呢?我仍然可以输入道路图像,同时使用原始系数标签创建的车道图作为新标签(即输出图像)。考虑到我已经用绿色画了车道,我决定让我的模型的输出“过滤器”仅仅是 RGB 的“G”通道(并且仅仅用它堆叠两个空白过滤器,以使相应的图像与原始道路图像混合)。这也帮助我将我的数据集扩大了一倍——还记得我之前是如何担心水平翻转图像的潜在副作用吗,因为系数标签不会与神经网络看到的匹配得很好?通过切换到这种方法,在预处理数据时,我可以同时翻转道路图像和车道图像标签。
One of the new labels — a lane image
我将快速后退一步,查看此时的数据集:
- 我的原始数据拉有 1,420 张图像(视频中“好”帧的十分之一)。我删除了其中 227 个无法正确标注的项目。
- 我只添加了 568 张来自弯曲道路视频的图片(从我试图使用的 1636 张图片中——由于我用于标记的 CV 模型不够充分,很多图片还是失败了)
- 另外 217 张图片来自 Udacity 的常规项目视频
- 总共 1978 张图片
- 这是低的,并且分布不均匀,所以由于原始系数上的各种小图像旋转没有很好地表示,我最终得到了 6382 个图像
- 水平翻转增加了一倍,达到 12,764 张图片
请注意,我仍然能够对这些新标签使用图像旋转,方法是在我检查哪些系数位于主分布之外时,确保道路图像、系数标签和车道图像标签保持链接。
鉴于我以前从未使用过完全卷积的神经网络,我想非常接近 SegNet 的架构。幸运的是,使用 Keras 做到这一点并不太复杂——解卷积层的一个不同之处是,您必须确保实际上数学与您想要做的事情正确匹配。我通过在最终的合并图层后精确地镜像我的模型,并对我的输入图像使用 80 x 160 x 3 的稍微不同的纵横比(而保持原始纵横比将会有 90 x 160 x 3)来使这变得容易。这样做也是为了让数学更容易,因为我对我的池层使用 2 x 2,从 90 开始会很快到达不能被 2 整除的层,导致在试图镜像前半部分时模型的另一面出现问题。
A quick mock-up of my new structure (left to right)
在我创建的模型中有一些小问题,因为我发现我在尝试根据我的需要向我的每个卷积&反卷积层添加批量归一化和丢弃时耗尽了内存(在上面,你会注意到我在开始和结束时最宽的层没有丢弃,而这些确实是最有效的点)。我满足于在开始时进行批量标准化,并在内层之间进行淘汰。最终的反卷积层输出一个 80 x 160 尺寸的过滤器(我用作“G”颜色通道),以更容易匹配原始道路图像(但这可能会更小,没有任何大问题)。我还通过在开始训练之前除以 255(意味着输出需要在预测之后乘以 255)来标准化车道图像标签,这改进了收敛时间和最终结果。
Comparing results from different models
最终的结果要好得多,从这里的视频中可以看到。当然,这个视频已经看到了一大块图像(可能在 10-20%之间),所以就此打住是欺骗,尽管它在旧的基于 CV 的模型最初未能产生足够标签的领域更有效。真正的测试是来自高级车道线项目的 Udacity 的挑战视频——我的模型从未见过它的任何一帧。但它在这个视频上也表现不错!它对高速公路立交桥下的阴影有一点问题,但在其他方面学会了推广到一个全新的视频。此外,它比旧型号快得多——通常能够用 GPU 每秒处理 25-29 帧,仅次于 30 fps 的实时速度。即使没有 GPU 加速,它仍然比 CV 模型略快,达到 5.5 fps,而之前只有 4.5 fps。
The old CV model vs. the new. You can’t really see it, but the CV-based model actually thinks both lines are on the right.
潜在的改进
这是我用深度学习进行车道检测的方法。当然,它并不完美。它比基于 CV 的模型更健壮,但在 Udacity 发布的更难挑战视频中,虽然做了一个令人钦佩的尝试,但在光影转换中,或当非常高的眩光击中窗户时,仍然会迷失方向。以下是我对未来改进我的模型的一些想法:
- 更多数据。当然,在深度学习中总是如此,但我认为随着更多的条件(如光线和阴影之间令人讨厌的过渡)和更多不同的相机,模型可以变得更好。
- 递归神经网络的使用。我还没有学会实际创建其中一个网络架构背后的技术,但是考虑到它能够使用过去的信息进行下一次预测,我认为这将是一个非常有用的研究途径。有趣的是,我目前在 SDCND 的第 2 学期研究专注于本地化的递归方法(尽管没有深度学习),我预感那里也有潜在的深度学习应用。
- 使用没有车道线或只有一条车道线的数据。这当然可以用在更多的情况下——许多城市以外的社区或地区并不标记所有的东西
- 扩展模型以检测更多项目——类似于图像分割,为什么不添加车辆和行人检测?最后,我可以在单独的滤波器上完成这些操作,越过我用于通道“G”通道的一个滤波器(也不一定仅限于“R”和“B”通道)。这可能比常规的图像分割好,也可能不好。
我也希望听到更多关于改进我的方法的想法。我真的很喜欢找出这种方法,我希望你也喜欢检查它!