综合大数据框架和深度学习
Photo from Apache Flink Website
大多数大数据框架软件工程师用 Java 编写,而大多数机器学习,特别是深度学习库的研究人员用 Python 编写。这在双方之间产生了一条有趣的断层线。一方面,我们拥有 Spark、Flink 和 Kafka 等大型数据框架,可以快速高效地处理海量数据集,但缺乏(轻松)训练和加载专门针对大型数据集的高度成功的模型的能力。另一方面,您有强大的框架来轻松实现深层架构,但是,这些框架没有提供将这些模型集成到大规模数据系统的简单方法。弥补这个缺陷并不是一个简单的问题,因为它需要将 Python 中编写的代码转移到 JVM 中。此外,还需要一系列的依赖和预处理。
历史和背景
JVM 上的
追溯到 2005 年 Hadoop 项目的最初形成,大数据框架一直在 Java 虚拟机上生存和发展。当时,Java 和 C++是占主导地位的编程语言之一(特别是在工业界)。因此,Hadoop 将存在于 JVM 上是理所当然的。2009 年,用 Scala 编写的 Apache Spark 出现在伯克利 AMP 实验室。Spark 由于其分布式内存结构,除了提高速度之外,还允许更广泛的计算。大约在同一时间,LinkedIn 出现了 Apache Kafka。Kafka 充当了连接实时数据源的中心框架。此后不久,Flink 在 2010 年作为一种完全基于流的大数据处理方法出现。
其次,Java 中涌现出大量的文件系统和数据库。HDFS、卡珊德拉、Neo4j 都成为了 Java 驱动的大数据文件系统/数据库。ElasticSearch 也主要用 Java 编写,尽管它的 API 允许来自任何语言或命令行的请求。虽然几乎所有的论文都有 Python 库,但是繁重的工作都是用 Java 完成的。
Python 端
与此同时,在这一切进行的同时,机器学习包继续在 Python 中开发。NumPY 是在 90 年代后期建立的,它为后来 Python 中的 DL 开发奠定了基础。尽管现在已被弃用,但 2007 年出现的 Theano 是第一个(2002 年出现的 Lua 中的 Torch)非专有 DL 框架。Theano 是由 MILA 的 Yoshua Bengio 发明的。随着深度学习开始起飞,许多研究人员选择 Python 作为他们的语言。Tensorflow、Keras 和 PyTorch 都迅速成为事实上的深度学习框架。现在很难找到哪个深度学习论文的代码不是用 Python 实现的。
就不能用 API 吗?
一个明显的问题是,为什么不直接使用 API 在 Java 框架和部署的 Python 模型之间进行通信。GraphPipe、Kubeflow 和 TF-Serving 都提供了将模型部署到 API 的方法。API 通常是一个很好的解决方案,特别是对于简单的用例,但是在某些情况下,它们可能会增加延迟。此外,对于流处理,这可能会变得非常复杂。例如,假设您有一个 ML 微服务,它为一个带有 GrahPipe 的模型提供服务。例如,现在从 Flink 调用微服务需要使用 AsyncIO,这可能很难实现。我们现在还必须单独处理 ML 微服务的扩展。此外,在理想情况下,我们可以使用底层数据平台以分布式方式训练模型。这尤其有用,因为这些大数据系统都有易于访问/处理的库来处理数据湖中的数据。然而,在某些情况下,微服务表现很好,因此我们应该总是根据微服务的性能进行基准测试。
持续解决方案
目前,有许多可能的解决方案“正在进行中”,尽管它们都有缺点,有些目前还处于规划阶段。
- PySpark:
Spark 生态系统在整合模型方面取得了重大进展。具体来说, Spark 深度学习旨在让将 DL 模型纳入 Spark 管道变得更加容易。Spark 深度学习 Spark 也投入了大量资源来使其 Python 库 PySpark 获得成功。PySpark 实际上是用 Py4J 编写的,我稍后会讨论这一点。然而,目前没有办法在 Spark 中加载 ONNX 模型。此外,这些技术目前在流设置中不起作用。
2。 阿帕奇光束
Apache Beam 缓慢地继续尝试使其平台与 Python 代码兼容。目前,所有 Python 代码仍处于正式的“测试”阶段。然而,从长远来看,Beam 希望在 Python 中支持 Flink 和 Spark。这肯定会证明是有用的,特别是如果你的公司有一个完整的 Python 堆栈,因为你可以合并 Flink 和其他 Java 技术。
****3。tensor flow Java
Tensorflow 提供了一个 Java 版本的框架,您可以在其中加载 Tensorflow 模型。这对 Tensorflow 很好,但是它不支持其他框架。另外,性能可能不如其他方法好。
****4。【Java 嵌入式 Python (JEP)
Java 嵌入式 Python 或 JEP 允许在 Java 中使用 Python 代码。用户可以调用 Python 方法,并通过实例化的 JEP 类导入 Python 包。这是通过 Java 本地接口 (JNI)完成的,它允许 C 和 C++应用程序调用 JVM 中的应用程序。为了在 Python 中使用 Java,不能从 Python 中启动 JEP。如果您想在 Python 应用程序中使用 Java,这是一个糟糕的选择。在关于预测性维护 D 的演讲中,ongwon Kim 总结说,JEP 通常比使用 TFServing 或 Java Tensorflow API 更快(至少对于 RNN 类型的预测)。
****5。【Py4j(逆))
Py4J 允许在 Python 中使用 Java。Py4J 使用 Java 网关是为了克服与从 Python 调用 Java 相关的问题。这实际上是 PySpark 构建的一个重要部分。从长远来看,为用 Java 编写的框架提供一个有效的 Python 库可能需要以某种方式使用这个框架。
6。 DL4J
Java 深度学习最初是作为 JVM 上 DL 的全面框架。如果您还想完全用 Java 进行模型开发,它仍然是最佳解决方案。但是,它现在也支持将 Keras 模型加载到 Java 中。也许更重要的是,它在 Java 中提供了对各种多维数组的支持(本质上相当于 numpy)。
Java CPPresets 是移植到 Java 的 C/C++包的集合。它也使用 JNI,但主要是直接用于 C++包,而不是 Python。最近,CPPresets 中包含了一个 ONNX 库。使用该库,您可以加载模型并将它们导出为其他格式。然而,目前没有后端,所以没有办法实际运行加载的模型,这显然是有问题的。一个名为 Lantern 的 Scala 库最终可能会为执行模型提供必要的后端,然而这还很遥远。
其他路线
Jython 不再是一个选项,因为它只支持 Python 2.7,不支持 numpy 和许多其他库。
结论
目前,尝试将模型加载到 Java 中有多种选择。然而,不幸的是,目前都没有完成。我目前的建议是,如果要使用 batch Tensorflow,使用 PySpark。流媒体在任何情况下都会更加复杂,因此 DL4J + Keras + Spark 可能是您的最佳选择。如果你需要使用 ONNX,那么 JEP 或者一个 API 是你唯一的选择。目前,我正在整合我的模型不可知预测库,以便与 JEP 一起工作。这应该有望缓解一些与 JEP 有关的繁琐问题。我希望在接下来的几周里有一个使用 JEP 和 Flink 的端到端流示例。
合成数据生成—新数据科学家的必备技能
简要概述为自驱动数据科学项目生成合成数据的方法/包/想法,并深入研究机器学习方法。
介绍
数据是新的石油,说实话,只有少数几个大玩家对这种货币拥有最强的控制力。这个世界的谷歌和 Facebooks 对他们最新的机器学习算法和软件包如此慷慨(他们免费提供这些),因为算法世界的准入门槛现在相当低。开源已经走过了漫长的道路,从被史蒂夫·鲍尔默等人称为邪恶的 T4 到成为微软不可或缺的一部分。大量开源项目正在推动数据科学、数字分析和机器学习的发展。
站在 2018 年我们可以有把握地说, 算法、编程框架、机器学习包(甚至是如何学习这些技术的教程和课程)都不是稀缺资源而优质数据才是。
对于数据科学和机器学习的初学者来说,这通常会产生一个复杂的问题。几年前,当我开始这条道路的旅程时,我自己也面临着这个问题。
让我也非常清楚地表明,在这篇文章中,**我只是在谈论用于学习目的的数据的稀缺性,而不是用于运行任何商业操作。**这不是关于如何为你正在开发的酷炫旅行或时尚应用获取优质数据的讨论。这种消费者、社会或行为数据收集有其自身的问题。然而,即使是像访问高质量数据集这样简单的事情,以开始一个人的数据科学/机器学习之旅,最终也不是那么简单。
对自驱动数据科学至关重要
数据科学热销。而且,人们正在转向数据科学。他们正在改变职业,支付新兵训练营和在线 MOOCs 的费用,在 LinkedIn 上建立关系网。但是,一旦他们通过了正规的课程,进入了一个不确定的领域,许多这样的新人就很难保持学习新技能的动力。
解决什么问题?关注哪个 MOOC?参加什么高尔夫球比赛?学什么新 ML 包?在 Github 上展示什么样的项目?需要掌握多少数学技能?
基本上,如何建立一个伟大的数据科学组合?— 根据一篇非常受欢迎的文章,答案是通过做公共工作,例如,为开源做贡献,展示创新思维和对数据建模、辩论、可视化或机器学习算法的原创贡献。
数据科学怎么找工作?了解足够的统计,机器学习,编程等,能够得到一个…
towardsdatascience.com](/how-to-build-a-data-science-portfolio-5f566517c79c)
但可悲的是,往往没有仁慈的指导或导师,往往,一个人必须自我推动。
据说,能够成功穿越这一灰色地带的人已经在自驱动数据科学领域找到了他/她的魔力。那个人会走得很远。但是,为了使这一旅程卓有成效,他(她)必须能够访问高质量的数据集进行实践和学习。
丰富的学习体验可能需要什么样的数据?
想象一下,你正在摆弄一个很酷的机器学习算法,比如 SVM 或深度神经网络。你应该在什么样的数据集上练习它们?如果您是从零开始学习,建议您从简单的小规模数据集开始,您可以在二维空间中绘制这些数据集,以便直观地理解模式,并以直观的方式亲自查看 ML 算法的工作情况。例如,这里有一篇关于各种数据集的优秀文章,你可以在不同的学习水平上尝试。
[## 24 个终极数据科学项目,提升您的知识和技能(可以免费访问)
www.analyticsvidhya.com](https://www.analyticsvidhya.com/blog/2018/05/24-ultimate-data-science-projects-to-boost-your-knowledge-and-skills/)
这是一个很好的开始。但这还不是全部。
当然,你可以更上一层楼,给自己找一个真实的大型数据集来练习算法。
但那仍然是一个固定的数据集,有固定的样本数,固定的模式,固定的正负样本的类分离度(如果我们假设是分类问题)。
你在学习算法的所有复杂之处吗
大概不会。没有一个数据集能够为给定的 ML 算法提供所有这些深刻的见解。但是,要成为一名真正的机器学习专家,这些都是非常重要的见解。
因此,你将需要一个极其丰富和足够大的数据集,它足够适合所有这些实验。
你能做什么?
那么,在这种情况下你能做什么呢?在互联网上搜寻更多的数据集,并希望其中一些能够揭示与特定算法相关的限制和挑战,并帮助你学习?
是的,这是一种可能的方法,但在时间和精力方面可能不是最可行或最佳的方法。好的数据集可能不干净或不容易获得。你可能会花更多的时间去寻找、提取和讨论一个合适的数据集,而不是花更多的时间去理解 ML 算法。
搜索现实生活中的数据集、提取它、运行探索性数据分析,并与它争论以使其为基于机器学习的建模做好适当准备的经历是无价的。我目前正在写一个关于这个主题的课程/书。
但这可以单独教授和练习。然而,在许多情况下,你可能只是想访问一个灵活的数据集(或几个数据集)来“教”你 ML 算法的所有血淋淋的细节。
令人惊讶的是,在许多情况下,这种教学可以用合成数据集来完成。
什么是合成数据集?
顾名思义,非常明显,合成数据集是以编程方式生成的数据的存储库。所以,它没有被任何现实生活中的调查或实验所收集。因此,它的主要目的是足够灵活和丰富,以帮助 ML 从业者用各种分类、回归和聚类算法进行引人入胜的实验。期望的特性是,
- 它可以是数字、二进制或分类(序数或非序数),
- 特征的数量和数据集的长度应该是任意的
- 优选地,它应该是随机的,并且用户应该能够选择各种各样的统计分布作为该数据的基础,即,潜在的随机过程可以被精确地控制和调整,
- 如果用于分类算法,那么类别分离度应该是可控的,以使学习问题容易或困难,
- 随机噪声可以可控方式插入
- 对于回归问题,一个复杂的非线性生成过程可用于获取数据
虽然在本文中,我们的讨论仅限于更好的 ML 算法的合成数据,但在它有助于解决真实数据集的安全和隐私问题的情况下,它的目的可能是深远的,因为真实数据集不能用于或获取学习目的。例如,想想医疗或军事数据。这里有一篇关于这些方法的精彩总结文章。
在接下来的几节中,我们将展示一些快速生成合成数据集的方法,用于实践统计建模和机器学习。
演示笔记本可以在我的 Github 库 这里找到 。
使用 scikit-learn 方法生成数据
Scikit-learn 是一个了不起的 Python 库,用于经典的机器学习任务(即,如果你不特别关心深度学习)。然而,尽管它的 ML 算法被广泛使用,但它提供的很酷的合成数据生成功能却不太受欢迎。
[## sci kit-learn:Python 中的机器学习
scikit-learn.org](https://scikit-learn.org/stable/)
这里是一个快速纲要,
回归问题生成 : Scikit-learn 的**dataset.make_regression**
函数可以创建任意数量的输入特征、输出目标以及它们之间的信息耦合度可控的随机回归问题。它也可以混合高斯噪声。
Fig: Random regression problem generation using scikit-learn with varying degree of noise.
分类问题生成 :类似于上面的回归函数,**dataset.make_classification**
生成一个随机的多类分类问题(数据集),具有可控的类分离和添加的噪声。如果需要,还可以随机翻转任意百分比的输出符号来创建更难的分类数据集。
Fig: Random classification problem generation using scikit-learn with varying class separation.
聚类问题生成 :生成有趣聚类的函数相当多。最直接的方法是datasets.make_blobs
,它可以生成任意数量的簇,并且距离参数是可控的。
Fig: Simple cluster data generation using scikit-learn.
各向异性集群生成:通过使用矩阵乘法的简单转换,您可以生成沿某个轴对齐或各向异性分布的集群。
Fig: Anisoproically aligned cluster data generation using scikit-learn.
同心环簇数据生成 :对于测试基于相似性的聚类算法或高斯混合模型,以特殊形状生成簇是很有用的。我们可以使用**datasets.make_circles**
函数来完成。
当然,我们可以在数据中混入一些噪声来测试聚类算法的鲁棒性,
月形聚类数据生成 :我们也可以使用**datasets.make_moons**
函数生成用于测试算法的月形聚类数据,噪声可控。
用任意符号表达式生成数据
虽然前面提到的函数从一开始就很棒,用户不容易控制数据生成的底层机制,回归输出也不是输入的决定性函数,它们确实是随机的。虽然这对于许多问题来说可能已经足够了,但人们可能经常需要一种可控的方式来基于明确定义的函数产生这些问题(涉及线性、非线性、理性甚至超越项)。
例如,我们想要评估各种内核化 SVM 分类器在具有越来越复杂分隔符(线性到非线性)的数据集上的功效,或者想要证明线性模型对于由理性或超越函数生成的回归数据集的局限性。使用 scikit-learn 的这些功能很难做到这一点。
此外,用户可能只想输入一个符号表达式作为生成函数(或分类任务的逻辑分隔符)。仅仅使用 scikit-learn 的实用程序很难做到这一点,必须为每个新的实验实例编写自己的函数。
为了解决符号表达式输入的问题,人们可以很容易地利用惊人的 Python 包 SymPy ,它允许理解、渲染和评估符号数学表达式,达到相当高的复杂程度。
在我以前的一篇文章中,我已经详细阐述了如何在 SymPy 库的基础上构建并创建类似于 scikit-learn 中可用的函数,但可以生成具有高度复杂性的符号表达的回归和分类数据集。查看这里的文章和我的 Github 仓库中的实际代码 。
我们描述了如何使用 SymPy,我们可以为多项式(和非线性)回归和…
towardsdatascience.com](/random-regression-and-classification-problem-generation-with-symbolic-expression-a4e190e37b8d)
例如,我们可以将一个符号表达式作为平方项( x )和正弦项(如sin(x))的乘积,并从中创建一个随机回归数据集。
Fig: Randomized regression dataset with symbolic expression: x².sin(x)
或者,可以生成基于非线性椭圆分类边界的数据集,用于测试神经网络算法。注意,在下图中,用户如何输入一个符号表达式 m='x1**2-x2**2'
并生成这个数据集。
Fig: Classification samples with non-linear separator.
使用“pydbgen”库生成分类数据
虽然网上有许多高质量的真实数据集可用于尝试很酷的机器学习技术,但从我的个人经验来看,我发现在学习 SQL 时并非如此。
对于数据科学专业知识来说,基本熟悉 SQL 几乎与知道如何用 Python 或 r 编写代码一样重要。但是访问一个足够大的数据库,其中包含真实的分类数据(如姓名、年龄、信用卡、SSN、地址、生日等)。)远不如访问 Kaggle 上专门为机器学习任务设计或管理的玩具数据集常见。
除了数据科学的初学者之外,即使是经验丰富的软件测试人员也会发现拥有一个简单的工具是有用的,在这个工具中,通过几行代码,他们可以生成任意大的数据集,其中包含随机的(伪造的)但有意义的条目。
输入 pydbgen 。在这里看文档。
这是一个轻量级的纯 python 库,用于生成随机有用的条目(如姓名、地址、信用卡号、日期、时间、公司名称、职位、车牌号等)。)并将它们保存在 Pandas dataframe 对象中,或者作为数据库文件中的 SQLite 表,或者保存在 MS Excel 文件中。
[## pydbgen 简介:一个随机数据帧/数据库表生成器
一个轻量级的 Python 包,用于生成随机数据库/数据帧,用于数据科学、学习 SQL、机器…
towardsdatascience.com](/introducing-pydbgen-a-random-dataframe-database-table-generator-b5c7bdc84be5)
你可以阅读上面的文章了解更多细节。这里,我将通过截图展示几个简单的数据生成示例,
Fig: Generate random names using pydbgen library.
生成几个国际电话号码,
Fig: Generate random phone numbers using pydbgen library.
生成一个完整的数据帧,随机输入姓名、地址、SSN 等。,
Fig: Generate full data frame with random entries using pydbgen library.
总结和结论
我们讨论了在进入令人兴奋的数据科学和机器学习世界的旅程中,访问高质量数据集的重要性。通常,缺乏足够灵活和丰富的数据集限制了人们深入研究机器学习或统计建模技术内部工作的能力,并使理解变得肤浅。
在这方面,合成数据集可以提供极大的帮助,并且有一些现成的函数可以尝试这种方法。然而,有时希望能够基于复杂的非线性符号输入生成合成数据,我们讨论了一种这样的方法。
要为计算机视觉和复杂的人工智能模型生成合成数据,请查看这篇文章。
人工智能和计算机视觉的合成数据终极指南什么是合成数据?合成数据是…
www.simerse.com](https://www.simerse.com/synthetic-data/)
此外,我们还讨论了一个令人兴奋的 Python 库,它可以为数据库技能练习和分析任务生成随机的真实数据集。
本文的目标是展示年轻的数据科学家不必因为没有合适的数据集而陷入困境。相反,他们应该寻找和设计自己的编程解决方案,为他们的学习目的创建合成数据。
一路上,他们可能会学到许多新技能,打开新的机会之门。
喜欢这篇文章吗?成为 中等会员 继续 无限制学习 。如果您使用下面的链接, ,我将收取您的一部分会员费,而不会对您产生额外费用 。
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@tirthajyoti/membership)
大会推特的表格分析
当我在大会上学的时候,我写了一个 python cronjob 来收集来自所有大会地点的推文。我想在课程期间写一篇关于它的博客和作品集,但是所有的测试、项目和其他事情都在进行中,事情远离了我。我最近看了一下 cronjob 收集的信息,我在 3 个月的时间里收到了 5340 条推文。我不应该让这个浪费掉,所以下面是我使用 Tableau 对 GA 的 twitter 策略的探索。如果您想与任何可视化交互,请单击可视化下方的链接。
警告/迷你咆哮
在对收集的信息和这些账户上的实际信息进行抽查比较时,我确实注意到一些推文不见了。这大概是我在 MacBook 上设置 cronjob 的一个功能。我不得不设置一个 cronjob 来收集推文,因为 Twitter 限制了在给定时间内可以收集的数据量。Macbooks 在您关闭时会进入睡眠状态,不会执行您的 cronjobs。当我了解到这一点时,我努力让我的 MacBook 在工作安排时保持打开。通常我会建议将 cronjobs 设置在一个服务器上,或者至少是一个您知道会可靠地开启和唤醒的本地服务器上,但是这些是我必须使用的资源,我觉得这些数据对于这个分析来说已经足够好了。
分析
我认为我的博客中列出的最活跃的校园,哪个 GA 校园最活跃?,也将拥有最活跃的社交媒体账户。我错了——墨尔本在这一时期最活跃,其次是波士顿。这有点道理,因为发推特不需要任何成本,但我认为有更多活动的校园会有更多的推特。
随着时间的推移查看推文,你可以看到什么校园在什么时候最活跃。例如,墨尔本在 6 月 8 日有很多活动,原因是看起来他们那天有一个基于推特语言的活动。
BufferApp 是 GA 最喜欢的推文模式。当我在 GayTravel.com 做社交媒体实习生的时候,他们最喜欢的模式是排在第二位的 Tweetdeck。
推文看起来很协调。在清理了自定义网址的推文后,5340 条中有 2339 条(44%)是唯一的。最受欢迎的推文是“雇主(像 GA!)提供丰厚的额外津贴来留住 Y 世代员工:“这段时间有 34 条推文进来。原因是这种联系导致《每日电讯报》发表了一篇报道,强调了在 GA 工作的一些额外津贴。看起来像是在 6 月 3 日和 6 月 16 日有一场通过所有校园推特账号发布这条推文的运动。我不怪 GA 宣传这份好报纸——根据你在 GA 工作第三年的文章,你有为期两周的带薪假期,包括酒店和机票!
大会有几个课类型包括 web 开发,移动开发,UX,数据科学(我毕业的那个)。UX 似乎肯定是通过标签宣传最多的(#UX、#UXDesign、#UXdesign、#ux、# UXDesign)。
就提及次数而言,GA_Denver 被提及次数最多。这并不是因为 GA 的其他校园在推广丹佛校园,而是 GA_Denver 转发了任何提到他们的人。
如果你想知道这些数据是如何收集的,或者你想要这些数据的平面文件,这里有 GitHub 链接。
R 中类似 Tableau 的拖放 GUI 可视化
Tableau 和 Qlik 等自助式数据可视化工具提供了 R 和 Python 等复杂的数据科学语言所不提供的少数几个功能之一,即创建可视化的拖放 GUI。您可以简单地拖放您的维度和度量标准,这种灵活性是如此直观,以至于没有技术经验的高中生也可以构建一个像样的可视化。
如果你是一个 R 用户,并且你一直羡慕他们,这里有一个神奇的工具——esquisse——它就在你的 RStudio 中,帮助你用拖放 GUI 构建 ggplot2 。(顺便说一下,这非常直观,Python 用户也能做到!)
关于 esquisse:
这个新的 R 包esquisse由法国公司 DreamRs 创建并开源,该公司已经开源了多个像这样有用的 R 包。
如文档中所述,
esquisse 允许您通过用 ggplot2 软件包可视化数据来交互式地浏览数据。它允许您绘制条形图、曲线、散点图、直方图,然后导出图表或检索生成图表的代码。
安装&装载
esquisse 在起重机上可用,因此可使用以下代码进行安装:
# From CRAN
install.packages("esquisse")
或者您可以使用以下代码安装 github 上的开发版本。
# with remotes
remotes::install_github("dreamRs/esquisse")
# or with install-github.me service (based on remotes)
source("https://install-github.me/dreamRs/esquisse")
# or with devtools:
devtools::install_github("dreamRs/esquisse")
拖放可视化
正如我们从一开始就知道的,这个软件包 esquisse 帮助我们通过拖放来生成可视化(ggplot2 ),我们将看到如何做同样的事情。
首先,我们将使用 R 包itunesr
提取一些应用评论(在本例中,是印度电子零售商 Flipkart 的 iOS 应用),并尝试使用我们的拖放 GUI 进行可视化。
#loading tidyverse to read inputlibrary(tidyverse)# loading itunesr for retrieving itunes review data that we will use in this analysislibrary(itunesr)#loading the magical esquisse librarylibrary(esquisse)# Flipkart Reviewsreviews <- getReviews(742044692,'in',1)#converting Rating to numeric typereviews$Rating <- as.numeric(reviews$Rating)#let us say we want to see if there's any correlation between rating and review lengthreviews$len <- nchar(reviews$Review)
上面的想法很简单。
- 我们正在加载所需的包
- 使用
itunesr
获取数据 - 将变量
Rating
转换为数值并计算len
中的审核长度的一些数据准备
这样,我们就可以用下面的代码开始我们的拖放之旅了。
#let the magic beginesquisse::esquisser(reviews)
正如您在上面看到的,函数esquisser
将我们想要可视化的数据帧作为参数,如果没有提供任何参数,它会将当前 R 环境空间中的数据帧视为选项。如果在当前的 R 环境空间中没有数据帧,那么就提供像diamond
这样的内置数据集。
从这一点来说,它将是基于 GUI 的动作,因此我为这篇文章创建了以下视频——解释如何使用拖放 GUI 创建 ggplot2 可视化,并最终复制所创建的绘图的 R 代码。
复制的代码如下:
#copied codeggplot(data = reviews) +
aes(x = len, y = Rating) +
geom_point(color = '#e31a1c') +
labs(title = 'Ratings vs Reviews Length',
x = 'Length of Review',
y = 'Rating associated with Review',
caption = 'Data Source: App Store',
subtitle = 'Flipkart iOS App Reviews') +
theme_linedraw()
这给出了下面的图:
尽管上面的情节并不花哨,但这是一个完整的情节,我的意思是,有右轴标签和细节,如标题、副标题和说明。
我认为这个包肯定会节省很多时间,也为 EDA 期间的分析师提供了更多的可能性。如果你想创建这样的解决方案,你可以从 Datacamp 的用闪亮的课程用 R 构建 Web 应用程序中学到更多。这里使用的完整代码可以在我的 github 上获得。
免费注册接收我的数据科学简讯——人工智能
探索性数据分析表
Photo by Stephen Dawson on Unsplash
任何数据科学项目最重要的一步是进行探索性数据分析(EDA)。根据约翰·图基的说法,
“探索性数据分析是一种态度,一种灵活的状态,一种寻找我们认为不存在的东西以及我们认为存在的东西的意愿”
EDA 是在做机器学习模型之前执行的步骤,它提供了关于数据当前状态的有价值的见解。它可以揭示导致数据的数据管道中的代码错误,也有助于可视化数据中的异常值。
实现 EDA 的方法有很多,最常见的方法是使用 matplotlib、Seaborn 等库。我更喜欢使用 Tableau 来执行 EDA,然后如果需要,使用库来获得任何可视化,这不是作为软件的一部分。在这里,我将带你了解我如何使用 Tableau 进行单变量和双变量分析。Tableau 是一款免费软件,可从这里下载。
单变量分析
单变量分析简单地说就是一次只看一个变量,试图理解它的均值、中值、方差和分布等。可视化分布的最简单方法是使用直方图和箱线图。
直方图和箱线图
在 tableau 中创建直方图非常简单。
- 从左侧窗格的功能列表中拖动一个功能。
- 默认情况下,如果要素是一个测量值(如一组数值),Tableau 会将值聚合为 sum 或 count。确保取消选中分析选项中的聚合度量,如下所示。
3.从可用的可视化效果中选择直方图。
4.产生如下所示的直方图。如果 x 轴上的变量不是分类变量。Tableau 会自动将它们转换为垃圾箱,这是一个很大的增值。
4.对于箱形图,选择以下选项。
双变量分析
双变量分析涉及对两个变量(通常表示为 X 、 Y )的分析,目的是确定它们之间的经验关系。
Photo by Chris Liverani on Unsplash
散点图
散点图是进行双变量分析和可视化两个变量之间关系的最佳方式。
按照以下步骤在 Tableau 中创建散点图。
- 将 x 变量拖到“列”窗格中。
- 将 y 变量拖到行窗格中。
- 默认情况下,如果要素是一个测量值(如一组数值),Tableau 会将值聚合为 sum 或 count。确保取消选中分析选项中的聚合度量,如下所示。
4.使用趋势线突出显示数据中有趣的趋势。
将所有内容整合在一起(仪表板)
Photo by Marek Szturc on Unsplash
一旦对数据集中的每个要素执行了上述步骤,您可能会得到大量的表,而将这些表集中到一个视图中的简单方法是使用仪表盘。创建仪表板
- 选择新仪表板
2.只需从左侧的工作表窗格中逐个添加您创建的工作表。
结论
通常 EDA 步骤会被忽略,但这一步是找出最佳模型的最重要步骤之一。EDA 可以显示数据是线性分布还是非线性分布,这可以提供关于哪个模型最适合数据集的宝贵见解。
如有任何反馈或问题,欢迎随时联系我 LinkedIn
加速和高精度处理大数据
Fast Machine Learning
监督模型用于预测业务成果,其中我们已经有了对历史数据集的响应。几个例子是线索转换,正确的广告位置,员工流失和它的许多应用。拥有大型数据集可以带来更高的准确性,从而带来更好的预测和更高的盈利能力或业务成功。但线性模型表现有限,落后于非线性模型,如梯度树提升、随机森林、SVM、深度学习等。我们将讨论梯度树提升算法,因为它给出了最好的结果之一。
梯度推进
梯度树提升是一种预测算法,通过解决无限维优化问题,以决策树的线性组合的形式顺序产生模型。但是训练这些数据需要大量的时间,因为我们需要调整参数来找到准确的模型。有一种方法可以提高训练速度,那就是加速。
With Acceleration and Without Acceleration
内斯特罗夫加速
加速是优化技术中的一个一般概念,我们试图快速达到方程的最小值。内斯特罗夫加速度一般用于加速训练。如果我们对寻找 f(x)的最小值感兴趣,我们使用下面的等式来寻找最小值
其中 w 是步长。
加速梯度推进
我们可以将梯度提升与加速度相结合,其中顺序拟合值知道梯度并被视为权重和。我们使用了两个真实世界的数据集来展示性能:-
数据集的来源-https://archive.ics.uci.edu/ml/datasets.html
犯罪数据集
原始数据集有 1993 个实例和 128 个要素,其中的响应是每个人口的暴力犯罪。31 个变量有 85%缺失,因此从数据集中丢弃。
下面是带加速和不带加速的梯度助推的性能对比。
船舶推进装置的视情维护-数据集
原始数据集有 11934 个实例和 16 个特征,其中压缩机衰变状态系数和涡轮机衰变状态系数是响应。我们使用涡轮机衰变状态系数作为响应。
在这两个例子中,我们假设收缩= 0.01,最大深度= 4,每个节点的最小观察值= 10。
我们可以清楚地看到,迭代次数可以减少到 10 倍,同时保持精度,对于示例 2 甚至更高的精度。
进一步工作
我们可以进一步研究加速梯度增强的性质,同时改变超参数,如收缩和终端节点。已经表明它对收缩不太敏感。
参考文献
[1] G. Biau,B. Cadre 和 L. Rouviere,“加速梯度推进”,arXiv:1803.02042 [stat .2018 年 3 月。
[2] Friedman,Jerome h . Greedy function approximation:一种梯度推进机。安。统计学家。29 (2001 年),第 5 号,1189-1232。doi:10.1214/aos/1013203451。
[3]内斯特罗夫。一种求解凸规划问题的方法,收敛速度为 o (1/k2)。苏联数学多克拉迪,第 27 卷,372-376 页,1983 年。
解决 Quora 问题数据集
语义相似性基本上是决定两个文档彼此有多相似,评估它对于识别重复帖子、半监督标签、两篇新闻文章是否谈论同一件事以及许多其他应用非常有用。因此,当 Quora 在一月份发布了一个潜在重复问题的数据集时,我非常感兴趣,我决定看看我是否可以快速建立一个合理的方法。TL;大卫:得到有效的东西很容易,但是得到真正有效的东西很难——但是我越来越接近了。
预处理
该文件包含大约 405,000 个问题对,其中大约 150,000 个是重复的,255,000 个是不同的。这种类的不平衡直接意味着,只要在每条记录上返回“distinct ”,就可以获得 63%的准确率,所以我决定平衡这两个类,以确保分类器真正学到了一些东西。我还必须纠正 TSV 格式的一些小问题(本质上,一些问题包含了不该包含的新行,这扰乱了 Python 的 csv 模块)。然后我使用 twokenize.py 对数据进行了标记化,这是 CMU 的 ark-tweet-nlp 标记器的一个端口,其中做了一些修改,增加了对 Python 3 的支持。使用这个标记器没有特别的要求,但是我发现它在 tweets 和大多数你可以在网上找到的其他非正式文本上表现得相当好。
基线
当一个简单的解决方案可以解决问题时,没有必要一头扎进一个复杂的解决方案,所以为了获得一个合理的基线,我决定使用一个标准的单词袋方法,同时使用线性和朴素贝叶斯分类器。scikit-learn 可以轻松处理这种事情,它的训练速度非常快,实际上很难击败——线性模型在自我评估中达到了大约 81%的准确率,这使它达到了我在深度模型中达到的最高水平。
Baseline assessment script.
德拉库拉
我以前写过关于 Dracula 的文章——它是一个字符级的自然语言模型,通过双向 LSTMs 构建更高级别的单词和文档表示。自从我上一次写这篇文章以来,我已经稍微改变了设计,去掉了特别昂贵的字符级 LSTMs,代之以卷积层:这导致了更大的单词级表示,并且看起来比旧方法稍微更准确,至少在 Twitter 词性标注方面。在此基础上需要的唯一修改是 1)同时对两个问题重复该模型,以产生文档级向量,以及 2)最终分类层,其将两者结合起来,以产生重复/不重复答案。我尝试了两种不同的方法来得出最终答案:
- 模型 1 使用标准的 softmax 层,它可以被解释为每个类的概率度量。这种情况下的成本函数是标准平均 softmax 交叉熵。
- 模型 2 将每个文档向量折叠成 128 个条目,然后使用欧几里德距离来比较它们。本来想用余弦距离,但是这个好像训练起来有难度。为了构建成本函数,我反转了标签(因此 1 变成了“不相关”,0 变成了“重复”),并对预测距离与标签进行了均方误差分析。相似的问题逐渐获得相似的表示,而不相关的问题则没有,同时保持合理的权重。
Pretty messy high-level overview of model 2: two source documents are run through identical Dracula models, and the final document vectors are compared with Euclidean distance.
The core of the model — most of the other code in the repository is just data and IO.
比较
Dracula 的一个问题是,它非常慢,并且需要花费许多小时来运行数据集的一遍,所以为了保持我的性情,我选择报告 50:50 平衡训练的模型的准确性,以及保留的评估和测试集,以及原始文件的一个小样本(我称之为猜测集),以了解它处理类不平衡的情况。评估集和测试集的区别在于,评估集是在训练 时使用的,以确保模型不会过度拟合训练数据,并让我了解模型是否在学习一些东西;而测试数据在训练期间根本不使用,纯粹代表模型的性能。评估不用于基线训练,但显示模型在 50:50 班级平衡时的表现。猜测集是从原始文件中提取的,具有正确的类别比例,因此它可能包含训练、评估和测试数据,以及新的示例。事情是这样的:
如前所述,基线在自我评估下表现得相当好,但是对于看不见的例子似乎表现得很差。这可能是因为它使用了一个热门词嵌入,这可能意味着它不能很好地概括新的例子。即便如此,67%也不应该被低估,因为它训练起来非常容易和快速——而且通过一些额外的功能工程,它可以很容易地变得更好。模型 1 似乎在看不见的例子上做得更好,但是仍然显示出过度拟合的迹象——我的假设是分类层很难将输入其中的两个文档向量关联起来。模型 2 在最初的试验中表现得特别好:由于每个字符只有 8 个浮点数的嵌入大小,它在看不见的例子上比模型 1 表现得更好,当用更大的嵌入大小重新训练时,它表现得甚至更好。也就是说,它仍然是最有趣的变体——它提供了良好的准确性和快速(相对而言)的训练,而文件大小不到 64 浮点模型的 1%。
将来的
因为我的时间和资源有限,所以我可以做很多超参数优化——特别是改变双向字级 LSTMs 的数量,并试验卷积层的数量和大小。我对谷歌在上周的 TensorFlow 开发峰会上宣布的 Tensorboard 中增加的功能感到兴奋,这些功能基本上允许你为一系列超参数试验绘制有趣的指标,以及他们的新部署选项。我还想扩展训练数据,以纳入更多的重复问题数据集,以及额外的短文档相似性任务。
密码
所有三个模型和基线的代码都在 Github 上:
有关下载模型的说明,请查看 README.md 文件。
Tag2Image 和 Image2Tag —图像和文本的联合表示
对人类来说,解析一个复杂的场景并描述其内容并不是一项复杂的任务。的确,人们可以用几句话迅速概括一个复杂的场景。但是对计算机来说要复杂得多。为了生产能够实现这一点的系统,我们需要结合计算机视觉和自然语言处理领域的最新技术。
作为第一步,我们将了解如何为视觉图像和文本数据生成特征向量。然后描述 CCA 算法,它将帮助我们在一个公共空间中连接构造的特征。最后,在微软 COCO 数据集上呈现两条流水线( Text2Image 和 Image2Text )的结果。
迁移学习
图像特征
卷积神经网络(CNN)可用于从图像中提取特征。在 ImageNet 上预训练的 16 层 VGGNet 就是一个例子。这是 2014 年 ImageNet 挑战赛中最先进的模型。我们只需要移除最后一个完全连接的层,并将 CNN 的其余部分视为数据集的固定特征提取器。这将为每个图像计算 4096-D 向量。
VGG-16 Architecture
标签功能
单词嵌入是一组自然语言处理工具,旨在将单词映射到一个高几何空间。换句话说,单词嵌入功能将文本语料库作为输入,并产生单词向量作为输出,使得任意两个向量之间的距离将捕获两个相关单词之间的部分语义关系。
例如,“学生”和“飞机”是语义不同的词,所以合理的嵌入空间应该将它们表示为相距很远的向量。但是“早餐”和“厨房”是有关联的词,所以需要紧密嵌入。
Word embedding space example
为了实现这种映射,我们可以使用任何最先进的预训练模型:Word2Vec(在谷歌新闻数据集上预训练的 300 维单词向量)或 GLOVE(在带有 1.9M vocab 的普通爬行数据集上预训练的 300 维单词向量)
典型相关分析
现在,我们将给出一个流行的和成功的方法,将视觉和文本特征映射到同一个潜在空间。
Two-view CCA minimizes the distance (equivalently, maximizes the correlation) between images (triangles) and their corresponding tags (circles)
给定 2 组 N 个向量: X 表示图像特征, Y 表示文本特征。分别设它们的协方差σxx 和σYY,设σxy 为互协方差。
线性典型相关分析(CCA)寻找使两个视图的相关性最大化的线性投影对:
CCA 目标可以写成以下优化问题:
设 x 和 y 分别是表示文本和视觉数据的点。为了比较 x 和 y,我们可以使用余弦相似度:
Similarity function
定性结果
在 MS COCO 数据集中,每幅图像由 5 个标题描述。第一步包括通过删除所有停用词来预先拥有这些标题,然后将它们连接起来以获得一个单词包(BoW)。然后,我们使用 TF-IDF 技术对所有嵌入的单词进行加权平均,该技术基于单词在每个字幕中出现的频率对单词进行加权。
Example of an image and its corresponding captions
tag 2 图像
对于这个任务,我们的目标是检索由给定查询文本描述的图像。给定一个查询文本,我们首先将其特征向量投影到 CCA 空间,然后用它从数据库中检索最相似的图像特征。
质疑 1:“一个打网球的人”。
质疑 2: “一个人踩着滑板在空中跳跃”。
我们可以清楚地注意到,检索到的图像与查询图像非常接近。
图像 2 标签
这里,我们的目标是找到一组正确描述查询图像的标签。给定一个查询图像,我们首先将其特征向量投影到 CCA 空间,然后用它来检索最相似的文本特征。
通常,检索到的关键字很好地描述了查询图像。但是,我们可以识别一些错误(红色)。例如,在最后一个例子中,单词“walking”被错误地检索到。我们认为这可能是由于训练集中有许多图像同时包含“人”和“行走”。
结论
典型相关分析可以用来建立多模态检索的管道。给定图像及其标签的数据集,CCA 将它们对应的特征向量映射到相同的潜在空间,在该潜在空间中,可以使用公共相似性度量来执行图像 2 标签和标签 2 图像搜索任务。
请继续关注,如果你喜欢这篇文章,请留下👏!
参考
[1] CCA:一个多视图嵌入空间,用于对互联网图像、标签及其语义进行建模。
使用 Spark 和 HBase 进行大数据处理
在 26 分钟内标记 2600 万份出版物—为代码添加“火花”
我们在的数据工程团队,在过去的两个月里一直在不知疲倦地工作,以减少标记我们整个出版物数据库所需的时间,我非常兴奋地与大家分享这一成果。该数据库拥有多达 2600 万份出版物。我们完成这项工作的最初方法是每天只标记一百万份出版物,这意味着整个数据需要 26 天,这意味着我们的实时产品在更新期间会有这么多天处于停机状态。我们不得不把这个时间缩短到几个小时,甚至缩短到几分钟。我将深入探讨这些方法以及我们是如何解决的。
为什么需要标签?
我们的产品 iPlexus.ai 为用户提供了一个可以找到出版物的界面。专利、临床试验、论文等。与生命科学研究相关。比方说,一位研究“结肠直肠癌”的院士希望看到该领域的最新出版物、专利或临床试验。为了筛选所有关于“结肠直肠癌”的资源,我们必须对我们的出版物数据库进行分类。所以我们想根据内容给我们的出版物添加标签。一个类似的例子是网飞根据类型对电影进行分类。
我们的标记方法
- 创建标记术语的数据库:
一旦我们确定我们必须标记整个数据库,我们称为“领域专家”的优秀团队在数据科学家团队的帮助下开始工作。他们必须找出不同研究领域的所有相关标签,以及我们需要寻找哪些术语来添加这些标签。此外,我们意识到在出版物的内容中可以找到开源的术语数据库,以及与这些术语相对应的标签。结合在一起,他们提出了一个本体论。这个本体充当我们的知识库。在许多其他事情中,它有 620 万个要查找的标签术语和与之对应的标签。
- 标记算法:
接下来,我们必须想出一个有效的标记算法。我们必须找到一种方法来利用这个本体并标记原始数据。在我们的出版物数据库中,我们有“文章标题”和“文章摘要”以及其他条目,如“作者”、“出版日期”、“期刊标题”。决定在“文章标题”和“文章摘要”中搜索标记术语的存在,然后相应地进行标记。标记术语可以是单词或短语,因此需要在“原样”的基础上匹配它们,字母的情况除外。标签术语中不同单词的顺序必须与文章标题和摘要中的顺序相同。此外,要检查整个短语,而不仅仅是短语的一部分。
由于出版物和标签术语这两个数据库非常庞大,我们不能选择遍历这两个数据库,因为复杂度是 O(n*n)。因此,我们选择创建一个术语标记图,其中关键字是我们将在出版物中寻找的术语,值是我们将添加到出版物中的标记。Redis 是一个显而易见的选择,因为它创建了一个内存中的数据库用于更快的查找,复杂度为 O(1)。现在,文章标题和摘要必须分解成与这些关键字相匹配的结构,以便我们可以查找它们的标签。因此,我们决定从标题和摘要中创建 ngrams ,并在 Redis 服务器中寻找这些 ngrams,如果存在的话,获取相应的标签,并相应地标记出版物。一个标签术语中的最大字数是 7,所以我们创建了 7 或更少的 ngrams。这样,复杂度将是 O(n)。
完成它
- 初始方法:Python 代码
接下来,我们的工作是实现这个算法。出版物数据存储在 mongoDB 中。标记术语存储在 Redis 服务器中。我们从编写一个 python 脚本开始,从 mongoDB 中读取发布数据,从这些数据中创建 n gram,从 Redis(如果存在)中提取这些 n gram 的值,并添加一个标签键和标签。当运行在 6 核服务器上,每个内存 8 GB 时,它每天标记大约 100 万个出版物。另一次尝试使用 60 个内核,却发现用了 6 天。
我们必须在最多一小时内完成。因此,一次头脑风暴会议被安排来彻底改变方法以减少时间。然后决定在代码中加入“Spark”。
- 最终方法:Spark/Scala 代码
出版物数据库转移到 HBase 进行分布式存储。实现了将数据从 mongo 写入 HBase 的 python 代码。事实上,spark 本身是用 scala 编写的,我们可以导入 java 的所有库以及它自己的库,所以我们选择用 scala 编写我们的标记算法。Spark 在内存中完成所有处理,比 mapreduce 编码模式快 100 倍。
出版物数据作为 RDD(弹性分布式数据集)从 HBase 提取到 Spark。类似地,从 Redis 服务器获取标记术语。为了更快地查找,我们创建了一个映射,其中关键字是这些标记术语,值是我们要标记的术语。对于出版物,创建少于或等于 7 个单词的 ngrams。这些 ngrams 在我们创建的映射中查找,如果存在,相应地标记值。
结果
怀着热切的希望,代码在一个 16 核服务器上运行,每个服务器有 64 GB RAM,标记整个出版物数据集只需要 26 分钟。我们对结果非常满意。更重要的是,我们的首席执行官在我们通知他的时候宣布了对我们的现场奖励。
基于重要单词标记文档
30 天写作挑战
这是我的 30 天写作挑战 的第三天,我试图在开始建立一个机器学习团队的新工作之前学习数据挖掘技术。昨天,我们深入研究了用于在文本文档中查找重要单词的 tf-idf 算法。现在,我们可以选择一个文档,并挑选出使该文档独特的单词,这将是一个很好的分组相似的文档在一起。可以把它想象成给每个文档建议“标签”,根据文档的内容对它们进行分类。
有很多方法可以解决这个问题,但是我将要工作的行业在不久的将来可能会受到严格的监管。我希望能够证明为什么我们为一个给定的文档建议一个类别,而不是依赖一个像神经网络一样的黑盒。我保证会在以后的文章中讨论神经网络。
有一个叫做贝叶斯分类的过程,它将让我们根据简单的概率来决定如何对事物进行分组。我不记得我是如何知道这种技术的,但我相当肯定贝叶斯定理是教给 16 岁的孩子的。我们应该会没事的…
好吧,我们言过其实了。先用通俗易懂的英语解释一下。
概率很简单。如果一个房间里有 100 个人,其中 55 个是女性,那么那个房间里的人是女性的概率是 55%。
我们把这个写成P(woman) = 55/100 = 55%
。
如果房间里有 30 个人戴着一顶帽子,其中 20 个是女性,10 个是男性,那么我们知道,如果他们戴着一顶帽子,那么这个人是女性的概率是 66%。
我们把这个写成P(woman|wearing a hat) = 20/30 = 66%
。
对,所以我们想知道,给定文档中的重要单词,文档属于某个类别的概率。然而,首先我们只能计算一个重要单词出现在给定类别的文档中的概率。这就是奇迹发生的地方。
贝叶斯定理让我们从P(evidence|outcome)
到
P(outcome|evidence)
,其实很简单。
这给了我们P(wearing a hat|woman) = (0.66 * 0.3)/0.55 = 36%
。
这就是我们所需要的一切,我们收集已被手动标记的文档,并构建一个模型来预测文档的正确分类。
到目前为止,我们只考虑了基于单一证据的可能性。给定几个证据,找到某件事的概率也很容易。
想象一下,在戴帽子的人中,有 5 个人是高的。我们想知道某人戴着帽子的概率,假设我们知道他们是女性并且很高。
这给了我们P(wearing a hat|woman and tall) = (0.66 * 0.17 * 0.3)/0.55 = 0.06
。
希望你能理解。
我们如何将此应用于文档分类应该是显而易见的。我想用一个真实世界的例子,你可能对可能的结果有一个直觉。我们不是要计算某人戴帽子的概率,而是要计算文档属于某个类别的概率。观察结果,比如这个人是女的还是高的,将改为文档是否包含某个单词。
这在一开始似乎是一个相当棘手的概念,但事实证明数学很简单。我们能够利用对现有数据的观察来确定一个项目属于某个类别的概率,给定一些我们知道的信息。
在下一篇文章中,我将看看如何对一个给定文档的输入数据进行规范化,这样我们就可以用同样的方式处理‘摩托车’和‘摩托车’了。
这是我的 30 天写作挑战 中的一个帖子。我是一名软件工程师,试图理解机器学习。我没有博士学位,所以我将用简单的语言和大量的例子来解释事情。
关注我的Twitter查看我的最新帖子。如果你喜欢这篇文章,请点击下面的心形按钮来分享——这将有助于其他人看到它。
标记溢出—在 Stackoverflow 中关联标记
为了从字里行间获得洞察力,您可以根据 StackOverflow 的标签所附加的问题对它们进行关联和分类。
**更新:**O ’ Reilly 的书《Apache Spark 和 Neo4j 上的图形算法》现在可以从 neo4j.com免费下载电子书
更新 : Piotr Migdal 联系了我,提到他在 2015 年已经做了一个类似的项目同名 。我不知道这件事。我们只是在黑客马拉松中随机选择了这个团队名称。
在这篇文章中,我想展示如何使用 Neo4j-Graph-Algorithms 库中的 Jaccard 过程来实现这一点。我们将 StackOverflow 的整个转储导入 Neo4j,运行算法,然后使用 Neo4j 浏览器和大型图形可视化工具 Graphistry 可视化结果。
注意:我更新了服务器网址,所以你可能也需要更新你的网址。
9 月,我们有机会在纽约 StackOverflow 的办公室运行 GraphConnect “时髦词-宾果”GraphHack ,这真的很酷。给我留下深刻印象的是,那里的人们真的采纳了 Joel Spolsky 多年前发表的关于软件公司(可能还有其他公司)更好的办公室布局的文章。许多开放的空间和房间可供讨论,但每个团队成员都有一个私人的六边形玻璃墙办公室,这是一个个性化的思考和工作场所。
Invidual offices at StackOverflow
The “StackExchange-Wall”
对于黑客马拉松,我们选择了项目和团队名称“tag overflow”。
数据模型和导入
StackOverflow 数据模型非常简单,用户发布问题和回答,其中一个被接受。每个问题也用一个或多个标签标记标签。
Simple StackOverflow Graph Model
对于进口,我们:
- 从互联网档案下载了 StackOverflow 转储文件
- 用 7zip 提取的
- 将我们感兴趣的 XML 文件转换成节点和关系的 CSV 文件
- 使用 Neo4j bulk importer 在几分钟内导入数据
- 再过几分钟,创建一些索引和约束
然后 StackOverflow 的 Neo4j 图形数据库就可以使用了。
导入步骤都记录在 GitHub 库中,我们不久前在10M 问题庆典中已经介绍过这个过程。
我们的测试实例目前作为 Neo4j 云实例提供:
- https://demo.neo4jlabs.com
- 数据库“stackoverflow”
- 用户“stackoverflow”
- 密码“stackoverflow”
对于只读用户。
数据探索
我们使用谷歌的 Colab 笔记本在黑客马拉松团队中工作,效果非常好。这就像 Python 笔记本的 Google docs,即你有可定制的共享设置,每个人都可以在自己的电脑上编辑和运行单元格。感谢 Graphistry 的 Leo 提醒我这个非常酷的工具。
我们使用 py2neo 库连接到 Neo4j,py2neo 库建立在 Neo4j Python 驱动程序的基础上,对 Pandas 和 Numpy 有一些很好的支持。要在 4.0 数据库上使用它,需要使用 py2neo 5.x。
graph = Graph("bolt+routing://f6087a21.databases.neo4j.io:7687",
auth=("stackoverflow", "stackoverflow"),
name="stackoverflow", secure=True)
对于数据探索,我们首先运行一个查询,显示我们的图表中每种类型有多少数据。
result = {"label": [], "count": []}
for label in graph.run("CALL db.labels()").to_series():
query = f"MATCH (:`{label}`) RETURN count(*) as count"
count = graph.run(query).to_data_frame().iloc[0]['count']
result["label"].append(label)
result["count"].append(count)
nodes_df = pd.DataFrame(data=result)
nodes_df.sort_values("count")
或者如图表所示:
Entity Count Distribution
今天,我们对用户、问题和答案不感兴趣,只对他们的标签感兴趣。所以我们有 52445 个标签,这相当多,比我预期的多。
当然,它们的使用是一种幂律分布,我们的前 20 个标签的使用比后面的加起来还要多。
tag_usage_query = """
MATCH (t:Tag)
RETURN t.name as tag, size((t)<-[:TAGGED]-()) as deg
ORDER BY deg DESC LIMIT 20
"""tag_usage = graph.run(tag_usage_query).to_data_frame()
并以同样的方式绘制成图表。
Tag Degree Distribution
标签相关性
类似于优先连接网络中的人和其他事物,标签也聚集在一起。通常,你会有一个主类别,比如javascript
、ruby
或neo4j
,然后还有很多相关的标签。有些只在那个主要类别内有效,如cypher
是neo4j
的一部分,有些来自其他平行区域,如neo4j
和javascript
。
Correlated Tags to “neo4j”
如果我们对按频率排序的标签ruby
进行同现查询。
MATCH (q:Question)-[t:TAGGED]->(tag:Tag {name:$tagName}),
(q)-[:TAGGED]->(other:Tag)
WITH tag,other, count(*) AS freq
ORDER BY freq desc LIMIT 15
RETURN other.name, freq
Tag correlations within the “ruby” tag.
您会发现结果是有意义的,其中许多标签要么是主要的 ruby 项目,要么是库。
我们还可以在 Neo4j 浏览器中将这些关联呈现为虚拟关系,方法是在我们的聚合数据上使用apoc.create.vRelationship
函数,用count
作为属性来表示SIMILAR
关系。
MATCH (q:Question)-[t:TAGGED]->(tag:Tag {name:"ruby"}),
(q)-[:TAGGED]->(other:Tag)
WITH tag,other, count(*) as freqORDER BY freq DESC LIMIT 50
RETURN tag, other,
apoc.create.vRelationship(tag,'SIMILAR',{freq:freq}, other);
Correlation Visualization with Virtual Relationships
接下来,我们想通过观察它们的程度,来看看这些其他标签的使用频率。
MATCH (q:Question)-[t:TAGGED]->(tag:Tag {name:$tagName}),
(q)-[:TAGGED]->(other:Tag)
WITH other, count(*) as freq
RETURN other.name, freq, size((other)<-[:TAGGED]-()) AS degree
ORDER BY freq DESC LIMIT 10
Usage frequencies of correlated tags.
原来rails
、arrays
、javascript
的使用率真的很高。Rails 显示了它的受欢迎程度,其他两个标签也独立于 Ruby 用于其他编程语言问题。
标签相似度
然后我们看了标签的相似度计算,基于它们所附加的问题。
我们从基于两个集合的交集和总大小的 Jaccard 相似度开始:
jaccard(A,B) = ∣A ∩ B∣ / ( ∣A∣ + ∣B∣ - ∣A ∩ B| )jaccard(A,B) = size(intersection(A,B)) /
(size(B) + size(B) - size(intersection(A,B)))
我们可以在 Neo4j 中运行它,或者作为一个函数,比如
RETURN algo.similarity.jaccard([1,2,3], [1,2,4,5]) AS similarity
它返回0.4
(即2/(3+4-2)
)。
或者作为用于更大数据量的过程。在那里,我们将传入一个地图/字典列表,其中每个条目都有一个item
值和一个categories
列表,例如[{item:1, categories:[1,2,3]},{item:2, categories:[2,3,4]}]
。然后,该过程并行计算所有对的交集和相似度。我们可以传递额外的参数,如最小相似度或节点度(相关性)的截止值,详细信息记录在上面链接的文档中。
我们在我们的一小部分数据样本上运行这个程序,以显示它是有效的。
// find 100 tags with more than 50 questions
MATCH (tag:Tag) WHERE size((tag)<-[:TAGGED]-()) > 50
WITH tag LIMIT 100MATCH (q:Question)-[:TAGGED]->(tag)
// find 3M tagged questions for those
WITH * LIMIT 3000000
// create the entry per item (tag) with its categories (questions)
WITH {item:id(tag), categories: collect(id(q))} as entry
WITH collect(entry) as entries// pass the entries to the algorithm, find the top 3 most similar items to each entry
CALL algo.similarity.jaccard.stream(entries, {topK:3})
YIELD item1, item2, count1, count2, intersection, similarity
// return each pair once
WHERE item1 < item2
// return the tag names, intersections and similarities ordered by highest similarityRETURN algo.getNodeById(item1).name AS firstTag,
algo.getNodeById(item2).name AS secondTag,
intersection, similarity
ORDER BY similarity DESC LIMIT 50;
Top3-Similarities between tags.
全球相关性
然后,我们在整个数据集上运行相似性计算,限于具有至少 100 个问题的相关标签,总共 17000 个标签节点,即 2.92 亿次比较(17k)。
// tags with at least 100 questions
MATCH (tag:Tag) WHERE size((tag)<-[:TAGGED]-()) > 100 WITH tag
// get the questions
MATCH (q:Question)-[:TAGGED]->(tag)
// create dict with tag as item and questions as categoriesWITH {item:id(tag), categories: collect(id(q))} as entry
WITH collect(entry) as entries
// run jaccard, write back resultsCALL algo.similarity.jaccard(entries,
{topK:5,similarityCutoff:0.1, write:true})
YIELD nodes, similarityPairs, write, writeRelationshipType, writeProperty, min, max, mean, stdDev,
p25, p50, p75, p90, p95, p99, p999, p100RETURN *;
在我们竞争的共享测试机上运行 13 分钟来计算数据,在专用硬件上会更快。
由于 0.1 的非常高的最小相似性,并且仅写入 5 个最相似的邻居,我们创建了 2864 个SIMILAR
关系,然后我们可以使用这些关系在上面运行其他图算法。
outputs of the jaccard similarity procedure.
在可视化中,我们看到我们只创建了“非常紧密”的相似性组,如scheme<->racket
或sed<->awk
,或者围绕 rdf、hadoop、flash 和 quickbooks 的一些小集群!
因此,我们以较低的相似性截止值 0.01 重新运行了计算,结果总共有 44728 个SIMILAR
关系。
我们只保留了每个节点的前 5 位邻居,所以您可能会想到的一些相似之处可能会丢失,因为它们没有被删除。
利用相似关系
现在,我们使用新创建的关系来运行其他算法,例如像最短路径这样简单的算法。即相关标签是如何传递连接的。
MATCH (from:Tag {name:'html'}),(to:Tag {name:'neo4j'})
MATCH path = shortestPath((from)-[:SIMILAR*]-(to))
RETURN [n IN nodes(path) | n.name] as nodes
这就引出了这条路:
["html", "javascript", "json", "jackson", "spring-mvc",
"spring-boot", "spring-data", "spring-data-neo4j", "neo4j"]
或者是“javascript”的第四级邻居。
MATCH path=(:Tag {name:"javascript"})-[:SIMILAR*..4]->()
RETURN path
Neo4j Browser Visualization of “javascript” Neighborhood
除此之外,我们还在我们的推断图上快速运行其他图形算法,并将结果写回我们的数据库。
call algo.pageRank('Tag','SIMILAR');
call algo.labelPropagation('Tag','SIMILAR');
call algo.betweenness('Tag','SIMILAR');
现在我们的标签还带有pagerank
、partition
、centrality
属性,这些属性捕捉了它们在我们的图中的相关性和位置。
match (t:Tag) return t limit 5;(:Tag {partition: 26, centrality: 406233.80006818444, name: ".net", count: 268970, pagerank: 2.532907, wikiPostId: 3607476})
(:Tag {partition: 4, centrality: 2545764.1141965324, name: "html", count: 752349, pagerank: 6.3226235, wikiPostId: 3673182})
(:Tag {partition: 415, centrality: 2731837.0951582957, name: "javascript", count: 1624044, pagerank: 5.2686405, wikiPostId: 3607052})
(:Tag {partition: 415, centrality: 642718.2814995827, name: "css", count: 537685, pagerank: 5.447395500000001, wikiPostId: 3644669})
(:Tag {partition: 204, centrality: 5703506.726861835, name: "php", count: 1200404, pagerank: 5.8298785, wikiPostId: 3607050})
形象化
既然我们的图的节点已经用图度量来丰富了,我们就可以将它们可视化,比如用我们的 NeoVis.js Javascript 库。
例如围绕javascript
标签的相似度图。
可视化:图形
幸运的是, Leo Meyerovich ,Graphistry 的首席执行官和创始人,一个基于 GPU 的高性能图形可视化工具包,也在黑客马拉松上。在我们研究相似性的同时,Leo 围绕 Neo4j Python 驱动程序构建了一个小包装器,将节点和关系从一个 Cypher 查询拉到 Graphistry 的数据帧中,并根据需要绑定其列。
现在 Neo4j 连接器已经正确地集成到 Graphistry 中,所以您可以开箱使用它*。此外,还有大量的 Jupyter 笔记本演示。*
不过,你需要一个图形键,所以 ping Leo。
下面你可以看到图形用户界面和“kubernetes”周围网络的可视化,查询如下:
MATCH p=(t1:Tag {name:'kubernetes'})-[r:SIMILAR*..4]-(t2:Tag)
RETURN p
以下是 python 代码:
GRAPHISTRY = {
'server': 'labs.graphistry.com',
'api': 2,
'key': 'xxxx'
} NEO4J = {
'uri': "bolt+routing://f6087a21.databases.neo4j.io:7687",
'auth': ("stackoverflow", "stackoverflow")
}!pip install pandas
!pip install graphistry[bolt] import pandas as pd
import graphistry
graphistry.__version__graphistry.register(bolt=NEO4J, **GRAPHISTRY)g = graphistry.cypher("""
MATCH p=(t1:Tag {name:'kubernetes'})-[r:SIMILAR*..4]-(t2:Tag)
RETURN p
""",
{})g = g.bind(point_title='name', edge_weight='score')
# point_size='pagerank', point_color='partition',g.plot()
Graphistry Visualization of the K8S neighborhood.
在 graphistry 中,你可以直接用绑定来配置一些可视化设置,见上面的name
。其他的更容易通过 UI 控制,通过Add Histogram for …
并选择一个属性,然后你可以使用这个分布来给节点和关系着色或调整大小。
摘要
这仅仅触及了图模型、图算法和 StackOverflow 数据可视化的表面。
我希望我激发了你对数据和数据集的兴趣,实例和笔记本是可以公开访问的,所以请尝试一下。我会再写一篇关于你可以在这个数据集上做的有趣的图形查询的文章。
对于流行语——黑客马拉松来说,这绝对是值得的——我们赢得了“最流行语”类别:)非常感谢我的合作者参与讨论,以及与这个很酷的数据集一起工作的乐趣。在这里,你可以读到黑客马拉松中另一个很酷的参赛项目,即空间图形应用。
请让我知道你还想做什么,我肯定有更多的想法。给 devrel@neo4j.com写信或者在这个帖子上留言。
Free download: O’Reilly “Graph Algorithms on Apache Spark and Neo4j”
照顾好你的神经瘤
什么是神经瘤?
这是你自己的智能技术。是湿科技和健康科技。它在你体内。
它有数千亿个神经元,每个神经元与相邻的神经元有大约 10,000 个连接,并调节数十亿个分子。你的神经细胞每时每刻都在发出数以万亿计的脉冲。
它有自己的编辑器:意识,一个紧急的策展人,有时会在周围留意一些事情,但不经常。
与神经瘤相比,意识非常小。然而,它有自己的小无限,被睡眠阻止,更广泛地被它不太了解的神秘开始和结束阻止。
你的神经瘤有自己的探测器,你的身体,插入外部世界,以电化学方式来回传递信号。
在它的一生中,你的神经瘤不断地根据通过你的身体进入的数据流进行自我重塑。它具有深度学习、机器学习、视频分析、大量有趣的内部人工智能(我们在环境中出现的其他自我,海滩你、酒吧你、关系你、工作你,甚至对你们中的许多人来说,一种特定的电话声音,与你的正常声音截然不同)。
它可能还有数以百万计的其他学习类型,编辑们还没有给它们贴上标签。
这是一个自我创作的复杂系统,你可以用你的意识来访问它的一部分,但大多数时候,你们中的大多数人没有足够的勇气去尝试,宁愿向外看,而不是向内看。
但是它需要你的关心。
存在于你头骨中的这个世界有一点硬技术来保护它免受许多物理撞击。
但是,它完全暴露在其环境中的数据流中,并且由于它总是响应,所以一直在根据这些数据流调整自己。
它筛选它们的模式,试图创造意义。它对威胁感到紧张,很容易被触发进入警报状态,有时是恐慌的失控警报状态,在此期间,它会分泌荷尔蒙,试图控制其检测系统的各个部分。
这些激素存在于一个持续的微妙的反馈平衡中,因为它们是它用来告诉发生了什么的方式,也是它用来使行动发生的方式。所以事情可能会出错。
它们也是重塑记忆过程的关键。对信息的反应中涉及的激素越多,神经瘤就越能被重塑以供下次回忆。
所有这些都是无意识的。严格来说,那不是真的,有些是半意识的,也可能是有意识的。所有的部分都是相连的,所以你可以用不同的方式操作它们。
我的意思是,我们可能会(在没有外部刺激的情况下)思考一些事情,而神经瘤会将这个想法作为其数据流的一部分接收到。然后,各种各样的混乱可能会在完全崩溃的恐慌和超过你一天所能处理的更多的快乐之间开始。
这是半意识的版本,你意识到这个想法,然后意识到它给你的感觉,有点意识到你做了什么,但没有太多其他的。
全意识版本是关于有意识地使用你的编辑器来学习如何保护和生长你自己的神经瘤,来监控和发展它的健康。
我想现在够了。一些让你思考和实践的东西。如果你愿意,可以和我谈谈。
迈出下一步:面向中间数据科学的 MOOCs
There are many steps in the journey to Data Science Mastery
一旦你完成了“面向初学者的机器学习”MOOC,你可以去一些地方。
为初学者找到数据科学课程相对容易——事实上,你甚至无法在没有收到 Udemy 垃圾邮件的情况下观看泰勒·斯威夫特的视频。为想更进一步的人找到课程有点困难。我在这里列出了一些目前或即将开始的 MOOCs,它们试图以不同的方式做到这一点。在某些情况下,这意味着重新审视我们已经深入了解过的材料。在其他情况下,这可能意味着向外扩展知识或学习更好的方法来应用现有的知识。
事实上,第一个示例课程将是学习应用知识的新方法。人们常说,数据科学是统计学、计算和业务知识的结合,或者类似的东西,但还没有大量针对数据专业人员的围绕业务知识的材料。埃塞克商学院(ESSEC Business School)开设的 Coursera Strategic Business Insights specialization 课程是填补这一空白的明确尝试。该系列的第一门课程,战略分析的基础,为这一努力定下了基调,专注于你可以将统计应用于更新更先进技术的商业用例。本课程的后续课程是营销分析基础,当这两个课程结合在一起时,您已经涵盖了商业导向的数据科学招聘广告中最常提及的广泛用例。
对于那些对深入研究统计学更感兴趣的人来说,有几个可能的选择。埃因霍温科技大学 Coursera 提供的一个很有前途的项目是改善你的统计推断。本课程以令人惊讶的方式介绍了支撑统计推断的理论,对于那些还没有有幸学习第三年或更高年级统计理论课程的人来说,本课程应该包含许多新材料,对于那些已经学习过的人来说,可能至少包含一些新材料。你也可以通过 Efron 和 Hastie 的新书“计算机时代统计推理”进一步学习,这本书可以免费下载,在与 Eindhoven 推理课程类似的地方开始后,可以更深入地研究应用于机器学习的推理。
埃因霍温课程提到了贝叶斯统计,但并不打算深入调查这一领域的统计推断。幸运的是,有一些课程,比如加州大学圣克鲁斯分校的贝叶斯统计就涉及到统计思想的这个重要领域。有概率和先验的前提条件(懂吗?)在统计推断方面的工作,这有望成为这一领域的实质性讨论。
数据科学家的另一个重要武器是对数据库实践的扎实知识。顾名思义,佐治亚理工学院的数据库系统概念课程从基础开始处理数据库,从数据库体系结构的基础开始,到对数据库构建方式的全面理解,以获得最佳结果。
最后一个产品来自微软,他们以相对较小的块组织了一个大数据专业程序。该计划将带您从大数据的开端到 NoSQL 的高级使用以及分析大数据的相关方法,所有这些都在当前的微软产品套件中。
罗伯特·德格拉夫为 Medium 撰写了许多文章,讲述了他在通过第一基地后遇到的数据科学方面的问题。最近的条目,关于使用质量保证技术在实现后保持稳定的模型是 在这里找到 。
机器学习国际会议的收获
我从 ICML 2018 中学到了什么
作为一名专注于应用机器学习的工程师,我很幸运地参加了今年在瑞典斯德哥尔摩举行的机器学习国际会议(ICML)。以下是我最大的收获。
1.模仿对强化学习有重要的好处
主持人:岳(加州理工)&黄明乐(加州理工)
也被称为“从示范中学习”或“学徒学习”,模仿学习是 ML 研究的一个有前途的领域,因为它通过模仿预先存在的目标行为来帮助学习主体克服在开放世界环境中学习的挑战。例如,迪士尼的研究使用模仿学习来创造面部动画,模仿人们在说各种语言时下巴移动的方式*——这是岳和乐与迪士尼合作的项目。*
探索的其他应用包括基于人类决策的自动驾驶汽车训练,基于获胜的例子跟踪运动员应该在场上的位置,以及挑选和放置物品以实现目标(想想亚马逊仓库)。
Demo of RL agent “mouthing” German by imitating a human.
模仿学习是引人注目的,因为它使用“成功”的例子来解决其母学科的一些基本挑战,强化学习。毕竟,强化学习的全部目的是训练一个代理人通过在一个环境中采取行动来最大化它收到的累积奖励(想象一只人工智能狗试图通过找出执行哪些技巧来最大化它可以获得的奖励数量)。通过发现预先存在的获胜行为作为目标(从“专家”或“示范者”那里),模仿学习有助于 a)缩小可能导致奖励的可能行动的范围(没有专家,“行动空间”可能会非常大)和 b)建立行动和奖励之间的直接关联(而不是不确定在给定的情节中哪个行动导致了奖励)。
本次演讲涉及的技术包括行为克隆、直接策略学习和反向 RL。
视频和幻灯片此处。
2.无模型强化学习还没有为现实世界做好准备
演讲者:本杰明·雷希特(加州大学伯克利分校)
无模型强化学习试图通过让代理直接与其环境交互来最大化代理获得的回报,而不是首先建立该环境的明确定义的模型并作为代理与该模型交互。无模型方法之所以吸引人,是因为它们不需要试图建立一个有问题的环境模型的努力和开销。
从表面上看,似乎无模型 RL 将是帮助解决现实世界场景,特别是连续控制问题的一个很好的选择。连续控制问题涉及控制现实世界动态系统的输入以最小化成本(例如,机器人学习移动,自动驾驶汽车在繁忙的道路上导航,以及无人驾驶飞行器学习在半空中稳定)。因为连续控制问题在公式化方面非常类似于 RL 问题,即由状态、动作、转换和回报组成的最小化问题,如果我们能够学会解决这些问题而无需首先模拟复杂的现实世界环境,那不是很好吗?
Image shot by a stable unmanned aerial vehicle.
然而,尽管这看起来很有希望,但让无模型的 RL 代理控制现实世界的系统存在一些基本挑战。正如 Recht 博士在他的教程中令人信服地指出的那样,无模型强化学习只有在高度结构化的封闭环境中才真正有效,例如在模拟和游戏中。一旦一个代理进入真实世界的连续环境,它的性能就会变得非常不稳定,甚至对初始化中最小的扰动和变化都很敏感。性能下降的原因可能是因为封闭环境不能模拟所有真实世界的条件,所以在封闭环境中表现良好的代理可能不太适合预测真实世界中看不见的扰动。
无模型强化学习在现实世界中失败的第二个原因是现实世界不允许太多的实验,这是无模型学习的关键基础,因为赌注要高得多。例如,考虑一个 RL 代理在高速公路上学习控制一辆摩托车:它不允许失败到与模拟中相同的程度,因为重复摧毁摩托车的成本——更不用说有人类参与的情况了——因此代理不能像模拟中一样通过试错来学习。
Humanoid trained to walk in simulation using model-free RL.
考虑到强化学习会议是今年 ICML 最受欢迎的会议之一(以至于会议被开玩笑地称为 ICRL),Recht 博士建议社区要么专注于基于模型的RL——特别是模型预测控制——要么寻找基本技术来进一步稳定现实环境中的无模型强化学习。Recht 警告说,如果我们继续只在仿真中优化无模型 RL 控制算法,我们就找错了对象。
为了更深入地了解 Recht 博士的工作,我推荐阅读他的简洁但极具教育意义的系列文章“一个局外人的强化学习之旅
视频和幻灯片在这里。
3.人工智能对安全至关重要
主持人:黎明之歌(加州大学伯克利分校)
这个演讲探讨了人工智能和安全交叉领域的挑战和机遇:如果我们要将人工智能研究投入产品,机器学习和安全如何有一个纠缠不清的前进道路。为了展示我们的学习算法有多脆弱,宋博士讨论了攻击深度学习系统的不同技术,特别是视觉系统(有关这方面的例子,请查看我的介绍性工作这里)。另一方面,机器学习也可以用于为不同的软件系统(例如 web 服务和物联网云)创建新的攻击。
关于安全和 ML 的叙述的另一个关键部分是隐私的处理,特别是防止从机器学习模型中提取敏感信息的问题。虽然本质上是介绍性的,但这个演讲是对安全和机器学习之间日益增长的关系的一个很好的看法,它强调了前进中需要注意的一些最重要的问题。
4.ICML 流行的纸主题
我在 ICML 偶然发现了一些有趣的论文,我认为按主题分类会有所帮助。
a)对手
我遇到的最大主题之一是对抗性机器学习,这是一个广泛的领域,利用学习算法之间的竞争来优化产生新样本的生成器。在这个领域中,有两个主要的子领域——一个是基于来自训练集的学习来生成新样本(例如训练生成器以得出特定风格的绘画),另一个是生成旨在欺骗神经网络的对立样本。
Image generated through generative adversarial learning.
论文:
模糊的渐变给人一种虚假的安全感:规避对敌对例子的防御
哪些 gan 的训练方法实际上是一致的?
b)深度学习的新架构
这个主题指的是在向神经网络引入新的架构组件方面的进步,我看到了很多关于这方面的讨论。这项工作从整体上推进了深度学习领域,并为解决不同领域的预测问题提供了新的工具。
论文:
c)将机器学习的进步应用到产品中
与在产品中部署机器学习系统相关的研究。
纸张:
d)强化学习
在状态-行动空间中通过决策解决累积奖励最大化问题的进展。
论文:
e)理论
这里的工作旨在进一步加深我们对机器学习(特别是深度学习)为什么以及如何工作的理论理解。这项工作对于使我们能够不断向前推进模型和网络的部署至关重要,因为它提供了基础知识来对比深度学习社区取得的高度经验性进展。
论文:
f)隐私和公平
随着深度学习在广泛处理人群的上下文中变得适用(例如,医疗保健、贷款申请评估等。),我们需要切向工具来消除训练数据中存在的历史偏见。同时,我们需要知道隐私信息不能通过敌对攻击从模型中提取出来的方法。这项工作在这些领域取得了进展。
论文:
5.在 ICML 偷听到的
最后,一些有趣而有意义的 ICML 语录:
“一旦我们将其投入生产,所有的机器学习都变成了强化学习。今天,你有这些大公司根据用户反馈定期重新训练模型。那就是强化学习。”
Benjamin Recht 博士,副教授(加州大学伯克利分校)
背景:【Benjamin Recht 博士提倡进行更多的基础研究,以稳定连续现实世界环境中的强化学习代理。他反映,生产中的许多非 RL 模型经常基于反馈进行再培训,实际上使它们成为 RL 系统。
“作为机器学习人员,我们都喜欢写的那一行,即“(acc,loss) = model.evaluate(x_test,y_test)”已经不够了。”
——尼古拉斯·卡里尼,研究科学家(谷歌大脑)
背景: Nicholas Carlini 因其作品“模糊的渐变产生一种虚假的安全感”获得最佳论文奖,他提倡一种更结构化的方法来验证模型,即通过创建方法来识别模型的安全程度。
怎么样了?谢谢你有用的建设性建议和你有价值的深度问题。如果我们有空间来测试我们的估计,我们将阐明我们所学到的内容并更新最终附录!
- ICML 2018 组委会
***上下文:*对于所有提交给 ICML 大学、需要修改才能被接受的论文,组织者使用经典的 NLP 技术来确定作者在回应批评时使用的最有可能改变结果的单词和短语。这是一个有趣的关键短语的大杂烩,旨在增加作者被 ICML 接受的机会…
结论
超过 5000 名与会者和 600 多篇论文、主题演讲、海报展示以及在六天的紧凑日程中颁发的奖项,今年的 ICML 可谓收获颇丰。除了学术机构,许多公司也蜂拥而至,设立了自己的展位(我在另一篇文章中专门写了谁在那里)。)今年提交给 ICML 的出席人数和新研究的增长不容忽视,这表明机器学习社区比以往任何时候都更加活跃。
对我来说,最重要的非技术性收获是机器学习中基础理论研究和产品开发的持续结合。ML 仍然是一个尚未真正商品化的领域。尽管我们有越来越复杂、先进和易用的工具(TensorFlow、PyTorch、云服务等)。),真正有影响力的创新仍然主要来自研究。这意味着大公司继续对未知领域进行大量投资,建立研究实验室,顶级学者可以在那里赚取高额薪酬,同时制定自己的工作日程。
我希望明年能看到更多的东西,包括:
- 蒸馏研究,即解决随着社区的发展而增加 研究债务 的研究。看到更多的研究人员愿意全面处理、简化研究,并将研究置于更广阔的背景下,以减少过去十年积累的研究债务,这将是一件好事。**
- 我也希望看到深度学习和强化学习之外的更广泛的优化探索。这只是我的看法,但我相信人工通用智能将不会是一个特定的领域,而是将优化与对大脑的半结构化理解结合起来。我认为,在解决智力问题时,社区应该继续从动物和人类的大脑中寻找灵感。
总而言之,ICML 是一次非凡的经历。我离开会议时充满活力,并受到鼓舞,继续致力于机器学习问题,将我的努力集中在提炼特定的研究领域,以便其他人可以了解哪些问题已经解决,并为解决其他挑战带来灵感。如果你有定量的背景并且对合作感兴趣,在这里评论或者发邮件给我。
Dhruv 是Connected的 ML 软件工程师,这是一家产品开发公司,与客户合作,通过软件驱动的产品来提高影响力。更多故事 此处 。
作者的评论
我想对伊莱·伯恩斯坦(Eli Burnstein)在多次修改中帮助校对和编辑这篇文章表示由衷的感谢。
像往常一样,留下评论并指出你在这里发现的任何错误。我会尽快修复它们!
脚注
- 基于模型的 RL 中的“模型”捕获状态和动作之间的转移概率,并包含一些关于来自这些转移的可能回报的信息。实际上,对转换动态的这种理解允许 RL 问题被简化为在一个环境中规划最优轨迹以最大化整体回报的问题。
- 连续控制问题和 RL 问题之间的相似之处是由于这两个问题的基本公式。大多数强化学习问题被认为是马尔可夫决策过程 (MDPs)。MDP 是一种数学框架,用于模拟决策场景,包括 1)有限的状态集,2)有限的行动集,3)行动导致特定状态的概率,4)由于行动而在状态之间转换后收到的即时奖励(或预期即时奖励),以及 5)折扣因子。连续控制问题也可以被认为是 MDP,具有上述相同的基本组成部分,因此强化学习技术在该领域也是有效的,这似乎是很自然的。
让 Deep Q Networks 更进一步
又见面了,
今天的话题是…嗯,和上一个一样。Q 学习和深度 Q 网络。上次,我们解释了什么是 Q 学习,以及如何使用贝尔曼方程来寻找 Q 值,从而得出最优策略。后来,我们介绍了深度 Q 网络,以及我们如何让深度神经网络学习近似它们,而不是计算 Q 表的所有值。
深度 Q 网络将环境状态作为输入,并为每个可能的动作输出 Q 值。最大 Q 值决定了代理将执行的操作。代理的训练使用 TD 误差作为损失,TD 误差是下一个状态的最大可能值和 Q 值的当前预测值之间的差(如贝尔曼方程所示)。因此,我们设法使用神经网络来逼近 Q 表。
到目前为止一切顺利。但是当然,也出现了一些问题。这只是科学研究前进的方式。当然,我们已经提出了一些很好的解决方案。
移动 Q 目标
第一个问题是所谓的移动 Q 目标。正如我们所看到的,TD 误差的第一个组成部分(TD 代表时间差)是 Q 目标,它的计算方法是立即奖励加上下一个状态的贴现最大 Q 值。当我们训练我们的代理时,我们根据 TD 误差更新权重。但是相同的权重适用于目标值和预测值。你看到问题了吗?
我们将输出移近目标,但我们也移动了目标。所以,我们最终追逐目标,我们得到一个高度振荡的训练过程。在我们训练网络的时候保持目标不变并不好。DeepMind 正是这么做的。
它不是使用一个神经网络,而是使用两个。是的,你没听错!(好像一个还不够)。
一个作为主要的深度 Q 网络,第二个(称为目标网络)专门且周期性地更新目标的权重。这种技术被称为**固定 Q 目标。**事实上,权重在大部分训练中是固定的,并且只是偶尔更新一次。
最大化偏差
最大化偏差是深度 Q 网络高估值和动作值(Q)函数的趋势。为什么会这样?我认为,如果由于某种原因,网络高估了某个动作的 Q 值,那么该动作将被选为下一步的首选动作,而同样的高估值将被用作目标值。换句话说,没有办法评估具有最大值的动作实际上是否是最佳动作。这个怎么解决?答案是一个非常有趣的方法,叫做:
双深 Q 网络
为了解决最大化偏差,我们使用两个深度 Q 网络。
- 一方面,DQN 一如既往地负责下一个动作的选择(取值最大的那个)。
- 另一方面,目标网络负责该动作的评估。
诀窍在于,目标值不是由最大 Q 值自动产生的,而是由目标网络产生的。换句话说,我们要求目标网络计算在下一个状态采取行动的目标 Q 值。并且作为副作用,我们还解决了移动目标问题。整洁对吗?一石二鸟。通过将动作选择与目标 Q 值生成分离,我们能够显著降低高估,并且训练更快、更可靠。
你觉得就这样了?抱歉让你失望了。我们将更进一步。现在怎么办?你打算增加第三个神经网络吗?哈哈!!
算是吧。现在谁在笑?
决斗深度 Q 网络
先刷新一下 Q 学习的基础。q 值对应于一个行为对于一个特定的州来说有多好的度量?这就是为什么它是一个动作值函数。度量标准只不过是该州对该行动的预期回报。事实上,q 值可以分解成两部分:状态值函数 V(s)和优势值 A(s,A)。是的,我们只是引入了一个新的功能:
Q(s,a)= V(s)+ A(s,A)
优势函数捕捉的是在给定状态下,一个行为与其他行为相比有多好,而价值函数捕捉的是在这种状态下有多好。决斗 Q 网络背后的整个思想依赖于将 Q 函数表示为值和优势函数的总和。我们简单地用两个网络来学习和的每一部分,然后我们合计它们的输出。
我们这样做有什么收获吗?当然,我们有。代理现在能够评估一个状态,而不关心该状态的每个动作的效果。这意味着决定一个状态好坏的特征不一定与评估一个动作的特征相同。并且它可能根本不需要关心动作。一个州采取的行动完全不会影响环境,这种情况并不少见。那么为什么要考虑它们呢?
- 快速提示:如果您仔细观察图像,您会发现,要合计两个网络的输出,我们并不是简单地将它们相加。这背后的原因是可识别性的问题。如果我们有 Q,我们就找不到 V 和 a,所以我们不能反向传播。相反,我们选择使用平均优势作为基线(减去的项)。
最后但并非最不重要的是,我们有更多的问题要讨论,它必须与优化经验重播。
优先体验重放
你还记得经验回放是指我们时不时地向代理人回放随机的过去经验,以防止他忘记它们。如果你没有,现在你有了。但是有些经历可能比其他经历更有意义。因此,我们应该优先播放它们。为此,我们使用优先级进行采样,而不是随机采样(来自均匀分布)。首先,我们定义 TD 误差的大小(加上一些常数,以避免选择体验的概率为零)。
p = |δ|+ε
中心思想:预测和目标之间的误差越高,就越迫切需要了解它。
为了确保我们不会总是重复同样的经历,我们添加了一些随机性,这样就万事俱备了。此外,对于复杂性的动摇,我们将经验保存在一个叫做 SumTree 的二叉树中。
太多了。很多新的信息,很多新的改进。但是想想我们能把它们结合在一起。我们做到了。
我试图给出该领域最重要的最新成果的总结,并辅以一些直觉思维和数学知识。这就是强化学习对学习如此重要的原因。有如此多的潜力和如此多的增强功能,以至于你不能忽视它将成为人工智能中的大玩家的事实(如果它还不是的话)。但这就是为什么学习和跟上它是如此困难。
我们要做的就是不断学习…
如果你有任何想法、评论、问题或者你只是想了解我的最新内容,请随时与我联系LinkedinTwitterinsta gramGithub或者****
要阅读整个深度强化学习课程,学习所有你需要知道的关于人工智能的知识,去 这里 。
原载于 2018 年 10 月 14 日sergioskar . github . io*。*
从混乱矩阵中找出混乱
Source: Understanding Confusion Matrix by Sarang Narkhede on Towards Data Science
当我第一次了解混乱矩阵的概念时,我有一种强烈的感觉:混乱。毕竟,它们被称为混淆矩阵。事实上,我确信它们之所以如此命名,是因为它们经常如此令人困惑(不要引用我的话)。但是,当你更深入地研究混淆矩阵的构造时,它实际上并不那么令人困惑。
最重要的是要知道,它完全基于结果。
真、假、正、负
How you should look at a confusion matrix
正/负标签指的是实验的预测结果,而真/假指的是实际结果。因此,如果我预测有人怀孕了,但他们没有,那么这将是一个假阳性,因为实际结果是假的,但预测是阳性的。
错误类型
Types of Errors
混淆矩阵有两类错误:第一类和第二类。
有人教我两种方法来保持第一型和第二型的正直。如果你知道这些年来有谁帮助过你,请在评论中留下他们——我喜欢好的记忆术!
第一种方法是重新写假阴性和假阳性。假阳性是一种 I 型错误,因为假阳性= F 也为真,并且只有一个 F。假阴性是一种 II 型错误,因为假阴性= F 也为 F 也为真,因此有两个 F 使其成为 II 型错误。(莱利·达拉斯的这种方法值得称赞!)
第二种方法是考虑这些单词的意思。误报包含一个否定词(False ),所以它是一类错误。假阴性有两个否定词(假+负),所以是第二类错误。
混淆度量
从我们的混淆矩阵中,我们可以计算出五个不同的度量标准来衡量我们模型的有效性。
- 准确度(全部正确 /全部)= TP + TN / TP + TN + FP + FN
- 分类错误(全部不正确 /全部)= FP + FN / TP + TN + FP + FN
- 精度(真正/预测正)= TP / TP + FP
- 灵敏度又名召回(真阳性/所有实际阳性)= TP / TP + FN
- 特异性(真阴性/所有实际阴性)=TN / TN + FP
示例
在这一点上,我已经向你抛出了许多单词和公式,所以让我们将我们所学的应用到一个例子中。我通过做例子学得最好,说到矩阵,没有比怀孕更好的例子了。
假设我为塔吉特百货工作,我想根据购物模式发现怀孕的青少年,这样我就可以在他们之前通知他们的父亲。我随机抽取了 500 名女性青少年顾客。在这些青少年中,有 50 人实际上已经怀孕。我预测总共有 100 个怀孕的青少年,其中 45 个真的怀孕了。
我们的任务是双重的: A) 识别 TP、TN、FP、FN,并构建混淆矩阵和 B) 计算准确度、误分类、精确度、灵敏度和特异性
首先,让我们分解我们的问题陈述来回答 a 部分。
我随机抽取了 500 名少女顾客作为样本。在这些青少年中,有 50 人实际上已经怀孕。我预测 100 个怀孕少女,其中 45 个实际怀孕**。**
我预测了 100 次怀孕,所以我们的“预测怀孕行”应该加起来是 100。我们知道 100 人中有 45 人确实怀孕了,所以我们可以把 45 人放在预测怀孕的实际怀孕点上,也就是真阳性。
45 are indeed pregnant
此外,我的样本中有 50 人实际上已经怀孕。所以我的实际怀孕数应该是 50。因为我们在这一栏中已经有 45 个,我们在预测的而不是实际的怀孕点中放了 5 个,也就是假阴性。
50–45 = 5
我预测了 100 次怀孕,但是只有 45 次真的怀孕了。那么在我预测的所有人中,有多少是我错误预测的呢?答案是 55,这是我的假阳性,因为我错误地预测了阳性结果。
100–45 = 55
最后,我可以通过将 45、55 和 5 相加,然后从 500 个样本中减去,来确定真正否定的数量。这给我们留下了 395 个真正的否定。一旦我们的数字被填入,我们可以通过把我们所有的方块加起来并确保它们加起来是 500 来复查我们自己。
我们也知道 55 或假阳性是我们的 I 型错误,因为我们知道我在总共 100 次预测怀孕中错误地预测了 55 次。我们知道 5 或假阴性是我们的第二类错误,因为我们知道我错误地预测了 50 个实际怀孕的女孩中有 5 个没有怀孕。
接下来,我们可以使用我们的标签混淆矩阵来计算我们的指标。
- 准确度(全部正确 /全部)= TP + TN / TP + TN + FP + FN
(45 + 395) / 500 = 440 / 500 = 0.88 或 88%准确率
2.分类错误(全部不正确 /全部)= FP + FN / TP + TN + FP + FN
(55 + 5) / 500 = 60 / 500 = 0.12 或 12%误分类
你也可以只做 1 —精度,所以:
1–0.88 = 0.12 或 12%误分类
3.精度(真正/预测正)= TP / TP + FP
45 / (45 + 55) = 45 / 100 = 0.45 或 45%精度
4.灵敏度又名召回(真阳性/所有实际阳性)= TP / TP + FN
45 / (45 + 5) = 45 / 50 = 0.90 或 90%灵敏度
5.特异性(真阴性/所有实际阴性)=TN / TN + FP
395 / (395 + 55) = 395 / 450 = 0.88 或 88%特异性
那又怎样?
Our final result
这一切都很好,但我们为什么要在乎呢?
我们之所以关心,是因为混淆矩阵可以帮助我们使用上面计算的指标来评估模型的性能。现在,我们不需要每次都做所有五个,我们只需要选择一个来帮助我们根据最坏的情况评估我们的模型。
在这种情况下,以我们的怀孕为例,假阳性的高发生率是最糟糕的结果。这使得精确度成为我想要关注的指标,它只有 45%,非常糟糕。这意味着我们有 55%的时间错误地预测怀孕,并通知父母不存在的怀孕。我们的模式,简单来说,很烂。
我希望这篇文章让您对混淆矩阵不再感到困惑。如果你有任何简化的问题或方法,请在下面的评论中留下。
1000 家 Crunchbase 创业公司的故事
介绍
受到 100 个企业家的故事的启发,我想利用 Crunchbase 创业公司的数据做类似的事情。
Crunchbase 是一个收集许多初创公司融资信息的网站。这是发现创新公司和了解他们背后的人的绝佳资源。
不幸的是,与其他公共数据源不同,人们必须支付专业会员费才能从 Crunchbase 下载数据。所以我决定在这里下载的数据,这不是最新的;然而,它对我的目的是好的。
与此同时,我创作了这个 Tableau 故事,可以在这里查看。
数据
先做最重要的事情;我们来探究一下 r 中的数据。
该数据集包含三个表:投资、公司和收购。它包括 66,000 多家成立于 1977 年至 2015 年之间的公司。在这 66,000 家公司中,大约有 18,000 家公司后来被收购。
投资
大多数资助金额在 5000 万至 6000 万美元之间。
Figure 1
按公司、类别和地区列出的最高筹资总额。
毫不奇怪,大多数顶级资助的 crunchbase 初创公司都位于美国,尤其是旧金山湾区。我相信你会熟悉这些公司中的一些或全部。
Figure 2
公司筹集的前 20 笔资金总额
Figure 3
按公司类别列出的前 20 名筹资总额
对于一家年轻的生物技术公司来说,这是一个激动人心的时刻,因为该行业的风险投资热潮。
Figure 4
生物技术风险投资排名前 15 位的城市
任何想创办生物技术公司的人都应该密切关注这个列表。
Figure 5
毫不奇怪,剑桥和波士顿应该争夺交易和美元排行榜的榜首。圣地亚哥远远落在第二位。旧金山、南旧金山、门洛帕克、海沃德、红木城和山景城都在湾区的名册上。
1977 年至 2015 年间,这 15 个最大的城市几乎占据了所有生物技术风险投资的一半。
按区域划分的前 15 名筹资总额
Figure 6
北京和上海现在是顶尖的创业中心,尽管这些亚洲城市获得的加速器资金比西欧城市少 10%。
毫不奇怪,随着联想、腾讯、阿里巴巴和百度等企业巨头在北京诞生,北京在 crunchbase 初创企业融资总额方面排名第四。
融资轮次
对那些不熟悉创业和早期投资领域的人来说(引用维基百科):
- 风险投资轮是一种用于风险资本融资的融资轮,初创公司通过它获得投资,通常来自风险资本家和其他机构投资者。获得风险投资是发展新公司和新技术的主要刺激因素之一。
- 私募股权通常是指以有限合伙制组织的投资基金,不公开交易,其投资者通常是大型机构投资者、大学捐赠基金或富裕的个人。
- 债务融资是指公司通过向个人和/或机构投资者出售债券、票据或票据来筹集营运资金或资本支出。
- 上市后是指公司首次公开发行股票后的一段时间,这是它在股权金融市场的首次亮相
- 术语“种子”意味着这是一个非常早期的投资,意味着支持企业直到它能够产生自己的现金,或者直到它准备好进行进一步的投资。
Figure 7
如果你想知道风险投资公司从哪里获得资金,可以看看 Quora 上的这篇文章。
按投资者和地区列出的最高融资额
Figure 8
前 20 名投资者中有 12 名在旧金山湾区。前 20 名投资者中有 3 名在纽约市地区。其余的顶级投资者来自巴尔的摩、中国、莫斯科、日内瓦和新加坡。
采集
对于大多数风险资本家来说,收购是一个重要的衡量标准。他们投资创业公司的钱最终必须回到锅里——最好是高倍数的。
在研究了收购表之后,我发现该表包括了失败的收购:也就是没有发生的计划收购,比如:
- 在奥巴马政府瞄准了将美国最大的制药公司转移到爱尔兰以降低其税收的交易后,辉瑞和 Allergan 终止了他们计划中的 1500 亿美元的合并。
- 美国地方法院裁决以反竞争为由阻止 Anthem-Cigna 合并, Cigna 公司取消了与 Anthem Inc .的 480 亿美元合并协议
- 在司法部计划对 Comcast 和时代华纳有线提起反垄断诉讼以试图阻止它之后, Comcase 宣布将撤回收购时代华纳有线的提议。
- 在法院以反垄断为由阻止交易后,Aetna 放弃了与 Humana 的 370 亿美元的合并计划。
- 迈兰以 260 亿美元收购佩里戈的计划失败了。
记住这一点,让我们研究一下采集数据。
收购价格金额分配
大多数收购金额在 1 亿美元左右(请记住,该数据包括高价值的不成功交易)。
Figure 9
按公司和收购方列出的顶级收购
Figure 10
记住,对于上表来说,№1,9,12,15 都没有发生。
需要多久才能被收购?
在我们的数据集中,绝大多数初创公司都是在成立 10 年内被收购的。
Figure 11
收购数量最多的顶级风投公司
最后,我们绘制了 10 大风投公司的图表(按照通过收购退出的数量排序)。
Figure 12
从 1960 年到 2015 年,思科投资、谷歌风险投资、微软风险投资、IBM 风险投资集团、惠普风险投资和英特尔投资是最活跃的企业风险投资者。雅虎和苹果没有风险投资部门。
甲骨文确实有一个风险投资部门,但它不再投资初创公司了。
EMC Ventures 现在是戴尔技术资本。
方法学
上述分析和 Tableau 中的仪表板基于从这里下载的数据,这些数据收集了 1977 年至 2015 年间成立的全球公司以及 1960 年至 2015 年间的收购信息。公司按行业分类。该图可能不包括在此期间成立和资助的所有公司。如你所见,数据中也有一些偏差。
创建这篇文章的源代码可以在这里找到。我将很高兴收到关于上述任何反馈或问题。
磁带的故事(或:如何让你的数据说简单的英语)
Do you know? (Picture by Ed Monkton)
数据=头疼。听起来熟悉吗?你可能从事销售、运营、客户服务、营销、产品、工程或任何其他工作;每个人都会受伤。
我曾在收入从 0 到 2.5 亿美元的企业中工作过,将等式改为数据=决策……在正确的时间做出正确的决定,朝着正确的方向前进。我学到的一件事是获取数据来说简单的英语。这篇文章只是关于这样做的一种方法——一个已经不再使用但仍然有效的老技巧。这不是一切,但这是一个很好的开始。
在书中,这被称为控制(或“XmR”)图。我称之为“我应该关心”图表。
TL;灾难恢复—告诉您某些事情已经改变的数据
如果现在你的业务/奖金/信誉/【你重视的东西】岌岌可危,因为你对定期跟踪的 KPI 的变化反应一贯缓慢或草率,那么这篇文章对你很重要。
当真正重要的是如果和的 KPI 已经改变了多少时,控制(或“XmR”)图结束了猜谜游戏。它检测每日/每周/每月数据中有意义的变化—销售、投诉、回扣、NPS 等—以便您知道何时做出反应。
在这篇文章的最后,我分享了一个模板,你可以用它来实践。这篇文章是根据上下文写的,以防你认为这句话适用于你,但你想核实一下。它也有高质量的图片。
Should I care? Do you care? Does anybody care? (Picture by Charlie Taylor)
如果疼,说明什么东西坏了
斯坦(真人;化名)在一家快速发展的企业中管理着一个 200 多人的运营团队。他必须确保业务能够吸收用户的指数级增长——产品发货、客户得到支持、人员得到雇佣、流程得到实施、工作实现自动化。
What’s your plan?
斯坦是个优秀的行动负责人。凡事都有计划;每个计划都有 KPI。然而,你不需要通过和迈克·泰森比赛来了解现实>计划。问题是如何预见打击的到来,并逆来顺受——换句话说,何时以及如何调整计划——因为被打脸(或害怕它会发生)是一种痛苦。
斯坦的第一个痛苦是担心生意会停滞不前。由于缺乏吸收增长的能力,营销和销售部门将不得不推迟新库存的到来或新员工的入职。他的第二个痛苦是害怕他看不到自己的深度。奖金、信誉、职业发展——今天的判断失误会让明天的回报受到质疑。
我问了斯坦他的经历。
我需要的不仅仅是漂亮的图表。数据应该回答一个问题,所以我知道要采取行动。当它不这样做时,我用直觉来填补空白。在熟悉的地方没问题,但在不熟悉的地方,这是试错法。当计划没有及时改变时,这可能是一个问题…但我不知道如何更快地发现数据的变化。你知道吗?
Up and Down, Up and Down (Caption from Venga Boys’ 1999 track: “Up and Down”)
金发女孩是一个童话故事
记得那次你改变了计划——不要太早,也不要太晚;不多也不少。刚刚好。你一次又一次地做对了。
不——因为企业是系统。事物通过它们流动(物理材料、数字内容、对话片段);在某些点上,你有更多的控制权,而在另一些点上,你的控制权则更少;有使事物向不平衡倾斜的反馈回路和维持和谐的回路;而且有延迟。
这就是系统的感觉:
- 我们用完了 ____
- 我们有太多的 __
- 花在 __ 上的钱太多了
- 对 __ 关注不够
- 为什么我们得到了这么多 __
- 下次多拿点 __
引发匆忙和克制的延迟反应和过度反应。草率和反应不足会导致延迟,还会增加一点“以防万一”。
我不是说所有这些都有一个单一的解决方案。事实并非如此:业务可能很复杂,许多因素都会引发这些问题。
我想说的是,更敏锐地发现数据中的信号将有助于你在手枪实际开火时(而不是之前或之后)走出大门,并根据比赛的变化需求调整你的努力。
换句话说,有一种方法可以让你的感官变得敏锐。
Shovel-ready
告诉我一些我不知道的
这里有三件事(如果你都知道,我们一起出去玩吧):
- 在 1924 年,一位电话工程师做了一张图来区分自然变异(即不要反应)并发出有事发生的信号(即 react),都是用常规的时序图(即。x 轴上的时间,y 轴上的 KPI)
- 有完善的规则来测试是否有事发生;还有一套更简单更实用的规则可以满足大多数情况
- 这些图表和规则不在 Excel 或 Google Sheets 工具栏中
这是控制图,也称为 XmR 图。在网上搜索这两个词,你可能会找到大量枯燥的技术信息。我推荐两个简单明了的信息来源:
做一个控制图,你会得到这样的东西:
Now you see it
- 灰色和彩色点是 KPI 在每个时间点的实际值
- 蓝线是给定时间点 KPI 的平均值;当系统改变时,蓝线移动并显示系统移动了多少
- 蓝色阴影区域是我们预期值下降的区域——即。它反映了系统基于其运行方式的自然变化
- 彩色点是系统性能变化的信号,即。系统脱离了自然变化——向你展示极移何时开始的
没有上下文,我们只会看着灰点,试图理解它们。数字在转化为文字之前毫无意义,而文字是空洞的,除非它们植根于我们可以信任的东西——直觉,在它可靠的情况下;大多数其他情况下的统计。控制图给数据一个你可以信任的声音。
你看着数据,它告诉你:我变了,这是我开始变的时候,这是我变了多少。现在由你来决定是否做出反应,改变计划。
那是什么——你没打算改变计划吗?那是改天的文章…
它可以是任何类型的数据。
- 如果是客户数据(如销售或 NPS),那就是客户的声音
- 如果是商品数据(如股票),则是流程的声音
- 如果是软件数据(比如 bug),那就是代码的声音
- …你明白了
如果你想做一个控制图,可以用 MATLAB 来做。不要尝试在 MATLAB 中做。
这里是我做的一个控制图 Excel 模板;用这个。如果你卡住了,让我知道。如果你认为我犯了一个错误,让我知道。如果你读到这里,心想,嗯——这并没有我想象的那么无聊,请告诉我。
我花了几年时间收集数据来说简单的英语,这只是一个例子。如果这对你有帮助,那么让我知道还有什么是有帮助的,我会分享我所知道的。
PS。如果你喜欢这篇文章,你可能会喜欢我的其他一些关于产品粘性的文章:
DAU/MAU 是排名第一的粘性指标。以下是如何得到它的权利。
blog.usejournal.com](https://blog.usejournal.com/fooled-by-stickiness-a53d241ba463)*
人才获取创新:利用人工智能进行简历筛选
Stay on top of Talent Acquisition’s latest innovations (in 60 seconds or less)!
今日热点:利用人工智能进行简历筛选。
人工智能在招聘中的应用最近成为头条新闻——但它实际上意味着什么呢?我们来看看现实生活中可能改变你筛选、面试和招聘方式的一个应用。
问题: 人工筛选简历是一项繁琐、累人的工作,尤其是收到的简历中有 75% — 88%是**不合格的。**此外,人工筛选简历往往缺乏标准化,可能会陷入无意识的偏见。
解决方案: 分分钟自动筛选数千份简历的人工智能。
结果: 候选人以近乎完美的准确度被筛选出来,并按照面试优先顺序呈现给招聘经理。这项技术为人才招聘专家节省了大量时间。利用人工智能技术,过去需要数百小时才能完成的事情几乎可以立即完成。
预测: 这项技术将腾出时间,以便人才招聘可以专注于最重要的事情:面试和建立他们最好的团队。这项技术对于大规模招聘尤其有价值。
在 YouTube 上观看此短片下载、订阅或分享!
你在寻找一个 AI 解决方案来自动化简历筛选吗?我们可以帮你找到 (点击这里)
Share on LinkedIn and impress your boss!
Share on twitter and show off to your followers!
原载于 2016 年 11 月 15 日ideal.com。
推特表情符号讲述的故事
《权力的游戏》的视觉舆情分析
本文是我和我的同学吉安娜·甘地 为完成马里兰大学帕克分校 INST 760 课程的作业要求而进行的数据可视化项目的成果。
社交媒体平台由于其提供的表达自由,最近已经成为了解公众情绪的流行来源。为了理解情感、网络、用户参与度等,已经对公开可用的 Twitter 数据进行了大量的文本分析和研究。因为推特是公众表达的真正来源。但是人们多久会考虑分析这些推文中使用的表情符号来理解流行情绪呢?
根据《广告周刊》引用的统计数据,92%的网民使用表情符号。
Twitter 报告称,仅自 2014 年以来,已有超过 1100 亿个表情符号被发布。这些丰富的表情符号是一个未开发的宝藏,可以告诉我们很多故事和见解。
作为《权力的游戏》的粉丝,这个受欢迎的电视节目显然是我表情符号分析的主题选择。我和我的同学决定创建一个可视化工具,从 Twitter 上与# GameOfThrones 标签相关的推文中探索数百万个表情符号。表情云比单词云更有吸引力,有趣,同时提供清晰的图片。
我们收集了过去四季的数据,使用 D3.js(一个 JavaScript 可视化库)构建了一个交互式可视化工具。这个工具给了我们很多有趣的故事,揭示了公众对《权力的游戏》角色的看法。
我们发现了什么?
Interactive visualization: Emoji clouds for Game of thrones characters and relationships
1.总体最高公众情绪表明高参与度
Emoji cloud for overall sentiment — a combination of all GoT characters
对于一个用高分辨率图形制作的龙、雪僵尸和雪龙的节目来说,人们对龙着迷并不奇怪🐉。占主导地位的表情符号😱,😭表示震惊和绝望,而👏 👌和🙌表示用户正在欣赏该节目。所以总体来说,顶级人气表明这部剧非常吸引观众。还有,看起来《冰与火之歌》更火🔥比冰还多。
2.乔恩的死是悲惨和令人心碎的
Top sentiments — Jon Snow
琼恩·雪诺是推特上讨论最多的热门人物,我们有很多情感数据要分析。他的表情云充满了绝望和震惊😭,😱,以及😢我们分析说,主要是在第五季最后一集琼恩·雪诺被刺死的时候。
还有,主宰火🔥表情符号告诉我们琼恩·雪诺的原名和他的坦格利安背景是如何在推特上的粉丝中变得非常受欢迎的。
另一个有趣的发现是,一个角色和完全不相关的表情符号之间的相关性可能经常发生。在琼恩·雪诺的表情云中,我们发现了一个比萨饼🍕由于多种原因而出现,例如达美乐披萨为乔恩最喜欢的披萨做广告,或者人们在推特上说他们正在 GoT 马拉松比赛中吃披萨。
3.粉丝们敬畏艾莉亚,并鼓励她的行动
Emoji cloud — Arya Stark
Arya 的表情云主要是鼓励和力量的表情,比如🙌,👏,💪,以及👌。她的可怕的狼🐺和她的剑针🗡都暗示了她的坚强性格。
4.阿多之死令人悲痛,而乔佛里之死却备受庆祝
阿多和乔佛里的表情云对比显示了粉丝对幻想世界中虚构人物的爱或恨。所有暗示悲伤和心碎的表情符号都用在了与阿多之死有关的推文中,而暗示派对和庆祝的表情符号则用在了与乔佛里之死有关的推文中。
5.人们嘲笑萨姆的痛苦
Emoji cloud — Samwell Tarley
山姆威尔·塔利的表情云有一个独特的表情符号—💩一堆粪便。他在推特上突然成名,因为他在城堡里辛苦工作,被困在清洁便盆、堆放书籍和端汤的平淡无奇的日常工作中。
6.剧透警报通常涉及乔恩和丹妮莉丝
虽然与角色无关,但像“红色警报”这样的表情符号经常在剧透警报的背景下弹出。在所有的表情符号中,警告表情符号只在乔恩和丹妮莉丝的关系中出现,这表明大多数剧透警告都围绕着这一对。
7.眼泪并不总是意味着悲伤。快乐的眼泪也是一种东西!
琼恩和珊莎的关系表现出一张引人注目的支配哭泣的脸😭我们想知道为什么。事实证明,在经历了五个漫长的痛苦季节后,人们在团聚时流下了幸福的泪水。
这种可视化背后的设计过程
我们的目标是创建一个通过表情符号展示公众情绪的数据故事。在创建概念草图之前,我们经历了一系列的头脑风暴会议,并通过亲和力图表进行了分析。然后,我们创建了一个低保真度的功能原型,以接收进一步迭代的反馈。
The data visualization design process
Initial prototype
设计决策
- 点击脸部触发表情云,表情云会重新排列,以显示推文中与该角色一起使用的表情。
- 表情符号根据其出现的位置调整大小。更大的表情符号显示出与角色更强的联系,传达出主流的公众情绪。
- 面孔之间的可点击链接清楚地展现了两个角色之间的联系。链接是互动的,点击它们会重新构建表情云,以显示在一条推文中与两个角色一起使用的表情。
我们实现了我们的设计目标,让 TweetCloud 成为一个简单、迷人和用户友好的讲故事工具。面部和表情符号创造了一个视觉上吸引人的故事,从可视化中可以了解到角色角色的有趣见解。这种设计可以推广到可视化任何其他数据集,如趋势电影或其他电视节目,以捕捉有趣的故事和细节。
驯服 LSTMs:可变大小的小批量和为什么 PyTorch 对你的健康有益
如果你使用过 PyTorch,你可能会感到兴奋,精力增加,甚至想在阳光下走一会儿。你的生活感觉又完整了。也就是说,直到您尝试使用 RNNs 进行可变规模的小批量生产。
并非所有的希望都破灭了。读完这篇文章后,你会回到你和 PyTorch 私奔到日落的幻想中,而你的循环网络达到了你只在 Arxiv 上读到过的新精度。
我们将开发的忍者技能:
- 如何在 PyTorch 中实现每个小批量中序列大小可变的 LSTM。
- PyTorch 中填充序列和填充序列的作用。
- 通过时间屏蔽反向传播的填充令牌。
TL;DR 版本:填充句子,使所有句子长度相同, pack_padded_sequence ,遍历 LSTM,使用 pad_packed_sequence ,展平所有输出并标记,屏蔽填充输出,计算交叉熵。
为什么这很难,为什么我在乎?
速度和性能。
将可变长度的元素一次输入到一个 LSTM 中是一个巨大的技术挑战,PyTorch 等框架已经很大程度上解决了这个问题(Tensorflow 也有一个很好的抽象,但它非常非常复杂)。
此外,文档不清楚,例子太旧。通过对来自多个例子而不是一个例子的梯度有一个更好的估计器,正确地做这将加速训练和增加梯度下降的准确性。
虽然 rnn 很难并行化,因为每一步都依赖于前一步,但我们可以通过使用迷你批处理获得巨大的提升。
序列标签
虽然我不能帮你解决你对贾斯汀比伯的困扰(我不会说),但我可以帮你对你最喜欢的 JB 歌曲进行词性标注。
这里有一个歌曲句子的例子:“现在说对不起还来得及吗?”(删除了’‘至’‘和’?')。
LSTM/GRU model we’re building
数据格式化
虽然您可以进行大量的格式化,但我们不会…为了简单起见,让我们用不同大小的序列制作这一批人为的数据。
*sent_1_x = ['is', 'it', 'too', 'late', 'now', 'say', 'sorry']
sent_1_y = ['VB', 'PRP', 'RB', 'RB', 'RB', 'VB', 'JJ']sent_2_x = ['ooh', 'ooh']
sent_2_y = ['NNP', 'NNP']sent_3_x = ['sorry', 'yeah']
sent_3_y = ['JJ', 'NNP']X = [sent_1_x, sent_2_x, sent_3_x]
Y = [sent_1_y, sent_2_y, sent_3_y]*
当我们将每个句子输入到嵌入层时,每个单词都会映射到一个索引,所以我们需要将它们转换成整数列表。
Indexing an embedding matrix
这里我们将这些句子映射到它们对应的词汇索引
*# map sentences to vocab
vocab = {'<PAD>': 0, 'is': 1, 'it': 2, 'too': 3, 'late': 4, 'now': 5, 'say': 6, 'sorry': 7, 'ooh': 8, 'yeah': 9} # fancy nested list comprehension
X = [[vocab[word] for word in sentence] for sentence in X]# X now looks like:
# [[1, 2, 3, 4, 5, 6, 7], [8, 8], [7, 9]]*
分类标签也是如此(在我们的例子中是 POS 标签)。这些不会被嵌入。
*tags = {'<PAD>': 0, 'VB': 1, 'PRP': 2, 'RB': 3, 'JJ': 4, 'NNP': 5}# fancy nested list comprehension
Y = [[tags[tag] for tag in sentence] for sentence in Y]# Y now looks like:
# [[1, 2, 3, 3, 3, 1, 4], [5, 5], [4, 5]]*
招数 1:通过填充使 mini-batch 中的所有序列具有相同的长度。
盒子里有什么东西,有各种不同的长度?不是我们的小批量!
为了让 PyTorch 完成它的工作,我们需要在填充之前保存每个序列的长度。我们将使用这些信息来掩盖损失函数。
*import numpy as npX = [[0, 1, 2, 3, 4, 5, 6],
[7, 7],
[6, 8]]# get the length of each sentence
X_lengths = [len(sentence) for sentence in X]# create an empty matrix with padding tokens
pad_token = vocab['<PAD>']
longest_sent = max(X_lengths)
batch_size = len(X)
padded_X = np.ones((batch_size, longest_sent)) * pad_token# copy over the actual sequences
for i, x_len in enumerate(X_lengths):
sequence = X[i]
padded_X[i, 0:x_len] = sequence[:x_len]# padded_X looks like:
array([[ 1., 2., 3., 4., 5., 6., 7.],
[ 8., 8., 0., 0., 0., 0., 0.],
[ 7., 9., 0., 0., 0., 0., 0.]])*
我们对标签做同样的事情:
*import numpy as npY = [[1, 2, 3, 3, 3, 1, 4],
[5, 5],
[4, 5]]# get the length of each sentence
Y_lengths = [len(sentence) for sentence in Y]# create an empty matrix with padding tokens
pad_token = tags['<PAD>']
longest_sent = max(Y_lengths)
batch_size = len(Y)
padded_Y = np.ones((batch_size, longest_sent)) * pad_token# copy over the actual sequences
for i, y_len in enumerate(Y_lengths):
sequence = Y[i]
padded_Y[i, 0:y_len] = sequence[:y_len]# padded_Y looks like:
array([[ 1., 2., 3., 3., 3., 1., 4.],
[ 5., 5., 0., 0., 0., 0., 0.],
[ 4., 5., 0., 0., 0., 0., 0.]])*
数据处理汇总:
我们将单词转换成索引序列,并用零填充每个序列,这样一批单词的大小就都一样了。我们的数据现在看起来像:
*# X
array([[ 1., 2., 3., 4., 5., 6., 7.],
[ 8., 8., 0., 0., 0., 0., 0.],
[ 7., 9., 0., 0., 0., 0., 0.]])# Y
array([[ 1., 2., 3., 3., 3., 1., 4.],
[ 5., 5., 0., 0., 0., 0., 0.],
[ 4., 5., 0., 0., 0., 0., 0.]])*
模型
我们将使用 PyTorch 创建一个非常简单的 LSTM 网络。这些层将是:
- 把…嵌入
- LSTM
- 线性的
- Softmax
招数二:如何使用 PyTorch pack_padded_sequence 和 pad_packed_sequence
概括地说,我们现在正在给一个已经填充了每个元素的批次供料。在向前传球中,我们将:
- 嵌入序列
- 使用 pack_padded_sequence 确保 LSTM 看不到填充的项目
- 将打包的批处理运行到 LSTM 中
- 使用 pad_packed_sequence 撤消打包
- 转换 lstm 输出,这样我们就可以馈送到线性层
- 通过 log_softmax 运行
- 将形状转换回来,以便我们以(batch_size,seq_len,nb_tags)结束
技巧 3:屏蔽掉我们不想在损失函数中考虑的网络输出
Mask out those padded activations
最后,我们准备计算损失函数。这里的要点是,我们不想考虑填充元素的网络输出。
***直觉预警:*考虑这样做的最佳方式是扁平化所有网络输出和标签。然后计算这一序列的损失。
哇,就这么简单。现在,您可以使用小批量更快地训练您的模型,并继续痴迷于 JB(仍然不会告诉,不要担心)。
我知道你现在的感受…
这当然是一个非常简单的 LSTM。你可以做些什么来美化你的模型(不全面):
- 用手套嵌入初始化。
- 使用 GRU 细胞。
- 使用双向机制(别忘了修改 init_hidden)。
- 通过用卷积网络创建编码向量并附加到单词向量,使用字符级特征。
- 添加辍学。
- 增加层数
- …太多了
- 当然,使用 Python 的最佳 hyperparemeter 优化库进行非常彻底的超参数搜索: 试管 (声明:我写了试管)。
总而言之:
这就是在 PyTorch 中通过向 LSTM 提供可变长度的批量输入来恢复理智的方法
- 首先按最大序列对输入进行排序
- 通过填充到批中最大的序列,使所有长度相同
- 使用 pack_padded_sequence 确保 LSTM 看不到填充的项目(脸书团队,你真的应该重命名这个 API)。
- 使用 pad_packed_sequence 撤消步骤 3。
- 将输出和标签展平为一个长向量。
- 屏蔽掉你不想要的输出
- 计算交叉熵。
完整代码:
出租车去冯克豪斯
不要试图把所有的知识都记在脑子里。你的大脑是一个可怕的信息存储媒介。把它放在它该在的地方:在软件里。并学会如何使用它。
我最近在柏林参加一个会议(柏林技术开放航空)。活动在一个叫 Funkhaus 的地方举行,离我在柏林米特的酒店很远。在这种情况下,我通常会打开我的优步应用程序,告诉它我想去哪里,然后优步的软件会给我发送一个司机,然后他会带我去我想去的地方。
可悲的是,优步在柏林是不存在的,因为政客们把他们的灵魂卖给了说客,这些说客扼杀了所有来自外部的创新尝试,却没有提供任何合理的对等物。所以我不得不体验德国传统出租车行业的迷人服务。
我用一个叫做 MyTaxi 的可怕的应用程序叫了一辆出租车,它缺乏让优步如此有用的所有功能。没有内置支付,没有评级,没有乘坐管理。只要大声喊一声“我在这里!”所有出租车,然后有人可能会来,如果你祈祷足够努力。
出乎意料的是,一辆出租车到了,我告诉司机我想去 Funkhaus,他说不知道那是哪里。巨大的建筑,重大的事件,一千或更多的与会者,但出租车司机从来没有听说过。对我来说很奇怪,但是没关系,没问题。我想没有人能知道所有的事情。正如哲学家唐纳德·特朗普曾经说过的,“没人知道这份工作有多难。”但谢天谢地,谷歌的机器知道。
“在谷歌地图上输入‘funk Haus’就可以了。这对我很有效,”我说。出租车司机开始摸索他的智能手机,问我地址。他为什么要地址?柏林有多少个冯克豪斯?但我没问,给了他街名:Nalepastrasse。然后他问我街道号码。“我没有电话号码,只有街道名”,我说。活动组织者只公布了街道名称。有点明显,因为这个地方太大了,几乎是整条街上唯一的东西。他们还不如叫它芬克豪斯街,而不是纳勒帕斯大街。但是没有,出租车司机没有被吓住。他需要一个确切的地址,否则他不能去。他可能想象纳勒帕斯大街会环绕东德,但事实并非如此。也许是德国的东西。
然后,我不骗你,司机拿出一本又大又旧的柏林街道手册,上面有数百页街道名称和街区地图。我的下巴掉到了汽车的地板上。我上一次看到这样的书是在 1997 年左右。我认为这可能是一个恶作剧。有人在和我开玩笑。某个地方肯定有一台照相机。接下来,司机可能会问我是否可以去查理检查站,因为他知道它在哪里。我试图保持友好。我想,下周我就可以上德国电视了。
有几分钟,我带着越来越大的困惑,看着德国出租车司机看似随意地敲着智能手机,翻看满是街道地图的页面。我在这里大方地使用了“司机”这个词,将这个词扩展到包括一个坐在驾驶座上,做了很多敲击和翻转,但没有实际驾驶的人。但是经过五分钟的不开车,我受够了。
“看在上帝的份上,让我带我们去吧,”我说。我手里拿着我的智能手机,启动 Waze,输入“Funkhaus”,点击 Go,然后说,“我们走,一直往前走!”在接下来的 20 分钟里,我把我们带到了纳勒帕斯大街。我想也许我应该向司机收费,而不是反过来,但我决定反对,因为它在德国电视上可能看起来不太好。这是我最大的市场。
到达目的地后,我付了出租车费,司机感谢我告诉他冯克豪斯在哪里。这也许是最令我困惑的。有一个出租车司机,他认为他必须知道所有东西在哪里。但是这在 21 世纪已经没有任何意义了。软件知道所有东西在哪里。他需要做的是学会如何通过智能手机上的导航仪询问软件。对出租车司机来说,这似乎是一项有用的技能。我在完全不知所措的情况下离开了汽车,确保对着电视观众向各个方向微笑。
那个星期,我又两次尝试使用名为 MyTaxi 的灾难软件,每次都有可预见的坏结果。因为它是由一个拒绝接受世界在前进的行业提供的。那么你能期待什么呢?我手机上的支付方式比我衣柜里的内裤还多。但是许多出租车仍然只收现金。还需要我多说吗?
就这样。
不要试图把所有的知识都塞进你的脑袋里。你的大脑是一个可怕的信息存储媒介。把它放在它该在的地方:在软件里。学会怎么用就好了。
我的团队希望在你的工作生活中为你导航,这样你就可以不再把所有事情都放在脑子里。 加入我未来的敏捷实践 。
TD 在强化学习中,最简单的方法
更新:学习和练习 TD 方法的最好方式是去http://rl-lab.com/gridworld-td
假设你正在驾驶装有 GPS 的汽车。在旅程开始时,GPS 会给你一个到达时间的估计值(基于统计数据),当你开车遇到交通堵塞时(或者没有),它会改进估计值并给你其他到达时间。
您会注意到,在旅程的每一段,您都会得到一些关于到达时间的估计。
现在假设你的全球定位系统没有给你任何估计,但存储的数据,直到你到达,然后给你一个详细的报告,每段路花了多少时间。这对你有用吗?
答案会是:这取决于你想做什么。
但肯定的是,你会感谢早期的反馈,即使不是很准确。
这就是蒙特卡罗和时态差的区别。
示例中的后一种方法是基于蒙特卡罗的,因为它会等到到达目的地后再计算行程各部分的估计值。而前者是时间差异。
事实上,如果将蒙特卡罗(MC)方法和动态规划(DP)方法结合起来,就得到时间差分(TD)方法。
注意:TD 将被记为 TD(0 ),这意味着它将向前看一步。TD(0)是 TD(n)的特例。
回想一下,在 MC 中,我们播放一整集,直到结束,然后我们计算该集中出现的每个州的折扣奖励。我们做了大量的事件,然后我们平均每个状态的不同值。
在 DP 中,我们随机初始化所有状态,然后根据周围状态的(先前计算的)值迭代计算每个状态的值。我们一直这样做,直到我们注意到任何状态值都没有显著的改善。
政策预测
我们已经看到,在 MC 中,我们播放一集直到结束,然后我们向后移动,给每个状态分配该集的贴现收益 G。但这意味着我们必须等到最后才能知道 G.
的值,然而在 TD(0)中,我们根据下一个状态的 估计值 来更新当前状态。还记得 GPS 的例子吗,在某一点上,GPS 可能会注意到您的速度下降到 10Km/h,因此它会将其到达时间的估计值更新+30 分钟,但这可能是一个非常短暂的减速,几分钟后您会再次加速,GPS 会将其估计值更新-20 分钟。
与 TD(0)相同,V(s)根据以下公式更新:
where α is the step size ∈ ]0,1], 𝛄 is the discount factor
这是一个增量平均计算。查看文章末尾的“增量平均计算”了解详情。
很明显,仅基于一个事件,对 V(s)的估计是不准确的。和你那天的汽车旅行一样!只做一次,你不会很好地估计总时间和每一部分的时间。也许那天你是幸运的,没有交通堵塞,或者相反,你是不幸的,由于车祸你被困在一个不寻常的堵塞中。
但是如果你每天都这样做(多放几集),你就能每天都精确你的估计。
TD(0)中策略评估的算法(伪代码)如下:
Evaluate_Policy(policy):
randomly_initialize_non_terminal_states_values()Loop number_of_episodes:
let s = start_state() # Play episode until the end
Loop until game_over(): let a = get_action(policy, s, 0.1)
# get action to perform on state s according
# to the given policy 90% of the time, and a
# random action 10% of the time. let (s', r) = make_move(s, a) #make move from s using a and get
#the new state s' and the reward r # incrementally compute the average at V(s). Notice that V(s)
# depends on an estimate of V(s') and not on the return
# G as in MC
let V(s) = V(s) + alpha * [r + gamma * V(s') - V(s)] let s = s' End Loop
End Loop
政策控制
TD(0)中的策略控制有两种实现: SARSA 和 Q-Learning 。
SARSA 是一个 On-Policy 方法,这意味着它根据某个策略来计算 Q 值 ,然后代理遵循该策略。
Q-Learning 是一种 Off-Policy 方法。它包括根据贪婪策略计算 Q 值 ,但是代理不一定遵循贪婪策略。
萨尔萨
像往常一样,当执行动作时,你需要计算动作-状态函数( Q 值 ),因为它将状态和动作映射到估计。
在蒙特卡洛的文章中,我们解释了为什么单独的***【V(s)】无助于确定最优政策(计划,或在每个状态下采取的行动)。
因此,假设我们处于状态 s 并且我们想要基于状态 s 和动作来计算 Q 值 ,正如我们之前看到的,TD(0)使用增量平均值来计算任何状态的值。这个平均计算,用下一个状态的值来表示。
既然我们在计算 Q 值 ,那么我们就得到了下一个状态*【s’**的 Q 值 。然而 Q 需要状态和动作两个参数。
SARSA 解决这个问题的方法是,为了得到 Q 值, 在状态**【s’选择一个动作【a’(基于ε贪婪方法),然后当代理到达【s’时,我们将执行动作【a’**。
下图给出了一个 SARSA 示例。
**
Four actions per state: North, South, West, East
在左侧网格中,代理处于状态 s ,它计算向北移动的值(蓝色箭头),为了能够进行计算,它需要向东移动的 Q 值s’(灰色箭头)。
右边的网格显示当代理移动到状态**‘s’**时,它遵循策略先前决定的动作,并计算向东(蓝色箭头)动作的 Q 值…
以下是 SARSA 的伪代码:
*SARRA():
#initialization
for each state s in AllNonTerminalStates:
for each action a in Actions(s):
Q(s,a) = random()
for each s in TerminalStates:
Q(s,_) = 0 #Q(s) = 0 for all actions in s Loop number_of_episodes:
let s = start_state() # get action to perform on state s according
# to the given policy 90% of the time, and a
# random action 10% of the time.
let a = get_epsilon_greedy_action(s, 0.1) # Play episode until the end
Loop until game_over(): # make move from s using a and get the new state s'
# and the reward r
let (s', r) = make_move(s, a) # choose action to perform on state s'
# a' will be used executed in the next iteration
# but for the moment it will be used to get Q(s', a')
let a' = get_epsilon_greedy_action(s', 0.1) # incrementally compute the average at Q(s,a)
let Q(s, a) = Q(s, a) + alpha*[r + gamma * Q(s', a') - Q(s, a)] let s = s' # move to the next state
let a = a' # use the same action a' as determined above End Loop
End Loop*
q 学习
Q-learning 与类似,只是在计算***【s,a】Q(s,a)【s’,a’时,它使用贪婪策略从下一个状态s’中确定Q(s’,a’。
记住贪婪策略选择给出最高
Q 值 的动作。然而,这一点很重要,它不一定遵循那种贪婪的政策。*
这个形象的打击说明了 Q-Learning 的机理:
左侧网格显示了处于状态 s 的代理在向北行驶时计算 Q 值(蓝色箭头)。为此,它在计算中使用由状态 s(橙色箭头)的贪婪策略确定的 Q 值 。
右边的网格显示代理移动到状态*‘s’*,但不一定遵循贪婪策略确定的动作(橙色箭头),而是选择随机动作(蓝色箭头)。
Q-learning 的算法如下:
**QLearning():
#initialization
for each state s in AllNonTerminalStates:
for each action a in Actions(s):
Q(s,a) = random()
for each s in TerminalStates:
Q(s,_) = 0 #Q(s) = 0 for all actions in s Loop number_of_episodes:
let s = start_state() # Play episode until the end
Loop until game_over(): # get action to perform on state s according
# to the given policy 90% of the time, and a
# random action 10% of the time.
let a = get_epsilon_greedy_action(s, 0.1) # make move from s using a and get the new state s'
# and the reward r
let (s', r) = make_move(s, a) # choose the max Q-value (qmax) on state s'
let qmax = get_max_qvalue_on_state(s') # incrementally compute the average at Q(s,a)
let Q(s, a) = Q(s, a) + alpha*[r + gamma * qmax - Q(s, a)] let s = s' # move to the next state End Loop
End Loop**
增量平均计算
这一段说明了增量平均值的计算方法。
平均值的项以既有 A(n+1)又有 A(n)的方式排列。
Incremental Average Computation
请注意,1/(n+1)表示状态值和动作值函数中的α项。
结论
时间差异比动态规划方法更好,因为它不需要环境的模型,也不需要报酬和概率分布。TD 也比蒙特卡罗方法有优势,因为不需要等到一集结束才知道回报,只需要一个时间步。
相关文章
TDA 统治一切:番茄集群
忘了 K-Means 吧!
Credits: Original Paper
你想念应用数学吗?同样,我的目标是推广拓扑数据分析及其提供的多种可能性。前一篇文章提到了机器学习和深度学习,但 TDA 在其中的一个领域找到了用途:集群。
今天,我将尝试给出一些关于 TDA(用于拓扑数据分析)的见解,这是一个快速发展的数学领域…
towardsdatascience.com](/from-tda-to-dl-d06f234f51d)
由 TDA 提供支持的聚类概念已经被引入(不那么)著名的番茄(拓扑模式分析工具)算法,在这篇论文中介绍。与更常见的(scikit-learn 类)聚类算法相比,该算法有两个优点:
- 它给你一个方法来知道你的数据似乎有多少个集群;
- 它为您提供了一种将这些数据收集到不同集合中进行聚类的方法。
我开发了与本文相关的代码作为概念验证,其中肯定有需要改进的地方!不要放弃看一看,我很乐意接受你的批评;) !
Credits: Gaijin et al.
算法演示
出于解释的目的,我将限于二维考虑。核心思想是将 TDA 应用于我们的数据点的密度估计,提取其最大值,从而提取其表观质心。很好,但是怎么做?
为了回到实际的 TDA,你需要建立单纯形树单纯形复形** 的嵌套族,最终基本上是一个对应于密度函数的图、**。
- 首先,计算密度估计并初始化结构;
- 第二,给你数据集的每一个点一个索引;
- 第三,将每个数据点通过它们的索引插入到你的单纯形树中,通过赋予它们相应的密度值作为过滤*值;
- 第四,通过平均过滤值将每个点链接到其邻域图。
您最终得到一个实例化的图,并且您可以通过上层过滤来计算相应的持久性(~ 通过对所获得的过滤值进行递减排序来定义单纯复形的嵌套族,在我的 Github 库中给出了进一步的说明。
(*)概念解释见下文
Density Estimation over a ‘two moons’ Dataset
通过计算这种过滤的持久性图(和持久性条形码),您会得到这样的结果:
gen = ClusterGenerator(structure=’anisotropy’, randomize=45)
clf = ToMaTo(*gen.generate())
_ = clf.estimate_clusters(graph=True)
Obtained Persistence from the upper levels Filtration of the Density Estimate
前面的结果让您对数据有了真正的了解:对角线上有两个元素,对应于具有最大持久性的对象。在这种情况下,持久性表征了已经创建的结构在你的图中难以重叠的程度。基本上是指全局最大值(用于上层过滤)或全局最小值(用于子层过滤)。在我们的例子中,我们只观察到你的数据有*两个质心,*对应两个密度峰值。现在,您需要将每个数据点链接到这两个质心,以构建不同的聚类。这可以通过一个 UnionFind 结构( disjoint-set 数据结构)来实现,并遵循下面算法中提出的思想。
ToMATo Algorithm
该概念仅基于过滤值的递减顺序。很好的一点是,你只需要一遍所有的数据点。对于每个有序数据点,您有两种可能性:
- 要么它没有具有更高过滤值的邻居,那么它被认为是局部密度最大值;
- 它也没有,您需要查看不同的邻居,合并根以将相同的边链接到其对应的最重权重的根(越接近给定的质心,权重越高)。
为了避免创建多个集群,对于由 *tau,*给出的过滤值有一个条件,它确保小集群将被链接到更大的集群。python 化后,它给出了以下内容(从一个更大的函数中提取,解释对象方法):
比较每个数据点的不同根/父项后:
gen = ClusterGenerator(structure='moons', randomize=45)
clf = ToMaTo(*gen.generate())
_ = clf.estimate_density(graph=**False**)
clf.estimate_clusters(graph=**False**)
prd = clf.fit_predict(num_clusters=2, graph=**True**)
其他例子
其他例子在我的 Github 资源库 中提供,作为处理各向异性数据的,那个 k-means (最常用的聚类算法之一)有聚类的麻烦(参见 scikit-learn 示例)。
gen = ClusterGenerator(structure='anisotropy', randomize=45)
clf = ToMaTo(*gen.generate())
_ = clf.estimate_density(graph=**False**)
clf.estimate_clusters(graph=**False**)
prd = clf.fit_predict(num_clusters=3, graph=**True**)
(*)一些概念
对于那些对固有理论及其数学形式感兴趣的人来说,这里有一些元素可能会告诉你。
Credits: The Simplex Tree
这个理论有很多可能性,这些结果和深度学习之间的接口目前仍在开发中。许多想法将会出现,这使得这个话题变得非常热门和有趣!敬请期待来稿,想要更多就鼓掌;)!