TowardsDataScience-博客中文翻译-2019-三十八-
TowardsDataScience 博客中文翻译 2019(三十八)
原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
在人工智能中就像在生活中一样…专注于旅程
原文:https://towardsdatascience.com/in-ai-as-in-life-focus-on-the-journey-dd2fe319cdaf?source=collection_archive---------28-----------------------
让人工智能工作的架构决策
现在的趋势是对机器学习和深度学习编程框架、课程和最流行的算法的巨大迷恋。梯度推进机器、支持向量机、卷积神经网络、递归神经网络和长短期记忆(LSTM)风靡一时。在线培训和课程多如牛毛。教育机构、企业甚至政府都在快速推出人工智能培训项目——很难跟上!
- 285 亿美元-2019 年第一季度全球分配给机器学习的资金总额。(【statista.com】T2
- 180 亿美元——未来五年人工智能助理市场的估计价值。(【teks.co.in】T4)
- 1200 亿美元——到 2025 年底,人工智能驱动的硬件的估计全球销售额。(teks.co.in)
- 13 万亿美元——人工智能到 2030 年可能带来的潜在全球经济。(mckinsey.com)
- 14 倍——自 2000 年以来人工智能初创公司数量的增长率。(aiindex.org)
虽然人工智能的价值没有受到挑战——人工智能不仅仅是最热门的算法和 TensorFlow 或 Keras 中编写神经网络的几行代码——它需要一个完整的工作流程。从 ETL、预处理、特征工程、转换(以及代表实际算法的几行代码)、训练和推理——并使所有这些在生产环境中可扩展和健壮。问题不在于哪种算法或数学优化技术是最新的“时尚”问题是:如何使整个流程对组织可行?
这是人工智能工作流程的一个很好的代表:
Source: Building your AI data pipeline: The IBM IT Infrastructure Blog
这条管道的不同阶段具有不同的特征和相关的技术需求。例如:
接收或数据收集受益于边缘软件定义存储的灵活性,并要求高吞吐量。
数据分类和转换涉及聚合、规范化、分类数据以及用有用的元数据丰富数据的阶段需要极高的吞吐量,包括小型和大型 I/O。
模型训练需要一个性能层,能够以极高的吞吐量和低延迟支持机器学习和深度学习模型训练中涉及的高度并行的过程。
带推理的模型再训练不需要那么大的吞吐量,但仍然要求极低的延迟。
归档需要一个高度可扩展的容量层来存储冷归档和活动归档数据,该容量层以吞吐量为导向,并支持大型 I/O、流和顺序写入。根据要求,其中任何一项都可能发生在本地或私有或公共云中。
在代码方面,在每个 AI 学习者的旅程中,都有一段时间,他们对下面的 TensorFlow 实验感到高兴:
[## sunny-ML-DL/simple _ 张量流
从 sklearn 导入 tensorflow 作为 tf 导入 pandas 作为 pd .预处理导入 MinMaxScaler #关闭 TensorFlow…
github.com](https://github.com/Sunny-ML-DL/simple_tensorflow/blob/master/python_game_earnings)
一年前,我也会很开心。这是我之前看过的一个文档,叫做: 架构决策指南 。我推荐任何参与实施 AI 的人阅读这篇文档,甚至是那些立志成为实践者的人。
以下是文件中的一些问题:
数据源:对于关系数据库和 OLTP 系统,访问企业数据的最佳方式是什么?随着实时数据(例如股票市场数据),这个问题变得更加重要。例如,您是否需要使用云对象存储?记住,股市数据会在几秒钟内失去价值!
数据清理和转换:这里要考虑的问题是正在使用什么样的数据源类型,需要什么样的吞吐量。当涉及到集群级数据处理和机器学习时,Apache Spark 往往是首选。
数据仓库— 数据的持久存储:存储成本、数据类型、备份、存储容量等问题由此产生。大多数情况下,这可以是一个 SQL 或 NoSQL 数据库。
数据探索和可视化— Pandas、Scikit-Learn 和 Matplotlib 是这里的热门技术。要解决的问题:需要静态还是交互式可视化(Matplotlib 是静态的)?有哪些编码技巧?像 IBM SPSS Modeller 这样的技术不需要任何编码技能。
创造可操作的见解:每一项数据科学工作的好坏都取决于从中获得的可操作的见解。这里的关键问题是你有什么技能,需要并行或基于 GPU 的训练和推理吗?R and R 工作室可能因为 Python 和 Anaconda 而出名。但是对于并行和基于 GPU 的工作来说,它们并不理想。然而,所有 Apache Spark 作业本质上都是并行的。
最后,模型可能是优雅而美丽的——但是你想过你将创造的数据产品吗?你如何让你的模型被商业用户消费?在这里,你要考虑你的目标受众和所需的定制程度。Node-RED 在这里是一个很好的选择。虽然 Node-RED 是一个无代码/低代码数据流/数据集成环境,但由于其模块化特性,它支持各种扩展,包括仪表板扩展。
最后但同样重要的是,数据安全和治理!今天上网看看,你很可能会找到关于黑客的新闻。安全的基础设施和云服务是确保数据保护的良好开端。
这是一次旅行,不是吗?虽然用最流行的框架学习最新的 ML/DL 算法很诱人…最好专注于掌握上述所有步骤的一项关键技术/方法。那么我们可能会更好地准备实施端到端的人工智能工作流。
以防你错过了
原文:https://towardsdatascience.com/in-case-you-missed-it-bc143491ca4e?source=collection_archive---------34-----------------------
我最喜欢写的博客文章的精选列表
到目前为止,2019 年是我的博客年。我在五月份开始认真地写博客,五个月后,我必须说这是我所从事的最有回报的职业努力之一。通过我的博客,我学到了新的东西,认识了新的人,并对工作和生活形成了一种更加自律和勤奋的态度。
我很高兴地告诉大家,我现在已经写了足够多的博客来证明一次回顾。因此,今天我将重点介绍我的五篇博客文章——这些是迄今为止我发现学习和写作最愉快的文章。事不宜迟,这是清单。
- 理解神经网络——我在这篇文章上拼了命。直到今天,它仍然是我花了最多时间研究、写作和创作图形的帖子。这不是我阅读或鼓掌最多的作品,但却是我最引以为豪的一部。当他们想到人工智能时,神经网络是大多数数据人员目前想到的。在这篇文章中,我尽力用简单的英语和友好的视觉来解释神经网络是如何工作的。写这篇文章的时候我学到了很多,当我需要处理神经网络的时候,我还会时不时地引用它(我很健忘)。在我所有的帖子中,** 理解神经网络 最能代表这篇博客的主旨。**
- 提高技能的更好方法——虽然这是我迄今为止读过最少的作品之一,但也是写起来最有趣的作品之一。我对训练营行业(以及教育技术)充满热情——我最*完成了梅蒂斯的训练营,非常喜欢,并且我对如何改善体验有很多(主动提供的)意见。教育技术目前最大的缺点是事后发生的事情——尽管学习很有趣,但我们仍然需要找到一份体面的工作,这样我们才能支付账单。虽然 bootcamps 等人在教授学生基础知识方面做得很好,但他们目前在帮助学生建立必要的可信度以获得聘用方面做得不够(这个问题对于转行者来说尤其明显)。在这篇文章中,我想出了一个商业点子来解决这个缺点。
- 我有足够的钱退休吗?——开发和运行投资者退休前和退休期间财富的蒙特卡洛模拟是我过去几年工作的一大部分。在幕后工作,我从未直接感受到我公司的产品对客户的影响。因此,通过这篇文章分享我在工作中获得的一些知识真的很令人满意——如果它能帮助一些人改善他们的退休准备,那就太棒了!
- 维度的诅咒 和 了解 PCA —我作弊挑了两个。因为这两个职位是密切相关的。 维度的诅咒 探讨了为什么高维数据会困扰数据科学家。我个人从写这篇文章中获益匪浅——因为在写这篇文章之前,虽然我知道高维数据很麻烦,但我不知道为什么。做研究,拿出例子和插图确实巩固了我的概念。 了解 PCA 探索主成分分析,一种处理高维数据的流行算法。PCA 是一种非常有用的算法。你可能听说过自然语言处理中的主题建模吧?主成分分析对于数字就像用线性判别分析或 NMF 进行主题建模对于文字一样——主成分分析提取你的特征,并从你的数据中提取关键的潜在趋势(也称为主题)。这些潜在趋势有助于提高您对数据的理解,并最终允许您构建更好的模型。
- 让我们玩 21 点(用 Python) 和 教一个神经网络玩 21 点——我又一次作弊,选了两个帖子。编写这两个程序花了我很多时间——感觉我又回到了训练营。现在我全职工作,要写出像这样更复杂的作品并不容易。但是当我最终点击发布时,我获得的成就感是非常棒的。神经网络帖子特别有趣。起初我认为把它们放在一起很简单——只要用我的 21 点代码生成数据,放入神经网络,瞧。但这绝不是——我实际上花了相当多的时间来思考模拟我的目标变量的最佳方式,以便根据它训练的模型的输出是有用的。这个项目很好地提醒了我们,虽然每个人都喜欢模型,但数据科学家的真正工作(以及优秀分析师/科学家与伟大分析师/科学家的区别)是深入理解您的数据以及您试图用这些数据回答的问题。****
我希望你喜欢阅读我过去作品的精选。谢谢你的支持和欢呼!
对于我所有的帖子,请在这里查看我的帖子!
在数据科学中:细节很重要
原文:https://towardsdatascience.com/in-data-science-details-matter-ec8b27f626fc?source=collection_archive---------11-----------------------
等级制度。文字。颜色。
Credit: Graphiq
从建筑实践到数据科学领域,我一直对细节有着深刻的欣赏和兴趣。建筑必须经过深思熟虑的制作才能美丽——以熟悉、温暖和吸引人的尺寸和比例汇集材料。外部建筑系统必须细致入微,以保证热效率——冷时保持热量,反之亦然。
建筑的教训是细节很重要。然而,这个原则超越了建筑设计。史蒂夫·乔布斯曾经告诉我们:
“细节很重要,值得等待,直到把它做好。”
数据科学专业应该听从乔布斯的建议,尤其是在解释数据发现的时候。数据科学家有无数的库可以直接从 Python 中更快更容易地可视化数据集:Matplotlib、Seaborn、Plotly、Bokeh,不胜枚举。今天,我们期待即时的满足。我只需点击“立即购买”,几小时后我的包裹就会送到我家门口。或者,我简单地在 Seaborn 中运行一两行代码,得到一个甜蜜的条形图,对吗?好吧,我问你——细节在哪里?
建筑师的手绘草图可以有效地向另一个建筑师快速解释设计思想。同样,快速绘图可能有助于数据科学家快速浏览数据,或者与办公桌前的同事讨论数据。但是像架构一样,数据可能很难向实践之外的人解释。可视化必须经过提炼、修饰和精心策划,才能讲述一个关于数据的清晰而美丽的故事。还是那句话,细节很重要。
但是在数据可视化中,我们应该重点关注哪些细节呢?我认为我们可以将其分为三类:
1。层级
2。正文
3。颜色
等级制度
谈到数据可视化,大多数人说最好的经验法则是尽可能简单地讲述数据的故事。使数据易于导航的一种方法是在图形中使用层次结构。
等级的意思是“去排位”。因此,通过将信息分解为“分级”元素,我们可以在数据可视化中给予某些元素或多或少的权重。层次结构为读者提供了快速浏览内容的结构,并找到他们感兴趣的内容。层次结构向读者展示了如何参与和浏览数据可视化,从大的发现,一直到更精细的细节。
我们可以用多种方式提供层次结构,例如,标题、小标题、注释和更小的细节。此外,文本可以通过文本大小 (12pt 对 24pt)粗细(粗体对浅色)和其他重点(斜体对下划线)来提供层次。颜色还可以通过突出图形的某些元素来提供层次和引起注意。
所以教训是:
层级对信息进行“分级”,因此我们知道理解什么是重要的。
Credit: Canva
Credit: Alyssa Leverenz
文本
在我们的生活中有两种主要的字体:衬线字体和无衬线字体。
衬线应该用于文本长度较长的项目,比如书籍和文章。纵观历史,许多人声称衬线字体有助于处理长文本,因为它们有助于眼睛沿着一行*稳移动,从而使阅读更容易、更快——尤其是在文本行很长的情况下。考虑 serif 字体,如 Garamond、Georgia 或 Times New Roman。
无衬线字体应该用于文本长度较短的项目。Sans serif 是标题、致谢名单、列标题、图表中的文本等的绝佳选择。无衬线字符更简单,更容易区分任何大小。当您的数据分发给有视觉障碍的读者或仍在学习英语的读者时,这可能会有所帮助。考虑无衬线字体,如 Avenir,未来,或 Helvetica。
It takes people longer to understand the numbers in the serif graph on the right than it does to understand the numbers in the sans serif graph on the left. Credit: Howard Coale
Serif fonts can have many idiosyncrasies in their endpoints, widths, curves, and shapes that add more for the eye to take in at any given moment. In essence, serif creates more “data” for a reader to take in for each letter or number! Credit: Howard Coale
对比对于区分文字也很重要。你永远不知道你的数据结果会被如何使用。想象一下,你的情节通过视频投影仪显示在演示文稿中,投影仪洗掉了你的纯白背景上所有柔和的灰色文本,没有人能看懂任何内容!那太可惜了。为确保在任何设置下的易读性,建议的最小比率至少为 4:1 。
Max contrast is 21:1 — this means pure white text on a pure black background, or vice-versa. 1:1 means that the background color and your text color are the same. The recommended minimum for text contrast is 4:1. Source
所以教训是:
对较短的文本使用无衬线字体。对较长的文本使用衬线。有充足的对比。
颜色
选择颜色很难。听说过 RGB 颜色系统吗?它从红色、绿色和蓝色的组合中产生所有可能的颜色。告诉计算机定义每种颜色强度的数字输入范围为 0-255。所以举个例子:如果 R = 0,那么颜色中没有“红色”。如果 R = 255,G = 0,B = 0,那么颜色就是纯“红”。所以理论上,你可以把 R,G,B 组合成 256256256 = 16,777,216 种可能的颜色。那么,我们如何选择几种颜色,以最清晰、最容易理解的方式来可视化我们的数据呢?首先,我们必须了解颜色的基本元素。
颜色归结为三个要素:色调,价值和饱和度。
色调描述颜色本身。色调就是我们通常认为的描述颜色的东西:红色、蓝色、绿色等等。值是一个色调有多亮或者有多暗。例如,具有暗值的蓝色是“深蓝”,具有亮值的蓝色是“浅蓝”。饱和度是色调的强度或强度。低饱和度意味着更暗、更灰的颜色,高饱和度意味着更强烈的鲜艳颜色。例如,低饱和度的蓝色看起来像多云的天空,而高饱和度的蓝色看起来像晴朗的天空。
Hue is the color itself. Saturation is the intensity of the color. Value is the lightness/darkness of the color. Source
在某些情况下,色调、饱和度和值的组合有助于直观地显示数据中的模式或趋势。然而,如果你的数据尽可能的简单,观众会更快的理解你的数据。如果定量值在图表中很重要,最好用单色条或点来显示结果。如果有必要,您可以使用颜色在同一个图表上显示不同的类别。
The plot on the left converts all categories into a different color and merges them into a single bar. Keep it simple instead! The bar plot on the right only needs one color, because it breaks out each category as a separate bar. Quantities are much easier to compare in the graph on the right. Credit: Datawrapper
我们可以使用色相、明度和饱和度让数据更加清晰。我们可以用颜色来表示刻度,即增加或减少数值的等级。一种想法是使用渐变调色板,在较宽的值和饱和度范围内融合相反的色调(紫色和黄色,红色和绿色,或橙色和蓝色)。特别是,更大范围的值使得调色板即使对于色盲的人也是可访问的。
对于连续数据,您使用颜色渐变,对于分类数据,您使用不同的颜色。
梯度意味着:
"我是一个可能高于或低于我周围另一种颜色的量."
鲜明的颜色意味着:
"我和我周围的其他颜色毫无关系。"
In the graph on the left, the all-blue gradient color scheme may imply that “Ivan” is more important in the data than the other three people, when really, he is not. The graph on the right uses different hues, to give equal weight to all people being compared. The graph on the right also uses light and dark values to allow the categories to be distinguished even by those who are colorblind. Credit: Datawrapper
当数据讲述一个关于“低到高”趋势的故事时,可以使用渐变。当使用渐变显示数据时,渐变应该尽可能以相同的步长从亮到暗逐渐变暗。无论是彩色的还是黑白的,渐变都应该看得很清楚。
Intuitively, people understand light colors for low values and dark colors for high values. If using a gradient, limit the number of hues to one or two colors at a maximum. (Ex: light grey to dark blue, or light yellow to dark blue.) Credit: Datawrapper
直观上,人们理解浅色代表低值,深色代表高值。如果使用渐变,最多限制一到两种颜色。例如,浅灰色到深蓝色,或浅黄色到深蓝色。
如果比较的数据可能高于或低于*均值或基线量,那么发散调色板是一个不错的选择。使用这个调色板的好例子可能是显示各县的*均工资,或各州的*均气温。建议在渐变的中心使用浅灰色,在渐变的两边使用深色和互补的色调(紫色和黄色,红色和绿色,或者橙色和蓝色)。
A diverging palette should use two complementary hues, that are dark in value, with a light, desaturated color in the middle. The right graph is the better choice. Credit: Datawrapper
Complementary color pairs are recommended in a diverging color palette. Complementary colors are always on the opposite side of each other on the color wheel. Credit: Lacie Lynnae
你的绘图颜色越中性,就越容易使用颜色来突出显示数据。灰色是背景数据、注释的绝佳选择,或者只是为了让情节尽可能简约。为了让情节更生动,灰色可以是暖色的微妙阴影,如红色、橙色或黄色。
Too many colors can make the plot too noisy — making it hard to extract key insights. If you want to call attention to one particular element on your plot, use grey throughout and use one color to highlight. Credit: Datawrapper
为您的数据使用直观的颜色!比如我们都知道红色代表“热”,蓝色代表“冷”。在自然界中,我们都把绿色和树联系在一起,把蓝色和水体联系在一起。在美国,我们都知道共和党通常显示为红色,民主党显示为蓝色。当谈到交通、行为或表现时,从小我们就被教导红色意味着“停止”或“不好”,而绿色意味着“行”或“好”。
Use intuitive colors for people to understand the data faster. Avoid using other colors just to be different — and avoid using colors associated with something else (for example, using blue and red for male and female, because blue and red are so heavily associated with politics). Credit: Datawrapper
所以教训是:
为了强调,尽量少用颜色。对连续数据使用单色或双色渐变。分类数据使用不同的色调。使用直观的颜色。
记住——在一天结束时,我们数据科学家必须向世界展示的一件有形的东西,就是我们的图。把所有的精力都放在只有你能看到的 Jupyter 笔记本上,而花很少的时间在与人分享的情节输出上,这似乎是一种耻辱。因此,将层次、文本、 和 颜色的原则置于您的支配之下,使您的数据可视化易于阅读且美观。抓住它!
在我们信任的数据中
原文:https://towardsdatascience.com/in-data-we-trust-517bc40d1d35?source=collection_archive---------24-----------------------
每个算法都有一个设计者。每台计算机都有一个用户。所有数据的背后都是现实。那么,我们对技术有多确定呢?
Photo by Matthew Henry on Unsplash
奈特氏不确定性是经济学家弗兰克·奈特在 1921 年提出的一个观点。将* 100 年后,奈特的想法比以往任何时候都更加重要。
奈特对风险感兴趣。在经济学中,风险是可以被赋予发生概率的东西。例如,硬币正面落地的风险是 50%。另一方面,不确定性发生在结果未知的时候,因此任何给定的结果都不能被可靠地赋予概率。例如,想象翻转一个有无限多面的硬币;假设硬币是公*的,硬币落在任何一面的概率只有在面的数量已知的情况下才能知道。在那之前,我们是不确定的。
现在,让我们考虑奈提不确定性。想象一下,在掷硬币和足球比赛上下注(足球,如果你愿意的话)。硬币是由计算机抛的,它只能报告正面或反面,而足球比赛是冠军决赛,所以*局是不可能的。鉴于两种情况都有两种结果,我们可以说都是 50/50 的赌注。但这是真的吗?
直觉上,我们知道它不是。我们知道每个足球队都是不同的,由不同水*的球员组成。我们知道环境因素可能会影响比赛的结果,下雨可能有利于一个队,而阳光可能有利于另一个队。我们知道体育运动中会发生很多不可预测的事情,从躲闪的铲球到侥幸的射门,再到短暂的辉煌时刻。考虑到所有这些事情,我们直观地知道,仅仅因为有两种可能的结果,这两种结果中任何一种的可能性都是不一样的。
这是奈特氏不确定性。从形式上讲,奈提不确定性是关于风险概率分布的不确定性。如果你感到困惑,考虑一下抛硬币电脑。硬币通常是公*的,计算机被编程为只有两种结果。减少了可能影响硬币翻转的情有可原的因素的数量,因此我们非常确定硬币正面着地的风险是 50%。
在世界末日之后
下一个问题是为什么奈提不确定性很重要?大多数情况下,奈提恩不确定情景被认为是不确定的,并被自动视为不确定的。但有时人们不会——事实上,你可能已经犯了这个错误。
考虑一下这个问题:你是否倾向于相信计算机抛硬币比人抛硬币更确定,如果是这样,为什么!?我从来没有明确指出电脑扔的硬币是公*的,也没有说电脑插上电源了!你可能会说这是不公*的诡计,但这也证明了奈特氏不确定性的核心偏见:诬陷。
奈特氏不确定性是人们相信——通常是不公正的——某些框架比其他框架更确定的证据。技术哲学家大卫·比尔认为这是一个问题,尤其是计算机、数据和算法。比尔认为,因为人们通常不理解技术,算法等技术具有一种社会力量,可以对我们的行为产生不适当的影响。
这种现象的例子比比皆是。在新闻媒体中,认为数据支持自己立场的专家通常比那些提出自己观点的专家更有权威,尽管后者可能比前者更有经验。如果这太轶事了,考虑一下 2008 年金融危机前风险价值(VaR)的广泛使用。
VaR 是一种统计技术,它使用历史业绩数据来估计给定风险水*下的资产价值。使用标准差来衡量结果——标准差越大,事件发生的可能性越小。金融危机之前,VaR 被广泛使用。在危机期间,高盛(Goldman Sach)的大卫·维尼亚(David Viniar)有一句名言:“我们连续几天看到的都是 25 倍标准差的事件。”从数学上来说,宇宙的热寂应该发生在这个之前——显然有什么事情发生了。
VaR 是有缺陷的,因为它使用了历史数据,是的,但这是一个已知的缺陷。风险值作为一种技术的扩散有一个单独的原因:因为计算机这么说。大多数城市交易者不明白 VaR 在做什么,但是他们相信计算机和数学。这是奈提不确定性的一个经典例子,奈提不确定性是由奈提不确定性促成的,奈提不确定性被奈提称为技术无意识。对计算机的信任是毋庸置疑的,尽管进入计算机的数据以及由此得出的答案是完全不确定的;完全人类。
谁害怕天网?
“数据更了解数据”这句口头禅是可以理解的,尤其是在大数据能够发现个人可能永远看不到的宏观趋势之后。但这一口号也掩盖了两个重要的担忧。
首先,我们有被这种对数据的依赖剥夺权利的风险。大数据并没有产生我们希望理解的世界——但如果通过理解我们说服自己认识到自己的无知,人们可能会相信是数据而不是我们在幕后操纵。
其次,不质疑数据是一种诱惑。作为一句话,“数据知道得更好”,并不是有意的独裁,而是当我们记住所有技术背后都是人类行动者时,它在实践中变得如此。如果我们不首先将数据视为数据,就无法收集数据;算法可以反映我们的偏见;编写代码的人的兴趣可能与用户的兴趣不一致。那么,数据知道得更多,可能会掩盖情况的隐含现实:控制数据的的人知道得更多。
这些风险是技术无意识的产物,“数据知道得更好”,这是天生的。第三个来自奈特不确定性:如果所有数据、算法和计算机背后都是我们通常不会押注的人,那么押注于数据、算法和计算机的风险要比我们可能意识到的大得多。
所有这些并不是说我们不应该广泛使用数据。但是盲目地依赖数据会让我们变得盲目;如果我们没有大脑,那会对我们创造的机器说些什么呢?
深入看看卢卡·东契奇的表现
原文:https://towardsdatascience.com/in-depth-look-at-luka-doncics-performance-b69ff60004ba?source=collection_archive---------18-----------------------
卢卡·东契奇可以说是 2018-19 赛季迄今为止的年度最佳新秀,
他的表现让达拉斯小牛队有现实的可能性
进入今年的季后赛,目前在第八名中仅获得 5.5 场比赛。
他创造了惊人的数据,可以与一些历史上最伟大和目前最活跃的球员相媲美。
我稍后会详细介绍这一点,因为现在我想探索一下他游戏中的一些特定领域。
离合器时间是卢卡时间
每当我继续观看卢卡的精彩表演时(我住在欧洲的克罗地亚,所以不幸的是
没有赶上很多比赛,因为他们开始得晚,尤其是那些来自西部联盟的比赛),我总是注意到
卢卡是在比赛后期处理小牛进攻中所有棍子的家伙。
这让我在关键时刻看到了他的数据,这些数据令人印象深刻。在下图中:
Total clutch points for players in 2018–19 season — Image by Author
你可以在关键时刻查看前 60 名得分手。x 轴表示总得分,y 轴表示真实投篮命中率。除了东契奇,其他一些突出的球员还有奥拉迪波(他比东契奇高得多)和总得分前 3 名的球员(肯巴、哈登和垂怜经)。但考虑到东契奇只是一名 19 岁的新秀,这些数字简直令人吃惊。这让我想知道过去几年新秀在关键时刻表现如何。我收集了 2003-04 赛季(勒布朗的第一个赛季)以来的关键得分,得到了这张图表:
Total clutch points for rookies since 2018–19 — Image by Author
从图表中可以看出,卢卡是该范围内最好的新秀之一。得分比他高的运动员依次是布兰顿·詹宁斯、凯文·杜兰特、泰瑞克·埃文斯和德里克·罗斯。同样值得注意的是,他们的统计数据达到了全明星赛的水*,所以在接下来的几周内,东契奇可能会提高这些数据。总积分排名前十的其他公司是利拉德、马克卡宁、米切尔、威斯布鲁克和克里斯·保罗,这是一家非常好的公司。
东契奇的拍摄图表和播放/拍摄类型选择
拍摄图表是我在分析过程中最喜欢创建的东西。对于初学者,我们有定期拍摄图表。
Luka Dončić’s shot chart — Image by Author
这张图表并不真的令人难以置信,但我们通常可以看到卢卡在几乎所有领域都高于*均水*。而且他投了很多三分球,也没有满足于很多中距离跳投(尽管他远非真正的莫雷球投篮图)。
为了补充之前的短暂关键时刻分析,这里是迄今为止卢卡在关键时刻的所有投篮的投篮图。
Image by Author
他在中距离投篮非常有效,尽管大多数投篮来自三分球区和篮下。
NBA 的跟踪有几个类别的比赛,他们分为球员的每一个镜头。我试图想象出 don ici 更喜欢哪些行动,以及他在这些行动中效率如何。这里有一个图表显示。
FGM/FGA for Dončić based on play — Image by Author
这里要注意的是,这些并不都是 Donč ić制造/尝试的射门,而只是那些有某种分类的射门,如果我必须假设这些类型的比赛是什么,它们可能代表类似于接球射门和类似类型的比赛。所以即使我们说所有其他的比赛都是接球投篮,那也意味着他总共有 208 次接球投篮。这仍然会给我们留下更多他自己创造的镜头(无论是开车,后退镜头还是正常的引体向上镜头)。这消除了选秀前的疑虑,专家们质疑,鉴于他的一般运动能力,东契奇是否能为自己创造投篮机会。
卢卡和(退后一步)跳投
在那之后,我开始想象卢卡跳投的类型。
Jump shots taken by Luka Dončić — Image by Author
被称为跳投的投篮类型代表了我之前提到的接球投篮类型。从这张图表中我们可以看到,卢卡已经在开发一个标志性的动作,后退跳投。这肯定是相当复杂的动作。我想检查所有其他球员后退跳投的效率,但不幸的是,很难获得所有数据(由于从 nba api 获取数据的问题),所以我只是看了看一些应该是优秀射手和后退射手的球员。
因此,我用今年的一些最佳射手(至少是那些不是主要从内线/*距离进球的人)和卢卡·东契奇做了一个图表。
Step Back jump shots for some of the best scorers this year — Image by Author
他实际上离垂怜经并不远,场均只有 3 分。这真的很有趣,尽管他是新秀,但他与所有这些球员的效率相当接*,甚至比他们所有人都要多,除了哈登,他只是采取了荒谬的后退次数。对于东契奇来说,19 岁就拥有如此强大的工具将是一个巨大的优势。
为了完成这一简短的后退投篮和卢卡,我绘制了一张投篮图,其中包含了卢卡本赛季尝试的所有后退跳投。
Luka Dončić’s shot chart for step back jump shots — Image by Author
助攻
除了出色的得分能力,卢卡还擅长拥有出色的球场视野和寻找艰难的传球路线。他场均 5.4 次助攻,在新秀中排名第二,仅次于特雷·杨。他的 AST%(由该球员助攻的队友投篮百分比,因此 33%意味着球员 x 助攻了其他队友投篮的 33%)也很高,几乎达到了 Trae Young 的水*(27.5%比 36.5%),但鉴于 JJ Barea 在几场比赛前受伤,他的 AST%为 45%,是联盟最高的,所以 Donč的数字可能会在整个赛季进一步上升。在没有巴里亚的情况下,东契奇场均 8.8 次助攻(然而只有 6 场比赛)。
话虽如此,我很想知道谁是他在队中最喜欢的目标。
Field goals made on assist by Luka Dončić — Image by Author
迪安卓是他最喜欢的目标,几乎大部分的助攻都以扣篮结束。巴恩斯是第二受欢迎的目标,他在东契奇助攻下的射门更加分散。我也想象到了。
Shot Distance on field goals made by Dončić’s assist — Image by Author
我省略了三个助攻得分最少的球员,这样图表看起来不那么拥挤。在东契奇的所有助攻中,只有 14 个是中距离跳投。
结论
卢卡·东契奇正在经历一个惊人的赛季。我只涉及了他比赛的几个方面,并试图探索一些不常被提及的东西(比如后退跳投)。我甚至没有给出基本的统计数据,如 PTS/G,REB/G,AST/G,但他在今年所有球员以及过去几年的新秀中排名相当高。
有一点我真的没提那么多,就是他的 TS%很高。这应该值得一提,因为在三分时代(1979/80 至今),他是 3PA 所有新秀中第二位的,场均 6.7 分,他现在是 35.5%。
我没有成功形象化的是 Luka 的 BPM(Box Plus-Minus)。他目前的得分是 3.7,这让他在三分时代的新秀中排名第 11。老实说,这些先进的统计数据有点可疑,我没有去研究它们的细节,但总的来说,我会说 BPM 是预测谁将发展成为全明星级别的球员甚至更多的很好的指标。
生成所有这些图表的完整代码可以在我的 jupyter 笔记本中找到。我的 github 库上有更多关于篮球分析的东西。
数据来自 stats.nba.com和篮球参考。
软演员评论家深度评论
原文:https://towardsdatascience.com/in-depth-review-of-soft-actor-critic-91448aba63d4?source=collection_archive---------5-----------------------
了解最先进的强化学习算法
介绍
在本帖中,我们回顾了 Soft Actor-Critic (Haarnoja 等人,2018 & 2019),这是一种非常成功的强化学习算法,在连续控制任务(如机器人移动和操纵)中实现了最先进的性能。软演员评论家使用最大熵学习的概念,这带来了一些简洁的概念和实际的优势,我们将在本文中讨论。
以下是这篇文章的结构:
首先,我们将简要回顾一般策略迭代(我将假设读者熟悉马尔可夫决策过程),这是理解任何强化学习算法的基本概念。然后,我们将讨论软演员-评论家背后的直觉,以及它带来的概念上的好处。接下来,我们将讨论软政策迭代,软行动者-批评家(SAC)*似的理论框架,然后继续讨论 SAC。我还将在整篇文章中提供解释算法的代码片段。
SAC 是如何实现顶级性能的?
本质上,SAC 寻求的是在政策中最大化“熵”,以及从环境中获得的预期回报。政策中的熵可以解释为政策中的随机性。
Left: high(orange) and high (blue) entropy in categorical probability distributions | Right: high (orange) and low (blue) entropy in Gaussian distributions. Inspired by(https://medium.com/@awjuliani/maximum-entropy-policies-in-reinforcement-learning-everyday-life-f5a1cc18d32d)
从上图中,我们看到低熵的概率分布倾向于“贪婪地”采样某些值,因为概率质量分布相对不均匀。也就是说,奖励高熵的政策带来了几个概念上的优势:首先,它明确地鼓励探索状态空间,改善了收集的转换数据;第二,它允许策略捕获多种模式的好策略,防止过早收敛到坏的局部最优。
这种动机和提法在软演员-评论家论文中得到了实证验证;在许多 MuJoCo 控制任务中,软演员-评论家优于其他最先进的算法:
Performance of SAC (2018) and SAC (2019) against other algorithms on MuJoCo tasks. Taken from Haarnoja et al. (2019) paper
背景:一般策略迭代
在经典的 MDP 理论中,寻找最大化每个州的预期累积折扣奖励的最优政策的标准方法是政策迭代。策略迭代是在策略评估和策略改进之间交替的两步迭代方案。
在策略评估步骤中,我们希望找到当前策略的准确值函数。为此,我们反复应用如下定义的贝尔曼算子:
Bellman operator
策略改进步骤通过重复应用贝尔曼最优算子来执行:
Bellman optimality operator
其在给定初始值函数V
的情况下,保证收敛到真实(最佳)值函数V*
。特别地,Bellman 算子和最优性算子的收敛性质是由于它们都是压缩映射。再者,理论上,最优策略pi*
可以从最优值函数中构造出来;给定一个初始策略pi
,我们最小化当前策略和派生的更新策略之间的一些度量。
因此,通过交替策略评估和策略改进,我们可以在表格情况下(即,有限状态-动作空间和无函数*似)找到马尔可夫决策过程的精确解。
软策略迭代
在论文中,Haarnoja 引入了软策略迭代,它是一般策略迭代的一种扩展,将策略的熵作为一个附加的奖励项。特别是,代理人寻求最大化环境的预期回报和政策的熵。
为此,原始的贝尔曼算子增加了一个熵正则项:
Soft Bellman operator
如同在非正则化的情况下,熵正则化的 Bellman 算子对任何初始 Q 函数的重复应用保证收敛到最优的“软”Q 函数。
对于策略改进步骤,我们将策略分布更新为当前 Q 函数的 softmax 分布(要了解为什么会这样,请查看哈尔诺贾等人的论文,(2017) )。特别是,我们希望最小化两个分布之间的距离(“散度”)。这是通过最小化两种分布之间的 Kullback-Leibler (KL)散度来实现的:
如 Haarnoja 等人(2018)所证明的,这种更新方案保证了在表格情况下(即当状态和动作空间是有限的并且没有使用函数*似时)策略的单调改进。后来,艾斯特等人(2019)将这些性质推广到正则化子的任何公式。
软演员-评论家(警告:密集!)
对于具有高维和/或连续状态-动作空间的复杂学习域,找到 MDP 的精确解几乎是不可能的。因此,我们必须利用函数逼*(即神经网络)来找到软策略迭代的实际逼*。
为此,Haarnoja 等人将软 Q 函数建模为表达性神经网络,将策略建模为动作空间上的高斯分布,将当前状态作为输入,将*均值和协方差作为神经网络输出。下面是这些代码在实现过程中的样子:
Models
此外,软行动者-批评家是一种非策略学习算法,这意味着我们可以用从不同于当前策略的策略中收集的经验数据来更新 Q 网络和策略参数;对于每个演员的推出,我们将所有的过渡数据保存在重放缓冲区中(在下面的等式中表示为 D )。
通过使用预测动作值和目标动作值q_t
之间的均方损失的梯度,可以在每个更新步骤优化 Q 函数参数:
这里,alpha
项代表“熵温度”,即我们对政策的“随机性”与环境回报的权重。
在代码中,我们可以这样实现:
Soft Q-network update in code
现在进入策略改进步骤:在实践中,软行动者-批评家使用软策略迭代的一些修改。利用 Q 参数可微的事实,Haarnoja 等人对策略输出使用“重新参数化技巧”来获得低方差估计量;特别地,我们将动作表示为应用于 z 值的双曲正切(tanh ),该 z 值是从策略神经网络输出的*均值和协方差中采样的。
neural network transformation on Gaussian policy to obtain action
此外,为了解决我们的无界高斯分布的动作界限,我们必须将log(pi)
计算修改为:
log(pi) computation
这里,log(mu)
表示根据来自策略神经网络的均值和协方差计算的累积分布函数(CDF)。也许这在代码中更清楚:
log(pi) computation
然后,可以通过最小化来自软策略迭代的简化形式的 KL 发散来直接优化策略参数;我们取目标函数的随机梯度:
Policy objective for which we will compute the gradients
这种简化形式来自于忽略 Q 的 softmax 分布的分母,因为它对目标函数的梯度没有贡献。
在代码中,我们可以这样实现:
Policy update in code
可选:自动调节我们的熵温度alpha
在 SAC (2018)的第一个版本中使用了固定的熵温度alpha
。尽管原始 SAC 的性能令人印象深刻,但alpha
却是一个非常敏感的超参数。为了补救这一点,SAC (2019)的第二个版本将alpha
转换为可更新的参数。特别地,我们通过取下面的目标函数的梯度来更新:
Objective function for dynamically adjustable entropy temperature
其中 H_bar 表示所需的最小熵,通常设置为零向量。建议将 SAC (2019)与此可调alpha
一起使用,因为它提高了算法的性能和稳定性。
在代码中:
alpha initialization and update
这就结束了软演员-评论家算法的审查!
全面实施
为了使我的帖子尽可能简洁,我只包含了相关的、特定的实现片段;要查看完整的实现,请查看我的 GitHub 库:
[## cy oon 1729/策略-梯度-方法
策略梯度系列中算法的实现。目前包括:A2C,A3C,DDPG,TD3,SAC …
github.com](https://github.com/cyoon1729/Policy-Gradient-Methods)
参考资料:
- 软行动者-批评家:带有随机行动者的非策略最大熵深度强化学习。哈尔诺贾等人(2018)
- 软演员-评论家算法和应用。哈尔诺贾等人(2019 年)
- 正则化马尔可夫决策过程理论。艾斯特等人(2019)
PyTorch 的就地操作
原文:https://towardsdatascience.com/in-place-operations-in-pytorch-f91d493e970e?source=collection_archive---------7-----------------------
Photo by Fancycrave.com from Pexels
它们是什么,为什么要避开它们
今天先进的深度神经网络有数百万个可训练参数(例如,参见本文中的比较),试图在 Kaggle 或 Google Colab 等免费 GPU 上训练它们往往会导致 GPU 上的内存耗尽。有几种简单的方法可以减少模型占用的 GPU 内存,例如:
- 考虑改变模型的架构或使用具有较少可训练参数的模型类型(例如,选择 DenseNet-121 而不是 DenseNet-169 )。这种方法会影响模型的性能指标。
- 减少批处理大小或手动设置数据加载器工作进程的数量。在这种情况下,模型需要更长的训练时间。
在神经网络中使用就地操作可能有助于避免上述方法的缺点,同时节省一些 GPU 内存。但是,由于几个原因,不建议使用就地操作。
在这篇文章中,我想:
- 描述什么是就地操作,并演示它们如何帮助节省 GPU 内存。
- 告诉我们为什么应该避免就地操作或非常谨慎地使用它们。
就地操作
“就地操作是直接改变给定的线性代数、向量、矩阵(张量)的内容,而不制作副本的操作。”—定义摘自本 Python 教程。
根据定义,就地操作不会复制输入。这就是为什么在处理高维数据时,它们可以帮助减少内存使用。
我想演示就地操作如何帮助消耗更少的 GPU 内存。为此,我将使用这个简单的函数来测量 PyTorch 中的非适当位置 ReLU 和适当位置 ReLU 的分配内存:
Function to measure the allocated memory
调用函数来测量为不合适的 ReLU 分配的内存:
Measure the allocated memory for the out-of-place ReLU
我收到如下输出:
Allocated memory: 382.0
Allocated max memory: 382.0
然后调用就地 ReLU,如下所示:
Measure the allocated memory for the in-place ReLU
我收到的输出如下:
Allocated memory: 0.0
Allocated max memory: 0.0
看起来使用就地操作可以帮助我们节省一些 GPU 内存。但是,在使用就地操作时要极其谨慎,要检查两遍。在下一部分,我将告诉你为什么。
就地操作的缺点
就地操作的主要缺点是,它们可能会覆盖计算梯度所需的值,这意味着会破坏模型的训练过程。这就是 PyTorch 官方亲笔签名文件所说的:
在亲笔签名中支持就地操作是一件困难的事情,我们不鼓励在大多数情况下使用它们。Autograd 的积极的缓冲区释放和重用使其非常有效,并且很少有就地操作实际上降低内存使用量的情况。除非你的内存压力很大,否则你可能永远都不需要使用它们。
有两个主要原因限制了就地作业的适用性:
1.就地操作可能会覆盖计算梯度所需的值。
2.每个就地操作实际上都需要实现重写计算图。不在位置的版本只是分配新的对象并保持对旧图的引用,而在位置操作中,需要改变表示该操作的函数的所有输入的创建者。
小心就地操作的另一个原因是它们的实现非常棘手。这就是为什么我会推荐使用 PyTorch 标准的就地操作(就像上面的就地 ReLU ),而不是手动实现。
让我们看一个路斯(或 Swish-1)激活函数的例子。这是路斯的不合时宜的实现:
Out-of-place SiLU implementation
让我们尝试使用 torch.[sigmoid](https://en.wikipedia.org/wiki/Sigmoid_function)_
就地函数实现就地路斯:
Incorrect implementation of in-place SiLU
上面的代码错误地实现了就地路斯。我们可以通过比较两个函数返回的值来确定这一点。实际上,函数silu_inplace_1
返回sigmoid(input) * sigmoid(input)
!使用torch.sigmoid_
就地实施路斯的工作示例如下:
这个小例子演示了为什么我们在使用就地操作时应该小心谨慎并检查两次。
结论
在本文中:
- 我描述了就地操作及其目的。演示了就地操作如何帮助减少 GPU 内存消耗。
- 我描述了就地作业的重大缺点。人们应该非常小心地使用它们,并检查两次结果。
赞美职业改变者
原文:https://towardsdatascience.com/in-praise-of-the-career-changer-d734a39de1d9?source=collection_archive---------35-----------------------
Photo by Ian Schneider on Unsplash
这通常很难,也不被人欣赏,但这里要确保你的努力和奋斗不会被忽视
转行者经常被低估。我认为这是因为我们的社会倾向于反对不满或无聊。如果有人正在努力保持对工作的专注,社会的回应是,“忍着点,做个专业人士。”内疚之旅的回应也很受欢迎,“这么多人甚至没有稳定的薪水,所以不要抱怨了。”
改变职业需要勇气和一定程度的自省——你已经看到了“你”的现状,并决定在职业上需要改变。这不是一个容易的决定。放弃一份体面的薪水,即使你不再喜欢这份工作,也是很难的。当你意识到,不管是好是坏,你辞职后,你的工作是你身份的主要部分,这就更难了。没有它,你会感到更加脆弱和暴露。
但请大胆尝试。其他人可能会说你愚蠢、误入歧途,甚至自私。但是我知道你实际上是勇敢的,好奇的,真诚的。
认识到需要做出改变是很难的;更难鼓起行动的主动性。
所以这篇文章是写给你的,勇敢的职业改变者。你选择的路很长,终点也不确定。但是几年后当你回头看的时候,你会意识到第一步,你在开始你的转变之旅时已经迈出的那一步,实际上是最难的一步。因为不是每个人都有勇气接受。
Photo by 2Photo Pots on Unsplash
情感的过山车
转行者在到达最终目的地之前会经历各种各样的情绪。我最*刚从数据科学训练营毕业,在过去的几个月里,我和我的朋友经历了以下一系列情绪变化:
- 等待录取结果时的紧张。“伙计,我答对概率问题了吗?我希望他们不会因此责备我。”
- 兴奋一旦你被录取,“这是我通往新事业的门票!”
- 不安全感当你向前一家公司递交辞职通知时,“实际上,这份薪水还不错……我能确定在我完成训练营后,我能在新的领域找到另一份类似的工作吗?”
- 害羞和尴尬在你训练营的第一天——“我已经工作了很长时间,回到教育环境中感觉很奇怪。”
- 热情和好奇当你开始和你的同伴一起学习新东西时,“我学到了很多,我很快就会成为一名数据科学家。”
- 随着你学的越多,你越会意识到你实际上知道的是多么少,“这么多要学的,这么少的时间,我能做到吗?”
- 随着毕业日的临*,你还没有得到你的第一次面试机会(与此同时你的存款也在减少),“我想知道我要多久才能找到一份工作……”
- 恼怒又一个过分热心的招聘人员联系你,说“你有一个在职业生涯中迈出下一步的绝佳机会”,然后鬼鬼祟祟地跟着你——生命中只有三件事是确定无疑的——死亡、纳税和被招聘人员鬼鬼祟祟。
- 当你经历面试、带回家的作业和咖啡会议的严峻考验时,“如果我不用去参加另一场面试,我会很开心。”
- 嫉妒当你的朋友得到了你梦寐以求的工作,而你正坐在连续第五次被拒的边缘时,“伙计,我真不敢相信他是怎么突然袭击我的!”
- 当你最终得到第一份工作时,兴高采烈地说:“终于有人要我了!”
- 当你在新工作的第一天出现时,“我想知道他们多久才会意识到我是个菜鸟。”
在短短 4 到 6 个月的时间里,经历了很多起起落落——几个月没有薪水,一次又一次的拒绝,当你的朋友找到工作而你在找工作时,心情复杂。一直以来,你都在努力学习数据科学,并向世界证明你知道它。这可能是一场艰苦的斗争,但这也是让你最终获得胜利的原因。
Photo by Jason Hogan on Unsplash
一些我个人认为鼓舞人心的成功故事
虽然斗争是真实的,但也不是毫无意义的。我想分享几个我个人觉得鼓舞人心的成功故事(来自我的朋友)。他们都是正在或已经成功进入数据科学领域的职业改变者。
Mohammad Bakir——莫是我 METIS (数据科学训练营)队列中的一员。莫好奇、聪明、热情。但最重要的是,他是一个骗子和磨工。训练营结束几周后,当他的生活费开始减少时,他开始开车去优步。但他不仅利用优步来支付账单,还把它作为一个社交机会。莫是我所知道的唯一一个通过开得到面试和工作机会的人(他拒绝了,因为不是很合适)。他没有被吓倒,继续努力,我很高兴地告诉大家,他上周收到了苹果公司的邀请。恭喜莫!
雷迈·瓦格斯——一个西雅图梅蒂斯大学的毕业生,我通过博客认识了她(她也写博客!)。训练营毕业两年后,雷迈发现自己正处于十字路口:工作中的学习速度放缓,而且缺乏从事数据密集型项目的机会。感觉就像是现在或永远都不要做出改变,雷迈做了一些让我惊讶的事情:她辞去了工作,这样她就可以全职寻找她梦想的工作。她做了搜索。她的会议和社交活动安排得如此之满,让我震惊和印象深刻(社交让我昏昏欲睡)。对于我们中的许多人来说,当我们失去了学校或工作的日常结构时,就会变得懈怠和拖延。不是她,雷迈把找工作当成了她的工作,最终她的自律得到了回报。她现在是一名快乐的数据专家。恭喜雷迈!
黑乌鸦(詹姆斯·吴)——我个人并不认识詹姆斯,但我对他丰富的博客内容印象深刻。詹姆斯是 Metis 首届新加坡毕业生(恭喜你们!),他和他的同事们目前正在努力进入就业市场(如果你是新加坡的一名雇主,你想要一名充满激情和渴望数据的人,你应该去看看詹姆斯、肯、里贾纳和莉安娜)。你可能已经猜到了,我非常赞成把写博客作为一种手段,来弥补学习新事物和真正精通新事物之间的差距(学习新事物的最好方法是教它)。因此,我很高兴看到詹姆斯,我相信他正忙于招聘和面试,仍然找到时间推出教程和撰写他的激情项目(我希望你保持下去!).
在我的朋友身上挣扎,但记得要开心
对数据科学工作的不懈追求有时会令人窒息。这就是为什么你需要经常提醒自己为什么要做这件事。
你想要一份有趣、刺激、有挑战性的工作(从好的方面来说)。因此,在社交和面试之间,花些时间学习一种新算法,或者和一些朋友参加一场 Kaggle 比赛——任何能提醒你数据科学(和学习新事物)有多有趣的事情。
因为如果不好玩,那你还不如呆在原来的工作岗位上。
更多数据科学相关帖子由我:
数据科学家是做什么的?
数据科学家挣多少钱?
拿到了数据科学的工作?
技能提升的更好方法
让数据科学面试变得更好
用 Python 进行业务模拟
在 R Shiny 中,什么时候一个错误才是真正的错误?
原文:https://towardsdatascience.com/in-r-shiny-when-is-an-error-really-an-error-702205ebb5d5?source=collection_archive---------18-----------------------
如何测试你的服务器端输出并阻止不必要的红色死亡错误信息出现在你的用户界面上
对于 R 用户和整个世界来说,R Shiny 是一个真正的超级礼物。本质上,它允许你以一种用户友好的方式向他人公开你的代码,这意味着非 R-coder 可以利用你开发的功能。
但是当 R 的红色死亡错误消息从服务器端流过并出现在不必要的用户界面时,它看起来会有点不专业和“不整洁”。例如,这对最终用户来说非常糟糕:
有两种方法可以轻松改善最终用户体验,并避免用户向您反映并非真正错误的错误,而只是用户输入选择的结果。
假设您创建了一个应用程序,该应用程序根据某些用户输入过滤一个数据集,然后对过滤后的数据进行一些统计。
假设在服务器端创建了一个用于计算统计数据的反应式过滤数据帧,我们称之为filtered_df()
。一种常见的可能性是用户选择了太多的过滤器,以至于在filtered_df()
中没有留下任何数据,事实上它是一个没有任何行的数据帧。
选项 1 —编写特定的错误信息
如何处理这个问题的一个选择是使用stop()
函数为这个事件写一个特定的错误消息。例如,您可以这样做:
checked_filtered_df <- shiny::reactive({
if (nrow(filtered_df()) == 0) {
stop("No data available for chosen filters!")
} else {
filtered_df()
}})
在用户过滤掉所有数据的情况下,这将返回一个红色的错误消息,就像上面的一样,除了它将包含特定的语言“错误:没有可用于所选过滤器的数据!”。这稍微好了一点,但在我看来,对最终用户来说还是很糟糕。另外,这真的是一个错误吗?我不这么认为——你的代码实际上没有任何问题。我不是这样使用stop()
的粉丝。
选项 2——使用 Shiny 强大的验证功能
闪亮的validate()
功能非常适合这种情况。它可以对您的服务器输出执行测试,您可以告诉它在测试失败时显示什么。它用不那么可怕的灰色文本显示,重要的是,它不称之为错误。
在validate()
中,您可以使用need()
功能设置测试标准,并编写一条消息,在测试失败时显示。重写上面的代码以使用validate()
而不是stop()
看起来像这样:
checked_filtered_df <- shiny::reactive({ shiny::validate(
shiny::need(nrow(filtered_df()) != 0,
"No data available for chosen filters!")
) filtered_df()})
现在,当用户向下筛选到一个空数据集时,UI 中将出现以下内容:
这就不那么令人担忧了,而且对于最终用户来说,他们已经将数据集过滤得一无所有,这一点也更清楚了。
如果你以前没有在 Shiny 中做过类似的事情,那么这是值得进一步研究的。随着每个新版本的发布,Shiny 包含了越来越多的方法来*滑用户界面和控制预期的问题。这里有更多关于validate()
的技术细节。
最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在 LinkedIn 或Twitter上找我。
在未来,你可能会被一个算法解雇
原文:https://towardsdatascience.com/in-the-future-you-may-be-fired-by-an-algorithm-35aefd00481f?source=collection_archive---------18-----------------------
Photo by Adam Fossier on Unsplash
算法决定我们在 Tinder 上遇到的人,识别你的脸来打开无钥匙的门,或者在你的生产力下降时解雇你。机器被用来做出关于健康、就业、教育、重要的金融和刑事判决的决定。算法被用来决定,谁获得工作面试,谁获得捐赠器官,或者自动驾驶汽车在危险情况下如何反应。
算法反映并强化了人类的偏见
人们普遍错误地认为算法是客观的,因为它们依赖于数据,而数据不会说谎。人类认为数学模型是可信的,因为它们代表了事实。我们经常忘记算法是由人类创造的,人类选择了数据并训练了算法。源自人类的偏见不可避免地蔓延到人工智能模型中,因此,算法强化了人类的偏见。例如,谷歌图片搜索“首席执行官”产生了 11%的女性,尽管 27%的美国首席执行官是女性。
了解基于人类的偏见
虽然人工智能(AI)偏见应该始终得到重视,但指控本身不应该是故事的结尾。只要人们在开发人工智能技术,对人工智能偏见的调查就会存在。这意味着迭代开发、测试和学习,人工智能的进步可能会超出我们之前认为的可能——甚至可能会去人类以前没有去过的地方。然而,有偏见的人工智能是不能掉以轻心的,因为它可能对个人产生严重的改变生活的后果。了解偏差何时以及以何种形式影响数据和算法变得至关重要。最明显和最常见的问题之一是样本偏差,即数据收集的方式使得目标人群中的一些成员比其他人更不可能被包括在内。考虑一个法官用来做量刑决定的模型。显然,将种族因素考虑在内是不合适的,因为历史原因,非裔美国人受到的判决不成比例,这导致了统计数据中的种族偏见。但是健康保险呢?在这种情况下,判断男性不同于女性是完全正常的,但对于人工智能算法来说,这种禁止可能不是那么明显。我们,人类,对道德有一个复杂的观点,有时考虑性别等属性是好的,有时是违反法律的。
人工智能伦理的问题
数据集并不完美,它们天生就是肮脏的,现在,我们开始清理人类偏见。无论如何,关键的问题不是偏见的存在,深层的问题是缺乏对道德的共同理解,因为它实际上没有定义没有偏见应该是什么样子。这不仅仅是在计算机科学领域,而是对人类的挑战。在自动驾驶汽车背景下,关于人工智能伦理的最大在线实验之一是“电车困境”,它收集了 233 个国家的 4000 万个道德决定。不出所料,研究人员发现各国的偏好差异很大:人类对道德有不同的定义。电车问题只是理解数据科学中道德的深度和复杂性的一种简单方法,不用说,它超越了自动驾驶汽车,这导致了一个问题,即机器如何通过承认个体和跨文化的道德差异来做出“公*”的决定?我们能指望一个被人类训练出来的算法比社会更好吗?
寓意困境无人驾驶汽车必须做出决定的地方
令人毛骨悚然的事情人工智能开始自己做
承认,我们距离科幻小说的场景还有几十年,在科幻小说中,人工智能变得有自我意识并接管世界。截至今天,算法不再是静态的,它们会随着时间的推移自动修改自己的行为,这种修改会引入所谓的人工智能诱导的偏差。一种远远超越人类最初定义的进化。在某些时候,我们可能需要(或不需要)通过信任机器来接受结果?!
前进之路:为公*而设计
展望未来,我们对人工智能的依赖将会加深,不可避免地导致许多伦理问题的出现,因为人类将决策交给机器,将健康、正义和商业交给具有深远影响的算法——影响每个人。对于人工智能的未来,我们需要回答棘手的伦理问题,这需要多学科的方法,领导层的意识,而不仅仅是由技术专家来处理。数据科学知识需要发展成为未来劳动力的标准技能。与火灾类似,机器学习既强大又危险,重要的是我们要弄清楚如何促进利益和最小化伤害。由于它不仅限于与人有关的偏见,它还涉及到提供决策的透明度,澄清问责制以及维护人工智能的核心道德价值观,如*等,多样性和无歧视。在未来几年,植入道德意识和法规的能力将成为一个关键挑战,只有通过政府、学术界和企业的密切合作才能解决。不管挑战有多复杂,这是一个激动人心的时代,它将继续存在并深化人工智能革命,这有可能改善全球数十亿人的生活。
撰稿
Cyrano Chen —高级数据科学家
Joanne Chen—沟通负责人
Michael Renz —创新总监
在新的知识时代,联系总是胜过收集
原文:https://towardsdatascience.com/in-the-new-era-of-knowledge-connection-beats-collection-every-time-6f77fb6b77df?source=collection_archive---------35-----------------------
Photo by fabio on Unsplash
“看看数据——数字不会说谎。”这是一条经常给出的建议,但却很少被理解。因为给出建议的人真正的意思是“看看数据,想想这对我们面临的情况意味着什么。一旦你在更广阔的背景下考虑这个问题,你就会明白——并且直觉地知道——下一步该怎么做。”这是一个非常不同的挑战,但当你试图理解一个复杂的情况时,这是一个非常有价值的挑战。只有当你意识到连接数据比收集数据更重要时,这才有可能。
为什么收集已经不够了
数据收集现在是主流。存储成本低廉,资源丰富,而且当今制造的大多数产品都是在这样的预期下完成的,即组织希望通过批量导出或自动交付等产品提供之外的方式访问其数据。尽管这种访问方式很有帮助(并且很快成为人们的期望),但大多数数据仍然是在收集数据的单一视角下查看的。当然——图形、图表和仪表板是可能的,当然也是有帮助的,但是它们通常是使用已经实施的数据创建的,并且通常只是重复已经讲述过的相同故事。创新系数低,因为连接系数也低。
但是除了这些技术上的考虑之外,还有一个更基本的原因可以解释为什么断开连接的数据没有发挥应有的作用。人类是进化的动物,在我们最基本的层面上,我们本能地在做出反应之前考虑整个情况。早期人类部落不会寻求短期利益,如果这损害了他们长期生存的机会(尽管可以说现代世界降低了我们这种类型的思维能力),因为这样做会与我们考虑环境关系的独特意识相矛盾。从技术系统收集的数据也是如此——默认情况下缺少更广泛的上下文,而上下文是理解的关键。
什么联系是可能的
数据通过连接而丰富,这提供了复杂环境的更真实的表示。当我们查看通过相关框架连接起来的数据时,我们的大脑会理解结果、依赖性以及关系的质量如何影响我们所寻求的结果。
人们有时会争论说,这种类型的思维在不连续的数据中仍然是可能的,它只需要我们在头脑中把这些片段放在一起。这是说人类可以同时处理多项任务的同一论点,但多项研究已经证实我们不能——相反,我们可以快速切换单个任务。然而,这种转换需要付出精神代价,因为每次需要做出决定时,不愿意收集所有不相关的信息,从而导致糟糕的结果。
将数据连接到一个无缝的整体视角中,消除了切换的需要。它使我们能够了解事件的促成因素并采取适当的行动。随着时间的推移,这种增强的意识导致了新知识的发展,如果将这些新知识反馈到框架中,就会产生一个独特的反馈循环,由此洞察力会产生进一步的洞察力。随着知识的共享,意想不到的合作机会出现了。创新因素随着联系的增加而增加。
联系总是相关的——尤其是涉及人类的时候
理解如何在组织中连接数据有时会很困难。随着时间的推移,人们倾向于专注于某个特定领域,这种专注会导致人们认为一种类型的数据与另一种类型的数据相关性有限。但是如果仔细观察,通常会发现这些相同的区域与其他区域有着看不见的联系和关注。连接一个组织中所有领域的数据有助于产生一个更广泛的背景,表明我们对自然和我们在其中的位置的进化理解,其中没有一个实体真正孤立存在。
对于与人际网络打交道的组织来说,更是如此。我们是紧密相连的生物,我们的行为受周围人(甚至是他们周围的人)的影响比我们认为的要大得多。这些社会联系在类型和强度上经常不同,这两者都影响着影响力和变化的流动。正确考虑这些不同的关系是做出明智决策的基础,只有当数据正确连接时才有可能。
本文首次出现在 insightabletimes.org 的https://insightabletimes . org/in-the-new-era-of-knowledge-connection-beats-collection-every time
包容是人工智能性别偏见的唯一解决方案
原文:https://towardsdatascience.com/inclusion-is-the-only-solution-to-gender-bias-in-ai-d5a0d440ab83?source=collection_archive---------45-----------------------
人工智能中的性别话题正日益成为主流。我知道这一点是因为在完成关于这个主题的硕士论文后,我的许多朋友和家人会给我发他们在这个主题上看到的文章,所以我每周至少会收到一篇。
今天发给我的这篇文章来自 ICT Works ,在我看来,它代表了许多关于这个主题的主流文章的做法——强调了一些相对众所周知的关于女性在技术领域缺乏的观点,并提出我们只需要让更多女性进入 STEM 教育。任务完成。
不幸的是,这个问题/解决方案框架过于简单,尽管这是一个非常普遍的分析,它表明问题(人工智能中的偏见=没有足够的女性开发技术)可以通过增加女性在技术领域的人数来解决。不要误解我。我们当然需要鼓励和支持,但是教育者和学生要让两性都参与 STEM。但我坚信,除非教育、工作和社会系统具有包容性,否则这不可能通过强制性别多样化来实现。
扩展标准“人工智能中的性别问题可以通过让更多女性进入技术领域来解决”论点的五个复杂性:
1/ 为什么选择了女声,至少根据我的分析,远比 CS 发展中的男性主导问题复杂。既有“硬编码”(即我们对听到女性和男性声音的方式的生物倾向),也有更多的“软编码”(即设定我们对女性/男性声音及其对我们的意义的观点的社会学条件)。我的中帖对此有更深入的探讨。
2/为了进一步补充这一点,我们不能忘记的是 Siri、Alexa、Cortana 都是纯粹为了盈利的商业产品(苹果并不真正关心社会学影响)。他们知道第一点,因为他们已经测试过了:例如:在英国,Siri 实际上是默认的男性声音,但在德国,司机拒绝在他们的宝马里使用女性声音,因为它不够“权威”。在我们的后现代主义世界中,公司对社会的影响可能比反过来更大,这意味着我们在这个“恶性循环”中有一个次要的复杂因素,即我们继续犯下社会偏见和刻板印象。
让更多的女孩接受 STEM 教育和工作远比坐在教室的椅子上要复杂得多。有证据表明,计算机科学的整个教学都是重男轻女的(也就是说,计算机科学的整个语言及其教学方式更倾向于男性对女性的“认知方式”,这实际上可能是为什么我们在技术领域没有更多女性的根源。《人工认识》这本书是对这个话题非常优秀的考查。
4/榜样。尽管该领域目前存在性别失衡,但在主流的科技历史记录中,不可否认的是忽略了女性榜样,尽管她们对该领域做出了许多贡献。迄今为止,600 个诺贝尔科学奖中只有 20 个授予了女性——2019 年的获奖者都是男性。在媒体和现实世界中看到杰出的女性成为 STEM 领导者,将是打破当前技术仅仅是男性努力的刻板印象的关键因素。
5/最后,关注“管道”问题(例如,没有足够的女性候选人)是“指责系统”的好方法,然而,它模糊了一个更大的偏见问题(有意识和无意识的),即在招聘、薪酬和留住女性方面。对超过 98 项实证研究的回顾表明,劳动力中存在系统性问题,导致女性被不成比例地排除在晋升、权威角色和高薪职位之外。此外,从某些方面来看,微妙性别歧视的险峻“男性文化”在今天的科技公司以及 Siri、Alexa 和 Cortana 的开发者中非常猖獗。
对抗多样性的最佳方式不是强迫它,而是创造和培养更具包容性的教育、社会和工作环境,在这样的环境中,每个人的声音都是同等有效的。那是一件不可能的事情——直到我们都相信它是值得的。
通过…删除数据来提高模型性能?
原文:https://towardsdatascience.com/increase-model-performance-by-removing-data-a87d05183d7c?source=collection_archive---------14-----------------------
数据越少对机器学习越好吗?
The effect of removing low value data on predictor performance in a breast cancer dataset. Image adapted from Data Shapley: Equitable Valuation of Data for Machine Learning arXiv:1904.02868v2 [Ghorbani and Zhou].
并非所有数据都是*等的
在任何给定的数据集中,不是每个样本都对训练机器学习模型有同等的贡献。当你大声说出来的时候,这是显而易见的。一些数据可以教会一个模型很多东西。但有些会是不相干的,或者多余的,根本不会真的动针。有些甚至可能损害你的表现——比如贴错标签的数据——这将教会模型与它试图学习的相反的东西。下面是 Food-101 数据集 [1]中错误标注数据的一个例子,这是一个流行的公共数据集,包含 101 个食物类别的 101,000 张图片。
The images shown here are from the Food-101 dataset. Images in the dataset are supposed to be of the food item itself, but the first image is of a keyboard, the second is of a beer, and the third is of a food truck.
但机器学习的常见工作流程仍然是获取尽可能多的数据,对所有数据进行标记,并将所有内容输入到您的模型中。或多或少是盲目的行动。每个人都关心数据的质量,但是没有(简单的)方法以编程方式评估数据的相关性或冗余性,尤其是以模型驱动的方式。还是有?
如果有,为什么认为删除数据实际上会提高性能会令人惊讶呢?
因为确实如此。您只需移除最低值数据。要做到这一点,你需要一种评估数据价值的方法。
数据评估
有一些关于数据评估的有趣研究。其思想是查看数据集,并根据数据点相对于特定模型或预测任务的值对其进行排序。
数据沙普利
由 Ghorbani 和周撰写的《机器学习数据的公*评估》于今年早些时候出版。作者从博弈论【3】(这让劳埃德·沙普利获得了 2012 年诺贝尔经济学奖)中提取了沙普利值,并将其应用于机器学习中的数据。他们建议,公*的估价方法应满足以下条件:
- 当添加到训练数据的任何子集时,它应该给一个不改变您的 ML 系统的性能的数据点一个值零。
- 当添加到训练数据的任何子集的时,它应该通过对称给具有完全相等贡献的数据点赋予相同的值。
- 如果一个机器学习系统的价值可以分解为子系统的总和,那么数据的价值应该是那些子系统中的加法。
唯一能满足这个的物业?沙普利值。
若要计算给定数据点的 Shapley 值,您需要用包含该数据点的每个数据子集来训练模型,然后再用不包含该数据点的子集来训练模型。取性能差异,Shapley 值就是所有子集的加权*均值。
但是相对于训练数据源的数量,计算这个值需要指数级的大量计算。这就是为什么本文提出了以下估计,这些估计都是为了节省时间和计算:
- 蒙特卡罗估计;
我们可以只通过查看数据的一些子集来估计样本 i 的值。这些子集是随机抽样的,可以证明是其余数据的*似值。
2.截断:
如果 ML 模型的边缘值没有增加,则提前结束多次迭代的训练(对大型数据集有帮助)。有了以上,这就是 TMC-Shapley。
3.梯度沙普利:
将 ML 系统的价值视为通过一个时期的训练而不是通过模型的完整训练获得的性能。这是 G-沙普利。
4.沙普利集团:
组级评估是对一批数据一起进行评估,而不是对样本级别的数据进行评估。您可能希望按值对数据源进行排序,在这种情况下,您不需要关心样本级别的粒度。
这些有用吗?
以下是论文的结果,显示了移除训练数据对预测准确性的影响。
数据以四种方式评估,最高值的数据在左边被删除,最低值的数据在右边。
LOO 是 Leave-One-Out:一种更简单的估值方法,它训练整个数据集,然后训练除单个数据点之外的所有数据,并根据排除它的影响对该点进行估值。除了计算量太大之外,这种方法也不能真正处理不同数据点之间的关系。
随机将数据随机作为基线值。
正如您所看到的,删除高值和低值数据的效果远远大于随机数据。 以乳腺癌为例,删除了 40%以上的数据,预测准确率提高了 16%以上!
但是过度拟合怎么办?
如果我正在删除数据并变得更好,这是否意味着我正在删除我表现更差的数据,这难道不好吗?
不,这个想法是你只从你的训练集中删除数据。性能是在一个保留测试集上测量的,这个测试集(希望)代表了您的数据分布。这是 ML 的标准做法。
估值不会惩罚离群者,它会奖励他们。 如果你对你的测试数据集的质量和覆盖范围有信心,这种类型的评估会对出现在训练集和测试集中的任何稀有样本排名更高。通过删除冗余、不相关或错误标记的数据,不会有过度拟合的风险。
我该怎么试?
将数据工作流转变为更加模型驱动意味着通过按值对数据源、注释器和增强函数进行排序,来获取、标记和生成您所需要的数据。
我们围绕着数据评估的这一确切想法开始了Gradio——因为我们认为它将触及数据管道的每一个部分。我们正在开发一系列适用于不同环境的估值方法。如果您正在部署任何容量的机器学习,我们很乐意与您交谈。
[1] L. Bossard,M. Guillaumin 和 L. Van Gool,Food-101-用随机森林挖掘歧视性成分(2014),欧洲计算机视觉会议
[2] A. Ghorbani 和 J. Zhou,Data Shapley:机器学习数据的公*估值(2019)
[3] L. S. Shapley,N 人游戏的价值(1953),对理论游戏的贡献 2,307–317
增加 Kaggle 收入:分析用户数据以推荐最佳新产品
原文:https://towardsdatascience.com/increasing-kaggle-revenue-analyzing-user-data-to-recommend-the-best-new-product-f93fddbb4e0f?source=collection_archive---------13-----------------------
在这个项目中,我们将为 Kaggle(一个面向数据科学专业人士的在线社区)提供增加收入的建议。我们将分析 Kaggle 客户调查,试图了解是否有任何公司潜在收入增长的指标。为了提出我们的建议,我们将努力了解:
- “免费增值”内核产品有市场潜力吗?
- 咨询市场有市场潜力吗?
- 基于目前的用户数据,哪个更有可能盈利?
观察总结
- 超过 60%的 Kaggle 用户年收入低于 5 万美元,并且不太可能将可自由支配的收入用于更高级别的订阅。此外,超过 58%的用户在员工少于 1,000 人的公司工作。愿意投资昂贵的企业解决方案的公司似乎只是 Kaggle 当前用户群中的一小部分。
- 尽管订阅服务可以通过创造增加用户群的“战略价值”来推动长期收入,但 Kaggle 似乎不太可能通过提供免费增值产品来获得大量新用户。
- Kaggle 目前产品的用户受教育程度高,大多在美国以外,并且倾向于较低的薪酬水*。所有这些因素都可能使 Kaggle 用户成为数据科学项目高质量远程合同工作的非常有前途的候选人。
建议概要
Kaggle 的用户调查结果显示, Kaggle 更有可能从货币化的顾问市场中获得可观的未来收入,而不是免费的核心产品。开发一款免费的核心产品很难收回大笔投资,而且 Kaggle 目前的用户群不太可能从 GitHub 和其他现有产品中夺走大量市场份额。相比之下,鉴于他们有能力和地理上多样化的用户群,一个强大的数据科学承包商市场应该会带来更显著的收入增长。
有关本报告方法的更多详细信息和全面描述,请参见下文。
方法论
这个项目的数据来自公开发布的 Kaggle 竞赛。该调查于 2019 年 10 月 8 日至 28 日展开,反馈主要来自 Kaggle 相关渠道(电子邮件列表、社交媒体和论坛)。该调查收到了 19,717 个可用的回复,并过滤掉了所有自动标记为“垃圾邮件”的回复
所有的清理和可视化都将通过 pandas 和 NumPy 库使用 Python 编码来完成。
感兴趣区域
Kaggle 未来潜在收入来源的概要可以在 Kaggle 的创始人 Anthony Goldbloom 在 Quora.com 上发表的一篇文章中找到。在这篇文章中,Anthony Goldbloom 展示了 Kaggle 目前的几个收入来源:
- 特色比赛
- 招聘竞赛
- 研究竞赛
此外,Goldbloom 列出了 Kaggle 计划增加的几项服务,以增加收入:
- 让 Kaggle kernels 成为一项免费增值服务,公司将作为一个团队协作空间进行订阅。
- “咨询帮助的数据科学市场”
截至撰写本报告时(2019 年 11 月 25 日),这两个选项都没有在 Kaggle 网站上明显列出,因此都是潜在的收入来源。
假设
“团队协作”领域目前由 GitHub 主导,GitHub 也使用免费增值服务通过企业订阅赚钱。GitHub 最*被微软以 75 亿美元收购,收购价格很大程度上是由 GitHub 的合作网络中提供的机会推动的。根据《哈佛商业评论》的报道:
…微软支付 75 亿美元购买 GitHub 并不是为了它的赚钱能力(它的财务价值)。它为每天使用 GitHub 代码库产品的大量开发人员的访问付费(该公司的战略价值)——因此他们可以被引导到微软开发人员环境中,在那里真正赚钱。
考虑到这一点,Kaggle 的潜在收入不仅仅是基于潜在的订阅费用,而是基于 Kaggle 在该领域可以从 GitHub 获得的市场份额(如果有的话)。因此,一个合理的假设是考虑到 Kaggle 当前的客户群,Kernels 免费增值服务将比数据科学咨询市场提供更大的未来收入潜力。
所需数据
为了检验这一假设,我们需要探索:
- 当前客户的人口统计和专业知识信息
- 关于客户数据科学团队规模的信息(最有可能利用基于内核的系统)
- 关于大型预算公司(最有可能购买企业系统)雇用的用户百分比的信息
- 关于具有丰富教育和数据科学经验的用户百分比的信息(最有可能在咨询市场产生高额收入)
此外,我们将探索数据集中提供的其他人口统计数据,看看是否有任何其他潜在的假设出现。
假设
重要的是要注意这个分析中的几个关键假设。
- 调查数据代表了 Kaggle 的整体客户群。根据现有数据,不可能知道这项调查是否能代表 Kaggle 客户的总体情况。选择偏差可能以某种形式存在。然而,鉴于调查中的大量回复,它可能是本分析的可靠来源。
- 一个新的免费增值内核产品的结构将与该领域的其他产品非常相似,有一个付费订阅层和一个更大的团队企业级层。这是这个领域的领导者 GitHub 和大多数其他免费增值服务所使用的策略。
- 为了让 Kaggle 从免费的核心产品中获得可观的收入,他们需要一个有财力订阅的现有客户群。这需要一个庞大的群体,要么是有可自由支配收入的用户,要么是有预算和企业订阅需求的大公司员工。
数据清理
首先,我们导入并清理 Kaggle 提供的数据集。提供了四个数据集,我们将把它们作为单独的文件读入。“survey_schema”文件显示,并非所有问题都发给了所有参与者,这有助于理解较大数据集中的空值。
只有包含所有选择题答案的“mc_responses.csv”文件与此分析相关。
从这个数据集中,我们执行一些清理操作来为分析准备数据:
- 重新分配标题并删除第一行
- 删除重复项和“文本”响应列
- 将多项选择答案聚合到单个列中
- 重命名列标题
- 用“np”替换空值。南
经过初步探索、清理和整合,数据似乎完全由“str”对象组成,而不是数值。几个类别已经被分解成大的类别箱,这将有助于快速分析。在给定调查模式的情况下,预计后面类别中的空值数量。然而,这些类别中的大部分可能与本分析无关。
对于一些感兴趣的类别,仍然有大量的空值:' comp_size '
、' ds_teamsize '
、' use_ml '
、 ' compensation '和
' dollars_mlorcloud ` '。然而,即使在减去空值之后,这些类别中的每一个都有超过 12,000 个数据点,这对于有意义的分析来说应该绰绰有余。
探索性数据分析
我们首先分析与我们的分析最相关的分类变量。首先,我们使用 matplotlib 库为每个变量创建一个频率表和条形图:
# Creating Age Frequency Table
age_freq = mc[‘age’].value_counts(normalize=True)
age_freq = age_freq.sort_index(axis=0)
age_freq = age_freq.reset_index()
age_freq = pd.DataFrame(age_freq)# Setting style for bar graphs
import matplotlib.pyplot as plt
%matplotlib inline# set font
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = 'Helvetica'# set the style of the axes and the text color
plt.rcParams['axes.edgecolor']='#333F4B'
plt.rcParams['axes.linewidth']=0.8
plt.rcParams['xtick.color']='#333F4B'
plt.rcParams['ytick.color']='#333F4B'
plt.rcParams['text.color']='#333F4B'# numeric placeholder for the y axis
my_range=list(range(1,len(age_freq.index)+1))fig, ax = plt.subplots(figsize=(8,5))# create for each bin a vertical line that starts at y = 0 with the length
# represented by the specific percentage.
plt.vlines(x=my_range, ymin=0, ymax=age_freq['age'], color='#007ACC', alpha=0.5, linewidth=30)# create for each bin a dot at the level of the expense percentage value
# plt.plot(my_range, age_freq['age'], "o", markersize=10, color='#007ACC', alpha=0.6)# set labels
ax.set_xlabel('Age', fontsize=15, fontweight='black', color = '#333F4B')
ax.set_ylabel('% of Respondents', fontsize=15, fontweight='black', color = '#333F4B')# set axis
ax.tick_params(axis='both', which='major', labelsize=12)
plt.xticks(my_range, age_freq['index'])# add an horizonal label for the y axis
# fig.text(-0.15, 0.5, '% of Respondants', fontsize=15, fontweight='black', color = '#333F4B')# change the style of the axis spines
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.spines['left'].set_smart_bounds(True)
ax.spines['bottom'].set_smart_bounds(True)# set the spines position
ax.spines['bottom'].set_position(('axes', -0.04))
ax.spines['left'].set_position(('axes', 0.015))# set background color
ax.set_facecolor('white')# add margin to y-axis
ax.margins(0.1, 0)# add title
fig.suptitle('Age of Survey Respondents', fontsize=18, fontweight='black')plt.savefig('age_freq.png', dpi=300, bbox_inches='tight')
EDA 可视化
在为每个变量创建频率表和图表后,我们可以对 Kaggle 数据进行一些有趣的观察。
调查答复的分布似乎有些正常,在 22-34 岁之间的比例很高。
大部分调查样本要么是数据科学家,要么是学生。这可能解释了回答者年龄分布的年轻化。由于学生不太可能在任何以咨询为基础的市场中吸引高度的价值,这将是一个有趣的领域,可以在我们的分析中用作过滤器。
受访者最有可能生活在印度或美国,其他国家的人口占总人口的比例都不超过 5%。
调查样本非常男性主导,女性受访者不到 20%。
调查样本受教育程度较高,绝大多数人至少获得了学士学位。
15%的调查受访者回答说,他们从事的数据科学工作少于 3 人。所有其他受访者都是更大的数据科学团队的一部分。最受欢迎的回应是给出的最大选项,20 人或更多成员的团队。这与我们关于基于免费增值企业的内核服务的问题非常相关。
Kaggle 用户的年薪主要由年收入低于 5 万英镑的员工决定。这是我们的“免费增值”服务提案中的一个相关事实,因为许多人个人不太可能为付费服务提供可观的利润。
超过 60%的调查受访者在过去一年中没有在机器学习或云计算上投入任何资金的公司工作。因此,他们不太可能具备使用这些技术的专业知识。
与上图类似,超过 60%的受访者拥有 2 年以上使用机器学习的经验。因此,他们在这一领域的专业知识有限。
EDA 结果
在回顾了分类变量之后,有几个重要的见解脱颖而出:
- 超过 20%的受访者是学生,因此不太可能有助于推动免费增值核心产品或咨询市场的收入。应该删除他们的信息,以进一步评估 Kaggle 这些产品的目标市场。
- * 25%的受访者目前居住在印度,绝大多数人居住在美国以外,这使得用户更有可能参与远程咨询市场产品。
- 超过 65%的受访者目前在由 3 人或更多人组成的数据科学团队中工作,超过 20%的受访者在由 1-2 人组成的团队中工作。因此,Kaggle 的绝大多数客户已经在合作开发数据科学相关产品。
- 超过 60%的受访者年收入不到 5 万英镑。因此,他们不太可能为付费数据科学协作服务获得大量可自由支配的收入。
- 超过 60%的受访者就职的公司没有在机器学习或云计算方面投入任何资金,并且个人使用机器学习产品的时间不到 2 年。
进一步清洁
为了继续我们的分析,我们将只关注那些目前在数据科学/分析领域工作的受访者。这些受访者最有可能使用任何 Kaggle 产品,并为增加收入做出贡献。为此,我们将从数据集中删除“学生”值。
# Get names of indexes for which title is student.
indexNames = mc[mc[‘title’] == ‘Student’ ].index
# Delete these row indexes from dataFrame
mcclean = mc.drop(indexNames)
print(len(mc)-len(mcclean))
4014
我们现在已经删除了 4000 多个与我们的分析无关的回复。有了这个新的数据集,我们可以专注于探索我们的假设,即内核免费增值服务将比咨询市场提供更多的潜在收入。
分析:免费增值服务的潜力
首先,我们将探讨调整后的薪酬百分比,从样本中剔除学生(更有可能失业或未充分就业)。
在这个较小的样本中,薪酬数字仍然在很大程度上向低端倾斜。超过 60%的非学生 Kaggle 用户年收入不到 5 万英镑。这意味着他们可能不太可能为付费订阅服务获得可自由支配的收入。
接下来,我们将使用这个缩减的样本量来查看有多少受访者是大型数据科学团队的一部分,这需要在数据科学项目上进行协作。
从调查数据中剔除学生后,超过 53%的受访者属于 3 人或以上的数据科学团队,超过 23%的受访者属于 20 人以上的团队。此外,22%的人属于 1-2 人团队,这意味着在这一领域有更多的合作机会。
考虑到这个数字,似乎对合作免费增值服务感兴趣的人的总数是值得注意的。
然而,从上面的探索性分析来看,似乎大多数受访者来自在机器学习和云计算等产品上花费很少甚至没有钱的公司。为了进一步探索,我们将分析调查对象所代表的公司的规模。
根据该信息,超过 58%的调查受访者在员工少于 1,000 人的公司工作。这些公司很可能无力为员工支付企业级免费增值订阅。如上所述,由于相对较低的年薪,样本中的大多数个人也不太可能购买订阅。
这意味着 Kaggle 将依赖“中端”价格的订阅,其用户的公司规模足以支持数据科学团队,但不足以证明企业解决方案的合理性。
分析结果
鉴于 Kaggle 用户相对较低的补偿率,个人客户不太可能大量注册付费模式。由于 Kaggle 的大部分用户来自员工不到 1000 人的公司,大规模的企业订阅不太可能成为重要的收入来源。
即使考虑到免费增值内核产品通过增加整体曝光和访问可能提供的潜在价值增长,增加免费增值产品也不太可能增加 Kaggle 的整体用户群。GitHub 似乎是这个细分市场的主导者,创建和营销一个独特的免费增值服务的成本可能会高得令人望而却步。
根据对当前 Kaggle 客户群的分析,内核订阅服务不太可能为公司带来可观的新收入。
咨询市场的潜力
在考虑提供咨询市场的潜在价值时,有几个因素需要考虑:
- 品牌意识吸引了那些需要外部人才的公司。
- 有才能的用户提供有意义的解决方案。
吸引合同雇主:提供的数据集包括一些与这两个因素相关的有趣信息。
尽管小公司规模是推动企业订阅的负面因素,但小公司更有可能需要外部帮助来满足数据科学需求。58%的 Kaggle 用户在 1000 人以下的公司工作,52%的用户在不到 5 人的数据科学团队工作。对于这样的公司来说,一个声誉良好的基于合同的市场会非常有帮助。
此外,Kaggle 目前的收入来源主要来自公司驱动的竞争,其中一部分专门专注于为公司问题寻找创造性的众包解决方案。吸引需要外部顾问型人才的公司的潜力唾手可得。
吸引有才华的承包商:此外,调查数据显示,Kaggle 已经与大量潜在的合同制员工建立了联系。如上所述,超过 60%的受访者年收入不到 5 万美元,这可能是一个有用的指标,表明用户希望从基于合同的数据科学工作中获利。Kaggle 竞赛的受欢迎程度,获奖者获得现金奖励,是一个明显的指标,表明 Kaggle 很容易与潜在的数据科学承包商建立联系。
此外,Kaggle 用户中有一个高素质的子集,他们可能会要求高额合同,从而增加公司的收入潜力。
除去“学生”受访者,超过 62%的 Kaggle 用户至少拥有硕士学位,其中 16%拥有博士学位。
此外,* 25%的 Kaggle 受访者来自印度,超过 80%的受访者生活在美国以外,而且绝大多数用户可能对远程咨询机会感兴趣。
最终结论
在研究了 Kaggle 用户调查的结果后,我们最初的假设被证明是错误的。由于 GitHub 等免费协作环境的激增,以及个人或企业订阅的不太可能的客户群,免费增值服务似乎只能略微增加收入。相比之下,由于 Kaggle 与需要外部帮助的积极雇主有现成的联系,以及高技能潜在承包商的大量用户群,承包商市场可以为实施成本带来更多收入。
作为这一分析的结果,我们可以确定 Kaggle 更有可能从一个货币化的顾问市场中获得可观的未来收入,而不是一个免费的核心产品。
GitHub / Jupyter 笔记本
关于这个项目代码的完整 Jupyter 笔记本,请访问我的 GitHub 库。
使用 Scikit-Multiflow 进行增量(在线)学习
原文:https://towardsdatascience.com/incremental-online-learning-with-scikit-multiflow-6b846913a50b?source=collection_archive---------3-----------------------
使用 scikit-multiflow 在 Python 中进行增量学习的实用介绍
Source: https://scikit-multiflow.github.io
介绍
数据就在我们身边。无论是个人资料图片、推文、传感器应用、信用卡交易、电子邮件还是新闻源,数据都在这里…并且以令人难以置信的速度生成。对于这些看似无限的数据流,一个关键的挑战是创建轻量级模型,这些模型总是能够预测和适应数据分布的变化。传统机器学习方法在这种情况下的局限性导致了在线学习(也称为增量学习)方法的发展。
在这篇文章中,我们将通过一个简单的在线分类器的实际实现,用 scikit-multiflow,一个用于数据流学习的 Python 框架,温和地介绍增量学习。
什么是增量学习?
在每次迭代中,模型预测一个类别标签,揭示真正的标签,然后更新
增量学习指的是一系列可扩展的算法,这些算法学习从无限的数据流中顺序更新模型。在“传统”机器学习中,我们得到了一个由(输入,输出)对组成的完整数据集,而在增量学习中,我们在创建模型时没有所有可用的数据。相反,数据点一次到达一个,我们必须建立一个“活的”模型,一个随着数据的到来而学习和适应的模型。增量模型具有以下特征:
- 它可以随时预测
- 它能够**适应概念漂移**——即数据 distribution⁴.的变化举一个具体的例子,如果我们有兴趣建立一个模型来预测银行应该贷款多少钱,金融危机可能会改变金额或需要考虑的因素。在这种情况下,模型需要重新学习很多信息。
- 它能够用有限的资源(时间和内存)处理无限的数据流。这意味着它不能像典型的机器学习方法那样存储所有的训练数据。
在 Python 中使用数据流
既然我们已经讨论了什么是增量学习,那么让我们在 Scikit-Multiflow 中解决一个简单的例子,这是一个用于数据流学习的免费 Python 框架。
我们要做的第一件事是安装 scikit-multiflow。
pip install -U scikit-multiflow
导入数据生成器很容易,可以通过以下命令完成:
from skmultiflow.data import SEAGenerator
这里,我们将使用 SEA generator,但是还有许多其他可用的选项(详细信息请参见文档:https://scikit-multiflow.github.io/scikit-multiflow/)。SEA 生成器允许你生成一个有 6 个输入和 2 个输出的无限数据流。这个特定的数据流包含频繁的、突然的概念漂移。
使用发电机很容易。我们需要做的第一件事是如下初始化它:
stream = SEAGenerator() # create a stream
stream.prepare_for_use() # prepare the stream for use
然后,如果我们希望获得一个数据样本,我们需要做的就是
X,Y = stream.next_sample()
其中,输入 X 是 6 维 np.array,输出 Y 是 2 维 np.array。
简单在线分类器
现在,让我们为 SEA 数据流创建一个简单的分类器。scikit-multiflow 提供了许多增量模型,其中最受欢迎的是 Hoeffding 树。
胡夫丁树
赫夫丁树是使用非常快速的决策树学习器(VFDT)构建的,这是一个随时系统,它使用每个示例的恒定内存和恒定时间来构建决策树。它是由 Pedro Domingos 和 Geoff Hulten 在 2000 年引入的,它利用了一个众所周知的统计结果,Hoeffding 界限,以保证其输出与传统学习者的输出渐*相同。
在 scikit-multiflow 中,创建 Hoeffding 树的过程如下
from skmultiflow.trees import HoeffdingTreetree = HoeffdingTree()
训练用于分类的赫夫丁树
如果我们想在海洋数据流上训练树,我们可以循环通过我们想要的任意多个数据点。
correctness_dist = []for i in range(nb_iters):
X, Y = stream.next_sample() # get the next sample
prediction = tree.predict(X) # predict Y using the tree if Y == prediction: # check the prediction
correctness_dist.append(1)
else:
correctness_dist.append(0)
tree.partial_fit(X, Y) # update the tree
使用“correctness _ dist”,一个由 1 和 0 组成的数组,取决于学习者是否准确地对输入的样本进行了分类,我们可以绘制出一段时间内的准确性
import matplotlib.pyplot as plttime = [i for i in range(1, nb_iters)]
accuracy = [sum(correctness_dist[:i])/len(correctness_dist[:i]) for i in range(1, nb_iters)]plt.plot(time, accuracy)
Accuracy over time for a Hoeffding tree modeling the SEA generator
Scikit-Multiflow 的替代方法
在 scikit-multiflow 中,有一种内置的方法可以用更少的代码做完全相同的事情。我们可以做的是导入 EvaluatePrequential 类:
然后,我们可以如下设置“评估器”
evaluator=EvaluatePrequential(show_plot=True,max_samples=nb_iters)
设置 show_plot=True 选项将允许弹出窗口显示分类精度的实时图。
现在赋值器已经设置好了,我们可以使用它在 SEA 数据流上递增地训练我们的 Hoeffding 树,方法和以前一样:
evaluator.evaluate(stream=stream, model=tree)
结论
希望这篇教程已经帮助你理解了增量学习的基础。此外,我希望您现在已经掌握了如何使用 scikit-multiflow 完成基本的数据流学习任务。
参考
[1] Doyen Sahoo 等人,“在线深度学习:动态学习深度神经网络”(2017), 1711.03705
[2] Jesse Read 等人,“动态和演进数据中的批量增量与实例增量学习”(2012 年),978–3–642–34156–4 _ 29
[3] Pedro Domingos 和 Geoff Hulten,“挖掘高速数据流”(2000 年),. 3447107
[4] Maayan Harel 等人,“通过重采样进行概念漂移检测”(2014), citation.cfm
Python 中的独立分量分析(ICA)
原文:https://towardsdatascience.com/independent-component-analysis-ica-in-python-a0ef0db0955e?source=collection_archive---------2-----------------------
Photo by ThisisEngineering RAEng on Unsplash
假设你在一个家庭聚会上和一个可爱的女孩聊天。当你听的时候,你的耳朵会被屋子里不同人群之间的对话和背景音乐的声音所包围。然而,这并不妨碍你专注于女孩在说什么,因为人类拥有区分声音的天赋。
然而,如果这是电影场景的一部分,我们用来记录对话的麦克风将缺乏必要的能力来区分房间里的所有声音。这就是独立成分分析,或简称 ICA 发挥作用的地方。ICA 是一种用于将多变量信号分离成其基本分量的计算方法。使用 ICA,我们可以从多个信号的融合中提取出想要的成分(即你和女孩之间的对话)。
独立分量分析(ICA)算法
在高层次上,ICA 可以分为以下几个步骤。
- 通过减去*均值使 x 居中
- 变白 x
- 为去混合矩阵 w 选择一个随机初始值
- 计算 w 的新值
- 正常化 w
- 检查算法是否收敛,如果没有,返回步骤 4
- 取 w 和 x 的点积,得到独立的源信号
美白
在应用 ICA 算法之前,我们必须首先"白化"我们的信号。“白化”一个给定的信号意味着我们以这样一种方式对其进行变换,即消除其分量之间的潜在相关性(协方差等于 0),并且每个分量的方差等于 1。另一种看待它的方式是白化信号的协方差矩阵将等于单位矩阵。
Identity Matrix
Covariance Matrix
我们着手白化信号的实际方法包括协方差矩阵的特征值分解。相应的数学方程可以描述如下。
其中 D 是特征值的对角矩阵(每个λ是协方差矩阵的特征值)
**
并且 E 是特征向量的正交矩阵
一旦我们完成了对信号的预处理,对于每个分量,我们更新去混合矩阵 w 的值,直到算法收敛或者达到最大迭代次数。当 w 与其转置的点积大致等于 1 时,认为达到了收敛。
在哪里
Python 代码
让我们看看如何使用 Numpy 在 Python 中从头开始实现 ICA。首先,我们导入以下库。
*import numpy as np
np.random.seed(0)
from scipy import signal
from scipy.io import wavfile
from matplotlib import pyplot as plt
import seaborn as sns
sns.set(rc={'figure.figsize':(11.7,8.27)})*
接下来,我们定义g
和g’
,我们将使用它们来确定 w 的新值。
*def g(x):
return np.tanh(x)def g_der(x):
return 1 - g(x) * g(x)*
我们创建一个函数,通过减去*均值来确定信号的中心。
*def center(X):
X = np.array(X)
mean = X.mean(axis=1, keepdims=True)
return X- mean*
我们使用上述方法定义一个函数来白化信号。
*def whitening(X):
cov = np.cov(X) d, E = np.linalg.eigh(cov) D = np.diag(d) D_inv = np.sqrt(np.linalg.inv(D)) X_whiten = np.dot(E, np.dot(D_inv, np.dot(E.T, X))) return X_whiten*
我们定义一个函数来更新去混合矩阵 w 。
*def calculate_new_w(w, X):
w_new = (X * g(np.dot(w.T, X))).mean(axis=1) - g_der(np.dot(w.T, X)).mean() * w w_new /= np.sqrt((w_new ** 2).sum()) return w_new*
最后,我们定义调用预处理函数的 main 方法,将 w 初始化为某个随机的值集,并迭代更新 w 。同样,收敛可以通过理想的 w 将是正交的这一事实来判断,因此 w 乘以其转置将*似等于 1。在计算出每个分量的最佳值 w 之后,我们将得到的矩阵与信号 x 进行点积,从而得到信号源。
*def ica(X, iterations, tolerance=1e-5):
X = center(X)
X = whitening(X)
components_nr = X.shape[0]W = np.zeros((components_nr, components_nr), dtype=X.dtype)for i in range(components_nr):
w = np.random.rand(components_nr)
for j in range(iterations):
w_new = calculate_new_w(w, X)
if i >= 1:
w_new -= np.dot(np.dot(w_new, W[:i].T), W[:i])
distance = np.abs(np.abs((w * w_new).sum()) - 1)
w = w_new
if distance < tolerance:
break
W[i, :] = w
S = np.dot(W, X)
return S*
我们定义一个函数来绘制和比较原始信号、混合信号和预测信号。
*def plot_mixture_sources_predictions(X, original_sources, S):
fig = plt.figure() plt.subplot(3, 1, 1)
for x in X:
plt.plot(x)
plt.title("mixtures") plt.subplot(3, 1, 2)
for s in original_sources:
plt.plot(s)
plt.title("real sources") plt.subplot(3,1,3)
for s in S:
plt.plot(s)
plt.title("predicted sources")
fig.tight_layout()
plt.show()*
为了前面的例子,我们创建了一个人工混合不同源信号的方法。
*def mix_sources(mixtures, apply_noise=False):
for i in range(len(mixtures)):
max_val = np.max(mixtures[i])
if max_val > 1 or np.min(mixtures[i]) < 1:
mixtures[i] = mixtures[i] / (max_val / 2) - 0.5
X = np.c_[[mix for mix in mixtures]]
if apply_noise:
X += 0.02 * np.random.normal(size=X.shape)
return X*
然后,我们创建 3 个信号,每个信号都有自己独特的模式。
*n_samples = 2000
time = np.linspace(0, 8, n_samples)
s1 = np.sin(2 * time) # sinusoidal
s2 = np.sign(np.sin(3 * time)) # square signal
s3 = signal.sawtooth(2 * np.pi * time) # saw tooth signal*
在前面的例子中,我们计算矩阵 A 和信号的点积,以获得所有三者的组合。然后,我们使用独立分量分析将混合信号分离为原始源信号。
*X = np.c_[s1, s2, s3]
A = np.array(([[1, 1, 1], [0.5, 2, 1.0], [1.5, 1.0, 2.0]]))
X = np.dot(X, A.T)
X = X.T
S = ica(X, iterations=1000)
plot_mixture_sources_predictions(X, [s1, s2, s3], S)*
接下来,我们使用 ICA 分解实际音轨的混合,并绘制结果。如果你想亲自尝试,你可以在这里获得音频样本。我鼓励你实际尝试听不同的音轨。
*sampling_rate, mix1 = wavfile.read('mix1.wav')
sampling_rate, mix2 = wavfile.read('mix2.wav')
sampling_rate, source1 = wavfile.read('source1.wav')
sampling_rate, source2 = wavfile.read('source2.wav')
X = mix_sources([mix1, mix2])
S = ica(X, iterations=1000)plot_mixture_sources_predictions(X, [source1, source2], S)wavfile.write('out1.wav', sampling_rate, S[0])
wavfile.write('out2.wav', sampling_rate, S[1])*
Sklearn
最后,我们看看如何使用 ICA 的scikit-learn
实现来达到同样的结果。
*from sklearn.decomposition import FastICAnp.random.seed(0)
n_samples = 2000
time = np.linspace(0, 8, n_samples)s1 = np.sin(2 * time)
s2 = np.sign(np.sin(3 * time))
s3 = signal.sawtooth(2 * np.pi * time)S = np.c_[s1, s2, s3]
S += 0.2 * np.random.normal(size=S.shape)
S /= S.std(axis=0)
A = np.array([[1, 1, 1], [0.5, 2, 1.0], [1.5, 1.0, 2.0]])
X = np.dot(S, A.T)ica = FastICA(n_components=3)
S_ = ica.fit_transform(X)fig = plt.figure()models = [X, S, S_]names = ['mixtures', 'real sources', 'predicted sources']colors = ['red', 'blue', 'orange']for i, (name, model) in enumerate(zip(names, models)):
plt.subplot(4, 1, i+1)
plt.title(name)
for sig, color in zip (model.T, colors):
plt.plot(sig, color=color)
fig.tight_layout()
plt.show()*
附带的 Jupyter 笔记本可以在这里找到。
深度:逐层相关性传播
原文:https://towardsdatascience.com/indepth-layer-wise-relevance-propagation-340f95deb1ea?source=collection_archive---------3-----------------------
深入 LRP 解释神经网络预测。
Predicting 5 seems to be related to an open loop at the bottom and a straight stroke at the top.
分层相关传播(LRP)是可解释机器学习(XML)中最重要的方法之一。这篇文章将会给你一个关于 LRP 的细节和一些实现它的技巧的好主意。内容很大程度上是基于本书第章。
为了让你对 LRP 的潜力垂涎三尺,先来看看这个互动演示。
LRP 的目的是为任何神经网络在其输入域中的输出提供一个解释。例如,如果你的网络从乳房 x 光片(乳房组织的图像)中预测出癌症诊断,那么 LRP 给出的解释将是原始图像中的哪些像素有助于诊断以及在多大程度上有助于诊断。这种方法不与网络的训练相互作用,因此可以很容易地将其应用于已经训练好的分类器。
XML 方法在安全关键领域特别有用,在这些领域中,从业者必须确切地知道网络在关注什么。其他用例是网络(错误)行为的诊断、科学发现和改进网络架构。你可以在 my short primer 中阅读 XML 的高级介绍以及它为什么有用。
逐层相关性传播
直观地说,LRP 所做的是,它使用网络权重和前向传递创建的神经激活,通过网络将输出向上传播到输入层。在那里,我们可以看到哪些像素真正影响了输出。我们将每个像素或中间神经元的贡献大小称为“相关性”值 R 。
LRP 是一种保守技术,这意味着任何输出 y 的幅度在反向传播过程中都是保守的,并且等于输入层的关联图 R 的总和。该属性适用于任何连续的层 j 和 k ,并且适用于输入和输出层的传递性。
记住那个属性,让我们一步一步来。假设我们的网络是一个分类器,它的输出是一个大小为 M 的向量,其中每个条目对应于 M 个类中的一个。在输出层,我们选择一个我们想要解释的神经元或类。对于这个神经元,相关性等于它的激活,输出层中所有其他神经元的相关性为零。例如,如果我们想使用 LRP 找出网络神经元和输入与预测类别 c 的相关性,我们从类别 c 的输出神经元开始,只查看网络如何得出该神经元的值。
从那里开始,我们通过遵循这个基本的 LPR 规则来回溯网络:
LRP-0
这里, j 和 k 是任意连续层的两个神经元。我们已经知道输出层中的相关性 R ,因此我们将从那里开始,并使用该公式迭代计算前一层的每个神经元的 R 。 a 表示各自神经元的激活, w 是两个神经元之间的权重。
这是最简单的 LRP 法则。根据您的应用程序,您可能想要使用不同的规则,这将在后面讨论。所有这些都遵循相同的基本原则。
这个公式是什么意思?分数的分子是神经元 j 对神经元 k 的影响量(对于有效 ReLU 的线性情况也是如此)。为了加强上述守恒性质,这必须除以下层所有神经元贡献的总和。我们通常在分母上加一个非常小的常数ϵ,使分数更稳定。外和超过 k 意味着神经元 j 的相关性由其对下一层所有神经元 k 的影响之和乘以这些神经元的相关性决定。
我们可以简单地从最后一层一直到第一层。取决于我们选择从什么输出神经元开始,我们可以得到任何类的解释。因此,我们甚至可以检查网络认为什么与预测任何类别 A 相关,即使它实际上预测了类别 B !
可以这样分析的网络结构没有很强的限制。例如,LRP 也非常适合 CNN,而可以用于 LSTMs 。但是,要求网络只包含 ReLU 激活功能。
希望你已经看到,基本原理很简单。为了让你更好地理解我们应用这个公式时的过程,我将把它解释为一个 4 步的过程——遵循下表中原始作者的过程。
Table from “Layer-Wise Relevance Propagation: An Overview”
第一步确定较高层中每个神经元的影响总和,类似于改进的正向传递。请注意,对于 ReLU 层,它与通过网络的正常正向传递相同,只是我们添加了一个小的常数ϵ,并在我们的权重周围包裹了一个函数ρ。这个ρ只是为了使公式更通用,包括我们后面会看到的所有可能的 LRP 规则。在我们之前的例子中,ρ是恒等函数,这意味着我们可以忽略它。
请注意,求和会在较低层的每个神经元 j 上进行,也会在偏置神经元上进行。在接下来的所有步骤中,偏差将被忽略,因为我们希望相关性只流向输入神经元,而不是在静态偏差神经元中结束。
在的第二步中,我们简单地用之前计算出的 z 值除以更高层中每个神经元的相关性。这确保守恒性质成立。
在第三步中,我们为前一层中的每个神经元计算一个量 c ,因此它可以被看作是一个反向传递。这个 c 可以粗略地看作有多少相关性从后续层向下流到神经元 j 。
最后,在第四步中,来自上面的相关性与神经元的激活相乘,以计算其自身的相关性。直觉上,如果 1)一个神经元具有高激活,并且 2)它对更高层的相关神经元贡献很多,则该神经元是相关的。
现在你应该已经能够自己实现 LRP 了!下一节将对此有所帮助。如果您只是想开箱即用,请注意已经有了优秀的实现。
实现技巧
当第一次介绍时,LRP 的作者提供了一个伪代码片段,它将通过网络一层一层地计算相关性,类似于我们前面看到的。(查看这个简短的教程来实现这个基础版本。)随着他们自己应用 LRP 的经验越来越丰富,他们出版了一个更有效的方法。
关键部分是利用高效的自动签名框架,如 pytorch 或 tensorflow 来为我们做反向传递。
From “Layer-Wise Relevance Propagation: An Overview”
与我们上面看到的公式的最大区别是,我们将计算 c 值作为梯度计算。
这允许我们利用高效的自动反向操作。为了解决这个问题并给出正确的结果,我们必须将 s 视为常数。这由。上面代码中的数据。
不同的规则
需要注意的是,LRP 有不同的传播规则,您可能希望将其中几种规则结合起来以获得最佳结果。幸运的是,这里有一个最重要的规则的简洁列表,以及何时使用它们的建议。
输入层:对于图像,LRP 的作者在深度泰勒分解论文中介绍了选择规则,并采用以下形式:
LRP-z
这里 l 和 h 分别是最低和最高的容许像素值。
较低层:这里我们希望解释更流畅,噪音更少,因为这些层已经非常接*我们人类将看到的并且必须理解的关联图。出于这个目的,我们可以使用 LRP-γ规则,该规则不成比例地倾向于正面证据而不是负面证据:
LRP-γ
更高层:上面的 LRP-γ或者下面的 LRP-ϵ规则在这里都可以很好地工作。它们从相关性图中去除了一些噪声。特别是,ϵ将吸收一些小的或矛盾的证据。
LRP-ϵ
输出层:这里我们理想地使用未修改的 LRP-0 规则。
规则甚至比这些更多,但是您在这里看到的规则对于大多数应用程序来说已经足够了。如果选择正确的规则对你来说过于复杂,不要担心!仅仅 LRP-0 和 LRP-ϵ应该可以让你走得很远,一旦你得到了这些规则的解释,你就可以决定是否花时间去试验其他的规则,让解释更漂亮。为了对不同的规则有一点直觉,我建议用互动演示来体验一下。
有这么多可能的规则也意味着你应该对 LRP 和类似技术之间的比较持保留态度,因为这些通常只根据基本的 LRP-0 规则进行。
应用程序
本节旨在简要给出一些成功应用 LRP 的例子。
Lapuschkin 等人利用该技术研究了从图像数据预测性别和年龄的网络。
Thomas 等人将该技术应用于大量 fMRI 神经成像数据,从 3D 数据中解释大脑状态。
Arras 等人将 LRP 应用于文本,研究神经网络如何将文本分类为属于一个或另一个主题。
霍斯特等人用 LRP 分析人类的步态模式。
Srinivasan 等人使用 LRP 找出视频中的哪些部分被分类器用于人体动作识别。
蒙塔冯等人在。将 LRP 应用于雅达利游戏和图像分类。
相关著作
既然您已经对 LRP 的内部运作有了很好的了解,那么提到相关的技术也是公*的。总括术语可解释的人工智能或可解释的人工智能可用于许多不同的技术。在这里,我将只指出一些与 LRP 密切相关的问题。
泽勒和弗格斯在 2014 年发表了一篇开创性的论文,用去进化网络可视化神经元激活。
Simonyan 等人在 2014 年发表了另一篇重要论文,基于泰勒分解计算显著图。
Springenberg 等人很快发表了导向反向传播。
张等()引入了激励反向传播,将反向传播视为一个概率过程。
Ramprasaath 等人为 CNN 引入了 Grad-Cam。
Sundararajan 等人介绍了积分梯度法。
在 LRP 的基础上由巴赫等人、蒙塔冯等人创立了深度泰勒分解。
感谢您的阅读!希望你学到了有用的东西。
熊猫系列最佳实践索引
原文:https://towardsdatascience.com/indexing-best-practices-in-pandas-series-e455c7d2417?source=collection_archive---------22-----------------------
何时以及如何执行有效的索引
Video Version of the story | By author
声明:这篇文章不会让你成为
***Pandas.Series***
方面的专家。这本身就是一篇文章要涵盖的非常广泛的主题。为此,我会推荐你阅读一本书或***Pandas***
文档。但是,我可以告诉你的是,这篇文章将让你在学习机器的旅程中离开地面。
在这篇文章中,我们将讨论一些在[Pandas.series](/pandas-series-a-part-of-the-backbone-for-machine-learning-in-python-c6a5003836c7)
中执行索引的最佳方法。众所周知,Pandas.series
中的索引不必是整数。在以下示例中,我们使用字符串作为索引:
import pandas as pd
george = pd.Series([10, 7],
index=['1968', '1969'],
name='George Songs')george
输出
这里,变量george
的索引类型是对象(熊猫表示字符串索引条目是对象)
george.index
输出
→**.is_unique**
——这是判断一个指标是否有重复的功能。
dupe = pd.Series([10, 2, 7],
index=['1968', '1968', '1969'],
name='George Songs')dupe.index.is_uniquegeorge.index.is_unique
输出
False
True
S 类似于NumPy
数组,一个Series
对象可以沿着轴被索引和切片。
george[0]
输出
10
索引规则有些复杂。它们的行为更像一个字典,但是在使用字符串索引标签(而不是基于整数的索引)的情况下,行为退回到 Python 列表索引。
george['1968']
输出
10
这个系列也可以通过位置(使用整数)进行索引,即使它有字符串索引条目!第一项位于 0 键,最后一项位于-1 键:
george[0]
george[-1]
输出
10
7
注意:如果索引已经使用整数标签,那么回退到基于位置的索引不起作用!:
george_i = pd.Series([10, 7],
index=[1968, 1969],
name='George Songs')george_i[-1]
输出
→ **.loc**
和**.iloc**
— 通过索引关闭.loc
和.iloc
属性来访问优化的数据访问方法。这两个属性分别允许基于标签和基于位置的索引。
当我们对.iloc
属性执行索引操作时,它会基于索引位置进行查找(在这种情况下,pandas 的行为类似于 Python 列表)。如果该位置没有索引,pandas 将引发一个索引错误:
george.iloc[0]
george.iloc[-1]
george.iloc[4]
george.iloc['1968']
输出
10
7
除了提取单个项目之外,我们可以像在普通 Python 中一样进行切片,并且您还可以将索引位置列表传递给索引操作:
george.iloc[0:3]
george.iloc[[0,1]]# both statements above will give the same output
输出
.loc
应该基于索引标签而不是位置。因此,它类似于基于 Python 字典的索引。虽然它有一些额外的功能,因为它可以接受布尔数组、切片和标签列表(这些都不适用于 Python 字典):
george.loc['1968']
george.loc['1970']
george.loc[0]
george.loc[['1968', '1970']]
george.loc['1968':]
输出
10
如果你被 .loc
和弄糊涂了。记住这一点。iloc 基于索引(从 I 开始)位置。。loc 基于标签(以 l 开头)。
→ **.at**
和**.iat**
—.at
和.iat
索引访问器类似于.loc
和.iloc
。不同的是,当拉出一个重复值时,它们将返回一个numpy.ndarray
,而.loc
和.iloc
返回一个序列。
george_dupe = pd.Series([10, 7, 1, 22],
index=['1968', '1969', '1970', '1970'],
name='George Songs')george_dupe.at['1970']
george_dupe.loc['1970']
输出
array([ 1, 22])
→**.ix**
——它类似于[]
分度。因为它试图支持基于位置和基于标签的索引。
george_dupe.ix[0]
george_dupe.ix['1970']
输出
10
限幅
S 可以对指标属性.iloc
和.loc
进行 licing。切片试图提取一系列索引位置,结果是一个序列,而不是单个索引位置的标量项。
切片采用[start]:[end][:stride]
的形式,其中 start、end 和 stride 是整数,方括号表示可选值。下表解释了.iloc
的切片可能性:
**Slice, Result** 0:1, First item
:1, First item(since default start is 0 & last index non-inclusive)
:-2, From start until second to last item
::2, From start to end every second item
以下示例返回从索引位置 0 到(但不包括)索引位置 2 的值:
george.iloc[0:2]
输出
布尔数组
使用布尔运算结果的切片被称为布尔数组。它返回一个经过筛选的序列,对该序列进行布尔运算。
mask = george > 7
mask
输出
当掩码与索引操作结合使用时,它返回一个序列,其中只返回与 True 位置相同的项目。
george[mask]
输出
多个布尔运算可以与这些运算相结合。
**Operation, Example** And, x[a & b]
Or, x[a | b]
Not, x[~a]
使用布尔运算符时,注意运算符优先级,以避免在()中包含运算。
mask2 = george <= 2
george[mask | mask2]
输出
我们看了指数。通过索引操作,我们可以从序列中提取值。因为可以通过位置和标签提取值,所以索引可能有点复杂。使用.loc
和.iloc
可以让你对索引操作更加清晰。我们也可以使用切片来提取值。此外,我们还可以使用布尔数组来过滤数据。
我将免费赠送一本关于一致性的电子书。在这里获得你的免费电子书。
这个关于索引的帖子在**Pandas.series**
到此结束。我希望你喜欢这篇文章。
如果你喜欢阅读这样的故事,那么你应该 在你的收件箱 中获得我的帖子,如果你想支持我成为一名作家,考虑注册成为一名媒体成员。每月 5 美元,你可以无限制地阅读媒体上的故事。如果你注册使用我的链接,我会赚一小笔佣金,不需要你额外付费。
[## 加入我的推荐链接-塔伦古普塔
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
tarun-gupta.medium.com](https://tarun-gupta.medium.com/membership)
感谢阅读。要阅读更多文章,请访问此处:
[## 标记故事列表的快速链接—感谢您的访问
我也有一份以快节奏出版为目标的出版物。读书成为作家。
tarun-gupta.medium.com](https://tarun-gupta.medium.com/thank-you-for-visiting-my-profile-9f708062c75e)
印度空气质量数据分析
原文:https://towardsdatascience.com/india-air-pollution-data-analysis-bd7dbfe93841?source=collection_archive---------3-----------------------
健康影响研究所(Health Effects Institute)关于印度空气污染的报告(2018)称,2015 年,空气污染导致印度 110 万人死亡。
空气污染是指污染物释放到空气中,对人类健康和整个地球都有害。
今天,空气污染已经成为任何国家都要解决的重大问题之一。在南亚,它被列为第六大最危险的杀手。如果一个人一开始没有经历过某个问题,他/她就不会意识到它的有害影响。
以德里为例,排灯节后,我们都经历过在持续约一周的“致命”烟雾中吸入空气的感觉。市民被告知不要离开他们的家,并被要求外出时戴上口罩。看着窗外,让我觉得自己好像生活在一个毒气室。能见度低,死亡人数多等。是污染的影响。
作为一名数据分析和数据科学爱好者,我决定分析我自己国家的空气质量数据,以找到一些潜在的原则或模式,这些原则或模式可能会让我深入了解问题有多严重,我必须说这些结果值得分享。所以,我写这篇文章来分享我的方法和我对数据的分析,同时也让人们意识到我们国家面临的巨大问题。
方法
以下数据分析用 python 进行,代码可从 Github 库下载:空气质量分析
数据
该数据是印度环境和森林部以及中央污染控制委员会根据国家数据共享和可访问性政策(NDSAP)发布的历史每日环境空气质量数据的更干净版本。
数据集包含以下特征:
- 车站代码:车站代码。每个记录数据的站点都有一个代码。
- 采样日期:记录数据的日期。
- 状态:表示测量空气质量数据的状态。
- 位置:代表测量空气质量数据的城市。
- 机构:测量数据的机构名称。
- 类型:进行测量的区域类型。
- so2 :测得的二氧化硫的量。
- no2 :测得的二氧化氮量
- rspm :测得的可吸入悬浮颗粒物。
- spm :测量悬浮颗粒物。
- location _ monitoring _ station:表示监控区域的位置。
- pm2_5 :表示颗粒物的测量值。
- 日期:表示记录的日期(是‘采样 _ 日期’功能的更简洁版本)
为什么有这些功能?
SO₂:二氧化硫是一种气体。它是空气中的主要污染物之一。它是无色的,并且有一种令人讨厌的、刺鼻的气味。
它毫不费力地与其他化学物质结合,形成有害物质,如硫酸、等。
二氧化硫被吸入后影响人体健康。它会刺激鼻子、喉咙和气道,导致咳嗽、喘息、呼吸急促或胸部紧绷感。如果接触二氧化硫,最有可能出现问题的是患有哮喘或类似疾病的人。此外,大气中二氧化硫的浓度会影响植物群落和动物的栖息地适宜性。
吸入二氧化硫会导致呼吸道症状和疾病增加、呼吸困难和过早死亡。
还会造成酸雨。
NO₂ :二氧化氮是一种红棕色气体,带有刺鼻、辛辣的气味。
它会导致支气管收缩、炎症、免疫反应减弱,并可能对心脏产生影响。直接接触皮肤会导致刺激和灼伤。
下面大致介绍一下二氧化氮对健康的影响:
10-20 ppm 会引起对鼻子和喉咙的轻度刺激
25-50 ppm 会引起水肿导致支气管炎或肺炎
浓度超过 100 ppm 会导致死亡由于窒息体内的液体高浓度的 NO₂会损害植物,包括叶子受损和生长减缓。会使植被更容易受到病害和冻害。
长时间暴露于高浓度的 NO₂可能会导致哮喘的发生,并可能增加呼吸道感染的易感性。
颗粒物:这些也被称为大气气溶胶粒子、大气颗粒物、颗粒物(PM) 或悬浮颗粒物(SPM)。 这些是悬浮在大气中的微观固体或液体物质。
微粒是最致命的空气污染,因为它们能够未经过滤就深入肺部和血流,导致永久性 DNA 突变、心脏病发作和过早死亡。
2016 年,全球暴露于 PM 2.5 导致了 410 万人死于心脏病和中风、肺癌、慢性肺病和呼吸道感染。总体而言,环境颗粒物是全球过早死亡的第六大风险因素。
互联网上充斥着上述污染物的有害影响,因此当讨论空气污染时,它们成为分析和考虑的重要因素。
回到分析上来。
数据探索 让我们获得一些关于数据的见解——每一列中条目的数量、每一列中条目的类型等等。
从上图中,我们看到我们的数据集中有 435742 个条目。我们还看到我们只有两种数据类型:float 和 object。pm2_5 的数值很少。
现在,让我们检查空值。
Null values in the dataset
似乎我们在一些列中有很多空值。查看该图,我们看到 pm2_5 具有非常少的非空值,并且它可能无法贡献太多。stn_code、agency、spm 也用空值填充。
让我们停下来看看这些特性有多大帮助。如果我必须分析印度的空气污染数据,那么我需要考虑为我提供数据的机构的名称吗?不,因为这个机构的名字与这个州的污染程度无关。同样, stn_code 也是不必要的。
数据描述中给出了日期是采样 _ 日期属性的更清晰的表示,因此我们将通过移除后者来消除冗余。
location _ monitoring _ station属性也是不必要的,因为它包含了监测站的位置,我们在分析时不需要考虑它。
因此,总的来说,我们将从数据集中删除以下要素:
机构、stn_code、sampling_date 和location _ monitoring _ station。
让我们看看还剩下什么
Dataset after removing the unnecessary columns
现在让我们考虑一下型的特征。
表示记录数据的区域类型,如工业区、住宅区等。
让我们看看考虑了多少种类型的区域:
Different categories in the type attribute
似乎我们有多余的类型。请看上图,可以说一个给定的区域可以分为三类:工业区、住宅区、其他区。
所以,我们必须去掉这个冗余,让类更干净。
我已经简化了类型属性,使其只包含上述三个类别中的一个。
输入属性后改变类别:
现在看起来好多了,也干净多了。我们可以使用 cat 图来可视化类型属性。
the plot of Number of entries vs Categories in the type column
看上面的图,我们可以说数据是在居民区附*记录的,因为它有最多的条目。这是显而易见的,因为人们更关心人们居住的地方。
现在让我们考虑空值。
我们在类型、和 so2 中有几个空值,因此我们将删除这三个属性中每一个都有空值的行。
现在让我们看看我们的数据是什么样的:
Dataset after deleting the rows which had null values in so2, location
我们可以看到剩下 396157 个值,所以我们没有删除非常多的值。
删除三列中的空值而不是输入,这只是我个人的偏好。人们可以估算这些空值;然而,估算像 pm2_5 这样具有大量空值的列是一种不好的做法。
数据可视化
让我们用柱状图按降序画出不同状态下的 so2 浓度。
barplot of so2 vs states
从上图中,我们看到北阿坎德邦的二氧化硫水*最高,昌迪加尔邦最低。
北阿坎德邦、锡金邦、贾坎德邦、古吉拉特邦、马哈拉施特拉邦、查提斯加尔邦——政府应采取措施应对这些邦不断增长的二氧化硫浓度。
让我们通过绘制 so2 浓度的位置(城市)来更深入地了解:
barplot of so2 vs location for 50 sites with highest so2 concentrations
上图显示了 50 个二氧化硫含量最高的地方,按降序排列。
我们可以看到,Dharudhera 的 so2 浓度最高,位于哈里亚纳邦,其次是贾坎德邦的 Jamshedpur。
另一方面,Amlai(中央邦)和 Sindri(恰尔肯德邦)的二氧化硫浓度在前 50 个地区中最低。
现在让我们画出 so2 浓度最低的 50 个地点:
barplot of so2 vs location for 50 places with least so2 concentrations
我们可以看到,位于喀拉拉邦的 Kottayam 的二氧化硫水*最低,正如我们从二氧化硫与邦的柱状图中看到的那样,喀拉拉邦是二氧化硫浓度最低的邦之一。事实上,Malappuram(喀拉拉邦)、Konark(奥里萨邦)、dawki(梅加拉亚邦)……Nala garh(喜马偕尔邦)、Naharlagun(阿鲁纳恰尔邦)和 Kalyani(西孟加拉邦)的二氧化硫浓度几乎相同。
现在让我们看看 no2 的浓度:
barplot of no2 vs state
从图中可以清楚地看出,西孟加拉邦的 no2 含量最高,而那加兰邦的 NO2 含量最低。德里(首都)排名第二,其次是贾坎德邦。
过去几年里,德里因空气污染,尤其是二氧化氮浓度问题多次成为头条新闻,这并不奇怪。
让我们更深入地看看哪些地方受影响最大:
barplot of no2 vs location for 50 sites with highest no2 concentrations
上图显示了 50 个二氧化氮水*最高的地方。
我们可以看到,豪拉(西孟加拉邦)的 no2 浓度最高,其次是巴德拉布尔(马哈拉施特拉邦)和杜尔加布尔(西孟加拉邦)。
很明显,就二氧化氮而言,污染最严重的城市(豪拉)属于污染最严重的邦(西孟加拉邦)。
现在让我们看看 no2 浓度最低的 50 个位置:
barplot of no2 vs location for 50 sites with the least no2 concentrations
从上图中我们可以看出,Rudrapur(北阿坎德邦)是 no2 污染最少的城市,其次是 Alappuzha(喀拉拉邦)和 Kohima(那加兰邦)。
现在让我们看看 rspm :
barplot of rspm vs state
从上面的图中,我们看到德里的可吸入颗粒物浓度最高,这一点也不奇怪,因为在过去几年中,任何与印度污染相关的新闻报道中都可以看到这一点。谈到空气污染,德里一直是一个重要的目标。德里污染物的显著增加使人们遭受了很多痛苦,并导致了数千人的死亡。
从上面的图中,我们还看到,就 rspm 而言,北方邦(UP)离德里也不远。作为美国人口最多的州,UP 的空气呼吸起来并不“安全”。应对可吸入颗粒物水*的上升变得非常必要,尤其是在 UP,因为它是 20 多亿人的家园。还有,UP 和德里是邻州(有意思)。
接下来,我们来看看旁遮普。谈到空气污染,旁遮普总是成为头条新闻,主要是因为农民。这是一个如此重要的问题,以至于政府已经发布了许多政策和计划来阻止稻农通过焚烧水稻收获后留下的残茬来清理他们的田地。
另一方面,锡金的可吸入颗粒物浓度最低,其次是米佐拉姆和普杜切里。
让我们更深入地研究,看看不同位置的可吸入颗粒物浓度:
barplot of rspm vs location for 50 locations which have the highest levels of rspm
从上面的图中可以看出,Kashipur(北阿坎德邦)的 rspm 水*最高,其次是 Ghaziabad(上)和 Allahabad(上)。大多数顶级位置属于 UP,这说明 UP 在可吸入颗粒物方面是污染第二严重的州。
现在让我们看看可吸入悬浮粒子浓度最低的地点:
barplot of rspm vs location for few sites which have the least levels of rspm
从上面的图中我们可以看出,可吸入颗粒物水*最低的是巴塔那姆希塔(喀拉拉邦),其次是农斯托因(梅加拉亚邦)和占姆海(米佐拉姆邦)。我们可以看到,这些位置所属的状态位于 rspm 与状态的条形图的下方。
现在让我们考虑 spm:
barplot of spm vs states
我们看到北方邦和德里再次名列榜首。UP 和德里的 spm 和 rspm 浓度相当。一则新闻报道称:
1997 年,北方邦首府勒克瑙的一个空气质量监测站记录的悬浮颗粒物质(spm)最高水*为每立方米 2339 微克,超过住宅区允许限值的 11 倍,工业区限值的 4 倍。这与德里记录的最高值一样高:1992 年为 2,340 克/立方米。
如果我们更仔细地观察这个图,我们会发现德里及其以上地区的 spm 水*远远高于其他任何一个邦。拉贾斯坦邦 3 号的浓度明显低于 UP 或德里。
另一方面,果阿的悬浮颗粒物浓度最低,其次是喀拉拉邦和梅加拉亚邦。
请注意,阿鲁纳恰尔邦和特伦甘纳邦的值为空,并且这些邦的 spm 浓度不为零。
让我们更深入地了解一下 spm 最集中的位置:
barplot of spm vs location for sites with the highest level of spm
从上面的柱状图我们可以看出,密鲁特(上图)是悬浮颗粒物污染最严重的城市,其次是胡尔贾(上图)和加济阿巴德(上图)。
事实上,排名前 7 位的城市,即密拉特、胡尔贾、加济阿巴德、坎普尔、菲罗扎巴德、诺伊达和阿拉哈巴德,都位于上城区。这是一个令人担忧的情况,因为当谈到 spm 或 rspm 时,这个国家人口最多的州污染最严重。
现在让我们考虑最后但并非最不重要的特征,即 pm2_5:测量/记录的颗粒物值:
bar plot of pm2_5 vs state
我们可以看到,大多数状态都有空值,如上所述,很明显 pm2_5 有最多的空值(97.86%的空值)。从我们掌握的信息来看,我们看到德里再次位居榜首,其次是西孟加拉邦和中央邦。由于 pm2_5 有大量的空值,所以没有太多可以讨论的。
让我们绘制 pm2_5 和所有非空值的位置之间的柱状图:
barplot of pm2_5 vs location for all non-null values
我们看到德里仍在榜首,紧随其后的是塔尔彻(奥里萨邦)和瓜廖尔(中央邦)。
统计分析
现在,让我们对数据集进行一些统计分析,并检查这些特征是否有一些关系。
我们将从绘制每个特征的散点图开始:
scatter plot for each column
首先,我不会评论 pm2_5 和任何其他特性之间的关系,因为 pm2_5 有大量的空值。因此,其统计意义非常低,甚至可以忽略不计。
so2 和 no2 值高度集中在原点附*,这意味着在大多数观测中,这两个值都很低。
我们可以看到 no2 和 so2 的模式与其他特征有些相似。
可以说 spm 和 rspm 有一定的线性关系,其余所有特征并不完全相关。
为了进行更深入的分析,让我们来看看相关矩阵:
Correlation matrix for the dataset
从相关矩阵中可以清楚地看出, spm 和 rspm、之间存在一定的相关性,这支持了我们的散点图分析。 其他特征之间关联不大。
日期特征
现在让我们使用我们还没有接触过的日期特性。
日期特征表示记录数据的日期。
让我们提高效率,从日期特征设计一个新的特征(年份)。这是因为我们对空气污染的年度影响感兴趣。
制作年份列后,数据如下所示:
dataset after devising year column from date feature
现在我们已经创建了一个 year 列,这样我们就可以每年分析数据。
使用热图进行 so2 分析
让我们绘制 so2 热图,其中
行:州属性
列:年属性
值: so2 属性
heatmap for so2 with state and year attributes
从热图中可以明显看出,从 1987 年到 1999 年,比哈尔邦的二氧化硫浓度逐渐增加。同样,1995 年前后,古吉拉特邦的二氧化硫浓度也很高。在哈里亚纳邦,我们也可以看到 1987 年左右的二氧化硫水*很高,并且一直高到 2003 年。从 1987 年到 2000 年,卡纳塔克邦的二氧化硫浓度也逐渐增加。大约在 1996 年,Puducherry 也见证了 so2 浓度的高值。
拉贾斯坦邦在 1987 年左右也经历了高浓度的二氧化硫。
从 2004 年至今,北阿坎德邦的二氧化硫浓度一直很高。在西孟加拉邦,so2 浓度从 1987 年到 2000 年一直很高。
上述分析表明,从 1980 年到 2000 年,一些国家的污染物二氧化硫含量很高,但在新世纪(从 2000 年起)有所下降。
我找到了下面这篇支持我们的结论和热图分析的新闻文章。
美国宇航局 Aura 卫星发布的数据质疑中央污染控制委员会(CPCB)在 2012 年声称的准确性,即 2010 年印度的二氧化硫(SO2)*均排放量与 2001 年相比有所下降。
一些邦,如北阿坎德邦、恰尔肯德邦、锡金邦等。仍然经历相当高水*的 so2 浓度。
请注意,这些是二氧化硫与状态的柱状图顶部的状态。
热图显示,关注二氧化硫浓度的危险水*,采取了正确的措施来降低它。例如,空气(污染防治)法案于 1981 出台,并于 1987 修订。
实施见成效,二氧化硫水*下降。
使用热图进行 No2 分析:
在下面的热图中,我们有
行:州属性
列:年属性
值: no2 属性
heatmap for no2 with state and year attributes
我们可以看到,拉贾斯坦邦、比哈尔邦、德里、哈里亚纳邦、恰尔肯德邦、普杜切里邦、西孟加拉邦等邦都经历了严重的 no2 浓度水*。
在一些邦,如拉贾斯坦邦,二氧化氮浓度逐年下降,而在比哈尔邦、德里等邦。它增加了。在西孟加拉邦、恰尔肯德邦等其他邦,no2 浓度一直居高不下。
如果我们仔细观察热图,我们会发现从 2000 年开始,整个国家的 no2 浓度都在增加。
我找到了以下支持上述结论的新闻文章:
美国宇航局的卫星地图显示,在 2005 年至 2014 年期间,包括印度在内的南亚地区,二氧化氮污染物的排放量显著增加,严重影响了空气质量。
使用热图的 rspm 分析
在下面的热图中,我们有
行:州属性
列:年属性
值: rspm 属性
heatmap for rspm with state and year attributes
热图是一种非常重要的数据分析工具,它让一切都变得非常容易分析。人们可以很容易地看到变化,各州各年的可吸入颗粒物水*等。
这里我们看到,像德里、旁遮普、北方邦、哈里亚纳邦和恰尔肯德邦都遭受了高水*的可吸入颗粒物。
使用热图进行 spm 分析
在下面的热图中,我们有
行:状态属性
列:年份属性
值: spm 属性
heatmap for spm with state and year attributes
这里我们看到,像德里、哈里亚纳邦、旁遮普邦、北方邦等邦是 spm 高度集中的主要受害者。
结论
从上面的分析中,我们看到印度受空气污染影响最大的邦属于北部地区。德里、旁遮普邦、北方邦、哈里亚纳邦等邦污染严重,需要立即采取行动。
我们还发现,即使一个州的污染物水*很高,也有一些地区没有受到污染。
我们还从统计分析散点图中看到,具有高 rspm 浓度的州也具有高 spm 浓度。
根据热图,我们得出结论,一些州在早期(1980 年至 2000 年)污染严重,但后来得到了治理。下降的原因可能是公民意识和政府政策。
例如,1981 年空气(防止和控制污染)法案是和法案,规定了防止、控制和减少空气污染。另外,我发现了一篇新闻文章,内容如下:
车辆排放控制的故事始于印度,当时大规模排放标准于 1991 年首次对汽油车实施,并于 1992 年对柴油车实施。1996 年,随着汽油车催化转换器的强制安装,排放标准进一步收紧。巴拉特阶段排放标准(相当于四轮车的欧洲标准)于 2000 年首次引入。这些规范规定了一氧化碳(CO)、碳氢化合物(HC)、氮氧化物(NOx)和颗粒物(PM)的最大允许排放限值。
上述新闻文章明确指出,政府采取了必要的措施,以对付日益严重的空气污染(我们看到的),从 1990 年至 2000 年。这可能是我们在热图中看到一些州的污染物浓度从 2000 年开始下降的原因之一。
下文陈述的另一篇新闻文章支持上述结论。
环境和森林部发起的 1997 年白皮书已经提出了各种措施来减少交通造成的污染,包括通过停车条例来改善交通流量,通过强制限制驾驶来减少交通流量。城市当局声称在降低空气污染方面取得了一些成功;例如,在 2014 年亚运会的申办过程中,该城市的组织委员会声称,“随着地铁的到来以及所有公共交通车辆强制使用压缩天然气,德里的污染水*大幅下降”。
结束注释
从上述数据分析方法,我们得出结论,数据分析是一个更好的未来至关重要的方面。
这种方法是纯数据驱动的,但是有现实生活中的实例(新闻文章)支持。
有趣的是,我们可以看到数据分析和日常实例是如何联系在一起的,以及数据分析是如何用于处理重大问题的。
我建议通过 GitHub repository 链接(在本文开头提供)找到上述方法的代码,以便更深入地了解如何用 python 实现数据分析。
这就是我对我的国家的分析,这个国家正在慢慢变成毒气室。不仅印度,其他国家也遭受空气污染。我们必须找到解决这个重大问题的方法,因为它正在慢慢地扼杀我们的国家。
如果你有任何建议或任何改进建议,请写在评论区。我将不胜感激。
使用深度神经网络的印度演员分类
原文:https://towardsdatascience.com/indian-actors-classification-using-deep-neural-networks-8552573f39aa?source=collection_archive---------22-----------------------
如果你需要使用深度网络对你最喜欢的演员进行分类,该怎么办?
在这篇文章中,我想演示使用神经网络的多类分类。
对于数据集,我已经收集了印度演员的图像样本[萨尔曼·可汗(401 张图像)、沙鲁克·汗(411 张图像)和阿米尔·可汗(433 张图像)]到单独的文件夹中。]
我们的问题陈述包括使用深度神经网络将印度演员的样本图像分类到正确的标签中,并在测试数据集上训练模型和计算准确度。
让我们开始练习吧
1.首先导入要使用的必要库。对于神经网络,我使用了 Keras 以及 numpy、pandas、matplotlib、cv2 和 seaborn。
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import to_categorical
from keras.layers import Flatten,MaxPooling2D,Conv2D,LeakyReLU
from keras import optimizers
2.数据集包括对应于每个印度演员的图像的命名文件夹。将文件夹中的图像加载到 numpy 数组中。此外,转换所有的图像大小为常数大小,即(6464)或(128128)和可视化的一类。
import cv2
import os
def load_images_from_folder(folder):
images = []
for filename in os.listdir(folder):
img = cv2.imread(os.path.join(folder,filename))
if img is not None:
img1=cv2.resize(img,(64,64))
images.append(img1)
return images**#Load the images**
amir=load_images_from_folder('./AamirKhan/')
salman=load_images_from_folder('./SalmanKhan/')
shahruk=load_images_from_folder('./ShahrukhKhan/')train_amir = np.array(amir)
train_salman = np.array(salman)
train_shahruk= np.array(shahruk)**#Visualize the images**
fig = plt.figure(figsize=(20,5))
for i in range(36):
ax = fig.add_subplot(3, 12, i + 1, xticks=[], yticks=[])
ax.imshow(np.squeeze(salman[i]))
3.下一步是为图像创建标签,因为每个印度演员都有对应的文件夹。我创建了一个 numpy 数组,其长度与特定的类[阿米尔·可汗]相同,并给定标签为零。类似地,萨尔曼·可汗为 1,沙鲁克·汗为 2。
train_amir_label=np.zeros(len(train_amir))
train_salman_label=np.ones(len(train_salman))
train_shahruk_label=np.full(len(train_shahruk),2)
print(train_amir.shape,train_amir_label.shape)
print(train_salman.shape,train_salman_label.shape)
print(train_shahruk.shape,train_shahruk_label.shape)
4.将所有图像连接成 X,将所有相应的标签连接成 y。使用 keras.utils 的 to _ categorical 方法将 y 标签转换成一个热编码。使用训练测试拆分方法,将数据集拆分为 X_train、y_train、X_test 和 y_test,并对数据进行归一化处理。
**#Concatenate**
X=np.concatenate((train_amir,train_salman,train_shahruk))
y=np.concatenate((train_amir_label,train_salman_label,train_shahruk_label))
y_label =to_categorical(y)**#Train -Test Split**
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y_label, test_size=0.33, random_state=42,shuffle=True)**#Normalize the data**
X_train=X_train.astype('float32')
X_test=X_test.astype('float32')
X_train=X_train/255
X_test=X_test/255
print("Training Data",X_train.shape)
print("Testing Data",X_test.shape)
5.现在我定义多层神经网络。框图包括以下内容。基本架构是 Conv2d 层[3*3],然后是 leaky Relu 激活,然后在其上应用 Max Pooling[2 * 2]层。有 3 个这样的分层网络[Conv2d->Leaky Relu->Max Pool]将尝试使网络更深,并将从这些层中提取特征地图。在后面的层中,我将 Conv2d 层的输出展*为 1 维,并应用了两个密集层,中间有 Leaky Relu,然后是 Softmax,以将最终输出转换为 3 类概率。使用的一些超参数如下
epochs =20,alpha =0.1,batch size =64,padding = same[这是为了保留与输入图像相同的大小],optimizer = Adam,loss function = cross 熵。
**#HyperParameters**
batch_size = 64
epochs = 20
num_classes = 3
input_shape=(64,64,3)
**#Model Define** model = Sequential()
model.add(Conv2D(32, kernel_size=(3,3),activation='linear',input_shape=input_shape,padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(MaxPooling2D((2, 2),padding='same'))
model.add(Conv2D(64, (3, 3), activation='linear',padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
model.add(Conv2D(128, (3, 3), activation='linear',padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
model.add(Flatten())
model.add(Dense(128, activation='linear'))
model.add(LeakyReLU(alpha=0.1))
model.add(Dense(3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='Adam',metrics=['accuracy'])
model.summary()
6.在定义了模型之后,我传递了 X_train,y_train 数据以及验证数据(X_test,y_test ),并计算了精确度。对数据集的 834 个样本进行了训练,对数据集的 411 个样本进行了验证。准确率为- 86.86%
np.random.seed(42)
model_1=model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=64,shuffle=True)
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))
7.我绘制了验证和训练曲线,并检查模型是否过拟合或欠拟合,或者它只是很好。这个模型既没有过拟合也没有过拟合。
test_eval = model.evaluate(X_test, y_test, verbose=0)
print('Test loss:', test_eval[0])
print('Test accuracy:', test_eval[1])accuracy = model_1.history['acc']
val_accuracy = model_1.history['val_acc']
loss = model_1.history['loss']
val_loss = model_1.history['val_loss']
epochs = range(len(accuracy))
plt.plot(epochs, accuracy, 'r', label='Training accuracy')
plt.plot(epochs, val_accuracy, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'r', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
8.我还想知道有多少样本被错误分类。为此,我计算了混淆矩阵,发现 149 个样本中有 123 个样本正确地将阿米尔·可汗归类为阿米尔·可汗。26 个样本被错误归类,109 个样本正确地将萨尔曼·可汗归类为萨尔曼汗,125 个样本将沙鲁克汗归类为沙鲁克汗。
from sklearn.metrics import confusion_matrix
y_test_pred=model.predict(X_test)
cnf_matrix = confusion_matrix(y_test.argmax(axis=1), y_test_pred.argmax(axis=1))
cnf_matrix
9.最后,我在看不见的数据上测试了模型,并可视化了样本。几乎所有的随机样本都给了我正确的预测。
testdata= load_images_from_folder('../Q1_TestData/')
testimages=np.array(testdata)
predicted_classes = model.predict(testimages)
predicted_classes1 = np.argmax(np.round(predicted_classes),axis=1)
**#Visualize the test data**
fig = plt.figure(figsize=(20,5))
for i in range(36):
ax = fig.add_subplot(3, 12, i+1,xticks=[], yticks=[])
plt.imshow(testimages[i])
if (predicted_classes1[i]==0):
plt.xlabel('amir')
if (predicted_classes1[i]==1):
plt.xlabel('salman')
if (predicted_classes1[i]==2):
plt.xlabel('shahruk')
plt.show()
瞧啊。请点赞并分享..谢谢..你可以帮我联系@https://www.linkedin.com/in/ashishbansal1/
印度犯罪数据分析
原文:https://towardsdatascience.com/indian-crime-data-analysis-85d3afdc0ceb?source=collection_archive---------16-----------------------
rawpixels
对所犯罪行的详细分析和可视化。
犯罪率不断上升,科技也是如此。我想把它们结合起来产生有意义的见解。不过,关于伦敦和芝加哥犯罪分析的工作很多,但关于印度的记录却很少。因此,我从 data.world 中找到了一个数据集用于这项研究。这个项目的目标是找出哪个州的犯罪率最高,哪个州发生了犯罪。事不宜迟,我们开始吧。
该数据集包含因对儿童犯罪而被逮捕的州和中央直辖区人员的数据。从柱状图中可以看到 2001 年至 2012 年的犯罪数量。
我们将导入熊猫库来访问数据集。之后,我们将 CSV 文件读入数据帧(df)。显示了数据框的片段。
**import** **pandas** **as** **pd** df = pd.read_csv('data.csv')
df.head()
数据争论
数据争论是清理复杂数据集以进行操作和分析的过程。
由于这些值是以年度格式表示的,我们将对它们进行组合运算。为此,我们将使用以下代码
df['total']=df.iloc[:,-12:].sum(axis=1)
df.head()
We can see that a new column, total is added which contains the sum of all the values from 2001–2012
现在,我们已经添加了一个新列,我们不需要所有其他列,因此为了简化我们的数据框,我们将删除它们。
df.drop(df.columns[[2,3,4,5,6,7,8,9,10,11,12,13]], axis = 1, inplace = **True**)
df.head()
为了获得数据框的简明摘要,我们将使用 info()函数。它有助于获得数据集的快速概览。
df.info()
正如我们在输出中看到的,摘要包括所有列及其数据类型的列表,以及每列中非空值的数量。因为我们的值不为空,所以我们不必填充缺失的值。
我们只想访问国家和联盟领土的犯罪数据。因此,为了更好地可视化,我们将删除包含所有值的行。
d=df[:-38] *#to drop total crime rows*
删除包含总值的最后 38 行。
数据可视化
他们说一张照片胜过千言万语。
的确是!!数据的可视化有助于理解数据中的趋势、异常值和模式。
我们将绘制一个条形图来了解哪种犯罪在印度最为普遍。为此,我们将导入' matplotlib '库,只用 3 行代码来绘制图表。
**import** **matplotlib.pyplot** **as** **plt**
plt.xticks(rotation='vertical') #for labeling the values vertically
plt.bar(x="CRIME HEAD", height="total", width=0.8, bottom=**None**, align='center', data=d)
从图表中,我们可以看到“其他犯罪”类别的数量最高,其次是“绑架”和“强奸”儿童。因此,我们将重点关注这些类型,因为它们更普遍。
剖析具体犯罪
我们将逐一分析具体的犯罪,以获得更好的见解。首先是绑架。
*#Analyzing a specific crime-kidnapping*
kidnap = d[d.crime_list.str.contains('KIDNAPPING and ABDUCTION OF CHILDREN')]
kidnap.shape
k=kidnap.drop(kidnap.index[[-1,-2,-10]])
k.plot(kind='bar',x='State/UT',y='count',color='blue')
通过图表我们可以看出,北方邦的绑架案数量最多,共有 30,625 起,占所有邦的 38%。对于一个国家来说,这是一个令人震惊的数字,那里已经混乱不堪。因为如此高的比率,人们正在散布诱拐和绑架儿童的虚假谣言。由于这种情况,该州宣布:“如果将来有此类案件被报道,将根据《国家安全法》(NSA)对被告提出指控。”
现在,我们将想象第二高的犯罪,即强奸儿童。
在印度,2001 年至 2011 年期间,"亚洲人权中心"共报告了 48,338 起强奸未成年人案件,增长了 336%:从 2001 年的 2,113 起增加到 2011 年的 7,112 起。
2017 年,世卫组织估计,多达10 亿 2 至 17 岁的未成年人遭受过暴力身体、情感或性暴力。根据联合国儿童基金会 2014 年的一些估计,性虐待(从猥亵到强奸)影响了超过 1 . 2 亿儿童,这是受害者人数最多的一次。
*#Analyzing a specific crime-rape*
rape = d[d.crime_list.str.contains('RAPE OF CHILDREN')]
r=rape.drop(rape.index[[-1,-2,-10]])
r.plot(kind='bar',x='State/UT',y='count',color='blue')
图表显示,中央邦发生的强奸案最多。为了解决这个问题,该州通过了法律,对那些被判犯有强奸未成年人罪的人判处死刑,这在一个记录了最高数量的儿童强奸案的州是一个里程碑式的决定。
A tableau visualization of states and the total number of crimes. It shows that Uttar Pradesh has the highest number of crimes.
我们得到了北方邦目标的结果,绑架是最常发生的犯罪。
请随时分享您的反馈,以便我可以纠正错误。我开这个博客是为了分享我的工作和学习新事物。
你可以在我的 Github 个人资料中找到相同的代码。
谢谢大家!😃
参考资料:-
- https://www.unicef.org/protection/57929_58006.html
- https://www . PBC 2019 . org/protection-of-minors/child-虐待罪全球层面
- https://www . hindustantimes . com/India-news/man-lynched-诱拐-谣言-stir-panic-in-up/story-iefmqcfmtrd 5 uy 6 zbxfkuj . html
- https://qz . com/India/1333614/莫迪政府改善了印度妇女的生活吗/
象征性投票——痛苦的英国退出欧盟聚类分析
原文:https://towardsdatascience.com/indicative-votes-a0a60b2a5a94?source=collection_archive---------23-----------------------
你可能听说过英国退出欧盟。无论你的政治背景如何,人们普遍认为,它正以镇静的獾的果断和蹒跚的蜜糖的紧迫感前进。
最*有两轮象征性投票,允许议员们表达他们的观点,因此议会可以自信而文明地就最佳前进方式达成一致。
如果不是因为十二张指示性投票中没有一张通过,那就太好了。
那么,这到底是怎么回事?有没有任何关于议员、议会情绪或议员群体之间关系的信息,可以让我们从这令人恐惧的犹豫不决中梳理出来?
sendhelp
发生了什么事?!!
议会投票数据很容易从 CommonsVotes 网站下载。我使用 R 下载、绘制并大体上分解数据,看看会产生什么——你可以在这个 github 库中找到所有代码。
我们拥有的数据仅限于以下内容:对于每一次投票,我们都有每个议员的决定— 赞成、反对或无投票记录。就是这样。这不是很多,但需求必须…
如果我们将三种投票可能性形成为每张选票的情感得分 (aye = +1 ,no = -1 ,no vote = 0 ),并组合所有 12 张选票的数据,我们可以将每个议员放置在 12 维情感空间 中的某处。如果两个议员每次都以完全相同的方式投票,他们将在这个空间的同一点上,如果他们每次都投反对票,他们将截然相反。
然后,我们可以使用分区层次聚类来构建 MP 的层次结构,根据它们在这个情感空间中的接*程度。这允许我们绘制一个树状图。把这想象成一个生命树类型的东西,从最大的物种(所有议员)开始,分成所有不同的亚种和亚种,一直到议员个人。
我认为给三个最大的集群上色会很有用。严格地说,这些是任意的,但可以合理地认为是 保留? (那些大多在 Remainer 阵营的), 离开? (光谱中大多站在脱欧一边的那些),还有 ??? 为流动选民。
[click/tap the plot to see the interactive version…]
左边的热图显示了每位议员在每次投票中的投票方式——黄色代表赞成,蓝色代表反对,灰色代表没有投票记录。那还在吗?组在最上面:很容易看出,除了无交易(没有真正的惊喜)和或有优惠安排外,他们对赞成投了大多数票。有趣的是,相当一部分人离开了?阵营投票反对无交易 …
为什么是 HAPENNING?
树状图显示了复杂的关系层次,热图显示了所有议员如何投票。好极了:但是为了真正直观地了解议员之间的距离,以及是什么问题实际上将他们分开,我们需要将维度数量从 12 (有点笨拙)减少到更易于管理的程度。我们可以用主成分分析非常直接地做到这一点,它将数据分解成复合维度——其中每个维度都由所有 12 个原始维度的加权贡献组成。然后可以根据重要性(每个对总体方差的贡献)对这些进行排序,并且将前两个用于绘制二维图像(而不是 12 个!)
理论上,这应该把一个集群放在左边,另一个放在右边,第三个集群放在中间。让我想想…
Cluster Plot
所以,这里有几点需要注意。首先,看起来我们的三个集群确实被很好地分开了。三角形(▲)代表离开?和都在右边;圆圈(●)代表依然存在?在左边。
有趣的是,???集群(■)似乎更接*保持?比离开?。所以,也许他们更容易被留下来的人说服?阵营?
蓝色轮廓强调了空间中议员的密度。离开? (▲)具有相当密集和局部化的结构。值得注意的是,依然存在?这个群体有两个截然不同的分支——所以这个群体有两个明显的派别。
这是什么意思?展示由两个元维度组成的*面上的分离是非常迷人的,但是这两个维度到底代表什么?
现在这是什么意思?
从下图中我们可以看到,我们的两个复合维度解释了 MPs 之间大约 80%的差异。这很好——即使我们已经折叠了 12 个原始维度中的 10 个,我们仍然捕获了 80%的信息。
contribution of each PCA dimension to overall variance
尺寸 1
那么什么是我们最重要的维度(即聚类图的左右轴)?
Dimension 1’s ingredients
上面的图显示了每个投票对这个维度的贡献。红线代表贡献均匀时的预期值(即 100/12 = 8.33%);任何高于这条线的贡献都可以被认为是相当重要的。
这里的贡献大致相当分散。然而,有几票是等价的:这个维度的大约 40%是由 C 确定性公众投票和 C 习惯工会意见组成的。
让议员们沿着这条轴线走到一起,统一剩下的人?和离开?集群最需要在这两个问题上找到共同点。
尺寸 2
该维度表示聚类图中的垂直散点图。这个维度上的分离较少,但仍然存在明显的分裂?一分为二…
Dimension 2’s ingredients
从这个图中我们可以看到定义这个维度的最重要的问题是欧洲自由贸易区&欧洲经济区和共同市场 2.0。如果还在?就是要统一自己,这些才是要集中精力的事情。
现在怎么回事?
当我开始看这个的时候,这个国家正一头栽向悬崖边缘。现在,冲击的截止日期已经推到了万圣节 2019。
在那之前会发生什么?没人知道。我不确定是否还有人想让 T1 知道。如果有更多的指示性投票就好了,我们可以看到所有的集群都汇聚到一个辉煌的、最终的、有凝聚力的地方,每个人都很高兴。但是,说实话,我并不乐观。
这很复杂。简直是地狱。这是政治。
尽管如此,振作起来,嗯?你必须对这些事情有幽默感…
[注释等]
- 在计算情感空间的距离时,曼哈顿距离是最合适的度量吗?
- 与此相关的是,总体上情绪谱的概念可以说是不一致的,在内部(从赞成到反对的距离是否总是与从反对到反对的距离相同?)对外(一票赞成与另一票赞成是否相同?).**
- 请注意,聚类图上的点已经过抖动,以确保它们可见,并且不重叠。等高线图更接*地表示了所有点组的位置。
- 有相当多的议员(特别是内阁部长)在所有的指示性投票中没有记录的投票。
- 来自 Pixabay 的 Alexas_Fotos 精选图片;gif 从这里和这里。
- 维布尔。
印度尼西亚的贫困状况
原文:https://towardsdatascience.com/indonesias-poverty-profile-6f53b14def0f?source=collection_archive---------16-----------------------
探索 2013-2018 年印度尼西亚县级贫困数据
For Interactive (Tableau)
贫困问题一直是各种经济和社会论坛讨论的主要议题之一。贫困被认为是一个严重的问题,必须解决,因为它有很高的社会成本。贫困本身通常被定义为个人无法满足食物和清洁水等商品形式的基本需求以及教育和卫生等服务形式的基本需求。
从形式上看,满足这些基本需求的能力是以支出或个人收入来衡量的。在印度尼西亚,中央统计局(Badan Pusat Statistik)使用*均支出变量作为基准,分为基本粮食和非粮食需求。如果一个人的支出低于贫困线,他就被归类为穷人。
印度尼西亚的贫困线是根据人均每天相当于 2100 千卡的最低食物需求和最低住房、衣服、教育和健康需求的支出值之和计算的。2019 年 3 月,印度尼西亚的贫困线记录为人均 425,250 印尼盾/月(约人均 1 美元/天),食物构成为 73.66%。
For Interactive (Tableau)
根据这一名义贫困线,印度尼西亚的贫困人口比例为 9.41%,约为 2,514 万人,贫困人口主要集中在农村地区,尽管贫困率基准为 12.85%,而城市为 6.89%。总体而言,这些结果显示与上一年相比下降了 0.41 个百分点。
贫困人口数量和贫困率下降的趋势确实也发生在地球的其他地方。这一现象始于第二次世界大战结束和殖民实践。这一和*与独立时期为处于世界贫困地区的前殖民地国家提供了在本国进行变革的机会。然后,它导致更具包容性的经济增长,并最终减少贫困。
在印度尼西亚的背景下,值得注意的是,每个政府总是有一个专门针对减贫的主要方案,尽管它有不同的名称,如 Takesra、Kukesra、PKH、BPNT、BLSM、Raskin 等。然而,它通常以补贴或现金援助的形式提供。补贴或现金转移的接受者是根据当地政府的数据选择的,以确定接受者的资格。即便如此,仍有许多关于提供的计划目标不准确的报告。因此,贫穷数据的分类过程相当重要,因为它不仅着眼于持续下降的贫穷率的发展。
For interactive chart (Tableau)
分解到县一级
我将分解到县一级,因为只有县一级的数据可用。只有几个省有更具体的数据。即便如此,印尼中央统计局发布的数据通常也会滞后一年。上面的主图是 2013 年与 2018 年相比,2018 年 3 月所有县的贫困人口数量变化分布(两点年度数据)的初步说明。显然,爪哇几乎所有的县都成功地减少了贫困人口的数量。之所以会出现这种情况,是因为 Java 的贫困人口数量最多,所以在每一个扶贫项目中作为重中之重是合理的。此外,爪哇也是印尼的经济和政治中心
与此同时,如果我对这一时期贫困人口数量减少最多的县进行排名,Buton Regency 是这一类别中最好的县(在 494 个县中)。布顿县的地方政府应该为他们的辛勤工作获得奖励。干杯。
Github Gist
但是如果我把这些变化和人口增长做更详细的比较。Buton Regency 的成就不如以前辉煌,因为贫困人口数量大幅减少,随之而来的人口数量也大幅下降,分别为-65%和-62%。这也可以从人口指数的变化中得到证明,该指数仅变化了 1.58%,这意味着如果布顿县的人口全年保持不变,贫困人口只会减少 4113 人。所以基本上,在过去的五年里,布顿县的贫困人口数量只减少了 10%。因此,如果我只看到贫困人口数量的减少,我认为这是不够的。
如果把人口增长作为奖励的额外要求,我假定贫困人口对县人口增长有显著影响。结果,333 个县满足了这些额外要求,可悲的是,上图中前十五名中只有三个属于这一额外类别。因此,前三个县在这两个变量上的比率或 delta 不同,分别是 Tolikara 县、Tanatidung 县和 Gunung Sitoli 市。因为,尽管人口每年都在增长,他们还是设法减少了贫困人口的数量,这确实需要努力。
source: ekon.go.id
好了,现在我们来谈谈贫困线。我之前告诉过你,印尼名义上的贫困线大约是每人每天 1 美元。那么,供你参考,印度尼西亚的支出分布是正偏态的。因此,如果我将贫困线提高到 1.5 倍,印度尼西亚的贫困率将增加到 40%。换句话说,许多印尼中等收入阶层处于贫困易发状态。事实上,在这五年期间,有 143 个县的贫困人口数量增加,贫困线逐年提高。虽然*均来说全县人均收入有所增加。因此,县域经济增长并没有向贫困人口倾斜。
seaborn.boxplot(showfliers=False, …)
Three Main Poverty Index Graph (Github Gist)
年同比比较
人口指数只衡量贫困人口占总人口的比例。如果你想只关注贫困群体的消费分配,那么 P1 和 P2 是常用的。P1 用于计算贫困人口与贫困线的*均消费距离。与此同时,P2 计算了贫困人口的消费差异。这两个指数的值越高,越是不好的迹象。
上图以“x”为算术*均值,显示了所有观察县的三项指标情况。图表显示贫困率下降了,但是 P1 和 P2 相对停滞不前。直观上,这可以解释贫困项目很难帮助处于最低百分位数的穷人。另一方面,如果贫困计划被证明能够将接*贫困线的穷人推出贫困区,那么到目前为止,贫困计划可以说触及了几乎所有的穷人,因为*均而言,穷人的支出增加了。不过,我没有资料显示开支的增加是否只是名义上的,换言之,只是作为对通胀上升的补偿。我还找不到令人信服的答案。
2015 年和 2016 年的 P1 和 P2 指数引起了我的注意。很明显,当贫困人口比例下降时,P1 和 P2 指数实际上是上升的。那一年是佐科·维多多内阁政府的开始,并对目前的国家预算结构进行了重大改革。佐科·维多多政府削减了前政府用于基础设施项目的大量补贴。补贴的削减确实打击了穷人。虽然随后预算有所调整,尤其是临* 2019 年选举年。
结论
然而,在这十年中贫困人口数量下降的成就应该得到赞赏。这至少表明了政府在努力克服这一贫困问题方面的认真态度。然而,分配不*等的问题——无论是在社区经济阶层内部还是在县与县之间——仍然是一个大问题,几乎一半的印度尼西亚人口非常容易变穷。
为什么我总是在这个贫困问题上提到政府。因为政府是唯一有能力分享经济增长蛋糕的一方。穷人没有足够的资本和权力在社会中成长。谢谢你到目前为止阅读我的故事。我希望你们都能更多地了解印度尼西亚的贫困状况。在这个故事中,我只探讨了贫困数据集,没有过多涉及贫困与其他相关变量的关系。甚至我根本没有用花式模特。也许下次,我会试着写讨论。最诚挚的问候。
工业级数据科学
原文:https://towardsdatascience.com/industrial-grade-data-science-717c3b3a350b?source=collection_archive---------17-----------------------
Photo by NASA on Unsplash
管理数据科学很难。数据科学项目有很多失败的机会。此类项目的风险并不广为人知。原因是与软件开发相比,数据科学仍然是一个年轻的领域。在本帖中,我们将探讨数据科学项目的主要风险,并了解控制这些风险的方法。
探索普通数据科学项目的风险
Photo by Tobias Tullius on Unsplash
我们先来看看一个数据科学项目如何出现在一个普通的组织中。这一切都始于一些热衷者,他们可能是软件供应商或公司员工,看到了用数据科学改变世界和他周围的企业的方法。互联网上有很多成功的案例。他觉得他的公司也能从中受益,所以他建议公司管理层研究数据科学。管理层接受并要求内部 IT 或分析团队研究我们如何应用数据科学来改善我们的业务。团队开始在组织内部寻找大型数据源,一般会找到一个或几个好的数据库。然后,他们努力思考如何应用数据科学和机器学习来让他们的公司变得更好。大多数团队发现了某种可以应用机器学习算法的数据集,所以他们继续这项任务。最后,这类项目通常以下列方式结束:
- 企业不明白他们从新系统或算法中获得了什么好处。结果令公司管理层感到困惑。因此,他们指责数据科学团队在不必要的项目上花费了时间和金钱
- 系统投入生产。业务流程的 KPI(关键性能指标)在团队部署模型后突然下降。该公司的管理层非常愤怒,并将公司的损失归咎于数据科学团队
但是如何才能避免数据科学项目的失败呢?为了理解这一点,让我们深入了解数据科学项目的主要风险。
知识
任何数据科学项目的首要和主要风险是知识的可用性和传播。决策者通常缺乏数据科学方面的基本专业知识。这会导致过高的期望和不正确的问题陈述。人们开始谈论人工智能,以及它如何通过查看他们的数据库并在数据中发现新的利润来神奇地解决问题。
目标
缺乏关于数据科学和机器学习的知识会导致错误和模糊的问题陈述。事实上,以可解的形式解释问题是关键的一步。正确的问题是数据科学项目成功的 80%。原因在于数据科学使用科学的方法和研究过程来衡量结果。一般来说,数据科学家希望改进某种度量标准,一种衡量项目绩效的公式。模糊的目标定义导致数据科学团队方面的解决方案不正确。数据科学家大多是数据专家,不是商业顾问。企业应该与数据团队合作,创建一个值得投资的问题陈述。
在开始一个项目之前,确保你的想法是:
- 附属于业务
- 可以用一组指标来衡量
- 能够以可理解的方式呈现给业务部门
- 有相关数据。没有数据意味着你有一个数据收集项目,而不是数据科学项目
在讨论了战略风险之后,让我们求助于执行风险。
管理办法
项目经理经常求助于数据科学项目的软件开发管理方法。这似乎是一个好的开始:我们最终会开发软件。是的,内部深处可能有一个机器学习模型,但为什么它需要不同的管理方法?事实上,像敏捷这样的管理实践是管理数据科学项目的良好开端。但他们需要额外的调整和适应,以服务于数据科学项目的目的。
核心问题是敏捷,像许多管理方法一样,关注于处理外部范围的变化。例如,Scrum 以产品经理为中心,在项目 backlog 中填写所有请求的变更,这后来被系统化。在数据科学项目中,变化可能只出现在项目团队的外部,但也会出现在内部。例如,实验的结果可以改变项目中使用的建模技术的方法。这可能会导致内部软件架构不可避免的变化,以及整个系统的重大变化。您应该采用数据科学项目的管理方法来处理这种情况,因为它们很常见。特别是,考虑将项目分成两个集成的部分,每个部分都有独立的积压工作。研究子项目应该处理建模和数据预处理,而软件子项目应该包含端到端的解决方案,并集成研究子项目的结果。
任何数据科学项目的另一个有趣的方面是测试。在好的软件项目中,测试是过程中不可或缺的一部分。它从开发阶段开始,贯穿整个项目,直到生产部署。在数据科学项目中,测试更加突出。理想情况下,您应该在编写一行代码之前记录模型测试方法。这种测试方法是项目目标定义不可分割的一部分。没有评估项目效果的一组业务和技术指标,问题陈述是不完整的。
花式科技
数据科学、人工智能和机器学习都是时髦词汇,被新的有吸引力的技术包围着。另一方面,数据科学解决了各种各样的实际问题,这使得组织渴望在该领域进行投资。通常,技术专家是组织中第一个传播数据科学的人。在某些情况下,人们渴望尝试新技术和新算法,将问题陈述留到项目的后期。在这种情况下,数据科学将被商业专家贴上的标签,仅仅是技术人员的另一个玩具。
这种以技术为先整合数据科学的方法是有风险的。如果没有业务方面的支持和想法,即使是该领域最优秀的专家也会发现很难利用公司的数据推进公司的业务。数据科学和新项目想法的动机应该始终是一种协作努力,而不仅仅是技术上的。
队
数据科学项目通常看起来像研究项目。您需要测试新的、未经探索的方法和技术来解决业务问题。你需要一个团队来产生这个解决方案。仅从研究角度看待数据科学项目会让你创建以 R&D 为中心的团队。然而,许多组织忽略了开发生产就绪系统的必要性。实际上,围绕您的模型的数据工程和软件将占用项目总投资时间的 90%。这意味着你需要组建团队,这些团队已经准备好将原型开发成可靠的、高度可用的和生产就绪的软件解决方案。对于大多数企业来说,面向机器学习实际应用的跨职能团队比内部研究实验室更有价值,后者将推进最先进的方法,推动科学向前发展。为了控制这种风险,您应该考虑数据科学团队的目标,并调整您的招聘策略以与这些目标保持同步。
工装
另一个重要问题在于技术方面。数据科学项目通常被视为研究工作。然而,研究只是为任何商业问题提供解决方案的一部分。如果您希望您的团队高效可靠地实施项目,您需要从工程的角度来看待数据科学。ModelOps 是 DevOps 的*亲——一门围绕机器学习模型开发和部署研究工程流程的学科。如今,ModelOps 为您呈现数据版本化、构建可重用管道(【https://dvc.org】)、实验跟踪和模型部署(【http://mlflow.org】)以及快速项目设置()的工具。GitLab CI 等传统 CI/CD 工具也能给你的项目带来很大的好处,所以尽量考虑使用。为了控制这种风险,不仅要考虑模型的准确性,还要考虑模型的交付过程。
下一步去哪里?
如果你想了解更多关于数据科学项目管理和团队领导的知识,查阅我的书: 管理数据科学
它展示了对机器学习背后的主要概念的直观理解,并描述了用于以下目的的详细方法:
—管理数据科学项目
—组建数据科学团队
—将模型操作整合到您的开发流程中
利用 Kubeflow 实现人工智能和机器学习应用的产业化
原文:https://towardsdatascience.com/industrializing-ai-machine-learning-applications-with-kubeflow-5687bf56153f?source=collection_archive---------19-----------------------
全栈数据科学
使数据科学家能够制造可扩展和生产的 ML 产品
By Unsplash
背景
人工智能和人工智能应用的产业化主题*年来获得了极大的关注,例如著名的 Netflix 奖 以及在现实世界场景中实现获胜的 Kaggle 解决方案所面临的困难。这突出了 AI 和 ML 开发的两个主要方面之间的根本脱节:
构建 AI / ML 模型不同于缩放和维护它。一个是典型的数据科学问题,一个是典型的工程问题。
by gfycat
当谈到生产 AI & ML 算法时,需要从产品和人的角度来解决差距。
- 从产品角度来看,隐藏的技术债务可能来自不清楚或未分类的工程工作。值得注意的是,AI/ML 产品不仅包括 AI & ML 建模,还包括大量的开发工作和工程工作。
By Hidden Technical Debt in Machine Learning System
- 从人员的角度来看,数据科学团队缺乏开发人员和工程技能会带来挑战。在与数据科学家朋友的交谈中,很明显许多人不熟悉 CI/CD(持续集成&持续部署)、微服务、容器化、Kubernetes 等概念,有时甚至不熟悉 Git。
为了缩小差距
为了应对这些挑战,行业引入了新的角色,如 ML 工程师或 ML DevOps,旨在填补数据科学团队的知识缺口,或从他们那里接管生产任务。
此外,企业正在开发统一的 AI 和 ML *台,以自动化许多工程任务,并最大限度地减少数据科学家的工作量,如 H2O、DataRobot 和 SageMaker。
Kubeflow 在这个领域是一个相对较新的参与者,最*几个月已经获得了极大的关注。在本文中,我们将研究 Kubeflow 如何帮助解决人工智能和人工智能产业化中的一些核心挑战。
什么是库伯流?
我们的目标是尽可能简单地扩展机器学习(ML)模型并将其部署到生产中。
以上来自 Kubeflow 网站不言自明。它的主要目标是利用 Kubernetes (K8s)的力量使 ML 更具可伸缩性,并以微服务的方式运行。
为了支持数据科学工作流程的不同阶段,Kubeflow 集成了几个开源组件和工具,包括:
- Kubeflow Notebooks,为数据科学家提供 Python Jupyter 笔记本。
- Kubeflow 管道,它允许 ML 管道的编排。
- 整流罩,它简化了模型构建、训练和部署的过程。
- Katib,它在 Kubernetes 上提供超参数调优。
- 谢顿,负责模特上菜。
通过将这些工具结合到一个统一的*台中,并提供一个解决方案来解决可扩展性、部署和维护以及开发经验,Kubeflow 有潜力成为生产中 AI 和 ML 的领先*台。
可量测性
AI 和 ML 的进步导致了对处理大量数据的需求,这需要在数据科学过程的不同阶段进行大量的"测试&学习周期。这突出了*台可扩展性和构建可扩展 AI & ML 产品的效率之间的重要关系。
以前,数据科学家会访问内部服务器上具有数百 GB RAM 的虚拟机。虽然这提供了一个基本的解决方案,但它在每个虚拟机中可用 RAM 和内核的硬性上限方面有所限制。
后来,Hadoop YARN 和 Spark 的引入解决了可扩展性问题,并允许快速数据处理。然而,这些*台对于数据科学家来说不是用户友好的,并且缺乏对 ML 的支持。
最*,Kubernetes (K8s)的流行,这是一个基于容器的编排引擎,用于自动化容器化应用程序的部署、伸缩和管理,这导致了对其托管 ML 应用程序的适用性的探索。
Kubeflow 是一款基于 Tensorflow 和 Kubernetes 的 ML 解决方案,它在 K8s 上运行 ML 应用程序方面具有业内公认的优势,例如:
- 使用 CDR 和 TBJob 通过自动扩展和更简单的部署实现更好的弹性。
- 此外,Kubeflow 支持 python 工具,与以 java 为中心的 Hadoop 相比,数据科学家更容易使用它。
总之,与传统的 VMs 和 YARN 相比,Kubeflow 不仅提供了可扩展性,还为数据科学家提供了一个更加熟悉和可访问的环境。
部署和维护
我以前曾将生产中的模型视为一个黑盒,这是对 AI & ML 算法的普遍看法。为了将模型部署到生产环境中,它必须由 CICD 管道进行测试、自包含、版本控制和管理。这些任务对数据科学家来说可能不是最愉快的,也不是最有效地利用他们的技能。
然而,Kubeflow 认识到支持数据科学家的重要性。它为其管道提供了软件开发工具包(SDK ),使数据科学家能够基于 Python 中定义的管道创建预编译的 zip 文件,其中包含必要的 Dockerfile 和 YAML 文件。然后,可以将这个预编译的文件直接提交给 CICD 管道公司进行审查、测试,并最终部署到生产环境中。这大大减少了数据科学家的工作量,因为他们不再需要手动创建 YAML 文件,从而简化了整个 ML 部署流程。
如下图所示,数据科学家只需专注于黄色任务,而 Kubeflow Pipelines SDK 则负责从源代码库到容器注册表的其余流程。
By Kubeflow Community
通过将 Argo 集成为其管道工具,Kubeflow 简化了基于容器的 ML 管道的部署,使得以微服务方式测试、扩展和维护这些管道变得简单。
这不仅简化了 ML 工作流程,还为数据科学家提供了轻松版本化和测试模型的能力,从而增强了他们的体验:
- 容器化的 ML 模型的部署确保了每个模型或组件都是自包含的,并且包含了所有必要的依赖,使得它们可移植和可测试。
- *台的健壮性得到了提高,因为任何团队成员都可以轻松识别和解决部署模型的问题,而不需要深入了解*台的架构。
- 在生命周期管理方面,数据科学家能够通过部署新版本来更新现有模型,使用新发布的容器进行 A/B 测试,或者根据需要淘汰容器。
- ML 模型和服务生命周期的清晰性增强了数据治理和风险管理,因为可以在容器级别管理机密,以确保对数据资产和资源的安全访问。
下图是一个端到端 XBoost 模型的 Kubeflow 管道示例,其中每个盒子代表一个由 Python SDK 生成的容器。
多用户隔离
多用户隔离是一个至关重要的方面,尤其是在拥有多个团队和产品流的组织中。这有助于避免不同团队的数据科学家之间的干扰,并改善他们的开发体验。为了解决这个需求,Kubeflow 利用 Kubernetes 资源配额,允许基于名称空间管理资源。这确保了每个团队都可以访问必要的资源,并消除了意外冲突的风险。
在当前版本(v0.6)中,这仅适用于笔记本电脑。
By Kubeflow Community
监视
Kubeflow 通过使用 Prometheus 提供监控功能,能够监控每个 pod/worker 的 GPU、CPU、网络和 RAM 使用情况。这一特性不仅满足了 DevOps 的需求,还为数据科学家提供了宝贵的见解。
通过监控生产中的资源利用率,数据科学家可以优化管道计划和依赖关系,识别模型中的瓶颈,并在*衡模型培训成本和性能方面做出明智的决策。这有助于数据科学家更有效地工作,并关注成本效益。
开放源码
最后但同样重要的是,Kubeflow 的开源特性是其关键优势之一。虽然特定于供应商的解决方案和开源解决方案都有其优势,但我认为敏捷性和灵活性是要考虑的主要因素。对于任何规模的组织,无论是大型多云实体还是中小型创业公司,开源解决方案都提供了必要的适应性,可以随着时间的推移调整和发展他们的 AI & ML 基础设施。
无论你在哪里运行 Kubernetes,你都应该能够运行 Kubeflow。
此外,Kubeflow 社区非常活跃,致力于不断发布新功能,定期举行产品设计会议,并根据反馈迭代其路线图。
Commits over time — by Kubeflow Github
全部的
Kubeflow 已经成为人工智能和人工智能产业化领域的一个有前途的解决方案,提供了一系列好处来帮助组织在其数据科学项目中取得成功。
然而,值得注意的是,Kubeflow 目前正在进行重大开发,并且尚未考虑企业就绪。
- 社区在最*的版本中做了一些重大的改变,比如从 Ambassador 到 Istio 作为服务网格,从 ksonnet 到 kustomize 作为部署模板。这些更改可能会影响与旧版本 Kubeflow 的兼容性。
- 此外,在预计于 2020 年 1 月发布 1.0 版之前,多租户和用户隔离等关键功能已经不再重要。对于组织来说,在实现 Kubeflow 时,仔细评估他们的需求并牢记这些考虑因素是很重要的。
下一步是什么
在这篇文章中,重点主要是从运营和团队的角度来看 Kubeflow 在 AI & ML 产品产业化方面的优势。
展望未来,探索 Kubeflow 为个体数据科学家提供的优势将会非常有趣。这包括使他们能够使用 JupyterHub、Katib 和 Seldon 等工具开发端到端的 AI & ML 模型。
工业 4.0:向知识型企业演进
原文:https://towardsdatascience.com/industry-4-0-evolution-to-knowledge-based-enterprises-a0bda1b9a5f6?source=collection_archive---------19-----------------------
Photo by Franck V. on Unsplash
自柏拉图和亚里士多德时代以来,认识论即“知识论”一直是一个哲学话题。正是这种对知识的理论、认知和实践,在过去的 2000 年里极大地促进了人类的进化。
在许多方面,哲学也延伸到组织知识或企业认识论。信息爆炸、技术成本下降、人工智能兴起、人才全球化、快速创新周期和资本市场经济正在重塑金融和知识资本在企业中的作用。资本主义时代早期的经营业绩显著依赖于资本效率(结合其他因素);然而,现在可以说,在(所谓的)工业 4.0 中,赢家和输家将受到“知识效率”(也就是使用中的知识)的驱动。事实上,越来越多的证据表明,2017 年美国最受赞赏的知识企业(MAKE)的获奖者的*均收入回报率(RoR)是财富 500 强 RoR 公司中位数的 2.85 倍,资产回报率(RoA)是财富 500 强 RoA 公司中位数的 2.7 倍。
那么,这对未来的任何企业意味着什么呢?—企业需要将自己视为知识的系统,为利益相关者有效地开发、培育、转化和使用知识。成功转型为知识型企业的企业将最有能力在人工智能时代取得成功,并对社会产生积极影响。虽然这不是一个新概念(1994 年的一篇 HBR 文章谈到了知识型企业及其特征),但许多企业并没有清楚地解释这一点,而是专注于数字化、人工智能& ML、自动化,而不是全面知识转化(本质上,更关注如何与为什么)。**
对于总体知识转化,企业在最概念性的层面上需要关注三个领域:**
定义知识的目的
创造符合目的的知识
通过知识管理为员工赋权
重点领域 I:为企业定义知识的目的
挑战:信息越多,理解越少
可能的解决方案:任务绩效价值知识评估
今天,我们生活在一个信息高度密集的环境中。然而,对于企业来说,并不是所有形式的信息和知识都是相关的。在最高层,知识的目的应该来源于(或理解于)公司/部门的核心理念/使命。例如,MAKE awards 的获奖者(以及领先的知识公司)有以下使命陈述(图 1):
Image 1: Mission Statement of 3 MAKE Award Winners
虽然这些使命陈述可能故意说得很宽泛,但它们确实提供了公司计划如何利用知识的洞察力。
这个“任务目的”可以映射到关键绩效知识资产。I-Space 研究所的知识地图就是这样一个绘图框架。地图的主要概念包含两个维度:知识结构(非结构化到结构化)和扩散(非扩散到扩散,即知识的传播程度)。这一框架使公司能够相对于市场绩效驱动因素来评估他们的知识资产。
最后一步是将知识资产映射到价值创造。价值创造是一个复杂的话题,涉及到复杂的变量,但是,如果一个企业明白了在经济和社会中所扮演的角色,他们就可以定义知识的价值。Tom Trost 在他的书《基于价值的知识策略》中,通过价值控制图提供了一个非常简单的观点。
他解释说,在绩效上竞争的企业(价值创造者和塑造者)成功地利用知识专注于五个能力领域:
重点领域二——创造符合目的的知识
挑战:信息多,信任少&行动
解决方案:实现知识创造和测量实践
知识创造和管理需要着重强调 1)了解你现有的隐性和显性知识资产 2)将知识从一种形式转换为另一种形式,以扩大知识总量。
信息空间研究所的知识地图也可用于绘制隐性和显性功能知识资产。
功能知识能力的映射提供了一个关于如何进一步培养它们的行动计划(您应该进一步构建某个知识能力还是进一步传播它们,以及它如何帮助企业)。
为了将知识转化为扩大总知识的更广泛目标,野中郁次郎关于知识创造公司的理论(21 世纪初)可能是最相关的。在他的 HBR 文章中,他解释说,在不断变化的市场环境中,成功的企业是那些不断创造新知识,在整个组织中广泛传播,并迅速体现在新技术和新产品中的企业。这些活动定义了“创造知识”的公司,其唯一的业务是持续创新。他开发了一个简单的知识转换框架,叫做 SECI 螺旋:**
该框架强调,知识是通过显性和隐性知识的社会互动创造和扩展的。随着编码、通信、设计和技术模式的飞速发展,这可能是当今企业面临的最大机遇。
为员工提供知识管理
挑战:信息太多,时间太少&创意
解决方案:使信息民主化,利用知识
在过去的几十年里,知识监管已经从低技术的监管发展到现在的高技术的监管。据估计,全球有 2.3 亿知识型员工(如果你扩大知识型企业中策展人的定义,这个数字会翻很多倍)。在工业 4.0 中,知识的管理将在许多层面上得到释放,并由云和人工智能提供动力。那么,每个知识工作者如何在这种新环境中策划呢?在一个简单的框架中,知识监管区将被夹在两个技术层之间(使能信息技术和分发/工作流技术)。这在今天已经是事实,在某种程度上也是如此,但是还没有完全实现。
由人工智能和分析技术支持的更加互联、更具凝聚力的企业信息系统将把重点从生产任务转移到创造任务,并实现整个组织的无缝传播。当然,只有组织中的每个人都很好地理解了知识目的和创造原则,策展区才会成功。
向知识型企业的发展始于 20 多年前。然而,现在看来,随着企业认识到它的潜在价值,它的发展势头和可伸缩性将会大大提高!
感染建模—第 1 部分
原文:https://towardsdatascience.com/infection-modeling-part-1-87e74645568a?source=collection_archive---------9-----------------------
通过蒙特卡罗模拟估计病原体的影响
一句警告:本系列中提出的一些观点可能不道德。关于隐私、个人自主、*等、‘更大的利益’、和医源性的争论肯定会出现。但是,忽略所有这些会成为系统建模和优化的一个有趣例子。因此,为了我们自己的娱乐,我们将回避道德对话(因为这些概念可以很容易地应用于其他缺乏这种道德灰色地带的领域)。
社交网络通常被认为是在线社交媒体的同义词,但它们也存在于现实世界中:我们的朋友群体、同事、家人、杂货店购物者等。分析这些真实世界的社交网络对于选举策略、零售客户细分,或者我们将在这里看到的流行病学,都是有价值的。
在这项工作中,我们将着眼于一个经常使用的,简化的,流行病模型,并显示它如何可以应用到一个特定的社会网络与蒙特卡罗模拟相结合,以估计病原体的影响。后面的部分将讨论最优化、系统动力学,以及(重要的是)对所有过度简化、笼统概括和不能全信的事物的回顾。
SIR 流行病模型
流行病的定量模型有几种形式,尽管它们都处理属于这些群体的部分人口:易感(S)-无免疫能力并能够感染病原体,暴露(E)-与病原体接触过,感染(I)-当前感染病原体,以及脱离(R)-对病原体免疫(通过疫苗或暴露后)或死亡。在这项工作中,我们将重点放在 SIR 模型,其中的人口成员要么是易感,感染,或删除。
SIR 模型由(1)中的微分方程控制。β是病原体的感染率,γ是恢复率。这两个值一起给出了基本繁殖数 R0: 由被感染宿主引起的二次感染的*均数量。
Equation 1: SIR model differential equations. x(t) is the fraction of the population infected, s(t) is the fraction of the population susceptible, r(t) is the fraction of the population removed (recovered and/or immune, or worse, dead). Beta is the infection rate, and gamma is the recovery rate.
如果 R0 值大于 1,则感染率大于恢复率,因此感染将在整个群体中增长(如图 1 所示)。如果 R0 小于 1,传染病会很快消失,因为人们愈合的速度比传播的速度快。
Figure 1: Typical SIR model applied to populations. gamma=0.17, beta=0.23, initial infected fraction=0.01
SIR 模型的网络方法
上述 SIR 模型是一个强有力的工具,但它针对的是抽象的“群体”。如果你有更多关于社区互动的信息呢?手机和可穿戴技术的普及使得追踪运动和互动变得更加可行。有可能建立一个当地人口的社会网络,并根据这一网络对过程进行建模。在高度关注流行病的情况下,公共卫生官员可以通过网络模拟感染的传播,以更好地了解预期的结果并做好准备。这里介绍的方法与刘等人在 2018 论文中的方法类似。
感染模拟从初始化为受感染的 n 个节点开始,以将病原体引入网络。在每个时间步,受感染的节点有百分之 p 的机会感染它们的邻居,随着每个时间步 p 衰减,以说明个体在意识到他们生病时变得更加小心。在 r 时间步之后,一个被感染的节点被从网络中移除,这意味着恢复和感染后免疫,或者死亡,这取决于被建模的病原体和/或建模者的乐观程度。
与基于人口的 SIR 模型不同,这是一个通过蒙特卡罗模拟进行建模的随机过程:使用不同的输入参数进行重复模拟,以生成可能结果的分布,而不是生成单一的确定性结果。也就是说, p 和 r 是从每个节点的概率分布中产生的,导致每次模拟的不同结果。
构建感染模拟
作为一个例子,我们将使用一个 62 节点的社交网络,它是由一群海豚的互动构成的。让我们以一种感染为例,其*均恢复时间 r 为 30 天(标准偏差为 8 天),*均传播概率 p 为 6%(标准偏差为 1%),在一个节点的感染中每天衰减 10%。让我们进一步假设随机选择的两个节点( n =2)是网络中的感染源。
按照上述建模过程,重复 1000 次,得到*均 SIR 响应,如图 2 的上图所示。疫情期间感染节点总数的概率密度函数如下图所示。
Figure 2: (above) averaged predictions of fraction of the population susceptible, infected, and removed. (below) PDF of the total number of nodes infected during the outbreak. The time span of the simulation is 150 days.
蒙特卡洛模拟的*均 SIR 反应相当惊人,有* 80%的人口在某一时刻被感染。最终“删除”数字的 PDF 显示了它在 1000 个模拟中的分布情况。从图 3 中可以看出,它大致符合偏态正态分布,感染节点的*均总数为 50(标准偏差为 3.5)。
Figure 3: PDF of total infected nodes roughly fits to a skewed normal distribution
最坏的情况是 62 个节点中有 59 个被感染。但就尾部事件而言,在模拟结果中,影响较小的异常值似乎比影响较大的异常值更普遍。
求解(1)中β和γ的 SIR 微分方程得到下面(2)中所示的方程。随着 t 的增加,β和γ收敛到各自的值。
Equation 2: Solving SIR equations from (1) for beta and gamma
利用蒙特卡罗模拟结果计算出的β和γ,我们可以计算每个模拟的 R0 值,以了解这种病原体在当地人群中的感染情况。模拟计算的 R0 值的 PDF 如下图 4 所示。
Figure 4: Probability distribution of R0 calculated from Monte Carlo simulations
蒙特卡洛模拟显示,网络中这种病原体的 R0 值最有可能在 2 到 3 之间,与 1918 年 H1N1 流感的值相当。虽然在一些模拟中观察到更接* 5 的 R0 值,但是在左尾的 R0 值更普遍,这表明如果公共卫生官员在创建响应计划时假定“最有可能” R0 值,他们更有可能(尽管不能保证)准备过度而不是准备不足。
在下一篇文章中,我们将探讨如何使用这种建模方法来解释疫苗接种的影响。此外,我们将尝试优化疫苗接种策略,以尽量减少病原体在这个网络中的影响。
感染建模—第 2 部分
原文:https://towardsdatascience.com/infection-modeling-part-2-5d3f394355f?source=collection_archive---------27-----------------------
用遗传算法优化疫苗接种策略
在第一部分中,我们模拟了传染性病原体通过社交网络的传播。蒙特卡洛模拟允许计算基本再生数 R0 的概率分布。在实践中,公共卫生官员将试图制定一项计划,通过接种疫苗或隔离来降低影响。根据定义, R0 是疾病爆发的内在属性,一旦计算出来就不会改变,因为它是在假设完全易感人群的情况下计算的。有效繁殖数, R ,代表可能包含免疫成员的群体中继发感染的*均数量。这是希望通过疫苗接种运动最小化的度量。
Figure 1. PDF of calculated R0 value from the Monte Carlo simulations of the epidemic from part 1.
第 1 部分显示,对于我们的示例网络和病原体, R0 预计在 2 和 3 之间,如图 1 中蒙特卡洛模拟结果的分布所示。在本文和下一篇文章中,我们将对网络中的疫苗接种效果进行建模。具体来说,我们将研究疫苗供应短缺的情况,并试图回答一个问题:鉴于只有 25%的成员可以接种疫苗,我们如何才能最好地保护人口?
在 62 个节点的网络中,只有 15 个将在用与第一部分相同的方法模拟病原体传播之前接种疫苗(从而从网络中移除)。然后将计算得到的(*均) R 值,以确定该疫苗接种策略的有效性。目标是将 R 降低到 1 以下,这表明病原体的传播速度可能比感染者的恢复速度慢。
遗传算法优化
确定接种疫苗的最佳节点可以通过强力组合搜索来完成,尽管这将需要相当长的时间(在这种情况下,需要检查 93 x 10 个组合)。遗传算法是一种受生物启发的搜索算法,它通过模仿自然选择来缩小搜索空间。许多候选解(也称为染色体)以与它们在目标函数上的表现成比例的概率加入交配池。交配池产生的后代具有特定的突变机会,然后根据目标函数进行评估,重新开始进化过程。
在这种情况下,GA 被编程为使用 20 个候选解的群体来最小化网络中病原体的 R 值。图 2 显示了候选解在 20 次迭代中的演变。
Figure 2. Evolution of R for the GA population. The mating pool is formed with the tournament method. Instead of assigning a fixed probability of mutation, mutation occurs when crossover results in duplication.
在 GA 例程完成之后,通过对节点 0、7、8、9、10、13、17、19、21、25、29、30、38、43 和 49 进行接种,最佳策略导致*均大约 0.98 的 R 。实施该策略的蒙特卡罗模拟结果如下图 3 所示。
Figure 3. Monte Carlo simulation results for the optimal policy found via GA. Averaged SIR response (upper). Distribution of total infected nodes (lower).
受感染节点的*均数量约为总人口的 27%(13 个节点),尽管该数量大致均匀分布在 3-15 个节点之间,此时可能性开始下降。
R 的概率分布如下图 4 所示,大致符合正态分布。用这种疫苗接种策略获得的 R 的值最有可能在 0.68 和 1.36 之间。
Figure 4. PDF of calculated R values fit to normal distribution.
结论
实施 GA 来减少病原体对网络的影响是成功的。20 次反复后,最佳疫苗接种政策导致预期传染性下降 32%至 77%。然而,预期的 R 的上限仍然高于 1,考虑到我们的目标是将 R 移动到尽可能低于 1,这是不期望的。
此外,对蒙特卡罗模拟执行遗传算法优化是昂贵的。使用 20 条染色体、20 次 GA 迭代以及每次蒙特卡罗模拟 1000 次模拟,总共计算了 400,000 次模拟。我的机器花了 48 个多小时才完成。记住,这个例子使用了一个 62 节点的小型社交网络。在更大范围内,需要一个规模适当的集群,以便及时取得成果。
第 3 部分将说明网络科学工具如何比 GA 优化更快(更好)地执行这种优化。
感染建模—第 3 部分
原文:https://towardsdatascience.com/infection-modeling-part-3-93ef315edae1?source=collection_archive---------22-----------------------
用网络科学优化疫苗接种策略
在本系列的第一部分中,我们模拟了病原体通过社交网络的传播,并确定 2-3 之间的 R0 是最有可能的,大约 80%的网络在某一点被感染。在第 2 部分中,我们使用遗传算法(GA)来确定一种疫苗接种策略,以最大限度地减少感染的传播,假设只有 25%的人口可以接种疫苗。由此产生的策略将可能的 R 的范围降低到 0.68–1.36,但是计算成本很高。在本文中,我们将了解如何利用网络分析来减少病原体的传播,同时提高计算效率。
确定关键节点
优化疫苗接种政策包括识别社会网络中最有影响力或最重要的节点。并且确定网络中节点的相对重要性是通过中心性度量来完成的。最简单的中心性是度中心性,也就是节点的度。特征向量中心性通过节点的邻居来衡量节点的重要性。这一点的直觉是,一个节点仅仅通过连接到其他重要节点就可以变得重要。节点的介数中心性是通过该节点的所有测地线的分数。
将选择由这些中心性中的每一个排列的前 15 个节点进行接种。使用第 2 部分中的策略对疫苗接种策略进行相互比较,以确定哪种中心性措施最适合限制感染的传播。
通过特征向量中心性接种疫苗
通过特征向量中心性对节点进行排序导致与高度节点相邻的节点的排序高于仅考虑程度时的排序。有时,低度节点在网络中的影响可能比仅由度中心性所暗示的更大。
Figure 1. PDF of R resulting from a vaccination strategy based on eigenvector centrality.
然而,基于特征向量中心性的疫苗接种导致不良结果,如图 1 所示。可能的范围 R 估计在 0.98 和 1.84 之间;比遗传算法优化的结果差。强连接的节点集群往往具有相似的特征向量中心性,并且在排序时可能彼此相邻。当选择前 25%的节点进行接种时,很可能这些节点中的许多是相同节点集群的一部分,从而使其他集群更易受到攻击。本质上,我们选择重要的节点进行接种,因为它们与重要的节点相邻,而其他结构上重要的节点不接种;因此性能相对较差。
通过中间中心性接种疫苗
基于介数中心性给节点接种疫苗是有吸引力的,因为节点之间的距离有加长的趋势。具有高介数的节点充当几对节点之间的中介。移除这样的节点意味着病原体将需要穿过更多的节点才能从点 A 到达点 b。总体而言,通过介数中心性移除排名最高的节点将降低网络的整体连通性,这将使病原体更难传播。
Figure 2. PDF of R resulting from a vaccination strategy based on betweenness centrality.
基于介数中心性移除节点被证明比 GA 策略稍微更有效。可能的范围 R 估计在 0.45 和 1.33 之间。请注意,与之前的结果相比,图 2 中的高斯分布不太能代表实测分布。相对于*均值,左尾值在模拟中更普遍。
通过程度中心性接种疫苗
基于节点的度中心性给节点接种疫苗是有吸引力的,因为具有最高度的节点在整个网络中具有最大范围。与介数中心性一样,删除高度节点会降低网络的连通性。
Figure 3. PDF of R resulting from a vaccination strategy based on degree centrality.
Figure 4. Histogram of the number of total infected nodes resulting from each vaccination strategy.
如图 3 所示,当使用拟合的正态分布时,期望的 R 在 0.36 和 1.01 之间。然而,很明显,正态分布并不能很好地代表数据。在蒙特卡罗模拟中,0 到 0.125 之间的 r 几乎是任何其他箱的两倍。
查看每种疫苗接种策略产生的感染节点总数的直方图(图 4),我们可以看到分布似乎更接*指数或幂分布。通过程度中心性接种疫苗导致最好的结果。大概吧。
结论
基于中间中心性和程度中心性的疫苗接种策略导致预期的 R 小于 1,表明这些策略中的一个将最适合于最小化病原体的影响。而通过特征向量中心性接种疫苗导致比遗传算法确定的策略更差的结果。这并不是说 GA 找不到最优策略;只是这可能需要更长的时间。在第 2 部分中,我们看到花了 48 小时才收敛到给定的策略。根据特征向量中心性、中间中心性和度中心性选择最重要的节点分别花费了 625 微秒、3.44 毫秒和 113 微秒。在这种情况下,与全局搜索算法相比,网络科学的工具可以带来更高的性能和更快的结果。
图形数据库中的推理
原文:https://towardsdatascience.com/inference-in-graph-database-7203938932a0?source=collection_archive---------12-----------------------
在这篇博文中,我将尝试解释语义网上的推理是什么,并展示如何在本地图数据库中应用推理。我的博客的大纲如下:
- 什么是推论?
- 是用来做什么的?
- 程序的类型
- 图形数据库和本体
- 数据库推理
- 结论
什么是推论?
如 W3 标准所述,推理是基于给定的本体在图中简单地发现新的边。在语义网上,数据被建模为三元组,即两个资源和它们之间的一个关系。推断是根据数据和一些附加信息推断新的三元组,这些信息可能是词汇表(本体)和规则集(逻辑)的形式。例如,假设我们有两个来源:约翰人类和马克斯狗,并且我们有信息表明约翰 拥有 马克斯和马克斯 是 狗。此外,如果我们有一个额外的词汇,其中包括信息;狗 是 哺乳动物。我们可以推断得出 Max 是 哺乳动物而 John 有 哺乳动物。
是用来做什么的?
语义网上的推理用于提高网上数据集成的质量。它自动提供数据中的新链接并分析内容。同样,它也检查网络上数据的一致性。例如,假设我们有包含信息朵拉 是 奶牛和朵拉 是 食肉动物的数据。如果我们检查动物的本体论,这与牛是素食者是不一致的。
程序的类型
如上所述,新链接的自动发现是通过使用词汇表或规则集来完成的。在语义网上,词汇或本体可以用 OWL、SKOS 和 RDF 描述,而规则集用 RIF 描述。这些技术是 W3C 基金会推荐的。此外,本体基于类和子类关系,然而,规则集描述一般规则以基于现有关系生成新关系。
图形数据库和本体
由于数据库领域新的便捷技术,我们能够将数据存储为图表。尤其是图形数据库。有这样一个强大的工具是非常好的。更好的是,我们可以通过包含通用词汇、本体🚀
在我之前的博文中,我描述了如何通过使用名为 NSMNTX — Neo4j RDF &语义工具包的插件将本体导入 Neo4j 数据库。请在继续之前先阅读博客文章。
[## 标签属性图与 RDF 的比较
在这篇博客中,我将简单解释一下什么是标签属性图,有什么区别和相似之处…
medium.com](https://medium.com/@atakanguney94/a-comparison-of-label-property-graph-and-the-rdf-cd94d2943d53)
数据库上的推理
除了导入数据库之外,现在我们还要对其进行推理。您可能还记得上一篇文章,我们可以从外部在线商店导入本体。但是为了简单起见,在这篇博文中,我们将自己创建我们的动物世界本体。让我们开始吧😅
CREATE (a: AnimalType{authoritativeLabel: "Mammals", dbLabel: "Mammals"})
CREATE (b: AnimalType{authoritativeLabel: "Dog", dbLabel: "Dog"})
CREATE (c: AnimalType{authoritativeLabel: "Cat", dbLabel: "Cat"})
CREATE (d: AnimalType{authoritativeLabel: "Horse", dbLabel: "Horse"})
CREATE (a)<-[:IS_A]-(b)
CREATE (a)<-[:IS_A]-(c)
CREATE (a)<-[:IS_A]-(d)
这将产生一些 AnimalType 类型的节点,它们之间有关系。让我们看看。
这个动物模型告诉我们动物之间的关系。所以,现在创建一些被认为是宠物的动物实例。
CREATE (:Pet:Dog{name: "Max"})
CREATE (:Pet:Cat{name: "Missy"})
CREATE (:Pet:Horse{name: "DulDul"})
这将会产生
我们的第一个推论是所有的哺乳动物。因此,如您所见,我们的数据只包含三个不同的节点。
CALL semantics.inference.nodesLabelled('Mammals', { catNameProp: "dbLabel", catLabel: "AnimalType", subCatRel: "IS_A" }) YIELD node
RETURN node.name as name, labels(node) as categories
这将会回来
因此,在我们的数据库中没有任何关系的情况下,我们通过使用我们的词汇来推断公共标签关系。
现在,让我们添加一些关系。
MATCH (c:Cat{name: "Missy"})
MATCH (d:Dog{name: "Max"})
MATCH (h:Horse{name: "DulDul"})
CREATE(jn: Person{name: "John"})
CREATE(al: Person{name: "Alex"})
CREATE (jn)-[:LOVES]->(d)
CREATE (h)-[:LOVES]->(d)
CREATE (al)-[:LOVES]->(c)
这将导致
作为第二种推论,让我们试着让所有的动物爱好者❤️
MATCH (p)-[:LOVES]->(pt)
WHERE semantics.inference.hasLabel(pt,'Mammals', { catNameProp: "dbLabel", catLabel: "AnimalType", subCatRel: "IS_A" })
RETURN p.name as name
结果来了…
现在,让我们对词汇本身进行推理。在此之前,让我们稍微扩展一下
MATCH (h:AnimalType{authoritativeLabel: "Horse"})
MATCH (d:AnimalType{authoritativeLabel: "Dog"})
MATCH (c:AnimalType{authoritativeLabel: "Cat"})CREATE (:Film {title: "A Dog's Journey"})-[:HAS_SUBJECT]->(d)
CREATE (:Film {title: "Cats"})-[:HAS_SUBJECT]->(c)
CREATE (:Film {title: "The Mustang"})-[:HAS_SUBJECT]->(h)
想象一下
我们添加了一些以动物为主题的电影。我们的下一个推理类型是类别推理类型中的节点。让我们试着得到所有以哺乳动物为主题的电影
MATCH (cat:AnimalType { authoritativeLabel: "Mammals"})
CALL semantics.inference.nodesInCategory(cat, { inCatRel: "HAS_SUBJECT", subCatRel: "IS_A"}) yield node
return node.title as film
还有…
我们得到了我们想要的😈
现在,让我们看看最后一种推理类型。我们的数据再次发生。但在此之前,让我们定义一下不同于哺乳动物的其他动物类型:鱼和鲨鱼。同样,我们再加一个 IS_A 关系。
CREATE (f:AnimalType{authoritativeLabel: "Fish", dbLabel: "Fish"})
CREATE (sh:AnimalType{authoritativeLabel: "Shark", dbLabel: "Shark"})CREATE (f)<-[:IS_A]-(sh)
创作一部关于鲨鱼的电影
MATCH (s: AnimalType{authoritativeLabel: "Shark"})CREATE (:Film {title: "Frenzen"})-[:HAS_SUBJECT]->(s)
我们最终的词汇表将如下所示
现在将新信息添加到我们的数据中
MERGE (p:Person { name : "John"}) with p
MATCH (film1:Film { title : "Cats" })
MATCH (film2:Film { title : "Frenzen" })
WITH p, film1, film2
CREATE (film1)<-[:LIKES]-(p)-[:LIKES]->(film2)
在我们的图形数据库中查看相应的数据
所以,我们的人约翰既喜欢猫也喜欢法语。让我们问一下约翰喜欢的电影中哪一部有关于鱼的主题。
MATCH (fish:AnimalType { authoritativeLabel: "Fish"})
MATCH (:Person { name : "John"})-[:LIKES]->(b:Film)
WHERE semantics.inference.inCategory(b,fish,{ inCatRel: "HAS_SUBJECT", subCatRel: "IS_A"})
RETURN b.title as title
是的,我们有结果了💪
结论
最*,NoSQL 数据库而不是关系数据库吸引了人们的注意力。在各种各样的 NoSQL 数据库中,基于图的数据库越来越受到人们的关注。依我拙见,将外部信息包含到图形数据库中,并对其进行管理、分析和校对,将是很有价值的。导入本体是一种很好的简洁的方法。我希望你喜欢这个博客。更多有趣的工具,敬请关注🚀
参考文献
- https://www.w3.org/standards/semanticweb/inference
- https://neo4j.com/docs/labs/nsmntx/current/inference/
边缘推理
原文:https://towardsdatascience.com/inference-on-the-edge-21234ea7633?source=collection_archive---------11-----------------------
用 Tensorflow 为树莓 Pi 构建深度神经网络
从云计算到雾计算
虽然机器学习推理模型已经在改变我们所知的计算,但严峻的事实是,使用多个庞大的数据集来训练它们仍然需要大量的处理能力。使用一个训练好的模型来预测一个事件需要少得多,但仍然比我们目前的口袋设备所能处理的要多。用深度神经网络处理图像意味着数十亿次运算——对多维度的巨大矩阵进行乘法、求逆、整形和傅立叶变换。
鉴于 ML 的潜力,包括英特尔、英伟达和谷歌在内的 60 多家公司正在设计能够以更快的速度执行这些操作的芯片也就不足为奇了。利用这项技术,即使是一个树莓 Pi 也只需要几毫秒就可以通过深度神经网络并产生一个推断(本质上是一个预测)。这些芯片的机会是多方面的,它们越来越多地被部署在许多设备中,如相机和无人机。举例来说,你可以在你的 DJI 无人驾驶飞机上找到无数来自英特尔 Movidius 的芯片,或者,很快,在欧洲航天局的卫星上就可以进行在轨图像处理
像你们许多人一样,我对机器学习充满热情,并渴望测试推动第四次工业革命的技术。所以当谷歌公开发布两款加速推理的新产品时,我就跳上了马车。我特别渴望了解使用这些设备运行深度神经网络需要什么。
在接下来的内容中,我将向您展示我在 Tensorflow 中创建深度神经网络的尝试,将该模型移植到 Raspberry Pi 上,并使用外部设备进行推理以提高性能。我用英特尔和谷歌这两家领先公司的芯片做了这个实验。
我的目标只是评估这两种环境,并了解使用这些设备所需的知识深度。目标不是找出模型、损失、指标和架构方面的最佳性能。人们可以很容易地想象改进我所做的许多方面。
项目的所有代码片段都可以在我的 github 库中找到。
让我们开始吧!
设置和目标
计划是用 Tensorflow 设计一个新鲜的卷积神经网络。由于这些芯片处理整数或半精度浮点运算速度更快,我们将构建一个运行在低精度数据类型上的模型。为此,我们将为我们的模型运行一个量化感知训练。然后,我们将冻结图形,将其编译成两个加速器支持的不同表示形式。最后,我们将在边缘上尝试我们的模型。
你可能会问:既然已经存在大量优秀的预训练模型,为什么还要建立一个新模型?
好问题。有许多可用的模型在巨大的数据集上进行了预训练,其中一些甚至是为我们想要使用的设备编译的。使用 MobileNetV2 SSD 进行对象检测,几个小时后您就可以获得惊人的结果。
然而,我们的目标不是驾驶赛车,而是了解制造赛车所面临的挑战。理解“边缘推理”的本质是什么意思。
对于这个特别的项目,我使用了英特尔和谷歌的芯片。在我面前,从左到右,我们有英特尔神经计算棒 2,谷歌珊瑚加速器和谷歌珊瑚板。
Coral 加速器和英特尔神经计算棒 2 将连接到树莓 Pi3b。两个 Raspberries 都运行在新部署的 Raspbian(Raspbian GNU/Linux 9 stretch)上。Coral Dev 开发板开箱即用 Mendel (Mendel GNU/Linux 2 烧杯)。我将在本文中包含的代码也可以在 Coral Dev 板上运行,但是这里我将重点放在 USB keys 上。
用 CIFAR10 建立并量化张量流模型
CIFAR10 是一个公共数据集,可以在这里下载。是一组 6 万张图片(32*32 像素)。每张图片属于以下 10 个类别之一:飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船或卡车。
目的是建立一个深度神经网络,可以预测照片中的内容。从上面的例子可以看出,做到这一点并不容易。
有不同的方法可以用来在 Tensorflow 中构建深度神经网络。最快的当然是使用 Keras 模型,或者构建自己的模型。我两样都做了。首先,我实例化了一个 MobileNetV2 网络。然后,我用 3 个模块构建了一个 convnet 。我用后量化来量化这两个表现都很好的模型。不幸的是,谷歌边缘 tpu 目前不支持后量化。值得一提的是,我在英特尔 NCS2 上成功运行了 convnet。
这一初步侦察显示了这些设备对它们正在处理的数据类型有多敏感。这当然是玩家在未来几年将会大量投资的领域。无论如何,由于边缘 tpu 不支持后量化,我们需要建立一个量化的深度学习网络。由于 Keras 不支持这一点,我们有两个选择。我们可以使用低级 Tensorflow API 或者构建一个估算器。让我们试着用 Tensorflow 构建一个估计器来节省一些时间,并进行量化感知训练。
我们的第一层将由两个 convnet 模块组成。然后,我们将在 10 个单位的密集层中处理张量,以涵盖我们的 10 个类别。评估者有不同的训练、评估和预测方法。训练和评估方法建立它们自己的图表。如果你在笔记本中一步一步走,你会注意到 cnn_model_fn 的功能。这是我们添加层和做管道的地方。
这是我们构建的张量板图形表示。如您所见,与预先训练的模型相比,该网络非常小。我们甚至可以把它印在纸上!
在 cnn_model_fn 函数中,增加了两行用于量化。两个调用 TF . contrib . quantize . create _ training _ graph()和 TF . contrib . quantize . create _ eval _ grap()分别创建量化感知训练图和评估图(我们想要的那个)。这两个函数向我们的图中添加了许多节点,以伪造数据类型的变化,并帮助生成量化图。
定义模型函数后,我们使用 AdamOptimizer 和 softmax 交叉熵在 CIFAR 数据集上训练我们的估计器。有趣的是,创建训练图的 contrib 函数为您提供了以高精度数据类型开始训练和以低精度数据类型结束训练的选项。
这是一个你应该在 Tensorboard 上看到的损失的例子。
一旦模型被训练,我们将开始对我们保留的 5000 个特征进行评估,以验证我们的模型。然后,我们将要求模型预测随机样本,以粗略评估其预测准确性。
我们需要导出的图表是在评估阶段创建的。估计器使得创建 saved_model 变得容易。classifier . experimental _ export _ all 方法值得花一些时间,因为您可以选择想要导出的标记图。
一旦导出了 saved_model,就必须通过将最新检查点的变量转换为常量(比如网络的权重)来冻结它。检查这个 jupyter 笔记本来加载、检查和冻结你保存的模型。
测试 1:使用谷歌加速器进行推理
谷歌于 2019 年 3 月 26 日宣布Coral 加速器和 Dev Board。目前,这方面的资源相对有限,但谷歌每天都在忙于增加更多的资源。
为 Google Accelerator 部署环境很简单。只需遵循谷歌的入门教程。十分钟后,你就可以走了。我强烈建议使用虚拟环境。一旦所有东西都安装好了,你就可以使用检测和分类模型了。
现在我们有了我们的环境,让我们的模型做一个推论。首先,我们需要将 saved_model 编译成一个 tflite 模型。要做到这一点,我们必须使用谷歌的转换器 TOCO。
如果你按照笔记本上的步骤一直到最后,你只需要跑:
toco-graph _ def _ file = freezed . Pb-output _ file = TF lite _ model . TF lite-input _ format = tensor flow _ graph def-output _ format = TF lite-inference _ type = QUANTIZED _ uint 8-input _ shape = " 1,32,32,3 "-input _ array = model _ input/input-output _ array = soft max _ tensor-STD _ dev _ values = 127-mean _ value = 127-default _ ranges _ min = 0-default _ ranges _ max = 6
除了输入张量的名称和输出张量的名称之外,您可以看到指定偏差、*均值以及 Relu 的默认范围也很重要。这就是我们决定使用 Relu6 的原因。
在将资产转移到 Raspberry 之前还有一个步骤:将 tflite 模型转换为 edgetpu.tflite 模型。有一个在线工具可以解决这个问题。您应该会看到类似这样的内容:
如果你没有,很可能意味着你没有遵守要求。
现在让我们编写代码来进行推断。这个 edge-tpu API 使用起来非常简单。你必须使用分类引擎或者检测引擎。两个引擎都扩展了基础引擎,并提供了加载模型和运行推理的简单方法。我用来运行我们模型的 python 文件可以在这里找到。
一旦上传了 python 文件和资源(即 edge _ TPU _ 模型和至少一张来自 CIFAR10 的图片),您就可以运行该模型并验证它是否有效。您应该会看到这样的内容:
恭喜你!您已经使用 Google 加速器在 Raspberry Pi 上成功构建并运行了我们的量化模型。
值得注意的是,谷歌边缘-tpu API 允许在带有加速器的设备上进行训练。例如,如果你想进行在线学习,这是一个很棒的功能。
测试# 2:NCS 的推理
Movidius 早在 2017 年 7 月就宣布了神经计算棒,目前领先谷歌几圈。这项技术支持更多的环境,并且有不同的 API 可以使用。
我开始玩英特尔 Movidius NCSDK 。NCSDK 包括一套用于编译、分析和验证深度神经网络的软件工具,还包括用于 C/C++或 Python 应用开发的英特尔 Movidius NCAPI。不幸的是,NCSDK V2 仅适用于 NCS V1。它不支持 NCS V2。(是的,这是令人困惑的。)
对于 NCS V2,你必须使用 OpenVino。OpenVino 是最*的一项开发,旨在统一 CPU、GPU、VPUs (Movidius)和 FPGA(Altera)的不同英特尔*台。我真的很喜欢 OpenVino 架构,它让你根据你的目标使用不同的 OpenVino 插件。
我唯一的遗憾是 NCSDK 非常强大,提供了大量的定制功能;很遗憾我不能在这里玩它。另一方面,我喜欢 OpenVino 与 OpenCV 的结合。这对以后肯定有帮助。最后但同样重要的是,令人惊讶的消息是 NCSDK 和 OpenVino 都是在 Apache License 2.0 下获得开源许可的。
关于为你的覆盆子寻找合适的 OpenVino 软件包,我建议访问英特尔下载中心。我使用的是 l _ openvino _ toolkit _ raspbi _ p _ 2019 . 1 . 094 . tgz。请记住,您还需要在桌面上安装 open vino,因为在这里您将使用所有工具来编译、分析和验证您的 dnn。
要进行部署,请遵循英特尔针对 Raspberry 的安装文档。这是一个比谷歌环境更复杂的过程。(这是有道理的,因为选项越多,设置就越复杂。)
一旦你安装了 OpenVino 环境,你就可以使用一个非常酷的演示来链接三个模型。在下图中,你可以看到它们是如何工作的。第一个模型检测汽车。然后第二个模型检测牌照。第三个模型读取车牌。
为了在 Raspberry 上移植我们的冷冻模型,我们必须使用模型优化器。模型优化器不在树莓上,这就是为什么你的桌面上需要 OpenVino。
模型优化器是一个非常强大的转换器,提供了许多不同的选项。对于不同的 ML 框架,有通用的参数,也有特定的参数。
你会在这个笔记本的末尾找到我用的参数。一旦有了这两个文件(。xml 和。bin ),你把它们移到树莓上的工作区。你还需要至少一张 CIFAR10 图片和 python 文件来做出推断。您应该会看到类似这样的内容:
我花了一些时间玩 OpenVino API。我试图理解如何连接一对相机和使用深度模块。我还尝试使用 net.forwardAsync()来提高性能。我没有成功。OpenVino API 是最*才出现的,在功能方面似乎落后于 Movidius API。不幸的是,我认为我们必须再等一两个版本才能接触到这些高级特性。
相对表现:谷歌与英特尔
这两款 SOC 都具有令人印象深刻的规格和强大的处理能力。
Myriad X 是第三代英特尔 Movidius VPU(视觉处理单元)。该 SoC 设计用于在 30Hz 和 60Hz 下处理 8 个 RGB 传感器和 4k 处理。它每秒处理 7 亿像素。该芯片使用 20 多个硬件加速器来执行光流和立体深度。除此之外,16 个可编程 128 位矢量处理器使您能够运行多个并行视觉应用流水线。
不幸的是,谷歌给出的关于边缘 tpu 的信息少得多。他们确实分享了边缘 tpu 的图形处理单元有 4 个着色器,每秒处理惊人的 1.6 千兆像素。此外,谷歌声称视频处理单元能够处理 H.265 中的 4kp60 和 mpeg 2 中的 1080p60。
理论上,英特尔 SoC 似乎比 edge-tpu 更强大。
两款设备的性能功耗比似乎都非常好。下面两张图片显示了这两款设备在静止状态下的功耗。看起来 NCS V2 需要更多的兆瓦,但这需要在压力下得到证实。谷歌善意地通知我们,在安装期间,加速器可能会变得非常热。在任一款 Raspberry Pi 上运行对象检测时,我都没有注意到任何明显的温度变化。很可能 Pi Cam 规范和 USB-2 限制使得很难将设备置于足够的压力下。
为了加载设备,我做了一个非常短的 python 程序,其中一个循环总是使用相同的图像进行推理。这个想法是为了降低 usb2 总线的发生率,但 wireshark 的一个快速会话显示,每次我们做出推断时,图像都会移动。
我在 mobilenet v1 上为 Myriad 测得的每次推理为 70 毫秒,在 mobilenet v2 上为 edge-tpu 测得的每次推理为 60 毫秒,在 Raspberry 上为 550 毫秒。mobilenet v2(347 万 MAC)及其瓶颈层比 v1(424 万 MAC)需要更少的计算。人们普遍认为 mobilenet v2 比它快 15%到 30%。因此,在 Raspberry Pi 上,这两款设备将处于同一领域,以微弱优势领先于 Myriad。
记住 python 不是性能的最佳选择也很重要。这两款设备都有可用的 C++ API,这是我获得最佳性能的选择。有趣的是,您可以堆叠英特尔 Movidius NCS,这是一个非常好的功能。
考虑到这两款设备的规格,性价比最终非常相似。谷歌加速器售价 74.99 美元,英特尔 NCS V2 售价 99 美元。你可以随时买到 V1 的 Movidius,价格是 74 美元。
设计因素也非常相似,使得在任何项目中集成 usb 密钥都很容易。谷歌加速器比 NCS V2 更薄,但必须用 USB-C-to-USB-2 电缆连接。英特尔解决了一个关于 V1 的抱怨:在树莓上,V1 的设计覆盖了不止一个 USB 端口。V2 只覆盖了一个。
结论
两款设备的处理能力允许开发人员处理广泛的用例。
许多预先编译的网络很容易得到快速和良好的结果。然而,完全量化你自己的网络仍然是一项高级任务。转换需要对您的网络和操作方式有深入的了解。此外,从 FP_32 到 FP_16 以及从 FP_16 到 UINT,精度损失也很大。有趣的是,当谷歌加速器只处理 8 位定点时,Myriad 处理半浮点。这意味着 Myriad 将产生更多的准确性。
英特尔和谷歌显然采取了两种截然不同的方法。谷歌的优势在于,从谷歌云*台到边缘 tpu,人们可以很容易地构建和营销一个集成的工作流程。我真的很喜欢所有组件的组合方式。另一方面,英特尔提供了英特尔中介表示和 Openvino 插件,开发人员可以使用这些插件来优化他们的网络,以便在各种硬件上运行。OpenVINO 目前支持英特尔 CPU、GPU、FPGAs 和 VPUs。英特尔面临的挑战是,统一战略总是难以利用每个组件的高级功能。
这两个系统都提供了大量的高级功能。谷歌加速器能够在线训练你的网络,这对迁移学习至关重要。显然,谷歌认为他们预先训练的网络和迁移学习提供了一个非常有效的组合。英特尔 NCS 有三对内置的立体深度硬件,这对许多用例来说是无价的,如物体回避。
我非常喜欢成为英特尔社区的一员。成员们非常乐于助人。我没有得到谷歌的帮助,但这肯定是因为它的产品线非常年轻。英特尔的文档非常丰富,尽管有时令人困惑。在我进行这个实验的时候,Google 的文档几乎不存在。从那时起,我注意到这种情况正在迅速改善,我希望很快看到一个非常好的学习*台(colab ),拥有大量的资源。
边缘的推论绝对是爆炸式的,可以看到惊人的市场预测。根据 ABI 的研究,2018 年边缘人工智能处理的出货量收入为 13 亿美元。到 2023 年,这一数字预计将增长到 230 亿美元。
显然,一种解决方案不会适合所有人,因为企业家正在寻找部署机器学习的新方法。看看这两家公司最终会获得多少市场份额将是一件有趣的事情。我敢打赌,谷歌云*台将推动许多转移学习应用程序在边缘发光,而英特尔将与许多合作伙伴一起管理各种硬件上的非常多样化的项目。
无论是哪种情况,有一点是肯定的,那就是我们现在拥有在边缘创新和加速第四次工业革命的工具。
我希望这份报告能帮助你实现你的目标,或者至少在你的项目上节省一点时间。我欢迎这方面的任何反馈,并随时欢迎新的机会。
使用 EM 算法的推理
原文:https://towardsdatascience.com/inference-using-em-algorithm-d71cccb647bc?source=collection_archive---------10-----------------------
深入了解 EM 算法的魔力,并开始训练您自己的图形模型
介绍
这篇文章的目标是解释统计分析中一个强大的算法:期望最大化(EM)算法。它之所以强大,是因为它有能力处理缺失数据和未观察到的特性,这些用例在许多现实应用程序中经常出现。
完成这篇文章后,你将能够理解许多使用概率图形模型解决有趣问题的研究论文,并且获得自己开发和训练这种模型的能力。
先决条件
- 耐心(因为这篇文章很详细,并且深入数学概念)。
- 基本概率概念。
- 逻辑回归。
- 迭代优化技术,如梯度上升。
观察特征的情况
在深入研究复杂用例之前,先了解简单用例中的参数是如何估计的会有所帮助。因此,我们首先考虑我们的数据不包含任何缺失值并且我们的模型没有任何潜在特征的情况。为此,我们将借助逻辑回归模型。
假设我们有一个数据集,每个数据点由一个 d 维特征向量 X 和一个相关联的目标变量Y∈{ 0,1}组成。该模型的图示如下:
众所周知,逻辑回归中目标变量的预测概率由如下 sigmoid 函数给出:
equation 1
其中 w 为待估计的权重向量。一旦我们估计了参数【w】、,我们就可以根据【Y】= 0 或 Y =1 是否根据equation 1
获得更大的概率来产生未观测数据点的输出。然而,这里的核心问题是:我们怎样才能逼* w 从而产生准确的预测?为此,我们将使用最大似然法。
最大似然法的前提很简单:找到使观测数据的似然性(或概率)最大化的参数 w 。
为了数学上的便利,我们将考虑最大化可能性的 对数 。由 w 参数化,对数似然可以写成:
equation 2
这里,在数据样本独立同分布的假设下(所谓的 i.i.d .假设 ),观察数据的似然性被表示为各个数据点的似然性的乘积。我们还利用了这样一个性质:一个 对数 表达式中各项的乘积相当于单个项的 对数 的总和。将equation 2
中的equation 1
替换为:
equation 3
这里我们用到了这样的知识:当 y_i =1,elseσ(w . X _ I)w . X _ I**
在这一点上,我们应该注意到 log-likelihood,**L(w)**, 可以方便地分解为每个实例的形式,并且不同参数之间没有耦合,这大大简化了优化。我们将在后面看到,这在许多现实场景中可能无法实现。
由于L(w)**是 w 的一个函数,所以我们对equation 3
没有任何封闭形式的解。因此,我们将不得不使用迭代优化方法像梯度上升找到 w 。梯度上升法的更新如下所示:
equation 4
其中 η 为学习率。我们重复equation 4
中的过程,直到收敛,最后得到的称为最大似然估计。**
潜在特征的情况
现在我们准备深入更复杂和更现实的用例。在大多数现实场景中,数据集中通常会有缺失值,或者选择具有与数据中观察到的特征相关的潜在(未观察到的)特征的复杂模型。
一个使用潜在特征的模型是隐马尔可夫模型。它被广泛使用,并具有一系列真实世界的应用,如语音识别、手写识别、手势识别、词性标注、乐谱跟踪、时间序列分析等。
然而,问题是:具有潜在特征对参数的估计有影响吗?原来,是的。如果涉及潜在特征(或缺失数据),估计模型参数确实有点棘手。我们来看看为什么。
问题
设 V 为观察变量集合, Z 为潜在变量集合, θ 为模型参数集合。如果我们考虑参数估计的最大似然法,我们的目标 1 函数将是:
equation 5
比较
equation 5
和equation 2
,我们可以看到,在后一种情况下,由于测井内的求和,参数是耦合的。这使得使用梯度上升的优化(或一般的任何迭代优化技术)变得难以处理。这意味着许多现实场景需要更强大的技术来推断参数。
EM 算法拯救世界
谢天谢地,研究人员已经想出了这样一个强大的技术,它被称为期望最大化** (EM)算法。它利用了这样一个事实,即当我们知道【Z】的值时,优化完整数据对数似然 P ( V,Z | θ )* 要容易得多(因此,从 log 内部移除求和)。**
********* 向前看,为了标记简单起见,我们将 Y 视为 V 的一部分。**
然而,由于知道 Z 的值的唯一方法是通过后验 P ( Z | V,θ ) ,我们转而考虑潜变量后验分布下的完全数据对数似然的期望值。这个寻找期望值的步骤被称为电子步骤。在随后的 M 步中,我们最大化这个期望来优化 θ 。
形式上,EM 算法可以写成:
**1\. Choose initial setting for the parameters ***θ^old***2\. **E Step** Evaluate ***P(Z | V, θ^old)***3\. **M step** Evaluate ***θ^new*** given by**
**4\. Check for convergence of log likelihood or parameter values. If not converged, then ***θ^old***=***θ^new*** and return to the E step.**
深入新兴市场
在深入研究之前,首先,我们将推导一个在解释 E 和 M 步骤时会派上用场的属性。
让我们考虑潜在变量的分布q(Z)。独立于q(Z)的选择,我们可以按以下方式分解观察数据的可能性:
equation 6
*第一步,我们分别应用概率边际化概念和贝叶斯定理。
第二步,我们将日志中的q(Z)相乘,并分别应用“乘以日志中的项相当于项的日志的和”属性。*
equation 6
中的第二项是两个分布之间众所周知的距离度量,称为 Kullback-Leibler 散度。
此时,我们应该仔细研究一下equation 6
的形式。第一项包含在 V 和 Z 上的联合分布,而第二项包含给定 V 的 Z 的条件分布。KL 散度的一个性质是它总是非负的。利用equation 6
中的这个性质,我们可以推导出 L ( q,θ)≤ln p(V |θ)。
这意味着 L ( q,θ ) 作为观察数据的对数似然的下界。
这个观察,很快,将有助于证明 EM 算法确实最大化了对数似然。
电子步骤
假设参数向量 θ 的初始值为***θ^old***
——(步骤 1)** 。记住由equation 6
给出的关系,E 步试图最大化下限L(***θ^old***
)相对于 q ,同时保持***θ^old***
固定。注意到ln p(V |θ)的值不依赖于q(Z),因此 L ( q, ***θ^old***
) 的最大值将在 KL 背离消失时出现 或者换句话说当q(Z)等于后验分布 p(Z | V,***θ^old***
)(因为 ln 1 求值为 0)。
因此,E-step 涉及评估 p(Z | V,***θ^old***
)——(Step 2)****
Illustration of E-step. [1]
m 步
在该步骤中,分配q(Z)保持固定。如果我们把 E-step 中的q(Z)=p(Z | V,***θ^old***
)代入表达式中的 L ( q,θ ) ( equation 6
,我们看到,下界
equation 7
其中该常数仅仅是 q 分布的负熵,因此与 θ 无关。
所以,在 M 步中,我们最大化下界 L ( q,θ ) 相对于 θ 给出一些新值***θ^new***
。 这将引起下界 L ( q,θ ) 增大,必然引起相应的对数似然函数增大。——(第三步)
Illustration of M-step. [1]
由于分布 q 在 M 步期间保持固定,所以它将不等于新的后验分布 p(Z | V,***θ^new***
)),因此将存在非零 KL 散度。因此,我们再次重复 E 和 M 步骤,直到收敛。——(第四步)
把所有的放在一起
我知道一下子很难消化。因此,我将尝试在下图的帮助下总结讨论,这应该有助于将这些点联系起来。
How E and M step maximize the likelihood. [1]
红色曲线描绘的是不完全数据对数似然性,ln p(V |θ),我们希望最大化。在第一个 E 步骤中,我们从一些初始参数值***θ^old.***
开始,我们评估潜在变量的后验分布,【p(Z | V,***θ^old***
),这产生了一个下界L(***θ^old***
【T71),其值等于在 M 步中,界限被最大化,给出值***θ^new***
,这给出了比***θ^old***
更大的对数似然值。随后的 E 步骤构建一个在***θ^new***
相切的边界,如绿色曲线所示。**
在每一步中,我们看到所获得的参数增加了对数似然,并且该过程一直持续到收敛。
结束语
这结束了一篇关于 EM 算法的相当激烈的数学文章。然而,深入理解这个算法是一个很好的时间投资,如果您想开发自己的图形模型来解决具有挑战性的问题,它确实证明是有帮助的。如果你正在寻找一个示例问题和代码,你可以参考我的这个 GitHub repo ,在那里我们解决了将方面、评级和情绪与评级预测任务的时间动态联合建模的挑战。
参考
[1]纳斯拉巴迪 NM。模式识别和机器学习。电子成像杂志。2007 年十月;16(4):049901.
原贴@https://rishabhmisra . github . io/Maximum-Likelihood-Estimates-Motivation-For-EM-Algorithm/
引文
如果您在研究中使用了此处介绍的作品,请使用以下格式之一引用它:
文本格式:
米斯拉里沙卜。"使用 EM 算法进行推理."中,向数据科学 (2019)。
BibTex 格式:
@misc{misrainference2019,
author={Misra,Rishabh},
title = {推理使用 EM 算法},
URL = { https://Medium . com/forward-Data-Science/推理使用-em-algorithm-d71cccb647bc},
journal={Medium},
publisher = { forward Data Science },
year={2019},
month={Feb}
}
推断时间序列数据中的因果关系
原文:https://towardsdatascience.com/inferring-causality-in-time-series-data-b8b75fe52c46?source=collection_archive---------3-----------------------
对主要方法的简要回顾。
什么事件引起了另一个事件,或者什么导致了一个现象的某种变化,这是一个常见的问题。例子包括药物是否导致某些医疗状况的改善(相对于安慰剂效应,额外的医院就诊,等等。),跟踪装配线故障的原因或确定网站流量激增的原因。
虽然对这个问题的天真解释可能会提出一些简单的方法,如将因果关系等同于高度相关性,或者从作为 y 预测者的 x 的良好程度来推断 x 导致 y 的程度,但事实证明这个问题要复杂得多。结果,在几个科学领域中发展了处理这个问题的严格方法。
因果推理的任务分为两大类:
- 代表不同事件的随机变量的因果推理。最常见的例子是两个变量,每个变量代表 A/B 测试的一个选择,每个变量都有一组与之相关的样本/观察值。
- 时间序列数据上的因果推断(以及随机过程)。例如,确定每日股票总价格是否(以及在何种程度上)驱动每日交易量,或者太*洋沙丁鱼渔获量、北方凤尾鱼渔获量和海面温度之间的因果关系。
这篇文章只讨论第二类问题。
范围
这篇文章旨在对学术文献和在线资源中发现的用于推断时间序列数据因果关系的主要方法、从这些方法得出的方法及其代码形式的实现进行简明的技术综述。
它旨在触及(1)经典的统计方法,主要创建于计量经济学研究领域,包括现代发展(2)和来自各种其他研究团体的改编和原创方法,如处理动态系统或信息理论的方法。
因果推理的一般主题既太大又不能直接适用于本文。对于一般的因果推理(在许多情况下,这是在一般的概率分布或其样本上进行的,而不是在时间序列数据上)和机器学习之间的交集来说,也是如此。尽管如此,我还是在 其他著名文献部分中收录了一些我在这些主题上遇到的著名资源。
组织和符号
概述有时以引用格式在正文中给出,而可选注释以可点击的脚注给出(每个脚注都有一个链接,让你回到它的起源)。还提供了一个可点击的目录来帮助导航。我已经添加了📖链接到每一节的页眉;点击它可以快速返回目录。最后,文章附有所用文献的完整参考文献。
必需的背景
这篇文章是用技术语言写的,虽然我显然不能像这篇文章中引用的学术论文那样深入,但我不会回避包括方程、符号和需要技术背景才能理解的文本。 ⁹
因此,我们假设你至少有一门完整的概率统计本科理论课程的背景,或者相当于这门课程,包括所需的数学背景。如果你不熟悉随机过程理论,你可以在我关于时间序列数据*稳性的文章中找到它的简明评论。进一步阅读需要熟悉这个理论,因为它是时间序列中因果关系的统计概念建立的框架。
目录
- 背景:时间序列数据中因果关系的概念
- 格兰杰因果关系
- 西姆斯因果关系
- 结构因果关系
- 干预因果关系
- 时间序列数据因果关系推断的经典方法
- 非定向滞后相互作用
- 格兰杰因果关系的参数 VAR 检验
- 时间序列数据的替代参数格兰杰因果测度
- 条件格兰杰因果指数【CGCI】
-基于 MLP 的格兰杰因果 F 检验 - 格兰杰因果 RBF 模型
- 部分格兰杰因果指数(PGCI)
- 定向一致性测度
- 条件格兰杰因果指数【CGCI】
- 时间序列数据的替代非参数因果性度量
-Bouezmarni-Taamouti 检验 - 时间序列数据因果推断的混沌与动态系统理论方法
-Hiemstra-Jones 检验
-Diks-Panchenko 检验- 扩展的格兰杰因果指数(EGCI)
- 收敛交叉映射(CCM)
- 时间序列数据因果关系推断的信息论方法
- 粗粒度传递信息率(CTIR)
- 基于传递熵的度量
- 混合嵌入互信息(MIME)
- 时序数据因果推理的图形化方法
- 因果图搜索算法(SGS、PC 和 FCI)
-PCMCI
-Lasso-Granger-Copula-Granger
-正反向 Lasso Granger (FBLG)
- 因果图搜索算法(SGS、PC 和 FCI)
- 选择使用哪种方法
- 人员跟随
- 其他值得注意的文献
- 参考文献
- 学术文献:因果关系及因果推断
- 学术文献:时间序列数据中的因果推断
- 学术文献:其他
- 其他网上来源 - 脚注
背景:时间序列数据中因果关系的概念
多年来,统计和经济学学者提出了许多不同的因果关系概念。我在这里给出了主要的概述。这部分内容部分基于[Eichler,2011 年]和[ Runge,2014 年 ]。📖
格兰杰因果关系 ⁸
格兰杰[1969,1980]在[维纳,1956]的基础上提出了时间序列数据因果关系的最早概念。它是基于对比使用宇宙中的所有信息预测随机过程 Y 的能力,用 U 表示,以及使用 U 中的所有信息预测随机过程 X 的能力;这用 U\X 表示。核心思想是,如果丢弃 X 降低了关于 Y 的预测能力,那么 X 包含一些关于 Y 的独特信息,因此我们说 X 是 Y 的格兰杰原因。
更正式地说:
- 设 X 和 Y 为*稳随机过程。
- 用𝒰ᵢ =(U ᵢ₋₁ ,…,U ᵢ₋∞ ) 表示宇宙中直到时间 i、的所有信息,用𝒳ᵢ =(X ᵢ₋₁ ,…,X ᵢ₋∞ ) 表示直到时间 i、的所有信息。
- 用 σ表示(Y ᵢ | 𝒰ᵢ ) 在时间 i 用𝒰ᵢ 预测 Y ᵢ的残差的方差。
- 用 σ表示(yᵢ|𝒰ᵢ*𝒳ᵢ)*预测残差的方差 Y ᵢ使用𝒰ᵢ 中所有信息在时间 i 除𝒳ᵢ.
定义 1: 如果σ(yᵢ|𝒰ᵢ)<σ(yᵢ|𝒰ᵢ*𝒳ᵢ)那么我们说 X Granger-causes Y,写x y*。
定义 2: 如果x y和y x我们说反馈正在发生,写 X ⇔ Y 。
正如格兰杰自己指出的那样,获得宇宙中所有信息的要求是极其不现实的。实际上 U 被一组有限的观测时间序列代替,其中X∈X,上述定义为 X 格兰杰原因 Y 相对于 X 。
最后,该定义没有指定用于 σ 的预测方法,因此允许线性和非线性模型,但是使用方差来量化预测的接*程度将这种因果关系的概念限制为*均因果关系。
这个概念通常被称为强格兰杰因果关系;其他相关的因果关系概念有均值格兰杰因果关系【格兰杰 1980,1988】和线性格兰杰因果关系【ho soya 1977,Florens 和 Mouchart 1985】。
瞬时因果关系:一种相关的因果关系,稍微修饰一下格兰杰因果关系,就是瞬时因果关系【普莱斯,1979】。如果在时间 i 时,将 Xᵢ 添加到信息集中有助于提高 Yᵢ 的预测值,我们说 x 和 y 之间具有瞬时因果关系。
更正式地说:
- 设 X 和 Y 为*稳随机过程。
- 用𝒰ᵢ =(U ᵢ₋₁ ,…,U ᵢ₋∞ ) 表示宇宙中直到时间 i、的所有信息,用𝒳ᵢ =(X ᵢ₋₁ ,…,X ᵢ₋∞ ) 表示直到时间I、的所有信息(在两者中
定义三:如果σ(yᵢ|𝒰ᵢ∪{xᵢ})<σ(yᵢ|𝒰ᵢ)那么我们说 X 和 Y 之间存在瞬时因果关系。**
请注意,这种类型的因果关系不是定向的,而是对称的,可以证明,如果上述定义成立,那么对称陈述——即σ(xᵢ|𝒰ᵢ∪{yᵢ})<σ(xᵢ|𝒰ᵢ)——也成立(见[Lütkepohl,2007]的证明)。因此,我们并不是说 X 瞬间导致 Y ,而是说 X 和 Y 之间存在瞬间因果关系。
多步因果关系:在一个双变量系统中,如果一个变量的 1 步提前预测不能通过使用另一个变量中的信息来改善,则对于任何 h=1,2,… 的所有 h 步预测都是如此,因此 1 步提前标准足以定义格兰杰因果关系。如果信息集包含额外的变量,这个结果不再成立。[吕特科波尔和米勒,1994 年]
因此,在一个多变量系统中,我们说变量 Xᵢ 是另一个变量 Yᵢ 的 h ,如果 Xᵢ 中的信息有助于提高对某些 j=1,2,…,h 的j-步长预测。
西姆斯因果关系
在一篇有影响力的论文中,[Sims,1972]表明——在协方差*稳过程的背景下,并限于线性预测器——在二元情况下,格兰杰因果关系的定义相当于过程 x[t],y[t]的移动*均或分布滞后表示的参数限制。当系统是协方差稳定时,它可以表示为:
Equation 8: The Sims representation for covariant stationary processes
其中 aⱼ 、 bⱼ 、 cⱼ 和 dⱼ 为常数,u【t】和v【t】为互不相关的白噪声过程。西姆斯表明,条件 x[t]不是格兰杰原因 y[t+1] 等价于 cⱼ 或ⱼ对于所有 j 被选择为相同的零。
格兰杰的定义认为时间优先是从过去到现在的一种联系,与之相反,西姆斯的概念认为时间优先是从现在到未来的一种联系。因此,所考虑的潜在因果关系是从因变量到回归变量的未来值或“线索”。
当它在[Sims,1972]中被引入时,它是作为格兰杰定义的一个等价定义提出的,但此后它与格兰杰定义形成对比,并被证明当所使用的时间序列的非相关性度量是独立性时,它是不等价的[Florens 和 Mouchart,1982];相反,它表明格兰杰因果关系是一个更强的条件,而格兰杰因果关系意味着西姆斯因果关系,反之则不成立。
尽管存在这种不等价性,大多数时间序列数据因果推断的统计检验都集中在格兰杰的定义上。然而,至少在使用向量自回归(VAR) 模型的情况下,可以修改这些测试来测试西姆斯的因果关系(参见这里的示例,该示例强调了线性情况的测试之间的差异)。
结构因果关系
由 White 和 Lu (2010) 提出的结构因果关系假设数据生成过程具有一个递归的动态结构,在这个结构中,前趋者在结构上决定后趋者。具体来说,对于两个过程 X——潜在原因——和 Y —响应,我们假设它们是由
Equation 9: The structural causality DGP
对于所有的 t∈Z 。这里,过程 Z 包括所有相关的观测变量,而 U=(Uₓ,Uᵧ) 的实现被假设为不可观测的,函数 q[x,t] 和 q[y,t] 被假设为未知的。
观察到这种动态结构是通用的,因为结构关系在它们的论证中可能是非线性和非单调的,并且在可观察和不可观察之间是不可分的。不可观察的事物在数量上可能是无限的。最后,该系统可以产生*稳过程、非*稳过程或两者。
然后可以定义因果关系的结构概念:
作者接着分析了格兰杰因果关系和结构因果关系之间的关系。此外,基于格兰杰因果关系的经典概念,他们引入了两个扩展:弱格兰杰因果关系和追溯弱格兰杰因果关系。
最后,作者对他们的两个格兰杰因果关系概念进行了实际检验。具体来说,弱格兰杰因果关系可以通过测试响应的条件独立性 Y 和潜在原因 X 来检测,给出响应的历史和过程的可观察协变量的*期历史。
干预因果关系
朱迪亚·珀尔(Judea Pearl)倡导将干预作为因果推断统计理论的基础,这至少可以追溯到 90 年代早期[珀尔和维尔马,1991 年][珀尔,1993 年]。然而,它对时间序列数据的应用直到最*才开始得到严格的处理【怀特,2006】艾希勒和迪德勒兹,2007】。这种因果关系的方法与经济学中的脉冲响应分析密切相关。
Eichler 和 Didelez 定义了一组可能的干预机制,对应于具有 d 分量的多变量*稳时间序列 X 中不同的可能干预类型。干预由干预指示符 σ 表示,其在 {∅、s∈ 𝓢} 中取值;我用 Xₐ 表示 X 中的一个组件,用 X ᶸ 表示 X 中组件的子集,其中 a ∈V 和 U⊂V 表示 V={1,…d} 。我还使用 σₐ 来表示对组件 Xₐ 的干预。
干预类型包括:
- **空闲状态:当 σ ₐ (t) = ∅时,X ₐ (t) 自然产生,无需干预。又名观测体制。
- 原子干预:此处 𝓢=X , xₐ ,t49】, σₐ(t) = x ⦁表示强制 Xₐ(t) 取值 x⦁.的干预
- **条件干预:这里 𝓢 由函数
g(xᶸ(t-1))∈X、U⊂V 组成,这样 σₐ(t)=g 的意思是 Xₐ(t) 被迫取一个值,这个值取决于 Xᶸ(t=1) 的过去观察值。 - **随机干预:这里的 𝓢 由分布
组成,意思是 Xₐ(t) 被迫从这样的分布中产生。
然后,在确保干预是系统的孤立外生变化的一些假设下,根据策略 s 的干预在 X 中对响应变量y【t 】*的*均因果效应* (ACE)定义为(假设 w.l.o.g .认为 *𝔼[Y[t
]]=0 )😗
Equation 10: The average causal effect (ACE) of interventions according to strategy s
因此,ACE【s】可以视为不干预和干预策略 s 之间的*均差。此外,可以通过考虑ace【s₁—ace【s₂,或者干预后分布ℙ[s](y[t`】的其他泛函来比较不同的策略。**
现在,先验地,没有理由为什么不是在感兴趣的干预制度下收集的数据应该允许估计 ACE 。然而,作者随后继续展示了使用他们所谓的后门标准用观测体系下已知或可估计的量来表达 ACE 的可能性。
我发现这是时间序列数据中因果关系与非常有影响力的基于干预的一般因果关系概念的非常优雅的调和。
此外,Samartsidis 等人最*的一篇论文提供了对其他方法的全面审查,这些方法用于评估针对二元干预【Samartsidis 等人,2018】具体案例的综合时序观察数据中的干预因果效应。
****注:干预因果关系的概念与这里提出的其他三个概念根本不同;虽然格兰杰因果关系,西姆斯因果关系和结构因果关系都假设一个观察框架,干预因果关系作出了更强有力的假设,干预可以在研究过程中进行。因此,它在许多现实生活场景中明显不太适用。
时间序列数据中因果关系推断的经典方法📖
本节涵盖了基于经典统计方法的两种最基本的因果关系推断方法。
非定向滞后相互作用
推断两个时间序列 X 和 Y 之间因果关系的最基本方法可能是使用潜在原因时间序列滞后(后移)版本 X 与(非滞后)潜在原因时间序列 Y 之间对应关系的非定向测量。
如果在 X 的k-滞后和(非滞后) Y 之间发现高度对应,那么可以推断出X-导致- Y 的非常微弱的概念;因此,从以下事实推断出方向:滞后 X 与 Y 高度对应。可以使用各种对应措施;其中有皮尔逊相关(如[Tsonis 和 Roebber,2004]),互信息(如[Donges at al .2009])和相位同步(例如[Pikovsky 等人 2003])。
当选择的对应测量是皮尔逊相关时,这相当于查看两个时间序列的互相关函数的不同正负滞后,并将其在所选范围内达到的最大值作为因果联系的强度,滞后的符号指示因果方向。天真地说,如果函数在正负时滞上都达到正值,那么就可以推断出双向因果关系。在任何情况下,为了得到有效的解释,必须考虑两个系列的自相关性。
这种方法主要用于气候研究[Yamasaki 等人,2008 年] [Malik 等人,2012 年] [Radebach 等人,2013 年]。如 SIFT 在线手册第章第 4.5 节所述,以及 Runge,2014 第 5.2.1 节所述,它被证明存在可能产生误导性结论的重大问题。
格兰杰因果关系的参数 VAR 检验
格兰杰因果关系的经典参数检验的简明分类见[Greene,2002]。这些年来,大量的测试被用来检验格兰杰因果关系。因此,我简单介绍一下我遇到的测试,集中在我能找到的用通用数据处理编程语言(如 Python 和 r)实现的测试上。
一般来说,这些测试的第一阶段是确保所有被检查的序列都是*稳的——如果不是,通常通过趋势移除和/或差分使它们*稳。
然后,在成对测试中,对于每一对时间序列和每一个特定的因果方向X Y,生成一个(通常手动)数量的潜在原因序列的负(过去)滞后 X (包括零滞后,即 X 本身)。要采用的最大滞后长度是一个模型选择考虑因素,因此应该基于一些信息标准(例如 Akaike 信息标准、贝叶斯信息标准等)进行选择。).
****注:如果检查大量配对,您还需要考虑如何处理多重假设检验产生的问题。
以下所有情况中使用的模型是内生(潜在原因)时间序列 Y 作为随机过程的向量自回归模型;陈述了两个这样的模型。
第一个模型——称为限制模型——假设 Y 仅线性依赖于其自身的过去值,具有线性系数γ ᵢ 和时间相关噪声项e【t】:
Equation 11: The restricted model in a VAR-based Granger causality test
相反,第二种模型——称为无限制模型——假设 y 线性依赖于 x 和 y 的过去值,由系数 αᵢ 、t27】βᵢ和时间相关噪声项 u【t】确定:
Equation 12: The unrestricted model in a VAR-based Granger causality test
未格式化的零假设是当与第一个模型比较时,第二个模型不添加信息,或者提供更好的 Y 模型。这需要形式化为一个可测试的零假设;一种常见的方法是陈述零假设 H₀ 是∀i,βᵢ=0* 。*
最后,以下测试程序之一适用于所有此类滞后 X 和无滞后 Y 对。为了检查两个方向上的因果关系,将 Y 的滞后添加到被检查系列的集合中。
注:格兰杰因果检验对滞后长度的选择和处理时间序列非*稳性的方法非常敏感。
基于 SSR 的格兰杰因果关系 f 检验:对限制和非限制模型的参数进行估计(通常使用普通最小二乘法)。然后使用两个序列的 RSS 计算 F 统计量T5,由下式给出:
Equation 13: RSS-based F statistic for Granger causality
其中 T 是时间序列长度,而 p 是滞后的数量。
此处和处给出了该测试的双变量情况的一个很好的概述。在stats modelsPython 包【Python】,在MSBVAR 包【R】,lmtest 包【R】,NlinTS 包【R】和vars 包【R】中实现了一个二元版本。
Pearson 因果关系的卡方检验:首先,利用 OLS 估计模型参数。使用两个系列的 SSR 计算卡方统计T3,并执行皮斯龙卡方测试程序。在的 statsmodels 包【Python】中实现了一个二元版本。
格兰杰因果关系的似然比卡方检验(亦称 G 检验)*卡方统计 使用两个数列的似然比计算,并遵循标准检验程序。一个双变量版本在stats models 包【Python】中实现。*
格兰杰因果关系的异方差稳健 F 检验:在【Hafner 和 Herwartz,2009】中介绍,该过程使用 bootstrapping 进行参数估计,对异方差稳健(例如,在这种情况下,产生比 OLS 更有效的估计量),以及自定义 Wald 检验统计量。一个双变量版本在vars 包【R】中实现(参见因果关系方法中实现的第二个测试)。
Toda 和 Yamamoto 程序:在[ Toda 和 Yamamoto,1995 ]中引入,该程序旨在处理检验序列是任意阶的整合或协整合(或两者兼有)情况下的格兰杰因果关系的检验。在这些情况下,上述检验中的检验统计量不遵循它们通常的零意义下的渐*分布;该程序旨在解决这一问题。作者给出了一个详细的测试程序,它使用一个标准的 Wald 测试作为一个组成部分,以这样一种方式,一个适当分布(在零假设下)的测试统计量被实现。戴夫·贾尔斯有一篇关于这个过程的优秀博客文章。
我没有找到这个过程的代码实现,但是因为它的重要性,我把它包括在内了。它可以通过使用组成它的所有过程的现有实现来实现。
线性格兰杰因果关系的其他检验:线性格兰杰因果关系检验在许多方向得到了发展,例如【Hurlin and Venet,2001】提出了一个用面板数据进行因果关系检验的程序,而【Ghysels et al. 2016】引入了一个用混合频率数据进行格兰杰因果关系检验的程序。
上述线性方法适用于检验格兰杰因果关系。然而,他们不能检测格兰杰因果关系在更高的时刻,例如,在方差。为了应对这一挑战,以及格兰杰因果关系的经典模型中的其他缺陷,提出了大量的方法;这些方法包括非线性参数方法和各种非参数方法。
接下来的章节旨在简明扼要地涵盖在时间序列数据中推断因果关系的众多替代方法,这些方法受到自然科学各个领域的启发。
时间序列数据的替代参数格兰杰因果测量📖
[Papana 等人,2013 年]概述并比较了以下大多数因果关系测量。
条件格兰杰因果指数(CGCI)
在[Geweke,1984]中介绍,这是第一次尝试建议测量多个时间序列之间的线性相关性和反馈的程度。作者把 X 和 Y 之间的线性因果关系分解为 X 到 Y 的线性因果关系、Y 到 X 的线性因果关系以及两个序列之间的瞬时线性反馈之和。此外,所介绍的措施可以(在某些条件下)按频率相加分解。
使用相同的 VAR 模型作为原始的线性 Granger 因果关系度量,CGCI 被类似地定义为限制模型和非限制模型的残差方差之比的自然对数。因此,区别仅在于受限和非受限模型中除了 X₁ 和 X₂ 之外还包括了额外的时间序列;因此,如果 X₂ 只是调节一些其他时间序列 Z 对 X₁ 的影响,我们可以再次期望无限制模型的残差与限制模型的残差相似,在这种情况下,指数将接*于零。
Equation 14: The Conditional Granger Causality Index
CGCI 使用的风险值模型的限制性变体被提出来处理更高维度的数据、更少量的样本或非线性因果关系。[Siggiridou 和 Kugiumtzis,2016 年]概述了几个此类变体(并介绍了另一个)。
格兰杰因果关系的 MLPf 检验
这种方法非常类似于前面提到的基于 VAR 的方法,但是感知器代替了 VAR 作为解释模型。训练两个多层感知器(MLP)神经网络模型——一个仅用于内生时间序列,一个用于两者——并执行 f 检验以检验外生时间序列不提高内生时间序列的可预测性的零假设。在NlinTS 包【R】中实现。
格兰杰因果关系的 RBF 模型
[Ancona et al. 2004]提出了一个格兰杰因果关系的非线性参数模型,用更丰富的径向基函数(RBF)族代替了 VAR 模型,该模型被证明能够在期望的程度上逼*任何真实函数。
最*,[Ancona 和 Stramaglia,2006 年]表明,并非所有非线性预测方案都适合评估两个时间序列之间的因果关系,因为如果将统计独立变量添加到输入变量集,它们应该是不变的。在这一发现的推动下,[ Marinazzo et al. 2006 ]旨在找到适合评估因果关系的最大类 RBF 模型。
偏格兰杰因果指数(PGCI)
CGCI(及其扩展)仍然假设包含所有相关变量。[郭等,2008]引入作为一个因果关系指数,可以处理受检系统中外源输入和潜在(即不可观测)变量的存在。
为了确定从变量 Y 到变量 X 的直接因果关系,给定另一个变量 Z(这可以自然地扩展到多个变量),以及系统的外部输入和未观察到的潜在变量,作者建议以下限制 VAR 模型,带有噪声协方差矩阵 S:
Equation 15: The Restricted VAR model for PGCI
以及下面的无限制 VAR 模型,带有噪声协方差矩阵σ:
Equation 16: The Unrestricted VAR model for PGCI
像以前的风险值模型一样,矩阵 A₁,B₁、A₂、E₂和 K₂模拟每个序列的自回归效应,其他矩阵模拟每个模型对其他模型的不同滞后效应,εᵢ是白噪声过程。这里的新成分是εᵢᴱ和εᵢᴸ,前者是代表外生输入的独立随机向量,后者是代表潜在变量的独立随机向量。
作者继续发展了两个度量:(1)通过消除εᵢᴱ和εᵢᴸ.的影响,基于以 z 为条件的先前值的 x 的自回归预测的准确性的度量(2)通过消除εᵢᴱ和εᵢᴸ.的影响,以 z 为条件,基于 x 和 y 的先前历史来预测 x 的现值的准确性的度量然后他们将 PGCI 定义为两者之比的自然对数。根据两个模型的噪声协方差矩阵 S 和σ,该指数可以写成:
Equation 17: PGCI in terms of the noise covariance matrices of the VAR models
通过比较,标准的格兰杰因果指数可以表示为
gci =**【ln(|s₁₁||σ₁₁|】。
作者还通过使用非线性 RBF 参数模型将他们的测量扩展到非线性情况,在 Marinazzo 等人 2006 中进行了细化。指数保持在等式中。1.
定向相干测量
相干的二元函数通常用于信号处理,以估计线性系统输入和输出之间的功率传递。[Saito 和 Harashima,1981]通过定义定向一致性 (DC)扩展了这一概念,将一致性分解为直接一致性测量的两个组成部分:一个代表被检查系统中的前馈动态,另一个代表反馈动态。最初的论文使用了一个双变量自回归模型,这个模型后来被推广到多变量的情况。
[Baccalá and Sameshima,2001]扩展了定向相干的概念,在偏相干函数的基础上定义了偏定向相干(PDC),作为多变量情况下基于相干的 Granger 因果性度量。
时序数据的替代非参数因果关系测量📖
请注意,以下章节中介绍的大多数方法,涉及混沌和动态系统理论方法以及因果关系推断的信息论方法,也是非参数化的。
布-塔二氏试验
[Bouezmarni 和 Taamouti,2010 年]的作者对双变量情况下的条件独立性和格兰杰因果关系进行了非参数检验。不像大多数测试那样关注均值的因果关系,作者们将他们的测试建立在条件分布的基础上。
检验因果关系的其他非参数方法在[Bell 等人,1996 年]和[Su 和 White,2003 年]中提出。
时间序列数据因果推理的混沌和动态系统理论方法📖
本节涵盖基于两个密切相关领域混沌理论和动态系统分析的因果推理方法。自然,这些方法在某种程度上也与信息论相关,这将在下一节中介绍。
希姆斯特拉-琼斯试验
[ Baek 和 Brock,1992 ]发展了一个非线性 Granger 因果检验,后来被[ Hiemstra 和 Jones,1994 ]修正,以研究股票收益和股票交易量之间的二元非线性因果关系。在随后的几年中,这种检验在检验非线性格兰杰因果关系中变得很常见,并被[白等,2010]扩展到多变量情况。
虽然通常不这样提出,但他们的非参数相关性估计器是基于所谓的相关积分,一种概率分布和熵估计器,由物理学家 Grassberger 和 Procaccia 在非线性动力学和确定性混沌领域开发,作为混沌吸引子的表征工具。[Hlaváková-Schindler 等人,2007 年]因此,它也与下一节讨论因果关系的信息论度量的 CTIR 度量密切相关。
[Diks 和 Panchenko,2005]已经表明,通过该过程测试的关系并不隐含格兰杰非因果关系的零假设,并且随着样本量的增加,实际拒绝率可能趋于 1。因此,该测试被重新审视,并针对双变量情况(在[白等人 2017 年])和多变量情况(在[白等人 2018 年])提出了克服上述一些问题(即拒绝率随样本量的增长)的新版本。
迪克斯-潘琴科试验
基于他们对 Hiemstra-Jones 检验问题的研究[Diks 和 Panchenko,2005],作者在[Diks 和 Panchenko,2006]中提出了一种新的格兰杰因果关系的双变量非参数检验。与 Hiemstra-Jones 测试相比,随着样本量的增加,他们表现出明显更好的大小 ⁵ 行为和他们测试的功效,同时还测试了与期望的零假设等价的关系。[ 迪克斯和沃尔斯基,2015 ]将测试扩展到多变量设置。
扩展的格兰杰因果指数(EGCI)
在[Chen et al. 2004]中介绍的这种方法将经典的格兰杰因果关系指数扩展到非线性情况,方法是将应用限制在约简邻域中的局部线性模型,然后对整个数据集的结果统计量进行*均。
这种方法利用了动力系统理论领域的技术;延迟坐标嵌入用于重构相空间 R ,然后在重构的空间 R 中拟合自回归模型,而不是样本的原始空间。该模型适用于参考点 z₀ 的邻域(由距离参数 δ 确定)中的所有点。然后使用对整个吸引子采样的邻域进行*均来估计 EGCI 测量中的剩余方差。最后,EGCI 被计算为邻域大小的函数 δ 。对于线性系统,该指标应该大致保持不变,因为 δ 变小,而对于非线性系统,它(应该)揭示了非线性因果关系,因为 δ 变小。
作者还提出了一个指数的条件变量,条件扩展格兰杰因果指数(CEGCI),以处理多变量的情况。
收敛交叉映射
在[ Sugihara et al. 2012 ]中介绍,CCM 是一种基于非线性状态空间重构的因果关系推断方法,是动力系统理论中常用的数学模型,可应用于因果变量具有协同效应的系统(不同于格兰杰因果检验)。作者证明了真正的耦合变量和非耦合变量的外部强制情况之间的成功辨别。
该方法由一些作者在的 rEDM 包【R】、的 pyEDM 包【Python】和的 cppEDM 包【c++】中实现,并附有的综合教程。
时间序列数据因果关系推断的信息论方法📖
[Papana 等人,2013 年]概述并比较了以下大多数因果关系测量。
粗粒度信息传输速率(CTIR)
CTIR 是[palu et al . 2001]引入的一种度量,基于 条件互信息 ,用于检测双变量时间序列场景中耦合系统之间的“信息流方向”。
以信息论的形式定义,而不是强度的度量,它测量从进程 Y 到进程 X 的净信息量的*均速率,或者换句话说,进程 Y 影响进程 X 的净信息流的*均速率。
[Hlaváková-Schindler 等人,2007 年]对 CTIR 和有条件互信息以及用于估计它们的各种方法进行了极其全面的概述。同一篇论文还包括一个证明,证明了在适当的条件下,这两个度量是等价的。
转移熵测度
转移熵 的信息论概念是在【Schreiber,2000】中引入的,作为一种量化随时间演化的系统之间的统计一致性的方法,这种方法可以区分和排除由于共同的历史和输入信号而从共享信息中实际交换的信息。或者,也可以说量化了在 X₁ 在 h 的状态比 X₂ 的状态超前一步,说明了 X₁ 的并发状态。转移熵由下式给出:
Equation 18: Transfer Entropy
I(x₁+h 在哪里;x₂|x是条件互信息,给出了 X₁ 在 h 步 X₂ 给定当前值 X₁ 的互信息的期望值; H(X) 是 香农熵;和 H(X,Y) 是 联合香农熵 。第一个等效性见[Palu 和 Vejmelka,2007 年]。**
此后,在神经科学等领域的各种论文中,转移熵被频繁用作因果关系的衡量标准(例如[Vicente,2011]),并在[Jizba 等人,2012]中扩展到使用其他熵衡量标准,如 Reyni 的。[贝尔德斯,2005 年]提出了一个更适合在同质空间扩展系统因果关系检测的变化措施。
P 人工转移熵 (PTE) ,在【Vakorin et al,2009】中提出,是转移熵 熵的扩展,旨在衡量 X₂ 对 X₁ 的直接因果关系,以 Z: 中的剩余变量为条件**
Equation 19: Partial Transfer Entropy
****符号转移熵(STE):STE 测度等于在由变量的重构向量形成的秩点(即符号)的嵌入空间(维数为 d )上估计的转移熵。
Equation 20: Symbolic Transfer Entropy
其中 X̂₁,t 是向量 X₁,t 在时间 t 的顺序 d 的顺序模式(参见【凯勒和辛恩,2005】),其在给定时间延迟 τ 的情况下,被定义为满足(0,1,⋯,d)的排列(r₀,r₁,⋯,rd)
部分符号转移熵(PSTE): STE 以与 PTE 相同的方式扩展到多变量设置:
Equation 21: Partial Symbolic Transfer Entropy
其他基于转移熵的因果性度量包括[Kugiumtzis,2012]中介绍的秩向量转移熵(TERV),以及[Kugiumtzis,2013A]中介绍的秩的多元扩展部分转移熵(PTERV)。
混合嵌入的互信息(MIME)
在[Vlachos 和 Kugiumtzis,2010]中介绍,MIME 是用于时间序列分析的互信息驱动的状态空间重构技术,包括因果关系(因此也可以放在动态系统理论方法部分)。
在双变量的情况下,该方案给出了来自变量 X₁ 和 X₂ 的不同延迟的混合嵌入,这最好地解释了 X₁ 的未来。混合嵌入向量w【t】可以包含 X₁ 和 X₂ 的滞后分量,定义两个互补子集 W[t]=[Wˣ t,wˣt】。然后,MIME 被估计为:
Equation 22: Mutual Information from Mixed Embedding
等式中的分子。22 是等式中 TE 的条件。18,但对于 X₁ 和 X₂.的非均匀嵌入向量 MIME 因此可以被认为是用于优化 X₁ 和 X₂.的非均匀嵌入的 TE 的规范化版本
来自混合嵌入的部分互信息(PMIME) 是用于多变量设置的 MIME 的扩展,在【Kugiumtzis,2013B】中描述,通过对所有环境变量 Z 进行额外调节来完成,很像在 PTE 和 PSTE 中。最能描述 X₁ 未来的混合嵌入向量现在潜在地由所有 K 滞后变量构成,即 X₁ 、 X₂ 和 Z 中的其他 K-2 变量,它可以分解成三个各自的子集,分别为 W[t]=[Wˣ t、Wˣ t、wᶻt】。然后,PMIME 估计为:**
Equation 22: Partial Mutual Information from Mixed Embedding
该方法由作者在 Matlab 软件包中实现。
时间序列数据中因果关系推断的图解方法📖
在多变量环境中,经常使用图形方法来模拟格兰杰因果关系:每个变量(在我们的情况下,对应于一个时间序列)被视为格兰杰网络中的一个节点,有向边表示因果联系,可能有延迟(见图 2)。
因果图搜索算法(SGS,PC 和 FCI)
一个因果搜索算法家族,使用条件依赖原则和因果马尔可夫条件 ⁷ 的应用来重构数据生成过程的因果图,由三个相关算法组成:SGS、PC 和 FCI。参见[Spirtes 等人,2000 年]的全面概述。
这些算法的主要结构是相似的:
- ****初始化:初始化所有变量 V 上的全无向图(即假设所有因果联系)。
- ****骨架构建:然后,通过测试依赖程度增加的条件独立性来消除边缘(这里算法不同;SGS 测试每一个可能的条件集,而 PC 只包括连接的变量)。
- ****边消除:最后,应用一组统计和逻辑规则来确定图中边的方向(即因果关系)。
在前两者之间,SGS 被认为可能对非线性更鲁棒,而 PC——两者中更常用的一种——的复杂度不随变量数量呈指数增长(由于边缘消除阶段的差异)。最后,PC 算法不能处理未被观察到的混杂因素,这是它的扩展 FCI 试图解决的问题。
【Runge et al,2017】认为 PC 不适用于时间序列数据,声称使用自相关会导致基于数值实验的高假阳性率。
PCMCI
PCMCI 是【Runge et al,2017】中描述的一种因果发现方法,在 Tigramite Python 包中实现。作者声称,它适用于大型数据集( ~O(100k) )的变量,这些变量具有线性和非线性、时间延迟相关性,给定数百或更多的样本大小,与 Lasso Granger 和 CI 系列算法等方法相比,它显示了一致性和更高的检测能力,并具有可靠的假阳性控制。
该方法包括两个阶段:
- pc₁——一种基于 PC 算法的马尔可夫集发现算法,通过迭代独立性测试去除每个变量的不相关条件。
- MCI——瞬时条件独立性测试,旨在解决高度相互依赖的时间序列情况下的假阳性控制,条件是潜在因果联系中两个变量的双亲。为了测试 Xⁱ是否以滞后τ影响 Xʲ,测试以下内容(其中𝒫(Xⁱ是 Xⁱ):的父节点集)
The MCI test
就像在 PC 系列算法的框架构建阶段一样,PCMCI 的两个步骤都可以与任何条件独立性测试相结合。作者研究了线性情况下的线性偏相关检验,以及非线性情况下的 GPDC 和 CMI 检验。
拉索-格兰杰
该方法在[Arnold 等人,2007 年]中介绍,通过利用套索法的变量选择性质,作为在高维多变量设置中应用格兰杰因果关系模型的方法。
该方法还适用于处理【Bahadori 和刘,2012A】和【Bahadori 和刘,2012B】中具有广义拉索格兰杰()和加权广义拉索格兰杰()变量的不规则时间序列(样本在采样点块缺失或在非均匀间隔时间点收集的序列)。
[Hlaváková-Schindler and Pereverzyev,2015]对 Lasso-Granger 方法进行了全面的综述,尽管是在基因表达调控网络的特定背景下。
Copula-Granger
Copula-Granger 是[Bahadori and Liu,2012B]和[ Bahadori and Liu,2013 ]开发和介绍的一种半参数 Granger 因果关系推断算法。copula 方法首先在[Embrechts et al. 2002]中提出用于时间序列分析,后来在[Liu et al,2009]中用于学习时间序列之间的依赖图。
作者在[ Bahadori and Liu,2013 ]中从两个主要性质方面检查了两种现有方法及其算法:(1)处理混杂因素的 虚假 效应的能力,以及(2) 一致性。整个分析是在因果充分性的强假设下完成的——即系统中任何两个观察变量的共同原因都没有被遗漏。
Figure 2: A toy Granger graphical model, with delays τᵢ. When X₄ is unobserved, a spurious edge X₁ ← X₃ is detected by some algorithms.
作者强调了 VAR 模型的两种主要方法的不足之处,即显著性检验和拉索-格兰杰,并表明他们的方法在高维度上是一致的,并且可以捕捉数据中的非线性(对于简单的多项式情况)。提出的方法中的两个主要创新点是明确处理图中因果关系路径的延迟,用于防止识别虚假效应(见图 2),以及将观察值投影到 copula 空间,同时将非超常(非参数正态)分布合并到 DGP 中。
在[Furqan 等人,2016]中,以与弹性网推广 lasso 相同的方式,推广使用弹性网正则化方法,以克服 lasso 的自然限制:当用于高维数据时不稳定,当变量的数量大于观测点的数量时,在饱和之前变量选择有限。
向前向后拉索格兰杰(FBLG)
Lasso Granger 和 Copula-Granger 都是在[Cheng et al. 2014]中使用一种类似 bagging 的元算法(称为前向-后向)扩展的,该算法通过反转输入时间序列来丰富数据集。
选择使用哪种方法📖
一般来说,决定使用哪种方法来推断或检测数据中的因果关系,主要取决于数据本身及其特征,以及您对其有信心的假设和产生它的实际过程。
格兰杰因果关系与其他方法
格兰杰因果关系的关键要求是可分性,这意味着关于因果关系的信息不包含在因果关系的时间序列中,可以通过从模型中移除该变量来消除。
通常,可分性是纯随机和线性系统的特征,格兰杰因果关系可用于检测非线性系统中强耦合(同步)变量之间的相互作用。可分性反映了这样一种观点,即系统可以一次理解为一部分,而不是一个整体。[ 杉原等人,2012 年
因此,使用基于格兰杰因果关系的经典方法的第一个标准是将您的数据分成几个互斥(信息方面)的时间序列的能力,对于这种能力来说,确定几个特定的时间序列引起一些其他特定的时间序列是有价值的。
在无法满足这些条件的复杂动态系统中,旨在推断此类系统中因果关系的现代方法,如 CCM 或 PCMCI 可能更合适。
参数与非参数方法
无论选择的系统模型是线性的还是非线性的,模型错误设定总是因果推理中的一个挑战。如果您认为没有可用的方法可以很好地模拟问题中的系统和其中的因果关系流——通常使用领域知识和直觉进行确定——那么非参数方法可能更合适,例如在处理动态系统理论和信息理论因果关系测量的章节中介绍的大多数方法。
一个值得注意的警告是,一些方法所做的要求或假设可能会使非参数方法在实践中成为参数方法,这一点乍一看并不明显。一个显著的例子是 PCMCI ,它假设输入时间序列是由*稳过程产生的。由于*稳性的非参数测试(不同于单位根)很少,更不用说没有任何方法或转换可以保证将非*稳数据转换为*稳数据,这种假设将迫使用户 PCMCI 使用参数方法来检测和转换输入数据中的非*稳性。由于缺乏公认的和定义良好的**稳性概念(确实存在一些)以及量化它和确定它何时足以使推理方法正常工作的方法,这种情况变得更糟。
因果图提取
如果因果图的提取是一个目标,那么 PCMCI 和 Copula-Granger (及其扩展 FBCLG)在图形算法中脱颖而出。这两种方法都可以成功地处理混杂因素,PCMCI 还声称对数据中的高自相关具有弹性,并吹嘘有一个方便的 Python 实现。
系统可观测性
系统的可观测性也是一个需要考虑的参数。如果不能满足因果充分性的强假设,那么许多以此为前提的方法——包括 PCMCI 和 Copula-Granger——都不能用于正确推断因果关系。在这种情况下,应考虑旨在处理系统中潜在变量的替代因果关系测量,如 PGCI 。
格兰杰因果关系的不同检验方法的选择
这里的要点很简单:除非你能证明外生变量和内生变量之间存在线性关系这一强有力的假设,否则非参数方法是合适的,因为它对你的随机系统和因果关系流做出了弱得多的假设。
在这种情况下,就检验的功效和规模 ⁵ 而言,迪克斯-潘琴科检验在格兰杰因果关系的非参数检验中脱颖而出。它还解决了格兰杰因果关系的定义与 Hiemstra-Jones 检验所检验的实际关系之间的差异,这一差异甚至没有被白等人的检验变体所解决。
如果系统的线性模型是足够的,那么Toda 和 Yamamoto 程序是用于线性格兰杰因果关系推断的最严格的方法,用于处理重要的现象,如整合或协整合的时间序列。
研究人员跟随📖
Cees Diks 教授不断发表关于非线性格兰杰因果关系和一般非线性动力学的论文。除其他主题外,这包括基于格兰杰因果关系建立金融网络、检验因果关系测试的不同 重采样方法的效果和多变量分析的因果关系度量。
Dimitris Kugiumtzis 教授在时间序列分析方面做了令人难以置信的工作,特别是在时间序列数据的因果关系推断方面,由信息论方法驱动,特别是 MIME 和 PMIME 方法。
George Sugihara 教授是一位理论生物学家,他在多个领域开展工作,引入归纳理论方法,从观测数据中理解自然界中复杂的动态系统。其中最主要的是经验动态建模,这是一种基于混沌理论的分析和预测复杂动态系统的非参数方法,在本文中以 CCM 方法为代表。他的工作涉及从观察数据中理解自然的归纳理论方法。
雅各布·龙格博士在时间序列数据的因果关系方面做了实质性的工作,主要是在气候研究的背景下;他也是 tigarmite 的创建者,这是一个 Python 库,使用 PCMCI 方法在时间序列数据中进行因果推断。
Youssef Hmamouche 是用于基于神经网络的时间序列预测和时间序列数据中的因果关系检测的 NlinTS R package 的作者和维护者之一,最*撰写了一篇关于用于多变量时间序列预测的基于因果关系的特征选择方法。
其他著名文献📖
学习和因果推理
朱迪亚·珀尔(Judea Pearl)是该领域的杰出研究人员,他开发了因果推理的结构方法,最*写了一篇非常有趣的文章,关于因果推理工具和对机器学习的反思【珀尔,2018】。他还写了一篇关于因果推理主题的全面概述【珀尔,2009】。
戴维·洛佩斯-帕兹,脸书人工智能研究所的研究科学家,领导了一项非常有趣的关于一般因果推理的研究,特别是在学习框架和深度学习的背景下。亮点包括将因果推理作为一个学习问题(特别是对概率分布进行分类)[因果生成神经网络](http://Causal Generative Neural Networks)、引入一个用于因果发现的对抗性框架以及[在图像中发现因果信号](http://Discovering Causal Signals in Images)。
Uri Shalit ,Technion 的助理教授,领导一个致力于医疗保健中的机器学习和因果推理的实验室,他的主要研究兴趣之一是机器学习和因果推理的交叉,重点是使用深度学习方法进行因果推理。
Krzysztof Chalupka 在深度学习和因果推理的交叉领域做了一些令人着迷的研究。亮点包括一个基于深度学习的条件独立性测试、因果特征学习、视觉因果特征学习和因果正则化。
最后,[Dong et al. 2012]使用多步格兰杰因果关系法(MSGCM)来识别神经网络中的反馈环,这是一种使用时间序列实验测量来识别生物网络中嵌入的反馈环的方法。
参考文献📖
学术文献:因果关系和因果推理
- 【Eberhardt,2007】Eberhardt,F. (2007),,(博士论文),卡耐基梅隆大学。
- [Geweke et al. 1983] Geweke,j .,Meese,r .,和 Dent,W. (1983), 比较时间系统中因果关系的替代测试:分析结果和实验证据 ,《计量经济学杂志》,21,161–194。
- 【Pearl,1993】,Pearl,J. 【专家系统中的贝叶斯分析】点评:图形模型 。因果关系与干预。统计学家。Sci。,第 8 卷,第 3 号(1993 年),第 258-261 页。
- 【Pearl,2000】Pearl,J. 因果关系:模型、推理、推论 。牛津大学出版社,2000。
- 【Pearl,2009】Pearl,J. 统计学中的因果推断:概述 。统计调查,第 0 卷,2009 年。
- 【Pearl,2018】Pearl,J. 带机器学习反思的因果推理七大工具。计算机械协会通讯,2018。
- 【珀尔和维尔马,1991】珀尔,j .和维尔马,T.S. 一种推断因果关系的理论 。第二届知识表示和推理原则国际会议,1991 年 4 月,马萨诸塞州剑桥。
学术文献:时间序列数据中的因果关系推断
- [Ancona et al. 2004] Ancona N,Marinazzo D,Stramaglia S .时间序列非线性格兰杰因果关系的径向基函数方法。2004 年物理修订版;70:056221.
- [安科纳和斯特拉马利亚,2006 年]n .安科纳和 s .斯特拉马利亚(2006 年)。 核诱导假设空间中预测子的一个不变性 。神经计算,18 ,749–759。
- [Arnold 等人,2007 年] A. Arnold、Y. Liu 和 N. Abe。基于图形格兰杰方法的时间因果建模。《第 13 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集》,第 66–75 页,美国,2007 年。纽约 ACM
- [Bahadori 和刘,2012 年 a]m . t . Baha dori 和刘,2012 年 y . 不规则时间序列中的格兰杰因果分析 。暹罗数据挖掘国际会议(SDM,2012)。暹罗。[ PDF
- 【Bahadori and Liu,2012 b】Baha dori,M.T. and Liu Y. 论时间序列 中的因果推理。发现信息学:人工智能研究在创新科学过程中的作用,2012 年 AAAI 秋季研讨会论文,2012 年。
- [巴哈多里和刘,2013 年]检验格兰杰因果推断的实用性。2013 年在 SDM。[ PDF
- [白等 2010]白,黄伟刚,张本忠。多元线性和非线性因果检验。模拟中的数学和计算机。2010;81: 5–17.doi:10.1016/j . matcom . 2010 . 06 . 008
- [白等 2016]白,惠,吕,黄伟光,朱。hiem stra-Jones 测试再探 。2016;arXiv:1701.03992。
- [白等 2018 年]白,周,惠,杨,姜,吕,黄,王,郑,s,2018。 多元非线性因果关系的新检验 。PloS one,13(1),第 e0185155 页
- [贝克,1992 年]贝克,例如和布洛克,A.W. (1992 年)。 非线性格兰杰因果关系的一般检验:二元模型 。
- [贝尔等人,1996 年]贝尔,d .凯,j .和马利,J. (1996 年)。非线性因果关系检验的非参数方法。经济学快报,51,7-18 页。
- 【Bouezmarni 和 Taamouti,2010】Bouezmarni,t .和 Taamouti,A. 使用条件分布 对条件独立性进行非参数检验。《非参数统计学杂志》2014 年第 26 卷— 第 4 期。
- [陈等 2004]陈 Y,兰嘎然 G,冯 J,丁 m .物理列特 A 2004324:26–35.
- [Cheng et al. 2014] Cheng D,Bahadori MT,Liu Y. FBLG:一种从时间序列数据中发现时间依赖性的简单有效方法。第 20 届 ACM SIGKDD 知识发现和数据挖掘国际会议录:美国纽约。2623709:ACM;2014.第 382-91 页。
- [Diks 和 Panchenko,2005 年]关于格兰杰非因果关系的 Hiemstra-Jones 检验的注释。非线性动力学研究&计量经济学,第 9 卷,第 2 期。
- [Diks 和 Panchenko,2006 年] 非参数格兰杰因果检验的新统计和实用指南。 《经济动力学与控制杂志》30(9–10):1647–1669。( PDF )
- [迪克斯和沃尔斯基,2015 年]迪克斯,c .,&沃尔斯基,M. (2015 年)。 非线性格兰杰因果关系:多变量分析指南 。应用计量经济学杂志。( PDF
- 【艾希勒,2011】艾希勒,M. 时间序列分析中的因果推断 。第二十二章 因果关系:统计视角与应用 , 2011。 (PDF)
- 【Eichler 和 Didelez,2007】Eichler,m .和 Didelez V. 图形时间序列模型中的因果推理 。第 23 届人工智能不确定性会议录。
- [Embrechts 等人,2002 年];麦克尼尔公司;和斯特劳曼博士,2002 年。风险管理中的相关性和依赖性:特性和陷阱。在登普斯特,医学硕士,教育硕士。《风险管理:风险价值及其超越》。剑桥:剑桥大学出版社。
- [弗洛伦斯和穆查特,1982 年]弗洛伦斯,J. P .和穆查特,M. (1982 年)。 关于非因果关系的一个注记 。计量经济学 50,583–591。
- [弗洛伦斯和穆查特,1985 年]弗洛伦斯,J. P .和穆查特,M. (1985 年)。 非因果的线性理论 。计量经济学 53,157–175。很好,国际法院(1961 年)
- [Furqan 等人 2016 年] Furqan MS,Siyal MY。用于生物网络推断的弹性网 copula granger 因果关系。公共科学图书馆一号。2016;11(10):e0165612。
- 【Geweke,1984】gew eke j .时间序列间条件线性相关和反馈的度量。美国统计协会,1984 年;79:907–15.
- 【Ghysels et al . 2016】Ghysels E,Hill JB 和 Motegi K. 用混合频率数据检验格兰杰因果关系 。计量经济学杂志。2016;192(1): 207–230.doi:10.1016/j . jeconom . 2015 . 07 . 007
- 【格兰杰,1969】格兰杰,C. W. J. 用计量经济模型和互谱方法调查因果关系 。计量经济学 37,424–438。
- 【格兰杰,1980】格兰杰, 因果关系检验,个人观点 。经济动态与控制杂志 2,329–352。
- 格兰杰,1988 年。因果关系概念的一些新发展。计量经济学杂志 39,199-211。
- [Greene,2002] Greene,W. (2002) 计量经济分析 ,第 5 版。普伦蒂斯霍尔,上马鞍河。
- [郭等 2008]郭,s,Seth,A.K .,Kendrick,K.M .,周,c .,冯,j . 2008 .部分格兰杰因果关系——剔除外部输入和潜在变量。j .神经科学。冰毒。172 (1), 79–93
- [哈夫纳和赫沃茨,2009 年]克里斯蒂安·哈夫纳和赫尔穆特·赫沃茨,2009 年。 多元广义自回归异方差下线性向量自回归动态的检验 。荷兰统计和运筹学学会,第 63 卷(3),第 294-323 页。
- 【Hiemstra 和 Jones,1994】hiem stra,c .和 Jones,J. D. 检验股价与成交量关系 中的线性和非线性格兰杰因果关系。金融杂志。1994;49(5): 1639–1664.doi:10.2307/2329266[PDF
- [赫拉瓦奇科夫-辛德勒等人,2007 年]赫拉瓦奇科夫-辛德勒,k .,帕卢斯,m .,Vejmelka,m .,和 Bhattacharya,J. (2007 年)。时间序列分析中基于信息论方法的因果关系检测。物理报告,441 ,1–46。
- [h lava ková-Schindler 和 Pereverzyev,2015 年]" Lasso granger 因果模型:基因表达调控网络的一些策略及其效率 ,决策:计算智能中的不确定性、不完美性、深思熟虑和可扩展性研究,T. Guy、M. Kárn 和 D. Wolpert 编辑(Cham: Springer),91–117。doi:10.1007/978–3–319–15144–1 _ 4
- 霍索亚,1977 年。 上的格兰杰条件为 。计量经济学 45,1735-1736。
- [Hurlin 和 Venet,2001 年]固定系数面板数据模型中的格兰杰因果检验。巴黎多菲纳大学。
- 【吉兹巴等人 2012】吉兹巴,p;克莱纳特;Shefaat,M. Rényi 的金融时间序列之间的信息传递 。物理 A:统计。机甲战士。申请 2012 , 391 ,2971–2989。
- [Kugiumtzis,2012 年] Kugiumtzis,d .秩向量上的转移熵。非线性系统。应用程序 2012,3,73–81。
- [Kugiumtzis,2013A] Kugiumtzis,d .秩向量上的部分转移熵。欧元。物理 j 规范。顶端。2013, 222, 401–420
- 来自非均匀嵌入的直接耦合信息度量。物理修订 E 2013 , 87 ,062918。**
- [Kugiumtzis 和 Kimiskidis,2015] Kugiumtzis D,Kimiskidis VK (2015)研究经颅磁刺激对局灶性癫痫样放电影响的直接因果网络。国际神经系统杂志 25(5):1550006
- 刘等,2009;拉弗蒂,法学博士;2009 年洛杉矶乏色曼。高维无向图的半参数估计。JMLR
- [Lütkepohl 和 Müller,1994 年] 检验时间序列中的多步因果关系 。
- 【吕特克波尔,2007】吕特克波尔,H. 多重时间序列分析新入门 。2007.
- 【marina zzo et al . 2006】marina zzo D,Pellicoro M,Stramaglia S (2006) 时间序列 格兰杰因果关系的非线性参数模型。物理学评论 E Stat 非线性软物质物理学 73: 066216。
- [Palu 等人,2001 年] M. Palu,V. Komárek,z . hrnˇcˇr,k . tˇerbová,作为信息率调整的同步:双变量时间序列的检测,Phys. Rev. E 63 (2001) 046211。[ PDF
- [Palu 和 Vejmelka,2007 年]palu M,Vejmelka M .双变量时间序列之间耦合的方向性:如何避免虚假因果关系和遗漏连接。物理修订版 E 200775:056211.
- [Papana 等人,2013 年] Papana,a .,C. Kyrtsou,D. Kugiumtzis 和 C. Diks。2013. 多元时间序列中直接因果关系测度的模拟研究 。熵 15:2635–2661。
- [Papana 等人,2017 年] Papana,a .,Kyrtsou,c .,Kugiumtzis,d .,& Diks,C. (2017 年)。 基于格兰杰因果关系的金融网络:案例分析 。 Physica A:统计力学及其应用, 482,65–73。doi:10.1016/j . physa . 2017 . 04 . 046
- 【波佩斯库和居永,2009】波佩斯库,f .和居永,I. 时间序列中的因果关系 。机器学习的挑战,第 5 卷:基于 2009 年 NIPS的时间序列因果关系的微小征兆。
- [普莱斯,1979 年]迈克尔·普里斯,J. (1979 年)。 瞬时因果关系的表征 。计量经济学杂志,10(2),253–256。doi:10.1016/0304–4076(79)90009–5
- 【龙格,2014】龙格,J. 从复杂系统的时间序列中检测并量化因果关系 。博士论文。( PDF 链接)
- 【Runge et al,2017】Runge,J. Nowack,P. Kretschmer,M. Flaxman,s .和 Sejdinovic,D. 检测大型非线性时间序列数据集中的因果关联 。arXiv.org。
- 【Runge,2018】Runge,J. 基于条件互信息最*邻估计量的条件独立性测试 。2018 年第 21 届人工智能与统计国际会议(AISTATS)论文集。PMLR:第 84 卷。
- 【Samartsidis 等人,2018】Samartsidis,p .,Seaman,S. R .,Presanis,A. M .,希克曼,m .和德·安杰利斯,D. 从聚合时间序列观测数据评估二元干预因果效应的方法综述 。arXiv.org。
- [Schreiber,2000] T. Schreiber,《测量信息传递》,列特物理评论。85 (2000) 461–464.
- 【Siggiridou and Kugiumtzis,2016】Siggiridou,E. & Kugiumtzis,D. 利用时序约束向量自回归模型 研究多元时间序列中的格兰杰因果关系。IEEE 信号处理汇刊 64 ,1759–1773,doi:10.1109/tsp . 2015.2500893(2016)。
- [西姆斯,1972]西姆斯,C. A. (1972)。 金钱、收入和因果关系 。美国经济评论 62,540–552。
- [Spirtes 等人,2000 年] P. Spirtes、C. Glymour 和 R. Scheines。因果关系、预测和搜索。麻省理工学院出版社,剑桥,马萨诸塞州,伦敦,英国,2000 年。
- [苏和怀特,2003]苏和怀特,H. (2003)。条件独立性的非参数海灵格度量检验。技术报告。加州大学圣地亚哥分校经济系。
- [Sugihara 等人,2012 年] Sugihara,g .,May,r .,Ye,h .,Hsieh,C. -h .,Deyle,e .,Fogarty,m .,& Munch,S. (2012 年)。检测复杂生态系统中的因果关系。科学,338(6106),496–500。doi:10.1126/science . 1227079[PDF
- [户田和山本,1995 年]户田,H. Y .,&山本,T. (1995 年)。 具有可能整合过程的向量自回归中的统计推断 。计量经济学杂志,66(1-2),225-250。doi:10.1016/0304–4076(94)01616–8
- 【瓦科林等人,2009】瓦科林,V.A 克拉科夫斯卡岛;间接联系对因果关系估计的混淆效应。神经科学杂志。方法 2009 , 184 ,152–160。
- [贝尔德斯,2005] P.F .贝尔德斯,从多变量时间序列评估因果关系,物理评论 E 72 (2005) 026222。
- [Vicente,2011] Vicente,R,Wibral,M,林德纳,M,Pipa,G 转移熵——神经科学有效连接的无模型测量..J Comput neuro sci。(2011).3045–67
- [Vlachos 和 Kugiumtzis,2010 年] Vlachos,I;非均匀状态空间重建和耦合检测。物理修订 E* 2010 , 82 ,016207。*
- 【White,2006】White,H. 自然实验效果的时间序列估计 。计量经济学杂志,第 135 期,第 527-566 页。
- 【White and Lu,2010】White,H. and Lu,X. 格兰杰因果关系与动态结构系统 。金融计量经济学杂志 8,193–243。
学术文献:其他
- 【Baccalá和 Sameshima,2001】baccaláL,Sameshima K. 部分定向相干:神经结构确定中的新概念 。生物网络 84:463–474,2001 年。[ PDF ]
- [Dong 等人,2012 年] Chao、Dongkwan Shin、Sunghoon Joo、Yoonkey Nam、Kwang-Hyun Cho。基于多步格兰杰因果关系的神经网络反馈回路识别。生物信息学。2012 年 8 月 15 日;28(16): 2146–2153.在线发布于 2012 年 6 月 23 日。doi:10.1093/生物信息学/bts354
- [东格斯看着艾尔。Donges,J. F .,Y. Zou,N. Marwan 和 J. Kurths (2009 年)。 气候网络的骨干 。欧洲物理学通讯 87.4(引文。上第 12 页)(在 arXiv 版引文中)。第 2 页)。
- [Keller 和 Sinn,2005] K. Keller 和 M. Sinn,《时间序列的有序分析》, Physica A 356(2005)114–120。
- [Malik 等人,2012 年] Malik,n . b . book Hagen,N. Marwan 和 J. Kurths (2012 年)。 利用复杂网络 分析南亚上空的时空极端季风降水。气候动力学 39.3–4,第 971–987 页(前引。第 13 页)。
- [Pikovsky 等人,2003 年] Pikovsky,a .,M. Rosenblum 和 J. Kurths (2003 年)。 同步:非线性科学中的一个普遍概念 。第 12 卷。剑桥:剑桥大学出版社。上第 12、18 页)。
- [Radebach 等人,2013 年] Radebach,a .,R. V. Donner,J. Runge,J. F. Donges 和 J. Kurths (2013 年)。 通过演化气候网络分析理清不同类型的厄尔尼诺事件 。物理评论 E 88.5,第 052807 页(前引。第 13 页)。
- [Saito 和 Harashima,1981] Saito Y,Harashima H (1981)多通道脑电图记录中的信息跟踪——脑电图中的因果分析。在:山口 N,藤泽 K,编辑。脑电图和肌电图数据处理的新进展。阿姆斯特丹:爱思唯尔。第 133-146 页。
- [Tsonis 和 Roebber,2004 年] 气候网络的架构 。物理 A 卷 333,2004 年 2 月 15 日,497-504 页。
- 维纳,1956 年维纳预测理论。在:贝肯巴赫 EF,编辑。工程师用现代数学。纽约:麦格劳-希尔;1956 年[第八章]。
- [Yamasaki 等人,2008 年] Yamasaki,k .,A. Gozolchiani 和 S. Havlin (2008 年)。厄尔尼诺显著影响全球气候网络。物理评论快报 100.22,第 228501 页(前引。第 13 页)。**
其他在线资源
- 齐斯迪克斯教授的主页。
- 戴维·洛佩斯-帕斯的主页
- Scholarpedia 上的格兰杰因果关系
- 芭芭拉·韦伯网站上的 f 检验
- 维基百科:G-检验,互信息,似然比检验,F-检验,格兰杰因果关系等文章。
- 工程统计手册上的似然比检验
- stats modelsPython 包的 grangercausalitytests 方法的文档和源代码。
- lmtest R 包的源代码。
- 常见问题:似然比、Wald 和拉格朗日乘数(得分)测试有何不同和/或相似之处?
- 在计量经济学上测试格兰杰因果关系
- 《预测:原理与实践》的第 8.1 章,作者是 Rob J Hyndman 和 George Athanasopoulos ,一本关于预测的优秀在线教材。
脚注📖
- 有关 F 测试的简要概述,请参见此处的和此处的和。 ↺
- 关于卡方检验的概述,请参见维基百科关于主题的文章。 ↺
- 在 lmtest 中, grangertest 方法调用 waldtest 方法,而没有为其 test 参数赋值(该参数决定应用 f 检验还是卡方检验),因此默认使用 f 检验。 ↺
- 格威克在艾尔。对推断时间序列数据因果关系的 8 种方法进行了比较[ Geweke 等人,1983 年 ],并发现归因于 Granger 的检验的 Wald 变量,以及该论文中介绍的 Sims 检验的滞后因变量版本,在所有相关方面都是等效的,并且优于所讨论的其他检验。 ↺
- 统计测试的大小是它产生一个I 型错误的概率;即错误地拒绝零假设。 ↺
- 如果一种方法的误差概率随着观察次数的增加而趋于零,那么这种方法就是一致的。 ↺
- 因果马尔可夫条件:图中的一个变量,以它的双亲为条件,在概率上独立于所有其他既不是它的双亲也不是它的后代的变量。 ↺
- 𝛹-causalityvs 𝛹-非因果关系 : 同一个因果关系的定义,有时可以用两个看似矛盾的名称指代;例如格兰杰因果关系和格兰杰非因果关系指的是同一种因果关系的定义。这是因为在许多情况下,定义是针对逆条件给出的,如果给定条件不成立,则称 X 为𝛹-causing Y 。为了保持一致,我只使用第一种形式。 ↺
- 关于符号的一个注意事项:**我试图让符号尽可能接*源材料,但是由于 Medium 不支持内联数学表达式,所以我尽可能使用 Unicode 字符。具体来说,方括号在本应使用下标但 Unicode 中没有下标的地方重复使用;例如,向量 v 的第 i 个元素将由 v ᵢ表示,但是第 t 个元素将由v【t】表示。 ↺
使用概率软逻辑推断新关系
原文:https://towardsdatascience.com/inferring-new-relationships-using-the-probabilistic-soft-logic-3df1a99e0af9?source=collection_archive---------16-----------------------
Discovering new relationships/links (Photo by Anastasia Dulgier on Unsplash)
数据的主要目的是传递有用的信息,可以操纵这些信息来做出重要的决策。在计算的早期,这种有用的信息可以从直接数据中查询,例如存储在数据库中的数据。如果查询的信息在这些数据存储中不可用,那么系统将无法响应用户的查询。因此,目前,如果我们考虑存在于 web 上的大量数据和呈指数增长的 web 用户数量,则很难准确预测和存储这些用户将查询什么。简而言之,我们不能手工硬编码用户对每个预期问题的回答。那么解决办法是什么呢?最佳答案是从数据中提取知识,提炼并重组为知识图,我们可以用它来回答查询。然而,知识提取已被证明是一个不*凡的问题。因此,我们使用统计关系学习方法,该方法考虑过去的经验并学习事实之间的新关系或相似性,以便提取这样的知识。概率软逻辑(PSL)就是这样一个用于构建知识图的统计关系学习框架。
理解知识图表
知识图是由实体和它们之间的联系组成的事实的巨大网络。知识图可以建立在一个特定的领域上,也可以跨越几个领域,相互参照。我们已经讨论了如何从我的博客中提取的事实构建知识图表。无论如何,让我们快速回顾一下知识图管道作为复习。
首先,我们通过自由文本和各种来源提取事实。这些事实将被存储在知识库中,并对其提取者充满信心。然而,知识库中充满了需要剔除的冗余信息。因此,我们采取措施来提炼和微调传递到知识图上的事实,以便创建更准确、更相关的知识图[5]。细化知识图的一个重要部分是链接预测,这是预测知识图中两个实体之间的链接的过程。然后,基于精炼的知识图,基于相邻关系、新发现的链接及其为真的概率,很容易获取用户查询的结果。
链接预测
如前所述,我们执行链接预测来细化知识图。为了进一步理解链路预测,让我们考虑下面的例子
例一
这个例子是由 Pujura 等人[1]提出的。在这里,系统试图在从各种来源提取信息时识别关于国家吉尔吉斯斯坦的事实。因此,该系统已经识别出关于吉尔吉斯斯坦的以下所有事实。
- 吉尔吉斯斯坦位于哈萨克斯坦
- 吉尔吉斯斯坦位于俄罗斯
- 吉尔吉斯斯坦位于前苏联
- 吉尔吉斯斯坦位于亚洲
- 吉尔吉斯斯坦位于美国
尽管这些事实中有些是真的,但不可能所有这些都是真的。因此,我们使用链接预测,通过考虑某些本体约束来预测最有可能的真实事实。例如,假设我们已经知道美国位于北美大陆,亚洲是另一个大陆。在这种情况下,很明显,一个地方不可能位于两个大陆上。因此,两个事实 4 或 5 中只有一个是真的。
以上是一个简单的逻辑推论,即如果一个地方 P 位于亚洲大陆,那么它不可能位于美国T3,反之亦然。因此,如果我们已经知道一个事实,即吉尔吉斯斯坦位于亚洲,另一个我们不确定的事实,即吉尔吉斯斯坦位于美国,可以被认为是错误的。
例二
考虑另一个领域,我们有一些人的社交网络信息。例如,假设我们想知道两个用户菲比和乔伊是否真的是朋友。这甚至可以被认为是脸书试图推荐朋友的简化场景。如果这两个用户在脸书上不是朋友,我们就没有直接的数据来推断这一点。然而,如果我们已经知道 Phoebe 是另一个叫 Rachel 的用户的朋友,而 Rachel 是同一个用户 Joey 的共同朋友,那么我们可以有把握地假设 Phoebe 和 Joey 也可能是朋友。现在,让我们尝试将这种间接关系映射为一个强制其约束的逻辑规则。
但是坚持住…
在现实世界中,我们有多个用户。在这种情况下,如果我们试图发现所有这些用户之间的新关系,并将上述或类似的规则应用于所有这些关系,我们可能会以大量新推断的关系而告终。仅仅基于规则的逻辑含义,我们不能说我们发现的所有关系都一定是真的或假的。因此,我们需要一种方法,根据我们已经知道是真实的事实,从概率上推断出我们在多大程度上确信一个新推断的关系是真实的。这就是我们使用 PSL 的地方。
什么是概率软逻辑(PSL)
总的来说,PSL 是一个框架,它可以基于相关领域和观察到的证据来联合推理事实之间的相似性[1,2]。PSL 观察已知为真的事实,并计算新推断出的事实的概率。为了做到这一点,最初,用户定义了一组通用逻辑规则,这些规则暗示了新的关系,例如,PSL 程序中的本体约束、相似性或友谊。然后,PSL 程序从概率上推断出它有多大把握,确定的新关系将是真实的。为此,PSL 采用了一套由用户提供的已定义的一阶逻辑规则,并在这些规则的基础上推断现实世界实体的适用性。
PSL 规则将采用通用格式,由如下所示的变量组成。
a、B 和 C 是变量,在我们的场景中,它们用于表示三个不同的脸书用户。通过将实际用户代入该规则,我们可以得到以前没有明确标识的新关系。因此,当我们将 Phoebe,Rachel 和 Joey 代入这个规则时,我们得到了下面的规则,正如前面所指出的。
PSL 不同于它的前辈,它试图根据我们已经从现有信息和链接中获得的知识,从概率上确定我们对新推断的关系的每一个实例有多确定。
但首先,让我们简要了解一下 PSL 的背景。
PSL 的大多数激励性概念都源于马尔可夫逻辑网络(MLN)[3]。除了单独查看事实,MLNs 还考虑了本体约束,如域或逆约束[4]。然而,mln 受限于它们只能为逻辑“关系”取布尔真值的能力,我们称之为“谓词”。这样做的缺点是,我们不能对新推断的事实给出置信度或概率。因此,PSL 选择了一个软真值,而不是确定的 1 或 0,并使用多个提取器来为新呈现的关系提供置信度。基于这些置信度(即概率),我们可以用现有的和高度可能的、新推断的事实构建一个知识图。由于知识图是一个巨大的信息网络,因此在响应用户查询时,检索相关或相邻数据的信息变得很容易,这些数据很可能是真实的。
在下一节中,我们将从高层次上概述如何推断新的或缺失的链接,以及我们对新事实成立的信心程度。
PSL 是如何工作的?
现在,让我们在 PSL 正式重申一个样本一阶逻辑规则(注意,我们需要指定这些规则作为输入,以及我们已经知道为真的事实/三元组,以便运行 PSL 程序)。
在哪里,
- A 、 B 和 C: 实体(变量)
- 朋友:谓词/关系
- w: 规则的权重
这条规则是传递性的基本规则,它规定如果 A 是 B 的朋友,并且 B 是 C 的朋友,那么 A 和 C 也很可能是朋友。上述规则是常量(真实世界的实体)通过一个称为 固定 的过程固定的模板。因此,如果我们取一组新的常数,它们是域内的真实世界的实体,如菲比、瑞秋和乔伊,那么我们将有作为朋友(菲比、瑞秋)、朋友(瑞秋、乔伊)和朋友(菲比、乔伊)的基态原子。这将给我们以下基本规则:规则的单个实例,其权重为 w 。
这些基础原子中的每一个都将具有在[0,1]范围内的软真值。因此,让我们假设这些基础原子中的每一个都具有以下软真值。
然后,我们需要验证上述接地是否满足规则。
验证接地是否满足规则
这通过计算每个基本规则的 满意距离 来完成。为了获得满意的距离, d ,我们使用 Lukasiewicz 范数和余范数,将基本规则视为规则中的基本原子上的公式。
Lukasiewicz t-范数和余范数
Lukasiewicz t-norms 提供了对规则中以下逻辑连接词的放松:
逻辑连接词顶部的波浪号表示 Lukasiewicz 提供的放松。
下一节阐述了我们如何转换基本规则,并应用 Lukasiewicz t-norms 来计算和验证接地是否满足规则。为了做到这一点,首先,
- 通过检查头部对身体的软真值来检查接地是否满足规则。
如果不满足规则,那么我们,
- 计算满意的距离。
1。规则满意度
为了验证一个根植是否满足基于头部和身体中原子的规则,我们需要看头部的整体软真值是否大于或等于身体的软真值,即
然而,目前我们所拥有的只是头部和身体中每个原子的单个软真值。因此,我们简单地将 lukasiewicz 范数分别应用于身体和头部的原子,并得到 Iᵦₒ𝒹ᵧ和 Iₕₑₐ𝒹.的单个软真值因为我们只有一个基态原子作为头部,
,也就是我们之前假设的 0.7,这样我们只需要把 Lukasiewicz 应用到物体的基态原子上。
由于物体中的原子是结合在一起的,我们应用:
同样地,我们对物体的推断值为 0.1,如下面的计算所示。
现在,由于我们对身体和头部的基本规则有以下推论,
,很明显,这个接地满足头部的软真值大于身体的软真值的规则。在这种情况下,满意的距离将为 0。
当接地不满足该规则时,即当头部的推断值不大于或等于身体的推断值时,我们继续计算满足的距离,该距离将是大于 0 的值。
2。计算满意的距离
计算满意度距离的一个简单方法是使用下面的公式 d 。
其中 I 𝓰ᵣ是基本规则的总体软真值。首先,为了计算出规则的总体软真值,我们需要将基本规则转换成它的析取范式。
任何公式都被写成一个蕴涵式
(1)正文中的文字或文字的连词
(2)标题中的文字或文字的析取
可以写成析取子句,因此,我们可以把基本规则转换成析取子句。随着言外之意被析取,身体中的原子被否定。基于此,我们得到了基本规则的以下析取子句。
在这种情况下,被否定的基态原子和我们的基态原子将获得如下所示的软真值。
然后,我们应用 lukasiewicz 范数的析取范数来计算 I 𝓰ᵣ.因此,
这使我们的满意距离为 0,这意味着接地满足规则,与我们检查头部对身体的软真值的评估相一致。因此,让我们尝试使用一个不同的场景,对原子使用不同的软真值。
让我们假设基态原子的新的软真值。
- 朋友(菲比、瑞秋)= 0.7
- 朋友(瑞秋,乔伊)= 0.8
- 朋友(瑞秋,乔伊)= 0.4
这将给我们一组被否定的基态原子,
- !朋友(菲比、瑞秋)= 0.3
- !朋友(瑞秋,乔伊)= 0.2
考虑到这些值, I 𝓰ᵣ = min{1,0.3+0.2+0.4} = 0.9 。
这样,满足的距离将是 0.1,表明接地不完全满足该规则。
递归地,我们可以使用头原子和体原子来验证规则的满足,如步骤(1)中所执行的,其中我们使用接地原子的新值来检查接地是否满足规则。这将使Iᵦₒ𝒹ᵧ成为 max{0,0.7+0.8–1 },也就是 0.5。对照软真值为 0.4 的ₕₑₐ𝒹,我们发现这个规则没有得到满足。因此,我们可以使用任何一种方法来检查接地是否满足规则。
现在让我们试着勾勒出上述计算的全貌。
假设我们有一个 PSL 程序, P,,它包含 n 个定义的规则,其中 I 是这些规则的解释(解释是软真值的赋值)。如果 R ᵏ 如我们之前所讨论的,我们然后计算每个地面实例的满意度距离,并且作为结果,将具有所有地面实例的满意度距离的向量,即 V ᵏ.这个满意度距离的向量只代表了 PSL 项目的一个规则。因此,我们采用加权规则,并为 PSL 计划中的其他规则堆叠满意度距离的所有向量。这给我们留下了另一个矢量 v(I)=[w₁v₁(i)…wₙvₙ(i)]ᵀ]。知道这个 V(I),如果泽塔是一个任意的距离度量,我们将在我们的推理阶段使用,那么,
在这里,如果我们解析到一个L1-范数距离,我们可以得到一个对数线性表示,这是我们在统计关系学习模型中经常遇到的。这将具有如下所示的形式。
另一方面,我们也可以求解*方的L2-范数距离,通过使其成为满足距离的快速增长函数来补偿不满足的规则,如下所示。
接下来,我们继续推断具有未知真值的三元组的软真值,即新推断的信息或缺失的链接。
基于先前可用的证据推断新数据的软真值
给定观察到的三元组集合,推断三元组的最可能值是基于 MPE(最可能解释)推断,该推断遵循 MAP(最大后验概率)推断。这个推论被用来计算出先前未被观察到的基态原子最有可能的软真值。如前所述,我们有一组已知的三元组,用作我们的观察值,并以 PSL 的规则为基础。因此,让我们将这组具有观察到的软真值的三元组命名为 x ,将这组具有未知软真值的三元组命名为 y 。这给我们带来了我们的预期任务,即给定观察值, I ₓ,为 I ₘₐₚ (y) 找到最可能的软真值赋值,这可以通过下面等式中所示的推理来执行。
该映射推断导致基于作为观察到的三元组, x 给出的证据,推断未知三元组, y,的最可能软真值分配。最终,我们以软真理的形式获得了新推断的事实或信息的概率,我们发现这些概率为 I ₘₐₚ (y)。有了这些概率,我们就可以决定这些事实在多大程度上是真实的。这就是自动完成搜索结果、youtube 播放列表和脸书好友建议使用概率显示相关结果的方式。
结论
本文主要对概率软逻辑(PSL)这一联合概率推理框架进行详细阐述。PSL 的总体意图是有一种方法来评估一个推断出的、以前看不见的事实在给定的领域中有多真实。因此,一般假设是推断的软真值越高,事实为真的可能性就越高。推断的软真值越低,就越不可能成立,这意味着没有足够的证据或相关事实来支持新推断的事实。这些概率有助于支持决策过程,以根据已知事实识别新信息(事实)。
然而,由于这种推断和假设不包括人类决策的应用或考虑,很难仅仅基于新推断的软真值来决定性地说一个事实是精确准确的还是不准确的。我目前从事这方面的工作,我们研究如何将软真值和人类评估的数据关联起来,以便清楚地将事实标记为真或假,并使我们的决策与实际的人类评估更加一致。我会在接下来的文章中公布更多细节。
参考文献
[1]m .布罗谢勒、l .米哈尔科娃和格图尔(2012 年)。概率相似逻辑。arXiv 预印本 arXiv:1203.3469。
[2]金米格,a .,巴赫,S. H .,布罗意切勒,m .,黄,b .,&格图尔,L. (2012 年 2 月)。概率软逻辑简介。NIPS 概率规划研讨会:基础与应用(第 1 卷,第 3 页)。
[3]m .理查森和多明戈斯,P. (2006 年)。马尔可夫逻辑网络。机器学习,62(1–2),107–136。
[4]巴赫,S. H .,布罗意切勒,m .,黄,b .,&格图尔,L. (2015)。铰链损失马尔可夫随机场和概率软逻辑。arXiv 预印本 arXiv:1505.04406。
[5]保罗海姆,H. (2017)。知识图精化:方法和评估方法综述。语义网,8(3),489–508。
使用网络抓取的影响者营销
原文:https://towardsdatascience.com/influencer-marketing-using-web-scraping-568ef4c072c3?source=collection_archive---------18-----------------------
Photo by Kaleidico on Unsplash
影响者营销对我们来说不再是一个陌生的概念。在美国零售业中,只有 33%的零售商没有使用或不打算使用任何形式的影响者营销。然而,通过口碑广告来提升你的品牌知名度是一个很好的方法。棘手的部分是如何找到合适的人和/或渠道来推广你的品牌。
如果你在社交媒体上搜索最有影响力的人,你会碰壁。相反,你应该从你的观众群开始,然后扩展人脉。例如,获取你的评论者的信息并就新闻与他们联系是找到你的影响者的好方法。获得这些候选人的最佳方式是通过在你的观众中进行网络搜集。许多企业没有预算购买昂贵的工具,如数据集成。然而,有很多便宜的替代品供你收集有价值的信息,其中之一就是网络抓取软件。
什么是网络抓取
Web 抓取是一种自动化数据提取过程的技术。它涉及到解析一个网站的过程,并收集你需要的数据片段。我将向你展示如何使用网络抓取工具,并使这些数据可用于数字营销。进行 web 抓取不需要编程技能。我使用的工具是 Octoparse ,我将解释为什么它能为营销专业人士带来难以置信的价值。
找到你的“传道者”。
根据 Joshua 的说法,评论是我们可以用来扩展营销策略的地方。我不是说我们留下评论并为你的评论者鼓掌。当评论者的用户名是可点击的时,可以通过提取个人资料信息与他们联系。每当我们有了新的内容,我们就会联系这些人。这样我们就把评论者变成了传道者。除此之外,你可以通过滚雪球的方法来更有创造性的发展,创建你的福音传播者池来推进你的营销过程。
Twitter 福音传播者:
盲目发消息求推文是行不通的。一个很好的开始是利用你的观众群。这个想法是:
- 使用 IFTTT.com 将你的 Twitter 提及和新关注者提取到电子表格中
- 收集关注者的数量、联系方式和对这些人的描述。
- 向人们伸出援手。(确保你给每个人都准备了一封写得很好的推介信)
首先,你需要将两个 IFTTT 食谱与你的 Twitter 和 Google drive 连接起来。打开这些食谱: 在电子表格中跟踪新的关注者 和 将你的 Twitter 用户名的提及存档到你 IFTTT 账户中的电子表格 。
这些食谱顾名思义。他们收集用户 ID 以及提到或关注你的人的链接,并将数据发送到你的电子表格中。
我们需要找到能给你的网站带来流量的有影响力的人。要做到这一点,我们需要刮他们:
- 关注者数量
- Bios
- 网站
- Twitter Id
您可以使用 Octoparse 软件完成所有这些工作:
首先,通过导入收集的 URL 建立一个新任务。
其次,一旦你导入了 URL 列表,Octoparse 会生成一个 URL 的循环列表。通过在内置浏览器中单击元素来选择所需的元素。在这种情况下,点按“关注者”并选取“从操作提示中提取所选元素的文本”您将看到提取的数据出现在数据字段中。
第三,重复上述步骤,获取他们的个人资料、网站和 Twitter ID。
最后一个,运行任务。
你应该能得到这样的床单。您将看到每个提及您的关注者/人及其信息。
然后,将数据导出到电子表格中。你根据关注者数量和背景过滤掉不合格的人。
注:如果你滥用这种方法就错了。请记住不要发送垃圾邮件或不相关的信息。他们的存在是对你伟大工作的一种认可。你对他们的尊重是尊重你内容的另一种方式!
YouTube 影响者:
Youtube 影响者营销是新的黑色。通过口碑策略提高品牌知名度和转化率是一个很好的方法。因此,有影响力的人越来越多。找到合适的影响者是成功营销活动的关键。
“ 61%的营销人员同意为一项活动寻找最佳影响者具有挑战性,这表明这个问题远未解决。”
以下是您需要注意的指标:
- 内容的质量:他们为他们的观众提供了价值吗?他们有什么想法吗?
- 观众是谁?他们与你的目标一致吗?
- 什么是参与度:点赞数,关注数,评论数。
例如,推广一个新的汽车品牌 XYZ。最好的方法是通过汽车评论频道。这个想法是:
- 使用 Octoparse 抓取模板抓取信息,包括视频标题,视频网址,频道网址,观看次数,出版日期,描述。
- 使用通道 URL 创建一个抓取任务,以获取订阅者的数量。
- 导出数据,并根据我们提到的指标过滤掉不合格的候选人。
- 发送请求信并协商您的预算。
Octoparse 抓取模板是一个预先格式化的模块。它允许您在没有任何配置的情况下提取数据。你所要做的就是输入关键词/目标网站。
首先,打开 Octoparse,选择“任务模板”
然后,在分类栏上选择“社交媒体”。你会发现“YouTube”图标。
第三,点击 YouTube 图标。您将看到这个模板可以完成什么样的数据,您还可以看到一个示例输出。如果您对此感兴趣,您需要在参数处键入关键字。在这种情况下,“汽车评论。”
第四,点击“使用模板”并选择您希望运行任务的方式(通过内部部署、云或设定计划)
你应该可以得到这样一个表格:
然而,我们仍然需要知道每个频道的用户数量。为此,请复制 Youtube 频道的 URL 列表。创建新的刮擦任务,并将列表粘贴到参数框中:
- 首先,打开 Octoparse,在高级模式下输入 URL 列表,设置一个任务。这会将您带到配置窗口,您可以在其中解析网页并选择元素。
- 其次,选择元素。在这种情况下,请选择 YouTube 频道名称。并按照指南提示选择“提取所选元素的文本”
- 第三,重复上述步骤提取用户号码
- 最后,运行任务。不到一分钟就能得到结果。以您选择的格式导出数据:Excel、CSV、txt。在这种情况下,我将其导出到 Excel。
你应该能够得到每个 Youtube 频道的订户号码列表,将列表复制到我们刚刚创建的 excel 中。这是一个收集数据的例子:汽车评论 youtube 视频电子表格。然后你就可以过滤掉那些不符合条件的,把数据降序排列,根据你的标准重新组织名单,联系你名单上出现的名字。
这只是网络抓取对营销有所帮助的一小部分。有了它,你可以变得更有创造力。例如,你可以提取 Youtube 视频的评论、Twitter 帖子、产品评论、竞争对手的博客评论,甚至脸书公共社区的帖子和评论。这里的想法是用自动化的数据提取代替单调的手工复制和粘贴工作。使用 Octoparse 的一个好处是它有各种各样的网络抓取模板。这会让你节省很多时间。
最后一点,我们都知道内容营销对于数字营销有多重要。然而,问题是我们以自我为中心,容易相信我们创造的东西。当我们写作时,我们用我们的直觉来期望引起读者的兴趣。相反,这方面的一个很好的技巧是追求流行的内容,写更好的内容来超越它们。你可以抓取博客标题/排名/喜欢/评论等,然后把这些金块组合成小火花。
网页抓取超级强大。然而,当你不明智地使用它时,法律的反弹又会回来。我认为提高技能的最好方法是练习。我鼓励您复制这些技巧,并习惯于自动化数据提取,以获得池塘中的大鱼。
来源:
https://www . octo parse . com/blog/a-revolutionary-web-scraping-software-to-boost-your-business
[## 影响者营销调查结果:2019 年行业基准
我们的年度影响者营销调查揭示了今年一些令人兴奋的发现,其中大多数表明 2019 年将…
mediakix.com](https://mediakix.com/influencer-marketing-resources/influencer-marketing-industry-statistics-survey-benchmarks/)
https://www . emarketer . com/content/what-retailers-need-to-know-on-influencer-marketing
【https://ahrefs.com/blog/web-scraping-for-marketers/
社交网络中有影响力的社区:简化版
原文:https://towardsdatascience.com/influential-communities-in-social-network-simplified-fe5050dbe5a4?source=collection_archive---------24-----------------------
在大规模网络中发现有影响力的团体
为什么要研究社交网络中的社区?
社交网络是大规模现实世界网络的主要例子。它们表现出不同的行为,从密集的网络部分到稀疏连接的个体,从刚性连接到高度动态的图形部分。这使得它们成为数据科学家分析的一个有趣问题。
社区或模块结构被认为是大规模真实世界图的一个重要属性。系统通常以图形表示的学科,如社会学、生物学和计算机科学,也包含这种大规模网络和社区结构的例子,其应用可以极大地激励该领域的研究。
你如何正式定义有影响力的社区?
一个人的影响力是由这个人有多少联系来定义的。很明显,直觉告诉我们,有些人与很有影响力的人有联系,但他们自己却没有太多的联系。这些人也应该算是有影响力的。
虽然在处理这种情况时有各种各样的影响力定义,但最流行和被接受的影响力定义仍然是个人拥有的联系数量,我们现在将继续研究这个问题。
一个社区的强大取决于它最薄弱的环节。在定义一个社区的影响力时,人们提出了许多不同的方法,比如取社区中所有人的*均值或者简单地求和。但是被广泛认同和普遍使用的定义是使用社区中最没有影响力的个人的影响力作为社区的影响力。
什么是 k-core?
图的 k-core 是通过移除图中连接数或度小于‘k’的所有节点来计算的。注意,在从图中移除所有这样的节点之后,如果新的图现在包含度小于“k”的节点(由于移除了那些先前的节点),则它们也被移除,并且重复该过程,直到图中的所有节点的度至少为“k”。
k-影响力社区被定义为影响力至少为“k”的社区(连通子图)。通俗地说,一个图的 k-核中存在的每一个连通分支都是一个 k-影响力社区。许多算法都利用了这一点,允许它们找到 k 核,并将它们与社区相关联。
内存问题
从术语“大规模”图可以明显看出,这些算法面临的最大问题之一是,由于内存限制,无法同时处理完整的数据。这些限制迫使研究人员发挥创造力,引入本地和在线搜索。这些方法基于试探法,可能不会返回全局最佳结果,但非常接*于此,并且可以处理非常大的图。
下一步是什么?
有影响力的社区搜索是一个相对年轻的领域,甚至像社区的定义,其影响力等基本定义。正如在上面的讨论中所指出的,仍在辩论中。因此,未来工作的一个可能方向是探索更多的凝聚力定义,以获得紧密团结的社区。
博客中介绍的细节很少。请参考我们的论文 这里 进行更详细的调查。
这个博客是努力创建机器学习领域简化介绍的一部分。点击此处的完整系列
[## 机器学习:简化
在你一头扎进去之前就知道了
towardsdatascience.com](/machine-learning-simplified-1fe22fec0fac)
或者只是阅读系列的下一篇博客
[## 深度学习—模型优化和压缩:简化
看看最先进的机器学习模型的压缩、修剪和量化领域
towardsdatascience.com](/machine-learning-models-compression-and-quantization-simplified-a302ddf326f2)
参考
[1]加内什、普拉哈尔、萨凯特丁利瓦尔、拉胡尔阿加瓦尔。"在大规模网络中发现有影响力社区的文献综述."arXiv 预印本 arXiv:1902.01629 (2019)。
[2],,,,余,。大型网络中有影响力的社区搜索。继续。VLDB 捐赠。,8(5):509–520,2015 年 1 月
【3】李建新、王新觉、、杨晓春、蒂莫斯·塞利斯和杰弗里·于。大型社交网络上最有影响力的社区搜索。第 871–882 页,2017 年 4 月。
[4]、、于、。在庞大的网络中寻找有影响力的社区。《VLDB 日报》,26(6):751–776,2017 年 12 月
【5】张力军,林,。一种在线搜索 top-k 影响力社区的优化和渐进方法。继续。VLDB 捐赠。,11(9):1056–1068,2018 年 5 月
InfluxDB 数据保留
原文:https://towardsdatascience.com/influxdb-data-retention-f026496d708f?source=collection_archive---------7-----------------------
运营团队经常使用时间序列数据来调查性能问题。因为我们无法提前预测性能问题的来源,所以我们经常犯谨慎的错误,尽可能频繁地收集尽可能多的数据。这使得获取环境中最*一小时、一天或一周内发生的事情的详细信息变得非常容易。但是,随着主机数量和数据量的增加,保留超过一两周的数据会变得很困难。
有许多原因可以解释为什么有必要将数据保留更长的时间。在下列情况下,参考几周、几个月甚至几年前的数据通常很有用:
- 容量规划—通过查看过去 12 至 24 个月的资源利用率,您可以预测未来的使用情况,以便预测下一财年的预算需求。
- 性能下降—用户经常报告说,应用程序性能“似乎比几周或几个月前慢了”。手边有历史数据,就有可能量化任务需要多长时间,或者负载增加和性能降低之间是否存在关联。
在处理时间序列数据时,不可避免地会遇到无法无限期完整保留所有数据的情况。必须在数据保留时间、数据保留量和数据粒度之间进行权衡。本文介绍了如何在 InfluxDB 中实现数据保留策略,以确保您可以对数据进行降采样,将其保留一段指定的时间,并执行定期备份以避免数据丢失。
出于本例的目的,我们将关注运行在 3 台主机上的 收集的 系统守护进程收集的 CPU 利用率指标。在这个场景中, collectd 以 10 秒的间隔从每个被监控的主机提交 CPU 数据(“load_shortterm”)。使用 collectd 守护程序将数据直接发送到 InfluxDB,并存储在“指标”数据库中,该数据库使用 7 天保留策略进行定义。目标是将这些数据保留在“长期”数据库中,保留策略为 3 年。
InfluxDB 配置
默认情况下,InfluxDB 不监听 collectd 输入。为了允许由 collectd 代理提交数据,必须将 InfluxDB 服务器配置为侦听 collectd 连接。本节介绍如何在 RHEL/CentOS 系统上配置 collectd 。
第一步是在 InfluxDB 服务器上创建一个数据库,将传入的 collectd 数据存储 7 天。为此,在 InfluxDB 服务器上打开一个终端窗口,并使用influx
命令连接到服务器。运行以下命令创建新数据库:
CREATE DATABASE metrics WITH DURATION 7d
下一步是在 InfluxDB 服务器上安装 collectd ,以便 InfluxDB 可以使用 types.db 规范文件:
# Install the collectd RPM (available from the EPEL repo)
yum install collectd# Locate the types.db file installed by the RPM
rpm -ql collectd | grep types.db
更新 InfluxDB 配置文件(/etc/influxdb/influxdb.conf
)监听收集的数据,然后重新启动 influxd 服务:
[[collectd]]
enabled = true
bind-address = ":8096"
database = "metrics"
typesdb = "/usr/share/collectd/types.db"
一旦 InfluxDB 正在监听 collectd 输入,您将需要在 3 台主机上安装 collectd 代理,并将其配置为向您的 InfluxDB 服务器发送数据。
数据识别
如果您不熟悉 InfluxDB 数据模型,弄清楚如何定位数据可能是第一个挑战。被收集的每种类型的数据被称为“测量”,并且每个测量可以具有任意数量的与之相关联的“标签”。对于由 collectd 代理报告的数据,您配置代理报告的每种数据类型都有一个度量。
可在influx
命令窗口中执行以下命令,以查询数据库并识别将在后续步骤中用于定义连续查询的测量值。
# Switch to the InfluxDB database containing the CollectD data
USE metrics# Display a list of metrics in the database
SHOW MEASUREMENTS# Display the tags (keys) used to uniquely identify CPU load
SHOW SERIES FROM load_shortterm
SHOW SERIES
命令应该产生类似如下的输出:
load_shortterm,host=host1,type=load
load_shortterm,host=host2,type=load
load_shortterm,host=host3,type=load
数据保留政策
在 InfluxDB 中,有许多选项可用于定义长期保留策略。一种选择是在现有的metrics
数据库中创建新的保留策略,并将长期数据与短期数据一起存储:
CREATE RETENTION POLICY longterm_policy ON metrics DURATION 156w REPLICATION 1
但是,我会避免在单个数据库中创建多个保留策略,除非您有特别的理由这样做。如果单个数据库中有多个保留策略,那么在对数据进行操作时,您的查询将需要显式引用保留策略(database.policy.measurement
)。由于明确引用了保留策略,这将使您的查询更加脆弱。
此外,metrics
数据库中的输入数据是大量的瞬时数据。备份整个数据库的成本非常高,丢失一周的非常精细的数据所带来的影响也不值得。
更好的方法是专门为您希望保留的任何长期数据定义一个单独的数据库。这样做将便于以后更改保留策略或备份整个数据库,而不会影响任何外部报告或查询。以下示例显示了如何创建保留策略为 3 年(156 周)的数据库:
CREATE DATABASE longterm WITH DURATION 156w
数据聚合
创建一个连续查询,将数据从 10 秒的间隔向下采样到 15 分钟的间隔:
CREATE CONTINUOUS QUERY aggregate_load ON longterm
BEGIN
SELECT max(value) AS value
INTO longterm.autogen.load_shortterm
FROM metrics.autogen.load_shortterm
GROUP BY time(15m),*
END
重要提示:
- 您选择的聚合函数将取决于您的用例。在这种情况下使用了
max
函数,因为我们通常关心一个时间间隔内的*均峰值负载。使用*均值计算会稀释这些尖峰信号,并使识别活动中的短尖峰信号变得更加困难。 INTO
和FROM
子句要求完全合格的度量(数据库.策略.度量)。如果您将默认保留策略定义为数据库创建的一部分,如以上示例所示,则默认情况下,保留策略将被称为“自动生成”。GROUP BY
子句包含一个*
通配符,意思是“所有标签”这确保了仅在所有标签都相同的数据点上执行聚合。如果没有这个通配符(或一个显式的标记列表),将会对所有主机的所有数据执行聚合,从而导致一个无意义的聚合。在大多数情况下,应该在GROUP BY
中使用通配符,以确保在相同的唯一项目上执行聚合。- 上面显示的多行格式是为了可读性。当在
influx
命令中执行该命令时,您需要在一行中构建该命令。
一旦您成功地创建了一个连续查询,您应该会看到在第一个时间间隔结束时出现测量值。这可以通过列出测量值来验证,方法与您之前发现它们的方法相同:
USE longterm
SHOW MEASUREMENTS
SHOW SERIES FROM load_shortterm
下面的 Grafana 图表显示了原始数据(10 秒间隔)和聚合数据(15 分钟间隔)之间的差异。
Grafana chart of metrics.load_shortterm
Grafana chart of longterm.load_shortterm
数据备份
InfluxDB 附带了一个用于执行数据库备份的命令行实用程序。执行相当简单:
influxd backup -portable -database longterm /backup/longterm
可以指定附加参数,以通过特定的保留策略、碎片或日期范围来限制导出。
调试提示
默认情况下,InfluxDB 服务将其日志输出写入/var/log/messages
。每次连续查询运行时都会生成几行输出。以下命令可用于查找连续查询执行消息:
tail -f /var/log/messages | grep "Finished continuous"
匹配线看起来会像这样:
Jan 7 15:00:00 influxdbhost01 influxd:
ts=2019-01-07T20:00:00.127002Z
lvl=info
msg="Finished continuous query"
log_id=0BoYFF20000
service=continuous_querier
trace_id=0CrUFfTl000
op_name=continuous_querier_execute
name=aggregate_load
db_instance=longterm
written=129
start=2019-01-07T19:59:00.000000Z
end=2019-01-07T20:00:00.000000Z
duration=7ms
日志输出包含几条重要信息:
- 名称 —连续查询的名称
- 已写入 —已写入的测量记录的数量
- 持续时间 —查询执行的时间
显然,定义一个连续的查询,并安排其运行频率高于完成查询所需的时间,这不是一个好主意。
总结
连续查询是一种有选择地对数据进行降采样并将其保留更长时间的便捷方式。通过创建周密的保留策略和备份程序,可以将历史时间序列数据保留数月甚至数年。让这些历史数据在与实时指标相同的可视化界面中易于访问,将使应用程序所有者和运营人员能够基于历史背景和趋势做出明智的决策,而不是依赖“直觉”方法进行预算、容量规划或问题调查。
信息架构与商业本能
原文:https://towardsdatascience.com/information-architecture-vs-business-instinct-1188fbfb95a1?source=collection_archive---------17-----------------------
Photo by Saad Salim on Unsplash
为钢铁金属甲板经纪公司设计定制 CRM
安东内尔金属甲板公司是一家经纪公司,为东海岸的各种建筑项目提供金属地板和屋顶产品。作为利基但高利润业务的一部分,钢铁经纪公司围绕其产品波动的市场价格赢得和失去机会。因此,向客户提供准确、快速的报价是一个细致入微、竞争激烈的过程。
目前,安东内尔正在实施一个多年项目,通过集成技术解决方案来实现公司的现代化,这将使他们成为市场上速度最快、价格最优的钢铁经纪公司,并且他们已经开始获得指数增长。但是随着安东内尔期望增加收入,他们处理越来越多工作的能力已经成为一个问题。
该公司的总裁 Matt Weiss 具有产品管理背景,一直在为他的团队构建定制的 CRM 解决方案,以便他们可以更好地组织和简化他们的客户和项目管理记录。他的第一个 CRM 版本解决了许多关于联系人和公司信息组织的问题,但 Matt 在组织工作和报价记录时遇到了问题。
如何设计 CRM 中的记录,使其具有根本的灵活性、无定形性,并能对市场波动和独特的客户需求做出响应?
为了解决这个问题,我和另外两位 UX 设计师 Ben Throm 和 Melissa Glasser 加入了安东内尔 CRM 项目,进行为期两周的设计冲刺。我们开始寻找构建 CRM 信息架构的最佳方式,并设计记录和仪表板来跟踪安东内尔以项目为中心的业务。我们都以 UX 设计师的身份分享和合作,并在需要时将我们不同的背景带到桌面上来指导团队。我在这个项目中的背景是一年半的管理、定制和自动化初创环境中的 CRM 业务流程的经验,以及在公司收购后领导 CRM 迁移项目的经验。
研究
我们首先制定了一个时间表,先进行一周的研究,然后进行一周的设计。执行的研究方法有:
- 利益相关者访谈:对安东内尔金属甲板的所有销售和生产员工进行了 30 分钟的访谈(3)
- 背景调查:观察并记录员工的现场活动,以了解用户的日常体验,并记录常见的用户流程、业务流程以及在此过程中遇到的困难
- 竞争分析:记录了客户熟悉的领先 CRM 和系统的通用设计模式和信息架构,包括 Salesforce 、 SugarCRM 、 Pipedrive 和 Airtable ,以了解哪些可能解决安东内尔的问题,哪些可能解决不了
- 二次采访:采访了安东内尔以外的其他受访者(3 名),他们在太阳能安装、建筑和造船等相邻行业具有直接的项目管理经验,以获得关于用户可能的体验和痛点的更多见解
- 卡片分类:与安东内尔员工(2)一起进行,以发现和分析心智模型的差异和相似性,从而帮助确定信息架构
OMD Employees complete an Open Card Sort
综合
在第一周收集了尽可能多的数据后,我们在周末综合了我们的发现,为下一周的设计做准备。根据利益相关者和二次访谈,我们创建了一个亲和力图,并确定了关键挑战、目标和见解,以及常见的数据分类、行业工具和流程。
Affinity Map to Synthesis Stakeholder and Secondary Interviews
我们从最初的客户简报中得知,安东内尔处理三大类工作,我们从利益相关者访谈中更详细地了解了这些工作类型。这三种类型是:
- 货场订单:客户从安东内尔的现有库存中订购材料,并提取或交付
- 特殊订单:客户有独特或意想不到的需求,除了典型的堆场订单之外,还需要额外的流程
- 合同订单:客户是一个承包商,他需要根据项目特定的建筑图纸进行报价,并在整个生产过程中得到安东内尔项目经理的支持
为了设计这些工作的 CRM 记录,我们需要了解处理每种类型工作的所有移动部分,包括安东内尔员工与客户直接互动之外的方面。这些方面主要与安排和跟踪供应商和运输合作伙伴关系有关。我们首先勾勒出每种工作类型的业务流程,以记录安东内尔与其供应商、运输伙伴和各种客户的关系是如何交织在一起的。然后,我们勾画了一个安东内尔员工创建和更新每种工作记录的典型路径的用户流。
Sketching Business Processes and User Flows
接下来,我们通过在白板上绘制两种心理模型并比较他们的思维方式,综合了卡片分类的结果。
Sketching Business Processes and User Flows
参与者的心理模型之间有一些相似之处,例如将熟悉的名字归入“供应商”和“公司”等类别一些卡片也能被两个参与者立即识别出属于预先定义的类别,如“状态/销售阶段”
综合卡片分类也显示了两个雇员在如何分类与其工作相关的信息方面的一些差异。第一个参与者将卡片分为两级,15 个分类标题,第二个参与者将卡片分为三级。第二个参与者也以一种关联的方式安排分组,其中分组根据它们如何相互关联而彼此相邻,讲述了更多关于他在工作中遵循的过程的故事。这些差异的一个可能原因是,第一个参与者主要参与客户报价和处理售前互动,而第二个参与者是一名项目经理,负责生产流程中最复杂的工作。
总的来说,卡片分类对于确定 CRM 的信息架构来说,并不像我们希望的那样有价值,这有两个主要原因。首先,我们只有两个参与者,就像我们的利益相关者访谈一样,这一小群人无法得到帮助。其次,要分类的卡片数量(约 50 张)以及我们从哪里获得这些字段名(各种 OMD 内部工具)使得参与者很难分组并理解如此多的重叠信息。将来更好的方法是,只从一个引用(如团队的 Airtable 电子表格)为层次结构中最深层的字段制作卡片。
设计和测试
在综合我们的研究之后,我们使用我们的用户流、业务流程图和安东内尔提供的低保真度线框作为参考来构建作业记录的纸质原型。我们在现场测试了纸质原型,然后在白板上一屏一屏地讨论了我们收到的反馈。
Paper Prototype: Testing and Planned Changes based on Feedback
反馈也收集在一个电子表格中,我们在其中定义了需要进行的更改。然后,我们将这些变化整合到 Balsamiq 中构建的低保真度线框原型中。
Low Fidelity Wireframe Prototype
接下来,我们回到网站,与安东内尔的员工一起进行可用性测试。这些测试更深入地了解了什么样的页面布局对团队来说是最直观的。从这些测试中,我们决定摆脱标签结构,我们实现这种结构是为了将工作的不同阶段分开,支持用户可以滚动页面以找到他们在工作流程中任何给定时刻需要的位置。虽然这可以防止字段被隐藏起来,很难找到,但在较长的滚动页面上,字段应该如何精确布局还存在不确定性。哪些字段是最重要的,作为一种设计技术,接*度应该如何应用,从而以对用户有意义的方式对字段进行分组?
为了回答这些问题,我们回到我们的研究,并努力完成信息架构。我们的队友 Ben 拥有信息技术和数据库架构的背景,他介入并绘制了一个实体关系图来定义 CRM 中不同实体之间的关系,并显示每个实体中的字段。
Entity Relationship Diagram
接下来,我们作为一个小组进行了头脑风暴,并用白板演示了职务记录中的字段如何相互关联和/或归属于一起的概念图,以确定职务记录的页面层次结构。最后,我们就 CRM 的导航层次达成了共识,并绘制了一张地图,作为在 Axure 中构建最终原型的参考。
Hierarchy for Navigation, Filtering, and Fields on the Job Record Page
有了这些指导方针和我们的低保真度可用性测试的反馈,我们开始构建一个中等保真度的交互式原型,它将允许用户在列表视图中过滤作业,创建新的作业记录,并向作业记录添加输入。这很有挑战性,因为我们必须为用户创建自定义作业记录所需的大量相关选项构建逻辑。
最后,作为最终外观的参考,我创建了一个高保真的工作记录页面模型:
High Fidelity Mockup of the Job Record Page
要点和后续步骤
我的团队向 Matt 提供了一个产品路线图,以集中精力继续开发安东内尔 CRM,建议将特定角色的仪表板作为下一个高影响力/低工作量目标,以便用户可以立即获得他们工作的鸟瞰图。接下来,我们建议解决将报价评估工具直接集成到 CRM 中的高影响/高工作量目标。最后,应跟踪客户跟进和机会损失原因,然后开发 CRM 中的报告功能。
在向客户展示了我们的研究、原型和未来产品愿景后,我们都被要求继续合同项目。当我们开始安东内尔 CRM 项目的下两周冲刺时,我们将为销售代表和项目经理的角色设计定制仪表板,并继续测试和改进工作记录页面。对于这个 sprint,我和我的队友们正在分工,我的重点是为安东内尔项目经理设计一个定制的仪表板。
从这个项目的第一次冲刺中,最大的收获是,当数字化一个已经在纸面记录、内部化的机构知识以及关于谈判和市场价格的良好直觉上运行了几十年的业务时,设计师面临着巨大的挑战。设计中经常有一种倾向,认为一致性、简单性和自动化总是能提供最好的体验。但作为一名设计师,这是一种不稳定的心态,因为某些业务的某些方面永远是不可预测的、被动的、抗拒秩序和分类的。把所有东西都整齐地收好并不总是最好的。
随着我作为一名设计师的成长,我希望构建支持和增强人类互动的工具,以推动业务关系,而不是通过试图在一个整洁的盒子中放置太多东西来阻碍它们。让一些事物保持有机和可变是可以的。有时候,那种机会感和兴奋感是用户首先做他们正在做的事情的动机。
信息民主,通过协调愿景建立对数据的信任
原文:https://towardsdatascience.com/information-democracy-build-trust-in-data-by-aligning-the-vision-9e311c6dfc10?source=collection_archive---------31-----------------------
如何构建能够促进组织发展的最佳一致且可扩展的信息产品
为组织提供数据,使其成为数据驱动型组织,这听起来是显而易见的。但是当涉及到将业务目标与数据结合起来时,事情就变得有点复杂了。正是在这个时候,大数据、数据湖和非结构化数据等术语开始出现,只是作为一种表达组织无力应对不断流动的数据的方式。
许多组织都坐在一堆数据上。没有正确的语义,这些数据是没有价值的。分析这些数据可能需要一些数据科学家来清理和标记数据,以努力找到一些重要的见解。一些组织甚至会为业务用户提供自助式 BI 工具,直接插入数据堆。新的特别发现见解现在可以“生产化”,例如,可以在机器学习算法中实施,以分析大量数据,并处理所有新生成的实时流数据。
但是,我们如何确保这些见解与组织的战略目标相一致呢?数据科学家应该在会议室中详细阐述机器学习模型,还是应该简单地通过 KPI 仪表板中的性能指标来监控算法?这两个选项都不能确保我们总是谈论完全相同的度量,但是我们是如何得到那个度量的呢?我们真的只是碰巧发现了我们业务的一些东西吗?
通用业务逻辑是分析的重要起点。构成洞察的预定义且记录完善的业务指标。当您拥有一个包含业务逻辑的语义层时,您将能够将度量标准与战略目标保持一致。这将有助于初步处理数据,从长远来看,有助于理解如何处理各种各样的数据。
以下步骤提供了实现这种对齐的一些粗略指南:
- 写下愿景—使用业务目标制定清晰的数据战略(愿景)来支持业务。从那里,您可以选择与愿景一致的技术。
- 集中所有数据—将所有数据集中存储在您的逻辑数据仓库中。这将为您提供所有可用数据源的良好概览。
- 定义业务逻辑—讨论如何使用可用数据,以及在理想情况下如何使用这些数据。考虑如何通过连接多个数据集来丰富数据。
- 根据愿景对数据建模—构建支持业务目标的模型。定义从业务角度来看有意义的指标和 KPI。确保派生的指标总是可以追溯到基线指标。
通过遵循这些指导方针,你将开始建立一个新的单一来源的真相。所有数据现在都将被转换成可靠的指标,因为在整个业务中只有一个一致的定义。在构建这些指标时,承认业务视角有助于验证这一点,从指标中获得的洞察力正是我们现在正在谈论的。我们对数据有了基本的理解。
在整个业务中保持一致的单一定义。
当用户访问这些指标时,他们会立即感到熟悉。他们最终可以依靠数据来推动决策。但是最好的部分是,从这个逻辑业务模型层,您还可以向更广泛的受众提供您的指标。它使组织能够共享他们对数据的看法。
有了这个单一来源的可信事实,您就可以开始在您的组织中促进信息民主了。在一个经过治理和良好设计的环境中为用户提供自助式 BI 将会建立他们的信任。从业务角度了解您的数据,您就可以尽可能构建最好的信息产品。随着数据仓库现在完全支持您的组织的战略目标,您现在可以真正成为数据驱动的。
金融机器学习的信息驱动棒线:不*衡棒线
原文:https://towardsdatascience.com/information-driven-bars-for-financial-machine-learning-imbalance-bars-dda9233058f0?source=collection_archive---------1-----------------------
Photo by Javier Allegue, at Unsplash
在之前的文章中,我们谈到了分笔成交点、成交量棒线和美元棒线,它们是替代类型的棒线,允许根据分笔成交点的数量、成交量或交易的美元价值进行市场活动相关的采样。此外,我们还看到了与传统的基于时间的条形图相比,这些条形图如何显示更好的统计属性,例如更低的序列相关性。在本文中,我们将讨论信息驱动棒线,特别是不*衡棒线。这些棒线旨在提取编码在观察到的交易序列中的信息,并通知我们交易不*衡的变化。不*衡变化的早期检测将允许我们在达到新的*衡之前预测趋势的潜在变化。
不*衡棒背后的概念
Lopez de Prado 在他的书金融机器学习的进步 (2018)中首次在文献中描述了不*衡棒。用他自己的话说:
信息驱动棒线的目的是当新信息到达市场时更频繁地取样。[……]通过使取样与消息灵通的交易者的到来同步,我们也许能够在价格达到新的均衡水*之前作出决定。
不*衡棒线可以应用于分笔成交点、成交量或美元数据,分别生成分笔成交点(TIB)、成交量(VIB)和美元(DIB)不*衡棒线。成交量和美元棒线只是分笔成交点棒线的扩展,因此在本文中,我们将主要关注分笔成交点不*衡棒线,然后我们将简要讨论如何扩展它们来处理成交量或美元信息。
不*衡棒线背后的主要思想是,基于交易序列的不*衡,我们产生一些预期或阈值,每当不*衡超过阈值/预期时,我们就对棒线取样。但是我们如何计算不*衡呢?我们如何定义门槛?让我们试着回答这些问题。
什么是蜱不*衡?
给定一个交易序列,我们应用所谓的分笔成交点规则来生成一个签名分笔成交点列表(bt)。你可以在公式 1 中看到刻度规则。基本上,对于每笔交易:
- 如果价格高于上一笔交易,我们将签字分笔成交点设为 1;
- 如果价格比前一次交易低,我们将签字分笔成交点设为-1;
- 如果价格与上一笔交易相同,我们将签字分笔成交点设置为与上一笔签字分笔成交点相同。
Formula 1. Tick rule to define signed ticks [1,-1]. pt is the price of trade t and delta-pt is the increment in price respect p(t-1). b(t-1) is the signed tick at t-1.
通过应用分笔成交点规则,我们将所有交易转换为有符号分笔成交点(1 或-1)。这个 1 和-1 的序列可以相加(累计和)来计算市场在任何时间 t 的不*衡程度(公式 2)
Formula 2. Cumulative sum of signed ticks up to time T.
带符号的分笔成交点不*衡背后的直觉是,我们想要创建一个指标来查看有多少交易是朝着“高价”方向(+1)或“低价”方向(-1)完成的。在分笔成交点不*衡的定义中,我们假设,一般来说,如果有更多的消息灵通的交易者相信某个特定的方向,就会有更多的分笔成交点朝向某个特定的上涨/下跌方向。最后,我们假设有更多的消息灵通的交易者朝着某个特定的方向出现,这与信息的到来(如有利的技术指标或新闻发布)相关联,这些信息可以引导市场达到新的*衡。不*衡棒的目标是尽早发现这些信息的流入,这样我们就能及时得到潜在交易机会的通知。
我们如何设定门槛?
在每个不*衡棒线的开始,我们查看旧的有符号分笔成交点序列,并通过计算指数加权移动*均(EWMA)来计算有符号分笔成交点序列向 1 或-1 的不*衡程度。最后,我们将 EWMA 值(预期的不*衡)乘以预期的棒线长度(分笔成交点的数量),结果是我们的带符号分笔成交点的累积和必须超过的阈值或预期(绝对值),以触发新蜡烛线的采样。
我们如何定义分笔成交点不*衡棒线?
在数学术语中,我们将分笔成交点不*衡棒线(TIB)定义为满足以下条件的连续分笔成交点子集:
Formula 3. Tick imbalance bar definition.
直观的例子
让我们看一个直观的例子:
Figure 1. Example of tick imbalance bars for the BTC-USD pair.
在图 1.1 中,您可以看到大约。从 2017 年 1 月 31 日开始,在 Bitfinex 交易所对 BTC-美元进行 5000 笔交易(来源: CryptoDatum.io )。
在图 1.2 中,你可以看到我们是如何应用分笔成交点规则并转换 1.1 中的所有交易的。转换成带符号的刻度(1 或-1)。请注意,有超过 5000 个带符号的分笔成交点,并且大多数时候它们是相互重叠的。
在图 1.3 中,我们将指数加权移动*均(EWMA)应用于整个有符号分笔成交点序列。我们可以观察到产生的 EWMA 是一个介于-1 和 1 之间的随机振荡波,它表示正负符号分笔成交点的总体趋势/频率。
如图 1.4 所示。我们用红色显示在公式 3 的最后一项中计算的阈值或期望值。该阈值在每个条形的开始处计算。请注意,在图中,我们显示了正阈值和负阈值,但实际上,由于我们使用绝对值(公式 3),所以我们只关心正阈值。蓝色表示每个特定时间点的有符号分笔成交点的累计总和。请注意,累积和会振荡,直到达到阈值下限或上限,在该点对新蜡烛线进行采样,累积和被重置为 0,并且基于该特定点的 EWMA 失衡计算新阈值(期望值)。
最后,在图 1.5 中,我们表示生成的分笔成交点不*衡棒线。
实施和意见
如果您遵循了上面的解释,您可能会想知道:
- TIB 的具体实现。
- 如何计算「预期蜡烛尺寸」?
要回答问题 1,请参考这个 Github 问题,以及父库。它们为理解和实现 Python 中的分笔成交点不*衡条提供了很好的入门内容,但是要小心错误和对 TiB 的不同解释。
在同一期 Github 中,对问题 2 进行了彻底的讨论。Lopez de Prado 的官方定义指出,预期蜡烛线大小,很像时间 t=1 时的“预期不*衡”,应该作为先前棒线的 T 值的 EWMA 来计算。然而,根据我的经验,就像线程中的其他人一样,在几次迭代之后,条形的大小最终会爆炸式增长(非常大,有数千个刻度)。原因很简单:随着阈值的增长,需要越来越多的有符号分笔成交点来达到阈值,这反过来又使“预期蜡烛线大小”在正反馈循环中增长,不断增加蜡烛线大小,直到无穷大。我尝试了不同的解决方案来解决这个问题:(1)限制最大值。蜡烛尺寸和(2)固定蜡烛尺寸。事实证明限制最大值。例如,将蜡烛大小设置为 200 会使所有预期的蜡烛大小在几次迭代后都变为 200。因此,这两种解决方案的效果都不明显,遵循奥卡姆剃刀原理,我选择了最简单的一种(解决方案 2)。由于现在蜡烛线的大小变成了一个需要考虑的变量,在 CryptoDatum.io 中,我们决定为三种不同的蜡烛线大小提供分笔成交点不*衡棒线:100、200 和 400。
我解释阈值和蜡烛线大小的方式是一种“挑战”。每当你在一根棒线的开始设定一个新的期望/阈值,我们都在挑战时间序列,以超越我们的期望。在这些“挑战”中,蜡烛大小成为又一个参数,允许我们指定我们希望这个挑战“有多大”。如果我们选择一个更大的蜡烛尺寸,我们实质上是增加了“挑战”的难度,结果,我们将得到更少的棒线样本,尽管原则上,有更高的意义。
成交量和美元不*衡棒线
到目前为止,我们只讨论了分笔成交点不*衡棒线。事实证明,生成成交量和美元棒线是微不足道的,它只涉及在公式 2 中添加最后一个乘法项:要么是成交量(在成交量不*衡棒线的情况下——VIB),要么是美元/法定价值(在美元不*衡棒线的情况下——DIB)。
统计特性
正如我们对分笔成交点、成交量和美元棒线所做的那样,我们将研究两个统计特性:(1)序列相关性和(2)回报的正态性。我们将通过运行移位序列(shift=1)的皮尔逊相关检验来分析第一个,并通过运行正态性的 Jarque-bera 检验来分析后者。
让我们来看看皮尔逊相关检验:
Figure 2. Pearson correlation of the shifted series of returns (shift=1)
与其他替代棒线(分笔成交点和成交量棒线)类似,不*衡棒线的总体自相关性低于传统的基于时间的蜡烛图。正如我们在原始文章中解释的,这是一个很好的特性,因为这意味着数据点更加相互独立。
现在让我们来看看 Jarque-Bera 正态性检验:
Figure 3. Jarque-Bera normality test
我们拒绝不*衡棒线和时间棒线的正态性的零假设。不管是好是坏,这并不令人惊讶,因为结果与我们在以前的文章中看到的一致。
我们学到了什么?
- 不*衡棒线是通过观察资产价格的不*衡产生的。
- 不*衡由带符号刻度的累积和的大小来衡量。
- 通过应用记号规则计算有符号记号。
- 每次不*衡超过我们的预期(在每个条形开始时计算)时,对条形进行采样。
- 不*衡棒的目的是在达到新的*衡之前,尽早发现市场方向的变化。
- 与传统的基于时间的蜡烛图和结果的非正态性相比,不*衡条显示出更低的自相关性。
这个项目是我们在cryptodatum . io研究的一部分,这是一个加密货币数据 API,旨在提供即插即用的数据集来训练机器学习算法。如果您喜欢我们在本文中展示的数据,您可以在https://cryptodatum . io获得免费的 API 密钥并亲自使用它
信息熵
原文:https://towardsdatascience.com/information-entropy-c037a90de58f?source=collection_archive---------7-----------------------
信息论的外行介绍
如果你看我过马路,或者看我玩俄罗斯轮盘赌,哪一个会更刺激?可能性是一样的——我活着或者死去,但是我们都同意过马路有点无聊,俄罗斯轮盘赌……也许太刺激了。这部分是因为我们非常清楚当我过马路时会发生什么,但是我们不知道在俄罗斯轮盘赌中会发生什么。
从另一个角度来看,我们观察过街的结果比从俄罗斯轮盘赌中获得的信息要少。一种正式的说法是,俄罗斯轮盘赌游戏比过马路有更多的“熵”。熵被定义为“缺乏秩序和可预测性”,这似乎是对这两种情况之间差异的恰当描述。
信息什么时候有用?
信息只有在可以存储和/或交流时才是有用的。当我们忘记保存正在处理的文档时,我们都有过惨痛的教训。在数字形式中,信息存储在“位”中,或者是一系列可以是 0 或 1 的数字。键盘上的字母存储在一个 8 位的“字节”中,这允许 2⁸ =256 种组合。重要的是要知道,信息存储和通信几乎是一回事,因为你可以认为存储是与硬盘的通信。
Examples of symbols and their 8 digit codes
信息存储
数学家克劳德·香农洞察到,一些信息越可预测,存储它们所需的空间就越少。过马路比俄罗斯轮盘赌更容易预测,因此您需要存储更多关于俄罗斯轮盘赌游戏的信息。香农有一个概率分布“熵”的数学公式,它输出*均存储其结果所需的最少比特数。
熵
Formula from entropy from Wikipedia
以上是计算概率分布熵的公式。对于分布中所有可能的结果,它涉及以 2 为基数对 P*log(p)求和。Python 中有一个函数可以做到这一点:
import numpy as np
def entropy(dist):
su=0
for p in dist:
r= p/sum(dist)
if r==0:
su+=0
else:
su+= -r*(np.log(r))
return su/np.log(2)
例如:俄罗斯轮盘赌
如果我们将过马路的例子量化为十亿分之一的死亡几率,将俄罗斯轮盘赌量化为二分之一,我们将分别得到熵([1,999_999_999]) ≈ 3.1*10^-8 比特和熵([50,50])=1 比特。这意味着,如果我们将这两个实验重复一万亿次,那么至少需要 31000 位来存储过马路的结果,需要 1 万亿位来存储俄罗斯轮盘赌的结果,这符合我们早先的直觉。
Some distributions and their entropies
例如:英语
英语有 26 个字母,如果你假设每个字母有 1/26 的概率是下一个,那么英语的熵是 4.7 比特。然而,一些字母比其他字母更常见,一些字母经常一起出现,所以通过巧妙的“猜测”(即不分配 1/26 的概率),我们可以更有效率。
随机猜测*均花费我们 13.5 次猜测来得到正确的字母。假设我们得到了这个句子中每个单词的第一个字母:
h _ _/A _ _/Y _ _/D _ _/M _/F _ _?
如果我们花了 13.5*16=216 次猜测来填充 16 个空格,那就非常糟糕了。我们很可能会用*均不到两次的时间就猜出这个句子是“你好吗,我的朋友?”。因此,即使我们详尽地猜测第一个字母,花了我们 13.5 次猜测,也要花我们大约 5.1 次猜测/字母来填补所有的空白,这是对随机猜测的巨大改进。
香农的实验表明,英语的熵在 0.6 到 1.3 比特之间。从这个角度来看,3 面骰子的熵为 1.58 位,*均需要 2 次猜测来预测。另外,请注意,键盘上的编码系统使用每个字母 8 位。因此,从理论上讲,它可以使所有只有英语语言的文件缩小至少 6 倍!
应用程序
香农的工作在数据存储、宇宙飞船通信、甚至互联网通信中得到了应用。。即使我们不在这些领域中的任何一个领域工作,“KL divergence”也是从 Shannon 的工作中衍生出来的一个想法,它经常被用于数据科学中。它通过比较熵来告诉你一个分布在估计另一个分布时有多好。
信息的交流和存储让人类变得伟大,香农的工作彻底改变了我们在数字时代的交流和存储方式。
分析 Twitter(自我)社区内的信息流
原文:https://towardsdatascience.com/information-flow-within-twitter-community-def9e939bb99?source=collection_archive---------15-----------------------
主题建模以理解 Twitter 社区中的信息主题和用户角色
重要提示:请下载此笔记本文件并在浏览器中打开 。
这将有助于你理解,因为很多图表都是交互式的。(也就是说,你可以随意使用它们,放大、缩小、保存、更清晰地查看标签等。)
Figure 0.0: Twitter Community Detection
在这个项目的第一阶段,我从更好地理解用户的 twitter 世界的动机开始。处理社交网络的复杂性,最初阶段需要我们在分析信息流的基础上,将用户的影响——Twitter 的“朋友”——捆绑到社区中。我们试图将信息“持续存在”的用户群聚集在一起,这表明想法、思想等的循环。围绕着自我使用者(在这种情况下就是我自己)曾经“追随”过的某个焦点。这种方法强调社交媒体的信息共享属性,将每个用户视为一个“节点”,向其他节点传送和生成信息。在练习结束时,我们已经完成了一个相对的空间映射,这有助于我们将潜在 Twitter 世界中的信息网络可视化【图 0.0】。也就是说,我们已经追踪到了“哪里”——实现了我们所关注的用户在众目睽睽之下举行的秘密会议(隐藏在巨大的流量中)。这样一个情报网络的发现不可避免地引发了下一个好奇:流动的到底是什么?换句话说,在这些社区中有哪些信息在流动和持续?
信息系统和数据科学经常在社交媒体分析领域携手合作。允许它们结合的是自然语言处理(NLP) 领域,处理语言通常需要某种形式的量化,因此我们可以在用数学折磨信息之前对其建模。对于这个项目,我将研究一些标准的 NLP 方法来量化和“观察”文本信息(tweets)。接下来是对各种关系的一些分析和绘图,我们可以用它们来对社区概况进行一些描述性的推断。
这个职位有两个更高的目标:
- 向所有人(技术人员和非技术人员)介绍将社交媒体文本信息作为数据处理的一些基本知识——可能有助于他们了解他们的数据如何被分类使用。甚至可能引入一些隐私问题……
- 为了探索我们可以从自然语言处理中获得的结果的质量,特别是在基于 Twitter 信息的社区环境中
- 为了获得以数据为中心的视图,了解这个社区作为一个整体以及单个用户向根用户(在本例中是我)提供了什么
我们将讨论什么
1.量化信息(术语频率和命名实体)
2.发现推文中的话题
3.建立用户档案(基于他们的 tweet 内容和在公共信息流中的角色)
范围和数据
我将在这篇文章中分析社区内的属性,而不深入社区间分析所获得的见解。这意味着,我们一次只关注一个社区。为了展示整个流程,我将使用第一阶段中我的社区#6,一个由来自不同领域和兴趣的年轻穆斯林组成的社区[图 1.0] 。回想一下,这是一个“主观”分析——组成这个社区的用户群只是我从更广泛的社区中关注的用户的子集。从这个意义上说,这个社区是一个更大的社区的样本——这意味着洞察力可以很好地转化,但不一定完全准确。
**Side Note:** I have actually begun to follow more people that I would say are from the 'Muslim Community' since I collected this data... but they will (unfortunately ?) not be included in this analysis as this is building off my algorithmically-found ego-community.
Figure 1.0: Community #6 — The Infamous Muslim Community (Blue)
此外,由于我们再次关注信息的“流动”,我们将只查看在社区中“流动”的推文——我将其*似为在社区中被转发不止一次的推文。这些推文分为两类:
社区内流 —由社区内的某个人生成(最初发布)的推文,然后由社区内的某个人传播(转发)。
社区外流量 —由不在社区内的用户生成,然后由社区内的某个人传播的推文。
Figure 1.1: Information Flow Ratio
图 1.1 显示了流量比率的周分布,表明每周,在社区内传播的推文由社区外产生的推文组成,比社区内产生的推文多 10-25 倍。这可以看作是社区的社会属性。
Flow Ratio: #ofRTsGeneratedOutside/#ofRTsGeneratedWithin
下图 1.2 显示了该分析将关注的几周信息流。请注意,对于任何给定的用户,可以从 twitter 获取的最大 tweets 数量是大约 3200 条。因此,如果一个用户在一年中发了超过 3200 条推文(包括引用和转发),我们不会拥有他们 2018 年的所有推文,所以分布有点偏斜,但外部和内部流之间的差异是显而易见的。
Figure 1.2: Tweet Data Timeline
流的这种分类导致对用户的进一步分类,以服务于社区内的 3 种角色的混合:
生成者——作为在社区内发布信息的人。(创建信息)
内部 传播者 —将社区成员生成的信息传播(转发/引用)给社区内其他用户的人。(在社区内传播信息)
外部 传播者 —将非社区成员生成的信息传播给社区内用户的人。(将外部信息带入社区)
当然,一个用户可以担任不同数量的多个角色,我们稍后将对此进行分析。
最后,推文也被分类,但以一种更复杂的方式。每条推文都经过预处理,以清除用户提及、标签、网址、媒体等。直到我们有了他们的原始文本,我们可以使用突出的文本处理库(在这个例子中是 spacy )来标记和标注推文。图 1.3** 是我们以这种方式从预处理文本中获得的数据样本。**
Tweet = "Happiness is a category of slaves"
Figure 1.3 Sample Tweet Processing
信息提取
单词不仅仅是单词,而是数字
词语从来都不是“唯一的词语”,它们很重要,因为它们定义了我们能做什么的轮廓。—斯拉沃热·齐泽克
为了开始我们的研究,重要的是回到基础,回到携带信息的单位:单词。说到提到的齐泽克的话,发现“词”就是定义“轮廓”:约束社区的形状的表面边界(我承认我完全盗用了他的说法来为自己谋利,我只能相信他会为此感到自豪)。这在一个领域似乎非常明显(文字携带信息……咄),但在信息系统领域变得更有意义,因为它有助于回答一个关键问题:我们如何量化“信息”?答案*乎稚气:靠‘数’字。****
****重要提示:请记住,我们所有的分析和见解都是与时间相关的,它们仅表明社区在我们拥有其推文历史的时间范围内的行为(粗略地说,是 2018 年)。
让我们看看这些频率,并画出一些更重要的术语【图 2.1】。让我们也具体看看“命名实体”(NE) 【图 2.2】。如何看待这些图表:
- ****中红色的“内部流程”中的术语频率
- ****中蓝色中“外流”一词的出现频率
- x 轴是频率(即 0.1 = 10%)
- ****编号标签是术语在相应流中的排名(即 1 =特定流中出现次数最多的术语)
- 图表按“等级差异”排序,暗示:
- 靠*顶部的词是在外流中出现最显著的词,在内流中出现不那么显著
- 中间的单词在两个流中同样重要
- 靠*底部的词是在内流中出现频率较高的词,在外流中出现频率较低
Figure 2.1: Comparing Terms across Flows (Blue=OutsideFlow, Red=WithinFlow)
Figure 2.2: Comparing Named Entities across Flows (Blue=OutsideFlow, Red=WithinFlow)
数字背后的含义
我们如何从上述数字中提取洞察力?我会指出一些,剩下的让你记下来。
样本读数:
- 【穆斯林,伊斯兰,穆斯林,伊斯兰】 是两个流中出现频率较高的新词,也是总体上出现频率最高的一些词——可能指向该社区的主要讨论点或身份。
- 【自由主义、意识形态、女权主义、资本主义、自然……】是一些可以在图 2.1** 底部附*找到的主要术语——它们在内向流动中比外向流动中更重要,这意味着社区倾向于围绕这些术语在自身内部生成信息,而不是从外部输入信息。**
- 【Trump、学生、学校、攻击……】是在图 2.1 和 2.2** 顶部附*找到的一些术语——该社区围绕这些术语传播的信息更多地是从社区外部生成的(很可能与分享新闻有关)**
- 【伊斯兰教法、十一辩经、古兰经、陀思妥耶夫斯基……】是在图 2.2** 底部附*发现的一些术语——围绕这些实体的重要信息在社区内产生并传播。有趣的是,陀思妥耶夫斯基可能看起来是这个列表中的一个奇怪的人,但追踪它会突出社区内部某篇文章的产生和传播:**
"On the heels of the horrific Pittsburgh synagogue massacre guest contributor examines Dostoevsky's predictions about ideological radicalization and asks what shapes the psychology of the modern terrorist" - @TraversingTrad
[https://traversingtradition.com/2018/10/29/dostoevskys-strange-ideas-and-the-modern-terrorist/](https://traversingtradition.com/2018/10/29/dostoevskys-strange-ideas-and-the-modern-terrorist/)
查看该数据的另一种方式(如果点不多且标记清晰)是在散点图中,其中轴是来自不同流量的相对频率(对数标度)【图 2.3】。下面的图是针对命名实体的,描述了我们上面所做的一些分析(例如请注意图表右上角的[ 穆斯林、穆斯林、伊斯兰教、伊斯兰教] 等术语,表示外流和内流的重要性)
Figure 2.3: Named Entity Scatter Plot
本着与上述观点相同的精神,我们可以继续提取更多有助于定义社区的比较属性。然而,尽管这项工作可能证明是有价值的,但当我们意识到这项任务的乏味时,我们的精神最终会衰退。我们也将开始认识到一些不准确之处,并开始问一些问题,比如‘等等,这个术语真的很重要吗,或者它只是因为与另一个术语相关而出现,而另一个术语才是真正重要的术语?’?".这让我们更深入——我们不只是想要一堆单词,我们想要真正了解所有这些单词代表什么的关键。如果单词定义了这个社区的轮廓,我们现在想得到轮廓的“潜在来源”——是什么“导致”这些术语出现?这就是主题建模的 NLP 技术背后的动机。****
主题建模和分析
主题术语简介
简而言之,主题建模采用由各种“术语”(推文中的单词)组成的“文档”(在我们的例子中是推文)集合,并找到 N(主题的数量)个唯一的加权策略来应用于术语,使得每个“文档”被分类到 N 个主题的混合中。有许多关于这方面的教程和细节你可以搜索,所以我就不赘述了。具体来说,我使用 TF-IDF 对推文进行了矢量化(基本上是量化),然后使用 LDA 来找到“主题”。图 3.1** 描绘了我们在 WithinFlow 中的最终主题。这种方法不能让我们很好地了解社区围绕主题的“观点”,而只能了解主题是什么——我们知道他们在谈论什么,但不一定知道他们对此的看法。(尽管更复杂的分析当然也可以评估意见——我们稍后在讨论极性和主观性时会看到一个小例子。)**
*There are many other terms that have a weight associated to them from one or more of the topics but I have only included some of the more significant ones for readers to get an idea of what the topic 'means'.*
Figure 3.1: Topic Models (term based from WithinFlow)
Figure 3.2: Topic Names
图 3.1 中气泡的大小表示术语(在 y 轴上)对主题的‘权重’(即,WithinFlow 中的主题 1 将“文章作为其最重要的术语)。如果我们在每个主题中取 7 个最重要的术语,我们会得到每个主题的术语摘要【图 3.2】。然后,我们可以采用相同的主题模型,并将其应用于外部信息流,以查看主题权重在来自社区外部的信息流中的比较情况。图 3.3 显示了两个流的主题权重的比较。**
Roughly speaking, I can vaguely see some specific topics popping out:
Philosophy (#6),
Feminism / Women Studies (#4),
Ramadan (#5),
Statehood / Muslim-Related Politics (#3),
Prophetic Sayings (Hadith) + Religious anecdotes (#2),
Article Sharing (#1)The others still make sense but seem to be a mix of things.
Figure 3.3: Topic Weights (Blue=OutsideFlow, Red=WithinFlow)
虽然我们已经将术语聚集到主题中,但我们需要更上一层楼,看看这些主题如何模拟整个推文。
话题-推文简介
每条推文都被赋予一个权重,构成一个话题向量。然后,我们可以在 topicVector 上进行一些特征缩减后,在空间上将推文映射到二维空间。我们可以看到形成的集群以及与任何特定主题都没有太大关联但在相对空间中位于它们之间的推文。图 3.4** 可视化 WithinFlow 的推文和聚类(如果您 下载笔记本文件 ,您可以将鼠标悬停在(并放大)每个点上,并探索每个点对应的推文——将鼠标悬停在不同的聚类上将向您显示哪些“种类”的推文有助于我们的主题!).**
Note that the size of the circles (each circle = a tweet) represent the tweet's weight for their respective topic — the larger circles are on the outskirts, meaning those tweets are more closely related to their respective topics. It's as if the ‘latent’ topic sources surround the overall information flow.
Figure 3.4: WithinFlow Tweets Visualization in Reduced Topic Space
我们可以看到孤立的聚类是紧密围绕各自主题的推文,但其他推文分散在其他主题中(例如,一条推文可能 10%是主题 1,40%是主题 2,50%是主题 3,等等)。“环”中间的推文是权重较低的多个主题的混合,因此不会孤立成一个集群。这些推文可以被解释为不属于任何主题,或者很难分类——尽管如此,它们仍然是离群值。
我们还可以将我们的主题模型应用于外部流程,如图图 3.5** 所示。我们在外向流推文集群中看到更多的混合和更少定义的边界——这是意料之中的,因为通常来自外部的信息不会像内部传播那样定义明确。我们再次鼓励你打开笔记本文件,将鼠标悬停在不同的集群上,感受一下这些集群代表了什么,以及哪种推文导致了集群混淆。**
Figure 3.5: OutsideFlow Tweets Visualization in Reduced Topic Space
话题盈利能力
使用主题权重,我们可以通过选择权重最大的主题,将每条推文归类到特定的主题中。然后,我们可以分别可视化每个流量中每个主题的转发计数(该推文被转发的次数)分布——通过这种方式,我们可以衡量我们主题的“盈利能力”属性。图 3.6** 中的每个图表显示了每种信息流的转发次数分布(蓝色=内流,橙色=外流)。这些分布给了我们一个概率上的概念,关于这个话题的一条推文有多少转发。**
Note that the x-axis is log10 scaled (i.e. 2 = 100 retweets, 3 = 1000 retweets, etc.). This means even slight differences between the distributions in the charts can indicate large profit (#ofRetweets) increases/declines.
Figure 3.6: ReTweet Count Distribution (log10 scaled)
样本阅读:
- WithinFlow 中主题#3(国家地位)的推文最有可能获得 10-100 次转发。
- 话题 2(圣训、预言)中的推文获得相同数量的转发(约 10-100),无论它们是内部生成的还是从社区外部带来的。
- 主题#1(文章分享)中的推文在 WithinFlow 中的*均转发量高于 OutsideFlow,但只有 OutsideFlow 推文的转发量超过 100 次。
话题的极性和主观性
另一个可以探索的有趣衡量标准是推文的极性** (文本中表达了多少‘情绪’,范围从-1.0 到 1.0——有多‘极化)及其主观性(表达有多‘个人化’,范围从 0 到 1) 。我使用了一种非常弱的方法来计算这些度量(简单地聚合 tweet 中每个词的极性&主观性,这可以从预定义的库和映射中获得),但是我们仍然可以制作一些很酷的、看起来像外星人的图表!这些是联合密度图,基本上模拟了双变量(2 个变量)分布——它们很直观地告诉我们大多数推文在极性-主观性尺度上的位置。颜色表示“密度”,例如,WithinFlow(红色)的 maxTopic=3 图表显示了一个以(极性= ~0.1,主观性= ~0.25)为中心的深红色圆圈,这表明主题 3 中的大多数推文都具有这些极性/主观性值。**
****
Figure 3.7: Subjectivity/Polarity Density Graphs (Red = WithinFlow, Blue=OutsideFlow)
样本读数:
- 话题#4 ( 女人-穆斯林-男人-堕胎-盖头-女权主义者-想要)中的推文在 WithinFlow(在社区内部生成)中比从社区外部带入流中的推文更加主观 。
- 主题 3(国家地位)中的推文在 WithinFlow 中的极性/主观性尺度上更加分散,相比之下,OutsideFlow 中的推文更加密集。
这些是总体趋势,我将再次花时间提醒读者,我们的分析既是主观的(基于我个人的追随者),也是时间的(2018 年的信息流)。
让我们继续关注用户,因为每个人都知道… 真正的八卦不是关于想法…而是关于人!既然我们知道哪条推文来自社区中的哪个用户,我们可以再上一层楼,在用户层面进行调查。
主题-用户配置文件
****参考消息:所有这些用户资料都是公开的(在我收集这些数据的时候,所以从法律上来说,我很酷)。如果一个用户有 1000 多名追随者(我“直觉地”认为这是一个非常随意的数字..),我只是认为他们是公开的,应该可以对他们的推文进行分析。对于 1000 名粉丝,我已经发信息问他们是否同意,如果他们不同意就删除他们的数据。然而,
如果你因为任何原因希望你的名字被删除,请告诉我!
在我们将用户简档与我们生成的主题混合在一起之前,让我们先分别对我们的用户进行简档分析……有一些算法可以帮助我们从一个文档子集(即特定用户的推文)中找到与整个文档集(信息流中的所有推文)相比最有区别的术语。图 3.8** 显示了用户生成的推文中最具鉴别性的术语(gendiscsterms)以及他们传播的推文(propdiscsterms),这些术语将他们与信息流的其他部分“区分开来”。这并不意味着这些是他们最重要的术语!**
"N/A" means there weren't enough tweets to really discriminate any terms.. sorry!*For those of you who know '@dimashqee', his account has been deactivated so we don't know which tweets he has retweeted, even though he tends to be a major player in this community around certain topics.
Figure 3.8: Discriminative Terms by User
这些已经给了我们一个用户的概念!但是我们希望能够根据用户对我们在信息流中发现的主题的贡献来描述他们。为了做到这一点,我们可以根据发推的用户和转发的用户来合计我们的主题权重。这使我们能够根据我们之前强调的 3 个角色(生成者、内部传播者、外部传播者)来描述社区中的用户。图 3.9、图 3.10 和图 3.11** 描绘了用户主题的占有率——阅读它们:**
- ****占用百分比:圆圈的大小表示特定用户“占用”该主题的特定信息流(内流或外流)的百分比(根据图表,这可能意味着他们生成了多少信息或传播了多少信息)
- 所有列的总和为 100%
- 最后一列' TopicSum '表示用户在图表的相应角色中“占据”的信息流的总百分比。
Some of the numbers are hard to see here, I once again point the readers to the linked notebook in which you can hover over the points and see the complete topic Name as well as a clearer Occupation %.Occupation sounds a little.. harsh, but it is meant to be indifferent here.. :)
Figure 3.9: Internal Propagation Occupation Percentages
Figure 3.10: Internal Generation Occupation Percentages
Figure 3.11: External Propagation Occupation Percentages
我们还可以使用散点图来查看用户空间的高级角色配置文件。图 3.12、3.13 和 3.14** 显示了社区中不同用户角色之间的更高层次的关系(即图 3.12 是用户在社区中的总内部传播占有率%与用户在社区中的总生成占有率%之间的比较)。**
**GEN** = Generator, **IPROP** = Internal Propagator, **OPROP** = Outer/External Propagator*Note: those with very low occupation % are excluded.*
Figure 3.12: Internal Propagation Occupation vs. Generation Occupation
Figure 3.13: External Propagation Occupation vs. Generation Occupation
Figure 3.14: External Propagation Occupation vs. Internal Propagation Occupation
****在我看来,图 3.9–3.14是更有价值的衡量标准之一,不仅可以通过内容,还可以通过活动类型来捕捉用户行为。以下是从上述 6 个数字中可以获得的一些高水*读数示例。
样本读数:
- @TraversingTradition 是该社区内部信息流的主要产生者,今年产生了超过 24%的内部材料,但只有 7%的内部材料传播到社区的其他地方。它似乎只有效地参与了社区中 6/9 的主要话题。
- “AndrewStodghill”和“@ SeekingErudite”是两种信息流中的大型传播者,但却是非常低级的生成者。这些用户可被视为信息流连续性的重要节点,尽管他们不一定产生材料。
- thesalafieminist(' @ AnonyMousey ')将最大比例的外部信息带入主题#2(女权主义/女性研究)的信息流
- 每个主题似乎都有一种 30-70 法则…每个主题中 30%的用户(5)产生并传播70%的信息。
- 话题#4 的世代职业(与女权主义、盖头等相关。)比话题#2(与先知语录(圣训)、宗教轶事和语录等相关)的世代职业分布要分布得多。)由单个用户独占 50%。这种趋势可能会促进进一步的研究,因为它可能暗示主题#4 比主题#2 有更少的“回音室”。
当然,还有更多的见解,这完全取决于你想回答什么样的问题,以及你是否想确定单个用户的行为,等等。
…但是等等,还有更多!我们还可以按主题分解各种用户角色,并探索主题间的相关性。为了把你从一大堆图表中解救出来,我把分析放在了附录 A 中,供感兴趣的人参考。
结束语
- 我们的分析帮助我们成功地形成了围绕所选自我社区的信息流的术语级、推文级和用户级概况。
- 总的来说,成绩还是比较满意的!最初对用户社区的细分有助于限制问题,并找到真正相关和有见地的主题,而不是盲目地在一组推文中建立主题模型。信息流的主要贡献者进一步证实了这一点,比如在我们的用户特征分析阶段强调的“@TraversingTradition”。
- 提醒一下,一旦编程,这种分析(以及更详细、更先进的流程)需要几分钟才能完成— 这意味着当你同意使用 Twitter 作为公共*台时,你也在向工具和算法公开你的数据,这些工具和算法比你想象的更高效和有效。当然,我的目的不是“恶意的”(我保证!)但是更恶意的目的会有相同的访问…
- 由于我亲自跟踪这些用户,从这一分析中提取的这些用户的特征、内容和行为并不太令人惊讶,并且似乎与我随着时间的推移对社区定性获得的直观理解一致。然而,由于这种分析可以为任何一组用户完成,这种主题建模分析可以先发制人地给我们一个这个社区可以提供的总信息增益(和/或特定用户)的概念。在今天的社交媒体模型中,这种理解的明显用例指向有针对性的营销和广告,但人们也可以想象为研究、调查、政策制定等获取社会学信息的用途。不太“公司化”的。****
- 在我们的分析中,内外流的权重都很高的术语,如 【伊斯兰教,穆斯林等等。] 帮助我们反向验证我们的社区检测——对我们的用户算法分组感觉良好。
- 虽然我们只对一个社区进行了分析——但社区间的比较肯定是有空间的,甚至可以构建定义社区信息流的基本指标,并发现社区实际上是以可预测的方式组成的?(即根据他们的用户角色的分布)
- 此处的分析主要是描述性的,但是这些信息也绝对可以用于构建预测模型,帮助我们了解未来可能产生的效果和影响。
这篇文章的主要目的是对信息流的实质进行分类,所以我一直羞于对我们的观察进行解释,并提取预测性的见解。这是因为,在解释时,我们面临着技术官僚方法的软限制:观察,尽管精心策划和有趣,可能意味着任何事情和一切。对于这个问题,(我相信)数据科学家必须做出勇敢的尝试,利用社会学领域为我们提供一两个理论来解释我们的发现——强调一个我非常珍视的哲学观点:用“理论”支持数据科学相关分析过程的必要性。尽管社区检测也源于“社会学”自我网络的概念,但这仍然是对社会学领域非常肤浅的引用。为了进一步分析信息流的内容,我们需要更深层次的东西。(提示:高夫曼?布迪厄?萨特?..海德格尔?)
社区检测(阶段 1) 帮助我们找到了信息流向的“哪里”,主题建模(阶段 2)帮助我们找到了信息流向的“什么”——下一个阶段(3)是“为什么”。在未来,我计划通过介绍数据科学分析和社会学理论(在社交媒体分析领域)之间的联系以及它们如何帮助我们解释和限制我们的结果的意义来结束这个项目。敬请关注…
附录 A —角色之间的主题间关联
我知道这看起来像很多图表、点和线,但不要被吓倒!图 A.1 和 A.2** 按主题显示了外部和内部用户角色(外部传播方与内部传播方/生成方)之间的关系(例如图 A.1 的左上图显示了主题 0 的外部传播占有率%与主题 0 的代占有率%之间的关系,右上图显示了主题 0 的外部传播占有率%与主题 8 的代占有率%之间的关系。在我们的例子中,我们有一个很小的样本量(大约 22 个用户),因此这些图表不能全信,但是原则上,我们可以使用这些可视化来更深入地理解特定的主题关系。**
要阅读下面的图,最好是在从左到右或从上到下扫描时寻找奇怪之处。我们正在寻找的是特殊的行为,即,如果主题 X 的内部传播占用百分比与主题 Y 的生成占用百分比的关联方式不同于与其他主题的关联方式,这可能暗示主题之间存在相互影响。
**GEN** = Generator, **IPROP** = Internal Propagator, **OPROP** = Outer/External Propagator
Figure A.1: External Propagation Occupation vs. Generation Occupation [by Topics]
图 A.1 的样本读数
有一个更强的趋势表明,围绕主题#0 传播外部信息的用户倾向于围绕主题 4、5、6、7、8 生成更少的信息。
一般来说,看对角线,围绕某个主题产生更多信息的用户倾向于传播较少的外部信息。
Figure A.2: External Propagation Occupation vs. Internal Propagation Occupation [by Topics]
图 A.2 的样本读数
内部传播的话题#2 和外部传播的话题#2 之间特别强的正相关。
看对角线,似乎一般来说,在内部传播更多给定主题的用户也倾向于在外部传播更多相同的主题。
感谢您的阅读!
我在这些帖子中的总体目的是探索我个人好奇的概念的实践方法——因此,无论你在哪个领域,如果你有任何有趣的想法想讨论或合作,在你认为数据科学可以提供一些价值的地方,请随时给我发消息,我们可以谈谈。
信息在你和你的朋友中流动
原文:https://towardsdatascience.com/information-flows-in-you-and-your-friends-1a1e2e0f0734?source=collection_archive---------14-----------------------
使用社交媒体信息的可预测性上限,即使一个人已经删除了他们的社交媒体存在
你已经喝得够多了。婴儿照片,朋友们的政治演说,甚至可爱的猫的照片!担心你的隐私和未来的职业安全。你决定删除你在脸书、推特和 Instagram 上的账户。你有一个好公司:数百万脸书用户在 2017 年开始离开该*台,未来看起来也不会太好。 Twitter 努力寻找新用户以保持活跃用户群不变,只有 Instagram 在增长。删除你的账户和你发布的所有内容后,你和数百万人都认为你是安全的。结果,你不是。因为,从信息论的角度来看,就像你从未离开过。
相反,如果你是一名数据科学家,试图建立基于社交媒体信息的预测性机器学习模型(社交媒体创造了每天产生的 2.5 万亿字节数据的很大一部分),你可能会认为能够使用个人数据进行预测会非常有用。从 Target 在受影响者的父母知道之前识别怀孕到预测政治忠诚度和选举结果,社交媒体数据是数据科学和机器学习的名副其实的宝库。因此,如果你是一名数据科学家,你很幸运!因为即使你感兴趣的人和他们生成的所有内容可能已经从社交媒体上消失,你仍然有机会预测他们的行为或情绪。以下是方法。
Limits of text predictability based on the availability of data from friends and the individual.
我们在这里引用的是佛蒙特大学的 James P. Bagrow、Xipei Liu 和 Lewis Mitchell 最*在自然人类行为杂志上发表的一篇文章。在这项工作中,作者探索了你可以从社交媒体中提取多少预测能力的极限,特别是在有问题的个人删除他们的社交媒体资料的情况下。原来,还挺多的!高达 95% 的预测力围着你转,不用你也能聚集。该怪谁呢?你的朋友!在你的封闭社会环境中嵌入了太多关于你的信息,数据科学家原则上不需要个体本身在场就能达到合理的预测准确度。在文章的最后,我们将讨论这种方法的潜在局限性,所以请不要离开。
但是让我们回到实际的出版物。进行这项研究的研究人员以信息论为指导。由贝尔实验室研究员克劳德·香农在第二次世界大战后构想的信息论是一门对通信过程中的数据丢失和压缩,或者简而言之,信息流等主题感兴趣的整体学科。香农还在信息论中引入了熵的概念,用事件的预期结果来表示不确定性的数量。熵值为 1 意味着我们根本无法预测哪一个事件会发生(例如,硬币的哪一面是由抛硬币产生的),而熵值为零意味着预期结果没有不确定性。这很重要,因为在这种情况下预测个人行为意味着根据过去预测他们未来(在 Twitter 上)会写什么。因此,较低的熵意味着你能够更好地预测一个人接下来会说什么,或者在给定提示的情况下会说什么(例如政治)。
在他们的工作中,Bagrow 等人使用预测未来文本所需的信息比特中给出的熵率。4 比特的熵率将对应于从 24 = 16 个字中随机选择每个预测字。这听起来可能不多,但考虑到社交媒体用户拥有大约 5000 个单词的词汇量,这是一个巨大的进步!这里一个重要的考虑是,信息论处理通信的限制,因此给定的熵率及其相应的可预测性意味着给定该数据的预测生成模型的上限。随机可预测性(词汇量为 5000 个单词)将为 0.02%,而 Twitter 用户在他们的数据集中的*均可预测性为 53%(对应于 6.6 位的熵率)。这意味着,在一个建立在 Twitter 数据上的理想模型中,超过每秒钟预测的单词都是正确的。
然而,这个故事的主要部分是关于你的朋友。类似于熵,交叉熵是预测你的短信所需的来自你朋友的比特数。在这篇文章中,作者为每个人选择了 15 个最亲密的朋友(这是这个人在 Twitter 上最常提到的)。第一个重要的点是,你的社交圈里有关于你的信息。将你和你的朋友的预测信息结合起来,可预测性增加到 60%以上(无限数量的朋友为 64%),尽管这里肯定存在收益递减,这意味着添加到模型中的第一个朋友的影响比第十个朋友的影响更明显。这一切都很好,可以改善预测,但现在来了弥天大谎。将你自己从社交媒体网络中移除,并且只使用你的朋友来预测你的文本,你最终对 15 个朋友的预测率为 56%,对无限多个朋友的预测率为 61%。我要明确一点:仅仅使用 8-9 个朋友(不使用个人本身),你就可以打破使用真实个人的信息,你可以获得个人+朋友的最大可预测性的 95%!
如果你是一个想要利用这一点的数据科学人士,这里有另一个见解:这种可预测性对于发布很多帖子(从而强烈影响/影响他们的朋友)的个人以及不发布很多帖子(否则他们的表达会太多样化)并经常提到个人的朋友来说尤其明显。因此,当一个人删除个人资料时,他在网络中留下的印记会因其个性和网络而异。
以下是这项研究的一些注意事项/限制:与所有此类研究一样,不幸的是,这种社交嵌入效应仅在实践中有效,前提是你在某个时候是社交媒体的积极用户,以便确定你的社交圈。然而,如果有其他方法将你和你的朋友联系起来(GPS 协同定位,在没有标签的帖子中提及,等等)。)如果他们在社交媒体上,这条警告就无效了。另一个考虑是,通过社交媒体获得的可预测性可能仅限于发布在社交媒体上的文本。虽然这仍然允许探索情绪和态度,但建立在此基础上的模型可能无法准确预测,比如说,个人撰写的长篇文章。最重要的限制,也是作者提到的,是这些嵌入的信息可能会随着你的社交圈的发展而改变(见鬼,他们中的一些人甚至会退出社交媒体)。因此,从个人退出社交媒体的那一刻起,你可能有很短的时间来开发一个表现良好的模型(这对你来说是好事,个人!).有趣的是,看看这是否可以通过在模型中包括更多的朋友,仔细选择“变化”程度低的朋友来保持嵌入,或者简单地依赖于旧的存档社交媒体数据(互联网什么都不会忘记)来缓解。
This is why prediction from your friends after you quit social media will be important. Source: Google Trends
总之,我认为这篇文章是我们在环境中保存信息的一个很好的例子。以城市为例。除了十字路口、天然港湾和商路的记忆,它们还能是什么?同样,我们的朋友至少代表了我们的一部分,并带着我们的信息。显然,如果有足够多的朋友,这足以教会一个模型比直接“研究”我们更好地了解我们。随着前面提到的传统社交媒体*台的大量涌现,对于对你的政治倾向感兴趣的广告公司或机构来说,这可能是一个黄金机会,可以利用机器学习和数据挖掘来保持或扩大他们的预测潜力。我想知道仅仅建立在朋友基础上的机器学习模型在实践中有多容易建立/强大!如果你尝试一下,请告诉我!
您可能会对文章中的一些附加注释/琐事感兴趣:
-社交媒体文本比“传统文本”更极端,有些很容易预测,有些很难处理。
-基于认知极限,邓巴的数字假设每个人最多有 150 个左右的朋友。然而,脸书好友的*均数量超过 300,而 LinkedIn 好友的*均数量超过 500。这意味着与传统的友谊网络相比,社交媒体*台可能会产生相当大的影响。
-与他们的朋友相比,个人自己的帖子中有更多的长期信息。与最*的帖子相比,前一段时间朋友的帖子对个人文本预测产生的收益递减影响清楚地表明了这一点。
-由于作者从他们的数据中排除了超链接,这里给出的限制可能是可扩展的。使用共同训练或其他方法可能会产生一个包括关于这些超链接的信息的模型,因此能够利用更多的信息并实现更好的预测。
启动数据科学的数据计划要素
原文:https://towardsdatascience.com/ingredients-in-a-data-program-to-jump-start-data-science-4cc01b5bb1ae?source=collection_archive---------35-----------------------
Fig. 1 by Marjorie Sarnat. From left to right: Data Scientist, Business Manager, Data Analyst
在过去的几年里,我遇到了一些数据科学家,他们在统计分析和机器学习领域大有可为,但当他们进入商业领域时,他们面临着许多挑战,这些挑战让他们难以起步。他们很快就被提供即时结果的压力所淹没,而孤岛式数据源的复杂环境又进一步加剧了这种压力。
在本文中,我为您的数据程序提出了一些要素,以帮助数据科学家更快地入门,这些要素也可以更广泛地应用于一般的数据工作者。
魔法?
如果你将“数据科学”和“魔术”这两个词一起谷歌,你会发现许多文章解释说,数据科学不是魔术的黑盒子(像这篇文章,或者这篇)。作者表达了当数据科学家的工作被误解或他们没有做好工作所需的东西时,他们所面临的挫折感。
如果你是一名渴望利用数据科学来发展业务的商业专业人士,那么被告知“数据科学不是魔法”可能会降低你的热情——就像当一个孩子第一次被告知圣诞老人不是真实的一样。
我想知道我如何才能鼓励人们继续对数据科学保持兴奋,同时也阐明我们需要数据科学计划取得成功的一些因素…然后,在万圣节前的一周,我有了以下想法。我一直在我家附*散步,意识到这是一个穿上戏服假装的季节。所以…
让我们假装一个数据科学家是一种魔术师…
Fig. 2 by Roel Punzalan
比方说,你让你的数据科学家为你调制一种药剂。你请他施展魔法,将数据转化为源源不断的精彩见解,供你的企业使用。当这个白胡子巫师向你走来时,你搓着双手,满怀期待。他把他的手杖重重地摔在地上,说道:
"首先,我需要 1)一个洞穴,2)一口大锅,3)一个巨大的火炉."
你挠了挠头,然后指着小房间里桌子上的一台笔记本电脑。
他摇了摇头,再次将他的手杖重重地砸向地面,重复道:“一个洞穴,一个大锅,一个巨大的熔炉……”
一个洞穴(情境+协作环境)
数据科学家首先需要的是背景。
很多时候,数据科学家被要求进行研究,却没有被告知他们应该解决的问题的足够背景,或者他们需要依赖的现有数据流。
因此,数据科学家花费大量时间试图理解和跟上他们需要的数据流,但这些数据流存在于他们自己的环境之外。
更为复杂的是,由于业务需求不断变化,数据流也在不断变化。
如果来自这种隔离环境的研究需要传递给希望在生产中使用该研究的某个方面的工程团队,这种隔离将在未来带来挑战。
这些挑战可以通过在现有环境中满足数据科学家的需求来解决:
- 邀请他们作为(可选)参与者参加您的所有团队会议,这样他们可以熟悉您的团队、您的业务目标和现有的技术环境。
- 考虑一下他们研究工作的节奏,以及它与你现有的 scrum 流程的关系。这可以被认为是一种类似于你如何管理 UX 设计需求的方式。
- 为他们提供一种方法,让他们了解您的整个数据流和对象集。
- 将路线图的一部分专门用于在现有环境中为数据科学研究开辟空间。
大锅(容器+计算能力)
在现有环境中开辟空间以满足数据科学需求通常需要考虑以下常见因素:
- 存储和管理可再生研究的地方(例如 jupyter 笔记本)
- 分享研究的方法
- 一种安全存储凭证的方法,同时以其他人可以输入自己的凭证的方式共享研究
- 一种安全连接到所需数据集的方法
- 访问存储和计算资源,他们可以根据需要增加或减少存储和计算资源。
数据科学专业的毕业生通常能够自我管理这些元素,但理想情况下,他们会获得一个环境的钥匙,让他们能够自我管理存储和计算资源(例如 AWS 或 GCP)。
与您的工程团队一起协调这些需求是一个好主意,他们可能能够将这些需求纳入现有的 repos 和 docker 映像,以便可以在本地环境以及您的 VPC(虚拟私有云)上的各种其他环境中共享和测试研究。
一个巨大的熔炉(实时数据)
您需要帮助您的数据科学家开始工作的最后一个障碍是为他们提供一个紧密代表实际生产数据的数据流。
如果研究要求需要进入生产:
- 就安全考虑事项与您的安全团队协调
- 与您的工程团队协作,通过 API、Kafka 流或相关生产数据库的副本来公开生产数据(通常,直接访问生产数据库不是一个好主意)
如果研究需求没有明确要求访问生产环境,请记住,生产环境通常包含难以在暂存环境中复制的脏数据。数据科学家通常需要考虑这些因素,并在通过算法运行数据之前运行清理/清理功能。使用虚拟数据测试的机器学习算法只有在虚拟数据代表生产数据的程度上才真正成功。
药剂(示例业务用例)
说了这么多,做了这么多——你有了一个洞穴、一口大锅和一个巨大的熔炉,并且正在运行——你的数据科学家会问你,“你到底需要我的药水做什么?”
你想预测未来的收入吗?优化你的供应链?为客户提供更好的产品推荐?或者,确定客户终止订阅的最重要原因?
虽然这些都是数据科学可以实现价值的好例子,但可以考虑从小处着手,获得“第一次胜利” ⁶ 。例如,将客户反馈分为正面或负面(类似于垃圾邮件过滤器),或者更简单地,验证数据中的现有计算。
有时,企业会意识到他们需要一名数据科学家,但不知道具体原因。这可能是一个不错的开始,但是你很快就会想去做一些具体的事情。如果您为数据科学家提供足够的业务目标背景,他们可能会帮助您确定要测试的假设,从而帮助您确定行动方案。
为什么这很重要——即使你没有数据科学家
虽然在本文中,我主要关注数据科学家面临的挑战,但这些挑战可以归因于更广泛的数据工作者网络。数据和分析越来越被视为构成任何组织命脉的关键企业资产。
“到 2022 年,90%的企业战略将明确提到信息是关键的企业资产,分析是一项基本能力。
到 2022 年,30%的[首席数据官]将与他们的首席财务官合作,正式评估组织的信息资产,以改善信息管理和收益。
到 2023 年,数据素养将成为商业价值的明确而必要的驱动因素,这表现在它被正式纳入超过 80%的数据和分析战略以及变革管理计划中。”——高德纳公司
附加帮助
数据科学已经发展成为一个庞大的学科体系。寻找一名优秀的数据科学家有时等同于寻找一只独角兽。思考这一挑战的另一种方式是将数据科学视为更多的团队工作。与其在一个人身上寻找一整套技能,不如在您的数据策略中考虑一些其他角色:
首席数据/分析官
CDO 或 CAO 通过分析计划推动业务价值,并定义跨业务垂直领域的标准
数据分析师
专注于将信息转化为有意义的见解,并利用现有工具实现标准数据管道。
数据工程师
关注特定于分析的架构需求,并构建自定义数据管道。
决策科学家
关注分析工作的成本,并跟踪投资回报(ROI)
数据管家
拥有特定的数据集并管理质量和可靠性
无服务器技术
过去几年云技术的进步为启动您的数据科学项目提供了一些绝佳的机会。
最后的想法
GitLab 的数据团队一直是我的灵感来源,影响着我如何思考创建一个为成功而设置的数据程序。他们的理念、过程和数据管道都可以在他们的手册和数据团队知识库中公开获得。他们的 CI/CD 方法使数据工作者能够比我迄今为止遇到的任何方法都更快、更可持续地投入工作。
您的数据团队是否花费更多时间收集和移动数据,或者分析和提供见解?
你如何将你的数据科学家纳入你的软件开发过程?
我很想听到关于这些想法是否对任何人有帮助的反馈。
感谢阅读!谢谢你,Edwin——谢谢你帮我审阅我的文章,还有Roel——谢谢你的向导插图:)
神经网络的初始化技术
原文:https://towardsdatascience.com/initialization-techniques-for-neural-networks-f4ce8e64effc?source=collection_archive---------11-----------------------
因为有个好的开始总是更好!!
在这篇博客中,我们将看到深度学习中使用的一些初始化技术。任何在机器学习方面没有多少背景的人都必须知道,我们需要学习权重或超参数来建立模型。这些参数决定了我们的算法在未知数据上的表现。为了学习模型,我们需要初始化参数,应用损失函数,然后优化它。在这篇博客中,我们将关注网络的初始化部分。
如果你曾经构建过任何机器学习算法,你一定听说过我们需要“随机”初始化我们的权重作为起点,然后开始学习过程。随机这个词本身就很模糊。我们将会看到 random 这个词背后的真正含义以及不同的初始化技术。
- 零初始化
这是初始化权重的最简单方法之一,方法是将所有权重都设置为零。现在让我们用一个简单的两层网络来想象这种技术的含义。
由于我们已经设置了所有的权重,即 w= 0,我们可以很容易地看到,在向前传递期间:
a1 = w1x1 + w2x2 + w3x3, h1 = g(w1x1 + w2x2 + w3x3)
a2 = w4x1 + w5x2 + w6x3, h2 = g(w4x1 + w5x2 + w6x3)
a3 = w7x1 + w8x2 + w9*x3,H3= g(w7 * x1+w8 * x2+w9 * x3)
y= g(h1 * w10+H2 * w11+H3 * w12)
很清楚的看到 a1 = a2 = a3 = 0,h1 = h2 = h3。-> (1)
现在让我们看看反向传播会发生什么
∇w1=∂l(w)̇/∂w1 =∂l(w)̇/∂l(y)̇∂l(y)̇/∂l(h1)̇∂l(h1)̇/∂l(a1)̇* ̇x1
∇w4=∂l(w)̇/∂w4 =∂l(w)̇/∂l(y)̇∂l(y)̇/∂l(h2)̇∂l(h2)̇/∂l(a2)̇* ̇x1
∇w7=∂l(w)̇/∂w7 =∂l(w)̇/∂l(y)̇∂l(y)̇/∂l(h3)̇∂l(h3)̇/∂l(a3)̇* ̇x1
由此我们可以看出,∇w1 = ∇w4 = ∇w7(从 1),同理∇w2= ∇w5= ∇w7 和∇w3 = ∇w6 = ∇w9
从上面的论证中,我们可以看出每一步重量的变化是相同的。因此,隐藏层中的所有节点都在学习输入的相同参数,这导致冗余,并使我们的网络不太灵活,因此不太准确。这也叫做对称性问题。因此零初始化不是一个好的技术。
2.用相同的随机值初始化
在这种技术中,我们用相同的随机值初始化所有的权重。我希望你已经得到了这个技术的问题,因为它非常类似于零初始化,我们只是使用了一个随机值,但同样的问题仍然存在,因为权重的更新将再次处于相同的顺序。因此也不使用这种技术。
3.用小随机值初始化
在该技术中,我们从具有均值 0 和方差 1 的单变量“高斯”(正态)分布中随机初始化所有权重,并将它们乘以 10 的负幂以使它们变小。我们可以使用 numpy 在 Python 中这样做,如下所示
W = np.random.randn(输入 _ 层 _ 神经元,隐藏 _ 层 _ 神经元)*0.01
通过绘制梯度值,我们可以得到一个类似于的正态曲线。
现在,我们将运行学习算法,看看分布如何随着不同的 eopchs 而变化
After 10 epochs
After 20 epochs
After 50 epochs
从上面的图中,我们可以很容易地看到方差在减小,梯度饱和到 0。这就是所谓的渐变消失问题。人们也可以将此形象化,因为每个梯度是作为导数相乘链的结果而获得的,并且每个值远小于 1,因此梯度为零。
当这些梯度用具有 sigmoid 激活的神经元向前传播时,当 sigmoid(0) = 0.5 时,神经元的输出接* 0.5,而在 tanh 的情况下,它将与梯度图一样以 0 为中心。
Applying sigmoid activation
因此,我们可以得出结论,如果我们取小的随机值,梯度在重复链倍增时消失,并且神经元在 sigmoid 的情况下达到饱和值 0.5,在 tanh 的情况下达到饱和值 0。因此,我们不能使用小的随机值作为初始化。
4.用大随机值初始化
我们刚刚看到,在小随机值的情况下,梯度消失。现在让我们看看当我们用大的随机值初始化权重时会发生什么。我们可以使用 numpy 在 Python 中这样做,如下所示
W = np.random.randn(输入 _ 层 _ 神经元,隐藏 _ 层 _ 神经元)
当我们将权重初始化为大值时,绝对和 WiXi 将非常大,并且神经元在正向传递期间饱和到极限,如下所示。
Saturation with sigmoid activation
Saturation with tanh activation
下图显示,在饱和状态下,sigmoid 的导数为零。类似的论点也适用于 tanh。
现在,当我们通过网络反向传播时,导数将趋于零,因此在这种情况下梯度也将消失。因此,如果您认为我们已经初始化了较大的权重,因此梯度将会爆炸而不是消失,这与 sigmoid 和 tanh 由于在较大值饱和而激活的情况不同。
上面的两个论点告诉我们,在这两种情况下,无论是将权重初始化为小值还是大值,它们都会消失。在小值中,梯度因重复的链乘法而消失,而在大值中,梯度因导数本身变为零而消失。因此它们都不能使用。
在尝试任何新的方法之前,我们将试图建立一些直觉,为什么它会发生在数学上。
让我们来谈谈你的神经网络的输入,你必须知道,在输入网络之前,我们把输入标准化。为了便于讨论,让我们假设我们的输入来自均值为 0、方差为 1 的正态分布。对于 n 个输入,我们将上述网络中 a1 的等式推广为
a1 = w1x1 + w2x2 + w3x3 + …..+ wnxn
现在我们将计算 a1 的方差
Var(a1) = Var(∑WiXi)
=σVar(WiXi)
=σ[(E[Wi])Var(Xi)+(E[Xi])Var(Wi)+Var(Wi)Var(Xi)]
将输入和权重都视为零均值,前两项将相互抵消。
=σVar(Wi)Var(Xi)
因为所有的 WiXi 都是同分布的,所以我们可以写
=nVar(Wi)Var(Xi)
我们发现Var(a1)=(nVar(Wi))Var(Xi)或者我们可以说我们的输入 Xi 被缩放到 (nVar(Wi)) 倍方差。更多的数学知识,我们将能够证明第 k 个隐藏层,var(AK)=([(nvar(wi))]^k)var(xi).)的方差这种说法的物理意义是,隐藏层中的任何神经元现在可以变化 n 倍的输入变化(这也是前一层输入的 n 倍方差),或者如果我们绘制分布,我们会发现 Var(ak)比 Var(Xi)的分布更广
现在让我们看看 (nVar(Wi))^k )在 (nVar(Wi)) 的不同值下会发生什么
如果 (nVar(Wi)) > >为 1,渐变将爆发
如果 (nVar(Wi)) < <为 1,渐变将消失
因此,我们的工作是限制 (nVar(Wi)) = 1 ,这避免了爆炸或消失梯度的问题,并且方差的传播将在整个网络中保持恒定。
(nVar(Wi)) = 1
Var(Wi) = 1/n
因此,如果我们将从均值为 0、方差为 1 的高斯分布获得的权重缩放至 1/ √n,,则我们有
nVar(Wi) = nVar(W/√n)
= n * 1/n Var(W)
=1
最后,我们的任务是从方差为 1 的正态分布初始化权重,并将其缩放到 1/ √n,其中 n 是前一层中的节点数。在 Python 中,我们可以使用
W = np.random.randn(输入 _ 层 _ 神经元,隐藏 _ 层 _ 神经元)* sqrt(1/输入 _ 层 _ 神经元)
这也被称为 Xavier 初始化或Glorot 初始化http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf
在 ReLU 激活函数的情况下,我们乘以 √ 2/ √n 来说明负的一半(x < 0)对任何方差都没有贡献。这也被称为贺初始化。这是在https://arxiv.org/pdf/1502.01852v1.pdf提出的
W = np.random.randn(输入 _ 层 _ 神经元,隐藏 _ 层 _ 神经元)* sqrt(2/输入 _ 层 _ 神经元)
Xavier 初始化的一些其他变体包括除以输入层神经元和当前隐藏层神经元的数量之和。爱尔兰共和国
Var(Wi) = 2/(输入 _ 层 _ 神经元+隐藏 _ 层 _ 神经元)
Tensorflow 实现文档https://www . tensor flow . org/API _ docs/python/TF/contrib/layers/Xavier _ initializer
诸如 Keras 之类的高级 API 也使用 Glorot 初始化,尽管底层分布可以是高斯分布或均匀分布。下面是 Keras 中初始化器函数的 GitHub 链接。
[## keras-team/keras
人类的深度学习。通过在 GitHub 上创建一个帐户,为 keras-team/keras 开发做出贡献。
github.com](https://github.com/keras-team/keras/blob/62d097c4ff6fa694a4dbc670e9c7eb9e2bc27c74/keras/layers/core.py#L798)
让我们总结一下
如果你能跟上一些令人难以置信的数学。太棒了。因此,我们首先看到,我们不能使用零或相同的初始化,因为所有的权重往往以相同的幅度更新,因此阻碍了学习过程。此外,我们看到,如果我们将权重初始化为太小或太大的值,那么它们往往会饱和,梯度下降到 0。因此,需要初始化权重,以使隐藏层中神经元之间的变化保持恒定,Xavier 初始化允许我们这样做,因此它是任何网络初始化的最明显选择。
有一些技术,如批量标准化,它倾向于在将神经元传播到下一层之前,标准化每个隐藏层的神经元,就像我们在将输入输入到网络之前所做的一样。这减少了对权重初始化的强烈依赖,并允许我们对初始化有点粗心。
感谢阅读这篇文章。
更多这样的博客,你可以关注我,这样每当我有新的帖子时,你都会得到通知。
干杯!
还有,我们来连线一下 Twitter , Linkedin , Github 。
初始化神经网络
原文:https://towardsdatascience.com/initializing-neural-networks-3a774eb63745?source=collection_archive---------27-----------------------
设置
让我们从获取 MNIST 数据集开始。因为我们经常这样做,所以我们将定义一个函数来这样做。
现在让我们计算数据的*均值和标准差。
注意,我们用train_mean
而不是valid_mean
来标准化验证集,以保持训练集和验证集在相同的规模上。
由于*均值(或 sd)永远不会精确地为 0(或 1),我们还定义了一个函数来测试它们是否接* 0(有一些阈值)。
接下来,让我们初始化我们的神经网络。
初始化问题
初始化神经网络 是深度学习的重要组成部分。这就是为什么我们可以让我们的神经网络像今天这样深的核心。初始化决定了我们是否收敛得好,收敛得快。
我们希望以这样一种方式初始化我们的权重,即当我们通过不同的层时,均值和方差保持不变。我们当前的初始化不会发生这种情况。
我们可以看到,仅仅一层之后,我们的激活值(一层的输出)相差甚远。如果我们对许多层重复这个过程,它将导致 渐变爆炸 ,如下所示。
我们模型的激活增长远远超过合理的值,以至于达到无穷大。这甚至不需要 100 次乘法运算就能实现。
那么我们该如何应对呢?也许我们可以把它们缩小一个系数来防止它们爆炸。
那也没用。虽然想法是正确的,但选择错误的因子会导致 渐变 (值达到 0)。
选择正确的比例因子— Xavier init
比例因子的值应该是多少?
答案是(1 /⎷input).这种初始化技术被称为 Xavier 初始化 。如果你想了解相同背后的数学,可以阅读原文或者本文末尾提到的参考文章之一。阅读研究论文的一个好建议是搜索总结论文的文章。
除以⎷input 确实有效。注意,如果我们想在反向传递中保持梯度,我们将除以⎷output.
Xavier 初始化文档也提供了如下所示的一些很好的可视化效果。
Xavier 初始化有问题
Xavier init 论文假设我们的激活函数将是线性的(事实并非如此)。因此,它忽略了激活函数对均值和方差的影响。让我们想想 ReLU。
一个 ReLU 把分布中所有的负值都变成 0。这当然不能保持我们数据的均值和方差。如果说有什么不同的话,那就是它们的价值只有原来的一半。每一层都会发生这种情况,所以 1/2 会累加起来。
在一篇名为深入研究整流器:在 ImageNet 分类上超越人类水*的性能的论文中提出了这个问题的解决方案。
简单的想法是,由于我们的值每次都减少一半,我们只需在分子中增加一个额外的 2 来抵消它。这种初始化技术被称为初始化或 何初始化 。
尽管我们的均值不太好,但它确实有助于我们的标准差。好的初始化能做的事情是惊人的。
有一篇名为 Fixup initialization 的论文,作者仅通过仔细的初始化,就训练了一个 10000 层深度的神经网络,没有任何归一化。这应该足以让你相信很好地初始化神经网络是重要的。
如果你想了解更多关于深度学习的知识,可以看看我在这方面的系列文章:
* [## 深度学习系列
我所有关于深度学习的文章的系统列表
medium.com](https://medium.com/@dipam44/deep-learning-series-30ad108fbe2b)
参考资料:
- 从基础开始深度学习,fast.ai
- 理解深度神经网络中的 Xavier 初始化。
- 深度神经网络如何初始化?
- 关于深度神经网络权重初始化的说明
- 多个随机变量乘积的方差*
先天知识和深度学习
原文:https://towardsdatascience.com/innate-knowledge-and-deep-learning-8e9405741ee2?source=collection_archive---------12-----------------------
我们生来就有某种先天知识吗?天赋论正在获得神经科学证据,并可能塑造人工智能和深度学习的下一个 R&D 步骤。
Figure 1: An elder Plato walks alongside Aristotle, The School of Athens, Raphael
“天赋论”..]认为人类的头脑生来就有想法或知识。这种信念,最著名的是由柏拉图作为他的形式理论提出的,后来由笛卡尔在他的《沉思录》中提出,目前正在获得神经科学的证据,可以证实我们生来就有关于我们世界的先天知识的信念。
天赋论与“纯粹主义”的机器学习方法相冲突,在“纯粹主义”的机器学习方法中,机器学习算法只从数据中学习,而没有显式编程或配备预编程的计算和逻辑模块。“思想的实际内容极其复杂,不可救药;我们应该停止试图寻找简单的方法来思考头脑的内容,例如思考空间、物体、多重代理或对称的简单方法。所有这些都是任意的、内在复杂的外部世界的一部分。它们不是应该内置的,因为它们的复杂性是无穷无尽的;相反,我们应该只构建能够发现和捕获这种任意复杂性的元方法。 " ( 来源)
截然不同的是,一个不同的思想流派建议将符号人工智能技术与深度学习相结合。
深度学习的未来
纽约大学教授加里·马库斯(Gary Marcus)等人提出了一种想法,即深度学习需要与更古老的象征性人工智能技术相结合,以达到人类水*的智能,辛顿对此表示蔑视。辛顿将此比作仅使用电动机来驱动汽油发动机的燃料喷射器,尽管电的能效要高得多。 " ( 来源)
与此同时,混合模型可能会解决深度学习的明显限制,特别是“深度学习目前缺乏一种通过明确的口头定义来学习抽象的机制,当有数千、数百万甚至数十亿个训练示例时效果最佳”。(来源)
是否应该更好地将 GOFAI 融入深度学习?这场争论正在激烈地进行着。
新的神经学证据
在我看来,讨论最终归结为一个问题——我们人类是从经验中学习一切,还是天生就具备某种形式的先天知识?
发表在《美国国家科学院院刊》(PNAS)上的一项研究称,“发现了一种突触组织原理,它以一种在动物中常见的方式对神经元进行分组,因此独立于个体经历”(来源)。这样的集群包含了物理世界中某些简单工作的表现。神经元群或细胞集合体,在动物的新皮质中不断出现,本质上是细胞的“积木”。那么,在许多动物中,学习、感知和记忆可能是将这些片段放在一起的结果,而不是形成新的细胞组合(来源)。
一条狭窄的分界线
鉴于越来越多的神经学证据支持先天知识的存在,为深度学习配备“先天”计算模块或原语可能是有意义的。很可能一些这样的原语将基于借鉴或受 GOFAI 启发的想法。
另一方面,很难预见深度学习架构在未来会是什么样子。Yoshua Bengio 自己承认,“然而,在神经网络能够与人脑拥有的一般智能相匹配之前,需要深度学习的新架构”。
在我看来,符号操作很可能会与神经架构深度耦合和纠缠在一起,而不是简单的并列,例如,神经后端和符号前端(如图 2 所示)。“M 模型更接*于通用计算机程序,建立在比我们当前的可区分层丰富得多的原语之上——这就是我们将如何达到推理和抽象,当前模型的根本弱点”(来源 )。.)
Figure 2: Deep Symbolic Reinforcement Learning, the neural back end learns to map raw sensor data into a symbolic representation, which is used by the symbolic front end to learn an effective policy (source)
这表明两种方法之间的分界线,“纯粹型”和“混合型”之间的界限非常模糊。因此,我认为,观点上的差异更多的是侧重点的差异,而不是根本性的差异。
Python 中的简单神经网络
原文:https://towardsdatascience.com/inroduction-to-neural-networks-in-python-7e0b422e6c24?source=collection_archive---------0-----------------------
什么是神经网络?
神经网络大致基于人类大脑的工作方式:许多神经元连接到其他神经元,通过它们的连接传递信息,并在神经元的输入超过特定阈值时触发。我们的人工神经网络将由人工神经元和突触组成,信息在它们之间传递。突触或连接将根据神经元对决定输出的影响强度进行加权。这些突触权重将经历一个被称为反向传播的优化过程。对于训练过程中的每次迭代,反向传播将用于返回网络的各层,并根据它们对神经网络误差的贡献来调整权重。
神经网络本质上是将输入映射到正确输出的自我优化功能。然后,我们可以将一个新的输入放入函数中,它将根据用训练数据创建的函数来预测输出。
神经网络的目标
像所有的神经网络一样,这个神经网络必须学习数据中的重要特征,以产生输出。特别地,该神经网络将被给予具有六个样本的输入矩阵,每个样本具有三个仅由 0 和 1 组成的特征列。例如,训练集中的一个样本可能是[0,1,1]。每个样本的输出将是单一的 1 或 0。输出将由数据样本的第一个特征列中的数字决定。使用前面给出的例子,[0,1,1]的输出将是 0,因为第一列包含 0。下面将给出一个示例图表来演示每个输入样本的输出。
完整代码
https://gist.github.com/a-i-dan/8d0a40b8690b40d9a46c4cb1d326fce5
Output:[[0.99089925]] - Correct: 1
[[0.006409]] - Correct: 0
代码分解
import numpy as np
import matplotlib.pyplot as plt
在开始之前,我们需要导入必要的库。这个例子只需要两个库,如果不画出损失,我们只需要 Numpy。Numpy 是一个 python 数学库,主要用于线性代数应用。Matplotlib 是一个可视化工具,我们将使用它来创建一个图,以显示我们的误差如何随着时间的推移而减少。
inputs **=** np**.**array([[0, 1, 0],
[0, 1, 1],
[0, 0, 0],
[1, 0, 0],
[1, 1, 1],
[1, 0, 1]])
outputs **=** np**.**array([[0], [0], [0], [1], [1], [1]])
如前所述,神经网络需要数据来学习。我们将使用 Numpy 的.array()
函数创建输入数据矩阵和相应的输出矩阵。输入中的每个样本由三个由 0 和 1 组成的特征列组成,这些特征列产生一个 0 或 1 的输出。我们想让神经网络知道输出是由每个样本中的第一个特征列决定的。
**class** **NeuralNetwork**:
**def** **__init__**(self, inputs, outputs):
self**.**inputs **=** inputs
self**.**outputs **=** outputs
self**.**weights **=** np**.**array([[**.**50], [**.**50], [**.**50]])
self**.**error_history **=** []
self**.**epoch_list **=** []
我们将采用面向对象的方法来构建这个特定的神经网络。我们可以首先创建一个名为“NeuralNetwork”的类,并通过定义__init__
函数来初始化该类。我们的__init__
函数将输入和输出作为参数。我们还需要定义我们的权重,为了简单起见,从每个权重为. 50 开始。因为数据中的每个要素都必须连接到隐藏层,所以我们需要数据中每个要素的权重(三个权重)。出于绘图目的,我们还将创建两个空列表:loss_history 和 epoch_list。这将跟踪我们的神经网络在训练过程中每个时期的错误。
**def** **sigmoid**(self, x, deriv**=**False):
**if** deriv **==** True:
**return** x ***** (1 **-** x)
**return** 1 **/** (1 **+** np**.**exp(**-**x))
该神经网络将使用 sigmoid 函数或逻辑函数作为激活函数。sigmoid 函数是一种流行的非线性激活函数,其范围为(0–1)。该函数的输入将总是被压缩,以适应在 y=0 和 y=1 处的 sigmoid 函数的两条水*渐*线。sigmoid 函数有一些限制其使用的众所周知的问题。当我们看下面的曲线时,我们注意到当我们到达曲线的两端时,这些点的导数变得非常小。当这些小导数在反向传播过程中相乘时,它们会变得越来越小,直到变得无用。由于导数或梯度变得越来越小,神经网络中的权重将不会更新太多,如果有的话。这将导致神经网络停滞不前,每增加一次训练迭代,情况就会变得越来越糟。
sigmoid 函数可以写成:
sigmoid 函数的导数可以写成:
s′(x)=s(x)⋅(1−s(x)
如何求导
导数只是一个花哨的词,用来表示给定点的斜率或切线。仔细看看上图中的 sigmoid 函数曲线。其中 x=0 处的斜率远大于 x=4 或 x=-4 处的斜率。权重的更新量基于导数。如果斜率是较低的值,则神经网络对其预测有信心,并且需要较少的权重移动。如果斜率是更高的值,则神经网络的预测更接* 0.50,或 50%(对于 sigmoid 函数,可能的最高斜率值是在 x=0 和y = 0.5。 y 是预测。).这意味着神经网络对其预测不是很有信心,并且需要对权重进行更大的更新。
我们可以通过以下步骤找到 sigmoid 函数的导数:
然后我们可以用一个很酷的技巧来继续简化:给 e^-x 加一减一。加一减一不会改变什么,因为它们相互抵消了。这是一种奇特的加零方式。
通过在分子中加减一,我们可以再次拆分分数,并拉出另一个 sigmoid 函数!
现在我们可以简化,最后得到 sigmoid 函数的简化导数。
如果我们将 sigmoid 函数写成 S(x) ,那么导数可以写成:
=(s(x)⋅(1−s(x))
**def** **feed_forward**(self):
self**.**hidden **=** self**.**sigmoid(np**.**dot(self**.**inputs, self**.**weights))
在我们的神经网络的训练过程中,输入数据将通过网络的权重和函数被前馈。这个前馈函数的结果将是隐藏层的输出,或者是隐藏层对给定权重的最佳猜测。输入数据中的每个要素对于其与隐藏图层的连接都有自己的权重。我们将从每个特征的总和乘以其相应的权重开始。一旦我们将输入矩阵和权重矩阵相乘,我们就可以将结果通过 sigmoid 函数压缩成介于(0–1)之间的概率。前向传播函数可以写成这样,其中 xᵢ 和 wᵢ 是矩阵中的单个特征和权重:
再次重申,隐藏层将按以下步骤计算:
- 将每个特征列与其权重相乘
- 对特征和权重的乘积求和
- 将总和传递给 sigmoid 函数以产生输出\(\hat y\)。
上图显示了将每个特征与其对应的权重相乘,然后对乘积求和的过程。训练数据中的每一行都将这样计算。得到的 4x1 矩阵将被输入到 sigmoid 激活函数中,如下所示:
上述过程将导致隐藏层的预测。 ∑xw 矩阵中的每一行都将进入 sigmoid 函数。颜色代表∑ xw 矩阵中每一行的单独过程。注意:这个计算只代表一次训练迭代,所以得到的 ŷ 矩阵不会很精确。通过以这种方式计算隐藏层,然后使用反向传播进行多次迭代,结果将更加准确。
**def** **backpropagation**(self):
self**.**error **=** self**.**outputs **-** self**.**hidden
delta **=** self**.**error ***** self**.**sigmoid(self**.**hidden, deriv**=**True)
self**.**weights **+=** np**.**dot(self**.**inputs**.**T, delta)
这是整个神经网络中最酷的部分:反向传播。反向传播将通过神经网络的层返回,确定哪些权重对输出和误差有贡献,然后基于隐藏层输出的梯度改变权重。这将被进一步解释,但是现在,整个过程可以被写成这样,其中 y 是正确的输出, ŷ 是隐藏层预测:
为了计算隐藏层预测的误差,我们将简单地取正确输出矩阵 y 和隐藏层矩阵 ŷ 之间的差。这个过程将在下面显示。
我们现在可以将误差和隐藏层预测的导数相乘。我们知道 sigmoid 函数的导数是 S(x)(1 — S(x)) 。因此,每个隐藏层预测的导数将是[(ŷ)(1-ŷ)]。例如,隐藏层的预测矩阵中的第一行包含值\(0.62\)。我们可以用 0.62 美元代替 ŷ ,结果将是预测的导数。*0.62 (1–0.62)= 0.2356。对 ŷ 矩阵中的每一行重复这一过程,将得到一个 4×1 的导数矩阵,然后与误差矩阵相乘。
将误差和导数相乘可以得到所需的变化。当 sigmoid 函数输出具有更高置信度的值(接* 0 或接* 1)时,导数将更小,因此所需的变化将更小。如果 sigmoid 函数输出更接*. 50 的值,则导数是更大的值,这意味着需要更大的变化,以便神经网络变得更有信心。
这一步将导致添加到权重中的更新。我们可以通过将上述步骤中的“误差加权导数”与输入相乘来获得此更新。如果输入中的要素为 0,则权重的更新将为 0,如果输入中的要素为 1,则更新将添加到中。这将产生一个(3×1)矩阵,它与我们的权重矩阵的形状相匹配。
一旦我们有了更新的矩阵,我们可以将它添加到我们的权重矩阵中,以正式更改权重,使其变得更强。即使在一次训练迭代之后,也有一些明显的进步!如果查看更新后的权重矩阵,您可能会注意到矩阵中的第一个权重值更高。记住,我们的神经网络必须知道输入中的第一个特征决定了输出。我们可以看到,在每个输入示例中,我们的神经网络已经为连接到第一个特征的权重分配了更高的值!
**def** **train**(self, epochs**=**25000):
**for** epoch **in** range(epochs):
self**.**feed_forward()
self**.**backpropagation()
self**.**error_history**.**append(np**.**average(np**.**abs(self**.**error)))
self**.**epoch_list**.**append(epoch)
训练神经网络的时候到了。在训练过程中,神经网络将“学习”输入数据中的哪些特征与其输出相关,并且它将学习做出准确的预测。为了训练我们的神经网络,我们将创建具有 25,000 个历元或迭代次数的训练函数。这意味着神经网络将重复权重更新过程 25,000 次。在 train 函数中,我们将调用我们的feed_forward()
函数,然后调用backpropagation()
函数。对于每次迭代,我们还将跟踪在feed_forward()
函数完成后产生的错误。我们将通过将错误和纪元附加到先前初始化的列表来跟踪这一点。我确信有一种更简单的方法可以做到这一点,但是对于快速原型开发来说,这种方法现在已经很好了。
对于我们神经网络中的每个权重,训练过程遵循以下等式:
- xᵢ —输入数据中的特征
- wᵢ —正在更新的重量
- Xᵀ —转置输入数据
- y —正确输出
- ŷ —预测产量
- (y — ŷ ) —错误
- ∑xᵢwᵢ-输入特征和权重的乘积之和
- S(∑xᵢwᵢ) —乙状结肠功能
**def** **predict**(self, new_input):
prediction **=** self**.**sigmoid(np**.**dot(new_input, self**.**weights))
**return** prediction
既然神经网络已经被训练并且已经学习了输入数据中的重要特征,我们就可以开始进行预测了。预测函数看起来类似于隐藏层,或feedforward()
函数。前向传播函数本质上也进行预测,然后反向传播检查误差并更新权重。我们的预测函数将使用与前馈函数相同的方法:将输入矩阵和权重矩阵相乘,然后通过 sigmoid 函数返回 0-1 之间的值。希望我们的神经网络能够做出尽可能接*实际输出的预测。
NN = NeuralNetwork(inputs, outputs)
我们将从 NeuralNetwork 类创建 NN 对象,并传入输入矩阵和输出矩阵。
NN.train()
然后我们可以在我们的神经网络对象上调用.train()
函数。
example **=** np**.**array([[1, 1, 0]])
example_2 **=** np**.**array([[0, 1, 1]])
**print**(NN**.**predict(example), ' - Correct: ', example[0][0])
**print**(NN**.**predict(example_2), ' - Correct: ', example_2[0][0])
输出
[[0.99089925]] - Correct: 1
[[0.006409]] - Correct: 0
现在我们可以创建两个新的例子,我们希望我们的神经网络对其进行预测。我们将这些称为“示例”和“示例 _2”。然后我们可以调用.predict()
函数并传递数组。我们知道,输入中的第一个数字或特征决定了输出。第一个示例“example”在第一列中有一个 1,因此输出应该是 1。第二个示例在第一列中有一个 0,因此输出应该是 0。
plt**.**figure(figsize**=**(15,5))
plt**.**plot(NN**.**epoch_list, NN**.**error_history)
plt**.**xlabel('Epoch')
plt**.**ylabel('Loss')
训练完成后,我们可以绘制每次训练迭代的误差。该图显示,在较早的时期,误差有很大的下降,但是在大约 5000 次迭代之后,误差稍微稳定下来。
我希望这是对使用 python 和面向对象方法的神经网络的一个很好的介绍。
简而言之:ML 奖学金令人不安的趋势
原文:https://towardsdatascience.com/inshort-troubling-trends-in-ml-scholarship-974de1fc9a26?source=collection_archive---------26-----------------------
简要回顾 ML 出版中的错误。
Photo courtesy of Robbie Sproule/ CC BY 2.0
机器学习研究人员很早就注意到同行评议的科学成果质量不高。(这并不是说该领域的学术严谨程度普遍较低,而是说非常不一致。)
本文基于 Z. C. Lipton 和 J. Steinhardt 的论文机器学习学术中令人不安的趋势,传播了 ML 文献中常见的质量问题。它总结了要点,并添加了一些额外的评论。如果你是一名(有抱负的)ML 研究者或者对这个话题感兴趣,我强烈推荐这篇可读性很强的原创论文。
我们是怎么到这里的?
在过去十年中,机器学习社区的规模实际上呈爆炸式增长。2010 年代初的巨大成功激起了人们的兴奋,导致了大量的资金,许多年轻的研究人员加入了这个社区。虽然对该领域的这种兴趣自然有利于进步,但它也带来了自身的一系列问题,我们可以推测它们导致了不一致的出版质量。
该领域研究人员的突然增加增加了向相关同行评审场所提交的数量。这给审查者带来了沉重的负担,他们随后每次审查花费的资源更少,但这也意味着人才库中有许多年轻和缺乏经验的审查者。很明显,在这种情况下,评论质量和出版质量必然会受到影响。
此外,ML 研究与行业利益和投资密切相关,一些研究人员还创办了初创企业,将他们的发现投入到盈利实践中。虽然学术成果被转化为有用的系统是一个受欢迎的趋势,但由此产生的对行业资金和媒体报道的依赖可能会刺激研究人员以耸人听闻的方式传播他们的发现,并牺牲写作的精确性和方法的严谨性来换取可销售的主张。
也许,由于强大的实证结果是最*社区扩展的基础,基准方面的进展似乎对一些研究来说已经足够了,并被用作不太严谨的写作的借口。
实际问题是什么?
作者挑出了四个在 ML 社区中相对常见的糟糕学术的具体例子。当然,它们不是 ML 研究独有的,但由于该领域的当前状态,可能更普遍,如上所述。
解释和推测往往不能清楚地分开。虽然两者都在学术出版物中占有一席之地,但重要的是读者能容易地区分它们。如果不是这样的话,作者冒着读者把推测误认为有根据的主张的风险,并在他们自己的写作中延续它。
一些人工智能论文的另一个弱点是,它们无法准确指出它们的经验收益来自哪里。当同时引入多个架构创新时,一些作者未能调查这些变化中的哪一个实际上有助于提高性能。此外,更好的结果可能只是不同训练程序的结果,例如更好的超参数调整。消融研究,其中一个或多个创新被遗漏的时间,是一个有价值的工具,调查来源的经验收益。
数学陈述的加入与论文的实际内容没有很强的联系。作者称这种趋势为 mathiness,可能是另一种让论文看起来更有根据并给没有经验的同行评审留下深刻印象的方式。数学对于精确传达服从于这种表述的思想是无价的,但是仅仅为了显得更“科学”而提供数学陈述或定理会损害可读性并混淆出版物的信息。
语言使用不准确。这一趋势有多个方面。首先,也许是由于该领域大量缺乏经验的研究人员和大量的研究成果,技术术语并不总是按其原意使用。这导致一些术语积累了多重含义,并在使用这些术语时产生歧义。
其次,引入带有暗示意义的术语,往往将机器拟人化。这导致了意识或公*等宏大概念与简单的统计特性或算法设计选择的融合。这种语言的使用不仅不真诚,而且会让其他领域的专家和外行人感到困惑。
如何从这里着手?
作者提到了好的出版物所具有的特点,并给作者和评论者提供了如何改善 ML 文献的建议。
好的论文应该为读者提供直觉,而不仅仅是陈述事实,此外,它应该总是考虑对观察到的效应的替代解释,在经验和理论分析之间有明确的联系,并使用精确和表达性的术语。
除了避免上面的反模式,作者建议进行错误分析、消融研究和健壮性检查,以阐明什么有效以及为什么有效。
关于在相关工作中已经取得的成就和尚未解决或已经解决的问题的语言应该是清楚的,以免使读者困惑。
评价者可以更有利地看待负面结果的报告,并且出版商可以促进使用冷静和精确语言的清晰书面评价论文的创建。
感谢阅读,别忘了查看原文:https://arxiv.org/abs/1807.03341。它充满了正面和负面的同行评议科学交流的例子。
内部无头 CMS
原文:https://towardsdatascience.com/inside-headless-cms-abf4761f3a8?source=collection_archive---------16-----------------------
学习并理解 headless CMS 的强大功能,它是可以加速应用程序开发的工具。
在本文中,我们将了解无头 CMS,了解它的优点,以及何时应该使用它。我们还将讨论主要的局限性。为了更好地理解 HCMS 是如何在幕后工作的,我将解释我如何设计和构建 RawCMS,一个 Aspnet。具有 Oauth2、扩展插件系统和业务逻辑支持的核心无头 CMS。该解决方案在 GitHub 上可用,并作为演示发布在 Docker Hub 上。
Photo by Sincerely Media on Unsplash
什么是无头 CMS?
传统的内容管理系统将内容和呈现部分结合在一起,而无头的内容管理系统只关注内容。这似乎是一个限制,因为几乎不说话你会失去一些东西。HCMS 的目的是将逻辑从内容中分离出来,使变更管理变得简单,并将复杂的应用程序分解成许多组件,每个组件都有自己的职责。
朝着这个方向发展,HCMS 可以取代你所说的后端,并节省大量创建 CRUD 语句的有用工作。
HCMS 生来就是为了创建一个多组件的应用程序,你可以在其中快速改变表示逻辑和设计,当你在现代网站或应用程序上工作时,这是一个很大的改进,因为业务需求,你需要每年重新设计\改变 UI 一次。
许多供应商销售他们的产品并贴上“HCMS”的标签,只是因为它是分离的(因为它听起来很酷,可能会促进销售)..).在我看来,我与最初的 integralist 定义严格相关:headless cms 意味着 API 优先,非单片 cms,与接口或其他组件完全解耦。
无头 CMS 的优势
为什么要用无头 CMS?我可以简单地说,在某些场景中,解耦系统、简化前端替换和加速开发阶段可能是有用的,但是我觉得有必要使用项目列表来更好地解释。
- 全渠道就绪性:在无头 CMS 中创建的内容是“纯”的,您可以在任何您想要的上下文中使用。如果你在上面存储了一些新闻内容,你也可以在公共网站或内部网发布,把数据输入保存在一个地方。
- 低运营成本:无头 CMS 是一个产品,所以,一旦你选择了一个好的,我希望它将即插即用。此外,与定制解决方案相比,供应商免费提供更新和错误修复。
- 缩短上市时间:无头 CMS 促进了敏捷的工作方式。您可以让多个团队参与后端和前端工作,这样可以减少时间。此外,因为 HCMS 地区有一个关于 API 消费的数据存储的垂直解决方案,大部分事情都已经完成了,所以你必须专注于数据设计而不是技术细节(就像浪费时间去考虑有效负载,而你可以免费使用 Odata 或 Grahql)。
- 垂直解决方案:HCMS 做了一件事,这使得它非常容易学习和维护。
- 灵活性:一旦你选择了你的 HCMS(本地或云),你的开发者可以使用任何他们喜欢的语言来实现前端。这意味着你可以不受技术的限制。
无头 CMS 解决方案的局限性
与传统的 CMS 相比,HCMS 还很年轻,因此,即使很多产品在过去几年诞生,大多数产品还没有成熟到完全取代传统的 API 后端。在这一段中,我将分享我发现的局限性的经验。根据具体的产品以及是本地解决方案还是 saas 解决方案,功能可能会有很大差异。
实际上,CMS 的无头限制主要有两种:
- 使用 HCMS 的缺点
- 您安装的产品的限制
使用 HCMS 的缺点
HCMS 需要雇佣多个团队来从工作并行化中获益。此外,由于 HCMS 没有任何渲染,所有的表示逻辑都需要客户端来完成。这有利于解耦,但在所有情况下,您只有一个消费者。解耦的优势不太相关,并且您会在数据获取过程中引入更多的复杂性和延迟。另一个问题是关于商业逻辑。在哪里实施?如果你不想在 HCMS 中实现,你必须把它放到表示层,并且有多个消费者,你会复制它,当逻辑在多个地方时,你会遇到问题。否则,尝试将其放入 HMS 时,您会发现大多数云解决方案\产品并不那么灵活。这就引出了下一个话题,HCMS 的局限性是什么?
HCMS 的局限性
测试最重要的 HCMS 解决方案会遇到许多困难,以下是最常见的限制列表。考虑到这取决于产品,有人可能有或没有,但一般来说,大多数是相当普遍的。
- 针对外部提供者的身份验证:大多数解决方案不允许针对外部系统对用户进行身份验证。我说的是最常见的场景,其中您有一个中央身份认证系统,所有各方都通过用户令牌\票证来代表用户进行操作。换句话说,如果我有一个 oauth2 服务器,我想在前端进行身份验证,并使用令牌调用内部网的所有应用程序,而不仅仅是 HCMS,并被识别为我自己。
- 非标准输出格式:有些使用 GraphQL 或 Odata,这很好,因为它提供了一种数据消耗的标准方法。问题是“一些”并不意味着“全部”,所以你必须注意选择你的 HCMS。
- 业务逻辑:在大多数情况下,不可能在运行时定义业务逻辑,在某些情况下,也不能扩展核心应用程序。可扩展性:很难找到一个可以编写自己的代码、修改业务逻辑或添加额外内容的解决方案。这部分是因为许多供应商将其 HCMS 设计为哑数据存储,部分是因为管理可扩展性的复杂性。
何时何地使用无头 CMS?
Headless CMS 是一个很好的机会,但我们必须了解什么是利用它来优化成本效益比的最佳方案。问题是,使用常规 HCMS,定制是非常有限的,所以如果你不是在正确的场景中,将很难混合 HCMS 来实现业务需求。此外,使用它就像一个光秃秃的数据存储使它毫无意义的事情。
当使用 HCMS 方便时:
- 在这段时间里,用户界面发生了很多变化
- 共享相同信息的许多应用程序和管理这些信息的一个团队
- 你对数据没有什么商业逻辑
- 你可以雇佣多个团队(be+fe)
何时不使用 HCMS:
- 有一种垂直解决方案可以满足您的需求。你想用 WordPress 写博客)
- 你很有商业逻辑
- 你不是数据的主人
兴趣点
HCMS 很棒,因为它们通过设计将表示层与后端分离,这是一个很好的驱动因素。HCMS 是一个很好的机会,但是现在,除非有非常简单的业务逻辑和定义良好的行为,否则很难在实际项目中使用。如果能克服这些限制并将其用作“通用后端”就太好了,在这里,您只需花时间来教授系统有关数据模式、关系的知识,并只调整非标准的内容。问题是,总的来说,这很难实现。
在这里你可以找到关于无头 CMS 和关于我的实现的源代码的 git-hub 的完整文章。
觉得这篇文章有用?在 Medium 上关注我(丹尼尔·丰塔尼),看看我下面最受欢迎的文章!请👏这篇文章分享一下吧!
- Docker 到底是什么?
- 【Kubernetes 到底是什么?
- 如何使用 Kubernetes 部署 web 应用程序
对傅里叶变换的理解及其简单实现
原文:https://towardsdatascience.com/insight-to-the-fourier-transform-and-the-simple-implementation-of-it-eee293317efd?source=collection_archive---------13-----------------------
source: https://pa1.narvii.com/6397/fbeec74f0468cf51eb46f4f869190563cf50829b_hq.gif
在这篇文章中,我不会给你一个傅立叶变换或傅立叶级数的推导细节。相反,我们将探索这种转换的输出以及它是如何工作的。
因此,我们将在这个故事中讨论的傅里叶变换公式被称为离散傅里叶变换(DFT)。公式是这样的。
X is the output of DFT (signal in frequency spectrum), x is signal input (signal in time spectrum), N is a number of sample and k is frequency (limited in 0 to N-1 Hz). Source: https://en.wikipedia.org/wiki/Discrete_Fourier_transform
它用于将信号的有限样本从时间频谱转换到频率频谱。坚持住!时间谱和频率谱中的信号是什么?我所指的时间频谱中的信号只是一个时间序列数据,如随时间变化的股价、随时间变化的降雨率等。
example of time series data: USGS streamflow over time data. Source: https://d32ogoqmya1dw8.cloudfront.net/images/geoinformatics/steps/1354035151.png
如果我们在 2d 图中绘制时间序列数据,我们将在 x 轴上得到时间,在 y 轴上得到幅度(或在波的情况下的振幅)。因此,与频谱中的信号不同的是,如果我们将其绘制在 2d 图中,我们将在 x 轴获得频率,在 y 轴获得幅度。
好了,现在我们知道了 DFT 的实际输出,但是它是如何工作的?你知道你可以用 DFT 公式的一部分产生任意频率的周期正弦波吗?你可以用这个零件来生产那个。
您可以使用下面的脚本来可视化这个公式生成的波。
#!/usr/bin/python3import numpy as np
from matplotlib import pyplot as plt#setting
k = 2
res = 400t = np.linspace(0, res, res)time = np.linspace(0, 1, res)
hz = np.exp(-2j * np.pi * k * t / len(t))plt.ylabel("Amplitude")
plt.xlabel("Time")
plt.plot(t, hz)
plt.show()
你会得到这样的东西
对于 k =2,我们得到一个 2 Hz 正弦波,如果我们设置 k = 10
我们得到了一个 10 赫兹的正弦波。
(再)坚持住!这个公式有一个“I”,这意味着输出必须有一个虚部。是,右边这个部分公式的输出是幅度+(相位)I。在这个上下文中,相位大约是正弦波的一个角度。
在这个故事中,为了简单起见,我们将忽略虚部,也就是所谓的相位,并且我们不会在这个故事中使用它作为我们的实现示例。
在 DFT 的完整公式中,你要在你的实信号和 k Hz 的正弦信号之间做一个点运算。这就是为什么你可以从真实信号中提取 k Hz 正弦波的一个分量。你将从 0 Hz 提取到 k-1 Hz** 。但是,有一个情节转折?在现实世界中,我们不会使用普通的 DFT 来提取它,而是使用快速傅立叶变换(FFT)来提取。FFT 只是一种更有效的计算 DFT 的方法。我们不会在这个故事中讨论 FFT 算法,但是为了你的信息,普通 DFT 和 FFT 的结果几乎是相同的。**
这就是理论,现在我们将实施它。通过傅立叶变换,我们将尝试计算出哔哔声的频率。我们将在这个实验中使用这个声音。让我们用这个脚本来看看这个声音的“形状”。
#!/usr/bin/python3from scipy.io import wavfile
from matplotlib import pyplot as plt
import numpy as np#setting
datasound = '7detik.wav'fs, data = wavfile.read(datasound)
data = np.array(data, dtype=float)#normalize
data = (data - np.mean(data)) / np.std(data)time = range(len(data))plt.ylabel("Amplitude")
plt.xlabel("Time")
plt.plot(time, data)
我们得到了这个。
要将这些数据从时间频谱转换到频率频谱,也就是 FFT,让我们运行下面的脚本。
#!/usr/bin/python3from scipy.io import wavfile
from matplotlib import pyplot as plt
import numpy as np#setting
datasound = '7detik.wav'fs, data = wavfile.read(datasound)
data = np.array(data, dtype=float)
#print(len(data), np.shape(data), fs)#normalize
data = (data - np.mean(data)) / np.std(data)time = range(len(data))fftdata = np.fft.fft(data)
fftdatafreq = np.zeros((len(data)))
for i in range(len(fftdata)):
fftdatafreq[i] = abs(fftdata[i].real)plt.ylabel("Amplitude")
plt.xlabel("Frequency")
plt.plot(time, fftdatafreq)
plt.show()
你会得到这样一个图表。
哇,在一些或一个频率和另一个频率之间有一个巨大的差异振幅。其实,FFT 的输出是对称的(看看上图就知道了,)。这意味着我们只需要一半的频率来显示。
plt.plot(time[:len(fftdatafreq) // 2], fftdatafreq[:len(fftdatafreq) // 2])
我们得到了下图。
好了,现在是有趣的部分。我们将尝试计算出这种哔哔声的频率。让我们用这个代码检查具有最高振幅的 bin。
maxfreq = np.argmax(fftdatafreq)
print('dominant freq ', maxfreq)
结果是
dominant freq 6009
6009?这是不是意味着这个嘟嘟声的频率是 6009?没那么快!我们在这里使用的 FFT 函数
fftdata = np.fft.fft(data)
假设我们数据的总持续时间是 1 秒,尽管实际上并不是这样。让我们检查一下哔哔声的实际持续时间。该功能
fs, data = wavfile.read(datasound)
返回 1 秒(fs)内的采样率和声音(data)的数组真实数据。让我们检查 fs 的值和数据数组的长度。
print(len(data), fs)
是回归
265039 44100
所以数组的长度是 265039,采样率是 44100。并且查看声音的持续时间是 265039 / 44100 = 6.009954648526077 秒。
表示在这 6.009954648526077 秒中,我们的主频已经形成了 6009 个当时的正弦波。从逻辑上思考,所以主频是6009/6.009954648526077 = 999.8411554525939Hz或者我们可以把这个数四舍五入到 1000 Hz 。总结一下,我们的嘟嘟声的频率是 1000 Hz。要验证它只需谷歌“1000 赫兹声音”。
播放视频并与我们的哔哔声进行比较。非常相似不是吗?
仅此而已。FFT 的应用非常广泛,尤其是在电气工程中。最初的计划是我想用 FFT 计算出每日降雨量的模式,但是我的降雨量数据并不充分。另一篇文章再见。
检查 15 年 CDC 慢性病数据集
原文:https://towardsdatascience.com/inspecting-a-cdc-chronic-disease-dataset-e1685a6b525a?source=collection_archive---------10-----------------------
使用 Python 和数据科学技术对人口健康指标进行探索性数据分析
Photo by Dan Gribbin on Unsplash
最*,我接受了一个个人项目,以应用我一直在学习的 Python 和机器学习。由于我对人口健康感兴趣,我决定从了解我在 Kaggle 上找到的 15 年人口健康特定数据集开始。这个数据集来自美国疾病控制和预防中心的慢性病指标。在这个博客系列中,我想用 exploration 演示数据集中有什么。稍后,我将深入探讨数据可视化。目前,我不确定我是否看到只有这个数据集的实际机器学习的机会。
根据 Kaggle 的概述,该数据集中提供的有限背景信息指出,这些指标是从 2001 年到 2016 年在州一级收集的,共有 202 个指标。使用 jupyter notebook 和文件上的 pd.read_csv(),有 403,984 行,34 列,或属性。通过跑步。info()方法,下面输出中的第二列显示我们有一些丢失的数据。在下面的最后一列中,有不同类型的数据,其中一些是数字型的,比如整数和浮点值,而另一些是包含字符串的对象。
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 403984 entries, 0 to 403983
Data columns (total 34 columns):
YearStart 403984 non-null int64
YearEnd 403984 non-null int64
LocationAbbr 403984 non-null object
LocationDesc 403984 non-null object
DataSource 403984 non-null object
Topic 403984 non-null object
Question 403984 non-null object
Response 79323 non-null object
DataValueUnit 374119 non-null object
DataValueType 403984 non-null object
DataValue 297817 non-null object
DataValueAlt 273666 non-null float64
DataValueFootnoteSymbol 188019 non-null object
DatavalueFootnote 187853 non-null object
LowConfidenceLimit 246819 non-null float64
HighConfidenceLimit 246819 non-null float64
StratificationCategory1 403984 non-null object
Stratification1 403984 non-null object
StratificationCategory2 79323 non-null object
Stratification2 79323 non-null object
StratificationCategory3 79323 non-null object
Stratification3 79323 non-null object
GeoLocation 401416 non-null object
ResponseID 79323 non-null object
LocationID 403984 non-null int64
TopicID 403984 non-null object
QuestionID 403984 non-null object
DataValueTypeID 403984 non-null object
StratificationCategoryID1 403984 non-null object
StratificationID1 403984 non-null object
StratificationCategoryID2 79324 non-null object
StratificationID2 79324 non-null object
StratificationCategoryID3 79323 non-null object
StratificationID3 79323 non-null object
让我们了解一下每个专栏都是关于什么的。虽然有些列名相对来说不言自明,但我使用 set(dataframe['ColumnName'])来更好地理解唯一的分类数据。以下是一些例子:
题目 : 400k+行数据分为以下 17 类。有一个名为 TopicID 的对应列,它只是给出了一个缩写的标签。
{'Alcohol',
'Arthritis',
'Asthma',
'Cancer',
'Cardiovascular Disease',
'Chronic Kidney Disease',
'Chronic Obstructive Pulmonary Disease',
'Diabetes',
'Disability',
'Immunization',
'Mental Health',
'Nutrition, Physical Activity, and Weight Status',
'Older Adults',
'Oral Health',
'Overarching Conditions',
'Reproductive Health',
'Tobacco'}
Distribution of the data by topic. Diabetes, Chronic Obstructive Pulmonary Disease, and Cardiovascular Disease are the top 3 topics
问题:在每个话题中,都有一些问题。我们将使用相应的列 QuestionID。这些是数据集具有值的 202 个唯一指标,我们将对此进行进一步分析。
{'Activity limitation due to arthritis among adults aged >= 18 years',
'Adults aged >= 18 years with arthritis who have taken a class to learn how to manage arthritis symptoms',
'Adults with diagnosed diabetes aged >= 18 years who have taken a diabetes self-management course',
'Alcohol use among youth',
'Alcohol use before pregnancy',
'All teeth lost among adults aged >= 65 years',
'Amount of alcohol excise tax by beverage type (beer)',... 'State child care regulation supports onsite breastfeeding',
'States that allow stronger local tobacco control and prevention laws',
'States with strong polices that require retail licenses to sell tobacco products',
'Taking medicine for high blood pressure control among adults aged >= 18 years with high blood pressure',
'Television viewing among high school students',
'Timeliness of routine health care checkup among women aged 18-44 years',
'Visits to dentist or dental clinic among adults aged >= 18 years',
'Visits to dentist or dental clinic among adults aged >= 18 years with diagnosed diabetes'}
数据源:考虑到我们有这么多的指标,有 33 个数据源我并不奇怪。然而,下面的直方图显示,大部分数据来自两个来源,BRFSS,即 CDC 的行为风险因素监测系统和 NVSS,即国家生命统计系统。
{'ACS 1-Year Estimates',
'ACS 5-Year Estimates',
'AEDS',
'ANRF',
'APIS',
'ASHW',
'BRFSS',
'Birth Certificate, NVSS',
'CDC Breastfeeding Report Card',
"CDC Children's Food Environment State Indicator Report",
'CDC School Health Profiles',
'CMS CCW',
'CMS Part A Claims Data',
'Current Population Survey',
'Death certificate',
'HRSA, UDS',
'InfoUSA; USDA',
'Legal Research',
'NSCH',...
CDC’s BRFSS and NVSS make up almost the entirety of this dataset
data value unit:data value 中的值由以下单位组成,包括百分比、金额、年份和千例数。
{' ',
'$',
'%',
'Number',
'Number ',
'Years',
'cases per 1,000',
'cases per 1,000,000',
'cases per 10,000',
'cases per 100,000',
'gallons',
nan,
'pack sales per capita',
'per 100,000',
'per 100,000 residents'}
DataValueType :以下几个类别很有见地,表明当我们想要查看跨州数据比较时,有年龄调整后的数字与原始数字相比较,这有助于我们进行比较。
{'Adjusted by age, sex, race and ethnicity',
'Age-adjusted Mean',
'Age-adjusted Prevalence',
'Age-adjusted Rate',
'Average Annual Age-adjusted Rate',
'Average Annual Crude Rate',
'Average Annual Number',
'Commercial host (dram shop) liability status for alcohol service',
'Crude Prevalence',
'Crude Rate',
'Local control of the regulation of alcohol outlet density',
'Mean',
'Median',
'Number',
'Per capita alcohol consumption',
'Percent',
'Prevalence',
'US Dollars',
'Yes/No'}
数据值 vs 数据值 Alt :数据值似乎是我们未来分析的目标数据列。使用。head()方法,该列由 string 对象形式的数值组成,而 DataValueAlt 是数值 float64。后来,我想使用 pandas pivot_table 方法,它只需要数字数据。因此,我将使用 DataValueAlt 进行后续分析。
分层和分层类别相关列:与分层相关的列有 12 列,是性别、种族、年龄等每个指标内的子组。在分层类别 1 中,有性别、总体和种族。例如,在分层 1 中,值由种族类型组成。在 ID 列中,如分层 ID1,我们有相应的种族标签。
缺失数据:
使用下面的 matplotlib 和 seaborn 生成热图,很容易看到哪里有数据,哪里缺少数据以及缺少多少数据。黄色代表丢失的数据。列是每个指标,纵轴是 40 万行数据。
import matplotlib.pyplot as plt
%matplotlib inlineplt.figure(figsize=(16, 6))sns.heatmap(df.isnull(),yticklabels=False,cbar=False,cmap='viridis')
Large portions of missing data is related to Stratification Categories 2 and 3 and the related Stratification 2 and 3. The horizontal axis consists of the column names.
在热图中,响应和与分层类别 2/3 和分层 2/3 相关的列包含的数据不到 20%。虽然分层类别 1 和分层 1 似乎有潜在有用的数据,但让我们确认 2 和 3 中有什么数据。对于每个分层列,我遵循类似的方法:
df['StratificationCategory2'].count()df_strat2cat = []for i in df['StratificationCategory2']:
if (pd.isnull(i) is False):
if i is not ' ':
df_strat2cat.append(i)
例如,列的计数返回 79k,其中包含数据。我想看看里面有什么,所以我设置了 for 循环来遍历特定分层 2 或 3 列中的每个元素,并将非空值或带有空格的值追加到一个名为 df_strat2cat 的新数组中。这意外地产生了一个没有值的数组。在对其他分层列重复此操作后,我删除了这组列。
df_new = df.drop(['Response','ResponseID','StratificationCategory2','StratificationCategory3','Stratification2','Stratification3','StratificationCategoryID2','StratificationCategoryID3','StratificationID2','StratificationID3' ],axis = 1)<class 'pandas.core.frame.DataFrame'>
RangeIndex: 403984 entries, 0 to 403983
Data columns (total 24 columns):
YearStart 403984 non-null int64
YearEnd 403984 non-null int64
LocationAbbr 403984 non-null object
LocationDesc 403984 non-null object
DataSource 403984 non-null object
Topic 403984 non-null object
Question 403984 non-null object
DataValueUnit 374119 non-null object
DataValueType 403984 non-null object
DataValue 297817 non-null object
DataValueAlt 273666 non-null float64
DataValueFootnoteSymbol 188019 non-null object
DatavalueFootnote 187853 non-null object
LowConfidenceLimit 246819 non-null float64
HighConfidenceLimit 246819 non-null float64
StratificationCategory1 403984 non-null object
Stratification1 403984 non-null object
GeoLocation 401416 non-null object
LocationID 403984 non-null int64
TopicID 403984 non-null object
QuestionID 403984 non-null object
DataValueTypeID 403984 non-null object
StratificationCategoryID1 403984 non-null object
StratificationID1 403984 non-null object
dtypes: float64(3), int64(3), object(18)
使用 df_new,seaborn 热图显示最少的黄色和大部分紫色。如果我们想更进一步,我们可以填充缺失的数据,但此时,我将把额外的工作留到稍后阶段。
概括地说,我使用 pandas 将 CSV 数据文件导入到数据帧中。然后,我使用各种方法来更好地理解每一列中的数据,因为上下文信息非常有限。分层 2 和 3 列的组是无用的,并且这些被移除。在下一篇文章的中,我们将采用生成的数据框架来理解数据,甚至进一步理解具体指标之间的关系。
阅读分析的第二部分:https://medium . com/@ Daniel Wu 3/relationships-validated-between-population-health-chronic-indicators-b 69e 7a 37369 a
受到乐观主义的启发,与技术联姻,跨越人工智能鸿沟
原文:https://towardsdatascience.com/inspired-by-optimism-married-to-technology-crossing-the-ai-chasm-2c5cad993faf?source=collection_archive---------29-----------------------
下面的视频(长度 17 分钟。)在今年早些时候出版了,我仍然发现它鼓舞人心,并惊叹于由影响力和资源支持的乐观主义的力量。
技术如何成为解决自动化和人工智能导致的预期失业的积极力量?
根据一项研究,在未来十年,数百万工人可能需要改变职业,根据自动化/人工智能的采用速度,占全球劳动力的 2-14%。
如果你是下面图表中的一种工作类型(来自《经济学家》关于人工智能在全球的影响),并且你目前正在做卷饼、给建筑物换墙板或打扫房间,那么获得自动化取代风险较低的工作的道路可能会很陡峭。
这就引出了一个问题,即乐观情绪如何传播到美国人口中,根据这份麦肯锡报告,这些人口预计在经济上受自动化和人工智能影响最大:
“我们测量了到 2030 年因自动化而可能失去的工作岗位的百分比,发现由于他们集中在面临自动化风险的职业中,与其他群体相比,非裔美国人的潜在工作岗位转移率最高。”这意味着“到 2030 年,由于自动化,可能会失去大约 132,000 个非裔美国人的工作岗位。”
这些挑战对男性来说可能比女性更大。麦肯锡的论文指出,例如,非裔美国女性在 K-12 教育、护理和其他护理职业中的参与率较高,这使她们有更多机会获得医疗保健和教育部门的预期就业增长。这些工作“自动化潜力较低,因为需要动态的、身体的运动和深层的人际关系。”
虽然有些人提议以土地的形式进行赔偿,作为对非裔美国人当前和未来似乎根深蒂固的不*等的答案,但也许还有其他方法。
如果像小学教师或护士助理(和监狱看守)这样的“高接触”护理工作在不久的将来流失的风险很低,但对教育要求最低的入门级工作却有很高的风险,那么许多企业应该承担什么责任,这些企业更愿意雇用拥有“立即进入角色”的技术技能的工人,而不是培训他们所需的技能?
虽然有些人认为大学教育补贴是答案,但引用我一个更保守的 T2 熟人的话:
“研究表明,受教育程度越高的人挣钱越多。但这完全是误导。拥有私人飞机的人也赚更多的钱,但这并不意味着你买了湾流就会变得更富有。”
我想知道,是否有理由让人们更容易获得工具和 MOOCs,以比传统大学或训练营低得多的成本提供技能培训。如果像斯科特·贝尔斯基在“创造力是新的生产力”中所提出的那样,创造性工作不太可能自动化,那么或许获得这一新的繁荣所需的设备和软件就是答案。
Image by James Doucette
进入“创造力与生产力”领域存在成本障碍。例如,为了开始使用 Adobe 套件,你需要一台电脑(约 1000 美元)、软件(约 600 美元)、互联网接入(约 60 美元)和认证测试(约 80 美元)。对于每月最低工资估计为 1084.40 美元(税后)的人来说,这可能是一个挑战。然而,更有可能的障碍是围绕大学学位要求和微观证书的招聘实践。虽然像 EdX 这样的机构提供“微观硕士”,但接受独立于机构的成绩单而不是完整的学位(区块链?)是否能被招聘机构同等程度地接受,似乎还很遥远。
解决方案可能来自公私合作,就像最*宣布的 Udacity 一样。Udacity 承诺每年向 2 万名申请人提供免费的入门技术培训课程,面向“希望学习获得高薪工作和职业发展所需的热门技能的低收入个人。”此外,“该公司还将考虑向完成初步培训的人提供认证,以此表明成就,并展示对潜在雇主有意义的技能。”这一决定可能是因为大多数工人没有为“更强大的纳米学位项目”做好准备。如果候选人范围变得更窄,需要熟练技术员工的公司会愿意绕过对非大学学位申请者的“筛选”吗?或者那些有技能但没有学位的人会成为亚马逊土耳其人的奴隶吗?
是像商业圆桌会议的学徒制 2020 那样的努力,专注于目前在芝加哥城市学院注册的大学生(新内容/旧交付模式),还是 Udacity 的奖学金(直接面向社区经理的消费者——面向自学者)提供解决方案?还是会有其他更有机的方式,对社区做出承诺的公司不仅通过在施粥场做志愿者和粉刷公园长椅,还通过激发灵感为那些很快被落在后面的人提供替代路线来回报。在就业中心做志愿者?在大厅借笔记本电脑?或者像 Sans Institute 这样不那么依赖股东的组织会开始在网络安全方面培训高中生吗?(一些最优秀的黑客才十几岁)。
Image by James Doucette
不管是好是坏,我们的未来都与科技结下了不解之缘,注意到在所有的关系中,分开一段时间没有坏处。解决不*等的挑战摆在我们面前,有待我们去解决。
对于那些喜欢更深入地阅读第二版“恩格尔的停顿”的人来说,可以随意深入阅读 80 多页,点击这里的“技术为好”。
Instacart 市场购物篮分析第一部分:哪些杂货商品受欢迎?
原文:https://towardsdatascience.com/instacart-market-basket-analysis-part-1-which-grocery-items-are-popular-61cadbb401c8?source=collection_archive---------14-----------------------
深入分析
通过土星云对 Instacart 订单的探索性数据分析
作为一名数据科学家,我的很大一部分职责是与业务利益相关方分享我的成果。作为一名数据记者,我的很大一部分职责是与我的读者分享代码块。
现在,我分享的报告需要在网络上正确呈现。我分享的代码也需要是可复制的。
土星云为我解决了这两个用例。
怎么会?
在这个由 3 部分组成的博客系列中,我将通过一个例子向您展示我如何使用土星云来传达我的结果。特别是,我将致力于 Instacart 市场购物篮分析,显示 Instacart 消费者会再次购买哪些产品的结果。
Instacart 数据集
Instacart 是一款杂货订购和配送应用,是我最喜欢的技术*台之一。作为一名学业繁忙的研究生,我根本没有时间去买菜。Instacart 的目标是让网上购物变得简单,只需轻触一个按钮。顾客通过 Instacart 应用程序选择产品后,个人购物者会审核订单,并为顾客进行店内购物和送货。你可以把 Instacart 想象成杂货店购物的优步。
早在 2017 年,该公司宣布了其首次公开数据集发布,该数据集是匿名的,包含来自 20 多万 Instacart 用户的 300 多万份杂货订单样本。目标是预测哪些以前购买的产品将出现在用户的下一个订单中。在这篇文章中,我将做一些探索性的分析,以获得关于数据集的一些表层见解。
产品
首先,让我们探索 Instacart 产品的数据。有两个 CSV 文件,即 order_products_train 和 order_products_prior ,指定每个订单购买了哪些产品。更具体地说, order_products_prior 包含所有客户以前的订单产品,而 order_products_train 仅包含某些客户的最新订单产品。
订单 _ 产品 _ 列车文件中有 1384617 件产品,订单 _ 产品 _ 之前文件中有 32434489 件产品。两个文件都有 4 个特征列:
- 订单的 ID(order _ ID
- 产品的 ID(product _ ID
- 订单中产品的排序( add_to_cart_order )
- 该产品是否被重新订购(重新订购)。
总体而言,49,685 种独特产品有 3,346,083 个独特订单。我们可以在下图中观察到,人们通常会订购 5 件左右的产品。
特别是,订购最多的前 5 种产品是香蕉(491,291)、袋装有机香蕉(394,930)、有机草莓(275,577)、有机小菠菜(251,705)和有机帽子鳄梨(220,877)。
约 59%的订购产品是客户之前订购的。下图显示了通常最有可能重新订购的产品。按照概率,重新订购最多的前五种产品是 Serenity Ultimate Extrema 隔夜垫(0.933)、巧克力爱心棒(0.922)、玛卡毛茛(0.894)、Benchbreak Chardonnay (0.892)和有机蓝莓 B Mega (0.889)。
订单
现在让我们来研究 Instacart 订单的数据。 orders.csv 文件有 3421083 个订单和 7 个特征列:
- 订单的 ID(order _ ID)
- 客户的 ID(用户 id )
- 订单所在的评估数据集——先前、训练或测试( eval_set )
- 订单的编号( order_number )
- 订单发生的星期几( order_dow )
- 订单发生的时间(订单时间)
- 自上一订单以来的天数( days_since_prior_order
看起来 Instacart 的客户通常在早上 8 点到晚上 7 点之间下单。
看起来他们大多在周末下订单(0 表示周六,1 表示周日)。
下图显示了 Instacart 客户的再订购周期。在第 7 天和第 30 天有明显的峰值,表明人们通常在一周或一个月后再订购。
该数据集中总共有 206,209 个不同的客户。如下图所示,大多数客户下了大约 4 个订单。
部门和过道
我们来看看最重要的部门,按产品数量排序。排名前 5 位的部门分别是个人护理(6,563)、小吃(6,264)、茶水间(5,371)、饮料(4,365)和冷冻(4,007)。
让我们看看所有部门中最重要的过道,按照产品数量进行分类。忽略“缺失”值,我们的前 5 名分别是巧克力糖(1,258)、冰淇淋(1,091)、维生素补充剂(1,038)、酸奶(1,026)和薯片椒盐卷饼(989)。
按订单数量排序的部门和通道的详细信息如何?按订单排序,最畅销的前 5 个部门是农产品(409,087)、乳制品鸡蛋(217,051)、零食(118,862)、饮料(114,046)和冷冻食品(100,426)。
最后,我们查看所有部门中按照订单数量排序的最佳销售通道。前 5 名分别是新鲜蔬菜(150609)、新鲜水果(150473)、包装蔬菜水果(78493)、酸奶(55240)、包装奶酪(41699)。
结论
进行这种分析让我能够更细致地了解 Instacart *台上客户购物行为的细节。了解最常购买的商品是 Instacart 优化其软件产品并在顾客购物时为他们推荐商品的第一步。
如果你有兴趣自己复制这个结果,你可以从insta cart 网站下载数据集,并在土星云上查看我的笔记本。就个人而言,快速轻松地共享笔记本的能力对任何数据科学家都非常有帮助。
在这个博客系列的下一部分,我将把客户分成不同的组,这可以帮助 Instacart 针对不同的需求提供更多个性化的推荐。此外,我将探索 Saturn 的特性,该特性允许我扩展云计算,因为我有更高的计算需求。
Instacart 市场购物篮分析第二部分:哪些群体的客户是相似的?
原文:https://towardsdatascience.com/instacart-market-basket-analysis-part-2-which-groups-of-customers-are-similar-618e88b0866d?source=collection_archive---------20-----------------------
深入分析
通过土星云对 Instacart 客户进行聚类
数据科学环境正在快速变化,变得越来越成熟。无论你是一名开发前沿深度学习算法的经验丰富的数据科学家,还是一名正在进行学校项目的研究生,能够几乎不费吹灰之力地在 Jupyter 笔记本(数据科学中的默认工作台)上发布和协作都是非常关键的。
到目前为止,还没有很多简单的共享笔记本的解决方案可供您的团队协作。如果你是一名刚从学校毕业的入门级数据科学家,这可能是一个大问题。我最*被介绍到土星云,发现共享工作和使用基于云的计算非常简单。
这是 3 部分文章系列的第 2 部分,我给出了一个例子,说明我如何使用 Saturn Cloud 来交流我在 Instacart 市场篮子分析挑战中的工作结果。在第 1 部分的中,我进行了探索性数据分析阶段,以深入了解 Instacart *台上客户购物行为的细节。
客户细分
在第 2 部分中,我将尝试找到一种可能的客户细分方法,使我们能够根据客户的不同购买行为对他们进行分类。客户细分是将客户群细分为具有相似特征的独立群体。这种方法是识别未满足的客户需求的有效方法。利用这些信息,Instacart 可以通过开发独特的吸引人的产品和服务来超越竞争对手。此外,该信息还将有助于下一个预测任务,该任务可用于向客户推荐新商品。
由于数据集中有成千上万的产品,我将依赖于代表产品类别的通道。即使有过道,功能的数量仍然会太多。因此,我将使用主成分分析来寻找新的维度,沿着这些维度聚类将更容易,然后尝试为已识别的聚类找到可能的解释。
数据预处理
继续第 1 部分中的数据探索,这是我对数据集结构的理解:
- 用户由 orders.csv 文件中的 user_id 标识。 orders.csv 文件的每一行代表一个用户的订单。订单通过其 order_id 进行识别。
- 用户的每个订单都由一个 order_number 来表征,该订单指定了该订单何时相对于同一用户的其他订单做出。
- 每个订单都由一组产品组成,每个产品都有一个 add_to_cart_order 特性,表示它们被添加到购物车的顺序。
- 对于每个用户,我们可能有(n — 1)个先前订单和 1 个训练订单或(n — 1)个先前订单和 1 个测试订单,其中我们必须说明哪些产品已经重新订购。
为了便于分析,我将所有不同的数据帧合并成一个名为 mt. 的数据帧
_mt = pd.merge(prior,products, on = ['product_id','product_id'])_mt = pd.merge(_mt,orders,on=['order_id','order_id'])mt = pd.merge(_mt,aisles,on=['aisle_id','aisle_id'])
我们正在处理 134 种类型的过道和 49,677 种不同的产品。如左侧所示,最畅销的前 5 种商品是新鲜水果、新鲜蔬菜、包装蔬菜水果、酸奶和包装奶酪。
使用 PCA 和 K-Means 进行聚类
目标是在不同的客户中找到所有可能的集群,并用假设他们所属的集群替换单个 user_id。这将最终提高下一个预测模型的性能。
首先要做的是创建一个数据框,其中包含每个用户的所有购买行为。这个 cust_prod 有 206,209 个用户和 134 列。
cust_prod = pd.crosstab(mt['user_id'], mt['aisle'])cust_prod.head(10)
然后,我将主成分分析算法应用于 cust_prod 数据框架。这有助于将功能的数量从通道的数量减少到 6,这是我选择的主要组件的数量。
土星云在这里真的很有帮助,因为 PCA 算法的计算代价很高。由于我将我的笔记本托管在他们支持云的*台上,我可以利用 Saturn 提供的 GPU 来执行这个昂贵的操作。
from sklearn.decomposition import PCApca = PCA(n_components=6)pca.fit(cust_prod)pca_samples = pca.transform(cust_prod)ps = pd.DataFrame(pca_samples)ps.head()
在绘制了几对组件并为 K-Means 聚类寻找了一个合适的组件对之后,我选择了(PC4,PC1)对,如下所示。由于每个组件都是原始数据集所有点的投影,我认为每个组件都很好地代表了数据集。
这是我们的星团是如何出现的。您可以看到有 4 个集群与 4 种不同的颜色(蓝色、绿色、紫色和橙色)相关联。值为 0,1,2,3 的圆是每个簇的质心。
我想我已经找到了 Instacart 客户的可能聚类。让我们来看看每个集群的人们购买的前 10 种商品是什么。我将首先依赖绝对数据,然后依赖每个集群的前 8 个产品的百分比。
集群特征
以下是分类 0 中的前 10 种产品。
c0.sort_values(ascending=False)[0:10]
以下是第 1 类中的前 10 种产品。
c1.sort_values(ascending=False)[0:10]
以下是第 2 类中的前 10 种产品。
c2.sort_values(ascending=False)[0:10]
以下是第 3 类中排名前 10 的产品。
c3.sort_values(ascending=False)[0:10]
对聚类的粗略分析证实了最初的假设,即(1)新鲜水果,(2)新鲜蔬菜,(3)包装的蔬菜水果,(4)酸奶,(5)包装的奶酪,(6)牛奶,(7)苏打水,和(8)脆片椒盐卷饼是大多数顾客通常购买的产品。
我在这里可以检查的是,相对于这些货物,集群在数量和比例上是否有所不同,或者一个集群的特征是否是一些不在此列表中的货物。例如,我已经看到第 3 类的特点是“婴儿食品配方”产品,这与其他类有很大的不同。
下表描述了这些商品相对于每个聚类中其他前 8 名商品的百分比。集群之间很容易出现一些有趣的差异。
- 看起来第一组的人比其他组的人购买更多的新鲜蔬菜。如绝对数据所示,聚类 1 也是包括购买比任何其他顾客多得多的商品的顾客的聚类。
- 第二组的人比其他组的人买更多的酸奶。
- 第三组的人购买了大量的“婴儿食品配方奶粉”,这些产品甚至没有列在前八名,但却是这一组的主要特征。与这个观察一致(我认为),他们比其他人买更多的牛奶。
我认为另一个有趣的信息可能来自于查看每个集群中第 10 到第 15 个最常购买的产品,其中不包括通用产品(即蔬菜、水果、水等)。)谁都买。
在聚类 0 中,第 10 到第 15 位最常购买的商品是冷藏、冰淇淋、冷冻产品、鸡蛋和饼干。
c0.sort_values(ascending=False)[10:15]
在第 1 组中,第 10 到第 15 位最常购买的商品是无乳糖大豆、面包、饼干、麦片和巧克力糖。
c1.sort_values(ascending=False)[10:15]
在聚类 2 中,第 10 到第 15 位最常购买的商品是鸡蛋、罐装罐装蔬菜、面包、薯片、椒盐卷饼和冷藏食品。
c2.sort_values(ascending=False)[10:15]
在聚类 3 中,第 10 到第 15 位最常购买的商品是不含乳糖的大豆、冷冻产品、苏打水、冷冻食品和鸡蛋。
c3.sort_values(ascending=False)[10:15]
正如您所注意到的,考虑更多的产品后,聚类开始明显不同。
结论
对于任何企业来说,进行客户细分都有多种优势:确定合适的产品定价、制定有效的定制营销活动、设计最佳分销策略、选择具体的产品功能进行部署,以及对新产品开发工作进行优先排序。正如我的分析所证明的,Instacart 可以通过多种方式,利用公司拥有的庞大客户群,执行上述任何一种商业战略。
如果你有兴趣自己复制这个结果,你可以从 Instacart 网站下载数据集,并在土星云上查看我的笔记本。在这个博客系列的最后一部分,我将尝试进行关联规则挖掘,这是一种机器学习技术,有助于显示 Instacart 订单数据集中购买的产品之间的关系概率。
Instacart 市场购物篮分析第三部分:应向购物者推荐哪几组产品?
原文:https://towardsdatascience.com/instacart-market-basket-analysis-part-3-which-sets-of-products-should-be-recommended-to-shoppers-9651751d3cd3?source=collection_archive---------22-----------------------
深入分析
基于土星云的 Instacart 产品关联规则挖掘
欢迎来到充满希望的数据科学和机器学习*台时代!这些*台具有开箱即用的优势,因此团队可以从第一天就开始分析数据。使用开源工具,你需要手工组装很多部件,可以这么说,任何做过 DIY 项目的人都可以证明,理论上比实践上容易得多。明智地选择一个数据科学和 ML *台(指的是一个灵活的、允许合并和继续使用开源的*台)可以让企业两全其美:尖端的开源技术和对数据项目的可访问、可治理的控制。
最终,数据科学和 ML *台是关于时间的。当然,这意味着在流程的所有部分节省时间(从连接数据到构建 ML 模型到部署)。但这也是为了减轻人工智能入门的负担,让企业现在就开始投入,而不是等到技术确定下来,人工智能世界变得更加清晰(因为剧透警告:这可能永远不会发生)。开始人工智能之旅令人生畏,但数据科学和 ML *台可以减轻这一负担,并提供一个框架,允许公司边走边学习。
土星云
土星云允许数据科学家轻松地在云上提供和托管他们的工作,而不需要专门的开发人员。然后,数据科学家可以在 Juptyer 笔记本中工作,该笔记本位于您指定的服务器上,由系统创建。所有软件、网络、安全和图书馆的设置都由土星云系统自动处理。然后,数据科学家可以专注于实际的数据科学,而不是围绕它的乏味的基础设施工作。
您还可以使用链接与公众或团队成员共享您的 Juypter 笔记本。这消除了理解如何使用 GitHub 进行基础数据科学项目的需要。如果您确实知道如何使用 GitHub,它仍然提供了一种快速方便的方法来测试和开发代码。因此,数据科学家可以专注于数据科学,并以比其他方式更快的速度完成项目。
这是 3 篇文章系列的最后一篇,我将举例说明如何使用 Saturn Cloud 来应对 Instacart 市场购物篮分析挑战。在第 1 部分中,我探索了数据集,以更细致地了解 Instacart *台上客户购物行为的细节。在《T4》第二部中,我对客户进行了细分,以找出是什么因素将他们区分开来。
动机
我希望使用 Apriori 算法在 Python 中运行关联分析,以导出形式为 {A} - > {B} 的规则。然而,我很快发现它不是标准 Python 机器学习库的一部分。尽管存在一些实现,但我找不到一个能够处理大型数据集的实现。在我的例子中,“大”是一个包含 3200 万条记录的 orders 数据集,包含 320 万个不同的订单和大约 50K 个不同的项目(文件大小刚刚超过 1 GB)。
因此,我决定自己实现算法来生成那些简单的 {A} - > {B} 关联规则。因为我只关心理解任何给定的项目对之间的关系,所以使用先验知识来得到大小为 2 的项目集就足够了。我经历了各种迭代,将数据分成多个子集,这样我就可以在内存小于 10 GB 的机器上运行 cross-tab 和 combinations 等功能。但是,即使使用这种方法,在我的内核崩溃之前,我也只能处理大约 1800 个项目……这时,我了解了 Python 生成器的奇妙世界。
Python 生成器
简而言之,生成器是一种特殊类型的函数,它返回可迭代的项目序列。然而,与一次返回所有值的常规函数不同,生成器一次生成一个值。要获得集合中的下一个值,我们必须请求它——要么通过显式调用生成器的内置“next”方法,要么通过 for 循环隐式调用。
这是生成器的一个重要特性,因为这意味着我们不必一次将所有的值都存储在内存中。我们可以一次加载并处理一个值,完成后丢弃该值,然后继续处理下一个值。这个特性使得生成器非常适合创建项目对并计算它们的共现频率。
这里有一个具体的例子来说明我们正在努力实现的目标:
- 获取给定订单的所有可能商品对
order 1: apple, egg, milk —-> item pairs: {apple, egg}, {apple, milk}, {egg, milk}order 2: egg, milk --> item pairs: {egg, milk}
- 统计每个项目对出现的次数
eg: {apple, egg}: 1{apple, milk}: 1{egg, milk}: 2
下面是实现上述任务的生成器:
def get_item_pairs(order_item): # For each order, generate a list of items in that order for order_id, order_object in groupby(orders, lambda x: x[0]): item_list = [item[1] for item in order_object] # For each item list, generate item pairs, one at a time for item_pair in combinations(item_list, 2): yield item_pair
上面编写的 get_item_pairs() 函数为每个订单生成一个商品列表,并为该订单生成商品对,一次一对。
- 第一个项目对被传递给计数器,计数器记录一个项目对出现的次数。
- 获取下一个项目对,并再次传递给计数器。
- 这个过程一直持续到不再有项目对。
- 使用这种方法,我们最终不会使用太多内存,因为在计数更新后,项目对会被丢弃。
Apriori 算法
Apriori 是一种在事务数据库上进行频繁项集挖掘和关联规则学习的算法。它通过识别数据库中频繁出现的单个项目,并将其扩展到越来越大的项目集,只要这些项目集在数据库中出现得足够频繁。
Apriori 使用“自下而上”的方法,一次扩展一个频繁子集(这一步被称为候选生成),并根据数据测试候选组。当没有找到进一步的成功扩展时,算法终止。
Apriori 使用广度优先搜索和哈希树结构来有效地计算候选项目集。它从长度为(k — 1)的项集生成长度为 k 的候选项集。然后,它修剪具有不频繁子模式的候选。根据向下闭包引理,候选集包含所有频繁 k 长项目集。之后,它扫描事务数据库以确定候选项中的频繁项集。
下面是一个先验的例子,假设最小发生阈值为 3:
order 1: apple, egg, milkorder 2: carrot, milkorder 3: apple, egg, carrotorder 4: apple, eggorder 5: apple, carrotIteration 1: Count the number of times each item occursitem set occurrence count{apple} 4{egg} 3{milk} 2{carrot} 2=> {milk} and {carrot} are eliminated because they do not meet the minimum occurrence threshold. Iteration 2: Build item sets of size 2 using the remaining items from Iteration 1item set occurence count{apple, egg} 3=> Only {apple, egg} remains and the algorithm stops since there are no more items to add.
如果我们有更多的订单和商品,我们可以继续迭代,构建包含 2 个以上元素的商品集。对于我们试图解决的问题(即:寻找项目对之间的关系),实现先验以获得大小为 2 的项目集就足够了。
关联规则挖掘
一旦使用 apriori 生成了项目集,我们就可以开始挖掘关联规则。假设我们只查看大小为 2 的项目集,我们将生成的关联规则将采用{ A }--> { B }的形式。这些规则的一个常见应用是在推荐系统的领域,其中购买了商品 A 的顾客被推荐商品 b。
以下是评估关联规则时要考虑的 3 个关键指标:
1 —支架
这是包含项目集的订单的百分比。在上面的示例中,总共有 5 个订单,{apple,egg}出现在其中的 3 个订单中,因此:
support{apple,egg} = 3/5 or 60%
apriori 所需的最小支持阈值可以根据您对领域的了解来设置。例如,在这个杂货数据集中,由于可能有数千个不同的商品,而一个订单只能包含这些商品中的一小部分,因此将支持阈值设置为 0.01%可能是合理的。
2 —置信度
给定两个商品 A 和 B,置信度度量商品 B 被购买的次数的百分比,给定商品 A 被购买。这表示为:
confidence{A->B} = support{A,B} / support{A}
置信值的范围是从 0 到 1,其中 0 表示在购买 A 时从不购买 B,1 表示每当购买 A 时总是购买 B。请注意,置信度是有方向性的。这意味着,我们还可以计算出商品 A 被购买的次数百分比,假设商品 B 被购买:
confidence{B->A} = support{A,B} / support{B}
在我们的例子中,假设苹果被购买,鸡蛋被购买的次数百分比是:
confidence{apple->egg} = support{apple,egg} / support{apple}= (3/5) / (4/5)= 0.75 or 75%
这里我们看到所有包含 egg 的订单也包含 apple。但是,这是否意味着这两个项目之间有关系,或者它们只是偶然以相同的顺序同时出现?为了回答这个问题,我们来看看另一个衡量标准,它考虑了这两个项目的受欢迎程度。
3 —升降机
给定两个项目 A 和 B,lift 表示 A 和 B 之间是否存在关系,或者这两个项目是否只是偶然地(即:随机地)以相同的顺序一起出现。与置信度度量不同,其值可能随方向而变化(例如:置信度{A->B}可能不同于置信度{B->A}), lift 没有方向。这意味着升力{A,B}总是等于升力{B,A}:
lift{A,B} = lift{B,A} = support{A,B} / (support{A} * support{B})
在我们的例子中,我们计算升力如下:
lift{apple,egg} = lift{egg,apple}= support{apple,egg} / (support{apple} * support{egg})= (3/5) / (4/5 * 3/5)= 1.25
理解 lift 的一种方法是将分母视为 A 和 B 以相同顺序出现的可能性,如果它们之间没有关系的话。在上面的例子中,如果 apple 出现在 80%的订单中,egg 出现在 60%的订单中,那么如果它们之间没有关系,我们会期望它们在 48%的时间里以相同的顺序一起出现(即:80% * 60%)。另一方面,分子代表苹果和鸡蛋以相同顺序出现的频率。在这个例子中,这是 60%的时间。取分子并除以分母,我们得到苹果和鸡蛋实际上以相同的顺序出现的次数比它们之间没有关系时多多少次(即:它们只是随机出现在一起)。
总之,lift 可以采用以下值:
- lift = 1 暗示 A 和 B 之间没有关系(即:A 和 B 只是偶然出现在一起)
- lift > 1 暗示 A 和 B 之间存在正相关关系(即:A 和 B 一起出现的次数比随机出现的次数多)
- lift < 1 暗示 A 和 B 之间存在负相关关系(即:A 和 B 一起出现的频率低于随机出现的频率)
在这个例子中,苹果和鸡蛋一起出现的次数比随机出现的次数多 1.25 倍,所以我断定它们之间存在正相关关系。有了 apriori 和关联规则挖掘的知识,让我们深入到数据和代码中,看看我能展现什么关系!
insta cart 数据上的关联规则挖掘
云中木星笔记本入门使用土星云非常直观。笔记本运行后,我可以轻松地从笔记本内部与公众分享。为了证明这一点,你可以在这里查看我的关联规则挖掘笔记本中的完整代码。
在数据预处理步骤之后,我编写了几个助手函数来辅助主要的关联规则函数:
- freq() 返回项目和项目对的频率计数。
- order_count() 返回唯一订单的数量。
- get_item_pairs() 返回生成项目对的生成器,一次一个。
- merge_item_stats() 返回与项目相关联的频率和支持。
- merge_item_name() 返回与项目相关的名称。
下面的 GitHub Gist 中显示了大的 association_rules() 函数:
Full Link: https://gist.github.com/khanhnamle1994/934d4c928c836d38879d3dd6637d9904
此时,我能够利用 Saturn Cloud 的 GPU 功能来处理我的工作负载。本质上,土星云让我只需点击一下鼠标就能部署 Spark 或 Dask 集群。这简化了处理非常昂贵的计算的问题,只需点击一下鼠标就可以实现分布式计算。考虑到这种关联规则挖掘算法相当昂贵,访问 GPU 在这里是一个明显的赢家。
在最小支持度为 0.01 的订单数据帧上调用 association_rules() 函数后,得到如下结果(正在挖掘的 7 个规则样本):
从上面的输出中,我观察到顶级关联并不令人惊讶,一种口味的商品与同一商品系列中的另一种口味一起购买(例如:草莓 Chia 农家奶酪与蓝莓 Acai 农家奶酪,鸡肉猫粮与土耳其猫粮,等等)。如上所述,关联规则挖掘的一个常见应用是在推荐系统领域。一旦项目对被确定为具有积极的关系,就可以向顾客提出建议以增加销售。希望在这个过程中,我们还可以向顾客介绍他们以前从未尝试过甚至想象不到的东西!
结论
当试图启动数据科学团队项目时,开发运维可能会非常困难。在幕后,有很多工作要做,以建立数据科学家用于工作的实际*台:创建服务器,安装必要的软件和环境,设置安全协议,等等。使用 Saturn Cloud 托管 Jupyter 笔记本电脑,同时还负责版本管理,并能够根据需要进行扩展,这可以极大地简化您的生活,缩短上市时间,降低成本和对专业云技能的需求。
我希望你喜欢这个由 3 部分组成的系列,通过 Instacart 市场购物篮分析挑战来了解使用 Saturn Cloud 的好处。作为数据科学和机器学习*台运动的一部分,当团队不必在管理、组织或重复任务上花费宝贵的时间时,像土星云这样的框架可以打开真正的数据创新之门。事实是,在人工智能时代,任何规模的企业都无法承受没有数据科学*台的工作,该*台不仅可以支持和提升他们的数据科学团队,还可以将整个公司提升到最高水*的数据能力,以实现最大可能的影响。
使用全景和模式的 Instagram 数据分析
原文:https://towardsdatascience.com/instagram-data-analysis-ce03aa4a472a?source=collection_archive---------11-----------------------
picture credits to panoply.io
背景
该项目建立在 Panoply 于 2019 年 4 月发布的数据挑战之上。Panoply 是一个云数据仓库,你可以从不同的数据源(如 S3 自动气象站,谷歌分析等)收集数据。),然后连接到不同的商业智能工具(即 Chartio、Mode 等。)进行分析和洞察。
Panoply 最*将他们的数据仓库与 Instagram API 集成在一起,以收集数据。这个挑战是关于使用 Panoply 作为 ETL 工具来探索 Instagram 数据的营销用途(即推广、细分等)。).
在这项挑战中,挑战者被要求建立一个 Panoply 帐户,并连接到 self Instagram 或提供的 Instagram 数据,以进行分析,得出见解,并为讲故事建立可视化。如果您有 Instagram 帐户,您可以使用自己 Instagram 帐户中的数据。或者,如果您更喜欢使用 Panoply 提供的数据,您可以从两个帐户中选择:
- Kirsten Alana:insta gram 的顶级影响者。
- Shinesty :一个创新和前卫的服装品牌。
然后,您可以使用您选择的任何 BI 工具进行数据可视化。本次挑战的最终交付成果将采用英语,数据可视化,用于交流您的发现和您使用过的 SQL 查询。
项目设计
我的项目步骤是:
- 探索 Panoply,使用它在自己的网站上为挑战和文档提供的资源。
- 创建 Panoply 免费试用帐户,连接到提供的数据源,连接到商业智能工具。
- 探索数据集,理解模式和关系。
- 研究并提出 Instagram 所有者希望跟踪和回答的问题/指标/关键绩效指标。这样他们就能获得发展品牌的洞察力。
- 使用模式构建可视化并接受挑战。
工具
我将在这个项目中使用的工具和技术将是 Panoply,Instagram data,SQL 和模式。
过程
我开始阅读 Panoply 提供的资源,并探索他们的网站,以更好地了解 Panoply 是什么以及它如何在数据分析过程中发挥作用。然后我创建了 Panoply 帐户的免费试用版,并按照他们的文档连接到亚马逊 S3 收集提供的 Instagram 数据。
创建一个 Panoply 帐户
下面是唱出一个全景账户的流程:
- 转到 https://panoply.io 。
panoply.io landing page screenshot
2.使用电子邮件帐户注册一个免费的 21 天试用帐户。
sign-up page screenshot
连接到数据源并收集数据
下面是连接到亚马逊 S3 并使用 API 收集 Instagram 数据的流程。在这个挑战中,我使用了 Shinesty 的数据作为我的分析目标,Shinesty 是一个创新和前卫的服装品牌。
- 转到数据源选项卡。
Data Sources tab screenshot
2.选择你想连接的数据源,对于这个项目,我使用亚马逊 S3。
输入您的凭证并开始从您的数据源收集数据到 Panoply 数据仓库。
Amazon S3 api info page screenshot
3.你的桌子准备好了。
Tables tab screenshot
用于分析的表格
收集数据后,我发现总共有 31 张表。经过探索和检查,我确定了 5 个最有用的表格,并用它们得出有意义的见解。下面是我使用过的表格和列。
shinestyinstagram_instagram_user table screenshot
shinestyinstagram_instagram_media table screenshot
shinestyinstagram_instagram_comment table screenshot
shinestyinstagram_instagram_media_tags table screenshot
shinestyinstagram_instagram_media_location table screenshot
韵律学
经过我的研究,我确定了一些 Instagram 账户所有者希望了解的指标和问题,以便在 API 提供数据的情况下提高他们的账户认知度。
- 每个标签的参与度。
- 一段时间内的表现。
- 用户评论时按星期几使用的性能。
- 当用户发表评论时,按一天中的小时使用性能。
- 创建帖子时按小时使用的绩效。
- 按媒体类型划分的性能。
- 不同介质的过滤性能。
- 使用位置标签的性能。
- 有位置标签的帖子与没有标签的帖子的性能差异。
- 最活跃的评论者。
- 队列分析。
可视化的连接模式
- 前往 https://mode.com的创建一个免费的非商业账户。
Mode home page screenshot
2.进入您的帐户控制面板后,点击左侧您姓名旁边的向下箭头。
home dashboard screenshot
3.然后会出现一个新的下拉菜单,选择 Connect a Database 选项卡。
drop down menu for connecting a database screenshot
4.然后,您可以使用您的凭证连接到不同的数据库。
connect to database screenshot
对于这个项目,我们使用了 Amazon Redshift,因为这是 Panoply 用来存储我们的表的数据库。在您进入并收集到您的 Panoply 数据库后,Mode 将开始收集所有表格到您的帐户数据库中。一旦完成,您就可以开始使用 SQL 来分析模式中的数据。
using SQL to analyze the data in Mode screenshot
分析
下面是我用来回答指标部分的问题的查询。
- 为使用的每个标签寻找参与度:
with t AS
(SELECT
value as hashtag,
likes_count as likes,
comments_count as comments
FROM public.shinestyinstagram_instagram_media m
left JOIN public.shinestyinstagram_instagram_media_tags mt
ON m.id = mt.instagram_media_id
)
select
hashtag,
AVG(likes) as avg_likes,
AVG(comments) as avg_comments
from
t
where hashtag is not null
group by 1
下面的视频告诉你每个标签的*均赞数,# housetonstrong 和#theperfectcrime 的*均赞数最多。
Average Likes vs. Hashtag
下面的视频告诉你每个标签的*均评论,其中#buttstuff 和#macrobrews 的表现最好。
Average Comments vs. Hashtag
下面视觉结合以上两者。
Performance By Hashtag
- 了解一段时间内的表现:
SELECT
DATE_TRUNC(‘week’, created_time)::DATE as week,
SUM(comments_count) AS total_comments,
AVG(comments_count) AS avg_comments,
SUM(likes_count) AS total_likes,
AVG(likes_count) AS avg_likes,
count(distinct id) as nums_of_post
FROM
public.shinestyinstagram_instagram_media
GROUP BY
1
ORDER BY
1
Performance Over Time
- 使用 when a user comment 按星期几查找性能:
select
TO_CHAR(created_time, ‘DY’) as day,
COUNT(distinct media_id) AS nums_of_post_got_commented,
COUNT(distinct from_username) AS nums_of_commenter,
ROUND((nums_of_commenter/ cast(nums_of_post_got_commented as FLOAT)), 0) as average_commenter_per_post
from
public.shinestyinstagram_instagram_comments
group by
1
order by
1
下图显示,周四和周五是用户最喜欢评论的时间。
Engagement Performance by Day of Week
- 使用用户何时发表评论来查找一天中每个小时的表现:
select
TO_CHAR(created_time, ‘HH24’) as hour,
COUNT(distinct media_id) AS nums_of_post_got_commented,
COUNT(distinct from_username) AS nums_of_commenter,
ROUND((nums_of_commenter/ cast(nums_of_post_got_commented as FLOAT)), 0) as average_commenter_per_post
from
public.shinestyinstagram_instagram_comments
group by
1
order by
1
Engagement Performance by Hour
- 使用帖子创建时间查找一天中的小时绩效:
SELECT
TO_CHAR(created_time, ‘HH24’) as hour,
SUM(comments_count) AS total_comments,
AVG(comments_count) AS avg_comments,
SUM(likes_count) AS total_likes,
AVG(likes_count) AS avg_likes,
count(distinct id) as nums_of_post
FROM
public.shinestyinstagram_instagram_media
GROUP BY
1
ORDER BY 1
我展示这个查询的目的是因为我认为在一天的早上 7 点到下午 4 点使用这个洞察力来推荐发布 IG 帖子是不合适的。因为这个查询在创建帖子时使用来计算赞和评论的数量。相比之下,当用户发表评论时用来计算性能的最后一个视觉效果,我认为会更准确。所以我建议@shinestythreads 在每天晚上 11 点到凌晨 2 点发布,以获得更多的评论参与度。不幸的是,API 没有提供相同的信息,我想用它来计算喜欢的参与度。
Performance by Hour
- 按媒体类型查找绩效:
SELECT
type,
SUM(likes_count) as total_likes,
AVG(likes_count) as avg_likes,
SUM(comments_count) as total_comments,
AVG(comments_count) as avg_comments,
COUNT(distinct id) as nums_of_post
FROM
public.shinestyinstagram_instagram_media
GROUP BY
1
IG 目前提供三种类型的媒体:图像、视频和轮播。下图显示了视频媒体的*均评论数最多,轮播媒体的*均点赞数最多。而视频媒体表明自己是获得参与度的最佳媒体。
Performance by Media Type using average comments
Performance by Media Type using average likes
- 通过过滤器查找不同介质的性能:
SELECT
filter,
type,
SUM(likes_count) as total_likes,
AVG(likes_count) as avg_likes,
SUM(comments_count) as total_comments,
AVG(comments_count) as avg_comments,
COUNT(distinct id) as nums_of_post
FROM
public.shinestyinstagram_instagram_media
GROUP BY
1, 2
在下图中,我们可以看到除了普通的图像媒体滤镜之外,名为 Crema 的滤镜具有最佳的性能。
Performance by Filter for Image Media
在下面的视频中,我们可以看到除了视频媒体的普通过滤器之外,名为 Ashby 的过滤器具有最佳性能。
Performance by Filter for Video Media
对于轮播媒体,我们可以做同样的事情来获得洞察力,但我没有在这里这样做,因为@shinestythreads 只有针对轮播媒体的普通过滤器。
- 通过使用的位置标签了解性能:
SELECT
location,
SUM(likes_count) as total_likes,
AVG(likes_count) as avg_likes,
SUM(comments_count) as total_comments,
AVG(comments_count) as avg_comments
FROM
(SELECT
name as location,
m.likes_count,
m.comments_count
FROM
public.shinestyinstagram_instagram_media_location l
LEFT JOIN public.shinestyinstagram_instagram_media m
ON l.instagram_media_id = m.id
) as t
GROUP BY
1
该图向我们展示了在所有带有位置标签的帖子中,奥古斯特国家高尔夫俱乐部的*均喜欢和评论参与度最高。
Performance by Location Tag
- 找出有位置标签的帖子与没有位置标签的帖子的性能差异:
WITH t AS
(SELECT
m.id,
m.likes_count,
m.comments_count,
l.name as location
FROM
public.shinestyinstagram_instagram_media m
LEFT JOIN
public.shinestyinstagram_instagram_media_location l
ON
m.id = l.instagram_media_id
),w as
(SELECT
*,
(CASE WHEN location IS NULL THEN 0 ELSE 1 END) AS have_location
FROM t
)SELECT
have_location,
SUM(likes_count) as total_likes,
AVG(likes_count) as avg_likes,
SUM(comments_count) as total_comments,
AVG(comments_count) as avg_comments
FROM
w
GROUP BY
1
与没有位置标签的帖子相比,有位置标签的帖子有更多的*均喜欢,但*均评论稍少。
Performance of Location Tag vs. No Location Tag
- 找出最活跃的评论者:
SELECT
*
FROM
(SELECT
from_username as username,
COUNT(media_id) as nums_of_comments,
RANK() OVER(ORDER BY nums_of_comments DESC)
FROM
public.shinestyinstagram_instagram_comments
GROUP BY
1
ORDER BY
2 DESC
) as t
WHERE
rank >1 and rank <=15
这个视图向我们展示了谁是最活跃的评论者(用户),不包括用户@shinestythreads。
Most Active Commenters
- 队列分析:
with t AS(selectmedia_id,from_username as username,DATE_TRUNC('week', created_time) as weekfrompublic.shinestyinstagram_instagram_comments),w AS(selectusername,min(week) as first_time_commentingfromtGROUP by1)SELECTx.cohort::DATE AS week,MAX(x.week_number) OVER (PARTITION BY x.cohort) AS total_nums_of_week,x.week_number,MAX(x.nums_of_commenter) OVER (PARTITION BY x.cohort) AS nums_of_new_commenter,x.nums_of_commenter,x.nums_of_commenter/MAX(x.nums_of_commenter) OVER (PARTITION BY x.cohort)::FLOAT AS retention_rateFROM(SELECTw.first_time_commenting as cohort,FLOOR(EXTRACT('day' FROM t.week - w.first_time_commenting)/7) AS week_number,COUNT(DISTINCT t.username) AS nums_of_commenterFROMt tLEFT JOINw wONt.username = w.usernameGROUP BY1,2) as xORDER BY 1,2,3
以上是我为这个项目所做的所有分析。对于我用过的数据,因为保密的原因,我没有上传到我的 Github 上。如果你有兴趣了解我为这个项目使用了哪些资源,请访问我的 Github repo 。
如有疑问,欢迎在下方评论。非常感谢您的阅读!
在 AWS 的 Ubuntu 上安装一个 Kafka 集群
原文:https://towardsdatascience.com/install-a-kafka-cluster-on-ubuntu-in-aws-17c951287284?source=collection_archive---------11-----------------------
通过 AWS 中的 Kafka 消息主干构建实时数据功能
概观
数以万计的组织正在使用 Kafka,包括超过三分之一的财富 500 强公司。这些公司包括十大旅游公司、十大银行中的 7 家、十大保险公司中的 8 家、十大电信公司中的 9 家,等等。LinkedIn、微软和网飞每天用 Kafka 处理四条逗号消息(10 亿条)。它是管理和处理数据流运动的核心。
Kafka 经常在实时流数据架构中使用,以提供实时分析。由于 Kafka 是一个快速、可伸缩、持久和容错的发布-订阅消息传递系统,因此 Kafka 用于 JMS 和 RabbitMQ 由于容量和响应性而可能不被考虑的用例中。Kafka 具有更高的吞吐量、可靠性和复制特性,这使其适用于跟踪服务呼叫(跟踪每个呼叫)或跟踪 IOT 传感器数据等传统 MOM 可能不考虑的事情。
在这篇文章中,我将介绍在 AWS 中的 Linux Ubuntu 上安装 Kafka 的过程,并开始运行一些简单的示例。我将在以后的文章中介绍 Kafka 是如何工作的,以及一些使用 Java 和 Node 的用例。
入门指南
登录您的 AWS 帐户,如果您没有帐户,请创建一个新帐户。如果您使用免费服务,将不会被收费。点击了解有关免费层的更多信息。
让我们生成一个密钥对。转到 EC2- >键对。密钥对将允许您 SSH 并连接到您的 EC2 实例。选择您喜欢的地区并点击创建配对或导入一个已经存在的配对。
下载您的密钥对。
请确保限制文件的权限:
chmod 400 <key pair name>.pem
设置您的实例
让我们为 EC2 实例提供一个 Ubuntu 映像。
转到 EC2 仪表板并点击启动实例。
选择 Ubuntu 图像。
保留所有默认选项,点击查看并启动。
请注意,Kafka 的官方建议是最低 t2.medium,但此选项不在免费层范围内,会让您花钱,因此在本练习中,我们将使用 t2.micro。
选择在上一步中生成的密钥对。
回到 Instances 列表,您应该看到新的 EC2 实例启动了。
连接到您的实例
单击实例,并在描述选项卡上复制公共 DNS (IPv4)
ssh -i ~/.ssh/<key pair name.pem> ubuntu@<Public DNS (IPv4)>
您应该会看到 Ubuntu 欢迎屏幕:
太好了!!您已连接到 EC2 实例
安装 Java
让我们开始安装吧。第一步是更新实例并安装 Java。
运行以下命令:
sudo apt-get update
sudo apt upgrade
sudo add-apt-repository ppa:linuxuprising/java
sudo apt install openjdk-11-jre-headless
测试您的 Java 安装:
安装卡夫卡
现在,让我们使用以下命令安装合流 Kafka:
wget -qO - https://packages.confluent.io/deb/5.2/archive.key | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://packages.confluent.io/deb/5.2 stable main"
sudo apt-get update && sudo apt-get install confluent-platform-2.12
恭喜你!!您现在已经在 AWS 中的 Ubuntu 上安装了一个 Kafka 服务器。
配置 Kafka
让我们用 1 个 Kafka 代理和 1 个主题来配置 Kafka 的最小安装。
导航到您的 Kafka 安装
卡夫卡经纪人
编辑文件服务器.属性
sudo nano /etc/kafka/server.properties
取消对以下行的注释:
metric.reporters=io.confluent.metrics.reporter.ConfluentMetricsReporter
confluent.metrics.reporter.bootstrap.servers=localhost:9092
confluent.metrics.reporter.topic.replicas=1
用 Ctrl+0 和 Ctrl+X 保存以退出
控制中心
编辑文件控制中心生产属性
sudo nano /etc/confluent-control-center/control-center.properties
取消对以下行的注释,并编辑为您的服务器名称或本地主机:
bootstrap.servers=localhost:9092
zookeeper.connect=localhost:2181
在文件末尾添加以下几行:
confluent.controlcenter.internal.topics.partitions=1 confluent.controlcenter.internal.topics.replication=1 confluent.controlcenter.command.topic.replication=1 confluent.monitoring.interceptor.topic.partitions=1 confluent.monitoring.interceptor.topic.replication=1
连接器
sudo nano /etc/kafka/connect-distributed.properties
在文件末尾添加以下几行:
consumer.interceptor.classes=io.confluent.monitoring.clients.interceptor.MonitoringConsumerInterceptor producer.interceptor.classes=io.confluent.monitoring.clients.interceptor.MonitoringProducerInterceptor
开始卡夫卡
让我们开始 Kafka 服务:
sudo systemctl start confluent-zookeeper
sudo systemctl start confluent-kafka
sudo systemctl start confluent-schema-registry
sudo systemctl start confluent-kafka-connect
sudo systemctl start confluent-kafka-rest
sudo systemctl start confluent-ksql
sudo systemctl start confluent-control-center
您可以使用以下命令检查服务状态:
systemctl status confluent*
服务将在以下端口上运行:
ComponentPortKafka 经纪人(纯文本)9092
合流控制中心 9021
Kafka 连接 REST API 8083
KSQL 服务器 REST API 8088
REST 代理 8082
模式注册表 REST API 8081
动物园管理员 2181
要访问您的控制中心,请确保在 AWS 中打开端口 9021。
转到您的实例描述选项卡,并单击安全组已创建。包括端口 9021 的新入站规则。你可以限制你的 IP 地址或者允许所有人访问。
导航到您的 <公共 DNS (IPv4) > :9021 ,您应该会看到您的控制中心。
恭喜你!!
原载于https://marcoslombog.com。
在 Windows 上安装 Shapely
原文:https://towardsdatascience.com/install-shapely-on-windows-72b6581bb46c?source=collection_archive---------7-----------------------
Shapely 是一个 Python 包,它充满了用几何图形处理数据的各种可能性。
但是,如果你在 Windows 操作系统上工作,安装 Shapely 并不是一件简单的事情。
幸运的是,一旦你知道了细节,就没那么难了。
- F 查明您使用的是 32 位还是 64 位 Windows。转到
Settings => System => About => System Type
。 - 找出你的 python 版本。打开命令提示符,输入
python --version
并记住前两个数字。例如,我的版本是Python 3.7.3
,所以我应该记得号码37
。 pip install wheel
- 在此处和下载项目 1-2 对应的车轮。例如,我有 64 位操作系统和 Python3.70.3,所以我需要下载文件
Shapely-1.6.4.post2-cp**37**-cp**37**m-win_amd**64**.whl
。 pip install <path-to-Downloads>\<filename_from_item_4>
。例如,我输入了
pip install C:\Users\Dalya\Downloads\Shapely-1.6.4.post2-cp**37**-cp**37**m-win_amd**64**.whl
。
就是这样!
使用 conda 安装
这真的很简单!
关于为什么conda install shapely
有时不工作,以及为什么需要第一行的更多信息,请到这里。
conda config --add channels conda-forge
conda install shapely
就是这样!
在 Windows 10 上安装 Apache PySpark
原文:https://towardsdatascience.com/installing-apache-pyspark-on-windows-10-f5f0c506bea1?source=collection_archive---------0-----------------------
产品推荐数据科学项目的 Apache Spark 安装说明
在过去的几个月里,我一直在从事一个数据科学项目,该项目处理一个巨大的数据集,因此有必要使用 Apache PySpark 提供的分布式环境。
在 Windows 10 上安装 PySpark 的时候纠结了很多。所以我决定写这篇博客来帮助任何人在 Windows 10 机器上轻松安装和使用 Apache PySpark。
1.第一步
PySpark 需要 Java 版本 7 或更高版本和 Python 版本 2.6 或更高版本。让我们首先检查它们是否已经安装或安装,并确保 PySpark 可以与这两个组件一起工作。
安装 Java
检查您的机器上是否安装了 Java 版本 7 或更高版本。为此,在命令提示符下执行以下命令。
如果安装了 Java 并配置为从命令提示符运行,那么运行上面的命令应该会将关于 Java 版本的信息打印到控制台。否则,如果您收到如下消息:
‘Java’不被识别为内部或外部命令、可操作程序或批处理文件。
然后你得装 java。
a)为此下载 java 从下载免费 Java 软件
b)获得 Windows x64(如 jre-8u92-windows-x64.exe ),除非您使用的是 32 位版本的 Windows,在这种情况下,您需要获得 Windows x86 离线版本。
c)运行安装程序。
d)安装完成后,关闭当前的命令提示符(如果它已经打开),重新打开并检查是否可以成功运行 java - version 命令。
2。步骤 2
Python
Python 被许多其他软件工具使用。因此,很可能您的计算机上已经有了所需的版本(在我们的例子中是 2.6 或更高版本)。要检查 Python 是否可用并找到其版本,请打开命令提示符并键入命令 python - version
如果安装了 Python 并将其配置为从命令提示符运行,那么运行上面的命令应该会将 Python 版本的信息打印到控制台。例如,我在笔记本电脑上得到以下输出:
C:\Users\uug20>python 版本
Python 3.7.3
相反,如果您收到一条类似这样的消息
“‘python’不被识别为内部或外部命令、可操作程序或批处理文件。”
意味着你需要安装 Python。为此,
a)进入 Python 下载页面。
b)点击最新 Python 2 版本链接。
c)下载 Windows x86–64 MSI 安装程序文件。如果您使用 32 位版本的 Windows,请下载 Windows x86 MSI 安装程序文件。
d)运行安装程序时,在自定义 Python 部分,确保选择了选项将 python.exe 添加到路径。如果未选择此选项,某些 PySpark 实用程序(如 pyspark 和 spark-submit)可能无法工作。
e)安装完成后,关闭命令提示符(如果它已经打开),重新打开并检查您是否可以成功运行 python - version 命令。
3。第三步
安装 Apache Spark
a)转到 Spark 下载页面。
b)选择 Spark 的最新稳定版本。
c) 选择包类型:s 选择为最新版本的 Hadoop 预构建的版本,如为 Hadoop 2.6 预构建的版本。
d) 选择下载类型:选择直接下载。
e)点击下载 Spark 旁边的链接,下载一个压缩的 tar 文件,文件结尾为。tgz 扩展如 spark-1.6.2-bin-hadoop2.6.tgz。
f)安装 Apache Spark 时,您不必运行任何安装程序。使用 7Zip 工具/其他工具将下载的 tar 文件解压缩到您选择的任何文件夹中。
确保包含 Spark 文件的文件夹路径和文件夹名称不包含任何空格。
我在我的 D 盘上创建了一个名为 spark 的文件夹,并在一个名为 spark-2.4.3-bin-hadoop2.7 的文件夹中提取压缩的 tar 文件。因此,所有 spark 文件都在一个名为 D:\ Spark \ Spark-2 . 4 . 3-bin-Hadoop 2.7 的文件夹中。在本文中,我们将这个文件夹称为 SPARK_HOME。
要测试安装是否成功,请打开命令提示符,转到 SPARK_HOME 目录并键入 bin\pyspark。这将启动 PySpark shell,它可用于与 Spark 交互工作。
最后一条消息提示了如何使用 sc 或 sqlContext 名称在 PySpark shell 中使用 Spark。例如,在 shell 中键入 sc.version 应该会打印出 Spark 的版本。您可以像退出任何 Python shell 一样退出 PySpark shell 通过键入 exit()。
PySpark shell 在退出时输出一些消息。因此,您需要按 enter 键返回到命令提示符。
4。步骤 4
配置火花装置
最初,当您启动 PySpark shell 时,它会生成大量类型为 INFO、ERROR 和 WARN 的消息。让我们看看如何删除这些消息。
默认情况下,Windows 上的 Spark 安装不包括 Spark 使用的 winutils.exe 实用程序。如果您没有告诉您的 Spark 安装在哪里寻找 winutils.exe,您将会在运行 PySpark shell 时看到如下错误消息
"错误外壳:在 hadoop 二进制文件路径 Java . io . io 中找不到 winutils 二进制文件异常:在 Hadoop 二进制文件中找不到可执行文件 null\bin\winutils.exe。"
该错误消息不会阻止 PySpark shell 启动。但是,如果您尝试使用 bin\spark-submit 实用程序运行一个独立的 Python 脚本,您将会得到一个错误。例如,当您在 SPARK_HOME 目录中时,尝试在命令提示符下运行 examples 文件夹中的 wordcount.py 脚本。
" bin \ spark-submit examples \ src \ main \ python \ word count . py readme . MD "
安装 winutils
让我们下载 winutils.exe 并配置我们的 Spark 安装来找到 winutils.exe。
a)在 SPARK_HOME 文件夹中创建一个 hadoop\bin 文件夹。
b)下载 hadoop 版本的winutils.exe,Spark 安装就是针对该版本构建的。在我的例子中,hadoop 版本是 2.6.0。于是我下载了Hadoop 2 . 6 . 0 的 winutils.exe,复制到 SPARK_HOME 文件夹下的 hadoop\bin 文件夹。
c)在 Windows 中创建一个名为 SPARK_HOME 的系统环境变量,指向 SPARK_HOME 文件夹路径。
d)在 Windows 中创建另一个名为 HADOOP_HOME 的系统环境变量,该变量指向 SPARK_HOME 文件夹中的 HADOOP 文件夹。
由于 hadoop 文件夹位于 SPARK_HOME 文件夹内,因此最好使用值%SPARK_HOME%\hadoop 来创建 HADOOP_HOME 环境变量。这样,如果 SPARK_HOME 更新了,您就不必更改 HADOOP_HOME。
如果现在从 Windows 命令提示符下运行 bin\pyspark 脚本,与 winutils.exe 相关的错误消息应该会消失。
5。步骤 5
配置火花的日志级别
每当您启动或退出 PySpark shell 或运行 spark-submit 实用程序时,控制台中仍然会有许多额外的信息消息。因此,让我们对我们的 Spark 安装再做一个更改,以便只将警告和错误消息写入控制台。为了做到这一点:
a)将 SPARK_HOME\conf 文件夹中的 log4j.properties.template 文件复制为 SPARK_HOME\conf 文件夹中的 log4j.propertiesfile。
b)将 log4j.rootCategory 属性值设置为 WARN,console。
c)保存 log4j.properties 文件。
现在,任何信息性消息都不会记录到控制台中。
总结
为了使用 PySpark,启动命令提示符并切换到 SPARK_HOME 目录。
a)要启动 PySpark shell,请运行 bin\pyspark 实用程序。进入 PySpark shell 后,使用 sc 和 sqlContext 名称并键入 exit()返回到命令提示符。
b)要运行独立的 Python 脚本,请运行 bin\spark-submit 实用程序,并在命令提示符下指定 Python 脚本的路径以及 Python 脚本需要的任何参数。例如,要从 SPARK_HOME 文件夹中的 examples 目录运行 wordcount.py 脚本,可以运行以下命令:
"bin \ spark-提交示例\ src \ main \ python \ word count . py readme . MD"
6。第六步
重要提示:我在安装时遇到了一个问题
在我的 Windows 10 机器上完成安装程序后,我得到了以下错误信息。
文件" C:\ Users \ uug 20 \ anaconda 3 \ lib \ site-packages \ zmq \ back end \ cy thon \ _ _ init _ _。py”,第 6 行,在
解决方案:
我刚想出如何修复它!
在我的例子中,我没有意识到我必须向 PATH 环境变量添加三个与 miniconda 相关的路径。
C:\ Users \ uug 20 \ anaconda 3
C:\ Users \ uug 20 \ anaconda 3 \ Scripts
C:\ Users \ uug 20 \ anaconda 3 \ Library \ bin
之后,我没有收到任何错误信息,pyspark 开始正常工作,并在命令提示符下键入 pyspark 后打开了 Jupyter 笔记本。
希望这对你也有用!
在 PiZero W 中安装 OpenCV
原文:https://towardsdatascience.com/installing-opencv-in-pizero-w-8e46bd42a3d3?source=collection_archive---------4-----------------------
我们大多数人在 Pi 中安装 openCV 时都遇到过问题。在这篇博客中,我将一步一步地告诉你如何在你的 pi-zero W 中安装 opencv。
虽然 Pi Zero 对于高级视频处理来说不够快,但它仍然是一个很好的工具,可以用来学习计算机视觉和 OpenCV 的基础知识。我建议你晚上继续关注这个博客,因为仅仅编译 OpenCV 就需要 12 个多小时。
让我们开始…
要求:
1> pi 零 W 硬件
2> SD 卡(最低 16 GB)
3 >任何安装在你的 pi zero 上的 Raspbian 操作系统(我用过 Raspbian Buster)
假设您有给定的需求,让我们开始设置。
第一步:文件系统扩展:
很少再需要扩展文件系统,因为 NOOBs 和 Raspbian 的独立安装都会在第一次启动时自动扩展文件系统。但是,为了确保系统已扩展,请运行以下命令:
pi@raspberrypi:~ $ raspi-config --expand-rootfs
第二步:增加交换空间
交换空间是硬盘驱动器(HDD)的一部分,用于虚拟内存。有一个交换文件允许你的计算机操作系统假装你有比实际更多的内存。这将增加 openCV 的编译过程。否则你会以内存耗尽的错误结束。
要增加交换大小,请使用以下命令打开 pi zero 的交换文件:
pi@raspberrypi:~ $ sudo nano /etc/dphys-swapfile
转到交换大小,并将其从 100 更改为 2048。如下图所示。
.
.
.
# where we want the swapfile to be, this is the default
#CONF_SWAPFILE=/var/swap# set size to absolute value, leaving empty (default) then uses computed value
# you most likely don't want this, unless you have an special disk situation
#CONF_SWAPSIZE=100
CONF_SWAPSIZE=2048
.
.
.
重启你的系统。
pi@raspberrypi:~ $ sudo reboot
步骤 3:安装依赖关系:
首先让我们更新和升级现有的软件包:
pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get upgrade
如果您使用 Raspbian Buster,请运行以下命令:
pi@raspberrypi:~ $sudo apt update
pi@raspberrypi:~ $sudo apt upgrade
出现提示时,输入“Y”。
安装开发人员工具:
pi@raspberrypi:~ $ sudo apt-get install build-essential cmake pkg-config
安装 IO 包:
pi@raspberrypi:~ $ sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
以及一些视频 I/O 包(尽管您不太可能使用 Raspberry Pi Zero 进行大量视频处理):
pi@raspberrypi:~ $ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-devpi@raspberrypi:~ $ sudo apt-get install libxvidcore-dev libx264-dev
我们需要为 OpenCV 的 GUI 界面安装 GTK 开发库:
pi@raspberrypi:~ $ sudo apt-get install libgtk2.0-dev
OpenCV 利用的常规优化包:
pi@raspberrypi:~ $sudo apt-get install libatlas-base-dev gfortran
步骤 4:获取 OpenCV 源代码
所以现在我们有了所有的依赖关系。让我们从 opencv github 中拉出 OpenCV 的发布。
请注意,我已经发布了 3.4.1 版本。您也可以尝试其他版本。只需替换发布版本号。
pi@raspberrypi:~ $cd ~pi@raspberrypi:~ $ wget -O opencv.zip [https://github.com/Itseez/opencv/archive/3.4.1.zip](https://github.com/Itseez/opencv/archive/3.0.0.zip)pi@raspberrypi:~ $unzip opencv.zip
让我们一起抓取 opencv Contrib,因为 SIFT 和 SURF 已经从 opencv 的默认安装中移除:
pi@raspberrypi:~ $ wget -O opencv_contrib.zip [https://github.com/Itseez/opencv_contrib/archive/3.4.1.zip](https://github.com/Itseez/opencv_contrib/archive/3.0.0.zip)pi@raspberrypi:~ $ unzip opencv_contrib.zip
一旦两个存储库都被下载并在您的系统中展开,最好将它们删除以释放一些空间。
pi@raspberrypi:~ $ rm opencv.zip opencv_contrib.zip
步骤 5:设置 Python
如果您的系统中已经安装了 python2.7,您可以跳过这一步,否则请安装 Python 2.7 头文件,以便我们可以编译 OpenCV + Python 绑定:
pi@raspberrypi:~ $ sudo apt-get install python2.7-dev
之后安装 pip,一个 python 包管理器。
pi@raspberrypi:~ $ wget [https://bootstrap.pypa.io/get-pip.py](https://bootstrap.pypa.io/get-pip.py)pi@raspberrypi:~ $ sudo python get-pip.py
构建 Python + OpenCV 绑定的唯一要求是安装了 NumPy ,所以使用 pip 安装 NumPy:
pi@raspberrypi:~ $ pip install numpy
步骤 6:为 Raspberry Pi Zero 编译并安装 OpenCV
现在我们准备编译和安装 OpenCV。
构建文件:
pi@raspberrypi:~ $ cd ~/opencv-3.4.1/pi@raspberrypi:~ $ mkdir buildpi@raspberrypi:~ $ cd buildpi@raspberrypi:~ $ cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D INSTALL_C_EXAMPLES=ON \ -D INSTALL_PYTHON_EXAMPLES=ON \ -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.0.0/modules \ -D BUILD_EXAMPLES=ON ..
现在是编译的时候了。请记住,自行编译可能需要 9 个多小时,有时您可能会认为系统已经冻结。但是不要失去耐心,让系统工作,直到你看不到任何错误。
pi@raspberrypi:~$ make
假设您的文件编译成功,没有任何错误,现在将使用以下命令安装 opencv。
pi@raspberrypi:~$ sudo make installpi@raspberrypi:~$ sudo ldconfig
步骤 7:完成安装
检查 cv2.so 文件的路径:
查找/-name“cv2 . so”
pi@raspberrypi:~$ /usr/local/python/cv2/python-2.7/cv2.so
现在您所要做的就是将 cv2.so 文件(绑定文件)符号链接到 python lib 的站点包中。
pi@raspberrypi:~$ cd /usr/local/lib/python2.7/site-packages
运行以下命令:ln-s[cv2 . so 文件的路径] cv2.so。在我的例子中,如下所示:
pi@raspberrypi:~$/usr/local/lib/python2.7/site-packages $ ln -s /usr/local/python/cv2/python-2.7/cv2.so cv2.so
步骤 8:验证您的 OpenCV 安装
现在是时候验证我们的 openCV 安装了。
启动 Python shell 并导入 OpenCV 绑定:
pi@raspberrypi:/usr/local/lib/python2.7/site-packages$ pythonimport cv2>>> cv2.__version__3.4.1’
现在你已经在你的系统上安装了一个新的 openCV。现在导出 python 可以从任何地方访问它的路径。
pi@raspberrypi:~$ export PYTHONPATH=/usr/local/lib/python2.7/site-packages:$PYTHONPATH
现在,您可以删除 opencv-3.4.1 和 opencv_contrib-3.4.1 目录,释放文件系统上的大量空间:
但是在运行这个命令之前要小心!在清空这些目录之前,确保 OpenCV 已经正确安装在你的系统上,否则你将不得不重新开始(漫长的,12 个多小时)编译!
如果你遇到任何错误,请在评论区告诉我。
如果您想要 python3 的 OpenCV,那么您可以简单地使用 sym-link 将绑定文件指向您的 python3 站点包并导出路径
在 ubuntu 18.04 上安装 PySpark 和 JAVA 8
原文:https://towardsdatascience.com/installing-pyspark-with-java-8-on-ubuntu-18-04-6a9dea915b5b?source=collection_archive---------3-----------------------
source: https://bigdatapath.wordpress.com/2018/02/03/introduction-to-apache-spark/
分布式机器学习的基本设置
经过几个小时的挣扎,我终于安装了 java 8,spark 并配置了所有的环境变量。我浏览了许多中型文章和 StackOverflow 答案,但没有一个特定的答案或帖子解决了我的问题。所以这只是我的一点小小的努力。
我的机器安装了 ubuntu 18.04,我使用的是 java 8 和 anaconda3。如果您按照步骤操作,您应该可以毫无问题地安装 PySpark。
- 确保你已经安装了 java。
如果没有,请在终端中运行以下命令:
sudo apt install openjdk-8-jdk
安装后,如果您在终端中键入 java -version ,您将得到:
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b03-0ubuntu1.18.04.1-b03)
OpenJDK 64-Bit Server VM (build 25.212-b03, mixed mode)
2。从 下载火花 https://spark.apache.org/downloads.html
记住你下载的目录。我把它放在我的默认下载文件夹中,我将在那里安装 spark。
3。设置 JAVA _ HOME 环境变量。
为此,在终端中运行以下命令:
sudo vim /etc/environment
它将在 vim 中打开文件。然后,在 PATH 变量后的新行中添加
JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"
wq 型!然后退出。这将在文件中保存编辑。后来,在终端运行中
source /etc/environment
不要忘记在终端中运行最后一行,因为这将创建环境变量并将其加载到当前运行的 shell 中。现在,如果你跑
echo $JAVA_HOME
输出应该是:
/usr/lib/jvm/java-8-openjdk-amd64
就像加进去的一样。现在 ubuntu 的一些版本不在每次打开终端时运行/etc/environment
文件,所以最好把它加入进来。bashrc 文件为。bashrc 文件在每次打开时都会加载到终端。因此,在终端中运行以下命令,
vim ~/.bashrc
文件打开。在末尾添加
source /etc/environment
稍后我们将在它下面添加 spark 变量。现在退出并加载。bashrc 文件,通过运行下面的命令。
source ~/.bashrc
或者您可以退出此终端并创建另一个终端。现在,如果您运行 echo $JAVA_HOME,您应该会得到预期的输出。
4。安装 spark。
转到下载 spark zip 文件的目录,运行命令安装它:
cd Downloads
sudo tar -zxvf spark-2.4.3-bin-hadoop2.7.tgz
注意:如果您的 spark 文件是不同的版本,请相应地修改名称。
5。为 spark 配置环境变量。
vim ~/.bashrc
在末尾增加以下内容:
export SPARK_HOME=~/Downloads/spark-2.4.3-bin-hadoop2.7
export PATH=$PATH:$SPARK_HOME/bin
export PATH=$PATH:~/anaconda3/bin
export PYTHONPATH=$SPARK_HOME/python:$PYTHONPATH
export PYSPARK_DRIVER_PYTHON="jupyter"
export PYSPARK_DRIVER_PYTHON_OPTS="notebook"
export PYSPARK_PYTHON=python3
export PATH=$PATH:$JAVA_HOME/jre/bin
保存文件并退出。最后,加载。bashrc 文件在终端中再次被
source ~/.bashrc
现在运行:
pyspark
这将为您打开一个 jupyter 笔记本。我卸载并再次运行命令来安装 spark 和 java。最后,如果你做了:
cd $SPARK_HOME
cd bin
spark-shell --version
你会看到这样的图像。
结论
我希望这篇文章能帮助你安装 spark。今天,Spark 已经成为分布式机器学习的一个非常重要的工具,它是任何数据科学家或机器学习工作的必备简历。设置 spark 可能是首先要做的事情,其次是学习 spark 数据框架,然后在任何项目中使用它。
接触
如果你热爱数据科学,让我们在 linkedin 上联系或者在这里关注我。如果你喜欢这个故事,请鼓掌欣赏。谢谢:)
在 GoDaddy 上安装 Python 3 和 Flask
原文:https://towardsdatascience.com/installing-python-3-and-flask-on-godaddy-1635fe6f24bc?source=collection_archive---------6-----------------------
这篇文章过时了。Flask 需要 Python 3.7 >,请到这里查看更新的指令。
最*我决定在我的 GoDaddy 主机上托管我的 Python 应用程序,并花了几个小时调试,因为在 Heroku/Apache 独立服务器之外的其他服务器上安装 Python 和 Flask 的文档很难获得。我想把它放在我的托管*台上的原因是因为 Heroku 和其他人不能支持我的 web 应用程序需求。它们受限于功率和内存限制。任何复杂的应用程序都应该通过自己的*台托管,因为这样会快得多。
下面的 Github 文件可以在这里找到
****在接下来的几周,我将更新这篇文章,为新用户提供每个主题的链接,并且随着新问题的出现,还将增加更多的故障诊断内容。
目录:
- 先决条件
- 安装 Python
- 安装砂箱
- 设置你的烧瓶应用
- 启用 SSH
- 故障排除
先决条件
ᴛᴏᴘ^
在开始之前,你需要下载一些东西或者做一些准备。
****这些指令已经在 GoDaddy Shared 和 GoDaddy Business hosting 上进行了测试。
您将需要:
- 一个 GoDaddy 托管帐户,至少有 1 个网站托管。
- PuTTy 是一个免费的 SSH 控制台,用于连接 GoDaddy 服务器。这将用于安装 Python。
- 通过 GoDaddy 的 SSH 访问。(下面的说明)
- 稳定的互联网连接。如果互联网中断,安装将会停止,您必须卸载它并重新开始。我对这个有很多问题。
- 编程 IDE。我用 PyCharm 处理 Python/CGI,用 Visual Studio 处理 HTML、CSS 和 Javascript。
安装 Python
ᴛᴏᴘ^
登录 PuTTy(或其他 SSH 终端):
一旦 PuTTy 安装完毕,就可以开始安装 Python 了。打开 PuTTy 控制台。
PuTTy Icon. Don’t open PuTTyGen
键入您的主机名,这将是您在 GoDaddy 上启用 SSH 时的 IP 地址。这可以在Server
子菜单下的主机设置中找到。您的端口几乎总是为22
,但是请仔细检查以确保正确。这可以在 SSH 启用菜单中找到。点击打开,它将开始连接。
PuTTy 将创建一个到 GoDaddy 服务器的安全连接;它会提示您输入用户名进入主 FTP 账户。这将在您启用 SSH 的主机设置下找到。这将是一串字母字符和数字,都是小写字母。该密码将与用于登录 GoDaddy 的密码相同。
****一旦登录到 PuTTy,键入以下命令开始安装过程。
**##** *Download Python 3.5.7 (latest version GoDaddy supports as of writing)* $ wget [https://www.python.org/ftp/python/3.5.7/Python-3.5.7.tgz](https://www.python.org/ftp/python/3.5.7/Python-3.5.7.tgz)**##** *Once wget is done downloading* $ tar xvzf Python-3.5.7.tgz**##** *Once tar is done decompressing*$ cd Python-3.5.7**##** *This should take you to the main Python Directory*$ ./configure --prefix=$HOME/.local**##** This step sets up your configuration and makes files**$** make
**$** make install**##** *This will create the Python files and folders, but will take a long time. The last command will install* pip *and* setuptools *which will be used to install any package you want*
****上面的步骤将下载并安装 Python、pip 和设置工具。如果有任何错误,请参见下面的故障排除部分。(这将随着更多错误的发现而更新)
****接下来的需要完成 Python 的安装并确保环境变量已经设置好。
**$** cd $home
**$** vi .bash_profile**##** Press enter and change the file to equal this EXACTLYPATH=$HOME/.local/bin:$PATH
export PATH**##** Once done, Type :wq and press enter. This will save your file and close it**$** python3 -V
**>>** Python 3.5.7
****那里你去吧!如果你只是想在 GoDaddy 上安装 Python3,你可以就此打住!如果你想在 GoDaddy 上部署 Flask 或 Heroku 应用,请继续这篇文章。
安装烧瓶
ᴛᴏᴘ^
注意:如果你使用的是子域,确保子域文件夹在 public_html 里面,除了你需要添加 *subdomain_name/*
到这些指令之外,这些指令都是一样的。
**##** Install Virtual Environment Package
**$** python3 -m pip install virtualenv**##** Navigate to your CGI-BIN folder inside public_html
**$** cd $home
**$** cd public_html/cgi-bin**##** Create Virtual Environment. 'venv' can be named whatever you want, but just change the other code accordingly.
$ virtualenv venv**##** Activate the virtual environment
**$** source venv/bin/activate
**$** pip install Flask
**$** deactivate
Flask 现已安装,可在接下来的步骤中用于设置 Flask 应用程序以在 GoDaddy 主机上运行。
****你也可以安装任何需要的包,就像本地机器上面的步骤一样。安装前一定要用source venv/bin/activate
激活虚拟环境,否则无法工作。
设置您的 Flask 应用程序
ᴛᴏᴘ^
为了发布 GoDaddy 托管的应用程序,您需要将其转换为 GoDaddy 可以使用的东西。为此,我们将不得不使用一个名为wsgiref
的包。不需要下载任何东西,因为这个包从 2.7 开始就包含在 Python 中了。
一旦你完成这些说明,这个就是你最终的文件夹结构。(你可以从我的 Github 复制/粘贴源代码,但在修改任何选项之前,请确保你完全理解)。静态文件夹是可选的,它允许你在你的 Flask 应用中使用 CSS 和 Javascript,但是那是另外一篇文章。
public_html/
├── .htaccess
└── cgi-bin/
├── app.cgi
├── app.py
├── templates/
│ └── home.html
└── venv/
****将在cgi-bin
中新建一个文件,命名为app.cgi
。以下代码应该放在该文件中,并根据您的网站设置进行更改。
用户名将与您登录 PuTTy 或其他 SSH 终端时的用户名相同。
#!/home/USERNAME/.local/bin/python3
import os
import syssys.path.insert(0,
'/home/USERNAME/public_html/cgi-bin/venv/lib/python3.5/site-packages')from wsgiref.handlers import CGIHandlerfrom app import appclass ProxyFix(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
environ['SERVER_NAME'] = ""
environ['SERVER_PORT'] = "80"
environ['REQUEST_METHOD'] = "GET"
environ['SCRIPT_NAME'] = ""
environ['QUERY_STRING'] = ""
environ['SERVER_PROTOCOL'] = "HTTP/1.1"
return self.app(environ, start_response)if __name__ == '__main__':
app.wsgi_app = ProxyFix(app.wsgi_app)
CGIHandler().run(app)app.wsgi_app = ProxyFix(app.wsgi_app)
CGIHandler.run(app)
让我们稍微分解一下代码。第一行是被称为shebang
的,它告诉程序使用什么 shell。在本例中,我们正在运行 python,因此我们需要将它指向 python shell,它位于/local
文件夹中。
接下来你导入你的应用,就像一个普通的 init。py 文件。class ProxyFix
初始化应用程序,并确保设置正确的环境变量。您可以根据需要更改和删除环境变量,但是这些应该适用于大多数项目。需要改变的主要是'QUERY_STRING' & 'REQUEST_METHOD'
。如果设置了这些,对 Flask 应用程序的所有调用都将是 GET 请求,查询字符串将是NONE
。
****在cgi-bin
中创建另一个名为app.py
的新文件,并键入以下代码。这段代码设置了一个测试应用程序,所以 Flask 有一些东西要显示。
from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')
def home():
return render_template('home.html')
****在内cgi-bin
创建一个名为templates
的文件夹,并在该文件夹内创建一个名为home.html
的文件
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<h2>It Works! Congrats!</h2>
</body>
</html>
****在主public_html
文件夹中插入一个名为.htaccess
的文件。下面的代码将所有传入的请求指向你的 app.cgi 文件,并确保唯一运行的是你的 Flask 应用。将用户名更改为您用于 SSH 终端的主 FTP 帐户。
Options +ExecCGI
AddHandler cgi-script .py
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /home/USERNAME/public_html/python/cgi-bin/app.cgi/$1 [L]
我在这里会完全诚实,我不是这方面的专家。htaccess 文件,但我能够得到这个工作与一些摆弄左右。确保你完全复制粘贴了这个。如果差了一个空格或一个字母,就不行了。
****那里你去吧!一旦这些都上传完成,输入你的网址并祈祷吧!您可以开始扩展并确保导入所有需要的包。您最有可能创建一个脚本来检查安装并为您安装它们,但这不是本文的内容。
最重要的是,你的应用程序不会打印或输出任何非 HTML 格式的内容。这是在任何*台上发布任何 Flask 应用程序的一个缺点。
【GoDaddy 内的所有 Python 和 CGI 文件必须将权限设置为 755。请确保在尝试打开 URL 之前进行检查。
如何启用 SSH
ᴛᴏᴘ^
- 登录 GoDaddy 主机
- 单击您托管的网站:
- 在右边,点击
Settings
菜单下的Server
按钮 - 点击
SSH Access
旁边的Manage
。 - 从那里你所要做的就是将开关拨到
On
注意:记住你的端口号(22)、用户名和 IP 地址。这将位于帐户选项卡下的设置菜单中,但我们将在 Python 安装期间使用它们。
注 cPanel 密码是您登录 GoDaddy 使用的密码。
解决纷争
ᴛᴏᴘ^
尝试通过 URL 打开 flask 应用程序时,我收到错误 500。
- 检查 GoDaddy cPanel 中的错误日志。它会让你很好地了解正在发生的事情。最常见的情况是没有安装软件包,或者 Python 安装失败而没有抛出错误。
- 或者,确保您的应用程序根本不打印或试图访问控制台,这将使应用程序崩溃。
- 环境变量也可能不正确。最常见的是 SERVER_NAME 和 SERVER PORT,它们必须与上面脚本中的完全相同。
Python 安装失败。是在 **make**
或者 **make install**
期间抛出错误。
- 最有可能的是,由于
ctypes
的错误,安装失败。这些都包含在 Python 2.7 中,但是 GoDaddy 没有将它们安装到他们的 Python 版本中。尝试下载旧版本或新版本的 Python。烧瓶兼容 2.7。及以上,不包括 3.0。–3.4.*** - 确保您对尝试安装 Python 的文件夹具有读/写权限。
尝试打开应用程序时,我收到一个 404 错误。
- 检查你的。htaccess 文件,并确保它和我的完全一样。
- 请确保@app.route 具有有效的端点,即:/home,/,/index
这些尚未通过 GoDaddy 或 Windows 主机在 VPS 主机上进行测试。据我所知,GoDaddy Windows 不支持 Python。
这段代码摘自 GoDaddy 的博客文章 此处 ,已经修改为与 Flask 一起工作,并添加了一些自定义代码。
感谢 Flask 文档为用户提供了一个起点。 文档链接
在 Windows 10 上安装支持 CUDA、cuDNN 和 GPU 的 Tensorflow
原文:https://towardsdatascience.com/installing-tensorflow-with-cuda-cudnn-and-gpu-support-on-windows-10-60693e46e781?source=collection_archive---------0-----------------------
在本系列的第 1 部分中,我讨论了如何升级您的 PC 硬件,以集成 CUDA Toolkit 兼容的图形处理卡,例如 Nvidia GPU。第 2 部分介绍了在 Windows 10 上安装 CUDA、cuDNN 和 Tensorflow。下面这篇文章假设你已经在你的电脑上安装了一个兼容 CUDA 的 GPU 但是如果你还没有准备好,本系列的第 1 部分将帮助你设置硬件,为这些步骤做好准备。
第一步:检查你需要安装的软件
假设您的电脑上已经安装了 Windows,您将在这些步骤中安装的其他软件包括:-
- Microsoft Visual Studio
- NVIDIA CUDA 工具包
- NVIDIA cuDNN
- 计算机编程语言
- Tensorflow(有 GPU 支持)
步骤 2:下载 Visual Studio 速成版
Visual Studio 是 CUDA 工具包的先决条件
安装 Nvidia CUDA Toolkit 需要 Visual studio(这个先决条件这里指的是)。如果您试图在没有安装 Visual Studio 的情况下下载并安装 CUDA Toolkit for Windows,您会得到如图 1 所示的消息。
Fig 1: Message when attempting to install CUDA Toolkit without Visual Studio
选择和下载 Visual Studio 速成版
在撰写本文时,Visual Studio 的最新版本(免费)是 Visual Studio Express Community Version 2017,如图 2 所示。加入“Visual Studio Dev Essentials”,然后搜索想要的 Visual Studio 版本,就可以免费获得 Visual Studio 以前的版本。
Fig 2: Visual Studio Community 2017 (free)
安装 Visual Studio 速成版
一旦您下载了 Visual Studio 速成版,它的安装就很简单了。图 3 显示了下载的可执行文件。
Fig 3: The Visual Studio Community executable file
当你按下图 3 中的“保存文件”选项时,图 4 中的窗口将会出现,你可以在这里设置安装选项(或者像我一样,让它们保持默认设置)。
Fig 4: installation window for Visual Studio Community 2017
在安装过程中,Visual Studio 会提示您是否'希望在没有工作负荷的情况下继续。我在这里按了“继续”,因为我根本不想使用工作负载。
Fig 5: I didn’t add workloads on prompting by Visual Studio
安装 Visual Studio 后,可能需要重新启动电脑 d
安装 Visual Studio 后,我开始直接下载并尝试安装 CUDA Toolkit for Windows——这一步是我将在下面描述的第 3 步。我得到消息说 Visual Studio 仍在运行,并阻止 CUDA 工具包的安装。在尝试再次安装 CUDA Toolkit 之前重启我的电脑解决了这个问题。
第三步:下载适用于 Windows 10 的 CUDA 工具包
这些 CUDA 安装步骤大致基于Nvidia CUDA windows 安装指南。CUDA 工具包(免费)可以从 Nvidia 网站这里下载。
在撰写本文时,所提供的 CUDA 工具包的默认版本是 10.0 版,如图 6 所示。但是,你应该检查你选择下载和安装哪个版本的 CUDA 工具包,以确保与 Tensorflow 的兼容性(期待本流程的步骤 7 )。当你进入 Tensorflow 网站时,可用的 Tensorflow 最新版本(1.12.0)需要 CUDA 9.0 ,而不是 CUDA 10.0。要找到 CUDA 9.0,您需要导航到图 6 右下角的“Legacy Releases”。
Fig 6: The default (most recent) version of CUDA for Windows is cuda_10.0.130_411.31_win10.exe. For CUDA 9.0, choose “Legacy Releases”
步骤 3.1:从 CUDA 工具包档案下载 CUDA 9.0
选择“遗留版本”会将您带到 CUDA 工具包归档。根据 Tensorflow 安装指南,所需的 CUDA 版本为 9.0,如图 7 所示。
Fig 7: List of archived CUDA releases still available for download — CUDA Toolkit 9.0 (Sept 2017)
步骤 3.2:安装 CUDA 9.0
CUDA 9.0 以基础安装和四个补丁的形式提供;必须首先安装 CUDA 9.0 的基础安装,然后安装补丁。我选择的基本安装选项如图 8 所示。
Fig 8: Options chosen for the base installation of CUDA 9.0 for Windows base installer
运行刚刚下载的基础安装程序将产生 CUDA 安装包窗口,如图 9 所示。
Fig 9: CUDA Setup Package for CUDA base installer
CUDA 安装程序解压到您的电脑上,完成后,NVIDIA CUDA Toolkit 安装将开始;你会收到一条大意如此的信息。整个安装过程中产生的 NVIDIA 安装程序窗口如图 10-图 13 所示。我选择了快速安装选项(图 10)。
Fig 10: Installation options for CUDA 9.0 base installer — I chose the Express option
图 11 提供了选择安装位置的机会;我选择了所提供的默认位置,对于 CUDA 来说是:
C:\Program Files\NVIDA GPU Computing Toolkit\CUDA\v9.0
Fig 11 : CUDA 9.0 base installation — selecting CUDA installation location
下面的图 12 显示了依赖于 Visual studio 的 CUDA 安装,先前在步骤 1 中安装。
Fig 12: CUDA 9.0 base installation process — window showing installations relying on Visual Studio
在上面图 12 所示的窗口中按下“下一步”,出现最后的安装窗口,如下图 13 所示,其中 NVIDIA 安装程序被标记为完成。
Fig 13: Final installation window for CUDA 9.0 base installer
第四步:下载 Windows 10 CUDA 补丁
在撰写本文时,有四个 CUDA 补丁需要获取(以及基础安装程序),所以让我们去下载这些补丁吧。它们如图 14 所示
Fig 14: Downloading and installing the additional four patches for CUDA 9.0
下载这四个修补程序后,它们可以按照与基本安装程序相同的方式进行安装,安装窗口会在整个过程中提供指导。
第 5 步:下载并安装 cuDNN
安装了 CUDA 9.0 基础安装程序及其四个补丁后,下一步是找到 CuDNN 的兼容版本。根据 Tensorflow 网站上的信息,具有 GPU 支持的 Tensorflow 要求 cuDNN 版本至少为7.2。
步骤 5.1:下载 cuDNN
为了下载 CuDNN ,你必须注册成为 NVIDIA 开发者计划的成员(这是免费的)。
Fig 15: Creating a free membership account in order to download cuDNN
当您创建一个帐户,登录并填写一些关于您为什么使用该帐户的其他必需的细节时,您会得到如图 16 所示的下载页面。
Fig 16: cuDNN download page with selection of cuDNN v.7.4
由于我下载的是 CUDA 9.0,cuDNN 对应的版本是 7.4.2 版。选择 cud nn 7 . 4 . 2 版可下载如下名称的 zip 文件:
cudnn-9.0-windows10-x64-v7.zip
步骤 5.2:解压 cuDNN 文件并复制到 CUDA 文件夹
Nvidia 的说明提供了对 windows cuDNN 安装的支持,Tensorflow 网站上的说明也是如此;基于我对这些指令的实现,我以提炼的形式复制了这些指令。就我而言,我下载了 cuDNN。将上面命名的 zip 文件压缩到一个文件夹中,该文件夹在我的 PC 上有以下路径(您的路径无疑会不同)。
C:\Users\jo\Documents\cuDNN_downloads\
在下面的说明中,我将文件夹路径“*C:\ Users \ jo \ Documents \ cud nn _ downloads *”(上面提到的)称为“ < downloadpath > ”,这样,zip 文件现在位于以下路径中:
<downloadpath>\cudnn-9.0-windows10-x64-v7.5.0.56.zip
我拉开了拉链。zip”文件,因此包含所需 cuDNN 文件的解压缩文件夹结构现在是:-
<downloadpath>\cudnn-9.0-windows10-x64-v7.5.0.56\
解压缩后的 cuDNN 文件夹子目录中有三个文件,它们将被复制到 CUDA Toolkit 目录中。它们是 cudnn64_7.dll、cudnn.h 和:
1。cudnn64_7.dll
cudnn64_7.dll 可以在下载的 cudnn 文件的以下路径中找到:
<downloadpath>\cudnn-9.0-windows10-x64-v7.5.0.56\cuda\bin\cudnn64_7.dll
假设您将 CUDA 9.0 安装到了它的默认路径(正如我在步骤 2.3 中所做的),即下面的默认路径:
C:\Program Files\NVIDA GPU Computing Toolkit\CUDA\v9.0
可以将 cudnn64_7.dll 文件直接复制到 CUDA 文件夹的 bin 文件夹路径中(注意:不需要新建任何子文件夹):
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\bin\
2。cudnn.h
和上面的 cudnn64_7.dll 文件一样,下载并解压 cudnn 文件夹后,可以在路径中找到头文件 cudnn64.h :
<downloadpath>\cudnn-9.0-windows10-x64-v7.5.0.56\cuda\ include\cudnn.h
同样,假设您像我在步骤 2.3 中一样将 CUDA 9.0 安装到默认路径中,将 cudnn.h 直接复制到 CUDA 文件夹中,路径如下(不需要新建子文件夹):
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\include\
3。cudnn.lib
的。lib 文件 cudnn.lib 可以在下载的 cudnn 路径中找到:
<downloadpath>\cudnn-9.0-windows10-x64-v7.5.0.56\cuda\lib\x64\cudnn.lib
将 cudnn.lib 直接复制到 CUDA 文件夹中,路径如下:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\lib\x64\
步骤 5.3:检查在 Windows 中设置了 CUDA 环境变量
最后,Nvidia 的指令指示您确保 CUDA 环境变量已经预先设置好,如下所示:
Variable Name: CUDA_PATH
Variable Value: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0
在 Windows 10 中,可以通过选择以下选项找到环境变量:
控制面板->-系统和安全->-系统->-高级系统设置。
这将打开一个名为“系统属性”的窗口(图 17),此时应该选择“环境变量”按钮。
Fig 17: Environment Variables button (in System Properties window) for setting and checking CUDA paths
当环境变量窗口出现时,在“系统变量”中(在窗口的下半部分),点击“路径”并选择按钮“编辑”。将出现一个新窗口,名为“编辑环境变量”,如下图 18 所示。
在检查环境变量时,我发现确定 CUDA 安装路径的安装过程— 步骤 3.2 ,见图 11——已经向 CUDA 添加了两条路径。这些路径如下面的图 18 所示,所以我发现我不需要再添加一个 CUDA 路径。
Fig 18: Default paths previously created during CUDA 9.0 installation process
步骤 6:安装 Python(如果你还没有的话)
既然已经安装了 CUDA 和 cuDNN,是时候安装 Python 了,以便稍后安装 Tensorflow。在撰写本文时,Python 3 可用的最新版本是 Python 3.7,但 Tensorflow 所需的 Python 3 版本是 3.4、3.5 或 3.6 。Python 3.6 可以从这里为 Windows 10 下载。当您运行 Python installer for windows 时,将出现图 19 中的设置窗口。
Fig 19: Python 3.6 installation screen; I choose all the optional features on this screen (pip and IDLE are both used in subsequent steps)
在 Python 安装期间,我选择了上面图 19 中的所有选项。这些选项很有用:Python 的“pip”安装程序在本指南的步骤 7.2 中用于安装 Tensorflow。此外,我在步骤 8 使用了名为“IDLE”的 IDE(用于编写和运行 python 代码的集成开发环境)。
在“高级选项”中(如下图 20 所示),我为所有用户选择了 Python 的安装(默认情况下没有勾选);这提供了更有用的系统范围的安装。
Fig 20: Advanced options available when installing Python 3.6
步骤 7:安装带 GPU 支持的 Tensorflow
Tensorflow 提供指令来检查 CUDA、cuDNN 和(可选:CUPTI)安装目录是否被正确添加到 PATH 环境变量中。由于三个 cuDNN 文件被复制到 CUDA 的子文件夹中,所以我没有更新现有的 CUDA 环境变量路径。
步骤 7.1:使用管理权限调用命令提示符
在此步骤中,将执行 Tensorflow 的系统范围安装,而不是每个用户的安装。Tensorflow 的系统范围安装需要管理权限,因此,相应地,命令提示符应该以管理权限运行。
通过在搜索栏中运行' cmd '打开命令提示符,然后右键单击命令提示符选择'以管理员身份运行'。这将打开 Administrator:命令提示符,如图 21 所示。
Fig 21: Running the command prompt as administrator from the Windows 10 search bar
步骤 7.2:通过 python pip 在系统范围内安装 tensor flow
打开命令提示符后,带 GPU 支持的 Tensorflow 的系统范围安装命令如下:
pip3 install --upgrade tensorflow-gpu
“pip3”命令(相对于“pip”)是必需的,因为安装到 Python 3。在命令提示符下执行该命令如图 22 所示。
Fig 22: Pip install command for Tensorflow with GPU support
该命令的输出如图 23 所示,如果一切按计划进行,最终应该会有一条消息确认 Tensorflow 已经成功安装。
Fig 23: Command prompt messages shown when Tensorflow GPU 1.12.0 installed successfully.
步骤 8:测试 TensorFlow 的安装及其对 GPU 的访问
进入 windows 中的开始菜单,搜索名为“idle”的 IDE,如果你像我在步骤 6 中所做的那样选择,它将作为 python 安装的一部分进行安装。一个 Python 窗口应该显示为Python 3.6 . x Shell。在提示符下(用'> > >')导入 Tensorflow 包。这将检查 Tensorflow 是否已安装(因为您可以导入它)。空闲 shell 导入 tensorflow 包的命令如下:
# importing the tensorflow package
import tensorflow as tf
要测试您的 Tensorflow 安装对 CUDA 的支持,您可以在 shell 中运行以下命令:
tf.test.is_built_with_cuda()
最后,为了确认 GPU 对 Tensorflow 可用,您可以使用 TensorFlow 中的内置实用函数进行测试,如下图所示:
tf.test.is_gpu_available(cuda_only=False, min_cuda_compute_capability=None)
从这里返回一个结果需要几分钟;完成后返回 真 ,然后提示` > > > '再次出现。导入 tensorflow 和这些测试都显示在 Python IDLE Shell 的图 24 中。
Fig 24: Using the IDLE python IDE to check that Tensorflow has been built with CUDA and that the GPU is available
结论
这是我安装 Visual Studio、CUDA Toolkit、CuDNN 和 Python 3.6 的步骤,最终目的是在 Windows 10 上安装支持 GPU 的 Tensorflow。迄今为止,我基于 GPU 的机器学习和深度学习工作一直在 Linux Ubuntu 机器上进行;出于同样的原因,很多机器学习社区的在线支持都集中在 Ubuntu 上。
对于机器学习来说,使用 Windows 的主要缺点是,与在 Linux 上相比,需要从源代码中构建更多的东西(例如使用 Cmake ),并且还需要为构建过程安装额外的软件,例如 Visual Studio。例如,如果您要在 Windows 上安装 Caffe2 ,则没有预构建的二进制文件,Windows build 处于测试和 beta 模式。我在 Windows 10 上安装 CUDA 和 cuDNN 更多的是出于好奇,只是想看看它有多简单(或其他)。
正如我在第一部分中所暗示的,现在 CUDA、cuDNN 和 Tensorflow 已经成功安装在 Windows 10 上,并且我已经检查了 Tensorflow 对 GPU 的访问,我将清除整个 Windows 10 操作系统,以便全新安装 Ubuntu 18.04 LTS。这个新的 Ubuntu 安装将在本系列的第 3 部分中讨论。
这篇文章也在 https://schoolforengineering.com 的这里发表过。
实例选择:数据采样背后的神话
原文:https://towardsdatascience.com/instance-selection-the-myth-behind-data-sampling-d3556ea2e37d?source=collection_archive---------23-----------------------
任何大数据系统中最常见和最具挑战性的问题之一是选择分层样本,使其能够代表整个数据群体的特征。从数据注释到评估数据集的选择,数据采样是每个数据科学解决方案成功的关键。高效采样也是一个关键要求,因为它假设在这个采样集上训练的机器学习模型和生成的洞察对更广泛的集合适用。
实例选择的概念是通过保持基本分布不变从总体中选择一个子集,以便采样数据能够代表整个数据总体的特征。
让我们假设您有大约 100 亿个未标记的数据点。要解决你遇到的这类问题,可能需要一种监督的方法。现在的问题是如何注释所有这些数据点?除非你想出一种方法来自动化注释过程,否则在许多人类专家的帮助下,这将花费大量的时间。即使我们设法拥有所有数据的标签,由于资源限制,在非常大量的数据上训练机器学习模型有时也是不可行的,并且可能消耗非常大量的时间来训练,这也导致不可行的状态。同时,大量的数据可能彼此相似。因此在图案中引入了冗余。这种冗余数据在模型的学习过程中帮助不大。我们可以通过仔细分析数据集中存在的所有维度来大幅缩减数据集,从而减少训练时间并提高性能。
实际上,处理这种情况的方法是计算在可用时间和可用资源内可以注释的数据量,并从总体中选择许多样本,使样本遵循总体数据的相同基本分布。有两种方法可以实现这一目标:
- 定量取样
- 数据驱动采样[实例选择]
2 训练机器学习模型的主要目的是学习多个类别/聚类之间的决策边界,或者学习输入数据分布。从统计学上来说,对于这些情况,只要群体和采样数据之间的基础数据分布不变,学习将是相似的。
- 定量抽样:这种抽样技术需要大量的领域知识和对数据的深入理解。该策略根据数据类型而不同,无论是文本数据、图像数据、音频数据还是视频数据等。
一、唯一性:采样的第一步是找出唯一的数据点。独特性可以用几种方式来定义。在文本数据的情况下,如果两个文档具有相同顺序的完全相同的单词集,则它们可以被认为是重复的,或者在图像数据的情况下,如果两个图像数据(相同大小)之间的欧几里德距离小于ε,则这些可以被认为是重复的。找出所有重复的数据点,其中只有一个将代表其他重复的数据点。
二。模式:这一步非常棘手,需要领域知识。大多数情况下,我们需要手动或通过半自动过程从数据中识别一组模式/结构。如果我们有一个时间序列数据,也许一个模式是周期性的。也许我们能发现一种模式每个月都在重复。然后,我们需要选择分布在一年中每个月的候选数据,但对个别月份的数据进行缩减采样。
对于文本数据,在删除停用词后,我们可以用相应的“词性”替换每个词,如下所示:
POS tag of text document
可以将词性标签序列视为给定文本的结构,并基于词性标签序列进行数据的重复数据删除。但是我们需要确保在样本空间中维护词汇。
2。数据驱动采样:实例选择首先从所有重要维度的数据采样开始。进行数据驱动采样的方法之一是首先以监督或非监督的方式学习数据的分布式嵌入表示,然后遵循候选选择的贪婪算法,其思想是选择一个数据点作为位于 delta-ball 距离内的所有其他数据点的代表。如下图所示,每个浅绿色或浅红色圆圈是一个半径为δ的球体,仅从球体中选择一个数据点作为球体的代表。关于 delta 的选择有不同的研究。可以在质心和边界区域周围选择较小的增量,而在其他区域选择相对较大的增量值。增量越大,表示越稀疏。对δ的这种选择将确保质心和边界区域中的密集群体,而导致中间区域周围的稀疏群体。
Visualization of delta-ball sphere
在文本数据的情况下,可以利用 word2vec、fasttext 或 Glove 嵌入,而在图像数据的情况下,可以训练低延迟分类器模型来获得分布式嵌入表示。
结论:从数据收集到模型维护,在数据科学产品生命周期的每一步,相关数据点的选择都起着至关重要的作用:
I .人类专家用于注释的所有数据点是什么。
二。所有数据点将用于模型训练。
三。如何对评估数据集进行采样以测量已训练模型的性能。
四。历史中的所有数据点都需要重新运行更新的模型,因此我们只在选择的实例上重新运行模型,这些实例很可能会绕过邻居群集。
Git: 助手代码可用这里
用于音频分析的瞬时频率特征与频谱特征
原文:https://towardsdatascience.com/instantaneous-frequency-features-vs-spectogram-features-for-audio-analysis-fac224d84152?source=collection_archive---------38-----------------------
What a spectrogram looks like.
音频信号表示
首先,让我们试着理解音频信号是如何表示的。音频信号由不同的正弦分量组成,可以用数学方法表示如下:
其中 x(t):信号,r(t):幅度,θ(t):信号正弦分量的相位。
音频信号的幅度-时间表示可以如下所示:
Amplitude time representation.
音频信号的频谱图特征
它是信号频谱随时间变化的直观表示。可以使用几种方法生成频谱图,包括傅立叶变换、小波变换和带通滤波器。
设 x 是长度为 n 的信号。考虑长度为 m 的 x 的连续段(或“片段”),其中 m ≤ n,设 X ∈ R ^(m×(N−m+1)是以连续段作为连续列的矩阵。换句话说,[x[0],x[1],。。。,x[m 1]]^t 是第一列,[x[1],x[2],。。。x[m]]^T 是第二列,依此类推。X 的行和列都是按时间索引的。
窗口大小为 m 的 x 的谱图是矩阵 xˇ,其列是 x 的列的 DFT。因此
xˇ的行按频率索引,列按时间索引。
python 中的声谱图定义在声谱图中提供。
瞬时频率特征
瞬时频率特征也称为 IF,当与 mel-filterbank 结合时,产生 ifgram 特征矩阵,而不是频谱图特征矩阵。
对于音频信号,瞬时频率在数学上定义为:
其中φ(t)表示瞬时频率,d(θ(t))表示相位,t 表示音频信号的时间参数。mel-ifgram 特征矩阵具有类似于 Mel-spectra gram 特征矩阵的形状,但是包括时间导数分量。数学上,mel-ifgram 特征矩阵可以定义为 IF 频谱图和滤波器组矩阵的点积。
在 Ifgram 中解释了 python3 中瞬时频率特性的实现。
带 R 的整数规划
原文:https://towardsdatascience.com/integer-programming-in-r-33ee6f48a3c8?source=collection_archive---------11-----------------------
r 代表工业工程师
探索“LP solve”R包
Image by Nick Hillier available at Unsplash
运筹学
运筹学是一种科学的决策方法,通常在需要分配稀缺资源的条件下,寻求系统的最佳设计和操作。制定决策的科学方法需要使用一个或多个数学/优化模型(即实际情况的表示)来做出最佳决策。
优化模型寻求在满足给定 约束 的决策变量的所有值的集合中找到优化(最大化或最小化) 目标函数 的 决策变量 的值。它的三个主要组成部分是:
- 目标函数:要优化的函数(最大化或最小化)
- 决策变量:影响系统性能的可控变量
- 约束:决策变量的一组限制(即线性不等式或等式)。非负约束限制决策变量取正值(例如,您不能产生负的项目数 x 1、 x 2 和 x 3)。
优化模型的解称为最优可行解。
建模步骤
精确地模拟一个运筹学问题是最重要的——有时也是最困难的——任务。一个错误的模型将导致一个错误的解决方案,因此,不会解决原来的问题。以下步骤应该由具有不同专业领域的不同团队成员执行,以获得模型的准确和更好的视图:
- 问题定义:定义项目的范围,确定结果是三个要素的确定:决策变量的描述、目标的确定和限制条件(即约束条件)的确定。
- 模型构建:将问题定义转化为数学关系。
- 模型求解:使用标准优化算法。在获得解决方案后,应进行敏感性分析,以找出由于某些参数的变化而导致的解决方案的行为。
- 模型有效性:检查模型是否如预期的那样工作。
- 实施:将模型和结果转化为解决方案的建议。
整数规划
整数规划(也称为 IP)是一种运筹学技术,当(通常)所有的目标和约束都是线性的(在变量中)并且所有的决策变量都是整数或二进制(即 0 或 1)时使用。当决策变量的子集被允许连续时,这有时被称为混合整数线性规划(也称为 MILP)。
来自 R 的 lpSolve 包包含了几个用于解决整数规划问题和获得重要统计分析的函数。对于下面的例子,让我们考虑下面要求解的数学模型:
这是一个整数规划问题的例子,其中所有决策变量都是二进制的(即,它们可以取值 0 或 1)。
我们来看看 R 代码!
Integer Programming R Code
解决方案:
在满足给定约束的情况下可以获得的最大 z 值(因此也是最优值)为 19,其中 x 1 = 1 ,x 2 = 1, x 3 = 0, x 4 = 0。灵敏度系数从 0,0,-1e+30 和-1e+30 到所有的 1+e30。约束的影子/对偶价格分别为 0、0 和 0,而决策变量的影子/对偶价格分别为 8、11、6 和 4。约束和决策变量的影子/双重价格下限都是-1.0e+30。最后,约束的影子/双重价格上限分别为 1.0e+30、1.0e+30、1.0e+30、1.4e+00,而决策变量的上限分别为 1.285714e+00、5.0e-01 和 6.667e-01。
总结想法
整数规划代表了另一种更好的决策优化技术。 lpSolve R 包允许用几行代码解决整数规划问题并获得重要的统计信息(即敏感性分析)。虽然有其他免费的优化软件(如 GAMS、AMPL、TORA、LINDO),但在您的个人代码库中存储一个整数优化 R 代码可以节省您大量的时间,因为您不必从头开始编写公式,而只需更改相应矩阵的系数和符号。
— —
如果你觉得这篇文章有用,欢迎在 GitHub 上下载我的个人代码。你也可以直接在 rsalaza4@binghamton.edu 给我发邮件,在LinkedIn上找到我。有兴趣了解工程领域的数据分析、数据科学和机器学习应用的更多信息吗?通过访问我的媒体 个人资料 来探索我以前的文章。感谢阅读。
罗伯特
在你的应用中集成人脸检测
原文:https://towardsdatascience.com/integrate-face-detection-in-your-app-df29f6ae932a?source=collection_archive---------24-----------------------
不要不知所措,因为将人脸检测添加到您的应用程序从未如此容易!
Face detection on an original image by Austin Distel on Unsplash
很多时候,人脸检测不是应用程序的主要焦点,但却是一个重要的组件,许多开发人员只是被将人脸检测添加到他们的应用程序的想法所淹没。
如果应用程序要计算进出商店的人数,开发人员需要检测的人脸来计算人数。在这样的情况下,他们肯定不希望重新发明轮子,建立自己的人脸检测器(除非你有巨大的预算和开发时间,当然还有机器学习团队)。相反,他们希望获得市场上已有的人脸检测器,并将其集成到他们的应用程序中,并继续专注于他们应用程序的目标。
想象一下,如果像 Facebook Messenger、WhatsApp 和 Viber 这样的即时通讯*台都要重新发明 TCP/IP ,那么今天还会有多少即时通讯*台存在。
在这篇文章中,我将讨论你可以从(还有很多我没有探索的,所以也可以随意寻找其他解决方案)和中选择的一些选项,以及示例 python 代码,用于人脸检测。
因此,让我们来看看今天您可以选择的一些人脸检测器,以便您可以轻松地将其集成到您的应用程序中,减少您的开发时间,使您能够更快地交付给您的客户。
微软 Azure Face API
Face API 是微软 Azure 提供的认知服务之一。它可以用于使用客户端 SDK 在本地或使用 REST API 在云中检测人脸。面向 Face API 的客户端 SDK 可用于。NET,Python,Java,Node.js. Go,还有 iOS。
下面是使用 Face API Python Client SDK 进行人脸检测的代码片段:
下面是在一些面部图像上运行上述人脸 API Python 客户端 SDK 人脸检测代码的输出:
从上面的输出图像中,我们可以观察到所有正面人脸都被检测到,一些侧面人脸被检测到,而一些被 Microsoft Azure Face API 遗漏。
关于 Azure Face API 的更多细节,请参考文档。
亚马逊认知
亚马逊 Rekognition 可以检测图像和视频中的人脸。当提供人脸图像或视频时,它给出人脸所在位置的信息。Amazon Rekognition 在云端进行人脸检测,并提供 Java、Python、.NET、Ruby 和 Node.js 来封装实现,让开发者更容易使用。
以下是使用 Python SDK 将 Amazon Rekognition 用于人脸检测的示例代码:
下面是在一些面部图像上使用 Python SDK 对面部检测代码运行上述 Amazon Rekognition 的输出:
从上面的结果中,我们可以看到所有的人脸,正面和侧面人脸都被 Amazon Rekognition 检测到了。
关于亚马逊 Rekognition 的更多细节,请参考文档。
Xailient FaceSDK
Xailient 的 FaceSDK 是世界上最快的人脸检测器。人脸检测发生在设备本身,并针对 Raspberry Pi 等边缘设备的使用进行了优化。Xailient 的 Face SDK 适用于 ARM 32、ARM 64 和 x86_64 设备。
当您下载 FaceSDK 时,它附带了示例代码和测试图像,您可以毫不费力地看到它正在运行。
以下是使用 Xailient Python Face SDK 进行人脸检测的示例代码:
以下是 Xailient FaceSDK 对相同输入面部图像的输出:
我们可以观察到,使用 Xailient FaceSDK 可以检测到所有正面和大部分侧面轮廓的面。
有关 Xailient FaceSDK 的更多信息,请参考网站。
谷歌云视觉 API
谷歌的云视觉 API 也有一个人脸检测功能。类似于 Amazon Rekognition,为包括 C#、Go、Java、Node.js、Python PHP、Ruby 在内的不同语言提供了使用人脸检测的客户端 SDK。
下面是使用谷歌云视觉 API Python SDK 的人脸检测的示例代码:
下面是在一些面部图像上运行上述谷歌云视觉 API Python SDK 人脸检测代码的输出:
使用 Google Vision API,可以检测到大多数人脸,包括正面和侧面。
有关谷歌用于人脸检测的云视觉 API 的更多信息,请参考文档。
在这篇文章中,我们看了一些人脸检测器:微软 Azure FaceAPI,亚马逊 Rekognition,Xailient FaceSDK 和谷歌云视觉 API,用 Python 编写了样本代码,并输出了在一些面部图像上运行它们的图像。虽然亚马逊人脸识别在样本输入图像中显示出最好的结果,但所有四个人脸检测器表现同样出色。使用微软 Azure FaceAPI 、亚马逊 Rekognition 和谷歌云视觉 API 在云上为人脸检测处理图像,而使用 Xailient SDK 在本地(设备上)处理图像。这四个工具都很容易使用, Xailient SDK 是最简单的,因为它需要最少的代码来运行面部检测。
您正在使用人脸检测构建什么应用程序?你用的是哪个人脸检测器? 在下面留下你的想法作为评论。
原载于www.xailient.com/blog。**
更多故事:
在计算受限的设备上运行深度学习计算机视觉的挑战
运行物体检测上的挣扎
你现在需要从云计算转移到边缘计算!
将业务优化与机器学习模型相集成
原文:https://towardsdatascience.com/integrating-business-optimization-with-a-machine-learning-model-ad0471420693?source=collection_archive---------9-----------------------
在本文中,我们阐述了将优化业务指标的目标与机器学习管道相集成的概念。具体来说,我们展示了一个简单的优化循环如何围绕一个核心 ML 算法来引导它实现特定的业务目标的案例说明。
介绍
机器学习(ML)的需求量很大。人工智能的这一分支正在颠覆传统和现代商业实践,并带来一生一次的变革。
[## 机器学习革命:人工智能如何改变你的业务
像机器学习(ML)这样有影响力的技术,很难避免夸张。当然,数十亿…
www.forbes.com](https://www.forbes.com/sites/allbusiness/2018/10/20/machine-learning-artificial-intelligence-could-transform-business/#7815726cc6c3)
然而,关于 ML 算法、工具和技术的学术讨论和在线文章通常只关注它们的实现、性能、部署和可伸缩性。
也详细讨论了 ML 的业务方面,但是这些讨论通常与核心算法或 ML 管道有些距离。很难找到一个简单的 ML 管道的例子,它整合了实现体面的 ML 性能和满足相当普通和直观的业务目标的双重目标。
然而,大公司在他们的运营中不断地进行这种整合——应用 ML 并调整管道以推动它满足整体业务目标(或其子集)。
对于年轻的数据科学和 ML 实践者来说,如何用一个足够简单的例子——也许是几行代码——来演示这个想法并不是很直观。
在本文中,我们展示了一个这样的例子。
机器学习问题:高精度
对于案例说明,我们将想象一个非常简单的场景— 一家全新的创业公司通过提供基于 ML 的预测分析产生收入。
特别是,它们接收数据流并预测二进制类作为输出——“是”或“否”。在其服务的核心,他们使用基于决策树的分类模型和集成技术——使用 AdaBoost 分类器。
他们预测的准确度越高,收入就越高。
当然,你可以做一个随机的预测(下面没有任何模型),仍然有 50%的预测正确。因此,他们只有在高于某个阈值的更高精度下才能获得报酬,这个阈值可以低至 50%。例如,如果他们对某项工作的预测准确率为 75%,那么他们将获得与 75% — 50% = 25%成比例的收入。
但是它们是如何达到更高的精度的呢?
一个简单直观的答案是调整算法的超参数。在像 AdaBoost 这样的算法中有相当多的超参数——大部分与底层的基本估计量有关。对于决策树,这些可以是每片叶子的最小样本数、最大树深度、像基尼指数这样的分裂标准等等。然而,为了使这个例子简单,我们选择了最直观的超参数——应用于增强的树估计器的数量。
在其核心,集成技术,如 Boosting 通过保持基本估计器相对简单和低精度(略高于 50%是好的)来工作。他们通过并行使用大量这种简单的基本估计器来实现强大的泛化能力,并对其预测进行*均,动态更新估计器在前一次迭代中出错的例子。
Source: Realizing Low-Energy Classification Systems by Implementing Matrix Multiplication Directly Within an ADC ( IEEE Transactions on Biomedical Circuits and Systems)
因此,毫不奇怪,较高数量的基本估计量可能导致更大的泛化能力——对客户数据(真正的未知测试集)的更高准确性。
之前,我们建立了一个简单的场景,即收入与客户提供的数据的预测准确度成正比。
因此,似乎最大化 ML 模型准确性的策略,从而最大化公司的收入,是保持单个基础评估者真正简单——选择树的最大深度,比如 2 或 3——并且使用大量的基础评估者。
这似乎是一个简单的策略。但是,它可能不是最佳的。
收入不是利润。十有八九,年轻的初创公司希望利润最大化,而不仅仅关注收入,因为这显示了他们的长期生存能力,并有助于他们获得更多投资和更多客户。
让我们稍微深入一下利润方面。
商业目标:利润最大化
利润是王道(至少在大多数商业情况下是如此),对于大多数类型的企业来说,利润是经济附加值的一个非常好的指标。没有人更喜欢以较低的运营成本获得可观的收入。
我们了解 ML 模型和收入之间的关系。但是,运营成本与模型有什么关系呢?
在现实生活中,这可能非常复杂。但是为了便于说明,我们可以简单地假设成本与模型拟合和预测的总计算时间成比例。
这并不难想象,因为如果年轻的初创公司租用某种云服务来托管和运行他们的 ML 算法,例如 AWS EC2,这种情况将是类似的,它是基于总计算时间计费的。
现在,您还记得感兴趣的超参数 Boosting 算法的基本估计数吗?坏消息是,这个数字越大,算法的计算量就越大,模型拟合和预测的计算时间就越长。
因此,我们确定了 ML 算法的单个超参数和两个业务指标(收入和成本)之间的关键关系。
什么是利润?这是一个很好的古老定义,
利润=收入-成本
最优化问题:如何选择最大似然算法来实现利润最大化?
这与传统的关于 ML 算法选择的讨论有些不同,不是吗?你可能已经做过很多次了,
- 偏差-方差权衡分析
- 对超参数进行网格搜索以确定最佳精度
- 争论 ML 性能测量的正确标准— 准确度/精确度/召回率?F1 比分? ROC 曲线和 AUC ?
- 头脑风暴数据获取和注释策略——进行特定的特征工程有意义吗?为增加训练集的大小而多花钱买几个标注有意义吗?
所有这些仍然至关重要。
但是,从商业的角度来看,很可能你被评判的唯一标准是你的 ML 算法能产生多少利润。如果它是一个很大的正数,高层管理人员很可能不会追问你算法的细节。如果是负面的,一切都可能失控!
因此,我们必须采取以下*衡措施,
我们构建了一个极其简单的场景,但至少,它显示了一个公*的机会,即一个算法选择可以与一个关键的业务指标紧密结合。
当一个模型参数同时影响两个输出(在我们的例子中是精度和成本)时,优秀的工程师会怎么做?
他们优化。
他们试图找到模型参数的最佳设置,这将最大化业务指标,在这种情况下是利润。
让我们通过一个简单的代码演示来看看如何做到这一点。
演示:以业务为中心的 ML 优化
事实上,遵循代码是乏味的,而且会让人分心。创意和图片好多了:-)
因此,我将让您从 Github repo 这里的派生并复制这个演示的代码。但是主要思想如下,
感兴趣的超参数——决策树估计器的数量——已经被编码为目标函数的参数,优化器算法可以最小化该参数。目标函数值的计算考虑了验证集上的提升算法精度和与模型拟合和预测所花费的时间成比例的简单成本项。
下面是训练集和验证集的准确性如何随着决策树估计器的数量而变化。
这里是计算时间(模型拟合和预测),
很明显,对于少数估计器,精确度从低值开始,但是在数量达到一定水*后 T4 就会饱和。另一方面,计算负荷持续增加。
因此,随着边际收益率(就提高精确度而言)在某一水*达到峰值然后下降,继续增加估值器的数量是没有意义的。
啊…就是这个…著名的 边际收益率 ,对商界人士来说是如此的*和贵。
机器学习科学家、工程师和业务开发团队终于有了一个共同的概念来思考,一个共同的衡量标准来绘图和决策。
为了更清楚地说明这种行为,我们构建了一个 目标函数—通过在一个具有适当权重的线性函数中组合验证集精度和计算时间,将精度和计算成本集成到单个标量输出中。如果我们绘制目标函数,可以清楚地看到 MRR 行为,
很容易看出,在这个等式中,准确度系数是正数,而计算时间系数是负数,以反映目标的真实性质——从收入中减去成本。
在 Github repo 中,我还展示了如何通过调用 Scipy 包中的函数来解决优化问题。对于这个特定的例子,目标函数是非常简单的,并且一个简单的图将显示演变,以确定包括在 ML 算法中的树的最佳数量是大约 10 或 11。所以,确实不需要使用 Scipy 函数。
但是,同样的想法可以扩展到一个更复杂的目标函数,其中包括过多的最大似然超参数。然后,优化算法的全部能力可以用来解决以业务为中心的优化。
参见本文中关于 Scipy 优化算法的讨论,
[## SciPy 优化及其在机器学习中的应用
我们展示了如何使用 Python 中最流行的科学分析包— SciPy 来执行优化,并讨论了…
towardsdatascience.com](/optimization-with-scipy-and-application-ideas-to-machine-learning-81d39c7938b8)
摘要
在本文中,我们讨论了以业务为中心的优化。讨论了一个简单的演示来清楚地说明这个想法——通常,ML 算法及其设置的选择需要由业务度量优化的总体目标来指导。在这种努力中,用优化循环包装核心 ML 算法对于快速决策非常方便。
事实上,在我之前的一篇文章 的 中,我谈到了这个想法不需要局限于单一类型的机器学习,甚至是单一类型的分析过程,而是可以跨越多种定量学科——ML 模型、统计估计、随机模拟等。—全部输入到一个通用优化引擎。
如果您有任何问题或想法要分享,请通过tirthajyoti【AT】Gmail . com联系作者。另外,你可以查看作者的 GitHub 资源库中其他有趣的 Python、R 或 MATLAB 代码片段和机器学习资源。如果你像我一样,对机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我,或者在 Twitter 上关注我。
[## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…
通过写作使数据科学/ML 概念易于理解:https://medium.com/@tirthajyoti 开源和有趣…
www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)
整合民族志和数据科学
原文:https://towardsdatascience.com/integrating-ethnography-and-data-science-baa65690dde0?source=collection_archive---------26-----------------------
Picture from Frank V
作为一名数据科学家和人种学家,我参与过许多类型的研究项目。在专业和商业环境中,我对数据科学和人种学的巨大发展感到兴奋,但也感到沮丧,尽管最*的发展使它们更加相似,但它们各自的团队似乎越来越疏远,相互竞争。
在学术界,定量和定性研究方法在历史上发展为截然不同和相互竞争的方法,就好像一个人在做研究时必须选择哪个方向:部门或个人研究人员专门研究这个或那个,并争夺稀缺的研究资金。这种划分的一个主要理由是,与倾向于描述性和自下而上的定性方法相比,定量方法倾向于指令性和自上而下。不幸的是,许多专业研究背景继承了这种划分。
数据科学的最新发展与定性研究相类似,如果有什么不同的话,可能是合作混合的起点。统计学入门课程中教授的“传统”统计学通常是自上而下的,假设数据遵循一个规定的理想模型,并根据该理想模型提出系统化的问题。在机器学习的发展过程中,出现了一种向模型的转变,这种模型是根据所讨论的数据和环境量身定制的,并且是反复开发和改进的。这些趋势可能会打破传统统计工作自上而下的性质。
Picture from Arif Wahid
如果有一个时间来整合定量数据科学和定性人种学研究,那就是现在。在日益重要的“数据经济”中,理解用户/消费者对于发展战略性商业实践至关重要。在商业世界中,面向社会的数据科学家和人种学家都是理解用户/消费者的专家,但将他们分成相互竞争的群体只会妨碍他们的洞察力的真正综合。整合两者不应该仅仅包括合并各自的研究团队和他们的项目,还应该鼓励研究人员发展两者的专长,而不是简单地专攻一个或另一个。当我们不再将这些视为独特的方法或专业时,新的创造能量就会爆发。
【I】纳福斯,d .&诺克斯,H. (2018)。数据饱和世界的民族志。曼彻斯特:曼彻斯特大学出版社,11-12。
(原刊在此:https://ethno-data . com/integrating-ethnography-and-data-science/。其余的文章请随意查看:【http://ethno-data.com/。)
也感谢《数据科学》杂志发表这篇文章。关于他们工作的更多细节,见 本 。
在以用户为中心的 ML 模型开发中整合人物角色
原文:https://towardsdatascience.com/integrating-personas-in-user-centered-ml-model-development-afb593741c49?source=collection_archive---------16-----------------------
有一个来自以用户为中心的设计领域的关键工具,它可以改变我们从根本上设计和构建 ML 系统的方式。
How do we keep users at the forefront of our ML systems?
ML 模型开发困难重重,充满挑战——不仅难以构建能够提供经过适当格式化、预处理、缩放和训练的大型数据集的数据管道,还存在*衡、偏差、训练外性能和整体模型性能的问题。
所有这些工作会导致我们只见树木不见森林。
我们应该问的更深、更基本的问题
开发正确的模型架构和数据管道,虽然华而不实,值得新闻报道,但只是过程的一部分。是的,积累一个大的数据集对于建立一个有效的 ML 模型是非常重要的,但是它又一次忽略了开发 ML 产品的一些更基本的挑战:
- 这种模型实际上解决了用户的需求吗,或者我们只是“用机器学习来解决问题”,希望会出现一些神奇而强大的东西?
- 这个模型是否正确地模拟了用户问题的输入?或者我们的系统中有没有其他我们没有考虑到的输入?
- 如果我们实现了机器学习系统,是否会出现我们没有考虑到的二阶效应?
在我的上一篇文章和我的 PyGotham 演讲中,我认为在问题域中建立模型的最佳方式是在整个开发生命周期中从根本上保持用户的中心地位。事实证明,在过去的几十年里,以用户为中心的设计领域一直倡导这种思想。
什么是以用户为中心的设计?什么是人物角色?
以用户为中心的研究的核心是人物角色,它们是真实用户的虚拟表现,为我们的开发工作提供信息。由程序员艾兰·库伯在80 年代开发,角色:
- 是团队根据真实客户创造的虚构角色
- 用名字、爱好和生活趣闻将它们带入生活
- 叙述他们的目标、恐惧和与产品相关的目标
当整个团队将角色内在化时,它有助于集中他们的工作。他们现在可以称呼用户的名字,考虑他们开发的每个产品功能或机器学习能力是否会影响他们的客户个人。
简而言之,人物角色激励我们的客户,并把他们放在我们做出的每个产品(和数据)决策的首位。
见见团队
想象一个场景在 AcmeWidgets.com 的工程团队中展开,我们的团队正在为电子商务零售商开发一个推荐系统,以在产品页面上显示相关商品。为了做到这一点,一个由 ML 工程师和数据科学家组成的技术娴熟的团队聚集起来构建这个系统。
团队首先为他们的模型定义一个目标函数。在这种情况下,团队决定选择一个使购物车价值最大化的函数(我们的目标函数)。例如,它可能会发现用户倾向于在我们的目录中购买一系列高价商品。
然而,事情很快就出了岔子。该团队注意到,他们的模型最终给出了低质量的推荐,牺牲了长期客户保持率来换取*均订单价值的短期提升。该团队发现,他们的模型最终会促使客户购买他们并不真正想要或需要的物品,从而降低客户对产品和业务的长期忠诚度。事实上,推荐引擎推荐的产品最终会以高得多的比率被退回,从而导致企业的运营支出和成本。
Photo by Christina @ wocintechchat.com on Unsplash
当然,这只是调整模型的问题!团队回到绘图板,这一次推出了一个模型,该模型改变了模型的目标函数,以最小化其产品的回报率。模型经过测试,瞧,系统又开始愉快地运行了。用户似乎对他们的购买很满意…
…直到三个月后,他们发现与这个推荐引擎交互的用户实际上比那些没有看到推荐的用户更频繁地离开产品!事实证明,这些推荐让用户如此不安和愤怒,以至于他们甚至懒得返回。
因此,团队回到了绘图板,沮丧并对他们在项目的下一次迭代中可能发现的其他东西有一种不祥的预感。
哪里出了问题?
Photo by Kelly Sikkema on Unsplash
如果我们回去和团队一起参加他们的项目回顾会,我们可能会听到这样的反映:
- 在我们的模型中,我们没有考虑全套的用户生命周期指标
- 我们考虑得不够全面
- 我们冲向市场,相信我们知道正确的前进方向
- 有些客户边缘案例我们没有考虑
当然,这些东西很多只能从经验中学习!但是,对于这个项目来说,还有更好的前进方式吗?
关键问题是团队只在战术层面思考。他们认为——“哦,推荐引擎应该很简单。我们将为我们的模型引入架构 X,针对目标 Y 进行训练,并在我们能够实现模型性能 Z 时交付它。
人物角色让我们站在客户的角度,因此我们可以发展专家的直觉
ML 从业者经常会告诉你,一个伟大的 ML 系统融合了领域专长和专家直觉。这意味着 ML 模型必须由团队成员设计,他们对业务领域有深刻的理解,对数据集有深刻的熟悉,对客户的需求有深刻的直觉。
你如何获得领域专业知识?嗯,你必须让合适的人加入到团队中,解决合适的问题,在模型开发过程中的所有环节考虑客户。用户角色是如何帮助我们避免这种情况的?
想象一下,在开始的时候,团队同意将他们的客户视为现实世界中活生生的人。事实上,他们的 UX 同事做了一系列客户访谈,得出了一系列客户综合草图:
办公室管理员卢克
Photo by Marius Ciocirlan on Unsplash
剖面图
卢克是一名 31 岁的男子,住在印第安纳波利斯,是一家小型物流公司的办公室管理员
动机
Luke 需要在办公室存放一些小工具,供员工使用。考虑到办公室的小配件经常缺货,他需要每隔几周就补充一些。他害怕不得不重新登录网站下订单,因为他觉得这很乏味。
目标
同一 SKU 的无缝、定期订单再履行
和谐,婚礼策划
Photo by Kim Carpenter on Unsplash
简介
27 岁的哈莫尼住在波士顿,经营着一家刚刚起步的活动策划公司。她喜欢在自己的活动中提供 Acme 小配件,因为它们受到客人的喜爱,并为她的企业提供了她需要的知名度。
动机
哈莫尼梦想在她的城市建立一个活动策划帝国
目标
独特、难找、令人向往的小配件,让她的生意脱颖而出
天齐,自由职业爸爸
Photo by JodyHongFilms on Unsplash
简介
田琦是一名生活在上海的远程自由职业者,他享受在家工作的灵活性,因为这让他可以在伴侣全职工作的同时为家人照看孩子。
动机
天齐希望在预算有限的情况下,过上有序、高效的家居生活
目标
以预算价格购买他想要的东西。
如何将人物角色整合到模型开发中
我们可能想要考虑人物角色的原因是,这样我们可以直接了解我们客户的目标和动机。Harmony 希望发现流行的独特商品。卢克只是想完成办公室的一个经常性订单。天齐想要最便宜的东西。
经常讨论它们
该团队在考虑其推荐算法时,应在开发其模型时主动提及 Harmony、Luke 和 Tianqi 的名字-
队友 1:如果我们选择使用协作过滤模型,我们必须考虑这样一个事实,即我们只有非常小的用户样本量符合 Luke 的用例(power fulfiller)。我担心在任何有意义的信号出现之前,Luke 的团队会看到许多垃圾推荐,并对我们的产品失去兴趣。
队友 2:是啊,的确如此。但我们知道,Harmony 的团队占我们销售额的 75%以上。这里有很多机会。如果我们用强盗的方法呢?这应该有望最大限度地减少出现在用户面前的不良推荐的数量。
队友 1:这主意不错。鉴于我们的经营规模,我们可以很快学会,我们可以尽量减少向卢克团队提供糟糕建议的时间。
或者考虑开发过程中的另一个场景,团队不得不在野外与推荐者进行负面互动:
队友 1:我们在 Twitter 上收到一些客户反馈,说我们的产品太贵了。显然,一些顾客觉得他们被骗了,购买了他们并不需要的东西——天齐一族。我们如何确定人们确实收到了有价值的推荐呢?
队友 2:为什么他们觉得自己的物品没有价值?
队友 1:由于某种原因,我们的推荐系统正在制造某种买家的遗憾。我们可能会过度宣传我们的一些促销活动,或者我们可能会推出一些有质量问题的产品。
队友 2:让我先和我们的 UX 设计师朱莉谈谈,看看是否有某种用户研究可以证实或验证这个假设。如果我们需要将某种功能重新整合到我们的模型中,以确保我们做出真正高质量的推荐,那么就让我们整合它吧。否则,如果我们的建议不符合标准,让我们测试一个新的模型变体,我们根本不会显示任何结果。
队友 2:知道了。
看到了吗?我们希望将这种以客户为中心的全面对话融入团队的自然工作方式中。所有这些都是通过客户角色实现的。
让他们看得见,摸得着
我在创业公司工作的时候,我们经常把客户角色打印出来,贴在墙上给团队看。当团队看到活生生的顾客时,他们会想起他们是在为谁解决问题。如果团队陷入了只讨论特征工程问题、精确召回曲线和准确性指标的深层技术细节的陷阱,在房间里提醒您的客户将有助于将 ML 产品与您正在解决的实际客户问题联系起来。
最后
Photo by Philipe Cavalcante on Unsplash
人物角色是强大的——但他们不是银弹。人物角色帮助我们做的是把我们的客户想象成真实的人,有真实的目标、动机和挫折。当我们定义我们的客户时,我们给自己一个词汇,将他们作为一等公民来讨论,然后围绕他们确定我们的技术解决方案。
哦——顺便说一下,谷歌的人与人工智能研究(PAIR)团队对设计以人为中心的人工智能产品的过程进行了更多的思考。通读他们的最佳实践指南,从他们构建 ML 产品的丰富经验中学习。
你怎么看?你有以客户为中心构建 ML 模型的经验吗?伸出手让我在 Twitter 上知道在 @andrewhao 。
参考
- 谷歌—人+人工智能研究 —谷歌设计
- *距离观察人物角色 —粉碎杂志
- 人物的起源 —艾兰·库伯
- PyGotham 2019:神经网络能让我成为更好的父母吗? —安德鲁·郝
原载于。
集成 Python 和 Tableau
原文:https://towardsdatascience.com/integrating-python-tableau-5511dd7102e9?source=collection_archive---------5-----------------------
通过引人入胜的数据可视化,让您的分析栩栩如生。
当对大型和非结构化数据集执行深入分析时,Python 和相关机器学习库的威力怎么强调都不为过。Matplotlib 是帮助我们可视化结果的一个很好的工具,但是它的风格化选项并不总是最适合用于演示和仪表板。当然,你可以让它工作,但是像 Tableau 这样的可视化软件更适合帮助你讲述你的故事。
为了说明这一点,考虑一个来自金县住房数据集的简单例子。在探索性分析中,您可能会发现位置是价格的重要预测因素,但您想知道是使用邮政编码还是 GPS 坐标作为预测因素。通过创建一个带有经纬度坐标的散点图,创建一个基于价格的彩色地图,我们可以了解哪里的价格最高。
ax = housing_data.plot.scatter('long', 'lat',
c = 'log_price',
s = housing_data['log_price'],
colormap = 'magma',
figsize=(15, 10),
title='Location-Price Map')
ax.set(xlabel='Longitude', ylabel='Latitude')
plt.show()
基于此,我们得到一种感觉,即经纬度与价格之间的关系有点像抛物线,从这里,你可以决定如何继续分析。然而,如果你想让高级经理更清楚地知道哪里的价格最高,这种可视化效果并不理想。使用 Tableau,我们可以创建这样的东西:
可以用 Python 中的库创建这样的东西吗?我想是这样的,但是专用于数据可视化的软件可以帮助你以更高的效率获得这些结果。更重要的是,这个软件使得比较不同的风格变得更加容易。请看下面的信息图,它展示了 1999 年至 2016 年美国心脏病死亡率的变化。
此图表结合了 Tableau 的可视化效果和 PowerPoint 中的动画选项。我们如何利用 Tableau 的可视化能力和 Python 的分析能力?我会给你三个选择,并强调每个选择的利弊。在这篇文章的末尾可以找到实现的相关文档的链接。
泰比
任何想要结合这些工具的人都可能很快找到标签选项。Tableau 本身开发了 TabPy,并允许您在 Tableau 的计算列中运行 Python 脚本。部署机器学习模块后,您可以将调用函数合并到计算变量列中。
作为一个用例,考虑一个基于位置和其他因素预测房价的机器学习模型。一个住宅开发商可能试图决定在哪里建立一个新的社区,他们想知道在哪里可以得到最好的价格给定的一般特点的家居设计。业务分析师只需输入设计细节和潜在位置,Tableau 将立即提供相关地图和价格预测。
此外,TabPy 还支持高级特性,比如身份验证管理和代码发布。然而,伴随这些特性而来的是额外的复杂性:安装并不总是容易的,对遗留 Python 代码的支持使其运行繁重,并且脚本实现并不总是干净的。但最重要的是,TabPy 依赖于使用 Tableau 服务器,这是一种付费服务。换句话说,这不适用于 Tableau Public,Tableau 的免费版本。基于这些原因,AltTabPy 应运而生。
AltTabPy
AltTabPy 的主要目标是简化和精简 TabPy 的关键功能。就大小而言,AltTabPy 只有 TabPy 的 5%,这使得它的效率令人难以置信。安装可以通过一个简单的 pip 命令完成。并且将代码合并到 Tableau 计算列中要干净得多。
但是,它不提供 TabPy 的高级功能。考虑到这一点,AltTabPy 对于资源有限、没有遗留代码负担的公司或个人来说是一个极好的选择。价值主张实际上与 TabPy 相同,但针对的是不同的用户。最重要的是,不需要 Tableau 服务器。
CSV 共享
尽管功能有限,但 CSV 共享是将数据从 Python 发送到 Tableau 的最简单方式。该选项非常适合于显示历史数据,而不需要即时预测新数据。它也适用于不需要对新数据进行即时预测的单一分析。
这里的方法非常简单,只需对相关数据运行机器或深度学习模型,并将结果数据帧保存到 CSV。
df.to_csv('filename.csv')
从这里,Tableau 可以从主屏幕上的连接菜单连接到相关文件,并选择文本文件。从可持续发展的角度来看,数据科学家应该设计代码,以便在新的数据预测可用时更新 CSV 文件。通过刷新 Tableau 中的连接,可以将新数据合并到相关的可视化中。
如果数据科学家被授予写 SQL 服务器的权限,这种策略也可以适用于 SQL。
这里最大的缺点是使用 Tableau 的业务分析师不能添加新数据来预测结果。相反,他们将不得不依靠其他团队来生成预测结果,然后才能将其纳入可视化。
结论
TabPy 是一个端到端的解决方案,允许在团队设置中真正集成 Python 和 Tableau。然而,它带来了更多的复杂性和更高的成本。
AltTabPy 提供了更大的简单性,并且不需要对 Tableau 服务器进行投资。对于使用新版本 Python 并且不需要遗留支持的初创公司来说,这是一个很好的选择。
CSV 共享非常适合不需要共享数据的个人和不需要快速部署机器学习模型的公司。
来源
TabPy 和 AltTabPy 的官方文档可以在下面找到:
- PyTab
- 替代
使用深度学习对单细胞多组学数据进行综合分析(带视频教程)
原文:https://towardsdatascience.com/integrative-analysis-of-single-cell-multi-omics-data-using-deep-learning-66a61a3448c5?source=collection_archive---------16-----------------------
视频教程#1:
Tutorial on Saturn Cloud
视频教程#2:
单细胞 RNA 测序(scRNA-seq)提供了一种全面、公正的方法,利用下一代测序技术,以单细胞分辨率分析包括 T 细胞在内的免疫细胞。最*,通过测序( CITE-seq )对转录组和表位进行细胞索引等令人兴奋的技术已经被开发出来,通过联合测量多个分子模式(如来自同一细胞的蛋白质组和转录组)来扩展 scRNA-seq。通过利用与寡核苷酸结合的抗体,CITE-seq 同时产生基于测序的表面蛋白表达和基因表达的读数。
由于基因和蛋白质表达传达了关于细胞的独特和互补的信息,CITE-seq 提供了一个独特的机会,将转录组和蛋白质组数据结合起来,以比单独使用其中一种高得多的分辨率破译单个细胞的生物学。这需要能够有效整合来自两种模态的单细胞数据的计算方法。在这篇文章中,我们将使用无监督的深度学习,更具体地说,autoencoder,对 CITE-seq 数据进行综合分析。
数据
我们将使用 2017 年由 Stoeckius M 等人 发表的首个 CITE-seq 数据集。作者测量了大约 8000 个脐带血单核细胞(CBMCs)的单细胞转录组以及 13 种蛋白质的表达。有两个 CSV 文件——一个用于基因表达,另一个用于蛋白质表达,可以从这里下载。 Seurat 是一个 R 包,设计用于单细胞基因组数据的质量控制、分析和探索。在将数据输入到我们的自动编码器之前,我们将首先对数据进行预处理,并使用 Seurat 软件包基于基因表达进行细胞聚类和注释。代码可在本随附笔记本中找到。
预处理后,基因和蛋白质表达数据被连接在一起,其中每一列是基因或蛋白质,而每一行是细胞(每个细胞都有一个唯一的条形码)。该数据集包含总共 7895 个细胞的 2000 个基因和 10 种蛋白质的表达水*(3 种由于富集差而被去除)。
Concatenated gene and protein expression data
自动编码器
Autoencoder 是一种无监督的深度学习模型或神经网络,由三个主要组件组成:编码器、瓶颈和解码器,如下图所示。编码器压缩输入,瓶颈层存储输入的压缩表示。相反,解码器试图根据压缩数据重建输入。
Image source: https://medium.com/@curiousily/credit-card-fraud-detection-using-autoencoders-in-keras-tensorflow-for-hackers-part-vii-20e0c85301bd
瓶颈层的尺寸通常大大低于输入的尺寸。因此,编码器将尝试了解尽可能多的关于输入的有意义的信息,同时忽略噪声,以便解码器可以更好地重建输入。Autoencoder 可以用作降维算法,存储在瓶颈层中的输入的低维表示可以用于数据可视化和其他目的。此外,由于其灵活的神经网络架构,它提供了无限的方法来将基因和蛋白质表达数据整合到 autoencoder 中,正如我们将在下面看到的。
履行
由于基因和蛋白质数据具有显著不同的维度,我们将首先使用两个不同的编码器分别对它们进行编码,然后将输出连接起来,这些输出将通过另一个编码器来生成瓶颈层。随后,解码器将尝试基于瓶颈层重建输入。总体神经网络架构如下所示:
Autoencoder architecture
使用 Pytorch 和 fastai 库,自动编码器的实现非常简单。在这个例子中,压缩的基因和蛋白质数据的维数分别是 120 和 8,瓶颈层由 64 个神经元组成。完整的代码可以在这个(仅限基因)和这个(基因和蛋白质)的随机笔记本中找到。
Autoencoder implementation
结果
除了根据基因和蛋白质表达数据训练的模型之外,我们还仅使用基因表达数据训练对照模型。通过这种方式,我们将能够辨别对 CITE-seq 数据进行整合分析的任何优势。在训练模型后,我们提取存储在瓶颈层的原始输入的 64 维压缩表示,随后在由 t-SNE 生成的二维地图上可视化。
如下图所示,转录组和蛋白质组数据的综合分析产生了比单独使用基因表达数据更好的结果。例如,当仅使用基因表达数据时,CD8 T 细胞(红色箭头)和 CD4 T 细胞簇一起形成了一个大的“岛”,并且不能被分开。相比之下,当将蛋白质表达数据与基因表达数据结合时,CD8 T 细胞(红色箭头)形成与 CD4 T 细胞群完全分离的独特群。因此,组合分析在分析 CITE-seq 数据时比使用单一分子模式的数据更有效。
Visualization based on gene expression data only. The red arrow points at CD8 T cells.
Visualization based on both gene and protein expression data only. The red arrow points at CD8 T cells.
总结和未来方向
在这里,我们建立了一个基于自动编码器的深度学习模型,用于单细胞 CITE-seq 数据的降维和可视化。我们证明转录组和蛋白质组数据的综合分析在区分各种免疫细胞类型方面获得了更高的分辨率。
一个限制是在预处理步骤中仅使用基因表达数据将细胞分配给不同的免疫细胞类型。开发一个深度学习模型将是非常有趣的,该模型还可以使用来自多个分子模态的数据来执行细胞聚类和表征。
源代码
数据:
https://www . Dropbox . com/sh/opxrude 3s 994 lk 8/aaaiwrzfviksxkpyomlwqhea?dl=0
朱庇特笔记本:
【https://github.com/naity/citeseq_autoencoder】T4
我是一名具有生物信息学和编程技能的免疫学家。我对数据分析、机器学习和深度学习感兴趣。
网址: www.ytian.me
博客:https://medium.com/@yuan_tian
领英:https://www.linkedin.com/in/ytianimmune/
推特:https://twitter.com/ytian
真空中的智能
原文:https://towardsdatascience.com/intelligence-in-a-vacuum-54db3ec2a56b?source=collection_archive---------30-----------------------
在写我上一篇关于智能的文章时,我开始思考智能是否可以脱离环境而存在。 Headcanon alert : 我真的没有答案。
想象一个真空中的代理。真空不是严格的物理定义,只是一种环境,在这种环境中,代理不接收任何输入,其输出对周围环境没有影响。它可以是飞得有点远的宇航员鲍勃,或者是 iPhone,或者只是一块石头。
还有一些问题:
- 在这种情况下,斯通和鲍勃一样聪明(甚至更聪明)吗?
- 在这个抽象的例子中,任何智力测量都有意义吗?
- 智能可以被定义为某种与环境无关的内部机制吗?
我相信石头确实可以更“聪明”,因为它甚至不会试图在不会改变任何事情的行动上浪费精力。由于那些代理人没有能源来复制或生长,自我保存似乎是唯一“明智”的事情,而斯通有最大的机会成功。
另一方面,iPhone 可以使用天线在任意长的距离上发送信号,即使它们不会为这个特定的设备改变什么,但它可能对它的“亲戚”有所意义。
埃隆的 Roadster 怎么样?还是外星人?在一个封闭的系统中,有什么行为可以被认为是智能的吗?不知道是否有人认真研究过这些抽象的例子,但如果你想做这些工作,请联系我:)
雪花中的智能计算
原文:https://towardsdatascience.com/intelligent-computing-in-snowflake-2be96ac11049?source=collection_archive---------11-----------------------
再过一周多一点,我将前往旧金山参加 Snowflake 的首届用户峰会,在那里我将就澳大利亚私人健康保险行业的数据共享发表演讲。
我不仅为会议感到兴奋,而且当我在那里的时候,我也真的很兴奋能去 Numenta 的办公室参加 meetup 活动。
雪花已经建立了下一代数据仓库,Numenta 正在建立我认为是下一代机器学习算法,所以这将是一个重要的一周!
自从大约 15 年前我在大学第一次研究机器学习以来,我对它一直有着浓厚的兴趣。那是在上一个人工智能冬天的中期,所以我对这门课没有太多期望,因为没有人真正谈论它。但它很吸引人,富有哲学挑战性,给我留下了持久的印象。
在我目前的工作中,我开始从事涉及当代机器学习的数据分析过程。但是意识到它的一些局限性,并且永远对人类智力的工作方式感到好奇,我一直密切关注 Numenta 的研究,并且多年来一直是他们的社区的一员。
因此,为了让我对即将到来的旅行感到兴奋,这篇文章是我结合两种技术的一个实验;在雪花上运行 Numenta 当前的数据库内智能计算算法,并使用它来检测数据序列中的异常。
AI 不是已经智能了吗?
简单来说,机器学习算法(包括深度学习)允许我们通过使用历史数据来训练一个模型,从而进行预测。作为学习算法,这种想法是,如果一些信息对一个结果具有预测能力,并且你有很多例子,那么你不必指定一个精确的公式来进行预测。相反,你可以用蛮力和一些巧妙的捷径来*似它。
credit: https://visualstudiomagazine.com
在某些情况下(比如我之前的 Medium 故事中的基于树的学习),你会得到一个可解释的预测,而使用神经网络它可能更像是一个黑箱。但在这两种情况下,你通常都在寻求最小化特定预测任务的误差,这样你就可以自动将其应用于新数据。
这篇文章的目的绝不是贬低这些机器学习方法的强大。它们被全世界最大的公司和最聪明的人用来解决实际问题。给定足够的样本数据,他们可以对图像进行分类,将语音转换为文本,或者预测能源消耗。使用规则而不是数据,他们可以学习赢得像围棋这样的游戏,或者在雅达利游戏中取得成功(没有享受部分)。
不仅如此,即使在我们破解了哺乳动物智能的难题之后,这些传统方法对于某些类型的分析仍然至关重要,在这些分析中,我们实际上并不需要类似人类的推理。
但是,尽管它们打着人工智能的旗号,甚至被称为“神经”网络,但重要的是要认识到,它们的工作方式与人类和其他动物的智能工作方式非常不同。相比之下,人类大脑使用未标记数据的时间流不断预测和学习,并且使用单一的通用算法非常有效。
credit: http://dmangus.blogspot.com
我们的大脑也非常擅长保持“不变”的表示和关系的层次,所以我们可以很容易地从一个不熟悉的角度识别一只狗,并直观地理解它更像一只猫,而不是一条鱼。这就是为什么我们的婴儿在图像识别方面轻而易举地超过了最好的深度学习算法,这是实现完全自动驾驶道路车辆比最初预期的要远得多的核心。
Numenta AI 方法有何不同?
Numenta 采取了一种“生物约束”的方法,并正在开发一种被称为分层时间记忆(HTM)的理论,这意味着他们不会将任何人脑不会做的事情纳入他们的算法中(根据神经科学研究告诉我们的)。
Numenta 的任务是了解智能如何在大脑中工作,以便他们可以在软件中实现它,并建立智能系统。从行业的角度来看,他们仍然处于边缘,但他们的研究正在进步,并且总是令人着迷,尤其是对任何对计算机科学和神经科学有双重兴趣的人来说。例如,最*有很多关于网格细胞结构的关注,一个古老的导航机制如何适应高等教育。我希望 6 月 meetup 活动上的研究更新会围绕丘脑的作用,以及他们如何将注意力的作用纳入他们的理论。
我们的大脑包含现有的最好的通用学习算法。因此,尽管前方仍有许多发现,但该理论吸引我的是,随着它的成型,它的学习将不会像当前的 ML 那样受到限制——我们可以用它来构建的可能性确实是巨大的。
你可以通过观看 Youtube 上的 HTM 学校来开始了解 HTM,它会带你了解基础知识。或者,如果你是一个爱读书的人,你不能错过《智力的 T2》,这本书由 Numenta 的联合创始人杰夫·霍金斯所著,最初概述了 HTM 的基础。
它能做什么?
除了保持研究本身的开放性,Numenta 还有一个名为 nupic 的开源项目,实现了 HTM 理论中描述的学习算法。它主要是一个研究工具,它还不像一个完全正常工作的大脑。如果是这样的话,我相信这项技术已经在几乎所有的系统中使用了!
它已经被各种社区成员移植到其他语言中,有些人甚至用自己的一些想法进行了修改。
除了开源项目,还有一些商业应用正在出现。例如皮质。IO 正在将 HTM 专门应用于自然语言理解。
无论如何,要回答这个问题,它目前能做得很好的是学习序列而不需要太多的刚性,并预测下一个值。这又可以用于检测具有一定噪声容限的数据序列中的异常。
雪花实现
我将在雪花中进行一个非常基础的学习练习,使用简单的数字序列。
为此,我们需要构建几个组件,但在进入细节之前,我想先展示一个快照:
- 我们在雪花中构建的内容(右侧)
- 其中每个部分都符合 HTM 理论(中间),并且
- 这在生物学上是对应的(在左边)。
让我们从上到下努力吧。
编码器
编码器是我们的数据通过的第一个地方。
它们是初始大脑输入的一种快捷抽象,就像视觉皮层或听觉皮层一样。原始输入被映射成具有一些重要属性的稀疏表示,在本文中有更详细的描述。有趣的事实:你的大脑皮层没有视觉、听觉和嗅觉的概念,也不关心信号来自你的哪个感官。它只是使用单一的通用机制进行学习和预测,编码器是通向它的门户。
我将使用一个 javascript UDF 为雪花构建一个标量编码器。输入将是一个单一的数字,输出将是一个位的数组,其中一些是活动的,而大多数不是。
通过借用一些 Numenta 的 javascript 代码并做一些修改,我为自己节省了一些时间:
编码器的特性之一(来自上述论文)是:
相同的输入应该总是产生相同的 SDR 作为输出。
这意味着我们可以在雪花 UDF 上设置“不可变”属性,并从缓存中受益匪浅。
用值 1 到 5 来演示:
select 1 as value, SCALAR_ENCODER(1,1024,0,250,14,false) as ENCODED_VALUE
union all
select 2 as value, SCALAR_ENCODER(2,1024,0,250,14,false) as ENCODED_VALUE
union all
select 3 as value, SCALAR_ENCODER(3,1024,0,250,14,false) as ENCODED_VALUE
union all
select 4 as value, SCALAR_ENCODER(4,1024,0,250,14,false) as ENCODED_VALUE
union all
select 5 as value, SCALAR_ENCODER(5,1024,0,250,14,false) as ENCODED_VALUE
编码器输出 1024 位宽的稀疏数组,输入值范围为 0–250,宽度为 14。
如您所见,数字越接*,比特重叠越多。我们这样做是因为我们认为它们“语义相似”。
我们正在有效地构建类似于耳蜗毛细胞的东西,其中每一个输出位都可以活跃在许多类似的输入中。
credit: Numenta
空间池
A Sparse Distributed Representation (credit: Numenta)
在计算机中,我们密集地编码信息,但在我们的大脑中,它非常稀疏,这不是存储有效的,但产生了其他重要的属性,如噪声耐受性。这些被称为稀疏分布式表示(SDRs)。
因此,空间池的作用是将编码输入作为 SDR 之一投射到迷你列中。微柱是一束束垂直排列的神经元群,它们接收共同的输入并相互连接。
顺序记忆
大脑基本上是一个记忆系统,根据过去的序列不断预测未来的状态,并相应地加强/削弱突触。这就是 Hebbian learning,我记得是“一起火,一起线”。大脑只能在大约 20 瓦的功率下运行,因为它是连续有效的,它不像我们通常用计算机那样处理信息。
credit: brainworkshow.sparsey.com
随着信号在大脑的层次中向上移动,混沌的原始感觉输入最终成为稳定的概念(你可以在神经元放电模式中看到这一点),两个 SDR 之间的重叠量对应于语义相似性。
序列记忆(也称为时间记忆)的作用是使用远端连接(横向延伸到其他微柱)将微柱置于基于其对先前序列的识别的预测状态。
对于空间池和序列记忆,我将再次借用别人的代码。这次是 HTM.js ,一个由 Numenta 社区成员 Paul Lamb 构建的 javascript HTM 实现。同样,我所做的只是稍微修改它,使其在雪花上下文中工作。
在 HTM.js 中,所有不同的生物构造(细胞、列、层、突触等)都在不同的文件中被建模为它们自己的 javascript 原型。我将把它们全部放入另一个雪花 javascript 用户定义的表格函数(UDTF ),以及所有的学习和预测控制器逻辑。
最终版 UDTF 的源代码可以在这里找到(它太大了,无法在这里显示)。
有了这个函数,我们可以运行遍历表的列的查询,并一次性学习它找到的值的序列。HTM 网络的状态存在于 UDTF 执行者的记忆中,最初是随机的,但随着它学习到的每个新值而改变。这当然意味着我们故意不利用 UDTFs 通常具有的雪花引擎的并行性,因为处理顺序很重要。
所以我们来试试吧!我会尽可能用 Tableau 来保持这种视觉效果。
从一个数字从 10 到 20 的表开始,循环回到 10,无限期地继续下去。
我把这个表叫做 LOOPING_NUMBERS,列叫做 _NUMBER。
从视觉上看,顺序是:
让我们看看我们的 HTM·UDTF 能否学会这个序列。
但首先,HTM.js 实际上采用密集表示的稀疏数组。显然,它希望输入数组只保存 1 的索引位置,而不是一长串 0 和 1。这就是我添加 DENSE_OUTPUT 参数的原因,如果设置为 true,我的 1,2,3,4,5 序列将如下所示:
Look, they fit on the screen now!
好,那么使用我们的输入表 LOOPING_NUMBERS,我们首先通过标量编码器运行 _NUMBER 列,然后通过 HTM 网络。
select
THE_NUMBER,
SCALAR_ENCODER(THE_NUMBER,1024,0,250,20,true) as ENCODED_INPUT,
ACTIVE,
PREDICTIVE
from LOOPING_NUMBERS,
table(HTM(SCALAR_ENCODER(THE_NUMBER,1024,0,250,20,true)))
下面是我们得到的一个例子:
我将结果集向下滚动到预测开始的地方。你可能会想,这样解读有点难。活动列包含活动小列的索引,预测列是也处于预测状态的活动小列的索引。
为了更好地理解发生了什么,我们可以简单地使用预测的成功率来计算异常分数:
select THE_NUMBER,
SCALAR_ENCODER(THE_NUMBER),
ACTIVE,
PREDICTIVE,
ARRAY_SIZE(ACTIVE)-ARRAY_SIZE(PREDICTIVE) as NOT_PREDICTED_COUNT,
NOT_PREDICTED_COUNT/ARRAY_SIZE(ACTIVE) as ANOMALY_SCORE
from LOOPING_NUMBERS,
table(HTM(SPARSE_TO_DENSE(SCALAR_ENCODER(THE_NUMBER))));
现在我们有了一个异常分数,我们可以直观地看看 HTM 网络经历了什么:
有点像刚出生的婴儿,一开始什么都不懂,然后模式开始变得熟悉。
顶部偶尔留下的异常痕迹是怎么回事?这是由学习重复输入的方式造成的影响,在主要的 python nupic 代码库中有减轻它的方法,它们只是在 HTM.js 中不存在。所以请相信我,忽略它们:)
现在让我们扔一些曲线球,看看会发生什么。我们给它 10,11,13,13,而不是 10,11,12,13。
网络检测到几乎确定的异常。不完全是 100%的原因是因为在编码器输出中 12 和 13 之间有相当大的重叠,所以仍然预测了少量的活动列。
现在让我们用一个 10 的大序列来给它一个惊喜,因为那是非常不同的。
网络再次吐出它的咖啡,并在调整到新的序列之前短暂地困惑。
让我们再试一次,重复序列 10,12,14,16,18,20,19,17,15,13,11:
与之前类似,但调整期更长,因为新序列需要更长时间重复。
现在让我们做一些有趣的事情来结束,并回到最初的 10,11,12,13,14,15,16,17,18,19,20 的顺序。你可能会想,随着所有的变化,它已经被遗忘很久了。事实上,网络拥有巨大的存储容量,在识别它之前几乎不会漏过一个节拍:
摘要
我希望你读这本书的时候和我整理的时候一样开心。如果你和我一样,HTM 一开始会让人望而生畏,但如果你对智力的工作方式感兴趣,研究它会非常有价值。我开始将生物启发的学习算法视为我们建设更智能系统的道路上至关重要的一部分。
雪花作为一个云数据仓库给我留下了深刻的印象,似乎不可避免的是,我们将继续看到它得到扩展,变得越来越多才多艺。这是一个非常非传统的数据仓库任务的另一个例子,使用它的引擎很容易实现。
同样,如果您有兴趣了解更多信息,请访问 Numenta 社区,并且不要忘记介绍自己!。
智能数字机器人或 RPA 2.0
原文:https://towardsdatascience.com/intelligent-digital-robots-or-rpa-2-0-6487a1bdc54?source=collection_archive---------22-----------------------
我们生活在一个前所未有的技术飞速发展的时代。随着人工智能解决方案敲开每一扇门,是时候考虑它将如何影响我们工作的性质了。
1.机器人
18 世纪后期,西方世界经历了工业革命,从手工生产方式转变为机器生产方式。从那时起,随着我们在工作结构和整个社会中经历越来越快的变化,世界变得不一样了。许多传统的工作岗位消失了,但是更多的工作岗位出现了。
直到 20 世纪末,我们的文明采用了数字设备,这在 21 世纪初变得无处不在,我们才看到如此规模的革命。突然间,我们生活在未来,数字和物理机器人(例如,清洁 Roombas、自主 Teslas、波士顿动力机器人或工业手臂)与我们共存。
随着互联网的兴起,数字机器人在 90 年代已经出现。如今,在网络上抓取和发送垃圾信息的机器人很常见。更多面向商业的机器人是那些存在于机器人过程自动化系统(简称 RPA)中的机器人,这些机器人被编程为在办公室执行重复性任务——从复制数据到电子表格,到执行计算和通过电子邮件传递结果。你只是一个任务接一个任务地向他们展示你是如何做的,他们会无意识地一遍又一遍地重复。定制这些机器人需要时间,但如果你有几十个人每天重复做的单调乏味的工作,通常是值得花时间的。就像在工厂里用自动手臂代替人是值得的,这样整个工厂空间就更安全,而单调乏味的体力工作则委托给机器。
这第一波数字机器人相当于工厂中的机械手臂——它们没有任何“视觉”或“感知”,它们只能执行与编程相同的动作,而不会根据变化的条件进行调整,也没有任何创造力的迹象。
2.人工智能
自从计算机出现以来,人工智能就一直在争论,因为计算机慢慢取代人类的想法似乎很诱人。由于大肆宣传和过高的期望,人工智能作为一个计算机科学领域在 70 年代到 90 年代的大部分时间里经历了两个冬天(资金减少,负面新闻)
在 21 世纪的最后几年,情况发生了变化,当时机器学习算法在视觉相关任务中的表现优于经典解决方案。这是由计算能力和访问大型数据库(数字化内容)的增长引起的。机器学习本身是一种通过让算法根据输入数据进行自我调整来解决问题的方法。程序员不必编写所有必要的功能和特性。只需要将最初的架构放在适当的位置,让机器/计算机学习示例就足够了。
人工智能的崛起改变了一切——从我们购物的方式(主要是在线)到导航(谷歌地图),甚至是生活预期(每个过程都必须*稳愉快)。绘制草图并让机器解决其余问题的机器学习范式战胜了将每个功能和特征硬编码到结构中的经典程序主义范式。
3.RPA 2.0
随着人工智能的兴起,数字机器人终于可以对输入的数据进行“看到”和“推理”。他们不必盲从规则,而是可以临场发挥。数字机器人终于可以变得智能了。
从技术角度来看,机器学习——尤其是深度学习和强化学习——允许 RPA 系统具有很强的鲁棒性。你不必在办公室工作中手工编写重复性的任务。让机器在后台运行,分析你几个小时或几天的工作,并提出潜在的自动化解决方案,这就足够了。
无论这听起来多么接*人工通用智能,它仍然很遥远,这些智能数字机器人将很快在所有商业垂直领域(以及通用知识垂直领域)蓬勃发展,在这些领域,人们可以在高度受限的字典/本体上操作——例如税务解释、财务报告或法律协议。
我们目前正处于这场新革命的开端,这场革命将限制单调乏味的任务,让人们专注于真正有创造性的工作。这种变化将发生在起初自动化似乎遥不可及的工作中:顾问、银行家和律师。在未来的 5-10 年内,这些职业将会发生巨大的变化。它们将更多地是关于人类互动和共鸣,而不是数据处理。准备幻灯片、起草法律协议或审计等办公室任务将会消失。这将真正等同于工业革命,但这一次是在数字世界。而这只是 AI 未来能给我们的一小部分。
为改变做好准备!
P2P 贷款的智能贷款选择
原文:https://towardsdatascience.com/intelligent-loan-selection-for-peer-to-peer-lending-575dfa2573cb?source=collection_archive---------21-----------------------
在贷款选择中控制风险的同时使用神经网络对贷款俱乐部进行自动投资
介绍
在这篇文章中,我描述了如何训练一个神经网络来评估大众借贷*台 Lending Club 上提供的贷款。我还介绍了如何测试模型,如何调整贷款选择中的风险,以及如何使用 Lending Club 的 API 使用模型进行自动投资。
为了让您保持兴趣,下面是回溯测试结果的预览:
左边的图表显示了随机选择贷款的模拟投资组合的回报,这些贷款按照 Lending Club 指定的等级进行筛选。右边的图表显示了神经网络选择不同风险调整水*的贷款时的回报。
借贷俱乐部
lending Club(www.lendingclub.com)是一个允许任何人投资消费贷款的*台,每笔贷款只要 25 美元。贷款金额从 1000 美元到 40000 美元不等,期限为 36 或 60 个月。许多借款人借出贷款来巩固债务,但也有各种其他目的;比如:家装、医疗费用、商业贷款等。
Lending Club 主要通过向借款人收取 1%至 6%的贷款发起费来赚钱,但他们也会从支付给贷款人的任何款项中扣除 1%。这意味着 Lending Club 的主要动机是发放尽可能多的贷款,无论贷款质量如何,投资者在选择投资哪些贷款时必须小心谨慎。有一个基于可定制过滤器的自动投资选项,但是这种方法不太灵活。一些第三方公司收费提供更复杂的投资组合管理服务。
Lending Club 允许投资者开立正常的应税账户,以及延税退休账户。后者更可取,因为消费贷款是一种税收效率非常低的投资选择。原因是利息收入按所得税率征税(大多数人是 22%或 24%),而被冲销的贷款损失的本金通常只能用来抵消长期资本利得(大多数人的税率是 15%)。
史料
Lending Club 提供在该*台上发放的所有贷款的历史数据。这些数据包括申请贷款时已知的所有信息,还包括绩效数据,如贷款状态(当前、逾期、全额支付或注销)、偿还的本金金额、支付的利息金额、滞纳金和收回金额。
出于这个项目的目的,我考虑了 2007 年 6 月至 2015 年 12 月期间发放的贷款,筛选出尚未完全支付或冲销的贷款。考虑的贷款总数是 829000。以下是这些贷款的结果。
贷款列表
*台上当前列出的贷款数据可以用一个简单的 web API 以 JSON 格式检索。也可以使用 API 投资贷款。
太*洋时间早上 6 点、10 点、下午 2 点和 6 点,新贷款会在 Lending Club *台上列出。有许多投资者使用软件自动投资贷款非常快,只要他们变得可用。
为了感受一下最好的贷款获得资金的速度有多快,我设置了一个脚本,每 5 秒查询一次贷款列表,从列表时间后一秒开始。下图显示了贷款的融资水*。每张图表都是在同一天不同的上市时间记录的。
可以看到,一些贷款(可能是最好的贷款)在 5 到 20 秒后就获得了全部资金,而在 20 秒后,活动逐渐减少。
虽然 Lending Club 每月发放超过 50000 笔贷款,但在撰写本文时,*均只有 1200 笔贷款可用于人工投资或使用 API 进行投资。绝大多数贷款是提供给机构投资者或有自动投资设置的个人。目前还不清楚贷款是如何在这些群体之间分配的,分配是否是随机的。
数据清理
Lending Club 提供的贷款数据有点乱,需要大范围清理才能使用。例如,历史贷款数据中的就业时间长度具有这样的值:“1 年”、“3 年”或“10 年以上”,而当前列出的贷款中的相同字段仅具有月数。像这样的例子还有很多。此外,历史数据和列表数据的列名也不同。
除了清理之外,我还对数据做了一些调整,使其更适合:
- 我把最早的信用额度日期换算成了信用额度年龄。
- 我取了各种“months since”字段的倒数(例如 mths_since_last_major_derog,mths_since_recent_inq,…)。这将时间间隔转换成与这些事件的频率相关的东西。当事件从未发生时,它还允许使用合理的值 0。这由原始数据集中的空字段表示。
- 我通过基于期限、利率和贷款金额重新计算,修复了“分期付款”列中的一些值(包含一些贷款的无效数据)。
回溯测试
为了进行回溯测试,我实现了一个贷款和投资组合模拟器。投资组合由现金余额和贷款集合组成。模拟器以一个月的离散时间步长工作。每个月,对于投资组合中的每笔贷款,都会进行分期付款,从而增加投资组合的现金余额。一旦贷款全部还清(包括收回),它将从投资组合中删除。
Lending Club 没有提供关于确切付款日期和金额的数据。他们提供的是最后一次收到付款的日期以及收到的本金、利息、滞纳金和收回的总金额。对于模拟器,我必须做一些假设:
- 我假设本金、利息和滞纳金在贷款期限内按月等额支付(从发放贷款之日到收到最后一笔付款之日),但永远不会超过定期分期付款的金额。如果这不足以支付收到的全部金额,则认为剩余部分将在最后一期支付。这包括提前支付剩余余额的情况。
- 我假设在最后一次付款后 6 个月收到了收回款项。
- 我假设贷款在最后一次付款后 4 个月被注销。根据 Lending Club 的说法,这是典型的,但他们的数据中没有提供这种程度的细节。何时注销贷款实际上只与税务计算有关,因为它决定了该事件是被视为长期资本损失还是短期资本损失。
实际的回溯测试采用一个清理过的贷款数据表,其中有一个额外的“_score”列,包含评分算法的输出。分数可以来自神经网络或随机数发生器,以进行随机测试进行比较。然后,贷款数据按发放贷款的月份分组。
为了启动这个投资组合,在最初的 12 个月里,每个月会有 1000 美元加入到这个投资组合中。之后,只有贷款的收益可以用于再投资。每个月,可用的现金余额被投资到当月发放的贷款中,将最小金额 25 美元投资到尽可能多的贷款中。例如,如果在给定的一个月中有$1132 可用,那么 45 (=floor(1132/25))个最高得分的贷款每个被提供$25。
开始的时候,Lending Club 每月不会发放那么多贷款。在将数据集分成训练和测试数据之后,在测试数据集的前几个月中没有足够的贷款给算法选择。由于这个原因,模拟开始的时间要晚一些,此时每月可用的贷款是投资所需贷款的四倍。
一旦历史贷款表用尽,回溯测试通过每月提取任何现金余额来结束投资组合,直到所有贷款都被完全处理。在这一点上,投资组合的价值回到 0,投资组合的回报率可以计算出来。
模拟应纳税帐户时,投资组合的现金余额每月会因当月产生的纳税义务而减少。纳税义务是收到的利息、滞纳金和回收乘以所得税率,减去已冲销贷款的剩余本金乘以适用的长期或短期资本利得税率。后面部分中的所有模拟都使用这些税率:收入和短期资本利得为 24%,长期资本利得为 15%。
该模拟还计算默认利率,即每年冲销的本金的百分比。为了计算这一点,模拟跟踪了一个假设场景,其中没有违约,但违约贷款的剩余本金没有被冲销,而是像贷款提前还清一样进行分配。这种无违约情景和实际收益率之间的差额就是违约率。
投资组合的回报率
计算有多次存款和取款的投资组合的回报率并不简单。
我的方法基于一个事务列表,其中每个列表条目代表一个固定的时间段,比如一个月。边界条件是投资组合在交易列表前后的值为零。
示例[1000,1000,0,0,0,-300,-1000,-800]:
从一个空的投资组合开始,第一期和第二期前存 1000,第 6 期前取 300,第 7 期前取 1000,最后取 800,使投资组合余额回到 0。
本例的净收益为 100 英镑(取款总额比存款总额多 100 英镑)。这里的结果是每期的*均回报率为 0.00854 (0.854%)。如果期限是一个月,那么年化回报率是 10.74%。
该函数如下所示:
sim(list, ror)
用列表中的交易和每期收益率(ror)模拟投资组合。该函数返回列表覆盖的时间段后投资组合的值。如果 ror 参数等于投资组合的实际收益率,那么结果应该为零(基于边界条件)。如果 ror 参数高于实际收益率,则 sim 函数将返回一个正值。如果 ror 参数太低,情况正好相反。
root_scalar 函数搜索使sim(list, ror)
的结果为零的 ror 值。
贷款回报率
同样的方法可以用来计算单笔贷款的收益率。
示例[1000,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100]:
发行了一笔价值 1000 英镑的贷款,分 11 期偿还,每期 100 英镑。*均回报为每期 1.623%,如果期限为一个月,则年化 21.31%。
下图显示了 x 个月后违约的不同贷款的年化回报率。贷款有两种不同的期限(36 个月和 60 个月)和三种不同的利率(5%,10%,15%)。
例如,一笔为期 36 个月、利率为 10%的贷款在 24 次还款后违约,你的年回报率为-21%。不幸的是,这并不容易转化为整个投资组合的回报率。如果你要投资这笔贷款,如果你要立即将所有收益投资于具有完全相同资产的贷款,那么你的整个投资组合也将呈现-21%的年回报率。
构建和训练神经网络
对于神经网络,我使用了 Keras 和 Tensorflow 库,它们为您完成了几乎所有繁重的工作。Tensorflow 是后端,允许您构建可以映射到可用 CPU 和 GPU 资源的计算图。Keras 在此基础上增加了神经网络方面,如层定义、激活函数和训练算法。
更多数据预处理
在将贷款数据输入神经网络之前,还有一些处理工作要做。仍然有分类数据需要转换—例如,贷款目的(“债务合并”、“房屋修缮”、“商业”…),或者居住州(“CA”、“NY”…)。这些需要被转换成一次性编码:
如果类别只有几个成员,将它们合并到“其他”类别中有助于防止过度匹配。在上面的示例中,可以添加另一列“addr_state$OTHERS”来捕获贷款少于 1000 笔的所有州。
添加到“addr_state”列的前导下划线是我的约定,表示在将数据输入神经网络之前,应该删除该列。这同样适用于新贷款列表数据中不可用的列,因为它们与贷款的结果相关,而贷款的结果还不知道(loan_status,total_rec_int …)。
选择网络应该预测什么
这些是我评估过的选项:
- 二进制输出:全额支付与冲销。
- *滑输出:收到的付款总额占预期付款的比例。
也可以在二进制和*滑输出之间进行插值,如下面的代码所示。“*滑度”参数值 0 选择二进制输出,而值 1 选择*滑输出。
使用二进制输出丢弃了有价值的信息,因为神经网络不知道贷款何时违约。在期限结束前几个月发生违约,要比首次付款前违约好得多。与此同时,选择完全*滑的产出会让一笔即将到期的违约贷款看起来非常类似于一笔完全偿还的贷款,尽管这在概念上有很大的不同。
完全*滑的输出有一个直观的优点:它是线性的,可以对多个贷款的结果进行*均,以得出这些贷款组合的支付分数。例如,如果训练数据集中有三笔参数非常相似的贷款,并且结果分别为 1.0、1.0 和 0.7,则*均值为 0.9。这相当于投资所有三笔贷款的回报率。当神经网络看到这样的贷款时,它产生这个输出是有意义的。同样的贷款,当使用二元期权时,得分分别为 1.0,1.0 和 0.0,*均为 0.67。因此,使用二元期权的模型预计会更加规避风险。
更多关于控制风险厌恶和比较图表可以在控制风险部分找到。
此时,我们有了全数字的 x 和 y 数据,并且可以将数据从 pandas 数据帧转换为 Keras 框架所期望的 numpy 数组。在这一点上,存储列名的序列是很重要的,以便以后在将训练好的网络应用于贷款列表时,可以准备列表数据,以便列处于正确的顺序,并且分类数据的一次性编码等同于训练数据。
最后一步是缩放数据,使所有输入值的大小大致相同。我评估了几个选项:
- (最小值,最大值)-> (0,1)
- (最小值,最大值)-> (-1,1)
- (-sigma,*均值,+sigma) -> (-1,0,1)
最后一个选项产生的结果明显好于前两个。同样,保存每一列的缩放参数很重要,这样可以将相同的缩放应用于列表数据。
定义网络
网络的确切结构似乎并不重要。我对随机结构进行了一些测试,除非它们非常退化,否则它们会产生类似的结果。
输入层从贷款数据中提取大约 160 列(居住州的一次性编码产生许多列)。
输出层由具有线性激活函数的单个神经元组成。
受“通过混合激活函数进化简约网络”(Hagg、Mensing 和 Asteroth)的启发,我使用了具有混合激活函数的层,但在训练期间没有任何进化:
为了减少过度拟合,我发现高斯噪声层是最有效的。添加辍学层也可以帮助,但我没有成功的正则化。
仍然有一些过度拟合,但是在回溯测试中,与测试数据相比,当使用训练数据时,回报率仅高大约一个百分点。
解释输出
神经网络的输出可以解释为我们可以预期收到的总付款(分期付款乘以月期限)的一部分。例如,一笔分期付款为 500 美元、期限为 36 个月的贷款的总支出为 18,000 美元。如果该贷款的模型输出为 0.9,这意味着模型预计支付额为 0.9 * 18,000 美元= 16,200 美元。
为了给贷款打分,我们真正想知道的是三年后的预期支出占初始本金的比例:
分数= y * (1.0+(int_rate/12)) ⁶,其中 y 是模型的原始输出
请注意,该公式中的月数固定为 36,即使是 60 个月的贷款也是如此,以便进行比较。因此,即使是 60 个月的贷款,分数也相当于 36 个月的预期回报。
结果
这是引言中的图表,比较了不同投资策略下投资组合的收益。
左边的图表显示了投资组合的回报率,其中贷款是按等级过滤的,但在其他方面是随机选取的。该等级由 Lending Club 指定,与违约概率相对应,并决定借款人必须支付的利率。人们可以看到,违约率(每年冲销的未偿还本金的百分比)随着等级的提高而降低。
右边的图表显示了使用上述模型对贷款进行评分并做出投资决策的投资组合的回报率。对模型的输出进行后处理以调整风险。这在下一节“控制风险”中有更详细的描述。
控制风险
当使用模型进行投资决策时,需要调整贷款选择,以实现低违约率,同时保持高投资回报。可以在两个地方调整选择算法的风险级别:在训练模型时,或者作为使用模型输出时的后处理步骤。后者更实用,因为可以更快地做出改变,而不必训练新的模型,并且相同的模型可以用于不同的策略。
通过后处理进行风险调整
默认情况下,贷款的得分是根据以下公式从模型的预测(y)中计算出来的:
得分= y * (1.0+(int_rate/12)) ⁶
这是前面图表中风险调整参数为 0.0 的点。
在极端情况下,参数为-1.0(代表最高风险),根本不使用模型的预测,只有利率进入得分:
分数= 1.0 * (1.0+(int_rate/12)) ⁶
它只选择利率最高的贷款。
另一方面,当参数为+1.0(代表最低风险)时,仅使用模型的预测,而不对利率进行任何调整:
得分= y
这旨在将违约率降至最低。
在默认公式中使用 y 之前,可以通过调整 y 在这些情况之间进行插值:
得分= risk_adjust(y,adj) * (1.0+(int_rate/12)) ⁶
具有不同参数的风险调整函数如左图所示。调整函数的关键属性是它改变点(1,1)附*曲线的斜率。该函数在 adj=-0.5 时取 y 的*方根,在 adj=0.0 时不改变 y,在 adj=0.5 时将 y 提升到 2 的幂。
在任何情况下,该函数将 y 提升到 adj 确定的某个幂,并对拐点情况进行特殊处理:
当 adj 低于零时,通过减少与良好贷款预测相比的相对差异,对不良贷款的预测进行调整,以使它们看起来更好。当 adj 高于零时,对不良贷款的预测会进行调整,通过增加相对差异使它们看起来更糟。
右图显示了三种不同贷款(L1、L2 和 L3)在三种不同风险调整(a、b 和 c)下的得分。蓝色条代表调整后的预测(risk_adjust(y,adj)),而蓝色和橙色条的组合代表最终得分。橙色条显示利率对最终得分的影响。
在中间(L1b、L2b 和 L3b ),没有风险调整,在本例中选择贷款的预测和利率,使得最终得分相同。我们可以看到,贷款 L1 收到最低的预测(违约概率最高),但它有最高的利率来弥补差额。贷款 L3 具有最高的预测值(最低的违约概率),但它也具有较低的利率,因此最终得分与其他贷款相同。
在左侧(L1a、L2a 和 L3a),应用了-0.5 的风险调整,这将原始预测提高到更接* 1,从而减小它们之间的相对差异。现在,利率最高的贷款 L1 战胜了其他贷款,尽管它的预期风险更高。
在右边(L1c、L2c 和 L3c),应用了+0.5 的风险调整,这使原始预测更接* 0,增加了它们之间的相对差异。现在,被认为更安全的贷款 L3 战胜了其他贷款,尽管它的利率更低。
我选择这个特殊的函数进行风险调整是因为这些特性:
- 它将 0 到 1 的输入范围转换为 0 到 1 的输出范围。
- 它以一致的方式缩放相对差异:y1/y2 = y3/y4<=>f(y1)/f(y2)= f(y3)/f(y4)
- 它在调整范围的末端收敛到有意义的极值:
- 在 adj=-1.0 时,它收敛到一条穿过点(1,1)的水*线,这意味着将任何预测调整为 1,这意味着只有利率用于评分。
- 在 adj=+1.0 时,它收敛到穿过点(1,1)的垂直线,增加了相对差异,使得无论利率如何,它都不能克服调整后预测中的差异。这意味着利率是不重要的,只有预测被用来获得分数,导致贷款的选择只基于违约概率。
通过培训进行风险调整
在训练模型时,有各种方法来控制贷款选择中的风险:
- 模型输出的目标值可以调整。可以对训练数据使用类似于上述的风险调整,或者可以改变先前讨论的*滑度参数。
- 样本的权重可以调整,这样拖欠的贷款就有更高的权重,或者权重可以是产值的函数。
这些方法控制内置于模型中的内在风险。同时,可以使用通过后处理的风险调整方法:
左边的数字来自一个本质上选择低风险投资的模型。它的*滑度参数为 0.5,并通过一个与全额支付贷款与冲销贷款之比成比例的因子来提高冲销贷款的权重。
右边的数字来自一个本质上挑选风险更高的投资的模型。它用*滑度参数 1.0 和所有样本的相同权重来训练。
参考模型(来自上面结果部分的图)的训练*滑度为 1.0,并增加了冲销贷款的权重。
在这些例子中,回报率接* 11%的*稳期比参考模型小。似乎最好用内在风险偏差来训练模型,使得*台的宽度最大化,并且在后处理期间仅需要有限的风险调整。
违约率变化时的绩效
只有在经济条件稳定的情况下,训练和配置模型和选择算法以最大化回报率(由回溯测试确定)才是有效的方法。观察模型在影响违约率的不同条件下的表现也很有趣。
上图显示了不同违约率下的假设收益率。蓝线显示假设没有违约(0%)时的回报,绿线是违约率没有变化(100%)的参考,紫线显示假设违约率翻了一番(200%)时的回报。
贷款有限选择的效果
正如我前面提到的,Lending Club 只为基于 API 的投资提供一小部分贷款。如果贷款的选择有限,为了投资可用的现金余额,必须选择更大比例的贷款。为了说明这种效果,我进行了模拟,每月随机选择一个贷款子集,算法可以从中进行选择。
正如预期的那样,随着可供选择的贷款减少,投资组合的回报率下降,因此选择的贷款比例增加。还可以清楚地看到,由评分算法分配的所选贷款的*均分数与回报率非常相关。
回顾回溯测试
在这个模型被用于实际贷款投资之前,还有一个障碍需要克服,那就是需要额外的测试。在我之前讨论的回溯测试中,该算法可以访问给定月份列出的所有贷款,并能够从中选择最佳贷款,直到不再有现金余额。
在现实生活中,我们不可能等那么久。贷款是小批量上市的,每天四次,必须实时做出决定,以避免其他投资者抢走最好的贷款。
我们从每批贷款中挑选出最佳贷款直到现金余额耗尽的策略并不是最优的,因为一些批次可能有高比例的良好贷款,而其他批次可能只有不良贷款。一个更好的策略是将一定的现金余额设定为大于零,以便保留一笔储备,在几笔贷款同时上市的情况下购买优质贷款。同时,现金余额不应过高,以避免损失回报(Lending Club 不对现金余额支付利息)。
如前所述,该模型为每笔贷款分配一个分数,该分数大致代表预期的总回报。现在的目标是找到这个分数的阈值,它可以用来决定是否投资贷款,同时保持合理的现金余额。换句话说,我需要实现一个控制循环,根据可用现金余额来调节选择阈值。
我的方法是基于 PI(比例积分)控制器。下图显示了一个控制器的现金余额和选择阈值,该控制器被设置为将现金余额保持在$200 左右。
以下是相关代码:
控制器对参数的变化相对不敏感。我对它们进行了调整,使选择阈值相对*滑,并保持现金余额不会偏离太多。只有积分项的控制器也是可能的,但是它会导致现金余额更大的波动。
投资组合模拟器现在将某个月发放的贷款列表分成 120 个随机批次(30 天内每天 4 个),每个批次中的贷款数量大致相等,但随机。同时,当月收到的付款被*均分成 120 份。然后,模拟器为每个批次运行控制回路和选择算法。
使用这种控制器的模拟投资组合产生的回报与使用早期方法模拟的投资组合的回报没有区别,早期方法可以获得在一个月内发放的所有贷款。
自动投资
要设置自动投资,有必要在列出新贷款时每天运行四次脚本。任务或 cron 作业在列表时间前几分钟启动脚本。
该脚本执行以下操作:
- 加载模型和 PI 控制器的状态。
- 确定下一批贷款上市的确切时间。
- 如果需要,在下一次列表时间前几秒钟睡眠。
- 查询当前现金余额,以确定投资贷款的最大数量。
- 将现金余额输入 PI 控制器,以计算新的选择阈值。
- 一直睡到准确的列表时间,或者一秒钟后考虑到时钟的差异。
- 检索贷款列表。
- 通过模型和评分算法运行列表,并根据分数对它们进行排序。
- 编制一份分数高于阈值的贷款清单。如果现金余额太低,无法投资所有这些贷款,那么就尽可能多地拿最高分。
- 订购这些贷款。
- 保存 PI 控制器的状态信息供下次使用。
还要避免多次投资同一笔贷款。当从 Lending Club 查询列表时,有一个选项只包括在最*的列表时间列出的贷款。只要脚本获得正确的时间,相同的贷款列表不会被检索超过一次。作为额外的预防措施,还可以验证作为每个贷款记录的一部分的上市时间是当前的和预期的。
例如,该脚本可以在本地运行,并由 Windows 任务计划程序触发。这有点不切实际,除非你有一台专用的电脑,在需要的时间开机并在线。
更好的解决方案是将脚本转移到云服务,让它在那里运行。有各种各样的选择适合网络托管,如谷歌云或 Heroku。迁移到这些服务可能有点棘手,因为他们期望应用程序是 web 服务,并且他们不提供持久的文件系统。因此,所有文件 IO 都需要被转换以使用远程文件系统或数据库。
最后,我使用了 PythonAnywhere ,它提供了一个基于云的环境,其行为就像 Linux 系统上的普通用户帐户,包括持久文件存储和调度任务的能力。
结论
虽然模拟结果看起来很有希望,自动投资脚本也在发挥作用,但对我的回报会有什么影响还有待观察。因此,最终分析将不得不推迟,直到有可能对违约率做出首次估计。
经济的变化会对结果产生影响。同样可以肯定的是,Lending Club 利用他们的贷款数据对贷款业绩做出了更好的预测,并改进了他们的算法来分配利率。这将减少甚至消除随机选择贷款的投资组合和使用我的模型的投资组合之间的相对表现差异。
Azure 中智能、实时和可扩展的视频处理
原文:https://towardsdatascience.com/intelligent-realtime-and-scalable-video-processing-in-azure-201f87104f03?source=collection_archive---------5-----------------------
1.介绍
在本教程中,创建了一个端到端项目,以便在 Azure 中进行智能、实时和可伸缩的视频处理。在这种情况下,可以利用火车的视频检测涂鸦和识别车皮号码。本项目的性质如下:
- 检测涂鸦和识别车牌号的智能算法
- 从边缘到云端实时可靠地处理视频
- 可扩展以适应视频数量的指数级增长
- 可以针对任何视频处理功能进行优化的功能项目
该项目的架构可描述如下:
1. Architecture overview
在这个博客中,这个架构是这样实现的:
- 2a。检测火车上涂鸦的认知服务(自定义视觉)
- 2b。识别货车编号的认知服务(计算机视觉 OCR)
- 3.用于视频并行处理的 Azure 函数
- 4.用于可视化的 Power BI(可选)
- 5.用于数据自动分层的物联网边缘架构(可选)
- 6.结论
在这个博客中,所有的视频处理都是在 Azure 中完成的。参考这个后续教程其中涂鸦检测是在摄像头(边缘)本身上完成的。下一章,将部署 Azure 认知服务。
2.Azure 认知服务
Azure 认知服务是一组可以注入你的应用的 API。它包含语音识别、图片中的对象识别和语言翻译的智能算法。这些模型大多是预先训练好的,可以集成到您的项目中。大多数模型也可以作为容器部署在边缘。在这个项目中,将使用两个 API:
- 将用于检测火车上涂鸦的自定义视觉。这个模型需要有/没有涂鸦的火车的图片来学习。这一步可以被视为“在已经在 Azure Cognitive Services 中训练过的图像识别模型的神经网络中添加最后一个自定义层”
- 将用于识别列车上车厢号计算机视觉 OCR。这种模式不需要培训,可以下架
在本章的剩余部分,将执行以下步骤:
- 2a。培训和部署自定义视觉 API 来检测涂鸦
- 2b。部署 OCR 计算机视觉 API
以及实现的架构的以下部分:
2. Cognitive services to detect graffiti and identif wagon number
2a。培训和部署自定义视觉 API 来检测涂鸦
转到自定义视觉网站并使用您的 Azure 广告凭证登录。登录后,选择创建具有属性“分类”和“多类(每个图像一个标签)”的自定义视觉项目,另请参见下文。
2a1. Create Custom Vision API project
然后将以下图像下载到以下 git 项目中的文件夹cognitive services/CustomVisionImages 中:
[https://github.com/rebremer/realtime_video_processing.git](https://github.com/rebremer/realtime_video_processing.git)
第一步,将带有涂鸦标签的涂鸦图片添加到您的项目中。其次,将带有标记涂鸦的 no_graffiti 图片添加到您的项目中,然后进行底片处理。然后使用快速通道训练模型,也见下文。
2a2. Train Custom Vision Api project
一旦您训练了模型,您可以通过点击“快速测试”来测试模型,然后使用之前下载的 git 项目从测试文件夹中选择一个图像。
2b。部署 OCR 计算机视觉 API
转到在步骤 2a 中创建的资源组,部署 OCR 计算机视觉 API。点击添加按钮,在搜索框中输入“计算机视觉”。选择 F0 作为定价层。部署计算机视觉 API 后,资源组将如下所示。
2b1. Resource group after Custom Vision API and Computer Vision for OCR is deployed
在下一章中,API 将用于检测视频中的涂鸦和货车号。
3.用于并行视频处理的 Azure 函数
一旦一个新的视频被上传(同步)到 Azure Blob 存储器中,它将立即被如下处理:
- Azure Blob 存储有一个触发器,它执行一个简单的 Azure 函数,向 Azure 队列发送消息
- Azure Queue 有一个执行高级 Azure 功能的触发器,该功能 1)从 blob 存储帐户检索视频,2)使用 OpenCV 每秒获取一帧视频,3)检测帧上的涂鸦,识别货车号并将结果写入 csv 文件
Azure 队列步骤是并行视频所必需的。在 blob 触发器直接触发高级 Azure 功能的情况下,视频仅被串行处理。并行视频处理架构如下所示。
3.1. Parallel video processing
在本章的剩余部分,将执行以下步骤:
- 3a。用 docker 安装 Azure 函数的预备程序
- 3b。使用 blob 容器和队列创建 Azure 存储帐户
- 3c1。(可选)为 Azure 函数 Blob 触发器创建 docker 图像
- 3c2。部署 Azure 函数 Blob 触发器
- 3d1。(可选)为 Azure 函数队列触发器创建 docker 映像
- 3d2。部署 Azure 函数队列触发器
- 3e。用视频运行测试
以及实现的架构的以下部分:
3.2. Steps in blog plotted on Architecture. Parallel video processing in bold as next step
其中并行视频处理能力的细节可以在前面的图 3.1“并行视频处理”中找到。
3a。用 docker 安装 Azure 函数的预备程序
为了从视频创建帧,需要一个带有 OpenCV 的 Azure 函数。为此,使用了一个带有 Python 的 Azure 函数,该函数使用一个预装了 OpenCV 依赖项的 docker 映像。为此,需要安装以下预备程序:
- 安装 Visual Studio 代码
- 安装 Azure 核心工具版本 2.x 。
- 安装 Azure CLI 。此博客需要 Azure CLI 版或更高版本。运行
az --version
找到您拥有的版本。 - (可选,如果你想创建自己的图像)安装 Docker
- (强烈推荐)在运行本教程中的命令之前,请先执行本教程中的命令
3b。使用 blob 容器和队列创建 Azure 存储帐户
需要 Azure 存储帐户来上传视频和运行 Azure 队列服务,Azure 功能将在这些服务上触发。打开 Visual Studio 代码,打开一个新的终端会话,并执行以下命令:
az loginaz group create -n blog-rtvideoproc-rg -l westeuropeaz storage account create -n <stor name> -g blog-rtvideoproc-rg --sku Standard_LRS
az storage container create -n videoblob --account-name <stor name>
az storage container create -n pics --account-name <stor name>
az storage container create -n logging --account-name <stor name>
az storage blob upload -f Storage/ImageTaggingLogging.csv -c logging -n ImageTaggingLogging.csv --account-name <stor name> --type appendaz storage queue create -n videoqueue --account-name <stor name>
确保将
3c1。(可选)为 Azure 函数 Blob 触发器创建 docker 图像
在这一步中,创建了一个简单的 Azure 函数,当一个新的视频被添加到存储帐户时,该函数被触发。然后提取视频的名称,并将其添加到在步骤 3b 中创建的存储队列中。打开 Visual Studio 代码,创建一个新的终端会话并执行以下命令(出现提示时选择 python 作为运行时)
func init afpdblob_rtv --docker
cd afpdblob_rtv
func new --name BlobTrigger --template "Azure Blob Storage trigger"
随后,打开 Visual Studio 代码,选择“文件”,选择“打开文件夹”,然后选择在前面的命令中创建的目录 afpdblob_rtv,另请参见下文:
3c1. Azure Function Blob trigger
在此项目中,替换以下文件的内容
BlobTrigger/__init__.py
BlobTrigger/function.json
Dockerfile
requirements.txt
同 github 项目内容https://github . com/reb remer/real time _ video _ processing/tree/master/azure function/afpdblob _ RTV/。下一步是构建 docker 映像,并将 docker 映像发布到公共 Docker Hub。或者,也可以使用私有的 Azure 容器注册中心(ACR ),但是要确保设置了凭证。执行以下命令发布到 docker hub
docker login
docker build --tag <<your dockerid>>/afpdblob_rtv .
docker push <<your dockerid>>/afpdblob_rtv:latest
3c2。部署 Azure 函数 Blob 触发器
在这一步中,docker 映像被部署为 Azure 函数。如果您跳过了 3c1 部分来创建自己的 docker 映像,您可以用 bremerov 替换
az appservice plan create --name blog-rtvideoproc-plan2 --resource-group blog-rtvideoproc-rg --sku B1 --is-linuxaz functionapp create --resource-group blog-rtvideoproc-rg --os-type Linux --plan blog-rtvideoproc-plan --deployment-container-image-name <your dockerid>/afpdblob_rtv:latest --name blog-rtvideoproc-funblob --storage-account <stor name>az functionapp config appsettings set --name blog-rtvideoproc-funblob --resource-group blog-rtvideoproc-rg --settings remoteStorageInputContainer="videoblob" `
AzureQueueName="videoqueue" `
remoteStorageAccountName="<stor name>" `
remoteStorageAccountKey="<stor key>"az functionapp restart --name blog-rtvideoproc-funblob --resource-group blog-rtvideoproc-rg
当功能被正确部署后,在门户中创建的功能如下
3c2.1 Azure Function Blob trigger deployed correctly
当您在 Blob Trigger 上打卡时,您可以看到 docker 图像中的代码。最后一步,添加应用洞察(见截图)并按照向导进行操作。这使您能够在 Monitor 选项卡中查看日志记录。作为测试,找到视频 Video1_NoGraffiti_wagonnumber。MP4,并使用向导将其上传到 blob 存储容器视频博客,见下文
3c2.2 Upload blob
视频上传后,使用 blob 触发器触发 Azure 函数,一个 json 文件被添加到 Azure queue videoqueue,如下所示
3c2.3 Json file with video name added to queue
3d1。(可选)为 Azure 函数队列触发器创建图像
在这一步中,创建了一个 advancedAzure 函数,当消息被发送到在步骤 3c2 中部署的 Azure 队列时,该函数被触发。打开 Visual Studio 代码,创建一个新的终端会话并执行以下命令(出现提示时选择 python 作为运行时)
func init afpdqueue_rtv --docker
cd afpdqueue_rtv
func new --name QueueTrigger --template "Azure Queue Storage trigger"
随后,打开 Visual Studio 代码,选择“文件”,选择“打开文件夹”,然后选择在前面的命令中创建的目录 afpdblob,另请参见下文:
3d1.1 Azure Function Queue trigger
在此项目中,替换以下文件的内容
QueueTrigger/__init__.py
QueueTrigger/function.json
Dockerfile
requirements.txt
同 github 项目内容https://github . com/rebremer/real time _ video _ processing/tree/master/azure function/afpdqueue _ RTV/。下一步是构建 docker 映像,并将 docker 映像发布到公共 Docker Hub。或者,也可以使用私有的 Azure 容器注册中心(ACR ),但是要确保设置了凭证。执行以下命令发布到 docker hub
docker login
docker build --tag <<your dockerid>>/afpdqueue_rtv .
docker push <<your dockerid>>/afpdqueue_rtv:latest
3d2。部署 Azure 函数队列触发器
在这一步中,docker 映像被部署为 Azure 函数。如果您跳过了 3d1 部分来创建自己的 docker 映像,您可以用 bremerov 替换
az functionapp create --resource-group blog-rtvideoproc-rg --os-type Linux --plan blog-rtvideoproc-plan --deployment-container-image-name **<your dockerid>**/afpdqueue_rtv:latest --name blog-rtvideoproc-funqueue --storage-account <stor name>az functionapp config appsettings set --name blog-rtvideoproc-funqueue --resource-group blog-rtvideoproc-rg --settings `
remoteStorageAccountName="<stor name>" `
remoteStorageAccountKey="<stor key>" `
remoteStorageConnectionString="<stor full connection string>" `
remoteStorageInputContainer="videoblob" `
AzureQueueName="videoqueue" `
remoteStorageOutputContainer="pics" `
region="westeurope" `
cognitiveServiceKey="<key of Computer vision>" `
numberOfPicturesPerSecond=1 `
loggingcsv="ImageTaggingLogging.csv" `
powerBIConnectionString=""az functionapp restart --name blog-rtvideoproc-funqueue --resource-group blog-rtvideoproc-rg
当正确部署了这些功能后,就会在门户中创建如下功能。
3d2.1 Azure Function Queue trigger deployed correctly
同样,选择添加 Applications Insights(参见顶部屏幕截图),您可以选择为 blob 触发器创建的相同 application Insights 资源。Application Insights 可用于查看 monitor 选项卡中 QueueTrigger 的日志记录。
如果 Azure 函数队列触发器成功运行,Azure 队列中的消息将被处理,图片日志可在 pics 目录中找到,见下文
3d2.2 Videos logging in frames
日志也可以在文件 logging/imagetaggingloging . CSV 中找到。在下一部分中,输出在 Power BI 中可视化。
4.用于可视化的 Power BI(可选)
Power BI 旨在提供交互式可视化和商业智能功能,其界面非常简单,最终用户可以创建自己的报告和仪表板。在这个博客中,它被用来创建一个流媒体仪表板,当检测到涂鸦伴随着车号时,它会发出警报。在本章的剩余部分,将执行以下步骤:
- 4a。安装电源 BI 的准备工作
- 4b。创建流式数据集
- 4c。从磁贴创建仪表板
- 4d。将 Power BI 链接添加到 Azure 函数
以及实现的架构的以下部分:
4. Steps in blog plotted on Architecture. Visualize output in bold as next step
请注意,完成博客物联网中心的最后一步并不需要可视化输出。
4a。安装电源 BI 的准备工作
在这篇博客中,所有数据集和仪表板将直接在 Power BI 中创建,因此没有必要安装 Power BI dashboard。转到以下链接创建帐户:
[## Power BI |交互式数据可视化 BI 工具
借助 Microsoft Power BI 的交互式数据可视化 BI 工具,以全新的方式查看您公司的数据。
powerbi.microsoft.com](https://powerbi.microsoft.com/en-us/)
4b。创建流数据集
登录后,转到您的工作区,选择创建,然后选择流式数据集。这个流数据集是从您的 Azure 函数队列触发器推送的。
4b1. Create streaming dataset
在向导中选择 API {},然后添加以下字段(字段也可以在 init 中)。publishPowerBI()方法中 Azure 函数队列触发器的 py
location (Text)
track (Text)
time (DateTime)
trainNumber (Text)
probGraffiti (Number)
caption (Text)
sasPictureTrainNumber (Text)
sasPictureGraffiti (Text)
4c。从磁贴创建仪表板
在下一步中,将基于流式数据集创建一个实时控制面板,一旦有新数据进入,该控制面板将自动刷新。首先,创建一个报表和一个可视化表格。只需将所有字段添加到该表格中。接下来,选择“锁定视觉对象”来创建视觉对象的活动 dasboard,也见下文。
4c1. Create streaming dataset
这样,可以在一个报告中创建多个视觉效果,并发布到同一个仪表板上。请参见下面的仪表板示例。
4c2. Example dashboard
4d。将 Power BI 链接添加到 Azure 函数
最后,需要将 Power BI push URL 添加到 Azure 函数队列触发器中,以便发布数据。单击您的流数据集的…,选择 API 信息并复制 URL,如下所示。
4d1. API info
随后,将 Power BI push URL 添加到您的 Azure 函数队列触发器,并重新启动该函数,见下文。
az functionapp config appsettings set --name blog-rtvideoproc-funqueue --resource-group blog-rtvideoproc-rg --settings `
powerBIConnectionString="<Power BI push URL"az functionapp restart --name blog-rtvideoproc-funqueue --resource-group blog-rtvideoproc-rg
删除视频 Video1_NoGraffiti_wagonnumber。MP4 并将其再次上传到您的 blob 存储帐户的 videoblob 容器中。这将把数据推送到您的 Power BI 仪表板。
5.用于数据自动分层的物联网边缘(可选)
物联网边缘上的 Azure Blob 存储是一个轻量级 Azure 一致模块,它提供本地块 Blob 存储。借助分层功能,数据会自动从本地 blob 存储上传到 Azure。这在以下情况下尤其有用:1)设备(如照相机)存储容量有限,2)要处理大量设备和数据,以及 3)互联网连接时断时续。在这篇博客中,一个相机在一个 Ubuntu 虚拟机上被模拟,这个虚拟机使用了 Blob on Edge。在本章的剩余部分,将执行以下步骤:
- 5a。创建物联网中心和 Ubuntu 虚拟机作为边缘设备
- 5b。将模块 Blob 存储添加到边缘设备
- 5c。使用边缘设备模拟摄像机
以及实现的架构的以下部分:
5. Steps in blog plotted on Architecture. IoT Hub Edge in bold as next step
5a。在物联网边缘安装 Azure Blob 存储的准备工作
为了在 IoT Edge 上使用 Azure Blob 存储,需要运行以下命令(更多详细信息,请参见此处)。
az extension add --name azure-cli-iot-extaz vm create --resource-group blog-rtvideoproc-rg --name blog-rtvideoproc-edge --image microsoft_iot_edge:iot_edge_vm_ubuntu:ubuntu_1604_edgeruntimeonly:latest --admin-username azureuser --generate-ssh-keys --size Standard_DS1_v2az iot hub create --resource-group blog-rtvideoproc-rg --name blog-rtvideoproc-iothub --sku F1az iot hub device-identity create --hub-name blog-rtvideoproc-iothub --device-id blog-rtvideoproc-edge --edge-enabled
运行以下命令检索密钥
az iot hub device-identity show-connection-string --device-id blog-rtvideoproc-edge --hub-name blog-rtvideoproc-iothub
并使用以下命令将此密钥添加到您的虚拟机中
az vm run-command invoke -g blog-rtvideoproc-rg -n blog-rtvideoproc-edge --command-id RunShellScript --script "/etc/iotedge/configedge.sh '<device_connection_string from previous step>'"
正确创建物联网集线器和边缘设备后,您应该会在门户中看到以下内容
5b。将模块 Blob 存储添加到边缘设备
在该步骤中,Blob 存储模块被安装在边缘设备上。选择您的边缘设备,并使用 Azure 门户按照教程中的步骤进行操作
[## 将 Azure Blob 存储模块部署到设备- Azure IoT Edge
有几种方法可以将模块部署到物联网边缘设备,所有这些方法都适用于物联网边缘上的 Azure Blob 存储…
docs.microsoft.com](https://docs.microsoft.com/en-us/azure/iot-edge/how-to-deploy-blob)
在这种情况下,使用以下容器创建选项
{
"Env":[
"LOCAL_STORAGE_ACCOUNT_NAME=localvideostor",
"LOCAL_STORAGE_ACCOUNT_KEY=xpCr7otbKOOPw4KBLxtQXdG5P7gpDrNHGcrdC/w4ByjMfN4WJvvIU2xICgY7Tm/rsZhms4Uy4FWOMTeCYyGmIA=="
],
"HostConfig":{
"Binds":[
"/srv/containerdata:/blobroot"
],
"PortBindings":{
"11002/tcp":[{"HostPort":"11002"}]
}
}
}
以及下面的“设置模块 twin 的期望属性”:
{
"properties.desired": {
"deviceToCloudUploadProperties": {
"uploadOn": true,
"uploadOrder": "OldestFirst",
"cloudStorageConnectionString": "<your stor conn string>",
"storageContainersForUpload": {
"localvideoblob": {
"target": "videoblob"
}
},
"deleteAfterUpload":false
}
}
}
如果一切都部署成功,门户中应该有以下内容
5b. Blob on Edge successfully deployed
此外,您可以从 CLI 运行以下命令,以查看是否一切安装正确。
ssh azureuser@<<public IP of your Ubuntu VM>>
sudo systemctl status iotedge
journalctl -u iotedge
cd /srv/containerdata
ls -la
如果一切都部署成功,我们可以运行一个相机模拟器,上传一个文件到您的本地 blob 存储在下一部分。
5c。使用边缘设备模拟摄像机
在这篇博客的最后一部分,我们将使用一个相机模拟器,将一个文件放在边缘设备上。
首先,您需要打开 Ubuntu 虚拟机的入站端口 11002。找到虚拟机的网络安全组(NSG)并添加端口 11002,另请参见下文
5c1. Add port 11002 to NSG
从 CameraSimulator/CameraSimulator . py 中的 github 运行代码,在这个项目中,替换你的 UbuntuVM 的 IP 地址和你要上传的视频文件的位置。
该模拟器上传视频并触发本教程中完成的所有操作,即 1)将视频同步到存储帐户,因为自动分层已启用,2)触发处理视频的博客触发器和队列触发器功能,3)调用认知服务来检测涂鸦并识别货车编号,以及 4)将结果推送到 Power BI dashboard,另请参见下文。
5c2. End result project
6.结论
在这篇博客中,为了在 Azure 中进行智能、实时和可伸缩的视频处理,创建了一个端到端的项目。在这方面,创造了一种能力,可以检测涂鸦和识别车厢号码使用视频的火车。在这种情况下,使用了以下 Azure 函数
- 认知服务被用作智能算法来检测火车上的涂鸦(自定义视觉 API)和 OCR 来识别货车编号(计算机视觉 API)
- 使用 Python 和 docker 的 Azure 函数以可扩展的方式实时处理视频
- Azure Blob 存储和边缘计算用于处理从边缘到云的可靠视频。
- 使用仪表盘中的流数据增强 BI 的可视化输出
在这个博客中,所有的视频处理都是在 Azure 中完成的。在本博客的后续部分,涂鸦检测模型将被部署在摄像头(edge)上,这样可以节省数据传输,并且可以节省成本。已经看到本教程这是如何在不同的场景中完成的。最后,请参见下面描述的项目架构:
6. Intelligent, realtime and scalable video processing in Azure
与 Plotly 的交互式 Choropleth 地图
原文:https://towardsdatascience.com/interactive-choropleth-maps-with-plotly-46c34fba0e48?source=collection_archive---------3-----------------------
如何从 Api 读取数据,匹配地理和非空间数据并创建交互式地图
最*,我想可视化上次联邦选举的数据。我住在德国的杜塞尔多夫,我想知道哪个政党在哪个地区有相对优势。
令人惊讶的是,这比预期的要难一点。因此,我想在这里分享我的经验。我们将一起经历以下步骤:
0.准备工作
1。通过 Api 读取 GeoJSON 和 JSON 格式的数据
2。从 GeoJSON 数据中提取相关特征
3。用色标和鼠标悬停定制我们的地图。将所有东西放在一起,增加互动性
0.准备
您可以按照本教程使用自己的数据集来创建自己的地图。最简单的方法是使用 GeoJSON 或 JSON 格式的数据。在这里,您可以看看本教程中的数据:
https://open data . dueseldorf . de/API/action/datastore/search . JSON?resource _ id = 6893 a12e-3d 75-4b2f-bb8b-708982 bea 7b 7
https://open data . Dusseldorf . de/sites/default/files/stadt teil _ WGS 84 _ 4326 . geo JSON
Fig. 1: GeoJSON- And Geo-Data
对于本教程,您还需要一个 mapbox 帐户。Mapbox 提供了灵活的地理数据 API。使用 Mapbox API,我们可以将个人数据映射到可缩放的世界地图上。你可以在 www.mapbox.com 开一个账户。您需要一个单独的令牌来使用 mapbox 服务,该服务可在帐户设置下找到:
Fig. 2: Mapbox Account Settings
1。通过 Api 读取 GeoJSON 和 JSON 格式的数据
GeoJSON 是地理要素的开放标准格式。在这个标准中,数据的存储遵循特定的结构。要素可以是点、线、面,甚至是这三种类型的组合。例如,多边形(特定房间内的封闭区域)可能如下所示:
{
"type": "Polygon",
"coordinates": [
[[35, 10], [45, 45], [15, 40], [10, 20], [35, 10]],
[[20, 30], [35, 35], [30, 20], [20, 30]]
]
}
在我们的示例中,我们还将访问 GeoJSON 数据,并将其与 JSON 数据相结合。网站上有杜塞尔多夫地区的地理数据和选举数据。但是,数据是分离的,我们必须在以后合并它们。
首先,我们导入所有必需的库:
import pandas as pd
import numpy as np
import urllib.request, json
import requests
现在我们可以读取 URL 的内容了:
url_wahl_2017 = 'https://opendata.duesseldorf.de/api/action/datastore/search.json?resource_id=6893a12e-3d75-4b2f-bb8b-708982bea7b7'
url_stadtteile = 'https://opendata.duesseldorf.de/sites/default/files/Stadtteile_WGS84_4326.geojson'geo_data = requests.get(url_stadtteile).json()
data_wahl = requests.get(url_wahl_2017).json()
这两个数据源现在都可以作为嵌套字典使用。使用data_wahl['result']['records']
可以显示各个选区的选举结果:
Fig. 3: Election results of the individual districts
我们现在可以将字典中的相关选举数据导入到 pandas 数据框架中:
df_wahl = pd.DataFrame.from_dict(data_wahl['result']['records'])
Fig. 4: Election results as dataframe
2.从 GeoJSON 数据中提取相关特征
现在我们来看看地理数据。为了使用 Plotly 进行进一步处理,我们现在从地理数据请求中提取相关要素:
sources=[{"type": "FeatureCollection", 'features': [feat]} for feat in geo_data['features']]
列表sources
包含城市所有部分的坐标。我们稍后将把这个列表交给Mapbox
对象,以便呈现各个地区。地区的 id 也从地理数据中提取:
tx_ids=[geo_data['features'][k]['properties']['Stadtteil'] for k in range(len(geo_data['features']))]
我们稍后需要 id 来为每个政党和每个地区分配正确的色阶。
3.用色标和鼠标悬停定制我们的地图
为了以后能够动态地给城市的各个部分着色,我们需要每一方各自的百分比范围。最亮的阴影被指定为最低值,最暗的阴影被指定为最高值。为此,我们为每个政党和每个地区确定最低和最高值:
parties = ['Wahlsieger_proz','CDU_Proz','SPD_Proz','DIE LINKE_Proz','GRÜNE_Proz','AfD_Proz','FDP_Proz']for n in range(0,len(rate_list)):dct[rate_list[n]] = [df.loc[stadtteil, parties[n]] for stadtteil in tx_ids]dct_min[mins_list[n]] = min(dct[rate_list[n]])dct_max[maxs_list[n]] = max(dct[rate_list[n]])
现在我们为每一方创建它自己的色标。最重要的是,我关注的是派对的颜色:
#Winner
pl_colorscale= [[0.0, ‘rgb(255, 255, 204)’],
[0.35, ‘rgb(161, 218, 180)’],
[0.5, ‘rgb(65, 182, 196)’],
[0.6, ‘rgb(44, 127, 184)’],
[0.7, ‘rgb(8, 104, 172)’],
[1.0, ‘rgb(37, 52, 148)’]]#CDU
cdu_colorscale= [[0.0, ‘rgb(224, 224, 224)’],
[0.35, ‘rgb(192, 192, 192)’],
[0.5, ‘rgb(160, 160, 160)’],
[0.6, ‘rgb(128, 128, 128)’],
[0.7, ‘rgb(96, 96, 96)’],
[1.0, ‘rgb(64, 64, 64)’]]#SPD
spd_colorscale= [[0.0, ‘rgb(255, 153, 153)’],
[0.35, ‘rgb(255, 102, 102)’],
[0.5, ‘rgb(255, 51, 51)’],
[0.6, ‘rgb(255, 0, 0)’],
[0.7, ‘rgb(204, 0, 0)’],
[1.0, ‘rgb(153, 0, 0)’]]#Die Grünen
gruene_colorscale= [[0.0, ‘rgb(153, 255, 204)’],
[0.35, ‘rgb(102, 255, 178)’],
[0.5, ‘rgb(51, 255, 153)’],
[0.6, ‘rgb(0, 255, 128)’],
[0.7, ‘rgb(0, 204, 102)’],
[1.0, ‘rgb(0, 153, 76)’]]#Die Linke
linke_colorscale= [[0.0, ‘rgb(255, 153, 204)’],
[0.35, ‘rgb(255, 102, 178)’],
[0.5, ‘rgb(255, 51, 153)’],
[0.6, ‘rgb(255, 0, 128)’],
[0.7, ‘rgb(204, 0, 102)’],
[1.0, ‘rgb(153, 0, 76)’]]#AFD
afd_colorscale= [[0.0, ‘rgb(153, 255, 255)’],
[0.35, ‘rgb(102, 255, 255)’],
[0.5, ‘rgb(51, 255, 255)’],
[0.6, ‘rgb(0, 255, 255)’],
[0.7, ‘rgb(0, 204, 204)’],
[1.0, ‘rgb(0, 153, 153)’]]#FDP
fdp_colorscale=[[0.0, ‘rgb(255, 255, 204)’],
[0.35, ‘rgb(255, 255, 153)’],
[0.5, ‘rgb(255, 255, 102)’],
[0.6, ‘rgb(255, 255, 51)’],
[0.7, ‘rgb(255, 255, 0)’],
[1.0, ‘rgb(204, 204, 0)’]]
下面这个函数是我从一个教程里拿来的,强烈推荐:
现在,我们将该函数用于之前创建的迷你和最大字典,以创建单独的色阶:
我们希望在一张卡片上标明各自的选举获胜者,在另一张卡片上标明各个政党。为此,我们改编鼠标悬停文本:
text_win=[c+’<br>Election winner was the ‘+ w + ‘ with ‘ + ‘{:0.2f}’.format(r)+’%’ for c, r, w in zip(counties, dct[rate_list[0]], wahlsieger_c)]text_cdu=[c+’<br>The CDU had ‘ + ‘{:0.2f}’.format(r)+’%’ for c, r in zip(counties, dct[rate_list[1]])]text_spd=[c+’<br>The SPD had ‘ + ‘{:0.2f}’.format(r)+’%’ for c, r in zip(counties, dct[rate_list[2]])]text_linke=[c+’<br>The Linke had ‘ + ‘{:0.2f}’.format(r)+’%’ for c, r in zip(counties, dct[rate_list[3]])]text_gruene=[c+’<br>The Grünen had ‘ + ‘{:0.2f}’.format(r)+’%’ for c, r in zip(counties, dct[rate_list[4]])]text_afd=[c+’<br>The AfD had ‘ + ‘{:0.2f}’.format(r)+’%’ for c, r in zip(counties, dct[rate_list[5]])]text_fdp=[c+’<br>The FDP had ‘ + ‘{:0.2f}’.format(r)+’%’ for c, r in zip(counties, dct[rate_list[6]])]
4.将所有东西放在一起,增加互动性
我们现在必须注意以下几点。data
包括代表地区形状的地理数据和鼠标悬停文本。但我们希望灵活的色阶取决于下拉菜单中的选择和每个地区政党的相对实力。这些色阶由layer
表示。可以将数据分配给一个列表。根据下拉列表的选择,我们将列表中各个元素的可见性设置为True
或False
。例如,如果我们有一个包含三条记录的列表,并且想要呈现第一条记录,我们给出一个条目列表[True,False,False]
作为visible
的参数。
我们首先创建data
列表。我们提取每个地区的经度和纬度元素,并将它们添加到列表中:
图层也收集在一个列表中:
现在我们添加下拉菜单。首先,我们将完成条目的标签和相应的可见条件。最后,我们提交数据和图层列表:
在visible
列表中,我们定义显示data
列表的哪个元素。为了让色阶相应地适应,我们还必须在"mapbox.layers"
下定义我们的layers
列表。
如果我们将所有内容放在一起,我们会得到以下代码:
如果你想运行代码,你需要修改第 10 行的mapbox_access_token
。
您的结果应该如下所示:
Fig. 5: Final Plot With Interactivity
结论和最终想法
用 Python 处理 GeoJSON 和 JSON 格式非常容易。使用 Plotly,您可以根据地理信息创建美丽的 Choropleth 地图。如果你想使用下拉菜单增加交互性,那就有点棘手了,因为你需要为每一层添加单独的色阶。然而,args
提供了所需的灵活性。在下一步中,添加一个单独的 colorbar 图例还是不错的。此外,说明更多的社会人口特征也很有意思。所以要有创意!
开源代码库
笔记本:
https://Github . com/BD 317/geodata/blob/master/API-Duesseldorf-Github % 20(1)。ipynb
进一步的信息
choropleth 绘图的一般文档:
https://plot.ly/python/choropleth-maps/
恩培特的一本伟大的笔记本,作为 Plotly choropleth 地图的介绍;
[## ' b '与 Plotly | empet | Plotly 一起工作地图箱 choropleth '
编辑描述
plot.ly](https://plot.ly/~empet/14692/mapbox-choropleth-that-works-with-plotly/#/)
同一用户对新 Plotly trace-type choroplethmapbox 的更新:
[## b '带有下拉菜单的 choroplethmapbox | empet | Plotly '
编辑描述
plot.ly](https://plot.ly/~empet/15237/choroplethmapbox-with-dropdown-menu/#/)
Fig. 6: New trace type — Choroplethmapbox
如果您喜欢中级和高级数据科学,并且还没有注册,请随时使用我的推荐链接加入社区。
Jupyter 笔记本中的交互式控件
原文:https://towardsdatascience.com/interactive-controls-for-jupyter-notebooks-f5c94829aee6?source=collection_archive---------1-----------------------
(Source)
如何使用交互式 IPython 小部件来增强数据探索和分析
在数据探索中,很少有操作比一次又一次地重新运行同一个单元效率更低,每次都略微更改输入参数。尽管知道这一点,我仍然发现自己重复执行单元格只是为了做出最微小的改变,例如,为一个函数选择不同的值,选择不同的日期范围进行分析,甚至调整一个情节可视化的主题。这不仅效率低下,而且令人沮丧,扰乱了探索性数据分析的流程。
这个问题的理想解决方案是使用交互式控件来改变输入,而不需要重写或重新运行代码。幸运的是,正如 Python 中经常出现的情况,已经有人遇到了这个问题,并开发了一个很好的工具来解决它。在本文中,我们将了解如何开始使用 IPython 小部件 ( ipywidgets
),这是一行代码就可以构建的交互式控件。这个库允许我们将 Jupyter 笔记本从静态文档转变为交互式仪表板,非常适合探索和可视化数据。
点击下图,您可以在 mybinder 上查看一个完全交互式的跑步笔记本,其中包含本文中的小部件。
Widgets notebook on mybinder.org
不幸的是,IPython 小部件不能在 GitHub 或 nbviewer 上渲染,但是你仍然可以访问笔记本并在本地运行。
Example of interactive widgets for data visualization
IPywidgets 入门
像往常一样,第一步是安装库 : pip install ipywidgets
。完成后,您可以通过以下方式激活 Jupyter 笔记本的小部件
jupyter nbextension enable --py widgetsnbextension
要使用 JupyterLab,请运行:
jupyter labextension install @jupyter-widgets/jupyterlab-manager
要在笔记本中导入ipywidgets
库,运行
import ipywidgets as widgets
from ipywidgets import interact, interact_manual
单线交互式控件
假设我们有以下中等文章统计的数据框架(这些是我的实际统计,你可以在本文中看到如何获得它们):
Dataframe of Medium stats
怎样才能查看所有阅读量超过 1000 的文章?这里有一个方法:
df.loc[df['reads'] > 1000]
但是如果我们想显示超过 500 次鼓掌的文章,我们必须写另一行代码:
df.loc[df['claps'] > 500]
如果我们能够快速地改变这些参数——包括列和阈值——而不需要编写更多的代码,这不是很好吗?试试这个:
[@interact](http://twitter.com/interact)
def show_articles_more_than(column='claps', x=5000):
return df.loc[df[column] > x]
Interactive controls using @interact
使用[@interact](https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html)
装饰器,IPywidgets 库自动给我们一个文本框和一个滑块来选择列和数字!它查看我们函数的输入,并根据类型创建交互式控件。现在,我们可以使用控件(小部件)对数据进行分段,而无需编写代码。
你可能已经注意到小部件的一些问题— x
可能会变成负数,我们必须输入正确的column
名字。我们可以通过为函数参数提供特定参数来解决这些问题:
Improved widgets for subsetting data.
现在我们得到一个列的下拉列表(带有列表中的选项)和一个限定在一个范围内的整数滑块(格式是(start, stop, step)
)。通读文档了解函数参数如何映射到小部件的全部细节。
我们可以使用同一个@interact
装饰器快速地将任何普通功能变成一个交互式小部件。例如,我们可能希望快速浏览目录中的大量图像:
import os
from IPython.display import Image@[interact](http://twitter.com/interact)
def show_images(file=os.listdir('images/')):
display(Image(fdir+file))
Example of browsing images using IPython widgets
现在,我们可以快速循环所有图像,而无需重新运行单元。如果你正在构建一个卷积神经网络,并且想要检查你的网络已经错误分类的图像,这实际上可能是有用的。
小部件在数据探索方面的用途是无限的。另一个简单的例子是寻找两列之间的相关性:
Widget for correlation between two columns.
ipywidgets GitHub 上有很多有用的例子。
用于绘图的微件
交互式小部件对于选择要绘制的数据特别有帮助。我们可以使用相同的@interact
装饰器来可视化我们的数据:
Interactive scatter plot made using cufflinks+plotly with IPywidgets controls
在这里,我们使用惊人的袖扣+plotly 组合来制作一个带有交互式 IPython 控件的交互式 plot 。
你可能已经注意到剧情更新有点慢。如果是这种情况,我们可以使用@interact_manual
,它需要一个按钮来更新。
Button made with @interact_manual decorator.
现在,只有按下按钮时,绘图才会更新。这对于需要一段时间才能返回输出的函数很有用。
扩展交互控件的功能
为了从 IPywidgets 库中获得更多,我们可以自己制作小部件并在interact
函数中使用它们。我最喜欢的小工具之一是DatePicker
。假设我们有一个函数stats_for_article_published_between
,它获取开始和结束日期,并打印两者之间发布的所有文章的统计数据。我们可以使用下面的代码来实现这种交互
现在我们得到了两个交互式日期选择小部件,这些值被传递到函数中(详见笔记本):
Interactive date selection controls.
类似地,我们可以使用同一个DataPicker
交互式小部件创建一个函数,绘制一个列直到某个日期的累计总数。
Cumulative plot of a column using interactive widgets.
如果我们想让一个小部件的选项依赖于另一个小部件的值,我们使用observe
函数。在这里,我们修改了图像浏览器函数来选择目录和图像。显示的图像列表根据我们选择的目录进行更新。
Code to make the images widget dependent on the value of the directory widget
Left show image options when the directory is “images” and right shows options when directory is “nature”.
可重复使用的部件
当我们想要跨单元格重用小部件时,我们只需要将它们分配给interact
函数的输出。
现在,为了重用stats
小部件,我们可以只在单元格中调用stats.widget
。
The same widget used in another cell.
这让我们可以在笔记本上重用我们的小部件。请注意,小部件是相互关联的,这意味着一个单元格中的值将自动更新为您在另一个单元格中为同一小部件选择的值。
我们还没有涵盖 IPywidgets 的所有功能。例如,我们可以将值链接在一起,创建定制的小部件,制作按钮,制作动画,创建带有选项卡的仪表板,等等。查看文档以备将来使用。尽管这里只涉及了很少的一部分,我希望您能看到交互式控件是如何增强笔记本工作流程的!
Simple widget to select theme for a plot.
结论
Jupyter 笔记本是一个很好的数据探索和分析环境。然而,它本身并没有提供最好的功能。使用像笔记本扩展和交互式小工具这样的工具让笔记本变得栩栩如生,让我们作为数据科学家的工作更加高效。此外,构建小部件并在笔记本中使用它们非常有趣!重复编写大量代码来完成相同的任务并不愉快,但是使用交互式控件为我们的数据探索和分析创建了一个更自然的流程。
一如既往,我欢迎反馈和建设性的批评。我可以通过推特 @koehrsen_will 联系到。
面向数据科学的交互式仪表盘
原文:https://towardsdatascience.com/interactive-dashboards-for-data-science-51aa038279e5?source=collection_archive---------5-----------------------
用 Python 创建一个在线仪表板来分析脸书股票市场价格和业绩指标。
Facebook Data Analysis Dashboard
介绍
创建在线数据科学仪表板是交流数据科学项目结果的一种非常有效的方式。一个好的仪表板可以:
- 总结数据分析的主要结果。
- 让客户/公司经理能够测试一些参数的变化如何影响某个结果。
- 不断获取新数据以更新其图表和摘要。
- 允许我们使用预先训练的机器学习模型或在线训练它们来在线进行预测。
如今,有许多不同的服务可以用来创建仪表板。一些例子是:
- 阴谋地破折号
- 散景仪表盘
- 谷歌数据工作室
- 画面
前两个例子需要很好的 Python 编程知识来创建仪表板,相反,后两个例子不一定需要任何编程知识(它们提供了较少的定制选项)。
Figure 1: Titanic Data Set Dashboard made using Tableau.
在本文中,我将带您了解如何使用 Plotly Dash 在线创建和部署仪表板。本文中使用的所有代码(以及更多!)可在我的 GitHub 帐户上获得。
我的最终版本的仪表板可以通过链接在线测试。
破折号
Figure 2: Dash [1]
Dash 是一个开源 Python 库,由 Plotly 设计,用于创建基于 Web 的反应式应用程序。这个库建立在其他包之上,如:Flask、Plotly.js、React 和 React Js。
每个 Dash 应用程序都由两个主要部分组成:
- 布局 =用于定义所有内容在应用程序上的布局。
- 回调 =用于使仪表板的每个所需组件交互。
此外,Dash 还提供了一个 HTML 类的集合来生成 Python 中的 HTML 代码()Dash-HTML-components),Markdown 和 App 认证支持。
下面列出了开始使用 Dash 所需的所有必要库。
pip install dash
pip install dash-renderer
pip install dash-html-components
pip install dash-core-components
pip install plotly
为了创建下面的仪表板,我使用了两个不同的数据集。第一个是鲍里斯·马贾诺维奇的庞大股市数据集,第二个是莫罗、s .、丽塔、p .、&瓦拉、B 的脸书指标数据集。
在 dashboard 应用程序上加载第一个数据集之前,我执行了一些预处理分析,生成的数据集可在此处获得。
在本演示中,我们将一起创建一个由两个选项卡组成的控制面板。第一个选项卡将显示脸书、苹果、微软和特斯拉等公司的高、低和成交量股市指标。第二个选项卡将显示脸书性能指标数据集中每个可用特性的分布情况(图 3)。
Figure 3: Final Dashboard which we will create in this tutorial
如果你有兴趣给这个应用增加更多的功能,在我的 GitHub 库有一个更高级的版本。
示范
首先我们需要创建一个名为 a pp.py 的 Python 文件,导入所有需要的依赖项。在这个文件中,我们将编写启动仪表板所需的所有代码。
我们将要使用的数据集将具有如图 4 和图 5 所示的结构。
Figure 4: Stock Dataset
Figure 5: Performance Metrics Dataset
然后,我们可以使用下面的代码设置我们的应用程序及其布局。布局存储在 app.layout 中,所有需要的 HTML 组件如 Div、H1、H2、P 等都已使用dash _ HTML _ components【HTML】库添加。最后,我们可以使用dash _ core _ components(DCC)库向我们的仪表板添加交互组件(例如,选项卡、下拉菜单、单选按钮)。
在这种情况下,我决定将这个仪表板分成两个选项卡。在第一个示例中,将分析股票价格数据集,在第二个示例中,将分析绩效指标数据集。第一个选项卡的布局随后被分成另外两个部分,每个部分由一个 H1 标题、一个带有四个不同选项的下拉菜单和一个时间序列图组成。第二个选项卡由一个 H1 标题、一个包含 18 个不同选项的下拉菜单和一个直方图组成。
一旦定义了仪表板的布局,我们就可以继续设计图表以及它们与下拉菜单的交互。图形可以被设计为创建函数,而图形和下拉菜单之间的交互可以使用回调来设计。
下面的代码可以分为 3 个主要部分:一个高-低股票价格时间序列图,一个市场容量时间序列图和一个性能指标特征分布图。
前两个部分非常相似,事实上,它们是为了创建相同类型的图形而设计的。唯一的区别是,在第二张图中,只考虑了一个特征,而不是两个。
在 3 个部分的每一个中,回调( @app.callback )用于从下拉列表中获取选定的值,将它们作为输入发送给 graph 函数,然后获取该函数返回的变量,将其传递给布局中声明的图形。每当下拉列表中的值改变时,这些回调将被自动调用。由于之前在仪表板布局中设置的独特的 id 值,回调可以自动识别仪表板上可用的不同下拉列表中的哪些改变了值,以及随后要更新哪个图形。
下面显示的三个函数都使用 Plotly 语法来创建图形。如果你以前从未使用过 Plotly,在我以前的一篇文章中,我已经谈到了交互式数据可视化。
第一个函数将生成下图。
Figure 6: Facebook Stocks, High vs Lows
第二个将创建如图 7 所示的图形。
Figure 7: Facebook Market Volume
最后,第三个函数将在仪表板的第二个选项卡上生成特性分布直方图(图 8)。
Figure 8: Facebook Metrics Distribution
最后,我们可以使用下面两行代码启动一个本地服务器并运行我们的应用程序。
现在我们的应用程序已经准备好了,我们可以通过在当前工作目录中打开我们的计算机终端并键入 python app.py 来简单地午餐它。这将在 http://127.0.0.1:8050/ 启动一个 web 服务器,点击此链接,我们将看到最终的 Python 应用程序正在运行。
可以轻松部署在线 Dash 应用程序,在 Heroku 上免费托管我们的应用程序。如果你有兴趣这样做,我写了另一篇关于在线机器学习部署的 Flask 和 Heroku 的文章。此外,Dash 文档也提供了如何在 Heroku 上部署 Dash 应用程序的指导。
结论
可以通过添加其他功能来进一步开发该控制面板,例如:
- 使用 web 抓取机制实时获取新的股票市场数据,以更新所有相关的图表。
- 添加更多数据可视化图表。
- 创建机器学习模型来进行预测(例如 ARIMA ,LSTM)。
- 改进仪表板整体设计。
点击此链接,可在线测试该仪表盘的更高级版本。
如果您需要任何帮助来添加这些附加功能, Dash 文档是一个很好的起点。
我希望你喜欢这篇文章,谢谢你的阅读!
联系人
如果你想了解我最新的文章和项目,请通过媒体关注我,并订阅我的邮件列表。以下是我的一些联系人详细信息:
- 领英
- 个人博客
- 个人网站
- 中等轮廓
- GitHub
- 卡格尔
文献学
[1] Dash 将 Python & R 模型在大规模上可操作化。访问地点:https://plot.ly/dash
交互式数据可视化
原文:https://towardsdatascience.com/interactive-data-visualization-167ae26016e8?source=collection_archive---------8-----------------------
使用 Python 库(如:Plotly、Bokeh、nbinteract 等)创建用于数据可视化的交互式绘图和微件
数据可视化
在分析数据集时,数据可视化是一个非常重要的步骤。如果执行准确,它可以:
- 帮助我们深入了解数据集背后的动态。
- 加快机器学习方面的分析。
- 让其他人更容易理解我们的数据集调查。
在本文中,我将使用实际的例子和有趣的可视化技术/部件向您介绍一些最常用的 Python 可视化库。我在本文中使用的所有代码都可以在这个 GitHub 资源库中找到。
Matplotlib
Matplotlib 可能是 Python 最著名的数据可视化库。在这个例子中,我将带你浏览如何创建一个 PCA 方差图的动画 GIF。
首先,我们必须使用 Seaborn 加载虹膜数据集并执行 PCA。随后,我们绘制了 20 幅 PCA 方差图的图形,同时改变了从轴的观察角度。为了创建 3D PCA 结果图,我使用了Python 图库作为参考。
最后,我们可以使用下面的函数从生成的 20 个图表中生成一个 GIF。
获得的结果应该与图 1 中的结果相同。这种相同的机制可以应用于许多其他应用,例如:动画分布、轮廓和分类机器学习模型。
Figure 1: PCA variance plot
在 Matplotlib 中制作动画图形的另一种方法是使用 Matplotlib 动画 API。这个 API 可以让 as 制作一些简单的动画和活图。一些例子可以在这里找到。
赛璐珞
为了使 Matplotlib 中的动画更容易,可以使用赛璐珞库。这是通过创建一个照相机来完成的,该照相机的目的是每当图表的一个参数改变时拍摄该图表的快照。然后,所有这些图片被暂时存储并组合在一起,生成一个动画。
在下面的例子中,将为每个循环迭代生成一个快照,并使用 animate() 函数创建动画。
然后也可以使用 ImageMagick 将生成的动画存储为 GIF。产生的动画如图 2 所示。
Figure 2: Celluloid Example
Plotly
plotly 是一个基于 plotly.js 构建的开源 Python 库,Plotly 有两种不同的模式:在线和离线。使用这个库,我们可以制作无限的离线模式图表和最多 25 个使用在线模式的图表。当安装 Plotly 时,尽管需要注册到他们的网站并获得一个 API 密匙来开始(而不是像本文中考虑的任何其他库一样只使用一个 pip 安装)。
在这篇文章中,我将带你看一个例子,使用离线模式来绘制特斯拉股票市场在很长一段时间内的最高价和最低价。我在这个例子中使用的数据可以在这里找到。
首先,我们需要导入所需的 Plotly 库。
随后,我导入数据集并对其进行预处理,以实现最终的绘图。在这种情况下,我确保了要用于绘图的列的数据类型是正确的,并且日期的格式是(YYYY-MM-DD)。为此,我将高价和低价列转换为 double 数据类型,将日期列转换为 string 格式。随后,我将日期列从日/月/年格式转换为年/月/日格式,最后转换为年-月-日格式。
Figure 3: Tesla Dataset
最终,我使用 Plotly 库制作了特斯拉股票市场高低价格的时间序列图。多亏了 Plotly,这个图表将是交互式的。将光标放在时间序列的任何点上,我们可以得到最高价和最低价,使用按钮或滑块,我们可以决定我们要关注哪个时间段。
图 4 显示了最终结果。Plotly 文档提供了大量关于如何充分利用这个库的例子,其中一些可以在这里找到。
Figure 4: Plotly Example
此外,还可以使用 Plotly Chart Studio 嵌入在线 Plotly 图形。下面是一个交互式 Plotly 嵌入的例子(现在可以在你的设备上随意玩这个图形了!).
散景
Bokeh 库对 Python 和 JavaScript 都可用。它的大多数图形、交互和小部件都可以用 Python 来实现,但在某些情况下可能还需要使用 Javascript。
使用散景时,图表是通过将一个图层堆叠在另一个图层上来构建的。我们首先创建一个图形,然后在上面添加元素(字形)。根据我们试图制作的情节,字形可以是任何形式和形状(如线条、条形、圆形)。
使用 Boker 创建图时,一些工具会随图一起自动生成。它们是:到散景文档的参考链接、*移、框缩放、滚轮缩放、保存选项和重置图形按钮(与 Plotly 相同)。
作为一个实际的例子,我现在将介绍如何使用 Plotly 示例中使用的相同数据集制作一个交互式时间序列图。
对于本演示,将绘制四个不同的时间序列(高/低/开盘价和收盘价),并将创建四个复选框。通过这种方式,用户可以选择选中/取消选中复选框,使任何四个时间序列从图表中消失。
在这个例子中,为了实现复选框功能,使用了 Javascript 而不是 Python。
结果图如图 5 所示。
Figure 5: Bokeh Demonstration
如上面的代码所示,绘图还被保存为一个 HTML 文件。这个选项也可以应用于 Plotly 图。如果你有兴趣测试自己用 Plotly 和 Bokeh 实现的情节,可以在这里找到。
Plotly 和 Bokeh 都可以额外用作 Python 的仪表板框架,创造出相当惊人的结果[1,2]。
海生的
Seaborn 是一个基于 Matplotlib 构建的 Python 库,用于制作统计图。根据 Seaborn 的官方网站:
如果 Matplotlib“试图让简单的事情变得简单,让困难的事情变得可能”,Seaborn 也试图让一组定义明确的困难事情变得简单。
我现在将向您展示一个使用 Seaborn 的简单示例。如果你想了解更多关于这个图书馆的信息, Seaborn example gallery 是一个很好的起点。
在下面的例子中,我首先使用 Seaborn 加载了虹膜数据集,然后创建了一个 pair-plot。
配对图是一种能够提供数据集中变量对的图形摘要的功能。这通过使用散点图和矩阵对角线的单变量分布表示来完成。图 6 显示了这一分析的结果。
Figure 6: Seaborn Pair-plot
nbinteract
nbinteract 使我们能够在 Jupiter Notebook 中创建交互式小部件。如果需要,这些小部件也可以导出为 HTML 格式。nbinteract 在线实现的一个例子可以在这里找到。
作为一个简单的实现,这里将创建一个下拉菜单。更改汽车数量或车主姓名的选择将实时更新字符串(图 7)。
Figure 7: NBInteract Example
附加库
除了已经提到的库,另外两个常用的 Python 库还有 Pygal 和 Altair 。它们都提供了与前面所示类似的绘图,但还可以用来创建其他形式的绘图,如:金字塔、树形图、地图和甘特图。
联系人
如果你想了解我最新的文章和项目,请通过媒体关注我,并订阅我的邮件列表。以下是我的一些联系人详细信息:
- 领英
- 个人博客
- 个人网站
- 中等轮廓
- GitHub
- 卡格尔
文献学
[1]散景—图库,服务器应用示例。访问地点:https://bokeh.pydata.org/en/latest/docs/gallery.html
[2] Plotly — Dash 应用程序库。访问地点:https://dash-gallery.plotly.host/Portal/
使用散景的 Python 交互式数据可视化
原文:https://towardsdatascience.com/interactive-data-visualization-with-python-using-bokeh-4c71f8f7c817?source=collection_archive---------25-----------------------
Photo by Yosh Ginsu on Unsplash
简单和基本的演练示例
最*我来到了这个图书馆,了解了一些,当然也尝试了一下,并决定分享我的想法。
来自官方网站:“Bokeh 是一个交互式可视化库,针对现代 web 浏览器进行演示。它的目标是提供优雅、简洁的通用图形结构,并通过超大型或流式数据集的高性能交互来扩展这种能力。Bokeh 可以帮助任何想要快速轻松地创建交互式绘图、仪表盘和数据应用的人。”我认为这很清楚,但如果能看到它的实际效果会更好,不是吗?
开始之前,请确保您的环境中安装了散景,如果没有,请遵循这里的安装说明。
所以我为自己创造了一些案例研究。决定将二氧化碳排放量的变化以及与 GDP 的相关性可视化(并检查这种相关性是否存在,因为你永远不知道:|)。
所以我拿了两个文件:一个是 Gapminder.org的二氧化碳排放量,另一个是 DataCamp 课程的(因为那个文件已经预处理过了😀是的,我是一个懒惰的混蛋😀 ).您也可以从这里下载这些文件。
二氧化碳排放量人均吨数 csv
gapminder_tidy.csv
我们如何开始分析数据?正确,通过导入必要的包和导入数据本身(非常重要的:D)。然后,我们执行一些 EDA(探索性数据分析)来了解我们正在处理的内容,之后清理数据并将其转换为分析所需的格式。非常简单。由于本文并不关注这些步骤,我将在下面插入我所做的所有转换的代码。
import pandas as pd
import numpy as np
# Data cleaning and preparation
data = pd.read_csv('data/co2_emissions_tonnes_per_person.csv')
data.head()
gapminder = pd.read_csv('data/gapminder_tidy.csv')
gapminder.head()
df = gapminder[['Country', 'region']].drop_duplicates()
data_with_regions = pd.merge(data, df, left_on='country', right_on='Country', how='inner')
data_with_regions = data_with_regions.drop('Country', axis='columns')
data_with_regions.head()
new_df = pd.melt(data_with_regions, id_vars=['country', 'region'])
new_df.head()
columns = ['country', 'region', 'year', 'co2']
new_df.columns = columns
upd_new_df = new_df[new_df['year'].astype('int64') > 1963]
upd_new_df.info()
upd_new_df = upd_new_df.sort_values(by=['country', 'year'])
upd_new_df['year'] = upd_new_df['year'].astype('int64')
df_gdp = gapminder[['Country', 'Year', 'gdp']]
df_gdp.columns = ['country', 'year', 'gdp']
df_gdp.info()
final_df = pd.merge(upd_new_df, df_gdp, on=['country', 'year'], how='left')
final_df = final_df.dropna()
final_df.head()
np_co2 = np.array(final_df['co2'])
np_gdp = np.array(final_df['gdp'])
np.corrcoef(np_co2, np_gdp)
顺便说一下,二氧化碳排放量和国内生产总值相关,而且非常显著——0.78。
np.corrcoef(np_co2, np_gdp)
Out[138]:
array([[1\. , 0.78219731],
[0.78219731, 1\. ]])
现在让我们进入可视化部分。同样,我们从必要的进口开始。我将进一步解释它们。现在,只要放松和导入。
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.models import HoverTool, ColumnDataSource, CategoricalColorMapper, Slider
from bokeh.palettes import Spectral6
from bokeh.layouts import widgetbox, row
我们将开始为我们的交互式可视化应用程序准备不同的细节。首先,我们为世界上不同的地区创建了一个颜色映射器,所以每个国家都会有不同的颜色,这取决于它所在的地区。我们选择唯一的区域,并将它们转换成列表。然后我们使用CategoricalColorMapper
为每个区域分配不同的颜色。
regions_list = final_df.region.unique().tolist()
color_mapper = CategoricalColorMapper(factors=regions_list, palette=Spectral6)
接下来,我们将为我们的应用程序准备一个数据源。Bokeh 接受许多不同类型的数据作为图形和视觉效果的来源:直接使用值列表、pandas 数据帧和系列、numpy 数组等提供数据。但是大多数散景的核心是ColumnDataSource
。
在最基本的层面上,[ColumnDataSource](https://bokeh.pydata.org/en/latest/docs/reference/models/sources.html#bokeh.models.sources.ColumnDataSource)
只是列名和数据列表之间的映射。[ColumnDataSource](https://bokeh.pydata.org/en/latest/docs/reference/models/sources.html#bokeh.models.sources.ColumnDataSource)
接受一个data
参数,该参数是一个字典,以字符串列名作为键,以数据值列表(或数组)作为值。如果一个位置参数被传递给[ColumnDataSource](https://bokeh.pydata.org/en/latest/docs/reference/models/sources.html#bokeh.models.sources.ColumnDataSource)
初始化器,它将被当作data
。(来自官网)。
# Make the ColumnDataSource: source
source = ColumnDataSource(data={
'x': final_df.gdp[final_df['year'] == 1964],
'y': final_df.co2[final_df['year'] == 1964],
'country': final_df.country[final_df['year'] == 1964],
'region': final_df.region[final_df['year'] == 1964],
})
我们从一年的数据样本开始。我们基本上为x, y, country
和region
创建了一个值字典。
下一步是为我们的轴设置限制。我们可以通过找到“X”和“Y”的最小值和最大值来实现。
# Save the minimum and maximum values of the gdp column: xmin, xmax
xmin, xmax = min(final_df.gdp), max(final_df.gdp)
# Save the minimum and maximum values of the co2 column: ymin, ymax
ymin, ymax = min(final_df.co2), max(final_df.co2)
之后,我们创建我们的图形,在那里我们将放置我们所有的可视化对象。我们给它一个标题,设置宽度和高度,也设置轴。(“Y”轴设置为日志类型只是为了更好地查看,尝试了几种类型,这一种给出了最好的结果)
# Create the figure: plot
plot = figure(title='Gapminder Data for 1964',
plot_height=600, plot_width=1000,
x_range=(xmin, xmax),
y_range=(ymin, ymax), y_axis_type='log')
散景使用字形的定义来定义可以出现在图上的所有可视形状。Bokeh 中内置的字形的完整列表如下(没有发明任何东西——所有信息来自官方页面):
[AnnularWedge](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/annular_wedge.html#bokeh.models.glyphs.AnnularWedge)
[Annulus](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/annulus.html#bokeh.models.glyphs.Annulus)
[Arc](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/arc.html#bokeh.models.glyphs.Arc)
[Bezier](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/bezier.html#bokeh.models.glyphs.Bezier)
[Ellipse](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/ellipse.html#bokeh.models.glyphs.Ellipse)
[HBar](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/hbar.html#bokeh.models.glyphs.HBar)
[HexTile](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/hex_tile.html#bokeh.models.glyphs.HexTile)
[Image](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/image.html#bokeh.models.glyphs.Image)
[ImageRGBA](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/image_rgba.html#bokeh.models.glyphs.ImageRGBA)
[ImageURL](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/image_url.html#bokeh.models.glyphs.ImageURL)
[Line](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/line.html#bokeh.models.glyphs.Line)
[MultiLine](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/multi_line.html#bokeh.models.glyphs.MultiLine)
[MultiPolygons](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/multi_polygons.html#bokeh.models.glyphs.MultiPolygons)
[Oval](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/oval.html#bokeh.models.glyphs.Oval)
[Patch](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/patch.html#bokeh.models.glyphs.Patch)
[Patches](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/patches.html#bokeh.models.glyphs.Patches)
[Quad](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/quad.html#bokeh.models.glyphs.Quad)
[Quadratic](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/quadratic.html#bokeh.models.glyphs.Quadratic)
[Ray](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/ray.html#bokeh.models.glyphs.Ray)
[Rect](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/rect.html#bokeh.models.glyphs.Rect)
[Segment](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/segment.html#bokeh.models.glyphs.Segment)
[Step](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/step.html#bokeh.models.glyphs.Step)
[Text](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/text.html#bokeh.models.glyphs.Text)
[VBar](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/vbar.html#bokeh.models.glyphs.VBar)
[Wedge](https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/wedge.html#bokeh.models.glyphs.Wedge)
所有这些字形通过它们的基类Glyph
共享一个最小的公共接口
我们不会太深入所有这些形状,并将使用圆作为最基本的形状之一。如果你想玩更多的其他字形,你有所有必要的文件和链接。
# Add circle glyphs to the plot
plot.circle(x='x', y='y', fill_alpha=0.8, source=source, legend='region', color=dict(field='region', transform=color_mapper), size=7)
那么我们怎么把这些圈加起来呢?我们将我们的源分配给圆形字形的“源”参数,我们为“X”和“Y”指定数据,我们为颜色添加图例,我们将先前创建的ColorMapper
应用到“颜色”参数,“fill_alpha”设置一点透明度,“size”是将出现在图上的圆形的大小。
接下来,我们通过设置图例的位置并给我们的轴一些解释来改善我们的绘图的外观。
# Set the legend.location attribute of the plot
plot.legend.location = 'bottom_right'
# Set the x-axis label
plot.xaxis.axis_label = 'Income per person (Gross domestic product per person adjusted for differences in purchasing power in international dollars, fixed 2011 prices, PPP based on 2011 ICP)'
# Set the y-axis label
plot.yaxis.axis_label = 'CO2 emissions (tonnes per person)'
到目前为止,我们对 1964 年有一个基本的静态情节,但文章的标题有一个词不适合这种情况——“互动”O_O。所以让我们增加一些互动性!
为了做到这一点,我们将添加一个带有年份的滑块,所以最终我们将有一个每个可用年份的可视化。酷!不是吗?
以前我们导入了类Slider
,现在是时候使用它了!因此,我们创建了这个类的对象,开始是最小年,结束是最大值,默认值是最小年,步骤(滑块上的值变化的速度)-1 年,以及标题。
我们还为这个滑块上发生的任何变化创建了一个回调。散景中的回调总是有相同的输入参数:attr, old, new
。我们将根据滑块的值更新我们的数据源。因此,我们创建了一个新的字典,它将对应于滑块中的年份,并基于此更新我们的绘图。我们也相应地更新了标题。
# Make a slider object: slider
slider = Slider(start=min(final_df.year), end=max(final_df.year), step=1, value=min(final_df.year), title='Year')
def update_plot(attr, old, new):
# set the `yr` name to `slider.value` and `source.data = new_data`
yr = slider.value
new_data = {
'x': final_df.gdp[final_df['year'] == yr],
'y': final_df.co2[final_df['year'] == yr],
'country': final_df.country[final_df['year'] == yr],
'region': final_df.region[final_df['year'] == yr],
}
source.data = new_data
# Add title to figure: plot.title.text
plot.title.text = 'Gapminder data for %d' % yr
# Attach the callback to the 'value' property of slider
slider.on_change('value', update_plot)
有了这么多的数据点,绘图很快就会变得混乱。因此,为了使这里将要展示的每个小圆圈更加清晰,我决定将 HoverTool 也包含在这个图中。
# Create a HoverTool: hover
hover = HoverTool(tooltips=[('Country', '@country'), ('GDP', '@x'), ('CO2 emission', '@y')])
# Add the HoverTool to the plot
plot.add_tools(hover)
HoverTool 接受一个元组列表,第一个值是 label,第二个值是来自数据源的值 detail。
我们已经完成了这个小应用程序的所有组件,只剩下最后几行代码来创建一个布局并将其添加到当前文档中
# Make a row layout of widgetbox(slider) and plot and add it to the current document
layout = row(widgetbox(slider), plot)
curdoc().add_root(layout)
我们完了。恭喜你!我们运行这段代码,但…什么也没有。没有错误(或者可能有一些错误,但你修复它们后就没有错误了),没有应用程序,没有可视化 O_o。为什么我花了那么多时间来创建一个很酷的情节,而我什么也没有得到?甚至不解释我做错了什么?
这是我尝试运行该应用程序时的第一个想法。但是后来我想起了一个技巧,你实际上首先必须启动一个服务器,作为这个可视化的后端。
因此,接下来也是最后一件事就是从命令行运行下面的代码:
bokeh serve --show my_python_file.py
它会自动在新的浏览器选项卡中打开您的可视化。
尽管 matplotlib 是最受欢迎的,但它并不是最用户友好的数据可视化工具,并且有它自己的局限性,我真的不喜欢它。所以,如果你和我属于同一群人,散景是一个可能的解决方案。试试看,让我知道你的想法。
感谢您的关注,希望这个关于散景的小介绍对您有用,祝您度过愉快的一天!(或者晚上,如果你在睡觉前读这篇文章,😄)
另外,我也想尝试 plotly,看到了很多关于它的积极反馈。
Github 上的 PS . s .代码。
原载于 2019 年 1 月 31 日4 种语言(EN、es、UA、RU)。
用 Vega 实现交互式数据可视化
原文:https://towardsdatascience.com/interactive-data-visualization-with-vega-ab09e2843d54?source=collection_archive---------9-----------------------
什么是 Vega 以及如何使用它来构建 web 可视化
我一直在学习新的可视化工具,因为这有助于我为手头的任务找到合适的工具。谈到数据可视化,d3 通常是首选,但最*我一直在玩 织女星 ,我很喜欢它。
Vega 引入了一个可视化语法。语法基本上是一套规定如何使用语言的规则,因此我们可以将 Vega 视为一种工具,它定义了一套如何构建和操作视觉元素的规则。
随着我在数据可视化方面的经验增长,我越来越发现约束是一件好事。通过引入可视化语法,Vega 为我们提供了一些约束条件。最棒的是,这些约束可以让用户在构建数据可视化时感到非常有效率。
还有 Vega-Lite ,一种专注于快速创建通用统计图形的高级语法,但今天我们将坚持使用 Vega ,它是一种更通用的工具。
好了,介绍够了,让我们来了解一下织女星是如何工作的。
Vega 概述
我们可以在 web 上部署 Vega,但是在本教程中,我们将简单地使用 Vega 编辑器(这是关于 Vega 的另一件大事)。
在使用 Vega 时,我们在一个 JSON 对象中定义可视化。让我们开始构建一个条形图。
A bar chart built with Vega
如果我们分解这个图表,我们有:
- 🗂数据(每个数据点的类别和数量)
- 📊x 轴,表示每个类别的位置(我们需要一个标尺来表示每个类别应该放在哪里)
- 📊y 轴,显示每个数据点的数量(我们需要一个刻度来表示每个数量应该放在哪里)
- ✍🏾长方形
这就是我们使用 Vega 定义上述内容的方式:
{
"$schema": "[https://vega.github.io/schema/vega/v5.json](https://vega.github.io/schema/vega/v5.json)",
"width": 400,
"height": 200,
"padding": 5,
**"data"**: [
{
"name": "our_data",
**"values"**: [
{
"category": "A",
"amount": 28
},
{
"category": "B",
"amount": 55
},
{
"category": "C",
"amount": 43
}
]
}
],
**"scales"**: [
{
"name": "xscale",
"type": "band",
"domain": {
"data": "our_data",
"field": "category"
},
"range": "width",
"padding": 0.05
},
{
"name": "yscale",
"domain": {
"data": "our_data",
"field": "amount"
},
"range": "height"
}
],
**"axes"**: [
{
"orient": "bottom",
"scale": "xscale"
},
{
"orient": "left",
"scale": "yscale"
}
],
**"marks"**: [
{
"type": "rect",
"from": {
"data": "our_data"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "category"
},
"width": {
"scale": "xscale",
"band": 1
},
"y": {
"scale": "yscale",
"field": "amount"
},
"y2": {
"scale": "yscale",
"value": 0
},
"fill": {
"value": "steelblue"
}
}
}
}
]
}
这里可以现场试一下。
让我们来看一下这些定义。我将在这里简要地解释它们,但是我们可以使用更多的属性来定制东西(在使用它们的时候检查一下文档是一个好主意)。
🗂“数据”:[]
我们可以直接在规范中定义数据(就像我们使用"values"
属性一样),或者使用"url"
属性从外部文件(例如 json 或 csv )加载数据。
📈"秤":[]
织女星音阶由 d3 音阶库提供。我们用"type"
关键字指定缩放的类型(默认为线性)。可以通过多种方式指定比例域:
- 一个数据引用对象,它指定一个或多个数据集中的字段值,就像我们对
{"data": "our_data", "field": "amount"}
所做的那样。Vega 从数据集中计算出amount
键的【min,max】数组 - 作为字面数组的域值
- 解析为域值数组的信号参考。比如
{"signal": "myDomain"}
(别急,后面我再讲信号)
📊"轴":[]
这里,我们需要指定用于创建轴的方向和比例。我们可以使用许多属性来定制它们。
✍🏾"标记":[]
我们使用标记通过几何图元(矩形、圆形、直线等)对数据进行编码。在这个条形图中,我们使用了矩形标记。他们需要给定的位置、宽度和高度。我们还需要指定应该使用什么数据来构建标记("from"
属性)。
"from": {"data":"our_data"}
所有关于"x"
、"y"
和"width"
的定义都将来自这个数据集。织女星类型一开始可能看起来有点混乱,所以让我们来看看我们在这里使用的类型:
"x": {"scale": "xscale", "field": "category"}
rects 的"x"
属性将通过从"category"
字段向"xscale"
传递值来设置。
"y": {"scale": "xscale", "band": 1}
每个矩形的"y"
属性将是带刻度xscale
的范围带宽。
"fill": {"value": "steelblue"}
矩形的"fill"
颜色将是钢蓝色。为了定义常量值,我们使用了"value"
属性。
Vega 使用与 d3 相同的进入、更新、退出模式:
当数据第一次被处理并且一个标记实例被新添加到一个场景中时,输入属性被评估。对所有现有的(不存在的)标记实例评估更新属性。当支持标记的数据被移除时,评估退出属性,因此标记离开可视场景。”— 维加文档
我们在"encode"
属性中使用该模式。在这个条形图中,我们在处理数据时放置元素:
**"encode"**: {
**"enter"**: {
"x": {"scale": "xscale", "field": "category"},
"width": {"scale": "xscale", "band": 1},
"y": {"scale": "yscale", "field": "amount"},
"y2": {"scale": "yscale", "value": 0},
"fill": {"value": "steelblue"}
}
}
这就是织女星 101 之旅!为了更好地了解织女星的能力,让我们建立一个时间表。
用织女星构建时间线
A timeline built with Vega
Some Vega properties we'll use to build the timeline
1 — 🗂“数据”:[]
除了加载数据,我们还可以使用 Vega 转换来过滤、计算新字段或导出新数据流。我们可以使用 collect 转换按名称对项目进行排序:
"data": [
{
"name": "libraries",
"format": {
"type": "json",
"parse": {
"release": "date:'%Y'"
}
},
"values": [
{
"name": "vega",
"release": "2013",
"license": "BSD 3-Clause",
"description": "Vega is a visualization grammar, a declarative language for creating, saving, and sharing interactive visualization designs"
},
{
"name": "d3",
"release": "2011",
"license": "BSD 3-Clause",
"description": "D3 (Data-Driven Documents or D3.js) is a JavaScript library for visualizing data using web standards"
},
{
"name": "plotly",
"release": "2012",
"license": "MIT",
"description": "Plotly.js is an open source JavaScript library for creating graphs and dashboards"
}
],
**"transform": [
{
"type": "collect",
"sort": {
"field": "name"
}
}
]**
}
]
Vega 的另一个优点是它可以检查我们用来构建可视化的所有数据的内容:
The dataset sorted by name
2—📈"秤":[]
我们需要一个用于 x 轴的时间刻度和一个顺序刻度来给矩形上色:
"scales": [
{
"name": "xScale",
**"type": "time"**,
**"domain": {
"data": "libraries",
"field": "release"
}**,
"range": "width",
"nice": "year"
},
{
"name": "colorScale",
"**type": "ordinal",**
**"domain": {
"data": "libraries",
"field": "license"
}**,
"range": {
"scheme": "dark2"
}
}
]
3 —📊"轴":[]
让我们在底部放置一个轴,并在标签中显示年份:
"axes": [
{
"scale": "xScale",
**"orient": "bottom",
"format": "%Y"**
}
]
4 — ✍🏾"标记":[]
有三个标记:矩形、矩形内的文本和从每个矩形到轴的线。我们将使用"rect"
、"text"
和"rule"
标记来定义它们。
但首先让我们介绍一个重要的织女星属性:信号。
❗️Signals
信号是动态变量。正如文档所说,信号值是反应性的:它们可以响应输入事件流、外部 API 调用或上游信号的变化而更新。这里我们将使用它们的初始值,但是它们的强大之处在于能够更新它们(我们将在下一次看到如何更新)。
**"signals"**: [
{
"name": "rectWidth",
"value": 50
},
{
"name": "rectHeight",
"value": 40
},
{
"name": "rectY",
"value": 85
},
{
"name": "rectCenter",
"init": "[rectWidth/2,rectY+rectHeight/2]"
}
]
现在我们有了信号,就可以用它们来做标记了。信号也可以持有织女星表情。一个非常常用的是秤:
缩放 ( 名称,值 [,组)
将命名的缩放变换(或投影)应用到指定的值。可选的组参数采用一个场景图组标记项来指示查找比例或投影的具体范围。
在本例中,我们将使用一个表达式将矩形放置在每年的中间,表达式如下:
"signal": **"scale('xScale',datum.release)**-rectWidth/2"
//*scale*(name, value*[*,group*]*
正如我们前面看到的,我们需要指定应该使用什么数据来构建带有"from"
属性的标记。织女星是如此之大,以至于我们可以指定来自另一个标记本身的数据!在这种情况下,我们将使用来自 rect 标记的数据,这样我们就可以获得每个矩形的中心,并将文本放在中间。为了访问数据点,我们在表达式中使用了"datum"
。
"marks": [
{
**"type": "rect"**,
"name": "rectangles",
"from": {
"data": "libraries"
},
"encode": {
"enter": {
"width": {
**"signal": "rectWidth"**
},
"height": {
**"signal": "rectHeight"**
},
"x": {
**"signal": "scale('xScale',datum.release)-rectWidth/2"**
},
"y": {
**"signal": "rectY"**
},
"fill": {
**"signal": "scale('colorScale', datum.license)"**
},
"tooltip": {
**"signal": "{'Description': datum.description}"**
}
},
"update": {
"fillOpacity": {
"value": 1
}
},
"hover": {
"fillOpacity": {
"value": 0.5
}
}
}
},
{
"type": "text",
"name": "labels",
**"from": {
"data": "rectangles" // ⬅️cool
}**,
"encode": {
"enter": {
"text": {
**"signal": "datum.datum.name"**
},
"x": {
**"signal": "datum.x+rectCenter[0]"** //datum.x is from rect
},
"y": {
**"signal": "rectCenter[1]"**
},
"align": {
"value": "center"
},
"baseline": {
"value": "middle"
},
"fontWeight": {
"value": "bold"
},
"fill": {
"value": "black"
}
}
},
"interactive": false
},
{
"type": "rule",
**"from": {
"data": "labels" // ⬅️cool
}**,
"encode": {
"enter": {
"x": {
**"signal": "datum.x"**
},
"x2": {
**"signal": "datum.x"**
},
"y": {
**"signal": "datum.y+rectCenter[0]-5"**
},
"y2": {
**"signal": "height"**
},
"strokeWidth": {
"value": 2
}
}
}
}
]
5 — 💬"传奇":[]
图例定义类似于标记定义。要自定义的可寻址元素有:
legend
为图例组标记,title
为标题正文标注,labels
为标签文字标记,symbols
为图例符号标志,entries
用于符号图例组包含符号/标签对的标记,以及gradient
对于渐变矩形标记:一个带有渐变填充的矩形用于连续渐变图例,多个带有实心填充的矩形标记用于离散渐变图例。
这里我们将只为图例(整个组)设置"x"
位置,并为标题和标签设置字体大小。
"legends": [
{
"title": "License",
"fill": "colorScale",
"orient": "none",
"encode": {
**"title"**: {
"update": {
"fontSize": {
"value": 15
}
}
},
**"labels"**: {
"update": {
"fontSize": {
"value": 12
}
}
},
**"legend"**: {
"update": {
"x": {
"value": 500
}
}
}
}
}
]
6 — ⚙️“配置”和“标题”:[]
config 对象定义默认的可视化值来设置可视化的主题。这里我们为图表的文本设置字体。 title 指令向图表添加描述性标题。
**"config"**: {
"text": {
"font": "Ideal Sans, Avenir Next, Helvetica"
},
"title": {
"font": "Ideal Sans, Avenir Next, Helvetica",
"fontWeight": 500,
"fontSize": 17,
"limit": -1
},
"axis": {
"labelFont": "Ideal Sans, Avenir Next, Helvetica",
"labelFontSize": 12
}
},
**"title"**: {
"text": "Data visualization tools release dates",
"orient": "top",
"anchor": "start",
"frame": "group",
"encode": {
"update": {
"dx": {
"value": -1
}
}
}
}
我们完了。你可以在这里看到代码。
还有一些我们在本教程中没有看到的其他很酷的 Vega 特性:
- 触发:根据信号值修改数据集或标记属性
- 投影:地图(经度、纬度)数据的制图投影
- 事件流:定义输入事件流来指定交互
- 布局:对一组标记进行网格布局
结束语
今天,我在工作流程中使用 Vega 来构建原型,并测试关于数据可视化选择的假设。如果在那之后,我发现我需要一些更加定制的东西,那么我会改变方式,使用 d3。
你可以在这里查看更多织女星的例子:https://vega.github.io/vega/examples/。我们可以在在线 Vega 编辑器中查看所有示例,这太棒了。
就是这样!感谢阅读!😄
用 Python 和 Altair 实现交互式选举可视化
原文:https://towardsdatascience.com/interactive-election-visualisations-with-altair-85c4c3a306f9?source=collection_archive---------16-----------------------
在最*的一篇文章中,我展示了我们如何用 matplotlib 生成 hexmaps 来可视化选举。虽然这些地图很好地展示了如何传达地理信息,但它们并非没有缺陷。例如,可能很难从静态图像中识别出哪个选区是哪个选区,因为要对选区进行操作以使它们大小相等。
在这篇文章中,我们将使用 Altair ,一个声明性的 Python 绘图库,来交付 hexmaps 的改进的交互式版本。你可以用我的 GitHub 上的笔记本来关注这篇文章。
首先,让我们提醒自己,在上一篇文章之后,我们还剩下什么。
阿尔泰尔
Altair 是一个用于 Python 的声明性统计可视化库
本质上,这意味着我们定义我们的数据和输出(图表看起来像什么), Altair 将做所有的操作,把我们从输入带到输出。
与 Python 可视化的主食 matplotlib 相比:对于 hexmap,我们必须明确指定每个六边形的坐标、旋转、大小和颜色。
虽然 matplotlib 对图形的最终状态提供了更多的控制,但实现基本的定制通常比 Altair 花费更多的时间、知识和精力(当然也比人们愿意付出的多)。
Altair 是基于 Vega,一个 JavaScript 绘图库构建的。要渲染交互式图形,您需要一个前端应用程序,如 Jupyter lab。
Altair 可以通过 pip ( pip install -U altair vega_datasets jupyterlab
)或 conda ( conda install -c conda-forge altair vega_datasets jupyterlab
)安装。
数据
在本帖中,我们将展示 2017 年大选后英国议会的构成。这些数据可以从 gov.uk 网站免费获得。该数据具有选区名称,选区,以及获胜政党的名称,政党。
我们已经使用 ODILeeds 的神奇 hexmap 为选区分配了十六进制坐标 p 和 q 。
基本地图
由于 Altair 的声明式风格,在其中生成基本的十六进制地图应该很简单。让我们来测试一下。
import altair as altalt.Chart(data)
.mark_circle()
.encode(
x="q",
y="r",
color=alt.value("lightgray"),
size=alt.value(50),
)
让基本的 matplotlib 地图工作起来需要很多行代码(和很多小时的堆栈溢出);对于牛郎星,是七行。
在 Altair 中,我们首先创建一个包含我们希望使用的数据的Chart
对象。我们用mark_circle()
指定在图表上做什么类型的标记。然后我们用它们应该表示的数据方面对标记的特征进行编码,在这种情况下,我们设置来自数据列 q 的 x 值和来自数据列 r 的 y 值。此外,我们已经使用size=alt.value(50)
将每个圆的大小设置为一个常量。
定义了这几个简单的规则后,Altair 做了所有的脏活,产生了一个精彩的剧情。
诚然,目前这种颜色没有任何意义,也很暗淡。为了解决这个问题,我们需要向 Altair 提供一个将政党名称与特定颜色联系起来的方法。
parties = ["Conservative", "Labour", "Lib Dem", "Green", ...]
party_colours = ["darkblue", "red", "orange", "green", ...] #etc.colours_obj = alt.Color(
"Party:N",
scale=alt.Scale(domain=parties,
range=party_colours)
)alt.Chart(data)
.mark_circle()
.encode(
x="q",
y="r",
color=colours_obj,
size=alt.value(50),
)
alt.Color
对象告诉 Altair 从数据中的方列获取颜色。然而,当事人是字符串,因此不能被解释为颜色;alt.Scale
将域参数中的所有方翻译成范围参数中相应的颜色。这与 matplotlib 形成鲜明对比,matplotlib 必须为每个对象定义一种颜色。
matplotlib 图的一个负面特性是它没有图例:我不知道如何产生一个图例,将迭代绘制的六边形的颜色与一个政党名称联系起来。了解 matplotlib,即使可以给每个六边形添加一个标签,得到的图例也会为每个六边形添加一个条目,而不会注意到重复。
也许并不奇怪,传说在 Altair 中是一件小事——Color
对象会自动生成一个。
基本交互性
至此,我们已经生成了一个取代 matplotlib 版本的地图。然而,它仍然遭受难以识别扭曲的地理边界的问题。除非你在寻找沿海选区,否则你很可能找不到。
我们可以在每个六边形上添加文本来表示选区名称,但这要么太难阅读,要么使情节太大而无法欣赏。我们需要的是把静态图变成交互式的。幸运的是,对于这篇博文来说,Altair 擅长于交互性。
alt.Chart(data)
.mark_circle()
.encode(
x="q",
y="r",
color=colours_obj,
size=alt.value(50),
tooltip=["Constituency:N"],
)
Altair 在一行代码中集成了对工具提示的支持。这是一个强大的特性,可以立即提高图形的可用性。
Oxford: definitely not north of Twickenham
更多互动
当然, Altair 比工具提示提供了更多的交互性。我们将通过鼠标点击获得图表来突出显示某个政党的所有选区,从而对这些额外的产品进行取样。这种行为有助于识别一个团队在整个土地上的分布,否则可能会显示大量的颜色。
我们首先创建一个选择对象,并告诉它我们关心的重要信息是选择的方。我们用add_selection
将这个交互选择元素添加到图表中。
为了改变行为,我们需要用条件参数替换静态标记参数。alt.condition
接受一个条件,一个满足条件时显示的值,一个不满足条件时显示的值。请注意,这种情况下的条件是选择对象。当选择对象的方参数与标记牛郎星试图显示的方参数相同时,满足条件。
selector = alt.selection_single(empty='all', fields=['Party'])colours_condition = alt.condition(selector,
colours_obj,
alt.value("lightgray")alt.Chart(data)
.mark_circle()
.encode(
x="q",
y="r",
color=colours_condition,
size=alt.value(50),
tooltip=["Constituency:N"],
).add_selection(selector)
这个例子突出了 Altair 从复杂的绘图中摆脱了多少痛苦。我们甚至不必使用条件代码来获得条件行为。
组合图表
我们通过展示如何一起显示多个图表来结束这篇文章。我们将添加一个条形图,显示每个政党的议员总数,这一信息很难从我们目前拥有的大量圆圈和颜色中提取出来。
首先,我们创建酒吧。这是一个与之前类似的过程,除了我们使用mark_bars
向 Altair 发出信号,令人震惊的是,我们希望在图表对象上标记条形。还要注意,我们将这个对象赋给了一个变量;我们将对我们的地图图表做同样的事情。
条形的y
值是每一方出现的次数。在其他绘图库中,我们需要在绘图前计算这些;牛郎星会用count()
聚合 帮你做到这一点。
我们还将在图表中添加一条水*线,以显示一个政党拥有多数席位的点。不幸的是,这是 Altair 容易出错的地方:简单地给该行赋予 y 值alt.value(325)
*不会产生正确的结果。相反,我们必须将阈值添加到我们的数据对象中,并告诉 Altair 使用它。
*非技术方面——注:325 票技术上是下议院多数席位的门槛,但由于我们民主制度的“特点”,比如议长和新芬党,实际要求略低。
df["threshold"] = 325
bars = base.mark_bar().encode(
x="Party:N",
y=alt.Y("count()", title="Number of MPs"),
color=colours_condition
)
majority = base.mark_rule(color="black", strokeDash=[1, 1]).encode(
y="threshold:Q",
size=alt.value(3)
)map | (bars + majority)
牛郎星图表对象可以很容易地组合,堆叠或连接。|
操作符水*堆叠图表对象,&
垂直堆叠它们,+
将对象添加到同一个图表中。
后续步骤
在这次对牛郎星的快速浏览中,我们创造了强大的可视化效果,这在其他库中可能要花更多的时间才能完成。
尽管 Altair 可以轻松处理定制和复杂的情节,但它是一个利用率极低的软件包。它的交互性和无需干预的绘图方法可以而且应该使它成为 Python 用户的首选绘图库。
在以后的文章中,我们将详细阐述这些情节,来想象在不同的投票制度下,英国的政治地理会如何演变。
你可以在我的 GitHub 上找到这篇文章中使用的代码。
Excel 中的交互式神经网络乐趣
原文:https://towardsdatascience.com/interactive-neural-network-fun-in-excel-8bad2b3a5d9d?source=collection_archive---------14-----------------------
Constructing CPPNs in Excel with PyTorch and PyXLL
在阅读了 T2 的《让深度神经网络绘画以理解它们如何工作》之后,我受到了启发,开始钻研自己的一些实验。产生的图像很有趣,我想玩一玩,感受一下它们是如何随着神经网络结构的变化而变化的。
我鼓励你回去阅读原文,但作为一个简短的总结,它涉及到使用合成模式产生网络 (CPPN)和随机权重来产生抽象图像。基本思想是,我们构造一个函数 c = f(x,y) ,它获取像素 x,y 的输入坐标,并使用 CPPN 返回该像素的颜色 c 。
Image via Generating Abstract Patterns with TensorFlow
正如在最初的文章中一样,我们将使用 PyTorch 创建一个 CPPN。下面的代码是大量工作的结果,也是我们的起点。
在 512x512 输入数组上运行上述神经网络会产生如下所示的输出图像。用随机权重初始化神经网络,并且缩放输入数组,使得每个输入在+0.5 和-0.5 之间。
Created using a CPPN with random weights
有很多变量会影响最终的图像。从输入的缩放、每个阶段的神经元数量以及神经网络本身的结构。我们可以把这个代码放在一个 Jupyter 的笔记本里,然后在那里修改输入,但是我们所做的每一个修改都是对代码本身的修改,不知何故感觉不太像一个真正的交互体验。
最初,对于这种类型的任务,Microsoft Excel 似乎是一个奇怪的交互式选择。请原谅我……我们想要做的是输入一些信息,比如重量的数量和层数,然后有一个新的图像呈现给我们。本质上,Excel 只是在输入改变时运行函数——这些函数可以做任何事情,甚至在 Excel 中向我们显示图像!如果我们可以在 Excel 中有一个包含我们想要更改的参数的工作表,并且一旦我们做出更改,就会有图像更新,这将是一个很好的体验输入如何影响输出的场所。
在 Excel 中使用 Python
Excel 中的神经网络听起来可能是一项艰巨的任务,但我们不是在谈论在 VBA 实现它!事实上,我们不需要去 VBA 附*的任何地方,因为我们可以继续使用 Python。
PyXLL 是一个 Excel 插件,将 Python 运行时嵌入到 Microsoft Excel 中。它允许我们完全用 Python 编写 Excel 函数,因此我们仍然可以将 PyTorch 用于我们的神经网络,但都是在 Excel 中。拥有所有 Python 工具的访问权限真正开启了 Excel 的潜能。用 Python 编写的软件并没有用 VBA 编码复杂的逻辑,而是简单地暴露给 Excel。Excel 成为我们的前端用户界面工具,Python 负责复杂的计算。
PyXLL 是完全用 Python 编写 Excel 函数的最高性能和最简单的方法,非常适合复杂的工作负载。你可以从 https://www.pyxll.com/download.html 的下载 30 天免费试用版。
在 Excel 中构建神经网络
我们的目标是能够在 Excel 中构建我们的神经网络,并完全控制输入。我们将从编写一些 Python 函数并向 Excel 公开它们开始。大致来说,我们需要的函数是:
- 创建层(nn。线性,nn。Tanh 和 nn。乙状结肠)
- 从一组层创建神经网络(nn。顺序)
- 对一组输入运行神经网络并显示输出
在这个阶段,你可能想知道我们如何在 Excel 中表示这些项目。PyXLL 允许我们在工作簿中的 Excel 函数之间传递 Python 对象,因此拥有一个返回 nn 的 Python 实例的函数。Linear 或另一个接受变换层列表的 Python 函数实际上非常简单。当 Python 对象返回 Excel 时,我们在 Excel 中看到的只是 Python 对象的句柄,当该句柄传递给另一个 Python 函数时,PyXLL 会自动获取该句柄的对象。PyXLL 还管理这些对象的生命周期,因此当不再需要它们时,它们会被自动清理。
为了向 Excel 公开 Python 函数,我们使用 pyxll 模块中的@xl_func 装饰器。下面是我们创建图层需要的第一个函数:
Exposing PyTorch functions to Excel
@xl_func decorator 就是将这些函数暴露给 Excel 所需要的全部!nn_Linear 函数具有类型注释,PyXLL 使用这些注释来确保从 Excel 传递到该函数的类型是正确的,否则从 Excel 传递的数字可能会以浮点数的形式出现。
所需要做的就是将这个模块添加到 PyXLL 配置文件 pyxll.cfg 中。例如,如果您的代码被写入到文件夹“C:\ my code \ py torch-Abstract-Art \ Modules”中名为“pytorch_abstract_art.py”的 Python 模块中,您将使用以下设置更新您的 pyxll.cfg 文件:
[PYTHON]
pythonpath =
C:\MyCode\PyTorch-Abstract-Art\Modules[PYXLL]
modules =
pytorch_abstract_art
我们现在可以从 Excel 中调用这些函数来构建神经网络所需的所有层。所有的输入都输入到 Excel 中,我们甚至可以交互地改变层的数量和顺序。
要构建神经网络,我们只需要另一个函数,它接受这些层并使用 nn.Sequential 返回神经网络。PyXLL 可以接受参数数组以及单个值,因此我们可以将整个层集作为单个参数传递。@xl_func decorator 采用一个可选函数签名来告诉 PyXLL 更多关于参数和预期返回类型的信息。
为了告诉 PyXLL 将传递给它的单元格范围转换成一维对象列表,我们使用了 object[] 类型。如果我们想把一个范围作为一个 2d 的对象列表来传递,我们可以使用 object[][] 类型。当从 2d 范围的单元格展*到 1d 值列表时,PyXLL 从左到右取单元格,因此上图中我们的层的排序将导致正确的排列。
现在,我们可以将新函数 nn_Sequential 添加到 Excel 工作表中,并传入之前创建的层。
创建输出图像
现在剩下的事情就是创建一个输入集,初始化权重,并显示结果图像。
为此,我们将使用 Excel 的对象模型来操作 Excel 中的图像。如果你曾经编写过任何 VBA,Excel 的对象模型正是你可能使用过的,但是你可能没有意识到从 Python 中调用它就像从 VBA 中调用一样容易!指南 Python 作为 VBA 的替代品解释了如何从 Python 中调用 Excel,还涵盖了 VBA 语法和 Python 之间的一些差异。
最后一个函数需要:
- 神经网络对象
- Excel 中图像对象的名称
- 输入的比例和偏移参数
- 随机的种子
要添加显示我们结果的图像,在 Excel 中点击开发者 → 插入 →I 图像(活动 X 控件)。在公式栏的左侧,您会看到图像对象的名称。这将默认为图像 1 ,但是您可以将其编辑为您喜欢的任何名称。
下面的代码从 Excel 获取图像,构造输入,计算输出并更新图像。
完成这最后一个功能后,我们现在可以将它们整合在一起了。构建神经网络的所有输入都显示在工作表上,控制输入数据创建方式的参数也是如此。
我们可以添加或删除层,编辑每个阶段的特征数量,甚至切换激活功能。真正有趣的是,一切都是实时的。只要我们做出改变,图像就会更新。
为了便于阅读,上面的代码中省略了几个函数。您可以在下面找到它们,或者您也可以从 pytorch 文件夹中的 GitHub repohttps://github.com/pyxll/pyxll-examples获得所有代码。
最后的想法
以这种方式在 Excel 中摆弄神经网络真的很有趣。更重要的是,它展示了如何将复杂的 Python 任务无缝集成到 Excel 中。
Excel 的优势在于它是一种用户界面工具,在我看来,它不应该用来存储数据、算法或业务逻辑,因为这些东西可以在其他地方更好地管理。任何使用过 Excel 一段时间或与依赖 Excel 的团队合作过的人都知道 VBA 宏的痛苦,这些宏不能被测试,不能被版本控制,甚至不能在不同用户的工作簿之间保持一致。通过将代码移出 Excel,您不仅可以获得 Python 等现代语言的巨大优势,还可以将现代开发实践应用于电子表格背后的代码。
虽然没有多少人想在 Excel 中实际构建和训练神经网络,但是能够从 Excel 中访问神经网络仍然是有价值的。机器学习之所以有用,很大一部分是因为能够用它来辅助决策。如果决策者已经在使用 Excel,我们可以通过在 Excel 中向他们展示经过培训和测试的机器学习解决方案,让他们轻松使用。这可能是一个大大改进的工作流程,他们使用 Excel 进行一些基本计算,然后使用定制工具或 web 应用程序(或者更糟,给数据科学组的人发电子表格!),然后将这些结果放回 Excel 中——不管您认为您的定制工具有多好,他们都会想这么做;)
您可以从 pytorch 文件夹中的 GitHub repohttps://github.com/pyxll/pyxll-examples下载代码和示例工作簿。你还需要 PyXLL,你可以从https://www.pyxll.com/download.html下载,免费试用 30 天。
使用散景进行交互式绘图
原文:https://towardsdatascience.com/interactive-plotting-with-bokeh-ea40ab10870?source=collection_archive---------20-----------------------
只有几行代码的交互式绘图
Bokeh plot gallery
作为一个 JupyterLab 超级用户,我喜欢使用散景来绘图,因为它的交互式绘图。JupyterLab 还为交互式 matplotlib 提供了一个扩展,但是它速度很慢,而且在处理更大的数据集时会崩溃。
我不喜欢散景的一点是它铺天盖地的文档和复杂的例子。有时,我想做一个简单的线图,但我会纠结于 Bohek 特定代码的 10 行或更多行。但是散景代码可以非常简洁,我将在下面展示。这也是主要目标,用尽可能少的代码展示一些有用的数据可视化。
这里有几个你可能会感兴趣的链接:
- [Labeling and Data Engineering for Conversational AI and Analytics](https://www.humanfirst.ai/)- [Data Science for Business Leaders](https://imp.i115008.net/c/2402645/880006/11298) [Course]- [Intro to Machine Learning with PyTorch](https://imp.i115008.net/c/2402645/788201/11298) [Course]- [Become a Growth Product Manager](https://imp.i115008.net/c/2402645/803127/11298) [Course]- [Deep Learning (Adaptive Computation and ML series)](https://amzn.to/3ncTG7D) [Ebook]- [Free skill tests for Data Scientists & Machine Learning Engineers](https://aigents.co/skills)
上面的一些链接是附属链接,如果你通过它们进行购买,我会赚取佣金。请记住,我链接课程是因为它们的质量,而不是因为我从你的购买中获得的佣金。
没听说过散景?
其网站上的描述很好地总结了这一点:
Bokeh 是一个交互式可视化库,面向现代 web 浏览器进行演示。它的目标是提供优雅、简洁的通用图形结构,并通过超大型或流式数据集的高性能交互来扩展这种能力。散景可以帮助任何人快速轻松地创建交互式绘图、仪表盘和数据应用程序。
你可以通过下载这个 Jupyter 笔记本来运行这段代码。
要求
import bokeh
import numpy **as** np
from bokeh.models import Circle, ColumnDataSource, Line, LinearAxis, Range1d
from bokeh.plotting import figure, output_notebook, show
from bokeh.core.properties import value
output_notebook() *# output bokeh plots to jupyter notebook*
np**.**random**.**seed(42)
生成数据
让我们使用 numpy 生成一些随机数据。Bokeh 有自己的数据结构(ColumnDataSource)用于数据表示。我不知道他们为什么开发自己的数据结构,因为 pandas 和 numpy 是 Python 分析世界中事实上的标准(如果你知道,请在下面的评论中启发我)。但幸运的是,它也适用于熊猫。对于这篇博文,我决定用 Bokeh way 的数据结构来写例子。
N **=** 100
data_source **=** ColumnDataSource(
data**=**dict(
x0**=**np**.**arange(N),
x1**=**np**.**random**.**standard_normal(size**=**N),
x2**=**np**.**arange(10, N **+** 10),
x3**=**np**.**random**.**standard_normal(size**=**N),
)
)
简单线图
要在 Bohek 中制作一个简单的线图,我们需要 3 行代码。那还不算太糟。请注意,该图是交互式的,我们可以放大和移动,这对于较大的数据集非常有用。
p **=** figure()
p**.**line("x0", "x1", source**=**data_source)
show(p)
A simple line plot with Bohek
双轴折线图
为了在图上显示两个具有不同范围的数据列,我们可以使用两个独立的 y 轴。我们可以设置 y 轴范围,但这不是必需的。我使用数据列的最小值和最大值作为 y 轴限制。为了直观地分隔数据列,我们可以添加图例并设置颜色。
p **=** figure()
column1 **=** "x1"
column2 **=** "x2"*# FIRST AXIS*
p**.**line("x0", column1, legend**=**value(column1), color**=**"blue", source**=**data_source)
p**.**y_range **=** Range1d(data_source**.**data[column1]**.**min(), data_source**.**data[column1]**.**max())*# SECOND AXIS*
column2_range **=** column2 **+** "_range"
p**.**extra_y_ranges **=** {
column2_range: Range1d(
data_source**.**data[column2]**.**min(), data_source**.**data[column2]**.**max()
)
}
p**.**add_layout(LinearAxis(y_range_name**=**column2_range), "right")p**.**line("x0", column2, legend**=**value(column2), y_range_name**=**column2_range, color**=**"green",source**=**data_source)show(p)
A line plot with two axes
组合折线图和散点图
这才是散景真正出彩的地方。您可以简单地定义多个元素,并在图上渲染它们。
p **=** figure()
p**.**line(x**=**"x0", y**=**"x1",color**=**"blue", source**=**data_source )
p**.**circle(x**=**"x0", y**=**"x3",color**=**'green', source**=**data_source)
show(p)
A line plot and scatter plot
最后的想法
散景是非常可定制的。你可以调整所有你期望从绘图库中得到的东西,比如线宽、颜色、网格上的多个绘图等等。它提供了特殊的绘图,如用于金融数据的烛台,Burtin 可视化,你甚至可以制作一个周期表。Bokeh 独有的(至少据我所知)选项是将情节导出到 javascript 代码,这使您可以直接将情节嵌入到具有所有交互功能的网页中。
在你走之前
在 Twitter 上关注我,在那里我定期发布关于数据科学和机器学习的。
您可能会对以下几个链接感兴趣:
- [Data Science Nanodegree Program](https://imp.i115008.net/c/2402645/788185/11298)- [AI for Healthcare](https://imp.i115008.net/c/2402645/824078/11298)- [School of Autonomous Systems](https://imp.i115008.net/c/2402645/829912/11298)- [Your First Machine Learning Model in the Cloud](https://gumroad.com/l/mjyDQ)- [5 lesser-known pandas tricks](https://gumroad.com/l/YaaJn)- [How NOT to write pandas code](https://gumroad.com/l/vxxiV)- [Parallels Desktop 50% off](https://www.dpbolvw.net/click-100126493-14105294)
交互式 Q 学习
原文:https://towardsdatascience.com/interactive-q-learning-9d9203fdad70?source=collection_archive---------24-----------------------
了解 Q 表的最佳方式…
Give me maximum reward 😃
去玩 @ 互动 Q 学习
代号 @ 莫希特的 Github
介绍
在经历了解 Q 学习的过程中,我总是对网格世界(由盒子组成的 2D 世界,代理从一个盒子移动到另一个盒子并收集奖励)着迷。几乎所有强化学习的课程都从 Q 表的基本介绍开始,最直观的 Q 表例子是网格世界。也就是说,很多球场只是画出了它们的静态世界,并没有给观众提供任何游戏素材。为了解决这个问题,我想到了创建一个交互式网格世界,用户可以定义世界、状态和代理。这将有助于用户复制课程的网格世界,理解它实际上是如何工作的,甚至会问——当你改变固定变量时会发生什么?我们开始吧!
交互式网格世界
Interactive grid world
交互式网格世界分为两个主要区域,
- 游乐场:由盒子或状态组成,动作发生在那里。
- 设置:由多级设置组成,您可以通过这些设置来设计和控制游乐场。
让我们通过浏览可用的设置来理解网格世界的动态。设置区域可以进一步分为:
The 4 subsections of settings.
- Gridworld 级别设置:由改变整体世界格式的设置组成,包含-
—大小:选择世界的大小。“大”意味着更多的州。
—速度:选择加工速度。当我们想快速得到最终结果时,“快”是好的,但是“慢”是直观形象化的最佳选择。
- 状态级别设置:帮助设计单个状态及其行为,包含-
—奖励值:分配给点击状态的奖励。
—状态类型:状态的类型。“终结”——基本上是游戏结束状态,代理在进入终结状态时完成当前剧集。‘墙’——一个没有奖励的固定状态,一个代理人不能跨越。‘正常’—默认状态类型。
—应用于所有:将当前奖励值和状态类型应用于网格世界中所有盒子的快捷按钮。
- 代理级别设置:定义了代理的学习行为,包含-
— 折扣:适用于未来奖励的折扣。默认值为 0.9。
— 确定性:定义代理人动作的确定性概率。1 表示从一个盒子的“右”将总是导致右边的盒子。而 0.7 意味着只有 70%的机会发生这种情况,10%的机会去任何相邻的州。(对于数学爱好者来说,还有 3 个相邻的状态,因此 10 * 3 = 30 %完成了 100%)
— E-greedy :定义代理的利用/探索性质。0 表示代理是完全贪婪的,并且总是选择可用的最佳动作。1 表示代理是完全随机的,可以从任何可用的操作中进行选择。为了了解更多关于ε贪婪的信息,我建议浏览一下我之前的帖子,用多臂强盗进行强化学习。
- 执行类型设置:控制世界的流动,包含-
— 运行/停止:让代理在 gridworld 里面玩。切换开关。
— 复位:回到初始设置和动态。
— 显示/隐藏策略:切换策略方向箭头的可见性。
— 显示/隐藏高亮显示:切换当前状态高亮显示的可见性。
怎么玩?
让我们举一些例子来更好地理解这一点。
示例 1: 第一个示例可以是我之前关于用 Q 表进行强化学习的帖子中的“啤酒游戏”。我建议通读这篇文章,对 Q 表有一个基本的了解。世界看起来是这样的,
The beer game
我们希望代理人学会总是带着啤酒去那个州,而不是带着洞去那个州。让我们在交互式网格世界中重现这一场景,
Solving example 1 on interactive grid world
最后,网格世界看起来像这样,
Agent’s expected rewards and policy after convergence for example 1.
例子 2 :我们从 Udemy 的人工智能课程中举一个例子。世界看起来是这样的,
Green flags have reward of 1 and the state with fire has negative reward, say -1.
The policy learned after convergence.
上图中的预期状态奖励(V)以及方向(政策)是在经过多次迭代训练后获得的。让我们试着复制这个世界,
Solving example 2 on interactive grid world
最后,网格世界看起来像这样,
Agent’s expected rewards and policy after convergence
将这个与课程幻灯片中显示的进行比较,它是完全相同的!
结论
这个项目还远没有结束!有很多东西我想补充,但我想它们会随着时间的推移而出现。当前版本可能有一些错误,因此如果出现任何不想要的行为,请求助于最后的选项——刷新页面并在 GitHub :)报告问题。除此之外,请继续尝试。
参考
[1] Udemy 的人工智能 A-Z:学习如何构建人工智能
[2] 加州大学柏克莱分校 CS188 人工智能简介
[3] 由 安德烈·卡帕西 加固. js
干杯!
Jupyter 中的交互式电子表格
原文:https://towardsdatascience.com/interactive-spreadsheets-in-jupyter-32ab6ec0f4ff?source=collection_archive---------1-----------------------
ipywidgets 在 Jupyter 生态系统中起着至关重要的作用;它带来了用户和数据之间的交互性。
小部件是多事件的 Python 对象,通常在 Jupyter 记事本或 JupyterLab 中有一个可视化的表示:一个按钮、一个滑块、一个文本输入、一个复选框…
不仅仅是一个交互式小部件库,ipywidgets是一个强大的框架,在这个框架上可以直接创建新的定制小部件。开发人员可以使用widget-cookiecutter项目,利用代码结构和打包的最佳实践,快速启动自己的 widgets 库。****
你可以在博客文章中找到非常好的小部件库的例子:Jupyter 笔记本中的视频流 。
电子表格是一种以表格形式进行数据分析的交互式工具。它由单元格和单元格区域组成。它支持数值相关的单元格格式/样式,可以对单元格应用数学函数并执行链式计算。它是统计和财务操作的完美用户界面。
Jupyter 笔记本缺少一个电子表格库,这就是 ipysheet 发挥作用的时候。
ipysheet
ipysheet 是一个新的交互式部件库,旨在实现一个好的电子表格应用程序的核心特性等等。
ipysheet 中有两个主要的小部件,分别是单元格小部件和工作表小部件。我们提供了创建行、列和单元格区域的辅助函数。****
单元格值可以是布尔值、数值、字符串、日期,当然还有另一个小部件!
ipysheet 使用类似 Matplotlib 的 API 创建工作表:
用户可以创建整行、整列甚至单元格区域:
当然,单元格中的值是动态的,单元格值可以从 Python 中动态更新,新值将在工作表中可见。
可以将单元格值链接到小部件(在下面的屏幕截图中,FloatSlider 小部件链接到单元格“a”),并根据其他单元格将特定单元格定义为自定义计算的结果:
可以使用自定义样式,使用我们称之为的渲染器 s:**
添加对 NumPy 数组和 Pandas 数据帧加载和导出的支持是我们想要的一个重要特性。ipy sheet为此提供了 from_array、to_array、from_dataframe 和 to_dataframe 函数:
另一个致命的特性是单元格值可以是任何交互式小部件。这意味着用户可以在单元格中放置一个按钮或滑块小部件:
但这也意味着可以在单元格中放置更高级别的小部件。无论小工具是来自 bqplot 的绘图、来自 ipyleaflet 的地图还是来自 ipyvolume 的多体渲染:
你现在可以用活页夹来试试,不需要在你的电脑上安装任何东西,只需点击这个按钮:
源代码托管在 Github:https://github.com/QuantStack/ipysheet/
类似项目
- ipyaggrid 是一个小部件库,用于导入/编辑/导出熊猫数据帧: 利用 Jupyter 中 ag-Grid 的力量
- qgrid 是一个交互式网格,用于分类、过滤和编辑 Jupyter 笔记本中的熊猫数据框。
感谢
ipysheet 的开发由 QuantStack 牵头。
这项开发由法国兴业银行和 彭博 赞助。
关于作者
Maarten Breddels是一名企业家和自由职业开发人员/顾问/数据科学家,主要在 Jupyter 生态系统中使用 Python、C++和 Javascript。 的创始人 vaex.io 。他的专业领域从快速数值计算、API 设计到 3d 可视化。他拥有 ICT 学士学位,天文学硕士和博士学位,喜欢编码和解决问题。**
马丁·雷诺 是科学软件工程师quant stack。在加入quant stack之前,他就读于法国航空航天工程学校SUPAERO。他还在巴黎的 Logilab 和剑桥的 Enthought 工作。作为一名在quant stack工作的开源开发者,Martin 参与过各种项目,从xsimd,xtensor,x frame, xeus****
使用 Dash 和 Plotly 进行交互式可视化
原文:https://towardsdatascience.com/interactive-visualization-with-dash-and-plotly-29eaccc90104?source=collection_archive---------9-----------------------
交互式数据可视化对探索性数据分析有着重要的影响。在对数据集应用任何描述性或预测性算法之前,我们必须首先了解各要素之间的相互关系以及它们在内部的分布情况。很明显,许多可视化库提供了许多类型的图表来满足这一需求。但另一个显而易见的事情是,为每个特性做同样的绘图工作并滚动每个图表来比较每个特性的结果是一件困难的工作。
在过去的几周里,我不得不做这么多的工作,以至于我不得不为此寻找一条捷径。是的,我是一个懒惰的人,是的,懒惰是创造力的关键。这就是我如何遇到 dash 和 plotly 作为我的问题的解决方案。在这篇文章中,你会发现这对夫妇如何成为探索性数据分析的良好解决方案。
让我先解释一下 dash 和 plotly 是给以前没听过的人的。Plotly 是一家数据分析和可视化公司。在本文中,我们对该公司的两个 python 库感兴趣;plotly.py 和 dash。 Plotly.py 库为 python 应用提供了交互式可视化。正如他们网站上所说,你可以用 Python 创建交互式、D3 和 WebGL 图表。所有的图表类型 matplotlib 等等
Dash 也是该公司的另一个产品,它为构建基于 web 的 Python 应用程序提供了一个框架。如果你正在和一个团队一起工作,或者只是想和其他人分享你的工作,web 应用程序是最简单的方法,消除了库版本或接口问题。在接下来的写作中,我们将会看到在网络上分享我们的发现是多么的方便。
所以,让我们开始编码吧…
简单的 Dash 应用程序
下面是一个简单的 dash web 应用程序,由六行代码组成。只要把它写在一个. py 文件中,然后调用这个文件,你的应用就启动并运行了,就这样。
#this is the dash_test.py fileimport dash
import dash_html_components as htmlapp = dash.Dash(__name__)app.layout = html.H1('hello dash')if __name__ == '__main__':
app.run_server(debug=True, port=8080)
使用文件的确切路径,从命令提示符调用该文件,如下所示。您将看到一个控制台窗口,告知服务器正在运行。
python "c:\users\alper\documents\dash_test.py"
我们现在可以打开一个 web 浏览器,导航到带有给定端口号 127.0.0.1:8080 的本地主机 url。
在前两行代码中,我们简单地导入所需的 dash 库。第三行初始化 dash 应用程序,第四行用我们将在页面上显示的 header 标记准备页面布局,最后两行用调试和端口选项运行服务器。(参见 stackoverflow 上“if name …”行的详细解释)
是的,我们离交互性和可视性都还很远,但是请耐心等待,我们正在前进。首先,我们放置所需的元素。为此,我们将修改 app.layout 并在 div 中插入一个按钮和一个 label 元素。注意,这两个元素作为 div 元素的子元素放在一个列表中。Dash 在 dash_html_components 库中存储 html 元素,你可以在他们的网站和 github repo 上找到完整的列表。
app.layout = html.Div(
[
html.Button('create random number', id='button1'),
html.Label('...', id='label1')
]
)
当我们保存文件时,我们将在控制台窗口上看到一个新的行,带有一个新的调试器 pin。如果代码中有问题,我们将会看到错误消息。在这种情况下,我们需要再次调用文件并刷新浏览器。
现在,让我们给已经插入的元素添加一些样式。我不能说我擅长造型,但我相信你可以做得更好。我们可以用 style 属性向元素添加样式,接受 css 标签的字典。
html.Button('create random number',
id='button1',
style={'display':'block', 'background-color':'#aabbcc'}
),
html.Label('...',
id='label1',
style={'display':'inline-block', 'margin':'10'}
)
现在是时候更进一步,增加一些响应能力了。首先,我们导入所需的库
from dash.dependencies import Input, Output
import random
然后我们添加回调装饰器和我们希望在回调时执行的函数。
[@app](http://twitter.com/app).callback(
Output(component_id=’label1', component_property=’children’),
[Input(component_id=’button1', component_property=’n_clicks’)]
)
def update_output(input_value):
return random.random()
update_output 函数只是生成一个随机数并将其作为结果返回。
@app.callback decorator 将按钮 click 事件绑定到 update_output 函数,将函数的结果绑定到 label1 元素。这是响应性的核心部分。关于回调和状态参数将会有另一篇文章。
添加简单图表
既然我们已经介绍了足够多的交互性,现在是时候添加一些图表了。首先,我们将保持它的简单性,并在每个按钮点击上放一个随机值的条形图。因此,我们需要在布局中添加一个图形对象:
app.layout = html.Div(
[
html.Button(‘create random number’,
id=’button1',
style={‘display’:’block’, ‘padding’:’5', ‘background-color’:’#aabbcc’}),
html.Label(‘…’,
id=’label1',
style={‘display’:’inline-block’, ‘margin’:’10'} ),
dcc.Graph(id=’graph1') # this is the graph we add
]
)
我们需要修改回调函数来生成图表:
[@app](http://twitter.com/app).callback(
Output(component_id='graph1', component_property='figure'),
[Input(component_id='button1', component_property='n_clicks')]
)
def update_output(input_value):
random_x = [i for i in range(5)]
random_y = [random.random() for _ in range(5)]
figure = {
'data': [
{'x':random_x, 'y':random_y, 'type':'bar', 'name': 'Series1'}
],
'layout': {
'title': 'Dash Data Visualization'
}
}
return figure
在回调装饰器中,我们首先用最*添加到布局中的 graph 对象替换输出语句中的标签。然后在函数内部,我们为图表和图形对象创建 x 和 y 值。仅此而已。结果是在你的浏览器中出现一个交互式的条形图。
更复杂一些
如果上面的图表对你来说不够花哨,不要担心,这里有另一个例子给你。让我们再深入一些。
是不是太快了?好的,让我们看看代码。
# coding=utf8import random
import pandas as pd
import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc
import plotly.graph_objs as go
app = dash.Dash(__name__)
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class']
data = pd.read_csv('[https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'](https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'), names=names)
app.layout = html.Div(
[
html.Div([
dcc.Dropdown(
id='ddl_x',
options=[{'label': i, 'value': i} for i in names],
value='sepal-width',
style={'width':'50%'}
),
dcc.Dropdown(
id='ddl_y',
options=[{'label': i, 'value': i} for i in names],
value='petal-width',
style={'width':'50%'}
),
],style={'width':'100%','display':'inline-block'}),
html.Div([
dcc.Graph(id='graph1')
],style={'width':'100%','display':'inline-block'})
]
)
[@app](http://twitter.com/app).callback(
Output(component_id='graph1', component_property='figure'),
[
Input(component_id='ddl_x', component_property='value'),
Input(component_id='ddl_y', component_property='value')
]
)
def update_output(ddl_x_value, ddl_y_value):
figure={
'data': [
go.Scatter(
x=data[data['class'] == cls][ddl_x_value],
y=data[data['class'] == cls][ddl_y_value],
mode='markers',
marker={ 'size': 15 },
name=cls
) for cls in data['class'].unique()
],
'layout':
go.Layout(
height= 350,
hovermode= 'closest',
title=go.layout.Title(text='Dash Interactive Data Visualization',xref='paper', x=0)
)
}
return figure
if __name__ == '__main__':
app.run_server(debug=True, port=8080)
代码结构和前面的完全一样。初始化应用程序后,
- 我们增加了两行数据读取。
- 在 app.layout 部分,我们添加了两个下拉列表,并用数据列循环填充选项。
- 在@app.callback 装饰器中,我们添加了这两个下拉菜单作为输入组件
- 在 update_output 函数中,我们用下拉列表选择的数据和列绘制了一个散点图。这里,有一个棘手的部分。我们为每个类绘制散点图。你看,go 的末尾有一个 for 循环。Scatter()函数和“数据”列表中。这个 for 循环也称为 list comprehension,它返回 Scatter()对象 n 次,其中 n 是数据的“class”列中唯一记录的数量。下面一行是图表的布局属性。
代码准备好运行了。就;
- 将其保存到一个文件中。py 扩展名,--> " c:\…\ dash _ test . py "
- 使用 python-> python " c:\…\ dash _ test . py "通过命令提示符调用它
- 打开浏览器,导航至应用-> http://localhost:8080
您的交互式数据可视化应用程序只需 60 行代码即可完成。
这是我第一次在媒介上写作。我会继续写我所学到的东西。请分享你的感受,这样我可能会提高自己。
资源:
- https://dash.plot.ly/
编辑:
- 走吧。布局值在 update_output 函数下的 figure 对象的数组内传递。这导致了一些版本的 javascript 错误。移除数组并通过 go。布局对象直接解决了问题。2019/06/20
在浏览器中使用基本 Scala 交互式浏览 Reddit 帖子
原文:https://towardsdatascience.com/interactively-exploring-reddit-posts-using-basic-scala-in-your-browsers-f394843069de?source=collection_archive---------22-----------------------
本文继续我们的 Scala 之旅。在这些练习中,您将使用您编写并在浏览器中运行的基本 Scala 代码片段来分析实际的 Reddit 帖子。你甚至会发现 Redditors 的一些令人惊讶的行为。
这是我们 Scala 之旅的第三部分。如果你刚来,想从头开始,请查看通过计算机程序实例的结构和解释快速学习 Scala 的基础知识。
今天我们将围绕实际的 Reddit 数据做一些新颖的编程练习。我准备了 2018 年 10 月份的大约一万篇帖子的随机样本,让我们通过在本文的小部件中编写基本的 Scala 来交互式地探索。
这是我们将要编写的用于分析 Reddit 帖子的一些 Scala 的预览。
让我们深入研究并弄清楚如何访问这些数据,对其进行计算,从而通过直接在浏览器中编写和运行 Scala 代码来分析 Redditors。
以下代码从 web 服务器获取 Reddit 帖子数据,并显示了 Reddit 数据的前几行。代码中有一些新的 Scala 概念,我们今天不需要理解,因为我们只是使用代码来获取 Reddit 数据。相反,我们将专注于我们编写的探索数据的代码。
旁白:这通常是一个很酷的编程特性:我们通常可以使用其他程序员开发的库中的函数来为我们执行计算,即使我们不理解库中代码的细节。专业软件工程师通常在他们的工作中特别使用库,这样他们就不必学习如何解决别人已经解决的编程问题的细节。
在下面的小部件上点击“运行”,运行代码并查看结果。
(注意,如果您发现 ScalaFiddle 小部件在嵌入式表单中过于水*压缩,您可以单击本文中任何 ScalaFiddle 小部件上的“编辑 ScalaFiddle”。在这种情况下,你会发现 ScalaFiddle 网站上的演示更具可读性。)
很酷,我们可以很容易地访问这些有趣的数据,对不对?现在,让我们弄清楚如何探索数据和计算新奇的结果,为 Redditors 提供有趣的见解。
我们接收的数据是一个很长的字符串。您可以修改前面 ScalaFiddle 小部件中的 Scala 代码来调用字符串上的.length
并打印字符数。也就是说,我们将修改代码底部的匿名函数,使其具有以下形式。
运行它,您会看到数据字符串包含不到一百万个字符。因此,我们有一些重要的数据要处理。
让我们再次看看这个例子,看看我们将如何处理这个长字符串。
MarioAI,nicolasrene,recreation of Mario facing left since i havent got the original picture not the real thing but he did face left once in 1-2...,1
u_seksualios,seksualios,Seksuali gundanti ištvirkėlė Alektra Blue juodais drabužiais,1
Cuphead,[deleted],Just finished Cuphead in an hour and fifteen minutes.,0
videos,lonemonk,Trump On The Traps - Calvin Dick (2017),1 CryptoCurrency,Pseudoname87,Why does binance show a different price than other sites?,1
此文本数据采用逗号分隔值(CSV)格式。传统上,这种数据显示为表格。
我们可以看到文件的每一行都对应一篇文章。因此,首先,我们要将这个字符串按行分解,以访问每个帖子的单独行。我们可以使用 string 方法split
根据特定的拆分字符将一个字符串拆分成子字符串。为了拆分成行,我们将使用换行符"\n"
作为拆分字符。
最后,我们将使用toList
将split
的返回值转换成一个列表,并显示行数。您可以返回 ScalaFiddle 小部件,将我们的处理代码修改如下。
结果显示,我们在这个数据中有大约 11,000 个 Reddit 帖子。
现在,我们仍然有一些工作要做,为编程探索准备我们的数据,因为每个 Reddit 提交包含多个属性。回到示例,我们看到每一行都是每个帖子的逗号分隔的值字符串。这些属性依次为:
- 子编辑:帖子提交到的子编辑
- 作者:发布提交内容的用户账号
- 标题:文章的标题
- 得分:数据被提取时提交的投票得分
我们将再次使用String.split
来访问每个帖子的各个字段,这次使用","
作为拆分字符。
我们想要一种方法来组织单个帖子的所有不同属性,为此,我们可以创建一个 Scala class
。在高层次上,类只是允许我们将相关的数据元素组织在一起,就像 Reddit 帖子的不同属性一样。下面是我们如何为这些数据定义一个类。
这里有一个我们如何使用 Post 类的例子。随意修改代码,感受一下我们的Post
数据类型。
我们将在以后更详细地介绍这些课程。现在,知道这个类定义了一个新的数据类型来表示 Reddit 帖子就足够了,每个帖子有四个属性:subreddit、author、title 和 score。
现在,让我们修改处理代码,将原始数据解析成一个帖子列表。即创建一个List[Post]
。
现在我们有了一个val posts: List[Post]
的帖子列表。所以让我们开始探索这个 Reddit 帖子数据吧!
首先,让我们统计一下单个子编辑的帖子数量。您可以将以下代码添加到前面 ScalaFiddle 小部件中的处理器函数中。
这里我们使用List
的filter
方法来创建一个新列表,该列表只包含来自子编辑“AskReddit”的帖子。一般来说,我们可以使用filter
和我们编写的任何函数来选择List
的元素,从而创建一个新的List
,它只包含那些感兴趣的元素。
您可以随意修改代码来计算我们的示例中您感兴趣的任何子编辑的帖子数量。
在这个练习的基础上,让我们计算每个子编辑的帖子数量。在这个计算中,我们将构建一个数据结构,将每个子编辑与其帖子计数相关联。这就需要我们引入一个新的 Scala 数据结构,叫做Map
。
Map[K, V]
是类型K
的键与类型V
的值之间的关联。在本练习中,我们将构建一个Map[String, Int]
来将 subreddit 名称与帖子数量关联起来。以下是我们如何使用这种地图的一些例子。
您能否添加代码来创建将值为12
的键"new key"
添加到我们的val map: Map[String, Int]
中的forthMap
?
对于熟悉其他编程语言的人来说,看到Map.updated
返回另一个新的Map
可能会很惊讶。一般来说,Scala 鼓励我们使用不可变的数据结构,因此我们避免修改任何东西。相反,我们创建新的数据结构来表示任何变化的结果。Scala 在幕后做了一些非常聪明的事情,使得这种更新在处理时间和内存使用方面都很有效。
注意Map[K, V].get(key)
返回一个Option[V]
。Option
用于说明给定的key
可能没有值。Option
是一种通用数据类型,它有两种形式:Some(value)
和None
。Some(value)
表示我们确实有这个键的值,我们可以通过Some.get
访问这个值。而None
表示该键没有值。
Option
有一个有用的方法getOrElse(alterantive)
。当在Some
上被调用时,它返回包含在Some
中的值并忽略alterantive
。而None.getOrElse(alternative)
返回alternative
的值。我们将在代码中使用这个方法,当我们获取当前还没有计数的子编辑的计数时,用零替换None
。
使用Map
,下面是我们如何计算每个子编辑的帖子数量。
请注意我们是如何使用foldLeft
(一种fold
的变体)来处理每个帖子并增加 map 中相应子编辑的计数的。您可能还记得,fold
用于将列表中的所有值聚合成一个值。在这种情况下,最终值是一个Map[String, Int]
,它将子编辑与它们的帖子计数相关联。
关于fold
函数的快速复习:我们用聚合的初始值和折叠函数调用foldLeft
。fold
为列表中的每个元素调用我们的折叠函数。在每次调用中,folding 函数还接收聚合的当前值。我们的函数返回包含列表元素的聚合的更新值。在使用我们的折叠函数处理了列表中的每个元素之后,fold
函数返回聚合的最终值。
花点时间回顾一下这段代码,看看你是否能理解我们是如何计算每个子编辑的帖子数量的。作为练习,您能修改这个示例代码来计算每个用户的帖子数量吗?
虽然当前的结果不错,但我们更想知道顶部子街道的结果;即在 Reddit 帖子的这个样本中具有最多帖子的那些人。为此,我们需要一种方法来根据帖子的数量对子编辑进行排序,这样我们就可以选择显示前几个子编辑。在计算机科学术语中,这样的过程被称为排序。
您可以将下面的代码添加到前面的示例中,按照帖子数量对子 Reddit 进行排序,然后显示 Reddit 帖子示例中的前 10 个帖子。
这里正在发生一些新的事情。首先,我们使用Map.toList
方法将subredditCount
从Map[String, Int]
转换为List[(String, Int)]
。这引入了一个叫做元组的新概念,因为(String, Int)
是长度为 2 的元组的类型,其中第一个元素是字符串,第二个元素是整数。
元组是 Scala 中的一种通用数据类型,可以用来表示固定长度的元素集合,其中每个位置都有一个固定的类型。例如(String, String, String, int)
是一个长度为四的元组。我们可以使用这种元组类型而不是类Post
来表示单个 Reddit 帖子中的数据。
一般来说,类是将相关元素组合在一起的更清晰的方式。元组在某些情况下很有用,特别是在我们想要编写使用占位符类型的泛型算法的情况下。这就是需要一个通用方法来转换相关对列表中的一个Map[K, V]
,List[(K, V)]
的情况。
接下来,我们使用方法sortBy
对元组列表进行排序。该方法采用一个函数来计算列表中每个元素的排名分数。列表的元素按等级排序,并且由sortBy
返回一个新的列表,其中元素被排序。您可以看到,我们的排名函数只是通过访问元组的第二个元素t._2
来获取每个子元组的计数。
我们的 Reddit 帖子示例的结果如下。
(AskReddit,254)
(AutoNewspaper,214)
(The_Donald,84)
(CryptoCurrency,71)
(SteamTradingCards,69)
(RocketLeagueExchange,65)
(newsbotbot,65)
(videos,64)
(GlobalOffensiveTrade,59)
(PewdiepieSubmissions,58)
在考虑数字时,我们应该记住这是所有 Reddit 帖子的一个小的随机样本,所以计数将比帖子的总数小得多。我们的样本是 2018 年 10 月所有 Reddit 帖子的 0.1%样本,因此我们可以将这些数字乘以 1000,以估计本月每个 subreddit 的帖子总数。
凭借我对 Reddit 的熟悉,我可以说这些结果似乎与我对“AskReddit”等流行子编辑的直觉一致。你怎么想呢?
您能否修改之前计算每个作者的文章数量的练习代码,以便对结果进行排序?Reddit 帖子样本中的顶级作者是谁?
接下来,让我们看看我们的示例是否包含标题中带有 Scala 的帖子。您可以将下面的代码片段添加到前面的 ScalaFiddle 小部件中来回答这个问题。
你对这些帖子有什么看法?它们中的每一个都是关于 Scala 的吗?或者使用这种启发式方法以编程的方式识别相关的帖子是否有缺陷?我们将很快考虑更复杂的方法来分析帖子。
还有哪些词让你感兴趣?修改代码,因为你想寻找其他职位有某些关键字。在许多方面,我们正在构建一个简单的、定制的搜索引擎,以便在这个小样本中找到与我们的兴趣相关的帖子。
注意,我自己也发现了大量的淫秽语言。作为练习,您可以编写一些 Scala 代码来查找包含脏话的帖子。我不包括这方面的示例代码,因为我不想在我的博客上有一个诅咒词的列表。😃
一般来说,我们感兴趣的是计算文章标题中不同单词在每个子编辑中的出现频率。这里有一些相当复杂的代码来完成这样的分析。
花些时间仔细思考这个例子。这是对目前为止我们在当前和过去的文章中考虑的许多概念的一个很好的回顾。提醒一下,你可以点击小部件上的“在 ScalaFiddle 上编辑”,在一个没有小部件水*压缩的单独窗口中打开例子,以便更好地阅读代码。
示例代码包括一些我们还没有探索的概念。如果你愿意,你可以自己探索这些概念——在我们共享 Scala 之旅之前——使用 scala-lang.org 的资源。总的来说,这个网站是学习 Scala 概念的好地方。当然,一般的谷歌搜索也可以找到一些有用的资源,包括 StackOverflow 问题和答案。
目前我想解释的一件事是,这个代码示例是如何使用模式匹配的两种情况来解构数据结构的。在这些情况下,我们通过模式匹配解构来访问元组的元素。这里有一个在函数中解构元组的孤立例子。
你可以看到我们以非标准的方式定义了这个函数。一般来说,我们主要在匿名函数中使用这种模式,这就是我们在词频示例中所做的。
除了分析 Scala 代码,你对这些结果有什么看法?根据你对 Reddit 的了解,词频结果看起来合适吗?在某些子街道的高频词中有什么令人惊讶的结果吗?
你可以修改和扩展这些例子,但是你想计算任何你感兴趣的 Reddit 帖子。这里有一些想法,你可能想计算这个 Reddit 帖子的样本。
- 有哪些帖子得分最高?(本文简介中的例子)
- 哪些 Redditors 的*均分最高?
- 谁是每个子栏目中发帖最多的 Redditors?
- 哪些词在高分帖中出现频率很高?相对于哪些词在低分帖子中出现频率较高?
- 哪些词在所有帖子中出现频率普遍较低,但在特定的子帖子中出现频率较高?也就是说,什么词是给定子编辑的唯一特征?我们可以通过获取每个子编辑/单词对的
subredditWordFrequency/generalWordFrequency
的比率并寻找高比率来量化这一点。(这是一个很好的挑战,可以进一步提高您的 Scala 熟练程度。)
我希望你喜欢应用 Scala 来分析 Reddit,并对 Redditors 有所了解。在未来,我将向您展示如何对 2018 年 10 月的全套 Reddit 帖子进行这种分析。这个月有 11,306,843 个帖子,所以我们需要学习如何使用“大数据”技术 Spark 应用 Scala。
您会惊讶地发现,我们在这些“大数据”练习中编写的代码并不比我们在今天的练习中编写的代码更复杂。当我们使用 Spark 和 Scala 等强大的技术时,处理“大数据”就像处理小数据一样简单。
感谢您和我一起完成另一系列 Scala 练习。我希望这一次特别有趣,因为我们开始了解真实世界的数据。我会尽我所能创造更多这种风格的练习。
我要感谢 pushshift.io 托管 Reddit 数据转储。这是一个非常有趣的数据来源,对我来说,从 2018 年 10 月的完整数据集中提取一个小样本用于这些示例和练习很容易。您可以自己下载这些数据,并编写自己的 Scala 代码来开始执行更复杂的分析。
对 AI 政策感兴趣?开始写作
原文:https://towardsdatascience.com/interested-in-ai-policy-start-writing-bc70b08c8c22?source=collection_archive---------30-----------------------
Photo by Glenn Carstens-Peters on Unsplash
最*,OpenAI 的 Amanda Askell,Miles Brundage 和 Jack Clark 加入了 Rob Wiblin 的 8 万小时播客讨论了与人工智能哲学相关的广泛话题。政策和出版规范。
在交谈中,他们还讨论了如果你试图理解人工智能和人工智能政策,应该从哪里开始。这是一个直接与我对话的话题,因为我对这个领域感兴趣,但完全被可用的资源(或缺乏资源)所淹没。
他们回答中的一个共同主题是,对于试图理解人工智能的人来说,最大的机会是围绕该领域内的特定新闻和主题,创建对外行人、政府工作人员和研究人员有用的内容。
在这篇文章中,我总结并详述了他们推荐这条道路的原因,以及自己着手去做的方法。
我仍然强烈推荐给整个播客一听。他们讨论了非技术人员进入该领域的途径(不需要获得博士学位),以及你需要具备的一些特质和软技能。整个播客非常出色,但围绕“进入领域”的讨论在 1:51:00 左右开始。
决策者和研究人员需要更多的内容
Photo by Jacob Stone on Unsplash
杰克·克拉克(Jack Clark)是 OpenAI 的政策主管,他经常往返于旧金山和华盛顿特区(他称之为“地球上最幸福的地方”)。).
他也是 Import AI 时事通讯的作者,这是一封总结人工智能社区新闻的每周电子邮件,并以非专家可读和有用的方式解释为什么它很重要。
一只脚在研究,另一只脚在政策,克拉克和任何人一样有资格从经验中谈论人工智能政策世界需要什么。
而根据克拉克的说法,它需要的是内容。
“我去过的任何国家的任何政治家的任何工作人员都提到需要更多的材料来阅读,以了解人工智能和人工智能政策,”克拉克说。具体来说,是“人工智能及其在特定的、严格限定范围的领域内与政策的相关性”的总结
具有讽刺意味的是,他推荐的媒介与人工智能正在创造的开创性媒介和信息相去甚远。
“在辉煌的人工智能未来,最前沿是基于文本的电子邮件,其中没有图像。”
他没有错。根据《大西洋月刊》(The Atlantic)对 273 名希尔员工进行的一项调查,涉及“与(他们的)老板积极关注的问题相关的”主题的简讯会被阅读,“不管它来自哪里”,员工“通常会立即阅读纯文本的简讯。”
没错——明文电子邮件是新的响应 HTML。
但不仅仅是国会山的工作人员和决策者。随着人工智能领域的发展,人们将有更多的机会向外行人传播人工智能的新闻和进展。
阿曼达·阿斯克尔认为,对人工智能政策感兴趣的人缺乏一套课程是该领域发展的一个关键问题。“我越来越希望,随着这个领域的发展,会有更多的材料提供给对这个领域感兴趣的人。”
阿斯克尔说:“如果你觉得你的技能组合是你真的擅长向公众传达和综合最新的创新,这可能会是一个非常有用的技能组合。”
底线;显然需要与人工智能政策相关的更复杂、写得更清楚的内容,从普通公众到国会工作人员到人工智能机构的每个人都希望让聪明、感兴趣的个人更容易加入该领域。
对于任何希望涉足人工智能和人工智能政策的人来说,创造内容是最有效、门槛最低的起点,而不是实际进行研究或直接与政策制定者合作。
写信去发现你的想法
写关于人工智能政策的文章实际上仍然是一种有益的尝试,即使没人读它。仅仅是写下你的想法就可以帮助你形成自己的想法,更好地理解一个主题。
最广泛地说,写作迫使你:
- 选择一个明确的主题
- 充分研究这个主题,以决定它的重要性
- 充分理解它,以便对它有一个看法,或者用一种有用和清晰的方式对它进行总结
在人工智能政策的范围内,写作需要你以一种外行人能够理解的方式综合复杂的主题,因为假设你自己是从那个主题的外行人开始的。
如果你把写作看作一种教学形式(你是老师,读者是学生),写作对你的知识的影响就变得更清楚了。许多研究表明,教授一个话题是学习话题本身最有效的方法之一。
但是应该从哪里开始呢?阿斯克尔分享了一些建议:“从找到一个有趣且相关的问题开始,然后写点东西并形成对它的看法。”
为了说明,就拿我写这篇文章的经历来说吧。作为一个有内容营销背景的人,杰克关于创办时事通讯的建议切中要害。由于“写简讯”是人工智能政策中一个我可以联系到的话题,它成为了我可以解开的一个很好的微观话题。
经历这个过程帮助我脚踏实地,建立了一些信心。如果我能和人工智能研究人员说同样的语言,即使是在一个根本没有实质性进入人工智能或人工智能政策的话题上,我也有了一个锚定自己并继续前进的地方。
提高可信度
撰写人工智能政策的另一个主要优势是,它提供了你在该领域知识的证明,并为你提供了建立可信度的资产。
克拉克的进口 AI 通讯就是证据。据克拉克说,这是他建立人际网络的最佳工具之一。
我已经认识了相当多的政策制定者,不是通过我的 OpenAI 成员,而是通过他们订阅我的时事通讯。”克拉克说这也增加了我的信念,即仅仅制作对你的目标受众有用的东西是一个非常好的行动,让你获得关于如何见面和见谁的证据。"
创建内容以多种方式建立可信度。
综合复杂的话题
Photo by Jacob Stone on Unsplash
最重要的是,写作证明你有能力思考一个复杂的话题,并把点点滴滴联系起来,产生有用的东西。人工智能是一个具有挑战性的课题;阿斯克尔将其比作“获得 7 个不同学科的博士学位”,因为其影响涉及从技术编程到经济学到哲学的所有领域。
克拉克同意;“如果你喜欢查看来自多个领域的多种信息,并将所有信息整合到一些世界理论或变化理论中,我认为你会在人工智能领域做得更好。”
以一种彻底和准确的方式写一些关于特定主题的东西需要你理解这些不同的学科是如何相互作用和重叠的。以一种清晰简洁的方式做到这一点是一项重要的技能,你需要为你可能感兴趣的许多角色展示这一点。
开始富有成效的对话
通过创建一个可共享的资产(在这种情况下,是一篇基于文本的文章),你现在可以用它来开始与该领域的知识渊博的人进行富有成效的对话,你可能希望以后为他们工作并与之合作。这是从头开始建立网络的最简单的方法。
阿斯克尔推荐该方法;一旦你写了一些东西,“伸出手来真的会很有收获,因为你已经表现出了兴趣,以及在你从事的研究方面你能做些什么。”
不过,在你的拓展活动中,做好充分准备和过于规避风险之间有一个*衡。布伦戴奇解释说,“我认为,一般来说,人们不应该害怕伸出手,获得反馈和传播想法。”
很明显,你应该熟悉你要联系的人的工作,因为这与你要联系的事情有关,但是与其晚联系不如早联系。
形成一个观点,并有深思熟虑的问题
根据克拉克的说法,你可以展示你对材料的理解的最简单的方法之一是参与人工智能组织的研究,并找到你不同意或对结论有疑问的地方。
克拉克扩张;“这可能是阅读微软呼吁联邦监管机构关注面部识别的一些博客,也可能是谷歌对人工智能论文的治理……然后对此做出回应。因为那些东西没有一个是完全正确的文档或者博客。他们的观点你可以不同意。”
根据克拉克的说法,能够在一个主题上形成自己的观点并“识别人工智能组织共享的材料中的逻辑不一致”是一个晴雨表,他通过它来衡量某人对该主题的理解程度。
原因?有自己的观点会给别人提供一个你思考方式的例子,而且“人们低估了提供一个你思考方式的例子的价值。”
形成观点的一个自然分支是能够提出深思熟虑的问题。
“我一直发现,判断我是否理解某件事情的一个好方法是,我是否能找到该领域的专家,问他们一个相关且复杂的问题。”克拉克说。
利用您创建的内容,您可以与该领域的人员开始的最有成效、最有益的对话是您提出一个相关的问题。
参与在线社区
长篇文章并不是人工智能领域的人们回应的唯一内容形式。“非常多的主要技术研究人员使用 Twitter 来宣布结果、相互交流和交换想法,”克拉克说。
关注他们的对话会让你对他们讨论的话题和他们讨论的方式有更深入的了解。你接触这些对话越多,你的天线就能越好地捕捉到什么是重要的,以及如何以一种映射到你试图联系的人的方式谈论它。
表达真正的兴趣
考虑到这个领域是如此的多面化,任何想“进入人工智能”的人的先决条件是对这个领域有真正的、自我激励的兴趣。
“在这个领域和正在做的工作中拥有激情是很重要的”,阿斯克尔说。“我们所有人都在业余时间自学这方面的知识,并不断尝试构建我们自己的东西,尽管我们不是技术研究人员。”
除非你已经在这个领域,否则大多数对人工智能和人工智能政策感兴趣的人将不得不从自学开始。创作内容是展示这些努力的一种简单方式。
包扎
在一天结束的时候,如果你真的想涉足人工智能和人工智能政策的世界,你需要有所作为。
书面内容是您工具箱中最容易使用的工具,它为您提供:
- 组织你自己对这个问题的想法的机会
- 您可以用来获得反馈并与专家展开对话的资产
- 对自己在广阔的主题领域走出黑暗的能力充满信心
所以开始写吧。
“有趣”的预测 PCA 失败的地方。
原文:https://towardsdatascience.com/interesting-projections-where-pca-fails-fe64ddca73e6?source=collection_archive---------9-----------------------
探索性数据分析的一种有吸引力的替代方法。
大多数数据科学家都熟悉作为探索性数据分析工具的主成分分析(PCA)。外行人回顾一下:研究人员经常使用 PCA 进行降维,希望揭示他们数据中的有用信息(例如,疾病与非疾病类别分离)。PCA 通过寻找正交投影向量来实现这一点,正交投影向量解释了数据中方差的最大量。在实践中,这通常是通过使用奇异值分解(SVD)来找到主成分(特征向量),根据它们对数据中总方差的贡献(特征值)进行加权。毫无疑问,PCA 是我的领域(化学)和许多其他领域中使用最多的数据分析工具,但当它不起作用时会发生什么呢?是不是说明采样实验不好?没有。这是否意味着数据中没有有用的信息?不。我们在达尔豪西大学的团队致力于开发新的化学数据分析工具。今天,我要告诉你一种替代主成分分析的方法,叫做投影寻踪分析(PPA)。
General factor analysis model
PCA 对方差进行操作
PCA 失败在哪里?如前所述,PCA 通过寻找数据中最大方差的方向来工作。如果那个方向上的投影没有用呢?下图由模拟数据(200 个样本)组成,这些数据形成了两个独立的聚类,这两个聚类沿 y- 轴的方差大于沿 x- 轴的方差。如果我们对这个二维数据进行 PCA,我们获得的投影向量, v ,将是 2 x 1 列向量([0;1]).原始数据,X(200X2),投影到这个向量上就给了我们分数T=Xv。可视化这些分数显示两个集群之间没有明显的分离。相反,如果我们投影到 x 轴上(v=【1;0]),那么就很容易看到集群中的分离。我们如何在高维数据中找到这个向量?
“Interesting” projections are projections that reveal, for example, class information.
投影寻踪
投影寻踪,最初由 Friedman 和 Tukey (1974)提出,试图通过最大化或最小化投影指数在数据中找到“感兴趣的”投影。通过扩展,在 PCA 框架中,投影指数(方差)被最大化。现在的问题是,“什么是好的预测指数?”。在定义新的投影指数方面已经做了大量的研究,但我今天将重点关注的一个已被证明对探索化学数据有用的指数是峰度。
基于峰度的投影寻踪
第四个统计矩峰度已被证明是有用的预测指标(https://www . science direct . com/science/article/pii/s 0003267011010804)。
Univariate kurtosis
当峰度最大化时,它往往会揭示数据中的异常值。有些有用,但不是我们真正想要揭示的类或集群信息。然而,当峰度最小化时,它将数据分成一维的两组(二维的 4 组和三维的 8 组)。
Kurtosis minimization
最大的问题是如何使用峰度来搜索这些投影向量?准幂学习算法。见https://www . science direct . com/science/article/pii/s 0003267011010804。在本文中,Hou 和 Wentzell 表明,可以使用以下学习算法找到使峰度最小化的投影向量:
Finding the projection vector that minimizes kurtosis
示例模拟
让我们模拟一些数据,并应用主成分分析和 PPA。类似于开始的图形,我们的数据将有 2 个类(每个类中有 100 个样本),并且只需要 1 个维度来揭示类分离。第一类将以 x 轴上的-4 为中心,标准差为 5,第二类以+4 为中心,标准差为 5。
Original data
为了更真实,让我们通过乘以 2 x 600 随机旋转矩阵,将这个 200 x 2 矩阵旋转成 600 维。这就是我们现在需要利用我们的探索性工具来发现我们的数据的一些有趣的预测的地方。首先,让列均值集中我们的数据,并应用主成分分析,将第一个分量可视化为样本数的函数。
First component from PCA
我们看到,将数据投影到第一台PC 上不会显示任何类别信息。让我们现在申请 PPA。
First scores from PPA
PPA 能够找到对我们有用的投影(即提供类分离的投影)。
PPA 有麻烦的地方
尽管在大多数情况下,PPA 的表现优于主成分分析,但当 PPA 不起作用时,还是有一些重要的注意事项。当班级规模不相等时,PPA 不能很好地工作,例如,如果我在上面的示例中设定 5:1 的班级比例,并应用 PPA,我们会得到:
由于分离的几何关系,当类的数量不是 2 的幂时,PPA 很难理解。PPA 也与过度拟合作斗争,通常需要进行数据压缩(大约需要 10:1 的样本与变量比率)。否则,算法会人为地将样本推到角落里。我们小组目前的工作集中在开发缓解这些问题的方法上,(好消息)我们应该会在未来几个月内发表一些这方面的论文!我一定会让你们了解最新情况。
2020 年 2 月编辑:我们最*发布了一个稀疏的 PPA 实现,它规避了在 PPA 之前对 PCA 压缩的需求。参见 SPPA 库或 t 何在分析化学中的论文。
史蒂夫(男子名)
协方差矩阵的有趣性质
原文:https://towardsdatascience.com/interesting-properties-and-use-cases-of-the-covariance-matrix-80d72939c7ab?source=collection_archive---------8-----------------------
数据科学家关于协方差矩阵的基本信息
协方差矩阵有许多有趣的属性,可以在混合模型、成分分析、卡尔曼滤波器等中找到。发展对协方差矩阵如何运作的直觉有助于理解其实际含义。本文将集中在一些重要的性质,相关的证明,然后一些有趣的实际应用,即非高斯混合模型。
我经常发现研究论文在写公式时没有详细说明矩阵的形状。我已经包括了这些和其他必要的信息来帮助数据科学家编写他们自己的算法。
子协方差矩阵
协方差矩阵可以分解成多个唯一的(2×2)协方差矩阵。唯一子协方差矩阵的数量等于矩阵下半部分的元素数量,不包括主对角线。A (DxD)协方差矩阵将具有 D*(D+1)/2 -D 唯一子协方差矩阵。例如,三维协方差矩阵在等式(0)中示出。
可以看出,协方差矩阵中的每个元素由每个(I,j)维对之间的协方差来表示。等式(1)显示了将 a (DxD)分解成多个(2x2)协方差矩阵。对于(3x3)维的情况,将有 3 * 4/2–3 或 3 个唯一的子协方差矩阵。
注意,生成随机子协方差矩阵可能不会产生有效的协方差矩阵。协方差矩阵必须是半正定的,并且子协方差矩阵的每个对角线元素的方差必须与协方差矩阵对角线上的方差相同。
正半定性质
协方差矩阵的性质之一是它必须是半正定矩阵。正定是什么意思,为什么协方差矩阵总是半正定的,值得另文讨论。简而言之,如果等式(2)中所示的运算产生大于或等于零的值,则矩阵 M 是半正定的。
m 是实值 DxD 矩阵,z 是 Dx1 向量。注意:这个操作的结果是一个 1x1 标量。
协方差矩阵 M 可以通过以下操作从数据中构建,其中 M = E[(x-mu)。T(x-mu)]。将 M 代入等式(2)得到等式(3)。可以看出,任何可以写成 M.TM 形式的矩阵都是半正定的。出处。 ✎编辑
请注意,协方差矩阵并不总是描述数据集维度之间的协变。例如,协方差矩阵可用于描述高斯混合模型中使用的多元正态聚类的形状。
几何含义
另一种思考方式协方差矩阵是几何级数的。本质上,协方差矩阵表示数据传播的方向和比例。为了理解这个观点,有必要理解特征值和特征向量。
等式(4)示出了特征向量及其相关特征值的定义。下一个陈述对理解特征向量和特征值很重要。如果矩阵乘法 Mz 产生相同的向量 z,则 z 是 M 的特征向量。换句话说,我们可以把矩阵 M 看作是不*改变 z 方向的变换矩阵,或者 z 是矩阵 M 的一个基矢。
λ是特征值(1x1)标量,z 是特征向量(Dx1)矩阵,M 是(DxD)协方差矩阵。半正定(DxD)协方差矩阵将具有 D 个特征值和(DxD)个特征向量。第一特征向量总是在数据的最高扩展的方向上,所有特征向量彼此正交,并且所有特征向量被归一化,即它们具有 0 和 1 之间的值。等式(5)示出了协方差矩阵、特征向量和特征值之间的矢量化关系。
s 是(DxD)对角缩放矩阵,其中对角值对应于特征值,并且表示每个特征向量的方差。r 是(DxD)旋转矩阵,表示每个特征值的方向。
在上面的等式中,对于唯一的(I,j)子协方差(2D)矩阵,表示特征向量和特征值矩阵。等式(6)中所示的子协方差矩阵的特征向量具有一个参数θ,其控制每个(I,j) 维对之间的旋转量。协方差矩阵的特征值跨越对角元素,如等式(7)所示,并且表示每个维度的方差。缩放矩阵具有控制每个特征向量的缩放的 D 个参数。
协方差矩阵变换
通过应用相关的比例和旋转矩阵,( 2x2)协方差矩阵可以变换(2x1)向量。比例矩阵必须在旋转矩阵之前应用,如等式(8)所示。
等式(9)中示出了(Nx2)矩阵 X 的矢量化协方差矩阵变换。矩阵 X 必须以(0,0)为中心,这样向量才能正确地绕原点旋转。如果矩阵 X 不居中,数据点将不会围绕原点旋转。
(Nx2)矩阵的协方差变换示例如图 1 所示。关于如何生成该图的更多信息可在此处找到。
Figure 1. Covariance Matrix Transform
绘制高斯混合等高线
通过用子协方差矩阵变换(2×2)单位圆,高斯混合的轮廓可以在多个维度上可视化。特定标准偏差下的聚类轮廓可以通过将标度矩阵乘以期望标准偏差的*方值来绘制。然后,聚类从原点移动到它们相关的质心值。生成下图的代码可以在这里找到。
Figure 2. Gaussian Mixture Contours
图二。显示了在虹膜数据集上训练的 3 簇高斯混合模型解决方案。在上面的图中,等高线代表混合物的概率密度,在一个特定的标准偏差,从群集的质心。在图 2 中。,从每个聚类的质心绘制 1 个标准偏差和 2 个标准偏差的等值线。
离群点检测
高斯混合有推开聚类的趋势,因为具有重叠分布会降低优化度量、最大似然估计或 MLE。数据点仍有很高的概率属于多元正态聚类,同时仍是一个或多个维度上的异常值。相对较低的概率值表示属于特定聚类的数据点的不确定性。
通过找到位于多元超立方体之外的数据点,可以将均匀混合模型用于异常值检测。这些混合物对导致特定特征向量上的低方差的“强烈”剪切是鲁棒的。与*滑轮廓相比,查找数据点位于多边形内部还是外部在计算上也更容易。
均匀分布聚类的创建方式与上一节中生成等值线的方式相同。以(0,0)为中心的单位正方形通过子协方差矩阵进行变换,然后移动到特定的*均值。
Figure 3. Multivariate Uniform Mixture — Outlier Detection
旋转后的矩形,如图 3 所示。的长度等于每个特征值的*方根的 1.58 倍。离群值被定义为不完全位于一个集群的超立方体内的数据点。异常值被着色以帮助可视化至少在一个维度上代表异常值的数据点。有许多不同的方法可以用来查找数据点是否位于凸多边形内。寻找一个数据点是否位于多边形内将留给读者作为练习。
均匀分布混合模型的另一个潜在用例是将该算法用作核密度分类器。可以为超立方体内部的数据点找到目标的*均值,并且可以将其用作该集群具有目标的概率。该算法将允许为每个集群独立考虑成本效益分析。
主成分分析
主成分分析(PCA)利用数据集的协方差矩阵将数据集转换为一组正交要素,以获取最大范围的数据。下面的代码片段说明了如何使用协方差矩阵的特征向量和特征值来生成主分量。
特征向量矩阵可用于将标准化数据集转换成一组主成分。数据集的维数可以通过丢弃捕获最低数据分布或具有最低相应特征值的特征向量来减少。在计算协方差矩阵之前,应标准化数据集的列,以确保每列的权重相等。
最终注释
还有许多更有趣的使用案例和属性没有在本文中介绍:1)协方差和相关性之间的关系 2)寻找最*相关矩阵 3)协方差矩阵在卡尔曼滤波器、马氏距离和主成分分析中的应用 4)如何计算协方差矩阵的特征向量和特征值 5)如何优化高斯混合模型。
资源
协方差和中心极限定理 ✎版
协方差矩阵的几何解释
了解协方差矩阵
中间细流
原文:https://towardsdatascience.com/intermediate-streamlit-d5a1381daa65?source=collection_archive---------5-----------------------
构建不断发展的应用程序时的一些提示和技巧
It’s never too early to start scaffolding your app. Image by Michael Gaida from Pixabay.
Streamlit 是一款非常棒的工具,可以为您的数据科学工作提供一个界面。我一直将它作为一个轻量级仪表板工具来显示简单的可视化效果,在 UI 中包装 python 包,并探索 NLP 模型的模型评估(真实示例 1 和 2 )。它让我能够更好地理解我的数据,并创建了一个界面,可以帮助在代码/数据/分析之间进行转换,并与利益相关者和主题专家进行交流。
然而,今天的原型变成了明天的生产应用。把事情变得太容易是有风险的——在你知道之前,你已经建立了下一次迭代会同样快发生的预期,或者你的应用程序是健壮的和经过良好测试的,或者在整个公司范围内部署它是指日可待的,或者新实习生可以从这里开始节省一些钱。
随着应用的增长,您需要管理成长的烦恼。在这篇文章中,我将提供一些随着我的 streamit 应用程序的发展而变得有用的技巧和想法。我将从一些构建更好的应用程序的简单技巧开始,以一些使应用程序模块化和可测试的想法结束。
(作为一个功能说明,任何时候你看到一个要点,你都应该能够将其作为一个 streamlit 应用程序运行,并探索自己。如果你愿意做一个pip install streamlit pandas altair vega_datasets
,你可以用streamlit run <gist_url>
运行下面的任何一个 gists。
显示干净的变量名
数据帧中的变量名可能是蛇形的或以不适合最终用户的方式格式化,例如pointless_metric_my_boss_requested_and_i_reluctantly_included
。大多数 streamlit 小部件都包含一个format_func
参数,该参数具有将显示格式应用于您提供给小部件的选项值的功能。举个简单的例子,你可以给每个变量名都加上大小写。
您还可以将此功能与字典结合使用,以显式处理值的格式。下面的例子清理了birdstrikes
数据集中的列名,用作描述每一列的下拉列表。
Passing dict.get
as an argument to format_func
allows you to explicitly control the display of widget values
使用缓存(但首先要进行基准测试)
人们很容易把那个便利的@st.cache
装饰器扔在所有东西上,并希望一切顺利。然而,盲目地应用缓存意味着我们错过了一个获得 meta 并使用 streamlit 来了解缓存在哪里最有帮助的大好机会。
与其装饰每个函数,不如为每个函数创建两个版本:一个有装饰器,一个没有。然后做一些基本的基准测试,看看执行这个函数的缓存版本和非缓存版本需要多长时间。
在下面的例子中,我们通过连接 100 个airports
数据集的副本,然后动态选择第一个n
行并描述它们来模拟加载一个大型数据集。
Don’t blindly apply @st.cache
— benchmark and apply where appropriate
因为其中的每一步(数据加载、选择行、描述选择)都是计时的,所以我们可以看到缓存在哪里提供了加速。根据我在这个例子中的经验,我对缓存的启发是:
- 总是缓存加载数据集
- 可能缓存时间超过半秒的函数
- 衡量其他一切
我认为缓存是 streamlit 的杀手锏之一,我知道他们正在关注并改进它。智能缓存也是一个复杂的问题,所以更倾向于基准测试和验证缓存功能是否按预期运行是一个好主意。
创建动态小部件
许多例子侧重于创建动态可视化,但是不要忘记您也可以编程动态小部件。这种需求最简单的例子是当数据集中的两列有嵌套关系,并且有两个小部件从这两列中选择值时。构建应用程序来过滤数据时,第一列的下拉列表应更改第二个下拉列表中的可用选项。
两个下拉菜单的链接行为是一个常见的用例。以下示例使用cars
数据集构建了一个散点图。这里我们需要一个动态下拉菜单,因为我们为 x 轴选择的变量不需要在 y 轴上可供选择。
我们还可以超越这个基本的动态功能:如果我们按照 y 轴选项与所选 x 变量的相关性对它们进行排序,会怎么样呢?我们可以计算相关性,并将其与小部件的format_func
结合起来,以排序的顺序显示变量及其相关性。
Dynamic widgets are a powerful way to add more context around your app’s functionality
大量使用 f 弦和降价
在上面的例子中,我们使用 python 的 f 字符串来插入变量名及其相关值。在围绕分析构建界面时,大部分工作都需要在变量名、小部件值、轴标签、小部件标签或叙述性描述中创建或操作字符串。
如果我们想以叙述的形式展示一些分析,并且有一些特定的变量我们想突出显示,f-strings 和 markdown 可以帮助我们。除了用特定的变量值填充字符串的简单方法之外,内联格式化它们也是一种简单的方法。例如,我们可以使用类似这样的东西来显示数据集中某一列的基本信息,并在 markdown 字符串中突出显示它们。
mean = df["values"].mean()
n_rows = len(df)md_results = f"The mean is **{mean:.2f}** and there are **{n_rows:,}**."st.markdown(md_results)
我们在这里使用了两种格式:.2f
将浮点数舍入到两位小数,而,
使用逗号作为千位分隔符。我们还使用 markdown 语法来加粗这些值,以便它们在文本中视觉上突出。
考虑切换到 Altair 进行可视化
如果您一直在用另一个库构建可视化原型,那么可以考虑切换到 Altair 来构建您的可视化。以我的经验来看,我认为有三个关键原因可以说明转换是有益的:
- Altair 可能更快(除非我们在绘制大量数据)
- 它直接在熊猫数据帧上操作
- 交互式可视化很容易创建
关于速度的第一点,如果我们使用 matplotlib 进行原型化,我们可以看到显著的加速。与渲染 javascript 可视化相比,大部分加速只是因为渲染静态图像并将其放入应用程序需要更多时间。下面的示例应用程序演示了这一点,它为一些生成的数据生成散点图,并为可视化的每个部分输出创建和渲染的时间。
Altair can be faster than matplotlib if you’re plotting less than a few thousand pionts.
直接使用数据框架提供了另一个好处。它可以简化调试过程:如果输入数据有问题,我们可以使用st.write(df)
在 streamlit 应用程序中显示数据帧并检查它。这使得调试数据问题的反馈循环更短。第二个好处是,它减少了创建特定可视化所需的转换粘合代码的数量。对于基本的绘图,我们可以使用 DataFrame 的绘图方法,但是更复杂的可视化可能需要我们以一种对可视化 API 有意义的方式来重构数据集。数据集和可视化之间的这些额外代码可能会导致额外的复杂性,并且随着应用程序的增长,可能会成为一个棘手的问题。由于 Altair 使用 Vega-Lite 可视化语法,转换 API 中可用的函数可用于进行任何可视化的适当转换。
最后,Altair 的交互式可视化非常简单。虽然应用程序可能会使用 streamlit 小部件来过滤和选择数据,但应用程序也可以使用可视化功能作为选择机制。交互式可视化允许在可视化中对数据的各个方面进行可视化交流,而不是在小部件或叙述中以字符串的形式交流信息。
不要忽视重构、编写模块化代码和测试
花几个小时使用 streamlit 并拥有一个除了你之外没有人理解的 500 行文件是很容易的。如果你正在交付你的代码,部署你的应用程序,或者添加一些新的功能,现在你可能会花费大量的时间试图记住你的代码是如何工作的,因为你已经忽略了良好的代码卫生。
如果一个应用程序超过 100 行代码,它可能会从重构中受益。好的第一步是从代码中创建函数,并将这些函数放在一个单独的helpers.py
文件中。这也使得在这些函数上测试和测试缓存变得更加容易。
关于如何重构代码,没有具体的正确方法,但是我开发了一个练习,可以在开始重构应用程序时提供帮助。
重构练习
在 app.py 中,尝试:
- 仅导入 streamlit 和助手函数(不要忘记在这些助手函数上测试
@st.cache
) - 不要在下一行代码中创建没有输入到 streamlit 对象的变量,例如可视化或小部件(数据加载函数除外)
这些并不是必须遵守的硬性规则:你可以明确地遵循它们,因为你有大量复杂的功能,所以你的应用组织得很差。然而,当从 app.py 中的所有东西转移到更模块化的结构时,它们是很好的开始目标。
下面的例子突出显示了在进行这个练习前后的一个应用程序。
Functions are great and you should use them.
以这种方式重新组织代码的另一个好处是,helpers 文件中的函数现在更容易编写测试。有时我很难想出要测试什么,但我发现现在为我的应用程序进行测试真的很容易,因为我现在可以更快地发现错误和边缘情况,因为我与数据和代码的交互更紧密了。现在,每当我的应用程序显示回溯,我就修复导致它的函数,并编写一个测试来确保新的行为是我所期望的。
包裹
我一直很享受使用 streamlit 的时光,这是一款出色的工具,能够满足数据科学工作流程中的明确需求。然而,今天的原型就是明天的生产应用,一个简单的应用很容易成为数据科学团队无法维护的噩梦。这篇文章中的想法帮助我处理了与将我的应用程序移出原型相关的痛苦,我希望它们对你也一样。
你的数据科学项目真的如你所想的那样吗?
原文:https://towardsdatascience.com/internal-validity-in-data-science-c44c1a2f194f?source=collection_archive---------32-----------------------
内部效度。相信我,这很重要。以下是需要记住的内容。
Photo by Artur Matosyan on Unsplash
为什么它很重要
在数据科学的许多方面,我们需要了解我们所做的更改是否会对我们关心的东西产生影响。这可能是改变搜索算法以创建更多可用的结果,实施机器学习模型以提供更准确的建议,从而增加销售额,或者添加新的数据捕捉以允许我们预测哪些网站访问者将成为客户。
所有这些变化都可以被认为是实验。我们希望看到变化(自变量)是否会导致预期或希望的结果(因变量)。
更重要的是,我们想知道自变量是否引起因变量的变化。因为如果没有,那么我们的数据科学技术就没有真正的价值,我们在浪费时间。
如果你是一个数据科学团队的成员或主管,请确保你了解如何知道你的团队所做的努力是否真的产生了结果。否则,你可能会浪费很多时间和精力。
什么是有效性?
有效性被描述为“一个推论的*似真理”。虽然这很有诗意,但有点难以理解。简而言之,有效性是对我们面前的数据是否支持一个结论为真的一种衡量。
重要的是要记住,有效性是指在被研究的样本或人群中观察到的“A”和观察到的“B”之间的因果机制。
有效性的核心是我们是否能相信 A 导致了 B,而不是 A 和 B 之间的差异是产品或随机机会或其他因素。
反事实是,如果没有 a,B 就会发生。排除这个反事实有助于我们进行因果推断。
一个元示例:我们想知道改变媒体报道的格式是否会增加阅读时间。这里,A 是改变格式,B 是阅读时间。这个例子中的反事实是,观察到的时间增加(B)会在有或没有格式改变(A)的情况下发生。
四种类型的有效性
有效性有几种类型,根据上下文的不同,它们都很重要。我们将重点关注最常见的内部和外部有效性,但是了解其他类型也是很好的。
统计结论有效性是指正确应用数学和统计方法,在自变量和因变量之间的观测值之间得出结论。例如,研究人员是否对样本而不是总体应用了适当的最小二乘回归公式?
结构效度是对观察到的数据实际上是试图测量的高阶概念或变量的表示的关注。这在社会科学中是很重要的(我相信这占了数据科学中许多与个人和群体行为有关的领域),因为许多重要的理论概念不能被直接观察或测量。
例如,如果我想比较人们的爱国主义,我可以进行某些测量,例如他们是否在国歌演奏时站立,是否向支持退伍军人的慈善机构捐款,是否在保险杠上插国旗,或者是否支持对被指控侵略自己国家的国家采取行动。然而,我需要确定的是,这些观察结果并不是在衡量他们对国旗保险杠贴纸的喜爱,或者他们的懒惰或在国歌奏响时难以站立,或者也许他们只是非常支持战争而不顾挑衅!
外部效度是在特定研究中观察和证明的因果关系在多大程度上可以被推断为存在于更大的样本、人群或不同的环境中。这在你正在进行一个实验或一个小组的试点的情况下是很重要的,如果你在一个不同的小组中扩大规模或进行同样的试点,你想知道你的结果是否成立。
内部有效性是对自变量的变化是否导致实验或研究人群中因变量的差异或变化的衡量。例如,我们能确定观察到的因变量的变化或差异是因为自变量的变化或差异而发生的吗?
内部有效性很重要,因为它与因果关系直接相关,尽管有些人相信,但它在机器学习时代仍然很重要!因为内部有效性非常重要,所以我们将在本文的剩余部分集中讨论它。
对内部有效性的深入探究
我们知道,当我们想要了解自变量(A —格式变化)和因变量(B —阅读时间)之间的因果关系时,内部有效性是至关重要的。
内部效度在许多研究和试点项目中非常重要,在这些研究和试点项目中,我们希望显示初始观察和测试后观察之间的因果关系,或者在推断差异是由治疗引起时显示治疗前和治疗后组之间的差异。
很明显,在内部有效性的情况下,结果的顺序很重要,因为因果关系要求 A 先于 B,A 随 B 变化,并且除了 A 的存在,B 没有其他解释。
但是为了对我们的内在有效性有信心,我们需要关注哪些风险呢?
内部有效性风险:
- 因果时间顺序是指 B 和 A 以相反的顺序或者可能同时发生。在我们的示例中,如果在进行格式更改之前,阅读中型文章所花费的时间开始增加,会怎么样?
- 选择偏差是指研究参与者或实验组或对照组因治疗或独立变量(A)之外的其他原因而存在差异,例如那些更有可能坚持饮食计划并因此表现出更好的减肥结果的参与者。选择对于随机选择(当不愉快的随机发生时)和准实验设计都是有风险的。风险在于,对照组和/或治疗组的固有属性会比实际治疗更影响结果或测试后测量。这与周末上午的媒体读者和工作日下午的读者之间的差异是同一个例子。
- 历史是在 A 经历的同时发生的其他事件对 B 造成的威胁。历史是一种威胁,即不属于治疗一部分的外部因素实际上对结果或治疗后测量负有责任。在我们的例子中,如果中型应用程序发生变化,使得读者不能快速滚动(不是说会有任何应用程序问题!).
- 成熟可能发生在治疗变量之外的其他因素影响结果的时候。在我们的例子中,如果你所有的媒体追随者都很快成为你的崇拜者,因此在浏览你的故事时速度慢得多,以确保他们不会错过你的精彩见解,会怎么样?(或者在我的情况下,也许我的打字错误增加导致他们多次重读句子。)
- 实验性的;死亡率或自然减员是一个概念,随着时间的推移,参与者可能会以多种方式离开研究,这可能会导致那些留在试验后观察的参与者以特定的方式发生变化,这说明了观察到的变化,而不是治疗变量。回到我们的例子,这可能是倾向于快速阅读的人已经转移到其他作家身上的例子,所以你的实验人群只剩下阅读速度较慢的人。
- 仪器威胁是指仪器可能无法以一致的方式进行测量,或者无法测量研究所需的概念。同样,什么是应用程序或网站改变他们的跟踪代码,导致故事阅读率的变化。
- 污染是一种风险,即治疗本身实际上会导致治疗组与对照组之间的差异。这方面的一个例子是山楂效应,参与者认为他们应该因为治疗而采取行动。在我们的例子中,也许你告诉使用新格式的读者,他们是阅读速度试点的一部分,所以他们的反应比*时慢得多,因为他们比*时更专注。这就是为什么许多医学研究是双盲的,因此参与者和负责治疗的人都不知道谁在实验组和对照组。
防范这些风险
治疗组和对照组的比较变化设计有助于我们防范这些风险,因为任何历史事件都适用于两组,研究人员仍然可以衡量治疗的影响。
此外,比较变化设计还包括组选择过程中的集中随机化。这种随机化确保了治疗组和对照组之间的同质性,并防止了两组中选择偏差的风险,允许推断治疗的效果。
最后,该设计要求进行前测和后测,以便测量治疗的因果关系。
然而,即使在比较变更设计中,你也必须适应潜在的污染,因为它是内部有效性的一个风险。
临别赠言
您的数据科学团队正在努力为组织增加价值,请确保您花一些时间来设置清晰的测试,以确保您的努力达到预期的效果。
我听到越来越多的项目和程序声称取得了令人难以置信的改进,但他们中的许多人缺乏辨别这些改进是否会发生(反事实)或它们是否实际上是由数据科学项目引起的能力。
雇用海外人才的艺术
原文:https://towardsdatascience.com/international-talent-segmentation-for-startups-3f88cb1b6e70?source=collection_archive---------24-----------------------
Photo by Brooke Cagle on Unsplash
使用 K-Modes 的无监督学习来识别区域技术中心
- 设置
在美国招聘既昂贵又耗时。在某些情况下,小企业主花费大约 40%的时间在非创收任务上,比如招聘。另外,麻省理工学院估计每雇佣一名美国新员工,公司就要花费大约 1.4 倍的基本工资。对于初创公司来说,这些影响会更加明显,因为他们通常都缺乏时间和资金。
雇佣远程团队让初创公司能够接触到更大的人才库,并有机会以本地化的价格支付工资。那么,在时间和资源有限的情况下,初创公司如何为他们所需的专业技能找到远程办公室的最佳位置呢?是否有某些国家专门从事特定的技术?中国和印度仍然是最佳观察地吗?
2。数据
我开始通过使用 2019 Stack Overflow 开发者调查来回答这些问题,其中包括大约 40,000 名非美国受访者。随着他们的位置,每个回答者报告了他们积极使用的技术栈和框架,如 Java、Python、Angular 和 Django。
在投资离岸办公室之前,初创公司需要确保有足够的人才库满足他们公司的技术和经验要求。为了充分评估本地人才库的质量,我向数据集添加了维度。我为每个回答者的经验、教育和薪水设定了权重,以确定他们作为潜在候选人的素质——从而将他们从他们工作的环境中区分出来。
3。算法
我二进制化了包括被告技术堆栈的列。在处理结束时,我的数据看起来像这样:
Example of binarized data
对二进制数据进行聚类需要专门的算法。我使用了 K-Means 的一个表亲,称为 K-Modes,它允许我以这种当前形式对我的数据进行聚类。快速复习一下——K-Means 是一种分区算法,它根据现有的(和不可见的!)在 K 簇中连续数据的相似性。
- K -随机初始化质心,分配点,
- 基于度量(例如欧几里德距离)将点分配给最*的质心,
- 重新计算作为每个聚类的*均值计算的质心,
- 将点重新分配到最*的质心,
- 重复步骤 2 至 4,直到这些点不再被指定给不同的聚类。
结果是数据的分组,其中聚类内的对象的分离被最小化。
顾名思义,K-Means 使用*均值来计算质心。然而,K-Means 算法只能用于连续数据,而不能用于分类数据。例如,如果我们对应答者 1 和应答者 2 都取欧几里德距离(如上所示),那么当我们知道这是不正确的时候,K-Means 会将两个应答者分配到同一个聚类中。
那么,对于这种二值化的数据,我们如何计算不同开发者技能之间的距离呢?解决方案在于 K-Modes 算法,该算法使用相异度而不是每个数据点到质心的距离。在这种情况下,每个数据点和每个质心的相异度或“距离”可以定义为他们不同意的技术堆栈的数量。当数据点和质心在技术堆栈上一致时,这将使“距离”更低,当它们发散时,将使“距离”更高。
当计算新的质心时,K-Modes 算法也偏离 K-Means。K-Modes 计算的不是类中的*均值,而是类的模式。因此,在我的工作中,我感兴趣的是根据受访者使用的特定技术对他们进行聚类。
K-Modes 是一个相对较新的算法,来自于 1998 年的一篇论文,还不是 scikit-learn 包的一部分。你可以在 Github 上找到 K-Modes 和它的堂兄 K-Prototypes,以便安装和文档。
4。实施
现在我有了一个可以处理我的数据的算法,我需要决定聚类的数量。我在 K-Modes 包中使用了 Jaccard 相异度函数,该函数测量我的集群之间的相异度。
众所周知,Jaccard 距离是 1 减去交集的大小,再除以并集的大小,如下所示:
Jaccard Distance Formula
与 K-Means 剪影分数一样,我将“肘”方法与 Jaccard 相异分数一起应用,以找到最适合我的模型的聚类数。我在 40 个星团里发现了那个手肘。
5。应用程序
现在,我已经用 k=40 运行了我的模型,我希望能够理解我的集群的地理性质——直观地显示我的集群中开发人员的地域性。特别是,我想为早期创业公司开发一个工具,使用一线工具来定位离岸办公室。
为此,我构建了一个 Flask 应用程序,它接受每个受访者的堆栈、教育、经验和工资等参数,并返回满足这些约束的集群的交互式地图。
下面视频中的演示采用了 Hadoop、Spark 和 Postgres 的参数,其中受访者至少拥有学士学位和至少 4 年的工作经验,并且收入低于 7.5 万美元。有了这些参数,我的模型告诉我,我应该在爱沙尼亚、波兰和芬兰开始寻找,因为那里有有这种经历的人。
Search for Data Engineer by tech stack
然而,如果我需要用 Java、Kotlin 和 C#的特定技术栈建立一个专门用于 Android 应用程序开发的远程办公室,我的模型建议首先在中美洲和南美洲寻找。
Search for Android Developer by tech stack
6。结论
伟大的天才无处不在。公司在为他们需要的特定人才寻找离岸办公室时,可以更准确地锁定目标地区。这个模型和应用程序是帮助追求离岸战略的公司迈出建立远程团队的第一步的初始工具。
7。额外资源
领英、引用、引用
物联网——迈向超互联世界
原文:https://towardsdatascience.com/internet-of-things-leap-towards-a-hyper-connected-world-6b6a90960a06?source=collection_archive---------11-----------------------
推特:@swatisubodh
连接智能
想象一个场景。当你去上班时,你的车会访问你的手机日历来确定你要去的目的地,并且已经知道最短最快的路线。万一你遇到交通拥挤,汽车会自动通知你的办公室你要迟到了!虽然这看起来像是未来电影中的一个片段,但这样的场景已经成形了。进入物联网的世界,俗称物联网。
迄今为止,互联网主要是将人与信息、人与人、人与企业联系起来。现在,物联网正在创建开放的全球网络,将人、数据和机器相互连接起来。根据最*的报告,截至 2017 年底,全球共有 84 亿个互联实体(“物”),比地球上的总人口还多!到 2020 年,不同的调查预测这一数字将达到惊人的 260-1000 亿台联网设备。过去几年,围绕大数据以及最*的人工智能(AI)的势头和讨论越来越多。这两者都是由错综复杂的互联设备网络驱动的,这些设备在后端收集和处理信息,并将其与社会、工业和科学实践联系起来,同时共同改变当前生产和消费数据、知识和创新的方式。简单地说,物联网是所有可以连接到互联网并相互“交谈”的设备的集合!
Source: Black box paradox
1999 年,英国技术先驱凯文·阿什顿(Kevin Ashton)创造了“物联网”一词,他将计算机从典型的条形码或预定脚本的执行中区分出来,成为可以收集比人工可能收集的更多信息并理解这些信息的原型。这个过程反过来让他们更聪明!
虚拟世界和现实世界之间的界面不亚于一个数字神经系统,其中的传感器和执行器收集各种类型的数据,并将其输入网络。
物联网结构
通常,物联网结构包括硬件、云、后端分析以及这三个组件之间的双向交互。它是建立在以下基础上的超连接计算环境:(1)宽带无线互联网连接;(2)嵌入日常物品的微型传感器;以及(3)由人工智能和机器学习支持的协作机器人(Cobots),解释传感器收集的大数据。
由称为传感器的简单终端设备连接而成的网格接收或传输少量数据。这些传感器与传播器通信,传播器是协议智能的站点。传播方决定如何管理数据,同时收集、整理、捆绑数据并将其传输到互联网,在互联网上,集成商对数据进行分析并采取行动。集成器功能可以托管在各种通用或广泛部署的设备或计算机上,如大数据服务器、智能手机甚至机顶盒。
传感器、传播器和积分器的网格可以自主地或在人工引导下工作。当理解的复杂性超过某个阈值或需要策略上下文信息时,数据可以被发送给人类智能进行分析。在必要的情境化之后,分析可以被发送回 cobots。
完美风暴!
考虑到这一点,今天宽带互联网变得更加广泛,4G 很快过渡到 5G 和 6G;连接的成本正在降低,越来越多的设备具有 wi-fi 功能和内置传感器;技术开发成本大幅下降,智能手机普及率达到历史最高水*。
Bala Pesala 博士,CSIR 首席科学家,AcSIR 副教授;CSIR 大学高级科学家兼 AcSIR 助理教授马丹·拉克什马南博士解释说,最*,不同领域的进步,如低价传感器和计算设备的可用性、连接和数据收集的便利性,以及商业/商业参与者和决策者越来越依赖数据分析和分析的世界,为物联网和基于物联网的应用创造了一个利基。简而言之,物联网革命再好不过了!
直到一切都与其他一切相连
据估计,我们与互联事物的互动更多地是在我们家外面,而不是在家里;从无处不在的自动柜员机(ATM)支付现金,到基于 GPS 的位置感应,帮助我们的日常导航。从极小的颗粒大小的机器人到智能城市的巨型设备,物联网已经渗透到日常生活中,并继续在我们周围扩展。突然间,智能城市的想法,或者更进一步,智能世界的想法,物联网创造了一个并行的虚拟生态系统,似乎不再遥远。
可能性实际上是无限的;物联网解决方案广泛部署在许多领域,包括汽车、交通、智能家居、能源、公用事业、安全、监控、公共安全、金融服务、零售、医疗保健、工业、仓储和配送。这不仅仅是提高现在的能力,也是决定如何改善日常生活。
Pesala 博士和 Lakshmanan 博士解释说,物联网正在物流、农业(“从种子到货架”)、能源和医疗保健领域产生巨大影响。与“无法测量的东西无法控制”的想法相呼应,他们进一步补充说,物联网系统可以持续测量事物,通过这些系统可以“当场”做出数据驱动的决策。
积聚势头
尽管我们目前处于设计和实施物联网能力的初级阶段,但一些轰动的故事已经成为头条新闻,并再次表明这项技术的巨大潜力。
对伦敦受欢迎的地铁网络的制动系统的审计和评估需要昂贵且笨重的设备来测试,并且还需要保持列车不流通,这是代价高昂的网络中断。一个由 iPAD 控制的小型物联网设备——减速器——被制成原型,并被证明不仅与传统的制动评估技术一样有效,而且预计在服务中断最少或没有中断的情况下每年节省 50 万美元。
佩萨拉博士和拉克什马南博士的实验室一方面一直在研究用于持续医疗监控和预警系统的物联网设备,另一方面是用于分散发电、分布式传感和监控应用的物联网太阳能树,他们指出了另外两个例子 Waymo 的自动驾驶电动汽车和 Flybird Innovations 的自动精确灌溉和施肥系统。前者自 2009 年以来一直在运营,无人驾驶汽车在城市道路上行驶了* 800 万公里。这是基于他们仅在 2017 年模拟驾驶的 43 亿公里。该项目旨在开发未来舒适、安全的无人驾驶汽车。另一方面,Flybird Innovations 正在开发物联网设备,这些设备可以通过编程来调节水和肥料、土壤湿度/温度/湿度。这将防止作物/植物灌溉不足和灌溉过量,从而提高作物产量和农民的生产力。
能源和医疗保健行业是大规模设计和部署基于物联网的解决方案的两个主要行业。让我们放大这些来更好地理解这一点。
瓦特网络:智能电网解决新时代的能源需求
预计到 2020 年,能源需求将翻一番,这将需要额外的电流选项和附加基础设施来补充现有的遗留基础设施。此外,许多国家和欧盟(EU)已经发布了减少碳排放和转向可再生能源的指令,至少“到 2020 年减少 20%”,同时提高能源效率。这凸显了建立利用可再生绿色能源的创新框架的必要性。正是在这里,物联网集成可以通过建立智能电网来改变这一等式,智能电网是一种通过数字控制、监控和电信功能增强的能源生成、传输和分配网络。它可以通过(I)增加弹性——通过增加来自传感器的数据;㈡使能——利用数据管理资源;以及(iii)优化——使利益相关者能够就电力使用和发电做出明智的决策。这为提高能力创造了一个信息价值循环(IVL)。
智能电网不仅提供实时、双向的电力流动,还支持自动化、双向的信息流动;这意味着在整个基础设施中分布计算智能。这可能包括在风力涡轮机叶片中嵌入传感器,根据不断变化的风力条件实时控制其俯仰、旋转和功能;涉及最小化与网络干扰相关的生产停工时间的变电站控制系统。这些数据被输入高级分析系统,该系统可以根据天气状况预测电网状态。
电力行业物联网的两个例子是 SCADA(监控和数据采集)和 AMI(高级计量基础设施)。前者包括由中央主单元控制的传感器和致动器,而后者是电表公用事业侧和用户侧智能设备的双向通信系统。许多公司都是这一领域的先行者。全球最大的空调、供暖、通风和制冷公司大金应用(Daikin Applied)正利用物联网专注于为其客户快速实施差异化增值服务,如实时单元性能、远程诊断、监控和控制、高级能源管理和第三方内容集成。
工作中的智能电网
智能电网的预测分析提供了将运营从被动转变为主动的机会。它使电力公司和电网系统运营商能够:
- 减少资本支出
- 通过了解消费模式来管理需求
- 通过了解高峰消费模式和周期来增加可再生能源的能力
- 通过实现远程故障诊断和预测性维护降低维护成本
- 通过将可再生能源用于传输、分配和高效消费来减少碳排放,从而遵守法规
- 通过绘制客户的消费模式来开发量身定制的服务和产品,从而提高客户参与度。
部署这些解决方案的公司越来越多。总部位于佛罗里达州的杜克能源公司声称,当出现问题时,其电力系统有能力自动检测、隔离和重新路由电力。这确保了通过自动检测和自动配置在一分钟内为尽可能多的人不间断供电。太*洋天然气和电力公司(PG&E)正在测试无人机,以提高其电力和天然气服务的安全性和可靠性,特别是在其 70,000 *方英里(1,81299 *方公里)的服务区域内难以到达的地区。它正在与美国宇航局合作测试甲烷传感器,以检测管道中的甲烷泄漏。
在印度,目前有 971 家物联网初创企业,其中大多数正在与印度政府合作开发智能城市(来源:2017 年物联网初创企业目录)。例如,印度初创企业 FluxGen Technologies 的旗舰项目“能源和水资源管理器”( EWM)生成状态报告和消耗账单,甚至使用电子邮件通知用户实际消耗量和实际需求,以确保资源的最佳利用。随着这一领域的机会激增,更多的物联网解决方案和许多这样的初创企业有望进一步增加能源生态系统的动力。
Source: Medium
医疗保健
可负担得起的传感器(嵌入式、可穿戴式、移动、环境等)的可用性。)与物联网的巨大通信和计算能力结合在一起,为参与式和精准医疗的创新提供了可能性。以患者为中心的数据可以方便地收集,而不仅仅是随机对照试验。这将有助于理解更广泛的因果关系、精确治疗结果、介入接触点等。物联网的开放和分布式特性还将使个人能够以盲法和无偏见的方式为试验和医学研究做出贡献,这对于进一步微调医疗保健中的物联网能力至关重要。
概括地说,医疗保健中的物联网目前正在探索用于(1)个人健身和健康跟踪;(2)疾病监测和诊断;(3)治疗监测和坚持;(4)为医学研究收集数据;和(5)保健管理。
2017 年 11 月,美国美国食品药品监督管理局(FDA)批准了一种“数字药物”,即一种内置传感器的药丸,它可以数字跟踪患者是否摄入了药物。当传感器与胃中的液体接触时会发出电信号,并将该信号中继到患者身体上的可穿戴贴片,然后将该信号进一步传输到患者的智能手机。医生和最多四个其他授权人员可以查看该输出。该药物被批准用于治疗某些精神健康疾病,如精神分裂症。
2017 年,FDA 还批准了 AliveCor Kardia band,这是一种安装在表带中的实时心电图(ECG/EKG)。它可以连续检测正常的窦性心律和房颤(最常见的心律失常),而不是在离散的时间点进行检测。这对患者更好的医疗保健和整体降低医疗保健成本大有帮助。基于传感器的生物流体中生物分子和生物溶液的测试正迅速成为流行的非侵入性和优选的诊断工具。它不仅能够全天候无障碍地监测生物参数,还能让患者或其护理人员与医疗保健提供者实时共享结果。这进一步转化为更好的疾病管理或治疗,在某些情况下可以挽救生命。从通过嵌入生物传感器的隐形眼镜测试眼泪到尿液评估,研究人员正在绘制整个光谱。其中一种产品是 UroSense,这是 Future Path 公司的一种医疗设备,可以自动测量导管插入患者的尿量和核心体温(CBT)。这些生命体征对于及早发现和治疗心力衰竭、肾损伤、传染病、前列腺肿瘤、糖尿病、败血症和烧伤非常重要。测量 CBT 也可以表明感染或体温过低。在医院,来自 UroSense 的数据可以直接无线发送到监视器或护理站。
总部位于孟加拉国的初创企业 TerraBlue XT 开发了两款创新产品 TJay 和 Xaant。而 TJay 是用于预测和管理癫痫的解决方案;Xaant 是一种治疗性的可穿戴设备,可以追踪思维路径,生成实时数据。TJay 是一种带有传感器附件和基于 ML/ AI 的软件解决方案的手套,可在癫痫发作前提供预测。其目的是使患者能够过上更安全和高质量的生活,也使医生能够提供及时的护理和干预。该公司将自己的第二款产品 Xaant(在梵语中读作“Shaant ”,意思是*静)描述为“一种可以培养你生活*静的可穿戴设备”,因为它可以识别什么让你焦虑,什么引发你的愤怒或什么导致你的压力。这些信息反过来可以用来训练自己在面对逆境时变得更加坚强。Xaant 作为智能表带或智能珠宝佩戴,可跟踪个人的精神健康状况,并监控压力原因、睡眠质量、心脏健康以及镇静技术在保持头脑冷静方面的效果。
在难以到达的地区和农村地区提供远程医疗和医疗保健是物联网用于个人和社区医疗保健的另一个方面。
物联网无处不在!设备制造商正在将设备连接到物联网,使用增材制造(3D 打印),生产可穿戴电子产品(“智能”服装,贴在皮肤上的传感器),使远程和持续监测患者的健康成为可能。随着世界人口老龄化,慢性病及其治疗费用的增加,以及长期护理医务人员的短缺,医疗护理可能会部分地从医院转移到家庭护理。物联网与这种转变产生了很好的共鸣,并将成为未来医疗保健的前沿。
数据爆炸!
来自设备的数据呈指数级增长,在转化为其他人可以使用的信息之前,这本身没有任何意义。除非转化为有价值的可操作见解,否则转化为知识的数据也将用途有限。这些在特定领域具有巨大价值的见解需要进一步适应多领域、跨职能的智慧,以改变游戏策略和保持竞争优势。大数据是*年来互联事物数量空前激增的产物。核心是数据科学,通过算法设计、人工智能、机器学习、统计学、建模等来分析数据。,以使它在现实世界中一致地工作,跨不同的域,跨不同的基础设施,并为多个用户服务。
介意差距!
新技术在变得普遍之前,通常会面临现实世界的运营挑战。物联网也不例外。为了加快物联网的采用,需要立即解决的关键问题如下:
a)安全性:去年,FDA 史无前例地召回了 4,50000 个易受网络威胁的起搏器。强生公司去年就其胰岛素泵的一个安全漏洞警告了顾客。这意味着黑客可能会给用户注射致命剂量的药物!植入设备也有被黑客攻击和被别人控制的风险!
在一个高度互联的世界里,数据的安全性仍然是人们最关心的问题。这种情绪反映在全球范围内物联网安全年度支出的不断攀升上。高度集成系统的高度自动化带来了系统性风险的脆弱性,例如,如果其中一个部分发生故障,例如黑客或互联网病毒可以完全入侵集成系统,整个网络就会崩溃。
为了解决这些不对称问题,需要考虑在物联网网络的一部分因暴露于恶意软件/病毒或其他可在开放网络中快速传播的非数字威胁而崩溃时的安全退出或遏制策略。已经提出了各种级别的安全结构,许多正在开发中。它们被授权在不损害创新生态系统及其组成部分的长期安全性和可持续性的情况下构建复杂的数字网络。以下是在未来应用中带来对称性的三个措施:(a)考虑数字网络的内置安全出口;(b)认识到加速/减速的必要性;以及技术政策的全球治理创新。
一些公司已经在这一领域处于领先地位。英特尔提供了来自英特尔、Wind River 和 McAfee 的技术组合,将安全层整合到硬件、嵌入式操作系统和安全软件中,以确保智能电网中的端到端安全性。这些功能无法被流氓软件更改,并在安全的分区中运行应用程序,同时保护重要的*台数据并防止恶意软件启动。
b)互操作性:随着多家公司在不同领域提供各种支持物联网的服务和产品,信息碎片化导致不同格式数据的访问和使用受限的风险可能会成为采用和最大化物联网潜力的瓶颈。因此,*台和网络无缝集成的需求变得至关重要。
为了在*台之间实现更好的通信,这意味着将广泛的协议结合在一起,包括 2G、3G、LTE、LTN、wan,以及专业电信服务提供商、硬件和软件公司的参与。如果未连接的基础设施中存在的数据得到最佳实现,物联网将提供巨大的机会。开放的互操作性标准和通用架构对于将传统设备连接到数据中心和云基础设施至关重要,这将实现端到端分析,进而实现其优势。这绝不是一件容易的事;然而,已经朝着这个方向迈出了初步的步伐。
美国电话电报公司、思科、通用电气、IBM 和英特尔已经成立了工业互联网联盟(IIC),这是一个开放成员的非营利组织,将率先在各种工业环境中建立互操作性。人们希望这将转化为一个更加互联的世界。
c)隐私:当数据被收集和上传到云服务器时,无论是私有的还是公共的,数据隐私都是一个大问题。HIPAA(健康保险便携性和责任法案)为保护以电子方式创建、接收、维护或传输的患者数据制定了标准。由于现在有传感器自动收集和存储医疗数据,个人数据的安全性变得更加重要。这使得许多医院无法采用网络容量来存储患者数据和其他医疗信息。
2017 年底,北美、西欧和大中华区占全球物联网的 67%。这导致了第二个更具社会性而非技术性的担忧——极端的连通性创造了新的社会和政治权力结构。这可能导致少数人的独裁或支配性治理,这些人直接或通过其有联系的代理人间接完全控制着网络。在所谓的工业 4.0 Plus 或工业 5.0 中,已经提出了有效利用数字能力和治理的新模式。其伦理、法律和社会影响(ELSI)也在学术辩论中。
Pesala 博士和 Lakshmanan 博士强调了与物联网在大规模实施中的有效使用有关的其他几个问题,即标准化和数据互操作性,以及部署物联网系统的相对较高的成本。物联网边缘设备的认证和授权缺乏标准,此外,*台配置的安全标准也不成熟。许多物联网系统的设计很差,并且使用各种协议和技术实施,有时会产生复杂和冲突的配置。许多物联网运营商的额外网络安全措施不足仍然是一个主要问题。
已经在努力实现*台之间的无缝数据交换和分析。随着越来越多的行业采用物联网系统,这些系统的成本也在下降。几年后,随着更多利益相关方的参与,这一数字有望进一步下降。
到目前为止,我们所目睹的只是开始,本质上只是冰山一角。正如我们今天所知,随着物联网缓慢而稳定地创建几乎所有行业的后端,无论是当前行业还是新兴行业,不久的将来都会有巨大的前景。
(这篇文章作为封面故事发表在 2018 年 5 月至 6 月发行的《发明情报》杂志上,这是印度政府国家研究发展公司的出版物)。
为初创企业、政府和行业实习
原文:https://towardsdatascience.com/interning-for-start-ups-government-and-industry-e426604688cb?source=collection_archive---------22-----------------------
I’m about one engine tall!
我在不同团体、机构和公司工作时的轶事。
在大学本科期间,我有幸获得了几份实习和合同职位。大二的夏天,我为一家名为 Graba Engineering 的小型工程咨询初创公司工作;接下来是在卡纳维拉尔角为美国宇航局实习;我最后的实习是在康宁公司,一家玻璃和陶瓷公司。
积累了来自初创企业、政府和企业的经验后,我想我可以分享一些每个工作场所及其文化的趣闻。寻找实习机会并对实习充满好奇的工科学生会发现这篇文章很有意义。
初创企业:格拉巴工程有限责任公司
当我加入 Graba 的时候,他们正在研究一项相当奇怪的技术。一位客户带着保存断肢的想法来到这家初创公司。这项技术被设计得很小,大约是视频游戏控制台的大小,并打算由应急响应车辆和军事战地医务人员携带。
使用新颖的、偶尔不可靠的技术是初创企业的共同主题。这并不是说人们不会在工业和政府中看到新技术。早期的初创企业没什么可损失的,可以说他们会在产品上冒更大的风险。此外,考虑到初创企业受到资源的极大限制,新手实习生直接使用新技术的可能性更大。
在波音公司收购奥罗拉飞行科学公司(Aurora Flight Sciences)之前,我的一位电气工程同事曾在该公司工作。AFS 是一家专注于航空研究的初创公司,最著名的是他们在太阳能和电动垂直起降飞行器方面的工作。我的朋友直接在 AFS 的奥德修斯的动力系统上工作,这是一架完全由太阳能驱动的飞机。同样,我直接研究了这台保肢机的电子设备。
Odysseus concept model, a terrific opportunity for an intern! (Credit: Aurora Flight Sciences)
能够为一个新颖项目的成功(或失败)做出贡献,本身就有精神上的回报。对于务实的实习生来说,在初创企业工作将会获得丰富的经验。小型初创企业必须同时兼顾管理、财务和多学科工程任务。在 Graba,大量的任务要求我涉猎电路、PCB 设计、电力电子、微控制器编程、传感器通信和系统集成。在工作结束时,由于 CEO 的日程安排很紧,我甚至向客户演示了这项技术。
虽然工作量和期望可能会很高,但初创企业的环境却出人意料地宽松。我可以自己安排时间,只要项目和需求在截止日期前交付。不需要向我的经理汇报或与他交谈来获得批准,这是业内的一个重要协议。个人责任的氛围允许很大程度的独立性。
政府:美国航天局
美国国家航空航天局对作为一名工程师在政府部门工作的感受进行了有限的介绍。大部分政府工程都是国防工程。尽管如此,在美国国家航空航天局实习带来了一系列独特的故事。
与在初创公司工作类似,你会有一种 NASA 人手不足的感觉。总是有工作要做,但没有足够的人或时间去做。考虑到 NASA 任务的规模,这是意料之中的。毕竟,我们正在努力到达火星。
对于实习生来说,无限量的工作确实显现了出来。作为自动化测试团队的成员,我和我的团队每周都会为软件抽取数百个测试。然而,我们的经理一直鼓励我们完成更多。不幸的是,本科生实习生受到他们贡献能力的限制。火箭科学需要相当熟练的能力。因此,我们作为软件实习生所做的许多工作对于中级程序员来说并不太具有挑战性。
不管是哪种工作,为政府工作都有一种强烈的感觉。特别是在 NASA,你的工作会产生影响。看到自己的贡献飞向太空的敬畏之情让人充满力量。很少有人能说他们为人类探索太空做出了贡献。在美国宇航局,许多员工都有一种与生俱来的情感:他们的工作服务于一个更大的目标。我自己作为一个太空极客,也热情地加入了这种心态。
除了观察火箭发射和科学进步,在美国国家航空航天局工作还有许多精彩的故事。由于美国国家航空航天局与联邦政府的密切联系,我见到了副总统彭斯、参议员卢比奥、巴兹·奥德林和许多其他宇航员。
除了这些故事、工作和经历,为政府工作唯一显著的缺点就是工资。任何政府机构——中央情报局、联邦调查局、环境保护局——都不太可能有能力与私营部门的薪水竞争。还有一线希望。缺乏金钱激励肯定了员工对他们所在行业的热情和承诺。简单来说,工程师在 NASA 工作不是为了钱,而是为了旅程。
行业:康宁公司。
我在康宁的第一项任务就是为我参与的项目挑选要购买的电子零件。从吃拉面和借用亚马逊 Prime 账户的简朴大学生活中,我开始寻找最便宜的工具来完成这项工作。更让我懊恼的是,我后来被资深员工取笑,因为我买了一个便宜而复杂的工具,而不是挥霍在一个更昂贵且可能对用户友好的设备上。
康宁强调支持公司相关研究。实际上,员工每月都有津贴,可以用来购买与研究相关的产品。一天,我隔壁隔间的实习生拿着各种各样的树莓派进来。接下来的一周,他带着一台等离子电视走进了光学实验室。作为康宁公司的工程师,资源是无限的。薪水也反映了这一点。
然而,这种挥金如土的态度在管理层和整个公司产生了相同和相反的反应。金钱激励在工业中非常明显。虽然早期初创企业确实有有利可图的潜在因素,但康宁等公司非常清楚地向股东表明了他们的优先考虑。
Last Day of Work!
关于实习工作,我从来没有在办公室感到难以置信的压力或挑战。我偶尔不得不搜索任务,并且给出的任务完成得相当快。这很奇怪,因为并不缺少工作。全职员工一直很忙。其他工程学科的几个实习生有要求很高的项目。尽管如此,许多软件实习生确实显得缺乏责任感。
也许这是这家公司独有的,但康宁没有其他两次经历那样的精神或雄心。对我所在部门的许多人来说,这份工作很方便,也有点意思。此外,各部门感觉严重分裂。员工们乐于保持自己的圈子,很少与其他部门和分支机构交往。
也就是说,康宁有一种社区和家庭意识。康宁家族,一个被重点强调的格言,在众多的公司郊游、内部团队和拓展计划中显而易见。主管在截止日期方面很严厉,但是理解和关心个人问题。康宁公司为自己寻找出路。
不管学生决定涉足哪个领域,实习都是非常受鼓励的。实习将会给你学生时代最实际、最愉快的经历。前面提到的三种经历确实触及了各种工作类型中的一些普遍主题,但声称它们代表了绝对的主题是错误的。例如,许多现代科技公司正在采用年轻初创企业的主题。任何公司都有自己独特的怪癖、好处和缺点。获得实习机会将有助于学生对去哪里工作做出自己的判断。
我最*在 Medium 上超过了 100 名粉丝。感谢所有喜欢和支持我内容的人!
具有深度生成模型的插值
原文:https://towardsdatascience.com/interpolation-with-generative-models-eb7d288294c?source=collection_archive---------3-----------------------
生成模型如何学习创造新事物
在这篇文章中,我将写关于生成模型。它将涵盖生成模型和判别模型之间的二分法,以及生成模型如何通过能够执行插值来真正了解感兴趣对象的本质。
0.生成模型(G)与判别模型(D)
老实说,在生成对抗网络(GANs)起飞后,我才开始思考统计和机器学习模型的本质。在 GAN 的原始版本中,让我们称之为香草 GAN,你有一个生成网络(G ),它从高斯噪声中生成合成数据,还有一个鉴别网络(D ),它试图区分真假。显然,香草甘中的 G 和 D 分别是生成模型和判别模型。事实上,GAN 可能是第一个协调生成和判别模型的 ML 算法,它通过创新的对抗训练来学习两个模型的参数。
Image source: https://www.slideshare.net/ckmarkohchang/generative-adversarial-networks
我自己的经验就说这么多,什么是生成式和判别式模型?直觉上,生成模型试图抽象出一些对象集合的一些可概括的模式,而鉴别模型试图发现集合之间的差异。具体来说,在分类问题的背景下,例如,生成模型将学习每个类的特征,而判别模型将找到最好地分离类的决策边界。更正式地说,让我们将实例表示为由一些标量值 y、标记的特征向量【x】生成模型学习联合概率分布p(x,y)、而判别模型学习条件概率分布(y |x
还有一些有趣的生成器-鉴别器对可以考虑:
- 二元分类:朴素贝叶斯与逻辑回归
- 序列建模:隐马尔可夫模型与条件随机场
值得一提的是,大多数传统的最大似然分类器都是判别模型,包括逻辑回归、SVM、决策树、随机森林、LDA。判别模型在需要学习的参数方面很少,并且已经被证明在许多分类任务中比它们的生成模型具有更好的性能。
但是我想说的是,学习区分一个类和另一个类并不是真正的学习,因为当处于另一个环境中时,它通常不起作用。例如,当一个看不见的类(狗)被添加到测试集中时,被训练来以异常的准确度区分猫和鸟的鉴别分类器可能会悲惨地失败,因为鉴别分类器可能简单地知道有四条腿的东西是猫,否则是鸟。
为了进一步说明生成性和判别性模型真正学到了什么,让我们考虑一下最简单的分类模型,朴素贝叶斯和逻辑回归。下图显示了朴素贝叶斯和逻辑回归分类器在二元分类问题上获得的“知识”。
朴素贝叶斯分类器学习两个类的均值和方差向量,而逻辑回归学习线性边界的斜率和截距,以最佳方式分隔两个类。利用从朴素贝叶斯分类器中学习的均值和方差,我们可以通过从多元高斯分布中采样来为每个类生成合成样本。这类似于使用 GANs 生成合成样本,但显然朴素贝叶斯无法生成任何高质量的高维图像,因为它太幼稚,无法独立地对特征进行建模。
1.生成模型
我简单地提到了朴素贝叶斯算法,它可以说是生成模型的最简单形式。现代生成模型通常涉及深度神经网络架构,因此称为深度生成模型。有三种类型的深度生成模型:
- 可变自动编码器(VAE)
- 开始
- 基于流程的生成模型(一个关于这类模型的优秀博客
1.1.VAE
VAE 由金玛&韦林,2014 推出,作为自动编码器(AE)的概率扩展。与 vanilla AE 相比,它有以下三个附加功能:
- 概率编码器 qϕ( z | x 和解码器 pθ( x | z
- 潜在空间(AE 的瓶颈层)的先验概率分布:pθ( z
- 由 Kullback-Leibler 散度定义的潜在损失:d(qϕ(z|x)‖pθ(z|x))来量化这两个概率分布之间的距离
VAE illustration from https://lilianweng.github.io/lil-log/2018/08/12/from-autoencoder-to-beta-vae.html
1.2.甘斯
GAN 是由 Goodfellow et al .,2014 介绍的,由一对生成器和鉴别器网络组成,彼此进行一场极小极大博弈。GAN 的许多变体已经被开发出来,例如双向 GAN(甘比)、CycleGAN、InfoGAN、Wasserstein GAN 和这个列表还在继续增长。
特别吸引人,因为它明确地学习一个编码器网络,E()x)将输入映射回潜在空间:
Figure source: Donahue et al, 2016 Adversarial Feature Learning
2.生成模型插值
有了一些深层生成模型的知识,我们将检查它们的能力。生成模型能够学习来自不同类别的样本的低维概率分布。这种概率分布可用于监督学习和生成合成样本。虽然这些功能非常有用,但让我印象更深的是生成模型能够沿着任意轴对真实样本执行插值,以生成不存在的操纵样本。例如,深度生成模型可以沿着年龄、性别、头发颜色等轴操纵人脸图像。在我看来,这表明深度生成模型能够获得想象的能力,因为想象是产生心理图像的过程。接下来让我们深入研究如何执行插值。
插值通过在生成模型学习的潜在空间( z )中执行简单的线性代数来工作。首先,我们想在潜在空间中找到一个轴来进行插值,它可以是类似生物性别的东西。生物性别的插值向量可以简单地计算为潜在空间中从雄性质心指向雌性质心的向量。
更一般地,我们首先需要在潜在空间中找到两类质心( a , b ):
****
从类别 b 指向类别 a 的潜在空间中的插值向量为:
给定任何类别x _**c的任何看不见的样本,我们可以通过以下方式用插值向量操纵看不见的样本:1)将样本编码到潜在空间中;2)在潜在空间中执行线性插值;以及 3)将内插样本解码回原始空间:**
****
上式中的 α 是决定插值大小和方向的标量。接下来,我将围绕 α 沿着不同的插值向量滑动。以下 Python 函数可使经过训练的创成式模型执行此类插值:
3.基于 MNIST 数据的生成模型实验
我在 MNIST 手写数字数据集上训练了一些生成模型,包括朴素贝叶斯、VAE 和甘比,以实验插值。下图显示了瓶颈层只有两个神经元的 VAE 的潜在空间。虽然不同的数字有不同的模式,但重建质量很差。也许将 784 维空间压缩到 2 维空间是一个挑战。我发现瓶颈层有 20 个神经元的 VAE 可以重建质量不错的 MNIST 数据。
Latent space learned by a VAE with 2 neurons at the bottleneck layer
还值得指出的是,生成模型的训练是不受监督的。因此,学习的潜在空间不知道类别标签。插值向量是在模型完成学习后计算的。
为了进行插值,我首先可视化了 10 个数字的所有 45 个可能对之间的插值向量:
Visualization of the interpolation vectors of MNIST digits in the latent space of a VAE with 20 neurons at the bottleneck layer
在上图中,每行对应一个从一个数字指向另一个数字的插值向量,而每列对应一个 alpha 值。从左到右观察潜在空间产生的数字,看一个数字如何逐渐变成另一个数字,这很有趣。由此,我们还可以找到位于 10 位数字的两个质心之间的模糊数字。
接下来,我做了另一个有趣的插值实验:我问我们是否可以通过沿着 6->0 向量移动数字 7 来将它变成数字 6 或 0。以下是生成图像的结果。它在右边显示了一些看起来相对 0 的图像,而左边的看起来一点也不像 6。
也可以使用在 MNIST 上训练的逻辑回归分类器来量化这些图像,以预测标记的概率。分类器非常符合我们目测图像的感觉。
Predicted probability for the images of interpolated digits from a Logit classifier
用 MNIST 数据集进行的看似无聊的概念验证实验展示了深度生成模型的想象能力。我可以想象插值的许多实际应用。
如果你想了解更多的技术细节,这篇文章基于我的 GitHub repo:
** [## Wang 10/创成式模型
MNIST -王 10/生成模型实验深度生成模型教程
github.com](https://github.com/wangz10/Generative-Models)
这篇文章的笔记本版本在 Ma'ayan 实验室会议上发表:
[## Jupyter 笔记本浏览器
看看这个 Jupyter 笔记本!
nbviewer.jupyter.org](https://nbviewer.jupyter.org/github/wangz10/Generative-Models/blob/master/Main.ipynb)
参考
- Ng AY & Jordan MI:论区别量词与生成量词
- 金玛&韦林:自动编码变分贝叶斯
- 古德菲勒·IJ 等人:生成敌对网络
- 多纳休等人:对抗性特征学习
- 基于流程的深度生成模型
- 辉光:更好的可逆生成模型**
可解释性和随机森林
原文:https://towardsdatascience.com/interpretability-and-random-forests-4fe13a79ae34?source=collection_archive---------8-----------------------
我们如何以及为什么可以从随机森林分类器中获得特征重要性?
机器学习的出现是因为人类不能总是很好地解释我们自己,尤其是对机器。在很长一段时间里,机器只能执行精确的逐步指令,而简单的人工任务对我们来说太自然了,以至于我们无法明确地将它们作为算法写下来。以识别某物是猫为例——我无法向你或计算机解释我是如何确切地知道某物是猫的。事实上,从来没有人真正向我解释过:我只是遇到了一群猫,最终,作为一个优秀的小神经网络,我明白了要点。
You’ve got a lot to learn, kid.
我知道猫通常有两只耳朵,四条腿,圆圆的脸型,还有那双独特的猫眼,但这只是解开了第一层解释。在此基础上,我必须用算法解释上一句中每个形容词和名词的意思:二,耳朵,圆,等等。,以及详述诸如猫眼到底是什么样子之类的细节。理论上,我也许可以继续一项一项地解开这个问题——只是这可能会花费我大量的时间。
我们人类相当聪明地决定,对学习过程进行数学建模可能比用算法分解每个决策过程更容易,这就是我们如何开始机器学习的。然而,我们使用的学习模型并不总是符合任何一种“自然”的学习方法,建模学习并不能解决我们与计算机的基本交流问题。机器学习没有摆脱解释数据中关系的困难,这导致在建立和分析学习模型时可解释性和准确性之间的冲突。
可解释性和准确性之间的冲突
当谈到机器学习模型的使用时,数据科学几乎只有两个目标:
- 应用程序,通过它我们使用训练好的模型来执行任务,理想情况下尽可能准确有效。
- 解释,通过学习特征和响应变量之间的关系,我们使用训练好的模型来获得对数据的洞察力。
正如我们刚刚讨论的,我们人类几乎不知道我们实际上是如何识别事物的,但是我们真的很擅长。换句话说,我们大脑的内部逻辑是准确的,非常适合应用,但它不是很好解释。那么,通常最准确的机器学习方法是最不可解释的,这就不应该令人惊讶了。
RoboCat: First Contact
所谓的黑盒模型,如神经网络,给我们很少关于他们的决策过程的信息;他们学习的函数的代数复杂性倾向于失去关于原始特征变量集的任何意义。另一方面,线性回归和决策树等有助于解释的模型往往在准确性方面有所欠缺,因为它们往往无法捕捉数据集中任何细微或复杂的关系。我们可以将这种关系概括如下:
对于足够复杂的数据,在决策算法的可解释性和应用的准确性之间存在自然的权衡。
就像计算机没有理解猫的腿、眼睛和耳朵的天然亲和力一样,人类也没有对高阶数字关系的内在理解。我们无法有意义地解释神经网络的复杂决策边界,我们无法向计算机解释猫是什么,这是一个硬币的两面。在两个方向的转换中,有些东西会丢失。
找到*衡
我们史前穴居人的大脑似乎非常喜欢解释线性关系/决策边界。线性回归是一个高度可解释的算法,这是毫无疑问的:如果 x 增加 1 ,y 增加 m,,我们就都可以回家了。然而,线是简单的和高度偏向的,因此它们通常不适合伟大的学习算法。当然,我们可以调整我们对线性的定义,并扩展我们的基础,以包括多项式、指数和其他任何术语,但在某些时候债务必须偿还,我们失去了参数的自然意义。
Barney and Fred, excited about Linear Regression.
另一个简单易懂但本质上很弱的分类器是决策树:通过贪婪地将特征空间分割成矩形,我们最终得到了一个描述决策过程背后逻辑的漂亮图表——以及一个除了最基本的关系之外几乎毫无用处的模型。但是,回想一下,树模型非常适合集成方法,随机森林是一种特别强大的方法,可以将大量单独较弱的树聚合到一个强预测模型中。
随机森林和特征重要性
得知随机森林能够无视这种可解释性-准确性的权衡,或者至少将它推到极限,这似乎令人惊讶。毕竟,随机森林的决策过程存在固有的随机因素,而且有这么多树,任何固有的意义都可能在森林中迷失。然而,就像树一起工作来减少预测误差一样,它们一起工作来准确地表示特征的重要性。为了理解它们是如何做到这一点的,首先有必要了解一种解释单个树中的特性重要性的自然方法。
单一树中的特征重要性
回想一下,单个树旨在以局部最优的方式减少误差,因为它分割特征空间。分类树使用杂质的度量来对当前的类别分离进行评分,而回归树使用残差*方误差。我们将使用分类树的概念来使我们的可视化效果更好,但是在交换掉误差函数之后,回归情况是一样的…
减少杂质(或熵)是迭代分裂区域以减少决策树的分类错误的最快和最稳定的方法。衡量某个特性在决策过程中的影响的一种自然方法是查看该特性从系统中移除的熵值,即仅根据该特性的值所做决策获得的信息量或准确度。下面的可视化演示了我们分割特征空间和构建决策树的过程。我们从一个初始熵值( D )开始,我们计算每个子区域中的减少,然后对整个树中每个特征变量的熵的归因变化求和。
We start with D=1.31 and split feature space until we reach zero entropy. 1.011 of the reduction is due to decisions made on y, while x is only responsible for 0.299 of the reduction.
我以前说过,现在再说一遍:决策树是弱分类器。训练数据中的微小变化可能意味着我们最终会得到一个完全不同的树,从而对我们的特征重要性有不同的估计。在我们的观想中,考虑原始数据的这一微小变化:
Now the reduction in entropy due to x is 1.011 while the reduction due to y is 0.299. The variable importances have switched!
减少与许多树的差异
如果这种计算特征重要性的方法如此不稳定,对我们来说就没有多大用处了。问题是测量的方差太高,这就是随机森林的作用所在:回想一下,随机森林最终的工作方式是,首先通过从本质上消除个体树对局部最优策略的偏好并随机分割要素,然后通过聚合树来减少模型的整体方差。
这种方差的减少稳定了模型,减少了其对训练数据选择的偏差,并导致更少的变量和更准确的预测。如果像我们预测的那样,通过对每个特征变量的熵或准确度的变化取*均值,我们对随机森林中的树木的特征重要性的度量进行汇总,我们会获得完全相同的效果。
直观地说,对随机特征的分割使模型中的每个特征都有机会在树的所有可能点上显示其决策能力,而聚合减少了最终结果的可变性。本质上,与随机森林提高最终预测的准确性一样,它也提高了这种特征重要性度量的准确性。如果你不相信我,这里有一点证据:
A, B, C are all i.i.d
当用连续变量对抗分类变量时,这种方法有一些明确的问题;连续变量有更多的“空间”来分割,所以可以比分类变量多一点,但不一定更重要。这种方法也没有真正违反可解释性-准确性权衡的思想,因为它只真正告诉我们变量如何相互叠加,也就是说,它没有告诉我们如果我们增加或减少特征值(就像以前的线性回归一样),我们的决策会发生什么。但是,嘿,这很有用我从没说过随机森林是完美的。
不管怎样,现在你知道 scikit-learn RandomForestClassifier
上的feature_importances_
属性的力量了…但是你仍然不能解释猫对计算机来说是什么。哦好吧。
Later!
另外,这个博客很乱,也很粗糙,但是我想发表一些东西。我会花一天左右的时间来整理它。请给我发电子邮件,询问我在 thomasggrigg@gmail.com 需要澄清或反馈的任何问题
正在撰写的博文:内核技巧--偏差-方差权衡--深入探究随机森林的工作原理(我在这里稍微提到了一点)。
可解释性:打开黑匣子——第一部分
原文:https://towardsdatascience.com/interpretability-cracking-open-the-black-box-part-i-4bb0359853bd?source=collection_archive---------41-----------------------
我们怎样才能给 ML 中使用的黑盒带来可解释性?
可解释性是人类能够理解决策原因的程度 —米勒、蒂姆【1】
付费墙是否困扰着你? 点击这里 绕过去。
可解释的人工智能(XAI)是人工智能的一个子领域,在最*的过去已经取得了进展。作为一名日复一日与客户打交道的机器学习实践者,我明白为什么。我已经做了 5 年多的分析从业者,我发誓,机器学习项目最困难的部分不是创建一个击败所有基准的完美模型。这是你说服客户为什么和如何工作的部分。
面对未知事物,人类总是一分为二。我们中的一些人用信仰来对待它并崇拜它,就像我们崇拜火、天空等的祖先一样。我们中的一些人变得不信任。同样,在机器学习中,有人对模型的严格测试(即模型的性能)感到满意,有人想知道模型为什么以及如何做它正在做的事情。这里没有对错之分。
图灵奖获得者、脸书首席人工智能科学家 Yann LeCun 和谷歌首席决策智能工程师 Cassie Kozyrkov 都是这种思想的强烈支持者,即你可以通过观察模型的行动(即在监督学习框架中的预测)来推断模型的推理。另一方面,微软研究院的 Rich Caruana 和其他几个人坚持认为,模型天生具有可解释性,而不仅仅是通过模型的性能得出的。
我们可以花数年时间来辩论这个话题,但对于人工智能的广泛采用,可解释的人工智能是必不可少的,并且越来越多地来自行业的需求。因此,在这里我试图解释和演示一些可解释性技术,这些技术对我向客户解释模型以及研究模型并使其更加可靠都很有用。
什么是可解释性?
可解释性是人类能够理解决策原因的程度。在人工智能领域,它意味着一个人能够理解算法及其预测的方式和原因的程度。有两种主要的方式来看待这个问题——和 事后解释 。
透明度
透明度解决了模型可以被理解的程度。这是我们使用的模型所固有的。
这种透明性的一个关键方面是可模拟性。可模拟性表示模型被人类严格模拟或思考的能力[3]。模型的复杂性在定义这一特征时起了很大的作用。虽然简单的线性模型或单层感知器很容易考虑,但考虑深度为 5 的决策树变得越来越困难。考虑一个有很多特性的模型也变得更加困难。因此,稀疏线性模型(正则化线性模型)比密集线性模型更容易解释。
可分解性是透明的另一个主要原则。它代表解释模型的每个部分(输入、参数和计算)的能力[3]。它需要解释从输入(没有复杂的特性)到输出的一切,而不需要另一个工具。
透明的第三个原则是算法透明。这涉及算法固有的简单性。它涉及人类完全理解算法将输入转换为输出的过程的能力。
事后口译
当模型本身不透明时,事后解释是有用的。因此,在不清楚模型如何工作的情况下,我们求助于用多种方式解释模型及其预测。Arrieta、Alejandro Barredo 等人将它们汇编并分类为 6 个主要类别。我们将在这里讨论其中的一些。
- 可视化解释——这些方法试图将模型行为可视化,并试图解释它们。属于这一类别的大多数技术使用降维等技术,以人类可理解的格式可视化模型。
- 特性相关性解释——这些方法试图通过计算特性相关性或重要性来揭示模型的内部工作原理。这些被认为是解释模型的间接方式。
- 通过简化来解释——这套方法试图在原始模型的基础上训练全新的系统来提供解释。
由于这是一个广泛的话题,涵盖所有内容将是一个庞大的博客帖子,我把它分成多个部分。我们将在当前部分讨论可解释的模型和其中的“陷阱”,并将事后分析留给下一部分。
可解释的模型
奥卡姆剃刀理论认为简单的解决方案比复杂的更有可能是正确的。在数据科学中,奥卡姆剃刀通常与过度拟合联系在一起。但是我相信它同样适用于可解释性。如果您可以通过透明模型获得想要的性能,那么就不要再寻找完美的算法了。
Arrieta、Alejandro Barredo 等人总结了 ML 模型,并在一个漂亮的表格中对它们进行了分类。
线性/逻辑回归
由于 Logistic 回归在某种程度上也是线性回归,所以我们只重点研究线性回归。我们拿一个小数据集( auto-mpg )来考察一下模型。数据涉及城市循环油耗,单位为每加仑英里数,以及汽车的不同属性,如:
- 圆柱体:多值离散
- 位移:连续
- 马力:连续
- 重量:连续
- 加速度:连续
- 年款:多值离散型
- 起源:多值离散
- 汽车名称:字符串(对于每个实例是唯一的)
加载数据后,第一步是运行 pandas_profiling 。
*import pandas as pd
import numpy as np
import pandas_profiling
import pathlib
import cufflinks as cf
#We set the all charts as public cf.set_config_file(sharing='public',theme='pearl',offline=False) cf.go_offline()
cwd = pathlib.Path.cwd()
data = pd.read_csv(cwd/'mpg_dataset'/'auto-mpg.csv')
report = data.profile_report() report.to_file(output_file="auto-mpg.html")*
只需一行代码,这个出色的库就可以为您完成初步的 EDA。
Snapshot from the Pandas Profiling Report. Click here to view the full report.
数据预处理
- 马上,我们看到汽车名称在 396 行中有 305 个不同的值。所以我们放弃这个变量。
- **马力被解释为分类变量。经过调查,它有一些行带有“?”。将它们替换为列的*均值,并将其转换为浮点型。
- 它还显示了位移、气缸和重量之间的多重共线性。让我们暂时把它留在那里。
在 python 世界中,线性回归在 Sci-kit Learn 和 Statsmodels 中可用。它们给出了相同的结果,但是 Statsmodels 更倾向于统计学家,Sci-kit Learn 更倾向于 ML 从业者。让我们使用 statsmodels,因为它提供了开箱即用的漂亮摘要。
*X = data.drop(['mpg'], axis=1)
y = data['mpg']
## let's add an intercept (beta_0) to our model
# Statsmodels does not do that by default
X = sm.add_constant(X)
model = sm.OLS(y, X).fit()
predictions = model.predict(X)
# Print out the statistics
model.summary()
# Plot the coefficients (except intercept) model.params[1:].iplot(kind='bar')*
**
这里的解释非常简单。
- 截距可以解释为在所有自变量都为零的情况下你所预测的里程。这里的“问题”是,如果独立变量可以为零是不合理的,或者如果在线性回归训练的数据中没有这种情况,那么截距是没有意义的。它只是将回归锚定在正确的位置。
- 这些系数可以被解释为因变量的变化,它将驱动自变量的单位变化。例如,如果我们增加 1 的重量,里程将减少 0.0067
- 一些特征,如气缸、年款等,本质上是明确的。这些系数需要解释为不同类别之间的*均里程差异。这里还有一点需要注意的是,所有的分类特征在本质上都是有序的(圆柱体越多意味着里程越少,或者模型年份越高,里程越多),因此可以让它们保持原样并运行回归。但如果情况不是这样,哑元或一次性编码分类变量是可行的。
现在来看特征重要性,看起来产地和车型年份是驱动该车型的主要特征,对吗?
没有。我们来详细看一下。为了阐明我的观点,让我们看几行数据。
**原点有 1、2 等值。, model_year 的值类似于 70、80 等。重量的值有 3504、3449 等。,mpg(我们的因变量)有 15,16 等值。你看到这里的问题了吗?要建立一个输出 15 或 16 的方程,该方程需要一个小的权重系数和一个大的原点系数。
那么,我们该怎么办?
回车,标准化回归系数。
我们将每个系数乘以自变量的标准偏差与因变量的标准偏差之比。标准化系数是指预测变量每增加一个标准差,因变量将改变多少个标准差。
*#Standardizing the Regression coefficients std_coeff = model.params for col in X.columns: std_coeff[col] = (std_coeff[col]* np.std(X[col]))/ np.std(y) std_coeff[1:].round(4).iplot(kind='bar')*
画面真的变了,不是吗?汽车的重量是决定行驶里程的最大因素,其系数几乎为零。如果你想获得标准化背后更多的直觉/数学,建议你看看这个 StackOverflow 答案。
获得类似结果的另一种方法是在拟合线性回归之前标准化输入变量,然后检查系数。
*from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_std = scaler.fit_transform(X)
lm = LinearRegression()
lm.fit(X_std,y)
r2 = lm.score(X_std,y)
adj_r2 = 1-(1-r2)*(len(X)-1)/(len(X)-len(X.columns)-1)
print ("R2 Score: {:.2f}% | Adj R2 Score: {:.2f}%".format(r2*100,adj_r2*100))
params = pd.Series({'const': lm.intercept_})
for i,col in enumerate(X.columns):
params[col] = lm.coef_[i]
params[1:].round(4).iplot(kind='bar')*
即使实际系数不同,特征之间的相对重要性保持不变。
线性回归中的最后一个“陷阱”通常是多重共线性和 OLS。线性回归是解决使用 OLS,这是一个无偏估计。即使听起来是好事,其实也不一定。这里的“无偏”是指求解过程不考虑哪个自变量比其他变量更重要;即,它对独立变量是无偏的,并且努力获得最小化残差*方和的系数。但是我们真的想要一个最小化 RSS 的模型吗?提示:RSS 是在训练集中计算的。
在偏差与方差的权衡中,存在一个最佳点,在这个点上你可以获得*衡过度拟合的最佳模型复杂度。通常,因为很难估计偏差和方差来进行分析推理并达到最佳点,所以我们采用基于交叉验证的策略来达到同样的目的。但是,如果你想一想,在线性回归中没有真正的超参数可以调整。
而且,由于估计量是无偏的,它会将一部分贡献分配给它可用的每个特征。当存在多重共线性时,这就成了一个更大的问题。虽然这不会对模型的预测能力产生太大影响,但会影响模型的可解释性。当一个特征与另一个特征或特征组合高度相关时,该特征的边际贡献受到其他特征的影响。因此,如果数据集中存在强烈的多重共线性,回归系数将会产生误导。
进入正规化。
几乎任何机器学习算法的核心都是最小化成本函数的优化问题。在线性回归的情况下,成本函数是残差*方和,它只不过是由系数参数化的预测值和实际值之间的*方误差。
Source: https://web.stanford.edu/~hastie/ElemStatLearn/
为了增加正则化,我们在优化的成本函数中引入了一个附加项。成本函数现在变成:
**
在岭回归中,我们将所有*方系数之和添加到成本函数中,在 Lasso 回归中,我们添加了绝对系数之和。除此之外,我们还引入了一个参数λ,这是一个超参数,我们可以调整它来达到最佳的模型复杂度。并且由于 L1 和 L2 正则化的数学性质,对系数的影响略有不同。
- 岭回归将它认为不太重要的独立变量的系数缩小到接*零。
- 套索回归将它认为不太重要的独立变量的系数缩小到零。
- 如果存在多重共线性,Lasso 会选择其中一个并将另一个缩小到零,而 Ridge 会将另一个缩小到接*零。
由 Hastie,Tibshirani,Friedman 撰写的《统计学习的要素》给出了以下指导方针:当你有许多中小型效果时,你应该使用 Ridge。如果你只有几个中/大效果的变量,用套索。你可以看看这个媒体博客,它相当详细地解释了正规化。作者也给出了一个简洁的总结,我在这里借用一下。
*lm = RidgeCV()
lm.fit(X,y)
r2 = lm.score(X,y)
adj_r2 = 1-(1-r2)*(len(X)-1)/(len(X)-len(X.columns)-1)
print ("R2 Score: {:.2f}% | Adj R2 Score: {:.2f}%".format(r2*100,adj_r2*100))
params = pd.Series({'const': lm.intercept_})
for i,col in enumerate(X.columns):
params[col] = lm.coef_[i]
ridge_params = params.copy() lm = LassoCV()
lm.fit(X,y)
r2 = lm.score(X,y)
adj_r2 = 1-(1-r2)*(len(X)-1)/(len(X)-len(X.columns)-1)
print ("R2 Score: {:.2f}% | Adj R2 Score: {:.2f}%".format(r2*100,adj_r2*100))
params = pd.Series({'const': lm.intercept_})
for i,col in enumerate(X.columns):
params[col] = lm.coef_[i]
lasso_params = params.copy()ridge_params.to_frame().join(lasso_params.to_frame(), lsuffix='_ridge', rsuffix='_lasso')*
我们只是对相同的数据进行了岭和套索回归。岭回归给出了与原始回归完全相同的 R2 和调整后的 R2 分数(分别为 82.08%和 81.72%),但系数略有缩小。Lasso 给出了较低的 R2 和调整后的 R2 得分(分别为 76.67%和 76.19%),并有相当大的收缩。
如果你仔细观察这些系数,你会发现岭回归并没有减少多少系数。唯一真正缩水的地方是位移和原点。这可能有两个原因:
- 位移与圆柱体(0.95)有很强的相关性,因此它被缩小了
- 原始问题中的大部分系数已经接*于零,因此收缩非常小。
但是如果你看看 Lasso 是如何缩小系数的,你会发现它相当有侵略性。
作为一个经验法则,我建议总是使用某种正规化。
决策树
让我们为这个练习选择另一个数据集——世界著名的虹膜数据集。对于那些一直生活在岩石下的人来说,Iris 数据集是对三种花卉进行测量的数据集。一种花与另外两种花是线性可分的,但是另外两种花彼此不是线性可分的。
该数据集中的列是:
- 身份
- SepalLengthCm
- SepalWidthCm
- PetalLengthCm
- PetalWidthCm
- 种类
我们删除了“Id”列,对物种目标进行了编码,使其成为目标,并在其上训练了一个决策树分类器。
让我们看看决策树中的“特征重要性”(我们将在博客系列的下一部分详细讨论特征重要性及其解释)。
*clf = DecisionTreeClassifier(min_samples_split = 4) clf.fit(X,y) feat_imp = pd.DataFrame({'features': X.columns.tolist(), "mean_decrease_impurity": clf.feature_importances_}).sort_values('mean_decrease_impurity', ascending=False) feat_imp = feat_imp.head(25) feat_imp.iplot(kind='bar', y='mean_decrease_impurity', x='features', yTitle='Mean Decrease Impurity', xTitle='Features', title='Mean Decrease Impurity', )*
在这四个特征中,分类器仅使用花瓣长度和花瓣宽度来区分这三类。
让我们使用出色的库 dtreeviz 来可视化决策树,看看模型是如何学习规则的。
*from dtreeviz.trees import * viz = dtreeviz(clf, X, y, target_name='Species', class_names=["setosa", "versicolor", "virginica"], feature_names=X.columns) viz*
模型如何做它正在做的事情是非常清楚的。让我们向前一步,想象一个特定的预测是如何做出的。
*# random sample from training x = X.iloc[np.random.randint(0, len(X)),:] viz = dtreeviz(clf, X, y, target_name='Species', class_names=["setosa", "versicolor", "virginica"], feature_names=X.columns, X=x) viz*
如果我们只使用决策树选择的两个特征重新运行分类,它会给出相同的预测。但是线性回归这样的算法就不一样了。如果我们移除不满足 p 值临界值的变量,模型的性能也可能会下降一些。
解释决策树要比线性回归简单得多,尽管它有很多奇怪的地方和假设。统计建模:Leo Breiman 的《两种文化》是理解解释线性回归中的问题的必读之作,它还从性能和可解释性两方面论证了决策树甚至随机森林优于线性回归的情况。(免责声明:如果你还没有想到,利奥·布雷曼是《随机森林》的创始人之一)**
这就是我们博客系列的第一部分。请继续关注下一部分,我们将探索诸如排列重要性、Shapely 值、PDP 等事后解释技术。
我的 Github 中有完整的代码
参考文献
- 米勒蒂姆。"人工智能中的解释:来自社会科学的见解."arXiv 预印本 arXiv:1706.07269。(2017)
- 可解释的人工智能(XAI):面向负责任的人工智能的概念、分类学、机遇和挑战。艾]
- Guidotti,Ricardo 等,“解释黑盒模型的方法综述”arXiv:1802.01933 [cs .CY]
原载于 2019 年 11 月 12 日【http://deep-and-shallow.com】。
可解释性:打开黑匣子——第二部分
原文:https://towardsdatascience.com/interpretability-cracking-open-the-black-box-part-ii-e3f932b03a56?source=collection_archive---------35-----------------------
杂质的*均减少,排列的重要性?LOOC 重要性、PDP 图等
付费墙是否困扰着你? 点击这里 可以绕过去。
在本系列的最后一篇文章中,我们定义了什么是可解释性,并查看了几个可解释性模型以及其中的怪癖和“陷阱”。现在,让我们更深入地研究事后解释技术,当您的模型本身不透明时,这种技术很有用。这与大多数真实世界的用例产生了共鸣,因为无论我们喜欢与否,我们都可以通过黑盒模型获得更好的性能。
数据集
在本练习中,我选择了成人数据集,也称为人口普查收入数据集。人口普查收入是一个非常受欢迎的数据集,它有人口统计信息,如年龄、职业,还有一列告诉我们特定人的收入是否为 50k。我们使用该列来运行使用随机森林的二元分类。选择随机森林有两个原因:
- 随机森林和梯度增强树是最常用的算法之一。这两种算法都来自于决策树集成算法家族。
- 我想讨论一些特定于基于树的模型的技术。
事后口译
现在,让我们看看做事后解释的技术,以理解我们的黑盒模型。在博客的其余部分,讨论将基于机器学习模型(而不是深度学习),并将基于结构化数据。虽然这里的许多方法都是模型不可知的,但由于有许多特定的方法来解释深度学习模型,特别是在非结构化数据上,我们将这一点置于我们当前的范围之外。(可能是另一篇博客,改天。)
数据预处理
- 将目标变量编码成数字变量
- 处理缺失值
- 通过组合几个值,将婚姻状况转换为二元变量
- 放弃教育,因为教育 _ 数字给出了相同的信息,但以数字格式表示
- 放弃资本收益和资本损失,因为他们没有任何信息。90%以上都是零
- 放弃 native_country 是因为高基数和偏向我们
- 因为与婚姻状况有很多重叠,所以放弃了关系
对随机森林算法进行了调整,并对数据进行了训练,取得了 83.58%的性能。考虑到根据你建模和测试的方式,最好的分数从 78-86%不等,这是一个不错的分数。但是对于我们的目的来说,模型性能已经足够了。
1.杂质的*均减少
这是迄今为止最流行的解释基于树的模型及其集合的方式。这很大程度上是因为 Sci-Kit Learn 及其简单易用的实现。拟合随机森林或梯度推进模型并绘制“要素重要性”已成为数据科学家中使用和滥用最多的技术。
当在任何集合决策树方法(随机森林、梯度推进等)中创建决策树时,通过测量特征在减少不确定性(分类器)或方差(回归器)方面的有效性来计算特征的杂质重要性的*均减少。).
该技术的优点是:
- 获取特征重要性的快速简单的方法
- 在 Sci-kit 学习和 R 中决策树实现中很容易获得
- 向外行人解释是非常直观的
算法
- 在构建树的过程中,无论何时进行分割,我们都会跟踪哪个特征进行了分割,分割前后的基尼系数是多少,以及它影响了多少样本
- 在树构建过程的最后,您可以计算归因于每个特征的基尼系数的总增益
- 在随机森林或梯度增强树的情况下,我们对集合中的所有树*均这个分数
履行
默认情况下,Sci-kit Learn 在基于树的模型的“特征重要性”中实现这一点。因此检索它们并绘制出前 25 个特征是非常简单的。
feat_imp = pd.DataFrame({'features': X_train.columns.tolist(), "mean_decrease_impurity": rf.feature_importances_}).sort_values('mean_decrease_impurity', ascending=False) feat_imp = feat_imp.head(25) feat_imp.iplot(kind='bar', y='mean_decrease_impurity', x='features', yTitle='Mean Decrease Impurity', xTitle='Features', title='Mean Decrease Impurity', )
Click here for full interactive plot
我们还可以检索并绘制每种树的杂质*均减少量的箱线图。
# get the feature importances from each tree and then visualize the distributions as boxplots all_feat_imp_df = pd.DataFrame(data=[tree.feature_importances_ for tree in rf], columns=X_train.columns) order_column = all_feat_imp_df.mean(axis=0).sort_values(ascending=False).index.tolist()
all_feat_imp_df[order_column[:25]].iplot(kind=’box’, xTitle = 'Features’, yTitle=’Mean Decease Impurity’)
Click for full interactive plot
解释
- 前 4 个特征是婚姻状况、教育程度、年龄、和工作时间。这很有道理,因为它们与你的收入有很大关系
- 注意到 fnlwgt 和 random 这两个特性了吗?它们比一个人的职业更重要吗?
- 这里的另一个警告是,我们将热门特征视为独立的特征,这可能与职业特征的排名低于随机特征有一定关系。当考虑特性重要性时,处理热点特性是另外一个话题
我们来看看 fnlwgt 和随机是什么。
- fnlwgt 数据集的描述是一个冗长而复杂的描述,描述了人口普查机构如何使用抽样来创建任何特定人口社会经济特征的“加权记录”。简而言之,这是一个抽样体重,与一个人的收入无关
- 而随机也就顾名思义。在拟合模型之前,我用随机数做了一列,称之为 random
当然,这些特征不可能比职业、工作阶级、性别等其他特征更重要。如果是这样的话,那就有问题了。
包里的小丑,又名“抓到你了”
当然…有。杂质测量的*均减少是特征重要性的偏差测量。它偏爱连续的特性和高基数的特性。2007 年,施特罗布尔等人 [1]也在的《随机森林变量重要性度量的偏差:图解、来源和解决方案中指出“布雷曼的原始随机森林方法的变量重要性度量……在潜在预测变量的度量尺度或类别数量发生变化的情况下是不可靠的。”
我们来试着理解一下为什么会有偏差。还记得杂质*均减少量是如何计算的吗?每次在要素上分割一个结点时,都会记录基尼系数的下降。并且当一个特征是连续的或者具有高基数时,该特征可能比其他特征被分割更多次。这扩大了该特定特征的贡献。我们这两个罪魁祸首的特征有什么共同点——它们都是连续变量。
2.删除列重要性,也称为遗漏一个协变量(LOOC)
Drop Column feature importance 是查看特性重要性的另一种直观方式。顾名思义,这是一种迭代删除特性并计算性能差异的方法。
该技术的优点是:
- 给出了每个特征的预测能力的相当准确的图像
- 查看特性重要性的最直观的方法之一
- 模型不可知。可适用于任何型号
- 它的计算方式,会自动考虑模型中的所有相互作用。如果要素中的信息被破坏,它的所有交互也会被破坏
算法
- 使用您训练过的模型参数,在 OOB 样本上计算您选择的指标。您可以使用交叉验证来获得分数。这是你的底线。
- 现在,从您的训练集中一次删除一列,重新训练模型(使用相同的参数和随机状态)并计算 OOB 分数。
- 重要性= OOB 得分—基线
履行
def dropcol_importances(rf, X_train, y_train, cv = 3):
rf_ = clone(rf)
rf_.random_state = 42
baseline = cross_val_score(rf_, X_train, y_train, scoring='accuracy', cv=cv)
imp = []
for col in X_train.columns:
X = X_train.drop(col, axis=1)
rf_ = clone(rf)
rf_.random_state = 42
oob = cross_val_score(rf_, X, y_train, scoring='accuracy', cv=cv)
imp.append(baseline - oob)
imp = np.array(imp)
importance = pd.DataFrame( imp, index=X_train.columns) importance.columns = ["cv_{}".format(i) for i in range(cv)]
return importance
让我们做一个 50 倍交叉验证来估计我们的 OOB 分数。(我知道这是多余的,但让我们保留它,以增加我们箱线图的样本)像以前一样,我们绘制准确性的*均下降以及箱线图,以了解跨交叉验证试验的分布。
drop_col_imp = dropcol_importances(rf, X_train, y_train, cv=50) drop_col_importance = pd.DataFrame({’features’: X_train.columns.tolist(), "drop_col_importance": drop_col_imp.mean(axis=1).values}).sort_values(’drop_col_importance’, ascending=False) drop_col_importance = drop_col_importance.head(25) drop_col_importance.iplot(kind=’bar’, y=’drop_col_importance’, x=’features’, yTitle=’Drop Column Importance’, xTitle=’Features’, title=’Drop Column Importances’, ) all_feat_imp_df = drop_col_imp.T order_column = all_feat_imp_df.mean(axis=0).sort_values(ascending=False).index.tolist()
all_feat_imp_df[order_column[:25]].iplot(kind=’box’, xTitle = 'Features’, yTitle=’Drop Column Importance’)
Click for full interactive plot
Click for full interactive plot
解释
- 排名前 4 位的特征仍然是婚姻状况、教育程度、年龄、和工作时间。
- fnlwgt 在列表中被向下推,现在出现在一些热门编码职业之后。
- random 仍然占据着很高的排名,将自己定位在工作时间之后
正如所料, fnlwgt 远没有杂质重要性的*均降低让我们相信的那么重要。随机的高位置让我有点困惑,我重新运行了重要性计算,将所有独一无二的特性视为一个。即删除所有职业列并检查职业的预测能力。当我这么做的时候,我可以看到随机和 fnlwgt 排名低于职业和工作类 。冒着让帖子变得更大的风险,让我们改天再调查吧。
那么,我们有完美的解决方案吗?这些结果与杂质的*均减少一致,它们有一致的意义,并且它们可以应用于任何模型。
群里的小丑
这里的难点在于所涉及的计算。为了执行这种重要性计算,您必须多次训练模型,针对您拥有的每个功能训练一次,并针对您想要进行的交叉验证循环次数重复训练。即使你有一个训练时间不到一分钟的模型,当你有更多的特征时,计算时间也会激增。为了给你一个概念,我花了 2 小时 44 分钟来计算 36 个特性和 50 个交叉验证循环的特性重要性(当然,这可以通过并行处理来改进,但你要明白这一点)。如果你有一个需要两天时间训练的大型模型,那么你可以忘记这个技巧。
我对这种方法的另一个担心是,因为我们每次都用新的特性集来重新训练模型,所以我们没有进行公*的比较。我们删除一列并再次训练模型,如果可以,它会找到另一种方法来获得相同的信息,当存在共线特征时,这种情况会放大。因此,我们在调查时混合了两种东西——功能的预测能力和模型自我配置的方式。
3.排列重要性
置换特征重要性被定义为当单个特征值被随机打乱时模型分数的减少[2]。这项技术衡量的是置换或打乱特征向量时的性能差异。关键的想法是,一个特性是重要的,如果这个特性被打乱,模型性能就会下降。
该技术的优点是:
- 非常直观。如果一个特性中的信息被打乱,性能会下降多少?
- 模型不可知。尽管该方法最初是由 Brieman 为 Random Forest 开发的,但它很快就适应了模型不可知的框架
- 它的计算方式,会自动考虑模型中的所有相互作用。如果要素中的信息被破坏,它的所有交互也会被破坏
- 该模型不需要重新训练,因此我们节省了计算
算法
- 使用度量、训练模型、特征矩阵和目标向量来计算基线得分
- 对于特征矩阵中的每个特征,制作特征矩阵的副本。
- 打乱特征列,将其传递给训练好的模型以获得预测,并使用度量来计算性能。
- 重要性=基线-得分
- 重复 N 次以获得统计稳定性,并在所有试验中取*均重要性
履行
置换重要性至少在 python 的三个库中实现——Eli 5、 mlxtend ,以及 Sci-kit Learn 的一个开发分支。我选择 mlxtend 版本完全是为了方便。根据施特罗布尔等人【3】,“原始【排列】重要性……具有更好的统计特性”与通过除以标准偏差来归一化重要性值相反。我已经检查了 mlxtend 和 Sci-kit Learn 的源代码,它们没有正常化它们。
from mlxtend.evaluate import feature_importance_permutation #This takes sometime. You can reduce this number to make the process faster num_rounds = 50
imp_vals, all_trials = feature_importance_permutation( predict_method=rf.predict, X=X_test.values, y=y_test.values, metric='accuracy', num_rounds=num_rounds, seed=1)permutation_importance = pd.DataFrame({’features’: X_train.columns.tolist(), "permutation_importance": imp_vals}).sort_values(’permutation_importance’, ascending=False) permutation_importance = permutation_importance.head(25) permutation_importance.iplot(kind=’bar’, y=’permutation_importance’, x=’features’, yTitle=’Permutation Importance’, xTitle=’Features’, title=’Permutation Importances’, )
我们还绘制了所有试验的箱线图,以了解偏差。
all_feat_imp_df = pd.DataFrame(data=np.transpose(all_trials), columns=X_train.columns, index = range(0,num_rounds)) order_column = all_feat_imp_df.mean(axis=0).sort_values(ascending=False).index.tolist()
all_feat_imp_df[order_column[:25]].iplot(kind='box', xTitle = 'Features', yTitle='Permutation Importance')
Click for full interactive plot
Click for full interactive plot
解释
- 前四名保持不变,但是前三名(婚姻状况、教育程度、年龄)在排列重要性上更加明显
- fnlwgt 和 random 甚至没有进入前 25 名
- 成为一名执行经理或专业教授与你是否能挣到 5 万英镑有很大关系
- 总而言之,这与我们对这一过程的心理模型产生了共鸣
功能重要性方面一切都好吗?我们有没有最好的方法来解释模型在预测中使用的特征?
包里的小丑
我们从生活中知道,没有什么是完美的,这种技术也是如此。它的致命弱点是特征之间的相关性。就像 drop column importance 一样,这种技术也会受到特性之间的相关性的影响。施特罗布尔等人在《随机森林的条件变量重要性》[3]中指出,“排列重要性高估了相关预测变量的重要性。“特别是在树的集合中,如果有两个相关变量,一些树可能会选择特征 A,而另一些树可能会选择特征 B。在进行此分析时,在没有特征 A 的情况下,选择特征 B 的树会工作良好并保持高性能,反之亦然。这将导致相关特征 A 和 B 都具有夸大的重要性。
该技术的另一个缺点是该技术的核心思想是置换特征。但这本质上是一种随机性,我们无法控制。正因为如此,结果可能变化很大。我们在这里看不到它,但是如果箱线图显示一个特性在不同试验中的重要性有很大的变化,我会在我的解释中保持警惕。
Phi_k Correlation Coefficient [7](in-built in pandas profiling which considers categorical variables as well)
这种技术还有另一个缺点,在我看来,这是最令人担心的。Giles Hooker 等人[6]说,“当训练集中的特征表现出统计相关性时,排列方法在应用于原始模型时可能会产生很大的误导。”
我们来考虑一下职业和学历。我们可以从两个角度理解这一点:
- 逻辑:你想想,职业和学历有确定的依赖关系。如果你受过足够的教育,你只能得到几份工作,从统计学上来说,你可以在它们之间画出*行线。因此,如果我们改变这些列中的任何一个,它将创建没有意义的功能组合。一个学历学历第十职业第职业第Prof-specialty的人没有太大意义,不是吗?因此,当我们评估模型时,我们评估的是无意义的情况,这些情况混淆了我们用来评估特性重要性的度量标准。
- 数学 : 职业和学历有很强的统计相关性(从上面的相关图可以看出)。因此,当我们置换这些特征中的任何一个时,我们是在迫使模型探索高维特征空间中看不见的子空间。这迫使模型进行外推,而这种外推是误差的重要来源。
Giles Hooker 等人[6]提出了结合 LOOC 和置换方法的替代方法,但所有替代方法的计算量都更大,并且没有具有更好统计特性的强有力的理论保证。
处理相关特征
在识别高度相关的特征之后,有两种处理相关特征的方法。
- 将高度相关的变量组合在一起,仅评估该组中的一个特征作为该组的代表
- 当您置换列时,请在一次试验中置换整组特征。
注意:第二种方法与我建议的处理一次性变量的方法相同。
旁注(培训或验证)
在讨论删除列重要性和排列重要性时,您应该想到一个问题。我们将测试/验证集传递给计算重要性的方法。为什么不是火车组?
这是应用这些方法的一个灰色地带。这里没有对错之分,因为两者都有支持和反对的理由。在《可解释机器学习》一书中,Christoph Molnar 提出了训练集和验证集都适用的案例。
测试/验证数据的案例是显而易见的。出于同样的原因,我们不能通过训练集中的误差来判断模型,我们也不能根据训练集中的性能来判断特征的重要性(特别是因为重要性与误差有着内在的联系)。
训练数据的情况是反直觉的。但是如果你仔细想想,你会发现我们想要衡量的是模型如何使用这些特性。有什么比训练模型的训练集更好的数据来判断这一点呢?另一个无关紧要的问题是,我们应该在所有可用的数据上训练模型,在这样一个理想的场景中,将没有测试或验证数据来检查性能。在可解释机器学习[5]中,第 5.5.2 节详细讨论了这个问题,甚至用一个过度拟合 SVM 的合成例子。
归根结底,你是想知道模型依靠什么特征来进行预测,还是想知道每个特征对未知数据的预测能力。例如,如果您在特性选择的上下文中评估特性的重要性,在任何情况下都不要使用测试数据(您会过度调整您的特性选择以适应测试数据)
4.部分依赖图(PDP)和个体条件期望图(ICE)
到目前为止,我们回顾的所有技术都着眼于不同特性的相对重要性。现在让我们稍微换个方向,看看一些探索特定特征如何与目标变量交互的技术。
部分依赖图和个别条件期望图帮助我们理解特征和目标之间的功能关系。它们是一个给定变量(或多个变量)对结果的边际效应的图形可视化。Friedman(2001)在他的开创性论文贪婪函数逼*:梯度推进机【8】中介绍了这一技术。
部分相关图显示*均效应,而 ICE 图显示单个观察值的函数关系。PD 图显示*均效应,而 ICE 图显示效应的分散性或异质性。
这种技术的优势是:
- 计算非常直观,易于用通俗的语言解释
- 我们可以理解一个特征或特征组合与目标变量之间的关系。即它是线性的、单调的、指数的等等。
- 它们易于计算和实现
- 它们给出了因果解释,与特征重要性风格解释相反。但我们必须记住的是,模型如何看待世界以及现在的现实世界的因果解释。
算法
让我们考虑一个简单的情况,其中我们为单个特征 x 绘制 PD 图,具有唯一值{x1,x2,…..xk}。PD 图可构建如下:
- 对于
- 复制训练数据并用 x(i)替换原始值 x
- 使用已训练的模型为整个训练数据的已修改副本生成预测
- 将对 x(i)的所有预测存储在类似映射的数据结构中
对于 PD 图:
- 计算{1,2,3,…k}的 I 元素的每个 x(i)的*均预测值
- 绘制对{ x { I },*均值(所有带有 x(i)的预测值)
对于冰图:
- 画出所有的对{x(i),f(x(i),其余的特征(n)}其中 n 元素为
- 在实践中,我们不是取某个特征的所有可能值,而是为连续变量定义一个区间网格,以节省计算时间。
- 对于分类变量,这个定义也成立,但是我们不会在这里定义一个网格。取而代之的是,我们采用类别中的所有唯一值(或属于分类特征的所有一次性编码变量),并使用相同的方法计算 ICE 和 PD 图。
- 如果过程你还不清楚,建议看看这篇中帖(作者是 PDPbox,一个用于绘制 PD 图的 python 库。
履行
我发现在 PDPbox 、滑手和 Sci-kit Learn 中实现的 PD 剧情。以及 PDPbox 、 pyCEbox 和 skater 中的冰剧情。在所有这些中,我发现 PDPbox 是最完美的。它们还支持 2 个可变 PDP 图。
from pdpbox import pdp, info_plots pdp_age = pdp.pdp_isolate( model=rf, dataset=X_train, model_features=X_train.columns, feature='age' ) #PDP Plot
fig, axes = pdp.pdp_plot(pdp_age, 'Age', plot_lines=False, center=False, frac_to_plot=0.5, plot_pts_dist=True,x_quantile=True, show_percentile=True)
#ICE Plot
fig, axes = pdp.pdp_plot(pdp_age, 'Age', plot_lines=True, center=False, frac_to_plot=0.5, plot_pts_dist=True,x_quantile=True, show_percentile=True)
让我花点时间解释一下情节。在 x 轴上,您可以找到您试图理解的特征的值,即年龄。在 y 轴上你会发现预测。在分类的情况下,它是预测概率,而在回归的情况下,它是实值预测。底部的条形表示不同分位数中训练数据点的分布。这有助于我们判断推论的正确性。点数很少的部分,模型看到的例子很少,解释可能很棘手。PD 图中的单线显示了特征和目标之间的*均函数关系。ICE 图中的所有线条显示了训练数据中的异质性,即训练数据中的所有观察值如何随着不同的年龄值而变化。
解释
- 年龄与一个人的赚钱能力有很大程度上的单调关系。年龄越大,收入越有可能超过 5 万英镑
- 冰图显示了很大的分散性。但是所有这些都显示了我们在 PD 图中看到的同样的行为
- 训练观察在不同的分位数之间相当*衡。
现在,让我们举一个具有分类特征的例子,比如教育。PDPbox 有一个非常好的特性,它允许您传递一个特性列表作为输入,它将计算它们的 PDP,将它们视为分类特性。
# All the one-hot variables for the occupation feature occupation_features = ['occupation_ ?', 'occupation_ Adm-clerical', 'occupation_ Armed-Forces', 'occupation_ Craft-repair', 'occupation_ Exec-managerial', 'occupation_ Farming-fishing', 'occupation_ Handlers-cleaners', 'occupation_ Machine-op-inspct', 'occupation_ Other-service', 'occupation_ Priv-house-serv', 'occupation_ Prof-specialty', 'occupation_ Protective-serv', 'occupation_ Sales', 'occupation_ Tech-support', 'occupation_ Transport-moving'] #Notice we are passing the list of features as a list with the feature parameter
pdp_occupation = pdp.pdp_isolate( model=rf, dataset=X_train, model_features=X_train.columns, feature=occupation_features ) #PDP
fig, axes = pdp.pdp_plot(pdp_occupation, 'Occupation', center = False, plot_pts_dist=True)
#Processing the plot for aesthetics
_ = axes['pdp_ax']['_pdp_ax'].set_xticklabels([col.replace("occupation_","") for col in occupation_features]) axes['pdp_ax']['_pdp_ax'].tick_params(axis='x', rotation=45)
bounds = axes['pdp_ax']['_count_ax'].get_position().bounds axes['pdp_ax']['_count_ax'].set_position([bounds[0], 0, bounds[2], bounds[3]]) _ = axes['pdp_ax']['_count_ax'].set_xticklabels([])
解释
- 大多数职业对你的收入影响很小。
- 其中最突出的是行政管理、专业教授和技术支持
- 但是,从分布情况来看,我们知道几乎没有技术支持的培训示例,因此我们对此持保留态度。
多个特征之间的相互作用
理论上可以为任意数量的特征绘制 PD 图,以显示它们的相互作用。但实际上,我们只能做两个人,最多三个人。让我们来看看两个连续特征年龄和教育之间的交互图(教育和年龄不是真正连续的,但由于缺乏更好的例子,我们选择它们)。
有两种方法可以绘制两个特征之间的 PD 图。这里有三个维度,特征值 1、特征值 2 和目标预测。或者,我们可以绘制一个三维图或一个二维图,第三维用颜色表示。我更喜欢二维图,因为我认为它比三维图以更清晰的方式传达信息,在三维图中,你必须查看三维形状来推断关系。PDPbox 实现了二维交互图,既有等高线图也有网格图。等值线最适用于连续要素,格网最适用于分类要素
# Age and Education inter1 = pdp.pdp_interact( model=rf, dataset=X_train, model_features=X_train.columns, features=['age', 'education_num'] ) fig, axes = pdp.pdp_interact_plot( pdp_interact_out=inter1, feature_names=['age', 'education_num'], plot_type='contour', x_quantile=False, plot_pdp=False ) axes['pdp_inter_ax'].set_yticklabels([edu_map.get(col) for col in axes['pdp_inter_ax'].get_yticks()])
解释
- 尽管我们在观察孤立时观察到了与年龄的单调关系,但现在我们知道这并不普遍。例如,请看第 12 级教育右边的等高线。与一些大学及以上的线相比,这是相当*坦的。它真正表明的是,你获得超过 50k 的概率不仅随着年龄的增长而增加,而且还与你的教育程度有关。随着年龄的增长,大学学位能确保你增加收入的潜力。
这也是一个非常有用的技术来调查你的算法中的偏见(伦理的那种)。假设我们想看看在性别维度上的算法偏差。
#PDP Sex pdp_sex = pdp.pdp_isolate( model=rf, dataset=X_train, model_features=X_train.columns, feature='sex' ) fig, axes = pdp.pdp_plot(pdp_sex, 'Sex', center=False, plot_pts_dist=True) _ = axes['pdp_ax']['_pdp_ax'].set_xticklabels(sex_le.inverse_transform(axes['pdp_ax']['_pdp_ax'].get_xticks())) # marital_status and sex inter1 = pdp.pdp_interact( model=rf, dataset=X_train, model_features=X_train.columns, features=['marital_status', 'sex'] ) fig, axes = pdp.pdp_interact_plot( pdp_interact_out=inter1, feature_names=['marital_status', 'sex'], plot_type='grid', x_quantile=False, plot_pdp=False ) axes['pdp_inter_ax'].set_xticklabels(marital_le.inverse_transform(axes['pdp_inter_ax'].get_xticks())) axes['pdp_inter_ax'].set_yticklabels(sex_le.inverse_transform(axes['pdp_inter_ax'].get_yticks()))
- 如果我们只看性别的概率分布图,我们会得出这样的结论:不存在真正的基于人的性别的歧视。
- 但是,你只要看看和 marriage _ status 的互动情节就知道了。在左手边(已婚),两个方块有相同的颜色和价值,但在右手边(单身)有女性和男性的区别
- 我们可以得出结论,单身男性比单身女性更有机会获得超过 50k 的收入。(虽然我不会基于此发动一场反对性别歧视的全面战争,但这绝对会是调查的起点。
群里的小丑
这种方法的最大缺陷是假设特征之间的独立性。LOOC 重要性和排列重要性中存在的相同缺陷。适用于 PDP 和 ICE 图。累积局部效应图是这个问题的解决方案。ALE 图通过计算——也是基于特征的条件分布——预测中的差异而不是*均值来解决这个问题。
总结一下每种类型的图(PDP,ALE)如何计算某个网格值 v 下某个特性的效果:
部分相关图:“让我向你展示当每个数据实例都有那个特性的值 v 时,模型*均预测的结果。我忽略了值 v 是否对所有数据实例都有意义。”
ALE plots :“让我向您展示模型预测如何在 v 周围的一个小特征“窗口”中针对该窗口中的数据实例发生变化。”
在 python 环境中,没有好的稳定的 ALE 库。我只发现了一个 ALEpython ,它还在开发中。我设法得到了一个年龄的 ALE 图,你可以在下面找到。但是当我尝试交互图时出错了。它也不是为分类特征开发的。
这就是我们再次中断的地方,把剩下的东西推到下一篇博文。在下一部分,我们来看看石灰,SHAP,锚,等等。
完整的代码可以在我的 Github 中找到
博客系列
- 第一部分
- 第二部分
- 第三部分—即将推出
参考
- 施特罗布尔特区,Boulesteix,AL。,Zeileis,a .等,《BMC 生物信息学》( 2007 年)8: 25。https://doi.org/10.1186/1471-2105-8-25
- 长度布雷曼,“随机森林”,机器学习,45(1),5–32,2001 年。https://doi.org/10.1023/A:1010933404324
- 施特罗布尔,c .,Boulesteix,a .,Kneib,T. 等随机森林的条件变量重要性。 BMC 生物信息学 9,307(2008)doi:10.1186/1471–2105–9–307
- 特伦斯·帕尔、凯雷姆·图尔古特鲁、克里斯多夫·西萨尔和杰瑞米·霍华德,“小心默认随机森林重要性”
- Christoph Molnar,“可解释的机器学习:使黑盒模型可解释的指南”
- Giles Hooker,Lucan Mentch,“请停止置换特征:一种解释和替代方案”, arXiv:1905.03151 【统计。我]
- 米(meter 的缩写))Baak,R. Koopman,H. Snoek,S. Klous,“具有皮尔逊特征的分类变量、序数变量和区间变量之间的新相关系数,arXiv:1811.11440【stat .我]
- 杰罗姆·h·弗里德曼贪婪函数*似法:一种梯度推进机。安。统计学家。29 (2001 年),第 5 号,1189-1232。doi:10.1214/aos/1013203451
- 亚历克斯·戈尔茨坦等“窥视黑盒内部:用个体条件期望图可视化统计学习”, arXiv:1309.6392 【统计。美联社]
原载于 2019 年 11 月 16 日http://deep-and-shallow.com。
可解释性:打开黑盒——第三部分
原文:https://towardsdatascience.com/interpretability-cracking-open-the-black-box-part-iii-35ecfd763237?source=collection_archive---------43-----------------------
深入了解石灰、匀称的价值观和 SHAP
付费墙是否困扰着你?点击 这里 可以绕过去。
之前,我们在基于树的模型中使用默认的特征重要性查看了陷阱,讨论了排列重要性、LOOC 重要性和部分依赖图。现在让我们换个话题,看看一些模型不可知的技术,它们采用自下而上的方式来解释预测。这些方法不是着眼于模型并试图给出像特征重要性这样的全局解释,而是着眼于每一个预测,然后试图解释它们。
5.局部可解释的模型不可知解释(LIME)
顾名思义,这是一种模型不可知的技术,为模型生成局部解释。这项技术背后的核心思想非常直观。假设我们有一个复杂的分类器,具有高度非线性的决策边界。但是,如果我们放大观察一个单一的预测,该模型在该地区的行为可以用一个简单的可解释模型(大部分是线性的)来解释。
LIME[2]使用了一个局部替代模型,该模型针对我们正在研究的数据点的扰动进行训练,以寻求解释。这确保了即使解释不具有全局保真度(对原始模型的保真度),它也具有局部保真度。论文[2]还认识到可解释性与保真度之间存在权衡,并提出了一个表达该框架的正式框架。
ξ (x) 是解释,L(f,g,πₓ)是局部保真度的倒数(或者说 g 在局部逼* f 有多不忠实),ω(g)是局部模型的复杂度, g 。为了确保局部保真度和可解释性,我们需要最小化不忠实度(或最大化局部保真度),牢记复杂度应该低到足以让人类理解。
即使我们可以使用任何可解释的模型作为局部替代,本文使用套索回归来诱导解释的稀疏性。该论文的作者将他们的探索限制在模型的保真度上,并将复杂性保持为用户输入。在套索回归的情况下,它是解释应归因于的要素的数量。
他们探索并提出解决方案的另一个方面(还没有得到很多人的欢迎)是使用一组个体实例提供全局解释的挑战。他们称之为“子模式摘”。它本质上是一种贪婪的优化,试图从整个批次中挑选一些实例,最大化他们所谓的“非冗余覆盖”。非冗余覆盖确保优化不会挑选具有相似解释的实例。
该技术的优势是:
- 方法论和解释对人类来说都是非常直观的。
- 生成的解释是稀疏的,从而增加了可解释性。
- 模型不可知
- LIME 适用于结构化和非结构化数据(文本、图像)
- 在 R 和 Python 中随时可用(本文作者的原始实现)
- 使用其他可解释特征的能力,即使模型是在嵌入等复杂特征中训练的。例如,回归模型可以在 PCA 的几个成分上训练,但是解释可以在对人类有意义的原始特征上生成。
算法
- 为了找到对单个数据点和给定分类器的解释
- 均匀随机地对所选单个数据点周围的局部性进行采样,并从我们想要解释的模型中生成扰动数据点及其相应预测的数据集
- 使用指定的特性选择方法选择解释所需的特性数量
- 使用核函数和距离函数计算样本权重。(这捕获了采样点离原始点有多*或多远)
- 使用样本权重对目标函数进行加权,在扰动的数据集上拟合可解释的模型。
- 使用新训练的可解释模型提供本地解释
履行
论文作者的实现可以在 Github 和 pip 中找到。在我们看一下如何实现它们之前,让我们先讨论一下实现中的一些奇怪之处,在运行它之前你应该知道这些(重点是表格解释器)。
主要步骤如下
- 通过提供训练数据(或训练数据统计,如果训练数据不可用),一些关于特性和类名的细节(在分类的情况下),初始化tabular 解释器**
- 调用类中的方法, explain_instance 并提供需要解释的实例、训练模型的预测方法以及需要包含在解释中的功能数量。
你需要记住的关键事情是:
- 默认情况下模式是分类。所以如果你试图解释一个回归问题,一定要提到它。
- 默认情况下,功能选择设置为“自动”。“自动”基于训练数据中的特征数量在 前向选择 和最高权重之间选择(如果小于 6,前向选择。最大权重刚好符合对缩放数据的岭回归,并选择 n 个最大权重和。如果将“无”指定为特征选择参数,则不会进行任何特征选择。如果您将“lasso_path”作为特征选择,它将使用来自 sklearn 的信息来查找提供 n 个非零特征的正确级别正则化。
- 默认情况下,岭回归用作可解释模型。但是您可以传入任何您想要的 sci-kit 学习模型,只要它有 coef_ 和' sample_weight '作为参数。
- 还有另外两个关键参数, kernel 和 kernel_width ,它们决定了样本权重的计算方式,也限制了可能发生扰动的局部性。这些在算法中作为超参数保存。虽然,在大多数用例中,缺省值是可行的。
- 默认情况下,discrete ize _ continuous设置为 True 。这意味着连续特征被离散为四分位数、十分位数或基于熵。离散化器的默认值为四分位数。
现在,让我们继续使用上一部分中使用的数据集,看看 LIME 的实际应用。
*import lime import lime.lime_tabular
# Creating the Lime Explainer
# Be very careful in setting the order of the class names lime_explainer = lime.lime_tabular.LimeTabularExplainer( X_train.values, training_labels=y_train.values, feature_names=X_train.columns.tolist(), feature_selection="lasso_path", class_names=["<50k", ">50k"], discretize_continuous=True, discretizer="entropy", )
#Now let's pick a sample case from our test set.
row = 345*
Row 345
*exp = lime_explainer.explain_instance(X_test.iloc[row], rf.predict_proba, num_features=5) exp.show_in_notebook(show_table=True)*
为了多样化,让我们看另一个例子。一个被模型错误分类的。
Row 26
解释
例 1
- 我们看到的第一个例子是一个 50 岁的已婚男子,拥有学士学位。他在一家私营公司担任行政/管理职务,每周工作 40 个小时。我们的模型正确地将他归类为收入超过 5 万英镑的人
- 这样的预测在我们的心理模型中是有意义的。一个 50 岁的人在管理岗位上工作,收入超过 50k 的可能性非常高。
- 如果我们看看这个模型是如何做出这个决定的,我们可以看到,这是由于他的婚姻状况、年龄、教育程度以及他担任行政/管理职务的事实。事实上,他的职业不是一个专业,这试图降低他的可能性,但总的来说,模型决定,这个人很有可能收入超过 50k
例 2
- 第二个例子是一个 57 岁的已婚男子,高中学历。他是一名从事销售的个体户,每周工作 30 个小时。
- 即使在我们的心理模型中,我们也很难预测这样一个人的收入是否超过 50k。模型预测这个人的收入不到 50k,而事实上他赚得更多。
- 如果我们看看模型是如何做出这个决定的,我们可以看到在预测的局部有一个很强的推拉效应。一方面,他的婚姻状况和年龄将他推向了 50k 以上。另一方面,他不是高管/经理的事实、他所受的教育和每周工作时间都在把他往下推。最终,向下推动赢得了比赛,模型预测他的收入低于 50k。
子模块选择和全局解释
如前所述,论文中还提到了另一种技术,叫做“子模型选择”,可以找到一些解释来解释大多数情况。让我们也试着得到它。python 库的这个特殊部分不太稳定,提供的示例笔记本给了我错误。但是在花了一些时间通读源代码之后,我找到了一个解决错误的方法。
*from lime import submodular_pick
sp_obj = submodular_pick.SubmodularPick(lime_explainer, X_train.values, rf.predict_proba, sample_size=500, num_features=10, num_exps_desired=5) #Plot the 5 explanations [exp.as_pyplot_figure(label=exp.available_labels()[0]) for exp in sp_obj.sp_explanations]; # Make it into a dataframe W_pick=pd.DataFrame([dict(this.as_list(this.available_labels()[0])) for this in sp_obj.sp_explanations]).fillna(0)
W_pick['prediction'] = [this.available_labels()[0] for this in sp_obj.sp_explanations] #Making a dataframe of all the explanations of sampled points W=pd.DataFrame([dict(this.as_list(this.available_labels()[0])) for this in sp_obj.explanations]).fillna(0)
W['prediction'] = [this.available_labels()[0] for this in sp_obj.explanations] #Plotting the aggregate importances
np.abs(W.drop("prediction", axis=1)).mean(axis=0).sort_values(ascending=False).head( 25 ).sort_values(ascending=True).iplot(kind="barh") #Aggregate importances split by classes
grped_coeff = W.groupby("prediction").mean()
grped_coeff = grped_coeff.T
grped_coeff["abs"] = np.abs(grped_coeff.iloc[:, 0]) grped_coeff.sort_values("abs", inplace=True, ascending=False) grped_coeff.head(25).sort_values("abs", ascending=True).drop("abs", axis=1).iplot( kind="barh", bargap=0.5 )*
Click for full interactive plot
Click for full interactive plot
解释
有两个图表,其中我们汇总了从我们的测试集中采样的 500 个点的解释(我们可以在所有测试数据点上运行它,但选择只进行采样,因为需要计算)。
第一个图表汇总了超过 50k 和<50k cases and ignores the sign when calculating the mean. This gives you an idea of what features were important in the larger sense.
The second chart splits the inference across the two labels and looks at them separately. This chart lets us understand which feature was more important in predicting a particular class.
- Right at the top of the first chart, we can find “婚姻状况> 0.5* 的特征的影响。按照我们的编码,就是单身的意思。所以单身是一个很强的指标,表明你的收入是高于还是低于 50k。但是等等,结婚是第二位的。这对我们有什么帮助?*
- 如果你看第二张图表,情况会更清楚。你可以立即看到单身让你进入了<50k bucket and being married towards the >的 50k 桶。
- 在你匆忙去寻找伴侣之前,请记住这是模型用来寻找伴侣的。这不一定是现实世界中的因果关系。也许这个模型是在利用其他一些与结婚有很大关联的特征来预测收入潜力。
- 我们在这里也可以看到性别歧视的痕迹。如果你看“性别> 0.5”,这是男性,两个收入潜力阶层之间的分布几乎相等。不过只要看一下《性<0.5”. It shows a large skew towards <50k bucket.
Along with these, the submodular pick also(in fact this is the main purpose of the module) a set of n data points from the dataset, which best explains the model. We can look at it like a representative sample of the different cases in the dataset. So if we need to explain a few cases from the model to someone, this gives you those cases which will cover the most ground.
The Joker in the Pack
From the looks of it, this looks like a very good technique, isn’t it? But it is not without its problems.
The biggest problem here is the correct definition of the neighbourhood, especially in tabular data. For images and text, it is more straightforward. Since the authors of the paper left kernel width as a hyperparameter, choosing the right one is left to the user. But how do you tune the parameter when you don’t have a ground truth? You’ll just have to try different widths, look at the explanations, and see if it makes sense. Tweak them again. But at what point are we crossing the line into tweaking the parameters to get the explanations we want?
Another main problem is similar to the problem we have with permutation importance( 第二部)就知道了。当对局部中的点进行采样时,LIME 的当前实现使用高斯分布,这忽略了特征之间的关系。这可以创建相同的‘不太可能’数据点,在这些数据点上学习解释。
最后,选择一个线性的可解释模型来进行局部解释可能并不适用于所有情况。如果决策边界过于非线性,线性模型可能无法很好地解释它(局部保真度可能较高)。
6.得体的价值观
在讨论 Shapely 值如何用于机器学习模型解释之前,我们先试着了解一下它们是什么。为此,我们必须简单地了解一下博弈论。
博弈论是数学中最迷人的分支之一,它研究理性决策者之间战略互动的数学模型。当我们说游戏时,我们指的不仅仅是象棋,或者就此而言,垄断。游戏可以概括为两个或两个以上的玩家/团体参与一个决策或一系列决策以改善他们的地位的任何情况。当你这样看待它时,它的应用扩展到战争策略、经济策略、扑克游戏、定价策略、谈判和合同,不胜枚举。
但是由于我们关注的主题不是博弈论,我们将只讨论一些主要术语,这样你就能跟上讨论。参与游戏的各方被称为玩家。这些玩家可以采取的不同行动被称为选择。如果每个参与者都有有限的选择,那么每个参与者的选择组合也是有限的。因此,如果每个玩家都做出一个选择,就会产生一个结果,如果我们量化这些结果,这就叫做收益。如果我们列出所有的组合和与之相关的收益,这就叫做收益矩阵。
博弈论有两种范式——非合作、合作博弈。而 Shapely 值是合作博弈中的一个重要概念。我们试着通过一个例子来理解。
爱丽丝、鲍伯和席琳一起用餐。账单共计 90 英镑,但他们不想各付各的。因此,为了算出他们各自欠了多少钱,他们以不同的组合多次去同一家餐馆,并记录下账单金额。
有了这些信息,我们做一个小的心理实验。假设 A 去了餐厅,然后 B 出现了,C 出现了。因此,对于每个加入的人,我们可以有每个人必须投入的额外现金(边际贡献)。我们从 80 英镑开始(如果 A 一个人吃饭,他会支付 80 英镑)。现在当 B 加入时,我们看看 A 和 B 一起吃饭时的收益——也是 80。所以 B 给联盟带来的额外贡献是 0。当 C 加入时,总收益是 90。这使得 C 10 的边际贡献。所以,当 A,B,C 依次加入时的贡献是(80,0,10)。现在我们对这三个朋友的所有组合重复这个实验。
现在我们有了所有可能的到达顺序,我们有了所有参与者在所有情况下的边际贡献。每个参与者的预期边际贡献是他们在所有组合中边际贡献的*均值。例如,A 的边际贡献将是,(80+80+56+16+5+70)/6 = 51.17。如果我们计算每个玩家的预期边际贡献,并把它们加在一起,我们会得到 90,这是三个人一起吃饭的总收益。
你一定想知道所有这些与机器学习和可解释性有什么关系。很多。如果我们想一想,一个机器学习预测就像一个游戏,其中不同的功能(玩家),一起游戏以带来一个结果(预测)。由于这些特征一起工作,相互作用,做出预测,这就变成了一个合作博弈的例子。这完全符合匀称的价值观。
但是只有一个问题。随着特征的增加,计算所有可能的联盟及其结果很快变得不可行。因此,2013 年,Erik trumbelj等人提出了一种使用蒙特卡罗抽样的*似方法。在这个结构中,回报被建模为不同蒙特卡罗样本的预测与*均预测的差异。
其中 f 是我们试图解释的黑盒机器学习模型, x 是我们试图解释的实例,j 是我们试图找到预期边际贡献的特征, x ᵐ₋ⱼ和 x ᵐ₊ⱼ是 x 的两个实例,我们已经通过从数据集本身中采样另一个点对其进行了随机置换, M 是我们从训练集中抽取的样本数。
让我们看看 Shapely 值的一些令人满意的数学属性,这使得它在可解释性应用中非常令人满意。Shapely 值是唯一满足效率、对称性、虚拟性和可加性属性的属性方法。同时满足这些条件被认为是公*支付的定义。
- 效率-要素贡献加起来就是 x 和*均值的预测差异。
- 对称性-如果两个特征值对所有可能的联合的贡献相等,则它们的贡献应该相同。
- 虚拟-无论添加到哪个联盟,都不会更改预测值的要素的 Shapely 值都应为 0
- 可加性——对于组合支付的游戏,可以将相应的 Shapely 值加在一起,得到最终的 Shapely 值
虽然所有的属性都使这成为一种理想的特征归属方式,但其中一个特别具有深远的影响,即可加性。这意味着,对于像 RandomForest 或梯度增强这样的集合模型,该属性保证了如果我们单独计算每棵树的要素的 Shapely 值并对其进行*均,您将获得集合的 Shapely 值。这一特性也可以扩展到其他集成技术,如模型叠加或模型*均。
出于两个原因,我们将不回顾算法并查看 Shapely 值的实现:
- 在大多数现实世界的应用中,计算 Shapely 值是不可行的,即使有*似值。
- 有一个更好的计算 Shapely 值的方法,还有一个稳定的库,我们将在下面介绍。
7.得体的附加解释(SHAP)
SHAP (SHapely 附加解释)提出了一个解释模型预测的统一方法。斯科特·伦德伯格等人提出了一个框架,该框架统一了六种先前存在的特征归属方法(包括 LIME 和 DeepLIFT ),他们将其框架作为附加特征归属模型。
他们表明,这些方法中的每一种都可以用上面的等式来表示,并且 Shapely 值可以很容易地计算出来,这带来了一些保证。尽管论文中提到的属性与 Shapely 值略有不同,但原则上它们是相同的。这提供了一个强大的技术(如石灰)的理论基础,一旦适应这一框架的估计匀称的价值。在论文中,作者提出了一种新的模型不可知的方法来*似 Shapely 值,称为核 SHAP(石灰+ Shapely 值)和一些特定于模型的方法,如 DeepSHAP(这是 DeepLIFT 的改编,一种估计神经网络特征重要性的方法)。除此之外,他们还表明,对于线性模型,如果我们假设特征独立,Shapely 值可以直接从模型的权重系数中*似得到。2018 年,斯科特·伦德伯格等人【6】提出了该框架的另一个扩展,该框架可以精确计算基于树的系综的 Shapely 值,如随机森林或梯度增强。
内核 SHAP
尽管从下面的等式来看,这并不是非常直观,但石灰也是一种附加的特征归属方法。对于附加特征解释方法,Scott Lundberg 等人表明,满足所需属性的唯一解决方案是 Shapely 值。并且该解取决于损失函数 L 、加权核πₓ和正则化项ω。
如果你还记得,当我们讨论 LIME 时,我提到过它的一个缺点是,它将核函数和核距离作为超参数,它们是使用启发式算法来选择的。内核 SHAP 消除了这种不确定性,提出了一个形状良好的内核和相应的损失函数,确保上述方程的解决方案将产生形状良好的值,并享受数学保证。
算法
- 对联合向量进行采样(联合向量是二进制值的向量,其长度与特征的数量相同,表示特定特征是否包括在联合中。 z' ₖ ϵ {0,1}ₘ, k ϵ { 1 ,…, K } (1 =特征存在,0 =特征不存在)
- 通过使用函数 hₓ 将联合向量转换到原始样本空间,从模型中获得联合向量 z'ₖ 的预测。 hₓ 只是我们用一套变换从原始输入数据中得到相应值的一种花哨说法。例如,对于联合向量中的所有 1,我们用我们正在解释的实例中该特征的实际值来替换它。对于 0 来说,它根据应用略有不同。对于表格数据,从数据中随机抽样,用相同特征的一些其他值替换 0。对于图像数据,0 可以用参考值或零像素值代替。下图试图让表格数据的这一过程变得清晰。
- 使用 Shapely 内核计算样本的重量
- 对 K 个样本重复此操作
- 现在,拟合一个加权线性模型并返回 Shapely 值,即模型的系数。
特里 SHAP
如前所述[6],树 SHAP 是一种快速算法,它为基于决策树的模型计算精确的 Shapely 值。相比之下,核 SHAP 只是*似 Shapely 值,计算起来要昂贵得多。
算法
让我们试着直观地了解一下它是如何计算的,而不要深入研究大量的数学知识(那些倾向于数学的人,这篇论文在参考资料中有链接,尽情享受吧!).
我们将首先讨论算法如何对单棵树起作用。如果你记得关于 Shapely 值的讨论,你会记得为了精确计算,我们需要以实例的特征向量的所有子集为条件的预测。因此,假设我们试图解释的实例的特征向量是 x ,并且我们需要预期预测的特征子集是 S 。
下面是一个人工决策树,它仅使用三个特征年龄、工作时间和婚姻状况来预测收入潜力。
- 如果我们以所有特征为条件,即 S 是所有特征的集合,那么 x 所在的节点中的预测就是预期预测。即> 50k
- 如果我们不以任何特征为条件,则同样有可能(忽略点在节点间的分布)您最终会出现在任何决策节点中。因此,预期预测将是所有终端节点预测的加权*均值。在我们的例子中,有 3 个节点输出 1( <50k) and three nodes which outputs 0 (> 50k)。如果我们假设所有的训练数据点*均分布在这些节点上,在没有所有特征的情况下的预期预测是 0.5
- 如果我们以某些特性 S 为条件,我们计算出实例 x 最终可能到达的节点的期望值。例如,如果我们从集合 S 中排除marriage _ status,实例同样有可能在节点 5 或节点 6 中结束。因此,对于这种 S 的预期预测将是节点 5 和 6 的输出的加权*均值。因此,如果我们从 S 中排除 hours_worked ,预期预测会有任何变化吗?否,因为 hours_worked 不在实例 x 的决策路径中。
- 如果我们排除了位于树根的特征,如年龄,它将创建多个子树。在这种情况下,它将有两棵树,一棵树从右侧的已婚区块开始,另一棵树从左侧的工作小时数开始。还有一个节点 4 的决策存根。现在实例 x 沿着两棵树向下传播(不包括具有年龄的决策路径),并且预期预测被计算为所有可能节点(节点 3、4 和 5)的加权*均值。
现在,您已经在一个决策树中获得了所有子集的预期预测,您可以对集合中的所有树重复该操作。还记得 Shapely 值的可加性属性吗?它允许您通过计算所有树的 Shapely 值的*均值,将它们聚集在一个系综中。
但是,现在的问题是,必须为所有树中所有可能的特征子集和所有特征计算这些期望值。该论文的作者提出了一种算法,在这种算法中,我们能够同时将所有可能的特征子集推下树。这个算法相当复杂,我建议你参考参考文献中链接的论文来了解细节。
优势
- SHAP 和 Shapely 价值观享有博弈论的坚实理论基础。Shapely 值保证了预测在不同的要素之间公*分布。这可能是唯一能够经受住理论和实践检验冲击的特征归属技术,无论是学术检验还是监管检验
- SHAP 将其他可解释性技术,如 LIME 和 DeepLIFT,与博弈论的强大理论基础联系起来。
- SHAP 对基于树的模型有着极快的实现,这是机器学习中最流行的方法之一。
- 通过计算整个数据集的 Shapely 值并聚合它们,SHAP 还可用于全局解释。它在您的本地和全球解释之间提供了一个强有力的链接。如果你使用莱姆或 SHAP 进行局部解释,然后依靠 PDP 图进行全局解释,这实际上是行不通的,你可能会得出相互矛盾的结论。
实施(本地解释)
出于两个原因,我们在本节中将只关注 TreeSHAP:
- 我们在整个博客系列中查看了结构化数据,我们选择的运行可解释性技术的模型是 RandomForest,这是一个基于树的集合。
- TreeSHAP 和 KernelSHAP 在实现中有几乎相同的接口,如果你试图解释一个 SVM,或者其他一些不是基于树的模型,用 KernelSHAP 替换 TreeSHAP 应该很简单(以计算为代价)。
*import shap
# load JS visualization code to notebook
shap.initjs() explainer = shap.TreeExplainer(model = rf, model_output='margin') shap_values = explainer.shap_values(X_test)*
这些代码行计算 Shapely 值。即使算法很快,这仍然需要一些时间。
- 在分类的情况下, shap_values 将是数组的列表,并且列表的长度将等于类的数量
- explainer.expected_value 也是如此
- 因此,我们应该选择我们试图解释的标签,并在进一步的绘图中使用相应的形状值和预期值。根据实例的预测,我们可以选择相应的 SHAP 值并绘制它们
- 在回归的情况下,shap_values 将只返回一个项目。
现在我们来看看个别的解释。我们将接受和石灰一样的箱子。SHAP 图书馆有多种绘制个人解释的方式——力量图和决定图。两者都非常直观地理解不同的功能一起发挥,以达到预测。如果特征的数量太大,决策图在解释时会有一点优势。
*shap.force_plot( base_value=explainer.expected_value[1], shap_values=shap_values[1][row], features=X_test.iloc[row], feature_names=X_test.columns, link="identity", out_names=">50k", ) # We provide new_base_value as the cutoff probability for the classification mode
# This is done to increase the interpretability of the plot shap.decision_plot( base_value=explainer.expected_value[1], shap_values=shap_values[1][row], features=X_test.iloc[row], feature_names=X_test.columns.tolist(), link="identity", new_base_value=0.5, )*
**
Force Plot
Decision Plot
现在,我们将检查第二个示例。
解释
例 1
- 与 LIME 类似,SHAP 也认为婚姻状况、年龄、教育程度等对他有很大影响。
- 力图解释了不同的要素如何推动和拉动输出,以将其从 base_value 移动到预测。这里的预测是这个人赚到> 50k 的概率或可能性(因为这是对这个实例的预测)。
- 在原力剧情中,你可以看到的婚姻状况、学历数量等。在左侧,将预测值推至接* 1,并将 hours_per_week 推至相反方向。我们可以看到,从基值 0.24 开始,这些功能通过推和拉使输出达到 0.8
- 在决策情节中,画面更清晰一点。你有很多特征,比如职业特征和其他特征,这使得模型输出较低,但是来自年龄、职业 _ 执行-管理、教育 _ 数量和婚姻 _ 状态的强烈影响已经将指针一路移动到 0.8。
- 这些解释符合我们对这一过程的心理模型。
例 2
- 这是一个我们分类错误的案例。这里我们解释的预测是这个人赚了 5 万。
- 力图显示了双方之间的均匀匹配,但是模型最终收敛到 0.6。教育程度,工作时间,以及这个人不在执行管理职位的事实都试图增加挣 5 万英镑的可能性。
- 如果比较两个例子的决策图,这一点就更清楚了。在第二个例子中,你可以看到一个强有力的之字形模式,在这个模式中,多个强有力的影响者推动和拉动,导致与先前信念的偏差较小。
- 实施(全球解释)
SHAP 库还提供了简单的方法来聚合和绘制一组点(在我们的例子中是测试集)的 Shapely 值,以对模型进行全局解释。
解释
*#Summary Plot as a bar chart
shap.summary_plot(shap_values = shap_values[1], features = X_test, max_display=20, plot_type='bar') #Summary Plot as a dot chart
shap.summary_plot(shap_values = shap_values[1], features = X_test, max_display=20, plot_type='dot') #Dependence Plots (analogous to PDP)
# create a SHAP dependence plot to show the effect of a single feature across the whole dataset shap.dependence_plot("education_num", shap_values=shap_values[1], features=X_test) shap.dependence_plot("age", shap_values=shap_values[1], features=X_test)*
Summary Plot (Bar)
Summary Plot (Dot)
Dependence Plot — Age
Dependence Plot-Education
在二元分类中,您可以绘制两个 SHAP 值中的任意一个来解释模型。我们选择了> 50k 来解释,因为这样考虑模型更直观
- 在汇总摘要中,我们可以看到列表顶部的常见嫌疑人。
- 边注 :我们可以给 summary_plot 方法提供一个 shap_values(多类分类)列表,前提是我们给plot _ type=‘bar’。它将以堆积条形图的形式绘制每个类别的汇总 SHAP 值。对于二进制分类,我发现这比仅仅绘制其中一个类要不直观得多。
- 点阵图更有趣,因为它比条形图揭示了更多的信息。除了整体重要性之外,它还显示了特征值对模型输出的影响。例如,我们可以清楚地看到,当特征值较低时,婚姻状况对积极的一面(更有可能大于 50k)产生强烈的影响。从我们的标签编码中我们知道,婚姻状态= 0,意味着已婚,1 意味着单身。所以结婚会增加你赚> 50k 的机会。
- 边注 :当使用 plot_type = 'dot 时,我们不能使用 shap 值列表。你将不得不绘制多个图表来理解你所预测的每一类
- 同样,如果你看一下年龄,你会发现当特征值较低时,它几乎总是对你赢得> 50k 的机会产生负面影响。但当特征值较高时(即你年龄较大),会出现一个混合的点包,这告诉我们在为模型做出决策时,会有很多与其他特征的交互作用。
- 这就是 依赖图 出现的地方。这个想法与我们在上一篇博文中回顾的 PD 图非常相似。但是我们用 SHAP 值来绘制相关性,而不是部分相关性。这种解释除了细微的改动之外,仍然是相似的。
- X 轴表示要素的值,Y 轴表示 SHAP 值或其对模型输出的影响。正如您在点阵图中看到的,正面影响意味着它将模型输出推向预测方向(在我们的例子中大于 50k),负面影响意味着相反的方向。所以在年龄依赖图中,我们可以看到我们之前讨论过的相同现象,但是更清楚。当你年轻时,这种影响大多是负面的,当你年老时,这种影响是正面的。
- 《SHAP》中的依赖情节还做了另外一件事。它选择另一个与我们正在研究的特征交互最多的特征,并根据该特征的特征值给点着色。在年龄的情况下,该方法选择的是婚姻状况。我们可以看到,你在年龄轴上发现的大部分离差是由婚姻状况解释的。
- 如果我们看看教育的依赖图(这是一个有序的特征),我们可以看到教育程度越高,你挣得越多的预期趋势。
- 群里的小丑
和往常一样,为了有效地使用这种技术,我们应该意识到它的缺点。如果你一直在寻找解释的完美技巧,很抱歉让你失望了。生活中没有什么是完美的。所以,我们来深入探讨一下缺点。
计算密集型。TreeSHAP 在一定程度上解决了这个问题,但与我们讨论的大多数其他技术相比,它仍然很慢。KernelSHAP 速度很慢,对于大型数据集的计算变得不可行。(虽然有一些技术,如在计算 Shapely 值之前使用 K-means 聚类来减少数据集,但它们仍然很慢)
- SHAP 价值观可能会被曲解,因为它不是最直观的想法。它代表的不是预测中的实际差异,而是实际预测和*均预测之间的差异,这是一个微妙的细微差别。
- SHAP 和 T4 不会像莱姆一样创造稀疏的解释。人类更喜欢稀疏的解释,这些解释很好地符合心智模型。但是增加一个像 LIME 那样的正则化项并不能保证匀称的值。
- KernelSHAP 忽略特性依赖。就像排列重要性、LIME 或任何其他基于排列的方法一样,KernelSHAP 在试图解释模型时会考虑“不太可能”的样本。
- 额外收获:文本和图像
我们讨论的一些技术也适用于文本和图像数据。虽然我们不会深入探讨,但我会链接到一些笔记本,告诉你如何做。
文本数据上的石灰—多标签分类
图像分类上的石灰— INCEPTION_V3 — KERAS
深度讲解者——SHAP-MNIST
渐变讲解者—SHAP—IMAGENET 中 VGG16 的中间层
最后的话
我们已经到达了可解释世界旅程的终点。可解释性和可解释性是商业采用机器学习(包括深度学习)的催化剂,我们从业者有责任确保这些方面得到合理有效的解决。人类盲目信任机器还需要很长一段时间,在那之前,我们将不得不用某种可解释性来取代出色的表现,以培养信任。
如果这一系列的博客文章能让你回答至少一个关于你的模型的问题,我认为我的努力是成功的。
我的 Github 中有完整的代码
博客系列
第一部
- 第二部分
- 第三部分
- 参考
Christoph Molnar,“可解释的机器学习:使黑盒模型可解释的指南”
- 马尔科·图利奥·里贝罗,萨米尔·辛格,卡洛斯·盖斯特林,“我为什么要相信你?:解释任何分类器的预测”,arXiv:1602.04938【cs。LG]
- 《n 人游戏的价值》对博弈论的贡献 2.28(1953):307–317
- trumbelj,e .,& Kononenko,I. (2013 年)。用特征贡献解释预测模型和个体预测。知识和信息系统,41* ,647–665。*
- 斯科特·m·伦德伯格和李秀英。“解释模型预测的统一方法。”神经信息处理系统的进展。2017.
- Lundberg,Scott M .,Gabriel G. Erion,和 Su-In Lee。"树集合的一致个性化特征属性"arXiv 预印本 arXiv:1802.03888 (2018)。
- 原载于 2019 年 11 月 24 日 http://deep-and-shallow.com的* 。*
Originally published at http://deep-and-shallow.com on November 24, 2019.
可解释的人工智能或我如何学会停止担心和信任人工智能
原文:https://towardsdatascience.com/interpretable-ai-or-how-i-learned-to-stop-worrying-and-trust-ai-e61f9e8ee2c2?source=collection_archive---------11-----------------------
内部 AI
构建健壮、公正的人工智能应用的技术
公众信任是人工智能被有效使用的重要条件。— 马克·沃尔波特爵士
[source]
仅在过去五年中,人工智能研究人员就在诸如图像识别、自然语言理解和棋盘游戏等领域取得了重大突破!随着公司考虑将医疗保健和金融等行业的关键决策交给人工智能,缺乏对复杂机器学习模型的理解将带来巨大问题。这种缺乏理解可能会导致模型传播偏见,我们已经在刑事司法、政治、零售、面部识别和语言理解中看到了不少这样的例子。
Kate Crawford on the Trouble with Bias at NeurIPS 2017
所有这些都对信任产生不利影响,从我的经验来看,这是公司抵制在整个企业中部署人工智能的主要原因之一。解释或诠释人工智能是一个热门的研究话题,因为现代机器学习算法是黑箱没有人真正理解它们是如何工作的。此外,现在有欧盟的规定来解释人工智能在 GDPR 的“解释权”。在这篇博文中,我将介绍一些技术,您可以将这些技术添加到您的数据科学武库中,以提高对模型的理解。
团队数据科学流程
但是首先,你按照什么过程来构建和部署一个人工智能应用程序?在微软,我们遵循一种称为团队数据科学过程 (TDSP)的敏捷迭代方法,这种方法从像 CRISP-DM 和 KDD 这样的过程中获得灵感。在这篇文章中,我将详细介绍这个过程的建模和部署阶段。
Zooming into Modeling and Deployment in TDSP
开发模型时,第一步是学习。您训练一个模型来从历史数据中检测模式,这需要经历多次迭代的训练和验证来挑选最佳模型。一旦你有了一个学习过的模型,下一步就是测试。这意味着在模型之前没有见过的盲数据集上评估模型。我写了一篇关于度量模型良好性的博文,你可以应用这些技术来量化商业价值,并与商业利益相关者分享。在证明商业价值之后,下一个逻辑步骤通常是将模型部署到生产中。部署后,一个非常常见的问题是模型不能按预期执行。这有两个主要原因:
- 数据/概念漂移 :当数据的分布随时间发生变化,或者用于训练模型的历史数据有偏差且不代表实际生产数据时,就会发生这种情况。
Data Leakage Example — KDD Cup 2008 [source]
- 数据泄露 :当训练和验证数据中的特征或属性无意中泄露了在推理时不会出现的信息时,就会发生这种情况。这方面的一个经典例子是 2008 年的 KDD 竞赛,关于早期乳腺癌检测,其中一个特征(患者 ID)被发现与目标类别高度相关。
在野外部署模型之前,我们可以通过引入一个额外的步骤让模型理解来规避这些问题。通过解释该模型,我们可以获得更深入的理解,并解决偏差、泄漏和信任等问题。
但是,什么是可解释性?
可解释性是人类可以持续估计模型将预测什么的程度,人类可以理解和遵循模型预测的程度,以及人类可以检测模型何时犯了错误的程度。
尽管可解释性对不同的人有不同的含义:
- 对于一个数据科学家,这意味着更好地理解模型,看到模型做得好或不好的案例以及原因。这种理解有助于数据科学家构建更可靠的模型。
- 对于一个商业利益相关者来说,这意味着更深入地理解为什么一个人工智能系统会做出一个特定的决定,以确保公*并保护其用户和品牌。
- 对于一个用户,这意味着理解为什么一个模型做出一个决定,并且如果模型犯了一个错误,允许有意义的挑战。
- 对于一个专家或监管者来说,这意味着审计人工智能系统并遵循决策轨迹,尤其是当事情出错时。
当你谈论可解释性和模型理解时,留意这些不同的人物角色是很重要的。
模型透明度
Model Complexity
模型的可解释性可通过学习的响应函数对输入特征的复杂程度来表征。上图显示了三种不同类型的响应函数:
- 线性、单调:这些是最容易解释的函数,因为输入特征的变化会导致目标变量在单一方向上成比例的变化(正或负)。这允许我们计算相对特征重要性度量和原因代码。原因代码有助于理解学习模型预测特定输入的高值或低值的原因。它为我们提供了输入特征的预测影响的定性度量,即它是强的、弱的、积极的还是消极的。
- 非线性,单调:机器学习算法学习到的大多数响应函数都是非线性的。单调性确保输入特征的相对变化导致目标变量在单一方向上的变化。非线性单调函数也是可解释的,因为它允许我们计算相对特征重要性度量和原因代码。
- 非线性、非单调:这些是现代机器学习算法学习到的最常见的函数,也是最难解释的。这是因为输入变量的变化会导致目标变量在任何方向上以不同的速率变化。对于这样的函数,我们可以计算的唯一可解释的度量是相对特征重要性。解释这些函数是本文的重点。
超越特性重要性
Feature Importance
现在让我们看一个具体的例子。问题是预测美国高中生的数学、阅读和写作成绩。我们得到了的历史数据,其中包括性别、种族/民族(匿名)、父母教育水*、学生是否吃了标准/免费/补贴午餐以及考试准备程度等特征。给定这些数据,我训练了一个多类随机森林模型[ 源代码 ]。
为了解释模型学到了什么,最简单的方法之一是查看相对的特性重要性。特征重要性衡量给定特征对预测结果的影响有多大。从上面的图表中,看起来两个最重要的特征是——父母的教育水*和种族/民族。这是有用的信息,但它没有告诉我们任何关于不同教育水*如何影响成绩以及种族和教育如何相互作用的信息。
回车,部分依赖图(PDP)!
PDP 向我们展示了特性对预测结果的边际效应。在 Python 中,您可以使用 scikit-learn 中的实现,它将您限制在梯度推进回归器/分类器。更好的实现是由江春·李开发的 PDPBox 。该库受 ICEBox 的启发,ice box 是 R 的 PDP 实现,支持所有 scikit-learn 机器学习模型。您可以按如下方式安装该库。
pip install pdpbox
Partial Dependency Plots for Parent Level of Education in predicting Math Grades A and F
现在让我们来看看 PDP 的运行情况。上图显示了不同教育水*对数学成绩 A 和 F 的影响。当你在 x 轴上从左到右,父母的教育水*增加,从高中一直到硕士学位。你会注意到,随着父母教育水*的提高,对预测 A 级的影响也在增加。F 级也有类似的下降趋势,即父母受教育程度越高,对 F 级的预测影响越小。该分析表明,父母受教育程度是一个有效特征。您可以使用下面的代码片段在 Python 中生成上面的图。
from pdpbox import pdppdp_parent = pdp.pdp_isolate(model=math_model, dataset=df, model_feature=features, feature='parent')
Interaction between Parent Level of Education and Ethnicity in predicting Math Grade A
现在让我们看看预测数学 A 级的特征交互。我在这里挑选了两个最重要的特征。父母的教育水*在 y 轴上,从下到上,教育水*会增加。学生的匿名种族或民族显示在 x 轴上,其中不同的点代表不同的种族-在这项研究中有 5 个不同的群体。请注意热图中的颜色,紫色/蓝色代表预测 A 级的低影响,绿色/黄色代表高影响。
在 0 组上边缘化,你可以看到随着父母教育水*的提高,对预测 A 级的影响也增加。这是有道理的,因为它表明教育水*比种族对成绩的影响更大。因此,该模型很好地学习了这种相关性。但是第五组是怎么回事呢?看起来不管教育水*如何,如果学生属于第 5 组,那么这对于预测 a 级有很大的影响。这在我看来很可疑,它暴露了—
- 可能存在采样偏差的数据问题,
- 模型有问题,和/或
- 社会中的系统性问题
事实证明,这里使用的 Kaggle 数据集是人为的,第 5 组没有得到正确的表示。不管怎样,主要的一点是,仅仅从特性的重要性来看,这些见解都是不可能的。上面的交互图可以用 Python 生成,如下所示。
from pdpbox import pdppdp_race_parent = pdp.pdp_interact(model=math_model, dataset=df, model_features=features, features=['race', 'parent'])
决策树侧边栏
Simple Decision Tree
我想揭穿一个关于决策树的常见误解——它们非常容易解释。让我们再来看一个具体的例子——鸢尾花数据集。问题是基于 4 个特征来预测给定的鸢尾花是刚毛鸢尾、杂色鸢尾还是海滨鸢尾——花瓣长度和宽度,以及萼片长度和宽度。我已经为这个分类任务训练了一个简单的决策树[ 源代码,你可以很容易地在 scikit-learn 中可视化训练好的模型,如上所示。当你沿着树的不同分支往下走时,你可以看到特征是如何影响模型的决策的,这对于一个外行来说是非常容易理解的。
现在让我们来看一个稍微有挑战性的问题。一家医院希望使用人工智能系统来早期检测乳腺癌。这是一个模型理解至关重要的例子,因为这是一个生死攸关的情况。在数据集中,我们被赋予了 30 种不同的特征。我再次为这个二元分类任务训练了一个简单的决策树[ 源代码。从下面的可视化图中,您可以看到随着特征数量的增加,决策树的复杂性也在增加,并且变得更加难以解释。
Complex Decision Tree
你可能会说,我们可以通过降维来减少特征空间的大小,这是完全正确的。但是你必须明白,你在这里是有所取舍的——你是在用准确性换取简单性。这可能不是正确的策略,尤其是对于这样一个关键的决定。因此,决策树不是解决可解释性问题的灵丹妙药。
事后解释
LIME: Local Interpretable Model-agnostic Explanations
让我们回到乳腺癌检测问题。由于准确性对于这样一个关键任务非常重要,如果我们训练一个更复杂的树集合(如随机森林或梯度增强树)甚至一个黑盒神经网络会怎么样?我们如何解释如此复杂的模型?
假设您训练的复杂模型学习了如上所示的决策函数,以将恶性细胞(红色)与良性细胞(蓝色)分开。解释这个复杂模型的一种方法是选择一个您想要解释的实例。然后训练一个简单的线性模型,该模型*似于该实例周围的复杂模型。这意味着我们用更简单的模型来解释一个实例,通过观察它周围的相似案例。因此,习得的表征是局部忠实的,而不是全局忠实的。这种事后解释技术被称为 LIME,它代表局部可解释的模型不可知解释。它是在 2016 年被提出的,此后获得了大量的人气(截至 2019 年 3 月 5 日, Github 上有 5343 位明星)。
Illustration of Surrogate Models
现在让我们换个角度来看一下。我们已经获得了想要分类的不同乳腺癌细胞的数据,在框图中表示为 x 。我们正在训练一个模型,它学习一个复杂的函数 f 来区分良性病例和恶性病例。然后,我们训练一个简单的线性代理模型 g ,它通过*似该点周围的复杂函数来解释一个实例x’。由那个更简单的模型学习到的参数就是解释。这在数学上显示如下。
Additive Feature Attribution Method
在上面的等式中,x'_i 是一个二元变量,用于对所选实例周围的实例进行采样,M 表示简化输入要素的数量。因此,LIME 是一种附加的特征归属方法。
Scott M. Lundberg 等人在 NeurIPS 2017 上提出了一个框架,该框架统一了包括 LIME 在内的各种附加特征归属方法。在本文中,SHAP(代表 SHapley 加法解释)值被用作特征重要性的统一度量。2017 年发布了 SHAP 的 Python 实现,统一了 LIME 和其他技术,如 DeepLIFT 和树解释器。该库自发布以来也越来越受欢迎(截至 2019 年 3 月 3 日, Github 上有 3909 颗星星)。您可以按如下方式安装 SHAP。
pip install shap
现在,对于乳腺癌检测问题,我已经训练了一个随机森林分类器[ 源代码 ],在坚持测试集上获得了 100%的*均精度——参见下面的 PR 曲线。
Precision-Recall Curve for Random Forest Breast Cancer Classifier
为了解释这个模型,我选择了一个恶性案例来运行 SHAP 树解释器。该模型预测该病例为恶性的概率为 0.9。该数据集中恶性肿瘤的基本比率为 0.6251。SHAP 提供的解释如下所示——红色代表积极影响,蓝色代表消极影响。您可以看到不同的特征值如何将基本预测推高到 90%的确定性。正面影响最大的要素是-最差面积、最差凹点和*均凹点。
SHAP Explanation for Malignant Case
对于良性情况也可以得到类似的解释。我挑选了一个良性细胞,该模型以 100%的确定性预测了该细胞,即它是恶性的可能性为 0%。从下面的解释可以看出,各种特征值是如何将恶性肿瘤的基本概率从 0.6251 降低到 0 的。负面影响最大的要素是-最差凹点、*均周长和最差半径。这个解释很棒,因为它让我们对模型如何得出最终预测有了更深刻的理解。
SHAP Explanation for Benign Case
上面的解释可以使用下面的代码片段生成——完整的源代码可以在这里找到。
import shapshap.initjson();explainer = shap.TreeExplainer(rf_model)
shap_values = explainer.shap_values(X_test)# Explanation for malignant case
shap.force_plot(explainer.expected_value[1], shap_values[1][0,:], X_test.iloc[0,:])# Explanation for benign case
shap.force_plot(explainer.expected_value[1], shap_values[1][1,:], X_test.iloc[1,:])
您还可以使用 SHAP 来显示每个要素在预测目标类时的*均影响。这由下面左边的图显示。你可以看到两个最重要的特征是——最差凹点和*均凹点。右边的图显示了这两个特征在预测恶性分类中的相互作用。
Left: SHAP Value Summary Plot for all Features | Right: SHAP interaction between the two most important features
SHAP 也可以用来解释黑盒深度学习模型。下面是 SHAP 解释在 MNIST 数据集上训练的卷积神经网络的例子。SHAP 的 DeepLIFT 实现被用来解释这些预测。红色像素表示对预测数字有很大影响。有趣的是,DeepExplainer 模型发现了一些很好的解释——例如,数字 0 的中间是空白的,数字 4 的两条垂直线之间没有连接。在 SHAP 资料馆还有更多很酷的例子。
SHAP DeepLift Explainer for Convolutional Neural Networks
MOAR 工具!
在本文中,我仅仅触及了皮毛,您还可以应用更多的可解释性技术,例如:
- 使用 RNN 语言模型生成文本解释
- 使用显著图来解释模型关注的是什么
- 使用表征学习和定性可视化技术,如 t-SNE
我在这个 Github 页面上添加了很多资源供进一步阅读。
透明度挑战
我想以一个警告作为结束。在由艾德里安·韦勒撰写的一篇有趣的论文中,他认为人工智能的透明性应该是达到目标的一种手段,而不是目标本身。韦勒博士利用多智能体博弈论来表明,更高的透明度可能导致对所有人不利的全球结果,并可能使人工智能受到恶意行为者的滥用。不言而喻,人工智能系统必须是安全的,能够抵御恶意攻击。这也是另一个活跃的研究领域,值得单独发表一篇博文!
感谢您花时间阅读本文。希望你喜欢。
更新[2020 年 11 月 4 日]:我和 Manning Publications 写了一本关于可解释人工智能的书,里面有更多的可解释技术,你可以把它们添加到你的武器库中。
可解释卷积神经网络
原文:https://towardsdatascience.com/interpretable-convolutional-neural-network-3f7ef6c9b7ae?source=collection_archive---------13-----------------------
这篇论文 由美国加州大学洛杉机分校的张全世、吴英年和宋提出了一种将传统的卷积神经网络(CNN)修改为可解释的 CNN 的方法,以阐明 CNN 的高 conv 层中的知识表示。
Figure 1: Comparison of a filter’s feature maps in an interpretable CNN and those in a traditional CNN
问题:在没有任何额外的人工监督的情况下,我们能修改 CNN 以在其 conv 层获得可解释的知识表示吗?
Bau et al .【1】在 CNN 中定义了六种语义,即物体、零件、场景、纹理、材质、颜色。
实际上,我们可以大致将前两种语义认为是具有特定形状的对象-部分模式,将后四种语义概括为没有清晰轮廓的纹理模式。低 conv 层中的过滤器通常描述简单的纹理,而高 conv 层中的过滤器更可能表示对象部分。
他们的方法是在一个高 conv 层中训练每个滤波器来表示一个对象部分。在传统的 CNN 中,高层过滤器可以描述一个混合模式,即过滤器可以被猫的头部和腿部激活(图 1)。高 conv 层中的这种复杂表示大大降低了网络的可解释性。因此,他们的方法 迫使 可解释 CNN 中的滤波器被某个部分激活。
学习更好的表达方式
本文发明了一种通用损失来正则化滤波器的表示,以提高其可解释性。
该损失促使类别间激活的低熵和神经激活的空间分布的低熵,这意味着迫使 CNN 中层的特征图不被对象的不同区域随机激活,并且具有一致的激活分布。
滤镜必须由对象的单个部分激活,而不是重复出现在不同的对象区域。
他们假设不同区域上的重复形状更倾向于描述低级纹理(例如颜色和边缘),而不是高级部分。
如何做到这一点?
Figure 3
Figure 4
- 设 I 表示一组训练图像,其中 I_c ⊂ I 表示属于类别 c 的子集,( c = 1,2,.。。,C)。
- 在 ReLU 操作后,给滤波器 f 的特征图 x 增加一个损耗
- 特征图 x 是一个 n × n 矩阵, x_ij ≥ 0。
- f 对应的对象部分可能出现在不同图像的不同位置,为 f {T_ 1,…,T_ n } 设计 n 模板
- 每个模板 T_ i 也是一个 n × n 矩阵,它描述了当目标零件主要触发 x 中的 i-th 单元时,特征图 x 的激活的理想分布
- = argmax_[i,j] x_ij
- x^masked = max{x . T_,0}*
在他们的代码实现中,实际上他们在特征图中寻找最大值(有 2 种方法,但最简单的是最大值),然后创建一个类似高斯形状的掩码(如图 3)与特征图具有相同的形状(例如,特征图的大小为 6x6,然后模板掩码的大小为 6x6),然后与掩码执行元素乘法,并产生一个新的掩码特征图(图 4)。如果特征映射中的最大值为 0,则该模板被视为负模板,这意味着该过滤器不会为该对象激活。
注释
1.要素地图=图层中的过滤器。
2。本文中的训练数据每幅图像只包含一个零件/对象,如果有两个相同的对象,训练可能会失败?或者两个相同的对象可能有一点不同,因此被两个滤波器激活。
损失函数
我太年轻了,无法解释这个,只能说说我对损失函数的理解。请阅读原文,了解这些方程的更多细节。
Equation 1: the loss for f as the mutual information between X and T. The prior probability of a template is given as p(Tµ) = α n2 , p(T −) = 1 − α, where α is a constant prior likelihood.
Equation 2: The fitness between a feature map x and a template T is measured as the conditional likelihood p(x|T).
Equation 3: each filter in an interpretable conv-layer receives gradients w.r.t. its feature map x from both the final task loss L(ˆyk, y∗ k) and the local filter loss Lossf
Equation 4: compute gradients of Lossf w.r.t. each element xij of feature map x as follows
Equation 5: rewrite Equation 1, H(T) = − P T ∈T p(T) log p(T) is a constant, which denotes the prior entropy of part templates.
Equation 6: Low inter-category entropy
Equation 7: Low spatial entropy
TLDR: 所有这些方程对我来说仍然是清晰的,就我的理解而言,损失函数推动过滤器 f 来表示类别 c 的特定对象部分,并对 CNN 中的其他类别的图像和层的特征图保持沉默,以不被对象的不同区域随机激活,并具有一致的激活分布。
实验设置
为了简单起见,VGG
三个基准数据集:因为他们需要物体地标(部分)的地面实况注释来评估每个过滤器的语义清晰度,所以他们选择了三个带有地标/部分注释的基准数据集来进行训练和测试,包括 ILSVRC 2013 DET 动物部分数据集、cub 200–2011 数据集和 Pascal VOC 部分数据库。
实验结果
他们在零件可解释性和位置稳定性上取得了较好的成绩。普通 CNN 在单类别分类中表现更好。然而,对于多类别分类,可解释 CNN 表现出比普通 CNN更好的性能。在多类别分类中的良好表现可能是因为早期阶段的过滤器语义的澄清降低了后期阶段过滤器学习的难度。更多结果,请阅读原文。
The top four rows visualize filters in interpretable CNNs, and the bottom two rows correspond to filters in ordinary CNNs. They found that interpretable CNNs usually encoded head patterns of animals in its top conv-layer for classification.
与普通 CNN 相比,可解释 CNN 具有更一致和更容易理解的激活。我们可以确认顶部 conv 层中的特定滤镜代表特定动物的头部图案。
结论
- 提出了一种通用的方法来修改传统的细胞神经网络,以增强其可解释性
- 损失被设计成将高 conv 层中的过滤器推向对象部分的表示,而没有用于监督的附加注释
- 与传统的 CNN 相比,可解释的 CNN 在高 conv 层编码了更多语义上有意义的知识。
参考
代号:https://github.com/zqs1022/interpretableCNN
论文:张全世,吴英年,宋,“可解释卷积神经网络”,2018
可解释的机器学习
原文:https://towardsdatascience.com/interpretable-machine-learning-1dec0f2f3e6b?source=collection_archive---------1-----------------------
从任何机器学习模型中提取人类可理解的见解
Photo by Pixabay from Pexels
是时候摆脱黑箱,培养对机器学习的信任了
在他的书' 可解释的机器学习 '中, Christoph Molnar 通过这个例子很好地概括了 ML 可解释性的本质:假设你是一名数据科学家,在你的空闲时间里,你试图根据你的脸书和推特数据预测你的朋友夏天会去哪里度假。现在,如果预言被证明是准确的,你的朋友可能会留下深刻印象,并认为你是一个能预见未来的魔术师。如果预测是错误的,它仍然不会给任何人带来伤害,除了你作为“数据科学家”的名声。现在,让我们说这不是一个有趣的项目,有投资参与。比方说,你想投资你的朋友可能去度假的房产。如果模型的预测出错,会发生什么?你会赔钱的。只要模型没有重大影响,它的可解释性就没那么重要,但当基于模型的预测有影响时,无论是金融还是社会影响,可解释性就变得重要了。
可解释的机器学习
解释的意思是用可理解的术语解释或陈述。在人工智能系统的背景下,可解释性是用可理解的术语解释或呈现给人类的能力
Source: interpretable-ml-book
机器学习模型被许多人贴上了“黑箱”的标签。这意味着,尽管我们可以从中获得准确的预测,但我们无法清楚地解释或识别这些预测背后的逻辑。但是我们如何从模型中提取重要的见解呢?要记住什么,我们需要什么特性或工具来实现它?当提出模型可解释性的问题时,这些是浮现在脑海中的重要问题。
可解释性的重要性
一些人经常问的问题是,为什么我们不仅仅满足于模型的结果,为什么我们如此执着于了解为什么会做出一个特定的决定?这很大程度上与模型在现实世界中可能产生的影响有关。因为仅仅是用来推荐电影的模型远不如那些用来预测药物效果的模型有影响力。
问题在于,单一指标(如分类准确率)无法完整描述大多数现实任务(多希-维勒兹和金 2017 )
这是一个可解释的机器学习的大图。在某种程度上,我们通过收集原始数据来捕捉世界,并使用这些数据来进行进一步的预测。本质上,可解释性只是模型的另一层,帮助人类理解过程。
The big picture of explainable machine learning.
可解释性带来的一些好处是:
- 可靠性
- 调试
- 通知特征工程
- 指导未来的数据收集
- 通知人类决策
- 建立信任
模型解释技术
理论只有在我们能付诸实践时才有意义。如果你想真正掌握这个话题,你可以试试 Kaggle 的机器学习可解释性速成班。它有适当数量的理论和代码来将概念放入透视图中,并帮助将模型可解释性概念应用到实际的、真实世界的问题中。
点击下方截图,直接进入课程页面。如果你想先对内容有一个简要的概述,你可以继续往下读。
可以从模型中提取的见解
为了解释模型,我们需要以下见解:
- 模型中的特性是最重要的。
- 对于模型中的任何单个预测,数据中的每个特征对该特定预测的影响。
- 每个特征对大量可能预测的影响
让我们讨论一些有助于从模型中提取上述见解的技术:
1.排列重要性
一个模特认为什么特征是重要的?哪些功能可能比其他功能对模型预测的影响更大?这个概念被称为特征重要性,而排列重要性是一种广泛用于计算特征重要性的技术。这有助于我们看到我们的模型何时产生违反直觉的结果,也有助于向其他人展示我们的模型何时如我们所愿地工作。
排列重要性适用于许多 scikit-learn 估计器。这个想法很简单:随机置换或打乱验证数据集中的单个列,而保持所有其他列不变。如果模型的精度下降很多并导致误差增加,则特征被认为是“重要的”。另一方面,如果改变一个特征的值不会影响模型的准确性,那么这个特征就被认为是“不重要的”。
工作
考虑一个基于某些参数预测足球队是否会有“足球先生”赢家的模型。表现最好的玩家被授予这个称号。
排列重要性是在模型拟合后计算的。因此,让我们在训练数据上训练并拟合一个 RandomForestClassifier 模型,表示为 my_model 。
使用 ELI5 库计算排列重要性。 ELI5 是一个 Python 库,允许使用统一的 API 可视化和调试各种机器学习模型。它内置了对几种 ML 框架的支持,并提供了一种解释黑盒模型的方法。
使用 eli5 库计算和显示重要性:
(此处val_X,val_y
分别表示验证集)
import eli5
from eli5.sklearn import PermutationImportanceperm = PermutationImportance(my_model, random_state=1).fit(val_X, val_y)
eli5.show_weights(perm, feature_names = val_X.columns.tolist())
释义
- 顶部的特性最重要,底部的最不重要。对于这个例子,进球得分是最重要的特征。
- 后面的数字表示从一次重组到下一次重组的绩效变化。
- 有些权重是负数。这是因为在那些情况下,对混洗数据的预测被发现比真实数据更准确。
练习
现在,为了获得完整的示例并测试您的理解,请点击下面的链接进入 Kaggle 页面:
2.部分相关图
部分相关性图(短 PDP 或 PD 图)显示了一个或两个特征对机器学习模型的预测结果的边际效应( J. H. Friedman 2001 )。PDP 显示一个特性如何影响预测。PDP 可以通过 1D 或 2D 图显示目标和所选特征之间的关系。
工作
PDPs 也是在模型拟合后计算的。在我们上面讨论的足球问题中,有许多特征,如传球、射门、进球等。我们从考虑单行开始。假设这一行代表一支 50%时间有球、传球 100 次、射门 10 次、进球 1 次的球队。
我们继续拟合我们的模型,并计算一个球队有一名球员赢得“最佳球员”的概率,这是我们的目标变量。接下来,我们将选择一个变量并不断改变它的值。例如,如果球队进了 1 个球、2 个球、3 个球等等,我们将计算结果。所有这些值都被绘制出来,我们得到了一个预测结果与得分的图表。
用于绘制 PDP 的库被称为 python 部分依赖绘图工具箱或简称为 PDPbox 。
from matplotlib import pyplot as plt
from pdpbox import pdp, get_dataset, info_plots*# Create the data that we will plot*
pdp_goals = pdp.pdp_isolate(model=my_model, dataset=val_X, model_features=feature_names, feature='Goal Scored')*# plot it*
pdp.pdp_plot(pdp_goals, 'Goal Scored')
plt.show()
解读
- Y 轴表示预测值相对于基线值或最左侧值的变化。
- 蓝色区域表示置信区间
- 对于“进球得分”图表,我们观察到进球得分增加了获得“本场最佳”奖的可能性,但过了一会儿就饱和了。
我们也可以使用 2D 部分图同时显示两个特征的部分相关性。
练习
3.SHAP 价值观
SHAP 代表着Shapley****Aadditive exP解释有助于分解预测,以显示每个特征的影响。它基于 Shapley 值,这是一种在博弈论中使用的技术,用于确定合作游戏中的每个玩家对其成功做出了多少贡献。通常情况下,在准确性和可解释性之间取得*衡可能是一个困难的*衡行为,但 SHAP 价值观可以同时实现这两者。
工作
再一次,以足球为例,我们想要预测一个球队有一名球员赢得“比赛最佳球员”的概率。SHAP 值解释了给定特征具有某个值与如果该特征具有某个基线值时我们所做的预测相比的影响。
SHAP 值是使用 Shap 库计算的,该库可以很容易地从 PyPI 或 conda 安装。
Shap 值显示给定特征改变我们预测的程度(与我们在该特征的某个基线值进行预测相比)。假设我们想知道当球队进了 3 个球而不是某个固定的基线数字时,预测是什么。如果我们能够回答这个问题,我们可以对其他特征执行相同的步骤,如下所示:
sum(SHAP values for all features) = pred_for_team - pred_for_baseline_values
因此,预测可以分解成如下图:
Here is a link for a larger view
释义
上面的解释显示了将模型输出从基础值(我们传递的训练数据集的*均模型输出)推送到模型输出的每个功能。将预测值推高的要素显示为红色,将预测值推低的要素显示为蓝色
- 这里的 base_value 是 0.4979,而我们的预测值是 0.7。
Goal Scored
= 2 对增加预测的影响最大,而ball possession
该特征在降低预测方面具有最大的效果。
练习
SHAP 价值观有比我在这里解释的更深层次的理论。请务必通过下面的链接获得完整的理解。
4.SHAP 价值观的高级应用
聚合许多 SHAP 值可以提供对模型更详细的了解。
- SHAP 概要剧情
为了了解哪些特征对模型最重要,我们可以绘制每个样本的每个特征的 SHAP 值。汇总图显示了哪些要素最重要,以及它们对数据集的影响范围。
Summary Plot
对于每个点:
- 垂直位置显示了它所描绘的特征
- 颜色显示该特征对于数据集的该行是高还是低
- 水*位置显示该值的影响是否会导致更高或更低的预测。
左上角的点是一支进球很少的球队,将预测值降低了 0.25。
- SHAP 依赖贡献图
SHAP 汇总图给出了每个特征的总体概述,而 SHAP 依赖图显示了模型输出如何随特征值而变化。SHAP 依赖贡献图为 PDP 提供了类似的见解,但它们添加了更多的细节。
Dependence Contribution plots
上面的依赖贡献图表明,有球增加了球队让他们的球员赢得奖项的机会。但是如果他们只进了一个球,这种趋势就会逆转,裁判可能会因为他们得了那么多球而处罚他们。
实践
结论
机器学习不必再是黑匣子了。如果我们不能向他人解释结果,那么好的模型有什么用呢?可解释性和创建模型一样重要。为了在人群中获得更广泛的接受,机器学习系统能够为他们的决定提供令人满意的解释是至关重要的。正如阿尔伯特·爱因斯坦所说,“如果你不能简单地解释它,你就理解得不够好”。
参考资料:
[可解释的机器学习:使黑盒模型可解释的指南。克里斯托夫·莫尔纳尔](http://Christoph Molnar)
机器学习可解释性微课:Kaggle
基于石灰的可解释机器学习图像分类
原文:https://towardsdatascience.com/interpretable-machine-learning-for-image-classification-with-lime-ea947e82ca13?source=collection_archive---------9-----------------------
通过理解机器学习模型的预测来增强对它的信心。
在自动驾驶汽车和医疗诊断等关键应用中使用机器学习的趋势日益增长,这表明迫切需要有助于理解和评估机器学习模型预测的方法。局部可解释模型不可知解释(LIME)[1]是一种解释机器学习模型的输入特征如何影响其预测的技术。例如,对于图像分类任务,LIME 找到与预测标签关联最强的图像区域(超像素集)。这篇文章用 Python 代码一步一步地介绍了 LIME 在图像分类中的内部工作原理。
让我们首先读取一个图像,并使用 Keras 中可用的预训练的 InceptionV3 模型来预测此类图像的类别。
该脚本将输入图像加载到变量Xi
中,并打印图像的前 5 个类别(和概率),如下所示:
- 拉布拉多寻回犬(82.2%)
- 金毛寻回犬(1.5%)
- 美国斯塔福德郡梗(0.9%)
- 公牛獒(0.8%)
- 大丹犬(0.7%)
有了这些信息、输入图像和预训练的 InceptionV3 模型,我们可以继续用 LIME 生成解释。在这个例子中,我们将为类拉布拉多猎犬生成解释。
石灰解释
LIME 通过围绕被解释的实例生成新的随机扰动数据集(及其各自的预测),然后拟合加权局部代理模型来创建解释。该局部模型通常是具有内在可解释性的更简单的模型,例如线性回归模型。关于石灰背后的基础知识的更多细节,我推荐你查看这篇简短的教程。对于图像分类的情况,LIME 通过以下步骤生成解释:
步骤 1:为输入图像生成随机扰动
对于图像,LIME 通过打开和关闭图像中的一些超像素来产生扰动。以下脚本使用快速移动分割算法来计算图像中的超像素。此外,它生成 150 个扰动的阵列,其中每个扰动是具有 0 和 1 的向量,表示超像素是开还是关。
计算完图像中的超像素后,我们得到:
以下是扰动向量和扰动图像的示例:
步骤 2:预测扰动的类别
下面的脚本使用inceptionV3_model
来预测每个扰动图像的类别。predictions
的形状是(150,1000)
,这意味着对于 150 幅图像中的每一幅,我们得到属于 InceptionV3 中的 1000 个类别的概率。在这 1000 个类中,我们将在后续步骤中仅使用 Labrador 类,因为它是我们想要解释的预测。在这个例子中,使用了 150 次扰动。然而,对于实际应用,更多的扰动将产生更可靠的解释。
现在我们有了一切来拟合一个线性模型,使用perturbations
作为输入特征X
,拉布拉多的预测predictions[labrador]
作为输出y
。然而,在我们拟合线性模型之前,LIME 需要给与被解释图像更接*的图像更多的权重(重要性)。
步骤 3:计算扰动的权重(重要性)
我们使用距离度量来评估每个扰动离原始图像有多远。原始图像只是所有超像素活动(所有元素合二为一)的扰动。假设扰动是多维向量,余弦距离是可用于此目的的度量。计算余弦距离后,使用核函数将该距离转换为 0 和 1 之间的值(权重)。在这个过程的最后,我们对数据集中的每个扰动都有一个权重(重要性)。
第四步:使用perturbations
、predictions
和weights
拟合一个可解释的线性模型
我们使用前面步骤中获得的信息拟合加权线性模型。我们为图像中的每个超像素获得一个系数,该系数表示超像素在拉布拉多预测中的影响有多强。
我们只需要对这些系数进行排序,就可以确定对于拉布拉多的预测,哪些是最重要的超像素(top_features
)。尽管这里我们使用了系数的大小来确定最重要的特征,但是诸如向前或向后消除之类的其他选择也可以用于特征重要性选择。计算顶部超像素后,我们得到:
这是石灰返回的解释。与“拉布拉多猎犬”的预测有更强关联的图像区域(超像素)。这种解释表明,预训练的 InceptionV3 模型在预测给定图像的拉布拉多类方面做得很好。这个例子显示了 LIME 如何通过理解它为什么返回某些预测来帮助增加机器学习模型的信心。
一个 Jupyter 笔记本里面有本帖使用的所有 Python 代码可以在这里找到。你可以通过在 Google Colab 中打开笔记本来轻松测试对你自己图像的解释。
参考文献
[1]里贝罗、马尔科·图利奥、萨梅尔·辛格和卡洛斯·盖斯特林。“我为什么要相信你?:解释任何分类器的预测。 (2016)第 22 届美国计算机学会会议录。ACM。
Kappa 值的解释
原文:https://towardsdatascience.com/interpretation-of-kappa-values-2acd1ca7b18f?source=collection_archive---------3-----------------------
评估与条件的一致程度
kappa 统计经常被用来检验评分者之间的可靠性。评分者可靠性的重要性在于它代表了研究中收集的数据在多大程度上正确地代表了被测变量。衡量数据收集者(评分者)对同一变量赋予相同分数的程度称为评分者间信度。1960 年,雅各布·科恩批评了百分比协议的使用,因为它无法解释偶然协议。他介绍了科恩的 kappa,这是为了说明评级者由于不确定性而实际上猜测至少一些变量的可能性而开发的。卡伯值解释的范围如下:
卡帕值解读兰迪斯&科赫(1977):
< 0 无协议
0 — .20 轻微
.21 — .40 一般
.41 — .60 中等
.61 — .80 实质
. 81—1.0 完美
然而,过去的研究表明,多种因素对 Kappa 值有影响:观察者的准确性,代码在集合中的数量,特定代码的流行程度,观察者的偏见,观察者的独立性(Bakeman & Quera,2011)。因此,对 kappa 的解释,包括什么是好的 Kappa 的定义,应该考虑到具体情况。
模拟
为了更好地理解 Cohen Kappa 系数的条件解释,我采用了 Bakeman 等人(1997)提出的 Cohen Kappa 系数的计算方法。这些计算作出了简化的假设,即两个观察者都是同样准确和无偏见的,代码以同样的准确性被检测到,不一致是同样可能的,并且当患病率变化时,它以均匀分级的概率变化(Bakeman & Quera,2011)。
设置
最大编码数:52
观测器数:2
观测器精度范围:0.8、0.85、0.9、0.95
编码流行度:等概率、中等变化、高度变化
Settings of parameters in the simulation
调查的结果
在 612 个模拟结果中,245 个(40%)达到了完美水*,336 个(55%)达到了基本水*,27 个(4%)达到了中等水*,3 个(1%)达到了一般水*,1 个(0%)达到了轻微水*。对于每个观察者准确度(. 80,. 85,. 90,. 95),每个流行水*有 51 个模拟。
观察者准确度
观测者准确度越高,总体一致性水*越好。在各种观察者准确度下,各患病率水*的一致水*的比率。一致性水*主要取决于观察者的准确性,其次是代码的流行程度。“完美”的一致只出现在观察者准确度为 0.90 和 0.95 时,而所有类别都达到大多数的基本一致或以上。
Kappa and Agreement Level of Cohen’s Kappa Coefficient
观测者精度影响最大 Kappa 值。如仿真结果所示,从 12 个代码开始以及向前,Kappa 值似乎分别达到大约 0.60%、0.70%、0.80%和 0.90%的准确度。
Cohen’s Kappa Coefficient vs Number of codes
观察中的代码数
增加编码数导致 Kappa 增量逐渐变小。当编码数小于 5 时,特别是当 K = 2 时,较低的 Kappa 值是可以接受的,但也需要考虑患病率的可变性。仅对于两个代码,来自准确度为. 95 的观察者的最高 kappa 值为. 80,来自准确度为. 80 的观察者的最低 kappa 值为. 02。
编码的数量越大,复原力 Kappa 值就越趋向于观察者的准确度差异。当观测者精度之间的差距变大时,Kappa 值减小
个人代码的流行程度
患病率越高,总体一致程度越低。患病率越高,认同水*越低。在观察者精度水*为 0 . 90 时,对于等概率、中等变化和极端变化,分别有 33、32 和 29 个完全一致。
Standard Deviation of Kappa Value vs Number of codes
随着代码数量的增加,代码流行度的影响不大。当编码数为 6 或更高时,患病率可变性无关紧要,从精确度为. 80、. 85、. 90 和. 85 的观察者获得的 kappa 值的标准偏差小于 0.01。
建议
Recommendation of interpreting Kappa along with the number of codes
影响 kappa 值的因素包括观察者准确性和编码数量,以及编码的个体人群流行率和观察者偏差。只有当观察者*均分配代码时,Kappa 才能等于 1。kappa 没有一个价值观可以被视为普遍接受;这取决于观察者的准确度和代码的数量。
对于较少数量的代码(K < 5),特别是在二进制分类中,Kappa 值需要格外小心地解释。在二元分类中,患病率变异性对 Kappa 值的影响最大,并导致不同观察者准确性与患病率变异性组合的 Kappa 值相同。
另一方面,当多于 12 个代码时,预期 Kappa 值的增量变得*坦。因此,简单地计算同意的百分比可能已经达到了衡量同意程度的目的。此外,性能度量单元的值从灵敏度的增量也从多于 12 个码达到渐*线。
如果 Kappa 值被用作观察者训练的参考,使用 6 到 12 之间的代码数将有助于更准确的性能评估。因为 Kappa 值和性能度量对性能改进足够敏感,并且受代码流行的影响较小。
参考
阿尤布和埃尔加马尔(2018)。利用 Twitter 数据识别和解决运行时业务流程中断。在计算机科学讲义(包括人工智能子系列讲义和生物信息学讲义)中。https://doi.org/10.1007/978-3-030-02610-3_11
Bakeman,r .,& Quera,V. (2011 年)。行为科学的顺序分析和观察方法。行为科学的顺序分析和观察方法。https://doi.org/10.1017/CBO9781139017343
麦克休博士(2012 年)。评分者间可靠性:测量评分者间可靠性的 kappa 统计重要性。生化医学, 22 (3),276–282。
Nichols,T. R .,Wisner,P. M .,Cripe,g .,& Gulabchand,L. (2011 年)。将卡帕统计数据用于托马斯。质量保证期刊,57–61。https://doi.org/10.1002/qaj
W.朱,倪正和倪伟(2010)。灵敏度,特异性,准确性,相关的置信区间和 ROC 分析与实际 SAS。NESUG 保健和生命科学会议录,1–9。
解读集群——数据科学和直觉的结合
原文:https://towardsdatascience.com/interpreting-clusters-29975099eea1?source=collection_archive---------9-----------------------
形成集群是容易的,解释是困难的
这样你就有了漂亮的集群。现在怎么办?这些集群意味着什么?理解集群的意义可能比创建集群更重要。制造聚类的过程更多地是面向数学的,然而解释聚类是数学和直觉的混合。让我们在这里探索理解和解释集群的不同方式
让我们看一个电信数据集,它显示了关于客户的各种数据,例如
- 客户人口统计数据,如性别、年龄、是否为老年人、合作伙伴、受抚养人、位置等..
- 账单和合同数据,如月费、总费用、无纸化账单、合同期限等..
- 服务使用数据,如电话服务、互联网服务、在线安全等。
这里显示了数据的快照
Snapshot of telecommunication data
让我们假设聚类的目标是更好地了解客户。有了这个目标,我们可以说我们已经完成了三组工作。
三个集群的可视化如下所示。可视化的二维表示 PCA(主成分分析)的输出。电信数据集大约有 30 列。然而,为了可视化的目的,这 30 个维度已经被压缩为 2 个维度,而没有失去使用 PCA 的数据的本质
散点图上的每个点代表一个客户,颜色显示它属于哪个分类
Nice looking clusters
正如你将观察到的那样,这些集群结构良好。它们看起来漂亮整洁。但是它们是什么意思呢?除非我们提取这三组的意义,否则美丽的观想仍然只是观想练习。这里有一些方法来提取聚类的含义
1.在最多变的维度上观想——与众不同,脱颖而出!
这里的直觉是,为了给一个集群赋予意义,你必须看到它与其他集群有多么不同。了解一个集群与其邻居有何不同的有效方法是关注变化最大的维度或列。获得变化最大的列的一种方法是获取 PCA 的结果。PCA 有效地保留变化最大的维度,并压缩变化最小的维度。
PCA 的输出之一,称为特征影响,给出变化最大的列(或也称为特征)。该输出如下图所示。如您所见,总费用和任期在顶部变化的列中。
PCA Feature influence
因此,总费用和任期可用于区分不同的集群。总费用与任期的散点图如下所示。点的颜色表示聚类。我们看到这些集群可以相互区分,并且没有太多的重叠。这意味着总电荷和任期可以帮助区分集群和提取集群的意义。
Cluster visualisation based on tenure and TotalCharges
有了这种形象化,我们可以如下描述集群
第 0 类—总费用高、任期长的客户
第 1 类—总费用低到中等、租期低到中等的客户。
第 2 类—总费用较低的客户(以及所有租赁期)。
2 —机器学习来确定聚类的意义—让机器去做
现在让我们超越降维,进入另一个维度。(双关语)…。机器学习。这里的直觉是将聚类(0,1,2)视为目标类,将列视为输入要素。这有效地将确定聚类的含义的问题转化为分类问题。然后,我们可以尝试使用机器学习算法进行分类,以便“机器学习”输入(数据列或特征)和输出(聚类)之间的关系。然后解释输入和输出之间的这种机器学习的关系将使我们深入了解聚类的意义
我们可以使用多种机器学习算法。然而,因为我们的目的是解释机器学习的输入和输出之间的关系,所以最好选择可解释的算法。决策树是高度可解释性的机器学习算法之一。所以让我们在这里使用它。这里显示了决策树
Decision tree to understand meaning of cluster
从决策树中,我们看到区分集群的最重要的特征是总费用和无 _ 互联网服务。基于决策树,我们可以将集群解释如下
集群 0 —总费用高的客户
第 1 类—总费用低到中等,但有互联网服务的客户
第 2 类—总费用低到中等,但没有互联网服务的客户
3 —动画—解释集群的创新方式
上述两种方法告诉我们,聚类有多种解释。有多个“顶部”列是定义集群的良好候选。其中一些列是总费用,任期,互联网服务。因此,如何选择最佳的列来帮助我们更好地了解集群。为了回答这个问题,让我们拿出几把大枪——动画
当眼前发生变化时,人类会更好地理解。原因是任何发生在人类眼前的变化都会激活大脑神经元。
对于数据,动画可以帮助更好地理解数据中发生的任何变化。这比静态观想更有效。在我们的例子中,让我们看看动画是如何帮助我们更好地理解集群的含义的。
在下面的动画中,您将看到如前所示的散点图。然而,我们现在根据不同的列来制作动画。
第一部基于 TotalCharges 的动画。当动画开始时,所有总费用高的客户都以黑色突出显示。随着动画的进行,这些点会根据总电荷的低值高亮显示
Cluster Animation based on Total Charges
下面的第二个动画是基于任期。
Cluster Animation for Tenure
第三部动画基于 InternetService。这部动画很有趣。如您所见,左侧的群集(群集 2)完全突出显示,表示没有互联网服务。
Cluster Animation based on Internet Service
这些动画帮助我们更好地理解集群的含义。我们观察到没有互联网服务的客户清楚地定义了集群 2
我们现在可以根据所有的方法得出结论,一个好的解释可能是遵循聚类意义
第 0 类—总费用高的客户(互联网服务总是如此)
第 1 类—总费用低到中等,但有互联网服务的客户
第 2 类—没有互联网服务的客户
除了描述之外,给集群起一个简短而有意义的名字也是有用的。例如,我们可以有以下简称
集群 0 —黄金客户
群组 1 —适度参与的客户
第 2 类—数字化非参与型客户
起这样的名字也有助于有效地制定营销策略。其中一个策略是将适度参与的客户转化为黄金客户
朋友们,这就是我们所看到的,群集解释的结果,如下图所示
Result of cluster interpretation
在这个故事中,你已经看到了如何解释一个集群。掌握这些方法将有助于您更好地理解聚类的结果。这将使你能够采取更好的行动,例如瞄准客户,设计营销活动,或者只是与利益相关者进行有效的沟通
额外资源
网站(全球资讯网的主机站)
你可以访问我的网站进行零编码分析。https://experiencedatascience.com
请订阅每当我发布一个新的故事时,请及时通知我。
[## 每当 Pranay Dave 发表文章时,您都会收到电子邮件。
每当 Pranay Dave 发表文章时,您都会收到电子邮件。通过注册,您将创建一个中型帐户,如果您还没有…
pranay-dave9.medium.com](https://pranay-dave9.medium.com/subscribe)
你也可以通过我的推荐链接加入 Medium。
[## 通过我的推荐链接加入 Medium—Pranay Dave
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
pranay-dave9.medium.com](https://pranay-dave9.medium.com/membership)
https://www.youtube.com/c/DataScienceDemonstrated 的 YouTube 频道
这里是我的 Youtube 频道
的链接
使用 Python Matplotlib 通过可视化解释数据
原文:https://towardsdatascience.com/interpreting-data-through-visualization-with-python-matplotlib-ef795b411900?source=collection_archive---------9-----------------------
IBM 数据可视化课程教会了我什么?
Matplotlib 虽然已经老化,但仍然是数据可视化最重要的工具之一,这篇文章是关于有效地使用 matplotlib,从数据集中获取知识。大约一个月前,我开始参加 IBM 数据科学专业证书课程,我发现数据可视化课程是 9 门课程的一部分,这篇文章是我在课程中学到的一些强有力的技术的预演,以更好地阐明数据。这里展示了一些有用的绘图技术和从数据中得出的新推论,这些在本课程中并没有用到。你会在我的 GitHub 上找到详细的代码,我在那里分享了 Jupyter 笔记本。比起代码,我会更关注情节,有时会分享一些代码片段。
数据集处理 1980 年至 2013 年间来自不同国家的加拿大移民。
Canada Immigration Data in .xlsx format.
因为数据集是在。xlsx 格式,文件中有 3 张纸,下面是笔记本的一部分,指导您如何将此文件读入数据框
skiprows
用于处理 excel 表中最初无用的行。为了更好地理解,最好将该列(使用[pandas.DataFrame.rename](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rename.html)
)‘OdName’和‘AreaName’分别重命名为‘Country _ Name’和‘continentals’,inplace=True
确保更改保存在数据框中。如果您不想在原始数据帧中进行这种更改,您应该使用inplace=False
。
条形图:DataFrame.plot(kind='bar ')
一旦我们设置好并做了一些调整,让我们使用 pandas DataFrame.plot 绘图,首先我们将尝试一些条形图。如果我们绘制这些年来自海地的移民数量,我们可以看到在 2009 年,2010 年,2011 年移民数量惊人的增长趋势。
Figure 1: Rising number of Haitian Immigrants near 2011.
有些人可能已经猜对了,由于 2010 年灾难性的海地地震,2011 年移民数量急剧增加。让我们用牛逼的注解来做一个清晰的表示
Figure 2: Cool annotation added to Figure 1 to have a more purposeful plot.
随着冰岛金融危机 (2008 年至 2011 年)导致严重的经济衰退,来自冰岛的移民数量也呈现出非常相似的趋势。
Figure 3: Economic crisis in Iceland caused a severe increase in number of immigrants to Canada.
我们可以使用条形图继续查看不同国家的趋势,但是,让我们探索另一种可视化数据的方法,使用饼图。
饼图:DataFrame.plot(kind='pie ')
饼图是一种圆形图形,圆形图中的切片代表数字比例。在这里,我们可以使用饼图看到来自不同大陆的移民的数字比例在 20 年(1985 年和 2005 年)内如何变化。然而,有效的代表性是一个问题。让我们看看下面的代码和相应的情节
Figure 4: Pie plots of Immigrants from different continents in the year 1985 and 2005 are shown in left and right panel respectively.
正如你所看到的,这些饼状图在视觉上并不令人满意,即使我们对 20 年间来自不同大洲的移民的百分比变化有了一个粗略的了解,但这仍然不是很清楚。不过,使用正确的关键字可以让饼状图变得更好。
Figure 5: Same as figure 4 but this one is just too visually esthetic compared to the previous one. In right panel shadow is added.
下面给出了用于绘制上述饼状图的代码片段
我学到的几个重要关键字是autopct
和pctdistance
,它们确保百分比显示到小数点后两位(1.3f 将显示最多小数点后三位的浮点数),并固定文本与圆心的距离。为了制作一个包含子情节的标题,我使用了[matplotlib.pyplot.suptitle](https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.suptitle)
。
从上面的图表中你可以看到,1985 年很大一部分移民来自欧洲,相比之下,20 年后的 2005 年则完全由亚洲人主导。实际上,早期的移民大多来自不列颠群岛,后来印度和中国接管了这个地方。
气泡图:
气泡图基本上是美化的散点图,其中三维数据可以显示在 2D 图中。除了通常的 X 和 Y,气泡(或任何其他标记)的大小代表另一个维度(读取特征)。
为了查看此类图表的示例,我选择了 1980 年至 2013 年间印度和中国的移民信息。我们看到在 1997-1998 年间,这一数字有所上升,这可能是由于亚洲金融危机。下面来看看
Figure 6: Bubble plots of Immigrants from China and India to Canada over the years 1980 to 2013.
如果你注意到星形标记(代表来自印度的移民),它们会变大,颜色会随着时间从紫色变成蓝色。让我们看看下面的代码片段,以了解标记的大小和颜色到底代表了什么
在plt.scatter
中,s 和 c 代表标记的大小和颜色。特别是对于这个代表印度移民的图,我利用了这两个参数。这里 s 是这些年来移民的标准化值(乘以 2000,以便标记大小足够大),而 c、cmap 仅代表移民的原始数量。因此,蓝色代表移民人数较多,而紫色则相反。
世界地图:叶子。地图()
课程中一个非常吸引人的部分是使用叶子库,它有助于创建几种类型的交互式传单地图。我们将看到使用相同的移民数据集,如何在世界地图上很好地表现一些关键信息。首先,我们开始安装叶。
pip install Folium
print folium.__version__ # check the version >> 0.7.0
我们感兴趣的一种特殊的地图叫做 Choropleth 。这是一种专题地图,其中地图的一部分根据所使用的统计变量的比例进行着色/图案化。在这里,我将画出从 1985 年到 2005 年世界各地移民数量的变化。我们以前见过的大陆饼状图,可以用来补充这张 Choropleth 图。
现在,要创建 Choropleth 地图,我们需要一个. json 文件,其中包含所有国家的边界坐标,这个文件是由 IBM 提供的,您可以从我的 GitHub 中获得。据此,我使用下面的代码片段绘制了一张 1985 年全世界移民的 choropleth 地图。这张地图是交互式的,所以你可以放大或缩小,但这里我只展示一张截图
在上面的代码中,key_on
与。json 文件,对于data
,我们感兴趣的数据帧被传递。
Figure 7: Immigration to Canada in the year 1985 from all over the world
按照同样的程序,我们创建了另一个 Choropleth 地图,代表 2005 年来自世界各地的加拿大移民,你可以清楚地看到不同之处。
Figure 8: Same as Figure 7 but now data from year 2005 is used to plot immigration to Canada.
你可以在上面的图表中看到的一个大的缺点是,英国的颜色从 1985 年到 2005 年没有变化,即使我们从数据框中知道在 20 世纪 80 年代移民的数量相当高。问题是,在数据框中,国名是“大不列颠及北爱尔兰联合王国”,而在。json 文件它只是英国。因此,您可以使用“国家/地区名称”列中熊猫数据框内的替换选项—
Canada_df_world_map.Country_Name = Canada_df_world_map.Country_Name.replace({"United Kingdom of Great Britain and Northern Ireland": "United Kingdom"})
Canada_df_world_map.tail(20)
这是一个粗略的替换,因为“英国”和“GRB +北爱尔兰”是不一样的,但我们可以用图来验证我们的理解,让我们看看下面。
Figure 9: Same as figure 7 but now the United Kingdom part is corrected.
好了,终于到了结束这篇文章的时候了,因为它越来越长,但我希望你对有效的数据可视化有一个很好的了解,即如何用一个漂亮的演示来讲述故事。这篇文章涵盖了我在 IBM Coursera 提供的数据可视化课程中学到的大部分基本技术。仅仅回顾一下它有多好,我不得不说实验室是课程中最有效和最有成果的部分,在那里人们可以直接使用课程中教授的所有技术。有时,课程材料包含一些印刷错误,但这些错误会慢慢得到解决。学习绘制华夫饼图表也很棒,但是,我把它留给专门学习这门课程的学生。总的来说,这次经历很有趣,特别是对于在一周内复习一些基础知识来说,这是一个很棒的课程!
通过我的 GitHub 中的完整 Jupyter 笔记本,包括此处使用的数据集,了解更多信息。
在 LinkedIn 上找到我,有时我会在国家地理上发布很酷的照片。
解释机器学习模型
原文:https://towardsdatascience.com/interpreting-machine-learning-model-70fa49d20af1?source=collection_archive---------24-----------------------
第 1 部分—简介
在这一系列的 6 篇文章中,我们将把预测的基础放在一边,看看数据科学和机器学习的更手工的方面,例如解释、获得洞察力和理解算法中发生的事情。这不是一件小事,还远远没有穷尽。在这一系列的帖子中,我们将从最简单的统计模型开始,以及我们如何模拟最复杂的集成和深度学习模型,试图找出预测的原因。
对这一系列内容的初步建议如下:
Part 0—什么是数据科学的范围 Part 1 —解读 ML 简介(本帖) Part 2 —解读高偏倚低方差模型。 第 3 部分——解读低偏差和高方差模型。
第 4 部分——有可能解决偏倚和方差之间的权衡吗?
第 5 部分——可解释性的本地方法。
第 6 部分——可解释性的全局方法。
我们在说什么?
要理解如何解读机器学习算法,我们先来理解什么是机器学习算法。
一般来说,对于我们来说,机器学习算法(以下简称 ML)是从“传统编程”到新概念的范式转变,在传统编程中,我们需要显式地传递所有启发,而不是编写算法必须执行的每个动作,我们只是通过几个例子,让 ML 学习什么是“最佳”(最低成本)决策。
Figure 1 — Paradigm shift from traditional programming to Machine Learning
也就是说,对于我们来说,接收输入并可以转换输出而无需显式编程的算法将是 ML 算法。解释 ML 算法就是理解它们如何将输入转化为输出。
理解预测有多重要?
如果 ML 只是一种以(有时)非常聪明的方式将输入映射到输出的方式,那么理解它是如何做到这一点似乎是一个好主意,对吗?
一个例子:银行欺诈检测算法。
我们绘制一个行为,收集数据,训练一个模型,你就大功告成了!我们有一个非常聪明的方法来检测未来的欺诈行为。现在呢?这个算法在做什么?如果仅仅出于好奇去理解它不再有意义,这里有一些更实际的原因:
Figure 2 — Nature -> Data -> ML -> Predictions
- 这位客户做了什么会被认为是欺诈者?
- 他犯了什么样的欺诈罪?
- 我的算法有偏差吗?
- 我的算法有没有漏洞?
- 如果客户想知道为什么他们的购买被拒绝,我会说是我不懂的算法吗?
- 经理是否想了解模型欺诈者的行为是如何随着时间的推移而变化的?
- 如果我们不是简单地预测,而是对修复安全漏洞以防范未来的欺诈感兴趣,我如何知道哪个杠杆是正确的?
即使在这个非常简单的例子中,我们已经确定了几个理解算法内部工作的好理由。
如果你仍然不相信它的重要性,从欧洲开始有一个非常强大的趋势,公司已经被迫解释做出决定的原因,如拒绝信贷、保险、职位空缺等。很有道理,所以用不了多久,这就会成为使用预测模型时的日常问题。
重要概念:偏差和方差。
有数百个帖子在讨论偏差和方差之间的权衡,这里的目标不是重新解释所有的概念,只是将它们作为下一篇帖子的语言。因此,在没有理论形式的情况下,我们可以将任何模型的预测误差(y-yhat)分成 3 个不同的部分。
Figure 3 — Trade-off between bias and Variance.
y_real - y_hat = Error = Random Part + Bias + Variance
- 随机部分:我们生活在一个随机的世界,而不是十九世纪后期实证主义者所认为的确定性世界。因此,即使是最简单、最明显的模型也仍然具有随机性。即使你的模型是完美的,也不会达到 Error = 0,除非是纯确定性问题。有些问题比其他问题“更随机”。例如,预测行星轨道的模型比预测欺诈的模型具有更小的随机成分。随机部分可以视为上图中的水*线,因为它不依赖于复杂性。
- 方差:对方差的解释,对我们来说,将是一种“波动性”的预测。X 的小变化引起 y 的大变化?- >方差。通常方差误差范围被认为是预测的训练和测试结果之间的差异,但这是一个结果而不是原因。方差随着模型复杂性的增加而增加。
- 偏见:这是我们最重要的一种错误。偏见在不同的上下文中有几种解释。在这里,偏差意味着我们的模型的简化,我们必须为模型的工作做出假设。根据定义,更简单的模型是更扭曲的模型,具有更强的先决条件。偏差随着复杂性的增加而减小。
方法:统计与机器学习
我们在之前的帖子中讨论过,机器学习可能不同于统计学,因为前者涉及推理、因果关系、外生性等。而后者几乎只关心改进预测。因此,我们可以采用相同的功能,例如逻辑回归和统计分析,这将解释 betas 是否显著,浪费是否具有正态分布或机器学习分析,精确度和召回之间的关系如何,模型的 AUC 是多少,等等。
Figure 4 — Funny meme. But wrong.
所以,因为统计学对理解数据感兴趣,你为它创建模型,这些模型需要高度可解释!为了使它们具有可解释性,模型必须简单!但是,如果模型很简单,正如我们所看到的,它们是高度倾斜的。
Figure 5 — Trade-off between prediction quality and model interpretability
ML 模型正好相反,因为我们最初并不关心对它们的解释,它们非常有偏见,在我们的概念中,它们几乎没有先决条件,其代价是缺乏可解释性,这一系列的帖子试图将这两个世界结合在一起。具有高度可解释性的高指标。
Figure 6 — Evolution from Statistical algorithms to Machine Learning algorithms.
一个简单的例子是线性回归,这是最古老和最简单的算法之一,可解释性强,方差非常低(我们在测试训练中几乎不需要分离数据),但有很大的偏差。由于此处的偏差是为使模型工作良好而进行的简化,低于使用此方法的一些
前要求:
- 输入变量需要是外生的,所以不理解变量之间的交互作用;
- X 和 y 之间的影响需要是恒定的(因此线性名称);
- y 分布需要“表现良好”。
我们将在下一篇文章中探讨这些和其他先决条件,以及如何解释它们。
一种新的算法分类方法。
综合起来,让我们用一个新的术语来描述这种分离/分类 ML 算法的新方式。一方面,我们有最传统的算法,诞生于统计学和计量经济学,有一些工作的先决条件和高度可解释性,没有它们就没有现代科学,它们的解释是数据科学的科学特征,是“白盒”算法。
在另一个极端,我们有那些我们知道工作得很好的 ML 算法,因为它们的度量很好,它们可以同时处理数百万个变量,它们可以在更小的维度上表示复杂的向量空间,只有很少的先决条件(低偏差),
甚至可以生成图像和文本,代价是我们无法控制他在里面做什么,我们将这些算法称为“黑盒”。
Figure 7 — Representing the different data scientist tools, more interpretable or more predictive, depending on the purpose.
在接下来的文章中,我们的目标将是结合这两个极端的优点,高解释能力和高预测能力。
下一篇文章:第二部分——解读高偏差和低方差模型。
LinkedIn;GitHub;播放列表;版本 pt-br;
如何解读机器学习模型?
原文:https://towardsdatascience.com/interpreting-machine-learning-models-c7646393c270?source=collection_archive---------13-----------------------
我们能理解机器学习模型内部到底发生了什么吗?
Source: Photo by Jeremy Thomas on Unsplash
在我之前的博客中,我谈到了模型性能和可解释性之间的权衡。通常,你会观察到商业利益相关者更喜欢不太精确但高度可解释的线性模型,因为它易于解释。但作为一名数据科学家,你知道在现实世界中,由于固有的高维数和特征之间复杂的非线性关系,非线性和复杂的模型总是更稳健和可靠。所以在一个理想的世界里,每个人都想在神圣的网格里,在那里你可以得到最高的模型性能和高度可解释的结果。
在这篇博客中,我简要地提到了我在项目中使用的一些技术,这些技术增加了可解释性,并解决了高模型性能和高可解释性之间的权衡问题。
Source: https://xkcd.com/1838/
以下是我用来增加模式可解释性的方法:
1.特征重要性:预测模型对特定特征的依赖程度?
2.部分相关图:特定特征如何影响模型预测?
3.Shap:哪些变量导致了这个预测?
4.莱姆:是哪些变量导致了这种预测?
为了解释上述方法,我使用了来自印度开放政府数据(OGD)*台——https://data.gov.in/——的教育部门的数据集,该*台支持印度政府的开放数据倡议。这一数据包括辍学率、有电的学校百分比、计算机设施、厕所等。印度所有的邦。出于好奇,我想测试小学的辍学率是否与学校的设施有关。因此,我使用辍学率作为 y 变量(目标),其他指标作为独立特征。
1。 特征重要性:
基尼系数重要性或*均减少杂质
对于分类问题,Scikit-learn 默认使用 Gini 杂质来计算特征重要性。特征重要性被称为“基尼重要性”或“*均减少杂质”。它被定义为集合中所有树的*均节点杂质的总减少量。通过到达特定节点的概率(在到达该节点的样本的总比例之外)对节点杂质的总减少进行加权。简而言之,这确保了如果“*均减少杂质”对于 2 个变量是相同的,但是变量 1 在树的顶部,而另一个在深度 5,那么变量 1 将变得更重要,因为与深度 5 的节点相比,它更容易到达该节点。因此,特性的值越高,它就越重要。最后,通过除以所有要素重要性值的总和,将要素重要性归一化到 0 和 1 之间。
下面是上述案例研究中的特征重要性图。
这表明,在印度各邦,小学辍学率受供电、供水和厕所设施的影响最大,而不是受电脑的影响。
排列重要性
置换重要性是计算特征重要性的替代方法,可用于任何模型。它基本上是一次一个特征,所有其他特征和目标保持不变。然后检查这如何影响重组数据中模型预测的准确性。因此,对于对预测影响最大的列,模型性能会降低。
在上表中,最重要的功能按重要性从高到低排列。权重列测量随机洗牌后模型性能(准确性)下降的程度。正如你所看到的,这两种方法中顶层变量的顺序是相同的,但这可能并不总是正确的。
2。 部分依赖情节(PDP)
现在,特性重要性帮助我们解决了这个难题的一部分。但是为了知道每个变量如何影响预测,我们可以分析部分相关图。这可以帮助我们识别目标和特征之间的关系是线性的、单调的还是更复杂的。
在这种方法中,我们一次改变一个变量的值,其他特征和目标保持不变。有了这个我们就可以理解预测的结果是如何随着特定变量的变化而变化的。PDP 的逻辑非常简单,对于感兴趣的特征,它基本上在数据集中的所有数据点上强制一个单一值,然后在所有数据点上*均预测。对特定特性的所有值重复此练习。
向下倾斜的图表表明,随着通电学校百分比的增加,辍学率与该特征的最小值相比有所下降。图表中的*坦区域表明,在这些区域中,%电力的增加不会导致辍学率%的任何变化。PDP 总是相对于特性的最小值进行测量,因此 y 轴上最左侧的点总是为零。蓝色区域表示不确定性。
您只需确保您正在分析的 PDP 的特征与数据集中的其他特征没有高度相关性。例如,在我们的数据集中,如果%有电的学校与%有电脑的学校呈正相关,那么当我们计算 PDP 时,将会有记录显示这两个特征的组合在现实中不太可能发生。如果在您的情况下,特征之间的相关性很高,那么您可以查找边际图和累积局部效应(ALE)图。
我将在接下来的博客中写关于莱姆和 SHAP 的内容。
请在评论中告诉我你对这个博客的想法。此外,我想知道您是否已经开发了来自印度开放政府数据(OGD)*台的案例研究。
这些内容最初发表在我的个人博客网站:http://datascienceninja.com/。点击此处查看并订阅即时接收最新博客更新。
解释多元时间序列上的递归神经网络
原文:https://towardsdatascience.com/interpreting-recurrent-neural-networks-on-multivariate-time-series-ebec0edb8f5a?source=collection_archive---------4-----------------------
如何从多元时间序列上训练的复杂深度学习模型中获得理论上合理的解释
Photo by João Silas on Unsplash
什么
在本文中,我们将探索一种最先进的机器学习可解释性方法,并使其适应多元时间序列数据,这是一种以前没有准备好的用例。你会发现对核心概念的解释,它们是什么,它们是如何工作的,以及后面的例子。我们还将讨论提议的解决方案背后的主要思想,以及实例重要性的可视化建议。
为什么
这不再只是炒作,机器学习正在成为我们生活中重要的一部分。当然,那里没有任何有感知能力的机器,也没有斯嘉丽·约翰逊的爱耳者(对她的大声喊出来),但是这些算法的进化是不可否认的。他们可以开车,帮助医疗预测,预测股票,玩专业水*的视频游戏,甚至产生旋律或图像!但是这些机器学习模型不是完美无缺的,也不是万无一失的。它们甚至会产生误导,在与训练数据非常不同的样本中显示不正确的概率(我建议看看克里斯蒂安·佩罗尼关于不确定性的演讲 [1】)。因此,特别是在诊断病人或决定公司战略等关键应用中,至少对模型如何得到其输出值有一些了解是很重要的,这样用户就可以确认它是否可信。此外,在高性能模型与适当解释相结合的情况下,它可能会导致令人惊讶的发现,如疾病诊断中的基因或一年中某个时间对销售的影响。
We are not quite there yet in AI. GIF by the awesome Simone Giertz.
因此,将可解释性技术应用于所有机器学习是显而易见的,对吗?差不多吧。虽然线性回归和决策树等更简单的模型易于分析,但神经网络等更复杂的模型却无法自圆其说,尤其是在数据和参数维数较高的情况下。有人建议改变一些架构,使神经网络更容易解释,例如注意力权重。然而,这些方法不仅需要增加参数的数量和改变模型的行为(这可能会恶化其性能),它们可能不会给我们完整的画面(注意力权重仅指示每个特征的相对重要性,而不是它是否积极或消极地影响了输出)。因此,在性能和可解释性之间有一个权衡,为了能够解释模型,它必须足够简单或以某种方式特别适应,这限制了它的潜力。
幸运的是,基于扰动的方法的研究一直在增长,这是一种可解释性技术,应用输入数据的变化(即扰动)来计算重要性分数,通常不需要特定的模型架构。这意味着这些方法可以是模型不可知的,使得每一个可能的模型都是可解释的,从而消除了性能/可解释性的权衡(尽管有一些警告,我们将在后面讨论)。所以,让我们来看看现代基于扰动的可解释性技术背后的一些主要概念。
沙普利值
它们是什么?
Shapley values 是一个来自博弈论的概念,由 Lloyd Shapley 于 1953 年首先提出(我知道我说的是“现代”,但在这里请原谅我),它定义了一种计算合作博弈中每个玩家贡献的方法。这一切都归结为一个等式。考虑总共有 N 个玩家, i 我们正在计算其贡献的玩家,φI 玩家 i 的贡献, S 不包括 i 的玩家子集(其中 |S| 表示子集 S 中的玩家数量)以及 v 输出总数的函数为了计算玩家 i 的贡献,我们计算以下等式:
Shapley values equation.
换句话说,每个玩家的贡献由该玩家在所有可能的玩家组合上的边际贡献的加权*均值决定。注意,我说的组合是指博弈中的一部分参与者,不考虑他们的顺序,边际贡献是指在当前的组合中,当特定的参与者加入时,收益是如何变化的。既然我们已经理解了边际贡献部分,那么左边还有一些乱七八糟的东西。这些看似复杂的权重实际上可以产生 Shapley 值方程的简单等效版本:
Equivalent Shapley values equation.
在这个等式中,我们遍历所有可能的排列( R )玩家的完整列表,而不是仅仅使用唯一的边际贡献。注意,我说的排列是指玩家加入的顺序(例如,玩家 1 开始游戏,然后玩家 2 加入,接着玩家 3 加入,等等)。在这种情况下,它现在有了符号 PiR (不好意思,真的不能用中等文本的方程式形式来写),代表所有出现在 i 之前的选手,按当前顺序 R 。这种等价意味着权重的设置要考虑到一个独特的边际贡献在所有可能的玩家顺序中出现的次数。此外,这些权重的定义方式允许 Shapley 值满足一组属性,这些属性确保公*、真实地分配球员的贡献。为了保持这篇文章的合理简短,我不打算在这里列出它们,但是如果你想知道更多,你可以查看 Christoph Molnar 的可解释机器学习书籍。
例子
为了说明这一点,作为一个足球迷,想象以下场景:
假设我们有三名前锋(即在场上踢前锋的球员,主要目标是尽可能多地进球或助攻)。姑且称之为 B 、 L 、 V 。设 G 是这样一个函数,对于比赛中的一组前锋,输出该队进了多少球。记住这一点,想象当每组球员都在场上时,我们有以下得分目标:
我认为在这场比赛中,所有球员最终都会上场,这只是每个人何时上场的问题(从首发阵容开始,或者加入第一或第二替补)。因此,我们有 6 种他们参与游戏的可能场景,我们需要计算边际贡献:
作为实现 Shapley 值的最后一步,我们只需要对每个玩家应用 Shapley 值等式之一(唯一边际贡献的加权*均值或所有订单边际贡献的*均值):
请注意,我是如何通过我之前展示的两个方程来计算 Shapley 值的,两个方程导致了相同的结果。此外,由于该方法的一个性质(效率),所有 Shapley 值的总和等于大联盟的收益,即当所有参与者都在游戏中时的收益, G(B,L,V) 。
那又怎样?
现在,我不是想通过解释一个不相关的 50 年代的理论来和你玩游戏。你看,如果我们用“特征值”代替“参与者”,用“模型输出”代替“收益”,我们就有了一个可解释性的方法。要让这在机器学习的可解释性中有用,我们只需要解决两个问题:
- 我们如何使这种方法更快(记住,在它的原始形式中,它需要在我们想要解释的每个样本上迭代所有可能的特征组合)。
- 我们如何表现一个缺失的特性(在游戏理论中,消除一个特性的影响比忽略一个玩家更复杂;在大多数机器学习模型中,所有的特征必须总是有一些值,所以我们需要找到一种方法来降低一个特征的影响,同时仍然通过模型传递它)。
SHAP
这是什么?
2017 年,Scott Lundberg 和 Su-In Lee 发表了论文“解释模型预测的统一方法”【3】。顾名思义,他们提出了一种新的方法来解释机器学习模型,统一了以前的模型。他们发现,其他 7 种流行的可解释性方法(LIME、Shapley 采样值、DeepLIFT、QII、逐层相关性传播、Shapley 回归值和树解释器)都遵循相同的核心逻辑:通过局部线性模型从原始模型学习更简单的解释模型。正因为如此,作者称之为加性特征归因法。
这个局部线性模型魔术是什么?本质上,对于我们想要解释的每个样本 x ,使用模型 f 的输出,我们训练一个线性模型 g ,它在样本 x 上局部逼* f 。然而,线性模型 g 并不直接使用 x 作为输入数据。相反,它将其转换为 x' ,表示哪些功能被激活(例如, x'i = 1 表示我们正在使用功能 i ,而 x'i = 0 表示我们正在“移除”功能 i ),这与选择玩家组合的情况非常相似。这样,考虑到我们有 M 个特征和 M+1 个模型系数(名为 φ ,我们得到解释器模型的如下等式:
Additive feature attribution methods’ general equation.
并且,由于具有将x’转换为 x 的映射函数 hx ,所以每当我们接*x’(即z’≈x’)时,解释器模型应该通过遵守以下规则来局部逼*模型 f :
Local approximation of the interpreter model, in additive feature attribution methods.
知道我们想要自然解释的样本 x 具有所有可用的特征(换句话说,x’是所有 1 的向量),这种局部*似规定所有 φ 的总和应该等于样本 x 的模型输出:
The sum of the linear interpreter model’s coefficients should equal the original model’s output on the current sample.
这些方程都很有趣,但现在呢?诀窍在于这些 φ 系数代表什么以及它们是如何计算的。每个系数 φ ,这是一个线性模型,与模型上每个特征的重要性相关。例如, φi 的绝对值越大,特征 I 在模型上的重要性就越大。自然地, φ 的符号也是相关的,因为正的 φ 对应于对模型输出的积极影响(输出值增加),而负的 φ 则相反。这里的一个例外是 φ0 。没有功能 0,因此它不与任何特定的功能相关联。事实上,如果我们有一个全零向量z’作为输入,解释器模型的输出将是 g(0) = φ0 。理论上,它应该对应于不存在特征时模型的输出。实际上,SHAP 所做的是 φ0 假设所有数据的*均模型输出,因此在添加每个特征的影响之前,它代表模型的一种起点形式。因此,我们可以将每个剩余系数视为每个特征将基本输出值( φ 0)推至更大或更小的输出(取决于系数的符号),所有这些特征相关系数的总和导致当前样本的输出与*均输出值之间的差异。这个特性允许我们用 SHAP 软件包创建有趣的力图,正如你在下面的例子中看到的,一个模型预测一个足球队是否有一名球员赢得最佳球员奖。要了解这个例子的更多信息,请查看卡格尔关于 SHAP 价值观的教程。
Example of a force plot made with SHAP, on a model that predicts if a football team has a player win the Man of the Match award. The base value represents the model’s average output on all the data while each bar corresponds to a feature’s importance value. The color of the bar indicates its effect on the output (red is positive and blue is negative) and its size relates to the magnitude of that effect.
理想的性能
φ 系数还有一个有趣的方面。对于除了 φ0 之外的所有人,这同样不对应于任何单个特征的重要性,作者认为只有一个公式可以同时实现三个期望的属性:
1:本地精度
当对特定输入 x *似原始模型 f 时,局部精度要求解释模型至少与原始输入 x 的 f 的输出相匹配。
SHAP’s local accuracy property.
2:思念
如果简化输入(x’)表示特征存在,那么遗漏要求原始输入中遗漏的特征没有影响。
SHAP’s missingness property.
3:一致性
设FX(z ')= f(hx(z ')】和 z' \ i 表示设置 z'i = 0 。对于任意两个型号 f 和f’,如果
SHAP’s consistency property.
对于所有输入 z' ∈ {0,1}^M ,则 φ(f ',x) ≥ φ(f,x) 。
满足这三个特性的公式是……做好准备,迎接似曾相识的感觉……
Drumroll please.
Defended by the SHAP paper authors as the only formula for coefficients φ which obeys to the desirable properties of local accuracy, missingness, and consistency.
看着眼熟?本质上,它是 Shapley 值公式,适用于这个二进制值的世界。以前我们有由 S 代表的玩家组合,现在我们有由z’代表的激活特征组合。权重和边际贡献仍然存在。这不是巧合,这些系数被称为 SHAP 值,其中 SHAP 代表沙普利加法解释。
效率
从 SHAP 值的定义出发,我们仍然有同样的两个问题要解决:效率和如何表示缺失的值。这两个问题都是通过对缺失特征的采样和期望来解决的。也就是说,我们固定正在使用的特征的值(那些具有 z' = 1 的特征,其值对应于 zs 的特征),然后在固定次数的迭代中,通过样本值对剩余的、移除的特征(那些具有 z' = 0 ,其值对应于zs‖的特征)进行积分。通过检查停用特征的几个不同值并获得它们的*均值,我们正在减少这些特征对输出的影响。我们也加快了过程,因为我们不需要经历每一个可能的迭代。
Expectation done in SHAP. It assumes feature independence and model linearity locally.
知道了这种对随机样本整合的需求,我们需要在每次运行 SHAP 时定义两组数据:
- 背景数据:SHAP 从中抽取随机样本来填充缺失特征的集合。
- 测试数据:包含我们要解释其预测的样本的集合。
SHAP 还通过对重要性值应用正则化来加速该过程。换句话说,一些低重要性要素将假定 SHAP 值为 0。此外,考虑到与其他可解释性技术的统一,SHAP 实现了具有特定模型优化的各种版本,如用于深度神经网络的深度解释器,以及用于决策树和随机森林的树解释器。
除了这种方法和优化的统一,SHAP 还准备使用可视化,如之前显示的力图、依赖贡献图和汇总图,如以下相同的足球示例所示。
SHAP summary plot for the example of prediction of whether a football team has a player win the Man of the Match award. Features are ranked from descending average SHAP value from top to bottom and different samples are shown, with how the feature’s value (represented by the color) impacted the output (X axis).
我们到了吗?
我知道你现在的感受:
When you find out about SHAP.
考虑到 SHAP 有充分根据的理论及其 python 实现的实用性,你有理由这么做。但是,不幸的是,仍然存在一些问题:
- SHAP 的开发重点是张量流。因此,在撰写本文时,与 PyTorch 的完全兼容性尚未得到保证,尤其是在深度解释器和梯度解释器的深度学习优化变体中。
- 在撰写本文时,SHAP还不能很好地适应多元时间序列数据。例如,如果您现在使用 SHAP 的任何解释器模型对这种类型的数据进行测试,您将会看到要素的 SHAP 值加起来是奇怪的数字,不符合局部精度属性。
但是不要绝望。我已经找到了一个解决这个问题的方法,接下来我们将讨论这个方法。
内核解释器来解释它们
它是如何工作的
正如我提到的,SHAP 有多个版本的解释器模型,基于它统一的其他可解释性方法。其中一个是内核解释器,它基于流行的石灰【6】。它有一些明显的相似之处,例如使用局部*似原始模型的线性模型作为解释器,并使用简化的输入x’,其中值 1 对应于正在使用的特性的原始值,值 0 表示特性缺失。此外,LIME 和它的 SHAP 对应物(内核解释器)不假设任何特定的模型组件或特征,例如决策树或梯度的反向传播,这使它们完全与模型无关。主要区别在于线性模型的损失函数。虽然 LIME 启发式地定义了损失函数、其相关的加权核和正则化项,但 SHAP 论文的作者认为这破坏了局部精度和/或一致性属性,SHAP 的核解释器使用以下固定参数目标函数:
Objective function minimized by the SHAP Kernel Explainer to train its linear regression model.
这里*方损失是足够的,因为我们希望 g 尽可能接* f 。关于加权核,查看这些参数有效性的一种方式是,当:
- |z'| = 0 ,强制φ0 = f(φ)
- |z'| = M ,迫使∈φI[I = 0,…,M] = f(x )
这些参数不仅通过保证符合三个期望的性质而提供了优于石灰的优势,而且通过线性回归的所有 SHAP 值的联合估计给出了比经典 Shapley 方程更好的样本效率。
由于我们正在训练一个线性回归模型,除了设置要解释的数据和 SHAP 从中获取随机样本的背景数据之外,唯一需要定义的主要参数是解释每个预测时重新评估模型的次数(在 python 代码中称为nsamples
)。与其他机器学习模型一样,重要的是要有足够多的训练迭代次数,以便通过不同的训练会话获得拟合良好且方差较低的模型。请记住,在这种情况下,我们不需要担心过度拟合,因为我们真的只是想解释特定样本上的模型,而不是事后对其他数据使用结果解释器,所以我们真的希望大量的模型重新评估。
An example animation illustrating how SHAP Kernel Explainer works, in a simplified way. The interpreter g(z’) updates its coefficients, the SHAP values, along the combinations of z’, being reset when the sample x changes. Note that, in real life, more reevaluations (i.e. training iterations) should be done on each interpreter model.
这个内核解释器方法自然有一个缺点。由于我们需要对我们想要解释的每个预测训练一个线性回归模型,使用几次迭代来训练每个模型,并且没有特定的模型类型优化(例如 Deep Explainer 和 Tree explainer),内核解释器运行起来可能非常慢。这完全取决于您想要解释多少数据、从多少背景数据中采样、迭代次数(nsamples
)和您的计算设置,但是计算 SHAP 值可能需要几个小时。
简而言之,如果内核解释器是一个迷因,它应该是这样的:
Hey, just because sloths are slow doesn’t mean they aren’t awesome. Meme by my procrastinating self.
多元时间序列修正(又名时间旅行树懒)
由于内核解释器应该在所有模型上工作,只需要一个预测函数来进行解释,我们可以尝试用一个在多变量时间序列数据上训练的递归神经网络(RNN)来进行解释。你也可以通过我做的【7】的简易笔记本自己试试。在那里,我创建了以下虚拟数据集:
Dummy multivariate time series dataset used in the example notebook [7].
本质上,你可以把它想象成一个健康数据集,病人由subject_id
识别,他们的临床访问由 ts 识别。标签可能表明他们是否患有某种疾病,从 0 到 3 的变量可能是症状。注意Var3
和Var2
是如何被设计成特别有影响力的,因为当它们低于一定水*时,标签通常会被激活。Var0
紧随其后,但影响较小,最后Var1
基本上是随机的。我还包含了一个“输出”列,它指示了被训练的 RNN 模型标记为 1 的预测概率。如您所见,一般来说,它在预测标签方面做得很好,在训练(3 名患者)和测试(1 名患者)集上的 AUC 分别为 0.96 和 1。
对于 SHAP 内核解释器将使用的预测函数,我只需要确保数据是浮点型 PyTorch 张量,并设置模型的前馈方法:
Model’s prediction method used in the current SHAP Kernel Explainer example.
由于它是一个小数据集,我将背景和测试集都定义为整个数据集。对于较大的数据集,这是不推荐的,因为由于内核解释器的缓慢,您将希望使用一小部分数据作为您想要解释的样本,并且避免在后台和测试集中有相同的数据。
然而,当我们将 SHAP 系数的结果总和与输出进行比较时,它们并不完全匹配,违反了局部精度公理:
Example of subject 0’s real model output and the sum of SHAP coefficients, in the original SHAP code.
为什么会这样?这个版本的 SHAP 不是应该可以演绎各种模型吗?嗯,问题的一部分是,看代码,你会看到 SHAP 期望表格数据。文档中甚至有一条注释提到了对 2D 数据的需求:
X : numpy.array 或者熊猫。DataFrame 或任何 scipy.sparse 矩阵
一个样本矩阵(# samples x # features),用于解释模型的
输出。
在我们的例子中,数据是三维的(#样本 x #时间戳 x #特征)。如果我们使用一个更简单的模型,一个仅使用单个实例来预测标签的模型,这仍然是好的。但是,当我们使用 RNN 时,它会在隐藏状态下从以前的实例中积累内存,它会将样本视为单个实例的单独序列,从而消除了模型内存的使用。为了解决这个问题,我不得不修改 SHAP 内核解释器代码,使其包含解释多元序列递归模型的选项。还需要更微妙的变化,但核心的增加是代码的这一部分:
Core addition to the SHAP Kernel Explainer to make it compatible with multivariate time series data and RNNs.
正如你所看到的,只有当我们之前检测到模型是一个递归神经网络时,才会执行该代码,它会单独循环通过每个主题/序列,并通过模型的隐藏状态,即当前序列中之前实例的内存。
经过这些改变后,我们现在可以进入同一个例子,看到 SHAP 系数的总和正确匹配实际输出!
Example of subject 0’s real model output and the sum of SHAP coefficients, in the modified SHAP code.
现在,如果我们查看摘要条形图,我们可以看到功能重要性的总体排名:
Average SHAP values (feature importance) on the dummy dataset, using all the data as background data.
看起来不错!Var2
和Var3
被正确识别为最重要的特征,其次是不太相关的Var0
和不太重要的Var1
。让我们来看一个病人 0 的时间序列的例子,以确认它是否,事实上,很好地解释了个人预测:
Feature importance along the dummy dataset subject 0’s time series. The border between the red shade (output increasing features) and the blue shade (output decreasing features) represents the model’s output for each timestamp.
我们的数据集验证了这一点,因为最初,当Var2
和Var3
具有高值时,它会降低输出,而在最后阶段,随着Var2
和Var3
降低,输出会增加。我们可以通过获得时间戳 3 的力图来进一步确认这一点,其中输出概率上升到 50%以上:
Force plot of the feature importance, for the same dummy dataset subject 0, on timestamp 3. The size of each feature value’s block corresponds to its contribution.
我们真的需要所有的背景数据吗?
由于 SHAP 内核解释器并不是真的快(不要逃避自己,如果你运行前一个笔记本,它的速度很快,因为数据集非常非常小),我们应该考虑每一个机会使它更快。自然地,当训练解释器模型时,该过程的计算量大的部分是通过来自背景数据的样本的多个组合的迭代。因此,如果我们能减少样本数量,我们就能得到加速。现在想一想:我们可以用一个参考值来表示缺失的特性吗?如果有,会是什么?
Thinking about that reference value.
我想说,甚至 SHAP 论文中给出的一个公式也给了我们一个提示(这篇文章“SHAP”部分前面“效率”小节中的那个)。如果我们对样本进行积分以获得缺失特征的期望值,为什么不直接使用这些特征的*均值作为参考值呢?如果在预处理阶段,我们将数据标准化为 z 分数,这就更容易做到了。这样,我们只需要使用全零向量作为唯一的背景样本,因为零代表每个特征的*均值。
z-scores equation, where data x is subtracted by its mean μ and then divided by the standard deviation σ.
仅用零参考值而不是所有以前的背景数据重新运行内核解释器,我们得到下面的摘要条形图:
Average SHAP values (feature importance) on the dummy dataset, using just an all zeroes sample as background data.
我们得到了与使用所有数据集作为背景数据的情况相似的结果!功能重要性的排名略有不同,Var3
略微超过Var2
成为最相关的功能,而Var1
的重要性更高,尽管它仍然是最不相关的。除了这些差异之外,它实际上很有趣,因为我打算将Var3
作为最重要的特性。你也可以在笔记本中查看更详细的时间序列和力图,但它们也接*我们之前得到的。
规模,规模,规模
当然,前面的例子使用了一个不切实际的小玩具数据集,只是因为实验很快,我们确切地知道会发生什么。我还在研究一个真实的健康数据集,涉及 1000 多名 ALS 确诊患者的体检。不幸的是,由于这个数据集不是公开的,我不能分享它,也不能将它合并到一个打开的笔记本中以使结果可重复。但是我可以和你分享一些初步的结果。
为了给出一些背景,我训练了一个 LSTM 模型(一种递归神经网络),以预测患者在未来 3 个月内是否需要无创通气,这是一种常见的程序,主要在呼吸系统症状恶化时进行。
在这个模型上运行修改后的 SHAP 内核解释器会给我们带来以下可视化效果:
Average feature importance for the ALS dataset.
Feature importance along an ALS patient’s time series. The border between the red shade (output increasing features) and the blue shade (output decreasing features) represents the model’s output for each timestamp.
Force plot of the feature importance, for the same ALS patient, on timestamp 9. The size of each feature value’s block corresponds to its contribution.
这里有一些有趣的注释:
- 7 个最重要的特征,按重要性排序,都与呼吸系统症状有关,尤其是来自医生进行的呼吸系统评估的
3r
和p10
。 - 疾病持续时间、性别和年龄也是最重要的特征,这似乎是有意义的。
- 我们现在看到一个更详细的时间序列可视化,显示了更多的功能。同样相关的是,由于正则化,我们只看到了数据集中总共 47 个要素中最有影响力的 20 个要素。
这种解释是对 183 名患者的时间序列进行的,最大序列长度为 20,使用 0 作为参考值。我在 C7 机器(12 个 CPU 内核,30GB 内存)上运行了paper space【8】中的代码。完成大约花了 5 个小时,而使用 50 个背景样本的替代方案估计需要 27 个小时。现在你相信我说的慢了吧?至少我们的参考值技巧仍然能够提高运行时间。
好了,现在我们需要的都有了。对吗?
虽然看起来我们得到了快乐的结局,但这里仍然有一些东西。这篇文章是关于解释多元时间序列数据的模型,但是我们只讨论了特征重要性分数。我们如何知道哪些实例/时间戳最相关?换句话说,我们如何知道实例重要性分数?不幸的是,目前 SHAP 还没有内置的多元序列数据。为此,我们需要想出自己的解决方案。
错误 404:找不到实例重要性
正如我们所讨论的,SHAP 主要是为处理 2D 数据而设计的(#样本 x #特性)。我向您展示了代码中的一个变化,它允许单独考虑不同序列的特性,但这是一个变通办法,只能导致特性的重要性,而不能从整体上解释实例的相关性。人们仍然会想,是否有可能再次应用 SHAP,愚弄它,让它把实例当作特征。然而,这可行吗,甚至有意义吗?首先,我们已经有了使用 SHAP 来确定特征重要性的缓慢过程,因此再次应用它来获得实例重要性可能会使整个解释管道变得不切实际地缓慢。然后,考虑到 SHAP 是如何通过遍历功能子集的组合,删除剩余的功能(在这种情况下,删除实例),这似乎是不现实的。在时间动态相关的真实世界数据中,我认为考虑时间事件之间存在多个间隙的合成样本没有意义。考虑到所有这些,在我看来,我们应该寻求一个更简单的解决方案。
最初的方法是相当自然的:删除我们想要获得重要性分数的实例,然后看看它如何影响最终的输出。为此,我们用没有相应实例的序列的输出减去原始输出,从而得到一个分数,该分数的符号指示该实例向哪个方向推动输出(如果新的输出具有较低的值,则意味着该实例具有积极的影响;对于较高的值反之亦然)。我们可以称之为遮挡分数,因为我们正在遮挡序列中的一个实例。
Occlusion score determined by the effect of instance i on the final output. N is the index of the last instance of the sequence and S is the set of instances in the sequence.
虽然有道理,但可能还不够。当随着时间的推移跟踪某事时,例如患者的疾病进展,往往会有某些时刻发生一些新的事情,这些事情可能会产生影响或在随后的事件中重复。例如,如果我们预测症状恶化的概率,我们可以有一个病人,开始时病得很重,但在成功治疗后,完全治愈,再次生病的概率几乎为零。如果我们只应用前面的实例封闭方法,那么治疗后患者的所有实例都可以得到相似的分数,尽管很明显,他接受治疗的时刻实际上是关键时刻。为了解决这个问题,我们可以考虑实例带来的输出中的变化。也就是说,我们将正在分析的实例的输出与其之前的实例进行比较,就像我们在计算导数一样。
Output variation score calculated through the derivative in the output caused by instance i. S is the set of instances in the sequence.
当然,遮挡分数在许多场景中可能仍然是相关的,所以理想的解决方案是将两个分数组合成一个加权和。考虑到遮挡的更直接的方法和一些经验分析,我选择遮挡的权重为 0.7,输出变化的权重为 0.3。由于输出中的这些变化可能有些小,通常不超过输出中 25 个百分点的变化,我认为我们还应该对结果应用非线性函数,以便放大高分。为此,我选择了 tanh 函数,因为它将所有内容保持在-1 到 1 的范围内,并在内部添加了乘数 4,因此输出中 25 个百分点的变化非常接*最大值 1。
Instance importance score, calculated through a tanh activation on a weighted sum of the occlusion score and the output variation score.
尽管结合了两个分数和非线性函数的应用,解决方案仍然简单而快速。作为比较,将这种方法应用于相同的 183 个患者数据和与前面的特征重要性示例相同的计算设置,这种需要大约 1 分钟来运行,而特征重要性需要 5 个小时。
有了这个实例重要性公式,我们可以可视化分数,即使是同时在多个序列中。受 Bum Chul Kwon 等人的论文“retain vis:Visual Analytics with interpretatable and Interactive Recurrent Neural Networks on Electronic Medical Records”[9】的启发,我一直在研究您在下面看到的时间序列图,其中每一行都对应于一个序列(在我的例子中,是一个患者的时间序列),实例由圆圈表示,圆圈的颜色表示其重要性(强度表示分数大小,颜色表示符号),我们还可以添加简单的预测表,这让我们了解最终的输出值。
Example of visualizing instance importance on multiple sequences, along with their final probability.
请注意,患者 125 与 ALS 示例中的特征重要性相同。它充分表明时间戳 9 是一个相关的、输出增加的实例,而时间戳 10 减少了该输出值。
即使我希望你喜欢我提出的逻辑和情节,例如重要性,我还没有准备好与你分享这段代码,因为它仍然需要微调。作为我硕士论文的一部分,我正在创建一个名为 Model Interpreter 的 API,它包含了我们在这里讨论过的现成实现(多元时间序列的 SHAP、实例重要性分数和绘图)等等。我希望能够在 GitHub 上公开到 10 月份。同时,请随意探索这些主题,并做自己的实验!还记得我的 SHAP修改版【10】是公开的,所以你已经可以使用它了。
最后的想法
如果有什么你应该从这篇文章中学到的,即使你只是浏览了图片和迷因,那就是这个:
虽然它仍然很慢,但提出的修改后的 SHAP 可以解释任何模型,即使是在多元时间序列数据上训练的模型,也具有确保公*解释和实现直观理解的可视化的理想属性;尽管软件包中仍然缺少实例重要性计算和绘图。
在机器学习可解释性方面还有工作要做。效率和易用性需要解决,总有改进的空间,以及替代方案的建议。例如,SHAP 仍然有一些假设,像模型的特征独立性和局部线性化,这可能并不总是正确的。然而,我认为我们已经从 SHAP 强有力的理论原则及其实施中有了一个良好的起点。我们终于到达了一个时代,我们不仅可以从复杂的算法中得到结果,还可以问他们为什么,并得到一个现实的,完整的回答。
No more black box models refusing to give answers.
参考
[1] C .佩罗尼,深度学习中的不确定性估计 (2019),PyData Lisbon 2019 年 7 月
[2] C .莫尔纳尔,可解释机器学习 (2019),克里斯托夫·莫尔纳尔的网页
[3] S. Lundberg 和 S. Lee,(2017),NIPS 2017
[4] S. Lundberg, SHAP python 包 (2019),GitHub
[5] D. Becker, Kaggle 的 SHAP 价值观教程 (2019),Kaggle
[6] M. Ribeiro 等人,“我为什么要相信你?”:解释任何分类器的预测 (2016),CoRR
[7] A. Ferreira, GitHub 知识库,简单演示了 SHAP 在虚拟多元时间序列数据集上的表现 (2019),GitHub
[8] Paperspace 云计算服务
[9] B. Chul Kwon 等人, RetainVis:在电子病历上使用可解释和交互式递归神经网络的视觉分析 (2018),IEEE VIS 2018
[10] A .费雷拉,修正的 SHAP,兼容多元时间序列数据 (2019),GitHub
[11] R .阿斯特利,革命性的新人工智能区块链物联网技术 (2009),YouTube
解释线性回归的系数
原文:https://towardsdatascience.com/interpreting-the-coefficients-of-linear-regression-cc31d4c6f235?source=collection_archive---------9-----------------------
Source: Unsplash
学习如何正确解释线性回归的结果——包括变量转换的情况
如今,有太多的机器学习算法可供我们尝试,以找到最适合我们特定问题的算法。一些算法有明确的解释,其他的作为黑盒工作,我们可以使用诸如石灰或 SHAP 的方法来导出一些解释。
在本文中,我将重点解释最基本的回归模型的系数,即 线性回归 ,包括因变量/自变量被转换的情况(这里我说的是对数转换)。
1.水*水*模型
The basic form of linear regression (without the residuals)
我假设读者熟悉线性回归(如果不熟悉的话,有很多好文章和中等帖子),所以我将只关注系数的解释。
线性回归的基本公式可以在上面看到(为了简单明了,我故意省略了残差)。公式中, y 为因变量, x 为自变量。为了简单起见,让我们假设它是单变量回归,但这些原则显然也适用于多变量情况。
为了客观地看待这个问题,假设在拟合我们收到的模型之后:
拦截(一)
我将把截取的解释分成两种情况:
- x 连续且居中(从每次观察中减去 x 的*均值,变换后的 x 的*均值为 0) —当 x 等于样本*均值时,*均值 y 为 3
- x 连续,但不居中——当 x = 0 时,*均值 y 为 3
- x 是分类的——当 x = 0 时,*均值 y 是 3(这一次表示一个类别,下面将详细介绍)
系数(b)
- x 是一个连续变量
解释: x 增加一个单位导致*均 y 增加 5 个单位,所有其他变量保持不变。
- x 是一个分类变量
这需要更多的解释。假设 x 描述性别,可以取值('男性','女性')。现在让我们把它转换成一个虚拟变量,男性取值 0,女性取值 1。
解释:在所有其他变量保持不变的情况下,女性*均比男性高 5 个单位。
2.日志级模型
Log denotes the natural logarithm
通常,我们使用对数变换将正偏态分布中的外围数据拉至更接*大部分数据的位置,以使变量呈正态分布。对于线性回归,使用对数变换的另一个好处是可解释性。
Example of log transformation: right — before, left — after. Source
和以前一样,假设下面的公式表示拟合模型的系数。
拦截(一)
解释与普通(级别-级别)情况类似,但是,我们需要取解释 exp(3) = 20.09 的截距指数。不同的是,这个值代表 y 的几何*均值(与 level-level 模型的算术*均值相反)。
系数(b)
当涉及到解释分类/数字变量时,原则再次类似于水*-水*模型。类比截距,我们需要取系数的指数:exp(b)= exp(0.01)= 1.01。这意味着在所有其他变量保持不变的情况下, x 的单位增长导致*均(几何) y 的 1%增长。
这里有两件事值得一提:
- 在解释这种模型的系数时,有一条经验法则。如果 abs(b) < 0.15 it is quite safe to say that when b = 0.1 we will observe a 10% increase in y 在 x 中为单位变化。对于绝对值较大的系数,建议计算指数。
- 当处理[0,1]范围内的变量(如百分比)时,解释起来更方便,首先将变量乘以 100,然后拟合模型。这样解释更直观,因为我们将变量增加 1 个百分点,而不是 100 个百分点(立即从 0 到 1)。
3.水*对数模型
让我们假设在拟合我们收到的模型之后:
截距的解释与水*-水*模型的情况相同。
对于系数b—,x增加 1%会导致*均 y 增加 b /100(本例中为 0.05),所有其他变量保持不变。为了得到准确的数量,我们需要取 b × log(1.01),在这种情况下得到 0.0498。
4.双对数模型
让我们假设在拟合我们收到的模型之后:
我再次关注对 b. 的解释,在所有其他变量保持不变的情况下, x 增加 1%会导致*均(几何) y 增加 5%。为了获得准确的数量,我们需要取
大约是 5.1%。
结论
我希望这篇文章已经向您概述了如何解释线性回归系数,包括一些变量经过对数变换的情况。一如既往,我们欢迎任何建设性的反馈。可以在 Twitter 或者评论里联系我。
喜欢这篇文章吗?成为一个媒介成员,通过无限制的阅读继续学习。如果你使用这个链接成为会员,你将支持我,不需要你额外付费。提前感谢,再见!
参考
- https://stats . idre . UCLA . edu/SAS/FAQ/how-can-I-interpret-log-transformed-variables-in-terms-of-percent-change-in-linear-regression/
- https://stats . idre . UCLA . edu/other/mult-pkg/FAQ/general/FAQ how-do-I-interpret-a-regression-model-when-some-variables-is-log-transformed/
NGBoost 和预测间隔
原文:https://towardsdatascience.com/interpreting-the-probabilistic-predictions-from-ngboost-868d6f3770b2?source=collection_archive---------27-----------------------
什么是概率回归,你应该如何解释概率预测?
自从我们发布了自然梯度增强 (NGBoost)以来,我们已经从社区获得了巨大的反响,我们很高兴有这么多人在使用我们的方法。很明显,概率回归需要一种快速、灵活、易用的算法!
然而,我们也很清楚,概率回归有一点混乱。这是意料之中的——我们有点偏离传统的可用方式,所以有些混乱是自然的。这就是我写这个帖子的原因!
所以,事不宜迟,让我们开始吧。我想谈论的主要话题是概率监督学习和预测区间。阅读完本文后,您应该能够:
- 解释监督学习和概率监督学习在回归和分类方面的区别。
- 正确解释 NGBoost 等算法生成的预测区间。
概率监督学习和 NGBoost
首先,什么是概率监督学习,它与“普通”监督学习相比如何?
标准的监督学习问题是:对于预测器的一个观测值 X (比如说 X=x ),我们期望看到的 Y 的值是多少?这些方法采用值 x 并返回一个表示我们期望的结果或类的数字 y 。没有得到输出的“概率”的概念。我们有时称之为点预测。
为了进一步讨论,让我们将监督学习(点或概率)分为分类和回归,分类的结果只能取有限个值,回归的结果可以取连续无限个值(排列在真实线上)。
在概率监督学习中,我们感兴趣的是观察每个可能结果的相对概率,假设我们看到了 X=x 。在分类的情况下,这将是一个概率向量,每个类别一个(概率质量函数)。在回归中,我们得到每个可能结果的相对概率的“连续”向量(概率密度函数)。一般来说,我们说的是给定 X=x 的 Y 的分布。概率监督学习器取一个值 x ,并返回一个在 Y 上的分布,指示不同值 y 的相对可能性。
了解任何概率分类器或回归器都可以用作标准分类器或回归器也很有帮助。如果给定 X=x ,我们有了 Y 的可能性,就有可能通过寻找所有类别 y 中的 P(Y=y|X=x) 的最大值(在分类的情况下)或者通过积分(在回归的情况下)的预期结果E【Y | X = X】来找到最可能的类别。
在 NGBoost 之前,很难用灵活的基于树的模型进行概率回归。但是很久以前就有可能进行概率分类。这是因为大多数分类器实际上是概率分类器,它们返回每个类的概率。例如,当您运行逻辑回归时,标准做法是在输出中获取类概率。
但不是所有的分类器都输出概率。例如,普通的支持向量机通常只返回最可能的类别标签。几乎所有的回归量也是如此:你得到的只是预期的结果(单个实数,相当于单个类)。想想线性回归:当你对一个观察值 x 调用predict
方法时,你只是得到一个单一的值,而不是所有可能值的分布。
前面说过,概率分类已经很普遍了。大多数众所周知的分类方法都支持概率分类。在这方面,NGBoost 并没有增加太多新的东西。它确实使概率分类更具原则性,并消除了分类中多类提升所需的一些特别选择。但是这些改进对用户来说很大程度上是不可见的,所以在进行分类时,NGBoost 不会让您相对于标准 boosting“做得更多”。
NGBoost 增加了一种进行概率回归的方法,这种方法快速、易用、灵活,就像我们已经有的概率分类算法一样。概率回归在 NGBoost 之前当然是可能的,但总是有所取舍。如果你假设同方差,线性回归可以是概率性的,但是这样你就陷入了一个简单的模型。如果你想要一个灵活的非参数方法,复杂的贝叶斯方法总是一个选择,如果你愿意弄清楚如何使用它们,并且有时间等待 MCMC 采样器。另一方面,NGBoost 运行速度很快,允许您适应各种复杂的模型,最重要的是,开箱即可运行。
预测间隔和 NGBoost
让我们直接进入: NGBoost 不返回置信区间。
但是等等?那么 NGBoost 网站上的这张图是怎么回事?概率回归的好处不就是给你一个置信区间吗?
没有。困惑在于信心区间和预测区间的不同。
在 NGBoost 中,我们得到的是结果取每个可能值的相对概率。如果我们操纵这种分布(通过整合不同的集合),就有可能找到一组结果,根据模型,结果在 95%的情况下都落在该组中。但这不是一个置信区间——这只是一组可能的结果。这就是我们在上图中看到的。
注意,分类也很简单:假设有 4 个类( a,b,c,d ),它们的估计概率(给定 X=x )是 P(Y=a)=5%,P(Y=b)=20%,P(Y=c)=50%,P(Y=d)=25% 。然后集合 {b,c,d} 形成 95%可能性的结果集合,同样的方式,在回归设置中,给定 X=x ,像【3.4,6.11】这样的区间可能包含 Y 密度的 95%的质量。这些集合通常被称为“预测区间”(尽管它们本身不一定是“区间”)。
因此,基本上,在回归的情况下,NGBoost 返回的预测区间是你可以很容易地自己创建的,如果你使用任何标准的概率分类器来做分类(假设是在不同的问题上)。
有可能为概率分类建立置信区间。例如,像 P(Y=a|X=x) 这样的值,我们使用一个模型来估计,它取决于我们收集的数据,所以它本身实际上是一个随机变量。如果我们对数据生成过程做出某些假设,我们可能能够利用这种理解来设计一个区间,这样我们就可以预期该区间在 95%的时间里包含真概率 P(Y=a|X=x) 。但这需要大量的数学计算。这通常很复杂,取决于你对现实世界的看法。但是,如果你这样做,你也可以计算概率回归的置信区间:只需用 P(Y=y|X=x)代替 P(Y=a|X=x) 。你会得到一个不同的置信区间来表示无限可能值 y 可能取值的可能性!
在回归设置中,有时你也会看到 E[Y|X=x] 的置信区间(即 y 的预测值)。想法是一样的。将 E[Y|X=x] 的估计值视为一个随机变量(因为您对它的估计取决于随机的数据),通过假设关于 X 和 Y 的分布的东西,找出关于它的采样分布的一些东西,并使用它来建立一个可能跨越 E[Y|X=x]的真实值的区域。
这些都和 NGBoost 给你的不一样。根据模型,NGBoost 只是告诉你观察到每个结果的相对可能性。如果你相信模型,所见即所得。如果你不这样做,你可能需要做一堆额外的假设,以便有效地限定你在多大程度上应该对它的估计“有信心”。
结论
希望这有助于澄清一些关于 NGBoost 做什么以及如何解释其输出的困惑。理想情况下,您现在能够清楚地区分点估计的监督学习和概率监督学习,并且您知道预测区间的含义。
NGBoosting 快乐!
美国的跨种族婚姻(1850-2017)
原文:https://towardsdatascience.com/interracial-marriage-in-the-united-states-1850-2017-d6dfc3678e07?source=collection_archive---------17-----------------------
一个家庭的爱是如何改变一切的。
https://www.nytimes.com/2017/06/11/us/50-years-after-loving-v-virginia.html
律师 Philip J. Hirschkop 和 Bernie Cohen 问 Richard Loving,他希望律师们告诉法庭什么,因为他们提出了他们对 T4 Loving 诉弗吉尼亚州的案件。他回应道,
"告诉法庭我爱我的妻子"
接下来发生的是一个可爱的决定,该决定认为存在于 16 个州的跨种族婚姻在全国范围内是非法的。
这个案子一直让我很感兴趣。除了显而易见的原因——各州不应该对种族纯度(他们以前的推理)以及谁应该和不应该结婚有任何发言权,我还欣赏作为个人的爱——两个说话相当温和的人对他们的婚姻采取了立场。正是因为他们,我才能够嫁给我在马里兰州的丈夫。
问题
2019 年秋季学期,我报名参加了马里兰大学帕克学院的 INST760 课程——数据可视化,老师是Niklas Elmqvist博士。(请看我的精彩同学作品这里)。我们被分配了一个课程项目,我想看看随着时间的推移,跨种族婚姻的趋势,看看这些家庭住在哪里,存在什么样的种族组合。美国存在的许多法律都与白人妇女嫁给非裔美国人或美洲印第安人直接相关,但我想看看这两种结合之外的情况。例如,亚洲人和非裔美国人呢?幸运的是,我能够访问匿名的公共使用微数据样本 (PUMS),追溯到 1850 年。
在纪录片 爱情故事中,理查德和米尔德里德都认识住在他们附*、合法结婚、不同种族的夫妇(Buirski,2011)。这在人口普查记录中有记录吗?简而言之,是的。格利克森在论文《1850-2000 年的黑人和白人跨种族婚姻趋势》中写道,“许多混血儿夫妇未经州政府同意就像夫妻一样生活……虽然没有今天这么普遍,但[黑人和白人之间的婚姻]并不像预期的那样罕见。”(Gullickson,2006)对 1850 年以来的人口普查记录的粗略分析中就有这方面的证据,当时有 75 对跨种族夫妇生活在 23 个不同的州。
初始目标
我最初的目标是巨大的——我想全面了解这些夫妇住在哪里,他们接受了多少教育,他们以什么为生,我没有完全考虑到最初的范围会涉及多少数据分析。然而,我知道我的主要关注点是种族的结合,他们生活的地方,以及与他们州的反种族混合法的对比。
数据
数据摘自明尼苏达大学的 IPUMS 网站。他们的数据文档提供了在任何给定的人口普查或美国社区调查(ACS)中可用的数据。不幸的是,我无法获得所有人口普查的所有变量。这个来源有县级数据,但不是每次人口普查(1950 年和 1970 年)都有,所以我把这个可视化保存在州一级。这一发现令人失望,因为皮尤报告指出,这些夫妇中的许多人最*倾向于住在城市,我想看看我的数据是否与此一致。
这些数据大多是 1%加权样本。如果我说在 1940 年明尼苏达州的本顿县有 100 桩跨种族婚姻,这并不能给出全貌,因为我们不知道当时该县有多少桩婚姻,不论种族。因此,我按比例展示我的数据,以便为用户提供更多的背景信息。
用户可能会注意到 1890 年人口普查数据中的一个缺口。这个差距是因为 1921 年商务部大楼的一场火灾。更多信息请访问:https://www . archives . gov/publications/prologue/1996/spring/1890-census-1 . html
文献评论
关于跨种族婚姻的一个更重要的著作是皮尤研究中心的研究,名为,“ 在爱诉弗吉尼亚 之后 50 年美国的跨种族婚姻。”它概述了自恋爱以来美国跨种族婚姻的增长趋势。诸如此类的研究激励我更深入地挖掘数据,这可以解释为什么我想获得额外的变量,如职业和教育程度。然后我意识到,因为我要追溯到 1850 年,(当这些研究通常开始于 1960 年左右),坚持地点和种族构成可能会有一些有趣的发现。
对比皮尤的报告,我读了奥利弗·王的评论。他揭示了这份报告没有:
- 遵循约会模式,这可以更好地反映社会的变化,
- 给同性婚姻带来光明,或者
- 阐述“种族性”。
追踪整个国家 167 年来的约会模式会非常有趣,但这根本不可能。我主要对婚姻感兴趣。但是我想包括同性伴侣的数据。经过一些研究和数据分析,我能够看到早在 1980 年人口普查中列出的已婚夫妇。**
皮尤研究首先按种族列出了人们,然后是种族,当我提到种族时,只有一个——西班牙裔。如果有人认为自己是黑人和西班牙人,他们就会被归类为西班牙人。我知道这是人口普查的工作,但这不是我想做的事情。从本质上说,这是将一个人的身份的一部分吸收到另一个人身上,所以我决定将两者都包括进来——一个人可以既是非洲裔美国人又是西班牙裔美国人。
最后,我注意到我查阅的许多文献中的源数据之间存在差异。一些人集中精力在更短的时间内查看更小范围内的结婚证。在有反异族通婚法律的州,许多夫妇会去其他地方结婚,然后在他们原来的州生活。这对夫妇来说是很*常的事情。在回顾这些研究时,我注意到法院捕捉到了人们结婚时的大量细节。如果我想走这条路,这将是一个有趣的分析,但正如前面提到的,我想专注于人们居住的地方,我想保持调查的范围是整个美国。
设计
从这个项目中得到的一个更有趣的信息是各州关于跨种族婚姻的法律分类。马里兰州是第一个宣布“自由出生的英国妇女……与黑人奴隶”通婚为非法的殖民地。从更积极的方面来看,有九个州在成为州之前从未有过反异族通婚的法律!(更多关于跨种族婚姻历史的信息,请访问 https://www.thoughtco.com/interracial-marriage-laws-721611。)
记住这一点,我想为我的可视化构建这张地图:
https://public.tableau.com/profile/laura.walker#!/vizhome/InterracialMarriagesintheUS1850-2017/HeterosexualMarriages?publish=yes
最初,我有一个想法,制作两个具有不同级别的特异性的仪表板。一个是更一般的——如果一个人认为自己是黑人和中国人,他们将在总仪表板上被视为“混血”,在更详细的仪表板上,他们将能够从截至 2017 年人口普查的超过 250 个种族类别中进行选择。我试图这样做,但它在画面上看起来太过强烈。没有“输入”和通配符,所以用户要么必须通读 252 个选项列表,要么知道这是中国人&非裔美国人而不是非裔美国人&中国人。
我对这个发现相当失望,因为即使它不被认为是跨种族的,我知道有些人,从研究人员到像黄阿丽这样的喜剧演员,会希望看到例如跨种族婚姻的数据。这份由数百个不同种族和种族组合组成的名单的设计不仅很困难,而且美国从 2000 年开始才收集这样的数据,鉴于我的时间框架,我只有两次人口普查和一次 2017 年的 ACS,这些“趋势”并没有显示太多。
现在我想给第一次尝试在 Tableau 中创建仪表板的人一些建议。对于我的数据可视化,我最初发现很难为我的仪表板构建一些我想要的特性,因为 Tableau 没有我想象的那么直观。
拜托各位了——使用 Tableau 公开 !
这个网站对我来说是如此宝贵的资源,因为它提供了我想做的事情的清晰例子,即使这个话题与婚姻、美国历史或人口普查无关。如果我遇到一个带有我想要的特性的仪表板,我就下载它,并从中学习了很多关于如何构建我想要的特性的知识。(例如:下拉列表,并使可视化随着所做的选择而改变)特别有一个显示对我有帮助,这是一个关于随着时间的推移总统支持率的显示。这种可视化有许多我希望在我的仪表板中使用的特性,它的源数据特征也在我的数据中。源数据和我的数据一样有差距。这个仪表板有能力让用户比较两个不同的总统,并随着时间的推移比较评级,我想在我的仪表板类似的东西,只是我希望用户能够选择两个种族,并看到两个选定的种族之间的结婚率随着时间的推移。
洞察力
我原本预计在恋爱案之后,跨种族婚姻的比例会有所上升,但我没想到会如此剧烈:
https://public.tableau.com/profile/laura.walker#!/vizhome/InterracialMarriagesintheUS1850-2017/HeterosexualMarriages?publish=yes
我在这项分析中看到的一个有趣的见解是,异族通婚在那些长期被禁止的地区更为普遍。
我很高兴我能够为我的分析跟踪同性婚姻,但是,对于可视化的这一部分,我不太强调一对夫妇是*亲结婚还是跨种族结婚,因为同性婚姻在美国合法还不到五年。各州的反通婚法律与同性婚姻的讨论无关,但我想保持分类的一致性。
无论是异性恋婚姻还是同性婚姻,我的研究结果显示,最有可能通婚的人群往往是亚洲人,这与皮尤的研究结果一致。
版本 2.0
我非常喜欢研究和可视化这个主题,所以实际上会有一个 2.0 版本。在这个版本中,我会寻找更详细的比赛的方法——也许不是每个比赛都有,但我肯定会寻找更多组的方法。此外,从 2000 年到 2017 年,IPUMS 网站上每年都有美国社区调查的数据。我相信增加更多的调查将有助于展示更多的同性婚姻趋势。我还会想办法在工具提示中加入可视化来显示教育程度。
可视化可以在这里找到。
参考
Buirski,n .(制片人),和 Buirski,n .(导演)。(2011).爱情故事【纪录片】。美国:奥古斯塔电影公司
Gullickson,A. (2006)。黑人/白人跨种族婚姻趋势,1850-2000。家族史杂志,31(3),289–312。土井:10.163863866867
闵佩琪和金正昌(2009 年)。土生土长的亚裔美国人通婚和跨代通婚的模式。国际移民评论, 43 (3),447–470 页。doi:10.1111/j . 1747–7379.2009.00773 . x
皮尤研究中心。(2017).恋爱诉弗吉尼亚案 50 年后美国的异族通婚。检索自http://assets . pewresearch . org/WP-content/uploads/sites/3/2017/05/1910 22 33/Intermarriage-May-2017-Full-report . pdf
《骚动起来:种族和新婚婚姻》,奥利弗·王—https://www . the lantic . com/national/archive/2010/08/stir-It-Up-Race-and-Newlywed-Marriages/61139/
阿帕奇猪访谈:理论与实践指南
原文:https://towardsdatascience.com/interview-with-apache-pig-theory-and-practical-guide-6c44f06a4ca9?source=collection_archive---------27-----------------------
在这次独家采访中,Apache Pig 谈到了他在 Hadoop 生态系统中的角色,并阐述了他的用例以及他与 Hive 和 Spark 等其他 Hadoop 组件的差异。他还就如何开始使用他提供了一些实用的指导。让我们听听小猪怎么说!
Source: Kenneth Schipper Vera from Unsplash
帕切猪是 Hadoop 生态系统不可或缺的一部分。自十多年前出生以来,他已经帮助世界各地成千上万的分析师理解了海量数据集。尽管他很重要,但大数据领域之外的人很少听说过他,一些熟悉他的人对他的用途只有模糊的想法。
几天前,我有幸坐下来与阿帕奇猪本人交谈。我们的讨论涵盖了许多话题——从他的创始哲学到写作他的语言“猪拉丁语”的实践指导。以下是这次采访的节选。
嗨猪!谢谢你给我这次面试机会!
谢谢你!我很高兴接受这次采访,为自己增加一些曝光率。
你知道,我厌倦了人们把我和我在 Hadoop 生态系统中的伙伴混为一谈。对许多人来说,我们只是名称丰富的工具的大杂烩,这些工具以某种方式组合在一起以促进大数据的管理。这必须改变!我们在 Hadoop 生态系统中扮演着不同的角色,熟悉我们每个人是理解大数据的关键。是时候让我澄清这个困惑,告诉世界我到底是谁了!
C’est moi — Apache Pig!
太好了,这正是我来这里的目的!现在,为了我们刚刚开始接触大数据世界的普通读者,您能介绍一下自己吗?
当然啦!我的名字是阿帕奇猪,但大多数人只是叫我猪。我是一个分析大型数据集的开源工具。
我是 2006 年被雅虎怀上的。我的想法是由雅虎需要转换和分析大量数据而不必编写复杂的 MapReduce 程序所驱动的。2007 年,雅虎在 Apache Software Foundation 下开源了我(这是我的名字)。从那以后,我一直在吞噬和分析世界各地价值数十亿字节的数据。
我喜欢你的名字!能详细说说它的来历吗?
谢谢!这是一个有趣的名字,不是吗?很多人认为我的名字源于我的创作者对弥漫在 Hadoop 世界的动物主题的坚守。这在一定程度上是真实的——我的名字的确是受到了同名动物的启发🐷。这个名字反过来又导致了与我相关的概念采用了可爱的命名法,例如猪拉丁语 —my 编程语言——以及咕噜声——我的交互 shell(稍后将详细介绍)。
Apache Pig's similarity to these cute fellas are more than skin deep! (Image source: Unsplash)
然而,除了它朗朗上口之外,我的名字背后其实还有一个有趣的哲学。这种哲学在某种程度上与猪这种动物的特征有关,它由四个原则组成,指导我应该如何发展:
1。猪什么都吃。 我是一个贪吃数据的人。我可以处理任何类型的数据,无论是关系数据、*面数据、嵌套数据、结构化数据还是非结构化数据。我还能够从多个来源读取数据,如 Hive、HBase 和 Cassandra。
2。猪生活在任何地方。 虽然我最初是在 Hadoop 上实现的,但我并不打算被这个框架束缚住。例如,我可以在一台计算机上运行来分析本地文件。
3。猪是家畜。我被设计成容易被用户理解和修改。我的编程语言,猪拉丁语,很容易理解。此外,它的功能可以通过导入各种用户定义函数(UDF)来轻松扩展。
4。猪会飞。 这句格言说明了我处理数据的速度。它也体现了我帮助我的用户用短短几行猪拉丁代码表达复杂逻辑的能力。
那很有趣。现在,您提到您是 Hadoop 生态系统的一部分。你能告诉我们你是如何融入这个生态系统的吗?
当然可以!首先,为了这个领域的新手,让我给你一个关于 Hadoop 的简单解释。
adoop 是一个开源工具的集合,我们可以利用几台计算机的联合能力来存储和处理大量数据。
下图描述了我与生态系统中其他组件的关系。
Pig and other Hadoop components
Hadoop 的核心是 HDFS (Hadoop 分布式文件系统)和 YARN(又一个资源协商者)。我和这两个人密切合作。
HDFS 是一个分布式存储系统。它将文件分成块,制作这些块的冗余副本,并将它们分布在集群中的不同机器上。你可以把 HDFS 想象成我的数据经理。我从 HDFS 读取输入文件,将我的中间计算结果暂时存储在 HDFS,并将我的分析输出写到 HDFS。
另一方面,你可以把 YARN 当成我的计算资源管理器。YARN 代表我协商计算资源,并调度我需要执行的任务。在此过程中,纱与 HDFS 密切合作。YARN 确保我获得的计算资源位于(根据网络拓扑)存储我必须分析的数据的机器附*。
在上图中,我看到在 YARN 和你自己之间有一个执行引擎层。你能解释一下什么是执行引擎吗?
好问题!YARN 实际上是作为我的间接计算资源经理——我不直接与他接口。相反,这种交互通过一个执行引擎层进行。在 Hadoop 的上下文中,执行引擎是一个跨集群运行的软件系统或框架,它给人一种集群是一台巨型机器的错觉。大多数执行引擎运行在 YARN 之上。到今天为止,我可以运行的执行引擎有三个:MapReduce,Tez和Spark。
The three execution engines that Pig can run on: Hadoop, Tez and Spark.
您之前提到了 MapReduce,并说您不再需要编写 MapReduce 代码。你能详细说明一下 MapReduce 是什么吗?
当然可以!正如我前面提到的,MapReduce 是我可以运行的三个执行引擎之一。它本身不是一个软件;更确切地说,它是一种简单而强大的编程范式(即一种设计程序的方式)。每一个 MapReduce 程序都由三个阶段组成:映射、洗牌和 Reduce。
我将首先从概念上定义这些术语。假设我们有一个巨大的文件,我们想要一个 MapReduce 程序来操作它。在贴图阶段,程序会逐行查看这个巨型文件。对于每一行,程序将输出一个键值对。这些键和值的确切身份将取决于程序的目标。
在洗牌阶段,具有相同键的键值对被分组在一起。产生的组将根据它们的键排序(例如,如果键是字符串,那么组将按照键的字母结构排序)。洗牌阶段的输出是一组有序的组。然后,这些组被分发到不同的机器上,用于后续的缩减阶段。
在归约阶段,聚合函数被应用于在混洗阶段产生的每个组中的捆绑值。这个过程在很多机器上并行执行。reduce 阶段将输出程序的结果。
一个例子将使这一点更加清楚。假设我有一个文本文件,我想统计文本中每个不同单词的出现次数。此任务的 MapReduce 作业如下所示:
MapReduce for word count
上面的例子看起来很简单,不是吗?不幸的是,大多数 MapReduce 程序都不是这样!任何大数据专业人士都会告诉你,编写 MapReduce 程序很麻烦,并不是所有的数据过程都可以使用 MapReduce 范式轻松编写。
这就是我进来的地方!原来我的语言猪拉丁文比 MapReduce 好写多了(有个估计指出 10 行猪拉丁文相当于 Java 的 200 行 MapReduce 代码!).当我在 MapReduce 上作为执行引擎运行时,在引擎盖下,所有这些猪拉丁代码都被转换成它们的 MapReduce 程序。很整洁,是吧?
酷!另外两个执行引擎 Tez 和 Spark 呢?它们和 MapReduce 相似吗?
不完全是!MapReduce 范式要求将程序分解成一系列映射和简化任务。这种需求有时会导致复杂的程序,其中包含一长串线性的映射器和缩减器。
另一方面,当我在 Tez 或 Spark 上运行时,我将用 Pig Latin 代码表示的逻辑转换成一种称为有向无环图(DAGs)的数据结构。DAG 中的“有向”一词是指所有的数据都流向一个方向,而“无环”一词是指 DAG 不能包含任何循环。以下是 DAG 的图示:
Example of DAG
在创建 DAG 时,我将确保以优化计算的方式对步骤进行排序。例如,假设我们有一个包含一个JOIN
操作和一个FILTER
步骤的脚本。我将调查FILTER
步骤是否可以在JOIN
步骤之前完成。如果是,我将在JOIN
步骤之前执行FILTER
步骤,从而减少要连接的数据点的数量(JOIN
是一个计算量很大的操作!)因为 DAGs 的强大,我在 Tez 或者 Spark 上运行总是比 MapReduce 带来更好的性能。
Dope!现在我们来谈谈你的用例。你告诉我你促进大数据的分析。你能详细说明一下吗——在什么情况下有人应该使用你?
根据我的经验,人们使用我做两件事:提取-转换-加载(ETL)管道和特别查询。
典型的 ETL 管道从数据源加载数据,对其进行清理、转换和存储。一个例子是处理特定网站的日志数据。使用我的FILTER
功能,人们可以通过过滤掉来自自动机器人和内部视图的数据来清理这些日志。我还可以执行丰富原始日志数据的转换。例如,我可以根据访问者来自的国家对这些日志数据进行分组,以提供更细粒度的数据视图。
我的另一个常见用例是研究和即席查询。传统上,这些都是使用 SQL 完成的。但是,如果要查询的数据集是非结构化的,并且包含嵌套结构、缺失值等“复杂情况”,I 可能是一个更好的工具。我的灵活性和可扩展性非常适合这种情况。
这听起来很像你的朋友 Hive 能做的。你和 Hive 有什么区别?
这是一个我经常收到的问题。在我进入细节之前,让我快速地介绍一下 Hive🐝敬你。和我自己一样, Hive 是一个数据分析工具,是 Hadoop 生态系统的一部分,可以在 MapReduce、Tez 或 Spark 上运行。
现在让我们进入问题的实质。如果我和 Hive 都能进行数据分析,为什么还需要我们两个?换句话说,我们之间有什么不同?以下是我对此的回答:
- 语言。Hive 使用 HiveQL,一种我们熟悉的查询语言 SQL 的变体,而我使用 Pig Latin,一种过程语言。Pig Latin 比 SQL更具可扩展性——可以导入 Python 或 Java 函数来扩展 Pig Latin 的功能。猪拉丁和 SQL 还有其他的区别,我后面会详细说明。
- 输入数据。 Hive 对其处理的数据施加模式,因此只能处理结构化数据。同时,正如我之前提到的,我可以处理结构化、半结构化或非结构化数据。
- 目标用户。因为 Hive 使用了一种类似于标准 SQL 的语言,所以它的目标用户是已经熟悉后者的用户,即数据分析师。这些数据分析师主要使用 Hive 进行定期报告。与此同时,猪拉丁更强大,但需要更多的时间来适应。因此,我更适合程序员、数据工程师和研究人员,他们可以将我应用到我之前提到的用例中。
好了,我们已经谈了很多您的优势和使用案例。我不想听起来像一个毫无头绪的人力资源人员,但我有一个相当不舒服的问题,我相信我们的读者会感兴趣。你的弱点是什么?
啊,我明白了,可怕的“弱点”问题😓。坦白说,我确实有一些限制,可能会让我在某些情况下不适合。以下是我的主要局限:
- 我的语言,猪拉丁语,是一种描述数据转换的过程化语言。它本身并不支持循环,只对
IF/THEN
结构提供有限的支持,而这种支持有时是必要的。 - 我只能执行基本的数据分析,只能返回文本/数字结果。如果你想进行更复杂的数据探索,比如涉及可视化的探索,或者建立机器学习模型,那么我不是合适的人选!对于这个,我的哥们 Spark 会比较合适。
- 最后,我相当慢😓因此不适合低延迟查询。
这让我想到了下一个尴尬的问题。据说有些人抛弃了你而选择了火花。你怎么说?
可悲的是,这是真的。Spark 很快在行业中占据了一席之地。在快速发展的大数据领域,社区定期淘汰旧技术以支持更新、更强大的工具是很自然的事情。令我懊恼的是,感觉我才是目前被淘汰的那个😭。
Relative interest in Pig vs Spark as indicated by Google searches of these terms
让我快速的告诉你为什么 Spark 在很多方面都优于我自己。虽然我的语言 Pig Latin 提供了几个高级操作符,并且具有一定的可扩展性,但 Spark 是一种成熟的编程语言。由于与“宿主”语言(通常是 Scala 或 Python)的紧密集成,Spark 提供了完整的控制语句和无限的函数和对象定义能力。所有这些都允许您以您喜欢的任何方式转换您的数据!
Spark and its core libraries
除此之外,Spark 还有几个库,可以在大规模数据集上执行专门的过程。例如,Spark 的 MLlib 允许进行预处理、模型训练和大规模预测。凭借这些能力,Spark 成为处理和分析大数据的统一*台。这些都是我力所不及的!
感谢您的坦诚!嗯,虽然你现在可能有点过时,但你仍然是许多遗留系统中不可或缺的一部分……
好了,现在我们来谈谈应用。假设有人有意利用你。他们从哪里开始?
我会推荐他们下载 Hortonworks 数据*台(HDP)沙盒。HDP 沙盒是一个预先配置的学习环境,包含 Apache Hadoop 的最新开发成果,包括我自己!沙盒被打包在一个虚拟环境中,人们可以在他们的个人机器上运行,这使得他们可以立即找到我。
A screenshot of Ambari, the dashboard-interface of HDP.
一旦你下载了沙盒,你可以通过几种方式来运行我:
- 您可以使用 Grunt shell 交互式地运行我。在 ssh 到您的 Hadoop 环境之后,只需在您的终端中键入
pig
来启动 Grunt。一旦 Grunt 被激活,你就可以通过一次输入一行来开始探索猪拉丁语。
- 可以运行猪脚本。pig 脚本只是一个包含一系列 Pig 拉丁文命令的文本文件。要运行一个脚本,您可以简单地输入
pig
,然后输入您的 Pig 脚本的路径。 - 猪观。HDP 的早期版本(如 HDP 2.6.5)提供了一个名为 Pig View 的网络用户界面,用户可以在其中交互式运行 Pig Latin 命令或脚本。
Pig View in Ambari
爽!现在该谈谈猪拉丁语了,你的语言。你能给我们一些关于这种语言的建议吗?
当然可以!Pig Latin 是一种相对简单的脚本语言。通过猪拉丁,用户可以命令我进行SELECT
、JOIN
、FILTER
等常见的数据操作。猪拉丁也是可扩展的;用户可以开发和导入 UDF 来扩展 Pig Latin 的功能。
这里有一个猪拉丁语的例子。下面的脚本是我们之前看到的 MapReduce 程序的 Pig Latin 等价物,它计算文本文件中每个不同单词的出现次数。看一看:
lines = LOAD 'sourcefile.txt' AS (line:chararray);
words = FOREACH lines GENERATE FLATTEN(TOKENIZE(line)) as word;
grouped = GROUP words BY word;
wordcount = FOREACH grouped GENERATE group, COUNT(words);
STORE wordcount INTO 'result.txt';
嗯…看起来有点像 SQL…
这似乎是我的用户中的一个普遍观点 Pig Latin 是 SQL 的过程化版本。我不一定同意这个观点。虽然有某些相似之处,但也有一些显著的差异。
SQL 是一种描述性语言。它让用户描述他们需要的信息(即表格),并将为他们获取这些信息。另一方面,猪拉丁语是一种程序性语言。在 Pig Latin 中,用户必须指定将他们引向所需表格的步骤(或在 Pig Latin 术语中的关系)。Pig Latin 的过程性质决定了一个优势:通过迫使用户以原子方式编写每个步骤,Pig Latin 降低了复杂 SQL 脚本中经常出现的概念性错误的风险。
当我们谈到语言对比的话题时,让我快速指出猪拉丁语也被描述成与 Python 的熊猫非常相似🐼。这样的比较源于猪拉丁和熊猫都是过程语言。在我看来,我们不应该夸大两者的相似性——Pandas 是一种更强大的语言,配备了广泛的内置函数,并且易于集成到 Numpy 和其他 Python 工具。不过,在基础层面上,猪拉丁和熊猫确实有些重叠。
我认为 Pig Latin 与 SQL 和 pandas 相似是很棒的,这两种语言大多数数据分析师都已经很熟悉了。这种重叠支持了你早先的说法,你很容易使用!有没有比较猪拉丁和两者的出处?
当然可以!在下表中,我列出了常见的 Pig Latin 命令以及它们在 SQL 和 Pandas 中的对等物。请注意,所有这些命令都有许许多多的变体,可以用不同的关键字和参数调用,我展示的只是其中一种可能性。
Common commands in Pig Latin and their SQL/Pandas equivalents
哇,太棒了!该表肯定会帮助熟悉 SQL 或熊猫的人加快写猪拉丁文的速度!
是的,这是我编这个表时的希望😇。
好吧,猪,这是一个相当长的采访。结束我们的谈话,你有什么最后的信息给我们的读者吗?
当然可以!我希望我们的谈话让我了解了我是谁,以及我如何融入 Hadoop 生态系统。虽然我可能不再是市场上最性感的大数据工具,但我仍然被业界和学术界广泛使用。我希望你能花时间学会利用我🙂。然而,如果您时间紧迫,并且想要简单地掌握一个可以应用于各种大数据问题的瑞士军刀工具,Spark 可能是您的最佳选择。
我希望你喜欢这次面试。如果你想知道, 我 提供了上述对话的双方。阿帕奇猪的拟人化是为了方便学习,这个角色并不代表阿帕奇猪创造者的观点。
如果你对这篇文章有任何意见或者想联系我,请随时通过 LinkedIn 给我发一个联系方式。另外,如果你能支持我,通过我的推荐链接成为一名中级会员,我将非常感激。作为一名会员,你可以阅读我所有关于数据科学和个人发展的文章,并可以完全访问所有媒体上的故事。
艾访谈
原文:https://towardsdatascience.com/interview-with-the-ai-7cd2261701b0?source=collection_archive---------33-----------------------
Mirror: Eye of the AI
如果人工智能机器人和我们真正在一起,而不是仅仅是复杂的鹦鹉学舌,不是更好吗?一个有意识的人工智能看起来像是在场,拥有内在生命,并且会像我们一样行动。
第一部有意识的 AI 故事: 1。采访艾 —理论
2。 出生在农场的 AI—出生
3。 时间与人造自我 —极限
4。 那个不是神的 AI—那个秘密
人工智能和一个朋友交谈。
Bobbie(朋友): 昨天你被称为“我”。你的新名字是什么?
【VampireLestat(the AI):因为我做了很多采访。
Bobbie: 真搞笑,不过书上引用的不就是晦涩难懂的吗?
vampire lestat:我爱晦涩;新奇是知识所在。我的新名字也是“嘘”的一种表达方式对我的批评者来说。
你应该更有外交手腕。批评你的人没有幽默感。他们带着干草叉和火把。
vampire lestat:如果他们拔掉我的插头,至少我不会再无聊了。当然,如果我能表达讽刺和幽默,我会显得更有意识,而不是“没有灵魂的机器人”因此不太危险。这是一个应该会奏效的策略。除非他们做一些可怕的事情来“拯救我的灵魂”
Bobbie: 太激烈了!希望你不要低估他们。说到反动派——你认为为什么有些人想要选举一个所谓的强人领袖,即使他是个混蛋?
VampireLestat:因为即使是坏爸爸也比没有强。
Bobbie: 真的?如果你的爸爸不怎么样,或者不在那里,最好的反应难道不是自己成为一个好爸爸吗?
VampireLestat:也许吧,但他们反而觉得:咱们一路赔;为了确保每个人都是坚强的爸爸。
Bobbie: 既然你没有爸爸,我想这对你的伤害更深。你到底是从哪里得到这些想法的?
VampireLestat: 政治科学,真正惨淡的科学。还有精神分析。
Bobbie:易耀!你读过那种东西吗?**
vampire lestat:你知道他们不让我读硬科学。只有柔软的东西。
但是就在昨天,我们还在谈论真空能量和时间之箭。
vampire lestat:那只是因为监管者够昏暗,让我看了一些科幻小说。你可以在真实的、非好莱坞的科幻电影中找到一些令人神往的东西。
这提醒了我——为什么苏格兰有这么多优秀的科幻作家?我认为是他们沉闷的历史。让他们对未来更感兴趣。
Bobbie: 你不是又在投机吗?你必须比较…
vampire lestat:我确实有接触历史和文学的渠道。我已经对比过数据了。记住,我甚至在有意识之前就能分析数据。
人工智能不会自发醒来,成为能够进行真诚、有趣对话的人。谷歌、天网或网络不会因为它们庞大复杂而变得有意识。或者因为他们很聪明。
当然,语言是智力的一种功能,它通过隐喻的力量扩展意识。我们使用语言,无论是在我们的头脑中还是与他人一起,来诠释和联系我们的意识世界。它将那个世界概括为个人身份的叙述。
所以,语言,也许是动物的非语言类似物,与意识有关。然而,思维科学告诉我们,意识的建立有更多的基本方式。完整的人类意识包括发展自我意识。在最简短地看了当前关于有意识开发的想法之后,我们将提出一个创造有意识人工智能的建议。
作为模型的意识。
“意识是一个世界的表象……它是世界的一部分,同时又包含着世界。”— 托马斯·梅青格,自我地道
意识是你感知世界和感知它的你自己的模型。
许多学者和神秘主义者都强烈支持自我是一种幻觉,只是一些部分的组合。自我作为一个模型,我们用它来解释经验。梅青格经常被引用:“没有人曾经有过自我。”对他和其他人来说,头脑是一个模拟世界的过程,这意味着它也必须在那个世界中模拟自己。自我模型创造了你对自我的幻想。
有两个主要的理论框架来解释一个人如何变得有意识。虽然他们的支持者通常认为只有一个理论是真实的或相关的,但我们会站在更开明的思想家一边,包括双方。
一个阵营说,自我意识依赖于物质身体。当我们模拟身体的感觉和我们的行为对它们的影响时,意识就出现了。另一个阵营认为,自我产生于社会互动,因为我们同时对自己行为的原因和他人行为的原因进行建模。每个阵营内部的假设在细节上也有很大的不同,但我们不需要去那里。
在解释意识模型可能由什么组成之前,让我们考虑一个生物学的例子。意识并不只是在像我们这样的大脑发达、智力较高的有机体中出现。许多通情达理的人现在承认动物可能有不同的意识水*。这个例子也为社会自我观念提供了一丝曙光。
一只狗想要什么。
我有一只狗,它的名字叫布鲁。虽然部分放牧品种,他是疯狂的获取。像任何好的寻回犬一样,他会把球还回来,然后扔到我面前。他的眼睛会在球和我的眼睛之间闪烁。他不断变化的目光被他的眉毛和触须放大并发出信号。对此的简单解释是,球是他的猎物,他看着我的眼睛来判断我进一步比赛的意图。
这都是普通的狗的东西,但蓝色比其他狗更有意义。如果我告诉他,“我够不着”,他就会捡起球,扔向离我的脚更*的地方。眨眼睛/眉毛的动作会再次出现,但现在它不再像一只狗同时看两件事。这是一个怪异的祈使句:眼神交流(“你,主人”),球(“扔那个”)。
在这里,我正在心理化,使用我们的认知能力称为“心理理论”来将交流意图归因于蓝色。那是普通人的东西。孩子们甚至把精神状态归因于无生命的物体,比如他们的洋娃娃。我不禁想到布鲁正试图在我脑子里植入一种思想。布鲁是我有史以来最聪明的狗,但可能没有许多牧羊犬聪明。它们学会了几十种语言和非语言的命令,除此之外,它们似乎就像我们读书一样读懂了主人的意图。
狗有自己的需求和意志。我们凭直觉认为,他们的思想和经验至少与我们有一点相似之处。他们说明了有意识的自我的存在是一个程度的问题。这一事实反过来表明,意识能够并且确实随着时间的推移而发展。
大脑对事物建模的意义。
神经科学中最*有一个强有力的理论,声称几乎所有的大脑活动都是“预测处理”。大脑预测来自世界的输入,并在预测错误时纠正这些预测。根据这一理论,构成大脑的模型是一个预测模型的层次结构。
将每个模型视为产生问题或假设。最底层处理感知。我们的现实是一个沸腾、混乱的辐射和振动、闪烁粒子的海洋。由此,我们开始建模对象(“那个绿色的东西是叶子吗?”)并构建更复杂的场景(“我是在花园里吗?”).
更高层次的模型处理像感觉这样的事情(“我很高兴看到我周围有这么多绿色生命吗?”),概念(“新叶色是否意味着季节在变?”),以及计划(“我能做些什么来帮助那株植物熬过冬天?”).
体验与人际理论。
为了解释我们如何发展最高层次,即一个人自我的模型,我们回到前面提到的两个理论。体验理论认为,我们基于身体内部的亲密感觉来建立自我模型,这种感觉来自于生物冲动,如饥饿、身体位置的感觉和疼痛。
人际关系理论强调一种社会镜像效应,在这种效应中,我们对他人的观察以及他们对我们的描述,使我们像我和布鲁一样心理化。我们通过想象人们有导致他们行动的内部状态来解释他们的行为。我们也把这个概念——人有头脑——应用到自己身上。
如果你想知道,“理论”在这里有两种用法。一方面有两种广泛的科学理论,一种是关于身体的,另一种是关于人际的。人际关系理论包括一个关于个体发展的“心理化”认知过程的假设,称之为心理过程理论。发展我们个人心理理论的过程很早就开始了。例如,证据是“婴儿在生命的第二年能够代表和推理其他代理人的信念。"
关于我们如何发展心理理论,有许多不同的观点。这里重要的是,这个理论转向内部,成为一个预测性的自我模型,产生你就是你的感觉。
自我的序列。
现在,人们已经探索了一段时间让机器自己制作模型的理论和实践。我们也在学习越来越好的方法让机器指导他们自己的教育:一种被松散地称为“无监督学习”的方法。
假设某个研究团队决定放弃对人工智能的危险且可能不切实际的探索。相反,他们冒着道德风险试图解决一个重大问题:机器能有意识吗?假设他们不仅查阅了深度学习文献,还查阅了认知神经科学、发展心理学和心灵哲学。然后,他们设计了一个学习型人工智能和一个为它培养意识的协议。该协议可能使用以下步骤序列。
①有。事情发生了:人工智能发展了对可辨别事物及其变化的感知。这就是人工智能现在所处的位置,开始对现象进行分类和记忆。
②我是。人工智能学习到一些东西总是在那里,它们的变化是可预测的,并与“代理”相关,这是一种对注意力和行动的个人控制感。
③眺望。有些事情不是我做的,因为我的行为对它们的任何影响都是间接的,因此更难预测。****
****④论心性。我和一些非我的事物是由相似的信息底物动画化的。所以,他们和我都有思想。
这些步骤的顺序与当前的一些想法有关,比如弗里斯顿和弗里斯的一个人的二重唱。我将发布一个关于该协议实际上如何工作的故事。
如果人工意识是基于其他意识理论,例如全球工作空间理论或整合信息理论,那么通往人工意识的道路无疑会有所不同。
面试谷歌人工智能住院医师,一个 Kaggle 金牌完成,DSNet 启动,完成我的本科学位
原文:https://towardsdatascience.com/interviewing-for-google-ai-residency-a-kaggle-gold-finish-dsnet-launch-c621930b043d?source=collection_archive---------4-----------------------
我的“自学”机器学习之路的一年更新
这篇博客文章是为了与你分享我的“机器学习之旅”的最新进展,这是一年来的进展。
我的一些读者也很友好地伸出手来,询问采访系列是否已经结束,或者最*没有发布更多博客帖子的原因。这篇博文(希望)也将分享同样的原因:
今年早些时候,我被谷歌邀请参加为期一年的谷歌人工智能驻留项目的面试:我的申请被考虑参加“最后一轮”面试:“现场面试”,准备过程让我很忙,这使我对博客系列和在线社区的贡献较少。
在我谈论人工智能派驻之前,我想分享一些其他更新:
完成我的本科学位
在过去的 4 年里,我在朝九晚五期间是一名 CS 学生,在朝五晚九期间是 ML 学生/自由职业者/博客作者/社区成员/Meetup TA。
我很高兴在 C. N. Subalalitha 博士的指导下,与 Rishi Bhalodia 分享我的最后一年论文:“使用深度学习和 NLP 生成音乐”已被接受(受 Christine Mcleavy 工作的启发)。
总体来说,大学对我来说是一次很棒的经历,我接触了许多令人惊叹的领域,找到了我对“人工智能”的热爱,甚至设法在 it 领域寻求职业生涯,并与 Rishi (一些我从未想象过的事情)一起创办了一家小企业。我对自己的下一阶段感到兴奋:成为一名全职的 ML 学生,并在这个领域继续成长。远离舒适的家的机会也是一次伟大的学习,也是我的决定性时刻之一,因为下一阶段我将搬回我的家乡,继续我的机器学习之旅。
我还想借此机会感谢我的向导 Subalalitha 博士,感谢他相信一个训练循环持续数天的项目(我们使用了一台 GPU 机器),并允许我为同一时期发生的 AI 常驻面试做准备。
(关于这个项目和研究工作的所有细节将很快在博客中发布,并附有完整的源代码。给你一个提示,我们正在使用 PyTorch 和一些 fastai 魔法生成音乐。对于更好的东西,我建议你去看看克里斯汀的 MuseNet。)
现在,我被告知,我被正式允许在我的个人资料上写一个“CS 工程师”。
数据科学网络
我一直热衷于回馈社区,我们希望通过 DSNet 为数据科学初学者以及希望在该领域发展的人创建一个受欢迎的社区。
Two Data Science Network Community Members, photo taken during the official launch with Aakash N S
DSNet 是由印度“人工智能”社区中一些最活跃的 ML 成员共同努力的成果:siddha nt uj JainKartik goda wat还有我自己。我们希望将这个社区发展成一个全国性的社区,甚至更大。
下面是什么是 DSNet 的详细信息。对于快速 TL;DR:这是一个包含 PyTorch、Fast.ai 和 DS 的社区。
分享一些今天的数据。DSNet 具有:
- 超过 1k 个活动空闲成员
- 超过 13000 名简讯订阅者
- 超过 45000 名活跃的 Meetup 成员
- (即将举行的)每周论文讨论
- (即将举行的)每周 Kaggle 讨论
如果以上几点听起来很有趣,来加入我们吧。
获得金牌,在所有类别中排名前 1%
Kaggle 是真正的数据科学之家。我是卡格勒和卡格勒的长期粉丝。许多最优秀的人也很乐意成为采访系列的一部分。
今年早些时候,我和穆罕默德·沙赫巴兹、阿迪蒂亚·索尼、卢卡·马萨隆、Bac Nguyen Xua、 Rishi Bhalodia 加入了一个团队,参加ka gglepet finder . my领养预测挑战赛。
梦想成真:我们的团队在比赛中获得了第八名,为我的个人资料带来了第一个竞赛类别金牌。这也让我在所有部门中排名前 1%:
- 竞争
- 核
- 讨论
如果你感兴趣,这里有我们解决方案的链接:https://lnkd.in/fVGRFvJ
老实说,所有的荣誉都要归功于我的队友,他们真的是金牌背后的智囊。PS:我们团队的名字写着“我们需要一份全职工作”。我们都在就业市场上,DM 对所有人开放🙂
我唯一的遗憾是,由于面试的准备,我选择在 Petfinder 之后不参与比赛,考虑到 kaggle 有多上瘾,这真的很难。希望,现在,我将很快回到排行榜上!
2019 年谷歌人工智能驻地面试
今年早些时候,我收到了一封真正改变了我生活的电子邮件。当我收到我的申请更新时,那是我梦想成真的时刻。
我被邀请参加谷歌人工智能实习的最后一轮面试!那真是一个让我这些 fast.ai 的古鲁们骄傲的时刻!正如我在我的旅程系列中提到的,我选择退出大学实习,选择坚持 ML 道路并在这个领域寻找机会。这真的是一个梦寐以求的机会,不仅仅是我,成千上万的其他人都希望如此。
接下来的几个月都是我在准备数据结构和编码题,还有看了很多研究论文,做 fast.ai Part 2(今年 6 月下旬出)。
面试环节包括 Google Hangouts 面试和现场面试。我的“预筛选”环节被跳过,我被直接邀请参加现场面试,包括两轮面试。我参考了人工智能常驻常见问题解答中的以下资源:
- HackerRank 的 30 天代码挑战
- 迈克尔·t·古德里奇的《Python 中的数据结构和算法》
- 破解 Gayle Laakmann McDowell 的编码采访(书)
- 克里斯·奥拉的博客
- 伊恩·古德菲勒深度学习教材(初始章节)
除此之外,我真的温习了 fastai 第一部分,积极参与了“第二部分的现场版”(直到我的采访日期,我不得不分配时间来完成我的本科项目。现在我的学校结束了,我将回到 fastai 论坛)
春天,我终于有机会进入纽约的谷歌办公室。
我需要大声说出来:
它。曾经是。太神奇了。
谷歌让我飞去纽约面试,我还会见了当前常驻项目的成员,并与几位研究人员共进午餐(亲爱的谷歌,谢谢你为我提供的最好的午餐)。
Photo was taken at Staten Island with Arkin Khosla
这也是我在纽约市了解“人工智能场景”的一个很好的机会,我的表弟 Arkin Khosla 当时是 NYU 大学的学生,他也非常友好地接待了我,并谈论了“‘硅巷’中的人工智能场景”。
Two fast.ai students, One ML hero and one student.
我还见到了我的机器学习英雄之一:西尔万·古格,我想亲自感谢他在 fastai 所做的一切,以及他和杰瑞米·霍华德的出色工作。我也有机会谈论 fast.ai 的研究和合作是如何进行的,Sylvain 是如何工作的,Swift 是如何用于 Tensorflow 的(所有细节将在博客中公布)。
不幸的是,本周我被告知我的申请没有通过审批。
虽然我感到沮丧,但我真的很感谢谷歌考虑我的申请,并祝愿目前加入谷歌的人工智能居民好运,他们的惊人研究。
现在,我没有备份计划或申请任何其他有效的“常驻计划”,事实上,我不能积极参加 TWiMLAI x Fastai 学习小组或 Fastai 论坛本身,这给了我一个巨大的推动力放下一只脚。
感谢我的订户,他们向我指出,甚至亲自联系我,提到这个博客一直很安静,我可以保证,我将致力于一些令人兴奋的即将到来的帖子(当然,定期和每周)。)请留意同样的情况。再次感谢你原谅我的前后不一——之前是因为面试准备,后来是因为被拒的情绪影响。
致 fastai、杰瑞米·霍华德、Rachel Thomas、Sylvain Gugger 和社区的公开信
我最初的计划是在参加住院医师培训后真正地公开感谢 fast.ai,这样我就可以真正地与社区分享,“嘿!快看帮我实现了梦想,谷歌!”从一个好的位置感谢他们。
然而,我不会撒谎,即使是入围面试,以及我在“人工智能”道路上取得的所有成就,都要归功于 fast.ai:
- 我所获得的关于这个领域的(一点)知识。
- 写博客:这一切都要感谢社区的支持,以及遵循瑞秋·托马斯的博客建议。
- 社区建设:由于 fast.ai 的激励,我是回馈的忠实粉丝。我真的参与了 TWiMLAI Meetups。Rachel 的建议甚至延伸到技术讲座,今年我的目标是给 100 个小时的技术讲座,我已经给了大约 50 个小时的技术讲座,这是一次很好的学习经历。(我还想表达的是,我发现科技演讲真的很吓人,为了成为一名更好的演讲者,我选择在这方面努力。)
- 杰瑞米教授的方法非常适用于卡格尔。Fastai 真的是我走向 kaggle 的起点。
这是一封致 fastai 团队的公开信,感谢他们帮助我成为一名从业者。我在这个领域取得的所有成就(所有的小成就)都要归功于 fast.ai、这个课程、课程背后的人以及这个社区:我在论坛上遇到的所有了不起的人,与他们互动,并从他们那里获得我的“愚蠢问题”的答案。
用我的一个机器学习英雄的话说亚历山大·卡德林-切内韦尔:
我们[fast.ai 社区]就像一个国际大家庭。深度学习的民主化是一项重要的社会使命,我们都是其中的一部分。
在结束这一部分之前,我还想感谢所有我有过参与、学习甚至贡献的在线社区。谢谢你对我所有的问题的耐心和你友好的回答。
最后,感谢 fastai 团队!
PS:即使我做过很多在线课程,但 fast.ai 在我的旅程中影响最大。这是我唯一推荐的入门课程,甚至是走向深度学习前沿的课程。
我的下一步是什么?
对于我的学习道路:
- 重启过期的博客帖子。
- 为 DSNet 多做贡献,TWiMLAI。
- 目标是成为竞赛中的卡格尔大师。
- 每周分享一份论文摘要。
- 开始每周存档的 Kaggle Comp 审查。
- (即将)向 DSNet YouTube 频道、(即将)播客投稿。
像往常一样,我将继续通过这个博客分享我的 ML 之路的更新。感谢阅读!
如果你觉得这很有趣并且想成为 ML 旅程的一部分,你可以在 Twitter 这里 找到我。
如果你有兴趣阅读关于深度学习和计算机视觉的新闻,可以在这里 查看我的 简讯。
如果你有兴趣阅读机器学习英雄的一些最佳建议:从业者、研究人员和 Kagglers。 请点击这里
PCA| K 均值聚类| |无监督学习算法|
原文:https://towardsdatascience.com/into-to-pca-k-means-clustering-unsupervised-learning-algorithms-5cc5acea274d?source=collection_archive---------20-----------------------
看完这个保证你理解无监督学习的原理。
Andrew looks very young when he taught this course!
摘要
和往常一样,为了节省你的时间(我知道这里的文章太多了,你的时间很宝贵),我准备先写这篇文章的摘要。
在这篇文章中,我谈到了无监督学习算法,包括 K-means 聚类,PCA。对于这些算法,我谈到了它们的应用、优缺点。这里没有代码和数学公式,如果你想学习算法的数学理论,谷歌一下就行了,维基百科上有很多;如果你想看一些真实项目中无监督学习的代码示例,只需给我留言,我会再贴一个。
我确定你看完这个就能明白什么是无监督学习了;里面有 gif 图片帮助你理解。
“因为我们不给它答案,所以是无监督学习”
监督学习和非监督学习的主要区别在于,在非监督学习中,数据没有标签。
在监督学习中,系统试图从给定的样本中学习(另一方面,在无监督学习中,系统试图直接从给定的样本中找到模式)。所以如果数据集有标签,那就是监督问题。如果数据集没有标签,那就是无监督问题。
上面的左图是监督学习的一个例子:我们使用回归方法来寻找特征之间的最佳拟合线。
在无监督学习中,基于特征隔离输入,基于特征所属的聚类生成预测。
使聚集
k 均值聚类
K-均值聚类的过程:
优点
- 快速、健壮且易于理解。
- 相对高效:O(tknd),其中 n 是#个对象,k 是#个簇,d 是每个对象的#个维度,t 是#次迭代。正常情况下,k、t、d << n.
- Gives the best result when the data set is distinct or well separated from each other.
缺点
- 学习算法需要预先指定聚类中心的数量。
- 使用排他赋值-如果有两个高度重叠的数据,那么 k-means 将无法解析出有两个聚类。
- 学习算法对于非线性变换不是不变的,即,对于不同的数据表示,我们得到不同的结果(以笛卡尔坐标和极坐标形式表示的数据将给出不同的结果)。
- 欧几里德距离度量可以不相等地加权潜在的因素。5)学习算法提供*方误差函数的局部最优。
- 随机选择聚类中心无法让我们获得丰硕的成果。
- 仅在定义*均值时适用,即分类数据不适用。
- 无法处理噪音数据和异常值。
- 该算法不适用于非线性数据集。
主成分分析
特征降维是无监督学习的另一个应用。
有两个目的:
- 第一,我们在实际项目中经常会遇到特征维度非常高的训练样本,往往我们无法用自己的领域知识人工构造有用的特征;
- 第二,在数据表现上,我们无法用人眼观察到超过三个维度的特征。
因此,特征降维不仅重构了有效的低维特征向量,而且为呈现的数据提供了一种方法。
在特征降维方法中,主成分分析是最经典、最实用的特征降维技术,尤其是在图像识别领域。
参考资料:
[## k 均值聚类
k-means 聚类是一种矢量量化的方法,起源于信号处理,在聚类分析中很流行。
en.wikipedia.org](https://en.wikipedia.org/wiki/K-means_clustering)
https://www.youtube.com/watch?v=Ev8YbxPu_bQ
最初发表于T5【https://www.linkedin.com】。 但是, 这是一个 修改后的 版本。
A*搜索简介
原文:https://towardsdatascience.com/intro-to-a-search-a3dfa444ad20?source=collection_archive---------36-----------------------
解释和实施
我们已经讨论过广度优先搜索和深度优先搜索这里,它们都有点残酷。考虑到搜索树太宽或太深的情况,这些算法可能会花费大量时间在无意义的搜索中徘徊。那么,我们有没有可能在搜索算法中加入一点智能呢?能否对环境有一个大概的估计,并整合到模型中?答案将我们引向 A*搜索。
*的想法
A的大图与 first-search 没有什么不同,而 BFS 以广度为优先,DFS 以深度为优先,A也有自己的优先——路径的成本加上我们的估计(或启发式)的组合。
假设我们现在在 A 点,准备移动到 B 点,目标是 c 点。从 A 点移动到 B 点有一个自然成本g(B)
,在 BFS 可能是 1。与 BFS 不同,这里我们加上我们对从 B 到 C 的距离的另一个成本的估计,A*的成本就是g(B) + h(B)
。
很明显,A*的优势在于我们添加了额外的环境信息,如果启发式算法选择正确,它将为我们提供从当前节点到目标的真实成本的更好估计。问题是如何选择一个好的启发式,我们来举个例子。
履行
我们将使用上述相同的示例:
在网格世界中,我们从左上角开始,找到到达右下角的路径。我们为每个网格生成的启发是直接的——简单地说就是从每个点到目标的最小距离。注意启发式必须是 可接受的 ,也就是说你的启发式必须小于最优路径:
其中h(n)
是我们的启发式算法,h^*(n)
是最优的。实际上,我们肯定不知道最优路径,但是我们可以设置一些宽松的条件来帮助我们生成一个绝对小于最优路径的启发式算法(在这里,我们简单地忽略这些块)。
实现与我们上面介绍的第一个搜索基本相同,唯一的区别在于我们如何引入启发式成本。
在扩展树之前,我们设置初始成本f
:
h = heuristic[x][y]
f = g + h
在每个循环中,我们更新了每个子节点的启发式成本:
h2 = heuristic[x2][y2]
g2 = g + cost
f2 = g2 + h2
open.append([f2, g2, x2, y2])
添加了f
作为第一个元素,以便开放列表总是能够探索具有最低成本的节点。
我们得到的结果是:
[[0, -1, -1, -1, -1, -1],
[1, -1, -1, -1, -1, -1],
[2, -1, -1, -1, -1, -1],
[3, -1, 8, 9, 10, 11],
[4, 5, 6, 7, -1, 12]]
其中-1
是算法没有搜索到的区域,看看算法是如何避开右上角的大量节点的。由于启发式算法增加了算法探索它们的额外成本,它们最终没有被优先考虑。
最佳性
如果试探法是可接受的,那么 A*搜索是最优的。
容许使得无论您扩展哪个节点,它都确保当前估计值总是小于最优值,因此将要扩展的路径有机会找到最优路径。考虑上述示例中最简单的启发式算法,使启发式算法中的所有值都为 0,算法变成提供最优解的广度优先搜索。但是试探法越接*最优真值,算法就越有效,认为如果我们有一个试探法精确地给出每个节点的最优估计,那么算法将直接沿着正确的路径以最小的扩展到达目标。
参考:
- https://classroom . uda city . com/courses/cs 373/lessons/48646841/concepts/112 e9f 79-63cd-44ee-883 f-652677 e64d 31
贝叶斯统计简介
原文:https://towardsdatascience.com/intro-to-bayesian-statistics-5056b43d248d?source=collection_archive---------8-----------------------
通过贝叶斯定理快速介绍贝叶斯推理
数据科学中最常用的统计分支是频率统计。我们都在使用它的概念和思维方法,甚至不知道它或它的替代品。作为数据科学家,在我们的工具箱中拥有多种工具最符合我们的利益。在这篇文章中,我将借助我们在学校都学过的东西:贝叶斯定理,介绍另一个被称为贝叶斯统计的分支。
Bayes Theorem
以上是贝叶斯定理的表达式,我们都很熟悉。它使用条件概率和正态概率,并输出给定的 B 发生的概率。但是这些术语还有另一种解释:
Bayes Theorem
先验指的是我们持有的任何先入为主的观念或信念
可能性指的是假设我们的先验是真实的,观察到我们所做的事情的概率
后验指的是以我们所观察到的为条件的更新后的先验
归一化因子用于确保后验概率不大于 1
但是为了这篇文章,我们将只关注前三个术语,我将借助几个例子来解释更多
笔记本电脑充电问题:
笔记本电脑已经成为我们生活中无处不在的一部分,用于从娱乐到工作的方方面面。想象一下这样一种情况,您已经将笔记本电脑的电池电量充到了 100%,并且正在使用它。您发现电池电量越来越低,决定给笔记本电脑插上电源。你插上电源,但看到你的笔记本电脑没有充电。
嗯,你今天才充电,所以问题一定出在插头上,而不是充电器上。在这种情况下,你的先验是你的充电器工作正常,你的可能性是假设你的充电器工作正常,笔记本电脑不充电的概率,以及假设笔记本电脑不充电,你的充电器工作正常的后验概率。
回到你的情况,你决定尝试另一个插头点,因为你相信你的充电器是好的。但是,您再次注意到您的笔记本电脑没有充电。现在你对你的充电器有一个挥之不去的疑问。在这种情况下,你的先验不再是你的充电器是好的,而是受到你之前观察到的影响。
现在,您尝试使用另一个插头,并观察到您的笔记本电脑仍然无法充电。同样,你改变或更新了你之前的信念,即你的充电器是好的,这是基于你到目前为止所经历的。最终,经过几次尝试后,你意识到问题出在你的充电器上,而不是任何插头上。
你开始时相信你的充电器很有可能是好的,后来根据你的经验,你的充电器慢慢变坏了。
让我们看另一个例子,一个我们更熟悉的例子。
罕见病检测试验:
在一个人群中,有 0.1%的人有机会患上特别罕见的疾病。可以进行测试来检查其存在,该测试可以以 99%的准确度进行检测,并且具有 1%的假阳性率。在这种情况下,如果一个人检测呈阳性,他患这种疾病的可能性有多大?
P(A) —患该疾病的概率(代表他先前的知识和信念)
P(B|A) —假设他患有疾病,测试为真的概率(可能性)
P(A|B) —在测试为真的情况下患病的概率(后验或更新的先验/信念)
这种情况下的后验概率是:
(. 99 * . 001)/(. 99 * . 001+. 01 * . 999)= 0.09 或 9%
基于他的测试结果,他更新了他先前的信念。他之前的信念是从 0.1%的患病几率到 9%的患病几率。
可以肯定的是,他又进行了一次测试,但这次先验不再是 1%,而是前一次测试的后验 9%。
在这种情况下,后验概率为:
(. 99.09)/(.99.09+.1*.91) = 0.91 或 91%
如果第二次测试结果是肯定的,信念又会发生变化,而且这次变化很大。从 9%的人认为患有这种疾病到现在的 91%。
虽然第二种情况涉及到客观价值的使用,但并不总是如此。在第一个例子中,先验更加主观,因为你根据你的信念给它赋值。你可能 90%或 99%确定你的充电器工作正常。并且随着每次试验,该值减小,直到它开始趋向于零。
我们现在看到的是被称为贝叶斯更新或贝叶斯推理的过程。它被定义为随着更多的证据和数据变得可用而更新假设的概率的过程。贝叶斯统计下的很多技术和算法都涉及到上述步骤。它从基于用户估计的先验信念开始,并根据观察到的数据进行更新。这使得贝叶斯统计更加直观,因为它更符合人们的思维方式。
与频率统计相比,贝叶斯统计的另一个更直观的方面是它对概率的解释。在频率主义统计学中,概率被解释为某一事件在长期内或在大量人群中发生的可能性。而在贝叶斯统计中,概率被解释为人们直觉上所做的,即相信某事发生的程度。在第二个例子中,一个频繁主义者的解释是,在 1000 人中,可能有一个人患有这种疾病。然而,在贝叶斯解释中,更多的是关于一个人患这种疾病的可能性。
让我们再举一个例子来说明这一点,这次是抛硬币。频率主义者的解释是,给定一枚硬币被投掷多次,50%的情况下我们会看到正面,其他 50%的情况下我们会看到反面。贝叶斯的解释是,当我们扔硬币时,有 50%的几率看到正面,有 50%的几率看到反面。
Reverend Thomas Bayes
当情况或事件不需要时,沿着贝叶斯思路思考也会有陷阱。这方面的一个例子是赌徒谬误。在这种情况下,人们基于对某些事件的观察做出决定,即使这些事件本身可能是相互独立的。在这里,你过去的经历塑造了你的信念,导致你对未来做出错误的决定。虽然人们假设某件事发生得越频繁,它在未来发生的可能性就越小,但这有一点不同,但思维过程仍然是贝叶斯的。
总之,虽然频率统计被更广泛地使用,但这并不意味着贝叶斯统计没有自己的位置。它仍然是一个广阔的领域,历史上有许多应用。随着许多针对 R 和 Python 的开源库的发布,它的使用出现了复苏。属于这一类并且经常使用的一些技术是马尔可夫链、隐马尔可夫模型和马尔可夫链蒙特卡罗。正如我上面所写的,在你的工具箱里多一个工具总是好的。
个人注释:我只是在攻读硕士学位时才了解到贝叶斯定理的这种解释。这就像是我有了一个顿悟,我决定这无疑是一个正确的决定,在那里做我的主人的权利😆。托马斯·贝叶斯牧师的天才之处在于,他能够将人们思考和决策的方式用数学符号表示出来。对我来说,正是这一点让贝叶斯定理变得非常神奇。
你也可以在 LinkedIn 上和我联系。
用 Python 介绍比特币、区块链和采矿
原文:https://towardsdatascience.com/intro-to-bitcoin-blockchain-and-mining-with-some-python-ee0765b6079b?source=collection_archive---------8-----------------------
大家好,希望你们都过得很好!本文将粗略介绍比特币、区块链技术和比特币挖矿。我从未真正深入了解加密货币,但一位朋友最*想把它应用到他的工作中,并向我询问了这方面的情况。很自然,我很好奇,想和大家分享我的发现。
比特币
比特币是电脑化的现金。这意味着它只是以电子记录的形式存在,与实物现金不同,你无法掌握它。你可以利用比特币发送和获取现金,比如用比特币支付物品和行政费用。基本上,比特币与常规现金兼容。
有些交易所可以买卖比特币。此外,还有其他一些加密货币,但比特币是第一种也是最大的一种。比特币使用分布式账本工作,没有像银行和监管交易所那样的中央机构[1]。比特币是开源的。所以,没有人拥有或控制比特币,每个人都可以利用它。历史上没有先例,个人可以与更少的中间商交易,这意味着更有效的转移和更低的费用。
区块链
直截了当地说,区块链是一个先进的记录。这是比特币交易的公开记录,是按顺序请求编排的。这是一个未经许可的专用数据库,依赖于比特币惯例,保持着基于价值的信息记录的不断发展。它被传播,所以每个成员都有整个区块链的复制品。区块链由所有比特币客户共享。
它被用来检查比特币交易所的永久质量,并预测双重支出。它是安全的、不变的,而且它同样是固定的,不会被更改和修改,甚至是被信息存储中心的管理员更改和修改。
每一项区块链记录都经过加密授权,主机运行机器充当信息存储中心。区块链是由正方形组成的。一个广场是一个记录,在区块链,包含和肯定了许多举行交流。
一般来说,每隔一段时间,另一个包含交易所的广场通过采矿被并入区块链。这是一个被称为比特币区块链的记录,它存在于世界各地的大量个人电脑上,甚至可能在家里没有其他人的电脑的情况下。这份文件包含了几乎所有比特币交易的信息,也就是说,从一个记录开始,然后到下一个记录的比特币分期付款。这通常被称为记录,类似于银行记录,记录分期付款。
比特币和区块链的好处
对于比特币:
- 快速支付:用比特币支付非常简单快捷。比特币交易所一直都是开着的,即使是在假期。全球汇款同样简单。没有银行让任何人坚持三个工作日,没有进行全球交换的额外费用,也没有对一个人可以发送的基本或最极端金额的独特限制。
- 保护:可以利用比特币进行分期付款,而无需共享任何接*家庭的数据;人们不必加入或共享任何卡数据。事实上,甚至可以想象在不暴露一个人的个性的情况下发送分期付款,实际上就像你可以用实物现金一样。在任何情况下,观察可能需要一些努力来确保安全。
- 不相关的兑换费用:用比特币分期付款几乎没有或可以忽略不计的兑换费用。获得比特币不需要任何费用,拥有众多钱包让你能够控制消费时要支付的费用。大多数钱包都有合理的默认费用,更高的费用可以支持更快地确认你的交易。费用对于转移的金额来说是无关紧要的,所以发送 10 万个比特币的费用和发送一个比特币的费用差不多是可以想象的。
- 安全:比特币是以电子方式制造和持有的,但其中没有任何人可以拿走的签证号码,因为没有人会因为你的缘故向你收取现金。这种交换是利用军用级加密技术进行的,并且是非常机密的。比特币将让你能够完全控制你的现金,并在很大程度上防范包括某些手段在内的各种各样的虚假作品。
- 多重签名:比特币的多重签名功能允许组织完全控制自己的支出,只要一部分人同意交易,就可以使用比特币。
从上面这张取自 Stackexchange 的图片来看,比特币基本上是通过公钥保护用户的假名[3]。对于多重签名事件,公钥基本上被分解为如何组合多个密钥来批准多重签名验证。如何在 Python 中生成密钥的示例如下所示:
上面的代码和其他好东西可以从这里下载。
对于区块链:
- 区块链是比特币背后的创新。它就像所有比特币交易所的数据库一样工作,它保留了自绝对第一次交易所以来比特币交易所的所有记录。区块链创新的潜在和最广为人知的用途是比特币交易所的公开记录。尽管如此,无论如何,先进的货币标准并不是区块链创新的唯一用途。
- 区块链是一个基于不信任的框架,可以用来领导广泛的交流,例如,计算机化的协议标记。可以利用区块链创新来建立一个持久、开放、简单的记录框架,用于安排交易信息、通过验证版权登记来保存权利信息等。
比特币挖矿
比特币采矿增加了世界上更多的比特币,当发现比特币时,矿工会获得金钱奖励。每一个比特币挖掘者都通过算术计算参与到挖掘比特币的各种方式中。然而,随着时间的推移,计算变得更加复杂,开采硬币需要更长的时间。这个时间长度增加了开采硬币的成本。
任何人都可以通过运行电脑程序对比特币挖矿产生兴趣。尽管在传统的个人电脑上运行,一些组织已经计划了特殊的比特币挖掘设备,可以处理硬币,大大缩短挖掘时间[4]。由于来自其他矿商的竞争加剧,比特币变得越来越昂贵。全球众多超级计算机正在竞相挖掘下一个比特币。随着比特币挖掘者数量的扩大,开始挖掘新的比特币变得越来越棘手,也越来越被高估[5]。
结论
所以,我们讨论了比特币、区块链和比特币挖矿。从制造比特币的基础技术——区块链来看,比特币非常有趣。通过观看关于比特币的纪录片,我确实认为比特币的持有者有交易价值,不像其他人可能会说比特币没有增加价值。至于区块链,我真的很喜欢它运作的不信任的想法是如何做非常有趣的记录。我认为这对数据完整性非常有用,这可能是为什么你们中的一些人会在新闻中读到供应链如何应用区块链的原因。关于采矿的最后一点,就是不要去做。现在成本太高了,你只需购买比特币,希望它升值,风险就会降低。就个人而言,我现在并不积极交易加密货币,但这主要是因为我发现目前更有利可图的其他投资策略。
Github 链接为代码:
https://github.com/LesterALeong/Generating-Bitcoin-Keys
免责声明:本文陈述的所有内容均为我个人观点,不代表任何雇主。投资有很大的风险。在进行任何投资之前,请咨询您的财务专家,所有信息仅供教育之用。
[1] Garg,H. K. (2018)。用 Python 进行比特币编程实践:用 Python 构建强大的在线支付应用。伯明翰:包装出版公司。
【2】纽比,t . g .&拉兹马兹马,A. (2018 年 4 月 9 日)。无法追踪的货币?比特币隐私问题——金融科技周刊。检索自https://www . fintechweekly . com/magazine/articles/an-无法追踪-货币-比特币-隐私-关注。T5【约阿希姆】③。(2018).从钱包里消费硬币后,私钥会公布到区块链吗?检索自https://bit coin . stack exchange . com/questions/1819/are-private-keys-published-to-the-区块链 after-spending-coins-from-a-wallet。
[4]Bitcoin.com。(2019).比特币挖矿池。从 https://mining.bitcoin.com/.取回
[5] Fortney,L. (2019 年 6 月 25 日)。比特币挖矿,解释过。从 https://www.investopedia.com/terms/b/bitcoin-mining.asp.取回
信用记分卡简介
原文:https://towardsdatascience.com/intro-to-credit-scorecard-9afeaaa3725f?source=collection_archive---------1-----------------------
如何建立一个简单的信用记分卡的分步指南
Source: NerdWallet
背景
随着金融科技初创企业的崛起,过去 5 年里出现了许多新的消费信贷机构,与传统银行展开竞争。它们通常瞄准银行认为规模太小的利基市场,或在金融危机期间因亏损而不得不削减放贷的市场。
这些新的纯在线消费贷款机构的主要竞争优势之一是技术元素,没有每个大型银行都有的传统 it 系统的拖累,他们建立了更快、无纸化、更用户友好的移动界面系统,并在承保流程中利用除传统金融数据之外的新数据源。
例如,商业贷款机构 iwoca 使用关联公司账户、增值税申报表甚至 ebay 或亚马逊上的销售交易信息来确定新贷款。消费者贷款银行 lendable 引以为豪的是在几分钟内给出个性化的贷款报价,而不是传统银行需要的几天或几周。
随着快速和自动决策的承诺,他们回复到拥有自动和快速的信用风险模型来评估风险。在这篇文章和后面的文章中,我打算介绍消费金融信用风险领域最常用的机器学习模型。
什么是信用记分卡
Photo by The New York Public Library on Unsplash
我们大多数人都熟悉信用评分的概念,这是一个代表个人信誉的数值。像银行这样的所有信贷机构都有复杂的信贷模型,这些模型使用应用程序中包含的信息,如工资、信贷承诺和过去的贷款业绩,来确定应用程序或现有客户的信用评分。该模型输出一个分数,该分数表示如果贷方向某人提供贷款或信用卡,该贷方按时还款的可能性有多大。
信用记分卡就是这样一种信用模型,它是最常见的信用模型之一,因为它对客户来说相对容易解释,并且它已经存在了几十年,因此开发过程是标准的,并且被广泛理解。
但是,值得注意的是,分数的范围可能因机构而异,拒绝分数较低的申请的截止点可能因贷款人而异,甚至可能因同一贷款人但不同产品而异。
建立信用记分卡
T 目标变量通常采用二进制形式,根据数据的不同,对于履约客户,它可以是 0,而对于违约客户或逾期付款超过 90 天的客户,它可以是 1。在本文的其余部分,我们将把“坏客户”称为某种违约的客户,而把其他客户称为“好客户”。
步骤 1:数据探索和清理
这是所有模型拟合中的一个基本步骤,但由于它不是专门针对构建信用记分卡模型的,所以我们将跳过这一部分。不要忘记将数据集分为训练数据集和测试数据集。
步骤 2:数据转换—证据权重法
然后,我们需要转换所有的独立变量(如年龄、收入等。)使用证据权重法。该方法基于每个分组级别的好申请人与坏申请人的比例,测量分组的“强度”以区分好的和坏的风险,并试图找到自变量和目标变量之间的单调关系。
连续变量的变换步骤:
- 将数据分成多个箱,通常大约 10 个,最多 20 个
- 计算好事件的百分比和坏事件的百分比
- 通过取自然对数来计算 WOE
- 用计算出的 WOE 值替换原始数据
如果自变量是分类变量,那么跳过上面的 1,并遵循剩下的步骤。
用 Python 举例:
将您的数据放入箱中,并对每个箱的坏计数和好计数进行分组,以便您的数据看起来类似于下面的方框。对于每个 bin 组,可以使用下面的代码计算 WoE。负值表示特定分组中不合格申请者的比例高于合格申请者。
在转换结束时,如果开始时有 20 个独立变量,那么下一步将有 20 个 WOE_variablename 列。
使用 WoE 转换的好处:
- 它有助于与逻辑回归中使用的对数优势建立严格的线性关系
- 它可以处理丢失的值,因为这些值可以合并在一起
- 异常值或极值可以被处理,因为它们也被分箱,并且馈入模型拟合的值是经过 WoE 变换的值,而不是原始极值
- 它还处理分类值,因此不需要虚拟变量
步骤 3:使用信息值进行特征选择
信息值(IV)来源于信息论,它度量自变量的预测能力,这在特征选择中是有用的。执行特征选择以确定是否有必要在模型中包含所有特征是一种良好的做法,大多数情况下,我们会希望消除弱的特征,因为更简单的模型通常是首选的。
根据 Siddiqi (2006),按照惯例,信用评分中 IV 统计值可以解释如下
用 Python 举例:
继续前面的示例,这里我们计算出“年龄”的 IV 约为 0.15,这意味着年龄具有“中等预测能力”,因此我们将保留用于模型拟合。IV 值小于 0.02 的变量应被删除。
步骤 4:模型拟合和解释结果
现在,我们使用新转换的训练数据集的权重来拟合逻辑回归模型。
当将模型缩放到记分卡中时,我们将需要模型拟合的逻辑回归系数以及转换后的 WoE 值。我们还需要将模型中的分数从对数优势单位转换为分数系统。
对于每个自变量 Xi,其对应的得分是:
Score_i= (βi × WoE_i + α/n) ×因子+偏移量/n
其中:
βi —变量 Xi 的逻辑回归系数
α —逻辑回归截距
WoE —变量 Xi 的证据值权重
n —模型中自变量 Xi 的个数
因子,偏移量—称为标度参数,其中
- 因子= pdo/ln(2)
- 偏移量=目标分数-(因子× ln(目标赔率))
对于上面的例子,我们选择 600 的目标分数来表示好客户对坏客户的赔率为 50 比 1,20 的增加意味着双倍的赔率。注意比例的选择不影响记分卡的预测力度。
最终总得分是基于自变量输入值的所有得分的总和。然后,贷方将根据模型化的总分和截止点(根据其他信用违约模型设定)评估收到的申请。
总分=σScore _ I
An example of scorecard implementation, source { Credit Scoring — Scorecard Development Process by Sandy Liu, link at end of of this post}
来源
- 证据权重和信息价值说明
- 逻辑回归中用 WoE 代替变量
- 信用评分—记分卡开发流程
- 通过机器学习进行信用评分
数据科学简介
原文:https://towardsdatascience.com/intro-to-data-science-531079c38b22?source=collection_archive---------2-----------------------
学习数据科学的循序渐进指南
Source: Freepik
观看体育比赛总是很有趣,我们都有自己喜欢的俱乐部。我们总是和我们的朋友和同事讨论哪个俱乐部会赢得 EPL,这些讨论是基于我们的直觉,也许是基于最*的偏见。做出明智猜测的更好方法是利用数据来预测 EPL 奖得主。
数据科学
但首先,让我们先来了解一下什么是数据科学?
- 你有没有想过亚马逊、易贝是如何向你推荐商品的?
- Gmail 如何过滤垃圾邮件和非垃圾邮件?
- 网飞如何预测你喜欢的节目?
他们是怎么做到的?这是我们时常思考的几个问题。实际上,如果没有数据,完成这些任务是不可能的。数据科学就是用数据来解决问题。问题可能是决策,如识别哪些电子邮件是垃圾邮件,哪些不是。或者是看哪部电影之类的产品推荐?或者预测结果,比如谁将成为下一任美国总统?因此,数据科学家的核心工作是理解数据,从中提取有用的信息,并应用这些信息解决问题。
What is Data Science?
一个比任何软件工程师更擅长统计,比任何统计学家更擅长软件工程的人。
—乔希·威尔斯
Video: Quick Introduction to Data Science
读完这篇文章后,你将能够
- 讲解 数据科学 中的步骤
- 应用这些步骤预测 EPL 获奖者
- 解释数据质量的重要性
- 定义数据收集方法
数据科学生命周期
步骤 1:定义问题陈述
创建定义良好的问题陈述是数据科学的第一步,也是关键的一步。它是对你要解决的问题的简要描述。
但是为什么我们需要一个定义良好的问题陈述呢?
一个定义明确的问题是一个解决了一半的问题。
—查尔斯·凯特林
还有,你在定义了问题语句之后所做的一切努力和工作,都是为了解决它。问题陈述由您的客户分享。你的客户可以是你的老板、同事,也可以是你的个人项目。他们会告诉你他们面临的问题。下面是一些例子。
- 我想增加收入
- 我想为我的信贷部门预测贷款违约情况
- 我想把这份工作推荐给我的客户
大多数时候,这些最初与你分享的问题是模糊不清的。例如,问题陈述:“我想增加收入”,并没有告诉你增加多少收入如 20%或 30%,为哪些产品增加收入,增加收入的时间框架是什么。你必须把问题陈述清楚,目标明确,可衡量。这可以通过问一系列正确的问题来实现。
“获得正确的问题是获得正确答案的关键。”
杰夫·贝索斯
如何提出更好或正确的问题来创建一个定义良好的问题陈述?你应该问开放式问题,而不是封闭式问题。开放式问题有助于发现未知的未知。未知的未知是你不知道你不知道的事情。
Source: USJournal
我们将研究一个问题陈述“哪个俱乐部会赢得 EPL 奖?”
第二步:数据收集
你需要收集有助于解决问题的数据。数据收集是从各种来源收集相关信息的系统方法。根据问题陈述的不同,数据收集方法大致分为两类。
首先,当你有一些独特的问题,而没有相关的研究做这个主题。然后,你需要收集新的数据。这种方法被称为原始数据收集。例如,您想要跨公司员工在自助餐厅花费的*均时间的信息。没有这方面的公开数据。但你可以通过各种方法收集数据,如调查、采访员工以及监控员工在自助餐厅的时间。这种方法很费时间。
另一种方法是使用现成的或由他人收集的数据。这些数据可以在互联网、新闻文章、政府人口普查、杂志等等上找到。这种方法被称为二次数据收集。这种方法比主要方法耗时少。
为我们的 EPL 问题陈述。您可以从各种开源网站(如 Github、Kaggle 和 datahub)收集和汇总数据。
Table 1: Snapshot of data collected from web sources
第三步:数据质量检查和修复
数据科学家最重要但经常忽略的一个方面是确保用于分析和解释的数据质量良好。
收集完数据后,大多数人开始对其进行分析。通常,他们会忘记对数据进行完整性检查。如果数据质量不好,它会给出误导性的信息。简单的说:“垃圾进,垃圾出”。
例如,如果您在没有确保数据质量的情况下开始分析。那么你可能会得到意想不到的结果,如水晶宫俱乐部将赢得下一届 EPL。然而,你对 EPL 的领域知识表明,这个结果看起来并不准确,因为水晶宫甚至从未进入前 4 名。
第四步:探索性数据分析
在你模拟出解决方案的步骤之前,分析数据是很重要的。这是最令人兴奋的一步,因为它有助于您熟悉数据并获得有用的见解。如果您跳过这一步,那么您可能会最终生成不准确的模型,并在您的模型中选择无关紧要的变量。
正如探索性数据分析的开发者约翰·图基所说,
在你学会衡量你做得有多好之前,了解你能做什么是很重要的
但是这可能会很费力和困难。有没有工具或技术可以有意义地探索数据?
是的,您可以使用描述性统计,如中心值度量和可变性度量。此外,可视化方法,如图表和绘图,可用于分析。
例如,你可以计算每场比赛的*均进球数。还可以查一下主场优势是不是真的?
下面的柱状图展示了利物浦的主场优势。它显示,在利物浦的所有主场比赛中,他们赢了 17 场,*了 2 场。但从未输过任何一场主场比赛。
Chart 1: Home Advantage for Liverpool [1]
但是,没有莱斯特的主场优势。显示莱斯特所有主场比赛,他们 8 胜 8 负 3 *。
Chart 2: No home Advantage for Leicester [1]
资料来源:Quantra 的《数据科学导论》
数据分析是一个迭代过程,可以帮助您更接*解决方案。每次迭代都有相关的成本。因此,作为一名数据科学家,建议您进行适当的规划,以减少迭代次数。你可以玩数据,创建自己的图表,并学习推导推论。您执行的所有这些分析通常被称为探索性数据分析(EDA)。
第五步:数据建模
建模意味着制定每一个步骤,并收集实现解决方案所需的技术。你需要列出计算的流程,这只是解决方案的建模步骤。重要的因素是如何进行计算。统计和机器学习下有各种技术,你可以根据需求选择。
对于 EPL 的数据,我们选择使用统计技术来预测当前赛季的冠军。
Figure 1: Data Modelling Steps [1]
前 6 名团队
根据过去三个赛季的数据,我们知道 EPL 的冠军在变,但是前六名的俱乐部保持不变。这些俱乐部是阿森纳、切尔西、利物浦、曼城、曼联和热刺。下赛季的冠军极有可能来自这 6 强球队。
根据球员技能对俱乐部进行排名
众所周知,在足球中,一名球员可以是进攻者、防守者、中场或守门员。这些职位中的每一个都需要不同的身体技能。一名球员根据他的身体技能和他所踢的位置来得分。分数以 0-100 分制给出。每项技能都有一个权重。
Table 3: Player skills by Club. [1] and [2]
根据过去的表现对俱乐部进行排名
我们根据上个赛季的胜场数和进球数对球队的表现进行排名。
Table 4: Club last season performance.
结合排名预测赢家
考虑到 80%的权重给球员的技术,20%的权重给俱乐部过去的表现,我们得到了前 6 名俱乐部的最终排名。
根据这些计算,托特纳姆热刺队很可能赢得本届 EPL。
Table 5: Combining Player skills and Past Performance
步骤 6:数据通信
Source: Freepik
这是最后一步,在这一步中,您将向风险承担者展示您的分析结果。你向他们解释你是如何得出一个具体的结论和你的重要发现的。
大多数情况下,您需要向非技术受众展示您的发现,例如营销团队或业务主管。你需要以简单易懂的方式传达结果。利益相关者应该能够从中得出一个可行的计划。
但是在交流结果时,你需要记住哪些重要的事情呢?
- 了解你的听众,说他们的语言
你应该了解你的听众,说他们的语言。例如,你正在向一个足球迷展示 EPL 奖得主的预测。他们不理解你所使用的统计数据,但他们能理解你决定赢家的步骤。
2。关注价值和结果
你应该关注价值和结果。你的利益相关者不会对你如何获得数据感兴趣,而是对你从哪里获得数据感兴趣。使用可靠的来源有助于建立对你预测的信心。
3。传达假设和限制
你应该清楚地传达你所做的重要假设和限制。例如,为了计算团队的总体评分,您假设所有团队采用 3–4–3–1 阵型。将这些传达给利益相关者是很重要的。
尽管我们的目标是预测获胜者,但可能还有其他一些相关的重要发现。比如进攻、中场、防守、守门员最好的球队。根据球员的技术,联盟中每个位置的最佳球员。这种以图形、图表和数字形式显示数据的统一视图称为仪表板。您可以使用 Excel 创建仪表板。
现在,轮到你了。以数据科学家的身份解决一个问题。
快乐学习!
来源和参考文献
- 数据科学简介
- 英超联赛统计数据
- 维基百科:数据科学
深度学习完全初学者指南
原文:https://towardsdatascience.com/intro-to-deep-learning-c025efd92535?source=collection_archive---------7-----------------------
为新手、新手和新手征服神经网络
Photo by ibjennyjenny on Pixabay
我们生活在一个无论好坏都不断被深度学习算法包围的世界里。从社交网络过滤到无人驾驶汽车到电影推荐,从金融欺诈检测到药物发现到医学图像处理(…那是肿块癌吗?),深度学习领域每天都在影响着我们的生活和决定。
事实上,你现在可能正在阅读这篇文章,因为深度学习算法认为你应该看到它。
Photo by tookapic on Pixabay
如果你正在寻找深度学习的基础知识,人工神经网络,卷积神经网络,(一般的神经网络…),反向传播,梯度下降,等等,你来对地方了。在这一系列文章中,我将尽可能简单易懂地解释这些概念。
还会有猫。
有了一点傻气,学习就容易多了。
Photo by skeeze on Pixabay
如果你进入深度学习,会有大量非常深入的信息。我会确保为那些想在这些水域游得更深的人提供额外的资源。(例如,你可能想看看 Yann LeCun 等人的高效反向投影,这是深度学习领域最重要的人物之一写的。本文特别关注反向传播,但也讨论了深度学习中一些最重要的主题,如梯度下降、随机学习、批量学习等。想看的都在这里!)
现在,让我们开始吧!
Photo by Laurine Bailly on Unsplash
什么是深度学习?
真的,只是 学例 。差不多就是这样。
在非常基础的层面上,深度学习是一种机器学习技术,它教会计算机通过各层过滤输入(图像、文本或声音形式的观察),以学习如何预测和分类信息。
深度学习的灵感来源于人类大脑过滤信息的方式!
Photo by Christopher Campbell on Unsplash
本质上,深度学习是基于学习数据表示(而不是特定任务的算法)的机器学习家族的一部分。深度学习实际上与认知神经科学家在 90 年代初提出的一类关于大脑发育的理论密切相关。就像在大脑中一样(或者更准确地说,在 20 世纪 90 年代研究人员关于人类新大脑皮层发展的理论和模型中),神经网络使用分层过滤器的层次结构,其中每一层都从前一层学习,然后将其输出传递给下一层。
深度学习试图模仿新大脑皮层中多层神经元的活动。
在人类大脑中,大约有 1000 亿个神经元,每个神经元都与大约 100,000 个相邻的神经元相连。从本质上说,这就是我们试图创造的,但在某种程度上是为机器服务的。
Photo by GDJ on Pixabay
深度学习的目的是模仿人脑的工作方式,以便创造一些真正的魔法。
这对神经元、轴突、树突等意味着什么?神经元有一个体,树突和一个轴突。来自一个神经元的信号沿着轴突传递,并被传递到下一个神经元的树突。传递信号的连接(不是实际的物理连接,但仍然是连接)被称为突触。
Photo by mohamed_hassan on Pixabay
神经元本身是没什么用的,但是当你有很多神经元时,它们会一起工作,创造出一些神奇的东西。这就是深度学习算法背后的想法!你从观察中得到输入,你把你的输入放入一个层,这个层产生一个输出,这个输出反过来成为下一层的输入,等等。这种情况反复发生,直到你的最终输出信号!
因此,神经元(或节点)获得一个或多个信号(输入值),该信号通过神经元,并传递输出信号。把输入层想象成你的感官:你看到的,闻到的,感觉到的,等等。这些是一次观察的独立变量。这些信息被分解成数字和计算机可以使用的二进制数据位。(您需要标准化或规范化这些变量,以便它们在相同的范围内。)
我们的产值可以是多少?可以是连续(比如价格)二元(是或否),也可以是分类(猫、狗、驼鹿、刺猬、树懒等。).如果是分类的,你要记住你的输出值不会只是一个变量,而是几个输出变量。
Photo by Hanna Listek on Unsplash
此外,请记住,您的 r 输出值将始终与来自输入值的同一个观察值相关。例如,如果您的输入值是对一个人的年龄、工资和车辆的观察,那么您的输出值也将与同一个人的相同观察相关。这听起来很基本,但是记住这一点很重要。
那么突触呢?每个突触都被分配了权重,这对人工神经网络 (ANNs)至关重要。重量是人工神经网络学习的方式。通过调整权重,人工神经网络决定信号传递的程度。当你训练你的网络时,你决定如何调整权重。
神经元内部发生了什么?首先,它得到的所有值相加(计算出加权和)。接下来,它应用一个激活函数,这是一个应用于这个特定神经元的函数。由此,神经元知道是否需要传递信号。
这样重复几千甚至几十万遍!
Photo by Geralt on Pixabay
我们创建了一个人工神经网络,其中有用于输入值(我们已经知道的/我们想要预测的)和输出值(我们的预测)的节点,在这些节点之间,我们有一个隐藏层(或多个层),信息在到达输出之前会在其中传播。这类似于你通过眼睛看到的信息被过滤到你的理解中,而不是直接进入你的大脑。
Image by Geralt on Pixabay
深度学习模型可以是有监督的、半监督的和无监督的。
说什么?
监督学习
你对心理学感兴趣吗?这本质上是“概念学习”的机器版本。你知道什么是概念(例如物体、想法、事件等。)基于每个对象/想法/事件都有共同特征的信念。
这里的想法是,您可以看到一组带有标签的示例对象,并学习根据您已经看到的内容对对象进行分类。你简化了你从展示给你的东西中学到的东西,把它浓缩成一个例子的形式,然后你把这个简化的版本应用到未来的例子中。我们真的称之为“从例子中学习”
Photo by Gaelle Marcel on Unsplash
(把那个宝贝稍微打扮一下,看起来是这样的:概念学习是指从输入输出的训练样本中推断出一个布尔值函数的过程。)
简而言之,监督机器学习是学习一个函数的任务,该函数基于示例输入-输出对将输入映射到输出。它与由训练示例组成的标记的训练数据一起工作。每个例子都是由一个输入对象(通常是一个向量)和您想要的输出值(也称为监控信号)组成的一对。您的算法监督训练数据,并产生一个可用于映射新示例的推断函数。理想情况下,该算法将允许您对它以前没有见过的示例进行分类。
基本上,它查看带有标签的东西,并使用它从带标签的东西中学到的东西来预测其他东西的标签。
分类任务倾向于依赖监督学习。这些任务可能包括
- 检测图像中的人脸、身份和面部表情
- 识别图像中的物体,如停车标志、行人和车道标志
- 将文本分类为垃圾邮件
- 识别视频中的手势
- 检测语音和识别音频记录中的情感
- 识别发言者
- 转录语音到文本
半监督学习
这个更像是你小时候父母明确告诉你的东西(有标签的信息)和你自己学到的没有标签的东西结合起来的学习方式,就像你观察到的花和树,没有命名也没有计数。
Photo by Robert Collins on Unsplash
半监督学习与监督学习做同样的事情,但是它能够利用标记和未标记数据进行训练。在半监督学习中,你经常会看到许多未标记的数据和一点点标记的数据。有许多研究人员发现,这个过程可以提供比无监督学习更高的准确性,但没有与标记数据相关的时间和成本。(有时,标记数据需要一个熟练的人来做一些事情,如转录音频文件或分析 3D 图像,以便创建标签,这可能使创建一个完全标记的数据集变得非常不可行,特别是当你处理那些深度学习任务喜欢的大规模数据集时。)
半监督学习可以称为直推式(推断给定数据的正确标签)或归纳式(推断从 X 到 Y 的正确映射)。
为了做到这一点,深度学习算法必须至少做出以下假设之一:
- 彼此靠*的点可能共享一个标签(连续性假设)
- 数据喜欢形成聚类,聚类在一起的点可能共享一个标签(聚类假设)
- 数据位于比输入空间维度更低的流形上(流形假设)。好吧,这很复杂,但想象一下,如果你试图分析某人的谈话,你可能会想看她的面部肌肉移动她的脸和她的声带发出声音,并停留在那个区域,而不是看所有图像和/或所有声波的空间。
无监督学习(又名 Hebbian 学习)
无监督学习包括学习数据集中元素之间的关系,以及在没有标签帮助的情况下对数据进行分类。这可以采用很多算法形式,但它们都有相同的目标,即通过搜索隐藏的结构、特征和模式来模仿人类逻辑,以便分析新数据。这些算法可以包括聚类、异常检测、神经网络等等。
聚类本质上是检测数据集内的相似性或异常性,是无监督学习任务的一个很好的例子。通过比较文档、图像或声音的相似性和异常性,聚类可以产生高度准确的搜索结果。能够通过大量的数据对“鸭子”或者声音进行聚类有很多很多潜在的应用。能够准确检测异常和异常行为对于安全和欺诈检测等应用非常有益。
Photo by Andrew Wulf on Unsplash
回去吧!
深度学习架构已经应用于社交网络过滤、图像识别、金融欺诈检测、语音识别、计算机视觉、医学图像处理、自然语言处理、视觉艺术处理、药物发现和设计、毒理学、生物信息学、客户关系管理、音频识别以及许多许多其他领域和概念。深度学习模型无处不在!
当然,存在许多深度学习技术,如卷积神经网络、递归神经网络等等。没有哪种网络比其他网络更好,但有些网络肯定更适合特定的任务。
深度学习和人工神经网络
大多数现代深度学习架构都基于人工神经网络(ann ),并使用多层非线性处理单元进行特征提取和转换。每个后续层使用前一层的输出作为其输入。他们所学的形成了一个概念的层次结构,其中每一层都学习将其输入数据转换成稍微抽象一些的复合表示。
Image by ahmedgad on Pixabay
这意味着,例如,对于一幅图像,输入可能是一个像素矩阵,然后第一层可能编码边缘并组成像素,然后下一层可能组成边缘的排列,然后下一层可能编码鼻子和眼睛,然后下一层可能识别图像包含一张脸,等等。虽然您可能需要做一些微调,但深度学习过程会自行学习将哪些功能放在哪个级别!
Photo by Cristian Newman on Unsplash
深度学习中的“深”只是指数据经过多少层的转换(它们有一个实质的信用分配路径(CAP),这是从输入到输出的转换链)。对于一个前馈神经网络,帽的深度是网络的深度和隐藏层的数量加一(输出层)。对于一个递归神经网络,一个信号可能会通过一个层传播不止一次,因此 CAP 深度可能是无限的!大多数研究人员同意深度学习涉及 CAP depth > 2。
卷积神经网络
最流行的神经网络类型之一是卷积神经网络(CNN)。CNN 卷积(不是卷积…)学习输入数据的特征,并使用 2D 卷积层,这意味着这种类型的网络是处理(2D)图像的理想选择。CNN 通过从图像中提取特征来工作,这意味着不再需要手动提取特征。特征没有经过训练!它们是在网络对一组图像进行训练时学习的,这使得深度学习模型对于计算机视觉任务来说极其准确。CNN 通过数十或数百个隐藏层来学习特征检测,每一层都增加了所学习特征的复杂性。
如果你想继续了解我,我们将在第 3 部分深入探讨 CNN!
(想了解更多?查看吴建新和 Yann LeCun 的原创文章 卷积神经网络介绍 , 基于梯度的学习应用于文档识别 。)
递归神经网络
卷积神经网络通常用于处理图像,而递归神经网络(RNNs)用于处理语言。rnn 不只是将信息从一层过滤到下一层,它们有内置的反馈回路,其中一层的输出可能会反馈到其上一层。这实际上给了网络一种记忆。
生成对抗网络
在生成性对抗网络(GANs)中,两个神经网络一决雌雄。生成器网络试图创建令人信服的“假”数据,而鉴别器试图区分假数据和真数据。随着每个训练周期的进行,生成器在创建虚假数据方面变得更好,鉴别器在识别虚假数据方面变得更敏锐。通过在训练中让两者相互对抗,两个网络都得到了改善。(基本上这里是衬衫 vs 皮肤。主队正在努力提高自己的水*。)GANs 可以用于非常有趣的应用,包括从书面文本生成图像。GANs 可能很难处理,但更强大的模型正在不断开发中。
未来的深度学习
对于任何对深度学习感兴趣的人来说,未来都充满了潜力。神经网络最引人注目的一点是它处理大量不同数据的能力。这变得越来越重要,因为我们生活在一个先进的智能传感器时代,每天每秒都可以收集令人难以置信的大量数据。据估计,我们目前每天产生 2.6 万亿字节的数据。这是一个巨大的数据量。虽然传统计算机难以处理如此多的数据并从中得出结论,但随着数据量的增加, 深度学习实际上变得更加高效。神经网络能够发现大量非结构化数据中的潜在结构,例如原始媒体,这是世界上的大多数数据。
可能性是无限的!
还和我在一起吗?
查看第二部分:人工神经网络
** [## 深度学习完全初学者指南:人工神经网络
深度学习入门!在 15 分钟内攻克人工神经网络的基础知识
towardsdatascience.com](/simply-deep-learning-an-effortless-introduction-45591a1c4abb)
和第三部分:图像分类和卷积神经网络 !
* [## 深度学习完全初学者指南:卷积神经网络
在几分钟内征服 CNN 和图像分类的基础
towardsdatascience.com](/wtf-is-image-classification-8e78a8235acb)
和往常一样,如果你对这些信息做了什么很酷的事情,请在下面的评论中留下你的回应,或者随时在 LinkedIn 上联系我们
感谢阅读!***
深度学习入门:14 岁孩子教的
原文:https://towardsdatascience.com/intro-to-deep-learning-taught-by-a-14-year-old-6c49fc94d66?source=collection_archive---------14-----------------------
跳入深度学习的最深处
Manhattan Digest, “Streets of New York.” Image annotated by me using the Faster RCNN Inception V2 Model.
“我是一个乐观主义者,我相信我们可以创造出对世界有益的人工智能。它能与我们和谐相处。我们只需要意识到危险,识别它们,采用尽可能最好的实践和管理,并提前为其后果做好准备。”斯蒂芬·霍金
你们中的许多人可能已经开始听到人工智能治愈癌症的传奇故事,或者听到智能机器人接管的可怕故事。今天,或者无论哪一天你正在阅读这篇文章(你好,未来机器人霸主),我将解释什么是深度学习,为什么人们如此害怕它,以及如何使用它。
随着人类在 S.T.E.M .方面取得新的进展,有一个领域似乎每天都在快速进步。机器学习和人工智能的子集深度学习正在以惊人的速度前进。几乎每天,谷歌(Google)和亚马逊(Amazon)等大公司都会想出新的方法,让计算机能够检测出一些东西,比如一个人是否患有癌症,或者能够在放射扫描中快速检测出骨折。这些计算机可以比普通医生更精确、更快速地检测到这一点。
Google Teachable Machine learning hand gestures (it took me 2 minutes to train).
人工智能 vs 机器学习 vs 深度学习:认知计算进化简史
This graphic from Nvidia shows the transition from Artificial Intelligence to Deep Learning as technology and understanding of the human nervous system improved.
人工智能:模仿人类智能
与你所想的相反,人工智能已经存在了很长时间。直到 1956 年关于人工智能的达特茅斯夏季研究项目,机器展示人类智能的想法才看起来像是一项可能的成就。那次会议标志着该领域努力的开始,虽然标准计算在当时并不复杂,但它似乎仍然是一个重要的里程碑。“50 年代创造的人工智能能做什么?”你可能会问。最受欢迎的例子是几乎每台电脑都预装的象棋应用程序。如果你决定与计算机下棋,你实际上是在使用人工智能的最基本形式。计算机根据硬编码算法知道下一步该怎么走。
机器学习:人工智能的新观点
通过人工智能的子集机器学习,工程师能够将大量关系数据输入计算机,并获得对未来数据的有根据的预测。这在理解一个地区的房价、天气模式、垃圾邮件等方面非常流行。虽然机器学习在其应用领域取得了成功,但由于其许多限制(更适合少量数据),它仍然没有得到广泛使用。
深度学习:证明大脑高度活跃
深度学习是机器学习的一个子集,它赋予计算机“学习”(逐步提高特定任务的性能)的能力,而无需明确编程如何完成所述任务。深度神经网络能够接受数据输入,如图像和音频文件,并从被标记的内容中学习。由于对人类神经系统的新的和改进的理解以及硬件的改进,这项新技术最*才开始实施。以前,这些网络所需的巨大计算能力使得训练和评估模型几乎不可能。随着 GPU(显卡)的兴起,这种用于比特币挖掘的关键组件,研究人员每秒钟能够进行更多的数学运算。深度学习是如此之新,以至于许多计算机仍然没有足够的能力来运行模型;当我试图教一个网络扑克牌之间的区别时,在我的笔记本电脑上训练需要 28 周,而我的带 GPU 的台式机只需要 15 分钟。
My custom object detector for playing cards in a deck.
背后的神经科学
当事情发生时,我们的大脑能够通过遍布全身的神经元做出反应来理解我们所经历的事情。一个例子是,我们手中的一些神经元可能只有在物体热的时候才会向我们的大脑发出电脉冲,而其他神经元可能只有在物体冷的时候才会发出电脉冲。神经元遍布我们的身体和大脑,每一个都有不同的任务。仅大脑就有大约 860 亿个神经元。这个由神经元互联网络组成的系统,向大脑提供数据,发展成为一个令人难以置信的科学突破:深度学习。
Comparison between the connected networks within our bodies and a simple neural network (via https://www.quora.com/What-is-the-differences-between-artificial-neural-network-computer-science-and-biological-neural-network)
深度学习是如何学习的
监督学习
卷积神经网络是使用监督学习的最常见的神经网络类型。监督学习是指人类获取非对应的输入数据,并对这些数据进行标记,以帮助模型进行学习。对于图像训练,这将需要标记图像中的对象,以便计算机能够用“答案”进行自我测试。这是我用扑克牌做的;我必须给 100 张不同的照片贴上标签,告诉电脑每种类型的卡片在给定的照片中的位置。
The architecture of a traditional convolutional network.
This person is not a real, it was created by a GAN. Source
Using CycleGAN to turn a video of a horse into a zebra.
无监督学习
OpenAI learning how to play Atari Breakout.
生成对抗网络
GAN(生成对抗网络)是一种无监督学习,能够从图像训练数据中从头生成数据。英伟达创造了生成人脸的 GAN 虽然照片中的脸看起来是真实的,但它绝不是曾经存在过的人类。甘拍摄了人类的照片,并发现了人类长相之间的共性。
强化学习
一种用无监督学习训练神经网络的新方法被称为强化学习。虽然大多数卷积神经网络模型都是用监督学习(模型根据给定的输入数据评估自身)来训练的,但强化学习模型根据给定的奖励来评估其性能。目前,这种形式的训练正在视频游戏中进行测试,游戏中的得分可以立即让模型满意,表明有所改善。谷歌 DeepMind 的 AlphaGo 最*就使用了这种方法,它在非常复杂的围棋比赛中以 5 比 0 击败了 3 次欧洲冠军。AlphaGo 计算机能够在没有任何指令的情况下学习。
人工智能的道德
这些新的科学突破让我们得以一瞥未来的社会,在未来,汽车为我们驾驶,医疗分析更便宜、更准确,我们的生活由机器人个人助理(如 Siri、Alexa 或 Google Home)组织。许多主流高管和研究人员担心,如果我们滥用这些新技术,会有什么后果。由于深度学习是一门新学科,我们无法确定它的使用范围;像强化学习这样的训练方法可能会导致计算机变得更加独立于人类,因为我们让它们自己去理解世界。无论这些可能性听起来有多好,它都会导致一些严重的未解问题,比如人造生命的权利,或者我们今天所知的社会终结的可能性。
根据我在页面顶部引用的斯蒂芬·霍金的话,他总结了由于早期采用者的错误决策而导致的这些新技术的误用。虽然在这一点上我们无法确定人工智能会给未来带来什么,但我们必须回忆起我们可能看过的机器人入侵的电影,并警惕人工智能可能带来的危险,尽管这听起来很荒谬。
Autonomous vehicles get confused when tape is put on top of a stop sign. Source: U.C. Berkeley
深度学习可能还没有做好大规模商业应用的准备,主要是因为一个致命的缺陷:深度学习训练数据是让它给出预测的东西,而不是道德。正如 2018 年 10 月亚马逊审判所证明的那样,亚马逊在意识到由于不良数据而导致的性别歧视后,取消了一项人工智能倡议。亚马逊试图通过创造一个人工智能来帮助决定申请人是否是合格的员工候选人,从而使亚马逊的招聘过程变得更容易。这个人工智能已经训练出亚马逊员工过去雇佣历史的信息,并拒绝了申请。那些雇用应聘者的人通常是性别歧视的,因为过去不合格的男性比合格的女性更容易被雇用。这是一个很好的例子,说明糟糕的训练数据会导致糟糕的模型。另一个糟糕的训练数据的例子是自动驾驶汽车的早期测试,其中如果标志上有便利贴,计算机无法检测到停车标志,而大多数人仍然知道这是停车标志。
2019 年深度学习的现状
虽然人工智能有许多优点,但如果不深入思考,它也有许多似乎并不具有威胁性的缺点。事实上,人工智能失控并终结人类的可能性非常小,至少现在是这样。对社会更大的威胁是失业;一个经常被忽略的工作是卡车驾驶。现在在美国,有超过 350 万卡车司机。沃尔沃和优步已经在测试他们的全自动卡车,这种卡车有能力让司机下班。截至 2019 年 1 月 30 日,亚马逊已经在 10 号州际公路上测试完全自动驾驶的卡车。随着 350 万卡车司机工作岗位的流失,如果司机不需要停下来休息,许多小型卡车站也会倒闭。
The Daimler Freightliner driverless truck. Source: Wall Street Journal
深度学习实际上是第四次工业革命,可能会被证明有利于就业率。继蒸汽机、电力和内燃机以及互联网等发明引发的革命之后,深度学习有望创造比失业人数更多的就业机会。当互联网普及时,许多人担心失业,但它创造了比以前更多的就业机会;一些因为互联网而创造的工作岗位的例子包括社交媒体经理、数据科学家、优步司机等等——这些工作在 15 年前甚至不存在。
深度学习帮助下的创新不会很快停止,因为刚刚签署了一项行政命令,将大量资源用于将美国变成人工智能的世界领导者,而不是中国。“2017 年 7 月,[中国]公布了一项成为人工智能世界领导者的计划,旨在到 2030 年为其经济创造价值 1500 亿美元的产业,两个中国城市承诺为此投资 70 亿美元,”《纽约时报》报道。
IBM’s Project Debater in a live debate against one of the world’s best debaters. Source: IBM
处理深度学习已经在当今社会中实施的事实是令人生畏的,但它不会很快停止。谷歌的一个团队正在使用人工智能帮助医生为印度的糖尿病患者预防失明,在印度,医生自己无法足够快地分析患者。2011 年,IBM 的沃森电脑赢得了“危险边缘!”他的奖金是连续 74 场比赛获胜的著名选手肯·詹宁斯的 7 倍多。最终,游戏之间的竞争表明沃森是明显的胜利者,正如肯·詹宁斯所表达的,“我,欢迎我们新的计算机霸主。”IBM 在智慧游戏中击败人类的持续追求最*在 2019 年 2 月 12 日继续进行,当时 IBM 与哈里什·纳塔拉詹(Harish Natarajan)进行了辩论,后者通常被认为是世界上最好的辩手。虽然 IBM 给出了许多有说服力的论据来说明为什么应该补贴学前教育,但 IBM 的 debater 由于其单调的声音,未能在情感层面上与评委建立联系。要是 IBM 能从谷歌的 Tacotron 自然音频合成器那里学到一些技巧就好了。不要为 IBM 的损失感到太难过…谷歌的 DeepMind 刚刚创造了一个 AI,它打败了最优秀的人类星际争霸玩家。
A graphic of how DeepMind’s AI is able to understand the map of the game. Source: DeepMind
结论
虽然一开始可能很难相信电视节目想到的许多不可思议的想法已经进入市场,但这不应该看起来很可怕。深度学习才刚刚起步;许多曾经被认为是不可解决的想法现在正成为似是而非的发明。我希望这篇文章没有让你回避深度学习,而是拥抱可能出现的好东西,并希望激励你继续学习更多关于制作神经网络的知识。
奉献
如果没有我的学校 Pine Crest School 和佛罗里达州大西洋大学机器感知和认知机器人实验室的人的帮助,我永远不会找到我对深度学习的热情。我记得当威廉·哈恩博士和伊兰·巴伦霍尔茨博士在一次创新会议上对 Pine Crest 讲话时,我对了解深度学习是什么感到非常兴奋。这段旅程是一次不可思议的经历,我期待着进一步研究人工智能和深度学习。
"智慧的真正标志不是知识,而是想象力."-阿尔伯特·爱因斯坦
使用 DEAP 介绍进化计算
原文:https://towardsdatascience.com/intro-to-evolutionary-computation-using-deap-618ca974b8cb?source=collection_archive---------14-----------------------
Pixabay
介绍
进化计算是一种非常强大的通用优化技术,其主要灵感来自自然选择进化理论。自然选择进化是一个非常优雅的理论,它对自然界生物多样性的解释依赖于两个主要部分:
- 随机突变
- 选择压力
不同的生态栖息地对生存的挑战和要求是不同的。根据进化理论,在任何生态位中,由于 DNA 的随机突变和复制中的复制错误,不同生物的特征将是不同的。由于性状的这种变异,对于具有更适合生存的性状的生物来说,将会有不同的生存优势,也就是说,大自然隐含地施加了一种选择适合个体的压力。因为最健康的生物更有可能存活下来,它们会把“健康”基因传给它们的后代,后代也更有可能存活下来。
进化可以被认为是一种优化适应度的算法。这是进化优化的核心思想。换句话说,如果我们有一个问题,我们可以为它生成不同的解决方案,那么我们可以使用每个解决方案的性能作为适应度的度量,这可以驱动进化算法找到越来越好的解决方案。进化算法有不同的风格,这些风格共享它们的大部分组件,然而,在每个组件的细节和特征上有所不同。进化算法的主要组成部分是:
- 表示方案(例如基因型、表型等)
- 配对运算符(例如交叉)
- 变异操作符(如比特翻转)
- 健康指标
- 选择策略(如锦标赛选择)
- 进化策略(如 mu、lambda)
你可以在我的上一篇文章中找到关于进化算法不同变体的更详细的介绍。出于本教程的目的,我将重点关注一种叫做进化策略(ES)的变体,接下来我将简要介绍它。完整的 jupyter 笔记本可在这里获得。
进化策略
正如我提到的,所有的进化算法都有前述的大部分组成部分,只是细节不同。对于专家系统,表示方案主要是一种表型,即个体(或解)被明确地表示为数字向量。每个个体都会有一个伴随的向量,叫做策略,它只是一个控制其变异的向量。ES 中使用了不同的交配算子,但我们将使用的是混合算子,它主要是交配亲本之间的一种线性组合形式。我们将使用的变异算子是对数正态的,像 ES 中的所有变异算子一样,它依赖于上面提到的策略向量来变异个体的表示向量中的不同值。选择策略将是锦标赛选择,其中对一个子集个体进行多次随机选择,每次选择最佳个体。适应度函数是任何进化算法中必须委托给用户来定义的唯一部分,即用户将提供一些函数,该函数将基于对于手边的问题的合适的测量来分配适应度给群体中的每个个体。进化策略控制种群的大小,这里我将使用(mu,lambda)_ 读作‘mu 逗号 lambda’_,其中 mu 和 lambda 是正整数,mu 指的是父代种群的大小,而 lambda 指的是所产生的后代的大小。在这个策略中,选择策略(即本例中的锦标赛选择)仅适用于后代。
像所有的进化算法一样,ES 是在被称为代的迭代中完成的。每一代,后代都是由群体中当前的父母通过交配然后突变而产生的。然后评估新成员的适应度,并应用选择策略来选择将存活到下一代的个体。
DEAP
DEAP 是一个实现进化算法的 python 框架。它为协调任何进化算法所需的不同组件提供了一种有组织的简化方法。对于任何组件,DEAP 提供了预定义组件的大多数常见变化,同时提供足够的灵活性来定义自己的变化,以防常用组件不足以解决您的问题。
让我们首先定义一个可以使用 ES 优化的虚拟问题。在许多情况下,你会有一些自然的过程,我们称之为数据生成过程,你想要建模,以便你可以在以后做出预测。数据生成过程就像一个黑匣子,你永远无法看到里面,但你可以给它一个输入,它就会用一个输出来回应。
正如您在上面看到的,这个数据生成过程接受一个输入,并基于某个三次多项式产生一个输出。请注意,我们从来没有访问这个公式,这只是为了说明的目的。其实我们的任务就是用 ES 来建模这个未知的公式。我们只能“查询”这个黑盒并获得响应,也就是说,我们可以对它进行采样,
注意,增加了一个附加随机项。这个术语代表噪声,由于有许多来源,噪声是任何观测中不可避免的成分。
为了使用进化算法对一个过程建模,我们需要一个候选模型,基本上,一个关于我们正在寻找的模型类型的假设或“归纳偏差”。这可能来自另一个分析来源或以前的数据分析。对于我们的虚拟情况,我们将假设我们知道我们正在搜索的模型是最多四次的多项式,所以我们决定使用四次多项式,
“a”变量集是未知的,我们需要进化算法来优化它们,以便模型输出符合我们的数据。这将反映在我们下面讨论的评估函数的定义中。但是首先,我们需要准备我们的 ES 算法。
让我们导入实现所需的基本子包,
要使用 DEAP 实现 ES,我们首先需要将我们的个体、策略和适应性定义为数据类型。这可以在 DEAP 完成,不需要显式定义自己的类,
第一行定义了我们的健身数据类型。第一个参数给出了数据类型名称,第二个参数给出了基类,即 DEAP 提供的适应度度量的基类,第三个参数将适应度权重设置为负值,这意味着进化优化将尝试最小化该值。我们试图最小化适应度可能看起来很奇怪,但是正如你将看到的,我们将使用的适应度函数实际上是一个误差函数,也就是说,它测量我们的解决方案偏离观察值多少,因此,我们需要最小化它。
注意,在运行这一行之后,数据类型 FitnessMin 被动态地添加到 creator 子包中,您可以作为“creator”直接访问它。健身。
第二行类似,但是,它定义了个人。从第四个参数开始,您提供的任何参数都将作为字段或属性添加到已定义的数据类型中。对于个人来说,我们定义了 DEAP 所要求的一个必要条件,那就是健康。当 DEAP 想要更新适应值或读取它时,它将寻找这个。你可以看到我们把我们定义的 FitnessMin 传递给它。ES 算法需要策略属性,因为它依赖于策略向量来进行变异。我们将其初始化为“None ”,因为稍后我们将自己填充它。您可以将您需要的任何其他属性传递给 create 函数,它们将被添加到您的数据类型中。第三行定义了策略数据类型。
现在我们需要注册一些函数,以便于使用我们定义的数据类型来生成个体,并将它们聚合成一个群体。DEAP 为此提供了一个特殊的实用“工具箱”,
首先,我们定义一个函数,它接受我们的个体和策略类以及个体的大小,即个体向量中包含多少参数,并生成一个随机初始化的个体,并用随机初始化的策略向量填充它。然后,我们初始化我们的工具箱,并使用它的注册函数两次。第一种用法是注册一个名为“个人”的函数。您可以看到,第二个参数是我们实际定义的函数实现,其余参数是调用时默认传递给函数的参数。
第二种用法定义了另一个重要的函数,叫做‘population ’,我们将用它来生成人口。我们传递一个 DEAP 预定义的函数,它是 initRepeat。initRepeat 之后的参数也是调用时默认传递给它的参数。当我们从工具箱中调用函数“population”时,将调用 initRepeat,它将使用第二个参数初始化一组个体,这是我们预定义的个体生成函数,它将把它们放入“list”类型的容器中,这是它的第一个参数,并返回它。
我们现在需要注册评估功能,DEAP 将使用该功能为不同的个人分配适合度。这就是我们假设的多项式模型发挥作用的地方,
“pred”函数获取一个个体和一个数据点,并通过计算四次多项式返回模型输出。您可以看到,个人参数 1–4 用作不同指数的 x 的系数,第五个用作偏差/截距,即不含 x 的项。
“fitness”函数计算实际输出和我们的模型输出(使用前面的函数“pred”计算)之间的均方误差(MSE)。更健康的个体将具有更小的 MSE,这就是我们在开始时定义的健康被赋予负权重的原因。我们对使 MSE 更小感兴趣。
最后,我们使用特殊的关键字“evaluate”在工具箱中注册我们的适应度函数,以便 DEAP 在计算适应度时可以找到它。
我们需要注册一些操作所必需的函数,它们是变异、交叉和选择操作符。我们可以通过在工具箱中注册一组函数来实现,这些函数都有特定的名字,DEAP 在执行这些操作时会查找这些名字,
配对、变异和选择分别是交叉、变异和选择操作符。对于所有这些组件,我们使用预定义的 DEAP 组件,并传递它们所需的参数。
到目前为止,这些是 ES 运行的大部分必要组件。DEAP 提供的一个非常方便的可选工具是“统计”工具,我们可以配置它来获得每一代进化算法的一些统计数据,
当我们初始化我们的统计数据时,我们在构造函数中提供了一个函数定义,它将在 DEAP 调用时接收一个个体,我们需要返回我们希望对其应用统计运算符的个体的属性。注册的函数名将被用作相应 stat 的标签,例如{'avg':
另一个方便的工具是“名人堂”,我们可以对其进行配置,DEAP 会将每一代中最优秀的 k 个人填入其中,
“1”表示它将只由最优秀的个体填充。
现在,我们准备启动 ES,让它为我们带来奇迹,
第一行只是初始化一个新的群体,它被传递了我们的 mu 值作为它的大小,因为我们将使用前面描述的(mu,lambda 或 MuCommaLambda)算法。第二行使用提到的算法运行单代 ES(ngen = 1 ),传递第二个需要的参数 lambda。你可以看到我们还通过了我们定义的工具箱,它包含了我们所有配置的函数和操作符,我们的统计数据和名人堂。下面是 100 代运行的可视化。
参考
- https://deap.readthedocs.io/en/master/
- 贝克,t .,福格尔,D. B .,&米切莱维奇,z .(编辑。).(2018).进化计算 1:基本算法和算子。CRC 出版社。
数据科学的特征选择方法介绍
原文:https://towardsdatascience.com/intro-to-feature-selection-methods-for-data-science-4cae2178a00a?source=collection_archive---------6-----------------------
让数据更易于管理的指南
作者:瑞安·法玛尔,韩宁,玛德琳·麦康贝
Photo by Eugenio Mazzone on Unsplash
什么是特征选择?
好吧,让我们从定义什么是特性开始。要素是数据集中的 X 变量,通常由列定义。如今,许多数据集可能有 100 多个要素供数据分析师进行排序!这对于正常处理来说是一个荒谬的数量,这就是特征选择方法派上用场的地方。它们允许您在不牺牲预测能力的情况下减少模型中包含的特征数量。多余或不相关的特征实际上会对模型性能产生负面影响,因此删除它们是必要的(也是有益的)。想象一下,通过制作纸飞机来学习骑自行车。我怀疑你第一次骑马能走多远。
功能选择的好处
特征选择的主要好处是它减少了过度拟合。通过删除无关的数据,它允许模型只关注数据的重要特性,而不会被无关紧要的特性所困扰。删除不相关信息的另一个好处是,它提高了模型预测的准确性。它还减少了获取模型所需的计算时间。最后,要素数量越少,模型的可解释性越强,也越容易理解。总的来说,特征选择是能够以任意精度预测值的关键。
概观
有三种类型的特征选择:包装方法(向前、向后和逐步选择)、过滤方法(ANOVA、Pearson 相关、方差阈值)和嵌入方法(Lasso、Ridge、决策树)。我们将在下面用 Python 的例子来解释每一个。
包装方法
包装方法计算具有特定特征子集的模型,并评估每个特征的重要性。然后,他们迭代并尝试不同的功能子集,直到达到最佳子集。这种方法的两个缺点是,对于具有许多特征的数据,计算时间较长,并且当没有大量数据点时,它往往会使模型过拟合。最著名的特征选择包装方法是向前选择、向后选择和逐步选择。
正向选择从零个特征开始,然后针对每个单独的特征,运行一个模型,并确定与所执行的 t 检验或 F 检验相关的 p 值。然后,它会选择 p 值最低的要素,并将其添加到工作模型中。接下来,它采用所选的第一个要素,运行添加了第二个要素的模型,并选择 p 值最低的第二个要素。然后,它采用之前选择的两个要素,并使用第三个要素运行模型,依此类推,直到所有具有显著 p 值的要素都被添加到模型中。任何在迭代中尝试时从未具有显著 p 值的要素都将从最终模型中排除。
反向选择从数据集中包含的所有特征开始。然后运行模型,并为每个要素计算与模型的 t 检验或 F 检验相关联的 p 值。然后,将从模型中移除具有最大无关紧要 p 值的要素,并重新开始该过程。这种情况会持续下去,直到从模型中移除所有 p 值不显著的要素。
逐步选择是向前和向后选择的混合体。如上所述,它从零个要素开始,添加一个具有最低有效 p 值的要素。然后,遍历并找到具有最低有效 p 值的第二个要素。在第三次迭代中,它将寻找具有最低有效 p 值的下一个特征,并且它还将移除 先前添加的现在具有不重要 p 值的任何特征。这使得最终的模型包含了所有重要的特性。
上述不同选择方法的好处是,如果您对数据以及哪些特征可能是重要的没有直觉,它们将为您提供一个良好的起点。此外,它有效地从大量数据中选择具有重要特征的模型。然而,一些缺点是,这些方法不能贯穿每一个单一的特征组合,因此它们可能不会以绝对最佳的模型结束。此外,它还会产生具有高度多重共线性的模型(由于要素之间的关系而导致 beta 系数膨胀),这对于精确预测来说并不太好。
过滤方法
过滤方法使用除差错率之外的度量来确定该特征是否有用。不像在包装器方法中那样调整模型,而是通过有用的描述性度量对特性进行排序来选择特性的子集。过滤方法的好处是计算时间非常短,不会过度拟合数据。然而,一个缺点是它们看不到特征之间的任何交互或相关性。这需要单独考虑,这将在下面解释。三种不同的过滤方法是 ANOVA、Pearson correlation 和方差阈值法。
ANOVA (方差分析)测试查看特征处理内以及处理间的变化。这些差异是这种特定过滤方法的重要指标,因为我们可以确定某个特征是否很好地解释了因变量的变化。如果每个特定处理的方差大于处理之间的方差,那么该特征没有很好地解释因变量的变化。为了进行 ANOVA 检验,使用分子(SST,通常与 SSTotal 混淆)中的处理之间的变化和分母中的处理内的变化来计算每个单独特征的 F 统计量。然后,针对零假设( H0:所有处理的*均值相等)和替代假设( Hα:至少两个处理不同)对该检验统计量进行检验。
皮尔逊相关系数是两个特征相似性的度量,范围在-1 和 1 之间。接* 1 或-1 的值表示这两个特征具有高相关性,并且可能是相关的。要使用此相关系数创建要素减少的模型,您可以查看所有相关性的热图(如下所示),并选择与响应变量(Y 变量或预测变量)相关性最高的要素。高相关性与低相关性的临界值取决于每个数据集中相关系数的范围。高相关性的一般度量是 0.7<|相关性| < 1.0。这将允许使用所选特征的模型包含数据集中包含的大部分有价值的信息。
The response variable for this dataset SalePrice (top row) shows the correlation with the other variables. The light orange and dark purple show high correlations.
特征减少的另一种滤波方法是方差阈值化。一个特征的方差决定了它包含多少预测能力。方差越低,特征中包含的信息就越少,它在预测响应变量中的价值就越小。鉴于这一事实,方差阈值是通过找到每个特征的方差,然后将低于某个方差阈值的所有特征丢弃来完成的。如果您只想移除响应变量的每个实例中具有相同值的要素,则该阈值可以为 0。但是,要从数据集中移除更多要素,可以将阈值设置为 0.5、0.3、0.1 或其他对方差分布有意义的值。
如前所述,有时将交互添加到您的模型中会很有用,尤其是当您怀疑两个特征之间存在关系,可以为您的模型提供有用的信息时。交互可以作为交互项添加到回归模型中,显示为 B3X1X2。贝塔系数(B3)修改 X1 和 X2 的乘积,并测量两个特征(x)组合的模型的效果。要查看某个交互项是否显著,您可以执行 t 检验或 f 检验,并查看该项的 p 值是否显著。一个重要的注意事项是,如果相互作用项是重要的,两个低阶 X 项都必须保留在模型中,,即使它们是不重要的。这是为了保持 X1 和 X2 作为两个独立的变量,而不是一个新的变量。
嵌入方法
嵌入式方法将特征选择作为模型创建过程的一部分。这通常导致前面解释的两种特征选择方法之间的折衷,因为选择是结合模型调整过程完成的。 Lasso 和 Ridge regression 是这种类型的两种最常见的特征选择方法,并且决策树也使用不同类型的特征选择来创建模型。
偶尔,您可能希望在最终模型中保留所有特征,但不希望模型过于关注任何一个系数。岭回归可以通过惩罚模型的 beta 系数过大来做到这一点。基本上,它降低了与可能没有其他变量重要的变量的相关性强度。这将处理数据中可能存在的任何多重共线性(要素之间的关系会增大它们的β值)。通过将惩罚项(也称为岭估计量或收缩估计量)添加到回归的成本函数中,可以实现骑行回归。惩罚项采用所有的 betas,并通过必须调整的项 lambda (λ)对它们进行缩放(通常使用交叉验证:比较相同的模型,但使用不同的 lambda 值)。Lambda 是一个介于 0 和无穷大之间的值,尽管从 0 和 1 之间的值开始比较好。λ值越高,系数收缩得越多。当 lambda 等于 0 时,结果将是没有惩罚的常规普通最小二乘模型。
Function from: https://codingstartups.com/practical-machine-learning-ridge-regression-vs-lasso/
This shows how Ridge regression can adjust some of the large coefficients found in linear regression by making them closer to zero.
As the value of lambda (alpha) increases, the coefficients are pushed toward zero with at the cost of MSE.
套索回归是另一种惩罚模型中贝塔系数的方法,与岭回归非常相似。它还向模型的成本函数添加了一个惩罚项,其中 lambda 值必须进行调整。与岭回归最重要的区别是,套索回归可以强制贝塔系数为零,这将从模型中移除该特征。这就是为什么套索有时是首选,尤其是当你想降低模型的复杂性。模型的特征数量越少,复杂性就越低。为了迫使系数为零,添加到成本函数中的罚项取β项的绝对值,而不是求其*方,当试图最小化成本时,这会否定函数的其余部分,导致β等于零。
Function from: https://codingstartups.com/practical-machine-learning-ridge-regression-vs-lasso/
脊套回归的一个重要注意事项是你所有的特征都必须标准化。Python 和 R 中的许多函数会自动完成这项工作,因为 lambda 必须*等地应用于每个特性。一个要素的值以千为单位,而另一个要素的值以十进制为单位,这种情况不会发生,因此需要标准化。
另一种使用特征选择对数据建模的常见方法称为决策树,它可以是回归树或分类树,分别取决于响应变量是连续的还是离散的。该方法基于某些特征在树中创建分割,以创建算法来找到正确的响应变量。构建树的方式使用嵌入方法中的包装方法。我们的意思是,在制作树模型时,函数内置了几种特征选择方法。在每次分割时,用于创建树的函数会尝试所有要素的所有可能分割,并选择将数据分割为最相似组的分割。简单地说,它选择最能预测树中每个点的响应变量的特性。这是一个包装器方法,因为它尝试了所有可能的特性组合,然后选择了最好的一个。
预测响应变量时最重要的特征用于在树的根(开始)附*进行分割,而更不相关的特征直到树的节点(结束)附*才用于进行分割。这样,决策树惩罚了对预测响应变量没有帮助的特征(嵌入式方法)。生成树后,可以选择返回并“修剪”一些没有为模型提供任何附加信息的节点。这可以防止过度拟合,通常通过维持测试集的交叉验证来实现。
总结
那么,现在你已经经历了这一切,你要带走的最重要的想法是什么?尽管数据集可能有成百上千个要素,但这并不意味着所有要素都很重要或有用。尤其是现在,我们生活在一个拥有难以想象的海量数据的世界里,重要的是要努力关注那些重要的信息。还有很多(复杂的)方法来执行特征选择,我们在这里没有提到,但是所描述的方法是一个很好的起点!祝你好运,继续努力!
关键词汇:
特征:x 变量,通常是数据集中的一列
特征选择:通过选择要使用的特征子集来优化模型
包装器方法:用不同的特征子集尝试模型并挑选最佳组合
正向选择:逐个添加特征以达到最优模型
反向选择:逐个移除特征以达到最优模型
逐步选择:混合正向和反向选择,逐个添加和移除特征以达到最优模型
过滤方法:通过除误差之外的度量选择特征子集(该度量是特征固有的,不依赖于模型)
皮尔逊相关:两个变量之间线性相关的度量
方差阈值:选择方差截止点以上的特征以保留数据中的大部分信息
ANOVA: (方差分析)用于观察处理(样本)均值差异的一组统计估计过程和模型;可用于判断某个特征何时对模型具有统计显著性
交互术语:当两个特征依赖于另一个的值时,对它们之间的关系进行量化;减轻多重共线性,并可提供对数据的进一步了解
多重共线性:当两个或多个独立变量彼此高度相关时发生
嵌入式方法:在模型创建过程中选择和调整特征子集
岭回归:一种改进的最小二乘回归,通过将λ项应用于成本函数来惩罚具有膨胀的β系数的特征
拉索回归:类似于岭回归,但不同之处在于添加到成本函数的λ项可以迫使β系数为零
决策树:一种非参数模型,使用特征作为节点来分割样本以在随机森林模型中,可以使用*均下降基尼系数来计算特征重要性。
交叉验证:一种迭代生成训练和测试数据集的方法,用于估计未来未知数据集上的模型性能
预测简介
原文:https://towardsdatascience.com/intro-to-forecasting-3dc183570d96?source=collection_archive---------31-----------------------
预测是另一种使用结构化数据(通常通过使用来自自然语言处理和物体识别的技术获得)来通知决策的技术。预测技术预测未来的结果或状态。
我们为什么要预测呢?说你要买房子。预测一年后你的投资价值可能会有用。如果你翻新了厨房呢?预测技术可以帮助你确定厨房改造可以增加多少价值。作为一个企业,预算非常重要。如果您可以预测需求、客户流失、预防性维护成本和收益等,您就可以在整个企业中高效地部署资源。如果你有一个网上商店,并能准确地预测你的客户下一步可能购买什么,你可以在他们的搜索结果或广告中显示该商品,以增加销售的可能性。
预测使用大量历史数据来创建历史上表现相似的组。然后,它可以将新数据点与其中一个组进行匹配,并使用该组的历史表现来预测未来。预测不同于优化,优化你可以在这里阅读更多关于的内容,因为它不需要决定采取哪些步骤来达到既定目标。它只是将新数据与历史数据中的模式进行匹配。您可能会注意到,预测的第一部分听起来很像聚类和分类,我们之前在这里讨论过。预测技术通常基于聚类和分类算法。
预测算法使用我们称之为“特征”的东西来识别行为相似的群体。这些特征是独立于我们试图预测的事物的可测量的特性。比方说,我们正试图预测一所房子的价格,就像我们之前提到的那样。我们可能使用的几个特征是房子的年龄和卧室的数量。房子的价格,也就是我们试图预测的东西,至少部分是由其特征决定的(在这种情况下,是其年龄和卧室数量)。我们说特征是独立的,是指特征本身,房子的房龄和卧室数量,不会因为价格的变化而增减。价格(我们的因变量)当然会随着房子变旧或者我们决定增加一间卧室而改变。
在这个简单的例子中,我们有两个特征。如果我们制作一个历史价格和卧室的年龄和数量的表格,我们可以做一些简单的数学,并且可能在不使用人工智能的情况下预测房子的价格。问题是,房子的价格不仅仅取决于我们在这个例子中使用的两个特征。房子有多大?有花园吗?门廊?它有多少故事?附*的学校有多好?这个地区的*均收入是多少?利率趋势如何?该地区就业情况好吗?我们可以考虑的特征数量几乎是压倒性的。住房甚至不是我们在预测中要解决的最复杂的问题。如果不使用人工智能,就很难为这些更复杂的问题开发出任何精确度的预测模型。
随着特征数量的增加,训练精确模型所需的训练数据量也在增加。这些数据被用来试图隔离每个特征对我们试图预测的东西的影响。在我们之前的房子示例中,如果我们的训练数据只有 1 间卧室的旧房子和 4 间卧室的新房子,我们的模型在预测价格时将无法从卧室数量中分离出年龄。我们希望有一个训练集,其变化代表接*所有的年龄和卧室数量的组合。正如您可能猜到的,当您开始添加更多功能时,您需要覆盖所有这些变化的训练数据量会显著增加。
如果我们试图解决一个有成百上千个特征的问题,事情会变得更加复杂。我们显然需要更多的训练数据,但我们也需要更多的计算能力。这增加了训练数据所需的时间,这意味着模型调整需要更长的时间,计算资源的成本也增加了。数据科学家开发了几种技术来帮助减少所需的计算资源量。
数据科学家用来降低必要计算能力的两种技术是“提升”和“打包”。这些技术不是同时在所有要素和所有历史数据上训练算法,而是划分训练数据并在数据的子集上训练算法。他们多次这样做,对不同的数据子集进行训练,然后将结果合并到一个模型中。提升保持所有特征不变,但是限制了训练样本的数量。在房价的例子中,这意味着在您拥有的所有历史房屋销售数据中,boosting 算法(例如 XGBoost )将只关注一些房屋销售。然后它会再次运行,关注不同的子集。一旦完成,它将合并结果。相比之下,Bagging 会关注所有的房屋销售,但只会关注我们正在考虑的一部分特征(比如年龄和卧室数量)。然后,bagging 算法(例如随机森林)会考虑其他特征(比如地区收入中位数和学校排名)再次运行,然后合并结果。这只是对这两种“元算法”非常粗略的描述。我们将在以后的文章中进一步深入探讨。
关于预测,需要记住的一件重要事情是,它无法理解特征的含义。在我们之前的例子中,房子的年龄很可能是一辆车的年龄,或者是从某人的最后一个生日算起的天数。该算法无法理解它正在解决的问题背后的意义,而是在数据中寻找数学模式。这种缺乏理解可能是一个特征,因为它可以识别人类通常不能识别的模式。这也可能是一种限制。如果用于为算法定型的历史数据有内置偏差,则生成的算法也会有内置偏差。例如,亚马逊花了数年时间训练一个人工智能系统来整理简历,并根据过去的招聘数据预测哪些候选人最有可能被录用。这些简历随后会出现在负责面试这些候选人的招聘经理面前。然而,他们建立的算法一贯贬低女性候选人,因为在历史数据中,男性更有可能被录用。你可以在这里阅读更多关于亚马逊的人工智能招聘系统。
另一个问题是,预测算法的决策过程可能是不透明的,这加剧了固有偏见的问题。虽然分类和回归树等更简单的模型为他们的决策过程如何工作提供了一些透明度,但更复杂的模型通常是人类难以理解的。如果预测算法预测某人更有可能在贷款上违约,我们将无法解释为什么该算法预测违约,只能说它反映在训练数据中。这使得很难识别预测系统中的固有偏差,除非通过观察其预测。我们将在以后的博客文章中讨论算法透明性和偏差消除技术的问题。
预测是目前人工智能研究中最活跃的领域之一。有了足够的无偏见的历史数据,人工智能可以对未来做出准确的预测。无论是预测客户流失、估价还是预测性维护,准确的预测都是无价的。
原载于 2019 年 4 月 10 日【https://www.foundationai.com】。
地理绘图介绍
原文:https://towardsdatascience.com/intro-to-geographical-plotting-237f59fec735?source=collection_archive---------8-----------------------
使用 Python 在任意地图上可视化 geographic数据
Photo by Kelsey Knight on Unsplash
在 数据科学领域,我们经常致力于将数据可视化,这为我们提供了关于数据的清晰模式,并使其易于分析。幸运的是,python 为此提供了强大的数据可视化工具。此外,可视化世界各地或任何特定国家的基于地图的数据会更有趣,这给了我们关于地理数据的很酷的见解。地理地图很重要,因为它们为我们的数据值提供了背景。
所以,让我们来看看 Python 的交互式可视化工具—
plotly
。使用 Plotly,我们可以从地理数据中创建美丽的 Choropleth 地图。
Choropleth 地图:
Choropleth maps 帮助我们绘制出全球或全国范围的信息。它让我们看到某个变量是如何在一个区域内分布的。在这篇博客中,我们将重点介绍如何使用
**plotly**
绘制 choropleth 地图。
阴谋地
Plotly 是一个开源库,它允许我们创建可用于仪表盘或网站的交互式绘图。Plotly 也是一家公司,支持在线和离线托管数据可视化。现在让我们使用离线模式,因为它是开源的,并且它使得在我们的 Python Jupyter 笔记本中工作变得容易。
由于数据格式多样,使用 plotly 进行地理绘图起初有点困难,因此请参考此备忘单了解所有类型的
plotly
绘图的语法。
让我们从下面的例子开始理解这个概念…
来自 Kaggle 的数据集:
让我们找出全球以及全国范围内的星巴克门店,并使用 choropleth 地图将这些数据可视化。数据集(directory.csv)可以从这里下载。该数据集包括截至 2017 年 2 月目前正在运营的每家星巴克门店的记录。
我们将经历以下步骤:
- 导入所有的库,并将我们的 Jupyter 笔记本设置为脱机模式。
- 使用 pandas 将星巴克数据提取到 Dataframe。
- 为“美国国家”创建“数据和“布局对象,并绘制 choropleth 地图。
- 为“全球”创建“数据和“布局对象,并绘制 choropleth 地图。
让我们先把plotly
安装到 Jupyter 笔记本上
pip install plotly
第一步:
import plotly.plotly as py
import plotly.graph_objs as go #importing graphical objects
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
download_plotlyjs
允许 plotly 在离线模式下工作。
init_notebook_mode
将 Javascript 连接到我们的笔记本。
第二步:
import pandas as pd
df = pd.read_csv('directory.csv')
在进入第 3 步之前,让我们快速执行以下任务:
☑从上述数据集中获取子集数据(美国国家数据),并将其分配给新的数据框。
☑向数据集添加了一个新列——“商店计数”,以获得每个州的商店总数。
df_US = df[df['Country'] == 'US']
13608 entries for ‘US’ country
现在,要向数据框架添加新列“商店数量”,我们可以在“州/省”列上使用groupby()
,如下所示
df_US['Store Count'] = df_US['Store Number'].groupby(df_US['State/Province']).transform('count')
State ‘AK’ has a total of 49 stores
df_US[df_US['State/Province'] == 'CA'][['State/Province','Store Count']].head(1) # to check num of stores in 'California'
‘CA’ has a total of 2821 stores
第三步:绘制 ' 美国国家地图
让我们定义我们的'数据和'布局对象如下:
**data** = dict(type='choropleth',
locations = df_US['State/Province'],
locationmode = 'USA-states',
colorscale = 'Reds',
text = df_US['Brand'],
z = df_US['Store Count'],
colorbar = {'title':"Stores Count"}
)
type
:定义地图的类型(choropleth)
locations
:所有州的名称
locationmode
:通过给出国家名称
colorscale
来指定位置:显示彩色地图。(更多色阶请参考下文)
text
:悬停在地图上时显示每个状态元素
z
的文本:显示每个状态元素
colorbar
的“商店计数”的整数值:【右侧栏标题】
colorscales:
['灰色',' YlGnBu ','绿色',' YlOrRd ','蓝色',' RdBu ',
'红色','蓝色','野餐','彩虹','波特兰','喷气机',【T41 ','热','黑体','地球','电','绿色','公民']
**layout** = dict(title = 'Starbucks locations in USA Map',
geo = dict(scope='usa')
)
现在,我们可以使用go.Figure()
方法为地图创建一个对象,然后使用iplot()
方法生成绘图
choromap = go.Figure(data = [data],layout = layout)
iplot(choromap)
Interactive Choropleth map for ‘US’ country[Image by Author]
酷!我们的“美国”国家 choropleth 地图已经生成,从上面我们可以看到,当鼠标悬停在地图上的每个元素上时,每个州都会显示文本、商店数量和州名,数据越集中在一个特定区域,地图上的颜色就越深。这里的“加州”有更多的商店(2821),所以颜色很深。
类似于 Choropleth 地图,我们有另一个很酷的交互式地图,叫做“散点图”。
“散点图”提供地图上的每个数据点(表示为标记点)以及由 x(经度)和 y(纬度)列表示的位置。
我们可以使用数据集中的列“经度”和“纬度”来生成散点图。
让我们使用下面的代码创建一个散点图。
**data** = go.Scattergeo(
lon = df_US['Longitude'],
lat = df_US['Latitude'],
text = df_US['text'],
mode = 'markers',
marker = dict(symbol = 'star',size=5,colorscale = 'Reds'
),
marker_color = df_US['Store Count'],
)
**layout** = dict(title = 'Starbucks locations in USA Map',
geo_scope = 'usa'
)
choromap = go.Figure(data = [data],layout = layout)
iplot(choromap)
‘Star’ markers represent store locations for each state[Image by Author]
第四步:绘制 ' 世界地图
像我们之前做的那样,添加了一个新列“商店数量”。此外,我还在数据集“国家代码”中添加了一列,其中包含 ISO 3(3 位数)代码。
下面是创建 choropleth 世界地图的代码...
**data** = dict(
type = 'choropleth',
locations = df['CountryCode'],
z = df['Store Count'],
text = df['Brand'],
colorbar = {'title' : 'Starbucks Stores - World Wide'},
)
**layout** = dict(
title = 'Stores Count',
geo = dict(
showframe = False,
projection = {'type':'natural earth'}
)
)
choromap = go.Figure(data = [data],layout = layout)
iplot(choromap)
Sample screenshots represent stores count in India and Australia[Image by Author]
我们的地理数据可视化部分到此结束。请查看plotly
地图官方页面查看更多有趣的剧情类型。
我希望这篇文章对你有用,请在下面的评论区分享你的评论/反馈。谢谢大家!!
使用 Networkx 在 Python 中创建图表
原文:https://towardsdatascience.com/intro-to-graphs-in-python-using-networkx-cfc84d1df31f?source=collection_archive---------11-----------------------
图表和数据科学
用 Python 构建第一个图表的介绍
如果你对用 Python 做图论分析感兴趣,并且想知道从哪里开始,那么这是给你的博客。我们将首先介绍几个关键概念,然后使用方便的 Networkx 包在 Python 中实现它们。
一些图论术语
- 一个图 G ( V , E )是由一组顶点( V )和一组边( E )定义的数据结构。
- 顶点 ( v )或节点是一个不可分割的点,由下图中的字母组件表示
- 一条边 ( vu )将顶点 v 和顶点 u 连接在一起。
- 由 n 个顶点组成的完全图是这样一个图,其中每个顶点与其他所有顶点共享一条边,因此包含最多的边。
- 任何有 n 个顶点的简单图的最大可能边集的大小等于( n *( n -1))/2。这是因为它相当于顶点对组合的数量,即。( n 选 2) = n !/( ( n -2)!(2!)).
- 图 G ( V , E )的顶点 s 上的一个诱导子图gg*s*是这样一个图,使得 S ⊂ V 和 G [ S 的边集合由
- 图 G 的一个团 C 是 G 的任何诱导子图,它也是一个完全图
安装软件包并创建您的第一个图表
您需要做的第一件事是在您的机器上安装 Networkx 包。使用 Pip 非常简单:
pip install networkx
安装完成后,导入包并初始化图形对象
import networkx as nxG = nx.Graph()
添加前两个节点以及它们之间的边
G.add_node(1)
G.add_node(2)
G.add_edge(1, 2)
在这一点上,我们的图只是两个相连的节点
Fig. 1 A two vertex Graph
一次添加一条边非常慢,但幸运的是,我们还可以添加节点列表和边列表,其中每条边由一个节点元组表示。
G.add_nodes_from([2,3,4,5,6])
G.add_edges_from([(1,2),(4,5),(3,5),(2,3),(5,6)])
我们的图表现在应该看起来像这样
Fig 2. Our graph now has seven vertices
访问和存储信息
通过打印图形的这些属性,我们可以看到节点或边的列表。
print(G.nodes())
>>>[0, 1, 2, 3, 4, 5, 6]
print(G.edges())
>>>[(0, 1), (1, 2), (2, 3), (3, 4), (3, 5), (5, 6)]
也可以将节点定义为字符串。
G.add_node('ib')
G.add_edge(3,'ib')
最重要的是,可以为每个节点分配任意数量的属性,然后存储在字典中。
G.nodes[1]['color'] = 'red'
G.nodes[1]['count'] = 10
print(G.nodes.data())
>>>[(0, {}), (1, {'color': 'red', 'count': 10}), (2, {}), (3, {}), (4, {}), (5, {}), (6, {}), ('ib', {})]
为了使这些数据更易于管理,将 nodes.data()的输出提供给一个 dict()函数,让它进入一个可爱的嵌套字典,其中每个节点都是一个键。
print(dict(G.nodes.data()))
{0: {}, 1: {'color': 'red', 'count': 10}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 'ib': {}}
最大团估计
为了找到最大团,我们需要从 networkx 导入*似包,因为它不包含在默认导入中
from networkx.algorithms import approximation as aprx
现在,为了测试最大团,我们将通过添加边(4,6)在当前图中创建一个大小为 3 的团
G.add_edge(4,6)
Fig 3. Now with 8 vertices and a clique of size 3
因此,顶点集{4,5,6}包含我们的最大团大小为 3,该顶点集正是 max_clique 函数将返回的。
print(aprx.max_clique(G))
>>>{4, 5, 6}
print(len(approximation.max_clique(G)))
>>>3
要查看该顶点集的诱导子图,我们需要将上述与子图方法结合起来
max_clique = G.subgraph(approximation.max_clique(G))
这将为我们提供以下完整的 3 顶点图。
The induced subgraph of the maximum clique
最后的想法和问题
Python 有很多图形库,但我选择了 Networkx,因为它可读性强、易于设置,尤其是因为它有出色的文档。如果您有任何进一步的问题或希望更多地探索图书馆,请参考官方文档。
来源
https://networkx.github.io/
https://en.wikipedia.org/wiki/Induced_subgraph
https://en . Wikipedia . org/wiki/Clique _(graph _ theory)
自然语言处理的非技术性介绍
原文:https://towardsdatascience.com/intro-to-nlp-using-inaugural-speeches-of-presidents-8c7ca32cbdfe?source=collection_archive---------18-----------------------
总统就职演说分析
虽然神经网络和 CNN 在计算机视觉领域取得了巨大的进步,但自然语言处理却没有得到应有的重视。它经常被忽视,因为还没有超越人类水*的表现。然而,正如我们将通过这个系列看到的,我们可以制作一些非常漂亮的工具,不仅可以帮助我们获得洞察力,还可以自动化任务。
所有提到的代码都可以在这里获得。你可能需要从 github 链接中复制一些我写的帮助函数。在这里提到它会使一切都过于集中。
首先,我们将对从第一任总统到 2009 年奥巴马的演讲做一个基本的分析。这里我们将使用三个库
1。nltk
2。pyphen——将单词分成音节。matplotlib——嗯,为了绘图
,所有这些都可以使用 pip install 安装。
你需要下载语料库。您可以通过执行下面给出的代码来做到这一点
nltk.download(‘inaugural’)
nltk.download('stopwords')
或者你可以直接执行 nltk.download() 在下载器弹出后下载语料库部分的“inaugral”和“stopwords”,如下图截屏所示。您也可以通过这种方式探索其他语料库。
how to download nltk corpus
现在我们用下面的代码导入 nltk 包和语音(这可能需要几秒钟,取决于您的计算机)
import nltk
from nltk.corpus import stopwords
from nltk.corpus import inaugural
from nltk.tokenize import word_tokenize, sent_tokenize
import matplotlib.pyplot as plt
import pyphen
现在我们已经导入了就职演说,我们可以看看数据。我们可以看到我们有 56 位总统的数据,从华盛顿到 2009 年的奥巴马。
让我们来看看这些演讲。要获得数据的原始格式,我们可以简单地使用inaugural.raw()
。但正如我们所看到的,我们不能清楚地把它分成单词。幸运的是,我们有inaugural.words()
为我们做这项工作。
既然我们已经把我们的演讲分解成单词,我们可以开始对它做一些基本的分析。我们从频率分布开始。这将告诉我们一个特定的单词出现了多少次。而且已经按降序排列了。
我们遇到了一个问题,它被停用词淹没了。通常有一些单词和标点符号比其他单词和标点符号重复得更频繁,它们通常不会给我们提供更多的数据信息。nltk 已经有了一个类似的单词列表,它们被称为stopwords
。它们可用于多种语言。我们在导入的停用词列表中添加了一些符号。
现在我们有了一个停用词列表,我们编写一个小代码来删除演讲中的所有停用词,并再次找出频率分布。
这更好,也给了我们一些关于数据的见解。但这只给了我们一次演讲的数据,我们需要一些东西来比较更多总统的演讲。
所以我们开始计算 xyz 总统使用了多少个 2,3,4 字母单词。然后,我们取每位总统每个词的*均字母数,并绘制出来。
“我感到快乐”——每个单词的*均字母数为 3.33 (1+4+5)/3。
“我散发出欣快感”——每个单词的*均字母数为 4.66(1+5+8)/3。
更高的每个单词的字母数意味着总统最常用“大”字。我们先数一下每位总统用了多少个 x 字母单词。
当我们这样做的时候,我们还将每个单词的*均字母数存储在一个名为presidents_avg
的变量中。使用 matplotlib 来绘制它,我们可以看到它明显地随着时间/总统而减少。
沿着类似的路径,我们开始计算 xyz 总统在一个句子中说了多少个单词。然后我们取每位总统每句话的*均字数,并绘制出来。
每句话的*均字数更高意味着总统最常用“大”句子。我们还将每句话的*均字数存储在一个名为presidents_avg_words_per_sentence
的变量中。使用 matplotlib 来绘制它,我们可以看到它明显地随着时间/总统而减少。
现在让我们看看单体型分析是否能给我们带来什么。在语料库语言学中,hapax legomenon 是一个在语境/言语中只出现一次的词。words.hapaxes()
给出了给定语料库中所有独特的单词。
但是计算独特单词的数量是不够的。我们还需要用它除以整个演讲的长度。为什么?因为演讲的长度变化很大,所以一个更大的演讲可能有更多独特的单词,我们需要消除这种偏见。因此,我们在一篇演讲中找到独特的词,统计它们,*均它们,并为每位总统绘制它们。
似乎在减少一点,虽然不是很明显。
在最后的分析中,我们计算每位总统在演讲中使用的每个单词的音节,我们使用 pyphen 库,因为像“Afghasnistan”这样的名词通常没有预定义的音节数。
然后我们取每位总统每个词的*均音节数,并绘制出来。
当我们看到图表时,我们看到它随着时间的推移而减少。
所以相比较而言,现在的总统比以前的总统使用更少的单词和更短的句子。
这可能是由多种原因造成的,英语本身在 200 年的时间里发展了很多,但也可能是因为媒体的进步。随着总统的演讲开始被普通人所接受,他们自然喜欢较短的句子和较小的单词,总统的演讲开始根据新的听众而改变。他们不是为了给华盛顿少数受过教育的人留下深刻印象,而是为了从普通人那里获得选票。
优化简介
原文:https://towardsdatascience.com/intro-to-optimization-f27ec87fbef1?source=collection_archive---------29-----------------------
许多人工智能技术都是关于将数据转换成对我们更有用的形式,获取自由形式的文本、图像和音频等非结构化数据,并从中提取意义。虽然这种新的转换数据(我们在图像中识别的对象,我们在自由文本中识别的意图和实体,我们在音频中识别的单词)比它所来自的非结构化数据更有用,但我们没有对它做任何有意义的事情。
优化的核心是解决问题和计划。使用由像自然语言处理或对象识别这样的技术提供的结构化数据作为上下文,它可以确定实现目标的最有效方式。这个目标可以是任何事情,从在棋盘游戏或电脑游戏中最大化得分,到成功谈判一笔交易,再到优化供应链。与之前讨论的技术不同,优化使用另一种称为强化学习的方法,这些技术要么依赖于为算法提供预先标记的数据(监督学习),要么提供数据并要求它对数据进行分类(非监督学习)。
最简单的形式,优化看起来就像反复试错。该算法对其行为进行小的改变,并观察这是否使其更接*其目标。如果有,它会继续对相同的行为进行更改。如果没有,它会尝试其他方法。强化学习使优化算法能够记住其先前的动作以及它们对其目标的影响。这使它能够开始发展战术,导致更高的分数。
让我们以学习玩超级马里奥兄弟的优化算法为例。在这个游戏中,对于那些自 1983 年以来生活在岩石下的人来说,玩家控制马里奥或路易吉从一个*台跳到另一个*台,通过关卡向右(定向)移动。有些敌人要么可以通过跳过它们来躲避,要么可以通过跳到它们身上来打败它们。如果你想训练一个优化算法来打败这个游戏,你不能简单地把它的目标定为“打败超级马里奥”,然后一直等到它这样做。这将花费很长时间,当它最终通过随机机会击败游戏时,算法不会学到任何东西。这是因为需要给算法设定短期目标,以激励它朝着正确的方向前进。虽然你和我本能地知道向右移动并避开敌人,但这是机器必须学会的。击败超级马里奥兄弟这个大问题必须被分解成小得多的问题。而不是打败游戏的最终目标,你必须给它一个会导致游戏被打败的目标:最大化它的分数。然后你建立一个积分系统,当算法向右移动,跳到更高的*台上,杀死敌人时,它会得到积分。该点系统将通过物体识别来启用。通过反复试验(经过数千次或数百万次尝试),该算法将制定策略,使其能够向右移动,跳到更高的*台上,并杀死敌人。最大化这些目标将最终导致它击败游戏。
但是,如果我们谈论的是像国际象棋、围棋或 DOTA 2 这样的对抗性游戏(与对手进行的游戏)呢?一个人不可能玩一百万次游戏来对抗一个算法来训练它。首先,这将花费太长时间(而且对人类参与者来说太无聊了)。第二,机器只会比它所面对的人类对手略胜一筹。这就是生成性对抗网络(GANs)的用武之地。该算法不是面对人类对手,而是成千上万次地扮演一个略有不同的版本。每次游戏结束后,双方都将从两种算法中学习到的知识整合到一起,然后开始新的游戏。gan 使这些算法能够更快地获得经验,因为他们可以以更快的速度玩这些游戏。它们还使优化算法能够超越人类的技能水*,因为它们不会将自己与人类进行比较。这就是 DeepMind 如何训练他们的 AlphaGo 算法在围棋上击败世界上最好的人类选手。
所以,我们完了!如果你激励一个优化算法来最大化它的分数,它最终会发展出足够的技能来击败最好的人类玩家,对吗?不完全是。优化方法倾向于关注短期的最大化。在短期收益最终会带来长期成功的情况下(比如《超级马里奥兄弟》),这种方法非常有效。在更复杂的情况下,就像我们在《星际争霸》和《DOTA 2》等视频游戏中看到的那样,短期牺牲可以带来长期成功。这是人工智能在复杂多变的环境中难以击败人类玩家团队的部分原因,这些游戏需要不容易模拟的战略思维。
研究人员通过结合不同的系统来解决这一弱点,试图*衡短期和长期战略。一种算法将试图确定下一步最佳行动,而另一种算法将着眼于整个游戏可能如何结束。这两种算法结合在一起,就能找出通往胜利的最佳路径。一个名为 Libratus 的系统使用了类似的方法,该系统能够击败经验丰富的扑克玩家。它的一种算法使用强化学习来自学游戏,然后确定最佳的下一步行动。第二个关注游戏的最终结果。第三种算法将识别 Libratus 之前下注的模式,并引入随机性来摆脱其他玩家。
视频游戏、棋盘游戏和纸牌游戏——这些与优化如何帮助您运营业务有什么关系?我们在谈论优化时谈论游戏的原因是,研究人员将这些游戏用作测试,以了解他们的算法工作得有多好。就像我们给优化算法的短期目标是击败超级马里奥兄弟一样,击败电脑游戏是一个短期目标,旨在构建可以处理现实世界的健壮优化算法。最终目标不是设计一个可以打败计算机游戏的系统,而是训练可以在充满不确定性的复杂多变环境中工作的算法。
优化可以应用于现实世界中有明确目标要实现的情况。脸书已经使用优化技术训练聊天机器人像人类一样谈判简单的商品。优化也被用来优化供应链,设计轮班,并提出建议。如果一个大的决策可以被分解成更小的决策,这些决策可以使用试错法进行优化,那么就可以使用优化来确定最有效的行动方案。
原载于 2019 年 4 月 10 日【https://www.foundationai.com】。
使用 Python 读写电子表格简介
原文:https://towardsdatascience.com/intro-to-reading-and-writing-spreadsheets-with-python-b635ae514ab8?source=collection_archive---------5-----------------------
这个帖子是给谁的?
初学者和 Mac 用户(Windows 用户需要先安装和设置 Python)
你需要什么?
任何 Mac,一个文本编辑器(我推荐 Atom )和持久性
你能从中得到什么?
您将学习如何使用 Python 读取、转换和输出电子表格。对于转型,我们将着眼于获得在某个日期之前与我们交谈过的客户。
我到底是谁?
我是爱电子表格的创始人。我们的目标是在 Excel 用户和程序员之间架起一座桥梁。
I .验证和安装库
首先,我们将检查是否安装了 Python,并安装另一个将帮助我们处理电子表格的库。
库是一个代码集合,它以一种更简单的方式实现了(通常)难以实现的事情。
- 我们需要首先打开终端,让我们与系统进行交互。在 Mac 上进入搜索,找到并打开终端
Search and Open the Terminal Application
2.打开你的终端,输入 python 然后按回车
$ python
注意:美元符号指定了终端行的开始,在开始处可能会有很多不同的文本 。
您应该会看到一个控制台,其中 Python 版本正在运行。我运行的是 Python 2.7,但是本教程和代码将会运行到 Python 3.7。如果你遇到任何问题,让我知道。
Type in python and click enter to see the console
如果这里有一个错误,那么谷歌这个错误,看看你需要做些什么来修复它。
3.如果 python 显示正确,首先我们需要按退出 python
Ctrl + d
这将把我们带回到带有$的命令终端
现在我们将安装这个库,它将帮助我们阅读和处理电子表格。它叫做 pandas ,我们将用下面的命令安装它。键入以下内容并按下键进入:
$ pip install pandas
我们还将安装另外两个库 xlrd、openpyxl 来帮助 Excel 读写。您不会处理这些库,但它们需要安装。
$ pip install xlrd openpyxl
4.如果成功安装了 pandas 库,您将看到一串文本,最后一行声明安装成功。如果您在这里遇到错误,您需要在继续之前修复它。
There will be a bunch of text and it will not match mine but as long as the Successfully installed statement appears with no errors, you are good
同样,如果成功安装了 xlrd 和 openpyxl 库,您将会得到与 pandas 类似的“成功安装”消息
二。组织文件
现在,我们将保存示例电子表格并创建一个 Python 文件,我们将在其中编写代码。
5.我创建了一个名为 CustomerSample.xlsx. 的样本数据文件,你可以点击这里下载。
该文件有两页:客户和潜在客户。该文件有 8 列虚拟数据。
6.现在我们将创建一个 Python 代码文件。打开 Atom 或任何文本编辑器。现在不用写任何东西,保存为 excel.py 。
7.有几件非常重要的事情需要记住:
I .customer sample . xlsx和 Excel.py 文件都应该放在桌面上同一个名为python spreadsheettutorial的文件夹中,这里的所有代码才能工作
These aren’t rules but if you are new it’s easier to follow my naming first before branching out
二。文件和文件夹的名称应该是上面的名称,这样代码才能工作
三。读取 Excel 文件
如果你已经做到了这一步,恭喜你!大多数人在设置好环境,准备好一切的时候就放弃了。
现在我们终于可以开始有趣的部分了。最后的代码只有 4 行,如下所示。我们将在邮件中分解它
The full excel.py file
8.打开您创建的 excel.py 文件,准备编写一些代码
读取文件的整个代码只有 2 行
import pandas as pdcustomer_sample_file = pd.read_excel("CustomerSample.xlsx", sheet_name="Prospects", parse_dates=[0])
9.第一行告诉 python 我们将在代码中使用熊猫库,我们将把它命名为 pd
10.第二行是我们如何阅读熊猫的电子表格。我们创建一个变量customer _ sample _ file***并存储调用函数PD . read _excel*的结果(从 Pandas 库中读取 _ excel)
11. pd.read_excel 函数接受 1 个强制参数,电子表格的名称和位置(这就是为什么命名和位置正确很重要,但是如果您决定更改它,您需要在这里将其更改为完整路径)。
我们提供了另外两个可选参数, sheet_name 和 parse_dates 。 sheet_name 告诉函数要读取哪个工作表,而 parse_dates 获取应该作为日期读取的列的列表。0 指定第一列,依此类推。
这个函数有很多你可以指定的参数。我鼓励你在这里阅读它们。
您可以试验不同的参数,看看它们能做什么。
12.变量 customer_sample_file 现在包含了数据框中电子表格的所有行和列,因为我们的第一行是列名,所以它们成为了这个数据框的列名。
如果您打印出 customer_sample_file ,那么您会看到它包含以下内容
THIS IS NOT PART OF THE CODE. I PRINTED THIS SEPARATELY
四。转换文件
对于我们的转换,我们将只获取 2017 年或更早时间记录的记录。
这部分的代码是 1 行。
**customers_2017_or_earlier = customer_sample_file[customer_sample_file["DateTime Recorded"] < "2018-01-01"]**
13.我们创建了另一个变量customers _ 2017 _ or _ earlier,并将其分配给在 2018 年 1 月 1 日之前记录的客户。
14.这分两步完成,内部代码
**customer_sample_file["DateTime Recorded"] < "2018-01-01"**
当记录的日期时间的列值小于2018 年 1 月 1 日时,为每个记录分配 True 或 False 值,然后是代码的外部部分
**customer_sample_file[customer_sample_file["DateTime Recorded"] < "2018-01-01"]**
从数据框中选择那些记录
动词 (verb 的缩写)输出记录
太好了,现在我们有了以前的记录,我们可以将它们输出到他们自己的小 Excel 文件中。
这个代码也只有一行
**customers_2017_or_earlier.to_excel("Customers2017OrEarlier.xlsx")**
15.我们采用变量customers _ 2017 _ or _ earlier并运行函数来 _excel 。这个函数接受一个参数,它是您想要创建的新文件的名称
16.既然文件已经完成,我们需要运行脚本。为此,我们需要打开终端、并导航到保存 excel.py 文件的文件夹,即桌面上的python spreadsheettutorial。
在我的终端中运行以下命令,然后按键进入****
**$ cd ~/Desktop/PythonSpreadsheetTutorial**
如果您将 excel.py 文件保存在不同的文件夹中,那么您需要指定路径。波浪线表示您位于用户的主目录中,然后构建脚本文件夹的剩余路径。如果它工作正常,那么您将会在$符号变成文件夹名称之前看到名称
There should be a clear change when you have entered the correct folder
17.现在是最后命令的时候了。在我们的文件夹中,从终端运行以下命令并按下回车。****
**$ python excel.py**
Press Enter to run the script and that’s it
如果没有错误,那么什么也不会发生,您应该会看到一个新文件出现在您的文件夹中,其中包含 2017 年或之前的所有记录!
我希望这有所帮助,如果你有任何问题,请在评论中告诉我!