TowardsDataScience 博客中文翻译 2020(九百二十四)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

理解链式法则——一种直观的方法

原文:https://towardsdatascience.com/understanding-chain-rule-an-intuitive-way-a7e715f43c86?source=collection_archive---------37-----------------------

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

图片来自https://unsplash.com/@kaleyloved,来源:https://unsplash.com/photos/gtVrejEGdmM

这篇文章是针对那些在理解链式法则上有困难的高中生或大学生的。我试图用一种直观而又不同的方式来解释一个概念,同时为将来会对你有所帮助的‘全微分’概念打下基础。尽管如此,如果你只是对数学感兴趣,那么这篇文章也适合你!

这是一个微积分系列的第一部分,在这里我将解释一元问题和多元问题的链规则的概念(在引入偏导数之后)。我打算通过提供“材料导数”概念的直观感受来结束这个系列。

在数据科学中,链规则是一个非常重要的概念,尤其是如果你想了解像神经网络这样的概念是如何工作的。

我会假设你从头到尾都知道什么是“导数”。

什么是链式法则?

链式法则是微积分中的一个概念,其中一个复合函数的导数不仅仅是母函数的导数,它还受到其子函数导数的影响。

那么这看起来像什么?

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

这个问题有点抽象不是吗?我们先简化一下,再赋予它意义。

假设你正试图衡量你的幸福😊变化,碰巧食物🍞让你开心,听起来很合理,对吗?

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

我理解你可能会觉得用表情符号来代表变量令人困惑,比你想象的要多(这发生在我们大多数人身上!).我将在开始写数学形式,但是我鼓励你‘打破符号’,试着理解概念是什么,而不是‘记忆’数学!

自然,真实的模型比上面描述的要复杂得多,但是我们都可以与之相关。当没有食物时,我们不快乐。当我们有足够的食物时,我们非常满足。当食物太多的时候,我们就不开心。

现在假设,食物🍞是时间的函数,所以它看起来像这样(当你有非常饥饿的家庭成员时尤其如此…):

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

现在,我对测量我的快乐随着时间的变化非常感兴趣。本质上:

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

我敢肯定,你的老师/讲师已经对你进行了训练,“你必须使用链式法则,因为🕒不是的直接变量😊。所以:

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

你有没有想过为什么这行得通?或者,如果我们的幸福方程式中有另一个变量,会发生什么?如果我们的幸福也依赖于其他东西呢?

另一种观点…全微分

考虑全微分的概念。对于一个简单的单变量问题(在我们的例子中,幸福😊只有 T1 是食物的功能吗🍞),意思是:

的总变化😊导数给出😊相对于🍞乘以乘以中的变化🍞

所以:

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

但是为什么我们首先要用全导数的定义呢?的导数有意义吗😊关于🍞,乘以中的变化🍞给了我们变化在😊?

让我们进一步研究这个问题:

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

既然我们现在理解了为什么全微分有意义,我们可以开始应用它了。

我们知道快乐😊是食物的一个功能🍞,所以我们可以用幸福的全微分来写:

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

我们知道食物🍞是时间的函数🕒,所以我们可以用食物的总导数来写:

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

替代食物中的变化🍞在第一个表达式中,通过第二个表达式,我们得到最后一个表达式:

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

现在,我们再次调用时间变化接近 0 的假设。这允许我们将弯曲的 d 转换成直的 d,所以:

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

如果您对曲线 d 如何变成直线 d 感到困惑,请查看此动画:

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

我们现在已经到了链式法则的表达式了!

现在来应用它…

好了,我希望你现在已经更好地理解了链式法则的概念,它是如何产生的,以及它为什么有意义。

我留给你一个问题去解决…

我用来代表快乐和食物的曲线如下:

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

利用链式法则,你能找到快乐随时间的变化吗?

读者注意:

我希望你喜欢这篇文章。我希望能启发你,不要把数学看作是学校里的一门无聊的课程,或者一堆丑陋的符号……而是一种美丽的语言,你可以用它从不同的角度看世界。

我希望我介绍这个概念的相当“非正统”的方法有所帮助。

如果你喜欢我的内容,请关注我,因为这将激励我创造更多…不要羞于通过评论提供反馈!我总是希望学习新的东西;)

了解聚类

原文:https://towardsdatascience.com/understanding-clustering-f25908f3ede5?source=collection_archive---------49-----------------------

让数据科学家理解机器学习的简单笔记

从复杂数据集中自动提取自然群体

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

来源( Unsplash )

什么是集群

聚类是一种无监督的学习技术,用于从预定义的类和先验信息中提取自然分组或标签。这是一项重要的技术,用于探索性数据分析(EDA)以从数据中发现隐藏的分组。通常,我会使用聚类来发现关于数据分布和特征工程的见解,从而为其他算法生成一个新类

聚类在数据科学中的应用

电子商务中的卖家细分

当我在 Lazada(电子商务)实习时,我处理 3D 聚类来找到卖家的自然分组。Lazada 销售团队要求进行分析,以通过多种促销和徽章奖励表现出色的销售人员。然而,要做到这一点,我们需要了解卖家是谁,他们的表现如何。为了做到这一点,我们设计并选择了三个主要维度:客户评论、交付和退款质量,以及产品供应(专业卖家或普通卖家)。

基于这些主要标准,我们创建了 3D 聚类可视化来识别我们的卖家。根据结果,我们对这些卖家进行了分类,并为每个卖家创建了奖励和徽章跟踪。最终,通过 AB 测试,我们提高了 23%的关键销售业绩,并改善了一般用户体验指标。

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

Lazada 使用 Scikit Learn 和一般关键销售业绩进行三维聚类。这是一个例子,而不是避免 NDA 冲突的真实表示(保密协议)。

其他应用

如果我的这个亲身经历还不够的话,在我们的生活中你还可以找到更多的集群应用。

标签标注:假设你想对很多产品进行分类,比如相机、衣服和冰箱。你怎么知道给他们贴什么样的标签合适呢?相机、电视和台式机应该归入相同的标签吗?为了更好地区分这些产品,您应该创建多少个标签?

**客户细分:**假设你正在努力改善零售采购。你能根据买家的购买模式对他们进行分类吗?什么是适当的标签和促销,以增加每个客户群的支出?

**推荐系统中的类型选择:**假设网飞向我们推荐要观看的节目。每个推荐应该有哪些合适的标签或流派来分析用户的观看行为?在节目创作的时间段上对他们的观点进行分类是个好主意吗?

所有这些都需要聚类技术来创建自然分组,尤其是在多维数据复杂性中。

集群是如何工作的?

给定一组对象,我们希望对它们进行聚类;将他们分成一组。

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

我从 IMDB 电影数据中分离聚类

在这个图像中,你可以直接看到一些点的自然组合。这很容易想象,因为我们这里只有两个维度(y 轴和 x 轴)。因此,我们可以突出分组。但是假设我们有很多维度。我们如何使用这些特性将它们分组?

集群目标:

  • 输入:一组物体:x .这是一个距离度量 D(。,.)其中它定义了物体间距离,使得 D(x,y) = D(y,x)其中 x,y E X。
  • 输出:如果 x 和 y 属于同一个集群,对象的划分使得 Pd(x) = Pd(y)

这种由距离定义的相似性概念使人想起 k 近邻(KNN)。这意味着我们可以将对象填充到特定的簇中,而无需测量好簇或坏簇。重要的是我们用来创建分区和分隔组的距离函数。

这意味着解往往具有很高的方差,并且依赖于算法。每个聚类算法可能会得出不同的最佳聚类结果。在本文中,我们将讨论单链接集群,K 表示集群和软集群:

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

具有单个链接聚类(2)和 K 表示聚类(3)的未分组数据集

单连锁聚类

这是最简单的聚类算法。

基本 SLC 聚类步骤

给定 k 个聚类的输入:

  • 我们将每个对象视为具有 n 个簇的簇
  • 我们将类间距离函数定义为多个类中最近的可能距离
  • 合并两个最近的集群
  • 重复这个算法 n-k 次,生成 k 个聚类。

这种算法让我想起了“连点”游戏,这是一种将点一个接一个连接起来以构建特定形状和结构的游戏。

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

把这些点连接起来(来源)

复杂性和局限性

有趣的是,这种聚类算法拥有有趣的属性:确定性(它像 MST 最小生成树算法一样运行),因为它将距离视为边长,时间复杂度为 O(n)。我们需要在 n 次内评估 n 对(最坏的情况)。我们需要重复 k 次(n/2 ),但是我们还需要查看所有距离,以找到具有不同标签的最近的一对 O(n)。

单链接聚类还应用试探法将多个可能没有预期行为的接近点连接在一起。

k 均值聚类

k 表示聚类是一种简单直接的算法,因为每次迭代只需要少量的琐碎操作。它还确定收敛到局部/全局最小值,这意味着我们可以增加置信水平来信任结果。

基本 K 均值聚类步骤

  • 选择 k 个随机质心
  • 将每个点与最近的中心点相关联
  • 通过平均聚类点来重新计算中心
  • 重复这些步骤,直到它收敛。

k 均值优化函数

  1. 配置→中心,P
  2. 分数→P 中心和 x 的平方差总和。
  3. 邻域→离质心最近的点。

与 SLC 相比,范式发生了转变

与 SLC 相比,这需要一些范式转换,并且是现在世界上广泛使用的聚类算法。

  • 取聚类中心(质心)的随机位置,而不是使用现有的观察值作为中心。
  • 迭代每个质心的多个观测成员,直到看不到进一步的改进(收敛)

复杂性和局限性

就 O 符号而言,k 均值比 SLC 更有效——每次迭代的多项式时间为 O(kn)。

然而,也有我们需要考虑的缺点。第一个,k 中的 k 表示之前需要识别。这意味着,在运行该算法之前,我们需要首先通过使用肘方法等来分析最佳聚类数(k)。其次,我们放置的初始种子/质心也会极大地影响我们的聚类。第三个,离群点会极大地影响我们放置的质心,从而影响集群成员。最后,k 表示对假设的球形聚类进行聚类,这在一些非球形数据分布中可能是个问题。

以前我们只讨论了某个只有一个类作为其成员的观察。如果观察结果不明确怎么办?

软聚类

以前我们只讨论了某个只有一个类作为其成员的观察。如果观察结果不明确怎么办?然后我们将观察结果分成两组。

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

分配该观察的正确类别是什么?这仍不清楚。如果我们把这个观察分配给两个类呢?

这就是软集群的用武之地。它使用概率确定性来识别使用所选高斯分布的可能聚类。目标是最大化数据属于某一类的可能性。这被定义为期望最大化(EM 聚类)。

有趣的是,由于 EM 是基于概率的聚类,这意味着有无限多的配置。你永远不会做得更差,但你会不断接近,永远不会接近最终的最佳配置。

聚类算法的属性

那么我们如何选择使用哪个集群呢?对于我们的聚类算法,我们需要考虑以下属性。每个属性将根据我们使用的数据模式和距离矩阵而变化。

  • 丰富度:对于将对象分配给聚类,存在某种距离矩阵 D,使得聚类收敛已经对给出最佳拟合的聚类数量设置了限制。如果我们在聚类未达到 k 时过早地停止 SLC 算法,我们将牺牲丰富性,因为我们限制了聚类的数量。
  • 尺度不变性:假设我们用一个任意的常数(比如从摄氏温度到华氏温度)提升距离度量,聚类成员结果应该不会改变。如果聚类相距某个单位,缩放结果将会改变生成的聚类成员。如果我们在聚类相距预定值单位时过早地停止 SLC 算法,我们将牺牲尺度不变性。
  • 一致性:通过压缩或扩展点,没有点会转移到另一个集群。如果聚类是具有最大识别距离的度数识别单元,那么我们可以转换这个距离公式并改变聚类成员。这意味着当我们使相似的点更相似或使不相似的点更不相似时,聚类不应该改变。如果当聚类是预定义的值单位除以最长的聚类内距离时,我们过早地停止 SLC 算法,我们将牺牲一致性。

理想情况下,您的集群应该具备所有这三个属性。但是,不幸的是,正如不可能定理中提到的,这是不可能的。请随意查看本文中的证明。

没有一种聚类方案可以同时满足这三个条件:丰富性、规模不变性和聚类性— 乔恩·克莱因伯格 15

最后…

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

我自己的聚类分析,使用各种聚类和特征变换技术

我真的希望这是一本很棒的读物,是你发展和创新的灵感来源。

请在下面的评论提出建议和反馈。就像你一样,我也在学习如何成为一名更好的数据科学家和工程师。请帮助我改进,以便我可以在后续的文章发布中更好地帮助您。

谢谢大家,编码快乐:)

免责声明:这是为我创建的复习笔记,用于更新我在佐治亚理工学院 OMSCS 课程中关于机器学习的知识。许多参考资料来自乔治亚理工学院的课堂和外部资源。

关于作者

Vincent Tatan 是一名数据和技术爱好者,拥有在 Google LLC、Visa Inc .和 Lazada 实施微服务架构、商业智能和分析管道项目的相关工作经验。

Vincent 是土生土长的印度尼西亚人,在解决问题方面成绩斐然,擅长全栈开发、数据分析和战略规划。

他一直积极咨询 SMU BI & Analytics Club,指导来自不同背景的有抱负的数据科学家和工程师,并为企业开发他们的产品开放他的专业知识。

最后,请通过LinkedInMedium Youtube 频道 联系文森特

理解组合学:网格上的路径数

原文:https://towardsdatascience.com/understanding-combinatorics-number-of-paths-on-a-grid-bddf08e28384?source=collection_archive---------6-----------------------

你能数出一个普通的 WxH 网格上有多少条路径吗?

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

照片由 Unsplash 上的延斯·勒列拍摄

B asic 组合学是编程人员不可或缺的工具,无论是开发人员、人工智能专家还是数据科学家。

在本文中,我们将解决一个简单的组合问题:计算从一个普通 WxH 网格的一个角到另一个角的路径数。

让我们从这个 3x3 的网格开始:

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

假设我们想从橙色方块到绿色方块。每一步我们都可能向右或向下移动。我们将用 R 表示向右移动的**,用 D** 表示向下移动的**。我们感兴趣的是我们可以选择的不同路径的数量。让我们手动列举路径:**

  • RRDD
  • DDRR
  • RDRD
  • DRDR
  • RDDR
  • DRRD

我们可以得出结论,在这个网格中有 6 条不同的路径。现在来看看这个 8×8 的网格:

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

如果你试图计算这个网格上的路径数,这将花费你相当长的时间。我们需要一些更聪明的数学方法。首先要注意的是,我们要走的步数并不取决于所走的路。

以步数计算的距离总是一样的。

这个距离也被称为 L1 距离、城市街区距离或曼哈顿距离,因为纽约市中心的街区是方形的。

另一方面,我们注意到在正方形网格上,由于对称性,R 移动的次数必须等于 D 移动的次数。此外,我们在每条路径上需要 7+7=14 步(你可以很容易地沿着网格的边界移动)。这两个要求使得以如下方式重新定义 8×8 栅格的问题成为可能:

找出字符串 RRRRRRRDDDDDDD 的不同排列的数目。

现在,排列的数量通常由 N 定义!或 N(N-1)(N-2)2 ,也称阶乘。据此, N 为弦的长度。在我们的情况下,14!= 87178291200.然而,我们必须考虑这样一个事实,即 R 和 D 的顺序并不重要;他们是一样的。两者不同排列的数量是 7!= 5040.我们必须数两遍这个数字,因为 R 和 D 是无法区分的。换句话说,我们分 14!7 点前!*7!。这给了我们 3432,这是正确的答案。

为了将我们的公式推广到任何 NxN 网格,我们可以写成:

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

顺便说一下,还有一种更简单的写法:数字 D = N!/ (K! (N-K)!)也叫二项式系数,我们可以写成(N 选 K)* 。这个数字表示我们可以从一袋 N 个物体中挑选 K 个物体的方法的数量,不考虑挑选的顺序。因此,我们也可以把我们的公式写成:

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

更通用的 WxH 网格呢?在这种情况下,步数是(W-1) * (H-1),我们必须选择(W-1) R 步(你可以自己检查)。因此,公式变为:

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

很简单,对吧?注意,我们可以选择(H-1) D 步,而不是选择(W-1) R 步。直觉上,这应该会给我们相同的答案,而确实是这样。换句话说,这意味着二项式系数是对称的:

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

作为练习,尝试在 30x20 甚至 99x99 的网格上计算路径的数量。你也可以试着写一个递归计算所有路径的程序,但是这样的程序在 99x99 的网格上要花很长时间才能完成!

结论

我希望你在这篇文章中学到了一些实用的组合学,并且你将被激励去学习更多关于这个迷人的主题。

理解并发和多线程程序

原文:https://towardsdatascience.com/understanding-concurrency-and-multi-threaded-programs-261047c8231f?source=collection_archive---------16-----------------------

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

迈克尔·泽兹奇在 Unsplash 上的照片

以及如何让你的程序变得高效

我最近不得不学习在 Go 中编程,因为我正在为浏览器开发一个多人游戏。

我在 reddit 的 r/gamedev 社区上问了一下,被推荐去看看 GO 的后端服务器。

Go 是一种相对较新的语言,由 Google 工程师开发,具有并发特性。

我们将在下一篇文章中学习围棋和多人视频游戏,但首先,我们必须了解并发是如何工作的。

并行执行到底是什么?

与其直接讨论并发性,不如理解什么是并行执行

如果您对计算机科学感兴趣,您可能听说过并行编程,但是如果您没有听说过,请不要担心。

并行执行一个程序基本上就是这个意思。

同时运行两段不同的代码

这意味着两个程序在任何给定的时间点都在运行。一个指令可能会在另一个指令之前完成,但它们不会像常规程序那样顺序执行——一个指令接一个指令。

这很棒,因为这意味着我们可以在相同的时间内将程序的速度提高一倍。同时做两件事比做一件事要快,对吗?

但是伴随着强大的力量而来的是巨大的责任和代价。实际上是两个。

并行运行程序的条件

并行执行需要额外的硬件才能同时运行。

  • 每个并行运行的程序需要一个内核

为了并行运行,两个程序必须严格无关。

  • 这是因为我们不能在不阻塞其中一个的情况下访问两个程序中的相同数据源,这将使程序不再是并行的

让我们讨论一下限制#1,以便更好地理解为什么我们至少需要两个内核来并行运行。

关于处理器的一些信息

程序和线程由我们计算机的处理器执行。处理器由内核组成,每个内核一次只能处理一条指令。

幸运的是,大多数现代处理器都配有 4 核或更多。这就是为什么我们称它们为四核处理器。像桌子这样的小设备可能只有不到四个内核来节省电池,或者因为它们需要更少的计算能力。

比如我的 2019 款 macbook air 就有双处理器。*平行哭泣 *

因为每个内核一次只能处理一件事情。我们至少需要两个内核才能执行任何类型的并行执行。所以如果你有四个内核,理论上,你可以同时执行四个不同的程序。速度快了 4 倍!但同样,它们必须是严格无关的。

两个相关的程序不能并行运行,因为它们需要某种同步才能正常工作。

双赢的并发性

计算机科学家意识到许多程序不能并行执行,因为它们是相互关联的。

每个内核通常也有 4 个线程。

一个线程只是一个开销较小的程序的子进程。

多线程程序将利用额外的线程和内核来更有效地分配程序负载,而不是让一个糟糕的内核完成所有工作,而其他内核只是旁观。

并发的前提是同时运行两个或更多不同的程序。

利用浪费的 CPU 周期

假设我们有一个程序,它等待用户的输入来打印“Hello {user’s input}”,而不是“Hello World”。

一个进程(一个线程也是一个进程)有 5 种状态,在它的生命周期中的任何时候都可以处于这 5 种状态。

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

由你真正创造

每当程序处于就绪或等待状态时,当程序等待一些输入或事件触发时,cpu 周期就会被浪费。

并发利用这种“浪费的时间”来执行另一个程序,而第一个程序正在等待所述事件,例如等待用户键入他的用户名和密码。

今天的计算机速度如此之快,以至于它们的操作系统使用这种策略来“同时”运行可能的程序,但实际上,程序之间的切换真的很快,以至于我们无法分辨它们的区别。

尽管没有并行那么快,但并发可以显著提高程序的速度。

并发编程很难

既然我们知道了什么是并发性以及它能实现什么,那么让我们来看看在实现它时可能会遇到的一些问题。

比赛条件

当两个进程争夺同一个资源时,就会产生争用情况。这意味着整个程序变得不可预测,因为一个程序可能会在另一个程序读取值之前修改它。

再次举例!

假设我们正在实现一个游戏,并将玩家的位置(X,Y)存储在一个哈希映射中。

现在假设玩家 A 向玩家 B 开枪,我们需要检查子弹是否会击中玩家 B 并造成伤害。

我们游戏的碰撞检测和玩家输入组件是同时运行的,所以我们需要确保不会产生竞争情况。

因此,如果我们有一个函数正在检查玩家 A 的子弹和玩家 B 的角色之间的碰撞,但玩家 B 可能同时在移动,则在我们寻找碰撞时,碰撞检测程序可能会修改玩家 B 在数组中的位置。

在最好的情况下,这会造成游戏逻辑的不一致,就像一个玩家没有受到碰撞的影响,但在最坏的情况下,我们的游戏会崩溃,因为内存不能同时读写。

无论哪种方式,我们都不希望发生这种情况,因为这个问题非常难以调试,因为我们不知道代码何时被执行。

并行问题解决方案

我们将使用下面的多人游戏设计来讨论一些现实世界中可以使用并发的场景。

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

多人游戏系统设计

线程间共享数据

有时,一些数据需要在线程之间共享,如果处理不当,这可能会导致争用情况。

解决这个问题的一种方法是提供一种同步线程的方法,这样在任何给定的时间,只有一个线程可以访问或读取选定的源。

在围棋中,这些解被称为通道。不要被这个名字吓倒,因为通道基本上只是一个添加了一些功能的队列。

当一个线程从一个通道中读取数据时,它将阻塞对任何其他线程的所有访问,直到当前线程使用完它。如果有两个或更多的线程想要访问通道,它们必须等到通道可用。这样,我们可以确保不会发生竞争情况。

创建数据的副本

我们可能会遇到这样的情况:我们需要每秒更新数据很多次,而与此同时,用户可能同时在修改数据。有时,我们不能对所有事情都使用同一个通道,除非我们不介意所有组件相互依赖。解耦是确保一个易于维护的干净项目的好方法。

比如,让我们回到游戏的例子。当玩家射击时,一个组件负责创建一个射弹,如果它移动了,还负责更新玩家。

使用第一种方法,我们可以通过一个通道发送每一个输入请求和抛射体创建,并让它从一个单一的源更新一切,以防止竞争情况。

但是直接更新玩家的位置并只发送投射物可能是一个更好的解决方案。这样,我们只需要担心更新投射物和检查物理组件中的碰撞,而不是处理玩家的移动。

为此,我们创建玩家位置的副本,并检查与该副本的碰撞,因为原始数据可能会在我们检查它时发生变化。

因为我们每秒 60 次更新抛射体并检查碰撞,这防止了同时读取被修改的数据,也使我们的物理逻辑与玩家的输入逻辑分开。

如上所述,另一种方法是处理物理组件中的所有内容,这会使我们的代码可读性更差,并且依赖于不相关的组件。

下一步是什么?

通过优化资源和等待时间的使用,并发性可以显著加快我们的程序,否则这些资源和等待时间会被浪费掉。在许多情况下,使用并发性可能会改进程序,但它通常是实时应用程序和视频游戏等高性能系统所必需的。

我们将在下一篇文章中讨论用于解决这些问题的各种策略,以及在 GO 中实现并发程序。

与此同时,你可以开始学习围棋,因为它不同于传统语言,可能需要一些时间来适应它。

祝您愉快!

参考

[1]麻省理工学院,并发性(2014),https://web.mit.edu/6.005/www/fa14/classes/17-concurrency/

[2]伊恩·哈里斯,《围棋中的并发》(2019),【https://www.coursera.org/learn/golang-concurrency

使用 R 中的线性回归模型对条件期望和迭代期望的回顾

原文:https://towardsdatascience.com/understanding-conditional-and-iterated-expectations-with-a-linear-regression-model-f90fb0a5533b?source=collection_archive---------33-----------------------

重访(意料之外?!)概率论结果使用lm()

太长;没看:

  • 您可以对分组变量加上任何其他变量的结果进行回归,未调整和调整后的分组均值将是相同的。
  • 我们可以在一个使用iris数据的简单示例中看到这一点:
iris %>%
 # fit a linear regression for sepal length given sepal width and species 
 # make a new column containing the fitted values for sepal length
 mutate(preds = predict(lm(Sepal.Length ~ Sepal.Width + Species, data = .))) %>%
 # compute unadjusted and adjusted group means group_by(Species)
 %>% summarise(mean_SL = mean(Sepal.Length), mean_SL_preds = mean(preds)) %>%
 kable()

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

  • 这是因为 E[E[Y|X,Z]| Z =Z]= E[Y | Z =Z
  • 我们可以将回归得到的拟合值 E[Y|X,Z]视为随机变量来帮助我们理解这一点。
  • 跳到最后看证明。

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

我承认我在概率论第一学期的大部分时间都在努力理解 X 和 x 之间的区别。当我最终学会了随机变量期望的所有规则时,我仍然对它们在我未来作为一名应用统计学家的工作中的影响毫无兴趣。

最近,当我试图在R中编写一个看似简单的函数时,我发现自己陷入了期望属性的兔子洞。现在我已经把函数的输出整理好了,我对如何使用回归(一个我非常熟悉的框架)来重新思考我在概率论课程中学到的一些性质有了新的认识。

在函数中,我回归了几个变量加上一个分组变量的结果,然后返回拟合值的分组平均值。我的函数一直输出调整后的组平均值,这些平均值与未调整的组平均值相同。

我很快意识到,对于我需要做的事情,我的分组变量不应该在回归模型中。然而,我仍然感到困惑的是,调整后的和未调整的组均值怎么可能是相同的。

我创建了一个非常基本的例子来测试这个意外的结果。我回归了一个来自iris数据集的变量Sepal.Length,一个叫做Sepal.Width的变量和一个分组变量Species。然后,我查看了未调整的Sepal.Length和来自我的线性回归模型的Sepal.Length的拟合值在Species的每个类别中的平均值。

library(dplyr) 
library(knitr)iris %>% 
# fit a linear regression for sepal length given sepal width and species 
# make a new column containing the fitted values for sepal length
 mutate(preds = predict(lm(Sepal.Length ~ Sepal.Width + Species, data = .))) %>%
 # compute unadjusted and adjusted group means
 group_by(Species) %>%
 summarise(mean_SL = mean(Sepal.Length), mean_SL_preds = mean(preds)) %>%
 kable()

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

我看到了同样奇怪的输出,甚至在我的简单示例中也是如此。我意识到这一定是我学过但后来忘了的一些统计学特性,所以我决定写下我在 expectations 中做了什么。

首先,我以期望值的形式写下了未调整组的均值。我写下了一个条件期望,因为当Species被限制在某个类别时,我们在看Sepal.Length的平均值。我们可以通过取一个随机变量萼片长度的期望值,同时设置另一个随机变量物种,一次只等于一个类别,来明确地展示这一点。

E[ 分离 | 物种 = 刚毛

E[ 分离度 | 种类 = 海滨锦鸡儿

E[ 独立 | 物种 = 云芝

更一般地,我们可以使用一个组指示变量物种写出未调整的组均值,它可以采用所有可能的值物种

E[ 分离 | =

这就是我们的未调整群的意思。调整后的群体均值呢?我们可以从写出线性回归模型开始,它是以随机变量 SepalWidth物种为条件的 SepalLength 的期望值。

E[ 萼片长度 | 萼片长度种类

当我对线性回归模型的拟合使用predict函数时,我从该期望值中获得了拟合值,然后将拟合值分组以获得分组平均值。我们可以将这些拟合值视为随机变量本身,并使用分组指示变量写出另一个条件均值,就像我们之前对未调整的分组均值所做的那样。

E[E[ 分离长度 | 分离宽度物种|物种 = 物种 ]]

我的未调整和调整的萼片长度的表因此向我显示:

[E[E[sepal length|sepal width,Species|Species=Species

= E[ 分离长度 | 物种 = 物种 ]]

或者,用更一般的符号来说:

E[E[Y|X,Z]|Z=z] = E[Y|Z=z]]

是真的吗?!剧透警报-是的。让我们一个一个地完成证明的步骤。

验证设置

让我们假设证明我们的 Y (结果) X (调整变量)和 Z (分组变量)都是分类(离散)变量。这只是为了使数学更清晰,因为离散变量的期望(加权求和)比连续变量的期望(概率密度函数的积分乘以随机变量的实现)更容易显示。

我们需要一些基本的预期结果:

条件概率

P(A | B)= P(A∩B)P(B)P(A | B)= P(A∩B)P(B)

划分定理

e[a|b]=∑ba⋅p(a=a|b=b)e[a|b]=∑ba⋅p(a=a|b=b)

联合分布的边际分布

∑a∑ba⋅p(a=a,b=b)=∑aa∑b⋅p(a=a,b=b)=∑aa⋅p(a=a)=e[a]

逐步证明

点击每个步骤后的上标数字了解更多信息。

E[E[Y|X,Z]| Z =ZE[E[Y | X,Z]|Z= z

=E[E[Y|X,Z =Z]| Z =Z]= E[E[Y | X,Z =Z]| Z =Z1

=∑XE[Y|X= x ,z =z]⋅p(x=x| z =z)=∑x e[y | x =x,z =z]⋅p(x=x| z =z)2

=∑x∑y⋅p(y=y| x =x,z =z)⋅p(x=x| z =z)=∑x∑y⋅p(y=y| x =x,z =z)⋅p(x=x| z =z3

=∑X∑Y⋅P(Y= y ,X= x ,z =zp(X= x,Z= z )⋅P(X= x ,z =zp(z =z)=∑x∑y⋅p(y=y,x =【t

=∑X∑Y⋅P(Y= y ,X= x ,z =zp(z =z)=∑x∑y⋅p(y=y,X= x ,z =zp(z =z)5

=∑Y∑X⋅P(Y= y ,X= x ,z =zp(z =z)=∑y∑x⋅p(y=y,X= x ,z =zp(z =z)6

=∑Y⋅P(Y= y ,z =zp(z =z)=∑y⋅p(y=y,z =zp(z =z)7

=∑y⋅p(y=yz =z)=∑y⋅p(y=y| z =z)8

= E[Y | Z =Z]= E[Y | Z =Z9

所以,我们已经证明了:

E[E[Y|X,Z]| Z =Z= E[Y | Z =Z]

谢天谢地,这意味着我有了函数输出混乱的答案。我突然意识到,我可以把内心的期望看作一个随机变量,我学到的关于条件和迭代期望的所有规则都可以应用到我每天拟合的回归中。

这里希望你也能感受到不时重温概率论的灵感,即使你的工作非常实用。毕竟,这是一个社交距离的完美活动!😷

说明

  1. 因为我们使我们的外部期望以 Z= z 为条件,我们也可以将 Z= z 移入我们的内心期望。这在iris示例中变得很明显,因为我们仅使用来自Species的一个类别的拟合值来获得该类别的调整组均值。
  2. 我们可以将 E[Y|X,Z= z 改写为 X 可以取的所有可能值的加权求和。E[Y|X,Z= z 将只能取在 x ,E[Y|X= x ,Z= z 范围内变化的 X 值,因为我们的值 z 已经固定了。我们可以用 P(X= x |Z= z )来加权这些可能的 E[Y|X= x ,Z= z 值中的每一个,因为这是 X 在我们已经固定的 z 取值 x 的概率。于是,我们就可以开始用 P(X =X| Z =Z)P(X =X| Z =Z)对每个 E[Y|X=x,Z= z 进行加权,并把它们全部加起来,就可以求出 E[E[Y|X,Z =Z| Z =Z]定理。
  3. 我们可以通过与步骤 2 类似的过程(用 P(Y= y |X= x ,Z =ZP(Y =Y| X =X,Z= z )加权每个 y 得到 Y 在 X 的每个可能值上的期望值。
  4. 根据条件概率定律,我们可以将条件概率改写为联合分布。
  5. 第一个分数的分母与第二个分数的分子相抵消。
  6. 我们可以交换求和,这样 y 在 x 的所有值的求和之外。这让我们只得到 y 和 z 的联合分布。
  7. 这是一个有条件的期望,写成联合分布的形式。
  8. 根据分割定理。
  9. 将之前的等式改写为期望值。

参考

一个条件期望——亚利桑那数学

原载于 2020 年 3 月 15 日【https://www.khstats.com】

理解条件变分自动编码器

原文:https://towardsdatascience.com/understanding-conditional-variational-autoencoders-cd62b4f57bf8?source=collection_archive---------2-----------------------

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

* 修改而来

(本博客的修改版可以在 这里找到 )

变分自动编码器或 VAE 是一个有向的图形生成模型,它已经获得了很好的结果,并且是生成建模的最先进的方法之一。假设数据是由某个随机过程产生的,涉及一个不可观测的连续随机变量 z. 假设 z 是由某个先验分布 P_θ(z) 产生的,数据是由某个条件分布 P_θ(X|Z) 产生的,其中 X z 有时被称为数据的隐藏表示 X

像任何其他自动编码器架构一样,它有一个编码器和一个解码器。编码器部分尝试学习 q_φ(z|x) ,相当于学习数据的隐藏表示 X 或者将 X 编码到隐藏表示中(概率编码器)。解码器部分尝试学习 P_θ(X|z) 对输入空间的隐藏表示进行解码。图形模型可以表示为下图。

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

(来源)

该模型被训练以最小化目标函数

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

该损失的第一项是重建误差或数据点的预期负对数似然。通过取几个样本,相对于编码器在表示上的分布来取期望值。当使用来自潜在分布的样本时,该术语鼓励解码器学习重构数据。较大的错误表示解码器无法重建数据。

第二项是编码器分布 q_φ(z|x)p(z) 之间的 Kullback-Leibler 散度。该散度测量当使用 q 来表示优于 z 的先验时丢失了多少信息,并促使其值为高斯值。

在生成期间,来自***【N(0,1)】***的样本被简单地馈入解码器。训练和生成过程可以表示如下

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

作为前馈神经网络实现的训练时变分自动编码器,其中 P(X|z)是高斯型的。红色表示不可微分的采样操作。蓝色显示损失计算。(来源)

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

测试时变化的“自动编码器”,它允许我们生成新的样本。“编码器”路径被简单地丢弃了。(来源)

之所以如此简短地描述 VAE,是因为它不是主要的焦点,但与主题非常相关。

使用 VAE 生成数据的一个问题是,我们无法控制它会生成什么样的数据。例如,如果我们用 MNIST 数据集训练一个 VAE,并尝试通过将 Z ~ N(0,1) 馈入解码器来生成图像,也会产生不同的随机数。如果我们训练得好,图像会很好,但我们无法控制它会产生什么数字。例如,您不能告诉 VAE 产生数字“2”的图像。

为此,我们需要对我们的 VAE 架构做一点小小的改变。假设给定一个输入 Y (图像的标签)我们希望我们的生成模型产生输出 X (图像)。因此,VAE 的过程将修改如下:给定观测值 y,z 从先验分布 P_θ(z|y )中得出,输出 x 从分布 P_θ(x|y,z) 中产生。请注意,对于简单的 VAE,先验是*P _θ(z)***P _θ(x | z)**产生输出。

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

条件 VAE 中的视觉表征任务(来源)

所以,这里编码器部分尝试学习 q_φ(z|x,y) ,这相当于学习数据的隐藏表示 X 或者将 X 编码成隐藏表示条件 y 。解码器部分尝试学习 P_θ(X|z,y) 对由 y 限定的输入空间的隐藏表示进行解码。图形模型可以表示为下图。

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

(来源)

条件 VAE (CVAE)的神经网络架构可以表示为下图。

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

x 是图像。y 是图像的标签,可以是 1 热矢量表示。

CVAE 在 Keras 的实现可在这里获得。

参考资料:

  1. 使用深度条件生成模型学习结构化输出表示
  2. 变型自动编码器教程
  3. 自动编码变分贝叶斯

置信区间有什么用?

原文:https://towardsdatascience.com/understanding-confidence-interval-12c99f677f01?source=collection_archive---------23-----------------------

数据科学,统计学

置信区间是一种显示某些统计数据中的不确定性的方法

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

来源:作者图片

在本文中,我们将探讨置信区间,并演示如何解释置信区间。

如何表达一个置信区间?

置信区间不是总体均值存在于区间内的概率,但是,它意味着样本存在于阴影区域的概率为 95%。

例如,平均值点估计不是单一估计,而是置信区间创建平均值的下限上限

区间估计值通常很有吸引力,因为总体参数、状态、均值的估计值会随着样本的不同而波动。

区间估计给出了我们对真实均值的估计有多脆弱的迹象。间隔越小,我们的估计就越精确。

例如,如果我们从喜欢产品 A 和产品 B 的顾客中选择第一个 500 人的样本,我们需要推测出喜欢产品 A 的顾客的数量。

我们将以什么方式做这件事?我们将试图通过观察总人口中的样本来发现它。

我们目前从第一个样本中选择的可能性极小,其平均值为 87%。万一我们现在从第二个样本中选择谁更喜欢产品 A,它将不会与平均值完全相同。

现在重复这个动作,再重复一次。毫无疑问,相对于过去的平均值,样本平均值可能是唯一的。那么你如何认识到人口意味着什么?

对此的回应是置信区间。它向你揭示了模糊的人口平均数的最可能的范围。

万一我们为每个样本计算出 95%的置信区间,那么样本的 95%的区间将具有总体均值。

随着样本量的增加,区间范围缩小,样本均值更接近总体均值,因为您正在缩小标准误差等于标准偏差除以样本量的平方根,从而扩大样本量。

因此,它本质上暗示了由于随机抽样误差的存在,我们对给定样本量的样本均值变化的预期程度。

我们以正或负的形式使用置信区间。当利用样本统计评估总体参数时,样本统计肯定是不准确的。始终会有一些误差,其特征是点估计值加上或减去误差幅度。

什么是点估计和区间估计?

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

照片由 Karina lagoUnsplash 上拍摄

置信界限用一个置信系数的文字来表达。尽管置信系数的决定在某种程度上是任意的,但我们通常使用 90%、95%和 99%的区间。

95%的置信区间并不意味着该区间有 95%的可能性包含真实均值。

根据给定样本计算的区间要么包含真实均值,要么不包含真实均值。相反,置信水平与估计区间的技术有关。

置信系数就是给定大小的样本的比例,它可以用来包含真实的平均值。

也就是说,对于 95%的置信区间,如果收集了几个样本并计算了置信区间,则这些区间的大约 95%将具有扩展运行中的真实平均值。

这是点估计和区间估计的根本区别。

如何估计一个总体均值?

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

照片由 Gursimrat GandaUnsplash 上拍摄

万一我们热衷于用样本评估总体均值,而总体方差是模糊的,我们假设总体分布是正态的。

用样本方差和(n-1)自由度 t 分布代替总体方差。

在这样的情况下, t 分布看起来,特别像标准的正态分布。主要的对比是它在某种程度上更加分散,并且这种分散的扩展对于小自由度来说更大。

当样本相当大时,自由度是显著的,t 分布和标准正态分布是相同的。

依赖于 t 分布的置信区间很难违反正态性,并且由于中心极限定理,正态总体假设对于较大的样本量不太重要。

例如,我有 95%的信心,新产品的平均客户满意度在 1 到 10 的范围内,从 5 到 7。

什么是比例的置信区间?

调查经常被用来估算比例,因此必须认识到如何为任何人口比例构建一个置信区间。样本需要是自主的。总体应至少是样本的 10 倍。

因此,比例的抽样分布是正态的,这意味着万一你一次又一次地做了类似的调查,并把每个样本的比例画在一条数字线上,图表就会形成一条钟形曲线。

例如,我有 95%的信心,对我们的新产品感到满意的客户的真实比例在 47%到 78%之间。

比例的单侧置信区间从无限大到某个上限,或者从某个下限到无限大。除非样本非常大,否则它们都很宽。

只是利用一个关于双边极限的类似方法,然而对于 95%的置信度,将 5%而不是 2.5%放在尾部。如果假设参数不在区间内,则拒绝应该等同于单侧检验。

在任何情况下,置信区间都是定期估计的,并且这种估计并不是在每种情况下都非常相称。

例如,在二项式中,置信区间通常是利用预期的标准误差来评估的,该误差取决于观察到的比例,尽管假设检验将它与假设的比例放在一起。

例如,对于制造工厂的抽样,找出低于质量的成品比例的单侧 95%置信区间的上限。

在 190 件抽样的成品中,发现 6 件质量不合格。

标准差的置信区间是多少?

在本例中,标准偏差被用作点估计值。在任何情况下,抽样分布都不是对称的,它不是正态分布或 t 分布。抽样分布是一个右偏分布,称为卡方分布

与 t 分布类似,卡方分布也有一个自由度参数。在此中,单样本置信区间用于测量平均值和标准偏差的 95%置信区间。

均值差异的置信区间是多少?

  • 为了达到置信区间,应满足以下假设。这两个群体有一个相似的方差。人口呈正态分布。每个值都是与其他值分开采样的。例如,双样本置信区间方法,发现两个公司客户的平均终身价值之间的差异的置信区间,并查看该置信区间如何帮助锁定最佳客户。
  • 不等方差、中,可以使用稍微不同的方法来计算均值之间差异的置信区间。在这种差异估计中,检验样本量较大的样本多于检验样本量较小的样本。例如,双样本置信区间方法,用于发现机场候机室高峰时段与非高峰时段滞留时间对比的置信区间。

配对样本之间的均值差异是什么?

当要比较的样本以某种规则方式配对时,为了确定配对样本之间的差异,应满足后续假设。它没有合理地剖析两个独立的变量。样本之间应该有关联。

对于样本中的每一对,计算该对的两个分数之间的差值。此时,对这些差异执行单样本分析。例如,双胞胎被要求从 1 到 10 对 iPhone 11 的功能进行评分,并找出他们评分的平均差异。

比例间差异的置信区间是多少?

双样本分析均值间的差异。尽管如此,我们现在不是对比两种方法,而是看比例。例如,找出购买带有和不带有 1 年额外保修优惠券的笔记本电脑的客户比例之间差异的置信区间。

一半的客户包括 1 年额外保修的优惠券。购买带有和不带有 1 年额外保修优惠券的笔记本电脑的客户比例之间差异的置信区间。

如何计算样本量?

  • 要计算近似总体均值的的基本样本量,首先确定最大误差,并计算与所需置信区间相关的 z 统计量。例如,在极小的可能性下,你需要 95%确定平均值在你的近似值正负误差范围内。为获得新产品平均客户评级的足够薄的置信区间所需的客户样本量。
  • 您还需要估计人口标准偏差。此时的公式是将 z 值乘以标准偏差,然后除以误差,最后将结果平方。向上舍入到最接近的整数。这是在给定置信水平的正负误差范围内逼近总体均值的基本样本量。
  • 在任何情况下,你都有可能试图用最小样本量来逼近人口比例。你需要 p,比例的最清晰可及的近似值,结合 z 和误差。计算 z 除以误差,并对结果求平方。乘以 p(1-p)。万一你现在还没有一个可靠的估计值 p,那么将 p 设为 0.5,这将在你解方程时带来最大可能的结果。了解尝试过新产品的顾客比例所需的样本量。
  • 用于估计均值间差异的样本量有助于了解每个调查小组中有多少员工必须被抽样到一个充分限定的置信区间,以确定平均投诉数之间的差异。他们有两种类型的员工。管理客户经验较少的人和管理客户经验较多的人。组织需要评估这些员工在平均客户投诉数量方面的差异。组织打算利用相同的样本量,从每种类型的雇员中随机选择样本来获取数据。
  • 估计比例差异的样本量了解每个城市必须抽样多少新产品,以实现新产品二次销售比例差异的充分严格的置信区间。销售经理需要知道新产品的二次销售比例在两个城市之间有多大差异。

结论

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

Kelly SikkemaUnsplash 上拍摄的照片

置信区间的问题在于,对于任何一个区间,我们都不能确定它是否包含真实值;然而,我们意识到,它包含真实价值的几率比不包含它的几率要高得多。

它鼓励你适应在产品和服务的不同阶段可能存在的许多不确定性。

现在,把你的想法放在TwitterLinkedin,以及Github!!**

同意 还是 不同意 与绍拉夫·辛拉的观点和例子?想告诉我们你的故事吗?

他对建设性的反馈持开放态度——如果您对此分析有后续想法,请在下面的 评论 或伸出手来!!

推文@ SauravSingla _ 08,评论Saurav _ Singla,还有明星SauravSingla马上!

理解混淆矩阵、精确回忆和 F1 分数

原文:https://towardsdatascience.com/understanding-confusion-matrix-precision-recall-and-f1-score-8061c9270011?source=collection_archive---------5-----------------------

为什么在评估机器学习模型时,准确性不应该是你唯一关心的性能指标

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

封面图片(图片由 Canva 提供,经作者许可编辑)

当我过去几天在 Kaggle 浏览几本笔记本时,我不禁注意到一些名为*“在 dataset_name 上实现 100%的准确性”、“使用 algorithm_name 实现完美的 100%准确性”、*的笔记本,以及其他各种关于如何在你遇到的每个数据集上实现 100%准确性的指南。虽然其中一些笔记本在构建数据集的概化模型方面做得很好,并提供了相当好的结果,但大多数笔记本只是对数据进行了过度拟合。

过度拟合是指产生的分析过于紧密或精确地对应于一组特定的数据,因此可能无法拟合额外的数据或可靠地预测未来的观察结果— 维基百科

这一切中最悲伤的部分是什么?他们甚至没有意识到,在试图达到那个黄金数字时,他们对数据集进行了过度拟合。大多数笔记本都是在初学者友好的数据集上找到的,比如“Iris 数据集”或“Titanic 数据集”,这是有意义的,对吗?我们大多数人在开始机器学习的时候只学到了一件事:“准确性很重要”。虽然这是真的,但这只是在一定程度上有关系。这就是为什么我将讨论其他一些性能指标,如混淆矩阵、精确召回和 F1 分数,在评估机器学习模型时,您应该考虑与准确性一起使用。让我们开始吧。

混淆矩阵

在机器学习领域,特别是统计分类问题中,混淆矩阵,也称为误差矩阵,是一种特定的表格布局,允许算法性能的可视化,通常是监督学习算法。— 维基百科

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

两类分类问题的混淆矩阵(图片来源:作者)

为了理解混淆矩阵,让我们考虑一个两类分类问题,其中两个结果是“肯定的”和“否定的”。给定一个要预测的数据点,模型的结果将是这两个中的任何一个。

如果我们将预测值与真实值(实际值)进行对比,我们会得到一个包含以下代表性元素的矩阵:

真阳性(TP): 这些数据点的实际结果是阳性的,并且算法正确地将其识别为阳性。

真阴性(TN): 这些是实际结果为阴性的数据点,算法正确地将其识别为阴性。

假阳性(FP): 这些数据点的实际结果是阴性的,但算法错误地将其识别为阳性。

假阴性(FN): 这些数据点的实际结果为阳性,但算法错误地将其识别为阴性。

正如您所猜测的,使用混淆矩阵评估模型的目标是最大化 TP 和 TN 的值,最小化 FP 和 FN 的值。

为了更好地理解这个概念,让我们举一个现实生活中的例子:心脏病的预测。在这种情况下,结果将是患者是否患有心脏病。混淆矩阵看起来像这样:

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

心脏病预测的混淆矩阵(图片来源:作者)

在这里,TP 意味着患者实际上患有心脏病,并且算法预测正确。TN 表示患者没有心脏病,算法预测正确。所以目标应该是尽可能地保持这些值。

混淆矩阵如何帮助检测过度拟合?

为了理解这一点,让我们考虑一下心脏病的例子。大多数时候,当我们处理医疗用例时,很有可能会有一个倾斜的数据集,即一个目标变量会比另一个有更多的数据点。在这种情况下,大多数接受测试的人不会被诊断出任何心脏病。因此,数据集中存在不平衡(偏斜)。

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

描述倾斜数据集的心脏病示例(图片来源:作者)

如果我们在上图所示的数据集上训练一个模型,由于没有心脏病的患者的数据点数量远远多于有心脏病的患者,该模型将偏向于具有更多数据点的目标(特别是如果我们仅基于其准确性来评估模型)。

现在,经过训练,如果我们在测试集(没有心脏病的患者有 8000 个数据点,而有心脏病的患者只有 2000 个数据点)上测试模型,即使模型预测所有 10000 个数据点都没有任何心脏病,准确率仍然高达 80%。这可能会产生误导,尤其是在假阴性的风险应该可以忽略不计的领域(一个预测患有心脏病的患者与没有心脏病的患者一样的模型将被证明是真正致命的)。

这就是混淆矩阵发挥作用的地方。对于上述场景,混淆矩阵如下所示:

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

上述场景的混淆矩阵(图片来源:作者)

现在,如果您查看混淆矩阵以及模型获得的准确性,我们可以清楚地识别出模型在训练数据集上过度拟合,因为它将每个未知数据点预测为没有心脏病的患者。如果没有混淆矩阵,我们永远不会知道潜在的问题。

scikit 学习包包括混淆矩阵。你可以在这里查阅官方文档

精确召回

既然你已经理解了混淆矩阵的作用,那么理解精确召回就更容易了。

我们已经看到准确性在某些情况下是如何误导人的。精确度和召回率帮助我们进一步理解所显示的特定问题的精确度有多高。

精度(也叫正预测值)是相关实例在检索到的实例中所占的比例,而召回(也叫灵敏度)是实际检索到的相关实例总数的比例。因此,精确度和召回率都基于对相关性的理解和度量。— 维基百科

简而言之,精确度意味着所做的正面预测有多少是正确的。

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

精度公式(图片来源:作者)

在我们的心脏病例子中,它看起来像这样:

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

精确示例(图片来源:作者)

它可以被翻译成简单的语言,在所有被归类为患有心脏病的患者中,有多少人实际上患有心脏病?

简单来说,回忆意味着分类器正确分类的实际正面预测的百分比。

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

回忆公式(图片来源:作者)

在我们的示例中,它看起来像这样:

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

回忆例子(图片来源:作者)

它主要是问,在所有患有心脏病的病人中,有多少人被归类为患有心脏病?

这个公式乍一看似乎有点相同,但是一旦你明白了要点,就很难把两者混淆起来。

scikit 学习包中也提供了 Precision-Recall。你可以在这里查阅官方文档

精确召回权衡

假设我们训练一个逻辑回归分类器来识别病人是否患有心脏病。如果概率(阈值)大于或等于 0.5,它将预测患者患有心脏病,如果概率小于 0.5,则患者没有心脏病。

现在,如果我们想建立一个模型,只有在对假设非常有信心的情况下,它才能预测患者是否患有心脏病,我们可能需要将阈值提高到 0.7 或 0.8。

在这种情况下,我们最终得到一个具有高精度和低召回率的分类器。精度更高,因为现在分类器更确信患者患有心脏病。召回率较低,因为现在分类器的阈值设置得如此之高,将会有更少的患者被分类为患有心脏病。

另一种选择是,我们建立一个模型,这样它就不会遗漏任何可能的心脏病患者病例(以避免假阴性)。如果一个患有心脏病的病人没有被模型注意到,这可能是致命的。在这种情况下,我们将阈值降低到 0.2 或 0.3,这样即使患者有轻微的可能患有心脏病,也会发出警报,并且可以进行进一步的诊断来证明该假设。

我们这里有一个高召回低精度的例子。召回率更高,因为我们将对更多的心脏病患者进行分类。精确度较低,因为在大量预测患有心脏病的患者中,一些人在进一步诊断后实际上不会患有心脏病。

一般来说,精确召回值会随着阈值的增加或降低而不断变化。构建具有更高精度或召回率的模型取决于您正在处理的问题陈述及其要求。

f1-分数

精确召回值对于理解特定算法的性能非常有用,也有助于根据需求产生结果。但是当涉及到比较在相同数据上训练的几个算法时,仅仅基于精确召回值就很难理解哪个算法更适合数据。

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

单纯基于查准率值,哪种算法更好?(图片来源:作者)

因此,需要一种采用精确召回值并提供这些值的标准化表示的度量。

在二进制分类的统计分析中, F1 得分(也称为 F 得分F 度量)是一个测试准确度的度量。通过测试的精度召回计算得出,其中精度是正确识别的阳性结果数除以所有阳性结果数,包括未正确识别的阳性结果,召回是正确识别的阳性结果数除以所有应被识别为阳性的样本数。— 维基百科

F1 得分也可以描述为精确度和召回率的调和平均值或加权平均值。

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

F1 得分公式(图片来源:作者)

精度或召回值为 0 是不可取的,因此它将使我们的 F1 得分为 0(最低)。另一方面,如果精度和召回值都是 1,那么我们得到的 F1 值为 1,表示完美的精度召回值。F1 分数的所有其他中间值的范围在 0 和 1 之间。

scikit 学习包中也提供了 F1 分数。你可以在这里查阅官方文档

结论

我希望这篇文章能帮助你理解混淆矩阵、精确回忆和 F1 分数这些术语。使用这些指标肯定会帮助您更好地了解模型的性能。一旦您完全理解了这些概念,您还可以研究一些其他评估指标,如对数损失、ROC-AUC 曲线、分类交叉熵等等。

参考

理解共轭先验

原文:https://towardsdatascience.com/understanding-conjugate-priors-21b2824cddae?source=collection_archive---------17-----------------------

基于 PyMC3 的贝叶斯机器学习方法

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

贝叶斯机器学习:传统方式!(图片鸣谢:Saptashwa!)

在这篇文章中,我将全面介绍共轭先验的概念,包括一些例子。共轭先验的概念非常有用,因为共轭先验将贝叶斯更新简化为仅修改先验分布中的一些参数。他们也有必要从贝叶斯方法中学习和理解机器学习。这篇文章使用的 Jupyter 笔记本可以在我的 GitHub 中找到(下面的链接)。你可能期望从这篇文章中学到什么—

  1. 共轭先验的定义
  2. 为什么相关?
  3. 简单的例子来理解这个概念。
  4. 使用 PyMC3 作为解决一般贝叶斯推理的工具。

因此,让我们毫不迟疑地开始吧:

定义:

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

贝叶斯公式:图像信用:作者

在贝叶斯概率理论中,如果后验分布与先验分布同族,那么先验和后验称为共轭分布,先验称为似然函数的共轭先验。最初,你可能认为这很酷,但是这对我们有什么帮助呢?

为什么共轭先验?

在贝叶斯方法中,我们的目标是获得后验分布。在现实生活问题中,证据的计算可能会带来痛苦。比方说,我们正在处理图像,我们的目标是从一组给定的图像中生成一个新的图像。这将是非常困难的建模图像的分布,这是我们的 P(D) 。此外,我们可以将 P(D) 视为一个归一化常数,它可以写成— ∫ P(D|θ) P(θ) dθ 。想象一下在神经网络环境中的这个积分,其中 θ s 是参数,即网络的权重,如果它是一个相对较深的网络,将有数百万个 θ s。因此积分将是难以处理的。共轭优先是来拯救我们从这种痛苦。如果我们的先验分布(在上面的例子中,它将是权重的分布)是似然函数的共轭先验,我们可以获得精确的后验分布。我们来看一个恶作剧的例子:

因为我的朋友 Kitty 有一只不太友好的猫 Nuo,拍拍她会导致要么以概率 p 变得暴躁要么以概率 *(1-p)开始咕噜咕噜叫。*由于我对这种行为不太了解,我假设一个关于 p 的先验分布,带有一个 Beta 分布Beta(2,2) 。如果诺在一个晚上发了 6 次脾气,只咕噜了 2 次,那么 p 的后验分布的参数是什么?每一次拍诺都可以被认为是两个固定结果之一的单个实验。这实际上被称为伯努利试验,类似于抛硬币。由于贝塔分布与伯努利似然共轭,我们已经可以知道后验分布将遵循贝塔分布(如下面的推导所示)。让我们试着找到参数…

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

正如我们所见,对于伯努利可能性,N1次的结果为 1,而第次的结果为 0。选择具有参数 a,b 的贝塔先验,给出具有参数 (N1 + a,N0+b) 作为后验的贝塔分布。因此,选择共轭先验有助于我们仅通过更新先验分布的参数来计算后验分布,并且我们根本不需要关心证据。鉴于我们的问题,我们将有一个后验分布,这将是一个参数(6+2,2+2)的贝塔分布。一旦我们知道了贝塔分布的参数,我们就可以计算出 x = 0.7 时的最大后验概率,如下图所示。此外,请注意,一旦我们使用了可能性,初始先验(参数为 2,2 的 Beta 分布)如何变为更新后的后验。**这是贝叶斯统计中的关键思想,即在看到数据后,我们对模型的最初信念是如何改变的!有关共轭分布的详细列表,请点击查看

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

不同参数下贝塔分布的概率分布函数。对于上面的例子,β先验被选择为具有参数(2,2),在观察一些伯努利试验之后,该参数被更新,并且我们获得了具有参数(8,4)的后验分布。来源:作者

贝叶斯更新的简单例子:二项式和贝塔

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

二项式分布给出了从 N 次伯努利试验中准确获得 k 次成功的离散概率分布(其中每次伯努利试验的结果以概率 p 为真,以概率 q= 1-p 为假)。

让我们用一个更现实的例子来扩展前面的愚蠢例子,我们将利用二项分布与贝塔分布共轭的事实。对于单次试验(例如:掷硬币),二项分布等价于伯努利分布。随着我们收集更多的数据,我们将看到我们的后验知识是如何更新的。让我们假设我们使用一个有偏向的硬币,其中伯努利试验的成功概率(正面)是 0.4。我们认为新的观察结果是二项分布,其中 k 头来自 N 次试验。从简单的β先验— β(1,1)(相当于均匀先验)开始,在下图中,我们看到更多的数据如何帮助我们更新和减少后验分布的不确定性。

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

用增加的伯努利试验(掷硬币)更新贝塔后验概率,成功概率= 0.4。用 python 和赛璐珞创作。来源:作者

让我们看看我用来制作这个简单动画的部分代码——

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

首先,我们使用scipy.stats.bernoulli.rvs创建伯努利试验的 numpy 数组,然后计算成功(人头)和失败的数量。基于这个数字,我们从统一的先验开始更新贝塔分布。赛璐珞模块用于创建 matplotlib 动画。

PyMC3 用于贝叶斯建模:

PyMC3 是构建在the no之上的用于贝叶斯统计建模的 Python 包。它允许用户使用包括马尔可夫链蒙特卡罗(MCMC)在内的各种数值方法来拟合贝叶斯模型。让我们从在 PyMC3 中构建硬币翻转模型开始。

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

这里,我们从使用伯努利似然开始,使用参数(1,1)的 Beta 先验。在伯努利函数的observed变量中,我们将输入数据。这是一种告诉 PyMC3 我们希望根据已知情况(观察结果)来处理未知情况的方式。

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

我们创建伯努利试验,这将是我们的输入数据。给定这个观察到的数据,然后我们告诉 PyMC3 生成 15,000 个样本,我们返回生成的样本和观察到的数据。这样,我们就可以调用函数并生成样本了—

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

我们创建一个观察值列表(伯努利试验),循环收集所有生成的样本和相应的观察值,并将它们存储在一个字典中。执行此代码块时,您将看到使用不掉头采样器(螺母)生成的样本数为 62,000。PyMC3 中的默认采样器是 NUTS,它并行使用 4 个内核(最大数量的 CPU)来创建 15000 个样本。最初的 2000 个样本(每个岩心中 500 个样本)用于调整坚果取样器,稍后将最终丢弃。查看 文档 了解更多。一旦样本生成过程完成,我们就可以想象随着试验(观察)次数的增加,后验曲线的演变

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

后验分布的演化。使用[PyMC3 traceplot](https://docs.pymc.io/api/plots.html). Source: Author绘制

我们可以清楚地看到,随着试验次数的增加,后验分布的不确定性越来越小。让我们绘制生成样本的直方图,并与真实的 beta 分布(使用 Scipy 计算)进行比较

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

使用 PyMC3 的采样后验分布(左)与使用 Scipy 获得的真实β分布(右)的比较。来源:作者

在这里,我们已经讨论了共轭先验,并通过一些简单的例子来巩固我们对它的重要性的理解。希望这至少能帮助你开始贝叶斯机器学习。

保持坚强,干杯!

页(page 的缩写)s:我在另一篇文章中介绍了贝叶斯机器学习中另一个可能是最重要的概念,即潜在变量和期望最大化算法

参考:

[1] 共轭先验的注释【M. Jordan 教授;加州大学伯克利分校。

【2】链接到我的笔记本!

为什么梯度下降适用于线性回归

原文:https://towardsdatascience.com/understanding-convexity-why-gradient-descent-works-for-linear-regression-aaf763308708?source=collection_archive---------24-----------------------

凸优化和机器学习之间的联系

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

阿萨·罗杰在 Unsplash 上的照片

当我第一次开始自学机器学习时,我惊讶地发现我已经有了一些这方面的背景。我在大学里只上过一门计算机科学入门课,所以我期望有更高的学习曲线。我过去的线性代数课以及 3Blue1Brown 线性代数系列(强烈推荐)都派上了用场。我没想到会派上用场的是我的优化课。这可能是因为我在对机器学习一无所知之前就上了这门课,因此很快就忘记了课堂上提到的这两者之间的任何明显关系。但当我开始学习线性回归时,我仍然记得看到“梯度下降”这几个字时,我想,“等等,我已经知道这是什么了。”凸性理论使我们很容易理解为什么我们可以使用梯度下降来解决线性回归成本函数。在这篇文章中,我希望涵盖该理论的基础,并提供对线性回归的更深入的理解。

凸面

我们先通过凸集和凸函数来定义凸性。史蒂芬·博伊德的凸优化教科书是这个主题的一个很好的资源。凸集定义如下:

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

直观地说,在二维空间中,我们可以把凸集想象成一个形状,在这个形状中,无论你画什么线来连接集合中的两点,该线的任何部分都不会在集合之外。

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

(左)凸集,(中)非凸集,(右)凸集

凸集的这种定义正好符合如下所示的凸函数的定义:

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

正如凸优化教科书中所述,你可以直观地将凸函数想象为这样一个函数,如果你从(x,f(x))到(y,f(y))画一条线,那么凸函数的图形将在这条线的下方。下面是三个例子,我们用这种直觉来判断函数是否是凸的。

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

(左)具有唯一优化器的凸函数,(中)非凸函数,(右)具有多个优化器的凸函数

我们可以看到中间的图不是凸的,因为当我们画一条连接图上两点的线段时,有一些点(x,f(x))f(x)大于线段上相应的点。

左边和右边的图形都是凸的。无论你在这些图上画什么样的线段,该线段总是在函数图的上方或等于函数图。右边的图有许多极小值,而左边的图有一个唯一的极小值。唯一的极小值意味着只有一个点上的函数最小。由于左边的图形是一个二次函数,通过对函数求导可以很容易地找到唯一的极小值。

现在我们对凸集和凸函数有了一些直觉和理解,让我们转向线性回归,看看凸性在哪里起作用。

线性回归概述

线性回归的目的是使最佳线性模型适合一组数据。假设有 m 个数据样本在 n 维空间中。每个样本都有 n 个映射到单个输出值的特征。我们可以访问输入和输出数据,但是我们想弄清楚输入数据和输出数据之间是否存在线性关系。这就是线性回归模型的用武之地。这个模型被写成这样的形式:

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

现在,我们确定最佳线性模型的方法是求解模型的系数,使我们的估计输出值和实际输出值之间的误差最小化。我们可以使用线性最小二乘法来实现这一点。因此,我们的成本函数如下:

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

我们称这个函数为“成本”函数,因为我们计算的是估计值和真实值之间的总误差或成本。由于线性最小二乘问题是一个二次函数,我们可以解析地最小化这个成本函数。但是,对于大型数据集,使用称为梯度下降的迭代方法来查找最佳系数通常计算速度更快。如何使用梯度下降来最小化成本函数的分解如下所示:

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

成本函数的凸性

现在让我们进入一些凸优化理论。如上所示,梯度下降被应用于寻找成本函数的全局最小值。但是我们怎么知道全局最小值的存在呢?**当最小化一个函数时,凸函数确保如果存在最小值,它将是全局最小值。**我们前面看到,二次函数是凸函数。既然我们知道线性最小二乘问题是一个二次函数,我们也知道它是一个凸函数。

此外,像线性最小二乘问题这样的二次函数是强凸的。这意味着该函数具有唯一最小值,且该最小值是全局最小值。因此,当我们应用梯度下降算法时,我们可以确信它将收敛于正确的极小值。如果我们试图最小化的函数是非凸的,如上图所示,梯度下降可能会收敛于局部最小值而不是全局最小值。这就是为什么非凸会更难处理的原因。这很重要,因为许多机器学习模型,最著名的是神经网络,是非凸的。下面你可以看到一个最简单的梯度下降法找不到全局极小点的例子。

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

非凸函数上收敛到局部最小值的梯度下降示例

结论

优化是机器学习的核心。虽然对二次函数应用梯度下降可能看起来很直观,但看看凸分析理论如何证明这种直观是很有趣的。这个理论可以扩展到分析任何机器学习模型,以了解它可能有多难解决。随着我继续我的机器学习之旅,我很兴奋地了解到优化可以帮助阐明不同机器学习概念的其他方式。

通过在 Julia 中实现来理解卷积

原文:https://towardsdatascience.com/understanding-convolution-by-implementing-in-julia-3ed744e2e933?source=collection_archive---------22-----------------------

一个关于我在 Julia 中实现卷积的实验以及从中得到的启示的故事。

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

罗马法师在 Unsplash 上拍摄的照片

在 Fast.ai 深度学习课程的第二部分中,我了解到不仅要能够使用 Tensorflow / PyTorch 等深度学习库,而且要真正理解其背后的想法和实际发生的事情,这很重要。没有比我们自己尝试和实现它更好的理解它的方法了。

在机器学习实践中,卷积是我们都非常熟悉的东西。所以我想,为什么不试一试呢?下面是我在 Julia 中实现卷积的实验结果。

为什么是朱莉娅?

当我上吴恩达的机器学习课程时,我主要是用 MATLAB 来理解机器学习算法。但是 MATLAB 是一种商业产品,可能非常昂贵。

Julia 非常快,并且专门设计为非常擅长数值和科学计算,这是我们在实现机器学习算法时需要的。也很好学。最重要的是,它是免费和开源的。

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

与其他语言相比。来源

开始实验

好了,现在是开始工作的时候了。你看,已经有这么多关于 CNN 的文章了,所以我就不多解释了。如果你正在研究 CNN 的基本概念,我推荐吴恩达的这个 Youtube 播放列表。

从简单的事情开始总是好的。所以对于我的实验,我将使用 6x6 矩阵作为输入,3x3 矩阵作为滤波器,以及 4x4 矩阵的预期输出。我从小矩阵开始,这样我可以检查我的函数的准确性。

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

通过电子表格卷积。

我通过 Julia CLI 定义输入、过滤器和预期输出。输入将是 6x6 矩阵,滤波器将是 3x3 矩阵,预期输出将是 4x4 矩阵,具有与上图相同的值。

**julia>** input = [[3,2,4,2,7,6] [8,0,2,1,7,8] [2,2,10,4,1,9] [1,5,4,6,5,0] [5,4,1,7,5,6] [5,0,2,7,6,8]]6×6 Array{Int64,2}:
3  8   2  1  5  5
2  0   2  5  4  0
4  2  10  4  1  2
2  1   4  6  7  7
7  7   1  5  5  6
6  8   9  0  6  8**julia>** filter = [[1,1,1] [0,0,0] [-1,-1,-1]]3×3 Array{Int64,2}:
1  0  -1
1  0  -1
1  0  -1**julia>** output = [[-5,-8,-2,1] [0,-12,-5,5] [4,4,2,-4] [3,6,0,-10]]4×4 Array{Int64,2}:
-5    0   4    3
-8  -12   4    6
-2   -5   2    0
 1    5  -4  -10

迭代#1

因为我们已经知道输入(6x6)和滤波器(3x3),所以输出应该是 4x4。在第一次迭代中,如果我们手动进行计算,并假设过滤器为 3x3,代码将如下所示:

第一次迭代

我们可以在 CLI 中复制整个函数并查看结果。

**julia>** conv_1(input, filter) == outputtrue

而且很管用!Julia 的另一个很棒的特性是我们可以对我们的函数进行基准测试。我们可以通过使用基准工具来完成。

**julia>** using BenchmarkTools**julia>** @benchmark conv_1(input, filter)BenchmarkTools.Trial:
memory estimate:  208 bytes
allocs estimate:  1
--------------
minimum time:     196.880 ns (0.00% GC)
median time:      200.165 ns (0.00% GC)
mean time:        212.749 ns (0.82% GC)
maximum time:     1.828 μs (0.00% GC)
--------------
samples:          10000
evals/sample:     616

正如你所看到的,朱莉娅速度惊人!但是如果我们有超过 3x3 的滤镜呢?

迭代#2

在第二次迭代中,让我们通过遍历一个滤波器矩阵来尝试这样做。代码将如下所示:

第二次迭代

**julia>** conv_2(input, filter) == outputtrue

代码正在工作,现在它可以接受任何大小的过滤器。它的性能怎么样?

**julia>** @benchmark conv_2(input, filter)BenchmarkTools.Trial:
memory estimate:  208 bytes
allocs estimate:  1
--------------
minimum time:     485.372 ns (0.00% GC)
median time:      488.586 ns (0.00% GC)
mean time:        517.087 ns (0.33% GC)
maximum time:     13.017 μs (0.00% GC)
--------------
samples:          10000
evals/sample:     191

还是很快的!但是我能让它更快吗?也许如果我找到另一种方式,而不是通过过滤器循环,这将使它更快,更简洁地阅读。

迭代#3

在 Julia 中,我们可以用点语法做到这一点。因此,我们可以这样做,而不是遍历过滤器:

第三次迭代。

第三次迭代现在更加简洁。让我们试一试:

**julia>** conv_3(input, filter) == outputtrue**julia>** @benchmark conv_3(input, filter)BenchmarkTools.Trial:
memory estimate:  5.20 KiB
allocs estimate:  33
--------------
minimum time:     2.378 μs (0.00% GC)
median time:      2.482 μs (0.00% GC)
mean time:        2.679 μs (2.05% GC)
maximum time:     71.501 μs (95.64% GC)
--------------
samples:          10000
evals/sample:     9

令我惊讶的是,它不但没有变快,反而变得更慢了,而且差别很大!!这是为什么呢?文档是这样写的:

在其他语言中,为了提高性能,通常也需要矢量化:如果循环很慢,函数的“矢量化”版本可以调用用低级语言编写的快速库代码。在 Julia 中,矢量化函数不是性能所需的而不是,事实上,编写自己的循环通常是有益的。

所以第二次迭代是目前为止卷积的最佳实现。但是这太简单了。如果我更进一步呢?

带衬垫

卷积中常用的另一个概念是填充。如果我们有 6×6 输入矩阵和 3×3 滤波器矩阵,而不是 4×4 矩阵作为输出,通过填充,我们可以得到 6×6 矩阵。这种方法通常被称为“相同”卷积。如果你想了解更多关于填充的概念,请尝试观看来自吴恩达的视频 C4W1L04

如何在我们的卷积函数中实现填充?一种方法是重新创建输入矩阵,在真实值周围填充。计算我们需要多少衬垫的公式是:

padding = (filter - 1) / 2

上面的公式假设滤波器矩阵的大小是奇数。即使不总是,这也是很奇怪的。所以在我的实现中,我假设滤波器矩阵的大小是奇数,我将用 0 填充填充。

带衬垫

当我试图计算填充值时,您可能会注意到\运算符。这是因为 Julia 的类型稳定性特征。基本上所有的/运算符都会返回 Float,所有的\都会返回 Integer。这种类型稳定性是 Julia 超快的一个主要原因!

让我们试试这个函数,以获得与输入和滤波器矩阵“相同”的卷积。请注意,从[2,2]到[5,5]的值与前一个函数完成的“有效”卷积相同。

**julia>** padding_conv_1(input, filter, "same")6×6 Array{Float64,2}:
 -8.0   1.0    2.0  -5.0    1.0   9.0
-10.0  -5.0    0.0   4.0    3.0  10.0
 -3.0  -8.0  -12.0   4.0    6.0  12.0
-10.0  -2.0   -5.0   2.0    0.0  13.0
-16.0   1.0    5.0  -4.0  -10.0  18.0
-15.0   3.0   10.0  -1.0   -9.0  11.0**julia>** padding_conv_1(input, filter, "same")[2:5,2:5] == conv_2(input, filter)true

我们的 padding_conv 函数的性能也不差。

**julia>** @benchmark padding_conv_1(input, filter, "same")BenchmarkTools.Trial:
memory estimate:  992 bytes
allocs estimate:  2
--------------
minimum time:     1.746 μs (0.00% GC)
median time:      1.803 μs (0.00% GC)
mean time:        1.865 μs (0.72% GC)
maximum time:     70.076 μs (96.21% GC)
--------------
samples:          10000
evals/sample:     10

虽然与预期的“有效”卷积相比相当慢,但内存分配仍然很低。

步进卷积

同样,我想通过尝试实现“步进”卷积来改进我的卷积。通常情况下,步幅=1。如果你想了解更多的概念,请观看来自吴恩达的视频 C4W1L05

实现步进卷积有点棘手。首先,我需要根据输入、过滤器和步幅找到输出矩阵的大小。该尺寸的公式为:

result = (input-filter) ÷ stride + 1

因此,如果我们有 7×7 输入矩阵和 3×3 滤波器矩阵,并且跨距=2,我们将有 3×3(而不是跨距=1 的 5×5)。棘手的部分是迭代输入矩阵。在我们的简单卷积中,输入和输出矩阵之间的变化率是相同的,即 1。这就是为什么我们在迭代输入矩阵时可以使用变量ij

但是当步幅不为 1 时,我们需要一个额外的变量来迭代输入矩阵。代码如下:

迈着大步

让我们看看性能结果。在这次检查中,我使用 7x7 输入矩阵和 3x3 滤波器。这是为了让我可以尝试 stride=1(预期 5x5 过滤器)和 stride=2 (3x3 过滤器)。

**julia>** input7 = rand(7,7)**julia>** @benchmark stride_conv_1(input7, filter)BenchmarkTools.Trial:
memory estimate:  288 bytes
allocs estimate:  1
--------------
minimum time:     742.395 ns (0.00% GC)
median time:      747.081 ns (0.00% GC)
mean time:        772.902 ns (0.40% GC)
maximum time:     5.709 μs (86.29% GC)
--------------
samples:          10000
evals/sample:     124**julia>** @benchmark stride_conv_1(input7, filter, 2)BenchmarkTools.Trial:
memory estimate:  160 bytes
allocs estimate:  1
--------------
minimum time:     319.876 ns (0.00% GC)
median time:      322.438 ns (0.00% GC)
mean time:        327.930 ns (0.56% GC)
maximum time:     2.753 μs (87.78% GC)
--------------
samples:          10000
evals/sample:     233

步幅越大,速度越快!这是有意义的,因为我们比以前迭代得少。

把所有的放在一起

我们已经看到了如何使用填充和步幅> 1 进行简单卷积。让我们看看能否将它们放在一个函数中。

基本二维卷积

我们可以在 CLI 上尝试一下。

**julia>** @benchmark conv2d(input7, filter, 2, "same")BenchmarkTools.Trial:
memory estimate:  944 bytes
allocs estimate:  2
--------------
minimum time:     980.100 ns (0.00% GC)
median time:      1.044 μs (0.00% GC)
mean time:        1.072 μs (1.00% GC)
maximum time:     55.501 μs (97.63% GC)
--------------
samples:          10000
evals/sample:     10

结论

我所做的只是一个非常基本的二维卷积算法。在实践中,我们通常使用多层的三维卷积,并且通常与池算法配对。但对我来说,在 Julia 中学习并实现一个非常基础的卷积已经是非常令人兴奋的事情了。

我也还在学习朱莉娅。请随时告诉我如何改进我的代码。感谢阅读。

如果你对代码感兴趣,这里有 GitHub 上资源库的 链接。

理解神经网络中的卷积和汇集:一个简单的解释

原文:https://towardsdatascience.com/understanding-convolutions-and-pooling-in-neural-networks-a-simple-explanation-885a2d78f211?source=collection_archive---------7-----------------------

对使卷积神经网络工作的概念及其背后的直觉的直观解释

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

来源: Unsplash

卷积网络的工作原理?它们背后的魔力是什么,让我们在图像分类、物体检测、人脸识别等广泛的应用中取得成功?

事实证明,所有这一切都是可能的,这要归功于两个惊人简单但强大的概念:卷积汇集

在这篇文章中,我将尝试用一种真正直观视觉的方式来解释它们,把数学放在后面。我在网上找了很多有很强数学基础的文档,但是我觉得核心思想有时候被所有的公式和计算冲淡了。

我们将在本帖中涉及的所有示例都可以在本笔记本中找到。

卷积:这都是关于过滤器的

我们需要理解的第一个关键概念是卷积运算。这很简单:我们将把一个滤镜应用到一个图像上来得到一个结果图像。

例如,假设我们有一个输入图像和一个过滤器:

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

来源:自己的阐述

请记住,任何图像都可以表示为像素矩阵,每个像素代表一种颜色强度:

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

来源

卷积的作用如下:

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

来源

这是,我们正在建立* 另一个图像通过应用过滤器到我们的输入图像。请注意,根据我们应用的过滤器(其形状和值),我们将获得不同的图像。*

但是,我们为什么要这样做呢?似乎没有太大意义!

事实是,这确实很有道理。为了理解为什么,让我们得到一个黑白网格的简单图像。

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

来源:自己的阐述

(请注意,这已经不是矩阵了。它实际上是一个图像)

并对其应用一些过滤器:

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

来源:自己的阐述

我们可以看到,使用特定的滤波器,输出图像只包含垂直边缘。让我们再试试:

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

来源:自己的阐述

在这种情况下,我们只得到输出图像中的水平线。另一种不同的过滤器允许我们强调边缘,而不管方向如何:

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

来源:自己的阐述

显然,我们可以应用一个滤波器,使输入图像保持不变:

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

来源:自己的阐述

这是过滤器背后的想法,现在你可能更好地理解为什么它们被这样称呼了:它们允许我们保留图片中的某种信息,而 T2 忽略其他信息。这是可能的,因为卷积运算是如何工作的。

但是,让我们用另一个图像来看看关于过滤器的更有趣的事情:

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

来源:自己的阐述

如果仔细观察结果,您会看到垂直线被删除,但水平线被保留。但是一个有趣的细节是,因为这个图像是等轴透视的,所以有而不是一条单独的纯水平线

然而,卷积能够处理透视图并且显示实际上是水平的线,尽管透视图并没有这样显示它们。

最后,让我们得到一个真实世界的图像,并应用一些过滤器,看看我们得到了什么。为了便于解释,我们将得到一张黑白照片,但对于彩色图像,直觉几乎是一样的。

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

来源

让我们应用一些过滤器,看看会发生什么:

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

来源:自己的阐述

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

来源:自己的阐述

正如我们所预料的,根据我们应用的过滤器,我们只从图像中提取我们想要的信息。

现在我们已经了解了卷积的工作原理,让我们引入另一个让它更加强大的想法:池化

池化:增强卷积的能力

池的概念很简单:

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

来源:自己的阐述

也就是说,我们将获取像素组(例如,2x2 像素组)并对它们执行聚合。我们可以进行的一种可能的聚合是取组中像素的最大值(这被称为最大池化)。另一种常见的聚合是取平均值(平均池)。

但是,这有意义吗?要回答这个问题,让我们得到一个以前的图像,并应用一个 2x2 最大池:

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

来源:自己的阐述

我们可以看到两件事:

  • 首先,图像尺寸缩小了到一半:通过采用 2x2 像素的组并只保留最大值,现在图像变大了一半。
  • 我们在使用垂直边缘滤波器进行卷积时保留的边缘不仅被保留,而且还被增强

这意味着我们已经能够减少图像包含的信息(通过仅保留一半的像素),但仍然保留并增强了滤波器在卷积图像时显示的有用特征。

这如何适应卷积神经网络?

最后,我将提供一个直观的解释,说明这两个概念是如何构建在卷积神经网络中的。同样,我不会进入数学细节,因为这超出了本文的目的。

一个基本的卷积神经网络可以被视为一系列的卷积层和池层。当图像通过它们时,重要的特征被保存在卷积层中,并且由于汇集层,这些特征被加强并通过网络保存,而丢弃所有对任务没有影响的信息

当我们在神经网络中旅行时,这些重要的特征可以从单线或边(如我们在示例中看到的)到更复杂的东西(例如,狗的耳朵)。

还有一个细微但至关重要的细节:在我们看到的例子中应用卷积时,我们选择了一个过滤器,然后观察输出。实际上,例如,如果我们正在执行图像分类任务,网络将学习哪些过滤器允许我们提取最有洞察力的特征,以便区分我们训练数据集中的类别

你自己试试吧

我已经创建了一个笔记本,这样你就可以自己尝试所有这些想法。您可以上传您想要的图像,并尝试不同滤镜和池的效果。

笔记本可以在这里找到

我建议在 google colab 上运行它,这样你就不必在电脑上安装所有必要的依赖项。

读完这篇文章后,我希望你学会了关于卷积和池如何工作以及为什么它们在 CNN 中有用的直觉。在下一篇文章中,我们将更详细地介绍图像如何穿过 CNN 的各个层,以及如何在每个步骤中提取特征。

免责声明 :本帖提供了关于卷积神经网络如何工作的直觉。为了便于解释,我省略了一些概念,如处理彩色图像中的不同通道、步幅、填充等。这些概念对于全面理解 CNN 很重要,所以一定要牢记在心!此外,这篇帖子的灵感来自 deeplearning.ai 的tensor flow in Practicespecialization,对 CNN 背后的直觉做了极好的解释。

理解相关性和多样化

原文:https://towardsdatascience.com/understanding-correlation-and-diversification-661c19a26555?source=collection_archive---------15-----------------------

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

安德鲁·雷德利在 Unsplash 上的照片

为什么投资不相关的资产是值得的

相关性是金融学和统计学中的一个基本概念。简单地说,相关性告诉我们两个变量一起移动的可能性。高相关性意味着当一个变量上升时,另一个也很可能上升。类似的公司,如可口可乐和百事可乐,它们的股票回报是正相关的:

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

正相关的事物往往会一起运动

负相关意味着相反(当一个变量上升时,另一个变量通常下降)。股票和国债往往是负相关的。

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

负相关的事物往往会向相反的方向运动

相关性为零相当于统计独立性。如果两个变量在统计上是独立的,这意味着两者互不影响。如果你和你最好的朋友每人扔一个六面骰子,结果将是独立的(不管你们两个有多少共同的想法)。

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

不相关的事物彼此独立运动

方差和不确定性

是时候做一点统计了。变量的方差是衡量它变化多少的尺度。你可以通过想象一个游戏来描绘变化,在这个游戏中,你把一根羽毛丢在地上,并试图预测它会落在哪里。如果那天没有风(或者你在室内玩),那就相当容易了。如果没有阵风把它吹来吹去,我们知道羽毛不会飞得太远。因此,我们可以说羽毛的最终潜在着陆点具有低方差:

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

在没有风的情况下,我们可以合理地确定羽毛会落在哪里(低方差)

如果你碰巧在龙卷风中掉了你的羽毛,那么谁也不知道羽毛会落在哪里(它可能会落在几英里以外或更远的地方)。潜在着陆点的极大范围就是高方差的一个例子:

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

在大风的情况下,我们不知道羽毛会落在哪里(高方差)

另一种思考方式是,低方差意味着低不确定性,高方差意味着高不确定性。因此,在可能的情况下,在金融、数据科学和一般生活中,我们希望减少方差,这是有道理的。更少的差异意味着结果更可预测,计划不太可能出错,我们不太可能承受损失(无论是经济上的还是情感上的)。因此,我们可以在保险、应急计划和对冲上花费更少的时间和资源。

低相关性多样化

这就是相关性(或缺乏相关性)的原因。假设我们有两个正态分布的随机变量,X 和 y。这两个变量的均值都是 0,标准差是 1,相互之间的相关性是 0。关于正态分布的基础知识,请看这篇博文。

我们两个随机变量平均值的标准差是多少?我们需要引入一些数学规则来解决这个问题:

  • 方差是标准差的平方(因此在我们的例子中,X 和 Y 的方差都是 1,因为 1 = 1):

Var(X) = Stdev(X)

  • 当我们将正态分布的随机变量 X 乘以常数 W 时,方差与常数的平方成比例:

Var(W*X) = W *Var(X)

  • 两个随机变量 X 和 Y 之和的方差等于它们的方差之和,如果 X 和 Y 是独立的:

Var(X+Y) = Var(X) + Var(Y)

取平均值就像对每个随机变量应用一个常数 0.5,然后求和。因此,我们可以将上述两条规则结合起来,计算出平均值的方差,如下所示:

Var(0.5 * X+0.5 * Y)= 0.5 * Var(X)+0.5 * Var(Y)

酷,现在我们可以计算 X 和 Y 的平均值的方差和标准差(让我们使用实际数字— Var(X)=1 和 Var(Y)=1):

var(0.5 * X+0.5 * Y)= 0.5 * 1+0.5 * 1 = 0.25+0.25 = 0.5

为了简化我们的符号,让我们将 X 和 Y 的平均值称为 A。我们可以很容易地计算 A 的标准偏差,因为我们已经知道它的方差:

stdev(A)= Sqrt(Var(A))= Sqrt(0.5)= 0.71

等等发生什么了?x 和 Y 的标准偏差都是 1,但它们的平均值的标准偏差是 0.71——变量的平均值比单个变量本身的波动性小。我想在这里强调两个关键:

  1. **取平均值很像创建投资组合。**这里,我们将 X 和 Y 分别乘以 0.5,取其平均值。但是我们可以很容易地称 X 为苹果股票回报,Y 为谷歌股票回报。那么我们会把 0.5 理解为一个权重。X 和 Y 的平均值就是平均分配给苹果和谷歌股票的投资组合的回报。因此,当我们进行投资组合时,我们实际上是在对他们的个人回报进行加权平均。
  2. X 和 Y 的平均值的方差(和标准差)低于它们各自的方差。发生这种情况是因为它们彼此独立运动,这使多样化(一个之字形,而另一个之字形,因此群体的平均运动比任何一个个体的运动更不稳定)。另一种理解方式是大数定律。您进行的独立观察越多,这些观察的平均值就越有可能接近真实值(因此 100 次观察的平均值比仅仅 3 次观察的平均值具有更低的方差)。

重要的是要注意,这种影响只发生在变量的相关性小于 1(理想情况下远小于 1)的时候。如果两件事完全相关,那么我们不能指望它们的运动多样化——相反,它们会以完全一致的步伐一起运动(即使我们平均了数千个完全相关的变量,方差也不会减少)。

还要记住,两个不相关变量的平均值的方差并不总是低于变量的单个方差。当一个变量具有高方差而另一个具有低方差时,两个变量的平均值的方差将介于两个个体方差之间。但是由于多样化,平均值的实际方差将明显小于单个变量方差的算术平均值。

我们看到,当我们对两个独立变量取平均值时,标准差是如何从 1 下降到 0.71 的。如果我们可以获得更多不相关的变量来增加我们的投资组合,会怎么样?下图显示了当我们增加更多不相关的随机变量时,标准差会发生什么变化:

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

添加更多不相关变量对平均值标准差的影响

最初增加的几个变量导致标准差在收益递减开始前急剧下降。这是意料之中的——我们已经包含在平均值中的变量越多,我们就越不应该预期每个新变量会对事物产生影响。但即便如此,我们可以看到大数定律在起作用——我们平均的变量越多,方差越低,我们就越有把握。转到金融领域,我们能找到的不相关投资越多,我们投资组合回报的方差(和标准差)就越低,我们就越确定我们不会亏钱。要了解为什么金融行业使用投资组合的标准差作为其风险的代理,请查看我以前的博客。

这正是想要击败世界的对冲基金想要做的。他们试图找到尽可能多的不相关的回报流,将它们组合成一个投资组合,然后希望印钱。通常情况下,事情不会像计划的那样发展,但这是一个美好的梦想。

实际问题

好了,现在我们都兴致勃勃地寻找尽可能多的不相关投资来填充我们的投资组合,是时候给我们的游行浇点冷水了:

  • 真正不相关的投资真的很难找到。你希望你的投资不仅现在是不相关的,而且在经济危机中也是不相关的(当你真正需要多样化的好处时)——而这些更难找到。事实上,大多数投资至少在某种程度上是相关的,这意味着将它们结合起来仍然会减少方差,只是没有那么多。从数学上来说,两项投资的相关性越低,它们就越多样化(见这里的等式)。下图显示了改变两个正态分布随机变量之间的相关性如何改变其平均值的标准偏差:

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

更高的相关性意味着更少的多样化(更少的方差减少)

  • 几乎每个人都拥有的典型风险投资是股票。因此,找到一种与股票负相关的投资将是一件好事,它让我们能够对冲风险(并降低我们整体投资组合的方差)。不幸的是,每个人都想这样。因此,任何与股票回报呈负相关的投资,比如国债、看跌期权或 VIX 期货,都会被定价为溢价,可能会给你带来低回报或负回报(嘿,保险从来都不是免费的)。国债很有趣,因为在过去几十年里,它们的回报与股票的回报呈负相关,而且它们的预期回报为正(不像其他对冲基金,你必须直接支付)。因此,股票和债券的核心配置是大多数长期投资组合的关键。然而,这种负相关并不是必然的——在很多年的时间里(比如 20 世纪 70 年代),股票和债券的回报高度相关(利率的持续上升通常会损害股票和债券)。
  • 这就引出了我的最后一点——我们想要正的投资组合回报(我们想要随机变量的平均值尽可能地大于零)。这意味着零或负预期收益的不相关随机变量对我们没有用。是的,将它们加入我们的投资组合会降低总体方差,但也会降低预期回报(加权平均),这将适得其反。

这篇文章是我投资组合优化入门的第三部分。如果你还没有看过,也看看第 1 和第 2 部分:

理解正态分布

了解投资风险

了解交叉验证

原文:https://towardsdatascience.com/understanding-cross-validation-419dbd47e9bd?source=collection_archive---------16-----------------------

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

萨姆·巴耶在 Unsplash 上拍摄的照片

交叉验证如何帮助我们避免过度拟合的陷阱

我记得我建立的第一个量化模型。这是一个基于我研究的各种市场和经济因素,在美国股票和新兴市场股票之间战术性转移资金的模型。

我花了大量的时间设计(实际上是过度设计)我的功能并运行回溯测试,直到我确信我有一个世界无敌的产品。我的模型最后投产的时候,花了一年时间,基本上什么都没做。最终,我认为它产生了轻微的负累积回报。

我认为自己很幸运。回想起来,我意识到我的模型严重高估了,我很幸运,它推荐的赌注没有让我的公司损失惨重。

识别模型何时过度拟合

今天我们将讨论交叉验证,这是一种帮助我们估计模型样本外性能并防止过度拟合的技术。但首先,让我们谈一谈什么是过度拟合,为什么会发生。

**过度拟合是指我们对现有数据的训练过度,以至于模型失去了泛化能力。**泛化能力好的模型能够合理成功地适应新数据,尤其是那些与该模型到目前为止看到的任何观察结果都不同的数据。因此,如果一个过度拟合的模型不能概括,那么当它投入生产并真正脱离样本时,它很可能表现不稳定(可能很糟糕)。过度拟合的最常见原因是:

  • **伪相关性:**如果我们足够努力地寻找,我们会发现强相关性。例如,我们可能会发现比特币的价格与津巴布韦的披萨价格高度相关。但这最有可能是由于偶然性和随机性,而不是任何真实的东西,我们将钱押在这样的相关性上是愚蠢的。如果我们用一堆与我们试图预测的事物虚假相关的因素来拟合我们的模型,它将不能很好地概括。
  • **过度使用测试集:**这个真的很难完全避免。如果模型在我们的测试集(测试集是我们提供的数据的一部分,以便我们可以评估模型如何在新数据上推广)上工作得不好,那么我们将调整它,直到我们找到在训练集和测试集上都工作得好的配置。这样做的含义是,测试集不再是对我们模型的样本外性能的无偏估计——毕竟,一旦我们开始使用保留集(也称为测试集)做出建模决策,那么我们真的可以认为它仍然是保留的吗?
  • **有偏差的训练集:**我们的训练数据很少能真正代表我们试图建模的人群。因此,我们应该意识到,我们实际上肯定会遇到我们的模型在某些时候发现完全不熟悉的数据。虽然我们应该尽最大努力使样本的特征与总体特征相匹配,但我们也应该知道样本的不足之处。因为这些领域的数据对我们的模型来说是最大的风险。如果我们的样本只代表一小部分人口,那么随着时间的推移,我们的模型将表现不佳。

交叉验证有什么帮助

交叉验证是一种技术,它允许我们使用训练集产生测试集,如评分指标。也就是说,它允许我们仅使用我们的训练数据来模拟“超出样本”的影响,因此我们可以了解我们的模型概括得有多好。

如果没有交叉验证,传统的模型训练过程如下所示:

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

传统列车测试分离

我们在蓝色部分进行训练,直到我们觉得我们的模型已经准备好面对野外。然后我们在测试集上给它打分(黄金部分)。传统方法的缺点是我们只有一次机会。当我们在测试集上测试我们的模型时,我们已经损害了我们的测试数据。如果我们的测试结果很糟糕,那怎么办?我们真的可以放弃所有这些小时的工作吗?或者我们只是开始为测试集优化我们的结果?

要是有一种方法可以模拟我们的模型可能在测试集上的表现,而不实际使用测试集就好了。有!这叫做交叉验证。

交互效度分析

我们将关注一种特定类型的交叉验证,称为 K-folds(所以当我仅仅说交叉验证时,我指的是 K-folds 交叉验证)。K 折叠交叉验证将我们的训练数据分成 K 个折叠(折叠=子部分)。然后,我们训练和测试我们的模型 K 次,以便每个折叠都有机会成为伪测试集,我们称之为验证集。让我们使用一些视觉效果来更好地理解正在发生的事情:

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

三重交叉验证

假设我们正在开发一个预测线性回归模型,并使用 R 作为我们的主要评分标准。我们已经将一些数据分成了训练集和测试集。我们主要关心的是我们的模型的样本外预测的准确性(它概括得有多好)。因此,我们决定直到最后才查看测试集(这样我们可以给我们的模型一个智力上诚实的分数)。

但是当我们调整和改进我们的模型时,我们仍然想知道我们所做的改变会如何影响它的样本外性能。所以我们交叉验证:

  • 我们决定运行 3 重交叉验证,这意味着我们将训练数据分成大小相等的 3 重。
  • 在我们的交叉验证的运行 1 中,折叠 1 被保持(标记为保持 1 的粉红色矩形)。因此,我们在不在折叠 1 中的训练数据(蓝色矩形)上进行训练,然后在折叠 1 上进行验证。这意味着我们使用非折叠 1 训练数据来拟合我们的模型,然后计算并记录我们对折叠 1 中因变量的观察值的预测程度。至关重要的是,在运行 1 中,我们在模型训练期间没有使用折叠 1 中的任何数据,因此使用折叠 1 计算的 R 有点像样本外的 R。
  • 在运行 2 中,折叠 2 伸出。现在,Fold 1,以前是我们的验证集,已经成为我们的训练集的一部分。我们使用折叠 1 和折叠 3 中的数据来拟合我们的模型,并使用折叠 2(通过 R)对其进行评分。
  • 运行 3 结束后,我们现在有三个 R 值(因为每一次折叠都有一次机会)。三个 R 的平均值给了我们模型中样本外 R 的合理估计。

关于交叉验证的工作原理,需要记住的最重要的一点是,在每次运行中,它报告的得分指标都是根据给出的倍数计算的。

结论

使用交叉验证时的一些提示:

  1. 重要的是要记住,我们的模型的交叉验证分数(比如 R)最多是对其在测试集上的性能的乐观估计。就像测试集上的性能充其量是对模型的真实概括能力的乐观估计。
  2. 如果我们对模型所做的更改增加了训练分数(这是在样本中估计的),但降低了交叉验证分数,那么这是一个好迹象,表明我们过度拟合了模型。
  3. 折叠太少会束缚模型,这是因为在每次交叉验证运行中,有太多的训练数据被保留。例如,对于 2 次折叠,一半的训练数据被保留,这意味着该模型仅适合剩余的一半(导致得分度量低于它们应有的值)。一个不适合的模型和一个过度适合的模型一样糟糕。
  4. 在我们训练测试分割之前打乱数据是一个好的做法,以防数据被排序。如果它以某种方式进行了排序,而我们忽略了对它进行洗牌,那么我们的训练测试分割将提供有偏差的数据集,其中任何一个都不能很好地代表实际人群。
  5. 一旦我们通过交叉验证完成了模型的改进,我们应该在测试集上测试它之前,在整个训练集上重新调整模型。

更多数据科学相关帖子由我:

QQ 剧情到底是什么?

理解正态分布

熊猫加入 vs 合并

理解贝叶斯定理

用 OpenCV、OCR 和 DNNs 理解纵横字谜

原文:https://towardsdatascience.com/understanding-crossword-puzzles-with-opencv-ocr-and-dnns-f7dd759650b2?source=collection_archive---------49-----------------------

你能教机器如何阅读填字游戏吗?

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

https://unsplash.com/photos/zlbB-anyO3I

简介

最近,我被分配了一个任务,创建一个算法,从纵横字谜照片中提取所有可能的元数据。这对我来说似乎是个有趣的任务,所以我决定试一试。以下是这篇博客将要涉及的话题:

  • 基于 OpenCV 的纵横细胞检测与提取
  • Pytorch CNN 纵横字谜细胞分类
  • 单元元数据提取

你可以在我的网站和我的 Github 上找到完整的代码实现。

纵横字谜细胞检测

首先,要提取元数据,您必须了解它的位置。为此,我使用简单的 OpenCV 试探法来识别纵横字谜上的线条,并用这些线条形成一个单元格网格。输入图像需要足够大,以便可以容易地检测到所有的线。

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

同一图像上的输入图像和输出行

之后,对于细胞检测,我找到了线之间的交叉点,并根据交叉点形成了细胞。

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

图像线交点

最后,在这一阶段,每个细胞都从图像中切下,并保存为一个单独的文件,以供进一步操作。

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

从单个图像中提取的细胞

用 PyTorch CNN 进行纵横字谜细胞分类

对于细胞分类,一切都很简单。该问题被建模为具有以下目标的多类分类问题:

{0: 'both', 1: 'double_text', 2: 'down', 3: 'inverse_arrow', 4: 'other', 5: 'right', 6: 'single_text'}

对于每个目标类,我为每个类手工标记了大约 100 个单元格。之后,我用以下架构安装了一个简单的 PyTorch CNN 模型:

class Net(nn.Module):
    # Pytorch CNN model class
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 3)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 3)

        self.conv3 = nn.Conv2d(16, 32, 5)
        self.conv4 = nn.Conv2d(32, 64, 5)

        self.dropout = nn.Dropout(0.3)

        self.fc1 = nn.Linear(64*11*11, 512)
        self.bnorm1 = nn.BatchNorm1d(512)

        self.fc2 = nn.Linear(512, 128)
        self.bnorm2 = nn.BatchNorm1d(128)

        self.fc3 = nn.Linear(128, 64)
        self.bnorm3 = nn.BatchNorm1d(64)

        self.fc4 = nn.Linear(64, 7)
    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.pool(F.relu(self.conv2(x)))

        x = F.relu(self.conv3(x))
        x = self.pool(F.relu(self.conv4(x)))

        x = x.view(-1, 64*11*11)
        x = self.dropout(x)
        x = F.relu(self.bnorm1(self.fc1(x)))
        x = F.relu(self.bnorm2(self.fc2(x)))
        x = F.relu(self.bnorm3(self.fc3(x)))
        x = self.fc4(x)
        return x

最终的模型预测几乎是下降的,甚至在不同格式的填字游戏中也能很好地概括。

单元元数据提取

我的最后一步是从标记的单元格中提取所有元数据。为此,我首先以 Pandas DataFrame 格式创建了每个图像单元的分类表示。

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

图像单元文本表示

最后,基于 cell 类,我或者使用 Pytesseract 从图像中提取文本,或者如果单元格被归类为箭头单元格之一,则提取箭头坐标和方向。

该脚本的结果输出以 JSON 格式显示如下:

{“definitions”: 
[{“label”: “F Faitune |”, “position”: [0, 2], “solution”:{“startPosition”: [0, 3], “direction”: “down”}}, 
{“label”: “anceur”, “position”: [0, 4], “solution”: {“startPosition”: [1, 4], “direction”: “down”}}]
}

结论

这项工作对我来说是一次很好的经历,并提供了一个很好的机会来深入研究一项混合了简单的 OpenCV 试探法以及使用更前沿的概念(如 OCR 和 DNNs)进行图像分类的任务。谢谢你的阅读!

你可以在我的 网站 上查看其他帖子

理解计算机视觉:人工智能如何看待我们的世界

原文:https://towardsdatascience.com/understanding-cv-how-ai-sees-our-world-a977b90bf612?source=collection_archive---------27-----------------------

研究人员是如何设法让计算机理解它们看到的东西的?让我们来找出…

“在所有的感觉中,视觉肯定是最令人愉快的.”

——海伦·凯勒

人工智能和神经网络如此受欢迎的一个原因可能是费李非教授在斯坦福大学开设的视觉识别公开课。与安德鲁·恩盖(Andrew Ngai)等许多其他有影响的人一起,他们吸引了大量对深度学习的关注。无论是检测医学图像中的癌症组织,还是在自拍照上添加可爱的动物耳朵,还是将汽车开上街道, C 计算机 V 视觉( CV )为我们描绘了一个美好的未来,在这个未来中,机器可以在许多方面让我们的生活更加便利。

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

机器人看着手,图像来自 Quantica

在本文中,让我们先来了解一些与 CV 相关的历史。然后,我们将进入一些基本的 CV 技术,如直线和边缘检测。在我们建立了基础和直觉之后,我们将进入现代 CV 模型如何工作的细节。在简要介绍深度学习之后,我们将更详细地了解卷积神经网络的基础知识。最后,我们将回顾一些当今最先进的算法。

计算机视觉简史

“如果我们想让机器思考,我们需要教它们看东西.”

—费·

从人工智能转向,CV 领域的研究开始于 20 世纪 60 年代左右。最早的相关论文之一可能是 Hubel 和 Wiesel 在 1959 年发表的猫的纹状皮层中单个神经元的感受野,他们将电极插入猫的大脑,并在改变猫的视觉后观察反应。

他们在 1962 年发表了另一篇论文,对猫的大脑如何处理视觉信息进行了更详细的研究。神经科学相关方法的早期研究相当糟糕。我在之前的一篇文章中提到过,基于神经网络的方法经历了一段黑暗时期,直到 2000 年。

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

Hubel & Wiesel 的实验,图片来自 CS231n 幻灯片

在这个领域还有其他的进展。例如,霍夫变换(Hough’s transform)是以 1962 年保罗·豪格的专利霍夫变换命名的,现在广泛应用于自动驾驶等领域。边缘检测是由 John Canny 在 1986 年提出的,在边缘检测中使用得相当多。边缘检测应用于许多不同的领域,如人脸识别。

当我在加拿大皇后大学(Elon Musk 也去了那里)学习时,格林斯潘教授也展示了他们在机器的对象持久性方面的进展。加拿大人在人工智能研究领域做出了很多贡献,包括著名的 CIFAR。

在我们进入深度学习之前,另一个值得一提的是 Lenna Forsén。如果你在任何与数字图像处理相关的领域,你很可能在某个地方见过她的照片。1960 年,劳伦斯·罗伯茨是第一个在他的硕士论文中使用她的照片的人。

这张照片后来不知何故成了图像处理领域的标准测试图像。《花花公子》杂志计划就肖像权提起诉讼,但当他们意识到这是为了研究和教育时,就好心地放弃了。

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

Lenna Forsén 的肖像,图片来自维基百科

现在让我们回到神经网络。受 Hubel 和 Wiesel 工作的启发,Kunihiko Fukushima 在 1980 年发明了“新克隆”。Neocognitron 可以说是卷积神经网络的最早版本。网络被用来识别手写字符。

Yann LeCun 因其在卷积神经网络方面的工作而闻名,他于 1989 年将反向传播应用于卷积神经网络。然后他在 1998 年发表了基于梯度的学习算法 LeNet-5

神经网络的转折点发生在 2012 年。Alex Krizhevsky 和他的 AlexNet 在 9 月 30 日赢得了 ImageNet 竞赛,展示了基于卷积神经网络的方法的优越性能。

ImageNet 的首席科学家和首席研究员费教授于 2006 年开始研究 ImageNet 的想法。她继续在世界各地的会议和会谈中旅行,影响其他人进入计算机视觉领域。

另一个值得一提的可能是约瑟夫·雷德蒙。雷德蒙在 2016 年发明了 YOLO 篮网。YOLO 这个词可能来自一个流行的网络俚语“YouOonlyLiveOnce”,暗示人们要充分享受生活,通常用在年轻人将要做出鲁莽举动的时候。在论文中,YOLO 代表“你只看一次”,这提供了基于神经网络的快速对象检测。

Redmon 在他的简历中也认为自己是一匹小马,指的是“我的小马”,这是一个针对小女孩的美国特许经营。

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

雷蒙顿简历的潜峰

计算机视觉的进步正以许多不同的方式让我们的世界变得更美好。是时候让我们了解这些算法是如何工作的了!

计算机视觉:基础,在神经网络之前

自从有了电视,监视器屏幕就通过调节三种不同颜色的Ca nodeRyTubes(CRT)的亮度来显示图像——Red(R)、Ggreen(G)和 B lue ( B 尽管现在我们的屏幕可能使用了更先进的硬件,如液晶显示器(LCD)或有机显示器(T42),图像通常以 RGB 表格的形式存储和传输例如,位图将图像存储在范围从 0x000000 到 0xFFFFFF 的十六进制值的数组中,这些值可以表示范围从 0 到 255 的 3 个数字。

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

位图插图,来自媒体上的it 下一篇文章

由于压缩格式或其他约定,某些图像格式可能会以不同的方式存储图像,但它们通常可以转换回 RGB 值数组。在数学直觉的背景下,RGB 值的差异并不代表它们在人类感知方面的实际差异。 C 委员会 I 国际deL’éclairage(CIE)提出了δE度量,从人类感知的角度更准确地表示了色差。****

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

CIE 1931 色彩空间中的麦克亚当图,图片来自维基百科

计算机如何存储和处理图形信息是另一个巨大的领域,我们可以在另一篇文章中深入探讨。

边缘检测和特征提取

“视觉图像是由我们大脑以边缘的形式将像素组打包在一起的能力构建的。”

—吉尔·博尔特·泰勒

由于像素阵列可能很复杂且有噪声,因此很难垂直分析图像。这也是研究人员通常提取边缘、线条等特征的原因。这些特征可以用简单得多的数值或关系来表示。有许多方法来检测边缘,如采取导数或 Canny 的方法。在本文中,我们将简要回顾一下 Sobel 的方法。

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

不同边缘检测算法之间的比较,图像来自 PyImageSearch

边缘本质上是像素间的高度差异,因此大多数边缘检测方法试图提取检测到像素间差异的区域。Sobel 的方法通过用两个特殊的核对图像的 3×3 区域进行卷积(由操作符 ***** 指示)来检测边缘。核将产生梯度的水平和垂直分量,其可用于计算表示边缘的方向和强度的向量。

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

索贝尔方法演示,作者图片

关于数学的更多细节可以在维基百科上找到,并在下面的视频中解释。作者还制作了其他图像处理算法的视频,如 Canny 边缘检测器模糊过滤器

寻找边缘(Sobel 算子),视频来自 Youtube

霍夫变换与自动驾驶

“在苏俄,汽车载着你!”

—俄罗斯逆转

想象一下,我们是一家汽车公司的工程师,该公司希望发明无人驾驶汽车。在某些时候,我们将不得不教汽车在道路上的车道内行驶。否则,我们的车会像《一家人》里的亚洲女司机一样。

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

来自家庭的亚洲女司机

如果交通线是连续的,那就容易了。我们可以确保当赛车太靠近线的任何一侧时,赛车会向后移动一点。但是我们知道,在大多数地方,比如加利福尼亚,街道上都有虚线。如果汽车只检测到它接近线,它可能会在实线之间的间隙失控。

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

经过处理的虚线图像,来自媒体的图像文章

由于霍夫变换,我们将能够从虚线重建直线。霍夫变换将 x-y 空间内的直线转换为 m-c 空间内的点。然而,x-y 空间内的点将被转换成 m-c 空间内的线。m-c 空间还具有这样的性质,即所有与同一点相交的线将对应于 x-y 空间内同一直线上的点。关于 Hough 变换直线检测的更多内容,这里是一篇论文。

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

霍夫变换演示,图片作者

霍夫变换不仅能检测直线,还能检测圆。阅读圆形霍夫变换广义霍夫变换了解更多信息!

走向深度学习:卷积神经网络和残差神经网络

“没有人告诉一个孩子如何看,尤其是在早年。他们通过真实世界的经历和例子来学习这一点。”

—费·

“机器学习”这个短语最早是由亚瑟·塞缪尔在 1952 年提出的。然而,在 2000 年之前,神经网络的研究一直受到严重阻碍。人工神经元的最早版本是由神经生理学家沃伦·麦卡洛克和数学家沃尔特·皮茨在 1943 年发明的。它旨在描述神经元如何在我们的大脑中工作。

在 2012 年 ImageNet 大赛之后,网络公司( CNN )成为了明星。从那以后,我们开始在任何可以与之相关的领域中超过 80%的新发表的论文中看到神经网络相关的模型。还有许多其他的机器学习算法,如 k-NN 和随机森林,但在图像处理方面,CNN 的性能不如它们。

深度卷积神经网络

每当提到卷积神经网络,数据科学家首先想到的可能是 Yann LeCun,他在 1998 年发表了关于 LeNet-5 的论文。

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

LeNet-5 的架构,图片来自原文

典型地,CNN 由 4 种类型的层构成。我在我的 Alpha Go 文章中提到了 3 个,因为它们是更常见的 3 个。研究人员也可能在他们的论文中加入一些小的变化,并发明新的图层类型。这 4 层是卷积层、汇集层、有限线性层和全连接层。

1。卷积层

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

卷积层(3x3),图片作者

卷积层通常作为卷积神经网络的第一层出现。这些类型的图层将使用过滤器扫描源图层,并将总和放入目标图层。有些过滤器擅长检测边缘,有些则擅长其他任务。卷积过程可以提取 2D 图像内部的空间信息,并将其传递给下一层。关于不同种类的卷积滤波器及其在计算机视觉中的应用的更多细节可以在这里找到。

2。汇集层

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

池层(2x2 最大池),作者图片

池层遍历源层,并在有界区域内选择一个特定的值。该值通常是该区域内的最大值、最小值和平均值。将信息缩小也称为“下采样”或“二次采样”。

当计算资源有限时,与将像素直接输入多层感知器的节点相比,通过卷积层和池层预处理的网络更加资源友好。在特殊情况下,“上采样”技术也可以用来产生更多的数据。

热路层

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

热卢层,作者图片

ReLU layer 将值提供给一个 ReLU 函数,该函数只是去掉负值。ReLU 是神经网络中常用的激活函数,因为它可以降低消失梯度问题的可能性。

全连接层

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

全连接层只是一个人工神经网络,图片作者

一个完全连接的层本质上是一个多层感知器,它有时被称为“softmax”,本质上做一些被称为“加权和”的事情。我已经在我的 Alpha Go 文章中解释了更多关于多层感知器的内容,包括前馈和反向传播。

深度残差神经网络

2015 年,微软研究院的何和他的团队发表了他们的论文用于图像识别的深度残差学习。论文将残差学习应用于卷积神经网络,取得了比当时所有其他State-of-the-Art(SOTA)模型更好的性能。

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

剩余连接示例,图片来自原始论文

剩余学习的一个关键概念是“捷径连接”的使用。这涉及到在网络的各层之间添加一个连接,这样信息就可以通过跳过层来传递。在对人脑的分析中也发现了这样的结构。具有跳过权重的网络也称为高速公路网络。

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

ResNet 与其他型号的对比,图片来自原纸

该网络还在 CIFAR-10 数据集上实现了更好的性能。

今日计算机视觉:语义分割、目标检测和图像分类

“大哥看着你呢!”

— 1984,乔治·奥威尔

随着计算机视觉的进步,人工智能现在可以做许多疯狂的事情。出于对隐私侵犯的担忧,欧盟甚至考虑禁止面部识别。而其他国家,如中国,已经将面部识别嵌入他们的社会信用系统

凡事都有取舍。随着电子支付和街头摄像头的进步,我可以向你保证,上海街头的扒手比过去少多了。与洛杉矶相比,上海的犯罪活动也少得多。

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

图片分类工作流程,图片作者

当我们谈论计算机视觉时,我们脑海中浮现的可能是包围盒中的标签图像。首先通过区域提议过程由区域勾勒出对象的轮廓,然后将检测区域内的内容。有 3 个热门的研究领域:语义分割,对象检测和图像分类。

语义分割:CASENet 和 Mask R-CNN

语义分割与边界和边缘的检测高度相关。例如,CASENet 勾勒出物体的边界。

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

使用 CASENet 进行语义分割,演示来自 Youtube

Mask R-CNN 可能是一个更受欢迎的模型,以语义分割著称。网络从 R-CNN 发展到快速 R-CNN 再到更快的 R-CNN

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

带掩码的语义分割 R-CNN,来自 Youtube 的演示

对象检测:YOLOv1、YOLOv2 和 YOLOv3

“你只看一次!”

—约瑟夫·雷德蒙

由 Joseph Redmon 于 2016 年发布的 YOLOv1 已经在物体检测方面展示了比当时其他模型快得多的速度。作者将该型号逐步改进为性能更好的约洛夫 2约洛夫 3

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

YOLOv2、YOLOv3、Mask R-CNN 和 Deeplab Xception 之间的比较,演示来自 Youtube

图像分类:CNN 的图像网络现状和史诗般的失败

ImageNet 邀请世界各地的研究人员在他们的数据集上竞争,最先进的模型仍在快速迭代。也许你会定义下一个 SOTA?

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

来自论文的影像分类精度可视化,代码,2020

CNN 上还有其他有趣的事实。一组研究人员在 2019 年 ICLR 上发表了一篇论文,显示 CNN 像人类一样基于纹理而不是形状对图像进行分类。

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

神经网络根据纹理、来自原始纸张的图像做出判断

神经网络也容易受到高频干扰。最近一篇关于太极的论文显示,当图片上有波纹时,VGG-16 会把松鼠归类为金鱼。

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

VGG-16 认为有波纹的松鼠是金鱼,图片来自原文

伊恩·古德费勒很久以前就研究过针对神经网络的对抗性攻击,当我们学习生成模型时,我们会更深入地研究他。

话说到最后…

“AI 无处不在。这在未来并不是什么可怕的事情。艾和我们在一起。”

—费·

我终于按计划完成了这篇文章。这个领域有太多的东西要写,你不可能在 10 分钟的文章里写完。我希望这篇文章能引起你对其中一些的兴趣。我可能会在未来的文章中写关于手势识别和社会行为预测的内容。

CV 和 NLP 是人工智能领域的两个热门话题。如今,云人工智能平台正把大部分精力投入到这两个领域,因为它们有潜在的应用价值。我也写过一篇关于 NLP 的文章。我计划稍后写自动化机器学习、生成模型和云平台。关注我了解更多信息。

此外,我还有一篇关于计算机视觉前端框架的文章。这些框架很容易自己尝试,也许今晚你可以用它们做一些很酷的应用程序!

逐步了解数据分析

原文:https://towardsdatascience.com/understanding-data-analysis-step-by-step-48e604cb882?source=collection_archive---------9-----------------------

对数据集应用数据分析以获得关于数据的见解。

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

马库斯·斯皮斯克在 Unsplash 上的照片

在当今世界,每天都有超过 2.5 万亿字节的数据生成。成为一名数据科学工程师/数据科学家/ML 工程师或任何你可能称之为数据分析艺术的人是你应该掌握的第一件事。

什么是数据分析?

这是一个对数据进行检查、清理、转换和建模的过程,以便我们可以从数据中获取一些有用的信息,并将其用于未来的预测。

数据分析工具使用户更容易处理和操作数据,分析数据集之间的关系和相关性,它还有助于确定模式和趋势以进行解释。

在这里,我们将使用 python 来深入研究数据分析,并研究数据分析的所有重要方面。在这里,我们将使用一个汽车设计数据集,你可以在这里下载。

从导入重要的库和读取数据集开始

#importing the important libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns#reading the dataset and creating a dataframe
df = pd.DataFrame(pd.read_csv('car_design.csv'))
df.head()

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

正如我们在这里看到的,数据被加载到名为“df”的数据帧中,因此让我们从数据争论部分开始,如了解数据的维度,数据有多少行和列。

步骤 1 理解数据

# Dimention of dataset
print("Dataset is of ", df.ndim, " dimension.")# Rows and column of dataset
print("Dataset has ", df.shape[0], " rows.","\nDataset has ", df.shape[1], " columns.")#Knowing the data Types of the columns
print("Data Types :")
print(df.dtypes)

上述所有步骤将帮助我们理解数据及其属性。

步骤 2 清理数据

当我们浏览数据时,我们看到一些列包含“?”而不是被认为是数据异常的正确数据。我们需要将它替换为“NaN ”,以执行进一步的操作。

df = df.replace("?", np.nan)
df.head()

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

这里你可以看到吗?替换为 NaN

现在,我们将用平均值的列替换缺失的数据,即 NaN,此操作只能在数据类型为 float 的列上执行。因此,我们将转换所选的列,将它们转换为 float,并用平均值替换缺失的数据。

# Replacing the missing data with respective column meanfor i in ['normalized-losses', 'bore', 'stroke', 'horsepower', 'peak-rpm', 'price']:
    df[i] = df[i].fillna(round(df[i].dropna().astype('float64').mean(),2))

步骤 3-了解数据的统计摘要

现在数据已经清理完毕,没有任何异常,让我们向前看一下数据的统计描述。为此,我们将使用描述功能。描述函数计算与数据框列相关的统计数据摘要。

df.describe()

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

数据框的所有数字属性的统计摘要。

现在让我们进入下一步。

步骤 4 数据可视化

在此,我们将根据问题陈述尝试可视化不同的列,并找出不同属性之间的关系(如果有的话)。因为我们这样做是为了通用目的,所以我们将可视化我们选择的列。

# Plotting histograms of the following numerical attributes --      # "engine-size", "peak-rpm","horsepower","price"hist_col_names = ["engine-size", "peak-rpm","horsepower","price"]
for i in hist_col_names:
    df[i] = df[i].astype(float) # It changes data typeplt.figure(figsize=(15,15))
cnt=1
for i in hist_col_names:
    plt.subplot(4,2,cnt)
    sns.distplot(df[i], hist=True, color = 'darkblue', kde_kws={'linewidth': 4})
    plt.title(i)
    cnt=cnt+1
plt.tight_layout()
plt.show()

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

选定数值属性的分布图。

只要有一点统计学知识,我们就能清楚地理解这些分布图想要表达的意思。在此之后,我们还可以找到不同数字属性的相关性,并使用热图将它们可视化。

热图是数据的二维图形表示,矩阵中包含的各个值用颜色表示。

# Creating the correaltion matrix
corr = df.corr()# Plotting the correlation matrix on a heatmap
fig, ax = plt.subplots(figsize=(12,9))
sns.heatmap(corr, annot=True)
ax.set_xticklabels(ax.get_xticklabels(), rotation=45);
plt.show()

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

描述不同数值属性之间从正到负的关系的热图。

另一种真正有洞察力的数据可视化图称为箱线图,这是一种通过四分位数图形化描述数字数据组的方法。箱线图也可以有从方框延伸的线,表示上下四分位数之外的可变性。

让我们在数据集的“驱动轮”和“价格”属性之间绘制一个箱线图。这将有助于我们找出不同驱动轮汽车的价格范围。

plt.figure(figsize=(8,8))
sns.boxplot(x="drive-wheels", y="price", data=df,linewidth=1.5, palette ='Set2')

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

在这里,我们可以清楚地看到不同驱动轮类别的价格范围。

现在让我们进入最后一步,从数据中获得一些见解。为此,让我们设想我们的问题陈述为“我们需要找出一家新公司推出的不同类型汽车的价格范围?”

步骤 5:从数据中得出推论/见解。

为了解决这个问题,让我们先根据驱动轮找出汽车的平均价格。

df_group=df[['drive-wheels', 'body-style', 'price']]
drive_wheel_avg=df_group.groupby(['drive-wheels'], as_index=False).mean()
drive_wheel_avg

现在,我们将根据不同车型的车身风格显示驱动轮的平均值。

group_avg=df_group.groupby(['drive-wheels','body-style'] , as_index=False).mean()group_avg

最后一步是将上述步骤中获得的数据转换为数据透视表,以便更好地可视化、精确查看和理解。

pivot_table=group_avg.pivot(index='drive-wheels', columns='body-style')
pivot_table=pivot_table.fillna('Not Applicable')
pivot_table

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

该表根据车身风格和驱动轮清楚地描述了不同汽车的价格范围。

该表可以帮助我们根据已经上市的其他公司的数据,找到我们可以推出汽车的价格段。这里我们可以清楚地看到,这种推断只是基于有限的属性,如果我们想要得到更精确的推断,我们需要考虑更多的属性。

在本文中,我向您解释了在处理数据集时应该遵循的基本步骤。遵循这些步骤没有硬性规定,但它们有助于你获得更好的洞察力。

请在我的 github 中找到数据集和完成的 python 文件,在那里我考虑了更多的属性,你可以通过它们更好地理解。

[## 从头开始创建 Streamlit 仪表板。

Streamlit 是一个很棒的工具,可以轻松构建视觉上吸引人的仪表板。

towardsdatascience.com](/creating-streamlit-dashboard-from-scratch-59316a74fa1) [## 使用 Faker 创建数据集并将其用于熊猫概况分析

创建您自己的数据并对其执行操作。

towardsdatascience.com](/creating-dataset-using-faker-and-use-it-for-pandas-profiling-6fe26e1b9557)

在你走之前

感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 您也可以在我的*Github中查看我在这里使用的代码和数据。*

用简单的例子理解数据丰富

原文:https://towardsdatascience.com/understanding-data-enrichment-with-simple-example-12ae97bb8f04?source=collection_archive---------18-----------------------

数据丰富在您的数据质量工作中具有特殊的重要性

在主数据管理领域中,有一个低挂的数据质量成果,听起来很简单,但是会将整个 MDM 计划提升到下一个级别。我在这里使用一个*“低挂果实”*术语,因为这个概念非常简单,但可能需要一些时间来实现,这取决于您的组织需求、专业知识等等。在这个机会中,我不打算深入研究进行数据丰富的技术观点,而是试图解释如何实现数据丰富的概念和想法。

在他们关于多领域多维数据模型的非常实用的书中,马克·艾伦和道尔顿·塞尔沃将数据丰富术语阐述为通过补充缺失或不完整的数据来增强现有信息的*过程。*众所周知,许多组织,尤其是大型组织,通常都由独立且分散的信息系统组成,每个信息系统都保存着自己的数据。例如,客户数据可以用不同的格式和完整性级别在不同的应用程序中表示和存储。一个系统存储特定客户的地址信息,而另一个系统出于某种原因只存储他/她的 ID,这种情况并不少见。

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

照片由 Unsplash 上按顺序拍摄

因此,丰富信息可以通过组合一个数据源和另一个数据源来完成。此外,我们可以通过来自数据本身的信息来丰富数据,如果数据被证明在其中有一些嵌入的智能。现在让我们深入这个简单的例子,以便更好地理解。

假设您有一份需要充实的客户数据记录,因为这将是您的黄金数据。该信息表示如下:

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

原始数据

初始数据只包含姓名和 ID。看看其他数据源,看看我们是否能找到额外的属性来完善我们的黄金数据,这可能很有诱惑力。但是坚持住,不要看得太远,先检查一下你现有的数据是否有一些嵌入式智能。

一些国家的 ID 号中存储了一些数据,我们可以提取这些数据来获取信息。在这个简单的场景中,如果我们看一下我们的虚拟 ID 号,我们可以看到其中包含如下信息…

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

虚拟编号,仅用于场景目的

瞧啊。在不涉及外部数据的情况下,我们可以仅从客户的 ID 推断出该客户的 DoB

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

请注意,并非所有类型的标识符号码都具有嵌入式智能。事实上,为了防止欺诈和数据滥用,产生没有存储信息的随机标识符号码现在是一种日益增长的趋势(不久将成为最佳实践)。现在,您的工作是检查您用来识别客户的身份证或任何类型的识别码,并确定是否可以提取任何信息来丰富您的数据。

随着 DoB 问题的解决,现在我们还剩下两个柱需要充实。既然我们已经从现有数据中提取了所有可用的信息,那么现在是时候从其他数据源中寻找了。

假设现在我们有来自系统 A 另一个数据源,它提供如下信息

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

来自系统 A 的数据

一切看起来都很好,除了一个争论,这个’ M.J .卡特’是否与我们的’ Margaret Johnson Carter '相同。

在有时间解决之前,另一个数据源从系统 B 弹出,表示为

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

来自系统 B 的数据

名字看起来一样,ID 看起来极其一样……除了最后一个数字……

虽然您现在已经有了完成黄金数据表的所有必要信息,但您仍然需要头疼地确定这些“M . J Carter”和“Margaret 女士”是否代表与“Margaret Johnson Carter”相同的实体。我想强调的是,这种令人头疼的问题在任何组织中都很常见,因为信息分散在不同的系统中,每个系统都可能属于不同的部门。也有可能是打字错误和其他人为错误,使事情变得更糟。这就是主数据管理工具派上用场的地方(参见我以前的关于 MDM 的文章)

基本上,您需要对所有这些数据进行“匹配”,以确定它们是否代表同一个实体。在进行匹配时,根据相似性比较所有数据属性,并分配最终分数以确定数据是否相同。分数越高,您就越有把握数据代表的是同一个实体。要做到这一点,您可以使用数据匹配工具或发挥您的力量,做一些手动验证。

为了完成我们的场景,假设在做了一些人工验证后,我们现在有足够的信心说这三个名字是同一个人。而现在…

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

我们完成了数据丰富工作:)

从上面这个非常简单的场景中,我希望你抓住数据丰富工作的概念,并得到一些关于你可以用你的数据做什么的启发。请记住,您不需要手动完成所有这些工作,因为现代 MDM 工具都配备了数据丰富功能。有些可能足够复杂,可以连接到组织外部的数据源,以检索通常在组织内部无法获得的信息。

永远记住,丰富的数据包含更强大的信息,因此被滥用的风险更大。数据安全应该始终是我们最关心的问题。

下次见!

理解 Python 中的数据结构

原文:https://towardsdatascience.com/understanding-data-structures-in-python-86e7da6a9b39?source=collection_archive---------40-----------------------

最有用的内置数据结构概述。

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

照片由 Riho KrollUnsplash 上拍摄

ython 有很大的可能性来处理我们的数据。让我们仔细看看列表、元组/命名元组、集合和字典的功能。我不打算深入研究,例如,如何在列表中添加或删除元素。我的目标是用简单直接的方式展示每个集合的操作,举例说明它们的陈述。在每个解释的最后,将展示每个系列的主要特征。这些例子将用 Python 语言编写,但是由于重点是概念而不是应用程序,所以您可以将这些应用到您的编程语言中,这可能会以非常相似的方式工作。

实验数字电视系统

2020–06–18

元组

元组是可以按顺序存储特定数量的其他对象的对象。一旦元素被放入 tuple 中,它们就变得不可变,这意味着您将无法在运行时添加、删除或移动这些元素。反过来,元组在大多数情况下用于存储数据,因此它的主要功能是在一个地方存储不同类型的数据。元组有两种声明方式,不管是否使用括号(,它们的项之间用逗号分隔。

带括号和不带括号的元组示例。

items = ('Name', 75, 80, 90)
items = 'Name', 75, 80, 90

此外,我们可以在元组中添加函数,例如:

items = calculate((“Name”, 75, 80, 90), datetime.date(2020,01,01))

在这个例子中,我们需要括号,所以函数的第一个参数是我们的元组,第二个是数据,最后,我们关闭函数的括号,这样我们的 Python 解释器将知道函数的开始和结束位置。

主要特征:

  • 无序的
  • 不变的
  • 比列表更快

命名元组

上面我们看到了元组的使用,但在某些情况下,我们可能希望单独访问我们的一些键,让我们分析下面的例子,其中我希望使用元组来表示 RGB 中的颜色。

rgb_color = (55, 155, 255)

我们可以同意,对这个作业的解读并不完全错误。读到这里,我可以确切地理解,当访问 rgb_color [0]键时,它反过来将返回值 55。通过对变量的描述,我知道值 55 代表 RGD 红,但在大多数情况下,这可能不是显而易见的,要么是由于使用的上下文,要么是由于开发人员的经验。举例说明了使用命名元组处理这种情况的更好方法。

from collections import namedtuple

Color = namedtuple("Color", "red blue green")
color = Color(red=55, blue=155, green=255)

命名元组的声明类似于传统元组的声明,在我们的 named tuple 中,作为第一个参数,我们必须通知我们的标识符,第二个参数字符串用空格或逗号分隔。结果是一个与传递的标识符完全相同的对象。这样,我们可以通过访问它的一个属性来解包您的值,例如:cor.blue

主要特征:

  • 类似于元组
  • 让您的元组自文档化。
  • 不需要使用索引来访问元素

目录

列表是几个项目序列的概念,其中,根据需要,您需要将它们分组或按顺序放置。列表的一个特性是,如果有必要,我们可以单独访问列表的每个位置,在 Python 中,它是在两个方括号[]之间声明的,它的内部项由逗号(,)分隔。

fruits = [‘apple’, ‘banana’, ‘orange’]

除了已经举例说明的数据之外,您还可以用其他类型的数据填充您的列表,比如对象、整数、元组甚至列表的列表。根据定义,我们应该总是优先在我们的列表中存储相同类型的数据,如果你觉得有必要做这种类型的操作,也许你应该看看字典提供了什么。

主要特征:

  • 整齐的
  • 易变的
  • 接受重复元素
  • 按索引访问元素
  • 可以嵌套
  • 动态增长

设置

您可以将该集合视为列表的扩展,在您想要存储唯一值的情况下应该使用它,而列表本身并没有提供这些值。它的主要特性是存储唯一的和无序的值。在 Python 中,在某些时候,你必须意识到所有的东西都是对象,默认情况下,我们的集合只存储每个对象的相同副本。集合在初始声明时用括号()声明。

在下面的示例中,我们有一个列表,其中包含汽车型号和品牌的元组:

brand_model = [("Fiesta", " Ford"), ("Gol", "VW"), ("KA", "Ford"), ("Uno", Fiat)]
unique_brands = set()

for model, brand in brand_model:
    unique_brands.add(brand)

>>> {'Fiat', 'Ford', 'VW'}

这个结果显示了我们独特的汽车品牌,一个重要的细节是,我们的 set 并不按照插入的顺序将结果返回给我们,就像字典一样,Set 并不保证其元素的顺序。我们可以利用集合的一个很好的用途是能够看到集合中有什么或没有什么。

主要特征:

  • 无序的
  • 不允许重复项目
  • 与列表相比,访问速度更快
  • 支持数学运算(并、交、差)

字典

根据我作为开发人员的经验,字典是使用 Python 操作数据的最简单和最有效的方式,因为您的问题和数据都可以使用字典。基本上,它在键和值存储中是有意识的,所以 redis 的主要目标是存储来自键-值对的信息,例如:color = blue,其中 color 是我的键,blue 是我的值。非常类似哈希内容,其他语言的 hashmap。在 Python 中,它是在两个大括号{}之间声明的,其内部项用逗号(,)分隔。

car = {'model': 'Ka', 'brand': 'Ford', 'Year': 2012}

主要特征:

  • 无序的
  • 存储不同类型数据的能力
  • 可以嵌套
  • 动态增长

结论

展示的每个系列都有自己的特色,每个系列都必须用于特定的场合。它们的结合使用为我们处理数据提供了极大的灵活性,并使我们解决实际问题的主要目标变得更加容易。

进一步阅读。

如果你想更深入地理解或者看到不同的方法,我在 Medium 上挑选了一些深入研究这个主题的文章。好好学习。

[## Python 的集合模块——高性能容器数据类型。

Python 集合模块的快速概述。

towardsdatascience.com](/pythons-collections-module-high-performance-container-data-types-cb4187afb5fc) [## Python 基础-数据结构

Python 内置集合简介

blog.usejournal.com](https://blog.usejournal.com/python-basics-data-structures-d378d854df1b) [## 您应该始终使用的 Python 集合

Python collections 是一个被低估的库,它可以将您的编码提升到下一个级别。

medium.com](https://medium.com/swlh/python-collections-you-should-always-be-using-b579b9e59e4)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值