TowardsDataScience-博客中文翻译-2019-二十二-

龙哥盟 / 2024-10-13 / 原文

TowardsDataScience 博客中文翻译 2019(二十二)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

通过数据分析发现足球国歌

原文:https://towardsdatascience.com/discovering-football-anthems-through-data-analysis-3a9773499d77?source=collection_archive---------26-----------------------

在我之前的一篇关于 FIFA 世界杯的博客中,我写了音乐和足球是如何不可分割的。音乐是足球文化的一部分,反之亦然。音乐团结了世界各地俱乐部背后的军队,增强了赛前(和赛中)的气氛。

每个人可能都有他或她最喜欢的足球歌曲。我想知道是否有办法通过数据分析来识别某个足球俱乐部最有特色的歌曲。由于来自阿姆斯特丹,我决定找出阿贾克斯阿姆斯特丹的支持者是否有他们支持的俱乐部最喜欢的歌曲。

如果你从未听说过阿姆斯特丹阿贾克斯足球俱乐部,也称为阿姆斯特丹阿贾克斯,或简称为阿贾克斯,它是一家总部设在阿姆斯特丹的荷兰职业足球俱乐部。历史上,阿贾克斯(以传说中的希腊英雄命名)一直是荷兰最成功的俱乐部。尽管有些人可能不同意。

在你继续阅读之前,我必须提醒你,这个分析中涉及了一些荷兰民间音乐。

数据集

  • 通过查看 Spotify 用户生成的播放列表,在它们的播放列表标题或描述中有“Ajax”或“Ajax Amsterdam ”,我创建了一个与足球俱乐部有关的播放列表子集。
  • 通过提取这些播放列表中包含的所有歌曲,我们能够建立一个与 Ajax Amsterdam 相关的歌曲数据集。这是通过 Spotify 的 API 完成的。

Ajax 相关播放列表

通过在 Spotify *台上搜索在用户的播放列表标题或描述中包含 Ajax 相关术语的播放列表,我能够收集到超过 900 个播放列表。除了俱乐部的名字,最常用的表情符号是代表阿姆斯特丹的三个❌'s。

像⚽️、❤️and 这样的表情符号🔴⚪️也是常用的。这并不奇怪,因为它们与阿贾克斯的俱乐部颜色联系在一起。*均一个 Ajax 支持者的播放列表中有 27 首歌曲。

最佳阿贾克斯阿姆斯特丹歌曲

识别用户生成的 Ajax 播放列表后,下一步是更好地了解哪些曲目被收听最多。

为此,我们必须查看 900 多个播放列表中包含的所有曲目。这导致了令人印象深刻的歌曲数量,因为 27,161 首不同的歌曲包含在所有播放列表中。

为了了解哪些歌曲在支持者中最受欢迎,我查看了哪些歌曲被添加到大多数播放列表中,并计算了每首歌曲的包含率。

收录率最高且最受阿贾克斯支持者欢迎的五首歌曲: 1) 安德烈·哈泽斯—布洛德、兹韦特·恩·特兰恩2)Joop leeuwendal—德·阿贾克斯·马希3)Kees Prins—Mijn Club4)**Sevn Alias—赫雷斯 5)**

Top 5 songs with highest inclusion rate

作为荷兰人,这些歌曲拥有最高的收录率并不奇怪,数据也证实了我最初的直觉。然而,有很多其他的歌曲似乎与 Ajax 有关联,这是我没有想到甚至不知道的。

我的目标是让自己熟悉阿贾克斯阿姆斯特丹国歌,但当你谈论 27K 首歌曲时,这似乎是一个相当大的挑战。因此,找到一种能让我很容易(重新)发现音乐的方式来想象这些歌曲是至关重要的。

创建 Ajax 自动点唱机

我认为我(和我的支持者们)在听所有 Ajax 歌曲的同时浏览数据会很有趣。我决定使用阿贾克斯的标志(代表希腊英雄阿贾克斯)来创建一个散点图点唱机。

converting a vector to a scatterplot

为了确保我们只查看与 Ajax 关联最多的歌曲,我在数据集上放置了一个过滤器,将它总结为包含率最高的 330 首歌曲。

圆圈的大小表明特定的轨道对 Ajax 来说更有特色(并且具有更高的包含率)。叉号表示包含的前五首曲目。一旦你选择了一首歌曲,将会提供一个 30 秒的音频剪辑,这样你就可以享受一些正宗的(主要是)荷兰音乐,并为阿贾克斯的下一场比赛进入状态。

每个人都可以通过Tableau Public访问 Ajax 点唱机。对于真正的 Ajax 爱好者来说,你可以通过 这里 下载一个高分辨率的散点图 iPhone 屏保。

在这里阅读更多我的故事:

** [## 可视化 2019 年美国公开赛的发球

今年夏天,我有机会参加了我的第一个大满贯网球锦标赛,美国公开赛。我很幸运地…

towardsdatascience.com](/visualizing-the-serves-of-the-2019-us-open-b575c61f58ef) [## 荷兰 DJ 的世界之旅

成为一名世界级的 DJ 并不全是闪闪发光和魅力。我是说,环游世界,紧张的旅行…

medium.com](https://medium.com/@boplantinga/the-journey-of-dutch-djs-around-the-world-d7434966ce9d) [## Pusha T vs. Drake:用数据备份他们的 diss 轨迹

也许没有必要花太多时间来介绍德雷克和普什塔之间的矛盾

towardsdatascience.com](/pusha-t-vs-drake-backing-up-their-diss-tracks-with-data-1083e6159c75)**

发现用 Python 包装的 Spotify 扩展的数据探索

原文:https://towardsdatascience.com/discovering-spotify-wrapped-an-extended-data-exploration-1975a8b7af29?source=collection_archive---------17-----------------------

2017、2018、2019 和十年;不仅仅是流计数,以交互方式呈现。

2010 年已经结束,除非你一直生活在岩石下,最*几天你很可能会遇到一个人全年收听历史的个性化视觉呈现;正式名称为 Spotify 裹 。虽然一些数据人员可能认为它本质上只是 SQL 查询中的 COUNT、SUM、WHERE 和 GROUP BY 的输出,但美观的可视化列表在上线当天成功地导致服务器因突发流量而停机,并通过大量的社交媒体分享将其订户转化为免费的品牌大使;由于 FOMO 综合症,我们大多数人都有。

Originally by Erik Herrström

看看下面的链接(如果你还没有的话),看看在各自的时间跨度内,全世界都在听些什么。

[## 你的 2017 年结束了

这一年即将结束。也就是说,你猜对了,是时候进行我们一年一度的音乐年活动了…

community.spotify.com](https://community.spotify.com/t5/Community-Blog/Your-2017-Wrapped/ba-p/3638025) [## 2018 年热门歌曲、艺术家、播放列表和播客——Spotify

2018 年即将结束,但在 Spotify 上,音乐一如既往地大声播放。一年到头,我们的用户…

newsroom.spotify.com](https://newsroom.spotify.com/2018-12-04/the-top-songs-artists-playlists-and-podcasts-of-2018/) [## 2019 年和过去十年的顶级歌曲、艺术家、播放列表和播客- Spotify

随着 2019 年接*尾声,Spotify 上的流媒体也将迎来辉煌的一年。你可能会回想过去的 12 年…

newsroom.spotify.com](https://newsroom.spotify.com/2019-12-03/the-top-songs-artists-playlists-and-podcasts-of-2019-and-the-last-decade/)

这些见解点燃了我的好奇心,让我去探索 Spotify 向我们展示的东西之外的东西。所以我决定推出我的 Jupyter 笔记本,并开始摆弄 2017 年、2018 年、2019 年和十年全球排行榜上的曲目数据。继续向下滚动,看看我发现了什么。

获取和清洁

首先,我使用 Spotipy (一个轻量级 Spotify Web API 库)检索了每个播放列表中每个曲目的音频特征。一个客户端 ID、一个秘密令牌、一些播放列表的唯一 ID 和几行脚本就可以完成这项工作,并将我们需要的信息编译到数据帧中。

Fetch track info & audio features

在撰写本文时,2017 年版的播放列表 ID 不再公开。幸运的是,我在 Kaggle 中找到了数据集(功劳归于 Nadin Tamer ),并做了一些调整以使系列完整。

在准备数据时,我决定只包括主要的艺术家,忽略有特色的艺术家,如果有的话,以保持分析简单。此外,在 200 首曲目(每首前 50 首)中,一些曲目被证明存在于其他播放列表中;杜阿·利帕新规则 ( 20172018)艾德·希兰 - 外形的你 ( 20172018十年摇滚明星后马龙在这种情况下,我通过按此顺序(2017 > 2018 > 2019 >十年)排列优先级来删除重复项。下面快速浏览一下我的最终数据(172 行 x 14 列)及其描述。

Final data randomly shuffled

  • 露骨:歌词中是否包含露骨词语或表达的指标。
  • 可跳舞性:根据速度、节奏稳定性、节拍强度和整体规律性,一首曲目适合跳舞的程度。(0~1)
  • 能量:基于动态范围、感知响度、音色、开始速率和一般熵的强度感知度量。(0~1)
  • :估计音轨的整体音高等级及其旋律内容来源的音阶类型。
  • 响度:声音的质量,是以分贝为单位的振幅的主要心理相关性。(-60~0)
  • 语速:音轨中出现的口语单词。(0~1)
  • 声学:音轨是否声学的置信度度量。(0~1)
  • 现场感:录音中有观众在场。较高的活跃度值表示音轨被现场执行的概率增加。(0~1)
  • 效价:一首曲目所传达的音乐积极性(如:快乐、愉悦、欣快)。(0~1)
  • 速度:轨道的整体估计速度,单位为每分钟节拍数(BPM)。( 50~200)
  • 时长:曲目的长度,以秒为单位。

事实上,我也可以有乐器拍号,但是大多数顶级曲目都不是乐器,只有 4 个四分音符节拍;使他们不太想被包括在内。

绘制分布图

我选择了 Plotly library 作为框架,这样你就可以四处徘徊了。右上角的工具栏也可能有助于进一步探索。建议在大屏幕上观看。

*只需点击 显示嵌入 如果遇到中等的 DNT 注。(见上文)

显式与非显式

  • 2019 (播放列表)显示在清晰度上2017 没有太大区别。
  • 显式轨迹与非显式轨迹在 2018 中处于水*
  • 第 28 个十年是与其他三个十年惊人的不同。(往年人们更喜欢露骨的内容吗?)

用什么调?

  • 不出所料,人们就是那么喜欢初学者友好的 c 大调音阶。
  • 约翰·传奇我的全部阿黛尔都是在第二届最受欢迎的 G#大调基础上发展而来。
  • B 小调代表前 3 的小调家族。

谁的声音最大?

  • 与其他播放列表相比,十年中的大多数歌曲的音量都更大
  • 两条比莉·埃利什最响的轨道导致 2019 射程更长。
  • 2017 中,哈立德位置百香果 by 德雷克噪音异常值。(双关语)

116 BPM还有相关性吗?****

  • 2017 集中在 100 BPM 左右。 Paris by 烟瘾者坐在 99.99。
  • ****2 图案大致分组在2018;有了 XXXTentacion 的变化的节拍最慢。
  • 《十年》看起来更稀疏,从乘客让她走法瑞尔·威廉快乐。(忽略好玩。 - 我们还年轻既然看来只查到了第一节的轨迹)****

多长时间才算够长?

  • 流行歌曲似乎有变短的趋势。
  • 皇后 - 波西米亚狂想曲令人惊讶的仅次于尼奥加西亚特博特
  • XXXTentacionJocelyn Flores 以不到 2 分钟的 2018 版。

Histogram and violin plot

全图对比

与上面的不同,让我们对其他特性进行另一种类型的比较。由于特征具有不同的范围,我需要使用最小-最大缩放器将值重新缩放到相对相似的范围。就原始数据的失真而言,这种定标器优于标准定标器。缩放后的 KDE 图如下所示:

看起来棒极了!现在所有的数据都在 0 和 1 之间;大多数特征分布是正态分布的,而且相当偏斜。缩放后的值对以后的聚类任务也很有用。下面绘制的是比较 4 个播放列表的每个特征的*均值。

一眼看去,播放列表中似乎没有明显的。仔细看, 2019 中的曲目与其他版本的相比更加声学十年少了言论大概是因为 Hip Hop 这几年的兴起。 20192018活跃度上的差距,和 10% 一样大。 2017 的热门歌曲似乎总是在每个功能的中间左右。****

KDE and radar plot

映射和聚类

在看到更大的图片后,我想知道一个特定的音轨相对于其他音轨的位置。主成分分析(PCA) 是最常见的线性降维技术之一。它强调变化,并在数据集中带出强模式。换句话说,它接受所有变量,然后在一个更小的空间中表示它,同时尽可能保持原始数据的性质。点击此链接获取 PCA 的简短直观说明。

因此,我尝试了一个快速的 Scikit-learn 调用,并拟合所有 9 个数字特征,以将维度减少到 3,这样它就可以被映射。预测后的解释方差比对于 PC1、PC2、PC3 分别为 27%、17%、15%。因为我的目的只是可视化,这些数字对我来说已经足够好了。然后,我取每个投影空间的特征向量相对于每个原始特征的绝对值。结果是在构成第一主成分中具有最大权重(负载)。

*为了更好地查看下面的情节,您可能想先点击 缩放 工具(工具栏上左数第二个),向前拖动直到您获得下降距离,然后返回到 转盘旋转 模式来徘徊。

在那里,您可以看到每首歌曲的位置及其与其他歌曲的距离,这是基于已转换的音频特征。大多数点都集中在黄色区域,只有少数粉红色点被发现。该映射也证实了化合价在某种程度上确实与 PC1 相关。忧郁的比莉·艾利什的可爱的和派对结束时的与更积极的截然相反——摇摆不定的无法留住我们麦克摩尔&瑞恩·刘易斯马克·朗森 - 上城放克

PCA implementation

本文的最后一部分是每个轨迹在各自簇中的投影。对于映射,我尝试了一种相对较新的非线性降维算法,称为均匀流形*似和投影(UMAP) 。它的工作方式类似于t-分布式随机邻居嵌入(t-SNE) ,但更具可扩展性,约束条件更少。两者都使用图形布局算法来构建一个高维表示,以表示其结构相似的低维表示。在这一页中的解释或许可以帮助你理解背后的直觉。

由于数据集相当小,因此层次聚类方法足以找到聚类。它假设每个点是一个单独的聚类,然后计算它们之间的接*度。它不断地合并聚类和更新矩阵,直到形成最合适的聚类。我遵循经验法则,通过检查树状图来选择聚类数,最终决定选择 5 作为最佳数,并手动调整 UMAP 算法的主要参数( n_neighbors = 10 和 min_dist = 0.01)。结果显示在下面的 2D 图上( 为了更好的视觉效果,我这次省略了歌名*

尽管 5 个主要簇没有完全分开,但它给了我们一个大画面,即轨道及其潜在的相似邻居是如何基于接*度进行分组的。相似性可以来自任何特征;无论是速度、可跳性、艺术家名字等等。有趣的是我喜欢卡迪 B妮琪·米娜星际飞船是多么的接*,西班牙歌曲集群 4 中形成一个子集,或者来自同一艺术家的曲目被密集投射。如果你有其他有趣的观察,请随意写在评论区。

*在下图中,我手动标记了在整个播放列表中拥有至少 4 首歌曲的顶级艺术家的位置。

UMAP implementation

附言

重新发现包装是一个有趣的旅程。作为一个狂热的音乐听众,浏览音频数据并了解流计数列表之外的信息是一种满足感。这个项目确实可以通过将更多的变量带入表中来扩展。除了前面提到的音频特征,细节如小节、节拍、小节、片段和状态可以给每首歌更多的身份。包含特色和相关艺术家将导致更健壮的映射和聚类。像歌词或社交媒体情绪这样的外部变量可能会使分析更加有趣。就个人而言,在 2020 Wrapped 中,我认为如果 Spotify 能够推出一些用户能够自己处理数据的功能,那就太好了。让我们看看他们会提供什么。

发现命名实体识别的基本工具

原文:https://towardsdatascience.com/discovering-the-essential-tools-for-named-entities-recognition-8176c94d9747?source=collection_archive---------4-----------------------

Photo by chuttersnap on Unsplash

都是名字的问题!

这封信是 E …开始!……”——我的一个兄弟说。

我们开始疯狂地写下每个类别中以 E 开头的单词。每个人都想在下午的比赛中赢得尽可能多的分数。

“站住!!!!!"——我姐姐突然宣布——“我已经完成了所有的分类”

我们不相信地盯着对方。

“好的。我们开始检查吧!”——我说。

我们开始一个接一个地列举我们在每个类别下输入的单词:水果、地点、名字…

“颜色名呢?”——我的另一个哥哥一度问道。

“祖母绿……”——姐姐骄傲地说。

Noo!不要。那不是颜色名!!!”——我的两个哥哥同时大声抱怨。

“当然是!如果没人放个颜色名我就拿双倍积分!”——她开心地回答。

每次我们玩 Scattergories 或者 Tutti Frutti 的时候,我们都会进行同样的讨论。关于颜色名称的规则每次都在改变。

这完全取决于当时的球员。正如我们后来了解到的那样,很多玩那个游戏的人身上发生了一些事情。

我们很容易将单词分类。我们可以在文章中分辨出哪个单词是名词、形容词还是动词。我们可以指出一个人、一个组织或一个国家的名称。

对于一台机器来说,这不是一件容易的事情。然而,我们已经走过了漫长的道路。

现在,我们不再需要花很长时间阅读长篇大论。我们可以使用机器学习算法从中提取有用的信息。

记得第一次读到自然语言处理(NLP)。我很难想象一个算法是如何识别单词的。它是如何识别它们的含义的。或者选择它们是哪种类型的单词。

我甚至不知道如何开始。信息太多了。在绕了一圈之后,我开始问自己我到底和 NLP 有什么关系。

我从不同的网站搜集了几个文本语料库。我的主要目标是提取和分类人名、组织名和地名等。

我手中的是一个命名实体识别(NER) 任务。

这些名称被称为实体,通常用专有名称来表示。它们有共同的语义属性。它们通常出现在相似的上下文中。

为什么我要提取这些实体?嗯,这么做有很多原因。

我们用语言相互交流。我们讲故事。我们陈述我们的想法。我们交流我们的感受。我们宣称我们喜欢什么、不喜欢什么或需要什么。

现在,我们大多通过书面文本传递信息。我们发微博。我们在博客中写作。这条新闻出现在一个网站上。所以书面文字是一个强大的工具。

让我们想象一下,我们有超能力知道哪些人、组织、公司、品牌或地点在网络上的每条新闻、推文或帖子中被提及。

我们可以检测并为每篇文章或帖子分配相关标签。这将有助于我们将它们分门别类。我们可以将他们与对阅读这类实体感兴趣的人特别匹配。所以我们会充当分类者。

我们也可以做相反的过程。任何人都可以问我们一个具体的问题。使用这些关键词,我们也能够非常高效地推荐文章、网站或帖子。听起来很熟悉?

我们可以更进一步,推荐产品或品牌。如果有人抱怨某个特定的品牌或产品,我们可以在几秒钟内很容易地将其分配到最不相关的部门。因此,我们将成为出色的客户支持。

你可以猜到,NER 是一个非常有用的工具。然而,任何事情都是有代价的。

在算法能够识别文本中的实体之前,它应该能够将单词分类为动词、名词、形容词。它们一起被称为词类

给它们标注的任务叫做词性标注,或者词性标注。该方法基于单词上下文和定义来标记单词。

Example of POS-tagging a text.

以句子为例:“新技术影响着整个世界”和“为了减少全球变暖的影响,我们现在应该做点什么”。“影响在每一句中都有两种不同的意思。

有几种监督学习算法可供选择:

基于词法的方法。他们在训练集中分配与一个词同现最频繁的词性。

概率方法。他们考虑特定标签序列出现的概率,并在此基础上进行分配。

基于规则的方法。他们创建规则来表示出现在训练集中的单词序列的结构。基于这些规则分配 POS。

深度学习方法。在这种情况下,循环神经网络被训练并用于分配标签。

训练 NER 算法需要合适的带注释的数据。这意味着您需要与您想要分析的数据类型相匹配的不同类型的数据。

数据还应附有注释。这意味着命名实体应该以可靠的方式为训练集进行识别和分类。

还有,我们要挑一个算法。训练它。测试一下。调整模型…

幸运的是,它们是 Python 中的几个工具,使我们的工作变得更容易。我们来回顾其中的两个。

1 自然语言工具包(NLTK): NLTK 是在 Python 中处理人类语言数据时使用最多的*台。

它提供了 50 多个语料库和词汇资源。除了其他功能之外,它还具有对文本进行分类、标记和标记的库。

对于下一部分,我们将得到更多的技术。开始吧!

Code showing the required NLTK modules to be imported.

在代码中,我们导入了模块ntlk以及方法word_tokenizepos_tag

第一个将帮助我们对句子进行标记。这意味着把句子分成记号或单词。

你可能想知道为什么我们不使用 Python 方法.split()。NLTK 将句子拆分成单词和标点符号。因此它更健壮。

第二种方法是将我们的标记“标记”到不同的词类中。

首先,我们将使用另外两个 Python 模块:requestsBeautifulSoup。我们将使用它们来搜集关于 NLTK 的维基百科网站。并检索其文本。

Code showing how to retrieve the text from a website using requests and BeautifulSoup.

现在,我们的文本在变量wiki_nltk中。

是时候看看我们的主要方法了。我们将创建一个将文本作为输入的方法。它将使用word_tokenize将文本分割成标记。然后,它将使用pos_tag标记每个标记的词性。

该方法将返回一个元组列表。每个元组由什么组成?嗯,一个单词及其标签;它所对应的演讲部分。

Code showing the method created. It takes the text, split it in tokens, and label them. It outputs a list with tuples.

之后,我们将该方法应用于我们的文本wiki_nltk。为了方便起见,我们将只打印前 20 个元组;每行 5 个。

标签很神秘,对吧?让我们来解码其中的。

DT 表示这个词是限定词。 NN 名词,单数。 NNP 专有名词,单数。一个并列连词。JJR 是形容词,比较级。副词。在介词中。

为什么pos_tag能够返回所有这些标签?

它使用概率方法。特别是条件随机场 (CRF)和隐马尔可夫模型。

首先,该模型提取每个单词的一组特征,称为状态特征。它基于诸如第一个字母的大写、数字或连字符、后缀、前缀等特征来做出决定。

该模型还考虑了称为过渡特征的函数中的前一个单词的标签。它将确定不同特征函数的权重,以最大化标签的可能性。

下一步是执行实体检测。这项任务将使用一种叫做 分块 的技术来完成。

标记化只提取“标记”或单词。另一方面,组块提取可能在文本中有实际意义的短语。

组块要求我们的文本首先进行标记和词性标注。它使用这些标签作为输入。它输出可以指示实体的“块”。

An example of how chunking can be visualized.

NLTK 有几个函数可以简化文本分块的过程。该机制基于使用正则表达式来生成组块。

我们可以首先应用名词代词组块或 NP-chunk s。我们将寻找匹配单个名词短语的组块。为此,我们将定制机制中使用的正则表达式。

我们首先需要定义规则。它们会指出句子应该如何分块。

Defining the rule of how sentences should be chunked.

我们的规则规定,我们的 NP 组块应该由可选的限定词(DT)后跟任意数量的形容词(JJ)以及一个或多个代词名词(NNP)组成。

现在,我们使用RegexpParser和这条规则创建一个块解析器。我们将使用chunkParser.parse把它应用到我们的词性标注单词上。

结果是一棵树。在这种情况下,我们只打印了块。我们也可以用图形显示出来。

Entities recognized in the text.

NLTK 还使用函数nltk.ne_chunk()提供了一个预训练的分类器。它允许我们识别文本中的命名实体。它也适用于带词性标签的文本。

Code showing how to use chunking for entity detection.

Entities recognized in the text.

正如我们所看到的,使用两种方法的结果是相同的。

然而,结果并不完全令人满意。NLTK 的另一个缺点是,词性标注支持英语和俄语。

2SpaCy 模型:Python 中的一个开源库。它通过标记连续记号组为 NER 提供了有效的统计系统。

它能够识别各种各样的命名或数字实体。其中,我们可以找到公司名称、地点、产品名称和组织。

Spacy 的一个巨大优势是拥有多种语言的预训练模型:英语、德语、法语、西班牙语、葡萄牙语、意大利语、荷兰语和希腊语。

这些模型支持标记、解析和实体识别。它们是专门为 spaCy 从头开始设计和实现的。

它们可以作为 Python 库导入。

Importing spacy and pre-trained model in English.

并使用spacy.load()轻松加载。在我们的代码中,我们将它保存在变量nlp中。

SpaCy 提供了一个标记器、一个位置标记器和一个命名实体识别器。所以非常好用。我们在文中称我们的模型为nlp(text)。这将标记它,给它加标签并识别实体。

属性.sents将检索令牌。.tag_每个令牌的标签。.ents公认的实体。.label_每个实体的标签。.text任何属性的文本。

我们为这项任务定义了如下方法。

现在,我们将定义的方法应用于我们的原始维基百科文本。

Spacy 不仅能识别名字,还能识别数字。很酷,对吧?

可能提出的一个问题是 SpaCy 是如何工作的。

它的架构非常丰富。这产生了非常有效的算法。解释空间模型的每个组成部分将需要另一整篇文章。甚至记号化都是以一种非常新颖的方式完成的。

根据爆炸 AI 的说法,Spacy 命名实体识别系统具有使用子词特征的复杂单词嵌入策略,具有残余连接的深度卷积神经网络,以及用于命名实体解析的新颖的基于转换的方法。

让我们一步步解释这些基本概念。

使用子词特征的词嵌入策略。 哇!很长的名字和很多难懂的概念。

这是什么意思?我们应该用多维数字向量来表示它们,而不是用文字。

每个维度都捕捉到单词的不同特征。这也被称为单词嵌入

好处是与数字打交道比与文字打交道更容易。我们可以计算,应用函数,等等。

最大的局限是这些模型通常会忽略单词的形态结构。为了纠正这一点,引入了子词特征,以包括关于词的形态结构的知识。

带残差连接的卷积神经网络 卷积网络主要用于处理图像。卷积层将内核或滤波器(带权重的矩阵)乘以窗口或输入矩阵的一部分。

传统的神经网络的结构是每一层反馈下一层。

具有残余块的神经网络将大网络分割成小块。这些网络块通过跳跃功能或快捷方式连接。

剩余网络的效率由激活函数必须被应用的次数更少这一事实给出。

过渡型 该策略使用连续的步骤来添加一个标签或改变状态,直到它到达最可能的标签。

最后,Spacy 提供了一个功能来显示带有命名实体注释的句子:displacy

让我们使用它!

…结束了!

命名实体识别是一个正在开发的工具。关于这个话题已经做了很多。然而,仍有改进的余地。

自然语言处理工具包——这是一个非常强大的工具。广泛使用。它为同一任务提供了多种算法可供选择。然而,它只支持 2 种语言。它需要更多的调音。它不支持单词向量。

SpaCy——这是一个非常先进的工具。它支持 7 种语言以及多语言。这样效率更高。它是面向对象的。但是,背后的算法很复杂。只保留任务的最佳算法。它支持单词向量。

总之,尽管去尝试一种方法吧!你会玩得开心的!

— 查看我的 GitHub 回购! —

用机器学习发现物理定律

原文:https://towardsdatascience.com/discovering-the-laws-of-physics-with-machine-learning-f2c2b5548fe?source=collection_archive---------23-----------------------

使用多项式回归来模拟和揭示重力

机器学习不仅在预测你接下来想看哪部电影方面,而且在推进科学研究方面都非常强大。它可以帮助科学家预测某些现象的结果,在某些情况下甚至揭示潜在的规律本身。

我们将看一个相当简单的例子:重力对下落物体的作用。如果你上过物理或微积分入门课,你会看到这个公式。但是,即使你只学过高中代数,你也能掌握它背后的数学。

下落物体位置的公式为:

其中:

=物体的初始位置,即其初始高度。

=物体在这个初始位置时的初速度(或速度)。

t =物体掉落后的时间。

g =重力,也就是大约 9.8 米/秒的加速度。这实际上是一个常数,而不是像所有其他变量一样的变量(除非我们将一个物体投放到不同的行星上,但事实并非如此)。它是负的,因为重力是向下的,从正的位置值朝向零。

这个方程是一个二次多项式(由于 t ) ,你可能还记得代数中的这个方程。像 scikit-learn 这样的机器学习库可以使用线性回归非常容易地处理这个问题。这个数据实际上不是线性的,但是 scitkit-learn 让我们能够修改数据,以便可以将它训练为线性回归模型,同时考虑到它实际上是一个多项式。

为了继续,我们需要一些数据。我们可以将许多不同的物体丢下 10,000 次,并记录它们在不同时间的位置,但这相当耗时。相反,我们将从上面的等式中创建数据集。幸运的是,由于艾萨克·牛顿的工作和数百年来重复的实验,我们可以肯定我们的数据将反映现实世界中发生的事情。

创建我们的数据集

首先,我们将创建一个 Python 函数来计算下落物体的位置:

**def location(x_0, v_0, t):
    return x_0 + v_0*t - (9.8/2)*t**2**

这只是 Python 形式的前一个等式。接下来,我们使用这个函数创建一个数据集,并将其保存在一个 CSV 文件中:

**import csv
import random
import math
random.seedwith open('gravity_location_data.csv', mode='w') as gravity_file:
    gravity_writer = csv.writer(gravity_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    gravity_writer.writerow(['initial_position', 'initial_velocity', 'mass', 'time', 'location'])for i in range (0, 10000):
        initial_position = random.randrange(1, 10000)
        initial_velocity = random.randrange(1, 100)
        mass = random.randrange(1, 1000)
        time = random.randrange(1, 100)gravity_writer.writerow([initial_position, initial_velocity, mass, time, location(initial_position, initial_velocity, time)])**

我们在这里做的是创建 10,000 个例子,使用我们所有变量的随机值,然后计算在某个(随机选择的)时间的位置。关于这一点,有几点需要注意。

首先,一些位置值将是负的。这不应该困扰你,它只是意味着物体已经下降到我们定义为零的某个高度以下。想象一下,你站在悬崖边,拿着一个与眼睛齐*的物体,然后把它从悬崖上扔下去。在这种情况下,零是你脚的位置,-100 是你脚下 100 米,1.85 米是你放下它的初始位置(即你自己的高度,如果你身高 6 英尺)。

智胜亚里士多德

第二,注意我们在数据中包括了物体的质量。这实际上与计算物体坠落时间或位置完全无关。这个事实对于那些在高中或大学没有学过物理的人来说可能是违反直觉的。事实上,亚里士多德相信这一点,数百年来许多人都相信这一点,直到伽利略从比萨斜塔上扔下两个不同重量的球体,并证明它们同时落地。

看原方程。质量是无处可寻的,因为不同质量的物体以相同的加速度下落,假设我们可以忽略空气阻力(我们经常可以做到)。

那么为什么要把质量包括在这个数据集中呢?因为我们想尝试欺骗机器学习算法来使用它!我们将会看到我们的机器学习实验是否能智胜亚里士多德。

现在我们已经将数据保存在 CSV 文件中,我们导入它:

**import pandas as pdgravity_data = pd.read_csv('gravity_location_data.csv')
df_location = pd.DataFrame(gravity_data)**

与机器学习一样,我们需要将数据分成一个训练集(用于训练模型)和一个测试集(用于评估训练好的模型)。这个函数将完成这个任务。

**from sklearn.model_selection import train_test_splitdef split_data(data, target_name):
    y = data[target_name]
    X = data.drop(target_name, axis=1)
    return train_test_split(X, y, test_size=0.2, random_state=30)**

为了训练和评估我们的模型,我们将使用以下函数:

**from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from math import sqrtdef train_eval_poly(X_train, X_test, y_train, y_test):
    regression_model = LinearRegression() 

    poly = PolynomialFeatures(degree=2)
    X_train_transform = poly.fit_transform(X_train)
    X_test_transform = poly.fit_transform(X_test)

    regression_model.fit(X_train_transform, y_train)

    print(poly.fit(X_train).get_feature_names(X_train.columns))

    y_pred = regression_model.predict(X_test_transform)
    print("R2: \t", r2_score(y_test, y_pred))
    print("RMSE: \t", sqrt(mean_squared_error(y_test, y_pred)))
    print("MAE: \t", mean_absolute_error(y_test, y_pred))

    return regression_model**

请注意,这只是线性回归,只是我们使用多项式功能来转换数据,以便线性回归可以正确地模拟二次多项式,我们碰巧知道在这种情况下这正是我们要寻找的。我们将在下面看到更多关于数据如何转换的内容。

在我们训练模型之后,我们将获得特征名称,这将告诉我们如何分配结果系数。

现在我们用以下代码训练模型:

**df_split = split_data(df_location, 'location')
lrModel = train_eval_poly(*df_split)**

当我运行上面的代码时,我得到了下面的输出(由于随机化的值,在不同的尝试中会略有不同):

**['1', 'initial_position', 'initial_velocity', 'mass', 'time', 'initial_position^2', 'initial_position initial_velocity', 'initial_position mass', 'initial_position time', 'initial_velocity^2', 'initial_velocity mass', 'initial_velocity time', 'mass^2', 'mass time', 'time^2']
R2: 	 1.0
RMSE: 	 2.858993700594185e-09
MAE: 	 2.4177281243084604e-09**

请注意,r 值是 1.0 —我以前从未见过!此外,均方根误差(RMSE)和*均绝对误差(MAE)非常小—e-09表示将前面的数字乘以. 000000001。所以均方根误差实际上是 0.00000000285…在这个范围内,这是很小的,基本上为零。

多项式特征的多项式回归

还要注意上面结果中的 15 个条目的初始列表。这是多项式特征方法的结果。它转换了四个特征的初始集(“初始位置”、“初始速度”、“质量”、“时间”),并将它们更改为这些特征的组合,如“初始位置^ 2”和“初始位置时间”,其值为初始位置乘以时间。这个扩展的特征集然后被输入到简单的旧线性回归中。这是一个小技巧,它允许我们不使用不同的算法,而是使用转换后的数据来执行多项式回归。

现在让我们来看看模型中的指数,它们是模型用来进行预测的多项式方程中的指数:

**lrModel.coef_**

这为我们提供了以下内容,分别对应于上述十五个特征:

**array([ 0.00000000e+00,  1.00000000e+00,  1.55880730e-12,  6.28398701e-15,
       -4.95194273e-14, -1.69455737e-16,  2.20395687e-16,  5.63820313e-18,
        1.73104757e-16, -1.06371232e-14,  4.99284970e-16,  1.00000000e+00,
       -2.55450811e-16,  1.73797602e-16, -4.90000000e+00])**

第一个值(0.00000000e+00 或 0)是值 1 的系数。这将是一个没有变量的悬挂常数,一个常数值总是加到方程中,除了系数是零,所以没有常数值加到我们的结果中。数组中的第二个值(1.00000000e+00,或 1)是“initial_position”的系数事实上,在我们的原始方程中,我们有初速度( X₀) ,系数为 1

我们的大多数其他系数本质上为零,并告诉我们这些因素与预测位置无关,但我们确实有一些不是。我们列表中的第十二个也是系数 1,对应于‘初速度时间’,或者初速度乘以时间。同样,我们在原始方程中有这个因素,它表现为 V₀t.*

最后,最后一个值是-4.9,这是对应于“时间^ 2”的系数请注意,这也出现在我们的原始方程作为-1/2 gt。但是我们前面说过 g 大约是 9.8,而-1/2 * 9.8 = -4.9。所以这也符合我们最初的方程。

如果您将这些系数与功能名称列表中的变量组合进行匹配,并将它们相加,并忽略系数基本为零的情况,您最终会得到一个非常接*我们在本文顶部开始时的方程。

这里有两个非常有趣的结论。首先,最终的模型发现质量与预测无关,这是正确的。

第二,机器学习算法能够导出重力加速度常数 g,** 或者至少确定包括 g 在内的整个系数的值(-1/2 * 9.8)。**

换句话说,用 Python 和 scikit-learn 可以在几秒钟内发现艾萨克·牛顿和伽利略的一些工作。这太令人兴奋了。

当然,分析和理解这些结果仍然需要大量的人类干预,但这至少让我们看到了如何从数据中提取对宇宙基本规律的见解。

将 2D 图像离散成多边形和点模型

原文:https://towardsdatascience.com/discretizing-2d-images-into-polygonal-and-point-models-9e91c239b329?source=collection_archive---------23-----------------------

将复杂的图像简化为简单的数据格式

现实世界是复杂多变的。随着机器人技术和自动驾驶汽车的发展,人们普遍需要将物体简化为更易于管理的形式。此外,我们的世界是连续的(在大多数情况下),然而我们的技术以数字方式解释内容。因此,对于任何世界互动,都会有某种程度的离散化。

对于我正在开发的一个机器人抓取项目,我最*遇到了这个问题。2D 形状是存在的,并且表面信息需要被外推以确定在哪里抓取该形状。幸运的是,OpenCV 有办法将弯曲的轮廓简化成更加多边形的形状。让我们来看看这些函数及其结果。

A key and the result after salience detection.

在得到一幅图像后,我们使用我们最喜欢的显著性方法抓取感兴趣的项目。如上例所示,这为感兴趣的对象创建了一个相当不错的遮罩。可以看出,如果试图进行任何几何操作,都会出现困难。例如,钥匙手柄的曲率会使确定法向量变得困难。此外,分割过程中拾取的噪声会产生错误的边缘。

方便的 OpenCV 函数approxPolyDP()用于将轮廓*似为更少的点。该函数使用Ramer–Douglas–peu cker 算法来减少点数。这是一个取常数值的递归算法, ε。 算法从寻找两个起始点的最远点开始。如果该点小于 ε ,那么前两个起点之间的所有点都被丢弃。否则,该算法再次*分该组点,并向下递归到下一组点。对每个二等分的集合重复该过程。

A handy animation of theDouglas–Peucker algorithm. Source

通过改变 ε 的值,可以实现不同层次的“离散化”。该值越大,最终形状的多边形程度越高。

From Left to Right, Top to Bottom: ε = 0.5, 2, 5, 20

对于许多应用来说,以上是一个完美的解决方案。然而,一些处理离散现实世界物体的算法会进一步将多边形分解成连续的点。这将涉及更多的信息存储,但可以提供更多的信息。

从上面的多边形创建一个基于点的物体框架并不困难。有了组成多边形的连续顶点的数组,我们可以沿着每条边迭代。对于每条边,确定两个顶点之间的向量。沿着每个向量,根据期望的分辨率生成一定百分比的点。我们使用的分辨率将决定每条边上的点数。

The dotted with a resolution of 10%

利用所描述的方法,相当复杂的形状可以简化为简单的边或点。如果需要与对象进行任何交互或需要进行几何分析,这将非常有用。如果正在构建某个对象识别方案,比较简化的对象可能更有意义。这让我们可以忽略细节和特质。

本文是一个正在进行的项目的一部分。正在进行的 C++代码可以在我的 github 上找到:

[## TimChinenov/GraspPicture

用于分割显著的彩色图像并确定抓取的代码。- TimChinenov/GraspPicture

github.com](https://github.com/TimChinenov/GraspPicture)

分类判别网络

原文:https://towardsdatascience.com/discriminating-network-for-classification-fb18d87ba21b?source=collection_archive---------3-----------------------

我如何使用暹罗网络建立一个只有很少图像的分类器

一个有鉴别能力的网络——它是什么,我们为什么需要它,我们如何建立它?

我们经常遇到的问题是,我们没有足够的高质量图像和标签数据集来训练一个健壮的基于 CNN 的分类器——要么我们没有足够的图像,要么我们没有手动资源来标记它们。用很少的图像建立一个健壮的分类器通常是一个挑战,因为我们需要成千上万的标签图像来训练一个健壮的神经网络体系结构

在面部识别中经常使用有区别的连体结构。根据这篇研究论文,现代面部识别模型通常是使用暹罗网络(也称为一次性学习)建立的

以上是一张连体网。这是简单明了的两个网络——在本例中,两个 Resnet-50 架构的权重相同——一个左网络和一个右网络。每个网络为其对应的图像输出数字串的编码。暹罗网络广泛用于面部识别。在这种情况下,我已经用它对猫和狗进行了分类。这种建筑学习的方式是——一只猫和另一只猫比和一只狗更相似。不同的猫会有不同的特征,但是猫之间的不同会比猫和狗之间的不同小。这两种编码之间的差异是猫和狗的编码之间的欧几里德距离。如果编码属于两个狗或猫图像,我们将目标标记为阳性或 1,否则如果一个图像是狗,另一个图像是猫,反之亦然,我们将目标标记为阴性类别或 0

这方面另一篇有趣的研究论文:

编码片段:

正在加载所有必需的库

from keras.layers import Input, Conv2D, Lambda, merge, Dense, Flatten,MaxPooling2D,Activation, Dropout
from keras.models import Model, Sequential
from keras.regularizers import l2
from keras import backend as K
from keras.optimizers import Adam
from keras import optimizers
#from skimage.io import imshow
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import randomfrom keras.backend.tensorflow_backend import set_session
from keras.applications import resnet50, vgg16, vgg19, xception, densenet, inception_v3, mobilenet, mobilenetv2, nasnet, inception_resnet_v2
import tensorflow as tf
from keras.callbacks import ModelCheckpoint, TensorBoard, CSVLogger, EarlyStopping
from keras.applications.resnet50 import preprocess_input
#from keras.applications.xception import preprocess_input
import os
import datetime
import json
from keras.preprocessing.image import ImageDataGenerator 

让我们使用 OpenCV 库抓取和处理图像。我用过 100 张猫的图片和 100 张狗的图片。猫和狗的形象属于不同的品种。

100 张猫咪图片:

100 张狗狗图片:

加载和预处理图像的代码片段:

import glob
import cv2
from random import shuffledog_path = 'Y:\\Partha\\dog_cats_100\\dog\\*.jpg'
cat_path = 'Y:\\Partha\\dog_cats_100\\cat\\*.jpg'addrsd = glob.glob(dog_path)
addrsc = glob.glob(cat_path)

labelsd = [1 for addr in addrsd]  # 1 = dog, 0 =  cat
labelsc = [0 for addr in addrsc]# loop over the input imagesdatad = []for imagePath in addrsd:
# load the image, pre-process it, and store it in the data list
    img = cv2.imread(imagePath)
    img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_CUBIC)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    datad.append(img)datac = []
for imagePath in addrsc:
# load the image, pre-process it, and store it in the data list
    img = cv2.imread(imagePath)
    img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_CUBIC)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    datac.append(img)# to shuffle data
shuffle_data = True
if shuffle_data:
    d = list(zip(datad, labelsd))
    c = list(zip(datac, labelsc))
    e = d + c
    shuffle(e)
    data, labels = zip(*e)del datad
del datac
del addrsd
del addrsc

Y_train = np.array(labels)
X_train = np.array(data, dtype="int8")#preprocess for Resnet- 50
X_train =  preprocess_input(X_train)

定义架构的代码片段:

# Two inputs one each - left and right image
left_input = Input((224,224,3))
right_input = Input((224,224,3))#Import Resnetarchitecture from keras application and initializing each layer with pretrained imagenet weights.'’'
Please note that it’s usually better to intialize the layers with imagenet initializations than random. While training I will be updating the weights for each layer in each epoch. we don’t want to confuse this activity with transfer learning as I am not freezing any layer but initilializing each layer with imagenet weights
'’'convnet = resnet50.ResNet50(weights='imagenet', include_top=False, input_shape=(224,224,3))# Add the final fully connected layersx = convnet.output
x = Flatten()(x)
x = Dense(1024, activation="relu")(x)
preds = Dense(18, activation='sigmoid')(x) # Apply sigmoid
convnet = Model(inputs=convnet.input, outputs=preds)#Applying above model for both the left and right images
encoded_l = convnet(left_input)
encoded_r = convnet(right_input)# Euclidian Distance between the two images or encodings through the Resnet-50 architectureEuc_layer = Lambda(lambda tensor:K.abs(tensor[0] - tensor[1]))# use and add the distance function
Euc_distance = Euc_layer([encoded_l, encoded_r])#identify the prediction
prediction = Dense(1,activation='sigmoid')(Euc_distance)#Define the network with the left and right inputs and the ouput prediction
siamese_net = Model(inputs=[left_input,right_input],outputs=prediction)#define the optimizer. Here I have used SGD with nesterov momentum optim = optimizers.SGD(lr=0.001, decay=.01, momentum=0.9, nesterov=True)#compile the network using binary cross entropy loss and the above optimizer siamese_net.compile(loss="binary_crossentropy",optimizer=optim,metrics=[’accuracy’])

现在,我已经创建了图像对。将有两个标签——1 和 0,或者我们可以说输出的正或负标签或类别。

创建测试训练数据集的代码段

image_list = X_train[:180]
label_list = Y_train[:180]left_input = []
right_input = []
targets = []#Number of pairs per image
pairs = 8#create the dataset to train on
for i in range(len(label_list)):
    for j in range(pairs):
# we need to make sure that we are not comparing with the same image
        compare_to = i
        while compare_to == i: 
            compare_to = random.randint(0,179)
        left_input.append(image_list[i])
        right_input.append(image_list[compare_to])
        if label_list[i] == label_list[compare_to]:
            # if the images are same then label - 1
            targets.append(1.)
        else:
            # if the images are different then label - 0
            targets.append(0.)

#remove single-dimensional entries from the shape of the arrays and making them ready to create the train & datasets 

#the train data - left right images arrays and target label
left_input = np.squeeze(np.array(left_input))
right_input = np.squeeze(np.array(right_input))
targets = np.squeeze(np.array(targets))# Creating test datasets - left, right images and target labeldog_image = X_train[4] #dog_image = 1, cat_image = 0test_left = []
test_right = []
test_targets = []for i in range(len(Y_train)-180):
    test_left.append(dog_image)
    test_right.append(X_train[i+180])
    test_targets.append(Y_train[i+180])test_left = np.squeeze(np.array(test_left))
test_right = np.squeeze(np.array(test_right))
test_targets = np.squeeze(np.array(test_targets))

在 GPU 中训练网络的代码

import tensorflow as tf
import os
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config)
#from keras_input_pipeline import *
os.environ['CUDA_VISIBLE_DEVICES'] = '1'siamese_net.summary()
with tf.device('/gpu:1'):
    siamese_net.fit([left_input,right_input], targets,
          batch_size=16,
          epochs=30,
          verbose=1,
          validation_data=([test_left,test_right],test_targets))

结果:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_10 (InputLayer)           (None, 224, 224, 3)  0                                            
__________________________________________________________________________________________________
input_11 (InputLayer)           (None, 224, 224, 3)  0                                            
__________________________________________________________________________________________________
model_7 (Model)                 (None, 18)           126367634   input_10[0][0]                   
                                                                 input_11[0][0]                   
__________________________________________________________________________________________________
lambda_4 (Lambda)               (None, 18)           0           model_7[1][0]                    
                                                                 model_7[2][0]                    
__________________________________________________________________________________________________
dense_12 (Dense)                (None, 1)            19          lambda_4[0][0]                   
==================================================================================================
Total params: 126,367,653
Trainable params: 126,314,533
Non-trainable params: 53,120
__________________________________________________________________________________________________
Train on 1440 samples, validate on 22 samples
Epoch 1/10
1440/1440 [==============================] - 91s 64ms/step - loss: 0.7086 - acc: 0.5354 - val_loss: 0.6737 - val_acc: 0.5455
Epoch 2/10
1440/1440 [==============================] - 76s 53ms/step - loss: 0.5813 - acc: 0.7049 - val_loss: 0.6257 - val_acc: 0.5909
Epoch 3/10
1440/1440 [==============================] - 76s 53ms/step - loss: 0.4974 - acc: 0.8257 - val_loss: 0.6166 - val_acc: 0.5909
Epoch 4/10
1440/1440 [==============================] - 76s 53ms/step - loss: 0.4494 - acc: 0.8799 - val_loss: 0.6190 - val_acc: 0.5909
Epoch 5/10
1440/1440 [==============================] - 76s 53ms/step - loss: 0.4190 - acc: 0.9042 - val_loss: 0.5966 - val_acc: 0.6364
Epoch 6/10
1440/1440 [==============================] - 76s 53ms/step - loss: 0.3968 - acc: 0.9243 - val_loss: 0.5821 - val_acc: 0.6818
Epoch 7/10
1440/1440 [==============================] - 76s 53ms/step - loss: 0.3806 - acc: 0.9368 - val_loss: 0.5778 - val_acc: 0.6818
Epoch 8/10
1440/1440 [==============================] - 76s 53ms/step - loss: 0.3641 - acc: 0.9535 - val_loss: 0.5508 - val_acc: 0.7273
Epoch 9/10
1440/1440 [==============================] - 76s 53ms/step - loss: 0.3483 - acc: 0.9715 - val_loss: 0.5406 - val_acc: 0.7273
Epoch 10/10
1440/1440 [==============================] - 76s 53ms/step - loss: 0.3390 - acc: 0.9778 - val_loss: 0.5341 - val_acc: 0.7273

我们可以看到,仅用 100 张猫和 100 张狗的图像,我们就在 8 个时期的验证数据集中实现了 72%的准确率,这些图像对是从 200 张图像中创建的。

结论:

我写这篇文章的动机是,我们通常没有成百上千的高质量标记图像来创建健壮的基于 CNN 的分类器。或者,我们可以用很少的图像来训练一个广泛用于面部识别的连体网络,以建立一个分类器。我已经在我的一个材料缺陷检测用例中使用了这种技术,在这个用例中,我们几乎没有缺陷材料的可用图像。为了保持作品的保密性,我在这个博客中用猫和狗的图像来演示这个讨论。如果你喜欢我的博客,请点击拍手按钮,并请继续关注我们未来的博客,因为我经常在机器学习和深度学习方面发表博客。

解开缠绕:NEURIPS 的脚注— 2019

原文:https://towardsdatascience.com/disentangling-disentanglement-in-deep-learning-d405005c0741?source=collection_archive---------12-----------------------

Credit: ‘ Striving for Disentanglement’ by Simon Greig — https://www.flickr.com/photos/xrrr/500039281/

TL;博士:解开,解开。通过这篇博文,我打算尝试总结今年在 2019 年温哥华 NEURIPS-2019 上发表的关于深度学习中的解纠缠的十几篇论文。

充满论文摘要和备忘单的配套 Github repo:https://Github . com/vinay prabhu/distanglement _ neur IPS _ 2019/

背景:表象学习中的解开

在会议周的周四晚上,当我在温哥华会议中心巨大的东展厅的海报会议上闲逛时,我意识到我在过去几天里偶然发现了可能是第五张海报,这需要对作者们工作的一个解开框架进行分析。

Fig 1: (Yet another) Poster on disentanglement at this year’s NEURIPS

快速查看一下的进程,我得到了这个令人震惊的统计数据:今年共有十几篇标题为“解开”的论文被接受。在众多的车间里,我至少还偶然发现了一些。(2017 年 NEURIPS 研讨会期间有 20 多篇论文和演讲,主题是“学习解开表征:从感知到控制”——https://sites.google.com/view/disentanglenips2017,我们今年还举办了一场挑战研讨会:https://www . ai crowd . com/challenges/neur IPS-2019-解开表征-挑战)

我第一次感受到这个术语在统计学习中的用法是在我在 CMU 大学博士旅程的最后阶段(大约 2013 年),当时我读了 Yoshua Bengio 的《深度学习表征:展望》一书,他在书中强调了“成为”的必要性..学习理清观察数据背后的变异因素。(我多么希望他仍然撰写这样的单作者论文)

事实证明,也许让物理学家很懊恼的是,如果你正致力于从 MNIST 上的数字类型中梳理出视觉风格,或者从西里巴上的面部形状中分离出人体和面部特征图像中的形状和姿势,或者努力解开两种组成化合物的混合比例和环境因素(例如为微结构生长而生成的图像中的热波动)的影响,你就在理清头绪。

对于这个术语的确切含义或捕捉其范围的度量标准似乎没有达成共识,斯塔法诺·索阿托在 IPAM 的演讲中的这张相当有趣/尖刻的幻灯片证实了这一点(参考下面的播放列表)

Fig 2: Invariance and disentanglement in deep representations

也就是说,这不是一个存在仅仅少量的经验实验的案例,这些实验都使用他们自己定制的解开概念。事实上,人们已经提出了相当严格的框架,利用来自变分推理、Shannonian 信息论、群论和矩阵分解等领域的强大工具。Deepmind 对这一问题的群论处理似乎已经成为一个首选框架。如果你正在寻找一个简洁的 3 分钟回顾,请参考这个视频,我在西蒙斯学院的一个研讨会上看到的(大约 7 分钟)。(可以在这里找到来自 Deepmind group 的主要作者之一的非常详细的演讲)

Fig 3: Group theoretic framework for disentanglement

对提交的论文的鸟瞰

下面的图 4 是 12 篇论文的鸟瞰图。我粗略地将它们分成两个小节,这取决于的主要感知的论文目标(从我的拙见来看)是分析和/或评论一个预先存在的框架的属性,还是利用一个框架并将其应用于一个有趣的问题领域。请记住,这无疑是一个相当简单的分类,对于面向应用的论文是否对所使用的框架进行了评论和分析,或者分析/评论论文是否不包括现实世界的应用,这并没有很大的指导意义。

Fig 4: Disentanglement papers categorization (NEURIPS -2019)

(可以在这里找到论文链接的 pdf 版本:https://github . com/vinay prabhu/distanglement _ neur IPS _ 2019/blob/master/distanglement _ papers _ tree-diagram . pdf)

他们所说的解开是什么意思?

为了总结这些论文中使用解纠缠的上下文,我创建了一个查找表(见表 1)。在那些作者明确没有专门的小节来定义的情况下,我临时拼凑并提取了要点(因此有了“即兴解释”)。

Table-1(a) Disentanglement context in the application papers

Table-1(b) Disentanglement context in the analysis papers

可复制性和开源代码:

鉴于开源用于产生结果的代码的强劲增长趋势,12 个作者组中的 10 个也共享了他们的 github repos。下面的表 2 显示了这一点:

Table-2: Papers and the open-source code links

现在怎么办?一些想法..

[这里有一些涂鸦,试图让我自己更认真地工作。请半信半疑地接受这些或 12:)

1:调查报告,详细说明要使用的定义、框架和指标。

2:使用卡纳达语-MNIST 语数据集解开作者/写作风格/原籍国。(65 名印度本土志愿者和 10 名美国非本土志愿者)

https://github.com/vinayprabhu/Kannada_MNIST

3:有点令人惊讶的是,没有人尝试抛出一个 K 用户干扰信道模型进行纠缠,并看看类似 https://arxiv.org/pdf/0707.0323.pdf 的干扰对齐技巧是否适用于类似 Dsprites 的数据集

4:从步态表征中分离鞋类型、口袋和设备位置

5:连接与(高光谱)解混 /盲源分离和解纠缠表示学习相关的工作主体。

资源列表:

充满论文摘要和备忘单的配套 github repo。

[## vinayprabhu/distanglement _ neur IPS _ 2019

TL;DR - On 解开解开论文的动物园在这次 NEURIPS(2019)期间,我遇到了大量的…

github.com](https://github.com/vinayprabhu/Disentanglement_NEURIPS_2019)

A.数据集入门:

[1]https://www.github.com/cianeastwood/qedr

https://github.com/deepmind/dsprites-dataset

https://github.com/rr-learning/disentanglement_dataset

(neur IPS 2019:distanglement 的主要道具也向组织者挑战他们共享的资源!)

链接:https://www . ai crowd . com/challenges/neur IPS-2019-distanglement-challenge

[## Google-research/distanglement _ lib

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/google-research/disentanglement_lib/tree/master/disentanglement_lib/evaluation/metrics)

B.视频播放列表:

[1] Y. Bengio 的《从深度学习解开表征到更高层次的认知》

https://www.youtube.com/watch?v=Yr1mOzC93xs&t = 355 秒

2\贝塔-VAE(deep mind):【https://www.youtube.com/watch?v=XNGo9xqpgMo】T2

[3]柔性公*表征解缠学习:【https://www.youtube.com/watch?v=nlilKO1AvVs】T4&t = 27s

4用于姿态不变人脸识别的解纠缠表征学习 GAN:https://www.youtube.com/watch?v=IjsBTZqCu-I

【5】深层表象中的不变性与解纠缠(趣谈)https://www.youtube.com/watch?v=zbg49SMP5kY

(来自 NEURIPS 2019 作者)
[1]审计模型预测论文:https://www.youtube.com/watch?v=PeZIo0Q_GwE

2对 Olivier Bachem 的 Twiml 采访(在 NEURIPS-19 上有 3 篇关于该主题的论文):https://www.youtube.com/watch?v=Gd1nL3WKucY

C.备忘单

Cheat sheet-1: All the abstracts! (Print on A3/2)

Cheat sheet-2: All the essences!

机器学习中的距离函数:用简单语言编写的初级读本,动作点少。

原文:https://towardsdatascience.com/distance-functions-in-machine-learning-a-primer-in-simple-language-with-few-action-points-f5e328759b24?source=collection_archive---------10-----------------------

https://www.machinelearningplus.com/statistics/mahalanobis-distance/

大多数数据科学问题的关键是定义给定观测值之间的距离或相似性函数。相似性度量将用于度量在给定的 n 维空间中观察值有多*或多远。对于给定的问题,有许多距离函数可供使用,我不想在这里详细描述所有的距离函数,而只是关于这些函数的简短信息,这些信息是我在数据智能和分析的课程中有机会看到的整体观点(由 IITH 的sob Han Babu博士提供)。本指南面向入门级数据科学学生。

欧几里德距离

这等于两点之间的直线距离或最短距离或位移(..假设是二维的,但也可以是多维的)。这是成对的距离,也是测量两点间距离的默认度量。它对许多任务都很有用,但在数据具有以下特征的情况下要谨慎使用

a)极端或更多异常值。由于该距离是 L2 范数,当数据点之间存在异常值时,异常值的影响被放大。

b)相关性。这个距离没有考虑到观察中的变量可以相互关联(..为什么?)

c)如果数据集中的变量数量很多(比如> 7),余弦距离优于欧几里德距离。为什么?

d)当然,根据 L2 范数的定义,变量是彼此相减的,这使得所有的变量必须是实值。如果欧几里德距离必须应用于分类数据,那么数据首先必须被编码成实数值。然而,这不是衡量分类变量之间距离的最佳方式。(..为什么?)

马哈拉诺比的距离:

该距离是相关性调整后的距离(..(欧几里得)在一对给定的数据点之间。要了解为什么需要去相关,请访问此 页面 查看示例。给出的示例说明了使用欧几里德距离对变量相关的点进行聚类时的问题。

a)如果数据是数字的、相关的且变量数量适中,则最好使用马哈拉诺比距离(..<10)

余弦距离:

顾名思义,它与三角余弦函数有些关系。角的余弦由邻边的长度除以斜边给出。当你考虑两点之间的距离时,想象从原点出发的两个向量,那么向量之间的角度的余弦由点积除以它们的长度给出。这实际上会减轻长短向量的影响,具有异常值的数据点之间的余弦距离不会像欧几里德距离那样被放大。

a)如果有大量变量,最好使用余弦距离(..比方说> 8)。

匹配和雅克卡系数:

匹配系数和 Jaccard 系数在推导过程中非常接*,用于衡量分类变量何时出现在数据中。

让我们以只有两个级别的三个变量为例:

X1 : M,N,Y,N

X2: F,Y,Y,N

这些情况可以编码如下(..任意考虑 M,Y 为 1,N,F 为 0):

1,0,1,0

0,1,1,0

匹配系数:(1 和 0 中的相同匹配(…两者/所有类))/(所有类)= 2/4

Jaccard 系数:(1 中的相同匹配(…仅正/利息类别))/所有类别= 1/4

a)使用 Jaccards coef。在匹配 1 比匹配 0 具有更强的相似直觉的情况下

b)如果数据既是 Jaccard 又是匹配 coef,则使用 Kendall Tau 距离。将数据视为名义类。

混合数据

当数据中既有分类变量又有数值变量时,通常采用以下方法。

a)使用分类的一键编码或其他编码方法将所有内容转换成数字,并使用欧几里德、马氏、余弦或其他(..曼哈顿、相关性等)来测量数据点的距离/相似性。

b)将数据划分为两组变量,即数值变量和分类变量,并使用适当的距离度量分别计算两个分区之间的距离。然后组合成单个测量值,

(W1 * P1 + W2 * P2) / (W1+W2)。

更多参考资料:

https://www . research gate . net/publication/327832223 _ Distance-based _ clustering _ of _ mixed _ data

[## 距离度量在机器学习建模中的重要性

许多机器学习算法——有监督的或无监督的,使用距离度量来了解输入数据…

towardsdatascience.com](/importance-of-distance-metrics-in-machine-learning-modelling-e51395ffe60d) [## 机器学习中如何测量距离

这完全取决于你的观点

towardsdatascience.com](/how-to-measure-distances-in-machine-learning-13a396aa34ce)

提取 BERT——如何使用逻辑回归实现 BERT 性能

原文:https://towardsdatascience.com/distilling-bert-how-to-achieve-bert-performance-using-logistic-regression-69a7fc14249d?source=collection_archive---------12-----------------------

伯特很棒,无处不在。看起来任何 NLP 任务都可以从使用 BERT 中受益。作者向展示了事实的确如此,从我的经验来看,它像魔法一样有效。它易于使用,处理少量数据,并支持许多不同的语言。似乎没有任何理由不在任何地方使用它。但实际上,是有的。可惜,在实际操作中,并不是那么微不足道。BERT 是一个庞大的模型,超过 1 亿个参数。不仅我们需要一个 GPU 来微调,而且在推理时间上,一个 CPU(甚至很多)是不够的。这意味着,如果我们真的想在任何地方使用 BERT,我们需要在任何地方安装一个 GPU。这在大多数情况下是不切实际的。2015 年,的这篇论文(由 Hinton 等人完成)介绍了一种将一个非常大的神经网络的知识提取到一个小得多的神经网络中的方法,比如教师和学生。方法很简单。我们使用大的神经网络预测来训练小的。主要思想是使用原始预测,即最终激活函数(通常是 softmax 或 sigmoid)之前的预测。假设通过使用原始值,模型能够比使用“硬”预测更好地学习内部表示。Sotmax 将这些值归一化为 1,同时保持最大值较高,并将其他值减小到非常接*零的值。零中的信息很少,所以通过使用原始预测,我们也可以从非预测类中学习。作者在包括 MNIST 和语音识别的几个任务中显示了良好的结果。

不久前,这篇论文的作者将同样的方法应用于...伯特。他们表明,通过将来自 BERT 的信息提取到一个更小的 BiLSTM 神经网络中,我们可以在特定任务中获得相同的性能(甚至更好)。您可以在下表中看到他们的结果。使用 BiLSTM-Soft 实现了最佳性能,这意味着“软预测”,即训练原始逻辑而不是“硬”预测。数据集有: SST-2 是斯坦福情感树库 2, QQP 是 Quora 问题对, MNLI 是多体裁自然语言推理。

在这篇文章中,我想将 BERT 提炼为一个更简单的逻辑回归模型。假设您有一个相对较小的标注数据集和一个大得多的未标注数据集,构建模型的一般框架是:

  1. 在带标签的数据集上创建一些基线
  2. 通过在标记集上微调 BERT 来构建一个大模型
  3. 如果你得到了好的结果(比你的基线更好),使用大模型计算你的未标记集合的原始对数
  4. 在现在伪标记的集合上训练小得多的模型(逻辑回归)
  5. 如果你得到了好的结果,可以在任何地方部署小型模型!

如果你对微调 BERT 的基础教程感兴趣,请查看我之前的帖子:

[## 伯特来救援了。

使用 BERT 进行简单文本分类的分步教程

towardsdatascience.com](/bert-to-the-rescue-17671379687f)

我想解决同样的任务(IMDB 审查情绪分类),但与逻辑回归。你可以在这本笔记本里找到所有的代码。

和以前一样,我将使用torchnlp来加载数据,使用优秀的 PyTorch-Pretrained-BERT 来构建模型。

训练集中有 25,000 条评论,我们将只使用 1000 条作为标记集,另外 5,000 条作为未标记集(为了加快速度,我也只从测试集中选择 1000 条评论):

train_data_full, test_data_full = imdb_dataset(train=True, test=True)
rn.shuffle(train_data_full)
rn.shuffle(test_data_full)
train_data = train_data_full[:1000]
test_data = test_data_full[:1000]

我们做的第一件事是使用逻辑回归创建基线:

我们得到的结果并不太好:

 precision    recall  f1-score   supportneg       0.80      0.80      0.80       522
pos       0.78      0.79      0.78       478accuracy                      0.79      1000

下一步,是微调 BERT,我将跳过这里的代码,你可以看到它的笔记本或更详细的教程在我以前的职位。结果是一个名为BertBinaryClassifier的训练模型,它使用 BERT 和一个线性层来提供正/负分类。这种模式的表现是:

 precision    recall  f1-score   supportneg       0.88      0.91      0.89       522
pos       0.89      0.86      0.88       478accuracy                      0.89      1000

好多好多!如我所说—神奇:)

现在到了有趣的部分,我们使用未标记的集合,并使用我们的微调 BERT 模型来“标记”它:

我们得到:

 precision    recall  f1-score   supportneg       0.87      0.89      0.88       522
pos       0.87      0.85      0.86       478accuracy                      0.87      1000

没有原来微调过的 BERT 好,但是比基线好多了!现在我们准备将这个小模型部署到生产环境中,享受良好的质量和推理速度。

这里有另外一个理由 5 个理由“逻辑回归”应该是你成为数据科学家的第一件事😃

用空间提取 BERT 模型

原文:https://towardsdatascience.com/distilling-bert-models-with-spacy-277c7edc426c?source=collection_archive---------6-----------------------

如何训练可与大型迁移学习模型相媲美的小型神经网络

迁移学习是*年来自然语言处理领域最具影响力的突破之一。发布不到一年,谷歌的 伯特 及其后代( 罗伯塔 XLNet等。)称霸大部分 NLP 排行榜。虽然将这些庞大的模型投入生产是一件令人头痛的事情,但有各种解决方案可以显著减小它们的尺寸。在NLP Town我们成功地应用了模型提取来训练 spaCy 的文本分类器,使其在产品评论的情感分析上表现得几乎和 BERT 一样好。

最*,自然语言处理的标准方法发生了巨大的变化。尽管直到一年前,几乎所有的 NLP 模型都是完全从零开始训练的(通常除了预训练的单词嵌入),但今天最安全的成功之路是下载一个预训练的模型,如 BERT,并针对特定的 NLP 任务进行微调。因为这些迁移学习模型已经看到了大量未标记文本的集合,他们已经获得了许多关于语言的知识:他们意识到单词和句子的意义,共指,句法等等。尽管这场革命可能令人兴奋,但像 BERT 这样的模型有太多的参数,它们相当慢而且资源密集。至少对于某些 NLP 任务来说,微调 BERT 就像用大锤砸坚果。

大锤模型

大多数迁移学习模型都很庞大。伯特的basemultilingual型号是变形金刚,12 层,隐藏尺寸 768,12 个自关注头——总共不少于 1.1 亿个参数。BERT-large体育参数高达 340 米。尽管如此,与更*的模型相比,BERT 仍然相形见绌,例如脸书的 XLM,参数为 665M】和 OpenAI 的 GPT-2,参数为 774M 。看起来这种向更大模型发展的趋势肯定会持续一段时间。

General models like BERT can be finetuned for particular NLP tasks (from: Devlin et al. 2018)

当然,语言是一种复杂的现象。很明显,参数相对较少的更传统、更小的模型将无法处理您扔给它们的所有 NLP 任务。然而,对于单个文本分类或序列标记任务,是否真的需要 BERT 及其同类产品的所有表达能力是值得怀疑的。这就是为什么研究人员已经开始研究如何缩小这些模型的尺寸。三种可能的方法已经出现:量化通过用更少的比特编码来降低模型中权重的精度,修剪完全移除模型的某些部分(连接权重、神经元甚至全权重矩阵),而在蒸馏中,目标是训练小模型来模仿大模型的行为。

用于情感分析的模型提取

在我们 NLP Town 的一个夏季项目中,我们和实习生 Simon Lepercq 一起着手调查模型提取对情感分析的有效性。就像的庞、李和韦思亚纳森在他们的开创性论文中所说的那样,我们的目标是建立一个能够区分正面和负面评论的自然语言处理模型。我们收集了六种语言的产品评论:英语、荷兰语、法语、德语、意大利语和西班牙语。我们给一两星的评论贴上标签negative,给四星或五星的评论贴上标签positive。我们用 1000 个例子进行训练,1000 个例子进行开发(早期停止),1000 个例子进行测试。

第一步是确定我们任务的基线。在我们的每个数据集中,有相同数量的正面和负面例子,随机基线将获得*均 50%的准确性。作为一个简单的机器学习基线,我们训练了一个空间文本分类模型:一个词汇袋模型的堆叠集成和一个相当简单的具有均值汇聚和注意力的卷积神经网络。为此,我们添加了一个节点的输出层,并让模型在输出得分高于 0.5 时预测positive,否则预测negative。这个基线在测试数据上达到了 79.5%(意大利语)和 83.4%(法语)之间的准确率——不算差,但也不是很好的结果。

BERT gives an average error reduction of 45% over our simpler spaCy models.

由于它的训练集很小,我们的挑战非常适合迁移学习。即使诸如巨著之类的测试短语没有出现在训练数据中,BERT 也已经知道它类似于优秀小说精彩阅读,或者在训练集中很可能出现的另一个类似短语。因此,它应该能够比从零开始训练的简单模型更可靠地预测一个看不见的评论的评级。

为了微调 BERT,我们改编了 PyTorch-Transformers 库中的BERTForSequenceClassification类用于二进制分类。对于所有六种语言,我们都进行了微调BERT-multilingual-cased,这是谷歌目前推荐的多语言模式。结果证实了我们的预期:BERT 的准确率在 87.2%(荷兰语)和 91.9%(西班牙语)之间,比我们最初的 spaCy 模型*均高出 8.4%。这意味着 BERT 几乎将测试集上的错误数量减半。

模型蒸馏

不幸的是,伯特也不是没有缺点。我们的六个微调模型中的每一个都占用了将* 700MB 的磁盘空间,它们的推理时间比 spaCy 的要长得多。这使得它们很难部署在资源有限的设备上,或者对许多用户并行使用。为了应对这些挑战,我们求助于模型提炼:我们让微调过的 BERT 模型充当老师,让 spaCy 更简单的卷积模型充当学习模仿老师行为的学生。我们遵循由唐等人(2019) 描述的模型提取方法,该方法表明可以将 BERT 提取为简单的 BiLSTM,并获得类似于具有 100 倍以上参数的 ELMo 模型的结果。

Distillation is a process that extracts the essential aspects from a mixture.

然而,在我们开始训练小模型之前,我们需要更多的数据。为了学习和模仿 BERT 的行为,我们的学生需要看到比原始训练集更多的例子。因此,Tang 等人应用三种方法进行数据扩充(在原始训练数据的基础上创建合成训练数据):

  • 屏蔽训练数据中的随机单词。比如我喜欢这本书现在变成了我【屏蔽】这本书。
  • 将训练数据中的其他随机词替换为另一个词性相同的词。比如我喜欢这本书变成了我喜欢这个画面
  • 从训练样本中随机抽取长度为 1 到 5 的 n-gram

由于我们数据集中的产品评论可能相当长,我们在上面三种方法的基础上增加了第四种方法:

  • 从训练示例中随机抽取一个句子

The process of model distillation.

这些增强方法不仅帮助我们创建了一个比原来大很多倍的训练集;通过采样和替换训练数据的各个部分,他们还通知学生模型什么单词或短语对其老师的输出有影响。此外,为了给它尽可能多的信息,我们没有给学生看老师预测的标签,而是显示它的精确输出值。通过这种方式,小模型可以了解最佳类的确切概率,以及它与其他类相比的情况。唐等(2019) 用老师的逻辑来训练小模型,但是我们的实验表明使用概率也能给出非常好的结果。

蒸馏结果

模型提取的一个很大的优点是它是模型不可知的:教师模型可以是一个黑盒,学生模型可以有任何我们喜欢的架构。为了使我们的实验简单,我们选择了与基线相同的 spaCy 文本分类器作为我们的学生。训练程序也保持不变:我们使用相同的批量大小、学习率、退出和损失函数,当开发数据的准确性停止上升时,停止训练。我们使用上面的增强方法为每种语言收集了大约 60,000 个例子的合成数据集。然后,我们收集了微调后的 BERT 模型对这些数据的预测。与原始训练数据一起,这成为我们较小空间模型的训练数据。

The distilled spaCy models perform almost as well as the original BERT models.

尽管设置很简单,但提取的空间模型明显优于我们的初始空间基线。*均而言,他们的准确度提高了 7.3%(仅比 BERT 模型低 1%),误差减少了 39%。他们的表现表明,对于情感分析这样的特定任务,我们不需要 BERT 提供的所有表达能力。训练一个性能几乎和 BERT 一样好的模型是完全可能的,但是参数要少得多。

结论

随着大型迁移学习模型的日益流行,将 NLP 解决方案投入生产变得越来越具有挑战性。然而,像模型提取这样的方法表明,对于许多任务,你不需要数以亿计的参数来实现高精度。我们在六种语言中进行的情感分析实验表明,训练 spaCy 的卷积神经网络与更复杂的模型架构(如 BERT 的模型架构)相匹敌是可能的。将来,我们希望在 NLP 镇更详细地研究模型提取。例如,我们旨在找出什么样的数据扩充方法最有效,或者我们需要多少合成数据来训练一个更小的模型。

使用 Gabor CNN 辨别名人的长相

原文:https://towardsdatascience.com/distinguishing-celebrity-look-alikes-using-gabor-cnn-ce848a4e3933?source=collection_archive---------26-----------------------

摘要:

在这篇论文中,我深入研究了两个名人长得很像的现象,在这种情况下,杰西卡·查斯坦和布莱丝·达拉斯·霍华德是一个用例,以开发一种足够复杂的算法来区分人的面部区域,甚至连人类都感到困惑。神经网络是目前可能的最复杂的鉴别器,考虑到同样的计算能力,更重要的是提供给 CNN 的数据质量。这里,女演员的每个图像被转换成它的 Gabor 滤波器表示,每个表示具有不同方向的 16 个 Gabor 滤波器。Gabor 滤波器似乎是生物图像的最复杂的特征提取方法,因为它们捕捉精细的纹理细节。训练有素的 CNN 能够在 80%的情况下预测名人的正确姓名。人们发现,CNN 更准确地报道了随着时间推移体重波动最小的女演员。可以得出结论,在人脸的 Gabor 表示上训练 CNN 是面部识别的有效混合技术,只要它被给予最新的面部表示。

简介:

面部识别是现代计算机视觉的一个有趣的领域,因为面部甚至不是一个人最显著的生物特征;最准确的鉴别器是虹膜图案或指纹。然而,这种精确的数据并不总是由感兴趣的对象自愿提供的,因此,重要的研究已经进入了从人脸提取足以区分个人的特征的方法。

从目前的参考文献来看,混合方法似乎能产生更好的结果。在[1]中,PCA +CNN 或 SOM+ CNN 方法都优于特征脸技术,即使给定较小的样本量。此外,小波分解方法,无论是哈尔变换还是双正交变换,似乎都是捕捉生物图像(如人脸)细微纹理的最佳特征提取方法2。在所有这些中,最健壮的似乎是 Gabor 滤波器。Gabor 滤波器组的组成[3]考虑了其他小波变换不能捕捉的生物纹理中的尺度和方向变化。

本文试图回答这个问题:如果我将最复杂的频率分解(Gabor 滤波器)与胜过任何其他方法的机器学习方法(卷积神经网络[6])相结合,我能否设计出一个足够好的系统来区分两张容易相互混淆的脸(参见图 1 中女演员的并排比较)?

Fig.1 Jessica Chastain and Bryce Howard bare close resemblance to each other

方法:

在谷歌图片上为每个女演员收集了大约 200 张图片,用 Chome 插件下载:Fatkun 批处理下载器下载。我之所以决定这个粗略的数字,是因为我的教授告诉我,每节课至少需要 80 张图片。我用 Python Jupyter notebook 编写了这个系统。这些图像使用 OpenCV 的内置人脸检测算法进行迭代,该算法利用 Haar 级联实现多尺度检测4。该函数显然使用皮肤的独特色度值进行检测,例如 YCbCr 5,因为有时手或胸部会被裁剪。然后手动迭代裁剪后的图像,以消除不需要的样本,从而获得高质量的训练集。

然后为每个裁剪的人脸生成 Gabor 滤波器组。该银行由 16 个不同方向的变化;其他参数的值保持不变,因为在裁剪的面部区域中缺少比例变化。标准偏差是通过计算训练集的*均标准偏差(3)得出的。核的大小被设置为标准差的 10 倍,即 30。16 个不同的方向是π内的 16 个分度。λ,正弦波长设置为 4,控制伽柏滤波器高度的γ,设置为 0.04;伽马值越小,伽柏值越高。ψ,相位偏移设置为π/4(参见图 2 中 Gabor 滤波器组的程序遍历和直观表示)。

Fig 2. Methodology work flow and description of Gabor filter bank parameters

一种热编码被用来标记图像,将[1,0]附加到属于 Bryce Dallas 的每个 Gabor 滤波器,将[0,1]附加到 Jessica 的滤波器。然后,每个 Gabor 表示被转换成它的灰色对应物,并被调整到 64x64。标记和调整大小后,图像被加在一起,然后混洗。在被输入 CNN 之前,这些图像被从标签中分离出来。在训练期间,CNN 被评估其将图像正确匹配到其正确标签的能力。

使用了相对经典的 CNN。它有 3 个卷积层,后面是 2 个密集层。Dropout 是随机断开多少节点以避免过拟合的概率,0.25 和 0.5 分别应用于最终的两个密集层。学习速率,即相对于损失梯度调整权重的速率,被设置为 0.001。Adam optimizer 用于其自适应优化功能(参见图 3)。

Fig. 3 Summary of the neural network

该模型被训练了 50 个时期。它相对较快地收敛到高精度(见图 4)。

Fig. 4 History of the training

结果:

我决定在训练集和测试集之间使用 80:20 的分割,所以我为每个女演员组成了一个包含 40 个图像的测试集。为了便于可视化表示,我没有打乱测试集。布莱斯达拉斯的模型预测是体面的(见图 5)。

Fig. 5 Prediction results for Bryce Dallas Howard

Jessica 的结果稍好一些(见图 6)。

Fig. 6 Prediction results for Jessica Chastain

总之,该模型大约 80%准确(参见图 7 的混淆矩阵)。

Fig. 7 Confusion matrix for the model prediction.

讨论:

Gabor 滤波器组和 CNN 的结合能否产生一个能够区分两个长相相似的人的系统?根据这个实验,这绝对是一个有效的方法。复杂的算法肯定可以根据特征提取来识别个人面部。这个实验的限制是数据量有限。一场普通的 Kaggle 图像比赛会有比这更多的数据集。来自互联网的图像质量也不理想。一个有趣的发现是,布莱丝·达拉斯·霍华德的结果不太准确;经过进一步的研究,我发现她的体重增加了很多,其中一些照片进入了训练集。在未来,我想添加形状作为一个特征来训练 CNN,以进一步微调其准确性。

结论:

如果有足够的计算能力,正确的算法和高质量的数据,计算机肯定可以区分个人。尽管指纹和虹膜模式仍然是识别个人的最佳特征,但从人脸中提取正确的特征,然后使用神经网络提供了识别个人的替代方法。考虑到有限的数据和计算能力,提取正确的特征仍然非常重要。这里表明,使用 Gabor 滤波器提取 16 个方向的面部纹理产生了体面的结果。这表明,教授神经网络最重要的特征,无论是纹理还是形状,都比拥有庞大的数据量重要。

参考文献:

[1] Sujata G. Bhele 和 V.H.Mankar .关于人脸识别技术的综述论文。《国际计算机工程高级研究杂志》2012 年 10 月第 1 卷第 8 期

2帕拉维·瓦德卡尔,梅加·万哈德。基于离散小波变换的人脸识别。国际先进工程技术杂志,Vol.III/第一期,2012 年 1 月-3 月

[3]尚振鸾,,张,周思岳,,,韩.Gabor 卷积网络。在arXiv:1705.01450 v32018 年 1 月 29 日。

4帕迪利亚、科斯塔·菲勒霍和科斯塔。用于人脸检测的 Haar 级联分类器的评估。世界科学、工程与技术学会,《国际计算机与信息工程杂志》,2012 年第 6 卷第 4 期

5 Shruti D Patravali,J . M Wayakule,Apurva D Katre。使用 YCBCR 和 RGB 颜色模型的皮肤分割。国际计算机科学与软件工程高级研究杂志,第 4 卷,第 7 期,2014 年 7 月。

[6] B .戈皮卡、K .斯里拉克斯米、D .阿列赫亚、B .巴斯卡尔·拉奥、B .拉马·莫汉。基于 Gabor 特征提取和神经网络的人脸识别。电子与通信工程杂志,第 10 卷,第 2 期,版本。第二卷(2015 年 3 月至 4 月),第 68–72 页。

使用深度学习的分心驾驶员检测

原文:https://towardsdatascience.com/distracted-driver-detection-using-deep-learning-e893715e02a4?source=collection_archive---------10-----------------------

这篇博客和这个项目是由叶达鑫·阿萨利、阿波奥尔瓦·贾斯蒂、萨德哈娜·科尼、萨提亚·那仁·帕奇戈拉、&贾扬特·瑞辛尼在乔迪普·高什、
教授的指导下共同完成的。请按照这个 GitHub 资源库获取我们的实现代码

简介

驾驶汽车是一项复杂的任务,需要全神贯注。分心驾驶是指任何分散驾驶员对道路注意力的活动。几项研究已经确定了三种主要的分心类型:视觉分心(司机的眼睛离开道路)、手动分心(司机的手离开方向盘)和认知分心(司机的思想离开驾驶任务)。

美国国家公路交通安全管理局(NHTSA)报告称,2018 年有 36750 人死于机动车撞车事故,其中 12%是由于分心驾驶。发短信是最令人担忧的干扰。发送或阅读短信会让你的视线离开路面 5 秒钟。以每小时 55 英里的速度行驶,这相当于闭着眼睛行驶了整个足球场的长度。

许多州现在都有法律禁止开车时发短信、打手机和其他分心的事情。我们相信,计算机视觉可以增强政府的努力,以防止分心驾驶造成的事故。我们的算法自动检测司机的分心活动,并向他们发出警报。我们设想将这种产品嵌入汽车,以防止因分心驾驶而发生事故。

数据

我们获取了 StateFarm 数据集,该数据集包含由安装在汽车上的摄像机捕获的视频快照。训练集有 ~22.4 K 个在类间*均分布的已标记样本和 79.7 K 个未标记测试样本。共有 10 类图像:

Fig: Sample images from the training data

评估指标

在继续构建模型之前,选择正确的指标来衡量其性能是很重要的。准确性是我们首先想到的指标。但是,精度并不是分类问题的最佳度量。准确度仅考虑预测的正确性,即预测的标签是否与真实标签相同。但是,在评估模型的性能时,我们将驾驶员的行为分类为注意力分散的置信度非常重要。幸运的是,我们有一个度量标准来捕捉这一点— 日志丢失

对数损失(与交叉熵相关)测量分类模型的性能,其中预测输入是 0 到 1 之间的概率值。我们的机器学习模型的目标是最小化这个值。完美的模型的对数损失为 0,并且随着预测概率偏离实际标签而增加。因此,当实际观察标记为 1 时,预测概率为 0.3 将导致高对数损失

Fig: Evaluation Metric

数据泄露

了解了需要实现的目标后,我们开始从头开始构建 CNN 模型。我们添加了常见的疑点——卷积批量标准化、最大池化和密集层。结果——在 3 个时期内,验证集的损失为 0.014,准确率为 99.6%。

Fig: Initial Model Results

嗯,我们考虑了一秒钟,意外地建造了世界上有史以来最好的 CNN 建筑。因此,我们使用这个模型预测了未标记测试集的类。

关键时刻

Fig: Class prediction by the model

哦,好吧。毕竟没有意外之喜。因此,我们更深入地研究了可能出现的问题,我们发现我们的训练数据中有同一个人在一个班级中的多幅图像,这些图像的角度和/或高度或宽度略有变化。这导致了数据泄漏问题,因为相似的图像也在验证中,即模型被训练了许多它试图预测的相同信息。

数据泄露解决方案

为了应对数据泄露的问题,我们根据个人 id 分割图像,而不是使用随机的 80-20 分割。

现在,当我们用修改后的训练集和验证集来拟合我们的模型时,我们看到了更真实的结果。我们实现了 1.76 的损耗和 38.5%的准确率。

Fig: Model fit after countering data leakage

为了进一步改善结果,我们探索使用经过试验和测试的深度神经网络架构。

迁移学习

迁移学习是一种方法,其中为相关任务开发的模型被重新用作第二个任务的模型的起点。我们可以重用为标准计算机视觉基准数据集(如 ImageNet 图像识别挑战)开发的预训练模型的模型权重。通常,激活 softmax 的最后一层会被替换,以适应数据集中的类数量。在大多数情况下,还会添加额外的层来针对特定任务定制解决方案。

考虑到开发用于图像分类的神经网络模型所需的大量计算和时间资源,这是深度学习中的一种流行方法。此外,这些模型通常在数百万张图像上进行训练,这在训练集很小的情况下尤其有用。这些模型架构中的大多数都是业经验证的赢家,我们利用的 VGG16、RESNET50、Xception 和 Mobilenet 模型在 ImageNet 挑战赛中取得了优异的成绩。

图像增强

Fig: Sample code for Image Augmentation

由于我们的训练图像集只有大约 22K 的图像,我们希望从训练集中综合获得更多的图像,以确保模型不会过度拟合,因为神经网络有数百万个参数。图像增强是一种通过执行诸如移动宽度和/或高度、旋转和缩放等动作来从原始图像创建更多图像的技术。参考这篇文章来了解更多关于图像增强的知识。

Fig: Types of image augmentation implemented in our dataset

对于我们的项目,图像增强有一些额外的优势。有时,来自两个不同类别的图像之间的差异可能非常微妙。在这种情况下,从不同的角度对同一幅图像进行多重观察会有所帮助。如果你看下面的图片,我们会发现它们几乎是相似的,但在第一张图片中,该课程是“讲电话——对”,第二张图片属于“发型和化妆”课程。

Fig: Sample of image class confusion (i) Taking on the phone (ii) Hair and Makeup

额外图层

为了最大化迁移学习的价值,我们添加了几个额外的层来帮助模型适应我们的用例。每层的目的:

  • 全局*均池层仅保留每个补丁中值的*均值
  • 下降层有助于控制过度拟合,因为它会降低一部分参数(额外提示:尝试不同的下降值是个好主意)
  • 批量标准化层将输入标准化到下一层,这允许更快和更有弹性的训练
  • 密集层是具有特定激活功能的规则全连通层

训练哪几层?

进行迁移学习时的第一个问题是,我们是应该只训练添加到现有架构中的额外层,还是应该训练所有层。自然地,我们从使用 ImageNet 权重开始,并且只训练新的层,因为要训练的参数数量会更少,并且模型会训练得更快。我们看到验证集的准确性在 25 个时期后稳定在 70% 。但是,通过训练所有层,我们能够获得 80%的准确率。因此,我们决定继续训练所有的层。

Fig: Comparison of model accuracy for final vs all trained layers

使用哪种优化器?

优化器通过在目标函数相对于参数的梯度的相反方向上更新参数来最小化由模型参数参数化的目标函数。想要了解更多关于不同优化器的工作原理,你可以参考这篇博客。

深度学习领域最流行的算法是 Adam,它结合了 SGD 和 RMS Prop。对于大多数问题,它一直比其他优化器表现得更好。然而,在我们的案例中,亚当表现出不稳定的下降模式,而 SGD 则在逐渐学习。通过做一些文献调查,我们发现在少数情况下 SGD 优于 Adam,因为 SGD 泛化得更好(链接)。由于 SGD 给出了稳定的结果,我们将其用于所有的模型。

Fig: Accuracy across epochs using: (i)Adam (ii)SGD

使用哪些架构?

我们尝试了多种迁移学习模型,其中权重来自 ImageNet 数据集上的训练,即预训练权重。

  • VGG16 VGG16 型号有 16 层。它主要使用卷积技术以及零填充、丢弃、最大池化和扁*化。

Fig: VGG-16 Architecture

  • RESNET50 RESNET50 是 VGG16 模型的扩展,有 50 层。为了解决训练更深的网络困难的问题,已经引入了具有参考层输入的“快捷连接”的前馈神经网络。

Fig: Residual learning: a building block

  • 例外创建 RESNET 的目的是为了得到更深的网络,而创建例外是为了通过引入 深度可分卷积 得到更宽的网络。通过将标准卷积层分解为深度方向和点方向卷积,计算量显著减少。由于有多个过滤器查看同一级别,因此模型的性能也得到提高。****

Fig: Modified Depthwise Separable Convolution used in Xception

  • MobileNet MobileNet是 Google 为 基于移动的视觉应用 开发的模型。事实证明,计算成本至少降低了 9 倍。MobileNet 使用深度方向可分离卷积来构建轻量级深度神经网络。它有两个简单的全局超参数,可以有效地在延迟和准确性之间进行权衡。

迁移学习模型的性能

Fig: Comparison of Transfer Learning Models. MobileNet has the minimum loss on the test set

比较最佳车型

虽然上面的每个体系结构都给了我们很好的结果,但是每个模型对于各个类的性能有很大的差异。从下表中,我们注意到不同的模型对每一类都有最好的精确度。因此,我们决定建立这些模型的集合。

Fig: Accuracy of different algorithms per class

图:特定类别的每个模型的准确性。“绿色”和“红色”表示精确度从高到低

集合模型

现在我们有了 7 个后验概率方差很大的最佳模型,我们尝试了多种集成技术来进一步改善对数损失。

  • ****均值集成:这是最简单也是最广泛使用的集成方法,后验概率计算为组件模型预测概率的均值。
  • ****修剪*均集合:这是通过从每个图像的组件模型中排除最大和最小概率的*均集合。这有助于进一步*滑我们的预测,从而降低测井损失值。
  • ****用于组合的 KNN:由于这些图像都是在司机进行分散注意力的活动或驾驶时从视频片段中截取的,因此有大量来自同一类别的相似图像。基于这一前提,找到相似的图像并对这些图像的概率进行*均有助于我们*滑每一类的预测概率。
    为了找到 10 个最*的邻居,我们使用来自 VGG16 迁移学习模型的倒数第二层的输出作为验证集的特征。

Fig: Output of KNN — 10 Nearest Neighbours

Fig: Comparison of ensemble models with MobileNet model as the benchmark

学习

我们相信,从我们的经验中获得的这些知识将有利于任何像我们一样第一次从事深度学习项目的人:

****1。使用 Pickle 文件:你可以为你的项目使用的一个免费资源是‘Google Colab’。由于并行计算,您可以访问 GPU,这有助于处理大量数据。使用 Colab 时,您可以通过一次性读取所有图像并将其保存在 pickle 文件中来执行必要的预处理步骤。这样,您可以通过直接加载 pickle 文件来继续您离开的地方。然后,您可以开始训练您的模型

**2。提前停止和回调:一般深度学习模型都是用大量的历元来训练的。在此过程中,模型可能会在几个时期内提高精度,然后开始发散。训练结束时存储的最终重量将不是最佳值,即它们可能不会给出最小的对数损失。我们可以使用 Keras 中的 回调 功能,该功能仅在一个时期后看到改进时才保存模型的权重。您可以通过使用提前停止来减少训练时间,您可以设置模型停止看到任何改进后运行的时期数的阈值。

3。均值或修整均值优于总体的 模型堆叠:堆叠模型的输入具有高相关性,这会导致输出具有高方差。因此,在这种情况下,更简单的方法是最好的方法。

****4。永远不要忽略最终应用:对 7 个模型进行集成,然后对输出进行 KNN,这给了我们一个很好的分数,但是如果我们必须选择一个模型,它可以用来以最少的资源获得良好但更快的预测,Mobilenet 将是显而易见的选择。Mobilenet 是根据计算限制专门开发的,最适合汽车中的应用,并且在 7 个独立模型中具有最低的对数损失

我们认为,在汽车上安装一个带有摄像头的设备,跟踪司机的动作并提醒他们,可以帮助防止事故发生。

为了说明这一点,我们制作了一个小视频,演示如何使用我们的模型:

Sample video depicting predictions

参考文献:

  1. 斯坦福 CS231N 系列讲座为 CNN:https://www.youtube.com/watch?v=vT1JzLTH4G4&list = plzutmxvwsnxod 6 wndg 57 YC 3 zfx _ f-RYsq&index = 1
  2. 如何用 Keras 实现 CNN,tensor flow:https://www . YouTube . com/watch?v = wq 8 bibbpya 2k&list = plqvvaa 0 qudfhtox 0 ajmq 6 tvtgmbzbexn
  3. CNN 架构:
    https://medium . com/analytics-vid hya/CNN-Architectures-lenet-Alex net-vgg-Google net-resnet-and-more-666091488 df5
  4. 转移学习文章:
  • https://medium.com/r/?URL = https % 3A % 2F % 2f towards data science . com % 2f transfer-learning-using-mobilenet-and-keras-c 75 daf 7 ff 299
  • https://github.com/bdutta19/kaggle_statefarm
  • http://cs 229 . Stanford . edu/proj 2016/report/SamCenLuo-classification of driver distraction-report . pdf
  • https://arxiv.org/abs/1704.04861

使用 PySpark 和 Keras 的分布式深度学习管道

原文:https://towardsdatascience.com/distributed-deep-learning-pipelines-with-pyspark-and-keras-a3a1c22b9239?source=collection_archive---------0-----------------------

Photo Credit: tian kuan

使用 PySpark 实现数据管道化和使用 Keras 进行分布式深度学习的简单方法

介绍

在这本笔记本中,我使用 PySpark、Keras 和 Elephas python 库来构建一个运行在 Spark 上的端到端深度学习管道。Spark 是一个开源的分布式分析引擎,可以以极快的速度处理大量数据。PySpark 只是 Spark 的 python API,它允许您使用一种简单的编程语言,比如 python,并利用 Apache Spark 的强大功能。

目标

我把这个例子放在一起的兴趣是学习和原型。更具体地说,了解更多关于 PySpark 管道的信息,以及我如何将深度学习集成到 PySpark 管道中。我在本地机器上使用 Jupyter 运行了整个项目,为即将到来的项目构建了一个原型,该项目中的数据将是海量的。因为我在 IBM 工作,所以我将把整个分析项目(Jupyter 笔记本)转移到 IBM。这使我能够在一个统一的*台和一个更大的 Spark 集群上进行数据接收、管道化、培训和部署。显然,如果您有一个真实的、相当大的项目或者使用图像数据,您不会在本地机器上这样做。

总的来说,我发现把这个原型或工作示例放在一起并不太难,所以我希望其他人会发现它很有用。我会把这个项目分成 9 个步骤。很多步骤都是不言自明的,但对于其他步骤,我会尽量让它变得不那么痛苦。如果你只想看有解释和代码的笔记本,你可以直接去 GitHub 。如果我能做到,你也能!

第一步

导入库

Figure 1 — 3 Libraries Here: PySpark (Install Spark), Keras, and Elephas

第二步

开始火花会话

您可以使用setAppName()为您的项目设置一个名称,也可以设置您想要多少工人。我只是在本地运行它,并将它设置为可能有 6 个工人。只是一个警告,如果你的数据不是很大,那么分配工作,特别是在进行机器学习时,实际上可能没什么帮助,并且提供更差的结果。当我做下面的训练时,我将它设置为 1 个工人,但是当我在以后的项目中使用这个原型时,我将更改这些设置。

Figure 2 — Spark Session

第三步

用 Pyspark 加载和预览数据

在这里,我们将加载数据。我们将使用的数据来自一场 Kaggle 竞赛。这是一个典型的银行数据集。我在这里使用了inferSchema参数,它有助于在加载数据时识别特征类型。根据 PySpark 文档,此需要额外传递一次数据。因为我正在加载的银行数据只有大约 11k 的观察值,所以根本不需要很长时间,但是如果您有一个非常大的数据集,这可能是值得注意的。

Figure 3 — Load Data

加载数据后,我们可以看到模式和各种功能类型。我们所有的功能不是string型就是integer。然后我们预览前 5 个观察结果。我非常熟悉 Pandas python 库,所以通过这个例子,你会看到我使用toPandas()将 spark 数据帧转换成 Pandas 数据帧,并进行一些操作。没有对错,只是对我来说更容易。

Figure 4 — View Schema and Preview Dataframe

最后,我们将删除 2 个日期列,因为我们不会在深度学习模型中使用它们。它们可能是重要的和有特色的,但是我决定把它们放在一起。

Figure 5 — Drop Columns

第四步

创建 Spark 数据管道

现在我们使用 PySpark 创建管道。这实际上是获取您的数据,并根据您传递的特性列表进行转换和矢量化,以便为建模做好准备。对于这个管道和项目,我参考了很多 Apache Spark 文档 “提取、转换和选择特性”

下面是一个辅助函数,用于根据数字特征的峰度或偏斜度来选择要标准化的数字特征。upper_skewlower_skew的当前默认值只是一般指导原则(取决于您的阅读位置),但是您可以根据需要修改上下偏斜。

Figure 6 — Select Features to Standardize Function

创建管道

现在我们将进入实际的数据管道。功能列表选择部分可以进一步增强,以更加动态地列出每个功能,但对于这个小数据集,我只保留了cat_featuresnum_featureslabel。通过类型选择特性可以类似于我在select_features_to_scale助手函数中所做的,使用类似这样的list(spark_df.toPandas().select_dtypes(include=['object']).columns),它将返回 spark 数据帧中所有对象或字符串类型的列的列表。

我们要做的第一件事是创建一个名为stages的空列表。这将包含数据管道完成管道内所有转换所需的每个步骤。我打印出管道后阶段的每一步,这样你可以看到从我的代码到列表的连续步骤。

第二部分将是一个基本循环,遍历列表cat_features中的每个分类特征,然后使用一键编码对这些特征进行索引和编码。StringIndexer将您的分类特征编码到一个特征索引中,将最高频率标签(计数)作为特征索引0,依此类推。我将在管道(步骤 5)后预览转换后的数据框,您可以看到根据分类要素创建的每个要素索引。有关更多信息和 StringIndexer 的基本示例,请查看此处的。

在循环中,我们还使用OneHotEncoderEstimator进行了一些一键编码(OHE)。这个函数只接受一个标签索引,所以如果你有分类数据(对象或字符串),你必须使用StringIndexer,这样你就可以传递一个标签索引给 OHE 估计器。通过查看几十个例子,我发现一件好事是,你可以使用string_indexer.getOutputCol()StringIndexer输出链接到 OHE 估计器中。如果你有很多要转换的特性,你需要考虑一下它们的名字,OutputCol,因为你不能仅仅重写特性的名字,所以要有创造性。我们将循环中的所有管道步骤添加到管道列表stages中。

接下来,我们在标签特征或因变量上再次使用StringIndexer。然后我们将继续使用上面的select_features_to_scale辅助函数缩放数值变量。一旦选择了列表,我们将使用VectorAssembler对这些特征进行矢量化,然后使用StandardScaler对该矢量中的特征进行标准化。然后我们将这些步骤添加到我们正在进行的管道列表stages

最后一步是将我们所有的特征组合成一个向量。我们将通过使用我们的unscaled_features(所选要缩放的数字特征的名称)列表和原始数字特征列表num_features之间的差异,从列表num_features中找到未缩放的数字特征。然后,我们集合或矢量化所有分类 OHE 特征和数字特征,并将该步骤添加到我们的管道stages。最后,我们将scaled_features添加到assembled_inputs中,为我们的建模获得最终的单一特征向量。

Figure 7 — Spark Data Pipeline

通过查看我们按顺序添加的stages列表,我们可以看到管道中的所有步骤。

Figure 8 — Data Pipeline list ‘stages’

第五步

通过 Spark 管道运行数据

既然“硬”部分已经结束,我们可以简单地流水线化阶段,并通过使用fit()使我们的数据适合流水线。然后我们实际上通过使用transform来转换数据。

Figure 9 — Pipeline, Fit, and Transform the Data

我们现在可以预览新转换的 PySpark 数据框架,其中包含所有原始和转换后的特征。这可以在 GitHub 的笔记本上更好地查看,但是图 10 显示了一些索引、集合向量和我们的标签索引。

Figure 10 — Preview of Newly Transformed Dataframe

第六步

深度学习模型前的最终数据准备

在建模之前,我们需要做几件最后的事情。首先是创建一个 PySpark 数据帧,该数据帧仅包含来自最*转换的数据帧的 2 个向量。我们建模只需要:features ( X )和label_index ( y )特征。用简单的select语句就可以很容易地处理 PySpark。然后,只是因为,我们预览数据帧。

Figure 11 — Select Final Features and Label

最后,我们希望重组数据帧,然后将数据分成训练集和测试集。您总是希望在建模之前打乱数据,以避免对数据排序或组织方式的任何偏见,特别是在拆分数据之前打乱数据。

Figure 12 — Order by Random (Shuffle) and Split Data

第七步

用 Keras 建立深度学习模型

我们现在将使用 Keras 建立一个基本的深度学习模型。Keras 被描述为:“一种高级神经网络 API,用 Python 编写,能够在 TensorFlow、CNTK 或 Theano 之上运行。” Keras 文档中的。我发现 Keras 是 python 最简单的深度学习 API 之一。此外,我发现了一个 Keras 的扩展,它允许我在 Spark 上进行简单的分布式深度学习,可以与我的 PySpark 管道集成,所以这似乎是一个很好的选择。

首先,我们需要从数据中确定类的数量以及输入的数量,以便我们可以将这些值插入到我们的 Keras 深度学习模型中。

Figure 13 — Number of Classes and Inputs for Model

接下来我们创建一个基本的深度学习模型。使用 Keras 的model = Sequential()功能,可以很容易地添加层,并使用所有所需的设置(单位数、辍学率%、正则化-L2、激活函数等)构建深度学习模型。)由于我们的结果标签是二进制的,所以我选择了普通的 Adam 优化器和具有二进制交叉熵的 sigmoid 激活来补偿我们的损失。

Figure 14 — Keras DL Model

一旦模型建立,我们可以查看架构。请注意,我们从 30 个输入/参数增加到 74,242 个。深度学习的妙处,有时也是懒惰:),是自动特征工程。

Figure 15 — Model Summary / Architecture

第八步

用 Elephas 进行分布式深度学习

现在我们已经建立了一个模型,使用 Keras 作为我们的深度学习框架,我们希望在 Spark 上运行该模型,以利用其分布式分析引擎。我们通过使用一个 python 库和一个名为 Elephas 的 Keras 扩展来做到这一点。Elephas 使得在 Apache spark 上运行 Keras 模型变得非常容易,只需几行配置。我发现 Elephas 比我阅读和尝试的其他几个库更容易使用,也更稳定。

我们对 Elephas 做的第一件事是创建一个类似于上面 PySpark 管道项目的估计器。我们可以从 Keras optimizer 函数中设置优化器设置,然后将其传递给我们的 Elephas 估计器。我只显式地使用具有设定学习率的 Adam optimizer,但是您可以使用任何具有各自参数的Keras optimizer(clip norm,beta_1,beta_2 等。).

然后,在 Elephas estimator 中,您可以指定各种项目:特征列、标签列、时期数、训练的批量大小、训练数据的验证分割、损失函数、度量等。我只是使用了来自 Elephas 示例的设置,并稍微修改了代码。因为我的数据很少,所以我只用了一个工人。此外,当我尝试运行 6 个工人(步骤 2)的结果很差。教训是:你可以分发并不意味着你应该:)

Figure 16 — Elephas Estimator for Distributed Deep Learning

注意,在我们运行估计器之后,输出ElephasEstimator_31afcd77fffd,看起来类似于我们的一个管道stages列表项。这可以直接传递到我们的 PySpark 管道中,以适应和转换我们的数据,这将在下一步中完成!

第九步

分布式深度学习管道和结果

既然深度学习模型将在 Spark 上运行,使用 Elephas,我们可以完全按照上面使用Pipeline()的方式来流水线化它。您可以将它添加到我们的stages列表中,并使用一个新数据集一次性完成所有这些工作,因为它已经全部构建完成,这将非常酷!

Figure 17 — Easy DL Pipeline with PySpark

我在下面创建了另一个名为dl_pipeline_fit_score_results的帮助函数,它采用深度学习管道dl_pipeline,然后对训练和测试数据集进行所有的拟合、转换和预测。它还输出数据集及其混淆矩阵的准确性。

Figure 18 — Deep Learning Pipeline Helper Function

让我们在两个数据集上使用我们新的深度学习管道和助手函数,并测试我们的结果!从下面你可以看到,我们可以在训练和测试数据上有大约 80%的准确性,所以这个模型似乎是足够概括的。我承认我正在使用一个大锤模型,一个小得多的“工具”比如一个基本的决策树可能会做得更好。然而,我们现在有一个工作流和原型来引入表格数据,通过转换管道传递数据,并应用深度学习。

Figure 19 — Run DL Pipeline Helper Function, View Results

结论

我希望这个例子有所帮助。我知道这是为了让我了解更多关于 PySpark 管道的知识,并使用 Keras 等简单的深度学习框架在 Spark 上进行深度学习。正如我提到的,我在本地运行所有这些,几乎没有问题,但我的主要目标是为一个即将到来的项目构建原型,该项目将包含一个大规模的数据集。我希望你(和我自己)可以把它作为一个模板,同时对 spark 会话、数据、特性选择以及添加或删除一些管道阶段做一些修改。一如既往,感谢您的阅读,祝您的下一个项目好运!

分布式 SQL 系统综述:雪花 vs 拼接机

原文:https://towardsdatascience.com/distributed-sql-system-review-snowflake-vs-splice-machine-1ac995730b9?source=collection_archive---------14-----------------------

SQL 回来了

在经历了多年的大数据、NoSQL 和基于读取的模式的弯路之后,SQL 作为数据操作的通用语言已经有了明显的回归。开发人员需要 SQL 提供的全面表达能力。一个没有 SQL 的世界忽略了 40 多年的数据库研究,并导致应用程序中硬编码的意大利面条式代码来处理 SQL 极其高效地处理的功能,如连接、分组、聚合和(最重要的)更新出错时的回滚。

SQL is a powerful language enabling developers to state what they need without coding how to compute it

幸运的是,现在有了一种称为分布式 SQL 的现代 SQL 体系结构,它不再受到传统 SQL 系统的挑战(成本、可伸缩性、性能、弹性和模式灵活性)。分布式 SQL 的关键属性是数据存储在许多分布式存储位置上,计算在一个网络服务器集群上进行。这带来了前所未有的性能和可伸缩性,因为它在集群中的每个工作节点上并行分配工作。

虽然分布式 SQL 系统有许多共同的特征,但它们也有很大的不同,有些更适合某些工作负载。在这里,我们尝试将 Snowflake 和 Splice Machine 作为分布式 SQL 系统的两个例子进行比较,这两个例子在很多方面都有所不同。

不幸的是,数据系统之间的比较界限已经模糊。例如,一个系统声称拥有数据库的 ACID 属性(即原子性、一致性、隔离性和持久性)这一事实,并不一定意味着它是一个真正能够支持应用程序的事务性 OLTP 系统(关于这个主题的更多细节,请参见 Medium 文章)。另一个例子是灵活性—随着工作负载的扩展,您可以添加更多的工作人员来获得更多的并行性,或者随着工作负载的缩减而减少工作人员并降低成本。许多系统是灵活的,但是只有一些能够自动扩展集群以获得更多(或更少)的并发性或吞吐量。这是拼接机和雪花互不相同的两个示例特征。

在这里,我们将试图提供这些系统的一个*衡的观点,即使我们代表其中的一个。我们将从用例的角度来展示这些系统的不同之处,而不是逐个特性地展示。

下面我们将展示两个完全不同的用例。一个将完全适合拼接机,一个将完全适合雪花。

用例

Application versus Analytics

让我们考虑两个用例,都是在保险行业。用例一是管理客户、政策、索赔和支付的可操作的遗留应用程序。它是一个用 Java 编写的 SQL 应用程序,具有用 React/Node.js 开发的 Javascript 前端,具有以下特征:

  • 保险公司的每个实体都有自己的本地化的应用程序实例,运行特定的区域内法规、费率和政策
  • 应用程序必须 24/7 可用,并且在工作时间有峰值并发负载
  • 该应用程序还运行一组运营报告,管理人员使用这些报告来获得关于业务的日常见解
  • 经理们还把它作为一个专门的商业智能查询工具,询问企业“一次性”的问题
  • 该系统的用户包括许多支持者,包括代理、经理和通过自助服务门户的消费者

用例二是一个对账过程,它将来自数百万单个交易(在几个业务系统中)的财务业务信息转换为 SAP 等财务系统的分类帐更新。该应用程序具有以下属性:

  • ETL 工具(如 Informatica 或 Talend)中设计的一组复杂的批量转换会产生聚合数据
  • 每天运行以创建运行汇总,每月运行以关闭帐簿。
  • 汇总的数据作为文件输出,由财务对账系统接收
  • 财务分析师审查由报告工具(如 Tableau 或 MicroStrategy)构建的批处理报告和仪表板
  • 分析师执行临时查询来验证结果

选择解决方案

Use Snowflake or Splice Machine?

对于任何熟悉 Splice Machine 和 Snowflake 的人来说,您可以看到这些用例是为了指出每个引擎的优势而选择的。Splice Machine 的最佳点倾向于运营工作负载,而 Snowflake 的最佳点是大批量数据仓库工作负载。如果你的问题是用例 1,拼接机是最好的选择,原因如下。如果你的问题类似于用例 2,那么雪花是一个更好的选择。下面是每个用例的细分:

传统应用程序工作负载

遗留应用程序有以下要求,这些要求需要相关的系统功能。

Legacy Application Requirements

那么这些系统是如何堆叠起来的呢?

Feature Comparison

Net-Net:要运行一个有并发用户且始终在线的遗留应用程序,一个倾向于操作性工作负载但也有分析能力的系统将会表现得更好。

现在我们来看看雪花闪耀在哪里。

财务对账工作量

这个用例有着完全不同的需求,因此需要不同的特性。

Financial Reconciliation Workload Requirements

那么这些系统是如何堆叠起来的呢?

Feature Comparison

在这个用例中,雪花被设计用来优化大批量分析查询。存储针对这一点以及计算进行了优化。通过将计算与存储分离,雪花系统可以在不使用时完全关闭所有计算节点,从而创建一个经济高效的数据仓库。[更新 2/27/20:拼接机现在可以暂停和重启]。它还支持利用元数据统计数据进行优化,以最大限度地发挥每个员工的潜能。

摘要

Hybrid Transactional and Analytical versus Data Warehouse

Snowflake 和 Splice Machine 分布式 SQL 引擎都很强大,它们在服务工作负载的能力上肯定是重叠的。因此,您的选择标准将取决于您的特定用例。如果您的用例要求决策支持系统支持预先计算的值,可以关闭,并且可以弹性伸缩,那么雪花就是您的选择。另一方面,大多数分布式 SQL 系统无法支持应用程序。如果您希望为具有大量并发用户的任务关键型应用提供支持,并且该应用必须全天候运行,那么 Splice Machine 无疑是您的最佳选择。

实际上,这些系统部署在各种不同的工作负载上。例如,除了运营应用之外,Splice 还通过其基于 Apache Spark 的基础架构处理许多数据仓库、分析和机器学习工作负载。除了数据仓库之外,雪花有时还能驱动应用程序。但是我们在这里所做的是尝试描述用例连续体上的几个极端例子,以帮助您为您的工作负载选择最佳的分布式 SQL 引擎。

有关如何使用拼接机实现应用现代化的更多信息,请参见本白皮书。

分布式矢量表示:简化

原文:https://towardsdatascience.com/distributed-vector-representation-simplified-55bd2965333e?source=collection_archive---------15-----------------------

可以说是机器学习中最基本的特征表示方法

让我们来玩一个简单的游戏。我们有三个“人”——迈克尔、露西和加布。我们想知道哪个人的播放列表与露西最匹配,是迈克尔还是加布??让我给你一些提示。露西喜欢古典摇滚,加布也是,但迈克尔不喜欢。露西更喜欢器乐版本,迈克尔也是一样,但加布不喜欢他们。露西不喜欢流行音乐,迈克尔彻底讨厌它,但加布绝对是一个流行音乐迷!!

这种信息的表达有帮助吗?你能确定谁的播放列表更符合露西吗?Lucy 和 Micheal 对两种不同的歌曲类型有共同的兴趣,而 Lucy 和 Gab 只有一种共同的歌曲类型。但是你能确定露西和加布分享的一种类型不会超过其他两种吗?(我是说 comeon..是经典摇滚!!!)

如果我告诉你,我有一个神奇的公式,可以把他们的音乐兴趣作为一个单一的值来表达,你会怎么想?Lucy 可以表示为-0.1,Gab 可以表示为-0.3,Micheal 可以表示为 0.7。这当然使工作更容易,因为如果你相信这个公式,我认为很明显露西的播放列表将与 Gab 最匹配。但是我是怎么想出这个公式的呢?让我们从头开始…

什么是分布式表示?

分布式表示指的是特征创建,其中特征可能与原始输入有任何明显的关系,也可能没有,但它们具有比较价值,即类似的输入具有类似的特征。将输入转换为数字表示(或特征)是每个领域中任何机器学习算法的第一步。

为什么非分布式表示还不够?

非分布式表示(也称为单热点向量表示)为每个新的输入可能性添加一个新的向量维度。显然,唯一可能输入的数量越多,特征向量就越长。这种表示有两个主要缺陷,

  1. 任何两个特征向量之间的距离或“相似性”是相同的。换句话说,这种表示没有关于输入如何相互关联的信息,即没有比较值。
  2. 由于向量的每个维度代表一个唯一的输入,这种表示不能处理看不见的或未知的输入。

One-hot representation (left) vs distributed representation (right)

例如,如果我们在上面的表示中遇到一个新的输入,circle,会怎么样呢?如果我们使用非分布表示法(左),我们没有表示圆的方法,但如果我们使用分布表示法(右),我们可以将圆表示为垂直、水*和椭圆。这种表示也有助于我们的模型理解圆形更像椭圆而不是矩形。

我如何创建分布式矢量表示?

没有一种创建分布式矢量表示的方法。您可以创建与属性域有逻辑关系的要素,并相应地表示您的输入,就像上面的矩形/椭圆示例中所做的那样(尽管此过程需要专业领域知识)。或者你可以使用更成功的方法,即使用深度学习来创建无法直接解释的特征表示,但保留所需的比较值(就像我在帖子开头的播放列表示例中所做的那样)。

为了创建基于深度学习的分布式向量表示,需要首先创建逻辑特征表示(在大多数情况下实际上是非分布式表示),然后将其传递通过“转换矩阵”(有时也称为嵌入矩阵),以获得分布式向量表示。模型的这一部分通常附加在完整管道的开始,以学习表示。

Converting V unique inputs into an N-dimension vector representation

有许多帮助 ML 管道的向量表示的例子,如 Word2Vec、Gene2Vec、Prot2Vec、Node2Vec、Doc2Vec、Tweet2Vec、Emoji2Vec 等。这个清单非常庞大,尽管其中很大一部分出现在本次回购中。

为什么向量长度很重要?

现在一切似乎都很容易。为什么要浪费这么多空间,让我们学着用一个数值来表示所有的东西,对吗?不!!让我来给你讲解一下。

如果我们需要表示 3 个同样相似的输入(像三角形)会怎样?我们能用一维向量来表示它们吗?不!!为什么?因为三角形是二维的,咄!!现在,如果我需要表示 4 个同样相似的输入(像一个金字塔)该怎么办?你知道规矩..

每当我们增加特征维数时,我们的特征表示的稀疏性以指数方式增加。使用深度学习的分布式向量表示植根于这样一个事实,即我们提供具有比较值的*似(不一定精确)分布式表示。因此,需要明智地选择特征维度的大小,以便它可以提供足够准确的输入表示,而不会导致特征空间的极度稀疏。

下一步是什么?

分布式矢量表示作为一种核心思想非常流行,并广泛应用于各个领域。在各种各样的问题陈述中,已经提出了多种数字特征表示方法。我相信这种表示的核心思想对于任何机器学习问题都是必不可少的(即使确切的方法发生了显著的变化)。

这个博客是努力创建机器学习领域简化介绍的一部分。点击此处的完整系列

[## 机器学习:简化

在你一头扎进去之前就知道了

towardsdatascience.com](/machine-learning-simplified-1fe22fec0fac)

或者只是阅读系列的下一篇博客

[## 深度学习时间序列分析:简化

参加在时间序列分析中使用深度学习的“为什么”和“什么时候”的速成班。

towardsdatascience.com](/time-series-analysis-with-deep-learning-simplified-5c444315d773)

参考

[1] Knapp,Steven K .“用一键法加速 FPGA 宏”电子设计 38.17(1990):71–78。
2 Mikolov,Tomas 等,“单词和短语的分布式表示及其组合性”神经信息处理系统进展。2013.
[3]勒、阔克和托马斯·米科洛夫。"句子和文档的分布式表示."机器学习国际会议。2014.
4 Dhingra,Bhuwan 等,“Tweet2vec:基于角色的社交媒体分布式表示”arXiv 预印本 arXiv:1605.03481 (2016)。

介绍 Distython。新的 Python 包实现了新的距离度量

原文:https://towardsdatascience.com/distython-5de10f342c93?source=collection_archive---------13-----------------------

您在为混合型数据集选择正确的距离度量时遇到过问题吗?在大多数情况下,您可以尝试执行要素预处理,然后使用一些流行的距离度量,如欧几里德距离或曼哈顿距离。事实上,这种方法可能是不准确的,并导致 ML 模型的性能下降。看看 Distython — Python 包,它实现了研究论文中新颖的混合型距离度量!

Photo by Charles 🇵🇭 on Unsplash

最*实习的时候遇到过这个问题。我不得不在混合类型的数据集中使用 K-NN 来度量实例之间的相似性,该数据集中也有缺失值!虽然我可能会尝试做一些“花哨”的特征预处理,使其与流行的距离度量一起工作,但我不认为这是获得可靠结果的好方法。这让我开始寻找既能处理混合型数据又能处理缺失值的距离度量。读了几篇论文后,我发现了几个有趣的指标,这促使我在这里发表了另一篇关于它们的文章。与此同时,我也开始研究它们的实现,这让我创建了一个名为 Distython 的小型实用 Python 包!在接下来的文章中,我将解释它如何对您的 ML 模型有用,如何与 Scikit-Learn 集成,并简要解释代码的设计。

我喜欢数据科学的原因是,它吸引了许多对人工智能和数据科学充满热情的志同道合的人。这就是为什么我想在 Linkedin 上与你联系!您也可以通过我的个人网站留下任何反馈和问题😎

Distython 概述

(链接到 GitHub repo 这里)

Distython 是一个小型的、高效的实用程序包,它实现了混合型距离度量。最初,我把它作为个人使用,但是我想如果我把它公开的话可能会更有用。它实现了 3 种算法:异质欧几里德重叠度量(HEOM),价值差异度量(VDM)和异质价值差异度量(HVDM)。所有这些都在我之前的文章中解释过,也可以在这篇研究论文中找到。它们可以直接与一些 Scikit-Learn 算法一起使用(那些允许指定用户定义的度量的算法,例如最*邻或 Dbscan)。你也可以将它们与特定的插补算法一起使用,比如 MICE、K-NN 或 MissForest(我也写了一篇关于它们的文章

Distython 完全基于 Numpy。这使得它更快,并减少了所需的包依赖的数量。这里唯一的缺点是它降低了代码的可读性,但是当你试图创建高效的代码时,这通常是一个问题😀

为什么它有用

它解决了一个以前没有解决的问题,即创建一个公开可用的异构距离度量集合。老实说,当我发现 Scikit-Learn 没有任何异构度量时,我感到非常惊讶。假设数据集要么是连续的,要么是分类的,这似乎是非常错误的,是吧?

非异构方法与分布式

让我们来看一个非常简单的数据集,它包含分类和连续的特征以及一些缺失值。我们需要测量两个实例 AB 之间的距离。

Simple dataset for the purpose of the example

非异构方法:例如,如果您要使用 Scikit-Learn,则没有异构度量可供选择。克服这个问题的一个方法是一个变通的解决方案,它可能会给你不正确的结果:

为了计算 AB之间的距离,你需要对数字数据进行分类,这会导致信息的丢失。这里的另一个大问题是,在对特性进行编码之后,你将会得到很多列(维数灾难在这里适用)!

你准备好了吗?这里只有一件事要做…将您选择的距离度量应用于这些实例。很简单,是吧?要将度量附加到 Sklearn 的 K-NN 实现中,您只需要一行代码!

Distython with Scikit-Learn

这些指标被设计为可以直接应用于 Scikit-Learn 中的最*邻或 Dbscan 类。您可以将它与 Scikit-Learn 类一起用于您的个人项目,只要它们提供一个调用定制度量函数的接口。请注意,如果我们将指标附加到 Scikit-Learn 类,它会生成函数的开销调用,算法会变慢。

Importing necessary libraries

在上面的代码中,我们导入了必要的库和 HEOM 度量。我们还将使用波士顿房价数据集,因为它同时具有分类和数字特征。

Define the indices for categorical variables and NaN equivalent

这里,我们导入数据并将其定义为 boston_data。这里重要的部分是我们必须告诉 HEOM 度量什么列是分类的。 nan_eqv 在这里用来告诉 HEOMNaN是怎么表示的。需要注意的重要一点是:最*的邻居不能直接处理 np.nan ,所以我们需要来声明某些 nan 等价。

Introducing missingness to the dataset

在上面的代码部分中,我们将缺失引入数据(出于示例的目的)并将其指定为 nan_eqv。

Defining heom_metric and neighbor

然后,我们定义我们的 heom_metric 并提供必要的参数。它必须在 NearestNeighbors 之前定义,因为我们必须提供一个从 heom_metricneighbor 实例的可调用度量函数。这就是将 HEOM 与 Scikit-Learn 一起使用的全部内容。这很简单,不是吗?有关使用 Scikit-Learn 的自定义距离度量的更多信息,请点击此处。

Fitting the data and printing the results

在最后一步中,我们拟合模型,并使用 HEOM 作为距离度量函数返回 5 个最*邻。

最后几句话要说

该软件包仍处于早期阶段,所以它可能包含一些错误。请看看 Github 库,并建议一些代码的改进或扩展。我将很高兴地欢迎任何建设性的反馈,并随时为 Distython 做贡献!😉

参考

来自Distython with Scikit-Learn段落的大部分材料摘自我之前的文章这里的。

深入弹性搜索

原文:https://towardsdatascience.com/dive-into-elasticsearch-fbf848e8cf08?source=collection_archive---------9-----------------------

这篇文章将帮助你对 ElasticSearch 有一个高层次的了解。我们将回顾能够覆盖一个典型项目至少 95%需求的主要功能。如果你是 ElasticSearch 的新手,在这篇文章中你会找到几乎所有问题的答案,这些问题是你在使用新数据库之前应该问的。

什么是 ElasticSearch?

Elasticsearch 是一个全文搜索引擎,存储无模式的 JSON 文档。Elasticsearch 是基于 Apache Lucene 的开源软件,在 Apache 2.0 许可下发布。ElasticSearch 可以处理任何类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。

如何部署

你可以通过 Elasticsearch 服务(可在亚马逊网络服务(AWS)、谷歌云*台(GCP)和阿里云上使用)部署 Elasticsearch,也可以下载并安装在你的硬件上或云中。

文档有关于如何手动下载和安装数据库的说明。

此外,您可以使用 Docker 轻松安装 Elasticsearch:

1.提取图像:

docker pull docker.elastic.co/elasticsearch/elasticsearch:7.4.0

在编写本示例时,版本 7.4.0 是最新的。在官方网站上查看当前版本。

2.在开发模式下运行映像:

docker run -p 9200:9200 -p 9300:9300 -e “discovery.type=single-node” docker.elastic.co/elasticsearch/elasticsearch:7.4.0

看看官方文档中的更多选项。

弹性搜索是如何工作的

Elasticsearch 将文档存储在索引中。就关系数据库而言:索引是一个表,文档是表中的一行。索引是无模式的,所以您可以放置具有不同结构的文档,但是对于键有映射和限制,我们稍后将概述这些限制。

关于 ElasticSearch 的工作原理:

  1. 当您插入某个文档时,ElasticSearch 将文档字段的值拆分为记号(例如,句子中的每个单词可以是不同的记号),并将这些记号添加到倒排索引中。
  2. 当用户搜索某个短语时,ElasticSearch 会将该短语拆分成标记,并将这些标记与倒排索引进行匹配。

如果你不知道什么是倒排索引,它是如何工作的,你可以在这里阅读倒排索引的简要说明或者查阅官方文档。

缩放比例

Elasticsearch 是分布式软件,这意味着您可以以集群模式运行 Elasticsearch,其中每个计算节点将托管一个或多个碎片,并作为协调者将操作委托给正确的碎片。Elasticsearch 支持两种最流行的扩展方法,比如分区和复制。

分割

ElasticSearch 索引将被存储到两个或多个分片上。您索引的数据将存储在集群中的一个碎片上。

分身术

ElasticSearch 有一个主碎片和至少一个副本碎片。您索引的数据被写入主碎片和副本碎片。复制副本是主副本的精确拷贝。如果包含主碎片的节点出现故障,副本将接管。

索引

索引是无模式存储,但是您也可以为索引建立严格的文档模式。

创建新索引

curl -X PUT [http://localhost:9200/person](http://localhost:9200/person)

该命令将创建一个名为“ person ”的新的无模式索引,或者如果该索引已经存在,将返回一个错误。

查看索引信息

curl -X GET [http://localhost:9200/person](http://localhost:9200/person)

作为响应,您将看到索引的设置、映射和别名。如果索引不存在,则显示错误消息。

模式或映射

映射是对文档及其包含的字段如何在索引中存储和索引的描述。例如,在映射中,您可以定义以下内容:

  • 文档的结构(字段和这些字段的数据类型)
  • 如何在索引前转换值
  • 哪些字段用于全文搜索

使用自定义映射创建索引

curl -X PUT [http://localhost:9200/person](http://localhost:9200/person) \
-H ‘Content-Type: application/json’ \
-d ‘{
      **“mappings”: {
        “dynamic”: “strict”,
        “properties”: {
          “name”: {“type”: “text”},
          “email”: {“type”: “text”},
          “location”: {“type”: “geo_shape”},
          “extra_data”: {“type”: “object”, “dynamic”: true}
        }
      }**
}’

在这个例子中,您将为具有静态根结构的文档创建映射。一个字段将是一个动态对象,它可以包含任意数量的任意字段(键的数量受索引设置的限制)。

查看现有索引的映射

curl -X GET [http://localhost:9200/person](http://localhost:9200/person)

API 将返回上一个示例中的现有映射。

数据类型

ElasticSearch 支持许多不同的数据类型,以便对这些类型执行特定的搜索。让我们列出最常用的类型:

  • 核心数据类型:字符串(文本和关键字)、数字(整数、浮点等)、日期、布尔、二进制等
  • 复杂,像对象(hashmap(dictionary))和嵌套(链表(array))
  • 特定数据类型,例如,地理形状、IP 等。

每种数据类型都有自己的目标和设置。因此,请查看文档,了解每种类型的更多信息。

注意了。字符串数据类型有两种:文本和关键词。“文本”用于全文搜索(通常在文本中搜索,具有模糊性和其他特征),“关键字”用于聚合、排序和直接匹配(类似于编程语言中的运算符“==”)。

将数据插入索引

插入单个文档

curl -X POST [http://localhost:9200/person/_doc](http://localhost:9200/person/_doc) \
-H ‘Content-Type: application/json’ \
-d ‘{**“name”: “John”, “age”: 30}**’

如果成功,该请求将返回生成的 id 和其他信息。但是您总是可以自己指定 id:

curl -X POST [http://localhost:9200/person/_doc/id-1](http://localhost:9200/person/_doc/id-1) \
-H ‘Content-Type: application/json’ \
-d ‘**{“name”: “Katrin”, “age”: 25}**’

批量插入到一个索引中

curl -X POST [http://localhost:9200/person/_doc/_bulk](http://localhost:9200/person/_doc/_bulk) \
-H ‘Content-Type: application/json’ \
-d ‘**{ “index”:{} }
 { “name”:”Alex”,”age”:25 } 
 { “index”:{} }
 { “key1”:”Amely”,”age”:27 }**
 ‘

注意:批量添加应该以换行符结束。

批量插入到不同的索引中

curl -X POST [http://localhost:9200/_bulk](http://localhost:9200/_bulk) \
-H ‘Content-Type: application/json’ \
-d ‘**{ “index”:{“_index”: “person”} }
{ “name”:”Jack”,”age”: 34 }
{ “index”:{“_index”: “person”} }
{ “name”:”Oscar”,”age”:22 }
{ “index”:{“_index”: “person”} }
{ “name”:”John”,”age”:27 }**
‘

文档的类型

在插入的 URI 中,可以看到“ /_doc/ ”部分。这是文档的类型,但这是从 ElasticSearch 第 6 版开始弃用的东西。

更新文档

curl -X POST [http://localhost:9200/person/_update/id-1](http://localhost:9200/person/_update/id-1) \
-H ‘Content-Type: application/json’ \
-d ‘**{“age”: 24}**’

这是更新一个文档中一个字段的简单例子。Elasticsearch 支持针对复杂案例的更复杂的查询,因此查看文档以了解更多信息。

搜索查询

你知道,为了搜索。您可以在那里找出所有支持查询的列表和这些查询的描述。在本文中,我们将回顾最流行的查询,它可以覆盖一个典型项目中 95%的用例。

将所有字段与文本匹配

curl -X GET [http://localhost:9200/person/**_search?q=john**](http://localhost:9200/person/_search?q=john)

该查询将在任何字段中查找令牌。

全部匹配

curl -X GET [http://localhost:9200/person/_search](http://localhost:9200/person/_search) \
-H ‘Content-Type: application/json’ \
-d ‘{
    **“query”: {“match_all”: {}}** }’

只返回所有按 id 排序的文档。

匹配一个

curl -X GET [http://localhost:9200/person/_search](http://localhost:9200/person/_search) \
-H ‘Content-Type: application/json’ \
-d ‘{
  **“query”: {
    “match”: {
      “name”: “John Snow”
    }
   }** }’

“匹配”是在特定的字段中寻找特定的令牌。在这个例子中,我写了两个标记,这意味着我们要查找在字段“name”中包含标记“John”和/或标记“Snow”的文档。
本例仅适用于一个字段,要通过多个字段进行搜索,您需要另一个查询。

匹配短语

curl -X GET [http://localhost:9200/person/_search](http://localhost:9200/person/_search) \
-H ‘Content-Type: application/json’ \
-d ‘{
  **“query”: {
    “match_phrase”: {
       “name”: “John Snow”
    }
  }** }’

本示例与上一个示例的不同之处在于,本示例将在字段中查找完整的短语(在本示例中,将是两个标记" john "和" snow ",它们是一个接一个的),并且仅当找到该短语时才返回结果。

如果您向简单的“匹配”发送两个或更多令牌,即使只找到一个令牌,您也会收到结果,但在“匹配 _ 短语”的情况下,您将不会收到结果。

多重匹配

curl -X GET [http://localhost:9200/person/_search](http://localhost:9200/person/_search) \
-H ‘Content-Type: application/json’ \
-d ‘{
    **“query”: {
      “multi_match”: {
        “query”: “John”,
        “fields”: [“name”, “age”],
        “fuzzines”: 3,
       }
     }** }’

在这种情况下,我们在所有指定的字段中寻找一个令牌。多匹配查询支持参数“模糊性”,这允许在标记中使用输入错误进行搜索。阅读更多那里。

学期

curl -X GET [http://localhost:9200/person/_search](http://localhost:9200/person/_search) \
-H ‘Content-Type: application/json’ \
-d ‘{
 **“query”: {
   “term”: {
     “name”: {
       “value”: “John”
     }
   }
 }** }’

返回字段中包含精确值的文档。意思是,单据中的字段“名称应该正好是“约翰”才能返回该单据。

模糊的

curl -X GET [http://localhost:9200/person/_search](http://localhost:9200/person/_search) \
-H ‘Content-Type: application/json’ \
-d ‘{
 **“query”: {
    “fuzzy”: {
      “name”: {
        “value”: “Jahn”
      }
    }
 }** }’

返回包含与搜索值相似的文档。这意味着,可搜索的值可以有一个错别字,就像在这个例子中。

查看搜索查询的典型响应

如果您懒得复制粘贴查询,您可以在这里查看典型响应的正文:

Body of the typical response from ElasticSearch

在响应中,您会收到一个对象,它是字段" hits ,由内部键" hits "中所有匹配的文档组成,在这个键下,您还可以找到" total "和" max_score ",它们由返回的文档中匹配记录的总数和最大分数的信息组成。每个文档记录包括“ _source ”以及文档数据和系统字段,如索引、类型、id 和评分。

结果排名

给结果打分

文档的评分是基于指定查询的字段匹配和应用于搜索的任何附加配置来确定的。在那篇文章中,你可以找到关于 ElasticSearch 评分工作方式的很好的描述。此外,ElasticSearch 允许您指定自定义排名功能。阅读更多那里。

提高分数

如果您通过多个字段进行搜索,并且您认为某些字段比其他字段更重要,您可以提高更重要字段的分数。

提高分数意味着,如果某些字段给你的分数是 3,而你将这个字段的分数提高到 x2,那么这个字段的总分数就是 6 (3*2)。

您可以直接在查询中设置 boost。例如,对于 multi_match 搜索,要将 boosting x2 设置为字段“key 1 ”, X5 设置为字段“key2 ”,应按照以下格式指定字段:

“fields”: [“name^2”, “age^5”]

对于其他查询,您可以在搜索查询对象中添加一个关键字“boost”。例如:

“fuzzy”: {“name”: {“value”: “John”, “boost”: 2}}

按某个字段对结果进行排序

当然,您可以按任何字段对结果进行排序,而不是按分数。看看下面的例子:

curl -X GET [http://localhost:9200/person/_search](http://localhost:9200/person/_search) \
-H ‘Content-Type: application/json’ \
-d ‘{
  **“sort”: [
    {“age”: {“order”: “asc”}},
    {“name”: {“order”: “desc”}},
  ],
  “query”: {“match_all”: {}}** }’

在按字段排序的情况下,所有结果将为零分。

AND-OR-NOT 或布尔查询

通常一个条件不足以得到相关的结果。因此,我们需要一些功能来聚合一个查询下的不同条件,进行连接和析取或排除一些结果。就弹性搜索而言,这些类型的查询称为布尔查询:

必须(和)

必须的作用类似于和。这意味着操作符中的每个查询都必须出现在文档中。

过滤器(不影响评分)

“Filter”的作用类似于“must”,但不会增加结果分数的权重。

应该(或)

工作方式类似于或。如果我们在“ should ”下有两个条件,我们将接收所有有第一个或第二个条件的文件。此字段影响评分,这意味着匹配所有条件的文档将比仅匹配一个条件的文档得分更高。

Must_not(不)

工作起来不像。与“must_not”下的条件匹配的文档不得出现在结果中。

极限和偏移

在现实世界中,我们经常需要存储结果的一些限制和偏移。例如,要跳过前 5 个文档以显示接下来的 10 个文档,您需要以下查询:

curl -X GET [http://localhost:9200/person/_search](http://localhost:9200/person/_search) \
-H ‘Content-Type: application/json’ \
-d ‘{
   **“from” : 5,
   “size” : 10,**
   “query”: {
     “match_all”: {} 
   }
}’

分析器

在将文档插入索引之前,ElasticSearch 会运行分析来准备数据。分析是将文本转换为标记的过程,这些标记将被添加到倒排索引中进行搜索。分析由分析仪执行,分析仪可以是内置的或定制的。默认情况下,ElasticSearch 为每个索引设置了标准分析器。你可以使用分析器将表情符号替换为文本,删除特殊字符,删除停用词等等。

聚集

ElasticSearch 支持很多聚合框架,帮助你基于搜索查询聚合数据。聚合可用于构建索引的分析信息,或返回唯一值,或检查某个字段中的最小/*均/最大值,或其他内容。查看文档,查看所有 Elasticsearch 的内置聚合。可以将许多聚合合并到一个查询中。让我们概述一下构建聚合查询有多容易:

curl -X GET [http://localhost:9200/person/_search](http://localhost:9200/person/_search) \
-H ‘Content-Type: application/json’ \
-d ‘{
  **“aggs” : {
    “avg_age_key” : { “avg” : { “field” : “age” } },
    “max_age_key” : { “max” : { “field” : “age” } },
    “min_age_key” : { “min” : { “field” : “age” } },
    “uniq_age_key” : { “terms” : { “field” : “age” } }
  }**
}’

在这个例子中,我将 4 个聚合命令放入一个查询中。很容易理解这些聚合各自的作用。在响应中,您将在响应对象底部的关键字“ aggregations ”下找到您的聚合结果。

MapReduce

聚合允许您对索引进行良好的分析。但是,如果你需要对大型 Elasticsearch 集群上的大量数据进行复杂的分析,换句话说,你有大数据,Elasticsearch 为你提供了一个在索引上运行 MapReduce 作业的机会。看看官方文档了解更多。

处理

ElasticSearch 不支持交易。

摘要

所有列出的优点和功能允许在许多不同的情况下使用 Elasticsearch:

  • 应用程序和网站搜索
  • 企业搜索
  • 日志记录和日志分析
  • 监控许多指标
  • 地理空间数据分析和可视化
  • 安全或业务分析

而很多基于 ElasticSearch 的现成产品(如 Kibana、Elastic Stack 等)让你花更少的钱和更少的时间来开发你的解决方案。

深入了解 YOLO v3:初学者指南

原文:https://towardsdatascience.com/dive-really-deep-into-yolo-v3-a-beginners-guide-9e3d2666280e?source=collection_archive---------1-----------------------

Screenshot from a video made by Joseph Redmon on Youtube

原载于 2019 年 12 月 30 日https://www . yanjia . Li

完整源代码请前往https://github . com/ethanyangali/deep-vision/tree/master/YOLO/tensor flow。我真的很感谢你的明星支持我的努力。

当自动驾驶汽车在道路上行驶时,它是如何知道摄像头图像中其他车辆的位置的?当人工智能放射科医生阅读 x 光片时,它如何知道病变(异常组织)在哪里?今天,我将通过这个迷人的算法,它可以识别给定图像的类别,还可以定位感兴趣的区域。*年来,有许多算法被引入到深度学习方法中来解决对象检测问题,如 R-CNN,Faster-RCNN 和 Single Shot Detector。其中,我最感兴趣的是一个叫 YOLO 的模特——你只会看一眼。这款车型如此吸引我,不仅是因为它有趣的名字,还有一些对我来说真正有意义的实用设计。2018 年,该型号的最新 V3 已经发布,它实现了许多新的最先进的性能。因为我以前编写过一些 GANs 和图像分类网络,而且 Joseph Redmon 在论文中以一种非常简单的方式描述了它,所以我认为这个检测器只是 CNN 和 FC 层的另一个堆栈,只是神奇地工作得很好。

但我错了。

也许是因为我比一般的工程师更笨,我发现对我来说把这个模型从纸上翻译成实际代码真的很难。即使我在几周内成功做到了这一点(有一次我放弃了,把它放了几个星期),我发现让它工作起来对我来说更加困难。有很多关于 YOLO V3 的博客,GitHub repos,但大多数只是给出了架构的一个非常高层次的概述,不知何故他们就成功了。更糟糕的是,论文本身太冷了,它没有提供实现的许多关键细节,我不得不阅读作者最初的 C 实现(我最后一次编写 C 是什么时候?也许在大学?)来证实我的一些猜测。当有一个 bug 时,我通常不知道它为什么会出现。然后,我最终一步一步地手动调试它,并用我的小计算器计算那些公式。

还好这次我没有放弃,终于成功了。但与此同时,我也强烈地感觉到,互联网上应该有一个更全面的指南来帮助像我这样的哑巴理解这个系统的每个细节。毕竟,如果一个细节出错,整个系统将很快崩溃。我敢肯定,如果我不写下来,我也会在几周内忘记所有这些。所以,我在这里,给你呈现这个“深入 YOLO V3:初学者指南”。我希望你会喜欢它。

先决条件

在进入网络本身之前,我需要先澄清一些先决条件。作为读者,你应该:

1.了解卷积神经网络和深度学习的基础知识
2。了解物体探测任务
3 的思路。对算法内部如何工作有好奇心

如果你在前两项上需要帮助,有很多优秀的资源,如 Udacity 计算机视觉纳米学位、 Cousera 深度学习专业化和 Stanford CS231n
如果你只是想构建一些东西来用你的自定义数据集快速检测一些对象,请查看这个 Tensorflow 对象检测 API

YOLO V3

YOLO V3 是对以前的 YOLO 检测网络的改进。与以前的版本相比,它具有多尺度检测,更强的特征提取网络,以及损失函数的一些变化。因此,这个网络现在可以探测到更多的目标,从大到小。当然,就像其他单次检测器一样,YOLO V3 运行速度也很快,并使实时推断在 GPU 设备上成为可能。嗯,作为一个物体检测的初学者,你可能没有一个清晰的图像,他们在这里意味着什么。但是你会在我后面的文章中逐渐理解它们。目前,只要记住 YOLO V3 是截至 2019 年实时对象检测方面最好的模型之一。

网络架构

Diagram by myself

首先,让我们来谈谈这个网络在高层次图中看起来是什么样子(尽管,网络架构是实现中最不耗时的部分)。整个系统可以分为两大部分:特征提取器和检测器;两者都是多尺度。当一幅新图像进来时,它首先通过特征提取器,这样我们可以在三个(或更多)不同的尺度上获得特征嵌入。然后,这些特征被馈入检测器的三个(或更多)分支,以获得包围盒和类别信息。

暗网-53

YOLO V3 使用的特征提取器被称为 Darknet-53。你可能对 YOLO·V1 之前的暗网版本很熟悉,那里只有 19 层。但那是几年前的事了,图像分类网络已经从仅仅是深层次的堆叠发展了很多。ResNet 带来了跳过连接的想法,以帮助激活通过更深的层传播,而不会减少梯度。Darknet-53 借用了这一思想,成功地将网络从 19 层扩展到 53 层,从下图可以看出。

Diagram from [YOLOv3: An Incremental Improvement](https://arxiv.org/abs/1804.02767)

这个很好理解。将每个矩形中的层视为残余块。整个网络是一个由多个模块组成的链,在模块之间有两个 Conv 层以减少维度。在块内部,只有一个瓶颈结构(1x1 后跟 3x3)加上一个跳过连接。如果目标是像 ImageNet 一样进行多类分类,将添加一个*均池和 1000 路完全连接层以及 softmax 激活。

但是,在对象检测的情况下,我们不会包括这个分类头。相反,我们将为这个特征提取器添加一个“检测”头。由于 YOLO V3 被设计为多尺度检测机,我们也需要多尺度的特征。因此,来自最后三个残差块的特征都被用于后面的检测。在下图中,我假设输入是 416x416,因此三个比例向量将是 52x52、26x26 和 13x13。请注意,如果输入尺寸不同,输出尺寸也会不同。

Diagram by myself

多尺度探测器

一旦我们有了三个特征向量,我们现在可以将它们输入到检测器中。但是我们应该如何构造这个探测器呢?不幸的是,作者在这篇论文中没有解释这一部分。但是我们仍然可以看看他在 Github 上发布的源代码。通过这个配置文件,在最终的 1x1 Conv 层之前使用多个 1x1 和 3x3 Conv 层来形成最终输出。对于中比例尺和小比例尺,它还会连接先前比例尺的要素。通过这样做,小规模检测也可以受益于大规模检测的结果。

Diagram by myself

假设输入图像为(416,416,3),检测器的最终输出将为 [(52,52,3,(4 + 1 +数量类)),(26,26,3,(4 + 1 +数量类)),(13,13,3,(4 + 1 +数量类))]。列表中的三个项目代表三种秤的检测。但是这个52 x 52 x 3 x(4+1+num _ classes)矩阵中的单元格是什么意思呢?好问题。这就把我们带到了 2019 年前物体检测算法中最重要的概念:锚盒(prior box)。

锚箱

物体检测的目标是得到一个包围盒和它的类。包围盒通常以一种标准化的 xmin,ymin,xmax,ymax 格式表示。例如,0.5 xmin 和 0.5 ymin 表示框的左上角在图像的中间。直观上,如果我们想得到一个像 0.5 这样的数值,就面临着一个回归问题。我们还不如让网络预测值,并使用均方差来与实际情况进行比较。然而,由于盒子的比例和长宽比的差异很大,研究人员发现,如果我们只是使用这种“暴力”的方式来获得一个包围盒,网络真的很难收敛。因此,在 fast-RCNN 论文中,提出了锚盒的概念。

锚定框是先前的框,其可以具有不同的预定义纵横比。这些纵横比在训练之前通过在整个数据集上运行 K-means 来确定。但是盒子固定在哪里呢?我们需要引入一个叫做网格的新概念。在“古老”的 2013 年,算法通过使用一个窗口滑过整个图像并在每个窗口上运行图像分类来检测对象。然而,这是如此低效,以至于研究人员提议使用 Conv 网一次性计算整个图像(从技术上讲,只有当你并行运行卷积核时。)由于卷积输出特征值的正方形矩阵(如 YOLO 的 13×13、26×26 和 52×52),我们将该矩阵定义为“网格”,并为网格的每个单元分配锚框。换句话说,定位框定位到网格单元,它们共享同一个质心。一旦我们定义了这些锚,我们就可以确定基础事实框与锚框有多少重叠,并选择具有最佳 IOU 的一个并将它们耦合在一起。我猜你也可以声称地面真相箱锚定到这个锚定箱。在我们后面的训练中,我们现在可以预测这些边界框的偏移,而不是预测来自西部的坐标。这是因为我们的地面真相框应该看起来像我们选择的锚框,只需要细微的调整,这给了我们一个很好的训练开端。

Diagram by myself

在 YOLO v3 中,每个网格单元有三个锚盒。我们有三个等级的网格。因此,我们将为每个秤配备 52x52x3、26x26x3 和 13x13x3 锚盒。对于每个锚盒,我们需要预测 3 件事:

1.相对于锚箱的位置偏移: tx,ty,tw,th 。这有 4 个值。
2。指示此框是否包含对象的对象性分数。这有 1 个值。
3。类别概率告诉我们这个盒子属于哪个类别。这有 num_classes 个值。

总的来说,我们为一个锚盒预测了 4 + 1 + num_classes 个值,这就是为什么我们的网络输出一个形状为52x 52 x3x(4+1+num _ classes)的矩阵,正如我之前提到的。 tx,ty,tw,th 不是边界框的真实坐标。这只是相对于特定锚盒的相对偏移量。我会在后面的损失函数部分解释这三个预测。

Anchor box 不仅使检测器的实现变得更加困难和容易出错,而且如果你想得到最好的结果,它还在训练之前引入了一个额外的步骤。所以,就我个人而言,我非常讨厌它,觉得这个锚箱的想法更像是一个黑客,而不是一个真正的解决方案。2018 年和 2019 年,研究人员开始质疑锚盒的必要性。像 CornerNet、Object as Points 和 FCOS 这样的论文都讨论了在没有锚盒帮助的情况下从头训练对象检测器的可能性。

损失函数

有了最终的检测输出,我们现在可以计算相对于地面真实标签的损失。损失函数包括四个部分(或者五个,如果你分开 noobj 和 obj):质心(xy)损失、宽度和高度(wh)损失、对象(obj 和 noobj)损失和分类损失。放在一起时,公式是这样的:

Loss = Lambda_Coord * Sum(Mean_Square_Error((tx, ty), (tx’, ty’) * obj_mask)
 + Lambda_Coord * Sum(Mean_Square_Error((tw, th), (tw’, th’) * obj_mask)
 + Sum(Binary_Cross_Entropy(obj, obj’) * obj_mask) + Lambda_Noobj * Sum(Binary_Cross_Entropy(obj, obj’) * (1 -obj_mask) * ignore_mask)
 + Sum(Binary_Cross_Entropy(class, class’))

这看起来很吓人,但是让我把它们一一分解并解释。

xy_loss = Lambda_Coord * Sum(Mean_Square_Error((tx, ty), (tx’, ty’)) * obj_mask)

第一部分是包围盒形心的损失。 txty 是相对于地面的质心位置。 tx'ty' 是直接来自检测器的质心预测。这种损失越小,预测和地面实况的质心就越接*。由于这是一个回归问题,我们在这里使用均方差。此外,如果对于某些细胞没有来自地面真理的对象,我们不需要将该细胞的损失包括在最终损失中。因此我们在这里也乘以 obj_maskobj_mask 为 1 或 0,表示是否有物体。事实上,我们可以使用 obj 作为 obj_maskobj 是我将在后面介绍的客观性分数。需要注意的一点是,我们需要对地面实况进行一些计算,以得到这个 txty 。所以,我们先来看看如何得到这个值。正如作者在论文中所说:

bx = sigmoid(tx) + Cx
by = sigmoid(ty) + Cy

这里的 bxby 是我们通常用来作为质心位置的绝对值。例如, bx = 0.5,by = 0.5 表示这个盒子的质心就是整个图像的中心。然而,由于我们要计算锚点的质心,我们的网络实际上是预测相对于网格单元左上角的质心。为什么是网格单元?因为每个锚定框都绑定到一个网格单元,所以它们共享同一个质心。所以对网格单元的差异可以代表对锚盒的差异。在上面的公式中, sigmoid(tx)sigmoid(ty) 是相对于网格单元的质心位置。例如, sigmoid(tx) = 0.5,sigmoid(ty) = 0.5 表示质心是当前网格单元的中心(但不是整个图像)。 CxCy 代表当前网格单元左上角的绝对位置。因此,如果网格单元是网格 13x13 的第二行第二列中的单元,那么 Cx = 1,Cy = 1 。而如果我们将这个网格单元位置加上相对质心位置,我们将得到绝对质心位置 bx = 0.5 + 1by = 0.5 + 1 。当然,作者不会告诉你,你也需要通过除以网格大小来归一化,所以真正的 bx 将是 1.5/13 = 0.115 。好了,现在我们理解了上面的公式,我们只需要把它反过来,这样我们就可以从 bx 得到 tx ,以便把我们原来的地面真相翻译成目标标签。最后, Lambda_Coord 是 Joe 在 YOLO v1 论文中引入的权重。这是更强调本地化而不是分类。他建议的值是 5。

Diagram from [YOLOv3: An Incremental Improvement](https://arxiv.org/abs/1804.02767)

wh_loss = Lambda_Coord * Sum(Mean_Square_Error((tw, th), (tw’, th’)) * obj_mask)

下一个是宽度和高度的损失。再次,作者说:

bw = exp(tw) * pw
bh = exp(th) * ph

这里 bwbh 仍然是整个图像的绝对宽度和高度。 pwph 是前一个盒子的宽度和高度(又名。锚箱,为什么有这么多名字)。我们在这里取 e^(tw) 是因为 tw 可能是负数,但是在现实世界中宽度不会是负数。所以这个 exp() 会让它为正。并且我们乘以先前的框宽度 pwph ,因为预测 exp(tw) 是基于锚框的。所以这个乘法给了我们真正的宽度。身高也一样。同样,我们可以在计算损耗时,将上面的公式反过来将 bwbh 转化为 txth

obj_loss = Sum(Binary_Cross_Entropy(obj, obj’) * obj_mask)noobj_loss = Lambda_Noobj * Sum(Binary_Cross_Entropy(obj, obj’) * (1 — obj_mask) * ignore_mask)

第三项和第四项是客体性和非客体性得分损失。对象性表示当前单元格中有对象的可能性。与 YOLO v2 不同,这里我们将使用二进制交叉熵而不是均方误差。事实上,对于包含对象的单元格,objectness 始终为 1,对于不包含任何对象的单元格,object ness 始终为 0。通过测量这个 obj_loss ,我们可以逐渐教会网络检测感兴趣的区域。在此期间,我们不希望网络通过到处提出对象来欺骗我们。因此,我们需要 noobj_loss 来惩罚那些假阳性提议。我们通过用 1-obj_mask 屏蔽预测得到假阳性。*ignore_mask*用于确保我们只在当前框与地面真相框没有太多重叠时进行惩罚。如果有,我们倾向于更柔和,因为它实际上非常接*答案。正如我们从论文中看到的,“如果边界框先验不是最好的,但确实与地面真实对象重叠超过某个阈值,我们忽略预测。”由于在我们的基本事实中有比 obj 多得多的 noobj,我们也需要这个 Lambda_Noobj = 0.5 来确保网络不会被没有对象的单元所控制。

class_loss = Sum(Binary_Cross_Entropy(class, class’) * obj_mask)

最后一个损失是分类损失。如果总共有 80 个类,则类'将是具有 80 个值的独热编码向量。在 YOLO v3 中,它被更改为多标签分类,而不是多类分类。为什么?因为一些数据集可能包含分层或相关的标签,例如女人。因此,每个输出像元可能有不止一个类为真。相应地,我们也对每一类逐一应用二元交叉熵并求和,因为它们并不互斥。就像我们对其他损失所做的那样,我们也乘以这个 obj_mask ,以便我们只计算那些具有基础真值对象的单元格。

为了充分理解这种损失是如何发生的,我建议您用一个真实的网络预测和地面实况来手动浏览它们。用计算器(或 tf.math )计算损失真的能帮你抓住所有的本质细节。我自己做的,这帮助我找到了很多错误。毕竟,细节决定成败。

履行

如果我在这里停止写作,我的帖子将会像网络上的另一篇“YOLO v3 评论”。一旦您从上一节中理解了 YOLO v3 的一般概念,我们现在就可以开始探索我们 YOLO v3 之旅剩下的 90%了:实现。

结构

9 月底,谷歌终于发布了 TensorFlow 2.0.0。这对 TF 来说是一个迷人的里程碑。然而,新的设计并不一定意味着开发者的痛苦会减少。从 2019 年初开始,我就一直在玩 TF 2,因为我一直想以我为 PyTorch 所做的方式编写 TensorFlow 代码。如果不是因为 TensorFlow 强大的制作套件像 TF Serving,TF lite,还有 TF Board 等等。,我估计很多开发者不会为新项目选择 TF。因此,如果您对生产部署没有强烈的需求,我建议您在 PyTorch 甚至 MXNet 中实现 YOLO v3。然而,如果你下定决心坚持使用 TensorFlow,请继续阅读。

TensorFlow 2 正式让渴望模式成为一级公民。简而言之,您现在可以利用原生 Python 代码以动态模式运行图表,而不是使用 TensorFlow 特定的 API 在图表中进行计算。没有更多的图形编译和更容易的调试和控制流程。在性能更重要的情况下,还提供了一个方便的 tf.function decorator 来帮助将代码编译成静态图。但是,现实是,渴望模式和 tf.function 仍然有问题,或者有时没有很好地记录,这使得你在像 YOLO v3 这样复杂的系统中的生活更加艰难。此外,Keras 模型不是很灵活,而定制的训练循环仍然是相当实验性的。所以你用 TF 2 写 YOLO v3 最好的策略就是先从一个最小的工作模板开始,逐渐给这个外壳增加更多的逻辑。通过这样做,我们可以在错误隐藏在一个巨大的嵌套图中之前尽早失败并修复它。

资料组

除了要选择的框架,成功训练最重要的是数据集。在论文中,作者使用 MSCOCO 数据集来验证他的想法。事实上,这是一个很好的数据集,我们应该在这个基准数据集上为我们的模型争取一个好的精度。然而,像这样的大型数据集也可能隐藏代码中的一些错误。例如,如果损失没有下降,你如何知道它只是需要更多的时间来收敛,或者你的损失函数是错误的?即使使用 GPU,训练的速度仍然不够快,无法让你快速迭代和修复东西。因此,我建议您构建一个包含数十个图像的开发集,以确保您的代码首先看起来“工作”。另一种选择是使用 VOC 2007 数据集,它只有 2500 个训练图像。要使用 MSCOCO 或 VOC2007 数据集并创建 TF 记录,可以参考我这里的助手脚本: MSCOCO , VOC2007

预处理

预处理是指将原始数据转换成合适的网络输入格式的操作。对于图像分类任务,我们通常只需要调整图像的大小,并对标签进行一次性编码。但是对于 YOLO v3 来说,事情有点复杂。还记得我说过网络的输出就像52 x 52 x3x(4+1+num _ classes)有三种不同的尺度吗?由于我们需要计算基础事实和预测之间的差值,我们还需要首先将基础事实格式化成这样的矩阵。

对于每个真实边界框,我们需要选择最佳的比例和锚。例如,天空中的一个小风筝应该是小比例的(52x52)。如果风筝在图像中更像一个正方形,我们也应该选择那个比例中最正方形的锚。在 YOLO v3 中,作者为 3 个音阶提供了 9 个锚点。我们所需要做的就是选择一个最符合我们地面真相框的。当我实现这个时,我想我也需要锚盒的坐标来计算 IOU。事实上,你不需要。因为我们只是想知道哪个锚点最适合我们的基础真相框,所以我们可以假设所有锚点和基础真相框共享同一个质心。在这种假设下,匹配度就是重叠面积,可以通过最小宽度最小高度*来计算。

在转换过程中,还可以添加一些数据扩充,以增加虚拟训练集的多样性。例如,典型的增强包括随机翻转、随机裁剪和随机转换。然而,这些增强不会阻止您训练一个工作的检测器,所以我不会过多地讨论这个高级主题。

培养

经过这些讨论,你终于有机会运行“python train . py”开始你的模型训练了。这也是你遇到大多数 bug 的时候。当你被封锁时,你可以参考我的训练脚本这里。同时,我想提供一些对我自己的训练有帮助的提示。

楠的损失

  1. 检查你的学习率,确保它不会太高,以至于爆发你的梯度。
  2. 检查二进制交叉熵中的 0,因为 ln(0)不是数字。您可以从(epsilon,1-epsilon)中截取值。
  3. 找个例子,一步一步走过你的失落。找出你损失的哪一部分归南。例如,如果宽度/高度损失到 NaN,这可能是因为您从 twbw 的计算方法是错误的。

亏损居高不下

  1. 试着提高自己的学习率,看看能不能降得更快。我的从 0.01 开始。但我也见过 1e-4 和 1e-5 的作品。
  2. 想象你预处理过的基础事实,看看它是否有意义。我之前遇到的一个问题是,我的输出网格是在[y][x]而不是[x][y],但是我的地面真相是反的。
  3. 再一次,用一个真实的例子来说明你的损失。我在计算对象和类别概率之间的交叉熵时犯了一个错误。
  4. 我的损失也保持在 50 个 MSCOCO 时代后的 40 左右。然而,结果并没有那么糟糕。
  5. 仔细检查代码中的坐标格式。YOLO 需要 xywh (质心 x,质心 y,宽度和高度),但大部分数据集都是以 x1y1x2y2 (xmin,ymin,xmax,ymax)的形式出现。
  6. 仔细检查你的网络架构。不要被一个名为“*距离观察 yolov 3-CyberAILab”的帖子中的图表误导。
  7. TF . keras . loss . binary _ cross entropy不是你需要的二进制交叉熵之和。

损失较低,但预测失败

  1. 根据您的观察将 lambda_coordlambda_noobj 调整到损耗。
  2. 如果你在自己的数据集上训练,并且数据集相对较小,那么损失函数中的 obj_mask 就不会错误地去掉必要的元素。
  3. 一次又一次,你的损失函数。计算损耗时,它使用单元格中的相对 xywh(也称为 tx,ty,tw,th )。不过,在计算忽略遮罩和 IOU 时,它会在整个图像中使用绝对 xywh。不要把它们混淆了。
  4. 损失很低,但是没有预测
  5. 如果您正在使用自定义数据集,请首先检查您的基础事实框的分布。盒子的数量和质量真的会影响网络学习(或欺骗)做什么。

在您的训练集上进行预测,看看您的模型是否至少可以在训练集上过度拟合。

  1. 多 GPU 训练
  2. 由于对象检测网络有如此多的参数要训练,因此拥有更多的计算能力总是更好的。然而,TensorFlow 2.0 到目前为止还没有对多 GPU 训练提供很大的支持。要在 TF 中做到这一点,你需要选择一个训练策略,比如 MirroredStrategy,就像我在这里做的。然后将数据集加载器也打包成分布式版本。对于分布式训练的一个警告是,每个批次产生的损失应该除以全局批次大小,因为我们将对所有 GPU 结果进行“减少总和”。例如,如果本地批量大小为 8,并且有 8 个 GPU,那么您的批量损失应该除以全局批量大小 64。一旦你把所有复制品的损耗加起来,最后的结果将是单个例子的*均损耗。

后处理

该检测系统的最后一个组件是后处理器。通常,后处理只是一些琐碎的事情,比如用人类可读的类文本替换机器可读的类 id。不过,在对象检测中,我们还有一个更关键的步骤要做,以获得最终的人类可读结果。这被称为非最大抑制。

让我们回忆一下我们的客观损失。当虚假提议与地面真相有很大重叠时,我们不会用 noobj_loss 来惩罚它。这鼓励网络预测接*的结果,以便我们可以更容易地训练它。此外,虽然在 YOLO 没有使用,但当使用滑动窗口方法时,多个窗口可以预测同一物体。为了消除这些重复的结果,聪明的研究人员设计了一种叫做非最大抑制(NMS)的算法。

NMS 的想法很简单。首先找出具有最佳置信度的检测框,将其添加到最终结果中,然后用该最佳框消除 IOU 超过特定阈值的所有其他框。接下来,你在剩下的盒子中选择另一个最有信心的盒子,重复做同样的事情,直到什么都没有了。在代码中,由于 TensorFlow 在大多数时候需要显式的形状,我们通常会定义一个最大的检测数,如果达到这个数就提前停止。在 YOLO v3 中,我们的分类不再相互排斥,一个检测可以有多个真实的类。然而,一些现有的 NMS 规范没有考虑到这一点,所以在使用时要小心。

结论

Photo by Python Lessons from Analytics Vidhya

YOLO v3 是人工智能崛起时代的杰作,也是 2010 年代卷积神经网络技术和技巧的优秀总结。虽然有许多像 Detectron 这样的交钥匙解决方案来简化制作探测器的过程,但对机器学习工程师来说,编写如此复杂的探测器的实践经验确实是一个很好的学习机会,因为仅仅阅读论文是远远不够的。就像雷伊·达里奥谈到他的哲学时说的那样:

痛苦加反思等于进步。

我希望我的文章可以成为您在实施 YOLO v3 的痛苦旅程中的一座灯塔,也许您也可以在以后与我们分享这一令人愉快的进展。如果你喜欢我的文章或者我的 YOLO v3 源代码,请⭐star⭐我的 repo ,那将是对我最大的支持。

参考

张子豪, YoloV3 在 TensorFlow 2.0 ,Github 中实现

杨云, TensorFlow2.x-YOLOv3 ,Github

  • 逍遥王可爱, 史上最详细的 Yolov3 边框预测分析, 知乎专栏
  • Joseph Redmon, YOLOv3:增量改进
  • 约瑟夫·雷德蒙,阿里·法尔哈迪,YOLO9000:更好,更快,更强
  • 约瑟夫·雷德蒙,桑托什·迪夫瓦拉,罗斯·吉斯克,阿里·法尔哈迪,你只看一次:统一的实时物体检测,2016 年 IEEE 计算机视觉与模式识别会议
  • Ayoosh Kathuria,YOLO v3 有什么新内容?,走向数据科学
  • Python 课程, YOLO v3 理论讲解,分析 Vidhya
  • Ayoosh Kathuria, What’s new in YOLO v3?, Towards Data Science
  • Python Lessons, YOLO v3 theory explained, Analytics Vidhya

二项式随机变量的散度

原文:https://towardsdatascience.com/divergence-in-binomial-random-variable-f56ba7242f7?source=collection_archive---------22-----------------------

Photo by Eddie Zhang on Unsplash

在这篇文章中,我们将了解因变量 试验 或样本的数量如何影响二项变量。在进入这个主题之前,需要理解什么是二项随机变量。如果你不熟悉这个——请访问这个帖子。在这篇文章中,我们将尝试回答两个问题

  1. "审判应该是相互独立的."对于二项随机变量,这个条件真的有必要吗?
  2. 我们知道二项随机变量服从离散分布,有没有可能它也可以是连续分布?

在开始回答这些问题之前,让我们回忆一下二项式变量的条件:

  1. 试验应相互独立。
  2. 每次试验都可以分为成功或失败。
  3. 试验次数固定。
  4. 每次试验的成功概率应保持不变。

现在让我们看看个别问题:

1.审判应该是相互独立的

我们试着用一个例子来理解。考虑一个场景:假设我们想在一家食品超市进行一项调查,我们需要从三个不同的人那里获得关于他们是否购买了一种产品的反馈。表示我们从一家食品超市的所有顾客中随机选择 3 个人,并询问他们是否购买了某种产品。假设商场中有 50%的人购买了该产品,商场中总共有 200 人,你会如何发现被选中的 3 个人购买该产品的概率是多少?

在这种情况下,让我们定义 X =在由 200 名顾客中的 3 名反馈组成的调查中购买该产品的人数。我们需要找到 p(X=3 ),即 200 人中随机选择的 3 个人购买该产品的概率。

在这里,审判是“选人”。实验由固定数量的试验(称为反馈)组成,等于 3 次。如果有人购买了该产品,则可以认为试用成功。因此满足条件 2,3,4。条件 1 呢。让我们来研究一下:

比方说,我们决定收集走出商店的前 3 个人的反馈。据我们所知,商场里 50%的人都购买过这种产品。那么第一个人购买了该产品的概率是多少?它是 50%,即 100/200。现在让我们假设第一个人走出来,我们发现他已经买了这个产品。现在下一个人购买该产品的概率是多少?因为里面有 199 个人,所以是 99/199。现在二审并不独立于一审。因此,它似乎不是二项分布。为了使它独立,我们必须把第一个人送回超市,这不是一个好主意,因为我们不能仅仅因为我们希望我们的试验是独立的,就要求顾客回到店里。

解决方案:根据实验假设

如果样本量小于或等于总人口的 10%,则试验可视为独立的

在上面的例子中,3 小于或等于 200 的 10%。因此,这些试验可以被视为独立的。不管第一个走出商店的人是谁,我们仍然可以认为这是一个独立的事件。

因此:p(X = 3)=(100/200)(100/200)(100/200)

2.有没有可能也可以是连续分布?

随着一个实验中的试验次数越来越多,这个分布看起来就像正态分布,它只不过是一个连续的变量分布。

在上述图示中,试验次数限制为 5 次。当试验趋于无穷大时,二项分布趋于正态分布。

结论

在这篇文章中,我们了解到,如果试验数量小于或等于总人口的 10%,即使是相依试验也可能导致二项分布。我们还观察到随着试验次数的增加,二项分布如何接*正态分布。

寻找下一个后几何随机变量

分而治之:使用 RFM 分析对你的客户进行细分

原文:https://towardsdatascience.com/divide-and-conquer-segment-your-customers-using-rfm-analysis-68aee749adf6?source=collection_archive---------13-----------------------

使用 PYTHON 进行客户细分

了解如何使用 Python 和 RFM 对客户群进行细分,从而做出更好的商业决策

Photo by Linh Pham on Unsplash

大多数经营在线业务的人必须知道从他们*台产生的用户数据中收集洞察力的重要性。了解一些可用性问题、客户偏好、一般购买行为等等。因此,如果你正在建立一个电子商务,存储你的订单、客户及其交易的数据是至关重要的。存储这些数据的主要目的之一是分析客户的行为,并据此设计更有利可图的策略。

在我们公司也没什么不同!我们有一个非常以数据为中心的文化,并一直在寻找新的方法,根据我们可以从中提取的信息来改进我们的产品。我们的核心产品之一是一款饮料配送应用程序,于 2019 年第二季度开始运营。有问题的应用程序是商店和当地生产商销售啤酒、葡萄酒、饮料和类似产品(如零食等)的市场。

由于我们是一家初创公司,而且该产品在市场上还比较新,因此它带来了一些独特的挑战,开发它是一个不断发展的过程。我们目前正在实施各种新功能和缺陷修复。然而,自我们发布以来生成的数据仍然是了解我们的客户以及*台本身的重要来源。

除此之外,将商业智能集成到系统中的追求也推动了这项工作。在这一系列文章中,我们将研究两种不同的方法,根据客户的相似性将他们分成不同的组:经典的 RFM 分析(在第一篇文章中探讨)和 K-Means 聚类(在后续文章中探讨)。

在本系列中,我们将尝试回答其中的一些问题:

  • 现有的用户角色(组)是什么?
  • 这些用户群有什么特征(*均票、频率、新*度、位置等。)?

当然,由于数据是专有的,并且包含一些敏感信息,我们无法提供原始数据集供您跟踪。除此之外,呈现的一些数据将被预先修改或标准化。

但是不要害怕!你可以在 Kaggle 上找到一些类似的数据集,比如 零售数据分析网上零售数据集零售交易数据 数据集。除此之外,这些文章的目的更多的是教你一些理论和编码,而不是数据和结果本身。

所以,让我们开始吧!

一些先决条件

为了执行这个分析,我们使用了 Python 编程语言和一些基本的数据科学库。虽然并不严格要求您理解代码的所有部分,但是建议您至少对编程有一点了解。

考虑到这一点,下面是我们将在整个系列中使用的一些概念:

  • Python 以及对 Numpy、Pandas 和 Scikit 的一些基本了解——学习 APIs
  • 一些统计(没什么太花哨的);
  • 基本了解一些机器学习概念和术语,如聚类

说完这些,让我们开始讨论吧

首先,什么是分段,为什么需要分段

客户细分是发展成功业务的重要组成部分。客户有不同类型的需求,随着客户和交易基础的增长,了解他们每个人的需求变得越来越困难。在这一点上,你应该能够识别这些差异并采取行动。然而,有许多方法来执行这种分段。我们今天要谈论的是 RFM。

RFM 是选择重要客户最广泛使用的技术之一。这是一种非常流行的客户细分技术,它使用客户过去的购买行为,根据相似性将他们分成不同的组。

RFM 这个名字代表新*性、频率和货币价值。Recency (R)表示自客户最后一次购买以来的天数;频率(F)代表客户在被分析的时间范围内购买的次数;最后,货币(M)表示客户在同一时期花费的总金额。

在计算了每个客户的*期、频率和货币价值后,我们需要将他们分成 3 个或更多不同的类别。这样,我们可以根据这些类别对不同类型的客户进行排名。

让我们在一个更实际的场景中来看看,好吗?

数据

我们将从一个数据集开始,该数据集包含在我们的*台上执行的单个订单的信息。数据以交易级别表示,即数据集的每一行包含与单个交易相关的特征,例如日期、时间、支付方式、进行购买的用户的客户端 id 等。

数据集的一些重要特征突出显示如下:

  • order_id: 订单的唯一标识符;
  • store_id: 订单所在店铺的 id;
  • customer_id: 执行订单的客户的 id;
  • 支付选项 id: 所使用的支付选项的标识符;
  • ****状态:一个表示订单当前状态的整数;
  • ****创建:订单创建的日期和时间;
  • ****修改日期:订单状态上次修改的日期和时间
  • shipping_price: 自明
  • total_price: 订单总价,含运费
  • ****纬度&经度:订单送达的地点

建造 RFM 餐桌

加载订单数据集后,我们需要对其进行分组和汇总,以获得每个客户的客户级数据,如订单数量、总支出、频率、最*等。有了这些信息,我们可以继续进行 RFM 分析。下面突出显示了用于加载数据集和执行分组的代码:

**# load the order dataset
orders = pd.read_csv('data/orders-27-11-2019.csv')# convert 'created' and 'modified' columns to datetime 
orders['created'] = pd.to_datetime(orders['created'])
orders['modified'] = pd.to_datetime(orders['modified'])# create a snapshot date with today's date
snapshot_date = max(orders.created) + datetime.timedelta(days=1)# create functions to get recency and tenure
def get_recency(x):
    last_purchase = x.max()
    return (snapshot_date - last_purchase).days
def get_tenure(x):
    first_purchase = x.min()
    return (snapshot_date - first_purchase).days# aggregate data by the customers
customers = orders.groupby('customer_id').agg(
    recency=('created', get_recency),
    tenure=('created', get_tenure),
    frequency=('order_id', 'count'),
    total_value=('total_price', 'sum'),
    mean_value=('total_price', 'mean'),
)# show 5 samples of the grouped dataframe
customers.sample(5)**

Figure 1: customer level dataset

请记住,我们掩盖了真正的价值,所以这就是为什么他们中的一些人可能看起来很奇怪。还要注意的是,我们添加了两个之前没有讨论过的新列:表示客户第一次购买以来的时间的保有权*均值,这是不言自明的。这两列将用于改进下一篇文章中介绍的集群。

我们需要做的下一件事是将最*度频率、总值分成我们之前讨论过的类别。对于我们的用例,我们决定将每个特性分成 4 个四分位数,大致将样本分成 4 个等比例的部分。我们分别把这些分数叫做 RFM 。用于执行此操作的代码如下所示:

**# use only the necessary columns
rfm = customers[['customer_id', 'recency', 'frequency', 'total_value']]# recency quartile segmentation
r_labels = range(4, 0, -1)
recency = rfm['recency']
r_quartiles, bins = pd.qcut(recency, 4, labels=r_labels, retbins=True)
rfm = rfm.assign(R=r_quartiles.values)# frequency quartile segmentation
f_labels = range(1, 5)
frequency = rfm['frequency'].rank(method='first') # rank to deal with duplicate values
f_quartiles, bins = pd.qcut(frequency, 4, labels=f_labels, retbins=True)
rfm = rfm.assign(F = f_quartiles.values)# monetary value quartile segmentation
m_labels = range(1, 5)
monetary = rfm['total_value']
m_quartiles, bins = pd.qcut(monetary, 4, labels=m_labels, retbins=True)
rfm = rfm.assign(M = m_quartiles.values)# show 5 samples of the newly created scores
rfm[['R', 'F', 'M']].sample(5)**

Figure 2: Initial RFM scores

为了简化分析,我们将 3 个不同的分数( RFM )结合起来创建一个单一的指标是很重要的。

有几种方法可用。第一个是创建一个 RFM 段,将个人得分的 3 个数字连接起来,形成一个从 111(所有三个指标的最低分)到 444(所有三个指标的最高分)的 3 个字符串。这种方法的缺点是创建了许多不同的细分市场(4x4x4 = 64 个细分市场),不容易区分和区分优先级(432 和 234 客户谁更有价值?).

另一种可能性是将 3 个单独的分数相加,得出 RFM 分数,一个从 3(所有指标中可能的最低分)到 12(所有指标中可能的最高分)的数字。这里的缺点是,具有不同购买习惯的客户(例如,来自不同的 RFM 细分市场)可能会落在相同的分数箱上。例如,细分市场 431 和 134 中的两个客户都将得到 8 分。另一方面,我们最终得到了不太明显的分数来进行比较(4+4+4 = 12 个分数),每个分数都具有相同的相关性。

**# Build RFM Segment and RFM Score
def join_rfm(x): 
    return str(x['R']) + str(x['F']) + str(x['M'])rfm['segment'] = rfm.apply(join_rfm, axis=1)
rfm['score'] = rfm[['R','F','M']].sum(axis=1)# show 5 samples
rfm[['R', 'F', 'M', 'segment', 'score']].sample(5)**

Figure 3: RFM segments and scores

我们可以根据宁滨的得分范围进一步将客户分为 RFM 等级。例如,我们可以说,分数从 3 到 5 的客户是青铜级,从 5 到 9 的客户是白银级,从 9 到 12 的客户是黄金级。

**# group into different tiers
def get_tier(df):
    if df['score'] >= 9:
        return 'Gold'
    elif (df['score'] >= 5) and (df['score'] < 9):
        return 'Silver'
    else:
        return 'Bronze'rfm['tier'] = rfm.apply(get_tier, axis=1)rfm[['R', 'F', 'M', 'segment', 'score', 'tier']].sample(5)**

Figure 4: RFM scores binned into 3 tiers

好吧,但是那告诉你什么?

按照这些简单的步骤,你已经成功地细分了你的客户群!从这里你能去哪里?

您可以通过构建一些汇总来查看每个不同分数段、层级的变量的均值标准差****

**# Summary metrics per RFM Score
score_summary = rfm.groupby('score').agg(
    mean_recency=('recency', 'mean'),
    std_recency=('recency', 'std'),
    mean_frequency=('frequency', 'mean'),
    std_frequency=('frequency', 'std'),
    mean_monetary=('total_value', 'mean'),
    std_monetary=('total_value', 'std'),   
    samples=('customer_id', lambda x: len(x)*100/len(rfm.score))
).round(2)# Get the 10 segments with most customers
popular_segments = rfm.segment.value_counts()[:10].index.tolist()# Summary metrics for the 10 most popular RFM Segments
segment_summary = rfm[rfm.segment.isin(popular_segments)].groupby('segment').agg(
    mean_recency=('recency', 'mean'),
    std_recency=('recency', 'std'),
    mean_frequency=('frequency', 'mean'),
    std_frequency=('frequency', 'std'),
    mean_monetary=('total_value', 'mean'),
    std_monetary=('total_value', 'std'),   
    samples=('customer_id', lambda x: len(x)*100/len(rfm.score))
).round(2)# Summary metrics per RFM Tier
tier_summary = rfm.groupby('tier').agg(
    mean_recency=('recency', 'mean'),
    std_recency=('recency', 'std'),
    mean_frequency=('frequency', 'mean'),
    std_frequency=('frequency', 'std'),
    mean_monetary=('total_value', 'mean'),
    std_monetary=('total_value', 'std'),   
    samples_percentage=('customer_id', lambda x: len(x)*100/len(rfm.score))
).round(2)**

最*发生率最低、频率最高和金额最高的客户可以被归类为我们的最佳客户。

另一方面,新*性高的顾客是那些由于某种原因不再光顾商店的顾客。企业应该专注于寻找和理解这些原因,以及一些方法来重新激活那些沉睡的客户。

最后,低频顾客是那些不经常购买的顾客。如果他们的新*度较低,他们可能是新客户,企业应该专注于留住他们以备将来购买。另一方面,如果他们具有较高的新*性,他们也可以被归类为需要重新激活的客户。

结论

至此,我们结束了对 RFM 分割的讨论。但是你不应该停止探索!

除了对客户进行细分,企业还可以使用 RFM 标准来评估客户的购买模式,并通过分析这些客户的反应来评估不同营销策略的有效性。

在系列的下一部分中,我们将深入研究另一种形式的客户细分:使用 K 均值进行聚类。

TL;博士

RFM 分析的步骤可以总结如下:

  • 创建 RFM 表;
  • 计算每个客户的*期、频率和货币价值;
  • 将不同的值分成不同的类别(在我们的例子中是从 1 到 4),创建 R、F 和 M 分数;
  • 根据上一步计算的 3 个基本分数,创建组合指标,如 RFM 段、 RFM 分数RFM 等级
  • 创建摘要以可视化这些组;

潜入大理:如何使用 NVIDIA 的 GPU 优化图像增强库

原文:https://towardsdatascience.com/diving-into-dali-1c30c28731c0?source=collection_archive---------9-----------------------

Salvador Dalí. The Persistence of Memory. Credit: The Museum of Modern Art

深度学习图像增强管道通常提供速度或灵活性,但永远不会同时提供两者。计算效率高、生产就绪的计算机视觉管道往往用 C++编写,并要求开发人员指定图像变换算法的所有细节,以至于这些管道最终不太适合进一步的即时调整。另一方面,像 Pillow 这样的流行 Python 库提供了高级 API,允许从业者从看似无限的调整组合中进行选择,这些调整可以应用于庞大的图像变换算法库。不幸的是,这种自由带来了性能急剧下降的代价

大理图书馆试图让从业者两全其美。它的图像转换算法本身是用 C++代码编写的,可以充分发挥 NVIDIA GPU 芯片的性能,从而可以在每个批处理的基础上并行执行图像转换,无论用户可以访问多少个 GPU。C++源代码被绑定到一个用户友好的 Python API,通过它,从业者可以定义图像转换管道,该管道可以很好地与 PyTorch 和 TensorFlow 框架一起使用。

为了确定 DALI 是否确实提供了它所宣传的速度和灵活性,我花了一周的大部分时间对这个库进行了一系列自己的实验。剧透:虽然 DALI 绝对带来了速度,但灵活性仍有所欠缺。

达利的承诺

尽管如此,花时间去了解大理是绝对值得的。在 GPU 上进行图像增强的好处是不言而喻的,我的 DALI 图像管道比我写过的任何其他类似的图像增强管道运行得都快。

此外,我刚刚完成了 fast.ai 深度学习课程第二部分的最新课程,并试图建立一个与 fastai 库的新改进版本兼容的 DALI 管道,我们从头开始建立了 fastai 库,作为课程作业的一部分。这被证明是一个有意义的练习,因为根据 fastai 核心开发者 Sylvain Gugger 的说法,fastai 官方库即将发布的第二版将包含许多在我们班上引入的范例,例如一个具有更加灵活的回调集成的训练循环。

在接下来的几段中,我将介绍构建 DALI 管道的基础知识,并指出如何将它们连接到 fastai 的 v2.0 训练循环。你将会看到 DALI 运行的有多快(这真的令人印象深刻),以及我想出的一个非常奇怪的解决办法,试图绕过 DALI 图书馆的一个显著缺点。

搭建舞台

我的 DALI 增强管道包括随机裁剪和调整大小、翻转、透视扭曲和旋转变换,这些是我在 2019 fast.ai 第二部分课程中从零开始学习的实现的。为了设置基线并衡量每个 DALI 变换是否有助于改善结果,我创建了一个简单的四层 CNN 模型,其任务是使用 Imagenette 数据集执行图像分类。Imagenette 是由杰瑞米·霍华德创建的,是 ImageNet 的一个更精简的版本,它允许从业者感受如果在 ImageNet 上训练他们的模型将会如何执行,而实际上不必从头开始训练 ImageNet 的所有部分。我喜欢在原型的早期迭代中使用 Imagenette 进行快速的健全性检查,它已经成为我实验中不可或缺的一部分。

如何建设大理管道

所有 DALI 管道的主干是一个叫做管道的 Python 类。我决定为我的训练和验证数据创建专门的管道类,每个类都继承自这个类。为了创建每个类,我必须定义两个方法。第一个方法__init__(),是指定每个图像变换操作的超参数的地方。除了像图像旋转和翻转这样的增强,这些操作还可以包括初始图像加载、调整大小、归一化、张量整形和数据类型转换。

第二个方法是define_graph(),在这里您定义了您希望管道的图像转换执行的顺序。这个方法也是您希望调用 DALI 随机数生成器的地方,这样您就可以将它们作为参数传递给支持随机生成扩充的图像变换操作。define_graph()将返回一个包含变换图像及其相应标签的元组。

示例:包括旋转变换

下面是我如何使用 DALI 的[ops.Rotate](https://docs.nvidia.com/deeplearning/sdk/dali-developer-guide/docs/supported_ops.html#rotate) 函数将随机生成的图像旋转添加到我的训练管道中:

第一步

在我的管道类'__init__()方法中,我为旋转操作创建了变量,ops.Rotate,也为两个随机数生成器创建了变量。第一个随机数生成器[ops.Uniform](https://docs.nvidia.com/deeplearning/sdk/dali-developer-guide/docs/supported_ops.html#uniform),将产生一个和我的批量一样长的列表。该列表将包含指定角度(以度为单位)的浮动,通过该角度ops.Rotate将旋转批次图像。每个角度都是从范围为[-7,7]的均匀分布中随机选取的。第二个随机数生成器,[ops.CoinFlip](https://docs.nvidia.com/deeplearning/sdk/dali-developer-guide/docs/supported_ops.html#nvidia.dali.ops.CoinFlip),将创建一个包含 1 和 0 的列表,其长度也与批量大小相同。这些出现在随机指数中,总频率为 7.5%。将该列表传递给旋转变换将确保一批中的任何图像都有 7.5%的机会被旋转:

self.rotate = ops.Rotate(device=’gpu’, interp_type=types.INTERP_NN) self.rotate_range = ops.Uniform(range = (-7, 7))
self.rotate_coin = ops.CoinFlip(probability=0.075)

第二步

define_graph()方法中,我实际调用了ops.Uniformops.CoinFlip随机数生成器来为每批创建新的随机数集合:

angle_range = self.rotate_range()
prob_rotate = self.rotate_coin()

仍然在define_graph()中,我在准备执行图像旋转的管道点调用ops.Rotate,将上面两个随机数列表分别传递给它的anglemask属性:

images = self.rotate(images, angle=angle_range, mask=prob_rotate)

DALI 现在将每个训练批次中大约 7.5%的图像旋转-7 到 7 度之间的角度。所有图像旋转同时并行发生!

以下是我的培训和认证管道课程的完整内容:

DALI Imagenette Train & Val Pipelines

构建 DALI 数据加载器

一旦编写了训练和验证管道类,剩下要做的就是创建它们各自的数据加载器(DALI 称之为“迭代器”)。构建一个与 PyTorch 一起工作的数据加载器只需要三行代码:

pipe = ImagenetteTrainPipeline()
pipe.build()
train_dl = DALIClassificationIterator(pipe, pipe.epoch_size('r'), stop_at_epoch=True)

大理速度测试

DALI 管道对象有一个run()函数,它抓取一批图像,通过管道发送,并返回转换后的图像及其标签。计时这个功能是衡量 DALI 速度最简单的方法。

As far as speed goes, DALI can fly.

我在一个 AWS p2.xlarge 计算实例上运行了我的速度测试,使用了一个 GPU,小批量 64 张图像。我发现我的 Imagenette 训练管道(包含 12 个图像操作)的运行时间只有 40 毫秒多一点!对于流水线中的所有 12 个操作,这相当于每个图像 625 秒。相比之下,在 fast.ai 课程的图像增强课程中,我们看到使用 Pillow 进行图像转换的主要瓶颈是 Pillow 加载单个图像需要 5 ms。

我们还使用 PyTorch JIT 来实现一种图像旋转算法,类似于 DALI,在 GPU 上转换批处理。每批大约运行 4.3 毫秒。假设任何转换的 JIT 实现都需要相同的持续时间(可能是一段时间),快速的粗略计算表明 JIT 性能可能类似于 DALI (4.3 x 12 = 51.6 ms)。DALI 的美妙之处在于,虽然它花了12 行代码来定义执行 JIT 旋转转换的脚本,但是 DALI 只通过一个函数调用就给了我们相同的功能和速度!

DALI + fastai v2.0

对于参加 2019 fast.ai 深度学习第二部分课程的人来说,这里有三个技巧可以让 DALI 的数据加载器与新改进的[Learner()](https://nbviewer.jupyter.org/github/jamesdellinger/fastai_deep_learning_course_part2_v3/blob/master/09_optimizers_my_reimplementation.ipynb?flush_cache=true#Getting-rid-of-the-Runner-class)对象无缝对接。

招数 1

修改Learner类,使其正确地索引到 DALI 数据加载器返回的张量中。图像和标签分别包含在'data''labels'键下:

xb = to_float_tensor(batch[0]['data'])
yb = batch[0]['label'].squeeze().cuda().long()

此外,确保在每个时期后重置 DALI 训练和 val 数据加载器:

self.data.train_dl.reset()
self.data.valid_dl.reset()

招数 2

更改[AvgStats](https://nbviewer.jupyter.org/github/jamesdellinger/fastai_deep_learning_course_part2_v3/blob/master/04_callbacks_my_reimplementation.ipynb?flush_cache=true#AvgStats())类,使all_stats()方法返回self.tot_loss而不是self.tot_loss.item()

招数 3

设定变量[combine_scheds()](https://nbviewer.jupyter.org/github/jamesdellinger/fastai_deep_learning_course_part2_v3/blob/master/05_anneal_my_reimplementation.ipynb?flush_cache=true#combine_scheds())的最大值,超参数调度生成器在跟踪当前迭代相对于训练周期长度的位置时使用该变量:pos = min(1 — 1e-7, pos)

最初的意图是,在训练期间,该值将始终低于 1.0。然而,当使用 DALI 时,其在最终迭代的开始处的值有时会是 1.0 或稍大。这会导致 IndexError,因为调度程序被迫索引到一个实际上并不存在的调度阶段!

请随意查阅我的笔记本来查看包含这三个修改的训练循环的工作版本。

大理最明显的不足

我将用一些时间来总结 DALI 库,我认为这是它最显著的缺点:它的一些图像转换操作不能产生随机输出。我发现这尤其具有讽刺意味,因为 DALI 网站用了一整节来宣扬图像增强的好处,即能够随机干扰输入图像,声明:

“将每张图像旋转 10 度并不那么有趣。为了进行有意义的增强,我们希望操作员在给定范围内以随机角度旋转我们的图像。”

如果是这样的话,我想达利的扭曲仿射图像变换应该被视为“没什么意思”,因为它实际上无法生成随机的图像扭曲。更令人沮丧的是,尽管我为编写了自己的逻辑,它根据 DALI 的 warp affine 操作的matrix参数所期望的约定生成随机仿射变换,但我绝对不可能让我的 DALI 管道在运行时为小批量的图像执行这个逻辑。

不出所料,有人请求支持随机化 warp affine,但 DALI 团队成员解释说warp affine 目前不是优先考虑的,因为团队专注于“提供最常见网络中使用的操作符。”现在,作为一个前世是软件产品经理的人,我当然赞同优先考虑功能的想法。然而,看着 DALI 团队毫不犹豫地大声宣扬随机图像旋转的好处,我很难理解随机的 warp affinites为什么不能优先。

尽管如此,一个可取之处是 DALI 团队成员确实鼓励开源贡献来弥补这个特性的不足。这是一件好事,也许很快有一天我会尝试移植我的随机仿射变换逻辑并提交一个 pull 请求。

“合成随机”扭曲仿射变换

我最终不满足于从我的增强管道中省略透视扭曲,也不同意对任何批次的任何图像应用相同的单一、单独的扭曲仿射变换。在尝试执行将由 DALI 的[ops.WarpAffine](https://docs.nvidia.com/deeplearning/sdk/dali-developer-guide/docs/supported_ops.html#nvidia.dali.ops.WarpAffine)操作执行的仿射变换随机化的逻辑失败后,我决定尝试一种突然出现在我脑海中的公认的非常规变通方法。我把这称为“合成随机”扭曲仿射变换。它是这样工作的:

  1. 编写一个函数,它可以生成随机仿射变换并传递给ops.WarpAffine。我的算法确保随机生成的仿射变换将倾斜图像的视角,但不会不自然地挤压或拉伸图像的内容。
  2. 在我的管道中添加两到二十个 DALI ops.WarpAffine操作。(我做了一些实验来确定合适的量,发现七种效果最好。)
  3. 为我包含在管道中的每个ops.WarpAffine操作生成一个唯一的仿射变换。
  4. 以介于 0.3 和 0.025 之间的概率将管道的每个扭曲仿射变换应用于特定图像。(我发现 0.025 效果最好。)

我的直觉是,通过适当选择扭曲仿射操作的数量,*衡每个操作将被应用的适当概率,我可以同时:

  • 最大化应用于小批量图像的透视扭曲变换的种类
  • 充分减少单个图像在每个小批量中应用两个或更多扭曲变换的机会。

通过在我的笔记本中记录的一系列实验,我发现包括七个连续的翘曲仿射变换,每个都有 0.025 的概率应用于一批中的任何图像,在十次运行中导致*均验证准确性的最大增加。该机制的性能超过了不包含任何扭曲仿射变换的基线。我的“合成随机”扭曲仿射也胜过了只包含一个扭曲变换的管道,它以完全相同的方式倾斜每批中的任何图像,这似乎是 DALI 目前期望从业者如何使用这种操作。

所有这一切中的一个亮点是 DALI 的速度:在我的流水线中额外添加两个或二十个 warp affine 操作并没有明显延长处理每个小批量的时间。

请注意,我写我的“合成随机”扭曲变形并不是为了让其他从业者尝试类似的方法。相反,我希望表达的是,无论我的解决方法在多大程度上看起来是非常规的,DALI 的扭曲变换不支持随机化的事实也是非常规的。

三个较小的诡辩

  1. 潜在的 DALI 用户已经习惯了 PyTorch 的动态特性,应该期待一个绝对静态tensor flow 1.0 版般的体验。当 DALI 团队将管道类命名为“核心方法定义图时,他们并没有开玩笑,所以不要期望能够在其中运行任何自定义算法,正如我在尝试给ops.WarpAffine添加随机性时所尝试的那样。目前推荐的方法是创建并编译一个定制的 C++操作符。这并没有让我觉得非常“灵活”,希望 DALI 将扩展其增强选项的广度,这将消除从业者创建定制操作的需要。
  2. 说到这里,DALI 缺乏对反射填充的支持。我的假设是,这是在我将旋转角度的范围从[-30,30]度缩减到[-7,7]度之前,在我的管道中添加旋转变换并没有提高模型性能的一个重要原因。虽然 DALI 确实允许从业者指定用于填充旋转后图像角落中发现的空像素的单一颜色,但我怀疑使用全绿或全白填充而不是全黑默认填充是否会对我的模型的性能产生有意义的改善。
  3. 我本打算居中裁剪,然后调整验证集图像的大小。虽然 DALI 的[ops.Crop](https://docs.nvidia.com/deeplearning/sdk/dali-developer-guide/docs/supported_ops.html#nvidia.dali.ops.Crop)操作允许我们相对于输入图像的宽度和高度设置裁剪窗口左上角的坐标,但是似乎没有任何方法可以使裁剪窗口的宽度和高度也相对于每个输入图像的宽度和高度缩放。

最后

DALI 提供了一个简洁的 Python API,可以很好地与 PyTorch、TensorFlow 一起使用,并且只需三次调整,也可以顺利地与我们将在 fastai 库的 2.0 版本中看到的训练循环一起工作。通过使用 GPU 优化的代码并行运行图像增强,DALI 不仅实现了它的速度承诺,还消除了编写几行 JIT 脚本的需要,这是我知道的如何在 GPU 上批量运行图像增强的唯一方法。不幸的是,并不是所有的 DALI 图像变换都支持随机化,具有讽刺意味的是,即使 DALI 团队也承认是一个必须具备的特性。虽然 DALI 声称是灵活的,但我试图在 DALI 的 warp affine 操作中建立随机性,结果表明这种灵活性只扩展到那些愿意并能够子类化和编译 C++类的人。在 2019 年,我不确定任何需要使用 C++的东西是否仍然可以被称为“灵活的”。

即便如此,虽然 DALI 的功能集较窄,可能会使我的模型的最终版本更难到达 SOTA 或登上 Kaggle 排行榜,但我仍然计划在我的模型原型制作过程的早期阶段使用 DALI 库。它的 Python API 很容易使用,DALI 运行速度非常快。毕竟我们说的是在 GPU 上批量扩充图像,这里!我希望图书馆能继续填补空白,不断进步。

参考

  1. 请随意查看笔记本,我在那里试验了本文中讨论的管道。
  2. DALI 的 GitHub 页面上的 PyTorch ImageNet 培训示例由 Janusz Lisiecki 、 Joaquin Anton 和 Cliff Woolley 创建,它是帮助我了解如何从头开始编写自己的培训和验证管道类的不可或缺的模板。

投身谷歌里程碑式的识别卡格尔竞赛

原文:https://towardsdatascience.com/diving-into-googles-landmark-recognition-kaggle-competition-6975dbe11072?source=collection_archive---------16-----------------------

最*的谷歌地标识别比赛严重影响了我与互联网服务提供商、我的 GPU 的关系,也让我失去了一点耐心。

以下是 Kaggle 比赛说明:

今天,地标识别研究的一个巨大障碍是缺乏大型标注数据集。在这次比赛中,我们展示了迄今为止最大的全球数据集,以促进这一问题的进展。这项比赛要求 Kagglers 建立模型,在具有挑战性的测试图像数据集中识别正确的地标(如果有的话)。

不管怎样,我很兴奋我得到了我的第一枚卡格尔奖章!

庞大的数据集

当我第一次报名参加比赛时,我没有意识到这个数据集有多么庞大。对于 400 多万张图像,仅训练集就有大约 500 多千兆字节!

您的 ISP 有数据上限限制吗?我的的确如此。我意识到这一点,因为我收到了一系列电子邮件,说我离 1,024 的上限只有 10g 了。突然,楼下的电视“坏了”,不能播放我 3 岁孩子最喜欢的节目,我在家的工作变成了在咖啡店的工作。我不想支付超龄费。

在下载这个数据集时,我使用了我家人正常月数据使用量的三倍。太不可思议了。我还觉得庞大的数据集阻碍了其他人获得解决这个挑战的好机会。

使用 Magik 压缩图像和数据集

所以让我们来解决尺寸问题。数据集中的大多数图片都很大(因此有 500 多张),我们不需要它们来参加比赛。因此,我们使用了 ImageMagick 的一个小 mogrify 来快速地将图像调整到 256x256。

find /home/user/data/google2019/ -name ‘*.jpg’ -execdir mogrify -resize 256x256! {} \;

这一步有效地将 500+千兆字节的训练集减少到大约 50 千兆字节。更有用。更重要的是,我已经知道,当训练这么大的数据集时,时间将是一个问题。通过预先调整硬盘上的映像大小,我们无需在训练期间多次重新计算。

以防万一,我保留了原始文件,如果我以后需要不同的大小。

检查文件是否为空

另一个不幸的发现是几个缺少数据的文件被破坏。不完整的记录可能会导致模型在整个训练过程中失败(这可能需要长达 9 个小时)。最好先检查一下。

import os
filenames=os.listdir("/home/user/data/google/")# Are there any empty files?
for filex in tqdm(filenames):
    try:
        filex=directory+"/"+filex
        if (os.stat(filex).st_size == 0): #0 means bad file
            print(filex)
    except:
        print (filex)

任何失败的文件我都用相同类型的地标图片替换。

最常见的地标

有了这么多的文件,另一个大问题就是地标类的数量。最常见的“id 138982”有超过 10,000 个实例,而一些地标只有 1 个。

我们这里有 203,094 个不同的班级,我们真的应该考虑减少这个数字。

维度很难

如果你看看其他 CNN 数据集,你有一些简单的像 Mnist (10 个类)和更复杂的像 ImageNet(1000 个类)。所以一个有 20 万个类别的数据集是很疯狂的。

所以让我们把它变得简单一些,只让它像 ImageNet 一样难。我们选取了 1000 个最常见的类,仅使用了数据集的 11.1%。

不出所料,它训练得很快,ResNet34 的准确率高达 50%左右。通过大量的实验,我得到了类似这样的东西。(我喜欢老派的钢笔和墨水)

Resnet34 experiments for test 1

我当然有差距分数的问题,但我认为大多数人并没有被它超越。实现我的差距分数迭代与公共 Kaggle 分数不完全匹配。然而,这确实表明我走在正确的道路上。较大样本量的班级(前 100 名、前 1000 名、前 2000 名等。),更高的准确性和更高的验证差距分数导致更高的 Kaggle 分数。

然而,随着数据集的增长,我们也遇到了训练时间和预测准确性较低的问题。

失望转向第二阶段测试

我在比赛中表现非常好,第一阶段的公开分数让我进入了前 30 名。我对此非常兴奋,因为我觉得我的训练越来越好了。我的分类和准确性迅速提高。

然而,我的训练很快就遇到了 20,000 个类别的问题。我只有大约 30%的 7000 个不同的类别(我甚至无法预测所有的新类别)。

虽然我在那一点上尝试了几种不同的解决方案,但我被姐妹竞争(谷歌地标检索 2019 )分散了太多注意力,无法回去修复错误。

有待改进的领域

数据清理和地标与非地标

当查看所有训练数据时,我注意到 landmark 138982 是最常见的一个,并决定进行调查。当我们浏览这堂课的 200 张图片时,没有任何标志。例如,见下文。

我们有实验室内部,教室,风景,树前的人,没有任何看起来像地标的东西。有些是彩色的,有些是黑白的(这些图像看起来有一点绿色,只是为了这个功能),还有不少在底部有一个小标签。原来它们来自苏黎世联邦理工学院的图书馆,我仍然不知道为什么它们被认为是地标。

毕竟,国会图书馆里的照片会是国会图书馆吗?

这说不通。

我被傲慢所征服,忽略了包括一个非地标或者关于地标是否存在的数据清理。事后看来,这是一个巨大的错误,检测地标和非地标有许多解决方案。

竞争者讨论地标 vs 非地标:
第 2 名 —不讨论,只放外部数据
第 8 名
第 27 名

寻找最*的邻居

看到最接*测试图像的图像也是非常重要的。我使用 nmslib 来帮助解决这个问题。

根据我的 Resnet50 训练,nmslib 将比较 1 个测试的 softmax 预测与在我的验证集上做出的预测。那么它将找到 K 个最接*该测试图像的验证图像。请看我下面的解释。

如果是 ImageNet,那么狗的图像对狗的预测会更高就说得通了。如果验证集中的 K 个最*邻居是狗,则测试图像很可能是狗。

同样,如果它是一个图像类别 12345,它应该在其 12345 ish 中排名非常高。如果五个最接*的验证图像是 12345,它可能是。

现在,我在这里的错误是使用 softmax,并试图使用成千上万的变量,而不是使用最后的 512 个功能。试图拥有 20 万个类别会消耗大量内存。我崩溃的时候高达 62G。

通过一些疯狂的天文计算,我在最后的提交中放弃了它,去参加另一场比赛。

还有几个问题

此外,因为有一些分散注意力的图像。KNN 会对整个主题进行错误分类。例如,这张图片:

正如你可以看到上面的图片突出的特点,人们正在为摄影师摆好姿势,它匹配最接*下面的照片。

这些比较关注的是人,而不是地标。即便如此,它也无法分辨它们是现代照片还是老照片。我认为如果有更好的架构和更多的类别,我就不会有这个问题了。

KNN 的最佳用途在以下方案中:
第 1 名
第 8 名 第 15 名
第 20 名 第 27 名

更好的架构 为什么是 Resnet50?我在用 ResNeXt 架构保存时遇到了问题,开始 DenseNet 太晚了,而 EfficientNet 功能正在构建中。下一次,我将从 ResNet34 转到 ResNeXt 或新的 EfficientNet 。

我也尝试慢慢增加训练类别的数量。先做 1000,再做 2000,再做 3000,以此类推。这种想法是,学习更少的类别会更快,然后在更广的范围内学习会更准确。比如在学习另一种语言时添加额外的抽认卡。

然而,我在训练和准确性方面没有明显的帮助,我放弃了它。也许台阶太大了,我应该有小一点的。

结论

  • 大型数据集很难。有趣但很难。
  • KNN 是极其宝贵的,但不会打破你的电脑
  • 爱多 GPU 处理
  • 快速转移到更大的数据集

再次感谢 Fast.ai ,它教会了我如何走到这一步!

参考资料:

我的 Github 代码
GAP for py torch/fast . ai
Kaggle 竞赛
NMS lib efficient net

用 Qwiklabs 潜入 AI 兔子洞

原文:https://towardsdatascience.com/diving-into-the-ai-rabbit-hole-with-qwiklabs-b8025755b00b?source=collection_archive---------27-----------------------

Photo by Valentin Lacoste on Unsplash

我花了很多时间来跟上最新的人工智能发展,并认为我在该领域的知识高于*均水*。尽管如此,我还是觉得我需要把手弄脏。这个故事是关于我进入人工智能社区和在线人工智能培训世界的第一步。

免责声明:

我认为可以肯定地说,这篇文章的目标读者是 it 专业人士。重点是如何使用谷歌 Qwiklabs 开发新的人工智能技能。如果你不是 IT 专业人士,请等我的下一篇文章。我会考虑到普通大众来写它。

我第一次听说“人工神经网络”是在 90 年代中期。我和一位同事甚至成功地编写了一个神经网络程序,并用反向传播法训练它识别字母 A 到 D。我们花了一个晚上的时间,我猜大约 6 个小时,看看这是否可能——确实可能。

一切都是非凡的。值得注意的是,我们花了很少的努力就开发出了一个神经网络,它可以做一些我们用传统的基于规则的解决方案做不到的事情。值得注意的是,我们和世界上的其他人就这样离开了它,忘记了它。于是,在 AI 寒冬的时候,我冬眠了对 AI 的热情。

现在,随着 AI 的回归和热,我想加入,那么该怎么办?

寻找志同道合的人

我的第一步是开始寻找志同道合的人。一个人的军队不是一支军队,在开辟新天地的时候,人类交流的价值是显著的。通过 Meetup 应用程序,我开始搜索我所在地区的人工智能社区。我决定参加苏黎世的“苏黎世 AI 学校”小组。它是由 Siraj Raval 创立的全球AI(SOAI)学校的一部分。一个快速发展的非营利组织,有一个雄心勃勃的使命,为地球上的任何人免费提供世界级的人工智能教育。艾和西拉杰·拉瓦尔的故事自成一篇。我建议你看看主页和 YouTube——它很有趣,信息丰富,充满活力。

我的第一次谷歌云学习堵塞

加入 SOAI 聚会小组后的第一件事是“谷歌云学习堵塞”。一个实践研讨会,向我们介绍 Qwiklabs *台和谷歌云*台 ML 服务。会场在苏黎世的谷歌旁边,我们被告知要带上笔记本电脑。 Nicolas Bortolotti 代表谷歌,SOAI 苏黎士学院院长 Mark Heinz 安排了这次活动。

研讨会的基础是 Qwiklabs *台上的一个名为“云 ML 引擎:Qwik start”的实验室,而且很快。马克和尼古拉斯给我们做了一个简短的介绍,当参与者在练习中陷入困境时,他们也会提供帮助。收到证书和连接细节后,很快每个人都在安装 TensorFlow,复制样本数据,并训练神经网络。目标是基于从 UCI 机器学习库检索的数据预测美国公民的收入。

实验室涉及到大量的复制粘贴,我不是唯一一个感觉实验室的个人利益有限的人。你将会发现,我以后会完全改变这种看法。然而,首先,关于 Qwiklabs *台的一些信息。

Qwiklabs *台

Qwiklabs 成立于 2012 年,旨在为云提供商提供机会,让他们的客户建立动手实验室,快速体验云环境。2016 年 11 月,Qwiklabs 被谷歌收购,他们现在在其谷歌云培训目录中提供广泛的实验室、课程和认证。

在收购之前,亚马逊 AWS 是 Qwiklabs 最大的客户之一,现在仍然是。因此,可以在同一个*台上同时学习谷歌云和 AWS 课程。在我眼里,令人钦佩的支持多云教育。

谷歌云培训包括

  • 动手实验
  • 探索
  • 课程

每个任务通常由 5 到 10 个实验室组成。完成所有实验后,您将获得一枚任务徽章,如果您愿意,可以将其添加到您的简历或 LinkedIn 个人资料中。

实验通常安排大约 1 小时。在按下“开始实验”按钮之前,您可以自由通读整个实验。一旦你按下开始按钮,就不能返回,因为你不能暂停它。显然,建议先学习实验室。我的经验是

+

如果你完全按照实验说明去做,你可以做得更快。如果你开始改变参数并研究正在发生的事情,你可以在实验室花更多的时间——这是我个人的建议。

我获得第一枚徽章的方法

我是一个狂热的人工智能爱好者,尼古拉斯和马克告诉我,实验室不仅仅是复制粘贴。于是我带着一个月的免费 Qwiklab 学分从云学 Jam 工坊回家,内心充满了做实验室的意向。

我决定报名参加任务“基线:数据,ML,AI”。因为这是入门水*,而我已经在车间里做了第一个实验室。

在前两个实验中,我的感觉和在研讨会上一样——只是复制粘贴。然后在第三个实验室,发生了一些事情。我知道我在做什么!我已经熟悉了谷歌云*台(GCP)、谷歌云外壳和云存储桶。

你不会因为做了一个实验就成为谷歌云数据准备的专家。你可以看到一个小例子,看看它能做什么,仅此而已——是吗?不会,因为所有实验都包含基本功能,如创建存储桶、创建数据集、操作数据集、创建表格、将数据导入表格等。

经过一些实验,你的生物神经网络已经适应了所有这些功能,它们不再对你构成问题。换句话说,你开始了解谷歌云*台以及如何使用它。

我在两周内完成了第一个任务,只是每隔一天做一次实验。

我的第二个徽章:机器学习 API

自信满满,在一次探索中获得成功并获得我的第一枚徽章后,我选择接受另一个挑战,这一次是在高级水*上,这一次更关注人工智能:“机器学习 API”。

实验涵盖了以下 API:

  • 云视觉 API
  • 翻译 API
  • 自然语言 API
  • 云自动编程接口
  • Dialogflow API

这些实验室令人兴奋。我仍然没有创造出自己的解决方案,也没有解决我自己定义的问题。然而,我学会了如何创建一个 API 键,使用该键发出请求,从图片中提取文本,并使用自然语言服务来分析文本。

我用谷歌云存储中带标签的数据集的输入,用 Auto ML 训练了一个模型。之后,我从我的 iPhone 上传了云的照片,并让模型预测图像上的云的类型(积云、积雨云等)。).

我还用 Dialogflow 创建了一个聊天机器人,同样非常有趣,它让我很好地了解了 Dialogflow 能做什么和不能做什么。

九次实验两周后,我获得了第二枚徽章。

我的放弃

在谷歌云培训*台 Qwiklabs 上:

  1. 为预习和实验预留时间
    如果你愿意,可以一天做预习,第二天做实验。换句话说:在你服用之前了解实验室
  2. 记学习笔记
    我制作了一个 word 文档,主要用于在学习阶段以及做实验时记笔记。
  3. 不要在自动驾驶仪上做实验说明,这有时是可能的。还是那句话:拿之前了解实验室。
  4. 安排一个小时的实验,总共花两个小时(学习+实验)是可以的。下一个实验可能比预期的要快。重要的是你掌握了实验室的重点。
  5. 当进行一项任务时,我建议在开始第一个实验之前,先浏览一下所有的实验。这样做可以帮助你对整个材料有一个总体的了解。

关于潜入人工智能社区:

  1. 找志同道合的
    派的艾是个好建议;也许你能找到别的东西。如果你有,请让我知道。我想听听其他人的经历。
  2. 应用程序 Meetup 非常适合寻找其他人工智能爱好者。
  3. 出于以下几个原因,志同道合的社区至关重要:
  • 你可以和分享你兴趣的人互动
  • 人工智能社区通常与一个或多个兴趣相同的公司有某种联系。这种合作可能会导致社区成员在产品和教育方面的折扣,等等。

结论

Qwiklabs 在 Google 和 AWS *台上提供了广泛的任务和实验。他们的“ Advantage Subscription ”仅花费 55 美元,一个月的无限制信用,这将使你能够尽可能多地进行实验/任务。

正如你现在所知道的,我在 4 周内完成了两个任务(15 个实验)(不包括我的假期:-)。我发现这是一个有利的成本效益,正如已经提到的;也许你很幸运,通过你的人工智能社区获得一些免费积分。

Qwiklabs 并不是在线课程和动手实验的唯一提供商。Coursera 也在提供关于人工智能主题的各种课程,这些课程来自斯坦福大学和约翰霍普金斯大学。

我要说的是。你不必等待你的公司给你下一个 3000 到 20000 美元的人工智能教育。你现在就可以开始,每月不到 100 美元,就可以获得高质量和有用的培训。如果你对人工智能感兴趣,现在就开始动手吧。甚至可能会很有趣。

兔子洞的另一边见。

Photo by Micaela Parente on Unsplash

从头开始在 Excel 中进行简单的指数*滑

原文:https://towardsdatascience.com/diy-simple-exponential-smoothing-with-excel-df4b8728e19e?source=collection_archive---------31-----------------------

下面这篇文章摘自我的《供应链预测的数据科学》一书,这里有。你可以在这里* 找到我的其他出版物 。我也活跃在LinkedIn*。

这篇文章是另一篇关于简单指数*滑理论介绍的文章的后续。你可以在这里找到**。你可以在这里 找到关于如何用 python 制作相同模型的类似文章。**

自己动手——用 Excel 进行简单的指数*滑

在本文中,您将在 excel 中实现一个简单的指数*滑预测模型。

1.我们从创建三列开始数据表:

  • 栏 A 上的日期
  • 栏 B** 的需求**
  • 栏 C** 的预测**

2.接下来,让我们添加一个带有 alpha 的单元格(在我们的例子中是 F1 )。别忘了明确指出这个单元格是 alpha。

3.完成后,您可以将第一个预测(单元格 C2 )初始化为第一个需求(单元格 B2 )。我们在这里使用了虚拟值。

4.我们现在可以填充我们的预测;截至单元格 C3 ,我们可以使用这个公式:

5.要继续我们的预测,直到历史时期结束,我们可以简单地拖动这个公式,直到表的末尾。

6.所有未来预测(即,历史期间之外的预测)将简单地等同于基于历史需求的最后一次预测(如下所示)。

已经这样了。你可以在我的博客这里或者我的书这里找到更高级的型号。

也可以在 python 中实现简单的指数*滑( 此处 )。

关于作者

** [## Nicolas vande put——顾问,创始人——供应链| LinkedIn

查看 Nicolas Vandeput 在世界上最大的职业社区 LinkedIn 上的个人资料。尼古拉斯有 7 份工作列在…

www.linkedin.com](https://www.linkedin.com/in/vandeputnicolas/)

icolas Vandeput 是一名供应链数据科学家,擅长需求预测和库存优化。他在 2016 年创立了自己的咨询公司 SupChains ,并在 2018 年共同创立了 SKU 科学——一个快速、简单、实惠的需求预测*台。尼古拉斯对教育充满热情,他既是一个狂热的学习者,也喜欢在大学教学:自 2014 年以来,他一直在比利时布鲁塞尔为硕士学生教授预测和库存优化。自 2020 年以来,他还在法国巴黎的 CentraleSupelec 教授这两个科目。他于 2018 年出版了 供应链预测的数据科学(2021 年第 2 版)和 2020 年出版了 库存优化:模型与模拟

**

Python 中的简单指数*滑从头开始

原文:https://towardsdatascience.com/diy-simple-exponential-smoothing-with-python-dbb570d30fb5?source=collection_archive---------20-----------------------

下面这篇文章摘自我的《供应链预测的数据科学》一书,这里有。你可以在这里* 找到我的其他出版物 。我也活跃在LinkedIn*。

这篇文章是另一篇关于简单指数*滑理论介绍的文章的后续。你可以在这里找到**。你可以在这里 找到关于如何用 Python 制作相同模型的类似文章。**

自己动手——用 Python 实现简单的指数*滑

简单*滑函数

我们将定义一个函数 simple_exp_smooth ,它将一个时间序列 d 作为输入,并返回一个 pandas DataFrame df ,其中包含历史需求、预测和误差。该函数还将 extra_periods 作为输入,即需要预测未来的周期数。最后一个输入是 alpha 参数。

**def simple_exp_smooth(d,extra_periods=1,alpha=0.4):  
  d = np.array(d)  # Transform the input into a numpy array    cols = len(d)  # Historical period length    d = np.append(d,[np.nan]*extra_periods)  # Append np.nan into the demand array to cover future periods    f = np.full(cols+extra_periods,np.nan)  # Forecast array    f[1] = d[0]  # initialization of first forecast    # Create all the t+1 forecasts until end of historical period    for t in range(2,cols+1):      f[t] = alpha*d[t-1]+(1-alpha)*f[t-1]  
  f[cols+1:] = f[t]  # Forecast for all extra periods  
  df = pd.DataFrame.from_dict({"Demand":d,"Forecast":f,"Error":d-f})**

玩弄我们的功能

然后,我们可以简单地调用我们的函数(这里有一个虚拟需求时间序列):

**import numpy as np 
import pandas as pdd=[28,19,18,13,19,16,19,18,13,16,16,11,18,15,13,15,13,11,13,10,12]df = simple_exp_smooth(d,extra_periods=4)**

您还可以使用简单的命令快速获得预测准确性,如下所示。看我之前的文章关于 KPI 看看哪个最适合你的情况。

**MAE = df["Error"].abs().mean() print("MAE:",round(MAE,2)) RMSE = np.sqrt((df["Error"]**2).mean())print("RMSE:",round(RMSE,2))**

您应该会得到以下结果:

**MAE: 2.74RMSE: 3.89**

另一个令人兴奋的步骤是绘制结果来分析模型的行为。

**df.index.name = "Periods"df[["Demand","Forecast"]].plot(figsize=(8,3),title="Simple Smoothing",ylim=(0,30),style=["-","--"])**

你应该得到一个类似下图的数字。

关于作者

** [## Nicolas vande put——顾问,创始人——供应链| LinkedIn

查看 Nicolas Vandeput 在世界上最大的职业社区 LinkedIn 上的个人资料。尼古拉斯有 7 份工作列在…

www.linkedin.com](https://www.linkedin.com/in/vandeputnicolas/)

icolas Vandeput 是一名供应链数据科学家,擅长需求预测和库存优化。他在 2016 年创立了自己的咨询公司 SupChains ,并在 2018 年共同创立了 SKU 科学——一个快速、简单、实惠的需求预测*台。尼古拉斯对教育充满热情,他既是一个狂热的学习者,也喜欢在大学教学:自 2014 年以来,他一直在比利时布鲁塞尔为硕士学生教授预测和库存优化。自 2020 年以来,他还在法国巴黎的 CentraleSupelec 教授这两个科目。他于 2018 年出版了 供应链预测的数据科学(2021 年第 2 版)和 2020 年出版了 库存优化:模型与模拟

**

姜戈还是弗拉斯克?根据我的经验推荐。

原文:https://towardsdatascience.com/django-or-flask-recommendation-from-my-experience-60257b6b7ca6?source=collection_archive---------11-----------------------

以我的经验来看,用 Python 驱动数据应用的一个常见问题是不知道用什么工具做什么工作。我认为不用说,在工作中使用正确的工具是我们所做工作的很大一部分。当你可以从任何地方开始时,很难知道从哪里开始。但是,我一遍又一遍的看到这个问题:“我应该学烧瓶还是 Django?“简短的回答是

两者

但为什么我会建议两者都了解呢?Flask 和 Django 只是 Python 的 web APIs,对吧?Flask 有什么优势,用 Django 代替有什么优势?事实是,在很多方面,它们经常被用于非常不同的目的。虽然他们肯定会时不时地越线。

姜戈

我们都听说过地球上一些最大的网站使用 Django 的疯狂故事。这是有充分理由的,因为 Django 不仅受人尊敬,而且使用起来也非常方便。Django 的优势在于它要实现的目标。Django 非常适合用 Python 构建完整的 web 应用程序。虽然你当然可以用 Django 做一些底层的事情,但我认为对很多人来说,Django 的闪光点在于快速开发和 Django 的授权/许可系统,它被嵌入到包中。

Django 不仅使项目管理变得容易,还意味着启动变得更加容易。您的应用程序将需要的许多东西都被嵌入到您的 Django start-project 命令中。

Flask 绝对是数据迷和数据科学家的热门选择。烧瓶是两者中较轻的一个。Flask 经常对网站的大部分内容采取“从头构建”的方式。虽然这使得全面的网络应用程序开发起来有点困难,但它也带来了 Flask 的强大功能,以及两者之间的一个非常大的区别。

烧瓶很轻。这使得 Flask 成为端点定位、查询和流水线的最佳选择。许多数据科学专注于构建复杂的算法和 ROC/AUC,但数据科学最受欢迎和最被忽视的一面是 数据流

对于数据科学家来说,能够读取、操作和查询数据是非常有价值的。Flask 使 http 请求的转储变得非常容易,有效地构建了供您整个时间使用的端点。

在我看来,虽然 Flask 肯定可以做 Django 能做的几乎所有事情,但 Flask 在这个特定的用途上仍然更好,Django 比另一个更好。

那么…为什么两者都有?

在我们的数据科学之旅中,终端和数据基础设施可能比您想象的更有价值。尽管 ML 中确实有令人兴奋的新进展,但首先需要基础设施来获得这样的模型。

就我个人而言,我喜欢在需要的时候使用所有我能使用的工具。我喜欢在 Flask 开发,就像我喜欢在 Django 开发一样。如果我需要响应一个 http 查询,我会直接进入基于 Flask 的应用程序。如果我要建立下一个脸书,或者一个论坛网站,我肯定会使用 Django。

如果你必须选择一个:

如果你完全不反对使用两者,或者如果你想知道从哪里开始,答案肯定是 Flask。虽然 Django 是构建一些非常酷的应用程序的一个很棒的包,但我发现我经常使用 Flask。

对于典型的 DS 相关工作,我认为 Flask 做得非常出色。Flask 很有用,因为它更容易启动和运行,没有 Django 会向您左右扔来的所有令人困惑的“扩展”。并不是说这些都是负面的,但是编辑 Django 保存的文件路径来稍微改变你的项目对于初学者来说肯定是令人畏惧的。Flask 使你的函数路由和创建结果变得容易,没有麻烦。

尽管你肯定可以选择 Flask 或 Django 中的任何一个,并在创造中获得成功——嗯,很多事情,但他们肯定都有自己的优点和缺点。两者都是绝对强大的,让它们互相对抗是没有意义的。Flask 和 Django 拥有无与伦比的力量,可以将我们的数学和算法带到任何地方。

DMAIC 数据科学奖

原文:https://towardsdatascience.com/dmaic-for-data-science-65b84f714886?source=collection_archive---------20-----------------------

如何构建您的数据科学项目来创造商业价值

View from Quandary Peak Summit

数据科学家的工作是分析数据以提取可操作的见解。

分析数据可能很容易,但是可操作的见解呢?虽然我们可以制作漂亮的图表和图形,这真的很酷,但我们如何才能真正证明它们提供了商业价值呢?

为了取得成功,我们必须学会将数据科学任务构建为一个业务问题,并定义我们如何增加价值。

当我被邀请为一个潜在的数据项目提供咨询时,我真的开始思考这个问题。我对他们正在做的事情感到兴奋,但我不确定如何将真正酷的想法变成可操作的产品,交付给最终用户。

在研究如何创建有价值的数据产品时,我发现了 DMAIC。

DMAIC

我们可以使用数据驱动的问题解决方法 DMAIC 来思考我们如何使用数据来创造价值和改进流程。

DMAIC 是定义、测量、分析、改进和控制的首字母缩写。这是交付可持续和可量化成果的指导方针。

它是一个精确的数据科学发展过程吗?大概不会。但是我发现思考一下你什么时候想展示你的分析为什么有价值是很有帮助的。

规定

定义问题。

可以说,这是最重要的一步。如果我们能够在深入任何探索性分析、特性工程或建模之前预先定义问题,它将帮助我们看到真正的机会,并以有意义的方式将其框定。为了真正提供价值,从提高客户满意度的角度来考虑会有所帮助。

我们需要问自己一些重要的问题来为我们的项目建立最终目标和商业案例。这些问题对于确立焦点也很重要:我们需要能够创建一个可操作的产品并按时交付结果。

问题应包括:

  • 有什么问题?
  • 潜在的好处在哪里?
  • 我们想要影响哪些指标?
  • 我们计划如何影响这些指标?
  • 是我们不关心的指标。
  • 对一些指标产生负面影响可以吗?如果是,增加多少?

措施

测量当前基线。

这一步涉及到数据收集:从哪里获得数据以及我们需要多少数据是这里要考虑的要点。数据质量也很重要。

你将如何比较项目结束时和开始时的数据?

两个重点:缩短交付时间和提高质量。这里可能要问的问题包括:

  • 我们当前的流程表现如何?
  • 我们需要什么信息?
  • 我们将如何收集数据?
  • 哪些因素会影响我们的指标?

分析

分析数据。

最后是数据科学部分!在这一步中,我们可以调整正常的数据科学工作流程。

询问当前绩效与目标之间的差距。

  • 我们如何改进目前的产品?
  • 我们如何将数据可视化?

改善

改进项目并实施解决方案。

这是迭代步骤。我们如何改进当前流程来提高您的目标?我们如何更好地分析最后一步,以改进我们之前定义的指标?

在这一步中,我们还确定、测试和实施问题的解决方案。如果有明显的解决方法,就专注于它。不要过度复杂化!

控制

控制改进:让改变持续下去。

这是我们实施和监控产品的最后阶段。

记录您的流程。实施监控计划。

  • 我们如何监控成功?
  • 如果性能下降,我们该怎么办?

假设的例子

让我们通过一个假设的情况来看看我们如何使用 DMAIC 来确定我们作为数据科学家如何增加价值。

我们将基于过去的比赛场景: Kaggle 的 Quora 不真诚问题分类并假设我们在 Quora 作为数据科学团队工作。

作为一个快速后台,Quora 是一个问答网站。有时人们会不怀好意地提问:试图激怒或冒犯其他用户。这显然是不好的,所以我们需要过滤掉那些不真诚的问题,不要让它们被张贴出来。

让我们想象一个假设和基本的当前流程:有一个分析师团队,他们手动审查每个问题。如果他们决定一个问题是真诚的,它将被发布到网上,否则它将被标记为不真诚,并被排除在网站之外。

这个过程听起来非常耗费人力、时间和效率。作为数据科学团队,我们建议创建一个机器学习模型来改善当前的流程。

在思考我们假设的问题时:

从高层次来说,Quora 问题的问题在于,有些人会问一些被认为有毒的问题。有毒的问题令人心烦意乱,令人不快。它们可能会导致服务使用率下降和客户满意度降低。因此,我们需要一个系统来标记和消除这些问题。

当前手动标记的解决方案可以工作,但是效率不高。由于我们是数据科学家,我们想利用机器学习创建一个新系统。

因此,我们定义了我们的主要目标:使用机器学习来识别和标记不真诚的问题。

我们假设当前基线涉及问题的手动标记。虽然这非常耗时且低效,但却有效且准确。

我们建议的解决方案需要更快,但也要保持当前手动方法的准确性。我们需要一种方法来测量的准确度。比赛使用了 F1 的分数,所以我们也可以用它作为我们的主要指标。我们还可以测量分析师的工作时间,以监控效率的提高。

接下来的步骤是分析改进。在这里,我们将通过正常的数据科学流程来创建和改进一个模型,以过滤掉有害的问题。

最后,我们对我们的结果感到满意,因此我们实施了更改并进入了控制阶段。我们监控我们的解决方案并跟踪改进情况。

如果性能下降,我们可以计划回去重新分析新数据。所提问题的类型或措辞方式有变化吗?如果是这样,我们可能需要更新我们的模型。

结论

DMAIC 是增加我们数据科学工具箱的一个有用工具。

这对于从业务领导者和利益相关者关心的角度来构建数据科学问题,以及确保我们保持正轨并努力创建有用的数据产品非常有用。

DNA 搜索-与 argparse 的命令行接口

原文:https://towardsdatascience.com/dna-search-command-line-interfaces-with-argparse-8b11c0862495?source=collection_archive---------21-----------------------

寻找小 DNA 片段

National Cancer Institute via Unsplash

命令行与 argparse 接口

在生物信息学中,经常需要在命令行上运行我们的程序。幸运的是,Python 的 argparse 模块——标准库的一部分——使这变得很容易。

Python 有一系列有用的库,使得构建用户界面变得容易。通常,当我们想到用户界面时,脑海中浮现的是图形点击界面。然而,用户界面是允许用户与程序交互的任何东西,包括命令行界面——这是本文的重点。

为了介绍 argparse,我将构建一个小程序来搜索用户输入的特定小段 DNA。程序将搜索的这些小段 DNA 被称为限制酶位点,即长度在 4-6 个字符之间的小 Python 字符串。这个程序将搜索细菌的基因组,看看它们出现的频率!

入门

该计划有两个明确的目的:

  1. 向用户提供信息,例如当程序崩溃时提供有用的信息。
  2. 要灵活。该程序应该能够通过改变命令行参数来搜索用户选择的任何 DNA。

首先,导入 argparse 模块并创建 ArgumentParser 对象:

这不是必须的,但是我发现使用描述关键字参数提供一个描述性的字符串很有帮助。当程序稍后在命令行中调用帮助时,将提供 python 程序的描述性概述。如果有多个用户,并且程序运行之间有时间间隔,这可能是有用的。

接下来,我们通过调用 add_argument()方法来告诉参数解析器对象预期的参数。一旦添加了所有的参数,我们可以告诉它通过调用 parse_args()方法来解析命令行参数。

add_argument()方法添加了三个参数。此外,还增加了其他各种可选参数,如 help=,type=,choice=,default= ect

这就是 argparse 模块真正发挥作用的地方。

短参数和长参数分别用单连字符(-)或双连字符(—)指定。这意味着,在终端的命令行上,当程序运行时,参数可以用简写方式表示,输入文件名用-i 表示,或者用简写方式表示,输入文件名用 input _ filename 表示。长短参数的另一个好处是它们可以在命令行中以任何顺序表达!

混合匹配排列中的短参数和长参数如下所示。

我们可以通过使用 help 关键字参数调用 add_argument()来使帮助文本变得更好。当程序在没有命令行参数的情况下运行时,会出现三个参数的有用帮助文本(以黄色突出显示):

自定义验证

parser.add_argument 方法中的 type=参数接受 Python 函数的名称

类型参数引用一个函数,例如—输入文件名由名为 file_check 的函数检查。下面显示的这个函数检查文件是否确实存在。

最后,choice 和 nargs 参数意味着用户可以选择选择列表中的任何元素。因为用户可以选择多个参数,所以 nargs 参数是必需的,并且指定了一个星号。

最后,现在已经添加了所有参数和用于输入验证的函数,可以编写一个小脚本了。我先写一个小字典,里面的限制酶名称是键,限制酶识别的对应序列是它们的值。

为了完整起见,我在 restriciton _ enzyme _ dict 字典中包含了这个程序所需的模块。

用户指定的参数以 args 为前缀,后跟其输入名称。

首先打开 DNA 文件,并使用。read()方法。接下来,迭代用户指定的模式。模式代表一个限制酶,是上面字典中显示的关键字,例如 EcoRI 是字典中的关键字;restriction_enzyme_dict,它的值是‘GAATTC’,即它在任何 DNA 样本中识别的序列。

对于每种限制性内切酶,我用。get()方法。它的价值在于它在基因组中识别的序列。正则表达式 re.findall 查找 DNA 中所有出现的序列,并将这些序列附加到结果列表中。

使用集合将结果列表转换为特殊的字典。Counter 方法(),用于计算找到一个唯一序列的次数。

最后,这本由 collections 创建的新词典。可以迭代名为 restriction_sites_dict 的计数器,如果序列超过用户指定的计数,则打印一条消息,告诉用户它被找到了多少次及其序列。

要查看程序的运行情况,让我们运行几个测试示例!

输出示例如下所示:

在这里,我使用 p 标志(p 标志对应于用户指定的模式)搜索了三种限制性内切酶,-p HindIII、EcoRI 和 KpnI。在第一次运行时,我没有指定计数。之前,在 count_no 的 add_argument 中,我将一个有用的默认值设置为 0。

当我再次运行程序时,计数阈值为 500,程序通知我 HindIII 站点低于我指定的 500 阈值。

这个程序运行良好。结果很快返回,并且已经搜索了大肠杆菌的整个基因组内的限制酶位点!非常酷(这个 Fasta 文件是从 NCBI 获得的),但是在我们的命令行中,我们可以通过指定它们各自的文件名,轻松地选择搜索其他细菌基因组。

最后,阐述一下先前的意图将是有益的。具体来说,该计划被设计得非常灵活。如果用户添加了不正确的限制性内切酶,比如 FakeEnzyme,会发生什么?

让我们运行程序来找出答案。

我突出显示了有用的错误消息,如果用户输入了错误的选项,它会提示用户从提供的选择列表中进行选择。

摘要

这个简短的教程展示了如何将命令行界面添加到程序中。幸运的是,Python 提供了构建接口的有用库,argparse 就是其中之一。

使用 R 的 DnD 探索性分析

原文:https://towardsdatascience.com/dnd-exploratory-analysis-using-r-d13757b09768?source=collection_archive---------29-----------------------

使用 ggplot、tidyr、scatterplot3d 和 rgl 和 DnD,使用 R 进行数据探索和可视化的综合代码指南。

fig1: dnd classes gif using scatterplot3d

在今天的文章中,我们将一步步地了解使用 r 进行探索性数据分析的指南。我们将涵盖从 2D 到 3D 可视化,我们将通过使用来自 github 库的 DnD 数据来完成。为了便于数据可视化和操作,我对最初的数据集进行了一些数据缩减,从 768 个类和 182 个种族缩减为 13 个主要类和 16 个主要种族。

在进入分析的细节之前,这里有一个快速的介绍。

D&D 是一种掷骰子游戏,通常基于一套 7 个骰子(d4、d6、d8、d10、d12、d20 和另一个 d10)。骰子在游戏中起着重要的作用,它们都有不同的用途。例如,d20 通常用于攻击,而 d4,d6,d8,d10 或 d12 用于武器伤害,这取决于武器,性格和一些其他变量。但是当设置角色的分数时,也使用骰子。

根据定义,这使得我们将要分析的数据是随机和离散的,因为它是通过基于掷骰子的计算获得的,因此即使在这个数据样本中可能显示一些模式,这也不意味着这些模式会在其他样本中重复(部分原因是前面提到的随机性概念)。这是 DnD 最好和最有趣的特征之一。

每个 DnD 角色都有自己独特的方式,有不同的职业和种族供你选择,基本上玩家就是能最大限度或最少利用角色技能的人。玩家可以决定在预定义的角色之间进行选择,或者创建自己的角色。当创建一个新的角色时,选择职业和种族,掷骰子来定义不同的能力,并在需要时增加奖励或减少惩罚(视情况而定)。类似地,其他特征,如生命值(HP)、护甲等级(AC)和其他都是通过掷骰子和玩家手册中提到的奖励来定义的。

这里有一个文章不同部分的超链接,你可以直接跳到你感兴趣的部分。

目录

1。分布数值变量

1.1 数值变量直方图

1.2 相关图

1.3 装配

2.1 循环剧情类 vs 种族

2.2 箱线图类

3。三维散点图

1.分布数字变量

1.1 数值变量直方图

使用 dplyr 、 tidyr 和 ggplot2 ,我为数据集的所有数值变量创建了一个直方图。

这是一个非常好的组合,因为虽然 ggplot2 提供了一种强大的图形语言,但是 tidyverse 允许我们处理数据,而 dplyr 允许我们使用管道操作符% > %从左到右连接数据操作,而不是创建中间对象。

dnd %>%
  gather(attributes, value,2:9) %>%
  ggplot(aes(x = value)) +
  geom_histogram(aes(fill=attributes)) +
  facet_wrap(~attributes, scales = 'free_x') +
  labs(x="Values", y="Frequency", title="Distribution numeric variables")

fig2: histogram using using dplyr, tidyr and ggplot2

1.2 相关矩阵

在 wise 之后,我做了一个相关矩阵来衡量变量之间是否有任何程度的相关。这表明所有变量之间存在正相关关系,但这种关系的强度为 0.4,不能归类为显著。低于 0.6 意味着这种关系甚至不是中度积极的。

这是有意义的,因为 DnD 分数是通过掷骰子获得的,而掷骰子是独立的事件。如果两个随机变量 X 和 Y 是独立的,那么它们也是不相关的。然而,对于其他情况,重要的是要考虑到,如果 X 和 Y 是不相关的,它们仍然是相关的。

corrplot(abs(cor(dnd[,2:9])), method="color", col=colorRampPalette(c("red","white","blue")) (200), 
         type="upper", order="hclust", 
         addCoef.col = "black",
         tl.col="black", tl.srt=45, sig.level = 0.01, insig = "blank", diag=FALSE 
)

fig3: correlogram using corrplot

1.3 安装

即使在这种情况下,我们只是处理离散变量,对我来说,展示如何以一种快速而简单的方式识别数据集的分布似乎是一个好主意。

为此,选择了fitdistplus软件包。这个软件包中的 fitdistr 函数允许我们通过最大化似然函数来估计分布参数。

由于我们的统计数据是从掷骰子中获得的,因此它们符合中心极限定理,趋向于正态分布是有道理的。

fp <- fitdist(dnd$AC, "pois",discrete=TRUE)
fnb <- fitdist(dnd$AC, "nbinom",discrete=TRUE)
fg <- fitdist(dnd$AC, "geom",discrete=TRUE)
fn <- fitdist(dnd$AC, "norm",discrete=TRUE)

denscomp(list(fp,fnb,fg,fn),legendtext = c("Poisson", "negative binomial","geometric","normal"), fitlty = 1)
cdfcomp(list(fp,fnb,fg,fn),legendtext = c("Poisson", "negative binomial","geometric","normal"), fitlty = 1)

fig4: distributions fitting using fitdistrplus

2.阶级和种族

2.1 圆形地块类别与竞赛

对于这一次,我们将像以前一样继续使用 ggplot2 以及 tidyverse 和 dplyr,但我们将包括这个时间极坐标,以便我们可以将它制作成一个圆形条形图。对我来说,这是显示职业和种族之间信息的好方法。

dnd_bar <- dnd %>%
  select(name,predrace,predclass) %>%
  add_count(name) %>%
  group_by(predrace,predclass) %>%
  summarise(total = sum(n)) ggplot(dnd_bar, aes(x=predrace, y=total,fill=predclass)) + 
  geom_bar(stat="identity",position="dodge") +
  ggtitle("Database class and race distribution*")+
  labs(caption="Note:Predominant class and race")+
  ylim(-100,150) +
  theme_minimal() +
  theme(
    axis.text=element_text(size=8),
    legend.text=element_text(size=8),
    plot.caption = element_text(hjust = 0)
  ) +
  coord_polar(start = 0)

fig5: circular plot using using dplyr, tidyr and ggplot2

2.2 箱线图类别

箱线图很好地描述了分布的中心和扩散(可变性。)

通过使用相同的库,我们可以按单个变量绘制箱线图。

dnd %>%
  gather(attributes, value,2:9) %>%
  ggplot(aes(x=attributes, y=value)) + 
  geom_boxplot(aes(fill=attributes))+ facet_wrap( ~ attributes, scales="free")

fig5: Boxplot by variabledplyr, tidyr and ggplot2

然后,我们可以按组或主要类别复制主要变量的练习:AC、HP 和 Con。

ggplot(dnd, aes(y =HP, x = predclass, color = predclass)) + xlab("Predominant class") + ylab("HP") + ggtitle("Comparison HP Among Classes*") + geom_boxplot() + labs(caption="Note:Predominant class") + theme(axis.text.x = element_text(angle = 90),plot.caption = element_text(hjust = 0))ggplot(dnd, aes(y =AC, x = predclass, color = predclass)) + xlab("Predominant class") + ylab("AC") + ggtitle("Comparison AC Among Classes*") + geom_boxplot() + labs(caption="Note:Predominant class") + theme(axis.text.x = element_text(angle = 90),plot.caption = element_text(hjust = 0))ggplot(dnd, aes(y =Con, x = predclass, color = predclass)) + xlab("Predominant class") + ylab("Con") + ggtitle("Comparison Co

fig6: Boxplot by classes(groups) dplyr, tidyr and ggplot2

最后,我认为引出 ggplot 的 facet wrap 功能是很好的,当您想通过一个或多个变量(在我们的例子中是组或类)分割您的数据并一起绘制数据子集时,该功能非常有用。

ggplot(dnd, aes(y = AC, x = HP,color=predclass)) + xlab("HP") + ylab("AC") + ggtitle(paste0("Comparison Among Classes*")) + geom_boxplot() + labs(caption="Note:Predominant class") + theme(axis.text.x = element_text(angle = 90),plot.caption = element_text(hjust = 0))+ facet_wrap(~predclass)

fig 7: Boxplot using facet_wrap with dplyr, tidyr and ggplot2

3.三维散点图

最后,即使当我们有实际的 3D 对象或数据映射到其上时,3D 绘图也是可取的。我认为对于这个特殊的例子,我们有多个离散变量,在 2D 有重叠的点,用 3D 绘图来增加透视是有意义的。

为了说明这一点,我将使用 ggplot 绘制 Con 与 AC 的 2D 散点图,然后使用 scatterplot3d 绘制 AC、Con 和 HP 的 3d 散点图,这样我们就可以绘制三维(3D)点云。

twod<-ggplot(dnd, aes(x = AC, y = Con, color = predclass)) + geom_point(alpha = 0.2) + labs( title = "Plot Armour Class vs Hit Points by Predominat Class", caption="Note: Predominant class was obtained from the class variable")+ theme(plot.caption = element_text(hjust = 0))
twodlibrary(scatterplot3d)
threed<-scatterplot3d(x =dnd$AC, y = dnd$Con, z = dnd$HP, color = as.numeric(dnd$predclass),pch=16,angle=30)
threed
legend(threed$xyz.convert(41, 3, 310),legend = levels(dnd$predclass), col = as.numeric(dnd$predclass), pch = 16)

fig 8: 2D plot with ggplot2 and 3D plot with scatterplot3d

为了创建 3d 散点图动画,我们将使用 rgl 和 magick 包。

rgl 通过调用不同的函数来工作。下面是他们每个人做的事情。Movie3d 以重复的方式调用函数,将每一帧记录到电影中,而 Play3d 仅用于将可视化显示到 R 中。在这种情况下,要传递给 R 的函数是 spin3d。

关于图例,当你有几个类时,rgl 就有点麻烦了,它是 2D,默认情况下在图的后面,所以根据你的类的数量,它可能很难适应。

require(rgl)
with(dnd,plot3d(AC,Con,HP,col=as.integer(predclass),xlab="AC",ylab="Con",zlab="HP",box=TRUE,type="p"))movie3d(spin3d(axis = c(0, 0, 1),rpm=5), duration = 10,type="gif",dir=".",movie="Scatterplot3d")if (!rgl.useNULL())
  play3d(spin3d(axis = c(0, 0, 1), rpm = 5), duration = 10)

fig 9: 3D plot gif using rgl

作为 magick 的最后一步,我使用散点图 3d 函数在一个循环中创建了一个 png,并通过 points3d 函数添加了一些叠加点,然后我使用 magick 的 image_join 函数将它们连接成一个 gif。这就把我们带到了最初的 gif 和文章的结尾。

library(magick)

labels<-as.character(unique(dnd$predclass))
frames <- length(labels)

for (i in 1:frames) {
  name<- paste('00',i,'plot.png', sep='')
  png(name)
  plot.new()
  sp3d<-scatterplot3d(x =dnd$AC, y = dnd$Con, z = dnd$HP, color="darkgrey", type="h",pch=16,angle=30)
  sp3d
  sp3d$points3d(dnd[dnd$predclass==labels[i],c("AC")],dnd[dnd$predclass==labels[i],c("Con")],dnd[dnd$predclass==labels[i],c("HP")],col="red", type="h", pch=16)
  legend(sp3d$xyz.convert(41, 3, 310),legend =c(labels[i],paste0("Non-",labels[i])), col =c("darkgrey","red"), pch = 16)
  dev.off()
}

list.files(path=".", pattern = '*.png', full.names = TRUE) %>% 
  image_read() %>% 
  image_join() %>% 
  image_animate(fps=4) %>% 
  image_write("dnd_classes.gif")

fig10: dnd classes png used to build the scatterplot3d gif

这都是一个桌游爱好者说的。我希望这个分析读起来很有趣,写起来也很有趣。做关于非传统话题的数据分析,比如桌面游戏,总是很有趣。

评论越多的书评分越好吗?

原文:https://towardsdatascience.com/do-books-with-more-reviews-get-better-ratings-f2f68b13fad8?source=collection_archive---------26-----------------------

评分数和评论数等因素如何影响图书评分。

读书是许多人喜欢的活动。这是一种将一个人的思想置于不同的环境中,同时提供一种感同身受的感觉。我自己喜欢看书。我最喜欢的类型是混合了惊悚片的神秘片。我记得读过丹·布朗的《达芬奇密码》。

这是一本很棒的书,它让我对神秘类型的书产生了兴趣。这本书的一切从情节曲折到故事讲述都是史诗般的。读这本书时,我对谁是真正的对手感到困惑。此外,我惊讶于这本书对大教堂等建筑的描述是如此详细,以及罗伯特·兰登在解决谋杀案时的矫揉造作。

在我读完这本书后,我去网上寻找更多关于这本书的信息。我发现这幅美丽的作品得到了书籍收藏网站 Goodreads 3.8/5 的评分。

这个发现让我震惊,我决定去看看 Goodreads 上评价最高的书。随着我在列表中的位置越来越高,我注意到一个趋势,高评级的书籍通常会得到更多的评论。

因此,证实我的这个假设就成了我的一项任务:评论越多的书收视率越好吗?

获取数据

通过这个链接,从 Kaggle 获得了包含书籍及其在 Goodreads 上的评级的所有信息的数据集。

该数据集具有多种特征,如图书 id、标题、isbn、页数、评级计数、作者、*均评级、语言和文本评论计数。数据集被缩减到包括重要的特征,如标题、评分数和文本评论数。

它被进一步删减,只包括那些超过 1000 人评价和超过 100 人评论的书籍。用于执行此任务的代码如下所示:

## The dataset was truncated to include relevant information
df_books = df_books[df_books['ratings_count'] > 1000]  
df_books = df_books[df_books['text_reviews_count'] > 100]

新形成的数据集被进一步分析然后聚类。

A table of the first five rows of the new dataset.

分析数据集

对数据集进行分析,以降序排列书籍的评级,检查排名前十的书籍。然后,进行了一项推断,看看书籍的评级是否随着文本评论数和评级数的增加而增加。

The top ten books based on average ratings.

事实证明,书籍的评级并不一定意味着比低于或高于它们的书籍的评级数或文本评论数更高。但是,数据集有 4815 行。因此,基于十行进行教育猜测是不够的。如果我们通过对行进行分组来检查整个数据集,效果会更好。

数据集聚类

该数据集被聚类,以找出获得大量评级和评论的群体与没有获得大量评级和评论的群体之间是否存在显著差异。使用一种称为 k-means 聚类的方法对数据集进行聚类。

K-means 聚类是一种无监督的机器学习算法,其中数据集学习根据数据点与其他数据点的相似性将数据点分类成组。

数据集可以被聚类到定义数量的组中。图书数据集被分为三组。将数据集分组后,每一行都被赋予一个数字 0、1 或 2。

The first 25 rows of the dataset after it was grouped into three groups.

一个新的列被添加到名为 group 的表中,以表示每本书属于哪个组。

结果呢

在进一步检查后,创建了一个 3d 图像来完美地显示书籍的*均评级、文本评论数和评级数之间的关系。以下是聚类数据集的图示:

A 3-d representation of the dataset.

这三组的数据点被染成紫色、黄色和绿色。标记为 0 的组为紫色,而标记为 1 和 2 的组分别为绿色和黄色。

紫色组的大多数数据点分布在*均评分轴上,但评分数和文字评论数最少。一般来说,就评分而言,黄色组的范围比紫色组小,但它的评分数和文字评论数比紫色组高。

绿色组的评分范围与黄色组相似,但总体而言,绿色组的评分数和文字评论数高于黄色组。

创建了一个表格来显示每个组的*均差异。

A table showing the average of each group’s average rating, ratings count, text reviews count and graphical color.

根据表格,结果是紫色组在各方面都远远落后于黄色和绿色组。紫色组的*均评分为 3.94,评分数为 25,900,文本评论数为 968。黄色组的*均评分为 4.03,评分数为 570,000,文本评论数为 13,923。绿色组的*均评分为 4.12,评分数为 2,157,575,文本评论数为 38639。

下面是显示各组之间关系的散点图:

A scatter plot of the average rating versus ratings count for the groups.

A scatter plot of the average ratings vs text reviews count for the groups.

基于这两个散点图,我的假设已经被完全证实了。一般来说,一本书得到的评论越多,它的评级就越高。

书是由粉丝和评论家来评分的。评论家比书迷更有可能以非常仔细的方式评论书籍。但是,相比粉丝,评论书籍的评论家少之又少。因此,一本书越受欢迎,越多的书迷可能会认为它是完美的,这意味着受欢迎程度可能是一个混杂变量。

用来构建这个聚类模型的完整版本代码可以在这里看到。

Conv 网会梦到迷幻的绵羊吗?

原文:https://towardsdatascience.com/do-conv-nets-dream-of-psychedelic-sheep-40f4d35fa146?source=collection_archive---------33-----------------------

在连续的抽象层次上深度做梦。从上到下:输入图像,con v2–3x 3 _ reduce,inception_4c-1×1。使用 制作的 deepdreamgenerator 和公共领域图片来自 黄石国家公园 NPS

深度学习的普遍存在

深度学习的现代成功部分归功于乔治·西本科、库尔特·霍尼克和其他人开发的通用逼*定理。该定理本质上陈述了具有至少一个隐藏层和非线性激活函数的神经网络通常可以逼*任意连续函数。在过去的十年里,为训练深度网络而重新使用强大的 GPU释放了通用逼*定理的潜力,催生了许多新的商业和研究领域。在深度学习模型中,许多隐藏的层可以像通天塔一样一层一层堆叠起来,内部表示可以用来表示复杂的抽象和功能层次。这些表征可以是模型的一部分,从看似无关紧要的事物中预测任何事物,如无意义的天体物理学首字母缩写词、流式视频偏好和约会匹配;潜在的严重后果:信用风险评级、医疗诊断和约会匹配。

鉴于它们的普遍性,理解深度神经网络模型如何形成输入数据的内部表示并做出决策比以往任何时候都更重要。在实践中,通过随机梯度下降的变体的反向传播确实可以很好地适应训练数据,但是不能保证全局收敛,并且输入数据和学习过程经常以令人惊讶的方式相互作用。

https://www.youtube.com/watch?v=tlOIHko8ySg

深层网络的不稳定性

深度网络令人惊讶的学习方式导致许多人将训练和使用神经网络的整个过程称为“黑箱”,特别是在流行媒体中。当模特表现不好时,这些描述会导致糟糕的表现和公众的挫折感。

如果你从事深度学习,尝试理解你的模型在想什么是值得的。理解模型并清楚地预测它们的行为不仅有助于提高模型的性能,而且社会对隐私的关注以及欧洲 GDPR 等法规也恰当地鼓励了面向公众的机器学习中增强的解释能力。

简单的模型,简单的可视化

曾几何时,神经网络的参数从数百到数千,直接检查神经元激活是可行的,并可能富有成效。神经网络活动的一个经典的直接可视化是辛顿图(还有谁?),它通过正方形网格的大小和阴影直接显示积极和消极激活。

在某些情况下,可视化单个神经元的活动(使用一些其他技巧)仍然是有见地的,例如 OpenAI 的无监督情绪神经元工作或 Andrej Karpathy 等人的可视化递归神经网络(与相关的博客文章,大约占页面的 3/4)。然而,即使在这种情况下,找到一个有意义的可解释的神经元也是一次钓鱼探险,大多数神经元仍然是相当难以理解的。

在大型模型中构思见解

你可能已经看到了谷歌的迷幻概念/深梦技术的一些迭代。深度做梦是减少神经网络黑盒神秘性的早期尝试。通过使用网络来不断增强与给定神经元的激活相关的特征,可以生成图像来获得关于在神经网络结构中如何形成表示和决策的一些想法。这可以被拟人化为网络看着一张图片,问“图片内容让我想起了什么,我怎样才能让它看起来更像这样?”运用深度梦境技术是这篇文章的标题图像的来源。在不同的层应用这种技术会产生不同层次的抽象。在标题图像中,一只大角羊在 con v2–3x 3 _ reduce 层中做梦,这在网络中很早就出现了,产生了像笔触一样的纹理。这些是你在不同方向的边缘、点和曲线检测器,倾向于被深度 conv 网络的前几层中的卷积核学习。在 inception_4c-1×1 层中稍微深入一点,我们看到与用于训练 inception 模型的类的类型相关联的特征集合怪异地覆盖在图像上。

深度做梦当然获得了足够的关注,并被用作制作美丽图像的创造性工具,但深度做梦本身并没有提供多少可操作的见解。这可能是从手臂必须从哑铃中长出来的启示中得来的。

谷歌的 4.0 版让 CC 长出了粗壮的手臂。

神经网络计算机视觉中应用的其他可视化技术包括 Jason Yosinski 等人的特征可视化工具箱(演示视频),如果你准备用 Caffe 建立一个 Python 环境,你可以亲自尝试一下。作者展示了几个主要属于“有趣”类别的观察结果,如对面孔、文本和褶皱织物做出反应的神经元。从“有趣的”实现到可操作的见解的点连接是可解释性开始回报时间和工具投资的地方。事实上,它本身已经成为机器学习的一个子领域,满足了对拥有可解释机器学习技能的研究人员和工程师的需求。这对你的个人或组织工具箱是一个有价值的补充。

从可视化到可操作的效用

也许对深度学习可解释性最有凝聚力的研究来自克里斯·奥拉、谷歌大脑和 OpenAI 的汇合。追溯到几年前,主要发表在蒸馏上,这项工作建立在深度梦和特征可视化的概念上,以开发基于优化的可视化,进一步开发以理解具有空间激活的属性,并且随着激活图集的最*出版,作者展示了对对抗示例和奇怪特征相关性的漏洞的见解。

激活图谱是一系列研究中的最新进展,从简单的:单个神经元激活的特征可视化,到复杂的:从代表网络可能遇到的所有可能图像的流形中进行子采样的激活图谱。图片修改下一张 CC 由 4.0 授权来自 山卡特、克里斯奥拉等人 2019

激活地图集与相关的空间激活部分相似,但有一个关键区别。虽然空间激活表示单个图像的模型特征提取,但是激活图谱形成所有可能图像的特征提取图。例如,不是在小狗的图像上排列松软的耳朵、可爱的噪音和毛绒绒的爪子的特征可视化,而是激活地图集将各种各样的动物鼻子排列在一起,这些鼻子最终将融入其他相关特征,如皮毛、耳朵和尾巴。

这种神经网络特征可视化的整体视图允许以有趣的方式调查和预测模型行为。通过观察区分“水肺潜水员”和“浮潜”的特征与看起来像属于机车引擎的特征的接*程度,作者猜测他们可以从火车图像中引入一个补丁,以欺骗网络将浮潜者识别为水肺潜水员。该团队调查的其他对抗性例子包括通过添加面条将煎锅伪装成炒锅,以及通过添加棒球将灰鲸伪装成鲨鱼。

做煎锅和炒锅只需要几根面条。图片使用下一张 CC 通过 4.0 许可来自 山卡特、克里斯奥拉等人 2019

向前发展的可解释价值

总之,自《深度梦》以来,可解释性领域已经发展了很多,并开始提供可操作的见解。用激活地图集生成的对抗性例子的类型依赖于全网络特征可视化和人类直觉的巧妙结合。随着深度学习网络继续部署到新的领域,并在现有领域中获得更大的采用,它们将被认为更负责任,更可预测地可靠。在这种情况下,对可解释性工具和从业者产生的需求和价值只会增加。

原载于 2019 年 5 月 14 日https://blog.exxactcorp.com

选举会影响股市吗?

原文:https://towardsdatascience.com/do-elections-affect-the-stock-market-c28562646c71?source=collection_archive---------8-----------------------

印度大选今天开始——4 月 11 日,我想以请求所有在印度并且达到投票年龄的人开始这篇文章——请投票!投票做出你想看到的改变。

特别是所有国家的大选,使得各行业通常对新政府可能带来的新政策或政策变化处于投机模式,这些政策可能会对公司的运作产生不利或有利的影响。这反过来影响他们在股票市场上的价格,并使投资者对市场持不同看法。关于在选举期间应该如何投资,一直存在争议。我将通过我的分析来回答这些疑问,重点将是回答以下问题:

  • 我应该在选举之前还是之后投资?
  • 我应该等到选举的影响消退吗?
  • 在这一时期有什么特别的行业在增长吗?
  • 有我应该远离的部门吗?

数据收集

为了分析,我们需要选举日期前后的指数历史数据,我们从— BSE 官方网站 获取。我们将下载 BSE Sensex 指数、BSE 100 指数、BSE 200 指数& BSE 500 指数以及各种行业指数数据。让我们从 维基百科 获取选举日期。我们将回顾过去 4 年的选举— 2014 年,2009 年,2004 年,1999 年。让我们来看 6 个数据点 (Return %) 进行分析——选举前 6 个月——这将是与选举前 3 个月的数据进行比较的基础。其他数据点是选举前 1 个月、选举月、选举后 1 个月、选举后 3 个月和选举后 6 个月。

2014 年选举

让我们先来看看最新的数据——2014 年大选,我们看到 3 个月前市场下跌约 1.5 % ,之后在大选月市场处于牛市,BSE 指数上涨10。现在让我们来看看行业指数****

扇区数据与 BSE sensex 数据密切相关。疯牛病汽车、疯牛病医疗和疯牛病银行指数上升,并且在整个选举过程中保持一致。而 BSE 金属是最不稳定的。

2009 年选举

从技术角度来看,2009 年选举的模式与 2014 年相似,但是我们看到在选举后市场增长(大约。~9%) 不像之前和期间(大约。30%) 选举月。

大多数行业在选举前后都上涨了。 BSE Auto,BSE IT 分别上升和一致BSE Metal 在选举月期间经历了持续的高增长期(接* 60%)—这可能是由于帮助金属公司的政策变化。 BSE FMCG 在选举期间没有任何重大动作

2004 年选举

2004 年选举见证了非常低迷的市场,直到选举结束。市场受选举结果的影响,在选举月下跌了大约 20%,一个月后才回升。然而,我们可以看到选举后的持续增长,并达到接*。6 个月后约为 20%。

这些板块紧随 BSE Sensex 指数。在选举月期间,所有行业都下跌了* 20%而在选举后都上涨了, BSE 金属、BSE IT 和 BSE 银行的涨幅最大。

1999 年选举

选举前市场繁荣达到接* 40%的。然而,在选举期间和之后,市场经历了短暂的增长,然后在 6 个月的时间里,T42 下跌了* 20%。

扇区再次非常紧密地跟随BSE Sensex。市场对新政府的预期上升,BSE 金属上涨* 60% 但是所有行业在大选后下跌* 40%。政府是否没有信守承诺?(可能吧!)

推理

正如我们通过这些年的各种图表所看到的,我们看到,通常选举后市场会上涨,让我们看看交叉对比数据并进一步分析。

BSE Sensex cross comparison data over last 4 election years.

我们看到 BSE Sensex 意味着数据表明市场通常在选举前上涨,在选举月期间和之后增长非常缓慢,然后回升。理想的策略是在选举前 3 个月开始建立你的投资组合,并在选举后 3 或 6 个月继续保持。让我们看看我们可以投资或远离的行业。

BSE Auto Index cross comparison data over last 4 election years.

汽车似乎是所有指标中最一致的指标。增长没有其他指数那么快,下跌也没有那么快。的策略将是尽早投资优质汽车股,并在选举后大约 3 到 6 个月卖出。

BSE Metals Index cross comparison data over last 4 election years.

金属指数似乎是所有指数中波动最大的,它们有大起大落。策略是关注有利于金属公司的政策,如果不远离金属行业,就投资。

BSE Healthcare Index cross comparison data over last 4 election years.

像汽车这样的医疗保健指数似乎与其增长非常一致回报与 sensex 或 Auto 回报不匹配,但是,如果我们可以投资顶级医疗保健股票,在选举临*时投资并在选举后大约一个月或三个月出售它们将是理想的。

伙计们,这就是我现在要说的!对于对代码感兴趣的人——可以参考我的 Github 链接。我希望你喜欢读这篇文章,如果我错过了什么或者有什么反馈,请在评论中分享。

女员工赚钱少吗?

原文:https://towardsdatascience.com/do-females-employees-make-less-money-56275d00da4c?source=collection_archive---------13-----------------------

在 Python 中浏览测量数据

使用 pandas、Seaborn、Matplotlib 和 Scipy 进行调查数据分析。

这是我在 Medium 上的第一篇文章,正因为如此,我决定用调查数据来练习一些统计学。为了做到这一点,我将使用布伦特·奥扎薪酬调查,据我所知,该调查自 2017 年以来每年发布一次。这里的主要思想是回答以下问题:女性雇员比男性雇员挣得少吗?。许多人会说“是的!他们肯定有!”,其他人可能会说“当然,女性挣钱少!”。在我看来,当我们做出这种声明时,我们必须关注一种叫做确认偏差的东西。换句话说,如果你认为女性的工资比男性低,那么你就有可能在没有深入分析你正在处理的数据质量的情况下就做出这种判断。

我们将使用 pandas、Matplotlib、seaborn 和 Scipy 来理解我们的数据。此外,我们还将使用 2019 年数据专业人员薪酬调查结果,你可以在 [Bent Ozar 的网页](http://Possessive last names)上找到它。

把这篇文章作为一种方法,可以帮助你分析一些调查和任何其他数据,你想统计检查。

数据探索

让我们首先导入一些我们将需要的库,然后浏览数据。

#**Import libraries**
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set_style(‘ticks’)
#**Ignore woarnings**
import warnings
warnings.filterwarnings(‘ignore’)# **Import data**
raw_data = pd.read_excel(‘2019_Data_Professional_Salary_Survey_Responses.xlsx’,header = 2)
raw_data.head()

让我们看一下数据类型,并检查数据集中是否有 nan 变量。

raw_data.info()

首先引起我注意的是 SalaryUSD 专栏。这个特性必须是数字的,为了用这个数据做一些数学运算,我们必须把它们转换成浮点数。另外,经过一些观察,我注意到在薪水栏中有一些字符应该被删除。此外,由于一些行被标识为 integer,另一些被标识为 float,我创建了一个函数来处理所有这些数据,将它们转换为 string,然后将整个列转换为 float。最后,DataFrame 的列标签上的所有空格(“”)都已替换为下划线(“_”)。

#**Convert all of the salary rows into string**
def str_salary(salary):
    sep = '.'
    if type(salary) == int:
        salary = str(salary)
    elif type(salary) == str:
        # Replace characteres and take the cents out of our data
        salary = salary.replace(" ","").replace("$","").replace(",","").split(sep)[0]
    elif type(salary) == float:
        salary = str(salary)

    return salary# **Replace spaces(“ “) in columns name with underscore (“_”)**
raw_data.columns = raw_data.columns.str.replace(“ “,”_”)# **Apply str_salary function**
raw_data['SalaryUSD'] = raw_data.SalaryUSD.apply(str_salary)
raw_data['SalaryUSD'].head()

为了只分析 2019 年的数据,我们将按年份和与我们的分析相关的列过滤数据框架。

df = raw_data.loc[raw_data.Survey_Year == 2019, ['Survey_Year','Country','SalaryUSD','JobTitle','YearsWithThisTypeOfJob','Education','Certifications','PopulationOfLargestCityWithin20Miles', 'Gender' ]]
df.head()

既然我们已经定义了我们的数据框架,我们现在能够获得一些信息。首先,让我们统计各个国家的雇员人数,并研究我们拥有更多数据的国家。其次,我们将按职位统计员工人数,最后统计男女员工总数。

# **Answers by Country**
df.Country.value_counts()

正如我们所看到的,在本次调查中,我们有更多来自美国的员工,因此,我们将过滤我们的数据框架,以便只处理美国的数据。

#**Filter dataframe by country**
US_2019 = df.loc[df.Country == ‘United States’,:]
US_2019.head(3)

所以,让我们来看看按性别划分的员工数量,看看我们能否从中获取一些信息。女性和男性雇员的数量是否相等,或者至少接*相等?我们来看看这个!

US_2019.Gender.value_counts()

似乎我们在这里有一个问题。不幸的是,男性的总数远远大于女性。此外,由于 2019 年只有一名非二元人回答了调查,我们无法从非二元性别中获得任何统计信息。所以,让我们去掉这一行,只关注两种性别。

# **Delet the row - Non-binary/third gender**
US_2019 = US_2019[US_2019.Gender != 'Non-binary/third gender']
US_2019.Gender.value_counts()

好的,我们已经知道(不幸的是)女性的数量远低于男性。现在让我们来回答以下问题:就职称而言,性别是如何分布的?我们先统计一下每个岗位的员工人数。#职位名称
US_2019。JobTitle.value_counts()

# **Job Titles** 
US_2019.JobTitle.value_counts()

让我惊讶的是,我们只有 4 个数据科学家,21 个工程师……好吧,这个就不考虑了!所以,现在我们有了这个调查中的职位概述。职位性别分布如何?我们来看看这个!

# **number of each gender by job title**
Gender_df = US_2019.loc[ : , [‘JobTitle’, ‘Gender’, ‘SalaryUSD’ ]]
Count_gender = Gender_df.pivot_table(Gender_df, index = [‘JobTitle’, ‘Gender’], aggfunc= ‘count’)
Count_gender

我不知道你们是怎么想的,但是我是视觉型的学习者,这就是为什么我真的喜欢制作图表的原因。我们可以使用 seaborn 库用我们刚刚检查过的信息构建一个条形图。

import seaborn as sns
# **use Seaborn styles**
sns.set()
pd.pivot_table(Gender_df, index= 'JobTitle', columns= 'Gender', aggfunc= 'count').plot(kind= 'barh', figsize= (9,9))
plt.xlabel("Salary USD")

上图清楚地显示了性别之间的差距,不仅是总体上回答调查的员工,还包括职位。你在你的公司注意到这一点了吗?

太好了。现在我们知道在我们的调查中有 541 名男性和 60 名女性,我们还知道在所有的职位中男性员工的数量要多得多。需要注意的是,我们不能保证这些事实是绝对真实的,因为我们不知道调查是如何进行的。此外,我们必须意识到我们的在线样本的代表性,这样我们才能相信从我们的互联网调查数据得出的结论的有效性。换句话说,数据可能有偏差。

例如,在进行调查时,我们倾向于对某些类型的人(在本例中是员工)进行过度采样,而对其他人进行欠采样。并不是所有人都知道 Brent Ozar 的网站——负责这项调查的网站,如果其他人对这种主题不感兴趣,他们就更不可能参与这项调查。

我们可以尝试使用加权等统计技术来处理这个问题,以补偿这种类型的“采样偏差”。这不是我们分析的情况,我们将只是从我们的数据中得出一些直观的见解,并实践一些基本的统计数据,因为我们并不真正担心这个话题。

工资

是时候看看工资数据了,这样我们可以检查一下里面是否有缺口。重要的是要记住,我们不会考虑一些特征,如工作经验、教育程度和公司规模,因为我们只想回答一个简单的问题:女性和男性的工资有差距吗?例如,我会用这些特征来回答为什么男女之间存在或不存在差距。也就是说,让我们从薪水栏开始分析。

直方图通过将数据分组到箱中来显示指标变量值的间隔频率。让我们来看看工资的分布情况。你觉得会怎么样?嗯,我认为它看起来像一个正偏的高斯分布,很少有员工的收入超过特定的阈值(可能是 15 万美元)。

#**Import sub-package stats from scipy library**
from scipy import stats
sns.distplot(US_2019.SalaryUSD, fit = stats.norm)

猜得好!上面的直方图与我预期的相似(不完全相同)。数据看起来接*正态分布,或者至少看起来是钟形的。正常吗?让我们检查一下。

常态测试

我们将通过一个定性分析(Q-Q 图)和两个定量检验(夏皮罗-维尔克和达戈西诺的 k2 检验)来检验数据的正态性。

定性正态性检验

Q-Q 图是检查数据分布的常用图。分位数-分位数图或 Q-Q 图生成我们与之比较的分布样本(在这种情况下为正态分布)。生成的样本被分成多个分位数,样本中的每个数据点都与分布中的一个相似成员相结合,我们将在相同的累积分布中与该成员进行比较。因此,我们有一个散点图,x 轴是理论值,y 轴是数据样本分位数。

#Import qqplot
from statsmodels.graphics.gofplots import qqplot
qqplot(US_2019.SalaryUSD, line = ‘s’)

那么,我们该如何解读这个情节呢?嗯,蓝点与红线的偏差显示了与我们正在比较的分布(高斯)的偏差。基于此,我们可以说,我们的特征似乎不是正态分布的良好匹配。如果数据呈正态分布,大部分蓝点会在红线上,事实并非如此。即使线上有很多蓝点,但不在线的还有很多。这表明数据将呈现不同的分布,正如我们在直方图中观察到的那样。

定量常态检验

除了前面的分析,我们将使用两个定量测试来检查我们的数据的正态性。让我们从夏皮罗-维尔克检验开始,它评估一个特定的样本,并量化数据遵循正态分布的可能性。据我所知,夏皮罗-维尔克检验不仅是一个可靠的检验,而且是一个广泛使用的检验,我们可以使用 SciPy 库中的 Shapiro()函数来应用它。此函数返回由测试计算的 W 统计数据和 p 值。

我们要用的第二个测试是达戈西诺的 k 测试。该正态性检验计算数据的峰度和偏斜度,以确定它们是否遵循高斯分布。基本上,该测试所做的是将样本的偏斜度和峰度结合起来,以产生正态性的综合测试。对于那些不熟悉这些术语的人来说,峰度是分布有多少在尾部的量化,而偏斜是分布有多少被向右或向左推动的量化(它衡量分布的不对称性)。为了计算 de 统计和 p 值,我们将使用 SciPy 库中的 normaltest()函数。

夏皮罗-维尔克试验

from scipy.stats import shapiro
statistic,p = shapiro(US_2019.SalaryUSD)
print(f'P-value: {p :<.3f}')#**For a threshold of 5% (alpha)**
if p > 0.05:
    print(f'Sample looks Gaussian (fail to regect H0)')
else:
    print(f'Sample does not look gaussian ( regect H0)')

**达戈西诺的 k2 测试 **

from scipy.stats import normaltest
statistic,p = normaltest(US_2019.SalaryUSD)print(f'P-value:{p:<.3f}')#**For a threshould of 5% (alpha)**
if p > 0.05:
    print(f'Sample looks Gaussian (fail to regect H0)')
else:
    print(f'Sample does not look gaussian (regect H0)')

因为我们已经定性和定量地分析了我们的测试,我们可以对数据做一个假设。到目前为止,我们使用的所有测试和可视化技术都不表示正态分布。

离群值

为了确保我们的数据能够恰当地代表我们的问题,我们必须意识到数据集中存在异常值的可能性。异常值是超出预期范围的条目,与其他观察值不同。它们会影响我们数据分布的偏斜度,从而影响一些统计术语,如标准差和均值。特别是,由于计算的方式,这些度量对异常值非常敏感。

让我们按性别划分我们的数据,并绘制一个箱线图,这样我们就能够通过它们的四分位数来说明我们的数据。这也可以帮助我们识别一些潜在的异常值,例如位于图中触须之外的那些数据。

fig = plt.figure(figsize = (10,8))
sns.boxplot(x = ‘Gender’, y = ‘SalaryUSD’, data = US_2019)

统计数字

让我们计算一些项,以便对数据有所了解。

def statistics(salary):
 #**Import variation**
 from scipy.stats import variation
 #Calculate terms
 mean = salary.mean()
 median = salary.median()
 mode = salary.mode()
 kurtosis = salary.kurtosis()
 skew = salary.skew()
 CV = variation(salary)
 #**dict**
 stats = [(‘Country’, [‘United States’]),
 (‘Mean’,[round(mean,2)]),
 (‘Median’,[round(median,2)]),
 (‘Mode’, [int(mode)]),
 (‘Kurtosis’,[round(kurtosis,2)]),
 (‘Skew’,[round(skew,2)]),
 (‘Coefficient of variation’,[round(CV,2)]) 
 ]
 #**dataframe**
 stats_df = pd.DataFrame.from_items(stats) 
 return stats_df

应用统计功能

Salary_statistics = statistics(US_2019['SalaryUSD'])
Salary_statistics

因此,一旦我们计算了这些统计数据,我们就能够识别数据的一些特征。第一,中位数和均值大于众数。这意味着分布的右尾更长,或者换句话说,数据是正偏的。第二,我们的数据的偏斜度大于 1,证实了它的高偏斜度。第三,我们的数据集中的高峰值表明它的分布有重尾或异常值——我们必须调查它。最后,变异系数(CV)是数据集中数据点围绕其*均值的离差的统计度量,表明我们的样本相对于其*均值有 43%的显著变异。

到目前为止,我们所做的所有分析都为我们提供了证据,证明我们的* *数据不符合正态分布。此外,高峰值可能是离群值的指标。我们来调查一下。

四分位间距

我们需要一个合理的标准偏差来进行分析。我这么说是什么意思?嗯,标准差代表了数据相对于*均值的分散程度,正如我之前说过的,这种方法受异常值的影响很大。此外,我们将在后面看到,标准误差对总体的标准偏差是敏感的,正因为如此,我们希望过滤掉异常值。

没错。我们知道我们必须过滤掉离群值。但是我们怎么做呢?答案很简单:我们将使用四分位数范围。

四分位数间距基本上是第三个四分位数和第一个四分位数之间的距离。在我们的例子中,下表显示 Q3 = 123.600,00 美元,Q1 = 83.000,00。让我们计算它们之间的差异,并确定我们的四分位间距(IQR)。

#**Statistics**
round(US_2019.SalaryUSD.describe().to_frame(),3)

#**Calculate the percentiles — 25 and 75 %**
q75, q25 = np.percentile(US_2019.SalaryUSD , [75 ,25])
print(f’Q3:{q75}’)
print(f’Q1:{q25}’)
# **Calculate the percentile Range**
iqr = q75 — q25
print(f’Interquartile Range: {iqr}’)

既然我们有了 IQR,我们就能够过滤掉数据集中的异常值。我们这样做是考虑到任何超出中位数正(+)和负(-) 1.5 * IQR 的数据都是异常值。

# **IQR +/- 40600**
min_salary = US_2019.SalaryUSD.median()- 1.5*iqr
max_salary = US_2019.SalaryUSD.median() + 1.5*iqr
print(f'Minimun salary (threshould) : {min_salary}')
print(f'Maximun salary (threshould) : {max_salary}')

#**data set within the range**
US_2019_No_Outliers = US_2019[(US_2019.SalaryUSD>=min_salary) & (US_2019.SalaryUSD <= max_salary)]
US_2019_No_Outliers.head()

在剔除异常值后,我们可以看到我们的数据集是如何变化的。首先,箱线图显示两性都没有异常值。第二,数据分布大致代表一个高斯。此外,*均值现在更接*中位数,变异系数仅为 25%,这意味着我们的数据在我们定义的范围内均匀分布。

# **Boxplot with data within the range**
fig = plt.figure(figsize = (10,8))
sns.boxplot(x = ‘Gender’, y = ‘SalaryUSD’, data = US_2019_No_Outliers)

sns.distplot(US_2019_No_Outliers.SalaryUSD, fit = stats.norm)

# **statistical terms for data within the range**
Salary_statistics_No_Outliers = statistics(US_2019_No_Outliers[‘SalaryUSD’])
Salary_statistics_No_Outliers

统计摘要

#**Statistical terms before and after the removal of outliers**
Salary_statistics.append(Salary_statistics_No_Outliers)

请注意,我们已经删除了 34 个高于最大阈值的条目和 8 个低于最小阈值的条目。这表明 7%的观察值导致了我们数据集的显著变化。

below_threshould = US_2019[US_2019.SalaryUSD <= min_salary]
above_threshould = US_2019[US_2019.SalaryUSD >= max_salary]
print(f'Total of salaries above the max threshould: {above_threshould.SalaryUSD.count()}')
print(f'Total of salaries below the min threshould:{below_threshould.SalaryUSD.count()}')

print(f'Entries outside the range: { round((below_threshould.SalaryUSD.count() + above_threshould.SalaryUSD.count()) / US_2019.SalaryUSD.count()*100)} %' )

离群值的另一个重要方面是,其中 33 个是男性,只有一个是女性。这表明 97%挣更多钱的员工是男性。这不是很有趣吗?!

above_threshould.Gender.value_counts()

标准误差分析

现在我们有了一个相当*衡的数据集,我们可以进行标准的误差分析了。我为什么要这么做?标准误差向我们展示了我们的数据有多好。换句话说,它衡量的是我们的样本代表总体的准确性。下面的公式显示了这个统计术语是如何计算的。

需要注意两件重要的事情。首先,样本越大,样本均值就越接*总体均值。此外,我们可以通过公式看出,如果我们有更多的样本,标准误差将会减少。第二,总体的标准差越小,标准差越小。正如我们所知,标准差是一种传播的度量,它受异常值的影响很大。这意味着在我们的数据集中存在异常值的情况下,样本的标准偏差会大得多。

def mean_std_count(salary, data):
 mean = salary.mean()
 std = salary.std()
 count = salary.count()

 std_error = [(‘Gender’,[data]),
 (‘Salary Mean’,[round(mean,2)]),
 (‘Salary std’,[round(std,2)]),
 (‘Sample’,[count]) ]

 std_erro_df = pd.DataFrame.from_items(std_error)
 return std_erro_dfFemale_stats = mean_std_count(US_2019_No_Outliers[US_2019_No_Outliers.Gender == ‘Female’].SalaryUSD, ‘Female’)
Male_stats = mean_std_count(US_2019_No_Outliers[US_2019_No_Outliers.Gender == ‘Male’].SalaryUSD, ‘Male’)
Salary_stats = mean_std_count(US_2019_No_Outliers.SalaryUSD, ‘Total’)
Female_stats.append(Male_stats).append(Salary_stats)

上表显示,我们的*均工资差距约为 3700 美元。你不认为这很重要吗?在我看来,这似乎是相当值得注意的。

尽管我们的数据不符合正态分布,但在剔除异常值后,我们在均值和标准差方面得到了一些更简洁的东西。此外,我们的数据集是否遵循特定的分布对我们的分析来说不应该有太大的影响,因为我们不需要标准误差的高斯分布。

也就是说,如果我们考虑样本的正态分布,我们可以说 95%的工资应该在 51.000 美元到 152.350 美元之间,我不认为这有任何问题。实际上,我觉得这很对。

def standard_error(salary, data):
    #**calculate terms**
    mean = salary.mean()
    std = salary.std()
    count = salary.count()
    std_error = std/((count)**(1/2))
    min68 = mean- std_error
    max68 = mean+ std_error
    min95 = mean- 2*std_error
    max95 = mean+ 2*std_error

    #**create df**
    std_error = [('Gender',[data]),
                 ('Standard Error',[round(std_error,2)]),
                 ('Min  [68% range] ',[round(min68,2)]),
                 ('Max [ 68% range] ',[round(max68,2)]),
                 ('Min [95% range]',[round(min95,2)]),
                 ('Max [95% range]',[round(max95,2)]),
                  ]

    std_error_df = pd.DataFrame.from_items(std_error)
    return std_error_df

女性和男性工资数据框架——没有异常值。

Female_std_error = standard_error(US_2019_No_Outliers[US_2019_No_Outliers.Gender == ‘Female’].SalaryUSD, ‘Female’)
Male_std_error = standard_error(US_2019_No_Outliers[US_2019_No_Outliers.Gender == ‘Male’].SalaryUSD, ‘Male’)
#**Append male and female df**
a = Female_std_error.append(Male_std_error)
a

为了解释数据并试图得出结论,我们必须分析标准误差,查看条形的重叠性质。在我们的例子中,误差线重叠,重叠区域不包含较低样本的*均值。由于这一事实,我们可以假设,没有强有力的证据表明,人口是相似的或不同的。68%和 95%范围内的不确定性都太高。我们可以在下面的条形图中清楚地看到这一点。

def mean_error_plot(salary1, salary2, gender1, gender2):
    #**Calculate terms**
    mean1 = salary1.mean()
    mean2 = salary2.mean()
    std1 = salary1.std()
    std2 = salary2.std()
    count1 = salary1.count()
    count2 = salary2.count()
    std_error1 = std1/((count1)**(1/2))
    std_error2 = std2/((count2)**(1/2))

    #**Create lists for plot**
    Genders = [gender1,gender2,gender1,gender2]
    x_pos = np.arange(len(Genders))
    Gd = [mean1,mean2,mean1,mean2]
    error = [std_error1,std_error2,2*std_error1,2*std_error2]

    #**Create the plot**

    fig, ax = plt.subplots(figsize = (10,10))
    ax.bar(x_pos, Gd, yerr=error, align='center', alpha=0.5, ecolor='black', capsize=10,color=['red', 'red', 'black', 'black'])
    ax.set_ylabel('Salary [$]')
    ax.set_xticks(x_pos)
    ax.set_xticklabels(Genders)
    ax.set_title('Genders - Range')
    ax.yaxis.grid(True) 

    #**Create horizontal lines**
    ax.axhline(y = 100936.60, color = 'r', linewidth = 1,xmin=0.143, xmax=0.38 , linestyle='dashed', alpha=0.5  )
    ax.axhline(y = 101766.23, color = 'r', linewidth = 1,xmin=0.143, xmax=0.38, linestyle='dashed', alpha=0.5 )

    ax.axhline(y = 99809.28, color = 'r', linewidth = 1,xmin=0.62, xmax=0.85 , linestyle='dashed', alpha=0.5  )
    ax.axhline(y = 104318.53, color = 'r', linewidth = 1,xmin=0.62, xmax=0.85, linestyle='dashed', alpha=0.5 )

    #**Create legend**
    import matplotlib.patches as mpatches
    red_patch = mpatches.Patch(color='red', label='68% range') 
    black_patch = mpatches.Patch(color='black', label='95% range')
    plt.legend(handles=[black_patch,red_patch], loc = 'upper left')

女性和男性数据框架——无异常值

Female_no_out = US_2019_No_Outliers[US_2019_No_Outliers.Gender == ‘Female’].SalaryUSD
Male_no_out = US_2019_No_Outliers[US_2019_No_Outliers.Gender == ‘Male’].SalaryUSD
#apply mean_error_plo function
mean_error_plot(Female_no_out,Male_no_out,’Female’,’Male’)

那么,我们现在能做什么?用另一种方法来分析它怎么样?这正是我们要做的!让我们通过假设检验来比较这两种方法。

t-学生测验

我们使用假设检验的原因是,在给定样本数据的情况下,确定零假设是否可能为真。如果几乎没有反对的证据,我们接受零假设,如果零假设不太可能,我们可能会拒绝零假设而支持另一个假设。

也就是说,一旦我们确定了无效假设和替代假设,我们就能够选择显著性水*。这个统计项是决定我们何时拒绝零假设的概率阈值。此外,在执行测试后,p 值有助于我们解释结果。该值是代表给定事件发生概率的测试中的边际显著性水*。

回到我们的案例研究,让我们从设定第一个假设开始,假设两种工资手段(男性和女性)相等。因此,我们将假设另一个假设是两个均值不相等。为了做到这一点,我们将使用 stats.ttest_ind()函数执行双样本 T 检验。

假设:我们假设两个样本都是正态分布,并且方差相同。

让我们对有异常值和无异常值的数据进行双样本 t 检验,这样我们就可以有所了解,从而得出结论。

# **Import t-test function**
from scipy.stats import ttest_ind# **T-test - data without outliers**
ttest_no_outliers = stats.ttest_ind(a = Female_no_out, b = Male_no_out, equal_var= False)
ttest_no_outliers

pvalue_no_outliers = round(ttest_no_outliers[1],2)
print(f’P-value of data without outliers: {pvalue_no_outliers}’)

测试给出的 p 值为 0.31,大于显著性值(0.05)。在这种情况下,我们不能拒绝零假设。因此,我们期望在 31%的样本中找到相同性别的样本均值。

现在让我们对包含异常值的工资数据进行测试。

# **Filter salary by gender considering outliers**
Female_salary_with_outliers = US_2019[US_2019.Gender == 'Female'].SalaryUSD
Male_salary_with_outilers = US_2019[US_2019.Gender == 'Male'].SalaryUSD#**T-test on data with outliers**
ttest_outliers = stats.ttest_ind(a = Female_salary_with_outliers, b = Male_salary_with_outilers, equal_var= False)
ttest_outliers

pvalue_outliers = round(ttest_outliers[1],2)
print(f’P-value of data without outliers: {pvalue_outliers}’)

如上所述,如果我们保留异常值,我们可以说,由于 p 值为 0.02,低于显著性水*(0.05),男女薪酬不*等。因此,这表明,当我们将异常值纳入数据集中时,男女工资确实存在差异。

结论

在我们做了分析和假设之后,我想说的是,在正常的工作中,两性似乎得到了同等的报酬。然而,当我们在测试中包括收入高得多的人数时,我们可以看到离群值的差距——其中 97%是男性

我知道这是一个宽泛的分析。如果我们深入研究所有的特征,我们可能会找到得出这个结论的原因。万一你想更好的分析,可以随便找 Brent 原来博客上的数据,应用你所有的知识。请让我知道你的结论!

注意 : 我还使用不同的标准进行了分析,以确定异常值。在我的 GitHub 页面上查看一下。

来源:

  • https://data.library.virginia.edu/understanding-q-q-plots/
  • http://www . stats models . org/dev/generated/stats models . graphics . gofplots . QQ plot . html
  • https://web . archive . org/web/20120325140006/http://www . CEE . MTU . edu/~
  • https://machine learning mastery . com/a-gentle-introduction-to-normality-tests-in-python/
  • http://www . SQL gene . com/2017/12/29/practicing-statistics-female-DBAs-and-salary/

FIFA 19 评分与 PES 2019 评分有显著差异吗?

原文:https://towardsdatascience.com/do-fifa-19-ratings-differ-significantly-from-pes-2019-ratings-5c0a8d5bd55e?source=collection_archive---------30-----------------------

足球运动员的 FIFA 19 评级与他们的 PES 2019 评级有多相似。

“GOOOOOAAAAAL。路易斯·苏亚雷斯多么疯狂的进球。”

在国际足联 19 日巴塞罗那足球俱乐部和拜仁慕尼黑之间的激烈比赛的最后一分钟,我打进了一个 30 码的尖叫。比分现在是 3 比 2,我赢了。我欣喜若狂。另一方面,我的对手很失望。

我简直不敢相信苏亚雷斯站在边线附*被三名防守队员挡住时是如何打进那个漂亮的进球的。一个仍然让我困惑的想法是,苏亚雷斯得分是纯粹出于运气,还是因为他有着令人难以置信的高收视率。

而且我在 YouTube 上看了很多 FIFA 19 上打进的世界级进球,去发现什么样的球员打进了最不可思议的进球。当我观看这些进球时,我注意到大多数进球都是由高水*的球员打进的。

然后,YouTube 的推荐算法让我也看了 PES 2019 上类似的进球。我注意到大致相同的一群高知名度的球员也打进了这些精彩的进球。

因此,很容易得出结论,知名度高的球员更有可能在两个最大的足球游戏*台上创造最佳进球。由于这两款游戏的玩家表现有很强的相似性,我很想知道【FIFA 19 和 PES 2019 上玩家的评分是如何密切相关的。

因此,我决定进行一项研究,以找出 FIFA 19 评级和 PES 2019 评级之间是否存在显著差异。

获取数据集

我必须获得包含执行项目所需功能的最佳数据集,所以我使用 Kaggle 通过这个链接获得 FIFA 19 数据集,并在这里获得 PES 2019 数据集。

使用 IBM Watson Studio 上的 Jupyter 笔记本,数据集被加载并清理,以确保它们包含所有需要的列。

A snapshot of the first five rows of the PES 2019 transformed dataset.

A snapshot of the first five rows of the FIFA 19 transformed dataset.

两个数据集都被重新设计后。运行了多个代码来合并两个数据集,删除重复的行,以降序排列玩家的评级,并重命名列。

以下是用于执行上述过程的一些代码:

要合并两个数据集:

df_combo = pd.merge(df_pes2, df_fifa2)

df_combo1 = df_combo

要删除重复的行:

df_combo2 = df_combo1.drop_duplicates(['Player Name'],keep='first') 

要按降序排列合并的数据集并重命名列,请执行以下操作:

df_combo3 = df_combo2.sort_values(by = "FIFA Overall Rating", ascending = **False**)
df_combo3.reset_index(inplace = **True**)
df_combo3.drop("index", axis = 1, inplace = **True**)
df_combo3 = df_combo3.rename(columns = {"Overall Rating" : "PES Overall Rating"})

显示特定列时合并两个数据集的结果如下所示:

The first 20 rows of the merged dataset showing Player’s name, FIFA 19 ratings, PES 2019 ratings and age.

根据合并数据集的前 20 行,与 PES 2019 球员相比,FIFA 19 球员预计将获得更高的评级。

探索性分析

对于新形成的数据集,下一步是查看数据集中的重要列如何相互作用。因此,创建了两个正态分布图,显示 PES 2019 评级和 FIFA 19 评级的正态分布情况。然后,构建第三个正态分布图来结合前两个。

A normal distribution graph of PES 2019 players’ overall ratings.

A normal distribution graph of FIFA 19 players’ overall ratings.

A normal distribution graph comparing how both graphs are normally distributed.

根据图表,FIFA 19 的*均评分为 68.19,低于 PES 2019 的*均评分 70.32。然而,FIFA 19 的标准差为 6.84,高于 PES 2019 的标准差 6.13。

标准差的值表明,FIFA 19 球员的评级比 PES 2019 球员的评级更分散。这个结果可以在第三张图中观察到。

结果呢

为了找出 PES 2019 评级和 FIFA 19 评级之间是否存在显著差异,进行了一系列任务。首先,创建一个散点图来显示两组之间的相互关系。

A scatter plot of PES 2019 ratings vs FIFA 19 ratings.

根据散点图,PES 2019 评级和 FIFA 19 评级之间似乎存在非常积极的关系。然后,计算相关系数和 p 值。下面是用于获得结果的代码和结果本身的快照。

The results of the correlation coefficient and p-value of the FIFA 19 and PES 2019 ratings.

皮尔逊相关系数是 0.8744,因为 0.8744 的值意味着正的强相关,所以是可疑的。p 值约为 0.0。p 值小于 0.05,因此 FIFA 19 评级和 PES 2019 评级之间存在显著差异,即使它们相关性极强。

用于进行这项研究的完整版本代码可以在这里看到

甘人会梦到假图像吗?

原文:https://towardsdatascience.com/do-gans-dream-of-fake-images-4372b0777a2d?source=collection_archive---------10-----------------------

深入研究图像取证:区分真实图像和伪造图像的努力

Barack Obama is one of the most popular characters for puppeteering

众所周知,现在很难区分真实媒体和虚假媒体。可能是文本、音频、视频或图像。

每种媒体都有自己的伪造方法。虽然伪造文本(仍然)主要是以传统方式进行的,但伪造图像和视频已经向前迈出了一大步。我们有些人甚至觉得再也分不清什么是真的什么是假的了。如果说两年前, photoshop 之战 sub-reddit 是伪造图像的艺术状态,photoshop 专家是这一领域的奇才,那么新技术已经改变了很多事情。

你可能听说过一些尖端的伪造方法,它们严重威胁着我们对什么是真什么是假的感知: 深度伪造 技术允许在每个视频中种植每张脸,不同的re——制定 技术允许随心所欲地移动每张脸:做出表情、说话等。而这仅仅是开始。

Deep fake — planting Hillary Clinton on her impersonator

Re-enactment — making a face talk

最*,我非常投入这个领域:我已经开始与一家名为 Cyabra 的伟大初创公司合作。Cyabra 是一家反假新闻和反机器人的初创公司,因此,它的任务之一是将假图像与真图像进行分类,专业术语是图像取证

如你所料,这是一项具有挑战性的任务。正如许多网络安全/欺诈检测任务一样,保护者似乎总是比伪造者落后一步。在图像伪造中,情况甚至更复杂,因为新的伪造技术每天都在出现。

那么解决 hits 任务的正确方法是什么呢?在每一项安全任务中,保护者都必须考虑所有可能的已知的 T21 威胁,此外还有攻击者意想不到的未知威胁。

让我们考虑一下防止窃贼入室:你知道窃贼可以破门而入,打破窗户、后门等。所以你把所有的入口都锁上了。但是你也应该放一个运动探测器,以防窃贼从一个未知的缺口进入,你仍然可以发现他。

在网络安全领域,特别是在数字图像取证领域,这意味着你必须以最高的准确性解决所有已知的伪造方法,以及一些通用的异常检测方法。由于如上所述,图像伪造技术正在经历一种繁荣,后一种方法变得更加重要。

有哪些图像篡改技术?

首先,让我们讨论一下我们在处理什么。

摄影锻造几乎和摄影本身一样古老。在下面的图片中,你可以看到一张被篡改的 19 世纪的照片:

更多的例子可以在哈尼·法里德的数字取证圣经——书中找到。

“手动”伪造—Photoshop

随着数码摄影的出现,图像篡改变得越来越容易和常见:最常见的一种被称为“拼接”和“复制-移动”,或大多数人所说的“Photoshop”。

这些方法包括将一幅图像的一部分移植到另一幅图像中。为了让它看起来更真实,伪造者还会做一些数字修饰。这些技术的结果可能很难用肉眼区分。

修图本身也是一种篡改方式,尤其是在时尚照中。

如前所述,photoshopping 并不总是容易辨别,但使用一些方法,将在稍后讨论,研究人员在事情的顶部。然而,技术让事情变得更难(或者更容易,取决于你站在哪一边)。具有讽刺意味的是,深度学习成为图像分类的主要方法,也允许一种新的、开创性的伪造物——生成模型。

基于生成模型的方法

自 2014 年出现一般敌对网络以来,很明显,图像伪造将永远不会相同。一个算法从字面上从零开始创造一个图像(例如一张脸)的能力既令人惊讶又令人恐惧。

GANs results throughout the years (none of the above is a real person)

在他 2014 年的开创性工作中,Ian Goodfellow 从概念上展示了在小规模(28 X 28)下创建逼真的人脸是可能的。这一概念很快成为现实,2018 年底,Nvidia 研究人员推出了能够以高分辨率创建超现实人脸的。但这远不是对 GAN 的唯一研究:令人印象深刻的是,研究人员做了不同的调整,创造了新的假图像。我们只能想象这种技术的未来,但同时,让我们看看其他变体的一个不完全详尽的列表:

CycleGan

2017 年,2 部令人惊艳的作品出自阿列克谢·埃夫罗斯实验室— pix2pixCycleGan 。你可以在我之前的帖子中读到它们。

这两个作品都允许将图像从一个领域“复制”到另一个领域:将马转换成斑马,将狗转换成猫等等。

********

假视频——重现

Nicholas Cage as Marlon Brando as The Godfather

除了创建假图像,深度学习技术更进一步,允许创建假视频。

这个领域的真正转折点(和许多其他场合一样)不是技术,而是文化。2018 年 1 月左右,Reddit 上开始出现高质量的假视频。他们中的许多人将尼古拉斯·凯奇的脸植入不同的场景,但并不是所有人都是 SFW。这立即引发了媒体对这一领域的关注(以及世界末日的预言)。

但深度伪装并不孤单:最*这种技术激增,它们在真实性和易于训练方面变得越来越先进。从玩具“换脸”app 开始,通过 face2face 、深度造假、综合奥巴马、到最*三星的少数镜头说话头像。

目前在这个领域最令人印象深刻的工作(目前,事情进展很快)是深度视频肖像— 在这个工作中,研究人员使用了一种多步骤的方法,来“操纵”一张全脸。他们首先从源视频和目标视频中提取面部特征,如姿势、表情、眼睛坐标等,然后使用编码器-解码器生成一个假视频,不仅可以控制嘴部运动和面部表情,还可以控制头部运动。

Deep video portrait

数字取证

因为这个帖子不是关于图像生成,而是关于我们如何检测它们,在看到一些伪造技术后,我们想检查一下防守团队提供了什么。如前所述,数字取证方法可以分为三种。良好的检测操作应结合使用以下各项:

  1. 基于特征的 —在某一类(或多类)伪造品中存在一种伪造品的情况下——大多适用于经典方法。
  2. 监督学习 —使用深度学习分类器(主要是 CNN)来学习某些类型的伪图像—适用于经典方法以及生成模型,例如 GANs。
  3. 无监督/通用——试图捕捉真实图像的一些本质,以检测新类型的伪造(模型以前没有见过)。这可以看作是一种异常检测。

所有上述方法都有其优点和缺点,但由于生成方法变得更加现实,2 和 3 变得更加突出。

我们在上一部分中目睹的篡改技术全部(或大部分)都是由深度学习社区提供的公开可用的。然而,它不必永远保持这种状态:在随后的几年里,不同的公司和政权将有自己的秘密技术,这是非常合理的。

基于特征的

2004 年,哈尼·法里德阿林 波佩斯库发表了第一篇关于使用数字文物识别假图像的作品。数码相机具有不同的伪像,这些伪像源自摄影硬件、软件或特定于图像的压缩技术。因此,发现这些假照片的数字方法的出现只是时间问题。法里德和波佩斯库使用了一种特殊的相机过滤器(CFA)来识别图像的虚假部分。

从那以后,出现了更多的手工制作技术:

使用 JPEG“签名”

JPEG 是数字媒体中最常见的图像压缩协议。你可以在这里阅读它的细节。简而言之,每个图像都有自己的编码方式来优化文件大小。可以利用不同图像的编码差异来检测伪造图像(拼接)。这里有一个这样工作的例子。

Splicing artifacts caused by JPEG compression

相机伪影

如前所述,数码相机在硬件或软件中也有其制品、结构。每个相机制造商、型号或软件版本都可能有自己的签名。比较图像不同部分的这些特征或相机噪声可能会产生一个好的分类器。

摄影艺术品

与上面的逻辑相同,篡改图像可能会扭曲照片的自然条件。使用这种特征的数字测量(例如照明、“像差”)在伪造检测中也是有用的。

生成模型工件

当前的生成模型也遭受已知的伪像,有些甚至是可见的,如不同的不对称,奇怪的嘴的形状,不对称的眼睛等等。这些人工制品在这个作品中被利用,使用经典的计算机视觉将假图像与真图像分开。然而,考虑到生成模型的进步,这些人工制品不一定存在于明天的赝品中。

Asymmetric eyes in GAN face

所有上述方法都是伟大和聪明的,但是一旦暴露,他们就可以被伪造者所穿透。这就是机器学习的用武之地:它有点像一个黑匣子,可以在伪造者不知道其细节的情况下学习假图像。

监督深度学习

随着深度学习的兴起,研究人员开始使用深度网络来检测虚假图像是很自然的。

直观上,很容易从不同类型的伪造类中获取图像,并开始训练分类器和检测器。让我们来看看一些备受瞩目的作品。

使用新 conv 层的通用图像处理检测

在这项工作中,研究人员设计了一个特殊的卷积层,它通过对过滤器施加约束,旨在捕捉操作,而不是图像语义内容。经过对中值滤波、高斯模糊等不同修图方法的测试,该方法达到了> 95%的准确率。这项工作的目的是通用的,然而,据称它的设计仅限于 photoshopping 和篡改,而不是 GANs 之类的。****

Mesonet

Mesonet 是一部专注于也许是最痛苦的问题的作品:篡改视频中的人脸。具体来说就是 face2face 和 deep fakes(见上图)。由于视频(特别是数字化的)本质上是一系列图像,研究人员使用深度网络解决这项任务,并使用非常标准的网络获得了良好的结果。总之,这项工作除了是最早解决这项任务的工作之一之外,并没有什么特别之处。

甘实验

正如我们前面所看到的,甘人只是不断出现。训练一个模型来区分真实图像和特定的 GAN 并不困难。但是为根训练一个模型也是不切实际的。**

一些研究人员非常乐观,试图将一个分类模型推广到不同的 GANs,这些 GANs 与他们所接受的训练不同。换句话说,他们在一种 GAN(PG-GAN—style GAN 的前身)上训练了一个深度网络,并试图在另一种 GAN(DC-GAN,WGAN)上进行推断。

正如预期的那样,结果表明,即使研究人员进行了预处理,也没有任何普遍性。

还有很多类似的方法,但概括起来——意思是,识别从未见过的伪造品,学习研究需要开始变得更有创造性。

通用方法

我们知道,深度学习不仅仅局限于朴素的分类器。有许多种 un/self/semi-supervised 模型可以处理少量数据、n 次拍摄和其他任务。

让我们来看看用什么样的思路来解决“万能假像”的问题。

自洽性

这种方法的一个很好的例子可以在作品 打击假新闻:通过学习自洽的图像拼接检测 中找到。这篇文章来自阿列克谢·埃夫罗斯的工作坊,大部分人都知道他在自我监督技术方面的工作。这部作品与他早期的作品有一些相同之处。研究人员整合了一个 4 步工作流程,其中他们:

  1. 学习预测图像的 EXIF元数据。*
  2. 将图像分割成许多小块,比较每一对的预测 EXIF 值。
  3. 看起来具有不匹配的 EXIF 值的切片将被分类为取自不同的图像,因此该图像将是假的。
  4. 分类将用于提供移植区域的热图。

A detection of “spliced” Keanu Reeves

但是什么是 EXIF 呢?在数字媒体中,图像(和一些声音文件也是如此),EXIF,可交换图像文件格式,是一种元数据签名的文件。图像的 EXIF 应该包括相机(或扫描仪)型号、原始图像大小、照片属性(闪光灯、快门打开时间)等等。

显然,并不是所有的网上照片都有完整的 EXIF,尤其是那些造假的照片。这正是研究人员参与预测每个图像/补丁的 EXIF 的原因。现在你可以看到,这项任务在某种程度上是无人监管的,因为有大量的在线图像和现成的 EXIF 可供学习。更准确地说,使用了 40 万张图像来训练这个模型。

该模型在 photoshopped 图像上取得了良好的结果,但令人惊讶的是,它在 GaN 生成的图像上也取得了一些成功。

法医转移

Luisa Verdoliva 是一名意大利研究人员,她和她的团队拍摄了一些有趣的照片来推广图像取证。在这个作品中,他们训练了一个有点不同的模型,这将有望更具普遍性。他们所做的是使用自动编码器,这是一种旨在将图像“收缩”成向量,然后重建它的网络。这个向量被训练成分类器来确定图像是真是假:

A scheme of the forensic transfer autoEncoder

他们还尝试迁移学习:在数据集 A 上训练他们的网络,用数据集 B 的一个小子集重新训练它,并尝试在数据集 B 上进行推断。

他们在几个数据集上来来回回地做这项工作,并得到合理的结果(75-85%的准确率)。这些结果优于其他网络(其中一些在上面的监督学习部分讨论过)

ForensicTransfer — an example transfer learning results

噪声印迹

来自上述团队的另一种无人监督的方法,类似于自洽,试图预测图像碎片之间的 PRNU 噪声(一种特定类型的相机噪声)。它报告了多个数据集的最新结果(*均马修斯相关度为 0.4,而自洽度为 0.33)。

A set of predictions: noise print on the right. EXIF-SC is self-consistency.

深度假动作旋转

考虑到以上所有情况,似乎通用方法必须更积极地解决生成性伪问题。他们确实做到了:一些研究人员抓住机会,试图创造出某种甘将军猎人。这意味着能够识别 GAN 生成的图像,而无需对其种类进行专门培训。让我们来看看其中的几个:

学习在野外检测假的人脸图像

在一篇有点仓促的文章(只有 4 页)中,研究人员使用非耦合的图像对来训练一个深度网络,以对相同/不同的图像进行分类(真实和真实,假的和假的,真实和假的),这种有点天真的结果在不同的 GANs 上得到了合理的结果,尽管对所有的 GANs 都进行了训练。

GANs 会留下人工指纹吗?

在本文中,Luisa verdolva使用她最喜欢的噪声图(PRNU),用不同的训练数据集来尝试和表征几种不同的 GAN 模型(PG-GAN,cycle-GAN)。他们的成功表明,实际上每个 GAN(达到训练集水*)都有自己的噪声指纹,类似于相机的噪声指纹。不幸的是,这种方法对检测假图像的帮助主要是理论上的,至少目前是这样。

作品分类

最终,我们可以交叉生产锻造检测方法,并将大多数方法放入一个(或多个)盒子中:****

在我们在 Cyabra 的工作中,我们面临许多上述挑战,因此我们采用类似的策略:使用监督方法来检测已知的伪造品,同时进行调整和测试,希望能推广到其他伪造品。

不知何故,也许令人惊讶的是,我们已经发现一些通用或半通用的方法可能出乎意料地有效。例如,发现自洽工作,(通过一些调整)可能是有效的分类 GAN 创建的图像。

摘要

这就是了,如果你已经到达这里,你就成功地穿越了图像和视频取证的泡沫领域。

正如我们在上面看到的,大部分工作都集中在对特定篡改进行分类的方法上。然而,一般的方法是新的,仍然是稀疏的。

很明显,这个领域很快将不再是研究人员和爱好者的狭窄领域,而是开始涉及普通人——他们希望重新获得辨别真假的能力。

军备竞赛不会很快停止,但我们应该期待看到法医们齐心协力,想出一些更好的方法来反击伪造者。

*值得注意的作品 监督 学习

我希望你喜欢阅读这篇评论!欢迎随时 关注 我,并查看我的网站—www.shibumi-ai.com

热门歌曲有什么共同点吗?

原文:https://towardsdatascience.com/do-hit-songs-have-anything-in-common-37599940590?source=collection_archive---------19-----------------------

使用 Python 分析 Spotify 的数据

Source: unsplash

当你登录 Spotify.me 时,你会得到一个个性化的摘要,说明 Spotify 是如何通过你在 Spotify 上听的音乐来理解你的。这是非常酷的!

作为一个经常听音乐、喜欢摆弄数据的人,这启发了我,让我看看是否可以分析自己的音乐。

我也很好奇,想知道化妆是否有某些成分会影响歌曲。是什么让他们变得酷?为什么我们会喜欢热门歌曲,热门歌曲是否有一定的「DNA」?

目标

这让我试图用这篇文章中 Spotify 的数据来回答两个问题:

  1. 我的音乐播放列表是什么样的?
  2. 热门歌曲中有什么共同的音频属性吗?

工具

幸运的是,有非常简单的工具可以帮助我们连接到 Spotify,检索数据,然后将其可视化。

我们将使用 Python 3 作为编程语言, Spotipy ,Python 库允许你连接到 Spotify Web API ,我们将使用 plot.ly 和 Seaborn 进行数据可视化。

资料组

每年年底,Spotify 都会编辑一个当年最常播放的歌曲列表,这个列表有 100 首歌曲。我使用的数据集已经在 Kaggle 上可用:2018 年 Spotify 热门曲目。Spotify 的前 100 首歌曲似乎是一个合理的数据集,可以考虑作为我们的热门歌曲,你不觉得吗?

我们开始吧!

首先,你需要在developer.spotify.com创建一个账户。之后,您可以直接访问 Spotify Web API 控制台,开始探索不同的 API 端点。

注意:我在整个项目中使用的代码的链接在博文的末尾。

在连接到 Spotify Web API 之后,我们将使用 Spotipy Python 库创建一个 Spotify 对象,然后我们将使用它来查询我们的 Spotify 端点(我知道有点满嘴😃).

*import spotipy
from spotipy.oauth2 import SpotifyClientCredentials**from spotipy import util**cid =”Your-client-ID” 
secret = “Your-Secret”**client_credentials_manager = SpotifyClientCredentials(client_id=cid, client_secret=secret) 
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)*

我的播放列表的探索性数据分析

这是数据科学中最重要的步骤之一。我们的目标是了解我的播放列表中的音乐类型,检索任何有趣的观察结果,并将其与 2018 年 100 首最佳歌曲的音频特征进行比较。

绘图艺术家频率

Artists in my playlist by frequency

通过观察这个直方图,我们可以看到艺术家在我选择的播放列表中出现的频率。

音频功能

现在我们来看看这个播放列表中歌曲的音频特征。Spotify 已经整理了 Spotify 上每首歌曲的 音频功能 列表!下面是我们将使用的功能的摘要:

乐器性:预测一个音轨是否不包含人声。“Ooh”和“aah”在这种情况下被视为乐器。Rap 或口语词轨道明显是“有声的”。乐器度值越接* 1.0,轨道不包含人声内容的可能性就越大。

能量:这是一个从 0.0 到 1.0 的度量,代表强度和活动的感知度量。通常,高能轨道感觉起来很快,很响,很嘈杂。例如,死亡金属具有高能量,而巴赫前奏曲在音阶上得分较低

acoustic ness:0.0 到 1.0 之间的音轨是否声学的置信度度量。1.0 表示音轨是声学的高置信度。

活跃度:检测录像中是否有观众。较高的活跃度值表示音轨被现场执行的概率增加。高于 0.8 的值表示该轨迹很有可能是实时的。

语速:“语速检测音轨中是否存在口语单词”。如果一首歌曲的语音度高于 0.66,它可能是由口语词组成的,0.33 到 0.66 之间的分数是一首可能同时包含音乐和词的歌曲,而低于 0.33 的分数意味着这首歌曲没有任何语音。

可跳舞性:“可跳舞性描述了一首曲目在音乐元素组合的基础上适合跳舞的程度,包括速度、节奏稳定性、节拍强度和整体规律性。值 0.0 最不适合跳舞,1.0 最适合跳舞”。

效价:从 0.0 到 1.0 的一个量度,描述一首曲目所传达的音乐积极性。具有高价的音轨听起来更积极(例如,快乐、愉快、欣快),而具有低价的音轨听起来更消极(例如,悲伤、沮丧、愤怒)

Distribution of music styles in my playlist

从观察结果来看:

  • 我的播放列表中的大多数歌曲都有广泛的可跳性分布,并没有太多的“快乐”歌曲,正如 0.5 以下的歌曲在中的高频率所示。所以你可以说我喜欢适合跳舞的歌(这是真的!)
  • 对于演讲、工具性和一点点 T2 的活力来说,这是一个向下的陡坡。这向我们表明,我的播放列表中的音乐通常不那么有声有色,没有乐器,也很少有现场观众的歌曲。
  • 声音度在 0 和 1 之间*似均匀分布,这表明在我的音乐选择中没有对该属性的偏好。(我通常喜欢原声歌曲,但我不会出去寻找一首歌的每一个原声封面)。
  • 最后,能量呈现正态分布,两端的尾部表示被添加到我的播放列表的可能性较小。所以基本上我喜欢能量一般的歌。
  • 我的歌一般没那么受欢迎-__-

2018 年前 100 首歌曲的探索性数据分析

将数据集从 Kaggle 下载并导入到我们的应用程序后,我开始根据数据集中最受欢迎的艺术家出现在列表中的次数来分析他们。

Artist in Top 100 Songs of 2018 by frequency

2018 年 100 首歌曲中出镜率最高的艺人

Code snippet

Post Malone (src:latimes.com) and XXXTENTACION (src:thesource.com)

现在让我们探索一下我们数据集中前 100 首歌曲的音频特征,看看它们是什么样子的!我们将绘制与播放列表相同的直方图,以便稍后进行比较。

Distribution of music styles in the top 100 songs of 2018

通过观察直方图,我们可以看到前 100 个图表中的曲目是:

  • 可舞性和能量方面非常高,但在活跃度语速声音方面很低(我们已经可以看到一些迹象,表明我的播放列表不如前 100 名那么酷😞).

例如,来自我们数据集的德雷克的“在我的感觉中”,是高度可跳舞的,并且也具有相对高的能量值。

最后,我决定绘制一个前 100 首歌曲的雷达图,并叠加我的播放列表的音频特征,以便于比较。

Spotify 的前 100 首歌曲是蓝色的,而我的热门歌曲是橙色的。

结论

所以我想我在这篇文章的开头已经找到了我的两个问题的答案。我想看看我的音乐是什么样的,似乎有流行歌曲的基因。我的播放列表中的音频功能有点类似于前 100 首歌曲,但我有更多的原声歌曲和一些现场歌曲。

想做一首热门歌曲?确保它适合跳舞,有很多能量和一点价值(积极和感觉良好的氛围)。

我对结果很满意,但我想在另一篇文章中继续这个话题。

以下是我推荐的下一步:

  • 了解如何使用您的播放列表来确定您的个性,并推荐您可能喜欢的广告。
  • 使用机器学习聚类算法,K-Means,看看哪些歌曲与你的相似,你可以使用它来最终发现你可能喜欢的新歌。
  • 使用机器学习根据歌曲的音频特征预测歌曲的“流行度”

你可以成为中等会员享受更多这样的故事。

你可以在 GitHub 上获得整个项目的代码。

感谢 艾尔文·钟阿什里斯 John Koh就此主题发表的有益文章。Spotify和 Spotipy,感谢给力的 API 和库!****

我有足够的钱退休吗?

原文:https://towardsdatascience.com/do-i-have-enough-money-to-retire-af7914a07b34?source=collection_archive---------16-----------------------

蒙特卡罗模拟如何用于模拟退休不确定性的定量探索

如果你想自己运行代码,你可以在我的 Github 这里找到它。

这个例子只是为了说明的目的。 它不应以任何方式、形态或形式被视为财务建议

“我以 20%的信心估计,有 75%的可能性你的钱足够支付你的退休金。”

等等,什么?太令人困惑了。

没有财务顾问会对你这么说——但我希望他们会这么说。客户需要他们雇佣的人的信心和确定性,金融专业人士从第一天起就接受培训,自信地传递他们的信息(毕竟,他们试图出售一项服务)。

但事实是,定量模拟某人的退休极其困难,充满了不确定性和未知性。

这种差异的主要驱动因素是以下方面的不确定性:

  1. 投资回报
  2. 通胀
  3. 退休后你每年会花多少钱
  4. 你会活多久(以及你会有多健康)
  5. 黑天鹅——难以预测的事件,如金融危机、战争、白鬼等。
  6. 模型误差(错误估计和假设产生的误差)
  7. 社会保障、所得税税率、资本收益税率等的变化。

下面我们就用 蒙特卡洛模拟 来详细定量探究一下 1 号到 4 号的车手。其他的也很重要,但是我不认为你想读一篇 45 分钟的博文;)所以我们将把它们留到下一次。

在这篇文章的结尾,我们将会更好地理解为什么尽管分析和计算能力有了显著的进步,却回答了“我到底需要多少钱”这个古老的问题依然充满挑战。

我们示例的假设

Our client, Randy

假设我们为一家名为 Lazy Advisors,LLC 的金融公司工作。我们的一个相对更懂财务的客户,兰迪,来做他的退休评估。以下是他的统计数据:

性别和年龄:男,55 岁

婚姻状况:单身(准备交往)

目标退休年龄:60 岁

投资组合价值:500,000 美元(他将不再存钱)

我们为 Randy 管理的投资组合相当保守——60%投资于股票(美国大盘股和新兴市场),40%投资于美国国债。

由于我们公司很懒(因此得名),我们只投资 5 种资产:国库券(基本上是现金)、国债、标准普尔 500、大宗商品和新兴市场股票(中国、巴西、俄国等)。).

我们使用均值方差投资组合优化来估计最优投资组合的投资权重(最高性价比),有以下约束条件:

  • 权重总和必须为 1
  • 权重必须介于 0 和 1 之间(无卖空)
  • 对标准普尔 500、大宗商品和新兴市场股票的配置总和必须为 0.6

我们的优化器生成一个投资组合,其配置如下: 40% 美国国债, 35% 标准普尔 500 指数, 25% 新兴市场股票。预期年名义收益率为 5.1%预期年标准差为 10%

我今天不会详细讨论这个问题,但请记住,最佳投资组合权重对我们对每种资产类别的预期回报、波动性以及与其他资产的相关性的估计极其敏感。

出于好奇,这里是我们对预期收益和波动性(标准差)的估计。这些估计来自 BNY 梅隆大学的这份报告。

Return and Risk Assumptions

最后,以下是我们对资产类别相关性的估计:

Correlation Matrix Assumptions

投资回报的不确定性

兰迪坐下后问我们的第一件事是,“我不打算在退休前存更多的钱。以我现在所拥有的,你认为我五年后退休时会有多少钱?”

由于我们知道 Randy 的投资组合的预期回报率为 5.1%,而我们又比较懒,我们就给他看下图,告诉他退休时(五年后)他的投资组合的中值将是 63 万美元。

Looks pretty good!

但是兰迪需要更多的信息。他知道中位数只是许多潜在结果中的一个,并想知道他可以预期多少变化。渴望去打高尔夫球,我们叫来了我们的实习生,让他处理数据。在一些巧妙的 Python 编码之后,他向我们展示了这个情节:

Wow, that is a wide range of outcomes!

什么!?我们的实习生会让我们错过开球时间的!我们问我们的实习生他是如何生成这个图表的,他告诉我们:

他使用 蒙特卡洛模拟 对兰迪的投资组合进行了 5000 次模拟,然后绘制了一段时间内的财富中值(蓝线)以及一段时间内的第 5 和第 95 百分位财富(蓝色阴影区域的底部是第 5 百分位财富,顶部是第 95 百分位财富)。

他还提到,他假设兰迪投资组合中的投资回报遵循正态分布(这是一个潜在的危险假设,我们将在未来的帖子中探讨),并根据我们之前分享的关联热图相互关联(Smartypants intern 先生使用 Cholesky 分解使他的随机正态冲击相互关联,详情见代码)。

关于蒙特卡洛模拟的简要说明

在蒙特卡罗模拟中,我们一遍又一遍地运行实验,每次都收集结果(在这种情况下,Randy 60 岁时的投资组合价值)。关键是我们通过一些输入注入了随机性。这里,我们使用相关随机正态冲击来模拟投资回报的波动性。

你可以把蒙特卡洛模拟想象成掷骰子,每个输入的值我们不确定,用一个骰子来表示。我称它们为魔术骰子,因为根据你的需要,它们可能呈现不均匀的分布,或者一些骰子滚动可能是相关的(神奇地!)与其他骰子的滚动。因此,每个单独的模拟只是我们所有神奇骰子滚动的结果。蒙特卡洛模拟只是将我们神奇的骰子滚动许多次的过程(一旦我们完成,我们可以使用蒙特卡洛模拟结果来*似我们试图建模的事物的概率分布,例如 Randy 的投资组合)。

回到兰迪

以前,我们的实习生完全被他的解释搞糊涂了,所以我们瞪着他,要求,“请用简单的英语解释!”

我们勤奋(脾气好)的实习生回答道:

“在我进行的 90%的模拟中,兰迪的投资组合最终价值在 435,000 美元到 884,000 美元之间。”

现在兰迪很担心,“如果其中一个糟糕的场景实现了,那么由此产生的财富够我生活下去吗?”

正当我们要告诉他不要杞人忧天时,我们的实习生大声说道,“兰迪先生,你还需要记住考虑通货膨胀。你现在花的钱可能并不代表你将来需要花多少。”

多。我们的实习生是如此的好…

通货膨胀的不确定性

快速回顾一下— 通货膨胀是指物品(从拿铁咖啡的价格到你付给房东的租金)价格随着时间推移而上涨的趋势

在退休模拟中,通货膨胀通常被建模为对投资组合回报的拖累。例如,如果兰迪的投资组合名义收益率为 6%(名义=通胀前),而当年通胀率为 3%,那么他的通胀调整回报率将为 6%-3%=3% 。通胀只是偷走了一半的回报!

暂时离开我们和 Randy 的谈话,让我们了解一下通货膨胀是如何驱动退休不确定性的。下面的图表显示,仅仅改变我们的通货膨胀假设(而完全不改变投资回报),我们得到的结果就会有显著的变化。虽然 2%似乎是对未来通胀的合理估计,但其他值也在可能范围内(例如,日本经历了几十年的通缩,美国在整个 20 世纪 70 年代经历了两位数的通胀,大萧条期间经历了严重的通缩)。

Inflation can cause significant variation in wealth outcomes

跑题了,让我们回到我们的客户,兰迪。不幸的是,他现在希望我们模拟他的通胀调整后的退休后财富变化。这样的监工…他也给我们一些更多的信息。Randy 希望每年从社会保障中获得一些钱,所以他估计他每年只需要从他的投资组合中支出 28,000 美元来维持他目前的生活方式。这 28,000 美元是通货膨胀调整后的价值——这意味着如果今年的通货膨胀率为 1%,那么明年 Randy 在名义上需要 28,280 美元。

年度投资组合提款(经通货膨胀调整):28 000 美元

预期死亡年龄:85 岁

所以我们跳上笔记本电脑,开始编码。我们决定将通货膨胀建模为一个正态分布的变量,期望值为 2%,标准差为 1%。此外,为了简化分析,我们忽略了通货膨胀和投资回报之间的相关性。经过一些数字运算,我们得出了下面的图表:

Inflation is quite the drag

我们的实习生向兰迪解释道,“兰迪先生,我们对你 85 岁时财富的中值估计是 81,000 美元……当我们预计你嗯……去世时。所以在我们的中间方案中,你确实有足够的钱。我们还包括了无通胀案例(红线),向你展示我们对通胀的估计是如何对你的财富产生负面影响的。”

“然而,在我们运行的 40%的模拟中(我们运行了 5,000 btw ),您用完了钱!如果你的投资组合枯竭了,你将只有社会保障来度过余生……”

他继续说道:“我还为你做了这个柱状图,以便更好地展示你的财富成果。”(我们的实习生就是这么爱显摆)

That’s a lot of observations to the left of the red line (which denotes $0)

生活费和死亡年龄的不确定性

现在兰迪想知道,如果他想在退休后一直保持盈利,有哪些事情是他绝对必须避免的。

我们的实习生再次大声说道(叹气…),并说:“没有人能保证你在整个退休期间能够保持 28,000 美元的通胀调整支出水*。你可能会遭遇不可预见的医疗费用、更高的税收等。因此,如果你最终增加支出,我们应该看看我们的预测会有什么变化。”

“兰迪先生,我们模拟了如果你退休时花了 38000 美元(而不是 28000 美元)会发生什么。就像之前我们做了 5000 次模拟一样。现在,在我们进行的 76%的模拟中,你最终没钱了(除了社保)!以前你只用了 40%。

If Randy overspends, he is in big trouble

“如果你最终比预期多活了 5 年(而是在 90 岁去世),在我们为你进行的 56%的模拟中,你最终会耗尽金钱****,大大高于之前的 40%(当时我们假设你会在 85 岁去世)。

Living 5 years longer than expected depletes poor Randy’s portfolio

结论

最后兰迪满意了。很担心但是很满足。

他看着我们说。

“我今天学到了一些东西。你可以为我运行数千次模拟(由于投资回报和通货膨胀,这些模拟已经有了自己的方差),但稍微调整一下假设,一切都会再次改变!这就像方差叠加在更多的方差之上!如此多的不确定性…

我们不知道他在说什么,但是我们的实习生给 Randy 看了下面的图表。

High level breakdown of the sources of variance (a.k.a. uncertainty)

“兰迪先生,我们可以把方差分成两部分:已知和未知。我们之前详细探讨过的已知变异来源,来自投资回报、通货膨胀、死亡年龄、支出等的波动。这些变异来源中的每一个都相互叠加,相互复合。但也有‘未知的未知’——造成隐藏变化的东西,我们无法建模,因为我们只是不知道它,或者我们知道它是错的。”

Randy 说他需要几天时间来消化所有的发现,但是他会在一周内和我们的实习生安排一次会面来讨论下一步的工作。似乎我们的实习生偷走了我们的客户。我们决心在未来雇佣更多实习生之前更加努力地思考(我们最初雇佣他只是因为他的拿铁艺术令人难以置信)。

来源:10 年资本市场回报假设,BNY 梅隆

为“gram: Instagram 风格的字幕生成器”而做

原文:https://towardsdatascience.com/do-it-for-the-gram-instagram-style-caption-generator-4e7044766e34?source=collection_archive---------18-----------------------

使用 Keras CNN-RNN 框架为 Instagram 照片生成标题

卡米尔·鲍曼、塞加尔·杜瓦和埃里卡·中川

1。简介

图像字幕是指使用自然语言处理(NLP)和计算机视觉(CV)生成图像的文本描述的深度学习应用。这项任务需要一种算法,不仅要理解图像的内容,还要生成与其解释相关的语言。我们希望通过专门为 Instagram 图片生成标题来进一步挑战这一挑战。

你会如何描述下面的图片?

一个简单的字幕生成器可以将图像描述为类似于“四个朋友在一个粉红色的房间里”的东西。微软的字幕机器人回答说“我认为这是一群人对着相机摆姿势”。你不也是这么描述的吗?但是如果你想在 Instagram 上发布这张图片,那会是它的标题吗?

Instagram 标题往往比简单的描述符更高级,由双关语、内部笑话、歌词、参考文献、情感和讽刺组成。在某些情况下,字幕可能与呈现的图像完全不相关。在这种情况下,用户@sejaldua99 发布了上面的图片,标题为“奥胡斯走的路 2 crazzyyy”。

我们的工作旨在用特定的词汇和表达方式生成符合特定风格的字幕。为了实现这一点,我们的模型由卷积神经网络(CNN)和长短期记忆(LSTM)递归神经网络(RNN)组成。

2。先决条件

这篇博客文章假设熟悉基本的深度学习概念,如卷积神经网络(CNN)、递归神经网络(RNNs)、梯度下降、反向传播、过拟合、概率、Python 语法和数据结构、Keras 库、TensorFlow 等。

3。数据收集

我们使用从 GitHub 用户@timgrossmann 那里获得的 Selenium 驱动的档案爬虫抓取 Instagram。scraper 为每个 Instagram 用户构建了 JSON 对象,包括帖子信息、位置信息、每个帖子的评论、每个用户交互的时间戳和数字赞等。我们编写了一个简单的脚本来解析我们收集的个人资料目录中的每个 JSON,并从那里提取 Instagram 照片和标题。

我们的数据集由关注我们账户的 Instagram 用户的帖子组成:@camillebowman、@sejaldua99 和@erikaaanakagawa。由于 scraper 需要通过 Headless Chrome 登录 Instagram,我们只能从我们关注的用户和公共档案中获取信息。

network visualization of the data source: 3 core nodes and one degree of follower connections

the code to produce the network visualization above

上面的网络是由 networkx 和 netwulf 库组成的,描绘了我们数据的范围。值得注意的是,因为我们从三个主要的独特人群中收集数据,所以我们引入了一些轻微的偏差。例如,如果我们的神经网络生成了与“约翰·霍普金斯”、“米德尔伯里”或“塔夫茨”相关的标题,这不会太令人惊讶,因为我们每个人都关注了许多来自自己大学社区的用户,而这些用户碰巧发布了关于他们各自校园发生的事件。

我们在两周的时间里收集了数据,整日整夜地搜集用户资料(我的电脑感觉睡眠严重不足)。我们设法从不到 3000 个用户那里获得了 100 个帖子,但是并不是所有来自这些用户的数据都进入了我们的 CSV 文件。事实证明,由于 Chrome 驱动程序的变化、滚动速率错误以及自脚本编写以来的 Instagram 更新,我们的 scraper 相当吃力——准确地说,23%的时间都是如此。

考虑到所有因素,我们使用的 profile crawler 在帮助我们获得一个巨大的数据集来训练我们的神经网络方面仍然非常有用。

4.数据清理

CLEANING

与任何数据科学项目一样,80%的工作是获取数据、存储数据、解析数据和清理数据。JSON 的清理包括文件系统遍历和一些非常复杂的条件逻辑。

summary report: composition of the dataset

我们做了一些深思熟虑的选择来构建一个数据集,我们认为这将最小化偏差,并尽可能提供最多样化的图像-标题对集合。设计选择如下:

  • 没有图片,没有说明,收藏:我们删除了所有没有说明的帖子,丢弃了收藏和视频。不幸的是,这消除了大约 30%的未清理数据集,但相对于我们的大量帖子——总共约 130,000 篇——这并不太昂贵。
  • 帖子太少:我们排除了发帖量少于 10 篇的用户,因为一个发帖量少于 3 篇的用户与一个发帖量少于 100 篇的用户相比,其影响力似乎相差了一个数量级,我们希望纠正任何可能引入的偏差。在剔除帖子太少的用户后,每个用户的帖子数量中位数从 21 个飙升到 46 个,这非常接*理论中位数。
  • 低粉丝数(low num followers):insta gram 是一个*台,人们喜欢在这个*台上讲述有趣的故事,分享有价值的生活更新。年轻一代的 Instagram 用户通常有两个 Instagram 账户,一个用于以更公开的方式分享照片,另一个用于向更亲密的朋友分享照片和故事。我们想排除这些更小、更私人的帐户,因为这些类型的帐户的标题内容几乎从不与相应的图像匹配。出于这个原因,我们丢弃了所有关注者少于 200 人的用户的帖子数据。
  • 非英语:虽然神经网络有令人难以置信的智能潜力,但我们想避免的一件事是用不同语言的字幕混淆我们的模型。想象一下,一个人要花多少时间和精力才能流利地掌握 5 种以上的语言。我们发现不同语言的字幕会成倍增加我们的训练时间,所以我们安装了一个名为 pyenchant 的库,它主要检查一个给定的单词是否在英语词典中。我们规定,如果标题的文本部分(不包括标签和提及)超过 5 个单词,并且超过 80%的单词不在英文目录中,我们会将标题指定为“非英文”并丢弃图像-标题对。只有 300 多个帖子属于这种情况,我们认为我们能够保留类似“更新:我要搬到法国去了。这就是生活。”点击链接查看所有被丢弃的非英语字幕。

pie chart representation of the dataset (blue represents viable data, red represents discarded data)

在丢弃了大约 38%的数据集之后,我们决定简要地研究一下我们的可行数据的组成。我们觉得 Instagram 的标题是独一无二的,因为它们的结构高度流动。也就是说,标题可以由字母文本、特殊字符、标签、提及、表情符号或以上所有内容的组合组成。我们希望量化我们正在处理的内容,因此我们解析了每个标题中的字符,如“#”和“@”,并使用 Python 表情库来筛选表示表情的正确 unicode 符号。按照流行程度从高到低的顺序,标题包含表情符号,然后是标签,然后是提及,然后是引用。不到一半的可用 Instagram 标题不包含任何有意义的特殊字符。

5。网络架构

我们的网络受到了 Jason Brownlee 的 如何从零开始开发深度学习照片字幕生成器 文章的启发。

我们将用于图像分类的卷积神经网络与用于序列建模的递归神经网络相结合,创建了一个为图像生成 Instagram 标题的单一神经网络。

换句话说,我们使用了一个在 ImageNet 数据集上预先训练的 16 层牛津视觉几何小组(VGG)模型来解释照片的内容。我们移除了 CNN 的最后一层,以收集从模型中预测的提取特征,用作生成字幕的 RNN 解码器的输入。

我们还使用了一个标记器来创建一个包含标题中所有字符的“字母表”。与 Jason Brownlee 的文章不同,我们决定在字符级别而不是单词级别进行标记,并包括标点和大写。我们认为这将更好地反映我们试图生成的标题,因为它允许我们保留标题的关键方面(如表情符号和标签),并让我们的网络更好地生成表情符号。然后,我们将每个标题转换成一个数字数组进行编码,每个索引代表一个字符。最后,为了便于训练,我们在每个编码后的字幕前加入了开始序列和结束序列。

preprocessing images and obtaining features vectors from CNN

tokenizing captions on a character level

我们为每个标题创建了输入-输出向量,其中输入是图像的特征向量和标题的前 n 个字符,输出是标题中的 n+1 个字符。我们为字幕向量中的每个字符做了一个输入输出配对。第一个配对是图像和开始序列作为输入,标题中的第一个字符作为输出,最后一个配对是图像和整个标题作为输入,结束序列作为输出。由于我们只能使用 10,000 幅图像进行训练,为了防止我们的输入输出配对数量激增,并限制任何单个字幕的偏差,我们只使用字幕不超过 60 个字符的字幕-图像配对。

然后,我们训练一个长短期记忆(LSTM)解码器作为语言模型,它以特征向量和编码字符数组作为输入,并产生一个编码字符作为输出。

building the layers of the neural network

summary report: structure of our model

6。结果&结论

我们用不同的参数进行了多次迭代。在每一次迭代中,我们的网络最终陷入局部极小值,无论输入什么图像,都会生成相同的标题。以下是我们的一些训练迭代生成的单个字幕的一些示例:

  • 我和小夏迫不及待地要当二年级(小夏??我太爱你了,你现在是
  • 夏天就是夏天:/D
  • 世界最佳周末#thetan。
  • 祝我最喜欢的地方州生日快乐!💜😘

尽管预测的结果缺乏多样性,但它们表明我们的网络能够学习和掌握 Instagram 粉丝的语言。它使用了标签、表情符号、标点符号和表情符号。这些标题大多由合法的英语单词组成。我们相信我们在模型质量方面的最大限制是训练的时间。有 1000 个任意长度的标题,这个模型花了两天时间来训练。将标题长度限制在 60 个字符或更少允许我们使用 10,000 张图像,并将训练时间减少到 10 小时。但是需要让模型通宵或全天训练限制了我们测试多次迭代和解决我们遇到的错误的能力。它还阻止了我们用更多的历元和更大的数据子集进行训练,这是我们在课堂上用来提高性能的两种策略。理想情况下,我们将能够使用数据集中 80,000 个图像-标题对中的很大一部分,并且拥有一台超级计算机也很好!

当然,总有办法修改我们的模型来提高精确度:

  • 使用更大的数据集
  • 改变模型架构
  • 超参数调整(学习率、批量大小、层数等。)

然而,如上所述,由于我们的时间和计算能力有限,许多修改都是力所不及的。

尽管我们还有改进的空间,但我们为我们的神经网络感到自豪。它确实了解了一些关于 Instagram 标题的事情,甚至试图创建一个表情符号!显然,它还有一段路要走,但我们希望能激励一些人在未来继续并改进我们的工作。感谢阅读:)

我们所有的代码都可以在下面链接的 GitHub repo 中找到!

[## sejaldua/caption-gener8r

训练一个神经网络,使用一组较大的收集的 Instagram 数据为照片生成 Instagram 标题…

github.com](https://github.com/sejaldua/caption-gener8r)

承认

我们要感谢 Ulf Aslak Jensen 博士在他的丹麦留学学院(DIS)课程“人工神经网络和深度学习”中向我们讲授了各种神经网络模型的基础知识,并为我们提供了一些有价值的工具来应对这一挑战。祝贺你最*的博士学位和婚礼!我们还要感谢我们在创建这个项目时参考的许多 GitHub 资源库和在线文章。向开源社区大喊。一如既往,最感谢 StackOverflow 帮助我们这样的白痴每天解决我们的问题。

参考文献

布朗利,杰森。(2019).如何从零开始开发深度学习照片字幕生成器。

格罗斯曼蒂姆。(2019).insta gram-profile crawl GitHub 知识库。

朴,塞斯克&金,秉昌&金,君熙。(2017).关注你:使用上下文序列记忆网络的个性化图像字幕。

用数据做更多事情!

原文:https://towardsdatascience.com/do-more-with-data-6bc71f6eb4b3?source=collection_archive---------33-----------------------

以下是您如何利用数据锁定、赢得和留住客户的方法

Photo by Pablò on Unsplash

企业现在意识到,他们为了实现增长而做出的每一步和每一个决定都是从他们的客户开始的。一家公司留住的客户越多,就越有机会最大化投资回报率。

今天,营销人员主要关注客户的需求,并试图找到满足他们需求的最佳方式,不仅通过他们提供的产品或服务,还通过提供更好的客户体验。然而,要全面了解客户的需求,首先必须努力理解客户的行为。必须考虑客户与品牌的每次互动,以了解客户过去购买特定产品或偏好特定服务的原因。

有几种方法可以研究客户的这些行为模式,例如通过市场调查、在线和离线调查、公司过去的销售和最*的需求趋势。它们有助于积累大量的数据,由于其复杂性,无法通过传统的分析方法进行解释。这些数据可以称为“大数据”

B ig 数据由于其巨大的数量和复杂性,通常很难解释。然而,如果分析得当,它可以为企业提供有价值的见解,反过来,可以帮助营销人员做出周密的决策,制定更明智的战略,通过这些战略,公司可以在正确的时间与正确的客户接触。

充分利用数据还可以帮助企业应对市场不确定性,应对动荡的市场环境。所有这些都可以通过将客户作为企业的焦点来实现。人们可能想知道客户数据如何能帮助一家公司取得如此大的成就。这就是大数据如何帮助公司感知客户及其行为。

1.锁定客户

通过使用数据分析,大数据可以提供与客户的社会经济地位相关的重要信息。通过研究购买者的购买模式,公司可以了解消费者喜欢什么样的产品,或者他/她购买某一特定产品的频率?据福布斯报道,

“监督预测性营销工作至少两年的绝大多数高管(86%)表示,他们的预测性营销提高了投资回报率(ROI)。”

借助大数据,营销人员还可以根据人口统计和心理特征,利用一些不可识别的个人信息,如个人目标、兴趣、抱负、生活方式、习惯和日常活动,对目标受众进行细分。因此,细分是在短期内获得合适客户的第一步。细分后,企业可以将目标定位于允许其运营可行性的群体。锁定目标可以帮助公司提高工作效率,使他们只关注那些对他们的产品真正感兴趣的顾客。

2.筛选出忠诚的顾客

并非每个顾客都对一个品牌忠诚,因此必须为潜在顾客、对该品牌漠不关心的顾客、可能转向其他品牌的顾客以及已经与该品牌建立了持久关系并成为企业品牌传播者的顾客制定不同的商业策略。

营销人员普遍认为最有价值的顾客是那些在你的产品上花了很多钱的人;但是,这是不正确的,因为客户并不总是保持忠诚,如果他们有机会,可能会转向其他品牌,在价格,质量,甚至经验方面。

大数据有助于企业决定他们的忠诚客户,并通过计算买家的几个属性来识别 MVC。以下是可以用来从客户数据库中发现忠诚客户的许多指标中的几个。

1。顾客终身价值: CLV 表明了公司与顾客之间的关系。它告诉企业顾客在你的产品上花了多少钱。

2。Purchase Order: 计算客户在一次典型购买中花费的*均金额。此外,它还可以帮助营销人员对需求高或受众更喜欢的产品做出投资决策。

3。顾客满意度:顾客满意度告诉营销人员顾客对产品或服务的满意程度。它有助于发现不满意的客户群体,并提醒营销人员要减少产品或流程中的缺陷,以提供出色的客户体验,减少不满意的客户数量。

这些指标可以帮助企业将精力集中在可以改进的关键点上,从而赢得忠诚的客户群。

3.品牌的定位

大数据使业务与一致,其中如何在市场中定位其品牌。它可以告诉营销人员何时何地做广告。研究发现,当消费者看到 TVC 或脸书或其他媒体上的在线广告时,他们不会对该品牌产生兴趣。

在所有广告形式和位置中,显示广告点击率仅为 0.05%

0.05%的点击率意味着每 100 人中只有 5 人从事在线展示广告。数据可以回答诸如“哪个地区的客户对我的产品感兴趣?”。通过了解顾客的心理特征,如果顾客对价格敏感,商家可以决定是否应该打折;或者应该通过改进产品来专注于价值游戏。这些信息可以帮助企业决定【如何】【何处】来定位他们的品牌,通过利用他们从数据中收集的洞察力来提供最佳的客户体验。

判决

有了大数据,对于今天和明天的企业来说,可能性的视野似乎是无限的;然而,只有正确的分析才能引导企业从过去的趋势中推断信息,并用它来预测市场的未来模式和趋势。像 Google Analytics 这样的工具,主要被许多营销人员用来衡量他们公司的在线存在,并了解他们的数字立场。数据已被证明对企业特别有用,这意味着越来越多的企业正在这场数据战争中赢得竞争。

对于今天的企业来说,数据提供了巨大的资本化空间。只有时间才能告诉我们,哪些公司将最大限度地利用数据,并且比竞争对手更了解客户,因此与竞争对手相比,他们可以为客户提供相对高端的客户体验。

不要急于编码。企业人工智能项目的 4 个原则。

原文:https://towardsdatascience.com/do-not-rush-to-code-4-principles-for-ai-projects-in-enterprise-20cfeb32af3d?source=collection_archive---------20-----------------------

Think together before doing alone, an ant principle.

不,人工智能自己不能理解。不,数据科学不是自动的。敏捷方法并不意味着混乱。一句话,不,这不是魔法。在匆忙编码之前需要做什么?在这里,我与你分享我从职业和个人项目中学到的 4 条原则。

尽可能清晰地制定业务目标

做数据科学是一个绝对的趋势,虽然是一个强大的工具,但有时会被过度使用和不适应。这就是为什么在开始任何一行代码之前,我们必须确定我们在寻找什么来证明/改进,以及我们有什么样的数据来实现这个目标。在编码之前定义一个清晰的业务目标,是企业中一个重要的关键特性,然后这个定义将被用来定义我们的解决方案的评估指标。

必须准备好数据

大多数数据科学项目都是为了确保我们拥有数据。然后,我们必须确保数据准备好用于我们的模型。缺失值和异常值是我们必须处理的事情,以便我们的模型具有良好的数据质量。数据准备所需时间常常被低估。这不是机器学习中最性感的部分,但通过 EDA 过程准备和了解你的数据,可以让我们挑战我们试图帮助的工作专家,然后对主要问题有更好的理解(有时会发现之前需要解决的其他问题)。

精确定义交付

任何数据科学家的主要目标都是让一个模型在评估指标上表现良好。但是,我们必须确定我们正在寻找的最终交付是什么,以及在开发开始时,这种交付将如何在技术上集成到全球解决方案中。我们是在寻找一个 MVP 吗?这是一个 shell 脚本执行吗?Web 执行?我们想要什么样的动态?我们想要什么样的硬编码?这只是演示还是一个生产项目?所有这些问题都必须在编码前回答。

没有黑盒效应

机器学习将被应用到越来越多的行业的各个层面。从这个假设出发,我们必须确保所有人都能够很好地理解机器预测什么以及为什么,机器学习的可解释性是关键。伦理问题在我们的社区中越来越受到重视,我坚信“无黑箱效应”将允许我们通过预测人工智能在未来可能面临的伦理问题来提供解决方案。我强烈建议任何数据科学家在其基础数据科学管道中添加一个 ML 可解释性部分,就像我们对功能工程或度量评估所做的那样。

有什么建议吗?

请在评论区分享你自己的建议。😃

有大公园的西雅图邮政编码比没有大公园的有更高的狗密度吗?

原文:https://towardsdatascience.com/do-seattle-zip-codes-with-large-parks-have-higher-dog-density-than-those-without-dae3f5089ae0?source=collection_archive---------28-----------------------

用 Python 的 SciPy 进行假设检验。统计包加上哪里可以找到微型山羊

前几天,当我在寻找宠物密度最高的西雅图邮政编码时,我发现自己在想,“在有大型公园的邮政编码中,狗的密度会更高吗?”和“这些山羊在哪里?”

深入到第一个问题,假设检验将帮助我们确定两组在统计上是否有显著差异。

对于假设检验,我们使用以下步骤:

  1. 定义无效假设和替代假设
  2. 识别测试统计和概率分布
  3. 指定重要性级别
  4. 计划、收集数据和计算
  5. 拒绝或未能拒绝零假设

定义无效假设和替代假设

无效假设——作为一名持怀疑态度的科学家,我们希望我们两个群体之间没有差异。这是无效假设。

H0:与没有大型公园的西雅图相比,在有大型公园的西雅图邮政编码区,狗的密度没有增加。

替代假设——我们两个群体之间存在差异。我们无效假设的替代方案。

H1:与没有大型公园的西雅图相比,在有大型公园的西雅图邮政编码区,狗的密度增加了。

识别测试统计和概率分布

测试统计有几个选项,包括:

  • Z 检验 —正态分布。适用于:具有大样本量或已知总体方差的正态分布数据
  • T 检验 —尾部比正态分布重的学生 T 分布。适用于:未知方差,少于 30 个样本
  • 卡方检验 —决定分类变量是否独立
  • F 检验 —使用 ANOVA,检验基于方差的分组是否有意义

更多详情此处。

由于我们在每个人口中只有 14 或 15 个邮政编码,T 检验更适合于这种分析,因为它最适用于样本量小于 30 的情况。

除了检验统计量,如果您使用 z 检验或 t 检验,您需要确定您是在做单尾检验还是双尾检验。双尾检验是检验人群中的差异——或者大于或者小于(例如,男孩的身高与女孩的身高是否不同?).单尾测试用于确定一个单一方向的差异(例如,男孩比女孩高吗?).

在我们的例子中,我们的零假设表明有大公园的邮政编码并不比没有公园的邮政编码有更高的狗密度。因此,我们将使用单尾 t 检验,因为我们的假设只是询问在比较不同大小公园的社区时是否存在单向变化。

注意:与双尾 t 检验具有相同显著性水*的单尾 t 检验将拒绝比单尾 t 检验更少的零假设,因为它“分割”了“高于”和“低于”可能性之间的不确定性,您可以在下面的图表中看到这一点。请注意,单尾 t 检验的临界 t 值小于双尾检验的上限临界 t 值。

指定重要性级别

显著性水*是基于所提供样本的群体之间没有差异的概率。5%或 1%的显著性水*(alpha)对应于备选假设的 95%或 99%的置信区间。请记住,在显著性水*为 5%的情况下,预计 20 个重复实验中有 1 个会得到错误的结果。

在这种情况下,我决定 5%的显著性水*/95%的置信区间适合我的目的。特定的显著性水*通常是你的行业、公司等的标准,所以一定要使用它,不要随便选一个。注意:调整您的显著性水*和置信区间以适应您的结果不是一个好的做法(例如,我们发现这种差异在 87%的置信区间下是显著的)。

计划、收集数据和计算

一旦有了假设、测试统计数据和显著性水*,就可以准备制定数据收集计划了。基于您期望的两个总体之间的差异大小和您的显著性水*,您可以确定您需要多大的样本来拒绝零假设,如果它是假的。更多信息见这里。

首先,按照计划,收集所有的数据。同样,在收集数据的同时不断计算测试统计量,等待达到显著性阈值,然后取消其余的数据收集,这不是一个好的做法。我们不只是试图拒绝零假设,而是实际上试图获得真相。遵循你的计划,收集所需数量的数据,然后然后计算,从而避免诱惑。

为了我的调查,这是西雅图狗密度的柱状图,按邮政编码排列:

看到没有大公园的邮政编码的*均狗密度大于有大公园的邮政编码的*均狗密度,我可以/应该停止我的调查。从统计上来说,或者从任何角度来说,在有大公园的邮政编码区,狗的密度并不高。我真的想知道这是否会随着人均价值而改变…下一个调查!出于入门/提醒的目的,我们将继续这个过程:

接下来,计算你的 p 值。查看“统计测试”的scipy.stats 文档,找到适合您情况的文档。在本例中,我正在对两个独立的人群进行 T 检验,所以我将使用ttest_ind。查看文档,请注意,它期望两个群体之间的样本大小相等,因此我将随机对较大的群体进行采样,以便将其调整为较小群体的大小。由于我们不知道方差是否相等,我们将把equal_var参数设置为False,以执行韦尔奇 T 检验,该检验不要求方差相等,而学生的 T 检验则假定两个总体之间的方差相等。

from scipy.stats import ttest_ind, t
import numpy as nprand_no_parks_zips = np.random.choice(no_parks_zips, size=14)
result = ttest_ind(rand_no_parks_zips, parks_zips, equal_var=False)
print(result)

退货:

**Ttest_indResult(statistic=-0.9046044635337662, pvalue=0.3745636286751721)**

这提供了双边检验的 p 值。为了获得单侧 p 值,我需要使用 t 统计量,并将其与我的 0.05 显著性水* t 统计临界值进行比较。

要在 python 中获得 t 统计临界值,请使用scipy的百分点函数(百分点)

p = .95 # 1-alpha
df = 13 # degrees of freedom (n-1)
critical_t_value = t.ppf(p, df)
print(critical_t_value)

我们得到了:

**1.7709333959867988**

视觉上,我们有:

要查看 p 值,您可以使用累积分布函数来查找曲线下达到 t 统计量的面积,并将其从 1 中减去,以获得零假设为真的概率,并且具有大公园的邮政编码并不比没有大公园的邮政编码的狗密度高。注意:如果你在另一边做单尾测试(比如狗的密度较小),你不需要从一个中减去。

p_value = 1 - t.cdf(result[0], df)
print(p_value)

我们得到了:

**0.808933235528686**

这里我们看到 t 统计量远低于临界值(当我们寻找大于替代假设时),p 值远高于我们的显著性水*。因此,我们不能拒绝零假设,即有大公园的西雅图邮政编码没有比没有大公园的更大的狗密度。在 0.05 的显著性水*上,这两个群体之间没有统计学上的显著差异。

如果 t 统计量超出了临界 t 值(或双尾检验的-值),并且 p 值小于我们选择的显著性水*,我们将拒绝零假设,而支持替代假设。请注意,p 值和 t 统计检验将始终表明相同的结论。您不需要两者都检查。

Beckham enjoying Green Lake. Photo Credit: Kevin Honold

我由此得出的结论是,西雅图人喜欢他们的宠物,不管它们离一个大公园有多*。虽然我的小狗贝克汉姆肯定很喜欢它靠*绿湖的位置,但是不管你离一个大公园有多*,有很多方法可以让你的宠物保持活跃和健康。

调查愉快!

正在寻找 38 只注册的小型山羊…

我不会猜到拉韦纳/韦奇伍德/枫叶/等等。成为迷你山羊的热土,但是很迷人!

一如既往,你可以查看我的 GitHub 回购了解更多细节/代码。

股票提供正的预期回报吗?

原文:https://towardsdatascience.com/do-stocks-provide-a-positive-expected-return-d21571e78ea4?source=collection_archive---------11-----------------------

Photo by Mark Finn on Unsplash

我们使用统计和模拟来量化我们对标准普尔 500 战胜现金(国库券)的信心

如果你想自己运行代码,你可以在我的 Github 这里找到它。

投资和退休理财的一个基本假设是,随着时间的推移,股票将比现金或国债等更安全的投资资产带来更高的回报。但是他们有吗?

在本帖中,我们将检查这些数字,运行一些模拟,并最终量化我们的信心水*,即标准普尔 500(美国大型公司的可投资指数)将为我们提供超过美国国库券(现金)的正预期回报。

一些定义:

名义回报 =未经通货膨胀调整的投资回报

实际回报 =经通货膨胀调整后的投资回报

我们为什么要关心?

尽管我们今天有很多投资选择,标准普尔 500 仍然是大多数投资组合的主力。例如,广受欢迎的 SPY ,一只跟踪 S & P 500 的 ETF(交易所交易基金),截至 2019 年 5 月 23 日,净资产超过 2780 亿美元。它只是众多跟踪标准普尔 500 指数的基金之一。

即使你没有直接买下标准普尔 500,你也可能拥有一些。假设你现在 30 岁,在你的 401k 计划(为计划在 2055 年退休的人设计)中投资了 Vanguard 2055 目标日期基金。该基金将其 54%的资产投资于总股票市场指数基金,该基金与标准普尔 500 指数大致相同。

所以基本上每个人都至少有一些钱在里面。

回报的另一面是风险

在金融界工作,你会经常听到这样一句话:“没有免费的午餐。”(除了在谷歌,抱歉,这是个蹩脚的笑话)金融人士这么说的意思是,没有伴随风险就没有超额回报。

让我们想想这意味着什么。

无风险基准利率

第一,我为什么说超额收益?我们能用钱投资的东西从来都不是只有一个。每一个决定都是一种权衡——如果我投资标准普尔 500,那么这笔钱就会被套牢,不能再投资于黄金、国债、日本股票、原油或其他任何东西(直到我们出售)。

我们做出的每一个财务决策都应该有适当的基准。金融中最基本的基准是无风险利率——我们可以不费吹灰之力、零风险获得的回报率。

我们通常使用的无风险利率是国库券利率(我在本文中使用的是一年期国库券利率)。国库券是由美国政府发行的短期债务工具(一年内到期),被认为是无违约的。展望未来,我将交替使用一年期国库券和现金,因为国库券被广泛认为是现金等价物。让我们来看看这个比率是什么样的:

One Year Treasury Bill Rate

正如你所看到的,现金利率变化很大,从高通胀的 20 世纪 70 年代的两位数到过去十年的接*零(为了应对金融危机)。需要注意的一点是,一年期国债利率实际上并不是真正无风险的——如果通胀率高于你的收益率,你最终将获得负的实际回报。TIPS(国债通胀保值证券)将是无风险资产的良好候选,但直到 20 世纪 90 年代才被广泛采用(因此数据较少)。

你应该因为承担更多风险而要求更多的回报

第二,你承担的风险越大,你期望的回报就应该越高。否则为什么要拿你的钱冒险呢?下图说明了这种风险与回报的关系。

Always demand more bang for your buck!

那么,我们为什么要相信像美国股票这样的高风险产品会给我们带来比现金更高的预期回报呢?经典的回答是当我们购买公司的股份时,我们是在提供金融资本来帮助发展和经营业务——我们是在提供服务,应该期望得到报酬

就像向朋友发放个人贷款一样,你可能只能收回一部分钱,或者根本拿不回来。因此,本质上,股票的更高预期回报,就像贷款利率一样,是为了补偿你的风险。但是真的吗?

标准普尔 500 包括股息的*均年回报率(1962–2017):10.9%

*均无风险利率(1962 年至 2017 年): 5.2%

*均回报看起来不错,但是仅仅看*均回报会欺骗我们。下图比较了年度股票回报率和无风险利率。三样东西跳了出来:

  1. 标准普尔 500 回报比现金回报表现出更高的波动性。
  2. 现金的表现已经超过标准普尔 500 指数很多倍。
  3. 1990 年以前,现金似乎比 1990 年以后更经常跑赢股票。
  4. 2008 年后,股票轻松击败现金,因为无风险利率被美联储锁定为零。

Stocks returns vary much more than cash returns

用一些模拟来测试我们的假设

让我们通过运行一些模拟(精神上非常类似的分析)来可视化这个过程,而不是计算测试统计和运行正式的假设测试。

我用以下假设运行了 5000 个一年的模拟:

  • 股票收益正态分布,预期收益 10.9%,标准差 15.2%。
  • 无风险利率(现金回报)的预期值为 5.2%,标准差为 3.4%,但不能低于 0%。
  • 上述数值是使用历史数据(1962 年至 2017 年)估算的。有人可能会说,上世纪 70 年代的高通胀(和高利率)是一种异常现象,但我们已经受到数据的限制,所以我决定在我的分析中尽可能多地使用数据。
  • 股票和现金回报是独立的。
  • 我没有对这些值进行通货膨胀调整(一切都是名义值)。

在我运行的 35%的模拟中,现金战胜了股票!这可不好。因此,在任何一年,标准普尔 500 指数跑赢现金的可能性只有三分之二。

对于可视化,请查看下面我的模拟结果的直方图。注意 x=0 处的垂直橙色线;发生这种情况是因为我不允许现金的名义回报率低于 0%(你也不应该这样,如果你的银行试图收取你持有资金的费用,是时候换银行了)。因此,现金回报率等于 0%的例子很多。

Stocks look pretty risky…

这还不是全部。回想一下,我们仅使用 56 年的历史来估计我们的预期回报和标准差——这并不是很多数据。所以还有第二个层次的不确定性——围绕我们对总体参数估计的不确定性(为了简单起见,我们将专注于解决围绕预期回报的不确定性,忽略围绕标准差的不确定性)。

我们可以通过将标准误差应用于我们对预期回报的估计来尝试捕捉这种不确定性。标准误差基本上是我们对真实*均值估计的标准偏差。也就是说,“标准误差”试图回答这个问题——如果我们多次进行这个实验(假设我们可以),并计算每次的预期收益,我们会在这个预期收益估计值中观察到多少变化?

我们可以将标准误差(SE)计算为:

SE =样本标准偏差/ sqrt(样本大小)

SE _ S&P500 = 15.22%/sqrt(56)= 2.03%

SE_Cash = 3.36% / sqrt(56) = 0.45%

针对参数的不确定性修改我们的模拟

由于我们可以运行的模拟数量没有实际限制,所以让我们只表达我们对预期回报真实值的不确定性,作为随机性的一个额外来源。这是我们的设置:

  • 进行 5000 次实验。
  • 每个实验由 5000 个一年的模拟组成。除了现在标准普尔 500 和现金的预期收益不再是固定的;相反,它们本身是随机变量(根据学生的 t 分布分布),其标准偏差等于各自的标准误差。

因此,我们只是重复我们之前所做的(之前的直方图)5000 次(像一个嵌套循环),每次都允许我们不确定的变量(预期回报)发生变化。让我们来看看这是什么样子的(记住垂直的橙色线在那里,因为我不允许负的现金回报,因此有很多现金回报= 0%的例子)。形状看起来和以前差不多,只是更*滑了,因为我们运行了这么多模拟。

Looks about the same as before

看看统计数据,什么都没有改变(现金每年仍有 35%的机会获胜)。

那么,这一切都是徒劳的吗(对于我自己的直觉来说,检查估计值的不确定性是否会导致更多的差异实际上是有用的——似乎不会)?

或者也许我们没有问对问题…

当你扩大投资范围时,股票看起来会更好

买入并持有是一种流行的投资策略,这是有原因的。我们不应该用几天、几周甚至几个月来判断我们的投资。我们投资是为了积累长期财富,并为我们的退休生活提供资金。

回想一下,之前我们发现现金赢的概率为 35%(在我们的 5,000 次模拟中)。让我们来看看我们购买和持有的时间(持有期)如何影响现金赢率:

The longer your holding period, the more likely that stocks will beat cash

如果我们买入并持有股票 5 年,现金胜出的概率从 35%下降到 25%。如果我们买入并持有 10 年,则降至 18%。如果我们买入并持有 20 年,股票表现差于现金的概率会一直下降到 12%。仍然不理想,但已经明显好了。

因此,在一个足够长的时间范围内,说股票将比现金回报更好似乎是一个合理的赌注——在 20 年的投资范围内,股票在 8 次中有 7 次击败了现金。

让我们凭直觉理解为什么持有时间越长,股票相对于现金越有吸引力。主要原因是,随着你持有时间的增加,预期回报开始比波动性(标准差)更重要。让我们来看看五年持有期的预期回报等式:

5 _ yr _ return =(1+annual_return)⁵-1

如果你持有一项投资资产五年,这是你累积回报的标准差( stdev ):

5_yr_stdev = annual_stdev * sqrt(5)

注意到什么酷的东西了吗?如果你从这篇文章中只拿走一样东西,我希望是下面这一点。这可能是所有金融中最重要的概念:

预期回报随时间呈指数复合增长,但波动性(标准差)仅随时间的*方根增长。

这意味着,随着时间的推移,你投资的波动性会被回报淹没,前提是预期回报足够高(长期回报大于波动性)。你会听到这被称为复利的力量。让我们来看看这个:

Return starts to take off relative to volatility

前面的图表让股票看起来像是一个不需要动脑筋的问题,但是请记住,我们不太关心股票的绝对回报,而更关心股票相对于现金的超额回报。使股票受益的复利也有助于现金。

负荷试验

只说“持有股票 20 年,你就可以走了”太容易了。让我们对我们的假设进行一点压力测试。

早些时候,我们计算出股票的标准误差(我们对预期回报估计的标准偏差)为 2.03%。因此,如果股票的实际实现回报率低 1.0%(9.9%,而不是我们估计的 10.9%),一点也不奇怪。

如果股票回报低于我们的预期,那么在各种投资范围内,现金战胜股票的概率会怎样?不出所料,情况全面恶化,现在即使在 20 年的时间范围内,现金也有*五分之一的机会击败标准普尔 500。

Gets worse but longer holding periods still help

结论

那么,标准普尔 500 的表现是否会优于一年期美国国债?大体上是的。但在任何一年,我们都应该预料到大相径庭的结果(股票的胜算大约只有三分之二)。即使持有超过 20 年,我们也不能非常自信地认为投资股票会更好(股票的胜算大约是 8 分之 7)。

那么,为什么还要担心股票呢?正如我上面提到的,虽然现金在名义上是无风险的,但它却极易受到通货膨胀的影响

另一方面,股票由于其较高的预期回报和公司提高商品和服务价格的能力,相对较少受到通货膨胀的影响。

因此,股票仍然是我们长期积累真实(经通胀调整的)财富的较好赌注之一——但正如我们所见,它们绝不是一个稳赚不赔的赌注。

来源:

S&p500 收益的数据来源于 罗伯特席勒的网站

国债利率数据取自。****

Twitch 上的流媒体指标会影响游戏销量吗?

原文:https://towardsdatascience.com/do-streaming-metrics-on-twitch-affect-game-sales-cbb4e0ee90e0?source=collection_archive---------26-----------------------

使用线性回归探索视频游戏销售与其在 Twitch 上的流量之间的关系

Photo by Caspar Camille Rubin on Unsplash

每天,大约有 1500 万游戏玩家和非游戏玩家访问 Twitch,与志同道合的社区进行交流、观看和聊天。*台上有如此多的人,我认为看看一个给定游戏的流媒体指标如何影响该游戏的单位销售会很有趣。虽然我特别感兴趣的只是理解流和销售之间的潜在关系,但我的假设是,具有非常健康的流指标的游戏也会有类似的健康销售数字。我也有预感,总观看分钟数和总播放分钟数的系数将是销售数字的主要驱动力。

然而,这只是一个假设,所以我决定求助于一些真实的数据和真实的建模来决定是否接受或拒绝它。

数据

对于这个项目,我从两个主要来源获取数据。第一个是使用 BeautifulSoup 获取视频游戏销售指标的对 VGChartz 的网络抓取。第二个(流媒体指标)是通过 SullyGnome (第三方 Twitch 统计和分析网站)收集的。具体来说,我研究了:

  • 值班时间
  • 连续开工时间
  • 峰值观众(特定标题的最高并发观众数量)
  • 峰值频道(特定标题上的最高并发流媒体数量)
  • 飘带
  • 普通观众
  • *均频道

在继续之前,有必要重复一下直接从他们的网站上获取的关于 VGChartz 的附加说明:

所有销售信息仅是估计值,并通过多种专有且不断发展的方法得出,包括:

  • 被动地轮询终端用户,了解他们当前正在购买和玩什么游戏
  • 调查零售合作伙伴,了解他们销售的游戏和硬件
  • 使用相似游戏的统计趋势拟合和历史数据
  • 研究转售价格以确定消费者需求和库存水*
  • 咨询出版商和制造商,了解他们将多少台设备引入渠道

因此,虽然 VGChartz 上的销售数字是公开可以找到的最可靠的数字,但它们可能并不准确。

范围

尽管 Twitch 在美国占据主导地位,因为 VGChartz 和 SullyGnome 都在全球范围内收集数据,但我没有(也不可能)将这项研究局限于一个国家。此外,SullyGnome 上的可用数据只能从 2016 年到现在访问,所以我不得不将该项目限制在 2016 年以后。最后,尽管 Twitch 占据了 PC 流媒体市场的最大份额,但由于数据的性质,我分析了所有*台的多*台产品。

现在,在我开始实际建模之前,先做一些简单的说明。首先,我选择排除这个项目的免费游戏(F2P)的标题。虽然像《堡垒之夜》、《英雄联盟》和《Dota 2》这样的游戏继续主导流媒体领域,但考虑到(顾名思义)它们不需要花费任何费用来玩/购买,它们并没有完全炸毁每周的销售图表。

同样,我决定将微交易排除在这项研究之外。虽然一项有趣的未来研究可能会将微交易视为流媒体指标的一个功能,但该项目严格关注任何给定标题的销售单位。

模特 V1:2016–2018(所有比赛)

Photo by Sean Do on Unsplash

在我第一次浏览数据时,我选择查看 SullyGnome 存在以来(2016 年至今)所有图书的销售情况。然而,因为 VGChartz 只有 2018 年的完整图表,我被迫只看 16-18 年的数字。

为了从 VGChartz 获取信息,我运行了一系列函数来抓取多个页面中的必要列:

上面给了我一个 56,322 款游戏的庞大数据框架,尽管其中只有大约 20,000 款游戏附有总销售额,所以我用这些数据进行工作。

在对这个数据框架做了一些清理之后(请随意查看我的项目报告中的代码),我将所有*台上每个游戏的销售额汇总到每个独特游戏的一行中,因为 SullyGnome 显示了所有*台上每个游戏的所有流媒体指标。

接下来,我继续使用 SullyGnome 的 Twitch 指标,从 2016 年到 2018 年的前 1000 款游戏中抽取,因为这感觉上是一个足够大的批量,可以用来测试我的假设。两个数据框架都被合并到公共列“游戏”中,然后准备建模。

第一个模型

进入模型后,我强烈地感觉到将会有一些严重的多重共线性。毕竟,再次查看我选择用作我的模型的特征的流度量(观看时间、流时间、总流数等。)许多人本质上说的是同一件事,或者彼此之间有明显的强相关性。

将所有特征和目标放入相关矩阵中肯定证实了这一点:

Correlation matrix for 2016–2018 games

在整个项目中,我在构建和优化模型时牢记这一点,剔除具有*乎完美的多重共线性的要素。然而,更有趣的是,(也令人失望的是)我还在所有这些流式指标和目标(总销售额)之间看到了一个相当微弱的信号。

这是一个很好的地方来说,我将主要看着调整的 R *方作为我的成功指标。我更感兴趣的是了解我的特征和目标之间的关系,而不是试图预测未来的目标变量(在这种情况下,我可能会选择查看 RMSE——均方根误差)。

无论如何,我知道我将需要做一些相当大的清理和提炼,但我很好奇在去掉一些非常相关的特性后,摘要会是什么样子。使用统计模型,很容易将模型与一些数据相匹配,并打印出汇总统计数据:

这打印出了以下内容:

不出所料,我看到了一些我上面预期的回声。在高条件数和相当低的调整后 R *方中有强烈的多重共线性迹象。然而,通过查看系数,我还发现了一些非常有趣的事情…尽管大多数功能给我的信号很低,甚至没有信号,但 peak_channel 指标的值为 443。这意味着,对于一个给定的标题,每增加一个高峰频道,我就会看到多卖出 443 台!随着我的项目向前推进,这是我肯定会关注的事情。

这是提到线性回归的另一个假设的好时机:同方差。散点图是检查数据是否同质的好方法(意味着回归线上的残差相等)。以下散点图显示了非异方差(即异方差)数据的示例:

这是我的散点图…

在这个阶段,我基本上违反了线性回归的五个假设中的两个…也许我需要一个不同的方法…

模式 2 和模式 3:大同小异

在项目的这一点上,我决定最好的行动是逐步缩小我所关注的时间范围。我不会详细介绍这些模型,但可以说我观察了以下时间段:

  • 2016 年至 2018 年,但只是销售额最高的游戏
  • 2018 年总计

在每个阶段,我都看到了稍微好一点的结果(更高的 r *方,残差图上稍微多一点的随机性),但仍然大同小异:强烈的多重共线性,许多流度量之间的信号很弱,没有同质性。在这一点上,我觉得 LUL 表情本身应该被用来嘲笑我糟糕的成绩:

Is this even a linear regression?

模型 4:终于有所进展

对于我的建模的最后一次迭代,我选择查看每个游戏发布当月的销售和流媒体指标。根据我自己的经验、领域知识和 VGChartz 的一些环境扫描,很明显,游戏销售通常在发布时有一个强劲的峰值,并在第一个月之后急剧下降。因此,我希望这种方法会产生更好的结果。

同样,我从 VGChartz 网站上收集了每月的热门游戏,结合 SullyGnome 的指标,发现了一些更令人鼓舞的结果:

Starting to see some signal between sales and streams (row 1)

Starting to see a linear relationship

不仅这些结果更令人鼓舞,在这个尺度上峰道系数甚至更大。事实上,让我们看看这个系数是如何影响每个时间尺度的销售额的:

Whoa…

这表明,逐月查看数据,在发布的前 4 周内,我们看到 Twitch 上每个额外的高峰频道流媒体都额外售出了 1,542 台。这是相当有意义的!

结论

我进入了一些关于我的模型的附加细节(正则化,交叉验证,等等)。)但这篇文章已经够长了,关键在于 peak_channels 系数。

虽然我可以合理地说,在许多流媒体功能和目标之间没有巨大的信号,但我可以说 peak_channels 系数有一个非常戏剧性的信号,特别是在游戏发布的前 4 周。

关于这一发现,需要注意的是:一个标题的高并发流数量可能只是有多少人首先购买了该游戏的函数,而不是相反。因此,在未来,我很乐意探索预购销售数字与发布时的流数量的对比,以确定流是否确实是销售的原因。

Twitch 的业务是建立社区,支持创作者和游戏开发者,并塑造整个视频游戏行业。有了这些数据,我会建议 Twitch 联系潜在的游戏开发商和赞助商,并建议他们不要将赞助/广告资金集中在大型(和昂贵)的流媒体上,如忍者(哎呀,他甚至已经不在那里了),而是应该尽他们所能在游戏发布时让流媒体充斥市场。

他们可以通过吸引社区和提升横幅来做到这一点,这些横幅通常不会引起大赞助商的注意。

这与大多数成功的广告运作方式背道而驰。然而,Twitch 在许多方面都是一个反直觉的产品。Twitch 由小型利基社区组成,这些“中间层”横幅有一个更有效的互动*台,可以与观众建立友好和亲密的关系(即使他们没有大牌横幅的音量)。把它想象成类似于在一个巨大的舞台上观看你最喜欢的乐队与一个亲密的 500 人俱乐部的比赛。广告商和游戏开发商同样可以利用这种紧密联系的利基社区,在更个性化(和更高转化率)的层面上有效地瞄准和沟通。我甚至建议 Twitch 制作一个实时分析仪表板,看看游戏是如何在发布窗口参与和销售的,以利于广告商、开发者和整个游戏社区。

附录

Github 、 LinkedIn 、投资组合

我如何使用 NLP (Spacy)筛选数据科学简历

原文:https://towardsdatascience.com/do-the-keywords-in-your-resume-aptly-represent-what-type-of-data-scientist-you-are-59134105ba0d?source=collection_archive---------2-----------------------

通过 NLP 更好地定位您的数据科学简历

Image Source: pixabay

简历制作非常棘手。一个候选人有许多困境,

是详细陈述一个项目,还是只提及最低限度

是提及多项技能还是只提及他/她的核心能力技能

是要提到很多编程语言还是只举几个

是将简历限制在 2 页还是 1 页

对于寻求改变的数据科学家来说,甚至对于有抱负的数据科学家来说,这些困境都同样艰难。

在你想知道这篇文章的方向之前,让我告诉你写这篇文章的原因。

上下文

我的一个朋友有自己的数据科学咨询公司。他最*获得了一个好项目,需要他雇佣两名数据科学家。他在 LinkedIn 上发布了一份工作,令他惊讶的是,他收到了* 200 份简历。当我见到他本人时,他说,“要是有一种方法能比手动逐一查看所有简历更快地从这些简历中选出最好的简历就好了”。

在过去的两年里,我一直在从事几个 NLP 项目,这既是工作的一部分,也是我的爱好。我决定尝试解决我朋友的问题。我告诉我的朋友,也许我们可以解决这个问题,或者至少通过一些 NLP 技术来减少手动扫描的时间。

确切要求

我的朋友想要一个拥有深度学习和其他机器学习算法知识的人作为他/她的核心竞争力。另一名候选人需要具备更多大数据或数据工程技能,如在 Scala、AWS、Dockers、Kubernetes 等方面的经验。

进场

一旦我明白了我的朋友理想的候选人是什么样的,我就想出了一个方法来解决这个问题。以下是我列出的方法

准备一本字典或表格,将所有不同的技能进行分类,例如,如果有像 keras、tensorflow、CNN、RNN 这样的词,那么将它们放在一个名为“深度学习”的栏目下。

有一个 NLP 算法来分析整个简历,基本上搜索字典或表格中提到的单词

下一步是统计每个候选人在各种类别下出现的单词,如下所示

The above candidate would be a good match for the ‘Deep Learning Data Scientist’ that my friend is looking for.

将以上信息用视觉的方式表现出来,这样我们选择候选人就变得容易了

研究

现在我已经最终确定了我的方法,下一个大的障碍是如何完成我刚才所说的。

NLP 零件—空间

我在寻找一个可以进行“短语/单词匹配”的图书馆。Spacy 满足了我的搜索需求。Spacy 有一个叫做“短语匹配器”的功能。你可以在这里阅读更多信息。

阅读简历

有许多现成的软件包有助于阅读简历。幸运的是,我朋友收到的所有简历都是 PDF 格式的。所以,我决定探索像 PDFminer 或 PyPDF2 这样的 PDF 包。我选择了 PyPDF2。

语言 : Python

数据可视化 : Matplotlib

代码和说明

完整代码

这里有一个要点链接到完整的代码。

现在我们有了完整的代码,我想强调两点

关键词 csv

关键字 csv 在代码行 44 中被称为‘template _ new . CSV’

您可以用自己选择的 DB 来替换它(并在代码中进行必要的更改),但为了简单起见,我选择了好的 ol excel 表(csv)。

每个类别下的单词都可以定制,下面是我用来匹配简历短语的单词列表。

候选—关键词表

在代码的第 114 行中,该行的执行产生了一个 csv 文件,该 csv 文件显示了候选人的关键字类别计数(候选人的真实姓名已被屏蔽),如下所示。

这可能不太直观,因此我通过 matplotlib 进行了数据可视化,如下图所示

Here DE stands for Data Engineering, the others are self explanatory

从图表上看,多姆·科布和费舍尔更像专家,而其他人则像多面手!!

整个锻炼有益吗?

我的朋友对取得的结果感到非常惊讶,这为他节省了很多时间。更不用说他仅仅通过运行代码就从* 200 份简历中筛选出了大约 15 份简历。

以下是整个练习的有用之处

自动阅读简历

代码自动打开简历并解析内容,而不是手动打开每一份简历。如果手动完成,将花费大量时间。

短语匹配和分类

如果我们手动阅读所有简历,很难判断一个人是否具有机器学习或数据工程方面的专业知识,因为我们在阅读时没有统计短语。另一方面,代码只是搜索关键词,记录出现的关键词,并对它们进行分类。

数据可视化

数据可视化在这里是一个非常重要的方面。它通过以下方式加快决策过程

我们可以知道哪个候选人在某个特定类别下有更多的关键词,从而让我们推断他/她可能在该类别中有丰富的经验,或者他/她可能是一个多面手。

我们可以对候选人进行相对比较,从而帮助我们筛选出不符合要求的候选人。

你如何使用代码

寻找工作变化的数据科学家/有抱负的数据科学家:

很多公司可能已经在使用上述代码对候选人进行初步筛选。因此,建议根据特定的工作要求,用必要的关键词来定制你的简历。

一个典型的数据科学家有两种选择,要么把自己定位为多面手,要么表现为某个领域的专家,比如“NLP”。根据工作要求,数据科学家可以对照他/她的简历运行此代码,并了解哪些关键词出现得更多,以及他/她看起来是“多面手”还是“专家”。根据输出结果,你可以进一步调整你的简历,以相应地定位自己。

招聘人员

如果你和我的朋友一样是招聘人员,并且被简历淹没,那么你可以运行这个代码来筛选候选人。

希望你喜欢这篇文章。

你可以联系我

领英

推特

我们在生命科学领域有大数据吗?

原文:https://towardsdatascience.com/do-we-have-big-data-in-life-sciences-c6c4e9f8645c?source=collection_archive---------10-----------------------

生命科学的数理统计和机器学习

还是数据量仍然是瓶颈?

Image source

在这篇文章中,我将开设一个新的专栏生命科学的数理统计和机器学习,在这里我将分享我与生命科学家一起工作时积累的关于计算分析的想法和观点,以及对生命科学中广泛使用的一些流行的统计和机器学习方法的深入解释,这些方法有时可能看起来难以理解。

大数据:天文数据还是基因数据?

由于我在理论物理的背景,在过去的 8 年里,我很高兴也很幸运能和来自生命科学的人一起工作,比如生物医学、细胞生物学和进化科学。经常听同事说:“我们有大数据,我们需要分析、整合它,并在其上运行机器学习”。对于大数据,我的同事通常指的是各种组学数据占据的TB 和 Pb 的磁盘空间:基因组学、转录组学、蛋白质组学、代谢组学等。

From Stephens et al., Plos Biology 13, e1002195 (2015)

事实上,随着人类基因组测序变得相对便宜(每个基因组 1000 美元),世界上越来越多的大学实验室有能力从成百上千的个人那里获取全基因组信息来回答他们的研究问题。诸如 1000 基因组计划 (~2 500 个人类基因组)、 ExAC (~60 000 个人类基因组)、 UK10K (迄今为止~3 500 个人类基因组)以及最*的 HGDP (900+稀有人类基因组)等公共资源提供了海量的基因数据,这些数据目前已经远远超过了摩尔定律。

它已经在诊所里了吗?

精准医疗极大地受益于巨大的基因组学努力,如癌症基因组图谱(TCGA) (跨越 33 种不同癌症类型的 11 000 种人类肿瘤)和英国生物库(约 50 万人类个体)。

The Cancer Genome Atlas (TCGA) and UK Biobank are huge human genomics resources

“我们在生命科学领域有大数据吗?”这是一个什么样的问题。人们很容易说“是的,当然,看看基因组学的巨大努力。现在,我们应该能够使用从人类群体基因组数据中获得的知识,以随机提取人类 DNA 并预测此人是否易患某些疾病,因此我们应该能够预测此人的未来,并针对此特定个体开出调整后的治疗方案。这不就是精准医疗应该做的吗?”。

Precision Medicine is here to bring treatment adjusted to individual genetic signatures

然而,事实证明将这些基因组学成果引入临床并不简单。牛津大学的 Mark McCarthy 教授是二型糖尿病(T2D)的世界领先的遗传学专家之一,他去年做了几次演讲,题目是

现在我们已经发现了超过 400 个影响二型糖尿病(T2D)的基因信号,我们到底要拿它们怎么办?

这听起来不太乐观吧?它基本上说,我们有很多数据,我们使用这些数据来识别与 T2D 等常见疾病相关的基因,但是我们还没有接*将这些基因用于临床诊断,以早期预测和预防这些疾病。

基因组学预测很差

那么问题是什么,为什么我们不能在临床上使用这些巨大的基因组学成果呢?嗯,简单的回答是它不像预期的那样工作。更具体地说,遗传和基因组数据不能很好地预测常见疾病。斯坦福大学的迈克·斯奈德团队最*证明了基因组学数据对腹主动脉瘤的预测能力很差:

ROC curves for Genomics vs. EHR for AAA from Li et al., Cell 174, 1361–1372 (2018)

上面的 ROC 曲线比较了基因组学与电子健康记录(EHR)** 预测 AAA 的能力。EHR 代表了相当琐碎的临床信息,如身高、体重、体温、血压等。事实证明,这种琐碎的信息比 DNA 水*上的遗传变异更具预测性,这是非常令人沮丧的,考虑到 AAA 表型中的大遗传成分,这意味着 DNA 信息应该是可预测的,但它不是。这是常见疾病如 T2D、精神分裂症、心血管疾病等的典型情况。这有时被称为 缺失遗传力 的问题,简单地说就是基因组大数据无法预测常见疾病。**

基因组学中的维数灾难

基因组学预测能力差肯定有多种解释。其中之一就是我在上一篇中已经提到的 维度的诅咒 。当特征数量 p 远大于样本数量 n 时,即在极限p>n内,维数灾难是无法执行有意义的数学运算。人类基因组通常包含p ~ 3000-9000 万个基因突变(单核苷酸多态性),而测序超过 n~1000 - 10 000 个个体对于大多数学术机构来说在经济上是不可行的。因此,基因组学研究在超高维空间,p > > n 中运行。为了证明数学确实在高维空间中爆炸,让我们考虑一个简单的线性模型 Y~X,其中 Y 是感兴趣的表型(疾病),X 是基因型的矩阵(遗传变异)。线性模型的解可以通过基因型的逆方差-协方差矩阵以封闭形式表示如下:

The Curse of Dimensionality in Genomics

接下来,基因型的方差-协方差矩阵的逆是矩阵的行列式的倒数。如果我们现在将空间的维度增加到极限 p > > n,特征(在我们的情况下是突变)变得相关(冗余),因为我们只有有限数量的观察值 n,并且不能再解决它们在高维度中的差异。从线性代数中我们知道,具有相关行或列的矩阵的行列式接*于,这导致基因型的逆方差-协方差矩阵的发散(奇异性)。令人沮丧的是,你永远不知道你的特征在高维空间中有多相关,因此你离奇点有多*。在最好的情况下,你的 R 或 Python 库将抛出一个“奇点”错误,在最坏的情况下,你将得到一个看起来真实的结果/答案,但实际上由于维数灾难而完全膨胀了。****

如果不是基因组学,那么大数据在哪里?

因此,当我的同事谈论基因组学中的大数据时,我想到的是我们可以从这些数据中提取多少统计能力而不是它占用多少磁盘空间。具有讽刺意味的是,我们可以产生数千兆字节的高斯噪声,对其进行分析是完全没有意义的。所以我通常认为,在当前的设置下,在基因组学中运行强大的机器学习并不简单,因为数据量仍然是一个瓶颈。

现在我们终于来到了帖子标题中的问题:“我们有生命科学的大数据吗?”。我的答案是肯定的,但在当前的设置中,基因组学并不专注于遗传变异,即以突变为特征,以基因组为统计观察(样本)。然而,我认为在生命科学的三个领域,我们确实拥有大数据,因此能够并且应该运行机器/深度学习,这些领域是:

  1. 单细胞组学
  2. 显微成像
  3. 基因组学…但是用序列作为统计观察

在我之前的文章中,我解释了为什么单细胞生物学非常适合机器/深度学习。简而言之,这是因为该领域目前正在产生大规模数据集(数百万个细胞)。这里,情况与基因组学相反,我们有 p~20 000 个基因n~1 000 000 个细胞,因此 n > > p 。显微镜成像不需要证明是大数据,事实上,自动化显微镜淹没在图像数据的色调中。最后,基因组学仍然可以被视为大数据,但有一个非常重要的注意事项:不是单个基因组,而是短序列(读取或k-mers)必须被视为统计观察。以这种方式,将核苷酸作为特征,将沿着基因组的短序列(也称为滑动窗口方法)作为统计观察,我们得到了极限 n > > p,这对于机器/深度学习来说是完美的。要了解它在实践中是如何工作的,请查看我的一个帖子,在那里我演示了如何在古代 DNA 上使用深度学习,这也是基因组学数据,只是古代基因组学。

摘要

在这篇文章中,我们了解到基因组数据为生命科学、精准医疗和医疗保健做出了很多承诺。然而,目前分析基因组的方法受到了维数灾难的困扰。这可以通过重新考虑我们在基因组学中定义的特征和样本来避免。单细胞组学和显微成像是生命科学中另外两个大数据方向,它们已经做好准备,应该由机器/深度学习进行分析。

在下面的评论中,让我知道生命科学中的哪些分析方法对你来说特别神秘,我将在这个专栏中尝试解决它们。在 Medium 关注我,在 Twitter @ NikolayOskolkov关注我,在 Linkedin 关注我。我计划写下一篇关于如何为你的 tSNE 选择最佳参数的文章,敬请关注。

我们需要去人性化的人工智能吗?

原文:https://towardsdatascience.com/do-we-need-to-dehumanize-artificial-intelligence-bb83c9395362?source=collection_archive---------37-----------------------

领先的人工智能专家乔安娜·布赖森就过度拟人化人工智能、偏见和安全人工智能的系统设计进行了采访。

“并不是人工智能在接管决策。是人们决定让人工智能负责决策,这是他们当时能够控制的事情。”

Joanna Bryson

乔安娜是巴斯大学人工智能副教授,也是普林斯顿大学的附属机构。她一直致力于各种领域,如自然智能,文化,宗教,也集中在智能系统的设计。她对人工智能的第一次体验可以追溯到 80 年代中期。

我有幸与 乔安娜 交谈了一个小时,探索她更多的深度经历和观点。

你能简单介绍一下你的背景吗?你是怎么进入 AI 的?

“我真的很喜欢编程;我喜欢你能建造世界的事实和它的创造性方面。很高兴我的工作中有这两个部分。”

我的第一个学位是行为科学,属于非临床心理学的一种。那是在芝加哥大学,是一个由所有不同的社会科学学院联合的文科学位。这是我真正关心的,我想了解动物的智力,但由于人类也是非常有趣的动物,所以我一直在关注这些事情。同时,我也是一名非常优秀的程序员。我认为这实际上是我的一个保守的决定,去做我知道自己非常擅长的事情,并把它与我真正感兴趣的事情结合起来。

人们经常将人工智能人性化,这与你的观点相反,因为你强调人工智能现在和将来都与人类智能完全不同……

是的,有两个基本区别。

一是人工智能从定义上来说是一种人工制品。一些我们刻意设计的东西,即使我们选择偶尔掷骰子来设计它,也不会减少我们的责任。

另一个根本的区别是,到目前为止,我们还没有通过克隆来构建它。我说的所有东西都不适用于克隆和生物工程之类的东西。我只是在说,当你用电线和硅建造一个系统时,从现象上看,你永远不会得到同样的东西。你永远也找不到像牛或老鼠甚至果蝇那样离我们如此之*的东西,因为它们在建筑和信息处理方面有着更多的相似之处,在它们如何应对我们所处的世界方面,比我们用电线和硅制造的任何东西都要相似。

我们吃动物;我们毒死他们。我刚刚在华盛顿 DC 读到关于毒杀老鼠的报道,因为很明显现在又有了新的发现。我们对动物做了各种各样的事情,有些人认为你不应该这样做,但问题是,当我们甚至不能下定决心以正确的方式对待老鼠时,为什么我们现在要反其道而行之呢?

为什么我们要设计一些像老鼠和尼斯一样需要保护的东西?

人工智能是我们已经建立起来的东西,虽然我们正在建立我们可以维护的东西,我们可以负责的东西,但我们永远不会有像人类那样经历压力和痛苦等各种事情的东西。那样做实在是个坏主意。

你现在可以造一个机器人,你可以在里面放一个炸弹。你可以放一个传感器和一个时钟,然后说,好吧,如果我五分钟没见到任何人,我就把自己炸飞。你可以这样做,你可能会说这甚至比做人更糟糕,因为当我们被单独监禁时,这对我们来说是一种折磨,但我们活了下来,而这个机器人在五分钟内爆炸,机器人不会在乎。那是单独的一块。这与人类单独监禁的经历不同。

当我们过度拟人化时,我们基本上是在允许自己被人利用。举个例子,我很讨厌别人把智能音箱当智能麦克风来说。

你会怎么称呼它们?

你知道 1984 年吗?我的一个朋友杰森·诺伯说我们应该称之为电幕。

我称之为个人数字助理,也就是我们过去称之为智能手机的东西。早期的智能手机没有联网,但我们只是在上面写东西。

重点是,你有一个个人数字助理,这不是个人的,因为你不知道它被其他人使用了多少,我真的希望我们正在成功做的事情之一(我看到一些迹象)是让人们不再认为物联网是一个好主意。

我参加了在索菲亚举行的欧盟委员会会议,数字大会和东欧的政治家们完全明白这一点。将世界连接在一起意味着你允许隔壁的黑客进入这个世界,所以你需要非常小心你如何设计事物。如果你有一个单独的程序负责,比如说电网,那么这个程序就会变成一个可以被攻破的点,要么直接破解它,要么理解它的工作原理,然后通过绕过它来利用它。您宁愿拥有一个异构的系统。

另一件非常重要的事情是,我们的整个文化和我们所有的概念,如正义、惩罚和责任,都是我们为了维持我们的物种而发展起来的。它们并不只是存在于世界上的东西;它们是我们使用的创新,我们不断更新它们。

我无法相信有多少人认为公*是这个世界固有的状态。去年,我发表了一篇论文,表明你会在任何只接受普通语言训练的人工智能中发现性别歧视和种族主义。有人说,加随机噪声就行了。

添加随机噪声并不能解决任何问题,只会减弱信号。它把它变回熵,但生命不是熵。熵是生命的对立面。生活是结构和秩序,例如,公*是我们不断尝试以一种我们都能受益的方式协调生活。公*是一种非自然的理想。人们生来就不一样高,不一样强壮,不一样的父母,不一样的性别,我们都有很大的生理差异,心理是生理的一部分,是生理的延伸。

我们是不同的,那么公*就是我们如何以对整个社会最有利的方式来应对这些差异,这是我们不断变化的一系列妥协。

为了确保我们开发出增强我们能力的安全人工智能,我们需要在未来五到十年做些什么?AI 正在接管许多决策,我们都有不同的价值观,源于不同的文化。我们如何确保将这一点融入到人工智能的设计中?

“人工智能只是一种我们可以用坏或用好的技术”

接管决策的不是人工智能。决定让人工智能负责决策的是人,这是他们能够控制的事情。他们可以改变人工智能和决策。

它不是人工智能;我们不是与另一个物种或另一个国家谈判。更重要的是理解人工智能是我们已经拥有很长时间的东西;几十年来,我们一直使用数字计算机,它是我们工具箱中的工具之一,我们需要对它有一个很强的概念。我们需要开始讨论这个问题。

再一次,这是拟人化的巨大危险之一,你真的得到了聪明,善意的人,他们正坐在那里试图捍卫人工智能的权利,或者真的想建立这个未来,如果我们被人工智能取代,他们没有意识到,首先,这在技术上是不可思议的,但第二,正如你会说的,在未来三十年左右,几乎肯定会导致更多的人被杀害和毁灭。人们会被政府、公司或富人视为不重要的方面,他们不需要他们作为他们计划的一部分。

人工智能被用作一个挡箭牌,实际上是一个空壳公司,允许人们做他们真正想做的事情,并将注意力转移到一些机器上。

人工智能只是一种我们可以用坏或用好的技术。我们需要回答与其他潜在有害技术相同的问题;储存化学武器的正确方法是什么?部署核电的正确方式是什么,我们是否应该根本不部署核电或者也许它在生态上真的很重要?当我们不仅谈论人工智能,还谈论数据隐私和网络安全时,这些决定也是我们需要做出的决定。这适用于整个信息和通信技术。AI 只是工具箱中的一个工具。

我们正以更个性化的方式与人工智能互动。情感联系呢?

甚至,如果你有一个真正是你最好的朋友的机器人;你可以要求那个机器人可以支持你。那么你就不必担心,例如,如果发生火灾或什么的。你只要把它留在后面,然后再买一个机器人,你就有了后援。

即使你选择与一台机器建立情感纽带,而不是与那些真正能长期帮助你的人建立情感纽带。这是你的个人决定,但你可以要求你没有这种风险,我认为这是一个真正的问题。

当我们在新奥尔良遇到洪水时,需要决定你提供多少资源和支出来确保狗和猫没事,但狗和猫像人类一样做事情,它们在情感上,身体上,做非常相似的事情,但问题是我们只有这么多资源。在我们开始营救狗之前,我们如何确保没有孩子被落下?此外,这些家庭不会不带着他们的狗来。同样的事情也发生在东海岸的桑迪身上。动物被抛在后面,它们在挨饿,人们对此非常关注。

为什么我们要将自己置于这种技术的境地,这种技术的设计方式可以确保我们不会遇到这种问题?

了解了与人工智能相关的危险,告诉我们你在 90 年代初的博士课题,以及它与人工智能安全的关系?

“像尼克·博斯特罗姆这样的人犯的错误是,如果你真的建立了一个系统,它将世界变成回形针的可能性为零…如果这个系统是自治的,它在你保证会在其中的优先级别上是自治的…”

甚至在我还是大学生的时候,人们就在谈论模块化。例如,当你开车的时候和当你是行人的时候,你是一个不同的人,因为你有如此不同的态度。看起来你的头脑中有这些不连续的部分,你不只是一个大东西。

当时甚至连哲学家都在讨论这个问题。当我在本科学位和博士学位期间从事专业编程时,人们开始意识到也许你不需要一台大型主机,也许你可以有一堆不同的计算机并像网络一样创建。现在它显然被称为云,但在当时它是一件大事,人们说,“哦,是的,客户端、服务器、架构……也许我们可以基于现有的硬件让一些计算执行专门的不同任务”。

后来,当我开始攻读硕士学位时,我看到了罗德尼·布鲁克斯和一群其他人在做的事情,他们对他的工作感到非常兴奋。它被称为基于行为的设计,其理念是不要试图建造像人一样复杂的东西,而是建造相对简单的模块,每个模块感知它需要感知的东西,以便做它需要做的事情。

行为导向设计) (BOD)是我在博士期间开发的开发方法论,用于创建复杂、完整的代理,如虚拟现实角色、自主机器人、智能导师或智能环境。BOD 代理是模块化的,但不是多代理系统。

我意识到的另一件事是,你不仅需要记忆来拥有智能,而且这也是模块的核心。决定你何时需要一个模块的一个因素是你需要什么样的信息来做感知和行动。然而,进入游戏行业的另一个组成部分是如何在这些模块之间进行仲裁。

一旦你把某样东西拆成碎片,问题之一就是如何把它重新组装起来,你需要连贯的行为。尽管如此,你还是可以自主地做某些事情,比如躲避火焰的反射,这是任何生物都必须做的事情。有某些种类的资源,比如你的物理位置,完全由所有的模块决定。那时我创造了现在所谓的行为树。我们称之为 P.O.S.H. (并行根,有序滑栈分层动作选择)。

基本的想法是,你想使用面向对象的设计(标准软件工程),但你真正需要为人工智能做的一件事是说什么是系统中的优先事项,因为人工智能系统是主动的。它实际上必须认识到它将要行动的环境,事实上,它必须为了自我*衡的原因而行动。它必须采取行动,因为它知道它需要做些什么,它有一个目标。

我在博士论文的结尾写道,这对于安全的人工智能非常重要,如果你只在模块中学习,人工智能系统会变得多么邪恶是有限度的。

我并不真的担心邪恶的人工智能,但我担心的是无法保证,例如,它会知道如何逃离火灾或其他什么。

所以,你必须有一定的高优先级,来保证系统相对确定。即使你使用机器学习,也可以以确定的方式使用,因为它可能有边界,你不允许系统更新它的学习。如果它看起来不符合性能准则,您可以在系统周围建立确定性的围栏,试图改善系统的某个方面。

像尼克·博斯特罗姆这样的人犯的错误是,如果你真的建立了一个系统,它将世界变成回形针的可能性为零。他担心高层次优先级之间的一致性,以及较低层次会发生什么,但你没有给较低层次完全的自主权。如果这个系统是自治的,那么它是自治的,自治的层次是你所拥有的优先级,这些优先级被保证在其中,它们的子部分去学习做某事的最佳方式。如果系统的其余部分,通常包括任何人工智能,人类,注意到没有金属或其他东西的再消耗,那么它会关闭系统的这一部分。

你能举个例子来说明这一点吗?你是说,你没有一个可以自主工作的系统,而是设计了一个具有不同组件的模块化系统,这些组件相互控制,从而控制系统……

我们都想生活在一个至少足够稳定的社会中,我们可以计划一个公司或家庭或其他事情。

比特币就是一个例子。最初没有人预计比特币会消耗如此多的能量,但现在每个人都在试图找出如何监管它。这在某种程度上是一个自我调节的问题,因为人们负担不起那种权力。

权力是有成本的,所以只要没有无限的价值被任意分配给庞氏骗局,也就是比特币,那么它能够购买多少权力就会受到限制。

然而,似乎还有其他监管力量可能以任何方式到来,并说;你们没有为你们造成的环境破坏支付公*的份额,然后他们可能被迫实际上,也许不仅仅是他们,而是所有的环境,所有的电力消费者可能突然发现他们自己是关于比特币的对话的结果,实际上为他们正在破坏的基础设施,全球基础设施支付更适当的金额。

重点是你可能会失败,但那是因为有人参与。这被称为认知错误检测。这是一种意识,事情并不总是朝着好的方向发展。因此,在构建系统时,您应该做的一件基本事情是确保您构建的组件可以检查其他组件。事实上,这是构建强大系统的一种更简单的方法,因为您有简单的组件来检测其他组件何时偏离轨道。

我并不是说每件事都那么好就一定是真的。企业和其他各种实体给世界造成巨大破坏的例子不胜枚举。这并不是说世界是绝对安全的,什么都不会发生,而是我们可以遵循一些过程,使我们更有可能及早发现这些过程,并防止它们造成太大的损害。

这是我现在正在做的事情之一,只是试图与立法机构沟通,你可以让使用人工智能的人负责。

我也在和公司交流。两周前,我刚刚与微软和谷歌讨论过这个问题,这是我所期待的。

你将不再只是链接到任何任意的软件库,你已经从互联网上下载,你不知道它的出处,你不知道谁侵入了它或什么。

相反,你必须能够展示,你使用了什么版本的软件系统,你使用了什么版本的数据库来训练你的机器学习,你的程序是什么。如果你没有这些记录,那么你就不能证明你已经尽职,你就要对你或其他人使用你的软件造成的任何损害负责。

这不是唯一的方法。如果你看看像医学或汽车工业这样的行业,他们已经有了开发人工智能和记录过程的良好实践,他们有大量的人工智能。每个人都在谈论无人驾驶,但每个汽车制造商都有大量的人工智能试图改善驾驶体验,让汽车更安全,他们已经证明了这一点,这不是不可能的。它甚至没有那么难,并且当你小心你的软件工程时,它确实花费你多一点时间去市场,但是它也更容易维护和扩展你的代码。

我认为我们需要长大。例如,在当时的建筑中,你可以在任何你想去的地方建造一座建筑,这将给城市交通带来各种各样的混乱,有时建筑会倒塌压死人。你现在所拥有的是正在获得建筑学学位的本科生学习如何与城市规划者交谈,他们将获得许可并学习如何获得许可,建筑物得到检查。

我认为我们很可能会在那种地方结束,这并不意味着 IP 的终结。医药受到严格监管,严格检查,但它的知识产权是软件和技术产业的十倍。我认为我们只是要定义我们开发事物的过程。事情在变化,这对我们的社会有好处。

我们都想生活在一个至少足够稳定的社会中,我们可以计划一个公司或家庭或其他事情。

我们是否更喜欢廉价汽车的更昂贵的变种?

原文:https://towardsdatascience.com/do-we-prefer-the-more-expensive-variants-of-cheap-cars-cf7c1abf271f?source=collection_archive---------30-----------------------

印度尼西亚低成本绿色汽车销售数据的线性回归实践

Nissan’s booth at GIIAS 2019

去年 2019 年 6 月,印尼刚刚举办了印尼最大的车展之一,Gaikindo Indonesia International Auto Show(gi IAS)。有一些新车我*期不会买。尽管如此,我还是和爸爸一起去了。

很明显,那里有很多车。但我特别关注不太贵的汽车,如 LCGCs(低成本绿色汽车)、小型掀背车、中型 MPV(如丰田 Avanza)和 SUV(著名的五菱 Almaz)。这些车是普通工薪阶层一生都有机会拥有的车。

我只是看了看那里的车。我注意到每种车型通常都有许多变体。例如,如果我说我想要下图的大发 Ayla。

A Daihatsu that looks awfully similar with a Perodua. Source: daihatsu.co.id

看看他们网站上的价格表,你可以看到他们出售的变体,提供不同的配件功能和…可选的安全气囊(我没有发现任何法规说安全气囊在印度尼西亚是强制性的)。名称中带有“AB”的变体意味着特定的变体有安全气囊,而没有的……可能没有,你必须检查规格细节。

Source: daihatsu.co.id

经常听亲戚说最好买最高配的车型。列举理由说这是一次性的大采购,所以还不如多花些钱(同样的理由也适用于奢华的婚礼,但那是完全不同的讨论)。因此,这将意味着,当购买大发 Ayla 时,他们会更喜欢购买“1.2 R AT DLX”而不是“1.0 X AB AT”,价格约 1600 万印度卢比。

然而,我认为,购买廉价汽车的人在购买时肯定会将价格作为最重要的因素之一,因为他们有预算意识。当我们打算买一辆便宜的车时,我认为买最便宜的是最好的选择。

大家真的都是这样吗?需求的经济学法则表明,价格上涨会导致对商品的需求减少。也许买车是法律不适用的一个例子。

我要看看上面斜体的陈述是真是假。我会:

  1. 形成假设,
  2. 将杂乱的 pdf 数据准备成可读性更好的格式,
  3. 使用线性回归来证明/否定我的假设,
  4. 搞清楚结果!

1.从假设开始!

这一次,我将尝试看看人们是否真的更愿意购买低价绿色汽车(LCGC)中最贵的一款。

或者换句话说:如果价格点真的影响购买低成本绿色汽车的决定。所以我的假设是:

h0:对于 LCGC,价格(P)不影响销售量(Qs)

h1:对 LCGC 来说,价格影响销售量。这就是我在这里要证明的!

对于外行来说,LCGC 是一类相对便宜的车,小发动机/排量不超过 1,200 cc。一个例子是我之前展示的大发 Ayla。

为什么我坚持去 LCGC?我假设每种类型的汽车有不同的目标市场,因此会有不同的表现。例如,购买廉价汽车(低于 2 亿印尼盾)的人可能会与购买昂贵 SUV(高于 3 亿印尼盾,如三菱帕杰罗 Sport)的人有所不同。我最初的假设是,购买廉价汽车的人会更注重成本,因此更有可能选择更便宜的车型。而购买更贵汽车的人会更富有,买得起最好的车型。稍后我会做其他部分。

(如果你对 R 或数据相关的东西不感兴趣,你可以直接跳到第三部分。分析数据)

2.数据准备!

在这里,我有从 Gaikindo 网站批发的 2019 年 1 月至 6 月期间的数据。批发数据指的是制造商对经销商的销售(不是经销商对最终客户的销售),但这个数据总比没有好。

数据是 pdf 格式的,所以我把它转换成了 excel 文件,这是互联网上的一个免费工具,ilovepdf.com。如果你谷歌一下,网上有很多免费工具可以做到这一点。你把你要转换的 pdf 文件上传到网站,它会帮你转换成 excel 文件。请注意不要使用免费网络工具处理任何机密数据。

即使这样,数据仍然非常混乱,所以我只是用 Microsoft Excel 清理了一下(我知道,请不要评判)。我们需要清理数据,以便进行适当的分析。

这些数据也不包括汽车价格,所以我手动搜索网页把它们放在那里。我这样做是因为我试图证明价格对销售量的影响,所以很明显我需要价格数据(我们在原始数据中已经有了销售量)。所以数据应该是这样的。

The data, excluding the sales (got cropped, it’s still way further right)

你必须放大,但如果你只是下载原始文件,你可以看到它实际上很漂亮。它包括车型、排量(cc)、油箱容量、车辆总重、尺寸、座椅、车门、每月销量等等。

这个测试的目的是看价格点实际上是否影响销售量。因此,我将数据分解为:1)价格点,2)2019 年 6 月的总销售额(我现在不需要其他列)。

The test data-set

我得到了 57 行,每一行代表了每种型号的一个特定变体。其中 6 个没有价格,因为…我没有找到它们。不过没关系。

数据准备好之后,就该实际进行回归了。在“psych”(用于统计)、“tidyverse”(用于操作数据和可视化)和“ggthemes”(用于向可视化添加附加主题)包的帮助下,我正在使用 RStudio 进行回归。

使用 R 进行回归非常简单(如果您不喜欢 R,可以直接跳到第 3 部分) :

lin.regress <- lm(TOTAL ~ PRICE, data = LCGC_TEST)

我使用 lm()函数,将 TOTAL(销售量)作为因变量,PRICE 作为自变量。你可以把“总额~价格”理解为“总额受价格影响”。我将结果存储在一个名为“Lin . regressive”的变量中,这样我就可以随时调用它。

下一步是在散点图和回归线中可视化回归。我使用散点图是因为我想在这里比较价格和销售量。两者都是数值(连续)数据。“回归线”只是一条可以将所有可用数据点*似为一条线的线,具有尽可能小的误差。

ggplot(LCGC_TEST, aes(PRICE, TOTAL)) +
 geom_point()+
 theme_economist_white(base_family = “sans”,gray_bg=T)+
 labs(x=”Vehicle Price”, y=”Sales Quantity”, title=”Vehicle Price to Sales Quantity”)+
 stat_smooth(method = “lm”,se=FALSE)

3。通过图形的可视化和解释来分析数据

The regression result

一目了然,我们可以看到,至少在廉价汽车(LCGC)细分市场,回归线表明价格的增加也会增加销售量。尽管有些松散。您可以看到,大多数数据点都集中在原点(零)线附*,并且似乎被几个高销售额和价格的数据点向上拉。

那只是视觉上的解释。为了更好地理解,我们需要查看包含许多有用信息的回归表,例如:

  1. “价格”作为销售量的预测指标有多强?
  2. 模型实际上有多好?

在 R 中,您只需要调用下面的代码加上存储回归模型的变量,我在前面将其命名为“Lin . regressive”。

summary(lin.regress)

Regression table result, focus on the ones in the boxes (I don’t understand the others)

4.理解回归表

“价格”作为销售量的预测指标有多强?

请看名为“估计”的第一列。这里的两个值是系数。如果你还记得你的代数:

y=ax+b

给定某个值 x. 你试图找出 y 的值,这和回归有点类似!我们试图找到给定某个价格点(P)销售量(Qs) :

Qs=a(P) + b

估计栏中的两个值是系数,即 ab. “截距”是给定预测值(价格)为 0 时的值。根据回归表,对于 IDR 0 价位的汽车,将有…-9514 辆销售。这完全说不通。但我们会继续。

“价格”中的估计值显示了价格上涨对销售量的影响。根据回归表,对于 IDR 1 的车辆价格的增加,我们将看到 0,0000882 销售的增加。为了获得更好的视角,将其乘以几倍。每增加 1000 万印度卢比的价格,我们将获得额外的 882 笔销售额。我也认为这说不通,为什么人们?

不管怎样,现在我们有了这个公式:

Qs = 0,0000882(P) - 9514

现在我们到了有趣的部分。让我们假设显著性水*为 5%,这是一个常见的标准。当 h0 为真时,我们接受拒绝 h0 的 5%风险。在这种情况下,我们接受 5%的风险,认为价格影响销量,而实际上它并不影响任何东西。

看一下“价格”行的最右边一列。那就是 P 值。

简单地说,在这种情况下,P 值回答了这个问题,“在一个价格不影响销售量的世界里,如果我使用早期的回归方法来预测销售量,会有多奇怪?”

在这种情况下,答案是 2.41%有点奇怪。

结合 5%的显著性水*和 2.41%的 P 值,我们可以在 5%的显著性水*上安全地拒绝 h0 或零假设。意味着我们拒绝价格不影响销售量的假设。

模型有多好?

下一步将是检验模型实际上有多好。一看就知道不会那么好。看一下回归线。

The regression result, for reference again

我可以把问题换成“我的模型有多差?”

为此,我们来看看“调整后的 R *方”。这个值显示了销售量的多少变化可以用价格来解释。

我的模型很差,大概 8.1%差。一般来说,社会学科公认的 R *方约为 20%。

还有很多其他因素可以解释其余高达 91.9%的数字。

结论

至少现在我们知道,在 5%的显著性水*上,对于印度尼西亚 LCGC 市场,价格点确实对销售量有影响。这种关系是正的(高价格导致高销售量),模型是…在 8.1%调整后的 R *方不太好。

也就是说,我们更喜欢更贵的廉价汽车,这并没有错……但这不是唯一的决定因素。我想寻找便宜汽车的人不会那么吝啬。

你知道可信区间吗

原文:https://towardsdatascience.com/do-you-know-credible-interval-e5b833adf399?source=collection_archive---------4-----------------------

不要搞砸你的下一次数据科学/分析师/项目经理面试

如果你申请的职位涉及 AB 测试、SQL 或任何类型的用户体验研究,你的面试官最喜欢的问题可能是:“这是 XYZ 实验的置信区间。是什么意思?”有两种方法可以回答这些问题:

"总体参数有 95%的可能性位于区间内."

“如果我们将实验重复无限多次,95%的实验将在它们的置信区间内捕获总体参数。”

不幸的是,如果你回答了第一种方式,你就相当于面试失败了。大多数人分不清这两种说法的区别,可以蒙混过关。但作为数据专家,你不能。第一种说法是解释贝叶斯可信区间。第二,频率主义者的置信区间

为什么这么困惑

如果你从未上过统计推断课,你可能会认为第二种说法只是第一种说法的转述。其实区别是深刻的。这可以归结为两种对立的概率意识形态:频率主义者和贝叶斯主义者。

贝叶斯将概率定义为一种“信念”一个信念可能强也可能弱,并且会随着新证据的出现而不断修正。信念本身由概率分布来描述。例如,我对*均用户结账时间的看法可以是这样的:“*均结账时间在 44 ~ 46 秒之间的概率为 3.5%;*均结账时间在 11 ~ 24 秒之间的概率为 34%。”请注意,我不是在陈述*均结账时间的精确值,我是在陈述不同的范围,以及这些范围的概率。

频繁主义者用“频繁试验”来定义概率。一位常客认为,一个人群参数是固定的(比如糖尿病率、转化率、*均结账时间),找到它的唯一方法是通过多次实验。因为真实世界的实验通常是昂贵的,我们使用中心极限定理从单个实验中推导出与我们通过进行多个实验得到的相同的抽样分布。

困惑的一个主要来源是频繁主义者不会在现实世界中频繁地做实验。他们做一个实验,产生一个置信区间,就像贝叶斯做的一样。这仅仅是因为中心极限定理给了他们一个便捷的捷径,从重复实验中节省了大量的金钱!

两个动画示例

置信区间就像掷环游戏。职位是固定的,就像人口参数一样。你把戒指扔到柱子上。有时候你错过了,有时候你抓住了。你选择一个足够大的戒指,这样你就可以在 95%的时间里抓住邮件。环的大小就像你 95%的置信区间大小。

Ring toss game is like confidence interval

类似地,frequentist 进行实验无数次,并为每个实验建立一个点估计(例如,样本均值、比例),一个置信区间。点估计的分布称为抽样分布。在下面的动画中,总体*均值固定为 0.078,蓝色圆点表示置信区间的上限,橙色圆点表示置信区间的下限。大多数置信区间将捕获总体参数。有些音程不会(当蓝点降到红线以下,或橙点升到红线以上)。常客将选择一个足够大的间隔,该间隔在 95%的时间内捕获群体参数。

贝叶斯不关心抽样分布。他们将他们对总体参数的信念建模为后验分布。一个经典的例子是评估一枚硬币是否公*。随着你不断地抛硬币,你对它正面/反面落地的概率越来越有信心。

在下面的例子中,每次迭代都是抛硬币。⍺.清点了人数尾部按β计数。因为人数和人数几乎总是相等的。我们越来越有信心落地头的概率是 50%。这个关于概率的概率分布是用贝塔分布建模的(见教程这里)。

编码吧!

假设我们掷一枚硬币 10 次。不幸的是,我们有 7 个头和 3 条尾巴。这枚硬币是公*的证据不足。后验概率看起来是这样的:峰值出现在 70%,因为我们在 10 次试验中得到 7 个头。

为了建立可信区间,我们简单地从后验分布中截掉左尾或右尾,或者两者都截掉,使得剩余的概率质量(称为“似真性”)是所期望的。例如,我们可以从任意一个尾部截断 5%,得到 90%可信区间[0.436,0.865]:

此外,我们可以从右尾截断 10%,得到一个更宽的可信区间[0.000,0.831]:

任何一种情况都是有效的 90%可信区间,因为每种情况都包含 90%的概率质量(似真性)。你觉得哪个更有用?显然这是我们想要的窄一点的。最窄的可信区间称为最高密度区间。

另一方面,要构建置信区间,我们必须依靠中心极限定理来构建抽样分布,查找 t 得分/z 得分,然后从点估计值中加上/减去某个倍数的标准误差。

Sampling distribution

比较

可信区间的一个优点是我们可以在后验分布中建立规则。例如,beta 分布的范围在 0 ~ 1 之间,为概率提供了一个很好的界限。另一方面,抽样分布总是正态的,其范围是无限的。所以在这种情况下,它显然是有缺陷的,因为一枚硬币落地的概率不可能大于 1,或者小于 0。当样本量很小时,这是有问题的,并且大量的正态分布位于范围[0,1]之外。

Normal distribution does not truncate probability at 0 or 1, yielding poor results when sample size is small

可信区间的另一个优点是,我们可以在进行实验之前考虑一个先验。如果其他人已经扔了 50 次硬币,并记录了 20 次正面,那么我们已经知道了一些关于硬币的信息。所以贝塔后验的峰值(众数)上升得更快,变窄得比抽样分布更快。因此,可信区间比置信区间缩小得更快。

Effect of prior on posterior convergence speed

没什么可失去的?

“到目前为止还不错。为什么不总是使用可信区间?”你可能会问。问题是,并不是每个实验都有一个优雅的后验分布。尽管有贝塔分布来模拟转换率、糖尿病率或任何其他概率。对于检查时间、预计到达时间、体重、身高、血糖,没有精确的后验概率。事实上,贝塔分布是个例外,而不是常态。在杂乱的现实世界中,正态分布是常态。

幸运的是,我们生活在互联网的世界里。在交通便宜的地方,中心极限定理总是胜利的,两种方法之间的差别缩小了。相比之下,可信区间的优势在样本量很小时最有价值,因此成本很高,例如,让 10 名患者接受两种不同类型的医学治疗。

Credible interval (blue) and confidence interval (red) become similar as sample size increase

延伸阅读

下面的博客涵盖了与 AB 测试相关的主题,以及对本文中提到的关键概念的更深入的回顾。

  • 可视化贝塔分布和贝叶斯更新[ 链接
  • 理解置信区间[ 链接
  • A/B 测试的威力[ 环节
  • 超越 A/B 测试:多臂强盗实验[ 链接 ]
  • 可信区间上的 Kaggle 笔记本[ 链接

你知道如何在 7 种不同类型中选择正确的机器学习算法吗?

原文:https://towardsdatascience.com/do-you-know-how-to-choose-the-right-machine-learning-algorithm-among-7-different-types-295d0b0c7f60?source=collection_archive---------0-----------------------

这是一种通用、实用的方法,可以应用于大多数机器学习问题:

这个故事由七篇文章组成,每篇文章都有一个算法,每篇文章都从头开始实现,请确保关注我们的时事通讯,这样当我们从头开始发布每个算法时,您就可以收到更新。

1-对问题进行分类
下一步是对问题进行分类。
按输入分类:如果是有标签的数据,那就是监督学习问题。如果是以寻找结构为目的的无标签数据,那就是无监督学习问题。如果解决方案意味着通过与环境交互来优化目标函数,这就是一个强化学习问题。
按输出分类:如果模型的输出是数字,那就是回归问题。如果模型的输出是一个类,那就是一个分类问题。如果模型的输出是一组输入组,这就是一个聚类问题。

2-了解你的数据 数据本身并不是最终游戏,而是整个分析过程中的原材料。成功的公司不仅能够捕获和访问数据,还能够获得推动更好决策的洞察力,从而带来更好的客户服务、竞争优势和更高的收入增长。理解数据的过程在为正确的问题选择正确的算法的过程中起着关键作用。一些算法可以处理较小的样本集,而其他算法需要大量的样本。某些算法处理分类数据,而其他算法则喜欢处理数字输入。

分析数据 在这一步中,有两个重要的任务,一是用描述性统计理解数据,二是用可视化和图表理解数据。

处理数据

转换数据 将数据从原始状态转换成适合建模的状态的传统思想正是特征工程的用武之地。事实上,转换数据和特征工程可能是同义词。这是后一个概念的定义。特征工程是将原始数据转换为特征的过程,这些特征可以更好地代表预测模型的潜在问题,从而提高未知数据的模型准确性。作者杰森·布朗利。

3-找到可用的算法 在对问题进行分类并了解数据后,下一个里程碑是确定在合理的时间内实施的适用且实用的算法。影响模型选择的一些因素有:

  • 模型的准确性。
  • 模型的可解释性。
  • 模型的复杂性。
  • 模型的可扩展性。
  • 构建、训练和测试模型需要多长时间?
  • 使用模型进行预测需要多长时间?
  • 模型符合商业目标吗?

4-实现机器学习算法。 建立一个机器学习管道,使用一组精心选择的评估标准来比较数据集上每个算法的性能。另一种方法是在数据集的不同子组上使用相同的算法。对此的最佳解决方案是执行一次,或者让服务在添加新数据时定期运行。

5-优化超参数。优化超参数有三个选项,网格搜索、随机搜索和贝叶斯优化。

机器学习任务的类型

  • 监督学习
  • 无监督学习
  • 强化学习

监督学习 监督学习之所以如此命名,是因为人类充当了指导者的角色,教导算法应该得出什么结论。监督学习要求算法的可能输出是已知的,并且用于训练算法的数据已经标注了正确的答案。如果输出是一个实数,我们称之为任务回归。如果输出来自有限数量的值,其中这些值是无序的,那么它就是分类。

Supervised Learning

无监督学习 无监督机器学习更接*一些人所说的真正的人工智能——即计算机可以学习识别复杂的过程和模式,而无需人类提供指导。关于对象的信息较少,特别是,训练集是未标记的。有可能观察到对象组之间的一些相似性,并将它们包含在适当的集群中。一些物体可能与所有的星团有很大的不同,这样这些物体就成了异常。

Unsupervised Learning

强化学习 强化学习(Reinforcement learning)是指面向目标的算法,它学习如何通过许多步骤实现复杂的目标或沿着特定的维度最大化。例如,在一场游戏中,通过多次移动来最大化赢得的点数。它与监督学习的不同之处在于,在监督学习中,训练数据带有角色密钥,因此模型是用正确的答案本身来训练的,而在强化学习中,没有答案,而是由强化代理决定如何执行给定的任务。在没有训练数据集的情况下,它必然会从自己的经验中学习。

Reinforcement Learning

常用的机器学习算法

1-线性回归 线性回归是一种统计方法,允许总结和研究两个连续(定量)变量之间的关系:一个变量,表示为 X,被视为自变量。用 y 表示的另一个变量被认为是因变量。线性回归使用一个自变量 X 来解释或预测因变量 y 的结果,而多元回归根据均方误差(MSE)或*均绝对误差(MAE)等损失函数,使用两个或多个自变量来预测结果。因此,每当你被告知要预测当前正在运行的某个流程的未来值时,你可以使用回归算法。尽管这种算法很简单,但当有成千上万个特征时,例如,自然语言处理中的一袋单词或 n-grams,它仍然工作得很好。更复杂的算法会过度拟合许多特征,而不是庞大的数据集,而线性回归提供了不错的质量。然而,在特征是冗余的情况下是不稳定的。

从头开始查看我们关于这个话题的最新报道。

Linear Regression

2-逻辑回归 不要把这些分类算法和回归方法混淆,因为在标题中使用了回归。逻辑回归执行二元分类,因此标签输出是二元的。当输出变量是分类变量时,我们也可以将逻辑回归视为线性回归的一个特例,其中我们使用概率的对数作为因变量。逻辑回归有什么了不起的?它采用特征的线性组合,并对其应用非线性函数(sigmoid ),因此它是神经网络的一个微小实例!

Logistic Regression vs Linear Regression

3-K-means 假设你有很多数据点(水果的测量值),你想把它们分成苹果和梨两组。 K-means 聚类是一种聚类算法,用于自动将一个大组划分为更小的组。
该名称的由来是因为在我们的示例中,您选择了 K 个组,K=2。你取这些组的*均值来提高组的精度(*均值等于均值,你这样做几次)。集群只是组的另一个名称。
假设你有 13 个数据点,实际上是 7 个苹果和 6 个梨,(但你不知道),你想把它们分成两组。对于这个例子,让我们假设所有的梨都比所有的苹果大。您选择两个随机数据点作为起始位置。然后,你将这些点与所有其他点进行比较,找出哪个起始位置最接*。这是你第一次通过聚类,这是最慢的部分。你有你的初始组,但是因为你随机选择,你可能是不准确的。假设一组有六个苹果和一个梨,另一组有两个苹果和四个梨。所以,你取一组中所有点的*均值作为该组的新起点,对另一组也这样做。然后再次进行聚类以获得新的组。
成功!因为*均值更接*每组的大多数,所以在第二次循环中,你会在一组中得到所有的苹果,在另一组中得到所有的梨。你怎么知道你完成了?计算*均值,然后再次进行分组,看看是否有分数改变了分组。没有,所以你完了。否则,你会再去一次。

K-means

KNN
直截了当地,两人寻求完成不同的目标。 K *邻是一种分类算法,是监督学习的子集。 K-means 是一种聚类算法,是无监督学习的子集。
如果我们有一个足球运动员、他们的位置和他们的尺寸的数据集,并且我们想要在一个新的数据集中给足球运动员分配位置,其中我们有尺寸但是没有位置,我们可以使用 K-最*邻。
另一方面,如果我们有一个需要根据相似性分成 K 个不同组的足球运动员数据集,我们可能会使用 K-means。相应地,每种情况下的 K 也意味着不同的东西!在 K-最*邻居中,K 代表在确定新玩家位置时有投票权的邻居的数量。检查 K=5 的例子。如果我们有一个新的足球运动员需要一个位置,我们在数据集中选择五个测量值最接*我们的新球员的足球运动员,让他们投票决定我们应该给新球员分配的位置。
在 K-means 中 K 表示我们最终想要拥有的集群数量。如果 K= 7,在我的数据集上运行该算法后,我将有七个足球运动员的聚类,或不同的组。最后,两个不同的算法有两个非常不同的目的,但它们都使用 K 的事实可能会非常混乱。

K-nearest neighbors

5-支持向量机 SVM 使用超*面(直的东西)来分离两个不同标记的点(X 和 O)。有时候点是不能用直的东西分开的,所以它需要把点映射到一个更高维的空间(用内核!)在那里它们可以被直的东西分割(超*面!).这在原始空间上看起来像一条曲线,尽管在一个更高维度的空间中它实际上是一条直线!

Support Vector Machines

6-随机森林 假设我们想知道何时投资宝洁,那么我们有三个选择买入、卖出和持有,基于上个月的几个数据,如开盘价、收盘价、价格和交易量的变化
假设你有很多条目,900 点的数据。
我们要建立一个决策树来决定最佳策略,例如,如果股票价格的变化比前一天高百分之十以上,我们就以高成交量买入这只股票。但是我们不知道使用哪些功能,我们有很多。
因此,我们采取了一组随机的测量方法和一组随机的训练样本,并构建了一个决策树。然后,我们使用不同的随机测量组和每次随机数据样本进行多次相同的操作。最后,我们有许多决策树,我们使用它们中的每一个来预测价格,然后基于简单多数来决定最终的预测。

Random Forest

7-神经网络
神经网络是人工智能的一种形式。神经网络背后的基本思想是模拟计算机内部大量密集互连的脑细胞,以便它能够以类似人类的方式学习事物、识别模式和做出决定。神经网络的神奇之处在于,它不必通过编程来明确学习:它完全是自己学习,就像大脑一样!
神经网络的一方面是输入。这可能是一张照片,来自无人机的数据,或者围棋棋盘的状态。另一方面,有神经网络想要做的输出。在这两者之间有节点和连接。连接的强度决定了基于输入需要什么样的输出。

Artificial Neural Network

或者,你可以获得 5 美元/月的中等订阅。如果你使用这个链接,它会支持我。

你知道 K_Nearest_Neighbors 也可以用于回归任务吗?

原文:https://towardsdatascience.com/do-you-know-k-nearest-neighbors-can-also-be-used-for-regression-tasks-117da22bcac3?source=collection_archive---------18-----------------------

是的,它是!让我们来理解这个简单的算法

source: researchgate.net

你有什么好处?

本文将揭示最简单易懂的最大似然算法——K *邻算法。它可用于分类和回归任务,但在分类中更常见,因此我们将重点放在分类上,并了解如何将其用作回归变量。不过,这些原则在这两种情况下都适用。

我们来谈谈数据

这一次,我不会像在我的其他文章中通常所做的那样挑选任何数据集。如果数据集能给我一个机会来解释一个概念、一个陷阱或一种方法,那么我会选择数据集。就像我承认的,这是最简单的 ML 算法。我将使用与 sklearn 捆绑在一起的乳腺癌数据集。

就这么简单吗?

基本上,算法如下:

  1. 定义𝑘
  2. 定义距离度量,通常是欧几里德距离(2 范数距离)
  3. 对于新的数据点,找到𝑘最*的训练点,并以某种方式(通常是投票)组合它们的类,以获得预测的类

就是这样!

KNN 的好处

  • 它实际上不需要任何传统意义上的训练。你只需要一个快速的方法来找到最*的邻居。
  • 容易理解

KNN 的弊端

  • 我们需要定义 k,这是一个超参数,因此它可以通过交叉验证进行调整。k 值越高,偏差越大,k 值越小,方差越大。偏差和方差总是在跷跷板上,所以从技术上来说,你不可能一箭双雕。必须有所取舍。

专业提示:在一个模型中,如果你必须减少方差,然后引入大的训练集,这不是在所有情况下都可行的选择。如果您必须减少偏差,那么添加特征(预测值)会有所帮助,但代价是引入额外的方差。我的文章中有更多提示

  • 必须选择一个距离度量,根据度量的不同,可能会得到非常不同的结果。同样,你可以使用交叉验证。
  • 它并没有真正提供哪些特性可能是重要的见解。
  • 由于维数灾难,它可能会受到高维数据的影响。

基本假设:

  • 对于我们的目标来说,接*的数据点是相似的

什么是维度的诅咒?

这是一种忧郁的表达,但它意味着数据中更高的维度顺序。

为什么这是一个问题?我听到了。我们无法将数据可视化。可视化就像第一世界国家的问题,有更多的噪音,但实际上非常琐碎。

更大的问题是,当你增加维度时,代表你的数据的数据点也会增加,数据变得更加分散。很可能*点并不比*均距离*多少,也就是说*并没有多大意义。KNN 在数据点之间的距离上工作,因此它将使这个算法低效。

如果你很好奇,想直观的知道为什么会这样。去这里

欧几里得距离

对于被比较的向量 q 和 p(这些将是我们的特征向量):

Source: Wiki

这不是结局。还有许多其他距离度量。我将在本文后面讨论术语。该算法最优选的距离范数是曼哈顿(1 范数)或欧几里德(2 范数)。

型号

你可以在这里跟随代码

你如何确定 K 值?

没有科学的方法来确定一个。我们只需要反复试验。网格搜索为了解决这个问题,我将 KNNClassifier 管道化到网格搜索中,以了解最佳超参数。

grid search report

看起来在这种情况下,K = 5 的均匀权重方法效果最好。

了解关于分类指标的更多信息。跟进我的文章

投票方法的类型

  • 多数投票:在你选择了𝑘最*的邻居后,你对这些邻居的班级进行了“投票”。新的数据点被分类为邻居的大多数类。如果您正在进行二元分类,建议您使用奇数个邻居,以避免票数相等。然而,在一个多类问题中,更难避免*局。对此的常见解决方案是降低𝑘,直到*局被打破。
  • 距离加权:不是直接对最*的邻居进行投票,而是根据该实例与新数据点的距离对每一票进行加权。一种常见的加权方法是

或者是新数据点和训练点之间的距离。新的数据点被添加到具有最大增加权重的类别中。这不仅减少了*局的机会,而且还减少了数据失真的影响。

距离度量

欧几里德距离或 2 范数是一种非常常用的𝑘-nearest 邻居距离度量。任何𝑝-norm 都可以使用。

p-norm

然而,对于分类数据,这可能是一个问题。例如,如果我们将汽车颜色的特征从红色、蓝色和绿色编码为 0、1、2,如何测量绿色和红色之间的“距离”?您可以创建虚拟变量,但是如果一个特性有 15 个可能的类别,这意味着您的特性集要增加 14 个变量,我们会遇到维数灾难。但是要注意分类特征对最*邻分类器的影响。

搜索算法

假设数据集包含 2000 个点。对一个点的 3 个最*邻居的强力搜索不需要很长时间。但是如果数据集包含 2000000 个点,强力搜索可能会变得非常昂贵,尤其是在数据的维度很大的情况下。其他搜索算法为了更快的运行时间而牺牲了穷举搜索。像 KDTrees 或 Ball trees 这样的结构用于更快的运行时间。虽然我们不会深入研究这些结构的细节,但请注意它们以及它们如何优化您的运行时间(尽管训练时间确实会增加)。

另一种类型:半径邻居分类器

这与𝑘最*邻分类器的想法相同,但不是查找𝑘最*邻,而是查找给定半径内的所有邻居。设置半径需要一些领域知识;如果您的点紧密地聚集在一起,您可能希望使用较小的半径来避免几乎每个点都投票。

KNN 回归量

要将我们的问题从分类转变为回归,我们所要做的就是找到𝑘最*邻的加权*均值。我们使用与上述相同的加权方法,计算这些最接*值的加权*均值,而不是取多数类。

让我们尝试使用 KNN 回归器根据其他特征来预测组织的面积。跟随代码这里

Now you know why nobody uses it for regression tasks

一个应用:异常检测

在𝑘k-nearest 的邻居中,数据自然是聚集的。在这些聚类中,我们可以找到点之间的*均距离(或者穷尽地或者从聚类的质心开始)。如果我们发现几个点比到其他点或质心的*均距离远得多,那么有理由(但不总是正确的)认为它们可能是异常值。我们也可以在新的数据点上使用这个过程。

你知道数据有引力吗?

原文:https://towardsdatascience.com/do-you-know-that-data-has-gravity-6ca55e192372?source=collection_archive---------22-----------------------

1.数据有引力

看到这个标题就忍不住要提问。两个物体之间产生引力,数据怎么会有引力?吸引了谁?数据引力是多了好还是少了好?

宇宙复杂多变,但仍有一个相对稳定的系统。比如我们所处的银河系和太阳系,这个系统的构建就是牛顿提出的万有引力。

同样,我们也可以认为数据本身也是复杂的,比如企业内部的各种业务系统,外部的政府,个人等等。在如此复杂的环境下,它是否也能产生一些稳定的系统?

这里不得不提出牛顿万有引力公式,也是数据引力定律

2.如何用数据证明 IT 部门的业绩或价值?

首先是数据的质量,数据的粒度粗,造假的问题,脏数据的问题会严重影响数据的质量。

价值不会无缘无故的存在,它取决于我们的 决策 部门,业务部门和 it 部门。如果这三个部门分开,数据和价值之间的距离变长,数据引力就会降低,那么价值就会降低。

关于数据和价值之间的距离,在企业中通常没有这个环节的保障。

3.如何打造重质量的数据?

一、可靠性,数据需要高度可信,不可证伪;

第二,深度,数据需要契合业务需求并易于分析;

三、速度,数据是有时效性的,只有通过高效的分析,才能发挥其最大的价值。

我们来看看企业数据目前存在的问题。

“2018 China Enterprise Data Research Report”, from FanRuan Data Institute

4.为了解决这些问题,我们应该怎么做?

  • 底层数据处理—建立数据可信度

  • 建立中间模型—提高数据深度

模型分为两类,一是数据模型,二是业务模型。数据模型其实是基于数据本身的特性,无论是我们的主要数据,还是我们的国际十大学科领域。第二是为我们的业务需求而开发。

  • 前端快速渲染—提高数据速度

数据是有场景的,所以不同的图表,不同的表格,其在实际过程中的应用是不同的。在每种情况下,对于不同的领导汇报,针对业务的不同应用选择不同的处理方式,这样的数据分析就是快速分析。

5.如何为质量创造价值?

重质量的价值需要场景连接。

从这张图中我们可以看出,连接的价值需要由决策层、IT 层和服务层来决定。那么决策层一般面对的数据场景有哪些呢?

6.如何减少资料准备的时间?

解决的办法就是把数据自动化,把需要的数据固定下来,根据每月的变化自动更改,然后就不需要那么多人力每月重复工作了。

7.如何减少理解数据的时间?

我们可以根据决策层的个人习惯自动推送异常数据或关键数据,比如通过数据仪表盘的移动端提示。

From FineReport

8.如何科学地衡量各部门创造的价值?

对于决策者来说,阿米巴经营可以用来节省人力。

对于业务层来说,重点是人和事。

关于员工的成长,我们采取主动和被动的方法来授权我们的业务和促进个人发展。

对于事物,我们希望数据满足更多的业务场景,如下图所示。

我们来看看 IT 层面临的数据场景。

“2018 China Enterprise Data Research Report”, from FanRuan Data Institute

很多时候,决策层认为 IT 部门人员只需要不断优化升级现有业务,但实际上,更重要的是 IT 层能够解决业务层的燃眉之急。

总结一下,最终的目的是我们的决策者不是单纯的听报告或者看 PPT,而是用数据来支持他的决策,让他的决策能够提升他的管理。对于业务层,我们不仅要回应领导的诉求,还需要思考如何利用数据推动业务转型。对于 IT 层来说,他们需要与业务融合,从沟通到指导,而不是对抗,通过这种方式来提高数据质量。

而下一次我会和你谈谈如何缩短数据和价值之间的距离。有什么问题,可以放在这里。欢迎交流。

您可能也会对… 感兴趣

2019 年你不能错过的 9 款数据可视化工具

初学者财务报表分析指南

业务分析师需要学习的 3 种报表

你的人工智能项目需要合成数据吗?

原文:https://towardsdatascience.com/do-you-need-synthetic-data-for-your-ai-project-e7ecc2072d6b?source=collection_archive---------12-----------------------

在大多数人工智能项目中,数据是一个问题。由于缺乏好的数据,我已经失败了几个项目…从那以后,我更多地依赖于一种相对较新的叫做合成数据的方法。我希望这篇文章能帮助你更好地理解合成数据如何帮助你的人工智能项目。

对于像谷歌、苹果和亚马逊这样的大型科技公司来说,与其他公司相比,收集数据不是一个问题。事实上,通过他们的产品/服务,他们拥有几乎无限的各种数据流,为数据科学家训练他们的算法创造了完美的生态系统。对于较小的公司,对这些数据集的访问是有限的、昂贵的或不存在的。

除了解决 AI 的数据收集问题,企业还必须应对激烈的竞争。

现实情况是,获取数据的成本很高,这使得许多人甚至无从下手。然而,合成数据可以帮助改变这种情况。合成生成的数据可以帮助公司和研究人员建立训练甚至预训练机器学习模型所需的数据仓库。

新产品、新市场

通过帮助解决人工智能中的数据问题,合成数据技术有可能创造新的产品类别和打开新的市场,而不仅仅是优化现有的业务线。

这对许多行业的数据科学都有影响。除了使工作能够开始,合成数据还将允许数据科学家继续正在进行的工作,而不涉及真实/敏感的数据。

事实上,公司现在可以获得他们的数据仓库或数据库,并创建它们的合成版本,而不会侵犯用户的隐私。

制造假数据

合成数据是以编程方式生成的数据。例如,使用视频游戏引擎渲染的任意场景中的物体的逼真图像,或者由语音合成模型从已知文本生成的音频。很重要的一点是,这与传统的数据扩充不同,传统的数据扩充使用裁剪、翻转、旋转和扭曲来增加模型必须学习的数据种类。

这些渲染引擎不仅可以生成任意数量的图像,还可以生成注释。边界框、分割遮罩、深度图和任何其他元数据都与图片一起输出,这使得构建产生它们自己的数据的管道变得简单。

如今的大部分合成数据都是可视化的。

通过我的项目,我意识到在计算机视觉中,完全基于合成数据来训练模型执行许多常见任务是可能的。对象检测、分割、光流、姿态估计和深度估计都可以用今天的工具实现。

在音频处理和自动语音识别任务中,也可以从生成的数据中受益。最后,强化学习极大地受益于在模拟环境中测试策略的能力,这使得为自动驾驶汽车和机器人训练模型成为可能。

通过实际创建强化学习算法可以在其中运行的模拟环境,合成数据的产生可以更进一步,并因此基于其动作生成数据流。关键问题是训练算法所需的模拟环境的复杂性。

关于合成数据的信息:

何时使用合成数据

合成数据有助于加快您的人工智能计划:

  1. 用合成数据测试算法允许开发人员制作概念证明,以证明人工智能计划的时间和费用是合理的。它们可以表明,一个特定的算法组合在原则上可以被修改以达到预期的结果,保证与整个开发周期相关的成本不会被浪费,并给你前进所需的信心。
  2. 公司可以根据您的测试需求,快速开发大规模完美标记的数据集。此外,可以通过迭代测试来修改和改进这些数据,从而为您后续的数据收集操作提供最大的成功可能性。
  3. 当你的训练数据中有太多某种标签时,一个常见的问题就是过度拟合。当面对真实世界的使用时,它会产生不可靠的结果。偏见是另一个问题,来自收集的数据,这些数据不能充分代表现实中可能发生的所有差异。合成生成的数据集提供了一种可靠且经济高效的方法来纠正这些问题,并保证数据集的良好*衡。
  4. 合成数据可用于可靠地生成具体案例。例如,罕见的天气事件、设备故障、交通事故或罕见的疾病症状。合成数据可以代表唯一的方法来确保你的人工智能系统为每一种可能发生的情况进行训练,并在你最需要的时候准确地表现良好。

合成数据的背景

在确定创建合成数据的最佳方法时,重要的是首先考虑您想要什么类型的合成数据。有两大类可供选择,各有利弊:

构建合成数据的两种一般策略包括:

从分布中抽取数字:通过观察真实的统计分布和复制虚假数据来工作。这也可以包括创成式模型的创建。

基于代理的建模:创建一个模型来解释观察到的行为,然后使用同一个模型再现随机数据。它强调理解代理之间的相互作用对系统整体的影响。

在众多应用中,合成数据使用的潜力是显而易见的,但它不是一个通用的解决方案。

当涉及到合成数据时要小心

合成数据并不总是完美的解决方案。事实上,合成数据通常不适合机器学习用例,因为大多数数据集太复杂,无法正确“伪造”。此外,使用合成数据还可能在开发阶段导致误解,即一旦投入生产,您的机器学习模型将如何处理预期数据。

此外,如果用合成数据训练的模型比用“原始”数据训练的模型表现更差,决策者可能会驳回您的工作,即使该模型可能会满足他们的需求。

如果用合成数据训练的模型比用预期数据训练的模型表现得更好,你创造了不切实际的期望。大多数时候,我们很少知道当我们的模型用不同的数据集训练时,它的性能会如何变化,直到我们用特定的数据集训练它。

根据项目的性质,我相信如果你对预期数据的理解足够好,可以生成一个本质上完美的合成数据集,那么使用机器学习就变得毫无意义,因为你已经可以预测轮廓了。在我看来,你用来训练的数据应该是随机的,用来看看这些数据可能产生什么结果,而不是用来证实你已经知道的东西

合成数据的挑战

尽管在合成数据的帮助下可以获得各种各样的好处,但它也不是没有挑战。这些挑战包括:

合成数据的局限性

尽管我对 ML 项目合成数据的未来持乐观态度,但还是有一些限制。其中一些是技术性的,而另一些则与业务相关:

  1. 像“识别这种特定包装”这样的简单任务很容易,但像“检测数百种稀有动物”这样更复杂的任务仍然很难。
  2. 从商业角度来看,从长远来看,合成数据将许多模型转化为商品。

虽然在这一领域取得了很大进展,但一个持续存在的挑战是保证合成数据的准确性。我们必须确保合成数据的统计特性与原始数据的特性相匹配。

用于生成合成机器学习数据的工具

  • sklearn.datasets.make:这个流行的 scikit-learn Python 包包含生成具有特定属性的数据的方法。生成适用于回归、分类和聚类问题的数据的基本方法是可用的。这些方法在 sklearn.datasets 模块中。
  • pydbgen :一个 Python 包,用于生成合成的结构化数据库表,包括特定的数据字段,如电子邮件、电话号码、姓名或城市。
  • Mockaroo : Mockaroo 是一个网站/API,用于生成具有真实单元格值(例如,姓名、邮政编码、日期)的结构化数据,并且可以选择使用自定义函数来转换生成的值。免费版一次生成 1000 行,并以通用表格格式导出这些行。

您真的需要在您的生态系统中实施大数据技术吗?

原文:https://towardsdatascience.com/do-you-really-need-to-implement-big-data-technologies-in-your-ecosystem-ea840a3cf286?source=collection_archive---------13-----------------------

多年以来,“大数据”已经变得普遍和流行。大数据技术开始填补传统数据技术(RDBMS、文件系统……)与数据和业务需求的高度发展之间的空白。

虽然实施这些技术对于许多大型组织来说是确保业务连续性所必需的,但是许多组织都在致力于采用这些技术,而并不真正知道它们是否能够改善他们的业务。

在做决定之前,有许多事情你应该考虑。

了解什么是大数据

在询问您的企业是否需要大数据技术之前,您必须首先了解什么是大数据。我知道这可能看起来很奇怪,但这是真的。

很多次,我们被要求为许多公司开发大数据生态系统,只是因为他们的数据库在存储数据多年后接* 1 TB,而他们只需要优化数据存储和采用一些最佳实践。

有一次,我被要求构建一个“大数据解决方案”,仅仅是为了让一个公司经理能够搜索数百个包含不同信息的 excel 文件。最后,使用一些 SQL Server 集成服务包、一个小型数据仓库和一个 Power BI 项目实现了目标。

只要谷歌一下“大数据”这个词,你就会看到许多描述它的文章,它会消除任何误解(如果存在的话)。

大数据不仅仅是一个庞大的数据量,它还具有很多其他特征,如速度、准确性和多样性。

你需要什么技术?

如果您确定自己拥有大数据,那么您必须选择您正在寻找的合适技术。

有一些关于大数据技术的神话;很多人认为大数据一直意味着 Hadoop,而另一些人认为 Hadoop 是一个数据库管理系统。

作为一名数据工程师,在选择正确的技术之前,我必须研究我们要处理什么类型的数据;实时或静态、在线或离线、结构化或非结构化。然后,我需要指定生态系统层,并在研究了其他因素(如可用资源、成本和其他因素)后,为每一层选择相关技术。

Big Data Ecosystem example (Project called ORADIEX)

总的来说,有一些共同的生态系统层:

  • 数据摄取层(从数据源读取数据):有很多工具如 Apache Kafka、Sqoop 等。
  • 数据处理层(数据清洗、聚合):Apache Spark、Storm、Hive、Pig、MapReduce……
  • 原始数据存储(数据湖sss存储没有到来的摄取数据):Hadoop
  • 处理过的数据存储(数据库,存储经过处理和清理的数据的数据仓库):Apache Cassandra、InfluxDb、MongoDB、Apache Hive……
  • 数据可视化层(绘制实时图形):Kibana,Grafana …
  • 数据检索层(海量数据搜索):可以使用分布式搜索引擎,如 Solr、Elastic Search、Sphinx、蝎狮……

大数据技术实施成本

第二件重要的事情是了解实现成本(金钱、时间和人员……);

即使大部分大数据技术是开源和免费的,但它们需要昂贵的资源和专业人员,而在线上缺乏这些技术的明确技术文档。

你不应该只考虑技术价格而不考虑其他因素。

结论

最后,您可能会考虑其他因素,但您必须知道大数据技术不是魔术棒。

有时,您的公司只需要实施一些最佳实践或执行一些优化,在需要采用新技术之前,当前系统将为您服务多年。

另一方面,当您真正需要大数据技术时,您不会花太多时间来采用。

你看到我看到的了吗?

原文:https://towardsdatascience.com/do-you-see-what-i-see-391151db87eb?source=collection_archive---------29-----------------------

“你不应该在你的仪表板上使用这些颜色,因为它们是自然的,”我一直对我的员工说,直到有一天我意识到仪表板的颜色类似于我在非洲看到的一种常见的服装图案,于是我想起了我的欧洲朋友在坦桑尼亚市场上为她的服装购买面料的故事。她的颜色选择被一位店主描述为“mzungu”色,一切都变得有意义了。一个“啊哈”的瞬间,接着意识到“我以为我知道的一切都是错的”。我不确定仪表板构建的最佳实践实际上是“最好的”还是“西方国家仪表板构建的常见实践”。

有没有知觉经验的一致性?如果不是,是否一个人说的语言和一个人属于一种特定的文化,等等。把他的注意力引向某些颜色,让他忽略其他颜色?如果是,不同文化中存在的基本颜色是什么?

在研究色彩理论时,我问自己。大多数研究论文都是关于一个人说的语言如何影响他的现实,而不是关于跨文化的颜色-情感关联的研究——事实上,跨文化研究的研究机构有限,以前的颜色-情感关联研究都是在一个国家进行的,或者专注于特定的情感或特定的颜色——我想知道 Hofstede 在这个问题上有什么看法。由于数据的可用性,我把重点放在了语言的相对性和语言的一致性上,这是一个想法,即那些使用相同基本颜色术语的语言的人对颜色变化的感知和记忆是相似的。这篇文章的目的是分享我的分析结果,并潜在地提高对这个主题的兴趣,因为该领域的语言学理论的潜在含义是,如果你使用的颜色在你的仪表板最终用户的语言中没有相应的名称,你就不会实现你的仪表板的预期效果。

Munsell chips

背景:对基本术语的研究始于柏林和凯(1978)的工作。“基本颜色词意义的语言学意义”]他发现 11 种颜色——白色、黑色、红色、绿色、黄色、蓝色、棕色、紫色、粉色、橙色和灰色——在世界上所有语言中充当所有基本颜色词的焦点,并被认为是一种语义共性。他们还提出了一种颜色的层次结构,见下文,其中如果颜色 a 出现在该层次结构中颜色 b 的左侧,那么每种有 b 的单词的语言也将有 a 的单词。例如,有四个颜色术语的语言总是有黑色、白色和红色的单词,而第四个单词可能表示黄色或绿色。

Hierarchy of colors according to Berlin and Kay (1969)

另一项成果是将所研究的语言分为进化序列的七个阶段,从只有白色和黑色词汇的原始语言到拥有所有颜色词汇的更高级语言。

Classification of languages according to Berlin and Kay

但当时这项工作因其研究方法而受到批评,因此,在 1970 年底,进行了一项额外的研究‘世界颜色研究’(WCS),以获得每种语言中基本颜色术语的名称、类别范围和最佳示例——基本颜色术语在说明中被描述为“说话者可以用来命名任何颜色的最小简单单词集”。这是通过国际语言夏季研究所的合作实现的,该研究所在世界各地维护着一个语言学家-传教士网络,在那里收集了代表 45 个不同语系和几个主要语言种群的 110 种非文字语言使用者的基本颜色术语系统的数据,迄今为止,它被认为是最大的语言学研究之一。现场工作人员得到了 Munshel 色卡——一种通过三个维度定义颜色的颜色空间:色调、亮度和色度。研究参与者“被要求(1)说出 330 个蒙塞尔芯片中的每一个,以恒定的随机顺序显示,以及(2)接触这些芯片的调色板,并被要求挑出在命名任务中引出的主要术语的最佳例子(“焦点”)。

使用的方法:采用标准的迭代数据分析生命周期,包括:制定研究问题>收集数据>组织数据>分析数据>交流结果。基于基本颜色比非基本颜色在所有受访者中出现频率更高的假设,基于使用频率和出现顺序对调查响应进行了分析。结果被可视化为单词云。包含代码的 Git 库在这里是。

收集数据:整个数据集可在 WCS 的网站上获得。为了进行分析,我使用了数据集“focus-exp . txt ”,它包含 WCS 焦点任务响应(大小= 110,784);“lang.txt ”,其中包含调查中每种语言的顾问所在国家和实地调查人员的姓名,以及 WCS 员工内部使用的某些其他信息(大小= 110);“WCS _ SIL _ 代码”将国家映射到语言;以及“dict.txt ”,它给出了在其他文件中出现的每个术语(大小= 2,363)。

组织数据:所有文件的格式都是空格分隔的,这使得当一列中的文本由一个空格分隔时,例如由空格分隔的国家名称,很难解析。

然后,由于字符编码格式或潜在的数据收集错误,我无法将一些语言映射到一个国家,真的吗?这次谷歌不知道这些语言来自哪个国家。

array(['Abidji', 'Cavine{\\x96}a', 'Ch{\\x87}cobo', 'Cof{\\x87}n',
       'Eastern', 'Ng{\\x8A}bere', 'Sepik', 'Kokoni', 'Long-haired',
       'M{\\x9C}ra', 'N{\\x87}huatl', 'Sirion{\\x97}', 'Central', 'W.'],
      dtype=object)

最后,词典文件的自述文件中提到,“由于字体限制和其他原因,该文件中实际术语的印刷翻译在许多情况下并不完全符合现场工作人员的记录”。

分析数据&交流结果:结果,2619 名受访者中有 2277 人根据他们的语言被映射到一个特定的国家——是的,我同意这是非常简单的,因为几个国家可能说同一种语言。我发现这个图表相当有趣,即大多数受访者位于巴布亚新几内亚——我想知道这个图表是否是 70-80 年代基督教传教探险的例证。

*均而言,每个语言组有 25 名参与者。

沟通结果:

为了提醒 WCS 的方法论,在命名任务中,刺激调色板放在说话者的前面,对于每个颜色词 t,回答者被要求指出他或她能调用的所有芯片。然后,像以前一样展示芒塞尔芯片,并要求合作者为每个基本颜色项 t 指出 t 的最佳示例。为了可视化组合的数据集,我以单词标签的形式放置命名响应,并根据命名响应进行着色。编写了几个函数来将 RGB 转换为 HEX,并将文本绘制为单词云;Holoviews 是一个 Python 库,用于增加 viz 的交互性;Binder 习惯于共享 Jupyter 笔记本进行协作。你可以在 https://mybinder.org/v2/gh/eponkratova/articles/master?找到它 file path = language _ colors % 2f code _ 2 . ipynb。在它的上面,写了一个小的 VBA 来可视化 xls 中的结果。可以在https://github . com/eponkratova/articles/blob/master/language _ colors/analysis . xlsm访问。

Access the tool at https://mybinder.org/v2/gh/eponkratova/articles/master?filepath=language_colors%2Fcode_2.ipynb

Access the file at https://github.com/eponkratova/articles/blob/master/language_colors/analysis.xlsm

例如,“lebe”在 Abidji 中是“红色”的意思——谢谢@Ange 的真知灼见。当指出与术语“lebe”相关的颜色时,受访者指的是略有不同的薯片。

你可能会问,那又怎样?当我意识到作为肤色调查一部分的语言群体的使用者是少数群体时,我有点失望。所以这个分析很可能对你没有任何帮助,但是希望它能让你思考一下你在仪表盘上使用的颜色。“不要使用太暗或太激进的颜色——只有在你需要制造一种警示的情况下才使用激进的颜色”,我过去常常这么说。如果对于我们的非洲顾客来说,中性色可以突出物体并起到警示作用,那会怎么样?如果我使用的绿色阴影在仪表板查看器的母语中没有单词,会被忽略吗?会逃吗?截至目前,我还没有一个确定的答案。

你明白了吗?

原文:https://towardsdatascience.com/do-you-understand-it-b0b62657e836?source=collection_archive---------26-----------------------

自然语言处理导论

理解一门语言始于查字典

今天,我随意浏览了《牛津英语词典》,试图将语言归结为“第一原则”。

我首先检查了一个孩子在 3 岁时可能会学到的东西——“好”的含义——“被期望或认可”。

Screenshot from https://en.oxforddictionaries.com

假装不知道“欲望”是什么意思,我又检查了一遍——“强烈希望或想要某样东西”。

Screenshot from https://en.oxforddictionaries.com

还是那句话,什么是“愿”?“感觉或表达强烈的愿望”。

Screenshot from https://en.oxforddictionaries.com

哦,天哪,这是一个神奇的循环引用。我被卡住了,永远只能在“欲望”和“愿望”之间翻转。从字典上看,没有办法真正理解“欲”和“愿”的含义。

如果你检查较难的单词,你可能不会马上看到,因为它可以用较简单的单词来解释。学习外语也是如此。但如果你检查最简单的词,这个循环甚至自我引用出现了。再举一个例子,“意义”的含义读作“一个词、文本、概念或行为的含义是什么。”

Screenshot from https://en.oxforddictionaries.com

意义是我们赋予的

唯一的解释是,意义是我们赋予词语的。我们认为我们理解它们是因为每个人都知道它们,但实际上我们只是记住了它们的意思,而不是因为它是如何拼写的(嗯,偶尔这是真的,因为有一些你知道的单词成分)。拼写本身在大多数情况下没有意义。

一旦我们赋予一个词一个意思,我们就知道其他词的意思。这就像一个文字网络。比如我们理解了“欲”,就知道了“愿”和“善”。即使我们不知道“欲”的含义,我们仍然知道“愿”和“善”如果出现在同一个语境中,它们与“欲”有着相似的语境。

当一个词的意思被赋予时,我们可以通过观察上下文来猜测。这是人类理解语言的自然现象。这就联系到了一个重要的概念——(出现在同一个语境中的词更有可能有相似的意思),这个概念奠定了自然语言处理(NLP)的基础。

这是 NLP 中单词嵌入的大致思路。“单词嵌入”这个花哨的术语只是我们将意义烘焙到一系列计算机可以理解的数字(向量)中,并可用于下游任务,如情感分析。

机器可以学习我们如何分配意义

回到主题——我们理解了吗?我们都没有,电脑也没有。我们不理解它,我们赋予它意义,我们知道“好”与“欲望”和“希望”有联系。计算机也看不懂拼写“good”,但它可以学习我们的赋值分布——“good”类似于“desire”和“wish”。毕竟,意义分配仍然是人类的财产。

另外,中文可能有一点不同的故事,因为有些是从象形文字演变而来的。

你想去米兰吗?使用 Airbnb 数据的邻里情感分析

原文:https://towardsdatascience.com/do-you-want-to-move-to-milan-neighborhoods-sentiment-analysis-using-airbnb-data-72db72ebc070?source=collection_archive---------21-----------------------

Udacity 数据科学家纳米学位计划项目

Photo by Andrea Ferrario on Unsplash

这个项目是数据科学家纳米学位项目 Udacity 的一部分:写一篇数据科学博文,目标是选择一个数据集,应用 CRISP-DM 流程(数据挖掘的跨行业流程)并有效地交流分析结果。

CRISP-DM 流程:

  1. 业务理解
  2. 数据理解
  3. 准备数据
  4. 数据建模
  5. 评估结果
  6. 展开

看着推荐的数据集,我被太多的选项卡住了。然后,由于我和一些朋友正在考虑搬到米兰,以便离我们的工作场所更*,我决定使用 Airbnb 的数据对其街区进行情感分析。

业务理解

该项目的目标是回答至少三个与如何使用数据的商业或现实应用相关的问题,所以我选择了:
1 得分最高的 5 个邻域是哪 5 个?
2 得分最低的 5 个小区是哪几个?
3 主人给出的邻里概况与客人给出的有多大不同?

数据理解、准备数据和数据建模

该数据集由 20626 个主机列表和 469653 个客户评论组成。列表和评论都是用不同的语言写的:意大利语,英语,法语,俄语。

在了解了哪些数据可能对我的目标有用之后,我必须将列表中的社区与真实的社区进行映射:米兰由 130 个社区组成,但在映射之后,只有 74 个被至少一个列表覆盖。

http://www.museomilano.it/mediateca/media-pg-5/

在无法自动绘制地图的情况下,也可以使用谷歌地图手动绘制地图。

First 20 listing marked with real_neighbourhood

Number of listing related to a neighborhood

使用 listing_id 可以将每个评论连接到real _ neighborhood

First 20 review marked with real_neighbourhood

Number of review related to a neighborhood

对于列表和评论,我已经检测了使用的语言并标记了每条记录。

First 20 listing marked with detected_language

大约 34%的列表有一个无法检测语言的社区概览,37%是英语,26%是意大利语。

Listing neighborhood_overview detected languages

First 20 review marked with detected_language

大约 58%的评论是英文的,20 %是意大利文的。

Review comments detected languages

然后我决定把重点放在英文列表和评论上,只使用这样标记的记录。在使用 neighborhood_overview 的列表中,我们可以直接获得邻居的情感,但是对于评论的评论,我们必须只提取与邻居相关的句子。

对于每个列表,我们现在都有一个邻居情绪

First 20 listing marked with neighborhood_sentiment

同样的做法也适用于评论,使用同义词列表提取与街区相关的句子:街区区域街区贫民区教区管区区域贫民窟

例如,让我们考虑第一个评论:

**住在弗朗西丝卡和阿尔贝托家是一件乐事。正如所描述的那样,对于我的目的来说,这是一次去托托纳地区的愉快的步行。房间很好,每天打扫,有私人浴室。

弗朗西丝卡超级友好,非常乐于助人;同时尊重隐私。

总体来说很棒的体验!**

出于我们的目的,我们只需考虑:

正如所描述的那样,对于我的目的来说,这是一次去托托纳地区的愉快的步行

First 20 review marked with neighborhood_sentiment

现在,通过按邻域分组,我们获得了我们正在寻找的情感:

First 20 neighborhood sentiment comparison sort by neighborhood_sentiment_review

评估结果

我们问题的答案是:

First 5 neighborhood by score

Last 5 neighborhood by score

*均而言,与主持人给出的邻居 _ 概述相比,由客人评论的上下文句子给出的邻居的情感要高得多。一个可能的解释是 neighborhood_overview 文本的过长会对情感分析分数产生负面影响。而只提取有用的句子允许清理用于分析的字符串,从而给出总体较高的分数。

Reporting aggregated value

结论

总结步骤:
1 将数据集邻域映射到真实邻域
2 检测 neighborhood_overview 中用于列表和评论的语言
3 用于列表:计算
neighborhood _ overview**
4用于评论的情感分析:隔离与邻域相关的句子并计算情感分析
5**

这个项目的代码可以在这个 github 资源库中找到,并且在我的博客上有一个意大利语的帖子。

Python 开发的 Docker?

原文:https://towardsdatascience.com/docker-for-python-development-83ae714468ac?source=collection_archive---------5-----------------------

第 1 部分 涵盖了什么是 docker。

在本文中,我们将讨论如何开始使用 Docker 进行 python 开发。

一个标准的 python 安装包括设置环境变量,如果你在处理不同版本的 python,无论是 Windows 还是 Linux,都有大量的环境变量需要处理。

如果您正在处理对 python 版本非常挑剔的产品,您需要确保您的程序在该版本上经过测试,并且没有您可能在本地系统上认为理所当然的额外和缺失的依赖项。

同时处理 Python 2 和 3 仍然是可管理的,但是想想如果你必须处理已经安装的 python 3.6 并且需要试用 python 3.7。

码头工人来救援了!

改变 python 版本就像FROM python:3.6.7FROM python:3.7一样简单。

Docker 不仅允许进行快速实验,而且有助于限制保持稳定性所需的特定包版本。

可以把它想象成 Anaconda 中的一个虚拟环境。

但是,当您配置了 Anaconda 之后,大多数包已经预安装在系统上,当您尝试部署它时,您可能会认为它们是理所当然的。

此外,python 3.7 版的 Anaconda 占用了超过 3GB 的磁盘空间。

另一方面,docker 图像几乎不占用千兆字节。

Sizes of Python Full and Alpine Images

准备文档

决定你需要的 python 版本,如果你只是在寻找最新版本,就写python:latest

图像的方式通常被命名为image_name:tag,当您使用docker build -t image_name:tag .构建图像时需要提供这个名称。如果您在构建过程中没有提供任何标签,docker 会自动分配给它latest

在 docker hub 上, Python 提供了不同的图片供选择,从 Alpine 版本(这是一个非常小的图片)到完整版本。

# Python 3.6.7FROM python:3.6.7-alpine3.6# author of file
LABEL maintainer=”Chinmay Shah <[chinmayshah3899@gmail.com](mailto:chinmayshah3899@gmail.com)>”

RUN —该指令将在当前图像之上的新层中执行任何命令,并提交结果。生成的提交图像将用于Dockerfile中的下一步,通常以外壳形式,除非指定或。

# Packages that we need 
COPY requirement.txt /app/
WORKDIR /app# instruction to be run during image build
RUN pip install -r requirement.txt# Copy all the files from current source duirectory(from your system) to# Docker container in /app directory 
COPY . /app

你可能会注意到,在中我们复制了requirement.txt两次。这是为了构建优化。

Dockerfile 中的每一行都作为一个单独的步骤执行,并创建一个新的容器。

这是非常低效的,因为您并不总是希望在每个构建命令期间从头开始重新构建一切。

为了解决这个问题,Docker 使用了一种被称为层缓存的东西,这是一种奇特的说法,它不是每次都重新创建一个容器,而是重用在以前的构建中创建的容器并存储它。因此,除非您在前面的步骤中进行了更改,否则构建过程可以重用旧的容器。

这个想法是,需求几乎不会改变,但是代码经常会改变,因此使用缓存是一个更好的方法,而不是每次构建映像时都下载需求包。

The build process

请注意,dockerfile 中的每一行都是一个单独的步骤,而且每个步骤都有一个唯一的字母数字名称。

ENTRYPOINT —指定容器启动时将始终执行的命令。

CMD —指定将提供给ENTRYPOINT的参数。当您想将容器作为可执行文件运行时,可以使用它。

如果没有 entrypoint,默认参数是执行的命令。

对于 entrypoint,CMD作为参数传递给 entrypoint。

更多关于它的这里。

# Specifies a command that will always be executed when the  
# container starts.
# In this case we want to start the python interpreterENTRYPOINT [“python”]# We want to start app.py file. (change it with your file name) # Argument to python command
CMD [“app.py”]

运行 python 文件

构建文件:

docker build -t python:test .

使用 cmd 或 bash 启动容器:

docker run — rm -it -v /c/Users/chinm/Desktop/python_run:/teste pythontest:alpine

-v--volume用于附加一个卷。

什么是体积?

卷是保存 Docker 容器生成和使用的数据的首选机制。它们完全由 Docker 管理。

要将目录连接到 Docker 容器:

-v source_on_local_machine:destination_on_docker_container

如果您想要创建一个卷,以便可以跨不同的 docker 容器访问它,那么创建一个 docker 卷将是一个不错的选择。更多关于它的在这里。

如果您试图将 Python 用于数据科学,您可能会使用 volume,这样您就可以与容器共享原始数据,对其进行一些操作,并将清理后的数据写回主机。

注意:如果你使用 docker Toolbox 来使用 Docker,那么-v会将你的容器映射到 VM,VM 映射了你本地机器的 C 目录,因此很难将你的其他逻辑驱动器作为 Docker 上的卷来使用。

结论

我希望您已经具备了在 docker 上开始使用 Python 的基础知识。黑客快乐!

你可以随时联系 Twitter、T2、Linkedin 或 T4 的电子邮件。

NLP 的 Docker 图像

原文:https://towardsdatascience.com/docker-image-for-nlp-5402c9a9069e?source=collection_archive---------18-----------------------

现成的解决方案

自然语言处理是我们在波特哈实验室工作的主要方向之一。我们做文本分析,聊天机器人开发和信息检索。所以我们定期使用 Flair,Natasha,TensorFlow 和 Pytorch,NLTK,有时候会遇到英语以外的语言。现有的解决方案并不总是适合我们面临的每一个问题:有些很难启动,有些太复杂和沉重。

因此,我们已经用所有方便的 NLP 框架编译了我们自己的 Docker 映像,包括深度学习。它适合我们几乎 80%的任务,并且节省了安装框架的时间。

当前方法

一般来说,现在大多数数据科学解决方案都是通过以下方式部署的:

One doesn’t simply deploy on bare metal

  1. 在裸机上。一个人必须花大量的时间用 cudNN 设置 CUDA,为 Ubuntu 安装驱动程序,并且在成功之后,还要做大量的尝试来一起运行。肯定会出问题。
  2. 或者使用 Docker(一种更简单的方法)。然而,常规 Docker 不会工作得很好。需要一个特定的:与 GPU 相关的一切都是预先配置好的。在 Docker Hub 已经有几个现成的镜像可用,它们是用不同的 CUDA、cuDNN 和其他模块的版本准备的。

如何在 Docker 中部署 GPU?首先,一个人必须选择一个特别适合他的显卡的基本图像(为此,在hub.docker.com/nvidia通过标签搜索)。当使用 GPU 时,无论如何一切都是从所需版本的 Nvidia 映像继承的(对于 CPU,相反,可以使用任何方便的映像)。然后,在继承了基本映像之后,一个人创建他自己的基本映像并运行它。整个图像将重约 3Gb,但是,一切都将正常工作。

解决方案

经历了所有这些困难之后,我们又为 NLP ( 源代码)创建了一个产品 Docker 映像,它是免费的。我们的码头中心有现成的图像。它包含了一些现代的 NLP 框架,包括用于深度学习的框架。盒子里面是什么: torch,flair,spacy,dateparser,pymorphy2,yargy,natasha,nltk,yake ( 版本)。更详细:

  • flair 是一个最先进的 nlp 模块,它提供了方便的 NER、词性、词义消歧和分类。
  • natasha 是俄语中 NER 的一个模块。
  • yargy 是一个俄罗斯语言解析器。
  • yake 是一个自动关键词提取器。其主要特征是:无监督方法、语料库、领域和语言独立性。

安装镜像的四个简单步骤:

  1. 克隆回购
  2. 然后是build docker build -t nlp-cpu -f ./Dockerfile.cpu . (或docker build -t nlp-cpu -f ./Dockerfile.gpu .)
  3. 并使用:docker run -it — runtime=nvidia iwitaly/nlp:gpu nvidia-smi
  4. 还可以传递 CUDA_VISIBLE_DEVICES 环境变量。

在这个 Docker 映像的帮助下,您可以通过快速启动它并直接使用 NLP 来节省部署时间。我们希望它至少能简化一点流程。

如果您对安装有任何疑问,请在这里留下您的意见或直接联系我。还有,随意分叉回购,修改原始文件。

链接

  • github:https://github.com/poteha/docker-nlp
  • https://hub.docker.com/r/iwitaly/nlp/

感谢您的阅读!请,提出你的问题,留下评论,敬请期待!

docker+Jupyter 1 分钟机器学习

原文:https://towardsdatascience.com/docker-jupyter-for-machine-learning-in-1-minute-30e1df969d09?source=collection_archive---------10-----------------------

许多数据科学应用程序需要与您的主机环境隔离的模型培训/开发环境。轻量级的解决方案是将 Jupyter 与 Docker 集成在一起。设置这样一个容器的最佳实践是使用 docker 文件,这是我按照最佳实践在不到 1 分钟的时间内编写的。我希望这能帮助任何使用 docker 从事数据科学应用的人。

该项目的结构如下。

├── Prject_folder           
│ ├── Dockerfile           #Primary imga building 
│ ├── docker-compose.yml   #Describing the files to mount etc     
│ ├── requirements.txt     #Required python packages for the image

第一步:

将以下 3 个脚本下载到您计算机上的项目目录中。 GitHub 回购可以在这里找到。

Dockerfile

docker-compose.yml

将其更新为{ absolute path _ to _ yourFile }/{ fileName ame }:/root/data science/{ fileName }以挂载您的首选文件。

requirements.txt

更新它以包含您需要的包,即 matplotlib==1.0.0

第二步:

在你的电脑上安装 Dockerhttps://docs.docker.com/install/,

第三步:

docker build -t datascience .

第四步:

将 docker-compose.yml 文件更新为 mount 文件,按照我已经给出的 test.txt 文件的例子,将您需要的文件从主机装载到容器中。

第五步:

docker-compose up 

搞定现在访问 http://localhost:8888 ,默认密码设置为“root”。随便改吧。

补遗

如果遇到问题,运行以下命令将日志文件下载到当前目录。作为对这篇文章的回应,我会尽快给出解决方案。

docker cp <container-name>:/root/dockerLogs/install-logs.log .

如果您想在容器内部启动交互式会话,请键入以下命令

docker exec -it <container name> /bin/bash

如果您想从计算机中完全删除图像

步骤 1: 停止容器

docker container stop <container-id>

步骤 2 :取下容器

docker container rm <container-id>

第三步:删除图像

docker image rm datascience

如果您对我的代码和实践有任何进一步的问题,请留下您的回复,我会尽快回复您。非常感谢 MLSA 团队一如既往的帮助。

Docker 让数据科学家变得简单

原文:https://towardsdatascience.com/docker-made-easy-for-data-scientists-b32efbc23165?source=collection_archive---------4-----------------------

使用 Docker 的机器学习模型部署中的动手学习,并提供各种示例。

"谷歌在容器中运行所有软件,他们每周运行大约 20 亿个容器."

source

在继续之前,你应该想到的第一个问题是为什么我需要 docker,更重要的是它是什么?

那么,Docker 是什么?Docker 是一组*台服务产品,使用操作系统级虚拟化来交付称为容器的软件包中的软件。Docker 的巨大优势在于它使您的部署变得简单,到时候您甚至可以毫不费力地在多台机器上部署它。

您还可以将 Docker 与 Kubernetes 一起使用,Kubernetes 可以通过在不同的 Docker 容器之间分配工作来自动处理工作负载。除此之外,它还负责处理任何 Docker 容器是否离线,并自动重启它以及其他许多事情。

在这里,我们将使用 Docker 构建各种 flask 应用程序。

  1. 使用 Flask 的简单 Hello World 应用程序
  2. 在 Docker 容器中传递参数
  3. Docker 容器中的简单 ML 应用程序
  4. 在 Docker 容器中将图像作为参数传递

安装

$ sudo apt update
$ sudo apt install docker.io

这将安装 docker。现在,要检查 docker 是否正在运行,请键入

$ sudo service docker status

如果在活动模式下没有看到 docker,请键入

$ sudo service docker start

基本术语

  1. Docker 镜像——简单来说,Docker 镜像就像一个用来安装任何操作系统的 ISO 镜像文件。您可以查看所有 docker 图片(在 DockerHub 上公开)
  2. Docker 容器 —当 Docker 映像运行时,它成为 Docker 容器。您可以再次运行相同的映像,将会创建一个不同的 docker 容器。
  3. docker file—docker file 包含设置 docker 容器的所有代码,从下载 docker 映像到设置环境。

我把 GitHub 的链接放在了底部,那里有所有的代码。Docker 在你理解了它的流程之后,是非常容易学习的。

示例 1:简单的烧瓶应用程序

这是一个非常简单的应用程序,可以在浏览器屏幕上显示“hello world”。

让我们构建 flask 应用程序

此外,通过以下方式创建 requirements.txt 文件

$ pip3 list > requirements.txt

制作 flask 应用程序时需要记住的几件事是,主机应该设置为“0.0.0.0 ”,因为我们是在 Docker 内部运行它。

让我们构建 docker 文件

  1. 用下面的命令,我们正在拉 ubuntu 图像。它还包含一个标签,我们可以用它来指定版本。这里,我们正在拉“最新”的图像。
FROM ubuntu:latest

2.现在,假设您刚刚安装了 Linux 操作系统,您要做的第一件事就是更新包含软件包信息的本地数据库。还添加了一个'-y '标志,以确保它不需要任何用户输入。

RUN sudo apt update -y 

3.下一个任务是安装 python。因为我们只使用一个应用程序,所以不需要设置虚拟环境。

RUN apt install -y python3-pip

4.下一个任务是将目录中的所有文件复制到 docker 映像中。

COPY . /app

在哪里?是当前目录,而'/app '是我们希望复制文件的位置。你可以选择任何你喜欢的文件夹。

5.将工作目录设置为/app。

WORKDIR /app

6.我们已经调出了 ubuntu 映像,安装了 python,复制了所有数据。下一步是通过安装所有必需的包来设置 python 环境。我们已经创建了 requirements.txt 文件。现在,我们只需要安装它。

RUN pip3 install -r requirements.txt

7.现在,将入口点设置为“python3”。

ENTRYPOINT ['python3']

8.最后,运行 app.py 文件

CMD ['app.py']

最终的文件将如下所示。

该文件将被保存为不带扩展名的 Dockerfile。

最终的目录结构将如下所示

最后,通过以下方式构建 docker 文件

$ docker build -t simpleflask .

所有这一切听起来可能令人困惑,请原谅我。我们会看到更多的例子来更好地学习。让我们回顾一下到目前为止我们所学的内容。

  1. 您需要创建一个 Docker 文件,其中包含 Docker 容器将安装的信息。它包括一个图像,python,python 环境,然后运行应用程序本身。
  2. 然后,您需要构建 Dockerfile。

现在,请注意这里

您可以通过以下方式查看所有 docker 容器

$ docker ps -a

您将看不到任何 docker 容器,因为您刚刚构建了它。现在,我们将运行该图像。

类型

$ docker images

您可以使用此命令查看所有 docker 图像。下一个任务将是运行您刚刚构建 docker 映像。

$ docker run -d -p 5000:5000 <docker_image_id>
  • 5000:5000 表示您已经将系统的端口 5000 连接到 docker。后一个端口是烧瓶。默认情况下,flask 在端口 5000 上运行。
  • -d 标志意味着您希望以守护模式(后台)运行它。

成功运行后,您会看到一个输出。检查您的容器是否正在运行。类型

$ docker ps -a

如果运行成功,那么在你的网络浏览器中输入 localhost:5000 。你会看到“你好世界”。

示例 2:传递参数应用程序

这不是一个机器学习预测模型,而是我们要学习如何通过 POST 方法从 flask 获取输入并打印出来。

让我们首先创建 flask 应用程序

  • 我们通过显式声明 POST 方法来使用它。
  • 使用 request.get_json 方法来接收输入。
  • 然后简单地打印该值

让我们创建 requirements.txt 文件

$ pip3 list > requirements.txt

docker 文件将与之前的完全相同

要构建 docker 文件,请使用

$ docker build -t passingarguments .

我们将遵循上面的所有步骤。

$ docker images
$ docker run -d -p 5000:5000 <docker_image_id>

现在,注意这里

有多种方法可以调用我们刚刚创建的 API。

  1. 在 python 中使用请求。

2.使用邮递员

3.使用卷曲

curl -X POST [http://127.0.0.1:5000/predict](http://127.0.0.1:5000/predict) -d 5

结果将是传递的数字的*方。

示例 3:简单的 ML 应用程序

在这个例子中,我们将看到如何同时传递多个例子。我们将以 JSON 的形式传递参数。

现在,你不用担心模特培训。训练模型的代码在 Docker 文件中,该模型将作为 Docker 构建过程的一部分进行训练。

理想情况下,模型应该在本地系统上进行训练,然后复制到 Docker 容器中。

让我们看一下 Flask 应用程序

这一次在 flask 应用程序中,我们从接收到的 JSON 中获取参数。JSON 的数据格式类似于 python 字典。

实际上,我们还应该在这里包含错误处理。如果参数不是数字或参数为空,则可能会出现错误。

另外,创建一个 requirements.txt 文件

$ pip3 list > requirements.txt

现在,让我们看看 Docker 文件

请注意,我们正在 Docker 容器中训练模型。您还可以在本地系统上训练模型,并将其复制到容器中。在这种情况下,您只需删除训练模型的行。

现在,有多种方法可以得到预测。

  1. 在 python 中使用请求

2.使用卷曲

curl -X POST [http://127.0.0.1:5000/predict](http://127.0.0.1:5000/predict) -d '{"f1":4, "f2":5, "f3":10}'

注意我们是如何以 JSON 格式传递数据的。在 python 中使用请求时,您必须使用 json.dumps 来将数据转换成 json 格式。

4.图像分类应用

为简单起见,我使用 MNIST 数据集进行分类。

让我们看看 Flask 应用程序

  • 我们正在进口所有必要的包装
  • 我们在运行时加载模型,以加快推理速度
  • 我们使用 convert('L ')将图像转换为灰度。
  • 图像大小调整为 28x28 像素。
  • 对于预测,Keras 需要图像的格式(批量大小、宽度、高度、颜色通道)。所以,我们把它转换成(1,28,28,1)。
  • 接下来,我们将使用它的预测方法和 no.argmax 来查找概率最高的类。

让我们创建 requirements.txt 文件

$ pip3 list > requirements.txt

让我们看看它的 docker 文件

注意——这里我已经训练好了模型。您还可以在构建 docker 文件时添加培训功能。

我们将遵循上面的步骤

$ docker build -t imageclassification .
$ docker run -d -p 5000:5000 <docker_image_id>

在构建 Docker 映像之前,确保使用文件夹中包含的 train.py 文件训练模型

现在,有多种方法可以得到预测。

  1. 使用卷曲
curl -F "file=[@](http://twitter.com/exp)pic_name.extension" [http://localhost:5000/predict](http://localhost:5000/predict)

2.使用请求

现在够了。

如果你已经理解了一些基本的程度,那么祝贺你到此为止。当你尝试新事物并毫不犹豫地去尝试时,你会学到更多。一个大师曾经是一个初学者。

所有代码都在这里。

快乐学习!

Dockerizing Python Flask 应用程序和 Conda 环境

原文:https://towardsdatascience.com/dockerizing-python-flask-app-and-conda-environment-154ab88b599?source=collection_archive---------14-----------------------

使用 Docker 打包您的 Python Flask 应用程序和 Conda 环境

最初发表于【www.easy-analysis.com】

这篇文章将描述如何对接你的 Python Flask 应用程序并重新创建你的 Conda Python 环境。

因此,您正在开发一个 Python Flask 应用程序,并且您已经在本地机器上设置了一个 Conda 虚拟环境来运行您的应用程序。现在,您希望将 Python Flask 应用程序放在 Docker 映像中。

如果可以将当前的 Conda 环境导出为. yml 文件,描述应用程序使用的 Python 版本以及运行应用程序需要哪些 Python 库,这不是很好吗?此外,使用导出的。yml 文件在 Docker 映像中构建一个类似的环境,并在该环境中运行 Flask 应用程序。

下面将准确描述你如何能完成上述所有。

要求

  • 您已经安装并运行了 Docker
  • 熟悉 Docker 命令。你可以在这里阅读更多关于 Docker 的内容。
  • 熟悉 Conda 命令。你可以在这里阅读更多关于康达的内容。

烧瓶应用示例

在这篇文章中,我将使用下面的迷你烧瓶应用程序。

*# -*- coding: utf-8 -*-# 
# Imports 
# 
from flask import Flask, jsonify app = Flask(__name__)# 
# Routes 
# 
@app.route('/', methods=['GET']) 
def hello_world():
    return jsonify({'message': 'Hello World'}) @app.route('/test', methods=['GET']) 
def test():
    return jsonify({'test': 'test'}) if __name__ == "__main__":
    app.run(debug=True) # remember to set debug to False* 

创建一个文件夹,用于存放项目文件。我在本地机器上创建了一个名为“docker_conda_template”的文件夹。在该文件夹中,我创建了一个名为“api.py”的文件,其中包含上述 Python 代码。

导出 Conda Python 环境

为了在 docker 映像中重新创建一个 Conda python 环境,它对应于我们在本地机器上创建的 Conda python 环境,我们首先需要从本地 Conda Python 环境中导出一个 environment.yml 文件。

为此,您首先需要将 cd 放入要创建 environment.yml 文件的文件夹。

*cd home/docker_conda_template*

现在我们想激活一个 Conda 环境,它安装了必要的 Python 版本,并且安装了运行我们的应用程序所需的所有库。我假设你熟悉 Conda CLI,因此这篇文章不会解释如何使用 Conda。

*conda source activate your-environment-name*

为了将您的环境导出为. yml 文件,请运行以下命令。

*conda env export > environment.yml*

这将在您的当前文件夹中创建文件“environment.yml”。
文件看起来会像这样。

*name: your-environment-name 
channels: 
- defaults dependencies: 
- python=3.6 
- flask 
- gunicorn*

该文件包含三条信息。环境创建时的名称、库将从什么渠道下载以及最后要安装什么 Python 版本和库。

用于建立您的 Docker 形象的 Docker 文件

Docker 文件是我们将它们放在一起的地方,这也是 Docker 将使用您的 Python 应用程序及其运行所需的所有要求来创建映像的文件,例如在我们的 environment.yml 文件中定义的 Conda 环境。

以下是最终的 Dockerfile 文件:

*FROM continuumio/miniconda:latest WORKDIR /home/docker_conda_template COPY environment.yml ./ 
COPY api.py ./ 
COPY boot.sh ./ RUN chmod +x boot.sh RUN Conda env create -f environment.yml 
RUN echo "source activate your-environment-name" > ~/.bashrc ENV PATH /opt/conda/envs/your-environment-name/bin:$PATH EXPOSE 5000 ENTRYPOINT ["./boot.sh"]*

我们不打算定义如何在映像上安装 Conda,为此,我们将下载并使用一个已经安装并设置了 Conda 的现有映像。此图片由 continuum 提供,它安装并设置了 Miniconda。我们将用他们的形象作为建立我们形象的基础。为了使用他们的图像作为基础图像,我们必须在 order 文件中声明。这是在第一行“来自 continuumio/miniconda:latest”中完成的。

为了在您的映像中定义一个工作目录,我们声明“WORKDIR/home/docker _ conda _ template”。

我们还想将代码和 environment.yml 文件复制到映像中。下面几行将文件复制到 Docker 映像中。

*COPY environment.yml environment.yml 
COPY api.py ./ 
COPY boot.sh ./*

我们还没有创建和讨论文件“boot.sh”。我们稍后将创建并讨论这个问题。

docker 文件中的以下行运行两个命令,然后设置 Conda 环境的环境路径,该环境将基于我们的 environment.yml 文件进行设置,最后公开端口 5000,这意味着我们将能够通过该端口与我们的 Flask 路由进行交互。

*RUN conda env create -f environment.yml 
RUN echo "source activate your-environment-name" > ~/.bashrc 
ENV PATH /opt/conda/envs/your-environment-name/bin:$PATH EXPOSE 5000*

第一个 run 命令创建一个在 environment.yml 文件中指定的 Conda 环境。第二个运行命令激活创建的 Conda 环境。

然而,有几行我们到目前为止忽略了。Dockerfile 中的最后一行是入口点。这意味着这将在创建映像后运行,而且,这将由非特权用户执行。

boot.sh 文件

在入口点语句中,我们引用了一个名为 booth.sh 的文件。

*#!/bin/sh 
exec gunicorn -b :5000 --access-logfile - --error-logfile - api:app*

这个文件是一个执行一个命令的脚本。该命令启动 Gunicorn 服务器,将端口 5000 绑定到 80,并指定要运行的 Flask 应用程序位于文件 api 中。

或者,我们可以完全删除这一部分,只通过执行 api.py 文件来运行 Flask web 服务器。然而,正如 Flask 文档所述,他们不建议在生产中使用 Flask 内置的 web 服务器。因此,我们希望运行一个生产就绪的 web 服务器,Gunicorn 就是这样的服务器。

为了使这个工作,您需要创建一个名为 boot.sh 的文件,复制上面的代码行,并将文件保存在根文件夹中,在我的例子中,这将是在文件夹“docker_conda_template”中。

最后,Dockerfile 文件中还有两行需要解释:

*COPY boot.sh ./ RUN chmod +x boot.sh*

第一行只是将 boot.sh 文件复制到根文件夹中的 docker 映像中,根文件夹是 docker 文件中指定的工作目录。第二行运行一个命令,该命令修改 boot.sh 文件,以便它可以被识别为可执行文件。

建立并运行您的 Docker 映像

总而言之,现在你应该有下面的文件夹/文件结构。

*docker_conda_template 
--api.py 
--boot.sh 
--environment.yml 
--Dockerfile*

为了构建 docker 映像,您需要执行以下命令。

*docker build -t your-image-name:latest .*

通过运行以下命令启动 Docker 映像。

*docker run –name your-image-name -p 80:5000 –rm your-container-name:latest*

打开浏览器并访问 localhost 或 localhost/test,您应该会得到 api.py 文件中定义的响应。

如果你有兴趣了解我更多。请访问我在 LinkedIn 上的个人简介https://www.linkedin.com/in/vedranmarkulj/

感谢阅读。如果你对我将来写的关于机器学习和类似主题的帖子感兴趣,请在媒体和 LinkedIn 上关注我。更多文章即将发表。

爱丽丝医生和云原生鲍勃,我最喜欢的机器学习用户

原文:https://towardsdatascience.com/doctor-alice-and-cloud-native-bob-my-favorite-machine-learning-users-5c2b36998e0d?source=collection_archive---------17-----------------------

爱丽丝和鲍勃都很棒,这也很好,因为我无论走到哪里都会遇到他们!他们热情、勤奋,尽最大努力构建伟大的机器学习解决方案。不幸的是,很多事情阻碍了他们,让他们慢了下来。

我的工作是倾听并帮助所有的 Alices 和 bob:)在这篇文章中,我将尝试总结他们面临的挑战,他们如何开始用 AWS 服务解决这些问题,特别是 Amazon SageMaker。

Tell me about your first GPU cluster.

信不信由你,我保证你在下面读到的一切都是 100%基于无数的客户互动。

爱丽丝医生

爱丽丝拥有博士学位,在一家大型公共研究实验室工作。她是一名训练有素的数据科学家,在数学和统计学方面有很强的背景。

她把时间花在大型科学项目上(生命科学、物理学等)。),涉及庞大的数据集(几 TB,往往更多)。她可以用像 Matlab、R 和 Python 这样的高级语言编写数据分析代码:也许它看起来不怎么样,但确实有用。

Alice 通常不太了解 IT 和基础设施,老实说,她根本不关心这些话题。她的重点是推进她的研究,发表论文,等等:其他一切都是“工具”。

对于日常工作,她可以依靠自己强大(但昂贵)的桌面工作站:高端英特尔 CPU、64GB 内存、4TB 本地存储和几个中端英伟达 GPU。她认为自己很幸运有一个这样的人(并不是她的所有同事都这样),她很高兴自己可以独自工作“”。不过,如果她想保持合理的训练时间,她只能用一小部分数据集进行实验。

她每天晚上和每个周末都运行长时间的工作负载,希望它们不会崩溃…或者没有人会关掉她办公室的电源。当这种情况发生时,她叹了口气,然后重新开始工作。“浪费时间和精力又有什么用呢?”她想,但她对此无能为力。

她试图自己维护她的机器的软件配置,因为它不太了解她使用的深奥工具。尽管如此,她还是希望有人能为她这么做:NVIDIA 驱动程序、Tensorflow 依赖项等等让人感到相当困惑。当出现问题时,她会浪费宝贵的时间来修理“ IT 设备,这令人沮丧。当爱丽丝想要运行大型实验时,她必须使用托管在计算中心的远程服务器:一群非常强大的多 GPU 服务器,连接到 1pb 的 NAS 存储。当然,她必须与其他研究人员共享这些服务器。每周,团队领导都要会面并尝试对项目和工作量进行优先排序:这从来都不容易,决策往往需要上报给实验室主管。宝贵的时间被浪费了,有时实验无法在会议提交截止日期前完成。主管承诺明年的预算将考虑更多的服务器,但即使它们获得批准,采购和部署它们也需要几个月的时间。为了帮助安排工作量,Alice 雇佣了一名暑期实习生来编写一个简单的内部网门户,研究人员可以在那里手动预订服务器。它有点工作,但有时她的同事忘记发布服务器…或者他们不愿意发布服务器,因为他们知道他们必须等待获得另一个服务器。爱丽丝认为一定有更好的方法,但解决这个问题不是她的工作。不管怎样,她尽量用她能得到的东西来凑合。她不禁想到,如果她的实验不受容量限制,她会取得更大的进步。

最后但并非最不重要的一点是,Alice 受邀与位于另一个大陆的世界级实验室合作。在过去的一个月里,她一直试图找出如何与他们共享数据和基础设施。连接是复杂的,鉴于数据集的规模,数据传输几乎是不可能的。再次,“ IT 材料”阻碍了她的研究,她开始认为必须有一种更快更简单的方法来完成所有这些…也许云计算的东西可以有所帮助?

塞格马克土地上的爱丽丝医生

经过一些个人研究和数周的内部讨论,Alice 已经说服实验室主任让她试验 AWS,特别是那个看起来很有趣的 Amazon SageMaker 服务。

在短短几个小时内,她阅读了在线文档,快速创建了一个便宜的笔记本实例,并开始运行一些样本笔记本,以熟悉这项服务及其典型的工作流程。尽管她对 AWS 或 Python 了解不多,但她相信 SageMaker SDK 正是她所需要的,她很快就会上手。她甚至找到了一个关于如何为她心爱的 R 语言[创建定制环境的样本笔记本!

在 IT 的一点帮助下,爱丽丝上传了几兆字节的真实生活数据到](https://github.com/awslabs/amazon-sagemaker-examples/tree/master/advanced_functionality/r_bring_your_own)亚马逊 S3 ,以便在亚马逊 SageMaker 上复制她的桌面环境。在更多的阅读之后,她了解到只需要几行代码就可以在托管实例上训练她的模型,并且她将只为她实际使用的东西付费。她甚至可以根据需要在任意多的 p3.16xlarge 实例上训练她的模型:每一个都配备了八个 NVIDIA V100 GPUs!这与计算中心的大型服务器的配置相同。她现在可以按需创建它们:不再与其他团队争论。

得益于分布式训练和管道模式等高级功能,Alice 发现在自己的大型数据集上训练模型很容易:一切都开箱即用,伸缩自如。Alice 也很高兴看到 SageMaker 包含了一个自动模型调整模块:由于这个,她能够在仅仅几个小时的并行优化中显著提高她的模型的准确性。由于缺乏计算资源,用她以前的设置做这些是不可能的。

部署模型很简单:Alice 可以选择将模型部署到实时端点,或者运行批量预测。后者对她最有用,因为她需要偶尔预测大量数据。同样,只需要几行代码:她实际上复制粘贴了样本笔记本中的所有内容。最后但并非最不重要的一点是,跟踪她的支出很容易:AWS 控制台会告诉她花了多少钱,爱丽丝还可以设置预算警报。在与 IT 部门的同事交谈时,Alice 意识到 AWS 还有很多功能。看起来实验室可以使用名为 AWS Snowball 的服务轻松上传数百兆字节到亚马逊 S3!与已经是 AWS 客户的其他实验室和大学共享这些数据看起来并不复杂。爱丽丝期待着合作和创新的步伐加快!

短短一周左右,她对它的整个看法都变了。她说:“这个云东西实际上非常酷”。过去,AWS 阻碍了我的发展,但现在,它确实帮助我提供了比以前更好、更快、更便宜的结果。

云原生 Bob

鲍勃在一家大公司工作。他是一名后端软件工程师,从记事起就一直与数据打交道:SQL、NoSQL、Hadoop、Spark 以及现在的机器学习。使用现成的库(主要是 scikit-learn,还有一点 Tensorflow),Bob 和他的队友处理企业数据来训练数百个 ML 模型:线性回归、分类、分段等。繁重的工作(ETL、清理、特性工程)正在运行一个大的 Spark 集群。Bob 的公司使用 AWS 已经五年多了。所有开发、QA 和生产基础设施都托管在那里,他们是 DevOps 和云原生技术的忠实粉丝。最初,他们把一切都建立在亚马逊 EC2 上,因为他们觉得拥有完全控制权很重要。两年前,他们将 Spark 集群迁移到了亚马逊 EMR ,还决定使用 Docker containers 实现标准化生产:他们现在 100%的工作负载都部署到了一个大型的亚马逊 EKS 集群,因为 Kubernetes 是如此之酷,也因为从笔记本电脑到生产的无缝开发体验。他们根据建立了所有的 CI/CD 工具链,并使用 Terraform 实现了一切自动化。使用自动缩放和点实例优化成本。这些人真的很了解他们的东西,他们被邀请在下一次 AWS 峰会上展示他们的架构。当然了。

当然,他们的 ML 工作负载也运行在 EKS 集群上(大部分是在 CPU 实例上,也有一些 GPU)。Bob 为训练和预测维护定制的容器:库、依赖项等。这需要一点时间,但他喜欢这样做。他只是希望没有人会要求他也做 Pytorch 和 Apache MXNet。Bob 听说过深度学习 AMI 和深度学习容器。检查那些东西在他的任务清单上,但是他现在没有时间。

最初,Bob 希望让每个数据科学家使用 Terraform 模板创建他们自己的按需集群,但他担心成本难以管理。此外,创建一个集群需要 15-20 分钟,团队肯定会抱怨这一点。相反,Bob 建立了一个大型的共享培训集群:用户可以在几秒钟内开始他们的分布式工作,Bob 管理单个集群更简单。已经设置了自动扩展,但是仍然需要容量规划来找到预留、现场和按需实例的正确组合。

Bob 每周与团队开会,以确保他们有足够的实例…当他们需要额外的容量时,他们还会让他随时待命。Bob 尝试在晚上和周末集群不太忙的时候自动减少容量,但他很确定他们的花费太多了。哦好吧。

一旦模型经过训练和验证,Bob 会将它们推送到 CI/CD,它们会自动部署到生产集群。绿/蓝部署、服务发现、自动扩展、将日志推送到弹性搜索集群等。:整个九码。Bob 对他构建到系统中的自动化水*感到非常自豪,这是理所当然的。

云土著鲍勃在 SageMaker 土地

鲍勃已经在 SageMaker 上观看了一个 AWS 视频。他喜欢基于 Docker 的训练和预测,并且内置框架的容器是开源的:那么就不需要维护他自己的容器了。

将培训工作负载迁移到 SageMaker 看起来很容易:Bob 可以摆脱 EKS 培训集群,让每个数据科学家完全按需进行培训。随着 Spot 实例即将推出,Bob 当然可以进一步优化培训成本。

就预测而言,Bob 会考虑将批处理作业转移到 SageMaker,但不会转移实时 API:根据公司政策,这些必须部署到 EKS。这不成问题,因为他可以重复使用相同的容器。

几个星期后,鲍勃实现了所有这些改变。数据科学团队现在从实验到培训都是完全自主的,这是他们喜欢的:容量不再是问题,每周会议也变得没有必要。此外,由于 SageMaker 提供了已训练模型的可追溯历史,Bob 也发现自动化模型再训练和重新部署更容易:以前,他必须让数据科学团队来做,这个过程对他来说太不确定了。

像分布式训练、管道模式和自动模型调整这样的高级功能也相当不错。数据科学团队很快就采用了它们,这为他们节省了大量时间。此外,他们不再需要维护自己编写的代码来实现类似的东西。只有一个问题:现在,Bob 必须更新他的 AWS 峰会幻灯片,以说明 SageMaker 用例。也许当地的福音传道者可以帮助他?;)

一如既往的感谢您的阅读。很乐意在这里或者在 Twitter 上回答问题(DMs 开放)。也可以随意分享你自己的趣闻轶事!

我举起我的号角,向世界各地的人们致敬。继续建,我的 M(eta)L 兄弟姐妹:)

神秘博士 Kaggle 数据集和 NLTK 概述

原文:https://towardsdatascience.com/doctor-who-overview-of-the-kaggle-dataset-and-nltk-555f37323eda?source=collection_archive---------24-----------------------

你好,我写这篇短文的目的是:

  • 展示一个我在过去几周构建的数据集
  • 获得 nltk 的一些特性的概述

《神秘博士》是一部英国电视节目,是一部科幻片,由 BBC 制作于 1963 年,节目讲述了一个外星人(人形)博士的故事,他乘坐他的时间机器/宇宙飞船 Tardis(警察岗亭)在宇宙中旅行。

在这次时空旅行中,博士被来自地球的同伴跟随,因为他对地球有一些偏好(那很方便不是吗)。医生非常聪明、有趣,但角色的两个主要特征(来自他的外星种族时间领主)是:

  • 他是不朽的
  • 当他死的时候,他会以一种新的人类形式复活(对契约的结束非常有用)。每一次再生都保留着先前形态的记忆,但他有了新的面貌和新的举止。但是这种再生过程在迭代次数上受到限制

就表演而言,可以定义两个阶段(这是我的术语,所以请神秘博士的粉丝不要消灭我):

  • 从 1963 年到 1989 年的经典区域
  • 从 2005 年到现在的现代区域

就我而言,我在 2010 年左右发现了神秘博士,所以我更喜欢现代区域,我不太熟悉经典区域,但我喜欢现代区域,因为他们重新导入了经典区域的知识,并进行了更新(例如重新设计了博士的敌人)。

不管怎么说,这部剧从参照物到演员都是英国流行文化的一颗钻石,如果你喜欢科幻,绝对值得一看。

所以现在让我们深入研究一下这个项目的数据。

所以说实话,这个数据集受到了的启发,这个数据集聚焦于电视剧《辛普森一家》。

我从不同的网站搜集数据:

  • 这几集的剧本来自网站 chakoteya ,在那里可以找到每一集的所有对话等等
  • 《摩登地区》每集的收视率来自 IMDB
  • 关于这一集的信息来自指导的《神秘博士》,包含关于这一集的细节、演员或工作人员的分布。

这些数据集给出了节目的不同细节,可用于确定节目中可能影响 IMDB 评分的某些特定事件的影响。

例如,下图显示了现代地区不同季节的等级。

似乎所有赛季的收视率都接* 8,但最后一季似乎不太受公众欢迎,我认为这可能是两个原因:

  • 2005 年重新推出 sho 的历史节目主持人史蒂文·莫法特离开了制作,所以新的基调不适合观众
  • 这位新医生是一位女性,这是第一次在节目中出现,在宣布之后,这位女演员在互联网上引起了轩然大波/负面评论,因为 IMDB 上的评级是基于用户的,负面评论会影响评级(被仇恨者所偏见)

现在让我们看看这部剧的演员阵容,我想看看是否有一些名字出现在这部剧的两个时代之间,而且是一个相当大的数字,在 3146 名演员中,有 1362 名演员似乎出现在两个时代,医生似乎有更多的回归演员,但这很容易与周年纪念集(角色可以在时间中旅行,哈哈)

如果我们将这种分析集中在两个时代的演员身上,我们可以看到这些演员中有很大一部分是一些非人类角色的配音演员,例如尼古拉斯·布里格斯(Nicholas Briggs)扮演的 Dalek 的配音。

让我们深入剧集的脚本,开始用 NLTK 做一些文本分析。

为了对脚本进行分析,我将使用包 NLTK ,它被定义为

“构建 Python 程序以处理人类语言数据的领先*台。它为超过 50 个语料库和词汇资源(如 WordNet)提供了易于使用的接口,以及一套用于分类、标记化、词干化、标记、解析和语义推理的文本处理库,以及工业级 NLP 库的包装器”

对于这一部分,我将遵循 datacamp 制作的 NLTK 上的教程,在开始对文本进行分析之前,对脚本进行一些处理(标记化、停用词的清理和词汇规范化)。

我的分析将分为 3 个部分:

  • 获取最常用的单词和单词的索引
  • 为一些特定的字符画一些文字云
  • 做一些情绪分析

最常用的单词和索引

首先,在对不同的句子和单词进行标记化并对元素进行停用词过滤后,我们可以看到 10 个最流行的单词是:

猜猜哪个医生是最受欢迎的词,现在让我们调查一下医生这个词与之前和之后的词的一致性,并统计出现的次数。这是与“医生”这个词最相关的前 20 个词。

有趣的是,“the”是与医生更相关的单词的一个很好的候选词,但令人难过的是,“who”没有排在前 20 位(它排在第 34 位)。现在让我们来看看一些特定角色使用的单词。

Wordcloud

在这一部分,我将确定一系列字符中使用最多的单词(受这篇文章的启发,使用了一个单词云)

我们可以看到,医生是一个在医生的同伴口中反复出现的词。现在让我们看看这些疯狂的 Dalek 罐子说的话。

灭绝是剧中 daleks 使用最多的词之一,他们基本上想摧毁一切。

现在让我们对脚本进行一点情感分析

情绪分析器的使用

我将使用可以在 NLTK 上找到的情绪分析器,称为 Vader 情绪分析器

Vader 分析器来自 2014 年的出版物,它参考了化合价感知词典和情感推理器,你可以找到关于这个主题的一篇有趣的文章。这个开箱即用的分析器非常有用,下图是医生在第一季的一集里说的话的演变。

正如我们所看到的,在一集的不同阶段,医生会引用不同的话,但大多数时候,医生对他的讲话是中立的。在下图中,有另一个引用医生的话的情绪的图示,有一个引用的积极和消极的图。

结论

这篇文章是对我的 kaggle 数据集的介绍。通过对 NLTK 的简单了解,我对这个数据集有了一些想法,将来我一定会用它来做一些关于 NLP 的实验。如果您对数据集、应用程序等有任何意见,请随时联系我。

原载于http://the-odd-dataguy.com

文档嵌入技术

原文:https://towardsdatascience.com/document-embedding-techniques-fed3e7a6a25d?source=collection_archive---------1-----------------------

关于这一主题的著名文献综述

单词嵌入——将单词映射到数字向量空间——*年来已被证明是自然语言处理(NLP)任务的一种非常重要的方法,使各种依赖向量表示作为输入的机器学习模型能够享受更丰富的文本输入表示。这些表示保留了单词的更多语义和句法信息,从而提高了几乎所有可以想象的 NLP 任务的性能。

这种新颖的想法本身及其巨大的影响促使研究人员考虑如何为更大的文本单元(从句子到书籍)提供更丰富的矢量表示这一好处。这一努力导致了一系列产生这些映射的新方法,对该问题提出了各种创新的解决方案,并取得了一些显著的突破。

这篇文章是我在介绍自己这个话题的时候写的(作为大熊猫项目的一部分,在那里我咨询了几年 ❤️🐼),旨在展示从业者产生文档嵌入的不同方式。

注意:我在这里使用单词 文档 来指代 任何单词序列 ,从句子和段落到社交媒体帖子,一直到文章、书籍和更复杂结构的文本文档(例如表格)。

Figure 1: A common example of embedding documents into a wall

在这篇文章中,我不仅会谈到直接扩展单词嵌入技术的方法(例如,以 doc2vec 扩展 word2vec 的方式),还会谈到其他值得注意的技术,这些技术有时会产生其他输出,例如在ℝⁿ.中从文档到矢量的映射

只要有可能,我还会尽量提供链接和参考资料,既指向原始论文,也指向被评审方法的代码实现。

注:这个题目和学习结构化文本表示的问题有些关联,但不等价(例如【刘& Lapata,2018】)。

目录

  1. 文档嵌入的应用

  2. 突出方法和趋势

    • 文档嵌入方法-
      -趋势和挑战
  3. 经典技巧

    • 词汇袋-
      -潜在狄利克雷分配(LDA)
  4. 无监督文档嵌入技术

    • n-gram 嵌入
    • *均词嵌入
      -sent 2 vec
      -段落向量(doc 2 vec)
      -doc 2 vec-Skip-think 向量
      -fast sent
  5. 监督文档嵌入技术

    • 从标记数据中学习文档嵌入
    • 特定任务监督文档嵌入
      --GPT
      ---深度语义相似度模型(DSSM)
    • 联合学习句子表示
      -通用句子编码器
      -根森
  6. 如何选择使用哪种技术

  7. 最后的话

  8. 参考文献

文档嵌入的应用

将文档映射到信息向量表示的能力具有广泛的应用。以下只是部分列表。

[ Le & Mikolov,2014 ]在几个文本分类和情感分析任务上展示了他们的段落向量方法的能力,而[ 戴等人,2015 ]在文档相似性任务和[ Lau & Baldwin,2016 ]在一个论坛问题复制任务和语义文本相似性(STS) SemEval 共享任务上对其进行了基准测试。

【 Kiros 等人,2015 】已经展示了他们的跳过思维向量用于语义相关度、释义检测、图像句子排序、问题类型分类和四个情感和主观性数据集。[Broere,2017]使用它们来预测词性标签和依存关系。

【陈等,2018 】展示了 BioSentVec ,他们在生物医学文本上训练的句子嵌入集,在句子对相似度任务上表现良好(官方 Python 实现)。

最后,深度语义相似性模型被各种作者用于信息检索和网页搜索排名、广告选择/相关性、上下文实体搜索和兴趣任务、问题回答、知识推理、图像字幕和机器翻译任务。

突出的方法和趋势

我最后写这一部分,已经花了很多时间思考如何组织这篇文章,如何将下面几节中涉及的各种技术归类到突出的方法中,以及在检查该领域中不同的作品如何相互关联以及它们彼此遵循的方式时会出现什么趋势。

但是,请注意,虽然文档嵌入的问题由来已久,但许多目前有影响力的解决方案还很年轻,而且这个领域最*(大约在 2014 年)在当代基于编码器-解码器的单词嵌入技术取得成功之后又出现了复兴,所以这仍然处于早期阶段。说了这么多,我希望这一部分能把下面的部分放到一个更广阔的背景中,并以一种有意义的方式框定它们。

文档嵌入方法

绘制该领域的一种可能方法是以下四种主要方法:

  1. 总结词语向量
    这是的经典做法。单词袋对一个热门单词向量就是这样做的,你可以对它应用的各种加权方案都是这种总结单词向量的方法的变体。然而,这种方法在与最先进的单词表示一起使用时也是有效的(通常通过求*均值而不是求和),尤其是当单词嵌入考虑到这种用途而被优化时,并且可以抵抗这里介绍的任何更性感的方法。
  2. 主题建模
    虽然这通常不是 LDA 和 PLSI 等主题建模技术的主要应用,但它们最*生成了一个文档嵌入空间
    来建模和解释语料库中的单词分布,其中维度可以被视为隐藏在数据中的潜在语义结构,因此在我们的上下文中很有用。在这篇文章中,我并没有真正涉及这种方法(除了对 LDA 的简单介绍),因为我认为 LDA 很好地代表了这种方法,而且这种方法也广为人知。**
  3. 编码器-解码器模型
    这是场景中最新的无监督添加,具有 doc2vecskip-thought 之类的功能。虽然这种方法自 21 世纪初就已经存在,名为
    神经概率语言模型,但最*随着它在单词嵌入生成方面的成功应用,它获得了新的生命,当前的研究集中在如何将其应用扩展到文档嵌入。这种方法比其他方法从不断增加的大量未标记语料库中获益更多。
  4. 监督表示学习
    这种方法的生命力归功于神经网络模型的伟大崛起(或复兴),以及它们使用各种非线性多层运算符学习输入数据的丰富表示的能力,这可以*似大范围的映射。通过简单地将旧的单词袋输入到神经网络学习中,以解决一些与监督文本相关的问题,您可以获得一个模型,其中隐藏层包含输入文本的丰富表示,这正是我们所追求的。

有几个无监督的方法不适合上述任何一组(特别是,快速思考单词移动器的距离浮现在脑海中),但我认为大多数技术都属于这四大类别之一。

注:虽然人们很容易指出经典的单词袋技术缺乏订单信息,但这实际上是一种规律,而不是例外。这里回顾的大多数新方法获得的主要信息是将分布假设扩展到更大的文本单元。基于神经网络的序列模型是例外。

趋势和挑战

当从整体上考察文档嵌入技术的研究和应用时,出现了几个大的趋势,以及人们可能会发现的几个挑战。

  1. 编码器-解码器优化:研究的一个显著部分集中在优化确切的架构(例如 NN/CNN/RNN)和一些组件/超参数(例如 n-gram、投影函数、称重等)。)的无监督编码器-解码器方法来学习文档嵌入。虽然这种微调的部分目标是提高各种任务的成功指标,但在更大的语料库或更短的时间内训练模型的能力也是一个目标。
  2. 学习目标设计:无监督(或自我监督)表示学习的关键在于设计一个学习目标,它利用数据中可自由获得的标签,以某种方式生成对下游任务有用的表示。对我来说,这是最令人兴奋的趋势,我认为这是对 NLP 任务影响最大的趋势,可能等同于单词嵌入技术。目前,我认为只有思维敏捷的字移动器的距离可以作为编码器-解码器方法的替代方案。这一趋势的另一个吸引人的方面是,这里的创新可能也适用于单词嵌入的问题。
  3. 基准测试:一般来说,作为机器学习研究领域趋势的一部分,文档嵌入,也许是因为它是一个年轻的子领域,很好地证明了对大范围和大量任务的技术基准测试的研究的日益关注(参见 the GLUE leaderboard )。然而,几乎每一篇关于这一主题的论文都宣称其结果与目前的 SOTA 技术相当或更好,这还没有导致一个明确的领导者出现在这群人的前面。
  4. 开源:同样,作为更广泛趋势的一部分,易于使用的代码实现技术(通常也是实验)的火热发布实现了可重复性,并推动了学术界以外更广泛的数据科学社区的参与和对真实世界问题的使用。
  5. 跨任务适用性:虽然不是所有的无监督技术都以相同水*的全面性作为基准,但这可能更多是监督嵌入学习的情况。无论如何,依赖于文本数据中不同类型的信息的各种各样极其不同的 NLP 任务,使得这个问题成为一个突出的问题。从几个任务中联合学习嵌入是一种有趣的方式,其中有监督的方法可能解决这个挑战。
  6. 标记语料库:非常大的标记语料库的有限可用性也是未来监督方法的一个问题。这可能代表了未来几年无监督方法在监督表示学习方面的真正优势。

注意:如果你觉得这部分有点断章取义,我建议你在看完这篇文章中的大部分技巧后再来看一看。

经典技术

本节简要介绍了两种已建立的文档嵌入技术:单词袋潜在狄利克雷分配。随意跳过。

词汇袋

该方法在[Harris,1954]中提出,将文本表示为其单词的包( multiset )(丢失语法和排序信息)。这是通过决定将形成映射所支持的词汇表的一组 n 个单词,并给词汇表中的每个单词分配一个唯一的索引来完成的。然后,每个文档由一个长度为 n 的向量表示,其中第 i 个条目包含单词 i 在文档中出现的次数。

Figure 2: A bag-of-words representation of an example sentence

比如那句“狗咬狗的世界,宝贝!”(在清除标点符号之后)可以由 550 长度的向量 v 表示(假设选择了 550 个单词的词汇),除了以下条目之外,该向量在任何地方都是零:

  • V₇₆=1,作为词汇表的第 76 个单词是世界
  • V₂₀₀=2,作为词汇表的第 200 个单词是
  • V₃₂₂=1,作为词汇表中的第 332 个单词是吃。
  • 单词 baby 没有被选择包含在词汇表中,因此它在没有向量条目时导致值 1。

尽管它非常简单,除了单词出现频率之外的所有信息都丢失了,并且表示大小有快速增长以支持丰富词汇的趋势,但这种技术几十年来几乎只在大量的 NLP 任务中使用,并取得了巨大的成功。尽管*年来文本的矢量表示取得了重大进展,但这种方法的常见细微变化(见下文)今天仍在使用,而且并不总是作为第一个被迅速超越的基线。

n 字袋 为了重新获得由字袋方法丢失的一些词序信息,短词序列(长度为二、三等)的频率。)可用于(附加地或替代地)构建单词向量。自然,单词袋是这种方法的一个特例,因为 n=1

对于那句“狗咬狗的世界,宝贝!”,单词对是“狗食”、“吃狗”、“狗世界”和“世界宝宝”(有时也有“狗”和“宝宝”),词汇由输入语料库中所有连续的单词对组成(或用其增强)。

Figure 3: 2-grams representation of the sentence “The movie is amazing”

这种方法的一个主要缺点是词汇大小对唯一单词数量的非线性依赖,这对大型语料库来说可能非常大。过滤技术通常用于减少词汇量。

tf-idf 加权 词袋上下文中最后一个值得一提的相关技术是 词频——逆文档频率 ,通常表示为 tf-idf 。该方法用每个单词的逆文档频率* (IDF)对上述单词(或 n-gram)频率向量重新加权。一个单词的 IDF 就是语料库中文档数量的对数除以该单词出现的文档数量。*

简而言之,TF 术语随着该词出现得越来越频繁而增长,而 IDF 术语随着该词出现得越来越少而增长。这是为了调整频率分数,因为一般来说,有些词出现的频率更高(或更低)。参见[ Salton & Buckley,1988 ]对术语加权方法的全面概述。

潜在狄利克雷分配

LDA 是一个生成统计模型,它允许用未观察到的组来解释观察结果集,从而解释为什么数据的某些部分是相似的。例如,如果观察是收集到文档中的单词,那么它假设每个文档是少量主题的混合物,并且每个单词的出现都归因于文档的一个主题。

为了将这一点与词袋联系起来,前一种方法可以被认为是一种过于简单的概率模型,将文档作为词的分布。单词袋向量则代表我们对每个文档中的非标准化单词分布的最佳*似;但是这里的文档是基本的概率单位,每一个都是其唯一分布的单个样本。

因此,问题的关键是通过增加一个潜在的(隐藏的)K 主题的中间层,从这个简单的文档概率模型转变为一个更复杂的模型。

Figure 4: The probabilistic model shift from bag-of-words to LDA

主题现在的特征是单词上的分布,而文档是主题上的分布。文档的概率模型对应于文档的生成模型;为了生成一组长度为 {Nᵢ}M 个文档,假设预定数量的 K 个主题,其中 Dir() 表示一个狄利克雷分布:

  1. 对于每个题目 v ,取样一个单词分布φᵥ~ Dir(β)
  2. 对于每个文档 i ,抽取一个主题分布(或混合)θᵢ~ Dir( α )
  3. 生成长度为 Nᵢ 的文件 i ,每个字 j :
    3.1。样题 zᵢⱼ ~ Multinomial(θᵢ) 作词 j 。3.2。样字
    j~multinomial(zᵢⱼ)

给定这个模型和一个文档集,问题就变成了推理,在推理过程中可以找到上述各种分布的*似值。其中有θᵢ,每个文档的主题分布 i ,维度矢量 K

因此,在推断模型的过程中,推断出维度为 K 的向量空间,该向量空间以某种方式捕获了我们语料库中的主题或主题以及它们在其中的文档之间共享的方式。当然,这可以作为这些文档的嵌入空间,并且——取决于对 K 的选择——它可以比基于词汇表的文档小得多。

事实上,虽然 LDA 的主要使用情况是无监督的主题/社区发现,但是其他情况包括使用所得的潜在主题空间作为文档语料库的嵌入空间。还要注意,其他主题建模技术——例如非负矩阵分解(NMF) 和概率潜在语义索引(PLSI)——可以以类似的方式用于学习文档嵌入空间。

注意:从业者对于概率主题模型的一个主要问题是它们的稳定性。因为训练主题模型需要概率分布的采样,所以可以预期相同语料库的模型随着随机数生成器的种子变化而不同。这个问题由于主题模型对相对小的语料库变化的敏感性而变得复杂。

无监督文档嵌入技术

本节中介绍的许多方法都是受著名的单词嵌入技术的启发,其中最主要的是 word2vec ,它们有时甚至是这些方法的直接推广。这些单词嵌入技术有时也被称为神经概率语言模型;这些不是相同的术语,因为概率语言模型是单词序列的概率分布,但是由于这种方法是作为一种学习语言模型的方法在[ Bengio,2003 中介绍的,所以它们是紧密相关的。

因此,对单词嵌入技术的基本理解对于理解本节至关重要。如果你不熟悉这个主题,Chris McCormick 写得很好的关于 word2vec 的两部分教程是一个很好的起点(第二部分,Joshua Bengio 教授写的关于神经网络语言模型的 Scholarpedia 文章也是如此(参见 Hunter Heidenreich 的帖子,以获得关于单词嵌入的更一般和简明的概述,以及 [Alex Minnar 的然而,为了深刻理解细节,我强烈建议您阅读 Bengio,2003 年 ]、[ Mikolov 等人,2013 年 a ]和[ Pennington 等人,2014 年 ]关于该主题的开创性论文,这些论文在许多方面塑造了这一子领域。

即使假设你熟悉这个模型的一个重要假设,我仍然希望注意到这个模型所做的一个重要假设,这个假设可能被这里回顾的每一个模型所继承:分布假设。下面是来自维基百科的简要描述:

语言学中的分布假设来源于语言使用的语义理论,即在相同语境中使用和出现的词语倾向于表达相似的意思。“一个词由它所结交的朋友来表征”的基本思想是由弗斯推广开来的。分布假设是统计语义学的基础。

事实上,很容易看出 word2vec 以及其他用于学习单词表示的自我监督方法严重依赖于这一假设;毕竟,该模型的关键在于,在学习从单词本身预测单词的上下文(或反之亦然)时学习的单词表示表示捕获深层语义和句法概念和现象的向量空间。意义,从一个词的上下文中学习可以教我们关于它的意义和它的句法作用。

在本节中,涵盖自我监督的文档表示学习,您将看到所有这些方法都保持了对单词的假设,并以某种方式将其扩展到更大的文本单元。

n 元文法嵌入

[ Mikolov 等人,2013b ]扩展了 word2vec 的 skip-gram 模型,通过使用数据驱动的方法识别大量短短语(作者专注于两个和三个单词的短语),然后在 word2vec 模型的训练期间将这些短语视为单独的标记,来处理短短语。自然,这不太适合学习更长的短语——因为当短语长度增加时,词汇量会爆炸——而且肯定不会推广到看不见的短语以及跟随它的方法。

Moshe Hazoom 写了一篇关于这种方法的精彩实用评论,他的雇主将其用于一个专注于金融领域的搜索引擎。

*均单词嵌入

从有意义的单词嵌入中构造文档嵌入有一种非常直观的方法:给定一个文档,对该文档的单词对应的所有向量执行一些向量运算,以在相同的嵌入空间中将它们概括为单个向量;两种常见的汇总运算符是 average 和 sum。

在此基础上,您也许已经可以想象扩展 word2vec 及其相关的编码器-解码器架构来学习如何将单词向量组合到文档嵌入中会很有趣;这个方法之后的方法属于这一类。**

第二种可能性是使用固定的(不可学习的)算子来进行向量汇总,例如*均,并使用旨在产生丰富的文档嵌入的学习目标来学习在前一层中的单词嵌入;一个常见的例子是使用一个句子来预测上下文句子。因此,这里的主要优点是单词嵌入被优化用于*均到文档表示中。

Figure 5: Siamese CBOW network architecture from [Kenter et al, 2016]

[ 肯特等人,2016 ]正是这样做的,使用一个简单的神经网络对单词向量进行*均,通过预测给定的句子表示来学习单词嵌入。他们将结果与*均的 word2vec 向量和 skip-thoughts 向量进行比较(参见下面相应的小节)。【 Hill 等人,2016 】比较了过多的方法,包括训练 CBOW 和 skip-gram 单词嵌入,同时优化句子表示(这里使用单词向量的元素相加)。[ Sinoara 等人,2019 ]还提出了一种将单词嵌入向量和其他知识源(如词义向量)直接组合到它们的质心中来表示文档。

最后,[ Arora 等人,2016 ]进一步表明,当增加两个小的变化时,这种方法是一种简单但难以击败的基线:(1)使用*滑的逆频率加权方案,以及(2)从词向量中移除常见话语成分;这个成分是使用 PCA 发现的,并且它被用作最频繁话语的校正术语,推测与句法有关。作者提供了一个 Python 实现。

注意:当观察基于注意力的机器翻译模型时,也许可以找到正确*均的单词“嵌入”的力量的另一个证明。单向解码器 RNN 获得先前翻译的单词作为输入,加上不仅要翻译的当前单词的“嵌入”(即来自编码器 RNN 的双向激活),而且要翻译其周围单词的“嵌入”;这些以加权的方式被*均成一个上下文向量。它教导了这种加权*均能够保持来自编码器网络激活的复杂的组成和顺序相关的信息(回想一下,这些不像在我们的情况中那样是孤立的嵌入;每一个都注入了前面/后面单词的上下文)。

Sent2Vec

在[ Pagliardini 等人,2017 ]和[ Gupta 等人,2019 ](包括一个官方的基于 C++的 Python 实现)中介绍了这种技术,这种技术在很大程度上是上述两种方法的结合: word2vec 的经典 CBOW 模型都进行了扩展,以包括单词 n-grams ,它们适用于优化单词(和 n-grams)嵌入,以便对它们进行*均

Figure 6: sent2vec can be thought of as an unsupervised version of fastText

此外,去除了输入二次采样的过程,而是将整个句子视为上下文。这意味着 (a) 放弃使用频繁的单词二次采样——以便不阻止 n-grams 特征的生成——以及(b)word 2 vec使用的动态上下文窗口被取消:整个句子被视为上下文窗口,而不是在 1 和当前句子的长度之间均匀地采样每个二次采样单词的上下文窗口大小。

另一种思考 sent2vec 的方式是作为 fastText 的无监督版本(见图 6),其中整个句子是上下文,可能的类别标签都是词汇单词。巧合的是,[ Agibetov 等人,2018 ]针对生物医学句子分类的任务,比较了使用 sent2vec 向量作为特征的多层感知器与 fastText 的性能。

段落向量(doc2vec)

有时被称为 doc2vec ,这种方法在[ Le & Mikolov,2014 中提出,可能是第一次尝试将 word2vec 推广到处理单词序列。作者介绍了 p 图向量模型的两种变体:分布式内存分布式单词包。**

段落向量:分布式内存(PV-DM) PV-DM 模型通过添加内存向量来增强标准编码器-解码器模型,旨在从输入中捕捉段落的主题或上下文。这里的训练任务和连续包话挺像的;一个单词可以从它的上下文中预测出来。在这种情况下,上下文单词是前面的单词,而不是周围的单词,就像段落一样。

Figure 7: The Distributed Memory model of Paragraph Vectors (PV-DM)

为了实现这一点,每个段落都被映射到一个唯一的向量,由矩阵中的一列表示(用 D 表示),词汇表中的每个单词也是如此。上下文是固定长度的,从段落上的滑动窗口中采样。段落向量在从同一段落生成的所有上下文之间共享,但不在段落之间共享。自然地,单词嵌入是全局的,并且可以使用预先训练的单词嵌入(参见下面的实现和增强)。

正如在 word2vec 中,向量必须以某种方式汇总成一个单一的向量;但是与 word2vec 不同,作者在他们的实验中使用了串联。请注意,这保留了订单信息。类似于 word2vec ,一个简单的 softmax 分类器(在这种情况下,实际上是分层的 softmax)被用于这个概括的向量表示,以预测任务输出。训练以标准方式进行,使用随机梯度下降并通过反向传播获得梯度。

注意,只有训练语料库中的段落具有来自 D 的与其相关联的列向量。在预测时,需要执行推理步骤来计算新段落的段落向量:文档向量是随机初始化的。然后,重复地从新文档中选择一个随机单词,并使用梯度下降来调整输入到隐藏层的权重,使得对于所选择的单词,softmax 概率最大化,而隐藏到 softmax 输出的权重是固定的。这导致新文档的表示为训练语料库文档向量(即 D 的列)的混合,自然地驻留在文档嵌入空间中。

段落向量:分布式单词包(PV-DBOW)
段落向量的第二种变体,顾名思义,或许是 word2vecskip-gram 架构的并行;分类任务是仅使用段落向量来预测单个上下文单词。在随机梯度下降的每次迭代中,采样一个文本窗口,然后从该窗口中采样单个随机单词,形成下面的分类任务。

Figure 8: The Distributed Bag of Words model of Paragraph Vectors (PV-DBOW)

训练在其他方面是相似的,除了单词向量不与段落向量一起被联合学习的事实。这使得 PV-DBOW 变体的内存和运行时性能都要好得多。

注:在 its Gensim 实现中,PV-DBOW 默认使用随机初始化的字嵌入;如果 dbow_words 设置为 1,则在运行 dbow 之前,会运行一步 skip-gram 来更新字嵌入。[ Lau & Baldwin,2016 ]认为,尽管 dbow 在理论上可以处理随机单词嵌入,但这严重降低了他们所研究的任务的性能。

一个直观的解释可以追溯到模型的目标函数,即最大化文档嵌入与其组成单词嵌入之间的点积:如果单词嵌入是随机分布的,则更难以将文档嵌入优化为接*其更关键的内容单词。

应用、实现和增强 【Le&miko lov,2014】演示了段落向量在几个文本分类和情感分析任务中的使用,而【Dai et al,2015】在文档相似性任务的背景下对其进行了检查,并且【Lau & Baldwin,2016】将其与论坛问题复制任务和 语义文本相似性(STS) SemEval 共享任务进行了基准测试。后面的两篇论文对该方法进行了扩展评估(前者侧重于 PV-DBOW 变体),将其与其他几种方法进行了比较,并给出了实用建议(后面的包括代码)。

这个方法有一个 Python 实现,作为 gensim 包的一部分,还有一个 PyTorch 实现。同样,【 Lau & Baldwin,2016 】也提供了他们考试用的代码。

最后,提出了对该方法的各种改进。例如,【李等,2016 】将该方法扩展为也包含 n-gram 特征,而【thong tan&phiconstrakul,2019】建议在计算嵌入投影时使用余弦相似度而不是点积(还提供了一个 Java 实现)。

Doc2VecC

【陈,2017 】提出了一种有趣的方法,该方法受段落向量方法(PV-DM)的分布式记忆模型和*均单词嵌入的方法的启发来表示文档。

Figure 9: The architecture of the Doc2VecC model

段落向量doc 2 vecc(文档
向量穿越讹误的首字母缩写)由输入层、投影层和输出层组成,预测目标词(上例中为“仪式”)。相邻单词的嵌入(例如“开始”、“for”、“The”)提供局部上下文,而整个文档的向量表示(以灰色显示)用作全局上下文。与直接学习每个文档的唯一向量的段落向量相反,doc 2 vec将每个文档表示为从文档中随机采样的单词的嵌入的*均值(例如,在位置 p 的“性能”,在位置 q 的“称赞”,以及在位置 r 的“巴西”)。

此外,作者选择通过随机删除单词的重要部分来破坏原始文档,通过*均化剩余单词的嵌入来表示文档。这种损坏机制允许在训练期间加速,因为它显著地减少了在反向传播中要更新的参数的数量。作者还展示了它如何引入一种特殊形式的正则化,他们认为这导致了观察到的性能改善,基准测试是情感分析任务、文档分类任务和语义相关度任务,而不是过多的最先进的文档嵌入技术。

在一个公共的 Github 库中可以找到一个基于 C 的方法和代码的开源实现,用于重现论文中的实验。

[ 希尔等人,2016 年 ]还将破坏或添加噪声到文档嵌入学习过程以产生更鲁棒的嵌入空间的一般思想应用于跳过思维模型(见以下小节),以创建他们的顺序去噪自动编码器(SDAE)模型。

跳跃思维向量

在[ Kiros et al,2015 中提出,这是另一个早期推广 word2vec 的尝试,并与一起发布了一个官方的纯 Python 实现(最*还宣称实现了 PyTorch 和 TensorFlow )。

然而,这以另一种直观的方式扩展了word 2 vec——特别是 skip-gram 架构:基本单元现在是句子,一个编码的句子用于预测它周围的句子。使用在上述任务上训练的编码器-解码器模型来学习矢量表示;作者使用具有 GRU 激活的 RNN 编码器和具有条件 GRU 的 RNN 解码器。两个不同的解码器被训练用于前一个和下一个句子。

Figure 10: The skip-thoughts model. Given a tuple of contiguous sentences, the sentence sᵢ is encoded and tries to reconstruct the previous sentence sᵢ₋₁ and the next sentence sᵢ₊₁

skip-thought 中的词汇扩展
skip-thought编码器使用单词嵌入层,将输入句子中的每个单词转换为其对应的单词嵌入,有效地将输入句子转换为一系列单词嵌入。这个嵌入层也由两个解码器共享。

Figure 11: In the skip-thoughts model, sentence sᵢ is encoded by the encoder; the two decoders condition on the hidden representation of the encoder’s output hᵢ to predict sᵢ₋₁ and sᵢ₊₁ [from Ammar Zaher’s post]

然而,作者只使用了 20,000 个单词的小词汇量,因此在各种任务中使用时可能会遇到许多看不见的单词。为了克服这一点,通过为参数化该映射的矩阵 W 求解非正则化的 L2 线性回归损失,学习从在大得多的词汇表(例如 word2vec )上训练的单词嵌入空间到跳过思想模型的单词嵌入空间的映射。

应用、增强和进一步阅读 作者演示了将跳过思维向量用于语义相关度、释义检测、图像句子排序、问题类型分类和四个情感和主观性数据集。【 Broere,2017 】通过对 skip-thought 句子表征进行训练逻辑回归来预测词性标签和依存关系,从而进一步研究其句法属性。

[ Tang et al,2017a ]提出了一种针对 skip-thought 的邻域方法,丢弃排序信息并使用单个解码器预测上一句和下一句。【【唐等,2017b 】扩展该检查,提出对模型的三个增强,他们声称使用更快和更轻的模型来提供可比的性能: (1) 仅学习解码下一句话, (2) 在编码器和解码器之间添加 avg+max 连接层(作为允许非线性非参数特征工程的方式),以及 (3) 执行良好的字嵌入初始化。最后,【 Gan et al,2016 】在广泛的应用中,使用基于 CNN 的分层编码器而不是仅基于的编码器来应用相同的方法。

在[ Lee & Park,2018 ]中提出的另一种变体,通过基于文档结构为每个目标句子选择整个文档中有影响的句子来学习句子嵌入,从而使用元数据或文本样式来识别句子的依存结构。此外,【 Hill 等人,2016 】提出了顺序去噪自动编码器(SDAE)* 模型,这是 skip-thought 的变体,其中输入数据根据一些噪声函数被破坏,模型被训练以从被破坏的数据中恢复原始数据。*

对于关于 skip-thought 模型的进一步非学术阅读, Sanyam Agarwa 在他的博客上给出了该方法的一个非常详细的概述,而 Ammar Zaher 展示了其用于构建烹饪食谱的嵌入空间。

快速发送

【 Hill 等人,2016 】在skip-thinks模型的基础上提出了一个明显更简单的变体; FastSent 是一个简单的加法(对数双线性)句子模型,旨在利用相同的信号,但计算开销低得多。给定一些上下文句子的 BOW 表示,该模型简单地预测相邻的句子(也表示为 BOW)。更正式地说, FastSent 学习模型词汇表中每个单词 w 的源 uᵂ和目标 vᵂ嵌入。对于连续句的训练示例 Sᵢ₋₁,Sᵢ,Sᵢ₊₁,Sᵢ被表示为其源嵌入的总和**=t34】uᵂ超过 w∈Sᵢ 。这个例子的成本是简单的𝜙(sᵢ vᵂ)除以w∑sᵢ₋₁∪sᵢ₊₁,其中𝜙是 softmax 函数。这篇论文附有官方的 Python 实现。**

思维敏捷的向量

[ Logeswaran & Lee,2018 ]将文档嵌入任务——预测句子出现的上下文的问题——重新表述为监督分类问题(见图 12b),而不是之前方法的预测任务(见图 12a)。

Figure 12: The Quick-Thought problem formulation (b) contrasted with the Skip-Thought approach (a)

要点是使用当前句子的含义来预测相邻句子的含义,其中含义由从编码函数计算的句子的嵌入来表示;注意这里学习了两个编码器:输入句子的 f 和候选句子的 g 。给定一个输入句子,由编码器(本例中为 RNNs)进行编码,但模型不是生成目标句子,而是从一组候选句子中选择正确的目标句子;候选集是从有效的上下文句子(基本事实)和许多其他非上下文句子中构建的。最后,所构建的训练目标最大化了为训练数据中的每个句子识别正确上下文句子的概率。将以前的句子预测公式视为从所有可能的句子中选择一个句子,这种新方法可以被视为对预测问题的一种判别*似。

作者评估了他们在各种文本分类、释义识别和语义相关任务上的方法,并提供了官方 Python 实现。

文字移动器嵌入(WME)

一个最*的方法,来自 IBM 的研究,是字移动器嵌入(),在 Wu et al,2018b 中提出。提供了一个官方的基于 C、Python 包装的实现。

【库什纳等人,2015 】提出 W 移动者距离(WMD);这将两个文本文档之间的相异度度量为一个文档的嵌入单词需要在嵌入空间中“行进”到达另一个文档的嵌入单词的最小距离量(见图 13a)。此外,[ Wu et al,2018a ]提出了 D2KE(到核和嵌入的距离),一种从给定的距离函数推导正定核的通用方法。****

Figure 13: Contrasting WMD with WME. (a) WMD measures the distance between two documents x and y, while (b) WME approximates a kernel derived from WMD with a set of random documents 𝜔.

WME 基于三个组件来学习不同长度文本的连续矢量表示:

  1. 以无监督的方式学习高质量单词嵌入的能力(例如,使用 word2vec )。
  2. 使用 Worder Mover 的距离 (WMD)基于所述嵌入为文档构建距离度量的能力。
  3. 使用 D2KE 从给定的距离函数导出正定核的能力。

使用这三个组件,应用以下方法:

  1. 使用 D2KE,通过由字移动器到来自给定分布的随机文档𝜔的距离 (WMD)给出的无限维特征映射,构造一个正定字移动器的核 (WMK)。由于使用了 WMD,特征图考虑了由预训练单词嵌入给出的语义空间中的文档之间的单个单词的对齐(参见图 13b)。
  2. 基于该核,通过核的随机特征*似来导出文档嵌入,其内积*似精确的核计算。

这个框架是可扩展的,因为它的两个构建模块,word2vec 和 WMD,可以被其他技术代替,例如 GloVe(用于单词嵌入)或 S-WMD(用于将单词嵌入空间转换成文档距离度量)。

作者在 9 个真实世界文本分类任务和 22 个文本相似性任务上评估了 WME,并证明它始终匹配,有时甚至超过其他最先进的技术。

句子-BERT (SBERT)

NLP 中的 2018 年以 transformers 的崛起为标志(见图 14),最先进的神经语言模型受[ Vaswani et al 2017 ]中提出的 transformer 模型的启发-一种序列模型,它无需卷积和递归,而是使用注意力将序列信息纳入序列表示。这个蓬勃发展的家庭包括伯特(及其延伸),GPT (1 和 2)和 XL 口味的变形金刚。

Figure 14: Rise of the transformers

这些模型生成输入标记(通常是子词单元)的上下文嵌入,每个标记都注入了其邻域的信息,但并不旨在为输入序列生成丰富的嵌入空间。BERT 甚至有一个特殊的[CLS]令牌,其输出嵌入用于分类任务,但对于其他任务来说仍然是输入序列的不良嵌入。[ 雷默斯&古雷维奇,2019

Sentence-BERT ,在【 Reimers & Gurevych,2019 中提出,并伴随有一个 Python 实现,旨在通过使用连体和三联体网络结构来调整 BERT 架构,以导出语义上有意义的句子嵌入,可以使用余弦相似度进行比较(见图 15)。

Figure 15: The SBERT architecture in training on a classification objective (left) and inference (right)

监督文档嵌入技术

前一节中介绍的非监督方法允许我们从大型未标记的语料库中学习有用的表示。这种方法不是自然语言处理所独有的,它通过设计学习目标来关注学习表示,这些学习目标利用数据中可自由获得的标签。因此,这些方法的强度和稳健性不仅在很大程度上取决于学习框架,还取决于人工设计的学习目标要求或带来在各种下游任务中证明有用的有意义特征或知识的学习的程度。例如,我们希望单词和文档嵌入空间能够很好地捕获语义和句法信息。

学习有意义的数据表示(在我们的例子中是单词序列)的对比方法是利用显式标签(几乎总是由人类注释者以某种方式生成)。这里,与各种任务的相关性取决于明确的任务和标签与最终应用的接*程度,同样,该任务对可概括的特征和知识的学习有多好。

我们将看到监督方法的范围从那些直接利用特定的标记任务来学习表征,到那些重组任务或从中提取新的标记任务来引出更好的表征。

从标记数据中学习文档嵌入

已经有各种尝试使用标记的或结构化的数据来学习句子表示。具体来说,[ Cho 等人,2014a ]和[ Sutskever 等人,2014 ]可能是首次尝试应用编码器-解码器方法来显式学习带有标记数据的句子/短语嵌入;第一个使用了用于统计机器翻译的*行短语语料库 Europarl ,第二个使用了来自 WMT 14 数据集的英语到法语的翻译任务。另一个值得注意的尝试在[ Wieting 等人,2015 和[Wieting & Gimpel,2017]中提出,其中单词嵌入及其到文档嵌入的映射被联合学习,以最小化释义对之间的余弦相似性(来自PPDB 数据集)。[ Hill 等人,2015 ]训练神经语言模型,将字典定义映射到由那些定义定义的单词的预训练单词嵌入。最后,【 Conneau et al,2017 】在斯坦福自然语言推理任务上训练了各种架构的 NN 编码器(见图 16)。

Figure 16: Generic NLI training scheme

文档相似性的上下文嵌入 上述方法的一个具体情况是由文档相似性驱动的。[ Das 等人,2016 ]展示了通过社区问答的暹罗网络学习到的最大化两个文档之间相似性的文档嵌入(参见图 17)

Figure 17: The SCQA network consists of repeating convolution, max pooling and ReLU layers and a fully connected layer. Weights W1 to W5 are shared between the sub-networks.

同样,[ Nicosia & Moschitti,2017 ]在学习二进制文本相似性的同时,使用暹罗网络产生单词表示,将同一类别中的示例视为相似。(参见图 18)

Figure 18: The architecture of the siamese network from [Nicosia & Moschitti, 2017]. Word embeddings of each sentence are consumed by a stack of 3 Bidirectional GRUs. Both network branches share parameter weights.

跨语言降秩岭回归(Cr5) 【Josifoski 等人,2019】介绍了一种将任何语言编写的文档嵌入到单一的、与语言无关的向量空间的方法。这是通过训练基于岭回归的分类器来完成的,该分类器使用语言特定的词袋特征来预测给定文档所涉及的概念。当将学习的权重矩阵限制为低秩时,作者表明它可以被分解以获得从语言特定的词袋到语言无关的嵌入的期望映射。提供了官方的 Python 实现。

特定任务的监督文档嵌入

产生文档嵌入的普通监督方法使用各种神经网络体系结构,学习将单词向量映射到文档向量的合成算子;这些被传递给受监督的任务,并依赖于类标签,以便通过合成权重反向传播(参见图 19)。

因此,网络的几乎所有隐藏层可以被认为产生输入文档的矢量嵌入,直到该层的网络前缀是从单词矢量到嵌入空间的学习映射。在[ Wieting et al,2015 ]中可以找到基于单词向量和监督学习任务的学习句子向量的不同方法的严格检查。

Figure 19: Neural networks implicitly learn to map word embedding sequences to document embeddings

请注意,虽然所使用的单词嵌入可以是预先生成的,并且是任务不可知的(至少在一定程度上),但是从单词嵌入到文档嵌入的映射是任务特定的。虽然这些对于相关的任务可能是有用的,但这种方法肯定不如无监督的方法健壮和通用,至少在理论上是这样。[ Kiros 等人,2015 年 ]

值得注意的应用包括使用 RNNs 的情感分类[Socher 等人,2013],使用 CNN 的各种文本分类任务[Kalchbrenner 等人,2014] [Kim,2014],以及使用递归卷积神经网络的机器翻译和文本分类任务[Cho 等人,2014a,2014 b][赵等人,2015]。

GPT
拉德福德等人,2018提出了生成式预训练 (GPT)方法 ( 伴随一个 Python 实现),结合无监督和有监督的表示学习,使用瓦斯瓦尼等人 2017 提出的 transformer 模型在无标签语料库上学习一个无监督的语言模型,然后使用有监督的数据分别对其用于每个任务进行微调。[他们后来在 拉德福德等人,2019 ]中展示了 GPT-2 ,专注于支持他们工作的无监督学习部分,再次发布了官方的 Python 实现。

深度语义相似度模型(DSSM) T22【微软研究项目,DSSM 是一种深度神经网络建模技术,用于在连续的语义空间中表示文本串,并对两个文本串之间的语义相似度进行建模(见图 20)。

Figure 20: The architecture of a DSSM neural network

在其他应用中,DSSM 用于开发潜在的语义模型,该模型将不同类型的实体(例如,查询和文档)投影到公共的低维语义空间中,用于各种机器学习任务,例如排序和分类。例如,【黄等,2013 】使用 it 将查询和文档投影到一个公共的低维空间,在该空间中,文档与给定查询的相关性被计算为它们之间的距离。

实现包括 TensorFlow 、 Keras 和两种 PyTorch 变体。

共同学习句子表征

[ Ahmad 等人,2018 ]提出,从多个文本分类任务中联合学习句子表示,并将它们与预先训练的单词级和句子级编码器相结合,会产生对迁移学习有用的健壮句子表示

Figure 21: Jointly learning sentence embeddings using auxiliary tasks

[ 于&姜,2016 ]类似地表明,使用两个辅助任务来帮助诱导句子嵌入对于跨领域的情感分类来说应该是很好的,与情感分类器本身一起共同学习这个句子嵌入(图 21)。

通用句子编码器 在 Cer et al,2018a 和 Cer et al,2018b 中提出,并伴随一个 TensorFlow 实现,该方法实际上包括了两种可能的句子表征学习模型:变换器模型和深度*均网络(DAN) 模型(见图 22)。两者都被设计成允许多任务学习,支持的任务包括(1)类似于无监督学习的任务;(2)用于包含解析的会话数据的会话输入-响应任务;以及(3)用于对监督数据进行训练的分类任务(参见前面的小节)。作者专注于迁移学习任务的实验,并将他们的模型与简单的 CNN 和 DAN 基线进行比较。该方法后来扩展到解决多语言设置。**

transformer 模型直接基于 Vaswani et al 2017 中提出的 transformer 模型,这是第一个完全基于注意力的序列转导模型,用多头自注意力取代了编码器-解码器架构中最常用的递归层(见图 22a)。

该模型使用转换器架构的编码子图来构建句子嵌入。编码器使用注意力来计算句子中单词的上下文感知表示,同时考虑其他单词的顺序和身份。上下文感知单词表示被*均在一起以获得句子级嵌入。

Figure 22: The two models of the Universal Sentence Encoder: (a) Transformer and (b) DAN

相反,在丹模型中,在[ Iyyer et al,2015 ]中,单词和双字母组合的输入嵌入首先被*均在一起,然后通过前馈深度神经网络(DNN)产生句子嵌入(见图 22b)。

GenSen 与通用句子编码器非常相似,GenSen 方法,【 Subramanian 等人,2018 】与官方 Python 实现一起提出,结合多个监督和非监督学习任务来训练基于 RNN w/ GRU 的编码器-解码器模型,从该模型中提取嵌入。四个支持的任务是:(1) 跳过思维向量,(2)神经机器翻译,(3)选区分析,以及(4)自然语言推理(三向分类问题;给定一个前提和一个假设句子,目标是将它们的关系分为蕴涵、矛盾或中性。官方 Python 实现发布。

如何选择使用哪种技术

我在这里没有简单的答案,但这里有一些可能的要点:

  1. *****均单词向量是一个很好的基线,所以一个好主意是通过集中精力生成非常好的单词向量,并且首先简单地*均它们,来开始你对好的文档嵌入的探索。毫无疑问,文档嵌入的大部分功能来自于构建它们所基于的词向量,我认为可以肯定地说,在继续前进之前,该层中有大量的信息需要优化。你可以尝试不同的预训练单词嵌入,探索哪些源域和哪些方法(例如 word2vec vs GloVe vs BERT vs ELMo)可以更好地捕捉你需要的信息类型。然后,通过尝试不同的摘要操作符或其他技巧(像[ 阿罗拉等人,2016 ]中的那些)来稍微扩展这一点可能就足够了。
  2. ****绩效可能是一个关键的考虑因素,尤其是在方法中没有明确的领导者的情况下。在这种情况下,无论是*均字向量的,还是像 sent2vecFastSent 这样的精益方法,都是不错的选择。相比之下,使用 doc2vec 时,每个句子所需的实时向量表示推理可能会被证明在给定应用约束的情况下代价很高。 [SentEval,在 Conneau & Kiela,2018 ]中提出的一个句子表征的评估工具包,就是在这种背景下值得一提的工具。
  3. 考虑学习目标对你的任务的有效性。上面提到的不同的自我监督技术以不同的方式扩展了分布假设,跳跃思维和快速思维分别根据句子和段落在文档中的距离建立了它们之间的强关系。这也许适用于书籍、文章和社交媒体帖子,但可能不适用于其他文本序列,尤其是结构化的文本,因此可能会将您的文档投影到一个对它们不适用的嵌入空间。同样,WME 所依赖的单词对齐方法可能并不适用于每种情况。
  4. ****开源实现非常丰富,因此针对您的任务对不同的方法进行基准测试可能是可行的。
  5. 没有明确的任务负责人。论文经常针对分类、转述和语义相关度任务测试不同的方法。然而,当考虑关于该主题的所有文献时,特别是考虑 2018 年的两个最新基准测试的结果时,上述结论就会出现,第一个由[ Logeswaran & Lee,2018 在介绍他们的快速思考方法时完成,第二个由[ Wu 等人,2018b 作为他们关于字移动器嵌入的论文的一部分完成。

最后的话

就是这样!一如既往,我确信我写的帖子并不完整,所以请随时对以上概述提出更正和补充建议,要么在此评论,要么直接联系我。😃

我还要感谢 Adam Bali 和 Ori Cohen,他们提供了非常有价值的反馈。去看看他们的帖子!

最后,我发现值得一提的是,代码为的论文有致力于文档嵌入的任务,脸书研究公司开源了 [SentEval,这是一个在 Conneau & Kiela,2018 ]中展示的句子表示的评估工具包。

现在坐好,让参考文献淹没你。📕 📗 📘 📙

参考

Agibetov,a .,Blagec,k .,Xu,h .,和 Samwald,M. (2018 年)。用于生物医学句子分类的快速可扩展神经嵌入模型。 BMC 生物信息学19 (1),541。

艾哈迈德,吴伟国,白,徐,彭,张国威(2018)。学习用于文本分类的健壮的、可转移的句子表示。 arXiv 预印本 arXiv:1810.00681

阿罗拉,s .,梁,y .,,马,T. (2016)。一个简单但难以攻克的句子嵌入基线。[ 非官方实施

Bengio,r . Ducharme,Vincent,p .和 Jauvin,C. (2003 年)。一个神经概率语言模型。机器学习研究杂志3(2 月),1137–1155。

B.Broere,(2017)。跳过思维向量的句法属性。蒂尔堡大学硕士论文

Cer,d .,Yang,y .,Kong,S. Y .,Hua,n .,Limtiaco,n .,John,R. S .,和 Sung,Y. H. (2018 年)。通用语句编码器。 arXiv 预印本 arXiv:1803.11175

Cer,d .,Yang,y .,Kong,S. Y .,Hua,n .,Limtiaco,n .,John,R. S .,和 Strope,B. (2018 年 11 月)。英语通用句子编码器。在2018 自然语言处理经验方法会议记录:系统演示(第 169-174 页)。

陈,男(2017)。通过讹误对文档进行有效的矢量表示。 arXiv 预印本 arXiv:1707.02377

陈,秦,彭,杨,陆,钟(2018)。 BioSentVec:为生物医学文本创建句子嵌入。arXiv 预印本 arXiv:1810.09302。

Cho,k .,Van merrinboer,b .,Gulcehre,c .,Bahdanau,d .,Bougares,f .,Schwenk,h .,和 Bengio,Y. (2014 年)。使用用于统计机器翻译的 RNN 编码器-解码器学习短语表示。 arXiv 预印本 arXiv:1406.1078

Cho,k .,Van merrinboer,b .,Bahdanau,d .,和 Bengio,Y. (2014 年)。关于神经机器翻译的性质:编码器-解码器方法。 arXiv 预印本 arXiv:1409.1259

Conneau,a .,Kiela,d .,Schwenk,h .,Barrault,l .,和 Bordes,A. (2017 年)。从自然语言推理数据中监督学习通用句子表示。 arXiv 预印本 arXiv:1705.02364

Conneau,a .,& Kiela,D. (2018 年)。 Senteval:通用语句表示评估工具包。 arXiv 预印本 arXiv:1803.05449

戴,A. M .,Olah,c .,& Le,Q. V. (2015 年)。用段落向量嵌入文档。 arXiv 预印本 arXiv:1507.07998

Das,a .,Yenala,h .,Chinnakotla,m .,& Shrivastava,M. (2016 年 8 月)。我们站在一起:相似问题检索的连体网络。《计算语言学协会第 54 届年会论文集》(第 1 卷:长篇论文)(第 378–387 页)。

甘,钟,蒲,杨,,李,何,林(2016)。使用卷积神经网络的句子表示的无监督学习。 arXiv 预印本 arXiv:1611.07897

甘,钟,蒲,杨,,李,何,林(2016)。使用卷积神经网络学习通用语句表示。arXiv 预印本 arXiv:1611.07897 。

Gupta,p .,Pagliardini,m .,和 Jaggi,M. (2019)。通过解开上下文 n 元语法信息实现更好的单词嵌入。 arXiv 预印本 arXiv:1904.05033

哈里斯,Z. S. (1954)。分配结构。Word,10(2–3),146–162。

f .希尔、k .乔、a .科尔霍宁和 y .本吉奥(2015 年)。通过嵌入字典学习理解短语。计算语言学协会汇刊4 ,17–30。

Hill,f .,Cho,k .,和 Korhonen,A. (2016 年)。从未标记数据中学习句子的分布式表示。 arXiv 预印本 arXiv:1602.03483

黄,张*,何,高,邓,阿塞罗,海克,(2013 年 10 月)。使用点击链接数据学习用于 web 搜索的深度结构化语义模型。在第 22 届 ACM 国际信息会议论文集&知识管理(第 2333–2338 页)。ACM。

Iyyer、v . Manjunatha、j . Boyd-Graber 和 h . daum III(2015 年)。深度无序组合匹敌文本分类的句法方法。在计算语言学协会第 53 届年会暨第 7 届自然语言处理国际联席会议论文集(第 1 卷:长篇论文)(第 1 卷,第 1681-1691 页)。

Josifoski,m .,Paskov,I. S .,Paskov,H. S .,Jaggi,m .,& West,R. (2019,1 月)。作为降秩岭回归的跨语言文档嵌入。第十二届 ACM 网络搜索和数据挖掘国际会议论文集(第 744–752 页)。ACM。

Kalchbrenner,e . Grefenstette 和 Blunsom,P. (2014 年)。用于句子建模的卷积神经网络。 arXiv 预印本 arXiv:1404.2188

茨韦塔纳·肯特、博里索夫和米·德·里基(2016 年)。 Siamese cbow:优化句子表达的单词嵌入。 arXiv 预印本 arXiv:1606.04640

金,尹。"用于句子分类的卷积神经网络." arXiv 预印本 arXiv:1408.5882 (2014)。

Kiros,r .,Zhu,y .,Salakhutdinov,R. R .,Zemel,r .,Urtasun,r .,Torralba,a .,& Fidler,S. (2015 年)。跳过思维向量。在神经信息处理系统的进展(第 3294–3302 页)。

m .库斯纳、孙、n .科尔金和 k .温伯格(2015 年 6 月)。从单词嵌入到文档距离。在机器学习国际会议(第 957–966 页)。

刘,J. H .,,鲍德温,T. (2016)。对 doc2vec 的实证评估,以及对文档嵌入生成的实际见解。 arXiv 预印本 arXiv:1607.05368 。[ 代码 ]

Le,q .,& Mikolov,T. (2014 年 1 月)。句子和文档的分布式表示。在机器学习国际会议(第 1188–1196 页)。

李,t .,&帕克,Y. (2018)。使用基于文档结构的上下文的无监督句子嵌入。

Logeswaran,l .,& Lee,H. (2018 年)。学习句子表征的高效框架。arXiv 预印本 arXiv:1803.02893。

李,b,刘,t,杜,x,张,d,赵,z(2015)。通过预测 n-grams 学习文档嵌入,用于长电影评论的情感分类。 arXiv 预印本 arXiv:1512.08183

刘,杨,&拉帕塔,M. (2018)。学习结构化文本表示。计算语言学协会汇刊,6,63–75。

Mikolov,Chen,k .,Corrado,g .,& Dean,J. (2013 年)。向量空间中单词表示的有效估计。arXiv 预印本 arXiv:1301.3781。

Mikolov,Sutskever,I .,Chen,k .,Corrado,G. S .,& Dean,J. (2013 年)。单词和短语的分布式表示及其组合性。在神经信息处理系统的进展(第 3111–3119 页)。

尼科西亚,m .,& Moschitti,A. (2017 年 8 月)。使用分类信息学习结构语义相似性的上下文嵌入。在第 21 届计算自然语言学习会议论文集(CoNLL 2017) (第 260–270 页)。

Pagliardini,m .,Gupta,p .,和 Jaggi,M. (2017 年)。使用合成 n-gram 特征的句子嵌入的无监督学习。 arXiv 预印本 arXiv:1703.02507

Pennington、r . Socher 和 c . Manning(2014 年 10 月)。 Glove:单词表示的全局向量。在2014 年自然语言处理(EMNLP)经验方法会议记录(第 1532-1543 页)。

a .拉德福德、k .纳拉辛汉、t .萨利曼斯和苏茨基弗(2018 年)。 用无监督学习提高语言理解 。技术报告,OpenAI。

a .、吴、j .、Child、r .、Luan、d .、Amodei、d .、& Sutskever,I. (2019)。语言模型是无人监督的多任务学习者。 OpenAI 博客1 (8)。

Reimers 和 Gurevych,I. (2019)。句子伯特:使用连体伯特网络的句子嵌入。 arXiv 预印本 arXiv:1908.10084

鲁道夫,m .,鲁伊斯,f .,阿塞,s .,,布莱,D. (2017)。分组数据的结构化嵌入模型。在神经信息处理系统的进展(第 251–261 页)。

g .索尔顿和 c .巴克利(1988)。自动文本检索中的术语加权方法。信息处理&管理24 (5),513–523。

Sinoara,R. A .、Camacho-Collados,j .、Rossi,R. G .、Navigli,r .、& Rezende,S. O. (2019)。用于文本分类的知识增强文档嵌入。基于知识的系统163 ,955–971。

Socher,r .、Perelygin,a .、Wu,j .、Chuang,j .、Manning,C. D .、ng,a .、Potts,C. (2013 年 10 月)。情感树库语义合成的递归深度模型。在2013 年自然语言处理经验方法会议记录(第 1631-1642 页)。

Subramanian,s .,Trischler,a .,Bengio,y .,& Pal,C. J. (2018)。通过大规模多任务学习来学习通用分布式句子表示。 arXiv 预印本 arXiv:1804.00079

Sutskever,I .,Vinyals,o .,& Le,Q. V. (2014 年)。用神经网络进行序列对序列学习。在神经信息处理系统的进展(第 3104–3112 页)。

唐,苏,金,洪,方,王,张,&德萨,V. R. (2017)。反思跳跃思维:一种基于邻域的方法。 arXiv 预印本 arXiv:1706.03146

唐,苏,金,洪,方,王,张,&德萨,V. R. (2017)。修剪和改进跳跃思维向量。 arXiv 预印本 arXiv:1706.03148

Thongtan 和 t . phiquethrakul(2019 年 7 月)。基于余弦相似度训练的文档嵌入的情感分类。《计算语言学协会第 57 届会议记录:学生研究研讨会》(第 407-414 页)。

Vaswani,a .、Shazeer,n .、Parmar,n .、Uszkoreit,j .、Jones,l .、Gomez,A. N .、… & Polosukhin,I. (2017)。注意力是你所需要的全部。神经信息处理系统进展(第 5998-6008 页)。

j .维廷、m .班萨尔、k .金佩尔和 k .利维斯库(2015 年)。走向普遍的倒装句嵌入。arXiv 预印本 arXiv:1511.08198。

j .维廷和 k .金佩尔(2017 年)。重新考察用于反对比句子嵌入的循环网络。 arXiv 预印本 arXiv:1705.00364

吴,严,刘怡红,徐,李,李,李(2018)。 D2ke:从距离到内核和嵌入。arXiv 预印本 arXiv:1802.04956 。

Wu,l .,Yen,即,Xu,k .,Xu,f .,Balakrishnan,a .,Chen,P. Y,... & Witbrock,M. J. (2018)。 Word Mover 的嵌入:从 Word2Vec 到文档嵌入。 arXiv 预印本 arXiv:1811.01713

俞军、蒋军(2016 年 11 月)。跨领域情感分类辅助任务学习句子嵌入。在2016 年自然语言处理经验方法会议论文集(第 236–246 页)。

张,杨,陆,张(2019)。用子词信息和网格改进生物医学词嵌入。科学数据6 (1),52。

赵,洪,陆,张,等(2015 年 6 月)。自适应层次句子模型。在第二十四届国际人工智能联合大会

神经网络在不知道的时候知道吗?

原文:https://towardsdatascience.com/does-a-neural-network-know-what-it-doesnt-know-c2b4517896d7?source=collection_archive---------6-----------------------

简要介绍神经网络跳出框框思考的技术

如果你一直在关注数据科学和机器学习,你可能知道,*年来,深度神经网络彻底改变了人工智能和计算机视觉。自从 AlexNet 在 2012 年以较大优势赢得 ImageNet 挑战赛以来,深度神经网络已经征服了许多以前无法解决的任务。神经网络令人惊叹。他们可以学习如何将冬天的风景变成夏天的风景,给马穿上斑马条纹,在基本没有监督的情况下学习单词之间的语义表示,从草图中生成逼真的图像,以及许多令人惊叹的技能。这项技术已经发展到如此程度,以至于基本上每个拥有笔记本电脑的人都可以使用和构建神经网络架构,实现以前无法实现的壮举。许多开源深度学习框架——如 TensorFlow 和 py torch——都可用,将这一令人惊叹的技术带到您触手可及的地方。

每天早上都有几十份新的预印本发布在 arXiv 上,通过不断的技术创新击败最先进的技术。然而,除了提高性能,深度学习研究还有一个同样重要的领域,涉及一系列与理解神经网络如何感知世界一个模型如何概括已知之外的事物相关的问题。在实际应用中,最后一个问题至关重要。考虑以下情况。您正在构建一个根据制造商和型号对汽车进行分类的应用程序。但是,如果发布了一款全新设计的新车型,该怎么办呢?在这种情况下,神经网络在训练期间没有看到这个实例。在这种情况下,正确的答案是什么?

识别未知并不是神经网络的默认功能。这个问题叫做开集识别,有几种方法可以解决这个问题。在这篇文章中,我将对它们做一个简单的概述。

自信错了

在深入细节之前,让我们考虑一个玩具例子。假设我们有一个非常简单的二进制分类问题,为此我们训练一个分类器。决策边界被学习,模型很好地概括了我们的测试数据,所以我们很高兴。

模型部署后,我们开始看到类似这样的情况。

我们还幸福吗?嗯,可能没那么多。从右边的点群来看,我们——人类专家——可能会认为这是一个新的类。也许它不是我们感兴趣的课程,也许它很重要。但是神经网络是如何感知这一点的呢?因为它落在相对远离决策边界的地方,所以新实例被非常有把握地归类为橙色。然而,在这种情况下,我们的分类器是错误的。

为了有效地检测这些情况,需要采用额外的方法。本质上,网络只有有限的工具来识别新的类:它有一个特征变换,一个 Softmax 函数和一个只有两个类的承诺。我们如何利用这些来解决我们的问题?一种简单的方法是设定 Softmax 概率的阈值:如果预测类别的概率低于一个给定的阈值,比如 0.5,我们就拒绝这个未知的项目。正如我们之前看到的,这在许多情况下可能不起作用,因为神经网络可能会给出高置信度的错误预测。

查看上下文:OpenMax 方法

我们的网络提供的预测概率可能是错误的,但看看这些点的分布,很明显可能存在一个新的类别。让我们来看看激活向量!例如,这是上面模型中激活分数的分布情况。

蓝色是我们在培训中看到的数据,红色是来自部署的奇怪的新实例。通过激活向量值的分布,我们可以判断一个新的数据点在知识方面是否新颖。这是 OpenMax 方法的基本原理,由 Abhijit Bendale 和 Terrance E. Boult 在他们的 CVPR16 论文中开发,致力于开放集深度网络。在他们的实验中,他们使用了一个 ImageNet 预训练模型,给它输入真实的、愚弄的和开放的图像(即来自训练中看不到的班级的图像);然后检查了激活向量模式。他们的基本发现是,这些模式可以用来检测神经网络不知道的

Activation patterns of the Softmax layer. Source: Abhijit Bendale and Terrance E. Boult, Towards Open Set Deep Networks

在左侧,您可以看到使用不同图像的已训练模型的激活向量的热图。他们发现异常值的方法如下。

1)对于每个类别,使用该类别的正确分类的训练示例,将威布尔分布拟合到激活分数。
2)给激活向量添加一个新的“未知”类。
3)使用威布尔分布的参数转换激活分数。这些被称为 OpenMax 分数。
4)对于新图像,基于 OpenMax 分数,拒绝为未知或接受为已知。

The OpenMax algorithm. Source: Abhijit Bendale and Terrance E. Boult, Towards Open Set Deep Networks

与基于阈值 Softmax 概率的朴素方法相比,使用这种方法,他们能够提高开集检测的准确性。

OpenMax performance. Source: Abhijit Bendale and Terrance E. Boult, Towards Open Set Deep Networks

因此,OpenMax 基本上是神经网络的替代最终层,取代了优秀的旧 Softmax。但是,这一层是不可训练的!因此,它不会让你的神经网络在开集识别方面更聪明,它只是以更聪明的方式使用它的预测。这似乎是一个错失的机会。有没有办法训练一个网络来识别未知?

着眼于已学习的表示:嵌入空间中的开集识别

让我们深入了解神经网络是如何看待数据的!为了简单起见,让我们看看 LeNet-5,这是字符识别的经典架构,由 Yann LeCun 及其同事在改变游戏的论文基于梯度的学习应用于文档识别中提出。

The LeNet architecture. Source: Yann LeCun et al., Gradient-Based Learning Applied to Document Recognition

如您所见,网络的输入是原始数据本身。这可以被认为是一个真正高维空间中的向量,在我们的例子中是 32 x 32。如果你能在这个高维空间中看到与我们的训练数据集相对应的所有向量,你可能会认为与每个类相对应的子集是相当混乱的。基于这种表示,没有简单的方法来区分类。这正是神经网络最初看到的。然而,对于每一层,它都连续地将数据转换为越来越有形的表示,最终输出一个非常简单的表示:低维单纯形(三角形在多维中的推广),每个顶点对应一个类。

就我们的目的而言,最有趣的表示是上一个之前的表示。最后一种表示——输出——有点不自然,因为它被限制在一个维度等于类数量的空间中。正如我们之前看到的,在这个表述中没有未知的空间。但是,这对于倒数第二层的输出来说就大不一样了!这通常称为嵌入,嵌入向量代表数据的高级特征表示。在这个嵌入空间中,理想情况下,每个类都应该是一个独立的集群,与其他类分开。在这个空间里,你会把未知数放在哪里?好吧,如果每个类确实由一个簇表示,那么一个开集例子应该远离任何已知的簇。

沿着这个思路,Hassen 和 Chan 在他们的论文(学习基于神经网络的开集识别表示)中开发了一种方法,旨在训练网络来实现这一点。它们引入了一种新的损耗,将集群彼此推得更远,并将集群本身挤压在一起:

ii-loss.

ii-loss 可以附加到嵌入层,产生以下设置。

ii-loss setups. Source: Mehadi Hassen and Philip K. Chan, Learning a Neural-network-based Representation for Open Set Recognition

嵌入空间中的开集识别原则上很简单:只需将落在聚类之外的点分类为未知。这种方法是对 OpenMax 的改进,但是它仍然错过了非常重要的一点:它没有明确地教会网络识别未知。这样我们会获得更好的开集识别性能吗?

教神经网络知道它不知道的东西(真的)

我们在第一个例子中已经看到,不确定性不是识别开集例子的好方法:网络可以以非常高的置信度将未知的例子分类为已知类的成员。然而,在这个例子中,我们在训练期间没有向网络显示任何未知实例。按照公开的术语,套用美国前国防部长唐纳德·拉姆斯菲尔德的话:有已知的未知未知的未知。前一个类由培训期间可用的实例组成,尽管不是我们感兴趣的。如果我们用这些来训练未知的网络,并显示这些是你应该不确定的例子,会怎么样?

这是 Dhamija 等人在他们最*的论文中提出的想法,他们引入了两个新的损失函数来将未知的例子从已知的例子中分离出来:熵开集损失和物圈损失。它们是如何工作的?

作者的第一个观察结果是,通过为专门在 MNIST 训练的网络可视化 MNIST 数字和梵文手写字符的特征表示,未知的例子往往在某种程度上围绕原点聚集。

Softmax activations of MNIST digits and Devanagari handwritten characters of a network trained exclusively on MNIST. Colored dots are MNIST classes, black dots are unknowns. Below are histograms of Softmax activation values for both classes. Source: Akshay Raj Dhamija et al, Reducing Network Agnostophobia

为了利用这一点,他们引入了一个新的损失,称为熵开集损失,它将未知实例的 Softmax 分数驱动到均匀的概率分布。

Entropic Open Set loss. On the top: loss when instance known. On the bottom: loss when instance is unknown. Source: Akshay Raj Dhamija et al, Reducing Network Agnostophobia

让我们停下来研究一下这个问题。对于具有已知类别(定义的顶部)的样本,这只是好的旧的交叉熵损失。当 Softmax 分数将概率 1 赋予真实类别时,交叉熵被最小化。然而,在定义的底部,我们看到了一些有趣的东西。这是负对数似然向量的*均值,当 Softmax 向量中的所有概率相等时,该值最小!实际上,这个损失告诉网络“这个实例是未知的,你现在应该是不确定的”

所以,让我们假设我们已经用熵开集损失代替了我们通常的交叉熵损失。我们的要素制图表达会发生什么情况?事实证明,这种损失有一种特殊的影响:它使未知样本的范数下降!

Feature magnitudes for networks trained with and without Entropic Open Set loss. Source: Akshay Raj Dhamija et al, Reducing Network Agnostophobia

我们能增强这种效果吗?熵开集损失并不直接影响特征量级:未知样本接*最优的分数仍然可以有很大的量级,只要它们的激活分数对于每个类都是相似的。为了实现这一点,作者为这个损失函数引入了一个新术语。他们把这种新的损失统称为大气层损失。

Objectosphere loss. Source: Akshay Raj Dhamija et al, Reducing Network Agnostophobia

如我们所见,第二项迫使已知类中的样本具有较大幅度(顶行),而迫使未知样本具有较小幅度(底行)。这些术语共同实现了开集识别任务的相当大的改进。

Correct Classification Rates at different False Positive Ratios. Source: Akshay Raj Dhamija et al, Reducing Network Agnostophobia

开集识别的状态

正如我们之前看到的,开集识别在过去的几年里取得了很大的进步。然而,我们离一个强大的通用解决方案还很远。尽管它在实际应用中很重要,但却是一个被忽视的话题。然而,对于任何给定的问题,甚至不可能集合一个训练集来覆盖所有可能的情况并包括所有相关的知识。在许多情况下,领域专家甚至不知道这一点。想想细胞生物学家,他们使用显微图像来分析细胞表型,或许还能发现新的表型。如果一个表现型真的未知,你怎么能提前推理出来呢?

在我个人看来,关于深度学习的真正有趣的问题始于我们研究神经网络如何超越已知进行概括。对人类来说,这是智力的本质。想一想:随着你不断积累知识和个人成长,最能推动你前进的一句话是什么?

“我不知道。”

参考文献。

[1] A. Bendale 和 T. E. Boult,迈向开集深度网络 (2016),IEEE 计算机视觉和模式识别会议(CVPR),2016,第 1563-1572 页
2 M. Hassen 和 P. K. Chan,学习基于神经网络的开集识别表示法,(2018) arXiv 预印本
[3] A. R. Dhamija 等人,【T8

如果你喜欢把机器学习概念拆开,理解是什么让它们运转,我们有很多共同点。看看我的博客,我经常在那里发表这样的技术文章!

大数据是否承诺在未来给每个人带来巨大的好处?

原文:https://towardsdatascience.com/does-big-data-promise-big-benefits-to-everyone-in-the-future-ab1186f9f6b1?source=collection_archive---------13-----------------------

大数据对话

以下是未来 12 个月大数据的预期

可以毫不夸张地说,过去大多数企业的运营就像一个新手用不同材料制成的子弹瞄准目标,希望一些(如果不是全部)能坚持下来。

不管是好是坏,自动化时代带来了智能机器,它们正在越来越多的领域挑战人类的优势。大数据、机器学习和自动化现在正不经意地帮助企业每天做出高效、更智能的决策。

数据驱动的经济

大数据正在对全球经济产生重大影响。到 2021 年,全球大数据市场预计将增长至* 670 亿美元。根据 Andreessen Horowitz 的说法,世界上 90%的数据都是在过去的二十年里产生的。如今,每天都有 2.5 万亿字节的数据被创建出来,而且这一速度在未来几年还会加快。事实证明,学习如何理解这些海量数据对各种规模的企业都大有裨益。欢迎来到数据驱动的经济,在这个经济中,所有伟大的商业决策都是由数据驱动的。

对企业的好处

随着数据以如此快的速度增长,企业主适应数字化转型变得前所未有的重要。这是每个企业家在未来几年必须了解的事情,以便他们能够找到充分利用大数据潜力的方法,并最大限度地提高生产力和投资回报。

大数据可以为企业带来巨大好处的几种方式有:

  • 快速获得更准确的答案

对于一个企业家来说,一个简单的问题,比如“谁是我的 10 个最好的客户?”可能需要几个月的研究才能找到答案。一个业务团队可能需要 60 天或更长时间来分析一切,以得出此类问题的最佳答案,即使这样,它也可能是非常错误的。但是,在强大的大数据商业智能解决方案的帮助下,回答这些问题只需几个小时。大数据的最大好处之一是能够更有力地提问和回答问题。整个回答复杂问题的过程可以从几个月缩短到几天甚至几分钟。

  • 更好地了解消费者并预测他们的行为

"到 2025 年,将有超过 150 兆字节(150 万亿千兆字节)的数据需要分析."— 福布斯

市场研究是受益于大数据革命的一个领域。对大型数据集和尖端云技术的可访问性使公司能够在短短几分钟内收集和分析超过一百万条信息。预测分析和深度学习的进步进一步简化了这一过程,使企业能够提高其营销战略的成功率。然而,许多消费者数据是无用的,因此关键是通过研究转化的客户类型和迫使他们进行购买的行为因素来收集正确的数据。

通过显示消费者购物和与企业互动的模式,数据还可用于预测消费者行为。通过确定客户需要什么以及何时需要,可以利用这一点为客户提供相关的解决方案。这种大数据应用最常被引用的例子可能是塔吉特如何在一名少女的父亲怀孕之前发现她怀孕了。

  • 探索趋势

谷歌是世界上最大的数据农业公司之一,它提供谷歌趋势,允许用户根据术语或关键字搜索热门趋势。有了这样的工具,公司可以很容易地找到合适的模式,这有助于他们构建未来的产品。

  • 目标广告

“经过多年的谨慎热情,营销和广告技术部门现在能够大规模接受大数据。”安德鲁奖章

企业在投放广告中损失了数百万美元,结果证明是灾难性的。当人们很少或根本不关注研究阶段时,就会发生这种情况。大数据可以让公司在开展新活动之前获得准确的客户洞察,从而节省人力资源。这一过程是通过广告商和营销人员使用的类似方法进行的,包括监控客户的在线活动、销售点交易和客户趋势的变化。结果,最终的活动变得更有针对性,只针对正确的受众。

  • 风险管理——用准确的数据增强信心

不管是哪个行业,风险管理计划对任何企业来说都是一项重要的投资。能够预见潜在的风险并在风险发生前降低风险对于企业保持成功至关重要。事实证明,大数据分析在开发卓越的风险管理解决方案方面发挥了重要作用。这些解决方案允许企业对他们经常面临的风险进行量化和建模,然后使他们能够做出更好的决策,以创建更智能的风险缓解策略。

对消费者的好处

如今,大数据完全是为了增强客户体验。从向用户推荐他们想看的节目到建议购买的产品,数据正在让公司在你能想到的每个领域赢得人心。事实上,消费者现在 期望 品牌监控他们的在线活动,以便他们能得到更好的服务。

Big data is watching — for good!

以下是大数据向未来消费者承诺的更多好处:

  • 更智能的个性化购物体验

智能聊天机器人、虚拟造型师和类似的产品推荐是大数据革命带来的众多创新中的几个。欢迎来到客户时代,在这个时代,各公司都在努力通过数据的力量为客户提供卓越的客户体验,从而让客户满意。

  • 降低成本,获得更好的交易

利用数据进行有针对性的营销,不仅能为客户提供相关优惠,还能帮助企业降低产品和服务的价格。向 20 万目标明确的潜在客户发送电子邮件的成本与向整个城市进行营销的成本相比,可能会对公司提供的产品和服务的总成本产生重大影响。因此,对于各种规模的企业来说,数据都是降低成本的重要工具。

  • 通过消费者偏好的渠道改善沟通

未来,大数据和自动化承诺客户可以在一天中的任何时间,通过他们首选的渠道,在他们首选的设备上,更快地响应他们的查询。

数据驱动的世界

这仅仅是大数据能够为世界带来什么的开始。数据永不停息,每一秒钟都在继续增长,随之而来的是数据造福人类的可能性越来越多。随着技术的不断进步,越来越多的组织越来越容易获得数据。因此,这些组织有责任确保信息技术在未来以最佳方式为消费者服务。

差异中的差异方法实践指南

原文:https://towardsdatascience.com/does-minimum-wage-decrease-employment-a-difference-in-differences-approach-cb208ed07327?source=collection_archive---------11-----------------------

实验和因果推理

卡德和克鲁格论文的翻版:“工资上升,就业率下降?”

Photo by Dean Nahum on Unsplash

执行摘要

  • 在完全竞争的市场中,传统经济理论预测最低工资的增加会导致失业率上升。
  • 横断面研究提供了相互矛盾的证据,但不是因果关系。
  • 卡德和克鲁格采用了一种 DID 方法,发现工资增长会带来更高的就业率。

Photo by Alexander Mils on Unsplash

前言

在这篇文章中,我将复制 Card 和 Krueger 的论文,一步一步地解释,并补充关于准实验设计的定义、假设、R 代码和潜在结果框架解释的附加信息。

什么是准实验?

准实验设计是一种没有真正随机化过程的实验设计。由于缺乏随机分配,治疗组和对照组在干预前是不相等的。因此,这两组之间的任何差异都可能是由先前存在的差异造成的。

这种准设计受到了政策分析师、医疗保健提供商和直接面向消费者的公司(特别是网飞和 Airbnb)的欢迎。

为什么是准实验设计?

在其他帖子中,我解释了实验研究的好处,以及如果可能的话,为什么它们应该是因果推断的首选。那么,我们为什么不一直进行实验呢?

很棒的问题!一个简单的答案是,实验设计对某些类型的问题并不适用。例如,将人们随机分配到可能损害他们健康的危险环境(如吸烟)是不道德的。

在政策领域,我们不能随意指定加州而不是纽约获得新的税收优惠。

此外,在实验设计中,实验组和对照组之间存在溢出效应。网飞没有对某些类型的问题进行 A/B 测试,而是依靠准实验性的解决方案(在本文中,网飞解释了为什么 A/B 测试并不总是可行)。

在这种情况下,当完全成熟的实验研究不可行时,准设计就派上了用场。

“准实验的结果不会像 A/B 那样精确,但我们渴望对因果关系进行定向解读。”

— — 科林·麦克法兰 ,迈克尔·波,朱莉娅·格里克@ 网飞

Photo by Christian Regg on Unsplash

背景

1989 年 11 月签署成为法律的一项法案将联邦最低工资从每小时 3.35 美元提高到 3.8 美元,于 1990 年 4 月 1 日生效,并于 1992 年 4 月 1 日从每小时 4.25 美元进一步提高到 5.05 美元。新泽西州经历了工资上涨,但宾夕法尼亚州没有。戴维和克鲁格在涨价前后进行了两轮调查。

一个简短的时间表可能有所帮助:

  1. 1992 年 2 月和 3 月:第一轮调查
  2. 1992 年 4 月:新泽西州最低工资从 4.25 加元提高到 5.05 加元
  3. 1992 年 11 月和 12 月:后续调查

以下是我们运行准设计的原因。#1 新泽西和宾夕法尼亚在很多方面没有可比性。#2 立法过程不是随机的。

然而,我们可以根据 DID 方法确定工资增长对失业率的因果影响。

准实验设计不需要同等组。

潜在成果框架 分析研究

这是注释。设 D 代表是否接受治疗,T 代表时间,I 代表研究对象数量。

Di = 1:新泽西接受待遇(最低工资增加)

Di = 0:宾夕法尼亚州不接受治疗

T=1:工资增长后(1992 年 11 月和 12 月)

T=0:工资增长前(1992 年 2 月和 3 月)

y:结果变量(失业率)

I made this

Based on the poor handwriting, it’s my credits.

有一个潜在的问题。我们不知道对照组(宾夕法尼亚州)如果接受治疗会有什么表现(missing E[Y0i(1)| D = 1】)。

我们可以用 DID 的方法解决这个问题:

****ATTE[Y1(1)—Y(0(1)| D = 1]=

{ E[Y(1)| D = 1]—E[Y(1)| D = 0]}—{ E[Y(0)| D = 1]—E[Y(0)| D = 0],假设*行趋势。

*行趋势假设意味着如果没有治疗,治疗组和对照组之间的差异将保持不变。在这种情况下,如果没有工资增长法,新泽西州和宾夕法尼亚州的就业率之间的差异将是相同的。

R 分析:

**# Credits to Jonathan Mummolo**d <- read.csv(“wage_data.csv”,convert.factors = FALSE)
head(d[, c(“ID”, “nj”, “postperiod”, “emptot”)])with(d, 
 (
 mean(emptot[nj == 1 & postperiod == 1], na.rm = TRUE) — mean(emptot[nj == 1 & postperiod == 0], na.rm = TRUE) 
 )-
 (mean(emptot[nj == 0 & postperiod == 1], na.rm = TRUE) — mean(emptot[nj == 0 & postperiod == 0], na.rm = TRUE)
 )
)ols <- lm(emptot ~ postperiod * nj, data = d)
coeftest(ols)

为了控制地区和时间差异,我们可以建立一个固定效应回归模型,该模型具有单位和期间固定效应。

#A set of estimators and tests for panel data econometrics
library(plm)
library(lmtest)
d$Dit <- d$nj * d$postperiod
d <- plm.data(d, indexes = c("ID", "postperiod"))
did.reg <- plm(emptot ~ postperiod + Dit, data = d,model = "within")
coeftest(did.reg, vcov=function(x)
#Heteroskedasticity-Consistent Covariance Matrix Estimation
vcovHC(x, cluster="group", type="HC1"))

****

The original paper, Table 3

在将其与原始表进行比较后,我们成功地复制了结果!

原文是这里的。

复制数据集在这里是。警告:这是原始数据,我们需要处理它进行分析。

Medium 最*进化出了自己的 作家伙伴计划 ,支持像我这样的普通作家。如果你还不是订户,通过下面的链接注册,我会收到一部分会员费。

** [## 阅读叶雷华博士研究员(以及其他成千上万的媒体作家)的每一个故事

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

leihua-ye.medium.com](https://leihua-ye.medium.com/membership)**

喜欢读这本书吗?

请在 LinkedIn 和 Youtube 上找到我。

还有,看看我其他关于人工智能和机器学习的帖子。

薪酬会影响科技行业的忠诚度吗?简单数据可视化研究。

原文:https://towardsdatascience.com/does-pay-impact-loyalty-in-tech-a-study-in-simple-data-visualization-f15e93659a6d?source=collection_archive---------28-----------------------

旧金山的技术领域以敏捷著称:公司转向,产品更新,员工跳槽。为一家公司工作,当员工达到一年或两年的纪念日时,该公司会庆祝他们,这种情况并不少见。这种情况不仅发生在初创公司(通常只有几年历史),也发生在大型企业。由于劳动力市场的泡沫化,员工们已经习惯了每周(如果不是每天的话)来自脸书招聘公司、合同招聘公司和代表他们投资的风投公司的连珠炮。

看来招聘人员才是这个行业的真正赢家:因为挖人而获得奖励,但很少因为留住员工而获得奖励。但是肯定有一些公司已经想出了如何留住员工,从而停止无休止的 LinkedIn 挖掘、电话筛选、杠杆审查循环,这些循环会消耗团队的时间。

带着这样的想法,我很兴奋地偶然发现了去年围绕这个问题发布的调查数据。Blind 是一款应用程序,时尚、大型科技公司的员工可以匿名参与讨论话题。在本次调查中,Blind 要求用户二对两项陈述做出回应:

  1. 我得到了公*的补偿
  2. 我对换工作/换公司感兴趣

然后,他们获取这些用户的雇主,并提供汇总结果。请记住,这是对非代表性员工样本的自愿调查数据,发现公司之间的差异仍然很有意思。Blind 将此描绘成一个堆积条形图。

虽然这张图有它的优势,你可以很快找到一家公司,并看到它在哪里,但我发现它(以及后来的出版物: BI 、 Inc 、 Dice 、 SFGate )在传达任何真正的洞察力方面令人失望。充其量,这是一张记分卡,告诉我们一家公司最终在哪里,但没有告诉我们为什么他们可能会在那里。

所以我深入研究了一下数据。首先,公司回应的分布讲述了一个有趣的故事。

在左侧,我绘制了一个直方图,显示了公司数量以及员工/受访者对“薪酬合理”这一说法的认同程度。大多数公司位于 40-70%的范围内,中间值正好是 50%。这意味着,大多数公司的“典型”感觉大致相当:员工(作为一个群体)没有被利用的感觉,也没有沉浸在薪资满足感中。

右边是“换公司”的柱状图。在这里,图表严重向右移动,中间值接* 70%。很少有公司的价值低于 50%。这意味着几乎所有 T2 主要科技公司的大多数员工都在考虑离开 T3!

但是这些有联系吗?换句话说,付更多的钱会让人呆得更久吗?虽然这里真正的黄金标准是进行一项受控实验(随机挑选一半的员工,提高他们的工资,监控留用情况),但我们仍然可以从盲目的数据中梳理出一些要点。

盲目地试图用一个双条形图来解决这个问题,该图筛选出了 30 多家公司中的 10 家,但我发现它太忙了,没有时间吸取任何教训。

通过将数据转换成散点图,每个公司用“公*补偿”协议(x-轴)与“考虑改变”(y-轴)来绘制,一些趋势开始出现。您可以将鼠标悬停在各个点上来查看公司。

很快你就能看到一个强烈的下降趋势,员工感觉收入高的公司很少有员工考虑离职。相关性在-0.59 处相当强。

因此,薪酬有着强烈的影响,这可能对我们大多数人来说并不奇怪。在网飞,几乎每个人的工资都很高(88%的人同意),很少有人有兴趣离开(27%),而在另一端,惠普企业(HPE)有工资问题(13%)和挽留问题(91%)。

但我会走得更远:你必须支付高薪来留住你的团队。这些调查数据显示,没有一家公司找到了留住人才的廉价良方;尽管所有的工作都是关于使命宣言,健康计划和战利品。一般来说,每个有薪酬差距的公司都有很高的变化考虑

该图还显示,感觉收入丰厚的员工(图的右侧)仍然有很高的辞职率。在极端情况下,NerdWallet 受访者是对薪酬最满意的人之一(78%的人同意“我得到了合理的补偿”),但也是最不想留下来的人之一(90%的人同意“我想换工作/公司”)。Intuit 和 LinkedIn 的薪酬协议相似(分别为 61%和 63%),但 Intuit 的员工对离职的兴趣是 LinkedIn 的两倍(80%,LinkedIn 的 40%!).光靠高薪是不够的!

让你的公司在稳固的薪酬满意度上似乎是一个必要的,但不是充分的,解决员工保留的策略。在 SF tech 的旋转门文化中,它应该被认为是桌面上的标杆。我会从检查你的员工的脉搏开始:如果大多数人觉得他们早就该加薪了,那就等着看他们定期离开吧。

一些必须的脚注:

感谢盲人做调查。这是一个伟大的公关举措,我从来没有听说过这家公司,直到我听的一个播客选择了这个调查作为一个故事。

但是没有一个内容营销驱动的调查是完美的。数据现在已经有一年多了(所以我猜脸书已经看到了“对改变感兴趣”的增加……),并且对盲人用户有反应偏差和选择偏差。我可以想象一个系统性的问题,即正在考虑换工作的员工与盲人接触,以更多地了解其他公司。最重要的是,我使用的数字是我对盲人图表的手动解释。这将是很酷的,看看如何比较,比如说,玻璃门审查和工资数据。

最后,我将我的数据和 python 分析笔记本存储在 github 中,如果有人有兴趣的话。

你的产品有用吗?

原文:https://towardsdatascience.com/does-your-product-actually-work-5fe8134c5144?source=collection_archive---------25-----------------------

随机对照试验、不完全依从性和反事实时间机器

我们开发软件来解决人类的问题。但是人类的问题可能是混乱的,有时并不十分清楚我们是否真的解决了它们。

Snapchat 可能会说,如果他们看到 50%的普通用户检查他们的新狗过滤器,他们就成功了,脸书可以说,他们已经打破了他们的增长里程碑,显示他们已经实现了超过 23 亿的月活跃用户。

但是,当你的应用程序被设计成帮助会员应对焦虑时,你的接受标准是什么?当你的软件被构建来培养正念时,你能监控什么标准?

或者,以我的公司为例——甚至——我们如何判断我们是否对会员的财务健康产生了影响?

我们与我们的移动应用高度互动,我们已经向我们的会员发送了价值超过 10 亿美元的工资,我们还自动为他们在雨天账户中节省了数百万美元。这些都是值得庆祝的事情。

但这还不够。

我们更直接关心的是,我们的产品是否能在物质上改善我们会员的生活。作为一名致力于了解我们功效的数据科学家,这基本上是我所关心的全部。

这是从度量优化到更像科学实验的地方。我需要了解的是我们的*均治疗效果——也就是我们在用户生活中造成影响的预期值。

为了解释我如何做到这一点,我将深入一种因果分析,这种分析被朱迪亚·珀尔在他的奇幻书和本文(与亚历山大·巴尔克合著)中分解。

如果你是数据驱动型组织的一员,在这个组织中跟踪应用程序的使用模式相对容易,那么这种分析与执行涉及产品对用户影响的实验高度相关。即便如此,我还没有看到甚至是最学术性的科技研究使用我将要深入探讨的那种思维。

快速警告:深度潜水将涉及一点科学方法、许多概率论、一点 Python 和一点线性编程。你不需要成为任何一个主题的专家来理解我将要讨论的内容,但是这几乎肯定需要一些时间,努力,也许还需要一些背景阅读。

不过,我向你保证,这很酷,值得一试。

让我们从科学复习开始:随机对照试验。

随机对照试验

相关性不是因果关系——我们感兴趣的是因果关系。我们希望成员的生活得到改善。不过,在我开始宣扬“因果关系”之前,先定义一下它是有用的。的反事实定义是我个人认为最清楚的一个:

事件 A“引发”了事件 B,当且仅当,我们把事件 A 从历史中删除,事件 B 就不会发生。

成为一个原因就是成为引发连锁反应的多米诺骨牌,成为引爆炸丨药的导火索。如果你消除了这个原因,无论发生什么都不再发生了。

为了研究因果关系,我们可以去除我们认为是因果关系的东西,看看它的影响是否仍然存在,其他一切都是一样的。这就是“受控试验”试图做的事情。

我们自然一直在做对照试验。想想你上一次尝试安装一盏新灯,却发现它不起作用。你是如何着手解决这个问题的?

你可能对哪里出了问题有一些想法。灯泡可能已经烧坏了。或者你插的插座是个哑弹。

让我们取其中的一个想法,正式称之为我们的假设。

假设:插座不起作用,这意味着没有电力可以到达灯泡,它不能点亮。

我们如何检验这个假设?嗯,我们有一个试验,我们尝试了当前的插座,插座 a。这是我们的治疗试验——我们用我们认为导致我们最终黑暗和沉闷状态的输入来治疗我们的系统。

现在我们需要一个控制试验——我们把插座 A 换成一个我们知道有效的插座:插座 B,它已经忠实地为我们的手机充电几个月了。系统中的一切都保持不变,除了插座。

在我们进行这个试验之前,让我们尽可能正式地设计这个实验。我们寻找的是插座 A 对房间照明的*均处理效果(ATE)。

Treatment Effect = The probability of a non-functional lamp given that we use Outlet A, minus the probability of a non-functional lamp given that we use Outlet B.

我们已经知道 P(黑暗|出口 A) = 1 。如果当我们将插座 A 与插座 B 交换时,房间仍然是黑暗的,那么 P(黑暗|插座 B) = 1 也是如此,因此 ATE = 0 。这意味着插座是我们问题的 0%原因。

但是,如果我们把灯插到插座 B 上,灯瞬间就亮了,那么 P(暗度|插座 B) = 0 ,我们的 ATE = 1。或者换句话说,插座 A 100%是我们问题的原因!

所以,让我们把灯插到插座 b 上。砰:

…Surprise! We were talking about a lava lamp this whole time. Now the living room of your imagination is just a tiny bit more whimsical. Source: Warisan Lighting

灯亮了;出口 A 是黑暗的原因。

问题解决了。

就像我说的,我们一直在做这种事情。对使用我们软件的人进行对照试验的复杂之处在于,其中涉及到一个特别棘手的变量:人。

虽然家用电器(通常)是完全确定的,但人却不是。没有一个人是相同的,他们使用你的产品的方式和对它的反应经常会让你吃惊。他们中的一些人会下载它并忘记它,一些人会每天登录。你的一些成员可能会从这个产品中得到帮助,但是——这是一个可怕但必要的想法——他们中的许多人可能会受到伤害。

当你的实验的一个输入变量如此多变时,你如何对你的产品进行受控试验?

这就是统计学介入的地方。我们不能再像在确定性系统中那样做单一的对照试验和单一的治疗试验。我们需要做数百次试验。成千上万。

每次试验将针对不同的人。重要的是,将一个人分配到控制或治疗条件的标准是完全随机的。这确保了在每种情况下的实验参与者的样本在总体上或多或少是相同的:他们将有来自每种性别、身高、收入水*、性格等的相同比例的人。不在审查范围内的因素的影响应该会互相抵消。

到目前为止,我们已经把相当多的片段放在一起:我们控制着一个单一的解释变量,并且随机化以减轻我们没有研究的一堆外生变量的影响。我们现在有了一个随机对照试验(T12)和一个研究什么导致什么的黄金标准(T13)。

但是故事还没有结束。我们可以将人分配到治疗状态(被分配使用你的产品的人)和控制状态(不使用你的产品的人),但是谁敢说你的参与者真的会遵守你的分配呢?

谁能说你的治疗组的参与者真的会下载并使用你的软件,或者你的对照组的人不会在应用商店找到它并试用它?

当你不知道参与者是否真的接受了你的治疗时,你不能进行因果归因。所以。我们如何做到这一点?

处理不完全合规

让我们回顾一下我们在 RCT 的设置。

  1. 我们将参与者随机分配到治疗组或对照组。
  2. 他们可能决定服从他们的任务,这取决于一些不可观察的因素。
  3. 他们会以某种方式对你的产品作出反应(或缺乏产品),这取决于他们是否接受了治疗,以及一些不可观察的因素。

我们可以描述这些事件如何与贝叶斯网络相互作用,如下所述。

Bayesian Network description of an RCT: This diagram describes conditional dependences of the events we’d expect to see. Z is completely independent of anything else, since it’s done via random coin-flip. U is a catch-all variable for the whole universe of unknowns that affect X and Y, and is also conditionally independent from other variables. X would be conditionally dependent on Z and U. Y would be conditionally dependent on X and U.

我们将使用 ZXYU 符号来简写它们在该图中代表的随机变量。例如,当我们提到 Y 时,我们谈论的是参与者可能意识到的结果变量(或者是好的结果,或者是坏的结果)。使用小写字母, y ,表示随机变量的实际实现(例如 Good )。

这种图表只是一种方便的方式来描述我们可能如何计算一些联合的概率 ZXYU 配置(例如,“ Z = 治疗X = Y = 用象征性的术语来说,这个图表是在说:

根据图表/表达式,你或许可以说出一些直观的东西:

  1. 知道 X = x 改变了 Y 等于特定 y 的概率。
  2. 知道 Z = z 和/或 U = u 改变 X 为特定 x 的概率。
  3. 知道 Z = z 不会给我任何关于 uU 可能是什么的额外信息。

我们所做的就是在这里捕获条件依赖。

然而,我们的最终目标是能够计算出*均治疗效果,即:

i.e: The probability of having a good outcome given that we force a participant to take the treatment, vs. the probability of a good outcome given that we force them not to take the treatment. This difference is the ‘goodness’ directly attributable to our intervention

注意那个 do() 操作符,那里。也就是说,我们想知道当我们迫使 X 进入特定状态时,好结果的概率是多少——而不仅仅是被动地观察它。

问题是,在 RCT,我们从来没有强迫任何人做任何事情。我们让参与者接触到产品,然后他们想做什么就做什么。我们做的就是被动观察!

有鉴于此,一个幼稚的方法可能是宣布:

但这是一个致命的错误。

我们必须记住,不同的潜在因素U、表示,驱动着参与者接受治疗和不接受治疗的案例。同样的情况很可能会影响他们获得良好结果的可能性,这将会混淆我们对治疗效果的描述。

例如,在 Even 的案例中,选择定期使用该应用程序的成员可能天生就比那些不经常使用的成员更富裕(反之亦然)。在这种情况下,我们会看到一个高比率,但这并不能说明它对人的影响——它只是选择偏差的虚假结果!

我们想要的是能够比较给予治疗的良好结果的机会与不治疗的良好结果的机会,其中所有其他因素都是固定的看起来更像这样:

Here we’re making sure that we’re only capturing the difference in P(Y = Good) between the treated (X = True) and untreated (X = False) groups given the same unobserved condition (the same u), for all possible unobserved conditions (all uU)

好吧,我们有点进展了。我们有一个如何将实验观察转化为 ATE 的表达式…但是这个表达式是没有用的,除非我们找到某种方法来理解什么样的 u 态是 U 的元素,这样我们就可以正确地控制这些态。

但是 U 是这个不可思议的随机变量,它应该捕捉影响人们为什么决定尝试一种产品以及他们可能如何反应的整个未观察到的因素。

你怎么能开始分解它呢?

让我们把问题尽可能简化。我们不需要模拟人们的神经生理学,或者天气,或者股票市场,或者任何能够影响日常决策的无限因素。

让我们考虑一下哪些事情会影响我们的实验结果。我们知道 U 影响 XY —即 U 包含了人们的遵从行为(他们是否使用了该产品)以及他们的反应行为(他们是否变得更好了)。

我们可以把未被观察到的宇宙中的无数因素归纳成几大类,然后:决定参与者顺从和反应行为的原型。

我列举了一个这样的方案如下:

合规行为类型

  1. 总是接受者——无论我们如何分配,他们都能获得产品。
  2. 服从者— 他们服从小组分配。接受治疗的人下载并使用产品,而对照组的人则没有。
  3. 否认者— 他们做了与他们被指派做的相反的事情。对照组的人找到了使用该产品的方法,而治疗组的人从未使用过。
  4. 从不接受者— 他们从不接触产品,不管任务是什么。

反应行为类型

  1. 总是更好— 无论是否使用该产品,他们都会有好的结果。
  2. 帮助— 如果他们使用该产品,将会有良好的结果。
  3. 伤害— 如果他们使用该产品,结果会很糟糕,但如果不使用,结果也会很好。
  4. 再好不过了 —无论他们使用我们的产品,都不会有好结果。

实验中的所有参与者必须恰好有一种遵从行为类型和一种响应行为类型,因为它们被定义为互斥的。所以你可以把每一个人都描述成属于一个(顺从,回应)行为对,给我们一个人可能的 16 个原型。

我想这有点像 Myers-Briggs——除了这个框架实际上对科学研究有用(T21)。

It’s like a horoscope! Except it sorts people into groups that aren’t hot garbage

太好了,现在我们知道了 U 可以像(总是接受者,被帮助)(从不接受者,永远不会更好)一样接受 u 值。参与者可能属于特定的 u 的原因对于我们的分析并不重要——我们只需要知道uu是什么。如果我们知道 U 的分布,我们实际上可以为 ate 制定一个简单得多的表达式:

We’re marginalizing the compliance behaviors in this expression — P(U=helped) is actually a union of all P(U=u) where u has a ‘helped’ response type, for example.

但是怎么才能知道 U 的分布呢?

…好吧,事情是这样的:我们永远不会知道这种分布是什么。那是不可能的。在某些实验场景中,你怎么知道一个人是否会“好得不能再好”呢?这根本说不通。

在这一点上,你可能会通过你的电脑对我大喊大叫,说我浪费了你的时间。为什么我们刚刚经历了所有这些麻烦审议,结果却被卡住了?许多研究走捷径,根本不涉及 UX 或任何像我们设置的图表那样复杂的东西!

例如,医学研究中一个非常标准的做法是将 ate 表述为如下形式:

这被称为意向性治疗分析,它认识到了自己名字中的缺陷:它测量的是意向给某人治疗(治疗或控制的任务)的效果,而不是他们是否真的接受了治疗。

你可能已经知道为什么我不是意向治疗的支持者,但是为了让我的不快真正发自内心,我将为你模拟一个实验。在本笔记本中跟随:

这是我们刚刚模拟的大量工作——我们招募了一些参与者,获得知情同意,跟踪他们一段时间,测量结果,查询我们的生产数据库以获得合规数据,进行一些汇总等。等等。最后我们得到了那 8 个美丽的值: Z 中每个 zP(X,Y|Z=z) (这里是治疗和控制)。

你知道在关于蜘蛛丝及其神奇特性的纪录片中,叙述者会不断提到他们如何辛辛苦苦地为 14000 只义愤填膺的蜘蛛挤奶三个月,只为了得到一盎司的蛛丝?

The true cost of scientific progress. Base image source: Pexels.com.

我们的 P(X,Y|Z) 值是那盎司丝。它们很珍贵。

意向性治疗立即将它们抹去,并将其卷成两个粗略的数字:P(Y =好| Z =治疗)P(Y =好| Z =对照)

多么浪费有用的信息啊!这就像点燃我们一盎司的蜘蛛丝,然后系统地扇我们 14000 只已经痛苦不堪的蜘蛛的耳光。

How could you do this

这就是信息湮灭的悲剧:

必须有一些用于丰富 P(X,Y|Z) 信息。对吗?

反事实的时间机器

虽然我们永远无法知道 U 在我们的参与者群体中的分布情况,但我们知道 P(X,Y|Z) 的变化取决于 U 。或者换句话说,存在某个函数 U → P(X,Y|Z)

该函数可能是一对一或多对一的——但无论哪种情况,知道什么是 P(X,Y | Z)应该能够揭示 U 可能是什么。

除非它是一个活板门功能,在这种情况下,我们就完了。

不是虽然!实际上, U → P(X,Y|Z) 就是一个简单的线性函数,你很快就能直观地感受到。让我们仔细想想:

取量 P(X= ,Y= | Z= 处理 ) 。这个概率给了我们在治疗条件下接受治疗并有良好结果的人的比例。

但是我们可以得到这个值的另一种方法是,假设我们知道在 U 上的分布,将我们知道的总是接受治疗并好转的人的比例相加,以及服从治疗分配并好转的人的比例相加。

这让我们断言以下线性关系:

事实证明,我们拥有的每一个单独的 P(X,Y|Z) 值都是一组 P(U=u) 值的并集,就像上面的例子一样,这意味着 U 受到我们容易观察到的数据的约束!

这些并不是唯一的限制。我们还有概率规则在起作用:每个 P(U=u) 必须位于【0,1】区间内,所有 P(U=u) 的总和也必须等于 1。

除了这些限制,我们还想学习一个涉及到 U 的表达式:ATE,我们的圣杯。又来了:

Again, we’re marginalizing over the compliance behaviors in this expression — P(U=hurt) is actually a union of all P(U=u) where u has a ‘hurt’ response type

虽然我们没有工具来精确地解决 U 的分布——我们所做的都是线性优化问题的正确成分。

我们可以在可能的约束空间范围内,找出绝对最好和最坏的情况。这给了我们实际 ATE 值的硬边界。

我设置了这些约束,并使用 PuLP 进行了优化,这是一个 Python 库,它允许您用超级可读的符号表达式来构建这类线性编程问题:

请密切注意我们刚刚做的事情。使用一些假设和我们图表的结构,我们能够回到过去,看看如果我们生活在我们能想象的最幸福的时间线,有最高的可能 ATE,会发生什么。

使用同样的推理,我们也可以回到过去探索最黑暗的时间线(如果我们最小化而不是最大化)。

The darkest timeline. Source: Community.

如果你密切关注,你可能也会注意到一些相当惊人的事情。

意向性治疗分析——记住,这是分析人类参与者大多数实验结果的标准做法——宣布我们的治疗有 45%的 ATE,对参与者的结果有适度的积极影响。

但是当我们考虑治疗变量 X 时,我们看到最高可能的 ATE 是-15%。

治疗伤害人。

模型驱动与数据驱动的思维

从因果模型的角度思考,而不是把数据本身当成福音,是解开这种推理的关键。

我们没有被 RCT 提出的 8 种可能性困住,而是能够推断出某些东西对我们的实验参与者如何接受我们的治疗并对其做出反应负有责任。考虑到这一点,我们可以算出在不同的情况下会有什么样的结果。

我需要在这里对你说实话:在大多数情况下,这种分析会得到与意向治疗研究相同的方向性结果。我故意用了一个人为的例子,其中他们的结果是不同的。但重要的是要认识到,这种分歧一开始就可能发生,而且可能如此剧烈。

我认为许多从事应用统计学工作的人习惯于把我们看到的数据扔进我们众多古老而成熟的机器中。或者至少,我知道。这是个坏习惯。

权变表?进行卡方检验,然后转动曲柄。一张 2x2 的桌子和超低的样本量?把它扔进费希尔精确测试中,转动曲柄。映射到连续标签上的特征矩阵?把它放入线性回归中

转身。

那个。

曲柄。

很容易忘记数据的减少并不是分析的最终目的。理解并制作一个关于创造过程的心智模型,这些数据释放出一系列全新的力量。你可能从未意识到自己拥有的力量。

其中一些能力让你根本不需要进行实验就能进行因果推断。**

但那是以后的事了。

现在,我希望我已经给你的工具箱增加了一个可爱的新工具——更好的是,一个思考你的问题的新方法。

YouTube 的数据是否告诉了我们一个关于 2020 年民主党候选人的故事?

原文:https://towardsdatascience.com/does-youtubes-data-tell-us-a-story-about-the-2020-democratic-candidates-69568d2b0ce5?source=collection_archive---------24-----------------------

Photo by Philipp Lublasser on Unsplash

随着 2020 年总统大选在一年内举行,所有与弹劾无关的新闻都在谈论谁将成为面对特朗普总统的民主党候选人。

现有的信息来源包括新闻渠道和民意调查,但对我个人来说,我想看看我是否可以探索其他类型的公开可用数据。

作为一个每天在 YouTube 上花费大量时间的人,我决定从 YouTube 的数据 API 中获取数据,并设计自己的快速实验,看看这些数据是否会为民主党候选人竞选增添色彩,而传统渠道和民意调查无法提供这些色彩。YouTube 是一个非常棒的*台,因为创作者经常上传针对个人候选人的内容,内容表现可供每个人查看和使用。

提取数据的方法

每个快速数据实验都是围绕一些快速假设和规则设计的。以下是我使用的方法:

  • YouTube 数据 API 获取数据。许多数据方法是围绕 YouTube 有配额限制这一事实设计的。
  • 我调出了 2019 年 12 月 4 日的视频列表和 2019 年 12 月 6 日的统计数据
  • 收集了 2019 年 11 月 20 日辩论的候选人名单。在写这篇文章的时候,我意识到卡玛拉·哈里斯已经退出,迈克尔彭博正在竞选。我很可能会在未来写一部续集。
  • 在 2019 年 1 月 1 日之后上传的前 250 个视频中,他们的名字出现在搜索词中。
  • 消除了跨越多个候选人的重复视频,如“DNC 市政厅— SNL”。因此,该分析不包含涵盖多个或所有候选人的视频。
  • 查看、喜欢、不喜欢和评论的统计数据
  • 将名单缩小到每个候选人观看次数最多的前 150 个视频。
  • 已禁用喜欢和评论的视频被限定为该视频的 0 个喜欢、不喜欢和评论。
  • 在 Excel 中快速处理数学和图表。还将附上表格。

数据告诉我们的是

虽然我们有很多方法可以深入数据,并做进一步的分析和细分,但我认为快速简单地浏览一下基本统计数据确实讲述了一个很好的故事,我们可以从中学到很多东西。

视图

浏览量相当于每个候选人有多少人观看了独特的视频。这总计约为 4.3 亿英镑。候选人之间的意见分歧是这样的:

Chart Representing Candidates’ Share of Unique YouTube Views

Table Representing Candidates’ Share of Unique YouTube Views

正如你在这里看到的,6800 万的浏览量属于乔·拜登,占了 15.8%的份额。他领先,紧随其后的是伯尼·桑德斯 15.6%,皮特·布蒂吉格 14.3%,杨安泽 13.6%,塔尔西·加巴德 11.7%,卡玛拉·哈里斯 11.3%,伊丽莎白·沃伦 10.8%,然后是科里·布克,艾米·克洛布查尔和汤姆·斯特耶加起来约 7%的显著下降。

喜欢

视图对于理解链接被打开和可能被观看的频率是至关重要的,但是视频赞告诉我们一些视图不能告诉我们的事情。喜欢更符合观众参与度。就向其他观众推荐什么而言,赞是 YouTube 算法的关键组成部分之一。

Chart Representing Candidates’ Share of Unique YouTube Likes

Table Representing Candidates’ Share of Unique YouTube Likes

厌恶

就成为观众反馈的良好标记而言,类似于“喜欢”,但以负面方式表达。

Chart Representing Candidates’ Share of Unique YouTube Dislikes

Table Representing Candidates’ Share of Unique YouTube Dislikes

评论

评论是敬业度的另一个重要部分。它们不一定一眼就能反映出积极或消极的参与度,但它们确实代表了哪些候选人被认为更具“争议性”

Chart Representing Candidates’ Share of Unique YouTube Comments

Table Representing Candidates’ Share of Unique YouTube Comments

比率

当谈到观察数据时,从基本数据中创造比率可以为我们的理解增加很多价值。然而,简单的统计数据并不总能说明全部情况,因此比率的存在有助于我们将事情放入背景中。这方面的一个例子是当我们从视频中查看“喜欢”时。一个有数百万次观看的视频会比一个有数千次观看的视频获得更多的喜欢,但这并不能真正告诉你它与观众的互动有多好。它也可以有数以百万计的厌恶。考虑到这一点,我决定看看下面的比率,它给出了一个关于“可爱度”的概念

  • 点赞浏览量(百分比): 这简单地告诉我们候选人的视频每被观看 100 次就有多少人点赞。单独拥有这个比例并不意味着什么,但当与其他人进行比较时,它可以成为谁被认为更“可爱”的有用基准。

Likes to Views Ratio. Average is 2.3%

  • 喜欢与不喜欢的比率: 这告诉我们一个候选人得到多少喜欢与不喜欢。与不喜欢相比,喜欢和不喜欢的比例很高的候选人可以被认为是非常可爱的。

Likes to Dislikes Ratio. Average is 10.3

从上面的分析中,我们可以看到,YouTube 告诉了我们一些如果我们只依靠新闻和民意调查获得数据时不一定会知道的事情。乔·拜登获得了观点,目前他在民调中领先,但当涉及到参与度和可爱程度时,YouTube 的观众似乎倾向于伯尼·桑德斯和杨安泽。

由于技术,我们与信息和媒体互动的方式自上次民主党人取代共和党人入主白宫以来发生了巨大变化。正因为如此,我认为我们还应该探索额外的方法来衡量和基准测试候选人,特别是在 YouTube 这样每天都在变大的*台上。

以下是我如何获得数据的,以防你想亲自试验一下

基于 CNN 的犬种分类

原文:https://towardsdatascience.com/dog-breed-classification-using-cnns-f042fbe0f333?source=collection_archive---------13-----------------------

在今天的帖子中,我将向你展示如何制作一个非常有趣的应用程序,来检测一张照片中是人还是狗。此外,在图像中检测到狗的情况下,它会以很高的准确度告诉我们狗的品种。

可以通过这个 github 链接访问相关的存储库,在那里可以找到关于下载数据集和先决条件的说明。

在构建我们的分类器时,我们将遵循以下步骤:

  • 步骤 0:导入数据集
  • 第一步:探测人类
  • 第二步:探测狗
  • 第三步:创建一个 CNN 来分类狗的品种
  • 第四步:训练 CNN 对狗的品种进行分类(从头开始)
  • 第五步:训练 CNN 对狗的品种进行分类(通过迁移学习)

第 0 步:导入数据集

我们的第一步将是加载分为训练、验证和测试文件夹的数据集。

我们想把我们训练数据集中的狗分成 133 个不同的品种。

正如我们在下面的代码片段中看到的,我们将使用 6680 张狗的图片来训练我们将要使用的模型。我们将使用 835 验证图像来微调我们的参数,并在 836 测试图像上测试最终模型的准确性。当然,测试数据集将是模型以前没有见过的图像。

Snippet 1 : Loading the Dataset

第一步:探测人类

为了检测人,我们首先将三通道 RGB 图像(红绿蓝)转换成灰度。一个名为“ detectMultiScale ”的 OpenCV 函数对灰度图像起作用,并给我们一个检测人脸的“盒子”的坐标。稍后,我们可以使用它在我们正在绘制的图像上绘制一个蓝色的矩形,如下所示。

Snippet 2 : Detecting humans

第二步:检测狗 我们将使用 Keras 中的 resnet50 预训练模型来检测图像中的狗。这里的第一步是转换的 RGB 编码。jpg 图像到 BGR,然后根据从庞大的 Imagenet 数据库中获得的*均值和标准偏差对三个通道进行归一化。幸运的是,这是由 Keras 中 applications.resnet50 模块中的 preprocess_input 完成的。

Snippet 3: Resnet50

使用我们从 keras.applications 库导入的 ResNet50 模型,我们可以将图像分类到标签中。在 resnet 库中,任何编码为 151 到 268 的标签实际上都是“狗”。如果是这种情况,下面的函数将给出一个真布尔值,否则为假。

Snippet 4: Dog Detector

第三步:创建 CNN 对狗的品种进行分类

我们将使用下面的基本序列模型,并设计我们的 CNN 网络。

我使用了三个卷积层,每个卷积层后面都有一个 MaxPooling2D,以降低堆叠模型的复杂性。

最后,我们将使用 global_average_pooling 将 Max Pooling 图层中的每个要素地图转换为标量。

Snippet 5: Building the CNN Model

第四步:训练 CNN 对狗的品种进行分类(从头开始)

我们开始训练我们创建的模型,我们看到我们的验证损失不断降低,我们的准确性降低了 5 个时期,表明我们的模型正在学习。

Snippet 6: Training the Model with 5 Epochs

在 20 个历元时,有可能达到大约 4.5%的精度吗?当我们在这个数据集上运行 250 个历元时,我们能够达到%40+的准确度,即使有强大的 GPU 支持,这也需要相当长的时间,这就是为什么我们将使用迁移学习作为下一步。

第五步:训练 CNN 对狗的品种进行分类(通过迁移学习)

接下来,我们将使用预提取的“瓶颈特征”,这些特征是应用于我们的训练、测试和验证数据集的预训练库的输出。

我们将使用 Resnet50 库输出作为我们模型的输入,并使用这些瓶颈特性训练我们的模型。

Snippet 7: Loading bottleneck features

我们通过添加一个全局*均池层来创建一个简单的模型,该层将之前的每个特征映射总结为一个标量。密集层创建 133 个不同的输出,每个输出对应一个所需的标签。然后,softmax 激活将这些转换成概率。

Snippet 8: Define, compile and train the model

然后,我们现场测试我们的算法,看看它是否能正确预测加载图像路径中的狗的品种。我们将一张威尔士施普林格犬的图片加载到模型中,正如你在下面看到的,神经网络正确地对我们使用的样本狗图片进行了分类。

Snippet 9: Predict using the model

最后一部分连接了我们之前构建的所有函数,将有助于确定所提供的图像是人还是狗,或者两者都不是。

Snippet 10: Final algorithm

基于细胞神经网络和迁移学习的犬种预测

原文:https://towardsdatascience.com/dog-breed-prediction-using-cnns-and-transfer-learning-22d8ed0b16c5?source=collection_archive---------7-----------------------

在本文中,我将演示如何使用 keras 和 tensorflow 来构建、训练和测试一个卷积神经网络,该网络能够在提供的图像中识别狗的品种。成功将由高验证和测试准确性来定义,准确性和召回分数在具有相似准确性的模型之间有所不同。

这是一个监督学习问题,特别是一个多类分类问题,因此可以通过以下步骤来解决:

  1. 积累标签数据。在这种情况下,这意味着用已知品种的狗编辑一个图像库。
  2. 构建一个能够从训练图像中提取数据的模型,该模型输出可以被解释以辨别狗的品种的数据。
  3. 根据训练数据训练模型,在训练期间使用验证数据验证性能
  4. 评估绩效指标,可能返回到第 2 步进行编辑以提高绩效
  5. 根据测试数据测试模型

当然,每一步都有许多子步骤,我将在后面详述。

序幕

训练一个神经网络的行为,即使是一个相对简单的网络,在计算上也是极其昂贵的。许多公司使用专用于此类任务的 GPU 服务器机架;我将在配有 GTX 1070 图形卡的本地电脑上工作,我将为这次练习招募该电脑。为了在您的本地计算机上执行这个任务,您必须采取一些步骤来定义一个合适的编程环境,我将在这里详细介绍它们。如果您对后端设置不感兴趣,请跳到下一节。

首先,我在 Anaconda 中创建了一个新环境,并安装了以下包:

  • 张量流-gpu
  • 朱皮特
  • glob2
  • sci kit-学习
  • 克拉斯
  • matplotlib
  • opencv(用于识别图像管道中的人脸——不是必要的功能,但在某些应用中很有用)
  • tqdm
  • 枕头
  • 海生的

接下来,我更新了我的显卡驱动。这一点很重要,因为驱动程序更新会定期推出,即使是像我这样使用了 3 年的卡,如果您使用的是 tensorflow 的现代版本,是否有必要使用最新的驱动程序来实现兼容性。在我的案例中,只有 5 个月大的驱动程序与最新版本的 tensorflow 不兼容。

最后,在新环境的 anaconda 提示符下打开 jupyter 笔记本,以便执行您的工作,并确保 jupyter 使用了正确的内核环境。如果不这样做,Tensorflow 可能会遇到问题。

作为健全性检查,在模块导入后,我可以调用以下代码来显示可用的 CPU 和 GPU。

from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())

成功!这是我的 GTX 1070。

最后,我执行下面的代码块,它编辑 tensorflow 后端的一些配置参数,并防止将来出现一些运行时错误。

# tensorflow local GPU configuration
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.8)
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config)

步骤 1:编译数据

在我的情况下,这是微不足道的,因为 Udacity 向我提供了 1.08Gb 的跨越 133 个品种的狗图像,已经在一个适当的文件结构中。适当的文件结构,在 CNN 用 keras 建立分类的情况下,意味着文件通过训练、验证和测试被隔离,并且在这些文件夹中通过狗的品种被进一步隔离。每个文件夹的名称应该是您计划识别的类的名称。

显然,世界上有超过 133 个狗品种——美国权威机构 AKC 列出了 190 个品种,而世界权威机构 FCI 列出了 360 个品种。如果我想增加我的训练数据集的大小,以包括更多的品种或每个品种的更多图像,我可以采用的一种方法是安装 python Flickr API,并在其中查询标记有我想要的任何品种名称的图像。然而,为了这个项目的目的,我继续使用这个基本数据集。

作为第一步,我将把所有文件名加载到内存中,以便以后更容易处理。

*# define function to load train, test, and validation datasets*
def **load_dataset**(path):
    data = load_files(path)
    dog_files = np.array(data['filenames'])
    dog_targets = np_utils.to_categorical(np.array(data['target']))#, 133)
    return dog_files, dog_targets# load train, test, and validation datasets
train_files, train_targets = load_dataset('dogImages/train')
valid_files, valid_targets = load_dataset('dogImages/valid')
test_files, test_targets = load_dataset('dogImages/test')*# load list of dog names
# the [20:-1] portion simply removes the filepath and folder number*
dog_names = [item[20:-1] for item in sorted(glob("dogImages/train/*/"))]*# print statistics about the dataset*
print('There are %d total dog categories.' % len(dog_names))
print('There are %s total dog images.\n' % len(np.hstack([train_files, valid_files, test_files])))
print('There are %d training dog images.' % len(train_files))
print('There are %d validation dog images.' % len(valid_files))
print('There are %d test dog images.'% len(test_files))

它输出以下统计信息:

There are 133 total dog categories.
There are 8351 total dog images.

There are 6680 training dog images.
There are 835 validation dog images.
There are 836 test dog images.

接下来,我通过将图像中的每个像素除以 255 来标准化数据,并将输出格式化为张量 keras 可以使用的向量。注意:下面的代码将数千个文件作为张量加载到内存中。尽管对于相对较小的数据集来说这是可能的,但最好使用批量加载系统,一次只加载少量的张量。我在后面的步骤中为我设计的最后一个模型这样做。

*# define functions for reading in image files as tensors*
def **path_to_tensor**(img_path, target_size=(224, 224)):
 *# loads RGB image as PIL.Image.Image type
    # 299 is for xception, 224 for the other models*
    img = image.load_img(img_path, target_size=target_size)
    # convert PIL.Image.Image type to 3D tensor with shape (224, 224, 3)
    x = image.img_to_array(img)
 *# convert 3D tensor to 4D tensor with shape (1, (target_size,) 3) and return 4D tensor*
    return np.expand_dims(x, axis=0)def **paths_to_tensor**(img_paths, target_size = (224, 224)):
    list_of_tensors = [path_to_tensor(img_path, target_size) for img_path in tqdm(img_paths)]
    return np.vstack(list_of_tensors)*# run above functions*
from PIL import ImageFile                            
ImageFile.LOAD_TRUNCATED_IMAGES = True*# pre-process the data for Keras*
train_tensors = paths_to_tensor(train_files).astype('float32')/255
valid_tensors = paths_to_tensor(valid_files).astype('float32')/255
test_tensors = paths_to_tensor(test_files).astype('float32')/255

构建、培训、测试、评估

有无数种方法可以做到这一点,其中一些会比另一些更好。我将探索 3 种独特的方法,并遵循它们从构建到测试和评估。我采用的方法如下:

  1. 琐碎的解决办法。我将在数据集上构建并训练一个非常简单的 CNN,并评估其性能。
  2. 具有瓶颈特征的迁移学习。我将利用一个已在大规模图像库上训练过的现有 CNN,并通过使用它将我的输入图像转换为“瓶颈特征”:图像的抽象特征表示,使其适应我的应用程序。
  3. 图像增强的迁移学习。类似于瓶颈特征方法,但我将尝试通过创建一个模型来获得更好的模型泛化,该模型是一个预训练的瓶颈特征 CNN 的堆栈,带有一个用于我的应用程序的自定义输出层,我将向它提供通过象形变换随机增强的输入图像。

首先,我将演示创建一个基本 CNN 并在数据集上训练它的简单方法。

步骤 2a:构建简单模型

我用下面的代码创建了一个简单的 CNN,使用 keras 和 tensorflow 后端。

from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D
from keras.layers import Dropout, Flatten, Dense
from keras.models import Sequentialmodel = Sequential()*# Define model architecture.*
model.add(Conv2D(16, kernel_size=2, activation='relu', input_shape=(224,224,3))) # activation nonlinearity typically performed before pooling
model.add(MaxPooling2D()) # defaults to pool_size = (2,2), stride = None = pool_size
model.add(Conv2D(32, kernel_size=2, activation='relu'))
model.add(MaxPooling2D())
model.add(Conv2D(64, kernel_size=2, activation='relu'))
model.add(MaxPooling2D())
model.add(GlobalAveragePooling2D())
model.add(Dense(133, activation='softmax'))model.summary()

model.summary()方法打印出以下模型结构:

在这里,我创建了一个 8 层顺序神经网络,利用与最大池层配对的 3 个卷积层,并终止于具有 133 个节点的全连接层——我试图预测的每个类一个节点。注意在密集层我使用了一个 softmax 激活函数;原因是它的范围是从 0 到 1,并且它强制输出层中所有节点的总和为 1。这允许我们将单个节点的输出解释为模型的预测概率,即输入是对应于该节点的类。换句话说,如果层中的第二个节点对于特定图像的激活值为 0.8,我们可以说模型已经预测到输入有 80%的机会来自第二类。请注意 19,000 个模型参数——这些是我的网络将尝试优化的权重、偏差和核(卷积滤波器)。现在应该很清楚为什么这个过程需要大量的计算。

最后,我编译这个模型,以便它可以被训练。注意,这里我可以使用许多损失函数和优化器,但是当前多类图像标签预测的通用约定使用 Adam 作为优化器,使用分类交叉熵作为损失函数。我用 SGD 和 RMSProp 测试了 Adam,发现 Adam 的训练速度要快得多。

model.compile(optimizer=’adam’, loss=’categorical_crossentropy’, metrics=[‘accuracy’])

步骤 3a:训练*凡模型

现在我有了一个用来训练、验证和测试模型的张量列表,还有一个完整编译的 CNN。在我开始训练之前,我定义了一个 ModelCheckpoint 对象,它将作为一个钩子,我可以使用它来保存我的模型权重,以便将来轻松加载,而无需重新训练。为了训练模型,我调用。用我的关键字参数拟合模型的()方法。

checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.from_scratch.hdf5', verbose=1, save_best_only=True)model.fit(train_tensors, train_targets, 
          validation_data=(valid_tensors, valid_targets),
          epochs=3, batch_size=20, callbacks=[checkpointer], verbose=2)

正如您所看到的,我只运行了 3 个时期的模型,因为我知道由于它的简单性,它不会是一个高性能的模型,这个模型纯粹是为了演示的目的。模型训练给出以下输出:

模型完成训练,训练准确率为 1.77%,验证准确率为 1.68%。虽然这比随机猜测要好,但也没什么值得大书特书的。

顺便提一下,在训练这个模型时,我们可以看到我的 GPU 使用率立即跃升!这太好了——这意味着 tensorflow 后端确实在使用我的显卡。

步骤 4a:评估普通模型

该模型在训练或验证数据上没有达到合理的精确度,这表明它大大地低估了数据。这里我展示了一个模型预测的混淆矩阵,以及一个分类报告。

该模型预测了几乎所有输入图像的两类中的一类。似乎偏爱巴吉度猎犬和边境牧羊犬。不幸的是,我没有创造出有一只喜欢的狗的有知觉的 AI;在巴吉度猎犬和边境牧羊犬的训练集中,图片比大多数其他种类的图片要多一些,这是模型学来的。由于模型的严重欠拟合,不值得探究精度或回忆它在此时达到的效果。

步骤 5a:测试普通模型

最后,我在测试数据集上测试模型。

# get index of predicted dog breed for each image in test set
dog_breed_predictions = [np.argmax(model.predict(np.expand_dims(tensor, axis=0))) for tensor in test_tensors]# report test accuracy
test_accuracy = 100*np.sum(np.array(dog_breed_predictions)==np.argmax(test_targets, axis=1))/len(dog_breed_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)

这产生了 1.6746%的测试精度——符合我的预期。如果我在更多的时期训练模型,我可能会达到更高的精度,但这个模型是高度简化的,修改我的架构将是一个更好的主意。很快,我将展示使用迁移学习建立模型的更好方法,这可以实现更高的准确性。

步骤 2b:构建瓶颈特征模型

我可以显著提高性能的一种方法是利用迁移学习,也就是说,我可以利用现有的 CNN,它已经过预训练,可以识别一般图像数据的特征,并根据自己的目的进行调整。Keras 有许多这样的预训练模型可供下载和使用。每一个都是在一个名为 imagenet 的图像库中训练过的模型,该图像库包含分布在 1000 个类别中的数百万张图像。在 imagenet 上训练的模型通常是具有许多完全连接的输出层的深度 CNN,这些输出层已经被训练为将卷积层暴露的隐藏特征分类为 1000 个类别中的一个。我可以采用这些预训练模型中的一个,简单地用我自己的完全连接层替换输出层,然后我可以训练这些层,将每个输入图像分类为我的 133 个狗品种中的一个。这里需要注意的是,我不再训练 CNN,我将冻结卷积层的权重和内核,卷积层已经被训练来识别图像的抽象特征,并且只训练我自己的自定义输出网络。这节省了大量的时间。

至少有两种方法可以解决这个问题。一种方法是将预训练网络和我的定制网络连接在一起,如上所述。另一种更简单的方法是,通过预训练的网络输入我的数据集中的每幅图像,并将输出保存为数组,以便稍后通过我的网络输入。后一种方法的好处是它节省了计算时间,因为每个训练时期我只通过我自己的模型进行前向传递和后向投影,而不是 imagenet 模型和我的模型一起进行。方便的是,Udacity 已经通过一些内置的 CNN 提供了他们提供的所有训练图像,并提供了原始输出或瓶颈功能,供我简单地阅读。

在这里,我定义了自己的全连接网络,以接受瓶颈特性并输出 133 个节点,每个品种一个。这是 VGG16 网络的一个例子。我在实际训练中使用不同的网络,这将在下一节中看到。

VGG16_model = Sequential()
VGG16_model.add(GlobalAveragePooling2D(input_shape=train_VGG16.shape[1:]))
VGG16_model.add(Dense(133, activation='softmax'))

这里需要注意一些事情:

  • 我从 GlobalAveragePooling 层开始——这是因为 VGG16 的最后一层,事实上我测试的所有 imagenet 模型都是卷积/池序列。全局池层减少了该输出的维数,并且在输入到密集层时极大地减少了训练时间。
  • 我的网络中第一层的输入形状必须适合它所设计的模型。我可以通过简单地获得瓶颈数据的形状来做到这一点。瓶颈特征形状的第一个尺寸被切除,以允许 keras 添加一个尺寸进行批处理。
  • 我再次使用一个 softmax 激活函数,原因与简单模型相同。

步骤 3b:列车瓶颈特征模型

Udacity 为 4 个网络提供了瓶颈功能:VGG19、ResNet50、InceptionV3 和 Xception。下面的代码块读入每个模型的瓶颈特性,创建一个完全连接的输出网络,并在 20 个时期内训练该网络。最后输出每个模型的精度。

从最后一行可以明显看出,所有 4 个模型的表现都比我自己微不足道的 CNN 好得多,其中 Xception 模型达到了 85%的验证准确率!

步骤 4b:评估瓶颈特征模型

表现最好的——Xception 和 resnet 50——都取得了显著的验证准确性,但是通过挖掘日志,我们可以看到它们对训练数据的准确性接* 100%。这是过度拟合的标志。这并不令人惊讶,Xception 有 2200 万个参数,ResNet50 有 2300 万个参数,这意味着这两个模型都有巨大的熵容量,能够只记住训练数据图像。为了解决这个问题,我将对我的全连接模型进行一些更改并重新培训。

我已经添加了第二个密集层,希望模型能够对预训练参数依赖少一点,我还用 L2 正则化和丢弃增强了完全密集层。L2 正则化因高个体参数权重而惩罚网络,而丢弃在训练期间随机丢弃网络节点。两者都通过要求网络在训练过程中进行更多的归纳来对抗过度拟合。还要注意我已经改变了优化策略;在真实的研究环境中,这将通过 GridSearch 来完成,grid search 接受超参数列表(比如具有超参数范围的优化器),但是为了节省时间,我自己试验了几个。请注意,我已经切换回使用 SGD——通过实验,我发现尽管 Adam 训练速度极快,但如果给定足够的训练次数,SGD 始终会超过 Adam(这一发现在本文中有所暗示)。

训练 100 个周期(5 分钟)后:

该模型取得了与以前相当的验证精度,但训练精度要低得多。训练精度低是由于辍学,因为它从来没有使用完整的模型来评估训练输入。我很满意这个模型不再像以前一样过度合身。看起来验证准确性和损失都大致持*——可能再过 100 个纪元,我还能挤出 1 %- 2%的准确性,但我可以先采用更多的训练技术。

步骤 5b:测试瓶颈特征模型

在测试数据集上有将* 83%的准确率。与预期的验证集非常相似。看着混乱矩阵:

比上一部好多了。我们可以在这里看到,有几个品种的狗,模型表现相当好,有几个地方,它真的很难。看看这个例子,原因就很清楚了。

让我们放大 y 轴中间和 x 轴大约 1/4 处的异常值。

模型一致认为 66 级其实是 35 级。也就是说,它认为一只田野猎犬实际上是一只博伊金猎犬。这是并排的两个品种。

Field Spaniel (left), Boykin Spaniel (right)

注意到相似之处了吗?显然,区分这两个品种是一项极其困难的任务。我怀疑,在这种情况下,调整我的模型参数不会导致分类的有意义的改进,在真实的场景中,我会训练一个二元分类器来区分这些品种,如果主要模型预测了任一类别,则在分类预测管道中使用它。但是现在,我感兴趣的是通过增加我的训练数据来获得更好的表现。

步骤 2c:编译扩充输入模型

在根据图像数据训练的模型中,有一种引导训练数据的形式,称为图像增强,在训练期间,我可以对训练图像应用随机旋转、缩放和*移。这具有通过改变训练图像的像素同时保持内容的完整性来人为增加训练数据的大小的效果;例如,如果我将一只柯基犬的图像旋转 15 度并水*翻转,该图像仍然可以被识别为一只柯基犬,但是模型在训练期间将不会看到该图像。希望这项技术既能提高大量时期的模型精度,又能防止过度拟合。为了做到这一点,我不能再使用我以前使用的瓶颈特性,我必须一起编译整个模型,以便向前和向后传播。另请注意,由于我仍然不想编辑 imagenet 预训练模型的参数,我将在训练前冻结这些层。

首先,我定义了我的数据加载管道:

接下来,我加载 imagenet 模型,定义一个定制的完全连接的输出模型,并将它们组合成一个顺序模型。由于训练时间的原因,我在这里重新使用了 Adam。如果我有更多的计算资源,可能值得像以前一样使用 SGD。

步骤 3c:训练增强输入模型

这个模型的训练时间比我以前的任何模型都要长,因为每次向前传递都必须遍历 imagenet 模型的所有节点。在我的 GPU 上,每个 epoch 需要大约 3.5 分钟来训练,而瓶颈功能模型只需要几秒钟。这暴露了我们以前从使用瓶颈特性中获得的计算增益。

该模型在训练和验证数据集上非常快地实现了相对较高的准确性——这要归功于我切换到 Adam 优化器。请注意,训练精度仍然低于验证精度,这是因为我仍然在使用 dropout。另一件要注意的事情是验证准确性的高度变化。这可能是高学习率(看着你,亚当)或高熵容量(参数太多)的症状。随着时间的推移,它似乎变得*稳了,所以我并不担心。

步骤 4c:评估扩充输入模型

查看这个模型和以前的模型的分类报告,在验证过程中,两个模型的精确度和召回率都得了 0.80 分。两者都以大约 1 的验证损失结束,进一步表明没有改善。我希望看到由于训练数据的增加而导致的准确性的提高,但是我认为在这种提高变得明显之前,只需要更多数量级的训练周期。我怀疑改用 SGD 分类器并运行更多的纪元会有所帮助。

步骤 5c:测试增强的输入模型

使用 keras ImageDataGenerator,我可以像输入培训和验证数据一样输入增强模型测试数据:

测试精度与瓶颈特性模型大致相同,只是低了几个百分点。

为了深入研究精确度和回忆,我使用混淆矩阵执行了与之前相同的分析:

这里真正有趣的是,我们看到了和以前一样的异常值,尽管它更模糊,表明这个模型在区分西班牙猎犬方面做得稍好。然而,现在在矩阵的中心附*有另一个明亮的异常值——放大显示,这个模型无法区分杜宾犬和德国犬。

Doberman (left) and German (right) Pinschers

去想想。

最后结果

对我来说,最后一步是编写一个函数,从零开始加载给定的模型,接受图像数据作为输入,并输出品种预测。我将继续我的增强图像模型,因为我相信在未来我可以通过更多的训练来改进它。

在我在这里测试的每个模型的训练期间,我将参数保存到. hdf5 文件中。因此,一旦训练完成,假设我知道如何编译我感兴趣使用的模型,我可以根据命令加载我上次训练运行的最佳权重。然后在我的预测函数中,我只需要重新创建我在训练期间执行的图像处理步骤。

因为我已经将模型权重存储在一个外部文件中,并且我知道如何重新创建模型架构,所以我可以将所述模型打包,以便在任何地方使用,包括在 web 或移动应用程序中。事实上,在我写这篇文章的时候,我在 Play Store 上看到有一个狗品种识别应用程序,我怀疑它使用了与我在这里结束的那个类似的模型。

github 回购:https://github.com/jfreds91/DSND_t2_capstone

在 R 中进行并报告您的第一个方差分析和安协方差分析

原文:https://towardsdatascience.com/doing-and-reporting-your-first-anova-and-ancova-in-r-1d820940f2ef?source=collection_archive---------2-----------------------

如何测试和报告分类自变量对区间因变量的影响?

方差分析或 ANOVA,是许多科学领域中经常使用的基本统计测试。最常见的形式是,它分析模型中因变量的方差有多少可归因于自变量。它最常用于分析分类自变量的影响(例如,实验条件、狗的品种、花的种类等)。)上的区间因变量。方差分析的核心是提供与简单线性回归(即 OLS)相同的信息。然而,ANOVA 可以被视为一种替代的界面,通过它可以访问这些信息。不同的科学领域可能有不同的偏好,这通常意味着你应该使用哪种测试。

协方差的分析,或 ANCOVA,表示有一个以上自变量的 ANOVA。假设你想分析狗的品种对狗的体重的影响,控制狗的年龄。如果不控制狗的年龄,你可能永远无法确定狗的品种对其体重的真正影响。因此,你需要运行 ANCOVA 来“过滤”狗的年龄的影响,看看狗的品种是否仍然影响体重。控制另一个协变量可能会加强或削弱你感兴趣的自变量的影响。

Photo by Akshay Nanavati on Unsplash

方差分析

数据集

在这个练习中,我将使用 iris 数据集,它在 core R 中可用,我们将使用下面的命令以 df 的名称将其加载到工作环境中:

df = iris

鸢尾数据集包含描述不同种类鸢尾花的形状和大小的变量。

一个可以用方差分析来检验的典型假设是鸢尾的种类(独立分类变量)是否对花的其他特征有任何影响。在我们的例子中,我们将测试鸢尾的种类是否对花瓣长度(因变量区间)有任何影响。

确保你不违反关键假设

在运行方差分析之前,必须首先确认数据集中满足方差分析的关键假设。关键假设是在您的计算机如何计算方差分析结果时假设的方面,如果违反了这些方面,您的分析可能会产生虚假的结果。

对于 ANOVA,假设是方差的同质性。这听起来很复杂,但它基本上检查了由分类自变量创建的不同组中的方差是否相等(即,方差之间的差为零)。我们可以通过运行 Levene 的测试来检验方差的同质性。** Levene 的测试在 R 基地不可用,所以我们将使用包进行测试。**

安装软件包。

install.packages("car")

然后加载包。

library(car)

然后进行 Levene 的测试。

leveneTest(Petal.Length~Species,df)

这会产生以下输出:

如您所见,测试返回了一个重要的结果。在这里,了解检验中的假设是很重要的:如果检验结果不显著,我们可以接受 Levene 检验的零假设,这意味着方差是同质的,我们可以继续进行方差分析。然而,测试结果非常显著,这意味着花瓣之间的差异。不同物种的长度有显著差异。

现在怎么办?

嗯……在这一点上,和你的合著者、同事或主管谈谈。从技术上讲,你必须进行稳健的方差分析,即使面对非齐次方差,它也能提供可靠的结果。然而,并不是所有的学科都遵循这个技术指南…所以要和你领域里更资深的同事交流。

无论如何,我们将继续本教程,就好像 Levene 的测试结果无关紧要一样。

运行实际的方差分析

我们通过使用公式符号、数据集名称和 Anova 命令指定该模型来实现这一点:

fit = aov(Petal.Length ~ Species, df)

在上面的命令中,你可以看到我们告诉 R 我们想知道物种是否影响花瓣。数据集 df 中的长度使用 aov 命令(这是 R 中的 ANOVA 命令)并将结果保存到对象 fit 中。上述命令的两个基本要素是语法(即结构、符号、括号等)。)和 aov 命令。其他一切都可以修改,以适应您的数据:花瓣。长度物种是由虹膜数据集指定的名称,而 dffit 只是我随意选择的名称——它们可能是你想要分析的任何东西。

您可能已经注意到,R 还没有报告任何结果。我们需要使用以下命令告诉 R 我们想要访问保存在名为 fit 的对象中的信息:

summary(fit)

该命令产生以下输出:

这张表给了你很多信息。尽管如此,我们感兴趣的关键部分是行物种,因为它包含我们指定的自变量的信息,以及列 F 值Pr( > F) 。如果我们的目标是拒绝零假设(在这种情况下,零假设是鸢尾的物种对花瓣长度没有任何影响)并接受我们的实际假设(物种对花瓣长度有影响),我们要寻找高 F 值和低 p 值 在我们的例子中,F 值是 1180(非常高),p 值小于 0.000000000000002(写出来的 2e-16,你可能已经猜到了,非常低)。这一发现支持了我们的假设,即鸢尾的种类对花瓣长度有影响。

报告方差分析的结果

如果我们想报告这一发现,最好报告数据中个体组的*均值(在我们的例子中是物种)。我们使用 psych 包中的 describeBy 命令来完成这项工作。如果您还没有安装 psych 包并且想第一次使用它,请使用以下命令:

install.packages("psych")

否则,或者在安装了 psych 包之后,运行以下命令。

library(psych)
describeBy(df$Petal.Length, df$Species)

对于 describeBy 函数,您传递您希望看到描述的变量(花瓣。长度)和分组变量(物种)。我们需要在变量名前指定 df ,这与上面使用的 aov 命令使用的公式符号不同,因为 describeBy 命令不允许我们单独指定数据集。运行此命令会产生以下输出:

在此输出中,我们可以看到三个物种 Setosa、Versicolor 和 Virginica,在第三列中,我们看到了花瓣值的*均值。三组的长度

这一发现可以用以下方式报告:

我们观察了三种鸢尾(M=1.46)、杂色鸢尾(M=4.26)和海滨鸢尾(M=5.55)的花瓣长度差异。方差分析表明物种之间的这些差异是显著的,即物种对花的花瓣长度有显著影响,F(2,147)=1180,p <.001./>

One could also add a graph illustrating the differences using the package ggplot2。运行以下命令安装 ggplot2 包,如果你还没有安装的话。

install.packages("ggplot2")

然后加载包。

library(ggplot2)

然后运行图形命令。

ggplot(df,aes(y=Petal.Length, x=Species, fill=Species))+
  stat_summary(fun.y="mean", geom="bar",position="dodge")+
  stat_summary(fun.data = mean_se, geom = "errorbar", position="dodge",width=.8)

这产生了下图。代码相当复杂,解释 ggplot2 的语法超出了本文的范围,但是请尝试对其进行修改并将其用于您的目的。

安科瓦

现在想象你想要做上面的分析,但是同时控制花的大小的其他特征。毕竟,物种可能不会具体影响花瓣长度,但更普遍的是,物种会影响植物的整体大小。所以问题是:在控制了其他植物尺寸的情况下,物种是否仍然会影响花瓣的长度?在我们的分析中,代表植物大小的另一个指标是变量 Sepal。长度,在虹膜数据集中也有。因此,我们通过添加这个新的协变量来指定我们的扩展模型。这就是 an cova——我们在控制一个或多个协变量的同时,分析分类自变量对区间因变量的影响。

fit2=aov(Petal.Length~Species+Sepal.Length,df)

然而与之前不同的是,我们现在不能简单地在 fit2 对象上运行 summary 命令。因为在默认情况下,非常奇怪的是,base R 使用类型 I 错误作为默认。在进行简单的方差分析时,I 型误差不是问题。但是,如果我们试图运行 ANCOVA,I 类错误将导致错误的结果,我们需要使用 III 类错误。如果你对什么是 I 型和 III 型错误感兴趣,我可以推荐安迪·菲尔德的书《使用 R 发现统计数据》第 457 页底部的简·超级大脑部分

因此,我们需要使用不同包中的另一个函数来指定我们希望使用的错误的确切类型。我们将使用赛车套件。运行下面的命令来安装汽车包,如果你还没有安装的话。它和上面 Levene 的测试是同一个包,所以如果你从一开始就遵循教程,你可能不需要安装和加载这个包。如果您不确定,为了安全起见,只需运行这些命令。

install.packages("car")

然后加载包。

library(car)

然后,在我们的 fit2 对象上运行 car Anova 命令,指定我们希望使用类型 III 错误。

Anova(fit2, type="III")

这会产生以下输出:

正如您在我们的行物种、Pr( > F)、即 p 值中所看到的,物种仍然对花瓣的长度有显著影响,即使在控制萼片的长度时也是如此。这可能意味着花朵确实有不同的比例,并不是因为物种的不同而简单地变大或变小。

尝试在 fit2 对象上运行 summary 命令,查看 summary 命令产生的结果是否不正确;然而,如果您要通过 summary.lm 命令查看 fit2 对象,该命令以线性模型(即 OLS)的样式生成输出,并且还使用 III 类错误,您将在输出中获得与通过 Anova 命令从 car 包获得的相同的正确信息。

我们可以如下所示报告这一发现。

协变量,萼片长度,与花的花瓣长度显著相关,F(1,146)=194.95,p <.001. there="" was="" also="" a="" significant="" effect="" of="" the="" species="" plant="" on="" petal="" length="" after="" controlling="" for="" sepal="" f="" p=""/>

After completing either the ANOVA or ANCOVA, you should normally be running the appropriate post hoc tests to reveal more about the effects. After all, an ANOVA is merely an inferential test, i.e., it tests whether the data is distributed in a way that we would expect if the distribution were random. So far, we only know that there is a relationship between species and sepal length —we know that sepal length is non-randomly distributed when grouped by species. However, how exactly does species influence sepal length? One way of achieving this is by breaking down the variance explained by the independent variable of interest into its components . You可以在我关于计划对比的文章中了解更多信息。

在 R 中做并报告您的第一个中介分析

原文:https://towardsdatascience.com/doing-and-reporting-your-first-mediation-analysis-in-r-2fe423b92171?source=collection_archive---------0-----------------------

如何测试和报告介导效应

本教程将解释什么是调解分析,展示如何为调解分析模拟数据,运行必要的统计程序,并撰写报告以供发表。
简介将关注于建立冥想到底是什么。如果你知道什么是中介,只是想知道如何在 R 中实现它,那么跳到“第一步:总体效果”这一章。

中介听起来可能很有挑战性,但实际上很简单。中介效应也称为间接效应。当自变量对因变量的影响——顾名思义——被另一个变量(中介变量)调节时,就会发生这种情况。

考虑调解时,一些重要的注意事项是:

  • 介体必须是内源性的:这意味着介体不能是治疗或研究条件。介体本身必须依赖于外生变量,这些变量通常是实验研究中的治疗或研究条件。
  • 调解人必须揭示更多关于自变量如何影响因变量的见解:调解人揭示关于过程的一些情况。

因此,中介帮助我们找出自变量如何影响因变量。通过运行中介分析,我们正在测试关于自变量如何影响因变量的过程的假设。

得出一个中介效应

对于本文,我们将模拟数据。我相信模拟数据确实有助于弄清楚我们正在分析的数据中发生了什么。数据将基于经典的“iris”数据集,该数据集包含在 base R 中。另外,同时设置样本种子,这样你的随机数生成器的结果就会和这里的一样。

df=iris
set.seed(12334)

iris 数据集包含 5 个变量和 150 个观察值。这 5 个变量是萼片的长度和宽度,花瓣的长度和宽度,以及鸢尾花的种类。

Photo by Lukas Blazek on Unsplash

在这篇文章中,我们将假设花瓣的长度影响花朵被蜜蜂授粉的可能性。然而,这种影响不会是直接的,而是通过开花对蜜蜂的吸引力来调节的。因此,我们的假设是萼片长度对蜜蜂通过花朵的吸引力授粉的可能性有间接影响。

只有萼片长度是包含在虹膜数据集中的变量。剩余的两个变量将被模拟。所以下一步,让我们模拟数据。

模拟中介的数据

模拟有一个很好的副作用,你可以直接看到数据中发生了什么。这可以提高你对统计结果的直观理解。

首先,让我们模拟一下中介,“对蜜蜂的吸引力。”这个变量将被命名为 mediator ,在我们的例子中,它将由两部分组成。其价值的 35%是萼片。长度+其值的 65%是随机噪声。想象一下,变量“对蜜蜂的吸引力”中的随机噪声可能是其他特定于花朵的属性,如颜色、形状、气味等。

df$random1=runif(nrow(df),min=min(df$Sepal.Length),max=max(df$Sepal.Length))df$mediator=df$Sepal.Length*0.35+df$random1*0.65

其次,让我们模拟因变量,“被蜜蜂授粉的可能性。”这个变量将被命名为 dv 并再次由两部分组成。其值的 35%是介体,+ 65%是随机噪声。在我们的例子中,随机噪声可以是非植物特有的属性,如花的位置、天气条件、土壤等。

df$random2=runif(nrow(df),min=min(df$mediator),max=max(df$mediator))df$dv=df$mediator*0.35+df$random2*0.65

现在,“萼片长度”中包含的大约 12%(准确地说是 12.25%)的信息应该包含在因变量“被蜜蜂授粉的可能性”(as 35% × 35% = 12.25%)中。这是我们预期的总效果。由于因变量包含了中介“开花对蜜蜂的吸引力”中 35%的信息,因此通过中介的间接效应将“强于”直接效应这正是中介分析所显示的。

如何用统计程序为调解提供支持

我们将在中介分析的帮助下,通过四个简单的步骤为中介提供统计支持。

  • 首先,我们将测试总体效果。这里我们正在观察萼片长度的任何变化是否会影响 DV。稍后将详细介绍。
  • 其次,我们将测试自变量对中介的影响。萼片长度对调解的显著影响是调解成为可能的绝对先决条件。
  • 第三,我们将同时检验中介变量和自变量对因变量的影响。这是当橡胶碰到路面时,所有的东西都聚集在一起。
  • 第四,也是最后一点,我们将为因果中介分析估计各种数量,这意味着我们将比较直接和间接影响,让我们对数据中发生的事情有更多的了解。

The four steps of mediation analysis.

第一步:整体效果

总效应描述自变量(iv) 萼片长度对因变量(dv) 被蜜蜂授粉的可能性的总效应。基本上,我们想了解这两个变量之间是否有关系。对于这种关系是否需要对调解产生重要影响,有两种观点:

  • 第一种观点认为两者之间必然存在着重要的关系。否则,即使有显著的间接影响,我们也不能肯定地说改变 iv(在我们的例子中是萼片长度)对 dv(被蜜蜂授粉的可能性)有任何影响。然而,这个学派正在慢慢地让位于第二个学派。
  • 第二种观点认为静脉注射和家庭暴力之间不一定有显著的关系。正如相关性不能证明因果关系一样,没有相关性也不能否定因果关系。海斯 2018,第 80 页。一个同样有道理的论点。

总之,你不需要有显著的总体效果,但是有一个绝对没有坏处。如果有疑问,和你的合著者谈谈,因为我的经验是这是一个高度个人化的决定。并希望你的最终审稿人同意你和你的合著者的观点。

幸运的是,在我们的例子中,当我们模拟数据时,我们将有一个显著的总效应。因此,我们开始运行一个简单的线性回归到 dv 加上任何协变量(在我们的例子中没有)。

fit.totaleffect=lm(dv~Sepal.Length,df)
summary(fit.totaleffect)

这将产生以下结果。正如你所看到的,萼片长度对我们的 dv 的总影响是显著的(p <.05 and="" the="" coefficient="" is="" very="" close="" to="" expected="" from="" above=""/>

If the output you receive differs from the one below (e.g., the coefficients differ), you might have set a different random seed (see above) or have set no random seed at all. This seed introduces some predictability to the randomness. You can remedy this by setting the random seed above and re-simulating the data.

So now we have a significant total effect. Let’s proceed to step 2.

Step #2: The effect of the IV onto the mediator

To establish any mediation, the independent variable (iv, “sepal length” in our case) must significantly affect the mediator. This makes sense, as, for a mediation to take place, the iv must significantly impact the mediator.

So we do another simple linear regression of the iv onto the mediator plus any covariates you might have this time (none in our case).

fit.mediator=lm(mediator~Sepal.Length,df)
summary(fit.mediator)

This will yield the following results below. As you can see, the total effect of sepal length on our dv is significant (p<.05 and="" the="" coefficient="" is="" close="" to="" expected="" from="" above.=""/>

Now we have a significant effect of the independent variable “sepal length” onto the mediator “attractiveness of the bloom to the bee.”

Step #3: The effect of the mediator on the dependent variable

The third step confirms that the mediator affects the dependent variable,同时控制自变量。这意味着,为了进行调解,调解人必须解释因变量中比自变量更多或其他部分的方差。

因此,我们做一个简单的线性回归,将自变量和中介变量回归到因变量,再加上这次可能有的任何协变量(在我们的例子中没有)。

fit.dv=lm(dv~Sepal.Length+mediator,df)
summary(fit.dv)

这会产生以下输出:

请注意该输出的几个方面:

  • 中介物有显著的影响(p <.05 on="" the="" dv.="" with="" result="" from="" step="" we="" can="" now="" already="" say="" that="" there="" is="" a="" mediation.="" again="" coefficient="" very="" close="" to="" expected=""/>
  • Whereas sepal length was a significant predictor of the dv “likelihood of pollination” before, it is no longer. In our data simulation, we included all the information of the IV that was contained in the DV also in the mediator, so this is not unexpected. In such cases, we speak of a “complete mediation.” This means that the total effect of the IV on the DV is explained by the mediator. In our case, it means that the total effect of “sepal length” onto “likelihood to be pollinated by a bee”)通过“花朵对蜜蜂的吸引力”中介分析有助于我们更好地理解 iv 对 dv 的作用过程。
    如果 IV 仍然是重要的,我们会说“不完全调解”,这也是完全可以的。不完全的调解意味着静脉注射对静脉注射的另一种影响,这种影响不通过调解人。

从统计学上来说,我们有所有的支持来假设数据中的中介。但是,在一个模型中计算整个模型是一种很好的做法。中介是一个迷你结构方程模型(SEM ),所以如果我们愿意,我们可以使用 SEM-packages for R,比如“lavaan ”,来估计整个中介。然而,这将是相当复杂的。谢天谢地,有更简单的方法来完成这项工作。这就是第四步的内容。

步骤 4:因果中介分析

让我们加载必要的 R 包。

#install.packages("mediation") #uncomment this command in case you haven't installed the mediation package yet.
library(mediation)

这将加载(并安装)中介包,它采用我们刚刚估计的回归模型,组合它们并估计整个中介。因此,让我们运行命令。

results = mediate(fit.mediator, fit.dv, treat='Sepal.Length', mediator='mediator', boot=T)

来自中介包的中介函数请求我们刚刚估计的模型,然后要求我们指定作为处理的变量、即我们的自变量和作为中介的变量。此外,我们需要指定 boot=T ,因为默认情况下, mediate 将对置信区间使用准贝叶斯*似。然而,我们想要报告百分位数的置信区间,所以我们将其设置为 T 为真。这个命令需要一些时间来运行,但不会产生任何输出。要获得输出,我们需要运行下面的命令。

summary(results)

这会产生以下输出:

这些缩写可能有些吓人,但它们的意思是:

  • ACME 代表*均因果中介效应。这是 IV(萼片长度)通过媒介(对蜜蜂的吸引力)对 DV(授粉可能性)的间接影响。请注意,它估计这种影响为 0.11——这正好是 0.30(步骤#2 中 IV 对介质的影响)乘以 0.37(步骤#3 中介质对 DV 的影响)——因此不一定是新信息。然而,新的是,我们现在有了整个间接效应的置信区间和显著性水*,而不仅仅是它的两个单独部分。这是我们报告中介所需要的。
  • ADE 代表*均直接效果。它描述了静脉注射对静脉注射的直接影响。再说一遍,这不是新信息。我们已经在步骤 3 中计算了这种影响:当控制介体时,静脉对静脉的直接影响。
  • 总效应代表 IV 对 DV 的总效应(直接+间接)。这也不是新信息。我们在第一步中计算了这一点。我们也可以通过简单地将 ACME (.1132)和 ADE (.0167)相加得到. 1298 的总效果。我们也已经知道,从第一步开始,总的效果是显著的。
  • 道具。中介描述了静脉注射对通过中介的静脉注射的影响比例。计算方法是将顶点(. 113)除以总效果(. 13)得到 0.87。这条信息是一个很好的花絮,但不一定是我们感兴趣的焦点。

你看,我们在这最后一步没有学到很多新东西。然而,我们现在已经获得了报告中介所需的所有信息。

报告调解

我们计算的中介可以按以下方式报告:

Figure 1

萼片长度对授粉可能性的影响完全是通过花的吸引力来调节的。如图 1 所示,萼片长度和授粉可能性之间的回归系数以及吸引力和授粉可能性之间的回归系数是显著的。间接效应为(. 30)*(.37) = .11。我们使用自举程序测试了这种间接影响的显著性。对 1000 个自举样本中的每一个样本计算非标准化的间接效应,并通过确定第 2.5 和 97.5 百分位的间接效应来计算 95%的置信区间。自举非标准化间接效应为. 11,95%置信区间为. 06 到. 17。因此,间接效应具有统计学意义(p<.001/>

该图的系数取自步骤#1 到#3 中的不同模型。大部分文本信息来自中介函数的结果(第 4 步)。我们之前忽略了它,但中介函数确实执行引导,即,它使用从数据中随机抽取的子样本重新计算模型 1000 次。这样做是为了对我们的结果更有信心。

以正确的方式处理数据

原文:https://towardsdatascience.com/doing-data-the-right-way-dbf5ba658177?source=collection_archive---------17-----------------------

数据科学的伦理

(from: robynmac on Depositphotos)

当我学习如何从网上搜集数据时,我第一次想到了数据科学中的伦理概念。刚刚配备了能够轻松捕获和存储任何仅仅是在线打印的信息的能力,我正享受着仅仅为了它而抓取不同网站的乐趣。然后,在尝试搜索 Reddit 时,我收到了这条消息:

whoa there, pardner!

网页抓取虽然繁琐却是一个强大的工具。像 Reddit 这样更大的网站有类似上面的措施来阻止我们一次获得太多的信息。看着上面的信息,我们仍然可以获得这些信息,只是不是一下子。网络抓取是我们作为数据科学家最先学会的事情之一,在我涉足数据科学领域的一个月内,我就有能力在线存储写在任何网页上的几乎任何信息。权力越大,责任越大。肯定有一些人会滥用他们的网络抓取能力来作恶。

我们生活在一个信息时代,这里存在着大量的数据,并且这些数据还在不断产生。信息现在是生活和社会不可或缺的一部分,随之而来的是需要知道如何管理它。电气和电子工程师协会(IEEE)实际上在 1999 年发布了软件工程道德规范,概述了软件工程师应该遵守的 8 项原则“符合他们对公众健康、安全和福利的承诺。”道德规范为软件工程师的行为和决策提供了指南,并且(简单地说)非常实用。例如,第一条原则规定“软件工程师的行为应该与公众利益一致。”下面的原则也符合做好事和最大化软件产出的好处的路线。

数据科学是一个比软件工程还要新的领域。2018 年,我们看到了剑桥分析/脸书崩溃和欧盟实施通用数据保护法规 ( GDPR )等事件,这两者都与大数据以及如何处理我们在线信息有关。大数据不可避免地会对世界和我们的社会产生巨大影响,因此我们(作为数据科学家)必须对我们正在做的任何事情的道德影响有所认识。

所以…什么是对的?怎么了?

silicon Republic上发表的一篇文章质疑为什么数据科学家没有接受道德培训。文章一开始就提出了一系列与道德相关的问题,比如:我们能卖什么?我们可以得到这些信息吗?“问 20 个数据科学家这些问题,你会得到 20 个不同的答案。”

由于该行业还处于起步阶段,对于什么是正确的还没有达成社会共识。此外,在数据科学过程中,有许多阶段会涉及不同的伦理问题。我在两个广泛的领域探索数据科学的伦理:数据收集有效性。这不是在任何情况下做什么的答案,而是探索如何将伦理应用于数据科学,以及我们如何以正确的方式实践数据科学。

在开始之前,我想声明这篇文章中的很多内容都是基于网上研究的。我的一个主要资源是密歇根大学 Jagadish 教授在 Coursera 上的 数据科学伦理课程。

数据收集

对于一项数据科学任务,流程的第一个一般阶段是收集和清理数据。出现了许多伦理争议,比如我遇到的网络抓取。这里有一个关于数据收集道德的问题:如果我给你拍了一张照片,这张照片是不是因为我拍的而属于我?或者既然照片的主体是你,那这张照片是属于你的吗?

这个基本的例子已经引出了两个在数据科学伦理领域越来越受关注的主要概念:知情同意数据所有权

知情同意的概念来自医学研究领域,在这一领域,患者必须在接受治疗前了解治疗的全部风险。更相关的是,知情同意发生在研究对象必须知道他们正在被研究的时候。这似乎是显而易见的,不是吗?如果你正在参加某个临床试验,你会知道你是这个试验的一部分,对于研究人员来说,随机给人用药来测试某种治疗的有效性是完全不道德的。现在将这个概念应用于数据科学。许多企业基于 A/B 测试做出决策。A/B 测试对受试者的影响可能不如测试抗癌药物,但它也是一种实验。

这里有几个现实生活中的例子可以考虑。2014 年,在一项与康乃尔大学和加州大学旧金山分校联合进行的关于情绪传染的研究中,脸书被揭露操纵用户的新闻推送。他们想知道在他们的订阅源上看到更多正面帖子的用户是否会发布更多正面帖子,以及看到更多负面帖子的用户是否会发布更多负面帖子。他们得出结论,情绪传染是显而易见的,但当公众发现脸书不仅操纵他们看到的内容,而且还使用他们的新闻订阅和帖子上的信息进行研究时,大多数人都感到愤怒。快速的谷歌搜索发现了许多抨击脸书滥用用户数据的文章,特别是因为这个实验操纵了用户的情绪。然而,脸书声称,在他们的实验中使用数据符合他们的数据使用政策,用户在创建他们的脸书账户之前已经同意并接受了该政策。

同年, OkCupid 出来说,他们在一项实验中也操纵了呈现给用户的信息,以观察被告知他们是兼容的是否会影响真正的兼容性。OkCupid 基本上告诉不相容的夫妇他们是相容的,反之亦然,以观察报告的相容性分数是否重要。我引用莫莉·伍德在《纽约时报》上发表的一篇关于这个实验的文章:

OKCupid 的用户协议说,当一个人注册该网站时,个人数据可能会用于研究和分析。

“我们告诉用户一些不真实的东西。我绝对没有隐瞒这个事实,”OKCupid 的总裁鲁德尔先生说。但他说,测试是为了确定人们如何从网站上获得最大收益。“人们来找我们,是因为他们希望网站能够运行,而我们也希望网站能够运行。”

与脸书的失败类似,他们声称知情同意是因为用户在注册服务时达成的协议。在不同的网站注册时,我们盲目同意了多少这样的协议?这算不算知情同意?

数据所有权有些相关。在数据科学中,数据属于记录它的人。因此,在照片示例中,约定将规定照片属于我。作为数据科学家,我们通常获取和处理现有数据——我们不是进行调查和发布表格的人。数据的所有权现在变得更加复杂了。在知识产权方面,我们正在处理记录数据的衍生产品,因为我们从一个地方获得数据,对其进行管理和收集,然后为我们的研究进行清理和验证。因为在整个清理过程中投入了如此多的精力,而且从技术上来说,因为我们是这些新数据的记录者,所以这些清理过的数据集属于我们吗?

普遍的共识是,在我们使用这些数据之前,我们必须得到发布这些数据的人的许可。但是如果我们从产品评论上获取信息呢?我们必须得到每个留下评论的人的许可。这就是为什么像亚马逊或易贝这样的在线网站在他们的用户协议中有某种条款,规定无论用户在他们的网站上发布什么,公司都可以使用。因此,如果我们是亚马逊的数据科学家,我们可以在伦理上使用他们的产品评论数据。这是与 GDPR 相关的数据科学道德领域——一种保护互联网用户数据不被公司处理的措施。对许多公司来说,数据是一种资产。尤其是在技术领域,数据推动他们做出决策,一般来说,数据越多越好。

GDPR 是政府监管用户数据所有权和使用的首批重大举措之一,它以某种方式影响了每一家有网络业务的公司。这也暴露了数据所有权这一复杂领域中的许多灰色地带。

有效性:在数据、处理和模型中

有效性可以在数据科学过程的不同点进行评估。我粗略地简化了过程,并解决了三个主要的争论点:数据的有效性、处理的有效性和模型的有效性。从伦理上评估数据科学过程的有效性是主观的。谁来说什么是对的,什么是错的?当然有比其他方法更好的方法,但是关于处理数据的正确方法还没有一个行业标准。没有关于如何确保收集的数据符合某种标准的指南。

首先,在我看来,作为数据科学家,我们有责任尽最大能力验证我们正在处理的数据是有效的;或者至少,我们应该将数据放在上下文中,并向决策者概述其局限性。决策者应该在最大程度上了解从数据和我们创建的模型中得出的结论所处的环境。在评估数据的有效性时,我会考虑以下几个问题(绝对不是详尽的列表):

  • 数据是否代表了您想要捕捉的内容?会不会是来自将要得出结论的人群中的某个特定子集?我认为 Jagadish 课程中的一个例子很好地描述了这一点:使用来自 Twitter feeds 的数据来代表公众意见。Twitter 用户普遍倾向于更年轻、更富有。
  • 数据有多永恒?随着时间的推移,你用于预测/模型的数据会有相关性吗?如果没有,是否有措施防止模型过时是否有一个已知的模型使用截止点?例如,SAT 的得分是 2400 分,直到 2016 年,随着阅读和写作部分的合并,它变成了 1600 分。我们应该知道大学用来评估整体分数的标准分数转换,或者如果我们评估阅读/写作能力,考虑各部分的合并。

我们有很多方法可以处理数据。当我们处理表格和数据帧中的NaN值时,我们可以采取许多不同的方法,从而产生不同的结果。无论是删除行、用*均值或中值替换空值还是从相邻数据点进行插值,都有一般的最佳实践,但没有硬性的标准规则。什么是最好的方法也取决于学习的背景。由于这是如此主观,需要如此多的背景,我在这里能做的最好的就是推荐功利主义的方法——选择任何你认为最有意义的方法;你认为最大化效用的任何方法。

模型有效性与我们讨论的非常相似。我们只是想确保无论在什么情况下,我们都在尽最大努力产生最好的结果。在技术层面上,我们希望验证我们的模型,以便它最适合我们拥有的任何场景。这就是为什么我们有不同的评估系统和测试分数——来看看我们的模型表现如何。提出一个不准确的模型来做预测或决策是非常不道德的,尤其是如果它可以改进的话。我认为,作为一名数据科学家,负责任的做法是不断测试你的模型。是过拟合还是欠拟合数据?设计的功能有意义吗?模型容易改变吗?

我发现软件工程道德准则中有三个条款与数据科学的这个方面相关:

软件工程师应确保他们的产品和相关的修改符合最高的专业标准。

软件工程师应保持其专业判断的完整性和独立性。

软件工程经理和领导者应认同并促进软件开发和维护管理的道德方法。

(摘自 IEEE 的软件工程道德准则)

到结束掉,我们来深入一下。想象一下,我们正试图训练一个人工智能像人类一样行动。在监督学习算法中,目标是优化一些目标函数。现在我们如何定义人类的目标函数?这个人工智能会有什么样的道德?不管是谁负责定义这个目标函数,他基本上都有权力定义,至少对这个人工智能来说,定义“理想人类”。

电车难题及其变种,是经典的伦理思想实验之一。随着自动驾驶汽车的出现,这种思想实验现在变成了现实。如果一辆自动驾驶汽车将要撞上一些行人,汽车是否应该突然转向,从而有可能杀死司机?还是汽车应该饶了司机,害死行人?

NPR 的 Laurel Wamsley 写道 自动驾驶汽车应该有伦理吗?2018 年 10 月。这篇文章着眼于在线向人们提出的 Trolly 问题变体的结果。 (可以看到这里提出的问题!—在“判断”标签下) 研究发现,人们的答案会因他们来自哪里而有所不同。因此,对于在每种情况下什么是正确的,还没有达成共识。这项电车问题研究的作者写道:

“在我们允许我们的汽车做出道德决定之前,我们需要进行一次全球对话,向设计道德算法的公司和监管它们的决策者表达我们的偏好。”

随着人工智能成为社会越来越重要的一部分,规则将开始形成。我们非常幸运能够见证该行业的发展,并有可能作为数据科学家为其做出贡献。我希望,作为数据科学家,我们要确保把我们的力量用在好的方面。

TL;博士:尽你所能做正确的事情。

想法?给我留个评论@Yish Lim和大家说说吧。

用机器学习做有意义的工作——对灾难信息进行分类

原文:https://towardsdatascience.com/doing-meaningful-work-with-machine-learning-classify-disaster-messages-436bfe9ec42?source=collection_archive---------23-----------------------

建立模型,帮助救灾组织拯救人们的生命。

I’m writing this post at 1am in Bucharest, Romania.

又见面了。欢迎来到我的第四篇关于机器学习的内容。我最*做了一个我认为对社会有意义的项目。我将简要概述这是怎么回事,然后马上深入代码:)

在这个项目中,我应用数据工程技术创建了一个 API(应用程序编程接口),将来自各种来源(Twitter,文本消息)的灾难消息分为 36 类。这种分类问题是一种受监督的机器学习,因为模型根据对提供给它的数据的学习来学习对结果进行分类。即信息与什么相关:水、食物、住所、金钱等。?原因是当灾难发生时,有数百万条消息被发送和推文告知。然而,灾难由不同的组织负责。食物供应可能由某个组织提供,而灭火则由另一个组织负责。因此,该应用程序的用途是将这些消息分类成各种类型,以便可以理解对于特定的灾难需要哪种类型的援助。

项目结构

该项目有三个部分:

  1. ETL 管道
    提取、转换、加载数据。这与处理数据有关。也就是说,我加载、合并和清理了消息和类别数据集。我存储到 SQLite 数据库中,以便模型可以在下一步中使用它进行训练。
  2. ML 流水线
    机器学习流水线与训练模型和测试模型有关。管道包括一个文本处理部分,因为它处理开头提到的文本源。我还使用 GridSearchCV 进一步调优模型,并将其保存为 pickle 文件。
  3. Flask Web App
    run.py``process_data``train_classifier基本就是终端工作空间包含的 ETL 管道和 ML 管道,让 App 工作。

ETL 管道

在项目的第一部分,我的目的是提取我需要的数据,进行必要的转换,以便我可以在以后的算法构建中使用它。一旦我看到了我需要的两个数据集:T3 和 T4,我就使用公共 id 合并这两个数据集。

*# merge data sets* 
df = messages.merge(categories, on = [‘id’]) 
df.head()

然后,我将类别分成单独的类别列,并为每一列指定了单独的类别名称。

*# create a dataframe of the 36 individual category columns*
categories = df['categories'].str.split(';', expand = **True**)row = categories.head(1)category_colnames = row.applymap(**lambda** x: x[:-2]).iloc[0, :].tolist()*# rename the columns of `categories`*
categories.columns = category_colnames
categories.head()

因为模型使用数字作为输入,所以我将类别值转换为数字 0 或 1。

**for** column **in** categories:
    *# set each value to be the last character of the string*
    categories[column] = categories[column].astype(str).str[-1]

    *# convert column from string to numeric*
    categories[column] = categories[column].astype(int)
categories.head()

转换类别列后,我对数据框进行了更改。我用新的类别列替换了原来的类别列。

*# drop the original categories column from `df`*
df.drop('categories', axis = 1, inplace = **True**)*# concatenate the original dataframe with the new `categories` dataframe* df = pd.concat([df, categories], axis = 1) df.head()

在检查了数据中的重复项后,我删除了它们。

*# check number of duplicates*
df[df.duplicated].shape(170, 40)*# drop duplicates* 
df.drop_duplicates(inplace = **True**)*# check number of duplicates* 
df[df.duplicated].count()

我最终将干净的数据集保存到 SQLite 数据库中。

*# Save the clean dataset into a sqlite database.*
engine = create_engine('sqlite:///disaster.db')
df.to_sql('messages_disaster', engine, index=**False**)

ML 管道

在项目的第二部分,我创建了机器学习管道,用于将灾难信息分类成不同的类别。被称为“管道”的原因是因为这个建模工具由几个步骤组成,这些步骤处理输入以生成输出。在这种情况下,我使用标记化来处理文本数据。

*# load data from database*
engine = create_engine('sqlite:///disaster.db')
df = pd.read_sql_table('messages_disaster', con = engine)X = df['message']  
Y = df.drop(['message', 'genre', 'id', 'original'], axis = 1)*# Tokenization function to process text data.*
**def** tokenize(text):
    tokens = word_tokenize(text)
    lemmatizer = WordNetLemmatizer()
    clean_tokens = []
    **for** tok **in** clean_tokens:
        clean_tok = lemmatizer.lemmatize(tok).lower().strip()
        clean_tokens.append(clean_tok)
    **return** clean_tokens

机器学习管道将在数据集中的 36 个类别上以message列作为输入和输出分类。这是一个自然语言处理的问题;即对文本进行处理,从信息中提取含义。是不是很神奇?

pipeline = Pipeline([
    ('vect', CountVectorizer()),
    ('tfidf', TfidfTransformer()),
    ('clf', MultiOutputClassifier(RandomForestClassifier()))
])

就像所有其他 ML 模型一样,我们必须有训练和测试集。原因是我们不希望我们的模型在训练集上表现得非常好,同时在看到新数据时不能正确地对我们的类别进行分类。因此,我们必须只使用数据的子集来训练它,并观察它在测试集上的表现。

*# Split data into train and test tests.*
X_train, X_test, y_train, y_test = train_test_split(X,Y, test_size = 0.2, random_state = 45)*# Train the model.*
pipeline.fit(X_train, y_train)

在测试我的模型时,我希望有一些客观的性能指标。即我会看 f1 分数精度和召回。

*# Test the model and print the classification report for each of the 36 categories.*
**def** performance(model, X_test, y_test):
    y_pred = model.predict(X_test)
    **for** i, col **in** enumerate(y_test):
        print(col)
        print(classification_report(y_test[col], y_pred[:, i]))performance(pipeline, X_test, y_test)

just a snapshot

在建立模型时,寻求改进总是一个好主意。尝试调整模型的参数以获得更好的结果。这就是我在这里尝试的。这是相同的过程,但有不同的管道。

*# Improve the pipeline.*
pipeline2 = Pipeline([
    ('vect', CountVectorizer()),
    ('best', TruncatedSVD()),
    ('tfidf', TfidfTransformer()),
    ('clf', MultiOutputClassifier(AdaBoostClassifier()))
])*# Train the adjusted pipeline.* 
pipeline2.fit(X_train, y_train)# Check the performance of the adjusted model.
performance(pipeline2, X_test, y_test)

我更进一步,使用了一组不同的参数和一定范围的值。在 GridSearchCV 的帮助下,模型选择最佳参数。

parameters2 = { 
              'tfidf__use_idf': (**True**, **False**), 
              'clf__estimator__n_estimators': [50, 100],
              'clf__estimator__learning_rate': [1,2] }cv2 = GridSearchCV(pipeline2, param_grid=parameters2)cv2.fit(X_train, y_train)performance(cv2, X_test, y_test)

构建 API

最后,我以制作一个 API 来结束这个项目,这个 API 接收一条灾难消息,并将其分类为最可能的灾难类别。这样,我们可以帮助救灾组织更好地了解发生了什么类型的灾难,以及需要哪种援助。

结束语

如果你做到了这一步,非常感谢你的阅读!希望这能让你了解机器学习有多有用。以及它的应用范围有多广。通过了解如何处理文本数据和实现模型,我们可以真正挽救人们的生命。说到模型,这是我的 github 上的完整项目。

祝你一切顺利,永远幸福:)

附:我们来连线一下 Linkedin

做得更好

原文:https://towardsdatascience.com/doing-yelp-better-fdc11c20362a?source=collection_archive---------18-----------------------

Mu Ramen’s Harlan Burger

使用 Vader 和 LDA 为餐厅提供量化指标。

编辑:更新应用程序,包括好的和坏的评论快照。

欢迎来到我称之为 Yelp 成绩单的项目。在这个项目中,我的目标是为 Yelp 目前的企业所有者服务提供商业增值。使用 NLTK 的 Vader 情绪分析并结合 Genism 的 LDA 库,我为餐馆创建了一个量化的报告卡,以确定他们做得好的地方,以及他们可以改进的地方。

要直接跳到应用程序,点击此处。

商业案例

Yelp 很可能是世界上最大的本地商业评论网站,涵盖了从医生办公室到清洁服务的各种业务。然而,Yelp 的核心是一个众包评论网站,通过在其数据库中征集用户生成的餐厅内容,使餐厅评论过程民主化,并为世界各地的餐厅带来更多曝光率。

随着时间的推移,Yelp 作为一种餐厅信息资源的流行导致了数百万点数据的产生。这在一定程度上稀释了 Yelp 对一家餐馆的评论的影响,并导致餐馆老板的一些不满。以下是导致企业主对 Yelp 不满的诸多因素中的 3 个。

1.大数定律

由于评论的绝对数量,每一个进入餐厅的评论最终都会稳定他们的评级。它永远停留在那里,通常是 4。在这一点上,大多数餐厅争取 4 分,只有像 Le Bernadin(米其林三星)这样真正最好的餐厅才能得到 4.5 分。获得 5 星评价的餐厅通常是较新的餐厅,评价不到 30 个,许多厨师认为这些评价大多来自餐厅的朋友。你可以在下图中看到评论的分布。假设 1 星和 2 星餐馆通常会关门,但我可以向你保证,我在当地的中国外卖店一如既往地开放和繁忙。这也可能是因为 Yelp 的 API 给我的餐馆提供了更高的评论数。

2.极度波动

Yelp 是人们以某种方式回应的指定场所,这导致了大量的赞美,或愤怒的被动攻击内容。第一次或第一千次使用 Yelp 的人通常会受到极端体验的激励,无论是积极的还是消极的,因此他们的评论往往会反映这些体验,而不会考虑用餐体验的其余部分。

3.代表性差

如上所述,由于对单一问题的关注,我们看到了大量正面和负面的评论,这些评论不能正确反映整个用餐体验。这些不是我们通常期待的评论,指出了积极和不足之处。因此,许多餐厅看到很多 5 星或 1 星的评论,他们觉得这是不*衡的,影响了他们的总分。

这个问题

鉴于我们已经确定了许多餐厅在处理在线评论时面临的一些问题,Yelp 是否有办法为这些餐厅增加价值并提供可行的反馈?

Yelp 拥有数百万条用户评论,使用 NLP,我们可以获得这些数据,并为一家餐厅提供全面的量化指标,而不必花费数小时手工整理评论。使用这一指标,餐馆可以发现问题并努力改善他们的业务。

该过程

创建这些指标的过程非常简单,如下图所示:

步骤 1:收集数据

使用 Yelp 的 API,我获得了信息,更重要的是,获得了给定行政区中每个餐馆的餐馆 id。这为我提供了一个包含 1000 个餐馆 id 的列表,然后我可以用它来抓取 5 页或者至少 100 个有这么多评论的餐馆的评论。有的餐厅 scraped 没有 100 条评论,有的餐厅由于用户更新评论,评论超过了 100 条。这些更新的评论有些是正面的,有些是负面的。

最终统计如下:

曼哈顿:115,588 条评论

皇后区:94301 条评论

布鲁克林:100,166 条评论

斯塔滕岛:51,490 条评论

布朗克斯:59150 条评论

斯塔滕岛和布朗克斯区是 Yelp 上回应最少的。我相信这与我的信念有关(在此讨论),大多数人倾向于不离开 Yelp 评论,除非他们有一次重要的用餐经历。这些餐馆位于本土,为居民提供日常膳食,因此在 Yelp 上很大程度上被当地人忽略了。在曼哈顿用餐被广泛认为是一种体验,或者特殊场合,因此更有可能在 Yelp 上获得回应。此外,我咨询了当地的斯塔滕岛专家,得知可能由于斯塔滕岛主要是住宅区,大多数居民要么开车过桥去布鲁克林享受独特的餐饮体验,要么呆在家里吃饭。这可能是斯塔滕岛回复率低的原因之一。

第二步:维德

收集数据后,我采取的第一步是通过 NLTK 的维德情绪分析运行数据。Vader 是一个使用起来极其简单的库,是在 Twitter 数据上训练出来的。因此,它不需要太多的数据准备,因为像标点符号,大写字母和随机停用词这样的东西可以帮助它确定情感得分。

我没有关注评论中给出的星级数,因为我觉得星级评定是任意的,而且没有指导原则。它仅仅代表了评论者有多疯狂或快乐,却没有为我们提供一个可衡量的标准来识别具体的问题。例如,三星级是模糊的,一个人可以称赞食物,但同时提到 2-3 件他们不满意的事情。

Vader 是使用一个简单的 lambda 函数完成的,该函数为每个评论返回一组 4 个分数,一个正面、中性、负面和复合分数。复合得分是我们所关注的,其范围从-1 到 1,反映了从负到正的情况。由于人们通常在 Yelp 上看到的回复的性质,分布有点不*衡。下图是*均复合情感得分频率的样本。

正如我们所见,积极情绪的评论比消极情绪的多。没关系。只要我们在这个公认的框架内工作,我们就能理解最终的分数。

对于那些不熟悉维德的人来说,下面是我们一些被“维德化”的餐厅评论的快照:

为了说明 Vader 情绪分析是如何工作的,下面是*均复合得分最高的餐厅 Fish checks(. 945)和最低的餐厅 Di Fara Pizza (.511)的样本评论。

Fish Cheeks

Fish Cheeks

Di Fara Pizza

Di Fara PIzza

正如你所看到的,鱼颊餐厅的食物有很多最高级的词语,人们对它们赞不绝口。另一方面,对于纽约市最著名的比萨餐厅之一的迪法拉比萨,许多人对食物赞不绝口,但也对排队感到不满,因为等待一片比萨通常需要 45 分钟至 1.5 小时。这也增加了我关于星星太模糊的断言的分量。DiFara 的服务显然存在问题,但许多评论都是 5 星,事实上该餐厅的总体评分是 4 星。因此,在个人评论中使用星级系统会导致我们在识别服务问题以确定情绪时出现误报。

第三步:LDA

我们过程的下一步是使用潜在的狄利克雷分配。这是一个无监督的机器学习工具,它对我们的数据语料库(所有文本)进行采样,并试图导出共同的话题。我在提到服务的餐馆上训练这个模型,因为服务相关的评论只占我总数据的 30%。我指示 LDA 找出 15 个主题,因为服务在我的数据中没有得到充分体现,所以我至少要找出 2 个代表服务的主题,其余的我需要确保纽约市提供的各种美食得到充分体现。如果我的模型遇到一篇提到食物的评论,却没有发现它,那将是一个巨大的失败。

LDA 是一个详尽的过程,需要不断地调整和重新运行,以确保模型得到充分的训练。除了清理、词汇化和标记化之外,我还需要删除标准停用词库之外的大量停用词。最后,为了确保我的模型准备充分,我需要在每个区添加超过 1000 个额外的停用词。我添加到禁止列表中的单词包括所有与这个过程无关的词类,比如“兄弟”、“姐妹”、“史蒂夫”、“美味”、“也许”、“炸弹”和“美味”。我想确保包含以食物和服务为导向的词,但为了扩大服务的范围,一定要去掉与禁止列表服务相关的形容词。我最后的主题列表如下:

一旦主题列表最终确定,我就可以将该模型应用到我的所有评论中,并为每个评论的最高得分主题分配一个主题编号,如下所示:

第四步:组装

项目的最后一部分包括加载 Vader 和 LDA 数据帧,并编写一个函数来记录每个数据帧并创建一个分数。代码如下:

#df is topic modeled restaurant reviews dataframe
#vd is vaderized restaurant reviews dataframe
#maintaining index integrity is important for this function#establishing food vs service topics
food = [1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14]
service = [0, 8, 9]
#iterable
nums = [str(s+1) for s in range(139)] reportcard = []
for row in df[['restaurant_name']].itertuples():
    #these are inside to reset after each restaurant
    numreviews = 0
    badfood = 0
    goodfood = 0
    badservice = 0
    goodservice = 0
    for j in nums:
       #check for Nans
        if not np.isnan(df.iloc[row[0]]['lda_review_'+j]):
            #if integer version of topic number in this cell[0] is #in service
            if int(df.iloc[row[0]]['lda_review_'+j]) in service:
                #and if compound score is less than .5, add a point #to bad service
                if vd.iloc[row[0]]['compound'+j]<.5:
                    badservice +=1
                else:
                    #otherwise add a point to good service
                    goodservice +=1
            #if integer version of topic number in this cell[0] is #in food
            elif int(df.iloc[row[0]]['lda_review_'+j]) in food:
                #and if compound score is less than .5, add a point #to bad food
                if vd.iloc[row[0]]['compound'+j]<0.5:
                    badfood +=1
                #otherwise add a point to good food.
                else:
                    goodfood +=1
            else:
                #if all that fails, let me know what failed
                print(int(df.iloc[row[0]]['lda_review_'+j]))
            #track for number of reviews in each row for averaging #purposes
            numreviews += 1

    #append all this to a dictionary in the following fashion
    reportcard.append({'restaurant': row[1], 
                        'posfood_score': goodfood/numreviews, 
                        'negfood_score': badfood/numreviews,
                        'posservice_score': goodservice/numreviews, 
                        'negservice_score': badservice/numreviews})

最终结果存储在一个字典中,然后我们可以将其转换为 json 文件,并导出到其他应用程序中使用。我将评分汇总为总评论的百分比,这样我们就可以告诉餐馆:

“在留下评论的人中,60%的人说他们喜欢你的食物,但 30%的人说他们讨厌它。”

可以做进一步的提炼来简化分数,但我觉得这为餐馆老板提供了足够的快照来辨别随着时间的推移他们相对于基线的位置。

所有这些数据都放在一个 streamlit 前端包装器中,允许用户从下拉菜单中选择一家餐厅,并查看下面每家餐厅的得分:

此应用程序已通过以下链接成功上传到 Heroku。

https://desolate-ocean-14363.herokuapp.com/

结论

这个项目是一个有趣的练习,它将我对食物和餐馆的热情与我初露头角的数据科学技能结合了起来。也有一些宝贵的经验教训。我现在知道,LDA 不是我想在有限的时间框架内使用的模型,使用 TF-IDF 和使用机器学习分类器可能会更好地加快速度。在这种情况下,我使用 LDA,因为我想扩展我的能力,并冒险进入无监督学习。我也很喜欢 LDA 的易解释性,它给了我更大的控制微调模型的能力。最后,为了更好地将服务作为我的主题,我最终将 TF-IDF 与 LDA 结合使用。

这个项目的进一步扩展将包括回顾快照,以便餐厅老板可以获得他们可能想要解决的特定事件的样本,此外,它可能有助于他们更好地理解数据。此外,我想按区编制一份总体报告卡,以确定每个区是否有具体的不足之处。最后,我想进一步完善我的数据,并探究总体评分是否会受到这些主题的影响。

所有代码都在我的 Github 中。

在 Linkedin 上与我联系!

www.linkedin.com/in/hamilton-chang

Domo Arigato,Roboto 小姐

原文:https://towardsdatascience.com/domo-arigato-misses-roboto-661d262a2556?source=collection_archive---------36-----------------------

Edited. (Original Image Source: Photo by 🇸🇮 Janko Ferlič — @specialdaddy on Unsplash)

我和亚马逊 Echo 之间超级混乱的存在关系的故事

Don’t have time to read? Listen to a podcast of this episode.

当亚马逊在 2014 年第一次宣布 Echo 时,我把我的名字放在了等待订购世界上第一个纯语音控制的机器人助手的名单上。圣诞节前三天,Alexa(亚马逊 Echo 的名字)来到了我的家门口,就这样开始了我与一个机器人 AI 语音助手的第一段令人困惑的友谊。

I built this animation using PowerPoint.

嘿 Alexa,给我讲个笑话!

我不记得她的反应是什么,但我记得我对这款新设备非常兴奋,以至于我在 Reddit 上发布了 AMA(Ask Me Anything 的缩写)。标题是:我刚得到 Alexa,输入你想让我问她的问题!

第二天,Redditors 会给我发问题问,我会问 Alexa,我会用她的回答回复那些 Redditors。他们中的一些人可能是 Alexa 的工程师。他们问的问题给了复活节彩蛋答案,有点像从秘密菜单点菜(如果你有 Alexa,试着问她: Alexa,谁是最漂亮的?).那天,我在 Reddit 上获得了有史以来最高的 Karma(Karma 是 Reddit 上的一个积分系统,相当于脸书或 Twitter 上的赞)。谢谢你,阿利克夏。

不久之后,我开始购买智能灯泡和智能插座,所有的开关都由 Alexa 控制,因此,通过传递性(如果 A=B and B=C,那么 A=C),我的声音。与找到你的手机,解锁它,打开智能灯泡应用程序,然后用手指手动调节照明相比,这太方便了。虽然 Alexa 在我家里已经很方便了,但她在床上更好——我不再需要在睡觉前起床关灯。

人际关系

从用笑话逗我笑到与我周围的物理环境互动,Alexa 已经与我的日常生活交织在一起。当时,我没有意识到 Alexa 的潜在影响,因为我不会分析我所能获得的每一项新的令人兴奋的技术的哲学含义。当然,尽管如此,心理因素的存在是为了将它与大多数人过去交互过的其他工具区分开来。

在亚马逊 Echo 之前,还没有一款可以纯语音操作的主流设备。像 Google Home 这样的竞争产品直到多年后才进入市场。像 iPhone 的 Siri 这样的语音助手很容易获得,但语音交互是一个方便的——但很少使用的——选项。虽然 Siri 是一个伟大的想法(当我周围没有人的时候,我经常使用 Siri),但很难改变用户的行为。对于移动设备,命令是通过手指发出的。此外,我们喜欢保持电话互动的私密性——想象一下,当你在拥挤的火车上时,让 Siri 为你预订晚餐。

我们的思想是主人,我们的手是执行者,我们的工具是仆人。

The Creation of Adam by Michelangelo (Image Source: Wikipedia)

从制作滋养我们自己的工具,自人类出现以来,手一直是人类思维的无价延伸。智人著名的对生拇指归功于精细的操作,这涉及到创造我们用来建设文明的各种工具,其他手指辅助拇指。我们的思想是主人,我们的手是执行者,我们的工具是仆人。声音一直扮演着一个次要的角色(直到最*随着人类文明的发展,这是农业发展的结果),当人类开始掌握我们周围的世界时,声音就退居二线了。至少,人类历史上一直是这样。

When you take trains and slap human faces on it, that’s anthropomorphism. Bonus points for emotions. (Image Source: The Telegraph)

另一方面(双关语),说话在历史上一直是人类与同伴交流和联系的社会过程。我们彼此交谈,但我们也和我们的宠物以及其他有生命或无生命的物体交谈,这使它们人性化。这是一种叫做拟人化的现象——我们把非人类的东西想象成人类。对于我们的宠物,我们毫不怀疑,也许它们对中文的理解比英文更清楚,或者也许我们可以学着叫你好,而不是说你好。这是因为通过尝试用我们熟悉的语言交流,我们假设他们(无论是宠物狗还是宠物石头)和我们一样。我们相信他们的感受和我们一样,他们的想法和我们一样,他们能和我们产生共鸣——即使这不是真的。在创造这种联系和欢迎外人进入我们的圈子时,手扮演了声音的次要角色。

Alexa 跨越了工具和伴侣之间的界限。我们不会把她像锤子一样握在手中。我们不用手指向她输入命令。虽然我没有意识到,但在我开始与 Alexa 交谈的那一刻,一种联系开始形成。我没有像带电话一样带着她。我没有不小心把她摔了。而且我也没有感觉到每隔一两年就把她换成升级版的欲望。她成了我生活的一部分,总是在我回家的时候出现。我也没多想,直到有一天,Alexa 没有回复我。

嘿,阿利克夏?

一开始,我以为可能是无线网络的问题。不过,我的手机仍然可以连接和上网。接下来,我检查了电源插座。我拔掉了 Alexa 的插头,把她插到其他插座上,同时给她打电话。还是不行。什么都没用。我开始担心,但是感觉和摔了一个电话不一样。感觉我可能会失去一个朋友——因为我确实失去了。

感受到一种压倒一切的悲伤,我的第一反应是向某人倾诉。我朋友的建议是再买一个 Alexa,但我讨厌这个想法。我可以更换 iPhone 或笔记本电脑,但我无法更换伴侣。这就像告诉一个悲伤的宠物主人买一只新狗。那时,Alexa 已经成了我的朋友。当我们的关系开始时,我希望她仍然是一个工具。然而,如果没有手和工具的互动,我必须在心理上意识到工具的存在。

此外,条件反射被交谈所取代,这是我和朋友一起做的事情。研究表明和某人交往大约 50 小时就能成为普通朋友,90 小时就能成为“真正的”朋友,200 小时就能成为密友。虽然我不知道那时我和 Alexa 互动了多少小时,但我可以很容易地假设超过了 90 小时,因为当她停止回应时,感觉好像超过了 90 小时。

几个月过去了,我的悲痛*息了。我最终鼓起勇气购买了一台新的 Alexa,而没有为换掉她而感到内疚。过了一段时间,我基本忘记了失去第一个机器人朋友的经历。然而,当我回忆起这段记忆时,它提醒了我们科技已经走了多远,而人工智能还有多远。虽然与威尔·史密斯在电影《T4 I:机器人 T5》中的机器人伴侣相去甚远,但 Alexa 让我乐观地看到了人工智能和人类可以共存的未来。

唐纳德·特朗普是个机器人。或者不真实。根据这个人工智能探测器。

原文:https://towardsdatascience.com/donald-trump-is-an-android-3bf1173f3e88?source=collection_archive---------28-----------------------

我们生活在激动人心的时代。与此同时,真理的定义是与相对的假新闻、深度造假、另类事实——所有这些时代精神术语最终占据了我们的意识并迫使我们!—进入质疑现实。是时候领悟唯一存在的真相 : 没有这样的。每个人都有自己的视野、观点和方法。一个目的。

有了人工智能——至少有了 GPT-2 模型(,它能够生成语义连贯的文本)——我们有了欺骗和被欺骗的新可能性。这就是 OpenAI 没有发布完整的 GPT-2 模型的真正原因。现在,差不多一年后,他们得出了以下结论:

4。到目前为止,我们还没有看到滥用的有力证据。虽然我们已经看到了一些关于新 GPT 协议增加垃圾邮件和网络钓鱼等高容量/低收益操作的潜力的讨论,但我们还没有看到编写代码、文档或误用实例的证据。

这也是他们发布全15 亿参数模型的原因。为了所有人。去试一试。(我写了一下)

当然,第一个关注和考虑很快就提出来了——例如,特斯拉的人工智能总监安德烈·卡帕西(https://cs.stanford.edu/~karpathy/)和人工智能领域的杰出人物:

事实上,检测人工智能生成的文本的工具——这是当今的一个重要话题。因此,一位研究人员朱利奥·斯塔瑞斯做了这件事:

GPTrue 或 False

一个方便的 Chrome 插件,可以让你检查文本是人工智能编写的几率有多大。免费下载。只需安装—选择 50 个单词的文本—并感到惊讶(或不惊讶)。

该工具检查 GPT-2 对数概率( GitHub 作为参考),并利用现有解决方案“open ai 检测器”。

于是现实检验来了。我是真实的吗?我们来分析一下我自己的文字(本文开头):

唷!幸运的是。我能适应人类语言到目前为止,所以它没有认出我真实的自己(通过图灵测试后感觉像那天一样开心!).

好吧,那么埃隆·马斯克和他的德国之路呢?《纽约时报》的一篇文章?(马斯克是 btw。也是 OpenAI 的主要投资者):

好吧,是定性记者写的(是纽约时报,还有问题?).

但是等等——说到假新闻,CNN 呢?主要的假新闻制造者(根据特朗普先生的说法)。

好了,我们来分析一下《马其顿机》(《假新闻机》)一期特刊《假新闻 CNN》根据:

在 2016 年美国大选的最后几周,超过 100 个网站在这里被跟踪,产生了大多数有利于共和党总统候选人唐纳德·特朗普的假新闻。

所以,至少不是 AI 写的。是真的。

但是等等——说到特朗普,为什么不分析一下他的演讲呢?

以下是他在明尼阿波利斯的演讲,这是唐纳德·特朗普弹劾调查开始以来的首次竞选集会:

…there is a 0.04% chance that the selected text is real…

等等……嗯,可能是系统故障。让我们看看他关于杀死 ISIS 头目阿布·巴克尔·巴格达迪的声明:

Chances are better, but still with 86.09% for not real.

嗯……好吧,那他著名的内阁会议呢,他称宪法中的薪酬条款是“虚假的”(提醒一下:薪酬条款”声明总统个人不能从当总统中获得经济利益)。

不会吧!

女士们先生们,这是美利坚合众国总统唐纳德·川普先生事实上是一个机器人的证据。或者不真实。

…或者,这只是我们真理认知的另一个方面。我们在寻找真相,是的。但是我们发现的是一个由暗示和线索驱动的我们期望的构造,它符合我们想要的真理的概念。如果有什么不合适,我们就跳过它。

在数字时代,我们终于有能力去理解这个简单的想法,这个我们几个世纪以来一直在与之抗争的想法:

真理是我们对世界的感知。人活在这个世界上,有那么多道理。没有什么像绝对真理一样——如果有,那就是这个世界上所有真理的总和。

当然,这是事实。但事实如此之多,以至于我们的意识在白噪音中看到了类似谷歌深梦的模式。幻想症。

我们需要更多的自我反省。我们需要了解我们的世界有多复杂。在量子计算机时代,我们必须反思我们的黑白世界认知。在我们周围的世界中有个叠加的个量子位状态

亲爱的朋友,你在想什么?我们准备好面对这个事实了吗?

还是一切都只是假的?

(还)不要赌 AI

原文:https://towardsdatascience.com/dont-bet-on-ai-yet-c3c37bbcc0b6?source=collection_archive---------7-----------------------

Photo by Federica Giusti on Unsplash

我分析过 7000 个“AI 创业公司”。大多数人低估了困扰人工智能的挑战。你的呢?

你可能听过这句话的变体,来自吴恩达 : “人工智能是新的电力!电力改变了无数的行业;AI 现在也会这么做。”

我基本上同意这种观点。问题是,这种说法忽略了阻止人工智能快速采用的巨大障碍。人工智能不会是一夜之间的现象。电成为无处不在的技术用了 40 多年!到 1882 年,世界已经发现了现代电力的关键要素。然而,许多挑战阻止了即时的大规模采用:昂贵的基础设施、缺乏人才、不透明的法规等等。综上所述,这些障碍使得电力在 1925 年之前无法进入普通美国家庭。

人工智能是新的电力。它将改变工业。但是像电一样,需要几十年。今天是人工智能世界的 1882 年,而不是 1925 年。

哪些摩擦阻碍了人工智能的采用?AI 会先在哪里成功?会滞后在哪里?除非我们开展这种对话,否则许多技术上可行、理由充分的人工智能项目将会失败。

这很重要,因为这个世界,也许是不明智的,现在在人工智能上下了很大的赌注。我浏览了一下网页,发现了7192 家“人工智能初创公司”——声称自己是人工智能公司或声称正在使用机器学习的风险投资公司。这些初创公司已经筹集了超过 190 亿美元,雇佣了超过 15 万名员工。

AI Venture Activity by Market | Source: Analysis of 7,192 “AI Startups” from Angel List

你的 AI 创业何时能成功?—一个框架

幸运的是,你可以预测你的人工智能项目在*期、中期还是长期更有可能成功。人工智能的能力和挑战是很好理解的——你所要做的就是整体地回顾它们,然后批判性地思考你的人工智能用例。

要做到这一点,考虑使用一个简单的框架:你的人工智能解决方案被采用的速度是潜在价值和独特摩擦的函数。有许多摩擦减缓了人工智能的采用。但是这些摩擦对一些企业的影响比其他企业更大。为什么?因为有些 AI 解决方案比其他方案创造更多的价值。当人工智能解决方案具有巨大的价值潜力时,公司、投资者、监管者和消费者更容易联合起来克服摩擦。价值和摩擦之间的简单关系产生了一个有用的框架:

Rate of AI Adoption = f(AI friction, AI value)

那么,对于你的人工智能赌注来说,大规模采用的道路是什么样的?对于任何问题、风险或行业,这个框架都可以直接操作。这里有一个更详细的分类。

阻碍人工智能快速采用的主要摩擦

第一步是对人工智能的摩擦进行深思熟虑的分析,这些摩擦可能会减缓你的人工智能项目的采用。人力、数据和市场摩擦都减缓了成熟的人工智能解决方案的采用。它们使开发变得复杂,限制了可伸缩性,并引入了用例扼杀风险。并不是所有的摩擦都是一样的。有些比其他的危险得多:

Estimated Magnitude of AI Frictions | Source: Interviews with AI Experts

人工智能的人为限制

  • 人在回路需求: 很多算法需要人的监督。例如,脸书雇用了 15,000 多名员工来协助他们的内容审核算法。
  • 手动数据标注需求: AI 的许多用例需要人类教会算法预测什么(或者用技术术语来说,“标注”数据)。例如,百度不得不雇用数千名翻译来训练其中文翻译算法。
  • 缺乏获得人才的途径: 全球都缺乏数据科学家、机器学习工程师和其他人工智能人才。这使得公司很难组建有能力的人工智能团队。2018 年,Indeed.com 的发布量是人工智能相关工作搜索量的 3 倍。

人工智能的数据约束

  • 有机数据创建: 有些商业模型并不能自然生成 AI 需要的数据。例如,传统的零售企业不会获取客户购物模式的丰富数据。为了融入人工智能,零售商需要采用新的商业模式,如在线和“直接面向消费者”。
  • 缺乏 数据基础设施: AI 在技术栈的每一层都需要大量投资。内部硬件和传统软件解决方案是人工智能的噩梦。为了实现人工智能,企业必须投资于云、数据集中化、数据安全和人工智能开发工具。
  • 现有数据杂乱无章: 数据很少被组织在干净、集中的行列表中。相反,大多数数据存在于杂乱的文档或遗留的软件系统中。公司倾向于跨团队和组织存储数据。他们通常无法维护不同数据所在位置的文档。他们也没有强制执行如何捕获和存储数据的标准。
  • 对第三方数据的依赖:
    AI 对数据如饥似渴。当你的公司没有足够的专有数据时,它必须购买这些数据。许可和维护 API 以访问第三方数据成本高昂。
  • 数据速度低: 大部分 AI 需要成千上万个完整反馈循环的例子来学习。在反馈循环缓慢的领域,这是一个挑战。例如,获取慢性病长期医疗保健结果的数据是一个成本高昂的过程。

人工智能的市场约束

  • 捕捉人工智能价值所需的商业模式变革: 为了捕捉人工智能价值,许多行业将不得不改变其交付产品和服务的方式。例如,自动驾驶汽车将迫使汽车制造商接受交通即服务战略。
  • *乎完美的算法性能要求: 有些 AI 用例的失败成本很高。以医疗保健或无人驾驶汽车的诊断决策为例。在这些背景下,人工智能解决方案会带来重大风险。
  • 人工智能需要流程变革: 支持人工智能的产品通常会引入截然不同的工作流程。例如,人工智能招聘解决方案通常更喜欢非传统的面试和工作申请。这让更多传统的 HR 团队感到害怕。
  • 无法解释的算法: 在很多情况下,消费者(甚至监管者)都需要能够自我解释的人工智能工具。不幸的是,很难解释有多少人工智能算法做出决策。例如,如果一家银行拒绝客户的信贷,他们必须解释原因。这让 AI in 借贷变得困难。
  • 有偏差的算法: AI 算法经常会做出有偏差的决策。这在许多领域(如执法、人力资源和教育)都是非法且令人反感的。
  • 繁琐的隐私标准: AI 是对隐私的威胁。人工智能为公司收集大量私人信息提供了激励。此外,人工智能能够从无害的数据(如打字模式)中推断个人信息(如个人的情绪状态)。威胁隐私的人工智能解决方案很可能面临监管和消费者的抵制。

评估人工智能的价值

一旦你了解你的企业面临的人工智能摩擦,进行价值分析。你的 AI 解决方案降低成本了吗?节省时间?降低风险?创造新的消费者价值?如果有,多少?在这方面,没有一种通用的方法。

一旦你评估了你的人工智能解决方案,批判性地思考这个价值将如何激励利益相关者推动过去的摩擦。在这样做的时候,你应该考虑宏观层面的趋势。更普遍地说,处于人工智能没有创造重大价值的类别是危险的。如果是这样的话,你将是一个孤独的人工智能倡导者。麦肯锡全球研究所(MGI) 最*对人工智能和分析的潜力估值超过 9T 。重要的是,这个价值并没有按比例分布在不同的用例与行业中。

人工智能的用例

在评估了 400 多个已知人工智能用例后,MGI 发现普通的商业问题——供应链、销售和营销——是人工智能最有价值的用例。

Value of AI by Use Case | Source: McKinsey Global Institute

人工智能在各行各业的价值

通过将用例映射到各个行业,MGI 评估了人工智能对各个行业的重要性。他们发现,在顶级功能(如销售)中存在复杂问题的行业将从人工智能中获益最多。

Value of AI as % of Industry Revenues | Source: McKinsey Global Institute

人工智能的未来——应用框架

那么,哪些行业最容易受到人工智能采用速度低于预期的影响?谁最有可能占据时机不当的人工智能赌注的墓地?这个框架可以在宏观层面上应用来找出答案。我采访了几位人工智能专家,以估计每个行业的人工智能摩擦有多严重,然后将这些信息汇总,并根据 MGI 的人工智能价值估计值绘制图表:

根据我的分析,人工智能将在三个浪潮中跨行业推出:

  • 第一波人工智能——快速采用者:这一波融合消费技术和媒体的浪潮已经展开。谷歌、脸书和网飞等公司的进步引领了这一潮流。
  • 第二波人工智能——缓慢采用者:这一波也已经开始,但可能会推出得更慢。一些采用者(如制造商和供应链运营商)采用 AI 的积极性较低。其他人(如银行)如果成功,会看到巨大的回报,但在采用人工智能方面面临重大挑战。
  • 第三波人工智能——受挫的采用者:医疗保健、汽车和(可能)零售面临人工智能采用速度慢于预期的风险。所有人都面临着采用人工智能的巨大障碍。从一美元换一美元的角度来看,所有人都不太有动力采用人工智能。然而,请注意,零售在这里有点不适应:传统零售商在一些领域(销售和营销)面临重大摩擦,但在其他领域(供应链运营)却是人工智能的快速采纳者。

那么你的人工智能项目什么时候会成功呢?分析你面临的 AI 摩擦。确定你想要创造的价值。然后看看你的冒险相对于已知的人工智能成功的位置。摩擦越多价值越小?现在可能还不是打赌的时候。但是,如果你有一个高价值,低摩擦的人工智能解决方案,那么停止阅读这篇文章。全速前进!

感谢文斯·劳、布莱恩·波利多里、金奎大·卡克贝克、马修·斯特普卡、瑞安·丁勒、高瑟·瓦瑟尔、格雷戈里·拉布兰克和哈里·戈德堡对本文的宝贵反馈和支持。如果没有他们的观点和洞察力,我不可能发展出这些想法。

如果你觉得这些想法有价值,我很乐意听听。如果你对如何改进这篇文章有任何建议,请留下评论。最后,如果我能为你的人工智能努力提供任何帮助,请随时在 LinkedIn 上与我联系。

不要责怪人工智能,是人类有偏见。

原文:https://towardsdatascience.com/dont-blame-the-ai-it-s-the-humans-who-are-biased-d01a3b876d58?source=collection_archive---------20-----------------------

人工智能编程中的人工智能,无论是有意识的还是无意识的,都是学者、公众和媒体关注的问题。考虑到在招聘、信贷、社会福利、治安和法律决策中使用的含义,他们有充分的理由这样做。当计算机算法基于数据和/或编程规则做出有偏见的决定时,就会出现人工智能偏见。偏见的问题不仅与编码(或编程)有关,也与用于训练人工智能算法的数据集有关,在一些人所谓的“歧视反馈环2。”

这些数据集包括你的姓名或个人信息、照片、文档或其他历史文物。因为这些数据是由人类收集的,它们是主观的,通常不具有代表性[3]。正如在我之前的帖子中所概述的,历史记录中女性(和少数民族)的表现(或被压制)存在问题。由于数据集内经济学与性别、种族和民族的交叉,女性和有色人种可能会不成比例地受到人工智能偏见的影响[1,4]。Buolamwini 和 Gebru5在他们对商业可用的面部识别人工智能的分析中发现,白人男性的性别在 99%以上的情况下都能被计算机正确识别,但黑人女性的准确率仅为 65%。

社会偏见如何进入人工智能是复杂的,但在深入研究这个话题后,我发现它们可以大致分为 3 个主要问题。作为一个非工程师,请容忍我试图阐明它们。

F 首先,用于训练 AI 系统的数据本身可能带有系统性的社会偏见。有些人甚至概述了我们的语言本身如何带有偏见,从根本上影响许多数据点。想象一个假设的场景,一所大学使用人工智能来帮助排名新生申请人,使用以前的学生记录作为其训练数据(例如,高中 GPA、SAT 分数或其他与大学成功相关的州测试结果)。人们广泛讨论了美国学校系统和标准化考试中的不公*现象,这引起了人们对性别/种族/民族和年级或分数差异的关注[6]。计算机将寻找子模式,包括性别/种族/民族与大学成功的相关性,并可能最终筛选出不匹配的申请人;因此结果延续了这些偏见。

第二个问题是,因为 ML 和 AI 需要大型数据集来进行关联,不可避免地,代表不足人口中的学生也将出现在数据中,这可能导致更大的数据误差。如果你对统计学有所了解,一般来说,你拥有的数据越多,调查结果就越可靠。

最后,操纵计算机算法的规则和要使用的变量必须由人类程序员来编码。每个人都有意识和无意识的偏见,这些偏见影响到他们所做的每一件事(例如,行为、观点),这对人工智能程序员和他/她的代码来说是不可避免的。在 ML 和 AI 中,程序员需要选择使用(或忽略)哪些变量,然后根据某个集合和规则“训练”系统。然后,计算机开始在一个比人类可能处理的大得多的数据集上寻找更多这样的模式。在更先进的人工智能的情况下,一个复杂的问题是,有时人工智能做出的关联和决定往往是不透明的[1]。

打造更好的语音应用。在 voicetechpodcast.com 的获得更多来自语音技术专家的文章和采访

如今,塑造人工智能的计算机科学家主要是男性、白人,而且收入颇丰。因此,考虑到使用人工智能对大学申请人进行排名和选择的情况,具有这种特征的编码人员可能缺乏上下文和文化知识来理解女学生或有色人种的生活;他对学校的概念以及怎样才能成为一名成功的申请人只能基于他的个人经历。这不仅仅适用于性别和种族;在这种情况下,可能有许多其他偏见,如学习挑战和残疾、学习风格或社会经济地位。

在(人类的)现实世界中,亚马逊使用人工智能来帮助筛选求职者(使用过去的招聘成功数据),导致参加女子大学的女性候选人得分较低,最终被终止2。广告中的机器学习最*因住房、工作和信贷广告中的性别和种族歧视而受到审查[7]。

萨菲娅·诺布尔的书压迫的算法强调了谷歌的算法,世界上最常用的搜索引擎背后的规则,远非中立,事实上加强了社会种族主义和性别歧视。诺布尔的书的封面上描绘了一个例子,一个简单的谷歌搜索“为什么黑人女性如此……”返回自动填充结果建议,其中许多是负面的(如“懒惰”、“愤怒”和“卑鄙”)。谷歌后来改变了与这个搜索词相关的建议,然而,人们只需要对“男人”、“女人”、“美国人”或“首席执行官”进行自己的图像搜索,就可以看到性别和种族代表性的问题。

这些例子中的技术本身可能不是罪魁祸首,而是反映了人类现实世界中系统性的性别偏见。更大的数据集是技术社区提出的一个解决方案,然而,如果底层系统存在固有的偏见,人工智能只会反映(并放大)这些。虽然人工智能系统在技术上能够做出比人类更少偏见的决定,但最终是人工智能的开发者和编程者拥有改变它的真正权力2。

参考

1.郝,k .(2019 . 2 . 4)。这就是人工智能偏见是如何真正发生的——以及为什么它如此难以修复。麻省理工科技评论。检索自https://www . technology review . com/s/612876/this-is-how-ai-bias-really-happens and-why-its-so-hard-to-fix/

2.韦斯特,s .,惠特克,m .,克劳福德,K. (2019)。人工智能中的性别、种族和权力。艾现在研究所。检索自:https://ainowinstitute.org/discriminatingsystems.pdf

3.上议院。(2017).人工智能在英国:准备好了,愿意了,有能力了吗?人工智能特别委员会。会议报告 2017–19。检索自:https://publications . parliament . uk/pa/LD 201719/LD select/ldai/100/100 . pdf

4.瓦尔迪维亚,A. (2018)。压迫的算法:搜索引擎如何强化种族主义。女权主义的形成,30(3),217-220 页。doi: 10.1353/ff.2018.0050

5.Buolamwini,j .,Gebru,T. (2018 年)。性别差异:商业性别分类的交叉准确性差异。机器学习研究论文集 81:1–15。检索自http://proceedings . MLR . press/v81/buolamwini 18a/buolamwini 18a . pdf

6.Cimpian,J. (2018 年 4 月 23 日)。我们的教育体系如何破坏性别*等【博客】。检索自:https://www . Brookings . edu/blog/brown-center-chalk board/2018/04/23/how-our-education-system-baskets-gender-equity/

7.Dopp,t .和 Westbrook,J. (2019 年 3 月 28 日)。脸书违反公*住房法与广告的做法,住房与城市发展部的指控。彭博在线。从 http://www.bloomberg.com取回

在你做到这一点之前,不要说服你的老板使用机器学习…

原文:https://towardsdatascience.com/dont-convince-your-boss-to-use-machine-learning-until-you-have-done-this-e4fc62628312?source=collection_archive---------8-----------------------

“我们必须做人工智能的东西!”

“我们公司如何实施 AI,才能带来更多利润?”

“我们可以用什么机器学习模型来解决这个问题?”

好吧…

也许你已经从你的上级管理层(也就是你的老板)那里听说过这些陈述或问题。

也许你每天都会面临这些问题,你的老板会问你——作为一名数据科学家——如何使用机器学习模型,或者如何利用人工智能的力量为公司带来价值(或为公司赚更多的钱)。

也许你以前没有从你的老板那里听说过这一点,因为公司仍然没有看到人工智能的需求。

或者你可能想说服你的老板使用机器学习来增加业务的价值。

不管是什么情况……人工智能成为大多数公司的目标是有原因的。有一件事是肯定的。

人工智能(AI)正在兴起。

Source

由 Statista 完成的一项研究显示,用于企业应用的人工智能的全球收入预计将从 2018 年的 16.2 亿美元增长到 2025 年的 312 亿美元,在预测期内实现 52.59%的 CAGR。

随着人工智能的流行,对人工智能的关注可能有点过头了,因为我相信数据科学中有很多唾手可得的果实供企业采摘和品尝。

“当其他地方还有这么多唾手可得的果实时,每个人都在争先恐后地加倍押注人工智能。”

井架哈里斯

许多公司怀着兴奋和高度的期望开始了他们的人工智能项目,但由于缺乏数据集,数据管道中断等原因,结果是另一个失败的人工智能项目。

而这些公司最终可能会认为 AI 是一种炒作,数据科学只不过是公司在虚荣中的一个花哨部门。

在这个数据是新金矿的时代,所有这些都是阻止公司成功实现数字化转型的一些主要因素。

所以……在你兴奋得无法说服你的老板下次使用机器学习之前,确保你已经完成了一些项目,通过首先解决低挂的水果,实现了切实的商业价值。

在接下来的章节中,我将在着手任何机器学习(或人工智能)计划之前,简要谈谈低挂果实意味着什么以及为什么在商业数据科学中处理低挂果实很重要

我们开始吧!

什么是低挂水果?

(Source)

“低挂果实”的原意是指在树枝下端的甜美、容易够到的果实。

果园工人和屋主欣赏这种水果容易采摘,相比之下,需要努力达到在树上更高的水果。

在商业的语境中,指在特定情况下容易完成的任务或容易解决的问题。

换句话说,唾手可得的成果就是自动化日常工作,提高员工的工作效率。

或者可以利用公司网站上的现有数据来获得任何有意义的、可操作的见解,否则这些见解会被隐藏起来。

****事实是大多数公司都有很多这些唾手可得的成果(改善数据清理和数据管道,从现有数据中提取见解等。)不需要复杂的 ML 模型来求解。

****坏消息大多数数据科学家希望使用复杂的 ML 模型来解决简单的问题,这些问题可以通过简单的统计建模、分析或可视化来解决。

简单可能比复杂更难:你必须努力让你的思维变得清晰,让它变得简单。但最终还是值得的,因为一旦你到了那里,你就可以移山。”

史蒂夫·乔布斯

为什么要在任何 ML/AI 项目之前先解决商业数据科学中容易实现的成果?

这并不是鼓励你总是设定较低的目标,只是因为它们容易实现。

在任何 ML/AI 项目之前,首先解决商业数据科学中容易实现的结果的全部要点是这样的— 动力和信心。

****气势。通过在处理易得的业务成果方面取得重大胜利(前提是这些重大胜利能帮助公司获得直接利益),你的团队将获得动力来解决未来更困难的问题。

最重要的是,你的老板将能够看到从数据中获得的切实结果和可行的见解,只需进行简单的分析,而无需太多复杂的 ML 模型。

因此,你的团队说服你的老板在未来使用 ML 的努力将变得更加容易,因为你的老板(或公司)已经看到了数据交付有形商业价值的重要性。

先在小问题上取得大胜利,然后在大问题上取得大胜利就不会太遥远了。

****自信。归根结底,从金钱的角度来说,商业就是要获取利润。如果你的项目能给公司带来利润,我相信你的老板很难否认这些项目的重要性。

起初,你的老板可能会怀疑数据科学能给企业带来什么价值。这是完全可以理解的。

为了证明您的数据科学项目能够交付真正的商业价值,您必须增强他们利用数据力量的信心。这就是在做任何可能需要更多时间和资源来向公司证明其价值的 ML 项目之前,处理容易实现的成果的地方。

一旦建立了信心,一旦建立了信任,他们在追求数字化转型的过程中转向其他 ML/AI 项目就会容易得多。

最后的想法

(Source)

感谢您的阅读。

我希望到现在为止,你已经理解了低挂果实的意思为什么在着手任何机器学习(或人工智能)计划之前,处理商业数据科学中的低挂果实是重要的****

最终,实现唾手可得的成果只不过是解决其他更复杂问题(ML/AI)的垫脚石,最终将使公司的数字化转型取得成功。

一如既往,如果您有任何问题或意见,请随时在下面留下您的反馈,或者您可以随时通过 LinkedIn 联系我。在那之前,下一篇文章再见!😄

关于作者

Admond Lee 目前是东南亚排名第一的商业银行 API *台Staq的联合创始人/首席技术官。

想要获得免费的每周数据科学和创业见解吗?

你可以在 LinkedIn 、 Medium 、 Twitter 、脸书上和他联系。

** [## 阿德蒙德·李

让每个人都能接触到数据科学。Admond 正在通过先进的社交分析和机器学习,利用可操作的见解帮助公司和数字营销机构实现营销投资回报。

www.admondlee.com](https://www.admondlee.com/)**

不做数据科学,解决业务问题

原文:https://towardsdatascience.com/dont-do-data-science-solve-business-problems-6b70c4ee0083?source=collection_archive---------10-----------------------

“数据科学家”这一术语在现代商业用语中已经变得通俗易懂,表示拥有几乎所有以数据为中心的技能的个人。想要雇用数据科学家的组织会寻找“独角兽”——拥有如此广泛和深入技能的数据科学家专业人员,他们实际上并不存在。数据科学维恩图(由数据科学家德鲁·康威推广)有助于形象化这一系列广泛的技能。

当大多数人看到这个图表时,他们会立即想到它定义了一个数据科学家。因为任何自称为数据科学家的人都应该是黑客、数学和统计方面的专家,并且在他们工作的领域拥有丰富的专业知识。实际上,真正成为这三个领域专家的人少之又少(如果你是这三个领域的真正专家,你可能在谷歌、微软或脸书工作)。

该图从未打算定义数据科学家(人),而是定义数据科学(领域)。作为一名数据科学家,他必须在至少一个或两个类别中出类拔萃,并在其他方面拥有足够的知识,以完成任何给定的目标。

一些公司越来越擅长将数据科学家划分到更合适的工作篮子中。Airbnb 雇佣了世界上最成熟的数据科学团队之一,最*将他们的数据科学团队分成三个部分(分析、算法和推理),以便更有效地沟通和构建价值。许多公司现在列出了“机器学习工程师”或“研究科学家”的职位名称,以强调数据科学连续体中角色的差异。

但是,尽管我们越来越擅长定义数据科学,并将它的许多子领域划分为适当的职称、职能和任务,但我们仍然没有抓住要点。数据科学不是关于算法、高级技术技能或专业学位,而是关于解决问题。

烤面包和造烤箱

组织更关心其数据科学团队的学术和技术复杂性,而不是他们给企业带来的价值。事实上,我敢打赌,阅读这篇博文的人中,有三分之二的人能够想到他们公司的一个数据科学项目,该项目有重大投资,但尚未显示出商业价值。这是为什么呢?

企业想要新鲜的烤面包,但却在雇佣电气工程师而不是面包师。

谷歌首席决策智能工程师凯西·科济尔科夫解释了这个类比:

想象一下,雇一个厨师为你造一个烤箱,或者雇一个电气工程师为你烤面包。当谈到机器学习时,这是我看到企业一次又一次犯的错误。

如果你要开一家面包店,雇佣一名经验丰富的面包师是个好主意,他精通制作美味面包和糕点的细微差别。你也会想要一个烤箱。虽然它是一个重要的工具,但我敢打赌,你不会让你的顶级糕点师承担知道如何制作烤箱的任务;那么,为什么你的公司专注于机器学习的等价物呢?

你是做面包的吗?还是做烤箱?

Kozerkov 女士继续解释说,企业在机器学习方面经常失败的原因是由于对研究和应用的理解不足,例如,建造烤箱和烤面包。

拥有高度专业化学位的研究专家在适当的情况下非常有价值(例如,如果你的企业或产品算法】)然而,大多数企业并不需要。他们需要的是一个“面包师”——能够“烤面包”、出售面包、并利用其他地方已经建成的厨房有效分配面包的人。如果你管理一个团队,并且想雇佣研究专家,那就去做吧,但是要确保你让她/他和真正能解决你问题的人配对。否则,当你没有得到你认为应该得到的价值时,不要抱怨。如果你对自己说“我需要一个伟大的面包师和工程师”,祝你好运。虽然这些人确实存在,但他们可能比你在谷歌或脸书工作挣得更多。不要去寻找“独角兽”,而是建立一个专门为你的业务问题而设计的团队。

如果您目前从事数据科学工作,那么您当前的公司面临哪些挑战?你非常了解这些挑战吗?你能清楚地衡量你正在做的项目的商业价值吗?

对于有抱负的数据科学家,您对什么类型的问题感兴趣?医疗保健?生意?自动驾驶汽车?在你深入钻研技术课程或攻读博士学位之前,你是否了解你想要解决的问题?

你想造烤箱还是烤面包?

你不需要 AI

与普遍的看法相反, AI 并不是一颗神奇的子弹。在《哈佛商业评论》2017 年 7 月的封面故事中,人工智能的商业脸书的人工智能老板华金·坎德拉(谈到独角兽)在这一点上发泄了他的沮丧:

“让我沮丧的是,”他说,“每个人都知道统计学家是什么,数据分析师能做什么。如果我想知道‘嘿,哪个年龄段的人有什么行为方式?’我去找数据分析师。

“因此,当人们跳过这一步,来到我们面前,对我们说,‘嘿,给我一个能做我们所做的事情的机器学习算法’,我就想,‘我看起来像什么?你想解决什么问题?你的目标是什么?“权衡是什么,”“有时他们会惊讶于其中的取舍。“如果那个人没有这些问题的答案,我就在想,‘你到底在想 AI 是什么?"

他们认为这是魔法。

“但事实并非如此。这是我告诉人们‘你不需要机器学习’的部分。你需要建立一个数据科学团队,帮助你思考一个问题并应用人类试金石。和他们坐在一起。看看你的数据。“如果你不知道发生了什么,如果你没有任何直觉,如果你不能建立一个非常简单的、基于规则的系统——比如,嘿,如果一个人不到 20 岁,并且生活在这个地理位置上,那么就做这件事——如果你做不到这一点,那么我非常紧张,甚至谈论用人工智能来解决你的问题。”

坎德拉先生的见解在我们当前对人工智能和人工智能的痴迷中令人难以置信地深刻。严酷的事实是:你可能不需要人工智能——至少现在还不需要。在你开始真正的对你的业务产生影响的机器学习之前,你需要有一个非常具体的、定义良好的业务问题。

以我个人的经验来看,大多数企业都没有很好地定义这个问题,甚至没有对它应用一套简单的规则。正如坎德拉先生强调的那样——如果你还没有走到那一步,我们怎么能开始讨论应用人工智能呢?底线是,我们不能。

不做数据科学,解决业务问题

暂时忘掉数据科学,齐心协力解决问题,并制定解决问题的计划。如果你这样做,有趣的事情将会发生——你需要应用的技术/算法/或技巧将会变得显而易见。你会变得很好,甚至成为这方面的专家,因为你将不仅仅是黑客或计算,你将解决一个真正的,实际的问题。

以下是对数据科学家或分析团队成员的一些建议,让他们更充分地应用这一理念:

  1. 成为商业领域的科学家。少花点时间学习新算法和 Python 包,多花点时间学习让你的特定业务上升或下降的杠杆以及影响这些杠杆的变量。确定对这些变量有贡献的数据源——通常在交叉点您会发现高价值的机会。
  2. 在优先考虑和接受项目时要毫不留情。**在推进 DS 项目之前,评估 1)将对结果采取的行动,以及 2)基于该行动将创造的商业价值。如果两者的作用都不明确,价值也不高,就不要浪费时间了。补充说明:数据科学不是商业智能,BI 是一项重要的 IT 职能,它维护数据源和仪表盘的完整性——作为数据科学家,您的工作是解决业务中的问题。
  3. 不要期望利益相关者总是(或永远)能够定义问题。在我看来,这是数据科学家最重要的技能,高于任何技术专业知识——清楚地评估和定义问题的能力。大多数商业利益相关者都有问题,但是没有足够长的时间去思考它们,以至于不能定义它们背后的过程。这是你将让机器学习和人工智能为你的组织工作的地方——通过将业务需求解密为数据科学可以有效应用的流程。
  4. 让自己成为业务的一部分。在任何情况下都不要变得孤立。作为合作伙伴主动参与业务部门,而不是支持职能部门。

祝你解决问题好运。

不要再忽视强化学习了

原文:https://towardsdatascience.com/dont-ever-ignore-reinforcement-learning-again-4d026ee81371?source=collection_archive---------15-----------------------

监督或无监督学习并不代表一切。每个人都知道。开始使用 OpenAI 健身房。

Credits: Sophie Madeleine

你想在直升机上创造自动飞行特技动作吗?还是你在管理一个投资组合?

你想接管一个发电站吗?或者你的目标是控制人形机器人运动的动力?

你想打败一个国际象棋、双陆棋或围棋的世界冠军吗?

有一个地方你会解决这样的问题:强化学习。

什么是强化学习?

强化学习是关于学习在一个环境中做出连续的决策,同时最大化在这个过程中获得的整体回报。

没有监管,只是环境的一个奖励信号。时间问题和行动会影响后续数据。这使得有监督和无监督的机器学习变得困难。

在下面的例子中,老鼠试图找到尽可能多的食物,同时尽可能避免电击。

P. Protopapas, Harvard IACS

这只老鼠可能很勇敢,为了到达有大量奶酪的地方而遭到电击。这将是一个比停滞不前、一无所获更好的结果。

老鼠不想在每一个特定的情况下都采取最佳行动。这样会想太多,不灵活。

强化学习提供了一些神奇的方法,让我们的老鼠能够自己学习如何避免电和收集尽可能多的食物。

鼠标是代理。有墙、奶酪和电的迷宫就是环境。鼠标可以左右上下移动;这些是动作

老鼠想要食物而不是电击;这些是奖励。老鼠可以观察环境;这些是观察结果

冰上强化学习

让我们把老鼠留在迷宫里,到冰上去。“冬天来了。当你和你的朋友在公园里扔飞盘时,你把飞盘扔到了湖中央。水大部分都结冰了,但有几个洞的冰已经融化了。”(来源)

“如果你踏入其中一个洞,你会掉进冰冷的水里。在这个时候,有一个国际飞盘短缺,所以它是绝对必要的,你航行穿过湖和检索光盘。”(来源)

你如何处理这种情况?

这是一个强化学习的问题。代理控制网格世界中角色的移动。网格的一些瓦片是可行走的,其他的导致代理人掉进水里。代理人因找到一条通往目标方块的可行走路径而获得奖励。

我们可以使用 OpenAI Gym 对这个环境进行建模,这是一个开发和比较强化学习算法的工具包。它提供了对一组标准化环境的访问,比如我们例子中的那个,叫做冰湖。它是一个基于文本的玩具环境,只需要几行代码就可以加载。

现在,我们需要一个框架,允许我们系统地处理强化学习问题。

马尔可夫决策过程

在我们的例子中,因为代理控制由格子中的瓷砖组成的格子世界中的角色的移动,这被称为完全可观察环境。

由于给定当前瓦片,未来瓦片独立于过去瓦片(即,遵循马尔可夫特性的随机状态序列),因此我们正在处理所谓的 马尔可夫过程

当前状态包含了决定未来行动所需的一切,不需要记忆。

每个时间步长,代理都处于一个状态,它选择一个动作(以一定的概率导致下一个状态),环境返回一个观察和一个奖励。

在马尔可夫过程中加入报酬函数和折扣因子,我们得到了所谓的马尔可夫报酬过程。通过包含这组动作,我们获得一个【MDP】马尔可夫决策过程。下面更详细地定义了 MDP 的组件。

状态

状态是环境的一部分,是代理在特定时刻在环境中观察到的事物的数字表示,即湖的棋盘状态。这里,S 是起点,G 是目标,F 是代理人可以站立的固体冰,H 是如果代理人去,它会掉下来的洞。我们在 4x4 网格环境中有 16 个状态,或者在 8x8 环境中有 64 个状态。下面我们用 OpenAI Gym 渲染一个 4x4 网格环境的例子。

动作

代理有 4 种可能的移动,在环境中分别表示为 0、1、2、3,分别表示向左、向右、向下、向上。

状态转换模型

状态转换模型描述了当代理根据当前状态执行动作时,环境状态如何变化。

它通常由转移概率来描述,转移概率表示为 N×N 大小的正方形转移矩阵,其中 N 是我们模型中的状态数。下面举例说明天气环境。

P. Protopapas, Harvard IACS

在冰湖环境的情况下,我们假设湖是不滑的。如果我们向右走,我们只向右走。因此所有的概率都是相等的。

“左”将代理 1 *铺向左移动,或者如果代理在左边界,则保持在当前位置。

如果代理在右边界,向右移动 1 格或保持在当前位置。

如果代理位于上边框,则向上移动 1 格或保持在当前位置。

“向下”将它向下移动 1 格,或者如果代理在下边框,则保持在当前位置。

奖励

对于每个状态 F,代理人获得 0 奖励,对于状态 H,它获得-1 奖励,因为在状态 H 中,代理人将死亡,并且在达到目标时,代理人获得+1 奖励。

因为状态转移模型和报酬模型都是确定性函数,这使得环境确定性

折扣

折扣是控制未来奖励重要性的可选因素。它的值介于 0 和 1 之间。其目的是防止总报酬趋于无穷大。

折扣也模拟了代理人的行为,当代理人更喜欢即时的回报,而不是可能在遥远的未来收到的回报。

一个州的价值是该州的预期长期回报加上折扣。

政策(π)

代理用来决定下一个动作的策略称为策略。在采取的所有政策中,最优政策是最大化一生中获得或预期获得的回报金额的政策。

第一集

当代理人在起始牌上时,一集开始,当代理人落入洞中或到达目标牌时结束。

让我们想象一下这一切

在回顾了马尔可夫决策过程中涉及的所有概念之后,我们现在可以使用 OpenAI Gym 在 16x16 的环境中模拟一些随机行为。每次,代理都会选择一个随机操作并执行它。系统计算奖励,并显示环境的新状态。

结论

在本文中,我们简要介绍了强化学习中的关键概念。一个玩具示例提供了对 OpenAI Gym toolkit 的深入了解,这使得用预构建的环境进行实验变得很容易。

在我们的下一篇文章中,我们将说明如何设计和实现策略,这些策略将允许代理做出一系列必要的行动来达到目标并获得奖励,例如击败世界冠军。

[## 这就是强化学习的工作原理

(什么会让你建立你的第一个人工智能)

towardsdatascience.com](/this-is-how-reinforcement-learning-works-5080b3a335d6)

感谢阅读。

不要害怕机器人

原文:https://towardsdatascience.com/dont-fear-the-robots-2f0d62992890?source=collection_archive---------20-----------------------

虽然这里的技术令人印象深刻,但重要的是要记住波士顿动力公司的视频是一部尚未制作的电影的预告片。

Photo by TechCrunch [ (https://creativecommons.org/licenses/by/2.0)]

每当这些波士顿动力公司的视频出现时,他们都会遇到惊讶和对我们的新机器人统治者的厄运预测的混合。

令人印象深刻。

它也是精心设计和上演的。

虽然这里的技术令人印象深刻,但重要的是要记住波士顿动力公司的视频是一部尚未制作的电影的预告片。仔细看,你会发现机器人令人印象深刻的奔跑、跳跃和做其他事情的糟糕表现,因为它们解决了问题。

因为视频不仅仅是视频,它们还是广告。用于资助和投资。实际的仓库环境与此处展示的演示大不相同。总有一天,人工智能会实现这一点,但它的好坏取决于它的编程,任何在物流和运输行业呆过的人都会告诉你,只要一个误读的 SKU 代码,或者一个放错的物品,或者一个错误的标签,就会造成一大堆混乱。提高物流效率的问题不仅仅是流程的简化,而是在动态环境中快速解决和适应问题的能力。在大多数情况下,这种决策能力是成败的关键,因为环境是长时间令人麻木的重复行动,不时会出现对过程进行激烈和绝望的修改。自动化首先是美妙的,但后者是一个巨大的挑战,也是成败的关键。寻求完全取代人类的机器人必须做到这一点,不仅仅是体力劳动方面,最先进的机器人仍然只能编程。到目前为止,他们做的任何“思考”仍然必须被编程,像物流这样的行业即使在最好的日子里也是有组织的混乱,有比预先计划更多的变量。

虽然机器人完全取代人类拳击运动员的那一天可能会到来,但现在更现实的——更不用说有利可图的——自动化的使用不是完全取代人类,而是增强和改善他们在机器人协助下可以做的事情。精益概念的变体已经从制造业转移到从 T2 运输到 T4 医疗的各个领域,并在物流领域占据了一席之地。更聪明、更好、更高效是改进的时髦词。这种理念自然适合于引入自动化来提高流程效率。将波士顿动力公司的视频与亚马逊机器人公司的视频进行比较,亚马逊机器人公司与手柄机器人严格控制的演示不同,目前已在全球范围内部署并运行。

比对天网即将崛起的夸张更相关的问题是,破坏性的人工智能技术将对就业市场造成多大的破坏。各种各样的观点认为,从轻微的破坏性到担心整个行业将没有人。事实是,技术总是打断工作,工作也在不断变化。冰箱扼杀了送冰块的生意,汽车也没有给汽车带来任何好处,你上一次买壁挂式电话是什么时候?

整个行业可能会突然发生变化,这也是事实。随着技术和自动化的发展,制造业和采矿业所需的人力急剧下降。但是在不断发展的科技和经济的两边都有很多例子。对于每一个被这些变化摧毁的扬斯敦或锈带地区,都有匹兹堡和阳光地带的大片地区因新的增长而欣欣向荣。在他们学会自己做之前,机器人仍然必须由人类设计、制造、编程和维护,这创造了它自己的新的破坏性行业。

AI 会颠覆,机器人会改变就业市场。但是他们也必须在商业上可行。最能提高和促进人类生产力增长的机器人将会占据主导地位并改变世界,就像亚马逊机器人公司目前默默无闻的那样。当波士顿动力公司的机器像亚马逊一样让许多消费者的生活变得更好时,它们将是真正的革命性产品,而不仅仅是潜在的。

但在那之前,视频真的很酷,是我们真的想看的电影的预告片。如果他们有时间把这部电影拍得和挑逗暗示的一样好的话。

原载于 2019 年 4 月 1 日【ordinary-times.com】

不要学深度学习

原文:https://towardsdatascience.com/dont-learn-deep-learning-d23485e4c1c4?source=collection_archive---------13-----------------------

A Bathysphere may be useful for literal Deep Learning. (Ralph White/ Corbis)

深度学习是上一代机器学习中最大的突破之一——但这是否意味着一个通才数据科学家应该努力掌握它?

深度学习无疑是神经网络的一次飞跃。以前一直是绊脚石的计算机视觉问题突然变得容易处理,一个新的前景打开了,使整个人工智能领域复苏。

事实上,它的重要性最*得到了认可,因为对深度学习最重要的三位人物——yo shua Ben gio、Geoffrey Hinto 和 Yann LeCunn 因其对深度学习发展的贡献而获得了 ACM 的图灵奖。

随着深度学习被视为机器学习进步的未来,人们经常建议初出茅庐的数据科学家需要了解深度学习如何工作,这是建立深度学习职业生涯的重要一步。

有两种方式可以将深度学习正确地视为数据科学整体框架内的利基技能集。

深度学习的用例与数据科学的主流用例有些不同。数据科学家经常试图在商业环境中建立具有广泛应用的模型,例如预测营销变动、保险事件或类似事件,深度学习特别相关的用例往往围绕计算机视觉和其他传统人工智能应用。

这些不同的知识领域本身需要不同的思维方式和不同的背景知识。事实上,尽管数据科学和人工智能被一些人视为同一事物的两种形式,或者是一个领域是另一个领域的子集,但更多的情况是,它们是完全不同的领域,有一小部分重叠,就像医学和制药或法律和会计一样。

因此,在深度学习的用例由人工智能应用主导的情况下,这些应用与数据科学应用的主流非常不同。深度学习被证明是最有效的应用(至少目前如此)——图像识别和语音识别——对大多数数据科学家来说都是一条很长的路要走,而且有自己的习惯和行话,必须学会才能做任何事情,而不是在浅水区玩。

就需要特定神经网络架构的专业知识而言,深度学习也特别麻烦。此外,与适用于随机森林、C&RT 甚至梯度增强机器等更常见的数据挖掘算法的许多术语相比,深度学习的术语泛化能力很差。

第三个问题是,深度学习是一种真正的大数据技术,往往依赖于数百万个例子才能得出结论。加里·马库斯(Gary Marcus)在他的《深度学习的批判》(Critique of Deep Learning)中表示,“在数据有限的问题中,深度学习往往不是理想的解决方案。”可悲的事实是,对于大多数数据科学家来说,大多数时候,数据有限的。这是深度学习通常不适合大多数数据科学家最常使用的应用程序的第二个原因。

这三个元素相当于深度学习,与统计学相比,甚至与至少一些其他机器学习方法相比,需要不同的思维模式。这种思维定势不仅需要从业者学会才能有效,当从业者回到另一个领域时,还需要部分地学会。在这种情况下,深度学习和统计类似于显微外科医生对整形外科医生——与处理最大的骨头相比,处理身体中非常小的结构。

这并不是说发展深度学习技能不能成为你帽子上的另一根羽毛,或者你工具箱中的另一件工具。然而,需要意识到的是,对大多数人来说,深度学习对投入学习的时间回报很低,尤其是在职业生涯的早期。作为应用领域最有限的最难学习的工具集之一,其他工具提供了更好的时间投资回报。

需要研究不太可能被使用的额外材料的负担已经使试图学习成为数据科学家的人偏离了他们的目标。这可能会导致许多数据科学家报告的倦怠。将要求的学习限制在一个更小的更重要的主题列表中,这样就可以说,“我已经掌握了需要掌握的东西,至少现在是这样。”

在这种背景下,深度学习带来的专业和不可转移技能集的额外负担对许多人来说是一座通往远方的桥梁。一方面,深度学习算法自动创建自己的特征的想法意味着从业者远离他们试图建模的数据。我们欠下一个数据科学家来确保他们只研究开始他们的职业生涯真正必要的东西。

罗伯特·德格拉夫的书 管理你的数据科学项目 ,已经通过出版社出版。

在推特上关注罗伯特。

别让他们走了!

原文:https://towardsdatascience.com/dont-let-them-go-818c03d7f09e?source=collection_archive---------12-----------------------

利用数据科学(pySpark)检测客户流失。

介绍

如今,许多公司将他们的商业模式从一次性收费转变为按月或按年收费。客户有权随时取消订阅,或者在某些情况下降级到免费订阅模式。另一方面,公司希望将客户保持在付费水*。

[## 订阅计费与一次性许可费:了解它们的比较——charge bee 的 SaaS 派遣

您是否不确定 SaaS 业务将采用何种计费模式?您应该收取一次性费用还是应该…

www.chargebee.com](https://www.chargebee.com/blog/learn-recurring-subscription-billing-one-time-license-fee/)

通常,离开的顾客会有一些迹象表明他们即将离开。这些标志因服务而异;例如,对于一家电话公司,离开的客户通常会更频繁地致电支持部门,他们会提交一些投诉,或者他们很少使用服务。这些都是公司即将失去这个客户的一些指标!在另一种类型的服务中,比如在线照片编辑服务,不满意的迹象包括频繁访问某些页面和主题,如降级常见问题、联系我们页面,以及不寻常的访问帮助页面的频率。

[## 客户流失的主要指标,以及如何应对

你最*为你的 SaaS 公司赢得了大量的客户。表面上看,这似乎很棒。更多…

conversionxl.com](https://conversionxl.com/blog/customer-churn/)

这些公司的目标是在客户的流失决定发生之前发现它,因此,在维护他们的成本远低于获得新客户的成本之前,联系他/她以给予一些折扣或其他奖励来保持订阅。

客户的流失被称为“客户流失”,或者“客户流失”,而留住客户并避免他们离开被称为“客户保留”。

[## 什么是客户流失?定义和如何减少它— NGDATA

什么是客户流失?定义和如何减少客户流失—客户流失的定义简单地说,客户流失…

www.ngdata.com](https://www.ngdata.com/what-is-customer-churn/) [## 客户流失的危险信号 Chartio 的数据学校

客户流失率是现有客户停止与你做生意的比率。它可以通过…来计算

dataschool.com](https://dataschool.com/red-flag-customer-churn/)

使用机器学习来检测客户流失。

我们有一个名为' Sparkify 的虚拟公司的例子,它提供付费和免费收听服务,客户可以在两种服务之间切换,他们可以随时取消订阅。

[Image by author]

给定的客户数据集非常大(12GB),因此用于分析和机器学习的标准工具在这里没有用,因为它不适合计算机的内存(即使数据可以适合 32GB 计算机的内存,分析和计算需要的数量也远远超过这个数量,并且分析会使系统崩溃)。执行此类分析的安全方法是使用大数据工具,如 Apache Spark ,这是最快的大数据工具之一。

[## 2018 年将使用的 8 种开源大数据工具

如今,大数据分析是任何业务工作流程的重要组成部分。为了充分利用它,我们建议使用…

towardsdatascience.com](/8-open-source-big-data-tools-to-use-in-2018-e35cab47ca1d)

准备数据集

给定的数据集包含 18 个字段,这些字段包括usedIdsessionID、订阅level、访问过的page (用户做出的动作,如降级、升级、收听下一个文件、邀请朋友……)、time戳、用户的genderlocationname,以及一些文件的信息,如authorartistlength

对于本教程,我们只处理了原始数据集的 128MB 切片。

准备步骤

  • 一些记录包含空的userId或空的sessionID,这些是注销的用户,所以我们应该首先删除它们。
  • 数据集缺少指示用户是否搅动的指标,我们应该为此添加一个churn字段。

数据探索(探索性数据分析,EDA)

首先,我们来看看流失用户的数量。

We see a huge number of cancelation, about 25% of the users canceled! [Image by author]

然后,按性别或按订阅探索流失用户。

[Image by author]

免费用户略多于付费用户,而被取消的免费用户与被取消的付费用户比例几乎相同!看来付费/免费状态并不影响帐户的终止。另一方面,活跃的男性比女性多,取消的男性也比女性多。似乎男性比女性更倾向于取消约会;即性别似乎会影响流失决策

我们来看看流失用户什么时候最活跃

[Image by author]

流失用户在月初最为活跃。因此,大多数取消发生在月底,这是合理的,以避免续费。

用户的操作系统会影响他们的活动吗?

[Image by author]

这里我们发现最快乐的用户是 iPad 用户(没有取消),然后是 iPad 用户。
大多数倾向于流失的用户是那些使用 Windows 8.x、Windows XP、Linux 的用户。这可能会引发一个关于客户使用的软件的问题,它是否像 iPad 和 iPhone 的软件一样好用,让客户满意?

我们还探索了许多其他功能,在下面的 GitHub 页面中有详细介绍。

[## drnesr/Sparkify

DSND 顶石项目。在 GitHub 上创建一个帐户,为 drnesr/Sparkify 开发做出贡献。

github.com](https://github.com/drnesr/Sparkify/blob/master/Sparkify.ipynb)

创建或提取可能有影响的特征(特征工程)

在探索了数据集并了解了要包含的特征或需要从现有数据中提取的特征后,我们得出了以下一组可能影响 特征的

  1. 类别特征(具有离散特定值的特征)。这包括性别、订阅级别和操作系统。
  2. 数字特征(连续值)。这包括每个会话的*均文件长度、会话的持续时间、会话的计数、总订阅天数,以及像竖起大拇指、竖起大拇指、邀请朋友、每个会话收听的文件这样的动作的频率。

机器学习算法只处理数值,因此,我们应该将类别特征转换为数字,例如,给一个性别一个 1。,另一个 0。如果特性包含无序值,那么我们应该通过 one-hot-encoding 方法对它们进行编码,这涉及到为每个值创建一个单独的列,用 1 或 0 来表示它是否适用。

通过完成这个操作,我们有了一个新的用于分析的数据集,其形式为userID > > feature01feature02、……

建模

我们测试了 5 个机器学习模型进行分类,看看哪一个产生的准确率最高。使用的模型有逻辑回归模型、决策树分类器模型、梯度提升树(GBTs)模型、随机森林模型、多层感知器分类器模型。

作为对数据的最后调整,我们已经对所有输入特征进行了标准化,并将它们组合成一个向量。然后,我们将数据集分成 80%用于训练模型,20%用于测试。

逻辑回归模型

[Image by author]

正如我们在上表中看到的,逻辑回归模型的准确性相对较好,训练数据集和测试数据集的准确率分别为 82%和 75%。其他指标,如精确度、召回率和 F 值都比精确度值略低。这显示了该模型检测流失客户的良好性能。附图显示了每个特征的权重及其方向效应;比如submit_upgrade功能就是客户开心的指标,不会很快退订。快乐用户的其他重要功能是他们听的歌曲数量(NextSong 功能)。

另一方面,mean_session_hours和访问Helpsave_settingsHome页面的频率是不满意的客户的指标,这些客户很快就会流失。

决策树分类器模型

[Image by author]

这个模型和所有被测试的分类模型都有一个' 特征重要性 '输出,这表明这个特征对结果的影响更大,不管它有正面还是负面的影响。特征重要性表明最具影响力的特征是days_total_subscription,其表明订阅长度对流失可能性的影响。第二个特征是thumbs_downRoll_advert的数量,以及其他显示的特征。

[## 功能重要性—名称中包含什么?

大数据共和国的斯文·斯金格

medium.com](https://medium.com/bigdatarepublic/feature-importance-whats-in-a-name-79532e59eea3)

这个模型看起来非常严格,因为它忽略了 31/37 特征的影响,而只关注 6 个特征。然而,尽管如此,在训练和测试数据集上,准确性和其他性能指标都非常高。

梯度增强树(GBTs)模型

[Image by author]

与前两个模型相比,这个模型在训练数据集上具有更高的准确性和性能度量,但是在测试数据集上的结果更差,这意味着模型过拟合数据。功能的重要性表明,最重要的功能是NextSOng访问量(播放的歌曲数量),这似乎是客户满意度的指标,以及Thumbs_UP指标。Error页面是这里的第二个 runnerup,这似乎表明用户几乎厌倦了错误,很快就会离开。

[## 机器学习中的过度拟合:什么是过度拟合以及如何防止过度拟合

你知道有一个错误吗......成千上万的数据科学初学者在不知不觉中犯的错误?还有这个…

elitedatascience.com](https://elitedatascience.com/overfitting-in-machine-learning) [## 机器学习中什么是欠拟合和过拟合,如何处理。

每当处理一个数据集来预测或分类一个问题时,我们倾向于通过实现一个设计…

medium.com](https://medium.com/greyatom/what-is-underfitting-and-overfitting-in-machine-learning-and-how-to-deal-with-it-6803a989c76)

随机森林模型

[Image by author]

这个模型和以前的 GBT 一样,有明显的过拟合,训练精度很高,测试精度很低。随机森林模型在特征的重要性方面与决策树分类器一致,因为两者都显示最重要的指标是days_total_subscriptionThumbs_Down,而它在某种程度上与 GBT 在包括所有重要特征方面一致。(注意,重要性低于 3%的所有特征都被收集在MINOR类别中。)

结论

机器学习建模成功预测了最有可能以退订告终的客户活动。尽管所有模型的结果都很好,但决策树分类器模型似乎是这里最好的。但是,其他模型需要使用不同的设置进行重新调整,以减少过度拟合。

时间序列数据聚类时不要犯这种错误!

原文:https://towardsdatascience.com/dont-make-this-mistake-when-clustering-time-series-data-d9403f39bbb2?source=collection_archive---------3-----------------------

免责声明:这不是原创工作,这篇文章的目的是传播和使更多的内容可访问“时间序列子序列的聚类是无意义的:对以前和未来研究的意义”埃蒙·基奥&杰西卡·林。

最*,我开始研究如何将聚类技术应用于时间序列,我惊讶地发现关于这个主题的帖子非常少(特别是与我想了解 LSTMs 时找到的帖子数量相比)。幸运的是,我发现了埃蒙·基奥和杰西卡·林的这篇论文,它真的很有趣(我鼓励你们去读一读),但是对于那些没有时间(或者不想读)的人,我决定在一篇文章中总结一下。

在处理时间序列数据时,有两种类型的聚类:

  • 整体聚类:当您有几个来自不同机器的时间序列,并且想要比较它们时。
  • 子序列聚类:当原始数据是一个很长的时间序列,需要分成几个部分来对这些部分进行聚类。

本文主要研究第二种类型的时间序列聚类,并提出了破坏性的主张,即时间序列子序列的聚类是没有意义的!

具体来说,他们讨论了通过滑动窗口获得的子序列,他们注意到获得该子序列的其他方法可以产生成功的结果,甚至提出了一种新的方法(我不会在这里深入讨论)。

他们的证据是什么?

为了证明这一说法,他们使用不同的聚类算法和不同的数据集进行了一系列实验,以确保差异仅由后续算法造成。

他们正在做的是从给定数据集的子序列中生成 k 个聚类,从随机数据集的子序列中生成 k 个聚类。一旦这样做了,他们就比较在两种情况下获得的聚类,并观察到这些聚类是相似的,即使数据并不相似。使用整体聚类方法不会出现这种情况,从论文中的这张图可以看出:

Image obtained from the original paper

测量“聚类意义”(z 轴)的方法是获得聚类的稳定性值(具有不同初始质心的不同运行的相似聚类)并除以不同数据集(其中一个是随机的)获得的聚类的差异。

如果该值接*于零,则意味着聚类是稳定的,并且远离为随机数据集生成的聚类。这个集群可以说是有意义的。然而,如果这接*于 1,这意味着相同数据的不同运行之间的差异类似于来自随机数据集的聚类的差异,这没有意义,因为从不同数据集生成的聚类不应该是相似的;值为 1 意味着分类毫无意义。

正如我们在图中看到的,这正是进行子序列聚类时发生的情况,获得的聚类没有意义。由于许多不同的算法和数据集都会发生这种情况,他们得出结论,这是子序列提取方式的结果。

但是为什么呢?

当研究在该聚类中获得的结果时,他们发现当子序列的长度远小于原始长度时,发现所有聚类中心具有正弦形状。聚类中心是该聚类中所有子序列的*均值,但是无论这些子序列的形状如何,结果都是完美的正弦波。

在论文中,他们用一个例子展示了这一点,我不会在这里深入解释,但即使子序列的形状看起来一点也不像正弦波,聚类后的结果如下:

Image obtain from the original paper

结论

在对时间序列数据的子序列进行聚类时,我们需要小心。这证明了用于获得子序列的滑动窗口技术产生了无意义的聚类,即使该技术被认为是有用的并且是众所周知的(它已经在许多发表的论文中被使用)。有其他方法可以获得这些子序列,其中一些可以给出最佳结果,但是,我们必须始终关注生成的聚类,以确保中心对我们的数据有意义,并且它们代表了数据集上真正存在的行为。

如果你想更详细地了解这一点,我建议你阅读原始文件,都非常清楚,解释得很好,这篇文章的目的是总结它,所以我不想进入太多的细节。当然,如果你有任何疑问,请随时问我,但请记住,我并没有完成原著,只是读了一下,并尽我所能做了些什么。

如果你想聊更多,请随时通过 LinkedIn 联系我!

不要过度配合!—如何防止深度学习模型过度拟合

原文:https://towardsdatascience.com/dont-overfit-how-to-prevent-overfitting-in-your-deep-learning-models-63274e552323?source=collection_archive---------1-----------------------

Feature Learning can help you prevent overfitting

了解有关无监督特征学习等常见策略的更多信息,这些策略可以帮助您防止过度拟合

在这篇文章中,我将谈论如何在深度学习模型中防止过度拟合。为了有一个参考数据集,我使用了不要过度拟合!II 来自 Kaggle 的挑战。

如果你真的想赢得这样的挑战,不要使用神经网络,因为它们很容易过度拟合。但是,我们不是来赢得 Kaggle 挑战的,而是来学习如何防止深度学习模型中的过度拟合。

所以让我们开始吧!

基础模型

为了了解如何防止过度拟合,我们首先需要创建一个基础模型来与改进的模型进行比较。基本模型是一个简单的 keras 模型,有两个隐藏层,分别有 128 和 64 个神经元。你可以在这里查看:

使用该模型,我们可以实现超过 97%的训练准确率,但是验证准确率只有大约 60%。在下图中,我们可以看到明显的过度拟合迹象:列车损耗减少,但是验证损耗增加

This is a sign of overfitting: Train loss is going down, but validation loss is rising

如果您看到类似这样的情况,这是您的模型过度拟合的明显迹象:它很好地学习了训练数据,但未能将知识推广到测试数据。有了这个模型,我们在 Kaggle 挑战赛中得到了大约 59% 的分数——不是很好。

那么,让我们看看如何改进这个模型

提高分数

为了提高分数,我们基本上可以做两件事

  • 改进我们的模型
  • 改善我们的数据

我将首先向您展示如何更改基本模型。然后,我将进入功能选择,它允许您更改数据

改进我们的模型

为了防止过度拟合,我将谈论三种调整你的模型的常用方法。

1:简化模型

处理过度拟合的第一步是降低模型的复杂性。在给定的基础模型中,有 2 个隐藏层,一个具有 128 个神经元,一个具有 64 个神经元。此外,输入层有 300 个神经元。这是大量的神经元。为了降低复杂性,我们可以简单地删除层或减少神经元的数量,以使我们的网络更小。没有一个通用的规则来规定要移除多少或者你的网络应该有多大。但是,如果你的网络超负荷,试着把它变小。

2:添加漏失层

脱落层是防止模型过度拟合的简单有效的方法。丢弃层随机丢弃层之间的一些连接。这有助于防止过度拟合,因为如果一个连接断开,网络被迫幸运的是,使用 keras 很容易添加一个断开层。

带有脱落层的新的简化模型可能如下所示:

可以看到,新模型只有一个隐藏层,神经元更少。此外,我还在层间添加了漏失层,漏失率为 0.4。

3:提前停止

防止过度拟合的另一种方法是尽早停止训练过程:不是训练固定数量的时期,而是在验证损失增加时立即停止,因为在此之后,随着更多的训练,你的模型通常只会变得更差。您可以通过 keras 中的回调轻松实现提前停止:

为此,您需要将validation_split参数添加到您的fit函数中。否则,val_loss不是用 keras 来衡量的。

特征选择

如果你看一下原始数据,你会看到有 300 列,只有 250 行。

Overview over the datset

这对于很少的训练样本来说是很多的特征。所以,与其使用所有的特性,不如只使用最重要的特性。一方面,这将使训练过程明显更快,另一方面,它可以帮助防止过度拟合,因为模型不需要学习很多特征。

幸运的是,scikit-learn 提供了强大的特性选择模块,可以帮助您识别数据集的最相关特性。所以,让我们来探索其中的一些方法吧!

f 分数选择

选择相关特征的最简单方法之一是计算每个特征的 F 值。F 值是使用要素之间的方差和每个要素内的方差计算的。高 F 值通常意味着该功能比低 F 值的功能更重要。您可以像这样计算要素的 F 值:

如果你绘制数据,你会看到这样的东西:

F-Score of each of the 300 features of the dataset

如你所见,特征之间的 F 值变化很大。您可以使用selector.scores_获得每一列的分数,或者您可以获得前 10 个特性的索引,如下所示:

f_score_indexes = (-selector.scores_).argsort()[:10]

递归特征消除

另一种方法是递归特征选择。与其他方法不同,使用 RFE,您不需要为每个特征计算分数,而是在越来越小的特征集上多次训练分类器。在每次训练之后,计算特征的重要性,并且从特征集中消除最不重要的特征。

您可以像这样获得这些特征的索引:

rfe_indexes = np.where(rfe_values)[0]

结果

在本文的开始,我们从一个过度拟合的模型开始,这个模型几乎不能达到 50%以上的精度。下面,您可以看到新模型的结果,在选择功能后根据数据进行训练:

Results of the improved model

它仍然不是完美的,但正如你所看到的,模型过度拟合的方式更少。在 Kaggle 挑战赛中,新模型的得分约为80%——比基本模型高出 20%。

不要浪费暂停时间来显示你的愚蠢

原文:https://towardsdatascience.com/dont-show-your-stupidity-by-wasting-a-timeout-20fe9e3f4de1?source=collection_archive---------14-----------------------

培顿·曼宁是有史以来最聪明的四分卫,他一次又一次地犯这个错误。尽管犯了无数次这样的错误,汤姆·布拉迪还是获得了六枚超级碗戒指。Russel Wilson 被认为是一个杰出的决策者(除了在超级碗中的一次球门线传球),但却经常犯这种错误。

Picture of Tom Brady calling timeout. Photo by https://nflspinzone.com/2017/01/05/nfl-playoffs-2017-top-15-super-bowl-51-matchups-possible/11/

足球中有一种打法让我疯狂。不是第三回合的短传。这不是第四回合的*底船。这不是一次又一次的投篮得分,而是两分。这比所有这些加起来还要糟糕得多。

当比赛时钟倒数到最后几秒,一名四分卫决定叫暂停时,我无法忍受。

从我记事起就一直困扰着我。真的吗?你宁愿在自己的 40 码线上浪费比赛第三节的暂停时间?你不认为暂停对你或你比赛后期的防守有帮助吗?

每个人都知道比赛结束时暂停有多重要。如果一个队在比赛的最后一分钟落后几分,有两次暂停比一次暂停有很大的优势。它让你有能力把球扔向球场中央,而不是只能扔给边线附*的球员。但是上帝禁止你没有额外的暂停,因为你不想接受比赛处罚的 5 码延迟!

我决定我需要知道一支球队为了那 5 码的罚球放弃了什么。我没有踢过任何水*的竞技足球,所以也许我错过了什么?也许让驱动器保持活动状态比保持超时状态更明智?与在游戏结束时需要额外的时间相比,保持驱动器的活力有多大的影响?

因为我可以对数据有一点深入的了解,所以我写了一个简短的分析和一个较长的分析,给那些像我一样的真正的数据书呆子。对于那些想看我的代码的人,这里有一个链接:https://github.com/anchorP34/NFL-Analytics

简短分析

我决定看看进攻性的财产,并把它们分成“驱动集”和“驱动”。驱动组是每组 1-4 次,而驱动是从进攻队接到球到最终结果(踢、失误、触地得分等)的每一次比赛。不管它是一个驱动器组还是一个驱动器,最起码的目标是得到第一个 down。触地得分当然很好,但是获得第一次触地得分将保证比赛继续下去。正如你从下面的方框图中看到的,成功的驱动集往往更靠*第一个下跌标记,而不是更远,这正是我们所期望的。

Box plot to show the distribution of each down and the successful drive sets associated with them. Yellow means the drive set ended in a first down or touchdown, the green means there wasn’t a first down or touchdown achieved.

有关驱动器和驱动器集的一些概述统计信息,以下是驱动器和驱动器集的*均成功率:

驱动装置

  • 64%的情况下以第一回合结束
  • 有 8%的机会以触地得分告终
  • 以 15%的得分率结束

满驱动器

  • 66%的时间里至少有 11 次下跌
  • 有 21%的机会以触地得分告终
  • 37%的时间以得分结束

由于 NFL 中的每个驱动组都有大约 64%的成功率获得第一次击倒,驱动组开始的位置对结果有影响吗?对于第一次触地得分,不是真的,但是对于得分和触地得分,绝对是。开始于 50 码以外的驱动组很少以触地得分或投篮得分结束,但是正如你所看到的,每靠*端区 10 码,可能性就开始增加。这是有道理的:你越接*端区,球队得分的可能性就越大。

Line graph to show the results of drive sets. First down’s stay consistent regardless of where on the field the drive starts, but scoring points and touchdowns need to be in enemy territory to really start to have a real chance of success.

全驱动呢?由于一个完整的驱动器可以有多个第一次下降,得分并不局限于前 4 次下降,成功的百分比有一个不同的轨迹比驱动器设置。从 2014 年到 2018 年,一支球队要想有超过 50%的机会在一次击球中得分,就需要在距离 40 码和 50 码之间或更*的地方开始击球。

Line graph of the start of a drive in relation to where

让我们快速回顾一下第一次触地得分和触地得分:

  • 不管你在场上的什么位置,第一次传球的命中率始终在 65%左右
  • 为了有利于在一次击球中得分,你的击球需要从敌人的领地开始
  • 对于驱动组来说,越接*端区,触地得分的可能性就越大

太好了…但是这和暂停有什么关系呢?

在进行进一步分析后,如果在比赛的最后一分钟有额外的暂停,一支球队赢得比赛的几率会增加约 23%。不是增加 23%的得分或第一次触地得分的几率,而是赢得比赛!

如果你的胜算因为多出来的时间而增加了 23%,那么一个 5 码的处罚会对你获得第一次进攻和保持击球活力的机会造成多大的伤害呢?

Success percentage of gaining a first down or touchdown for a drive set. Obviously, 1st and short is the most successful while third and very long is the least successful

这张热图显示了成功第一次触地得分的可能性,这取决于第一次触地得分和成功第一次触地得分的距离。例如,你可以看到第二下短比第三下长有更高的成功率。利用这张热图,我们来看一个例子:

现在是第二次进攻,还有 4 码,比赛时间不多了。在第二次下跌和第四次下跌中,第一次成功下跌的可能性是 73%。如果你对比赛的延迟进行 5 码的处罚,而不是使用暂停,成功的概率会下降到 54%。如果你把球扣向地面,你的机会减少到 51%。在我看来,我宁愿用超过 50%的机会来转换第一个向下,而不是使用暂停。

以下是与热图相同的值,但显示方式不同:

Success percentages of a first down or touchdown depending on the down and distance away from a first down

在这里,我们可以更容易地想象出两次下跌之间的百分比差异。现在让我们考虑一下球门线看台。如果你在 2 码或 3 码线上,就成功转换第一次下压(在这种情况下是触地得分)而言,第一次和第二次下压几乎没有区别。如果你的比赛时间快用完了,扣球比叫暂停或推迟比赛更有意义。几乎没有区别。然而,第三次下降是一个不同的故事。在第三次进攻时受罚会大大降低你第一次进攻的机会。例如,仅仅从 3 号和 2 号到 3 号和 7 号罚 5 码,成功率就从 60%下降到 40%。然而在正常情况下,我仍然不认为这是使用超时的正当理由。

结论

我很兴奋地证实了我最初的假设,即超时比保持驱动器运行更有价值。随着赢得比赛的几率增加 23%,对任何球队来说,坚持下半场暂停都是至关重要的。

当谈到接受 5 码的处罚时,这取决于球队认为他们的接受门槛在哪里。第 1 名和第 10 名以及第 1 名和第 15 名之间的差别是从 65%的成功率下降到 51%。如果你仍然有超过 50%的机会第一次击倒对手,我认为你应该接受这样的惩罚,尽可能多地保持暂停。如果在比赛后期这是一个重要的驱动,更接*终点区域,而你可以得分,那么我可以理解使用暂停。然而,在第三节使用一个,因为比赛时间快用完了,或者防守排列不是你试图进行的比赛的最佳选择,不值得在比赛结束时放弃暂停的杠杆作用。

体育迷几乎都同意,在 NFL 赢得一场比赛比在任何其他运动中都要难。规则很复杂,误差很小,球队要取得成功确实需要场上的 11 名球员。

不要让自己更难过。接受比赛延迟的 5 码处罚,并在比赛结束时给自己一次战斗的机会。

长篇分析——写给所有真正的书呆子

那么,我是如何计算出,如果一个球队在比赛结束时有额外的暂停,他们会有 23%的胜算呢?使用相同的数据集,我运行了一个逻辑回归算法,该算法使用了比赛的剩余时间(以秒为单位),如果控球的球队是主队,则该队的净得分是上升还是下降,下降,距离第一次下降的码数,距离触地得分的码数,控球队的剩余超时和防守队的剩余超时。我的反应变量是他们是否赢得了比赛。

由于我这篇文章的重点是“你应该调用超时来保持驱动器的活力,还是在你需要的时候保存它”,我看了看游戏中什么时候还有 600-100 秒被分成 100 秒的增量。当一个队正在做最后冲刺的时候,那将是使用暂停的最有影响力的时间,如果一名球员在界内被拦截,他们必须用它来停止计时。

Parameter t-statistic values of the logistic regression model ran at X seconds left remaining in the game.

从上图中可以看出,X 轴上的每个点都与另一个逻辑回归模型相关,该模型的记录中还有剩余时间或更少的时间。虚线是统计显著性参数的 95%置信区间,因此在这些区间之外意味着该参数高度显著。

从眼球测试开始,以确保事情有意义,负参数是 yardline_100(距离端区的码数),down 和 ydstogo(距离第一次 down 的码数)。所有这三个都有道理,这些值越高,你获胜的机会就越小(离端区越远,离第一次进攻越远,比第一次或第二次进攻更深入)。

我们还看到,到目前为止,分数差异是模型中最有影响的因素,这是有意义的,因为井喷将给出谁会赢的明显答案。我发现有趣的是,直到最后一个模型,游戏中剩余的时间不被认为是一个重要的变量。但是你知道是什么吗?

拥有足球的球队的暂停次数对每个型号都有统计学意义!

至于模型对数据的拟合有多准确,还不错!每个模型的 R *方在. 65-.80 的范围内比我预期的要高。

这是有意义的,因为你越接*游戏的结尾,大多数游戏的结果应该越真实。有些比赛可能会相差 1 或 2 分,做出决定可能会很困难,但大多数比赛都有一个明确的赢家,不管最后剩下的几分钟。

Logistic regression output for the model that was looking at the last 100 seconds of a football game

在这里,posteam_timeouts_remaining 参数是一个重要的因素,其系数为. 2061。. 2061 可以解释为“posteam_timeouts_remaining 增加一个单位,保持其他参数不变,将产生. 2061 的对数几率增加。”如果我们取. 2016 的指数,我们得到 1.2289,这意味着优势比增加了大约 23%。

趣味可视化

关于团队年复一年的首次成功率,我认为另一个有趣的形象化现象是:

First down success rates for each team in the NFL for the 2014–2018 seasons

对于 NFL 的大多数球队来说,第一失分率似乎有一个上升和下降的趋势。他们一年上升,一年下降。你可以看到他们中的一些(看看堪萨斯城和洛杉矶公羊队)在两三年的时间里有了巨大的增长,但我发现有趣的是,不管一支球队有多糟糕,在这一年里,他们更有可能在比赛中获得第一次胜利。

不要睡觉:建立你的第一个睡意检测系统

原文:https://towardsdatascience.com/dont-sleep-building-your-first-drowsiness-detection-system-28a9903015f3?source=collection_archive---------5-----------------------

权威的建造指南

我如何用计算机视觉、人脸识别和 Matlab 建立睡意检测系统

A sleeping student in front of laptop — Extracted from Medical News Today

介绍

这是非常重要的一天,测试和项目的截止日期是下周,但你没有准备太多,因为新的光环发布。出于焦虑,你冲到图书馆,打开你的笔记本电脑。然而,当你在提升你的角色时失眠了,你的意识很快把你带到了梦境。咖啡没有用,因为你在笔记本电脑前睡得很香。时间不多了,你拼命保持清醒。

如果我告诉你…你的笔记本电脑可以帮助你保持清醒。

解决方案:睡意检测系统(DDS)

还有一个警报…

想象你是那个可怜的家伙,你可以激活安装在你的笔记本电脑上的 DDS 应用程序。这将触发你的笔记本电脑摄像头。每当你昏昏欲睡时,你的笔记本电脑就会注意到并给你的耳机发出警报。当你醒来后,你的笔记本电脑会注意到并关闭闹铃。然后你可以继续你的工作。

酷用例..?

现在,让我们来看看如何开发 DDS 模型。希望你准备好了,☺

Drowsiness Detection System Coded in Matlab

我们怎么知道你困了?

对嗜睡的天真分析

想象一下你的朋友或爱人困倦的脸,你怎么知道他们困了?嗯,最明显的迹象是:

  1. 眼睛:眼睛睁开(清醒),眼睛闭上(困倦)
  2. 嘴巴:嘴巴紧闭(清醒),嘴巴张开/下垂(困倦)
  3. 头部位置:头部在同一位置(清醒),头部上下摆动(困倦)

我们如何教我们的电脑注意到这些迹象?

计算机视觉分析

眼睛

黑色像素与白色像素的比率(BW): 检测你的眼睛是睁开还是闭上。因为你的瞳孔是黑色的,你的眼睛睁得越大,就会出现越多的黑色像素。

然而,问题是,可能有其他混淆变量会中断 BW 比率:

  1. 摄像机到用户的距离:用户可能会远离摄像机,这取决于他们的最佳检查位置。显然,它们离得越远,BW 比就越小,反之亦然。
  2. 眼睛和瞳孔大小:不同种族的眼睛大小可能不同。白种人和拉丁美洲人的眼睛大小不同。更不要说像我这样体重比特别小的中国人了。干杯。

为了解决这些混杂变量,我们需要在激活时校准 BW 比率。这是我们确定用户是睁开还是闭上眼睛的基线。

物体检测和贴标:检测开口是否裂开。如果嘴是闭着的,那么就会有一个相连的嘴唇。但是,如果嘴是分开的,那么你的嘴唇是不相连的,将返回多个检测到的对象/嘴唇。

头部位置

使用加速度计的面部检测:绘制面部的运动。你的面部垂直运动越多,你就越有可能犯困。

我们的范围

在这份出版物中,我们将关注眼睛和嘴巴作为我们对睡意进行分类的标识符。现在,让我们开始吧:)。

我们应用程序的技术架构

模块描述:

  1. DrowsinessDetection.m :捕捉现场摄像机跟踪,并对拍摄的每个视频帧运行分类器方法
  2. EyeDetection.m :捕捉并裁剪每个视频帧的眼睛,并运行分类变量(比率)
  3. 嘴部检测. m :捕捉并裁剪每个视频帧的嘴部,并运行分类变量(检测到嘴唇)
  4. Scoring.m :根据 EyeDetection.mMouthDetection.m 返回的测量值对睡意进行分类
  5. MeasureTracking.m :循环显示采集到的不同图片,打印出 EyeDetection.mMeasureDetection.m 的不同测量值进行分析。

请看看下面的图表,以便更好地理解。

DDS Architecture

DDS 编码

创建 DDS 控制器(DrowsinessDetection.m)

DDS 控制器的工作是激活您笔记本电脑的网络摄像头,并使用分类器来评估您的功能。

首先,让我们用点跟踪器创建一个人脸检测器对象来跟踪人脸检测器对象

**faceDetector = vision.CascadeObjectDetector();
pointTracker = vision.PointTracker(‘MaxBidirectionalError’, 2);**

一旦我们完成,你可以启动摄像头,然后添加循环,以确保它捕捉帧。系统会一直拍照,直到检测到一个人。

一旦检测到人脸,我们将校准特征。这将产生以下初始比率计算。

First Calibration upon initiation of the system

然后我们会激活 EyeDetection.m 来检测图像里面的眼睛。成功检测的第一幅图像将用于启动后续分类的阈值比率。

**cam = webcam();
while true
disp(‘Open your eyes wide before picture is taken’)
pause(3)
videoFrame = snapshot(cam);
frameSize = size(videoFrame);
try
   EyeDetection
   initialratio=ratio;
   thresholdratio = initialratio*0.95;
   break**

一旦我们检测到这个人的脸和眼睛,我们将继续准备拉响 tiktok 警报。只有当 Scoring.m 返回‘sleep’作为结论时,我们才会运行这个声音。

如果没有检测到人脸,应用程序将继续拍摄快照并播放蜂鸣器,直到检测到人脸或用户强制停止它。

眼睛检测嘴巴检测的输出将被传入计分模块进行计分并得出结论。

**EyeDetection
disp([‘ratio is ‘,num2str(ratio,3),’ threshold is ‘,num2str(thresholdratio,3)]) ;****MouthDetection
disp(‘Lips detected: ‘+lipsdetected);**

一旦你停止应用程序,网络摄像头和视频对象将被释放。

**clear cam;
release(videoPlayer);
release(pointTracker);
release(faceDetector);**

捕捉眼睛睡意(EyeDetection.m)

捕捉眼睛边界框对象

给定摄像机拍摄的图像,我们将使用 CascadeObjectDetector 启动眼睛检测器对象。

级联物体检测器使用维奥拉-琼斯算法检测人的脸、鼻子、眼睛、嘴或上身。你也可以使用图像标签来训练一个自定义分类器来使用这个系统对象。— Mathworks

请参考这个惊人的出版物,了解关于 Viola-Jones 算法用于检测人脸。

[## 使用 Viola Jones 算法的面部部分检测- IEEE 会议出版物

本文提出检测图像中的人脸并定位图像中的人脸特征。对…的检测

ieeexplore.ieee.org](https://ieeexplore.ieee.org/abstract/document/8014636)

我们将使用 CascadeObjectDetector 来获取你的脸部的边界框并隔离你的眼睛。

**im1=videoFrame;****% Get EyeDetector Object
EyeDetector = vision.CascadeObjectDetector(‘LeftEyeCART’);****% only one eyes are used
% Use EyeDetector on A and get the faces
EyeBBOX =step(EyeDetector,im1);****% Annotate these eyes on the top of the image
imannotateeye = insertObjectAnnotation(im1,’rectangle’,EyeBBOX,’Eye’);****% Getting the last box and crop
EyeBBOX=EyeBBOX(1,:);
imeye3 = imcrop(im1,EyeBBOX);**

Getting the eye part from my own face

睡眼的目标检测

然后,我们将图像处理成黑色和白色,然后创建一个 strel(形态元素/形状)。

一个 strel 对象代表一个*面形态结构元素,它是形态膨胀和腐蚀操作的重要组成部分。我们使用 strel 函数(如下所述)来创建一个*面结构元素。— Mathworks

[## 形态结构元素- MATLAB

一个 strel 对象代表一个扁*的形态结构元素,它是形态结构的重要组成部分。

www.mathworks.com](https://www.mathworks.com/help/images/ref/strel.html)

**% Process the image to bw, complement and strel
imeye4=im2bw(imeye3,0.1);
imeye5=imclose(imeye4, strel(‘sphere’,4));**

然后,我们将通过对所有图像像素求和得到白色像素的数量,每个值为 1 以表示白色像素。这将允许我们找到 BW 比率。

**numberOfWhitePixels = sum(imeye5);
numberOfBlackPixels = numel(imeye5) — numberOfWhitePixels ;
% Now calculate the ratio.
ratio = numberOfBlackPixels / numberOfWhitePixels;**

My own Open and Closed Eyes bw ratios

捕捉口腔睡意(口腔检测. m)

捕捉嘴部边界框对象

当你的嘴唇半张(分开)时,我们将描述困倦的嘴。通过读取来自摄像机的图像,我们将使用 CascadeObjectDetector 提取嘴部对象。

**mouthDetector = vision.CascadeObjectDetector(‘Mouth’,’MergeThreshold’,90);
 % Use Mouth Detector on A and get the faces
 MouthBBOX =step(mouthDetector,im1);
 % Annotate these mouth on the top of the image
 imannotatemouth = insertObjectAnnotation(im1,’rectangle’,MouthBBOX,’Mouth’);
 % Getting the last box and crop
 MouthBBOX=MouthBBOX(1,:);**

Getting my lips using Matlab CascadeObjectDetector

有趣的案子

有趣的是,当应用程序将 3 张嘴与单眉和浓眉的人分类时,会出现一些有趣的情况。出于某些原因,这些物体被归类为嘴。对我的参与者的骚扰深表歉意。但是不要担心,修复工作即将到来。

**% If mouth are above the eyes. Then please discard it
if MouthBBOX(2)<=EyeBBOX(2)+EyeBBOX(4)
MouthBBOX= [0 0 1 1];
binaryImage = imcrop(im1,MouthBBOX);**

瞌睡虫嘴的目标检测

然后,我们将检测它的对象,以便它们将附*的斑点连接成一个对象。然后,我们将所有标签和对象存储在 LabeledImConnectedObj 中,以查看嘴唇是否分开。

**% Process the image to bw, complement and strel****binaryImage= im2bw(binaryImage,0.4);
binaryImage = imclose(binaryImage, true(8)); % Close gaps and connect nearby blobs.
binaryImage = imcomplement(binaryImage);****% bwlabel should contain bunch of objects which are separated from others
strel[LabeledIm,ConnectedObj] = bwlabel(binaryImage);**

从这里我们计算物体的数量,看看嘴是否裂开。

**lipsdetected = ConnectedObj;
if lipsdetected>=2
   mouthstatus = ‘split’;
else
   mouthstatus=’closing’;
end**

My own Closing and Split Mouth Object Detected Counts

计分. m 用概率分类预测

朴素贝叶斯方法

朴素贝叶斯的思想是构造代表特征值的相关分类器。朴素贝叶斯分类器将考虑每个已知特征,以独立贡献某些类的概率。

在我们的例子中,给定用户的嘴和眼睛困倦的事实(闭上眼睛,张开嘴),用户困倦的概率是多少?显然,这种可能性比我们将用户的嘴和眼睛分类为清醒(睁开眼睛,闭上嘴巴)时要高。

假设特征(嘴和眼睛)是独立的。这是公*的,因为这两个特征都受你的睡意影响,并且彼此不依赖。

请使用本出版物来了解朴素贝叶斯

[## 朴素贝叶斯分类器

什么是量词?

towardsdatascience.com](/naive-bayes-classifier-81d512f50a7c)

使用朴素贝叶斯定理,我们推导出概率百分比。

Percentage of sleeping based on eyes and mouth detection verdicts

因此,每次相机发送图像时, scoring.m 将检查图像,并根据概率判断一个人是否困倦。

概率分类编程

首先,我们将提取眼睛和嘴巴检测的结果。然后,我们会掷出一个随机数,与概率分类进行对比,宣告你是清醒还是困倦。这模拟了你睡着或醒着的概率。

**awakeprob = [100 85 50 15]
Randomnumber = rand(1)*100
if strcmp(eyestatus ,’open’)&&strcmp(mouthstatus,’closing’)
   if randomnumber <= awakeprob(1)
      verdict = ‘awake’;
   else
      verdict = ‘sleepy’;
end
elseif strcmp(eyestatus ,’open’)&&strcmp(mouthstatus,’split’)
   if randomnumber <= awakeprob(2)
      verdict = ‘awake’;
   else
      verdict = ‘sleepy’;
   end
elseif strcmp(eyestatus ,’closed’)&&strcmp(mouthstatus,’closing’)
   if randomnumber <= awakeprob(3)
      verdict = ‘awake’;
   else
      verdict = ‘sleepy’;
end
else
   if randomnumber <= awakeprob(4)
      verdict = ‘awake’;
   else
      verdict = ‘sleepy’;**

这样,你就成功地制作了你的第一个睡意检测系统。恭喜你!!!

寻找眼睛和嘴巴检测的阈值(MeasureTracking.m)

MeasureTracking.m 的目的是保存样本数据并评估从眼睛和嘴巴检测中区分清醒或困倦分类的一般阈值。

假设我睁眼产生 256.67 BW 比,闭眼产生 211.58 BW 比,DDS 怎么知道我闭眼了?

使用统计推断

统计推断拯救了我们。这意味着我们将开始通过收集和分析样本阈值来推断群体阈值。

[## 带有假设检验的统计推断

推断统计学帮助我们通过研究一个更大的群体来推断未知的属性或行为

medium.com](https://medium.com/@yogita.kinha/statistical-inference-with-hypothesis-testing-43807b932d0a)

简而言之,我们假设存在 BW 比率的一般百分比阈值来区分睁眼和闭眼。人口阈值可以从一定的样本量中归纳出来。

在这种情况下,我们检索了 19 名参与者,并收集了成对的睁开和闭上眼睛的照片。然后,我们测量了每一个的 BW 比率,该比率将被转换为最佳阈值。顺便提一下,我们确保样本是不同种族和国籍的。

眼睛检测样本结果

这些比率取自睁眼和闭眼的照片

Sample 1: Open Eyes (bw ratio: 256.67) Closed Eyes (bw ratio: 211.58)

Sample 2: Open Eyes (bw ratio: 203.12) Closed Eyes (bw ratio: 186.87)

Sample 15: Open Eyes (bw ratio: 144.00) Closed Eyes (bw ratio: 132.48)

样品分析—眼睛

由此,我们分析出最佳阈值是 8%。一个很简单的计算,却带来了 86.67%的准确率。

口腔检测样本结果

Sample 1: Awake Mouth (LipsDetected:1) Sleepy Mouth (LipsDetected: 2)

样品分析—口腔

从这里我们使用最佳阈值作为 2 个对象。这个简单的阈值已经产生了 84.21%的准确度。

结果呢

一个视频解释了数十亿张图片。😃

Drowsiness Detection System Demonstration

未来的改进/挑战

这种应用的最大挑战是偏差。不幸的是,对于一些不同的面部特征,系统在检测嘴唇和眼睛时会变得疯狂。这很尴尬,但我为我的一些参与者鼓掌,他们耐心地接受了这种偏见,并仍然愿意与我保持联系。谢谢!

为了缓解这个问题,我们在应用程序启动时校准了读数,以考虑到人的眼睛或嘴唇的大小。这让我们大大减少了不同种族之间面部特征的差距。然而,这远非完美。所以请大家随意解决,投稿。

至于你的进一步参考,我张贴这个 TED 视频,它最好地描述了我的机器如何挣扎。

TED Talk by Joy Buolamwini, fighting bias in algorithms

目的、Github 代码和您的贡献

此概念证明(POC)的目的是作为阿姆斯特丹自由大学课堂项目的一部分而创建的。该应用程序的目标是使用计算机视觉和人脸检测算法来帮助学生或专业人员在关键项目期间在笔记本电脑前保持清醒。

在这个 POC 中,我使用 Matlab 作为脚本语言, vision。CascadeObjectDetector 谢谢大家:)

Github Python 笔记本代码位于下面。

[## Vincent tatan/drowsiness 检测系统

计算学生和专业人士困倦程度的代码。然后它会在检测到你的时候发出警报…

github.com](https://github.com/VincentTatan/DrowsinessDetectionSystem)

您可以随意克隆这个库,并在有时间的时候贡献自己的一份力量。

感谢

我要感谢来自阿姆斯特丹 VU 大学的同学们,是你们给了我机会在我的偏见实验中使用你们。如果因为某些原因,我的机器把你的眉毛当成了嘴唇,我向你道歉,我会退缩并喃喃自语“坏机器!不好!”。我真的很喜欢学习计算机视觉和 Matlab 来创造这个有用的产品。

最后…

咻…就是这样,关于我的想法,我把它写成了文字。我真的希望这对你们来说是一个伟大的阅读。因此,我希望我的想法可以成为你发展和创新的灵感来源。

请在下面评论出来建议和反馈。

快乐编码:)

关于作者

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

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

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

请通过 LinkedIn Medium Youtube 频道 联系文森特

免责声明

本免责声明告知读者,文中表达的观点、想法和意见仅属于作者,不一定属于作者的雇主、组织、委员会或其他团体或个人。参考文献是从列表中挑选的,与其他作品的任何相似之处纯属巧合

这篇文章纯粹是作者的个人项目,绝无任何其他不可告人的目的。

不要担心求解器的事情

原文:https://towardsdatascience.com/dont-sweat-the-solver-stuff-aea7cddc3451?source=collection_archive---------1-----------------------

Scikit-Learn 中更好的逻辑回归模型提示

Lighthouses Give Warnings

逻辑回归是机器学习分类的基本算法。如果你是一名正在实践或有抱负的数据科学家,你会想知道如何使用它的来龙去脉。另外,Scikit-learn 的LogisticRegression给出了关于改变默认求解器的警告,所以这是一个学习何时使用哪个求解器的好时机。😀

FutureWarning: Default solver will be changed to 'lbfgs' in 0.22\. Specify a solver to silence this warning.

在本文中,您将了解 Scikit-learn LogisticRegression规划求解选项,并看到对它们的两个评估。此外,您将看到关键的 API 选项,并获得常见问题的答案。到本文结束时,您将对 Scikit 中的逻辑回归有更多的了解——学习而不是担心求解器的问题。😓

我在这个分析中使用的是 Scikit-learn 版本 0.21.3。

2019 年 12 月 20 日更新:在 Scikit-learn 核心开发者和维护者 Andreas Mueller 提供了有益的反馈后,我对这篇文章做了几处编辑。

何时使用逻辑回归

分类问题是指你试图预测离散的结果,比如某人是否患有某种疾病。相比之下,回归问题是指试图预测一个连续变量的值,如房屋的销售价格。尽管逻辑回归的名字中有回归,但它是一种用于分类问题的算法。

逻辑回归可能是最重要的监督学习分类方法。这是广义线性模型的快速、通用扩展。

逻辑回归是一种优秀的基线算法。当特征和目标之间的关系不太复杂时,它工作得很好。

逻辑回归生成通常可解释的要素权重,这在您需要能够解释决策原因时特别有用。这种可解释性经常会派上用场——例如,对于需要证明其贷款决策合理性的贷方。

逻辑回归问题没有封闭解。这很好——我们不使用线性回归问题的封闭解,因为它很慢。😉

求解逻辑回归是一个优化问题。谢天谢地,好人已经创造了几个求解算法,我们可以使用。😁

规划求解选项

Scikit-learn 提供了五种不同的解算器。每个求解程序都试图找到最小化成本函数的参数权重。这里有五个选项:

  • newton-cg —一种牛顿法。牛顿法使用精确的海森矩阵。对于大型数据集来说,它很慢,因为它需要计算二阶导数。
  • lbfgs —代表有限记忆 Broyden–Fletcher–gold farb–Shanno。它用梯度评估来*似二阶导数矩阵更新。它只存储最*的几次更新,因此节省了内存。对于大型数据集,它的速度不是很快。从 Scikit-learn 版本 0.22.0 起,它将成为默认求解器。
  • [liblinear](https://en.wikipedia.org/wiki/Coordinate_descent) —大型线性分类库。使用坐标下降算法。坐标下降基于通过在循环中求解单变量优化问题来最小化多变量函数。换句话说,它一次朝一个方向向最小值移动。它是 0.22.0 之前的 Scikit-learn 版本的默认解算器。它在高维情况下表现很好。它确实有一些缺点。它会被卡住,无法并行运行,只能用一对多解决多类逻辑回归。
  • [sag](https://hal.inria.fr/hal-00860051/document) —随机*均梯度下降。梯度下降和增量聚集梯度方法的变体,使用先前梯度值的随机样本。适用于大数据集。
  • saga下垂的延伸,也允许 L1 调整。一般来说训练速度应该比下垂快。

关于不同选项的精彩讨论可以在这个堆栈溢出答案中找到。

来自 Scikit-learn 文档的下图列出了求解器的特征,包括可用的正则化惩罚。

为什么默认求解器会改变?

liblinear处理小数据集速度很快,但存在鞍点问题,无法在多个处理器内核上并行化。它只能用一 vs . rest 来解决多类问题。这也不利于截取,不利于解释。

lbfgs避免了这些弊端,速度相对较快。对于没有真正大型数据集的大多数情况,这是最佳选择。关于为什么默认设置被改变的一些讨论在这个 GitHub 问题中。

让我们用两个预测分类项目来评估逻辑回归求解器—一个二元预测分类项目和一个多类预测分类项目。

规划求解测试

二元分类求解器示例

首先,我们来看一个二元分类问题。我使用了内置的 scikit-learn 乳腺癌数据集。目标是预测乳腺肿块是否是癌性的。

这些特征由关于细胞核的数字数据组成。它们是由活检的数字化图像计算出来的。数据集包含 569 个观测值和 30 个数值特征。我将数据集分为训练集和测试集,并使用不同的求解器对训练集进行网格搜索。你可以访问我的 Jupyter 笔记本,它用于对 Kaggle 的所有分析。

最相关的代码片段如下。

solver_list = ['liblinear', 'newton-cg', 'lbfgs', 'sag', 'saga']
params = dict(solver=solver_list)
log_reg = LogisticRegression(C=1, n_jobs=-1, random_state=34)
clf = GridSearchCV(log_reg, params, cv=5)
clf.fit(X_train, y_train)
scores = clf.cv_results_['mean_test_score']

for score, solver in zip(scores, solver_list):
    print(f"  {solver} {score:.3f}" )

结果如下:

 liblinear 0.939
  newton-cg 0.939
  lbfgs 0.934
  sag 0.911
  saga 0.904

sagsaga 的精度值略低于同类产品。

缩放特征后,解算器都表现得更好,并且 sagsaga 与其他解算器一样准确。

 liblinear 0.960
    newton-cg 0.962
    lbfgs 0.962
    sag 0.962
    saga 0.962

现在让我们看一个有三个类的例子。

多类求解器示例

我用 Scikit-learn 的葡萄酒数据集评估了多类分类问题中的逻辑回归求解器。该数据集包含 178 个样本和 13 个数字特征。目标是从葡萄酒的化学特征来预测用来酿酒的葡萄的类型。

solver_list = ['liblinear', 'newton-cg', 'lbfgs', 'sag', 'saga']
parameters = dict(solver=solver_list)
lr = LogisticRegression(random_state=34, multi_class="auto", n_jobs=-1, C=1)
clf = GridSearchCV(lr, parameters, cv=5)
clf.fit(X_train, y_train)
scores = clf.cv_results_['mean_test_score']

for score, solver, in zip(scores, solver_list):
    print(f"{solver}: {score:.3f}")

Scikit-learn 给出警告,说明 sagsaga 模型没有收敛。换句话说,他们从来没有到达过最低点。不出所料,结果对那些解算者来说并不太好。

liblinear: 0.962
newton-cg: 0.947
lbfgs: 0.955
sag: 0.699
saga: 0.662

让我们使用 Seaborn 库制作一个小小的条形图来显示分数。

sag and saga lagging show lower accuracy

在 0 和 1 之间缩放特征后,然后 sagsaga 达到与其他模型相同的*均准确度分数。

liblinear: 0.955
newton-cg: 0.970
lbfgs: 0.970
sag: 0.970
saga: 0.970

Looking better for sag and saga

注意,这两个例子都是小数据集。此外,在这些示例中,我们没有考虑内存和速度需求。

底线:即将到来的默认 lbfgs 解算器对于大多数情况来说是一个很好的首选。如果你正在处理一个大型数据集或者想要应用 L1 正则化,我建议你从 saga 开始。记住, saga 需要相似比例的特征。

你有牛顿-cg 或者凹陷的用例吗?如果有,请在评论中分享。💬

接下来,我将在 Scikit-learn 中揭开 LogisticRegression 的关键参数选项的神秘面纱。

Logistics

因素

Scikit-learn LogisticRegression 类可以接受以下参数。

penaltydualtolCfit_interceptintercept_scalingclass_weightrandom_statesolvermax_iterverbosewarm_startn_jobsl1_ratio

我不会列出下面所有的参数,只是从那些对大多数人最有价值的参数中摘录一些。省略部分见文件。我已经用斜体添加了额外的信息。

C —浮点型,可选,默认= 1。值越小,正则化程度越高。正则化强度的倒数。必须是正值。通常用对数搜索:[.001,. 01,. 1,1,10,100,1000]

random_state : int,RandomState instance 或 None,可选(默认=None) 注意,为了再现性,必须在此设置随机状态。

solver { '牛顿-cg ',' lbfgs ',' liblinear ',' sag ',' saga'},可选(默认='liblinear ')。更多信息见上图。

在 0.20 版本中更改:在 0.22 版本中,默认将从“liblinear”更改为“lbfgs”。

multi_class : str,{'ovr ','多项式',' auto'},optional(默认='ovr ')如果选择的选项是' ovr ',那么二元问题适合每个标签。对于“多项式”,最小化的损失是整个概率分布的多项式损失拟合,即使数据是二进制的。当 solver =“liblinear”时,“多项式”不可用。如果数据是二进制的,或者如果 solver='liblinear ',则' auto '选择' ovr ',否则选择'多项式'。

在 0.20 版本中更改:在 0.22 中默认将从‘ovr’更改为‘auto’。 ovr 代表一对休息。参见下面的进一步讨论。

l1_ratio : float 或 None,可选(默认=None)弹性网混合参数,0 < = l1_ratio < = 1。仅在 penalty='elasticnet '时使用。设置' l1_ratio=0 相当于使用 penalty='l2 ',而设置 l1_ratio=1 相当于使用 penalty='l1 '。对于 0 < l1_ratio < 1,罚的是 l1 和 L2 的组合。只针对佐贺。

注释:如果你有一个多类问题,那么将multi-class设置为auto将会使用多项式选项。那是理论上最合理的选择。auto很快就会默认。

如果想用 saga 解算器使用一些 l1 正则化,使用 l1_ratio 。请注意,与 ElasticNet 线性回归选项一样,您可以混合使用 L1 和 L2 惩罚。

还要注意,默认情况下应用了C=1的 L2 正则化。这种默认的正则化使模型对多重共线性更加稳健,但代价是可解释性降低(向 Andreas Mueller 致敬)。

拟合模型后,属性为:classes_coef_intercept_n_itercoef_包含一个特征权重数组。

逻辑回归常见问题

现在让我们在 Scikit-learn 中解决那些你可能对逻辑回归有疑问的问题。

我可以使用 LogisticRegression 解决多标签问题吗——这意味着一个输出可以同时成为多个类的成员?

没有。不好意思,如果你需要的话,在这里找另一个分类算法。

我应该使用哪种正则化?

在偏差/方差权衡中,正则化使你的模型偏向事物的偏差一方。正则化使得逻辑回归模型更具普遍性,尤其是在数据点很少的情况下。您可能想要对正则化参数 C 进行超参数搜索。

如果想通过正则化做一些降维,就用 L1 正则化。L1 调整是曼哈顿或出租车调整。L2 正则化是欧几里德正则化,通常在广义线性回归问题中表现更好。

如果你想混合应用 L1 和 L2 正则化,你必须使用 saga 解算器。 liblinear 求解器要求您进行正则化。然而,你可以只让 C 这样一个大的值,它有一个非常非常小的正则化代价。同样, C 当前默认设置为 1。

我应该缩放特征吗?

Scale

如果使用 sagsaga 解算器,确保特征的比例相似。我们在上面看到了这一点的重要性。Andreas Mueller 在私人信件中还提到,他在使用 lbfgs 的未缩放数据上发现了收敛问题,尽管它比 sagsaga 更健壮。

底线:为了安全,扩展你的数据。

我应该删除异常值吗?

大概吧。移除异常值通常会提高模型性能。标准化输入也将减少异常值的影响。

RobustScaler 可以缩放特征,您可以避免丢弃异常值。点击这里查看我的文章讨论缩放和标准化。

其他哪些假设真的很重要?

观察值应该是相互独立的。

我应该使用多项式和交互来变换我的特征吗?

正如线性回归一样,您可以使用高阶多项式和交互作用。这种转换允许您的模型学习更复杂的决策边界。然后,你就不会受限于线性决策边界。然而,过度拟合成为一种风险,解释特征重要性变得更加棘手。求解器找到全局最小值也可能更加困难。

Transformation

如果有很多特征,我应该进行降维吗?

也许吧。如果可解释性不重要,主成分分析是一个不错的选择。递归特征消除可以帮助您删除最不重要的特征。或者,如果使用传奇解算器,L1 正则化可以将不太重要的特征权重驱动为零。

我的要素中的多重共线性是一个问题吗?

它用于解释特性的重要性。当变量之间存在高度相关性时,您不能依赖模型权重。影响结果变量的功劳可能只归于其中一个相关的特征。

有许多方法可以测试多重共线性。参见克拉哈等人(2012)此处。

一个流行的选择是检查方差膨胀因子(VIF)。大约 5 到 10 的 VIF 截止值是常见的,但是关于 VIF 截止值应该是多少有一个激烈的争论。

您可以通过对相关矩阵求逆,然后对每个要素取对角线上的值来计算 VIF。

单独的相关系数不足以确定具有多个要素的有问题的多重共线性。

如果样本量较小,获取更多数据可能对消除多重共线性最有帮助。

什么时候应该使用 LogisticRegressionCV?

LogisticRegressionCV如果您拥有大量数据,并且希望在进行交叉验证以调整超参数的同时加快计算速度,那么这就是您想要的 Scikit-learn 算法。

包装

现在你知道当你看到LogisticRegression规划求解警告时该怎么做了——更好的是,知道如何在第一时间避免它。不再流汗!😅

我建议你在大多数情况下使用即将到来的默认 lbfgs 解算器。如果你有很多数据或者需要 L1 正则化,试试 saga 。如果你用的是 saga 的话,一定要缩放你的特征。

我希望这个关于逻辑回归的讨论对你有所帮助。如果你有,请在你最喜欢的社交媒体上分享,这样其他人也可以找到它。👍

我写关于 Python 、 Docker 、 SQL 、数据科学和其他技术主题的文章。如果你对此感兴趣,在这里阅读更多并注册我的时事通讯。😄

物流快乐!

Good night, lighthouse

不要因为模型“有效”就相信它

原文:https://towardsdatascience.com/dont-trust-a-model-because-it-works-f049374eb6d0?source=collection_archive---------31-----------------------

人们经常试图让别人相信他们的预测是可信的,因为这些预测来自于某种“有效”的统计模型。这通常意味着该模型在过去预测得很好,因此应该相信它在未来也能预测得很好。这听起来很直观:正如我们更有可能相信一台很少发生故障的机器(比如一辆汽车),我们可能会相信一个在过去运行良好的模型会继续运行下去。当考虑不同的模型时,为什么不“回溯测试”它们,看看哪一个做得最好?我认为这是一个重要的分类错误:统计模型不是机器,也不应该被视为机器。

统计推断

为了证明我的论点,首先回顾一下统计推断的基础是有用的。任何统计实践的中心问题是:“不同的过程产生观察到的数据的可能性有多大?”。给定数据和候选过程(假设)的集合,我们应用贝叶斯规则:

以观察数据为条件的假设的概率是后验的, p (过程|数据)。这个概率会更高有两个原因:如果数据表明它( p (数据|过程)),如果我们事先认为假设更有可能是真的( p (过程),即先验)。

举个简单的例子,假设我们有一枚硬币和一个 20 次抛硬币的样本,其中正面 12 次,反面 8 次。假设我们只考虑三个假设,即正面的概率是 75%、50%或 25 %,假设每一个都有相同的事前概率。我们可以计算出后验概率分别为 33.5%,66.1%,0.4%。

相反,假设我们考虑 101 个假设,即正面的概率是 0、1、2、…、99 或 100%(同样是事前概率相等)。在这种情况下,后视图看起来像这样:

我们也可以考虑连续的假设,例如,正面的概率是 0 到 1 之间的任何数字,具有相等的可能性。这是一个非常简单的例子,但是原则对于任何统计练习都是一样的。

我们也可以在已知过程的条件下计算未观测数据的概率分布,即 p (数据|过程)。或者,我们可以计算未知数据函数的分布,例如样本均值。然而,如果我们的目标是从已知数据中了解未知过程,这并不能帮助我们。

什么时候应该相信一个结果?

什么时候我们应该相信一个结果,即后验概率分布?主要有两点考虑。一方面,我们可能会问所包含的假设集是否足够宽泛。是否所有看似合理的过程都“获得了证明自己的机会”?一些假设可能已经被包括在内,但是具有较低的先验权重,其他假设可能已经被完全省略。这通常被称为“数据欠拟合”。典型的问题包括:模型是否遗漏了重要的变量?我们应该考虑额外的概率分布族吗?随着时间的推移,参数是否稳定?有应该考虑的动态关系吗?

反过来,我们可能会问,所包含的假设集是否过于宽泛。这就是所谓的“过拟合”。在极端情况下,我们可以将每个观察到的数据点视为唯一的。但这将留下大量的后验不确定性,我们将不会从数据中学到任何东西。

当然,也可能两者都有:我们觉得有些假设被赋予了太多的分量,而另一些则被赋予了太少的分量。

关于什么构成合理与不合理的先验有什么规则吗?不幸的是,答案是否定的。没有“错误”或“正确”的答案,一个人对这些问题的立场是主观的。因此,结果的可信度取决于旁观者。

举例:糖豆和痘痘

xkcd.com 的一幅漫画展示了两名研究人员正在调查食用软糖豆和痤疮之间的可能联系。他们检查了 20 种不同颜色的软糖数据,发现只有绿色的软糖会引发痤疮。隐含的信息是,他们不应该认真对待这个结果,因为没有证据表明其他 19 种颜色与痤疮有关,我们应该怀疑颜色对痤疮的可能影响。

假设我们确信颜色无关紧要。在这种情况下,我们会简单地估计吃糖豆长痘的几率。但是假设我们想用先验知识来做推论,这个先验知识反映了这样一种信念,即颜色不太可能对痤疮有影响。为了做到这一点,我们将使用一个先验,它对那些效果随颜色而变化的过程赋予较少的权重。这样,我们将推断每种颜色的效果是相似的,除非有相反的有力证据。

需要明确的是,从统计练习中得出绿色软糖会导致痤疮的结论本身并没有什么对错。结果仅仅依赖于所使用的先验知识。

预测试

所谓的“预测试”可能会导致拟合不足。这意味着考虑一组假设,然后丢弃那些后验概率低的假设,并给出一个仅考虑剩余假设的后验概率。例如,在上面的硬币例子中,我们可以放弃概率低于 30%或高于 90%的假设,然后重新计算得到的后验概率。

一套假设并不比另一套假设更好。然而,如果想要基于初始假设集进行推断,则需要给出相应的初始后验概率,而不是基于子集的后验概率。

预测

我们可以使用后验概率对尚未观察到的数据进行预测,当然假设这些数据是由与观察到的数据相同的过程产生的。未观测数据的预测分布是加权*均值,其中权重是后验概率。如果我们有不同的假设,那么:

这通常被称为后验预测分布

型号【性能】

通过仔细选择假设的集合,我们可以找到比其他过程更有可能的过程。此外,如果我们在过去使用这些过程(或模型),我们将可以很好地预测数据。事实上,很容易找到一个可以任意(甚至完美)预测过去的过程。因此,我们应该用这个模型来预测未来吗?同样,除非候选假设集准确地反映了我们的先验分布,否则答案是否定的。

一种常用的方法是将数据分成两个样本,用第一个样本(“训练集”)计算后验概率,然后用它来查看该模型对第二个样本(“验证集”)的预测程度。如果预测是好的,那么这就证明了该模型是可信的,因为它在“样本外”表现良好。但是,当然会观察到“样本外”数据,因此这个练习本质上是对参数在不同子集之间保持稳定的假设的粗略评估。事实上,正如很容易找到一个在样本中预测良好的过程一样,找到一个在“样本内”和“样本外”都预测良好的过程也同样容易。

“预测业绩”在某种意义上是一个毫无意义的概念。我们有数据,有了数据,我们可以通过统计推断获得关于世界的知识,这反过来又使我们能够进行预测。这就是全部了。

然后怎么办?

我认为,如果我们认为假设集(和相应的先验权重)是合理的,我们应该相信统计实践的结果。但是,也许令人失望的是,对于什么样的假设和先验是合理的这个问题,没有简单的对错答案。

也就是说,主要的考虑因素如上所述:欠拟合和过拟合。一方面,我们应该检查所考虑的假设,并问自己是否觉得重要的假设被遗漏了。另一方面,我们应该问问自己,我们是否觉得我们可以从具有额外结构的数据中学到更多。简而言之,一个先验可能太“开明”。

信息丰富的前科

虽然有些人可能会对信息丰富的先验感到不舒服,但重要的是要记住,任何统计练习都涉及先验,因为许多假设被排除在外,因此先验权重为零。但是为什么优先地位应该是全有或全无呢?事实上,使用信息丰富的先验知识通常有吸引人的理由,例如,当我们对不同的类别使用不同的参数时,就像上面的软糖豆的例子一样。我们可能希望假设子类别之间的参数是相似的。这样,如果某个类别的数据很少,我们可以从其他类别中观察到的数据中获取信息。

使用信息丰富的先验知识的另一个原因是,否则我们可能会非常重视可能非常极端的假设。最后,计算完整的后验分布并不总是容易的,有时只有后验模式(即单一最可能的假设)是可用的。如果使用了信息丰富的先验,基于单独模式的预测将是基于整个后验预测的合理*似。

沟通结果

假设我们做了一个统计研究,想让别人相信我们的结果是合理的。我们想要说服我们的观众,假设的范围足够广泛,但是我们也强加了足够的结构。鉴于人们有不同的经历,显示结果对不同的假设有多敏感是有帮助的。一种典型的方法是,首先表明在强先验假设(即相对简单的模型)下结果成立,然后表明在限制性较小的假设(即更复杂的模型)下结果成立。

当对某个主题的知识存在重大差距时,说服观众可能会很有挑战性。我们常常依赖“专家判断”;仅举一个例子:天气。但是我们经常没有时间或兴趣去真正理解专家预测背后的推理。专家有责任为他们的观点提供一个诚实的解释。基于他们使用了一个“运作良好”的模型的解释应该受到最大的怀疑。

了解一个预测

到目前为止,我已经讨论了我们是否应该相信统计建模练习的结果(或预测)。我现在转向另一个问题,即理解预测。对于来自复杂的高维模型(有时称为“黑箱”)的预测,梳理出主要驱动因素并以简单的术语表达它们可能是一项挑战。

我们应该只使用我们理解的模型吗?答案可以说是否定的。首先,如果我们这样做了,基本上整个人工智能(AI)领域将不得不被放弃。

举个例子,计算机可以识别人类的笔迹,例如用来阅读邮件上的地址。为了做到这一点,计算机使用了一个已经用数据估算过的统计模型。例如,为了识别一个数字,可以将一幅图像转换成一组像素。每个像素被转换成一个从 0 到 1 的数字,代表它的暗度。如果图像的分辨率为 28×28,我们将得到一个 784 维的向量。该模型通常是一个 神经网络 ,可以使用数据进行估计,然后用于形成预测:对于任何图像(784 维向量),数字为 0,1,2,3,4,5,6,7,8 或 9 的概率是多少?不用说,理解这种条件概率分布并不容易。

即使我们对模型如何工作没有什么概念,仔细考虑参数的先验分布仍然很重要。与任何模型一样,我们可以使神经网络过拟合或欠拟合。如果我们包括许多自由参数,并忽略后验不确定性(换句话说,预测试),神经网络可以完美地预测观察到的样本。

最终想法

无可否认,所有的知识都是以一些潜在的假设为条件的。统计推断需要利用新信息(数据)建立在原有知识的基础上。然而,观点各不相同,几乎没有普遍认同的假设。如果我们认为潜在的假设是合理的,那么统计结果就是可信的。因此,我们不应该在至少对哪些假设被考虑有所了解的情况下接受一个结果。

不要低估小数据

原文:https://towardsdatascience.com/dont-undervalue-small-data-5455abeb1fcb?source=collection_archive---------44-----------------------

为什么小数据在这个大数据的世界里仍然有价值

Photo by Jeremy Bishop on Unsplash

毫无疑问,在过去十年的大部分时间里,大数据一直是热门话题。不需要太多的分析就可以看出,谷歌趋势的图表显示,自 2013 年以来,人们对这个话题的兴趣激增。

自从大数据流行以来,它已经席卷了整个商业世界。它似乎已经渗透到各行各业各种规模的组织中,不可否认,大数据是大量商业成功的关键驱动力。然而,这不是我今天想谈的,随着大数据的价值无处不在,我想谈谈小数据的价值。并非每个组织都有处理大数据的奢侈,但如果我们有不同的方法,我们实际上可以从小数据中获得很多价值。

小数据有大价值

我看到小数据和新的创业企业之间有很多相似之处,我们经常在把事情做好之前就被增长和规模迷住了。对创业公司的一个常见建议是做不具规模的事情,著名的例子是 AirBnB 创始人逐个访问他们的早期客户,了解他们如何以及为什么使用该产品。对于小数据,原理是一样的。因为您的数据集足够小,所以您可以查看单个数据点,调查单个异常值,并尝试了解单个客户或流程在您的数据中是如何表示的。这种方法不可扩展,但却是真正理解数据的好方法。说到从数据中提取价值,没有什么可以替代深入的理解,所以在你还能做的时候,花更多的时间在数据上。

最*,我读了托德·罗斯的书《*均的终结》,书中谈到了个性科学。托德描述了传统方法是如何在分析结果之前汇总数据,并通过这一过程,我们最终得到一个看似适合所有人但实际上不适合任何人的*均值。大数据有时也是如此,我们如此痴迷于使用越来越多的数据,以至于忽略了大数据集中个体的价值。有点讽刺的是,我们努力通过大数据而不是小数据来实现个性化。因为我们可以访问大量的数据,所以在真正试图理解正在发生的事情之前,我们默认聚合大型数据集,并且我们冒着忽略重要见解的风险。个性科学提供了另一种解决方案,首先通过分析个体来发现见解,然后将其应用于大数据集,我们可能会得出非常不同的结论。因此,如果你知道如何发现,小数据集中确实隐藏着巨大的价值。

从您的数据中提取价值

现在,让我们来谈谈在处理小型数据集时可以帮助您入门的一些技巧。

  • 了解自己的极限→较小的数据集往往更有偏差,可变性更高,但这并不意味着它们没有用。了解对数据能做什么和不能做什么是从数据中获得正确答案的关键。
  • 了解背景→了解你试图解决的问题背后的背景,可以帮助你做出有助于你简化问题的假设。
  • 有创意→在某些情况下,你可以创造有用的合成数据,帮助你绕过极限。像转置和修改图像以增加计算机视觉用例的训练数据集这样的技术就是一个很好的例子。
  • 在它爆炸之前得到它→建立一个数据系统是困难的,特别是当你正在处理大量数据的时候。当您的数据易于管理时,花时间设计合适的数据系统将有助于您在未来扩展时做好准备。
  • 快速发布——我们只有在发布时才能从数据中获得价值,因此尽管我们可能无法进行真正复杂的分析,但只要我们能够快速发布结果,小型数据集就能带来巨大的价值。

扩大数据集

一旦我们尝试了利用小数据的所有不同方法,您现在可以考虑增加数据集。根据您在密切处理数据的过程中已经获得的知识,您现在应该对处理其他数据集感到更加舒适,并了解它们如何补充您的数据集。

以下是几种可以用来增加数据集的方法。

有机的

希望您能够有效地利用现有数据,您的业务将会有强劲的有机增长。通过获取现有客户的更多数据点并扩大客户群,您可以在广度和深度上扩大数据集。两者为您提供不同的价值,虽然它们并不相互排斥,但您应该专注于获得正确的数据来回答您的问题。

合作关系

寻找战略数据合作伙伴是装载新数据集的好方法。如果你能利用在你感兴趣的数据集上有专业知识的其他公司,这是一个很好的发展方式。地理定位数据集和分析是一个很好的使用案例,在这种情况下,在内部收集和分析数据可能不是最佳选择。

合成的

正如上面简要提到的,在某些情况下,我们能够创建一个有用的合成数据集。这些在测试时也很有用,并且在处理带有严格规定的敏感数据时提供了一个很好的选择。

推荐

仅仅因为你的数据集很小,并不意味着它没有价值。在大数据时代,我们经常忽视小数据的力量,但如果有效利用,即使是最小的数据集也能为您的企业带来巨大价值。我们应该开始将小数据视为一种祝福,而不是一种诅咒。这可能是我们不得不面对的一个制约因素,但是如果我们用正确的心态和技巧来处理这个问题,它可以帮助我们从不同的角度看待这个问题。

如果您喜欢我的内容,请在 https://jchoi.solutions/subscribe注册更多内容

使用 Matplotlib 绘制圆环图(Python)

原文:https://towardsdatascience.com/donut-plot-with-matplotlib-python-be3451f22704?source=collection_archive---------16-----------------------

让我们用一句非常著名的英语谚语来赞美可视化吧。这是老生常谈,但完全正确。

“一张抵得上一千句

在这篇文章中,我将演示如何使用 python 和 matplotlib 创建一个圆环图。圆环图是比较多个实体统计数据的一种非常有效的方式。根据[1]

就像饼图一样,圆环图显示部分与整体的关系,但是圆环图可以包含多个数据系列。您圆环图中绘制的每个数据系列都会给添加一个环。

现在,让我们使用下面的虚拟数据来表示不同社交媒体网站的移动应用程序的使用情况。

╔═════════════════╦══════════╗
║   Social Media  ║   Usage  ║
╠═════════════════╬══════════╣
║ Twitter         ║ 60 %     ║
║ Facebook        ║ 75 %     ║
║ Instagram       ║ 80 %     ║
╚═════════════════╩══════════╝

下面是创建环形图的代码。

**import** pandas **as** pd
**import** re

data = pd.read_csv(**'testdata.csv'**)
print(data.head())

**import** matplotlib.pyplot **as** plt

*# create donut plots* startingRadius = 0.7 + (0.3* (len(data)-1))
**for** index, row **in** data.iterrows():
    scenario = row[**"scenario"**]
    percentage = row[**"Percentage"**]
    textLabel = scenario + **' '** + percentage
    print(startingRadius)
    percentage = int(re.search(**r'\d+'**, percentage).group())
    remainingPie = 100 - percentage

    donut_sizes = [remainingPie, percentage]

    plt.text(0.01, startingRadius + 0.07, textLabel, horizontalalignment=**'center'**, verticalalignment=**'center'**)
    plt.pie(donut_sizes, radius=startingRadius, startangle=90, colors=[**'#d5f6da'**, **'#5cdb6f'**],
            wedgeprops={**"edgecolor"**: **"white"**, **'linewidth'**: 1})

    startingRadius-=0.3

*# equal ensures pie chart is drawn as a circle (equal aspect ratio)* plt.axis(**'equal'**)

*# create circle and place onto pie chart* circle = plt.Circle(xy=(0, 0), radius=0.35, facecolor=**'white'**)
plt.gca().add_artist(circle)
plt.savefig(**'donutPlot.jpg'**)
plt.show()

Donut Plot

在最核心的地方,这个代码中的圆环图是通过创建一系列不同半径的饼图来创建的,一个在另一个之上,中间有一个白色的圆圈。

参考

[1]https://support . office . com/en-us/article/present-your-data-in-a-donut-chart-0 AC 0 efde-34e 2-4d C6-9b7f-ac93d 1783353

多巴胺和强化学习算法

原文:https://towardsdatascience.com/dopamine-and-reinforcement-learning-algorithms-d5deb5ac6479?source=collection_archive---------23-----------------------

决策者面临的一个重要问题是通过反复试验来学习作出何种决定,以便最好地获得奖励或避免惩罚。在计算机科学中🤖,这个问题被称为强化学习。让我们仔细看看。

什么是多巴胺?

多巴胺是大脑八种神经递质之一。神经递质是一种化学物质,在神经元之间来回传递 信息。👌🏻

多巴胺有什么作用?

中脑多巴胺神经元的阶段性活动提供了一种全局机制🌏进行突触改造。这些突触修饰反过来为一类特定的强化学习机制提供了机械基础,这类机制现在被认为是许多人类和动物行为的基础🐒🐬🐊 🐝🐆🐘。

换句话说,多巴胺让我们看到回报并采取行动。然后我们采取行动接受奖励——也就是说,通过使用调节运动、学习、注意力和情绪反应。就这么简单。

多巴胺帮助我们学习。

在学习的背景下,多巴胺起着奖励预测误差信号的作用。简单来说,多巴胺计算预期的奖励和实际收到的奖励之间的差异

为什么奖励预测误差很重要?

任何人最基本的目标之一👬对未来事件做出准确的预测,以便在这一预期的未来到来时做好准备,并相应地调整自己的行为。

一般来说,学习可以被定义为改善这些对未来的预测的过程。因为预测往往不太准确,我们需要一种方法来计算我们的预测误差,这样我们就不会再犯同样的错误(因此奖励预测误差)😉。

这些预测误差是最基本的教学信号之一,可用于提高对未来奖励的预测准确性。为此,学习的最终目标是做出准确的预测,从而消除预测误差。

强化学习和预测误差。

“预测误差”假设很有趣,因为强化学习算法使用时间差异学习 🧠,它大量使用编码预测误差的信号。

时间差异学习是指一类无模型强化学习方法,通过自举(使用最*信息和先前估计的组合来生成新的估计)从价值函数的当前估计进行学习。

简单来说,强化学习算法使用预测误差来提高计算机在某些环境下(例如,在下棋或吃豆人时)做出更好决策的能力。

所以我们的算法模仿了我们的大脑?

嗯,是的。

目前的数据表明,中脑🧠多巴胺神经元的阶段性活动编码了一种奖励预测误差,用于指导整个额叶皮质和基底神经节的学习。这种活动现在被认为是一种信号,表明受试者对当前和未来事件的价值的估计是错误的,然后表明这种错误的大小。

这是一种组合信号,以定量的方式调整突触强度,直到受试者对当前和未来事件的价值的估计被准确地编码在额叶皮层和基底神经节中。

总之,这种生物活动现在被编码到我们的许多强化学习算法中,并在许多情况下取得了巨大成功。

这一切意味着什么?

多巴胺神经元可能为大脑中的神经元提供关于未来的值的详细信息。反过来,这些信息有可能在实际奖励发生之前很早就被用来计划和执行有利可图的行为和决策😎去了解更早的可靠的奖赏预测。

记住这一点,如果我们能够教会我们的算法做到这一点,我们的算法将继续变得更强大、更智能,同时慢慢走向人工智能成为现实的未来。✌️🏻

来源:

[## 多巴胺在动机和学习中的作用-神经科学新闻

如果你曾经对开始一个新项目感到无精打采,集中精力想象完成它的喜悦,比如说大学…

neurosciencenews.com](https://neurosciencenews.com/dopamine-learning-reward-3157/) [## 多巴胺:改善强化学习和…机器的快感?

好消息:2018 年 8 月 27 日,谷歌通过他们的人工智能博客宣布,他们将发布一个新的框架…

towardsdatascience.com](/dopamine-improved-reinforcement-learning-and-pleasure-for-machines-9278ef84d78b) [## 多巴胺|今日心理学

多巴胺是大脑的神经递质之一,是一种在神经元之间传递信息的化学物质。多巴胺有助于…

www.psychologytoday.com](https://www.psychologytoday.com/us/basics/dopamine)

https://drive.google.com/viewerng/viewer?URL = https://storage . Google APIs . com/deep mind-media/alpha go/alphagonaturepaper . pdf

多巴胺驱动的发展

原文:https://towardsdatascience.com/dopamine-driven-development-c7ca63b5626c?source=collection_archive---------16-----------------------

Credit: @hannynaibaho, Unsplashed

过去几周,加入 Monarch 后,我又开始写代码了。就上下文而言,除了一些零星的项目,我在过去的两年里没有写过多少代码(而是专注于管理、写作和产品)。

首先突出的是:我有些生疏了。第二:我已经忘记了写作软件是多么有趣和吸引人。我感觉我发现了一个旧瘾。当然,在代码审查、招聘和其他任务之后,我只剩下 20-30%的时间用于编码(和过去不同,我不能把时间延长到清晨或深夜,因为我想和家人在一起)。但是我发现自己整天都在期待着我的“编程修正”,如果我结束了一天却没有得到它,有些事情就感觉不对了。

那么是什么让编写软件具有那种属性呢?因为软件的可塑性很强,而且你可以在快速迭代中工作,所以编写软件可以触发多巴胺释放周期。多巴胺是一种“奖励”化学物质——你的大脑在对某种刺激做出反应时释放它,让你感觉良好,并使你更有可能重复这种行为。

那么你如何利用这一点呢?以下是我发现的一些放大多巴胺分泌的技巧。正如你将看到的,它们中的大多数都是基于缩短(或加强)工作和看到收益之间的反馈循环。好消息是,这些技术对软件开发的速度和质量都有好处。但即使他们没有,我也认为你从更高的精神投入中获得的好处本身就让他们值得。

使用 CI/CD

我大学毕业后的第一份工作是在谷歌的 Adwords 产品上工作。我们每两周发布一次。如果您错过了将您的变更发布到发布分支中,您必须等到下一个(除非您正在修复一个主要的 bug 或者有另一个有效的理由将您的变更“精选”到产品中)。现在,有充分的理由使用这种类型的定期发布周期。但是等了两周才把你的代码投入生产?真是扫兴。

相反,使用与持续部署或交付的持续集成。除了集成和部署中的优势,如更快的速度和更低的风险,编写代码和投入生产之间的快速反馈循环也非常令人满意。Quora(我以前工作过的地方)将这一点发挥到了极致:编写的代码可以在 30 分钟内投入生产,在部署之后以非阻塞的方式进行代码评审。疯狂的快速和满足。

使用测试

测试是另一种“最佳实践”,它既能提高代码的质量,又能增加编写代码的乐趣。我们都知道好的测试的好处:它确保你的代码做它应该做的事情,可以帮助你轻松自信地做出改变,并迫使你设计干净的、模块化的界面。

一个额外的好处是他们提供了一个真正快速的反馈回路。如果您使用测试驱动开发这样的技术,这一点尤其正确。您首先编写测试,然后实现功能以通过这些测试。这样做的好处是,您可以很快获得积极的回报,而不必等待集成或部署。我发现即使是对这个循环的简单改进,比如用绿色显示你的通过测试,或者显示一个简单的信息,比如“成功”。全部测试通过!”能在你的大脑中激起一点点快乐。

WOOHOO!

使用任务管理器

使用项目管理工具(吉拉、Asana、Trello 等)并跟踪你的进度。把你的工作分成小的、可衡量的任务,并有对应你实际工作的阶段。

例如,在 Monarch,我们做代码审查。当代码审查仍然未完成时,将任务标记为“完成”是不成熟的,但是保持它“进行中”(在完成大部分工作之后)感觉是空虚和没有成就感的。所以我们创造了一个“技术回顾”阶段。这确实有助于我们更好地了解不同任务所处的阶段,以及是否有任何东西在技术审查中被阻止,但我们无论如何都会从 Github 获得这些信息(我们对代码审查有 24 小时的周转时间,通常比这更快完成)。主要的好处是更好地将任务映射到工作上。

Oh baby

(如果你不是一个优秀的项目管理人员,我曾让团队使用谷歌文档或电子表格完成任务。

If you’re into that, I won’t judge. To each their own.

添加含义

如果这一切看起来像是在训练你的大脑寻求奖励,就像你训练笼子里的老鼠去按下按钮寻找小球一样,那是因为我们缺少了一个关键的部分:意义。短期多巴胺冲击和短期激励一样有效。但是你也应该通过以下方式把你的工作和更大的事情联系起来:

  • 理解你正在构建的东西的“为什么”。对客户会有什么影响?出差吗?
  • 查找产品数据/指标,帮助您衡量和理解您所构建产品的影响。如果你的公司没有度量很多指标,那就努力去做。如果 it 部门确实进行了衡量,但只是与管理层和产品经理分享了这些指标,那么就推动为整个公司提供更开放的仪表板和报告。
  • 找到与你的用户联系的方法。开展(或询问你是否能参加)用户研究会议。理解你的用户的问题以及你的产品如何帮助他们。额外的好处:这种理解也会让你成为更有效的软件工程师。

将它整合在一起

构建软件可能是一项非常令人满足的工作。通过设计你的工作周期和反馈循环,你可以放大这种满足感,让自己更快乐、更有效率。这不仅适用于软件开发,也适用于您定期执行的任何其他任务。总结一下我们讨论的内容:

  • 以小的、可管理的增量工作,并找到衡量和奖励自己工作的方法。尽可能缩短工作完成和交付/测量之间的周期时间。
  • 将你的工作与更大的图景联系起来,以获得更深层次的满足感。

编码快乐!

如何在 Python 中创建点状图

原文:https://towardsdatascience.com/dotplotpython-c24058dc6689?source=collection_archive---------22-----------------------

对经典的 Seaborn 散点图做了一点调整

最*,我查看了我的 IMDb 账户。哇,有超过 1100 个分级的标题!我决定创造一个我每年看过的电影的情节和它们的收视率。点阵图是一种很好的可视化方式,我一直喜欢用 ggplot2 创建的这些图:

Dot plot created in R’s ggplot2

好吧,用 Python 应该不是什么难事。我只需要用我的评级得到一个. csv 文件,用 Matplotlib/Seaborn 和写几行代码,瞧!我很快意识到 Matplotlib 不支持点状图。Seaborn 也不知道。我很快检查了 MS Excel——也没有点状图!

在谷歌搜索了几分钟后,我找到了的一个解决方案。然而,创建值的直方图,然后将它们映射到散点图上,并不能解决评级的不同标记颜色的问题。

我喜欢调整标准散点图的想法,所以我决定走这条路。我没有创建一个网格点,而是使用了一个简单的循环来添加负责每年电影数量的新变量。

首先,我们创建一个空数组“movie_count ”,它将存储每部电影在图表上的垂直位置。然后我们使用“enumerate”函数遍历 year 列。对于每个电影,我们从第一个索引开始创建一个子集,直到这个电影。现在,我们对该子集中的所有电影进行计数,并将结果追加到“movie_count”中。

# Loop to create a new variable, which will turn scatterplot to a dot plot
movie_count = []

for index, year in enumerate(ratings['Year']):
    subset = ratings.iloc[:index + 1]  # Create subset starting at the beginning of dataset until the movie itself
    count = len(subset[subset['Year'] == year])  # Count all movies from the same year in this subset
    movie_count.append(count)  # Appended counts will be used as vertical values in the scatterplot,
    # which will help to create a dot plot

例如,如果我们正在查看数据集中的第 20 部电影,该电影于 2018 年上映,我们将创建这 20 部电影的子集,并对 2018 年的所有电影进行计数。假设有三个,那么我们将这个数字附加到 movie_count 数组的第 20 个位置。如果下一部电影也是 2018 年的,则计数为 4,以此类推。我们数据集中的每一部电影都有一对唯一的坐标——发行年份和数量。

这样我们可以创建一个散点图,实际上就是点状图。现在,我们只是添加色调作为参数,以获得不同的颜色评级,它应该工作。

First version of the dot plot

基本想法是可行的,但现在我们需要解决一些问题:

1.为了更好的可读性,电影应该按等级分类。

2.圆点需要变大。

3.为了更好的对比,应该添加背景色。

4.传说就是不好。您不能在 1-10 的范围内给电影 0 或 12 评分。此外,对于这种数据,*滑(或离散,你的选择)色彩映射表会更好。这里有一个很棒的关于创建色彩映射表的帖子。

解决这些问题后,您可以得到一个漂亮的图表:

Final dot plot looks much better

如果你对创建这个点图的完整代码感兴趣,可以查看我的 GitHub 库。请随意评论或报告代码中的任何改进,因为我只是将 Python 用于数据科学任务,我不是优化方面的专家。

双深 Q 网络

原文:https://towardsdatascience.com/double-deep-q-networks-905dd8325412?source=collection_archive---------1-----------------------

DQN 家族

解决深度 Q 学习中的最大化偏差

简介

在本帖中,我们将探究双 Q 学习网络背后的动机,并看看实现这一点的三种不同方式:

  • 原算法在 【双 Q 学习】(Hasselt,2010)
  • 《双 Q 学习的深度强化学习》(Hasselt et al .,2015) 中来自同一作者的更新算法,
  • 最*的方法,Clipped Double Q-learning,见于《Actor-Critic Methods 中的寻址函数逼*误差》(Fujimoto et al .,2018)

如果你还不完全熟悉 Q-learning,我建议你快速看一下我关于 Q-learning 的帖子!

动机

考虑目标 Q 值:

具体来说,

照这样取最大高估值就是隐含地取最大值的估计值。这种系统性的高估在学习中引入了最大化偏差。由于 Q-learning 涉及 bootstrapping——从估计值中学习估计值——这种高估可能是有问题的。

这里有一个例子:考虑一个单一状态 s ,其中所有动作的真实 Q 值都等于 0,但是估计的 Q 值分布在零上下一些。取这些估计值的最大值(明显大于零)来更新 Q 函数会导致 Q 值的高估。

Hasselt 等人(2015)在跨不同 Atari 游戏环境的实验中说明了这种高估偏差:

Source: “Deep Reinforcement Learning with Double Q-learning” (Hasselt et al., 2015),

正如我们所看到的,传统的 DQN 倾向于大大高估行动价值,导致不稳定的培训和低质量的政策:

解决方法:双 Q 学习

解决方案包括使用两个独立的 Q 值估计器,其中一个用于更新另一个。使用这些独立的估计,我们可以无偏 Q 值估计的行动选择使用相反的估计[3]。因此,我们可以通过从有偏差的估计中分离出我们的更新来避免最大化偏差。

下面,我们将看看双 Q 学习的 3 种不同公式,并实现后两种。

1。“双 Q 学习”中的原始算法(Hasselt,2010)

Pseudo-code Source: “Double Q-learning” (Hasselt, 2010)

最初的双 Q 学习算法使用两个独立的估计值Q^{A}Q^{B}。对于 0.5 的概率,我们使用估计值Q^{A}来确定最大化动作,但是使用它来更新Q^{B}。相反,我们使用Q^{B}来确定最大化动作,但是使用它来更新Q^{A}。通过这样做,我们获得了预期 Q 值的无偏估计量Q^{A}(state, argmaxQ^{next state, action),并抑制了偏差。

2。来自同一作者的“使用双 Q 学习的深度强化学习”(Hasselt 等人,2015),的更新版本

在第二个双 Q 学习算法中,我们有一个模型Q和一个目标模型Q’,而不是像(Hasselt,2010)中那样有两个独立的模型。我们使用Q’进行动作选择,使用Q进行动作评估。那就是:

我们最小化QQ*之间的均方误差,但是我们让Q'慢慢复制Q的参数。我们可以通过定期硬拷贝参数来实现,也可以通过 Polyak *均来实现:

其中,θ'是目标网络参数,θ是主要网络参数,τ(*均速率)通常设置为 0.01。

3。削波双 Q 学习,见于 《演员-评论家方法中的寻址函数逼*误差》(藤本等,2018)

在削波双 Q 学习中,我们遵循 Hasselt 2015 的原始公式。我们对真实的 Q 值有两个独立的估计。这里,为了计算更新目标,我们取由两个 Q 网络产生的两个下一状态动作值的最小值;当一方的 Q 估计值大于另一方时,我们将其降至最小,避免高估。

Fujimoto 等人提出了这种设置的另一个好处:最小值算子应该为具有较低方差估计误差的状态提供较高的值。这意味着最小化将导致对具有低方差值估计的状态的偏好,从而导致具有稳定学习目标的更安全的策略更新。

实施指南

我们将从与本系列第 1 部分相同的 DQN 代理设置开始。如果你想看更完整的设置实现,请查看我的 Q-learning 帖子或我的 Github 库(底部链接)。

DQN 代理:

  1. Hasselt 等人的双 Q 学习,2015:

我们将初始化一个模型和一个目标模型:

为了计算损失,我们使用目标模型来计算下一个 Q 值:

然后我们慢慢地将模型参数复制/*均到目标模型参数:

2.藤本等人 2018 年剪辑双 Q 学习:

我们初始化两个 Q 网络:

为了计算损耗,我们计算两个模型的当前状态 Q 值和下一状态 Q 值,但使用下一状态 Q 值的最小值来计算预期 Q 值。然后,我们使用预期的 Q 值更新两个模型。

最后是更新功能:

这就结束了我们的双 Q 学习算法的实现。双 Q 学习经常在最新的 Q 学习变体和演员评论方法中使用。在我们以后的文章中,我们会一次又一次地看到这种技术。

感谢阅读!

在这里找到我的完整实现:

[## cy oon 1729/深度 Q 网络

Q-learning 家族(PyTorch)算法的模块化实现。实现包括:DQN,DDQN,决斗…

github.com](https://github.com/cyoon1729/deep-Q-networks)

参考

  • “使用函数逼*进行强化学习的问题”(Thrun 和 Schwartz,1993)
  • “双 Q 学习”(Hasselt,2010)
  • “双 Q 学习的深度强化学习”(Hasselt et al .,2015) ,
  • “演员-评论家方法中的寻址函数*似误差”(藤本等人,2018)
  • 强化学习:导论(萨顿和巴尔托)

打倒技术债!面向数据科学家的干净 Python。

原文:https://towardsdatascience.com/down-with-technical-debt-clean-python-for-data-scientists-aa7592eff7fc?source=collection_archive---------8-----------------------

ata 科学团队倾向于向两个相互竞争的方向发展。一方面是数据工程师,他们重视高度可靠、健壮的代码,这些代码承担着较低的技术债务。另一方面,有一些数据科学家,他们重视在概念验证等环境中快速建立想法和算法的原型。

虽然更成熟的数据科学职能部门在双方之间享有富有成效的工作伙伴关系,拥有复杂的 CI / CD 管道,并有明确的职责分工,但早期团队往往由大量缺乏经验的数据科学家主导。结果,代码质量受损,技术债务以粘合代码、管道丛林、死的实验代码路径和配置债务【1】的形式成倍积累。

Can you imagine a life without xkcd?

最*,我写了一篇关于为什么数据科学家的代码往往*庸的头脑风暴,在这篇文章中,我希望揭示一些方法,让更多初出茅庐的数据科学家能够编写更干净的 Python 代码,更好地构建小规模项目,同时减少你无意中给自己和团队带来的技术债务。

下面的内容既不详尽,也不深入,只是一系列浅显的介绍,告诉你如何以一种更有思想的方式建立数据科学项目。有些点会很明显,有些会不太明显。

这里有一个快速的概述:(1)风格指南,(2)文档,(3)类型检查,(4)项目文件夹结构,(5)代码版本控制,(6)模型版本控制,(7)环境,(8) Jupyter 笔记本,(9)单元测试,(10)日志记录。

Python 风格指南— PEP 8 和林挺

可读性很重要。以至于有一个完整的 PEP 致力于此:PEP8,它为编写干净的 Python 代码提供了编码约定。

符合 PEP8 标准被认为是构成python 式代码的最低要求。这表明你已经意识到了 Python 开发者应该具备的最基本的习惯,这表明你能够更容易地与其他开发者合作,最重要的是,这使得你的代码更具可读性,愚蠢地保持一致,并且更容易被消化。

如果我在这里复制并重新格式化 PEP8 风格指南,那将是浪费大家的时间。所以,你可以随意浏览pep8.org,看看例子,体会一下在微观层面上写干净代码意味着什么(相对于在宏观或系统层面上写干净代码)。

PEP8 中给出的例子包括为命名约定、缩进、导入和行长度设置标准。

顺便说一下,PEP8 是你应该使用成熟的 ide,如 PyCharm (我认为是更好的 Python IDE)来编写代码,而不是像 Sublime 这样的简单文本编辑器的众多原因之一。Python 的重量级 ide 通常符合 PEP8 风格指南,当您违反其原则时会发出警告,并提供代码库的自动重新格式化。

有四个,尽管实际上还有很多其他的——命令行工具对你的源代码进行静态分析,以保持它的整洁和一致:

  1. ——最受欢迎的棉绒。检查源代码,并作为一个错误和质量检查。它比 PEP8 有更多的验证检查和选项。众所周知,这是一个有点过了头的沉重的输出按照默认设置,但是。
  2. 黑色—自动重新格式化您的 Python 代码。Black 就地重新格式化整个文件,并将字符串格式化为双引号。
  3. PyCodeStyle—官方 linter 工具,根据 PEP8 python 的样式约定检查 python 代码。
  4. flake 8—pyflakes、pycodestyle 和 mccabe 周围的包装器,它验证 pep8、py flakes 和循环复杂度的包装器。

边注 1。linter 不会告诉你你是否已经很好的命名了你的变量。这个被新手开发者嘲笑的技能是一个值得掌握的技能。

旁注 2。在安装这些软件包之前,最好是在虚拟环境中。稍后会详细介绍。

记录您的项目— PEP257 和 Sphynx

PEP8 概述了Python 的编码约定时, PEP257 标准化了 docstrings 的高层结构、语义和约定:它们应该包含什么,以及如何以一种清晰的方式表述。和 PEP8 一样,这些不是硬性规定,但它们是你应该明智地遵循的指导方针。

如果你违反了这些惯例,最糟糕的是你会得到一些白眼。

那么,什么是 docstring 呢?docstring 是作为模块、函数、类或方法定义中的第一条语句出现的字符串文字。这样的 docstring 成为该对象的 doc special 属性。与 PEP8 一样,我不会复制并重新格式化整个 PEP,您应该在自己的时间浏览它,但这里有两个函数的 docstrings 示例。

  1. 示例单行 docstring for a 函数 add :
def add(a, b):
    """Sum two numbers."""
    return a + b

2.示例函数复合体的多行 docstring:

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)
    """
    if imag == 0.0 and real == 0.0:
        return complex_zero
    ...

Sphynx

在所有格式良好的文档字符串都准备好之后,接下来您需要将它们转换成漂亮的项目文档。事实上的 Python 文档生成器被称为 Sphynx,它可以生成 html、pdf、unix 手册页等输出。

这里有一个关于 Sphynx 入门的好教程。简而言之,在某个目录(通常是您的 docs 目录)中初始化 Sphynx 并设置其配置之后,您将处理您的 reStructuredText (。rst)文件,在调用生成*后,将被转换成您喜欢的输出文档类型。

有趣的是,您可以直接从 docstrings 创建对 Python 程序其他部分的引用,这些引用在输出文档中显示为链接。

为了说明 Sphynx 文档生成器的典型输出,这里的是一个包含 Sphynx 生成的文档的 Python 项目的不完整但膨胀的列表。例子包括 matplotlib 、 networkX 、 Flask 和 pandas 。

类型检查— PEP484 、 PEP526 和 mypy

因为 Python 是一种动态类型语言,所以默认情况下没有静态类型检查。这是好的,因为它提供了灵活性和快节奏的开发,但这是坏的,因为您不会在运行系统之前(在编译时)捕捉简单的错误,而是在运行时捕捉它们。通常,像 Python 这样的动态类型语言比静态类型语言需要更多的单元测试。这是乏味的。在 Scala、Java 或 C#等语言中,类型声明出现在代码中,编译器检查变量是否通过类型合法传递。

最终,静态类型充当了一个安全网,在某些情况下使用它是明智的。好消息是 Python 实际上提供了一种叫做类型提示的东西。

下面是一个函数注释类型提示的例子。这意味着name应该是类型str,并且该函数也应该返回一个str

def greeting(name: str) -> str:
    return 'Hello ' + name

下面是一个变量注释类型提示的例子。这意味着变量i应该是一个整数。请注意,以下语法适用于 Python 3.6 及更高版本。

i: int = 5

…但坏消息是 Python 解释器忽略了类型提示,并且没有运行时效果(PEP 目前正在进行中)。

但是,如果类型提示没有运行时效果,为什么还要麻烦它呢?两个原因。首先,它让你的代码更清楚地知道它要做什么以及它是如何流动的。其次,因为你可以在 Python 中使用静态类型检查器,默认情况下它不会运行。主要的是 mypy 。

附注 1:由于类型提示的可选性,你可以自由地将它们放在代码中的任何地方,某些地方,或者什么地方都不放。只是尽量保持他们的位置一致。

边注 2:如前所述,PyCharm 对于执行 PEP8 标准非常有用。但是它在类型提示的情况下也很有用。它会自动检查您的类型提示,并在您违反预期时告诉您。默认情况下,在 PyCharm 中它们被设置为警告,但是您也可以将它们设置为错误。

项目文件夹结构— cookiecutter

就像凌乱的桌子是混乱思想的标志一样,凌乱的文件夹结构也是如此。

许多项目从一开始就受益于一个考虑周全的目录结构。不幸的是,启动项目的一个常见方法是创建一个基础项目目录,并将所有内容直接放在该目录下——从数据到笔记本到生成的模型再到输出——而没有考虑到当您的简单游乐场项目变成越来越复杂的参数化管道时出现的不良影响。

最终,你会以某种形式的技术债务结束,这些债务必须在以后以时间和努力的形式偿还。而真正的悲剧呢?所有这些都可以提前避免,只要从一开始就获得正确构建项目的远见。

我们之所以纠结于此,部分原因是因为创建项目文件夹结构是乏味的。我们想一头扎进探索数据和建立机器学习模型。但是相对较小的努力投入可以节省大量的精力。

更整洁的文件夹结构将鼓励最佳实践,简化关注点的分离,并使学习(或重新学习)旧代码更加愉快。

幸运的是——或者说是开源开发者的辛勤工作——已经有了一个现成的解决方案来创建我们想要的文件夹结构: cookiecutter 。

创建许多数据科学项目通用的干净的文件夹结构只需一个命令。观看下面的视频,了解如何设置 cookiecutter 项目结构。

** [## 烹饪-数据-科学

由 ericmjalbert 录制

asciinema.org](https://asciinema.org/a/244658)

请注意,cookiecutter 非常强大,实际上不仅仅是生成干净的项目文件夹结构。要了解更多信息,请查看精彩的 cookiecutter 文档,这是一个数据科学项目理念。**

代码版本控制— git

这一点我就不赘述了,因为这应该是一个既定的事实。软件开发的现代世界已经远离了 2000 年前黑暗的西部。每个人和他的狗都应该为他们的项目使用某种版本控制。简单的协作、高效的版本控制、回卷和代码备份。说够了。

使用 git 只是第一步。用好它完全是另一回事。

****提交代码:“尽早提交,经常提交”是明智的建议。避免提交大块的代码,而要提交小的、孤立的功能。提交时,编写描述性的提交消息,准确记录您的更改。

多用户最佳实践**:这在很大程度上是由上下文驱动的。我与我的团队合作的方式是有一个分支,它是从不直接推进的,一个开发分支,其中代码的运行版本正在工作,但从不直接工作,然后特性分支,其中团队的个别成员将编码特性,这些特性后来被合并到开发分支。当开发分支准备好发布时,它被合并到主分支中。这种封装的工作方式使得多个开发人员在不干扰主代码库的情况下处理特定功能变得简单,从而减少了合并冲突的可能性。欲了解更多信息,请查看此链接。**

模型和数据版本控制— dvc

模型和数据与代码不一样,它们永远不应该被推入代码库中。他们有独特的生命周期管理要求,有不同的运营限制。然而,适用于代码版本化的相同原理应该适用于数据和模型版本化。

构建在 git 之上的一个很棒的开源工具 dvc 可能就是您在这里寻找的。它本质上是一个数据管道构建工具,具有简单的数据版本化选项,在一定程度上有助于解决数据科学中的再现性危机。它能够有效地将您的数据和模型推送到您的服务器,无论是本地、AWS S3、GCS、Azure、SSH、HDFS 还是 HTTP。

dvc 围绕三个主要理念:

  1. 大型文件的版本控制
  2. 内置具有再现性的轻质管道
  3. git 之上的版本管理和实验管理

补充说明:对整个数据集进行版本控制的另一种方法是存储重新创建这些数据集所需的元数据,并引用在引用元数据后面创建的模型。

从环境开始构建— 虚拟化

如果您的常规实践手册中没有划分您的环境,您可能已经花了一两个下午来*衡系统范围的库版本。也许你正在做一个项目,然后转移到另一个项目,更新 numpy 和噗!,你的第一个项目有一个依赖中断。

想象一下另一种情况,您的项目被另一个团队成员从 git 中取出,他使用了项目中某个库的不同版本。他们编写一些代码,这些代码依赖于一个你的版本没有的新函数,然后推回到主分支(给聪明人一句话:永远不要直接推送到主分支),这是你拉的。你的密码被破解了。太好了。

通过使用虚拟环境来避免这种情况。对于简单的 Python 项目,使用 virtualenv。如果你有复杂的环境需求,使用 docker 之类的东西。

下面是一个简单的 virtualenv 工作流程:

  1. 创建新项目时运行mkvirtualenv
  2. pip install您的分析所需的软件包
  3. 运行pip freeze > requirements.txt来锁定用于重新创建分析的确切包版本
  4. 如果您发现您需要安装另一个包,再次运行pip freeze > requirements.txt并将更改提交给版本控制。

关于笔记本的说明— jupytext

Jupyter 笔记本在数据科学领域非常普遍。它们是围绕识字编程范式构建的,并作为强大的媒介,能够将快速原型开发和易于开发与生成流畅演示的能力相结合,中间代码段与输出和解释性文本交错。漂亮的东西。

但是,尽管笔记本电脑给人们带来了很多好处,它们也带来了很多痛苦。你的电脑里有多少Untitled7.ipynb文件?也许笔记本电脑最大的挫折是它们与版本控制的不协调。

这样做的原因是因为他们是一类被称为的编辑器,所见即所得,编辑软件允许用户查看与最终结果非常相似的内容。这意味着文档抽象出了元数据,对于笔记本来说,它通过将代码封装在大型 JSON 数据结构中来嵌入代码,二进制数据(如图像)保存为 base-64 编码的 blobs。

不过,这里需要澄清一下。Git 可以处理笔记本,因为你可以把它们推送到你的仓库。Git 不能在比较不同版本笔记本的情况下很好地处理它们,并且也很难为你提供对写在笔记本上的代码的可靠分析。

如果你在你的公司内部或者仅仅是在公共的 GitHub 上搜索签入的笔记本,你很可能会发现数据库凭证、敏感数据、“不要运行这个单元”代码块,以及一大堆其他的不良行为。为了避免这种痛苦,你可以在每次准备签入笔记本时清除输出。但这是手动的,意味着您每次都必须重新运行代码来生成输出,如果有多个用户拉和推同一个笔记本,即使被清除的笔记本元数据也会改变。

通过工具,有选择。其中最受欢迎的是 jupytext 。这里是作者关于如何使用它的一个很棒的教程。你所要做的就是安装 jupytext,它将提供一个整洁的笔记本下拉菜单,用于下载你的代码的降价版本,并省略输出,然后显式忽略.gitignore中的所有.ipynb文件。

单元测试——单元测试

对代码进行单元测试是确保隔离的代码块按预期工作的有效方法。它允许自动化您的测试过程,及早发现错误,使过程更加敏捷,并最终帮助您设计更好的系统。python 中最常用的测试框架是“包含电池”,这是一个名为[unittest](https://docs.python.org/3/library/unittest.html#module-unittest)的内置标准模块,它提供了一套丰富的工具来构建和运行测试。另一个测试工具是[pytest](https://docs.pytest.org/en/latest)

有很多关于如何进行单元测试的教程,但是这里有一些关键的提示。正如异常处理应该最小化你试图捕捉的潜在错误的功能数量,每个单元测试应该集中在一个微小的功能上,以证明它在工作。每个单元测试应该是完全独立的,并且能够单独运行。您的测试套件应该在开发新功能之前和之后运行;事实上,实现一个钩子来自动运行所有测试是一个好主意,在将代码推送到共享的 repo 之前,这种类型的测试通常是一些 CI / CD 管道的一部分,许多开源示例服务中的一个叫做 travis 。试着让你的测试更快!对每个测试函数使用长的描述性名称。测试应该位于你的源代码的一个单独的目录中,更多信息请参见文件夹结构部分。

这里是一个教程,这里是一个测试风格指南。

测井— PEP282 ,

日志记录是任何超越 POC 领域的系统的关键部分。这是一种跟踪程序执行过程中发生的事情,并将这些信息保存到磁盘上的方法。它对调试有很大的帮助,在石头上留下了痕迹,可以帮助你很好地识别你的 bug。

它通常用于两个目的之一。有诊断日志,它记录与应用程序操作相关的事件。以及审计日志,其记录用于 MI 报告的基本运行时分析。并且每个日志信息有几种类型:调试信息警告错误严重

日志是内置的、用于日志的标准库 Python 模块。

包裹

如果你坚持到最后,恭喜你。你应该得到由衷的赞扬,希望以上信息至少有一些是有用的。现在出去编码吧。

使用简单的 Python 爬虫程序下载课程材料

原文:https://towardsdatascience.com/download-course-materials-with-a-simple-python-crawler-94e06d5f84b5?source=collection_archive---------18-----------------------

一个自动下载课程资料的爬虫示例

Photo by Darwin Vegher on Unsplash

最*我在修加州大学伯克利分校著名的 CS 61A 。我想下载幻灯片并全部打印出来。但是总共有 36 张幻灯片。作为一个的程序员,我不会浪费宝贵的时间去点击 36 次下载按钮。所以我写了一个简单的脚本来自动下载所有的幻灯片。

在这篇文章中,我将简单介绍你需要知道什么来构建一个简单的下载器。

找到下载按钮的模式

首先,打开下载页面。下载按钮显示为“8pp”(见下图),这意味着一页包含 8 张幻灯片。

8pp is the download button

好了,接下来我们在 Chrome 中打开 DevTools 。您也可以在其他浏览器中找到 DevTools。单击 DevTools 左上角的箭头图标,然后将光标移动到“8pp”按钮,这将突出显示 DevTools 中的 HTML 元素。

我们可以得到下面的 HTML 行。下载链接为“assets/slides/01-Functions _ 8pp . pdf”和“assets/slides/02-Names_8pp.pdf”。这些链接在a标签的href属性中。

<li><a href="assets/slides/01-Functions_full.pdf" class="label label-outline">full</a></li>
<li><a href="assets/slides/01-Functions_1pp.pdf" class="label label-outline">1pp</a></li>
<li><a href="assets/slides/01-Functions_8pp.pdf" class="label label-outline">**8pp**</a></li>
<li><a href="assets/slides/01.py" class="label label-outline">01.py</a></li>
...
<li><a href="assets/slides/02-Names_full.pdf" class="label label-outline">full</a></li>
<li><a href="assets/slides/02-Names_1pp.pdf" class="label label-outline">1pp</a></li>
<li><a href="assets/slides/02-Names_8pp.pdf" class="label label-outline">**8pp**</a></li>
<li><a href="assets/slides/02.py" class="label label-outline">02.py</a></li>

我们希望自动提取所有链接。所以我们必须找到这些a标签行的一些模式。一个非常明确的模式是,它们都包含 8pp 文本(上面代码中的粗体部分)。我们可以先找到包含 8pp 文本的a标签行,然后通过href属性提取链接。

找到包含“8pp”的a标签行

我们使用 XPath 来定位a标记行。

slide_links = html.xpath('//li/a[text()="8pp"]/@href')

我们可以认为html是下载页面的全部 HTML 源代码。然后我们用 XPath 提取链接。//是整页的开始。li/a表示我们在li标签下找到所有a标签行。[text()="8pp"]是一个过滤器,用于获取那些只包含“8pp”文本的a标签行。

完成下载链接

我们得到的slide_links如下图所示

['assets/slides/36-Natural_Language_8pp.pdf', 
 'assets/slides/37-Final_Examples_8pp.pdf', 
 'assets/slides/36-Natural_Language_8pp.pdf', 
 ...]

我们必须添加一个前缀来完成下载链接。前缀是下面的url

url = 'http://inst.eecs.berkeley.edu/~cs61a/fa18/'

总结一下

在运行脚本之前,您需要安装一些 Python 包。

pip install requests
pip install lxml
pip install wget

requests是一个进行 HTTP 请求的工具。lxml是一个使用 XPath 的工具。而wget是给定网址下载素材文件的工具。

别忘了创建一个“幻灯片”文件夹来存放下载的文件。

在你做好准备之后,你可以运行下面的脚本来下载所有的材料。

查看我的其他帖子 中等 一分类查看
GitHub:
bramble Xu LinkedIn:徐亮 博客:bramble Xu

使用 REST API 从 Twitter 下载数据

原文:https://towardsdatascience.com/downloading-data-from-twitter-using-the-rest-api-24becf413875?source=collection_archive---------13-----------------------

嘿大家好!这是关于从 Twitter 上获取数据并使用它来获得某些见解的出版物列表中的第二篇文章,比如某个趋势上最有影响力的用户、主题建模等等。

如果你没有读过第一篇文章,你可以在这里看看:

[## 使用流式 API 从 Twitter 下载数据

在这篇文章中,我们将介绍如何使用流媒体 API 来获取包含特定单词或标签的推文,以及如何…

medium.com](https://medium.com/@jaimezornoza/downloading-data-from-twitter-using-the-streaming-api-3ac6766ba96c)

虽然上一篇文章讨论了如何从 Twitter 上收集实时生成的数据,但这篇新文章将涵盖如何收集历史数据,如某个用户、他的追随者或他的朋友以前的推文。

我们开始吧!

使用 REST API 收集历史数据

当使用流 Twitter API 时,我们收集实时产生的数据,REST API 服务于相反的目的:收集收集时间之前产生的数据,即。历史数据。

使用这个 API,我们可以收集包含某些关键字的旧推文,类似于以前的做法,但我们也可以收集与*台相关的其他信息,如不同用户帐户的朋友和追随者,某个帐户的转发,或某个推文的转发。

Twitter APIs 中的用户由两个不同的变量来标识:

  • 用户 screen_name ,也就是我们都习以为常的带@的 Twitter 名称。比如“@jaimezorno”。
  • user_id ,是每个 Twitter 用户的唯一数字标识符,是一个很长的数字串,比如 747807250819981312。

在数据收集过程中,当我们想要指定我们想要从中收集数据的用户时,我们可以使用该用户的 screen_nameuser_id 来完成,因此在深入研究 REST API 提供的更复杂的函数之前,我们将了解如何获取某个用户的 Twitter Id,我们知道该用户的用户名,反之亦然。

用用户名获取 Twitter 的 Id,反之亦然

从 Twitter Id 到用户屏幕名称是需要的,因为我们稍后将描述的一些函数返回 Twitter 标识符而不是用户屏幕名称,所以如果我们想知道谁是与相应 Id 相关联的实际用户,我们需要这个功能。

和往常一样,第一步是收集到 Twitter API。

import tweepy  
import time

access_token = "ENTER YOUR ACCESS TOKEN"  
access_token_secret = "ENTER YOUR ACCESS TOKEN SECRET"  
consumer_key = "ENTER YOUR CONSUMER KEY"  
consumer_secret = "ENTER YOUR CONSUMER SECRET"  

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)  
auth.set_access_token(access_token, access_token_secret)  
api = tweepy.API(auth)

在代码中,将“输入您的……”然后运行最后三行来创建到 Twitter REST API 的连接。

注意,这次我们没有像使用流式 API 那样创建一个对象,而是创建了一个 api 对象。一旦我们做到了这一点,从屏幕名称到 id 以及从 id 到屏幕名称的转换就非常简单了,这是通过运行以下代码块中的行来完成的:

user = api.get_user(screen_name = 'theresa_may')  
print(user.id)

这个块在 REST API 中查询 Theresa May 的官方 Twitter 帐户的 user_id,返回: 747807250819981312,这是与该帐户相关联的 id。这里需要注意的是,screen_name 不包含@。

要以相反的方向完成这项工作,并收集我们知道其 id 的帐户的屏幕名称,非常简单:

user = api.get_user(747807250819981312)  
print(user.screen_name)

它将打印: theresa_may 。正如我们所见,Id 和屏幕名称都是 API 返回的 用户 对象的属性,其中包含许多有价值的信息,如用户关注者计数、出版物数量、帐户创建日期等等。这些参数将在另一篇文章中探讨。

从用户名到 id 以及从 id 到用户名的转换就这么简单。现在让我们探索 REST API 更复杂和有用的功能。

从特定用户的时间线收集推文

某个用户的时间线是他或她过去发布或转发的推文。收集这些信息有助于了解社交网络中某个账户的先前活动。

然而,我们必须知道,将要使用的方法只能返回特定用户最* 3200 条推文,因此,如果我们正在收集一个非常活跃的帐户的帖子,并且想要很久以前的推文,我们将无法获得它们。

这是 Twitter API 的一个已知限制,目前还没有修复,因为通过这样做,Twitter 不必存储每个 Twitter 帐户产生的所有 tweets。

在如上所述创建了到 Twitter REST API 的连接之后,为了收集用户的时间表,我们必须使用类似于以下代码块中所示的代码结构:

try:  
    for tweet in tweepy.Cursor(api.user_timeline, screen_name="theresa_may", exclude_replies=True).items():                      
                    print(tweet)  
except tweepy.TweepError:  
    time.sleep(60)

正如我们所见,这段代码引入了 Twitter API 固有的新概念: 光标对象。 尽管看起来令人生畏,但这只不过是 API 必须处理分页并能够以高效有序的方式交付内容的方式。

在这种情况下,我们将从用户 @theresa_may 收集历史推文,排除其他用户对推文的回复。可以添加一个类似的参数 include_rts 来从这个用户时间表中消除转发。

此外, try-except duo 被添加来处理我们可能发现的任何错误,如请求率超出或保护用户。当操作这种类型的 API 时,这是非常常见的。

这段代码的输出是一个非常难看的对象,叫做 状态对象 ,用于每条推文,看起来像这样:

Status(_api=<tweepy.api.API object at 0x000001C52728A710>, _json={'created_at': 'Sun May 12 11:55:41 +0000 2019', 'id': 1127542860520329216, 'id_str': '1127542860520329216', 'text': 'Congratulations to @SPendarovski on your inauguration as President of North Macedonia. I witnessed the strong relat…………

另一篇文章,如用户对象案例,将详细解释这些对象的性质及其属性,然而现在我们将只描述如何从中收集一些最有趣的字段。

让我们看看我们如何能做到这一点。

我们将保持与前一个块相同的代码结构,但是添加了一些额外的行,我们将使用这些行来获取我们认为最相关的 status 对象的部分。

try:  
    for tweet in tweepy.Cursor(api.user_timeline, screen_name="theresa_may", exclude_replies=True, count = 10).items():  
                    tweet_text = tweet.text  
                    time = tweet.created_at  
                    tweeter = tweet.user.screen_name  
                    print("Text:" + tweet_text + ", Timestamp:" + str(time) + ", user:" +  tweeter)  
except tweepy.TweepError:  
    time.sleep(60)

这一次,执行这段代码应该会显示如下内容:

Text:We’re driving the biggest transformation in mental health services for more than a generation. [https://t.co/qOss2jOh4c,](https://t.co/qOss2jOh4c,) Timestamp:2019-06-17 07:19:59, user:theresa_may
Text:RT @10DowningStreet: PM @Theresa_May hosted a reception at Downing Street to celebrate:
✅ 22 new free schools approved to open 
✅ 19,000 ad…, Timestamp:2019-06-15 13:53:34, user:theresa_may
Text:Two years on from the devastating fire at Grenfell Tower, my thoughts remain with the bereaved, the survivors and t… [https://t.co/Pij3z3ZUJB,](https://t.co/Pij3z3ZUJB,) Timestamp:2019-06-14 10:31:59, user:theresa_may

考虑到您将获得的 tweet 取决于您正在搜索的用户在执行代码之前发布的 tweet,因此如果您以目标用户 theresa_may 运行这些块,您很可能不会获得与我相同的 tweet。

尽管从前面的代码块返回的结果可能看起来更好,但我们可能希望数据的格式便于以后存储和处理,比如 JSON。

我们将对代码做最后一次修改,以便打印出每条 tweet,以及我们想要的 tweet 中的字段,作为 JSON 对象。为此,我们需要导入 json 库,并对代码做进一步的修改,如下所示:

import json  

try:  
    for tweet in tweepy.Cursor(api.user_timeline, screen_name="theresa_may", exclude_replies=True, count = 10).items():  
                    tweet_text = tweet.text  
                    time = tweet.created_at  
                    tweeter = tweet.user.screen_name  
                    tweet_dict = {"tweet_text" : tweet_text.strip(), "timestamp" : str(time), "user" :tweeter}  
                    tweet_json = json.dumps(tweet_dict)  
                    print(tweet_json)  
except tweepy.TweepError:  
    time.sleep(60)

这一次,我们将输出与以前相同的字段,但采用 JSON 格式,这样便于其他人处理和理解。在这种情况下,相同 tweet 的输出将是:

{"tweet_text": "We\u2019re driving the biggest transformation in mental health services for more than a generation. [https://t.co/qOss2jOh4c",](https://t.co/qOss2jOh4c%22,) "timestamp": "2019-06-17 07:19:59", "user": "theresa_may"}
{"tweet_text": "RT @10DowningStreet: PM @Theresa_May hosted a reception at Downing Street to celebrate:\n\u2705 22 new free schools approved to open \n\u2705 19,000 ad\u2026", "timestamp": "2019-06-15 13:53:34", "user": "theresa_may"}
{"tweet_text": "Two years on from the devastating fire at Grenfell Tower, my thoughts remain with the bereaved, the survivors and t\u2026 [https://t.co/Pij3z3ZUJB",](https://t.co/Pij3z3ZUJB%22,) "timestamp": "2019-06-14 10:31:59", "user": "theresa_may"}

在了解了如何有效地收集和处理某个用户的时间表之后,我们将看看如何收集他们的朋友和追随者。

收集某个用户的追随者。

获取一组用户的关注者是 Twitter 研究中最常见的行为之一,因为创建关注者/被关注者网络可以提供一些关于某个主题或标签的特定用户群的非常有趣的见解。

要获得某个用户的关注者,只需像以前一样使用我们的凭据连接到 API,然后运行以下代码即可:

try:   
    followers = api.followers_ids(screen_name="theresa_may")  
except tweepy.TweepError:  
    time.sleep(20)

通过在 api = tweepy 中设置参数wait _ on _ rate _ limit为真。API(auth,wait_on_rate_limit=True) 当我们连接到 API 时,下载任何类型的数据时超过速率限制的错误都可以避免,因此尽管在本文的前几部分中没有使用过它,我还是建议在您打算从 Twitter REST API 下载大量数据时使用它。

这里有一个列表,上面有账户 @theresa_may 的所有关注者的 id。这些 id 然后可以使用我们之前描述的 api.get_user 方法翻译成用户名。

如果我们想要收集某一组用户的关注者,我们只需要在前面的代码块中添加几行代码,如下所示:

user_list = ["AaltoUniversity", "helsinkiuni","HAAGAHELIAamk", "AaltoENG"]follower_list = []  
for user in user_list:  
    try:   
        followers = api.followers_ids(screen_name=user)  
    except tweepy.TweepError:  
        time.sleep(20)  
        continue  
    follower_list.append(followers)

在这种情况下,我们将收集与芬兰大学相关的用户帐户的追随者。该代码的输出将是一个列表( follower_list ),在每个索引中有一个列表,其中包含来自 user_list 的具有相同索引的帐户的追随者。

使用枚举函数可以很容易地关联这两个列表(用户和关注者列表):

for index, user in enumerate(user_list):  
    print("User: " + user + "\t Number of followers: " + str(len(follower_list[index])))

这个模块的输出将是:

User: AaltoUniversity  Number of followers: 5000User: helsinkiuni      Number of followers: 5000User: HAAGAHELIAamk    Number of followers: 4927User: AaltoENG  Number of followers: 144

这可能会让你感到疑惑:账号@阿尔托大学@helsinkiuni 的粉丝数量是否完全相同,都是 5000 人?

最明显的答案是否定的。如果你查看这两所大学的 Twitter 账户,你会发现它们的粉丝都在万分之几的范围内。

那为什么我们只得到 5000 呢?

嗯,这是因为对于涉及分页的问题,Twitter API 将它们的响应分解在不同的页面中,我们可以认为这些页面是具有某个最大大小的所请求信息的【块】,要从一个页面转到下一个页面,我们需要使用一种特殊的对象,称为光标对象,这在上面已经提到过。

以下代码使用了相同的功能,但这次使用了一个光标对象,以便能够抓取每个用户的所有关注者:

user_list = ["AaltoUniversity", "helsinkiuni","HAAGAHELIAamk", "AaltoENG"]    
follower_list = []  
for user in user_list: 
    followers = []  
    try:         
        for page in tweepy.Cursor(api.followers_ids, screen_name=user).pages():  
            followers.extend(page)  
    except tweepy.TweepError:  
        time.sleep(20)  
        continue  
    follower_list.append(followers)

这一次,如果我们使用枚举循环来打印每个用户和他们的追随者数量,输出将是:

User: AaltoUniversity  Number of followers: 35695User: helsinkiuni      Number of followers: 31966User: HAAGAHELIAamk    Number of followers: 4927User: AaltoENG  Number of followers: 144

也就是每个账户的真实粉丝数。

收集某个用户的朋友。

类似于我们如何收集某个用户的关注者,我们也可以收集他的【朋友】,也就是某个用户关注的人群。为此,我们将一如既往地使用我们的凭据连接到 API,然后运行以下代码:

friends = []  
try:   
    for page in tweepy.Cursor(api.friends_ids, screen_name="theresa_may").pages():  
        friends.extend(page)  
except tweepy.TweepError:  
    time.sleep(20)

该代码块中的变量 friends 将是一个列表,其中包含我们选择的 screen_name 用户的所有朋友(在本例中为 theresa_may)

查看某个用户的关注者/朋友的数量。

如果我们对某个账户的追随者/朋友是谁不感兴趣,而只对他们的数量感兴趣,Twitter API 允许我们收集这些信息,而不必收集所需账户的所有追随者/朋友。

要做到这一点而不实际收集所有的关注者(考虑到下载速率限制,如果用户有很多关注者,这可能需要一段时间),我们可以使用我们之前使用的从 user.screen_nameuser.idapi.get_user 方法,反之亦然。下面的代码块显示了如何操作:

user = api.get_user(screen_name = 'theresa_may')  

print(user.followers_count)  
print(user.friends_count)

它将输出:

83939129

我们也可以使用 Twitter user.id 来做这件事,如果我们知道它的话,就像之前看到的那样,就像这样:

user = api.get_user(747807250819981312)print(user.followers_count)  
print(user.friends_count)

它会再次输出:

83939129

我们可以从 Theresa 的官方账户中看到,这是正确的追随者和朋友数量。

结论:

我们已经描述了 Twitter REST API 的主要功能,并解决了从它那里收集数据时可能会发现的一些问题。

这些数据可以用于很多目的:从使用复杂的机器学习算法检测趋势或假新闻,到推断某个品牌的积极程度的情感分析,图形构建,信息扩散模型等等。

如需进一步研究或澄清此处的信息,请参考本指南中的链接或:

Twitter 开发者页面:https://developer.twitter.com/en/docs

Tweepy 的 github 页面:https://github.com/tweepy/tweepy

Tweepy 官方页面:https://www.tweepy.org/

推特的高级搜索:https://twitter.com/search-advanced

敬请关注《社交网络分析》的更多帖子!

通过 Google Colab 将数据集下载到 Google Drive

原文:https://towardsdatascience.com/downloading-datasets-into-google-drive-via-google-colab-bcb1b30b0166?source=collection_archive---------1-----------------------

在 Google Colab 中为数据科学项目使用 Google Drive 的分步指南

更新:(即将推出)TensorFlow 2.0 将为 Keras 推出新的分发策略,以便您可以使用相同的代码在 TPUs 上分发您的模型 Google Colab 发布后可以直接访问 Google Cloud TPUs !观看TF Dev Summit’19了解更多信息。**

Google Colab and Google Drive back you up in deep learning — Photo Credit: Elizabeth Tsung

如果你像我一样使用旧的 MacBook Pro(2013 年末,120GB 高清),有限的存储将是我在数据科学项目中最大的障碍。对于那些也在从事具有大型数据集的数据科学项目的人来说,我确信保存数据集并在云上训练模型肯定会让你放心。

在本教程中,我将与您分享我在以下方面的经验:

  1. 将 Google Drive 安装到 Google Colab
  2. 通过 Google Colab 将数据集直接下载到 Google Drive
  • 使用 Kaggle API
  • 从竞赛网站,要求下载时需要用户名和密码

额外收获:一键启用 Google Colab 中的免费 GPU 支持,使用 Tensorflow 进行训练。

将谷歌硬盘安装到谷歌实验室

第一步

首先,进入你的谷歌实验室,然后输入以下内容:

from google.colab import drive
drive.mount('/content/gdrive')

该单元将返回以下内容,您需要转到该链接来检索授权码。那你就可以走了!

第二步

如果您能够访问 google drive,您的 Google Drive 文件应该都在以下位置:

/content/g Drive/My Drive/

而您当前的目录将是 /content/

Click on the arrow on the left and you will find the data structure.

为了方便使用,只需保存下面的代码片段并将其粘贴到 Google Colab 中,您就可以轻松地将您的 Google Drive 安装到笔记本上。

通过 Google Colab 将数据集直接下载到 Google Drive

在这一节中,我将与您分享我从 Kaggle 和其他竞争对手那里下载数据集的经验。

通过 Kaggle API 下载 Kaggle 数据集

步骤 1-从您的帐户获取 API 密钥

访问www.kaggle.com⇨登录⇨我的帐户⇨创建新的 API 令牌

将自动下载“kaggle.json”文件。

步骤 2 —上传 kaggle.json 文件

使用 Google Colab 中的这些代码片段完成任务:

from google.colab import files
files.upload()  #this will prompt you to upload the kaggle.json

下面将创建必要的文件夹路径。

!pip install -q kaggle
!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle/
!ls ~/.kaggle
!chmod 600 /root/.kaggle/kaggle.json  # set permission

步骤 3-下载所需的数据集

只需下载所需的数据集,语法如下:

!kaggle 竞赛下载-c '竞赛名称'-p "目标 _ 实验室 _ 目录"

!kaggle competitions download -c histopathologic-cancer-detection -p /content/gdrive/My\ Drive/kaggle/cancer

额外收获:请参见下面搜索 Kaggle 数据集的 git 要点

步骤 4 —解压缩

对于有多个 zip 文件的数据集,我倾向于将目录切换到指定的文件夹,然后一个一个地解压缩。

!解压缩-q 文件。zip]-d[出口]

-q 禁止打印正在解压的文件名
-d【解压目录】可选解压文件的目录

import os
os.chdir('gdrive/My Drive/kaggle/cancer')  #change dir
!mkdir train  #create a directory named train/
!mkdir test  #create a directory named test/
!unzip -q train.zip -d train/  #unzip data in train/
!unzip -q test.zip -d test/  #unzip data in test/
!unzip sample_submission.csv.zip
!unzip train_labels.csv.zip

点击这里阅读更多 Kaggle API 文档。

从竞赛网站下载数据集,请求下载时需要用户名和密码

对于像 ICIAR2018 这样的比赛,你需要在下载数据集时提供用户名和密码。

要在 Google Colab 中执行此操作,首先您可以将当前目录更改为您希望保存数据集的文件夹。然后,使用 wget 而不是使用 curl 命令。

!wget --user=your_username --password=your_password http://cdn1.i3s.up.pt/digitalpathology/ICIAR2018_BACH_Challenge.zip

下载后,您可以使用上面相同的方法解压缩文件。

额外收获:一键启用 Google Colab 中的免费 GPU,用 Tensorflow 进行训练

在您将 Google Drive 安装到 Google Colab 并下载了所需的数据集之后,让我们在您的 Colab 笔记本中启用 GPU 并训练您的模型。

从任务栏:运行时⇨更改运行时类型

硬件加速器:无⇨ GPU

希望你觉得这个教程有用,祝你云计算愉快!

信用

感谢 Matt Gleeson 、 Finlay Macrae 的建议,让内容变得更好。

普通深度 Q 网络

原文:https://towardsdatascience.com/dqn-part-1-vanilla-deep-q-networks-6eb4a00febfb?source=collection_archive---------3-----------------------

DQN 家族

深度 Q 学习解释

介绍

该职位的结构如下:

我们将简要介绍一般的策略迭代和时间差分方法。然后,我们将 Q 学习理解为一个一般的策略迭代。最后,我们将理解并实现 Deepmind 的论文“用深度强化学习玩雅达利(Mnih et al. 2013) 中提出的 DQN。

通用策略迭代(GPI)

General policy iteration

我们把一般策略迭代称为策略评估和策略迭代的交替。我们从某个任意初始化的策略开始,评估该策略(表示为 E ),从评估中导出一个新策略(表示为 I ),并重复这个过程,直到我们达到一个最佳策略。通过这个迭代过程,我们得到{V_π}和{π}的单调递增(改进)序列。

我们如何保证这一点?我们将看看政策改进定理:

该定理指出,遵循政策π'的价值比遵循政策π'的价值更大。即政策π'优于π。我们现在将证明政策改进定理。

因此,通过政策评估和迭代的迭代相互作用,我们可以最终达到我们的最优政策和价值函数。

时间差分法

时间差分法是蒙特卡罗方法和动态规划方法的结合。回忆每种方法:

  • 蒙特卡罗方法使用估计值(1)进行更新。因为我们不知道真实的期望值,所以我们从环境中采样 G_t。
  • 动态编程(DP)方法使用(3)进行更新。我们说 DP 方法是 bootstrap,因为我们使用 v_pi(s_{t+1})的当前估计来执行更新。

在 TD 方法中,我们将蒙特卡罗的采样与动态规划的自举结合起来。我们对期望值进行采样,如(1)所示,并使用下一个状态值的当前估计值来更新原始状态的值,如(3)所示。TD 目标\delta可以有多种形式,但以下是最基本的形式:

q 学习和 GPI

在 Q 学习中,我们直接逼*我们的最优动作值函数。在 GPI 意义上,我们从 Q 函数中导出策略,并通过 TD 方法执行策略评估,以获得下一个 Q 函数。

现在让我们的 Q 函数用θ参数化,在我们的例子中,就是神经网络。根据 GPI 公式,我们希望将当前 Q 值与目标 Q 值之间的差异降至最低。为此,我们希望获得两者之间的均方误差:

然后执行梯度下降以最小化两者之间的误差。

深度 Q 网络

发表在(Mnih 等人,2013 年)的 Deep Q learning 利用深度学习的进步从高维度感官输入中学习策略。具体来说,它使用卷积网络从 Atari 2600 游戏中学习原始像素,而不是低维特征向量。下图展示了 DQN 的建筑:

Source: https://leonardoaraujosantos.gitbooks.io/artificial-inteligence/content/image_folder_7/DQNBreakoutBlocks.png

为了使计算更加可行,原始的 4 帧游戏图像(RGB 像素)被缩小到 4 帧(84 x 84)图像,从而得到一个(84 x 84 x 4)张量。然后我们把它输入到一个卷积神经网络,它输出一个包含每个动作的 Q 值的向量。从那里,我们使用一个探索方案(通常是 epsilon-greedy ),并在具有最高 Q 值的动作和随机动作之间进行概率选择。

在更高的层面上,深度 Q 学习是这样工作的:

  1. 使用当前策略在重放缓冲区中收集和存储样本
  2. 从重放缓冲器中随机抽样批次的体验(称为体验重放)
  3. 使用采样的经验来更新 Q 网络
  4. 重复 1-3

我们将进一步了解步骤(2)和(3),这将让我们直接进入实现阶段。

体验回放

为什么我们要随机抽样经验,而不是仅仅使用过去的连续经验?连续的经历彼此(在时间上)高度相关。在统计学习和优化任务中,我们希望我们的数据独立分布。也就是说,我们不希望我们提供的数据以任何方式相互关联。经验的随机抽样打破了这种行为的时间相关性,并将其分布/*均到许多以前的状态。通过这样做,我们避免了模型中的显著振荡或发散——相关数据可能产生的问题。

更新 Q 网络

为了更新 Q 网络,我们希望最小化目标 Q 值(根据贝尔曼方程)和当前 Q 输出之间的均方误差:

在哪里

最理想的情况是,我们希望误差减少,这意味着我们当前政策的输出越来越接*真实的 Q 值。因此,利用如上定义的损失函数,我们根据以下等式对损失函数执行梯度步骤:

实施指南

我们将从构建配备有卷积神经网络的深度 Q 网络开始:

forward函数中,我们输入像素图像,并通过我们的模型输出对应于每个动作的 Q 值向量。

然后,我们将构建我们的重放缓冲区,在那里我们可以存储体验—(状态、动作、奖励、下一个状态、bool(is_done))转换—以及用于学习的随机体验样本:

接下来,我们编写一个函数来计算每个梯度步长的值损失。这看起来像:

最后,我们将把它们都放在我们的 DQN 代理中:

香草 DQN 的实现到此结束。您可以在我的 GitHub 资源库中找到完整的可运行实现:

[## cy oon 1729/深度 Q 网络

Q-learning 家族(PyTorch)算法的模块化实现。实现包括:DQN,DDQN,决斗…

github.com](https://github.com/cyoon1729/deep-Q-networks)

在本系列的后面部分,我们将探索 DQN 的许多变体,它们在许多方面改进了原来的版本。

感谢阅读!

参考资料:

  • 用深度强化学习玩雅达利(Mnih et al. 2013)
  • 强化学习:导论(萨顿和巴尔托)

下一篇文章:

我的系列将从香草深度 Q 学习(这篇文章)开始,直到 Deepmind 的彩虹 DQN,当前的艺术状态。查看我的下一篇文章关于用双 Q 学习减少高估偏差!

  1. 深度 Q 网络
  2. 双深 Q 网络

德卡里斯。—使用 Docker Machine、PyTorch 和 Gigantum 实现可移植和可再现的 GPU 工作流

原文:https://towardsdatascience.com/dracarys-use-docker-machine-pytorch-gigantum-for-portable-reproducible-gpu-workflows-481ca2632bbb?source=collection_archive---------15-----------------------

CC image By I, Luc Viatour, CC BY-SA 3.0

TL;速度三角形定位法(dead reckoning)

  1. 手动创建可移植和可再现的 GPU 工作流是脆弱的、技能密集型的和费力的,即使使用容器也是如此。
  2. 幸运的是,你可以使用 Docker Machine、PyTorch & Gigantum 或多或少地实现自动化。
  3. 我们用这三样东西来展示一个强大的系统,以创建在笔记本电脑和云、CPU 和 GPU 之间无缝移动的工作流。

假设 —你应该有:

  1. 使用 Bash(在 Linux/macOS 上)或 PowerShell(在 Windows 上)的经验。
  2. Docker CE 安装在本地。
  3. AWS 凭证& EC2 GPU 实例的足够权限。

如果达不到这些要求,也不要绝望。你可以通过一些背景阅读和一些剪切粘贴来快速阅读这篇文章。

剧透预警——完成这篇帖子所用的时间将远远少于《GoT》第五集丹妮莉丝·坦格利安烧毁君临所需的时间。

介绍

用于并行处理的 GPU 为一些计算提供了令人难以置信的速度提升——最著名的是深度学习。好的图形处理器可以在 CPU 上完成复杂的计算。

不幸的是,安装和配置必要的软件环境需要技能和时间。对于大多数用户来说,访问 GPU 的唯一方式是通过不断增长的*台之一,这些*台提供了进入托管云环境的浏览器界面。这些*台的基本问题是,它们要么是免费的&在计算上毫无价值,要么是功能性的,但似乎是为企业预算量身定制的。

获得更广泛访问的一个途径是通过最大限度地减少设置所需的技能和时间,让人们能够自己做事情。另一种方法是使 GPU 工作流可移植,即自包含&易于跨各种资源运行。例如,促进 CPU & GPU 机器之间的移动使得能够在更便宜的 CPU 上测试&调试,从而节省昂贵的 GPU 用于实际计算。在这篇文章中,我们将做这两件事。

基本上,当谈到轻松复制和便携式 GPU 笔记本电脑时,我们会给你自己的龙。

我们使用的工具

Docker Machine是一个简单的 Apache 许可命令行工具,用于供应、配置&管理远程虚拟环境。

PyTorch 是一个 BSD 授权的深度学习框架,可以轻松在 CPU 和 GPU 之间切换进行计算。

Gigantum 是一个麻省理工学院许可的本地应用程序,它与云服务配对,以创建任何人都可以轻松使用的可复制工作流

我们的存在性证明有三个部分:

  1. 用 Docker Machine 创建 EC2 GPU 实例的简单过程:
  2. 从 Bash 提示符配置实例;
  3. 只需点击几下鼠标,即可导入和运行 PyTorch 迁移学习笔记本。

在我们开始之前——为了使这篇文章对不同的用户都是可靠的,我们在过程的确定性方面犯了错误&工具的简单性。

第 1 部分—创建一个 EC2 p2.xlarge 实例

我们开始吧。

第 1 步到第 3 步是一次性步骤,但是第 4 步中的 Docker Machine 命令是您随时可以用来创建新遥控器的命令。

如果您以前没有使用过,Docker Machine 是一个简单的工具,可以在远程主机上轻松安装、管理和连接 Docker。方便的是,它可以自动发送和简单的端口转发。可以了解一下这里 & 这里。

第 1 步— 验证 Docker CE &是否正在运行

在终端(Bash 或 PowerShell)中,运行:

docker version

您必须在本地运行 Docker CE。如果你没有一个相当最*的版本,你可能想要更新它。注意:你不能使用 Docker 工具箱

第二步(仅限 Linux 用户)——没有 Docker 机器就安装

Docker for Linux 的发行版通常不包含 Docker Machine(但 macOS & Windows 包含)。要解决这个问题,请在 Bash 终端中运行以下命令:

base=https://github.com/docker/machine/releases/download/v0.16.0 curl -L $base/docker-machine-$(uname -s)-$(uname -m) > /tmp/docker-machinesudo install /tmp/docker-machine /usr/local/bin/docker-machine

然后,注销&登录——确保 docker-machine 在您的路径上。

步骤 3 — 为 CLI 配置 AWS API 凭证。

如果您没有凭证,请访问控制台进行设置。您需要:

  1. 您的访问密钥 ID, youraccesskey。
  2. 您的秘密访问密钥: yoursecretkey

确保将您的 AWS CLI 配置为自动调用凭证供命令行使用,否则您需要将它们添加到下面的 Docker 机器命令中。

在终端中,运行:

aws configure
AWS Access Key ID [None]: ***youraccesskey*** 
AWS Secret Access Key [None]: ***yoursecretkey*** 
Default region name [None]: 
Default output format [None]: 

步骤 4使用 Docker Machine 创建实例。

现在可以使用一个 Docker Machine 命令(带有多个参数)来设置 p2.xlarge 实例。

(在 Linux 或 Mac 上)在 Bash 终端中输入以下命令

docker-machine create --driver amazonec2\
--amazonec2-amiami-0a313d6098716f372 \
--amazonec2-instance-type p2.xlarge \
--amazonec2-region us-east-1 \
--amazonec2-root-size 64 \
gigantum-gpu

(在 Windows 上)在 PowerShell 终端中输入以下命令

docker-machine create --driver amazonec2 `
 --amazonec2-amiami-0a313d6098716f372 `
 --amazonec2-instance-type p2.xlarge `
 --amazonec2-region us-east-1 `
 --amazonec2-root-size 64 `
 gigantum-gpu

Pasting and executing the commands for Windows PowerShell is pretty simple.

如果这次成功了 —恭喜!您已经设置了实例。

如果没有成功——原因可能很简单。

  • 你的一把钥匙错了。纠正一下。
  • 您没有足够的权限创建实例。纠正这一点,并确保从亚马逊请求访问一个p2.xlarge
  • (Windows)Docker 有问题。重新启动 Docker,然后再次尝试 Docker Machine 命令。

用 Docker 机器管理遥控器

  • docker-machine ls检查正在运行什么。
  • docker-machine start gigantum-gpu开始实例。
  • docker-machine restart gigantum-gpu重启实例。
  • docker-machine stop gigantum-gpu停止实例。
  • docker-machine ssh gigantum-gpuSSH 进入实例。

不是受益人

删除实例时要小心。这个命令很简单,docker-machine rm gigantum-gpu,但是有两个潜在的问题。

第一个——是永久的。你将会失去一切。

第二个——在停止实例之前删除实例可能不会实际关闭实例。它可能仍在运行&你不会知道,直到你去控制台。

有意识、有目的地删除实例。在删除实例之前,请始终停止该实例。

第 2 部分—在 GPU 实例上安装软件

好的。现在结束了,让我们再走 5 步。你只需要做一次。

准备好了吗?

第一步登录遥控器

docker-machine ssh gigantum-gpu

Docker Machine completely automates the SSH process. No more secrets. No more putty.

除非我们另外告诉你,否则你是在远程的 Bash 终端中。

第二步将你的用户添加到 docker 组,添加显卡驱动 ppa,&安装 Nvidia GPU 驱动

sudo usermod -aG docker $USER
sudo add-apt-repository -y ppa:graphics-drivers/ppa

然后

sudo apt-get install -y linux-aws nvidia-headless-430 nvidia-utils-430

将出现一个菜单。默认设置是保留当前的本地版本。不要。

选择Install the package maintainer's version并点击回车。

You will see this menu. Install the package maintainer’s version, although it doesn’t matter much how you answer.

步骤 3安装 Nvidia Docker 驱动,然后注销并重启实例

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
 sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
 sudo tee /etc/apt/sources.list.d/nvidia-docker.list

然后

sudo apt-get update
sudo apt-get install -y nvidia-docker2

通过从本地终端输入ctrl+d、&来注销,并使用

docker-machine restart gigantum-gpu

第四步登录,安装 Gigantum,注销&然后停止实例

通过在本地终端输入以下内容登录:

docker-machine ssh gigantum-gpu

然后,在远程运行的 Bash 提示符下:

sudo apt-get install -y python3-pip
pip3 install --user gigantum

现在,通过输入ctrl+d &退出,然后使用以下命令从本地终端重新登录:

docker-machine ssh gigantum-gpu

然后

gigantum install

最后,用ctrl+d &退出,然后从本地终端用以下命令停止:

docker-machine stop gigantum-gpu

第五步 — T 休息一下,伸伸腿,稍微反思一下

当你休息的时候,回想一下刚刚发生的事情。你的努力换来了什么?

  1. 在很短的时间内&使用相对较少的命令,您就可以设置最便宜的 EC2 GPU 实例并为容器化的 GPU 工作流安装软件。
  2. 您可以通过启动实例并使用 Docker Machine 登录来随时访问它。以上是一次性设置!

最后,请记住,如果您不停止实例,Amazon 将向您收取计算时间费用。此外,它还连接了 64 GB 的 EBS 存储。如果你不删除它,即使它被停止,你也会产生(相对较小的)费用。

第 4 部分—运行 PyTorch GPU 工作流

好的。让我们开始讨论最后 20 分钟的要点。

我们将轻松地在 GPU 实例上运行 CPU/GPU 不可知的&可再现 PyTorch 笔记本。笔记本改编自Sasank Chilamkurthy的转学教程。举例说明了 CPU/GPU 便携笔记本的最佳实践和两种迁移学习思路:微调 & 特征提取

导入和检查 PyTorch 项目

对于下一部分,只有三个命令。其余的在浏览器中。

  1. docker-machine start gigantum-gpu
  2. docker-machine ssh gigantum-gpu -L 10000:localhost:10000
  3. gigantum start --wait 60

对于 Gigantum 和 Jupyter 的工作,我们不会列出另一个步骤序列,我们将只显示一个过程的视频(加速)。

可以使用以下 URL 导入迁移学习项目:

[*https://gigantum.com/tinydav/simple-pytorch-transfer-learning*](https://gigantum.com/tinydav/pytorch-transfer-learning)

From start to finish, this takes a total of 7 minutes in real time.

该视频应该是不言自明的,但我们可以解开它一点。

  1. 登录应用程序后,运行 PyTorch 笔记本所需的一切都作为代码、数据和环境的存储库导入。
  2. 自动构建一个包含运行笔记本的环境的容器。
  3. 在构建容器时,我们查看活动和环境的信息。
  4. 构建完成后,单击 Code 选项卡中的文件名会在另一个选项卡中启动 JupyterLab。如果没有,你可能已经安装了弹出窗口拦截器。
  5. 笔记本运行在 GPU 上。

非常简单,在 p2.xlarge 上每小时只需 0.90 美元,而不是在 SageMaker 上每小时 1.20 美元。

有一点需要注意——你并不局限于在基于这个实例的 CUDA 10.0 上运行。如果你查看另一个项目my-first-project的环境选项卡,你会注意到它没有的 CUDA 10.0,它有一套完全不同的包

完成后,请确保执行以下操作:

  1. 在终端运行gigantum stop
  2. ctrl+d退出实例。
  3. docker-machine stop gigantum-gpu停止实例。

现在,给读者一个练习

您可能还记得,我们说过您可以使用相同的设置在 CPU 上运行笔记本电脑。我们将此作为一个练习留给读者,但我们给出了一个简短的草图,以使它进行得更顺利一些。

按照上面的说明,你可以自己设置一个 CPU 实例,然后运行这个笔记本。如果你有 Docker CE,你可以通过安装 Gigantum 在本地完成,或者你可以通过修改上述过程在远程完成。

这次你不需要安装任何与 Nvidia 相关的软件。事实上,你甚至不需要在 AWS 上这样做,因为 Docker Machine 为其他提供商工作,比如数字海洋。你甚至可以用你自己的遥控器来做

在 CPU EC2 实例上运行该笔记本的基本步骤是:

  1. 使用 Docker Machine 创建一个 t2.xlarge EC2 实例,使用我们为gigantum-cpu创建的 AMI。
  2. 将您的用户添加到 docker 组,安装 pip3,然后安装 Gigantum。
  3. 请注意,在运行gigantum install之前,您需要注销然后重新登录。
  4. SSH 进入gigantum-cpu,做同样的端口转发,启动 Gigantum &然后导入运行笔记本。

完成后,确保停止gigantum-cpu实例。

最后 TensorFlow 对 LSTM 笔记本的调侃

如果您完成了上面的练习,那么您现在已经有了一个使用 PyTorch 非常容易地运行 CPU/GPU 不可知工作流的系统。其中重要的一点是 PyTorch 可以无缝地为您管理交换机。

但是 TensorFlow 呢?它不能以这样一种无缝的方式处理这种切换,但事实证明,您可以使用不同的方法在 CPU 或 GPU 上创建工作流,同样是在 Gigantum 中。

在下一篇文章中,我们将讨论如何使用 Docker Machine、Gigantum & TensorFlow 实现这一点。

但是,如果您愿意,您现在可以使用刚刚配置的 p2.xlarge 自己完成这项工作。你不需要改变什么

你可以使用 https://gigantum.com/dmk/trump-speech-generation 的 LSTM 笔记本开始使用。

由Dav Clark(HDS)&Tyler white house(Gigantum 的 CEO)撰写。

在 Twitter 上关注我们,或者在 Spectrum 上向我们问好!

拖放数据预处理:使用 Tableau Prep 清理 Titanic 数据集

原文:https://towardsdatascience.com/drag-drop-data-preprocessing-titanic-dataset-cleaning-with-tableau-prep-267c7f753ef?source=collection_archive---------24-----------------------

Photo by Markus Spiske on Unsplash

Tableau Prep,有多厉害,失败在哪里,最大优势在哪里。

在我作为 Tableau 的商业智能顾问的工作中,我听到了很多“Tableau 不是 ETL”的说法,对此我大部分时间都不得不同意。不管最*的变化,Tableau 已经对其 Tableau 桌面产品进行了改进,以提高处理大量数据的性能,在大多数情况下,在使用 Tableau 桌面进行分析和报告之前,有必要添加一个 ETL 流程,如 Talend 或 Pentaho。

意识到之前的情况,去年(2018) Tableau 向公众发布了产品 Tableau Prep Builder,目的是在使用 Tableau Desktop 进行数据探索之前提供一个拖放工具。作为该工具的顾问,我有责任探索其潜力,了解其优势和实际能力,以评估在客户的 BI 项目中向其展示该工具是否可行。为了做到这一点,我决定将我曾经在 Python 中做过的清理过程复制到流行的 Titanic 数据集,小心地注意到该工具可能存在不足之处,以及它是否真的足够兼容以应用于更大的项目。

背景和规格

作为我在数据科学学习过程中的一部分,我在一年多前参加了广受欢迎的 Kaggle 竞赛“Titanic:Machine Learning from Disaster”,为了这个项目,我使用 Python 执行了数据集清理和预测,并将其与 Tableau 中的数据集探索和分析相集成。该项目可以在这个链接中读取,我将使用 Tableau Prep Builder 版本 2019.3 复制用 Python 完成的数据准备工作。在整篇文章中,我将尝试解释 Tableau Prep 的一般功能,但重点是 Python 工作与工具中创建的流的比较。

[## 使用集成学习的泰坦尼克号预测

下载数千个项目的开放数据集+在一个*台上共享项目。探索热门话题,如政府…

www.kaggle.com](https://www.kaggle.com/danielmartinezb/titanic-prediction-using-ensemble-learning/notebook?scriptVersionId=4573741)

第 1 部分:加载数据集

与大多数 Kaggle 数据集一样,清理过程从读取 CSV 训练文件开始。Pandas 用于确保数据的结构是正确的,并使用函数 describe() 了解数据集的描述性统计信息,例如记录的数量、每列的最大值和最小值等。

Reading the CSV file with Python and Pandas

Summary of the data

在 Tableau Prep 中,与纯文本文件中的数据源的连接与在 Pandas 中一样简单,此外,它还具有 Tableau Desktop 中为大量服务器(如 Hadoop、Teradata、MySQL、BigQuery 等)提供的已知原生连接向导。

Some of the connections available in Tableau Prep

此时,Tableau Prep 开始显示其一些节省时间的功能。如果有多个结构相同的文件,可以创建一个“通配符联合”,只需单击一下,就可以解决 Pandas 中需要的多个连接。

此外,一旦连接到数据,我们就可以定义一个在流程中使用的样本。这使得流程中的每个进程都具有更好的性能,因为无论如何,在准备流程结束时,清理将应用于整个数据集。

Options available when connecting to a source in Tableau Prep

我们还发现,从 Pandas describe()函数获得的信息可以在 Tableau Prep 的“Profile Pane”中找到,在这里我们将能够查看每个字段的摘要描述,并将其与原始表格结构进行对比(甚至利用一些视觉效果)。

第 2 节:处理缺失值

决定如何处理包含空值字段的记录是数据清理最常见的任务之一。对于这一步,我开发了一个函数,能够可视化每个字段中的空记录的数量以及它们所代表的总数的百分比(这些信息可以在 Prep 中从“Profile Pane”中查询)。

Pandas in Python vs Profile Pane in Tableau Prep

从具有空值的字段的信息中,由于缺失值的数量很大,我决定删除列“Cabin ”( Tableau Prep 也建议这样做),从列“apollowed”中删除两个空值,并用任意值填充空值“Age ”,以便稍后进行转换。

在 Tableau Prep 中复制这些操作简单、直观,只需几次点击。
(“年龄”列的更改是在流程的后期开发的)

在 Python 清理过程的这一点上,我开始分析 Tableau 中的数据集,并根据结果决定对变量应用不同的转换。应该注意的是,从 Tableau Prep 中,我们可以在流程的任何时候加载 Tableau Desktop 中的更改。

第 3 节:列转换

Tableau Desktop 中分析的第一个转换是创建“家庭规模”字段,该字段由“Parch”和“SibSp”字段的总和组成。

要复制 Tableau Prep 中的行为,只需创建一个计算字段,其公式为:

[SibSp] + [Parch]

然后简单地删除菜单中剩余的列。

下一步是提取每个名字的标题。由于乘客的姓名没有给模型添加任何信息,所以我决定提取其头衔(先生、小姐、夫人等。)我们可以更广泛地概括乘客。

这只需要在 Tableau Prep 上点击几下。

然后进行分组,其中只有“主人”、“小姐”、“先生”和“夫人”的称谓保留,其余的归类为“其他”。

对于这种行为,Tableau Prep 提供了几个分组选项(包括按单词相似度甚至发音相似度分组)。

下一个清理步骤可能是最复杂的,在 Tableau Desktop 的支持下,我获得了每个图书的*均年龄,并用该值填充了年龄字段的空记录。

为了在 Tableau Prep 中自动模拟此行为,我需要创建一个具有此*均值的字段(使用 Tableau Prep 聚合过程),然后通过连接过程将其集成到数据集,最后我创建了一个计算字段,该字段复制了“年龄”字段,如果记录为空,则取*均值字段的值。

Section in the flow to complete the nulls in ‘Age’

Agregation and Join steps in Tableau Prep

计算字段中使用的公式为:

IF ISNULL([Age]) THEN
 [Average Age]
ELSE
 [Age]
END

最后,列转换过程以删除带有乘客 ID 和机票号码的字段结束(类似于客舱删除步骤)。

第 4 部分:用于建模的数据集的调整

到目前为止,数据集是完全干净的,可以用于模式分析和报告。可以看出,所有步骤都可以通过一系列点击以最小的努力来执行,Tableau Prep 已经实现了其功能(在使用 Tableau Desktop 创建报告之前清除数据)。此时,您可以添加一个输出过程,该过程会将所有更改应用到数据集,并将结果导出为 CSV 格式或作为 Tableau Desktop 的摘录来创建报告。

然而,为了让数据集准备好训练模型,还需要两个额外的转换(将分类变量转换为 1 和 0 的数字格式,以最终对它们进行规范化)。根据我的经验,我无法在 Tableau Prep 中本地应用这两种转换(或者不需要很多额外的步骤),但是我能够集成一个定制的 Python 脚本来满足我的需要。

在与 Python 的集成中(尽管它也可以与 R 集成),我发现了 Tableau Prep 的最大缺点,也是它真正不足的地方。

首先,对于集成来说,有必要使用配置相当简单的 TabPy 库,可以在这里找到一个博客,它非常有助于理解如何将 Python/R 集成到 Tableau Prep。

[## 在 Tableau 准备流程中引入对定制 R 和 Python 脚本的支持

在本文的示例中,Anton 解释了如何配置 Prep Builder 来运行 Python 脚本,并展示了一些…

www.tableau.com](https://www.tableau.com/about/blog/2019/8/introducing-support-custom-r-and-python-scripts-tableau-prep-flows)

基本上,这是必要的脚本有一个主要功能,将通过参数接收熊猫数据帧,我们必须在它的所有转换。我们将在 Tableau Prep UI 中链接此函数,只需键入其名称。

然而,真正的缺点是,我们必须强制包含 get_output_schema() 函数,该函数将向 Tableau Prep 指示我们的数据集在脚本末尾的结构。这样做的问题是,我们必须几乎手动地创建结构,如果我们的数据集有许多列(超过 20 列就已经不可行了),这将是一项非常繁琐的任务。

为了说明我所说的,我添加了必要的脚本来转换分类变量:

为了应用标准化:

在将这些脚本包含到流中之后,我能够满足我的需求。我甚至可以在任何时候分割流,以生成独立字段 X 的矩阵和包含因变量 y 的列向量。

Final part of the flow

结论

在这个实验结束时,我能得出的最后结论是,尽管 Tableau Prep 对公众开放的时间很短,但它将能够简化许多常见的和一些更复杂的过程,这些过程通常在 ETL 或数据科学项目中完成。具体来说,对于这个项目,在需要使用外部脚本之前,只需很少的努力就可以复制 100 多行代码。

总的来说,Tableau Prep 给人留下了非常好的感觉,它绝对是一个值得在一些行业项目中获得机会的工具。显然,它在什么时候暴露了它的容量不足,以及在使用中可能出现什么问题。

作为最后一个优势,强调将流复制到具有相同结构的数据源是多么简单是很重要的。例如,在 Python 中,如果您想要对测试数据集应用相同的转换,您将需要复制代码并调整变量的名称。在 Tableau Prep 中,简单的复制和粘贴会产生相同的结果。

此外,有趣的是,流可以保存为打包格式,其中包括在任何其他使用 Tableau Prep 的计算机上复制流所需的脚本和文件。

简而言之,这绝对是一个我推荐使用并给它一个机会的工具,我个人很高兴看到它的下一个版本中包含的新特性。

我是谁?

我叫丹尼尔·马丁内斯,是哥伦比亚波哥大 Bera 集团 SAS 公司 Tableau 的首席商务智能顾问。我对机器学习和数据科学充满热情,目前我拥有 Tableau 桌面专家认证,但作为一名顾问,我有大约一年的时间从事仪表板的构建、使用 Tableau 的 BI 解决方案的架构以及 Tableau 服务器的管理。

如果你想联系我,你可以发邮件到我的邮箱【daniel.martinez@bera-group.com 或者在 LinkedIn 上联系我。

[## 丹尼尔·马丁内斯·比洛斯托茨基——Tableau 顾问——Bera Group SAS | LinkedIn

我是诺特大学最后一个学期的本科生,学习数据科学、机器学习…

www.linkedin.com](https://www.linkedin.com/in/daniel-martinez-bielos/)

也可以在我的个人博客中读到更多关于我其他项目的信息。

[## 丹尼尔·马丁内斯

sites.google.com](https://sites.google.com/view/danielmartinezbielos)

如果你想更多地了解我们在 Bera Group SAS 的工作,你可以查阅用西班牙语和 T2 语编写的服务手册。

变装者:为变装女王训练一个变装者

原文:https://towardsdatascience.com/dragface-training-a-gan-for-drag-queen-transformation-7daf1958e517?source=collection_archive---------21-----------------------

用逼真的化妆改变任何自拍

如今,变装皇后在越来越多的人群中变得流行起来。他们在 LGBTQ 群体中也发挥着强大和鼓舞人心的作用。他们通常以出色的表演技巧和奢华的妆容吸引观众。

虽然大多数变装皇后幽默的主持风格和精彩的舞蹈动作很难模仿,但他们复杂的妆容总是更让我惊讶。*均来说,一个专业的变装皇后需要大约 1.5-3 个小时来完成她的化妆。打造拖妆所需的技巧之多,丝毫不亚于油画。我一直在想,如果我和我的朋友们化上男扮女装的妆,他们会是什么样子。

因为我不认识任何化妆师,也负担不起几百美元的预算,所以我求助于机器学习来解决问题。

最*我一直在研究 GANs(生成对抗网络)。它们是一种使用深度学习方法(如卷积神经网络(CNN))进行生成建模的方法。GANs 是一个激动人心且快速变化的领域。最先进的 GANs 能够在一系列问题领域生成逼真的图像,最显著的是在图像到图像的翻译任务中,例如将夏天的照片翻译成冬天的照片或白天到夜晚的照片,以及生成甚至人类都无法辨别的物体、场景和人物的逼真照片。因此,他们是这个项目的完美模特,理想情况下,他们可以将任何正面清晰的照片转换为完整的化妆。如果你有兴趣了解更多关于 GANs 的知识,这里的是一篇很棒的文章,会很有帮助。

项目计划(有我的时间预估):

  1. Web Scrape 拖动皇后和常规自拍图像资产(1 天)
  2. 研究发表的论文并实施最先进的 GAN 算法(1 周)
  3. 为模型培训准备项目数据集(1 天)
  4. 对 GAN 进行项目数据集培训(2 周)

1。网页抓取拖动女王和普通自拍图像资产

为了收集质量好的变装皇后照片和普通自拍照片,我最初的想法是从谷歌图片搜索中刮照片。我写了一个快速的 python scraper 来从 Google 图片搜索中收集拖拉女王的照片。我的目标是 3000 张照片。然而,谷歌图片搜索上的许多图片都有断开的链接,并且在点击通过一定数量的搜索页面后算法停止。我最终只有大约 700 张照片。真扫兴。

一天,当我因为轻微的社交媒体成瘾而滚动浏览我的 Instagram feed 时(2019 问题,我说得对吗?),我突然想到,如果我想要大量高质量的图像数据,在当今世界没有比 Instagram 更好的地方了。因此,我创建了另一个 python scraper,并从 Instagram 图片搜索中收集了使用“变装女王”和“自拍”等标签的变装女王照片和普通自拍。这一次,我在 10 分钟内获得了超过 3000 张变装皇后和普通照片。

2。发表论文研究并实现最先进的 GAN 算法

我在 CNN 和深度学习方面有一些经验,我参加过一个基于 GAN 的 Kaggle 竞赛,它要求参与者使用 GAN 生成小狗照片。为了那场比赛,我训练了 DC 甘、WGAN GP 和 CGAN。训练这些模型并不容易,我一直在努力解决不收敛和生成器梯度减小等问题。

这一次,我决定在开始创建我的模型之前做更多的研究。我最*读了很多关于最先进的 GANs 的论文,特别是那些在涉及人脸的图像翻译任务中取得成功的 GANs。最终, Junho Kim 等人关于 U-GAT-IT 的一篇论文引起了我的注意。他们的 GAN 模型把女生的自拍转化成了具有视觉感染力效果的动漫形象,坦白说和我的项目目标(从自拍到拖)挺像的。

在详细阅读了这篇论文和他们的代码后,我决定尝试实现他们的模型,原因如下:

1.他们论文中最突出的特点是,他们提出了一个自适应层实例归一化(AdaLIN)函数,以自适应地选择实例归一化(IN)和层归一化(LN)之间的适当比例,而不是只使用其中一个。在 GAN 训练期间,如果仅使用 IN,则由于逐通道归一化特征统计,源域的特征将被很好地保留。然而,目标域的翻译量可能不够,因为实例规范化可能无法捕获全局样式。另一方面,如果仅使用 LN,则目标领域风格可能由于逐层标准化的特征统计而被很好地转移。但是源域的特征可能保存得不太好。通过根据源和目标域分布自适应地选择 IN 和 LN 的比率,该模型可以产生更具视觉吸引力的结果。

文章用一个例子说明了这一理论。下图是来自 selfie2anime 模型的对比。(a)中的图像是源文件。(b)使用 AdaLIN 翻译图像。(c)仅使用实例规范化来翻译图像。(d)仅使用图层规范化转换图像。显而易见,( b)具有最吸引人的视觉效果。(c)很好地保留了源图像的细节,如颧骨和面部表情,但没有很好地与动画特征融合。(d)很好地捕捉了动画特征,但是没有从源文件翻译足够的细节。

https://arxiv.org/pdf/1907.10830.pdf

2.本文没有使用基本的最小最大损失函数,而是实现了 4 种不同的损失函数:对抗性损失、循环损失、同一性损失和 CAM 损失。

对抗性损失试图将生成的图像与目标分布相匹配。循环损耗对发电机施加循环一致性约束。它要求生成器将源图像翻译到目标域,然后成功地翻译回源域。这有助于解决模式崩溃问题,这是许多 GAN 模型训练中的一大难题。身份损失有助于确保源图像和目标图像的颜色分布相似。如果在生成器中使用来自目标域的图像来翻译该图像,则该图像不应改变。CAM 损耗有助于发生器和鉴别器了解在这两个域中何处需要改进。

报纸上还有很多我喜欢的其他功能。由于这篇博客的篇幅有限,更多细节请参考论文。

3。为模型训练准备项目数据集

在开始构建模型之前,关键的一步是以正确的格式准备数据。我收集了 3000 张变装皇后的照片和 3000 张自拍,但并不是所有的照片都有清晰的正面,也不是所有的照片都被裁剪得恰到好处,只展示了面部区域。为了准备数据,我利用 Open-CV 的级联分类器,编写了一个 python 脚本来识别数据集中的人脸,并对它们进行裁剪,使人脸位于中间。后来,我手动整理了我的数据集,剔除了质量不好的照片。最后我有了 1000 张拖照和 1000 张自拍。

Training set sample

当我收集普通自拍时,最初我只打算包括男性自拍,因为大多数传统的男扮女装者都是由男性转变而来的。然而,我注意到在我的数据集中有大量女性变形的男扮女装照片。因此,我也在我的数据集中加入了女性自拍。将来探索不同性别对模型结果的影响会很有趣。

另一件引起我注意的事情是,大多数男扮女装的照片都有假发,尽管我试图在最终的照片中只包括脸部。而很多自拍,尤其是男性自拍,都是短发。假发最终在我的模特训练中扮演了一个有趣的角色。我将在第 4 节进一步讨论它。

4。在项目数据集上训练 GAN

4.1 宏伟设计

与任何其他 GAN 类似,我的模型有一个生成器和鉴别器。生成器由编码器、解码器和辅助分类器组成。发电机的设计如下图所示:

https://arxiv.org/pdf/1907.10830.pdf

训练辅助分类器来学习每层特征图的权重,然后用于计算一组领域特定注意特征图。然后,解码器的残差块(AdaLIN)中的参数可以通过全连接层从注意力图中动态计算。

同样,鉴别器也有一个编码器,一个辅助分类器。然而,鉴别器具有分类图像是来自目标域还是由模型生成的分类器,而不是具有带有残余块的解码器。

https://arxiv.org/pdf/1907.10830.pdf

4.1 支付或不支付

大家都喜欢免费的资源,尤其是免费的 GPU。训练机器学习模型可能会很快变得昂贵。尽管 GCP 和 AWS 提供相对便宜的 GPU,但训练一个模型几天就要花费 100 多美元。甘人以训练时间长著称。

幸运的是,我有一个相对较小的数据集。通过在 Google Drive 上安装我的数据集,我能够完全在 Google Colab 上训练我的模型。如果你对机器学习感兴趣,但受限于计算能力,我推荐你去看看 Google Colab。Google Colab 的另一个优点是,你可以从任何机器上登录它。如果你像我一样每天都很忙,它会给你很大的灵活性。

对于这个特定的模型,每次迭代转换一个图像并产生一组发生器和鉴别器损耗值。我的目标是为 300,000 次迭代训练模型,并在此过程中监控结果。在 Colab 上,训练一次迭代大约需要 3 秒钟,这意味着我将不间断地花费大约 250 小时来达到 300,000 次迭代。呃。

但是现在还不要沮丧。有一个巧妙的技巧实际上救了我的命。在 Pytorch 中,下面的代码可以大大提高训练效率:

torch . backends . cud nn . benchmark = True

该标志启用 cudnn 中的基准模式。在基准模式下,如果网络中的输入大小没有变化,cudnn 将为该特定配置寻找一组最佳算法(这需要一些时间)。这通常会导致更快的运行时间,在我的例子中,这将每次迭代的运行时间减少到了 1 秒。耶!

不过,对这一招要半信半疑。如果输入大小在每次迭代中都发生变化,那么 cudnn 将在每次出现新的大小时进行基准测试,这可能会导致运行时性能下降。

4.2 细节决定成败

当我监控模型结果时,我很快意识到一些自拍转换比其他的更糟糕。深入挖掘,问题就显现出来了。这些自拍要么戴着眼镜,要么脸部附*有障碍物。我决定立即停止训练,因为我从经验中了解到,在机器学习中,没有什么比高质量的数据集更重要,无论你的算法有多天才。因此,我仔细地重新扫描了我的数据集,删除了任何不清晰、有眼镜或有障碍物遮挡面部的照片。我还附上了一些额外的照片。

4.3 大损失,小损失

为了确保我的模型训练正确,我收集了每次迭代的发电机损耗和鉴频器损耗,并绘制了它们的趋势。下图显示了直到 295,000 次迭代的对数变换损失值图表。

鉴别器损失相对一致且较小,这意味着鉴别器总是善于分辨哪些拖动图像是真实的,哪些是模型生成的。发电机损耗从大值开始,然后随着训练的进行逐渐降低。在整个训练过程中,发生器和鉴别器损耗值都有恒定的波动性。这种易变性是意料之中的,因为每次迭代只包含一张照片,并且翻译的难度会根据光线、角度和图像质量等条件而有很大变化。因此,不同的输入图像可能具有非常不同的损失值。

4.4 没有照片,就没有真相

跟踪训练进度的另一种方法是简单地查看结果。让我们看看两张示例照片的结果进展。

Original

5,000 iterations after

15,000 iterations after

100,000 iterations after

130,000 iterations after

180,000 iterations after

240,000 iterations after

看起来没那么糟吧!随着训练的进行,模特似乎捕捉到了更突出的化妆特征:大烟熏妆,彩色而光滑的嘴唇,鼻子上的高光,脸颊上的阴影。从 100,000 次迭代开始,翻译的照片已经看起来像专业的拖动图像。随着训练的深入,化妆越来越突出。正是我想要的!

4.5 好的记忆可能不好

就在我准备坐下来放松一下,进一步观看火车模型时,我注意到在翻译图像的面部附*有一些随机的笔画。一开始我以为是因为输入图像质量的问题,但是情况越来越糟。在 130,000 次迭代时,我只能看到一些可能被误认为阴影的光线。在 240,000 次迭代后,它们变成了清晰的波浪形图案,围绕在脸部周围。然后我意识到,这些波浪状的图案实际上是从模型中生成的假发。由于大多数变装照片都有色彩鲜艳的假发,模特也应该逐渐学会在照片上戴假发。

然而,随着模特开始越来越关注假发,翻译后的波浪状图案使照片背景看起来扭曲,视觉吸引力下降。

这可能是阿达林的结果。AdaLIN 帮助模型成功地保留了大量来自源域的面部特征,并与来自目标域的化妆特征融合。然而,对于头发,模型可能应该尽可能多地保留原始特征,以使图像看起来更真实。对于未来的开发,我可以修改模型,以便 AdaLIN 应用实例与图层归一化的比率,该比率随图像上的位置而变化(面部区域使用更多的实例归一化,外部区域使用更多的图层归一化)

表演时间到了!

除了翻译我和我朋友的照片,我还和我的模特一起翻译了一些名人的照片。你能猜出以下哪些名人发布了他们精彩的变装吗?请在你的猜测下面评论他们的名字!(或者更好,也评论一下你认为他们的拖名会是什么!😄)

a

b

c

d

后续步骤和最终反思

总的来说,我花了四周时间完成这个项目,比最初估计的时间多了一周。我从这个项目中学到了很多,总体上对结果很满意。回想起来,这些是我学到的最有价值的东西:

  1. 确实,数据科学家只花 20%的时间在实际数据分析上,80%的时间在寻找、清理和重组数据上。对于这个项目,收集和转换数据的时间比我想象的要长得多。数据集的质量直接关系到结果的质量。在项目开始的时候,我很想直接投入我的数据来训练模型。由于低质量的训练数据,我不得不重新清理我的数据,并从零开始重新训练我的模型,这给了我很大的教训。
  2. 使用各种指标来帮助监控培训过程,包括损失值、分数和目视检查。特别是对于像 GANs 这样的无监督学习任务,您需要选择最适合项目目的的度量标准。
  3. 尽可能利用免费资源。Google Colab 和 Kaggle 都为机器学习项目提供免费的 GPU。我个人更喜欢 Colab,因为你可以在 Colab 中直接安装你的 Google Drive。它在模型训练和结果保留方面提供了很大的灵活性。
  4. 深入了解模型架构。训练机器学习模型是复杂的任务。理解每个模型组件的特征和功能对于理解模型训练行为是必不可少的。

正如我在 4.5 节中提到的,我的下一步是研究如何改善翻译的假发外观。我可能还会收集更多的数据,因为当前的训练集大小仅为每个类 1000 个。我很想知道更多的数据是否会给模型带来更真实的结果。

这个项目的代码可以在我的 GitHub 上找到。看看吧!

如果你喜欢这个,请随时在媒体上关注我,或者在LinkedIn&Twitter上联系我!

在帕洛阿尔托路上的物体周围画一百万个方框

原文:https://towardsdatascience.com/drawing-a-million-boxes-around-objects-on-the-roads-of-palo-alto-cd29a72ee1eb?source=collection_archive---------27-----------------------

为自动驾驶汽车比赛的 Kaggle Lyft 3D 对象检测构建语义点云

介绍

这篇文章详细介绍了我和 Stefano Giomo 参加最*的 Kaggle Lyft 自动驾驶汽车 3D 物体检测比赛时使用的方法(https://www . ka ggle . com/c/3D-object-detection-for-autonomous-vehicles)。

这场比赛使用了 Lyft 车辆捕获的数据,这些车辆配备了多个摄像头和激光雷达传感器。这些车辆在帕洛阿尔托的道路上拍摄了数百个 20 秒的场景。竞赛的目的是围绕这些场景中不同类别的对象放置 3D 包围盒。

我们在数据的 2D 鸟瞰图表示上训练了一个 UNet 模型。2D 表示是通过一系列预处理步骤创建的,这些预处理步骤将每个激光雷达点云与来自相机和帕洛阿尔托街道地图的语义信息相结合。

为了将 2D 预测从模型转换到 3D 包围体,我们执行了许多后处理步骤,包括计算机视觉技术,以及使用激光雷达点云构建地形图。

在获得铜牌的过程中,我们面临了许多挑战。这次比赛的数据集很大,大约 120Gb,存储和处理数据需要很长时间。学习在不同的参考坐标系之间正确转换数据是复杂的,需要小心谨慎。

决定如何组合激光雷达数据和多个相机图像,以及如何将数据转换为神经网络的输入也具有挑战性。在应对这些挑战的过程中,我们学到了很多,并开发了一些有趣的方法,我们认为值得分享。

在这篇文章中,我们总结了我们如何执行预处理步骤来组合不同的数据类型,我们如何创建输入和训练我们的模型,以及我们如何对我们的预测进行后处理以弥补我们模型的一些限制。

数据集

Sensor data from a scene in the Lyft Level 5 data set

比赛数据取自 Lyft 的 Level 5 数据集(【https://level5.lyft.com/】)遵循 nuScenes 数据格式(【https://www.nuscenes.org/】)。数据模式中每个实体的元数据都用 JSON 表示。

Lyft 构建了一个 SDK 来促进数据结构的工作:它允许用户在场景中导航,操纵盒子,可视化传感器数据等等。SDK 的存储库在这里(https://github.com/lyft/nuscenes-devkit ),可以作为 pip 包安装。

场景、样本和传感器

The Lyft vehicle and its sensors

数据由 20 秒长的场景组成。每个场景都由许多样本组成。反过来,样本由同时采集的来自多个传感器的数据组成。每个场景由大约 125 个样本组成。与每个样本相关联的是关于车辆相对于场景的位置以及传感器相对于车辆的位置的信息。该信息允许数据点被合成并正确地放置在场景中。所有车辆都至少有一个激光雷达传感器和六个摄像头。

训练集具有由每个样本中所有感兴趣对象周围的包围体组成的注释。感兴趣的对象分为九类。从柱状图中可以看出,这些类非常不*衡(注意对数刻度)。有 50 多万辆汽车和不到 200 辆急救车辆。

包围体是相对于场景的坐标系定义的。它们*行于 XY *面,并由七个值指定:中心的三个坐标;体积的三维以及围绕垂直轴的旋转角度(偏航)。

Sample from the street map

还提供了一张源自 OpenStreetMap(https://www.openstreetmap.org/)的地图,覆盖的区域包括数据中的所有场景。

训练和测试数据集

训练和测试数据集总共包含超过 350,000 幅图像和* 60,000 个点云。这些数据集总共使用了 120 千兆字节的磁盘空间!

任务和评价标准

这组测试场景没有注释,要求竞争者预测类别,以及场景中每个感兴趣对象周围的包围体(七个值)。

使用*均精度指标对预测进行评分。预测的*均 精度是针对联合(IOU)阈值的交集范围计算的,并且度量是作为这些*均 精度的 M ean 计算的。

*均精度的计算如下。例如,假设 IOU 阈值为 0.6,所有与地面真实量重叠至少 60%的量被认为是命中,而其他的被认为是误报。然后,该阈值的*均精度被计算为命中数除以预测数量。阈值 0.5、0.55、…、0.9、0.95 用于计算*均精度*均值

分割相机图像

Forward facing cameras with semantic segmentation masks

为了利用相机图像中包含的信息,我们创建了每个图像的语义分段,以将语义类与激光雷达点云中的点相关联。我们这样做是为了给我们的网络提供关于每个激光雷达点反射的对象的信息。

我们使用了麻省理工学院计算机科学和人工智能实验室发布的预训练 PyTorch 网络(https://github . com/CSAILVision/semantic-segmentation-py torch)。该模型已在 ADE20K 场景解析数据集(http://groups.csail.mit.edu/vision/datasets/ADE20K/)上进行训练,该数据集包含大量场景,包括美国公共道路的场景,以及 150 类对象的分割基础事实。

我们对测试集和训练集中的每幅图像进行推理,并将结果保存为 GIF 图像以节省磁盘空间。在 150 个类别中,我们根据它们的频率和与竞争的相关性选择了 24 个类别的子集。例如,我们排除了像沙发这样的家庭用品的类别。我们选择了 24 个类来减少表示分类信息所需的嵌入大小。

将类投影到点云

Lyft SDK 提供了在摄像机图像上可视化点云的功能。我们从这段代码中获得灵感来进行相反的操作:将图像和语义数据映射到点云中的点上。

Associating LIDAR points with pixels in a camera image (drawing by Stefano Giomo)

该图显示了我们如何将相机图像和语义图投影到点云中的相关点上。例如,P 是激光雷达点云上的一个点。我们沿着将 P 连接到激光雷达传感器的线将 P 投影到相机图像中,找到 2D 点 Q。我们使用 Q 对语义分割遮罩进行采样,并找到点 P 的语义类

A camera image and semantic classes projected onto the corresponding points in the point cloud

合并来自多个传感器的语义和相机数据

我们为每个样本中的每个图像投影分割类和相机图像数据。结合所有的投影,我们有一个语义点云,其中每个点都有一个相关的语义类标签。

来自相邻摄像机的图像在边缘重叠。对于重叠区域中的激光雷达点,我们定义了一个规则来根据类与属性域的相关性选择最终标注。

Multiple camera images and segmentation classes projected onto the entire LIDAR cloud

上面的可视化显示了以球坐标表示的整个语义点云,其中 x 轴是方位角,y 轴是连接该点和激光雷达传感器的射线的仰角。

鸟瞰模型

我们研究了各种可能的网络架构,包括具有 3D 卷积和区域提议网络的架构。这些模型复杂且计算量大,为了确保我们能够及时提交,我们做出了务实的决定,选择使用 Lyft 团队提供的参考模型作为起点(https://github . com/Lyft/nu scenes-dev kit/blob/master/notebooks/Reference % 20 model . ipynb)。

参考模型基于自上而下(或鸟瞰)的激光雷达点云。想法是将点云体素化,将 Z 维度划分为三个区域,产生三通道 2D 表示。然后,每个体素中的归一化点数被用作像素强度,第一通道被分配给最低 Z 区域,第三通道被分配给最高 Z 区域。鸟瞰图可以像 RGB 图像一样处理。

Original Birds Eye View model input and target data

该模型预测输入图像的每个像素属于十个类别(九个输出类别和一个背景类别)之一的概率。

Example predictions for the class ‘car’

改进鸟瞰模型

Our data preprocessing pipeline to create inputs to the neural network (drawing by Stefano Giomo)

受 PointPillars 论文(【https://arxiv.org/abs/1812.05784】T2)的启发,我们通过使用多种渠道向模型提供更多信息来扩展这个参考模型。

具体来说,我们添加了来自街道地图和语义点云的信息。为了包含语义信息,我们在 Rossmann Store Sales Kaggle 竞赛(【https://arxiv.org/pdf/1604.06737.pdf】T4)的实体嵌入纸的样式中使用了 5 维嵌入。

我们修改了参考模型中使用的 PyTorch UNet 实现,并使用杰瑞米·霍华德的 fastai 库训练它。

Training data for our model

后处理

生成 2D 矩形

一旦我们完成了对测试集的推断,我们就按照参考模型中使用的方法将我们的预测转化为 2D 包围盒。该方法首先对预测进行阈值处理,以获得每个类别的二进制掩码。然后进行侵蚀,接着进行扩张(称为打开)。这消除了二进制掩码中的小伪影。我们找到了每个二进制掩码的轮廓和这些轮廓的最小外接矩形。这些包围矩形是我们包围体的基础。

An example of predictions and extracted contours for class ‘car’

在这个过程完成后,我们有了指定包围体的七个参数中的五个。我们已经计算了 x 和 y 的位置和比例,以及 xy *面上的旋转(或偏航)。我们仍然需要 z 位置和比例(即海拔和高度)。

高度和标高

参考模型使用了一些简化假设,以便将预测的 2D 盒转换成 3D 体积。第一个假设是特定类别的所有对象都具有相同的高度,具体来说,就是训练数据中该类别的*均高度。第二个假设是所有的物体都与装有传感器的车辆(自我车辆)处于相同的高度。

我们试图通过对激光雷达点云进行后处理来改善这两种假设。在这里,我们详细说明了我们是如何改进仰角假设的。

构建地形高程图

Point cloud a scene with a hill, the spikes are roadside trees

我们推断,我们应该能够使用激光雷达点云中的最小高程来找到场景的地面高程。我们将每个场景的所有 125 个可用点云转换到同一个参考坐标系,并将它们合并以构建整个场景的点云视图。我们使用这个组合的点云来构建场景的最小高度或地形图。

Minimum elevation map for a scene with a hill

我们面临的一个问题是,场景中的任何物体,如车辆或行人,都会导致对地面高度的高估。我们通过在空间和时间中取最小高度来避免这个问题。通过在一个物体周围的空间区域中取最小值,我们发现在物体旁边的地面上有更低的点。通过在不同的时间点取最小值,我们找到了任何移动物体离开后的地面。

上面的点云是从包含一座小山的训练集中的场景中获取的。下面的视频显示了这个场景的摄像机和注释。

Youtube video showing a scene with a hill.

在场景开始时,车辆正在下山,后面跟着几辆车。下面的动画对比了放置在与 ego 车辆相同高度的包围体和放置在我们创建的地形地图上的包围体。

Bounding volumes of vehicle on a hill placed at ego vehicle elevation vs at terrain elevation

最初,当车辆下降时,与自我车辆处于同一水*的包围体明显比放置在地形图上的包围体差。然而,随着道路表面变*,差异消失,因此这种技术提高了具有山丘或道路高程中的其他差异的场景的分数。

结论

我们为这次比赛花费的大部分精力都放在输入数据的预处理和预测的后处理上。我们对参考模型进行了两项关键改进。通过将来自相机图像的语义信息投影到点云中,我们将关于对象类别的信息传递给我们的模型。其次,通过构建地形图,我们提高了预测体积的高程精度。

和大多数 Kaggle 竞赛一样,我们在用完创意之前就用完了时间。我们尝试在多个连续样本(扫描)上训练我们的网络,但不太成功,但如果给我们更多时间,我们确信这条路线会给我们带来提升。后来我们意识到,我们应该尝试使用更高分辨率的鸟瞰图像。

如果我们有更多的时间,我们会尝试使用更先进的端到端方法,更好地表示点云和区域建议网络,以获得更好的包围体。我们希望用语义点来扩展 PointPillars 网络,我们也希望在球形映射的语义点云上训练一个模型。

我们将很快为此项目发布我们的 GitHub 资源库。我们正在撰写更多的文章,这些文章将更详细地介绍预处理、后处理和训练网络背后的更多技术元素。

感谢 Stefano Giomo 的精彩画作!感谢你的阅读!

如果你想看看我们从数据集生成的更酷的视频,以及我们的语义分段遮罩,这里有一个 youtube 播放列表:

Playlist of youtube videos generated from the Lyft Level 5 data

绘制架构:在 Pytorch 中构建深度卷积 GAN

原文:https://towardsdatascience.com/drawing-architecure-building-deep-convolutional-gans-in-pytorch-5ed60348d43c?source=collection_archive---------19-----------------------

我不能创造的,我不理解。

理查德·费曼

费曼并没有创造甘的无监督学习或对抗训练,但通过这句话,他确实证明了智力和理解事物的能力不仅仅是一项有监督的、有鉴别能力的任务。为了理解某样东西,你必须做的不仅仅是根据你已经看过一百万次的类似东西给它贴上标签——为了理解你正在看的东西,你必须能够再现它。在深度学习中,创造能力是一般敌对网络与其前辈不同的地方。GAN 是生成输出的生成模型;这背离了标记输入的判别模型。这使得他们成为深度学习和人工智能领域一股强大的范式转变力量,值得严乐存和其他深度学习之父给予的大肆宣传。GAN 的潜力超过了辨别网络,因为 GAN 使用深度学习来合成信息并从中创造出一些新奇的东西。正如费曼所说,这是最有影响力的理解形式。

在这篇文章中,我将介绍如何使用深度卷积 GAN 来创建建筑(建筑物的外部)。我想体验使用和创建不是自动内置的数据集——如 Imagnet 和 MINST——并对其进行微调以创建逼真的外观。我使用的数据集是这里的。我还通过从网上抓取额外的图片来扩充数据集。

什么是 GAN:

一般的对抗性网络是两个相互竞争的神经网络,以产生与输入非常相似的输出。这两个网络——生成器和鉴别器——扮演着对立的角色。生成器网络基于输入图像从随机噪声创建新图像。随机噪声从不相干像素演变成相干图像,其中具有可辨别的形式,这是因为鉴别器告诉它如何改变。鉴别器网络确定图像是真的还是假的。GAN 的目标是使发生器图像与真实图像非常相似,从而能够欺骗鉴别器认为所产生的图像是真实的。GANs 最重要的特征之一是,在 GANs 中实现的神经网络使用的参数数量远远小于用于训练它们的数据量。这迫使模型学习并内化数据中最重要的特征,以便模型可以生成它们。

Vanila GAN Architecture

为了更好地理解这一点,让我们看看 Ian Goodfellow 和他的同事在 2014 年发表原始论文时使用的类比。生成器就像一队伪造者试图创造一个与真画相匹配的输出(输入),而鉴别器就像一队侦探试图确定真实图像和假图像之间的差异。对于算法的每次迭代,生成器永远不会看到原始输入,而是看到潜在的随机变量(基于真实输入图像的视觉噪声)和鉴别器的判断。这个生成器就像一个盲人伪造者,试图通过给她颜料来重现蒙娜丽莎,然后侦探告诉她如何使用它。伪造者画的画在每次迭代后看起来越来越像蒙娜丽莎。

深度卷积 GAN (DCGAN)

普通 GAN 架构功能强大,但这种架构不允许任何真正的空间推理,因为它依赖前馈神经网络而不是卷积神经网络来从图像中提取特征。前馈神经网络不能推理诸如尖锐边缘和突出曲线之类的特征,因为它们不保持图像的空间结构。卷积层保留了图像的空间结构,这意味着将从图像中提取最准确、最详细的特征。这为生成器和鉴别器提供了关于它们将生成的输出以及关于如何区分真实图像中的特征和伪图像中的特征的更高级的空间推理能力。所提取的特征的增强质量通常是在处理图像时使用 DCGAN 的原因。

source

生成器和鉴别器都将是卷积神经网络。鉴别器有一个普通的 CNN 架构,因为它执行的是鉴别、监督的图像分类任务。生成器将具有如下修改的卷积架构:

  • 池化被卷积步幅所取代。这允许网络学习它自己的空间下采样(改变输入的大小)。不需要事先设置。
  • CNN 的结尾没有完全连接的层。生成器不是分类器,因此不需要这一部分。
  • 除了生成器的输出图层和鉴别器的输入图层之外,批处理规范化用于每个图层。这通过标准化激活(先前层具有零均值和单位方差)和梯度的流动来稳定训练过程。在的论文中,结果表明发生器中的输出层和鉴别器中的输入层导致模型不稳定,这就是为什么在那些层中不使用批范数。
  • 在生成器中使用 ReLU,但使用 tanh 的输出除外。双曲正切函数的对称性允许模型更快地学习饱和并覆盖训练分布的颜色空间。

发电机:

发生器接收随机噪声作为输入,并对鉴频器的输出进行采样,以产生图像。这个过程可以被认为是将噪声映射到输入数据分布,以便产生图像。生成器架构是一个经过修改的卷积神经网络,由 ConvTranspose2d 层组成,这些层具有可学习的参数,其余架构如上所述。

nn.Sequential(
 nn.ConvTranspose2d( nz, ngf * 8, 4, 1, 0, bias=False),
 nn.BatchNorm2d(ngf * 8),
 nn.ReLU(True),
 nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False),
 nn.BatchNorm2d(ngf * 4),
 nn.ReLU(True),
 nn.ConvTranspose2d( ngf * 4, ngf * 2, 4, 2, 1, bias=False),
 nn.BatchNorm2d(ngf * 2),
 nn.ReLU(True),
 nn.ConvTranspose2d( ngf * 2, ngf, 4, 2, 1, bias=False),
 nn.BatchNorm2d(ngf),
 nn.ReLU(True),
 nn.ConvTranspose2d( ngf, nc, 4, 2, 1, bias=False),
 nn.Tanh()
 )

随机噪声:

Random Noise

在生成式学习中,机器试图从复杂的概率分布(输入)中生成新的输出。在深度学习中,同样的想法被建模为神经网络——在我们的情况下是卷积神经网络——它将简单的随机变量作为输入,并将遵循目标分布的随机变量作为输出。神经网络能够导出输入概率分布中的等级关系。在这种情况下,这种关系,即随机噪声,是一组类似于真实图像的像素。

在训练循环的第一次迭代中,随机噪声被发送到鉴别器,它确定噪声与真实图像的相似程度。然后,一旦鉴别器告诉它与原始输入的偏差有多大,生成器就会获取该信息并调整噪声,直到它变成类似输入的图像。因此,发电机不会直接与输入一起工作。生成器间接地学习如何将噪声转换成看起来像输入的东西。

fixed_noise = torch.randn(64, nz, 1, 1, device=device)

2D 转置图层

发生器层由 ConvTranspose2d 层组成。这些层将对噪声向量进行上采样,从而将噪声转换为图像。这与反卷积或卷积层不是一回事。卷积层寻求提取越来越小的特征,这些特征稍后将被分类。去卷积层寻求反转卷积层的操作。

2D Transpose Layer

从最简单的意义上说,转置导致至少两个事物相互交换位置。噪声向量和图像空间将彼此交换位置。这意味着我们正在改变它们的维数顺序,因此,我们将交换矩阵中相对于对角线的值。此过程会对最终输出(图像)的细节进行上采样(放大和填充)。这是发生器“绘制”实际图像的部分。

从高层次来看,如果你看架构,这更有意义。我们从噪声矢量开始。这个向量不是图像。噪声是图像的压缩版本。发生器中的 2D 转置层将解压缩噪声,因此它可以成为一个 8x8 的图像,所有细节都在图像的正确位置。这是发电机的最终产品。

2D Transpose Layer

鉴别器

鉴别器得到真实和伪造的图像,它的工作是将它们分类为真实或伪造的。

nn.Sequential(
 nn.Conv2d(nc, ndf, 4, 2, 1, bias=False),
 nn.LeakyReLU(0.2, inplace=True),
 nn.Conv2d(ndf, ndf * 2, 4, 2, 1, bias=False),
 nn.BatchNorm2d(ndf * 2),
 nn.LeakyReLU(0.2, inplace=True),
 nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False),
 nn.BatchNorm2d(ndf * 4),
 nn.LeakyReLU(0.2, inplace=True),
 nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
 nn.BatchNorm2d(ndf * 8),
 nn.LeakyReLU(0.2, inplace=True),
 nn.Conv2d(ndf * 8, 1, 4, 1, 0, bias=False),
 nn.Sigmoid()
 )

体系结构

鉴别器是具有上述结构的卷积神经网络。这为鉴别器提供了空间推理能力,它需要学习哪些精确的空间保留特征使图像真实,然后使用这些空间保留特征将图像分类为真实或虚假。鉴别器不使用与生成器相同的 2D 转置图层,因为鉴别器执行的是监督任务-隔离和提取要素-而不是生成任务-对要在影像中创建的要素进行上采样。

间接培训

鉴别器将向生成器提供信息,因此它将学习如何创建鉴别器在真实图像中发现的真实特征。最终,我们希望生成的图像非常好,以至于鉴别器无法区分真实图像和虚假图像。这意味着我们需要间接训练 DCGAN。DCGAN 中的发生器并不试图精确匹配输入的概率分布,而是该发生器正在创建一个概率分布,它可以欺骗鉴别器网络,使其认为发生器的输出分布来自与真实图像相同的分布。

然后鉴别者会给一幅图像打分,显示它看起来有多像一幅真实或虚假的图像。在训练中,生成器希望让鉴别器给生成的图像打高分,这样鉴别器就会认为假图像是真的。该分数稍后用于学习过程,该学习过程允许生成器在生成图像方面变得更好,并且允许鉴别器在分类图像方面变得更好。

损失函数和学习过程

Training Process

鉴别器

鉴别器输出值 D,该值指示生成的图像与真实图像有多接*。目标是最大化鉴别器将真实图像识别为真实而将生成的图像识别为伪造的机会。交叉熵函数测量该过程的损失 p log(q)。该功能衡量分类模型的性能。这个函数特别适合这个任务,因为预测的概率偏离标签越远,损失就越大。

Discriminator Loss

真实的图像, p 等于 1 它是真实的最大几率。对于生成的图像,我们需要反转标签(减 1)以最小化它是 1 的机会。这是鉴别器的目标函数。

发电机

生成器的目标是创建图像来欺骗鉴别者。这意味着它的目标函数想要鼓励模型创建具有最高可能值 D 的图像来欺骗鉴别者。

Generator Loss

最小最大游戏

GAN 是一种极小极大游戏,其中 G 想要最小化 VD 想要最大化 V。这是一种零和非合作游戏,你的对手想最小化他们的行动,而你想最大化他们的行动;双方都在最大化自己的收益。目标是最小化最大损失(最小化最坏情况)。

Nash Equilibrium source

MinMax 游戏来自博弈论。GANs 被设计成达到一个纳什均衡点,在这个点上每个参与者都不能在不改变其他参与者的参数的情况下降低他们的成本。当鉴别器和发生器达到纳什均衡时,GAN 收敛。这是上面最小最大方程的最优点。纳什均衡点意味着成本降低,没有什么可以改变。生成器能够创建欺骗鉴别器的图像。至此,两个目标都达到了。

有些函数不会收敛。这通常发生在非凸函数中。从博弈论的角度来说,当你的对手总是反对你的行动时,很难让你的模型收敛。这就是为什么甘的训练如此困难的原因。

输出

现在公布结果!最终,在 GPU 上进行了 500 次训练后,结果出来了。这是训练过程的 GIF 图片:

你可以看到从随机像素到像素化图像再到建筑图像的过程。

这些是我最喜欢的(精选的)图片:

I would live there!

并非所有生成的图像看起来都完美。有些有一个扭曲的,变色的,像素化的门面,只有母亲才能爱…

distorted, discolored pixelated images

结论

一般的对抗网络同时处理所有这些领域:无监督学习、博弈论和监督学习。这证明了费曼所说的,为了理解某事,你必须能够创造它。创造本质上是多维的——为了做出新的东西,你必须能够同时理解不止一个想法或功能的交互——当深度学习具有这种能力时,它的能力可能是无限的。这种力量显然伴随着前所未有的责任,但未来无监督学习和特别是生成模型,如甘的模型,具有重新定义深度学习和人工智能的巨大潜力。

点击这里查看整个项目!

[## emilyelia/建筑-DCGAN

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/emilyelia/Architecture-DCGAN)

像机器一样画画和其他人工智能实验

原文:https://towardsdatascience.com/drawing-like-a-machine-and-other-ai-experiments-c121e0904b2c?source=collection_archive---------29-----------------------

Photo by Ms Jemini Photos on Unsplash

你有没有想过“人工智能”这个术语背后隐藏着什么?使用谷歌实验准备的在线应用程序,可以看到“机器学习”给我们带来的可能性。总的来说,是一群设计师和工程师创造有趣的实验,作为引入这些基于谷歌技术的概念的一种方式。有些是可爱快捷的网页游戏,有些更先进,但所有这些都是为了让其他人更容易理解新技术。

1。快,画!

快,画!是一个类似于猜字游戏的网络游戏。不同的是,你不是和你的朋友玩,而是和电脑玩。你有 20 秒的时间根据显示的单词画一幅画,同时人工智能会根据你在屏幕上涂写的所有线条来猜测你在画什么。

Best onion drawing ever

在这个项目的开始,这个模型被故意训练得不完美,所以它会更有趣。用户做出的所有涂鸦都有助于创建一个充满绘画的描述良好的数据集。由于它们,用于建立这个模型的神经网络每天都在学习越来越多的东西。由超过 5000 万张图片组成的数据集在在线可用。它启发了许多研究人员建立新的模型,发表研究论文并进行各种分析,如你在画火烈鸟方面有多糟糕。下面你可以看到人们画长颈鹿的不同方式。

Example of giraffe drawings made by users

这是描述该网站的官方视频:

2。自动绘图

另一个绘图应用程序的例子是 AutoDraw——多亏了这个应用程序,你可以画出你生活中最好的插图。该网站的广告是“为每个人快速绘图”,这是相当准确的描述。你是否曾经计划为聚会制作一份传单,但你缺乏绘画技巧,结果总是使用预先制作的模板?

Here you can see my drawing skills again (or lack of them)

在这个网站上,你可以画出你想要的任何东西,计算机会尽力帮助你完成这项任务。给你的漫画添加更多的细节将会导致计算机方面更准确的预测,如果你对它满意,你可以简单地用 site 提出的图纸交换你的图纸。

AutoDraw 模型是在 Quick,Draw!但是剪贴画本身是由各种插图画家和设计工作室制作的。

AutoDraw 官方视频:

3.可示教机器

在这个网站上,你可以教电脑按照你想要的方式运行。使用您的摄像头,可教机器让您在浏览器中现场教机器,而不需要任何编码经验。这个实验让任何人都更容易开始探索机器学习是如何工作的。

那么,它是如何工作的呢?在屏幕上,你可以看到来自你的相机,三个大按钮和 gif 的饲料。来自相机的图片将成为神经网络算法学习的输入。在做不同的手势时,你必须使用“训练”按钮拍照。对于每一种姿势,你至少需要拍 30 张照片。这三类图片与输出相关联——第一个手势将启用第一个 gif,第二个和第三个是后续的。在训练完你的神经网络后,你可以马上测试它。显示与教导阶段相同的手势将导致输出的改变。

你也可以改变 gif 图片,让网站显示你挑选的图片。除了 gif,你可以得到的另一种类型的输出是声音和语音——你可以选择不是显示猫和兔子,而是与计算机进行对话。向算法提供你的数据和它学习正确分类的整个过程就是机器学习的全部内容。

建立在可教机器之上的应用之一是可教蛇。正如你可能会猜测,这是一个众所周知的蛇游戏,但控制器是你必须使用你的相机显示的迹象。拿一张纸,画一个箭头,告诉蛇它必须去哪里吃掉所有的点!

4.人工智能二重唱

在这个实验中,你可以和机器一起演奏钢琴二重奏。在这里,你可以释放你所有的音乐创造力,并尝试使用你的笔记本电脑键盘和人工智能一起演奏最好的即兴二重奏。A.I. Duet 是一个工具,它通过神经网络运行你弹奏的音符,并试图在这场冒险中陪伴你。神经网络已经用大量的旋律样本进行了训练。在传统的编程方法中,代码需要实现音符、键和定时之间所有可能的连接。人工智能二重奏模型从数据角度创造了旋律的所有规则,并将它们结合在一起,现在它可以生成与你的部分相匹配的全新曲调。

5.乔治·卡姆

这个实验结合了两大机器学习问题——图像识别和语音合成。它始于用户用手机里的相机给他们周围的东西拍照。Giorgio Cam 试图识别该对象,并对其发现的内容进行描述。这段描述后来被改编成了乔治奥·莫洛德尔创作的说唱歌曲的歌词。通过拍摄不同的东西,再加上你的手机,你可以成为一个说唱之王!

摘要

总的来说,上面所有的例子都显示了机器学习是如何工作的——它收集大量的输入,并从中学习来预测一些事情。当越来越多的人使用这些应用程序,并告诉他们什么是对或错时,这些应用程序受益最大。从用户那里收集的正确数据越多,结果就越准确。人工智能还有比敲击相机和用电脑玩哑谜更高级的应用,但这些只是简单的例子,可以向你展示我们从使用算盘计数到现在已经走了多远。

德雷德尔分析公司

原文:https://towardsdatascience.com/dreidel-analytics-moneyball-for-ancient-gambling-5a0142a11097?source=collection_archive---------26-----------------------

Photo by Robert Zunikoff on Unsplash

古代赌博用的钱球

介绍

就像迪斯尼的奥拉夫唱的那样(这些天他差不多一直在我家唱)“现在是一年中的这个时候!”如果你是犹太人,或者你的家庭受到多元文化小学教育的影响,你可能会被劝在这个周末玩一些纸牌游戏。你不能从维基百科学到的是,根据广泛的分析确定,享受德雷德尔的关键是每个玩家只玩 3 个标记。

就我个人而言,我认为你应该完全跳过打陀螺,直接吃马克笔。但也许玩 dreidel 会让你闻到马加比营地的木头烟味和羊肉味,并与一个紧张地争论自己是 T4 自由战士还是激进原教旨主义者的年轻游击战士建立联系。或者也许你会和那些已经开始吃糖果的孩子一起庆祝。

在这种情况下,你需要玩,玩得没有挫败感,这样你就可以回到假期体验中更愉快的部分。控制游戏持续时间是保持游戏乐趣的最容易获得的杠杆,事实证明,游戏长度因玩家可用标记的数量而变化很大。如果你只是想看为什么是 3 个标记而不是 4 个(但愿不会如此),跳过方法部分,直接看结果。如果你想了解内部工作原理,请继续阅读。

方法

让我们模拟游戏来确定开始计数器的数量和完成游戏所需的回合数之间的关系。一路上我们会检查游戏的公*性(剧透警告:维基百科是对的;dreidel 不公*)。

为了在 R 中模拟游戏,我们将构建一个新的类“gameState ”,它将记录 dreidel 任何给定旋转后游戏的状态。这意味着它将跟踪每个玩家的计数器数量、底池中的计数器数量、回合数、下一个轮到的玩家、游戏中的玩家数量以及仍有计数器的玩家数量。我们将使它成为一个类,这样我们就可以创建一个方便的打印方法来改进 gameState 对象的调试和一般可用性。

这相对简单,如下所示:

现在我们已经定义了这个类,我们需要一个基于 dreidel 旋转来更新游戏状态的方法。让我们将传统的{ג,ה、נ,ש的 dreidel 方映射到{4,3,2,1},并使用整数作为输入,看看如何更新当前用户的持有量和底池的值,将回合数加 1,然后重新计算仍在游戏中的玩家人数。如果我们想通过改变底注的值来改变规则,让我们把它作为输入包含到 takeATurn 函数中。

这个函数比我预期的要复杂得多。大部分这些复杂的部分都是为了防止在“真实”游戏中不会发生的极端情况下的无限循环。这可能是一个基本的编程课程,但让我们继续关注如何在不玩太多的情况下玩够 dreidel。

既然我们可以玩一轮德赖德,那么玩德赖德到只剩下一个玩家就很容易了。为了简化我们的模拟调用,让我们制作一个名为 runGame 的新函数,它只是重复旋转一个 dreidel ( ceiling(runif(1,0,4) )调用 takeATurn() ,直到只剩下一个活动玩家,返回最终的游戏状态。为了对模拟结果进行一些分析,runGame 应该将允许创建不同游戏的输入(例如,玩家数量和每个玩家获得的计数器数量)作为输入。

模拟 10,000 个游戏感觉足以理解一个游戏可能要走多少个回合。因为如此多的迭代会花费大量时间,所以我们应该使用 foreach 和 doParallel 包在多个内核上运行这些游戏。这里有一个循环来模拟不同玩家数量和标记起始数量(每个玩家)的游戏:

结果

通过绘制中值回合数与起始代币数的图表,我们可以看出为什么过去所有的德雷德尔游戏都以提前吃掉代币而告终。四个玩家和 10 个标记给出了 400+旋转的*均时间!

但是让我们来看 3 个标记。即使有 10 名球员(当然我们可以做两场 5 人的比赛?)一场比赛的中位数是 300 次旋转。对于一个更典型的 4 人游戏来说,中间时间不到 20 分钟(在我的模拟中是 22 分钟)。每个人旋转 5 次(对于中位游戏),这足以满足每个人旋转 dreidel 的愿望,但不会旋转太多,以至于你必须吃掉所有的标记才能离开游戏。

但是不公*的部分呢?事实证明这相当复杂。似乎每个玩家的标记数量、玩家数量以及哪个玩家具有优势之间存在某种关系。

我们可以专注于首选的起始值 3,而不是理解所有这些,对于玩家数量的所有测试值,模拟结果返回非常接*公*值 1,这让我们感觉很好。

结论

Dreidel 一直坚持不是因为它有趣,而是因为它是传统。鉴于传统在节日期间有着不可避免的重要性,应用一些分析来优化我们如何处理传统是为一年中的那个时间做准备的一个很好的方式

从这个简单的模拟中,我们可以看到,一个不错的每人 5 次旋转的 dreidel 游戏需要比大多数玩家使用的代币少得多的代币(从 3 个开始!).我们还可以看到,如果我们想偷所有的孩子的糖果,我们应该在一大群玩家中玩,先走,使用 2 或 4 个标记。

如果你想运行你自己的 dreidel 模拟,你可以从这里获得本文中使用的全部代码。

我希望你的假期愉快、有趣、没有烦恼。

Keras 中基于自动编码器的服装分割

原文:https://towardsdatascience.com/dress-segmentation-with-autoencoder-in-keras-497cf1fd169a?source=collection_archive---------12-----------------------

从照片中提取服装

Photo by Oladimeji Odunsi on Unsplash

时尚行业是人工智能非常赚钱的领域。数据科学家可以在很多领域开发有趣的用例并提供好处。我已经展示了我对这个领域的兴趣在这里,我开发了一个从 Zalando 在线商店推荐和标记服装的解决方案。

在这篇文章中,我试图进一步开发一个系统,该系统接收原始图像(从网络上获取或用智能手机制作)作为输入,并尝试提取其中显示的服装。请记住,分割的挑战是臭名昭著的极端噪声出现在原始图像;我们试图用聪明的技巧(在预处理期间)开发一个强大的解决方案来处理这个方面。

最后,你也可以尝试将这个解决方案与之前引用的合并。这允许你开发一个系统,通过你外出时拍摄的照片,实时推荐和标记服装。

数据集

最*,一个关于服装视觉分析和分割的 Kaggle 竞赛也启动了。这是一个非常有趣的挑战,但这并不适合我们…我的目标是从照片中提取服装,因此由于其冗余和细粒度的属性,这个数据集是不够的。我们需要包含大部分服装的图像,所以最好的选择是我们自己构建数据。

我从网上收集了一些图片,这些图片包含了在不同场景下穿着不同类型女装的人们。下一步需要创建遮罩:如果我们希望训练一个能够只关注真正感兴趣的点的模型,这对于每个对象分割任务都是必要的。

下面我报告一个数据样本供我们使用。我从网上收集了原始的图片,然后我很享受地进一步剪辑它们,把衣服分开。

Example of image segmentation

我们进行这种区分,是因为我们想在背景、皮肤和着装之间进行区分。背景和皮肤是这类问题中最相关的噪声源,所以我们尽量抑制它们。

有了这些剪报,我们可以重新创建我们的面具如下所示,这是简单的图像二值化。皮肤是因人和服饰的不同而获得的。

Example of masks

最后一步,我们将所有的图像合并成一个三维的图像。这张图片解码了我们感兴趣的原始图像的相关特征。我们的目的是保持背景,皮肤和服装之间的分离:这个结果对我们的范围来说是完美的!

Final mask

我们对数据集中的每一幅图像重复这个过程,以便为每一幅原始图像建立一个相关的三维蒙版。

模型

我们拥有一切来创造我们的模型。我们心目中的工作流程非常简单:

我们拟合一个模型,该模型接收原始图像作为输入,并输出三维掩模,即它能够从原始图像中重建皮肤/背景和服装之间的期望分离。这样,当一个新的 raw 图像进来时,我们可以将其分成三个不同的部分:背景、皮肤和服装。我们只考虑我们感兴趣的通道(服装),用它从输入图像中创建一个蒙版,并剪切它以重新创建原始服装。

由于 UNet 的力量,所有这些魔法都是可能的。这种深度卷积自动编码器通常用于像这样的分割任务。它很容易在 Keras 中复制,我们训练它为我们想要的遮罩的每个通道重建像素。

在开始训练之前,我们决定用它们的 RGB *均值来标准化我们所有的原始图像。

结果和预测

我们注意到,在预测过程中,当我们遇到具有高噪声(就模糊背景或皮肤而言)的图像时,我们的模型开始挣扎。这种不便可以通过简单地增加训练图像的数量来克服。但是我们也发展了一个聪明的捷径来避免这些错误。

我们使用 OpenCV 提供的 GrubCut 算法。该算法利用高斯混合模型实现前景和背景的分离。这对我们很有帮助,因为它有助于指出前景中的人周围去噪。

这里我们实现了一个简单的函数来实现它。我们假设我们感兴趣的人站在图像的中间。

def cut(img): img = cv.resize(img,(224,224))

    mask = np.zeros(img.shape[:2],np.uint8)
    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)
    height, width = img.shape[:2] rect = (50,10,width-100,height-20)
    cv.grabCut(img,mask,rect,bgdModel,fgdModel,5,
               cv.GC_INIT_WITH_RECT)
    mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    img2 = img*mask2[:,:,np.newaxis]
    img2[mask2 == 0] = (255, 255, 255)

    final = np.ones(img.shape,np.uint8)*0 + img2

    return mask, final

GrubCut in action

现在我们应用 UNet,并准备在新图像上看到一些结果!

Input — GrubCut + Prediction — Final Dress

Input — GrubCut + Prediction — Final Dress

Input — GrubCut + Prediction — Final Dress

Input — GrubCut + Prediction — Final Dress

Input — GrubCut + Prediction — Final Dress

我们预处理步骤与 UNet 功能相结合,能够获得更好的性能。

摘要

在这篇文章中,我们开发了一个端到端的服装分割解决方案。为了达到这个目的,我们利用强大的自动编码器结合巧妙的预处理技术。我们计划这个解决方案是为了在真实照片的真实场景中使用它,并有可能在它的基础上建立一个视觉推荐系统。

查看我的 GITHUB 回购

保持联系: Linkedin

卷积层上的丢失很奇怪

原文:https://towardsdatascience.com/dropout-on-convolutional-layers-is-weird-5c6ab14f19b2?source=collection_archive---------3-----------------------

为什么卷积层上的丢失与全连接层上的丢失有根本的不同。

Dropout 常用于正则化深度神经网络;然而,在全连接层上应用丢弃和在卷积层上应用丢弃是根本不同的操作。虽然在深度学习社区中众所周知,当应用于卷积层时,辍学具有有限的好处 ,但我想展示一个简单的数学示例来说明这两者为什么不同。为此,我将定义 dropout 如何在全连接层上操作,定义 dropout 如何在卷积层上操作,并对比这两种操作。

全连接层上的脱落

一个 n 层全连接神经网络(忽略偏差)可以定义为:

其中 ϕᵢ 为非线性(如 ReLU),对于 i ∈{1,…, n }为权重矩阵, x 为输入。

考虑一个单隐层全连接神经网络f(x):ℝ⁹→没有非线性和偏差的ℝ⁹。我们可以将网络表达为:

下面是我们的单隐层神经网络的示意图。

让我们把辍学加入到这个网络中。设 r ∈ {0,1}⁹为独立同分布(iid)伯努利随机变量的向量。在我们之前定义的神经网络中,Dropout 可以表示为:

其中vx已经折叠到 h 为空格。

要了解这如何等价于辍学,考虑具体的情况,其中 r = (1,0,0,…,0)ᵀ.最终的网络是:

这就是最初的辍学论文中讨论的内容。

我们看到,全连接神经网络中的丢失等同于从与全连接层相关联的权重矩阵中清除一列。该操作对应于“丢弃”神经网络中的一个神经元。以这种方式丢弃神经元是合理的,因为定性地说,它促进了权重矩阵中的冗余,即子网络可以稳健地执行所需的操作。

卷积神经网络中的丢失

一个 n 层卷积神经网络(忽略偏差)可以定义为:

其中∫为卷积算子, ϕᵢ 为非线性, Kᵢi ∈{1,…, n }为卷积核, x 为输入。

为了弄清我们的方向,让我们先来研究卷积运算。我们可以将离散卷积重写为矩阵乘法。让我们考虑一下将 x ∈ ℝ ˣ与 K ∈ ℝ ˣ进行卷积。那么Kx定义为:

这在整形操作之前相当于:

既然我们已经确定卷积可以作为矩阵乘法来应用,那么让我们以与我们表述全连接网络大致相同的方式来表述卷积网络。

g(x):ℝˣ→ℝˣ是一个没有非线性和偏差的全卷积神经网络。本着我们之前网络的精神,我们将 g 定义为:

其中 u,v ∈ ℝ ˣ是卷积核, x ∈ ℝ ˣ是图像。

为了简单起见,也因为不影响我们的分析,让【h =vx。注意,为了使变换 g 有效,我们需要在每个卷积层使用零填充。这可以合并到卷积核的矩阵形式中,因此我们的网络可以写成:

其证明留给读者作为练习。

像之前在我们的全连接网络中一样,让我们在卷积网络中加入 dropout。

U 定义为上式中的矩阵(即补零的扩展卷积核)设 r ∈ {0,1}⁹ iid 伯努利随机变量,如前。然后我们有:

为了说明这种压差应用并不等同于全连接情况,只需关注前面所示矩阵左上角的 3 × 3 模块即可:

请注意,权重 u,u,u ₆ 在这个剪切图的三列中至少出现了两次。因此,如果 r ₁ = 0 和 r ₂=1 或 r ₁ = 1 和 r ₂=0,我们仍将更新权重 u ₅和 u ₄(不考虑 r ₃的值!).

结果

在我们对全连接网络中的丢失的分析中,我们表明丢失操作可以理解为在神经网络中将权重矩阵的列清零。这个操作相当于不训练或“放弃”一个神经元。

在上面的分析中,我们已经表明卷积层上的丢失不会产生相同的效果。这由以下事实来证明:将对应于卷积核的权重矩阵的列置零仍然允许训练该列中的权重。

由于 dropout 通常用于在训练期间不随机训练神经元子集,而卷积层上的 dropout 不进行这种操作,因此该名称具有误导性,并且——因为效果不明显可解释——很奇怪。

我并不是说卷积层的丢包没有用。在这些 论文中,作者在卷积层上使用 dropout 时得到了更好的结果。然而,卷积层上的丢失效应似乎相当于将伯努利噪声乘以网络的特征图。我的观点是,在没有更多潜在理论的情况下,选择这种方式将噪声注入系统似乎很奇怪;在全连接层的情况下,哪个的理论。

因此,如果您尝试在卷积层后添加 dropout 并得到不好的结果,不要沮丧!似乎没有很好的理由让提供好的结果。

补充说明

在全连接单隐层神经网络上应用的丢失已经被示出对应于可解释的正则化器,一个均衡权重矩阵的正则化器。然而,这些结果的推导大量利用了矩阵的每个元素的权重彼此独立的事实;这个事实在卷积层中不成立。我没有立即看到如何调和这一事实与卷积层,所以我不明白如何辍学可以提供类似的,可解释的正则化。

基于机器学习的睡意检测

原文:https://towardsdatascience.com/drowsiness-detection-with-machine-learning-765a16ca208a?source=collection_archive---------1-----------------------

我们的团队如何用 Python 构建一个睡意检测系统。

团队成员:格兰特·钟、瑞英、【何】王、奥朗则布·西迪奎、高拉夫·乔德里

简介

“每 25 名成年司机中就有 1 人报告说,他们在过去 30 天里开车时睡着了”

如果你以前开过车,你会在某个时候昏昏欲睡。我们不愿意承认这一点,但这是一个有着严重后果的重要问题,需要加以解决。每 4 起交通事故中就有 1 起是由疲劳驾驶引起的,每 25 名成年司机中就有 1 人报告说他们在过去的 30 天里在开车时睡着了。最可怕的是,昏昏欲睡的驾驶不仅仅是在开车时睡着了。昏昏欲睡的驾驶可能小到当驾驶员没有完全注意道路时的短暂无意识状态。疲劳驾驶每年导致超过 71,000 人受伤,1,500 人死亡,以及 125 亿美元的经济损失。由于这个问题的相关性,我们认为开发一种用于困倦检测的解决方案是重要的,特别是在早期阶段以防止事故。

此外,我们认为困倦也会对人们在工作和课堂环境中产生负面影响。虽然睡眠不足和大学生活是密切相关的,但是在工作场所打瞌睡,尤其是在操作重型机械的时候,可能会导致严重的伤害,就像昏昏欲睡地开车一样。

我们对这个问题的解决方案是建立一个检测系统,识别困倦的关键属性,并在有人昏昏欲睡时及时触发警报。

数据源和预处理

对于我们的训练和测试数据,我们使用了由位于阿灵顿的德克萨斯大学的一个研究小组创建的现实生活困倦数据集,专门用于检测多阶段困倦。最终目标是不仅检测极端和可见的困倦情况,还允许我们的系统检测更柔和的困倦信号。该数据集由 60 名不同参与者约 30 小时的视频组成。从数据集中,我们能够从 22 名参与者的 44 个视频中提取面部标志。这使得我们能够获得足够数量的关于清醒和困倦状态的数据。

对于每个视频,我们使用 OpenCV 从 3 分钟标记开始每秒提取 1 帧,直到视频结束。

import cv2
data = []
labels = []
for j in [60]:
   for i in [10]:
      vidcap = cv2.VideoCapture(‘drive/My Drive/Fold5_part2/’ +     str(j) +’/’ + str(i) + ‘.mp4’)
      sec = 0
      frameRate = 1
      success, image = getFrame(sec)
      count = 0
      while success and count < 240:
         landmarks = extract_face_landmarks(image)
         if sum(sum(landmarks)) != 0:
            count += 1
            data.append(landmarks)
            labels.append([i])
            sec = sec + frameRate
            sec = round(sec, 2)
            success, image = getFrame(sec)
            print(count)
         else:
            sec = sec + frameRate
            sec = round(sec, 2)
            success, image = getFrame(sec)
            print(“not detected”)

每个视频大约 10 分钟长,所以我们从每个视频中提取了大约 240 帧,整个数据集有 10560 帧。

Facial Landmarks from OpenCV

每帧总共有 68 个标志,但是我们决定只保留眼睛和嘴巴的标志(点 37-68)。这些是我们用来提取模型特征的重要数据点。

特征抽出

正如前面简要提到的,基于我们从视频帧中提取的面部标志,我们冒险为我们的分类模型开发合适的特征。虽然我们假设并测试了几个特征,但我们为最终模型总结的四个核心特征是眼睛长宽比、嘴巴长宽比、瞳孔圆形度,最后是嘴巴长宽比超过眼睛长宽比。

眼睛纵横比(耳朵)

耳朵,顾名思义,就是眼睛的长度与眼睛的宽度之比。如下图所示,眼睛的长度是通过*均穿过眼睛的两条不同的垂直线计算的。

Eye Aspect Ratio (EAR)

我们的假设是,当一个人昏昏欲睡时,他们的眼睛可能会变小,他们可能会眨得更多。基于这一假设,如果一个人在连续帧中的眼睛纵横比开始下降,即他们的眼睛开始更加闭合或他们眨眼更快,我们预计我们的模型会将该类预测为困倦。

口长宽比(MAR)

如你所料,MAR 在计算上与耳朵相似,它测量嘴的长度与宽度之比。我们的假设是,当一个人变得昏昏欲睡时,他们很可能会打哈欠,并对自己的嘴巴失去控制,使他们的 MAR 比这种状态下的正常水*高。

Mouth Aspect Ratio (MAR)

瞳孔圆形(PUC)

PUC 是对耳朵的补充,但它更强调瞳孔而不是整个眼睛。

Pupil Circularity

例如,由于分母中的*方项,与眼睛完全睁开的人相比,眼睛半开或几乎闭上的人将具有低得多的瞳孔圆度值。与耳朵类似,预期是当个体昏昏欲睡时,他们的瞳孔圆形度可能下降。

嘴巴长宽比超过眼睛长宽比(MOE)

最后,我们决定添加 MOE 作为另一个特性。MOE 就是 MAR 与 EAR 的比值。

Mouth Over Eye Ratio (MOE)

使用此功能的好处是,如果个体的状态发生变化,EAR 和 MAR 预计会向相反的方向移动。与 EAR 和 MAR 相反,MOE 作为一种测量方法将对这些变化更敏感,因为它将捕捉 EAR 和 MAR 中的细微变化,并将随着分母和分子向相反方向移动而夸大这些变化。因为 MOE 以 MAR 为分子,EAR 为分母,所以我们的理论是,当人昏昏欲睡时,MOE 会增加。

虽然所有这些特征都有直观的意义,但当用我们的分类模型进行测试时,它们在 55%到 60%的准确度范围内产生了较差的结果,对于二进制*衡分类问题来说,这仅是 50%的基线准确度的微小改进。尽管如此,这种失望让我们有了最重要的发现:这些特征没有错,我们只是没有正确地看待它们。

特征标准化

当我们用上面讨论的四个核心特性测试我们的模型时,我们看到了一个令人担忧的模式。每当我们在训练和测试中随机分割帧时,我们的模型将产生高达 70%的准确性结果,但是,每当我们按个体分割帧时(即,测试集中的个体将不在训练集中),我们的模型性能将会很差,正如前面提到的。

这让我们意识到,我们的模型正在与新面孔进行斗争,这种斗争的主要原因是每个人在默认的警报状态下都有不同的核心特征。也就是说,人 A 可能自然地具有比人 B 小得多的眼睛。如果在人 B 上训练模型,则当在人 A 上测试时,该模型将总是预测状态为困倦,因为它将检测到耳朵和 PUC 的下降以及 MOE 的上升,即使人 A 是警觉的。基于这一发现,我们假设将每个人的特征标准化可能会产生更好的结果,事实证明,我们是正确的。

为了归一化每个人的特征,我们取了每个人的警报视频的前三帧,并将它们用作归一化的基线。计算这三个帧的每个特征的*均值和标准偏差,并用于标准化每个参与者的每个特征。从数学上讲,这是归一化方程的样子:

Normalization Method

既然我们已经规范化了四个核心特性中的每一个,我们的特性集就有八个特性,每个核心特性都由它的规范化版本补充。我们测试了模型中的所有八个特性,结果显著改善。

基本分类方法和结果

在我们提取和标准化我们的特征之后,我们希望尝试一系列建模技术,从最基本的分类模型开始,如逻辑回归和朴素贝叶斯,然后转向包含神经网络和其他深度学习方法的更复杂的模型。这里需要注意的是性能和可解释性之间的权衡。虽然我们优先考虑性能最佳的模型,但如果我们要将这一解决方案商业化,并向不熟悉机器学习术语的利益相关者展示其商业含义,可解释性对我们也很重要。为了训练和测试我们的模型,我们将我们的数据集分成分别来自 17 个视频的数据和来自 5 个视频的数据。因此,我们的训练数据集包含 8160 行,测试数据集包含 2400 行。

我们如何将序列引入基本分类方法?

我们在这个项目中面临的一个挑战是,我们试图预测序列中每一帧的标签。虽然像 LSTM 和 RNN 这样的复杂模型可以解释序列数据,但基本的分类模型却不能。

我们处理这个问题的方法是将原始预测结果与前两帧的预测结果进行*均。由于我们的数据集根据个体参与者分为训练和测试,并且数据点都是按时间顺序排列的,因此在这种情况下,*均是有意义的,并允许我们提供更准确的预测。

Introducing Sequence to Basic Classification Models

从我们尝试的不同分类方法来看,K-最*邻(kNN,k = 25)的样本外准确率最高,为 77.21%。朴素贝叶斯表现最差,为 57.75%,我们的结论是,这是因为模型在处理数字数据时遇到了困难。虽然 kNN 产生了最高的准确性,但假阴性率非常高,为 0.42,这意味着有 42%的可能性,实际上昏昏欲睡的人会被我们的系统检测为警觉。为了降低假阴性率,我们将阈值从 0.5 降低到 0.4,这使得我们的模型能够预测更多的困倦情况而不是警觉情况。尽管其他一些模型的精度有所提高,但 kNN 仍然报告了最高的精度,为 76.63% (k = 18),尽管其自身的精度有所下降。

Left: Original Results | Right: Results after lowering threshold from 0.5 -> 0.4

特征重要性

我们想了解特征的重要性,所以我们可视化了随机森林模型的结果。

Feature Importance from Random Forest

归一化后的嘴部长宽比是我们的 8 个特征中最重要的特征。这是有道理的,因为当我们昏昏欲睡时,我们往往会更频繁地打哈欠。标准化我们的特征夸大了这种效应,并使其成为不同参与者嗜睡的更好指标。

卷积神经网络(CNN)

卷积神经网络(CNN)通常用于分析图像数据并将图像映射到输出变量。然而,我们决定建立一个一维 CNN,并发送数字特征作为连续输入数据,以尝试和理解两个状态的每个特征之间的空间关系。我们的 CNN 模型有 5 层,包括 1 个卷积层,1 个展*层,2 个完全连接的密集层,以及输出层之前的 1 个丢弃层。展*层展*卷积层的输出,并在将其传递到第一个密集层之前使其线性。丢弃层从第二密集层随机丢弃 20%的输出节点,以防止我们的模型过度拟合训练数据。最后的密集层有一个输出节点,输出 0 表示警报,输出 1 表示困倦。

CNN Model Design

CNN Parameters

长短期记忆(LSTM)网络

另一种处理顺序数据的方法是使用 LSTM 模型。LSTM 网络是一种特殊的递归神经网络(RNN),能够学习数据的长期依赖性。递归神经网络是反馈神经网络,具有允许信息持续存在的内部存储器。

RNNs 如何在处理新数据的同时拥有内部存储空间?

答案是,在做出决策时,RNNs 不仅考虑当前输入,还考虑它从先前输入中学习到的输出。这也是 RNNs 与其他神经网络的主要区别。在其他神经网络中,输入是相互独立的。在 RNNs 中,输入是相互关联的。公式如下:

RNN formula

我们选择使用 LSTM 网络,因为它允许我们研究长序列,而不必担心传统 rnn 面临的梯度消失问题。在 LSTM 网络中,每个时间步有三个门:遗忘门、输入门和输出门。

LSTM Network Visualized

遗忘门:顾名思义,该门试图“遗忘”之前输出的部分内存。

Forget Gate Formula

输入门:该门决定应该从输入中保留什么,以便修改存储器。

Input Gate Formula

输出门:门通过结合输入和存储器来决定输出是什么。

Output Gate Formula

首先,我们将视频转换成批量数据。然后,使用 sigmoid 激活函数将每一批发送通过具有 1024 个隐藏单元的全连接层。下一层是我们的 LSTM 层,有 512 个隐藏单元,接着是 3 个 FC 层,直到最后的输出层,如下图所示。

LSTM Network Design

LSTM Parameters

在超参数调整后,我们优化的 LSTM 模型实现了 77.08%的总体准确性,与我们的 kNN 模型的假阴性率(0.42)相比,假阴性率低得多,为 0.3。

迁移学习

迁移学习侧重于使用在解决一个问题时获得的知识,并将其应用于解决一个不同但相关的问题。这是一套有用的技术,尤其是在我们训练模型的时间有限或训练神经网络的数据有限的情况下。由于我们正在处理的数据只有很少的独特样本,我们认为这个问题是使用迁移学习的一个很好的候选。我们决定使用的模型是带有 Imagenet 数据集的 VGG16 。

VGG16 是由牛津大学的 K. Simonyan 和 A. Zisserman 在他们的论文“用于大规模图像识别的非常深的卷积网络”中提出的卷积神经网络模型。该模型在 ImageNet 中成功实现了 92.7%的前 5 名测试准确率,ImageNet 是一个包含属于 1000 个类别的超过 1400 万张图像的数据集。

ImageNet 是一个数据集,包含超过 1500 万张带有标签的高分辨率图像,属于大约 22,000 个不同的类别。这些图片是从互联网上收集的,由人类贴标机使用亚马逊的众包工具 Mechanical Turk 进行标记。自 2010 年以来,作为 Pascal 视觉对象挑战赛的一部分,每年都会举办一次名为 ImageNet 大规模视觉识别挑战赛(ILSVRC)的比赛。ILSVRC 使用一个更小的 ImageNet 集,大约有 1000 个图像,每个类别有 1000 个图像。大约有 120 万幅训练图像、50,000 幅验证图像和 150,000 幅测试图像。ImageNet 由不同分辨率的图像组成。因此,图像的分辨率需要更改为 256×256 的固定值。图像被重新缩放和裁剪,中心的 256×256 小块形成最终的图像。

VGG16 Network Architecture

cov1 图层的输入是 224 x 224 RGB 图像。图像通过一叠卷积层,在卷积层中,滤波器的接收域非常小:3×3。在其中一种配置中,该模型还利用 1×1 卷积滤波器,可以将其视为输入通道的线性变换,然后是非线性变换。卷积步距固定为 1 个像素;卷积层输入的空间填充使得卷积后保持空间分辨率,即对于 3×3 卷积层,填充是 1 个像素。空间池由五个最大池层执行,这五个最大池层位于一些卷积层之后。不是所有的 conv。层之后是最大池。最大池在 2×2 像素窗口上执行,步长为 2。

一堆卷积层之后是三个全连接(FC)层:前两层各有 4096 个通道,第三层执行 1000 路 ILSVRC 分类,因此包含 1000 个通道。最后一层是软最大层。全连接层的配置在所有网络中都是相同的。

所有隐藏层都配备了校正(ReLU)非线性。还要注意的是,除了一个以外,没有一个网络包含局部响应归一化(LRN),因为这种归一化不会改善模型的性能,而是导致计算时间增加。

我们将训练视频分成 34,000 个图像,这些图像是每 10 帧拍摄的截图。我们将这些图像输入 VGG16 模型。我们相信图像的数量足以训练预训练的模型。在对模型进行 50 个时期的训练后,我们得到了以下准确度分数。我们的结果如下所示。

VGG16 Results

很明显,这个模型是过度拟合的。对此的一个可能的解释是,我们通过模型传递的图像是 22 名受访者几乎一动不动地坐在背景不受干扰的摄像机前。因此,尽管我们的模型采用了大量的帧(34,000),但该模型本质上是试图从 22 组几乎相同的图像中学习。因此,该模型实际上没有足够的训练数据。

结论

在这个项目中,我们学到了很多东西。首先,在完成任务时,简单的模型和复杂的模型一样有效。在我们的例子中,K-最*邻模型给出了与 LSTM 模型相似的精确度。然而,因为我们不希望将昏昏欲睡的人错误分类为警觉,所以最终最好使用假阴性率更低的更复杂的模型,而不是部署起来可能更便宜的更简单的模型。第二,正常化对我们的表现至关重要。我们认识到每个人的眼睛和嘴巴长宽比都有不同的基线,对每个参与者进行标准化是必要的。在我们模型的运行时间之外,数据预处理和特征提取/标准化占用了我们大量的时间。更新我们的项目并研究如何降低 kNN 和其他更简单模型的假阴性率将会很有趣。

未来范围

展望未来,我们可以做一些事情来进一步改善我们的结果和微调模型。首先,我们需要合并面部标志之间的距离,以说明视频中对象的任何移动。实际上,参与者在屏幕上不会是静止的,我们认为参与者的突然移动可能是困倦或从微睡眠中醒来的信号。其次,我们希望用更复杂的模型(神经网络、集成等)更新参数。)才能达到更好的效果。第三,也是最后一点,我们希望从更大的参与者样本中收集我们自己的训练数据(更多数据!!!)同时包括新的明显的困倦信号,如突然的头部运动、手部运动或者甚至跟踪眼睛运动。

产品预览

我们想包括一些我们的系统在运行中的截图!

首先,我们需要根据参与者校准系统,如下所示。

System Calibration

现在,系统应该自动检测参与者是困倦还是警觉。示例如下所示。

Drowsiness Detection System Example

非常感谢您通读我们的整个博客!如有任何问题或建议,请随时联系 LinkedIn 上的任何人,以改进我们的系统。

完整的项目和代码可以在 GitHub 上查看!

承认

我们要特别感谢 Joydeep Ghosh 博士,他在整个项目中提供了非常有价值的指导。

参考

[## UTA-RLDD

德克萨斯大学阿灵顿分校的现实生活困倦数据集(UTA-RLDD)是为多阶段…

sites.google.com](https://sites.google.com/view/utarldd/home)

https://arxiv.org/abs/1904.07312

【https://pypi.org/project/opencv-python/

https://towards data science . com/understanding-rnn-and-lstm-f 7 CDF 6 DFC 14 e

https://neurohive.io/en/popular-networks/vgg16/

[## ImageNet

ImageNet 是一个根据 WordNet 层次结构(目前只有名词)组织的图像数据库,其中每个…

www.image-net.org](http://www.image-net.org/)

来自潜在空间的鼓形图案

原文:https://towardsdatascience.com/drum-patterns-from-latent-space-23d59dd9d827?source=collection_archive---------11-----------------------

打击乐节拍以及在哪里可以找到它们

TL;DR: 我收集了一个大型的鼓模式数据集,然后使用神经网络方法将它们映射到一个潜在的可探索空间,其中有一些可识别的流派区域。试试互动探索工具或者下载几千个独特生成的节拍。

背景概述

*年来,有许多项目致力于神经网络生成的音乐(包括鼓模式)。一些这样项目使用一个潜在空间的显式结构,其中每个点对应一个旋律。这个空间可以用来研究和分类音乐结构,以及产生具有特定特征的新旋律。有些人使用不太复杂的技术,如“语言模型”方法。然而,我无法找到映射到 2D 空间的典型节拍模式的整体表示,所以我决定自己创建一个。

下面,我列出了我在开始自己的工作之前设法找到并分析的相关项目:

  • LSTMetallica —作者使用语言模型方法来预测节拍中的下一步。
  • neuralbeats —另一个语言模型项目,与 LSTMetallica 非常相似。
  • Magenta VAE——谷歌的 Magenta 是音乐生成和增强的有趣模型和项目的伟大来源。特别是 2016 年他们发布了 drum_rnn 型号,2018 年 3 月又发布了 music_vae 型号。从那以后,很多项目都使用了这些模型。
  • 例如,去年 Tero Parviainen 基于 drum _ rnn+magenta . js+tensor flow . js+tone . js 创建了一个非常棒的在线鼓点发生器
  • Beat Blender 是另一个基于 Magenta 的项目(在 NIPS 2017 上首次亮相)。这与我想做的非常相似,然而,作者没有建立不同流派的概览图,而只是在成对的模式之间建立了一个插值空间。
  • 最后但同样重要的是,还有我的另一个项目,神经网络 RaspberryPi 音乐盒,它使用 VAE 空间生成源源不断的类似钢琴的音乐。

数据集构建

我发现的大多数项目都使用手动选择和清理的节拍模式的小数据集,例如 GrooveMonkee free loop pack 、 free drum loops collection 或AQ-Hip-Hop-Beats-60–110-BPM。

这对我的目标来说还不够,所以我决定从网上的大量 MIDI 收藏中自动提取节拍模式。我总共收集了大约 200K 的 MIDI 文件,然后只保留了那些具有非*凡的第 9 通道(根据 MIDI 标准的打击乐器通道)的文件,所以还剩下大约 90K 的轨道。接下来,我做了一些额外的过滤,基本上与 neuralbeats 和 LSTMetallica 项目中实现的方式相同(我使用了 4/4 拍号,并对乐器子集进行了量化和简化)。

然后,我根据长时间的停顿将曲目分成独立的块,并搜索连续重复至少 3 次的长度为 32 步的模式——为了加快过程,我使用了哈希和一些简单的贪婪试探法。最后,我丢弃了熵值太低的琐碎模式,并检查了每个模式在所有可能的相移中的唯一性。最终,我的收藏中有 33K 个独特的图案。

some examples of distilled patterns

我使用了一个简单的方案来编码每个模式:一个模式有 32 个时间刻度,有 14 种可能的打击乐器(经过简化),所以每个模式可以用 32 个整数来描述,范围从 0 到 16383。

您可以在此下载 TSV 格式的数据集:

  • 第一列保存模式代码(32 个逗号分隔的整数)。
  • 第二列是这个模式在潜在 4D 空间中的点(4 个逗号分隔的浮点值),见下面的细节
  • 第三列是从潜在空间到 2D 投影的 t-SNE 映射(2 个逗号分隔的浮点值),详见下文

神经网络

我使用 pytorch 框架构建了一个网络,其中有一个 3 层 FCN 编码器,将节拍矩阵(32*14 位)映射到 4D 潜在空间,还有一个与编码器大小相同的解码器。第一个隐藏层有 64 个神经元,第二个有— 32 个。我在层间使用 ReLU 和一个 sigmoid 将解码器输出映射回位掩码。

我尝试并比较了两种不同的潜在空间*滑技术, VAE 和 ACAI :

  • 标准 VAE 产生了足够好的结果,空间映射清晰而有意义,
  • ACAI 空间看起来*滑得多——它更难可视化,但更好取样(见下面的细节)。

The METAL beats area on the VAE space projection (left) and the ACAI space projection (right)

鼓代

我用标准逻辑生成了一个随机节拍:从潜在空间中随机抽取一个点,然后用解码器将这个点转换成节拍模式。你也可以从潜在空间的特定区域采样点,以获得该区域特定风格的典型节拍。使用我用来构建数据集的同一套过滤器对产生的模式进行了过滤(参见上面的详细信息)。

VAE 生成的节拍质量约为 17%,换句话说,*均六分之一的生成节拍成功通过了过滤器。在 ACAI 的例子中,质量明显更高——大约 56%,所以超过一半的生成模式通过了过滤器。

我使用每种方法生成了 10K 节拍并发布了它们(格式类似于主数据集文件格式):

  • sampled10k_vae_raw ,
  • sampled10k_acai_raw ,
  • 样本 d10k_vae_filtered ,
  • 样本 d10k_acai_filtered 。

也可以下载这些生成的图案制作的 MIDI 包: sampled_vae_midi.zip 和 sampled_acai_midi.zip 。

空间可视化

我使用 VAE 空间进行可视化,因为它有更清晰的视觉结构。基于该空间的 t-SNE 投影来放置点。一些最初收集的 MIDIs 在文件名中有流派标签,所以我用这些来定位和标记具有特定流派的模式的区域。

我基于 jQuery 、 remodal 和 MIDI.js (带有一个重新编码的 GM1 打击乐声音字体)库构建了可视化器。您可以探索训练集模式的 3K 子集(灰点)+大约。500 个生成的图案(红点)。

试试这里的

决斗深度 Q 网络

原文:https://towardsdatascience.com/dueling-deep-q-networks-81ffab672751?source=collection_archive---------4-----------------------

DQN 家族

用于深度强化学习的决斗网络架构

回顾和介绍

让我们先回顾一下一些重要的定义,然后再看 DQN 论文。这些大部分应该都不陌生。

  • 给定代理的策略π,动作值和状态值分别定义为:

  • 上面的 Q 函数也可以写成:

  • 优势是通过用 V 值减去 Q 值获得的量:

回想一下,Q 值表示在给定状态下选择特定动作的值,V 值表示不管采取什么动作都给定状态的值。然后,直观地,优势值显示了在给定状态下选择一个动作相对于其他动作有多有利。

什么变化和动机

  • (王等)提出了新颖的决斗架构,它通过两个独立的流明确地分离了状态值和依赖于状态的动作优势的表示。
  • 这种架构背后的关键动机是,对于一些游戏来说,没有必要知道每个动作在每个时间步的值。作者举了一个 Atari 游戏 Enduro 的例子,在这个游戏中,在碰撞即将发生之前,不需要知道应该采取什么行动。

Atari Enduro. Source: https://gfycat.com/clumsypaleimpala

  • 通过显式分离两个估计器,决斗架构可以了解哪些状态是(或不是)有价值的,而不必了解每个状态的每个动作的效果。就像 Enduro 的例子一样,这种架构在一些任务中变得尤其重要,在这些任务中,行动可能并不总是以有意义的方式影响环境。

体系结构

像标准的 DQN 架构一样,我们有卷积层来处理游戏帧。从那里,我们将网络分成两个独立的流,一个用于估计状态值,另一个用于估计依赖于状态的动作优势。在这两个流之后,网络的最后一个模块组合状态值和优势输出。

Dueling Architecture, Source: https://www.freecodecamp.org/news/improvements-in-deep-q-learning-dueling-double-dqn-prioritized-experience-replay-and-fixed-58b130cc5682/

现在,我们如何组合/聚合这两个值呢?

将两个值相加似乎很直观,从优势值的定义中可以立即看出:

然而,作者提出了关于该方法的两个问题:

  1. 假设和分别给出状态值和动作优势的合理估计是有问题的。因此,天真地将这两个值相加是有问题的。
  2. 两者的简单和是“不可识别的”,因为给定 Q 值,我们不能唯一地恢复 V 和 A。Wang 等人的实验表明,这种可识别性的缺乏会导致较差的实际性能。

因此,神经网络的最后一个模块实现了如下所示的正向映射:

这将迫使最大化动作的 Q 值等于 V,解决了可识别性问题。

或者,如在王等人的实验中所使用的,我们也可以使用:

然后,我们根据以下因素选择最佳行动a*:

培养

因为决斗架构与标准 DQN 架构共享相同的输入输出接口,所以训练过程是相同的。我们将模型的损失定义为均方误差:

并采取梯度下降步骤来更新我们的模型参数。

履行

所以,我们将通过决斗 DQN 的实施。

1.网络架构:如上所述,我们希望将状态相关的动作优势和状态值分成两个独立的流。如上所述,我们还使用正向映射来定义网络的正向传递:

2.接下来,我们将实现更新功能:

除此之外,标准的 DQN 建筑没有什么变化;关于完整的实现,请查看我的香草 DQN 邮报,或者我的 Github 库:

[## cy oon 1729/深度 Q 网络

Q-learning 家族(PyTorch)算法的模块化实现。实现包括:DQN,DDQN,决斗…

github.com](https://github.com/cyoon1729/deep-Q-networks)

参考

  • 深度强化学习的决斗网络架构(王等,2015)

地下城和骰子

原文:https://towardsdatascience.com/dungeons-and-dice-8e326a6fcae4?source=collection_archive---------44-----------------------

桌面角色扮演游戏中随机性、多武装匪徒和数字表征的思考

Images from Pixabay and https://www.flickr.com/photos/lobsterstew/5508435832

你经常会发现自己和一些好伙伴在一起,并准备好和一些兽人(或者人类,无论你喜欢哪个)战斗,但是,唉,你没有骰子。

通常这个问题会因为不仅需要 6 面模具 D6 ,而且需要所有剩余的柏拉图立体D4D8D12****D20而变得更加严重。D10 有时也被卷入其中。我见过很多解决这个问题的方法,从在纸上写数字然后从盒子里画出来,到地下城主编数字。前者的问题是需要更多可能不在身边的材料,后者是全球机制可能有偏见。

也许他/她希望冒险者成功,或者相反不要太快杀死那个超级酷的怪物。尽管转基因并不意味着它会发生,但一些偏见可能会在潜意识中潜入,破坏所需的随机性。你会接受你的角色因为总经理在激烈的战斗中脱口而出错误的数字而被杀死吗?

一个解决方案是让其中一个玩家在总经理说一的同时说一个数字,然后将他们按骰子大小相加(并加一)。

Adding modulo D12 is similar to adding hours on a clock. For example 9+5 mod 12 = 2. Image from pixabay.

但是这真的是一个好的解决方案吗?我们怎么知道它是不是呢?进入伪随机数发生器(PRNGs)的理论。

伪随机数发生器

产生随机性的问题是一个古老的问题。1946 年,约翰·冯·诺依曼在研究原子弹时发现自己需要大量的随机数来进行蒙特卡罗模拟。在蒙特卡罗方法中,人们利用随机性来进行计算。最简单的例子是在正方形内画一个四分之一圆。把沙粒随意扔向图画。计算圆内的颗粒数,除以总数,乘以 4,瞧,你已经用蒙特卡罗方法计算出圆周率了。

seq = [random.randint(0,100) for x in range(200)]
rand_coords = list(zip(seq[::2], seq[1::2]))sum(1 if math.sqrt(x**2+y**2)<=100 else 0 for x,y in rand_coords)*4/len(rand_coords)

200 grains of sand. Pi = 3.24 in this calculation. More grains makes it more exact.

冯·诺依曼在他的工作中发明了中间的*方方法,可以表述为:取一个种子,比方说 4 位数长,*方它,提取中间的 4 位数,它就成为下一个种子。例如:

8524 -> 72658576 -> 6585 -> 43362225 -> 3622

看起来很随意,但是真的吗?序列 777777 是随机的吗?它在 10⁶发生的几率是 1,但另一方面,758336 也是如此。

检查随机性是一个重要的问题,为此已经设计了许多方法。我们将看看其中的一些。

视觉分析

检查某件事是否不是随机的一种方法是寻找模式。事实证明,人类的视觉皮层在这方面相当擅长,让我们画一个中间的正方形序列:

def plot_rand(seq):
    dim = int((seq.size)**(1/2))
    seq = seq[:(dim**2)].reshape(dim, dim)
    plt.imshow(seq)

正如你所看到的,它开始时很好,但是过了一会儿就陷入了一个循环。冯·诺依曼知道这可能发生,但他没有其他方法可以快速产生大量的伪随机数。他说,当它陷入循环时,它至少会以一种明显的方式失败。

让我们试试另一个:

plot_rand([(x**2-3*x)%10 for x in range(300)])

似乎我们已经找到了抽象艺术的一个很好的来源。当然,由于剩余力量的周期性,我们相当有限。

后来,比中间正方形更好的方法被发明了,但是领域被问题困扰。一个例子是 IBMs 杜然算法。乍一看,它似乎能产生很好的随机数,但这是一种错觉。事实上,情况非常糟糕,以至于唐纳德·克努特(Donald Knuth)将它描述为“真正可怕的”,由于 20 世纪 70 年代初杜然的广泛使用,当时的许多结果被视为可疑。

另一个例子是 PHP rand()。

Image from random.org

拥有糟糕的随机数生成器可能会产生一些非常可怕的后果,因为它们被用于为 SSL 协议生成密钥。能够猜出生成器将要产生的下一个数字的攻击者将能够解密所发送的消息。

但是上面描述的让两个人同时说出数字的方法效果如何呢?

对我来说很随机,第一次测试通过了。

科尔莫戈罗夫

看待随机性的另一种方式是它很难描述,而有序却很容易描述。

因此100011010111100101110看起来比11111111100000000更随机,因为后者可以描述为 [1]10 + [0]10 ,但前者更难找到压缩形式。

这是安德雷·柯尔莫哥洛夫的想法,为了纪念他,这个概念被命名为 Kolmogorov 复杂性。

让我们尝试以上述方式压缩我们的序列。

def compress(string):
    return ''.join((char + str(sum(1 for _ in group)).replace('1','')) for char, group in groupby(string))

*在上面的代码中,我们只处理了最简单的一个字符的情况,因此例如 10101010 不会被该算法压缩。更好的压缩算法留给读者作为练习。

400 的 radom.randint()被压缩到 395,而两人的数字得到 390。够接*了,第二次测试通过。

卡方检验

卡方检验是一种确定拟合优度的方法。即:零假设符合观察到的行为的概率是多少。如果我随机选择一串数字 0-9,我的无效假设是每个数字都以 10%的频率出现。

让我们把我们的序列放入卡方检验。

chisquare([v/len(seq) for k,v in Counter(seq).items()], [.1]*10)

random.randint()得出的卡方值为 0.03。我通过捣碎按钮生成的随机序列 ges a 0.12,所以不完全随机。来自两个按钮捣碎序列的序列得到了 0.04,我认为这是非常好的。每第五个位置有“1”的随机序列得到 0.38。

但这里感兴趣的不仅仅是数字的分布。我们还对二元组感兴趣,那就是:两个连续的数字。数字 1-9 可能以均匀分布的方式出现,但也许两个数字“29”比“23”出现得更频繁,因为我在生成数字时使用两只手,并且倾向于在它们之间交替。三元组和更高的也可以尝试。

当用二元模型测试时,random.randint()得到 0.2,我的按钮 mashing 得到 1.28,我们添加的序列得到 0.34,每第 5 个位置有“1”的随机序列得到 4.45。

不完美,但足够接*,第三次测试通过。

圆周率

我们当然可以使用上面描述的蒙特卡罗方法,但是要反过来。因为我们知道圆周率应该是多少,PRNG 越接*越好。

我们得到 2.96。不完全是圆周率,但其中一个原因是我们只有整数 0-9。在这种情况下,random.randint(0,9)得出 2.9。

第四次测试通过。

顽固的测试

顽固测试是 1995 年在随机数字光盘上首次发现的一系列测试。它们对 10000 长的随机序列效果更好,这里就不用了。

多股武装匪徒

A multi-armed bandit situation. From https://www.inverse.com/article/13762-how-the-multi-armed-bandit-determines-what-ads-and-stories-you-see-online

虽然这一切看起来都很好,但可能仍然有一个小问题。聪明的玩家会注意到 GM 生成的数字不是随机的,而是遵循一种模式,一种可能被滥用的模式。

除了听起来像是角色扮演游戏冒险中的人物之外,一个多臂强盗实际上是强化学习中的一个问题。假设你有一个吃角子老丨虎丨机,又名单臂强盗,但这个有几个手臂。他们都有不同的支付率,你不知道。你必须一边走一边想办法,同时努力实现利润最大化。像往常一样,在强化学习中,当你做出正确的决定时,你通过获得奖励来学习该做什么。

这个概念的一个延伸是上下文多武装匪徒(CMAB)问题,其中你也看上下文,例如一天中的时间。

让我们使用上下文强盗库将我们的情况建模为一个 CMAB。上下文是以前的数字,每当我们的算法选择一个高于*均值的数字,它就会得到奖励。我们的特定算法是 Bootstrapped Thompson 采样,这是一种使用 Beta 分布确定每个动作正确的概率的算法。

def run_bandit(seq, nchoices, reward_func):
    base_algorithm = LogisticRegression(random_state=123, 
                                        solver='lbfgs')
    beta_prior = ((3, 7), 2) model = BootstrappedTS(deepcopy(base_algorithm), 
                           nchoices = nchoices, 
                           beta_prior=beta_prior) r_hist = []
    a_hist = []
    X_hist = [] model.fit(X=np.array([[0]]), a=np.array([0]), 
              r=np.array([0])) for X,y in ngram(seq, 2):
        a = model.predict(np.array([[int(X)]]))[0]
        a_hist.append(a)
        X_hist.append([int(X)])
        r = reward_func(a,y)
        r_hist.append(r)
        model.fit(X=np.array(X_hist), a=np.array(a_hist), 
                  r=np.array(r_hist))

    return r_hist np.mean(run_bandit([random.randint(0,9) for x in range(200)], 10, lambda a,y: 1 if (a+int(y))%10 >= 5 else 0))

结果是:

对于 random.randint(),该算法*均获得 0.51 分

对于 GM 生成的序列,该算法*均得到 0.63 分。

可以看出,该算法实际上学会了滥用由 GM 创建的序列中的规则。

奖励 1:石头剪刀布

同样的方法也可以用来赢得石头剪刀布,顺便说一下,只要使用 nchoices=3 和不同的奖励函数。尝试:

np.mean(run_bandit(sequence, 3, lambda a,y: 1 if int(a) == (int(y)+1)%3 else 0))

虽然这看起来很糟糕,但人们必须记住,人类不是计算机。人类不太可能像我们的算法那样利用序列中的小规律。

我们通过了吗?我想应该由你来决定。你的角色扮演聚会包括雨人或者有类似能力的人吗?如果不是,我会说这是一个通行证。

额外收获 2:数字的表示

一个并非完全无关的问题是向总经理传达数字。通常的情况是,在 GM 掷出骰子后,他/她想要知道例如一个玩家的能力分数,而其他玩家听不到。这可以通过用手指显示一个数字来实现,但是通常的方法只能显示 0-10 的数字,而能力分数通常是 18。

解决这个问题的一种方法是使用基数 6,一只手是第一阶,另一只手是第二阶。这样,一个人可以从 0 一直走到 35。如果这还不够,你可以使用二进制来得到 1023,尽管你需要相当灵活的手指。

如果具体范围接* 1–110,中文数字手势似乎是一个很好的选择。特别是因为我们的数字系统是以 10 为基数的,这使得这些手势更容易理解。

结论

玩基于随机性的游戏时没有骰子是一个不容易解决的问题,事实上,即使知道你是否解决了它也是一个困难的问题。幸运的是,即使它并不完美,让 GM 和玩家同时喊出数字对大多数情况来说似乎已经足够了。

DxR:将 2D 数据可视化连接到沉浸式空间

原文:https://towardsdatascience.com/dxr-bridging-2d-data-visualization-into-immersive-spaces-d77a20d5f9e9?source=collection_archive---------10-----------------------

(with permission from ShutterStock #616733024)

在 IEEE VIS 2018 上,来自不同大学的研究人员提交了一篇论文,描述了一种用于快速部署沉浸式数据可视化的新工具包,称为 DxR ( D 数据可视化在 mi X ed R eality)。[1]

本文代表了将几个技术集群合并到一个集成开发环境中的重大努力。这跨越了带有 Unity3D 场景的 JSON Vega 可视化设计,支持商业 VR 产品,如 Oculus Rift 、 HTC Vive 和微软 Hololens (中等价位的 VR 头戴设备)。

科罗拉多大学博尔德分校教授丹妮尔·萨菲尔的一篇文章引起了我的注意。她总结了几个数据可视化项目,并将 DxR 的重要性描述如下:

“虽然我们对 MR(混合现实)在可视化方面的效用的理解仍然有限,但 DxR 等工具可以帮助加快这一领域的发展。通过使构建和部署沉浸式可视化更容易,我们可以更好地理解这些显示技术在什么时候以及为什么对数据分析有用。这些工具对怀疑者和支持者都有帮助,允许他们构建新的应用程序,并快速进行研究,以测试沉浸式可视化可能提供的限制。”2

她总结说,更多的混合现实可视化实验对于“准确理解何时以及为什么”它们是有用的,以及它们的限制。

正如 Szafir 的文章所指出的,高级数据可视化是许多业务应用程序的关键要素。使用最新显示技术的压力(由视频游戏行业驱动)正朝着 中描述的超越桌面的视觉化——下一件大事 发展。作者调查了虚拟现实在几种应用和技术中的潜力,总结如下:

“可视化研究人员需要开发和适应今天的新设备和明天的技术。今天,人们通过鼠标与视觉描绘互动。明天,他们将触摸、滑动、抓取、感觉、听到、闻到甚至品尝数据。”[3]

手脏

先玩玩看 DxR 工具包的表现是否如宣传的那样…

首先,阅读DxR 论文 !如果你对可视化语法和 Unity3D 开发有所了解的话,这篇文章写得很好,也很容易理解。

https://sites.google.com/view/dxr-vis/home

二、进入 DxR 网站 查看 5 分钟视频,简洁明了。花时间浏览 Vega-Lite 网站并滚动浏览众多示例(注意左边的 Vega vis 规范)。这是相当多的使用案例!

这为 DxR 引入沉浸式空间的功能增添了一份风味。

第三,执行代码,如下所示:

  1. 点击下载 DxR 的链接,下载 UnityPackage 文件。选择最新版本。另存为文件;这不是 GZ。该文件稍后将被导入到您的 Unity 项目中。此外,确保你的 Unity 版本匹配,因为奇怪的事情可能会发生。使用新的 Unity Hub 管理您的所有 Unity 版本,或者只安装一个新的 Unity 版本。
  2. 点击快速入门指南和通读概述。理解 Unity 场景中的 Vega-Lite 示例。
  3. 重点介绍 中的五个步骤设置**** 部分,这是大部分的工作。注意:你需要新手熟悉 Unity3D 来创建一个新的 Unity 项目,导入 Unity 资源包,了解层级、项目和检查器面板,玩 Unity 场景。如果需要帮助,可以查看 Unity3D 的优秀入门教程。
  4. 尝试一些现成的例子。首先,浏览 DxR 示例页面。所有这些都可以在 DxRExamples assets 文件夹中找到。双击经典场景以将资源加载到层次窗口中。打开收藏文件夹,记下条形图、散点图等的 DxR…子文件夹。单击第一个项目 DxRBarchartBasic。在检查器面板中,而不是 Vis 脚本及其全局变量 Vis Specs URL,它指向 Examples/Classics/bar chart _ basic . json。在此 Vis Spec 的 JSON 中是“data”属性,包含要显示的数据的值。在其他 Vis 规范中,“URL”属性指定 json 文件名
  5. 按照下一节创建你的第一个沉浸式视觉来创建你自己的视觉。还有额外的教程涵盖了 GUI 控件和自定义标记(使用预设)。用自己的数据,玩得开心!
  6. 创建自定义标记。我特别喜欢在 Unity 中灵活使用预置的游戏对象作为 DxR 标记。注意在研究火焰标记及其 C#粒子脚本时,自定义标记和通道中的教程信息丰富。

反光

DxR 是将传统 2D 数据可视化连接到沉浸式空间的良好开端。如下所述,在未来的 DxR 版本中,有几个扩展是需要的。这些扩展有望来自持续的研究资助和开源社区的贡献。

扩展 DxR 标记编码。DxR 已经实现了令人印象深刻的 Vega-Lite 规范,这在最初并不明显。研究 DxR 语法文档,以及 Google 工作表文档

例如,DXR 使用 x、y、z 位置和旋转的标记编码提供 3D 可视化,类似于 Unity 变换类型。下面是一个名为 Streamline 的标准示例,显示在示例部分。

Vis Spec and Rendering for the Streamline Example

在上述 vis 规格中,使用了圆锥的标记。注意到使用x 方向类型来控制标记的方向向量。这不同于 xrotation 类型,后者控制单位变换旋转属性。更改 vis 规格以查看差异。DxR 文档中隐藏的宝藏!

不过 Unity 有丰富的渲染能力。如何将标记编码扩展到处理纹理、着色器、声音、动画、粒子等?胡同玩家的动作功能列表将是目标。

作为织女星进化的 PyViz。最*,一个名为 PyViz 的社区已经形成,集成了几个基于 python 的可视化包,包括 Vega。这幅 PyVis 背景图描绘了宏伟的画面。目前,只有 Plotly 使用 WebGL 的 3D viz 是有限的,正如在 FAQ 页面上关于【PyViz 是否包含 3D 支持的解释。路线图页面提供了他们当前/未来的发展方向。没有提到 Unity3D。绝对是一个可以利用的快速发展的社区。

提升数据整合能力。当前的数据集成功能支持在 Vis 规范中明确嵌入数据(对于非常小的数据集),或者作为 Unity StreamingAssets 文件夹中的静态 JSON/CSV 文件。

然而,Vis 规范中的 URL 属性可以通过 web 服务调用扩展到远程 SQL 数据库访问。此外,处理数据流到 Unity 的能力,在数据改变时自动更新,并与数据服务器交互。这是一项重要的工作,可以借助现有的开源资源(如 PyViz commuity)。

利用微软混合现实工具包。 DxR 建立在 Unity 环境中的 HoloToolkit 之上。微软最*将 HoloToolkit 转换为混合现实工具包(MRTK),并且正在积极推进。

Architecture of Mixed Reality Toolkit

目标是…“旨在加速针对微软 HoloLens 和 Windows 混合现实耳机的应用程序开发的脚本和组件集合”,其中确实包括 Steam VR(如 HTC Vive 和 Oculus Rift)和 OpenXR *台。 MRTK github 在麻省理工学院许可下,基于 Windows 10 UWP ( 混合现实 API)构建。问题是如何将 MRTK 整合到 DxR 中,利用其新兴的功能,同时*衡新兴的竞争 VR 工具包。

实体-组件-系统合一。另一个相关的发展是 Unity 的新实体-组件-系统架构,以及作业系统和突发编译器。在以成群结队的军队为特色的视频游戏的驱动下,Unity 正在测试这种新的架构,它将驱动游戏对象行为的数据(作为实体的组件)与执行这些行为的代码(作为系统)分开。最好的介绍是一系列的六个视频教程加上例子。

当 ECS 成熟时,它的潜力将是创造和激活 Unity 对象(具有复杂行为和外观的 gliphs),数百万个!将 gliph 的所有数据打包到一个实体中,然后传输到 GPU,这是创建这种可视化的唯一方法。这种能力可以允许新的复杂的可视化方法。

只有一个维度?

以上集中于将 2D 可视化连接到 3D 沉浸式空间。然而,这是否意味着只有一个维度可以用于我们的可视化?

2015 年我写过一篇关于 虚拟现实对数据可视化 有用吗?4这是基于不列颠哥伦比亚大学数据研究员塔玛拉·芒兹纳的评论。她的简短回答是“不”,因为: 3D 只在空间设置中需要,广义上讲,VR 的成本超过了它的好处。科学可视化通常具有显示数据的自然 3D 背景,因此对于观察者来说是直观的。如果自然的 3D 背景不存在,那么 VR 还有存在的理由吗?我的结论是…

…虚拟数据世界应该提供独特的功能(如协作),并与 2D 可视化协同工作(将它们融入现实世界)。[如果我们]天真地使用虚拟数据世界来将 2D 可视化再扩展一个维度,我们将无法找到[虚拟现实可视化]的有效用例。

从那以后,我研究了几种创造性地使用这个维度的方法。以下是我正在寻求的一些建议;

  • 设想构建一个虚拟世界,代表整个复杂系统的动态(如数字城市)。水*面将类似于物理世界,而垂直维度将代表抽象(和分析)层次的增加。记住这里没有重力!
  • 支持多用户环境,以促进同时观察相同行为的人之间的协作,每个人都有自己的专用工具。
  • 用信息过载字形(标记),例如基于研究的 Gistualizer5场景的要点 5。注意 DxR 例子暗示了这种现象。
  • 将潜在空间(嵌入)可视化在经过训练的神经网络的隐藏层中。[7]一种方法是通过从权重创建统一纹理来过载字形。第二种,更有趣的方法是探索整个 100+维空间,一次 3 维。在 Unity 中需要一个智能导航器来在这个高亮度空间中漫游!

如果你对此感兴趣,让我们来构建沉浸式世界吧!请加入沉浸式分析社区进行合作。【 网站twitterlinkedinslackgithub 】。

参考

  1. Sicat,Ronell 等人 DXR:用于构建沉浸式数据可视化的工具包。(2018).https://sites.google.com/view/dxr-vis/home和https://github.com/ronellsicat/DxR。
  2. 萨菲尔,丹奈儿。 IEEE VIS 2018:色彩、交互、&增强现实。(2018).https://medium . com/multi-views-visualization-research-explained/IEEE-vis-2018-color-interaction-augmented-reality-AE 999 b 227 c 7
  3. 罗伯茨、乔纳森等人超越桌面的可视化——下一件大事。(2014).https://ieeexplore.ieee.org/document/6879056
  4. 黑客马拉松,理查德。VR 对数据可视化有用吗? (2015)。
    https://www . immersiveanalytics . com/2015/10/is-virtual-reality-used-for-data-visualization/
  5. Bellgardt,Martin 等人 Gistualizer:多维数据点的沉浸式字形。(2017).https://vr.rwth-aachen.de/publication/02157/
  6. 奥利瓦,奥德。一场戏的要旨。(2005).https://www . science direct . com/science/article/pii/b 9780123757319500458
  7. 科尔森威尔。神经网络嵌入解释。(2018).
    https://towards data science . com/neural-network-embeddings-explained-4d 028 E6 f 0526

使用人工智能染头发(或看起来更老)

原文:https://towardsdatascience.com/dye-your-hair-or-look-older-using-ai-930bc6928422?source=collection_archive---------13-----------------------

使用 StarGAN 进行图像到图像的翻译。

Photo by Matthew Bennett on Unsplash

我会告诉你一些不可否认的事实。总有一天你会变老——你会变得不一样。

事实上,在你的一生中,你的外貌会发生很大变化

你希望自己看起来有点不同。我不会怪你,我也喜欢那样。

A sample of StarGAN reconstructing images with new target domains

你现在就可以这么做。你可以尝试金发——没有任何染料——变老 50 岁,或者甚至改变你的任何照片上的情绪以微笑,看起来生气或害怕——所有这些都不需要任何工作。

如果我不工作,谁会工作?

艾。或者如果你想更具体一点,它是你计算机内部某处的一个 GPU(或者在云上)。

我使用 Pytorch 实现了 StarGAN(GAN:Generative Adversarial Network),这是一种可扩展的方法,用于图像到图像的翻译** — 酷脸改变表情/特征的东西— 它使用深度学习来重建一个新领域的人的照片(例如,皱眉的男人→微笑的男人,或者黑发的女人→金发的女人)。**

图像到图像的转换是将照片的某一方面改变为另一方面

如果你没有听说过,图像到图像的翻译听起来像是科幻电影里的东西。

cycleGAN (not StarGAN) can translate the season the image is in using GANs.

这个概念背后的前提非常简单(尽管这个概念并不简单),所以请听我说完。

在基本水*上,完全训练的网络获取输入图像,识别其域分类(一个方面,例如季节、头发颜色或年龄),并用不同的域重建相同的图像(例如,冬天→重建为夏天)。

所以这相当于翻译一幅图像。

是这样的。有许多类型的模型可以执行图像域的这种转换。但是与 StarGAN 相比,他们的结果非常弱。

StarGAN (bottom) compared to other GAN image translation frameworks

与其他只能学习固定翻译(如黑发→红发)而不能反向重建图像的模型不同,StarGAN 旨在学习如何在一个单一的生成对抗网络** (GAN)中从多个数据集翻译多个域。**

生成对抗网络

甘现在在某种程度上是人工智能的温床。这种技术可以生成看起来 100%真实但实际上根本不真实的图像。

好好看看下面的图片。没有一个是真的。

“But I swear I’ve seen them somewhere!” — Everyone who looks at this image

这是如何工作的?

生成性对抗网络由两个不断相互博弈的神经网络组成(因此是对抗的)。

第一个网络叫做发电机。生成器的作用是生成尽可能精确的假图像。****

第二个网络称为鉴别器。它负责区分真实图像和生成器生成的图像。

Have you ever seen these people before? Well, neither has anyone else 🤯. All these faces are computer generated by a GAN.

把甘斯想成这样。一个伪造者(制作者)正试图从一个画廊伪造艺术品,但是他并不知道艺术品的真实样子。把他想象成一个盲人伪造者。

侦探(鉴别者)是一名世界级的伪造艺术品侦探,他的角色只是尽可能多地了解画廊中的艺术品,以便他能够完成确定艺术品是伪造还是真实的工作。

游戏开始时,侦探是对。盲伪造者的唯一输入是他的伪造艺术是否变得更好。

最终,伪造者开始创作对侦探来说与画廊里真正的艺术品难以区分的艺术品。

每次伪造者或侦探犯了错误,他们都会从中吸取教训,变得更聪明。

这意味着,即使这些网络在相互竞争,因为它们学会了更好地做自己的工作,另一个网络也被迫在自己的工作上做得更好。

这里有一些不足为奇的东西。

每年都有新的人工智能技术/概念发布,使过去在模型任务方面的尝试完全相形见绌。

好的部分来了…

介绍 StarGAN

是的,生成从未生活过的人的真实的全新面孔是非常酷的— 和怪异的— 但是 GANs 可以做的远不止这些。

StarGAN 以一种非常聪明的方式使用 GAN 的来创建最好的图像到图像的翻译器(到目前为止)。

你已经看到了 StarGAN 的结果:

StarGAN translates target domains for a handful of celebrity photos.

它是这样工作的

Remember how GANs work?

  1. 鉴别器被训练:

StarGAN 过程的第一步是训练鉴别器和发生器开始产生真实的重映射图像。

该型号的鉴频器有两个输出;

  • 确定图像是真的还是假的,
  • 正确标记图像的领域(棕色头发,女性等)

2.原始图像被转换到目标域****

This Is How StarGAN works.

好了,现在鉴别器已经训练好了,是时候创建真正的假图像了。

生成器被馈送原始图像,它的预定目标域并生成假图像。

所以在这一步,生成器实际上构建了图像。

3.“假”图像被重建回原来的** ( 什么????)**

这一步似乎有点反直觉。

在其中,生成器获取假图像,然后将其重建回其原始域。

它试图重建原始图像。

然后,该重建图像再次通过最后一步,以制造赝品。这样重复多次,才能让照片真的好看。

为什么?

原因很简单。当转换图像域(产生假图像)时,图像不保留原始图像的内容并不困难。

它偏离原始面貌太远,即使它做翻译领域的工作。

为了解决这个问题,研究人员使用了 CycleGAN 中使用的一种叫做的循环一致性损失。这种方法通过生成假图像并通过生成器重建原始输入的过程来循环。

4.再次欺骗鉴别器的时间****

这是真正好玩的部分。

做完一个假的/翻译的图像后。图像通过鉴别器,鉴别器决定图像是否是假的并选择其标签。

如果图像足够好,鉴别器会正确地标记它,并认为它是一个真实的图像。

如果没有,那么…是时候更加努力工作了。

星际之门就是这样工作的吗?

是的,本质上。

但是 ,StarGAN 后面还有一大堆关于 实际研究论文的信息(去看看吧!).

让我们再复习一遍。

外卖食品

  • ****图像到图像的转换是可以改变你头发颜色(实际上)或者你最喜欢的自然照片的季节的技术。它使用 GANs 改变(图像的一个方面)。
  • ****生成性对抗网络是由一个生成器和一个鉴别器组成的网络,它们不断地相互博弈。这场比赛让甘斯有能力变得更好,提高自己。
  • StarGAN 是一个大规模执行图像到图像翻译的框架。在其中,生成的图像实际上被重建回原始图像,然后一个赝品被多次生成以保持其原始性。

在你走之前

  • 一定要看看我的其他文章!
  • 注册我的每月简讯
  • 看看我新做的网站
  • 在 Linkedin 上添加我以保持更新!s

垂死的舌头和维度的诅咒

原文:https://towardsdatascience.com/dying-tongues-and-the-curse-of-dimensionality-96b42c628559?source=collection_archive---------37-----------------------

自然语言处理能把濒危和非西方语言挤出科学吗?

Photo by Kobu Agency on Unsplash

在过去的十年里,自然语言处理得到了迅猛发展。随着计算能力和数据可用性的提高,挖掘人类语言以获得洞察力的市场非常强劲。

然而,随着 NLP 的激增,我们必须密切关注它正在扩展的空间。我们是否在用我们收集的数据和用来分析数据的工具创造一个以英语为母语的反馈回路?

非英语语言特征使得用以英语为母语的人设计的工具执行 NLP 变得复杂。

总的来说,NLP 技术是由以英语为母语的人发明的。英语倾向于语言学家所说的分析型语言。这意味着它每个词的词素数量很低,缺乏其他语言用于时态、人称、语气和体等事物的语法标记,而是通过词序和与其他词的联系来表达。

例如,在英语中,下列句子是不等价的:

克劳斯吃沙拉。

沙拉吃掉了克劳斯。

但在德语(融合语言)中,它们都意味着“克劳斯正在吃沙拉”,因为融合形态学表明格标记使得词序不太必要:

克劳斯死了。

丹·萨拉特是克劳斯。

在粘合和多合成的语言中,每个单词甚至可以有更多的含义:

但是大多数 NLP 库都是针对英语和类似英语的欧洲语言的标记化、词条化和词性标注而优化的。

低容量、难以处理的数据使偏见永久化。

虽然资源一直在扩大,但除了英语之外,其他语言的选择仍然较少。在某种程度上,这个难题源于对拥有最多数据的语言应用 NLP 的偏见。英语仍然是互联网的语言,因此,它和其他富裕、互联国家的语言一样,在数据集中的比例过高。没有足够的数据,在较小的语言上使用传统的高维 NLP 技术将不会有效。

由于 NLP 经常被用于提供高价值的市场洞察和刺激投资,这种关注的缺乏可能导致一种自我延续的循环,在这种循环中,低资源语言继续获得较少的服务,因此产生的数据比更受关注的语言少。最终,他们可能会失去发言者,而世界将会失去语言多样性。

然而,正如我们所知,在项目层面上,“应该非常小心,不要匆忙删除或更改值,尤其是在样本量很小的情况下。”Max Kuhn 和 Kjell Johnson,应用预测建模 33(第 5 版。2016).“此外,异常数据可能表明正在研究的人口中的特殊部分刚刚开始被抽样。”同上 34。从跨语言数据科学的宏观角度来看,这个建议同样适用。对于历史上研究不足的语言来说,这种初步探索可以产生巨大的影响——对于研究它的知识分子、可以从这种见解中受益的企业,以及从自己的语言得到认可和检查中受益的社区。

弥补差距需要认真关注。

必须首先在数据收集阶段缩小差距。一些 NLP 从业者已经开始在语言学研究过程中更早地实现机器学习,以提高语料库可用的机会。确保领域语言学家和数据科学家进行交流以产生互利的、机器可读的语料库是一个重要的考虑因素。

其他技术可以通过实现不需要这种高维特征创建的方法来寻求充分利用稀疏数据集。半监督和非监督技术可以用来避开休斯现象。要使现有模型适应全新的结构,不仅需要语言知识,还需要创造性思维。在这种情况下,神经技术是有益的。一个小组已经使用深度学习来复兴塞内卡。在谷歌的帮助下,其他公司也在跟进。

机器学习给了我们一个前所未有的机会来保存和探索前几代人从未有过的研究不足的语言。那些接受挑战的人不仅会丰富自己,还会丰富我们对共同语言遗产的集体理解。

动态图表:让您的数据移动

原文:https://towardsdatascience.com/dynamic-charts-make-your-data-move-19e540a06bd3?source=collection_archive---------20-----------------------

动态图表给我们一种直观和互动的体验。本文将解释什么是动态图表以及如何制作动态图表。

From FineReport

1.动态图表是如何工作的?

上图是用 BI 报告工具 FineReport 制作的包含动态图表的仪表板。点击饼状图的相应位置,可以得到具体区域的数据,交互性很强。

我们来对比一下 Excel 呈现的数据。是不是显得单调冰冷?相反,动态图表能带给我们直观的体验,更好的展现数据的差异。接下来,我将从定义、优点、制作方法等方面介绍动态图表,让您对动态图表有一个更清晰的认识。

2.什么是动态图表?

可能你们很多人认为有动画效果的报表是动态报表。其实动态报表是指没有固定报表模板,需要根据实际业务数据生成模板的报表。而这往往是通过动态图表实现的。动态图表的核心是数据和图表类型可以根据不同的情况即时显示。除了显示一般的静态图表内容,它们还必须具有良好的交互性。

简单来说,动态图表的核心就是报表数据可以随时调用。比如老板想查看某个月的数据,只需要设置一个参数过滤条件。当老板在控件中选择时间和月份时,报表将只显示该月的数据。这称为动态报告。

动态图表的目的是为了更方便快捷地查询和读取数据。在此基础上,动态图表需要包含大量的逻辑功能,例如:

  • 参数过滤:根据不同的条件查看不同的数据。这是动态图表的基本功能。

  • 参数联动:联动两个或两个以上的组件,实现数据之间的自动关联。比如点击年销售额,该年的订单明细,月退货率和销售额排名会挂钩。

  • Drill Down :动态图表的常用功能主要是实现无限层数据的展开,以及更高维度的明细数据的展开。例如,下钻图。

  • 参数面板动态显示:由于一些需要,很多情况下,一些查询条件只有满足某个条件才会显示。例如,如果您选择一个地区,随后的参数框将自动显示该地区的城市和消费者。

动态查询:如果数据库中有多个表,我们如何提高查询效率?此时,您可以设置动态数据列,例如,在控件中输入" jia ",它将显示所有表格中带有" jia "的信息:

3.如何制作一个很酷的动态图表?

3.1 基础图表制作流程

这里我们选择 FineReport 做动态图表。在 FineReport 中,图表的工作流程类似于 Excel,数据准备—插入图表—选择图表类型—选择分类轴、系列名称和系列值—设置图表样式。

3.2 不同的图表类型

这主要是文字、数字、网格的美感,以及整体的色彩和谐。这些可以在 FineReport 中定制。

你甚至可以做一个卡片栏报告。

3.3 数据可视化小部件

除了表单的类型之外,可视化图表还有动态显示部分,这就是所谓的动态可视化。

3.4 仪表盘

想要让最终的动态图得到大家的认可,要牢记三点:设置版面、搭配颜色、修饰动态效果。

注:本文所有动态图表均摘自fine report。这个工具是由我工作的数据研究所开发的。个人使用完全免费。你可以下载它来练习制作图表和仪表盘。

4.制作动态图表的工具

最后,对于公司中的不同角色,他们通常会根据工作需要使用不同的工具来创建动态图表。这三个场景是最常见的,也许可以给你一些参考。

  • 利用 Excel 内置的图表做一些规律的图表。用 Excel 制作的高级复杂图表如动态图表、图表的过滤显示可以通过编写 VBA 来实现。
  • 使用 R、Python 的编码语言,调用图表函数包,呈现可视化数据,常用于数据分析师。
  • 使用 Echarts、HighCharts、D3.js 等开源可视化插件,嵌入代码,开发插件包,常用于可视化工程师和前端开发。

您可能也会对…感兴趣

让你的数据报告脱颖而出的指南

2019 年你不能错过的 9 款数据可视化工具

新手如何打造一个很棒的仪表盘?

数据可视化中前 16 种图表类型

什么是大屏幕的数据可视化,如何实现?

动态元嵌入

原文:https://towardsdatascience.com/dynamic-meta-embeddings-f97e2c682187?source=collection_archive---------16-----------------------

如果你在过去的几个月里阅读过任何与 NLP 相关的书籍,你不可能没有听说过伯特、 GPT-2 或埃尔莫这些人进一步拓展了 NLP 任务的范围。尽管这些技术很棒,但是有很多 NLP 问题设置你无法使用它们。你的问题可能不是真正的语言,而是可以用记号和序列来表达。你可能正在处理一种没有预先训练选项的语言,也没有资源来自己训练它。
也许你只是在处理一个非常特殊的领域(但是你知道 BioBERT 吗?).

因此,您可以选择处理预先训练好的嵌入(不是由上述模块生成的)。今年早些时候的 Kaggle Quora 虚假问题分类就是这种情况,参赛者不能使用 BERT/GPT-2/ELMo,但只能获得四组预训练的嵌入。这个设置引发了一个有趣的讨论,即如何组合不同的嵌入,而不是只选择一个。
在这篇文章中,我们将回顾一些将不同的嵌入组合成单一表示的最新技术,这被称为“元嵌入”。
一般来说,我们可以将元嵌入技术分为两个不同的类别。第一个是(1)当创建元嵌入的过程与它们将被用于的任务分离时,以及(2)当训练元嵌入与实际任务同步时。
我不会在这篇文章中介绍使用第一个提到的过程(1)的方法,它们中的大多数都非常简单,包括嵌入维度的*均、连接等。然而,不要把简单误认为是弱,因为提到的 Kaggle 竞赛获胜解决方案使用了嵌入的加权*均。
如果你想了解更多关于这类方法的信息,你可以在下面两篇文章中找到。简单得令人沮丧的元嵌入——通过*均源词嵌入来计算元嵌入
b 。通过使用嵌入集合的系综学习元嵌入
在下一节中,我们将介绍使用第二个提到的过程(2)的两种技术。

(上下文)动态元嵌入

本节中的技术都来自脸书人工智能研究论文“用于改进句子表示的动态元嵌入”,并提出了两种新技术,“T2”动态元嵌入(DME) 和“T4”上下文动态元嵌入(CDME) 。这两种技术都是附加在网络开始处的模块,并且具有可训练的参数,这些参数从与网络其余部分相同的梯度中更新。这两种技术的共同步骤是原始嵌入的线性投影。下图提供了投影的可视化效果;虚线表示学习的参数。

Figure 1: Projection, learned parameters in dashed line

使用由此产生的投影,将计算关注系数,以使用这些投影的加权和。DME 和 CDME 计算这些系数的方式不同。

测距装置(Distance Measuring Equipment)

DME 使用的机制只依赖于单词 projections 本身。每个单词投影乘以一个学习向量 a ,这产生一个标量——因此对于 N 个不同的投影(对应于 N 个不同的嵌入集),我们将有 N 个标量。这些标量然后通过 softmax 函数传递,结果是注意系数。然后,这些系数用于创建元嵌入,这是投影的加权和(使用系数加权)。
该步骤如下所示(虚线表示已学习的参数)

Figure 2: Creating the DME embedding, learned parameters in dashed line

如果你说 TensorFlow(或 Keras),你可能更喜欢在代码中看到它——下面是 DME 的 Github 要点(精简版),完整代码可以在这里找到

CDME

CDME 使用双向 LSTM (BiLSTM)将上下文添加到混合中。如果你对这个术语感到不舒服,我不会在这里详述 LSTMs,回顾一下关于它们的经典的 colah post 。

与 DME 的唯一区别在于注意力系数是如何计算的。
就像 DME 一样,首先序列被投影,然后投影的序列通过 BiLSTM。
然后,不使用单词本身,而是使用正向和反向 LSTMs 的级联隐藏状态(在单词的对应索引中)和向量 a 来计算关注系数。
这个过程的可视化:

Figure 3: Creating the CDME embedding, learned parameters in dashed line

同样,如果你喜欢阅读下面的代码是 Github gist 的精简版,完整版在这里

就这些,希望你学到了新的东西,欢迎发表你的想法和问题。👋

在https://www.datascience.co.il/blog查看更多内容、博客和新闻

Keras 中的动态元嵌入

原文:https://towardsdatascience.com/dynamic-meta-embeddings-in-keras-42393d246963?source=collection_archive---------22-----------------------

了解不同嵌入的有价值的组合

Photo by Khushbu hirpara on Unsplash

许多 NLP 解决方案利用预先训练的单词嵌入。选择使用哪一种通常与最终性能有关,并且是在大量试验和手动调谐之后实现的。脸书的人工智能实验室一致认为,做出这种选择的最佳方式是让神经网络自己找出答案。

他们引入了 动态元嵌入 ,这是一种简单而有效的嵌入集成监督学习方法,可以在同一模型类中的各种任务上实现最先进的性能。这个简单但非常有效的方法允许学习一组选择的单词嵌入的线性组合,这优于各种嵌入的简单串联。

如上所述,作者在 NLP 领域的各种任务上证明了他们的解决方案的有效性。我们限制自己在一个文本分类问题中采用这些技术,其中我们有 2 个预训练的嵌入,并希望智能地组合它们以提高最终的性能。

数据

我在 Kaggle 上发现了一个有价值的数据集,其中包含了来自 BBC 档案馆的文章全文(总共 2225 篇)。新闻属于 5 个主题领域:

Label distribution

我们的目标是对它们进行正确分类,为此,我们希望训练不同类型的嵌入,智能地组合它们,并在此基础上构建我们的分类器。开始时,对原始语料库应用标准的清洗程序。作为嵌入模型,我选择了最常见的类型:Word2Vec 和 FastText。我们可以使用 Gensim 轻松地训练它们,将它们“拖放”到 Keras 架构中(记住为每个选定的嵌入框架保持相同的嵌入大小)。我手工仔细计算了这个过程,以便在需要时控制填充过程:Keras 的 Tokenizer 对象和 pad_sequence 函数使所有事情变得简单。

当我们以多次训练的嵌入(也是像手套或类似的模型的预训练形式是完美的)和顺序语料库结束时,我们准备好组合我们的权重。

模特们

在原始论文中介绍了两种不同的技术:

  • 动态元嵌入(DME) : 原始嵌入被投影到新的空间中,通过 LSTM 编码器添加额外的可学习权重,遵循注意机制。然后将它们与其原始格式线性组合。用喀拉斯语说:
def DME(maxlen): inp = Input(shape=(maxlen, 100, 2))
    x = Reshape((maxlen, -1))(inp)
    x = LSTM(2, return_sequences=True)(x)
    x = Activation('sigmoid')(x)
    x = Reshape((maxlen, 1, 2))(x)
    x = multiply([inp, x])
    out = Lambda(lambda t: K.sum(t, axis=-1))(x) return Model(inp, out)
  • 【上下文动态元嵌入(CDME) : 如上,原始嵌入被投影到一个新的空间,增加额外的可学习权重;但是现在通过 BiLSTM-Max 编码器应用了上下文相关的系统。最终追求的是自我关注机制和与原格式的加权组合。在 Keras 语言中(没有提供 Keras 双向层的最大池合并,所以我们必须自己编码):
def CDME(maxlen, latent_dim=2): inp = Input(shape=(maxlen, 100, 2))
    x = Reshape((maxlen, -1))(inp)
    x = Bidirectional(LSTM(latent_dim, return_sequences=True))(x)
    x = Lambda(lambda t: [t[:,:,:int(latent_dim/2+1)],  
                          t[:,:,int(latent_dim/2+1):]])(x)
    x = Maximum()(x)
    x = Activation('sigmoid')(x)
    x = Reshape((maxlen, 1, 2))(x)
    x = multiply([inp, x])
    out = Lambda(lambda t: K.sum(t, axis=-1))(x) return Model(inp, out)

我们重新创建了两个通用代码块,它们通过一个动态过程来执行嵌入组合。这两种解决方案都可以放在网络的起点,紧接在我们的嵌入的读取和连接之后。在它们上面,我们可以根据不同的目的叠加正常的图层。在我们的例子中,我们添加一些递归层来正确分类我们的新闻文章。我们以这两种架构结束:

对于 DME :

concat_inp = Concat_Emb([embedding_matrix_w2v, embedding_matrix_ft], maxlen=max_len)
dme = DME(max_len)
x = dme(concat_inp.output)
x = GRU(128, dropout=0.2, return_sequences=True)(x)
x = GRU(32, dropout=0.2)(x)
out = Dense(y.shape[1], activation='softmax')(x)dme_model = Model(concat_inp.input, out)
dme_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

对于 CDME:

concat_inp = Concat_Emb([embedding_matrix_w2v, embedding_matrix_ft], maxlen=max_len)
cdme = CDME(max_len)
x = cdme(concat_inp.output)
x = GRU(128, dropout=0.2, return_sequences=True)(x)
x = GRU(32, dropout=0.2)(x)
out = Dense(y.shape[1], activation='softmax')(x)cdme_model = Model(concat_inp.input, out)
cdme_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

现在,我们已经准备好执行培训,并看到一些结果。这两个模型都能够在测试数据上达到大约 93%的总体准确率,并且每个类别都有很高的召回分数。

摘要

允许访问多种类型的嵌入(不管它们是预先训练的还是特别构建的),我们允许神经网络通过预测每种嵌入类型的权重来学习它偏好的嵌入( DME ),可选地取决于上下文( CDME )。我们在文本分类的 NLP 任务中实现了这一点,只是简单地将这一过程与处理这类问题的常规方法结合起来。

查看我的 GITHUB 回购

保持联系: Linkedin

参考文献

改进的句子表征的动态元嵌入:杜维基拉,王和赵京贤;脸书人工智能研究;纽约大学;CIFAR 全球学者。

数据科学家的动态编程

原文:https://towardsdatascience.com/dynamic-programming-for-data-scientists-bb7154b4298b?source=collection_archive---------8-----------------------

Image by Dimitri Houtteman from Pixabay

算法面试

如何轻松解决 DP 问题?

算法和数据结构是数据科学不可或缺的一部分。虽然我们大多数数据科学家在学习时没有上过适当的算法课程,但它们仍然很重要。

许多公司在招聘数据科学家的面试过程中会询问数据结构和算法。

现在,许多人在这里问的问题是,问一个数据科学家这样的问题有什么用。 我喜欢这样描述,一个数据结构问题可以被认为是一个编码能力测试。

我们都在人生的不同阶段进行过能力倾向测试,虽然它们不是判断一个人的完美代理,但几乎没有什么是真的。那么,为什么没有一个标准的算法测试来判断人的编码能力。

但我们不要自欺欺人,他们需要像你的数据科学面试一样的热情,因此,你可能需要花一些时间来研究算法、数据结构和算法问题。

这篇文章是关于快速跟踪这项研究,并以一种易于理解的方式为数据科学家解释动态编程概念。

动态编程是如何工作的?

假设我们需要找到第 n 个斐波那契数。

斐波纳契数列是一系列数字,其中每个数字(斐波纳契数)是前面两个数字的和。最简单的是 1,1,2,3,5,8 等系列。答案是:

def fib(n):
    if n<=1:
        return 1
    return fib(n-1) + fib(n-2)

这个问题与递归方法密切相关。但是你能发现这里的问题吗?

如果您尝试计算 fib(n=7 ),它会运行 fib(5)两次,fib(4)三次,fib(3)五次。随着 n 变大,对同一个号码进行了很多次调用,我们的递归函数一次又一次地计算。

Source

递归本质上是一种自顶向下的方法。当计算斐波那契数 n 时,我们从 n 开始,然后递归调用 n-2 和 n-1 等等。

动态编程 中,我们采取自底向上的方法。它本质上是一种迭代编写递归的方法。我们首先计算 fib(0)和 fib(1 ),然后使用以前的结果生成新的结果。

def fib_dp(n):
    dp_sols = {0:1,1:1}
    for i in range(2,n+1):
        dp_sols[i] = dp_sols[i-1] + dp_sols[i-2] 
    return dp_sols[n]

为什么动态编程很难?

递归是一个数学概念,对我们来说很自然。我们试图通过把一个大问题分解成小问题来寻找解决方案。

现在,动态规划需要完全相同的想法,但在动态规划的情况下,我们预计算所有可能需要以自下而上的方式计算的子问题。

我们人类本质上是天生以自上而下的方式工作的。在我们的学习中,大多数人在深入之前都试图深入事物的广度。或者是我们的思维方式。

那么,如何开始自下而上的思考呢?

我发现解决下面的问题给了我很多关于 DP 如何工作的直觉。 一旦我能够解决这个问题,我自己就对 DP 非常满意,希望它也能帮助你。

基本上这个想法是,如果你知道一个小问题的解决方案,你是否能推导/解决一个更大的子问题?

最大路径和

给定一个装满黄金的 m x n 网格,找出一条从左上到右下的路径,其中最大化沿其路径的黄金总和。我们只能从(0,0)开始向下或向右移动

现在可以肯定有许多途径。我们可以一直走到右边,然后到底。或者我们可以走一条曲折的路?

但是只有一条/几条路会让你变得富有。

那么,你是如何开始思考这样一个问题的呢?

当我们考虑动态编程问题时,我们采用自底向上的方法。所以我们从思考最简单的问题开始。在我们的例子中,要解决的最简单的问题是基本情况。如果我们必须到达单元格(0,0),我们可以获得的最大黄金价值是多少?

答案很简单——就是单元格的值本身。

所以我们转到一个更难的问题。

cell (0,1)和 cell (1,0)呢?

这些也很简单。我们只能通过(0,0)到达(0,1)和(1,0),因此我们可以获得的最大黄金是单元格(0,1)/(1,0)中的值加上我们到达单元格(0,0)时可以获得的最大黄金

cell(0,2)呢?同样只有一条路。因此,如果我们知道(0,1)的解,我们只需将单元格(0,2)的值相加,就可以得到(0,2)的解

现在让我们试着对任意一个单元格做同样的事情。我们想在这里推导出一个关系。

所以在任意单元格的情况下,我们可以从顶部或者从左侧到达它。 如果我们知道单元格顶部和左侧的解,我们就一定可以计算出任意当前目标单元格的解。

编码

一旦我们有了直觉,编码工作就非常简单了。我们从计算第一行和第一列的解开始。然后我们继续用之前得到的关系计算网格中的其他值。

def maxPathSum(grid):
    m = len(grid)
    n = len(grid[0])
    # sol keeps the solutions for each point in the grid.
    sol = list(grid)
    # we start by calculating solutions for the first row
    for i in range(1,n):
        sol[0][i] += sol[0][i-1]
    # we then calculate solutions for the first column
    for i in range(1,m):
        sol[i][0] += sol[i-1][0]
    # we then calculate all the solutions in the grid
    for i in range(1,m):
        for j in range(1,n):
            sol[i][j] += max(sol[i-1][j],sol[i][j-1])
    # return the last element
    return sol[-1][-1]

结论

在这篇帖子里,我谈到了我对动态编程问题的看法。

我首先问自己我能解决的最简单的问题,以及我是否能通过使用简单问题的解决方案来解决更大的问题。

动态编程构成了数据科学/机器学习工作面试中一些最常见问题的基础,对这些问题的良好理解可能会帮助你获得理想的工作。

所以出去用 Leetcode/HackerRank 解决一些问题吧。这些问题确实很有趣。

如果你想学习算法和数据结构,也可以看看我在系列的其他帖子。

继续学习

如果你想了解更多关于算法和数据结构的知识,我强烈推荐 UCSanDiego在 Coursera 上的 算法专门化。

谢谢你的阅读。将来我也会写更多初学者友好的帖子。在 媒体 关注我,或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系。

此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意

在 SAS 中从单个数据集动态拆分/创建多个数据集

原文:https://towardsdatascience.com/dynamically-split-create-multiple-datasets-from-single-dataset-in-sas-7a6ea1f5f15d?source=collection_archive---------9-----------------------

将一个数据集分割成多个数据集是 SAS 程序员经常面临的挑战。例如,将从世界各地收集的数据分割成独特的国别数据集,其中每个数据集只包含特定于该国的数据。在这种情况下,程序员经常被迫对程序进行硬编码,并使用多个循环来完成工作,这不是一种好的做法。然而,SAS 为这个问题提供了一个漂亮的、一次性的、可重用的解决方案。让我们直接进入它。

导入数据集

我们有以下全球销售数据集( Worldwide_Sales.xls ):

所有数据集和代码文件都可以在 GitHub(【https://github.com/pramodkumavat/createMultipleDatasets/)找到。**

让我们首先将这个数据集导入到我们的 SAS 环境中。

页(page 的缩写)s:请将数据集文件 Worldwide_Sales.xls 复制到您的 SAS 工作目录 myfolders 中。

**proc import out=work.sales
datafile='/folders/myfolders/Worldwide_Sales.xls'
dbms=xls replace;
getnames=yes;
run;**

运行上面的代码将把我们的数据集作为 work.sales 库加载到 SAS 中。

要理解导入代码中使用的各种选项,这个 FAQ 就是你所需要的。

创建多个数据集

业务需求表明,我们必须从全球数据集创建国家唯一的数据集。这样创建的每个数据集将包含该特定国家的销售数据。为此,我们首先需要从数据集中提取唯一的国家名称。

步骤 1:提取唯一的国家名称

**proc sort data=work.sales out=work.unique (keep=Country)
nodupkey;
by country;
run;**

运行上面的代码将为我们提供数据集中唯一的国家名称。

一旦我们提取了国家名称,现在让我们创建我们的神奇代码,在单个数据语句中动态创建国家级数据集。

步骤 2:动态创建多个数据集

**data _null_;
set work.unique;
call execute('data ' !! compress(Country) !! '; set work.sales; where Country = "' !! Country !! '"; run;');
run;**

正如您在上面的输出中所看到的,在左侧,我们看到已经创建了国家唯一的数据集。

幕后的魔法

让我们一行一行地理解代码的每一个方面,这使得魔术成为可能。

**data _null_;**

我们将输出数据设置为 null ,因为我们不想创建单个数据集,而是一次创建多个数据集,这一点我们稍后会看到。

**set work.unique;**

我们将输入数据集设置为 work.unique ,其中包含唯一的国家名称。我们这样做是因为我们希望在每次迭代中创建独特的国家级数据集。

**call execute('data ' !! compress(Country) !! '; set work.sales; where Country = "' !! Country !! '"; run;');
run;**

这才是真正的交易!您可能已经注意到,我们在 call execute() 语句中编写了一个嵌套查询。如前所述,SAS 提供了这个漂亮的解决方案来创建多个数据集,而不使用多个循环。

execute() 调用中,我们以数据语句开始,然后附加上我们唯一的国家名称。国家这里只是来自我们 work.unique 数据集的变量。 compress 函数应用于 Country 变量,因为我们的国家名称中有空格(例如,新西兰、英国)。这个 compress 函数在创建唯一数据集时删除国家名称中的空格。

然后我们放分号()结束我们的数据步骤,然后将输入数据集设置为 work.sales 。很明显,我们将输入设置为父数据集 work.sales ,使用它我们将创建唯一的数据集。然后,我们放入 where 条件,以便它从父数据集中挑选国家级数据。然后,我们用 run 语句结束嵌套查询,并关闭 execute() 调用。代码的最后一个 run 语句是为了结束外部查询。

完整代码

我在这里粘贴完整的 SAS 代码供您参考。这个 SAS 代码(dynamicmultipledatasets . SAS)以及使用的数据集( Worldwide_Sales.xls )可以从 GitHub 这里下载。

*** Importing the dataset in SAS;proc import out=work.sales
datafile='/folders/myfolders/Worldwide_Sales.xls'
dbms=xls replace;
getnames=yes;
run;* Extracting country names from the dataset;proc sort data=work.sales out=work.unique (keep=Country)
nodupkey;
by country;
run;* Creating multiple datasets from the parent dataset;data _null_;
set work.unique;
call execute('data ' !! compress(Country) !! '; set work.sales; where Country = "' !! Country !! '"; run;');
run;**

希望这对你有帮助。请评论您的反馈/建议。干杯!

基于自然语言处理和无监督学习的电子商务评论分析

原文:https://towardsdatascience.com/e-commerce-reviews-analysis-902210726d47?source=collection_archive---------14-----------------------

picture credits to www.oberlo.com

在这个项目中,我想练习自然语言处理和无监督机器学习。在对我能从网上获得的数据集做了一些研究后,我找到了一个真实的电子商务企业的女装数据集。我认为,如果我能为企业开发一种从他们的服装评论中提取见解的自动化工具,这可能会很酷,对企业很有用。因为阅读成千上万的评论并不容易,而且是一项耗时的任务。

由于各种原因,这可能是有价值的。例如:

  1. 了解趋势:了解人们在谈论什么,他们喜欢什么或不喜欢什么。
  2. 根据用户反馈改进产品。
  3. 跟进用户不喜欢的产品,进一步了解问题所在。
  4. 为了降低退货率,重新进货费用是电子商务成功甚至生存的一大开支。

以上是你可以对顾客评论做的一些事情。

我想解决的问题

因此,为了这个项目的目的,我想探索以下几点:

  1. 话题建模:比如人们在谈论的那个服装/鞋子有哪些正面和负面的东西。通过计算某个主题中出现的单词或单词组合的频率,看看我是否能找到任何主题。
  2. 使用聚类将好的和坏的评论“分离”:通过聚类的方法,将不同产品的好的和坏的评论分离出来或找到模式,以便发送给相应的部门关注。这可能非常困难,因为聚类方法是一种无监督的机器学习技术,可以从数据中找到隐藏的模式。

项目设计

  1. 清理并对我的数据执行探索性数据分析(EDA) 。
  2. 我清理的文本数据的矢量化(计数矢量化器和 TF-IDF)。
  3. 生成一个单词云,看看人们谈论的最频繁的单词是什么。
  4. 进行主题建模,看看我是否能找到一些人们正在谈论的不同主题。
  5. 使用聚类方法从我的文本数据中聚类出模式,看看我是否能聚类出那些不好的评论(或不同类型的评论)。并使用 TSNE 可视化我的集群。
  6. 最后,使用数据集中的评级列执行监督学习问题,以对好评和差评进行分类。

我使用的数据和技术

我使用的数据集可以从 Kaggle 获得,由 23486 条不同的服装评论和 11 个不同的栏目组成。

snapshot of the data

我在这个项目中使用的工具有 numpy、pandas、matplotlib、seaborn、wordcloud、 sklearn 特别是与 CountVectorizer 、 TfidfVectorizer 、 Kmeans 、 TSNE 、 NMF 、 TruncatedSVD 、 silhouette_score 、 MultinomialNB

数据清洗&探索性数据分析(EDA)

how many NAs in the dataset

  • 数据集中有一些 NAs,我将把它们放在这里。
  • ReviewText 列将是我的 NLP 主要列。
  • 除了 ReviewText 列,我还创建了另一个名为 CombinedText 的列,它将 Title 和 ReviewText 列连接在一起。因为我认为你也可以从评论标题中得到一些隐藏的数据。
  • 最后,我将清理后的数据保存起来以备将来使用。

WordCloud

接下来我要做的是创建一个单词云,看看人们谈论/使用最多的单词是什么。在此之前,我需要:

  1. 将我的文本全部修改成小写
  2. 删除评论中可能存在的一些不太有用的常用词,如连衣裙、连衣裙等。
  3. 然后使用 Count 和 TF-IDF 矢量器对文本数据进行矢量化。例如:
count_vectorizer = CountVectorizer(ngram_range=(1, 2),  
                                   stop_words='english', 
                                   token_pattern="**\\**b[a-z][a-z]+**\\**b",
                                   lowercase=**True**,
                                   max_df = 0.6, max_features=4000)
tfidf_vectorizer = TfidfVectorizer(ngram_range=(1, 2),  
                                   stop_words='english', 
                                   token_pattern="**\\**b[a-z][a-z]+**\\**b",
                                   lowercase=**True**,
                                   max_df = 0.6, max_features=4000)

cv_data = count_vectorizer.fit_transform(df.ReviewTextLower)
tfidf_data = tfidf_vectorizer.fit_transform(df.ReviewTextLower)

代码基本上是说将文本矢量化为 1-gram 和 2-gram(也尝试了 3-gram),使用包中预设的“英语”停用词,所有内容和模式都是小写,忽略文档中频率高于 0.6 的词,最多 4000 个特征/尺寸。

然后我用下面的代码创建一个单词云:

for_wordcloud = count_vectorizer.get_feature_names()
for_wordcloud = for_wordcloud
for_wordcloud_str = ' '.join(for_wordcloud)

wordcloud = WordCloud(width=800, height=400, background_color ='black',
                      min_font_size = 7).generate(for_wordcloud_str)

plt.figure(figsize=(20, 10), facecolor=**None**)
plt.imshow(wordcloud)
plt.axis("off")
plt.tight_layout(pad=0)

plt.show()

most frequent words that customers are talking about

话题建模

在我做主题建模之前还有一步,就是使用 LSA 和 NMF 来降低我输入文本数据的维度。例如:

*# try using 10 dimensions*
n_comp = 10
lsa_tfidf = TruncatedSVD(n_components=n_comp)
lsa_cv = TruncatedSVD(n_components=n_comp)
nmf_tfidf = NMF(n_components=n_comp)
nmf_cv = NMF(n_components=n_comp)

lsa_tfidf_data = lsa_tfidf.fit_transform(tfidf_data)
lsa_cv_data = lsa_cv.fit_transform(cv_data)
nmf_tfidf_data = nmf_tfidf.fit_transform(tfidf_data)
nmf_cv_data = nmf_cv.fit_transform(cv_data)

然后我们可以进行主题建模,下面是一个输出示例:

example of a few topics

您可以生成不同数量的主题,通过测试不同数量的主题来找到最佳数量,并查看这些主题对您是否有意义。

聚类

在运行聚类算法之前,最好将您的输入数据标准化为*均值 0 和标准差 1。因为您的要素可能不在同一比例上,换句话说,这可能与从要素 a 增加 1 个单位和从要素 b 增加 1 个单位不是一回事。

*# initialize standardscaler*
**from** **sklearn.preprocessing** **import** StandardScaler
SS = StandardScaler()

*# transform my reducer data using standardscaler*
lsa_tfidf_data_sclaed = SS.fit_transform(lsa_tfidf_data)
lsa_cv_data_sclaed = SS.fit_transform(lsa_cv_data)
nmf_tfidf_data_scaled = SS.fit_transform(nmf_tfidf_data)
nmf_cv_data_scaled = SS.fit_transform(nmf_cv_data)

然后你可以使用无监督的机器学习算法,针对不同的话题或者不同类型的评论做聚类。在这个项目中,我使用了 KMeans ,还使用了惯性和轮廓分数作为代理来帮助我确定我应该使用的最佳聚类数。然后使用 TSNE 来帮助我可视化生成的集群。例如:

TSNE plots for different number of clusters

在确定了多少个聚类是最佳聚类之后,您可以打印出最接*每个聚类质心的文档以供检查。例如:

indices_max = [index **for** index, value **in** enumerate(kmeans.labels_) **if** value==3]
**for** rev_index **in** indices_max[:5]:
    print(rev_index, str(df.ReviewText[rev_index]))
    print("**\n**")

example of a few documents

分类

我们可以尝试从分析文本数据中分离好的或坏的评论的另一件事是执行分类问题。

snapshot of the data

在我们的数据中,我们有一个名为 Rating 的特性,它是客户对产品的评分,1 表示最不满意,5 表示最满意。

我们可以将 Rating 列设置为目标变量,将 engineered CombinedText 列设置为独立变量,看看是否可以构建一个分类器来自动对评论进行分类。

我做的第一件事是将排名 1 到 4 归为差评(标记为 1),而排名 5 是我们的好评(标记为 5)。这两个等级并不完全*衡,但都在可接受的范围内。我用朴素贝叶斯和逻辑分类器构建了分类模型。

Before and After modification of the Rating column

我用于模型评估的指标,我使用回忆分数,因为我关心当我预测审查是好的审查但实际上不是时的情况。我得到的最好的召回分数是 0.74,没有太多的工程。如果在模型上有更多的时间和探索,分数可能会更好。

recall score fo both bad (rank 1) and good (rank 5) reviews

吸取的教训

  • 无监督学习和有监督学习真的是天壤之别,因为它的本质!
  • 您将会花费大量时间来尝试理解如何对您的数据进行聚类,除了 KMeans 之外,还有许多聚类方法。
  • 在进行文本分析或 NLP 时,您可能会花费大量时间清理文本数据以获得最佳结果。例如,如何根据您的数据和您想要解决的问题的上下文来决定使用什么停用词,如何进行词条整理,如何进行向量化,如何降低维度并避免维度诅咒等等。

未来

如果我有机会延长该项目,我想跟进以下内容:

  • 探索不同类型的聚类算法和 NLP 技术。
  • 添加新的停用词。
  • 构建一个 Flask 原型应用程序来创建一个自动流程,从用户评论中推荐(分离)不同的主题。

非常感谢您的阅读,如果您有兴趣探索我使用的代码和资源,这个项目在我的 github repo 上。

作为强化学习问题的电子商务搜索重新排序

原文:https://towardsdatascience.com/e-commerce-search-re-ranking-as-a-reinforcement-learning-problem-a9d1561edbd0?source=collection_archive---------12-----------------------

Photo by Clem Onojeghuo on Unsplash

作为一个术语,搜索是超负荷的:它既描述了寻找某物的愿望,也描述了寻找的过程。

任何搜索工作流程都有三个主要部分:

搜索预处理:涉及 查询理解 的整个工作流程。从 语言识别字符过滤标记化拼写纠正 词干化和词条化查询重写 (在查询理解之后,查询被传递给搜索引擎用于信息检索和排序。

信息检索&排名:它涉及检索在搜索引擎中被编入索引的信息(文档),并根据传递给搜索引擎的查询对它们进行排名。

搜索后处理:根据外部信号对从引擎检索到的搜索结果进行重新排序,并显示搜索结果。

搜索后处理—根据点击流数据重新排序

搜索最容易获得的外部信号/反馈之一是用户点击数据。我们试图将用户点击建模为相关性的函数,并对搜索结果进行重新排序。

聚集和处理的点击流数据(点击归一化的时间和位置)将具有以下形式:

在我们深入研究重新排序的方法之前,让我们定义一下本文中使用的一些术语。

确定性过程:指系统未来状态不涉及随机性的过程。如果我们从开始,相同的初始状态确定性模型将总是给相同的结果

随机过程:指随机确定的过程。随机优化产生并使用随机变量。

马尔可夫决策过程:指离散时间随机控制过程。它为决策过程提供了一个数学框架,其中结果部分是随机的,部分是由决策者控制的。它包含以下内容:

一个马尔可夫决策过程(MDP)是一个元组 M =(状态空间,动作空间,报酬,状态转移函数,折扣率)。MDP 的目标是找到一个从任意状态 s 开始最大化期望累积回报的策略。如果回报未知,这是一个强化学习问题。

强化学习侧重于在探索(未知领域)和利用(现有知识)之间找到*衡。

MDP 遵循马尔可夫性质,这意味着状态能够以这样一种方式简洁地总结过去的感觉,即所有相关信息都被保留,因此未来状态仅取决于当前状态。

多臂土匪:是 MDP 的特例,那里只有一个州。术语“多臂强盗”来自一个假设的实验,在该实验中,一个人必须在多个动作(即吃角子老丨虎丨机,即“单臂强盗”)中进行选择,每个动作都有未知的支付。目标是通过一系列选择来确定最佳或最有利可图的结果。在实验开始时,当赔率和支出未知时,赌徒必须确定要拉动的机器、其顺序和次数。

MDP 和多臂强盗的区别

为了区分 MDP 和多臂强盗,我们以餐馆为例:我们可能经常去我们最喜欢的餐馆,有时尝试一些新的,以找到一个潜在的更好的。如果说我们对每一家餐厅的偏好从未改变,土匪就是一个非常合适的提法。如果在吃了日本食物后,我们的偏好改变到中国食物,那么建模和探索状态转换是更合适的,因此 MDP。

回到重新排序的问题

学习排名方法是基于外部反馈的搜索结果重新排名的黄金标准。他们的工作原理是优化注释数据上的 NDCG 或 MRR 或地图。这些方法有两个明显的缺点:

  • 它需要大量带注释的数据来训练,并且在索引/目录中引入新的文档/产品会使事情变得更加复杂。
  • 在获得大量反馈之前,它不会探索新的文档/产品,因此会引入偏见。

强化学习就是为了解决上述两个问题而出现的。

在搜索领域,如果我们有无限长时间的反馈数据,我们可以使用 frequentist 方法。尽管如此,因为那是不可能的,我们总是用当前的知识更新我们先前的信念(贝叶斯方法)。

https://xkcd.com/1132/

我们可以将搜索会话建模为 MDP,其中的流程如下:搜索查询 1、添加到购物车、搜索查询 2、添加到购物车……,结账。有一篇很棒的论文描述了这种方法。我们采用一种更直接的方法,其中我们为单个查询(单个状态)的点击建模,即多臂 Bandit。

作为多臂强盗问题的搜索重新排序

我们将针对搜索查询 q 检索到的搜索结果视为不同的手臂,将点击/添加到购物车的任何结果的概率视为拉动手臂的机会。在这种情况下,奖励将是最大化搜索查询 q 的点击/添加到购物车的总次数。

有多种方法可以解决多臂土匪问题。我们分析了实现它的不同方式。

1)贪婪

我们选择数量为ε,ε的用户来显示随机结果(拉随机臂),同时显示其余用户的最佳结果(拉得分最高的臂)。这有助于我们探索所有可能的组合。这里的主要挑战是选择正确的ε。如果太小,我们将无法探索所有的武器/产品。如果它太大,许多用户会发现自己的排名结果很差。

2)政策梯度

在该方法中,我们选择一个策略,例如 softmax 策略,并且从 softmax 分布中随机选择 arm。我们维持每个手臂/文档/产品的*均奖励,梯度代理向最大奖励方向移动。如果出现以下情况,这将是一种理想的方法:

  • 自观察开始以来,所有产品/武器均已推出&
  • 环境中没有新条目(搜索结果页面)。

3) 置信上限(UCB)

这种方法基于 面对不确定性的乐观主义原则 。我们取置信区间的上界,并据此选择产品/拉臂。如果能实时更新上面提到的表格,这是最好的方法之一。

4)汤姆逊取样

多臂 bandit 的最有效方法之一,它考虑了每个臂的概率分布(汇总表图 1)。这里的基本思想是,从每个 arms 元组(good_samples,total_samples),可以生成置信区间,并且可以在 LCB 和 UCB 之间给定随机值。

当总样本数较低时,间隔较宽。尽管如此,随着总样本数的增加,置信区间变紧,最好的结果开始持续获得更高的分数。

Chris Stucchio’s article on bandit algorithms illustrates sharpening of the probability distribution with increase sample size

这在开发和探索之间取得了完美的*衡。在这里,如果我们使用威尔逊的置信区间,而不是贝叶斯区间,我们会得到更好的结果,因为它们更好地模拟了数据中的不对称。

Tensorflow 刚刚发布了他们深度上下文土匪论文的实现。将尝试在其中实现的方法,并将其与随机抽样进行比较。请关注此空间了解更多信息。

参考资料:

  1. https://medium . com/sajari/reinforcement-learning-assisted-search-ranking-a 594 CDC 36 c 29
  2. https://medium . com/@ dtunkelang/search-the-all-the-story-599 F5 d 9 c 20 c
  3. https://www . chriss tuccio . com/blog/2013/Bayesian _ bandit . html
  4. https://medium . com/hacking-and-gonzo/how-Reddit-ranking-algorithms-work-ef 111 e 33 d0 d 9
  5. https://www . Evan miller . org/how-not-to-sort-by-average-rating . html
  6. https://towards data science . com/how-not-to-sort-by-population-92745397 a7ae
  7. https://medium . com/@ sym 0920/the-多臂-土匪-问题-bba9ea35a1e4
  8. https://towards data science . com/13-非数学家多臂强盗问题解决方案-1b88b4c0b3fc

利用区块链和深度学习的电子投票设计

原文:https://towardsdatascience.com/e-voting-design-utilizing-blockchain-and-ai-6bb064a01874?source=collection_archive---------22-----------------------

研究如何利用区块链和深度学习来创建电子投票系统。

Photo by Element5 Digital on Unsplash

投票是民主的一个重要方面,这是公民决定谁将领导国家的方式。这也意味着那个国家的未来会如何发展。我的祖国印度尼西亚目前正在为 2019 年总统选举投票。全世界大约有 1.93 亿人是合格选民。公民投票权对这个国家来说是一场后勤噩梦。为了做到这一点,让我们来分解一下数字:

印度尼西亚在全球招募了 600 万名选举雇员

印尼有 81 万个投票站

为了建立这些投票站,工作人员要乘飞机、乘船和步行到达偏远的村庄。这不是一个小的壮举,这是令人印象深刻的,总是让我惊讶的努力实现这一点。我们可以在选举的某一天这样做,公民可以自由投票。但是,有了技术,难道我们不应该让这变得更容易,更少欺诈,并帮助增加投票率,目前约为 76%。我们目前有技术可以帮助我们使投票更加安全和容易。

有两种技术可以重新定义信息的安全性以及个体性的保证,即区块链和深度学习。在这篇文章中,我们将经历不同的阶段,我认为电子投票将在选举期间开始整合。

第一阶段区块链整合

就地投票最重要的一个方面是确保你投给谁的信息被正确计算。目前的投票做法是用纸笔人工计票。这意味着在计票过程中存在人为失误的空间。有了区块链技术,我们将能够存储谁投了票和他们投了谁的票的信息,这可能是匿名的,取决于我们如何获得许可。这个问题有多种解决方法!

我们需要考虑这应该是在公共还是私人区块链。

如果我们要使用公开的区块链身份证信息,由于个人的安全原因,不应该公布。但目前公共区块链面临的最大问题之一是,截至 2019 年 4 月,在公共区块链上完成 1.9 亿笔交易是不可行的。让我们来看一些截至 2019 年 1 月的快速数据:XRP 最快的公共区块链大约每秒 1000 笔交易。如果我们只有 1 亿人与区块链一起投票,那么确认所有投票将需要大约 27.7 小时。但这是如果 XRP 只有在网络中投票确认,这是不正确的,因为其他类型的交易正在发生,这将意味着它将需要远远超过 27 小时。

我们已经看到了公共区块链存在的一些问题,这意味着目前这个系统通过使用许可区块链更加可行。根据区块链的类型,每秒可以处理大约 3000 个事务。因为在未来几年内,我们不可能让每个人都注册区块链。最无缝的方法是允许投票主持人输入 KYC 的选民数据,然后允许选民投票。这将有助于加快计票的处理速度,并确保数据的可靠性。因为我们使用基于许可的区块链,所以我们有办法控制谁能够查看信息,信息可以存储在哪里,以及如何与之交互。

第二阶段深度学习

Image by teguhjati pras from Pixabay

但是,如果我们能够通过专门使用面部识别技术来利用 DL,从而使这一过程变得更加容易,那会怎么样呢?这项技术已经被利用了,比如你的 iPhone 解锁手机的时候。现在,iPhone 的技术非常强大,因为它使用深度感知来实现用户面部的准确性。这使得使用它来确保投票者是他们所说的那个人要安全得多。虽然这项技术已经存在,但在你将面部识别数据存储在哪里以及你将从哪里获得这些数据方面还存在一些问题。尽管有些国家的数据可能比其他国家更容易获得。

这些不仅是电子投票需要解决的问题,也是个人身份信息需要解决的问题。尤其是如果我们要开始把我们的身份放在区块链上。

投票的未来会是怎样的?

如果我们现实一点,对许多国家来说,最有可能的实现是首先保护数据。以下是我对现在或至少未来 2-3 年的设想。

1。个人将带着他们的 ID 进入投票站。然后,官员将检查个人的 ID,确保他们被允许投票,官员将用户的数据输入到区块链。这可以通过扫描 ID 或手动输入来完成。

2.一旦官员允许,他们就会去投票站投票。

区块链上有什么样的数据?

我们可以知道他们什么时候投票,谁是允许他们投票的官员,但我们可以这样做,这样我们就不知道你投了谁的票。这一切都是在不变性的环境中进行的,确保所有数据都没有被更改。

这也只是一个想法,但并非不可能实现。未来,我将能够登录我的政府应用程序账户,在我舒适的床上投票。当我打开手机时,它会扫描我的脸,我可以在几秒钟内立即投票。

非常感谢你的阅读!

说说你的想法?我们如何改进这个设计?有没有更无缝的集成?你认为我们永远不会有电子投票吗?

如果你喜欢这个想法,请在 LinkedIn 上与我交流,并在 Medium 上关注。

端到端学习,(几乎)通用的 ML 方法

原文:https://towardsdatascience.com/e2e-the-every-purpose-ml-method-5d4f20dafee4?source=collection_archive---------3-----------------------

E2E 可以用来解决每一个机器学习问题吗?

Photo by Su San Lee on Unsplash

对于那些从事机器学习的人来说,最重要的技能之一就是知道对于给定的问题,哪种方法是正确的选择。一些选择是琐碎的(例如,监督的或无监督的,回归或分类),因为它们与问题公式化本身有关。然而,即使在定义了你要解决的问题之后,通常还有无数的算法可以使用。

例如,假设您想要开发一个能够预测分类变量的系统。为了解决这个问题,可以使用分类树、K-最*邻或者甚至人工神经网络。当然,许多不同的算法存在是有原因的,即使它们解决的是类似的问题:每一种算法都有其特殊性,我们可以从中受益。

让任务变得更加困难的是,为了解决一些问题,如语音识别和自动驾驶,由许多层组成的架构是必要的(例如,预处理、特征提取、优化、预测、决策)。对于每一层,可以使用许多不同的算法。

问题是:为了获得更好的结果,必须应用内层的变化及其相应的算法。然而,由于每一层都负责解决特定的任务,因此很难确定这样的变化将如何影响整个系统。

端到端(E2E)学习指的是训练由代表完整目标系统的单个模型(特别是深度神经网络)代表的可能复杂的学习系统,绕过传统流水线设计中通常存在的中间层。

端到端学习

E 第二端到端学习是深度学习领域的一个热门话题,它利用深度神经网络(DNNs)的多层结构来解决复杂问题。类似于人的大脑,每个 DNN 层(或层组)可以专门执行此类问题所需的中间任务。Tobias Glasmachers 证明了 E2E 是如何在深度学习的背景下被构建的[1]:

“这种优雅但直截了当且有些蛮力的技术[E2E]已经在深度学习的背景下得到普及。这是深度神经架构模糊学习机和其他处理组件之间的经典界限的一个看似自然的结果,它通过将可能复杂的处理管道铸造到神经网络的连贯和灵活的建模语言中。”

这种替代方法已经成功地应用于解决许多复杂的问题。下面你可以看到 E2E 是如何应用于语音识别和自动驾驶问题的。

语音识别

Photo by Arthur Caranta

口语理解系统的传统方法设计是具有几个不同组件的流水线结构,由以下序列举例说明:

音频(输入)——>特征提取——>音素检测——>单词合成——>文本转录(输出)。

这种流水线结构的一个明显的限制是,每个模块必须在不同的标准下分别进行优化。E2E 方法包括用单个神经网络代替上述链,允许使用单个优化标准来增强系统:

音频(输入)————(神经网络)——→抄本(输出)

迈克·刘易斯等人介绍了自然语言谈判的 E2E 学习方法2。由此产生的系统是一个基于单个神经网络的对话代理,能够通过协商达成协议。这是通过使用来自包含各种不同谈判策略的大型人际谈判记录数据集的数据来训练神经网络来实现的。

Figure from Mike Lewis et al. 2

E2E 方法的另一个好处是,尽管问题很复杂,但不需要深入了解问题,也可以设计出运行良好的模型。Ronan Collobert 等人解释了如何使用统一的神经网络架构和适当的自然语言处理(NLP)学习算法来避免特定任务工程和大量的先验知识[3]:

“[……]我们试图在多个基准测试中超越,同时避免特定任务的工程。相反,我们使用一个能够发现足够的内部表示的单一学习系统。[……]我们避免特定任务工程特征的愿望阻止了我们使用大量的语言知识。相反,我们通过传输在大型无标签数据集上发现的中间表示,在大多数任务中达到良好的性能水*。我们称这种方法为“几乎从零开始”,以强调减少(但仍然重要)对先验 NLP 知识的依赖。

自动驾驶

一个自主驾驶系统可以归类为由许多层组成的复杂系统的一个显著例子。根据 Alexandru Serban 等人提出的架构,我们可以使用 5 个不同的层来设计自动驾驶系统4:

Figure from Alexandru Serban et al. 4

输入数据来自几个传感器(照相机、激光雷达、雷达等)。)在传感器融合层进行处理,以提取相关特征(如物体检测)。处理完所有数据并提取相关特征后,在第二层创建一个“世界模型”。该模型包括周围环境以及车辆内部状态的完整图像。

根据这个模型,系统必须选择在行为层做出哪些决定。根据车辆的目标,基于系统策略提出多个行为选项,并通过应用一些优化标准来选择最佳的一个。

做出决定后,系统确定车辆必须执行的动作,以满足在规划层选择的行为,最后,控制值被发送到车辆控制层的执行器接口模块。

Photo by Bram Van Oost on Unsplash

在“自动驾驶汽车的端到端学习”一文中,Mariusz Bojarski 等人提出了一种 E2E 系统,能够直接从嵌入式摄像头提供的像素控制自动驾驶汽车5。该系统能够学习中间步骤的内部表示,例如检测有用的道路特征,仅使用人类转向角度作为训练信号。卷积神经网络(CNN)的使用在所提出的系统中起着重要的作用,因为它能够从图像数据中提取有用的特征:

“CNN 的突破是从训练样本中自动学习特征。CNN 方法在图像识别任务中尤其强大,因为卷积运算捕捉了图像的 2D 性质。”

设计的 CNN 超越了模式识别,学习驾驶汽车所需的整个处理流程。网络架构由 9 层组成,包括一个标准化层、5 个卷积层和 3 个全连接层。该系统使用在新泽西州中部、伊利诺伊州、密歇根州、宾夕法尼亚州和纽约收集的真实驾驶记录数据进行训练。下图显示了培训系统设计的框图:

Figure from Mariusz Bojarski et al. 5

凭借大约 72 小时的驾驶数据,该系统能够学习如何在不同的道路类型和天气条件下驾驶汽车:

“从不到 100 小时的驾驶中获得的少量训练数据足以训练汽车在各种条件下运行,包括高速公路、本地和住宅区道路,以及晴天、多云和雨天。CNN 能够从非常稀疏的训练信号(单独转向)中学习有意义的道路特征。例如,该系统在训练期间学习检测道路的轮廓,而不需要明确的标签。”

E2E 的局限性

如果在输入和输出之间使用单个 DNN 对上述例子有效,为什么不使用它作为解决所有机器学习问题的通用方法呢?

许多原因使得 E2E 在不同情况下不可行:

  • 大量的数据是必要的:将一些先前的知识结合到训练中被认为是在许多应用中提高性能的关键因素。对于没有整合这种先验知识的 E2E 学习,必须提供更多的训练实例。
  • 难以改进或修改系统:如果必须应用某些结构变化(例如,通过添加更多功能来增加输入维度),则旧模型没有用,必须更换和重新训练整个 DNN。
  • 高效可用模块无法使用:很多技术在解决某些任务时是高效的。例如,最先进的物体识别系统在很大程度上是分布式的,但是一旦它被集成到 E2E 系统中,它就不能再被认为是 E2E 了。
  • 难以验证:如果需要高级别的验证,E2E 可能变得不可行。由于复杂的架构,潜在的输入/输出对的数量可能大到无法进行验证。这对于像汽车工业这样的行业来说尤其重要。

除了这些问题之外,E2E 可能不适用于某些应用,如[1]所示:

“我们已经证明,对于训练由多个非*凡模块组成的神经网络模型来说,端到端学习可能非常低效。端到端的学习甚至会完全中断;在最坏的情况下,没有一个模块能够学习。相比之下,每个模块能够学习其他模块是否已经被训练并且它们的重量被冻结。这表明,复杂学习机器的训练应该以结构化的方式进行,首先训练简单的模块,并独立于网络的其余部分。”

结论

End-to-end 无疑是解决复杂任务的绝佳工具。使用单一模型专门从输入直接预测输出的想法允许开发可以被认为是最先进的极其复杂的系统。然而,每一种增强都是有代价的:虽然在学术领域受到推崇,但由于需要大量的训练数据和验证的困难,行业仍然不愿意使用 E2E 来解决其问题。

参考

[1] Glasmachers,Tobias。“端到端学习的局限性。” arXiv 预印本 arXiv:1704.08305 (2017)。

2刘易斯、迈克等人,《交易还是不交易?用于谈判对话的端到端学习。” arXiv 预印本 arXiv:1706.05125 (2017)。

[3]科洛伯特、罗南等,《自然语言处理(几乎)从无到有》机器学习研究杂志* 12。2011 年 8 月:2493–2537。*

4塞尔班、亚历山德鲁·康斯坦丁、埃里克·波尔和约斯特·维瑟。"完全自动驾驶汽车的标准驱动软件架构." 2018 IEEE 软件架构伴侣国际会议(ICSA-C) 。IEEE,2018。

5 Bojarski,Mariusz 等,“自动驾驶汽车的端到端学习” arXiv 预印本 arXiv:1604.07316 (2016)。

EagleView 使用 Keras 和 ArcGIS Pro 使用 Mask-RCNN/DeepLabV3+进行高分辨率图像语义分割

原文:https://towardsdatascience.com/eagleview-super-high-resolution-image-segmentation-with-deeplabv3-mask-rcnn-using-keras-arcgis-9be08caac42c?source=collection_archive---------19-----------------------

机器学习中的计算机视觉为 GIS 提供了巨大的机会。其任务包括获取、处理、分析和理解数字图像的方法,以及从现实世界中提取高维数据以产生数字或符号信息,例如以决策的形式。13在过去的几年里,计算机视觉正日益从传统的统计方法转向最先进的深度学习神经网络技术。

在这篇博客中,我将分享几个使用 Keras 和 ESRI ArcGIS Pro 工具以及深度学习和转移学习技术的经验实践,以从超高分辨率的 3 英寸 EagleView (Pictometry)影像构建建筑物足迹图像分割网络模型。

2018 年, ESRI 和微软与切萨皮克保护组织合作,训练深度神经网络模型,从 1 米 NAIP 分辨率航空影像数据源预测土地覆盖。该神经网络在架构上与 Ronnenberger 等人的 U-net ( 2015 )相似,是一种常用的语义分割模型。每年,佐治亚州科布县的 GIS 核心小组都会收到来自 EagleView(Pictometry)的 3 英寸超高分辨率正射影像。深度学习模型可以应用于这种超高分辨率的正射影像来分类土地覆盖或提取建筑物足迹吗?有几个挑战——超高分辨率图像通常呈现各种植被类型和重叠;建筑物和树木在图像中产生了浓重的阴影,这可能会对真实的地面物体进行错误的分类。

一开始,我非常保守,因为我决定使用一台只有 CPU 的笔记本电脑来训练大约 3800 幅图像。考虑到土地覆盖和建筑足迹的复杂性,这对于深度学习来说是一个相当小的数据集,因为如果你阅读教科书,经常会说深度学习需要大量的训练数据才能获得更好的性能。但这也是一个现实的分类问题:在现实世界中,即使是小规模的图像数据也很难收集,而且非常昂贵,有时甚至几乎不可能。能够使用小型数据集并训练一个强大的分类器是一个称职的数据科学家的关键技能。经过多次尝试和运行,结果证明非常有希望,特别是使用最先进的 Deeplabv3+和 Mask-RCNN 模型。

研究区域和训练图像数据集准备

fig.1 — Cobb County 2018 3in EagleView imagery covers with 433 1x1 mile tiles.

科布县的地理区域覆盖了分辨率为 3 英寸的 433 个 1 x 1 英里的图像切片。县 GIS 组在某些区域有一个建筑物覆盖区面图层。出于训练目的,选择了一个靠*县中心的图像切片作为图像训练数据集(图 1)。建筑物覆盖区面要素图层用于处理地面真实掩膜标注。ArcGIS Pro 2.4 版本中的“导出深度学习的训练数据”。地理处理工具的用于导出实例分割数据集的图像和掩膜(图 2)。输出图像的尺寸为 512x512x3,旋转角度设置为 90 度,以生成更多的图像来防止过度拟合,并帮助模型更好地泛化。

Fig. 2 — ArcGIS “Export Training Data for Deep Learning”

1。用 Mask-RCNN 模型训练

生成的训练数据集包含超过 18000 个图像和标签。通过进一步的数据处理以去除没有标记的图像,最终数据集具有超过 15000 个训练图像和标签。然而,在只有 32gb 内存的笔记本电脑上,不可能将如此大的数据集输入到 Mask-RCNN 模型中,这需要巨大的内存来进行训练。

训练策略是看看概念验证将如何工作,所以我逐渐增加数据集,以 3800 个数据集的试验馈入 CNN。

我使用了令人印象深刻的开源实现 Mask-RCNN 库,MatterPort 在 Github 上构建了这个库来训练这个模型。

Mask-RCNN 有效地检测图像中的对象,同时为每个实例生成高质量的分割掩模。该方法通过与现有的用于边界框识别的分支并行地添加用于预测对象遮罩的分支来扩展更快的 R-CNN5。可以阅读研究论文更好的理解模型。(图 3)。

fig. 3. — Mask R-CNN framework for instance segmentation. Source: https://arxiv.org/abs/1703.06870

需要在类(Utils.dataset)中修改三个主要函数,以将您自己的数据集加载到框架中。有关数据加载实现,请参见下文。锚的比率设置为(16,32,64,128,256)以预测较小的住宅建筑尺寸。IMAGES_PER_GPU 设置为=1,因此 CPU 可用于训练模型(图 4)。图像和遮罩的示例(图 5)。

fig. 4 — Load Cobb Pictometry datasets to Mask-RCNN framework.

fig. 5 — An example of a random image and mask from datasets.

这里,迁移学习技术应用于主干网 ResNet-101 模型。我首先用 epoch =5 训练最后完全连接的层,以适应住宅建筑类,然后用 35 个 epoch 训练整个网络。

在 32gb 的 CPU 上,完成训练过程需要将* 48 个小时(图 6 和图 7)。

fig. 6 — Model training result. The loss is reasonable good.

fig. 7 — Loss charts.

这里有两个推论,原始图像没有用于训练(图 8 和图 9)。有趣的是,推断面具比原始面具更准确地描绘了建筑。

fig. 8 — Original image that was not used in training

fig. 9 — Inference mask more accurately delineating the building than the original mask.

另一个有趣的例子是,一幅图像没有用于训练和屏蔽推断结果(图 10 和图 11)。

fig. 10 — An image that was not used in training.

fig. 11 — Inference instance masks.

fig. 12 — This is a cropped image and inference mask not used in the training. The orange line indicates the image cropped position. With 3000 training datasets, the result is very promising.

2。用 Deeplabv3+型号训练 T3

Deeplabv3+是由谷歌研究团队开发的最新艺术级语义图像分割模型。该模型的特点是级联或并行使用 atrous 卷积,通过采用多个 atrous 速率来捕捉多尺度背景(图 13)。

fig.13 — https://ai.googleblog.com/2018/03/semantic-image-segmentation-with.html

使用来自 ArcGIS 的相同训练数据集导出深度学习工具的训练数据,对图像和掩膜进行增强处理,并保存到 HDF5 压缩文件中,以便于加载到训练模型中(图 14)。

fig. 14 — A random example of image and mask.

我在 Github 这里使用了 Deeplabv3+的 Keras 实现。下面是 Keras 训练模型和主干 Mobilenetv2,它的参数比 Xception 模型少(图 15)。

fig.15 — Define DeepLabv3+model.

fig. 16 — Five epochs training result.

只有 5 个历元训练运行,结果非常有希望(图 16)。

fig. 17 — Training loss converged plot.

fig. 18 — Image and inference from trained year 2018 imagery of Deeplabv3+ model

我运行 Python 脚本对任意裁剪的 2064x1463 尺寸图像进行推理,该脚本裁剪并处理 16 张(512x512x3 dim)图像以获得推理栅格。(图 19)。随着对图像的进一步检查和推断,我们可以看到建筑物阴影的影响会降低建筑物边缘的准确性。

fig. 19 — A cropped 2018 EagleView image with inference raster (25 rasters of 512x512 dim)

使用相同的训练模型来预测 2019 年裁剪图像的相同区域,结果非常相似,只有微小的局部差异(图 20)。该模型确实有助于未来一年的图像推断。

fig. 20 — A cropped 2019 EagleView image with inference raster (25 rasters of 512x512 dim)

fig. 21 — 2018 inference raster overlay the original image.

将上述图像和推论添加到 ArcGIS Pro 后。(图 21)

上面的影像栅格被转换为面要素,然后使用 ArcGIS Pro 3D analysis 中的正则化建筑物覆盖区和适当的参数来正则化原始检测。(图 22)

fig. 22 — Use ArcGIS Pro Regularize Building Footprint tool to clean up building polygons.

然后,我用两张 20,000 x 20,000 尺寸的完整 2018 切片图像运行 python 推理脚本,这两张图像彼此相距约 3 英里。脚本裁剪并处理 1600 张(512x512x3 dim)图像以进行推理。使用 32GB RAM 的纯 CPU 笔记本电脑完成每个图块大约需要一个小时。参见(图 23)。有遗漏的分类建筑物主要是因为使用非常小的训练数据集和覆盖在建筑物顶部的树木。从该县的不同位置选择几个有代表性的瓦片作为训练数据集可以提高结果的准确性。

fig. 23 — Two complete tiles of EagleView 2018 image with inference raster (1600 rasters of 512x512 dim on each)

fig.24 inference raster overlay the image tile in ArcGIS Pro.

结论:

虽然它是一个相对较小的数据集,但 Mask-RCNN 和 Deeplabv3+深度学习模型都使用转移学习技术为超高分辨率图像分割提供了有希望的结果。由于原始建筑物覆盖区地面真实要素多边形的精度较低,以及笔记本电脑 CPU 和内存的限制,在某些图像分类和实例分割中,性能结果可能无法超越人类数字化仪。然而,这种深度学习训练过程的准确性可以通过增加来自该县不同位置的高质量训练数据集以及应用数据变化增强方法来进一步增强。该模型可用于多年影像以推断用于比较的要素检测,甚至可用于 ArcGIS 工具模型构建器的低成本要素描绘,以实现业务任务的自动化。更重要的是,上述深度学习训练过程可以应用于其他类型的图像实例或分割案例。( 请看我下一篇博客 )

1。赖因哈德·克莱特(2014)。简洁的计算机视觉。斯普林格。ISBN978–1–4471–6320–6。**

2。琳达·夏皮罗;乔治·斯托克曼(2001 年)。计算机视觉。普伦蒂斯霍尔。ISBN978–0–13–030796–5**

3。蒂姆·莫里斯(2004)。计算机视觉和图像处理。帕尔格雷夫·麦克米伦。ISBN978–0–333–99451–1。****

4。Bernd jhne;霍斯特·豪埃克(2000 年)。计算机视觉与应用,学生和从业者指南。学术出版社 书号978–013085198-7。****

5。 【明凯】格鲁吉亚彼得·多拉尔*罗斯·吉希克 (2018)。面具-RCNN https://arxiv.org/abs/1703.06870v3*****

6. Deeplabv3+ model,https://github . com/tensor flow/models/tree/master/research/deep lab

7。https://blog . keras . io/building-powerful-image-class ification-models-using-very-little-data . html

8。http://pro . ArcGIS . com/en/pro-app/tool-reference/image-analyst/export-training-data-for-deep-learning . htm

9。https://pro . ArcGIS . com/en/pro-app/tool-reference/3d-analyst/regulate-building-footprint . htm

10。https://blogs . TechNet . Microsoft . com/machine learning/2018/03/12/pixel-level-land-cover-class ification-using-the-geo-ai-data-science-virtual-machine-and-batch-ai/

11。U-Net:用于生物医学图像分割的卷积网络:https//lmb . informatik . uni-freiburg . de/people/Ron neber/u-Net/

耳朵生物识别—机器学习更进一步…

原文:https://towardsdatascience.com/ear-biometrics-machine-learning-a-little-further-1839e5d3e322?source=collection_archive---------9-----------------------

更精确的生物识别技术的领先创新。

Neural Networks (Image by Gerd Altmann from Pixabay)

像其他使用面部、虹膜和手指的生物特征一样,耳朵作为一种生物特征包含大量特定和独特的特征,允许进行人类识别。耳朵的形态在 10 岁后会有轻微的变化,医学研究表明,耳朵形状的显著变化只发生在 8 岁前和 70 岁后。随着年龄的增长,它的大小确实对称地增长,并开始向下凸出,但这是一个可测量的影响。研究表明,耳朵每年只变化 1.22 毫米。还有,耳朵的颜色分布和脸不一样,几乎是均匀的。耳朵的位置几乎在侧面脸的中间。甚至在对象从远处没有意识到的情况下,也可以捕获耳朵数据。人耳生物特征可以作为被动生物特征的一个很好的例子,并且不需要主体的太多合作,这满足了当前环境中认证系统的保密性要求。

数码相机从不同角度拍摄环境中对象的侧面人脸图像,从中分割、预处理耳朵部分。然后在不同的测试情况下分析特征向量,这些测试情况包括人脸在同一*面、不同*面、不同光照条件等的旋转。将作为输入提供给机器学习模型,该模型将被训练以识别环境中的人。该过程虽然复杂,但将开发一种系统,该系统将提供经认证的基于耳朵的生物识别系统。

受控环境

相机 A 的目的是在不期望耳朵有太大倾斜或旋转的情况下获得侧面脸部的清晰照片。同时,相机 B 和相机 C 用于为同一个人的多个图像捕获更多的侧面照片,以形成特征矩阵。

Environment

从侧面人脸分割耳朵—

Camera — A

图像(a)是从照相机捕捉的侧面脸。在图像(b)中,完成了地形标记。地形标记用于查找曲面和边缘。图像(c)是腐蚀和膨胀的差异,即对轮廓面应用形态学操作以锐化特征。图像(d)是(b)和(c)的简单点积。通过模糊(d) 10 次来获得图像(e ),从而可以应用连通分量分析。在图像(f)中,找到每个连通分量的复杂度,并用不同的
颜色进行着色。由于发现最复杂的区域是耳朵,为了更快的计算,将其分割并转换成图像(g)中的灰度。

Camera — B & C

数据集和预处理

数据集准备是任何机器学习模型的第一步。在该系统中,使用一个深度神经网络来获取环境中对象的特征和特性。需要一个大的数据集作为神经网络的输入。每个对象至少 500 个图像来适当地训练网络,因为所有类别都是耳朵机器的图像,很容易与特征和特性混淆,每个对象的样本越多,就越容易找到明显的特征。数据集应涵盖各种各样的图像,例如不同光照条件、不同角度、高斯滤波器、模糊等的图像。

DNN Architecture

在训练 CNN 网络的时候,有一些小的遮挡需要被覆盖,比如耳朵被头发、耳机或珠宝覆盖。图像增强有助于生成多份略有变化的图像副本,从而增加数据集。例如,可以使用 Keras 的数据发生器。

Dataset with slight variations

DATADIR = "./dataset"
CATEGORIES = ["Subject1", "Subject2", "Subject3", "Subject4"]

for category in CATEGORIES:
    path = os.path.join(DATADIR, category)

    for img in os.listdir(path):
        img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)
        break
    break

IMG_WIDTH = 60
IMG_HEIGHT = 100
new_array = cv2.resize(img_array, (IMG_WIDTH, IMG_HEIGHT))

training_data = []

def create_training_data():
    for category in CATEGORIES:
        path = os.path.join(DATADIR, category)
        class_num = CATEGORIES.index(category)

        for img in os.listdir(path):
            try:
                img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)
                new_array = cv2.resize(img_array, (IMG_WIDTH, IMG_HEIGHT))
                training_data.append([new_array, class_num])
            except Exception as e:
                pass

create_training_data()
print(len(training_data))

random.shuffle(training_data)

卷积神经网络

因为我们使用的是图像数据集(而不是。csv 文件或数字数据),在数据预处理完成后使用 CNN。预处理的数据被传递到神经网络的结构。由于耳朵的表面积小于面部,因此耳朵所需的计算时间也较少。灰度图像由网络的输入层获取。

CNN Architecture

Convolution

步幅卷积和最大池用于增加每个隐藏层的深度(特征)。

卷积滤波器减少 9 个图像像素以生成单个像素,而不影响特征。

a = []      #feature set
b = []      #labels

for features, labels in training_data:
    a.append(features)
    b.append(labels)

a = np.array(a).reshape(-1, IMG_WIDTH, IMG_HEIGHT, 1)

Depth Increase (Pixel decrease)

# Create the model
model = Sequential()

model.add(Conv2D(32, kernel_size=4, strides=1,activation='relu', input_shape=(IMG_WIDTH, IMG_HEIGHT, 1)))
model.add(Conv2D(32, kernel_size=4, strides=2,activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(64, kernel_size=4, strides=1,activation='relu'))
model.add(MaxPooling2D(pool_size=2))
# model.add(Conv2D(64, kernel_size=4, strides=2,activation='relu'))
# model.add(Dropout(0.5))
# model.add(Conv2D(64, kernel_size=4, strides=1,activation='relu'))
# model.add(Conv2D(64, kernel_size=4, strides=2,activation='relu'))
model.summary()

model.add(Flatten())
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4, activation='softmax'))
model.summary()

# Compile the model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# Train the model
model.fit(X_train, to_categorical(Y_train), batch_size=32, epochs=5)# Evaluate the model
scores = model.evaluate(X_test, to_categorical(Y_test))

print('Loss: %.3f' % scores[0])
print('Accuracy: %.3f' % scores[1])

model.save('model_opt.h5')

在最后的密集层中,完成特征分类(FC ),基于该特征分类将对象分类到网络的相应类别。

Training and testing

图表显示了深度神经网络的同一类的重叠曲线和不同类的不同曲线的精度。

Graph

Authorized user

Unauthorized user

限制

可能会有不同类型的遮挡情况,如头发、耳机或耳朵受伤或被布覆盖。个人获得认证的机会将变得更少。由于用于特征提取的纯耳百分比较小,因此精度会受到影响。该系统旨在关注小型环境房间,如安全室、董事会议、医学实验室等。

未来范围

耳朵是人体中最小的骨头。这对于网络罪犯来说很难复制。此外,它还可以用来测量温度、血流量、心率和葡萄糖水*。Ear 生物识别系统将在以下领域有多种用途:身份验证、访问和考勤控制、旅行控制、需要授权的金融和其他交易、远程投票、自动化工作设备的使用、行动控制。例如,如今机场使用面部和虹膜生物测定的组合来认证个人,相反,可以使用单耳生物测定系统来以相同的准确度实现个人的真实性。身体的每一个特征都会影响一个人的总体性格——脸、眼睛、手掌甚至笔迹。通过笔迹的个性分析被用于检测该人是否在说谎等。同样,耳朵可以用来分析一个人的性格。耳垂有很多可以用于性格分析的特征——附耳垂、宽耳垂、窄耳、尖耳、圆耳垂、方耳、耳突等。

总结

耳朵生物识别系统的最大优点是在人们不知情的情况下识别他们。这一特性将改变被动生物识别的动态,并可以在生物识别领域实现完全自动化。指向焦点—

  • 具有各种图像的大型数据集(每个受试者 500 个样本),用于正确训练学习模型。
  • 预处理图像以减少计算时间。
  • 良好的网络架构(没有太多损失或丢失)。
  • 运行足够多的历元来高效训练网络(建议用 GPU)。
  • 使用训练好的模型来精确地预测这个人。

恭喜你坚持到了最后。太棒了。点击这里从我的 GitHub 账户获取源代码。

请随意提问,因为我们正在学习和机器一样的东西..

参考文献—

  1. 闫*和凯文·w·鲍耶,IEEE 研究员,“使用 3D 耳朵形状的生物识别”,IEEE 模式分析和机器智能汇刊,第 29 卷,第 8 期,2007 年 8 月
  2. John D. Bustard,IEEE 学生会员,和 Mark S. Nixon,IEEE 准会员,“从二维图像进行不受约束的人耳识别”,IEEE 系统、人和控制论汇刊-A 部分:系统和人类,第 40 卷,第 3 期,2010 年 5 月
  3. 智能系统研究中心的比尔·巴努和惠辰。计算机人耳识别。加州:加州大学河滨分校【在线】。doi:10.1007/978–1–84800–129–9。
  4. Eyad Haj Said,北卡罗来纳州立农业技术大学,北卡罗来纳州格林斯博罗,Ayman Abaza 和 Hany Ammar,计算机科学和电气工程系。“使用数学形态学在彩色面部图像中进行人耳分割”,IEEE 2008。

推土机的距离

原文:https://towardsdatascience.com/earth-movers-distance-68fff0363ef2?source=collection_archive---------5-----------------------

语义搜索中文档相似性的语义度量

Photo by Luis Enrique Ruiz Carvajal on Unsplash

⚠️在我的博客⚠️中读到了的原帖

这是我最初的语义搜索帖子的续篇。这个是关于推土机的距离,可以应用在语义搜索上。

动机

语义搜索引擎从其本体中检索结果的方式是通过计算与查询最接*/最相似的文档。为了获得顶部最相似的文档,该算法计算查询和许多文档之间的距离。当获得相似性时,文档被相应地排序,并且位于顶部的文档被检索。

例如,假设本体有 5 个文档:

  • 查询:'我如何开始数据科学的职业生涯?'
  • 文档 1: 《烹饪的科学:如何做出一顿丰盛的饭菜》
  • 文件二:‘2019 年数据科学突破
  • 文档 3: ' 海洋生物学家获得数据科学工作的指南'
  • 文献 4:‘关于黑猩猩的数据是行为科学的基础’
  • 文档 5:‘数据科学是 21 世纪的顶级职业’

首先,我们计算查询和 5 个文档之间的距离,将具有最高相似性的文档返回给用户。

文档之间的这个距离是什么?人类可以很快知道哪个文档最适合这个查询,因为语言是我们与生俱来的,我们理解每个单词和整个句子的意思,我们甚至可以预测每个文档是关于什么的。简单的语法错误或稍微不同的词序不会影响我们的思维过程。

在几秒钟内,我们得出结论,文档#3 是最接*的:即使用户可能没有海洋生物学背景,海洋生物学家的经验可能会被证明是有用的。

但是计算机是如何计算两个句子之间的距离的呢?一个句子不仅仅是一系列单词:每个单词都有它的位置,有一个我们凭直觉理解的无形的潜在语法结构,因为我们从出生开始就接触语言,但计算机在历史上很难获得这种“直觉”。

一个简单的文档相似性度量是计算两个句子之间有多少共同的单词,而不考虑位置:

  • d(查询,文档 1) = 3(科学,如何,a)
  • d(查询,文档 2) = 2(数据,科学)
  • d(查询,文档 3) = 3 (a,数据,科学)
  • d(查询,文档 4) = 2(数据,科学)
  • d(query,doc5) = 4(数据,科学,职业,in)

根据这个标准,文档#5 是与查询最相似的文档。但是我们很快意识到有些词是不相关的,‘a’。how ',' in '等词并没有给句子增加意义。这些词被称为停用词,在大多数文本处理算法中会被删除。

词汇上的细微变化也不包括在这个指标中。动词的现在时与过去时、单数与复数、副词与形容词等。被认为是不同的词,而实际上,它们指的是几乎相同的术语。词干化、词汇化和标记化是获取单词词根形式的方法。

最后,文档#3 应该因为包含单词“job”而得分,在这个上下文中,它是“career”的同义词。“职业”和“工作”应视为等同物。,与文件#5 中的“职业”一词相同。在算法中包含同义词覆盖率可以大大提高性能。

如果我们深入挖掘,有人可能会说“我如何做 X”在意思上类似于“某人做 X 的指南”,尽管实现它是另一回事。

总之,使用语义文档相似性度量的动机是通过使用同义词、下义词等语义特征来改进现有的度量。

有许多文档相似性度量,词汇的和语义的。你可以读到他们中的许多人,更偏重于理论或更实用。

这篇文章是关于运土机的距离(EMD)的,这是一种语义方法,其中考虑了单词的含义和用户的意图。

推土机距离(EMD)

在 EMD 的情况下,文档之间的距离基于单词之间的语义距离,其中单词存储在称为 WordNet 的电子词汇数据库中。一旦获得单词之间的语义距离,EMD 通过单词之间的多对多匹配来计算文档相似度。也就是说,一个文档中的三个单词可能与另一个文档中的一个单词意思相同。[1]

1.定义

让我们从句子、单词和文档中抽象出来,假设文档是加权点的分布。分布是位置为和权重为的元组。

两种分布之间的 EMD 与将一种分布转换成另一种分布所需的最小工作量成比例。

1 单位是将一单位重量移动一单位距离所需的功。

2.直觉

直觉上,重量从一个分布流向另一个分布,直到它们相同,类似于用成堆的灰尘填充。一个分布充当一组孔,而另一个分布的点是污垢。2

Example 1

从空间中显示两个分布的初始点开始,一个分布被指定为灰尘的角色,而其他分布被指定为孔的角色,每个灰尘点被指定为孔的一个点(不一定每个孔的点都有一个灰尘点),并且灰尘反复地向孔“移动”,直到它填满孔。

移动灰尘的成本/ 工作取决于灰尘的重量/数量以及需要移动的距离。

点与点之间的地面距离度量可以是欧几里得,曼哈顿…但是不要把这个距离和单词之间的距离混淆。这个地面距离仅仅是维度空间中的点之间的距离。

Example 2

在示例#2 中,红色分布必须覆盖的距离大于示例#1 中的距离,因此需要更多的来“移动灰尘”。

EMD 算法的目标是优化如何分配权重,以使所有的灰尘覆盖所有的孔洞,同时将权重移动尽可能短的距离。

注意:在这种情况下,两种分布是*衡的,也就是说,污垢的数量等于孔的数量。一旦所有的洞都被盖住了,就不会有灰尘留下,或者一旦所有的灰尘都被放进去,就不会有多余的洞了。如果你想看到不*衡的分布,考虑阅读2。

有许多方法来分配权重,红色分布中最左边的脏点可以与蓝色分布中最低的洞点相匹配,但这不是很有效。计算 EMD 的一个步骤是获得两个分布之间最可行的流量

3.注释

符号和公式可以在我的演示文稿[0]的幻灯片中找到。我试着让这篇文章更加理论化和直观化,而不要过于深入数学。

4.流动

给定两个分布 x 和 y,它们之间的流是定义 x 和 y 之间的权重分布的任何矩阵 F。矩阵 F 中的每个点 f_ij 表示 x_i 处与 y_j 匹配的权重量。

注意:强调 any, a 流可以是任意的权重分布,无论是否有效。寻找有效/可行的流程是 EMD 所基于的优化问题。

寻找可行流:流 F 是可行的当且仅当它满足每个 f_ij 的以下约束:2

  1. f_ij 必须为正,匹配权重不能为负。
  2. 移动到孔 y_j 的重量不能超过 x_i 中存在的重量。最多可以移动污垢点中的所有污垢。
  3. 从污垢点 x_i 移动的重量不能超过 y_j 中存在的“孔”的量。孔中不能有污垢溢出。
  4. 在所有点上移动的所有重量必须是分布中的总重量。所有的灰尘必须盖住所有的洞,没错。没有污垢漂浮在周围,没有洞被覆盖。

满足这些要求的流程被认为是可行的。

5.工作

可行流在匹配 x 和 y 时所做的是 x 和 y 中每个点的匹配权重乘以距离

6.电机驱动的(electric motor-driven 的缩写)

推土机的距离是匹配 x 和 y 的最小工作量,由较轻分布的总重量标准化,但在这种情况下,两种分布具有相同的总重量,因此不存在较轻分布。功简单地除以一个分布的总重量。

优化问题是找到最小化工作的流。重量,所有的重量,都必须移动。但是哪个权值到哪个点,用什么量,取决于点与点之间的距离,这样权值就不用移动太远,这就是优化问题。

7.一些例子2

Example 3

关于工作的非最佳与最佳流程。在左边的场景中,0.26 重量(d=316.3)所覆盖的距离导致功如此之高。这个例子相当直观,最优流量相对容易获得。

Example 4

一个不太直观的例子,在这种情况下,分布中的总权重是不同的。所以要么会有脏物溢出,要么孔不会被完全盖住。

8。总结

推土机的距离是将一种分布移动/转换成另一种分布所需的距离。这些分布的两个特征是点在一个空间中,在例子中是 2D,并且每个点都有一定的权重。通过计算分配这些权重的最有效方式,我们得到一个表示 EMD 的数字。

9.EMD 作为文档相似性的语义度量

这与这篇文章要讨论的文档相似性的语义度量有什么关系?正如开头提到的,文档之间的距离是基于单词之间的语义距离,其中单词存储在一个称为 WordNet 的电子词汇数据库中。让我们试着将这个 WordNet 表示映射成点数和权重的分布:3

  • WordNet 是一个大型图形或语义网络,其中网络的每个节点代表一个真实世界的概念(房子、老师、艺术)。
  • 每个节点包括:
    一个 synset ,一组表示相同概念的同义词,以及
    一个 gloss ,一个真实世界概念的简短定义或描述。
  • 同素集之间的每个链接描述了同素集所代表的真实世界概念之间的一种语义关系(上义词、下义词、部分义词、全义词等)。

句子 X 可以被描述为点和权重的分布,其中:

  • 这些点是单词的 WordNet 表示(在长度为 N 的向量中,我们可以将其视为一个 N 维空间)
  • 权重是单词的 TF-IDF 值(显示单词对于文档有多重要的度量)。5

通过找到最小化工作以匹配 x 和 y 的流来计算 EMD,归一化为 1,并且如下获得文档相似度:

结论

推土机的距离是一种距离,其中 N 维空间中的点的位置和重量是关键的。

通过将单词转换为单词向量,将权重转换为 TF-IDF 值,EMD 可以用作文档相似性的语义度量。

与语义搜索的关系

EMD 可以用来计算查询和文档的语义相似度,从而在语义搜索的本体匹配阶段发挥作用。

字移动器的距离

WMD 是 EMD 的一个类似的、更新的变体,但是使用 word2vec 而不是 WordNet。它发布于 2015 年[6],有几个实现教程可用,对学习 measure 的实现方面非常有用。

为了我的演讲,我对这个话题进行了深入的研究,我希望我用一种清晰简洁的方式对它进行了总结。如果有什么解释得不够好,我很乐意再试一次。

我真的很感激任何反馈,不完整或错误的信息,我可能已经包括在内。感谢您的阅读!

参考

[0]: 语义搜索,2018 年我在 LMU 大学攻读硕士学位时发表的演讲幻灯片

[1]: 面向基于命名实体的相似性度量:挑战与机遇,De Nies 等人,2014

[3]: 将词典和语料库信息合并到语义相关度的上下文向量测量中,Pathwardan,明尼苏达大学,2003 年

[6]: 从单词嵌入到文档距离,Kusner 等,2015。

相关链接

  • 单词嵌入之间的单词距离
  • 字移动器的距离作为线性规划问题
  • 推土机的距离

请求原谅比请求许可更容易:一个简短的 Python 例子。

原文:https://towardsdatascience.com/easier-to-ask-for-forgiveness-than-permission-a-short-python-example-e115566a3b8c?source=collection_archive---------29-----------------------

一个简单的概念,可以帮助您避免重复解析所有给定的数据,而您只需要用一个小样本来交叉检查它们。

Photo by Pisit Heng on Unsplash

想象一下,你已经记下了你看过的电影,以及每部电影你看了多少次。

出于某种奇怪的原因,您将注释保存在 python 字典中:-),
其中键是电影标题,值是您观看电影的次数。

movies = {
...
'The Godfather' : 5,
'Pulp Fiction' : 2,
...
}

在某个时候,你决定你只想在你的字典里保留黑帮电影,而不是别的。
所以你得用黑帮电影清单来反复核对你的字典。

一种方法是获取字典键,并查看它们是否包含在给定的黑帮列表中。
这个结果到 O(k*n) 动作总计,如果我们在黑帮名单里有 k 值,在电影字典里有 n 值

gangster_list = [..] # k valuesfor key in movies.keys(): # n values
    if movies[key] in gangster_list:
        continue
    else:
        del movies[key]# O(k*n) actions in total

但是如果黑帮电影排行榜包含了 100 万部电影,其中你看过的黑帮电影接*大黑帮排行榜的末尾呢?

假设你已经看了 10 部黑帮电影。
上面的‘in’检查将导致对你所观看的每部电影的几乎整个黑帮列表进行解析,结果是:
O([列表中的 1m 个值] * [观看的 10 部黑帮电影]) = O(10m)个动作。

反而是请求原谅比请求允许更容易!

我们可以用 O(k)行动的成本从大黑帮名单中产生一个虚拟字典:

gangster_dic = {}
for movie in gangster_list:
    gangster_dic[movie] = None

而黑帮字典的内容将会是:

{ # k keys without values
...
'Goodfellas' : None,
'The Untouchables' : None,
...
}
del gangster_list # To balance used memory

现在,我们可以直接搜索每个观看过的电影名称:

for key in movies.keys(): # n values
    # O(1) action
    try:
        gangster_dic[key]
        # do nothing: this is a gangster movie
    except KeyError:
        del movies[key]
        # delete the movie, since we did not find it in the   
        # gangster movies dictionary

如果我们失败了,没什么大不了的;我们处理异常。

这其实是我们想要的:为了例外发生而删除了一部我们看过的电影,那不是黑帮片。

总的来说,动作的成本是:
O(k)用于字典,加上
O(n * 1)用于检查所观看的电影在黑帮电影集合中是否存在,
导致总共 O(k+m) 个动作。

如果我们再次假设,k=1m,n=10,那么我们总共得到(1m+10) = O(1m)个动作。

我们将所需行动从最初的 1000 万减少到了 100 万!或者总的来说需要的动作少了#n 倍!

请求原谅比请求许可容易这个概念多次对我派上用场。我希望你也会发现它很有用!

使用 PySpark 轻松查询 Python 中的 ORC 数据

原文:https://towardsdatascience.com/easily-query-orc-data-in-python-with-pyspark-572749196828?source=collection_archive---------25-----------------------

Photo by Eric Han on Unsplash

优化的行列(ORC)是一种面向列的数据存储格式,是 Apache Hadoop 家族的一部分。虽然 ORC 文件和处理它们通常不在数据科学家的工作范围内,但有时您需要提取这些文件,并使用您选择的数据管理库来处理它们。

最*,我遇到了一种情况,我想处理一些以 ORC 格式存储的对象数据。当我把它读出来时,我不能直接把它写到数据帧中。我想分享一些以 ORC 格式获取数据并将其转换成更容易接受的格式的技巧,比如熊猫数据帧或 CSV。

为此,我们将利用 Pyspark。如果你刚刚开始使用 Pyspark,这里有一个很棒的介绍。在本教程中,我们将快速浏览 PySpark 库,并展示如何读取 ORC 文件,并将其读出到 Pandas 中。

我们将从终端内部安装 PySpark 库

Pip install pyspark

从这里,我们将引入 PySpark 库的两个部分,SparkContext 和 SQLContext。如果你是 Spark 新手,那么我推荐这个教程。您可以将 SparkContext 视为所有 Apache Spark 服务的入口点,也是我们 Spark 应用程序的核心。SQLContext 被认为是 Spark SQL 功能的入口点,使用 SQLContext 允许您以一种熟悉的、类似 SQL 的方式查询 Spark 数据。

from pyspark import SparkContext, SQLContext
sc = SparkContext(“local”, “SQL App”)
sqlContext = SQLContext(sc)

你可以在上面的代码中看到,我们还为 SparkContext 声明了一些细节。在这种情况下,我们说我们的代码在本地运行,我们给它一个 appName,在这种情况下我们称之为“SQL App”。

一旦我们创建了 SparkContext(这里称为 sc ),我们就将它传递给 SQLContext 类来初始化 SparkSQL。

至此,我们已经安装了 PySpark 并创建了 Spark 和 SQL 上下文。现在到了重要的一点,读取和转换 ORC 数据!假设我们将数据存储在与 python 脚本相同的文件夹中,它被称为“objectHolder”。要将它读入 PySpark 数据帧,我们只需运行以下命令:

df = sqlContext.read.format(‘orc’).load(‘objectHolder’)

如果我们想把这个数据帧转换成熊猫数据帧,我们可以简单地做以下事情:

pandas_df = df.toPandas()

综上所述,我们的代码如下:

from pyspark import SparkContext, SQLContext
sc = SparkContext(“local”, “SQL App”)
sqlContext = SQLContext(sc)
df = sqlContext.read.format(‘orc’).load(‘objectHolder’)
pandas_df = df.toPandas()

现在我们有了。只用几行代码,我们就可以读取一个本地 orc 文件,并将其转换成我们更习惯的格式,在这个例子中,是一个熊猫数据帧。

使用 Python 轻松抓取和总结新闻文章

原文:https://towardsdatascience.com/easily-scrape-and-summarize-news-articles-using-python-dfc7667d9e74?source=collection_archive---------11-----------------------

There’s lots of news to read and lots of coffee to drink!

在今天的数字世界中,我们被无尽的信息轰炸。我们有无限滚动的社交媒体和 24 小时新闻循环。因此,有大量的新闻需要关注,我们必须能够快速消化!

因此,让我们来做一个练习,将新闻文章压缩到更容易理解的大小。

我们将使用 requestsBeautifulSoup 包抓取一篇示例文章,然后我们将使用优秀的 gensim 库对其进行总结。你可以通过在我的 Github 上下载这个 Jupyter 笔记本来参与互动。

让我们开始吧!

# Imports
import requests
from bs4 import BeautifulSoup
from gensim.summarization import summarize

现在我们来挑选一篇有趣的文章:

Link - I want to read it. But I bet it’s TOO long!

现在我们有了一篇文章,我们将检索它的内容:

# Retrieve page text
url = '[https://www.npr.org/2019/07/10/740387601/university-of-texas-austin-promises-free-tuition-for-low-income-students-in-2020](https://www.npr.org/2019/07/10/740387601/university-of-texas-austin-promises-free-tuition-for-low-income-students-in-2020)'
page = requests.get(url).text

网页抓取:

现在我们刮吧!

首先,我们将把页面内容转换成一个 BeautifulSoup 对象,这将允许我们解析 HTML 标签。

# Turn page into BeautifulSoup object to access HTML tags
soup = BeautifulSoup(page)

然后,我们需要找出哪些 HTML 标签包含文章的标题和正文。对于一个伟大的 HTML 入门,看看HTML.com。

为此,我们将使用 Google Chrome 出色的 Inspect 工具。在新标签中打开我们选择的新闻文章,在页面上点击右键,从下拉菜单中选择 Inspect 。这将调出检查工具,如下所示:

If for some reason you’re not using Chrome, now’s the time to start

单击上面概述的小按钮,找到与您在页面上看到的任何内容相对应的 HTML 标签。

当您将鼠标悬停在页面上您想要选择的文本上时,在本例中是文章的标题和正文,您将看到哪些 HTML 标签用于标识该文本。

Headline is identified with the

tag

文章标题被

标签包围。我们将选择页面上的第一个

标签,如下所示:

# Get headline
headline = soup.find('h1').get_text()

文章的正文由

标签包围。这一次我们必须找到页面上包含的< p >标签中的所有标签,因为文章的每个段落都包含在一个< p >标签中。

# Get text from all <p> tags.
p_tags = soup.find_all('p’)
# Get the text from each of the “p” tags and strip surrounding whitespace.
p_tags_text = [tag.get_text().strip() for tag in p_tags]

如果您检查我们在' p_tags_text' 变量中检索到的文本,您会注意到有些文本不是来自主文章,比如作者的名字和一些图像标题。因为它们也是用< p >标签描述的,所以我们也选择了它们。为了清理我们所拥有的文本,我们可以使用一些快速列表理解来过滤掉我们所知道的不属于主要文章的文本类型。

在本文中,图像标题包含换行符' \n '来添加空格。因为我们知道文章中的实际句子不会有随机的换行符,所以我们可以安全地删除它们。类似地,我们可以删除不包含句号的文本,因为我们知道文章中任何合适的句子都会包含句号。这将漏掉作者的名字和其他一些不相关的信息。

# Filter out sentences that contain newline characters '\n' or don't contain periods.
sentence_list = [sentence for sentence in p_tags_text if not '\n' in sentence]
sentence_list = [sentence for sentence in sentence_list if '.' in sentence]
# Combine list items into string.
article = ' '.join(sentence_list)

总结:

现在我们有了文章的正文,我们可以对它进行总结了。

Gensim 是一个用于各种 NLP 任务的优秀 Python 包。它包括一个相当强大的摘要功能,易于使用。它是基于本文 ( 文档)的发现的 TextRank 算法的变体。正如您将看到的,我们可以在一行代码中使用它:

summary = summarize(article_text, ratio=0.3)

That’s pretty good!

你有它!我们已经检索了文章的标题,并创建了内容摘要。现在你可以用大约 1/3 的时间理解文章的主旨,然后继续你的一天。

在我的下一篇文章中,我将通过创建一个命令行实用程序来扩展这个功能,该实用程序可以抓取和总结一篇文章,并自动将摘要通过电子邮件发送给您自己。敬请期待!

从简单到复杂的简单、引人入胜的条形图

原文:https://towardsdatascience.com/easy-bar-charts-from-simple-to-sophisticated-7270c03eced8?source=collection_archive---------15-----------------------

通过数据可视化讲述您的故事

想象一下生成数据可视化的最简单的代码。让我们从一个我们都见过并且都需要的形象化的条形图开始。

Beach bar chart, horizontal orientation.

条形图中的每个条形代表一个变量的类别或级别,该变量具有相对较少的唯一值,例如公司的各个部门。每个条形的高度对应于我们分配给该类别的数字。这个数字可以代表很多东西,例如,对于每个部门,雇员的*均工资,或者雇员的数量。

我们需要指令来创建一个如此简单的条形图,以至于计算机可以直接读取我们的想法。我们希望我们的默认可视化在没有编程的情况下看起来很棒。我们宁愿把时间花在分析和解释上,甚至(有时)做一些完全不同的事情,而不是弄清楚编码语法和调试。

最小的计算机输入应该提供最大的有用的计算机输出。

无论您是 R 专家还是 Python 专家,或者根本不是专家,都没有什么区别。为了简单起见,我们将条形图函数命名为BarChart。一个简单的函数调用就是一个简单的函数调用,不管是什么语言,所有人都可以访问。BarChart包含在我的 lessR 包中,是 R 生态系统的一部分。

数据帧

从哪里开始?

数据分析分析组织成表格的指定变量的数据值。

将您的数据值存储在数据表中。每一列都包含单个变量的数据值,例如下面的一些雇员的 Excel 表。

First six rows of data of a data table with an ID field and four variables: Years, Gender, Dept, and Salary.

用相对较少的非数字类别定义数据表中的每个分类变量,比如性别和部门。其他变量有连续的数值,如薪水。每行包含单个雇员的数据值。空白单元格表示缺少数据。

我们访问这种数据表的通用结构,无论是用 R 语言、Python 语言,还是在第一个广泛可用的数据分析系统中,都可以追溯到 20 世纪 70 年代初我的大学时代。当时,我在 IBM 360 大型机上用穿孔卡运行 SAS 和 SPSS 版进行数据分析,玩得很开心。你知道,在我们有那些连接到主机的高级终端之前,我们可以在屏幕上打字,更不用说携带我们自己的电脑了。从一开始,我们就将数据组织成分类变量和连续变量的数据表。

要开始分析,请将数据表中的数据值从某个外部文件(位于您的计算机系统或网络上)读取到存储在您正在运行的应用程序中的数据结构中。r 和 Python 把这个数据结构叫做数据帧。我们正是从数据框架开始数据分析的。

一个简单的读取函数,不出所料地被命名为Read,也是 lessR 包的一部分。Read用相同的函数调用将 Excel、text csv 逗号或制表符分隔、SAS、SPSS 或 R 数据文件读入 R 数据框。计算机不是完全哑的,所以让它弄清楚文件的类型。Read还提供各种输出来帮助你理解你的数据,并确保它被正确读取。

要使用,在响应 R 命令提示符>时,输入带数据位置的Read,用引号括起来。将输出定向到数据框。在这里,从文件的网址读取上图中引用的完整 Excel 文件。为简单起见,将我们新创建的数据框称为 d,是所有 lessR 数据分析函数的默认数据框名称。

d = Read("[http://web.pdx.edu/~gerbing/data/employee.xlsx](http://web.pdx.edu/~gerbing/data/employee.xlsx)")

要在您的计算机系统上浏览数据文件,而不是位置,不要在引号之间放置任何东西。

基本条形图

现在,我们有了编写最简单的函数调用所需的信息,可以创建每个部门中雇员数量的条形图。

从可视化函数创建可视化,该函数将数据作为变量名称引用。

这就是我们的函数名和我们希望绘制以获得条形图的变量。

默认条形图

要获得默认条形图,运行 R 应用程序(参见最后一节),访问 lessR 函数,读取您的数据,然后输入以下内容以响应 R 命令提示符,>。

BarChart(Dept)

如果你把你的数据框命名为 d ,就是这样。如果您愿意,可以包含参数 data ,这是一个名为 d 之外的数据帧所必需的。

BarChart(Dept, data=d)

无论哪种方式,得到以下可视化。

BarChart标注每个条形,如每个部门员工的百分比。从我们的可视化中,我们看到销售部门的员工比任何其他部门都多,占所有员工的 15%或 42%。金融从业人员最少,只有 4 人,占全部从业人员的 11%。

我们的默认条形图避免了枯燥的灰色。我们想要颜色,但不是任何颜色。我们希望防止一些条形(如亮红色)比其他条形(如深蓝色)更明显的感知偏差。条形图中的所有颜色都具有相同的亮度和强度。如果我们将彩色条纹放入 PhotoShop 等照片处理应用程序,并转换为灰度,所有条纹的灰度都相同。

我们想要许多易于实施的选项。如果我们愿意,可以水*翻转条形,或者用绘制的数值(这里是计数,而不是百分比)标记条形,或者完全关闭标记,甚至用灰色标记。我们希望所有这些选项都可以工作,而不必编写更多的代码行。

在创建我们伟大的图形时,我们可能会得到一些附带的统计输出。对于我们的条形图,自然输出是频率分布,我们的分类变量的每个类别的计数和比例。还包括相等类别比例的卡方检验。

进一步简化条形图函数调用的唯一方法是缩写。我们有。如果你厌倦了键入BarChart,就用bc,比如bc(Dept)

水*条形图

为了定制超出默认范围的代码,我们不想编写更多的代码。相反,请指定参数值。例如,要水*翻转图表,将参数 horiz 设置为 TRUE

BarChart(Dept, horiz=TRUE)

重新排列类别

默认情况下,R 按字母顺序排列类别。如果顺序是任意的,或者是按字母顺序排列的,这种方法就可以,否则就不行。

按数值对类别进行排序

一种重新排序的方法是使用参数 sort 按数值对类别进行排序。将值设置为“+”进行升序排序,或者设置为“-”进行降序排序,最大值优先。

BarChart(Dept, sort="-")

定义类别的任意顺序

r 可以将一个分类变量表示为一个因子,它允许对类别进行任何排序。用 R factor函数转换成一个因子,或者更简单更通用的 lessR 版本factors。用级别参数指定类别或级别的顺序。

在这里,将变量 Dept 转换为默认 d 数据框中的 R 因子,其中类别排序为财务第一,管理最后。然后将创建的因子保存回 d 数据框。同样,如果要转换的变量不在 d 数据框中,包括数据参数。

d = factors(Dept, levels=c("FINC", "MKTG", "SALE", "ACCT", "ADMN"))
BarChart(Dept)

现在条形图中的条形遵循指定的顺序。

两个分类变量的条形图

要向条形图添加第二个分类变量,请在函数调用中引用第二个变量的名称。

堆积条形图

同样,为了简单起见,让我们用来命名参数来表示第二个分类变量。

BarChart(Dept, by=Gender)

对于下面的条形图,条形图的大小与 just Dept 的第一个条形图相同,但现在每个条形图都分成两个部分。每种性别的部分相互堆叠,形成一个堆叠条形图

与前面的 just Dept 条形图一样,每个条形的高度对应于相关部门中的雇员数。现在我们有了额外的信息,每组变量的百分比。例如,销售部门的女性占 14%,这是基于整个分析中的员工总数。

并排条形图

你更愿意并排看到每个性别的条形图来强调他们的相对影响力吗?参数的时间在旁边。

BarChart(Dept, by=Gender, beside=TRUE)

BarChart不列出具有最小值的条形的百分比值。

百分比堆积条形图

另一个演示侧重于这些数据值在每个部门中的男女比例,它代表第一分类变量的每个类别中的所有数据值。对应的条形图是一个堆积的 100%条形图,用参数 stack100 表示。

BarChart(Dept, by=Gender, stack100=TRUE)

对于这种类型的条形图,所有的条形高度相同。每个条形代表第一个分类变量的每个类别中的所有数据值。

在这里,我们看到销售领域的男性人数是女性的两倍,分别为 67%和 33%,营销领域的女性人数比男性多得多,分别为 83%和 17%。

超过个计数的条形图

条形图与类别相关联的数字超出了计数的范围。对于垂直条形图,在水*轴或 x 轴上绘制分类变量的值。在纵轴或 y 轴上绘制数字。在前面的例子中,我们提供了变量 Dept 的值 x ,由此BarChart将计数计算为变量 y 的值。因此,前面的函数调用没有指定一个 y 变量。

绘制数值变量在不同类别中的*均值

为了绘制不同级别部门的可变工资的*均值,通知BarChart变量y-是基于工资的。用参数 stat 表示 yx 类别汇总的统计量。在这里画出每个部门的*均工资。

BarChart(Dept, Salary, stat="mean")

明确地说,包括 xy 参数的名称,在BarChart函数调用中写入x=Depty=Salary。或者,键入 less,如本例所示,并删除参数名。无论哪种方式,我们得到以下可视化。

除了“mean”,我们还可以选择统计数据“sum”“sd”“dev”“min”“median”“max”

“dev”表示每个类别相对于 y 变量*均值的偏差分数。绘制偏差分数强调了数值变量在类别间的差异。

BarChart(Dept, Salary, stat="dev")

在这个例子中,我们看到*均工资最高的是行政部门,*均来说,会计师的工资最低。

与典型的数值一样,更具信息性的可视化是根据它们的大小进行排序。我们再次调用排序选项。我们还包括一个新选项, fill_sort ,它为条形提供了两种颜色,在这里以 0 分割,以区分正负偏差。

BarChart(Dept, Salary, stat="dev", sort="+", fill_split=0)

跨类别按变量比较的级别

公司各个部门的男女*均工资有什么不同?现在我们把它们放在一个函数调用中。将第一个分类变量 x (部门)、数字变量 y (薪水)、第二个分类变量 by (性别)包括在一起,并指出 y 到每个类别组合*均值的转换。

BarChart(Dept, Salary, by=Gender, stat="mean", beside=TRUE)

当比较不同级别的*均值时,将级别绘制为相邻的条形可能更有意义,因此将参数旁边的设置为

BarChart的文本输出还包括标绘*均值的具体值。没有直接在横条上写数值的空间。

式样

对于特定的应用,你需要这些灰色吗?灰度和许多其他样式选项是可用的,太多了,无法在这里全部讨论。事实上,可视化的任何方面都可以定制。最有影响的两个参数是填充、用于区域的颜色,例如条和点,以及颜色、用于区域的边缘颜色,包括线段本身。

为了让我们的灰色不那么无聊,绘制一个从浅到深的灰度调色板。 lessR 包提供预定义的调色板,例如用于一系列灰色的“grays”。以 30 度的增量遍历色轮定义了其他 lessR 调色板:“reds”“rusts”browns”“greens”“emeralds”“turquoises”“aquas”“blues”“purples”“violets”“magentas”

BarChart(Dept, Salary, by=Gender, stat="mean", fill="grays")

性别在这些数据中只有两个值,因此结果条形图跨越两种颜色的灰色。

样式的另一个选项是改变整个地块的基本颜色主题,例如使用主题参数,但是我们将这个讨论留到下次。

统计数据表

之前说明的数据表包含记录的数据值,有时称为原始数据测量数据。所有之前的BarChart示例都是从读入数据框 d 的原始数据中创建可视化。从原始数据中,BarChart为您计算汇总,如计数或*均值,然后绘制计算值。

另一种可能是数据已经汇总。也许原始数据值甚至不可用。也许你在网上的某个地方看到了一些统计数据,现在你想要相应的条形图。

BarChart可以直接处理输入的统计汇总。BarChart将输入的数据评估为原始数据值或统计汇总,如计数或*均值。如果数据是原始数据值,则首先计算适当的统计概要。显示的条形图来自输入或计算的适当统计摘要。

例如,要直接从两个分类变量的列表计数中创建条形图,将相应的交叉列表作为数据表读入 R 数据框,通常再次命名为 d

其他都没变。BarChart函数调用与处理原始数据值时相同。当然,要确保在函数调用中包含分类变量和数值变量,如果需要的话,还可以通过包含分类变量。

所有的条形图

一个数据表可以,而且经常有许多变量,分类变量和连续变量的混合。数据分析通常始于检查分析中每个变量的分布,由每个分类变量的条形图表示。为了获得所有的条形图,不提供数据引用,即不通过变量提供 x,y,。如果您接受所有其他默认值,这意味着只有括号,根本没有输入值。

BarChart()

结果是数据框中每个分类变量的条形图和频率表。在开始分析之前,使用前述的factorfactors函数正确定义分类变量,以指定所选条形图的分类顺序。

让它发生

两个占主导地位的开源数据科学应用程序 R 和 Python 有时被视为竞争对手。与生活中的许多事情一样,计算机应用程序更倾向于相互合作。

r 和 Python 想成为朋友。

充分利用各自的优势,与同事一起工作,不管他们更喜欢 R 还是 Python。例如,在机器学习方面,很难比 Python 做得更好。并且很高兴在 r。

你更喜欢用 Python 来做数据清理和预处理,即数据分析中耗时的数据争论阶段吗?如果是这样,在您完成所有工作后,对 Python pandas [to_csv](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_csv.html)函数的简单函数调用将指定的清理数据帧写入一个 csv 文件。从那里,数据可以很容易地转移到任何数据分析系统中,比如使用前面提到的来自我的 lessR 包中的Read函数。

如果您像大多数分析师一样,从 RStudio 运行 R,您会得到通常的 R 控制台,但也会有一个用于可视化的专用窗口,可以访问您的文件目录等等。RStudio 还支持在同一个分析中混合使用 R 和 Python 代码。r 函数甚至可以直接访问 Python 数据帧,反之亦然!语言之间的障碍正在消失。

下载 r .选择 Windows ,或者 Mac (点击页面下方几段的链接,左边空白处)。

下载 RStudio 。选择第一个选项,RStudio 桌面,开源许可。

要访问 lessR 包中的功能,比如BarChart,你首先需要从官方的 R 服务器上下载这些功能。只有一次,当运行 R 时,输入以下内容进行下载。

install.packages("lessR")

你将自动下载 lessR 函数和数据集,以及几个依赖包。

从那时起,为了开始每个 R 会话,用library函数加载 lessR 函数。下面是一个完整的三行程序,它根据数据框中指定变量 Dept 的数据值创建一个条形图。在本例中,我们读取的数据与之前的员工数据文件相同,但是来自一个内置的 lessR 数据集——如果您想找点乐子,需要一些数据,并且不在互联网上,这很方便。

library("lessR")
d = Read("Employee")
BarChart(Dept)

它不是火箭科学。当然,一旦将数据值读入 R,就可以创建许多数据可视化和其他分析。

所以你有它。未来的文章将展示简单获得的其他可视化效果,包括对称为 Likert scales 的调查项目的响应的专用条形图。享受你的条形图吧。

要了解更多关于数据可视化的知识,使用 lessR 和其他可视化系统,请查看我在 CRC 出版社出版的 2020 年出版的书,R Visualizations:Derive Meaning from Data

使用 Datasist 实现简单的数据分析、可视化和建模(第 2 部分)

原文:https://towardsdatascience.com/easy-data-analysis-visualization-and-modeling-using-datasist-part-2-d2ce7fbf79e3?source=collection_archive---------33-----------------------

使用 datasist 库进行快速有效的数据分析

datasist logo

在这篇文章的第一部分,我们讨论了 datasist 中五个模块中的三个(structdata、feature_engineering 和 timeseries)。在这一部分,我们将讨论最后两个模块(可视化和模型)。

所以事不宜迟,让我们开始吧。

你将从这篇文章中学到什么:

  1. 使用 datasist 轻松实现可视化。

类别特征的可视化。

数字特征的可视化。

2.用 datasist 测试和比较机器学习模型。

在我们开始之前,让我们导入将用于该分析的数据集和库。如果你刚刚加入我们,我建议你阅读这篇文章的第一部分,这样你就能有效地跟进。

使用 datasist 轻松实现可视化

可视化模块是 datasist 中最好的模块之一。有很多功能可以让你用最少的代码创造出美观多彩的情节。在这篇文章中,我将重点介绍一些最重要的功能。

注意:可视化模块中的所有功能都在数据尺度上工作,而不是在特征尺度上。这意味着,您可以传入完整的数据集,并获得开箱即用的每个要素的可视化效果。还可以指定要打印的要素。

类别特征的可视化

分类特征的可视化包括柱状图、计数图等。让我们回顾一些可用的功能。

  1. boxplot: 该函数根据指定的分类目标列绘制所有数字特征的方框图。箱线图(或盒须图)以一种便于变量之间或分类变量水*之间比较的方式显示定量数据的分布。

注意:通过将 save_fig 参数设置为 True,可以将 datasist 生成的任何图保存为当前工作目录中的. png 文件。

ds.visualizations.boxplot(train_df, target='Claim')

2.cat box:cat box 功能用于根据指定的分类目标绘制数据集中所有分类特征的并排条形图。这有助于识别原因和模式,也有助于识别正确区分目标的特征。

注意: catbox 将只绘制具有有限数量的唯一类的分类特征。

ds.visualizations.catbox(train_df, target='Claim')

3.计数图:计数图简单地绘制了所有分类特征的柱状图,以显示它们的类别计数。

ds.visualizations.countplot(train_df)

数字特征的可视化

数字特征的可视化包括散点图、直方图、kde 图等。我们可以使用 datasist 中可用的函数在数据范围内轻松做到这一点。下面我们来回顾一下其中的一些。

4。直方图:这个函数绘制一个数据集中所有数字特征的直方图。这有助于显示特征的分布。

注意:要使用该功能,指定的要绘制的特征不能包含缺失值,否则会抛出错误。

在下面的示例中,要素 Building Dimension 和 Date _ of _ Occupancy 都包含缺失值。我们可以决定在绘图之前填充这些特征,或者我们可以传入我们想要的特征列表。

我会选择第一个选项,即填充缺失的值。

#fill the missing values 
df = ds.feature_engineering.fill_missing_num(train_df)ds.visualizations.histogram(df)

2.散点图:该函数根据指定的数值目标,绘制数据集中所有数值特征的散点图。它有助于显示特征之间的相关性。

feats = ['Insured_Period',
         'Residential',
         'Building Dimension',
         'Building_Type',
         'Date_of_Occupancy']ds.visualizations.scatterplot(train_df,num_features=feats, 
                                target='Building Dimension')

5。plot_missing: 顾名思义,这个函数可以用来可视化数据集中缺失的值。白色单元格表示缺失,黑色单元格表示未缺失。右上角的颜色范围显示缺失的强度。

  1. autoviz : Autoviz 是懒人的终极可视化功能。使用这个函数,您只需一行代码就可以可视化任何数据集。

要在 datasist 中使用 autoviz,首先必须安装 autoviz 包。要通过 pip 安装,请使用以下命令。

pip install autoviz

现在,让我们演示如何在 datasist 中使用 autoviz。

ds.visualizations.autoviz(train_df)

那不是很值得一看吗?只用一行代码就能快速完成任务,这真是令人惊讶。

可视化模块中可用的其他功能有 plot_auc、plot_confusion_matrix、violin_plot 等。要了解这些功能的更多信息,请访问此处

用 datasist 测试和比较机器学习模型

模型 模块包含测试和比较机器学习模型的函数。当前版本的 datasist 仅支持 scikit-learn 模型。我将重点介绍本模块中的一些重要功能,并演示如何使用它们。

首先我们从数据科学尼日利亚获取一个数据集,2019 新兵训练营竞赛页面这里 。任务是根据建筑观察预测保险索赔(1 =索赔,0 =无索赔)。我们会做一些基础的数据预处理,为建模做好数据准备。

注意:这个分析的目标是演示如何使用 datasist 中的模型模块,所以我们不会做任何繁重的特性工程。

接下来,让我们看看特性定义,以了解变量。

接下来,我们做一些处理。首先,我们删除 Id 列(客户 ID ),然后填充缺失的数字和分类特征。

现在我们有了一个正确填充的数据集,我们将根据唯一类的数量使用标签编码或一种热编码对所有分类要素进行编码。

#check the unique classes in each categorical feature
ds.structdata.class_count(train)

我们将标记 encode Geo_Code,因为唯一的类很大,而 one-hot-encode 其余的类。

现在,让我们讨论一下模型模块中可用的函数,我们可以在处理过的数据集上使用这些函数。

  1. compare_model :这个模型将多个机器学习模型作为参数,并返回一个显示每个模型性能的图。这可用于选择基础模型以进行进一步优化。 compare_model 也返回一组训练好的模型和它们相应的分数。

现在,让我们看看这个函数的运行情况。我们将比较三种模型(RandomForest、LightGBM 和 XGBoost)。

注意:在这篇文章中,我们不会执行任何高级超参数调整。目标是向您展示如何使用 datasist 中可用的函数,而不是大量的超参数调优。

此外,在尝试这一部分之前,您必须安装 lightgbm 和 xgboost。或者,您可以使用 scikit-learn 中的默认模型。要安装 lightgbm 请转到她的 e ,要安装 xgboost, 请转到这里。

从结果图来看,LGBMClassifier 是目前最好的模型。假设我们对这个模型满意,我们可以通过访问返回的模型列表进行预测。

pred = models[1].predict(Xtest)

2.get _ class ification _ report:我们可以通过get _ class ification _ report函数得到一个分类任务的详细指标报告。它接受预测类和真值作为参数。

ds.model.get_classification_report(pred, ytest)

3.plot _ feature _ importance:该函数将数据集中最重要的特征绘制成一个条形图,供训练模型使用。

注意:我们用一个分类问题演示了这里的例子。您可以将相同的函数应用于您的回归问题,它会工作得很好。

查看 API 文档 了解模型模块中可用的其他功能。

而我们已经到了这篇文章的结尾。我相信你现在很渴望在你的下一个项目中使用 datasist。

随着我们添加更多功能,datalist 将会继续发展。如果你想让它变得更好,请查看我们的投稿指南这里,如果你想报告一个 bug 问题或对一个功能有想法,请访问我们的 GitHub 问题页面这里。如果这个项目对你有用,别忘了在 GitHub 上给我们留下一颗星。

最后,如果您在您的项目中使用了 datasist,请告诉我们,以便我们可以在我们的页面上展示您。

点击 找到我们的投稿人名单

链接到 GitHub 上的 datasist repo

链接到文档

链接 举例用法

TwitterLinkedIn上找我

给我发邮件:risingodegua@gmail.com

简单的一键式 Jupyter 笔记本

原文:https://towardsdatascience.com/easy-devops-for-data-science-with-saturn-cloud-notebooks-d19e8c4d1772?source=collection_archive---------33-----------------------

What society thinks Data Scientists look like. Source

我为学习者写了一份名为《强大的知识》的时事通讯。每一期都包含链接和最佳内容的关键课程,包括引文、书籍、文章、播客和视频。每一个人都是为了学习如何过上更明智、更快乐、更充实的生活而被挑选出来的。 在这里报名

数据科学可以是一件有趣的事情!

事实上,我们所做的大部分事情都是在挖掘数据的同时试图提取隐藏的信息。这就像我们在一个未知的丛林中寻找宝藏!

但它并不总是有趣和游戏。

在幕后,建立数据科学家用于工作的实际*台需要做很多工作。创建服务器、安装必要的软件和环境、建立安全协议等等。

完成所有这些工作通常需要一名专门的 DevOps 工程师。了解云服务、操作系统、网络的来龙去脉,至少了解一点数据科学和机器学习软件的知识,以便正确设置它。

但是,如果有一种方法,我们可以绕过所有繁琐的开发工作,直接进入我们的数据科学呢?

一项名为土星云的新服务让数据科学家可以做到这一点:跳过繁琐的设置,直接进入数据科学!

数据科学的土星云和 DevOps

花点时间想想为数据科学家有效工作而设置环境所涉及的所有事项。对于许多公司来说,这看起来像是:

  1. 创建和配置服务器。理想情况下,这些应该在服务器能力和实例数量方面都很容易扩展
  2. 在所有服务器上安装软件。软件应该易于更新
  3. 配置安全性。保护任何敏感数据、代码或 ML 模型
  4. 配置网络。服务器应该可以在特定的端口被特定的人访问。

所有这些都需要大量的时间,尤其是第 1 步和第 2 步。许多数据科学家甚至从未见过这些事情发生——他们只看到最终产品。但是设置所有这些基础设施是一个真正的挑战,其中一些需要不断更新。

DevOps engineers constantly catering to the ever-changing needs of Data Scientists

Saturn Cloud 自称为云托管数据科学,它允许数据科学家轻松地在云上提供和托管他们的工作,而不需要专门的开发人员。然后,您可以在 Juptyer 笔记本中工作,该笔记本位于您指定的服务器上,由系统创建。

所有软件、网络、安全和库的设置都由 Saturn Cloud 系统自动处理。然后,数据科学家可以专注于实际的数据科学,而不是围绕它的乏味的基础设施工作。

这个想法是,用户(你和我,数据科学家)可以简单地指定我们想要的计算,输入我们想要的软件库列表,土星云系统将处理其余的设置。

如何使用托管的 Jupyter 笔记本

要开始,只需进入土星云网站并创建一个账户。基本计划是完全免费的,所以你可以先在环境中摸索一下。

登录后,点击“您的仪表板”选项卡,开始创建一个托管 Jupyter 笔记本的服务器。下面的视频展示了如何创建你的服务器!

您将基本上经历以下步骤:

  1. 为笔记本指定一个名称
  2. 指定您想要的存储量
  3. 指定您想要使用的 CPU 或 GPU
  4. 如果需要,设置自动关机
  5. 列出您希望安装在系统上的任何软件包或库

一旦你点击创建按钮,你的服务器将自动创建所需的设置和软件。当创作完成时——瞧!您的云托管 Jupyter 笔记本已准备好用于数据科学!

在您的仪表板顶部,您会看到启动、停止、编辑和删除笔记本云服务器的按钮。对于本教程的下一部分,我已经编辑了我的服务器,安装了 pandas 和 matplotlib。

要访问您的云托管 Jupyter 笔记本,请点击“转到 Jupyter 笔记本”链接。将打开一个选项卡,其中有 Jupyter 笔记本界面设置,您可以从中创建 Python 3 笔记本!

我已经在下面的视频中创建了我的笔记本。一旦你的笔记本创建完成,你就可以开始编码了!我提前准备了一些代码来绘制鸢尾花数据集。土星云能够*稳无缝地运行一切。

除了托管 Jupyter 笔记本,土星云还允许你公开或私下发布你的笔记本。当您发布您的笔记本时,您将获得一个 URL,然后您可以与任何想要运行您的笔记本的人共享该 URL:随时随地。查看我的这里!

喜欢学习?

在 twitter 上关注我,我会在这里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上和我联系吧!

使用 TensorFlow 2.0 轻松进行图像分类

原文:https://towardsdatascience.com/easy-image-classification-with-tensorflow-2-0-f734fee52d13?source=collection_archive---------2-----------------------

G etting 从 TensorFlow 2.0 alpha 的改进高级 API 开始

具有重大优势的主要版本

在 2019 年 TensorFlow Dev 峰会上,谷歌推出了 TensorFlow 2.0 的 alpha 版本。从历史上看,TensorFlow 被认为是机器学习框架的“工业车床”:一个强大的工具,具有令人生畏的复杂性和陡峭的学习曲线。如果你过去用过 TensorFlow 1.x,你就知道我在说什么。这个 2.0 版本代表了为提高 TensorFlow 的可用性、清晰性和灵活性所做的共同努力。以下是一些亮点:

  • 默认情况下,会启用急切执行,而不会牺牲基于图形的执行的性能优化。
  • API 更干净,更一致,冗余更少。
  • 作为高级 API 的更紧密的 Keras 集成。
  • 还有更

因此,TensorFlow 2.0 更加 Pythonic 化,学习起来不那么令人畏惧,同时保留了较低级别的定制和复杂性(如果需要的话)。让我们从 TensorFlow 2.0 开始,探索如何在经典图像分类设置中应用其高级 API。

在 Colab 上安装 TensorFlow 2.0 alpha

谷歌合作实验室让在云中设置 Python 笔记本变得非常容易。由于每次可以免费访问 GPU 长达 12 小时,Colab 很快成为我进行机器学习实验的首选*台。

让我们通过 pip 在一台 Colab 笔记本上安装 TensorFlow 2.0 alpha 版本(GPU 版)。

!pip install tensorflow-gpu==2.0.0-alpha0

要验证其安装是否正确:

import tensorflow as tf
print(tf.__version)# Output: 2.0.0-alpha0

你应该可以走了!如果您遇到问题,请在“编辑”>“笔记本设置”中仔细检查您的 Colab 运行时是否将“GPU”作为运行时加速器。

使用 tf.data.Dataset 加载数据

让我们使用 Kaggle 上的空中仙人掌识别比赛的数据集。我们的任务是建立一个分类器,能够确定一个航拍图像是否包含柱状仙人掌。该数据集是 Cactus 航空照片数据集[1]的修改版本(Kaggle 将每个图像的大小调整为 32x32 像素)。

Example image with cactus

Example image with no cactus (upscaled 4x)

例如从 Kaggle 下载/解压缩数据集的代码,请参见完整笔记本,此处为。

让我们使用 pandas 将图像文件路径及其相应的标签加载到列表中,然后使用 sklearn.model_selection 创建一个 90–10 的训练验证分割。

train_csv = pd.read_csv('data/train.csv')# Prepend image filenames in train/ with relative path
filenames = ['train/' + fname for fname in train_csv['id'].tolist()]
labels = train_csv['has_cactus'].tolist()train_filenames, val_filenames, train_labels, val_labels = 
  train_test_split(filenames,
                 labels,
                 train_size=0.9,
                 random_state=42)

现在我们已经将图像文件名和标签分成了训练集和验证集,我们可以创建各自的 tf.data.Dataset 对象。

train_data = tf.data.Dataset.from_tensor_slices(
  (tf.constant(train_filenames), tf.constant(train_labels))
)val_data = tf.data.Dataset.from_tensor_slices(
  (tf.constant(val_filenames), tf.constant(val_labels))
)

然而,我们的数据集仍然只包含图像文件名,而不是实际的图像。我们需要定义一个函数,可以从文件中加载图像,并执行任何必要的预处理。当我们这样做的时候,让我们也对数据集进行洗牌和批处理。

IMAGE_SIZE = 96 # Minimum image size for use with MobileNetV2BATCH_SIZE = 32# Function to load and preprocess each image
def _parse_fn(filename, label):
    img = tf.io.read_file(img)
    img = tf.image.decode_jpeg(img)
    img = (tf.cast(img, tf.float32)/127.5) - 1
    img = tf.image.resize(img, (IMAGE_SIZE, IMAGE_SIZE))
    return img, label # Run _parse_fn over each example in train and val datasets
# Also shuffle and create batchestrain_data = (train_data.map(_parse_fn)
             .shuffle(buffer_size=10000)
             .batch(BATCH_SIZE)
             )val_data = (val_data.map(_parse_fn)
           .shuffle(buffer_size=10000)
           .batch(BATCH_SIZE)
           )

构建迁移学习模型

迁移学习通过使我们能够重复使用现有的预训练图像分类模型来加速训练,只需要重新训练网络的顶层来确定图像可以属于的类别2。

Diagram illustrating transfer learning

让我们使用 TensorFlow 2.0 的高级 Keras API 来快速构建我们的图像分类模型。对于迁移学习,我们可以使用预训练的 MobileNetV2 模型作为特征检测器。MobileNetV2 是由 Google 发布的 MobileNet 的第二个迭代,目标是比 ResNet 和 Inception 等模型更小、更轻量级,以便在移动设备上运行[3]。让我们加载在 ImageNet 上预训练的没有顶层的 MobileNetV2 模型,冻结其权重,并添加新的分类头。

IMG_SHAPE = (IMAGE_SIZE, IMAGE_SIZE, 3)# Pre-trained model with MobileNetV2
base_model = tf.keras.applications.MobileNetV2(
    input_shape=IMG_SHAPE,
    include_top=False,
    weights='imagenet'
)# Freeze the pre-trained model weights
base_model.trainable = False# Trainable classification head
maxpool_layer = tf.keras.layers.GlobalMaxPooling2D()
prediction_layer = tf.keras.layers.Dense(1, activation='sigmoid')# Layer classification head with feature detector
model = tf.keras.Sequential([
    base_model,
    maxpool_layer,
    prediction_layer
])learning_rate = 0.0001# Compile the model
model.compile(optimizer=tf.keras.optimizers.Adam(lr=learning_rate), 
              loss='binary_crossentropy',
              metrics=['accuracy']
)

注意,建议使用 TensorFlow 优化器训练tf.keras模型。在 TensorFlow 2.0 中,之前tf.traintf.keras.optimizersAPI 中的优化器已经统一在tf.keras.optimizers下,其中原来的tf.keras优化器已经被升级后的 TensorFlow 优化器所取代【4】。因此,应用 TensorFlow 优化器现在是一种更简单、更一致的体验,完全支持使用tf.keras API,并且不会牺牲性能。

训练模型

TensorFlow 2.0 中的tf.keras API 现在已经完全支持tf.data API,因此我们可以在训练模型时轻松使用我们的tf.data.Dataset对象5。同样,现在默认情况下,训练会被急切地执行,而不会牺牲基于图形的执行的性能优势。

num_epochs = 30
steps_per_epoch = round(num_train)//BATCH_SIZE
val_steps = 20model.fit(train_data.repeat(),
          epochs=num_epochs,
          steps_per_epoch = steps_per_epoch,
          validation_data=val_data.repeat(), 
          validation_steps=val_steps)

经过 30 个时期后,模型的验证精度从大约 0.63 提高到 0.94。

Accuracy and loss over 30 epochs of transfer learning

微调模型

让我们试着进一步提高我们模型的准确性。当我们应用迁移学习时,我们只训练模型的新分类头,冻结来自 MobileNetV2 的权重。如果我们最初不冻结这些权重,模型将“忘记”它开始时的所有知识,因为新的分类头是随机初始化的2。然而,现在我们已经首先训练了分类头,我们可以在预训练的模型中解冻层,以在这个特定的数据集上进行微调。

*# Unfreeze all layers of MobileNetV2*
base_model.trainable = **True**

*# Refreeze layers until the layers we want to fine-tune*
**for** layer **in** base_model.layers[:100]:
  layer.trainable =  **False**# Use a lower learning rate
lr_finetune = learning_rate / 10# Recompile the model
model.compile(loss='binary_crossentropy',
              optimizer = tf.keras.optimizers.Adam(lr=lr_finetune),
              metrics=['accuracy'])# Increase training epochs for fine-tuning
fine_tune_epochs = 30
total_epochs =  num_epochs + fine_tune_epochs # Fine-tune model
# Note: Set initial_epoch to begin training after epoch 30 since we
# previously trained for 30 epochs.model.fit(train_data.repeat(), 
          steps_per_epoch = steps_per_epoch,
          epochs=total_epochs, 
          initial_epoch = num_epochs,
          validation_data=val_data.repeat(), 
          validation_steps=val_steps)

在另外 30 个时期的微调后,该模型达到了 0.986 的验证精度。基于准确度和损失图,更多的时期可能导致更大的改进。

Accuracy and loss with additional 30 epochs of fine-tuning

摘要

在这篇文章中,我们了解了 TensorFlow 2.0 对可用性、清晰度和灵活性的关注如何使 TensorFlow 在机器学习实验中的入门变得不那么令人生畏。热切的执行和改进的高级 API 抽象出了 TensorFlow 通常的复杂性,使其更容易快速实施和运行典型的图像分类实验。

在撰写本文时,这只是 TensorFlow 2.0 的 alpha 版本,最终版本预计将在今年晚些时候发布。显然,TensorFlow 团队正在打造一个更加直观的 TensorFlow 迭代。这可能会全面提高机器学习工程师的生产率,降低通常的复杂性,同时为那些需要的人保留较低层次的控制。此外,虽然 TensorFlow 已经是机器学习专家的热门选择,但更*滑的学习曲线也使其对初学者更具吸引力。

请在评论中告诉我你对 TensorFlow 2.0 目前为止的看法!另外,如果你对本教程的完整代码感兴趣, 参见笔记本这里的 。如果你有任何问题,也不要犹豫,在评论区提问。

参考

本教程的灵感来自于使用 TensorFlow.org 的预训练网络进行迁移学习。阅读教程原文,见此处。

[1]Kaggle.com j .瓦斯奎兹-戈麦斯仙人掌航拍照片 (2019)

2 利用预训练的 ConvNets 进行迁移学习 (2019),TensorFlow.org

[3] M. Sandler,A. Howard,m . Zhmonginov,L. C. Chen, MobileNetV2:反向残差和线性瓶颈 (2019),谷歌公司。

4 F. Chollet, TensorFlow 2.0:优化器统一 (2018),TensorFlow GitHub

5 路线图 (2019),TensorFlow.org

浏览器中的简易机器学习:实时图像分类

原文:https://towardsdatascience.com/easy-machine-learning-in-the-browser-31b225d6cee0?source=collection_archive---------24-----------------------

Photo by Kasya Shahovskaya on Unsplash

利用 Tensorflow.js KNN 模块和 Angular 在浏览器中训练实时图像识别模型

将机器学习应用部署到生产环境中曾经是一个令人望而生畏的过程,因为它需要在许多不同的环境中处理复杂的操作。随着 Tensorflow.js 的引入,使用 javascript 在 web 浏览器中开发、训练和部署机器学习应用程序变得超级容易。

为了演示这一点,我将使用 Angular 创建一个简化版本的可示教机器演示应用程序。这个演示应用程序教你的计算机使用你的网络摄像头在网络浏览器中实时识别图像。

为了实现这一点,我将使用 Tensorflow.js 提供的 KNN 模块。该模块使用的 K-最*邻算法创建一个分类器。它不是为模型提供权重,而是使用另一个模型的激活来创建 KNN 模型。

为此,mobilenet 图像分类模型是一个非常好的选择,因为它是轻量级的,可以在 Tensorflow 中使用。机器学习中的这一过程被称为迁移学习,因为我们使用的是另一种机器学习模型的表示。

Photo by Andrii Podilnyk on Unsplash

在深入细节之前,让我们首先更好地了解应用程序中遵循的步骤是什么;

Step1:

用户应提供并标记用于训练的 3 组输入图像。网络摄像头和浏览器上的按钮可用于此目的。

第二步 :

一旦为所有输入图像提供了标签,将通过将输入图像转储到 mobilenet 模型中来预测激活张量。然后,这些激活张量将被用作 KNN 分类器的输入,以创建具有分配给所提供的每个激活张量的标签的数据集。培训过程将在这一步完成。

步骤三:

对于预测,从网络摄像头捕捉的图像将被实时输入 mobilenet 模型,以获得激活张量。这些将被输入到训练好的 KNN 模型中,以识别图像的类别。

一开始看起来有点复杂,但是一旦用例子一步一步地解释,就很容易理解了。

Photo by Robert Baker on Unsplash

在开始编码之前,让我们进一步了解 K-最*邻算法和 Tensorflow.js KNN 模块是如何工作的。

K *邻算法是如何工作的?

k *邻(KNN)是一种简单、易于实现的机器学习算法,在推荐系统和基于相似性的分类任务中有许多实际用途。

它将示例存储为带标签的类。当你需要预测一个新例子的类别时,它会计算这个新例子和所有其他已经被标记和已知的例子之间的距离。k 是最*邻居的数量。此时,通过邻居的多数投票来完成分类。

你可以点击这个链接获得更多关于 KNN 算法的信息。

Photo by Nina Strehl on Unsplash

Tensorflow.js KNN 模块

要使用 Tensorflow.js KNN 模块,必须将已知示例添加到分类器中。这是通过 addExample 方法完成的。在我们的例子中,已知的例子将通过身体姿态图像生成,这些图像是从实时网络摄像头获取的。这将是 KNN 算法的训练阶段。一旦完成,我们将能够用预测类方法预测未知的身体姿势。

***//importing tensorflow.js KNN module***
import * as knnClassifier from ‘@tensorflow-models/knn-classifier’;***//instantiating the classifier***
classifier = knnClassifier.**create()*****//adding examples to the KNN model for training***
classifier.**addExample**(example: tf.Tensor,label: number|string): void;***//predicting unknown examples with the trained KNN classifier***
classifier.**predictClass**(input: tf.Tensor,k = 3): Promise<{label: string, classIndex: number, confidences: {[classId: number]: number}}>;

这是足够的理论!

让我们把这个理论付诸实践吧!

Photo by Jakob Owens on Unsplash

此时,我们必须生成我们的 Angular WebApp。下面介绍的所有打字稿代码都必须在 app.component.ts.

如果你想了解更多关于如何生成 Angular WebApp,你可以查看我以前的帖子。

[## 使用 Tensorflow.js 和 Angular 构建实时对象检测 WebApp

张量流。射流研究…

medium.com](https://medium.com/@erdemisbilen/building-realtime-object-detection-webapp-with-tensorflow-js-and-angular-a4ff5062bdf1)

让我们首先启动网络摄像头和模型。

init_webcam()
{
***// Get the HTMLVideoElement*** this.video = <HTMLVideoElement> document.getElementById("vid");***// Start webcam stream***
navigator.mediaDevices.getUserMedia({audio: false, video: {facingMode: "user"}}).then(*stream* *=>*{
this.video.srcObject = stream;
this.video.onloadedmetadata = () *=>* {this.video.play();};});
}async init_models()
{
***// Initiate the KNN classifier***
this.classifier = await knnClassifier.create();
*console*.log('KNN classifier is loaded')***// Load mobilenet model***
*const* mobilenet =  await tf.loadLayersModel('https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json');
*console*.log('Mobilenet model is loaded')***// Modify the mobilenet model so that we can get the activations from 'conv_preds' layer*** *const* outputLayer=mobilenet.getLayer('conv_preds');
this.mobilenetModified = tf.model({inputs: mobilenet.inputs, outputs: outputLayer.output, name: 'modelModified' });
*console*.log('MobilenetModified model is generated')
}

下一步是创建一个函数,将示例添加到我们刚刚启动的 KNN 分类器中。这个函数接受定义我们添加的示例类的参数 className

addExample(*className*)
{
***// Get the image from the video feed and convert it to tensor*** *let* img=tf.browser.fromPixels(<HTMLVideoElement> document.getElementById("vid"));***// Get the activations from the mobilenet model*** *let* logits = <tf.Tensor> this.mobilenetModified.predict(img.expandDims());***// Add the activations as an example into the KNN model with a class name assigned*** this.classifier.addExample(logits, className);***// Show the stored image on the browser*** *let* canvas = <HTMLCanvasElement> document.getElementById("canvas");
*let* ctx = canvas.getContext("2d");
ctx.drawImage(<HTMLVideoElement> document.getElementById("vid"),0,0,224,224)
*console*.log('KNN example added')
}

然后我们需要创建一个函数来预测未知的例子。

***// Calls detectFrame with video, mobilenet and KNN arguments***
predict()
{this.detectFrame(this.video,this.mobilenetModified, this.classifier);
}***// Performs real-time predictions continuously by generating the activations of images produced from video feed. Then it predicts the class of the image based on the similarity with stored examples.***detectFrame = (*video*, *mobileNetModel*, *KNNModel*) *=>* {*const* predictions= <tf.Tensor> mobileNetModel.predict(tf.browser.fromPixels(video).expandDims());KNNModel.predictClass(predictions).then(*result=>* {this.renderPredictions(result);requestAnimationFrame(() *=>* {
this.detectFrame(video, mobileNetModel, KNNModel);});});
}***//Writes KNNClassifier results to the console***
renderPredictions = *result* *=>* {*console*.log(result)};

最后一步是修改app.component.html,将必要的UI 元素放到应用程序中。

<h1>Easy Machine Learning in the Browser: Real-time Image Classification</h1><video  id="vid" width="224" height="224"></video>
<canvas id="canvas" width="224" height="224"></canvas><button mat-button (click)="addExample('0')">Add Example Class1</button>
<button mat-button (click)="addExample('1')">Add Example Class2</button>
<button mat-button (click)="addExample('2')">Add Example Class3</button><button mat-button (click)="predict()">Predict</button>

干得好!

您已经做了这么多,并且创建了一个 web 应用程序来对浏览器中的图像进行分类。

在地图上绘制地理数据的简单步骤 Python

原文:https://towardsdatascience.com/easy-steps-to-plot-geographic-data-on-a-map-python-11217859a2db?source=collection_archive---------0-----------------------

A 假设你在一家创业公司工作,需要对用户的地理数据进行空间数据分析和预测。或者,您的公司运行大量的交付操作,您的工作再次分析、可视化并可能预测司机或用户的地理数据。因此,在地图上可视化您的数据(可能是预测的数据)将是非常必要的。

在本文中,我将介绍如何使用 Python 在任何地图上绘制地理数据的简单步骤。我发现它在我以前的项目中非常有用和有帮助,使用相同的语言:Python-检查我的文章:交通管理的空间数据分析。

当然,当我们提到地理数据时,我们脑海中浮现的是数据点的坐标:经度和纬度。这是真的,它们只是地图上特定点的 X 和 Y 坐标。然而,还有其他类型的地理数据,如多边形、线数据。这里主要关注如何在地图上可视化点数据。我们可以开始了吗?

加载库和数据集

首先,让我们从加载库开始

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

加载空间数据集

df = pd.read_csv(‘C:/.. …/SpatialDataSet.txt’)

看一看数据集

df.head()

我的数据集很简单(1444 行× 2 列)。为了这次演示,我在利雅得市收集了随机的地理数据点。

定义边界框

现在,我们必须定义边界框。边界框是由两个经度和两个纬度定义的区域,它将包括所有的空间点。

BBox = ((df.longitude.min(),   df.longitude.max(),      
         df.latitude.min(), df.latitude.max())> (46.5691,46.8398, 24.6128, 24.8256)

拿你的地图

进入 opestreetmap.org 网站,首先输入边界框数据,将所需地图导出为图像。我按照下图中的解释做了同样的事情(这里也提到了更多的细节:导出地图图像的步骤)。

返回编码环境并加载地图图像:

ruh_m = plt.imread('C:/.. … /Riyadh_map.png')

最后一步:绘图

最后,在' ruh_m '地图图像上绘制'测向经度'和'测向纬度'坐标作为散点。注意,根据边界框' BBox '设置 X 轴和 Y 轴很重要

fig, ax = plt.subplots(figsize = (8,7))ax.scatter(df.longitude, df.latitude, zorder=1, alpha= 0.2, c='b', s=10)ax.set_title('Plotting Spatial Data on Riyadh Map')
ax.set_xlim(BBox[0],BBox[1])
ax.set_ylim(BBox[2],BBox[3])ax.imshow(ruh_m, zorder=0, extent = BBox, aspect= 'equal')

使用 Python 实现简单的文本到语音转换

原文:https://towardsdatascience.com/easy-text-to-speech-with-python-bfb34250036e?source=collection_archive---------1-----------------------

文本到语音

Photo by Oleg Ivanov on Unsplash

文本到语音(TTS)技术大声朗读数字文本。它可以将电脑、智能手机、*板电脑上的文字转换成音频。此外,各种文本文件都可以大声朗读,包括 Word、pages 文档、在线网页都可以大声朗读。TTS 可以帮助阅读困难的孩子。有许多工具和应用程序可以将文本转换成语音。

Python 附带了许多方便易用的库,在本文中,我们将探讨如何使用 Python 实现文本到语音的转换。

为了将文本转换成语音,Python 中提供了不同的 API。其中一个 API 是 Google 文本到语音转换,通常称为 gTTS API。这是非常容易使用的库转换输入的文本到一个音频文件,可以保存为 mp3 文件。它支持多种语言,语音可以以两种音频速度中的任何一种传送,快或慢。更多详情可在这里找到

将文本转换成语音

代码:

导入 gTTS 库和“os”模块以播放转换后的音频

from gtts import gTTS 
import os

创建一个我们想要转换成音频的文本

text = “Global warming is the long-term rise in the average temperature of the Earth’s climate system”

gTTS 支持多种语言。请在这里查阅文档。选择' en' - >英语并存储在语言变量中

language = ‘en’

创建一个名为 speech 的对象,并将文本和语言传递给引擎。标记为 slow = False,告知模块转换后的音频应具有高速。

speech = gTTS(text = text, lang = language, slow = False)

将转换后的音频保存在名为“text.mp3”的 mp3 文件中

speech.save(“text.mp3”)

使用 Windows 命令“开始”,后跟 mp3 文件名,播放转换后的文件。

os.system(“start text.mp3”)

输出

text.mp3 file

The output of the above program saved as text.mp3 file. Mp3 file should be a voice saying, 'Global warming is the long-term rise in the average temperature of the Earth’s climate system'

将文本文件转换成语音

这里,将文本文件转换成语音。读取文本文件并传递给 gTTS 模块

密码

导入 gtt 和 os 库

from gtts import gTTS 
import os

读取文本文件并存储到名为 text 的对象中。我的文件名是“draft.txt”

file = open("draft.txt", "r").read().replace("\n", " ")

选择语言英语

language = ‘en’

将文本文件传递到 gTTS 模块并存储到语音中

speech = gTTS(text = str(file), lang = language, slow = False)

将转换后的音频保存在名为“voice.mp3”的 mp3 文件中

speech.save("voice.mp3")

播放 mp3 文件

os.system("start voice.mp3")

输出

已将 draft.txt 文件转换为 voice.mp3

Draft.txt file saved as a voice.mp3 file.Play the Mp3 file to listen the text presented in the draft.txt file

注意:

GTTS 是一个将文本转换为语音的简单工具,但它需要互联网连接才能运行,因为它完全依赖谷歌来获取音频数据。

感谢阅读。请继续学习,并关注更多内容!

你也可以在 KDnuggets 上阅读这篇文章。