不列颠哥伦比亚政治:情绪分析预测霍根获胜
The candidates: The NDP’s John Horgan, the Liberal’s Christy Clark and the Green Party’s Andrew Weaver. Adapted from the Vancouver Courier. Photo by Dan Toulgoet.
对 Reddit 帖子的情绪分析表明,NDP 领导人约翰·霍根将在 5 月 9 日星期二赢得不列颠哥伦比亚省的选举。这项研究表明,虽然 Reddit 用户在 r/Vancouver 和 r/BritishColumbia 子编辑中发布了更多关于简蕙芝和不列颠哥伦比亚自由党的信息,但他们对霍根和不列颠哥伦比亚新民主党的看法要积极得多。
什么是情感分析?
情感分析,也称为观点挖掘,旨在识别给定文本中说话者或作者的感觉和态度。该技术可以根据作者使用的单词来确定文本是积极的、消极的还是中性的。具有积极情绪的单词使文本倾向于积极得分;否定词,否定。因此,情感分析程序可以快速有效地扫描大量的评论、帖子或页面,并将它们分类为表达对某个主题的情感范围。
情感分析在未来几年将变得越来越重要,原因有二;首先,随着固定电话被废弃,越来越少的人接听民意调查者的电话,传统的民意调查方法正在迅速失去可信度和有效性。其次,Twitter、脸书、Instagram 和 Reddit 等网站上的互联网对话呈指数级增长,这意味着数以百万计的个人观点突然可以通过这些技术进行审查。
在最近的美国大选中,社交媒体分析比民调更能预测特朗普的胜利。
该领域还处于起步阶段,但很可能会迅速发展,并在不久的将来成为民意研究的标准组成部分,甚至可能取代民调本身,成为评估政治竞争的标准手段。
Reddit 的观点
对来自两个政治上最活跃的不列颠哥伦比亚相关子区 r/Vancouver 和 r/BritishColumbia 的最近 1000 个帖子的情绪分析表明,Horgan 将在本周二获胜。
Sentiment towards the B.C. Liberal Party. Net Positive Sentiment: 2.7%
Sentiment towards the B.C. NDP. Net Positive Sentiment: 13%
根据 Reddit 的说法,这些图表显示了各方的偏好。根据研究结果,对 NDP 的净正面情绪为 13%,对自由党的净正面情绪为 2.7%。
任何观察不列颠哥伦比亚政治的人都会证明,这听起来是对的。你会发现,在任何一个晚宴上,任何一方的支持者和反对者都势均力敌。说到领导者,差距就更大了:
Sentiment towards Christy Clark. Net Positive Sentiment: 6%
Sentiment towards John Horgan. Net Positive Sentiment: 17%
根据这项测试,霍根个人在净正面情绪竞赛中领先克里斯蒂,17%对 6%。这是政治专家们可以深入研究的事情:霍根明显领先,我们可以宣布他是未来的赢家。
但这当然有些为时过早。
一些注意事项
情绪分析能够识别与候选人相关的积极帖子,如“无论你怎么说简蕙芝,她仍然是一位出色的活动家,”以及“是的,不列颠哥伦比亚省 NDP 领导人约翰·霍根很生气——但这是一种好的方式。”负面帖子也很容易识别,比如“金钱和傲慢会让简蕙芝输掉不列颠哥伦比亚的选举吗?”“不列颠哥伦比亚省 NDP 领导人霍根在一些问题上不明确,在资金上不具体。”但是很少有帖子这么明确。很多帖子都是模棱两可的,导致大量帖子不得不贴上“中立”的标签。
进一步,一个问题出现了:我们能相信 Reddit 上用户的情绪吗?样本量很小,在 Reddit 上发帖的人不一定能代表整体人群。他们对候选人的感觉是否准确地代表了总体人口?Reddit 用户会投票吗?
此外,这项研究没有包括非英语语言的情感——鉴于某些语言的构成,这是一个相当重要的缺失。
更重要的是,情绪和投票意向之间的关系还不清楚。很有可能一个选民会同情一个政党,但仍然不投他们的票。那些对霍根有利的数据,显示他远远领先于克拉克?嗯,韦弗的不列颠哥伦比亚绿党也有一个净积极。这是百分之百。
Sentiment towards the B.C. Green Party. Net Positive Sentiment: 100%
Sentiment towards Andrew Weaver. Net Positive Sentiment: 37.5%
虽然很明显绿党不会彻底赢得选举,但他们似乎有 Reddit 的投票!这些都是非常好的消息。
指路
因此,关键问题是样本大小、样本构成以及情绪与投票意向的关系。随着可供分析的项目数量呈指数级增长,前两个问题在未来可能会变得不那么严重,情感与意图之间的关系将永远是一个黑箱。有可能通过小规模的投票来填补特定的空白,以确定每个个案中的确切关系。
目前,可以肯定的是,根据 Reddit 的报道,下周这个时候,这个省将会有一个新政府。
要了解更多关于情绪分析和我使用的 Python 包,名为 VADER,请查看 我的 github 。
婴儿步入舞台:可视化虹膜数据集
Source: Google Images
Tableau 有一句口号是“ ,改变你对数据的看法。经过一番思考,我们很容易得出这样一个结论:这句口号非常中肯。Tableau 作为一种工具给了我们力量,向我们展示了数据的奥秘。更重要的是,Tableau 教会了我们如何利用数据的力量,揭开这些谜团。因此,在这篇进入 Tableau 的文章中,我将带你通过使用虹膜数据集来了解 Tableau 的重要特性。
现在 Tableau 不仅仅是一个数据可视化软件,它还是一个商业智能应用程序(BI App)。有了 Tableau,商业智能变成了自助服务。
本质上,Tableau 是一个专注于商业智能的数据可视化软件。现在,对于你们中的一些人来说,“商业智能”这两个词可能会让人感到困惑,甚至会让一些人不知所措。但是,在数据可视化(即以可视化形式呈现数据)的帮助下,简单地支持或帮助组织做出决策的想法,无论是从运营到战略的任何事情,都是商业智能的核心。
Tableau 是用现代分析增强整个企业商业智能的领导者。根据 Gartner 的 2017 年魔力象限,Tableau 是商业智能和分析平台的明确领导者。
现在我们有了 Tableau 是什么的想法,让我们现在了解它的用户界面,以便最终能够使用该软件。
Tableau 的界面
Tableau 的工作空间的结构非常容易理解,它是用一种简单的方法制作的,即使如此,它也没有简单到可以简单的程度,可能需要一些时间来适应。
让我们深入研究一下。
在页面顶部,我们有一些用于文件、数据、工作表、仪表板等的下拉框。通过经常使用,你会发现最有价值的命令存在于这些下拉菜单中。
在这些下拉菜单下,我们有一个工具栏,工具栏包括许多有用的命令。第一个是保存,添加一个新的数据源,暂停任何来自数据源的自动更新,添加一个新的工作表,复制和几个其他命令,这些命令将在我们创建可视化时发挥作用。
左上角的 Tableau 徽标命令会将您带到起始页,如果要连接到另一个数据源,您可能需要返回到起始页。
要返回,我们只需再次点击徽标。
此外,页面左侧还有数据窗格。如果我们在“数据”选项卡上,我们会看到它列出了所有打开的数据源,并从该数据源中选择字段作为维度或度量。
度量是连续变量,本质上是数字。而维度是离散变量,如文本字符串和日期。
数据窗格还将显示我们可能有的任何集合或参数。
如果我们单击“analytics”选项卡,我们可以直接以拖放元素的形式显示我们的分析片段。如果它们与我们当前正在处理的视图或视觉类型无关,某些元素将会变灰。例如,时间线上的总计。
如果我们选择类似趋势线的东西,我们可以将它带到这些拖放区中的任何一个,以控制其属性的各个方面,如模型类型以及它应该应用于哪个度量等。
在底部,我们有新的工作表标签。我们可以使用这些选项卡创建工作表、仪表板和故事。我们可以做诸如重命名工作表、复制工作表、复制格式等许多事情。
如果工作簿有很多工作表,我们可以使用右下角的控件轻松导航。
界面最重要的部分之一是界面右侧中央的行和列架。要创建我们的可视化,我们只需将维度和度量从数据窗格拖到列和行架中。我们也可以这样做,将我们的维度和度量直接拖到画布上,让 Tableau 自动分离行和货架。
当我们将维度和度量值拖动到列和行卡片时,我们将观察到一个特定的配色方案。蓝色代表尺寸,绿色代表尺寸。
对于您创建的几乎每个可视化,我们都将向列架和行架添加维度和度量。
当我们举一个实际的例子并看到第一手的应用时,这一点将会更加清楚。
然后,我们有一个中央工作区,一旦行和列中有了度量和维度,可视化就会出现在这里。
在这里,我们可以给出工作表标题,为我们的可视化写标题,安排我们的可视化,还可以做一些格式化。
在右上角,我们有“演示”选项。
如果您不确定要创建什么样的可视化或 Tableau 中有哪些可用选项,可以单击“演示”选项,该选项将显示各种类型的可视化,您可以使用所选的维和度量或从当前存储在列和行中的数据创建这些可视化。
“演示”选项的一个优点是它会自动告诉您哪些类型的图表适合您所拥有的数据。因此,Tableau 试图向您介绍数据可视化的一些最佳实践。
现在来看 Tableau 界面最重要的部分之一。页面、过滤器和标记卡位于页面的中央左侧,靠近我们的行和列架以及工作区。
这两种卡片,过滤器和标记,在大多数可视化中被广泛使用。
过滤器允许我们从可视化中排除某些数据类型。例如,我们可能希望从我们的可视化和用于特定可视化的数据中排除一些值。
为此,我们可以设置一个范围并删除值。
另一方面,标记允许我们更详细地格式化图表。Marx card 由其他几个架子组成,每个架子上都可以放置字段,单击这些字段可以编辑它们的特征。更改标记类型可以更改标记卡上的架子,这样选择形状会调出形状架子。
根据视图的组成,可以有多个标记卡,每个测量一个。
将字段放置在颜色大小或形状架上时,将自动创建颜色大小和形状等图例。但是,可以通过单击菜单并选择隐藏卡片来删除图例。要恢复图例,右键单击画布本身的任意位置,选择 legend 并选择所需的图例。
应用:使用 Tableau 创建我们的第一个可视化
为了更加清晰地理解我们刚刚学到的关于 Tableau 界面的知识,让我们看一个例子并创建我们的第一个可视化。
对于这第一个可视化,我们将使用 UCI 机器学习库中非常著名的 Iris 数据集创建一些简单的图表。
这是一个相当简单的数据集,有 150 个实例、4 个属性和一个类;即萼片长度、萼片宽度、花瓣长度、花瓣宽度和具有三个类别的类别属性,即刚毛鸢尾、杂色鸢尾和海滨鸢尾。
尽管我们目前不会对该数据集进行任何分类或预测分析,但该数据集已被广泛用于进行此类分析。
就像我们将带有 Iris 数据集的 excel 表导入 Tableau 一样,我们可以立即查看数据集的各种实例和属性。在这里,我们还可以更改各种属性的数据类型。
现在让我们直接进入工作表,开始我们的可视化。
对于这里的第一个例子,我们看到了花瓣长度和花瓣宽度之间的图,它根据物种进行了颜色编码,这可以在图例中看到。
在这里,在数据窗格中,我们可以看到度量和维度之间的属性划分。如前所述,数字属性属于 measures 类别,而类属性属于 dimensions 类别。
我们已经创建了一个非常简单的散点图,显示了花瓣长度和花瓣宽度之间的关系,考虑到了各种物种。哪一个被分别放在列和行的架子上?
在标记卡中,我们可以清楚地看到,指定的属性已被放到颜色架上,以根据物种对分散点进行颜色编码。我们还可以看到颜色代码的补充图例。
让我们尝试另一种可视化方式,这次是直方图。
这种可视化表现了基于花瓣长度、花瓣宽度、萼片长度和萼片宽度的三个物种之间的比较。
我们可以看到,这四个属性是 rows shelf 的一部分,类变量 species 是 Columns shelf 的一部分。
此外,使用标记卡根据物种进行了颜色编码,正如上一个示例中所做的那样,我们还可以在图表的 X 轴上看到物种,因为物种也是色谱柱架的一部分。
结论
既然我们已经看到了这两个例子,那么 Tableau 及其界面的可用性一定非常清楚。
Tableau 有很多功能,可以通过使用各种选项进行很多小的调整,这些选项你只会在练习制作自己的可视化效果时遇到。
有很多东西需要探索,所以访问 UCI 机器学习库或任何像 Kaggle 这样的数据集资源,迈出可视化世界的第一步,成为这个领域要求你成为的探索者。
原载于 2018 年 9 月 14 日【stepupanalytics.com】。
在简单的 RNN/LSTM 上推导反向传播(专长。艾丹·戈麦斯)
Gif from this website
Aidan Gomez 做了一项惊人的工作,详细解释了反向传播 LSTM 一般是如何工作的。我也做了我的这篇文章。然而,我的朋友阿部康对我的帖子有一个问题。
所以今天,我想回顾一下反向传播的一些基本概念,同时将我的帖子和 Aidan 的帖子联系起来。
最后,我们学校的所有实验室都在翻新,因此我没有白板可以写,所以我会尽我所能在笔记本上写得尽可能整洁。
衍生品的快速重述
首先,让我们在继续之前练习一些导数。看着上面的图片,如果你觉得一切都有意义,请继续,否则我会建议你通过阅读这篇文章来复习更多关于衍生品的知识。
另外请注意,f(x) = tanh(x)的导数是 1-tanh(x ),可以改写为 1-f(x)。
链式法则的快速重述
Image from this website
所以链式法则也非常简单,上面我们可以看到,我们想要对函数 y 的 x 求导,但是,函数 y 本身不包含变量 x,所以我们不能直接求导。谢天谢地,函数 y 包含变量 u,u 包含 x,所以我们最终能够对函数 y 的 x 求导,这要感谢链式法则。
多变量衍生工具的快速重述
蓝色 →对变量 x 的导数
红色 →对变量 Out 的导数
现在让我们回顾一下多变量的导数,它只是对每一项单独求导。此外,现在请忽略变量的名称(如 x 或 out ),它没有重要的意义。让我们看另一个例子。
Left Image from this website, Right Image from this website
因为 ln(x)的导数是 1/x,如果我们对每个方程分别对 x 和 y 取偏导数,我们会得到类似上面的结果。最后,让我们看一个在逻辑 sigmoid 函数中的多变量函数的例子。
蓝色 →对变量 x 的导数
红色 →对变量 Out 的导数
递归神经网络的基本构建模块
Modified Image from this website
所以上图告诉了我们简单递归神经网络的基本构建模块,具有四个状态(用符号 s 表示)、三个输入(用符号 x 表示)和一个误差(用符号 E 表示)。现在让我们把它放进数学方程,但是没有任何激活函数。
绿框 →相对于状态 3 的误差导数
蓝框 →相对于状态 2 的误差导数
红框 →相对于状态 1 的误差导数
现在让我们看看每个状态的导数,很简单,对吧?使用链式法则以及多变量导数,我们能够对每个状态取导数,以相应地更新权重(U)。(请注意,我没有对状态 0 求导,我们使用的是 L2 损失函数。).现在让我们通过对输入求导来完成这个任务。
绿框 →相对于输入 3 的误差导数
蓝框 →相对于输入 2 的误差导数
红框 →相对于输入 1 的误差导数
LSTM 的前馈操作
Right Image from this website
前馈操作看起来非常复杂,但是,当我们做实际的数学运算时,它非常简单。左图是 LSTM 的图形表示,右图是来自 Aidan Gomez 的数学表示。现在让我们写下状态 1 和状态 2 的数学表达式(请注意,我在这篇文章中互换使用了状态和时间戳这两个术语)。我将使用艾登的符号,因为它会更容易理解。
请再次注意,我们使用的是 L2 成本函数。现在让我们来看一个数字例子,下面两张图片来自 Aidan 的博客文章。(请注意,在我的笔记中,为了简单起见,我没有写偏见术语。)
Aidan 也使用了状态 0 和 1,而我使用了状态 1 和 2。
时间戳 2 处的反向传播
Left Image Back Propagation equations by Aidan
这里有两点需要注意…
1.绿线→请记住 Tanh()的导数可以这样改写。如果您不记得原因,请向上滚动。
2.我没有对 i(2)和 f(2)求导。原因是因为那两项与 a(2)具有非常相似的导数结构。我将在下面详细解释原因。
如果我们观察 state(t)是如何计算的,我们可以看到涉及到 a(t),i(t),f(t)和 state(t-1)项。所以当我们对变量 a(t)求导时,我们可以知道,这和对 i(t)求导非常相似。然而,有一个术语我们需要更深入地研究,那就是 o(t)。因为这个术语是在我们计算状态(t)之后使用的,导数也是不同的。
橙色框 →关于 o(2)的导数
我们可以清楚地看到,导数方程与 a(2)相比有一些差别。
记住这些想法,我们可以看到,在时间戳 2 推导反向传播并不困难,因为它是 LSTM 的最外层。
时间戳 1 处的反向传播
绿框 →时间戳 1
处误差函数的直接导数部分蓝框 →时间戳 2
处的导数部分红框 →将符号汇总为β
上图是时间戳为 1 时的反向传播操作。现在,我再次使用艾登的符号,然而有一部分,我的朋友已经指出。
蓝框 →计算 t 点的导数时,为什么需要 t+1 的一项?
在第一个网站上,它肯定看起来令人困惑,所以让我们更深入地看看前馈操作。
蓝框 →当时间戳为 1(左图)和时间戳为 2(右图)时,显示状态 1
请注意,我会交替使用“时间戳”和“状态”这两个术语。不管怎样,我们可以观察到,当对状态 1 求导时。我们需要两个方程。
- 首先,当时间戳为 1(绿框)时,我们需要渐变
- 第二,我们需要时间戳为 2 时的梯度。(蓝色方框)
让我们回顾一下蓝框术语的来源。(关于状态(2)的导数)
所以在上面的导数之后,我们还需要加上 f(2)项。其原因可以解释如下。
请记住,在前馈操作期间,当时间戳为 2 时,我们将状态(1)乘以 f(2)。因此,如果我们对状态(1)求导,我们也需要乘以该项。
时间戳 1 时相对于 O 的反向传播
橙色框 →相对于 O 项的导数
现在让我们考虑关于 o 项的反向传播过程,与我们在上一节中所做的反向传播相比,有一个有趣的事实需要我们注意。
橙盒 →艾丹反向传播方程
没有 t+1 的项。对状态(t)求梯度时,这是一个明显的区别。换句话说……
a)在对状态(t)取梯度时→我们需要考虑来自未来时间戳状态(t+1)的梯度
b)在对 o(t)取梯度时→我们不需要考虑来自未来时间戳状态(t+1)的梯度
当考虑时间标记 1 的反向传播时,可以再次看到这一点。
蓝框 →其中状态(2)(换言之状态(t+1)存在
黄框 →受状态(t+1)影响的导数
黑框 →不受状态(t+1)影响的导数
为了进一步证实这个想法,让我们看一下我以前的博客帖子,在那里我更详细地介绍了反向传播。
Image from this post
蓝框 →从时间戳 1
的成本函数对 o(用 W(o)表示)求导;绿框 →从时间戳 2 的成本函数对 o(用 W(o)表示)求导
到目前为止,我们可以理解导数,但是现在让我们看看数学。
请暂时忽略绿色/红色框。好的,这是我们得到的数学公式,但是现在让我们比较一下,我们从之前的帖子到现在的帖子得到的公式。为了便于比较,让我们扩展等式,如下所示。
红框 →公式展开的重复项
绿框 →时间戳 2 的导数
现在把所有的东西放在一起,我们从上面看到的所有的绿盒子元素,进入黑星变量。所有的红框元素都完全一样。(除了输入的 x 符号)。
这里我们可以确认的是,当对 o 项求导时(见下文),我们不需要考虑状态(t+1)的导数。
最后的话
希望这篇文章可以澄清一些困惑,但是我知道我的英文解释不是最好的。所以如果你有任何问题,请在下面评论。
如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请在这里查看我的网站。
与此同时,在我的 twitter 上关注我这里,访问我的网站,或者我的 Youtube 频道了解更多内容。
参考
- 反向传播一个 LSTM:一个数值例子。(2016).中等。检索于 2018 年 5 月 1 日,来自https://medium.com/@aidangomez/let-s-do-this-f9b699de31d9
- 微积分评论:衍生规则——Magoosh 高中博客。(2017).Magoosh 高中博客。2018 年 5 月 1 日检索,来自https://magoosh . com/hs/AP-calculus/2017/calculus-review-derivative-rules/
- 微积分的规则-多元。(2018).Columbia.edu。检索于 2018 年 5 月 1 日,来自http://www . Columbia . edu/ITC/SIPA/math/calc _ rules _ multivar . html
- lnx 的衍生和例子—mathbootpcamps。(2016).数学夏令营。检索于 2018 年 5 月 1 日,来自https://www.mathbootcamps.com/derivative-natural-log-lnx/
- 基于递归神经网络的电价预测。(2018).Slideshare.net。检索于 2018 年 5 月 1 日,来自https://www . slide share . net/taegyunjeon 1/electric-price-forecasting-with-recurring-neural-networks
- 微分 3 微分的基本法则积和商法则链式法则经济学中的边际函数高阶导数。— ppt 下载。(2018).Slideplayer.com。检索于 2018 年 5 月 1 日,来自http://slideplayer.com/slide/10776187/
- 反向传播一个 LSTM:一个数值例子。(2016).中等。检索于 2018 年 5 月 2 日,来自https://medium.com/@aidangomez/let-s-do-this-f9b699de31d9
- 只有 Numpy:推导长期短期记忆中的前馈和反向传播(LSTM)第 1 部分。(2018).成为人类:人工智能杂志。2018 年 5 月 2 日检索,来自https://becoming human . ai/only-numpy-derivating-forward-feed-and-back-propagation-in-long-short-term-memory-lstm-part-1-4ee 82 c 14 a 652
借助人力资源分析重返校园
现在是返校季,这让我想知道教育对分析成就有多重要。由于互联网分析是一个快速发展的话题,并且不断发展,分析专业人员必须做一些功课,以跟上行业标准、最佳实践和工程进步。但人力资源分析领导者也应该发挥教师的作用,向一系列内部利益相关者和外部合作伙伴讲授分析的价值,以及它为什么重要,以及它如何帮助实现特定的业务目标。
让我们看看分析教育的几种课程选择
教育企业主:第一件事将是教导业务单位和产品经理关于信息共享,并指导他们如何利用几个分析工具。教科书大小的报告充满了员工的信息和行为,没有上下文,不会帮助公司高管做出更好的决策。事实上,它们只会导致沮丧和困惑。例如,员工绩效数据应始终与去年、上个季度或上个月进行比较,以便更好地理解。
根据该公司的情况,有一个完整的“语言”课程,以及精心定义的页面浏览量、独立访问者和会话长度等短语,可能是必不可少的。此外,管理人员应该了解这些度量标准如何相互关联,以及如何与中心业务目标保持一致。
不完全理解参数或 人力资源分析 功能的执行团队可能会匆忙采取适得其反的行动。一家大型媒体公司的高管团队感到沮丧,你永远也不想看到他们是否从两个据称可靠的来源持续获得报道,报道明显相同的细节。
人力资源分析的目标
人力资源分析旨在为组织提供有效管理员工的见解,以确保快速高效地实现业务目标。人力资产分析面临的挑战是确定应该记录哪些信息,以及如何使用这些信息来建模和预测能力,以便组织的人力投资获得最佳投资回报(ROI)。
人力资源部门正在创建比以往任何时候都多的数据,但与此同时,他们经常难以将信息转化为有价值的见解。根据领导者和人力资源人员在全球公司的工作,专家们确定了一些基本的分析方法,经理们可以利用这些方法来改善他们组织中与人相关的方面。这篇信息丰富的文章基于我的关于重要的 商业分析程序 的帖子,这可能是很好的额外背景阅读。
投资合适的人力资源分析工具
使用正确的分析工具发现并最终确定劳动力空缺,从而满足您的业务需求。了解运营和战术人力资源缺口,以加强人员规划。利用招聘、流动和退休趋势,以及人力资源干预和策略库来减少可能阻碍进步的危险。通过对劳动力论文和价格建模,评估劳动力计划情况的财务后果。
利用可靠的情报推动业务决策。探索招聘、多样性、人员流动和功能性等挑战。通过个性化标题、人力资源仪表板和报告分享见解和趋势。
Right 人力资源分析解决方案 连接业务和 IT,帮助您缩小自动化转换策略和实施之间的差距。从价值和设计发现,到加速创造,再到成功利用有形业务成果,有可能通过使用最了解应用程序的可靠顾问开辟新领域来发展您的公司。
深度学习背景去除
也可以看看我们的网站—www.shibumi-ai.com
介绍
在过去几年的机器学习中,我一直想打造真正的机器学习产品。
几个月前,服用了伟大的 Fast 之后。AI 深度学习课程,看起来就像星星排成一行,我有机会:深度学习技术的进步允许做许多以前不可能的事情,新的工具被开发出来,使部署过程比以往任何时候都更容易。
在前面提到的课程中,我遇到了 Alon Burg ,他是一位经验丰富的 web 开发人员,我们合作追求这个目标。我们共同为自己设定了以下目标:
- 提高我们的深度学习技能
- 提高我们的人工智能产品部署技能
- 根据市场需求制造有用的产品
- (为我们和我们的用户)享受乐趣
- 分享我们的经验
考虑到上述情况,我们正在探索以下想法:
- 尚未完成(或未正确完成)
- 计划和实施不会太难——我们的计划是 2-3 个月的工作,每周一个工作日。
- 将有一个简单而吸引人的用户界面——我们想做一个人们会使用的产品,而不仅仅是为了演示的目的。
- 将随时可以获得训练数据——正如任何机器学习从业者都知道的那样,有时数据比算法更昂贵。
- 将使用尖端的深度学习技术(谷歌、亚马逊和朋友们在其云平台上尚未商品化),但不会太尖端(因此我们将能够在网上找到一些例子)
- 将有可能达到“生产就绪”的结果。
我们早期的想法是从事一些医学项目,因为这个领域非常贴近我们的内心,我们觉得(现在仍然觉得)在医学领域有大量容易实现的深度学习成果。然而,我们意识到我们将会遇到数据收集的问题,也许还有合法性和监管的问题,这与我们保持简单的意愿相矛盾。我们的第二个选择是背景去除产品。
如果你使用某种“标记”和边缘检测,手动或半手动(Photoshop,甚至 Power Point 都有这样的工具)去除背景是一项非常容易的任务,见这里一个例子。然而,全自动背景去除是一项相当具有挑战性的任务,据我们所知,仍然没有产品能取得令人满意的结果,尽管有些人做了尝试。
我们将移除什么背景?这被证明是一个重要的问题,因为一个模型在物体、角度等方面越具体。分离的质量就越高。在开始我们的工作时,我们想的很大:一个通用的背景去除器,它将自动识别每种类型的图像中的前景和背景。但是在训练了我们的第一个模型之后,我们明白了将我们的努力集中在一组特定的图像上会更好。因此,我们决定以自拍和人像为主。
Background removal of (almost) human portrait
自拍是一种具有突出和聚焦前景的图像(一个或多个“人”),保证我们在物体(面部+上半身)和背景之间有良好的分离,以及相当恒定的角度,并且总是同一物体(人)。
考虑到这些假设,我们开始了研究、实施和数小时培训的旅程,以创建一个易于使用的一键式背景移除服务。
我们工作的主要部分是训练模型,但是我们不能低估正确部署的重要性。好的细分模型仍然不如分类模型紧凑(例如【SqueezeNet】),我们积极研究了服务器和浏览器部署选项。
如果你想了解更多关于我们产品部署过程的细节,欢迎你查看我们在服务器端和客户端的帖子。
如果你想了解这个模型和它的训练过程,继续下去。
语义分割
当检查与我们相似的深度学习和计算机视觉任务时,很容易看出我们的最佳选择是语义分割任务。
其他策略,如深度检测分离也存在,但对我们的目的来说似乎还不够成熟。
语义分割是一项众所周知的计算机视觉任务,与分类和对象检测并列为三大任务之一。从将每个像素分类到一个类别的意义上来说,分割实际上是一个分类任务。与图像分类或检测不同,分割模型真正显示了对图像的一些“理解”,不仅说“在这个图像中有一只猫”,而且在像素级别上指出猫在哪里以及是什么。
那么分段是如何工作的呢?为了更好地理解,我们将不得不考察这一领域的一些早期作品。
最早的想法是采用一些早期的分类网络,如 VGG 和 Alexnet 。 VGG 是 2014 年图像分类的最新模型,由于其简单明了的架构,现在非常有用。当检查 VGG 早期层时,可能会注意到在要分类的项目周围有高激活。更深的层具有更强的活性,然而由于重复的汇集作用,它们本质上是粗糙的。记住这些理解,假设分类训练也可以通过一些调整用于发现/分割对象。
语义分割的早期结果与分类算法一起出现。在这篇文章中,你可以看到一些使用 VGG 得到的粗略分割结果:
后期图层结果:
Segmentation of the buss image, light purple (29) is school bus class
双线性上采样后:
这些结果来自于仅仅将完全连接的层转换(或保持)成它的原始形状,保持它的空间特征,得到一个完全卷积的网络。在上面的例子中,我们将一个 7681024 的图像放入 VGG,得到一个 24321000 的图层。2432 是图像的合并版本(乘 32 ), 1000 是图像网络类计数,从中我们可以导出上面的分割。
为了平滑预测,研究人员使用了一个简单的双线性上采样层。
在 FCN 的论文中,研究人员改进了上面的想法。他们沿途连接了一些层,以允许更丰富的解释,根据上采样率,这些层被命名为 FCN-32、FCN-16 和 FCN-8:
在层之间添加一些跳跃连接允许预测从原始图像中编码更精细的细节。进一步的训练进一步提高了成绩。
这种技术表明自己并不像想象的那么糟糕,并证明了深度学习在语义分割方面确实有潜力。
FCN results from the paper
FCN 解开了分段的概念,研究人员为此尝试了不同的架构。主要思想保持相似:使用已知的架构、上采样和使用跳过连接在较新的模型中仍然很突出。
你可以在一些好的帖子中读到这方面的进展:这里,这里和这里。您还可以看到,大多数架构都保留了编码器-解码器架构。
回到我们的项目
在做了一些研究后,我们选定了三种模型:FCN、 Unet 和提拉米苏 —非常深入的编码器-解码器架构。我们也有一些关于 mask-RCNN 的想法,但是实现它似乎超出了我们的项目范围。
FCN 似乎并不相关,因为它的结果并不像我们希望的那样好(即使作为一个起点),但是我们提到的另外两个模型显示了不错的结果:在 CamVid 数据集上的提拉米苏,以及 Unet 的主要优势是它的紧凑性和速度。就实现而言,Unet 的实现非常简单(我们使用了 keras ),而提拉米苏也是可实现的。为了让我们开始,我们在杰瑞米·霍华德的伟大的深度学习课程的最后一课中使用了提拉米苏的一个很好的实现。
有了这两个模型,我们开始在一些数据集上进行训练。我必须说,在我们第一次尝试提拉米苏后,我们看到它的结果对我们来说有更大的潜力,因为它有能力捕捉图像的清晰边缘。另一方面,unet 似乎不够好,结果似乎有点不太好。
Unet blobbiness
数据
在用模型设定了我们的大方向后,我们开始寻找合适的数据集。细分数据不像分类甚至检测那样常见。此外,手动标记实际上是不可能的。最常见的分割数据集是 COCO 数据集,它包括大约 80K 张 90 个类别的图像, VOC pascal 数据集,有 11K 张图像和 20 个类别,以及更新的 ADE20K 数据集。
我们选择使用 COCO 数据集,因为它包含了更多的" person "类的图像,这是我们感兴趣的类。
考虑到我们的任务,我们考虑是只使用与我们高度相关的图像,还是使用更通用的数据集。一方面,使用具有更多图像和类别的更通用的数据集将允许模型处理更多的场景和挑战。另一方面,一个通宵的培训课程让我们浏览了大约 15 万张图片。如果我们引入带有整个 COCO 数据集的模型,我们将以模型看到每张图像两次(平均)结束,因此稍微修剪一下将是有益的。此外,它将为我们的目的产生一个更集中的模型。
还有一点值得一提的是——提拉米苏模型最初是在 CamVid 数据集上训练的,该数据集有一些缺陷,但最重要的是它的图像非常单调:所有图像都是汽车的道路照片。正如你很容易理解的,从这样的数据集中学习(即使它包含人)对我们的任务没有好处,所以在短暂的尝试后,我们继续前进。
Images from CamVid dataset
COCO 数据集附带了非常简单明了的 API,它允许我们确切地知道每个图像中有什么对象(根据 90 个预定义的类)
经过一些实验后,我们决定稀释数据集:首先,我们只过滤有一个人的图像,给我们留下 40K 的图像。然后,我们丢弃了所有有很多人的图片,只留下一两张,因为这是我们的产品应该找到的。最后,我们只留下了 20%-70%的图像被标记为人物的图像,删除了背景中有一个非常小的人或某种怪异的怪物(不幸的是不是所有人)的图像。我们最终的数据集由 11K 的图像组成,我们觉得在这个阶段已经足够了。
Left: good image ___ Center: too many characters ___ Right: Objective is too small
提拉米苏模型
如前所述,我们在杰瑞米·霍华德的课程中被介绍了提拉米苏模型。虽然它的全名“100 层提拉米苏”意味着一个巨大的模型,但它实际上很经济,只有 9M 参数。相比之下,VGG16 的参数超过 130M。
****提拉米苏**模型基于 **DensNet,一种最新的图像分类模型,其中所有层都是相互连接的。此外,提拉米苏为上采样层添加了跳过连接,如 Unet。
如果你还记得的话,这个体系结构与 FCN 提出的想法是一致的:使用分类体系结构、上采样和添加跳过连接来进行细化。
Tiramisu Architecture in general
DenseNet 模型可以看作是 Resnet 模型的自然演变,但是 DenseNet 不会“记住”每一层直到下一层,而是记住整个模型中的所有层。这些连接被称为高速公路连接。它导致过滤器数量的膨胀,这被定义为“增长率”。提拉米苏的增长率为 16,因此每一层我们添加 16 个新的过滤器,直到我们达到 1072 层过滤器。你可能期望 1600 层,因为它是 100 层提拉米苏,然而,上采样层丢弃了一些过滤器。
Densenet model sketch — early filters are stacked throughout the model
培养
我们用原始论文中描述的时间表训练我们的模型:标准交叉熵损失,具有 1e-3 学习率和小衰减的 RMSProp 优化器。我们将 11K 图像分成 70%的训练、20%的验证和 10%的测试。以下所有图片均取自我们的测试集。
为了使我们的训练时间表与原始论文保持一致,我们在 500 幅图像上设置了纪元大小。这也允许我们定期保存结果中的每个改进的模型,因为我们在更多的数据上训练它(本文中使用的 CamVid 数据集包含不到 1K 的图像)
此外,我们只在两个类上训练它:背景和人,而报纸有 12 个类。我们首先尝试在 coco 的一些课上进行训练,但是我们发现这对我们的训练没有太大的帮助。
数据问题
一些数据集缺陷阻碍了我们的得分:
- 动物 —我们的模型有时会分割动物。这当然导致欠条低。把动物加到我们的任务中,在同一个主要类中或作为另一个类,可能会删除我们的结果
- 身体部位——因为我们用程序过滤了我们的数据集,我们没有办法判断 person 类实际上是一个人还是像手或脚这样的身体部位。这些图像不在我们的观察范围内,但仍然到处出现。
Animal, Body part, hand held object
- 手持物体- 数据集中的许多图像都与运动相关。棒球棒、网球拍和滑雪板随处可见。我们的模型不知何故弄不清应该如何分割它们。在动物的例子中,在我们看来,将它们作为主类的一部分或作为单独的类添加将有助于模型的性能。
Sporting image with an object
- 粗糙地面真相—coco 数据集没有逐个像素地进行注释,而是用多边形进行注释。有时这已经足够好了,但是其他时候地面实况非常粗糙,这可能会妨碍模型学习细微之处
Image and (very) Coarse ground truth
结果
我们的结果令人满意,尽管并不完美:在我们的测试集上,我们已经达到了 84.6 的 IoU,而当前的技术水平是 85。这个数字很棘手:它在不同的数据集和类中波动。有些类别本身更容易分割,例如房屋、道路,其中大多数模型很容易达到 90 IoU 的结果。其他更具挑战性的类别是树和人,在这些类别上,大多数模型达到大约 60 IoU 的结果。为了衡量这一困难,我们帮助我们的网络集中于单一类别和有限类型的照片。
我们仍然不认为我们的工作是“生产就绪”,因为我们希望它是,但我们认为这是一个很好的时间停下来讨论我们的结果,因为大约 50%的照片会给出好的结果。
下面是一些很好的例子,让你感受一下应用程序的功能:
Image, Ground truth, our result (from our test set)
调试和日志记录
训练神经网络的一个非常重要的部分是调试。在开始我们的工作时,很容易就进入正题,获取数据和网络,开始培训,看看会有什么结果。然而,我们发现跟踪每一步非常重要,为我们自己制造工具,以便能够检查每一步的结果。
以下是常见的挑战,以及我们所采取的应对措施:
- 早期问题 —模型可能没有训练。这可能是因为一些固有的问题,或者是因为某种预处理错误,比如忘记对一些数据块进行规范化。无论如何,简单的可视化结果可能会很有帮助。这里有一个关于这个主题的好帖子。
- 调试网络本身 —确保没有关键问题后,训练开始,使用预定义的损耗和指标。在分段中,主要的度量是IoU——交集超过并集。我们花了几节课才开始使用 IoU 作为我们模型的主要衡量标准(而不是交叉熵损失)。另一个有用的实践是显示我们的模型在每个时期的一些预测。这里有一个关于调试机器学习模型的好帖子。请注意,IoU 不是 keras 中的标准度量/损失,但您可以在网上轻松找到它,例如这里的。我们也使用这个要点来绘制每个时期的损失和一些预测。
- 机器学习版本控制 —在训练一个模型的时候,有很多参数,有些很难遵循。我必须说,我们仍然没有找到完美的方法,除了热情地写下我们的配置(和用 keras 回调自动保存最佳模型,见下文)。
- 调试工具——完成上述所有工作后,我们可以在每一步检查我们的工作,但不是无缝的。因此,最重要的步骤是将上述步骤结合在一起,创建一个 Jupyter 笔记本,使我们能够无缝加载每个模型和每个图像,并快速检查其结果。这样,我们可以很容易地看到模型之间的差异,陷阱和其他问题。
下面是通过调整参数和额外训练改进我们模型的一个例子:
对于保存到目前为止具有最佳验证 IoU 的模型:(Keras 提供了一个非常好的回调来使这些事情变得更容易)
callbacks = [keras.callbacks.ModelCheckpoint(hist_model, verbose=1,save_best_only =True, monitor= ’val_IOU_calc_loss’), plot_losses]
除了对可能的代码错误进行正常调试之外,我们还注意到模型错误是“可预测的”,例如“切割”看起来不在通用身体计数器中的身体部分,“咬”大段,不必要的继续延伸身体部分,光线差,质量差,以及许多细节。在添加来自不同数据集的特定影像时,处理了其中的一些警告,但其他警告仍是需要应对的挑战。为了改善下一个版本的结果,我们将在模型的“硬”图像上使用增强。
我们已经在上面提到过这个问题,关于数据集的问题。现在让我们看看我们的模型的一些困难:
- 衣服——深色或浅色的衣服有时会被理解为背景
- “咬”——其他的好结果,有一些咬在里面
Clothing and bite
3.光照不足的闪电和昏暗在图像中很常见,但在 COCO 数据集中却没有。因此,除了模型处理这些事情的标准难度之外,我们甚至还没有为更难的图像做好准备。这可以通过获取更多的数据以及数据扩充来改善。同时,最好不要在晚上尝试我们的应用程序:)
poor lighting example
进一步的进展选项
继续培训
我们的生产结果是在对我们的训练数据进行大约 300 个时期的训练后得出的。过了这个时期,模型开始过度拟合。我们在离发布很近的时候得到了这些结果,因此我们还没有机会应用数据扩充的基本实践。
在将图像大小调整为 224X224 后,我们对模型进行了训练。使用更多数据和更大图像(COCO 图像的原始大小约为 600X1000)的进一步训练也有望改善结果。
通用报告格式和其他改进
在某些阶段,我们看到我们的结果在边缘有点嘈杂。一个可能使这一点更加精确的模型是通用报告格式。在这篇博文中,作者展示了一个使用 CRF 的略显幼稚的例子。
然而,它对我们的工作不是很有用,也许因为它通常在结果粗糙时有所帮助。
铺垫
即使我们目前的结果,分割是不完美的。头发、精致的衣服、树枝等精细物体永远不会被完美分割,甚至因为地面真实分割不包含这些细微之处。分离这种精细分割的任务被称为抠图,并定义了一个不同的挑战。这里有一个艺术抠图的例子,在今年早些时候的 NVIDIA 会议上发表了。
Matting example — the input includes the trimap as well
抠图任务不同于其他与图像相关的任务,因为它的输入不仅包括图像,还包括三分图—** 图像边缘的轮廓,这使得它成为一个“半监督”问题。**
我们尝试了一点抠图,使用我们的分割作为三分图,但是我们没有达到显著的结果。
另一个问题是缺乏适当的数据集进行训练。
摘要
正如开始所说,我们的目标是建立一个重要的深度学习产品。正如你在 Alon 的帖子中看到的,部署变得越来越容易,越来越快。另一方面,训练一个模型是很棘手的——训练,尤其是在夜间进行的训练,需要仔细的计划、调试和记录结果。
在研究和尝试新事物,以及平凡的训练和提高之间取得平衡也不容易。自从我们使用深度学习以来,我们总是有一种感觉,即最佳模型,或我们需要的确切模型,就在眼前,另一个谷歌搜索或文章将带领我们找到它。但是在实践中,我们的实际改进来自于简单地从我们的原始模型中“挤压”越来越多的东西。如上所述,我们仍然觉得有更多的挤压出来。
总之,我们在做这项工作时获得了很多乐趣,几个月前,这在我们看来就像科幻小说。我们将很高兴讨论和回答任何问题,并期待在我们的网站上看到你:)
E 喜欢这篇文章吗?想要了解更多信息?参观www.shibumi-ai.com
糟糕的空气、病毒和 BI
来自 19 世纪伦敦的商业智能故事
(这个故事最早出现在 3AG Systems 博客 )
瘴气理论——认为疾病是由“不良空气”传播的古老信念——有一点真实性。当人们专注于掩盖臭味而不是改善卫生时,这一理论遇到了限制,正如许多人在 1858 年伦敦大恶臭期间所做的那样。值得庆幸的是,通过仔细的观察和思考,像约翰·斯诺这样受数据驱动的人成功地打破了流行的智慧,正确地确定了水传播疾病的根本原因。
一个现代的对等词是“误传”,当疾病因病毒误传而传播时就会发生。想想这里的反 vaxx 迷因。
我们如何描述发生在公司内部的类似现象?“误解”似乎已经够不祥的了。这实际上只是曲解这个词的一个花哨版本,但却格外庄重。
为什么误解会在组织内部传播?我想是因为它们都包含着一丝真理。他们是可信的。当足够多的人重复同样的误解时,很难有相反的意见。悲哀的是,在一个点头的房间里,孤独的反对者。
那么,公司如何预防病毒性误解呢?一种方法是鼓励不同意见。另一个方法是鼓励思想开放。但是,要建立一个强大的系统,公司需要投资于证据生成工具,这些工具可以尽早消除误解。这意味着投资于商业智能战略、数据挖掘工具、数据报告工具、预测分析,或许最重要的是,投资于数据可视化最佳实践,以确保人们能够正确解读呈现给他们的证据。
对公司的最终衡量是基于它们正确识别情况并做出适当反应的能力。拥有适当的工具来确保大众的智慧不仅仅是经常重复的误解似乎是明智的。
特别感谢 Nat Gyenesan 和 Xiao Mina 在《大西洋月刊》上发表的文章误导如何传播疾病。
做出数据驱动的决策。在 3AG Systems,我们通过将数据转化为可操作的见解来帮助企业改进。 了解更多 。
一言以蔽之,视觉词汇包
选择重要特征的艺术
Bag-of-visual-words (BOVW)
视觉单词包是图像分类中常用的方法。它的概念改编自信息检索和 NLP 的单词袋(BOW)。在 bag of words (BOW)中,我们统计每个词在一个文档中出现的次数,用每个词出现的频率来知道文档的关键词,并从中做出一个频率直方图。我们将文档视为一个单词包(BOW)。我们在视觉单词包(BOVW)中有相同的概念,但是我们用图像特征代替单词作为“单词”。图像特征是我们可以在图像中找到的独特模式。
Keywords in documents
什么是视觉单词包(BOVW)?
视觉单词包(BOVW)的基本思想是将图像表示为一组特征。特征由关键点和描述符组成。关键点是图像中“突出”的点,因此无论图像被旋转、缩小或扩展,其关键点将始终相同。描述符是对关键点的描述。我们使用关键点和描述符来构建词汇,并将每个图像表示为图像中特征的频率直方图。从频率直方图中,以后,我们可以找到另一个相似的图像或预测该图像的类别。
Histogram of visual words
如何建立一个视觉单词包(BOVW)?
我们检测特征,从数据集中的每个图像中提取描述符,并建立视觉字典。在图像中检测特征和提取描述符可以通过使用特征提取算法(例如,SIFT、KAZE 等)来完成。
Detecting features and extracting descriptor
接下来,我们根据描述符进行聚类(我们可以使用 K-Means、DBSCAN 或其他聚类算法)。每个聚类的中心将被用作视觉词典的词汇表。
Descriptors clustering
最后,对于每幅图像,我们从词汇和词汇在图像中的频率制作频率直方图。那些直方图是我们的视觉单词包(BOVW)。
我有一个图像,我想从数据集中找到另外 20 个类似的图像。我该怎么做呢?
给定另一幅图像(无论是否来自数据集),如前所述,我们检测图像中的特征,从图像中提取描述符,对描述符进行聚类,并构建与先前直方图长度相同的直方图。通过使用来自我们数据集的视觉单词包表示,我们可以计算该图像的最近邻。我们可以通过使用最近邻算法或其他算法来实现。
Image’s histogram
参考:
荣获 2005 年 ICCV 最佳短期课程奖李菲菲(史丹福),Rob…
people.csail.mit.edu](http://people.csail.mit.edu/torralba/shortCourseRLOC/)
平衡偏差和方差以控制机器学习中的错误
在机器学习的世界里,准确性就是一切。 你努力通过调谐和调整参数使你的模型更加精确,但永远无法使它 100%精确。这是关于你的预测/分类 模型的硬道理,它们永远不可能没有错误。在本文中,我将讨论为什么会发生这种情况,以及其他可以减少的错误形式。
假设我们正在观察一个响应变量 Y (定性或定量)和输入变量 X 具有 p 个特征或列(X1,X2……Xp)并且我们假设它们之间有关系。这种关系可以表示为
Y = f(X) + e
这里,f 是 X1、…、Xp 的某个固定但未知的函数,而 *e 是一个随机误差项,它独立于 X,均值为零。*在这个公式中,f 表示 X 提供的关于 y 的系统信息。这个关系或 f(X)的估计被称为统计学习。
一般来说,我们无法对 f(X)做出完美的估计,这就产生了一个误差项,称为可约误差。可以通过对 f(X)进行更精确的估计来提高模型的精确度,从而减小可约误差。 但是,即使我们对 f(X)做出 100%准确的估计,我们的模型也不会是无误差的,这就是所谓的不可约误差 (上式中的 e)。
换句话说,不可约误差可以看做是 X 无法提供的关于 Y 的信息 量 e 可能包含对预测 Y 有用的不可测量变量 :由于我们不测量它们,所以 f 无法用它们进行预测。 量 e 也可能包含不可测的变化。 例如,根据药物本身的生产差异或患者当天的总体健康状况,特定患者在特定日期出现不良反应的风险可能有所不同。
每个问题中都存在这样的最终情况,并且它们引入的误差是不可减少的,因为它们通常不存在于训练数据中。我们对此无能为力。我们能做的是减少其他形式的误差,以得到 f(X)的一个接近完美的估计。但是首先让我们来看看机器学习中的其他重要概念,为了更进一步,你需要理解这些概念。
模型复杂性
输入和响应变量之间关系 f(X)的复杂性是从数据集学习时要考虑的一个重要因素。简单的关系很容易解释。例如,线性模型应该是这样的
Y ≈ β0 + β1X1 + β2X2 + …+ βpXp
从这种关系中很容易推断出信息,而且它清楚地说明了特定特征如何影响响应变量。这种模型属于限制模型的范畴,因为它们只能采取特定的形式,在这种情况下是线性的。但是,关系可能比这更复杂,例如它可能是二次的、圆形的等等。这些模型更加灵活,因为它们更紧密地拟合数据点,可以采取不同的形式。通常这种方法会导致更高的精度。但是这种灵活性是以可解释性为代价的,因为复杂的关系更难解释。
选择灵活的模型并不总是保证高精度。发生这种情况是因为我们灵活的统计学习程序过于努力地寻找训练数据中的模式,而 可能拾取了一些只是由随机机会而不是由未知函数 f 的真实属性 引起的模式。这改变了我们对 f(X)的估计,导致模型不太准确。这种现象也被称为过拟合。
当推理是目标时,使用简单且相对灵活的统计学习方法有明显的优势。然而,在某些情况下,我们只对预测感兴趣,而对预测模型的可解释性根本不感兴趣。这是我们使用更灵活的方法的时候。
拟合质量
为了量化给定观察的预测响应值接近该观察的真实响应值的程度,回归设置中最常用的度量是均方误差(MSE),
Taken from Wikipedia
顾名思义,*它是所有输入的预测值和观测值的误差或差异的均方值。*用训练数据计算的称为训练 MSE ,用测试数据计算的称为测试 MSE 。
对于给定值 x0,预期测试 MSE 总是可以分解为三个基本量之和:f(x0)的方差、f(x0)的平方偏差和误差项 e 的方差,其中,e 是不可约误差,我们之前讨论过。所以,让我们看看更多关于偏差和方差的内容。
偏见
偏差是指用一个简单得多的模型来逼近一个可能极其复杂的现实问题所引入的误差。所以,如果真实的关系是复杂的,并且你试图使用线性回归,那么它无疑会导致对 f(X)的一些偏差。当真实的关系非常复杂时,无论你有多少观察值,如果你使用一个限制性的/简单的算法,都不可能产生一个准确的预测。
差异
方差是指如果我们使用 different 训练数据集来估计 f(X ),您对 f(x)的估计会改变的量。由于训练数据用于检验统计学习方法,different 训练数据集将产生 different 估计。但是理想情况下,对 f(X)的估计在训练集之间不应该变化太大。然而,如果一种方法具有高方差,那么训练数据中的小变化会导致 f(X)中的大变化。
一般规则
当使用试图过于紧密匹配数据点的统计方法时,数据集中的任何变化都将提供不同的估计,这是非常准确的。一般规律是, 当统计方法试图更紧密地匹配数据点或者使用更灵活的方法时,偏倚减少,但方差增加。
Credit : An Introduction to Statistical Learning by Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani
在上图中,左侧显示了回归设置中 3 种不同统计方法的图表。黄色的是线性的,而蓝色的是稍微非线性的,绿色的是高度非线性的/灵活的,因为它与数据点太接近了。在右侧,您可以看到这三种方法的 MSE 与灵活性的关系图。红色代表测试 MSE,灰色代表训练 MSE。不确定具有最低训练 MSE 的方法也将具有最低测试 MSE。 这是因为一些方法专门估算 coefficients,以最小化训练 MSE,但它们可能没有低测试 MSE。这个问题可以归结为过度拟合的问题。 如图所示,绿色曲线(最灵活)具有最低的训练 MSE,但不是最低的测试 MSE。让我们更深入地研究一下这个问题。
Credit : ISLR by Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani
这是一个图表,显示了特定数据集所选方法灵活性的测试 MSE(红色曲线)、偏差(绿色曲线)和方差(黄色曲线)。最小均方误差点是误差形式偏差和方差的一个有趣的点。它表明随着灵活性的增加,偏差减少的速度比方差增加的速度更快。在某个点之后,偏差不再减少,但是由于过度拟合,方差开始快速增加。
偏差-方差权衡
Credit : An Introduction to Statistical Learning by Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani
在上图中,假设目标的中心是一个完美预测正确值的模型。随着我们远离靶心,我们的预测变得越来越糟糕。想象一下,我们可以重复整个模型构建过程,以获得对目标的多次单独命中,这样每个蓝点就代表了基于同一问题的不同数据集的模型的不同实现。它显示代表高低偏差和方差组合的四种不同情况。高偏差是指所有的点都远离靶心,高方差是指所有的点都分散。结合前面的解释,这个例子清楚地说明了偏差和方差之间的区别。
如前所述,**为了最小化预期测试误差,我们需要选择一种统计学习方法,同时实现低方差和低偏差。**这些值之间总有一个 trade-off,因为很容易获得一个偏差极低但方差很大的方法(例如,通过绘制一条经过每个训练观察的曲线)或一个方差极低但偏差很大的方法(通过在数据上画一条水平线)。挑战在于找到一种方差和方差均较低的方法。
掌握偏差和方差之间的权衡是成为机器学习冠军的必要条件。
在解决机器学习问题时,应该记住这个概念,因为它有助于提高模型的准确性。此外,掌握这些知识有助于你快速决定不同情况下的最佳统计模型。
如果你喜欢这篇文章,一定要点击下面的❤来推荐它,如果你有任何问题,留下评论,我会尽力回答。
为了更加了解机器学习的世界,跟我来。这是最好的办法,等我多写点这样的文章就知道了。
也可以在 Twitter 关注我在@ pra shant _ 1722, 直接发邮件给我 或者 在 linkedin 上找我。我很乐意收到你的来信。
乡亲们,祝你们有美好的一天:)
推荐系统优化的拦路虎
任何在亚马逊上购物、在 Spotify 上听音乐、或者在网飞上浏览值得狂欢的电视连续剧的人都体验过个性化推荐。公司使用推荐系统来增加客户参与度和收入。这些算法将用户、产品和上下文元数据作为输入,并通过协作或基于内容的过滤方法产生个性化的动态内容作为输出。
推荐系统的质量通常通过 A/B 测试实验来衡量。然而,A/B 测试传统上用于测量静态 UI 变体中的转换率(例如,蓝色链接对绿色链接)。这就是为什么我在推荐系统的范围内探索多臂强盗作为 A/B 测试的替代。
我们将从经典的多臂土匪思想实验的概述开始。接下来将通过正式定义和示例对上下文多臂土匪进行讨论。最后,我们将传统的 A/B 测试实验与多臂 bandit 进行比较。
多兵种土匪问题
多臂土匪问题是从经典贝叶斯概率衍生出来的强化学习的一个例子。这是一个假设的实验,一个赌徒被给了一个有多个分支的老虎机,每个分支都有自己未知的概率分布。目标是在收集信息的同时按顺序一个接一个地拉动武器,以便在长期内最大化总支出。
更正式的描述假设奖励来自概率分布 a(y|θ),其中 a 表示采取的行动(或手臂运动);y是观察到的奖励,而 θ 是一组通过实验学习的未知参数[6]。多臂土匪问题的重要性在于我们(代理人)无法获得真正的土匪概率分布——所有的学习都是通过试错法和价值估计的方式进行的[7]。这被称为探索-开发权衡,即边学边赚。
背景强盗问题
情境土匪问题是对多臂土匪的一种概括,它通过使行动以环境状态为条件来扩展模型[3]。与经典的多臂 bandit 不同,它解决了在最佳时间为个人用户识别最合适内容的问题[2]。上下文信息可用于通过分类或聚类技术根据共享特征对用户进行分组,假设属于相同聚类的用户倾向于具有相似的行为,而位于不同聚类的用户具有显著不同的行为【1】。
以下是上下文多武装匪徒的正式定义:
Source: http://www.hongliangjie.com/2014/04/14/unbiased-offline-evaluation/
一个常见的真实世界上下文强盗的例子是新闻推荐系统。给定一组呈现的新闻文章,奖励由用户的点击行为决定。如果她点击了这篇文章,就会产生 1 英镑的支出,否则为 0 英镑[2]。点击率(CRT)用于确定新闻推荐应用程序中广告的选择和放置。
现在假设奖励由 CTR 结合关于用户的元数据(例如,年龄和性别)来确定,因此推荐可以进一步个性化。以一名 65 岁的女性和一名 18 岁的男性为例,两人都从他们的移动设备上阅读新闻文章。对这两个用户的推荐应该反映他们的对比概况。向 18 岁的男性展示退休计划或成熟女性服装店(例如 Talbots )的广告是没有意义的。
上下文信息还可以包括地理位置、时间、星期几和季节。假设地理位置元数据可通过 18 岁男性的移动设备获得。他离德克萨斯大学奥斯汀分校很近,并通过点击行为表达了对滑板和冲浪商店的兴趣。有了这个关于用户的上下文信息,应用程序应该显示他当前地理位置内的滑板和冲浪商店的广告(例如, Tyler 的)。如果是学期开始,比如说在九月或一月,应该为这个用户生成大学教科书商店(例如,大学合作)的广告,因为他很可能是购买教科书的大学生。
A/B 测试诉多武装匪徒
对于大多数现代互联网公司来说,只要有可以衡量的指标(例如,在一个页面上花费的时间、点击率、销售转化率),几乎总是在幕后进行随机试验,目的是确定一个替代网站设计,提供对默认设计的改进[8]。这个过程和方法通常被称为 A/B 测试。 A/B 检验是统计假设检验的一种形式,使用两个给定的样本 A 和 B,前者为对照,后者为变异体。给定一个默认配置和几个备选方案(例如,网站的配色方案),标准做法是将少量科学家流量转移到这些备选方案的随机试验中,并记录每个备选方案的期望指标[8]。
多臂 bandit 是 A/B 测试的替代方案。当存在差异时,多臂 bandit 方法在寻找最佳臂方面比传统的统计实验更有效,并且其优势随着臂数的增加而增加[6]。直觉上,我们需要给新内容分配更多的流量,以便更快地了解其价值,并减少用户跟踪现有内容的时间变化[2]。以下是 Google Analytics 的高级经济分析师 Steven L. Scott 对多臂土匪实验的好处的讨论:
基于多支武装匪徒的实验通常比基于统计假设检验的“经典”A-B 实验有效得多。它们在统计学上同样有效,而且在许多情况下,它们能更快地给出答案。它们更有效率,因为它们让流量逐渐走向成功的变化,而不是强迫你在实验结束时等待“最终答案”。它们速度更快,因为本来会出现明显较差变异的样本可以分配给潜在的赢家。在高性能变体上收集的额外数据可以帮助更快地将“好”臂与“最好”臂分开。
基本上,土匪让实验更有效率,你可以多尝试。你也可以分配更多的流量给你的实验,因为流量会自动导向性能更好的页面。
现在,让我们来并排比较一下这些竞争测试方法:
Source: https://conductrics.com/balancing-earning-with-learning-bandits-and-adaptive-optimization/
正如您从上面的图中看到的,A/B 测试并不适应整个实验阶段,因为勘探和开发阶段是静态和不同的,而多臂土匪通过同时勘探和开发进行调整。此外,对于多兵种土匪,分配给次等兵种/片的时间和资源更少。相反,在整个实验过程中,流量会逐渐分配给更优化的切片。土匪测试的一大好处是土匪减轻了“遗憾”,这基本上是你在测试中探索潜在的更坏的变化时所经历的转换损失[5]。
有关多武装匪徒的更多信息,请参见以下链接:
一种有效的实时多元优化 bandit 算法
亚马逊如何采用汤普森抽样的多臂强盗方法,在一周内增加 21%的购买量。
商业实用人工智能:强盗算法
Max Pagels 关于 bandit 算法及其实际商业应用的精彩演示。他通过清晰简洁的解释呈现了多种武器的强盗,这些解释比学术白皮书中复杂的论点更容易理解。
https://www . slide share . net/SC5/practical-ai-for-business-bandit-algorithms
使用依赖臂的多臂 Bandit 的在线交互式协同过滤
通过考虑项目间的依赖关系来讨论在线交互式协同过滤问题。
【https://arxiv.org/pdf/1708.03058.pdf
时变背景的多武装匪徒
报酬映射函数随时间变化的时变上下文多臂强盗问题的研究。
https://users.cs.fiu.edu/~taoli/pub/p2025-zeng.pdf
参考
[1]李,卡拉佐格鲁,和詹蒂莱。协同过滤土匪。https://arxiv.org/pdf/1502.03473.pdf
[2]李、朗福姆和沙皮雷。个性化新闻文章推荐的上下文相关方法。https://www.cs.princeton.edu/~schapire/papers/www10.pdf
[3]保罗·苏尔梅诺克。情境强盗和强化学习——走向数据科学。https://towards data science . com/contextual-bottoms-and-reinforcement-learning-6bdfeaece 72 a
[4]史蒂文·斯科特。多臂强盗实验。【https://support.google.com/analytics/answer/2844870?hl=en 号
[5]亚历克斯·伯基特。A/B 测试精通:从初学者到专家。【https://conversionxl.com/blog/ab-testing-guide/
[6]史蒂文·斯科特。在线服务经济中的多股武装匪徒。https://static . Google user content . com/media/research . Google . com/en//pubs/archive/42550 . pdf
[7]王,安森。解决多臂强盗问题。https://towards data science . com/solutioning-the-multi-armed-bandit-problem-b 72 de 40 db 97 c
[8]杨、拉姆达斯、贾米森和温赖特。具有在线 FDR 控制的多 A(rmed)/B(andit)测试框架。https://arxiv.org/pdf/1706.05378.pdf
争取你(竞争对手)的钱
Image from pexels.com
2014 年 12 月 23 日,iOS 游戏 The Room Two 的开发者醒来时发现了一些不可思议的巨额销售。事实上,至少比上个月的任何一天都要大。他们收到了 52 条评论,是前一周平均水平的两倍多。而且不止于此。在接下来的两周,第二会议室平均每天收到 60 条评论,几乎是 12 月 23 日之前一个月每天平均评论的三倍。这是圣诞奇迹吗?不知何故。事情是这样的:12 月 23 日,苹果在 AppStore 的首页打出了一条横幅,宣传包括每款 99 美分的“神奇应用&游戏”在内的促销活动。房间二是而不是特色应用之一。事实上,第二房间的竞争者、狮子座的财富之一也在其中。狮子座的财富价格降低了 75%至 99c。
Daily Review Volume for The Room Two mobile app. The dotted line represents that day the Leo’s Fortune went on 75% sale
是的,不仅竞争对手降价,苹果公司也大力促销。然而,不知何故,这帮助了房间二。
那么为什么会出现这种情况呢?苹果的 AppStore 就像今天的许多商店一样,根据用户的浏览和购买行为向他们推荐产品。与亚马逊在其产品页面中的“购买了该商品的顾客也购买了”部分非常相似,苹果在许多 iOS 应用程序的页面上都有“顾客也购买了”部分。这些推荐是由机器学习算法产生的,这些算法读取用户的观看/购买行为,并试图理解相关性:亚马逊知道经常购买这顶帽子的用户也会购买那些手套,网飞知道经常喜欢这个节目的用户也会观看另一个节目。而且苹果知道经常浏览/购买《狮子座的财富》的用户也浏览/购买了《房间二》。
再次关注苹果 AppStore 的具体设置,我们可以想象应用程序页面之间的这些联系会影响用户在应用程序之间的“行走”:如果我在愤怒的小鸟和水果忍者的页面上,我有可能会点击水果忍者图标并进入他们的页面。诸如此类。可以想象愤怒的小鸟页面访问量的突然增加或减少会对水果忍者页面的访问量产生实质性的影响。
作为我在西北大学博士论文的一部分,我收集并分析了 4 次大型 iOS 促销活动的数据,并获得了许多有趣的见解。在这篇文章中,我将集中讨论一个问题。我的问题很简单:一个应用页面访问量的突然增加如何影响该应用类似应用的访问量,即“顾客也购买了”栏目下的应用。
我发现了一个有趣的二分法。首先,我发现,当被推广的应用程序将其价格降至免费(即使其原价仅为 99 美分)时,其竞争对手的销售额大幅下降。这里有一个原因的解释:当一个用户看到一个点击和免费的东西时,没有什么可失去的。而且没有理由看得更远。
事情变得非常有趣了。当被推广的应用程序降价 3 美元或 9 美元时(记住这是 AppStore,中间价格是 0!)他们的竞争对手看到他们的销售额有了的增长。当用户看到一个在售但仍不免费的应用程序时,他们会有动力在做出承诺前进一步探索。除了查看页面上的其他应用程序,还有什么更好的探索方式呢?
总的来说,当一束假设的强光照射在一款免费应用上时,竞争对手的页面会变得更暗。但是当聚光灯照在一个 99 美分的应用上时(即使总的绝对折扣更大),竞争对手不可避免地会偷走一些光。
那么这对开发者意味着什么呢?
开发者,你需要意识到你的“邻居”和他们的行为。你的营销活动应该考虑到你的竞争对手在做什么,并实时做出反应。你应该意识到你的营销活动也能让他们受益。另一方面,如果奥普拉把你的一个竞争对手放在她的“银河中最喜欢的东西”列表中,不要失去所有的希望。只要竞争对手不是免费的,这也能促进你的销售。
这对苹果意味着什么?
苹果的激励措施之一是通过不断向用户提供优秀的创新应用来尽可能地让他们开心。但是 AppStore 有超过 150 万个应用程序,因此没有一个用户会去探索哪怕是整个系列中的一小部分。这正是这些推荐系统诞生的初衷:帮助用户发现和浏览新内容。
不可避免的是,任何这样的大型系统都会将大部分成功集中在少数几个应用程序上。随着成功的应用程序变得越来越成功,富人变得越来越富的效应也会出现一些变化。
我们的发现可以为苹果(以及任何其他集中式市场)提供另一种方式,以某种方式“推动”成功的分布:通过巧妙地决定如何填充“顾客也购买了”部分。例如,如果一款应用获得了广泛的成功,将它放在更少的付费应用的“顾客也购买了”部分是一个好主意,这样就可以为其他不太成功但同样出色的应用腾出位置。
超越苹果和移动应用
产生这篇文章的数据是特定于苹果的应用商店的,但是洞察力不是。类似的效果发生在所有类型的具有这种推荐算法的平台上。任何类型的卖家都应该意识到他们的营销活动会以意想不到的(有时是积极的)方式影响他们的竞争对手。对他们来说,集中式市场可以利用这些见解更好地在他们平台的卖家中分配焦点,并进一步帮助他们的客户发现优秀的内容。
感谢阅读!
这篇文章最初写于 2016 年,当时约尔戈斯还是一名博士生,从事在线消费者评论的研究。
依靠事实——专家意见有什么价值?
Maptive
几年前,当我开始下一项任务时,我接待了三位新同事的来访。我很惊讶地听到第一个人承认“在这里你必须学会的第一件事是,每个人都在所有事情上撒谎”。第二个来访者不再令人鼓舞地证明只有她一个人说了实话。第三个来访者——正如他们在法语中所说的“没有三个人的两个人”——试图让我“放心”,如果前两个人说实话,他们会被闪电击中。在一个虚伪的世界里,人们要么永远诚实,要么永远虚伪,我的三个来访者中,哪一个值得相信?【我】
在一个越来越以假新闻和另类事实为标志的后真相世界里,这个故事在我的脑海中依然清晰可见。尽管同事们公然歪曲数据的情况非常罕见,但区分事实和虚构绝非易事。当今管理面临的复杂问题挑战了真理的单一版本的概念。这些挑战使得选择最佳行动方案变得更有价值,无论是在鉴定业务的“无形资产”、提高管理效率还是衡量客户满意度方面。征求专家的意见并不能解决很多问题,因为他们通常更愿意回忆过去,而不是规划未来。如果经理的工作是根据事实做出决定,他或她怎么能指望专家的建议呢?
为什么如此多的专家,即使是真诚的,也只能提供可怜的建议?风险、不确定性和模糊性等不利因素通常会阻碍专家客观评估新挑战的能力。依赖“机器学习”并不能解决问题——对于许多关键变量,每个算法都依赖于这些专家的主观估计。他们的建议意见很少因为他们对这些模型的信任而调整——他们计算客观概率,而不考虑他们自己的偏见、怀疑和对手头问题的理解。Julia Galef 将这种倾向称为“动机推理”,专家(像大多数其他人一样)倾向于优先考虑与他们自己的精神状态相对应的数据。【ii】套用幽默作家乔希·比林斯的话“问题不在于你的专家们知道什么,而在于他们如何确定事实并非如此”。【iii】
无需求助于昂贵且耗时的“大数据”和“人工神经网络”,可以使用几种相对简单的方法来证实并最终校准专家的观察能力。正如道格·哈伯德(Doug Hubbard)所建议的,将适当的方法应用于非常小的样本可以大大减少不确定性的来源。他提倡“五法则”,即评估一个分布的五个随机估计值提供了 93 . 5%的置信指数,即它的中值在最低和最高估计值之间。类似地,捕获/再捕获方法基于超几何分布有效地估计大种群的规模。【VI】定点取样提供了另一种选择,它随着时间的推移随机拍摄现象的快照,而不是不断地跟踪它们。最后,通过简单地识别随机的一组观察值,然后与该组一起采样,聚类采样产生了令人惊讶的好结果。【VII】
本文开头的谜语是“骑士和无赖”谜题的一个应用,我们假设骑士永远不会说谎,而无赖永远不会说真话。因为陈述是矛盾的,在测试假设时,只有第二个来访者内心是真实的。在商业中,背景和解决方案都更加复杂,因为事实和虚构之间的界限往往很模糊。学会利用手头的数据来支持或配合每个专家的观点可以帮助我们减少专家自身认知偏差的影响。提高决策能力是商业分析学院、暑期学校和大师班的核心。提高自己的决策能力只需点击一下鼠标。
Lee Schlenker 是 Pau 商学院的教授,也是 http://baieurope.com 商业分析学院的负责人。 他的领英简介可以在【www.linkedin.com/in/leeschlenker.】查看 你可以在https://twitter.com/DSign4Analytics关注我们的推特
【I】改编自 Smullyan,R. (1978)。这本书叫什么名字?。普伦蒂斯霍尔
【ii】Galef,J. (2016),人类擅长辩论,却不擅长推理。Heleo 对话
【三世】比尔盖茨,J. (1874)。智慧和幽默的百科全书和谚语哲学
贝叶斯定理将在另一篇文章中展开。
Hubbard,D. (2014),如何衡量任何事物:寻找商业中“无形资产”的价值
【VI】【马】d .(2010)捕获/再捕获方法,概率统计博客
神经网络
初学者的基本概念
torres.ai
同样,当你开始用一种新语言编程时,有一个用 Hello World print 做这件事的传统,在深度学习中,你首先要创建一个手写数字的识别模型。通过这个例子,这篇文章将介绍神经网络的一些基本概念,尽可能减少理论概念,目的是为读者提供一个特定案例的全局视图,以方便阅读后续文章,其中该领域的不同主题将得到更详细的处理。
研究案例:数字识别
在这一节中,我们将介绍我们将用于第一个神经网络示例的数据:MNIST 数据集,它包含手写数字的图像。
MNIST 数据集可以从MNIST 数据库页面【1】下载,由手工制作的数字图像组成。该数据集包含用于训练模型的 60,000 个元素和用于测试模型的 10,000 个附加元素,并且对于第一次进入模式识别技术来说是理想的,而不必花费大量时间预处理和格式化数据,这在数据分析中是非常重要和昂贵的步骤,并且在处理图像时具有特殊的复杂性;这个数据集只需要很小的改动,我们将在下面进行评论。
这个黑白图像数据集已被归一化为 20×20 像素,同时保留了它们的纵横比。在这种情况下,重要的是要注意图像包含灰度级,这是归一化算法中使用的反走样【2】技术的结果(将所有图像的分辨率降低到较低的分辨率)。随后,图像以 28×28 像素为中心,计算这些像素的质心并移动图像,以便将该点定位在 28×28 视场的中心。这些图像具有以下样式:
Pixel images of handwritten texts (From: MNIST For ML Beginners, tensorflow.org)
此外,数据集对每张图像都有一个标签,表明它代表哪个数字,因此是一种监督学习,我们将在本章中讨论。
该输入图像用矩阵表示,每个 28×28 像素的亮度值在[0,255]之间。例如,此图像(训练集的第八个图像)
用这个 28×28 点的矩阵来表示(读者可以在本章的笔记本上查一下):
另一方面,记住我们有标签,在我们的例子中是 0 到 9 之间的数字,表示图像代表哪个数字,也就是说,它与哪个类相关联。在这个例子中,我们将用 10 个位置的向量来表示每个标签,其中对应于表示图像的数字的位置包含 1,其余的包含 0。这个将标签转换成与不同标签的数量一样多的零的向量,并将 1 放入对应于标签的索引中的过程被称为独热编码。
感知器
在继续之前,对单个神经元如何工作以实现其从训练数据集学习的目的的简单直观的解释可能对读者有所帮助。让我们看一个非常简单的例子来说明人工神经元如何学习。
回归算法
基于上一章已经解释的内容,让我们对经典的机器学习回归和分类算法做一个简单的提醒,因为它们是我们深度学习解释的起点。
我们可以说,回归算法使用误差测量值损失对不同输入变量(特征)之间的关系进行建模,这将在迭代过程中被最小化,以便“尽可能准确地”做出预测。我们将讨论两种类型:逻辑回归和线性回归。
逻辑回归和线性回归的主要区别在于模型的输出类型;当我们的输出是离散的时,我们谈论逻辑回归,当输出是连续的时,我们谈论线性回归。
根据第一章中介绍的定义,逻辑回归是一种监督学习算法,用于分类。我们接下来将使用的示例是一个二元分类,它通过分配 0 或 1 类型的离散值来识别每个输入示例属于哪个类。
普通的人工神经元
为了展示基本神经元是怎样的,让我们假设一个简单的例子,其中我们在二维平面中有一组点,并且每个点已经被标记为“正方形”或“圆形”:
给定一个新的点“ X ,我们想知道它对应的标签是什么:
一种常见的方法是画一条线将两个组分开,并使用这条线作为分类器:
在这种情况下,输入数据将由( x1,x2 )形式的向量表示,这些向量表示它们在这个二维空间中的坐标,我们的函数将返回‘0’或‘1’(在线的上方或下方),以知道它应该被分类为“正方形”还是“圆形”。正如我们已经看到的,这是一个线性回归的例子,其中遵循第 1 章给出的符号的“线”(分类器)可以定义为:
更一般地说,我们可以将这条线表示为:
为了对输入元素 X 进行分类,在我们的例子中输入元素 X 是二维的,我们必须学习与输入向量维数相同的权重向量 W,即向量( w1,w2 )和 b 偏差。
有了这些计算值,我们现在可以构建一个人工神经元来对新元素 X 进行分类。基本上,神经元将计算出的权重的向量 W 应用于输入元素 X 的每个维度中的值,并在最后添加偏差 b. 其结果将通过非线性“激活”函数来产生结果“0”或“1”。我们刚刚定义的这种人工神经元的功能可以用更正式的方式来表达,例如:
现在,我们将需要一个函数来对变量 z 进行转换,使其变为‘0’或‘1’。虽然有几个函数(我们将在第 4 章中称之为“激活函数”),但在本例中,我们将使用一个被称为sigmoid【3】的函数,该函数针对任何输入值返回 0 到 1 之间的实际输出值:
如果我们分析前面的公式,我们可以看到它总是倾向于给出接近 0 或 1 的值。如果输入 z 相当大且为正,则负 z 处的“e”为零,因此 y 取值为 1。如果 z 具有大的负值,那么对于“e”的大正数,公式的分母将是一个大的数字,因此 y 的值将接近 0。从图形上看,sigmoid 函数呈现如下形式:
到目前为止,我们已经介绍了如何定义人工神经元,这是神经网络可以拥有的最简单的架构。具体来说,这种架构在本主题的文献中被命名为感知器【4】(也称为线性阈值单元 (LTU)),由 Frank Rosenblatt 于 1957 年发明,并在视觉上概括为以下方案:
最后,让我帮助读者直观地了解这个神经元如何从我们已经标记为“正方形”或“圆形”的输入数据中学习权重 W 和偏差 b (在第 4 章中,我们将介绍如何以更正式的方式完成这个过程)。
对于所有已知的带标签的输入示例,这是一个迭代过程,将通过模型估计的标签值与每个元素的标签期望值进行比较。在每次迭代之后,以这样的方式调整参数值,即随着我们以最小化上述损失函数为目标继续迭代,所获得的误差变得越来越小。下面的方案希望以一种通用的方式直观地总结一个感知器的学习过程:
多层感知器
但是在继续讨论这个例子之前,我们将简要介绍当神经网络是由我们刚刚介绍过的感知器构造而成时,它们通常采用的形式。
在该领域的文献中,当我们发现神经网络具有一个输入层,一个或多个由感知器组成的层,称为隐藏层,以及具有几个感知器的最后一层,称为输出层时,我们称之为多层感知器(MLP)。一般来说,当基于神经网络的模型由多个隐藏层组成时,我们称为深度学习。在视觉上,它可以用以下方案来表示:
MLP 通常用于分类,特别是当类别是排他性的时,如在数字图像分类的情况下(从 0 到 9 的类别)。在这种情况下,由于一个名为 softmax 的函数,输出图层返回属于每个类的概率。视觉上,我们可以用以下方式表示它:
正如我们将在第四章介绍的,除了 sigmoid 之外,还有几个激活函数,每个都有不同的属性。其中之一就是我们刚刚提到的那个 softmax 激活函数【5】,它将有助于呈现一个简单的神经网络的示例,以在两个以上的类中进行分类。目前,我们可以将 softmax 函数视为 sigmoid 函数的推广,它允许我们对两个以上的类进行分类。
Softmax 激活功能
我们将以这样的方式来解决这个问题:给定一个输入图像,我们将获得它是 10 个可能数字中的每一个的概率。这样,我们将有一个模型,例如,可以预测图像中的 9,但只有 80%的把握是 9。由于这张图片中数字底部的笔画,它似乎有 5%的几率成为 8,甚至有一定的概率成为任何其他数字。虽然在这种特殊情况下,我们会认为我们的模型的预测是 9,因为它是概率最高的一个,但这种使用概率分布的方法可以让我们更好地了解我们对预测的信心程度。这在这种情况下很好,因为数字是手工制作的,当然在很多情况下,我们不能 100%确定地识别数字。
因此,对于这个 MNIST 分类的例子,我们将为每个输入例子获得一个输出向量,该输出向量具有在一组互斥标签上的概率分布。也就是说,10 个概率的向量(每个概率对应于一个数字)以及所有这 10 个概率的总和导致值 1(概率将在 0 和 1 之间表示)。
正如我们已经提出的,这是通过在我们的具有 softmax 激活函数的神经网络中使用输出层来实现的,其中该 softmax 层中的每个神经元依赖于该层中所有其他神经元的输出,因为所有这些神经元的输出之和必须是 1。
但是 softmax 激活功能是如何工作的呢?softmax 函数基于计算特定图像属于特定类别的“证据”,然后将这些证据转换为它属于每个可能类别的概率。
一种测量某一图像属于特定类别的证据的方法是对属于该类别的每个像素的证据进行加权求和。为了解释这个想法,我将使用一个可视化的例子。
假设我们已经学习了数字 0 的模型(我们将在后面看到这些模型是如何学习的)。目前,我们可以把模型看作是“某种东西”,它包含了知道一个数是否属于某一类的信息。在这种情况下,对于数字 0,假设我们有一个如下所示的模型:
Source: Tensorflow tutorial[6])
在这种情况下,对于 28×28 像素的矩阵,其中红色像素(在书的白/黑版本中是最浅的灰色)表示负权重(即,减少其所属的证据),而蓝色像素(在书的黑/白版本中是最深的灰色)表示正权重(其证据是更大的增加)。黑色代表中性值。
假设我们在上面画了一个零。一般来说,零点的轨迹会落在蓝色区域(请记住,我们讨论的是归一化为 20×20 像素的图像,后来以 28×28 的图像为中心)。很明显,如果我们的笔画越过红色区域,很可能我们写的不是零;因此,使用基于如果我们通过蓝色区域则相加,如果我们通过红色区域则相减的度量标准似乎是合理的。
为了确认它是一个好的度量,现在让我们想象我们画了一个三;很明显,我们用于零的前一个模型中心的红色区域会影响前面提到的指标,因为,正如我们在该图的左部看到的,当写 3 时,我们忽略了:
Source: Tensorflow tutorial[6])
但另一方面,如果参考模型是对应于数字 3 的模型,如上图右侧所示,我们可以看到,一般来说,代表数字 3 的不同可能走线大多位于蓝色区域。
我希望读者看到这个直观的例子后,已经直觉地知道上面提到的权重的近似值是如何让我们估计出它是多少的。
Source: Tensorflow tutorial[6])
上图显示了为这十个 MNIST 类中的每一个学习的具体模型示例的权重。请记住,在这个视觉表示中,我们选择了红色(黑白图书版中的浅灰色)来表示负权重,而我们将使用蓝色来表示正权重。
一旦属于 10 个类别中的每一个的证据被计算出来,这些必须被转换成概率,其所有成分的总和加 1。为此,softmax 使用计算证据的指数值,然后将它们归一化,使总和等于 1,形成概率分布。属于类别 i 的概率为:
直观地说,使用指数得到的效果是,多一个单位的证据具有乘数效应,少一个单位的证据具有反效应。关于这个函数有趣的事情是,一个好的预测在向量中有一个接近 1 的值,而其余的值接近 0。在弱预测中,将有几个可能的标签,它们将具有或多或少相同的概率。
参考文献
【1】MNIST 手写数字数据库。[en línea]。可在:http://yann.lecun.com/exdb/mnist【咨询日期:2017 年 2 月 24 日】。
【2】维基百科,(2016)。抗锯齿。可用地点:【https://es.wikipedia.org/wiki/Antialiasing【访问时间:2016 年 9 月 1 日】。
【3】维基百科,(2018)。乙状结肠函数。可用时间:https://en.wikipedia.org/wiki/Sigmoid_function【访问时间:2018 年 2 月 3 日】。
【4】维基百科(2018)。感知器。可在https://en.wikipedia.org/wiki/Perceptron获得【2018 年 12 月 22 日访问】
【5】维基百科,(2018)。Softmax 函数[en línea]。可用地点:https://en.wikipedia.org/wiki/Softmax_function【访问时间:2018 年 2 月 22 日】。
【6】tensor flow,(2016)教程 MNIST 初学者。[en línea]。可在:https://www . tensor flow . org/versions/r 0.12/tutorials/mnist/初学者/ 【访问时间:2018 年 16 月 2 日】。
原载于 2018 年 9 月 16 日Torres . ai。
[基础数据清理/工程会议] Twitter 情绪数据
Gif from this website
所以这篇文章只是让我练习一些基本的数据清理/工程操作,我希望这篇文章能够帮助其他人。
请注意,这篇文章是为了我将来回顾数据清理/工程 方法,而不是重新研究。
推特 Kaggle 数据集
Image from this website
我将使用 Kaggle 的 Twitter 情绪分析数据。该数据包含 8.7 MB 的(训练)文本数据,这些数据是从 Twitter 中提取的,没有经过预处理。
原始文本数据的第一视图
如上所述,我们可以直接注意到数据中包含了大量的停用词和一些俚语(如 bf → Boy Friend ),需要替换或完全删除。
步骤 0)将数据读入 Panda 数据帧和基本审查
如上所示,当我们打印一些关于数据的基本信息时。我们可以马上注意到每行是如何用 int64 或 Object(对于 TextData)表示的。最后,当我们绘制情感数据的直方图时,我们可以知道正面例子比负面例子多。(1 表示积极情绪,而 0 表示消极情绪。)
步骤 1)清除停止字【清洗】
为了更快地执行,我将只使用前 5 行来清理示例数据,如上所示,当我们删除所有的停用词(如 is、so 等)时。)句子变得更干净了。
一个例子是**“我的天已经 7:30 了”→“我的天已经 7:30 了”**
步骤 2)替换缩写和一些拼写更正【清理】
借用这篇博客文章中的代码,我们将把一些俚语替换成更合适的单词,并做一些拼写纠正。我们可以注意到,一些社交媒体俚语已经变成了完整的词,如“哦,我的上帝”或“男朋友”。
一个例子是**“OMG 已经 7:30 了”→“天哪已经 7:30 了”**
步骤 3)词干化【新功能】
词干化是将屈折词(或有时是派生词)简化为词干、词根或词根形式的过程。如上所述,这个词已经变成了“已经”,以及“欺骗”。如果你想了解更多关于这些话题的信息,请点击这里阅读我对 30 个数据科学家问题的看法。
步骤 4)词汇化【新功能】
词汇化是将一个单词的词尾变化形式组合在一起的过程,因此它们可以作为一个单独的项目进行分析,通过单词的词汇或词典形式进行识别。这个过程与词干提取非常相似,但是我们可以注意到的一个区别是,单词没有变成 already。如果您希望了解有关这些主题的更多信息,请单击此处阅读我对 30 个数据科学家问题的看法。
步骤 5)词性标注(POS)【新功能】
词性标注是语法标注或词类消歧,是根据定义和上下文将文本(语料库)中的单词标记为对应于特定词性的过程。如上所述,我们已经将句子中的每个单词标记为动词、名词或代词等。
步骤 6)大写
最后,我只是想尝试一下,因为大写被认为是 NLP 中的降维技术,因为它减少了表示原始文本所需的字符。(将所有字符转换成小写具有相同的效果。)
互动码
对于 Google Colab,你需要一个 Google 帐户来查看代码,而且你不能在 Google Colab 中运行只读脚本,所以在你的操场上复制一份。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!
要访问这篇文章中使用的代码,请点击这里。
最后的话
我目前正在学习更多关于 NLP 环境下的数据清理和工程的知识,这是练习我的技能的好方法。但下一次我希望创造更复杂的功能。
如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请点击这里查看我的网站。
同时,在我的推特这里关注我,访问我的网站,或者我的 Youtube 频道了解更多内容。我还实现了广残网,请点击这里查看博文 pos t。
参考
- 推特情绪分析| Kaggle。(2018).Kaggle.com。检索于 2018 年 5 月 27 日,来自https://www . ka ggle . com/c/Twitter-情操-分析 2 #评价
- UnicodeDecodeError,i. (2018)。UnicodeDecodeError,无效的延续字节。堆栈溢出。检索于 2018 年 5 月 27 日,来自https://stack overflow . com/questions/5552555/unicode decodedeerror-invalid-continuation-byte
- dataframe,P. (2018 年)。Python 删除了熊猫数据帧中的停用词。堆栈溢出。检索于 2018 年 5 月 27 日,来自https://stack overflow . com/questions/29523254/python-remove-stop-words-from-pandas-data frame
- python,H. (2018)。如何使用 nltk 或 python 删除停用词?堆栈溢出。检索于 2018 年 5 月 27 日,来自https://stack overflow . com/questions/5486337/how-to-remove-stop-words-using-nltk-or-python
- 熊猫?,H. (2018)。如何应对熊猫中设置 SettingWithCopyWarning?。堆栈溢出。检索于 2018 年 5 月 27 日,来自https://stack overflow . com/questions/20625582/how-to-deal-withcopywarning-in-pandas
- 城市词典:APL。(2018).都市词典。检索于 2018 年 5 月 28 日,来自https://www.urbandictionary.com/define.php?term=APL
- dataframe,P. (2018 年)。Python 删除了熊猫数据帧中的停用词。堆栈溢出。检索于 2018 年 5 月 28 日,来自https://stack overflow . com/questions/29523254/python-remove-stop-words-from-pandas-data frame
- Python 脚本将文本/消息缩写转化为实际短语。(2017).中等。检索于 2018 年 5 月 28 日,来自https://medium . com/nerd-stuff/python-script-to-turn-text-message-abstracts-into-actual-phrases-d5db 6 f 489222
- ‘数据’,N. (2018)。NLTK-attribute 错误:模块“NLTK”没有属性“data”。堆栈溢出。检索于 2018 年 5 月 28 日,来自https://stack overflow . com/questions/45786059/nltk-attribute error-module-nltk-has-no-attribute-data
- Python?,W. (2018)。Python 中最好的词干法是什么?。堆栈溢出。检索于 2018 年 5 月 28 日,来自https://stack overflow . com/questions/24647400/what-is-the-best-stemming-method-in-python
- Stemmers。(2018).Nltk.org。检索于 2018 年 5 月 28 日,来自http://www.nltk.org/howto/stem.html
- 自然语言机器学习中的预处理。(2017).走向数据科学。检索于 2018 年 5 月 28 日,来自https://towardsdatascience . com/pre-processing-in-natural language-machine-learning-898 a 84 b 8 BD 47
- 引理化?,H. (2018)。我如何做词干或词汇化?。堆栈溢出。检索于 2018 年 5 月 28 日,来自https://stack overflow . com/questions/771918/how-do-I-do-word-stemming-or-lemmatization
- 大写,H. (2018)。如何将一个字符串变成大写?堆栈溢出。检索于 2018 年 5 月 28 日,来自https://stack overflow . com/questions/9257094/how-to-change-a-string-to-upper case
- TypeError:序列项 0:应为字符串 i. (2018)。TypeError:序列项 0:预期的字符串,找到的是 int。堆栈溢出。检索于 2018 年 5 月 28 日,来自https://stack overflow . com/questions/10880813/type error-sequence-item-0-expected-string-int-found
- 下载?,W. (2018)。NLTK POS tagger 让我下载的是什么?。堆栈溢出。检索于 2018 年 5 月 28 日,来自https://stack overflow . com/questions/8590370/what-is-nltk-pos-tagger-questing-me-download
- 堵塞。(2018).En.wikipedia.org。检索于 2018 年 5 月 28 日,来自 https://en.wikipedia.org/wiki/Stemming
- 我用 30 个问题来测试一个数据科学家在自然语言处理方面的交互能力。(2018).中等。检索于 2018 年 5 月 28 日,来自https://medium . com/@ SeoJaeDuk/my-take-on-30-questions-to-test-a-data-scientist-on-natural-language-processing-with-interactive-5b 3454 a 196 ef
- 词性标注。(2018).En.wikipedia.org。检索于 2018 年 5 月 28 日,来自https://en.wikipedia.org/wiki/Part-of-speech_tagging
- 引理满足。(2018).En.wikipedia.org。检索于 2018 年 5 月 28 日,来自https://en.wikipedia.org/wiki/Lemmatisation
- 我用 30 个问题来测试一个数据科学家在自然语言处理方面的交互能力。(2018).中等。检索于 2018 年 5 月 28 日,来自https://medium . com/@ SeoJaeDuk/my-take-on-30-questions-to-test-a-data-scientist-on-natural-language-processing-with-interactive-5b 3454 a 196 ef
基础医疗数据探索/可视化——心脏病
GIF from this website
今天,我想再次练习我的数据探索技能,我想在这个 心脏病数据集 上练习。
请注意,这篇帖子是为了我未来的自己回顾和回顾数据探索的基本技术。
数据集
Image from this website
这个数据集包含 302 个患者数据,每个数据有 75 个属性,但是我们只使用其中的 14 个,如下图所示。
如果有人对每个属性的确切含义感兴趣,请看看下面的屏幕截图。
Image from this website
数据集概述/清理/查看
红框 →数据类型对象
像往常一样,让我们从简单的开始,看看一般的平均值,标准差和其他东西。很快,我们可以认识到我们的一些数据是在对象类型中。
然而,我们也可以观察到没有空变量的事实。
在进行简单的清理后,将非数字值更改为 NaN 并用 0 替换 NaN。我们现在可以有把握地说,我们的数据有些干净。
前/后 10 行
同样,为了更好地理解数据,让我们检查第一/最后几行。如上所述,没有什么太不寻常的。
数据直方图
通过简单的数据直方图,我们可以很容易地观察到不同属性的分布。这里需要注意的一点是,我们很容易看出哪些属性是分类值,哪些不是。
为了更仔细地观察,让我们来看看年龄和空腹血糖的分布。我们可以看到,年龄分布非常类似于高斯分布,而 fbs 是一个分类值。
方差-协方差矩阵
上面看到的所有图像都是方差-协方差矩阵,然而不同的是,对于最左边的一个,我使用 Numpy 手动计算。中间的那个我用了 Tensorflow,最后右边的那个我用了内置的数据框函数。而且我们可以观察到,大多数属性并没有很强的协变关系。
相关矩阵
同样,左边的图像是通过手动 numpy 计算创建的,我们可以观察到,在这些属性中,实际上彼此之间有很强的相关性。(尤其是心脏病和 thal)
交互式直方图
现在我知道这是多余的,但我想包括,因为有一个互动的部分。👌 👌
柱状图/箱线图/对线图
让我们先来看看心脏病患者和非心脏病患者的平均年龄。我们可以观察到年龄稍大的人患心脏病的几率更大。(仅来自这个数据集。)
同样,当我们创建一个与患有/未患有心脏病的平均人数相关的方框图时,我们可以观察到年轻人患心脏病的可能性较小。
最后,我想展示这一对相对于一些属性的图,如年龄、身高、ca
(胸痛类型)、thalach(达到的最大心率)和心脏病的存在。从相关矩阵中可以看出,我们可以观察到年龄和 thalach 之间有很强的负相关性。
一致流形逼近和投影嵌入(UMAP)
t 分布随机邻居嵌入(t-SNE)
再次遵循之前博文的传统,我想执行简单的降维技术,看看我们是否能够将数据分成两组。如上所述,umap 在聚类每个类方面做得相当不错。
最后,上面是 t-SNE 降维的结果图。
GitHub 代码
要获取这篇文章的代码,请点击这里。
遗言
这是另一个很好的绘图和简单的数据探索会议,我希望在不久的将来创造更多的先进的阴谋。
如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请在这里查看我的网站。
同时,在我的推特这里关注我,并访问我的网站,或我的 Youtube 频道了解更多内容。我还实现了广残网,请点击这里查看博文 pos t。
参考
- UCI 机器学习知识库:心脏病数据集。(2018).Archive.ics.uci.edu。检索于 2018 年 6 月 25 日,来自https://archive.ics.uci.edu/ml/datasets/Heart+Disease
- RPubs——用于心脏病预测的机器学习。(2016).Rpubs.com。检索于 2018 年 6 月 25 日,来自 https://rpubs.com/mbbrigitte/heartdisease
- DataFrame,H. (2018)。如何给熊猫数据框添加标题行?堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/34091877/how-to-add-header-row-to-a-pandas-data frame
- JaeDukSeo/每日神经网络实践 2。(2018).GitHub。检索于 2018 年 6 月 25 日,来自https://github . com/JaeDukSeo/Daily-Neural-Network-Practice-2/blob/master/Medical _ EXP/Pima _ Indians/a . ipynb
- 熊猫。data frame . describe—pandas 0 . 23 . 1 文档。(2018).Pandas.pydata.org。检索于 2018 年 6 月 25 日,来自https://pandas . py data . org/pandas-docs/stable/generated/pandas。DataFrame.describe.html
- Pandas DataFrame:替换一列中的所有值,b. (2018)。Pandas DataFrame:根据条件替换列中的所有值。堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/31511997/pandas-data frame-replace-all-values-in-a-column-based-on-condition
- 系列?,P. (2018)。熊猫—如何在 DataFrame 系列中用零值替换字符串?。堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/33440234/pandas-how-to-replace-string-with zero-values-in-a-data frame-series
- pandas . to _ numeric-pandas 0 . 23 . 1 文档。(2018).Pandas.pydata.org。检索于 2018 年 6 月 25 日,来自https://pandas . pydata . org/pandas-docs/stable/generated/pandas . to _ numeric . html
- dataframe,H. (2018)。我如何用零替换熊猫数据帧的一列中的所有 NaN 值?堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/13295735/how-can-I-replace-all-the-nan-values with a-column-of-a-pandas-data fra
- dataframe,P. (2018 年)。使用 seaborn 为数据帧绘制直方图。堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/32923301/plotting-histogram-using-seaborn-for-a-data frame/33137122
- 0.11.0,h. (2018)。如何为熊猫增加 Dataframe.hist 的图形大小 0.11.0?堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/43392588/how-to-increase-the-figure-size-of-data frame-hist-for-pandas-0-11-0
- matplotlib?,H. (2018)。如何改变用 matplotlib 绘制的图形的大小?。堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/332289/how-do-you-change-the-size-of-figures-drawn-with-matplotlib
- 可视化数据集的分布— seaborn 0.8.1 文档。(2018).Seaborn.pydata.org。检索于 2018 年 6 月 25 日,来自https://seaborn.pydata.org/tutorial/distributions.html
- seaborn . distplot-seaborn 0 . 8 . 1 文档。(2018).Seaborn.pydata.org。检索于 2018 年 6 月 25 日,来自https://seaborn.pydata.org/generated/seaborn.distplot.html
- 零?,H. (2018)。如何将现有 Pandas 数据帧的所有值设置为零?。堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/42636765/how-to-set-the-all-the-values-of-an-existing-pandas-data frame-to-zero
- DataFrame,C. (2018)。将数据帧中的字符串转换为浮点数。堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/16729483/converting-strings-to-floats-in-a-data frame
- pandas & Seaborn——Python | Tryolabs 博客中的数据处理和可视化指南。(2017).Tryolabs.com。检索于 2018 年 6 月 25 日,来自https://tryolabs . com/blog/2017/03/16/pandas-seaborn-a-guide-to-handle-visualize-data-elegantly/
- 协方差矩阵。(2018).Stattrek.com。检索于 2018 年 6 月 25 日,来自 https://stattrek.com/matrix-algebra/covariance-matrix.aspx
- 如何在 Python 中构建方差-协方差矩阵?(2015).Firsttimeprogrammer.blogspot.com。检索于 2018 年 6 月 25 日,来自http://first time programmer . blogspot . com/2015/01/how-to-build-variance-协方差-matrix.html
- seaborn . bar plot-seaborn 0 . 8 . 1 文档。(2018).Seaborn.pydata.org。检索于 2018 年 6 月 25 日,来自https://seaborn.pydata.org/generated/seaborn.barplot.html
- seaborn . pair plot-seaborn 0 . 8 . 1 文档。(2018).Seaborn.pydata.org。检索于 2018 年 6 月 25 日,来自https://seaborn.pydata.org/generated/seaborn.pairplot.html
- 3D 散点图— Matplotlib 2.2.2 文档。(2018).Matplotlib.org。检索于 2018 年 6 月 25 日,来自https://matplotlib.org/gallery/mplot3d/scatter3d.html
- Pyplot 教程— Matplotlib 2.0.2 文档。(2018).Matplotlib.org。检索于 2018 年 6 月 25 日,来自https://matplotlib.org/users/pyplot_tutorial.html
- 笔记本,P. (2018)。Python & Matplotlib:在 Jupyter Notebook 中进行 3D 绘图交互。堆栈溢出。检索于 2018 年 6 月 25 日,来自https://stack overflow . com/questions/38364435/python-matplotlib-make-3d-plot-interactive-in-jupyter-notebook
- 颜色示例代码:colormaps _ reference . py—Matplotlib 2 . 0 . 2 文档。(2018).Matplotlib.org。检索于 2018 年 6 月 25 日,来自https://matplotlib . org/examples/color/colormaps _ reference . html
- r:解一个方程组。(2018).Stat.ethz.ch 于 2018 年 6 月 25 日检索,来自https://stat . ethz . ch/R-manual/R-devel/library/base/html/solve . html
- r 求解函数示例— EndMemo。(2018).Endmemo.com。检索于 2018 年 6 月 25 日,来自 http://www.endmemo.com/program/R/solve.php
- r:标准差。(2018).Stat.ethz.ch 于 2018 年 6 月 25 日检索,来自http://stat . ethz . ch/R-manual/R-devel/library/stats/html/SD . html
- (2018).Users.stat.umn.edu。检索于 2018 年 6 月 25 日,来自http://users.stat.umn.edu/~helwig/notes/datamat-Notes.pdf
- 相关和依赖。(2018).En.wikipedia.org。检索于 2018 年 6 月 25 日,来自https://en.wikipedia.org/wiki/Correlation_and_dependence
- 霍尔茨,Y. (2017)。#372 3D PCA 结果。Python 图表库。检索于 2018 年 6 月 26 日,来自https://python-graph-gallery.com/372-3d-pca-result/
- 操作员,I. (2018)。Tensorflow 中的交互式会话-卷积运算符的不同输出。堆栈溢出。检索于 2018 年 6 月 26 日,来自https://stack overflow . com/questions/40221651/interactive-session-in-tensor flow-different-output-for-convolution-operator
- tensorflow,D. (2018)。张量流中两个向量的点积。堆栈溢出。检索于 2018 年 6 月 26 日,来自https://stack overflow . com/questions/40670370/tensor flow 中两个向量的点积
- 安装 mpld3 —将 Matplotlib 引入浏览器。(2018).mpld 3 . github . io . 2018 年 6 月 26 日检索,来自http://mpld3.github.io/install.html
- NumPy . histogram—NumPy 1.14 版手册。(2018).Docs.scipy.org。检索于 2018 年 6 月 26 日,来自https://docs . scipy . org/doc/numpy/reference/generated/numpy . histogram . html
- 使用 pygal 在 IPython 笔记本中进行交互式绘图。(2015).伊诺·德·布鲁因。检索于 2018 年 6 月 26 日,来自 http://ino.pm/blog/ipython-pygal/#.WzGzS6dKiUk
- 使用交互式代码探索基础医学数据。(2018).走向数据科学。检索于 2018 年 6 月 26 日,来自https://towards data science . com/basic-medical-data-exploration-with-interactive-code-aa 26 ed 432265
- JaeDukSeo/每日神经网络实践 2。(2018).GitHub。检索于 2018 年 6 月 26 日,来自https://github . com/JaeDukSeo/Daily-Neural-Network-Practice-2/blob/master/Medical _ EXP/heart/heart . ipynb
使用交互式代码的基础医学数据探索
GIF from this website
今天我想做一些数据探索,从简单的开始,我想使用著名的皮马印第安人糖尿病数据库创建一些图表。
请注意,这篇文章是为了我未来的自己审查这些材料。
- 简单查看数据格式和数据类型
由于我使用了 Pandas Dataframe 来研究 csv 数据,我们可以轻松地查看数据类型以及数据背后的简单见解,例如平均值或标准值。
马上我们可以看到所有的数据都是由数值组成的,事实上我们有 768 列,没有空值。
2。第一个和最后 10 个数据点
虽然我们知道我们的数据是由数值组成的,但我喜欢浏览数据(主要是第一个和最后 10 个或 100 个),只是为了好玩而查看它们。
3。相关矩阵
接下来,我想看看每一列是如何相互关联的,再次感谢 pandas Dataframe 的强大功能,制作这个图表非常容易。我们已经可以观察到结果栏与葡萄糖、身体质量指数和年龄高度相关。
4。各列直方图
现在让我们来看看每一列的分布,我们可以立即观察到我们的数据库中有更多的非糖尿病患者。在执行分类时,这可能是一个有用的信息。接下来,我们可以观察到年龄部分有一个异常值。(因为我们只有一个年龄在 80 到 81 岁之间的人。)
在这里我们可以观察到更多的情况,例如,我们大多数患者的胰岛素水平在 0-19μU/ml 之间
5。散点图矩阵
散点图矩阵图(或 SPLOM)也可以用来找出不同的相关性。使用这篇博客文章中的代码,我们可以观察每个特性是如何相互关联的。从表面上看,身体质量指数和血糖水平似乎是非常重要的特征。(正如我们在关联热图中已经看到的。)
6。一致流形逼近和投影嵌入(UMAP)
t-分布随机邻居嵌入(t-SNE)
Inspired by this blog post
最后,让我们将数据集投影到三维空间中,我们已经知道我们有 8 个特征向量(因为最后一个是患者是否患有糖尿病的二进制值,所以我们不会对其进行计数。)所以让我们把它们投射到 3D 空间。如上所述,无论是 t-SNE 还是 UMAP 都没有在非糖尿病患者和糖尿病患者的聚类方面做得很好。
如上所述,我决定只使用 4 个具有最高相关值的特征向量。
不幸的是,结果似乎并没有改变太多:(
GitHub 代码
要访问这篇文章的 ipython 笔记本,请点击这里。
遗言
对于数据探索来说,这是一个很好的起点,我希望将来能做得更多。
如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请在这里查看我的网站。
同时,在我的 twitter 这里关注我,并访问我的网站,或我的 Youtube 频道了解更多内容。我也实现了广残网,请点击这里查看博文 pos t。
参考
- 绘制对角线相关矩阵——seaborn 0 . 8 . 1 文档。(2018).Seaborn.pydata.org。检索于 2018 年 6 月 24 日,来自https://seaborn . pydata . org/examples/many _ pairwise _ correlations . html
- 带注释的热图— seaborn 0.8.1 文档。(2018).Seaborn.pydata.org。检索于 2018 年 6 月 24 日,来自https://seaborn.pydata.org/examples/heatmap_annotation.html
- colormap,P. (2018)。用取自色彩图的颜色绘制直方图。堆栈溢出。检索于 2018 年 6 月 24 日,来自https://stack overflow . com/questions/23061657/plot-histogram-with-colors-take-from-colormap
- matplotlib?,H. (2018)。如何改变用 matplotlib 绘制的图形的大小?。堆栈溢出。检索于 2018 年 6 月 24 日,来自https://stack overflow . com/questions/332289/how-do-you-change-the-size-of-figures-drawn-with-matplotlib
- 什么是 SPLOM 图表?用 Python 制作散点图矩阵。(2018).中等。检索于 2018 年 6 月 24 日,来自https://medium . com/@ plotlygraphs/what-is-a-splom-chart-make-scatter plot-matrices-in-python-8dc 4998921 C3
- Plot.ly. (2018)。秘密地进口。_ _ version _ _ | Dreamshot | Plotly。【在线】可在:https://plot . ly/~ dream shot/9242/import-plotly-plotly-version-/#/【2018 年 6 月 24 日访问】。
- 直方图。(2018).Plot.ly .检索于 2018 年 6 月 24 日,来自https://plot.ly/pandas/histograms/
- 属性错误问题#24 lmcinnes/umap。(2018).GitHub。检索于 2018 年 6 月 24 日,来自https://github.com/lmcinnes/umap/issues/24
- dataframe,S. (2018)。在熊猫数据框架中选择列。堆栈溢出。检索于 2018 年 6 月 24 日,来自https://stack overflow . com/questions/11285613/selecting-columns-in-a-pandas-data frame
- 如何选择所有列,e. (2018)。如何选择除熊猫中一列外的所有列?。堆栈溢出。检索于 2018 年 6 月 24 日,来自https://stack overflow . com/questions/29763620/how-to-select-all-columns-except-one-columns-in-pandas
- 数字数据集的降维。(2018).Plot.ly .检索于 2018 年 6 月 24 日,来自https://plot . ly/~ empet/14816/dimension-reduction-of-digits-dataset-v/#/
- 皮马印第安人糖尿病数据库。(2018).Kaggle.com。检索于 2018 年 6 月 24 日,来自https://www.kaggle.com/uciml/pima-indians-diabetes-database
- 熊猫。数据框架-pandas 0 . 23 . 1 文件。(2018).Pandas.pydata.org。检索于 2018 年 6 月 24 日,来自https://pandas . pydata . org/pandas-docs/stable/generated/pandas。DataFrame.html
《哈利·波特》文本的情感分析
附带 Matplotlib 高级特性的附加教程!
我是 Greg Rafferty,湾区的数据科学家。你可以在我的 github 上查看这个项目的代码。如有任何问题,请随时联系我!
在这一系列的文章中,我通过《哈利·波特》的镜头来看一些简便的自然语言处理技术。本系列之前关于基本自然语言处理的文章着眼于使用潜在狄利克雷分配的主题建模、正则表达式和文本摘要。
什么是情感分析?
在之前的一篇文章中,我研究了主题建模,这是一种学习给定文本主题的自然语言处理技术。情感分析的存在是为了了解人们对那个话题说了什么——是好是坏?随着互联网在我们日常生活中的使用越来越多,每天每秒钟都有大量的非结构化文本发布在博客帖子、论坛、社交媒体和评论网站上,仅举几例。情感分析系统可以获取这种非结构化数据,并自动为其添加结构,捕捉公众对产品、服务、品牌、政治等的看法。例如,这些数据在市场分析、公共关系、产品评论、净推广者评分、产品反馈和客户服务等领域具有巨大的价值。
我已经用哈利波特的文本演示了很多这样的 NLP 任务。这些书富含读者能从内心感受到的情感体验。电脑能捕捉到这种感觉吗?让我们来看看。
VADER
我用 C.J .休顿的 VADER 包提取每本书的感悟。VADER 是一个专门针对社交媒体的词汇和基于规则的工具,它代表了 ValenceAwareDictionary 和 sEentimentReasing。给定一个文本字符串,它输出一个介于 0 和 1 之间的十进制数来表示文本的消极、积极和中性,以及一个介于-1 和 1 之间的复合分数,它是一个聚合度量。
关于 VADER 软件包的开发、验证和评估的完整描述可以在本文中阅读,但要点是该软件包的作者首先构建了一个与情感相关的词汇特征列表,然后将该列表与一些描述短语的语法结构如何增强或减弱情感的规则相结合。当与人类评分员进行测试时,VADER 的准确率高达 96%到 84%。
VADER 最擅长短文本(最多两个句子),把它一次应用到一整章会导致极端和大部分没有价值的分数。相反,我逐个循环每个句子,得到 VADER 分数,然后取一章中所有句子的平均值。
Goblet of Fire, Chapter 16: Harry discovers the missionary position
通过绘制每本书每一章的 VADER 复合乐谱,我们可以清楚地标记书中的事件。上图中三个最大的峰值是哈利在第 70 章左右被火焰杯选中,塞德里克·迪戈里在第 88 章左右死亡,以及邓布利多在第 160 章左右死亡。
下面是生成该图表的代码(我的 Github 上有完整的笔记本)。数据存在于字典中,以每本书的书名作为关键字;每本书的值是另一个字典,每个章节的编号是一个键。每个章节的值是一个由章节标题和章节文本组成的元组。我定义了一个函数来计算数据的移动平均值,这基本上使曲线变得平滑了一点,并且更容易看到贯穿故事的长的多章节弧线。为了将每本书绘制成不同的颜色,我创建了一个名为book_indices
的字典,其中每本书的标题作为关键字,值是该书的起始章节号和结束章节号的 2 元素元组(就好像所有的书都与整个系列中按顺序编号的章节连接在一起)。然后,我根据章节号将故事分成几个部分。
import matplotlib.pyplot as plt# Use FiveThirtyEight style theme
plt.style.use('fivethirtyeight')# Moving Average function used for the dotted line
def movingaverage(interval, window_size):
window = np.ones(int(window_size))/float(window_size)
return np.convolve(interval, window, 'same')length = sum([len(hp[book]) for book in hp])
x = np.linspace(0, length - 1, num=length)
y = [hp[book][chapter][2]['compound'] for book in hp for chapter in hp[book]]plt.figure(figsize=(15, 10))
for book in book_indices:
plt.plot(x[book_indices[book][0]: book_indices[book][1]],
y[book_indices[book][0]: book_indices[book][1]],
label=book)
plt.plot(movingaverage(y, 10), color='k', linewidth=3, linestyle=':', label = 'Moving Average')
plt.axhline(y=0, xmin=0, xmax=length, alpha=.25, color='r', linestyle='--', linewidth=3)
plt.legend(loc='best', fontsize=15)
plt.title('Emotional Sentiment of the Harry Potter series', fontsize=20)
plt.xlabel('Chapter', fontsize=15)
plt.ylabel('Average Sentiment', fontsize=15)
plt.show()
我还使用 TextBlob 朴素贝叶斯和模式分析器制作了同样的图表,结果更差(这些图表见我的 Github 上的 Jupyter 笔记本)。朴素贝叶斯模型是根据电影评论训练出来的,这些电影评论一定不能很好地解释哈利波特世界。模式分析器工作得更好(几乎和 VADER 一样好);它基于模式库,一个与 VADER 非常相似的基于规则的模型。
情感词汇
我还通过使用由加拿大国家研究委员会创建的超过 14000 个单词的词典来研究情绪,每个单词都被分为与两种情绪(消极、积极)或八种情绪(愤怒、期待、厌恶、恐惧、快乐、悲伤、惊讶、信任)中的任何一种相关或不相关。他们友好地向我提供了词典的访问权限,我写了一个 Python 脚本,它循环一章中的每个单词,在词典中查找,并输出该单词所关联的任何情绪。然后,每一章被赋予每种情绪的分数,该分数对应于该章包含的与该情绪相关联的词的数量与该章中的总字数的比率(这基本上使分数标准化)。
这是“愤怒”和“悲伤”情绪的曲线图。我觉得很有意思的是,愤怒总是伴随着悲伤而存在,但悲伤有时可以在没有愤怒的情况下存在:
Wow, Voldemort. You really pissed off Harry when you killed the adults in his life
Those mood swings hit hard during puberty
再一次,看看我的 Github 上的 Jupyter 笔记本,看看所有情绪的详细图表。这是一个精简版:
让我们来看看我是如何制作这些支线剧情的:
length = sum([len(hp[book]) for book in hp])
x = np.linspace(0, length - 1, num=length)fig, ax = plt.subplots(4, 3, figsize=(15, 15), facecolor='w', edgecolor='k')
fig.subplots_adjust(hspace = .5, wspace=.1)
fig.suptitle('Sentiment of the Harry Potter series', fontsize=20, y=1.02)
fig.subplots_adjust(top=0.88)ax = ax.ravel()for i, emotion in enumerate(emotions):
y = [hp_df.loc[book].loc[hp[book][chapter][0]][emotion] for book in hp for chapter in hp[book]]
for book in book_indices:
ax[i].plot(x[book_indices[book][0]: book_indices[book][1]],
y[book_indices[book][0]: book_indices[book][1]],
label=book, linewidth=2)ax[i].set_title('{} Sentiment'.format(emotion.title()))
ax[i].set_xticks([])fig.legend(list(hp), loc='upper right', fontsize=15, bbox_to_anchor=(.85, .2))
fig.tight_layout()
fig.delaxes(ax[-1])
fig.delaxes(ax[-2])
plt.show()
但是看到所有的情绪如何相互比较真的变得很有趣。用这么多的差异叠加 10 条线很快就变得一团糟,所以我再次使用移动平均线:
有趣的是,矛盾的情绪会相互对立,最明显的是上面代表“积极”和“消极”情绪的粉色和棕色线条。请注意,由于移动平均窗口大小为 20 个数据点,前 10 章和后 10 章已从图中删除。
我去掉了 y 轴,因为这些数字对我们来说毫无意义(仅仅是小数:那种情绪的单词量与该章总单词量的比率)。我还删除了水平和垂直图表线,以清理情节。我并不特别在意标记常规的章节号,但我确实想在书上做标记;因此,我添加了那些垂直的虚线。图例在这个图中被颠倒了,这对于可读性或任何东西来说都不是必需的,但我这样做是为了与接下来的面积图和柱形图保持一致。
我是这样做的:
# use the Tableau color scheme of 10 colors
tab10 = matplotlib.cm.get_cmap('tab10')length = sum([len(hp[book]) for book in hp])
window = 20# use index slicing to remove data points outside the window
x = np.linspace(0, length - 1, num=length)[int(window / 2): -int(window / 2)]fig = plt.figure(figsize=(15, 15))
ax =fig.add_subplot(1, 1, 1)# Loop over the emotions with enumerate in order to track colors
for c, emotion in enumerate(emotions):
y = movingaverage([hp_df.loc[book].loc[hp[book][chapter][0]][emotion] for book in hp for chapter in hp[book]], window)[int(window / 2): -int(window / 2)]
plt.plot(x, y, linewidth=5, label=emotion, color=(tab10(c)))
# Plot vertical lines marking the books
for book in book_indices:
plt.axvline(x=book_indices[book][0], color='black', linewidth=2, linestyle=':')
plt.axvline(x=book_indices[book][1], color='black', linewidth=2, linestyle=':')plt.legend(loc='best', fontsize=15, bbox_to_anchor=(1.2, 1))
plt.title('Emotional Sentiment of the Harry Potter series', fontsize=20)
plt.ylabel('Relative Sentiment', fontsize=15)# Use the book titles for X ticks, rotate them, center the left edge
plt.xticks([(book_indices[book][0] + book_indices[book][1]) / 2 for book in book_indices],
list(hp),
rotation=-30,
fontsize=15,
ha='left')
plt.yticks([])# Reverse the order of the legend
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1], loc='best', fontsize=15, bbox_to_anchor=(1.2, 1))ax.grid(False)plt.show()
我还做了一个面积图来显示每一章的整体情感品质。这也是一个移动平均值,以消除更极端的峰值,并更好地显示所有书籍中的故事:
这本书似乎以一点前一个故事的拖尾情绪开始,但在中间章节很快平静下来,只是在结尾时又回来了。
length = sum([len(hp[book]) for book in hp])
window = 10
x = np.linspace(0, length - 1, num=length)[int(window / 2): -int(window / 2)]fig = plt.figure(figsize=(15, 15))
ax = fig.add_subplot(1, 1, 1)y = [movingaverage(hp_df[emotion].tolist(), window)[int(window / 2): -int(window / 2)] for emotion in emotions]plt.stackplot(x, y, colors=(tab10(0),
tab10(.1),
tab10(.2),
tab10(.3),
tab10(.4),
tab10(.5),
tab10(.6),
tab10(.7),
tab10(.8),
tab10(.9)), labels=emotions)# Plot vertical lines marking the books
for book in book_indices:
plt.axvline(x=book_indices[book][0], color='black', linewidth=3, linestyle=':')
plt.axvline(x=book_indices[book][1], color='black', linewidth=3, linestyle=':')plt.title('Emotional Sentiment of the Harry Potter series', fontsize=20)
plt.xticks([(book_indices[book][0] + book_indices[book][1]) / 2 for book in book_indices],
list(hp),
rotation=-30,
fontsize=15,
ha='left')
plt.yticks([])
plt.ylabel('Relative Sentiment', fontsize=15)# Reverse the legend
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1], loc='best', fontsize=15, bbox_to_anchor=(1.2, 1))ax.grid(False)plt.show()
请注意,在此图表中,为了可读性,反转图例变得非常必要。默认情况下,图例项是按字母顺序向下添加的,但数据是自下而上堆叠的。因此,图例和面积图的颜色走向相反——在我看来,非常混乱,难以理解。因此,在底部绘制“愤怒”,我也希望它在传奇的底部,同样在顶部绘制“信任”。
最后,一个堆叠条形图显示了各种情绪在书籍中的权重:
自然,与任何积极情绪相关的词也会与“积极”情绪相关,同样也与“消极”情绪相关,所以这两种情绪承载了书籍的大部分情绪质量也就不足为奇了。我发现值得注意的是,每本书的情绪相对一致,只是在数量上略有不同,但重量一致,除了红色的“恐惧”情绪;它似乎是整个系列中变化最大的。我也希望随着赌注越来越高,在整个系列赛中,情感的累积量会增加;然而,虽然最后一本书确实是最高的,但其他 6 本书没有显示出这种逐渐增加,而是几乎相反,从第 2 本书开始持续下降。
books = list(hp)
margin_bottom = np.zeros(len(books))fig = plt.figure(figsize=(15, 15))
ax = fig.add_subplot(1, 1, 1)for c, emotion in enumerate(emotions):
y = np.array(hp_df2[emotion])
plt.bar(books, y, bottom=margin_bottom, label=emotion, color=(tab10(c)))
margin_bottom += y# Reverse the legend
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1], loc='best', fontsize=15, bbox_to_anchor=(1.2, 1))plt.title('Emotional Sentiment of the Harry Potter series', fontsize=20)
plt.xticks(books, books, rotation=-30, ha='left', fontsize=15)
plt.ylabel('Relative Sentiment Score', fontsize=15)
plt.yticks([])
ax.grid(False)
plt.show()
这个图中棘手的地方是使用margin_bottom
变量来堆叠每一列。除此之外,它只是使用了一些以前剧情中的技巧。
《哈利·波特》文本的解读
基于潜在狄利克雷分配的主题建模
“Hmm,” said a small voice in his ear. “Difficult. Very difficult. Plenty of courage, I see. Not a bad mind either. There’s talent, oh my goodness, yes — and a nice thirst to prove yourself, now that’s interesting. . . . So where shall I put you?”
我是 Greg Rafferty,湾区的数据科学家。你可以在我的 github 上查看这个项目的代码。如有任何问题,请随时联系我!
在这篇文章中,我将通过《哈利·波特》的视角,用潜在的狄利克雷分配来描述主题建模,并比较不同的算法。即将发布的帖子将涵盖另外两个 NLP 任务:文本摘要和情感分析。
最近,我和一个团队参与了一个新项目,他们一致感到震惊和失望,因为我从未读过或看过关于一个名叫哈利·波特的虚构巫师的电影。为了融入团队,显然也为了避免我的职业生涯过早结束,我很快意识到我必须参加一个关于霍格沃茨发生的事情的速成班。带着我的电子书阅读器和七个闪亮的新 pdf 文件,我坐下来看看到底是怎么回事。与此同时,我已经开始从事一个由一堆不相关的 NLP 任务组成的兼职项目。我需要一套大小合适的文本文档,我认为所有这些闪亮的新 pdf 将是一个很好的来源。
在第三本书中间的某个地方,我突然意识到 LDA 基本上只是一个算法排序帽。
LDA,或潜在的 Dirichlet 分配,是由单词和/或短语组成的文档语料库的生成概率模型(在 NLP 术语中)。该模型由两个表组成;第一个表是从特定主题采样时在语料库中选择特定单词的概率,第二个表是从特定文档采样时选择特定主题的概率。
这里有一个例子。假设我有这三个(相当不重要的)文档:
document_0 = "Harry Harry wand Harry magic wand"
document_1 = "Hermione robe Hermione robe magic Hermione"
document_2 = "Malfoy spell Malfoy magic spell Malfoy"
document_3 = "Harry Harry Hermione Hermione Malfoy Malfoy"
以下是这些文档的术语频率矩阵:
从这一点看,很明显 0 号文件主要是关于哈利的,有一点是关于魔法的,还有一部分是关于魔杖的。文件 1 也有一点关于魔法,但主要是关于赫敏和长袍。文件 2 也是部分关于魔法,但主要是关于马尔福和咒语。文件 3 同样是关于哈利、赫敏和马尔福的。通常不太容易看出这一点,因为更实用的语料库将由成千上万的单词组成,所以让我们看看 LDA 算法选择什么主题:
Data Science with Excel!
这大概就是我们根据词频和直觉预测的结果。主题的数量是一个超参数,您需要仔细选择和调整,我将在后面详细介绍,但在这个示例中,我选择了 4 个主题来阐述我的观点。上面的表格显示单词和主题,下面的表格显示文档和主题。上表中的每一列和下表中的每一行的总和必须为 1。这些表格告诉我们,如果我们从 Topic 0 中随机抽取一个单词,有 70.9%的几率会得到“Harry”。如果我们从话题 3 中选一个词,几乎可以肯定我们会选“魔法”。如果我们对文档 3 进行采样,那么我们选择主题 0、1 或 2 的可能性是相等的。
这取决于我们这些聪明的人,他们可以从一堆单词中推断出这些主题的意思。在这些词汇非常有限的例子中,主题显然与单个单词相对应。如果我们在几千个餐馆描述上运行 LDA,我们可能会找到与菜肴类型或氛围相对应的主题。值得注意的是,与 Kmeans 等典型的聚类算法不同,LDA 允许一个文档存在于多个主题中。因此,在这些餐馆描述中,我们可能会在“意大利”、“约会之夜”和“咖啡馆”主题中找到一家餐馆。
这一切和分院帽有什么关系?霍格沃茨所有的新生在到达的第一天都要经历一个仪式来决定他们将住在哪个房子里(我可能是唯一一个直到几周前才知道这件事的人)。分院帽一旦戴在某人的头上,就能理解他们的思想、梦想和经历。这有点像 LDA 构建词频矩阵并理解每个文档中包含哪些单词和 N 元语法。
分院帽然后将学生的属性与各个学院的属性进行比较(勇敢归格兰芬多,忠诚归赫奇帕奇,智慧归拉文克劳,卑鄙、狡诈的人渣归斯莱特林(好吧,就一个简短的题外话——有谁能向我解释一下为什么斯莱特林坚持了这所学校的千年历史吗?这就像一个兄弟会发现自己每年都陷入另一个可笑的淫秽丑闻!)).这是 LDA 创建单词-主题表并开始关联主题属性的地方。
由于哈利集勇气、智慧、天赋和雄心于一身,他在格兰芬多和斯莱特林之间的排名明显不同,但格兰芬多只是略微领先,哈利·波特成为了整整一代年轻千禧一代的英雄,而不是反面角色。LDA 在这里创建文档主题表,并最终确定每个文档的主导主题。
好了,现在我们大致了解了 LDA 的功能,让我们来看看 Python 中的两种不同实现。查看我的 Github repo 了解所有的基本细节。
首先,确定应该建模多少主题的最佳方法之一是肘图。这也是通常用于确定使用聚类算法选择多少个聚类的技术。在这种情况下,我们将根据主题数量绘制一致性分数:
你通常会选择连贯性分数开始稳定的最低数量的主题。这就是为什么它被称为肘图——你在陡峭的收益和浅的收益之间选择肘。在这种情况下(这是一个非常尖锐的情况;通常曲线比这个稍微平滑一点),我会选择大约 20 个主题。
我使用的第一个模型是 Gensim 的 ldamodel 。在 20 个主题中,Gensim 的一致性得分为 0.319。这并不伟大;事实上,我们接下来要看的 Mallet 算法几乎总是优于 Gensim 的算法。然而,Gensim 的一个真正酷的东西是 pyLDAvis,一个可以在 Jupyter 笔记本上运行的交互式图表。它用两个主成分绘制聚类图,并显示每个聚类中单词的比例:
Harry Potter and the Allocation of Dirichlet
我研究的下一个实现是 Mallet ( 马ChineLearning forLanguagET12ool kit),这是 UMASS Amherst 推出的一个基于 Java 的包。Mallet 和 Gensim 的标准 LDA 之间的区别在于,Gensim 使用变分贝叶斯采样方法,该方法比 Mallet 的 Gibbs 采样更快,但精度较低。幸运的是,对于那些喜欢用 Python 编码的人来说,Gensim 有一个 Mallet 的包装器:通过 Mallet 的潜在 Dirichlet 分配。为了使用它,你需要从这里http://mallet.cs.umass.edu/dist/mallet-2.0.8.zip下载 Mallet Java 包并安装 Java 开发工具包。一旦一切都设置好了,实现这个模型就和 Gensim 的标准模型差不多了。使用 Mallet,20 主题模型的一致性分数增加到 0.375(记住,Gensim 的标准模型输出 0.319)。这是一个适度的增长,但通常会持续各种数据源,所以尽管 Mallet 稍慢,但我更喜欢它的回报增加。
最后,我在哈利波特系列的所有 7 本书的 192 个章节上建立了一个木槌模型。以下是每个潜在主题的模型输出的前 10 个关键词。你如何命名这些集群?
比特币价格数据的基本时间序列分析和交易策略
Photo by Dmitry Demidko on Unsplash
我必须说,时间序列分析不是一个简单的话题。至少对我来说是这样。在伦敦大会数据科学沉浸式课程的课堂上,我有机会了解这个主题,并花了一些时间来理解它。
这篇文章的目的是通过实施并试图向他人解释来巩固我所学到的东西。我不是金融专家,所以非常感谢熟悉这个领域的人的任何建议或反馈。
时间序列
时间序列是一系列按时间顺序索引(或列出或绘制)的数据点。时间序列数据应与其他类型的数据区别对待。统计数据假设之一是其独立性。独立性意味着一个观察值不会影响其他观察值。但是在时间序列数据中,每个数据点在时间上是靠在一起的,它们并不完全独立于它们的相邻值。因此,我们需要一种不同的方法来模拟时间序列数据。
首先,从加载依赖项开始。Pandas_datareader 是一个从 web 中提取金融数据的有用库。对于这篇文章,我将从雅虎财经中提取数据。
import pandas as pd
import pandas_datareader.data as web
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import datetimeplt.style.use('fivethirtyeight')%config InlineBackend.figure_format = 'retina'
%matplotlib inline
好了,我们来获取 2017 年初至 2017 年 12 月 27 日 BTC-美元(比特币价值以美元计)的价格数据。
btc = web.get_data_yahoo('BTC-USD', start=datetime.datetime(2017, 1, 1), end=datetime.datetime(2017, 12, 27))
btc.head()
如您所见,该数据有六列。“开盘价”代表当天的开盘价,“高”代表当天的最高价,“低”代表当天的最低价,“收盘”代表当天的收盘价,“调整收盘”代表调整后的收盘价,“成交量”代表成交量。在股票价格中,调整后的收盘价反映了股票在任何给定交易日的收盘价,该收盘价已被修改为包括第二天开盘前任何时间发生的任何分配和公司行为。
但是 100%诚实地说,我不确定一种货币的调整后收盘价将考虑哪些因素,但是通过查看“收盘”列和“Adj Close”列的差异,它们似乎完全相同。
np.sum(btc['Close'] - btc['Adj Close'])
让我们在图表上绘制“Adj Close”价格数据。
btc_adj = btc['Adj Close']
btc_adj.plot(lw=2.5, figsize=(12, 5))
plt.show()
看起来比特币的美元价值在 2017 年上半年一直保持稳定,但从 11 月份左右开始振荡并急剧上升。
移动平均数
时间序列数据的基本分析技术之一是移动平均。顾名思义,移动平均值(也称为滚动平均值)不是计算整个数据集的平均值,而是计算具有特定窗口大小的子集的平均值,并向前移动。移动平均线用于平滑短期波动,突出长期趋势或周期。
让我们通过绘制 2017 年 1 月 10 日至 2017 年 12 月 27 日的价格数据来看看移动平均线在图表上的工作原理。我选择了 2017 年第四季度来绘制数据中有强烈趋势的地方,以清楚地看到移动平均线是如何工作的。
btc_recent = btc_adj.loc['2017-10-01':'2017-12-27']
rroll_d3 = btc_recent.rolling(window=3).mean()
rroll_d7 = btc_recent.rolling(window=7).mean()
rroll_d14 = btc_recent.rolling(window=14).mean()plt.figure(figsize=(14, 7))
plt.plot(btc_recent.index, btc_recent, lw=3, alpha=0.8,label='Original observations')
plt.plot(btc_recent.index, rroll_d3, lw=3, alpha=0.8,label='Rolling mean (window 3)')
plt.plot(btc_recent.index, rroll_d7, lw=3, alpha=0.8,label='Rolling mean (window 7)')
plt.plot(btc_recent.index, rroll_d14, lw=3, alpha=0.8,label='Rolling mean (window 14)')
plt.title('BTC-USD Adj Close Price 2017-10-01 to 2017-12-27')
plt.tick_params(labelsize=12)
plt.legend(loc='upper left', fontsize=12)
plt.show()
与用蓝线绘制的原始观察结果相比,我们可以看到,随着窗口尺寸变大,线条曲线变得更加平滑。
双重移动平均线交叉
均线的另一个使用案例是在一个叫做双重均线交叉的交易策略中。我通过一篇中型博客文章了解到这一点,它被很好地解释了,不仅是关于动量策略,还有 Python 在交易策略建模中的一般用例。如果你是对 Python 金融建模感兴趣的初学者,我强烈推荐这篇文章。
我下面实现的只是我提到的博客文章中的教程的一个应用,但是我将短窗口改为 10 天而不是最初文章的 40 天,对于更长的时间,我使用 50 天并将其命名为 mid_window,而不是最初文章作者使用的 100 天。我想,如果把时间框架改得更短,这个策略将会更加短视。但我不是金融专家,我不确定将时间框架改得更短是否会犯根本性错误。如果阅读这篇文章的人是金融专家,请随时纠正我的逻辑错误。
双重均线交叉的概念非常简单。计算价格的两条移动平均线,一条是短期的,另一条是长期的。长期移动平均线的方差较低,与短期移动平均线的移动方向相同,但速率不同。不同的方向变化率导致两个移动平均值可能相等或彼此交叉的点。这些点被称为交叉点。在双重移动平均线交叉交易策略中,这些交叉点是决定买入或卖出货币的点。
按照原博文作者的说法,“当短期平均线穿越长期平均线并升至其上方时,产生买入信号,而当短期平均线穿越长期平均线并跌破长期平均线时,触发卖出信号”。
然而,在寻找关于这个主题的更多材料时,我也发现了对相同信号点的相反方法。作者介绍的上述方法称为技术方法,另一种方法称为价值方法。
价值方法提供了与技术方法相反的交易信号。价值方法认为,当短期平均线从长期平均线的下方穿越到上方时,投资现在被高估了,应该卖出。相反,当货币短期平均值低于长期平均值时,则货币被低估,应该买入。
看到对同一情况有两种相互矛盾的观点是非常有趣的。但是在这篇文章中,我将集中讨论技术方法。现在让我们看看如何将它应用到真实数据中。
short_window = 10
mid_window = 50signals = pd.DataFrame(index=btc_adj.index)
signals['signal'] = 0.0roll_d10 = btc_adj.rolling(window=short_window).mean()
roll_d50 = btc_adj.rolling(window=mid_window).mean()signals['short_mavg'] = roll_d10
signals['mid_mavg'] = roll_d50
signals['signal'][short_window:] = np.where(signals['short_mavg'][short_window:] > signals['mid_mavg'][short_window:], 1.0, 0.0)
signals['positions'] = signals['signal'].diff()
现在我们可以把它画出来,看看它在图表上是什么样子。
plt.figure(figsize=(14, 7))
plt.plot(btc_adj.index, btc_adj, lw=3, alpha=0.8,label='Original observations')
plt.plot(btc_adj.index, roll_d10, lw=3, alpha=0.8,label='Rolling mean (window 10)')
plt.plot(btc_adj.index, roll_d50, lw=3, alpha=0.8,label='Rolling mean (window 50)')plt.plot(signals.loc[signals.positions == 1.0].index,
signals.short_mavg[signals.positions == 1.0],
'^', markersize=10, color='r', label='buy')
plt.plot(signals.loc[signals.positions == -1.0].index,
signals.short_mavg[signals.positions == -1.0],
'v', markersize=10, color='k', label='sell')plt.title('BTC-USD Adj Close Price (The Technical Approach)')
plt.tick_params(labelsize=12)
plt.legend(loc='upper left', fontsize=12)
plt.show()
initial_investment = btc_adj.loc[list(signals[signals.positions == 1.0].index)][0]
bought = np.sum(btc_adj.loc[list(signals[signals.positions == 1.0].index)]*-1.0)
sold = np.sum(btc_adj.loc[list(signals[signals.positions == -1.0].index)])
current_btc_value = btc_adj[-1]balance = pd.DataFrame([btc_adj.loc[list(signals[signals.positions == 1.0].index)]*-1.0,
btc_adj.loc[list(signals[signals.positions == -1.0].index)]]).transpose()
balance = balance.fillna(0)
balance['balance'] = balance.sum(axis=1)print "Initial investment amount: {0:.2f} USD".format(initial_investment)
print "Maximum invested amount: {0:.2f} USD".format(abs(min(balance.cumsum().balance)))
print "Current asset value: {0:.2f} USD".format(bought+sold+current_value)
按照技术方法,我会以 1,048.89 美元开始投资,在大约一年的时间内,我需要 1,551.77 美元继续投资,我的 1 比特币的最终价值现在应该是 1,3864.87 美元(2017 年 12 月 27 日)。这可能是一个天真的计算,没有考虑交易费或其他可能发生的费用。但在一个简化的计算中,这并不是一项糟糕的投资。
如果将价值方法应用于同一图表,情况可能会有所不同。金融学里有“做空”和“做多”的概念。“卖空一项资产意味着出售一项我们目前不持有的资产,并获得其现金价值。卖空与出售我们已经拥有的资产不同,后者被称为做多。”对我来说,这听起来总是有点违背直觉,出售一个人甚至不拥有的东西。如果你有兴趣了解这方面的更多信息,你可能会发现来自 Investopedia 的这一页很有帮助。
从技术角度来看,最后一笔交易是“买入”,但从价值角度来看,这笔交易应该是“卖出”。正如你所看到的,价格没有下跌,而是继续上涨,在这种情况下,卖空者可能会被他的经纪人追加保证金。
指数移动平均线
时间序列数据的另一种平滑技术是 EMA(指数移动平均线)。EMA 是最近 n 个(窗口大小)价格的加权平均值,权重随着每个价格/周期呈指数下降。简而言之,最近的价格比过去的价格被赋予更大的权重,并且随着时间周期从当前观察进一步向过去发展,贡献的程度呈指数衰减。
时间 t 的(调整后的)指数移动平均值定义为:
这里α是衰减因子。但是有一点我不能理解。我能理解这种逻辑,但是当涉及到 Pandas 的“ewm”函数时,我弄不明白 alpha 的默认值是什么。也许有一个标准,即使没有明确说明,每个人都同意,但我花了大量的时间试图弄清楚这一点,但我仍然不确定。也许我错过了一些重要的东西。如果你对此很熟悉,任何帮助都将不胜感激。
*更新:我在上面找到了自己问题的答案。我不得不承认,我没有仔细查看文档。有时候真的很奇怪,我在文档中查看了所有的解释,但不知何故我不能理解。与熊猫的 EWM 函数,没有默认值,你必须指定衰变。有四种不同的方式可以指定它。在下面的代码中,我用“span”来指定它,在这种情况下,alpha 被定义为 2/(span+1)。因此,通过将“span”指定为 10,我将 alpha 指定为大约 0.18。也可以从 Pandas 0 . 18 . 0 版直接指定 alpha。
但直觉上,与简单移动平均线相比,指数移动平均线对最近的价格变动反应更快,因为它赋予当前价值更多的权重。
exp_weighted_mean = btc_recent.resample('D').sum().ewm(span=10).mean()
sma_d10 = btc_recent.rolling(window=10).mean()
ax = btc_recent.plot(lw=3, figsize=(14, 7), label='Original observations')
exp_weighted_mean.plot(ax=ax, lw=3, label='EMA (window 10)')
sma_d10.plot(ax=ax, lw=3, label='SMA (window 10)')
plt.title('BTC-USD Adj Close Price 2017-10-01 to 2017-12-27', fontsize=16)
plt.tick_params(labelsize=12)
plt.legend(loc='upper left', fontsize=12)
plt.show()
从上面的图表中,你可以看到红线的均线在 12 月中旬比黄线的均线更快地抓住了向下的趋势,并且在最后,均线开始抓住向上的趋势,而均线仍然显示向下的趋势。
你可以把双重均线交叉的相同逻辑应用到原始观察和均线上。只是这次我们寻找原始观察值和均线的交叉点。让我们看看在从 2017 年 1 月 10 日到 2017 年 12 月 27 日的短时间内这将如何表现。
exp_weighted_mean = btc_recent.resample('D').sum().ewm(span=20).mean()signals_ema = pd.DataFrame(index=btc_recent.index)
signals_ema['signal'] = 0.0signals_ema['original'] = btc_recent
signals_ema['EMA'] = exp_weighted_meansignals_ema['signal'] = np.where(signals_ema['original'] > signals_ema['EMA'], 1.0, 0.0)signals_ema['positions'] = signals_ema['signal'].diff()
现在让我们在图表上看看这个。
plt.figure(figsize=(14, 7))ax = btc_recent.plot(lw=3, figsize=(14, 7), label='Original observations')
exp_weighted_mean.plot(ax=ax, lw=3, label='Exponentially weighted mean')plt.plot(signals_ema.loc[signals_ema.positions == 1.0].index,
signals_ema.EMA[signals_ema.positions == 1.0],
'^', markersize=10, color='r', label='buy')
plt.plot(signals_ema.loc[signals_ema.positions == -1.0].index,
signals_ema.EMA[signals_ema.positions == -1.0],
'v', markersize=10, color='k', label='sell')plt.title('BTC-USD Adj Close Price (EMA Trading Strategy)')
plt.tick_params(labelsize=12)
plt.legend(loc='upper left', fontsize=12)
plt.show()
initial_investment = btc_recent.loc[list(signals_ema[signals_ema.positions == 1.0].index)][0]
bought = np.sum(btc_recent.loc[list(signals_ema[signals_ema.positions == 1.0].index)]*-1.0)
sold = np.sum(btc_recent.loc[list(signals_ema[signals_ema.positions == -1.0].index)])
current_btc_value = btc_recent[-1]balance_ema = pd.DataFrame([btc_recent.loc[list(signals_ema[signals_ema.positions == 1.0].index)]*-1.0,
btc_recent.loc[list(signals_ema[signals_ema.positions == -1.0].index)]]).transpose()
balance_ema = balance_ema.fillna(0)
balance_ema['balance'] = balance_ema.sum(axis=1)print "Initial investment amount: {0:.2f} USD".format(initial_investment)
print "Maximum invested amount: {0:.2f} USD".format(abs(min(balance_ema.cumsum().balance)))
print "Current asset value: {0:.2f} USD".format(bought+sold+current_value)
使用 EMA 交易策略,我会以 4,321.44 美元开始投资,在大约两个月的时间内,我需要 6,665.21 美元继续投资,我的 1 比特币的最终价值现在应该是 8,751.43 美元(27/12/2017)。
这是一个有趣的玩具项目,以实际落实我在课堂上学到的知识,我将尝试用时间序列分析和比特币数据进行进一步探索。但是我应该投资比特币吗?我还不确定,也许当我进一步探索的时候,我会找到一些答案。
感谢您的阅读,您可以从下面的链接中找到上面代码的 Jupyter 笔记本。
https://github . com/tthustle sa/TSA _ bit coin/blob/master/BTC _ price . ipynb
熊猫的基本时间序列操作
[image courtesy: https://pixabay.com/]
作为一个几乎每天都在处理时间序列数据的人,我发现 pandas Python 包对于时间序列操作和分析非常有用。
这是关于 pandas 的时间序列数据操作的基本介绍,可以让您开始时间序列分析。具体目标是向您展示如何:
- 创建日期范围
- 使用时间戳数据
- 将字符串数据转换为时间戳
- 对数据框中的时间序列数据进行索引和切片
- 对不同时间段的聚合/汇总统计数据的时间序列进行重新采样
- 计算滚动统计,如滚动平均值
- 处理缺失的数据
- 了解 UNIX/纪元时间的基础知识
- 了解时间序列数据分析的常见陷阱
让我们开始吧。如果您想处理您拥有的真实数据,您可能想从使用 pandas [read_csv](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html)
将您的文件读入数据框开始,但是我们将从处理生成的数据开始。
首先导入我们将要使用的库,然后用它们来创建一个日期范围
import pandas as pd
from datetime import datetime
import numpy as npdate_rng = pd.date_range(start='1/1/2018', end='1/08/2018', freq='H')
此日期范围具有每小时一次的时间戳。如果我们调用date_rng
,我们会看到它看起来像下面这样:
DatetimeIndex(['2018-01-01 00:00:00', '2018-01-01 01:00:00',
'2018-01-01 02:00:00', '2018-01-01 03:00:00',
'2018-01-01 04:00:00', '2018-01-01 05:00:00',
'2018-01-01 06:00:00', '2018-01-01 07:00:00',
'2018-01-01 08:00:00', '2018-01-01 09:00:00',
...
'2018-01-07 15:00:00', '2018-01-07 16:00:00',
'2018-01-07 17:00:00', '2018-01-07 18:00:00',
'2018-01-07 19:00:00', '2018-01-07 20:00:00',
'2018-01-07 21:00:00', '2018-01-07 22:00:00',
'2018-01-07 23:00:00', '2018-01-08 00:00:00'],
dtype='datetime64[ns]', length=169, freq='H')
我们可以检查第一个元素的类型:
type(date_rng[0])#returnspandas._libs.tslib.Timestamp
让我们用时间戳数据创建一个示例数据框,并查看前 15 个元素:
df = pd.DataFrame(date_rng, columns=['date'])df['data'] = np.random.randint(0,100,size=(len(date_rng)))df.head(15)
Example data frame — df
如果我们想进行时间序列操作,我们需要一个日期时间索引,这样我们的数据框就可以在时间戳上建立索引。
将数据帧索引转换为日期时间索引,然后显示第一个元素:
df['datetime'] = pd.to_datetime(df['date'])df = df.set_index('datetime')df.drop(['date'], axis=1, inplace=True)df.head()
df with datetime index
如果我们数据中的“时间戳”实际上是字符串类型而不是数字类型,会怎么样?让我们将我们的date_rng
转换成一个字符串列表,然后将字符串转换成时间戳。
string_date_rng = [str(x) for x in date_rng]string_date_rng#returns['2018-01-01 00:00:00',
'2018-01-01 01:00:00',
'2018-01-01 02:00:00',
'2018-01-01 03:00:00',
'2018-01-01 04:00:00',
'2018-01-01 05:00:00',
'2018-01-01 06:00:00',
'2018-01-01 07:00:00',
'2018-01-01 08:00:00',
'2018-01-01 09:00:00',...
我们可以通过推断它们的格式将字符串转换成时间戳,然后查看值:
timestamp_date_rng = pd.to_datetime(string_date_rng, infer_datetime_format=True)timestamp_date_rng#returnsDatetimeIndex(['2018-01-01 00:00:00', '2018-01-01 01:00:00',
'2018-01-01 02:00:00', '2018-01-01 03:00:00',
'2018-01-01 04:00:00', '2018-01-01 05:00:00',
'2018-01-01 06:00:00', '2018-01-01 07:00:00',
'2018-01-01 08:00:00', '2018-01-01 09:00:00',
...
'2018-01-07 15:00:00', '2018-01-07 16:00:00',
'2018-01-07 17:00:00', '2018-01-07 18:00:00',
'2018-01-07 19:00:00', '2018-01-07 20:00:00',
'2018-01-07 21:00:00', '2018-01-07 22:00:00',
'2018-01-07 23:00:00', '2018-01-08 00:00:00'],
dtype='datetime64[ns]', length=169, freq=None)
但是如果我们需要转换一个独特的字符串格式呢?
让我们创建一个字符串形式的任意日期列表,并将它们转换为时间戳:
string_date_rng_2 = ['June-01-2018', 'June-02-2018', 'June-03-2018']timestamp_date_rng_2 = [datetime.strptime(x,'%B-%d-%Y') for x in string_date_rng_2]timestamp_date_rng_2#returns[datetime.datetime(2018, 6, 1, 0, 0),
datetime.datetime(2018, 6, 2, 0, 0),
datetime.datetime(2018, 6, 3, 0, 0)]
如果我们把它放到一个数据框里会是什么样子?
df2 = pd.DataFrame(timestamp_date_rng_2, columns=['date'])df2
回到我们最初的数据帧,让我们通过解析时间戳索引来查看数据:
假设我们只想查看日期是本月 2 日的数据,我们可以使用如下的索引。
df[df.index.day == 2]
这个的顶部看起来像:
我们也可以通过数据框的索引直接调用我们想要查看的日期:
df['2018-01-03']
在特定日期之间选择数据怎么样?
df['2018-01-04':'2018-01-06']
我们填充的基本数据框以每小时的频率为我们提供数据,但是我们可以以不同的频率对数据进行重新采样,并指定我们希望如何计算新采样频率的汇总统计数据。我们可以取最小值、最大值、平均值、总和等。,按照下面的示例,以每天的频率而不是每小时的频率来计算数据的日平均值:
df.resample('D').mean()
那么窗口统计呢,比如滚动平均值或滚动总和?
让我们在原始 df 中创建一个新列,计算 3 个窗口期间的滚动总和,然后查看数据框的顶部:
df['rolling_sum'] = df.rolling(3).sum()
df.head(10)
我们可以看到,这是正确的计算,只有当有三个周期可以回顾时,它才开始有有效值。
这是一个很好的机会,看看我们如何在处理缺失数据值时进行数据转发或回填。
这是我们的 df,但增加了一个新列,接受滚动总和并回填数据:
df['rolling_sum_backfilled'] = df['rolling_sum'].fillna(method='backfill')
df.head(10)
用现实值(如一段时间内的平均值)填充缺失的数据通常很有用,但请始终记住,如果您正在处理一个时间序列问题并希望您的数据是现实的,您应该而不是对您的数据进行回填,因为这就像是展望未来并获得您在该时间段内永远不会获得的信息。您可能希望向前填充数据的频率高于回填。
处理时间序列数据时,您可能会遇到 Unix 时间中的时间值。Unix 时间,也称为纪元时间,是自协调世界时(UTC)1970 年 1 月 1 日星期四 00:00:00 以来经过的秒数。使用 Unix 时间有助于消除时间戳的歧义,这样我们就不会被时区、夏令时等弄糊涂了。
下面是一个以纪元时间表示的时间 t 的示例,并且将 UNIX/纪元时间转换为以 UTC 表示的常规时间戳:
epoch_t = 1529272655
real_t = pd.to_datetime(epoch_t, unit='s')real_t#returnsTimestamp('2018-06-17 21:57:35')
如果我想将 UTC 时间转换成我自己的时区,我可以简单地做以下事情:
real_t.tz_localize('UTC').tz_convert('US/Pacific')#returnsTimestamp('2018-06-17 14:57:35-0700', tz='US/Pacific')
有了这些基础知识,您就可以开始处理时间序列数据了。
以下是在处理时间序列数据时需要记住的一些技巧和要避免的常见陷阱:
- 检查您的数据中是否存在差异,这些差异可能是由特定地区的时间变化(如夏令时)引起的。
- 小心翼翼地跟踪时区——让阅读您代码的其他人知道您的数据处于哪个时区,并考虑转换为 UTC 或标准化值,以便保持您的数据标准化。
- 丢失数据可能经常发生——确保您记录了您的清理规则,并考虑不要回填您在取样时无法获得的信息。
- 请记住,当您对数据进行重新采样或填充丢失的值时,您会丢失一些关于原始数据集的信息。我建议跟踪你所有的数据转换,并跟踪数据问题的根源。
- 当你对数据进行重采样时,最好的方法(平均值、最小值、最大值、总和等。)将取决于你所拥有的数据种类以及数据的取样方式。考虑好如何为你的分析重新采样数据。
使用 IBM PowerAI 开源框架的机器学习中的图像分类基础(第 2 部分)
介绍
图像分类已经成为展示机器学习的关键试点用例之一。在之前的文章中,我介绍了机器学习,IBM PowerAI,在 IBM Power 平台上运行图像分类程序时比较了 GPU 和 CPU 的性能。在本文中,我们来看看如何检查神经网络任何内层的输出,并通过使用 Nvidia DIGITS 来训练您自己的模型。
观察隐藏层参数
直到 20 世纪 80 年代,研究人员才发现给神经网络增加更多的层可以极大地提高其性能。这种具有几个隐藏层的神经网络如今在包括图像分类在内的几个用例中很常见。与名称所表明的相反,可以观察隐藏层中的相关参数。
卷积神经网络体系结构
现在你可能知道,卷积神经网络(CNN)是一种深度神经网络,用于图像分类时会产生相当准确的结果。
在工科学校学习数字信号处理的时候,你一定会碰到卷积这个术语。简单来说,两个信号的卷积是两个信号函数的乘积的积分,在其中一个函数被反转和移位之后。在我们的例子中,每个输入图像都是像素值的矩阵。要查看隐藏层中如何执行卷积的可视化表示,请考虑以下示例。
Source: https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/
在本例中,橙色矩阵(3x3)称为滤镜,用于计算原始图像(5X5 像素矩阵)的卷积输出。结果被称为激活图或功能图。应当理解,根据所应用的滤波器,可以修改和训练输出特征图,以获得期望的输出。
在现代 CNN 中,滤波器是在训练过程中自动学习的,但是我们确实根据所使用的架构指定了某些参数(如下所示)。如果你需要更详细的分析,请访问这个博客。
在我们的例子中,使用了 AlexNet 的一个版本,这是我们所依赖的标准架构。在下面的代码中,我们阅读了网络的结构。CNN 包含两个有序字典;
a) **Net.blobs**
为输入数据;
a.它有以下参数–批量大小、通道尺寸、高度和宽度
b) **Net.params**
是具有权重和偏差参数的斑点向量;
a.权重表示连接的强度。接近零的权重表示输入和输出之间的良好相关性。
b.偏差表示预测值与实际值之间的差距,对于预测值进入下一步非常重要。
c.它具有以下参数——权重的输出通道、输入通道、滤波器高度和滤波器宽度,以及偏差的一维输出通道。
让我们试着把这些打印出来。
# for each layer, show the output shapefor layer_name, blob in net.blobs.iteritems():print layer_name + ‘\t’ + str(blob.data.shape)
这是输出。
data (50, 3, 227, 227)conv1 (50, 96, 55, 55)pool1 (50, 96, 27, 27)norm1 (50, 96, 27, 27)conv2 (50, 256, 27, 27)pool2 (50, 256, 13, 13)norm2 (50, 256, 13, 13)conv3 (50, 384, 13, 13)conv4 (50, 384, 13, 13)conv5 (50, 256, 13, 13)pool5 (50, 256, 6, 6)fc6 (50, 4096)fc7 (50, 4096)fc8 (50, 1000)prob (50, 1000)
和;
for layer_name, param in net.params.iteritems():print layer_name + ‘\t’ + str(param[0].data.shape), str(param[1].data.shape)
这是输出。
conv1 (96, 3, 11, 11) (96,)conv2 (256, 48, 5, 5) (256,)conv3 (384, 256, 3, 3) (384,)conv4 (384, 192, 3, 3) (384,)conv5 (256, 192, 3, 3) (256,)fc6 (4096, 9216) (4096,)fc7 (4096, 4096) (4096,)fc8 (1000, 4096) (1000,)
如你所见,我们这里有四维数据。这里有一个函数来可视化这些数据;
def vis_square(data):
“””Take an array of shape (n, height, width) or (n, height, width, 3)
and visualize each (height, width) thing in a grid of size approx. sqrt(n) by sqrt(n)”””
# normalize data for display
data = (data — data.min()) / (data.max() — data.min())
# force the number of filters to be square
n = int(np.ceil(np.sqrt(data.shape[0])))
padding = (((0, n ** 2 — data.shape[0]),
(0, 1), (0, 1)) # add some space between filters
+ ((0, 0),) * (data.ndim — 3)) # don’t pad the last dimension (if there is one)
data = np.pad(data, padding, mode=’constant’, constant_values=1) # pad with ones (white)
# tile the filters into an image
data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))
data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])
plt.imshow(data); plt.axis(‘off’)
在这里,您可以看到层 conv1 中的滤波器;
# the parameters are a list of [weights, biases]filters = net.params[‘conv1’][0].datavis_square(filters.transpose(0, 2, 3, 1))
Filters in a layer
这里,我们看到前 36 个滤波器的校正响应;
feat = net.blobs[‘conv1’].data[0, :36]vis_square(feat)
Rectified output
在这里,我们看到第五层的输出,在池化之后;
feat = net.blobs[‘pool5’].data[0]vis_square(feat)
Output of the fifth layer after pooling
第一个完全连接的层是“fc6 ”,它是一个整流输出。使用此代码显示所有非负值的直方图;
feat = net.blobs[‘fc6’].data[0]plt.subplot(2, 1, 1)plt.plot(feat.flat)plt.subplot(2, 1, 2)_ = plt.hist(feat.flat[feat.flat > 0], bins=100)
Histogram of rectified output — More explanation in this blog
这里,我们看到了所有预测类的最终概率值的直方图。这里最高的峰值显示了最高的预测类别,在我们的例子中,是猩猩。还显示了其他次要的簇峰。
feat = net.blobs[‘prob’].data[0]plt.figure(figsize=(15, 3))plt.plot(feat.flat)[<matplotlib.lines.Line2D at 0x7f09587dfb50>]
The top peak here shows the top predicted class, in our case, orangutan
如何训练自己的机器学习模型?
英伟达是什么数字?
Nvidia 深度学习 GPU 训练系统( DIGITS )是一个应用程序,用于对图像进行分类,执行分割和对象检测任务。这是一个基于 GUI 的应用程序,与 Caffe 接口。下载和安装程序可以在他们的网站上找到。Github 上也有稳定版和其他测试版。DIGITS 服务器安装在我在这个演示中使用的容器中。安装后,可以从端口 5000 访问 GUI。
下一步是从网上下载一个样本数据集到我在虚拟机中创建的目录(/DIGITS)中。这个数据集被称为 CIFAR-100。它包含 100 个图像类别,每个类别包含 600 个图像。每个类有 500 个训练图像和 100 个测试图像。CIFAR-100 中的 100 个类被分成 20 个超级类。每个图像都有一个“精细”标签(它所属的类)和一个“粗糙”标签(它所属的超类)。
下面是它包含的内容的简要说明;
-
Labels.txt:该文件包含训练数据集中的类的列表。
-
Train:该目录包含用于训练的图像。
-
Train.txt:该文件包含训练文件到类之间的映射列表。标签是按位置排列的,即 labels.txt 文件中的第一个标签用数字 0 表示,第二个用数字 1 表示,依此类推。
4)测试:该目录包含用于测试训练质量的图像。
- Test.txt:这个文件包含测试文件和类之间的映射列表。标签是按位置排列的,即 labels.txt 文件中的第一个标签用数字 0 表示,第二个用数字 1 表示,依此类推。
root@JARVICENAE-0A0A1841:~/DIGITS# python -m digits.download_data cifar100 .
输出;
Downloading url=http://www.cs.toronto.edu/~kriz/cifar-100-python.tar.gz …Uncompressing file=cifar-100-python.tar.gz …Extracting images file=./cifar-100-python/train …Extracting images file=./cifar-100-python/test …Dataset directory is created successfully at ‘.’Done after 65.3251469135 seconds.
让我们来看看下载的数据集。虽然我没有显示上面列出的其他目录,但假设它们已经下载并存在。
root@JARVICENAE-0A0A1841:~/DIGITS# ls fine/train | headappleaquarium_fishbabybearbeaverbedbeebeetlebicyclebottle
让我们用下载的预训练数据集(CIFAR-100)创建一个新的分类数据集。
New Image Classification Dataset on DIGITS
这里,/root/DIGITS/fine/train 路径是我们数据集的路径。还要注意“单独的测试图像文件夹”选项,并指定/root/DIGITS/fine/test 目录。您还可以为此数据集指定一个名称,例如“Cifar100”(未在上面的屏幕截图中显示)。
当您单击 Create 时,将启动一个创建培训数据库的新作业,如下所示。
Job status
上图中右侧窗格显示了相关作业的状态。完成后,您的 DIGITS 主屏幕现在应该显示该数据集可供使用。
创建新的图像分类模型
让我们用我们创建的 CIFAR-100 数据集创建一个名为“分类图像”的新图像分类模型。我们将为该模型使用预构建的 AlexNet 神经网络架构。
New image classification model
单击“Create ”(创建)后,一个新的作业会像以前一样启动。下面的屏幕截图显示了名为“Train Caffe Model”的作业的状态。
Job status of new image classification model
随着培训的进行,工作状态将在下图中更新。随着时间的推移,我能够看到准确性的提高。
Training your model
一段时间后,当作业完成时,您将能够上传测试图像并根据您的模型对其进行分类。一个示例图像(一个青苹果)正在上传,结果立即可见。
Sample image classification
对于像 CIFAR-100 这样的小数据集来说,这是相当好的精度,当使用较大的数据集时,可以预期更好的精度值。
我想写一个更短的第三部分来展示火炬的好处。时间会证明一切。
如果你喜欢这首曲子,请鼓掌👏🏻(可以不止一次鼓掌)!你也可以在网上的某个地方分享,这样其他人也可以阅读。
本网站上的帖子是我自己的,不一定代表 IBM 的立场、策略或观点。
作者:乌彭德拉·拉詹