细胞自动机和无人驾驶汽车
自组织网络、物联网、机器学习和火车
介绍
本文以一个简单的思维实验开始:如果所有的汽车都是无人驾驶的,我们还需要红绿灯吗?
在这种情况下,我指的是专门的无人驾驶汽车,而不是仍然需要人类驾驶的自动驾驶汽车。也许是语义上的差异,但在本文的其余部分,它们将被称为无人驾驶汽车。
很明显,从每个主要技术和汽车制造商投入的多年努力和数十亿美元的 R&D 来看,目标是最终将人类从驾驶等式中移除。所以,当我们最终到达那里时,一些令人困惑的问题出现了:
- 一个 100%无人驾驶汽车的系统本质上不会是下一代火车(就像很好的机车类型的火车)网络吗?尽管现在铁轨是公路,火车是实时联网的汽车。
- 机器学习和深度神经网络等复杂的过渡技术将会发生什么,这些技术被训练成在人类水平上驾驶(坏主意!)与实际的人类驾驶进行交互(即,在仍然允许人类驾驶员的“过渡期”期间)?一旦所有汽车都实现无人驾驶和联网,我们就不需要所有这些了——我们只需要确保汽车保持在轨道上,不会相互碰撞。那我们在做什么?
火车,第一辆无人驾驶汽车
让我们坐上时光机,回到过去,想象一下,如果轨道交通取代了免费的汽车,某种轨道技术形成了我们现在所知的当地街道,以及后来的城镇和城市。这很容易发生——迪斯尼设想未来的交通是单轨铁路。它可能不是真正的轨道,也可能是线控技术。我们所有的街道都可能是用简单的线路“铺设”的,或者街道涂料可能具有某种电磁特性。我们将拥有自动驾驶汽车专家声称的所有好处——减少事故,更好地利用驾驶员(现在是乘客)的时间,等等。
但是,唉,这并没有发生!现在我们有失控的青少年开着 100 英里的时速,一边喝着啤酒一边给他们的朋友发短信。因此,让我们回到时间机器中,随着汽车向 100%无人驾驶(完全没有人类驾驶)的发展,向前迈进,想象一下实现这一目标将会使用或需要的技术(或许更有趣的是,可能不会使用的技术)。
如果火车挂钩,即防止火车车厢相互碰撞并保持最佳间距的连接器,被某种自组织算法取代,该算法在每辆无人驾驶汽车内部和之间运行,会怎么样?每辆车可以与附近的所有其他车进行通信,他们可以就如何最佳地前进达成有组织的共识。例如,每一个都可以用细胞自动机启发的算法来操作,这将在后面描述。今天,我们已经有了能“感知”何时与另一辆车靠得太近,甚至能自动平行泊车的汽车。这些可以被视为这些算法的早期版本,为火车挂钩提供了虚拟的替代品。
接下来,为了增强这些“计算机感官”(接下来将详细描述),我们看到了物联网(IoT)的最终成果。街道铺设了可以感知的技术,以及与交通有关的一切(人、障碍物等)。)还被灌输了一种可以感知的物联网设备。
电脑感官
电脑看东西不像人类。这是当今 AI 最大的错误。我们花了这么多时间让计算机像人类一样行动——听语音、看面孔——却没有意识到这些不是计算机的感官,这难道不奇怪吗?不要太深入创或矩阵的领域,但计算机并不像我们一样有自然的感觉。
例如,当 5G 无处不在时,一组十几辆接近十字路口的无人驾驶汽车可以立即相互联网,并确定它们如何高效地通过十字路口。12 个人的小组不能实时地将彼此的思想联网。人类没有 WiFi“感应”,电脑有。
因此,在这个简单的例子中,自然的计算机“感觉”——即“看到”网络上的其他计算机并立即交换算法数据的能力——在无人驾驶汽车场景中比经过训练识别物体的神经网络更有用。我们如此专注于用具有人类感官的机器来取代人类,以至于我们没有意识到机器也有自己优越得多但不同的感官。
这在无人驾驶汽车的世界中意味着,如果要让无人驾驶汽车“看到”,一切都必须有一个数字表示。不是教神经网络识别一个正在过马路的人,那个人必须有一些设备,让无人驾驶汽车使用他们的计算机感官看到他们。
听起来很疯狂?嗯,狗身上已经植入了芯片,几乎地球上每个人的口袋里(或手腕上)都有一部智能手机。我们差不多已经到了。可穿戴设备,可植入设备,它们都是我们的未来。我们正在做的是创建我们自己的数字表示,以便计算机可以看到我们。
让我们从蚂蚁开始
你曾经从上面实时观察过交通状况吗?也许是从当地新闻拍摄的交通直升机上,或者是当你即将着陆时从飞机上。每辆小车看起来很像一只蚂蚁,整个系统看起来很像你在自然界宏观层面上看到的东西。你不会注意到每一辆单独的车,或者蚂蚁,但作为一个整体,它们以流体动力学的方式运动。事实上,也许是宇宙中最聪明的生物驾驶着一辆汽车,从上面看完全看不出来,它看起来只是一个在溪流中流动的水分子。一个完全愚蠢的分子。(当然,有些司机近距离看起来也是这样)。
这里有许多讽刺之处:
- 首先,今天的机器学习无法精确地复制蚂蚁大脑——然而我们正在开始复制人脑来驾驶我们的汽车?我们先把蚂蚁模拟做好怎么样?
- 蚂蚁的感官与人类不同。也许我们不能模拟蚂蚁,因为我们没有模拟它们的感官。
- 为什么我们要花费如此多的时间和精力来重新创造一个驾驶一辆汽车的智能生物,而我们可以很容易地从上面重现交通流的宏观特征,并且多年来一直能够用传统算法做到这一点?
- 顺便问一下,当人类在驾驶方面表现糟糕时,我们为什么要训练神经网络像人类一样驾驶?
元胞自动机
元胞自动机或元胞自动机(CA)的完整历史超出了本文的范围,但将讨论其过去的一些简要内容。此外,为支持本文而构建的计算机模拟没有使用传统的 CA 规则或网格,而是借用了 CA 的基本概念。
CA 的基本思想是创建一个网格(传统上是 1 或 2 维),其中每个单元可以是“开”或“关”。每个单元使用一个规则来确定它应该打开还是关闭,例如“当我有 3 个以上的邻居单元打开时,我关闭,否则我打开”。CA 算法在迭代(即世代)中运行,并且单元根据规则打开和关闭。
当人类查看这些算法的输出时,我们的大脑会看到有机行为——它看起来像自然,像从直升机上看到的交通视图。我们知道这实际上不是有机行为,这是计算机模拟,但我们的大脑认为它是有机的。最常提到的 CA 的例子是康威的“生命的游戏”,在这篇维基百科文章中有充分的描述和演示。快速浏览一下这个例子,你会发现它的输出是有机的。尽管控制细胞生命的规则(无论它是开着还是关着)极其简单,但由此产生的行为却极其复杂,几乎不可能用其他方式来编码。
史蒂夫·沃尔夫勒姆在 2002 年写了一本关于这个主题的大部头书,书名大胆地定为“一种新的科学”。在这本 1197 页的书中,Wolfram 分析了大量的规则以及它们经过多次迭代后的结果。他提出并实现了一门新的科学,该科学关注于利用简单规则的 CA 系统的涌现行为。一门新的科学,研究从简单中脱颖而出的复杂事物。
下一个(或真正的)人工智能——人工生命
人工智能必须超越简单的模仿人类。有了足够的向量匹配,这实际上是所有神经网络,我们将能够识别地球上的每一张脸。这不是智能——因为一个特定的人不可能认出地球上的每一张脸。这只是大规模回归算法在起作用。
在欧文·薛定谔的名著《什么是生命》中,他讨论了为什么事物是“大”的,但却是由像原子这样非常微小的其他东西构成的。更重要的是,为什么微观层面的随机性(例如布朗运动)会产生看起来相对稳定的“大”东西。(剧透一下,事情所以大,要从微观的不稳定创造宏观的稳定。)
我们的大脑是 1000 亿个神经元的集合,每个神经元的行为更像是 CA 算法,而不是机器学习算法。不知何故,大脑设法将这些大量的微小元素整合成一个连贯的整体——一组产生“大”智能的小东西。
人们还可以认为,机器学习算法类似于 CA,因为它们是在模拟的“神经元”级别与模拟的层一起定义的,例如在反向误差传播算法(或其他梯度下降算法)中。然而,有一个总体控制算法通常不是并行的,实际上专注于简单的向量匹配,而不是利用意外的突发行为。
人工生命将通过复制从上面看起来有机的东西来实现。通过这种方式,康威的“生命游戏”比神经网络更具生活气息。CA 也是大规模并行算法,从计算的角度来看比机器学习简单得多。人工生命将把人工智能放在适当的位置——即在向 100%无人驾驶汽车过渡的时期,更准确地将人类的感官转化为计算机的感官。
代码示例
本文附带了一个简单的软件模拟(从 GitHub 下载)来对本文提出的概念进行具体化。本文开头显示了程序输出的一个截屏。
模拟的目标很简单:
- 模拟一个在街道和十字路口网格中向各个方向行驶的汽车系统。
- 给每辆车一个简单的规则来管理它相对于其他车的运动。
- 汽车可以相互交谈,但没有一个支配性的算法来控制它们的运动。
- 确保没有汽车相撞。
- 确保没有任何东西被“卡住”。
简而言之,这个模拟是文章开头提出的原始问题的结果:“如果所有的汽车都是无人驾驶的,我们还需要红绿灯吗”?模拟演示的答案显然是否定的
当项目运行时,点击“开始”按钮,汽车开始出现在网格的边缘。随着时间的推移,越来越多的汽车出现,所有的汽车都必须相互协商,以避免撞车,尤其是在十字路口。看了几秒钟后,你会看到汽车行为的有机本质,就像你看“生命的游戏”一样。
更有趣的是,当这些车的各种规则被尝试时,事情被卡住了,很多。很容易出现这样一种情况,四辆车同时来到一个十字路口,因为他们的规则造成了僵局而被卡住。事实上源代码中的“Car1”就是这样一辆简单的汽车。它的规则是“如果在我的方向下一个细胞是明确的,采取它”。尽管这条规则很简单,但在路上车少的情况下,它确实相对有效。
但是“Car4”按照预期工作(Car2 和 Car3 是不值得包括在内的失败尝试)。汽车不会卡住,模型永远运行,显示了其有机的突现行为的一面。它的规则稍微复杂一些,但关键是创造了礼貌的概念——偶尔(随机地),一辆可以通过十字路口的汽车决定等待,并慷慨地让其他人通过。
“礼貌”因素是一堂算法人生课!
摘要
在观看本文提供的模拟时,有趣的是,将简单的规则应用于作为一个群体一起工作的独立汽车,可以创造出人工生命,可以与当今最复杂的算法和数十亿美元的无人驾驶汽车研究相媲美——但仍然不起作用。这值得重复,从上面看,一个简单的模型只用了几天时间就组装好了,已经可以媲美最复杂的自动驾驶汽车“人工智能”。
可能很难想象我们将如何为所有无人驾驶汽车的未来“铺设轨道”,以及无人驾驶汽车必须“看到”的所有实体如何必须有一些与计算机感官兼容的数字表示。但是有了物联网,智能手机,手表,可穿戴设备等。我们已经走上了这样的道路。至少,在可预见的未来,过渡时期的自动驾驶汽车将需要一种冗余机制(目前是一名人类司机,当神经网络转向一边时,他会接管控制权)。也许我们现在应该铺设一些轨道,为 100%无人驾驶汽车或火车的未来提供这样的冗余。
代码详细信息:
该代码是一个 React.js 项目,因为它使在 Web 浏览器中更新用户界面变得简单,所以可以将重点放在算法上,而不是编写用户界面代码。要安装和使用,只需安装 Node.js,git 拉出 auto-car 存储库,然后运行“npm install ”,然后从 auto-car 项目目录中的命令提示符下运行“npm start”。
- /src:包含模板 React.js 支架。
- /src/components:包含渲染网格和汽车的用户界面控件(JSX)。
- /src/modules/autostimdel . js:容纳实际的网格。next()方法运行下一代。
- /src/modules/cars:该目录包含 car 对象(及其基类)。请注意,Car4 是最有效的,因为它具有一些利他主义的特征。Car1 制造的汽车在快速添加汽车时会很快被卡住,但是如果汽车添加得很慢,它仍然可以正常工作。
参考文献/参考书目:
- 康威,J.H. (1970 年)。*生命的游戏。*取自https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
- Schrodinger,e .,& Penrose,R. (1992)。什么是生活?:《有心灵、有物质、有自传的素描》 (Canto)。剑桥:剑桥大学出版社。doi:10.1017/CBO9781139644129
- 沃尔夫拉姆,斯蒂芬。(2002).一种新的科学。Wolfram Research。伊利诺伊州香槟。
- 孔宪娟。(2007).基于元胞自动机的交通流建模与特征分析研究。北京交通大学,2007。
更新:
我增加这一部分是为了捕捉相关的新闻文章或其他与此处讨论的主题相关和/或支持此处讨论的主题的更新,以使本文更像一份“活的”文件。
- 2019 年 4 月 22 日:我刚收到一篇关于“V2X”的文章。(参见https://en.wikipedia.org/wiki/Vehicle-to-everything)。我真希望我第一次写这篇文章时就遇到了这个问题。这项技术与我对计算机如何看起来像计算机,而不像人类,以及所有东西必须如何连接(即使是行人和骑自行车的人)的想法完全吻合。知道其他人也不那么疯狂总是好的,或者也许就像!
- 2019 年 1 月 5 日:《华尔街日报》一篇题为*“杂货机器人来了”*的文章出现在今天的问题中,讨论了正在测试的自动驾驶汽车运送杂货。两个关键的报价是“除非城市为自动驾驶货车创造特殊的车道,否则它们可能会成为行人的麻烦”。特殊车道?听起来很像“跟踪”不是吗?此外,“几乎所有这些机器人都需要这样或那样的看护人”。这是文章。
细胞核图像分割项目
2018 年 数据科学碗 Kaggle 竞赛引起了我的注意,因为它有可能对生物技术行业产生深远的实际影响。这篇文章涵盖了我的全部经历,而我工作的详细总结可以在我的 Github 上找到。
挑战:
给定在不同环境条件下拍摄的多种类型细胞核的显微镜图像,建立一个可以检测细胞核的机器学习模型。
3 raw microscope images of differentiating cellular nuclei from the training set. Note that the samples have most likely undergone some type of fluorescence filtering to distinguish the nuclei from potential background interference.
动机:
这个挑战的目标是为量化生物系统的一个方面的能力建立一个基础。具体而言,通过具有能够在显微镜图像的混乱中分割出细胞核的模型,可以应用当前可用的软件来计数检测到的细胞核的数量。知道了生物样本中的细胞核数量,科学家就可以量化他们的观察结果,而不是“瞎猜”。
例如,在药物发现研究领域,将测试药物应用于一批细胞后,该模型将能够报告细胞计数是否因药物而增加或减少。此外,执行相同任务的传统软件方法能力有限,可能需要几天到一周才能完成。通过减少这项任务的时间,我只能想象相关研究的成本会降低,发现有益药物的机会会更快到来。
来自挑战赛组织者的这段 视频 详细阐述了这一动机。
型号:
这个项目的挑战是图像分割问题。有许多卷积神经网络(CNN)架构,每一个都适合于特定的任务。然而对于生物医学应用来说, U-Net 架构 已经被证明是相当成功的。因此,我根据这个架构建立了我的模型。我的目标是利用 U-Net CNN 从图像中的各种物体中分割出细胞核。
U-Net CNN Architecture. Note the “U” shape.
训练数据由 670 幅原始显微镜图像组成。此外,每个原始图像具有其各自的二进制掩模,即单独的图像,使得白色像素指定细胞核存在的区域,而黑色像素指定细胞核不存在的区域。比赛的组织者手工给二元面具贴上了标签。我们需要这些二进制掩码,以便模型在训练阶段有一个参考来知道它是否正确地分割了细胞核。
Respective binary masks of the 3 raw microscope images depicted earlier. White pixels signify present nuclei. Black pixels signify absence of nuclei.
然后我用 600 张图片训练这个模型,留出 70 张作为测试集。
结果:
这里是 U-Net 架构的 Python 代码 。在训练完模型后,我在测试集中的 70 张图片上对它进行了测试。对于每个测试图像,模型返回一个预测的二进制图像。
我们通过在预测结果上叠加原始图像的二值掩码来评估模型的性能。由此,我们可以看到模型预测正确和不正确的区域。
From Left to Right: Original Image, Original’s Binary Mask, Model’s Prediction, Overlay of Original + Prediction Masks
上面叠加图像中的颜色如下:
- 黄色:真阳性
- 黑色:真阴性
- 绿色:假阳性(错误)
- 红色:假阴性(错误)
为了量化模型的性能,我使用了 *Jaccard 距离(也称为联合上的交集)*度量。这个 Jaccard 距离值是通过获得正确预测细胞核(真阳性)的区域面积,并将该值除以假阴性、假阳性和真阳性面积的总和来计算的。
Jaccard Distance = True Positive / (True Positive + False Negative + False Positive)
因此,这个度量值的范围在 0 到 1 之间。满分为 1 意味着该模型能够检测细胞核的所有区域,而没有任何假阴性和假阳性。
对于 70 张测试图像,我的平均 Jaccard 距离等于 0.75 。这意味着平均而言,该模型能够正确地检测所有细胞核的相当大的一部分。
结论:
结果表明,U-Net 结构在分割细胞核区域方面是令人满意的。虽然不是 100%最佳,但结果足以满足生物学家的工作和需求。
该模型始终捕捉到大块的细胞核,对于生物学家来说,任何误差区域都无关紧要。对于分割细胞核的重要部分,您可以应用其他软件来计数它们的数量或计算它们的大小。这将使生物学家能够进行细胞计数,但与传统方法相比,时间要短得多。著名的 Python 库 OpenCV 具有对象检测功能,可以用来实现这一点。
然而,在原子核重叠的情况下,仍然存在一个共同的挑战。该模型如何区分两个或多个重叠的原子核与单个原子核?
我对这个问题的初步建议解决方法是测量一种细胞的平均细胞核大小(在这种情况下是局部区域,因为图像描绘了细胞核的 2D 表示)。然后,在模型返回相同类型细胞核的二进制图像之后,在合理的误差量内,识别面积大于平均细胞核尺寸的相连白色像素区域。如果这样一个区域超过一个任意的阈值,比如平均值的 1.5 倍,那么将这个区域计为 2 个细胞核。我再说一遍,这是一个粗略的建议,它只适用于单一类型的原子核,因为不同类型的原子核大小不同。对这一挑战的进一步探索留待今后的工作去做。
总的来说,这次 Kaggle 比赛的目标是实现一个可以分割细胞核的机器学习模型,我说我的努力相当令人满意。
如果这项任务可以通过解决上述问题得到进一步改进,那么我看到了这样一个有能力的模型可以作为一个软件产品为学术界和工业界的生物学研究人员商业化的潜力。
对象检测评论中心网关键点三元组
CenterNet 的论文是 CornerNet 的后续。CornerNet 使用一对角点来克服使用基于锚的方法的缺点。然而,当检测物体的边界时,角网的性能仍然受到限制,因为它参考物体的全局信息的能力较弱。CenterNet 论文的作者分析了 CornerNet 的性能。他们发现,由于不正确的边界框的比例,在 MS-COCO 验证集上 CornerNet 的错误发现率很高(特别是在小对象上)。
Diagram of the CenterNet
CenterNet 试图克服 CornerNet 中遇到的限制。顾名思义,该网络使用附加信息(中心化信息)来感知每个建议区域内的视觉模式。现在,它不再使用两个角信息,而是使用三元组来定位对象。该工作指出,如果预测的边界框具有与地面实况框的高 IoU,则在其中心区域的中心关键点被预测为相同类别的概率高,反之亦然。在推断过程中,给定角点作为提议,网络通过检查是否有相同类别的中心关键点落在其中心区域内来验证角提议是否确实是对象。对象中心化的额外使用使网络保持为单阶段检测器,但继承了 RoI 轮询的功能,就像在两阶段检测器中使用的一样。
中心网络图显示了检测中心热图的附加分支。预测角点的分支的工作方式与 CornerNet 论文中描述的方式类似。CornerNet 有两个输出通道,分别用于预测对象的左上角和右下角。它还预测嵌入和一组偏移,学习将热图中的角重新映射到输入图像。
中心池
提出了一种新的池化方法来捕捉更丰富、更易识别的视觉模式。这种方法是必需的,因为对象的中心点不一定传达非常容易识别的视觉模式。上图显示了如何执行中心池。给定主干层的特征图,我们确定特征图中的像素是否是中心关键点。特征图中的像素本身并不包含足够的物体中心信息。因此,水平和垂直方向的最大值被找到并加在一起。通过这样做,作者声称可以更好地检测中心关键点。
级联角池
在 CornerNet 论文中,提出了角池来捕获对象的角点中的局部外观特征。与中心池在水平和垂直方向都取最大值不同,角池只在边界方向取最大值。
a) center pooling taking max values in both horizontal and vertical directions b) corner pooling taking max values in boundary directions c) cascade corner pooling taking max values in both boundary directions and internal directions of objects
然而,仅在边界方向上取最大值使得角点的检测对边缘敏感。为了解决这个问题,提出了级联角池。该方法的不同之处在于,它不是仅在边界方向上取最大值,而是首先沿着边界寻找边界最大值,然后沿着边界最大值的位置向内寻找内部最大值,最后将两个最大值相加。
a) center pooling module and b) the cascade top corner pooling module
通过组合不同方向的拐角汇集,可以容易地实现中心汇集和级联拐角汇集。上图 a)显示了中心汇集模块的结构,b)显示了级联顶角汇集模块的结构。与 CornerNet 中的顶角池相比,在顶角池之前增加了左角池。
结果
上表显示了 CenterNet 在 MS-COCO 数据集上的性能。结果表明,CenterNet 加强了 CornerNet 的弱点,并且优于大多数一阶段方法。
参考
[## 角网:将对象检测为成对的关键点
我们提出了 CornerNet,一种新的对象检测方法,其中我们将对象包围盒检测为一对关键点…
arxiv.org](https://arxiv.org/abs/1808.01244) [## CenterNet:用于对象检测的关键点三元组
在对象检测中,基于关键点的方法经常遭受大量不正确的对象包围盒,可以说…
arxiv.org](https://arxiv.org/abs/1904.08189)
中心极限和大数
很好奇中心极限定理和大数定律是如何工作和相互联系的?来和我一起看看吧!
如果你学习一些概率论和统计学,你会发现两个突出的定理:
- CLT ,是中心极限定理的简称
- LLN ,是大数定律的简称
因为它们似乎在这个领域非常重要,所以我想确保我理解了它们的实质。我相信,阅读关于他们的各种文章让我有了这种感觉,但同时这样做也有点令人困惑,因为在他们的陈述所基于的概念中有许多微妙的细节。此外,它们实际上不仅仅是两个不同的定理,而是每一个都有几个版本。
为了让我理解它们,并最终将它们的精髓留在我的长期记忆中,我运用了三种技巧:
- 将它们的种类减少到最简单和实际上最相关的情况
- 通过利用对最简单情况的限制,找到两者的最大共性和明显差异的表示
- 写这篇关于它的文章;-)
Bell curves arise from frequencies of sums of random numbers
首先,让我用简单的术语给你这些定理的松散和非正式的陈述。
大致说来,最简单版本的 CLT 告诉我们这一点:
进行相同但独立的实验,每个实验产生一个随机数,并将所有这些数相加。如果重复这个过程得出一个随机数的和,得到的和的频率将近似遵循正态分布(即高斯钟形曲线)。每次实验的数字加起来越多(实验越多),近似值就越好。
同样,LLN 最简单的版本声明:
进行相同但独立的实验,每个实验产生一个随机数,并对所有这些数进行平均。你做的实验越多,平均值就越有可能接近(实验的)预期值。
尽管很简单,让我们看看用 Python 模拟的一个例子的图表结果:我们投掷一个普通骰子 100 次,然后把所有的数字加起来。然后我们重复这个过程 10.000 次。对于 CLT ,我们在分布图中记录不同结果总和的相对频率,并将曲率与正态分布的密度函数图进行比较。对于 LLN ,我们计算增长总和的平均值,最后将这些平均值与预期值 3.5 进行比较。
Left Plot: Distribution of Sums (blue) approximating the theoretical distribution of the limiting case (red) — Right Plot: Averages (blue) approximating the Expected Value 3.5 (red) — Find the code at https://gist.github.com/BigNerd/04aef94af57f72d4d94f13be3f7fde70
在另一个模拟中,我们想看看重复实验的次数和每次实验的随机数总和的变化如何影响 CLT 陈述的结果。作为可视化,我们以标准化的方式(平均值为 0,标准偏差为 1)绘制结果分布图,以便于比较,并且每隔一个条形使用绿色而不是蓝色,以便更好地查看它们的宽度:
Summing more numbers yields finer resolution along the x-axis, repeating the experiment more often gives better accordance with the red Gaussian curve along the y-axis — Find the code at https://gist.github.com/BigNerd/63ad5e3e85e0b676b0db61efddedf839
如果你对数学方程感兴趣,让我们现在转向定理的形式表示,以便更精确地理解它们的主张和两者之间的关系。
中心极限定理
让
是独立同分布的随机变量,具有期望值*、有限方差***【σ***。然后*
收敛于分布中的标准正态分布。分布收敛意味着随机变量的累积分布函数(CDF)向一个极限值收敛,在这种情况下,随着 n 变大,它们向标准正态分布的 CDFφ收敛:
这就是所谓的林德伯格/李维版的 CLT。
大数定律
再说一遍,让
是具有期望值 μ 和有限方差 σ 的独立同分布随机变量。然后
或者用不同的方式书写
它变成了
这就是众所周知的切比雪夫版本的弱 大数定律(据说还有其他版本也是如此)。第一个极限方程更适合与 CLT 进行比较,后者更适合捕捉用平均值逼近期望值的直觉。
类似
通过模式匹配可以看出 CLT 的极限项
以及上述 LLN 的极限项的第一个变型,
它们确实非常相似(不同之处是蓝色)。
两者都陈述了在围绕 0 的任意边界框内获得其表达式值的概率,即*-ϵ, ϵ [** 。此外,两者都计算相同随机变量的相同和,两者都需要通过从和中减去增加的期望值来居中,并且两者都需要通过增加的因子来收缩,以使收敛在技术上可行。*
差异
所比较的两个极限项的区别显然是分母的顺序(**√n*vs .n)以及右边的结果极限:【1−2φ(−ϵ】*vs .1。因此,基本上,两者都处理相同的过程,即随着 n 变大,聚合数变得越来越接近零均值的正态分布。但是,由于我们更积极地缩小了 LLN 中的值,它们的方差趋近于零,而不是保持不变,这就将所有概率渐近地浓缩在期望值上。
通过对差异应用以下基本规则
我们可以证明这是这样的:
最后,从另一个模拟中,我们得到了方差减少的可视化,因为在由 LLN 描述的平均过程中变大:**
Averaging more numbers per experiment reduces the variance of the averages around the true mean — Find the code at https://gist.github.com/BigNerd/ad880941bbe6987e6621cf99e3b2af78
结果
当将两个定理限制在一个特殊但重要的情况下,即具有有限期望和方差的独立同分布随机变量,并进一步将比较限制在弱 LLN 时,我们可以发现相似之处和不同之处,这有助于加深我们对两者的理解。
柴时代数据科学展公告
重启《机器学习英雄访谈》并收集最佳建议
在过去的几个月里,我非常幸运地采访了一些顶尖的 Kagglers,研究者和实践者。这些采访以博客的形式发布,每个星期,所有的 ML 英雄都很友好地分享许多给初学者的令人惊叹的话,分享他们进入这个领域的旅程。
在本帖中,我非常激动地宣布柴时代数据科学:
柴时间数据科学是机器学习访谈的重启,我在过去的 3 个月里一直致力于这个项目,我非常高兴地分享,第一集将于 7 月 21 日周日发布,每周日和周四发布。
我稍后会谈到这个节目,但首先我想分享一下之前 25 次采访中的最佳建议:
请注意,这将是一个非常精简的建议,可能有点缺乏上下文。我建议你也看看所有的采访,以获得更详细、更丰富的指导
采访 DL 从业者:Dominic Monn
不管是在商业还是机器学习领域,都不要害怕尽可能早地暴露自己的名字,弄脏自己的手。快速出货,获得实习机会,下定决心,剩下的事情自然会到来。
不要放弃,数据科学是一个多学科领域,很难在每个方面都做得很好。一开始选择一个专业,把全部精力放在上面。例如,我为计算机视觉选择了深度学习,而不是时间序列或 NLP。不要像我 2 年前开始时那样被人工智能炒作所迷惑,没有人工智能(或 AGI,随你怎么说),如果你选择了计算机视觉道路,那么你就成为了计算机视觉专家,对于 NLP 你就成为了 NLP 专家。深度学习只帮助解决大图的一部分,它不是大图本身,只是添加到你的工具带上的一个工具。作为一名自由职业者或“专家”(随你怎么称呼),你将被要求做更多的事情,而不仅仅是在大部分时间里玩深度学习模型。了解数据准备、软件工程技能、一些 devops 和 co,基本上是在生产中创建和交付深度学习项目的整个堆栈,而不仅仅是有趣的部分。但最重要的是,学会学习和适应,关注最新趋势,并始终跟上数据科学领域的发展。
采访 Kaggle Kernels 专家:aa kash Nain:
有时,看到大量的研究正在进行,你也会感到沮丧。如果你有这种感觉,没关系。只有两件事我们应该永远记住:
你的成功不依赖他人,反之亦然。
即使是最基本的问题,也不要害羞/害怕去问。如果你不问,你就是阻碍你进步的人。
每次比赛结束后,阅读并撰写顶级团队的评论。如果你参加比赛会更好,因为你会从报道中得到更多,但是阅读所有报道是有用的。那是你在 Kaggle 上学习最多的时候。
采访卡格尔大赛特级大师:卡扎诺娃(排名第三):马里奥斯·米凯利迪斯博士
理解问题和 度量 我们都在考——这是关键。
创建一个可靠的交叉验证流程,最好类似于排行榜或测试集,因为这将允许我探索许多不同的算法和方法,知道它们可能产生的影响。
了解不同算法族的重要性,看何时何地强度最大化(是线性还是非线性类型的问题?)
在给定的问题上尝试许多不同的方法/技术,并从算法选择、超参数优化、特征工程、缺失值处理等所有可能的角度抓住它——我将所有这些元素视为最终解决方案的超参数。
深度学习与 NLP 研究员访谈:Sebastian Ruder
当我开始为自己写博客以更好地理解某个特定话题时,我有过写博客的最好经历。如果你发现自己不得不投入大量的工作来建立直觉或做大量的研究来掌握一个主题,考虑写一篇关于它的帖子,这样你就可以在未来加快其他人的学习。在研究论文中,通常没有足够的空间来恰当地描述一部作品,突出动机和直觉等。博客文章是让技术内容更容易理解和接近的好方法。
博客的伟大之处在于它不需要完美。你可以用它来提高你的沟通技巧,并获得关于你的想法和你可能错过的事情的反馈。
深度学习研究员、GANfather:Ian good fellow 博士 访谈
从真正学好基础知识开始:编程、调试、线性代数、概率。大多数先进的研究项目要求你在基础方面非常优秀,而不是要求你知道一些非常先进的东西。例如,今天我正在调试一个阻止我运行我的一个实验的内存泄漏,并且我正在加速一个软件库的单元测试,以便我们可以更快地尝试更多的研究想法。当我还是本科生和早期博士生时,我经常向吴恩达寻求建议,他总是告诉我要努力彻底掌握这些基础知识。我认为那真的很无聊,并一直希望他会告诉我学习超实数或类似的东西,但现在几年过去了,我认为这个建议绝对是正确的。
采访 OpenAI 研究员:Christine McLeavey Payne
就细节而言——我最喜欢的一条建议来自 FastAI 的杰瑞米·霍华德。他告诉我要专注于做一个真正伟大的项目,展示我的技能。他说,很多人在 github 上有很多有趣但尚未完成的项目,最好有一个真正完善的项目。
我要补充的另一件事是,当我把深度学习教给别人时,我学到了最多。我成了吴恩达 Coursera 课程的导师,试图回答其他学生的问题推动我在更深层次上理解这些材料。每当你学习一个新的话题时,试着向别人解释一下(这也是为工作面试做好准备!).
采访最年轻的卡格尔特级大师:米克尔·波贝尔-伊里扎(阿诺卡斯)
如果你刚刚开始,看看操场上的比赛或者过去几年的比赛是很有用的。Kaggle 内核可能是最好的学习资源,因为人们分享了大量的分析和所有比赛的解决方案。最重要的只是自己去实验,努力提高分数!
深度学习研究员、OpenMined 负责人安德鲁·特拉斯克 访谈
进入深度学习社区的秘诀是高质量的博客。阅读关于同一主题的 5 篇不同的博客文章,然后尝试综合你自己的观点。也不要只是写一些好的东西——花 3 到 4 天的时间写一篇文章,尽量使它简短(但完整)。重写多次。当你一遍又一遍地写,思考你想教的主题时,你会逐渐理解它。此外,其他人也会理解它(他们会理解你理解它,这有助于你找到工作)。大多数人希望有人在整个过程中牵着他们的手,但最好的学习方法是写一篇牵着别人的手的博客,一步一步地(用玩具代码示例!).还有,做代码示例的时候,不要写一些面向对象的大乱七八糟的东西。越少越好。把它写成剧本。只使用 numpy。教授每行的功能。冲洗并重复。当你感觉足够舒服的时候,你就可以用最近发表的论文来做这件事了——这是你真正知道你在进步的时候!
我认为你不应该把你的梦想和外在的身份标志联系在一起,比如为一家特定的大公司工作,或者赚一笔特定的钱,或者获得一个特定的职位。弄清楚你在生活中看重什么,然后忠于你的价值观。你永远不会后悔任何一个决定。
专访 PyImageSearch 作者、计算机视觉从业者:Adrian Rosebrock 博士
开始写任何东西的最糟糕的方式之一,不管是不是技术性的,是打开一个新文档,然后期待你会有文字涌出,神奇地填满页面——这很少会发生,而且通常会导致沮丧和失败。
相反,我建议先列出大纲。我个人用要点概括。
先从你的标题开始——你打算写些什么?按什么顺序?
从那里返回并开始填充子标题。你需要在每一部分涵盖什么?
最后,我返回并包含每个部分的详细信息。有时我甚至用完整的句子来写,但那是个人的选择。
我总是给自己留便条,比如“在这里插入一张图片”或者“some_script.py 的 X-Y 行到这里”。我尽量让自己专注于实际的写作过程。实际的图像和代码可以在排版过程中插入。
数据科学家 Kaggle 大师访谈:Bojan Tunguz 博士
不要害怕失败,试着从错误中学习。阅读论坛中的讨论,看看最好的内核,并尝试对它们进行改进。
专访 fast.ai 深度学习研究员:Sylvain Gugger
这并不是说这个理论没有用,它将是帮助初学者打造直觉的关键部分,但是在解释背后的东西之前,从训练一个实际的模型并部署它开始是很有意义的。
专访 Salesforce 首席科学家:Richard Socher 博士
区分无根据的恐惧和实际的威胁。人工智能偏见是一种迫在眉睫的恐惧,需要得到解决,而周二的场景是一种危险的分心。人们需要开始密切关注,以确保人工智能训练的数据集是多样化的,没有偏见,并且建立这些系统的团队也代表了一系列多样化的观点。
采访 kaggle 的数据科学家:Rachael Tatman 博士
我的普遍建议是不要获得博士学位。我前阵子甚至写了一篇关于此事的博文。这个博客是专门关于语言学的,但大部分也适用于机器学习。我认为,当你寻找数据科学工作时,拥有博士学位可能是一个优势,但除非你真的想 1)做研究或 2)成为教授,否则获得博士学位真的没有任何好处。你不能更快地获得博士学位。
我认为 Kaggle 或其他实践经验会让你更快地找到工作。不过,我可能不会建议只做卡格尔比赛。通过这种方式,你会学到很多关于算法的知识,但是你不会得到像清理数据或设计指标这样的实践。这也是我建议人们也做自己的项目的部分原因。这展示了你提出有趣问题、获取和注释数据、清理数据以及思考用户需求的能力。
深度学习自由顾问、区块链开发者访谈:Mamy andré-Ratsimbazafy
我认为大部分招聘人员和公司对候选人的评估还不够成熟。许多人仍在组建自己的团队,没有内部专业知识来寻找招聘能力的外部迹象。我更关心的是经验要求。深度学习的兴起是在 2012 年有了 AlexNet。除了美国,我猜想许多专注于数据科学的硕士是在 2014 年左右在大学里产生的,因此大多数拥有实际数据科学学位的新员工最多有大约 3 年的经验。大多数更有经验的人可能是自学的。
在 H2O.ai 采访两次 Kaggle 特级大师和数据科学家:苏达莱·拉杰库马尔
阅读多种好内核,并尝试详细理解它们。了解他们如何从数据中创造洞察力,他们用来描绘数据的图表,他们得出的推论。接受一个新概念(比如一个新的算法或一种新的技术)并就此教育人们也是一个好主意。我个人不喜欢混合了两三个其他内核的输出并得到高分的内核。
专访放射科医师、fast.ai 研究员、Kaggle 专家:亚历山大·卡德林-钱纳维特博士
参加 Kaggle 比赛在我深度学习的学习曲线中至关重要。几乎任何学习过程的成熟都是基于知识到技能,或概念到行动的转化。每次比赛都是朝这个方向发展的机会。但是,自然地,代价是你在这些比赛上投入的时间。因此,我自己的观点是参加数量有限的计算机视觉竞赛,这些竞赛被选中来有效地捕捉最大的潜在利益。
采访 DeOldify,fast.ai 的创作者学生:Jason Antic
是的,你必须知道什么时候该退出,这是一门艺术。事实上,我对很多事情说“不”,或者退出。为什么?因为你对每件事说“是”,你就在对许多其他事情说“不”。时间(和理智)是宝贵的。结果,尤其是最近,我拒绝了很多别人觉得难以拒绝的机会。
因此,对我来说,放弃首先取决于这条路是否完全符合我的价值观、兴趣和保持理智。如果你在谈论一个雄心勃勃的技术项目,那么你必须更进一步,评估它实际上是否可行。通常你不能马上回答这个问题,尤其是如果你正在做一个雄心勃勃的项目!这就是为什么你要做实验。如果你找到了一个合理的理由(而不仅仅是愤怒-放弃合理化)来解释为什么有些事情行不通,那么就放弃,从中吸取教训,继续前进!但是在这一点上要小心——许多问题都可以通过稍微转换一下视角来轻松解决。出于这个原因,我会比看起来合理的时间更长地坚持一个问题,因为我的观点经常是错误的。通常,当我走开的时候,解决方案就来了(基本上是淋浴的想法)。
专访 X5 零售集团计算机视觉负责人 Kaggle 特级大师:阿图尔·库津
Kaggle 可以让你快速发展特定的技能。用正确的方法,这些技能可以转化为工作所必需的素质()。此外,比赛可以让你尝试许多不同的任务,并大大扩展你的知识。最后,如果你能找到一个像 ODS.ai 这样友好的社区,那真是太有趣了
嗯,如果我正在阅读一篇论文,并由此产生一个想法,一个重要的因素是作者是否公开了他们的代码。如果是的话,我会下载并运行它来复制他们的实验。然后我可以迅速尝试我自己的想法,看看它是否有意义。快速原型制作对我来说很重要。此外,他们的代码提供了一个基线。
访 Lyft 高级计算机视觉工程师 Kaggle 大师:Vladimir I. Iglovikov 博士
真的希望越来越多的卡格勒人投入写作。可以是博客帖子、论文,也可以是其他东西。人与人之间的信息交流越多越好。写一篇博文或技术报告将有助于你构建对问题的想法,它将有助于其他人在类似的挑战中有一个温暖的开始,最有可能的是,它将有助于你获得职业机会。这意味着你将致力于更令人兴奋的问题,同时获得更高的报酬。
采访 Kaggle 特级大师,Point API (NLP startup)的数据科学家:帕维尔·普莱斯科夫
因此,我给每个人的建议是:不要浪费宝贵的时间,尽快开始练习——你会在以后弥补理论上的差距。
好了,什么是柴时间数据科学?
这是早期系列的重新启动,也是:
- 播客
- 视频采访
- 博客帖子采访
现在我刚刚毕业,很遗憾没能参加谷歌人工智能常驻项目,我决定把这段时间以视频、音频和博客帖子的形式提供给大家!这是可能,因为我远程工作,但讨论是为了节目(很快就会发布的集!)
名字
在大学的最后一个学期,我有足够的带宽为社区做更多的贡献:我花了很多时间在数据科学网络和 TWiMLAI 社区上。
我决定花 50 个小时/月的时间打开我的日历,让任何人都可以进行“Chai Time DS 对话”。因为我已经是一个贡献者,并得到了了不起的人们的认可。我一个月的时间不到一天就被预订了!
接下来,我决定开展一项投票,如果我得到的表情符号反应超过 25 个(这是一种新的投票方式,不是吗?)
**
不到一天就被预订了!
我最终在五月、六月的整个月里,每天都做 3 次对话。我个人在帮助社区的过程中学到了很多。对话的主题通常是 Kaggle、fast.ai 和项目创意。我强烈建议所有阅读这篇文章的人尝试这样做!
由此得名,柴次秀听起来最为贴切。这个展览也收集了我最常见的问题,一如既往地希望帮助社区成长并成为更好的数据科学从业者。
希望你喜欢这场演出!
请点击此处查看网站:请每周与柴一起关注数据科学讨论。
该节目将在所有最常用的播客平台上发布,视频记录将在 YouTube 上发布,当然还会通过博客发布。
如果你觉得这很有趣,想成为我的学习之路的一部分,你可以在 Twitter 这里 找到我。
如果你有兴趣阅读关于深度学习和计算机视觉的新闻,可以在这里 查看我的 简讯。
挑战者:一个快速原型项目
📷 — Gwen Gummersall from Citadel at West Coast Citadel Hackathon
黑客马拉松,一切都始于黑客马拉松。他们的内在功能很简单:在有限的时间内设计一个新产品,说服陪审团这个产品值得人们使用。我在这里提出的区别通常是改变游戏规则的,因为没有好故事的好产品不会影响任何观众,同样,没有好产品的好故事也太依赖于陪审团的技术技能。做出妥协以获得两者的好版本(不需要完美)通常会让你处于一个好的位置。做了几十个之后,我对任务冗余感到震惊,尤其是当产品是关于利用机器学习来解决一个明确的问题时。
因为我个人讨厌浪费时间重复做同样的事情,所以我设计了这个 python 包作为我的任何小项目的任务缓解器。你会注意到,它现在仅仅专注于数据科学任务,因为这是我在过去几年中主要做的事情。它帮助我进行数据预处理、机器学习模型拟合在一个可控且可重复的环境中(这通常需要你没有的时间)图形利用和可视化、API调用、一般数据可视化、 Flask web 服务器模板和 PowerPoint 演示以确保故事讲述涵盖了它应该涵盖的一切。
通过多次体验,我注意到那些项目的部分可以自动化,发布这个开源包是我试图给每个人这个工具箱来玩。
包装结构
下面的图表很好地概述了我是如何定义这个无处不在的包的模块化的。我的策略是发布多个版本,因为这将是增量开发和改进的。此外,我的经验告诉我,没有必要从第一天开始就部署一切,因为所有这些都将是多个想法的结果!
The current roadmap for Project Challenger
自动化特征化
这可能是所有任务中最无聊的一项,深度学习可以部分解决这个问题。然而,你通常需要解释,这也参与了你的故事讲述。此外,在一次黑客马拉松中,用特性和经典模型制作原型是容易、快速和足够 T2 的。既然一切都可以矢量化成特征,不管是时间序列、图像还是文本,让我们享受一些自动化吧!第一版包含一维时间序列的特征,并将进一步扩展到多模态序列。
750 Designed Features for Time Series — Configuration
特征化是一个棘手的问题,因为它需要非常深入的领域知识才能获得最佳性能。尽管如此,用“经典特性自动化这个过程将会让很多学生和原型设计者松一口气。
这种特征化过程目前特别适合分析 EEG 信号、惯性流或金融时间序列,因为我通过参加特定的数据竞赛构建了其中的大部分功能。在这篇文章中,你可能会发现我对脑电图大脑信号的一些研究结果。
运行受控 ML 实验
B 因为知道用什么框架,优化什么模型,使用什么参数是一件痛苦的事情,所以通过 Challenger 可以使用不同的机器学习优化策略。总体目标当然是控制实验、再现性和快速参数化。目前,它处理两种类型的优化: PARZEN (灵感来自hyperpt)和 BAYESIAN (灵感来自 GitHub )优化。我还将这两种方法结合成一种进化方法,因为 parzen 在做出选择时完成了贝叶斯优化。
如何使用这个包的一个例子是:基于你自己的训练和测试数据集快速原型化一个机器学习模型。在这种情况下,代码加载太著名的 iris 数据集,将其分成 80%的训练和 20%的测试,实例化一个实验,使用所有可用的 CPU,基于测试集上模型的准确性( acc ),通过贝叶斯优化来优化 ExtraTrees 模型( ETS )。
Tutorial example to run an experiment
这样一个实验提供的是一个 config.json 文件,聚集了实验中使用的所有参数,以及一个 params.json 文件,记录最佳确定的参数。两者都提供了再现性和最终模型,供您在生产中使用/提交您的预测。一个仪表板类型的可视化也可以让你更好地理解你的训练模型在测试集上的表现,以及特征重要性的解释(如果可以的话)。
General output dashboard
当然,这可以扩展到交叉验证,并在 HPC 机器上运行。目前,我在这样的机器上使用 Slurm 进行作业调度,但是将来可能需要实现其他框架。
玩图表
T 软件包的这一部分最初是为一个小型竞赛开发的,其解决方案实际上是 Dijkstra 算法的一个技巧。当时,我浪费了大量宝贵的时间来研究算法优化版本的实际实现。即使不谈图形分类,可视化和路径确定也是该领域的主要目标。因为我已经多次重复使用了它,其中一个值得注意的例子是 AsTeR 项目在给定的旧金山地图上派遣紧急单位,我觉得将这个过程形式化和自动化是个好主意。
Code snippet to interact with Folium map
Folium output visualization
对于图形分析的其他目的,我将享受这一节,将您重定向到我设计的另一个工具箱,这次是为了拓扑数据分析。
让它开源并建立一个社区!
我还想给你看更多的东西,但是我知道让这个包描述太长会让你不愿意读到最后。让它开源背后的整个想法是传播这种工具的使用,并让黑客马拉松爱好者帮我设计一个更好的包,让新人在这种活动中充分利用时间!敬请期待来稿;)!
参考
情感分析的挑战:词云案例(目前)
探索用于营销的简单 python 代码可视化
Machine understanding and capability get merged together in popular culture.
当我想到人工智能时,我养成了将理解与能力相结合的棘手习惯。我想我们有办法通过一台机器能生产什么来判断它知道多少。然而,对我来说有趣的是,机器实际上不需要理解任何东西来进行大量计算。围绕图灵测试等问题的大量讨论使得大众科学模糊了这一概念。像《前任玛奇纳》和《T2》《刀锋战士》这样的电影给了我们一种感觉,也许对机器可以呈现它们周围的世界有一些理解。我们时代精神中的这些想法模糊了我们如何看待今天工业中使用的工具能力。通过一些第三级数据科学探索,我将尝试解开当今市场营销中仍然普遍面临的一个挑战——在不阅读所有内容的情况下总结内容。
应对营销挑战。
当我们在开会时,我们可以倾听并总结我们正在消费的内容的要点。然而,假设我们需要总结 400 个文档——一定有比阅读所有文档更好的方法。社交倾听在营销中被用作综合大量品牌内容的手段,但总结信息的常用方法仍有许多不足之处。
A low-cost social listening dashboard that can be used by marketers.
我们早就知道,twitter 可以用来聚合对人们谈论内容的理解。在许多方面,我们可以获得无与伦比的洞察力,如品牌认知、流行词汇、积极或消极态度以及各种基于感觉的总结。在我的上一份工作中,我使用了一个社交媒体监听仪表板。我能够查询主题,并从某种意义上获得一个“刮刀”来收集网络上的书面内容。我当时并不知道,但这是我第一次涉足非结构化“大数据”背后的挑战。
How can I get the summaries of these mentions without reading through each tweet myself? What if all the mentions are not in english? (Source: http://bit.ly/2LIErFq)
虽然我能够从“野生”中收集想法,但将这些想法总结成意义比我预期的有更多的细微差别。我想制作一个人们在比文字云所能提供的更高层次上所写的思想的浓缩版本。今天,社交倾听平台可以帮助我们理解内容是积极的还是消极的,以及内容可能表达的情感。但是,我还是要看内容,把表达的想法和标签化的情绪联系起来。
通过学习数据科学技能,我明白了我们如何用基本代码解决这些问题。我现在拥有的数据科学工具可以处理数据中的噪音,但不能为我阅读和总结。很长一段时间,我确信有比通过文字云更好的方式来总结内容。然而,经过大量的搜索,我开始接受单词云是非常好的——就目前而言。
收集我自己的推文。
我使用了提供的收集推文和分析社会情绪的教程,来看看为什么云这个词最终会起作用,尽管它感觉被高估了,以及为什么更好的东西很难找到。我将使用关于最近优步 IPO 的零散推文作为数据集的例子。我的问题是,我如何想象几天前围绕优步 IPO 的对话摘要?
A piece on NPR. (Source: https://n.pr/2YuWIrk)
At this point, follow the code provided by: [Amardeep Chauhan](https://towardsdatascience.com/@amardeepchauhan) in his post [Scraping Tweets And Analyzing Social Sentiment](/selenium-tweepy-to-scrap-tweets-from-tweeter-and-analysing-sentiments-1804db3478ac).
我收集了推文,清理了文本,将他们的情绪符号化,然后将推文分成积极和消极两个情绪组。鉴于要在使用 Tweepy 和 Selenium 之间进行选择,我决定使用 Tweepy 来收集 1057 条推文。Selenium 是我更熟悉的工具,但是如果不登录 Twitter,我的指针永远无法到达我的抓取起点。
这既是可视化的一课,也是后续教程的一课。似乎有两行代码需要将情感放入数据框中的一个“列”或系列中,而我正在使用的教程中没有:
def fetch_sentiment_using_textblob(text):
sentiment = []
for i in text:
analysis = TextBlob(i)
# set sentiment
if analysis.sentiment.polarity >= 0:
sentiment.append('positive')
else:
sentiment.append('negative')
return sentimentCode above by: [Amardeep Chauhan](https://towardsdatascience.com/@amardeepchauhan)**tweet_list = tweets_df['absolute_tidy_tweets'].tolist()****tweets_df['sentiment']= fetch_sentiment_using_textblob(tweet_list)**
询问我的分类工具是否有效。
在这个阶段,我停下来想,我用来分离情感的算法有用吗?例如,如果我只获取正面推文的列表,并使用不同的分类方法获得正面组的总情绪得分,我会看到正面推文组中有一些负面情绪。
{ ‘正’:108,‘中性’:189,‘负’:89}
sid = SentimentIntensityAnalyzer()
sentiment_summary = dict()
# for readme in readmes:
# sentences = nltk.tokenize.sent_tokenize(readme)
# for sentence in sentences:
# sentiment_score = sid.polarity_scores(sentence)messages = pos_list
summary = {"positive":0,"neutral":0,"negative":0}
for x in messages:
ss = sid.polarity_scores(x)
if ss["compound"] == 0.0:
summary["neutral"] +=1
elif ss["compound"] > 0.0:
summary["positive"] +=1
else:
summary["negative"] +=1
print(summary)Code above by: [Thomas Barrasso](https://itnext.io/@tbarrasso)
我也可以比较给我正面和负面分类的算法。在这种情况下,我查看了:a .单词包(简单矢量化),B. TF-IDF(词频-逆文档频率)。单词包(简单矢量化)产生 0.7745 的 F1 分数,而 TF-IDF 产生 0.79227 的 F1 分数。差不太多!关于 F1 分数意味着什么的更多信息,请看 Koo Ping Shung 的这篇文章。
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score
def naive_model(X_train, X_test, y_train, y_test):
naive_classifier = GaussianNB()
naive_classifier.fit(X_train.toarray(), y_train)# predictions over test set
predictions = naive_classifier.predict(X_test.toarray())
# calculating f1 score
print(f'F1 Score - {f1_score(y_test, predictions)}')X_train, X_test, y_train, y_test = train_test_split(bow_word_feature, target_variable, test_size=0.3, random_state=870)
naive_model(X_train, X_test, y_train, y_test)X_train, X_test, y_train, y_test = train_test_split(tfidf_word_feature, target_variable, test_size=0.3, random_state=870)
naive_model(X_train, X_test, y_train, y_test)Code above by [Amardeep Chauhan](https://towardsdatascience.com/@amardeepchauhan)
分享发现。
所以现在我问我如何与非技术观众分享这些想法。我用柱状图看了一下最常用的词。
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inlinex = list(dict(top_15_pos).keys())y = list(dict(top_15_pos).values())plt.barh(x,y, align='center', alpha=0.5)
plt.xlabel('Mentions')
plt.title('Top 15 words used in positive Uber IPO tweets')
那么更复杂的东西呢?seaborn 库有很多选项,我迭代了很多我认为可能比单词云更直观的选项。然而,我的结论是,尽管有很多“看起来复杂”的可视化工具,但它们中的大多数并不比条形图或文字云更好地分享内容意义。
Different visualizations that the seaborn library can help produce.
这些图表实际上没有产生任何进一步的见解。我向我正在使用的情感分析教程的作者询问了他将使用的可视化类型。以下是他的回应:
最终,我用这个教程和下面的代码创建了两个单词云,分别是与积极情绪相关的和与消极情绪相关的。
all_words = ' '.join([text for text in pos_df['absolute_tidy_tweets']])
from wordcloud import WordCloud
wordcloud = WordCloud(width=800, height=500, random_state=21, max_font_size=110).generate(all_words)plt.figure(figsize=(10, 7))
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis('off')
plt.show()
The words that occurred with a positive value for the text.
“云”这个词的有用之处在于,它确实开始成为一些术语超越其他术语的标尺。我也可以用云这个词来说明使用算法是多么有用。消极和积极的可视化中都有共同的词,表明相同的短语在新的上下文中可能意味着不同的事情,并且算法可以从整个短语中消耗信息。
Words that occurred with the negative labeling of text.
但是说我不需要仅仅知道一些新闻是否被正面看待,我需要知道它意味着什么。我无法用更长的短语来总结所有的想法,就像你用文字云从会议记录中得到的笔记一样。我失去了这些短语所在的整个句子的上下文,只能把我自己的解释和外部研究带入这些单词簇。
最后,读一读像这样的文章可能会更有用,这样可以真正理解我们说话时的意思。然而,我确实想以这样一个想法来结束我的演讲:通过深度学习*,我们能够*到总结整个想法,而不仅仅是单词统计。我的一个朋友深入研究了情绪分析的深度学习,我强烈推荐阅读这本书。挑战在于许多主流工具还没有提供这些功能,而且从各方面考虑,单词云也不是那么糟糕的选择。
A piece from the New York Times. (Source: https://nyti.ms/2W1w63j)
数据产品经理面临的挑战
如何预测、计划和减轻风险
Unsplash — https://unsplash.com/photos/pypeCEaJeZY
随着对数据科学家需求的快速增长,数据产品经理作为一个新角色应运而生。随着企业开始认识到建立和运营数据团队的独特挑战,他们正在雇用以数据为中心的产品经理来处理建立新数据产品带来的独特的战略和战术决策。
The slow rise of the Data Product Manager via Google Trends
这些新上任的数据产品经理面临着独特的挑战。企业如何正确预测、规划和克服这些挑战?如果你是一名数据产品经理或者想成为一名数据产品经理,你会面临哪些挑战?
数据产品经理的职责与任何软件产品经理基本相同。90%的日常职责仍然是确定优先级、沟通、利益相关者管理、设计协作和创建规范。您仍然需要构建业务案例,管理积压工作,提交发布计划,并充当与内部和外部利益相关者的接口。从根本上说,你仍然有责任合理安排 R&D 短期和长期投资的优先次序,以优化业务成果。
挑战来自于额外的工作,不仅要优先考虑和指定以工作流为中心的解决方案,还要优先考虑和指定数据驱动的解决方案。交付数据驱动的解决方案需要更长期的规划,通常需要更多资本密集型投资。这些过程也随着更复杂的开发周期和持续维护的变化而变化。
期权的商业案例
如果你是在一个已建立的产品或者一个全新的产品上构建特性,选择最高优先级的问题来解决仍然是你的最高优先级。“数据产品经理”这个头衔可能会让你偏向于你的特性的交付方法——数据科学或某种风格的分析。作为一名项目经理,你需要抑制住对所有可投资问题抛出数据解决方案的冲动。你的投资者会感谢你明智地选择了数据而不是工作流解决方案。
那么,你如何制定你的解决方案——只有工作流,数据驱动的工作流?
- 数据解决方案中的价值是否推动了独特而有价值的见解?还是价值存在于一个工作流程的效率发挥中?
- 在您的业务案例中,您的数据采集和/或数据标记成本在财务上是否可行?不要低估这个成本——许多项目需要新的资本注入,仅仅是为了创建标签化的训练数据。
- 您在数据资产、愿景和人才方面处于领先竞争对手的有利位置吗?
如果这些问题的答案让你有“不”或“听起来我应该只做一个工作流功能”的感觉,那么你已经有了答案,应该首先解决这些挑战。假设你说“是的!让我们来研究数据科学”之后,还有一些其他的事情需要考虑。
更复杂的开发周期
你的发展周期即将改变。随着数据科学发展带来的资源和独特流程的增加,它们会变得更长、更复杂。数据科学团队的任务包括数据收集/来源、发现、清理/处理、培训,有时还包括部署。这些新的数据科学家和你现有的开发团队的最初整合是非常重要的。许多数据科学家和新数据科学团队的高管对数据前三个步骤(收集、发现和清理)所花费的时间感到震惊。数据科学家 90%以上的时间都花在这些任务上,而不是模型创建、测试和部署。那么该怎么办呢?
Credit: Microsoft — https://docs.microsoft.com/en-us/azure/machine-learning/team-data-science-process/overview
如果您在数据科学家方面捉襟见肘——雇用数据分析师,并为他们提供他们需要的工具,如 Alteryx 、DataRobot 或 Knime。优秀的数据分析师可以使用这些解决方案,尝试创建数据管道、发现、清理和测试通用模型。您的分析师所做的早期工作可以大大加快您的构建时间,并且是一个预算友好的解决方案,否则数据科学家将在模型创建和测试之前花费大量时间。
持续维护
为即将到来的车型退化制定计划,因此比通常的持续维护成本更高。一个机器学习模型随着它所接触的世界而发展——它需要保持最佳状态。就像你对非数据项目的新特性所做的那样——需要比平常更高的前期维护和一个长尾巴的后续维护。如果您必须手动标记训练数据或者有一个手动收集过程,不要忘记这也是维护的一部分,因为您可能需要用这些新信息更新您的模型。
掌握数据科学的复杂性
如果你没有数据科学背景,没关系。我的首要建议是让自己沉浸在数据科学的世界中,即使是很短的时间。这将为您提供背景信息,并让您更好地了解您的数据团队将面临的挑战。我推荐几条途径:
- 参加 MOOC 在投入机器学习之前,先温习一下你的统计。
- 如果你没有软件开发背景——使用帮助你加速学习的工具——alter yx、Knime、RapidMiner 和 DataRobot 都是不同价位的出色工具(Knime 有最有用的免费选项)。
- 使用上面的工具之一进行 Kaggle 或 DrivenData 比赛。这些只需要 2 个小时,是边做边学的好方法。如果你想通过这些比赛之一来看看深度学习的力量——尝试使用 H2O 的无人驾驶人工智能解决方案,这太不可思议了。
对数据产品经理面临的额外挑战有什么想法?让我知道!您一直在考虑的数据项目需要帮助吗?发推文或在 Linkedin 上发消息给我。干杯!
挑战传统是数据科学家的一项关键技能
如果你看过数据科学中一些更具突破性的部分。让你“惊叹”的部分,比如能够在自己的游戏中击败职业选手,数大群人或者检测癌症。仔细想想,所有这些都是巨大的成就。这些任务中的每一项都需要 100 个小时的练习,对于一台机器来说,能够复制它,更重要的是能够容易地复制,这是令人惊讶的。
但是还有其他的东西在起作用,那就是挑战公认信念的能力。十年前,如果你说机器学习可以做一些它现在能做的事情,人们可能不会相信,这种批判的眼光可能是数据科学家的一个关键资源,也可能说明一个事实,即我们经常遭受比我们意识到的更多的虚幻真理效应。这种效应会阻碍机器学习领域的进步。
什么是虚幻的真实效果?
这是一种效果,如果你从足够多的来源听到足够多的东西,你会天生相信它。通常这是没有真正质疑的。不相信我?试试这个问题。
什么星球离地球近的时间最多?
听起来很简单,我打赌你的第一个想法是金星。但是如果你仔细想想,你为什么会这么想呢?这是因为我们被告知金星比我们离太阳更近,我们已经跳跃性地认为它一定离我们最近。
这个问题受到虚幻的真理效应的影响,因为如果你在网上搜索,你会发现许多文章说金星在大多数情况下或大多数时间最接近地球。
事实上,自从我在 2019 年 3 月 15 日左右写了这篇文章以来,你会发现许多这些链接现在都变低了,因为人们已经发表了许多文章来纠正这种信念,但如果你向下扫描搜索结果,你会发现许多这些旧的信念链接。对每个人都好,但对我的论点不好!但几个月前它还是有效的,所以请原谅我。
哪个应该更近?
我首先想到的也是金星。但是当你在任何时间点考虑它时,最近的距离取决于每个行星在其轨道上的位置。会有火星、水星或金星比其他任何一个都更靠近地球的时候。但是,如果我们在考虑哪一个离地球更近的时间最长,那么我们会更多地考虑统计数据,希望得到一段时间内的平均值。
我的第一个思想实验是考虑这些轨道。
Orbital Distance Thought Experiment (Credit: Author)
看上面的图,如果我们想到每个行星相对于地球画出的圆(我没有包括偏心率,因为这比我的大脑内部能容纳的数学还要多)。我们从地球画一个半径,接触水星最近和最远的半径。这些区域代表金星总是更近(蓝色)和水星总是更近(绿色)的区域,以及一个灰色区域,其中任何一个都可能更近,但可能平均起来相同。这给了我一种直觉,因为绿色的面积比蓝色的大,所以金星在大多数时候可能不会比水星更近。
但是作为一名数据科学家(或普通科学家),你需要事实来证明一些事情。所以我转向模拟。
基本模拟
我自己算出来的方法是做一个“信封背面”的计算。我取了每个行星的半长轴(我忽略了偏心率)和它们以天为单位的轨道周期。我用 Python(在 Jupyer 的笔记本里)把这个编程到一个简单的太阳系里,把它们排好,让它们运行 100 年。
Simulation of planet orbits assuming no eccentricity.
然后我计算了每个时间点离地球的距离,并计算了中间距离。我有:
- 火星:1.826 天文单位
- 金星:1.231 天文单位
- 水银:1.073 金
(一个天文单位代表天文单位,因为涉及的距离如此之大,他们使用地球到太阳的平均距离。
我选择中值的原因是平均值可能会受到异常值的影响,中值表示一半数据低于该值,一半数据高于该值的值。因此,它在这里工作得很好,因为如果水星有 50%的数据点低于其他两颗行星,它必须比其他两颗行星花更多的时间靠近地球。
我还绘制了一个经验累积密度函数,并绘制了一条 50%的线,与上面的值相匹配。
Empirical Cumulative Density Functions for distances between earth and Mercury, Venus and Mars.
这种距离排序大致符合 Wolfram Alpha 的答案(记得我的模型不包括偏心轨道,有人做了更复杂的东西这里)。这似乎很违背直觉,但是如果你想到轨道,水星离太阳很近,所以不能移动很远(最多是它的轨道半径加上地球的),而其他的有更大的范围。如果你想要这些距离的漂亮图形,那么大众机械师有一个在这里。
我的外卖?不要总是把引用的事实当作真理,做你自己的测试来确认你相信它,你可能会惊讶于假数据是如何传播并成为事实而没有受到质疑或至少没有经过理智检查。通常这仅仅是因为被引用的次数足够多,以至于人们认为它一定是正确的。一点点研究通常可以表明某件事是否现实(基本上更像是笛卡尔的观点)。
这是伟大的数据科学。
如果城市能够感知并回应我们的情绪会怎样?
2019 年深圳双年展上的情感城市装置探索了 e 运动感应人工智能的环境潜力,以感知人类的情绪状态,并通过光和运动表达人工移情
The Emoting City. Photo Credit:©Dalia Tondo (Shared with permission of Shenzhen Biennale)
如果城市获得了感知能力并引发人类情感会怎样?
这个项目设想了一个未来的场景,城市变成了一台情感机器。一种由能够看到、感觉到甚至重新配置自身与人类情感相关的功能的元素创造的机器。纵观历史,情商将人类与机器区分开来。虽然人类有一种天生的能力来发现微妙的社会线索并相应地修改行为,但机器系统是确定性的,对人类的感觉漠不关心;通过编程来客观、限制或控制人类行为,从而导致对其使用的怀疑。
“The Emoting City ‘’ conceptual diagram depicting applications and components across 3 layers: artificial, environmental, and human
这种系统的普遍存在有助于在世界范围内新发现的经济和社会效率。然而,常规和消费的强加效应也使人们疏远了他们与生俱来的行为。如果建成的环境能够“看到”和“感觉到”情感,从而唤起新形式的真实的城市景观、欲望和游戏,会怎么样?
基于情感的计算机视觉和人工智能技术的进步将很快使这成为现实。“情感城市”体现了这些技术的物理形式,以展示一个替代的未来,人类与人工智能的交互超越了监视系统和社交机器人的拟人化设计,走向透明的界面,这有助于实现新水平的交互性和自我洞察力。
由一个反应性建筑组件的网络组成,最终的装置将居住者面部表情的情绪解释为新的环境因素。然后,个人情绪通过变换颜色和形式来表现,作为一系列心理状态的必然结果,作为强化或干预。
Layered (transparency and reflection) smart mirror in use. Self-empathy via facial tracking and color change. Infinity mirror effect is achieved through the superposition of two mirrors, whereby one-way film is applied to the front mirror, which creates a series of smaller and smaller reflections which recede to infinity
在元尺度上,算法从个体表达数据中计算出一段时间内的群体情绪指数。最终,用户体验是个人关注的焦点,也是社区建设和景观的焦点。它鼓励游客之间的有意合作,以引发新的反应和城市的情况。
Distributed Cyberception network. [A] Local server. [B] Communication between program instances [C] data dashboard and visualization
“情感城市”位于活跃的福田火车站内,为大型公共空间赋予了一种移情作用,并展示了连接人类思维与城市的建筑的潜力。促进城市的情感感知*眼睛,*该项目倡导负责任地使用机器视觉来庆祝居民的真实愿望,并减轻无处不在的技术的疏远效应。
The Emoting City. Photo Credit:©Prospekt (Shared with permission of Shenzhen Biennale)
C R E D I T S
激情城市(2019)深圳城市/建筑双年展(UABB)“城市之眼”部分
合作者:雷纳塔·莱默斯·莫莱斯、阿尔汉·艾哈迈德、安德烈·巴卢塔、尼基莱什·莫汉
特别感谢:迪拜设计创新学院
21 世纪人工智能革命改变了商业动态
商业生态系统每天都在随着新技术的引入和发展而不断发展。几乎每个企业都在投资新技术,努力在拥挤的商业环境中保持竞争力…
人工智能(AI)已被证明是技术竞赛中一个有前途的竞争者,并正在帮助企业改善业务流程。
AI 市场收入增长(2018–2025)
Source: Statista [The global AI market is expected to cross $118 billion in revenues by 2025.]
基于人工智能的工具和解决方案的出现正在以前所未有的方式改变着每个领域和行业。在这篇博客中,我们来看看 AI 对博客周围各大行业的影响。
- 网络安全&网络基础设施
69% 的 IT 高管承认,没有人工智能,他们无法应对网络安全威胁。
人工智能正在提高网络安全分析师的效率。使用人工智能工具和技术,网络安全专家可以自动化威胁检测过程,并全天候分析网络漏洞。
AI 可以使用高级推理,并可以从过去的事件中学习,以改善现代企业内部的网络基础设施。在未来几年,越来越多的公司将开始使用人工智能进行网络监控和对漏洞和黑客的早期响应,从而改变整个网络安全格局。
2。物流
整个物流行业都在受益于人工智能技术在提高运输运营效率方面的优势。从智能物流管理系统到智能仓储解决方案。人工智能正越来越多地被物流公司融入到传统的商业运营中。
在客运方面,人工智能也在帮助组织提高服务客户和推动创新的效率。
人工智能进入交通领域的一个最好的例子是自动驾驶汽车和汽车。从优步到谷歌,以及许多其他公司,每个人都在努力完善可以在实际道路上使用的智能驾驶自动化系统。据说,一旦技术成熟到一定程度,智能驾驶会减少道路上的事故。
人工智能还将在未来优化道路交通流量和公共交通时间表。
3。制造
由于人工智能(AI),自动化正在成为制造业的现实。未来,工厂将会在智能网络上运行,由机器人完成大部分危险任务。这不仅会提高生产单位的生产率,还会减少因人工干预而发生事故的机会。
在未来,人工智能驱动的协作机器人的概念将彻底改造我们所知的制造业。机器人将与人类一起工作,提高安全标准,同时提高工厂的利润。事实上,一项研究显示,合作机器人市场将很快超过 10 亿美元。
4。医疗保健
由于其数据管理和分析能力,人工智能在提高向患者提供医疗保健的质量方面具有惊人的潜力。ML 可以帮助护理人员发现大群体中的异常和模式,提高准备状态。
人工智能在医疗保健领域的最大影响是数据分析能力。最常见的情况是,医疗保健机构拥有大量与患者相关的医疗保健数据。人工智能可用于从存储的医疗保健数据中获取意义,以找出模式并提高诊断和治疗的质量。
IBM 等公司已经在使用其智能系统 Watson 来创建智能诊断系统,该系统可以推荐潜在的行动方案和治疗计划。
5。施工
建筑行业可以从人工智能中受益匪浅。最重要的使用案例与使用智能分析改进工作流程和最大限度地减少材料浪费有关。使用人工智能,可以分析建筑和施工模型,以识别漏洞并有效地降低施工成本。
6。高级护理
除了普通医疗保健,人工智能(AI)也在改善老年人和护理过程。基于人工智能的工具可以用于持续监控老年人的健康状况,并在紧急情况下自动发出红色警报。作为一种充分证明、零错误的技术,人工智能可以取代容易出现差异的过时技术。
未来,我们将看到智能人工智能助手的引入,可以添加到他们的家中和高级护理中心,以提供更好的护理。
7。零售&电子商务
在不久的将来,零售和电子商务领域作为一个行业有着惊人的增长潜力。随着基于人工智能的工具和技术的引入,这些细分市场正在改善购物体验。一些最大的电子商务和零售公司越来越多地利用人工智能和机器学习来提供个性化的购物建议。
基于人工智能的算法正在改变电子商务网站为其潜在和现有客户服务的方式。同样,零售商店越来越多地寻找在商店内添加基于人工智能的解决方案的方法,以更好的方式取悦和满足他们的客户。
人工智能驱动的聊天机器人还被零售部门用于客户服务运营,增强了受害客户的互动和满意度。
8。商业智能
可能,人工智能最早的用例之一是在商业智能领域。成长中的企业已经开始利用海量数据来制定跨部门的数据驱动型决策。从人力资源到生产,从销售到营销,每个人都在使用人工智能商业智能解决方案来改善业务运营。
在未来几年,商业智能将进一步发展,以帮助组织在客户服务、产品开发和有针对性的营销方面变得更好,这一切都要归功于人工智能革命。
9。城市规划与管理
人工智能(AI)在城市规划、发展和管理中的应用将提高整个城市基础设施发展的效率。人工智能可以用来收集和分析有用的见解,这将有助于管理员了解居民希望从城市的设施,公共交通,公用事业等方面得到什么。
10。银行&金融
银行和金融部门正在非常有效地使用人工智能(AI ),这一趋势在不久的将来将继续发展。基于人工智能的聊天机器人将在该领域普遍出现,以解决客户查询,甚至分析市场,提供个性化的投资建议。
由于人工智能可以非常容易和快速地分析大量数据,银行和投资业务可以从该技术中受益匪浅。根据行业估计,在未来 5 年内,人工智能将管理很大一部分财富。
算法交易也与时俱进。人工智能将提高自动化交易的准确性。此外,银行可以使用人工智能来评估贷款申请,并简化审批流程。对于保险业来说,人工智能也将通过指导用户根据他们的生活方式,收入和未来的财务义务购买哪些计划和产品来改善客户体验。
11。教育
学习领域也将受益于人工智能的力量。人工智能将有助于改进课程,并帮助教师根据每个学生的兴趣和潜力创建个性化的学习计划和课程。
此外,基于人工智能的工具可以通过跟踪学生的表现模式并自行建议纠正未来的行动来改善学习、准备和能力分析。
12。时尚
人工智能技术对时尚产业有很多潜在的影响。首先,人工智能可以通过分析过去的数据来预测未来的时尚趋势。基于人工智能的购物助手也是一个巨大的潜在用例,可以帮助时尚人士和时尚品牌改善客户体验。
除此之外,AI 肯定有潜力通过自动化从制造到库存管理、物流管理和有针对性的营销活动的几个过程来协助新产品线的生产。
13。供应链管理
供应链管理也是核心领域之一,人工智能将带来积极的突破。人工智能不仅会改善一般流程,还会帮助预测未来的任务和情况,这将有助于降低风险和降低供应链管理的成本。
在供应链生态系统中,数据驱动的决策将减少因人为偏差而导致的错误。从长远来看,这将改善几个业务部门的整个供应链运作。
遗言
人工智能正在改变我们多年来熟知的传统行业。在未来十年,我们将看到人工智能驱动的工具成为我们日常生活中至关重要的一部分。公司也将最大限度地利用人工智能,变得更加以客户为中心,实现他们的商业目标。
目前,从零售到电子商务,医疗保健到教育,几乎每个领域都需要人工智能驱动的工具。一家人工智能开发公司可以通过设计和部署由人工智能驱动的面向未来的工具来帮助几家企业提高利润。为了让企业在未来几年蓬勃发展,他们需要对人工智能技术进行战略性投资,并找到一家有能力的人工智能开发公司作为他们的长期颠覆合作伙伴。
遗传序列的混沌博弈表示
这是我关于生物信息学领域的第二篇文章,我们将一个基因序列呈现为一个混沌游戏表示图。通过这一系列的文章,我希望我能让更多的人对生物信息学感兴趣。
混沌游戏表示是一个序列的图形表示。这是一种将长的一维序列(在我们的例子中是基因序列)转换成图形形式的方法。这是一种新的整体方法,提供了一个 DNA 序列的视觉图像,与传统的核苷酸线性排列完全不同。CGR 可以识别核苷酸序列中的模式,这些模式是使用分形结构技术,通过将 DNA 序列视为由 A、T、C 和 g 四个单元组成的字符串,从一类基因的数据库中获得的
这种模式识别依赖于视觉识别。它是非随机输入在迭代函数系统中的应用。该方法最初是针对 DNA 序列提出的,现在正被用于任何任意符号。CGR 展示了基因组的显著模式特征。由于模式对基因组来说是独特的,这可以用来识别基因组片段或检测水平基因转移。此外,CGR 模式的定量分析可用于序列比较,用 CGR 进行无比对和基于比对的序列比较都是可能的。
这就是科学介绍,现在让我们从基础开始。核苷酸是一种分子,当它们结合在一起时,构成了核酸 RNA 和 DNA 的单个结构单元。我们有四种不同的核苷酸。腺嘌呤(A)、胸腺嘧啶(T)、胞嘧啶©、鸟嘌呤(G)。为了配合化学反应,这里有一些化学公式:
Our respective actors in this article, adenine, thymine, guanine and cytosine.
在我们的例子中,我们将分析生物序列,更具体地说,DNA 序列。生物序列被定义为:
由于我们将分析 DNA,我们的序列将被定义为:
为了开始绘制我们的混沌游戏表示,我们必须先计算我们的 k-mers。什么是 k-mers?术语 k-mer(或 x-mer,其中 x 实际上可以是任何选择的辅音)通常指核酸或氨基酸序列的特定 n-元组或 n-gram,其可用于识别生物分子如 DNA(用于基因预测)或蛋白质中的某些区域。这样的 k-mer 串可以用于寻找感兴趣的区域,或者使用给出许多可能的 k-mer 组合(或者具有重复的排列)的离散概率分布的 k-mer 统计。特定的短 k-聚体被称为寡聚物或简称“寡聚物”。为了简单地解释这一点,让我们看一个简短的序列
所以如果我们计算 1 聚体的数量,那只是核苷酸出现的数量。因此,在我们的示例中,出现的情况是:
在我们写算法之前,让我们看一下 Genbank 和 FASTA 文件格式。Genbank 是所有公开可用的 DNA 序列的注释集合,这些文件以 FASTA 格式编写。FASTA 格式包含一个标题和 DNA 序列。因此,我们将分析 NC_012920 文件,这是智人线粒体,你可以通过搜索 Genbank 数据库或从这里获得该文件。在我们开始分析序列之前,让我们写一些代码来读取文件。
Reading the FASTA file.
这是最基本的东西,我们读取文件,把新的线连接起来,这样我们就形成了一个大的基因串。现在我们需要计算 k-mers 在序列中的出现次数。我们来写一个方法 count_kmers :
Counting k-mers.
在我们的例子中,序列参数是数据,k 是一个整数。你可能已经注意到我们从字典中删除了一个 N。我们正在分析的序列也包含一个 N,这个 N 可以是 A、C、G 或 T 中的任何一个,这取决于概率。因为序列中只有一个 N,所以我们忽略它。
现在我们已经得到了 k-mer,我们需要计算 k-mer 出现的概率。如果你记得你的概率和统计课,这应该是一个简单的问题。如果我们定义
作为基因结构中的一个子序列,出现的概率
是
在哪里
是序列的长度
是 k-mer 的长度
是 k-mer 出现的次数。
现在让我们写一些 Python 代码来计算这个。
Calculating the probabilities.
现在混沌游戏的基本表现已经完成。现在让我们解释什么是 CGR。CGR 是序列的广义尺度无关马尔可夫概率表,寡聚体表可以从 CGR 图像推导出来。CGR 通过以下程序生成:
CGR pseudo code.
我们试图编写的程序将创建一个图像,显示给定序列中所有 k-mers(长度为 k 的寡核苷酸)的丰度。例如,对于四聚体(k=4),得到的图像将由以下组成
方框,每个代表一个低聚物。寡聚物名称和丰度写在这些方框内,丰度也用方框颜色显示,从白色(无)到黑色(高频率)。这个 k-mer 表也称为 FCGR(从混沌游戏表示中提取的频率矩阵)。
A k-mer table example for CGR.
如果你问自己为什么 4 的 4 次方,这是概率和统计的基础。如果我们有一个长度为 4 的 k-mer,每个点有四个可能的值(A,C,G,T),那么我们有
可能的组合。基本上,我们在做一个二维数组。我们可以用下面的公式来计算它的大小
在哪里
是 k-mer 的长度。现在我们需要计算低聚物的位置。寡聚体的位置可以递归定位如下:
对于低聚物中的每个字母,一个盒子被细分为四个象限,其中 A 是左上,T 是右下,G 是右上,C 是左下。因此,低聚物 ACGT 是在
- A =左上象限
- C =上象限内的左下方
- G =上方象限内的右上
- T =上述象限内的右下方
How the quadrants work when representing a gene structure.
现在让我们写一些代码。现在我们可以使用递归,但我们不会这样做,因为我们可以用数学方法计算元素的位置。
Calculating CGR array.
该方法采用两个参数,第一个是 k-mer 概率的字典,第二个是 k-mer 长度。首先,我们使用上面的公式计算数组大小,然后初始化 maxx、maxy、posx 和 posy 变量。然后我们遍历所有的键,对于每个键,我们计算 k-mer 在表中的位置。
现在让我们把所有东西放在一起,运行程序。
我们最终的结果是两张图片:
CGR representation of 3-mers of the NC_012920 sequence.
CGR representation of 4-mers of the NC_012920 sequence.
参考
- H.乔尔·杰弗里,“基因结构的混沌游戏表示”,收录于核酸研究,第 18 卷,第 8 号,1990 年,第 2163–2170 页。
- 混沌游戏表现。在线:http://www . lifen science . com/bio informatics/chaos-game-representation
- K-mer。在线:【http://en.wikipedia.org/wiki/K-mer
- CGR G 语言项目。在线:http://www.g-language.org/wiki/cgr
- Wolfram Mathematica 中的 CGR 表示。在线:https://community.wolfram.com/groups/-/m/t/920422
聊天机器人没有你想象的那么难制造
NLP 学习系列
达斯·维德的聊天机器人指南
聊天机器人。聊天机器人。到处都是聊天机器人。
每个网站都必须执行。每个数据科学家都必须了解它们。每当我们谈论人工智能的时候;聊天机器人必须讨论。
但他们会威胁到这个领域的新手。甚至在我们开始着手解决问题之前,我们就已经纠结于许多问题了。
它们很难创造吗?在使用这些技术之前,我应该了解哪些技术?
最后,我们最终沮丧地阅读了网上那么多的帖子,却一事无成。
Photo by Katarzyna Pe on Unsplash
我向你保证,这不会是“那种帖子”。
我将尝试从我在 高级机器学习专业化的 自然语言处理 课程中的一个项目中提取一些知识。
所以在我开始之前,让我先说不要被围绕聊天机器人的炒作和谜团吓倒。他们使用了我们大多数人都已经知道的非常简单的自然语言处理技术。
如果你不知道,欢迎你来看看我的NLP 学习系列,在这里我用深度学习 和 迁移学习 的方法详细地讲解了文本分类的问题。****
另外,如果你对在工作中使用的定制深度学习工作站或服务器感兴趣,Exxact Corporation 有一系列基于人工智能的解决方案,起价为 3700 美元,带有几个英伟达 RTX 30 系列 GPU,3 年保修和深度学习软件堆栈。
聊天机器人的简短介绍
因此,我们可以从逻辑上将聊天机器人分为以下两类。
- 基于数据库/常见问题解答的 —我们有一个带有一些问题和答案的数据库,我们希望用户可以使用自然语言查询数据库。这就是你在大多数银行网站上找到的那种回答常见问题的聊天机器人。
- 基于聊天的 —模拟与用户的对话。这些聊天机器人给聊天机器人带来了乐趣。我们可以使用 Seq-2-Seq 模型和编码器-解码器架构来创建这样的机器人。
StackOverflow 聊天机器人
我们将创建一个对话聊天机器人,它将能够:
- 回答编程相关问题(使用 StackOverflow 数据集)
- 闲聊并就所有与编程无关的问题进行模拟对话
一旦你将它安装并运行,我们最终的聊天机器人应该是这样的。
The Final Chatbot we will create
好像挺好玩的。
我们将借助 Telegram 和 Chatterbot 等资源来构建我们的聊天机器人。因此,在我们开始之前,我应该让您开始使用这两个工具。
1.电报:
来自 网站 :
Telegram 是一款专注于速度和安全的消息应用,它超级快速、简单且免费。您可以同时在所有设备上使用 Telegram 您的信息可以在任意数量的手机、平板电脑或电脑之间无缝同步。
对于我们来说, Telegram 为我们提供了一个创建聊天机器人 UI 的简单方法。它为我们提供了一个访问令牌,我们将使用它来连接到 Telegram 应用程序后端并运行我们的 chatbot 逻辑。
自然,我们需要一个窗口,在那里我们可以向聊天机器人写问题,这是通过电报提供的。此外,telegram 通过与我们的聊天机器人逻辑进行通信来为聊天机器人提供动力。以上截图仅取自 telegram app。
设置电报:
如果你还不明白它是如何工作的,也不要担心;在我们前进的过程中,我会试着给出一步一步的指示。
- 第一步: 在笔记本电脑上下载安装 电报 App。
- 第二步:在 Chrome 中打开这个 链接 ,随后在你的 Telegram 应用中打开,与僵尸父亲对话。
- 第三步:以上步骤将带你到一个名为 Botfather 的聊天机器人,它可以帮助你创建一个新的机器人。 盗梦空间有人吗? 大概会是这个样子。
- a)使用命令“/newbot”设置一个新的机器人
- b)为您的机器人创建一个名称。
- c)为你的机器人创建一个用户名。
Inception!!!
- 步骤 4:您将获得一个 bot 的访问令牌。在安全的地方复制令牌。
- 第五步:点击“t.me/MLWhizbot”链接,在新窗口中打开与聊天机器人的聊天。
现在,如果你试图与聊天机器人交流,你不会得到任何答案。这就是它应该的样子,因为我们还没有写任何逻辑。
Unresponsive…. Not Cool
但这一点也不好玩。是吗?让我们用 python 变变魔术,让它反应灵敏。
让我们的电报聊天机器人响应
创建一个文件main.py
并将下面的代码放入其中。不要担心,这里的大部分代码是样板代码,让我们的聊天机器人使用访问令牌与电报通信。
我们只需要担心实现类SimpleDialogueManager
。这个类包含一个名为generate_answer
的函数,我们将在这里编写我们的机器人逻辑。
Simple main.py code
现在,您可以在终端窗口中运行文件main.py
来使您的 bot 做出响应。
**$ python main.py**
A very Naive Chatbot
很好。它遵循简单的逻辑。但好消息是我们的机器人现在做了一些事情。
如果你到了这里,稍微祝贺一下自己吧。我们在这里取得的成就是不平凡的。
另外,看看我们运行main.py
文件的终端窗口。每当用户提问时,我们会得到下面的那种字典,其中包含唯一的聊天 ID、聊天文本、用户信息等。我们以后可以根据需要使用它。
**Update content: {'update_id': 484689748, 'message': {'message_id': 115, 'from': {'id': 844474950, 'is_bot': False, 'first_name': 'Rahul', 'last_name': 'Agarwal', 'language_code': 'en'}, 'chat': {'id': 844474950, 'first_name': 'Rahul', 'last_name': 'Agarwal', 'type': 'private'}, 'date': 1555266010, 'text': 'What is 2+2'}}**
到目前为止,我们所做的都是一些设置和工程方面的工作。
现在,如果我们能在main.py
中的generate_answer
函数中编写一些合理的数据科学逻辑,我们应该有一个像样的聊天机器人。
2.说话机器人计算机程序
从文档中:
ChatterBot 是一个 Python 库,可以很容易地对用户的输入生成自动响应。ChatterBot 使用一系列机器学习算法来产生不同类型的反应。这使得开发人员可以轻松创建聊天机器人,并自动与用户对话。
很简单。这是一个黑盒系统,可以为我们的聊天机器人提供聊天类型问题的回答。
最棒的是,它很容易与我们当前的流程集成。
我们也可以训练一个 SeqtoSeq 模型来做同样的事情。也许我会在以后的文章中这样做。我跑题了。
所以,让我们安装它:
**$ pip install chatterbot**
并将 main.py 中的SimpleDialogueManager
类更改为以下内容。我们可以有一个机器人,它可以与用户交谈并回答随机查询。
**class SimpleDialogueManager(object):
"""
This is a simple dialogue manager to test the telegram bot.
The main part of our bot will be written here.
"""
def __init__(self):
from chatterbot import ChatBot
from chatterbot.trainers import ChatterBotCorpusTrainer
chatbot = ChatBot('MLWhizChatterbot')
trainer = ChatterBotCorpusTrainer(chatbot)
trainer.train('chatterbot.corpus.english')
self.chitchat_bot = chatbot **def generate_answer(self, question):
response = self.chitchat_bot.get_response(question)
return response****
init
中的代码使用 chatterbot 实例化一个聊天机器人,并在 提供的英语语料库 数据上训练它。
数据很小,但是你也可以在你的数据集上训练它。就看 文档 。然后,我们可以在generate_answer
函数中使用 Chatterbot 聊天机器人给出我们的响应。
我必须说,不要太“巴阿阿阿阿阿阿阿”了。
创建我们的 StackOverflow 聊天机器人
好了,我们终于到了可以做自己喜欢的事情的阶段。使用数据科学推动我们的应用/聊天机器人。
让我们从创建一个我们下一步要做的粗略架构开始。
The Architecture of our StackOverflow Chatbot
我们需要创建两个分类器,并将它们保存为.pkl
文件。
- 意图分类器:该分类器将预测一个问题是否是堆栈溢出问题。如果不是堆栈溢出问题,我们让 Chatterbot 来处理。
- 编程语言(标签)分类器:如果问题是堆栈溢出问题,该分类器将预测问题属于哪种语言。我们这样做是为了只在我们的数据库中搜索那些语言问题。
为了简单起见,我们将创建简单的 TFIDF 模型。我们需要保存这些 TFIDF 矢量器。
我们还需要存储每个问题的单词向量,以便稍后进行相似度计算。
让我们一步一步地经历这个过程。您可以在我的 项目资源库 中的这个 jupyter 笔记本 中获取完整代码。
第一步。读取和可视化数据
**dialogues = pd.read_csv("data/dialogues.tsv",sep="\t")
posts = pd.read_csv("data/tagged_posts.tsv",sep="\t")dialogues.head()**
Dialogues Data
**posts.head()**
StackOverflow Posts data
**print("Num Posts:",len(posts))
print("Num Dialogues:",len(dialogues))**
*Num Posts: 2171575 Num Dialogues: 218609*
步骤 2:为意图分类器创建训练数据—聊天/堆栈流问题
为此,我们将创建一个带有逻辑回归的 TFIDF 模型。如果你想了解 TFIDF 型号,你可以在这里阅读。
我们也可以使用一种深度学习模型或迁移学习方法来做到这一点,但由于这篇文章的主要目标是启动并运行聊天机器人,而不是太担心准确性,我们只使用基于 TFIDF 的模型。
**texts = list(dialogues[:200000].text.values) + list(posts[:200000].title.values)
labels = ['dialogue']*200000 + ['stackoverflow']*200000
data = pd.DataFrame({'text':texts,'target':labels})def text_prepare(text):
"""Performs tokenization and simple preprocessing."""
replace_by_space_re = re.compile('[/(){}\[\]\|@,;]')
bad_symbols_re = re.compile('[^0-9a-z #+_]')
stopwords_set = set(stopwords.words('english')) text = text.lower()
text = replace_by_space_re.sub(' ', text)
text = bad_symbols_re.sub('', text)
text = ' '.join([x for x in text.split() if x and x not in stopwords_set]) return text.strip()# Doing some data cleaning
data['text'] = data['text'].apply(lambda x : text_prepare(x))X_train, X_test, y_train, y_test = train_test_split(data['text'],data['target'],test_size = .1 , random_state=0)print('Train size = {}, test size = {}'.format(len(X_train), len(X_test)))**
*Train size = 360000, test size = 40000*
第三步。创建意图分类器
这里,我们创建一个 TFIDF 矢量器来创建要素,并训练一个逻辑回归模型来创建 intent_classifier。请注意我们是如何将 TFIDF 矢量器保存到resources/tfidf.pkl
并将 intent_classifier 保存到resources/intent_clf.pkl
的。
一旦我们要为最终的聊天机器人编写SimpleDialogueManager
类,我们将需要这些文件。
**# We will keep our models and vectorizers in this folder
!mkdir resourcesdef tfidf_features(X_train, X_test, vectorizer_path):
"""Performs TF-IDF transformation and dumps the model."""
tfv = TfidfVectorizer(dtype=np.float32, min_df=3, max_features=None,
strip_accents='unicode', analyzer='word',token_pattern=r'\w{1,}',
ngram_range=(1, 3), use_idf=1,smooth_idf=1,sublinear_tf=1,
stop_words = 'english')
X_train = tfv.fit_transform(X_train)
X_test = tfv.transform(X_test)
pickle.dump(tfv,vectorizer_path)
return X_train, X_testX_train_tfidf, X_test_tfidf = tfidf_features(X_train, X_test, open("resources/tfidf.pkl",'wb'))intent_recognizer = LogisticRegression(C=10,random_state=0)
intent_recognizer.fit(X_train_tfidf,y_train)
pickle.dump(intent_recognizer, open("resources/intent_clf.pkl" , 'wb'))# Check test accuracy.
y_test_pred = intent_recognizer.predict(X_test_tfidf)
test_accuracy = accuracy_score(y_test, y_test_pred)
print('Test accuracy = {}'.format(test_accuracy))**
*Test accuracy = 0.989825*
意图分类器有相当好的 98%的测试准确率。TFIDF 没那么差。
步骤 4:创建编程语言分类器
让我们首先为编程语言分类器创建数据,然后使用 TFIDF 特性训练一个逻辑回归模型。我们将这个标签分类器保存在位置resources/tag_clf.pkl
。
我们做这一步主要是因为我们不想对整个问题数据库进行相似性计算,而只是根据语言标签对问题子集进行相似性计算。
**# creating the data for Programming Language classifier
X = posts['title'].values
y = posts['tag'].valuesX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
print('Train size = {}, test size = {}'.format(len(X_train), len(X_test)))**
*Train size = 1737260, test size = 434315*
**vectorizer = pickle.load(open("resources/tfidf.pkl", 'rb'))
X_train_tfidf, X_test_tfidf = vectorizer.transform(X_train), vectorizer.transform(X_test)
tag_classifier = OneVsRestClassifier(LogisticRegression(C=5,random_state=0))
tag_classifier.fit(X_train_tfidf,y_train)
pickle.dump(tag_classifier, open("resources/tag_clf.pkl", 'wb'))# Check test accuracy.
y_test_pred = tag_classifier.predict(X_test_tfidf)
test_accuracy = accuracy_score(y_test, y_test_pred)
print('Test accuracy = {}'.format(test_accuracy))**
*Test accuracy = 0.8043816124241622*
又不赖。
步骤 5:存储问题数据库嵌入
人们可以使用来自 Google 的 预训练词向量 或者通过使用他们的数据训练他们的嵌入来获得更好的结果。
因为准确度和精确度不是这篇文章的主要目标,我们将使用预训练向量。
**# Load Google's pre-trained Word2Vec model.
model = gensim.models.KeyedVectors.load_word2vec_format('GoogleNews-vectors-negative300.bin', binary=True)**
我们希望将每个问题转换为一个嵌入并存储它们,这样我们就不用每次都计算整个数据集的嵌入。
本质上,每当用户提出堆栈溢出问题时,我们都希望使用某种距离相似性度量来获得最相似的问题。
**def **question_to_vec**(question, embeddings, dim=300):
"""
question: a string
embeddings: dict where the key is a word and a value is its' embedding
dim: size of the representation result: vector representation for the question
"""
word_tokens = question.split(" ")
question_len = len(word_tokens)
question_mat = np.zeros((question_len,dim), dtype = np.float32)
for idx, word in enumerate(word_tokens):
if word in embeddings:
question_mat[idx,:] = embeddings[word]
# remove zero-rows which stand for OOV words
question_mat = question_mat[~np.all(question_mat == 0, axis = 1)]
# Compute the mean of each word along the sentence
if question_mat.shape[0] > 0:
vec = np.array(np.mean(question_mat, axis = 0), dtype = np.float32).reshape((1,dim))
else:
vec = np.zeros((1,dim), dtype = np.float32)
return veccounts_by_tag = posts.groupby(by=['tag'])["tag"].count().reset_index(name = 'count').sort_values(['count'], ascending = False)
counts_by_tag = list(zip(counts_by_tag['tag'],counts_by_tag['count']))
print(counts_by_tag)**
*[('c#', 394451), ('java', 383456), ('javascript', 375867), ('php', 321752), ('c_cpp', 281300), ('python', 208607), ('ruby', 99930), ('r', 36359), ('vb', 35044), ('swift', 34809)]*
我们将嵌入保存在一个名为resources/embeddings_folder
的文件夹中。
该文件夹将包含每个标记的. pkl 文件。例如,其中一个文件将是python.pkl
。
**! mkdir resources/embeddings_folderfor tag, count in counts_by_tag:
tag_posts = posts[posts['tag'] == tag]
tag_post_ids = tag_posts['post_id'].values
tag_vectors = np.zeros((count, 300), dtype=np.float32)
for i, title in enumerate(tag_posts['title']):
tag_vectors[i, :] = question_to_vec(title, model, 300)
# Dump post ids and vectors to a file.
filename = 'resources/embeddings_folder/'+ tag + '.pkl'
pickle.dump((tag_post_ids, tag_vectors), open(filename, 'wb'))**
我们现在已经接近尾声了。我们需要有一个函数来获取数据集中最相似问题的 post id ,因为我们知道问题和问题的编程语言。这是:
**def **get_similar_question**(question,tag):
# get the path where all question embeddings are kept and load the post_ids and post_embeddings
embeddings_path = 'resources/embeddings_folder/' + tag + ".pkl"
post_ids, post_embeddings = pickle.load(open(embeddings_path, 'rb'))
# Get the embeddings for the question
question_vec = question_to_vec(question, model, 300)
# find index of most similar post
best_post_index = pairwise_distances_argmin(question_vec,
post_embeddings)
# return best post id
return post_ids[best_post_index]get_similar_question("how to use list comprehension in python?",'python')**
*array([5947137])*
我们可以使用这个帖子 ID,在https://stackoverflow.com/questions/5947137找到这个问题
相似性检查器建议的问题有实际的文本:“我如何使用列表理解来扩展 python 中的列表?[重复]"
还不错,但是如果我们训练我们的嵌入或者使用 starspace 嵌入,我们可以做得更好。
组装拼图— SimpleDialogueManager 类
最后,我们到达了整个练习的终点。现在,我们必须在我们的SimpleDialogueManager
类中安装拼图的所有部分。这是代码。
仔细阅读评论,了解各个部分是如何组合在一起,构建一个完整的逻辑的。只看初始化和 generate_answer 函数。
点击获取整个[**main.py**](https://github.com/MLWhiz/data_science_blogs/blob/master/chatbot/main.py)
的代码供你使用和查看。只需使用运行整个main.py
**$ python main.py**
如果我们的机器人能够访问所有的资源,我们将让它启动并运行。耶!
同样,这里是 GitHub 库 的链接
可能性真是无穷无尽
这只是一个小的演示项目,演示你可以用聊天机器人做什么。一旦你认识到后台只是 python,你可以做更多的事情。
- 一个想法是在所有服务器上运行聊天机器人脚本,我必须直接从 telegram 运行系统命令。我们可以使用
os.system
来运行任何系统命令。再见宋承宪。 - 你可以通过使用简单的基于关键字的意图让聊天机器人完成一些日常任务。这只是简单的逻辑。了解天气、板球比分或者新上映的电影。不管什么能让你开心。
- 或者尝试在你的网站中集成基于电报的聊天机器人。参见中的 livechatbot 中的
- 或者试着从中获得乐趣。
结论
在这里,我们学习了如何创建一个简单的聊天机器人。它工作正常。我们可以通过提高分类器准确性、处理边缘情况、使其响应更快、使用更好的相似性度量/嵌入,或者添加更多逻辑来处理更多用例,来对当前的聊天机器人进行大量改进。
但事实不变。聊天机器人中的人工智能只是简单的人类逻辑,而不是魔法。
在这篇文章中,我密切关注了这个 课程 中的一个项目来创建这个聊天机器人。
如果你有困惑,一定要看看这个课程,或者在评论中告诉我你的问题。我一定会尽力帮忙。
再见!!
Python 数据帧↔ R 数据帧语法转换的备忘单
对于那些熟悉使用 Python 或 R 进行数据分析,并希望快速学习另一种语言的基础知识的人来说,这是一个迷你指南
Photo by Mad Fish Digital on Unsplash
在本指南中,对于 Python,以下所有命令都基于“pandas”包。对于 R,某些命令需要“dplyr”和“tidyr”包。
欢迎评论/建议。
Python ↔R 基础知识
**# Python** ⇔ **R: object types**
type(a) ⇔ class(a) # "class" is better than "typeof"**# Python** ⇔ **R: variable assignment**
a=5 ⇔ a<-5 # a=5 also works for R **# Python list** ⇔ **R vector:**
a = [1,3,5,7] ⇔ a <- c(1,3,5,7)
a = [i for i in range(3,9)] ⇔ a <- c(3:9)**# Python 'for loop':** for val in [1,3,5]:
print(val)**# R 'for loop':** for (val in c(1,3,5)){
print(val)
}**# Python function:** def new_function(a, b=5):
return a+b**# R function:** new_function <- function(a, b=5) {
return (a+b)
}
检查数据帧
**# Python** ⇔ **R**
df.head() ⇔ head(df)
df.head(3) ⇔ head(df,3)
df.tail(3) ⇔ tail(df,3)
df.shape[0] ⇔ nrow(df)
df.shape[1] ⇔ ncol(df)
df.shape ⇔ dim(df)
df.info() ⇔ **NO EQUIVALENT**
df.describe() ⇔ summary(df) # similar, not exactly the same
**NO EQUIVALENT** ⇔ str(df)
文件输入输出
**# Python**
import pandas as pd
df = pd.read_csv("input.csv",
sep = ",",
header = 0)
df.to_csv("output.csv", index = False)**# R**
df <- read.csv("input.csv",
header = TRUE,
na.strings=c("","NA"),
sep = ",")
write.csv(df, "output.csv", row.names = FALSE)# na.strings: make sure NAs are not read as empty strings
创建新的数据框架
**# Python** import pandas as pd
df = pd.DataFrame(dict(col_a=['a','b','c'], col_b=[1,2,3]))**# R**
col_a <- c('a','b','c')
col_b <- c(1,2,3)
df <- data.frame(col_a, col_b)
列/行过滤
**# Python: row filtering**
df[(df['column_1'] > 3) &
(df['column_2'].isnull())]**# R: row filtering**
df[(df$column_1 > 3) &
(is.na(df$column_2)), ]
**OR** library(dplyr)
df %>% filter((column_1 > 3) & (is.na(column_2)))**# Python** ⇔ **R: column filtering (keep columns)**
df[['c1', 'c2']] ⇔ df[c('c1', 'c2')] # OR: df[,c('c1', 'c2')]**# Python** ⇔ **R(with dplyr): column filtering (drop columns)** df.drop(['c1', 'c2'], axis=1) ⇔ df %>% select(-c('c1', 'c2'))**# Python** ⇔ **R: select columns by position** df.iloc[:,2:5] ⇔ df[c(3:5)] # Note the indexing**# Python: check if a column contains specific values** df[df['c1'].isin(['a','b'])]
**OR**
df.query('c1 in ("a", "b")')**# R: check if a column contains specific values** df[df$c1 %in% c('a', 'b'), ]
**OR**
library(dplyr)
df %>% filter(c1 %in% c('a', 'b'))
缺失值处理/计数
**# Python: missing value imputation** df['c1'] = df['c1'].fillna(0)
**OR**
df.fillna(value={'c1': 0})**# R: missing value imputation** df$c1[is.na(df$c1)] <- 0
**OR** df$c1 = ifelse(is.na(df$c1) == TRUE, 0, df$c1)
**OR**
library(dplyr)
library(tidyr)df %>% mutate(c1 = replace_na(c1, 0))**# Python** ⇔ **R: number of missing values in a column** df['c1'].isnull().sum() ⇔ sum(is.na(df$c1))
单列的统计信息
**# Python** ⇔ **R: count value frequency (Similar)**
df['c1'].value_counts() ⇔ table(df$c1)
df['c1'].value_counts(dropna=False) ⇔ table(df$c1, useNA='always')
df['c1'].value_counts(ascending=False)
⇔ sort(table(df$c1), decreasing = TRUE)**# Python** ⇔ **R: unique columns (including missing values)**
df['c1'].unique() ⇔ unique(df$c1)
len(df['c1'].unique()) ⇔ length(unique(df$c1))**# Python** ⇔ **R: column max / min / mean** df['c1'].max() ⇔ max(df$c1, na.rm = TRUE)
df['c1'].min() ⇔ min(df$c1, na.rm = TRUE)
df['c1'].mean() ⇔ mean(df$c1, na.rm = TRUE)
分组和聚合
**# Python: max / min / sum / mean / count** tbl = df.groupby('c1').agg({'c2':['max', 'min', 'sum'],
'c3':['mean'],
'c1':['count']}).reset_index()
tbl.columns = ['c1', 'c2_max', 'c2_min', 'c2_sum',
'c3_mean', 'count']
**OR (for chained operations)**
tbl = df.groupby('c1').agg(c2_max= ('c2', max),
c2_min= ('c2', min),
c2_sum= ('c2', sum),
c3_mean= ('c2', 'mean'),
count= ('c1', 'count')).reset_index()**# R: max / min / sum / mean / count** library(dplyr)df %>% group_by(c1) %>%
summarise(c2_max = max(c2, na.rm = T),
c2_min = min(c2, na.rm = T),
c2_sum = sum(c2, na.rm = T),
c3_mean = mean(c3, na.rm = T),
count = n()) **# Python: count distinct** df.groupby('c1')['c2'].nunique()\
.reset_index()\
.rename(columns={'c2':'c2_cnt_distinct'})**# R: count distinct**
library(dplyr)
tbl <- df %>% group_by(c1)
%>% summarise(c2_cnt_distinct = n_distinct(c2))
创建新列/改变现有列
**# Python: rename columns** df.rename(columns={'old_col': 'new_col'}) **# R: rename columns** library(dplyr)
df %>% rename(new_col = old_col)**# Python: value mapping** df['Sex'] = df['Sex'].map({'male':0, 'female':1})**# R: value mapping** library(dplyr)
df$Sex <- mapvalues(df$Sex,
from=c('male', 'female'),
to=c(0,1))**# Python** ⇔ **R: change data type** df['c1'] = df['c1'].astype(str) ⇔ df$c1 <- as.character(df$c1)
df['c1'] = df['c1'].astype(int) ⇔ df$c1 <- as.integer(df$c1)
df['c1'] = df['c1'].astype(float) ⇔ df$c1 <- as.numeric(df$c1)
按行筛选器更新列值
**# Python** ⇔ **R:** df.loc[df['c1']=='A', 'c2'] = 99 ⇔ df[df$c1=='A', 'c2'] <- 99
连接/分类
**# Python: inner join / left join** import pandas as pd
merged_df1 = pd.merge(df1, df2, on='c1', how='inner')
merged_df2 = pd.merge(df1, df2, on='c1', how='left')
**OR (for chained operations)**
merged_df1 = df1.merge(df2, on='c1', how='inner')
merged_df2 = df1.merge(df2, on='c1', how='left')**# R: inner join / left join** merged_df1 <- merge(x=df1,y=df2,by='c1')
merged_df2 <- merge(x=df1,y=df2,by='c1',all.x=TRUE)
**OR**
library(dplyr)
merged_df1 <- inner_join(x=df1,y=df2,by='c1')
merged_df2 <- left_join(x=df1,y=df2,by='c1')**# Python: sorting** df.sort_values(by=['c1','c2'], ascending = [True, False])**# R: sorting** library(dplyr)
df %>% arrange(c1, desc(c2))
串联/采样
**# Python (import pandas as pd)** ⇔ **R: concatenation** pd.concat([df1, df2, df3]) ⇔ rbind(df1, df2, df3)
pd.concat([df1, df2], axis=1) ⇔ cbind(df1, df2)**# Python random sample** df.sample(n=3, random_state=42)**# R random sample** set.seed(42)
sample_n(df, 3)
链式操作的一个例子
**# Python: chained operations with '.'** df.drop('c1', axis=1)\
.sort_values(by='c2', ascending=False)\
.assign(c3 = lambda x: x['c1']*3 + 2)\
.fillna(value={'c2': 0, 'c4':-99})\
.rename(columns={'total': 'TOT'})\
.query('c3 > 10')**# R: chained operations with '%>%'** library(dplyr)
library(tidyr)
df %>% select(-c('c1')) %>%
arrange(desc(c2)) %>%
mutate(c3 = c1*3 + 2) %>%
mutate(c2 = replace_na(c2, 0),
c4 = replace_na(c4, -99)) %>%
rename(TOT = total) %>%
filter(c3 > 10)
复选标记状态识别将使 NLP 项目更上一层楼!
从扫描图像中检测复选标记状态并对其进行进一步分析可以为 NLP 项目添加有意义的功能
在许多商业交易中,纸质文档仍然被用作主要的数据交换。
例如,
- 需要回答客观类型问题的纸质问卷或调查,
- 保险索赔文件
- 国际贸易融资或银行文件,其中承运人携带进口商/出口商的文件,这些文件使用扫描仪进一步数字化为图像或 PDF 文件。
扫描的图像要么按原样加载,要么使用 **OCR(光学字符识别)**技术进行转换,以获得文本内容。然而,像表格、复选框、徽标、单选按钮和手写文本这样的 HTML 元素在 OCR 转换中会丢失。
捕捉这些元素有一些有用的应用,并且有一种方法可以捕捉它们。
有许多光学标记识别 (OMR)工具,开源的和付费的都可以提取这些元素。但是,这些工具需要在表单或模板中定义一个要捕获的区域。
当然,这是设计时的更改,也就是说,如果模板或文档结构发生了更改(这是很可能的),那么模板更改从设计阶段到生产的传播可能会非常漫长和令人沮丧。
我们最近在我们的项目中遇到了类似的问题,这篇文章讨论了所采取的方法和技术细节。
使用深度学习从图像中进行“复选标记状态识别”
先说一些基础知识,
- 以图像形式存储的文档—许多应用程序以图像形式生成或存储交易文档或 pdf
- 复选标记字段是机器可读表单上的一个元素
- 通常为矩形或圆角矩形,通常称为“复选框”
- 做了一个记号(一个勾/记号,一个 X,一个大点,涂上墨水等)。)—它需要被捕获
- OCR 引擎可以捕获字符/文本,但不能捕获特殊区域,如复选框、表格等。
Check-mark states can be in any form but not limited to
解决方案亮点
- 支持输入的图像类型: jpeg、tiff
- 它使用 OCR 线索词实时提取复选标记,例如“收集兴趣”是上图中与之相对的复选框的线索词
- 提取分两步进行:检测和识别
- 混合使用 OCR、图像处理和机器学习技术
- json 配置—定义模板和复选标记列表,以及每个模板中每个复选框的线索词和图像区域像素
- 模板布局分析、图像预处理是填充配置文件的先决条件
- 在分类模型中捕获复选标记的状态— 复选(1)、未复选(0)、噪声/无法读取(-1)
- 准确率高达 94%*
下面是一个示例配置文件。它为客户列出了一个模板,模板中有两个复选框以及线索词和像素(宽度和高度)来捕捉图像区域。
{"templates": [ { "templateID": "1", "templateName": "Customer_NAME_ABCD", "templateCode": "TEMPLATE_ABCD", "cb_size": [-100, 60], "keywords": [
{ "keywordID": "1", "entity": "Cable advice for NP", "code": "CABLEADVICENP", "keyword": "Cable advice of non-payment", "clue_string": "Cable advice of non-payment", "pixels": [-75,-20] }, { "keywordID": "2", "entity": "Recover Charges", "code": "RECOVERYCHARGES", "keyword": "Recover Charges", "clue_string": "Recover Charges", "pixels": [-75,-20] },….
解决方案图
Solution
详情
复选标记提取在以下步骤中执行:
第一步。模型构建
导入用于深度学习的 Keras python 库和相关 python 包
from keras.models import Sequentialfrom keras.layers import Conv2Dfrom keras.layers import MaxPooling2Dfrom keras.layers import Flattenfrom keras.layers import Densefrom keras.callbacks import ModelCheckpointfrom keras.callbacks import TensorBoardfrom keras.preprocessing.image import ImageDataGeneratorimport osimport fnmatchimport numpy as npimport timefrom keras.preprocessing import imagefrom keras.models import load_modelimport matplotlib.pyplot as plt
定义模型—创建序列并添加层
# Initializing the CNNclassifier = Sequential()# Step 1 — Convolutionclassifier.add(Conv2D(32, (3, 3), input_shape = (60, 100, 3), activation = ‘relu’))# Step 2 — Poolingclassifier.add(MaxPooling2D(pool_size = (2, 2)))# Adding a second convolutional layerclassifier.add(Conv2D(32, (3, 3), activation = ‘relu’))classifier.add(MaxPooling2D(pool_size = (2, 2)))# Step 3 — Flatteningclassifier.add(Flatten())# Step 4 — Full connectionclassifier.add(Dense(units = 128, activation = ‘relu’))classifier.add(Dense(units = 3, activation = ‘softmax’))
编译模型—指定损失函数和优化器
# Compiling the CNNclassifier.compile(optimizer = ‘adam’, loss = ‘categorical_crossentropy’, metrics = [‘accuracy’])modelcheckpoint = ModelCheckpoint(‘./models/checkbox_model.hdf5’, monitor=’val_acc’, verbose=0, save_best_only=True, save_weights_only=False, mode=’auto’, period=1)tbcheckpoint = TensorBoard(log_dir=’./logs’, histogram_freq=0, batch_size=32, write_graph=True, write_grads=False, write_images=False, embeddings_freq=0, embeddings_layer_names=None, embeddings_metadata=None)
拟合模型—使用图像数据执行模型
# Part 2 — Execute the model using image datatrain_datagen = ImageDataGenerator(rescale = 1./255, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True)test_datagen = ImageDataGenerator(rescale = 1./255)training_set = train_datagen.flow_from_directory(‘cbimagestrn’, target_size = (60, 100), batch_size = 32, class_mode = categorical’)test_set = test_datagen.flow_from_directory(‘cbimagestst’, target_size = (60, 100), batch_size = 32, class_mode = 'categorical')# Part 3 — Model trainingclassifier.fit_generator(training_set, steps_per_epoch = 1000,epochs = 50, validation_data = test_set, validation_steps = 500,callbacks=[modelcheckpoint, tbcheckpoint])…
进行预测—使用模型根据新数据或测试数据生成预测
# Part 4 — Model accuracy testing (Making new predictions)# use test data / images to predict [obvious and trivial code is eliminated]…result = model.predict_proba(test_image_arr)…# from the result, we can know how many files are mis-classified or not
第二步。检测
系统检测可能包含复选标记的矩形区域。
在这种方法中,来自 OCR 的线索词用于定位像素坐标,以识别要捕捉的块/区域
如果现有模板发生变化或新模板被添加到系统中,唯一需要的变化是在配置文件中
第三步。识别和分类
检测到这些区域后,将对该区域的图像进行裁剪,以将其识别为复选标记对象。
使用机器学习模型将裁剪后的图像分类为已检查、未检查、噪声
图像处理= CNN from Tensorflow,分类器:optimizer = 'adam ',loss = ’ categorical _ crossentropy ’
*在基线数据集上
结论
使用表单或模板结构的应用程序(其中使用 OCR 技术来捕获文本)可以从捕获复选标记状态中受益,从而丰富数据并减少分析时间。
如果在任何商业交易中表单变化的速度是中等到高,那么 OCR 和深度学习技术的结合,如上所述,可以帮助您变得更加敏捷。
感谢阅读。任何意见和建议——请分享。
参考文献:
[1] Keras 文档
检查分析的实验室数据是否有错误
教程:自动分析实验室数据以创建性能图
如何确保实验室数据集中没有错误
科学家发现自己拥有大型数据集是很常见的。有时,它以单个文件中数千兆字节数据的形式出现。有时是数百个文件,每个文件包含少量数据。无论哪种方式,都很难管理。很难理解。你的电脑很难处理。您需要一种方法来简化这一过程,使数据集更易于管理,并帮助您跟踪一切。
这就是本教程的内容。我们正在编写 Python 脚本,它将自动为您分析所有数据,并以有意义、直观的文件名存储数据。同时使用来自实际研究的例子,这样你就知道你正在发展的技能是实用和有用的。
本教程的第一篇文章介绍了本教程的概念。如果“热泵热水器”、“性能系数(COP)”和“性能图”这些术语对你来说毫无意义,你可能想读一下。
第二篇文章介绍了的配套数据集,将数据集分割成多个文件,并使用用户友好的名称。
伴随数据集是教程过程中有价值的一部分,因为它允许您跟随。您可以编写与我将要展示的完全相同的代码,运行代码,查看结果,并与我展示的结果进行比较。这样,你就能确保你做得对。
在这个过程的最后,我们留下了这个过程中最重要的问题之一。到目前为止,该流程运行正常吗?可能会出现许多问题。实验人员可能在进行测试时犯了错误,导致错误的数据。传感器可能已经损坏,导致数据丢失。即使输入数据是正确的,数据处理代码中也可能存在错误,从而导致奇怪的结果。
这篇文章将向你展示如何手动检查数据错误。这一步很重要,因为它教会了你错误检查中涉及的所有概念,比如如何思考测试中什么是重要的,以及如何检查数据以确保一切正常工作。这将为教程的下一阶段做好准备,下一阶段的重点是自动完成这项工作。
本教程这一阶段的起点将与上次的程序相同。我们将在 for 循环中添加新的代码来分析数据,并利用我们已经导入 bokeh 用于绘图的事实。
第一步是考虑什么可能出错,以及我们需要检查哪些潜在的错误。
我应该寻找哪些错误?
为了识别重要的错误检查,我们需要考虑测试的哪些部分是重要的。对于这些测试,我确定了以下几点:
- 初始水温:初始水温必须高于规定的初始水温。如果不是,那么数据集将不会覆盖整个测试范围,测试必须重新进行。
- 最终水温:同样,最终水温必须高于规定的最终水温。如果不是,那么数据集会过早截止,不能提供所需的全测试范围。
- 环境温度:测试过程中的平均环境温度必须接近规定的环境温度。由于每个测试都提供了热泵在指定环境温度下的 COP,因此不正确的环境温度会导致不正确的性能图。
- 回归质量:这项工作的重点是建立一个预测热泵 COP 的回归模型。这意味着我们需要确保:a)计算的 COP 始终在 2–8 范围内,预计会超过该范围;b)我们在上一篇文章中创建的 COP 回归能够准确预测该测试中的 COP。
为了手动检查所有这些项目,我们需要绘制曲线图,显示测试过程中的水温、环境温度和耗电量。
我如何创造必要的情节?
要为每个测试创建必要的绘图,我们必须添加代码来绘制 for 循环中的每个项目。这样,为单个测试创建每个图,然后程序继续进行下一个测试,并为该测试创建图。
幸运的是,我们在上一篇文章中导入了必要的散景函数,这次不需要担心这个问题。这意味着我们可以通过编写一行代码来创建第一个显示水箱水温的绘图对象。这是用下面一行代码完成的。
p1 = figure(width=800, height=400, x_axis_label='Time (min)', y_axis_label = 'Water Temperature (deg F)')
这一行引用散景函数“figure”来创建一个图形对象。它被分配给变量“p1 ”,因此我们可以在将来通过引用 p1 来编辑该图形。在该函数中,它将绘图的宽度设置为 800 像素,高度设置为 400 像素,x 轴标签设置为“时间(分钟)”,y 轴标签设置为“水温(华氏度)”。我们现在有了一个图的结构,可以根据需要添加数据。
通过编辑图来添加新的数据系列来添加数据。添加的每个数据系列使用一个新行,可以通过引用数据分析中使用的数据框来添加数据。为了将水温数据添加到绘图中,我们使用以下代码:
p1.circle(Data['Time Since Test Start (min)'], Data['T1 (deg F)'], legend='Temperature 1', color = 'skyblue')p1.circle(Data['Time Since Test Start (min)'], Data['T2 (deg F)'], legend='Temperature 2', color = 'powderblue')p1.circle(Data['Time Since Test Start (min)'], Data['T3 (deg F)'], legend='Temperature 3', color = 'lightskyblue')p1.circle(Data['Time Since Test Start (min)'], Data['T4 (deg F)'], legend='Temperature 4', color = 'lightblue')p1.circle(Data['Time Since Test Start (min)'], Data['T5 (deg F)'], legend='Temperature 5', color = 'cornflowerblue')p1.circle(Data['Time Since Test Start (min)'], Data['T6 (deg F)'], legend='Temperature 6', color = 'royalblue')p1.circle(Data['Time Since Test Start (min)'], Data['T7 (deg F)'], legend='Temperature 7', color = 'blue')p1.circle(Data['Time Since Test Start (min)'], Data['T8 (deg F)'], legend='Temperature 8', color = 'mediumblue')p1.circle(Data['Time Since Test Start (min)'], Data['Average Tank Temperature (deg F)'], legend='Average', color = 'darkblue')
上述代码的每一行都向绘图中添加了一个新的数据系列。这些行调用 p1.circle 函数,说明新的数据系列将在图上表示为圆形。在函数调用中,第一项是 x 数据,第二项是 y 数据。您可以看到,每个数据系列都将测试开始后的时间(以分钟为单位)作为 x 数据,并将不同的水温作为 y 数据。共有九个数据系列,前八个代表从数据中直接测量的水温,第九个代表计算的平均水温。每个数据系列的图例说明说明了数据系列在图例中的表示方式,颜色指定了绘图中圆圈所用的颜色。圆圈的颜色选择在坦克的顶部使用浅蓝色,在底部使用深蓝色。
最后,我们要指定图例的位置。如果不是这样,图例可能会覆盖数据集的一部分,掩盖我们需要看到的信息。我们可以在图的右下方添加一行:
p1.legend.location = "bottom_right"
这就完成了第一个图,所以我们可以转到代表环境温度的第二个图。这与创建 plot 对象并向其添加数据系列的过程相同。因为您已经看到了这个过程,所以这里的细节和讨论较少。
p2 = figure(width=800, height=400, x_axis_label='Time (min)', y_axis_label = 'Ambient Temperature (deg F)')
p2.circle(Data['Time Since Test Start (min)'], Data['T_Amb (deg F)'], color = 'red')
这创建了一个类似的图,但它只有一个数据系列,显示数据框中的“T_Amb(华氏度)”列。请注意,y 轴标签也发生了变化,以显示数据集中的变化。
我们需要的第三个图显示了测试过程中的警察。与环境温度类似,由于您已经熟悉了这一过程,因此对该图的讨论较少。第三个图是用以下代码创建的:
p3 = figure(width=800, height=400, x_axis_label=’Average Tank Temperature (deg F)’, y_axis_label = ‘Coefficient of Performance (-)’)
p3.circle(Data[‘Average Tank Temperature (deg F)’], Data[‘COP (-)’], legend = ‘Measurement’, color = ‘red’)
p3.line(np.arange(72, 140.1, 0.1), Regression(np.arange(72, 140, 0.1)), legend = ‘Regression’, color = ‘black’)
这段代码的新内容是增加了一行,显示使用上一篇文章中的回归计算出的器件 COP。这是使用 p3.line 函数调用的。传统上,线用于模拟数据。然后,使用范围从 72 到 140.1、步长为 0.1 的 numpy 数组创建该行的 x 数据。注意,由于 Python 不包括数组中的最后一个条目,这实际上创建了从 72 到 140 的数据点。y 数据使用与我们的 COP 回归输入相同的范围,然后绘制计算的 COP 值。图例和颜色条目与之前图中的相同。
这段代码创建了三个图,但实际上并没有保存它们。散景将图作为用户定义的数组保存在. html 文件中。为了保存绘图,我们需要指定数组和。html 文件,然后保存数据。我们可以用下面的代码做到这一点:
p = gridplot([[p1], [p2], [p3]])
output_file(Filename_Test[:-4] + '.html', title = Filename_Test[146:-4])
save(p)
第一行创建一个由三个列表组成的 gridplot 对象。在这种格式中,每个列表代表要放入每行的图。由于数据是作为三个单独的列表输入的,每个列表包含一个图,所以这些图将显示在。html 文件。如果我们想要多列,我们可以在列表中添加多个条目。
函数的作用是:指定文件的名字和标题。html 文件。在这种情况下,我们使用动态命名赋予绘图与数据文件相同的名称,但以. html 结尾而不是. csv。“csv”来自文件名。当指定文件名时,我们添加。以确保它保存为. html 文件。当指定标题时,我们不需要包含扩展名。最后,我们保存。包含绘图的 html 文件保存到计算机§。
我如何使用这些图来检查结果?
我们可以通过检查图来检查数据和分析的质量,以确保它们显示了我们需要看到的内容。让我们通过检查我们刚刚为 55 华氏度环境温度测试创建的三个曲线图来讨论这个问题。
第一个图显示了测试过程中水箱中每个深度的水温。下面介绍一下。
在这个测试中,我们可以看到每个测量都是从 72 华氏度开始的。这正是我们所期望看到的。此外,每次测量报告的最终温度为 140 华氏度。同样,这正是我们期望看到的。最后,我们看到每次测量中的温度逐渐升高,正如我们预期的那样,当它被热泵缓慢加热时。该图显示数据符合我们对该数据集的预期。
请记住,这是捏造的数据,而不是实际的测试测量。我在创建数据时没有添加任何随机化,这就是为什么这个数据集非常平滑的原因。在处理真实数据时,永远不要期望事情会如此顺利。
我们讨论的第二个图是环境温度。这一点可以从下面的剧情中看出。
注意这个数据比水温更随机一些。它没有直接放置在测试中指定的 55 华氏度,而是从 54 华氏度反弹到 56 华氏度。这是因为我在配套数据集中对环境温度添加了少量随机化。这是为了让你更好地理解真实数据中的内容。当环境温度不在设定点时,如何检查以确保环境温度足够接近指定的 55 华氏度?
在这种情况下,可以肯定地说,测试被设置为 55 华氏度。我这样说是因为数据的平均值明显接近数据。我也认为可以说设备得到了很好的控制。我这样说是因为温度总是接近设定温度;虽然它的温度从华氏 54 度到 56 度不等,但它绝对不会在华氏 45 度或华氏 70 度时移动。
最终曲线图显示了热泵的计算和回归 COP 作为水温的函数。如下图所示。
在这种情况下,我们可以看到热泵的实测 COP 从 72°f 逐渐降低到 140。这是意料之中的,因为水温的升高使水更难从制冷剂转移到水中。与 COP 的突然或急剧变化相反,COP 的逐渐下降也是可以预期的。我们还可以看到,COP 落在预期的 2–9 范围内。
总的来说,这三幅图都表明数据符合我们的规格,并表明测试和计算是正确进行的。
包装它
在本文中,我们介绍了如何添加代码以在分析数据集时自动绘制数据集,如何考虑检查数据,以及如何检查图形以手动验证实验和计算。这是重要的一步,因为基于错误数据或错误计算的项目结果是没有价值的。
然而,这不是执行这种错误检查的最佳方式。如果您执行具有成百上千个测试的项目,手动检查每个测试的图会很耗时,这意味着既昂贵又乏味。最好在程序中添加一个新的部分,自动比较来自实验和计算的值与用户指定的阈值。通过这种方式,我们的代码可以自动识别不符合预期的测试或计算,标记潜在的错误,并向用户报告这些潜在的错误。我们将在下一篇文章中讨论这个主题。
教程目录
这是一系列文章的一部分,教你自动分析实验室数据和绘制热泵热水器性能图所需的所有技巧。本系列的其他文章可以通过以下链接找到:
检查自动化数据分析的错误
自动化数据分析时,如何手动和自动检查错误
这是教你如何编写自动分析科学数据的程序的系列文章的第四篇。首先介绍了概念和动机,然后规划了高级步骤。第二个教你如何构建数据集,使自动化数据分析成为可能,并自动识别每个测试的条件。的第三篇文章讨论了创建一个 for 循环,自动对每个测试结果执行计算并保存结果。这第四篇文章可能会涵盖整个过程中最重要的部分:检查数据和分析结果中的错误,以避免它们影响最终结果。
检查测试和分析结果的质量
也许反对数据分析自动化的最强有力的论据是可靠性。一个无意识地执行计算和分析的计算机算法不会识别出表现不佳的测试或分析中的错误,这些疏忽将导致最终项目结果中的错误。这不仅仅是人们害怕新的做事方式,这是一种合理的担忧。在实验室测试的情况下尤其如此;实验室测试并不总是按计划进行,有时需要在数据分析过程中识别这些错误。
幸运的是,可以在程序中添加错误检查方法。这些技术中的一些,即打印中间输出和绘制所有数据,需要手动数据检查,尽管仍然比完全手动数据分析少得多的人力。其他的,即创建一个自动化的数据检查算法,允许程序自己进行错误检查,大大减少了数据检查的时间需求。结合计算机程序的自然可重复性,这些方法可以使数据分析过程比手动计算更可靠,同时也明显更快。
以下部分将描述 Python 程序中数据质量检查的三种方法。
打印中间输出
打印中间输出类似于显示所有计算。这是一个好的实践,因为它既方便了程序创建时的调试,又允许其他人检查结果并建立对自动化数据分析程序的信心。因为许多人不想直接查看 Python 代码,所以他们不能像使用 Excel 电子表格那样检查公式。这使得提供尽可能多的中间输出变得尤为重要,这样人们就可以自己检查计算结果。
打印中间输出的基本前提是以类似于 Excel 的格式显示尽可能多的计算步骤。通过让其他人更容易理解,这有助于检查代码的结果。然后,他们可以轻松地执行自己的计算,并将结果与 Python 输出进行比较。这通常通过以下两个步骤来完成。
1.在数据框中显示尽可能多的计算细节。外部变量或列表可能是必要的,但应谨慎使用。将所有数据和计算包含在一个数据框中,便于其他人理解和检查计算。
2.将每次测试的数据框打印到唯一的。csv 文件。
在数据框中呈现计算细节的某些方面变得很自然。大多数计算将在数据框上执行,结果将作为直接结果存储在数据框中。其他方面需要额外付出一点努力。例如,常数更自然地被用作独立变量,但是在数据框中为它们添加一列允许其他人在只检查输出表的同时检查这些常数。
保存新的。csv 文件是一种非常有用的方法,可以确保保存整个项目中的所有计算,而不是在分析新测试的结果时覆盖旧的计算。这通常通过以下方式完成:1)在分析每个测试时创建一个新文件夹,以存储该测试的结果;2)使用动态文件名将结果保存到. csv 文件中,该文件名会发生变化,以表示当前正在分析的测试的条件。使用下面的代码可以实现这两个目标。请注意,示例代码使用了第 2 部分中显示的技术来跟踪测试的条件。
Flow_Hot = Find_Between(filename, ‘_FlowHot=’, ‘_FlowCold)Flow_Cold = Find_Between(filename, ‘_FlowCold=’, ‘_TemperatureHot’)Temp_Hot = Find_Between(filename, ‘_TemperatureHot=’, ‘_TemperatureCold’)Temp_Cold = Find_Between(filename, ‘_TemperatureCold=’, ‘.csv’)Folder = r’C:\Users\JSmith\DataAnalysis\Data\Flow_Hot=’ + Flow_Hot + ‘Flow_Cold=’ + Flow_Cold + ‘Temp_Hot’ = Temp_Hot + ‘Temp_Cold=’ + Temp_Coldif not os.path.exists(Folder):os.makedirs(Folder)#CalculationsData.to_csv(Folder + ‘\Flow_Hot=’ + Flow_Hot + ‘Flow_Cold=’ + Flow_Cold + ‘Temp_Hot=’ + Temp_Hot + ‘Temp_Cold=’ + Temp_Cold + ‘.csv’, index = False)
将前面的代码分成五个步骤,它:
1.使用第 2 部分中的技术来识别当前正在分析的数据集的名义条件。在本章的上下文中,这确保了程序拥有创建文件夹和文件名称所需的信息,并且结果以有序的方式存储,便于以后理解。
2.使用步骤 1 中读取的条件创建一个名为 Folder 的变量。文件夹的路径对于此测试是唯一的,并在文件名中使用测试条件。
3.检查是否已经有与该名称匹配的文件夹,如果没有,则创建一个。
4.第四步是对数据执行所有计算。为了简化讨论,并把重点放在打印中间输出上,计算用上面的一个注释来表示。
5.分析完成后,此步骤将数据帧写入新的。csv 文件。的。csv 文件位于新文件夹内,包含标称测试条件,并且本身包含标称测试条件。这种严格的命名结构确保了在以后需要时可以很容易地找到正确的数据集。
使用图检查结果
检查测试数据质量和相关数据分析性能的一种简便方法是通过绘图。自动化数据分析程序的优势在于,它们可以为数百个测试快速创建图表,减少了单独生成图表所需的人工劳动。这使得用户可以快速浏览图,并快速确保数据质量。
为每个测试自动生成和保存图的过程现在是读者可以做的事情。一般流程是使用在 自动化科学数据分析第 2 部分 和自动化科学数据集分析中描述的技术来创建一个程序,该程序循环通过所有数据集,执行所需的计算,生成所需的图,并保存结果。这些技术已经讨论过了。
这里的关键概念是绘制足够的数据集特征,以便能够快速、直观地检查以确保测试正确进行。回到第 2 部分描述的热交换器示例,这意味着保存的图必须允许用户快速确定:
1.测试热端和冷端流量与测试计划中要求的标称测试条件非常匹配,
2.测试热端和冷端入口水温符合测试计划中要求的标称测试条件,
3.所有参数都足够稳定,以确保质量、稳态运行,
4.用于确定试验稳态周期的过滤器选择了数据集的正确部分,以及
5.最终稳态有效性值是稳定且合理的。
这个目标可以用三个情节来完成。
图 1 给出了一个示例图,显示了通过热交换器两侧的水流量。为了这个例子,假设这个测试的标称流速条件在装置的两侧都是 3.5 加仑/分钟。在图 13 中,两种流速都在 3.4 至 3.6 加仑/分钟之间。这是少量的变化,在测试中的预期变化范围内,因此与标称测试条件非常匹配。图 1 显示第一个条件得到满足。不令人满意的操作示例包括两侧的平均流速为 3.2 加仑/分钟,或分散范围为 3.0 至 4.0 加仑/分钟。
图 1 还显示流量满足条件三。虽然数据中有少量分散,但正如预期的那样,长期趋势非常稳定,大约在 3.5 加仑/分钟左右。例如,如果在回到设定流速之前,流速暂时降至 3.0 加仑/分钟,则认为测试不令人满意。
Figure 1: Flow Rate Data from an Example Data Set
图 2 用于温度数据的相同目的。示例数据假设热端入口温度为 100.4°F,冷端入口温度为 50°F。与流量数据一样,如果记录的入口温度接近这些标称条件,且在试验的稳态部分没有显著变化,则认为试验有效。这两个条件都满足,因此该图表明记录的温度满足条件二和条件三。
Figure 2: Temperature Data from an Example Test
图 3 显示了热交换器的计算效率图。根据第 2 部分中显示的技术,该数据集经过过滤,仅显示阀门切换到测试流量后的数据。该数据明显围绕 0.34 的效率等级波动,存在一些变化。这种变化是意料之中的,因为温度和流速数据都有一些变化。最初的几个数据点清楚地表明,当过滤器第一次应用时,该装置处于过渡期,但是只有几个,所以对计算的平均效率的影响是最小的。除了这些开始点之外,所呈现的效果是相当稳定的。该图证实了该数据集满足条件四和条件五。
Figure 3: Effectiveness Data from an Example Test
有了这三个图,用户只需主动参与几秒钟,就能确保测试正确执行,数据有效。在自动数据分析程序中包含创建和保存所需图的部分是确保数据集质量的非常有效和高效的方法。
自动数据检查器
检查测试中数据质量的最详细和自动化的方法是创建一个自动化的数据检查器。这是一个脚本,它检查测量数据以确定记录了什么,将其与标称测试条件进行比较,确定它们是否可接受,并向用户报告不可接受的结果。这对于用户来说是有利的,因为它限制了需要手动检查的图的数量。具有数百个测试的项目可以很容易地产生数千个图,减少需要审查的数量可以节省大量的时间、繁琐和项目预算。
以下代码提供了如何完成此过程的示例。假设程序已经有了一个名为“Temp”的数据帧来临时存储关于可疑结果的信息,还有一个名为“SuspiciousTests”的数据帧来存储完整的列表。
if abs(Temperature_Hot — np.mean(Data[‘Hot Inlet Temperature (deg F)’])) > Threshold_Difference_Temperature:Temp.loc[0, ‘Filename’] = filenameTemp.loc[0, ‘Test Parameters’] = ‘H’ + str(Flow_Hot) + ‘-C’ +
str(Flow_Cold) + ‘-T’ +str(Temperature_Hot)Temp.loc[0, ‘Code’] = ‘Temperature_HotInlet_Avg’Temp.loc[0, ‘Value’] = np.mean(Data[‘Hot Inlet Temperature (deg
F)’])SuspiciousTests = SuspiciousTests.append(Temp)SuspiciousTests.to_csv(r'C:\Users\JSmith\DataAnalysis\Suspicious
Tests.csv', index = False)
该代码的工作方式如下。
1.首先,它将标称热端入口温度 Temperature_Hot 与测得的平均热端入口温度进行比较。如果差值大于用变量 Threshold _ Difference _ Temperature 设置的预定值,则确定测试有问题。
2.如果测试有问题,它会记录测试的参数。这些参数包括文件名、标称测试条件、代表未满足测试条件的代码以及该条件的测量值。这些条目都被添加到可疑测试数据框中。
3.程序处理完所有数据后,可疑测试会打印到一个. csv 文件中,并记录下哪些测试似乎不令人满意。
该示例显示了单次检查,将平均热端入口温度与测试的标称条件进行比较。一个完整的程序将包括对其他测试参数的检查,以及对标准偏差的检查,以确保所有参数都是稳定的。
通常,在创建自动数据检查算法时,最好记住以下准则:
- 它应该检查所有标称测试条件,以确保它们在平均值和标准偏差方面都是足够的,
- 它应该检查任何过滤器的结果,以确保它们捕捉到正确的数据范围,
- 它应检查最终计算的输出,以确保其在预期范围内,并确保测试提供了可靠的信号,以及
- 在被信任之前,需要对它进行彻底的检查,以确保它识别出有问题的测试,而不是足够的测试。
后续步骤
到目前为止,文章中提供的内容已经教会了您如何为自动化构建数据集,自动打开和分析所有文件,以及检查数据集的错误。下一步是以一种允许你自然发展回归的方式存储这些结果。这将在我的下一篇文章中讨论。
调试神经网络的清单
您可以采取切实可行的步骤来识别和解决机器学习模型的训练、泛化和优化问题
Photo by Glenn Carstens-Peters on Unsplash
众所周知,机器学习代码很难调试,因为寻找错误的代价很高。即使对于简单的前馈神经网络,你也经常不得不围绕网络架构、权重初始化和网络优化做出几个决定——所有这些都可能导致你的机器学习代码中潜在的错误。
正如 Chase Roberts 在一篇关于“如何对机器学习代码进行单元测试”的优秀文章中所写的那样,他的挫折源于常见的陷阱,比如:
- 代码不会崩溃,不会引发异常,甚至不会变慢。
- 网络仍在训练,损失仍会下降。
- 几个小时后,这些值收敛,但结果很差
那么,对此应该做些什么呢?
本文将提供一个框架来帮助您调试您的神经网络:
- 开始简单
- 确认你的损失
- 检查中间输出和连接
- 诊断参数
- 跟踪你的工作
请随意跳到特定部分或通读下面的内容!请注意:我们不涉及数据预处理或具体的模型算法选择。网上有很多关于这些主题的资源(例如,查看‘选择正确的机器学习算法’)。
1.从简单开始
具有带正则化和学习率调度器的复杂架构的神经网络将比简单网络更难调试。我们在第一点上有点欺骗,因为它与调试你已经建立的网络并不真正相关,但它仍然是一个重要的建议!
从简单开始:
- 首先构建一个更简单的模型
- 在单个数据点上训练您的模型
先建立一个更简单的模型
首先,构建一个只有一个隐藏层的小型网络,并验证一切都正常工作。然后逐渐增加模型的复杂性,同时检查模型结构的每个方面(附加层、参数等)…)在继续前进之前起作用。
在单个数据点上训练您的模型
作为快速的健全性检查,您可以使用一两个训练数据点来确认您的模型是否能够过度拟合。神经网络应该立即以 100%的训练精度和与你的模型随机猜测相称的验证精度过度拟合。如果你的模型不能适应这些数据点,那么要么它太小,要么有一个错误。
即使你已经验证了你的模型是有效的,在继续之前尝试训练一个(或几个)时期。
2.确认你的损失
模型的损失是评估模型性能的主要方式,也是模型评估以设置重要参数的内容,因此您需要确保:
- 损失适合于任务(对于多分类问题使用类别交叉熵损失,或者使用焦点损失来解决类别不平衡)
- 你的损失函数正在正确的尺度上被测量。如果您在网络中使用了一种以上的损失类型,如 MSE、对抗性、L1、特征损失,那么请确保所有损失都被适当地缩放到相同的数量级
注意你最初的损失也很重要。如果你的模型是通过随机猜测开始的,检查初始损失是否接近你的预期损失。在的斯坦福 CS231n 课程作业中,安德烈·卡帕西提出了以下建议:
寻找正确的机会表现损失。当你用小参数初始化时,确保你得到了你期望的损失。最好先单独检查数据丢失(所以把正则化强度设置为零)。例如,对于具有 Softmax 分类器的 CIFAR-10,我们预计初始损失为 2.302,因为我们预计每个类别的扩散概率为 0.1(因为有 10 个类别),Softmax 损失是正确类别的负对数概率,因此:-ln(0.1) = 2.302。
对于一个二进制的例子,你可以简单地为你的每个类做一个相似的计算。假设您的数据中有 20%为 0,80%为 1,那么您的预期初始损耗将为 0.2 ln(0.5)0.8 ln(0.5)= 0.693147。如果您的初始损失远大于 1,这可能表明您的神经网络权重没有正确平衡(即,您的初始化很差)或您的数据没有标准化。
3.检查中间输出和连接
若要侦错类神经网路,瞭解类神经网路内部的动态、个别中间层所扮演的角色,以及各层之间的连接方式,通常会很有用。您可能会在以下方面遇到错误:
- 梯度更新的表达式不正确
- 未应用权重更新
- 消失或爆炸渐变
如果您的梯度值为零,这可能意味着优化器中的学习率太小,或者您遇到了上面的错误#1,梯度更新的表达式不正确。
除了查看梯度更新的绝对值之外,确保监控每个层匹配的激活、权重和更新的幅度。例如,参数(权重和偏差)的更新幅度应该是 1-e3 。
有一种现象称为“死亡 ReLU”或“消失梯度问题”,其中 ReLU 神经元在学习了其权重的大的负偏差项后将输出零。这些神经元再也不会在任何数据点激活。
您可以通过使用数值方法近似梯度,使用梯度检查来检查这些错误。如果它接近计算的梯度,则反向传播被正确地执行。要实现渐变检查,请查看 CS231 这里和这里以及吴恩达关于该主题的具体课程中的这些伟大资源。
Faizan Shaikh 讲述了可视化神经网络的三种主要方法:
- 初步方法 —简单的方法,向我们展示一个训练好的模型的整体结构。这些方法包括打印出神经网络各层的形状或过滤器以及每层中的参数。
- 基于激活的方法 —在这些方法中,我们破译单个神经元或一组神经元的激活,以获得它们正在做什么的直觉
- 基于梯度的方法— 这些方法倾向于在训练模型(包括显著性图和类别激活图)时操纵由正向和反向传递形成的梯度。
有许多有用的工具用于可视化各个层的激活和连接,如 ConX 和 Tensorboard 。
A sample dynamic, rendered visualization made with ConX
处理图像数据?Erik Rippel 在“使用 Keras 和 Cats 可视化部分卷积神经网络”上发表了一篇精彩多彩的文章
4。诊断参数
神经网络有大量相互影响的参数,使得优化变得困难。请注意,这是一个活跃的研究领域,所以下面的建议只是一个起点。
- 批量(技术上称为小批量)—您希望批量足够大,以获得准确的误差梯度估计,但又足够小,以使小批量随机梯度下降(SGD)可以调整您的网络。小批量将导致学习过程以训练过程中的噪音为代价快速收敛,并且可能导致优化困难。论文‘关于深度学习的大批量训练:泛化差距和尖锐极小’描述了如何:
在实践中已经观察到,当使用较大批量时,模型的质量会下降,这通过其概括能力来衡量。我们调查了大批量模式中这种泛化能力下降的原因,并提供了支持以下观点的数字证据:l 大批量方法倾向于收敛到训练和测试函数的尖锐极小值,众所周知,尖锐极小值导致较差的泛化能力。相比之下,小批量方法始终收敛于平坦极小值,我们的实验支持一个普遍持有的观点,即这是由于梯度估计中的固有噪声。
- 学习率—学习率太低会导致收敛缓慢或陷入局部最小值的风险,而学习率太大会导致优化发散,因为你有跳过损失函数更深但更窄部分的风险。考虑纳入学习率计划,以随着培训的进展降低学习率。CS231n 课程有很大一部分是关于实现退火学习率的不同技术。
Keras、Tensorflow、PyTorch、MXNet 等机器学习框架现在都有关于使用学习率调度器/decay 的文档或示例:
https://keras.io/callbacks/#learningratescheduler
tensor flow—https://www . tensor flow . org/API _ docs/python/TF/train/exponential _ decay
py torch—https://py torch . org/docs/stable/_ modules/torch/optim/lr _ scheduler . html
- 梯度剪辑 —这将在反向传播过程中以最大值或最大范数剪辑参数的梯度。有助于解决您在上述步骤 3 中可能遇到的任何爆炸渐变
- 批量标准化—批量标准化用于标准化每一层的输入,以对抗内部协变量偏移问题。如果您同时使用 Dropout 和 Batch Norma,请务必阅读以下关于 Dropout 的要点。
这篇文章来自di shank Bansal’tensor flow 中批处理规范的缺陷和训练网络的健全性检查’,是批处理规范化常见错误的重要资源。
- 随机梯度下降(SGD) —有几种风格的 SGD 使用动量、自适应学习率和内斯特罗夫更新,在训练性能和泛化能力方面没有明显的赢家(参见 Sebastian Ruder 的精彩文章‘梯度下降优化算法概述’和这个有趣的实验’SGD>亚当?))一个推荐的起点是具有内斯特罗夫动量的亚当或普通新币。
- 正则化-正则化对于构建概化模型至关重要,因为它会增加模型复杂性或极端参数值的损失。它显著降低了模型的方差,而没有显著增加其偏差。如cs 231n 课程所述:
通常情况下,损失函数是数据损失和正则化损失之和(例如,L2 权重罚)。需要注意的一个危险是,正则化损失可能会超过数据损失,在这种情况下,梯度将主要来自正则化项(通常具有简单得多的梯度表达式)。这可以掩盖数据丢失梯度的不正确实现。
要对此进行审核,您应该关闭正则化并独立检查您的数据丢失梯度。
- 辍学——辍学是另一种规范你的人际网络以防止过度适应的方法。在训练时,仅通过以某个概率 p(超参数)保持神经元活动来实现退出,否则将其设置为零。结果,网络必须在每个训练批次中使用不同的参数子集,这减少了特定参数的变化相对于其他参数变得占优势。
- 这里重要的一点是:如果你同时使用丢弃和批处理规范化(批处理规范),要注意这些操作的顺序,甚至是同时使用它们。这仍然是一个活跃的研究领域,但你可以看到最新的讨论:
From Stackoverflow 用户
MiloMinderBinder
:“Dropout 是指完全阻断某些神经元的信息,以确保神经元不协同适应。因此,批处理规范化必须在丢失之后进行,否则您将通过规范化统计传递信息。”From arXiv : 通过方差移位理解丢失和批量归一化之间的不协调( 李翔,硕辰,胡小林,杨坚)——“理论上,我们发现当我们将那个网络的状态从训练转移到测试时,丢失会使特定神经单元的方差发生移位。然而,在测试阶段,BN 将保持其从整个学习过程中积累的统计方差。方差不一致性(我们称此方案为“方差移位”)导致推理中不稳定的数值行为,当在 BN 之前应用丢失时,最终导致更多的错误预测
5.跟踪您的工作
人们很容易忽视记录实验的重要性,直到你忘记了你使用的学习率或班级权重。有了更好的跟踪,你可以很容易地回顾和重现以前的实验,以减少重复工作(也就是遇到同样的错误)。
然而,手动记录信息可能很难做到,也很难扩展到多个实验。像comet . ml这样的工具可以帮助自动跟踪数据集、代码变更、实验历史和生产模型(这包括关于您的模型的关键信息,如超参数、模型性能指标和环境细节)。
您的神经网络可能对数据、参数甚至包版本的微小变化非常敏感,从而导致模型性能下降。跟踪您的工作是开始标准化您的环境和建模工作流的第一步。
Check out model performance metrics and retrieve the code used to train the model from within Comet.ml. There’s an example of Comet’s automatic experiment tracking here.
快速回顾
我们希望这篇文章为调试你的神经网络提供一个坚实的起点。为了总结要点,您应该:
- 从简单开始— 首先构建一个更简单的模型,通过训练几个数据点进行测试
- 确认你的损失——检查你是否使用了正确的损失,并回顾你的初始损失
- 检查中间输出和连接— 使用梯度检查和可视化来检查您的层是否正确连接,以及您的梯度是否按预期更新
- 诊断参数 —从 SGD 到学习率,识别正确的组合(或找出错误的组合)😅
- 跟踪你的工作——作为基线,跟踪你的实验过程和关键的建模工件
觉得这个帖子有用?觉得它少了点什么?请在下面评论您的反馈和问题!👩🏻🎓
关注黑客新闻上的讨论!
机器学习中特征选择的卡方检验
特征选择在机器学习中一直起着关键作用
image by Vladislav Babienko
我们总是想知道卡方检验在机器学习中的什么地方有用,以及这个检验有什么不同。特征选择是机器学习中的一个重要问题,在机器学习中,我们将有几个特征,并且必须选择最佳特征来建立模型。卡方检验通过检验特征之间的关系来帮助您解决特征选择中的问题。在这篇文章中,我将引导通过
a.卡方分布。
b.特征选择的卡方检验
c.使用 Python 进行卡方检验
卡方分布
如果随机变量ꭓ可以写成标准正态变量的平方和,则它遵循卡方分布。
Z1, Z2… are standard normal variables
自由度:
自由度是指逻辑上独立的值的最大数量,这些值可以自由变化。简而言之,它可以定义为观测值的总数减去施加在观测值上的独立约束的数量。
在上图中,我们可以看到不同自由度的卡方分布。我们还可以观察到,随着自由度的增加,卡方分布接近正态分布。
特征选择的卡方检验
卡方检验在统计学中用于检验两个事件的独立性。给定两个变量的数据,我们可以得到观察计数 O 和期望计数 E。卡方测量期望计数 E 和观察计数 O 如何相互偏离。
让我们考虑一个场景,其中我们需要确定独立类别特征(预测器)和从属类别特征(响应)之间的关系。在特征选择中,我们的目标是选择高度依赖于响应的特征。
当两个特征独立时,观察计数接近预期计数,因此我们将具有较小的卡方值。所以高卡方值表明独立性假设是不正确的。简而言之,卡方值越高,特征越依赖于响应,并且可以被选择用于模型训练。
卡方检验的步骤及示例:
考虑一个数据集,我们必须确定客户离开银行的原因,让我们对两个变量进行卡方检验。客户的性别,值为男性/女性作为预测值, 退出 描述客户是否离开银行,值为是/否作为响应。在这个测试中,我们将检查性别和 Exited* 之间是否有任何关系。*
执行卡方检验的步骤:
- 定义假设。
- 建立一个应急表。
- 求期望值。
- 计算卡方统计量。
- 接受或拒绝零假设。
1.定义假设
零假设(H0):两个变量是独立的。
替代假设(H1):两个变量不是独立的。
2.相依表
显示一个变量在行中的分布和另一个变量在列中的分布的表格。它用于研究两个变量之间的关系。
Contingency table for observed values
列联表的自由度给定为(r-1) * (c-1),其中 r,c 是行和列。这里 df =(2–1)(2–1)= 1。*
在上表中,我们已经算出了所有的观察值,我们的下一步是找到期望值,获得卡方值并检查关系。
3.求期望值
基于两个变量独立的零假设。我们可以说如果 A,B 是两个独立的事件
让我们来计算第一个细胞的期望值,这是那些男性,并从银行退出。
The calculation for the expected value
类似地,我们计算 E2,E3,E4,得到如下结果。
Expected values
4.计算卡方值
将观察值和计算出的期望值汇总成表格,并确定卡方值。
**
我们可以看到,通过使用卡方统计公式,卡方被计算为 2.22。
5.接受或拒绝零假设
在α= 0.05 的 95%置信度下,我们将检查计算的卡方值落在接受或拒绝区域。
自由度=1(用列联表计算)且 alpha =0.05,卡方值为 3.84。
卡方值可通过卡方表确定。
卡方分布位于右侧,因为观察值和期望值之间的差异很大。
在上图中,我们可以看到卡方的范围从 0 到 inf,α的范围从 0 到 1,方向相反。如果卡方值落在误差区域(α从 0 到 0.05),我们将拒绝零假设。
这里我们接受零假设,因为卡方值小于临界卡方值。
为了得出这两个变量是独立的结论,性别变量不能被选择用于训练模型。
限制
卡方对表格单元格中的小频率很敏感。通常,当表的某个单元格中的期望值小于 5 时,卡方检验会导致结论错误。
注意:这里我们考虑的是大小为 400 的样本,对于更大的样本,结果可能会有所不同。
使用 Python 进行卡方检验
下面是关于如何使用 python 执行卡方测试的代码。
你也可以在 GitHub 上找到同样的内容。
到目前为止,我们已经了解了分类反应和分类预测,但如果我们有连续反应和分类预测呢???我们将使用方差分析。请查看我的文章 ANOVA,了解机器学习中的特征选择。
如果你好奇想了解特征选择方法。下面是文章的深度。
*【https://neptune.ai/blog/feature-selection-methods *
方差分析在特征选择中的应用
towardsdatascience.com](/anova-for-feature-selection-in-machine-learning-d9305e228476)
希望你喜欢!!!请对任何疑问或建议发表评论。*