TowardsDataScience-博客中文翻译-2020-八十六-

TowardsDataScience 博客中文翻译 2020(八十六)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

我对当前数据科学行业的观察和职业建议

原文:https://towardsdatascience.com/my-observations-of-the-current-data-science-industry-and-career-advice-1fbe36cd6a83?source=collection_archive---------58-----------------------

大海的观点

我自己的简短简历。我是一名 1 岁的数据科学家,在新加坡工作。没有计算机科学或统计学学位,我花了 3 年时间追求数据科学的职业生涯,然后我得到了一份全职的 DS 工作。在这篇博客中,我想分享我对数据科学行业的理解,并给热衷于从事 ds 职业的朋友们一些建议。这里表达的观点代表我自己,是基于我的工作经验、社交网络以及我阅读的书籍和文章而给出的。

1.数据科学家的头衔正在经历一场“膨胀”。

由于近年来对人工智能和大数据的关注越来越多,越来越多的公司声称他们正在他们的产品中采用人工智能技术,并寻求雇用数据科学家。但是,一个公司是否需要很多数据科学家,“数据科学家”真的在做实际的数据科学工作吗?“科学家”的头衔听起来很好听,但大多数数据科学家的日常工作与实际的科学家相去甚远,例如在研究所从事前沿研究课题的统计学家和物理学家。因此,对于热衷于从事 ds 职业的朋友们,第一个建议是,不要被花哨的标题所迷惑。有必要了解 DS 的角色,选择最适合自己兴趣和实力的工作。

了解 DS 的生命周期,找到您的兴趣和优势

有几个朋友问我,数据科学家平时的日常工作是什么?被称为 21 世纪最性感的工作,数据科学家实际上不是一个独立的工作,而是需要各种角色之间的广泛合作。很好地理解典型 DS 生命周期中的不同角色非常有帮助。

图 1 典型的数据科学生命周期

图 1 给出了典型数据科学生命周期中的常见角色。一般来说,数据科学家的主要职责是开发具有适当算法和工具的机器学习模型,以解决特定的商业问题,如欺诈检测和需求预测。在下游,机器学习工程师将原型模型从笔记本带到生产中。以上所有的角色在一个 DS 项目中都是不可或缺的。在创业公司,有可能一个人需要承担多个角色。

以下博客详细介绍了不同项目阶段涉及的各种数据相关角色。

[## 你是哪种类型的数据专家?

扩展数据科学领域的实地指南

towardsdatascience.com](/which-flavor-of-data-professional-are-you-5e01375584ce)

2.不同公司的数据科学家的价值由他们带来的业务影响来衡量。

作为各种 IT 专业人士的新宠之一,数据科学家被认为具有超强的赚钱能力。然而,事实并非如此,至少在东南亚是如此。图 2 显示了新加坡和旧金山的数据科学家和软件工程师的平均年薪对比。

图 2 数据科学家和软件工程师的薪资对比

新加坡数据科学家和软件工程师的薪酬差距比旧金山小得多。这表明 SEA 中的 DS 产业还不成熟。大多数中小企业不能理解 DS 和 ML 技术的能力。他们不知道 DS 功能可以实现什么,也不知道如何建立 DS 员工队伍。

对薪酬差距较小的另一种解释是,SEA 中的数据科学家带来的业务影响有限。就工作的复杂性和技术技能的要求而言,数据科学家和软件工程师可能同样具有挑战性。对于大多数 IT 公司来说,开发人员永远是他们技术团队的中坚力量。没有开发人员的贡献,他们的产品无法生存,而他们的数据科学家在理想情况下可能会将利润提高 5%。你能看出这里的区别吗?

因此,我想在这里给出的第二个建议是,当你选择一份 DS 工作时,评估你作为一名数据科学家能够给企业带来的职位和潜在影响。

在选择 DS 工作时,评估您作为数据科学家的职位以及您可以为企业带来的潜在影响。

你可以问自己几个问题。

  • DS 是公司产品的核心技术吗?
  • 作为一名数据科学家,你会参与产品或内部使用的系统的开发吗?
  • 你将处理什么样的问题和项目?是你喜欢的吗?

答案没有对错好坏之分。这完全取决于你的兴趣所在。

3.DS 的研究和实验性质使它具有挑战性,但也令人着迷。

如果你到了这里,我希望你没有因为前两个观察而对追求 DS 望而却步。当你开始处理现实世界的问题时,DS 就变得很吸引人,例如用户行为、营销策略、各种可能影响收入的因素。当数据科学家开发的应用程序能够预测用户的未来决策并推动销售增长时,他们最有成就感。如果没有繁琐的数据处理、大量的研究和重复的实验,这是无法实现的。当商业目标实现后,所有的努力都是值得的。

另外,DS 需要更多的商业思维和创造力。如何将问题框定,使其可用现有数据解决?模型应该使用什么样的特征?应该使用什么指标来衡量绩效?这些问题都不容易回答。这就是领域知识在 DS 工作中扮演重要角色的原因。这也是数据科学家和开发人员的区别。

知道了它的利弊,如果它是你喜欢的东西,那就瞄准它,下定决心去努力。有大量的资料介绍如何为 DS 职业做准备。这里我只做一个快速的总结。

  • 为技术技能做准备:数学、编程、机器学习。
  • 建立 DS 项目组合。竞赛和自发项目是一个很好的起点。
  • 阅读并与 DS 人员交谈,了解该技术如何应用于不同行业。

下面的博客给出了自学 DS 的实用指南。我曾经被各种资源淹没:在线课程、书籍、竞赛平台。正确的方法是为每个主题找一个好的材料,并坚持下去。熟能生巧。

[## 如何免费学习数据科学

一个完整的学习路径,包括不花你一分钱的资源

towardsdatascience.com](/how-to-learn-data-science-for-free-eda10f04d083)

谢谢你的阅读。我欢迎反馈和建设性的批评,您可以通过 LinkedIn 联系我。

我的奥德赛,寻找最流行的 Python 函数

原文:https://towardsdatascience.com/my-odyssey-finding-the-most-popular-python-function-6aa216db047c?source=collection_archive---------18-----------------------

我们都喜欢 Python,但是我们多久使用一次这些强大的功能呢?一篇关于我寻找答案的文章

在 Pythonrepositories 中提到最多的 Python 函数是通过 GitHub 提交计算的。作者图片

介绍

有一天,当我通过 map()运行 zip()和一些列表时。我无法停止注意这些年来我的 Python 风格发生了多大的变化。

我们以前都问过自己这个问题,其他人用这种美丽的语言做什么?他们用什么功能?

作为一名数据科学家,我的目标是更容易衡量的东西。GitHub 提交中提到最多的 Python 功能是什么?

在下面的文章中,我将

  1. 讨论这样一个问题的局限性,以及我用了多少方法都没能找到答案
  2. 展示我如何从 GitHub 收集数据
  3. 最重要的是,教你如何用酷的赛车吧来吸引普通读者

限制

最初,我开始这个项目是为了弄清楚 Python 函数被调用的频率。很快我们注意到,在 Github 上,你可以很快找到它。使用搜索功能!

GitHub 上 print()函数的数量,图片由作者提供

问题解决了!

嗯,不完全是…

问题是这些结果是不稳定的。通过多次调用这个搜索,我们可以得到任意数量的结果!这意味着当再次调用它时。

GitHub 上再次调用 print()函数的数量,图片由作者提供。

我们得到一个非常不同的结果…

Github API

GitHub 有一个神奇的搜索 API!

问题解决了!

嗯,不完全是…

这里的问题是,他们只提供代码的前 34k 结果或类似这样的结果,在相当长的时间内试图从中获得一些有用的东西。我不得不意识到他们不会允许我这样做。遗憾的是,我们的问题无法用简单的方法来回答。

通过提交的 Github 搜索功能

过了一段时间后,我发现在 Python 语言中可以通过提交和时间进行搜索!

问题解决了!

嗯,不完全是…

虽然这种搜索方式似乎相当可靠。它会产生很多假阳性。例如,它将显示提交到只提交一点点 Python 的存储库。在某种意义上,提交可以包括单词或函数。

虽然这并不理想,但我决定采用这种方法,因为它允许随着时间的推移进行比较。此外,我尝试了我能想到的所有其他方法,如果你找到了更好的方法,请在评论中告诉我。总的来说,这个数据必须带着许多怀疑,但我希望它能给我们一些有价值的教训。最肯定的是,它创造了一个杀手情节;)

数据收集

我们有找到答案的近似方法。现在,我们要做的就是调用 GitHub API!

问题解决了!

嗯,不完全是…

问题似乎是这个 API 应该更多地用于你的存储库内部的实际搜索。GitHub 似乎对他们返回给你的链接数量有硬性限制。他们似乎寻找了 X 秒钟,然后停下来,并返回他们到目前为止得到的任何东西。这很有意义,因为处理如此大量的数据非常昂贵。可悲的是,这也让我们寻找答案的旅程变得更加艰难。

由于我们拒绝放弃,我们决定调用他们的网站,并从返回的 HTML 解析答案!虽然这既不优雅也不简单,但我们不是懦夫。

让我们建立我们的联系。链接示例可能如下所示

[https://github.com/search?q=**{function}**%28+language%3A**{Language}**+type%3Acommits+committer-date%3A%3C{**before_year**}-01-01&type=commits](https://github.com/search?q=len%28+language%3APython+type%3Acommits+committer-date%3A%3C2000-01-01&type=commits)

示例链接,作者图片

如我们所见,我们主要寻找三样东西。

function: What function do we want to know about? e.g. len()
language: What programming language? e.g. Python
before_year: Before what year? e.g. 2000

当把这些参数输入 GitHub 时,它会告诉我们在那个日期之前已经提交了多少函数!

在调用这个链接之后,它返回给我们一个 HTML 文件,我们可以过滤这个文件来得到我们的答案。做这些事情的代码可以是

import urllib.requestlanguage='Python'
befor_year=2000# create the url using a year and a language
url_base = *f"https://github.com/search?l=Python&q={search_term}%28+language%3A{language}+type%3Acommits+committer-date%3A<{befor_year}-01-01&type=commits"*fp = urllib.request.urlopen(url_base)
byte_html = fp.read()
org_html = byte_html.decode("utf8")
fp.close()

例如,为了过滤结果 HTML,我们可以使用 regex。我们也可以使用 BeautifulSoup 或者其他一些可爱的 HTML 解析库,但是使用 regex 会大大简化本文的可读性。在这种特定的情况下,我们只关心一个数字,这使得简单地寻找那个数字更快。

import re
find_count = re.compile(r'([0**-**9,]+) (available|commit)')

上面的正则表达式“find_count”查找字符串“44,363 commits”。使用匹配组(“()”中的所有内容),我们可以从字符串“44,363”中提取数字组合。

快速完成这项工作的完整代码是,

正如我们所看到的,我们迭代所有的术语和年份,为每个函数收集一个数据点。然后我们从 HTML 中解析结果并存储它。剩下的整个过程是为了确保我们遵守 GitHub 的速率限制,不会被禁止累积我们的数据!

GitHub 似乎并不喜欢我们一直调用他们相对昂贵的功能;)这个我跑了 20 年,20 个函数,用了 80 多分钟,我觉得挺惊讶的。

最后,我们已经收集了我们想要的数据,现在可以用一些很酷的图来炫耀了!

形象化

我们现在有了一个大致如下的数据框架,

date,print(),len(),join()
2000-01-01,677545,44165,23534
2001-01-01,859815,66593,40032
2002-01-01,1091170,93604,59618
2003-01-01,1391283,117548,80327
2004-01-01,1755368,152962,125238
2005-01-01,2049569,185497,173200

每年每个函数提交的函数数量。这个数据集合特别易于可视化。

要把数据随时间可视化,我觉得赛车吧是最酷的。虽然它们可能不是信息最丰富的,但它们看起来令人难以置信!

我们需要的是一个 CSV,对于每个日期,有几个类别。一旦我们有了这样一个 CSV,我们就可以很容易地使用奇妙的 bar_chart_race 库。

注意:当通过 pip 安装时,这个库似乎没有完全更新,所以通过 github 安装

python -m pip install git+[https://github.com/dexplo/bar_chart_race](https://github.com/dexplo/bar_chart_race)

现在,剩下要做的就是将我们的 CSV 传递给函数,创建一个漂亮的 gif。

def plot_search_term_data(file):
    *"""
    This function plots our df* ***:param*** *file: file name of the csv, expects a "date" column
    """* df = pd.read_csv(file).set_index('date')
    bcr.bar_chart_race(
        df=df,
        filename=file.replace('.csv', '.gif'),
        orientation='h',
        sort='desc',
        n_bars=len(df.columns),
        fixed_order=False,
        fixed_max=True,
        steps_per_period=10,
        period_length=700,
        interpolate_period=False,
        period_label=
        {'x': .98, 'y': .3, 'ha': 'right', 'va': 'center'},
        period_summary_func=
        lambda v, r: {'x': .98, 'y': .17,
                      's': f'Calls{v.sum():,.0f},
                      'ha': 'right', 'size':11},
        perpendicular_bar_func='median',
        title='Most Mentioned Python Functionality Over Time',
        bar_size=.95,
        shared_fontdict=None,
        scale='linear',
        fig=None,
        writer=None,
        bar_kwargs={'alpha': .7},
        filter_column_colors=False)

在 Pythonrepositories 中提到最多的 Python 函数是通过 GitHub 提交计算的。作者图片

结论

我们已经看到了如何使用 regex 而不是通常的 bs4 直接从 HTML 收集数据。虽然这种方法不应该用于更重要的项目,但是对于像这样的简单任务,这种方法是必须的。我们还看到,最突出的数据源可能并不总是有效的。

最后,我们发现了一个新的可爱的图书馆和如何创建美丽的赛车酒吧,将捕获您的观众的兴趣!

如果你喜欢这篇文章,我会很高兴在 Twitter 或 LinkedIn 上联系你。

一定要看看我的 YouTube 频道,我每周都会在那里发布新视频。

整个代码

我成为认证解决方案架构师的途径

原文:https://towardsdatascience.com/my-path-to-become-a-certified-solution-architect-a22d9650af1d?source=collection_archive---------19-----------------------

这是我如何在 28 小时的准备时间内成为认证解决方案架构师的故事

菲德尔·费尔南多在 Unsplash 上的照片

介绍

大家好,我叫 Philipp,在一家科技孵化创业公司担任机器学习工程师。在工作中,我为金融科技和保险公司设计并实现了云原生机器学习架构。

我在两年半前开始使用 AWS。从那以后,我已经使用 AWS 服务在私人和工作中构建了许多项目。最喜欢 aws 的无服务器服务。对我来说,无服务器优先总是适用的。

总之我有几年的 AWS 专业和兼职经验,但是没有证书。我知道实践经验和知识比证书更重要。但是有时候你需要一张纸来证明。

放弃

这篇文章不会展示每个人如何在 30 小时的学习中获得认证。而是应该激励其他和我有同样经历但是太懒的人。

证书

因此,几周前,我决定参加“AWS 认证解决方案架构师——SAA 助理-C02”认证。

“AWS 解决方案架构师-助理 SAA-C02”证书验证了在 AWS 上设计和部署动态可扩展、高度可用、容错和可靠的应用程序的能力。考试时间为 130 分钟,由 65 道题组成。

研究

首先我研究了一下,考试标准是什么。根据AWSSolution _ Architect-_ Associate _ SAA-C02 _ Exam _ Blue _ Print,它由这 4 个主题组成。

除了 PDF 文档

第二,我研究了在线课程和总结/小抄。我很快找到了一个在线课程,因为我已经熟悉了云专家。在谷歌搜索了一番后,我找到了贾延德拉的博客,几乎每个话题都有一份备忘单。

研究

最初,我看了一位云专家的“AWS 认证解决方案架构师助理 SAA-C02”课程。由于我的经验,我以 2 倍的速度观看了课程。每一集包含一个实验室,我后来都独立实现了。

在我完成课程后,我参加了一个云专家的模拟考试,获得了 78 分。因此我预约了 3 天后的实习。在这 3 天里,我每天学习 4 个小时,做了 10 次模拟考试,用小抄学习。

学习路径概述

学习路径

我总共花了 7 周零 28 小时完成了“AWS 认证解决方案架构师-助理 SAA-C02”证书。

考试

考试当天,我参加了最后一次模拟考试,并做了 a cloud guru 课程的每个测验。我在家通过 PearsonVue 参加考试。作为一名模范考生,我提前满足了所有要求,为考试做好了准备。入住非常容易,导师也很和蔼。大约花了 10 分钟才开始。

我花了 80 分钟完成并通过了考试。

学习

实践考试是好的,但由于 AWS 发展如此之快,他们不一定要准确。就我而言,我有大约 8 到 10 个关于存储网关、efs、fsx 的问题,而在模拟考试中这些问题要少得多。我从中得到的教训是,我应该少做一次模拟考试,多读一些文档。

我学到的第二件事是,对自己能力的肯定是一件值得骄傲的事情。

感谢阅读,特别感谢贾延德拉的博客一位云计算大师

如果你有任何问题,随时联系我。你可以在 TwitterLinkedIn 上与我联系,或者给我写一封电子邮件

原载于 2020 年 10 月 24 日https://www . philschmid . de

我挑选的 48 个高级数据库系统面试问题

原文:https://towardsdatascience.com/my-pick-for-top-48-advanced-database-system-interview-questions-deb7b30968ca?source=collection_archive---------2-----------------------

适用于中高级受访者

旧的数据库系统,美好的往昔——照片由 Unsplash 上的 Kolar.io 拍摄

除了知道如何查询,你还应该了解一些数据库系统的知识。这是意料之中的,面试的时候经常会出现这些知识问题。在这里,我试着挑选我最喜欢的高级数据库系统面试问题。重点是“高级”,我假设您熟悉数据库基础知识,所以我跳过诸如什么是 DBMS 之类的基本问题。什么是 SQL?什么是交易?或者要求您运行一些基本的查询。我也尽我所能的把这些问题分类,归类,让学习更容易。

我希望这篇文章短小精悍,但结果并非如此。所以,我希望你做好长时间阅读的准备。如果你想通过数据库系统面试,你必须开始花时间做功课,我相信这篇文章是一个很好的起点。

我试图删除不必要的细节,只解释必要的内容。但是,当问题本身很有趣,值得多读的时候,我提供了一些补充材料的链接。

好的。我们开始吧。

一般问题

#1 传统的基于文件的系统有哪些问题使得 DBMS 成为更好的选择?

一个主要问题是准入。在没有索引的情况下,你唯一的选择就是全页扫描,速度超级慢。

另一个问题是冗余和不一致。文件有许多重复和冗余的数据,如果你改变其中的一个,你可能会使它们都不一致。保持文件的一致性是非常昂贵的。

另一个问题是缺乏并发控制。因此,一个操作可能会锁定整个页面,而在 DBMS 中,允许对单个文件执行多个操作。

数据隔离、完整性检查、事务的原子性和安全问题是传统的基于文件的系统的一些其他问题,DBMSs 为这些问题提供了一些很好的解决方案。

#2 有哪些开源和商业关系型 DBMSs 的例子?

对于开源 RDBMS,三种流行的软件是 MySQL、PostgreSQL 和 SQLite。对于商业 RDBMSs,您可以提到 Oracle、Microsoft SQL server、IBM DB2 和 Teradata。

#3 什么是数据库模型?列举几个常见的数据库模型?

数据库模型是数据库的逻辑结构,描述存储和访问数据的关系和约束。一些常见的数据库模型包括:

  • 关系模型
  • 层次模型
  • 实体关系模型
  • 文档模型
  • 面向对象(OO)模型

#4 如何选择数据库模型?

在某种程度上,这取决于您的应用程序,每个数据库模型都有自己的优势。例如,文档模型适用于文本或半结构化数据。另一方面,如果您有原子数据,关系模型是您的最佳选择。
这也取决于你使用的数据库管理系统。许多数据库管理系统只适用于一种特定的模型,用户没有其他选择。

#5 什么是 ER 建模?

实体关系是一种建模形式,它试图模仿现实世界中实体之间存在的关系。在 ER 建模中,实体是真实世界的某个方面,例如事件、地点、人员,而关系,顾名思义,是这些实体之间的关系。

在 ER 建模中,所有实体都有它们的属性,这些属性在现实世界中可以被看作是对象的特征。例如,如果 employee 是一个实体,那么该雇员的姓名就是它的属性之一。

作为 ER 建模的示例,我们可以对员工之间的一种关系形式建模如下:两个实体,即主管和员工,以及一种关系,即主管。你可以像这样对你的整个组织建模。

员工的 ER 模型

#6 什么是 NoSQL?

NoSQL 指的是为一些特定的数据模型而构建的一组数据库,例如图形、文档、密钥对和宽列。与关系数据库不同,NoSQL 数据库具有灵活的模式。NoSQL 数据库因其易开发性、功能性和大规模性能而得到广泛认可。与 SQL 数据库不同,许多 NoSQL 数据库可以跨数百或数千台服务器进行水平扩展。

与传统的关系数据库相比,NoSQL 系统被认为是非常年轻的。然而,由于许多创新和性能改进,它们的受欢迎程度正在上升。

除了这些系统的所有好处之外,值得一提的是,NoSQL 数据库通常不能提供与关系数据库相同的数据一致性。这是因为 NoSQL 系统牺牲了 ACID 属性来支持速度和可伸缩性。

如果你想了解更多关于 NoSQL 数据库的信息,这里有一个极好的来源。

#7 什么是交易的 ACID 属性?

代表 A 富, C 协调, I 溶解, D 耐久。为了维护数据库的一致性,在事务之前和之后,必须满足这四个条件。下面,我试着简单描述一下这个概念。

原子性:又称“全有或全无法则”。基本上,要么存储事务的所有部分,要么不存储任何部分。不允许部分交易。例如,如果一个交易是从一个账户取钱并存入另一个账户,那么它的所有部分都必须完成,这样数据库才能保持一致。如果我们部分地做这个交易,那么我们就使我们的数据库不一致。

一致性:对这一术语的定义没有共识。一般来说,您可以这样看,在事务之前,数据库是一致的,在事务之后,它也必须保持一致。

隔离:我们同时运行许多事务,每个事务的中间状态必须对其他事务不可见。例如,在我为原子性描述的转账交易中,其他交易必须要么看到一个帐户中的钱,要么看到另一个帐户中的钱,而不是两个都看到。换句话说,如果我们让事务彼此完全隔离,那么事务就必须看起来是串行运行的,而不是并发运行的。

持久性:当事务成功提交时,它必须持久化(存储在磁盘上),并且不能撤销,即使在崩溃的情况下也是如此。

#8 数据抽象的不同层次是什么?

DBMS 中的数据抽象是对用户隐藏不相关细节的过程。一般来说,数据抽象有三个层次。1)物理层,其是最低层,是数据存储描述,该层由 DBMS 管理,并且该层的细节通常对系统管理员、开发者和用户隐藏;2)描述数据库和不同字段之间关系的概念或逻辑层。开发人员和系统管理员在这一层工作;3)仅描述部分数据库的外部或视图级别。例如,查询的结果是视图级别的数据抽象。用户通常在这一层工作,表模式及其物理存储的细节对他们是隐藏的。

存储管理

#9 列式和基于行的数据库有什么区别?

基于行的数据库将数据逐行存储在磁盘上,而列数据库将数据逐列存储。每种方法都有自己的优点。前者对于行上的操作非常快速和高效,而后者对于列上的操作非常快速和高效,例如为列的子集聚集大量数据。

通常需要整行的操作是写操作,如INSERTDELETEUPDATE。需要列的操作通常是读操作,如SELECTGROUP BYJOIN等。

一般来说,列数据库是分析操作理想选择,行数据库是事务处理的理想选择。

#10 什么是 OLTP 和 OLAP 及其区别?

OLTP 和 OLAP 都是在线处理系统。OLTP 代表“在线事务处理”,它是一个管理面向事务的应用程序的系统,OLAP 代表“在线分析处理”,它是一个管理分析查询的系统。

这两个系统的主要区别在于,OLTP 是一个写入密集型系统,而 OLAP 是一个读取密集型系统。这种差异对它们的实施有重大影响。例如,对于 OLTP 系统来说,采用适当的并发控制非常重要,而这在读取量大的操作中并不是主要问题。这两个系统之间的另一个区别是,OLTP 查询通常很简单,返回的记录数量相对较少,而 OLAP 查询非常复杂,涉及许多复杂的连接和聚合。

另一个区别是,由于 OLTP 系统的实时性,它们通常采用分散式架构来避免单点故障,而 OLAP 系统通常采用集中式架构。

此外,在大多数 DBMSs 中,OLTP 是基于行的数据库,而 OLAP 是列数据库。

#11 什么是正常化和去正常化?

规范化是将数据组织到多个表中以最小化冗余的过程。去正常化是相反的过程。它将规范化的表合并到一个表中,以便数据检索变得更快。规范化的主要优点是可以更好地利用磁盘空间。规范化后,维护数据库的完整性也更容易。

JOIN 是允许我们反转规范化并创建数据的非规范化形式的操作。

#12 什么是数据仓库?

它是从不同来源收集(提取、转换和加载)数据并将它们存储到一个数据库中的过程。您可以将数据仓库视为一个中央存储库,数据从事务系统和其他关系数据库流入其中。它可以关联广泛的业务数据,以提供对组织绩效的更深入的管理洞察。数据仓库是商业智能的核心,商业智能是用于数据分析和报告的系统。

该数据库与标准操作数据库分开维护。它们是两个独立的系统,后者经过优化,可以快速准确地更新实时数据,而前者最适合离线操作,可以长期查看数据。

数据库

并发控制

克里斯·萨博尔在 Unsplash 上的照片

并发控制是 DBMS 中确保同时操作不会相互冲突的过程。

#13 什么是数据库锁及其类型?

一般来说,可以说锁主要用于确保只允许一个用户/会话更新特定的数据。这里我描述了两种类型的锁:共享锁(S)和排他锁(X)。这些锁可以保存在表、页、索引键或单独的行上。

共享锁:当一个操作请求一个表上的共享锁时,如果被授予,这个表就可以被读取。这个锁可以与其他读操作共享,并且它们可以同时读这个表。

排他锁:当一个操作请求一个表上的排他锁时,如果被授予,就拥有对该表写的排他权。如果其他操作请求对该锁定的表进行访问,将会被阻止。

锁兼容性矩阵

对于锁还有另一个相关的概念,叫做意向(I)锁。我们有意向共享锁(IS)和意向排他锁(IX)。这些锁允许更细粒度的并发控制。从技术上讲,我们不需要它们。s 和 X 锁足够了,但是对查询优化有帮助。关于意向锁的更多细节通常超出了高级问题的范围。

#14 什么是“锁升级”?

数据库锁可以存在于行、页或整个表或索引中。当事务正在进行时,事务持有的锁会占用资源。锁升级是指系统将多个锁合并到一个更高级别的锁中(例如将多个行锁合并到一个页面或将多个页面合并到一个完整的表中),通常是为了恢复大量细粒度锁占用的资源。

#15 什么是“锁争用”?

当多个操作请求一个表上的排他锁时,就会发生锁争用。在这种情况下,操作必须在队列中等待。如果您遇到长期锁争用,这意味着您的数据库的某些部分是热的,您必须进一步划分这些数据块,以允许更多的操作同时获得独占锁。锁争用可能是扩展数据库的瓶颈。

#16 什么是“僵局”?

死锁是指一些事务无限期地等待对方放弃锁的情况。通常,有两种方法来解决这个问题,一种是惰性方法,这意味着什么都不做,如果发生了,那么检测它并重新启动一个操作来解开死锁。另一种方法是主动的,这意味着防止死锁的发生。如果你想了解更多关于死锁预防的知识,请点击这里阅读

#17 什么是隔离级别?

隔离是酸性的第三个字母。有了这个属性,我们的目标就是让所有的事务彼此完全隔离(可序列化)。然而,有些应用不需要完全隔离。因此,我们定义了一些没有完全隔离严格的其他隔离级别。一般来说,定义了五个隔离级别。

Read Uncommitted: 根本没有锁。并发事务可以读取其他事务的未提交数据,也可以写入这些数据。在数据库术语中,他们说 DBMS 允许脏读。

读提交:在这个级别,DBMS 不允许脏读。在此级别,每个事务持有当前行的读/写锁,只有在提交更改时才会释放。这种隔离级别仍然允许不可重复的读取,这意味着事务在读取同一行时返回不同的值。如果你看看下面的图片,会更清楚。很明显,不允许脏读,但是不可重复的读仍然存在。

提交读隔离级别的示例

可重复读取:正如您之前看到的,“提交读取”隔离级别的问题是“不可重复读取”。为了避免不可重复的读取,每个事务必须对它们读取的行持有读锁,对它们写入的行持有写锁(例如,插入、更新和删除),直到它们提交更改。这种隔离级别是可重复读取的。

但是,在这个隔离级别中仍然有一个场景,它会使数据库不一致。如果我们向表中插入或删除新行,然后进行范围查询,那么结果将会不一致。看下面的例子。事务 1 中的同一个查询返回两个不同的结果。这种情况被称为“幻像读取”。

可序列化:这是最高的隔离级别。正如您在“可重复读取”中看到的,幻像读取可能会发生。为了防止幻影读取,我们必须持有整个表的锁,而不是行的锁。下图是迄今为止所有隔离级别的总结。

快照:这个隔离级别不同于我目前描述的其他隔离级别。其他的是基于锁和块的。这个不用锁。在此隔离级别中,当事务修改(即插入、更新和删除)行时,已修改行的提交版本将被复制到临时数据库(tempdb)并接收版本号。这也称为行版本控制。然后,如果另一个会话试图读取已修改的对象,该对象的已提交版本将从 tempdb 返回给该操作。

如果我描述的快照隔离听起来与其他隔离级别有根本的不同,那是因为它确实不同。其他隔离级别基于悲观的并发控制模型,但快照隔离基于乐观的模型。乐观模型假设冲突很少发生,并决定不阻止它们,如果它们发生了就处理它们。它不同于悲观模型,悲观模型确保无论如何都不会发生冲突。

访问方法

马库斯·斯皮斯克Unsplash 上拍摄

访问方法是支持快速访问行/列子集的组织技术或数据结构。一些最常见的数据结构是哈希表和 B 树的变体。

#18 什么是哈希及其优缺点?

哈希是一种查找技术。基本上,这是一种将键映射到值的方法。散列函数将字符串转换成通常较短的固定长度的值,然后这些值可以用作存储原始元素的索引。

如果我们使用一个好的哈希函数,哈希可以用来在一个常数时间内索引和检索数据库中的项目,这比其他的查找技术要快。

优势:

  • 哈希表是点查找(也称为等式查询)的理想数据结构,尤其是当数据库很大时,因为无论输入大小如何,您都可以在恒定的时间内搜索、插入和删除数据。

缺点:

  • 有些情况下,哈希不一定是最佳选择。例如,对于小数据,好的散列函数的成本使得散列比简单的顺序搜索更昂贵。
  • 另一种情况是范围扫描操作(也称为范围查询),对于这种操作,B+树是一种理想的数据结构。
  • 另一种情况是寻找子字符串或前缀匹配,哈希对于这些操作基本上是无用的。
  • 哈希的另一个缺点是可伸缩性。随着数据库的增长,哈希表的性能会下降(更多的冲突和更高的冲突解决成本,例如,添加更多的存储桶或重新散列现有项目)

#19 什么是 B+树及其优缺点?

B+树是 B 树家族中的一种数据结构。这种数据结构及其变体在索引方面非常流行。该树是自平衡树,并且有适当的机制来确保节点至少是半满的。在 B+树中,数据存储在叶节点中,并且叶节点彼此顺序链接。叶节点之间的这些顺序链接允许在不遍历树结构的情况下顺序访问数据。这种顺序访问允许快速有效的范围扫描。

B+树允许在对数时间内进行搜索、顺序访问、插入和删除。在这个回答的最后,可以找到一个 B+树样本可视化。如果你有兴趣,你可以通过这个可视化工具为自己绘制一个(这里)。

通常,在数据库系统中,B+树数据结构与哈希表进行比较。所以,在这里我试着解释一下 B+树相对于哈希表的优缺点。B+树的优点是在范围查询和搜索子字符串中,使用 LIKE 命令。另一方面,对于等价查询,哈希索引优于 B+树。B+树的另一个优点是它可以很容易地随着数据增长,因此,它更适合在磁盘上存储大量数据。

一个常见的后续问题是,B+树和二叉查找树(BST)之间有什么区别?B+ tree 是 BST 的推广,它允许树节点有两个以上的子节点。

如果有人问你 B 树和 B+树的区别,你可以提两点。首先,在 B+ three 中,记录只存储在叶子中,内部节点存储指针(key)。与 B+树不同,在 B 树中,键和记录都可以存储在内部节点和叶节点中。第二,a B+树的叶节点是链接在一起的,而在 B 树中,它们是不链接的。你可以在下面的例子中看到这两个不同之处。

b 树可视化

B+树可视化

#20 聚集索引和非聚集索引有什么区别?

索引用于加速查询过程。没有它们,DBMS 需要执行全表扫描,这非常慢。

聚集索引与数据的物理存储相关。基本上,我们要求 DBMS 按列对我们的行进行排序,并按照这个顺序物理存储它们。如您所见,每个表只能有一个聚集索引。聚集索引允许我们非常快速地检索数据,因为它提供了快速的顺序扫描。您可以创建自定义的聚集索引,也可以让 DBMS 使用主键自动为您创建聚集索引。

相比之下,非聚集索引与物理存储无关。这些索引基于列进行排序,并存储在不同于表的位置。您可以将这些索引想象成一个包含两列的查找表。一列是一个表列的排序形式,另一列是它们在内存中的物理地址(行地址)。对于这些索引,如果我们寻找一个记录,我们首先在查找表中搜索它的索引,然后我们到物理内存中获取与该行地址相关的所有记录。

总之,非聚集索引比聚集索引慢,因为它们涉及额外的查找步骤。此外,由于我们需要存储这些查找表,我们需要额外的存储空间。另一个区别是,我们可以为每个表创建一个聚集索引,而非聚集索引的数量可以根据我们的需要而定。

操作员执行

塞巴斯蒂安·莱昂·普拉多Unsplash 上拍摄的照片

#21 什么是相关和非相关子查询?
就相互依赖而言,有两种类型的子查询,一种是内部查询依赖于外部查询的值,我们称这种查询为“相关”查询,另一种是内部和外部查询相互独立,我们称之为“非相关”查询。

不用说,相关子查询非常慢,因为它要求内部子查询对外部查询中的每一行运行一次。

#22 有哪些不同的 JOIN 算法?

有三种主要的算法来执行连接。这里我试着简单描述一下,并提及它们的优点。

  • 嵌套循环:它将外部表和内部表的所有值相互比较。这是唯一能够交叉连接(多对多连接)的算法。在没有更好的算法的情况下,它可以作为一个后备选择。
  • 散列连接:这是最通用的连接方法。简而言之,它构建两个输入中较小的一个内存哈希表,然后读取较大的输入并探测内存哈希表以找到匹配。哈希联接只能用于计算等值联接。它通常比嵌套循环更有效,除非连接的探测端非常小。
  • 排序-合并连接:该算法首先根据连接属性对两个表进行排序。然后找到第一个匹配项,向下滚动两个表,合并匹配属性的行。

#23 什么是存储过程?

你可以把它当作一个半程序。执行特定任务的一组 SQL 语句。如果这个任务是一个常见的任务,那么我们可以将查询存储到一个过程中,并在需要时执行它,而不是每次都运行查询。下面是一个结构简单的程序。

CREATE PROCEDURE <Procedure-Name> AS
Begin
     <SQL STATEMENT>
End

创建一个过程后,无论何时需要,我们都可以使用 execute 命令来执行它

EXECUTE <Procedure-Name>

存储过程有很多好处。主要的一点是 SQL 代码的可重用性。如果该过程是常用的,它有助于避免多次编写代码。另一个好处是当我们使用分布式数据库时,它减少了通过网络发送的信息量。

#24 什么是数据库触发器?

触发器是一个存储过程,在事件发生之前/之后自动运行。这些事件可以是 DML、DDL、DCL 或数据库操作,如登录/注销。通用触发器语法如下:

CREATE [ OR ALTER ] TRIGGER [ Trigger_name ] 
[BEFORE | AFTER | INSTEAD OF]  
{[ INSERT ] | [ UPDATE ] | [ DELETE ]}  
ON [table_name]  
AS
{SQL Statement}

触发器的一些应用有:检查事务的有效性、实施参照完整性、事件记录、自动生成一些派生列以及用户登录前/后的安全授权。

如果你被问到触发器和存储过程的区别,你可以提到触发器不能被自己调用。它们在事件期间被调用。相比之下,存储过程是一个独立的查询,可以独立调用。

查询规划和优化

阿尔瓦罗·雷耶斯在 Unsplash 上拍摄的照片

查询规划和优化是许多 RDBMSs 的一个特性。查询优化器试图通过考虑可能的查询计划来确定执行给定查询的最有效方式。

什么是执行计划?

执行计划是对数据库引擎为有效运行查询而计划执行的操作的描述。您可以将它视为 DBMS 查询优化器的一个视图,DBMS 查询优化器基本上是一个寻找实现查询的最有效方法的软件。执行计划是对性能不佳的查询进行故障排除的主要手段。

阅读执行计划,理解它并根据计划排除故障是一门艺术。因此,如果你想了解更多,一个很好的参考是这里

#26 什么是查询优化?

SQL 是一种声明性语言,而不是过程性语言。基本上你告诉数据库管理系统你想要什么,但你没有说如何得到这些结果。这要靠数据库管理系统来解决。DBMS 可以采用多种查询策略来获得正确的结果。但是,这些执行计划会产生不同的成本。查询优化器的工作是比较这些策略,并选择预期成本最低的策略。在这种情况下,成本是 I/O 和处理成本的加权组合。I/O 成本是从磁盘访问索引和数据页的成本。

#27 提几个提高查询性能的最佳实践?

这是一个普遍的问题,实际上有许多方法可以提高查询性能。这里我只提几个。

  • 避免在单个查询中使用多个连接
  • 使用连接代替子查询。
  • 对常用数据和更复杂的查询使用存储过程。
  • 使用 WHERE 表达式尽可能限制结果的大小。

这里是回答这个问题的另一本好书。

故障修复

照片由罗姆森·普里查维特Unsplash 上拍摄

崩溃恢复是回滚到一致且可用的状态的过程。这是通过撤销未完成的事务并重做崩溃发生时仍在内存中的已提交事务来实现的

#28 什么是预写日志?

在 DBMSs 中,恢复管理和维护原子性和持久性的实际技术是使用预写日志(WAL)。使用 WAL,所有的更改首先被写入一个日志,然后日志本身必须被写入一个稳定的存储器,然后更改才被允许被物理地应用。这就是它被称为预写日志的原因。一个简单的技术,保证当我们从崩溃中回来的时候,我们仍然可以弄清楚我们在崩溃之前正在做什么,并从我们停止的地方继续。

什么是检查点?

检查点与基于日志的恢复系统相关。为了在崩溃后恢复数据库,我们必须重做所有的日志记录。但是如果我们从头开始重做所有的日志记录,那么恢复一个数据库将花费很长时间。所以,一段时间后我们必须忽略一些记录。检查点是我们出于恢复目的决定忽略它们之前的记录的点。如您所见,通过使用检查点,DBMS 可以减少在崩溃时重启数据库的工作量。

分布式系统

什么是分布式数据库?

分布式数据库是多个相互连接的数据库的集合,这些数据库在物理上分布在不同的位置。几乎在所有情况下,这些物理上分离的数据库都具有无共享的架构,并且彼此独立。然而,DBMS 以一种对用户/应用程序显示为单个数据库的方式逻辑地集成数据。

#31 什么是数据库分区?

分区是将非常大的表分成多个较小的可管理的部分的过程。分区的一些好处包括更快的查询、更快的数据加载和更快的旧数据删除。分区的好处受到分区键和粒度选择的限制。

有两种方法可以对表进行分区:水平和垂直。垂直分区将不同的列放入不同的分区,而水平分区根据分区键将行的子集放入不同的分区。例如,公司的销售记录可以根据销售日期进行水平划分。

#32 什么是数据库分片?

本质上,分片是一种水平分区架构。每个碎片都有相同的模式和列,但是有不同的行,并且它们是相互独立的。

分片的主要好处是可伸缩性。借助自动分片架构,您可以根据需要随时向堆栈中添加更多机器,并降低现有机器的负载,从而提高流量和处理速度。它对成长期的应用程序非常有吸引力。

如果想了解更多,可以参考这篇文章(此处)。

SQL 相关问题

#33 什么是不同类型的 SQL 语句?

SQL 语句是高级指令,每条语句负责一项特定的任务。这些陈述通常可以分为五类:

  • 数据定义语言(DDL)
    *这一系列 SQL 命令用于定义数据库模式。
    *例子包括CREATEDROPALTER
  • 数据操作语言(DML)
    *这一系列 SQL 命令用于修改表中的数据。
    *例子包括INSERTUPDATEDELETE
  • 数据查询语言(DQL)
    *这一系列 SQL 命令对现有的表执行查询。
    *例子包括SELECT
  • 数据控制语言(DCL)
    *这一系列 SQL 命令处理权限和许可。
    *例子包括GRANTREVOKE
  • 事务控制语言(TCL)
    *这一系列 SQL 命令用于处理事务。
    *示例包括COMMITROLLBACKSAVEPOINT
    *只有在有 OLTP 操作的情况下才需要这些命令。

# 34 DDL 和 DML 的区别是什么?

他们关系密切。DDL 负责定义表的结构,基本上是什么允许进入表,什么不允许。DDL 可以看作是一组塑造表结构(模式)的规则。在 DDL 定义了模式之后,DML 的工作就是用数据填充表。

#35 标量函数和聚合函数有什么区别?

这两个函数都返回单个值,不同之处在于输入,标量函数对单个值进行操作,而聚合函数对一组值进行操作。我试着用一个例子来说明两者的区别。比如像ISNULL()ISNUMERIC()LEN()这样的字符串函数就是标量函数。它们输入单个值并返回单个值。另一方面,AVG()MAX()SUM()是聚合函数,它们输入多个值并输出单个值。

#36 什么是数据库视图?

视图是一个虚拟的表。这个虚拟表可以临时保存 SQL 查询的结果,以供将来参考。您可以将它视为一个命名查询,以后可以通过它的名称来引用它,而不必重新编写整个查询。视图的一个优点是,不用创建一个全新的表来存储查询结果,而是创建一个视图来节省磁盘空间。

#37 视图和物化视图有什么区别?

视图结果不存储在磁盘上,每次运行视图时,我们都会得到更新的结果。但是,在物化视图中,事情就不一样了。我们将结果存储在磁盘上,并采用某种机制来保持它们的更新(也称为视图维护)。

当视图被频繁访问时,物化视图是有益的。这样,我们不需要每次都运行它。然而,物化视图有存储成本和更新开销。

#38 什么是常见的餐桌用语(CTE)?

CTE 可被视为临时视图或“内嵌”视图。换句话说,CTE 是一个临时结果集,您可以在另一个SELECTINSERTUPDATEDELETE语句中引用它。我之所以说 CTE 是一个临时视图,是因为它只能被附加到它的查询使用,而不能在其他地方被引用。

CTE 用WITH算子定义。下面是 CTE 的简单蓝图。您可以只使用一个WITH来定义多个 cte,它允许您简化复杂的查询。

不是我最喜欢的,气人,但他们经常被问到

# 39 DROP 和 TRUNCATE 命令有什么区别?

DROP 将整个表删除,并且不能回滚。另一方面,TRUNCATE 会删除该表中的所有行。使用 TRUNCATE,表定义(模式)仍然存在,如果需要,我们可以在将来插入数据。

#40 删除和截断命令有什么区别?

DELETE 和 TRUNCATE 属于两个不同类别的 SQL 命令,前者属于 DML,后者属于 DDL。换句话说,前者在行级别上操作,而后者在表级别上操作。TRUNCATE 一次删除表中的所有行。DELETE 也可以做到这一点,但是它会一行一行地删除它们,这样会花费太多的时间。如果使用 TRUNCATE,则不能回滚数据,但使用 DELETE,可以回滚删除的行。

#41 主键和外键有什么区别?

这些关键字是交叉引用不同表的非常重要的工具。它们也有助于参照完整性。然而,它们在性质上是不同的。一个表只有一个主键。主键 1)可以唯一地标识表中的记录;2)不能接受空值;3)对于大多数 DBMSs,默认情况下,是聚集索引。与主键不同,一个表可以有多个外键。外键 1)是另一个表中的主键;2)不能唯一标识表中的记录;3)可以接受空值,4)不会自动索引。由用户为其创建索引。

# 42 WHERE 和 HAVING 从句有什么区别?

这两个子句都用于通过提供一些条件从结果集中筛选行来限制结果集。然而,有一点不同。WHERE 子句扫描原始数据(逐行)以检查条件并对其进行筛选,但让扫描聚合结果以检查条件并对其进行筛选。因此,在 SQL 查询中,HAVING 位于GROUP BY之后。总之,WHERE 过滤原始数据,而 HAVING 过滤经过处理的数据。

#43 什么是函数依赖?

如果其中一个属性唯一地标识另一个属性,则表的属性在功能上是相关的。通过一个例子,它变得更加清晰。假设我们有一个带有属性的雇员表:Id、姓名和年龄。在这里,雇员 Id 唯一地标识雇员姓名,因为如果我们知道雇员 Id,我们就可以唯一地说出他/她的姓名。函数相关性用箭头→表示。所以,在这种情况下,我们可以用Id -> Name来表示

#44 什么是不同的归一化类型?

正常化有许多级别。正如我前面解释的,规范化的目标是避免冗余和依赖。但是,这个目标不是一步就能实现的。每一个规范化步骤(类型)都让我们更接近我们的目标。

我们从非规范化形式的数据(UNF)开始,在 UNF 中,单元格可以有多个值(非原子的),如果我们将这些值分成多个单元格,以确保每个表格单元格都有一个值,并删除重复的行以确保所有记录都是唯一的,那么我们将 UNF 转换为第一范式(1NF)。

下一步是引入主键和外键。在这一步中,我们进一步划分 1NF 表,创建新表,并通过主键和外键连接它们。如果在这些新表中,所有非键属性都完全依赖于主键,那么我们就达到了第二范式(2NF)

虽然有了 2NF,我们已经大大减少了冗余和依赖性,但仍有很大的改进空间。下一步是移除传递性函数依赖,这基本上意味着这样一种情况:如果我们更改一个非键列,我们可能会导致另一个非键列发生更改。为了理清这些非键列,我们必须创建一个单独的表。当我们没有传递函数依赖时,我们就达到了第三范式(3NF)。

在几乎所有的数据库中,3NF 是一个我们无法将数据库进一步分解成更高形式的规范化的点。但是,在一些复杂的数据库中,有些情况下您可以实现更高形式的规范化。

更高形式的规范化是 Boyce-Codd 范式(BCNF)、4NF、5NF 和 6NF,我不想讨论它们。如果你有兴趣了解更多关于这些更高形式的规范化,你可以从维基百科的数据规范化页面阅读它们(此处)。

#45 什么是不同的诚信规则?

有两种类型的完整性规则,如果我们遵守它们,我们可以维护我们的数据库一致性。实体规则和参照规则。实体规则与我们的主键相关,如果我们将一列作为主键,那么它不能有任何空值。引用规则与我们的外键相关,我们的外键必须具有空值,或者它们的值必须是另一个表的主键。

#46 什么是 DML 编译器?

它是一个翻译器。它将 DML 查询从高级语句转换为可由查询评估引擎执行的低级指令。

#47 什么是光标?

光标是一种工具,用户可以使用它来以逐行的方式返回结果。这与典型的 SELECT 语句不同,后者返回整个结果集。通常,我们对完整的行集感兴趣,但是有些应用程序,尤其是那些交互式和在线的应用程序,并不总是能够有效地将整个结果集作为一个单元。这些应用程序喜欢逐行处理数据。游标允许它们执行这种逐行操作。

你可以在下面的例子中看到使用光标的整个过程。

#48 什么是基数?

数据库系统上下文中的基数意味着“唯一性”。例如,当我们说一个列的基数较低时,这意味着它有许多重复值。

参考

  • 数据工程师必读的五本书 ( 链接)
  • 实施数据治理:实现合规性和数据驱动洞察的分步指南 ( 链接)
  • 数据目录:开启商业洞察力的钥匙 ( 链接)
  • 元数据管理:数据治理的关键组件 ( 链接)
  • 确保数据质量:最佳实践、挑战和解决方案 ( 链接)
  • 数据安全:数据工程师的基本考虑 ( 链接)
  • 数据完整性与数据质量 ( 链接)
  • 探索使用数据集成 API 的好处和挑战 ( 链接)
  • 数据处理的发展:ETL 与 ELT——哪一个适合您的业务需求? ( 链接)
  • 数据编排 101:了解不同类型的工具及其用例 ( 链接)
  • 数据网格:实现以产品为中心的数据架构的概念和最佳实践 ( 链接)
  • 从头开始设计数据仓库:技巧和最佳实践 ( 链接)
  • 查询优化 101:技术和最佳实践 ( 链接)
  • 我挑选的 48 个高级数据库系统面试问题 ( 链接)
  • ACID 属性:深入研究数据库系统事务 ( 链接)
  • 机器学习模型开发、部署和维护的最佳实践 ( 链接)
  • 边缘计算和机器学习:释放实时数据分析的潜力 ( 链接)
  • GraphQL 和机器学习:如何构建更好、更智能的应用 ( 链接)
  • 特征库:类固醇上的特征工程,缩放机器学习的关键 ( 链接)
  • 使用 BigQuery ML 简化机器学习:全面概述 ( 链接)

我希望你喜欢读这篇文章。如果你愿意支持我成为一名作家,考虑报名参加成为一名媒体成员。每月只需 5 美元,你就可以无限制地使用 Medium。

我的灵活推荐 Python 代码

原文:https://towardsdatascience.com/my-python-code-for-flexible-recommendations-b4d838e9e0e0?source=collection_archive---------50-----------------------

我的额外定制 Python 代码,使您能够基于 Surprise library 的 K-Nearest neighborhood 样式模型运行更灵活的推荐。

照片由merit ThomasUnsplash 上拍摄

在我的上一篇博文中,我详细讨论了如何使用惊奇库在 Python 中使用推荐系统,从数据处理到预测和前 N 名推荐。如果你不熟悉这个主题,我建议你先阅读这篇文章,作为对协同过滤推荐系统的介绍,我不会重复其中的段落让你厌烦。

我在开始我的上一篇文章时打了一个比方,蛋糕店里的纸杯蛋糕排起了长队,作为一个消费者,由于资源有限,你无法尝试所有的蛋糕,因此推荐系统非常重要。继续这个类比,如果在我们分析了所有可用的纸杯蛋糕后,有人想出了一个额外的纸杯蛋糕,我们宁愿产生结果而不是重新开始整个过程。(我真的很期待我能弄清楚如何继续类比,以及什么样的封面图片将符合我接下来要写的基于模型的推荐系统的逻辑...)

在使用 Surprise 时,我不喜欢的一点是,为了给新用户做推荐,你必须将用户的评级添加到大量的训练数据中,然后重新拟合你的整个模型。其原因是预测模型建立在相同的类结构之上,对于使用矩阵分解的更复杂的模型,重新拟合是唯一的选择。

在这篇文章中,我将展示如何在不重新运行模型的情况下进行推荐。我们将构建一个推荐器类

  • 使用 Surprise library 在大群体中只需计算一次参数,
  • 当您输入新的单个用户评级时,返回推荐项目的有序列表。

我们关注的是KNNWithMeans模型,这是在我的项目中导致最高RMSE分数的模型类型,但是该方法也可以很容易地针对KNNBasicKNNWithZScores模型进行调整。你可以在我的 GitHub repo 里找到整个项目的代码。

数学背景

正如我提到的,我不想重复我以前的帖子,但我认为有一个关于KNNWithMeans模型背后的数学公式的快速提醒是很好的。 rᵤᵢ 是用户 u 对项目 i 的评分, μᵢ 是对项目I【nᵤᵏ(i】所有评分的平均值)是用户 u 评分的项目中“最接近I】项目的最大 k 数。

surprise 的 KNNWithMeans 模型中的估计用户评分

计划

我们将利用这一事实来估计用户 u 将如何基于他们的其他评价来评价项目 i ,我们需要的是:

  • 其他项目的平均评分,或μᵢ
  • 物品之间的相似性,或者说 sim ( i,j )。

我们将创建一个名为KNNWithMeans_Recommender的类,它有三个参数:

  • sim_dataframe:一个pandas DataFrame对象,一个带有项目间相似性的方阵。我们不关心使用哪种方法,可以是cosinepearsonMSD。列名应该与索引名(项目的名称)相同,顺序相同。
  • average_ratings_by_item : a pandas Series,每个项目的平均评分,其中指数为项目名称。这将提供KNN模型的“带手段”部分。
  • k_factor:一个整数,用于限制我们在评估评级时考虑的相邻项目的数量。

我们稍后将研究如何创建这些参数,现在,我们将重点放在推荐器类上。当我们初始化一个对象时,保存这些参数就是全部了。

该类将有两个功能:estimate_all_for_userestimate_item

默认情况下,当我们与类交互时,我们将使用estimate_all_for_user。它将有一个参数,user_input_dict,这是一个字典,其中条目名称是键,等级是值。(后面我们会看到一个例子。)该函数遍历用户没有评级的项目,并使用estimate_item函数来估计评级。该函数将返回一个字典,其中键是项目名称,值是估计的评级。

另一个函数,estimate_item将基本上是我们前面看到的数学公式,使用相似性和每个项目的平均评分。

密码

下一个块包含我们刚刚描述的类的 Python 代码。

请注意,考虑到我们刚刚讨论了结构,我省略了上面要点中的大部分文档字符串和注释。如果你确实想使用代码,我建议从我的 GitHub repo 中复制原文。(有一些命名上的区别,我的项目本来是一个 boardgame 推荐系统,所以“物品”和“游戏”是可以互换使用的。)

如何使用—输入参数

首先,我们将讨论如何为我们的KNNWithMeans_Recommender对象创建所需的参数。

先说average_ratings_by_item,我们需要一个pandas Series,其中项目名称是指标,评分是数值。我认为您不能从surprise库中生成这个,但是您可以简单地使用groupby方法,假设您在一个名为df的对象中有所有的评级:

avg_ratings_by_item = \
    df.groupby('item_name').mean()['rating'].copy()

sim_dataframe稍微复杂一点。我打算先把所有东西都保存在一个文件里,这样以后更容易利用。我们需要两样东西:相似性和项目名称。

surprise中,kNN 类型的模型有一个sim方法,该方法将以numpy array格式返回相似性矩阵,不包含索引。我使用numpy将它保存在一个名为 pearson_sim 的csv文件中。

my_sim_option = {'name':'pearson', 'user_based':False}
model = KNNWithMeans(sim_options = my_sim_option, verbose = False)
model.fit(trainsetfull)np.savetxt('./results/pearson_sim.csv', model.sim, delimiter=',')

需要注意两件事:

  • 在上面的代码中,我使用了pearson相似度,但是还有其他可用的相似度,参见文档。我使用了pearson,因为这导致了我的项目中最高的RMSE分数。
  • 对于这一步,你从惊喜库中使用哪个 KNN 模型可能并不重要,相似性是以同样的方式计算的。为了保持一致,我们可以使用KNNWithMeans

下一步是获取项目名称,它们将被用作索引和列名。我们可以使用惊喜库的all_itemsto_raw_iid功能(再次请参考我之前的帖子了解详情)。

trainsetfull_iids = list(trainsetfull.all_items())
iid_converter = lambda x: trainsetfull.to_raw_iid(x)
trainsetfull_raw_iids = list(map(iid_converter, trainsetfull_iids))

我还将这些保存在一个csv文件中:

with open('./results/item_ids_for_sim_matrix.csv', 'w') as f:
    writer = csv.writer(f)
    writer.writerows(zip(trainsetfull_raw_iids, trainsetfull_iids))

然后在项目的后期,我将这两个文件,评级和项目列表合并到一个名为pearson_simDataFrame中。这将是我们创建推荐对象时要传递的参数。

pearson_sim = \
    pd.read_csv('./results/pearson_sim.csv', header = None)sim_matrix_itemlist = \  
    pd.read_csv(
        './results/item_ids_for_sim_matrix.csv', header = None)pearson_sim.columns = sim_matrix_itemlist[0]
pearson_sim.index = sim_matrix_itemlist[0]

将结果保存在文件中并将它们组合起来并不是最有效的解决方案,但是我发现这是一种干净的结构,可以方便地在过程的不同区域处理这些结果。

如何使用—预测

好了,有趣的部分来了!

首先,我们需要导入该类,假设您将文件命名为 recomm_func.py:

from recomm_func import kNNWithMeans_Recommender

然后,您可以通过传递我们刚刚讨论过的两个输入参数和一个用于k_factor的整数来初始化一个新对象:

recommender = kNNWithMeans_Recommender(
    pearson_sim, average_ratings_by_item, 10)

正如我提到的,我用这个项目来建立一个棋盘游戏推荐器,一个用户输入的例子是,如果你喜欢棋盘游戏,你可以看到这个测试用户更喜欢欧洲风格的标题:

user_input = {
    'Le Havre': 8,
    'Concordia': 9,
    'The Castles of Burgundy': 8,
    'Mansions of Madness: Second Edition': 5,
    'Kingdom Death: Monster':6
}

estimate_all_for_user方法返回一个包含所有项目和估计评分的字典,下面块中的下一行根据评分对它们进行排序,这样我们可以很容易地确定推荐给用户的前 N 个游戏。

estimated_ratings = recommender.estimate_all_for_user(user_input)sorted_ratings = \
    sorted(estimated_ratings.items(), key=lambda x: x[1])

通过对 sorted_ratings 进行切片,我们可以获得前 10 个推荐:

sorted_ratings[-10:]

将返回以下列表:

[('Agricola', 7.436929246134879),
('Agricola (Revised Edition)', 7.456466489174002),
('Through the Ages: A New Story of Civilization', 7.46818223297934),
('Orléans', 7.4808225652209),
('Terra Mystica', 7.498203401133102),
('Terraforming Mars', 7.5063889188525685),
('Gaia Project', 7.621611348138763),
('Puerto Rico', 7.665136353318606),
('Great Western Trail', 7.786750410443334),
('Brass: Birmingham', 7.82265622044594)]

再一次,作为一个桌游爱好者,这些建议对我这个特定的测试用户来说是有意义的。

通过从前面分割sorted_ratings列表,该代码还可以用于制作反推荐,即用户可能不喜欢的项目。如果你对其他不同的测试用户推荐感兴趣,请查看这款 Jupyter 笔记本的结尾

结论

这就结束了我们在定制推荐功能上的工作。在我看来,一旦建立起来,这个类使用起来真的很方便,而且它使我的项目的代码结构更加精简。一个额外的优势是,你可以利用从早期阶段保存的惊喜库的结果,而不必依赖于当前环境中的库。

我希望你觉得它有用,请随意在你的项目中使用代码,如果你遇到任何问题,请告诉我。

参考

[## 欢迎使用“惊喜”文档!-惊喜 1 文档

如果您对惊喜感到陌生,我们邀请您看一看入门指南,在那里您会找到一系列…

surprise.readthedocs.io](https://surprise.readthedocs.io/en/stable/index.html) [## 如何使用 Python Surprise 构建基于内存的推荐系统

使用 Python 中的 Surprise 库实现 kNN 风格推荐引擎的分步指南,来自 data…

towardsdatascience.com](/how-to-build-a-memory-based-recommendation-system-using-python-surprise-55f3257b2cf4)

我的蟒蛇熊猫小抄

原文:https://towardsdatascience.com/my-python-pandas-cheat-sheet-746b11e44368?source=collection_archive---------3-----------------------

作为一名数据科学家和软件工程师,我每天都在使用熊猫的功能

一位导师曾经告诉我,软件工程师就像索引而不是教科书;我们不会记住所有的东西,但是我们知道如何快速查找。

能够快速查找和使用函数,可以让我们在编写代码时达到一定的流程。所以我创建了这个函数清单,我每天都用它来构建网络应用和机器学习模型。

这不是一个全面的列表,但是包含了我最常用的函数,一个例子,以及我对什么时候它最有用的见解。

内容: 1)设置
2)导入
3)导出
4)查看和检查
5)选择
6)添加/删除
7)合并
8)过滤
9)分类
10)聚集
11)清洗
12)其他
13)结论

1)设置

如果你想自己运行这些例子,从 Kaggle 下载动漫推荐数据集,解压后放到你 jupyter 笔记本的同一个文件夹里。

接下来运行这些命令,你应该能够复制我的以下任何函数的结果。

import pandas as pd
import numpy as npanime = pd.read_csv('anime-recommendations-database/anime.csv')
rating = pd.read_csv('anime-recommendations-database/rating.csv')anime_modified = anime.set_index('name')

2)导入

加载 CSV

将 CSV 直接转换为数据框。有时从 CSV 加载数据也需要指定一个encoding(即:encoding='ISO-8859–1')。如果您的数据框包含不可读字符,这是您应该尝试的第一件事。

另一个类似的函数叫做 excel 文件的pd.read_excel

anime = pd.read_csv('anime-recommendations-database/anime.csv')

从输入的数据构建数据框架

当您想要手动实例化简单数据时非常有用,这样您就可以看到数据在管道中流动时是如何变化的。

df = pd.DataFrame([[1,'Bob', 'Builder'],
                  [2,'Sally', 'Baker'],
                  [3,'Scott', 'Candle Stick Maker']], 
columns=['id','name', 'occupation'])

df.head()

复制数据框

当您想要在保留原始数据框副本的同时对数据框进行更改时,此功能非常有用。加载完所有数据帧后立即copy是一个很好的做法。

anime_copy = anime.copy(deep=True)

3)出口

保存到 CSV

这会转储到与笔记本相同的目录中。我只保存下面的前 10 行,但你不需要这样做。同样,df.to_excel()也存在,功能基本相同,为 excel 文件。

rating[:10].to_csv('saved_ratings.csv', index=False)

4)查看和检查

获取顶部或底部n记录

显示数据框中的第一个n记录。我经常在笔记本的某个地方打印一个数据框的顶部记录,这样如果我忘记了里面的内容,我就可以参考它。

anime.head(3)
rating.tail(1)

计算行数

这本身不是一个 pandas 函数,但是len()计算行数,并且可以保存到一个变量中并在其他地方使用。

len(df)
#=> 3

计算唯一的行

对列中的唯一值进行计数。

len(ratings['user_id'].unique())

获取数据框信息

有用的获得一些一般信息,如标题,值的数量和列的数据类型。一个类似但不太有用的函数是df.dtypes,它只给出列数据类型。

anime.info()

获取统计数据

如果数据框包含大量数值,这将非常有用。了解评级列的平均值、最小值和最大值可以让我们了解数据框的整体外观。

anime.describe()

获取值的计数

获取特定列的值的计数。

anime.type.value_counts()

5)选择

获取列的值列表或系列

如果您需要将列中的值放入Xy变量中,这样您就可以适应机器学习模型,那么这种方法是有效的。

anime['genre'].tolist()
anime['genre']

动漫【流派】。tolist()

动漫['流派']

获取索引值列表

从索引创建值列表。注意我在这里使用了anime_modified数据框,因为指数值更有趣。

anime_modified.index.tolist()

获取列值列表

anime.columns.tolist()

6)添加/删除

用设定值追加新列

当我在两个独立的数据帧中有测试和训练集,并希望在组合它们之前标记哪些行与哪些集相关时,我有时会这样做。

anime['train set'] = True

从列的子集创建新的数据框

当您只想保留大型数据框中的几列,而不想指定要删除的每一列时,这种方法非常有用。

anime[['name','episodes']]

删除指定的列

当您只需要删除几列时非常有用。否则,把它们都写出来会很乏味,我更喜欢前一个选项。

anime.drop(['anime_id', 'genre', 'members'], axis=1).head()

添加包含其他行总和的行

我们将在这里手动创建一个小数据框,因为这样更容易查看。这里有趣的部分是df.sum(axis=0),它将各行的值相加。或者,df.sum(axis=1)将各列的值相加。

当计算计数或平均值时,同样的逻辑也适用,即:df.mean(axis=0)

df = pd.DataFrame([[1,'Bob', 8000],
                  [2,'Sally', 9000],
                  [3,'Scott', 20]], columns=['id','name', 'power level'])df.append(df.sum(axis=0), ignore_index=True)

7)合并

连接两个数据帧

如果您有两个具有相同列的数据框,并且想要合并它们,请使用此选项。

在这里,我们将一个数据帧一分为二,然后将它们重新组合在一起。

df1 = anime[0:2]df2 = anime[2:4]pd.concat([df1, df2], ignore_index=True)

合并数据帧

当您有两个数据框并且想要在一列上连接时,这类似于 SQL 左连接。

rating.merge(anime, left_on=’anime_id’, right_on=’anime_id’, suffixes=(‘_left’, ‘_right’))

8)过滤

检索具有匹配索引值的行

anime_modified中的索引值是动漫的名称。请注意我们如何使用这些名称来获取特定的列。

anime_modified.loc[['Haikyuu!! Second Season','Gintama']]

按编号索引值检索行

这与之前的功能不同。使用iloc,第一行的索引为0,第二行的索引为1,以此类推……即使您已经修改了数据框,并且现在在索引列中使用字符串值。

如果您想要数据框中的前 3 行,请使用此选项。

anime_modified.iloc[0:3]

获取行

检索列值在给定列表中的行。anime[anime[‘type’] == 'TV']在匹配单个值时也有效。

anime[anime['type'].isin(['TV', 'Movie'])]

切片数据帧

这就像分割一个列表。对数据帧进行切片,以获取指定索引之前/之间/之后的所有行。

anime[1:3]

按值过滤

过滤满足条件的行的数据框。请注意,这将保持现有的索引值。

anime[anime['rating'] > 8]

9)分类

排序值

按列中的值对数据框排序。

anime.sort_values('rating', ascending=False)

10)聚集

分组和计数

计算列中每个不同值的记录数。

anime.groupby('type').count()

Groupby 和聚合列的方式不同

注意,我添加了reset_index(),否则type列将成为索引列——我建议在大多数情况下也这样做。

anime.groupby(["type"]).agg({
  "rating": "sum",
  "episodes": "count",
  "name": "last"
}).reset_index()

创建数据透视表

对于从数据框中提取数据子集来说,没有比数据透视表更好的了。

请注意,我已经对数据框进行了严格的过滤,这样可以更快地构建数据透视表。

tmp_df = rating.copy()
tmp_df.sort_values('user_id', ascending=True, inplace=True)
tmp_df = tmp_df[tmp_df.user_id < 10] 
tmp_df = tmp_df[tmp_df.anime_id < 30]
tmp_df = tmp_df[tmp_df.rating != -1]pd.pivot_table(tmp_df, values='rating', index=['user_id'], columns=['anime_id'], aggfunc=np.sum, fill_value=0)

11)清洁

将 NaN 单元格设置为某个值

NaN值的单元格设置为0。在这个例子中,我们创建了与之前相同的数据透视表,但是没有fill_value=0,然后使用fillna(0)来填充它们。

pivot = pd.pivot_table(tmp_df, values='rating', index=['user_id'], columns=['anime_id'], aggfunc=np.sum)pivot.fillna(0)

12)其他

对数据帧进行采样

我一直用这个从一个大的数据框架中抽取一个小样本。它允许随机重新排列行,同时保持索引。

anime.sample(frac=0.25)

迭代行索引

迭代数据框中的索引和行。

for idx,row in anime[:2].iterrows():
    print(idx, row)

启动 jupyter 笔记本

以非常高的数据速率限制启动笔记本电脑。

jupyter notebook — NotebookApp.iopub_data_rate_limit=1.0e10

13)结论

我希望这也能成为你的参考指南。随着我发现更多有用的熊猫功能,我会不断更新。

如果有任何你离不开的功能,请在下面的评论中发表!

我的隔离项目:使用 Tensorflow 的实时面罩检测器

原文:https://towardsdatascience.com/my-quarantine-project-a-real-time-face-mask-detector-using-tensorflow-3e7c61a42c40?source=collection_archive---------35-----------------------

检疫项目

在新冠肺炎封锁的最初几天,我决定做一些与疫情有关的项目,这些项目可能会变得有用。有很多伟大的项目使用了疫情的数据,所以我想专注于一些独特的东西。

随着该国开始经历重新开放的各个阶段,口罩已经成为我们日常生活中的一个重要元素,并将继续存在。为了社交或开展业务,需要佩戴口罩(并正确佩戴)。因此,我决定创建一个应用程序,利用摄像头来检测一个人是否戴着面具,以及面具是否被正确使用。

Kaggle,Tensorflow 和合作实验室

在 Kaggle 上导航时,我遇到了一个由带注释的面具图片组成的小数据集。这是一个很好的注解,这是一个完美的起点。

鉴于我对 Tensorflow 对象检测 API 有些熟悉,我决定使用预先训练好的 COCO 数据集模型。这些预先训练的模型对于 COCO 中已经存在的 90 个类别(例如,人类、汽车、狗等)的开箱即用推理非常棒。它们还特别适用于作为初始化新模型以训练全新数据集的基线。

有许多在浏览器中编写和执行 Python 的好方法,比如 AWS SageMake r,但是 Google Colaboratory 提供免费的 GPU 计算,所以我选择使用 Colab 笔记本来运行我的所有培训。后来,我决定升级到专业帐户,以保证我总是有 GPU 和内存可用。

Google 协作配置

不是巧合,卡格尔。Tensorflow 和 Colaboratory 是谷歌的产品。我确信我可以找到类似的 AWS 或微软的产品,但是没有什么比免费的更好。

为训练准备数据集

带有遮罩批注的元数据文件是 XML 文件,包含有关图像的信息和每个元素的边界框信息。他们使用 PASCAL VOC 格式,这是一种常见的结构。

<annotation>
 <folder>images</folder>
 **<filename>1_13.jpg</filename>** <path>P:\mask_mouth\images\1_13.jpg</path>
 <source>
  <database>Unknown</database>
 </source>
 **<size>**  <width>918</width>
  <height>506</height>
  <depth>3</depth>
 </size>
 <segmented>0</segmented>
 <object>
 **<name>good</name>**  <pose>Unspecified</pose>
  <truncated>0</truncated>
  <difficult>0</difficult>
 **<bndbox>**   <xmin>133</xmin>
   <ymin>109</ymin>
   <xmax>215</xmax>
   <ymax>201</ymax>
  </bndbox>
 </object>

name字段包含对象的类。在这个数据集的情况下,三个类名有些混乱:good代表戴面具的人,bad代表不戴面具的人,none代表面具放置不正确。这很傻,但这给我带来了问题,使这个项目花费了更长的时间,因为我使用了不同类名的 labelmap 进行推理。

生成 CSV 文件

需要做一些调整来规范化数据集。有些文件是 png,有些是 jpg,有些没有相应的 XML 文件,反之亦然。在确保它们都是一致的之后,我将它们随机分成训练集和测试集(80/20)。来自 XMLs 的数据然后被导入到一个 CSV 文件中。每行对应一个注释。CSV 列有:filenamewidthheightclassxminyminxmaxymax

train_xml_df.to_csv(train_path_csv + 'train_labels.csv', index=None)
test_xml_df.to_csv(test_path_csv + 'test_labels.csv', index=None)

生成 TFRecord

TFRecord 是一种存储二进制记录序列的简单格式。所以我的下一步是使用 CSV 创建一个 TFRecord 文件,用于训练网络。为拆分的训练集和测试集分别生成了不同的 TFRecord 文件。

generate_tfrecord(train_csv_file, HOME_DIR, 'train.record', train_path_images)
generate_tfrecord(test_csv_file, HOME_DIR, 'test.record', test_path_images)

培训 TFRecords

在 TFRecords 可用的情况下,下一步是从 Tensorflow 模型动物园中选择一个预训练的模型,并使用它来训练 TFRecords。

在对一些模型进行了一些调查后,我决定使用ssd_inception_v2_coco,因为它可以很好地平衡速度和平均精度(地图)。

关于 Tensorflow 对象检测 API 的事情是,它不被最新的 2。张量流的 x 个版本。遗留代码不是向后兼容的,所以需要做一些工作来找出可以工作的最佳版本。该过程的一部分是编译协议缓冲区,并确保它们包含在PYTHONPATH中。堆栈溢出很方便地帮助我解决了必须降级gast(==0.2.2)numpy(==1.17.4)的问题,并避免在训练中途崩溃。

# Testing Object Detection worksfrom tensorflow.contrib import slim
from nets import inception_resnet_v2
from object_detection.builders import model_builder
from object_detection.protos import input_reader_pb2

型号配置

在能够训练之前,我必须用 TFRecords 的参数和文件位置修改ssd_inception_v2_coco配置文件。每一篇关于物体检测的文章都会详尽地告诉你如何去做。

ssd_inception_v2_coco.config 摘录

拥有可用的 GPU 和 RAM 很有帮助,甚至尝试了大量的步骤。笔记本电脑可以在夜间运行,不会出现大的问题。当有事情发生时,我总是可以从检查点恢复。

python ./models/research/object_detection/**model_main.py** \
--pipeline_config_path={pipeline_fname} \
--model_dir={model_dir} --alsologtostderr \
--num_train_steps={num_steps} --num_eval_steps={num_eval_steps}

培训损失

导出训练好的推理图

一旦训练工作完成,下一步是提取新训练的推理图,该推理图稍后将用于执行对象检测。这可以使用 Tensorflow 对象检测程序来完成。

python object_detection/**export_inference_graph.py** \
--input_type image_tensor --pipeline_config_path {pipeline_fname} \
--trained_checkpoint_prefix {last_model_path} \
--output_directory /content/mask-detection/training/exported_graph

这个过程生成frozen_inference_graph.pb,它是一个 protobuf 文件,包含图形定义以及模型的所有权重。有了这个文件,我们就可以运行训练好的模型并进行推理。

在一些训练图像中运行检测工作得相当好。

训练图像上的目标检测。

我更进一步,将它转换成一个tflite_graph.pb文件作为输入,最终得到一个 TensorFlow Lite flatbuffer 格式detect.tflite

python object_detection/**export_tflite_ssd_graph.py** \
--pipeline_config_path={pipeline_fname} \
--trained_checkpoint_prefix={last_model_path} \
--output_directory /content/mask-detection/tflite \
--add_postprocessing_op=true**tflite_convert** --graph_def_file=/content/mask-detection/tflite/tflite_graph.pb \
--output_file=/content/mask-detection/tflite/detect.tflite \
--output_format=TFLITE --input_shapes=1,300,300,3 \
--input_arrays=normalized_input_image_tensor \
--output_arrays ='TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3' \
--allow_custom_ops --mean_values=128 --std_dev_values=127 \
--change_concat_input_ranges=false --allow_custom_ops

TensorFlow Lite 文件可用于在移动、嵌入式和物联网设备上运行模型。它们支持低延迟和小二进制大小的设备上推断。

在我的下一篇关于在 Raspberry PI 4 上运行 TF Lite 的文章中,请遵循我的中等配置文件。这是这个项目的 Github

我的隔离区,包好了

原文:https://towardsdatascience.com/my-quarantine-wrapped-94e5015dc847?source=collection_archive---------13-----------------------

在新冠肺炎疫情隔离期间,我用 Spotify 的 Python 客户端 SpotiPy 分析了我的音乐收听模式

播放列表' Kartik 的热门歌曲 Kartik Dhawan 的 Quarantine '的专辑封面。

2020 年初,Spotify 推出了一项名为“wrapped”的功能,为用户提供对其收听历史的分析。作为一个数据和音乐的爱好者,我真的很喜欢在应用程序上了解我的活动!几个月后,冠状病毒疫情迫使世界大部分地区进入强制隔离状态,导致许多人在家工作,与社会隔绝。

在隔离期间,我花了很多时间听音乐,所以我决定在 Spotify 上分析我的收听历史,并创建一个' Wrapped '来找点乐子!本文涵盖了一些基本的数据工程、分析、可视化,最重要的是一组高质量的曲子。

数据收集

Spotify 为开发者提供了一个名为 SpotiPy 的 python 库。它提供了对 Spotify 庞大音乐数据库上的 API 的访问。除此之外,Spotify 允许用户下载他们拥有的关于您的数据,以遵守欧盟的一般数据保护条例(GDPR)政策。我按照的这些步骤去做。数据文件包括一个流部分,这是我在这个分析中使用的部分。

熊猫数据帧中加载的 JSON 流文件

隔离期间我在 Spotify 上花的时间比平时多吗?

我问自己被困在家里是否影响了我在 Spotify 上的时间。我的直觉是,我比平时流了更多的歌曲,因此在应用程序上花费了更多的时间,我想用一个简单的图表来证明这一点,该图表按周绘制了总的流时间(以毫秒为单位)。

出于分析的目的,我将把 2020 年 3 月 11 日作为我隔离的开始,因为这是我开始在家工作的日期。根据上面的图表,隔离开始后的一周(3 月 16 日至 22 日)是我在 Spotify 上播放时间最多的一周。除了被隔离的一周,其他时间都以高于平均水平的时间进行了播放!很明显,自从隔离开始后,我在 Spotify 上花的时间比平时多。

我从我的流历史中创建了两个数据帧,以根据开始日期(2020 年 3 月 11 日)之前/之后播放的歌曲来识别隔离区中的活动。我合计了隔离数据帧的 ms streamed 列,以获得在 Spotify 上流式播放音频所花费的总时间。

隔离期间,我在 Spotify 上总共花了 12222 分钟

我花时间听了什么?

我花了多少时间听播客和音乐

Spotify 提供的流媒体数据不包括该曲目是播客还是音乐的指标。我通常听的播客大约 20-60 分钟,平均每首歌大约 4 分钟。我找到了所有超过 12 分钟的歌曲的艺术家,并将他们标记为“播客”。

我的流媒体历史中的播客

我是经济播客的忠实粉丝,NPR 的《星球货币》是我最喜欢的一个!),我的一个朋友推荐《变革之风》作为一个很好的调查播客,它是关于中情局参与热门歌曲蝎子以及它如何潜在地导致冷战结束的。这是超级有趣的,看看吧!

按音频类型划分的 MsPlayed 切片

我在 spotify 上花了大约 20%的时间听播客

我发现了多少新的艺术家?

发现新音乐总是一个有趣又耗时的旅程。有了世界上所有的时间和 Spotify 上不同播放列表的访问权限,我开始了我的隔离音乐探索。

当我有一个播放列表在随机播放模式下运行,并且我不喜欢一首歌的前几秒钟,我通常会跳过它。为了避免计算跳过的歌曲,我添加了一个限制,即歌曲必须播放超过 10 秒。然后,我只是统计了隔离数据框中不存在于常规数据框中的艺术家数量。

我发现了 281 位艺术家6 个播客

我在播放列表中添加了多少首新曲目?

一个自然的过程是计算出我在我的播放列表中添加了多少首新歌。我在 Spotify 上有 5 个公共播放列表,用于不同的心情/场合。我使用 SpotiPy 的user _ playlistsAPI 来获取我所有的公共播放列表 ID,并将这些 ID 传递给 APIuser _ playlist _ tracks来获取这些播放列表中的所有歌曲,我将一些必要的属性存储在一个数据帧中。

播放列表的随机样本跟踪数据帧

最后,为了与流历史文件保持一致,我在 3 月 11 日之后和 5 月 15 日之前按添加的日期对这些数据进行了切片。

我添加了 89 首歌曲横跨 5 个播放列表

在隔离期间,我的流历史记录中有哪些常见主题?

我问自己,在封锁期间听的歌曲中是否有共同点。SpotiPy 有一个 API,允许用户从音轨返回音频特征。这些音频功能的例子有:

  1. 可跳性:0-1 之间的一个值,用于判断一个轨道的可跳性
  2. 能量:0-1 之间的一个值,用来衡量一个轨迹的强度和活跃程度
  3. 响度:整体响度,单位为分贝。值的范围从-60 到 0
  4. 语速:测量音轨中有多少是由口语组成的,范围为 0-1
  5. 声音度:测量音轨是否有声音,范围为 0-1
  6. 乐器性:预测音轨是否没有人声,范围为 0-1
  7. 效价:这描述了音轨在音乐上的积极程度。标度 0-1

关于这些属性的更多信息可以在 API 的官方文档中找到这里

该 API 需要一个 track_id 作为参数,所以第一步是为我的隔离流历史中的每个磁道返回一个磁道 id。我使用 SpotiPy search API,在一些正则表达式的帮助下,使用我的流数据中的 trackName 和 artistName 列构建一个查询,以返回我的数据帧中的 songId。

我使用上面代码返回的歌曲 ID 作为audio _ featuresAPI 中的参数,并将元数据保存为我的数据帧的一部分。

:什么样的剧情最适合把数据可视化在音乐上?

A :小提琴剧情..(咄!)

我在隔离期间的流动历史非常适合跳舞,充满活力,因为毕竟谁不需要一个理由来跳舞,而被困在家里?在我的流历史中,效价图显示的积极因素是均匀分布的。

上述大多数音频特征的头和尾都延伸到了极端,这表明我听的歌曲在乐器、现场或原声方面范围很广。然而,我的大部分流都在所有三个指标的底部。

隔离期间听了高度 可舞活力的歌曲

我最喜欢的流派是什么?

2019 年 Wrapped 的一个流行特征是“顶级流派”。我发现 SpotiPy 库将流派作为艺术家的一部分,而不是歌曲的一部分,它可以通过艺术家 API 获得。

一个艺术家可以有多种风格。这提出了一个数据工程的挑战,因为在我的基础数据框架中存储流派会引入重复,并且做额外的分析会变得复杂。因此,我决定将艺术家和流派保存在一个单独的数据框中,并将其加入到我的流历史框中,以通过简单的分组方式获得顶级流派。

我遍历我的流媒体历史中所有独特的艺术家,以构建 SpotiPy 搜索查询,然后遍历与艺术家相关的每个流派,并将流派和艺术家的名字添加到 pandas 数据框中。我将此数据框加入到我的艺术家姓名和流派分组的流历史中。结果在下图中!

说唱是我最喜欢的类型。我的前 10 个流派很好地混合了嘻哈子流派(德西、地下、南方)。除了 Hip Hop/Rap,我还听了一些流行音乐、陷阱音乐和独立灵魂音乐!

谁是我的顶级流媒体艺术家?

这是 Spotify 2019 wrapped 中的一个受欢迎的功能。我决定看看我最喜欢的 10 位艺术家。一群简单的熊猫就做到了!

当我在为 TDS 写我的上一篇文章时,我在 YouTube 上发现了的这首 集,我再次迷上了他的音乐。特拉维斯·斯科特是我最喜欢的艺术家已经有一段时间了。威肯推出了一张新专辑, 下班后 在隔离期开始的时候,来点复古的感觉吧!FKJ 是我在隔离期间发现的一位艺术家,他演奏多种乐器,是我听过的最有天赋的艺术家之一。看看他的专辑, 法国猕猴桃汁

我最喜欢的歌曲是什么?

综合起来,我想生成一个播放列表,其中包含我在隔离期间的所有热门歌曲,这样我就可以记住这段时间以及帮助我度过这一阶段的歌曲!

我创建了一个数据框,用熊猫分组,按播放次数降序排列,得到我的前 50 首歌曲。我使用了一个函数来获取这些曲目的歌曲 id。我使用user _ playlist _ createAPI 创建了一个播放列表,然后使用user _ playlist _ add _ tracks添加我的分组数据框对象中的所有歌曲。

我包装上的歌曲包括新专辑 drops ( 威肯)、历史上最受欢迎的(足以相信)、复古(加尔文·哈里斯)以及流行文化歌曲,如“sketcher”,这些歌曲在被推荐到 Tik Tok 和“Bella Ciao”后迅速走红,这是我在隔离期间碰巧狂看的热门网飞系列《金钱大劫案》的主题曲!

最后,我想对那些把新音乐介绍给我的人大喊一声,你们知道你们是谁!Spotify 是一个如此棒的应用程序;通过让音乐变得容易理解来帮助人们度过困难时期。享受听这些宝石!

这是我的 git 库的链接:

[## kartikd1/Spotify

通过在 GitHub 上创建帐户,为 kartikd1/Spotify 开发做出贡献。

github.com](https://github.com/kartikd1/Spotify)

Python 中的随机森林分类器

原文:https://towardsdatascience.com/my-random-forest-classifier-cheat-sheet-in-python-fedb84f8cf4f?source=collection_archive---------2-----------------------

一次处理分类变量和数值变量的端到端注释

Guillaume HenrotteUnsplash 上拍摄的照片

内容

  1. 数据预处理(自动处理分类特征和 NAs 的技巧)
  2. 训练射频分类器
  3. 评估分类器(准确度、召回率、精确度、ROC AUC、混淆矩阵、绘图)
  4. 特征重要性
  5. 通过随机搜索调整超参数

现在让我们开始吧,伙计们!

数据描述

在本文中,我使用的数据集来自我在一家科技公司为一个数据科学职位进行的真实技术测试。你可以在这里获得数据(点击下载 ZIP)。

声明:数据中描述的所有信息都不真实。

这里的exit_status是响应变量。注意,我们只给出了train.csvtest.csvtest.csv没有exit_status,即仅用于预测。因此,方法是我们需要将train.csv分成训练和验证集来训练模型。然后用模型预测test.csv中的exit_status

这是一个典型的数据科学技术测试,您有大约 30 分钟的时间来制作详细的 jupyter 笔记本和结果。

1.数据预处理

import pandas as pd
import numpy as np
import matplotlib.pyplot as pltdata = pd.read_csv('train.csv')

哎呀,我们看到了 NaN,让我们检查一下我们有多少 NaN

检查 NAs

data.isnull().sum()

由于总共有 2600 行,所以这里使用 NAs 的行数相对较少。但是,我在这里没有删除 NAs,因为如果test.csv数据集也有 NAs,那么删除训练数据中的 NAs 将无法使我们预测有 NAs 的客户的行为。但是,如果test.csv没有任何 NAs,那么我们可以继续并删除训练数据集中的 NAs。但是让我们先来看看test.csv

test = pd.read_csv('test.csv')
test.isnull().sum()

不出所料,test.csv中有 NAs。因此,我们将 NAs 视为一个类别,并假设它对响应变量exit_status有贡献。

exit_status 中的是-否替换为 1–0

exit_status_map = {'Yes': 1, 'No': 0}
data['exit_status'] = data['exit_status'].map(exit_status_map)

这一步在后面很有用,因为响应变量必须是一个数字数组才能输入到 RF 分类器中。正如我前面提到的,RF 模型不能读取字符串或任何非数字数据类型。

将数据分为 X 和 y

y = data.pop('exit_status')
X = data.drop('id',axis = 1)

id列不会给我们的工作增加任何意义,因为它不会影响客户是选择留下还是离开,所以我们应该删除它。

创建培训和验证集

seed = 50  # so that the result is reproducible
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.333, random_state = seed)

现在,是时候让 NA 成为一个类别了。在 Python 中,NaN被认为是 NAs。编码后,那些NaN将被忽略。因此,用na代替NaN是有用的,它现在是一个叫做‘na’的类别。稍后编码时会考虑到这一点。

X_train = X_train.fillna('na')
X_test = X_test.fillna('na')

创建分类变量列表进行编码

X_train.dtypes

请注意,只有分类变量具有 dtype = object

现在,让我们创建一个分类变量列表

features_to_encode = list(X_train.select_dtypes(include = ['object']).columns) # Or alternatively, features_to_encode = X_train.columns[X_train.dtypes==object].tolist() 

为我们创建一个处理分类特征的构造函数

这是我最喜欢的一步,因为通过重新创建这个新的构造函数,当传递到模型中时,我不需要对任何 X 数据帧进行任何转换。 这个构造函数会自动处理分类变量,而不会影响数值变量 。多方便啊!!!

from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import make_column_transformercol_trans = make_column_transformer(
                        (OneHotEncoder(),features_to_encode),
                        remainder = "passthrough"
                        )

remainder = 'passthrough'允许构造器忽略那些包含在features_to_encode中的变量。

现在我们的输入准备好了。让我们训练射频分类器。

2.训练射频分类器

让我们首先创建我们的第一个模型。当然可以从rf_classifier = RandomForestClassifier()开始。然而,大多数情况下,这个基本模型的性能不会很好(至少从我的经验来看,你的可能会有所不同)。所以我总是从下面的一组参数开始,作为我的第一个模型。

from sklearn.ensemble import RandomForestClassifierrf_classifier = RandomForestClassifier(
                      min_samples_leaf=50,
                      n_estimators=150,
                      bootstrap=True,
                      oob_score=True,
                      n_jobs=-1,
                      random_state=seed,
                      max_features='auto')

我建议总是从模型开始,因为最好使用袋外样本来估计泛化精度。oob 误差估计与通过 k 倍交叉验证获得的误差估计几乎相同。与许多其他非线性估计器不同,随机森林可以适合一个序列,并在此过程中进行交叉验证。

现在,让我们通过使用Pipeline来组合我们的分类器和我们之前创建的构造器

from sklearn.pipeline import make_pipeline
pipe = make_pipeline(col_trans, rf_classifier)
pipe.fit(X_train, y_train)

pipe是一个新的黑盒,由 2 个组件组成:1。一个构造函数来处理带有分类变量的输入,并转换成正确的类型。从构造函数接收这些新转换的输入的分类器。

y_pred = pipe.predict(X_test)

3.评估分类器

from sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score, roc_auc_score, roc_curve, f1_score

准确度= (TP + TN) / (TP+TN+FP+FN)

召回= TP / (TP + FN)

精度= TP / (TP + FP)

f1-得分= 2 精度召回/(精度+召回)

在本例中,1 为正,0 为负

我不会解释上面每个术语的意思,因为这篇文章并不是随机森林算法的详细文档。我想我们都知道这些术语的意思。当然,如果你不确定,可以在评论区问我。

准确度(正确分类样本的分数)

accuracy_score(y_test, y_pred)print(f"The accuracy of the model is {round(accuracy_score(y_test,y_pred),3)*100} %")**The accuracy of the model is 91.1%**

进行概率预测

train_probs = pipe.predict_proba(X_train)[:,1] 
probs = pipe.predict_proba(X_test)[:, 1]train_predictions = pipe.predict(X_train)

predict_proba(dataframe)[:,1]给出数据帧中类别标签 1 的预测概率分布。这对于计算 ROC_AUC 分数很重要。你可能会问为什么类的标签是 1 而不是 0。以下是我从 sklearn 文档中得到的内容:

对于y_score,‘二进制情况…分数必须是标签 大于的类的分数。这就是为什么我们需要得到标签 1 而不是标签 0。

*print(f'Train ROC AUC Score: {roc_auc_score(y_train, train_probs)}')print(f'Test ROC AUC  Score: {roc_auc_score(y_test, probs)}') **Train ROC AUC Score: 0.9678578659647703 
Test ROC AUC Score: 0.967591183178179***

现在,我们需要绘制 ROC 曲线

*def evaluate_model(y_pred, probs,train_predictions, train_probs): baseline = {} baseline['recall']=recall_score(y_test, [1 for _ in range(len(y_test))]) baseline['precision'] = precision_score(y_test, [1 for _ in range(len(y_test))]) baseline['roc'] = 0.5 results = {} results['recall'] = recall_score(y_test, y_pred) results['precision'] = precision_score(y_test, y_pred) results['roc'] = roc_auc_score(y_test, probs) train_results = {} train_results['recall'] = recall_score(y_train,       train_predictions) train_results['precision'] = precision_score(y_train, train_predictions) train_results['roc'] = roc_auc_score(y_train, train_probs) for metric in ['recall', 'precision', 'roc']:          print(f'{metric.capitalize()} 
                 Baseline: {round(baseline[metric], 2)} 
                 Test: {round(results[metric], 2)} 
                 Train: {round(train_results[metric], 2)}') **# Calculate false positive rates and true positive rates** base_fpr, base_tpr, _ = roc_curve(y_test, [1 for _ in range(len(y_test))]) model_fpr, model_tpr, _ = roc_curve(y_test, probs) plt.figure(figsize = (8, 6))
    plt.rcParams['font.size'] = 16 # Plot both curves plt.plot(base_fpr, base_tpr, 'b', label = 'baseline')
    plt.plot(model_fpr, model_tpr, 'r', label = 'model')
    plt.legend(); plt.xlabel('False Positive Rate');
    plt.ylabel('True Positive Rate'); plt.title('ROC Curves');
    plt.show();evaluate_model(y_pred,probs,train_predictions,train_probs) **Recall Baseline: 1.0 Test: 0.92 Train: 0.93 
Precision Baseline: 0.48 Test: 0.9 Train: 0.91 
Roc Baseline: 0.5 Test: 0.97 Train: 0.97***

结果看起来不错。测试和训练结果之间的差异非常小,表明我们的模型没有过度拟合数据。

混乱矩阵

人们可以简单地输入confusion_matrix(y_test, y_pred)来得到混淆矩阵。然而,让我们采取更高级的方法。在这里,我创建一个函数来绘制混淆矩阵,这个函数打印并绘制混淆矩阵。(改编自代码来源)

*import itertoolsdef plot_confusion_matrix(cm, classes, normalize = False,
                          title='Confusion matrix',
                          cmap=plt.cm.Greens): # can change color     plt.figure(figsize = (10, 10))
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title, size = 24)
    plt.colorbar(aspect=4) tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45, size = 14)
    plt.yticks(tick_marks, classes, size = 14) fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2. # Label the plot for i, j in itertools.product(range(cm.shape[0]),   range(cm.shape[1])): plt.text(j, i, format(cm[i, j], fmt), 
             fontsize = 20,
             horizontalalignment="center",
             color="white" if cm[i, j] > thresh else "black") plt.grid(None)
    plt.tight_layout()
    plt.ylabel('True label', size = 18)
    plt.xlabel('Predicted label', size = 18) # Let's plot it outcm = confusion_matrix(y_test, y_pred)
plot_confusion_matrix(cm, classes = ['0 - Stay', '1 - Exit'],
                      title = 'Exit_status Confusion Matrix')*

4.特征重要性

首先,让我们检查模型中有多少个特征重要性值

*print(rf_classifier.feature_importances_)print(f" There are {len(rf_classifier.feature_importances_)} features in total")**[7.41626071e-04 6.12165359e-04 1.42322746e-03 6.93254520e-03  2.93650843e-04 1.96706074e-04 1.85830433e-03 2.67517842e-03  1.02110066e-05 2.99006245e-05 6.15325794e-03 1.66647237e-02  4.49100748e-03 3.37963818e-05 1.87449830e-03 1.00225588e-03  3.72119245e-04 1.39558189e-02 8.28073088e-04 3.41692010e-04  1.71733193e-04 7.60943914e-02 1.09485070e-02 1.78380970e-02  1.63392715e-02 2.93397339e-03 1.46445733e-02 1.34849432e-01  1.33144331e-02 4.42753783e-02 3.13204793e-03 4.97894324e-03  6.17692498e-03 2.70959923e-02 1.61849449e-03 7.57024010e-02  2.31468190e-02 4.66247828e-01]** **There are 38 features in total***

总共有 38 个特征。但是,X_train 只有 15 列。这是因为模型pipe自动对 X_train 中的分类变量进行编码。例如,X_train 中的gender列被转换为 2 列FemaleMale

因此,为了将特性与从rf_classifier获得的特性重要性值相匹配,我们需要在编码的 X_train 中获得所有那些对应的列。

问题:

我们只有一个特征重要性数组,但是有分类和数字特征,我们如何知道哪个值属于哪个特征?

还记得我们之前创建的构造函数col_trans吗?col_trans.fit_transform(X_train)将给出编码的 X_train。

*# Let's look at the first row
print(col_trans.fit_transform(X_train)[0,:])**[ 0\.    1\.    0\.    0\.    0\.    1\.    1\.    0\.    0\.    1\.    1\.    0\.   0\.    0\.    1\.    0\.    0\.    0\.    1\.    0\.    0\.    1\.    0\.    0\.   1\.    0\.    0\.    1\.    0\.    0\.    0\.    1\.    0\.    1\.    0\.   30\.  74.75 14\.  ]**# And the first row of X_train
X_train.iloc[0,:] **gender                             Male
age                                 >60
dependents                           No
lifetime                             30
phone_services                      Yes
internet_services                    3G
online_streaming             Major User
multiple_connections                 No
premium_plan                         No
online_protect                       No
contract_plan            Month-to-month
ebill_services                      Yes
default_payment         Online Transfer
monthly_charges                   74.75
issues                               14
Name: 1258, dtype: object***

对于 X_train,有 3 个数值变量,值分别为 30、70.75 和 14。对于编码的 X_train,这 3 个数值放在所有分类变量之后。这意味着对于rf_classifier.feature_importances_ ,首先显示所有编码的分类变量,随后是数值变量

好了,现在我们知道了,让我们创建一个合适的编码 X_train。

*def encode_and_bind(original_dataframe, features_to_encode): dummies = pd.get_dummies(original_dataframe[features_to_encode])
    res = pd.concat([dummies, original_dataframe], axis=1)
    res = res.drop(features_to_encode, axis=1)
    return(res)X_train_encoded = encode_and_bind(X_train, features_to_encode)*

函数encode_and_bind对分类变量进行编码,然后将它们与原始数据帧相结合。

x _ 火车 _ 编码

酷,现在我们有 38 列,这和之前在rf_classifier.feature_importances_中显示的 38 个特性完全一样。

*feature_importances = list(zip(X_train_encoded, rf_classifier.feature_importances_))**# Then sort the feature importances by most important first**
feature_importances_ranked = sorted(feature_importances, key = lambda x: x[1], reverse = True)**# Print out the feature and importances** [print('Feature: {:35} Importance: {}'.format(*pair)) for pair in feature_importances_ranked];*

一些特征及其重要性分数(降序)

***# Plot the top 25 feature importance**feature_names_25 = [i[0] for i in feature_importances_ranked[:25]]
y_ticks = np.arange(0, len(feature_names_25))
x_axis = [i[1] for i in feature_importances_ranked[:25]]plt.figure(figsize = (10, 14))
plt.barh(feature_names_25, x_axis)   #horizontal barplot
plt.title('Random Forest Feature Importance (Top 25)',
          fontdict= {'fontname':'Comic Sans MS','fontsize' : 20})plt.xlabel('Features',fontdict= {'fontsize' : 16})
plt.show()*

5.使用 RandomSearchCV 调整超参数

由于模型性能非常好,具有很高的准确度、精确度和召回率,因此实际上几乎不需要对模型进行调优。但是,如果我们的第一个模型表现不佳,可以采取以下步骤来调整模型。

让我们看看目前使用的参数

*from pprint import pprintprint('Parameters currently in use:\n')
pprint(rf_classifier.get_params())*

现在,我为模型创建了一个参数网格,以便随机挑选和训练,因此命名为随机搜索。

***from sklearn.model_selection import RandomizedSearchCV**n_estimators = [int(x) for x in np.linspace(start = 100, stop = 700, num = 50)]max_features = ['auto', 'log2']  # Number of features to consider at every splitmax_depth = [int(x) for x in np.linspace(10, 110, num = 11)]   # Maximum number of levels in treemax_depth.append(None)min_samples_split = [2, 5, 10]  # Minimum number of samples required to split a nodemin_samples_leaf = [1, 4, 10]    # Minimum number of samples required at each leaf nodebootstrap = [True, False]       # Method of selecting samples for training each tree random_grid = {'n_estimators': n_estimators, 'max_features': max_features, 'max_depth': max_depth, 'min_samples_split': min_samples_split, 'min_samples_leaf': min_samples_leaf, 'max_leaf_nodes': [None] + list(np.linspace(10, 50, 500).astype(int)), 'bootstrap': bootstrap}*

现在,我首先创建一个基础模型,然后使用随机网格根据 ROC_AUC 得分选择最佳模型,因此有了scoring = 'roc_auc'

***# Create base model to tune**rf = RandomForestClassifier(oob_score=True)**# Create random search model and fit the data**rf_random = RandomizedSearchCV( estimator = rf, param_distributions = random_grid, n_iter = 100, cv = 3, verbose=2, random_state=seed,                        scoring='roc_auc')rf_random.fit(X_train_encoded, y_train)rf_random.best_params_rf_random.best_params_**{'n_estimators': 206,
 'min_samples_split': 5,
 'min_samples_leaf': 10,
 'max_leaf_nodes': 44,
 'max_features': 'auto',
 'max_depth': 90,
 'bootstrap': True}***

我们将用三重交叉验证进行 100 次迭代。关于参数的更多信息可以在这里找到。

或者,我们可以再次使用pipe,这样我们就不需要编码数据了

*rf = RandomForestClassifier(oob_score=True, n_jobs=-1)rf_random = RandomizedSearchCV( estimator = rf, param_distributions = random_grid, n_iter = 50, cv = 3, verbose=1, random_state=seed, scoring='roc_auc')pipe_random = make_pipeline(col_trans, rf_random)pipe_random.fit(X_train, y_train)rf_random.best_params_*

请注意,这两种方法给出的答案可能略有不同。这是由于选择参数的随机性。

***# To look at nodes and depths of trees use on average**n_nodes = []max_depths = []for ind_tree in best_model.estimators_: n_nodes.append(ind_tree.tree_.node_count) max_depths.append(ind_tree.tree_.max_depth)print(f'Average number of nodes {int(np.mean(n_nodes))}')   print(f'Average maximum depth {int(np.mean(max_depths))}') **Average number of nodes 82 
Average maximum depth 9***

评估最佳车型

***# Use the best model after tuning**best_model = rf_random.best_estimator_pipe_best_model = make_pipeline(col_trans, best_model)pipe_best_model.fit(X_train, y_train)y_pred_best_model = pipe_best_model.predict(X_test)*

第 3 节中使用的相同代码可以再次应用于 ROC 和混淆矩阵。

*train_rf_predictions = pipe_best_model.predict(X_train)train_rf_probs = pipe_best_model.predict_proba(X_train)[:, 1]rf_probs = pipe_best_model.predict_proba(X_test)[:, 1]**# Plot ROC curve and check scores**evaluate_model(y_pred_best_model, rf_probs, train_rf_predictions, train_rf_probs)**Recall Baseline: 1.0 Test: 0.94 Train: 0.95 
Precision Baseline: 0.48 Test: 0.9 Train: 0.91 
Roc Baseline: 0.5 Test: 0.97 Train: 0.98***

这组参数使模型的性能比我们的原始模型稍好一些。差别并不大。这是可以理解的,因为我们的原始模型已经表现得很好,得分更高(准确度、精确度、召回率)。因此,调整一些超参数可能不会给模型带来任何显著的改进。

***# Plot Confusion matrix**plot_confusion_matrix(confusion_matrix(y_test, y_pred_best_model), classes = ['0 - Stay', '1 - Exit'],title = 'Exit_status Confusion Matrix')*

test.csv数据使用最佳模型

现在我们有了最好的模型,让我们用它来进行预测,并编译我们的最终答案来提交。

*test = pd.read_csv('test.csv')
test_withoutID = test.copy().drop('id', axis = 1)
test_withoutID = test_withoutID.fillna('na')final_y = pipe_best_model.predict(test_withoutID)
#pipe model only takes in dataframe without ID column. final_report = test
final_report['exit_status'] = final_y
final_report = final_report.loc[:,['id','exit_status']]# Replace 1-0 with Yes-No to make it interpretablefinal_report= final_report.replace(1, 'Yes')
final_report= final_report.replace(0, 'No')*

我们都看到了No。让我们检查以确保该列中也有Yes

*final_report.exit_status.value_counts()**No     701
Yes    638
Name: exit_status, dtype: int64***

好了,我们安全了~

保存并提交文件

*final_report.to_csv('submissions.csv', index=False)*

结论

我希望这也能成为你们有用的参考指南。您可以使用本指南来准备一些技术测试,或者将它作为一个备忘单来复习如何用 Python 实现随机森林分类器。我一定会继续更新,因为我发现了更多有用的函数或技巧,我认为它们可以帮助每个人快速解决许多数据科学问题,而不需要在 StackOverflow 这样的平台上查找,特别是在时间有限的技术测试中。

如果还有其他你认为重要的技巧或功能,请在下面的评论区告诉我。此外,我欢迎任何人的建设性反馈。

谢谢你的阅读。祝您愉快,编程愉快!

我的深度学习阅读清单

原文:https://towardsdatascience.com/my-reading-list-for-deep-learning-686e1c80359d?source=collection_archive---------45-----------------------

为那些希望开始深度学习的人和那些希望填补他们知识空白的人推荐的文献。

真诚媒体Unsplash 上拍摄的照片

这是我推荐的关于深度学习各个方面的资源的精选列表,虽然基于我自己的个人经验,但很大程度上受到了这个 Github 库的启发。我打算随着新论文的出现,或者如果我设法发现一些真正对我有影响的论文,几乎定期地更新这个列表。

这个阅读清单相对来说比较长,我并不宣称已经阅读了每一页上的每一个单词。然而,我坚信发展良好的基础:鉴于深度学习的当前状态有多广阔,如果你从零开始,你必须赶上很多。我的建议是大步前进,在你需要的时候学习你需要的东西;这是必然的,但不是不可克服的

建立良好的基础

不管你喜不喜欢,深度学习无论是线性代数还是统计,都需要大量的背景知识;你需要一个坚实的基础才能建造一座大厦。前者是理解每一个模型背后的核心机制的一个必要条件,而发展一个良好的线性代数直觉可以让你洞察到一些模型所涉及的一些技巧(例如,内积解码器,inception 架构)。对于一些较简单的任务,例如分类,需要对后者有基本的了解。当我们讨论更复杂的问题时,贝叶斯统计的背景非常有帮助:这些想法构成了概率建模的主干,用于生成模型——基于所学知识创建新数据的模型。

对于线性代数,我其实并不推荐一本数学教材。而是推荐 数学对于量子化学;不要让标题把你搞糊涂了,因为这本已经很短的书的前几章给了你一个快速入门和线性代数性质的很好的参考。量子化学实际上使用了许多与深度学习相同的机制(有许多矩阵乘法和因式分解),所有这些都是为了解决薛定谔方程的近似问题。您将学习如何将概念表达为基函数、投影和求解线性方程。这本书是由多佛出版社出版的,所以买起来非常便宜,而且随身携带也很好!

对于统计学,我一般会避免典型的侧重于假设检验(即p-值)的大学教科书,这在心理学和生物学中可能会很常见。这些想法背后的前提是“频繁主义者”,依我拙见,你最好像贝叶斯统计学家那样思考(尽管不要太害怕被不确定性麻痹)。出于这个原因,我推荐盖尔曼、卡林、斯特恩和鲁宾的 贝叶斯数据分析 ,还有一本更实用的书,麦克雷瑟的 统计再思考:一门贝叶斯课程,示例见 R 和斯坦 。前者特别让你根据可能性来构建任何问题,并提供案例研究来理解贝叶斯统计如何帮助我们解决现实生活中的问题并理解不确定性的作用。

建造房子的框架

有两个具体的资源我会推荐,它们会让你做好准备: 深度学习 由该领域的三位巨头:伊恩·古德菲勒、约舒阿·本吉奥和亚伦·库维尔,以及吴恩达的关于 deeplearning.ai 的课程。前者提供了深度学习基础的极其坚实的基础和理论支撑,而吴恩达的课程更加务实,教你如何从头开始实现这些模型。配合吴恩达课程的好书是弗朗索瓦·乔莱的《用 Python 进行深度学习的》。在这两种情况下,都非常关注 Tensorflow 和 Keras(原因很明显),尽管从深度学习中学习应该为您提供足够的抽象来实现许多基础知识。

本质上,这三种材料的组合足以让你开始摆弄深度学习模型。当然,这确实说起来容易做起来难,因为有大量的阅读,但是你未来的自己会感谢你的!

在这一点上,许多深度学习的最新概念来自学术论文:与许多其他领域不同,几乎所有的材料都是免费的。我们很幸运,机器学习和深度学习研究人员倾向于将大量论文上传到 arXiv 上,这对于其他学科(例如化学、物理等)来说并不真实。).我建议找一些你有兴趣解决的事情,并开始阅读提供这些问题解决方案的论文。例如,如果你正在处理图像,看看卷积模型:AlexNet,LeNet,Inception,举几个例子(按这个顺序)。如果你处理数字/序列数据,看看递归神经网络。这个 Github 库提供了直到几年前的论文集锦,涵盖了许多当前最先进的更具开创性的论文。如果我没有提到其中的一篇论文,它可能会在那个库中。

在接下来的几节中,我将讨论更多具体的应用,这些应用并不总是被系统地报道或者进入主流媒体,但是(我认为)非常酷。这是我对一些文件的一站式商店的想法,它将让你开始一段漫长的旅程。

额外材料: 这篇 arXiv 论文提供了深度学习相当全面的历史概述,可以追溯到 20 世纪初的思想。

特定主题

学习动力和能力

有一件事,我还没有找到很多关于神经网络容量的帖子或文章:这不是一个简单的问题,在这个问题上,文献实际上是非常多样的。虽然大多数人可能会认为这“太理论化”,但通过理解神经网络如何保留 T2 的信息,还是有重要的意义。我发现这个领域非常有趣,因为它无疑为优化问题增加了一个“有机”的成分。

图改编自估算神经网络中的信息流

自动编码器

自动编码器是一类整洁的模型,试图学习以无监督的方式提取有用的特征。基本要点是编码器模型产生嵌入,解码器模型可以使用该嵌入来再现输入,并且通过这样做,学习将输入的重要部分压缩成小的特征向量。这篇博客文章全面概述了各种自动编码器。

图改编自自动编码变分贝叶斯

虽然变分自动编码器很酷,但它们通常受到一个事实的限制,即在许多(可能是大多数)情况下,对角高斯不能很好地逼近真实的后验概率。规范化流是一种通过一系列可逆转换将简单、易于计算的分布转换为更具表达性的分布的方法。

根据标准化流的变分推断改编的图形

概率模型

**贝叶斯数据分析这本书应该为本节提供一个良好的基础:尽管这一节的标题,重点更多的是捕捉模型的不确定性, à la 贝叶斯统计。不确定性量化是理性决策的一个重要组成部分,为政策制定、自动驾驶汽车等等“让人工智能值得信赖”的总体主题增添了新的内容。这一部分并不全面,我打算进一步扩展。

改编自改进机器学习模型中的非分布检测

强化学习

深度学习的热门话题,让神经网络通过试错来自学如何解决问题。这个部分对我来说有点稀疏,但是我很快会填充它。

图改编自通过逆向强化学习的学徒学习

图形模型

图论是对各种问题建模的一种方式:例如,社会网络、电路和结构化数据,当然还有神经网络。概率图也越来越受欢迎,因为它们可以很容易地理解因果关系。最近,深度学习中的许多主流思想,如卷积和生成模型,在图形神经网络文献中找到了类似的推导。

图改编自变分图自动编码器

结论

目前,这些是我进行深度学习的资源。我会试着定期更新这篇文章,但是你也应该做你自己的发现!最简单的方法之一就是浏览 ArXiv,找到你感兴趣的论文。考虑到它的广阔性,以及每周都有数十到数百个新发现被报道的事实,我的建议还是要深入细节,因为你需要解决不同的问题。你不可能掌握所有的事情,为了你自己的理智和精神健康,你应该按照自己的速度处理这些文件和新文件!

如果您有任何问题,或者如果您认为我遗漏了什么,我应该将它添加到列表中,请随时联系我!另外,请让我知道这是否对你有所帮助!

我对数据科学项目的思考——哪些可行,哪些不可行

原文:https://towardsdatascience.com/my-reflection-on-data-science-projects-what-worked-and-what-didnt-4c0af29aef95?source=collection_archive---------40-----------------------

吸取教训,这样你就可以避免同样的错误,更明智地投资你的时间。

Unsplash 上由 Brad Neathery 拍摄的照片

在过去的 5 年里,我一直在数据科学领域工作,为公司供应链领域的用户提供服务。我开发了各种仪表板和一些小型数据应用程序。部署的大多数解决方案仍在积极使用,而少数项目在开始时看起来很花哨,很有前途,但却未能扎根。

我思考了项目的本质,在这篇文章中,我想分享为什么我的一些项目成功了,而一些项目失败了的艰难原因。

让我先说说哪些方法行之有效。

  1. 观察一个业务痛点,然后填补空白 在供应链业务中,一个主要挑战是运营经理需要实时数据来指导他们的运营,几个小时的老化数据被视为无用。每天,分析师都会提取和编辑各种数据,以创建支持业务决策的指标。这些任务是重复的、手动的和不可持续的。我知道我们需要一种不同的方法来解决这个问题。经过一番研究,我开发并部署了一个集成的仪表板,它可以获取实时数据,并具有更丰富的洞察力。此外,仪表板是可重用的。这满足了每天需要快速实时指标的用户的渴望。
  2. 与流程负责人合作,实现基本任务的自动化 有许多成熟的业务流程,但缺乏创造性的执行方式。财务人员花费数天时间准备半年度预算;工程师每周花几个小时提取各种数据表,以估计仓库中的存储消耗。这些是保持业务运行的基本任务和必须做的活动的例子。工作人员可能不知道有更好的方法来执行任务。有几次,我与用户合作来自动化和简化这个过程。这改变了他们执行任务的方式。合作的结果令人满意,自动化帮助他们提高了工作效率。
  3. 将分散的数据组织成一个精简的数据库
    有几次,我观察到我的同事在他们的电脑上创建了非常有用的数据表,用于特定的分析。在本地维护数据表没有错,我对数据集的潜力感到兴奋。我把数据集从电子表格转换成主流数据库。结果呢?更多的人利用数据集,更多的成功用例被创建。我已经将孤岛和独立形式的数据释放到一个简化的集成数据库中。我的观点是始终关注好的数据,将其转换为更系统、更可扩展的格式。这必然会将范围扩大到更广泛的受众,并且您已经走上了创建更强大的应用程序的正确道路。

另一方面,我并不总是那么幸运。我有几个没有小费的项目。归结起来有以下两个主要原因。

  1. 花哨的概念,但没有真正的商业案例 有几个项目,我想象它会很酷,没有太多的研究,我开始开发应用程序。在其中一个项目中,我花了三个月的时间开发一个供应链可视化工具。虽然这是真的,我设法让利益相关者惊叹,但从那以后我没有收到他们的回复。也有一些时候,一个商业伙伴向我提出了一个非常酷的概念,我花了几个星期开发原型。我们没能实现原型。事后看来,我已经痛苦地认识到,一个没有坚实的研究基础,主要基于想象的概念往往会失败。有时候,练好策略拖延症,多花点时间听听用户,了解他们的油漆点再急着做开发工作,不失为一个好策略。
  2. 过度工程化一个解决方案 我刚才说的是要永远听用户的,对吧?不是所有的时间。用户可能会想象一个很酷但不实用的功能。注意这种问。有一个项目,经过 3 天的改善讨论,我得到了一个很长的改进列表,我花了 3 个月来构建所有的功能。输出是一个由 14 个模块组成的集成仪表板,但很快我意识到在这 14 个模块中,用户只主动使用了其中的 5 个!我终于明白,虽然总是倾听用户是对的,但用户可能是错的!他们可能和你一样有“想象”综合症。不要太慷慨地接受一大堆请求,相反,要质疑他们提出的每一个功能。

最终想法: 要创建一个成功的数据科学项目,我经常发现最具挑战性的部分不是在开发阶段,而是在我们是否能够将工作付诸实施,以便目标受众开始采用解决方案。以下是我积累的重要经验。

  1. 识别业务痛点,然后填补空白
    有时,用户不知道有更好的出路。多和他们聊聊,多去竞技场,把手弄脏。
  2. 利用现有的繁琐业务任务
    与所有者合作改进流程。让所有者对解决方案负责,在幕后支持他们。
  3. 跟随数据
    将分散的数据组织到一个更精简的平台通常是一种快速的胜利。数据越丰富,数据越完整越好。
  4. 不要幻想解决方案
    了解用户面临的真正问题。不要因为看起来很酷就急于发展。
  5. 不要太慷慨地接受所有的请求
    探查每一个改进,深入了解需求的根源,关注少数需求。

感谢你的阅读,我希望你会发现这些课程是有用的,并能够帮助你在未来更明智地投资你的时间。

我参加 TensorFlow 开发者认证考试的故事

原文:https://towardsdatascience.com/my-story-of-taking-the-tensorflow-developer-certification-exam-85d4fb777cbb?source=collection_archive---------8-----------------------

我参加考试的总体经历,我是如何准备的,如果我不得不再次参加考试,我会做些什么。

克林特·帕特森在 Unsplash 上拍摄的照片

老实说,我不知道 TensorFlow 提供认证考试,直到我看到有人在 Twitter 上发布了关于它的推文。我做了一些研究,以了解更多关于考试的信息,我对自己说:这将是我探索机器学习世界之旅的下一个目标。

在这篇文章里,我想谈谈我参加 TensorFlow 开发者认证考试的亲身经历,以及我是如何备考的。希望这篇文章对近期有兴趣参加考试的各位有所帮助。

现在,在我讲述我的经历之前,有必要先谈谈 TensorFlow 开发人员认证考试到底是什么。

什么是 TensorFlow 开发者认证?

你可能已经知道,谷歌在 2015 年发布了一个名为 TensorFlow 的机器学习应用开源软件库。TensorFlow 是目前最受欢迎的深度学习库之一,它使您能够轻松地大规模构建和部署不同类型的深度学习模型。

TensorFlow 开发人员认证考试允许您展示您使用 TensorFlow 构建各种模型来解决不同类型的机器学习问题的实际技能。如果你看一下这个认证考试的考生手册,你很快就会知道,你将被要求解决与结构化数据或图像和文本等非结构化数据相关的问题。

由于这是一个使用 TensorFlow 的实践考试,因此它假设您已经知道浅层神经网络、深层神经网络、卷积神经网络和序列模型背后的一般概念。在考试期间,你应该用 TensorFlow 实现这些机器学习概念。

考试本身的费用是每次 100 美元,这意味着如果你没有通过考试,你需要为每次考试再次支付考试费。如果第一次考试失败,你可以在第一次考试 14 天后重考。如果你第二次尝试失败了,你需要等两个月才被允许做第三次尝试。

您将有 5 个小时的时间来解决 PyCharm 环境中的不同问题,在您结束考试后,您将通过电子邮件直接收到通知,无论您是否通过考试。如果你通过了考试,你的证书会在几天后发给你,三年后到期。

我为什么要参加认证

作为一个希望不断发展技能来解决不同类型的机器学习问题的人,毫无疑问 TensorFlow 是我经常使用的基本工具之一。

以参加 TensorFlow 开发者考试为主要目标的想法确实激励我不断发展如何利用 TensorFlow 解决机器学习问题的技能。此外,知道考试时会有时间限制,真的会让考试更有挑战性。我越是知道我的目标将会有多么具有挑战性,我就会越努力地为它做准备。

另一个优势是,如果你试图进入人工智能行业,拥有 TensorFlow 认证肯定会给你一个额外的证书,尽管我不能保证仅凭证书就足以让你进入人工智能。你可以在你的简历、LinkedIn 或 GitHub 中分享你的证书。

对考试有帮助的学习材料

现在您已经知道 TensorFlow 开发人员认证考试是什么,并且您可能想在不久的将来参加它。接下来,你可能想知道哪些学习材料会对你准备考试有所帮助。

嗯,这取决于你目前所知道的…

如果你已经知道了深度学习的大致概念,那么 Coursera 上的tensor flow in Practice Specialization就是你准备考试的最好方式。

如果你看一下考生手册中的技能清单,你会找到成功通过认证考试所需的相关技能。一开始看到技能清单可能会感到害怕,但是所有这些技能都包含在 TensorFlow 的实践专业化中。

参加 TensorFlow 实践专业化课程每月需要花费 49 美元,但实际上你可以免费旁听课程,你可以在 Google Colab 上获得学习材料和实用代码。在学习本课程时,尝试自己从头开始重新创建代码以最大化您的学习体验也很重要。

然而,如果你还不熟悉深度学习的一般概念,那么我推荐以下材料,让你在参加 TensorFlow 实践专业化之前快速掌握:

  1. 吴恩达深度学习专业化
  2. 用 Scikit-Learn、Keras 和 TensorFlow 进行机器学习,作者是 Aurlien GRon。
  3. CS231n:斯坦福大学用于视觉识别的卷积神经网络
  4. CS224n:斯坦福大学深度学习的自然语言处理
  5. Franois Chollet 的《深度学习 Python》,整本书你都可以在线免费阅读。
  6. 麻省理工 6。S191 深度学习介绍

这些是我的首选资源,我发现从不同的资源和角度学习深度学习概念是有益的,因为它有助于巩固我的知识。

我发现在考试前你需要学习的另一件非常重要的事情是 TensorFlow 数据集。了解如何使用 tf.datasets 加载数据,更重要的是,了解如何对 tf.datasets 中的数据进行预处理,以便将它们输入到模型中。您可以在 TensorFlow 文档页面中了解更多信息。

我是如何准备考试的

我总共花了大约三周时间准备考试。

在前两周,我从 TensorFlow 的实践专门化中学习了所有材料,并从头开始重新创建了代码。

接下来,因为我们需要在 PyCharm 环境中进行考试,而我以前从未使用过 PyCharm,所以在考试前一周,我花时间学习了更多关于 PyCharm 的知识。我认为,如果您以前使用过 Spyder 等其他 Python IDE,那么熟悉 PyCharm 不会花费您太多时间。

TensorFlow 开发者认证文档中解释了安装考试所需 PyCharm 和插件的所有详细步骤。现在如果你想了解更多关于 PyCharm 的功能,那么我推荐以下材料:

  1. JetBrains 的 PyCharm 视频系列入门
  2. JetBrains 的 PyCharm 文档入门

在我熟悉了 PyCharm 并检查了所有必要的插件都可以正确安装之后,我在 PyCharm 环境中的 Practice Specialization 中重新创建了 TensorFlow 的代码,以确保运行代码时没有错误。

我参加考试的亲身经历

终于,考试日到了,2020 年 7 月 9 日…

要参加认证考试,您需要做的就是前往 TensorFlow 开发者认证网站的,并点击“开始考试”按钮。在那里,您需要提供您的 ID 和支付信息,以及设置您的考试环境。

一旦您完成付款,设置考试环境的所有步骤都将在一份机密的 PDF 文档中详细解释,因此您无需担心。

设置好所有的考试环境后,您可以选择点击“开始考试”按钮开始考试。一旦你点击那个按钮,5 个小时的计时器将立即启动,你需要在这段时间内完成不同的任务。

访问 GPU 是完成考试的必要条件吗?

现在你可能会问:你需要访问 GPU 才能完成考试吗?我的回答是:不一定。

我个人只在我的华硕笔记本电脑的 CPU 上训练了所有的模型,所以没有什么复杂的。直到现在我都不知道为什么我在考试的时候没有使用我在 Colab 上的免费 GPU 访问权限,我在考完试后才意识到这一点。但我想我们都经历过。

但这证明了一件事:你虽然没有 GPU,但也可以完成并通过考试。然而,如果你计划在你机器的 CPU 上训练你所有的模型,不要重复我的错误,我会告诉你我的错误是什么。

正如你从候选人手册中已经知道的,你需要在 5 个小时内解决不同的问题,每个问题都会比前一个问题更复杂。

我的错误是我按顺序解决问题,这意味着我先解决最简单的问题,然后再去解决更复杂的问题。这种方法没有错,但当我试图解决更复杂的问题时,我没有太多的时间来训练模型,尽管该模型在计算上比前一个问题更需要训练。

我已经用大约一个半小时完成了所有问题的编码部分,但是还有两个不同的计算密集型模型仍在同时训练。从那以后,基本上就是我的笔记本电脑 CPU 的处理能力和时间之间的竞赛了。

我,在只剩 30 分钟,模特还在训练的时候(来源: GIPHY )

幸运的是,所有的训练都在时间结束前完成了,它们在验证集中表现得非常好,所以一切都很好。

现在我要谈下一点..

如果我再参加一次考试,我会有什么不同的表现

如果我想完全用笔记本电脑的 CPU 来解决整个考试,那么我想先解决比较复杂的问题,然后再解决不太复杂的问题。

在不给出太多问题细节的情况下,包含卷积层以及 LSTM 或 GRU 层的模型当然会比另一个在计算上要求更高。如果你先解决更复杂的问题,那么你就有更多的时间来训练模型。如果复杂的模型没有你预期的那么好,你仍然有时间调整它并重新训练它。模型一训练好,就开始解决更简单的问题。

为了避免 CPU 和考试时间之间的竞争,我还想利用 Colab 免费访问 GPU。你可以用 Colab 解决问题,在那里用 GPU 训练模型,把训练好的模型复制到考试的目录下。任何可以访问 Google Drive 的人都可以免费使用 Colab,如果你想了解更多关于如何设置和使用 Colab 的细节,我推荐你阅读这篇文章

你怎么知道你通过了考试?

考试结束后不久,您会收到一封电子邮件反馈,告知您是否通过了考试。

然而,你应该已经知道在考试期间你是否会通过。一旦你把每个问题的训练好的模型提交给评分员,你会马上得到反馈。

外卖食品

现在,您已经了解了 TensorFlow 开发者认证考试的所有必要内容,以下是一些要点:

  • 如果你已经了解了深度学习的大致概念,那么 Coursera 上的《实践专精》中的 TensorFlow 就是最好的备考学习资料。
  • 如果你还不熟悉深度学习的一般概念,那么我上面列出的学习材料将有助于你在参加 TensorFlow 实践专业化之前达到速度。
  • 了解 TensorFlow 数据集以及如何对其进行预处理。
  • 花点时间熟悉 PyCharm 环境,并尝试在 it 专业实践中重新创建 TensorFlow 的项目,以确保一切都完美运行。
  • 如果你计划完全在你机器的 CPU 上完成考试,确保你合理地管理你的时间,先解决复杂的问题,再解决简单的问题。
  • 您可以使用 Colab 上的免费 GPU 访问来优化考试期间的工作流程。

而这就是我参加 TensorFlow 开发者认证考试的亲身经历,以及我是如何通过的。我希望这有利于你们中任何一个想在不久的将来参加考试的人。如果你有问题,我很乐意帮助你。

我的 Tableau 仪表盘糟透了——直到我开始先画它们

原文:https://towardsdatascience.com/my-tableau-dashboards-sucked-until-i-started-drawing-them-ec4c9d4a4fe8?source=collection_archive---------19-----------------------

为什么手绘仪表板可以培养更强的数据可视化技能,并更好地理解图形概念

一个简单的手绘仪表板的例子

我们都有过这样的经历——你正在浏览网页,突然发现一个你根本无法解读的表格或图表。在对它进行短暂的内部判断后,你继续你的一天,甚至忘记了它不久后就存在了。是因为图形实现不当而难以理解吗?有大量的信息吗?也许创作者根本没有做好用手头的数据讲一个故事?如果你不想开发易被遗忘的仪表板,先尝试手绘。

这个故事主要是针对最近的毕业生和那些开始发展这方面技能的人,但我希望任何人都能从中收集一些有用的见解。

该设置

众所周知,数据可视化是一项越来越受欢迎、需求越来越大的技能。在 LinkedIn 上简单搜索“数据可视化”会返回大量结果,通常来自那些希望创建引人注目的仪表板以向利益相关者、董事和客户展示的雇主。

没有比这更好的时间来提高你在这方面的能力了。可悲的是,能够创建准确和引人注目的仪表板是我见过的困扰无数学生和专业人士的事情。很多时候,人们似乎对寻找展示信息的最佳方式并不感兴趣,他们只是在寻找展示信息的任何方式。**

我先举一个例子来说明这个问题有多普遍。几个月前的早上 8 点,我坐在一个闷热的房间里,急于在研究生水平的可视化课程中与我的小组一起展示本学期的最后一个 Tableau 仪表板。我们整个学期都在学习如何有效地将数据传达给观众,然而当一批又一批的人来到我们面前时,每个人都展示了一个比一个更具误导性和设计不当的仪表板。只占 80%的饼状图和不小心实现的布局只是我们所接触到的问题的一小部分(后面还有更多例子)。

你可能不认为这个故事适用于你,但除非你坐下来,在用一些软件建模之前计划好每一个可视化,否则你可能已经成为这些问题的受害者之一。这可能是一件简单的事情,就像找不到一个更好的可视化方法,只差一步之遥。

可视化工具的陷阱

Tableau 之类的数据可视化工具受到人们的喜爱和使用,因为它们可以非常简单地显示大型数据集中的相关性。它们被使用的确切原因也是它们最大的缺陷。

在找到看起来可以接受的东西之前,简单地点击按钮太容易了。

让我们看一些例子。我重新创建了特定仪表板的一部分,这是我在我提到的课程的最终项目中回忆起来的,所有仪表板都与世界各地的新冠肺炎统计数据相关。请记住——这些是来自研究生水平课程的可视化。****

每个单独的状态使用单独的一行

在本例中,每个州都绘制在一条单独的线上。这使得几乎不可能区分大部分的州,并导致整体上的草率外观。50 句台词重叠在一起很容易让观众不知所措,这一点很明显。令人失望的是,类似的图表在公共仪表盘上司空见惯,在各地年轻专业人士的投资组合中也随处可见。

另一个常见问题是这样的显示:

重叠的球体使得理解与每个数据点相关的地理区域变得困难

在本例中,数据最好用简单的热图来表示。使用热图不仅可以让你看到潜在的州边界,还可以使用阴影代替不同的球体大小。

热图可视化是显示区域数据的巧妙方式

再一次,这看起来像是曾经解释过的显而易见的事情,但是这是许多人挣扎的事情。创建合适的可视化的门槛比大多数人认为的要低得多。

那为什么人们最终会有这样的可视化效果呢?主要有两个原因。

Tableau 等数据可视化软件提供了可视化选定变量的建议。

推荐功能是一把双刃剑。它们可能非常方便和有用,但也可能阻止你找到更引人注目的图形。我经常看到我的同行使用推荐的图表,并表示“嘿,这给了我一个我可以使用的解决方案!”以为他们的工作已经完成了。他们没有意识到,工作不是找到解决方案,而是找到最佳解决方案

第二个原因是,人们可能不太了解某种类型的图形或图表应该在什么情况下使用。

数据可视化软件在通知或促进学习方面作用不大,并且依赖于你已经知道何时使用某些类型的图表。

这会导致许多问题——折线图代替条形图,饼图相加不到 100%,等等。

谢天谢地,有一个简单的方法可以提高你在这两方面的技能。

成功素描

手绘仪表板有几个主要原因。

花时间手绘一个可视化需要你思考你实际上在做什么。

参考前面的例子,你会在彼此的上面手绘 50 条线吗?不。人类是懒惰的——你会很快停下来,对自己说:“嘿,如果不可能区分超过 2 或 3 条不同的线,那么这样做有什么意义。”同样,参照前面的第二个例子,你会在每个州周围画一个大圈来代表该州的新冠肺炎病例数吗?难道你不想找一种更简单的方式来表达你的信息吗?

只画了三个圆,很明显哪个图形更好理解。

就像我已经说过的,一旦解释清楚,这似乎是显而易见的,但是很多人都在为此而挣扎。整个研究生水平的课程之所以存在是为了教授人们这些技能,是因为它们并不像人们想象的那样显而易见。

手绘图表让常识占上风。手绘视觉效果的每一个细节都倾注了心血。

绘制可视化图形需要你思考 为什么 你要以某种方式建模。它迫使你对每一行、每一笔和每一处删除都进行思考。我可以整天坐在我的桌面上点击按钮,直到一些可接受的可视化出现,但是坐下来画画是最简单的方式来实际 思考 我想要如何可视化一些东西。正如我前面说过的,创建合适的可视化的门槛比你可能认为的要低得多。

此外,你不需要成为一名艺术家或做任何复杂的事情来从中受益。一些最简单的图表在你的会议或演示中可能是最有效的。

为了让广大观众理解,简单是王道。

让我们回顾一下之前关于小组陈述的趣闻。当我们正在决定在最后的报告中加入什么内容时,图书馆的网络突然中断了。这给我们留下了一个空白的白板,一些干擦记号笔,和我们的数据变量的笔记。

以下是一些例子:

勾勒出部分仪表板

我怎么强调都不为过——你不需要设计任何花哨的东西,这就是 Tableau 这样的工具存在的原因。即使你确实想拥有比铅笔素描更好的东西,也没有什么能阻止你加载一个预装的绘图应用程序,并制作一个看起来更整洁的显示器。你看到这一页最上面的图形了吗?用 MS Paint 大概花了 3 分钟。

手绘可视化可以帮助培养批判性思维和思考技能

当你画东西的时候,你有意识地对你正在做的事情做出决定。为什么我在这里使用条形图?为什么在那里使用散点图?我是否应该寻找另一种方法来可视化这些信息?这些是你应该问自己的问题。即使你不在乎答案,股东和雇主也需要准确、易懂的信息来推动商业决策。

绘制图表需要你有意识地对自己进行推理为什么你正在做出具体的决定,以及在每个选项之间进行权衡。这里的线图会不会太混乱了?我是否需要一个饼图来提供信息,或者我可以简单地在不同的区域添加一个百分比标签?能够思考你为什么要做决定是一项至关重要的技能,它适用于生活的每一个方面。

结论

当今的劳动力越来越需要数据可视化技能。

由于缺乏关于何时实现某些表或图的知识,人们很难进行数据可视化。

手绘图表有助于促进更强的数据可视化和批判性思维技能,因为它需要你有意识地坐下来思考你建模的一切。

如果你认为它有什么有趣的,不正确的,或者误导的——请随意回复,我可以修正它或者重新思考我的逻辑。我非常感谢那些花时间完整阅读这篇文章的人。

我的时间序列工具包

原文:https://towardsdatascience.com/my-time-series-toolkit-4aa841d08325?source=collection_archive---------13-----------------------

我选择的时间序列分析模型

说到时间序列预测,我坚信模型越简单越好。

然而,并非所有的时间序列都是一样的。一些时间序列具有明确的趋势,例如,我们经常在经济数据中看到这种趋势:

资料来源:美联储经济数据

其他的则显示出更稳定的模式,例如每月的航空乘客人数:

资料来源:旧金山公开数据

时间序列模型的选择在很大程度上取决于所处理的时间序列的类型。以下是我遇到的一些最有用的时间序列模型。

1.ARIMA

以我的经验来看,ARIMA 在建模有强烈趋势的时间序列时最有用。该模型还擅长模拟季节性模式。

我们举个例子。

假设我们希望对一段时间内每月的航空乘客数量进行建模。原始数据来源于三藩市公开数据

这样的时间序列将有一个季节性的组成部分(例如,假日季节往往有较高的乘客人数)以及一个趋势的证据,当序列分解如下所示。

资料来源:RStudio

使用 ARIMA 模型的目的是捕捉趋势以及说明时间序列中固有的季节性。

为此,可以使用 R 中的 auto.arima 函数,该函数可以为模型选择最合适的 p,d,q 坐标以及适当的季节分量。

对于上述示例,就最低 BIC 而言,表现最佳的模型如下:

Series: passengernumbers 
ARIMA(1,0,0)(0,1,1)[12]Coefficients:
         ar1     sma1
      0.7794  -0.5001
s.e.  0.0609   0.0840sigma^2 estimated as 585834:  log likelihood=-831.27
AIC=1668.54   AICc=1668.78   BIC=1676.44

这是预测的图像。

资料来源:RStudio

我们可以看到,ARIMA 是充分预测的季节模式系列。就模型性能而言,RMSE(均方根误差)和 MFE(平均预测误差)如下:

  • RMSE: 698
  • MFE: -115

给定验证集内每月平均 8,799 名乘客,记录的误差与平均值相比非常小,表明该模型在预测航空乘客数量方面表现良好。

2.先知

让我们再来看一下空中乘客的例子,但是这次使用的是脸书的先知。Prophet 是一个时间序列工具,允许根据附加模型进行预测,尤其适用于具有强烈季节性趋势的数据。

航空乘客数据集似乎符合这个要求,所以让我们来看看这个模型与 ARIMA 相比表现如何。

在本例中,Prophet 可用于确定航空乘客数量的长期趋势,以及全年的季节性波动:

来源:Jupyter 笔记本输出

prophet_basic = Prophet()
prophet_basic.fit(train_dataset)

标准的 Prophet 模型可以自动选择趋势和季节成分,尽管这些也可以由用户手动配置。

Prophet 的一个特别有用的组件是包含了变点,或者时间序列中的重大结构突变。

来源:Jupyter 笔记本输出

通过反复试验,显示了 4 个变点来最小化 MFE 和 RMSE:

pro_change= Prophet(n_changepoints=4)
forecast = pro_change.fit(train_dataset).predict(future)
fig= pro_change.plot(forecast);
a = add_changepoints_to_plot(fig.gca(), pro_change, forecast)

RMSE 和 MAE 现在可以计算如下:

>>> from sklearn.metrics import mean_squared_error
>>> from math import sqrt
>>> mse = mean_squared_error(passenger_test, yhat14)
>>> rmse = sqrt(mse)
>>> print('RMSE: %f' % rmse)RMSE: 524.263928>>> forecast_error = (passenger_test-yhat14)
>>> forecast_error
>>> mean_forecast_error = np.mean(forecast_error)
>>> mean_forecast_error71.58326743881493

Prophet 的 RMSE 和 MFE 均低于使用 ARIMA 获得的结果,表明该模型在预测每月航空乘客人数方面表现更好。

3.张量流概率

在新冠肺炎事件之后,许多时间序列预测被证明是错误的,因为它们是在错误的假设下做出的。

越来越多的人开始认识到,能够产生一系列预测的时间序列模型可以得到更实际的应用,因为它们允许对未来可能发生的事情进行“情景分析”。

例如,使用上述航空乘客数据建立的 ARIMA 模型不可能预测到新冠肺炎导致的乘客数量的急剧下降。

然而,使用更多最近的航空乘客数据,让我们看看使用张量流概率建立的模型会如何表现:

来源:张量流概率

虽然该模型没有预测到最终发生的急剧下降,但我们确实看到该模型预测乘客数量将下降到低于 150,000 。使用这种模型可以进行更多的“假设”系列预测,例如,航空公司可以预测特定机场的每月乘客人数,并注意到乘客人数可能比平时低得多,这可以为公司管理资源(例如机队利用率)提供信息。

具体来说,张量流概率使用后验分布的假设进行预测,后验分布由先验分布(先验数据)和似然函数组成。

来源:图片由作者创建

作为参考,此处举例说明的示例使用了 TensorFlow Probability tutorial 中的结构化时间序列建模的模板,其原作者(版权 2019 tensor flow 作者)已经在 Apache 2.0 许可下提供了该模板。

结论

时间序列分析是关于使用适合数据的模型进行可靠的预测。对于具有确定趋势和季节性成分的数据,根据我的经验,这些模型工作得相当好。

希望你发现了上面这篇有用的文章,欢迎在评论区留下任何问题或反馈。

免责声明:本文是在“原样”的基础上编写的,没有任何担保。本文旨在提供数据科学概念的概述,不应以任何方式解释为专业建议。

我的 2019 年十大深度 RL 论文

原文:https://towardsdatascience.com/my-top-10-deep-rl-papers-of-2019-68d0000704e2?source=collection_archive---------17-----------------------

引人入胜的一年的主要趋势和亮点

2019 年是深度强化学习(DRL)研究的一年,也是我作为该领域博士生的第一年。像每个博士新手一样,我不得不花大量时间阅读论文,实现可爱的想法&对大问题有所感悟。在这篇博文中,我想分享我在 2019 年文献中的一些亮点。

为了让这篇文章更有条理,我决定将论文分成 5 个主要类别,并选出一个冠军和一个亚军。事不宜迟,以下是我 2019 年的十大 DRL 论文。

免责声明:我没有阅读 2019 年以来的每一篇 DRL 论文(这将是相当大的挑战)。相反,我试图提取一些关键的叙事以及让我兴奋的故事。这就是我的个人十大——如果我错过了你最喜欢的论文,请告诉我!🤖🌏🧠

第一类:大型项目

Deep RL(例如 ATARI DQNs、AlphaGo/Zero)在 2019 年之前取得的大多数突破性成就都是在具有有限行动空间、完全可观察状态空间以及适度信用分配时间尺度的领域中取得的。部分可观测性、长时间尺度以及广阔的行动空间仍然是虚幻的。另一方面,2019 年证明,我们还远远没有达到将函数近似与基于奖励的目标优化相结合的极限。诸如《雷神之锤 3》/【夺旗】《星际争霸 2》《Dota 2》以及《机器人手操纵》这样的挑战仅仅凸显了现代 DRL 有能力应对的令人兴奋的新领域的一个子集。我试图根据科学贡献来选择第一类的获奖者,而不仅仅是现有算法的大规模扩展。每个人——只要有足够的计算能力——都可以用疯狂的批量进行 PPO

🏆- DeepMind 的 AlphaStar (Vinyals 等人,2019)

“大规模 DRL 项目”类别的第一名是……”(插入一只手拿着麦克风笨拙地打开信封)+🥁:·deep mind 的 AlphaStar 项目,由 Oriol Vinyals 领导。在阅读《自然》杂志的论文时,我意识到这个项目在很大程度上是基于用于处理《雷神之锤 3》的 FTW 设置:将分布式 IMPALA 演员-学习者设置与诱导结构化探索的强大先验结合起来

FTW 使用基于两个 LSTMs 的时间尺度层次的先验,而 AlphaStar 使用人类演示。专家演示用于通过监督最小化 KL 目标来预先训练代理的策略&提供有效的调整,以确保代理的探索行为不会被星际争霸的维数灾难淹没。但这绝对不是全部。科学贡献包括一个独特版本的优先虚构自我游戏(又名联盟)、一个带有指针网络的自回归分解策略、上行策略更新(UPGO——结构化动作空间的 V-trace 偏离策略重要性采样校正的演变)以及分散连接(一种特殊的嵌入形式,可保持地图层中实体的空间一致性)。就个人而言,我真的很欣赏 DeepMind,尤其是 Oriol Vinyals 对星际社区的关注。科幻小说常常使我们的认知偏向于认为 ML 是一场军备竞赛。但是它是人类为了提高我们的生活质量而创造的。

2️⃣ - OpenAI 的‘魔方求解’(open ai,2019)

众所周知,深度学习能够解决需要提取和处理高级特征的任务。另一方面,低水平的灵巧性,一种对我们来说如此自然的能力,为当前的系统提供了一个主要挑战。至少我们是这么认为的。OpenAI 的灵巧性努力中我最喜欢的贡献是自动域随机化(ADR ):在机器人任务上训练深度 RL 代理的一个关键挑战是将在模拟中学到的知识转移到物理机器人上。模拟器仅捕获现实世界中有限的一组机制&精确模拟摩擦需要计算时间。昂贵的时间&可以用于在环境中产生更多(但有噪声的)转换。已经提出了域随机化以获得稳健的策略。不是用一组生成环境的超参数在单个环境中训练代理,而是在大量不同的配置中训练代理。 ADR 旨在设计一个环境复杂的课程,以最大化学习进度。通过根据代理的学习进度自动增加/减少可能的环境配置的范围,ADR 为代理提供了一个伪自然的课程。令人惊讶的是,这(以及基于 PPO-LSTM-GAE 的政策)引发了一种元学习形式,而这种形式似乎还没有达到其全部能力(截至本文发表之时)。Twitter 上有很多关于“解决”这个词的讨论。该算法没有端到端地“完全”了解解决立方体&的正确移动顺序,然后进行所需的灵巧操作。但老实说,哪一个更令人印象深刻:在疯狂的回报稀疏的情况下进行手动操作,还是学习一个相当短的符号变换序列?Woj Zaremba 在 NeurIPS 2019 的“学习可转移技能”研讨会上提到,他们花了一天时间与 DRL &一起“解决立方体”,这表明完全端到端地完成整个哑谜是可能的。令人印象深刻。

第二类:基于模型的 RL

虽然前两个项目令人兴奋地展示了 DRL 的潜力,但它们的样本效率低得离谱。我不想知道电费,OpenAI & DeepMind 要交。好消息是,有人通过在潜在空间产生幻觉来提高样本(但不一定是计算)的效率。传统上,基于模型的 RL 一直在努力学习高维状态空间的动力学。通常,许多模型容量不得不“浪费”在状态空间的不相关部分(例如,ATARI 帧的最外部像素),这很少与成功相关。最近,有多种在抽象空间进行规划/想象的提议(例如,一个抽象 MDP )。这是我最喜欢的两种方法:

🏆- 穆泽罗(Schrittwieser 等人,2019)

MuZero 提供了从 AlphaGo/AlphaZero 项目中移除约束的下一次迭代。具体来说,它克服了过渡动态的认可。因此,通用 MCTS +函数逼近工具箱对更通用的问题设置开放,例如基于视觉的问题(例如 ATARI)。

该问题被简化为预测奖励、价值和政策的回归,以及将观察映射到抽象空间的表示函数 h 的学习,动态函数 g 以及政策和价值预测器 f 。然后可以通过在给定嵌入观察的潜在空间中展开确定性动力学模型来进行规划。与之前一样,下一个动作是根据 MCTS 展示&与访问计数成比例的采样来选择的。使用 BPTT &对整个架构进行端到端训练,在低样本状态下,其性能优于 AlphaGo 和 ATARI 基线。有趣的是,能够模拟奖励、价值观政策似乎是有效计划所需要的。作者表示,潜在空间的规划也开启了 MCTS 在随机转变环境中的应用——如果你问我,我会觉得相当令人兴奋。

2️⃣ - 梦想家(又名。星球 2.0;哈夫纳等人,2019)

另一方面,梦想家提供了对连续行动空间的原则性扩展,能够基于高维视觉输入驯服长期任务。表征学习问题被分解为迭代学习表征、转换和奖励模型。通过使用想象的轨迹训练基于行动者-批评者的策略,整个优化过程是交错的。梦想家通过世界模型的想象轨迹传播学习状态值的“分析”梯度来学习。更具体地说,多步回报的随机梯度通过使用重新参数化技巧的神经网络预测被有效地传播。该方法在 DeepMind 控制套件中进行了评估,能够基于 64 x 64 x 3 维视觉输入控制行为。最后,作者还比较了不同的表征学习方法(奖励预测、像素重构&对比估计/观察重构),并表明像素重构通常优于对比估计。

第三类:多代理 RL

代理超越了简单的中央控制模式。我们的日常生活充满了需要预测和心理理论的情况。我们不断假设其他人的反应,并根据最近的证据重新调整我们的信念。通过梯度下降的简单独立优化容易陷入局部最优。这在一个由两个特工甘训练的简单社会中已经变得很明显了。联合学习导致了环境中一种形式的非平稳性,这是多智能体 RL (MARL)的核心挑战。两篇精选的 MARL 论文强调了两个中心点:从经典的集中训练+分散控制范式走向社会奖励塑造&自我游戏的规模化使用和意想不到的结果:

🏆- 【社会影响】作为内在动机(Jaques et al .,2019)

虽然传统的内在动机方法通常是临时的和人工定义的,但本文引入了一个因果概念,即通过由有影响力的行为产生的伪奖励来实现社会授权。关键的想法是奖励导致其他代理行为相对较大变化的行为。

因此,影响的概念是基于一种反事实的评估:如果我在这种情况下采取不同的行动,另一个代理人的行动会如何改变。边际和其他代理人的行动条件政策之间的 KL 差异可以被视为社会影响的一个衡量标准。作者在一组连续的社会困境中测试了提出的内在动机公式,并为增强的紧急协调提供了证据。此外,当允许向量值通信时,社会影响奖励成形导致信息&稀疏通信协议。最后,他们通过让代理学习预测彼此的行为,一种心理理论的软版本,来摆脱对其他代理策略的集中访问。

2️⃣ - 自动课程&紧急工具使用(OpenAI,2019)

严格来说,OpenAI 的这项工作可能不会被视为一个纯粹的泥灰文件。有一个基于 A3C-PPO-LSTM-GAE 的中央控制器,而不是学习一组分散的控制器。尽管如此,训练是通过多智能体自我游戏和你能想象到的最简单的奖励来进行的:在多智能体捉迷藏游戏中生存。作者展示了这样一个简单的奖励结构如何与自我游戏相结合,可以导致比内在动机更有效的自我监督技能习得。用作者的话说:

“当一个新的成功策略或突变出现时,它会改变邻近代理需要解决的隐含任务分配,并产生新的适应压力。”

这种自主课程的出现和显性策略的区分最终导致了意想不到的解决方案(比如在物体上冲浪)。代理人经历了 6 个不同阶段的主导策略,其中的转变是基于与环境中的工具的相互作用。由于基于团队的奖励,隐藏者学会了分工。最后,关于大规模实施的一些有趣的观察:

  1. 在 MARL 中训练中央控制器时,大批量是非常重要的。它们不仅显著地稳定了学习,而且允许更大的学习速率和更大的时期。
  2. 根据对所有代理的状态观察来调节评论家,能够向行动者提供更强有力的反馈信号。这是洛等人(2017) 在马-DDPG 的论文中已经做出的观察。

第四类:学习动力

深度学习中的学习动力仍远未被理解。与监督学习不同,在监督学习中,训练数据在某种程度上是给定的,并被视为 IID(独立且同分布),RL 需要一个代理来生成他们自己的训练数据。这可能导致显著的不稳定性(例如致命三和弦),这是任何玩弄 dqn 的人都会经历的。仍然有一些围绕新发现的重大理论突破(如神经正切核)。动态类别的两个获奖者强调了基于记忆的元学习(比 RL 更普遍)以及基于策略的 RL 的基本特征:

🏆——非交错元学习者动力学(Rabinowitz,2019)

最近,在理解深度学习的学习动力学方面有了一些进展&随机梯度下降。其中包括关于交错任务发现的发现(如 Saxe et al .,2013拉哈曼等人,2018 。理解元学习的动力学(例如,王等,2016 ) &另一方面,外环和内环学习之间的关系仍然是虚幻的。本文试图解决这一问题。

作者从经验上证明了元学习内环经历了非常不同的动态。元学习者不是顺序地发现任务结构,而是同时学习整个任务。这让人想起贝叶斯最优推理&为元学习&经验贝叶斯之间的联系提供了证据。因此,外部学习循环对应于在内部循环期间学习用于快速适应的最佳先验。每当系统的实际学习行为很重要时(例如,课程学习、安全探索以及人在回路中的应用),这些发现都很重要。最后,它可能有助于我们设计出允许快速适应的学习信号。

2️⃣ - 射线干涉(Schaul et al .,2019)

光线干扰是在(多目标)深度 RL 中观察到的一种现象,当学习动力学通过一系列平台时。这些学习曲线步骤的转变与交错的发现相关联(&忘却!)和路径是由学习和数据生成的耦合引起的,这种耦合是由于政策上的展开而产生的,因此是一种干扰。这限制了代理一次学习一件事,而对单个上下文的并行学习将是有益的。作者推导出一个分析关系的动力系统,并显示了鞍点过渡的联系。实证验证是在情境强盗上进行的。我很想知道在经典的基于策略的连续控制任务中,干扰问题有多严重。此外,我个人对这可能与基于群体的训练(PBT)等进化方法的关系感到特别兴奋。作者指出,PBT 可以抵御这种有害的政策影响。PBT 不是训练单个代理,而是并行训练具有不同超参数的群体。因此,合奏可以产生多种多样的体验,这些体验可以通过群体成员的多样性来克服高原。

第五类:合成和先验

获得有效且快速适应的代理的一种方法是知情的先验。代理可以依赖先前以先验分布形式提取的知识,而不是基于非信息知识库进行学习,但是如何获得这样的知识呢?下面两篇论文提出了两种不同的方法:同时学习目标不可知的默认策略&学习能够表示大量专家行为的密集嵌入空间。

🏆-KL-正则化 RL 中的信息不对称(Galashov et al .,2019)

作者提供了一种在学习问题中利用重复结构的方法。更具体地,默认策略的学习是通过限制默认策略接收的状态信息(例如,外部对本体感受)来实施的。KL 正则化的预期回报目标然后可以被重写,使得计算代理的策略和接收部分输入的默认策略之间的差异。然后,通过在代理策略的梯度下降更新(标准 KL 目标-正则化)和默认策略(给定代理策略轨迹的监督学习-提取)之间交替进行优化。

在几个实验中表明,这可能会导致在稀疏奖励环境中的可重用行为。通常 DeepMindLab 的大动作空间是被一个人类的先验(或者偏见)缩小了。作者表明,这可以通过学习一个约束行动空间的默认策略来规避&从而降低探索问题的复杂性。可以表明,存在各种连接到信息瓶颈的想法,以及学习生成模型使用变分 EM 算法。

2️⃣ - NPMP:神经概率运动原语(Merel et al .,2019)

少击学习一直被认为是智力的关键。这需要大量的归纳&我们人类一直在这样做。实现这种灵活性的一种机制是子程序的模块化重用。因此,在电机控制文献中,已经讨论了一组可以有效重组和整形的电机原语/默认值。在今天帖子的最后一篇论文中,Merel 等人(2019)将这种直觉投射到深度概率模型领域。作者介绍了一种具有潜在变化瓶颈的自动编码器架构,以在潜在嵌入空间中提取大量专家策略。重要的是,专家策略不是任意的预先训练的 RL 代理,而是 2 秒钟的动作捕捉数据片段。他们的主要目标是提取不仅能够对行为的关键维度进行编码,而且在执行过程中也容易回忆起来的表征。该模型归结为一个状态条件行动序列的自回归潜变量模型。给定当前历史和一个小的前瞻片段,模型必须预测实现这种转换的动作(也称为逆模型)。因此,该动作可以被认为是未来轨迹和过去潜在状态之间的瓶颈。考虑到这样一个强大的“运动原语”嵌入,我们仍然需要获得学生策略。Merel 等人(2019 年)反对行为克隆的观点,因为这往往导致样本效率低下或不稳健。相反,他们将专家概念化为围绕单一名义轨迹的非线性反馈控制器。然后,他们记录每个动作-状态对的雅可比矩阵,并优化扰动目标,这类似于一种去噪自动编码器。他们的实验表明,这能够提取 2707 个专家&执行有效的一次性转移,从而产生平滑的行为。

结论

总而言之,2019 年凸显了深度 RL 在以前无法想象的维度中的巨大潜力。突出显示的大型项目仍然远非样本高效。但是这些问题正在被当前寻找有效的归纳偏差、先验和基于模型的方法所解决。

我对 2020 年即将到来的事情感到兴奋&我相信这是一个在这个领域工作的绝佳时机。存在重大问题,但一个人所能产生的影响也是相当大的。没有比现在更好的生活时机了。

原载于 2020 年 1 月 14 日https://roberttlange . github . io**

我设计熊猫数据框架的 4 大功能

原文:https://towardsdatascience.com/my-top-4-functions-to-style-the-pandas-dataframe-932cdc79be39?source=collection_archive---------19-----------------------

为什么你需要设计你的熊猫数据框架,以及如何去做

paweczerwi ski 在 Unsplash 上的照片

熊猫数据框架是数据科学家分析数据时最常用的对象。虽然主要功能只是放置数据并进行分析,但我们仍然可以为多种目的设计数据框的样式;即对于呈现数据更好的美观

让我们以一个数据集为例。我会使用 seaborn 提供的“行星”数据进行学习。

#Importing the modules
import pandas as pd
import seaborn as sns#Loading the dataset
planets = sns.load_dataset('planets')#Showing 10 first row in the planets data
planets.head()

我们可以像下面这样设计我们以前的熊猫数据框。

它现在看起来很丰富多彩,因为我把所有的东西都放在里面,但我会把我最喜欢的一些东西分解开来。这里有 4 个函数来设计我在日常工作中经常使用的熊猫数据框对象。

“虽然主要功能只是放置数据并进行分析,但我们仍然可以为多种目的设计数据框的样式;即为了呈现数据或更好的美感

1。隐藏功能

有时当你做分析并向他人展示结果时,你只想展示最重要的方面。我知道当我向非技术人员展示我的数据框时,问题通常是关于他们默认数字中的索引,例如“这是什么数字?”。出于这个原因,我们可以尝试用下面的代码隐藏索引。

#Using hide_index() from the style function

planets.head(10).style.hide_index()

就这样,我们隐藏了我们的索引。这是一件简单的事情,但在工作环境中,我知道有时会成为一个问题。只是多了一个成为问题的栏目。

此外,我们可以尝试用链接方法隐藏不必要的列。假设我不想显示“方法”和“年份”列,那么我们可以用下面的代码编写它。

#Using hide_columns to hide the unnecesary columnsplanets.head(10).style.hide_index().hide_columns(['method','year'])

2。高亮功能

有时,我们希望展示我们的数据框架,只突出显示重要的数字,例如最高数字。在这种情况下,我们可以使用内置方法,用下面的代码突出显示它。

#Highlight the maximum number for each columnplanets.head(10).style.highlight_max(color = 'yellow')

在上面的数据框中,我们用黄色突出显示了每列中的最大数量。如果您想突出显示最小数字而不是,我们可以使用下面的代码。

planets.head(10).style.highlight_min(color = 'lightblue')

如果你想连锁,我们也可以这样做。

#Highlight the minimum number with lightblue color and the maximum number with yellow colorplanets.head(10).style.highlight_max(color='yellow').highlight_min(color = 'lightblue')

实际上,您可以突出显示每一行中的最小或最大数量,而不是每一列。我在下面的代码中展示了它。****

#Adding Axis = 1 to change the direction from column to rowplanets.head(10).style.highlight_max(color = 'yellow', axis =1)

正如我们所看到的,现在改变轴是没有用的,因为它没有突出任何重要的信息。在每一列彼此差别不大的情况下,它会更有用。

另外,我们可以用下面的代码突出显示空值。****

**#Higlight the null valueplanets.head(10).style.highlight_null(null_color = 'red')**

3。渐变功能

在展示您的数据时,我们也可以使用所有信息作为展示数据的主要方式。我经常用一种背景颜色来显示数据,以突出哪个数字在较低的区域,哪个数字在较高的区域。让我们通过下面的代码来使用这个例子。

**#Gradient background color for the numerical columnsplanets.head(10).style.background_gradient(cmap = 'Blues')**

使用 background_gradient 函数,我们可以将数据框着色为渐变。颜色取决于 cmap 参数,该参数从 matplotlib 库中接受颜色图。

我们也可以使用条形图作为我们的渐变背景色。让我在下面的例子中展示一下。

**#Sort the values by the year column then creating a bar chart as the backgroundplanets.head(10).sort_values(by = 'year').style.bar(color= 'lightblue')**

正如我们在上面看到的,我们现在用一种不同于 background_gradient 函数的方式从最低到最高高亮显示数字。我们还可以看到,由于排序函数的原因,索引是无序的;正如我在上面的文章中告诉你的那样,最好隐藏索引。

4。自定义功能

如果您希望对数据框的样式有更具体的要求,您实际上可以这样做。我们可以将样式函数传递给以下方法之一:

  • Styler.applymap:元素方面
  • Styler.apply:列/行/表格方式

这两种方法都采用一个函数(和一些其他的关键字参数),并以某种方式将我们的函数应用于数据帧。假设我有一个阈值,任何低于 20 的数字都应该被涂成红色。我们可以通过使用下面的代码来实现。

**#Create the function to color the numerical value into red colordef color_below_20_red(value):
    if type(value) == type(''):
        return 'color:black'
    else:
        color = 'red' if value <= 20 else 'black'
        return 'color: {}'.format(color)#We apply the function to all the element in the data frame by using the applymap functionplanets.head(10).style.applymap(color_below_20_red)**

就像这样,每一个小于或等于 20 的数字都会被涂成红色,其余的都是黑色。

结论

我已经展示了在设计我们的数据框时要使用的前 4 个函数;隐藏功能。我们可以设计数据框的样式来展示我们的数据,或者只是为了更好的美观。如果您想了解更多关于我们如何设计数据框样式的信息,您可以在此处阅读。

访问我的LinkedInTwitter

如果您喜欢我的内容,并希望获得更多关于数据或数据科学家日常生活的深入知识,请考虑在此订阅我的简讯。

如果您没有订阅为中型会员,请考虑通过我的介绍订阅。

我的 5 大熊猫数据操作功能

原文:https://towardsdatascience.com/my-top-5-pandas-data-manipulation-function-680e346809c7?source=collection_archive---------13-----------------------

作为数据科学家,了解您的熊猫图书馆功能库

沙哈达特·拉赫曼在 Unsplash 上拍摄的照片

作为一名使用 Python 作为主要语言的数据科学家,我们知道熊猫图书馆在我们的日常生活中是不可分割的。从你开始使用 Python 学习数据科学直到你的职业生涯,了解熊猫提供的每一件小事都不会伤害你。虽然,有一些函数我比其他的更经常使用来操作我的数据。

请注意,DataFrame 和 Series 函数甚至会在应用数据操作函数之前使用,所以我不会解释这些函数。

以下是我在日常工作中经常使用的 5 个熊猫功能。

熊猫功能

根据你工作的需要,有许多熊猫的功能是有用的,尽管有些可能比其他的用得更多。在这里,为了向您展示我经常使用的函数,我将使用 seaborn 模块(可视化库,但我只使用它来获取数据)中的 mpg 数据集。

import pandas as pd
import seaborn as snsmpg = sns.load_dataset('mpg')

来自 seaborn 模块的 mpg 数据集

现在,让我们进入要点。

1.交叉表

crosstab 是一个熊猫函数,用于计算两个(或更多)因素的交叉列表。如果你不知道什么是交叉列表,让我用一个例子给你看。

pd.crosstab(index = mpg['origin'], columns = mpg['model_year'])

双因素交叉列表示例

以上是交叉列表的一个例子。数据本身仍然是 DataFrame 对象。我们从数据集的类别变量中指定表的索引和列;在我的例子中,我使用“origin”和“model_year”类别变量。默认情况下,crosstab 函数会计算因子的频率,并显示在交叉表中。虽然,我们可以通过引入另一个因素来改变它,这个因素通常是一个连续变量。

pd.crosstab(index = mpg['origin'], columns = mpg['model_year'], values = mpg['mpg'], aggfunc = 'mean')

以连续变量为另一因素的交叉制表

上面,如果我们将“mpg”变量添加到值中,并将 aggfunc 参数设置为“mean ”,我们将获得交叉列表,其中“mpg”的平均值由类别分隔。它类似于我们称之为数据透视表的熊猫函数 pivot_table 可以实现类似的结果。

2.切口

Pandas cut 函数用于将连续值宁滨成离散区间。当我们需要对连续值进行分段和分类时,我们使用 cut。你不知道宁滨是什么;是把连续值放入某个范围区间的过程。最好用直方图来描述。

mpg['mpg'].hist()

直方图示例

这里,我们将连续值输入到某个范围间隔中,并创建箱。每个条形显示落入这些区间的值,条形越高,频率越大。

范围间隔取决于箱的数量。例如,如果我们有一个最小值为 10、最大值为 45 的连续变量,并且我们想要创建 10 个区间,那么范围间隔将是(最大-最小)/区间。这意味着(45–10)/10 = 3.5。因此,第一个容器将由 10 到 13.5 之间的连续值填充,依此类推。

这个函数对于从连续变量到分类变量也很有用。例如,cut 函数可以将年龄转换为年龄范围组。让我们用一个数据集例子来展示这个函数。

pd.cut(x = mpg['mpg'], bins = 4, labels = [1,2,3,4])

在上面的函数中,我将 bins 参数设置为 4,因为我希望获得 4 个类别,标签设置为 1、2、3 和 4。cut 函数的输出将是一个包含所有连续值的序列,这些连续值已被入库并转换为可接受的类别。这是我将它放入数据框后的样子。

mpg['mpg_bin'] = pd.cut(x = mpg['mpg'], bins = 4, labels = [1,2,3,4])
mpg[['mpg', 'mpg_bin']]

3.qcut

在熊猫身上,我们有 cut 功能,我们也有 qcut 功能。与 cut 函数类似,我们将宁滨作为连续变量,但在 qcut 函数中,基于等级或基于样本分位数,仓位大小将相等。分位数基本上是一种以相等方式划分连续值的除法技术。例如,如果我们将连续值分为 4 部分;它将被称为四分位数,如下所示。

让我用一个代码示例向您展示。

pd.qcut(x = mpg['mpg'], q = 4, labels = [1,2,3,4])

以上是 qcut 函数的输出。这里我将 q 参数输入为 4,将连续值分成四分位数,并用 1、2、3 和 4 标记它们。与 cut 函数相比,结果是不同的,因为它们的计算已经不同。让我也把它放到数据框中,这样我们就可以看到结果的不同。

mpg['mpg_qcut'] = pd.qcut(x = mpg['mpg'], q = 4, labels = [1,2,3,4])
mpg[['mpg', 'mpg_bin','mpg_qcut']]

4。get_dummies

该函数用于通过对分类变量进行一次热编码,将分类变量转换为数字变量。对于不知道 One-Hot-Encode 是什么的人来说,这是一个从我们的分类变量创建新列的过程,其中每个类别都成为一个新列,值为 0 或 1 (0 表示不存在,1 表示存在)。

为什么我们要把分类变量转换成数值变量?这是因为许多统计技术或机器学习方程只接受数值而不是类别值。

让我用一个代码示例向您展示我所说的内容。

上面是 mpg 数据集中的“原点”变量。它是具有 3 个基数的分类变量(“美国”、“欧洲”和“日本”)。这里我将使用 get_dummies 函数对这个变量进行一次热编码。

origin_dummies = pd.get_dummies(mpg['origin'])
origin_dummies

就像这样,我们已经得到了 3 个新列,每个类别成为一个新列,值为 0 或 1。

5.串联

我最常用的数据操作函数是 concat 函数。这个函数就像它所调用的那样;它串联起来。但是,这个函数连接了什么呢?它连接 pandas 对象(系列或数据帧)。让我给你看一个例子。比方说,我只想让“mpg”列显示我刚才创建的 origin_dummies 变量。

pd.concat(objs = [mpg['mpg'], origin_dummies], axis = 1)

使用 concat 函数,我只是将两个 pandas 对象(系列和数据帧)组合成一个数据帧。在函数中,我将轴参数指定为 1,因为我想组合熊猫对象,使列看起来像并排粘在一起。这个轴参数只接受 2 个东西;0 或 1。根据您想要连接 pandas 对象的方式,如果您想要像堆叠对象一样连接 Pandas 对象(像添加新行一样连接对象),请将它设置为 0;如果您想要对象相对于索引并排,请将它设置为 1。

如果我们将轴设为 0,会发生以下情况。

pd.concat([mpg['mpg'], origin_dummies], axis = 0)

我们现在可以看到,我们的数据框中有 796 行和许多 NaN 对象。发生这种情况是因为我们连接了 Pandas 对象,但是当我们设置它时,我们堆叠了该对象,不是所有的列名都存在于任一对象中,所以它用 NaN 值填充了先前不存在的列。

结论

这篇文章向你展示了我经常使用的前 5 个熊猫的数据操作功能。这些功能是:

  1. 交叉表
  2. 切口
  3. qcut
  4. 获取 _ 假人
  5. 串联

希望有帮助!

如果您喜欢我的内容,并希望获得更多关于数据或数据科学家日常生活的深入知识,请考虑在此订阅我的简讯。

如果您没有订阅为中等会员,请考虑通过我的介绍订阅。

我的五大数据科学可视化工具

原文:https://towardsdatascience.com/my-top-5-visualization-tools-for-data-science-45a4968ae695?source=collection_archive---------7-----------------------

以及如何为您的受众选择合适的工具

罗伯特·卡茨基在 Unsplash 上的照片

还记得很多年前我刚开始职业生涯的时候,团队里的标准可视化工具是 Excel 图表。我们花了很多时间进行手工处理,没有多少时间来寻找见解或提出建议。在过去的十年中,我们已经看到了无数现代工具在数据可视化方面的兴起。科技已经取得了长足的进步。

在本文中,我将首先列出我的 5 大数据科学可视化工具,然后根据您的受众解释何时使用它们。

1.擅长

Excel 在任何地方都被每个人使用。我从未遇到过没有使用过 Excel 的分析专家。信不信由你,即使在今天,一些数据科学家仍在日常工作中主要使用 Excel。

Excel 的好处是显而易见的:它无处不在。如果你想和某人分享一份工作,你永远不需要担心他们是否能打开文件。

此外,像在这里或那里调整数字这样的特别任务非常容易。一切都很透明。你可以清楚地看到每个细胞在做什么。

因为这两个优势,相信 Excel 在可预见的未来还是有它的一席之地的。

2.(舞台上由人扮的)静态画面

我大约在 7 年前开始使用 Tableau。我们必须为它建立一个商业案例,因为它不是免费的。它值这个价钱吗?肯定!

以下是我在 Tableau 中可以轻松完成但在 Excel 中无法完成的一些事情:

  1. 想到一个想法,并立即在几个拖放动作和几个点击中将其可视化。
  2. 将变量级别分组(例如,将年龄变量分为 0-18、19-25…组),并将结果立即反映在所有图表中。如果您在 Excel 中有很多图表,您会喜欢这个特性。
  3. 动画。如果使用得当,这些图表可以传递静态图表所不能传递的强有力的信息。

Tableau 还有很多其他特色。例如,您可以构建交互式仪表板,并让许多其他用户可以使用它们。这就是你如何减少 BI 团队的工作量,让人们自给自足,而不是每次有小事情需要改变时就来找你帮忙。

对我来说,主要的用例是探索性的数据分析。在我看来,在这方面没有什么比 Tableau 更好的了。

为了了解 Tableau 能够提供什么,这里是我最近为冠状病毒爆发制作的数据可视化:

[## 10 张图中冠状病毒爆发的状态(和主要发现)

确诊病例——Mainland China 境外

medium.com](https://medium.com/@zemingyu/state-of-the-coronavirus-outbreak-in-10-charts-and-key-findings-721f62c08a9e)

3.功率 BI

在很多方面,Power BI 与 Tableau 相似。我可能有偏见,但是用了一段时间后,我发现在某些领域用户体验不如 Tableau。

例如,如果你想对图表中的一个变量重新排序,你需要创建一个自定义的顺序,这将在下面的教程中通过 11 个截图来解释。在 Tableau 中,这可以通过拖放在 1 到 2 个步骤中完成,为您节省大量时间。

[## 如何重新排列 Power BI 中的图例

在你开始研究 Power BI 中任何太酷的东西之前,有必要先了解一个理想的传说。当使用 Power BI 来…

www.seerinteractive.com](https://www.seerinteractive.com/blog/reorder-powerbi-legend/)

话虽如此,我认为 Power BI 在仪表板方面做得更好,最重要的是,有一个免费的桌面版本(它不允许与您的团队协作,但对于一个用户来说往往足够好)。

如果您没有预算,但仍想提高效率,Power BI 就是答案。

4.Plotly

如果你懂 R 或 Python,你可以从 Plotly 提供的丰富的交互式图表中获益。你可以在 Tableau 中制作的大多数图表都可以在 Plotly 中复制。

你可能想知道:

“如果我有 Tableau 或 Power BI,为什么我需要 Plotly”?

答案是可扩展性

假设您正在按季度监控保险投资组合的业务组合。有 20 个不同的分类变量,包括地区、产品、性别等。

假设你很熟练,每张图表需要你 2 分钟来完成。也就是 2*20=40 分钟。

使用 Python 和 Plotly 做这件事是不同的。你可能需要花 10 分钟为你的第一个图表写代码。(是的,编程比拖放更难!)

接下来,花 5 分钟编写一个循环,为 20 个变量中的每一个创建一个图表。总共是 10 + 5 = 15 分钟。

有了循环的的好处,工作量的增长远小于 20 倍。此外,您现在可以保存代码并在将来的项目中重用它。

我通常在 Jupyter 笔记本上使用 Plotly,这样我就可以和同事们分享了。

5.破折号

假设你已经建立了一个机器学习模型来预测每份保单的盈利能力。您希望公司的每个保险商在日常工作中使用该模型,而不是将它放在硬盘上积灰。为此,您可以构建一个基于 Dash 的 web 应用程序。

这里有另一个你可以用 Dash 构建的例子:利用历史终极格斗冠军赛(UFC)的比赛结果,陈柏宇构建了一个机器学习模型来预测未来的比赛结果。Jason 没有止步于此,而是将模型部署给所有人使用。

[## UFC MMA 预测器

编辑描述

ufcmmapredictor.herokuapp.com](https://ufcmmapredictor.herokuapp.com/)

注:如果你喜欢 R 胜于 Python,你应该试试 R Shiny

如何为您的受众选择合适的工具

看过 5 大可视化工具后,你可能会想在每个用例中使用最先进的解决方案( Dash )。

这就像看到了深度学习的预测能力,你可能会忍不住把其他所有技术都扔进垃圾箱,把深度学习用于你做的每个项目。

这是一个非常糟糕的方法。

我们需要考虑我们的受众,定制我们的可视化方法来满足他们的需求。把他们分成几个不同的组可能会有帮助。

活动创作者Unsplash 上拍摄的照片

第一组高级管理人员

这些人是组织的关键决策者。他们没有很多时间。他们更关心见解和建议,而不是技术细节。他们的大脑总是在寻找这些问题的答案:

发生什么事了?

为什么会这样?

我们应该做什么,我在冒什么风险?

对他们来说,我认为最好的可视化方法是把几张幻灯片放在一起,直接回答这些问题。

您可以使用 Tableau 或 Plotly 甚至 Excel 来创建图表。没关系。重要的是你需要直接简洁地回答关键问题。否则,你的观众将会脱离,这意味着你的努力没有转化为行动,被浪费了。

第二组操作人员

这些人使用你的工具。让我们看看保险行业的一些例子:

  • 对于承保人来说,你可以建立一个交互式仪表板,这样他们就可以评估他们承保的每一项商业地产风险。
  • 对于索赔调查人员,您可以构建一个交互式欺诈评分 web 应用程序,为高风险索赔提供警告。

在保险行业之外,你可能会有自行车共享平台的维修人员,他们在交互式仪表盘上回复,找到附近的坏自行车,进行收集和检查。

关于工具,如果您的组织已经投资了 Power BI 或 Tableau,那么遵循现有的方法是有意义的。

如果你想从头开始构建一些东西,并充分利用其灵活性,你可以使用 Dash。

第 3 组分析专家

对于这一群人,我更喜欢用 Jupyter 笔记本来交付 Plotly 图形。

我喜欢它们,因为我可以轻松地提供可重复的分析。包括代码、输出和图表在内的一切都在一个地方,这使得人们很容易进行同行评审。

对于简单的特别分析,我也广泛使用 Tableau 和 Excel。

第四组其他利益相关者

虽然上述 3 个群体通常代表最重要的利益相关者,但偶尔您可能会遇到不属于这些群体的利益相关者。

如果他们是技术人员,你可以遵循与第三组相同的方法。如果是非技术类的,Excel、Tableau 或者 Power BI 可能是不错的选择。只要确保你的观众能接触到软件并知道如何使用它。

照片由海莉·凯瑟琳Unsplash 上拍摄

结论

我们已经看到了数据科学五大可视化工具的优缺点。

没有哪一种工具能主宰所有其他工具。但是,对于给定的受众,有些工具比其他工具更合适。

作为数据科学家,我们花了很多时间研究数据和构建模型,但我们花了足够的时间考虑我们的利益相关者吗?他们是谁?他们的技术能力如何?我们如何以最吸引他们的方式交付结果?

为了释放数据科学的全部力量,我们需要尽最大努力将数据驱动的建议转化为现实世界的行动——无论是让产品线更有利可图,还是捕捉更多欺诈案件或实现收入最大化。

要做到这一点,我们必须从仔细研究我们的受众开始,选择最适合他们的传播方式。

我对疫情时代求职的两点看法

原文:https://towardsdatascience.com/my-two-cents-on-job-hunting-in-the-pandemic-era-9c432af0637d?source=collection_archive---------44-----------------------

办公时间

最近,经过 5 个月的求职,我在亚马逊找到了一个 ML SDE II 的角色(是的!5 个月!所以振作起来!).这篇文章的唯一目的是给你希望,提示和工具,为自己找到一个好的。我知道这很难,但这是可能的。我有一个,你也会有!

我会建议一种更符合人体工程学的姿势和更少的咖啡因![图片来源 MixKit

快到一月底的时候,我正在和朋友吹嘘我的股票市场投资组合,所有领域的市场都在蓬勃发展,几乎所有的商业实体,包括我们街对面的小地方市场,都至少有一个数据科学家的空缺职位!

一切都准备好了,可以申请我梦想中的工作,在我选择的地方挑选一份我最喜欢的工作,并在我想要的时候开始工作。相反,我对自己说:“让我们等待这个项目完成,在这个会议提交后,我将开始!”。截止日期是 2 月 24 日,几乎在那之后,疫情猛烈出击,以你所知道的方式改变了一切:它开启了许多公司招聘的冰河期(又名招聘冻结)。

我从许多人那里听说现在不是申请的好时机,我听说招聘被冻结了,招聘比以前慢了很多,我的朋友最近被解雇了,市场上有许多有经验的人期望很低,等等。
你也会听到同样的消息,但不要在这样的坏消息上浪费你的时间和精力。他们在告诉你真相!但是你能做什么呢?你有两个选择:

  1. 坐下来放松
  2. 更好的准备自己,争取自己的位置!

我选择了第三个选项,我到处寻找,没有留下一个石头没有转动,而不是进入恐慌模式,为我不确定会来或不来的采访做更多的准备。在这个过程中的一两天,手里拿着大约 70 份工作清单,我发现有这么多知名和不太知名的公司仍在招聘(至少他们说他们在招聘),所以我放松了。然后我就去方案二准备自己反击。我想分享的第一件事是,不要按顺序做事!在你的头脑中理清你的优先事项,然后平行地做事情!不要花几个月的时间在你的简历上,然后查看工作列表,因为它们会告诉你什么是简历中重要的内容!我对自己的期望很低,但希望很高!我发现这是接近或继续这个过程的健康方式,所以我建议你也这样做。

并不是我的故事的每一步都适用于你的情况,所以我尽量不在这里扮演黄色杂志类型的影响者,来谈谈我的故事。相反,我决定分享那些我希望早点知道的教训,希望它至少能在这个过程中帮助一个人。

有趣的休息

上帝保佑 HMS 公司的核心,他们量身定制的和具体的角色描述使我在那些紧张的日子里过得很好。他们列出了一个数据科学角色,并对该角色提出了以下“工作条件和身体要求”:

  • 需要偶尔站立、行走、举起和移动物体(重达 10 磅。)
  • 使用电脑、电话和外围设备需要手的灵活性!

当时,该职位没有申请人,我一遍又一遍地阅读这些陈述,想象像我一样的申请人害怕阅读这些要求,并认为他们每天都会做以下事情:

向 Capital One 的招聘人员大声疾呼,他们的拒绝信息真的很感人。其内容如下:

“我们在招聘过程的后期收到了您的申请,因此无法考虑您的职位。”

尽管这是一封拒绝信,但这并没有坏处。因为你应该努力工作,😄

建议和意见

在这个过程中,你会要求许多朋友和专业关系给你一些建议、意见和意见。我发现的独特见解如下:

  • 把这个过程看作是一个机会,可以更深入地了解你通常不关心的领域。你将申请一系列的职位,对于每个职位和每家公司,你会发现比其他人更重要的具体方面,掌握它们,同时告诉自己你会很快需要并使用它们,也许是在工作中,甚至是在偶然的交谈中!
  • 利用你的机会早点毕业。感谢疫情,它并不适用于我,但它在这里,以防它帮助你平静下来:)
  • 不要把拒绝(以及与招聘人员沟通的延迟)当成个人问题。被拒绝的理由多得数不清!我听说一些公司已经知道他们的候选人,比如他们现在的实习生,但是他们面试你,不管结果如何,拒绝你。我不知道这在多大程度上是正确的,但即使是正确的,想想它的长期好处。事实上,你在真实的情况下评估自己,你有机会建立新的联系,这将在你的职业生涯中帮助你,他们甚至在许多方面增强你的信心。
  • 越多越好。当你在考虑去哪里申请,找谁谈,找谁推荐,问什么问题,以及你期望的薪水时,把它记在心里。我申请了 250 多个角色!是啊,250 个角色!美国所有的公司都有我的简历,我给了他们至少一次拒绝我的机会,这对他们有好处。

这些是我送的:

  • 人脉很重要,但不是唯一的因素。关于人脉的两件事:
    ——第一,联系你的朋友和人脉,向他们寻求暗示,他们会以不同方式做的事情,或者让他们成功的事情。这很有帮助。还要注意人们的性格、心态、期望和技能的差异。所以试着理解他们建议的核心要素,并决定它是否适用于你的情况。有人可能会说:“我讨厌那个角色/公司,不要接受!”我建议你进一步问,“但是为什么?”然后再决定。在某些情况下,他们只是听到谣言!
    -第二,内部推荐很重要,但如果你没有,也不是世界末日。我有许多内部推荐,但最终我得到了一个不是内部推荐的。因此,虽然我建议在可能的情况下,毫不犹豫地向你的朋友寻求内部推荐,但不要认为没有它你就没有机会。
  • 找一个好的导师。这将帮助你从现在开始成为更好的“你”。一个信任你的技能并会推动你变得更好的人。你的导师可以是你的家人,你现在的老板,你的主管,或者你的伙伴。如果你觉得生活中没有这样的人,那就积极寻找一个好的。
  • 梦想一点点。不要太超前,也不要浪费太多时间做白日梦。但是要知道,这将是一段艰难的短时间。所以,当你因为压力或思考过去的面试而筋疲力尽或无法入睡时,当你毕业并获得工作机会时,看一眼理想的未来吧…你看到了什么?你的梦想之车?假期?一个装满礼服的步入式衣柜?游戏机?你值得拥有它们,所以为什么不享受拥有它们呢?
    但是记得要像对付啤酒一样对付梦!负责任地享受!😄
  • Sh发生。回顾你的记忆,这是常有的事,对吧?!
    所以保持冷静,明白这是有可能发生的。你可能没有好心情去面试,面试官也可能没有好心情!他们可能会问你一些你一直都知道很难或者与你的职业无关的问题,但是你能做什么呢?它发生了!尽力而为,继续前进!寻找帮助你继续前进的方法。我发现虚拟面试给了我在现场面试之间放松的机会!太好了!所以我在 YouTube 上听了维瓦尔第的春天之歌来提神醒脑,放松心情,继续前进,尤其是当 sh
    发生的时候!相信我,这在我身上发生过很多次!
  • 养成良好的应对机制。求职也改变了我的日常生活。每天,我醒来都会看到一些拒绝,措辞不同,但传达的信息是一样的:“我们和其他合格的候选人很高兴看到你后悔”,或者可能是这些词的政治正确组合!但是我试着不去太在意它们,而是把它们变成我寻找更多机会的动力,把更多机会添加到我已经填充的列表中。最坏的情况,假装直到你成功!
  • 跟踪进度,现在创建电子表格!相信我,事情会变得一团糟。最好的方法是创建一个电子表格,我用了谷歌的电子表格在线工具,里面至少有以下几栏:
    -角色
    -公司
    -地点
    -网址
    -申请?
    -推荐(可以在内部推荐你担任该职位的朋友或关系)
    -当前状态(已申请、电话面试、现场、已拒绝、聘用)
    这将帮助你保持有序,并跟踪你已经申请、被推荐或被拒绝的职位。我建议为每一类公司(科技、非科技、金融、医疗保健、能源等)准备一张单独的表格..)
    你也可以享受数字带来的乐趣,就像我对我内心的数据科学孩子所做的那样:

  • 做连接。这是我个人的想法,但我喜欢把这个过程看作是一个机会,让我在我的领域里认识更多的人,并围绕我在这个过程中喜欢的人发展我的社区。我通常会在我的 LinkedIn 上添加我最喜欢的人,让他们决定是否要联系。他们中的许多人做到了,现在他们是我职业道路的一部分。
  • 搜索并准备。每个角色都有特定的面试流程,每个公司都有不同的价值观和目标。一定要提前搜索,问问在那里工作的朋友,看看网上论坛等。我认为我知道很多事情,所以我不需要收集特定角色或公司的信息,但这很重要!
  • 最后一句话。万一你错过了,只要知道 Sh**发生了!

简历!

除了你能在任何黄色杂志上找到的所有技巧和窍门,我还学到了以下几点:

  • 和那些在你想申请的领域工作的人一起回顾你的简历。你的目标是谷歌的数据科学职位,导师的指导不会是你的最佳选择,而是使用你大学的职业中心服务。请毕业的朋友提供一些意见。
  • 和那些对你深信不疑的人一起回顾和修改你的简历!它们会帮助你更好地展示自己!总是试着尽可能的现实,但是要在边缘上行走。说到底,就是生意!
  • 针对不同的角色/公司,有一份量身定制的简历也无妨。如果没有,确保个性化你的求职信。我没有充裕的时间为所有的角色做这件事,但是我为我更关心的角色做了。
  • 拥有你的求职信,这是你的第一印象。阅读尽可能多的模板,但是最后一定要在你的求职信中加入你的个人风格,尤其是第一段和最后一段。
  • 根据角色描述,调整简历的 20%左右(主要是内容的组织)。我超级懒的去做那件事,但是我会建议你去做。与此相关的是,让你的简历保持一种易于编辑的格式,这样你就不会花太多时间去编辑或决定是否值得修改。就算不为所有,也要为自己最喜欢的角色去做。

拒绝!

你会经常听到这样的话:“不要把拒绝当回事!”你会听到它,你会被拒绝,会感到沮丧,如果这些天在就业市场上不是你唯一的任务,那么它会影响你的表现。

拒绝有不同的类型:

  • 进-出拒绝:也就是说当你申请的时候,你的简历进去了,拒绝出来了。别担心,你会很快习惯的。
    这些也可能是一个迹象,表明你在简历中使用的关键词可以改进,或者你的简历可能无法被招聘软件正确解析。通过尝试相关的在线网站来确保不是这种情况。
  • 电话面试拒绝:你和招聘人员交谈,她非常兴奋,说会和招聘经理谈论你,但之后你会遭到拒绝。再说一次,这和你的技术无关,对吗?想都别想。为了确保你有更好的状态,在下一次电话面试之前,阅读一下职位描述和公司的价值观。
  • 第一次技术性拒绝:我会说从这一步开始就开始疼了。如果你已经抓住了问题,那么就有无数的理由。公司价值观,招聘经理的风格和特点,以及他们寻找的候选人类型,这些可能都不匹配。而且,这个角色本来是可以有人来担任的。一切皆有可能。如果你没有做到最好,那就多练习。把这当成一次嘲弄的采访吧!最终,它为你的下一次面试做好了准备。
  • 最后一步拒绝:在我的一次现场面试结束时,经理告诉我,之前所有面试官的反馈都是积极的,如果我们第二天没有拒绝你,这表明我们正在努力争取你的录用!我当时压力很大,等那一时刻等了 2 个多月!但是在那次会议后的两个星期里,他们没有给我任何消息,我被拒绝了!阅读它很容易,但它伤害!现在我回头看,我相信我早该知道会发生这样的事!有时是你,有时是角色,有时是公司,有时是招聘经理,有时是所有人!你不会知道发生了什么,所以放轻松,继续前进!

时间线!

我告诉过你不要把发生的事情当成私人恩怨,对吗?时间就是其中之一。根据团队的需要、招聘人员的风格、公司、经济和许多其他因素,时间表可能会有所不同。

在我递交申请的第二天,也就是递交申请的两个月后,我接到了电话面试。我在电话面试后仅两周就进行了现场面试,40 天后也达到了那个水平!有关系吗?是啊!精神上需要大量的精力和无意的过度思考。但是影响结果吗?不一定。

记住!在这个过程中,应对挑战最有效的方法就是把这个过程看作是学习更多的机会。获得新的技能,更多地了解自己。不管你给自己增加多少困难,你都会找到这个角色的!(这和努力是不一样的!)

准备!

这里我列出了我在准备面试时发现有用的资源。有建议?请在评论中分享它们,我会把它们添加到这个列表中…

关于统计与概率:

在 Python 上:

关于机器学习/深度学习:

关于编码:

也试试:

最后的话!

我祝福你们所有人。记住,有一个角色是为你而生的,只是时间和努力的问题。耐心点,我希望你能找到一份你最想要的工作,并且每天都能享受这份工作。

  • 如果你有任何建议,任何经验,或更好的解决方案与我分享,我会把它添加到列表中!
  • 如果你觉得我能有所帮助,让我们在 LinkedIn 上联系吧。
  • 当你找到一份工作时,如果这些提示有助于你与我分享,那么我们可以一起庆祝!

求职愉快!

我从数据工程师到数据科学家的不可思议的转变,之前没有任何经验

原文:https://towardsdatascience.com/my-unbelievable-move-from-data-engineer-to-data-scientist-without-any-prior-experience-6f76614fe340?source=collection_archive---------13-----------------------

通过掌握一项基本技能

照片由 PhotoMIX 公司Pexels 拍摄

那是 2013 年,一年前哈佛商业评论将数据科学家评为“21 世纪性别歧视的工作”。我曾在一家大型零售公司担任数据科学团队的数据工程顾问。当我接受这份工作时,顾问的生活并不是我想象的那样,我决定是时候继续前进了。与此同时,数据科学团队正在招聘人员来填补一年前离职人员的职位空缺。有一天,我和团队中的一位数据科学家谈论我的求职,谈话内容大致如下:

数据科学家:这个空缺找个好人选太难了。我面试了这么多人,没有一个合适的。

我:也许我应该申请数据科学家的职位。(开玩笑)

数据科学家:如果你感兴趣,我会说服我们的分析副总裁雇用你。

我:当真?我没有数据科学经验。你为什么想雇佣我?

数据科学家:因为你知道数据。

“因为我了解数据”我能够利用我作为数据工程师时掌握的这一基本技能,在没有任何经验的情况下成为一名数据科学家。这些是你需要遵循的关键步骤,以成为这一基本技能的大师。

1.不要只处理数据。对数据进行质量检查。

当您获得一个原始数据文件时,您的第一反应是查看文件分隔符,找出字段类型,并将其加载到数据库中,而不是实际查看数据吗?然后你会给数据科学家发电子邮件,告诉他们数据加载无误,然后继续下一个任务吗?这是处理的数据。

QA(质量保证)包括什么?这是检查数据不规则性的过程,例如主键的重复、意外丢失的值、文件包含历史数据时丢失的日期等等。学习如何对数据进行基本的 QA 检查,将培养您在数据提交给数据科学家之前发现上游数据问题的能力。这证明了数据科学家花 80% 的时间做数据准备的能力。

如果您不知道要运行什么 QA 检查,请询问数据科学团队他们在查看新数据时通常会检查什么。还要记下数据科学家在处理数据后提到的问题,并在下次加载类似数据时进行检查。您可能无法找到所有问题,但数据科学家会感谢您在将问题交给他们之前花时间检查明显的问题,因为这可以腾出他们的时间来构建模型。

2.了解哪些数据是可用的,以及它们之间的关系。

作为一家零售公司的数据工程师,我处理了大量的数据,如客户信息、网站活动和购买情况。网站活动中缺少的一条关键信息是,如果客户在购买前浏览过产品,但没有登录网站,则该客户会有一个链接。

通过利用我对数据及其相互关系的了解,我能够使用不同的标识字段(如电子邮件地址和 cookie ID 与客户 ID)将网站活动联系起来。当数据科学团队构建购买倾向模型时,这些数据被证明是非常宝贵的,因为以前的网页浏览是购买的主要指标。

3.了解利益相关者的需求。

当数据科学团队请求为模型开发开发一个数据集市时,我问他们需要如何构建数据。他们告诉我,客户的每个特性都必须在一行中,这意味着要构建一个包含数百列的非常宽的表。对于数据工程师来说,这是一个难以管理的表结构。

我没有创建一个宽表,而是设计了一个需要有限数量的列的表结构,并开发了数据科学家可以调用的函数来聚合和转置数据以进行建模。通过处理数据并了解如何最好地聚合数据以用于模型开发,我能够构建一个可扩展的表结构,以便数据工程师支持,但允许快速添加新功能。数据科学数据集市的开发后来成为雇用我这个没有任何经验的数据科学家的主要理由。

“了解数据”是一项基本技能,对于任何与数据相关的工作都至关重要,无论是数据工程师、数据科学家还是数据分析师。作为一名数据工程师,我已经展示了数据科学家所需的 80%的数据准备技能。虽然我的经历是一个异数,但我希望我的故事能为你提供灵感,让你知道掌握一项基本技能是开启你进入数据科学职业生涯的关键。

你可能也会喜欢…

[## 我作为数据科学家和数据分析师的经历

我希望从一开始就知道的成功秘诀

towardsdatascience.com](/my-experience-as-a-data-scientist-vs-a-data-analyst-91a41d1b4ab1) [## 我作为数据工程师学到的 6 个最佳实践

以及作为数据科学家如何应用它们

towardsdatascience.com](/6-best-practices-i-learned-as-a-data-engineer-9d3ad512f5aa) [## 数据科学家如何像数据工程师一样解决 ETL 问题

常见原因及其处理方法

towardsdatascience.com](/how-to-troubleshoot-etl-issues-like-a-data-engineer-d761f7d361d4)

我非常规的数据科学和分析之旅

原文:https://towardsdatascience.com/my-unconventional-journey-to-data-science-and-analytics-d6750090498c?source=collection_archive---------33-----------------------

利用你现有的技能。

图片来自皮克斯拜

你好。我叫安吉拉。我从 2013 年开始从事数据科学和分析领域的工作。我在这个领域的道路相当不寻常,但是,我仍然在这里取得了成功,并且每天都在继续大步前进。我想与你分享我是如何选择这个领域的,并展示我的技能是如何与我现在的位置相辅相成的。

如果你有兴趣在数据科学和分析领域工作,你的多学科技能可以作为你的优势。我坚信,数据科学和分析领域将随着技能、人员和背景的多样化而蓬勃发展。随着我们日益成为一个数据驱动的社会,我们需要不同的技能来共同解决不同的问题。学习技能,练习手艺,加入我们吧。

让我们从头开始…

图片来自 PixabayFathromi Ramdlon

本科

犯罪学

很久以前(2005-2008 年),我是新墨西哥大学犯罪学的本科生。在学习期间,我学习了社会学和犯罪、越轨行为之间的联系,并用手进行统计计算。在我的顶点课上,我们用 SPSS 分析了犯罪数据——这是我第一次真正接触数据分析,远在数据分析流行之前。我选择犯罪学是因为我被这段时间流行的过多的犯罪调查节目所吸引。我确信我想成为一名联邦调查局特工或调查员。我一点也不知道,我最终会成为一名数据调查员!

💡获得/发展的技能:

  • 批判性思维
  • 求知欲
  • 数据分析
  • 统计分析
  • 耐心(对过程、自己和他人)
  • 考虑他人(我学会了考虑他人观点的基本原则,在研究中,有时观点不同。)

研究生教育

公共管理

犯罪学毕业后,我决定立即在新墨西哥大学攻读公共管理硕士学位。我觉得这个学位会很有意思,是进入公共部门工作的一个开端。这个项目是我第一次真正接触到评估同行评议的期刊文章、分析数据、与他人合作以及发表演讲。强调团队合作和大量的小组项目。在攻读学位期间,我选修了与法律、社会学、人力资源和预算相关的各种课程。我不是一个有天赋的演说家,这是我至今仍需要努力的地方。但很高兴我有这样的经历。

💡获得/发展的技能:

  • 团队合作
  • 评估同行评审期刊和信息
  • 数据分析
  • 公开演讲
  • 主动倾听
  • 恭敬的辩论
  • 撰写有效的文档

信息技术

完成公共管理教育后,我搬到了南加州。我觉得我想探索技术领域的职业生涯。在此期间,我开始从事技术性更强的工作,因为对这些技能的需求越来越强烈。我听到越来越多关于数据分析和 python 编程能力的说法。经过一番思考和反思,我开始在 Azusa 太平洋大学攻读信息技术学位。那时我住在南加州,我真的很喜欢梓太平洋的小校园。在这个学位项目中,我学到了与计算和工程相关的各种技能,但没有具体到数据科学或分析。这个学位是我对技术感兴趣的催化剂。这是我第一次真正开始钻研技术,在与我职业生涯中工作过的技术团队类似的团队中工作,并学习坚持的艺术。我的代码已经失败过很多次,或者我根本不知道某个问题的答案。我参加了一个软件工程课程,在课程中我们团队设计了一个智能冰箱……就像现在可以买到的类型。你在课堂上能想到的东西真是太神奇了。看起来我们已经错过了与三星或 LG 的职业生涯,哈哈。

💡获得/发展的技能:

  • 编程技巧(Java、Visual Basic、SQL)
  • 技术意识
  • 技术团队
  • 数据库设计
  • 创意

生物医学信息学

当我获得信息技术硕士学位后,我开始收到数据分析师的工作邀请。老实说,我不知道这是一个职业领域,但它似乎很吸引人,所以我尝试了一下😊。我的第一个角色是一家耐用医疗设备供应商。然后,我从加州搬了出来,开始在一家专注于肿瘤数据的初创公司担任健康数据分析师。我从未如此热爱一份工作,起床后精力充沛地去工作。我喜欢数据和你可以用它做的一切。我还发现我是一个冷酷的书呆子,对此我没有意见👍。正是在这段时间里,我知道这是我想从事的职业,我将继续深造。我申请了罗格斯大学生物医学信息学博士项目,并被录取。我快毕业了。*请注意,罗格斯大学不再提供博士项目。以下是我在博士项目的旅程中所学到和获得的技能。

💡获得/发展的技能:

  • 临床数据分析
  • 临床研究
  • 流行病学
  • 机器学习
  • 临床操作

数据科学和分析的自学

图片来自 PixabayStartupStockPhotos

自创业以来,我一直在几家医疗保健集团从事数据分析工作,并了解到“分析”并不一定有一个标准,因为每个公司对它的定义都不一样。我在临床和技术环境中都工作过,发现通常有一些知识是我所缺乏的。我没有感到不安全和“情绪激动”,而是决定为此做点什么。鉴于我的背景是非传统的,我想更多地了解这个领域,成为一名更有效的专业人士。以下是我所做的,并且一直持续到今天:

  1. 我开始自学 python 编程。在创业初期,python 是我们的首选语言。开始编写功能代码很容易。
  2. 我开始在 Udemy 和 Coursera 上学习课程,只是为了让自己熟悉别人眼中的数据科学。我在 Coursera 上参加了吴恩达的机器学习课程。我开始看奥莱利的书系列,封面是动物,lol。我特别喜欢韦斯·麦金尼写的这本书。
  3. 开始在数据集上练习我新获得的技能,并建立作品组合。
  4. 我一直在通过演讲会练习我的公开演讲能力。
  5. 我刚刚完成了 Data Science Dojo 的训练营,我强烈推荐他们。该计划对我理解如何实施解决方案以及将我的知识应用到现实世界的场景中至关重要。我还学会了如何调整模型。

我对数据的热爱和对学习的热情仍在继续。只要有机会,我就会抓住学习的机会。我似乎总能学到新东西。我已经接受了我不可能知道所有的事情,因此,我是一个终生学习者。

我的技能+数据科学

图片由 Gerd AltmannPixabay 拍摄

我学到的是,这个领域远不止数据分析、算法和编程。人们普遍不言而喻地期望与人有效合作,交流你的结果,并在工作场所保持愉快。如果一个优秀的数据科学家/分析师不善于沟通,他们将会受到阻碍。以下是我在整个学术生涯中学到的技巧,这些技巧对我在这个领域的个人旅程非常有用。

——在开始分析之前,对我们收到的信息和数据进行辨别和判断是非常重要的。我们的目标是全面评估我们现有的数据,以及这些数据对于我们试图回答的问题是否可以接受。

领域知识——我主要在医疗保健行业工作,所以这在那些环境中很有帮助。

求知欲——对数据保持好奇并提出问题是构建最具商业影响力的有效解决方案的关键。

——数据科学和分析中有一种创造性和艺术性的元素。在向利益相关方展示结果时,有效的数据故事讲述(包括数据可视化工具和吸引受众的沟通)将改变游戏规则。

数据分析——分析数据以理解如何衍生商业价值的能力是一项关键的、绝对必要的技能。

团队合作——这是一项绝对需要掌握和发展的技能。独自工作而没有任何其他人类互动的可能性相当低。你绝对需要能够与他人合作。

统计分析——这是一项关键技能,取决于分析的角色和类型。融入数据科学的角色需要牢固掌握概念。

公开演讲——向决策者展示结果和建议的能力是任何数据角色的一个心照不宣的期望。花些时间了解你的听众,并根据他们的需求定制你的演讲。

编程技能——这是这个领域内必不可少的技能。有几种语言是通用的:Python,R,SQL。也有一些工作场所需要精通 SAS、C++、Java 等,但除了我提到的常用语言之外,我个人没有什么经验。

写作——我的写作量因角色而异,但无论是电子邮件、文档还是白皮书,我都需要在每个角色中写作。我很感激我的本科和研究生教育给了我这个机会。

最后

我进入这个领域的道路是非传统的,但我在这个过程中学到的一切对我作为一名专业人士的发展都很有用。技术技能是必要的,但不是唯一必要的技能!

非常需要各种背景的数据专业人员。有一个普遍的信念,只有拥有一定学位的个人才能在这个领域茁壮成长;现实情况是,随着数据问题变得越来越多样化,解决上述问题的工作人员也需要多样化。不是每个人都以同样的方式处理同样的问题,因此在多元化的团队中工作是有好处的。请忽略任何关于“如何识别假数据科学家”、“谁应该成为数据科学家”以及其他恶作剧的文章。

你对数据有热情吗?你想在这个领域工作吗?学习入门所必需的技能:编程、统计、沟通、领域知识(取决于你对哪个特定领域感兴趣),并开始用数据集练习。请注意,这个领域也需要与他人合作。建立一个作品集。学会利用你的技能来产生商业影响。这个领域需要时间、耐心和练习。没有一定的人能做这项工作。你决定你能带来什么价值。球在你的球场上。干杯!

联系我

随时联系 Linkedin

人工智能研究科学家的四种特质之我见

原文:https://towardsdatascience.com/my-views-on-ai-researcher-traits-93326a5d9905?source=collection_archive---------37-----------------------

职业,人工智能研究,经验

根据我和几个博士毕业生在一家初创企业工作的经验

纽约公共图书馆拍摄于 Unsplash

大家好!终于又可以写文章了。我想写几个想法。之前,我想写另一个关于深度学习的有趣项目。不幸的是,这个计划被搁置了,因为我有其他事情要做。在我自由之后,我忘记了这个项目,并决定放弃它。然后,突然想写一下自己的科研生涯经历。因此,我给你这篇文章。

在这篇文章中,我想分享我在工作中所学到的东西。告诉你,我是 Kata.ai 的人工智能研究科学家。我的工作是用机器学习来解决一些自然语言处理的问题。我已经做了一年的人工智能(AI)研究员,之前我的工作不是研究员。我会说,我在这个职业生涯中相对较新。

基于我的经验,强调人工智能的研究环境,我想分享基于我在我的研究团队工作的经验的研究员特质。这个团队由几名博士毕业生组成。我想给你们概述一下研究人员的一些特质。概述是基于我的观点,刚刚踏上研究员生涯。我希望它能为对此感兴趣的人提供一些见解。

批判性思维

照片由布鲁斯·马尔斯Unsplash 上拍摄

我认为这种特质对于一个想成为研究者的人来说是必要的。正如你所看到的,这个职业的工作是研究一些东西,发现一些东西,如基于研究结果的洞察力。原因是我们需要确保发现是有效的。换句话说,我们想让人们相信我们的结果是实质性的。

我对我们如何进行批判性思考的一种态度是怀疑主义。这很违反直觉,对吧?在解决问题时,我们通常需要乐观,但在这里,我们使用怀疑态度。是关于什么的?

怀疑论在这里意味着我们怀疑一个研究结果。例如,当我们发现某篇论文说这篇论文的发现很有希望时,我们会在心里问自己:“这是真的吗?我不认为这种方法对 B 有效。

这种思维模式可以提供一种新的研究思路。你可以验证你怀疑的说法,如果这是真的,这可能是一个新的研究项目想要解决。

在我去研究团队之前,我是一个认为当那篇论文有很酷的直觉和方法,并且受欢迎是很棒的人。感谢我的团队,我可以阐明这种心态。这并不是说我对任何论文都完全持怀疑态度,但至少我的大脑中有“好得不真实”的陈述,尤其是当我读到一些声称一切都很棒的东西时。

弗朗西斯科·冈萨雷斯在 Unsplash 上拍摄的照片

我有一个读学士学位的朋友在 NLP 做了一个研究项目。由于不熟悉,他决定请一位博士生做他的导师。他的导师给了他一篇论文,里面有一个很有前途的方法。导师建议我的朋友在他的项目中使用论文的方法。他决定相信他的导师给的研究论文。不幸的是,在项目结束时,他没能用论文的方法创造出一个好的模型,因此他在这门学科上得了一个很差的分数。一年后,他意识到论文是垃圾。

从上面的故事来看,如果我的朋友具有批判性思维特质,他就可以避免糟糕的成绩。对论文好不好持怀疑态度可以拯救你。尽管如此,怀疑主义并不意味着我们总是消极地看待事物,而是客观地评估我们关注的对象。

好奇心

照片由约瑟夫·罗萨莱斯Unsplash 拍摄

随着研究成为研究人员的日常任务,好奇心,在我看来,必须存在于任何研究人员的心态。有了好奇心,我们可以丰富研究发现。因此,使结果更有见地被消化。

当我们(我的研究团队)被给予一个问题时,我们讨论如何解决这个问题的几个想法。讨论是需要研究者的好奇心的事件之一。我们制定了几个假设,认为几种方法可能值得尝试解决这个问题。

在我的团队中,当我们回答一个研究问题时,通常不会以此结束。这也是需要好奇心的地方。具体来说,在我们完成了一个问题的实现和实验之后,我们需要分析结果。通常,在分析结果时,他们会突然想到几个问题来探索与结果相关的其他事情。例如,对于一个专注于深度学习的人工智能研究人员来说,当他开发出一个新的架构模型来给出显著的结果时,他可能会忍不住质疑它的好性。其中一个方法是做一个消融研究,他可以做实验,看看当新模型的一部分不存在时,质量是否会下降。带着好奇心,它可以丰富对发现的分析,这可能会进一步说服读者。

总而言之,好奇心进一步加强了研究工作。在我看来,研究工作的结果,其中之一是由团队的好奇心塑造的。当给予足够的好奇心时,它会输出一个有见地的发现。

艰苦的

道格·图尼森在 Unsplash 上拍摄的照片

并不是所有的研究实验都能得到想要的结果,因为研究人员会去研究未知的东西。所以,当一个研究结果给出可怕的结果时,要强硬。

以我的经验来说,我经历过很多失败的实验。首先,我很不幸地知道我的实验毫无结果。但是,后来,我意识到失败是一个教训,可以让我成为一个更好的研究者。失败的经历告诉了我今后需要避免的错误。杀不死你的会让你变得更强,对吗?

所以,是的,通过接受你的失败,它会让你成长。然而,当一个研究项目失败时,并不意味着所有的工作都是徒劳的。你可以在研究论文里写你失败的原因。对于任何想研究解决类似问题的人来说,这也是一种洞察力。不幸的是,每个人都如此专注于一个'成功的研究成果,而不是一个失败的。在我看来,我认为一个失败的故事比成功的故事更有价值,它可以警告某人不要再犯。尽管如此,书面报告需要彻底强调失败的原因才有价值。

所以,不要让研究实验给出不好的结果。学习并从中前进!

系统作家

照片由 Aaron BurdenUnsplash 上拍摄

实验之后,我们会有一个发现或者一些我们引以为豪的研究。那么下一步是什么?是的,把结果告诉大家它的酷!

书面报告是告诉大家的渠道之一。在我的团队中,我们经常以报告的形式写一篇研究论文。这是我们的媒体之一,在这里我们向外界传达我们的发现。

当我们与人交谈时,我们知道我们需要确保我们的信息能够被理解。然后,当我们想说服某人我们的观点是可靠的,我们需要给出一些合理的论据。这和我们如何写报告是一样的。我们需要系统地写一份合理且易于理解的报告,以使我们的发现是有成效的。然后,我们的文章越有洞察力,越容易理解,越多的人会认可我们的研究。

我在这里学到,当我们写论文时,我们需要写一个故事来系统地联系我们的发现。我们需要把动机、背景、实验结果和分析联系起来,才能做出报告。我们认为这会让我们的读者满意并喜欢我们的作品。

良好的..其实主要是为了通过审稿人对提交论文的判断😆。

结论

在这篇文章中,我给出了几个研究人员的特质,这些特质是我基于与一个人工智能研究团队合作的经历而感受到的。他们是批判性思维、好奇心、坚韧和系统化的作家。每个特征都有利于他们更好地完成研究项目。

说实话,看了一个博士毕业的 AI 研究员是怎么工作的,我离一个完全意义上的研究员还很远。但是我喜欢和他们一起工作,尤其是在讨论如何解决问题的时候。我从他们身上学到了很多,尤其是他们处理问题的方式。

编后记

感谢您阅读我的文章😃。下一次,我想写一些关于人工智能的技术。请给我一些力量来写我的下一篇文章。

一如既往,

我欢迎任何可以提高我自己和这篇文章的反馈。我正在学习写作,学习变得更好。我感谢任何让我变得更好的反馈。

在我的下一篇文章中再见!

来源: PixabayPixabay 牌照

我 2077 年的 Visual Studio 代码

原文:https://towardsdatascience.com/my-visual-studio-code-from-2077-1f5b08411dbe?source=collection_archive---------39-----------------------

让我们谈谈代码——Visual Studio 代码

来源:谷歌图片

来自未来的代码编辑器!

从崇高的文本和原子中迁移出来后,我可以说我不后悔我的决定!这是我迄今为止最喜欢的编辑器,也是开发者的终极体验,包括透明度在内的许多功能都已解锁! 我会写在 Linux 上设置它,但你可以在任何平台上设置

V S 代码使用Electron作为其基础,这使其能够跨平台并在 macOS、Windows 和 Linux 上工作。它是使用node . js构建的,完全支持任何 JavaScript 开发者。

我的主题

这是我最喜欢自定义字体的两个主题!

(灵感来自赛博朋克)——我的最爱!

我的个人

monokai(vs code 附带的内置主题)

我的个人

我的字体

firico(组合 Fira 代码 Pacifico为斜体)

这是我用于编程的字体设置。它使用 Fira 代码作为默认字体,Pacifico 代码作为斜体。由于 Fira 代码,它也有字体连字。

定制

定制字体(例如调整其中一种字体的大小)最简单的方法是使用 FontForge。只要打开”。ttf" 文件,编辑后导出回 "ttf" 。你只需要确保你没有编辑任何元数据,否则字体将无法工作。

什么是斜体?

许多编辑器/ide(如 VSCode)对某些表达式(通常是关键字或类型)采用所选字体的斜体样式。这种字体用另一种字体:Pacifico 替换了 Fira 代码的默认斜体样式,所以我们基本上是“欺骗”了程序。

在 VSCode 表达式中,斜体样式是由你的主题控制的,但是你可以在的【editor . token color customizations】下的 settings.json 中进行更改和定制。

这是我的配置:

图标主题

素材图标主题

材料-用户界面启发的文件图标,一个文件图标的替代品。

图像来源

降价支持

一体降价

所有你需要写 Markdown(键盘快捷键,目录,自动预览,等等)。

奖金!(生产力工具)

1.八叉树【浏览器扩展】

浏览器扩展(Chrome、Firefox、Opera 和 Safari)在 GitHub 上显示代码树。对于探索项目源代码来说太棒了,而不必将每个存储库都拉到您的机器上。

2. OctoLinker 【浏览器扩展】

使用 OctoLinker 浏览器扩展高效浏览 GitHub.com 的项目。非常适合查看 JS/Node/Ruby/Python 源代码。

3.设置同步

使用 GitHub Gist 在多台机器上同步设置、代码片段、主题、文件图标、启动、按键绑定、工作区和扩展。

4. GitHub 黑暗主题【浏览器扩展】

还有吗?请在评论中告诉我!

图片来源

在 Twitter 上关注我— @TheTweetofSKR ,查看我的其他帖子!

我的大数据工程之路

原文:https://towardsdatascience.com/my-way-to-big-data-engineering-9f681dc6e140?source=collection_archive---------34-----------------------

我是如何把事情搞砸,最终走上正确的道路

伊恩·施耐德在 Unsplash 上拍摄的照片

自从我的大数据工程师职业生涯开始以来,这是一次相当大的冒险。与典型的道路相比,我的开始是不同的。作为一名应届毕业生,我只拥有学术研究背景和热情的态度。但这还不够,这几年我过得很艰难。

在生活中,当你知道应该避免什么时,事情会变得简单得多。我没那么幸运,但我已经从错误中吸取了教训。我的文化中有这样一句话: “你不能选择你的工作,但它会选择你” 。就我的情况来说,这多少有些道理。我当初没有选择大数据工程。

在生活中,当你知道应该避免什么时,事情会变得简单得多

我犯了很多错误,选择了很多错误的道路,把我的信仰交到了一些错误的人手中。但我很高兴我今天的位置,我愿意倾吐我的心声,让你知道我在成为大数据工程师之前有多傻。没什么好吹嘘的,只是我的故事和你能从中得到什么。

Web 开发是一个开端

我渴望找到一份工作,任何工作。我在大学的时候做过一些计算机编程之类的事情。作为一名移民,获得一份工作是我在外国定居的方式。我对自己的技术能力和专业沟通技巧都没有信心。

尽管如此,我还是像其他人一样开始了我的过程:我在发送我的求职申请。我拿起电话,穿好衣服,去参加我人生中第一次正式面试。事情很艰难。人们拒绝了我,而不是给我回电话。这并没有让我失去应有的动力,但我开始怀疑自己。

照片由绍洛·莫哈纳Unsplash 上拍摄

我很沮丧。我开始将我的求职范围扩大到与我的学习稍微相关的领域。我最初想找一份数据科学家或机器学习工程师的工作。但是由于我在战场上毫无经验,这听起来像是一个不可能完成的任务。希望有一家初创公司接受了我的网站开发申请。和我的同龄人相比,我的工资很低,但我没有犹豫一秒钟。我需要一份工作,我接受了提供的工作。

这是我的第一个错误。不要误解我。工作很好,每个人都很友好,任务也不复杂。它只是不符合我的期望,一旦我离开学校,我会做什么。

我以为我会在机器学习模型上破解一些奇特的算法。实际上,我在建立与概率和统计学习无关的网站。我对 web 开发职业本身没有任何冒犯。我们不仅仅是天生一对。

我开始懈怠工作。我没有和上级想办法,而是选择了别的:另谋高就。我知道这听起来很糟糕。我只干了几个月,但单调的工作日快把我累垮了。我很害怕,很羞愧,也很困惑,不敢和任何人说话。我背着每个人做了一些快速采访,我找到了另一份工作。

新工作是关于数据挖掘、大数据、机器学习,你能想到的每一个关键词。不用说,我被宣传要马上开始新工作。我试图面无表情地告诉我的经理,我想辞职。他没有感到震惊,这让我感到震惊。不管怎么说,我们发现这张纸很好用。我得到了两天的休假通知。我想不出一个欢送会的理由,因为不是每个人都知道我的存在。

在我第一份工作的最后一天,我不得不和一个我很亲近的同事说再见。我说:“我必须去”。她很惊讶:“什么意思?你要去哪里?”。我不擅长说再见,所以我很直接:“我要辞职了”。她从惊讶到愤怒,然后有点怜悯。

太残酷了。我没有以专业和情感的方式恰当地处理这项工作。是我的无知和天真改变了我的决定。我的下一个希望寄托在下一份有前途的工作上。但我不知道事情开始变得更糟。

***What you can learn:***- You don't have to accept any offers just because it's the only choice. You'll end up regret for it most of the time.
- Communication is the key.
- The grass might be greener on the other side, but it's merely a matter of perspective.

机器学习还是炒作

我没有时间后悔我的退出决定,因为我很高兴能开始下一次冒险。在这份新工作中,他们给我安排了一个新项目,从技术上来说,这个项目没有人做过。这些新项目可能会有很多问题。它们通常含糊不清,缺乏技术规范,结果很糟糕。

至于我的这个项目,这三个都有。他们向我承诺了数据挖掘和机器学习应用,但没有什么可以申请的。没有数据,没有软件架构,没有技术眼光。我一整天都在参加人们争论而不是工作的会议。我看不到任何地方可以把我的技术能力用在我目前的职位上。

来自 Pexels 的 Andrea Piacquadio 的照片

我的经理让人无法忍受。在某个时候,他给我一些无关紧要的任务,只是为了让我忙起来,因为他也不知道我们要去哪里。那时我意识到,大多数公司声称要用机器学习和大数据来改变世界,但实际上并不具备适当的专业知识。

我在公司呆了一段时间。主要是因为我想让我在这个国家的居留合法化。我忘了说,自从我开始职业生涯以来,我从未停止过自学。尤其是度过困难时期,你最好做好准备。我已经跳到了每一条建议上,关于如何跟上最新的趋势,以及哪些技能是我应该最关注的。

我的最终道路仍然模糊不清。我尽可能以最普通的方式增强了我的投资组合。这是初级工程师的常见错误。但这是难以避免的。当你没有尝试过每一个选项时,你不会知道你想做什么。后来有一天,我和我的雇主再也无法忍受对方了。我们说了再见,但关系不太好。

直到今天我都恨我自己。我让一些流行语进入了我追求扎实的工程职业的道路。我发誓再也不会以貌取人了。就这一次,运气站在我这边。这一次,我将进入一个新世界:大数据领域。

***What you can learn:***- Don't believe on what you hear companies say, but on what you see they do.
- Buzzwords are real, and don't fall into traps.

我是如何在不知情的情况下接受大数据的

还记得理查德·布兰森说过:

如果有人给你提供了一个绝佳的机会,而你不确定你能做到,那就答应吧——然后再学习如何去做。

这可能听起来很老套,但对我来说曾经是真的。当我得到一份成为大数据开发人员的工作邀请时,我遇到了大数据。他们和我开诚布公地谈了一些我不胜任的工作要求。幸运的是,他们问我是否准备好进入一个不确定的大数据世界。Scala 或 Hadoop 生态系统之类的东西对我来说很遥远,但我说是的。这不是一个自信的“是”,而是“是的,我能做到!”,而是一个到底能出什么差错“是的”。

然后,我在大数据世界的冒险开始了。我首先浏览了一些关于 HadoopSpark 的书籍,这是当时大数据领域最重要的两个概念。我设法理解了他们的架构和技术背景,但是如果不使用它,很难掌握这些工具。当我在工作中等待足够长的时间来学习时,我开始向大数据的神秘领域前进。

进入大数据世界是什么感觉。照片由 Ashley BatzUnsplash 拍摄

起初,我惊讶于数据并没有像小数据那样以普通的方式表现。这个领域的规则很特别,我必须去适应它。但是当我了解事情的运作方式后,我意识到大数据并没有什么特别的。我告诉自己:“它只是大而已。作为一名工程师,我们只是使用工具按原样处理大数据,不多也不少”。天哪,那时候我完全错了。

请允许我引用我的母语中的另一句谚语

井底之蛙以井的周长来看待世界。

我就是那只青蛙。我以为大数据那么小,我都能看懂。我忘记了我处于大数据领域的边缘,我的旅程才刚刚开始。大数据工程不仅仅是利用工具来大规模处理数据,还包括我们如何处理这种宝贵的资源,从而为业务决策和面向客户的演示带来价值。

***What you can learn:***- You can start woking professionally on a field without minimal experience, but that doesn't exists everywhere. Be prepared.
- Be humble. What you know today might be obsolete tomorrow.

结论

埃斯特扬森斯Unsplash 上拍摄的照片

我已经列出了我的错误,这样你就不会再犯了。一个专业的职业道路是漫长的,僵化的,有些乏味的。有了经验,我们进步得更快,同时也避免了前人所犯的错误。我希望当轮到你的时候,旅程将同样充满冒险,充满挑战,并在结束时硕果累累。直到那时,快乐学习!

我的名字叫 Nam Nguyen,我写的主要是关于大数据的文章。享受你的阅读?请在 Medium 和 Twitter 上关注我,了解更多更新。

我在挪威成为高级分析初级顾问的奇妙旅程

原文:https://towardsdatascience.com/my-wonderful-journey-to-become-an-advanced-analytics-junior-consultant-in-norway-6df652ad9487?source=collection_archive---------38-----------------------

商业分析理学硕士学位如何帮助我加快职业生涯并过渡到数据科学领域

图片作者。

一些朋友问我在挪威学习商业分析理学硕士(MSc)的个人经历,以及我在数据科学领域开始职业生涯的旅程如何。这就是为什么,我决定分享我的真实经历,这样你就可以更好地了解会发生什么,并有希望帮助你决定这是否是你的正确选择。

此外,我决定分享我的整体经验,而不仅仅是谈论硕士及其职业机会,所以我会涵盖其他话题,如我参加的一些课外活动,我在挪威的生活经历,我在一家能源咨询和商业智能数据公司担任数据分析师的实习经历等。

以下是我证词的大致结构🙂。

总体结构(图片由作者提供)

1.大师与大学

稍微介绍一下我的背景

在开始攻读硕士学位之前,我在墨西哥城的 ITAM 获得了工商管理学士学位。此外,我在墨西哥做了一年的量化股票交易员,在我学士学位的最后一年,我有机会在巴黎 HEC 和吴维也纳经济和商业大学留学。这次经历让我置身于一个难以置信的学习环境中,从那一刻起,我知道我想去国外读硕士,尤其是在欧洲。

为什么要进行商业分析?

有了工商管理的背景,我知道我想选择一个更技术性的硕士学位(不是 MBA ),但始终牢记商业和应用方面。这就是为什么商业分析硕士学位非常吸引我。随着每天产生的大量数据以及计算机和软件功能的新发展,我知道基于数据驱动的分析优化和改进公司决策有着巨大的潜力。就业市场和在任何类型的行业和部门实施分析的可能性也非常有吸引力。

为什么 毕挪威商学院

BI 挪威商学院的硕士项目结合了一系列知识和技能,将数据科学与商业学科相结合。它非常强调知识的应用,并通过实习、交换项目和认证为你提供个性化学位的灵活性。

在 2019 年年度欧洲商学院排名中,T4 大学也连续第五年被英国《金融时报》评为挪威最佳商学院。

为什么是挪威?

正如我之前提到的,我想在欧洲的某个地方学习我的理学硕士学位。我在英国、法国、德国、瑞士和北欧国家寻找不同的项目,但挪威引起了我的注意。在了解了它的高生活水平、性别平等、稳定的经济、有吸引力的就业市场、低水平的腐败和很棒的户外活动后,我被说服了。

当然,一切都不像听起来那么完美,世界上任何地方都有不好的一面。你还会经历寒冷和黑暗的冬天,也许不是最好的夜生活(尤其是来自墨西哥),高昂的物价,有时很难真正了解挪威人。我将在后面的部分更详细地讨论这一点,在那里我谈到了奥斯陆,它的人民和文化。

课程结构、课程内容和难度

硕士是一个为期两年的全日制项目,分为两个学期,一个在秋季,一个在春季。第一年,你的大部分课程都是学习基础知识的。它是讲座、小组项目、期末考试、选修课和研讨会的结合。第二年比较应用,可以选择去实习,成为外部公司的顾问,或者通过成为研究助理来追求自己的学术兴趣。此外,你还必须在最后一年完成两门课程并撰写硕士论文。该计划提供了在世界任何地方完成第二年理学硕士课程的灵活性,班级规模约为 40 人,因此您可以体验更多个性化的关注。

程序结构和类概要(图片作者)。

在理科硕士的第一学期,我修了 5 门课程:数据管理和 Python 编程、业务优化、应用数据分析、现代商业环境中的数据保护和道德,以及决策理论和系统动力学。

Applied Data Analytics 专注于使用 r 的统计和数学。从我的经验来看,难度是中等的,但它让我对不同的主题有了很好的更新,如逻辑回归、假设检验和探索性因素分析。在数据管理和 Python 编程中,我们学习了如何使用 Jupyter 笔记本编写 Python 代码,在课程的第二部分,我们学习了关系数据库以及如何使用 SQL 从这样的数据库中检索数据。

业务优化是一门非常有趣且富有挑战性的课程。我们学习了如何使用数学建模来支持实际的商业管理决策。在本课程中,我们使用了 AMPL 代数建模系统,并学习了一些最常见的确定性优化建模技术,如线性规划(LP)、整数规划(IP)、混合整数规划(MIP)和非线性规划(NLP)及其在物流/运营和战略中的应用。

伦理学是一篇普通的论文,重点是 GDPR 和决策理论和系统动力学的课程,我觉得有点无聊,小组项目非常耗时。该课程包括使用 Vensim(一种模拟软件)对奥斯陆的垃圾分类系统进行建模,以分析不同的行动和策略如何影响城市中可回收材料的百分比。

第二学期,我也有 5 门课:机器学习预测分析、商业模拟、可视化和网络理论,还有两门选修课:人工智能——技术和应用,以及供应链分析。

我最喜欢的课程是约翰·钱德勒·约翰逊的机器学习预测分析,太棒了!他在斯坦福大学获得了统计学硕士和博士学位,他非常擅长沟通和教授这门课程。我喜欢他的方法,即专注于为公司提供价值的商业应用,但也要记住在建立机器学习模型的过程中需要的最重要的概念和技术要求。

我们学习了如何使用 Python 和 DataRobot 构建有监督的机器学习模型,并在一个团队项目中为一家银行检测信用卡欺诈。我原以为这门课的难度会很高,但结果是中等难度。

我选修的人工智能与机器学习的课程有关,难度更高,技术性更强。我们从对人工智能的介绍开始,学习了人工智能如何在商业中付诸实践,以及如何评估其潜在的好处。本课程涵盖了 Python 中的面向对象编程(OOP)以及一些最常见的搜索算法、约束满足问题和更多关于机器学习的内容。

我选的另一门选修课,供应链分析,是业务优化的延续。我们解决了供应链优化、需求预测、运营调度和安全库存分析等更高级的问题。

对于商业模拟课程,我们在 AnyLogic 中建立了一个模拟模型来测试登机的不同政策,对于可视化和网络理论课程,我们使用 Gephi 进行社交网络分析。从我的角度来看,我认为可视化课程还有很多需要改进的地方。希望在未来,他们不会太关注社交网络分析,而是开始使用更多的 Tableau 和 Power BI 来学习如何构建仪表板和引人注目的可视化,以使用正确的图表讲述故事。

附加资源

此外,该大学为您提供免费访问 DataCamp 网站的机会,这是一个了解更多数据科学知识和补充您的研究的好地方。您还可以参加免费的电子学习课程,获得 SAS 软件的认证,并访问 金融时报 时事通讯。

如果你想做交换,你可以在第二或第三学期做但选项(大学)有限。第二学期,你可以在沃里克,博科尼,或者葡萄牙学习,第三学期,你可以去荷兰,在蒂尔堡。

2.职业机会

行业曝光

我真正喜欢我的大学,并认为与挪威其他大学相比的优势是它与行业的紧密联系。自从开始学习以来,你在招聘会、研讨会和公司活动中接触了很多不同的公司。作为 Master Merit Society 的成员,我有机会与 Gjensidige、Equinor、Deloitte 等公司一起参加研讨会,更深入地了解他们。此外,您可以访问 BI 职业门户网站,在对大学生档案感兴趣的公司中搜索工作。

最后,我鼓励你积极主动地搜索你所在地区附近发生的事件。在我的第一个学期,我去了奥斯陆大学(UiO)的数据科学日,这是一次很棒的经历!你有机会结识对数据科学感兴趣的人,聆听数据科学家的会议(就我而言,是一位在美国工作的脸书数据科学家),并与出席活动的公司建立联系,例如 BCG Gamma 和 DNV GL 等。

我在雷斯塔能源公司做数据分析师实习生的经历

正如我之前提到的,在硕士的第三个学期,你有三个选择:实习,在选定的公司做咨询项目,或者作为研究助理与老师合作。我有机会在雷斯塔能源公司做了 10 周的数据分析师实习。他们是领先的能源咨询和商业智能数据公司之一,为石油服务公司、投资者和政府提供全球数据库、战略咨询和研究产品。

办公室位于 Aker Brygge,拥有奥斯陆峡湾的美丽景色(图片由作者提供)。

在这次实习期间,我参与了的两个主要项目

在第一个项目中,我使用地理坐标和阿根廷油井的特定标识符在 Python 中进行地理空间分析,以提高数据建模的准确性,并使用 Tableau 创建可视化。

在第二个项目中,我收集、整理和综合了来自多个来源的数据,根据每桶二氧化碳的排放量来衡量上游行业最大的石油公司。

这次经历对我来说是非常有意义的,也很重要,让我认识到无法像你希望的那样找到完整和干净的数据的挑战。我学会了如何在国际办公环境中合作,与你的团队保持持续沟通有多重要,以及你的工作如何影响其他公司根据你的分析做出的决定。

我在 SAS Software 担任高级分析初级顾问的经历

几周前,我开始了我职业生涯的新旅程,我很高兴成为其中的一员。我加入了挪威的 SAS Institute,与他们的一个电信行业客户合作一个咨询项目,通过实施高级分析来帮助他们利用数据的价值,从而改进他们的营销决策。

让我向您介绍 SAS 软件公司新一代高级分析初级顾问👨🏻‍💼💼来自挪威、墨西哥、瑞士和南非(图片由作者提供)。

我和我的团队目前正在机器学习算法的帮助下优化客户旅程。其理念是使用 SAS Customer Intelligence 360,根据不同的细分、渠道和触发事件,在网站上个性化数字客户体验。

到目前为止,我们正在试验 A/B 测试和归因分析。开始时,在与不同的利益相关者举行多次会议并向我的主管汇报进展的同时,保持进度并学习如何熟练地使用解决方案有点困难;但我相信,凭借奉献精神和团队合作,这个项目将为客户创造价值。

在 SAS 的第一周,我们与不同部门的人举行了多次会议,在会上我们了解了公司、公司的价值观、对人工智能的投资以及解决方案。他们的办公室就在挪威皇家宫殿的后面,每个人都非常有经验并且乐于助人。

在不久的将来,我会写一篇博客,介绍在这个项目中遇到的挑战、取得的成果和学到的技能💪🏼。

3.课外活动和爱好

对我来说,学习期间的另一个重要方面是参与不同的课外活动,并不断锻炼以保持健康、强壮和专注。

大学的学生会提供各种各样的社团和组织,你可以成为其中的一员。通常,在每学期开始时,他们组织招募日,所有的学生组织都出席,分享他们的活动和事件。

硕士第一学期,我决定加入毕启航团队BISO 投资-资本管理担任风险分析师。我喜欢这两种经历,它帮助我认识了更多来自其他硕士项目的人,并体验了难以置信的机会,如在挪威峡湾航行😎。

与 BI 帆船队一起在奥斯陆峡湾航行。毫无疑问,这是我在奥斯陆做过的最好的活动之一。

4.我的新家——住在挪威奥斯陆

在 hike️后欣赏格雷夫森科伦的美景。

奥斯陆是一个非常放松和令人愉快的城市,在那里你可以体验到美丽的人和高价格的大自然😅。总的来说,与其他国家相比,挪威人的生活质量很高,对待事情很冷静,没有压力。

在搬到奥斯陆之前,我住在墨西哥城,所以对我来说,奥斯陆在一开始并不重要。我记得在第一周我参观了这个城市的大部分地方,但是随着时间的推移,你会发现很多徒步旅行和美丽的地方。

挪威人非常友好,总是愿意帮助你。大多数人英语说得很好,他们喜欢在外面的树林里,与朋友和家人一起在他们的小屋里徒步旅行和放松。我认为他们开始时很害羞,但当你对他们了解多一点后,他们就会敞开心扉,变得非常友好(尤其是如果你给他们一些酒的话)😂).我有许多挪威朋友,但我认为和他们很亲近会更困难,尤其是如果你不会说挪威语的话。

公共交通非常高效,城市非常安全,距离森林或海滩只有 10 分钟的路程。根据季节的不同,你可以练习不同的活动,比如冬天去越野滑雪,夏天去远足和露营。

在奥斯陆 Vettakollen 的顶端(图片作者)。

在这里,你会看到我大约每月生活费的清单。这是一个“近似值”,因为有几个月我旅行了,出去多了一点,或者买了额外的东西,这些都没有包括在这个预算中。我知道有些人每月花费 8000 挪威克朗(一个非常有限的预算),而其他朋友花费更多,但我认为学生平均每月花费 9 到 12000 挪威克朗。

我的生活费(图片作者)。

我很感激我获得了 BI 总统奖学金,它涵盖了我所有的学费,此外,我每个学期还获得了一笔助学金来支付我的生活费用。

通常情况下,我花的钱比我从大学里得到的要多,但有了实习的工资和父母一开始的一点额外帮助,我能够支付整个硕士的生活费用。

我认为经济因素是一个需要考虑的重要方面,因为挪威是一个生活成本非常高的国家,所以如果你没有奖学金或者没有能力在不影响钱包的情况下支付学费和生活费,我认为这太冒险了。当然,在国外读硕士是一个很棒的经历,你可以从中学到很多东西,但现在网上有很多资源可能是你更好的选择(但那是另一个要讨论的话题)。

挪威是一个生活的好地方,但同时,我真的很想念我来自墨西哥的家人和朋友,那里完美的天气,美味的食物,精彩的聚会,以及热情的人们,这些也许在挪威很难找到。我的哲学是,你需要享受和欣赏你现在拥有的美好事物,并利用你此刻生活的机会和经历。

5.最后的想法

学习商业分析硕士一直是一个不可思议的经历,不仅从学术和专业方面,而且满足来自世界各地的人,体验新的文化,传统和探索挪威的性质。

如果你有出国读硕士的可能,我真的鼓励你去做!它会帮助你在生活的各个方面成长,你会在旅途中获得很多乐趣(长时间呆在图书馆里🤓).

感谢这个机会,我能够在数据科学领域开始职业生涯,并在国际环境中的不同公司工作,与非常聪明和有经验的人一起帮助我学习和专业成长。

如果您有任何与硕士学位、我在挪威的经历或数据科学相关的问题,请随时联系我并在 Linkedin 上给我写信。我希望我的证词有助于更好地了解这些大师,并激励你考虑从事数据科学。

最后,我要感谢你阅读我的证词,并祝你在职业和个人生涯中好运!😃

MyAnimeList 用户评分:网络抓取和线性回归的乐趣

原文:https://towardsdatascience.com/myanimelist-user-scores-fun-with-web-scraping-and-linear-regression-9dd97900a82b?source=collection_archive---------44-----------------------

蒂姆·莫斯霍尔德在 Unsplash 上的照片

Metis 数据科学训练营的第三周已经结束,训练营的第二个项目也已经结束。下面我详细介绍一下我做的项目,就是从 MyAnimeList (MAL)中抓取数据,然后使用线性回归模型根据动漫的特点预测用户评分。

TL;博士:

  • 从 11541 个动漫作品中刮净 19 个特征
  • 通过虚拟变量转换的特征;剪裁异常值;应用 log10 和 sqrt 和乘法/除法功能
  • 通过 statsmodel 的 OLS 选择了 11 个特征;scikit-learn 的套索;R 和 MSE 等指标;直觉和领域知识
  • LASSO 在性能上挤掉了 plain linear regression 和 Ridge,但是线性回归模型的选择最终没有产生差异
  • 最终的模型可以预测一部动画是高分还是中分,但是有负偏差相对广泛的传播
  • 不同类型的动画也有非常不同的剧集分布和时长
  • 接下来的步骤是将线性回归模型分别应用于不同的动画类型,并研究更复杂的模型

一.背景

MAL 声称它是“世界上最大的动漫数据库和社区”。网站上的大部分信息(如果不是全部的话)都是用户生成的,从给一部动漫的评分和评论到该动漫的人物简介和列表。

《仲裁示范法》清单示例(来源)

用户生成的分数很好地代表了一部动漫的质量和受欢迎程度。因此,我想知道我是否可以使用 MAL 在这部动画上的数据来预测它将获得的分数。

对于决定下一部作品的动画制作公司来说,或者对于决定委托或授权播放哪部动画的电视网络来说,这将是非常有价值的信息。

二。收集数据

我使用 BeautifulSoup 收集了 2020 年 4 月 23 日至 24 日之间的 16706 部动漫作品的数据。

我如何分割恶意数据

在这些条目中,有 5,165 个被排除在最终测试和训练数据集之外,因为它们没有分数(也称为目标值)。这给我留下了 11,541 个条目,或者原始数据集的 2/3。然后,我将剩余条目的 1/5(或 2,279)分成一个测试数据集,并保留剩余的 9,262 个条目用于训练和验证。

以下是最终考虑的 19 个特性列表。

关联属性的类型

被删除但没有使用的功能包括制作方、许可方和工作室,以及日本的播出时间。未被删除的特征包括动画中的角色、配音演员和其他工作人员。所有这些特征都可以包含在对恶意代码数据的任何进一步调查中。

三。准备数据

a)空数据

最终数据集中有几个空数据实例。所以我选择删除下面的内容,剩下 9144 个条目:

  • 150 个尚未播出或正在播出的节目。他们没有列出结束日期和/或没有集数
  • 7 个已经结束播放但没有开始日期的节目

我还将剩余的空数据处理如下:

  • 没有列出集号的电影被认为只有一集,大多数电影都是这样
  • 各个相关属性的空条目可以被认为是空列表

b)整合流派

数据集中有 41 个流派,这可能意味着多达 41 个特征;然而,只有 9 种类型有超过 200 个相关的动画条目:

那可是好多流派啊!

因此,我将少于 200 个条目的所有流派合并到“其他”类别中,结果是一个更易于管理的 10 个流派的列表:

好多了。

c)流派和类型的虚拟变量

我为 10 个综合类型和 6 个动画类型生成了虚拟变量,其中电视和 OVA 列表占了大多数。

动漫类型及其分类

d)流派和相关属性的计数

每个动画条目可以被标记为多种类型和相关属性。因此,我生成了以下内容:

  • 流派的数量
  • 每个关联属性的计数
  • 关联属性的总数

e)额定值的数值

动漫的分级从适合所有年龄的(G)到色情的。因此,我决定给每个等级分配一个等级,用 0 表示最适合家庭,用 5 表示最不适合家庭。

一小部分动漫没有评级;对于这些,我假设它们的评级为 PG13,这是最常见的评级(占训练数据集的 44%)。

动漫分级及其分类

f)剪辑情节和持续时间

我发现剧集(一些剧集播放时间很长)和时长(一些电影播放时间接近 3 小时)都存在极端异常值,如下图所示:

1750 集!?!?

请注意< 5 分钟左右(对应于非常短的动画)和~25 分钟左右(对应于典型电视或 OVA 剧集的长度)的峰值

因此,我选择将剧集剪辑为 60 集(略多于一年的动画),时长为 150 集(典型电影长度的上限),如下所示。

请注意 1 集(对应于电影和其他单镜头)以及 13、26 和 52 集(对应于电视动画的第 1、2 和 4 季)的峰值

在第 90 分钟左右略有起伏

g)动画的开始年份和年代

从动画条目的开始字段中,我提取了动画开始的年份,并按年份计算了动画的年龄。

h)其他转换

我对以下特征应用了 log10 变换,这些特征显示出更符合泊松分布:

  • 剪辑的剧集和剪辑的时长
  • 成员和收藏夹(对此我也应用了额外的 log10 转换)
  • 动漫时代
  • Gerne 和相关计数

需要 log10 转换的功能示例

我还应用了以下转换:

  • 开始年份的平方根
  • 按日志成员划分日志收藏夹(以获得收藏夹与成员的比率)
  • 将剪辑的剧集与剪辑的时长相乘以获得剪辑的长度;将测井次数乘以测井持续时间,得到测井长度
  • 类型和相关属性的倍增虚拟变量与日志长度

四。选择最终特征

总共考虑了 86 个特征;其中包括成员和收藏夹以及以下 84 个转换后的功能。

转换后的要素列表

为了减少功能的数量,我使用了以下代码:

  • statsmodel 的 OLS ,使用参数的 t-scores 确定其显著性(选择的分界点为 5%显著性)
  • scikit-learn 的套索,查看哪些参数在λ= 0.01处被丢弃(选择的截止点为 0.01)
  • scikit-learn 的 LinearRegression,查看 R、均方误差、平均绝对误差和最大误差
  • 直觉和领域知识

用于选择要素的工具

这给我留下了如下 11 个特征。

动词 (verb 的缩写)拟合和选择模型

出于这个项目的目的,我考虑了 scikit-learn 的以下线性回归模型:

  • 线性回归
  • 山脉
  • 套索

这三个模型在训练数据集上用 5 重交叉验证来训练。结果非常相似,如下表所示:

我选择了 LASSO 模型,因为它比其他两个模型稍微好一点(特别是在最大误差方面),但这两个模型都可以工作得很好。以下是 LASSO 训练结果的图示:

不及物动词观察

将最终模型应用于测试集给出了以下结果:

这比在训练/验证集上的性能稍好。最终的模型看起来也足够强大,足以表明一部动画是否会获得高分或中等分。

检查如下表所示的调整后的参数权重,我发现如下:

  • 最喜欢的成员的比例是用户生成的动画分数的最重要的预测因素。这是有意义的,因为用户将一部动画放在喜爱的列表中很可能给该动画一个高分。
  • 父母故事和前传数量也是重要的预测因素。这可以归功于一部属于已知特许经营的动漫,从而成为其粉丝中的已知数量。

这也表明了依赖用户生成分数的风险;我们已经看到,在整个数据集中,较高的分数比较低的分数更普遍,所以粉丝喜爱的人可能倾向于获得较高的分数,而不管观众的规模如何。

  • 动漫长度也是用户生成分数的一个重要预测指标,这是有意义的,因为长期播放的电视剧通常是如此,这是因为受欢迎的需求和随后的经济回报。

调整后的重量=模型重量的绝对值除以数值范围

但是,我注意到以下限制:

  • 模型有一个负偏斜;分数> 8 偏向较低分数,分数< 5 偏向较高分数
  • 该模型有一个相对较高的传播,尤其是分数< 5。所以精确的分数预测有点超出了它的范围
  • 不同动漫类型的剧集和时长分布差异很大。比如电影多为一集,时长在 1 到 3 小时之间;电视连续剧往往至少有 13 集,每集 24 分钟。

顶行表示持续时间,底行表示发作次数。请注意不同动漫类型之间的分布差异有多大。

七。进一步的工作和学习要点

显然,需要一个更复杂的模型来准确预测恶意动漫作品的用户生成分数。可能的方法包括:

  • 对每个动画类型(无论是电视还是电影)分别应用线性回归或其他模型。决策树算法在这里可能会创造奇迹。
  • 纳入当前分析中遗漏的特征,如制片人、工作室和工作人员。
  • 整合其他动漫网站的数据,如 AniDB 和动漫新闻网。
  • 应用更复杂的模型,如神经网络。

我学到了很多关于典型数据分析的工作流程,我很高兴看到如何将我学到的知识应用到下一个项目中。

云中的 MySQL 8.0

原文:https://towardsdatascience.com/mysql-8-0-in-the-cloud-927c8dddd908?source=collection_archive---------43-----------------------

照片由晨酿Unsplash 拍摄

Azure、Google 和 AWS 现在都支持 MySQL 8.0

万岁!

两天前,当 Google Cloud 宣布在 Cloud SQL 上支持 MySQL 8.0 GA 时,最受欢迎和使用最广泛的开源数据库终于在 cloud trinity 上实现了。第一个在云中提供 MySQL 8.0 升级的显然是 AWS,然后是 Azure,现在是 Google。

[## MySQL 8 现已登陆云 SQL |谷歌云博客

云 SQL 旨在提供不复杂的多层安全性,无论您是想保护您的…

cloud.google.com](https://cloud.google.com/blog/products/databases/mysql-8-is-now-on-cloud-sql)

MySQL 8 提供了一系列奇妙的功能,如在线 DDL、期待已久的窗口函数、增强的 JSON 功能、用于分层查询的递归公共表表达式(cte)、默认UTF8MB4排序&编码、软删除、不可见索引、递减索引、分阶段推出等等。Cloud SQL 确实提供了标准的安全特性,可以选择用自己的密钥加密数据。传输中加密和静态加密都受支持。您可以在 MySQL 服务器团队的以下博客文章中找到特性列表

[## MySQL 8.0 有什么新特性?(正式上市)

我们自豪地宣布 MySQL 8.0 正式上市。立即下载!MySQL 8.0 是一个非常令人兴奋的新版本…

mysqlserverteam.com](https://mysqlserverteam.com/whats-new-in-mysql-8-0-generally-available/?fbclid=IwAR1mUEwsOGtj4J7agfCAHeceQl9Pguya2Ecez_bPDfGNwt8nW7EnPnaiIMw)

要探索 MySQL 8.0 的详尽特性列表,请访问 MySQL 服务器团队发布的这篇博客文章

支持 BCP 的其他标准功能,例如通过使系统具有容错能力来实现高可用性,以及可以选择将相同的数据复制到多个区域。还有云 SQL 代理——

云 SQL 代理允许具有适当权限的用户连接到第二代云 SQL 数据库,而不必手动处理 IP 白名单或 SSL 证书。它的工作方式是在本地机器上打开 unix/tcp 套接字,并在使用套接字时代理到相关云 SQL 实例的连接。

如果您还没有将本地或云 MySQL 实例升级到 MySQL 8,现在正是时候。与每次升级一样,MySQL & SeveralNines 的以下博客文章中有许多警告(没有任何限制)

[## 从 MySQL 5.7 迁移到 MySQL 8.0 —您应该知道的

MySQL 8.0 在性能和安全性方面有重大改进,在此之前有几件事需要考虑…

severalnines.com](https://severalnines.com/database-blog/moving-mysql-57-mysql-80-what-you-should-know) [## 升级到 MySQL 8.0?以下是你需要知道的…

在我之前的博文中,我描述了从 MySQL 5.7 升级到…的就地升级步骤

mysqlserverteam.com](https://mysqlserverteam.com/upgrading-to-mysql-8-0-here-is-what-you-need-to-know/)

竞争对手

MySQL 最接近的竞争对手是 PostgreSQL。如果您尝试并理解这两个数据库的产品路线图,您会发现它们的目标都是做对方做的事情。PostgreSQL 大概是想实现一层存储引擎。另一方面,MySQL 正在尽力提供强大的 JSON、数组和地理空间支持。MySQL 最后引入了窗口函数。PostgreSQL 已经拥有它们很多年了。

优步的工程团队有一篇颇具争议的博文,是关于几年前他们为什么从 PostgreSQL 转向 MySQL 的。这是一本非常有趣的读物,但也受到了批评。

[## 为什么优步工程公司从 Postgres 转向 MySQL

优步的早期架构包括一个用 Python 编写的单片后端应用程序,用于数据…

eng.uber.com](https://eng.uber.com/postgres-to-mysql-migration/)

在过去几年中,谷歌在诸如 Airflow、Kubernetes 等开源工具的支持下,加速了其云扩张。并公开 Google 自己的高度可扩展的服务,如 BigTable。随着像 Kaggle 和 Looker 这样的收购,谷歌在未来几年的前景看起来很好。我想说的就是——在谷歌云平台上运行 MySQL 8.0 的时候要有安全感。

谷歌云 SQL 简介

围绕相关性的神话与现实

原文:https://towardsdatascience.com/myths-and-reality-around-correlation-9b359456d8e1?source=collection_archive---------45-----------------------

正确理解相关性概念的终极指南

图片霍尔格链接通过上 Unsplash

相关性是两个随机变量之间的统计关系。这是两个变量相关的程度。

正相关意味着两个变量同向变动,一个变量上升也会导致另一个变量上升,同样,一个变量下降也会导致另一个变量下降。类似地,当负相关时,变量向相反方向移动。相关性的概念广泛应用于数据科学和其他领域。找到变量之间的相关性是任何探索性数据分析的最基本和最重要的部分。

金融部门,相关性用于检查股票相对于市场和其他股票的运动(上涨和下跌)。在零售部门,相关性可用于查看一件商品的销售如何与其他商品的销售相关联,等等。

检查变量之间的相关性并丢弃高度相关的特征使得模型简单、直观和透明。这有助于消除多重共线性

说够了,言归正传,这个博客是关于什么的。这个博客是这个概念的实践指南。这篇博客也是关于相关性可以揭示什么,以及如何在不落入陷阱的情况下得到正确的结果。让我们从概念上开始深入探讨。

计算相关性

相关性解释了两个变量之间的依赖程度,即这两个变量是如何相关的。可以计算各种相关系数。一些著名的相关系数是皮尔逊相关系数斯皮尔曼等级相关系数

1.皮尔逊相关系数

皮尔逊相关系数计算如下:

图片来源~ 维基百科

其中ρ是随机变量“X”和“Y”之间的相关系数。

μ是变量的平均值,σ是变量的标准差。

E[]是期望值。

2.斯皮尔曼等级相关系数

斯皮尔曼相关系数计算如下:

图片来源维基百科

其中 X 和 Y 被转换成等级(rg)。剩下的公式与皮尔逊相关系数相同。Spearman 系数情况下的等级排序重新映射了 X 和 Y 的值,使其不同于 Pearson 系数。

关于 Spearman 等级相关系数最好的事情是,人们可以创建他们自己的等级排序函数,根据问题或用例来调整相关系数。

围绕相关性的神话与现实

1.相关性解释了依赖的程度

神话是相关性只能捕捉变量之间的线性关系。事实上,皮尔逊系数捕捉到了线性关系,但其他系数,如斯皮尔逊等级系数,也适用于许多(如果不是全部)非线性关系。

让我们看一个例子

y = (4x — 30)²¹

数据生成,

y = []
from random import randint
x = [randint(1, 100) for i in range(1000)]
for elem in x:
    y.append(math.pow((elem * 4 -30),21))

x 和 y 之间的非线性关系

计算相关系数,

Perason Coefficient Value 0.48
Spearman's Coefficient value 1.0

皮尔逊系数不能捕捉非线性关系,但斯皮尔曼的等级系数可以。

2.一个接近+1 或-1 的相关性,我们能推断出更多什么?

皮尔逊相关系数的值介于+1 和 1 之间,其中+1 表示完全正线性相关,0 表示没有线性相关,1 表示完全负线性相关。[[来源维基百科 ]]

假设您在数据集中观察到两个或多个变量的皮尔逊相关系数几乎为 1 或-1。这是什么意思?

一个人需要非常清醒,不要落入“”的陷阱,“相关性意味着因果关系”。事实上,关联并不意味着因果关系。但是,在这种情况下,我说的是相关系数几乎为 1 或-1 的特殊情况。而且显然有原因/关系。

有一篇关于为什么相关性并不意味着因果关系的文章。可以参考了解更多的话题。

[## 为什么相关性并不意味着因果关系?

相关性和因果关系是最容易被误解的术语,并且经常互换使用。了解这两者…

towardsdatascience.com](/why-correlation-does-not-imply-causation-5b99790df07e)

这意味着两个变量很有可能是从另一个变量派生出来的。神话是,即使在+1/-1 皮尔逊相关系数的情况下,找到公式/关系可能是困难的,因为我们不知道它会有多复杂。相反,事实是,无论线性关系有多复杂,它总是可以简化为 y = Wx + b 的形式,并且我们可以使用线性回归或线性方程求解器以高度的正确性来近似它。

让我们看一个例子,

y = (x * 7 - 30)/4 * 8 + 7

y 是用一些复杂的公式从 x 推导出来的。但是,我们总是可以把它简化成 y = Wx + b 的形式

在这种情况下,

y = 14x - 53

让我们首先检查相关系数值的值

y = []
from random import randint
x = [randint(1, 100) for i in range(1000)]
for elem in x:
    y.append(((elem * 7 - 30)/4) * 8 + 7)

将数据可视化,

x 和 y 之间的线性关系

计算相关系数

import scipy.stats
pearsonr(x,y),spearmanr(x,y)

结果:

Perason Coefficient Value 1.0
Spearman's Coefficient value 1.0

两者,相关系数导致 1

接下来,让我们运行一个回归,并验证假设,如果皮尔逊相关性接近+1 或-1,我们总是可以反向工程找到公式/关系。

reg = LinearRegression().fit(x,y)
print("Intercept: {} Coefficient: {}".format(reg.intercept_,reg.coef_))
y_pred = reg.predict(x)

导致,

Intercept: -53.00 Coefficient: [14.]

这才是真正的关系。

3.如何得到正确的相关系数?

神话是相关系数表示依赖程度。事实上,相关系数只有在计算方法正确的情况下才表示依赖程度。

两只股票在一段时间内有很高的正相关性并不一定意味着它们以相似的模式向同一个方向移动。当分析这两只股票在多个时期的市场下跌和上涨,然后找到相关系数,将给出正确的图片。

同样,两个显示相似或相反销售模式的项目可能只是由于促销或特定季节。在收集多个时间段的销售数据,然后计算相关系数之后,可以确定正确的关系。

结论

有很多关于相关性的文章。我试图提出一个不同的观点,揭示这个主题周围较少探索和隐藏的领域。这篇博客也是关于相关性可以揭示什么,以及如何在不落入陷阱的情况下得到正确的结果。希望你喜欢。

我的 Youtube 频道获取更多内容:

[## 阿布舍克·蒙戈利

嗨,伙计们,欢迎来到频道。该频道旨在涵盖各种主题,从机器学习,数据科学…

www.youtube.com](https://www.youtube.com/channel/UCg0PxC9ThQrbD9nM_FU1vWA)

关于作者-:

Abhishek Mungoli 是一位经验丰富的数据科学家,拥有 ML 领域的经验和计算机科学背景,跨越多个领域并具有解决问题的思维方式。擅长各种机器学习和零售业特有的优化问题。热衷于大规模实现机器学习模型,并通过博客、讲座、聚会和论文等方式分享知识。

我的动机总是把最困难的事情简化成最简单的版本。我喜欢解决问题、数据科学、产品开发和扩展解决方案。我喜欢在闲暇时间探索新的地方和健身。在 Linkedininsta gram关注我,查看我以前的帖子。我欢迎反馈和建设性的批评。我的一些博客-********

n 是敌人

原文:https://towardsdatascience.com/n-is-the-enemy-c72cc1ba683b?source=collection_archive---------38-----------------------

大量人口+大数据=严重失败

Joshua Coleman 在 Unsplash 上拍摄的照片

我们被卖给了一个虚假的承诺。

在某种程度上,我们欺骗自己,认为真理是数量的副作用。“如果我们收集了足够的数据,”我们说,“我们压倒性的统计能力将会在未知中炸出一个洞。”

相反,我们搬起石头砸了自己的脚。

在他的文章统计天堂&大数据中的悖论中,哈佛统计学家(在我看来,他是公认的天才)肖-李梦提供了一个严格的证据,证明当我们收集数据时,不管数据是如何收集的我们有多糟糕。

他利用了优雅而又深奥的数学——所以为了让大家理解他的观点,我将求助于现代技术作家的惯用手段:Javascript 模拟。

Javascript 模拟在大多数方面都过于简化,但是正好正确到足以给我们上几课。

首先,一些背景。

数据缺陷指数

统计学的一个基本承诺是:给定一个有限的样本,我们可以对更多的人群进行概括。

这是一个超级大国。这就是为什么科学可以作为一系列小的受控实验而不是一个完整的宇宙普查出现。这使得了解世界成为一项可行的任务。

但不是所有的样本都是一样的。不同的样本由不同的抽样机制创建:例如,随机电话拨号器、在线调查等。不管抽样机制在实践中采取什么形式,我们都可以抽象地把它们看作是总体上的二元掩码。

让我们把这个掩码 R 和人口数据它的掩码 G 。掩码值 R ᵢ —一个 0 或 1 开关—决定值是否包含在我们的样本中。

一个抽样机构 R. 红色的 R ᵢ元素选择大小为 G ᵢ的项目作为我们的样本。我们的样本量是 3。

在理想情况下,采样机制是完全随机的, R ᵢ和gᵢ(corr[rᵢ,g)之间的相关性为 0。但是通常情况下,取样机制在某些方面有轻微的缺陷。****

举一个荒谬而极端的例子,想象一个旨在评估客户群体对调查的热情的调查。如果我们的抽样机制(【r】)是一封电子邮件,要求参与者选择加入,并让我们衡量他们选择加入的热情(【g】),我们可以猜测 CORR[ R ᵢ,g将非常接近 1。******

有缺陷的采样机制 R. 由于 G 是按大小排序的,我们只挑选第一个项目的 R 会导致高corr[rt55】ᵢ、t57】gt59】ᵢ,因为我们只选择最大的项目。************

那个 CORR[ R ᵢ、g的值——或者更准确地说,𝔼【corr[rᵢ、g],虽然不是这个小数字是大数据统计工作中的扳手。正如我们将很快看到的,它对我们是否可以依赖大型数据集的洞察力有着巨大的影响。******

弹跳球

让我们用一个玩具例子来研究一下 d.d.i 的影响。

假设我们把 N 个球丢进一个空间。有些比其他的大,但是它们都有相同的能量。所以大的跳得很慢,而小的像兴奋的刺猬一样到处跑。球的大小来自正态分布。

假设你是一个球科学家(球学家?)并且你想估计这个小宇宙中球的平均半径。你的计划是对 n 个球进行抽样,收集样本平均值,并将其用作总体平均值的估计值。

但是有一个问题:不管出于什么人为的原因,你只能在球飞到指定的红色突出显示的取样区时进行取样。****

你可以在下面的采样区玩玩。

拖移滑块以调整采样区域的大小。取样球被涂成红色。n= 10; N = 75。****

你注意到了什么?

随着您滑动采样区域使其越来越包含空间,真实平均半径和采样半径之间的误差会减小。如果你向左滑动,使采样区域占空间的一小部分,误差就会上升。

原因很简单:球越小,它跑得越快。如果采样区域很小,很可能只有最快的球会从它们的起始位置到达那里。另一方面,如果采样区域很大,我们就更有可能公平地采样。

这使得取样区的宽度可以方便地模拟 d.d.i 。宽度越低, d.d.i 越高!

高 d.i .提高了估计误差。

我们从这个实验中得到了一个相当明显的发现:高的 d.d.i 会提高估计误差。

采样频率

让我们扩展一下,考察人口规模和样本规模对我们估计误差的影响。

n = 10;N=750

当我们将我们的人口规模放大 10 倍时,我们的误差对于每一个设定的d . d . I .都是一致的 T18 恶化 T19。这应该是意料之中的。球的数量越多,就有越多微小快速的球比其他球更快地被采样,缩小了半径的平均测量值。****

当我们相应地增加样本量来帮助估计时会发生什么?

n = 100;N=750

就错误率而言,n 增加 10 倍只会让我们回到起点。

当你有一个有缺陷的采样机制时,重要的是采样 频率,而不是样本大小。

这里有一个重要的教训。当你有一个非零的 d . d . I .时,你的样本的绝对大小正好等于 jack。当你有一个有缺陷的采样机制时,重要的是采样 频率 ( f = n/N ),而不是样本大小。

如果你想用高得离谱的采样频率来掩盖有缺陷的采样机制,你还不如做一次人口普查。

****n= 500;N= 750; f= 2/3。

科学家的杠杆

在这一点上,你很有希望确信 d.d.i 可以破坏估计,并且它唯一的缓解因素是放大的采样频率, f

肖-李梦博士的证明揭示了基于抽样机制的估计的均方误差的精确表达式:

其中𝛀是 G 分布中的方差,𝔼【corr[rᵢ,g]d.d.i 的精确公式, f 是采样频率。******

我们真的对𝛀无能为力,所以我们真正能利用的杠杆是:****

  • 通过良好的随机抽样机制减少 d.d.i。
  • 提高采样频率。

这与我们之前的实验结果非常吻合。

n 是敌人

一个阴险的发现落在上面的表达式。

如果我们尝试比较基于简单随机抽样的估计和依赖于抽样机制的估计,我们会得到一个叫做 设计效果(Deff)的度量。 Deff 本质上是告诉我们,相对于黄金标准,我们的特定采样机制会出错多少。**********

原来,通过一些巧妙的数学运算,这个 Deff 可以用 CORR[ R ᵢ、g和我们的人口规模 N: 来表示**********

呀。

为了保持 Deff 不变, R ᵢ 和 G ᵢ之间的相关性需要缩小 N. 的平方根的一个因子

这是肖的笑点。为了保持 Deff 不变, R ᵢ 和 G ᵢ之间的相关性需要随着 N 的增长而缩小 N 的平方根的因子。换句话说, CORR[ R ᵢ,g必须是o(√n),否则采样机构 R 将会产生大范围的 N 垃圾火结果。**********

为了保持 Deff 不变,所选取样机构 RCORR[ R ᵢ、g必须作为 N 的因子快速下降。******

仅有的表现如此的采样机制是随机的。也就是说,对于高 N,随机采样不仅仅是一个好主意:这是一个要求。

未能理解这一点导致我们疯狂地错误预测了 2016 年总统大选。我们不认为一点点反应偏差会影响我们的结果,尽管仅仅一点点就足以彻底摧毁我们。几乎不可避免地如此。

现在更相关的是:这就是为什么我们试图理解新冠肺炎的致命性是如此的漫无目的。

N 是我们的敌人,如果我们的抽样机制有缺陷,那么面对它,高样本量也无济于事。

它只会增加我们对几乎肯定是错误的结果的信心。

朴素贝叶斯:一个简单而方便的离散分类器

原文:https://towardsdatascience.com/naive-bayes-a-simple-but-handy-discrete-classifier-731fe133d8a8?source=collection_archive---------30-----------------------

而且终究不是幼稚!

几个月前,我发表了一篇介绍贝叶斯定理的文章。今天我将介绍贝叶斯定理在分类上的一个实际应用,朴素贝叶斯分类器。

(这是我关于贝叶斯定理的文章的链接。在阅读这篇文章之前,最好先理解它,否则你不会明白发生了什么。)

[## 贝叶斯定理如何应用于测试一种疾病(如冠状病毒)?

这是有用的,尤其是在这个冠状病毒疫情

towardsdatascience.com](/how-bayes-theorem-applies-to-test-a-disease-like-coronavirus-e63c38b3dbbe)

朴素贝叶斯分类器,它的名字已经告诉了你一切:利用贝叶斯定理在朴素假设下进行分类,也就是说特征与他人无关。

为了介绍朴素贝叶斯分类器是如何工作的,这里有一个例子(PS:一个例子总是好的,或者至少没有什么不好)

明天你将和你的朋友见面进行一场足球比赛。今天天气不好,现在你担心比赛会不会因为天气而取消。天气预报显示明天将刮风下雨。幸运的是明天不会有雷雨。问题是这场足球赛会不会取消?

维吉尔·卡亚萨在 Unsplash 上的照片

现在你回想一下天气是如何影响你之前的足球比赛的,于是你拿出了你的日记。?)并查看之前所有足球比赛的天气情况。你拿出下面的记录:

例如,当天气晴朗时,6 场比赛中有 5 场没有取消。当天气刮风时,10 场比赛中有 6 场被取消(有点悲哀)。现在是时候推出朴素贝叶斯分类器了。

朴素贝叶斯分类器的概念是在训练集的帮助下,根据观察到的属性值计算所有可能类的可能性。新实例的类将是可能性最高的类。用一个更通俗的术语来说,我们选择在观察条件下最有可能发生的一个。

那和贝叶定理有什么关系呢?

在独立性假设下,涉及多个事件的 Baye 定理的一般公式如下

b 是我们想知道的事件,Aᵢ是第 I 个观察到的事件。在朴素贝叶斯分类器中,B 是将基于那些观察到的事件分配的类。如果我们安排配方,

第二部分计算所有观察到的事件在没有任何前提条件下发生的概率,这与所选择的类别无关。因此,公式的第一部分是一个似然函数(如果你不知道什么是似然函数,这里是 wiki 链接)来确定应该分配哪个类。

回到你的足球比赛,现在你可以根据明天的天气预报和历史结果来计算“取消”和“不取消”的可能性。

表示 A₁是展望,A₂有风,A₃是雷雨。因此,

由于“取消”的可能性高于“不取消”,结果将是“取消”(太可悲)。

在这个例子中,观察到的事件都是离散的。在连续事件的情况下,分布通常被假设为正态分布,因此,如果每个类别下的平均值和标准偏差都是已知的,则可以使用通常的正态分布方法来计算概率。

上面的例子已经显示了朴素贝叶斯分类器的一个主要问题。假设所有观察到的事件都是独立的通常是不真实的。雷雨经常伴随着大雨和大风。

另一个问题被称为“零频率问题”,这意味着有一个新的观察结果,以前从未发生过。例如,在过去,没有龙卷风袭击你的邻居。突然明天就会有一个。那么你就不能计算任何类别下的概率。这个问题可以通过加法平滑(又名拉普拉斯估计器)来解决。

由于朴素贝叶斯分类器的简单性,它可以在没有大量计算的情况下提供快速预测。因此,它用于一些实时预测。它还可以用于多类预测,而不需要额外的努力。

朴素贝叶斯分类器的介绍到此结束。我希望您喜欢这篇文章,并了解更多关于离散分类的知识。下次见。

我的其他文章

现在学习如何掌握 Python 中的 groupby 函数

如果你是 Python 新手(尤其是自学 Python 的话),请将此加入书签

(第 2 部分)如果您是 Python 新手(尤其是自学 Python 的话),请将此加入书签

朴素贝叶斯分类器:贝叶斯推理,中心极限定理,Python/C++实现

原文:https://towardsdatascience.com/naive-bayes-classifier-bayes-inference-central-limit-theorem-python-c-implementation-bdffb3b35de?source=collection_archive---------18-----------------------

理解朴素贝叶斯分类器的数学基础

目录

  • 简介

  • 1。条件概率

  • 定义

  • 直觉

  • 快速示例

  • 链式法则

  • 2。独立性

  • 定义

  • 直觉

  • 快速示例

  • 3。条件独立性

  • 定义

  • 证明

  • 快速示例

  • 4。贝叶斯定理和朴素贝叶斯分类器

  • 定义

  • 证明

  • 5。中心极限定理和正态分布

  • 6。理论的实现

  • 7。结论

  • 8。资源和参考资料

介绍

在下面的文章中,将讨论贝叶斯理论的细节和相应的数学证明,然后使用编程语言 Python 和 C++在朴素贝叶斯分类器的上下文中实现该理论。这篇文章主要针对那些渴望深入了解贝叶斯推理惊人世界的人。值得注意的是,在介绍贝叶斯定理的概念之前,我们将讨论一些里程碑,对于这些里程碑,最少的概率论知识是先决条件。一旦理解了算法的数学基础,实现就会一路走下坡路。

1.条件概率

概率是数学的一个分支,它将样本空间的结果的概率度量进行公理化和形式化。样本空间是事件的集合,比如掷骰子得到 5。

定义

条件概率是在另一事件 B 已经发生的情况下,对事件 A 的概率度量。简单地说,如果两个事件相互关联,拥有其中任何一个事件的信息都会影响另一个事件的概率度量。在下面的等式 1.1 中,描述了给定事件 B 的事件 A 的条件概率度量。

直觉

图 1

等式 1.1 可以描述为事件 A 和 B 的交集的面积除以子空间 B 的整个面积。

快速示例

成年人中男性和酗酒者的比例为 2.25%。假设是男的,成为酒鬼的概率有多大?

转述一下问题,随机选择的个体,作为男人和酒鬼的概率是 2.25%。如果你已经知道一个人是男的,那么他酗酒的概率是多少?

假设 2 性别平均分布,是男的概率暗示 0.5。通过将所有给定的参数放入等式 1.1 中,我们得到 4.5%

基本上,拥有关于个体性别的额外信息会将我们的概率确定性从 2.25%提高到 4.5%。

链式法则

链规则是一种概率现象,它帮助我们使用条件概率的乘积来找到集合成员的联合分布。为了推导链式法则,可以使用等式 1.1 。首先,让我们计算两个事件 A 和 b 的联合概率。

利用同样的原理,我们也可以找到 3 个事件的联合概率——A,B,c。

通过比较方程 1.2方程 1.3 之间的模式,可以确定计算 N 个事件的联合概率的通用方程。

2.独立性ˌ自立性

如果一个事件的发生不影响另一个事件发生的概率,那么这两个事件就是独立的。[2]

定义

等式 2.1 可以清楚地看出,拥有关于事件 B 的信息不会影响事件 A 的概率度量- > P(A|B) = P(A)

直觉

如果事件 A 和 B 是独立的,那么拥有关于事件 B 的信息应该会像拥有来自论域 U 的任何信息一样影响事件 A 的概率度量(参见 图 1 )。

快速示例

如果掷骰子两次,得到两个 5 的概率是多少?

事件 A —第一次掷骰子获得 5 分
事件 B —第二次掷骰子获得 5 分

因为骰子上有六个不同的数字,所以得到 5 的概率为:

很明显,第一次得到 5(事件 A)并不提供关于事件 B 的任何信息。因此,由于事件 A 和 B 是独立的,因此事件 A 和 B 都得到 5 的概率为:

3.条件独立性

定义

给定 C,事件 A 和 B 是条件独立的当且仅当,给定 C 发生的知识,A 是否发生的知识不提供关于 B 发生的可能性的信息,并且 B 是否发生的知识不提供关于 A 发生的可能性的信息。[3]

基本上,R 和 B 是人 AB 及时回家吃晚饭的事件,Y 是暴风雪袭击城市的事件。当然,RR 和 BB 的概率将取决于 YY 是否发生。然而,就像假设如果这两个人没有任何关系,他们及时回家的概率是独立的一样,这似乎是合理的

证明

等式 3.1 中的模式也可以应用于 N 个条件独立事件:

4.贝叶斯定理和朴素贝叶斯分类器

定义

贝叶斯定理是一个强大的工具,它使我们能够根据给定的先验知识和证据来计算后验概率。这与对数据进行训练并获得有用的知识以进行进一步预测的原理相同。

  • P(y|x) — 后验 —给定事件 x 发生的情况下,事件 y 发生的概率。
  • P(x|y) — 可能性 —给定事件 y 发生的情况下,事件 x 发生的可能性。
  • P(y) — 先验 —在获得某些知识/证据 x 之前,关于未知事件发生的概率测度的信念 y
  • P(x) — 证据 —作为计算后验概率的证据给出的一条信息

证明

对于机器学习分类和预测任务,通常给我们的是特征向量 X = (x1,…,xn)和对应的类别标签 y = (1,…,m)。特征行向量可以被假设为特征的联合概率。因此,等式 4.1 变为:

现在向量 X 的特征将被假设为独立事件以简化模型复杂性。然后,4.2 将通过挪用方程 3.2 而进一步简化。

的确,独立性假设是这种方法被称为“ 【幼稚 ”的主要原因。因为在现实世界的应用中,很有可能特征是相互关联或相互依赖的。尽管有“天真”的假设,模型复杂性的简化有时会产生令人惊讶的有用性能。

等式 4.3 将帮助我们通过比较不同类别参数-y 的后验概率的度量来预测给定特征向量 x (x1,…xn)的类别。然后,具有对应于该类别的最高值的后验将被选择为未知特征向量 x 的类别。

假设方程的分母在不同类别 y 的比较过程中保持不变,可以只比较方程的分子部分,这将进一步简化过程。

上面的等式(4.5)足以预测给定特征向量的类别。然而,考虑到概率测度的取值范围在 0 到 1 之间,拥有几个概率测度的乘积会导致算术下溢的问题[5]。幸运的是,这个问题可以很容易地通过取等式 4.5 的对数(基数应该大于 1)来解决。

在等式 4.6 中,需要 2 个参数来预测特征向量的类别标签 x

  1. P(y) — 先验 —在考虑证据(特征向量)之前,类别标签 y 的概率分布是一个先验概率,与其在训练集中的出现频率有关。基本上,对于示例性给定的标签集 < 0,0,1,1,1 > ,类‘0’的先验是 2/5。

2.P(x₁| y)… P(xₙ| y) —对于分类问题,虽然 y —类标签的值是离散的,但特征向量 x 的值通常是连续值,如表 1 所示。

表 1

因此,我们需要一种特殊的工具,这将有助于我们获得有关某些事件发生的可能性的信息。例如,如果类 1.0 的对应特征值是 1.898,那么如果特征值是 1.897,那么拥有 1.0 的可能性是多少?

5.中心极限定理和正态分布

中心极限定理指出,如果您有一个均值为μ、标准差为σ的总体,并从替换为的总体中抽取足够大的随机样本,那么样本均值的分布将近似为正态分布。[7]

正态分布:资源与参考文献【6】

简单地说,在概率论和自然界中,正态分布近似于随机量偏离“真实”(平均)值的模式。举个例子:

下面的直方图描述了泰坦尼克号事故中幸存/死亡乘客的年龄分布。在这里也可以看到上述的正态分布模式。

图 2

通过考虑独立随机变量的一般分布模式,我们将假设对于每个类,特征列的值也是正态分布的。因此,每个类别的列值的平均值将代表该类别的“真实”特征值。未知的特征向量与某一类别的平均特征值的接近程度将代表它们有多可能相同。为了表示这种相似性的度量,我们将使用高斯概率密度函数(高斯 PDF)。

图 3

图 3 显示了两类特征的分布。每个类别都有自己的平均值和标准偏差值,并在图的图例上显示精确值。所以:

  • P( x | μ ,σ ) ≈ 0.125
  • P( x | μ ,σ ) ≈ 0.025

因此,x 成为类“0”的可能性大于类“1”。

6.理论的实施

考虑到它的广泛使用,将在 Python 编程语言上解释它的实现。然而,相同的代码实现已经在 C++中实现,并添加到参考资料和参考资料部分的项目代码链接中。[9]

由于便于使用,算法将以类结构代码的形式编写。该类将接受两个参数:

  • x-训练特征集
  • y-标签集

下一步是编写“fit”函数,在此过程中,特性列的平均值和标准值被存储到定义的列表中。这个过程也可以称为训练。

一旦计算了类别的相应平均值和标准值,就可以预测未知特征向量的类别。

为了测试算法的性能,我们可以使用“sk learn”python 模块随机生成数据,然后将其拆分为训练和测试数据集。

正如你所看到的,基于“天真”假设的算法非常有效,准确率超过 90%。关于随机生成的数据集特征,准确度的值可以增加/减少。

7.结论

我希望这篇文章充分挖掘了朴素贝叶斯分类器的主题。如果你对这篇文章有任何意见/建议,你可以通过我的推特账号联系我。

8.资源和参考资料

[1] 维恩图—维基百科
【2】独立性—维基百科
【3】条件独立性—维基百科
【4】数学 StackExchange 问题答案—有人能解释一下条件独立性吗?
【5】算术下溢—维基百科
【6】正态分布—维基百科
【7】中心极限定理
【8】马尔可夫链的起源|信息论之旅|计算机科学|可汗学院
【9】朴素贝叶斯分类器‘Python/c++’项目代码

朴素贝叶斯分类器-解释

原文:https://towardsdatascience.com/naive-bayes-classifier-explained-50f9723571ed?source=collection_archive---------8-----------------------

scikit-learn 的理论和实现

朴素贝叶斯是一种用于分类任务的监督学习算法。因此,它也被称为朴素贝叶斯分类器。

与其他监督学习算法一样,朴素贝叶斯使用特征对目标变量进行预测。关键区别在于,朴素贝叶斯假设特征是相互独立的,特征之间没有相关性。然而,现实生活中并非如此。这种特征不相关的天真假设是这种算法被称为“天真”的原因。

在这篇文章中,我将首先介绍一些关于概率的基本概念,并展示朴素贝叶斯分类器的核心——贝叶斯定理是如何推导出来的。然后,我将展示朴素贝叶斯分类器如何建立在贝叶斯定理之上,以及朴素贝叶斯的优点/缺点及其在 scikit-learn 上的实现。

概要:

  1. 概率和条件概率
  2. 贝叶斯定理
  3. 朴素贝叶斯分类器
  4. 朴素贝叶斯分类器的利与弊
  5. Scikit-learn 实现

概率和条件概率

我们已经知道了“天真”的来源。“贝叶斯”怎么样?贝叶斯来自托马斯·贝叶斯著名的贝叶斯定理。要全面理解贝叶斯定理,先说概率和条件概率。

概率只是指事件发生的可能性,通常取 0 到 1 之间的值(0 和 1 包括在内)。事件 A 的概率被表示为 p(A) ,并且被计算为期望结果的数量除以所有结果的数量。例如,当你掷骰子时,得到小于 3 的数字的概率是 2 / 6。期望结果的数量是 2 (1 和 2);总结果数为 6。

条件概率是在与事件 A 相关的另一事件已经发生的情况下,事件 A 发生的可能性。假设我们有 6 个蓝色球和 4 个黄色球放在两个盒子里,如下图所示。我让你随机选一个球。得到蓝球的概率是 6 / 10 = 0,6。如果我让你从盒子 A 中选一个球呢?选到蓝球的概率明显降低。这里的条件是从明显改变事件概率的盒子 A 中选择(选择一个蓝球)。假设事件 B 已经发生,事件 A 的概率表示为 p(A|B)

在介绍贝叶斯定理之前,还有一个概念需要学习。联合概率是两个事件一起发生的概率,表示为 p(A 和 B) 。对于独立的事件,联合概率可以写成:

p(A 和 B) = p(A)。p(B)…………(1)

假设我掷骰子,掷硬币。得到 1 和正面的概率是:

(1 / 6).(1/2) = 1/12 = 0.08

为了使计算正确,事件必须独立于。抛硬币的结果对掷骰子的结果没有任何影响,所以这些事件是独立的。让我们也举一个依赖事件的例子。我从一副牌中选了一张,又从同一副牌中选了第二张。在第二次选择中某一特定观察值肯定受第一次选择影响的概率。在非独立事件的情况下,等式 1 无效。应该稍微修改一下,使其适用于任何两个事件:

p(A 和 B) = p(A)。p(B | A)…………(2)

等式(1)是等式(2)对于独立事件的特例,因为如果事件 B 和事件 A 独立, p(B|A) = p(B)。

贝叶斯定理

我们将从任意两个事件的联合概率是可交换的这一事实开始。那就是:

p(A 和 B) = p(B 和 A)…………(3)

从等式 2 中,我们知道:

p(A 和 B) = p(A)。p(B|A)

p(B 和 A) = p(B)。p(A|B)

我们可以将等式 3 改写为:

p(一)。p(B|A) = p(B)。p(A|B)

用 p(B)除两边给出了贝叶斯定理:

现在我们对贝叶斯定理有了理解。是时候看看朴素贝叶斯分类器是如何使用这个定理的了。

朴素贝叶斯分类器

朴素贝叶斯是一种用于分类的监督学习算法,因此任务是在给定特征值的情况下找到观察值(数据点)的类别。朴素贝叶斯分类器计算给定一组特征值(即 p(yi | x1,x2,…,xn))的类的概率。把这个输入到贝叶斯定理中:

p(x1,x2,…,xn | yi) 表示给定类别标签的特征的特定组合的概率。为了能够计算这一点,我们需要非常大的数据集来估计所有不同特征值组合的概率分布。为了克服这个问题,朴素贝叶斯算法假设所有特征都是相互独立的。此外,分母(p(x1,x2,…,xn))可以被移除以简化方程,因为它仅归一化给定观察值的类的条件概率的值(p(yi | x1,x2,…,xn))。

一个类的概率(p(yi))很容易计算:

在特征相互独立的假设下, p(x1,x2,…,xn | yi) 可以写成 :

给定类标签(即 p(x1 | yi))的单个特征的条件概率可以更容易地从数据中估计出来。该算法需要独立地存储每个类别的特征的概率分布。例如,如果有 5 个类别和 10 个特征,则需要存储 50 个不同的概率分布。分布的类型取决于特征的特性:

  • 对于二元特征(Y/N,真/假,0/1):伯努利分布
  • 对于离散特征(即字数):多项式分布
  • 对于连续特征:高斯(正态)分布

通常用特征分布来命名朴素贝叶斯(即高斯朴素贝叶斯分类器)。对于混合型数据集,不同的要素可能需要不同类型的分布。

将所有这些加起来,对于朴素贝叶斯算法来说,计算观察一类给定值的特征的概率( p(yi | x1,x2,…,xn) ) 变得很容易

朴素贝叶斯算法的利弊

优点:

  • 所有特征都是独立的假设使得朴素贝叶斯算法比复杂算法更快。在某些情况下,速度优先于更高的精度。
  • 它可以很好地处理文本分类、垃圾邮件检测等高维数据。

缺点:

  • 所有特征都是独立的假设在现实生活中并不常见,因此这使得朴素贝叶斯算法不如复杂算法准确。速度是有代价的!

Scikit-learn 实现

首先导入依赖项:

我将使用 scikit-learn 上的一个可用数据集(乳腺癌)。scikit-learn 的 train_test_split 模块用于将数据集分为训练集和测试集,以便我们可以首先训练模型,然后在新的、以前未见过的数据上测量其性能。

然后,我们加载数据集,并将其分为训练集和测试集:

然后,我们创建一个高斯朴素贝叶斯分类器对象,并使训练数据适合分类器:

最后,我们在训练集和测试集上测试了分类器的性能。

准确度相当高,但这是一个简单的任务,用于展示概念并完成实施步骤。需要记住的一件重要事情是,训练集的精度不应该比测试集的精度高很多,这表明我们的模型太具体,没有很好地概括。这导致过拟合,这对于任何机器学习算法都是一个严重的问题。

感谢您的阅读。如果您有任何反馈,请告诉我。

我的其他帖子

朴素贝叶斯分类器解释

原文:https://towardsdatascience.com/naive-bayes-classifier-explained-54593abe6e18?source=collection_archive---------13-----------------------

朴素贝叶斯分类器解释。介绍朴素贝叶斯分类器背后的逻辑,并详细解释数学原理。

朴素贝叶斯分类器是一个简单的模型,通常用于分类问题。它背后的数学很容易理解,基本原理也很直观。然而,该模型在许多情况下表现得令人惊讶地好,并且该模型及其变体被用于许多问题。因此,在本文中,我们将解释模型背后的数学和逻辑,并在 Python 和 Scikit-Learn 中实现一个朴素贝叶斯分类器。

凯文·Ku 在 Unsplash 上的照片

本文是关于朴素贝叶斯分类器的两个小型系列的一部分。这将涵盖分类器背后的理论、数学和原理。如果您对使用 Python 和 Scikit-Learn 实现更感兴趣,请阅读另一篇文章,Python 和 Scikit-Learn 中的朴素贝叶斯分类器教程

机器学习中的分类任务

机器学习中的分类任务负责将一系列输入 X = [x1,x2,…,xn]映射到一系列概率 Y = [y1,y2,…,ym]。这意味着给定一组特定的观察值 X = (x1,x2,…,xn),我们需要找出 Y 是 yi 的奇数,并且为了获得分类,我们只需要选择最高的 yi。

等等,什么?

是的,我知道,我也不喜欢这样解释这些事情。我知道一个正式的解释是必要的,但是让我们也用另一种方法来试一试。让我们用这个虚构的表格来预测一个城市是否会发生交通堵塞。

朴素贝叶斯分类器—数据表

因此,在分类任务中,我们的目标是训练一个分类器模型,它可以从左侧获取信息(外面的天气、今天是哪一天以及一天中的什么时间),并可以预测该城市是否会遇到交通堵塞。

注意:这个表格看起来很简单,因为我们只有几个数据点。但是在现实世界中,我们会有更多的信息,每个数据点会有更多的值。我用这个简单的表格来解释只是为了简单。

回到之前的解释,我们会进食

X =[晴朗,工作日,早晨]

给我们的模型,然后我们的模型会返回给我们

Y = [y1,y2]

其中 y1 是不堵车的概率, y2 是堵车的概率。我们只需要选择最高的概率,我们就完成了,我们得到了我们的预测。

更正式的表达方式是,我们需要计算一个条件概率,即给定 X=(x1,x2,…,xm)的情况下,Y 是 Y 的概率。

P(Y=y|X=(x1,x2,…,xm))

朴素贝叶斯分类器

贝叶斯定理告诉我们如何计算这个条件概率。让我们看看这个等式。

朴素贝叶斯分类器——贝叶斯定理。来源:维基百科

  • P (A | B)是一个条件概率,它给出了事件 B 发生的概率
  • P (B | A)是另一个条件概率,现在很清楚,它给出了事件 B 发生的概率,因为事件 A 已经发生了。
  • P(A)和 P(B)是事件 A 和 B 发生的概率。

但是为什么是朴素贝叶斯呢?

我们从概率论中知道,如果 X1 和 X2 是独立的值(这意味着,例如,天气下雨和今天是周末是完全独立的,它们之间没有条件关系),那么我们可以使用这个等式。

独立概率

在我们的例子中,这个假设是正确的。今天下雨的事实绝对不会受到今天是星期六的事实的影响。但一般来说,这种假设在大多数情况下并不成立。如果我们观察一个分类任务的大量变量,很可能这些变量中至少有一些是相关的(例如,教育水平和月收入)。

但是朴素贝叶斯分类器之所以被称为朴素,只是因为它是基于这种假设工作的。我们认为所有观察到的变量都是独立的,因为使用上面的等式有助于我们简化接下来的步骤。

所以让我们回头看看我们的表,看看发生了什么。假设天气晴朗,今天是工作日,现在是早上(我们表格中的第一行),让我们试着看看发生交通堵塞的概率是多少。

交通堵塞的可能性

不,我们只需要扩展它,这样我们就可以把这个方程变成一个只包含基本概率的方程。

扩展方程

从这里开始,我们已经可以计算每一个概率,例如:

朴素贝叶斯分类器-交通堵塞的概率

你可以看到这已经成为一个痛苦的过程。你可能会有疑问,因为这个模型背后的直觉看起来非常简单(尽管计算如此多的概率可能会让你头疼),但它确实工作得非常好,并且在如此多的用例中使用。让我们看看其中的一些。

朴素贝叶斯分类器—应用和用例

  • 实时分类-由于朴素贝叶斯分类器的工作速度非常非常快(与其他分类模型相比快得惊人),因此它被用于需要对中小型数据集进行快速分类响应的应用程序中。
  • 垃圾邮件过滤——这是您最常听到的分类器用例。它广泛用于识别邮件是否是垃圾邮件。
  • 文本分类—朴素贝叶斯分类器在文本分类方法中非常有效。
  • 朴素贝叶斯分类器通常非常适合多类分类,即使它使用了非常朴素的假设,它仍然优于其他方法。

朴素贝叶斯分类器的作用

如果你和我一样,所有这些理论几乎都没有意义,除非我们看到分类器在运行。让我们看看它在现实世界中的应用。我们将使用 Python 中的 Scikit-Learn 实现并使用数据集。这是一篇相当长的文章,所以为了使它更容易,我把这个主题分成了一个由两篇文章组成的迷你系列。关于 Python 和 Scikit-Learn 中的实现,请阅读 Python 和 Scikit-Learn 中的朴素贝叶斯分类器教程。

本文原载于 程序员背包博客 。如果你想阅读更多这类的故事,一定要访问这个博客。

非常感谢您阅读本文!对更多这样的故事感兴趣?在 Twitter 上关注我,地址是@ b _ dmarius,我会在那里发布每一篇新文章。

使用 C++从头开始的朴素贝叶斯

原文:https://towardsdatascience.com/naive-bayes-implementation-from-scratch-using-c-51c958094041?source=collection_archive---------20-----------------------

关于如何使用 C++实现机器学习基础的工作代码教程

aive Bayes 是一个概率算法家族,它利用概率论和 Bayes 定理来预测结果。这是通过基于可能与结果相关的条件的先验知识计算每个可能结果的概率来给出的。

“我们的信念基于我们的经验,这给了我们一个非常不完整的世界图景,我们很容易得出错误的结论。”
― Pedro Domingos,大师算法:对终极学习机器的探索将如何重塑我们的世界

亚历克斯·钱伯斯在 Unsplash 上的照片

朴素贝叶斯假设:

基本的朴素贝叶斯假设是:

  • 假设每个特征都独立于
  • 每个特征对结果的加权贡献是相同的。

实际上,这些假设使得朴素贝叶斯被称为“朴素的”,因为在现实世界中,独立性关系是不正确的。

查看本文作者克里斯·迪南:

[## 朴素贝叶斯有什么幼稚的?

朴素贝叶斯(NB)是“朴素”的,因为它假设一个度量的特征是独立的…

towardsdatascience.com](/whats-so-naive-about-naive-bayes-58166a6a9eba)

这篇文章是解决机器学习算法在 C++中实现的系列文章的一部分,在整个系列中,我们将使用 C++特性实现基本的机器学习算法。

朴素贝叶斯定理;

朴素贝叶斯理论超出了本文的范围,但是如果需要查看这些资源来帮助您更好地理解朴素贝叶斯理论,我推荐阅读下面这篇由 Rohith Gandhi 发表的文章和其他文章。

[## 朴素贝叶斯分类器

什么是量词?

towardsdatascience.com](/naive-bayes-classifier-81d512f50a7c) [## 朴素贝叶斯算法是如何工作的?(带示例和完整代码)| ML+

朴素贝叶斯是一种基于贝叶斯定理的概率机器学习算法,广泛用于各种…

www.machinelearningplus.com](https://www.machinelearningplus.com/predictive-modeling/how-naive-bayes-algorithm-works-with-example-and-full-code/) [## 用 Python 和 R 语言学习朴素贝叶斯算法的 6 个简单步骤

注意:本文最初发布于 2015 年 9 月 13 日,更新于 2017 年 9 月 11 日概述了解其中一个…

www.analyticsvidhya.com](https://www.analyticsvidhya.com/blog/2017/09/naive-bayes-explained/)

实施演练:

在本文中,我们希望实现以下内容:

目标实施结构

第一行是分类器实例声明,这是我们告诉编译器创建一个分类器实例并声明所有的类私有和公共变量的地方。

首先,我们需要定义类,定义类的合适位置是在 Naive_bayes.h 文件中,

朴素贝叶斯类定义和类实现的帮助函数

我们创建了一个名为 Naive_Bayes 的类,包含两个公共方法 fit()和 predict()。这些方法将用于数据训练和测试。它也有一些私有向量,我们将在上面存储模型信息,我们马上就会知道这些变量中到底存储了什么。

其次,我们需要定义类的方法。我们需要定义 fit()方法,现在是解释朴素贝叶斯模型中 fit 方法的功能的时候了。

拟合方法:

从我们对朴素贝叶斯定理的理解中,我们需要知道以下的概率:

P(类=0|X1,X2)= P(X1 |类=0) * P(X2 |类=0)* P(类= 0)

这意味着如果我们有 X1,X2 特征数据,我们有某一类的概率是多少,换句话说,如果我们有一株萼片长度为 5.1,萼片宽度为 3.5 的植物,这株植物属于鸢尾类的概率是多少。这可以通过将给定类别 0 的 X1 的概率乘以给定类别 0 的 X2 的概率以及类别 0 本身的概率来计算。为了更好地理解这个方程的来源,请回到朴素定理一节。

所以我们需要计算每个类的概率和每个值可能属于这个类的概率。我们将使用正态分布来计算概率。在其他文章中,我们描述了如何计算平均值和标准差。

平均值计算 API

标准偏差计算 API

如果您需要更多关于它们的实现的信息,请重新阅读这篇文章。

为了使用正态分布获得概率,我们将使用以下函数:

使用正态分布计算 pdf 的函数

下一步是计算每个要素的每个类的平均值和标准差,我们称之为类摘要。

用于计算课程总结的函数

类别概要是由包含每个特征的平均值和标准偏差的二维向量和包含类别概率的变量组成的结构。

一个结构包含类摘要

因此,calculate_Class_Summary 函数将负责为 fit 函数中的每个类填充 Naive_Bayes 类私有向量。

朴素贝叶斯模型的拟合函数

请注意,该函数是通用的,将使数据适合您拥有的尽可能多的要素,因为它从标签向量中提取唯一的标签,然后使用这些标签来迭代和计算每个标签摘要,然后将它们打包到类私有成员摘要中。

预测方法:

正如我们之前所说,目标是计算给定数据的分类概率

P(类=0|X1,X2)= P(X1 |类=0) * P(X2 |类=0)* P(类= 0)

在预测步骤中,我们使用此等式来评估每个类的概率,并查看数据更有可能属于哪个类。

朴素贝叶斯模型的预测方法

前面的函数使用测试数据来获取这些数据属于每个类要素的概率,并获取计算出的最大值的索引。该索引将是数据最可能属于的特征索引。

为了计算每个类别的概率,我们使用以下函数:

通过分类汇总计算数据的概率

它使用之前计算的类摘要来计算每个特征的概率,然后将概率乘以类的概率。注意,这个函数是朴素贝叶斯定理等式的实际实现。

P(类=0|X1,X2)= P(X1 |类=0) * P(X2 |类=0)* P(类= 0)

评分:

我们将实现一个简单的评分函数来比较预测和实际标签,并返回匹配的百分比。

函数来计算预测和标签之间的匹配百分比

综上所述:

实现朴素贝叶斯的一个例子

结果呢

正如你所看到的,这个算法的分数非常好~对于一个简单的算法来说,93%的准确率是非常好的。

在下一篇文章中,我们将实现另一个算法,并将结果与朴素贝叶斯算法得分进行比较。

推荐书籍:

“从昨天学习,为今天而活,对明天充满希望。重要的是不要停止质疑。”~阿尔伯特·爱因斯坦

希望这篇文章对您有用,请关注本系列新文章发布时的通知。

您可能也会发现这些文章很有用。

[## 什么时候应该用 C++学习机器学习?

机器学习的科学家、开发者和用户指南。

medium.com](https://medium.com/ml2b/when-should-you-learn-machine-learning-using-c-6edd719f95ff) [## 每个开发人员必读的 8 本 C++编程书籍。

从哪里开始学 C++,业内专家写的。

medium.com](https://medium.com/coderbyte/the-8-c-programming-books-each-developer-must-read-da5ce755429f) [## C++中的数据预处理和可视化

关于如何使用 C++实现机器学习的基本功能的工作代码示例

towardsdatascience.com](/data-preprocessing-and-visualization-in-c-6d97ed236f3b) [## 使用 C++进行数据操作

关于如何使用 C++实现机器学习的基本功能的工作代码示例

towardsdatascience.com](/data-manipulation-using-c-389d6c4493b1) [## 加入我的介绍链接媒体-艾哈迈德哈希什

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@ahmhashesh/membership)

自然语言处理中的命名实体识别

原文:https://towardsdatascience.com/named-entity-recognition-in-nlp-be09139fa7b8?source=collection_archive---------3-----------------------

真实世界的用例、模型、方法:从简单到高级

玛丽安·龙在 Unsplash 上的照片

在自然语言处理中,命名实体识别(NER)是识别和提取文本中特定类型实体的问题。如地名。事实上,任何有名字的具体“事物”。任何程度的特异性。职位名称公立学校名称体育名称音乐专辑名称音乐人名称音乐流派,…你明白了。

正如我们将在下面看到的,NER 既是 NLP 中一个有趣的问题,也有许多应用。首先,我们来看一个具体的例子。

例子

Wimbledon is a tennis tournament held in the UK in the first two weeks of July every year. In 2019, the men’s singles winner was Novak Djokovic who defeated Roger Federer in the longest singles final in Wimbledon history.

我们可能会提取实体

**Person name(s)**: Novak Djokovic, Roger Federer
**Sport name(s)**: tennis
**Country name**: UK
**Month**: July
**Year**: 2019

让我们思考一下如何使用上面例子中提取的实体(和想象中的扩展)。这将揭示一些将在 NER 的各种用例中发挥作用的想法。然后我们将讨论用例——在这些想法的“肩膀”上。

发现课文主题:这个例子是关于网球运动和两个运动员的。似乎少了些关于国家(英国),或者月份(七月),或者年份( 2019 )。从一整篇文章中,也就是说,远远不止两句话,我们也许能够强化(或反驳)这种评价。

例如,如果文章中频繁提到诺瓦克·德约科维奇,可能就是关于他的。另一方面,如果网球被频繁提及,而每个球员只被提及几次,那么这篇文章可能更多地是关于网球的。如果文章中还提到了其他人的名字,那就更是如此了,每个名字只出现几次。

如果 2019 在文章中被反复提及,或许文章讲的就是当年的锦标赛。

发现实体之间的关系:假设我们有一个大的语料库。比如罗杰·费德勒这个名字经常出现在网球运动附近。推断这两者有关联是合理的。事实上,这个推论只是该类型的一个具体实例:

“statistical co-occurrence” (usually with some qualification added) implies association. 

在我们的例子中,限定条件是我们把自己局限于实体,而不是文本中任意的单词或短语。另外,我们知道每个实体的类型。

我们应该给一个推断出的关联赋予什么样的力量?这里就不赘述了。好奇的话谷歌关联规则信心解除

因此,从一个大的语料库中,通过高质量的 NER 方法,我们可以构建一个所谓的实体图。图形的节点是实体,带有附加的属性,如实体类型。该图是有向的。图上的每个弧都有一个属性,该属性捕捉有向关联的强度。弧可能有额外的元数据。

接下来,我们来讨论具体的用例。

搜索

一个重要的是在网络搜索中。通过理解查询中的实体,搜索引擎可以提供更好的结果。谷歌使用这种方法。

让我们更详细地讨论这个问题。传统上,搜索引擎使用一种叫做关键词搜索的方法。该文件是按其中出现的词来编索引的。通过计算哪些查询词出现在文档中并适当地加权每个命中,为文档与查询的相关性评分。命中,即出现在文档中的查询词,通过称为 TF-IDF 的因子来加权。这是基于该词在文档中的频率,并根据其在语料库中的稀有程度进行调整。因此,如果查询包含一个不常见的单词,并且该单词在文档中出现得非常频繁,则该文档与查询的相关性很高。有道理对吗?

关键词搜索肯定很有用。然而,可以通过增加实体识别来进一步改进它。此外,这还利用了在文档中找到的关于主要实体的知识,以及对它们在该文档中所扮演角色的重要性的判断。

除了提高相关性,这种方法还有另一个主要好处。如果查询包含已识别的实体,搜索引擎还可以返回关于它们的关键事实。读者可能已经在谷歌上看到了这一点。输入巴拉克·奥巴马作为搜索词。搜索引擎理解这个实体。它使用这种理解来返回关于奥巴马的其他关键事实。比如从他的维基百科页面上搜集到的信息。还有他的照片。

由实体(除了实体识别之外)支持的搜索引擎可以进一步提高搜索相关性。他们可以提供更好的建议,比如人们所看到的“人们也在搜索”的那种。

索引文件

另一个重要的应用是对网页或在线文章等文本文档进行编目或索引。这包括提取文档中的重要实体,并使用这些实体对文档进行索引。在线杂志和新闻出版商经常这样做。当然还有搜索引擎。

下面是考虑这种相关性的一种方法。文档更可能是关于文档中频繁提及的实体,而不是频繁提及的任意单词。也就是说,实体检查充当质量过滤器。

产品评论

第三个用例是在零售环境中从在线评论中提取产品名称或其他重要实体。这些评论可能来自电子商务网站或社交媒体网站。很明显,了解特定评论中讨论的是哪些产品和功能是很有用的。作为一个例子,考虑审查

I like my new XYZ smartphone but the camera sucks

XYZ 智能手机相机 是我们想要提取的实体。我们还想提取情感词,如sucks ,并将每个词与正确的实体相关联。情绪分析超出了本文的范围。除了说情感也可以被建模为实体。例如,我们可能有两种实体类型正面情感负面情感,其中类似于前者的一个实例吸收了后者的一个实例。情感分析已经被广泛研究。还有更先进的方法。

然后,评论可以被自动分类到它们所应用的产品或其他突出的实体下。由此产生的分组也可以揭示新的见解。比如人们抱怨(或称赞)最多的是哪些产品或功能。

电子邮件中的实体

第四个用例是从电子邮件中检测和提取实体,并自动触发某些操作。许多读者可能已经在他们自己的智能设备上看到了这种情况。举个例子,假设你收到一封来自航空公司的电子邮件,确认你购买了一张机票。最先进的电子邮件引擎可以自动提取相关信息(航空公司、出发日期和时间等),并从中在您的数字日历中创建一个条目。这里的实体是航空公司名称日期时间,其中日期时间标记为出发

从语料库中构建结构化数据库

第五个用例是通过从语料库中识别所需类型的实体来构建结构化数据库。例如,我们可以通过抓取 web 并识别这种类型的实体来建立医疗疾病名称的数据库。(顺便说一下,纯粹基于字典的识别方法是行不通的,因为我们要找的结果就是那个字典。)

这种专门的名单是有市场的。有一些利基供应商已经通过销售这样的列表赚了一段时间的钱。

走向构建本体

第六个用例实质上是从一个文档集(比如网页或公司内部的文档)构建一个实体图。它也可以被看作是第五种用例的增强版本,其中实体之间的关系也被推断出来。

节点是被识别的实体。弧来自足够频繁地足够接近的实体对。对于弧上更精细的点,如权重,请参见前面的讨论。

除了前面提到的实体图的用途,深度和丰富的特定领域本体作为数据产品提供也有市场,例如,在利基电子商务网站上改进浏览和搜索。自动实体识别和 arcs 推理与人工管理的某种结合具有很大的潜力。有利基公司在这个领域赚钱。

实体识别算法

接下来,我们讨论识别和提取实体的各种方法,从最简单的到更高级的。我们还讨论了它们的优点和局限性。我们还描述了如何以及为什么组合一些互补的简单方法来构建更高级的方法。

基于字典的

这是最简单的一种。对于要识别的每种实体类型,我们都有一个值字典。为了识别和提取实体,我们只需扫描文本并在各种字典中找到匹配项。命中还揭示了实体类型,因为我们知道被命中的字典。

这里有一个简单的例子。

假设我们有以下字典:

**Month** = January, February, …, July, …, December
**Country** = USA, United States, UK, United Kingdom, France, …
**Person First Name** = John, Roger, Jim, …
**Person Last Name** = Smith, Green, …

考虑我们之前看到的文本。

Wimbledon is a tennis tournament held in the UK in the first two weeks of July every year. In 2019, the men’s singles winner was Novak Djokovic who defeated Roger Federer in the longest singles final in Wimbledon history.

提取的实体是

**Month** = July, **Person First Name** = Roger, **Country** = UK

啊,令人惊讶——提取完全不完整!事实上,在较小的程度上,这甚至发生在现实世界的 NER。我们正在体验现实。

好吧,让我们更深入地挖掘…首先,实体识别只和字典一样好。诺瓦克在我们人的名字字典里是缺失的,所以它被遗漏了。字典缺乏完整性和维护它们的挑战无疑是这种方法中的一个主要问题。第二,我们选择为一个人的名和姓准备单独的字典,而不是为一个人的全名准备一个字典。由于人的名和姓在某种程度上是独立的,后一种类型的字典将会非常庞大。组装和维护更具挑战性。考虑到这种选择,我们需要某种机制将一个人的名和姓组合成全名。事实上,它可能是基于模式的。也就是说,我们已经看到了结合基于字典和基于模式的方法的效用。

基于字典的方法的另一个重要问题,尽管在我们的例子中没有出现,是它们不能很好地适应歧义。相同的值存在于多个字典中。考虑一下卡特。这通常是一个人的姓,但有时也可以是一个人的名。

当然,我们可以把它放在两个字典里。我们不会捕捉到它更有可能是姓而不是名的概率。如果没有捕捉到这样的概率,模糊值的数量越多,字典就会被污染得越严重。我们将无法区分模糊的成员和重要的成员。

基于模式的

假设我们希望在一些文本中提取美国电话号码。如(123)456–7890。使用基于字典的方法没有意义。这将需要在字典中存储所有可能的美国电话号码。包括所有格式变化,如 123 456 7890

通过模式匹配可以更好地识别这些实体。通常,这是使用正则表达式完成的。

例子

考虑文本

Recognize all these as US phone numbers: (123) 456 7890, 456 7890, 123–456–7890, +1 (123) 456 7890.

这个例子的目的是揭示要识别的模式确实开始变得错综复杂。现在,将全球各地的国际电话号码添加到此列表中。现在,这变得非常复杂。按照软件工程的说法,复杂场景中的模式匹配有三个涉及“软件”的问题,这里是正则表达式。

  1. 首先,它们更难调试
  2. 它们通常是不透明的(难以理解)。
  3. 它们很难维护,也就是说,当需要更改时(例如,当发现错误或需要添加新的场景,如新国家的电话号码时)很难更新。

尽管有上面的 1-3,模式匹配是当实体被结构模式最好地描述时使用的方法。其他此类实体的示例有电子邮件地址URL美国邮政编码

概率词典

前面我们提到过,基于字典的方法不能令人满意地适应歧义。我们的例子是卡特和 T21。可以是一个人的名,也可以是一个人的姓。因此,它应该被收入两部词典。然而这样做隐含地假设卡特同样可能是一个人的名或姓。这种不必要的推断会对实体识别结果的质量产生不利影响。

幸运的是,基于字典的方法很容易增强以适应歧义。对于字典中的每个值,我们都附加了一个属性,即它的频率。如果一个值的频率不可用,我们将它默认为 1。频率是正数,但也可以是分数。

这里有一个例子。比方说,我们有 10 个出现的卡特,其中 2 个是名,8 个是姓。(这些数字是虚构的。)我们可以将卡特放在两个字典中,并在此人的名字典中分配频率 0.2,在此人的姓字典中分配频率 0.8。(或者我们可以只使用实际计数 2 和 8 作为频率。)把这想象成 Carter 的默认频率 1 按比例分配给两个实体类型。

好的,我们给字典中的每个值都加上了频率。我们实际上如何使用来预测一个值的实体呢?我们选择对该值具有最高概率的字典。我们在下面正式描述这一点。

考虑值 v 。对P(D|v)的简单经验估计是 Dv 的频率除以 v 在所有字典上的频率之和。

让我们看一个数字例子。下面是三本字典。

D1      D2     D3
**a** 10    **a** 1    e 1
b 20    c 5    f 5
e 15

我们应该预测什么作为 a 的实体类型?在 11 次出现的 a 中,10 次在 D1,1 次在 D2,没有一次在 D3。所以 D1 的可能性最大,D2 次之,D3 最小。所以我们有把握在 2011 年 10 月 11 日预测 D1 是一个实体。(注意,我们互换使用术语实体类型字典。)

间接,通过贝叶斯法则

有时,我们有一些在频率中没有捕捉到的关于字典的额外的先验知识。或者在我们的频率中某个特定值 v 的总频率太小,以至于我们不愿意相信我们的经验概率估计。

考虑这个例子。说我们有两本字典:。一个合理的先验是(1/2,1/2)。也就是说,在我们看到它之前,两者都同样可能是特定值的实体类型。考虑补偿值 Xincal 。说它只出现一次,在字典里的第一个名字。已知 Xincal名字的经验概率为 1。鉴于我们只见过 Xincal 一次,我们真的应该那么确定 Xincal 的实体吗?并且鉴于实体类型同样丰富。

贝叶斯规则让我们将数据证据与先验信念结合起来,以缓解这个问题。也就是说,对于给定的值,我们找到字典的概率不仅取决于我们的数据,还取决于我们先前的信念。

更详细地说,我们使用贝叶斯规则估计后验概率

P(D|v)=P(v|D)P(D/P(v)

这里的P(v|D)是字典 D. 中值 v 的似然性,从经验上讲,它就是 Dv 的频率除以 D 中所有值的频率之和。

接下来我们注意一下P(v)= sum _D'P(v|D')P(D')。所以我们可以在推断 v 的可能字典的过程中,实时计算 P ( v )。

回到经验后验,添加伪计数

在明确调用贝叶斯规则后,我们发现实际上并不需要使用它。有一种简单、直观的方法可以有效地产生相同的行为。

考虑我们的()例子。假设我们有一个先验的信念,认为两种实体类型的可能性是相等的。我们可以通过为每一个值 v 向两个字典中的每一个添加一个伪计数 n 来表明这一信念。把 n 想象成字典中一个值的初始频率。然后将该值的实际观察频率加到 n 上。

一旦我们有了伪计数和字典中的计数,我们就可以像以前一样精确地计算字典给定值的经验概率。

什么是 n ?它影响了我们先前信念的强度。n 越大,我们先前的信念就越强。也就是说,我们需要越多的证据来修正这个信念。也就是说,即使是 n = 1 通常也是对 n = 0 的改进,因此不值得为选择而烦恼。

伪计数是有理论支持的。特别是,它们的行为就好像在模拟一个所谓的狄利克雷先验。这个话题我们在本帖就不多说了。我们建议您使用谷歌。

例子:考虑我们的的例子。考虑值 Xincal 。假设我们选择 n = 1。中的 Xincal 的伪频率各为 1。现在加上 Xincal 的实际频率,在中为 1,在中为 0。所以组合频率是

Xincal                  first name (2)             last name (1) 

所以的后验概率是 2/3。实体类型的名字仍然获胜,尽管由于先前的信念而具有比以前更低的置信度。

在这个例子中,我们对伪计数的选择可以被解释为获取了下面的先验信念。如果一个值在我们的数据集中只出现一次,我们就不要用概率 1 来预测它出现的字典了。

复合实体

我们所说的复合实体是指本身由其他实体组成的实体。这里有两种类型的例子:

**Person name**: John K Smith | Dr. John Smith | John Smith, jr | John Smith, PhD**Street Address**: 10 Main St, Suite 220 | Hannover Bldg, 20 Mary St

在每种情况下,竖线分隔实体值。

复合实体有一个重要的特例,我们称之为多令牌实体。在本节关于复合实体的(长)讨论之后,我们将单独讨论这种情况。我们以这种方式组织内容,因为深入复合实体将有助于我们在随后关于多令牌实体的讨论。对多标记实体感兴趣的读者应该在“看够了”当前的内容后,向下滚动到该部分。

当处理复合实体时,它有助于区分两个计算问题。

解析又名分解:将一个复合实体分解成它的组件实体。这里有一个例子。

Dr. John K Smith ⇒ {**salutation** =Dr., **first_name** = John, **middle_name** = K, **last_name** = Smith}

识别:这里复合实体嵌入在一些非结构化的文本中。任务是识别实体的边界以及它的类型。并且可能还将它解析(即分解)成它的成分。这里有一个例子。

I looked up Dr. John K Smith. His street address came up as 10 Main St, Suite 220 in San Francisco.

我们希望我们的认可产生以下结果:

Dr. John K Smith      ⇒ **person_name**
10 Main St, Suite 220 ⇒ **street_address**

区分解析和识别的一个原因是不同的用例映射到一个或另一个。例如,我们可能有一个完整的人名数据库,并试图将每个人的名字解析成各个部分(名、姓等)。这不涉及任何承认。只是解析。

另一个原因是“各个击破”。假设我们的任务是识别非结构化文本中的复合实体并解析它们。两阶段方法——首先识别实体边界及其类型,然后解析识别出的实体——是有意义的。

我们并不是说两阶段方法会比同时进行识别和解析的集成方法更准确,只是说当您想要快速获得合理有效的解决方案,并且有更简单的方法来分别解决这两个问题时,这种方法值得考虑。

在这篇文章的剩余部分,我们将重点解析复合实体。

解析/分解的方法

首先,我们想观察复合实体的解析可能被框架化为一个序列标记问题。复合实体被适当地标记化,以产生标记序列。与令牌相关联的标签是其组成实体。下面是复合实体人员姓名的示例。

**Token sequence**: Dr. John K Smith
**Label sequence**: salutation first_name middle_name last_name

我们假设我们有(标记序列标签序列对形式的训练集。这类似于固定维度空间中监督学习的训练集,除了这里我们的输入和标签是(对齐的)序列

为什么要以这种方式对复合实体进行模型解析?主要原因是标签序列中隐藏着可以有效利用的信息。

假设我们有一个丰富的(标记序列标签序列)对数据集,可用于学习解析人名。有用的信号仅隐藏在标签序列中。称呼通常出现在名字之前,而不是之后。名字通常在姓氏之前,而不是之后。

训练和推理

好的,我们有一组训练序列(标记序列标签序列)对。我们的任务是从这个数据集中学习一个机器学习模型,以便当一个令牌序列是一个输入时,可能是一个在训练期间从未见过的输入,该模型输出它的最佳标签序列。同样,这类似于向量空间中的监督学习,除了我们的输入和输出是序列

隐马尔可夫模型

这是最广为人知的建模序列标记问题的方法。它非常适合我们的需要。话虽如此,它确实做了一个强有力的假设,马尔可夫假设。有时,这可能会过度限制。对更高级的方法感兴趣的读者,或者有更长距离交互的用例(即具有长令牌序列的复合实体,其中相距很远的令牌相互影响)的读者,也应该阅读条件随机场

好吧,回到 HMMs。我们将说明如何设置它来解析人名实体。在结构上,HMM 是一个有向无环图,具有节点(也称为状态)和弧(也称为转换)。实际上还有更多。节点可以从一些字母表中发出可观察到的信号。

HMM 具有附加到各种节点和弧的参数。这些参数形成合适的概率分布。更详细地说,一个州的排放是由可观测字母表上的概率分布决定的。这种分布是特定于州的。从一个状态的转移由状态的概率分布来控制。这些分布特定于起始状态。简而言之,从一个州你必须去某个地方。状态转移的概率分布捕捉了我们对下一步应该去哪里(哪个状态)的偏好。

用于解析人名

这有点抽象。让我们把它具体化。这个练习也将揭示 HMM 中的“H”,它代表隐藏的

我们将描述一个 HMM 来解析一个人全名的简化版本。具体来说,我们将只解析与以下正则表达式格式匹配的名称。

*[salutation_word] first_name_word [middle_name_word] last_name_word*

让我们读出这个正则表达式的内容。全名可以选择以称呼开头,然后是名,再然后是中间名,最后是姓。所有这些实体都必须是单字实体。

HMM vs 基于模式的解析

第一个问题,为什么不直接用这个正则表达式解析?也就是说,为什么不应用基于模式的方法来解决这个解析问题。如果你的目标是快速开发一个轻量级的方法,你可以。

基于 HMM 的方法在以下方面更强大。

部分解析:考虑输入史密斯。基于 HMM 的方法可能会将其解析为 last_name = Smith 。这是因为它也模拟实体概率。(详情如下。)基于模式的方法无法做到这一点。它无法知道史密斯更有可能是姓而不是名。

更好地解决歧义:考虑输入史密斯博士。基于 HMM 的方法可能会将其解析为称呼=T21 博士姓氏 = 史密斯。基于模式的方法可能会将其解析为名字 = 医生姓氏 = 史密斯。再说一次,因为它没有对实体概率建模,所以它无法知道 Dr. 更可能是称呼而不是名字。**

附上解析置信度得分:考虑两个输入约翰·史密斯史密斯·约翰。与基于模式的方法一样,基于 HMM 的方法可以很好地将这些分别解析为{ 名字 = 约翰姓氏 = 史密斯 }和{ 名字 = 史密斯姓氏 = 约翰 }。基于 HMM 的解析可能比第二个解析更信任第一个解析,因为它知道 John 更可能是名而不是姓,Smith 更可能是姓而不是名。

这样的置信度分数可以用来寻找低置信度的解析(也许可以区别对待它们)。它们也可能暴露数据问题。就像在这个例子中,名字和姓氏似乎颠倒了。

人名解析 HMM:结构

好的,让我们回到定义 HMM 匹配的正则表达式。

*[salutation_word] first_name_word [middle_name_word] last_name_word*

由此,我们将确定 HMM 的状态为称呼字名字字中间名字姓氏字。对此,我们将增加两种状态:开始结束。**

我们也将使用正则表达式来确定弧。下面是弧线

*begin → salutation_word 
begin → first_name_wordfirst_name_word → middle_name_word
first_name_word → last_name_wordlast_name_word → end*

计算机科学家认为 HMM 的结构定义了一个有限状态自动机。

在离开这个主题之前,我们想指出的是,可以直接从训练集推断 HMM 的结构(节点和转换)。这可以更加灵活。随着训练集的发展,结构也可以发展。

我们基于正则表达式预先确定结构的主要原因是教学上的。它允许我们将对 HMM 结构的讨论与对其学习(关于其发射和转换的概率参数)的描述分开。

我们还想指出的是,即使训练集原则上可以确定结构,在查看训练集之前,考虑用现有的领域知识初始化结构也是有帮助的。这使得人们可以将领域知识(对于 Bayesians 人来说,是先前的信念)用于建模。这可以弥补训练集中的弱点。

培训

接下来,我们将说明从训练集中训练 HMM 的参数。

正如我们前面提到的,训练集是(标记序列标签序列)对的集合。从这样的训练集中,在 HMM 中学习发射和转移概率。这两种概率的训练分解了,我们很快就会看到。我们可以称这样的训练为模块化。按照培训说明,我们将触及模块化培训的一些好处。

让我们看一个例子。它有三个训练实例。注意,我们已经将开始结束状态添加到侧翼。这些将在训练中发挥作用,我们很快就会看到。

 *Dr.        John       K          Smith
begin salutation first_name middle_name last_name end John      Smith
begin first_name last_name end John       Kent       Smith
begin first_name middle_name last_name end*

**开始结束状态被称为静默,因为它们不发出任何令牌。

训练转移概率

为了训练这些,我们只需要看状态序列。就好像我们的训练集

*begin salutation first_name middle_name last_name end
begin first_name last_name end
begin first_name middle_name last_name end*

从状态 a 到状态 b 的转移概率,即在弧 ab 上的转移概率,仅仅是状态 a (不包括任何作为状态序列中最后一个状态的状态)被状态 b 所接替的概率。

让我们来看看一些已知的转移概率。

*begin → salutation       ⅓ 
first_name → middle_name ⅔ 
first_name → last_name   ⅓*

状态开始的三个事件之一之后是状态问候。状态的三次出现中有两次跟随状态,一次跟随状态

训练发射概率

为了训练这些,我们丢弃序列信息,并且仅在每次令牌令牌从状态状态发出时跟踪(状态令牌)对。就好像训练集是

***state       emitted token**
salutation  Dr.
first_name  John
first_name  John
middle_name K
middle_name Kent
last_name   Smith
last_name   Smith*

从状态 s 发出令牌 t 的概率正好是发出令牌 t 的状态 s 出现的分数。

模块化训练

一个国家可能发出的不同价值观的数量是相当大的。例如,state first_name 可以发出数百万个不同的值。每一个都需要被明确地建模,以便将名字从诸如 xyz 这样的无意义的字符串中区分出来。

期望(记号序列标签序列)对的训练集足够丰富以覆盖所有可能的名字是不现实的。幸运的是,不一定是这样。可以独立于转换来训练发射。只要我们有每个实体(状态)值的丰富字典,最好是增加频率信息,我们就可以从中学习发射概率。

另请注意,相比之下,这种爆炸并不适用于学习转移概率。少量的精选状态序列可以充分地捕获大多数全名的序列结构。如果希望能够解析各种地区的人名,“小”可能不像人们想象的那么小。例如西班牙语和阿拉伯语。尽管如此,即使在这种情况下,手动管理训练集也是可行的。

推论

好了,现在我们有了经过训练的 HMM,或者至少我们可以想象它,让我们来看一个推理的例子。推理的特定目标是输入一系列标记并输出最佳解析。为了很好地定义这个过程,我们需要(I)一个评估令牌序列特定解析质量的核心函数和(ii)一个寻找最高分解析的搜索过程。我们需要一个搜索过程的原因是,穷举搜索的方法——对所有可能的解析进行评分,并选择一个得分最高的解析——可能太慢,即使只有几个标记。

黄金标准搜索程序是一种称为维特比算法的动态编程形式。它隐式最大化的得分函数是(记号序列标签序列)对的联合概率。令牌序列是固定的;标签序列是可变的,每次解析一个。维特比算法操作就好像正在对给定标记序列的所有可能的标签序列进行穷举搜索,只是它要快得多。

这里我们将不正式描述维特比算法。对于这篇已经很长的文章来说,它太复杂了。然而,我们将通过一个例子来说明它工作的某些方面。不可否认的是以一种粗略的方式。我们的希望是,那些第一次阅读它的人会足够好奇,从其他地方了解更多(见下面的参考资料),而那些已经阅读过它的人会从我们的插图中找到一些见解,以增加他们的理解。

我们将展示的输入是约翰·史密斯博士。我们想要描述的第一个关键思想是维特比算法通过维护一个矩阵来操作,该矩阵的行索引 HMM 的状态,其列索引输入中的记号。在我们的例子中,这个矩阵的结构如下

 *Dr.           John        Smith
begin       1
salutation  0    P(b)P(s|b)P(Dr.|s)
first_name  0                         ?
middle_name 0
last_name   0
end         0          0*

什么进入矩阵的每个单元,它是如何到达那里的?这太复杂了,在我们分配给它的空间里很难详细说明和解释。因此,我们在一些单元格中放入了值或公式,我们将在下面解释。

让我们从第一栏开始。那里的价值观很容易解读。为了解析输入,HMM 必须从状态开始开始。这在第一列中表示为“处于状态 begin 的概率是 1,处于任何其他状态的概率是 0”。

接下来,我们来看看细胞[ 称呼博士。这里的值是解析到第一个标记并以状态 salutation 结束的概率。(在我们的例子中,“在状态称呼中结束”意味着博士是从称呼中发出的。)

这个概率就是从状态开始,过渡到状态称呼,从称呼发出T21 博士的概率。这是我们在那间牢房里看到的。**

现在让我们看看什么进入了单元格[first _ nameJohn。我们在那里放了一个问号,因为这个表达太复杂了,无法以一种抓住所有正在发生的重要事情的方式放在那里。所以我们在这里只讨论它们。

首先,让我们提醒自己,我们希望什么进入这个单元格。它是前两个记号的联合概率和这些记号的最佳解析。说什么?**

让我们慢慢来。首先,从现在开始,让我们将对上述联合概率的引用缩写为“这些记号的最佳解析的概率”。这损失了一些精确性,但是可读性更好。根据检查,您认为最好的解析是什么?【开头称呼名字对吗?这个解析的概率就是进入这个单元格的内容。

接下来是一个关键的观察。我们不会证明的。这对理解这种算法是如何工作的至关重要。这个解析的概率是[begin,salutation是对[ Dr. ] 的解析的概率乘以扩展这个解析以覆盖从 first_name 发出的 John 的概率。我们已经计算了粗体部分,并将其结果存入矩阵的单元格[ salutationdr]中。所以我们只需要将这个单元格的值乘以上述扩展的概率,即从状态称呼转换到状态名字的概率乘以从名字发出约翰的概率。这种对先前计算的概率的重用是该算法相对于穷举搜索实现加速的关键。

还有一个问题。在前两段中,为了便于解释,我们假设我们知道[ Dr.John ]的最佳解析是[ beginsalutationfirst_name ]。算法当然不会。我们该如何应对?

首先,让我们明确我们知道什么。我们确实知道 John 必须从 first_name 中发出,因为我们正在尝试填写该单元格的值。我们不知道的是[ Dr. ]的最佳解析以及它的最终状态。姑且称这个未知的‘T42’为‘博士’的状态吧。对于博士状态的每个可能值,我们知道形式为开始博士状态】的博士的最佳解析的**概率。对于其中的每一个,我们都乘以扩展解析成为[ beginDr. 的 statefirst_name ]的概率。这里唯一的变量是博士的州,所以因为我们想要最佳解析的概率,我们只取博士的州的所有值的最大概率。请注意,在这些计算中,我们以粗体重复使用了概率,因为在此之前,它们已经被计算并存储在矩阵中。**

恢复最佳解析

我们还没完。在我们填充了矩阵之后,我们所知道的就是完整输入的最佳解析的概率。它位于矩阵的右下角。我们不知道实际的解析。

为了恢复一个实际的(得分最高的)解析,首先,在构建得分矩阵的“自底向上”阶段,我们捕获一些额外的元数据。一旦构建了矩阵,我们就使用这个元数据来查找实际的解析。

让我们看看分数矩阵,其中一些单元格增加了上述元数据。让我们用它自己的矩阵来描述它,我们称之为回指矩阵。这个矩阵具有与分数矩阵相同的结构。唯一的区别是它的单元格不存储分数,而是存储其他单元格的索引。因此得名“反向指针”。

下面是填充了一些值的反向指针矩阵。来解释一个吧。单元格[2,2]包含值[1,1]。这捕获了[ 博士约翰的最佳解析的信息,其中状态名字被约束为从状态称呼发出约翰发出博士。该信息在计算分数矩阵中相应单元格的分数的过程中出现。特别是在计算各项的最大值的过程中。

 *0        1        2        3
                        Dr.     John     Smith
0 begin
1 salutation           [0,0]
2 first_name                    [1,1]
3 middle_name
4 last_name                              [2,2] 
5 end                                    [4,3]*

接下来,让我们看看如何使用这个矩阵来找到一个实际的最佳解析。我们从右下角的单元格开始,即单元格[5,3]。从这个单元格,我们沿着一条路径回到单元格[0,0]。在我们的例子中,路径是

*[5,3] → [4,3] → [2,2] → [1,1] → [0,0]*

该路径包含逆向恢复(最佳)解析的信息。这在下面描述。

*[5,3]    →    [4,3]    →    [2,2]    →    [1,1]   →    [0,0]
                     Smith          John         Dr.
        end        last_name      first_name   salutation     begin*

在每一个反向指针步骤中,我们揭示反转令牌序列中一个令牌的状态。在步骤[5,3] → [4,3]中,我们恢复[,end]。令牌丢失,因为处于静默状态。在步骤[4,3] → [2,2]中,我们从状态 4 ( 姓氏)移动到另一个状态(状态 2),同时从令牌 3 ( 史密斯)移动到令牌 2。这些移动产生了一对(史密斯姓氏)。事情就是这样。

最后一步是反转解析,这在堆栈的帮助下很容易做到。

多令牌实体

多标记实体是复合实体的一种特殊情况,其中实体的值跨越多个标记,但实体类型本身不会分解为更精细的实体类型。(或者我们不在乎。)

这里有两个这样实体的例子:国家公园名称医疗疾病名称。让我们来看一些例子:

***national park names**: Yellowstone national park, Yosemite national park, Grand Canyon national park, ...**disease names**: Parkinson's disease, Type I diabetes, heart disease, alzheimer's disease*

在多标记实体中,没有解析问题,只有识别问题。也就是说,目标是识别流动文本中的实体及其边界。就像

*I traveled to **Yellowstone National Park** and after that went to Colorado.* 

方法

基于字典的

这是最简单的一种。然而,当字典不完整时,它就不起作用了,当我们试图首先使用实体识别来构建一个丰富的字典时,情况就是这样。(参见本文前面描述的用例从语料库构建结构化数据库。)

监督二元分类

这是解决这个问题的一个有吸引力的方法。训练实例可以是一个短短语,标记为(实体的实例)或(不是实体的实例)。我们还会选择合适的特征从输入短语中提取出来。(稍后将详细介绍这一点。)

一个重要的考虑是如何为训练集选择负实例。负面例子的世界是巨大的——所有短语都有一定的长度(应该是什么?).从宇宙中随机取样可能会给我们微弱的否定。因此,相对于我们对标记数据集的训练测试分割的评估,学习的分类器可能比我们想象的更弱。重点是否定实例不是真实的——我们通过特定的过程构建了它们——而这个过程可能并不代表我们在这个领域中得到的实际否定,它可能是文本中足够短的短语,而不是这个实体的实例。

相比之下,添加表面上看起来像正面的人为负面信息可能会产生更准确的分类器。这里有一个关于实体国家公园名称的负面例子:城堡石国家公园。这是一个公园,但不是国家公园。

前面段落的讨论还意味着,无论我们如何仔细地挑选否定,分类器准确性的最终评估都应该基于它在实际中如何使用的实际文本上的实体识别准确性。

再一次,这是因为我们正在从一个巨大的空间中挑选负面因素,我们不能排除选择偏差。第二个重要原因是,领域中的类别比例,特别是在操作期间输入到分类器的短语的比例是负的,将严重依赖于它所应用的文本。考虑疾病名称。金融文档中作为疾病名称的短语的比例可能远低于 WebMD 文档中的比例。因此,两者的假阳性率可能大不相同。

特征工程

考虑识别国家公园的名称,即将它们与其他短语区分开来。我们已经看到的例子表明,一个有目的的启发式单词袋变体作为特征。具体来说,首先,我们将输入标记为单词,然后将最后两个单词组合成一个二元模型,并捕获它们是最后两个单词。这很容易用例子来说明。

*Yellowstone National Park --> {yellowstone, 'national_park_end'}
Castle Rock State Park    --> {castle,rock,'state_park_end'}*

为什么我们把最后两个词组合成一个二元结构?因为将它们分开会有更高的假阳性率。比如黄石国家银行(杜撰的例子)。

值得注意的是,这一计划提供了一些灵活性,如果我们在稍后阶段决定将国家纪念碑也视为国家公园,我们只需要增加一些积极因素。恐龙国家保护区就是一个例子。我们所选择的特征将选择这些。

这些特征利用了国家公园名称的结构。他们在其他多标记问题上的表现取决于它的结构是否与国家公园的名称相匹配。考虑疾病名称。当然,最后一个词通常是积极消极的预测。(参见我们之前列出的疾病名称示例。)也就是说,将最后两个词组合成一个二元模型可能不够概括。这是因为在疾病名称中,只有最后一个词可能是提示词。(如。)使用国家公园名称特征将不会检测到以单词 disease* 结尾的疾病,除非训练集具有一些以单词 disease 结尾的阳性。可能是一个很具体的字。这就是为什么我们说这些特征不能很好地概括疾病名称。*

分类器算法

既然我们已经定义了我们的标记训练集和特征,我们原则上可以使用任何二进制分类器算法来解决这个问题。两个想到我们的逻辑回归和朴素贝叶斯。两者我们都不深究。

备选方案:HMM

解决这个问题的另一种方法是将其公式化为一个序列标记问题,尽管有一点扭曲。这值得考虑,因为多标记实体识别肯定具有顺序结构。也就是说,它确实需要一些关于原始实体是什么的想法。另外,我们如何将 HMM 转换成二进制分类器。

想想国家公园的名字。以黄石国家公园为例。假设我们将其对应的状态序列建模为name _ word geo _ level _ word park _ type _ word。也就是说,作为一个(令牌序列,标签序列)实例,这将被表示为

 *Yellowstone  National        Park
begin    name_word    _national_      park_type_word     **positive***

现在考虑一个负面的:城堡石州立公园。它的标签实例可能如下所示。

 *Castle     Rock      State    
begin    name_word  name_word _state_                   **negative***

再来看一个负面:莫卡冰淇淋。它的标签实例可能如下所示。

 *Mocca    Ice      Cream
begin    word     word     word                        **negative***

我们的 HMM 会有我们在这三个标签序列中看到的状态。这里的想法如下。对于任何特定的输入,我们将强制一条路径以状态结束。如果在某些输入上从 begin 可以到达这两种状态,那么我们希望我们的 HMM 结构和训练将有利于通向输入的类()的路径。

讨论

上一节提供的是这种解决方案的关键要素。在实际环境中,这种方法可能需要进一步完善。

例如在状态(例如进一步细化的状态,也许是词性:专有名词名词动词形容词冠词,…

或者放松一阶马尔可夫假设。最常见的情况是,条件随机场也是如此。

延伸阅读

* [## 自然语言处理中使用条件随机场的命名实体识别(NER)

在深入讨论了自然语言处理中的词性标注算法之后,是时候开始研究自然语言处理中的信息抽取了

medium.com](https://medium.com/data-science-in-your-pocket/named-entity-recognition-ner-using-conditional-random-fields-in-nlp-3660df22e95c)*

使用 Keras 双向 LSTM 的命名实体识别(NER)

原文:https://towardsdatascience.com/named-entity-recognition-ner-using-keras-bidirectional-lstm-28cd3f301f54?source=collection_archive---------2-----------------------

通过双向 LSTM 理解句子的上下文进行分类,而不删除停用词。

使用 spaCy 实体的句子示例,突出显示句子中的实体。

命名实体识别(【NER】)(也称为实体识别实体分块、实体提取)是信息提取的一个子任务,它试图定位非结构化文本中提到的命名实体并将其分类成预定义的类别,例如人名、组织、位置、医疗代码、时间表达式、数量、货币值、百分比等。

在这个项目中,我们将使用 Kaggle 提供的 NER 数据集。数据集可以在这里访问。该数据集是从 GMB 语料库中提取的,该语料库经过标记、注释和专门构建,用于训练分类器来预测命名实体,如名称、位置等。数据集还包括一个额外的特征,可以用于分类的词性。然而,在这个项目中,我们只使用一个特色句子。

1.加载数据集

让我们从加载和可视化数据集开始。要下载 ner_dataset.csv,请转到 Kaggle 中的这个链接

加载数据时请使用 encoding = 'unicode_escape'。该函数使用一个参数来切换换行引号的添加,并在字符串中转义该引号。

import pandas as pd
data = pd.read_csv('ner_dataset.csv', encoding= 'unicode_escape')
data.head()

请注意,数据集中的句子在“单词”列中被标记化。“句子#”列显示一次句子编号,然后打印 NaN,直到下一个句子开始。“标签”列将是我们的标签(y)。

2.提取神经网络所需的映射

为了训练神经网络,我们将使用下面给出的两个映射。

  • {token} to {token id}:寻址当前 token 的嵌入矩阵中的行。
  • { tag }至{ tag id }:用于计算网络输出损耗的单热点真实概率分布向量。

这一步在任何机器学习模型中都是需要的,包括需要整数作为输入的神经网络。

data['Word_idx'] = data['Word'].map(token2idx)
data['Tag_idx'] = data['Tag'].map(tag2idx)
data.head()

我们可以看到,该函数为 X (Word_idx)和 y (Tag_idx)变量添加了两个新的索引列。接下来,让我们按照各自的顺序将令牌收集到数组中,以充分利用递归神经网络。

3.转换列以提取顺序数据

为了将列转换成顺序数组,我们将

  • 使用 fillna 中的 ffill 方法在“句子#”列中填写 NaN。
  • 接下来,按句子列进行分组,以获得标记和标签的数组。
# Fill na
data_fillna = data.fillna(method='ffill', axis=0)# Groupby and collect columns
data_group = data_fillna.groupby(
['Sentence #'],as_index=False
)['Word', 'POS', 'Tag', 'Word_idx', 'Tag_idx'].agg(lambda x: list(x))# Visualise data
data_group.head()

用令牌和标签序列转换数据。

4.将数据集分成训练集,填充后测试

填充:LSTM 层只接受相同长度的序列。因此,每一个用整数表示的句子(' Word_idx ')都必须被填充以具有相同的长度。我们将处理最长序列的最大长度,并填充较短的序列来实现这一点。

请注意,我们也可以使用较短的衬垫长度。在这种情况下,您将填充较短的序列并截断较长的序列

我们还将使用 Keras 中的 to _ categorical 函数将 y 变量转换为 one-hot 编码向量。让我们导入所需的包。

from sklearn.model_selection import train_test_split
from keras.preprocessing.sequence import pad_sequences
from keras.utils import to_categorical

5.构建模型架构

神经网络模型使用图形结构。因此,我们首先需要设计架构,并为每一层设置输入和输出维度。rnn 能够处理不同的输入和输出组合。对于这项任务,我们将使用“多对多”架构。参考下图中的最后一个架构。我们的任务是输出在每个时间步摄取的令牌(X)的 tag (y)。

rnn 能够处理不同的输入和输出组合。

让我们从加载所需的包开始。

import numpy as np
import tensorflow
from tensorflow.keras import Sequential, Model, Input
from tensorflow.keras.layers import LSTM, Embedding, Dense, TimeDistributed, Dropout, Bidirectional
from tensorflow.keras.utils import plot_model

为可复制性设定一个种子总是最好的。

from numpy.random import seed
seed(1)
tensorflow.random.set_seed(2)

为了更好地理解层的输入和输出尺寸,请将模型图中的层与下图(模型图)中给出的每个层的简介进行比较。

在该架构中,我们主要使用三层(嵌入、bi-lstm、lstm 层)和第四层(时间分布密集层)来输出结果。我们将在下面的章节中详细讨论这些层。

  • 第 1 层—嵌入层:我们将指定填充序列的最大长度(104)。在网络被训练之后,嵌入层将把每个令牌转换成 n 维向量。我们选择 n 维为(64)。

尺寸(?,104,64)来自这些规范。请注意第一维显示“?”或者在情节中没有。它们代表批量大小。如果没有提供,它们会显示“?”或者没有,这意味着模型可以接受任何批量大小。

  • 第二层——双向 lstm: 双向 LSTM 以一个递归层(如第一个 LSTM 层)作为自变量。该层从先前的嵌入层(104,64)获取输出。

由于这是双向 lstm,我们将有前向和后向输出。在将这些输出传递到下一层之前,通过求和、取平均值、连接或相乘来组合它们。在 bi-lstm 层的合并模式参数中找到这些函数。在默认模式下,输出被连接在一起,从而使下一层的输出数量加倍。在我们的例子中,它变成了 128(64 * 2)。

  • 第 3 层——LSTM 层:一个 LSTM 网络是一个递归神经网络,它用 LSTM 细胞块代替了我们的标准神经网络层。这些单元有不同的组成部分,称为输入门、遗忘门和输出门。

该层从先前的双向 lstm 层(?104,128)和输出(?, 104, 256)

  • 第 4 层——时间分布式层:我们正在处理多对多 RNN 架构,我们期望从每个输入序列得到输出。这里有一个例子,在序列(a1 →b1,a2 →b2…an →bn)中,a 和 b 是每个序列的输入和输出。TimeDistributeDense 层允许在每个时间步长的每个输出上进行密集(全连接)操作。不,使用这一层将产生一个最终输出。

该层采用前一 lstm 层(104,256)的输出维度,并输出最大序列长度(104)和最大标签(17)。

input_dim = len(list(set(data['Word'].to_list())))+1
output_dim = 64
input_length = max([len(s) for s in data_group['Word_idx'].tolist()])
n_tags = len(tag2idx)print('input_dim: ', input_dim, '\noutput_dim: ', output_dim, '\ninput_length: ', input_length, '\nn_tags: ', n_tags)

下面给出了用于构建我们上面讨论的模型架构的代码。在拟合模型之前,通过使用 plot_model 函数绘制模型或运行 model.summary()获取模型摘要来检查模型图。

6.符合模型

我们将用 for 循环来拟合模型,以保存和可视化每个时期的损失。

results = pd.DataFrame()model_bilstm_lstm = get_bilstm_lstm_model()
plot_model(model_bilstm_lstm)results['with_add_lstm'] = train_model(train_tokens, np.array(train_tags), model_bilstm_lstm)

该模型以 0.9169 的精度开始,以 0.9169 的精度结束。以 1000 个批量运行 25 个时期后,最终精度为 0.9687。

请使用不同的批量大小、差值、优化器、指标和层来试验模型,以获得更好的结果。在 Github 资源库中找到该项目的完整代码。

对于任何感兴趣的人来说,这里有一段代码,它将使用 spaCy 突出显示任何给定句子中的实体。

import spacy
from spacy import displacy
nlp = spacy.load('en_core_web_sm')text = nlp('Jim bought 300 shares of Acme Corp. in 2006\. And producing an annotated block of text that highlights the names of entities: [Jim]Person bought 300 shares of [Acme Corp.]Organization in [2006]Time. In this example, a person name consisting of one token, a two-token company name and a temporal expression have been detected and classified.State-of-the-art NER systems for English produce near-human performance. For example, the best system entering MUC-7 scored 93.39% of F-measure while human annotators scored 97.60% and 96.95%.[1][2]')displacy.render(text, style = 'ent', jupyter=True)

参考文献:

[## 何时以及如何使用 TimeDistributedDense 问题#1029 keras-team/keras

解散 GitHub 是超过 5000 万开发者的家园,他们一起工作来托管和审查代码,管理项目,以及…

github.com](https://github.com/keras-team/keras/issues/1029) [## 如何在 Keras 中使用时间分布层-机器学习掌握

最近更新的长短期网络或 LSTMs 是一种流行和强大的递归神经网络,或 RNN…

machinelearningmastery.com](https://machinelearningmastery.com/timedistributed-layer-for-long-short-term-memory-networks-in-python/)

使用 spaCy 的命名实体识别| NLP |第 4 部分

原文:https://towardsdatascience.com/named-entity-recognition-ner-using-spacy-nlp-part-4-28da2ece57c6?source=collection_archive---------3-----------------------

使用 spaCy | NLP 库进行文本处理

命名实体识别是信息检索中最重要的,或者说是最开始的一步。信息检索是从非结构化的原始文本文档中提取重要有用信息的技术。命名实体识别 NER 的工作原理是定位和识别非结构化文本中的命名实体,将其分为标准类别,如人名、位置、组织、时间表达式、数量、货币值、百分比、代码等。Spacy 附带了一个非常快速的统计实体识别系统,该系统将标签分配给连续范围的标记。

Spacy 安装和基本操作| NLP 文本处理库|第 1 部分

Spacy 提供了向实体识别系统添加任意类和更新模型的选项,甚至包括除了模型中已经定义的实体之外的新示例。

Spacy 具有 'ner' 管道组件,用于识别符合一组预定命名实体的令牌跨度。这些可以作为 Doc 对象的ents属性使用。

# Perform standard imports import spacy nlp = spacy.load('en_core_web_sm')# Write a function to display basic entity info: def show_ents(doc): if doc.ents: for ent in doc.ents: print(ent.text+' - ' +str(ent.start_char) +' - '+ str(ent.end_char) +' - '+ent.label_+ ' - '+str(spacy.explain(ent.label_))) else: print('No named entities found.')doc1 = nlp("Apple is looking at buying U.K. startup for $1 billion") show_ents(doc1)

doc2 = nlp(u'May I go to Washington, DC next May to see the Washington Monument?') show_ents(doc2)

这里我们看到令牌组合起来形成了实体next Maythe Washington Monument

doc3 = nlp(u'Can I please borrow 500 dollars from you to buy some Microsoft stock?') for ent in doc3.ents: print(ent.text, ent.start, ent.end, ent.start_char, ent.end_char, ent.label_)

实体注释

Doc.ents是具有自己的注释集的记号跨度。

访问实体注释

访问实体注释的标准方法是 doc.ents 属性,它产生一系列 Span 对象。实体类型既可以使用 ent.label 作为哈希值访问,也可以使用 ent.label_ 作为字符串访问。

Span 对象充当一系列标记,因此您可以迭代实体或对其进行索引。您还可以获得整个实体的文本形式,就像它是单个令牌一样。

还可以使用 token.ent_iob 和 token.ent_type 属性来访问令牌实体注释。token.ent_iob 指示实体是在标记上开始、继续还是结束。如果令牌上没有设置实体类型,它将返回一个空字符串。

doc = nlp("San Francisco considers banning sidewalk delivery robots") # document level for e in doc.ents: print(e.text, e.start_char, e.end_char, e.label_) # OR ents = [(e.text, e.start_char, e.end_char, e.label_) for e in doc.ents] print(ents)#token level # doc[0], doc[1] ...will have tokens stored. ent_san = [doc[0].text, doc[0].ent_iob_, doc[0].ent_type_] ent_francisco = [doc[1].text, doc[1].ent_iob_, doc[1].ent_type_] print(ent_san) print(ent_francisco)

IOB SCHEME I - Token is inside an entity. O - Token is outside an entity. B - Token is the beginning of an entity.

注意:在上面的例子中,只有San Francisco被认为是一个命名实体。因此,其余的令牌被描述为在实体之外。而在San FranciscoSan是实体的起点而Francisco是实体内部。

标签可以通过实体的.label_属性来访问。

用户定义的命名实体并将其添加到 Span

通常我们会让 spaCy 通过对几个文本样本进行训练来建立一个命名实体库。
有时候,我们想给一个特定的令牌分配一个命名实体,但这个实体不能被训练好的空间模型识别。我们可以这样做,如下面的代码所示。

示例 1

示例 2

将命名实体添加到所有匹配范围

如果我们想要标记一个令牌的所有出现的会怎样?在本节中,我们将展示如何使用 PhraseMatcher 来识别文档中的一系列跨度:

doc = nlp(u'Our company plans to introduce a new vacuum cleaner. If successful, the vacuum cleaner will be our first product.') show_ents(doc) #output: first - 99 - 104 - ORDINAL - "first", "second", etc.#Import PhraseMatcher and create a matcher object: from spacy.matcher import PhraseMatcher matcher = PhraseMatcher(nlp.vocab)#Create the desired phrase patterns:
phrase_list = ['vacuum cleaner', 'vacuum-cleaner']
phrase_patterns = [nlp(text) for text in phrase_list]#Apply the patterns to our matcher object:
matcher.add('newproduct', None, *phrase_patterns)#Apply the matcher to our Doc object:
matches = matcher(doc)#See what matches occur: matches #output: [(2689272359382549672, 7, 9), (2689272359382549672, 14, 16)]

#Here we create Spans from each match, and create named entities from them: from spacy.tokens import Span PROD = doc.vocab.strings[u'PRODUCT'] new_ents = [Span(doc, match[1],match[2],label=PROD) for match in matches] #match[1] contains the start index of the the token and match[2] the stop index (exclusive) of the token in the doc. doc.ents = list(doc.ents) + new_ents show_ents(doc)output: vacuum cleaner - 37 - 51 - PRODUCT - Objects, vehicles, foods, etc. (not services) vacuum cleaner - 72 - 86 - PRODUCT - Objects, vehicles, foods, etc. (not services) first - 99 - 104 - ORDINAL - "first", "second", etc.

计数实体

虽然 spaCy 可能没有内置的实体计数工具,但我们可以将条件语句传递给列表理解:

想象 NER

Spacy 有一个名为“displaCy”的库,它帮助我们交互式地探索实体识别模型的行为。

如果你正在训练一个模型,自己运行可视化是非常有用的。

你可以传递一个Doc或一个Doc对象列表来显示并运行displacy.serve来运行网络服务器,或displacy.render来生成原始标记。

#Import the displaCy library
from spacy import displacy

一行一行地想象句子

查看特定实体

您可以传递实体类型列表来限制可视化:

造型:定制颜色和效果

您还可以传递背景颜色和渐变选项:

这是所有关于命名实体识别 NER 和它的可视化使用空间。希望你喜欢这篇文章。

在下一篇文章中,我将描述句子分割。敬请期待!

如果您有任何改进内容的反馈或想法,请写在下面的评论部分。你的评论很有价值。

spaCy NLP 系列以前的文章:

谢谢大家!

参考资料:

原载于 2020 年 4 月 27 日http://ashutoshtripathi.com

Spark 自然语言处理中基于 BERT 的命名实体识别(NER)

原文:https://towardsdatascience.com/named-entity-recognition-ner-with-bert-in-spark-nlp-874df20d1d77?source=collection_archive---------2-----------------------

用 BERT 在 Spark NLP 中的几行代码训练一个 NER,获得 SOTA 精度。

照片由 Jasmin NeUnsplash 上拍摄

NER 是信息提取的一个子任务,它试图定位非结构化文本中提到的命名实体并将其分类成预定义的类别,例如人名、组织、位置、医疗代码、时间表达式、数量、货币值、百分比等。

NER 在自然语言处理(NLP)的很多领域都有应用,它可以帮助回答很多现实世界的问题,比如:

  • 新闻中提到了哪些公司?
  • 哪些测试适用于患者(临床报告)?
  • 推文中有提到产品名称吗?

Spark 自然语言处理库中的临床 NER 模型

NER 系统公司

NER 是 NLP 和的一个活跃话题,多年来研究工作一直在进行。我们可以将这些努力总结为以下主题:

  1. 传统方法(基于规则)
  2. ML 方法
  • 多类分类
  • 条件随机场

3.DL 方法

4.混合方法 (DL + ML)

NER 和伯特在星火 NLP

在本文中,我们将尝试向您展示如何使用 BERT 在 Spark NLP 库中构建一个最先进的 NER 模型。我们要实现的模型受到了 NER 以前的艺术模型的启发: Chiu & Nicols,使用双向 LSTM 的命名实体识别-CNN 并且它已经嵌入在 Spark NLP NerDL 注释器中。这是一种新颖的神经网络架构,使用混合双向 LSTM 和 CNN 架构自动检测单词和字符级特征,无需大多数特征工程。

在开发该模型时,没有类似 BERT 的语言模型,并且在原始论文中使用了 Glove 单词嵌入。但是在本文中,我们将使用 BERT 替换 Glove。

Spark NLP NER DL 基准

在 Spark NLP 中,有三种不同的预训练单词嵌入模型(及其变体),您可以根据您的使用情况即插即用。

为了简单和节省您的时间,我们将跳过安装步骤。我们已经有另一篇文章详细介绍了 Spark NLP。而我们会做好 Colab 里的所有工作,让你直接跳到 Spark NLP。

我们开始吧!

我们从下载训练和测试集开始。我们将使用官方的 CoNLL2003 数据集,这是一个几乎在所有 NER 论文中都使用过的基准数据集。你可以在这里下载这个数据集

让我们简单解释一下什么是 CoNLL。作为“自然语言学习会议”的缩写, CoNLL 也是用于训练集以训练 NER 模型的注释的标准格式。这是它的样子。您可以在 CONLL 中注释自己的数据,然后在 Spark NLP 中训练一个自定义 NER。还有一些免费的注释工具可以用来标记你自己的数据。

下面是我们要一一讲解的流程。

我们导入相关的包,然后开始编码。

from pyspark.sql import SparkSession
from pyspark.ml import Pipelinefrom sparknlp.annotator import *
from sparknlp.common import *
from sparknlp.base import *import sparknlp
spark = sparknlp.start()print("Spark NLP version: ", sparknlp.version())
print("Apache Spark version: ", spark.version)*>> Spark NLP version:  2.4.1 
>> Apache Spark version:  2.4.4*

如果你想在 GPU 上训练你的模型,你可以用spark = sparknlp(gpu=True) 开始你的 Spark 会话。

然后,我们将 CoNLL 文件转换为 Spark 数据帧,并生成所有附加字段供以后使用。

from sparknlp.training import CoNLL
training_data = CoNLL().readDataset(spark, './eng.train')
training_data.show()

如您所见,输入数据集只有线和标注,现在这里有几列。Spark NLP 中的 CoNLL helper 类将数据集作为输入,并准备我们将使用的 NER 算法所需的令牌、词性和句子。您需要做的就是准备或下载一个 CoNLL 格式的数据集。

(注意:尽管原文建议使用 POS,但在 Spark NLP 培训中不会使用。因为 POS 标签是 CoNLL 格式的,所以 CoNLL helper 类从作为输入给出的 CONLL 文件中提取它们。因此,我们甚至可以用-X-来代替在源文件中张贴标签。)

下一步是通过 BERT 获得单词嵌入。我们将使用名为BertEmbeddings() 的 Spark NLP 注释器。

bert = BertEmbeddings.pretrained('bert_base_cased', 'en') \    .setInputCols(["sentence",'token'])\
.setOutputCol("bert")\
.setCaseSensitive(False)\
.setPoolingLayer(0) # default 0

在 Spark NLP 中,我们有四种预先训练好的 BERT 变体:bert_base_uncasedbert_base_casedbert_large_uncasedbert_large_cased。使用哪一个取决于您的用例、训练集以及您试图建模的任务的复杂性。

在上面的代码片段中,我们基本上从 Spark NLP 公共资源加载了bert_base_cased版本,并将sentencetoken列指向setInputCols().简而言之,BertEmbeddings()注释器将获取sentencetoken列,并在bert列中填充 Bert 嵌入。一般来说,每个单词被翻译成一个 768 维的向量。参数setPoolingLayer()可以设置为0为第一层最快,-1为最后一层,-2second-to-last-hidden layer

正如官方 BERT 论文 的作者所解释的,不同的 BERT 层捕捉不同的信息。最后一层在预训练期间太接近目标函数(即,掩蔽语言模型和下一句预测),因此它可能偏向那些目标。如果你想使用最后隐藏层,请随意设置 *pooling_layer=-1* 。直观上, *pooling_layer=-1* 接近训练输出,所以可能会偏向训练目标。如果你不微调模型,那么这可能会导致一个坏的表现。也就是说,这是模型准确性和您拥有的计算资源之间的权衡问题。

然后我们导入NerDLApproach()注释器,它是负责训练 NER 模型的主要模块。

nerTagger = NerDLApproach()\
.setInputCols(["sentence", "token", "bert"])\
.setLabelColumn("label")\
.setOutputCol("ner")\
.setMaxEpochs(1)\
.setRandomSeed(0)\
.setVerbose(1)\
.setValidationSplit(0.2)\
.setEvaluationLogExtended(True)\
.setEnableOutputLogs(True)\
.setIncludeConfidence(True)\
.setTestDataset("test_withEmbeds.parquet")

让我们解释一下每个参数:

.setInputCols([“sentence”, “token”, “bert”]):NER 模型将用来生成特征的列。

.setLabelColumn(“label”):目标列

.setOutputCol(“ner”):预测将被写入ner

.setMaxEpochs(1):训练的历元数

.setVerbose(1):训练时的日志级别

.setValidationSplit(0.2):每个历元上要对照模型验证的训练数据集的比例。该值应介于 0.0 和 1.0 之间,默认情况下为 0.0 和关闭。

.setEvaluationLogExtended(True):是否延长验证日志:显示每个标签的时间和评估。默认值为 false。

.setEnableOutputLogs(True):是否输出到日志文件夹。当设置为真时,日志和训练指标将被写入主文件夹中的文件夹。

.setIncludeConfidence(True):注释元数据中是否包含置信度得分。

.setTestDataset(“test_withEmbeds.parquet”):测试数据集的路径。如果设置了,它将用于在训练期间对其进行统计。这也是一种 CoNLL 格式,但是嵌入像以前一样通过添加并保存到磁盘。如果你不需要在 Spark 中一个不可见的测试集上评估你的模型,你就不需要设置这个。

test_data = CoNLL().readDataset(spark, './eng.testa')
test_data = bert.transform(test_data)
test_data.write.parquet("test_withEmbeds.parquet")

还可以设置学习率(setLr)、学习率衰减系数(setPo)、setBatchSizesetDropout速率。完整名单请见官方回购

现在我们可以在管道中添加这两个注释器。

ner_pipeline = Pipeline(stages = [bert, nerTagger])ner_model = ner_pipeline.fit(training_data)

根据数据集大小和您设置的历元数完成拟合后,它就可以使用了。让我们看看仅仅一个时期后的日志是什么样子的(在你的主文件夹的annotators_log文件夹中)。

你可以在Colab实例的根目录下找到这个文件夹。

拟合时,训练日志被写入磁盘

*Please check* [*here*](https://nlp.johnsnowlabs.com/docs/en/graph) *in case you get an IllegalArgumentException error with a description such as: Graph [parameter] should be [value]: Could not find a suitable tensorflow graph for embeddings dim: [value] tags: [value] nChars: [value]. Generate graph by python code in python/tensorflow/ner/create_models before usage and use setGraphFolder Param to point to output.*

总之,我们可以用 Spark NLP 中的几行代码在 SOTA 算法中训练一个自定义的 NER。

在 Spark NLP 中训练 NER 的整个流程

我们也可以将这个拟合的 NER 模型保存到磁盘上。由于 NERDL 模型是管道中的第二个阶段(第一个阶段是 BertEmbedding annotator),我们可以通过在阶段中建立索引来引用它。

ner_model.stages[1].write().save('NER_bert_20200221')

然后使用NerDLModel 注释器加载回来。

loaded_ner_model = NerDLModel.load("NER_bert_20200221")\
   .setInputCols(["sentence", "token", "bert"])\
   .setOutputCol("ner")

并在另一个流水线(即预测流水线)中使用

拟合管道并获得预测。

text = "Peter Parker is a nice man and lives in New York"prediction_data = spark.createDataFrame([[text]]).toDF("text")prediction_model = custom_ner_pipeline.fit(prediction_data)preds = prediction_model.transform(prediction_data)preds.show()

我们还可以编写一些 PySpark 函数,在 NerConverter 的ner_span的帮助下,使输出更加漂亮和有用。

我们也可以将此管道转换为 LightPipeline,以消除开销中的火花,并进行光速推断。一旦您将任何拟合的管道转换为 LightPipeline,您可以更快地轻松获得字符串或字符串列表的预测。你可以在这里找到更多关于光线管道的细节。

所有代码都可以在 Github 获得。在我们通过 Github 分享的笔记本中,你甚至会看到带有各种其他嵌入的附加实现,以及如何准备自己的 CoNLL 文件来训练定制的 NER 模型。

结论

目前就这些。在这篇文章中,我们讨论了如何在 Spark NLP 中与 BERT(NLP 镇上最酷的孩子)一起训练最先进的 NER 模型。我希望你喜欢!

我们还举办了一场关于这个主题的网络研讨会,录音可在此处获得!

我们希望您已经阅读了我们的官方媒体页面上的前几篇文章,并开始使用 Spark NLP。以下是其他文章的链接。别忘了关注我们的页面,敬请期待!

NER 与伯特在 Spark NLP 笔记本(本文)

如何使用其他单词嵌入在 Spark NLP 中训练 NER 模型(Colab)

在空气间隙网络中安装 Spark NLP 和 Spark OCR(离线模式)

Spark NLP 简介:基础和基本组件(第一部分)

Spark NLP 简介:安装和入门(第二部分)

Spark NLP Youtube 频道

为 nanoHUB.org 构建一个混合推荐系统

原文:https://towardsdatascience.com/nanohub-rec-b91e1a0beb06?source=collection_archive---------23-----------------------

为访问者和贡献者定制在线教育平台推荐器原型的案例研究

本文记录了我在 洞察数据科学 担任研究员期间(1 月-3 月)项目的构思、思考过程和结果。2020).

背景

nanoHUB.org(www.nanohub.org)是一个纳米技术教育/研究的在线平台。该网站的年访问量超过 140 万,是最大、最活跃的纳米技术在线社区之一。

图一:nanoHUB.org 主页(2020/2/10 快照)

“我们的使命是通过以用户为中心的科学工程来加速创新。我们的愿景是让科学工程产品对学习者、教育工作者、研究人员和商业人士来说是可用的、可发现的、可复制的和易于创造的。”—nanoHUB.org 使命宣言,https://nanohub.org/about

当深入研究这 140 万访问者的用户行为时,我对高流失率感到惊讶。如下图所示,大约 73%的访问者在离开网站前只访问了一个项目。换句话说,跳出率很高,这不是一个好消息。

图 2:2004 年至 2020 年数据的访客跳出率。

此外,这些反弹并不都发生在主页上,而是分散在整个网站的各个项目中。大多数流量来自搜索引擎——例如,当一名学生在谷歌上搜索一个纳米技术术语时,可能会出现几个 nanoHUB 项目。因此,这不是主页设计的 UX 问题,而是访问者在查看一个项目后失去兴趣的普遍问题。

“消费者研究表明,典型的网络会员在做出选择大约 60 至 90 秒后会失去兴趣……”卡洛斯·戈麦斯·乌里韦和尼尔·亨特。2016.网飞推荐系统:算法、商业价值和创新。ACM Trans 管理。Inf。系统。6、4、第十三条(2016 年 12 月),DOI:https://DOI . org/10.1145/2843948

推荐系统的主要目标是通过将相关商品放在点击可及的范围内来吸引访问者,看起来这正是 nanoHUB 所需要的。

提高访客留存率有利于 nanoHUB 的商业模式。作为一个内容依赖于社区贡献者自愿贡献的在线平台,贡献者群体与访问者群体相比同样重要。所以在设计推荐人制度的时候,不能忘记投稿人的利益。

一般来说,贡献者希望他们的内容被使用和认可。新内容尤其难以吸引注意力。如果一个推荐系统建立的不小心,那么受欢迎的项目会获得更多的推荐流量,在推荐系统中这个所谓的“富人越来越富”的问题上变得更加受欢迎(详见下面 Baptiste Rocca 的精彩文章)。显然,在设计有效的推荐系统时,还必须考虑贡献者的利益,即公平地重新分配推荐者流量,以推广新的和未充分使用的项目。

[## 推荐系统简介

几种主要推荐算法综述。

towardsdatascience.com](/introduction-to-recommender-systems-6c66cf15ada)

最后,与贡献者的兴趣相似,nanoHUB 的商业模式更喜欢推广一种特殊的项目——在线模拟工具(https://nanohub.org/resources/tools)。这些工具是 nanoHUB 的明星产品,具有长期的商业重要性和影响。只要有可能,我想把它们推荐给用户来推广它们。

业务 KPI

综上所述,本项目追求三个业务 KPI:
1 .推荐器有效性:该 KPI 可以基于 ML 模型的准确性进行评估。
2。覆盖率:这个 KPI 被定义为推荐者流量覆盖项目的均匀程度。
3。特殊产品促销:该 KPI 定义为特殊种类物品——模拟工具——的预期流量增加量。

我想花点时间来回答这个问题“人为地保持所有项目的覆盖范围一致真的公平吗?”在我看来,不是的。项目的质量当然各不相同,高质量的内容自然会吸引更多的访问者。人为地保持所有项目接收相同的流量将冲淡用户观看的内容质量。因此,从长远来看,这样做会损害业务。然而,策略是最初提供统一的覆盖作为起点,低质量的内容将获得低评级。在未来的某一点上,项目的评级将成为推荐系统的一个特征,并且覆盖范围将根据项目的评级进行相应的调整。这超出了为期 3 周的洞察项目的范围,将在下一阶段实施。

数据准备和设置

为了建立推荐系统,需要访问者-项目交互数据。这些数据告诉我们哪个访问者在什么时间查看了哪个项目。由于 nanoHUB 不需要注册就可以查看除模拟工具之外的项目,所以我不能依靠注册用户的网络数据来形成训练集。这样形成的数据集是不完整的,并且严重偏向模拟工具,因为访问者需要注册和登录才能使用模拟工具。此外,网络 cookie 的使用是最近为 nanoHUB 添加的,仍处于实验阶段,所以我不能依赖 cookie 来形成用户活动会话。因此,需要一种特别的方法。

为了简单起见,我决定使用 nanoHUB OLAP 数据库中的 web 日志表。这个 web 日志表是原始 Apache web 日志的过滤版本,由跨越 17 年的 4 亿行组成。

图 3:数据清理过程和访问者会话形成的总结。

在检查了 web 日志之后,我意识到在这个数据清理过程中有两个挑战。如何有效聚合日志形成用户会话?
2。移除 bot/crawler 流量

用户会话被定义为访问者连续活动的一部分。比如 IP 123.456.789.11 在特定时间访问了 A 项、B 项、C 项。这些形成了构建推荐系统所需的用户-项目交互矩阵。具有少于 2 个项目的任何会话对于形成用户-项目交互矩阵是无用的,因此被移除。为了防止共享相同 IP 地址的两个访问者的错误加入(这种情况可能发生在例如大学实验室中),当 IP 地址在 12 小时后变为非活动时,会话结束。

为了处理大量数据,SQLAlchemy 用于将数据从 OLAP 数据库虹吸到本地 HPC 环境中,Spark 用于将日志映射到会话中。在具有 20 个核心和 64 GB RAM 的单个节点下,这个 mapreduce 过程可以在 8 小时内完成。

数据探索过程中的一个观察结果是发现了剩余的 bot/crawler 流量。SQL 中过滤后的 web 日志应该会删除所有 bot/crawler 流量。然而,发现事实并非如此。从原始的 Apache web 日志到 SQL,这个过程主要依赖于 bot/crawler 的自我识别。例如,来自 Bing bot 和 Knowledge AI 的两个日志如下图所示。

图 4:(左上)一个可疑机器人从主页爬行的网络日志。(右)可疑机器人的访问次数与在每个页面上花费的秒数。显然,在 2300 页上花 1 秒钟很可能是非人类行为。(左下)来自 Bing 和 Knowledge AI 的自识别爬虫流量。

并非所有的机器人/爬虫都能自我识别。在上图中,检测到一个可疑 bot 行为的实例,显示从主页开始的周期性(大约 1 秒)爬行行为。这种记录必须被识别和删除,因为它们是非人类的,并且使结果偏向网络图的连通性。部署了两种策略来对抗这些非自我识别的机器人/爬虫:1 .基于聚类的僵尸检测技术;2 .使用用户项目协同过滤技术。

图 5:(左)散点图和(右)KDE 图,显示了已访问的项目数与活动(> 200 个已访问项目)人群的平均时间。每个点都是一个独立的 IP 地址。

为了获得可疑 bot/crawler 流量的概览,我绘制了每个 IP 地址访问的项目数与平均花费时间的关系。这些聚集的度量是 IP 地址行为的相当粗糙的表示。可以使用会话来代替,但是如果检测到某个 IP 地址有 bot/crawler 行为,它的所有会话都会被丢弃。选择这些指标也是为了避免大量的数据点。总体而言,散点图和 KDE 图中的已访问项目数与平均花费时间图如上所示,其中仅显示了已访问项目数> 100 的部分,从现在开始,我将称之为“高使用率人群”。从 KDE 图中,可以看到两个不同的高使用率人群。一个是用红色虚线标记的,圈出了平均每项花费时间低而使用率高的人群。这对应于 IP 是爬虫的高可能性。另一方面,用蓝色虚线标记的另一条曲线,圈出了显示每个项目平均花费时间高和使用率高的人群。这可能是一个正常的活跃用户。

在没有进行详细的聚类分析的情况下,我应用了一个简单的截止方法,从数据集中删除大于 200 个项目并且平均花费时间少于 40 秒的 IP。

总体而言,与总体会话相比,可疑的 bot/crawler 数量较少。此外,用户-项目协同过滤技术具有一定的防范爬虫的能力。直觉是,机器人/爬虫的行为方式类似,查看大量与 web 图形空间密切相关的项目,并且很可能集中在主页周围。这导致内容相似的大型会话。普通访客的会话要小得多,内容也多样化。在用户项目协同过滤下,当寻找与普通访问者行为相似的访问者时,机器人/爬虫因此被过滤掉。

由于 bot 检测不是这个项目的主要主题,我不会进一步复杂化这项工作,而是使用清理后的数据集(总共约 200 万个会话)来构建 nanoHUB 的推荐系统。

注意:小型数据集可能面临许多独特的挑战。我最近了解到一个有趣的项目,该项目通过 Minting 预测了加州附属住宅单元的采用,Minting 遇到了一个小数据集问题,并使用各种 ML 技术解决了该问题。

[## 甜蜜的家!

预测加州附属住宅单元的采用情况

medium.com](https://medium.com/@mintingye_43620/home-sweet-home-747df73d8808)

EDA:基础

进行基本的 EDA 是为了理解数据、获得洞察力、确认直觉和发现异常。其中包括以下:
1。每次会话查看的项目数量直方图:如图 2 所示,证实了高跳出率的用户行为。
2。跟踪已知用户以验证会话形成:我检查已知用户(包括我自己)的会话,并直观地检查活动。这些行为可以被直观地解释,并且从这种观察来看,会话被认为是准确的。
3。特性探索,会话长度:项目之间的持续时间可以解释为用户在该项目上花费的时间。这可能与用户对该项目的情感相关,因为被吸引的用户更关注该项,导致更长的会话。然而,这取决于各种因素,包括项目内容长度、假设用户没有停止另一个活动(午休、访问一些其他网站等)。).因此,该特征不包括在研究中。
4。特征探索、内容相似度:当按时间顺序(项目+下一个查看的项目)检查相邻活动时,发现内容相似度很高。这将在后面的章节中讨论,并成为提高推荐器准确性的重要特征。

EDA:覆盖率

网站流量常见的一个关键问题是“长尾”问题:很少有高访问量的热门项目,而很多访问量低的项目。这也发生在 nanoHUB 上,如图 6 所示。

图 6:(左)nanoHUB.org 项目(资源)的“长尾”。(右图)在未优化推荐流量的情况下实施标准推荐系统时,“越富越富”问题的图示。

这种“长尾”问题对 nanoHUB 的贡献者来说是不可取的,并伤害了他们贡献内容的动机,这对 nanoHUB 依赖自愿贡献者的内容来繁荣的商业模式产生了负面影响。贡献者更喜欢他们自己内容被广泛快速的曝光。“广泛”曝光是指浏览该项目的访问者数量。这是一个长期的指标,也是基于项目的优点-如果项目是低质量的,这是可以理解的,也是合理的低流量。这种基于价值的度量是项目的评级,并且由于时间限制,在推荐系统中没有实现。“快速”曝光意味着新发布的内容需要以主动的方式“推”给相关受众,而不是被动地等待被发现。通过修改覆盖范围并积极地推广未被访问的和新的项目,推荐系统可以给贡献者快速展示他们的新内容。

模型

推荐系统有多种模型,从协同过滤技术到神经网络。对于这些技术的回顾,我推荐 Pavel 的关于推荐系统的机器学习系列。为了演示基于神经网络的推荐系统如何为用户提供有效和定制的体验,我想向您介绍我的朋友 Sid Wang 博士最近的项目:commaful 的故事推荐系统。

[## 面向商业的故事推荐系统;

你读故事,我们读你

medium.com](https://medium.com/@yuwang2020/a-story-recommender-system-for-commaful-c9fd08045aaf)

对于这项工作,我选择了用户项目协作过滤技术,因为它的简单性和可解释性。此外,正如附录中所讨论的,它提供了一定程度的抵御 bot/crawler 流量的健壮性,我只是以一种非常简单和特别的方式删除了它。

用户项目协同过滤技术的基本原理如图 7 所示。为了向访问者(“A”)推荐下一个项目,只需找到最相似的访问者(“B”),并向访问者 A 推荐访问者 B 的项目。这是通过 kNN 搜索完成的,每个项目是一个特征(维度),每个用户是一个数据点。

图 7:用户项目协同过滤技术的图示。

整个流程如图 8 所示。大约 200 万个会话被分成 85%-15%的训练测试部分。训练数据集用于构建用于协同过滤的用户-项目交互矩阵。测试数据集从每个会话中移除 1 个项目,并等待测试。对于测试数据集中的每个会话,推荐器给出 5 个推荐项目。将这些推荐项目与延期结果进行比较,如果延期结果与 5 个推荐项目中的任何一个匹配,则得分为 1,否则为 0。最终,标准的用户项目协同过滤技术给出了大约 15%的准确率,推荐了 5 个项目。

图 8:采用标准用户项目协同过滤技术的推荐系统的整体流程。

不算太坏。让我们花点时间研究一下这个误差,看看这个误差是否可以减小。因此,该策略是混合推荐系统的策略。对于标准用户项目协同过滤所缺乏的各个方面,我用来自更强预测器的另一个项目替换最不相似的项目。因此,混合推荐系统应该优于标准的用户-项目协同过滤。

图 9:这项工作的一般策略:用来自更强预测器的另一个项目替换最不相似的项目。这就是混合推荐系统的本质。

错误减少:关联规则挖掘

关联规则挖掘,也称为购物篮分析或 apriori 算法,是一种发现项目之间关联的技术。我推荐 Surya 的文章关联规则挖掘来回顾这个概念。本质上,从用户-项目交互矩阵中,它能够说出诸如“如果访问者选择了项目 A 和 B,根据我对这种情况的观察,我非常确定项目 C 也被选择了”这样的陈述(规则)直观上,这种陈述的确定性称为“置信度”,这种规则的观察次数称为“支持度”。图 10 显示了挖掘出的强关联规则及其分布的例子。

图 10:(左)从训练数据集中挖掘强关联规则的例子。显示置信度和支持度(以计数为单位,而不是通常的百分比)。(右)所有挖掘出的关联规则的置信度分布显示出包含高置信度规则的递减尾部。

为什么要在用户项目协同过滤中挖掘关联规则?用户-项目协同过滤依赖于用户相似性进行推荐。另一方面,关联规则挖掘依赖于项目间的相关性来进行推荐。有了以上的理解,另一个奇怪的问题出现了:“关联规则挖掘比传统的项目-项目协同过滤有什么优势?”

事实上,关联规则挖掘和项目-项目协同过滤之间的差异很小,而且经常讨论不足。到目前为止,我发现的最好的讨论之一来自一个交叉验证的帖子这里。另外我想提供一些我的看法:
1。关联规则挖掘给出了两个直观的度量:置信度和支持度。这些度量标准,由于其直观的本质,在选择包含什么规则时是非常好的处理方法。例如,在这项工作中,我选择置信下限为 85%,支持值为 200。这直观地解释为“任何具有 85%正确率并在我的数据集中出现超过 200 次的关联规则,我将直接应用它们,而不管其他条件。”
2。关联规则挖掘对于流行项目的优势是健壮的。例如,如果项目 A & B 作为一个事实总是一起出现,但是访问者使用了项目(A,X,Y,Z)。(X,Y,Z)可以是非常受欢迎的项目,并且用户-项目或项目-项目协同过滤技术可以基于(X,Y,Z)推荐而忽略(A)。因为我们在 200 个计数上应用了支持截止,所以关联规则加强了对中等流行项目的预测。

减少错误:基于内容的建模

对我来说,在 EDA 过程中出现了一个“啊哈”时刻:如果没有有效的推荐系统,访问者如何从一个项目跳到下一个项目?无论答案是什么,都应该是一个需要考虑的重要特征。

为了发现项目之间的关联活动,我查看网络活动日志寻找答案。这一次,项目访问之间的事件掌握着线索。通过对一个月(2019/3/1–2019/4/1)的网络日志进行子采样,约 60%的关联事件是文本搜索、作者姓名 URL 点击或内容标签点击。因此,我决定使用标题文本相似性作为构建基于内容的模型的关键特征。由于时间限制,也为了避免受欢迎的作者占主导地位,作者姓名作为一个功能被放弃了——“富人越来越富”的问题,但就作者而言。由于 nanoHUB 计划对标签进行彻底检查,因此放弃了将标签作为一项功能。标签的质量也很低 nanoHUB 上的标签数量比商品总数还多,许多作者疯狂地将从“yoga”到自己名字的任何东西都贴上标签。

图 11:EDA 过程中的“啊哈”时刻。游客如何从一个项目转移到下一个项目?

标准的自然语言处理过程被应用于将标题转化为可用特征的准备工作中。使用 SpaCy,停用词首先被删除,但是词干化和词条化没有被应用,因为许多词是高度技术性的。比如“隧穿”是一个物理学术语,简化为“隧道”可能不太合适。在停用词被删除后,词频被绘制出来,如图 12 中左图所示。项目标题的词频,不出所料,大多遵循 Zipf 定律。最常见的词出现违规,这些词大多是与纳米技术相关的领域关键词。换句话说,这些包含的信息很少,在将一个项目与另一个项目分开时帮助很小。

为了加快速度,我决定去掉流行的词,只保留不常用的词,但是我还需要确保不常用的词能够覆盖所有的条目。图 12 的右侧显示了项目覆盖率与应用文档频率截止的关系。通过包含仅在所有标题中出现约 1%的罕见词,几乎所有条目都可以被表示。这样做可以减少词汇量,提高计算速度。

图 12:(左)去除停用词后的词频图。(右)涵盖的项目数与文档频率截止值

在将完整的标题简化为用生僻字表示的形式后,我准备分析它们的相似性。在两个标题之间,相似性被定义为(共享单词的数量)/(较短标题中的单词的数量)。这是相似性的一个相当粗略但快速的定义。

进行 t 检验:1 .训练集中每个会话中按时间顺序相邻的项目对,以及 2。来自所有标题的随机项目对。结果分布如图 13 所示。

图 13 :(左)随机配对抽样与(右)相邻配对抽样的相似性得分分布。

很明显,两个抽样分布偶然出现的零假设可以被拒绝。访问者选择的项目和下一个项目具有相似的标题。

图 14:在线和离线评估标题相似性的内容建模管道。左下角显示了两个相似性得分示例。

因此,从现在开始,推荐者的任务是琐碎的。给定前一个项目,推荐器在所有项目中搜索并找到一个具有最相似标题的项目。如果相似性得分高于临界值(在本工作中,相似性临界值= 0.75),则该项目被接受为推荐。否则,不进行基于内容相似性的推荐。这遵循混合推荐系统的一般策略:尝试用来自更强预测器的项目替换最不相似的项目,如果这样的预测器存在的话。

寻找具有最相似标题的项目可能是一项计算量很大的任务。例如,对于 8000 个项目的总体而言,(8000 * 8000/2–8000)=必须进行超过 3100 万次评估。这对于并行处理来说还是可以管理的,但是随着项目数量的成倍增长,这很快就会变成一项不可能完成的任务。使用这种预先生成的表的优点是速度,因为它有效地减轻了离线计算标题相似性的负担,即每周重新计算相似性表。在在线评估中,计算标题相似性的任务是即时完成的。然而,这并不意味着需要评估(1 * 8000–1)= 7999 次,因为不是与一般项目群体进行比较,而是可以将其与来自用户项目协同过滤的候选项目进行比较,这减少了所需的评估数量。在这个项目中,我选择在线评估。

注意,通过以这种方式引入基于内容的建模,解决了标准协作过滤技术的另一个弱点:缺少项目的时间顺序作为特征。事实上,访问者所访问的项目的特定顺序对于协同过滤技术没有价值,因为用户-项目交互矩阵去除了任何时间顺序和重复。事实上,访问者决定下一步要看的内容,从邻居抽样项目对中可以明显看出,在内容相似性方面是高度相关的。因此,基于内容的建模的引入解决了标准用户-项目协同过滤技术的缺点,并增强了推荐系统。

减少错误:基于规则的建模

另一个观察结果来自前面的标题相似性方面:标题相似的一个主要原因是它们中的很大一部分是讲座。图 15 显示了在测试数据集中正确和错误推荐的情况下相邻对的项目类型。讲座与讲座之间的差异是误差的重要组成部分。

图 15:在测试数据集中正确和错误推荐的情况下,来自相邻对的不同类型的项目

访问者与讲座相关的行为是相当可预测的:访问者倾向于观看系列中的下一个讲座。这可以简单地通过观察相邻项目对中的项目来得出结论,这具有直观的意义。

图 16:基于内容的建模管道。如果时间上的前一个项目是一个讲座,则推荐系列的下一个讲座。

为了捕捉访问者可能观看系列中的下一个讲座的趋势,我实现了检测讲座并找到系列中的下一个讲座的函数。该功能扫描所有项目,以“ABC 123 讲座 09…”的形式捕获标题,“XYZ 123:标题”等。对于讲座编号不存在的情况,例如“XYZ 123:标题”,讲座按照访问者数量降序排序。这是基于一个假设,即随着讲座系列的继续,观众的数量会减少。

覆盖范围-准确性权衡

除了提高推荐准确率,还必须满足业务 KPIs)和(3):
2。覆盖率:这个 KPI 被定义为推荐者流量覆盖项目的均匀程度。
3。特殊产品推广:该 KPI 定义为特殊种类物品——模拟工具的预期流量增加量。

如果推荐系统按原样部署,也就是说,在不考虑其他因素的情况下被调整到最大的准确性,则所得到的流量模式被标记为“之前”,如图 17 所示。图 17 中显示的每个点都是一个单独的项目。“当前流量”是该项目从网络活动日志中收到的访问者数量。然后,每个项目的“当前流量”被平均分成 5 份,并分配给 5 个推荐项目中的每一个。这是一个非常理想的情况,假设访问者会点击推荐者。这样一来,原来的流量被重新分配,被贴上了“来自推荐者的流量”的标签。显然,存在“富人越来越富”的问题——已经受欢迎的项目也从推荐者那里获得更多的重定向流量。

为了提升较少访问的项目,使用先前的替换方法,除了不是用来自更强预测器的项目替换最不相似的项目,而是现在用较少访问的项目替换它。当然,就推荐器性能而言,这个较少访问的项目将不如它所替代的项目好。希望是,通过替换 5 个推荐项目列表中最不相似的项目,准确度损失的量将很小,而覆盖增益的量将很大。换句话说,我愿意用精确度的小幅度下降来换取覆盖范围的大幅度增加。

图 17:(左)推荐较少访问项目的策略。通过将每个较少访问的项目与 5 个推荐反向配对,并随后根据可见性(访问者数量/天)对它们进行排名,覆盖范围和相关性得到了平衡。(右)覆盖优化前后访客流量与推荐者重定向流量的对比。

当选择这种较少访问的项目时,必须在相关性和覆盖范围之间保持微妙的平衡。为了选择较少被访问但也相关的项目,首先基于项目的可见性对其进行排序,可见性被定义为每天的平均访问者数量。这为项目建立了一个优先级队列——当被选择推荐时,较稀有的项目将具有优先级。每个项目通过推荐系统运行,以获得 5 个最相关的项目。这是一个单项建议,如图 17 所示。为了不与主推荐者混淆,我将这个表称为“较少访问的项目推荐者列表”。当向访问者发布推荐时,从最少访问的项目开始遍历“较少访问的项目推荐者列表”,并且如果任何推荐的项目与访问者在会话日志中查看的任何项目相匹配,则选择较少访问的项目来替换推荐者列表中最不相似的项目。

由此产生的覆盖率改进如图 17 所示。在覆盖优化之前(标为“之前”),存在“富者愈富”的问题。优化后(标记为“After”),所有项目的推荐流量更加平衡,确保所有项目通过推荐系统对访问者具有良好的可见性。

另一个重要的商业指标是模拟工具的推广。为了保持管道简单,模拟工具,不管受欢迎程度如何,都被放在“较少访问的项目推荐列表”的顶部。这给了他们被选中的最高优先权。

结果

对于上面描述的所有模型例程,整个管道如图 18 所示。

图 18:整个推荐系统管道。

在引入基于规则的建模、基于内容的建模和关联规则挖掘之后,整个混合推荐系统达到了 32%的准确率,相比之下,标准协同过滤技术的初始准确率为 13%。在将最不相似的项目替换为较少访问的项目后,准确率略微损失到 29%,但覆盖率显著增加到 85%。这就是上一节提到的“精确度-覆盖率”的折衷。

关于管道的一个细节是模型的排列(用黑色标记),遵循标准的协同过滤。没有直接的比较来定量地衡量从各种技术中选取的项目之间的相似性得分。一个假设是,随后的模型是比标准的协同过滤技术更强的预测器。因此,插入总是出现在队列的开头,而移除总是在末尾。

生产实施计划

由于时间限制,推荐系统是在 Jupyter 笔记本环境中原型化的,不适合生产。然而,这并不意味着推荐系统的设计没有考虑产品。我想在这里简单地谈谈我将这个模型投入生产的计划,这是这个项目的下一阶段。

为了使其适合于生产,推荐系统是用流线型的、更简单的模型而不是计算昂贵的、高级的模型如神经网络来构建的。正如前面所讨论的,这个决定对我们的模型施加了一些限制:协同过滤不考虑事件的特定时间顺序,但是像 LSTM 和马尔可夫链模型这样的高级技术可以。访问者查看的项目已被证明在时间顺序上是相关的,这一缺失的特征可能有助于进一步提高模型的准确性。模型复杂性、可解释性和产品可部署性之间的权衡是一个重要的优化,需要进一步的工作。目前,我坚持使用不太复杂的模型,以获得更好的可解释性和可部署性。

生产的另一个重要方面是计算成本。如果建议是基于访问者的会话日志,那么这个建议是在线的,这意味着根据访问者的当前会话数据实时计算接下来的 5 个项目。这可能是一项计算量很大的任务。当我以稍微不同的方式对模型进行训练测试时,发生了一些奇怪的事情。不是使用每个访问者的完整会话日志,而是将会话分成 2 个一组的元组。例如,如果访问者以时间顺序(1,2,3,4)查看项目,则结果元组是(1,2),(2,3),(3,4)。每个元组可以被视为一个新的小型会话。测试集以相同的方式形成,并且元组中的第二项(时间上较晚的项)被保留。如果用这样的二元组训练推荐系统,得到的准确度大约是 19%。

这是一个奇怪的观察,因为它表明了访问者的项目偏好的马尔可夫属性,也就是说,访问者的下一个项目很可能依赖于并且仅依赖于之前查看的项目。访问者行为的马尔可夫性假设可以将推荐计算的负担从在线转移到离线,代价是准确率下降约 10%。如果我愿意做出这样的折衷,生产的解决方案就会变得简单得多。推荐器离线基于从 web 日志生成的访问者会话的二元组为每个项目计算 5 个项目。例如,这种刷新可以由 cron 调用,并且每周执行一次。
2。产生的推荐可以存储在 SQL 表中,主键是项目 ID,一列包含 5 个推荐的项目。
3。推荐 SQL 表可以由前端拉,并显示在现场网站。

结论

在这个项目中,一个混合推荐系统的原型是 nanoHUB.org,一个每年有超过 140 万访问者的在线教育和研究平台。混合推荐系统由用户-项目协同过滤、基于内容的模型、基于规则的模型和关联规则挖掘组成。附加模块修改最终建议,以优化覆盖范围和模拟工具推广。总体而言,推荐系统实现了 29%的准确率和 85%的覆盖率。推荐系统满足目标业务 KPI,包括推荐准确性、覆盖范围和特殊内容推广。我希望这个新功能可以增强每年 140 万用户的 nanoHUB 浏览体验,并了解更多关于纳米技术的知识!

缩小数据范围

原文:https://towardsdatascience.com/narrowing-the-data-3adeb6e04b02?source=collection_archive---------41-----------------------

缩小大型数据集范围的技术探索。

阿什利·朱利斯在 Unsplash 上拍摄的照片

最近,我完成了一个项目,预测美国面临粮食不安全风险的社区。你可以在这里找到关于那个项目的信息,包括代码和一个 PowerPoint 演示。在那个项目中,我使用了美国农业部的政府数据集,名为 SNAP QC 数据。这些是超过 40k 条记录和 800 多个特性的大规模数据集,并附有解释特性的技术文档。我将对我如何缩小数据集进行技术分析。

什么是 QC 数据集?

美国农业部的 SNAP 程序使用“质量控制”数据。这些是质量控制数据集,这意味着它们已经以某种方式被手工挑选出来,以纳入最终的数据集。不幸的是,这些精挑细选的标准每年都在变化,尽管变化并不剧烈。由于政府数据对于这些项目来说是如此庞大,统计学家们正试图实现一些“特征”,这些特征代表了对那些参与项目的人的外部影响。对于 SNAP 参与者,大量不完整的申请被排除在外,这导致这些数据集更能代表受益者,而不是所有申请该计划的人。此外,这些数据集是加权的。这些权重是由对各州的经济影响决定的。例如,如果一个州宣布进入紧急状态,参与者的权重就会降低,以减少异常值对整个数据集的影响。

缩小数据范围:GIS

对 2007-2008 年数据的空间分析显示,与邻近县相比,这些县是异常值。这是在 ESRI 空间数据科学 MOOC 期间完成的。首先,构建了一个 2D 模型,它可以直观地显示一个县一年到下一年的变化。这是用 ESRI 的“2D 时间序列分析”工具建立的。接下来,使用他们的“新兴热点分析”工具来显示从 2007 年到 2008 年在统计上与其周围邻居有显著差异的县。

它通过“使用您提供的空间关系的概念化值来计算每个条柱的 Getis-Ord Gi*统计 ( 热点分析)来实现这一点。时空热点分析完成后,输入 NetCDF 立方体中的每个条柱都会添加相关的 z 值、p 值和热点条柱分类。接下来,使用 Mann-Kendall 趋势测试评估这些热点和冷点趋势。使用数据得到的每个位置的趋势 z 值和 p 值,以及每个条柱的热点 z 值和 p 值,新兴热点分析工具对每个研究区域位置进行分类。—摘自工具上的 ArcGIS Pro 文档

结果突出了新墨西哥州圣胡安的一个使用增加的热点。以及内布拉斯加州樱桃县的一个新兴冷点,那里的参与者减少了。由于 QC 快照数据来自州一级,无法按县过滤,我选择比较内布拉斯加州和新墨西哥州,以突出极端情况。我还想做一个 10 年的缺口分析,以反映 2008 年危机对面临粮食不安全风险的社区的影响。所以我最终得到了 4 个数据集:2007 年新墨西哥州和内布拉斯加州,2017 年新墨西哥州和内布拉斯加州。

由此产生的“新兴热点分析”图。(图片由作者提供)

缩小数据范围:高无效性

为了进一步缩小数据范围,我选择移除 100%为空的列,这意味着它们是不包含数据的要素。这些功能可能是为了在全国范围内使用而添加的,根本不符合内布拉斯加州或新墨西哥州申请人的任何用例。对于内布拉斯加州和新墨西哥州来说,这些列是不同的,从 2007 年到 2017 年,它们也是不同的列。简单地说,每个数据集中所有空值的列都被删除。

接下来,我发现了一篇名为“缺失数据的比例不应用于指导多重插补的决策”的论文,该论文讨论了高无效性的潜在概念。这篇论文得出的结论是,如果没有足够的信息来真实地表现这些特征,从这些栏目中收集的信息的完整性就会受到威胁。作者测试并得出结论,数据的价值比缺失的信息量更重要。因此,我决定将这些数据集中的高空性定义为超过 50%的记录被标记为空值的列。我做出这个假设是基于这样一个事实,即我在每个数据集中有大量的记录,这些记录至少有 50%或更多的数据是原始的。然后我删除了那些高无效列。

最后,在使用预测模型之前,我必须考虑数据集中剩余的空值。因此,我使用 sklearn 的简单估算器来输入其余值的平均值。使用平均值是因为一旦去除了高无效性特征,它是原始数据的合理表示。

移除高 nullity 值的列后剩余的列数。(图片由作者提供)

缩小数据范围:相关性

我选择将我的模型作为监督模型运行,目标变量为“猫 _ELIG”。这是一个将每个应用程序标记为“是”或“否”的字段,表示它们有资格获得 SNAP 优势。这在 2007 年还好,但在 2017 年,内布拉斯加州和新墨西哥州的所有申请都被接受。因此,与目标变量的相关性仅在使用 2007 年数据集时有效。为了进一步增加相关性的维度,我可以使用 PCA(主成分分析)来运行 2017 年的数据,PCA 最适合推断无监督数据之间的相关性(这意味着不定义目标变量,因为所有应用程序在 2017 年对“CAT_ELIG”都标记为“是”)。不过,我在这里的目的是在 2007 年,即最初的 GIS 热点分析年,找到统计上显著的相关性,并看看它们在 2017 年如何变化。

技术文件包括 6 个观察部分。我的最终数据集是每个部分的前 5 个相关特征,作为最终的列集。每个数据集都有非常相似的前 5 个相关要素,从新墨西哥州到内布拉斯加州只有一些差异。最终结果是 32 个特性+目标列。

使用 2007 年新墨西哥州数据集的每个类别的前 5 个相关性的示例。(图片由作者提供)

缩小数据:型号

对于这一分析,我想要一个可解释的模型,以便更准确地描述是什么影响了粮食不安全。由于高度多重共线性的内在可能性,我需要在最终模型中降低这种风险。一篇名为“支持向量机与随机森林用于遥感图像分类:元分析和系统综述的论文讨论了 SVM 自 70 年代以来一直存在,是机器学习的真正进步,但它受到相关特征的高度影响。然而,兰登森林在一些情况下胜过了 SVM。由于随机森林使用 bootstrap 和要素采样,因此它可以同时处理行和列级别的数据集,从而大大降低多重共线性对结果的影响。最终,我选择了 Random Forest 来:

  1. 帮助缓冲与其他功能相关的功能的影响。
  2. 这给了我一个更高的精度和更少的超参数调整,从而通过不使其成为“黑盒”模型来增加其系数的可解释性。

最终找到正确模型的一个好方法是对数据进行几次初始测试,并比较分数。这可以告诉你哪些数据处理得很好。在测试和训练集上比较交叉验证的分数,以查看数据中有多少差异。对于这个项目来说,重要的是在正面预测方面出错,不管它们是否正确。这是因为,低估有需要的领域比担心被标记为需要更多支持但并不需要支持的领域更危险。因此,回忆被用来显示做出了多少正面预测,而精确则显示了多少正面预测是正确的。数字越接近,预测模型就越准确。

图片作者。

我使用带有随机森林、梯度推进和 Bagging 分类器的投票分类器来给出 95%的交叉验证分数。

  • 出于上面给出的原因,我使用了随机森林。
  • 通过平衡正精度来提高精度的梯度增强。
  • 和精度分数的 bagging 分类器。

最后的想法

每个项目都是独一无二的。虽然在这种情况下选择可解释的模型减少了可以设置的超参数,但这使得特征选择成为提高准确性的少数方法之一。数据科学家是数据将讲述什么故事的最终决定者。有很多方法可以微调我用来缩小数据的步骤,但缩小特征的数量是至关重要的,因为高方差对准确性和解释非常不利。最终,数据科学家必须根据数据和手头项目的最佳表现做出决策。

使用贝叶斯状态空间模型的预测

原文:https://towardsdatascience.com/natural-gas-price-prediction-using-bayesian-state-space-model-for-time-series-forecasting-f630dda1c808?source=collection_archive---------14-----------------------

基于单变量时间序列的价格预测

随机和季节性时间序列预测

作者图片

ime 序列观测值被假定为线性依赖于一个未被观测的状态向量,该状态向量是由状态空间分析中的随机动态过程产生的。进一步假设观测值受测量误差的影响,并且与状态向量无关。因此,构成状态空间模型的两个主要部分是观察到的数据和未观察到的状态。

时间序列由随机过程(Yt;t = 1,2,.。。),即由索引为 t(时间)的随机向量的有序序列。为简单起见,我们将考虑等距的时间点(每日数据、每月数据等等)。目标是预测下一个观测值[yn+1]的值,该值具有直到时间 n 的观测数据,(y1 = y1,.。。,yn)]。

数据加载和可视化:

barChart(NG)

这一系列看起来显然是非平稳的,实际上是非常不规则和不稳定的。从 2007 年至今,该数据处于日常水平。我们可以看到,在 2008/2009 年期间,价格从近 20 美元大幅下跌至近 1 美元,然后在 2010/2011 年期间上涨至约 15 美元;然而,一个高度动荡的状态,因为可以看到所有的日期和最后的价格记录为 8.61 美元。

  • 从这个时间序列中我们可以看出,价格肯定有一些季节性变化;每年冬天都有一个高峰,几乎每年冬天都有一个低谷的转折点。
  • 同样,这似乎可以用一个加法模型来描述,因为季节性波动的大小在一段时间内大致恒定,似乎不取决于时间序列的水平,而随机波动似乎在一段时间内恒定。

我们将进行单变量分析;因此,让我们从数据集中提取每月的“接近”价格。月度数据是为了便于计算。根据可用的计算能力,可以每小时、每天或每周采集数据。

后续数据处理对于将数据转换为数据框架和进一步的时间序列以供未来分析非常重要。

在这里,我们的数据集现在已被处理,我们准备好执行进一步的分析。

概率分布:

大多数统计模型依赖于正态分布,这种分布是对称的,具有典型的钟形。概率分布通常(不完全)用图表来表示,图表的横轴表示变量的可能值,纵轴表示发生的概率。

上面包括密度和正态 Q-Q 图的分布图清楚地表明,数据分布不是正态的,反映了非高斯特征。

平稳性测试:

上述平稳性测试的输出显示了数据的非平稳特征。

标准化:

由于随机行为的值,我们将股票预测场景中的数据规范化。这里,不建议最小-最大归一化,因为股票值不限于某个价格范围;价格具有布朗运动,可以剧烈变化。因此,建议用初等标准化函数来标准化股票价格:

z =(X-平均值(X))/标准差(X)

我们在这里看到:

  • 稳定信号几乎没有超过 ACF CI 的滞后。
  • 这种趋势导致几乎所有的滞后都超过了置信区间。

因此,可以断定 ACF 信号是平稳的。但是,趋势信号不是静止的。平稳序列在平均水平附近具有更好的方差,峰值是原始序列中干预的证据。我们将进一步分解时间序列,包括水平、趋势、季节性和噪声成分的组合。分解有助于在分析和预测过程中更好地理解问题。

分解:

分解一个时间序列意味着把它分成它的组成部分,这些组成部分通常是一个趋势部分和一个随机部分,如果数据是季节性的,则是一个季节性部分。

分解非季节性数据:

非季节性时间序列由趋势成分和随机成分组成。分解时间序列包括试图将时间序列分成这些单独的部分。一个季节性时间序列,除了趋势和随机成分外,还具有季节性成分。分解季节性时间序列意味着将时间序列分成这三个部分。让我们估计天然气 ts 的趋势、季节性和随机成分。

plot(decompose(df1), yax.flip=TRUE) # Decompose time-series

上面的图清楚地显示了趋势是不稳定的,我们可以从标准化部分的趋势信号图中看到这一点。季节性因素每年都存在一小段时间,最有可能是在冬季。总的来说,随着随机游走,价格波动很大。

单变量线性高斯状态空间模型的滤波、平滑和预测

不幸的是,状态空间模型没有普遍接受的符号。然而,在统计学和计量经济学应用中最常用的符号可以在 Harrison & Stevens (1976)和 West & Harrison (1997)的工作中找到。贝叶斯分析的主要焦点是未知参数的最大似然估计。我们将从一个局部模型开始介绍这种方法。

我们将使用一个基本水平模型进行预测,然后使用 ARIMA 和动态线性模型来比较预测结果。

状态空间模型:

状态空间模型基于这样的想法,即时间序列(Yt)是一些潜在的不可观测过程(θt,t = 1,2,.。。),称为状态过程。

结构时间序列:

状态空间框架促进了时间序列分析的结构方法。在这种方法中,不同的未观察到的成分负责系列的动态。这些是趋势变量、季节性变量、周期变量,解释变量和干预变量的影响在被放入状态空间模型之前被分别识别。让我们理解局部水平模型的数学直觉。

时间序列通常被认为是一组按时间顺序排列的观察值 y1,…,yn。这里,表示时间序列的基本模型是加法模型。该公式可以写成:

  • μt 是一个缓慢变化的分量,称为趋势;
  • ϒt 是固定周期的周期性成分,称为季节性;
  • εt 是随机噪声或称为误差的不规则分量;

为了开发合适的模型以及μt 和ϒt,我们需要随机游动的概念。我们可以考虑一个简单形式的模型,其中μt = αt,其中αt 是随机游走,不存在季节性,所有随机变量都是正态分布。我们假设εt 具有恒定方差σ2ε。这给出了模型:

对于 t = 1,…..,n,其中εt 和ηt 相互独立,独立于α1。有两个参数,σ2η。这是一个 ARIMA(0,1,1)模型,但对参数集有限制。这被称为局部水平模型,为我们的分析提供了基础。它展示了状态空间模型的特征结构,其中有一系列不可观测值α1,…,αn,它们是状态,代表所研究系统随时间的发展以及一组观察值 y1,…,yn,它们通过状态空间模型与αt 相关。这适用于经典分析和贝叶斯分析。在εt 和ηt 不是正态分布的情况下,我们从最小方差线性无偏估计的角度得到了等价的结果。

最初我们假设,α1 ~ N(α1,P1),其中α1 和 P1 已知,σ2ε和σ2η已知。因为随机行走是非平稳的,所以模型是非平稳的,并且随机变量 yt 和αt 的分布依赖于时间 t。

局部线性趋势模型,type = "trend ",具有相同的测量方程,但是在动态中具有时变斜率。基本结构模型 type = "BSM ",是一个带有额外季节性成分的局部趋势模型。

Call:
StructTS(x = df1, type = "level")

Variances:
  level  epsilon  
   1.26     0.00

线性高斯状态空间模型中的所有显著性检验(以及置信区间的构建)都基于关于分析残差的假设。残差应该满足独立性、同方差性和正态性。残差的独立性和正态性可以使用 Box-Ljung 检验统计量进行诊断。可以通过检验标准化预测误差的方差来检查同方差性。

结构时间序列的预测;

下图显示了 12 个月的预测收盘价数据,以及 50%和 90%的概率区间。

plot(forecast::forecast(fit_level, level = c(50, 90), h = 12), xlim = c(2016, 2021))

预测输出(结构局部水平):

pred <- predict(fit_level, n.ahead = 12)

ARIMA 模式:

自回归综合移动平均(ARIMA)模型可以转化为状态空间形式。

在 auto 中,arima 能够决定是否使用季节性 arima (SARIMA)模型。

auto.arima(df1, trace = T, stepwise = F, approximation = F)

# Arima 
arima <- Arima(df1, order = c(0,1,0))
checkresiduals(arima)

我们可以从第一个和最后一个图中看到,残差似乎不是白噪声。ACF 图显示残差之间不存在显著的相关性。

# Forecast of 12 months
pred_arima <- forecast::forecast(arima, h=12)
plot(pred_arima)

预测产量(ARIMA):

这种预测类似于结构时间序列。然而,我们将在下一节进一步检查动态线性模型。

动态线性模型(DLM):

动态线性模型是状态空间模型的特殊情况,其中状态和观察分量的误差是正态分布的。DLM 可以用两个方程来表示

这里,Gt 和 Ft 是已知的矩阵,而(vt)和(wt)是两个独立的白噪声序列(即,它们是独立的,在它们之间和它们的每一个内),分别具有均值为零和已知的协方差矩阵 Vt 和 Wt。

单变量时间序列(Yt,t = 1,2,.。。)是所谓的随机游走加噪声模型,定义如下:

具有任意功能 gt 和 ht,更加灵活。误差序列(vt)和(wt)是独立的。线性状态空间模型将 gt 和 ht 指定为线性函数,而高斯线性模型添加了高斯分布的假设。

随机水平和确定性季节性:

多项式 DLM(局部水平模型是一阶多项式 DLM),局部线性趋势是二阶多项式 DLM)。你可以在这里 找到更多 dlm 型号 的细节。

自变量 dV 和 dW 分别用于指定观测和演化协方差矩阵的对角线。

卡尔曼滤波器:

卡尔曼滤波器的主要目的是仅考虑观测值{y1,y2,.。。,yt1 }。因此,预测状态及其相关估计的关键属性是它们仅基于序列的历史值。过滤的目的是在每次引入新的观察值 yt 时更新我们对系统的了解。

# applying kalman filter
model_filter <- dlmFilter(df1, modelfit)
plot(residuals(model_filter, sd = FALSE), type = “o”, ylab = “Standardized prediction error”)
abline(h = 0)

卡尔曼平滑器:

卡尔曼平滑器允许计算θt|DT 的密度,从 T = t1 开始,在这种情况下,θT|DT ~ N(sT = mT,ST = CT),然后向后计算 T = T2、T = T3 等情况下的θT|DT 的密度。

随机水平和确定性季节模型的随机水平及其 90%置信区间:

预测产量(DLM):

*forecast$f*

在这里,我们可以从上面的图中看到,该模型已经能够很好地捕捉趋势。经过过滤和平滑的线条在序列中一起移动,彼此没有太大差异。未来 12 个月的预测系列线是从原始系列结束的地方选取的

如果我们比较三种预测结果,我们发现,DLM 模型能够更好地捕捉趋势。

结论:

类似的方法可以用于分析和预测单变量和多变量时间序列。这里,结构时间序列计算基本结构模型的方差参数和状态向量的滤波均值的最大似然估计,即由随机游走加噪声组成的常数 DLM,局部线性趋势。为了保持一致性,我们在所有三个模型中使用了相同的数据集。有趣的是,ARIMA &结构模型不能像 dlm 模型那样提取季节性成分。在 dlm 建模的情况下,我们没有考虑季节因素。但是,为了更好地预测,也可以添加季节性因素。

DLM 是一个相当有趣的软件包,我想在未来进一步使用它进行多变量分析。

我可以到达 这里

注意:此处描述的程序是实验性的,应谨慎使用。所有此类使用风险自负。

参考文献:

  1. Petris,g .,Petrone,S., & Campagnoli,P. (2009 年)。动态线性模型。在带 R 的动态线性模型中(第 31-84 页)。纽约州纽约市斯普林格。
  2. 乔瓦尼·佩特里斯(2010 年)。动态线性模型的 R 包。统计软件杂志,36(12),1–16。
  3. 德宾 J,库普曼 SJ (2001 年)。用状态空间方法进行时间序列分析。牛津大学出版社,牛津。
  4. 哈里森 PJ,史蒂文斯 CF (1976)。“贝叶斯预测。”皇家统计学会杂志 B,38,205–247。

基于人工神经网络的天然气现货价格预测

原文:https://towardsdatascience.com/natural-gas-spot-price-prediction-using-artificial-neural-network-56da369b2346?source=collection_archive---------21-----------------------

基本面分析的明确指南&时间序列价格预测

使用门控循环单元(GRU)架构的多变量案例研究

P 天然气价格的预测因为与原油的关联变得越来越重要。包括天然气价格在内的能源商品波动剧烈,具有高风险和不确定性。在这里,我们将研究天然气现货价格和其他变量,如气象数据、经济数据等。与气候相关的数据,包括生产相关数据、消费相关数据和温度相关数据。

数据集结合了亨利中心和 WTI 历史现货价格的月度数据以及其他相关因素( 46 个变量,不包括亨利中心和 WTI )。

问题描述

尽管我们都知道这样一个事实,冬季期间的天然气消耗量历来很高,这导致市场价格上涨。然而,市场并不按照我们预期的方式运行;问题是,与普遍的看法相反,几乎全年的价格都有显著的偏差。

为了解决上述问题,我们将使用机器学习算法来检验我们是否可以通过添加可能对天然气价格产生外部直接或间接影响的不同参数来预测未来价格。我们将尝试开发一个预测模型,根据历史价格预测天然气的现货价格。

滞后散点图可用于检查自相关性;x 轴上的数据(t)与 y 轴上的上月数据 "t-1/t-2/t-3/t-4" 。带有大圆点的对角线清楚地显示了一种关系或某种相关性。这里也可以看到中间缺少的值。

我们可以看到,序列中存在一些模式,并且序列是自相关的。滞后 1 显示数据大多集中且高度相关。然而,我们将用自相关图进一步验证这一点。空白是因为数据中缺少值。

下面,我们添加了另一个变量,即月度回报百分比变化,这使数据正常化,但巨大的波动仍然显示了亨利中心现货价格(HH)的高波动性和随机性。

让我们回顾一下 HH 时间序列在其滞后版本之间的相互关系。在下图中,蓝色阴影区域是 95%的置信区间。我们可以看到几个滞后到 10 个月。

这里,我们假设当前值依赖于它以前的值,有一些滞后。为了找到可以用来预测未来价格的最大滞后,我们查看部分自相关图,并确定大多数滞后不显著之后的滞后。这里,我们从 pacf 中看到,1 个月后有一个大的峰值,这可以用作未来预测的回顾期。

理想情况下,我们应该尝试一些不同的滞后组合

  1. 根据某种信息标准(AIC 或 BIC)选择其中的最佳者
  2. 基于它们的可能性、信息标准等对模型进行加权。

我们的数据集有很多缺失值。因此,我们创建了一个函数,用以前的值来填充丢失的值。

统计分析

让我们研究一下时间序列分布。从下面的直方图和 Jarque-Bera 正态性检验表明,价格时间序列不是正态分布的。然而,对数价格遵循高斯分布。

所以,我们可以先假设正态分布为变量的差和或天然气价格的对数。

差异通货膨胀系数(VIF)

很难从下面的相关性皮尔逊相关图中识别变量并做出任何假设。

除了相关图之外,为了确定在回归分析中导致标准误差的变量,我们使用了一个易于理解的指标(方差膨胀因子)。因此,这有助于检测数据集中的多重共线性。大 VIF (> 5)意味着存在显著的多重共线性,理想情况下,我们应该从回归分析中删除这些变量。

对于一些变量,我们的 VIF 系数大于 5,甚至更高。所有上述分析表明,使用神经网络将是一个理想的选择,也表明,理论上我们可以使用一个高自相关滞后(1)来开发一个神经网络模型。

LSTMs 在涉及自相关的时间序列预测任务中非常有用,因为它们能够在时间序列的长度上保持状态和识别模式。递归架构使得状态能够持续,或者随着每个时期的进展在权重的更新之间通信。

单变量和多变量

价格预测可以是单变量或多变量模型。

  1. 单变量模型试图通过目标变量本身及其滞后来模拟现象。在此模型中,假设所有原因都反映在价格中,则不考虑可能影响因变量行为的其他变量。
  2. 具有不同相关变量并可能影响相关价格变量的多变量模型称为外生变量。这些变量可能会根据不同的情况(如经济、社会、政治或环境)影响因变量的行为。这类模型需要预测未来的关联变量,以便预测目标变量。

这里,我们将研究使用 GRU 网络架构的第二种模型。GRU 控制信息流,而不需要使用存储单元。它相对较新,计算效率更高,结构不太复杂。

训练/测试分割

值序列对于时间序列数据至关重要。因此,我们使用如下的系统方法将训练和测试中的数据分开。此外,需要标准化来拟合用于神经网络架构学习的数据。

为神经网络准备数据

我们将准备 X_train,y_train,回看选项为 1,如前面的 acf/pacf 图所示。

GRU 网络架构

准备测试数据

一旦模型适合训练数据,我们希望看到模型在样本外数据上的技巧。与我们在训练集中所做的一样,我们将准备测试集,并且我们需要从训练数据中提取回望值。回看是用作输入变量的先前时间步长的数量,以预测下一个时间段(本例中为 1)。

诊断图

该算法的目标是在过拟合和欠拟合模型之间找到一个位置。一个好的拟合是由一个训练和验证损失确定的,该损失减少到一个稳定点,在两个最终损失值之间有一个最小的差距。你可以阅读这里了解更多关于诊断情节。

训练数据集的模型损失几乎总是低于验证数据集。这意味着我们应该预料到训练和验证损失学习曲线之间的一些差距。这种差距被称为“泛化差距”

然而,诊断图显示了非代表性训练数据集的符号,这意味着模型没有从训练集中获得足够的信息来学习问题。

实际结果与预测结果

换算预测值

我们将观察值和预测值连接在一个数据框中,以便更好地表示和报告。

准确性指标

均方误差(MSE) : MSE 测量误差平方的平均值,即估计值和实际值之间的平均平方差。MSE 越小,我们就越接近最佳拟合模式。

均方根误差(RMSE) : RMSE 是预测值和实际观测值之间的平均平方差的平方根。由于在取平均值之前误差是平方的,RMSE 对大的误差给予相对高的权重。这使得 RMSE 在不希望出现大误差时最为有效。

平均绝对误差(MAE) : MAE 是预测值和实际观测值之间绝对差异的测试样本的平均值,其中所有个体差异具有相同的权重。

实际与预测图

我们可以看到,结果并不如预期。但在这里,我们的目标是找到一个模型,拟合和预测天然气现货价格。我们采用了 1 个月的时间范围,我们的算法能够学习和预测未来的价格。学习能力和泛化能力是神经网络的关键特征。此外,其中一个优点是,可以应用线性或非线性的激活函数(model . add(Activation(" relu "或" sigmoid")) 。网络架构的内存块通过层连接。每个模块都包含用于管理状态和输出的门,并根据输入序列进行操作。而且,一个街区内的每个门都用 激活 单元来控制。默认情况下,架构使用【sigmoid】激活。这里,通过选择各种非线性函数以及神经元和层的不同排列,捕获对刺激的非线性响应。最后,我们观察到,GRU 网络结构可以有效地用于预测我们的时间序列数据的未来市场价格。

模型精度需要用更多的训练数据来测试,批量大小可以配置为 64 或 128,输入参数的数量可以是选择性的。我们使用了月度数据集,其中每日数据可能有助于实现更好的准确性。

特征重要性

我们可以从如下所述的数据集中找出 10 大重要特征来预测 Henry Hub 现货价格的月度价格变动:

  1. 美国天然气进口价格,
  2. 美国液化天然气进口,
  3. 美国天然气进口,
  4. 极端最高日温度—纽约,
  5. 美国天然气总提取量,
  6. 美国从油井中提取的天然气总量,
  7. 冷却度天数— TX,
  8. 美国天然气从气井中的总提取量
  9. 美国注入地下储气库的天然气总量
  10. 美国液化天然气出口

摘要

预测股票市场指数的准确每日价格一直是一项困难的任务。许多因素,如政治事件、总体经济状况和交易者的预期,都可能对现货价格指数产生影响。这里,我们应用了几个输入变量来预测未来 12 个月的价格方向。然而,通过选择有效的输入指示符,可以进一步提高预测性能。此外,我们可以包括一些可能影响预测性能的其他技术指标。实验中的模型以回归的方式解决了这个问题。回归模型可以与预测上升和下降的分类模型相结合,以提高精确预测的方向准确性。此外,由于非参数建模方法需要更多的训练数据来估计映射函数,因此需要用大量数据来测试同一模型的预测精度。

我可以到达 这里

自然梯度

原文:https://towardsdatascience.com/natural-gradient-ce454b3dcdfa?source=collection_archive---------4-----------------------

梯度助推器

梯度下降更好的梯度?

我们从这个系列中走了一个简短的弯路来理解什么是自然渐变。我们在梯度推进世界中考察的下一个算法是 NGBoost,为了完全理解它,我们需要理解什么是自然梯度。

保罗·吉尔摩Unsplash 上拍摄的照片

预读:我将谈论 KL 散度,如果你对这个概念不熟悉,暂停一下,跟上进度。我在另一篇文章中给出了熵、交叉熵和 KL 散度背后的数学和直觉。

我也假设对梯度下降基本熟悉。我相信你会在网上找到上百万篇关于梯度下降的文章。

有时,在解释过程中,我们可能会涉及一些数学内容。但是只要有可能,我也会提供直觉,这样如果你不喜欢数学和方程式,你可以直接跳到直觉。

梯度下降

互联网上有一百万篇文章解释什么是梯度下降,但这不是第一百万篇文章。简而言之,我们将只涉及足够的梯度下降,使前面的讨论相关。

问题设置是:给定一个函数,我们想找到它的最小值。在机器学习中,这通常是损失函数,并且是算法的参数(例如,在神经网络中是网络的权重和偏差)。

  1. 我们为 x 取一个初始值,大多是随机的,
  2. 我们计算损失函数的梯度 w.r.t .参数 x

3.我们调整参数 x ,使得

,其中α是学习率

  1. 重复 2 和 3,直到我们对损失值感到满意。

来源:关于梯度下降的更多数学公式,你可以访问 Sebastian Raschka 的 mlxtend

该算法有两个主要成分——梯度和学习率。

梯度无非是损失函数 w.r.t .的一阶导数。这也叫做函数在该点的斜率。从高中几何中,我们知道斜率可以有符号,根据符号我们知道哪个方向是“下”。例如,在上图中,梯度或斜率是负的,我们知道我们必须向负方向移动才能达到最小值。所以梯度也给了你需要移动的方向,这就是梯度下降使用的性质。

学习率 是一个必要的缩放,应用于每次的梯度更新。它只是一个很小的量,我们用它来限制基于梯度的参数更新,以确保我们的算法收敛。我们将很快讨论为什么我们需要它。

限制

梯度下降的第一个陷阱是步长。我们使用损失函数的梯度来调整参数 x (按学习率缩放)。

来源:讲稿马克·图森

梯度是损失函数的一阶导数,根据定义,它只知道计算点的斜率。这是短视的,因为斜率甚至是无穷小距离上的一点。在上图中,我们可以看到两个点,陡坡上的点具有较高的梯度值,几乎平坦的点具有较小的梯度值。但这是否意味着我们应该分别迈出更大或更小的步伐?因此,我们只能将梯度给出的方向作为绝对真理,并使用超参数 学习速率 来管理步长。这个超参数确保我们不会跳过最小值(如果步长太大)或永远达不到最小值(如果步长太小)。

这是你在几乎所有一阶优化算法中都能找到的一个陷阱。解决它的一种方法是使用二阶导数,它也告诉你函数的曲率,并在此基础上进行更新步骤,这就是牛顿拉夫森优化方法所做的(在以前的一篇博客文章中的附录)。但是二阶优化方法有其自身的问题——计算和分析的复杂性。

另一个缺陷是,这次更新通过学习率来衡量所有的参数,从而将所有的参数都一视同仁。可能有一些参数对损失函数的影响比其他参数更大,通过限制这些参数的更新,我们使算法收敛的时间更长。

替代方案

有什么选择?恒定的学习率更新就像是我们给算法的一个安全垫,这样它就不会盲目地从一个点冲到另一个点,完全错过最小值。但是我们可以用另一种方法来实现这个安全垫。

我们可以固定目标输出的分布空间中的距离,而不是固定每个参数移动的欧几里德距离(参数空间中的距离)。即,不是在ε距离内改变所有参数,而是我们将模型的输出分布约束在来自前一步骤的分布的ε距离内。

现在我们如何测量两个分布之间的距离?库尔贝克-莱布勒散度。虽然从技术上来说不是距离(因为它是不对称的),但在它被定义的位置上,它可以被认为是距离。这对我们来说很好,因为我们也关心当我们在参数空间中做小的步骤时,输出分布如何变化。本质上,我们不像在正常梯度下降中那样在欧几里得参数空间中移动。但是在以 KL 散度为度量的分布空间中。

费希尔信息矩阵和自然梯度

我将跳到最后,告诉你有一个神奇的矩阵,称为费歇尔信息矩阵,如果我们将它包括在常规梯度下降公式中,我们将得到自然梯度下降,它具有在每个更新步骤中约束输出分布的属性[1]。

这正是梯度下降方程,有一些变化:

  1. α,即学习速率,用ηₜ代替,以清楚地表明步长可能在每次迭代中变化
  2. 在正常梯度上增加了一项 F(θₜ)₋₁。

当正常梯度与费希尔矩阵的逆成比例时,我们称之为自然梯度。

现在,对于那些能够接受费舍尔矩阵是一个神奇的量,使正常梯度自然的人来说,跳到下一节。对于那些留下来的勇敢的人来说,一点数学知识正在你的路上。

数学(费希尔矩阵)

我假设每个人都知道 KL 散度是什么。我们将从 KL 散度开始,看看它如何转化为费雪矩阵,什么是费雪矩阵。

正如我们在深度学习和信息理论中看到的,KL 散度被定义为:

那是当我们谈论一个离散变量,像一个分类结果。在更一般的意义上,我们需要用积分来代替求和。让我们也切换符号,以适应梯度下降框架,我们正在工作。

不把 P 和 Q 作为两个分布,我们说P(x;θ)p(x;θ + δθ) 是两个分布,其中 x 是我们的输入特征或协变量,θ是损失函数的参数(例如,神经网络中的权重和偏差),δθ是我们在梯度更新步骤中对参数的微小改变。因此,在新的符号下,KL 散度被定义为:

让我们用p(x;来重写方程的第二项;θ) 利用二阶泰勒展开式(即利用特定点的导数进行近似)。泰勒展开在其一般形式下是:

以这种形式重写第二项,我们得到:

让我们把高中微积分中可靠的链式法则拿出来应用到第一学期。Log x 的导数为 1/x,第二项的泰勒展开式为:

把这个代入 KL 散度方程。我们得到:

重新排列我们现有的术语:

第一项是同一分布之间的 KL 散度,它将为零。另一种思考方式是 log 1 = 0,因此第一项变成 0。

第二项也将为零。下面我们来看看。我们用来推断零的关键属性是概率分布 P(x)对 x 的积分是 1(就像概率分布曲线下面积的总和是 1)。

现在,留给我们的是 log p(x;)θₜ。一点数学知识(手摇)让我们明白:

让我们把这个放回 KL 散度方程。

第一项变成零,因为正如我们之前看到的,概率分布 P(x)对 x 的积分是 1。1 的一阶和二阶导数是 0。在第二项中,积分称为费雪矩阵。姑且称之为 F 。所以 KL 散度方程变成了:

直觉(费希尔矩阵)

费希尔矩阵中 x 上的积分可以解释为期望值。而构成费希尔矩阵的是log p(x;)θₜ。和log p(x;)无非是对数似然。我们知道一阶导数给出了斜率,二阶导数(Hessian)给出了曲率。因此,费希尔矩阵可以被视为对数似然函数的曲率。

费希尔矩阵也是得分函数的协方差。在我们的例子中,得分函数是对数似然,它衡量我们预测的好坏。

数学(自然渐变)

我们看了什么是费希尔矩阵,但是我们仍然没有把它和梯度下降联系起来。现在,我们知道 KL 散度是 Fisher 矩阵和两个分布之间参数的 delta 变化的函数。正如我们之前所讨论的,我们的目标是确保在将 KL 散度保持在恒定的【c】内的前提下,使损失最小化。

形式上,可以写成:

让我们采用问题的拉格朗日松弛法,并使用我们信任的一阶泰勒松弛法

为了最小化上面的函数,我们将导数设置为零并求解。上述函数的导数为:

将其设置为零并求解 δθ ,我们得到:

这意味着因子为 1/λ(这是我们接受的拉格朗日松弛的误差容限),我们得到最佳下降方向,考虑到在该点对数似然的曲率。我们可以把这个放松的常数因素带入学习速率,并把它看作是同一个常数的一部分。

最后一点数学技巧是,我们有自然梯度,

渐变与自然渐变

我们已经讲了很多关于渐变和自然渐变的内容。但是理解自然梯度不同于正常梯度的原因对于理解自然梯度下降如何不同于梯度下降是至关重要的。

在这一切的中心,是一个损失函数,衡量预测输出和地面真相之间的差异。我们如何改变这种损失?通过改变改变预测输出从而改变损失的参数。所以,在正态梯度中,我们取损失函数对参数的导数。如果预测的概率分布更接近真实分布,导数将会很小,反之亦然。这表示如果您将每个参数移动一个单位,您的损失将会改变。因此,当我们应用学习率时,我们将梯度更新按固定量缩放到这些参数。

在自然渐变世界中,我们不再限制参数空间中参数的移动。相反,我们在每一步都阻止了输出概率分布的移动。我们如何测量概率分布?对数可能性。费希尔矩阵给出了对数似然的曲率。

正如我们之前看到的,法线梯度不知道损失函数的曲率,因为它是一阶优化方法。但是,当我们将 Fisher 矩阵包括到梯度中时,我们所做的是用对数似然函数的曲率来缩放参数更新。因此,在对数似然随参数快速变化的分布空间中,相对于分布空间中的平坦平面,参数的更新会更少。

除了使用曲率信息调整我们的更新的明显好处之外,自然渐变还允许我们直接控制你的模型在预测空间中的移动。在正常梯度中,你的运动严格地在参数空间中,我们用一个学习率来限制该空间中的运动,希望预测空间中的运动也被限制。但是在自然梯度更新中,我们通过规定模型在 KL 散度项中仅移动固定的距离来直接限制预测空间中的移动。

因此..为什么我现在才听说?

一个显而易见的问题是,很多人会想:如果自然梯度下降真的很棒,而且明显比梯度下降好,为什么它不是神经网络中的事实标准呢?

这是实用主义战胜理论的领域之一。理论上,使用自然渐变的想法是美好的,而且它也像预期的那样工作。但问题是,当参数数量巨大时,计算费希尔矩阵及其逆矩阵成为一个棘手的问题,就像在典型的深度神经网络中一样。此计算存在于 n_parameter 中。

自然梯度没有受到太多关注的另一个原因是,深度学习研究人员和实践者想出了一些聪明的技巧/启发,在二阶导数中近似信息,而不计算它。深度学习优化器已经从 SGD 走了很长一段路,很多进展都是在使用这样的技巧来获得更好的梯度更新。动量RMSProp亚当,都是 SGD 的变体,其使用梯度的移动平均值和/或移动方差来近似二阶导数,并使用该信息来进行梯度更新。

与计算二阶导数或自然梯度相比,这些试探法的计算量要小得多,并且已经使得深度学习能够扩展到当前的水平。

也就是说,自然梯度在一些情况下仍然有用,其中要估计的参数相对较小,或者预期分布相对标准,如高斯分布,或者在强化学习的一些领域。最近,它也被用于一种形式的梯度增强,我们将在本系列的下一部分讨论。

在我们系列的下一部分中,让我们来看看新的产品— NgBoost

其他文章在T3T5【渐变助推器】

参考

  1. 甘利顺一。自然梯度在学习中很有效。神经计算,第 10 卷,第 2 期,第 251–276 页。
  2. 这很自然:过度深入自然梯度优化,https://towards data science . com/its-Only-Natural-An-over-Deep-Dive-into-Natural-Gradient-Optimization-75d 464 b 89 dbb
  3. 拉特里夫,内森,信息几何与自然渐变,https://ipvs . informatik . uni-stuttgart . de/MLR/WP-content/uploads/2015/01/mathematics _ for _ intelligent _ systems _ lecture 12 _ notes _ I . pdf
  4. 自然渐变下降,https://wise odd . github . io/tech blog/2018/03/14/natural-Gradient/
  5. 费舍尔信息矩阵,https://wise odd . github . io/tech blog/2018/03/11/fisher-Information/
  6. 什么是自然渐变,它是如何工作的?,http://kvfrans . com/what-the-natural-gradient-and-where-it-appeared-in-trust-region-policy-optimization/

原载于 2020 年 4 月 1 日【http://deep-and-shallow.com】

自然语言处理:初学者指南第一部分

原文:https://towardsdatascience.com/natural-language-processing-a-beginners-guide-part-i-1a5880cc3bdc?source=collection_archive---------26-----------------------

从零开始用 nltk 库学习 NLP

https://unsplash.com/

表达式包含大量数据。每次我们说话或写作时,它都有一些与特定主题、社区、教义等相关的解释。,可以在更大范围内影响人。作为一个人,分析这些数据非常困难,但由于机器学习和人工智能,这变得很容易!

在网民时代,信息在各种社交媒体平台、不同语言的电子报纸中流通。通过自然语言处理,收集这些非结构化数据并分析其不同的解释现在已经成为可能。

自然语言处理是人工智能领域,处理机器和人类语言之间的交互。换句话说,NLP 帮助机器理解人类(自然)语言的含义。

用例

智能助手如谷歌助手、SIRI、亚马逊 Alexa 等。基于 NLP 概念的工作。这些助手将你的演讲转换成文本,进行分析,然后付诸行动。

情绪分析:在社交媒体平台中,人们对你可以使用 NLP 分析的推文或帖子的情绪。组织通过使用 NLP 的反馈处理来分析客户对产品的情感,并在业务中获得收益。

主题建模:你可以使用 LDA(潜在狄利克雷分配 ) 技术深入主题建模的世界。我将在这个博客的第二部分对此进行更多的讨论。

垃圾邮件检测:公司使用 NLP 对流经其服务器的垃圾邮件进行分类。

假新闻检测:一些机构使用自然语言处理来检测社交媒体、电子媒体中的假新闻。

NLP 还有许多其他的用例。在这篇博客中,你将作为初学者理解使用 NLP 对一篇报纸文章的文本分析。为此,您可以直接转到链接并复制文章进行处理,也可以使用 Python 进行抓取。网络抓取真的很有趣,我会在另一个博客中讨论它。

让我们用 NLP 做一些伟大的事情!

https://unsplash.com/

基本安装:

对于这个博客来说, nltk 开源库和 spyder IDE 将会得心应手。这个库描述了 NLP 的许多功能。首先,您需要导入 nltk 库,然后从 GitHub 库下载一些必需品。

#import library nltk
import nltk
nltk.download()

一旦您在 spyder IDE 中运行这些东西,就会出现如下弹出窗口。你需要全部下载。

从我的电脑输出

记号化:它是文本处理部分,帮助你将一个大的字符串分割成几个记号。换句话说,这种技术可以帮助你将段落分成一系列的句子,将一个句子分成一系列的单词。

paragraph =’’’
Ahead of U.S. President Donald Trump’s visit to India, some of the key deliverables from the trip, as well as the outcomes that may not be delivered after his meeting with Prime Minister Narendra Modi on Tuesday, are coming into view. The larger question remains as to whether the bonhomie between the two, who will be meeting for the fifth time in eight months, will also spur the bilateral relationship towards broader outcomes, with expectations centred at bilateral strategic ties, trade and energy relations as well as cooperation on India’s regional environment. On the strategic front, India and the U.S. are expected to take forward military cooperation and defence purchases totalling about $3 billion. Mr. Trump has cast a cloud over the possibility of a trade deal being announced, but is expected to bring U.S. Trade Representative Robert Lighthizer to give a last push towards the trade package being discussed for nearly two years. Both sides have lowered expectations of any major deal coming through, given that differences remain over a range of tariffs from both sides; market access for U.S. products; and India’s demand that the U.S. restore its GSP (Generalised System of Preferences) status. However, it would be a setback if some sort of announcement on trade is not made. A failure to do so would denote the second missed opportunity since Commerce Minister Piyush Goyal’s U.S. visit last September. Finally, much of the attention will be taken by India’s regional fault-lines: the Indo-Pacific strategy to the east and Afghanistan’s future to the west. India and the U.S. are expected to upgrade their 2015 joint vision statement on the Indo-Pacific to increase their cooperation on freedom of navigation, particularly with a view to containing China. Meanwhile, the U.S.-Taliban deal is expected to be finalised next week, and the two leaders will discuss India’s role in Afghanistan, given Pakistan’s influence over any future dispensation that includes the Taliban.Any high-level visit, particularly that of a U.S. President to India, is as much about the optics as it is about the outcomes. It is clear that both sides see the joint public rally at Ahmedabad’s Motera Stadium as the centrepiece of the visit, where the leaders hope to attract about 1.25 lakh people in the audience. Despite the Foreign Ministry’s statement to the contrary, the narrative will be political. Mr. Trump will pitch the Motera event as part of his election campaign back home. By choosing Gujarat as the venue, Mr. Modi too is scoring some political points with his home State. As they stand together, the two leaders, who have both been criticised in the last few months for not following democratic norms domestically, will hope to answer their critics with the message that they represent the world’s oldest democracy and the world’s largest one, respectively.
‘’’
#tokenizing sentences
sentences = nltk.sent_tokenize(paragraph)#tokenizing words
words = nltk.word_tokenize(paragraph)

这里的段落包含一篇特定的报纸文章。使用 sent_tokenize()和 word_tokenize()可以创建令牌列表。

词干化:将派生单词还原为其词干或词根形式的过程。

Negligence    |
Negligently   | ============> Negligen 
Neglligent    |

在这里,疏忽、疏忽、过失这些词将被简化为疏忽。但是它有一个缺点——词干可能没有意义。

from nltk.stem.porter import PorterStemmer
from nltk.corpus import stopwords

您需要创建一个 PorterStemmer 对象,并遍历句子标记来执行词干提取。

词汇化:是一种类似词干化的活动。但在这种情况下,基本词会有一些意义。

from nltk.stem import WordNetLemmatizer

注意:

  1. 每次执行词汇化或词干化时,都需要将标记转换成小写,并删除停用词。
from nltk.corpus import stopwords

2.如果需要更多的文本清理活动,您可以使用 Python re 模块

https://www.thehindu.com/opinion/editorial/

在目前的讨论中,文章多次包含美国。因为它与文章更相关,所以你需要转换美国。使用 replace()方法对' America '进行替换。执行上述功能后,输出如下。

从我的电脑输出

在此图中,显然'可交付物''已被简化为'交付物'。它没有任何意义。所以我进行了词汇化。这是输出。看看第一行中的单词'可交付物'。

从我的电脑输出

停用词: nltk 支持各种语言,每种语言都有不同的停用词。对于英语来说,停用词就像“a”、“the”、“where”等。

从我的电脑输出

恭喜你!!!

你已经成功的将句子记号词条化了!

包话:

它是一个帮助你理解单词在文档或句子中出现的模式,而不管语法和单词的顺序。

您可以创建一个对象 CountVectorizer 来执行这个操作。

from sklearn.feature_extraction.text import CountVectorizer

从我的电脑输出

到目前为止,我们可以从讨论中得出两个推论。

  1. 在词汇化和词干化中,所有的单词都具有同样的重要性。
  2. 在我们收集的单词中没有语义信息。

为了克服这些问题,采用了另一种方法— TFIDF

词频和逆文档频:

你是否有一些信息,以生僻字的形式出现,但在文本分析中却非常重要?

别担心,TFIDF 会帮你解决的!

版权所有-Somesh

版权所有-Somesh

TFIDF = TF * IDF

再次感谢 Sci-Kit Learn library 减少了您的一些努力。创建 TfidfVectorizer 的 sn 对象来应用这个概念。

from sklearn.feature_extraction.text import TfidfVectorizer

看一下结果

这些不同的小数输出显示了单词相对于文档/句子的实际重要性。同样,这种方法既没有语义也没有上下文。但这是一种奖励词语的方法,却忽略了词语的频繁出现。

此外,我们可以利用主题模型,分析具有相同上下文的其他来源的文章,以了解作者的情绪。

但是这些内容将在第 2 部分中讨论!!!

自然语言处理是人工智能的一个广阔和蓬勃发展的领域,尽管在这方面工作非常具有挑战性。从智能助手到疾病检测,自然语言处理在很多领域都非常有用。

祝贺并欢迎所有从事自然语言处理的人!!!

感谢克里斯·纳伊克,是他让这一旅程成为可能。

对于建议,我将在 LinkedInGmail 上,并在 GitHub 关注我的工作。

自然语言处理:初学者指南第二部分

原文:https://towardsdatascience.com/natural-language-processing-a-beginners-guide-part-ii-54a1bf8c0497?source=collection_archive---------40-----------------------

让我们再深入一点…

我已经在 NLP 系列的第一部分讨论了 NLP 的基础知识。您会注意到,TF-IDF 的概念没有传达任何语义或上下文。但是你可以从语法的角度来解释这些文章。

让我们一起来探索语料库的隐藏之美吧!

来源

位置标签

这指的是句子中的词类的概念,你们在高中已经学过了。使用 nltk 库,你可以给每个单词甚至短语添加词性标签。这是一个复杂的过程,有时单词在句子的形式上有模糊的意思。语料库有两种词性标注。

1.基于规则的位置标记:

当你遇到模棱两可的词时,你可以使用这个技巧。分析前人和后人。它也是特定于特定语言的。大写和标点词性标注是这种技术的一部分。

其中一个例子是布里尔的标签。它是一个基于规则的标记器,在训练数据中实现,找出词性标记错误较少的规则集,对数据进行最佳定义。

2.随机位置标记:

如果一个单词在训练句子中被标记了特定的标签,分析最高频率或概率,该单词将被赋予一个特殊的标签。

这也被称为 n 元语法方法,指的是基于具有 n 个先前标签的概率来决定单词的事实。

import nltkparagraph =’’’
Ahead of U.S. President Donald Trump’s visit to India, some of the key deliverables from the trip, as well as the outcomes that may not be delivered after his meeting with Prime Minister Narendra Modi on Tuesday, are coming into view. The larger question remains as to whether the bonhomie between the two, who will be meeting for the fifth time in eight months, will also spur the bilateral relationship towards broader outcomes, with expectations centred at bilateral strategic ties, trade and energy relations as well as cooperation on India’s regional environment. On the strategic front, India and the U.S. are expected to take forward military cooperation and defence purchases totalling about $3 billion. Mr. Trump has cast a cloud over the possibility of a trade deal being announced, but is expected to bring U.S. Trade Representative Robert Lighthizer to give a last push towards the trade package being discussed for nearly two years. Both sides have lowered expectations of any major deal coming through, given that differences remain over a range of tariffs from both sides; market access for U.S. products; and India’s demand that the U.S. restore its GSP (Generalised System of Preferences) status. However, it would be a setback if some sort of announcement on trade is not made. A failure to do so would denote the second missed opportunity since Commerce Minister Piyush Goyal’s U.S. visit last September. Finally, much of the attention will be taken by India’s regional fault-lines: the Indo-Pacific strategy to the east and Afghanistan’s future to the west. India and the U.S. are expected to upgrade their 2015 joint vision statement on the Indo-Pacific to increase their cooperation on freedom of navigation, particularly with a view to containing China. Meanwhile, the U.S.-Taliban deal is expected to be finalised next week, and the two leaders will discuss India’s role in Afghanistan, given Pakistan’s influence over any future dispensation that includes the Taliban.Any high-level visit, particularly that of a U.S. President to India, is as much about the optics as it is about the outcomes. It is clear that both sides see the joint public rally at Ahmedabad’s Motera Stadium as the centrepiece of the visit, where the leaders hope to attract about 1.25 lakh people in the audience. Despite the Foreign Ministry’s statement to the contrary, the narrative will be political. Mr. Trump will pitch the Motera event as part of his election campaign back home. By choosing Gujarat as the venue, Mr. Modi too is scoring some political points with his home State. As they stand together, the two leaders, who have both been criticised in the last few months for not following democratic norms domestically, will hope to answer their critics with the message that they represent the world’s oldest democracy and the world’s largest one, respectively.
‘’’#tokenizing sentences
sentences = nltk.sent_tokenize(paragraph)#tokenizing words
words = nltk.word_tokenize(paragraph)#pos tagging
for word in words:
 print(nltk.pos_tag(words))

运行上面这段代码,你可以看到单词和相应的 pos 标签压缩在一个列表中。

仅代表目的。版权所有 Somesh

这里的缩写像 NNP——专有名词,单数。

IN 表示介词等。您也可以探索 nltk 库中关于缩写的更多信息。

还可以进行组块操作,得到一组单词。组块用来给句子增加更多的结构。您还可以添加正则表达式技术来形成不同种类的标记组或名词短语组等。它也被称为浅层解析或轻量解析。

pattern = ‘’’chunk_sample:{<NNP.?>*<IN.?>}’’’
chunky = nltk.RegexpParser(pattern)
print(chunky)chunk_op = chunky.parse(nltk.pos_tag(words))
print(chunk_op)

这里的模式告诉我们如何从单词标记中创建组块。

关于模式创建的一些有用信息:

Special Symbols       Meaning
.                    Any character except newline*                    Match 0 or more repetitions?                    Match 0 or 1 repetitionspattern = '''chunk_sample:{<NN.?>*<VBD.?>*<JJ.?>}'''
chunky = nltk.RegexpParser(pattern)
print(chunky)#corpus_lem[5]=['however','would','setback','sort','announcement','trade made']chunk_op = chunky.parse(nltk.pos_tag(corpus_lem[5].split(' ')))
print(chunk_op)chunk_op.draw()

如果您运行上面这段代码,您可以更好地理解分块技术,并将其可视化。

版权所有 Somesh

版权所有 Somesh

这里的图表描述了每个带有词性标签的单词。您可以更多地使用 RegexpParser 来从语法上理解标记,并可以制作漂亮的图形来更好地可视化。

#Ngram in nltk 
from nltk import ngramsbigram = list(ngrams(corpus_lem[8].split(),2))
trigram = list(ngrams(corpus_lem[8].split(),3))

BIGRAM 输出版权 somesh

三元模型输出版权所有 Somesh

您可以清楚地看到二元模型方法形成了两个单词的元组,三元模型方法形成了三个单词的元组。

隐马尔可夫模型:

这些是概率模型,基于先前识别的单词和当前单词,帮助决定最可能的决定。

HMM 是具有单个状态变量 S 和单个观察变量 O,的概率模型,因此该模型将具有两个概率部分。诸如

(I)过渡模型——它告诉我们一个国家在一段时间内的过渡。

(ii)观察模型——它告诉我们在给定的状态下,您获得不同观察结果的可能性有多大。(参考下图)

版权所有 Somesh

下面是 HMM 概念的图形表示,称为结构化转换模型。这些数值对应的是在给定时间状态到当前状态的每一次转移的概率。每个节点都是一个特定的指定状态变量。

在这里,S1 以 0.7 的概率转移到 S2,并以 0.2 的概率停留在原来的状态。其他州也有类似的解释。

版权所有 Somesh

这是关于 HMM 的概念。它被广泛用于 NLP 项目中,如机器人定位、语音识别、生物序列分析、文本分析等。我将在接下来的故事中讨论详细的模型和编码部分。

到目前为止,我们只分析了使用 nltk 库的单词。在这里,我将尝试使用 wordcloud 赋予文字艺术感。很迷人,不是吗?

如下导入所需的库。将每个句子的词条转化成一个字符串,使用 wordcloud 你可以表达它。

#to intsall wordcloud in anaconda type "pip install wordcloud" in #anaconda prompt#import librariesimport pandas as pd
from wordcloud import WordCloud#convert the corpus_lem to a dataframe
df = pd.DataFrame(data=corpus_lem,columns=[‘words’])stop_words = set(stopwords.words(‘english’))
words_test = ‘’#convert all the lematized sentence token to a string
for i in df.words:
 words_test = words_test+i+’ ‘

#put it in a wordcloud
word_cloud = WordCloud(width = 900, height = 900,stopwords = stop_words,
 background_color = ‘white’,min_font_size = 12).generate(words_test)#show using matplotlib
import matplotlib.pyplot as pltplt.figure(figsize = (10, 10), facecolor = None) 
plt.imshow(word_cloud) 
plt.axis(“off”) 
plt.tight_layout(pad = 0) 

plt.show()

版权所有 Somesh

在这里,你可以发现作者试图将重点放在像 美国、印度、贸易、合作、莫迪、特朗普等词上。

稍后我将解释 HMM,Word2Vec 概念,以便更深入地理解 NLP &请务必阅读本系列的第 1 部分,以便更好地理解这个故事。

直到那时享受自然语言处理!!!

我希望你喜欢自然语言处理第一部分。在 媒体 上关注我,或者订阅我的博客来了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @RoutraySomesh 联系。

自然语言处理:简单解释

原文:https://towardsdatascience.com/natural-language-processing-a-simple-explanation-7e6379085a50?source=collection_archive---------46-----------------------

自然语言处理(NLP)正在迅速发展,并在许多方面改善着我们的生活——下面是一个简单的介绍。

照片由西德·瓦克斯Unsplash 上拍摄

什么是自然语言处理?

自然语言处理,简称 NLP,是专门分析人类语言人工智能(AI) 的一种。

[## 什么是人工智能?-高要求技能

人工智能(AI)是一个你可能听说过的术语——它对社会产生了巨大的影响,并且…

highdemandskills.com](https://highdemandskills.com/what-is-artificial-intelligence/)

NLP 通过以下方式做到这一点:

  • 阅读自然语言,这种语言是通过人类的自然使用进化而来的,我们每天都用它来相互交流
  • 解释自然语言,通常通过基于概率的算法
  • 分析自然语言并提供输出

你有没有用过苹果的 Siri,想知道它是如何理解(大部分)你说的话的?这是 NLP 在实践中的一个例子。

NLP 正在成为我们生活中必不可少的一部分,与机器学习和深度学习一起,产生的结果远远优于几年前可能实现的结果。

在本文中,我们将仔细研究 NLP,看看它是如何应用的,并了解它是如何工作的。

自然语言处理能做什么?

如今,NLP 的使用方式多种多样。其中包括:

机器翻译

你上一次访问外国并用智能手机进行语言翻译是什么时候?或许你用过谷歌翻译?这是 NLP 机器翻译的一个例子。

机器翻译通过使用 NLP 将一种语言翻译成另一种语言来工作。历史上,简单的基于规则的方法已经被用来做这件事。但是今天的 NLP 技术是对已经存在多年的基于规则的方法的一个很大的改进。

为了让 NLP 在机器翻译方面表现出色,它采用了深度学习技术。这种形式的机器翻译有时被称为神经机器翻译(NMT),因为它利用了神经网络。因此,NMT 解释语言的基础上,统计,尝试和错误的方法,可以处理语境和其他微妙的语言。

除了像 Google Translate 这样的应用程序,NMT 还用于一系列商业应用程序,例如:

  • 翻译纯文本、网页或文件,如 Excel、Powerpoint 或 Word。Systran 是这样做的翻译服务公司的一个例子。
  • 实时翻译社交内容,由专门从事公共部门语言服务的 SDL 政府提供。
  • 在医疗情况下翻译语言,例如当一名讲英语的医生正在治疗一名讲西班牙语的病人时,由 Canopy Speak 提供。
  • 翻译财务文件,如年度报告、投资评论和信息文件,由专门从事财务翻译的公司提供。

语音识别

前面我们提到 Siri 是 NLP 的一个例子。Siri 使用的 NLP 的一个特殊功能是语音识别。Alexa 和 Google Assistant(“ok Google”)是 NLP 语音识别的其他众所周知的例子。

语音识别并不是一门新科学,它已经存在了 50 多年。多亏了 NLP,直到最近它的易用性和准确性才有了显著的提高。

语音识别的核心是识别口语单词、解释它们并将其转换为文本的能力。然后可以采取一系列行动,如回答问题、执行指令或写电子邮件。

NLP 中使用的强大的深度学习方法使今天的语音识别应用程序比以往任何时候都更好地工作。

聊天机器人

聊天机器人是模拟人类自然对话的软件程序。它们被公司用来帮助客户服务、消费者查询和销售查询。

上次登录公司网站并使用在线帮助系统时,您可能已经与聊天机器人进行了互动。

虽然简单的聊天机器人使用基于规则的方法,但今天更有能力的聊天机器人使用 NLP 来理解客户在说什么以及如何回应。

聊天机器人的众所周知的例子包括:

  • 世界卫生组织(世卫组织)聊天机器人,建立在 WhatsApp 平台上,分享信息并回答关于新冠肺炎病毒传播的询问
  • 《国家地理》的天才聊天机器人,说话像阿尔伯特·爱因斯坦,与用户互动以推广同名的《国家地理》节目
  • Kian 是韩国汽车制造商起亚在 FaceBook Messenger 上的聊天机器人,它回答关于起亚汽车的查询,并帮助销售查询
  • 全食超市的聊天机器人,帮助提供食谱信息、烹饪灵感和产品推荐

情感分析

情感分析使用 NLP 来解释和分类文本数据中包含的情感。例如,这用于根据正面或负面体验对在线客户关于产品或服务的反馈进行分类。

在最简单的形式中,情感分析可以通过根据传达情感的指定单词对文本进行分类来完成,如“爱”、“恨”、“快乐”、“悲伤”或“愤怒”。这种类型的情感分析已经存在了很长时间,但是由于其简单性,实际应用有限。

今天的情感分析使用 NLP 基于统计和深度学习方法对文本进行分类。结果是情感分析可以处理复杂和自然的声音文本。

如今,全世界的企业都对情感分析产生了浓厚的兴趣。它可以提供对客户偏好、满意度和意见反馈的宝贵见解,有助于营销活动和产品设计。

电子邮件分类

电子邮件超载是现代工作场所常见的挑战。NLP 可以帮助分析和分类收到的电子邮件,以便它们可以自动转发到正确的位置。

过去,简单的关键字匹配技术被用来对电子邮件进行分类。这有好有坏。NLP 允许更好的分类方法,因为它可以理解单个句子、段落和整个文本部分的上下文。

鉴于当今企业必须处理的电子邮件数量庞大,基于 NLP 的电子邮件分类可以极大地帮助提高工作场所的生产力。使用 NLP 进行分类有助于确保电子邮件不会被遗忘在负担过重的收件箱中,并被正确归档以供进一步处理。

自然语言处理是如何工作的?

既然我们已经看到了 NLP 能做什么,让我们试着理解它是如何工作的。

本质上,NLP 的工作原理是将一组文本信息转换成指定的输出。

如果应用程序是机器翻译,那么输入的文本信息将是源语言(比如说英语)的文档,输出将是目标语言(比如说法语)的翻译文档。

如果应用是情感分析,那么输出将是输入文本到情感类别的分类。诸如此类。

NLP 工作流

现代 NLP 是一门混合学科,它借鉴了语言学、计算机科学和机器学习。NLP 使用的流程或工作流有三个主要步骤:

步骤 1 —文本预处理

步骤 2 —文本表示

步骤 3 —分析和建模

每一步都可能使用一系列技术,这些技术随着不断的研究而不断发展。

步骤 1:文本预处理

第一步是准备输入文本,以便更容易分析。自然语言处理的这一部分已经很好地建立起来,并且利用了一系列传统的语言学方法。

此步骤中使用的一些关键方法有:

  • 记号化,将文本分解成有用的单元(记号)。例如,用空格分隔单词,或者用句号分隔句子。标记化也识别经常在一起的单词,例如“纽约”或“机器学习”。例如,句子“客户服务好得不能再好了”的标记化将导致以下标记:“客户服务”、“可能”、“不是”、“是”和“更好”。
  • 规范化使用像词干词汇化这样的技术将单词转换成它们的基本形式。这样做是为了帮助减少“噪音”和简化分析。词干提取通过删除词尾来识别词干。例如,单词“studies”的词干是“studi”。词汇化同样会删除后缀,但如果需要的话也会删除前缀,从而产生自然语言中通常使用的单词。例如,单词“studies”的引理是“study”。在大多数应用中,词汇化比词干化更受欢迎,因为生成的单词在自然语言中有更多的含义。
  • 词性标注利用了形态学,即研究单词之间的相互关系。单词(或记号)基于它们在句子中的功能被标记。这是通过使用从文本语料库中建立的规则来识别语音中单词的目的,即。动词、名词、形容词等。
  • 解析利用句法,或者对单词和句子如何组合的理解。这有助于理解句子的结构,是通过根据语法规则将句子分解成短语来完成的。一个短语可能包含一个名词和一个冠词,如“我的兔子”,或者一个动词,如“喜欢吃胡萝卜”。
  • 语义确定句子中所用单词的预期含义。单词可以有一个以上的意思。例如,“通过”可以表示(I)实际交出某物,(ii)决定不参加某事,或(iii)衡量考试成功。通过查看单词前后出现的单词,可以更好地理解单词的意思。

步骤 2:文本表示

为了使用机器和深度学习方法分析文本,需要将其转换为数字。这就是文本表示的目的。

此步骤中使用的一些关键方法有:

一袋单词

单词包(Bag of words,简称 BoW)是一种表示文本的方法,它通过计算每个单词在输入文档中出现的次数,与已知的参考单词列表(词汇表)进行比较。

结果是一组向量,包含描述每个单词出现次数的数字。这些向量被称为“包”,因为它们不包含任何关于输入文档结构的信息。

为了说明 BoW 是如何工作的,考虑例句“猫坐在垫子上”。这包含单词“the”、“cat”、“sat”、“on”和“mat”。这些单词的出现频率可以用[2,1,1,1,1]形式的向量来表示。这里,单词“the”出现两次,其他单词出现一次。

当与大词汇量相比较时,向量将扩展到包括几个零。这是因为词汇表中所有不包含在例句中的单词都没有出现频率。得到的矢量可能包含大量的零,因此被称为“稀疏矢量”。

BoW 方法相当简单易懂。然而,当词汇表很大时,得到的稀疏向量可能非常大。这导致计算上具有挑战性的向量不包含太多信息(即大多为零)。

此外,BoW 会查看单个单词,因此不会捕获任何关于单词组合的信息。这导致后面分析的上下文丢失。

一袋 n-克

使用 BoW 减少上下文丢失的一种方法是创建成组单词的词汇表,而不是单个单词。这些分组的单词被称为“n 元语法”,其中“n”是分组大小。由此产生的方法被称为“n-grams 袋”(BNG)。

BNG 的优势在于,每个 n-gram 比单个单词捕捉到更多的上下文。

在前面的例句中,“sat on”和“the mat”是 2-gram 的例子,“on the mat”是 3-gram 的例子。

TF-IDF

计算一个单词在文档中出现的次数的一个问题是,某些单词开始在计算中占主导地位。像“the”、“a”或“it”这样的词。这些词经常出现,但不包含太多信息。

处理这种情况的一种方法是将文档中频繁出现的单词与唯一出现的单词区别对待。频繁出现的单词往往是像“The”这样的低值单词。这些单词的计数可以被扣分以帮助降低它们的优势。

这种方法被称为“术语频率—逆文档频率”或 TF-IDF。术语频率查看一个词在给定文档中的频率,而逆文档频率查看该词在所有文档中的稀有程度。

TF-IDF 方法的作用是淡化频繁出现的单词,并突出具有有用信息的更独特的单词,如“cat”或“mat”。这可以带来更好的结果。

单词嵌入

一种更复杂的文本表示方法包括单词嵌入。这将每个单词映射到单独的向量,其中向量倾向于“密集”而不是“稀疏”(即。更小并且具有更少的零)。在映射过程中会考虑每个单词及其周围的单词。由此产生的密集向量允许更好地分析和比较单词及其上下文。

单词嵌入方法使用强大的机器学习和深度学习来执行映射。这是一个不断发展的领域,已经产生了一些出色的成果。目前使用的关键算法包括 Word2Vec、GloVe 和 FastText。

步骤 3:分析和建模

NLP 过程的最后一步是对通过步骤 1 和 2 生成的向量进行计算,以产生所需的结果。这里使用了机器学习和深度学习的方法。来自非 NLP 领域的许多相同的机器学习技术,如图像识别或欺诈检测,可用于此分析。

考虑情绪分析。这可以使用监督或无监督的机器学习来完成。有监督的机器学习需要预先标记的数据,而无监督的机器学习使用预先准备的精选单词(词典)数据库来帮助对情感进行分类。

使用机器学习,使用概率方法对输入文本向量进行分类。这是通过训练模型(监督机器学习)或通过与合适的词典进行比较(非监督机器学习)来完成的。

结果是基于通过机器学习过程生成的概率的情感分类。

结论

NLP 发展迅速,对社会的影响越来越大。从语言翻译到语音识别,从聊天机器人到识别情感,NLP 正在提供有价值的见解,并使我们的生活更加富有成效。

现代 NLP 通过使用语言学、计算机科学和机器学习来工作。近年来,NLP 已经产生了远远超过我们过去所看到的结果。

自然语言处理的基本工作流程包括文本预处理、文本表示和分析。如今使用了多种技术,并且随着研究的进行,更多的技术正在开发中。

NLP 承诺将彻底改变工业和消费者实践的许多领域。它已经成为我们日常生活中熟悉的一部分。

有了 NLP,我们有了一种强大的方式,通过一种我们天生熟悉的媒介——我们通过自然语言交流的能力——来参与数字未来。

[## 博客-高要求技能

阅读那些需求量很大的技能,这些技能可以让你更有生产力和效率,并且可以帮助你实现你的…

highdemandskills.com](https://highdemandskills.com/blog/)

自然语言处理

原文:https://towardsdatascience.com/natural-language-processing-a1496244c15c?source=collection_archive---------12-----------------------

使用 NLTK 的介绍和预处理

科伦萨·皮克特在 Unsplash 上拍摄的照片

什么是自然语言处理?

自然语言处理(NLP)是用于帮助机器理解和学习文本和语言的技术。通过 NLP 数据,科学家们旨在教机器理解所说的和所写的,以理解人类语言。用于将机器学习算法应用于文本语音

在本文中,我们将通过机器学习来了解 NLP 工作是如何理解人类语言的。

对我们重要吗?

我们可以使用 NLP 来创建类似于语音识别机器翻译垃圾邮件检测、文本简化问题回答、自动完成、预测打字、情感分析、文档摘要等等的系统。几个例子包括:

谷歌翻译 —语言翻译应用

语法上 —使用自然语言处理检查文本的语法准确性

个人协助——OK 谷歌、Siri、Cortana、Alexa 等应用。

关键词搜索,拼写检查,同义词搜索。

查询如产品价格、位置、公司名称等。在搜索引擎上。

这是一项容易的任务吗?

NLP,情感和歧义:教计算机关于语言的确切意义和情感被认为是计算机科学中的一个难题。

腾雅特Unsplash 上拍照

完全理解和表达语言的意义是一个极其困难的目标。开发 NLP 应用程序的主要挑战之一是,计算机很可能需要结构化数据,但就人类语音而言,这些数据是非结构化的,而且常常是模糊的。

使用自然语言指导信息的规则对于计算机来说不容易理解和翻译,尤其是感知语气,例如,如果某人使用讽刺的话来传递信息。这意味着计算机必须全面理解单词的含义以及单词背后的意图或情感。与编程不同,人类语言是模糊的,这使得它们复杂而难学。

NLP 中用到的技术有哪些?

自然语言处理主要有两个方面:自然语言理解 (NLU)或自然语言解释(NLI)(即人对机器)和自然语言生成 (NLG)(即机器对人)。简而言之,人们可以说 NLG 是 NLU 的逆(广义上称为 NLP)。自然语言生成(NLG)是指软件自动将数据转换成书面叙述。

句法和语义分析

自然语言处理任务主要通过句法分析和语义分析来实现。

术语 句法 指的是文本的语法结构,而 语义 指的是句子的意思。句法正确的句子并不意味着语义总是正确的。

句法分析(句法分析或解析),使用形式语法分析自然语言。语法规则适用于类别和词组,但不适用于单个单词。

示例:

  • 解析 —包括对提供的句子进行语法分析。
  • 词汇化 —将一个单词的各种屈折形式简化为单一形式。
  • 词干 —将屈折变化的单词切割成它们的词根形式。
  • 分词 —将一大段连续文本分成不同的单元。
  • 形态切分 —将词分成单个单位。
  • 词性标注 —识别每个单词的词性。
  • 断句 —在一大段文本上放置句子边界

语义分析是对句子的词语、符号、语气、结构进行理解和解释的过程。这项任务分析句子背后的意思或逻辑。我们主要依靠我们的直觉、关于语言和语调的知识来理解某人所说的话。

示例:

  • 命名实体识别(NER) —确定文本中可以被识别并归类到预设组中的部分,如人名和物体名。
  • 词义消歧——根据上下文赋予单词意义
  • 自然语言生成(NLG):——它涉及使用数据库来推导语义意图,并将它们转换成人类语言。

近年来,文本、视频、音频和照片形式的非结构化数据激增。NLU 有助于从文本中提取有价值的信息,如社交媒体数据、客户调查和投诉。

读取文本数据&为什么我们需要清理文本?

文本数据可以是结构化或非结构化的格式。

结构化的格式具有明确定义的模式,而非结构化的数据没有合适的结构。在这两种结构之间,我们有一种半结构化格式,它的结构化程度比非结构化格式要好。

在 python 中,我们有几个库来处理文本。

  • Scikit-learn,Keras,TensorFlow —具有一些文本处理功能
  • NLTK —自然语言工具包。
  • SpaCy —是一个工业级的 NLP 包,在一个漂亮的 API 中有许多实用的工具。
  • 其他库 — TextBlob,gensim,Stanford CoreNLP,OpenNLP。

在本文中,我们将介绍使用最常用的 python 库(即 NLTK)预处理文本数据的各种方法和技术。

自然语言工具包(NLTK)

(用于文本处理的 Python 库)

自然语言工具包(NLTK)是一个已知的 Python 开源包,它允许我们运行所有常见的 NLP 任务。它提供了易于使用的接口和一套文本处理库在预处理过程中涉及的大量步骤,如分类、标记化、词干化、标记、解析和语义推理。

需要对文本数据进行预处理

  • 真实数据——往往不完整、不一致,并且充斥着大量的噪音和错误
  • 数据结构 —大约。90%的数据是非结构化的
  • 多样性 —文本可以来自单个单词、句子、多个段落的列表(有或没有正确的拼写和标点)
  • 噪音——这些数据从来都不干净,包含大量噪音。

在建模和分析之前,有必要对数据进行预处理。简而言之,预处理将原始文本数据转换成计算机可理解的格式。

文本预处理

让我们创建一个数据框(df)** 来练习文本数据的预处理。**

  • 将文本转换成小写的,使所有的数据格式一致

  • 标点— 标点不添加任何额外信息。这一步骤减少了数据的大小,因此提高了计算效率

  • 数字— 将数字转换成文字或删除数字。删除不相关的数字或改为文字。

  • ****不重要的词“停用词”——是非常常见的词,与其他关键词相比没有意义或意义较小。如果我们去掉不常用的词,我们可以把注意力放在重要的关键词上。

  • 标记文本— 文本预处理中的一个强制步骤,其中文本被分割成最小有意义单元。可以是单词(word_tokenize)也可以是句子(sent_tokenize)。

  • 词干化 词干化是通过去掉单词的后缀来提取词根的过程。在这篇文章中,我们将集中在 3 个词干技巧:波特斯特梅尔,斯诺鲍斯特梅尔和兰卡斯特斯特梅尔**

  • 词汇化— 词汇化是通过考虑词汇来提取词根的过程。词汇化是一种更强大的操作,它考虑了单词的形态分析。

"词干化是一般操作,而词汇化是智能操作,其中将在字典中搜索适当的形式;因此,你以后会有更好的机器学习功能。”

摘要

在本文中,我们讨论了自然语言处理的基本概念和应用,以及使用 python 库 NLTK 的预处理步骤。一旦预处理完成,人们就可以将数据用于更复杂的 NLP 任务。

享受 NLP,感谢阅读😄。

自然语言处理—从初级到高级(第三部分)

原文:https://towardsdatascience.com/natural-language-processing-beginner-to-advanced-part-3-bbd536a89ecb?source=collection_archive---------27-----------------------

NLP 项目

高级词汇处理——如何处理文本数据中的杂波,以及如何构建自己的拼写校正器。

图片由洛伦佐·卡法罗皮克斯拜拍摄

在“NLP 项目”系列的前一部分中,我们学习了所有基本的词汇处理技术,比如去除停用词、标记化、词干化和词条化。

即使经过了所有这些预处理步骤,文本数据中仍然存在大量噪声。例如,由于错误和选择而发生的拼写错误(非正式的词,如' lol ',' u ',' gud '等。).此外,由于发音不同(例如 Mumbai,Bombay)而出现的单词拼写变化问题。

我们在上一部分中谈到的两种方法——词干化和词汇化——都是称为规范化的技术的一部分。基本上,规范化意味着将一个单词简化为它的基本形式。

有些情况下,我们不能仅仅通过词干化和词汇化来规范化一个单词。因此,我们需要另一种技术来正确地规范化单词。例如,如果单词“allowing”被拼错为“alowing ”,那么在阻止拼错的单词后,我们将有一个多余的标记“alow ”,并且词条化甚至不起作用,因为它只对正确的词典拼写起作用。

同样的问题也存在于不同方言中相同单词的发音上。例如,英式英语中使用的单词“幽默”在美式英语中被拼写为“幽默”。这两种拼写都是正确的,但是在词干之后,当用于形式“幽默”和“幽默”时,它们会给出两种不同的基本形式。

语音散列法

有些词在不同的语言中有不同的发音。因此,它们最终的写法是不同的。例如,一个常见的印度姓氏如“Srivastava”也被拼写为“Shrivastava”、“Shrivastav”或“Srivastav”。因此,我们必须把一个特定单词的所有形式简化为一个单一的普通单词。

为了达到这个目的,我们将了解一种叫做语音哈希的技术。语音散列法将相同的音素(声音的最小单位)组合到一个桶中,并为所有变体赋予相同的散列码。所以,单词“color”和“colour”有相同的代码。

语音哈希是一种用于将具有不同变体但语音特征相同(即发音相同)的单词进行规范化的技术。

现在, Soundexes 是可以用来计算给定单词的哈希码的算法。语音哈希使用这些 Soundex 算法。算法因语言而异。美国的 Soundex 是最流行的 Soundex 算法,我们将使用它。此外,输入的单词来自哪种语言并不重要——只要单词听起来相似,它们就会获得相同的哈希代码。

拼音哈希是一个四字码。因此,让我们通过应用以下步骤来计算单词“Chennai”的散列码(也称为 Soundex)

  1. 保留单词的首字母——Soundex 的基本原理是,英语发音取决于辅音的首字母和模式。所以,C 变成了第一个字母。
  2. 去掉所有的元音。所以我们现在有了“CHNN”。
  3. 用数字替换辅音,如下所示(第一个字母后)
  • b,f,p,v → 1
  • c,g,j,k,q,s,x,z → 2
  • d,t → 3
  • l → 4
  • m,n → 5
  • r → 6
  • h、w、y→未编码/已移除

编码后,代码变成 C55。

4.如果原姓名中有两个或两个以上同号字母相邻(步骤 1 之前),只保留首字母;同样,由“h”或“w”分隔的具有相同数字的两个字母被编码为单个数字,而由元音分隔的这种字母被编码两次。这条规则也适用于第一个字母。现在,我们有两个 5,所以我们将它们合并成一个,得到 C5。

5.如果单词中的字母太少,我们无法分配三个数字,请添加零,直到有三个数字。如果我们有四个或更多的数字,只保留前三个。由于我们只有一个字母和一个数字,我们将在编码的末尾添加两个零,使其成为一个四字符代码。因此,我们得到 C500 作为“钦奈”的最终代码。

因此,我们看到像“Bengaluru”和“Bangalore”这样的城市名称的 Soundex 代码是相同的,B524,这就是我们的目标。

所以,我们看到了如何处理一个特定单词的不同发音。接下来,让我们看看如何处理拼写错误。

编辑距离

简而言之,编辑距离是将一个字符串转换为另一个字符串所需的最小编辑次数,即给定字符串到目标字符串。

现在,你一定想知道什么是编辑。因此,可能的编辑如下:-

  • 将一个字符插入给定的字符串。要将拼写错误的单词“Aquire”转换为正确的拼写“Acquire ”,我们需要在给定的拼写错误的字符串中插入字符“c”。
  • 从给定的字符串中删除一个字符。要将“necessary”转换为“必需的”,我们需要从给定的字符串中删除多余的“c”。
  • 给定字符串中字符的替换。为了将 Absense 转换成正确的形式 Absense,我们需要用字符 c 代替字符 s。

最常见的编辑距离算法是 Levenshtein 编辑距离,你可以在这里详细了解。还有另一个编辑选项叫做“转置操作”,你可以交换给定字符串的两个相邻字符。但是,该操作仅在damer au-Levenshtein编辑距离中可用。

拼写纠正器

拼写校正器是一个广泛使用的应用程序。如果您在电话上启用了“自动更正”功能,不正确的拼写将被正确的拼写替换。另一个例子是,当你使用谷歌这样的搜索引擎搜索任何东西,却打错了一个单词,它会提示正确的单词。拼写纠正是词汇处理的重要组成部分。在许多应用中,拼写校正形成了初始预处理层。

我们看到了如何计算两个单词之间的编辑距离。现在,我们将使用编辑距离的概念来制作拼写校正器。我们现在来看看如何制作著名的 Norvig 法术修正器。

我们需要大量拼写正确的文本。这个文本语料库也将作为我们的拼写校正器的字典搜索。在这里,文本“big.txt”的大型语料库只不过是一本书。这是古腾堡计划网站上以文本格式呈现的《夏洛克·福尔摩斯历险记》一书。

# function to tokenise words
def words(document):
 “Convert text to lower case and tokenise the document”
 return re.findall(r’\w+’, document.lower())# create a frequency table of all the words of the document
all_words = Counter(words(open('big.txt').read()))

我们将使用五个主要函数来查找单词的正确拼写,它们如下:

  1. edits_one() :函数创建与输入单词相距一个编辑距离的所有可能单词。这个函数创建的大多数单词都是垃圾,即它们不是有效的英语单词。例如,如果我们将单词' laern '(单词' learn '的拼写错误)传递给 edits_one(),它将创建一个列表,其中将出现单词' lgern ',因为它是远离单词' laern '的编辑。但这不是一个英语单词。只有一部分单词是真正的英语单词。
def edits_one(word):
 “Create all edits that are one edit away from `word`.”
 alphabets = ‘abcdefghijklmnopqrstuvwxyz’
 splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
 deletes = [left + right[1:] for left, right in splits if right]
 inserts = [left + c + right for left, right in splits for c in alphabets]
 replaces = [left + c + right[1:] for left, right in splits if right for c in alphabets]
 transposes = [left + right[1] + right[0] + right[2:] for left, right in splits if len(right)>1]
 return set(deletes + inserts + replaces + transposes)
  1. edits_two() :函数创建一个所有可能的单词的列表,这些单词与输入单词相差两个编辑点。这些话大部分也会是垃圾。
def edits_two(word):
 “Create all edits that are two edits away from `word`.”
 return (e2 for e1 in edits_one(word) for e2 in edits_one(e1))
  1. known(): 函数从给定单词列表中过滤出有效的英语单词。它使用频率分布作为使用种子文档创建的字典。如果使用 edits_one()和 edits_two()创建的单词不在词典中,它们将被丢弃。
def known(words):
 “The subset of `words` that appear in the `all_words`.”
 return set(word for word in words if word in all_words)
  1. possible_corrections(): 该函数获取输入单词,并使用上述三个函数返回给定输入单词的正确拼写。首先,它检查输入单词的拼写,如果拼写是正确的,也就是说,如果该单词存在于字典中,它不返回拼写建议,因为它已经是一个正确的字典单词。

如果拼写不正确,它将搜索与输入单词相差一个编辑的每个词典单词,并返回它们的列表。如果词典中没有与给定单词相距一个编辑点的单词,那么它将搜索相距两个编辑点的所有词典单词,并返回它们的列表。如果没有两个编辑之外的单词,输入的单词被返回,这意味着拼写纠正器找不到替代词。

def possible_corrections(word):
 “Generate possible spelling corrections for word.”
 return (known([word]) or known(edits_one(word)) or known(edits_two(word)) or [word])

5.prob():prob()函数将创建与每个建议的正确拼写相关联的概率,并返回具有最高概率的拼写,或者我们可以说,它采用建议的正确拼写并返回在我们的文本语料库中的输入单词中最频繁出现的拼写。

这就是为什么我们需要一个大的文本语料库,而不是一本字典。字典只包含所有正确英语单词的列表。但是,文本语料库不仅包含所有正确的单词,还可以用来创建所有这些单词的频率分布。

def prob(word, N=sum(all_words.values())): 
 “Probability of `word`: Number of appearances of ‘word’ / total number of tokens”
 return all_words[word] / N

现在,我们几乎完成了拼写校正器的构建。我们只需要把所有的代码片段放在一起,并把它们包装在一个新的函数中,这个函数使用到目前为止创建的所有函数。

def spell_check(word):
 “Print the most probable spelling correction for `word` out of all the `possible_corrections`”
 correct_word = max(possible_corrections(word), key=prob)
 if correct_word != word:
 return “Did you mean “ + correct_word + “?”
 else:
 return “Correct spelling.”

瞧啊。我们已经成功地创建了一个简单却非常有效的拼写纠正器。我们现在可以使用它来纠正任何给定文本语料库的拼写。

这就是第三部分的内容。我们已经在第 2 部分和第 3 部分中介绍了整个词汇处理过程。现在,我们将进入 NLP 的下一个主要部分——句法处理。干杯!

自然语言处理:使用 Spacy 和 Python 智能搜索文本

原文:https://towardsdatascience.com/natural-language-processing-document-search-using-spacy-and-python-820acdf604af?source=collection_archive---------4-----------------------

使用 Python 和机器学习从文本中提取有用信息

在文本中搜索是自然语言领域中机器学习应用的关键焦点领域之一。

但是如果我们必须从一个大文档(100+页)中搜索多个关键词呢?此外,如果我们在我们的文档中进行了上下文搜索(搜索相似含义的关键字),该怎么办!——传统的“CTRL + F”解决方案要么需要很长时间来完成这项任务(或者在上下文搜索的情况下,将无法找到任何有意义的文本)。

本文将帮助读者理解我们如何使用 Spacy(一个强大的开源 NLP 库)和 Python 来使用机器学习解决这个问题。

数据预处理

构建任何基于机器学习的解决方案的第一步是预处理数据。在我们的例子中,我们将使用 Python 中的 PyPDF2 包预处理 PDF 文档,然后将整个文本转换成 Spacy 文档对象。对于没有使用过 Spacy 的读者来说,这是一个高级的 Python 开源库,用于各种 NLP 任务。对于有兴趣了解 Spacy 更多信息的用户,请参考此链接阅读文档并了解 Spacy 更多信息—https://spacy.io/

我们将首先加载 PDF 文档,清理文本,然后将其转换为 Spacy 文档对象。以下代码可用于执行此任务-

数据预处理

首先,我们必须加载 Spacy 的' en_core_web_lg '模型,这是 Spacy 中提供的一个预先训练好的英语语言模型。Spacy 还提供了对多种语言的支持(更多信息可以在文档链接中找到)。此外,Spacy 有多种型号(小型、中型和大型),对于我们的情况,我们将使用大型型号,因为我们必须使用仅大型型号支持的单词向量。

' setCustomBoundaries() '用作客户句子分割方法,与默认选项相反。同样的方法可以根据我们处理的单据进行修改。

一旦我们准备好了空间的文档对象,我们就可以进入下一步,处理需要在文档中搜索的输入查询(关键字)。

处理查询-查找相似的关键字

在进入编码部分之前,让我们看一下为了从我们正在搜索的文档中获得更准确的搜索结果而采用的更广泛的方法。

流程工作流

直到数据预处理阶段,我们已经将 PDF 文档文本转换为 Spacy 的文档对象。现在,我们还必须将我们的关键字转换为 Spacy 的文档对象,将它们转换为等价的向量形式((300,)维),然后使用余弦相似度来查找相似的关键字。最后,我们将有一个类似的关键字以及原始关键字的详尽列表,我们现在可以通过搜索我们的文档来生成准确的结果。

请参考以下代码来执行此任务-

生成相似的关键字

既然我们已经找到了与原始关键字上下文相似的单词,让我们开始最后的搜索部分。

通过文本搜索关键词

对于搜索,我们将使用 Spacy 的 Matcher 类的 PhraseMatcher 类。此时,重要的是要记住 Spacy 的文档对象不同于简单的 python 字符串,因此我们不能直接使用 if then else 来查找结果。

请参考以下代码来执行此任务-

在文本中搜索

上面的代码将搜索整个文本中的每个关键字,并在找到匹配的地方返回整个句子。

上述代码将生成以下输出-

搜索输出截图

您可以增加或减少想要为任何原始关键词查找的相似关键词的数量。此外,一旦在数据帧中获得结果,您可以简单地添加更多的逻辑来对结果进行排序(给精确的关键字匹配更多的权重,等等)。

注意:增加相似关键字的数量可能会增加整个程序的计算成本,因此应该明智地选择。

这就是你如何创建你自己的基于 ML 的 Python 程序来搜索任何文本。

在任何其他输入源(照片、网页等)的情况下。)你只需要定制数据预处理部分(OCR,网页抓取等。)和其余的逻辑应该执行得很好。

Python 中面向消费者满意度的自然语言处理

原文:https://towardsdatascience.com/natural-language-processing-for-consumer-satisfaction-in-python-e2b6d473efd1?source=collection_archive---------35-----------------------

消费者评论的数据挖掘和可视化

照片由晨酿Unsplash 拍摄

一家公司如何更好地了解消费者对其产品的看法,以便改进产品?

营销咨询公司或内部团队一直在分析消费者的感知,以了解如何改进其产品、品牌和营销活动。但是解决这个问题的传统方法是深度访谈或调查,这些方法通常不遵循统计抽样技术,并且需要资源来收集数据。

在社交网络时代,我们每天都会产生大量的数据。例如,该公司的脸书页面可以作为收集评论、收件箱信息和反应的宝贵资源。其他数据来源是亚马逊和 Lowe's 等电子商务平台上消费者的评论和评价。在这里,我将介绍如何使用 Python 和自然语言处理(NLP)来分析文本数据,并从这些评论中获得见解。

在下面,我们可以看到所使用的数据集,例如,它由来自不同零售商和产品(主要是冰箱)的 20473 条消费者评论组成。目标是(1)提取文本中编码产品功能、结构或购买过程的特征的单词;(2)确定销售渠道中的内容;(3)探索这些信息以产生洞察力,例如,哪些特征与正面评价最相关?最后,(4)生成数据可视化以传达结果。

作者图片

探索我们将使用哪些属性(列),可以看到我们有有用的信息,如零售商、类别、品牌、评论用户评级和文本评论本身。因此,我们可以考虑实现目标所需的步骤:

A.预处理和探索性分析:(1)清洗和标记文本;(2)统计总字数以识别特征为最常见的名词;(3)创建产品的二元估价(好/坏)。

B .情感分析:(1)识别有价值的特征进行发掘;(2)特征附近最频繁出现的形容词的词云可视化;(3)对时间特征的情感。

预处理和探索性分析

首先,我们导入库和 NLTK 模型。如果你没有这些库,你可以在终端中使用 pip 安装库来安装。注意使用 NLTK 包进行自然语言处理,熊猫用于数据操作, plotly袖扣用于数据可视化。

第一步是根据 review_id 列识别重复的评论并删除它们。69%的数据是重复的,这是一个很高的数字,应该由从网站上收集这些数据的负责团队进行验证。

在导入和探索之后,我们可以对评论进行预处理,将单词放在小写字母中,删除数字,删除停用词(连接词)并应用词汇标准化算法。这个过程使我们的文本标准化,以便使特征提取更有效,所以我们使“令人愉快的”和“享受”去“享受”,例如。

现在我们可以统计评论中的单词并识别词类(名词、形容词、动词、副词等。).通过这一步,我们将能够识别用名词表达的相关特征。

作者图片

在这里我们可以看到相关的特征,如冰箱、门、冰、冰箱、水、空间等。下一步是探索哪些情感与这些特征相关联。

情感分析

为了执行情感分析,我列出了在之前的分析中观察到的相关特征。我们将使用这个列表在数据集中创建其他属性:(1)标识每个评论上是否有相关特征的属性;(2)具有形容词(情感)和的列;(3)告诉我们评论是正面(≥4 星)还是负面(< 4 星)的属性。

现在可以搜索特征附近的单词和形容词,以了解人们对每个方面的看法。我还要强调的是,这个过程可以通过实施一个简单的过滤器,将您的品牌与其他品牌进行比较,从而导向一个特定的品牌或产品,但出于教育目的,我们在这个分析中包括了所有品牌。

在这里,我编写了三种不同的分析策略来聚合我们正在寻找的特征附近的文本,因此在下一步中,将对提取的文本进行计数。我们可以识别特征评论中的所有词(ruleAll),特征词右边的词(ruleNext),或者离特征 3 个词距离的特征附近的词(ruleNear)。

最后,我们编写了 wordcloud 可视化代码,它对前面的搜索算法返回的文本字符串中的单词进行计数。

现在我们可以看到结果:

作者图片

第一个来源于探索特征旁边的文字,这导致了文字制造者机器分配器,表明许多评论都与冰箱的这一方面有关。

更深入的分析是识别与单词“冰”相关的消极和积极情绪,这样我们可以从消费者对制冰机的感知中获得洞察力。下面左边的词云是基于正面评论中接近特征 ice 的词,其中观察到相关形容词,如 easybig、spatial、large表示消费者对大型制冰机的兴趣。

右边的词云捕捉了负面评论中接近于的词,这里我们可以看到形容词的突出显示,即增强了消费者对大型冰生产商的兴趣,但不太大,因为我们发现是对冰的差评。

同时,也有可能在差评中看到与 ice 相关的正面情绪,像 goodgreat ,这表明即使在差评中人们仍然可以指出产品的一个好的特性。

只要改变函数 aspectSentimentWordcloud()中的“方面”,就可以为任何其他特性复制相同的模型。

(左)作者在“ice”附近的正面评论中的单词| (右)作者在“ice”附近的负面评论中的单词

时间序列情感分析

正如我们在开始时看到的,数据集中有日期信息,可以用来让我们了解特定品牌、产品或功能的正面评论的分布情况。在这里,我展示了按日期计算正面评论的代码,并使用 plotly 交互图来可视化它。

在生成的图中,我们可以看到没有明确的长期趋势,因为回归线(trace1) 几乎没有变化。尽管如此,正面百分比线本身也存在表达上的变化,比如从 2019 年 9 月到 10 月,我们观察到的负面影响几乎只有 60%的正面评论,随后正面评论飙升至 90%。这个分析可以告知消费者对某个在此期间推出的产品的感知。

结论

在本文中,我想展示分析师或数据科学家如何使用 Python 工具处理、分析和可视化文本数据,以从消费者的感知中获得洞察力。

一旦来源是来自满意或不满意的消费者的大量评论和意见,而不是来自调查的封闭问题,使用这些工具不仅可以降低收集数据的成本,还可以获得自发的趋势和想法。

人们也可以用它来分析调查或深度访谈中的开放性问题。虽然数据量可能没有线上平台那么大。

我对小鸟的数据集表示感谢。如需获取数据和查看完整项目,您可以访问 https://github.com/claudioalvesmonteiro/nlp_birdie

自然语言处理:从西瓜盒子到单词嵌入

原文:https://towardsdatascience.com/natural-language-processing-from-watermelon-boxes-to-word-embeddings-4eb32e7dfd8a?source=collection_archive---------37-----------------------

使用单词嵌入的自然语言处理的强大发展

众所周知,人类不擅长随机应变。不管我们是否意识到这一点,我们做的每件事都有一定的模式。

我们用来交流的语言也不例外。所有的语言都遵循某种被称为句法的规则模式。

但是这有什么关系呢?

深度学习行业的很大一部分专注于一种名为的自然语言处理(NLP) 的东西。 NLP 是人工智能的一个子领域,专注于训练计算机处理人类语言。

信用:猫王

自然语言处理始于 20 世纪 50 年代,当时哈佛的一名研究人员创造了一种叫做“西瓜盒”的机器。

它做了一件简单的事情…当一个人说“西瓜”这个词时,它可以探测到。

创造它的人认为 NLP 的未来是创造数千个盒子,每个盒子检测一个单词…

这在现在听起来很可笑,但在当时却是一项非常重要的发明。

从那以后,我们走过了漫长的道路,西瓜盒子现在已经被遗忘了很久。事实上,如果没有数以千计的方形西瓜出现,很难在网上找到任何关于它们的信息:

信用:melonmold.com

现在,NLP 到处都在用。无论你使用的是谷歌翻译、Siri,还是语法——都有一个人工智能在后台使用 NLP 来理解你用什么语言交流。

所以最大的问题是:神经网络是如何变得如此擅长理解人类语言的?

信用:igeeksblog.com

让我们从经典的全连接神经网络如何处理这个问题开始。

如果你想了解神经网络是如何工作的,可以看看 这篇文章

首先,神经网络只能接受数字作为输入。所以你不能只给它一堆文本来处理。你得把它转换成一个数值。

最初解决这个问题的方法是通过索引。基本上每个单词都会用它自己唯一的数字来表示。这个数字然后被一键编码。

这相当于给一个对化学一无所知的人一个基本周期表的单个单元格。

就像桌子上的每个元素都有唯一的原子序数一样,神经网络看到的每个单词都有唯一的索引。

元素在周期表上的位置提供了很多信息。很明显,只有表格中的一个单元格,您会丢失那些有价值的信息。

同样,简单的全连接神经网络的问题是,人工智能没有这个词的上下文。

它不知道在它所查看的单词之前出现了什么单词,所以你不能指望它用那个单词做任何有价值的事情。

递归神经网络

NLP 的很多改进都是从递归神经网络(RNNs)开始的。它们非常擅长处理一系列数据(比如句子),因为它们使用内存来使用上下文。

你可以在这里了解递归神经网络如何工作

用我们的化学类比,这和给你整个周期表是一样的。现在,您有更好的机会根据元素所在的行和列来理解趋势。

类似地,RNN 可以使用它正在分析的词周围的词来理解上下文并做出更好的预测。

RNNs 是一个重大的进步,可以更好地生成和分析文本。

Word2Vec

从那以后,NLP 有了更多的进展,出现了各种关于新的训练优化器、网络架构等的研究论文。

但是在所有这些中,NLP 最大的胜利之一是使用了像 Word2Vec 这样的嵌入层。

使用 RNNs,算法可以识别单词的上下文,但它不会真正理解每个单词。它只是看到一个随机的索引号。

神经网络遗漏了关于每个单词的如此多的信息。

任何语言中的每个单词都有几个我们在理解该语言时下意识分析的属性。一个词可以是复数,可以是名词,可以有特定的动词时态,等等。

Word2Vec 确实如其名。它获取一个单词,并将其转换为向量表示:

我将忠于我的周期表类比,展示使用 Word2Vec 这样的嵌入层处理 Word 的整个过程。

索引氦给出了它独特的数字表示:它的原子序数。

将这个数字传递给经过训练的 Word2Vec 层,我们就可以得到氦的矢量表示。这将是原子量,电子配置,物理状态等。

这里有一个我创建的可视化,用来总结 Word2Vec 和 RNNs 对自然语言处理的影响的周期表类比:

通过嵌入 Word2Vec 这样的层产生的矢量中最酷的部分之一是你可以可视化和量化单词之间的关系。

嵌入向量的维数取决于嵌入的大小(由程序员决定)。

当任何单词被转换成向量时,它的维数等于嵌入的大小。

然后,您可以在图表上绘制这些向量,并可视化各种单词之间的关系。

让我们以嵌入大小为 3 为例。它将生成 3D 矢量,我们可以在笛卡尔平面上绘制这些矢量:

在实践中,嵌入层比这大得多,但是你不能可视化超过 3 维的空间。

你可以立即看到这些向量位置的一些趋势。相似的词在向量空间中位置相近。我对矢量头部进行了颜色编码,以阐明示例中的聚类:

红色→ 地方

橙色→ 动词

黄色→

更有趣的是,单词之间精确的矢量转换背后也有意义。

每个箭头颜色都是某种矢量变换,代表单词之间的关系。

以下是本例中矢量变换及其显示的关系的摘要:

绿色:国家→首都

粉色:不定式→过去式

蓝色:不定式→现在式

紫色:男性→女性

棕色:人→皇室

Word2Vec 向量是如何计算的

Word2Vec 通过学习从训练句子中预测单词来嵌入单词。

这个想法是,神经网络将学习为以类似方式使用的单词分配类似的权重。

拿下面这句话来说:

The ____ 正在跳跃。

空白单词可以是任何名词,如青蛙、人、狗等。

因此,相似的单词将具有相似的权重值,将它们连接到嵌入层中的每个节点。

你可以用余弦距离来衡量单词之间的相似度。相关单词将具有小的余弦距离。

由于单词是一次性编码的,嵌入层的权重变成了一个查找表,我们可以在其中找到该单词的矢量表示。

信用: Udacity

这就像一本字典,你提供你想要嵌入的单词的索引和它在权重矩阵中相应行的外观。

Word2Vec 的类型

即使在 Word2Vec 中,也有多种类型:连续单词包(CBOW)和 Skip-gram。

信用:machinelearningmastery.com

在 CBOW 中,你取一个句子中某个窗口的单词,试着填空。 CBOW 获取上下文并生成单词。

Skip-gram 做的正好相反——它取一个单词,然后猜测它周围出现的单词。 Skip-gram 获取一个单词并生成其上下文。

直觉上,你会认为 CBOW 比 Skip-gram 更容易实现,因为两者之间的比率给了你更多的信息,而你需要猜测的更少。

有趣的是 Skip-gram 是实现 Word2Vec 的首选方式。只是看起来效果更好。

除了 Word2Vec,在嵌入层方面还有一些更有趣的进步。

另一种称为 Doc2Vec 的嵌入类型创建整个段落的矢量表示,顾名思义就是文档。

原帖:

* [## Mayank Jain - NLP:从西瓜盒子到单词嵌入

众所周知,人类不擅长随机应变。不管我们是否意识到,我们所做的一切都倾向于…

mayankjain.ca](https://mayankjain.ca/blog-posts/17)

如果你喜欢这篇文章:

  • Medium 上关注我,在 LinkedIn 上与我联系,了解我的最新工作进展!
  • 订阅我的时事通讯,跟随我的旅程!:

[## 注册我的每月更新!

注册以跟上我每月的进度,包括项目、会议、文章等等...

www.subscribepage.com](https://www.subscribepage.com/mayank)*

将 PDF 和 Gutenberg 文档格式转换为文本:生产中的自然语言处理

原文:https://towardsdatascience.com/natural-language-processing-in-production-converting-pdf-and-gutenberg-document-formats-into-text-9e7cd3046b33?source=collection_archive---------20-----------------------

在生产级自然语言处理(NLP )中最关键的是将流行的文档格式快速预处理成文本。

企业中有大量不同的文档。资料来源:联合国人类住区规划署

据估计,世界上 70%–85%的数据是文本(非结构化数据)。大多数英语和欧盟商务数据格式为字节文本、MS Word 或 Adobe PDF。[1]

组织 web 显示一个dobePostscript 文档格式文档( PDF )。[2]

在这篇博客中,我详述了以下内容:

  1. 从 web 文件名和本地文件名创建文件路径;
  2. 将字节编码的古腾堡项目文件转换成文本语料库;
  3. 将 PDF 文档转换成文本语料库;
  4. 将连续文本分割成单词文本语料库。

将流行的文档格式转换为文本

1.从 web 文件名或本地文件名创建本地文件路径

以下函数将采用本地文件名或远程文件 URL 并返回一个文件路径对象。

#in file_to_text.py
--------------------------------------------
from io import StringIO, BytesIO
import urllib

def file_or_url(pathfilename:str) -> Any:
    *"""
    Reurn filepath given local file or URL.
    Args:
        pathfilename:

    Returns:
        filepath odject istance

    """* try:
        fp = open(pathfilename, mode="rb")  # file(path, 'rb')
    except:
        pass
    else:
        url_text = urllib.request.urlopen(pathfilename).read()
        fp = BytesIO(url_text)
    return fp

2.将 Unicode 字节编码文件转换成一个 o Python Unicode 字符串

您将经常遇到 8 位 Unicode 格式的文本 blob 下载(在浪漫的语言中)。您需要将 8 位 Unicode 转换为 Python Unicode 字符串。

#in file_to_text.py
--------------------------------------------
def unicode_8_to_text(text: str) -> str:
    return text.decode("utf-8", "replace")import urllib
from file_to_text import unicode_8_to_texttext_l = 250text_url = r'[http://www.gutenberg.org/files/74/74-0.txt'](http://www.gutenberg.org/files/74/74-0.txt') 
gutenberg_text =  urllib.request.urlopen(text_url).read()
%time gutenberg_text = unicode_8_to_text(gutenberg_text)
print('{}: size: {:g} \n {} \n'.format(0, len(gutenberg_text) ,gutenberg_text[:text_l]))

输出= >

CPU times: user 502 µs, sys: 0 ns, total: 502 µs
Wall time: 510 µs
0: size: 421927 

The Project Gutenberg EBook of The Adventures of Tom Sawyer, Complete by
Mark Twain (Samuel Clemens)

This eBook is for the use of anyone anywhere at no cost and with almost
no restrictions whatsoever. You may copy it, give it away or re-use
it under the terms of the Project Gutenberg License included with this
eBook or online at www.guten

结果是text.decode('utf-8') 可以在大约 1/1000 秒内格式化成一个包含一百万个字符的 Python 字符串。这一速度远远超过了我们的生产率要求。

3.将 PDF 文档转换为文本语料库。

“将 PDF 文档转换成文本语料库 ”是我为 NLP 文本预处理做的最麻烦也是最常见的任务之一。

#in file_to_text.py
--------------------------------------------
def PDF_to_text(pathfilename: str) -> str:
    *"""
    Chane PDF format to text.
    Args:
        pathfilename:

    Returns:

    """* fp = file_or_url(pathfilename)
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, laparams=laparams)
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    password = ""
    maxpages = 0
    caching = True
    pagenos = set()

    for page in PDFPage.get_pages(
        fp,
        pagenos,
        maxpages=maxpages,
        password=password,
        caching=caching,
        check_extractable=True,
    ):
        interpreter.process_page(page)

    text = retstr.getvalue()

    fp.close()
    device.close()
    retstr.close()

    return text
-------------------------------------------------------arvix_list =['[https://arxiv.org/pdf/2008.05828v1.pdf'](https://arxiv.org/pdf/2008.05828v1.pdf')
             , '[https://arxiv.org/pdf/2008.05981v1.pdf'](https://arxiv.org/pdf/2008.05981v1.pdf')
             , '[https://arxiv.org/pdf/2008.06043v1.pdf'](https://arxiv.org/pdf/2008.06043v1.pdf')
             , 'tmp/inf_finite_NN.pdf' ]
for n, f in enumerate(arvix_list):
    %time pdf_text = PDF_to_text(f).replace('\n', ' ')
    print('{}: size: {:g} \n {} \n'.format(n, len(pdf_text) ,pdf_text[:text_l])))

输出= >

CPU times: user 1.89 s, sys: 8.88 ms, total: 1.9 s
Wall time: 2.53 s
0: size: 42522 
 On the Importance of Local Information in Transformer Based Models  Madhura Pande, Aakriti Budhraja, Preksha Nema  Pratyush Kumar, Mitesh M. Khapra  Department of Computer Science and Engineering  Robert Bosch Centre for Data Science and AI (RBC-DSAI)  Indian Institute of Technology Madras, Chennai, India  {mpande,abudhra,preksha,pratyush,miteshk}@ 

CPU times: user 1.65 s, sys: 8.04 ms, total: 1.66 s
Wall time: 2.33 s
1: size: 30586 
 ANAND,WANG,LOOG,VANGEMERT:BLACKMAGICINDEEPLEARNING1BlackMagicinDeepLearning:HowHumanSkillImpactsNetworkTrainingKanavAnand1anandkanav92@gmail.comZiqiWang1z.wang-8@tudelft.nlMarcoLoog12M.Loog@tudelft.nlJanvanGemert1j.c.vangemert@tudelft.nl1DelftUniversityofTechnology,Delft,TheNetherlands2UniversityofCopenhagenCopenhagen,DenmarkAbstractHowdoesauser’sp 

CPU times: user 4.82 s, sys: 46.3 ms, total: 4.87 s
Wall time: 6.53 s
2: size: 57204 
 0 2 0 2     g u A 3 1         ]  G L . s c [      1 v 3 4 0 6 0  .  8 0 0 2 : v i X r a  Offline Meta-Reinforcement Learning with  Advantage Weighting  Eric Mitchell1, Rafael Rafailov1, Xue Bin Peng2, Sergey Levine2, Chelsea Finn1  1 Stanford University, 2 UC Berkeley  em7@stanford.edu  Abstract  Massive datasets have proven critical to successfully 

CPU times: user 12.2 s, sys: 36.1 ms, total: 12.3 s
Wall time: 12.3 s
3: size: 89633 
 0 2 0 2    l u J    1 3      ]  G L . s c [      1 v 1 0 8 5 1  .  7 0 0 2 : v i X r a  Finite Versus Infinite Neural Networks:  an Empirical Study  Jaehoon Lee  Samuel S. Schoenholz∗  Jeffrey Pennington∗  Ben Adlam†∗  Lechao Xiao∗  Roman Novak∗  Jascha Sohl-Dickstein  {jaehlee, schsam, jpennin, adlam, xlc, romann, jaschasd}@google.com  Google Brain

在这个硬件配置上,“将 PDF 文件转换成 Python 字符串需要 150 秒。对于 Web 交互式生产应用程序来说不够快。

您可能希望在后台设置格式。

4.将连续文本分割成单词文本语料库

当我们阅读https://arxiv.org/pdf/2008.05981v1.pdf'时,它返回的是没有分隔字符的连续文本。使用来自 wordsegment,的包,我们把连续的字符串分成单词。

from wordsegment import load,  clean, segment
%time words = segment(pdf_text)
print('size: {:g} \n'.format(len(words)))
' '.join(words)[:text_l*4]

输出= >

CPU times: user 1min 43s, sys: 1.31 s, total: 1min 44s
Wall time: 1min 44s
size: 5005'an and wang loog van gemert blackmagic in deep learning 1 blackmagic in deep learning how human skill impacts network training kanavanand1anandkanav92g mailcom ziqiwang1zwang8tudelftnl marco loog12mloogtudelftnl jan van gemert 1jcvangemerttudelftnl1 delft university of technology delft the netherlands 2 university of copenhagen copenhagen denmark abstract how does a users prior experience with deep learning impact accuracy we present an initial study based on 31 participants with different levels of experience their task is to perform hyper parameter optimization for a given deep learning architecture the results show a strong positive correlation between the participants experience and then al performance they additionally indicate that an experienced participant nds better solutions using fewer resources on average the data suggests furthermore that participants with no prior experience follow random strategies in their pursuit of optimal hyperparameters our study investigates the subjective human factor in comparisons of state of the art results and scientic reproducibility in deep learning 1 introduction the popularity of deep learning in various elds such as image recognition 919speech1130 bioinformatics 2124questionanswering3 etc stems from the seemingly favorable tradeoff between the recognition accuracy and their optimization burden lecunetal20 attribute their success t'

你会注意到单词切分完成了相当精确的单词切分。有一些错误,或者我们不想要的单词, NLP 文本预处理清除掉。

阿帕奇语段速度很慢。对于少于 1000 字的小文档,它几乎不能满足生产的需要。我们能找到更快的分割方法吗?

4b。将连续文本分割成单词文本语料库

似乎有一种更快的方法来“将连续文本分割成单词文本的语料库”

正如以下博客中所讨论的:

[## 符号拼写与 BK 树:模糊字符串搜索和拼写检查快 100 倍

传统智慧和教科书说 BK 树特别适合拼写纠正和模糊字符串搜索…

towardsdatascience.com](/symspell-vs-bk-tree-100x-faster-fuzzy-string-search-spell-checking-c4f10d80a078)

SymSpell 快 100-1000 倍。哇!

注:编辑:2020 年 8 月 24 日沃尔夫·加贝指出值得称赞

SymSpell 博客文章中给出的基准测试结果(快 100-1000 倍)仅指拼写纠正,而非分词。在那篇文章中,SymSpell 与其他拼写纠正算法进行了比较,而不是与分词算法进行比较。2020 年 8 月 23 日

此外,从 Python 调用 C#库还有一种更简单的方法:https://stack overflow . com/questions/7367976/calling-a-C-sharp-library-from-Python—Wolfe Garbe 8/23/2020

注:编辑日期:2020 年 8 月 24 日。我打算试试 Garbe 的 C##实现。如果我没有得到相同的结果(很可能如果我得到了),我将尝试 cython port,看看我是否能作为管道元素适合 spacy。我会让你知道我的结果。

但是在 C# 中实现。因为我不会掉进无限的老鼠洞:

  • 把我所有的 NLP 转换成 C# 。不可行的选择。
  • Python 调用 C# 。我和 Python 团队的两位工程师经理谈过。他们拥有 Python-C# 功能,但是它涉及到:

注意:

  1. 翻译成VB-香草;
  2. 人工干预和翻译必须通过再现性测试;
  3. VB -vanilla 翻译成C
  4. 手动干预和翻译必须通过重复性测试。

相反,我们使用一个到 Python 的端口。下面是一个版本:

def segment_into_words(input_term):
    # maximum edit distance per dictionary precalculation
    max_edit_distance_dictionary = 0
    prefix_length = 7
    # create object
    sym_spell = SymSpell(max_edit_distance_dictionary, prefix_length)
    # load dictionary
    dictionary_path = pkg_resources.resource_filename(
        "symspellpy", "frequency_dictionary_en_82_765.txt")
    bigram_path = pkg_resources.resource_filename(
        "symspellpy", "frequency_bigramdictionary_en_243_342.txt")
    # term_index is the column of the term and count_index is the
    # column of the term frequency
    if not sym_spell.load_dictionary(dictionary_path, term_index=0,
                                     count_index=1):
        print("Dictionary file not found")
        return
    if not sym_spell.load_bigram_dictionary(dictionary_path, term_index=0,
                                            count_index=2):
        print("Bigram dictionary file not found")
        returnresult = sym_spell.word_segmentation(input_term)
    return result.corrected_string%time long_s = segment_into_words(pdf_text)
print('size: {:g} {}'.format(len(long_s),long_s[:text_l*4]))

输出= >

CPU times: user 20.4 s, sys: 59.9 ms, total: 20.4 s
Wall time: 20.4 s
size: 36585 ANAND,WANG,LOOG,VANGEMER T:BLACKMAGICINDEEPLEARNING1B lack MagicinDeepL earning :HowHu man S kill Imp acts Net work T raining Ka nav An and 1 an and kana v92@g mail . com ZiqiWang1z. wang -8@tu delft .nlM arc oLoog12M.Loog@tu delft .nlJ an van Gemert1j.c. vang emert@tu delft .nl1D elf tUniversityofTechn ology ,D elf t,TheN ether lands 2UniversityofC open hagen C open hagen ,Den mark Abs tract How does a user ’s prior experience with deep learning impact accuracy ?We present an initial study based on 31 participants with different levels of experience .T heir task is to perform hyper parameter optimization for a given deep learning architecture .T here -s ult s show a strong positive correlation between the participant ’s experience and the fin al performance .T hey additionally indicate that an experienced participant finds better sol u-t ions using fewer resources on average .T he data suggests furthermore that participants with no prior experience follow random strategies in their pursuit of optimal hyper pa-ra meters .Our study investigates the subjective human factor in comparisons of state of the art results and sci entific reproducibility in deep learning .1Intro duct ion T he popularity of deep learning in various fi eld s such as image recognition [9,19], speech [11,30], bio informatics [21,24], question answering [3] etc . stems from the seemingly fav or able trade - off b

Python 中实现的 SymSpellpy 大约快了 5 倍。我们没有看到 100-1000 倍的速度。

我猜 SymSpell-C# 是在比较用 Python 实现的不同分割算法。

也许我们看到的加速是由于 C# ,一种编译过的静态类型语言。由于 C#C 的计算速度差不多,我们应该期待 C#Python 实现快 100-1000 倍。

注意:有一个 spacy 流水线实现 spacy_symspell,直接调用 SymSpellpy。我建议你不要使用 spacy_symspell。Spacy 首先生成令牌作为流水线的第一步,这是不可变的。 spacy_symspell 从分割连续文本生成新文本。它不能在空间中生成新的令牌,因为空间已经生成了令牌。。一个 空间管道工作于一个令牌序列,而不是一个文本流。人们将不得不衍生出一个改变了的版本。何必呢?代替将连续文本分割成单词文本语料库。然后更正单词中嵌入的空格和带连字符的单词。做任何其他你想做的原始清洁。然后将原始文本输入到空间

我显示空间 _ 符号拼写。再一次我的建议是 不要 使用它。

import spacy
from spacy_symspell import SpellingCorrector def segment_into_words(input_term):
nlp = spacy.load(“en_core_web_lg”, disable=[“tagger”, “parser”])
corrector = SpellingCorrector()
nlp.add_pipe(corrector)

结论

在以后的博客中,我会详细介绍许多常见和不常见的快速文本预处理方法。此外,我将展示从移动 SymSpellpycython 的预期加速。

在“将 X 格式转换成文本语料库”的世界中,您需要支持更多的格式和 API。

我详细介绍了两种更常见的文档格式, PDF古腾堡 项目格式。另外,我给出了两个 NLP 实用函数segment_into_wordsfile_or_url.

我希望你学到了一些东西,并且可以使用这个博客中的一些代码。

如果你有一些格式转换或者更好的软件包,请告诉我。

参考

[1] 我们每天会产生多少数据?

[2]https://en.wikipedia.org/wiki/PDF

【3】将 DNA 序列分割成‘单词’

4 个基本正则表达式操作符简化了自然语言处理

原文:https://towardsdatascience.com/natural-language-processing-made-simpler-with-4-basic-regular-expression-operators-5002342cbac1?source=collection_archive---------56-----------------------

了解四种基本的常规操作,以清理几乎所有类型的可用数据

图为苏珊尹Unsplash

用机器学习和深度学习来构建自然语言处理项目总是很棒的。然而,在我们开始构建我们的模型之前,我们遇到了一个非常无聊但重要的问题。

在数据收集和探索性数据分析步骤之后,我们必须立即处理令人厌烦的预处理步骤。显然,我们可用的大多数数据并不清晰,我们必须对其进行处理以提高数据集的质量,从而从构建的模型中获得更有效的结果。

今天,我们将看看带有四个内置函数的正则表达式是如何成为最佳解决方案的。正则表达式是一个内置的标准库模块,可用于清理和预处理数据。下面的简单命令可以用来导入正则表达式模块。

import re

在开始之前,让我们先了解正则表达式模块和一些基础知识,以便更直观地理解进一步的概念。

正则表达式:

正则表达式是字符串,其语法允许它们处理其他形式的文本数据中的模式。re 模块用于解析文本数据,不需要额外安装。

GIF 来自 GIPHY

正则表达式文档提供的常见模式列表非常庞大。我将提供清理数据所需的更简短的形式。这些是我唯一用过的。我会少用一些其他的。

因此,我发现与其他操作相比,用于匹配文本数据的一些常见模式是最有用的,如下所示:

  1. \d: 匹配任何 Unicode 十进制数字(即 Unicode 字符类别[Nd]中的任何字符)。这包括[0-9],以及许多其他数字字符。如果使用了[ASCII](https://docs.python.org/3/library/re.html#re.ASCII)标志,则只有[0-9]匹配。
  2. \D: 匹配任何不是十进制数字的字符。这是\d的反义词。如果使用了[ASCII](https://docs.python.org/3/library/re.html#re.ASCII)标志,这相当于[^0-9]
  3. \s': 匹配 Unicode 空白字符(包括[ \t\n\r\f\v],以及许多其他字符,例如许多语言中排版规则要求的不间断空格)。如果使用了[ASCII](https://docs.python.org/3/library/re.html#re.ASCII)标志,则只有[ \t\n\r\f\v]匹配。
  4. '\S': 匹配任何不是空白字符的字符。这是\s的反义词。如果使用了[ASCII](https://docs.python.org/3/library/re.html#re.ASCII)标志,这相当于[^ \t\n\r\f\v]
  5. '\w': 匹配 Unicode word 字符;这包括任何语言中单词的大部分字符,以及数字和下划线。如果使用了[ASCII](https://docs.python.org/3/library/re.html#re.ASCII)标志,则只有[a-zA-Z0-9_]匹配。
  6. '\W': 匹配任何不是单词字符的字符。这与\w相反。如果使用了[ASCII](https://docs.python.org/3/library/re.html#re.ASCII)标志,这相当于[^a-zA-Z0-9_]。如果使用了[LOCALE](https://docs.python.org/3/library/re.html#re.LOCALE)标志,则匹配当前语言环境中既不是字母数字也不是下划线的字符。
  7. '+或*': 执行贪婪匹配。
  8. 'a-z':匹配小写组。
  9. 'A-Za-z':匹配大小写英文字母。
  10. '0–9':匹配从 0 到 9 的数字。

要了解更多关于这些常见图案的信息,以及如何搭配它们以发现更多图案和风格,请访问官方网站此处

正则表达式函数和方法:

在本节中,我们将讨论四种正则表达式方法,它们可以用来解决数据清理和数据预处理的大多数常见问题。正则表达式函数与正则表达式模式一起使用,对我们拥有的文本数据执行特定的操作。

艾德·罗伯森Unsplash 拍摄的照片

现在,让我们通过下面的文本示例更详细地分析如何使用这个模块,以及如何准确地使用 re 模块来执行适当处理和解析文本数据所需的各种操作。我只是用一些随机的不规则句子组成了一个随机的文本样本。你可以用和我一样的句子,或者随便编一个句子,然后跟着学。

文本示例如下所示:

sentence = "Machine Learning is fun. Deep learning is awesome. Artificial Intelligence: is it the future?"

我们将用于数据预处理的函数是以下四个基本的正则表达式操作—

  1. re.findall()
  2. 重新拆分()
  3. re.sub()
  4. 重新搜索()

使用上述四个函数,几乎可以完成任何自然语言任务和文本数据的数据预处理。所以,事不宜迟,让我们开始分析这些功能,以及如何利用它们。

  • re.findall()

上面的方法返回所有匹配的列表。如果没有找到匹配,则返回一个空列表。

让我们试着找出所有以大写字母开头的单词。下面的代码块可用于以下过程—

capital = re.findall("[A-Z]\w+", sentence)
print(capital)

这应该会给我们以下输出['机器','学习','深度','人工','智能']。

如果你想知道文本数据中有多少个句号或句号,你可以使用两个命令中的任何一个

1\. len(re.findall("[.]", sentence))
2\. len(re.findall("\.", sentence))

上面的两个命令都应该给出结果 2,因为我们总共有两个周期。backlash '\ '命令用于一个分隔符,只查找句点,而不执行另一个正则表达式操作。

  • re.split()

这个函数可以用来相应地拆分文本,只要有匹配,就会返回一个数据列表。否则返回一个空列表。

让我们执行一个拆分操作,得到一串由句点分隔的句子。下面的命令将是这个操作。

re.split("\.", sentence)

该操作将返回以下句子列表。

['Machine Learning is fun',
 ' Deep learning is awesome',
 ' Artificial Intelligence: is it the future?']

如果你想用句点和问号来分割,那么请执行下面的命令。

re.split("[.?]", sentence)
  • re()

以下函数在找到匹配项时执行替换操作。如果没有找到匹配,则模式保持不变。

如果你想用解释代替所有的句号和问号,你可以使用下面的命令

re.sub("[.?]", '!', sentence)

函数中的第一个位置是要替换的项目。第二个位置是您指定用什么来替换选择的位置。最后和第三个位置是要执行替换操作的句子或文本数据。

执行上述操作后,您应该会看到下面的句子。

'Machine Learning is fun! Deep learning is awesome! Artificial Intelligence: is it the future!'
  • re.search()

该函数查找特定单词、标点符号或选定项目的第一个匹配项,并相应地返回操作。如果没有找到匹配,则返回 none 类型值。

如果我想找到单词“fun”的起始字符和结束字符的位置在文本中,然后我可以运行下面的命令。

x = re.search("fun.", sentence)
print(x.start())
print(x.end())

上述代码块将返回 20 和 24 的输出。这个结果告诉我们,f 的位置是 20,而。是 24。我强烈推荐您使用这个功能尝试更多的操作。

这样,我们就完成了常规行动的主要部分。继续尝试本模块,以了解与本主题相关的更复杂的细节。

照片由 Giammarco BoscaroUnsplash 拍摄

结论:

在本文中,我们已经涵盖了机器学习的大多数数据集的预处理所需的大多数重要模式。我们还可以将从这篇文章中学到的知识用于网络抓取以及其他需要清理数据的活动。在 python 中使用正则表达式模块在较小程度上简化了这个枯燥的过程。

利用所有提供的模式和四个特定的函数通常足以执行几乎任何预处理操作,但是可以从正则表达式官方网站的这里的查看更多这些操作。

看看我的其他一些文章,你可能也会喜欢读。

[## 带有完整代码片段和有用链接的 5 个最佳 Python 项目创意!

为 Python 和机器学习创建一份令人敬畏的简历的 5 个最佳项目想法的代码片段和示例!

towardsdatascience.com](/5-best-python-project-ideas-with-full-code-snippets-and-useful-links-d9dc2846a0c5) [## 人工智能是破解宇宙奥秘的关键,下面是原因!

人工智能、数据科学和深度学习的工具是否先进到足以破解人类大脑的秘密

towardsdatascience.com](/artificial-intelligence-is-the-key-to-crack-the-mysteries-of-the-universe-heres-why-56c208d35b62) [## OpenCV:用代码掌握计算机视觉基础的完全初学者指南!

包含代码的教程,用于掌握计算机视觉的所有重要概念,以及如何使用 OpenCV 实现它们

towardsdatascience.com](/opencv-complete-beginners-guide-to-master-the-basics-of-computer-vision-with-code-4a1cd0c687f9) [## 迷失在密林中:用简单的代码对机器学习中稀疏性的直觉!

为什么 ML 需要稀疏性?理解稀疏性的核心概念。

towardsdatascience.com](/lost-in-a-dense-forest-intuition-on-sparsity-in-machine-learning-with-simple-code-2b44ea7b07b0) [## 在不知道任何编码的情况下,在可教机器上免费训练机器学习模型!

不需要编码,不需要注册,没有额外的东西,只是你的浏览器。训练计算机识别您的…

medium.com](https://medium.com/illumination-curated/train-machine-learning-models-without-knowing-any-coding-for-free-on-teachable-machine-51d69657c6e5)

谢谢你们坚持到最后。我希望你们都喜欢阅读这篇文章。祝大家度过美好的一天!

自然语言处理(NLP):不要重新发明轮子

原文:https://towardsdatascience.com/natural-language-processing-nlp-dont-reinvent-the-wheel-8cf3204383dd?source=collection_archive---------22-----------------------

加速 Python NLP 项目的工具和技术

(图片由作者提供)

介绍

自然语言处理(NLP) 是一个令人生畏的领域的令人生畏的名字。从非结构化的文本中生成有用的见解是的难题,有无数的技术和算法,每一种都有自己的使用案例和复杂性。作为接触 NLP 最少的开发人员,可能很难知道使用哪些方法,以及如何实现它们。我是来帮忙的。

如果我用最少的努力提供完美的结果,你有理由怀疑。相反,使用 80/20 原则,我将向你展示如何快速(20%)交付解决方案,而不显著牺牲结果(80%)。

80/20 原则表明,少数原因、投入或努力通常会导致多数结果、产出或回报

——理查德·科赫,80/20 原则的作者

我们将如何实现这一目标?用一些奇妙的 Python 库!与其重新发明轮子,不如站在巨人的肩膀上,快速创新。通过预先测试的实现和预先训练的模型,我们将专注于应用这些方法并创造价值。

本文面向希望快速将自然语言处理集成到项目中的开发人员。强调易用性和快速结果会带来性能下降的负面影响。根据我的经验,80%的前沿技术对于项目来说已经足够了,但是在其他地方寻找 NLP 研究:)

事不宜迟,我们开始吧!

什么是 NLP?

自然语言处理是语言学、计算机科学和人工智能的一个分支,允许通过软件自动处理文本。NLP 赋予机器阅读、理解和响应杂乱无章的文本的能力。

人们通常将 NLP 视为机器学习的子集,但现实情况更加微妙。

(图片由作者提供)

有些 NLP 工具依赖于机器学习,有些甚至使用深度学习。然而,这些方法通常依赖于大型数据集,并且难以实现。相反,我们将关注更简单的、基于规则的方法来加速开发周期。

术语

从最小的数据单位开始,一个字符是一个字母、数字或标点符号。一个是字符列表,一个是单词列表。一个文档是句子列表,一个语料库是文档列表。

预处理

预处理可能是 NLP 项目中最重要的一步,它包括清理输入,以便模型可以忽略噪声,专注于最重要的部分。强大的预处理管道将提高所有型号的性能,因此我再怎么强调它的价值也不为过。

以下是一些常见的预处理步骤:

  • 分段:给定一长串字符,我们可以用空格分隔文档,用句号分隔句子,用空格分隔单词。实施细节将因数据集而异。
  • Make 小写:大写一般不加值,让字符串比较更棘手。只需将所有内容小写。
  • 删除标点符号:我们可能想要删除逗号、引号和其他不增加意思的标点符号。
  • 删除停用词:停用词是指“她”、“the”和“of”这样的词,它们不会增加文本的含义,并且会分散对更相关的关键词的注意力。
  • 删除其他:根据您的应用,您可能希望删除某些没有附加值的单词。例如,如果评估课程评论,像“教授”和“课程”这样的词可能没有用。
  • 词干化/词尾化:词干化和词尾化都会生成词根形式的屈折词(例如:“running”到“run”)。词干提取更快,但不能保证词根是英语单词。词汇化使用一个语料库来确保词根是一个单词,代价是速度。
  • 词性标注:词性标注根据定义和上下文用词性(名词、动词、介词)标注单词。比如我们可以把重点放在名词上进行关键词提取。

要更全面地了解这些概念,请查看这个令人惊叹的指南:

[## 自然语言处理实践指南(第一部分)——处理和理解文本

经过验证和测试的解决 NLP 任务的实践策略

towardsdatascience.com](/a-practitioners-guide-to-natural-language-processing-part-i-processing-understanding-text-9f4abfd13e72)

这些步骤是成功预处理管道的基础。根据您的数据集和任务,您可以跳过某些步骤或添加新步骤。通过预处理手动观察您的数据,并在出现问题时进行纠正。

Python 库

来源:python.org

让我们来看看几个领先的 Python 库。这些工具将在预处理期间,尤其是预处理之后,处理大部分繁重的提升工作

NLTK

自然语言工具包是 Python 中使用最广泛的 NLP 库。NLTK 是在 UPenn 为学术目的开发的,有大量的特性和语料库。NLTK 非常适合处理数据和运行预处理。

[## 自然语言工具包- NLTK 3.5 文档

NLTK 是构建 Python 程序来处理人类语言数据的领先平台。它提供了易于使用的…

www.nltk.org](https://www.nltk.org/)

这里有一个来自 NLTK 网站的例子,展示了对句子进行标记和词性标注是多么简单。

空间

SpaCy 是一个现代和固执己见的包。虽然 NLTK 的每个特性都有多个实现,但是 SpaCy 只保留了性能最好的实现。Spacy 支持广泛的特性,请阅读文档了解更多详细信息:

[## Python 中的 spaCy 工业级自然语言处理

spaCy 旨在帮助您做真正的工作——构建真正的产品,或收集真正的见解。图书馆尊重你的…

空间. io](https://spacy.io/)

只需几行代码,我们就可以用 SpaCy 执行命名实体识别。使用 SpaCy API 可以快速完成许多其他任务。

根西姆

与 NLTK 和 SpaCy 不同,GenSim 专门处理信息检索(IR)问题。GenSim 的开发重点是内存管理,它包含许多文档相似性模型,包括潜在语义索引、Word2Vec 和 FastText。

[## 稀有技术/基因工程

Gensim 是一个 Python 库,用于大型语料库的主题建模、文档索引和相似性检索。目标…

github.com](https://github.com/RaRe-Technologies/gensim)

下面是一个预训练的 GenSim Word2Vec 模型的示例,该模型用于查找单词相似性。不用担心那些乱七八糟的细节,我们可以很快得到结果。

还有更多…

该列表并不全面,但涵盖了一系列特性和使用案例。我建议查看这个库以获得更多的工具和参考资料。

应用程序

现在我们已经讨论了预处理方法和 Python 库,让我们用几个例子把它们放在一起。对于每一个,我将介绍几个 NLP 算法,根据我们的快速开发目标选择一个,并使用其中一个库创建一个简单的实现。

应用#1:预处理

预处理是任何 NLP 解决方案的关键部分,所以让我们看看如何使用 Python 库来加速这个过程。根据我的经验,NLTK 拥有我们需要的所有工具,并针对独特的用例进行了定制。让我们加载一个样本语料库。

按照上面定义的管道,我们可以使用 NLTK 实现分段、删除标点符号和停用词、执行词汇化等等。看看移除停用字词有多容易:

整个预处理流水线花了我不到 40 行 Python。完整代码见这里。请记住,这是一个一般化的例子,您应该根据您的具体用例的需要修改这个过程。

应用#2:文档聚类

文档聚类是自然语言处理中的一项常见任务,因此我们来讨论一些实现方法。这里的总体思路是给每个文档分配一个向量,代表所讨论的主题:

(图片由作者提供)

如果向量是二维的,我们可以像上面一样可视化文档。在这个例子中,我们看到文档 A 和 B 紧密相关,而 D 和 F 松散相关。使用距离度量,我们可以计算相似性,即使这些向量是三维、一百维或一千维的。

下一个问题是如何使用非结构化文本输入为每个文档构造这些向量。这里有几个选项,从最简单到最复杂:

  • 单词袋:给每个唯一的单词分配一个维度。给定文档的向量是每个单词出现的频率。
  • 词频—逆文档频率(TF-IDF) :根据一个单词在其他文档中的常见程度来缩放单词包表示。如果两个文档共享一个罕见的单词,那么它们比共享一个公共单词更相似。
  • 潜在语义索引(LSI) :单词包和 TF-IDF 可以创建高维向量,这使得距离度量不太准确。LSI 将这些向量压缩到更易于管理的大小,同时最大限度地减少信息丢失。
  • Word2Vec :使用神经网络,从大型文本语料库中学习单词关联。然后将每个单词的向量相加,得到一个文档向量。
  • Doc2Vec :构建在 Word2Vec 的基础上,但是使用了一种更好的方法来逼近单词向量列表中的文档向量。

Word2Vec 和 Doc2Vec 相当复杂,需要大数据集来学习单词嵌入。我们可以使用预先训练的模型,但它们可能无法很好地适应特定领域的任务。相反,我们将使用单词包、TF-IDF 和 LSI。

现在来选择我们的图书馆。GenSim 是专门为此任务构建的,包含所有三种算法的简单实现,所以让我们使用 GenSim。

对于这个例子,让我们再次使用布朗语料库。它有 15 个文本类别的文档,如“冒险”、“社论”、“新闻”等。运行 NLTK 预处理程序后,我们可以开始应用 GenSim 模型。

首先,我们创建一个将标记映射到惟一索引的字典。

接下来,我们迭代地应用单词包、术语频率—逆文档频率和潜在语义索引:

在大约 10 行 Python 代码中,我们处理了三个独立的模型,并为我们的文档提取了向量表示。利用余弦相似度进行向量比较,可以找到最相似的文档。

就这样,我们有了结果!冒险文本最类似于小说和浪漫,而社论则类似于新闻和政府。已经核实了。查看完整代码在这里

应用#3:情感分析

情感分析是将非结构化文本解释为正面、负面或中性的。情感分析是分析评论、衡量品牌、构建人工智能聊天机器人等的有用工具。

与应用预处理的文档聚类不同,我们在情感分析中不使用预处理。一篇文章的标点符号、流程和上下文可以揭示很多关于情感的东西,所以我们不想删除它们。相反,我们直接进入模型。

为了保持简单有效,我推荐使用基于模式的情感分析。通过搜索特定的关键词、句子结构和标点符号,这些模型可以测量文本的极性。这里有两个内置情感分析器的库:

VADER 情绪分析:

VADER 代表价感知词典和情感识别器,是用于情感分析的 NLTK 的扩展。它使用模式来计算情绪,尤其适用于表情符号和短信俚语。也超级容易实现。

TextBlob 情感分析:

一个类似的工具是 TextBlob,用于情感分析。TextBlob 实际上是一个类似于 NLTK 和 SpaCy 的多功能库。关于它的情感分析工具,它在报道的极性和主观性上都与 VADER 不同。从我个人的经历来说,我更喜欢 VADER,但是各有各的优缺点。TextBlob 也非常容易实现:

注意:基于模式的模型在上面例子中的小文本上表现不佳。我推荐对平均四句话的文本进行情感分析。如需快速演示,请参考Jupyter 笔记本

其他应用

这里有几个额外的主题和一些有用的算法和工具来加速您的开发。

  • 关键词提取:使用 SpaCy 的命名实体识别(NER),使用 ntlk-rake 的快速自动关键词提取(RAKE)
  • 文本摘要:使用 PyTextRank SpaCy 扩展的 TextRank(类似于 PageRank),使用 GenSim 的 TF-IDF
  • 拼写检查 : PyEnchant、SymSpell Python 端口

希望这些例子有助于展示 Python 中自然语言处理可用的大量资源。不管问题是什么,很可能有人已经开发了一个库来简化这个过程。使用这些库可以在短时间内产生很好的结果。

提示和技巧

通过对 NLP 的介绍、对 Python 库的概述和一些示例应用程序,您几乎已经准备好应对自己的挑战了。最后,我有一些技巧和诀窍来充分利用这些资源。

  • Python 工具:我推荐诗歌用于依赖管理,Jupyter Notebook 用于测试新模型,Black 和/或 Flake8 用于林挺,GitHub 用于版本管理。
  • 保持条理:从一个库跳到另一个库很容易,复制代码来测试十几个想法。相反,我推荐一种更有分寸的方法。你不想在匆忙中错过一个很好的解决方案。
  • 预处理:垃圾进,垃圾出。实现一个强大的预处理管道来清理你的输入是非常重要的。目视检查处理后的文本,以确保一切按预期运行。
  • 展示结果:选择如何展示你的结果会有很大的不同。如果输出的文本看起来有点粗糙,可以考虑显示聚合统计数据或数字结果。

现在你应该已经准备好处理一些现实世界的 NLP 项目了。祝你好运,并快乐编码:)

如果你用这些信息做了什么酷的事情,请在评论中留下你的回复。如有任何反馈或见解,欢迎随时联系我LinkedIn。感谢阅读!

面向初学者的自然语言处理

原文:https://towardsdatascience.com/natural-language-processing-nlp-for-beginners-6d19f3eedfea?source=collection_archive---------13-----------------------

使用 Python 的 NLP 循序渐进初学者指南

Bram Naus 在 Unsplash 上拍摄的照片

在这篇文章中,我将向你介绍一个最著名的人工智能领域,叫做自然语言处理。介绍结束后,我将带您完成一个动手练习,我们将从一个特定的网站中提取一些有价值的信息。对于动手项目,我们将使用一个名为 NLTK(自然语言工具包)的特定 NLP 模块,这将在简介部分之后介绍。读完这篇文章后,您将对自然语言处理应用程序及其工作原理有更好的理解。抓紧时间,让我们开始吧!

目录

  • 简介
  • 【自然语言工具包】
  • BS4(美汤 4)
  • 第一步——导入库
  • 第二步—阅读页面
  • 第三步—数据清理
  • 第四步——标记化
  • 第五步—数据可视化
  • 视频演示

介绍

自然语言是指我们在日常生活中使用的语言。这个领域已经存在很长时间了,但是随着计算机科学和编程的发展,关于这个领域的人工智能相关研究已经增加。互联网改变了我们的生活方式,以及我们相互交流的方式。例如,我们开始使用文本消息、电子邮件、语音消息等,而不是发送纸质邮件和信件。你可以通过在网上做一些研究来了解这个领域。

为了让你更好地了解自然语言处理如何被用于机器学习和人工智能领域,我想与你分享一些现实生活中的应用:

  • Google 翻译:Google Translate 背后的机器智能理解单词,并逐字翻译成你想要的语言。它在翻译时不会丢失句子的意思。
  • 语法上:这项服务背后的机器智能擅长语法和单词。这是语言处理在过去几年中如何发展的一个很好的例子。它检查句子的语法,甚至给出一些如何提高文章质量的建议。
  • 语音助手:这个领域也是语言处理进步很大的大部分领域。语音识别技术主要用于文字处理。目前,最知名的是苹果 Siri、谷歌助手和亚马逊 Alexa。
  • 聊天机器人:另一个语言处理的好例子是聊天机器人。他们非常像虚拟助理,但有更具体的目标。它们最常用于客户访问的网站。他们帮助你获得你需要的信息,而不需要和任何真实的人交谈。首先,他们试图理解你的需求,然后把结果呈现在你面前。
  • Web 抓取: Web 抓取是语言处理常用的另一个领域。它用于从网页中提取信息,甚至不需要花费时间一段一段地复制。网络抓取是收集有价值的数据和训练机器学习模型的一种很好的方式。网页抓取也是一个非常有用的工具,当工作与搜索引擎优化。

自然语言工具包

NLTK 是构建 Python 程序来处理人类语言数据的领先平台。它提供了 50 多个语料库和词汇资源(如 WordNet)的易用接口,以及一套用于分类、标记化、词干化、标记、解析和语义推理的文本处理库,以及工业级 NLP 库的包装器。

参考:http://www.nltk.org

我们必须安装 NLTK 模块,以便我们可以在我们的项目中使用它。在您的终端中运行以下代码将为您完成安装:

pip install nltk

美丽的汤 4

Beautiful Soup 是一个 Python 库,用于从 HTML、XML 和其他标记语言中获取数据。Beautiful Soup 帮助您从网页中提取特定内容,删除 HTML 标记,并保存信息。它是一个网络抓取工具,可以帮助你清理和解析从网上下载的文档。

参考:https://programminghistorian . org/en/lessons/intro-to-beautiful-soup

现在,让我们使用 pip 安装最新版本的漂亮汤库:

pip install beautifulsoup4

步骤 1-导入库

库安装完成后,我们就可以开始编程了。为了这个项目,我将使用 Jupyter 笔记本。好的,首先,让我们将库导入笔记本。

import nltk

from nltk.corpus import stopwordsfrom bs4 import BeautifulSoupimport urllib.requestimport plotly.io as pio

步骤 2 —阅读页面

在这一步中,我们将使用 urllib 请求方法打开网页。打开后,我们会读取网页的全部代码。如你所知,网页有一个代码在后台运行。你可以在任何网页上点击右键,然后点击“inspect element”来了解代码。

我选择了维基百科关于自然语言处理的页面。

page =  urllib.request.urlopen('[https://en.wikipedia.org/wiki/Natural_language_processing'](https://en.wikipedia.org/wiki/Natural_language_processing'))html_plain = page.read()print(html_plain)

这是我们打印普通 html 代码时的样子:

html 代码

步骤 3 —数据清理

从截图中可以看出,普通的 html 代码需要一些清理。BeautifulSoup 将在这个数据清理过程中帮助我们。我们必须去掉许多不必要的字符,比如双引号、斜线、大于号和小于号等等。别担心,它还会清理 HTML 语法单词😊

运行以下几行来看看 BS4(美人汤 4)的神奇力量:

soup = BeautifulSoup(html_plain,'html.parser')soup_text = soup.get_text(strip = True)

太好了!在我们拆分单词之前还有一件事:为了提高处理的质量,我建议所有的字符都小写。当我们开始计算单词的频率时,这将是有帮助的。否则,由于 Ascii 值不同,机器会将“自然”和“自然”视为不同的单词。

ready_text = soup_text.lower()print(ready_text)

看起来好多了!现在,让我们进入下一步,将每个单词拆分成一个列表项。这个过程被称为标记化。

步骤 4 —标记化

在处理自然语言处理项目时,这一步至关重要。首先,我们将通过将每个单词分成列表项来对它们进行标记。之后,我们会做一些单词清理。NLTK(自然语言工具包)将用来清除停用词。这将给我们留下关键词,让我们对网页有更好的了解。这样我们就不算停用词了,比如 a,and,of,that,the,with 等

tokens = []
for t in ready_text.split():
    tokens.append(t)print(tokens)

#Run this line if you get an error message in the next code block
nltk.download()

现在,让我们清除令牌列表中的停用词。

stop_words = stopwords.words('english')
clean_tokens = tokens[:]for token in tokens:
    if token in stop_words:
        clean_tokens.remove(token)print(clean_tokens)

清理的令牌

步骤 5 —数据可视化

在这一步中,首先我们将统计标记的频率,然后我们将过滤高频标记。过滤后,就该可视化自然语言处理维基百科页面中最常用的词了。视觉化将帮助我们按照它们的频率顺序来看它们。

让我们用 NLTK 的 FreqDist 函数来计算单词的频率。

freq = nltk.FreqDist(clean_tokens)for key, val in freq.items():
    print('Word: ' + str(key) + ', Quantity:' + str(val))

代币数量

现在,我们将定义一个新的字典,并获取页面中使用次数超过 10 次的标记。这些关键词比其他关键词更有价值:

high_freq = dict()
for key, val in freq.items():
    if (val > 10):
        high_freq[key] = val

完美!现在我们有了一本叫做高频的新词典。让我们进入最后一步,创建一个条形图。我认为条形图用定量数据表示会更好。我还按照降序排列,所以出现频率最高的单词排在最前面。以下是可视化代码:

#Note: to pass keys and values of *high_freq* dictionary, I had to convert them to list when passing themfig = dict({
    "data": [{"type": "bar",
              "x": list(high_freq.keys()),
              "y": list(high_freq.values())}],
    "layout": {"title": {"text": "Most frequently used words in the page"}, "xaxis": {"categoryorder":"total descending"}}
})pio.show(fig)

plotly 条形图

视频演示

恭喜你。!您已经创建了一个程序来检测页面中的关键字。现在,不用阅读整个页面,你仍然可以使用自然语言处理对页面有所了解。希望你喜欢阅读这个实践指南。如果你今天学到了新东西,我会很高兴。从事像这样的动手编程项目是提高编码技能的最好方式。如果您在执行代码时有任何问题,请随时联系我

关注我的博客youtube 频道,保持灵感。谢谢你,

[## 用 Python 构建人脸识别器

使用 OpenCv 库进行实时人脸识别的分步指南

towardsdatascience.com](/building-a-face-recognizer-in-python-7fd6630c6340) [## 使用 Python 从视频中提取语音

使用 Google 语音识别 API 的简单实用项目

towardsdatascience.com](/extracting-speech-from-video-using-python-f0ec7e312d38)

自然语言处理与空间——阿瑟·柯南·道尔和阿加莎·克里斯蒂的写作风格分析

原文:https://towardsdatascience.com/natural-language-processing-nlp-with-nltk-and-spacy-sir-arthur-conan-doyle-and-agatha-christies-d3ba967bd666?source=collection_archive---------35-----------------------

内部 AI

在本文中,我将对阿瑟·柯南·道尔的《巴斯克维尔的猎犬》和阿加莎·克里斯蒂的《林克斯谋杀案》进行对比分析。

马库斯·温克勒Unsplash 上拍摄

我相信我们都喜欢读著名侦探夏洛克·福尔摩斯和赫丘里·波罗写的经久不衰的惊险侦探小说。作为一名数据科学家,我很好奇亚瑟·柯南道尔和阿加莎·克里斯蒂的写作风格有没有相似之处。如果我能在自然语言处理(NLP)的帮助下,从成功的侦探小说写作食谱中提取任何见解,那就太好了。

目标

在本文中,我将对阿瑟·柯南·道尔的《巴斯克维尔的猎犬》和阿加莎·克里斯蒂的《林克斯谋杀案》进行对比分析。

在我的完整分析中,我考虑了每个作者的十个故事来进行比较,但是为了简单起见,我在本文中用每个作者的一个故事来解释这个过程。下面提到的框架和代码很容易扩展,我强烈建议你们都来试试亚瑟·柯南·道尔爵士和阿加莎·克里斯蒂的全套故事。

主要目的是展示使用 NTLK 和 spaCY 之类的包来执行自然语言处理(NLP)是多么容易,并提供一个初始框架结构来自我探索和深入研究其他作者的作品。

入门

我已经下载了亚瑟·柯南·道尔爵士的《巴斯克维尔的猎犬》和阿加莎·克里斯蒂的《链接上的谋杀》的文本版本。

我使用了“ en_core_web_lg ”通用预训练模型来预测命名实体、词性标签和句法依赖。

spaCY 提供三种尺寸的预训练模型,即小型、中型和大型,规模越来越大,预测越来越准确。

作为先决条件,我们需要用下面的命令下载大模型。

python -m spacy download en_core_web_lg

步骤 1: 我们将使用 NLP 包 NLTK 和 spaCy 进行分析。首先,导入所有需要的包,并通过加载预先训练的模型“en_core_web_lg”来创建 NLP 对象。顾名思义,Matcher 包将有助于执行基于模式的搜索,并将在本文后面详细讨论。

import spacy
from spacy.matcher import Matcher
nlp = spacy.load("en_core_web_lg")
matcher = Matcher(nlp.vocab)

第二步: 在下面的代码中,读取从项目古腾堡下载的“巴斯克维尔的猎犬”“链接上的谋杀”的文本文件。

Sherlock= open("Sherlock.txt", "r")
Poirot= open("Poirot.txt", "r")

第三步: 我们想知道两个故事中名词、动词和句子的数量。我们将编写一个小的自定义管道组件,它可以添加到标准的开箱即用管道中来获取这些信息。

在主程序中(后面会解释),我们会把全文分成单个单词 token。在下面的代码中,我们检查 token 的词类是名词还是动词,并根据测试增加相应的计数器。

此外,我们正在使用 spaCY 中的标准 doc.sents 方法计算文本中的句子数量。

def length(doc):
    nou=0
    ver=0
    sentence=0
    for token in doc:
        if token.pos_=="NOUN":
            nou=nou+1 
        elif token.pos_=="VERB":
            ver=ver+1
    print("Number of Verbs in the text = ",ver)
    print("Number of Nouns in the text = ",nou)for sent in doc.sents:
       sentence=sentence+1
    print("Number of Sentences in the text = ",sentence)
    return doc

第四步: 我们将使用 add_pipeline 方法将自定义管道组件“长度”添加到标准空间管道中。

nlp.add_pipe(length)

第五步: 在下面的代码中,我们通过第二步读取的文本来创建 doc 对象,Arthur 和 Agatha。创建 doc 对象时,在后台按顺序执行一组操作,doc 对象是带有语言注释的单词序列。

Arthur=nlp(Sherlock.read())
Agatha=nlp(Poirot.read())

它从标记化开始,然后是标记、解析等。如下图。我们在最后加入了自定义管道来统计名词、动词和句子。

作者绘制的图像

对于本文的范围,我们感兴趣的是我们在步骤 3 中编写的最后一个定制管道操作的输出。

“巴斯克维尔的猎犬”中的动词、名词和句子数量的自定义管道输出

自定义管道输出与一些动词,名词和句子在“谋杀的联系”

基于程序输出的词性分析

第六步: 接下来,我们来分析一下主角侦探福尔摩斯和波洛采取任何行动的次数。作为一个近似的解决方案,我们需要寻找侦探的名字后面跟一个动词的模式。

在下面的代码中,我们定义了一个模式 holmes_pattern,用于查找紧跟动词的“holmes”的出现次数。

Add 方法用于将模式包含到匹配器中。最后,doc 对象即被传递给匹配器,以收集文本中与后跟动词的 holmes 模式匹配的所有实例。

matcher = Matcher(nlp.vocab)
holmes_pattern = [{"TEXT": "Holmes"}, {"POS": "VERB"}]matcher.add("Action", None, holmes_pattern )
matches = matcher(Arthur)
print("Sherlock Acted:", len(matches))

匹配的长度给出了在文本中找到模式匹配的次数。

如果我们循环匹配对象,如下面的代码所示,那么我们可以打印单独的模式匹配文本

for match_id, start, end in matches:
    print("Sherlock Action Found:", Arthur[start:end].text)

程序输出

阿加莎·克里斯蒂的小说《链接上的谋杀》中的侦探波洛也有类似的逻辑

poirot_pattern = [{"TEXT": "Poirot"}, {"POS": "VERB"}]
matcher.add("Action", None, poirot_pattern )
matches = matcher(Agatha)
print("Poirot Acted:", len(matches))for match_id, start, end in matches:
    print("Hercule Action found:", Agatha[start:end].text)

程序输出

看来波洛比夏洛克·福尔摩斯活跃多了:-)

第七步: 接下来,我们会看到在各自的故事中,有多少次主角侦探和他的副手的名字被描述。

我们之前了解到,在标记化过程中,每个单词都被分离和分类。我们将比较每个令牌的文本,以计算夏洛克、华生、波洛和黑斯廷斯在各自故事中的实例。

sherlock_count=0
watson_count=0
for token in Arthur:
    if token.text == "Sherlock":
        sherlock_count=sherlock_count+1
    elif token.text == "Watson":
        watson_count=watson_count+1print(sherlock_count)
print(watson_count)

poirot_count=0
hasting_count=0
for token in Arthur:
    if token.text == "Poirot":
        poirot_count=sherlock_count+1
    elif token.text == "Hastings":
        hasting_count=watson_count+1print(poirot_count)
print(hasting_count)

程序输出的图表

第八步: 最后,我们会看到每个作者在故事中使用频率最高的 15 个词。我们将使用 NLTK 模型进行分析,并绘制一个累积图。

from nltk import *Arthur_plot = FreqDist(Sherlock)
Arthur_plot .plot(15, cumulative=True)

在上面的代码中,我们将文本传递给 NLTK 的 FreqDist 内置函数,然后使用 plot 方法绘制最常用单词的累积图表。我们可以看到《巴斯克维尔的猎犬》中 15 个最常用的单词加起来接近 1700 个单词。

《巴斯克维尔的猎犬》中最常用词汇的累积图表

我们对阿加莎·克里斯蒂的小说《链接上的谋杀》做了同样的分析。

Agatha_plot = FreqDist(Poirot)
Agatha_plot .plot(15, cumulative=True)

“链接上的谋杀”中最常用词的累积图表

我们已经讨论了很多领域,所以为了快速回顾一下,我们从分析每个故事中动词、名词和句子的数量开始。作为一个自我探索的练习,我建议你扩展形容词、介词等的词性分析。以获得更好的洞察力。

我们进一步学习了使用模式搜索,并发现了前导字符名称后面跟一个动词的次数。接下来,我们分析了探长和他的同事的名字在各自的故事中被提及的次数。我们用故事中最常用的 15 个词来结束我们的分析。

正如在开始时提到的,本文旨在展示使用 NTLK 和 spaCY 这样的包来执行自然语言处理(NLP)是多么容易,并提供一个初步的框架结构来自我探索和深入研究其他作者的作品。

自然语言处理流水线解码!

原文:https://towardsdatascience.com/natural-language-processing-pipeline-decoded-f97a4da5dbb7?source=collection_archive---------34-----------------------

来源

自然语言是我们书写、说话和理解的语言。世界上几乎所有已知的语言都属于自然语言的范畴。自然语言处理是处理语言的书面形式并使计算机理解它们的任务。

让我们来谈谈为了让自然语言机器或深度学习模型做好准备所需的一些非常基本的任务。

句子分割

转换成小写

词语的标记化

删除标点符号、特殊字符和停用词

词汇化/词干化

创建单词袋模型/ TF-IDF 模型

下面就一个一个说吧。

句子分割 是一个众所周知的文本分割子任务。文本分割基本上是将给定的文本分成逻辑上可理解的信息单元。一个这样的逻辑单元的例子是句子。因此,将给定文本划分成句子的任务被称为句子分割。这项任务是处理文本的第一步。将包含大量文本的文档分成句子有助于我们逐句处理文档,从而不会丢失它们可能包含的重要信息。

请注意,句子分割取决于文档的性质和文档遵循的句子边界的类型。例如,在一个文档中,文本可以根据“.”分成句子而在另一个文档中,文本可以根据换行符或“\n”来划分。因此,在进行句子分割之前,查看您的文档并在尝试句子分割之前找到合理的句子边界是非常重要的。

句子分割插图

上图展示了一个例子,说明了 spacy 如何通过使用句号将给定文本分成两个句子来帮助执行句子分割。

下一个任务通常是 将所有句子转换成小写 。在你不想根据大小写来区分单词的问题中,这是很重要的。例如,如果您的任务是分类,那么“Run”“Run”是相同的单词,不应该被您的模型视为两个不同的单词。

转换成小写插图

一个很好的反例是命名实体识别问题(NER),在这种情况下,转换为小写可能会导致重要信息的丢失。如果一个句子中的所有单词都被转换成小写字母,那么对系统来说,识别命名实体就变得更加困难。如果所有单词都转换成小写,即使像 spacy 等库也无法识别准确的命名实体。因此,在尝试将文档中的所有单词小写之前,理解问题的细微差别是非常重要的。

下一个要理解的任务是 单词标记化 。标记化是把一个句子分成单词的过程。这样做是为了让我们能够理解(语料库的)每个句子中包含的句法和语义信息。因此,我们通过逐字分析来破译句子的相关性,从而确保没有信息丢失。可以基于不同的试探法或单词边界(如空格、制表符等)来执行句子的标记化。一个这样的例子如下所示。

文字插图的符号化

如您所见,spacy 检测单词边界并帮助标记给定的文本。

接下来,我们 去掉标点符号 以确保我们没有“,”,”等等在我们的令牌列表中。这在几个问题类型中很重要,因为在使用机器或深度学习算法处理自然语言时,我们通常不关心标点符号。因此,移除它们似乎是明智之举。你可以通过遍历你的标记列表来删除标点符号,也可以从一开始就把它们从每个句子中删除。后者如下所示。

标点符号移除插图

下一步通常是 去掉特殊字符 比如*"!@#$%^&**来自令牌化后接收到的令牌列表。这是根据需要完成的,并且高度依赖于您试图解决的问题类型。例如,你可以尝试在给定的语料库中检测推文,删除像 '@' 这样的特殊字符可能对你的努力没有帮助,因为人们通常在推文中使用 '@' 。下面显示的是一个代码片段,如果您的问题需要,它可以帮助您从句子中删除任何特殊字符(使用 python: re 的 regex 库)。

特殊字符删除说明

另一个重要步骤是 去除停用词停用词是任何语言中最常见的词。为了方便起见,让我们假设英语是我们的主要语言。一些最常见的停用词有、【in】、【and】、【a】、等。这是重要的一步,因为你不希望你的模型在没有任何意义的单词上浪费时间,停用词本身几乎不包含任何意义。它们可以很容易地从一个句子或一列标记中删除,而不会导致太多的信息损失,从而加快模型的训练过程。因此,在尝试训练模型之前删除它们几乎总是一个好主意。

给出的图像显示了如何使用 nltk 来完成这一操作。

停用字词删除图示

下一个任务通常是 词汇化和/或词干化 。这两个过程都涉及到单词的规范化,因此只有单词的基本形式保留下来,从而保持了完整的意思,但删除了所有的屈折词尾。这是一个重要的步骤,因为你不希望你的模型把像“running”“run”这样的单词当作单独的单词。

词汇化使用形态分析和词汇来识别基本单词形式(或词汇),而词干化通常砍掉词尾,如、【ing】、【s】、等,希望找到基本单词。下图显示了两者的区别。

词汇化 v/s 词干插图

正如你所看到的,上图中的 lemmatizer 正确地识别出单词【语料库】有基础形式【语料库】,而斯特梅尔没有检测到这一点。但是,词干分析器正确地将【rock】识别为【rocking】的基本形式。因此,使用词汇化或词干化,或者两者都用,很大程度上取决于您的问题需求。

既然我们已经讨论了处理文本数据所必需的基本思想,那么让我们来谈谈如何将文本转换成机器可学习的形式。一种这样的技术是创建 单词袋模型 。单词包只是简单地计算文本中出现的所有单词的数量。

单词袋模型插图

上面给出的代码首先获取一个包含 4 个句子的语料库。然后它使用 sklearn 的计数矢量器创建一个单词包模型。换句话说,它创建了一个模型,其中包含关于语料库中每个唯一单词在每个句子中出现多少次的信息(我们使用矢量器. get_feature_names() )。为了方便起见,我增加了一列【句子】,帮助我们理解哪个计数值对应哪个句子。此外,代码中的最后一行创建了一个 "bow.csv" 文件,该文件包含与所有单词对应的所有上述计数,如下所示。

单词袋模型插图

另一个这样的模型叫做 词频逆文档频率(TF-IDF)模型。 该模型在词频(TF)和逆文档频率(IDF)之间找到一个折衷。词频是每个词在给定文本语料库或文档中出现的次数(如词袋模型图所示)。逆文档频率是单词在语料库中的文档中出现的次数的倒数。换句话说,术语频率发现一个单词有多常见,逆文档频率发现一个单词有多罕见。

现在,让我们看看如何在 python 中实现它。

TF-IDF 插图

上面给出的代码首先获取一个包含 4 个句子的语料库。然后,它使用 sklearn 的 TF IDF 矢量器创建一个包含 TF-IDF 值的 TF-IDF 模型。代码还创建了一个文件“tfi df . CSV”,其中包含了语料库中的唯一单词,作为列,以及它们对应的 TF-IDF 值,作为行,以帮助理解模型创建背后的思想。它创建的文件类型的一个例子如下所示。

TF-IDF 模型图

现在,您可以使用这些模型中的任何一个作为文本分类、情感分析等问题的训练数据。现在您已经理解了处理文本数据的基础,您已经准备好开始您的第一个项目了!

这篇文章的全部代码可以在 这里 找到。请注意,jupyter 笔记本中的每个单元格都可以独立运行(由于单元格特定的导入语句,为了方便起见),您可能希望将代码顶部的所有内容只导入一次,而不是多次导入!

我希望这篇文章能帮助你理解如何使用自然语言,并有朝一日开始你掌握自然语言处理的旅程!

感谢您的阅读!

附言:如果你有任何问题,或者你想让我写任何特定的话题,请在下面评论。

参考文献:

  1. 语音和语言处理,第三版,作者丹·茹拉夫斯基詹姆斯·h·马丁
  2. sk learn:https://scikit-learn.org/stable/
  3. 空间:https://spacy.io/
  4. NLTK:https://www.nltk.org/

自然语言处理:变形金刚的时代

原文:https://towardsdatascience.com/natural-language-processing-the-age-of-transformers-a36c0265937d?source=collection_archive---------39-----------------------

自然语言处理深度学习简史

在最近的过去,如果你专门研究自然语言处理(NLP),可能会有一些时候你会有点嫉妒你在计算机视觉领域工作的同事。看起来他们似乎拥有所有的乐趣:一年一度的 ImageNet 分类挑战赛神经类型转移生殖对抗网络,仅举几例。最后,干旱期结束了,NLP 革命正在进行中!公平地说,转折点是 2017 年,当时谷歌的 论文中引入了 Transformer network,注意力是你所需要的全部 。从那以后,多项进一步的进展接踵而至,其中最重要的一项是伯特。

为了给 Transformer 的讨论打下基础,让我们从一个常见的 NLP 任务类别开始:序列到序列(seq2seq) 问题。它们就像它们的名字所暗示的那样:seq2seq 任务的输入和输出都是序列。在 NLP 环境中,通常会有一些额外的限制:

  • 序列的元素是对应于某个集合词汇的标记(通常包括一个用于词汇外单词的未知标记)
  • 序列中的顺序关系到

接下来,我们将花点时间来缅怀那些逝去的英雄,没有他们,我们就不会有今天的成就。当然,我指的是 RNNs——递归神经网络,这是一个在深度学习领域几乎成为 NLP 同义词的概念。

1.变形金刚的前身:RNN 编码器-解码器

这个故事将我们一路带回到 2014 年( Ref ,另一个 Ref ),当时通过两个递归神经网络结合成一个编码器-解码器模型来处理 seq2seq 问题的想法诞生了。让我们用机器翻译任务中的一个简单例子来演示这个架构。举一个法英句子对,输入为“我是学生”,输出为“我是学生”。首先, "je" (或者,最有可能的是,一个嵌入了代表 "je" 的标记的字),通常伴随着一个常量向量 h_E0 ,该向量可以是已学习的或固定的,被送入编码器 RNN。这产生了输出向量 h_E1 (隐藏状态 1),它与输入序列“suis”中的第二个元素一起作为编码器 RNN 的下一个输入。该操作的输出、 h_E2“étudiant”再次被馈入编码器,产生该训练样本的最后一个编码的隐藏状态、 h_E3 。h_E3 向量依赖于输入序列中的所有记号,所以它应该代表整个短语的意思。为此,它也被称为上下文向量上下文向量是解码器 RNN 的第一个输入,然后它将生成输出序列“I”的第一个元素(实际上,解码器的最后一层通常是 softmax ,但为了简单起见,我们可以只保留每个解码器步骤末尾最可能的元素)。此外,解码器 RNN 产生隐藏状态 h_D1 。我们将 h_D1 和先前的输出“I”反馈回解码器,希望得到“am”作为我们的第二输出。这个生成输出并将输出反馈到解码器的过程一直持续到我们产生一个 < EOS > —句子标记的结尾,这表示我们的工作已经完成。

RNN 编码器-解码器模型在运行。为了避免混淆,我想请你注意一些事情。多个 RNN 块出现在图中,因为序列的多个元素被馈入网络/由网络生成,但是不要搞错,这里只有一个编码器 RNN 和一个解码器 RNN 在起作用。这可能有助于将重复的块视为不同时间步长的相同 RNN,或者视为具有共享权重的多个 rnn,它们一个接一个地被激活。资料来源:OP

这种架构可能看起来很简单(特别是在我们坐下来实际编写代码并加入了 LSTMsGRUs 之前),但事实证明它对许多 NLP 任务非常有效。事实上,自 2016 年以来,谷歌翻译一直在使用它。然而,RNN 编码器-解码器模型确实存在某些缺点:

1a。RNNs 的第一个问题:关注救援

如上所述的 RNN 方法对于较长的句子并不特别有效。想想看:整个输入序列的含义预计将由一个具有固定维度的单个上下文向量捕获。这对于 "Je suis étudiant" 来说已经足够好了,但是如果您的输入看起来更像这样呢:

“是一个错误的电话号码引起的,夜深人静的时候电话铃响了三次,电话那头的声音在问一个不是他的人。”

编码成上下文向量!然而,事实证明有一个解决方案,被称为注意力机制

注意(左)传统 RNN 编码器-解码器和(右)RNN 编码器-解码器的示意图。资料来源:OP

注意力背后的基本思想很简单:我们不是只将最后一个隐藏状态(上下文向量传递给解码器,而是将来自编码器的所有隐藏状态传递给解码器。在我们的例子中,这将意味着 h_E1h_E2h_E3 。解码器将通过 softmax 层确定他们中的哪一个得到关注(即,关注哪里)。除了增加这个额外的结构之外,基本的 RNN 编码器-解码器架构保持不变,然而当涉及到更长的输入序列时,所得到的模型表现得更好。

1b。复发性 NNs 的第二个问题:他们是(惊喜!)经常性

困扰 RNNs 的另一个问题与名称中的 R 有关:根据定义,递归神经网络中的计算是顺序的。这种财产意味着什么?顺序计算不能并行化,因为我们必须等待上一步完成后才能进入下一步。这既延长了训练时间,也延长了运行推理的时间。

解决顺序困境的方法之一是使用卷积神经网络(CNN)而不是 RNNs。这种方法已经取得了成功,直到被超越

阿瑟尼·托古列夫Unsplash 上的照片

2.关注是你所需要的一切谷歌,2017

论文中介绍了 Transformer 架构,其标题配得上一本自助书籍的标题: 注意力是你所需要的全部 。再次,另一个自我描述的标题:作者字面上关注 RNN 编码器-解码器模型,并扔掉 RNN。你需要的只是关注!实际上,它要比这个复杂得多,但这是基本前提。

这是如何工作的?首先,输入序列 w_i 的每个预处理(稍后详述)元素作为输入馈入编码器网络——这是并行完成的,与 RNNs 不同。编码器有多层(例如在原始变压器纸中,它们的数量是六层)。让我们使用 h_i 来标记每个 w_i 的最后一个编码器层的最终隐藏状态。解码器也包含多个层,通常数量与编码器的数量相等。所有隐藏状态 h_i 现在将作为输入馈送到解码器的六层中的每一层中。如果这看起来对你来说很熟悉,那是有原因的:这是变形金刚的编码器-解码器注意力,它在精神上与我们上面讨论的注意力机制非常相似。在我们继续讨论如何实现变压器的注意力之前,让我们讨论一下预处理层(在编码器和解码器中都存在,我们将在后面看到)。

预处理有两个部分:首先,有我们熟悉的嵌入了的单词,这是大多数现代 NLP 模型中的主要部分。这些单词嵌入可以在训练期间学习,或者可以使用现有的预训练嵌入之一。然而,还有一个特定于变压器架构的部分。到目前为止,我们还没有提供任何关于序列中元素的顺序的信息。在没有顺序 RNN 架构的情况下,如何做到这一点呢?好了,我们有了位置,让我们把它们编码到向量中,就像我们用单词嵌入来嵌入单词记号的意思一样。产生的经过后处理的向量携带了单词的含义及其在句子中的位置的信息,被传递到编码器和解码器层。

具有两层的编码器,并行处理三元素输入序列(w1、w2 和 w3)。每个输入元素的编码器还通过其自我关注子层接收关于其他元素的信息,允许捕捉句子中单词之间的关系。资料来源:OP

2a。注意,线性代数的前景

我来自量子物理学背景,在这里向量是一个人最好的朋友(有时,真的是这样),但是如果你更喜欢注意力机制的非线性代数解释,我强烈推荐看看 Jay Alammar 的插图变压器

让我们用 X 来标记注意力层输入的向量空间。我们在训练中想要学习的是三个嵌入矩阵, WᴷW ⱽ和 Wᴬ ,它们将允许我们从 X 到三个新的空间: K (键)、 V (值)和 Q (查询)。恼人的是,“Q”没有下标(真人真事!),所以我求助于 Wᴬ ,其中“a”代表“问”。以下是我们目前掌握的情况:

K = X Wᴷ

Q = X Wᴬ

这些嵌入向量随后在编码器-解码器注意力中使用的方式如下。我们从解码器获取一个 Q 向量(一个查询,也就是说,我们指定我们想要关注的信息种类)。此外,我们将向量 V ( )视为类似于来自编码器的向量 X 的线性组合(然而,不要从字面上理解“线性组合”,因为 XV 的维数通常是不同的)。向量 K 也取自编码器:每个kⁿ索引由值 Vⁿ 捕获的信息种类。

为了确定哪些值应该得到最多的关注,我们取解码器的查询 Q 与编码器的所有键 K 的点积。结果的 softmax 会给出各个值的权重 V (权重越大,关注度越大)。这种机制被称为点积注意,由以下公式给出:

其中可以任选地将 QK 的点积除以关键向量 d_k 的维度。为了给你一个在实践中使用的维度的概念,在 中介绍的变形金刚d_q=d_k=d_v=64 而我所说的 X 是 512 维的。

2b。新鲜事:自我关注

除了编码器-解码器关注,变压器架构还包括编码器自关注解码器自关注。这些都是以与上面讨论的相同的点积方式计算的,有一个关键的区别:对于自我关注,所有三种类型的向量( KVQ )来自同一个网络。这也意味着所有三个都与相同序列的元素相关联(编码器的输入和解码器的输出)。引入自我注意的目的是学习句子中不同单词之间的关系(这个功能过去由顺序 RNN 来完成)。一种方法是将序列中的每个元素表示为序列中其他元素的加权和。何必呢?考虑以下两个短语:

1。 动物 没有过马路是因为 太累了。

2。这只动物没有穿过 马路 是因为 马路 太宽了。

显然, it 与第一个短语中的动物和第二个短语中的道路关系最为密切:如果我们使用单向正向 RNN,这些信息将会丢失!事实上,编码器自我关注,设计上是双向的,是 BERT 的关键部分,这是预先训练的上下文单词嵌入,我在这里讨论过。

在哪里进行编码器自关注的计算?事实证明,在每个编码器层中。这允许网络在不同的抽象级别关注输入序列的相关部分:较低编码器层的值 V 将最接近原始输入标记,而较深层的自我关注将涉及更抽象的构造。

2c。把所有的放在一起

到目前为止,我们已经确定,转换器放弃了 rnn 的顺序性质,而是并行处理序列元素。我们看到了编码器自关注如何允许输入序列的元素被单独处理,同时保留彼此的上下文,而编码器-解码器关注将它们全部传递到下一步:用解码器生成输出序列。这一阶段发生的事情可能还不太清楚。如您所知,RNN 编码器-解码器一次生成一个元素的输出序列。先前产生的输出在随后的时间步长馈入解码器。变形金刚真的能找到一种方法让我们从这个过程的顺序性中解放出来,并以某种方式一次生成整个输出序列吗?嗯——是也不是。更准确地说,在训练时答案是[大致]是,在推理时答案是“否”。

该变压器结构具有双层编码器/解码器的特征。编码器并行处理输入序列的所有三个元素(w1、w2 和 w3),而解码器顺序生成每个元素(仅描述了生成输出序列元素 v1 和 v2 的时间步长 0 和 1)。输出标记生成继续,直到出现句子标记的结尾。资料来源:OP

解码器的输入有两种类型:作为编码器输出的隐藏状态(这些用于每个解码器层内的编码器-解码器注意)和输出序列的先前生成的令牌(用于解码器自我注意,也在每个解码器层计算)。因为在训练阶段,输出序列已经可用,所以可以通过屏蔽(用零替换)“先前生成的”输出序列的适当部分来并行执行解码过程的所有不同时间步长。这种屏蔽导致解码器自关注是单向的,与编码器相反。最后,在推理时,输出元素按顺序一个接一个地生成。

今天结束前的最后一句话:

在上图中,我称为后处理的解码器部分类似于人们通常在 NLP 任务的 RNN 解码器中找到的部分:完全连接(FC)层,它遵循从网络输入中提取某些特征的 RNN,以及 FC 层之上的 softmax 层,它将为模型词汇表中的每个令牌分配概率,作为输出序列中的下一个元素。此时,我们可以使用波束搜索算法来保留每一步的前几个预测,并在最后选择最有可能的输出序列,或者每次只保留顶部的选择。

变压器架构是 NLP 领域许多最新突破背后的驱动力..由阿瑟尼·托古列夫Unsplash 上拍摄的照片

本文的一个版本于 2019 年 8 月 22 日首次发表于 Scaleway 的博客

Scaleway 智能标注是一个托管数据注释平台,可帮助您标注计算机视觉(2021)和 NLP (2022)项目所需的数据!借助我们路线图中的自动预标记和主动学习功能,您的数据集将很快准备就绪。注册以便在智能标签可用时获得通知!

用 PySpark 和 Spark-NLP 进行自然语言处理

原文:https://towardsdatascience.com/natural-language-processing-with-pyspark-and-spark-nlp-b5b29f8faba?source=collection_archive---------7-----------------------

深入阅读金融服务消费者投诉文本

当我们深入挖掘客户投诉时,寻找宁静。汤姆·盖诺尔在 Unsplash 上的照片

问题:哪些词(来自抱怨)明显是对等的?

今天,我们深入美国消费者金融保护局的金融服务消费者投诉数据库,查看针对公司的投诉文本。问题:哪些词(来自抱怨)明显是对等的?我们将使用 Spark-NLP 研究文本清理、标记化和旅鼠,使用 PySpark 进行计数,以及 tf-idf(术语频率-逆文档频率)分析。

我用了约翰·斯诺实验室的 Spark-NLP 库。你可以从他们,或者维基百科(大概也是他们写的,只是风格不同)。

安装 Spark-NLP

约翰·斯诺实验室提供了几个不同的快速入门指南——这里这里和这里这里——我发现一起使用很有用。

如果您尚未安装 PySpark(注意:PySpark 版本 2.4.4 是唯一受支持的版本):

$ conda install pyspark==2.4.4
$ conda install -c johnsnowlabs spark-nlp

如果你已经有了 PySpark,一定要把 spark-nlp 安装在和 PySpark 相同的通道里(你可以从 conda 列表里查看通道)。在我的例子中,PySpark 安装在我的康达-福吉频道上,所以我使用

$ conda install -c johnsnowlabs spark-nlp — channel conda-forge

我已经安装了 PySpark,并设置为与 Jupyter 笔记本一起使用,但是如果没有,您可能需要在终端中设置一些额外的环境变量(正如第二个快速入门指南中提到的,但不是第一个,所以…)

$ export SPARK_HOME=/path/to/your/spark/folder
$ export PYSPARK_PYTHON=python3
$ export PYSPARK_DRIVER_PYTHON=jupyter
$ export PYSPARK_DRIVER_PYTHON_OPTS=notebook

Spark-NLP 入门

如果您希望使用预安装的数据集,因此不需要访问 spark 会话,可以从下面两行开始:

import sparknlp
sparknlp.start()

在我的例子中,我需要 SparkSession 从 parquet 文件中加载我的数据,所以我将添加。config("spark.jars.packages "," com . johnsnowlabs . NLP:spark-NLP _ 2.11:2 . 3 . 5 ")到我的 SparkSession.builder

from pyspark.sql import SparkSession# start spark session configured for spark nlp
spark = SparkSession.builder \
     .master('local[*]') \
     .appName('Spark NLP') \
     .config('spark.jars.packages', 
             'com.johnsnowlabs.nlp:spark-nlp_2.11:2.3.5') \
     .getOrCreate()

就是这样!你站起来了!

停止字

Spark-NLP 没有内置的停用词词典,所以我选择使用 NLTK 英语停用词,以及在我的数据集中找到的“xxxx”修订字符串。

from nltk.corpus import stopwordseng_stopwords = stopwords.words('english')
eng_stopwords.append('xxxx')

设置您的文本操作管道

首先,导入您的工具:

from sparknlp.base import Finisher, DocumentAssembler
from sparknlp.annotator import (Tokenizer, Normalizer,
                                LemmatizerModel, StopWordsCleaner)
from pyspark.ml import Pipeline

大多数项目在开始时需要 DocumentAssembler 将文本转换成 Spark-NLP 注释器就绪的形式,在结束时需要 Finisher 将文本转换回人类可读的形式。您可以从注释器文档中选择您需要的注释器。

在设置管道之前,我们需要用适当的输入初始化注释器。我们将使用典型的 Spark ML 格式.setInputCols(*list of columns*).setOutputCol(*output column name*),以及其他特定于注释器的函数(参见文档)。每个输出列都将是下面的注释器的输入列。

documentAssembler = DocumentAssembler() \
     .setInputCol('consumer_complaint_narrative') \
     .setOutputCol('document')tokenizer = Tokenizer() \
     .setInputCols(['document']) \
     .setOutputCol('token')# note normalizer defaults to changing all words to lowercase.
# Use .setLowercase(False) to maintain input case.
normalizer = Normalizer() \
     .setInputCols(['token']) \
     .setOutputCol('normalized') \
     .setLowercase(True)# note that lemmatizer needs a dictionary. So I used the pre-trained
# model (note that it defaults to english)
lemmatizer = LemmatizerModel.pretrained() \
     .setInputCols(['normalized']) \
     .setOutputCol('lemma')stopwords_cleaner = StopWordsCleaner() \
     .setInputCols(['lemma']) \
     .setOutputCol('clean_lemma') \
     .setCaseSensitive(False) \
     .setStopWords(eng_stopwords)# finisher converts tokens to human-readable output
finisher = Finisher() \
     .setInputCols(['clean_lemma']) \
     .setCleanAnnotations(False)

现在我们准备定义管道:

pipeline = Pipeline() \
     .setStages([
           documentAssembler,
           tokenizer,
           normalizer,
           lemmatizer,
           stopwords_cleaner,
           finisher
     ])

使用管道

我导入并选择我的数据,然后使用 pipeline.fit(数据)。转换(数据)。例如:

# import data
df = spark.read.load('../data/consumer_complaints.parquet',
                     inferSchema='true', header='true')# select equifax text data as test
data = df.filter((df['company'] == 'EQUIFAX, INC.')
           & (df['consumer_complaint_narrative'].isNull() == False))
data = data.select('consumer_complaint_narrative')# transform text with the pipeline
equifax = pipeline.fit(data).transform(data)

这将返回一个 DataFrame,其中添加了管道注释器中指定的列。因此 equifax.columns 返回:

['consumer_complaint_narrative',
 'document',
 'token',
 'normalized',
 'lemma',
 'clean_lemma',
 'finished_clean_lemma']

当我们更仔细地观察整理器的输出时,在这个例子中是“finished_clean_lemma”,我们看到每个记录都是一个单词列表—例如[address, never, …][pay, satisfied, …]

对文本进行计数矢量化

为了让每个单词都在同一水平线上,我使用了pyspark.sql分解功能。

from pyspark.sql.functions import explode, colequifax_words = equifax_words.withColumn('exploded_text', 
                               explode(col('finished_clean_lemma')))

现在文本准备好.groupby().count()来获得每个单词的计数。

然后,我将结果转换为 pandas,并使用字典理解将表转换为字典(这可能不是最优雅的策略)。

counts = equifax_words.groupby('exploded_text').count()
counts_pd = counts.toPandas()
equifax_dict = {counts_pd.loc[i, 'exploded_text']: 
                counts_pd.loc[i, 'count'] 
                for i in range(counts_pd.shape[0])}

完全披露:即使使用在所有四个内核上运行的 Spark,为前 20 名抱怨者做这件事也要花费大量的时间——这是大量的计算!

Tf-idf

现在我已经将每个公司的投诉计数的文本矢量化(也就是转换成{word1: count1,word2: count2…})了,我已经准备好获取每个公司单词集中每个单词的 tf-idf。

助手功能:

def term_frequency(BoW_dict):
     tot_words = sum(BoW_dict.values())
     freq_dict = {word: BoW_dict[word]/tot_words 
                  for word in BoW_dict.keys()}
     return freq_dictfrom math import logdef inverse_document_frequency(list_of_dicts):
    tot_docs = len(list_of_dicts)
    words = set([w for w_dict in list_of_dicts 
                   for w in w_dict.keys()])
    idf_dict = {word: log(float(tot_docs)/
                      (1.0 + sum([1 for w_dict in list_of_dicts 
                              if word in w_dict.keys()]))) 
                    for word in words}
    return idf_dictdef tf_idf(list_of_dicts):
     words = set([w for w_dict in list_of_dicts 
                  for w in w_dict.keys()])
     tf_idf_dicts = []
     idfs = inverse_document_frequency(list_of_dicts)
     for i, w_dict in enumerate(list_of_dicts):
          w_dict.update({word: 0 for word in words 
                         if word not in w_dict.keys()})
          tf = term_frequency(w_dict)
          tf_idf_dicts.append({word: tf[word]*idfs[word] 
                               for word in words})
     return tf_idf_dicts

综合起来看:

list_of_word_dicts = [company_complaint_word_counts_dict[company] 
                      for company in companies]
tf_idf_by_company_list = tf_idf(list_of_word_dicts)
tf_idf_by_company_dict = {c: tf_dict 
           for c, tf_dict in zip(companies, tf_idf_by_company_list)}

我们每个顶级公司的投诉有什么独特之处

为了找到让每家公司与众不同的词,我找到了我感兴趣的公司中 tf-idf 得分最高的词。

不幸的是,这表明我没有做足够的工作来清理我的数据。所有 tf-idf 得分最高的单词都是错别字或组合在一起的单词(如“tobe”、“calledthem”等)。).有时候 1000 个字符串不带空格。所以在这里,我添加了一个基于nltk.corpus words.words()列表的过滤器。不幸的是,tobe 实际上是一个单词,所以它仍然出现在一些热门搜索结果中。鉴于数据集中缺少空间的问题,我怀疑人们是否在谈论“北非和中非一些地区的传统外衣,由一段布料缝制成宽松的长裙或披在身上并系在一个肩膀上”( Collins Dictionary )。

让我们来看看我们十大公司的一些顶级 tf-idf 评分词:

Equifax:经销商,原告,重新插入,可证明,可证明,运行

益百利:经销商,原告,可证明的,可证明的,运行者,再插入

跨国联盟:经销商,原告,可证明的,可证明的,顺从的,重新插入

美银:商户、止赎、柜员、白金、梅隆(?),火器,mesne

富国银行:保护,止赎,评估,保护主义者,出纳员,交易商

摩根大通:蓝宝石,西南,商人,航空公司,探险家,出纳员

花旗银行:仓库,促销,固特异,威望,商人,股息

资本一:科尔,水银,品味,果园,商人,风险,再比尔

Navient 解决方案:先锋、mae、无补贴、文凭、再认证、毕业

奥克文金融:回家,取消抵押品赎回权,悬念,流氓,复式

我们确实看到了不同类别的金融机构,金融局从提供更多抵押贷款和店面银行业务的银行以及美国教育部贷款服务机构 Navient 得出了不同的结果。

同时,这个结果也相当令人沮丧。这些最重要的话,感觉不是超级有见地。我在想:

  1. 也许我们需要看的不仅仅是这些热门词汇,比如前 100 名?
  2. 或者,tf-idf 可能不是这项工作的合适工具。由于对这些公司的投诉如此之多,许多词在所有或几乎所有公司的投诉“文集”中至少出现一次。这个因素,逆文档频率,压倒了文本频率。我想知道如果我使用所有的公司,而不仅仅是前 20 名,结果会有什么不同。

一如既往,在 GitHub repo 中找到更多(代码)。

编码快乐!

Unsplash 上由 Austin Schmid 拍摄的照片

Spark 自然语言处理

原文:https://towardsdatascience.com/natural-language-processing-with-spark-9efef3564270?source=collection_archive---------23-----------------------

利用 PySpark MLlib 对灾难推文进行分类(文本分类)

西蒙·马辛格在 Unsplash 上拍摄的照片

这是一个关于使用 PySpark 开发预测机器学习模型的介绍性教程。我将展示自然语言处理(NLP)的基础,同时利用 Spark 的强大功能。我们会用 PySpark 这是一个用于 Spark 的 Python API。本教程的数据集来自于【NLP with Disaster Tweets】ka ggle 竞赛。GitHub 上有完整的代码。

这些数据由推文组成,我们的任务是预测哪些推文与灾难有关。这可以改善几个相关方的响应时间,例如警察部队、消防队或新闻机构等。我们将通过建立预测机器学习模型来执行文本分类,这是 NLP 的一个类别。下面的算法可以帮助你在文本分析或自然语言处理中得到启发,并且有很多应用。

文本分类是根据文本的内容给文本分配标签或类别的过程。它是自然语言处理的基本任务之一,具有广泛的应用,如情感分析、主题标注、垃圾邮件检测和意图检测。—来自 Monkeylearn

让我们马上开始研究数据吧。为此,我们需要了解一下火花数据帧。现在,我们需要在 Python 中启动一个 Spark 会话来使用 Spark。我们使用以下命令启动会话,appName 参数,即“nlp”在这种情况下可以由用户选择。

*spark = SparkSession.builder.appName('nlp').getOrCreate()*

一旦我们开始 Spark 会话,我们将使用' spark.read.csv '函数加载数据。将数据文件加载到工作空间后,我们需要对文本数据进行预处理。数据帧的头部如下图所示。我们将处理‘文本’字段,以预测‘目标’字段。

推文数据的最高记录

数据预处理(提取特征)

以下工作流详细介绍了从数据中提取要素的过程。每个阶段的描述都跟在图像后面。

用于特征提取的数据处理工作流程

1)删除空值:我们删除文本中所有具有 null/na 值的记录。为此,我们可以使用 dropna()函数。

2)从推文中删除数字:我们使用正则表达式(regex) 操作符来进一步清理文本数据。下面的代码删除文本中的所有数字。我们正在处理单词而不是数字来识别灾难推文。

*regexp_replace(col(‘text’), ‘\d+’, ‘’)*

3)分离单词:然后我们将推文分解成单个单词进行分析。为此,我们使用 RegexTokenizer()

4)删除停用词:我们使用py spark . ml 库中的【stopwodsmover()函数从分离的词中删除停用词。一些停用词的例子有:I,the,a,has,等等。从这些例子中你可以注意到,这些单词没有携带太多的信息,因此我们从分析中去除了它们。

5)创建 features 列:在从数据中删除不重要的单词后,我们使用 CountVectorizer() 函数。该函数将单词转换为数字向量,以便能够将其输入到机器学习模型中。

现在,我们的数据可以输入预测模型了。完成上述过程后的数据是这样的。

清洗和特征提取后的最终数据帧

让我解释一下上面数据框架中的所有字段;我们从‘文本’字段开始。执行上述工作流程的前 3 个步骤后,【单词】会显示分离的单词。‘filtered’栏显示按照第 4 步所述移除停用词后的单词。完成步骤 5 后,‘特征’字段是数值向量字段,这是我们将用于训练机器学习模型的字段。‘目标’字段是我们的预测变量,它显示推文是否与灾难有关。

机器学习模型

我们将从前面的过程中获得的数据分成训练验证。我们使用训练数据帧来训练机器学习模型,使用验证数据帧来验证它们对未知数据的准确性。验证分类模型有几个标准,我们将使用 ROC 和准确性进行分析。验证后,我们将对测试数据进行预测。

我将举例说明一些常见的分类机器学习算法。我假设你熟悉这些算法,我会尽量不要用这些算法来烦你。

朴素贝叶斯

朴素贝叶斯模型是最常用的文本分类算法之一。朴素贝叶斯算法假设所有的预测变量都是相互独立的。简而言之,它假设某个特定要素的存在与数据中的任何其他要素无关。这个假设在现实生活中并不总是正确的,然而,它在文本分类中是有意义的。以下代码用于使用 PySpark 对朴素贝叶斯模型进行定型和验证。

*from pyspark.ml.classification import NaiveBayes
from pyspark.ml.evaluation import MulticlassClassificationEvaluator## Fitting the model
nb = NaiveBayes(modelType="multinomial",labelCol="label", featuresCol="features")
nbModel = nb.fit(train)
nb_predictions = nbModel.transform(validate)## Evaluating the model
evaluator = MulticlassClassificationEvaluator(labelCol="label", predictionCol="prediction", metricName="accuracy")
nb_accuracy = evaluator.evaluate(nb_predictions)
print("Accuracy of NaiveBayes is = %g"% (nb_accuracy))#Accuracy of NaiveBayes is = 0.803448*

逻辑回归

它是回归的一种变体,使用逻辑函数为二元结果变量建模。下面的代码演示了如何定型和验证逻辑回归。

*from pyspark.ml.classification import LogisticRegression## Fitting the model
lr = LogisticRegression(featuresCol = 'features', labelCol = 'target', maxIter=10)
lrModel = lr.fit(train)
lrPreds = lrModel.transform(validate)## Evaluating the model
evaluator = MulticlassClassificationEvaluator(labelCol="label", predictionCol="prediction", metricName="accuracy")
lr_accuracy = evaluator.evaluate(lrPreds)
print("Accuracy of Logistic Regression is = %g"% (lr_accuracy))#Accuracy of Logistic Regression is = 0.768276*

决策树

决策树本质上是基于试图学习其关于结果变量的行为的列来分割数据集,即,我们将预测器空间分割成简单的区域。Will Koehrsen 的这篇文章有助于详细理解决策树和随机森林。我们可以使用下面的代码来训练和验证决策树。

*from pyspark.ml.classification import DecisionTreeClassifier## Fitting the model
dt = DecisionTreeClassifier(featuresCol = 'features', labelCol = 'target', maxDepth = 3)
dtModel = dt.fit(train)
dtPreds = dtModel.transform(validate)## Evaluating the model
evaluator = MulticlassClassificationEvaluator(labelCol="label", predictionCol="prediction", metricName="accuracy")
dt_accuracy = evaluator.evaluate(dtPreds)
print("Accuracy of Decision Trees is = %g"% (dt_accuracy))#Accuracy of Decision Trees is = 0.651034*

随机森林

随机森林是一种集合机器学习方法。它们使用自举技术,从根本上说是众多弱学习者的组合,特别是决策树。查看以下代码,了解如何在 spark 中实现随机森林。

*from pyspark.ml.classification import RandomForestClassifier## Fitting the model
rf = RandomForestClassifier(featuresCol = 'features', labelCol = 'target')
rfModel = rf.fit(train)
rfPreds = rfModel.transform(validate)## Evaluating the model
evaluator = MulticlassClassificationEvaluator(labelCol="label", predictionCol="prediction", metricName="accuracy")
rf_accuracy = evaluator.evaluate(rfPreds)
print("Accuracy of Random Forests is = %g"% (rf_accuracy))#Accuracy of Random Forests is = 0.581379*

梯度推进树

梯度推进树是一种类似于随机森林的集成方法。构建树的方法不同于随机森林;由梯度推进树建立的每个新树试图纠正由前一个树产生的错误。我们使用来自py spark . ml . class ification库中的 GBTClassifier 来训练和验证数据。

*from pyspark.ml.classification import GBTClassifier## Fitting the model
gbt = GBTClassifier(maxIter=10)
gbtModel = gbt.fit(train)
gbtPreds = gbtModel.transform(validate)## Evaluating the model
evaluator = MulticlassClassificationEvaluator(labelCol="label", predictionCol="prediction", metricName="accuracy")
gb_accuracy = evaluator.evaluate(gbtPreds)
print("Accuracy of GBT is = %g"% (gb_accuracy))#Accuracy of GBT is = 0.681379*

根据测试数据进行预测

既然我们已经训练并验证了几个模型,我们就可以对看不见的测试数据进行预测了。我们可以根据所有可用的训练数据重新训练模型,然后进行预测。下面的代码演示了如何使用梯度推进模型进行预测。但是,您可以对任何训练过的模型重复同样的操作,并且使用其他模型进行预测的完整代码可以在 Github 上找到。

*## Fitting the model
gbt = GBTClassifier(maxIter=10)
gbtModel = gbt.fit(trainData)## Make predictions
gbtPreds = gbtModel.transform(testData)
gbtPreds.select('id','prediction').show(5)+---+----------+
| id|prediction|
+---+----------+
|  0|       0.0|
|  2|       0.0|
|  3|       1.0|
|  9|       0.0|
| 11|       0.0|
+---+----------+
only showing top 5 rows*

一旦你做出了预测,你就可以将数据帧转换成 CSV 格式并提交给比赛。您现在已经准备好使用 Spark 来开发机器学习模型。文本分类有无数的应用,例如识别垃圾邮件、标记网站/产品内容等。并且上述算法适用于所有这样的任务。希望你觉得这很有用,并让我知道你的想法。快乐学习!

感谢您的阅读。我希望这对你有所帮助。如果你有任何建议,请在评论区添加。请随时通过我的网站LinkedIn 与我联系。

参考资料:

  1. Spark 文档:https://spark . Apache . org/docs/2 . 2 . 0/ml-classification-regression . html
  2. https://monkeylearn.com/text-classification/
  3. Kaggle 笔记本:https://www . ka ggle . com/palmero/binary-class ification-with-py spark-and-ml lib
  4. Github 笔记本:https://github . com/LP-data ninja/spark ml/blob/master/py spark-NLP-ka ggle . ipynb

SQL 的自然语言:在你自己的数据库中使用它

原文:https://towardsdatascience.com/natural-language-to-sql-use-it-on-your-own-database-d4cd5784d081?source=collection_archive---------4-----------------------

使用 EditSQL 将自然语言问题转换为类似 SQL 的查询,用于自定义数据库模式

托拜厄斯·菲舍尔在 Unsplash 上的照片

不是每个人都喜欢或知道如何编写 SQL 查询来在一个巨大的数据库中进行搜索。对于一个门外汉来说,用 SQL 函数和关键字构造复杂的查询——比如 JOIN 和 GROUP BY——将是一场噩梦。一个将简单的信息检索问题转换成相应的 SQL 查询的系统将会派上用场,特别是对于的银行和医疗保健部门。随着 NLP 的进步,这可能很快就会成为现实。

虽然已经有大量的研究来解决这个问题,但我们还没有得到完全准确的结果。尽管如此,通过对基准数据集如 WikiSQL 、Spider、SPaRC 和 ATIS 所做的工作,人们已经成功构建了文本到 SQL 系统,并取得了不错的结果。在这里,您将看到如何使用 EditSQL 模型实现这样一个系统,以及在您自己的模式上使用它的简单方法。

本文结构如下:

1.介绍

2.在 SParC 上安装和运行 EditSQL

3.对代码进行更改

4.添加自定义数据库并构建 Vocab

5.测试您的问题

6.结论

作者图片

1.介绍

从用户问题生成 SQL 查询涉及到解决任务,而不仅仅是问答和机器翻译。就像在问答中一样,随着用户交互的增加,他们通常会提出需要复杂处理的问题,比如引用前面提到的一些信息,或者需要几个不同模式的组合。作为一种工具,这样的系统帮助通常在数据库查询方面缺乏经验的最终用户从大量复杂的数据库中提取信息。

已经在不同的基准数据集上进行了一些尝试,以解决文本到 SQL 任务中的此类问题,尤其是在语义解析中。你可以看看这个有趣的调查【4】,它很好地介绍了任务和问题。

你也可以看看这个由 AllenNLP 团队在 ATIS 数据集上构建的交互式转换器。就像其他几个性能更好的模型一样,它们使用语义解析和编码器-解码器架构来完成这项工作。

来自 SParC 数据集的示例。图片来自[1]

截至 2020 年 7 月,Spider 和 SParC 的排行榜将以下型号列为性能最佳的型号,并给出了开放源代码:

在这里,您可以找到 SpiderSParC 的完整排行榜。出于实用性考虑,我们将本文的范围限制在探索 EditSQL,尤其是 SParC 上的 EditSQL。

团队在排行榜上给出的另一个 SParC 示例

局限性:

虽然列出的模型在各自的数据集上表现良好,但给定的代码没有在自定义数据库上测试模型的选项(更不用说训练了)。事实上,即使对数据集的现有查询进行更改也是一个乏味且容易出错的过程。

然而,在上面给出的模型之外,我们可以对 EditSQL 进行一些修改,并设法在定制的 SQLite 数据库上运行 SParC 实验。这些变化很小,并且被证明是在您自己的数据库上测试性能的一种简单的变通方法。

关于 EditSQL:

EditSQL 试图解决依赖于上下文的文本到 SQL 查询生成任务,并结合了交互历史以及话语表编码器-解码器单元,以可靠地理解用户话语(或问题)的上下文。为此,他们使用了一种基于 BERT 的编码器,这种编码器有助于捕捉复杂的数据库结构,并将它们与话语相关联。因此,给定一个任意的问题,该模型将最确定地正确识别该问题所对应的数据库模式。

表编码器结构在[1]中给出

[1]中给出的发声编码器结构

此外,EditSQL 考虑了用户话语和表结构之间的关系以及最近的编码历史,以正确识别上下文。如上图所示,这里获得的信息然后被传递到一个表感知解码器,该解码器使用注意力增强 LSTM 来执行 SQL 生成。

然而,用户经常询问包含在先前交互中提供的信息的问题。在顺序生成机制中,这可能导致处理和查询生成中的冗余。EditSQL 之所以得名,是因为它采用了一种新颖的机制来“编辑”生成的查询标记,并使用另一个双 LSTM 和启用了注意力的上下文向量来解决这个问题。

用于编辑查询的模型架构(在[1]中给出)

2.在 SParC 上安装和运行 EditSQL

要运行该模型,请确保您有一个支持 GPU 的系统。或者,你可以在 Google Colab 上工作。

首先,将这个存储库克隆到您的系统中(或者在 Colab 中):

git clone [https://github.com/ryanzhumich/editsql](https://github.com/ryanzhumich/editsql)

从他们的官方页面下载 SParC 数据集来运行实验,或者使用如下的gdown 命令:

pip install gdowngdown --id 13Abvu5SUMSP3SJM-ZIj66mOkeyAquR73

将解压后的文件夹放入 editsql/data/sparc

接下来,您可以遵循他们的自述文件中的说明或遵循以下步骤:

pip install -r requirements.txt #install dependencies#Download pre-trained BERT modelgdown --id 1f_LEWVgrtZLRuoiExJa5fNzTS8-WcAX9# or download it directly from [https://drive.google.com/file/d/1f_LEWVgrtZLRuoiExJa5fNzTS8-WcAX9/view?usp=sharing](https://drive.google.com/file/d/1f_LEWVgrtZLRuoiExJa5fNzTS8-WcAX9/view?usp=sharing)

并将预训练的 BERT 模型放在文件树中,如下所示:

作者图片

如果上述步骤成功执行,您可以运行下面的 bash 脚本开始训练:

bash run_sparc_editsql.sh

作者将他们的实验日志保存在logs/logs _ SPARC _ editsql中的 log.txt 中,在这里可以找到每个时期的细节和性能。

在培训期间,您至少需要成功执行初始预处理和 vocab 构建步骤。这将创建名为

  • logs_sparc_editsql
  • processed _ data _ SPARC _ remove from
  • 已处理 _ 数据 _ sparc _ 移除 _ 测试

一旦您的输出如下所示,您就可以中断执行(Ctrl+C)(在实际训练开始之前)。根据您的配置,示例数量和批量值可能会有所不同。

作者图片

这些步骤的成功执行将创建开发集测试所需的已处理数据文件和 vocab 文件。

由于我们没有真正执行任何“训练”,我们将需要下载作者的预训练模型,并将其放在logs/logs _ SPARC _ editsql下,名称为 save_31_sparc_editsql

gdown --id 1MRN3_mklw8biUphFxmD7OXJ57yS-FkJP#or download directly from #https://drive.google.com/file/d/1MRN3_mklw8biUphFxmD7OXJ57yS-FkJP/view?usp=sharing

现在,您已经准备好运行 bash 脚本来对 dev 集进行预测了。

bash test_sparc_editsql.sh

预测保存在一个结构化的 JSON 文件中,该文件位于logs/logs _ SPARC _ editsql中,名为dev _ use _ predicted _ queries _ predictions . JSON

用相应的问题来验证每个预测的查询可能很麻烦。因此,您可以运行以下脚本来获得存储在文件中的可读输出。该脚本将创建包含输入问题、预测查询和预测文件中每个问题-查询对的预测置信度的 output.txt

创建可读输出文件的脚本

3.自定义数据库:对代码进行更改

  • 确保你有一个。包含您的 SQL 数据库的 sqlite 数据库文件。假设您有一个名为“ sales.sqlite 的 db 文件。将该文件放在一个名为“ sales 的新文件夹中,如下所示。

作者图片

  • 接下来,打开在 data/sparc 中找到的 tables.json ,并在那里添加数据库模式和表的描述。在这里使用自述文件的表格部分描述的结构。您可以使用 tables.json 中已经存在的条目作为参考,并为您的模式添加一个类似的条目。
  • 打开 dev.jsondev _ no _ value . JSON,在同一个目录下找到,观察输入的问题结构如蜘蛛的资源库所示:就在这里并带有示例文件parsed _ SQL _ examples . SQL。您所要做的就是复制一个完整的条目(下一个" database_id "条目之前的" { "和" {database _ id"之间的所有内容)。
  • 一旦你追加了这个复制条目,只需编辑你想要的问题的" 话语 "和" 话语 _toks "和你的数据库名称的" 数据库 _id "在我们的示例中,它将是 "database_id" : "sales"

编辑话语、话语 _toks 和数据库 _id(图片由作者提供)

  • 最后,将 database_id (您的数据库名称)添加到dev _ db _ ids . txt(位于同一目录)中的数据库名称列表中。

4.添加自定义数据库并构建 Vocab

  • 在培训的预处理和 vocab 构建步骤中,我们将所谓的“交互”写入 pickle 文件并保存在 data/sparc_data_removefrom 中。
  • 这些交互是 SParC 数据集中固有的,您可以在他们的论文[2]以及论文[1]第 3.2 节中的 EditSQL 上下文中读到。
  • 类似地,基于 tables.json 中的表格描述和训练序列,模型为存储在processed _ data _ SPARC _ remove from的每个训练、有效和开发实验创建不同的词汇文件。

processed _ data _ SPARC _ remove from 的内容(图片由作者提供)

  • 出于这个原因,当我们添加一个新的数据库或者编辑 dev 文件时(就像我们在步骤 2 中所做的那样),我们需要再次运行训练脚本。就像在步骤 1 中一样,一旦预处理步骤完成,我们就可以终止脚本。

注意:请删除培训脚本创建的所有文件夹,然后再次运行。这也包括 logs _ SPARC _ editsql/args . log 这些文件不会更新,除非脚本从头开始创建它们。

5.测试您的问题

  • 运行bash test_sparc_editsql.sh以获得您的问题的预测查询。
  • 按照步骤 1 中提到的测试步骤,生成 output.txt 以获得可读的结果视图。

从 output.txt 清除结果

6.结论

现在,您可以轻松地将自然语言问题转换为自己模式上的 SQL 查询。

感谢阅读!

参考资料:

[1]张,芮,等,基于编辑的跨域上下文相关问题 SQL 查询生成(2019), arXiv 预印本 arXiv:1909.00786

Github:https://github.com/ryanzhumich/editsql

[2]于,陶等,Sparc:语境中的跨领域语义解析(2019)。 arXiv 预印本 arXiv:1906.02285

Github:https://github.com/taoyds/sparc

[3]于,陶等,Spider:面向复杂跨领域语义解析和文本转 sql 任务的大规模人类标注数据集(2018), arXiv 预印本 arXiv:1809.08887

https://github.com/taoyds/spiderGithub:

[4] Affolter,Katrin,Kurt Stockinger 和 Abraham Bernstein,对数据库的最近自然语言接口的比较调查(2019),《VLDB 日报》28.5:793–819。

[5]王,白林等,Rat-sql:面向文本到 sql 解析器的关系感知模式编码与链接(2019), arXiv 预印本 arXiv:1911.04942

[6]郭,,等,面向带中间表示的跨域数据库复杂文本转 SQL(2019), arXiv 预印本 arXiv:1905.08205

使用深度学习的自然场景识别

原文:https://towardsdatascience.com/natural-scene-recognition-using-deep-learning-91b6ba86bad5?source=collection_archive---------35-----------------------

在计算机视觉中,场景识别是最具挑战性的研究领域之一。

一眼就认出环境是人类大脑最有成就的行为之一。虽然最近在对象识别任务中的巨大进步源于诸如 COCO 之类的大型数据集的可用性以及用于学习高级特征的卷积神经网络(CNN)的兴起,但是场景识别性能并没有获得同样程度的成功。

在这篇博文中,我们将看到分类模型如何对一个场景的图像进行分类。对于这项任务,我们采用了 Places365-Standard 数据集来训练模型。该数据集具有 1,803,460 个训练图像和 365 个类,每个类的图像数量从 3,068 到 5,000 不等,图像的大小为 256*256。

数据集的图像

安装和下载数据

让我们从设置 Monk 及其依赖项开始:

!git clone [https://github.com/Tessellate-Imaging/monk_v1.git](https://github.com/Tessellate-Imaging/monk_v1.git)
*! cd monk_v1/installation/Linux && pip install -r requirements_cu9.txt*

安装完依赖项后,我下载了place 365-Standard数据集,可以从这里下载。

创造一个实验

我已经创建了一个实验,对于这个任务,我使用了 mxnet 胶子后端。

import os
import sys
sys.path.append("monk_v1/monk/");
from gluon_prototype import prototype
gtf = prototype(verbose=1);
gtf.Prototype("Places_365", "Experiment");

模型选择和培训

我尝试了各种模型,如 resnet、densenet、inception、vgg16 等等,但是只有 vgg16 比其他任何模型都具有更高的验证准确性。

gtf.Default(dataset_path="train/",
            path_to_csv="labels.csv",
            model_name="vgg16",
            freeze_base_network=False,
            num_epochs=20);gtf.Train();

经过 20 个历元的训练,我得到了 65%的训练准确率和 53%的验证准确率。

预言;预测;预告

gtf = prototype(verbose=1);
gtf.Prototype("Places_365", "Experiment", eval_infer=**True**);img_name = "test_256/Places365_test_00208427.jpg" 
predictions = gtf.Infer(img_name=img_name);
**from** **IPython.display** **import** Image
Image(filename=img_name)

对测试图像的预测

img_name = "test_256/Places365_test_00151496.jpg" 
predictions = gtf.Infer(img_name=img_name);
**from** **IPython.display** **import** Image
Image(filename=img_name)

对测试图像的预测

在此之后,我试图找出为什么精度没有比我得到的提高更多。一些可能的原因是:

标签不正确:- 检查训练文件夹时,有些图像的标签不正确,如 baseball_field 的图像不正确。还有很多不正确的标签。

棒球场中的错误图像

img=mpimg.imread(“images/train/baseball_field2469.jpg”)
imgplot = plt.imshow(img)

不清晰的场景:- 由于各种类似的类共享类似的对象,如餐厅和食堂、森林道路和田野道路,因此存在非常难以分类的不清晰图像。

标签:field_road

标签:森林 _ 道路

正如我们所见,很难对这两幅图像进行分类。

多个场景部分:- 由多个场景部分组成的图像不能像海洋附近的建筑物一样归为一类。这些场景可能很难分类,需要更多的地面真实标签来描述环境。

总之,这篇博文展示了我们如何使用深度学习网络来执行自然场景分类,以及为什么场景识别性能没有达到与对象识别相同的成功水平。

参考

[## shubham7169/MonkAI

github.com](https://github.com/shubham7169/MonkAI/blob/master/Scene Recognition.ipynb)

http://places2.csail.mit.edu/PAMI_places.pdf

自然启发的优化算法:使用 Python 的粒子群优化

原文:https://towardsdatascience.com/nature-inspired-optimization-algorithms-particle-swarm-optimization-2cd207d0d37e?source=collection_archive---------12-----------------------

鸣椋鸟

利用百万年自然选择过程解决数值优化问题

目录

  • 简介
  • 什么是涌现复杂性?
  • 建模鸟群智能
  • 使用 Python 实现理论
  • 结论
  • 资源和参考资料

介绍

粒子群优化(PSO)是一种基于随机优化的强大算法,其灵感来自于大群鸟中的规则。在本文中,将支持该方法的可行性,然后将推导出这些原则的精确模型。最后,将描述数值优化问题的这些原理的数学模型的实现,然后使用 Python 来实现,以找到 Rastrigin 函数的全局最小值[1]。如果你用 C++编程,你可以参考参考资料一节[2]中的链接来查看项目源代码。

什么是涌现复杂性?

涌现复杂性[3]是一种现象,它描述了大群体的各个组成部分如何以相同但更简单的规则一起工作来创建多样而复杂的系统。有一些自然的复杂行为可以作为涌现的例子。例如,蚂蚁本能地互相交流,以建立一个活的桥梁,在寻找食物源的时候最小化交流距离[4]。鸟类相互跟随,形成更大的群体,这增加了它们发现捕食者和食物来源的可能性。与不一定有用的通常的复杂性概念不同,自然复杂性是百万年自然选择过程的结果,其中能量使用是增加存活机会的最重要因素。因此,如果同一个问题有两种解决方案,由于自然选择,更简单和需要更少能量的方法将会存在。这就是为什么《自然》杂志提出的解决方案既简单又能有效地尽可能减少动物的能量消耗。因此,科学家们单独观察一群椋鸟中的每只鸟,发现它们中的每一只都采取简单的行动来形成复杂的结构。

  1. 每只鸟都有自己的位置和速度
  2. 每只鸟都有自己的视野范围,可以跟随周围的鸟。这只鸟完全不知道这个跨度之外的活动。
  3. 如果任何一只鸟发现了食物,鸟群中所有的鸟都会朝那个方向飞去。

鸟群智能建模

在自然界中,在一个数值问题中,任何 boid(类鸟物体)的可观测邻域都被限制在某个范围内。因此,它可以收敛到某个局部最小值或鞍点,其中梯度(在我们的情况下是速度)将为 0。然而,拥有一个以上的 boid 允许群体中的所有鸟意识到误差函数的更大表面,并且如果它们中的任何一个已经看到了误差方面的更好位置,则不会陷入局部最小值。为此,我们将对上述原则进行数学建模,以使群体找到误差函数的全局最小值

  1. 每个 boid 都有自己的位置和速度。我们可以把速度看作误差函数的偏导数的向量。

f(x)= x +y 函数的曲面图

2.每个 boid 保持跟踪它曾经经历过的最佳位置,这在某种预定义的程度上有助于 boid 的当前速度。

3.这是整个鸟群所见过的最佳位置。因此,它将以预定的速率影响所有物体的速度。

通过使用上述规则,我们可以很容易地推导出驱动每个 boid 的数学方程。

计算 Delta V 的向量表示

在上面的等式中:

  • w——惯性决定了 boid 的当前速度对δV 的影响程度
  • c₂c₁——定义了 boid 和 swarm 的最佳记录位置将如何分别影响δv

w、c₁、c₂、学习率——是在优化过程中应该微调的超参数。

使用 Python 实现理论

对群体智能背后的数学理论进行了讨论和建模,它可以使用任何现代编程语言来实现。然而,由于它的广泛使用,实现将使用 Python 来实现。不过,在本文的参考资料部分,也可以找到 C++项目代码。为了测试该算法,Rastrigin 函数将被用作误差函数,这是优化问题中最具挑战性的函数之一。在平面上有大量的余弦振荡会引入无数的局部最小值,在这些局部最小值中,物体会被卡住。

拉斯特里金函数

Rastrigin 函数的 3D 曲面:【1】

如上所述,每个 boid 都有一个位置、速度、误差、最佳位置和已知误差。我们还应该编写一个 setter 函数,在需要时修改参数。

PSO 类将由误差函数表面上的移动粒子列表组成。为了初始化函数,需要函数的维数、boids 的数量以及历元的数量。

最后,我们编写代码来找到最佳优化误差函数的位置。首先,在每个时期,每个粒子被一个接一个地挑选并且优化它的位置。一旦粒子的位置被更新,“if”语句将检查它是否是蜂群的最佳位置。

现在,是时候运行 PSO 并观察算法的性能了。

粒子群输出

从下面的等值线图可以很容易地看出,swarm 只需要几个历元就可以收敛到 Rastrigin 函数的全局最小值。要获得创建轮廓可视化的代码以及流程的误差历元图,可以参考参考资料和参考资料一节中给出的链接。

结论

总而言之,粒子群优化模拟了鸟(或鱼)群体的集体行为。它受益于自然形成的解决自身优化问题以最小化能量使用的方式。大自然的设计及其原理在计算机科学问题上的实际应用是了不起的。虽然有无数的资源可以帮助你获得更多关于涌现和 PSO 的见解,但我将列出一些有区别的资源,你可以用它们来更深入地挖掘群体智能的主题。

资源和参考资料

[1] 维基百科,拉斯特里金函数

[2] T. Ahadli,粒子群优化 C++/Python 项目代码

[3] 对话,复杂中的非凡简单

[4] 《国家地理》,蚂蚁如何只用身体在半空中搭建桥梁

[5] 詹姆斯·麦卡弗里,利用 Python 实现群体智能优化

导航 2020:人工智能创业故事

原文:https://towardsdatascience.com/navigating-2020-an-ai-startup-story-5746cd13f04a?source=collection_archive---------49-----------------------

在疫情中心建立人工智能业务

图片由 Pixabay 提供

3 月 12 日上午,怀着沉重的心情,我和我的管理团队讨论了我们的决定,不再续租波士顿人工智能初创公司 Neurala 的海港总部。

我生在意大利,长在意大利,从朋友和家人那里我已经听够了现实生活中的故事。许多人希望的是一场只影响世界其他角落的严重流感,结果却是一场全球性的疫情,在我的祖国肆虐,并正向波斯顿蔓延。

我当时并不知道,这不仅仅是一个“在家工作一段时间”的问题,而是生活中一个新阶段的开始,我们业务的所有方面都需要彻底重新考虑。

人工智能平衡术

人工智能初创公司不适合胆小的人——新技术进入新市场,寻求可重复的商业模式。人工智能远非“一蹴而就”,经营一家小型创业公司与谷歌、亚马逊和微软等巨头竞争本身就是一项挑战——没有一个全球性的疫情与之抗衡。

2020 年 3 月,这变得更加困难。创建 Neurala 后,我们开始与 DARPA 和 NASA 合作,设计能够在小型计算硬件上运行和学习的创新人工智能。我们正在学习前进的每一步,所以我们带着这样的信念进入 2020 年,我们已经找到了我们的最佳点——为正确的市场提供正确的产品。

在一些成功的概念验证之后,我们帮助制造公司部署智能摄像机,以增强人眼以惊人的速度发现产品缺陷的能力,我们准备推出我们的新软件,让任何人——没有人工智能专业知识——在几分钟内直接在生产线上实施人工智能,无需编写代码。

在 2020 年 3 月推出一款产品被证明是有问题的。

具有讽刺意味的是,一个完全偏远的组织第一次试图推出一个旨在安装在内部的产品,这一点我们没有忘记。我们的客户、日本和意大利等国的制造商纷纷迅速关闭,看不到重新开业的迹象。没有能力出差、会见客户、排除软件故障,我们决定“冬眠”。为了保住工作,我们都降了薪,在波士顿的家中设立了办公室,专注于产品开发,并狂热地为以后的发布做准备。

那是艰难的几个月。对许多人来说,家庭责任(即管理放学后也在家的年幼子女)加剧了工作挑战。我和我的妻子,我们公司的联合创始人和首席运营官,我们有四个孩子,年龄从 1 岁到 9 岁不等,所以困难并没有在我们身上消失。但我们坚持下来,继续专注于前方的道路。作为一个团队,我们 100%的活动都集中在我们的产品发布上,我们在 6 月份成功完成了发布。

“找到了!”时刻

到那时,意想不到的事情发生了。在我 25 年的人工智能职业生涯中,我从未感受到围绕人工智能、机器人和自动化的对话出现如此大的转变。而不是“你不怕你在造终结者吗?”,我被问到的问题更多的是“你认为我们什么时候能得到足够的人工智能来帮助解决这个疫情问题?”仿佛突然之间,人们集体意识到,在最需要自动化和人工智能的时候,这些技术的缺乏实际上正在伤害人类。由于缺乏可用劳动力,工厂无法运营,自动化程度远远达不到没有人工监督就能工作的水平,公司现在开始询问他们何时可以测试我们的产品并自动进行质量检测,以便制造和运送客户需要的产品。

潮汐的变化

在几个月的时间里,制造业对人工智能的需求——幸运的是,我们的软件——已经增长到了我们决定重新开设波士顿办事处的时候了。尽管任何积极的事情都会在 2020 年带来一种奇怪的感觉,但在 8 月份,我们扣动了扳机,租了一个空间来容纳 10 个人(总共 40 多人)。

我最喜欢的爱因斯坦相对论的定义是:“一分钟有多长取决于你在浴室门的哪一边”。过去的六个月对我来说绝对是漫长的,每一天都充满了不确定性,让我感觉时间在流逝。

我相信,在这些充满挑战的日子里,围绕一个共同目标的人们可以团结起来,找到一条在平时可能找不到的前进道路。

导航 ML 部署

原文:https://towardsdatascience.com/navigating-ml-deployment-34e35a18d514?source=collection_archive---------19-----------------------

我们通常认为“部署”是将软件打包成一个工件,并将其移动到一个环境中运行。对于机器学习来说,将部署视为“将资源带入有效行动的行动”(牛津对“部署”的定义之一)可能更好。

使用 ML 模型进行商业决策有多种模式。部署机器学习模型可能意味着不同的事情,这取决于上下文。理解关键的预测模式有助于决定哪些工具适用于您的用例。

基于矢量卡通剪贴画的图片, CC BY-SA 4.0 ,通过维基共享

不同的情况适合不同的部署模式。但是有时同一个模型可能会以多种方式部署。模式的用例更多的是通过模型如何被消费来区分的,而不是预测的类型或意义。

许多项目目前认为他们必须构建自己的 ML 部署基础设施。有了部署模式的知识,我们将看到有工具可以提供帮助。

离线预测

离线预测是临时或一次性的预测。这可以在本地机器上完成,取决于预测的规模和所需的计算资源。

图片作者。来自 clipartdoc.com的商业人士剪贴画,按照他们的术语使用。

离线预测可以直接从 python 代码(例如 jupyter 笔记本)生成,并提供给目标受众(例如以 CSV 格式通过电子邮件发送)。这最适用于单个事件的预测,以及新事件需要新模型的情况。例如预测选举或体育赛事的结果。

批量预测

批量预测是指需要从文件或存储中进行一组预测,通常以固定的时间周期(例如每周)进行。假设有一个模型用于预测下一季度的收入。或者预测下周作物需要多少水。

图片作者。商务人士剪贴画来自clipartdoc.com,按照他们的条款使用。

对于批量用例,有一个规则的预测周期,每个周期可能使用相同的训练数据或相同的模型。或者可能每个周期都有新的训练数据可用,并且每次都需要生成新的模型。无论哪种方式,用例都适合触发器激活的处理作业,这些作业通过输入数据的存储进行预测。

实时服务

实时服务通常通过 HTTP 调用按需进行预测。这些在线用例包括(但不限于)用于推荐产品或广告等内容的电子商务应用程序。

图片作者。来自freesvg.org的网络服务器图标公共域

通常,一个模型在一个训练环境中被训练,并被打包用于实时服务。打包的模型经过一个提升过程到达实时服务环境。如果有新的培训数据可用,则“培训-薪资包-升级”流程将再次启动。

还有其他不太常见的服务用例,如在线学习。通过在线学习,训练持续发生,并且每个新的预测请求也是一个新的训练数据。大多数服务工具集中于单独的培训和服务,而不是在线学习。

实时服务可以与推广和监控紧密联系在一起。被服务的模型变成了微服务,需要安全地推出新版本的微服务,并监控其性能。

流动

流用例通过所需预测的吞吐量来标记,该吞吐量可能很高且可变。流式传输可以类似于批处理或实时传输,但增加了一个消息传递系统,以便按照处理速率而不是到达速率对预测进行排队。

流与其他实时情况的区别在于使用队列来平滑可变预测工作量的处理。

图片作者。来自 pngwing 的消息队列图标——非商业用途,DMCA。

实时预测在生成时可能会进入文件、数据库或 HTTP 服务。

流的一个例子可能是在线欺诈检测,其中可能允许交易通过,然后异步排队等待欺诈检测模型的交易后验证。

利用 ML 部署工具

如果我们将机器学习部署分成几个类别,它会变得更容易导航。这里我们提出了离线预测、批量预测、实时服务的空间。这些地方都有开源工具。已建立的工具从一开始就设计用于处理生产中的缩放和操作预测系统。

了解工具的一个很好的地方是 Linux 人工智能基金会(LFAI)的景观图(T1)。这是 LFAI 图表的一部分:

谢顿、皮质和射线是用来上菜的。Kubeflow 和 mlflow 是包含服务能力的端到端平台。Spark 在批量处理方面很受欢迎。 LFAI 景观图片段,拍摄于 2020–11–14 23:28:19Z。在 Apache License 2.0 下使用。

图表中间的特写是谢顿,我工作的地方。Seldon Core 是一个开源的实时服务解决方案,集成了批处理用例。Seldon 集成了渐进式展开指标审计日志解释数据漂移检测。Seldon 支持一系列不同的框架,并允许不同类型的模型无缝交换或混合(例如,使用多臂土匪路由器)。

我们在 Seldon 的理念是专注于关键用例,并与开源社区以及企业客户合作,以形成灵活和可扩展的解决方案。这导致了某些技术选择。目标平台的 Kubernetes。Knative,带有消息代理的可插拔选项(包括一个 Kafka 选项),用于流架构。用于 Argo 工作流或 kubeflow 管道的批处理选项。

要深入研究每个领域可用的工具范围,我建议使用“令人敬畏的生产机器学习”GitHub repo。它在编写时有 7k 个开始,并且具有关于模型服务(实时)数据管道(批处理)数据流处理(流)的专用部分。

摘要:导航 ML 部署

决定如何最好地从 ML 模型中获得预测可能会令人困惑。如果我们牢记关键的部署模式— 离线、实时、批处理,我们可以更清晰地做出决策。

许多项目目前认为他们必须构建自己的 ML 部署基础设施。但是对于四种部署模式中的每一种都有相应的技术。对这些模式的了解也让你确信你并不孤单。

在 R 中导航随机森林算法

原文:https://towardsdatascience.com/navigating-the-random-forest-algorithm-in-r-5ccbc0ef70e?source=collection_archive---------10-----------------------

图片来自 Pixabay501stCommanderMax

袋装树和随机森林有什么相似之处?

随机森林与袋装树的相似之处在于,随机森林或袋装树模型中的每棵树都根据数据的随机子集进行训练。事实上,这种对不同数据组进行采样以训练独立模型的过程是一种称为 bagging 的集成方法;因此得名袋装树。(见此处袋装树课:https://datasciencelessons . com/2019/08/05/learn-bagged-trees-for-class ification-in-r/)

它们有什么不同?

随机森林与袋装树的不同之处在于,袋装树可以访问任何给定树上的所有变量,因此袋装树的主要区别仅在于数据的采样。对于随机森林,用于训练模型的变量是在每棵树上随机选择的。这个过程被称为特性打包,因为它在概念上非常类似于引导聚合,只是针对变量。

许多人想知道为什么这个特征打包过程会导致更好的性能,原因是因为每个决策树有更大的不同可能性,因此每个树对因变量的变化给出不同的解释。

由于随机森林是对袋装树的改进,它们通常更有性能,在许多情况下也更容易调整。

现在使用我在打包文章中使用的相同数据集;我将在这里使用相同的数据集。

让我们开始吧

我们将使用randomForest包。需要记住的一点是,当调整ntree超参数时,更多的树几乎总是意味着更好的模型性能,您只需权衡计算时间和您可能获得的任何性能增益。(默认为 500 棵树)。

使用与决策树和袋装树教程中相同的数据集,我在每个模型中运行相同的公式。

正如我在其他教程中所说的,下面的formula部分是你告诉函数你想要理解什么的地方。~之前的变量是你的因变量或者你想了解的东西。~符号表示,表示,或者表示,接下来的一切就是你用来解释因变量的变化。

在这里,我们试图了解是否有人有可能在泰坦尼克号上幸存,给定他们的性别,年龄,兄弟姐妹数,票价,等等。

set.seed(14)
model <- randomForest(formula = as.factor(Survived) ~ Pclass + Sex + Age + SibSp + Parch + Fare + Embarked,
data = train)
print(model)

这里你可以看到打印出来的模型。包括了我们模型本身的一些解释,比如类型、树计数、变量计数等等。最有趣的是OOB estimate of error rateOOB代表出袋错误;与袋装树相似,这意味着当你采集数据样本来训练模型的每个版本时,你会遗漏一些数据。对于遗漏的数据,或者我们称之为袋外数据,模型会对其进行预测,并将其与实际数据进行比较,从而得出您在上面看到的错误率。上面计算误差的方法是通过错误分类计数并确定它占总分类的比例。比如我们预测 87 + 193 为 1 或者有可能存活。31%的错误率是通过将我们得到的错误数 87 除以预测值 87 + 193 计算出来的。

够了!让我们开始预测吧!

这里,我们使用刚刚训练的模型来预测测试中每个记录的类别。

性能赋值

混淆矩阵

从那里,我们实际上必须声明它是一个因子。如果两个字段不是同一个类,则CaretconfusionMatrix功能将不起作用。

test$pred <- predict(model, test)
test$pred <- as.factor(test$pred)
confusionMatrix(test$pred, test$Survived)

正如您在上面看到的,这是confusionMatrix函数的输出。

该函数向您显示了预测值和实际值如何匹配的表格。所以预测值和参考值相同的对角线单元格代表我们得到的正确值。

我将给你上一堂课,教你如何解读下面的困惑矩阵:

True positive:象限中引用和预测都为 1 的单元格。这表明你预测了存活,而他们确实存活了下来。

假阳性:这里你预测为阳性,但你错了。

真阴性:当你预测为阴性,并且你是正确的。

假阴性:当你预测为阴性,而你是不正确的。

需要记住的几个关键指标是灵敏度和特异性。敏感度是您正确预测的真实记录的百分比。

另一方面,特异性是衡量实际错误记录中你正确预测的部分。

在不平衡数据集上进行预测时,要记住特异性。一个非常常见的例子就是对垃圾邮件进行分类。99%的情况下它不是垃圾邮件,所以如果你预测没有垃圾邮件,你有 99%的准确率,但你的特异性是 0,导致所有的垃圾邮件都被接受。

ROC 曲线和 AUC

ROC 曲线或受试者工作特征曲线是一种可视化二元分类模型正确诊断或预测能力的方法。ROC 曲线绘出了不同阈值下的真阳性率与假阳性率的关系。

我们对于 ROC 曲线的目标是真阳性率 100%,假阳性率 0%。那条曲线会落在图的左上角。

AUC 旨在确定可分性的程度,或正确预测类别的能力。AUC 越高越好。1 是完美的,0.5 是随机的。

pred <- predict(object = model,
            newdata = test,
            type = "prob")library(Metrics)
auc(actual = test$Survived, 
    predicted = pred[,"yes"])

结论

那就是我对 R 中随机森林进行分类的介绍!希望对你有帮助!如果你愿意跟随我写关于数据科学、机器学习之类的东西,来 datasciencelessons.com 找我吧。

祝数据科学快乐!

如果你有兴趣了解这个主题的更多信息,请务必订阅!我目前正在写一本书,更详细地探讨这一原则和其他原则。

NBA 深度跳水

原文:https://towardsdatascience.com/nba-deep-dive-7f7558174672?source=collection_archive---------73-----------------------

斯蒂芬·库里的薪水太高了,而詹姆斯·哈登的薪水刚刚好

埃德加·恰帕罗在 Unsplash 上拍摄的照片

NBA 有大量的统计数据供统计学家和机器学习爱好者研究。有一堆网站拥有广泛的 NBA 数据,如 nba.com 的和 basketball-reference.com 的。

探索这些数据也是提高你的 TableauSQL 技能的好方法。我就是这么做的。下面的图都是用 Tableau 和 SQL(Python 中的 SQLite)做的表。

事不宜迟,我们来探究数据,建立模型吧!

探索数据

探索的许多变量(球队和球员统计)可以在这个词汇表或这个词汇表中找到。此报告包含数据、tableau 工作表、SQL 查询和模型。

你来自一个过度攻击性或防御性的国家吗?

在我们回答上面的问题之前,让我们看看每个州目前出生的 NBA 球员人数(截至 19-20 赛季仍在联盟中)。

当前 NBA 球员的出生状态计数

毫无疑问,加州以 44 名玩家排名第一。许多中西部的州有一两次这样的机会。

更有趣的是每个州的平均 VORP。 VORP 代表价值超过替补球员 这基本上就是团队中有一个单独的球员比一个普通替补球员好多少。这是衡量一个玩家成功的一个很好的标准。

目前联盟中球员的平均 VORP(仅显示至少有 10 名 NBA 球员的州)

加州拥有最高的平均 VORP,拥有哈登、威斯布鲁克、利拉德、伦纳德、控卫等大牌球员。佛罗里达州目前最低。如果这是 2000 年代初,在文斯·卡特的领导下,FL 会更高。

接下来,我们来看看哪些状态更倾向于产生进攻型或防守型的球员。下面是进攻获胜份额(OWS)和防守获胜份额(DWS) 之间的平均差异,这是分别衡量球员进攻和防守贡献的良好指标。更红的颜色意味着更多关注 OWS,更蓝的颜色意味着更多关注 DWS。

OWS 和 DWS 之间的差异(仅显示至少有 10 名 NBA 球员的州)

来自加州的 NBA 球员更注重进攻,鉴于上面列出的一些名字,这是有道理的,因为 VORP 倾向于进攻。纽约最注重防守,有安德烈·德拉蒙德和丹尼·格伦这样的球员。

大学对 NBA 的贡献

我们来看看目前 NBA 各学院的球员数量。

目前 NBA 球员最多的大学

肯塔基州和杜克大学遥遥领先,北卡罗莱纳州位居第三。

举例来说,虽然杜克大学在 NBA 有许多球员,但在普通 VORP,这些球员并不公平。(我不得不指出这一点,因为我是北卡罗来纳州的校友)

目前 NBA 球员的平均 VORP

肯巴·沃克和安德烈·德拉蒙德贡献了康尼提库的大部分 VORP。虽然肯塔基有顶级球员,如 AD,Bam Adebayo 和 Karl-Anthony Towns,但也有许多低于标准的球员拉低了平均水平。

比较球员的防守和进攻能力总是很有趣的,让我们为大学目前的 NBA 球员做这件事。

目前在联盟中的 NBA 球员 OWS 和 DWS 的区别

维克森林大学的差异最大,这意味着这所大学的 NBA 球员更倾向于进攻而不是防守。克里斯·保罗是这里最大的贡献者。德雷蒙德·格林对密执安州的贡献最大,比 DWS 高。德雷蒙德·格林是一个很难分析的球员,但他无疑是防守方面的大师之一。

哈登 vs …?

詹姆斯·哈登被认为是有史以来最好的 NBA 球员之一。然而,他也被认为缺乏一些防守能力。在过去的一个赛季中,还有一名 NBA 球员比哈登更擅长投篮而不是盖帽。

OWS 和 DWS 差距最大的球员(高等 OWS)

达米恩·利拉德在 OWS 和 DWS 的得分高达 8.1 分。而哈登得到了 5.6 分。下降继续与德马尔·德罗赞,然后平滑。数据不会说谎,利拉德的 DWS 比哈登低得多,OWS 也只比他好一点点。

主场优势;有多重要?

现在来看一个有趣的统计数据。主场优势是否存在。让我们看看过去这个赛季排名前 5 和排名后 5 的球队的客队和主场胜率。

前 5 名球队客队主场胜率

垫底的 5 支球队客队主场胜率

前五名中的两个队和后五名中的两个队实际上在客场比在主场表现得更好。总的来说,10 / 30 球队在客场比赛时表现更好。因此,大多数球队的大部分胜利确实发生在主场,但差距不是很大。主场优势确实存在,但没有一些人想象的那么重要。

谁的工资太高了?而且太少?

首先,看看哪些职位的平均工资更高。你可能会猜大前锋有詹尼斯,勒布朗詹姆斯和阿德这样的伟大球员。或者和斯蒂芬库里、威斯布鲁克、利拉德一起做控卫。但实际上是…中心!

每个职位的工资

在 17-18 赛季,中锋的平均工资接近 800 万美元。而控卫的平均年薪是 550 万美元。怎么回事?

  1. 打中锋的低薪球员比其他所有位置都少,尤其是控球后卫
  2. “中间”中锋比所有其他位置的中场球员工资高

接下来,我测量了高级玩家数据和薪水之间的皮尔森相关性,发现胜率(WS)和 VORP 与玩家薪水的相关性更强。

又发现了一个重要的东西…而且是令人不安的。在 17-18 赛季,斯蒂芬·库里(红圈)不仅收入最高,而且远远高于他的 WS 和 VORP 的平均水平。下面的趋势线显示了他与预测的差距。

WS 和 VORP 的趋势线

詹姆斯·哈登(紫圈)的报酬刚刚好。卡尔-安东尼·唐斯(蓝圈)因其对球队的贡献而被非法低薪(不幸的是,是森林狼)。他拥有比库里更高的 WS 和 VORP,但得到的报酬却少得多。

这只是显示了更多的球队重视进攻而不是防守球员。

模型

现在让我们看看是否可以建立一个模型来预测哪支球队将在比赛中获胜。我收集了过去 5 个赛季所有的常规赛。这种型号不会是猛禽,但这是一个开始。

首先,让我们建立一个简单的基线模型,预测获胜者是在给定的赛季中赢得更多胜利的球队。换句话说,这个模型从不预测“冷门”。有了这个简单的衡量标准,70%的情况下可以找到赢家。

现在来看看这个模型。每行包含

  • 每支球队在那场比赛之前的胜败次数
  • 客队必须走多远(距离和高度)
  • 如果那场比赛的先发球员(过去 5 场比赛的连续先发球员)已经被更换
  • 每个团队的高级团队统计数据,如速度
  • 各队先发球员的高级球员统计,如、WSBPM

这些数据有点不真实,因为球队和球员的高级统计数据实际上是那个赛季结束时的总统计数据。不幸的是,这是我能很容易找到的,然而,另一种选择是实际计算每个统计的总数,直到当前游戏与nba.com

我使用 XGBoost 并对多个超参数进行网格搜索。我能得到的最好的性能是大约70%5 重交叉验证。这和基线一样好。这意味着即使有了所有这些先进的统计数据,也无法制造出更好的模型。这可能有两个原因。要么是这些数据中缺少了某些更细微的变量,而这些变量可以更好地预测赢家,要么是方差太高了。让我们探索更多:

最重要的特性如下所示,按增益计算。

基于模型使用的增益的前 10 名

最好的特点是球队的净评分。被支点分析定义为“一个特定球员在场上时,球队的好坏程度有多大】。其他先进的统计数据对首发球员和整个球队都很重要。值得注意的是,特殊变量,如客队必须走多远,以及球队是否有首发变化,根本没有被模型使用,因为它们没有收益。

模型和无扰动基线之间的预测有多相似?

有些相似;这个模型和他们预测的 82% 上的基线相符。因此,在大多数情况下,该模型也预测不发生镦粗,但有 18%的情况下它会预测镦粗。然而,它仍然没有表现得更好。此外,无论预测结果是否正确,该模型都是最不自信的。试着训练一个只针对不正常情况的模型,并将其与基线相结合,以获得更好的结果。

如果我们去掉低信心预测会怎么样?

如果我们尝试去除置信区间低于 0.1 的预测,准确率会从 70%72% 。因此,该模型对其不正确的预测相当自信。

这只是对这些数据的初步尝试。鉴于 NBA 已经提供的所有数据,还有很多要探索的!还有更多的模型要制作。查看回购并为自己做一些探索。

NDArray — —一个基于 Java 的 N 维数组工具包

原文:https://towardsdatascience.com/ndarray-a-java-based-n-dim-array-toolkit-60b4035b10b8?source=collection_archive---------15-----------------------

DJL,一个引擎无关的深度学习库

来源

介绍

在许多开发语言中,有一个使用 N 维数组的流行范例。它们允许您编写数字代码,否则只需几个简单的操作就可以完成许多层次的嵌套循环。由于并行化的能力,它的运行速度甚至比标准循环还要快。这现在是数据科学、图形和深度学习等许多领域的标准实践,但可以用于远远超出这一范围的应用。

在 Python 中,NDArrays 的标准库叫做 NumPy。然而,在 Java 中没有等价的标准库。AWS 的深度 Java 库(DJL) 为有兴趣使用 NDArrays 的 Java 开发者提供了一个产品。虽然它也包含深度学习,但核心是一个强大的 NDArray 系统,它可以单独使用,将这种范式引入 Java。借助对多个深度学习框架(PyTorch、TensorFlow、MXNet)的支持,DJL 可以允许 NDArray 操作大规模跨多个平台运行。不管你运行的是 CPU 还是 GPU,PC 还是 Android,都简单好用。

在本教程中,我们将介绍如何利用 DJL 的 NDArray 用 Java 编写 NumPy 代码,并将 NDArray 应用到现实世界的应用程序中。

设置

您可以在 gradle 项目中使用以下配置。或者,您可以跳过设置,直接在我们的 交互式在线控制台中尝试。

plugins {
    id 'java'
}
repositories {                           
    jcenter()
}
dependencies {
    implementation "ai.djl:api:0.6.0"
    // PyTorch
    runtimeOnly "ai.djl.pytorch:pytorch-engine:0.6.0"
    runtimeOnly "ai.djl.pytorch:pytorch-native-auto:1.5.0"
}

就这样,现在我们可以开始实现了。

基本操作

让我们首先创建一个 try 块来为我们的代码创建一个作用域(如果您使用的是交互式控制台,可以跳过这一步):

try(NDManager manager = NDManager.newBaseManager()) {
}

NDManager 帮助管理n arrays的内存使用。它创造了它们,也有助于清除它们。使用完 NDManager 后,它还会清除在其作用域内创建的所有 NDArrays。NDManager 通过跟踪 NDArray 的使用情况,帮助整个系统高效地利用内存。

为了比较,让我们看看 Python 的 NumPy 中的代码是什么样子。我们将从导入带有标准别名的 NumPy 库开始。

import NumPy as np

在下面的部分中,我们将比较 NumPy 和 DJL 的 NDArray 的实现和结果。

n 阵列创建

ones是生成用 1 填充的 N 维数组的操作。
数字

nd = np.ones((2, 3))

[[1. 1. 1.]
[1. 1. 1.]]

恩达雷

NDArray nd = manager.ones(new Shape(2, 3));
/*
ND: (2, 3) cpu() float32
[[1., 1., 1.],
 [1., 1., 1.],
]
*/

你也可以尝试随机生成。例如,我们将生成从 0 到 1 的随机均匀数据。

NumPy

nd = np.random.uniform(0, 1, (1, 1, 4))
# [[[0.7034806  0.85115891 0.63903668 0.39386125]]]

恩达雷

NDArray nd = manager.randomUniform(0, 1, new Shape(1, 1, 4));
/*
ND: (1, 1, 4) cpu() float32
[[[0.932 , 0.7686, 0.2031, 0.7468],
 ],
]
*/

这只是一些常用函数的快速演示。NDManager 现在提供了超过 20 种数组创建方法,涵盖了 NumPy 中大多数可用的方法。

数学运算

我们还可以使用 NDArrays 尝试一些数学运算。假设我们试图做一个转置并给 NDArray 的每个元素加一个数。我们可以通过执行以下操作来实现这一点:

NumPy

nd = np.arange(1, 10).reshape(3, 3)
nd = nd.transpose()
nd = nd + 10

[[11 14 17]
[12 15 18]
[13 16 19]]

恩达雷

NDArray nd = manager.arange(1, 10).reshape(3, 3);
nd = nd.transpose();
nd = nd.add(10);
/*
ND: (3, 3) cpu() int32
[[11, 14, 17],
 [12, 15, 18],
 [13, 16, 19],
]
*/

DJL 现在支持超过 60 种不同的 NumPy 数学方法,涵盖了大多数基本和高级数学函数。

获取和设置

NDArray 最强大的特性之一是其灵活的数据索引,这是受 NumPy 中类似特性的启发。

假设我们要过滤矩阵中所有小于 10 的值。

NumPy

nd = np.arange(5, 14)
nd = nd[nd >= 10]
# [10 11 12 13]

NDArray:

NDArray nd = manager.arange(5, 14);
nd = nd.get(nd.gte(10));
/*
ND: (4) cpu() int32
[10, 11, 12, 13]
*/

现在让我们尝试做一些更复杂的事情。假设我们有一个 3x3 的矩阵,我们想把第二列乘以 2。

NumPy

nd = np.arange(1, 10).reshape(3, 3)
nd[:, 1] *= 2

[[ 1 4 3]
[ 4 10 6]
[ 7 16 9]]

恩达雷

NDArray nd = manager.arange(1, 10).reshape(3, 3);
nd.set(new NDIndex(":, 1"), array -> array.mul(2));
/*
ND: (3, 3) cpu() int32
[[ 1,  4,  3],
 [ 4, 10,  6],
 [ 7, 16,  9],
]
*/

在上面的例子中,我们在 Java 中引入了一个叫做 NDIndex 的概念。它反映了 NumPy 支持的大多数 NDArray get/set 功能。通过简单地传递一个字符串表示,开发人员可以在 Java 中无缝地进行各种数组操作。

真实世界应用

当我们需要操作一个巨大的数据集时,这些操作非常有用。让我们看一个具体的用例:令牌分类。在这种情况下,开发人员试图通过对其应用深度学习算法,对他们从用户那里收集的文本信息进行情感分析。在预处理和后处理中应用 n 阵列运算来编码和解码信息。

标记化

在将数据输入到 NDArray 之前,我们将输入文本标记为数字。下面代码块中的tokenizer是一个Map<String, Integer>,它作为一个词汇表将文本转换成相应的向量。

String text = "The rabbit cross the street and kick the fox";
String[] tokens = text.toLowerCase().split(" ");
int[] vector = new int[tokens.length];
/*
String[9] { "the", "rabbit", "cross", "the", "street",
"and", "kick", "the", "fox" }
*/
for (int i = 0; i < tokens.length; i++) {
    vector[i] = tokenizer.get(tokens[i]);
}
vector
/*
int[9] { 1, 6, 5, 1, 3, 2, 8, 1, 12 }
*/

处理

之后,我们创建一个NDArray。为了进一步进行,我们需要创建一批令牌,并对它们应用一些转换。

NDArray array = manager.create(vector);
array = array.reshape(new Shape(vector.length, 1)); // form a batch
array = array.div(10.0);
/*
ND: (9, 1) cpu() float64
[[0.1],
 [0.6],
 [0.5],
 [0.1],
 [0.3],
 [0.2],
 [0.8],
 [0.1],
 [1.2],
]
*/

然后,我们可以将这些数据发送给深度学习模型。用纯 Java 实现同样的事情需要更多的工作。如果我们试图实现上面的整形函数,我们需要在 Java 中创建一个 N 维数组,看起来像:List<List<List<...List<Float>...>>>来覆盖所有不同的维度。然后,我们必须动态地插入一个新的包含元素的List<Float>来构建结果数据结构。

为什么要用 NDArray?

通过前面的演练,您应该有了在 Java 中使用 NDArray 的基本经验。总而言之,使用它有三个主要优势:

  • 简单:通过简单的输入和相同的输出访问 60 多个 Java 操作符。
  • 快速:完全支持最常用的深度学习框架,包括 TensorFlow、PyTorch 和 MXNet。现在,你可以让你的计算在 CPU 上被 MKLDNN 加速,在 GPU 上被 CUDA 加速等等。
  • 深度学习就绪:支持高维数组和稀疏 n 数组输入*。您可以在所有平台上应用这个工具包,包括 Apache Spark 和 Apache Beam,用于大规模数据处理。它是数据预处理和后处理的完美工具。

*Sparse 目前仅涵盖 PyTorch 中的首席运营官和 MXNet 中的 CSR/Row_Sparse。

关于恩达里和 DJL

在尝试了 NDArray 的创建和操作之后,你可能想知道 DJL 是如何实现 NDArray 来实现这些行为的。在本节中,我们将简要介绍 NDArray 的体系结构。

NDArray 建筑

如上所示,NDArray 有三个关键层。接口层包含 NDArray,它是一个 Java 接口,定义了 NDArray 应该是什么样子。我们仔细评估了它,并使所有函数的签名足够通用和易于使用。

在 EngineProvider 层,有不同引擎对 NDArray 的实现。这一层充当解释层,将引擎特定的行为映射到 NumPy 行为。因此,所有引擎实现的行为方式都与 NumPy 相同。

在 C++层,我们构建了 JNI 和 JNA 这两个公开 C++方法供 Java 调用。这将确保我们有足够的方法来构建整个 NDArray 堆栈。此外,由于所有引擎都是在 C/C++中实现的,因此它通过直接从 Java 调用 C++来确保最佳性能。

关于 DJL

深度 Java 库(DJL) 是一个用 Java 编写的深度学习框架,同时支持训练和推理。DJL 建立在现代深度学习框架(TenserFlow、PyTorch、MXNet 等)之上。您可以轻松地使用 DJL 来训练您的模型或部署您喜爱的模型从各种引擎,没有任何额外的转换。它包含一个强大的 ModelZoo 设计,允许您管理训练好的模型并在一行中加载它们。内置的 ModelZoo 目前支持来自 GluonCV、HuggingFace、TorchHub 和 Keras 的 70 多个预训练和随时可用的模型。NDArray 的加入使 DJL 成为 Java 中运行深度学习应用程序的最佳工具包。它可以自动识别您运行的平台,并判断是否利用 GPU 来运行您的应用程序。

从最新发布的版本来看,DJL 0.6.0 正式支持 MXNet 1.7.0、PyTorch 1.5.0 和 TensorFlow 2.2.0。我们在 Android 上也有 PyTorch 的实验支持。

关注我们的 GitHub演示库Slack channeltwitter 获取更多文档和 DJL 的例子!

用遗传算法提高你的成功的巧妙技巧

原文:https://towardsdatascience.com/neat-tricks-to-boost-your-genetic-algorithms-86eb6d5f13dd?source=collection_archive---------36-----------------------

如何与时俱进,用您的 GA 魔力给其他数据科学家留下深刻印象

国家癌症研究所Unsplash 上拍摄的照片

遗传算法(或称进化算法)——一种简单但非常强大的优化技术,最近又重新流行起来。从进化强化学习模型神经架构搜索,或者简单的特征选择,遗传算法(以下简称为 g a)甚至为最复杂的深度学习提供了一个强有力的竞争者——甚至大牌,如优步谷歌,都在尝试 GA。

如果您是 GA 新手,您可能会发现这篇文章很有用。

[## 遗传算法简介—包括示例代码

遗传算法是一种受查尔斯·达尔文的自然进化理论启发的搜索启发式算法。这个…

towardsdatascience.com](/introduction-to-genetic-algorithms-including-example-code-e396e98d8bf3)

不管 GA 有多强大,它也不是没有缺点。事实是,GA 实现起来非常简单,但掌握起来却非常困难。尝试 GA 的新数据科学家经常会发现他们因陷入局部极小值、多样性问题和过度拟合而感到沮丧。这通常会导致完全放弃 GA,这是非常不幸的。

因此,我将分享一些我学到的小技巧(学到的?)并成功实施到我的工作流程中。

1.随机环境

你知道该怎么做。你设置奖励函数(或适应函数或 KPI 或其他)。你倾尽所有的数据,开始遗传算法。喝了几杯咖啡后,你回到电脑前,却发现遗传算法的解决方案过于简单,基本上没有用。

接下来你要做的是将数据分成训练集和测试集。您将改进您的解决方案,并每 X 次迭代检查一次测试集。然后,您会注意到在测试集上找到的最佳解决方案。

你以为你已经搞定了。你去喝了更多的咖啡。几个小时后,你回来看到测试集上的分数基本上是一条下降线。遗传算法学习适应训练集中的噪声,测试集上的最佳解决方案来自早期迭代,得分平平。

现在你陷入了进退两难的境地。

嗯,我估计 90%都是因为这个问题而放弃使用 GA 的。

GA 实现对于无噪声数据或高 SNR 数据工作良好。但是当你的数据非常嘈杂时,坦白地说,这几乎是所有有趣的数据,遗传算法只是锁定噪声,就像你的宠物的皮毛锁定你的衣服一样。

让我头疼了几个星期后,我找到了解决办法。我给 GA 一个随机子集,而不是让 GA 针对所有数据评估解(染色体)。所以,环境现在是动态的。GA 将在第一轮中用 10%的数据评估其群体。然后,经过选择和交叉,我将通过随机选择不同的 10%的数据来创建一个新的环境。GA 现在必须根据这个新的子集来评估群体。由于环境的变化,在第一轮中表现良好的染色体可能在第二轮中被丢弃。

我还记录了每条染色体的年龄。我的适应度函数会根据每个染色体存活的时间给出一个小奖励。使用这种方法,我鼓励 GA 找到一个通用的解决方案。

2.压力测试

这个基本上是上面解决方案的扩展。在金融领域,压力测试意味着模拟一个金融实体,比如银行,在经济低迷时期的表现。因此,我采用了类似的 GA 方法。我会准备一个压力测试数据集。这个数据集将与主数据集非常不同。压力测试数据可能大多是异常值,或者是在现实生活中发生几率非常低的模拟数据。

这个想法是为了看看哪条染色体可以在非常紧张的情况下坚持下来——这是你通常不会想到的情况。每隔一段时间,我就会把压力测试数据扔给 GA。然后我会丢弃大部分染色体。这类似于小行星消灭恐龙。它为新的生命形式提供了一个滋生的土壤,并清洗了那些“太习惯旧方式”的人

3.新颖性搜索

我相信进化出解决方案,然后发现所有的染色体在后来的迭代中几乎都是一样的,这并不罕见。这样做的问题是双重的——这导致基因库缺乏多样性,GA 很容易陷入局部极小值。为了补救这一点,有一个巧妙的技巧叫做新奇搜索。

简而言之,你应该考虑每条染色体的独特性,而不是只选择表现最好的染色体。有几种方法可以实现这一点——给含有稀有基因的染色体加分,给含有未知基因的染色体分配额外的配额,选择更多含有不同基因的染色体,等等。

关键的想法是,具有独特基因(参数值)的染色体应该得到更多的考虑,因为它们将为基因库带来更多的多样性,并使你摆脱那个局部最小值。

4.精心打造你的健身功能

我想很多人可能都知道这一点,但是让我强调一下——小心你要的东西。许多新手对适应度函数采取了一种简单化的方法,这可能会失败得很惨。

想象一下,开发一辆自动驾驶汽车,你的奖励(健身)功能是最大限度地减少旅行时间。你可以肯定这辆车会像《速度与激情》中的演员一样驾驶——因为你忘记了包括其他方面,如违反交通法,乘客舒适和安全,等等。

休息一下。睡一觉。好吧,睡上几个晚上吧。良好的健身功能会让你免去很多头疼的事情。

也许,你应该惩罚解决方案中的复杂性?给一致性加分怎么样?有很多事情需要深思。

我希望这个指南能帮助你在 GA 土地上的冒险。

快乐进化!

参考

[1] Paras Chopra,无梯度强化学习:使用遗传算法进化智能体 (2019)

[2]亚楠等,用遗传算法自动设计 CNN 结构用于图像分类 (2020),IEEE 控制论汇刊

[3] Edoardo 等人,通过一群寻求新奇的代理人改进深度强化学习进化策略的探索 (2017),优步人工智能实验室

[4] Esteban Real,使用进化 AutoML 发现神经网络架构 (2018,谷歌大脑团队

需要测量分布——范围、方差、标准差

原文:https://towardsdatascience.com/need-for-measures-of-spread-range-variance-standard-deviation-28bc21e6f0ac?source=collection_archive---------49-----------------------

当集中趋势不足以区分数据集时

菲德尔·费尔南多在 Unsplash 上的照片

如果有人给你下图所示的五个数据集的 1 位数摘要(集中趋势),在你看来,你会认为它们都是相同的,因为它们的平均值是相同的,但当你绘制每个数据集的每个数据点并对它们进行视觉比较时,你会意识到应该有一种方法来检测这种不同的模式。

(图片由作者提供)

向价差测量值——范围/方差/标准差打招呼

参考之前博客中使用的相同数据:

[## 均值、中值和众数——何时使用哪个集中趋势指标?

为了将数据表示为 1 个数字的摘要,我们使用集中趋势度量来这样做。存在三个主要趋势…

towardsdatascience.com](/mean-median-mode-which-central-tendency-measure-to-use-when-9fb3ebbe3006)

范围

数据集的最快传播度量是范围。我们从数据集中取出最大值和最小值,然后相减得到范围。

(图片由作者提供)

(本博客假设数据为人口数据)*

差异

对于这项措施,我们将不得不回去参考,让我们回忆一下以前提到的一些想法。如前所述,当绘制在数轴上时,这些数字只不过是距离原点的距离。

(图片由作者提供)

让我们再取一个数据集,其中有 7 个数据点具有相同的值(即我们的父数据集的平均值)。

(图片由作者提供)

父数据集= 150,155,160,160,170,175,180(单位均为厘米)

新数据集= 164.3、164.3、164.3、164.3、164.3、164.3、164.3(均以厘米为单位)

现在,我们将计算两个数据集到原点的平均平方距离:

差值= 27092.85–26994.49 = 98.36 平方厘米

两个数据集的这两个测量值之间有明显的差异,但如果我们将参考值从原点改为均值,我们会发现:

你现在也会同意,事情在参考和输出价值方面变得更好了,再次可视化它们将导致进一步的清晰:

(图片由作者提供)

标准偏差

您可能已经注意到,方差输出的单位是 cm2 &如果我们想要一个具有相似均值参考但使用原始单位(cm)的分布度量,那么我们需要做的就是求方差的平方根。这就是标准差。

  • 注意—以上完成的所有计算都假设数据集为群体集。讨论最多的&辩论主题与此类测量的分母相关,即为什么样本为 N-1,为什么总体为 N,将在以后的博客中解释。

有了 2 个数字的汇总(集中趋势和扩散),我们可以更好地区分数据集,并记住每个统计测量都有其服务的目的。这些度量标准是为了捕捉现有度量标准没有捕捉到的细节。在接下来的博客中,你会注意到需要使用更多的统计方法来捕捉更多可提取的细节。就这样,我在这里结束这个咀嚼,期待在未来分享更多的博客。

谢谢!!!

需要在仪表板上强调变化吗?忘记条形图,用哑铃图代替!

原文:https://towardsdatascience.com/need-to-emphasize-change-in-your-dashboard-forget-bar-charts-use-dumbbell-charts-instead-84b97c591f12?source=collection_archive---------28-----------------------

哑铃图易于构建和理解,对于商业受众来说是一种很好的替代图表类型。

尼科埃尔尼诺在 iStockphoto 拍摄的图像

在设计仪表板和其他数据可视化时,图表类型的选择是一个关键的工具,你可以用它来让你的观众关注最重要的信息。尤其是仪表盘,信息丰富。减少你的听众提取关键信息所需的工作量会使他们更加有效和强大。

条形图是数据可视化的主要工具。它们是所有图表类型中最容易理解的,并且能够准确无误地描述变化(假设坐标轴总是从零开始——你只会犯一次新手的错误!反馈是一种天赋,对吗?!).

在仪表板中,任务通常是比较数值——今年与去年,实际值与目标值,等等。大多数软件工具引导我们使用的默认图表类型是簇状柱形图。这是一个不错的选择,但是随着类别数量的增加,它会很快失控…

簇状条形图虽然继承了条形图的许多优点,但并不是比较数值的最有效的图表。为什么?考虑上面的图表,为了了解今年与去年相比的情况,我需要根据每个条形的长度读取条形的值,将其与条形对进行比较,并保留该信息,同时对下一个条形对、下一个条形对等等进行同样的操作。很快我就要记住 24 个数字和 12 个不同点。我不知道你怎么想,但我努力在脑子里记住这么多信息。更不用说处理它来理解是否有某种模式。

我需要的是一个图表类型,重点是在价值的差异。我可以画出这两个值之间的差异,但是如果绝对值对观众很重要,而我们又不想失去这些信息,该怎么办呢?在这里,哑铃图表成为一个伟大的选择。

对商业和非技术受众使用替代图表类型总会有一些风险,但幸运的是哑铃图表不会对大脑造成太大的压力。哑铃图表的伟大之处在于,它允许你:

  • 保留关于绝对值的信息
  • 垂直轴从非零值开始(意味着您可以突出显示微小的变化),并且
  • 通过连接这些点,观众本能地关注它们之间的距离(这是你的图表的要点!).

有什么不喜欢的?但是如果您坚持使用不提供这种图表类型的 Excel 呢?没问题,它们构造起来超级简单。

循序渐进

  1. 首先用标记构建一个折线图。

2.增加标记大小,删除连接线,并根据您的意愿设置样式。我喜欢直接标记系列,而不是使用图例,因为这样更有效。

3.现在插入高低点线,方法是选择一个系列,然后在功能区的图表工具>设计部分单击“添加图表元素”。悬停在“线”上将显示“高低线”选项。点击就大功告成了!

4.晒晒你的老板和同事的赞赏吧!

想更刺激一点吗?

通过直接标记标记而不是使用轴来获得极简的外观。看啊…

这里没有文本框…使用数据标签对你有利。添加数据标签,使用“中心”标签位置,并根据需要设置它们的样式。

你从来不知道你可以像那样使用数据标签,是吗?!

需要为您的 Python 分析准备一个演示站点吗?想想 Heroku+Flask/Dash

原文:https://towardsdatascience.com/need-to-prepare-a-demo-site-for-your-analysis-on-python-think-of-heroku-flask-dash-f8680a859105?source=collection_archive---------45-----------------------

从 Hello World 开始的初学者演练

有一天,当我为一个概念验证项目制作一个数据科学 web 应用程序时,我意识到如何部署该应用程序并不一定是显而易见的。我希望该应用程序能够:

  • 全天候运行并提供演示,
  • 呈现在任何可通过互联网访问的设备上,以及
  • 不像生产应用程序部署那样需要太多的成本和精力。

我最终发现使用“Heroku”以及 python 的 web 框架库(如“Flask”或“Dash ”)最符合我的预期。

在这篇文章中,我将总结一下我当时学到的东西:我们如何配置 Heroku+Flask/Dash app,从 Hello World 到一个专业的例子。

目录:

  1. 你如何为你的 Web 应用建立演示环境?
  2. 烧瓶和 Dash 是什么?
  3. 应用程序部署练习 1:仅限烧瓶——向自己问好
  4. App 部署练习 2:Heroku+Flask——向世界“你好世界”
  5. 应用部署练习 3: Heroku + Dash —显示带有动态过滤的 Iris 数据表
  6. 应用部署练习 4: Heroku + Dash —专业示例
  7. 结尾注释

本杰明·蔡尔德Unsplash 上的照片

1.你如何为你的 Web 应用建立演示环境?

假设您刚刚在 Python 上构建了一个 web 应用程序作为 PoC 工作(因此,作为一名数据科学家,我在这里设想了一个数据科学应用程序(例如,data dashboard),但可能同样适用于任何应用程序),并希望在许多演示机会中演示它,例如讲台演示、投资者推介或网络聚会。

作者用免费插图网站“IRA suto-ya”(【https://www.irasutoya.com/】T4)的材料制作的插图

您所期望的是:

  • 你想在任何设备上看到它,以便你的同事或客户访问该应用程序并四处游玩,
  • 您希望它全天候运行,并且
  • 尽管如此,因为它不是一个生产应用程序,而是一个概念验证阶段,所以您希望在部署它时尽量减少开发本身的额外工作。

现在,让我们看看 web 应用程序部署中的三个可能的例子。

1.1。将应用程序保存在您的电脑上

作者使用免费插图网站“IRA suto-ya”(https://www.irasutoya.com/)的材料制作的插图

在这里,您在 PC 上开发应用程序,并在同一台 PC 上进行部署(类似的案例研究在下面的“应用程序部署练习 1:仅 Flask—“Hello World”to Yourself”中)。

优点:

  • 应用程序开发后没有额外的操作。

缺点:

  • 除了你没有其他人可以进入。

在这种情况下,你的客户体验应用程序的唯一方式就是你从你的电脑上展示它。

1.2。准备一台服务器 PC 并在其上部署应用程序

作者使用免费插图网站“IRA suto-ya”(【https://www.irasutoya.com/】)的材料和 GitHub 的官方徽标制作的图形

在这种情况下,您需要准备自己的服务器(本地或云实例)并在其上部署应用程序。

优点:

  • 高灵活性和对部署环境的控制。

缺点:

  • 必须自己管理两个机器环境。一个部署将需要,从您的开发环境推送到存储库,从存储库拉到服务器,在服务器上配置和运行它。
  • 维护服务器的额外成本。

在这种类型中,您花费更多的时间和金钱,但对部署环境有更高的控制力。您可以授予外部用户访问权限,也可以阻止其中一些用户。

但是,由于这种类型是针对生产架构的,如果您只想在较短的时间内演示您的 PoC 工作,而不是针对永久运行的生产线,这就太多了。

1.3.使用 heroku 进行部署

作者使用免费插图网站“IRA suto-ya”(https://www.irasutoya.com/)的材料以及 GitHub 和 Heroku 的官方标志制作的图形

这里我要介绍一下Heroku。****

Heroku 是一个基于网络的服务,用来取代以前架构的服务器部分。一旦它通过您的应用程序连接到您的 GitHub 存储库,它会自动从 GitHub 中提取您的模型,并将其部署到互联网上添加唯一的 URL,而您只需进行最少的配置(我们将在下面的应用程序开发练习 4–6中看到这一点!)应用程序的更新以同样的方式发生:一旦你将新代码推送到 GitHub 存储库,heroku 会检测到变化并自动更新部署。**

还有,对于非制作级别的 app,不用花钱!

优点:

  • 比服务器选项更少的配置和维护负担。

缺点:

  • 对配置的控制不如服务器选项。因此,不适用于生产应用程序。

2.烧瓶和 Dash 是什么?

我还要提一下【Flask】【Dash】,这些在 Python web app 构建中非常有用,我在下面的 App 部署练习中使用过。

Flask 和 Dash 的官方标志

“Flask”是一个 python 库,提供微 web 框架,通过 python 编码支持 web 应用的开发。Flask 可以提供你用 python 代码编写的动态应用程序的 web 内容。由于 python 相对于其他语言的优势是易于机器学习建模,所以大量使用 Flask 来创建 web API 以返回 ML 模型预测。

Flask 很好地提供了动态 web 组件,但它本身在视觉上并不漂亮。为了使它更漂亮,我们需要 html 模板和 CSS 文件都编码良好。

" Dash "是另一个让美化视觉更容易的 web 框架。它在 python/R/Julia 中可用,构建在 Flask、plotly 或其他库之上。与 Flask 相比,它更专注于数据科学仪表板 UI,并提供了许多内置道具,使应用程序更漂亮。

仪表板上的数据仪表板示例(https://dash-gallery.plotly.host/dash-oil-and-gas/)

3.应用程序部署练习 1:仅限烧瓶——向自己问好

3.1。安装烧瓶。

3.2。准备 app_helloworld.py 代码。

3.3。运行 app_ hello world. py .

3.4。去网络浏览器找到“你好世界!”。

在这里,我们现在尝试在您的本地机器上运行一个简单的 Flask 应用程序。如果你的应用不能在本地运行,它将永远不能在 heroku 上运行!该应用程序将显示“Hello World!”在你的浏览器上。

3.1.

首先,通过在终端上运行以下命令,在本地计算机上安装 Flask:

**$ pip install Flask**

3.2.

接下来,准备一个名为 app_helloworld.py 的. py 文件,如下所示:

“app”是 Flask 类的一个实例,它在代码中充当 WSGI@app.route('/')是另一个告诉 Flask 哪个 URL 将触发函数index的神奇代码。函数index将打印“你好,世界!”。最后两行定义了当我们通过终端运行这个文件时的行为。

进一步的解释可以参考烧瓶快速启动页面

3.3.

最后,在您的终端上运行以下程序:

**$ cd <path where you placed app_helloworld.py>
$ python app_helloworld.py**

您将在终端上看到这一行。

3.4.

转到您的 web 浏览器,在 URL 单元格中键入127.0.0.1:5000(显示的 IP 地址)或localhost:5000。然后,你会看到这个:

成功!

但是,你必须记住一些缺点:

  • 127.0.0.1是私人 IP 和《Hello World 仅在您的电脑上可见。你永远不会在你的智能手机或客户的机器上看到同样的东西。
  • 将你的电脑关机或甚至进入睡眠模式将会或可能会停止应用程序。你必须重新运行代码来保持“Hello World!”活着的东西。

这就是为什么我们需要后端服务器功能来在任何机器上全天候供应应用程序。“heroku”将帮助我们做到这一点。

4.App 部署练习 2:heroku+Flask——向世界“你好世界”

4.1.确保你能运行“Hello World!”否则,请回到上一节。

4.2.准备另外两个关键文件:“requirements.txt”和“Procfile”。

4.3.做一个 GitHub 库,推送准备好的文件。

4.4.配置 heroku 在上面运行和部署应用程序。

4.5.去(任何)网络浏览器找到“你好世界!”。

4.6.(可选)查看当您将代码推送到 GitHub 时,app deploy 是如何更新的。

我们现在想要做的是将应用程序移动到 heroku 服务器,并保持它全天候(而不是本地)运行(不仅仅是在您的 PC 打开时。)

4.1.

作为先决条件,确保你的 hello world 可以在你的本地电脑上运行。如果没有,请回到上一节。

4.2.

接下来准备两个关键文件:“requirements.txt”和“Procfile”。

“requirements.txt”在您为虚拟环境准备它时具有相同的用途。在“你好世界!”例如,我们需要一个烧瓶,但要添加另一个名为“gunicorn”的烧瓶。

你还记得当你在本地运行 Flask 时得到一个错误信息吗?

**WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.**

使用 gunicorn 是一种解决方案。它将作为 WSGI 服务器工作。

那么,现在 requirements.txt 应该是这样的:

**Flask==1.1.1
gunicorn==19.9.0**

你还需要一个名为‘Procfile’(没有扩展名)的文件来告诉 gunicorn 哪个文件作为应用程序运行。我不解释太多如何写这个文件和你可以参考他们的文件的细节。在我们的 hello world 示例中,以下是“Procfile”中的行:

**web: gunicorn app_helloworld:app**

app_helloworld 是的名称。py 文件在这里。如果您使用不同的名称,请调整它。

4.3.

现在,您准备一个新的 GitHub 存储库,并推送上面准备的三个文件。这是我的例子。

4.4.

现在我们将配置 heroku 环境。

首先创建 heroku 账号。我将跳过如何到这里。

接下来,点击“创建新应用程序”按钮。

决定你的应用程序名称,无论你喜欢什么,但它必须是全球唯一的。然后点击“创建应用”并继续。

选择 Deployment method=GitHub,用你的 app 连接到你的 GitHub 库。

查看您的应用程序是否成功连接到 GitHub 存储库。接下来单击“启用自动部署”,然后单击“部署分支”。

当 heroku 尝试部署时,您会看到一些日志消息。你可以找到烧瓶和 gunicorn 是否安装在 heroku 容器中。

4.5.

当部署成功时,您将看到一个按钮“查看”。当你点击它,一个网页将开始,你可以发现该网页是在唯一的网址。

此 URL 已经全球可用。我可以在手机上看到。

而且只要 heroku app 还活着就可以用。

4.6.

或者,你可以检查当你把你的编辑推送到 GitHub 时,应用程序自动更新的程度。

让我们制作“你好,世界!”到“你好世界!已更新”在您的 app_helloworld.py 中。

一旦你被推送到你的库,heroku 上的自动应用构建就会开始。

构建完成后,您可以刷新页面并立即看到更新后的部署(或在浏览器上经过 TTL 时间后)。

为了更新应用程序,我只将新代码推送到 GitHub。现在,你可以认识到这是多么容易!!

5.应用部署练习 3: heroku + Dash —显示带有动态过滤的 Iris 数据表

5.1.确保您成功运行了之前的“Hello World!”heroku 上的 app。

5.2.准备一个新的。使用破折号的 py 文件。

5.3.编辑配置文件。

5.4.推到 GitHub,等待 heroku 建造。

5.5.在浏览器上打开 app,开心就好。

这个练习不仅仅是 hello world!我们将在 web 应用程序上显示著名的“虹膜数据表”,并允许它根据虹膜类名进行过滤。

5.1.

像往常一样,确保我们都擅长前面的练习。否则,返回并成功运行前面的内容。

5.2.

接下来,准备一个新的。使用破折号的 py 文件。我的例子是一个显示著名的虹膜数据的前 10 行的应用程序,它还允许根据 web 查看者在 web 浏览器上选择的类型来过滤特定的虹膜类型。我的新文件“app_dash_basic.py”在这里:

带破折号的代码在新生眼里看起来很复杂,但是逐行查看,就不一定了。特别是,当你有一些关于 html 的知识时,你会发现它使用了很多 HTML 元素。

5.3.

配置文件需要一些编辑。

就因为我的代码用了破折号和熊猫,requirements.txt 如下:

**Flask==1.1.1
gunicorn==19.9.0
dash==1.12.0
pandas==0.25.1**

Procfile 为:

**web: gunicorn app_dash_basic:server**

注意它使用的是:server而不是:app

不要忘记下载 iris.csv 文件并将其放在本地存储库中。

5.4.

接下来和以前一样,把他们推到 GitHub,等待 heroku 的部署。

********

5.5.

瞧啊。我们现在得到了我们想要的!该应用程序显示 iris.csv 中的前十条记录,还允许动态更改过滤器。

我们可以用相同的网址在你的手机上播放完全相同的歌曲。

6.应用部署练习 4: heroku + Dash —专业示例

6.1.在远程存储库上克隆目标存储库。

6.2.进行相同的部署练习。

6.3.享受 pro 应用程序!

上一节中的 Iris 示例有些廉价,没有展示 Dash 的全部功能。

在这一部分,让我们来看一看你可以在官方 Dash 应用程序库中找到的一个专业示例。

我选择了药物发现的例子。

6.1.

只需找到包含您的目标代码的存储库,将其克隆到您的远程存储库中。只要你只是使用现有的代码,这是一个显而易见的。

********

6.2.

这取决于你在 heroku 中使用的最大应用数量的支付选项,但最有可能的是你删除旧的应用并创建一个新的应用,因为一次只能有一个应用处于活动状态。

接下来,你只需做同样的练习:将 app 连接到你刚刚克隆的 GitHub 库,按下两个按钮,然后等待。

6.3.

给你!

当然,你也可以在手机上享受同样的乐趣。

7.结尾注释

当您想在 PoC 阶段制作一个演示 web 应用程序时,您可能希望它可以通过互联网 URL 获得,但是准备服务器或云实例太多了。“Heroku”是一个强大的选择,可以最大限度地减少这种型号开发的额外成本和负担。

一旦你把你的模型推送到 GitHub,Heroku 会自动检测其中的更新,并更新部署。同样,从金钱的角度来看,小规模部署在 Heroku 是完全免费的。

通过减少部署阶段的成本和工作,您可以将更多精力放在模型/应用程序开发上。

伦敦国际学生的邻里搜索

原文:https://towardsdatascience.com/neighborhood-search-for-international-students-in-london-c5bca67a1e38?source=collection_archive---------51-----------------------

使用 K-Means 聚类算法的数据科学项目

布鲁内尔大学,威盛, flickr (CC BY-NC-ND 2.0)

凭借其世界公认的大学、多元文化的环境和高技能的学术人员,英国在国际学生中的受欢迎程度持续上升。根据高等教育统计局 2018/2019 年的统计数据,485,645 名国际学生在英国攻读学位,其中 125,035 人在首都伦敦学习。

搬到伦敦继续他们的学业,这些国际学生有关于住宿的疑问-一个重要的是“我应该考虑哪个社区的住宿?”在英国找到合适的住房并不容易。尤其是在最受欢迎的大学所在的城市,这使得学生住宿有些繁琐,而且费用昂贵。学生们更喜欢住在离他们的大学近的地方,住在公共交通方便的地方。当我来到伦敦帝国理工学院商学院攻读硕士学位时,我也有同样的问题:哪些街区离大学很近?邻里关系好吗?

在这个项目中,我将通过探索特定大学附近的社区来解决这个问题。该解决方案是为前往伦敦求学的国际学生设计的。该代码可在 GitHub 中获得。

这个项目是从技术背景过渡到数据科学领域的踏脚石,它利用了通过 IBM 数据科学认证课程获得的知识。

数据要求

对于这个项目,我将使用以下数据:

  • 伦敦大学/机构的地理位置数据: 英国学习提供商提供英国所有大学的数据及其地理位置。从这里,我将只提取伦敦大学的这个项目。

显示伦敦学院分布的伦敦地图

  • 伦敦邮政编码:所有伦敦邮政编码及其区和地理数据的列表可在 Doogal.co.uk获得我需要获得邮政编码的前缀,并将它们分组。

  • 公共交通无障碍水平数据:伦敦交通局(TFL-伦敦交通局)开发了一种工具,用于评估伦敦各地公共交通的无障碍水平。公共交通可达性水平(PTAL)评估了到交通站点和车站的步行距离水平,包括测量交通服务水平和更广泛的连通性。这个地区的数据可以在伦敦数据库中找到。每个区域的得分在 0 到 6b 之间,0 分表示公共交通非常差,6b 表示公共交通非常好。

将 PTAL 分数添加到邮政编码数据集中:

  • 距离研究所 5 公里以内的街区: Postcodes.io 提供免费 API,调用该 API 时,会生成一个 JSON,其中包含给定邮政编码 5 公里以内的 outcodes(邮政编码区)数据。我将使用 API 来获取邻域的输出代码。

我已经从我们之前的数据集中选择了第一个学院“皇家兽医学院”,以探索其附近更多的场馆。这所大学方圆 5 公里有 38 个不同的区号。将邮政编码数据添加到机构数据中:

皇家兽医学院周围的 38 个街区

  • 附近的场馆:这个数据是使用 Foursquare API 获得的。利用一个地区的地理位置,我们探索每个社区的顶级场馆。确定了学院周边 38 个区号的 2344 个场馆。对应区域代码的 PTAL 分数得出以下数据集:

方法论

场馆类别和 PTAL 的一键编码:使用一键编码技术为分类变量-场馆类别和 PTAL 分配数值;

然后将编码后的数据集按“区号”分组,得到 38 个区号中每一个的场馆类别和 PTAL 的含义;

获取每个区域代码中排名前 10 的场馆,这将有助于学生了解该区域代码中排名靠前的场馆类别。

K-均值聚类

我想根据场地类别和 PTAL 将我们的区号分组,因此我们使用 K-means 建模技术来得到我们的聚类。

寻找用于训练数据的最佳 k 值:我正在使用肘方法来获得最佳值。下面的第一个图告诉我们,肘点是 3(左),然而,为了证实它,我们创建了另一个图,直到值 6(右)。

使用 k-means =3,将模型拟合到以下数据:

结果

皇家兽医学院周围的 38 个区号分为三组,如下图所示:

  • 蓝色-最高连接性(6b)
  • 洋红色-良好的连接性(6a)
  • 橙色-中等连通性(其他)

第一聚类具有最高 PTAL 分数(6b)的邻居

第二个聚类具有良好的连通性得分(6a)

最终集群具有中等连通性(3,4,5)

聚类技术主要根据 PTAL 评分将社区分为 3 类,该评分评估了到交通站和车站的步行距离水平,包括测量交通服务水平和更广泛的连通性。

基于邻域的连通性对其进行聚类,聚类 0 和 1 比聚类 2 具有最高(6b)和良好(6a)的连通性,聚类 2 具有中等连通性。

一个代表皇家兽医学院周围的邻域分布的条形图清楚地显示了大多数邻域具有最佳的网络连通性,并且将是最可取的位置。

进一步看附近列出的场馆;我们看到大部分街区在饮食点方面分布得很好。基于这些分组,学生可以选择他们喜欢的社区。一个健身爱好者的学生,想住在一个连通性更广的街区,可以在 0 群的 neighborhoods -NW1 3,W1T 7 搜索住宿。

结论

虽然这个项目是为了帮助皇家兽医学院的学生/学生,但也可以扩展到其他学院。该方法不限于机构,也可用于任何探索某个位置(如办公室附近)附近社区的人获得相同的结果。

通过考虑更多因素以获得更精细的输出,可以进一步完善该项目,例如取决于房屋类型的平均租金、每个街区的犯罪率、与大学的平均距离。将这些因素考虑在内将有助于学生确定准确的邻域。大多数学生更喜欢住在离学校近、连通性好、安全的社区。

使用 Foursquare API 进行邻域分割和聚类

原文:https://towardsdatascience.com/neighbourhood-segmentation-and-clustering-using-foursquare-api-c43c113e89fb?source=collection_archive---------23-----------------------

在印度海得拉巴建立购物中心

谁说金钱买不到幸福,谁就不知道去哪里购物。

介绍

对于许多购物者来说,在周末和假期逛商场是放松和享受的好方法。房地产开发商也在利用这一趋势建造更多的购物中心来迎合需求。因此,海得拉巴市有许多购物中心,还有更多正在建设中。开设购物中心可以让房地产开发商获得稳定的租金收入。与任何商业决策一样,开一家新的购物中心需要认真考虑,而且比看起来复杂得多。特别是,购物中心的选址是决定购物中心成败的最重要的决策之一。

商业问题

这个项目的目标是分析和选择在印度海得拉巴市开设新购物中心的最佳地点。该项目主要关注海得拉巴市的地理空间分析,以了解哪个地方是开设新商场的最佳地点。该项目使用数据科学方法和聚类等机器学习技术,旨在提供解决方案来回答这个商业问题:在海德拉巴市,如果一家房地产开发商打算开设一家新的购物中心,你会建议他们在哪里开设?

数据

为了解决这个问题,我们需要以下数据:
·海得拉巴的街区列表。这确定了本项目的范围,该范围限于泰伦加纳的首都海德拉巴市,该市位于印度南部
这些街区的经纬度坐标。这是绘制地图和获取场馆数据
所必需的,场馆数据,尤其是与购物中心相关的数据。我们将使用这些数据对邻近区域进行聚类。

数据来源和提取数据的方法

这个 维基百科页面 是海得拉巴的街区列表,有 200 个街区。在 Python 请求和 beautifulsoup 包的帮助下,我使用 web 抓取技术从维基百科页面中提取数据。然后,我们可以使用 Python 地理编码器包来获取街区的经纬度坐标。之后,我使用 Foursquare API 来获取这些街区的场地数据。

Foursquare API 将提供许多类别的场馆数据,为了帮助我们解决业务问题,我们对购物中心类别特别感兴趣。这是一个将利用许多数据科学技能的项目,从网络抓取(维基百科),使用 API (Foursquare),数据清洗,数据争论,到机器学习(K-means 聚类)和地图可视化(foylus)。

方法学

Foursquare API 允许应用程序开发人员与 Foursquare 平台进行交互。API 本身是一个 RESTful 地址集,您可以向其发送请求,所以实际上没有什么需要下载到您的服务器上。

搜索海得拉巴的咖啡馆

四方返回的咖啡馆

在左边,你可以看到所有的咖啡馆和它们的名字,类别,海得拉巴每个地点的地址。在右边,你可以看到左边的场馆地图。

探索咖啡馆

如果你点击第一个是咖啡杯,那么你会被重定向到这个页面,在这里你会看到 Foursquare 数据集中关于咖啡杯的所有信息。这包括它的名字,完整的地址,工作时间,提示和用户发布的关于咖啡馆的图片。同样,你也可以探索海得拉巴市的购物中心。

要探索 Foursquare,点击 此处

网页抓取

使用 Python 请求和 beautifulsoup 包执行抓取,以提取邻居数据列表。

# Send the GET requestdata = requests.get("[https://en.wikipedia.org/wiki/Category:Neighbourhoods_in_Hyderabad,_India](https://en.wikipedia.org/wiki/Category:Neighbourhoods_in_Hyderabad,_India)").text# Parse data from the html into a beautifulsoup objectsoup = BeautifulSoup(data, 'html.parser')# Create a list to store neighbourhood dataneighborhoodList = []# Append the data into the listfor row in soup.find_all("div", class_="mw-category")[0].findAll("li"):
  neighborhoodList.append(row.text)# Create a new DataFrame from the listkl_df = pd.DataFrame({"Neighborhood": neighborhoodList})
kl_df.head()

这是抓取数据后创建的数据框。为了能够使用 Foursquare API,我们需要获得经纬度形式的地理坐标。为此,我们将使用 Geocoder 包,它允许我们将地址转换为经度和纬度形式的地理坐标。

# Defining a function to get coordinatesdef get_latlng(neighborhood):
    # initialize your variable to None
    lat_lng_coords = None
    # loop until you get the coordinates
    while(lat_lng_coords is None):
        g = geocoder.arcgis('{}, Hyderabad, India'.format(neighborhood))
        lat_lng_coords = g.latlng
    return lat_lng_coords# Call the function to get the coordinates, store in a new list using list comprehensioncoords = [ get_latlng(neighborhood) for neighborhood in kl_df["Neighborhood"].tolist()]

我们已经获得了所有地点的经纬度坐标,因此需要将坐标合并到原始数据框中。

# Create temporary dataframe to populate the coordinates into Latitude and Longitudedf_coords = pd.DataFrame(coords, columns=['Latitude', 'Longitude'])# Merge the coordinates into the original dataframekl_df['Latitude'] = df_coords['Latitude']
kl_df['Longitude'] = df_coords['Longitude']print(kl_df.shape)
kl_df(200,3)

这是包含所有街区和地理坐标的组合数据框。

# Getting the coordinates of Hyderabadaddress = 'Hyderabad, India'
geolocator = Nominatim(user_agent="my-application")
location = geolocator.geocode(address)
latitude = location.latitude
longitude = location.longitude
print('The geograpical coordinate of Hyderabad, India {}, {}.'.format(latitude, longitude))

收集数据后,我们必须将数据填充到 pandas 数据框架中,然后使用 follow 包在地图上可视化邻近区域。

map_kl = folium.Map(location=[latitude, longitude], zoom_start=11)# Adding markers to mapfor lat, lng, neighborhood in zip(kl_df['Latitude'],  kl_df['Longitude'], kl_df['Neighborhood']):
 label = '{}'.format(neighborhood)
 label = folium.Popup(label, parse_html=True)
 folium.CircleMarker([lat, lng],radius=5,popup=label,color='blue',fill=True,fill_color='#3186cc',fill_opacity=0.7).add_to(map_kl)
map_kl

包含所有街区的海德拉巴地图

使用 foursquare API 探索社区

CLIENT_ID = '' # your Foursquare ID
CLIENT_SECRET = '' # your Foursquare Secret
VERSION = '20180604'radius = 2000
LIMIT = 100
venues = []
for lat, long, neighborhood in zip(kl_df['Latitude'], kl_df['Longitude'], kl_df['Neighborhood']):# Create the API request URLurl = "https://api.foursquare.com/v2/venues/explore?client_id={}&client_secret={}&v={}&ll={},{}&radius={}&limit={}".format(CLIENT_ID,CLIENT_SECRET,VERSION,lat,long,radius,LIMIT)# Make the GET requestresults = requests.get(url).json()["response"]['groups'][0]['items']# Return only relevant information for each nearby venuefor venue in results:
    venues.append((neighborhood,lat,long,venue['venue']['name'],
    venue['venue']['location']['lat'],venue['venue']['location']    ['lng'],venue['venue']['categories'][0]['name']))

在提取了所有的场馆之后,我们必须将场馆列表转换成一个新的数据帧。

要了解更多关于 Foursquare 文档,请点击 此处

venues_df = pd.DataFrame(venues)
# Defining the column namesvenues_df.columns = ['Neighborhood', 'Latitude', 'Longitude', 'VenueName', 'VenueLatitude', 'VenueLongitude', 'VenueCategory']
print(venues_df.shape)
venues_df.head()

# Lets check how many venues were returned for each neighbourhoodvenues_df.groupby(["Neighborhood"]).count()# Lets check out how many unique categories can be curated from all the returned valuesprint('There are {} unique categories.'.format(len(venues_df['VenueCategory'].unique())))There are 174 unique categories# Displaying the first 50 Venue Category namesvenues_df['VenueCategory'].unique()[:50]

分析每个邻域

在这里,我们将一个热编码应用于所有的场馆。所以现在列数变成了 175

# One hot encodingkl_onehot = pd.get_dummies(venues_df[['VenueCategory']], prefix="", prefix_sep="")# Adding neighborhood column back to dataframekl_onehot['Neighborhoods'] = venues_df['Neighborhood']# Moving neighbourhood column to the first columnfixed_columns = [kl_onehot.columns[-1]] + list(kl_onehot.columns[:-1])
kl_onehot = kl_onehot[fixed_columns]print(kl_onehot.shape)(6684, 175)

接下来,让我们通过对每个类别的出现频率求和来对邻域行进行分组。

kl_grouped=kl_onehot.groupby(["Neighborhoods"]).sum().reset_index()
print(kl_grouped.shape)
kl_grouped(198, 175)

len((kl_grouped[kl_grouped["Shopping Mall"] > 0]))

海得拉巴有 66 个购物中心,非常高。所以现在我们必须选择一个购物中心较少的合适地点,这样我们在那个地点建立购物中心的机会应该很大。

# Creating a dataframe for Shopping Mall data only
kl_mall = kl_grouped[["Neighborhoods","Shopping Mall"]]

聚集邻居

现在,我们需要将所有的邻居分成不同的组。结果将使我们能够确定哪些街区的购物中心更集中,而哪些街区的购物中心数量较少。根据购物中心在不同街区的出现情况,这将有助于我们回答这样一个问题:哪些街区最适合开设新的购物中心。

# Setting the number of clusters
kclusters = 3
kl_clustering = kl_mall.drop(["Neighborhoods"], 1)# Run k-means clustering algorithm
kmeans = KMeans(n_clusters=kclusters,random_state=0).fit(kl_clustering)# Checking cluster labels generated for each row in the dataframe
kmeans.labels_[0:10]array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0], dtype=int32)

我们将聚类数设置为 3,并运行该算法。在应用 K-Means 聚类算法之后,所有的邻域被分离并形成不同的聚类。

# Creating a new dataframe that includes the cluster as well as the top 10 venues for each neighborhood.kl_merged = kl_mall.copy()# Add the clustering labelskl_merged["Cluster Labels"] = kmeans.labels_
kl_merged.rename(columns={"Neighborhoods": "Neighborhood"}, inplace=True)
kl_merged.head(10)

这里,购物中心列表示特定区域中购物中心的数量,分类标签表示分类编号(0 或 1 或 2)

 # Adding latitude and longitude values to the existing dataframekl_merged['Latitude'] = kl_df['Latitude']
kl_merged['Longitude'] = kl_df['Longitude']# Sorting the results by Cluster Labelskl_merged.sort_values(["Cluster Labels"], inplace=True)
kl_merged

现在,我们可以清楚地看到属于第一个群集(群集编号 0)的所有位置。类似地,我们看到所有的分类编号都是按照 0,1,2 的顺序排列的。

可视化产生的集群

# Creating the mapmap_clusters = folium.Map(location=[latitude, longitude], zoom_start=11)# Setting color scheme for the clustersx = np.arange(kclusters)
ys = [i+x+(i*x)**2 for i in range(kclusters)]
colors_array = cm.rainbow(np.linspace(0, 1, len(ys)))
rainbow = [colors.rgb2hex(i) for i in colors_array]# Add markers to the mapmarkers_colors = []for lat, lon, poi, cluster in zip(kl_merged['Latitude'], kl_merged['Longitude'], kl_merged['Neighborhood'], kl_merged['Cluster Labels']):label = folium.Popup(str(poi) + ' - Cluster ' + str(cluster), parse_html=True)
  folium.CircleMarker([lat,lon],radius=5,popup=label,color=rainbow[cluster-1],fill=True,fill_color=rainbow[cluster-1],fill_opacity=0.7).add_to(map_clusters)map_clusters

检查星团

len(kl_merged.loc[kl_merged['Cluster Labels'] == 0])
len(kl_merged.loc[kl_merged['Cluster Labels'] == 1])
len(kl_merged.loc[kl_merged['Cluster Labels'] == 2])

结果

在 3 个聚类中最高的聚类 0 中有 132 个地点,并且聚类 0 包含没有购物中心的所有地点。聚类 1 包含 51 个地点,并且它们都恰好包含 1 个购物中心,而聚类 2 包含 15 个地点,其中所有地点都包含 2 个或更多个购物中心。

K-means 聚类的结果表明,我们可以根据“购物中心”的出现频率将街区分为 3 个聚类:
聚类 0:购物中心数量非常少的街区
聚类 1:购物中心中度集中的街区
聚类 2:购物中心高度集中的街区
我们在地图中可视化聚类结果,聚类 0 为红色,聚类 1 为紫色,聚类 2 为薄荷绿。

结论

许多购物中心都集中在海得拉巴市的中心区域。集群 0 的商场数量非常少。这代表着开设新购物中心的巨大机会和高潜力领域,因为现有购物中心几乎没有竞争。同时,由于供过于求和购物中心高度集中,集群 2 中的购物中心可能会面临激烈的竞争。因此,该项目建议房地产开发商利用这些发现,在集群 0 的社区开设新的购物中心,几乎没有竞争。拥有独特销售主张以从竞争中脱颖而出的房地产开发商,也可以在竞争适度的第 1 类社区开设新的购物中心。最后,建议房地产开发商避开第二组中已经有大量购物中心和激烈竞争的街区。

因此,我们可以对大型数据集应用相同的方法,并可以根据类别轻松区分场馆。假设在一个城市里有 400 家餐馆,那么我们可以很容易地把它们分成不同的群。我们不仅可以将这种方法应用于购物中心,还可以应用于餐馆、咖啡店等等。在本项目中,我们只考虑一个因素,即购物中心出现的频率,还有其他因素,如人口和居民收入,可能会影响新购物中心的选址决策。

但是对于建立一个购物中心,我们需要考虑其他因素,如租金成本、购物中心周围的环境、当地的人们——如果这是一个许多人喜欢外出的豪华区域,他们的生活方式将与其他人不同,因此会花费很多。如果我们决定一个竞争较少的地方,那么我们也需要考虑住在那个地方的人们。如果那个地区的人们花费很多并且喜欢外出,那么这将是一个成功。如果住在购物中心附近的人不喜欢外出,那么最好考虑一些竞争较少、人群较好的其他地方。

整个项目可以随时参考我的 GitHub 库

“我们曾经建造文明。现在我们建商场。”比利·布莱森

LinkedIn 上与我联系

我希望你觉得这篇文章很有见地。我很乐意听到反馈,以便即兴创作,并带来更好的内容。

非常感谢您的阅读!

如何从 Python 查询 Neo4j

原文:https://towardsdatascience.com/neo4j-cypher-python-7a919a372be7?source=collection_archive---------3-----------------------

在 Python 中使用 Neo4j:Neo4j Python 驱动程序和 Cypher 查询语言的快速入门。

Neo4j 是一个图形数据库管理系统。

图片作者。Neo4j 浏览器窗口。

根据其网站:

Neo4j 是一个本地图形数据库,从头开始构建,不仅利用数据,还利用数据关系。 Neo4j 连接存储的数据,以前所未有的速度实现前所未有的查询。

在本文中,我们将提供一个关于使用 Python 中的 Neo4j 的简短教程。

安装 Neo4j Desktop 并配置数据库

如果已经安装并配置了图形 DBMS 的实例,则可以跳过本节。为了安装 Neo4j 桌面,请遵循官网上的分步指南。:)正确安装后,您应该会有一个如下图所示的浏览器窗口。

图片作者。Neo4j 浏览器。

您可能已经创建了一些预定义的示例项目。在本教程中,我们将创建并使用一个全新的项目。只需点击新建按钮,并为我们的项目选择一个名称!

图片作者。新项目创建。

最初,项目是空的。我们可以从添加新数据库开始。

图片作者。在 Neo4j 浏览器上的项目中添加数据库。

一旦创建了数据库,启动并打开它。您应该会看到一个如下图所示的窗口,其中有用于从客户端连接到数据库的信息。在我们的例子中,URI 是

bolt://localhost:7687

图片作者。Neo4j 浏览器在一个数据库上打开。

从左侧的垂直栏中,您可以进入用户管理菜单来创建新用户。

图片作者。在 Neo4j 中创建新用户。

在本例中,我们将创建一个管理员用户。

Username: superman
Password: pizza
Role: admin

我们可以通过从左侧垂直栏中选择用户列表来检查新用户的创建。

图片作者。Neo4j 中的用户列表。

现在,我们从服务器端准备好了!让我们转向 Python 吧!

安装 Neo4j Python 驱动程序

在我们的 Python 环境中安装包 neo4j :

pip install neo4j

这是官方支持的驱动程序,所以我们在本教程中坚持使用它。然而,你可以为未来的项目考虑其他设计良好的社区驱动因素。一旦安装了 neo4j 包,可以尝试用 Python 导入。

from neo4j import __version__ as neo4j_version
print(neo4j_version)

如果一切正常,您应该会收到 neo4j 包的版本(在本例中是 4.0.1)作为输出。

现在,我们准备好查询图形数据库了!

用 Python 进行查询

首先,我们需要定义一个连接类来连接图形数据库。

from neo4j import GraphDatabaseclass Neo4jConnection:

    def __init__(self, uri, user, pwd):
        self.__uri = uri
        self.__user = user
        self.__pwd = pwd
        self.__driver = None
        try:
            self.__driver = GraphDatabase.driver(self.__uri, auth=(self.__user, self.__pwd))
        except Exception as e:
            print("Failed to create the driver:", e)

    def close(self):
        if self.__driver is not None:
            self.__driver.close()

    def query(self, query, db=None):
        assert self.__driver is not None, "Driver not initialized!"
        session = None
        response = None
        try: 
            session = self.__driver.session(database=db) if db is not None else self.__driver.session() 
            response = list(session.run(query))
        except Exception as e:
            print("Query failed:", e)
        finally: 
            if session is not None:
                session.close()
        return response

上面的类在初始化时需要 url、用户名和密码。在查询方法中,查询字符串要用 Neo4j 的图查询语言来写: Cypher 。更多详情,请查看密码参考卡

让我们用之前定义的参数创建一个连接实例。

conn = Neo4jConnection(uri="bolt://localhost:7687", user="superman", pwd="pizza")

然后,我们可以进行第一次查询!让我们创建一个名为 coradb 的数据库。

conn.query("CREATE OR REPLACE DATABASE coradb")

我们可以用来自 CORA 数据集的数据填充我们的数据库。

Cora 数据集包括 2708 份科学出版物,分为七类。引文网络由 5429 个链接组成。数据集中的每个出版物由 0/1 值的词向量来描述,该词向量指示字典中相应词的存在与否。这部词典由 1433 个独特的单词组成。

让我们从 CSV 文件创建引用图。我们逐行读取包含节点信息的 CSV 文件,并将每个节点添加到带有标签纸张和属性 id(纸张)的图中。

query_string = '''
USING PERIODIC COMMIT 500
LOAD CSV WITH HEADERS FROM
'[https://raw.githubusercontent.com/ngshya/datasets/master/cora/cora_content.csv'](https://raw.githubusercontent.com/ngshya/datasets/master/cora/cora_content.csv')
AS line FIELDTERMINATOR ','
CREATE (:Paper {id: line.paper_id, class: line.label})
'''conn.query(query_string, db='coradb')

我们对边信息做同样的处理(注意定义边中的“箭头”语法)。

query_string = '''
USING PERIODIC COMMIT 500
LOAD CSV WITH HEADERS FROM
'[https://raw.githubusercontent.com/ngshya/datasets/master/cora/cora_cites.csv'](https://raw.githubusercontent.com/ngshya/datasets/master/cora/cora_cites.csv')
AS line FIELDTERMINATOR ','
MATCH (citing_paper:Paper {id: line.citing_paper_id}),(cited_paper:Paper {id: line.cited_paper_id})
CREATE (citing_paper)-[:CITES]->(cited_paper)
'''conn.query(query_string, db='coradb')

最后,我们准备在我们的引用网络上进行查询!例如,我们可以问网络中有哪些类别的论文:

query_string = '''
MATCH (p:Paper)
RETURN DISTINCT p.class
ORDER BY p.class
'''conn.query(query_string, db='coradb')

或被引用最多的论文列表:

query_string = '''
MATCH ()-->(p:Paper) 
RETURN id(p), count(*) as indegree 
ORDER BY indegree DESC LIMIT 10
'''conn.query(query_string, db='coradb')

您可以在 Cypher Refcard 上使用任何语法,唯一的限制是您的幻想!

运行图表数据科学算法

除了 Cypher 查询之外,您还可以在 Neo4j 中运行图形算法,例如:路径查找、中心性计算、社区检测等。为此,我们需要激活 Neo4j 图形数据科学库。我们需要返回 Neo4j 浏览器,进入图形数据库的配置菜单(3 点)。

图片作者。图形数据库的配置菜单。

插件标签下,安装图形数据科学库并重启。在计算任何度量之前,我们需要创建一个图。

query_string = '''
CALL gds.graph.create(
  'coraGraph',
  'Paper',
  'CITES'
)
'''conn.query(query_string, db='coradb')

现在,我们可以计算图中每个节点的 PageRank介数并保存在 properties 中。

query_string = '''
CALL gds.pageRank.write('coraGraph', {
  writeProperty: 'pagerank'
})
YIELD nodePropertiesWritten, ranIterations
'''conn.query(query_string, db='coradb') query_string = '''
CALL gds.betweenness.write('coraGraph', { 
  writeProperty: 'betweenness' })
YIELD minimumScore, maximumScore, scoreSum, nodePropertiesWritten
'''conn.query(query_string, db='coradb')

实现算法及其语法的完整列表可以在这里找到。

如果我们现在查询该图,我们可以发现每个节点还有两个属性(pagerank 和介数)。我们可以将输出转换成数据帧,并从那里继续我们的分析。

from pandas import DataFramequery_string = '''
MATCH (p:Paper)
RETURN DISTINCT p.id, p.class, p.pagerank, p.betweenness
'''dtf_data = DataFrame([dict(_) for _ in conn.query(query_string, db='coradb')])dtf_data.sample(10)

上面的代码产生以下输出:

图片作者。从密码输出到熊猫数据框架。

如果我们已经完成了查询,我们可以关闭连接。

conn.close()

联系人: LinkedIn | Twitter

Neo4j vs GRAKN 第一部分:基础知识

原文:https://towardsdatascience.com/neo4j-vs-grakn-part-i-basics-f2fe3511ce88?source=collection_archive---------4-----------------------

两个最流行的知识库之间的详尽比较

亲爱的读者,在这一系列文章中,我比较了两个流行的知识库:Neo4j 和 Grakn。很久以前,我就决定应你的要求写这篇比较,然而,命运就是现在😊

这是一个分三部分的详细比较:第一部分致力于技术细节,第二部分深入语义和建模的细节。简介部分给出了 Neo4j 和 Grakn 如何工作的快速信息,以及它们带给我们的新内容的一些细节。如果你已经知道了第一部分,你可以直接进入语义能力部分。第三部分致力于比较图算法,推荐系统的核心和社会网络。该系列将继续图形学习,聊天机器人 NLU 和更多的两个平台的语义。

在本文中,我将简要比较 Neo4j 的做法与 Grakn 的做法有何不同。正如你将遵循的例子,如何创建一个模式,如何插入,删除和查询;你会注意到范式的不同。这部分不是战斗,而是比较。

我知道你等不及看内容了,让我们开始比较吧…以下是一些亮点:

Grakn 的工作原理

Grakn is the knowledge graph, Graql is the query language notes Grakn 主页。Grakn 是知识图,完全真实;但是 Graql 语言是面向数据的,类似于本体论。Graql 是声明性的,定义数据,操作数据。我们将在接下来的章节中看到更多关于 Graql 的内容。

Grakn:专注于知识表示,而不是放弃图形

在我看来 Grakn 是知识库,Graql 是面向数据的查询语言;所有这些都建立在一个图形数据结构上,但是你永远感觉不到图形在那里。他们的网站是这样描述的:

When writing Graql queries, we simply describe **what** information we would like to retrieve, rather than **how** should it be obtained. Once we specify the target information to retrieve, the Graql query  processor will take care of finding an optimal way to retrieve it. 

当我第一次见到 Grakn 时,我想this is a knowledge modeler并且我仍然有同样的感觉。Grakn 到底是什么的最佳解释来自他们自己:

Grakn is a database in the form of a knowledge graph, that uses an  intuitive ontology to model extremely complex datasets. It stores data  in a way that allows machines to understand the meaning of information in the complete context of their relationships. Consequently, Grakn allows computers to process complex information more intelligently with less human interventionGraql is a declarative, knowledge-oriented graph query language that uses machine reasoning for retrieving explicitly stored and implicitly derived knowledge from  Grakn.

正如我以前说过的,尽管他们自己说的是Grakn is a database,我仍然提出我的反对意见,坚持认为 Grakn 是一个知识库😄

Neo4j 的工作原理

Neo4j 是一个图形外观的知识图😄虽然我在他们的主页上看到过一次connected data,但是人们必须浏览他们的文档才能看到他们实际带来的语义:

Neo4j:看起来只是一个图形数据库,但实际上是一个知识图。

虽然他们只在头版写了一个graph database,但我非常不同意。Neo4j 绝对是知识图谱。可以看到关系、类、实例、属性,即模式定义。这是语义学,就是这样。Neo4j 绝对不仅仅是一个图形数据库,一个可以建模的知识。

Grakn 如何战胜 OWL

好吧,如果我们已经可以写下一些 OWL,那么我们为什么要用 Grakn 来代替呢,有人可能会想。Grakn 在他们的帖子中详细解释了这个问题。对我来说,first plus 绝对是 Graql,读写方便。OWL 通常由的门徒或其他类似的框架创建,生成的 XML 基本上是不可读的。下面在 OWL-XML 和 Graql 中找到相同的descends关系:

Graql 和 OWL-XML 中的下降关系。

从生产的角度来看,Grakn

  • 可攀登的
  • 高效
  • 拥有 Python、Java、Node.js 客户端
  • 被包装成一个完整的框架

…即生产就绪。从发展的角度来看

  • 查询得到了高度优化
  • 底层数据结构对于语义建模是灵活的
  • 还提供了图形算法。

从语义学的角度来看,Grakn 更有力量;数据模型

  • 易于更新/添加
  • 允许抽象类型(我们将谈到这一点)
  • 与 OWL 相比有一个巨大的优势,它保证了逻辑完整性。OWL 有一个开放世界的假设,而 Grakn 提供了开放世界和封闭世界假设的别致组合。您可以在逻辑完整性部分了解更多信息。
  • 通常允许更多的抽象细节。例如,底层超图允许 n 元关系。在 OWL 中建模 n 元关系有点痛苦,这里有一个完整的描述。

Neo4j 带来了什么

老实说,我不知道从哪里开始。Neo4j 以提供连接数据在 NoSQL 世界大放异彩,以其卓越的后端和高性能在图形数据库中大放异彩。与许多其他图形数据库不同,Neo4j 提供了

  • 快速读写
  • 高可用性
  • 水平缩放。水平扩展是通过两种类型的集群实现的:高可用性集群和因果集群。
  • 缓存分片
  • 多聚类
  • 没有连接。数据通过边连接,不需要复杂的连接来检索连接/相关的数据
  • 粒度安全。

就我个人而言,在阅读 Neo4j 无与伦比的可伸缩性技能时,我从椅子上摔了下来。我强烈推荐访问相应的页面。警告:你也可能坠入爱河,❤️

从数据角度来看,Neo4j 提供

  • 时态数据支持
  • 3D 空间数据支持
  • 实时分析。

从左上开始:寻找有价值的异常值,以不同的方式表示连通性,查询和可视化空间数据。全部摘自 Neo4j 主页。

如果你想建立一个社交网络模型,建立一个推荐系统或为任何其他任务建立连接数据模型;如果您想要操作时间或空间数据,想要一个可伸缩、高性能、安全的应用程序,那么 Neo4j 是您的最佳选择。这里不再多言。

入门指南

开始使用 Grakn 很容易:首先一个安装Grakn,然后制作一个grakn server start。之后,可以使用 Grakn 控制台Grakn 工作台工作。

同样适用于 Neo4j,下载安装以非常专业的方式提供。如果你需要,Docker 配置和框架配置手册也在那里。之后可以下载 Neo4j 浏览器开始玩或者可以发现后端更多。你也可以不用通过他们的沙箱下载就可以试验 Neo4j,我真的很喜欢。您可以在没有任何下载拥挤的情况下玩游戏。

Neo4j 和 Grakn 下载页面

我必须说,我完全爱上了 Neo4j 文档,因为边注,努力和专业水平是巨大的。

开发环境和可视化

Grakn 和 Neo4j 都提供了易于使用和可视化的 ide。

Grakn workbase 提供了两个功能:知识图的可视化和与模式交互的简单方式。您可以在工作库中执行match-get查询和path查询。

使用 Grakn workbase 进行查询,照片取自他们的 Github

Neo4j 提供他们的浏览器也有两个目的:简单的交互和可视化。人们还可以在他们的图形中探索模式、聚类和遍历。

在 Neo4j 浏览器中查询,摘自他们的文档

此外,Neo4j 提供了更多用于可视化的 Neo4j Bloom其他用于可视化的开发工具,主要是 JS 集成。使用 Neo4j Bloom,您可以发现集群、模式等。

聚类和链接探索与布鲁姆,图片取自他们的网站和媒体开发博客

这还没有结束,Neo4j 有甚至更多的可视化工具用于空间数据和 3D。一般来说,Neo4j 是空间数据的大师,但可视化工具将 Neo4j 带到了一个不同的水平:

Neo4j 地图数据可视化,取自他们的媒体开发者博客

两个平台都提供了很好的可视化效果,Neo4j 由于较老而提供了更多😄

我们已经介绍了这两个平台的基础知识,现在我们可以进入开发细节了。

底层数据结构

简称 Grakn 为超图,Neo4j 为有向图。如果你进一步对 Neo4j 如何存储他的节点、关系和属性感兴趣,你可以访问他们的开发者手册或者堆栈溢出问题

数据建模

数据建模是我们从老猫头鹰那里学到的方法。

Neo4j 使用知识图概念:节点(实例)、标签(类)、关系、关系类型(属性)和属性(数据属性)。

具有图形概念的建模知识,图片取自 Neo4j 文档

Grakn 风格的知识建模更接近于本体方式、声明性和更面向语义。观念是:

  • 实体(类)
  • 例子
  • 属性
  • 角色
  • 规则
  • 类型层次结构
  • 抽象类型

Grakn 建模,实体关系,子实体,三元关系。摘自他们的头版。

如果你更多地走上本体论一边,Grakn 的思维方式确实是类似的。建模容易,提供语义能力和效率。

查询语言

Graql 是声明性的,更面向数据。Neo4j 的 Cypher 也是声明性的,但是风格是 SQL。对我来说,Graql 感觉像本体,Cypher 感觉像数据库查询。比较以下两种语言中的简单查询:

//CypherMATCH (p:Person { name: "Duygu" })
RETURN p//Graql
match
  $p isa person, has name "Duygu";
get $p;

我个人认为 Graql 在语义上更友好。

创建模式

在 Grakn 中创建模式很容易,记住 Graql 是声明性的。基本上,你打开一个.gql文件,开始创建你的模式,就是这样😄。这是他们首页的一个例子:

define

person sub entity,
  has name,
  plays employee;

company sub entity,
  has name,
  plays employer;

employment sub relation,
  relates employee,
  relates employer;

name sub attribute,
  datatype string;

Neo4j 创建实体和实例的方式是CREATE。一旦创建了这些节点,就可以进行一个MATCH查询来获得相应的节点,并在它们之间创建一个关系。一个创建节点、边及其属性:

CREATE (d:Person { name:"Duygu"})
CREATE (g:Company {name: "German Autolabs"})MATCH (a:Person),(b:Company)
WHERE a.name = 'Duygu' AND b.name = 'German Autolabs'
CREATE (a)-[r:Employed { since: '2018' }]->(b)
RETURN type(r), r.name

询问

Graql 是声明性的,查询又是本体论的方式。通过match子句进行查询。以下是一些关于银行客户的简单查询:

match $p isa customer; get;match $p isa customer, has first-name "Rebecca"; get;match $p isa customer, has full-name $fn; { $fn contains "Rebecca"; } or { $fn contains "Michell"; }; get;

到目前为止一切顺利。现在,我们可以从客户那里获得一些见解。这是对average debt of the Mastercard owner customers, who are younger than 25的查询:

match
  $person isa customer, has age < 25;
  $card isa credit-card, has type "Mastercard";
  (customer: $person, credit-card: $card) isa contract, has debt $debt;
get $debt; mean $debt;

看起来很干净。Neo4j 怎么样?密码查询也是由MATCH子句完成的,但是语法完全不同;更确切地说是一个带有WHERE的数据库匹配风格。有WHERE的时候,也可以玩一些串法游戏😄:

MATCH (customer:Customer)
RETURN customerMATCH (customer:Customer)
WHERE customer.first_name = 'Rebecca'
RETURN customer//or equivalently with a bit syntactic sugarMATCH (customer:Customer {first_name: "Rebecca"})
RETURN customer//MATCH (customer:Customer)
WHERE p.first_name STARTS WITH 'Steph'
RETURN p

谈到关系,我们需要通过箭头关注边缘方向。以下是对驾驶奥迪的银行客户的查询;注意DRIVES关系是从客户指向他们的汽车的:

MATCH (car:Car {brand: "Audi"})<-[:DRIVES]-(customers)
RETURN customers.first_name

聚合也类似于 SQL,下面是对年轻的万事达卡用户客户的债务的相同查询:

MATCH (customer:Customer)-[:OWNS]->(card:CreditCard {type: "Mastercard"})
WHERE customer.age < 25 
RETURN AVG(card.debt)

SQL 语法适用于一般的 Cypher 查询,如果你喜欢写 SQL,那么你一定会对 Cypher 如鱼得水。这是一个查找具有最多属性的节点的查询:

MATCH (n)
RETURN labels(n), keys(n), size(keys(n)), count(*)
ORDER BY size(keys(n)) DESC

回到语义,可以查询实体/实例如何相关:

MATCH (:Person { name: "Oliver Stone" })-[r]->(movie)
RETURN type(r) //DIRECTED 

“连接”呢,即关于相关节点的查询?人们通常像在 Grakn 中一样处理这样的查询,只是多了一些实例和更多的关系箭头:

//Name of the movies that Charlee Sheen acted and their directorsMATCH (charlie { name: 'Charlie Sheen' })-[:ACTED_IN]->(movie)<-[:DIRECTED]-(director)
RETURN movie.title, director.name

我一次又一次地强调 Neo4j 是一个图形,现在让我们看看它是如何工作的……我们可以用 Cypher 生成path queries,或者用path restrictions生成常见的语义查询。

假设您有一个社交网络,您想要查找与 Alicia 的距离为 2 的所有人,以及谁在哪个方向跟随谁并不重要:

MATCH (p1:Person)-[:FOLLOWS*1..2]-(p2:Person)
WHERE p1.name = "Alicia"
RETURN p1, p2

当然,最短路径是社交网络中的经典,你可能想知道艾丽西娅和艾蜜蕊的社交联系有多紧密:

MATCH p = shortestPath((p1:Person)-[*]-(p2:Person))
WHERE p1.name = "Alicia" AND p2.name = 'Amerie'
RETURN p

这样,我们可以通过任何关系类型寻找最短路径。如果我们需要,我们可以用[:FOLLOWS]代替[*]来指定我们需要这个关系。(可能还有其他关系类型,上同一所大学,住在同一座城市……)

正如你所看到的,Cypher 提供的远比你看到的要多。诚然,语法看起来像 SQL …但故事是非常不同的,图的概念和语义的概念满足燃料 Neo4j。

推理

语义推理机从 RDF 时代就存在了。从图式知识和已有的数据中推断新的关系和事实对人脑来说很容易,但对知识库系统来说就不那么简单了。我们是否允许开放世界的假设(如果你不确定某件事并不意味着它是错的,你只是不知道);世界是由我们已经知道的东西组成的吗(当一个看不见的实体来到我们的封闭世界时会发生什么),我们应该推断多少,我们应该允许长路径吗… Hermit 是 OWL 的一个流行选择(我也用过),它可以作为 Protégé的一个插件使用。

Neo4j 中的推理没有内置工具。在这里我将介绍 Grakn 是如何处理它的。

Grakn 中的推理通过rules处理。下面是他们如何描述规则的:

Grakn is capable of reasoning over data via pre-defined rules. Graql  rules look for a given pattern in the dataset and when found, create the given queryable relation.Graql reasoning is performed at query time and is guaranteed to be complete.

让我们看一个兄弟姐妹规则的例子,如果两个人有相同的父母;那么可以推断他们是兄弟姐妹。如何用 Grakn 表示这个推论如下:

兄弟推理规则,取自 Grakn 文档

Grakn 规则的创建是直观的:when满足一些条件,then我们应该推断出以下事实。我发现语法令人耳目一新。特别是在药物发现和任何其他种类的发现任务中,人们需要 100%的推理。如果我参与到发现类型的任务中,我只会因为这个原因而使用 Grakn。

逻辑完整性

一旦您创建了您的模式并且可以推断新的关系,之后您会希望您的模式保持不变,并且不允许不正确的数据进入您的模型。例如,你可能不希望在一个person和一个carpet之间有一个marriage关系(尽管人+树在世界的某些地方是合法的😄).

尽管 Neo4j 在他们的文档中有约束,但是这些只是用于数据验证和空值检查的数据库约定:

Neo4j helps enforce data integrity with the use of constraints.  Constraints can be applied to either nodes or relationships. Unique node  property constraints can be created, as well as node and relationship  property existence constraints.

Graql 通过roles确保逻辑完整性,正如你在上面的例子中看到的,每个角色来自一个类。同样,对于发现类型的任务,这是必需的。

可量测性

两者都是超级可扩展的。我在上面讲了很多关于 Neo4j 可伸缩性的内容,但是对 Grakn 的可伸缩性保密😄Grakn 利用了幕后的 Cassandra,因此 Grakn 非常具有一致性、可伸缩性和容错性。

图形算法

是下一篇文章的主题。你将不得不等待 2 个以上的职位😉

Grakn 世界 vs Neo4j 世界

…看起来非常不同,但同时又非常相似。Grakn 的方式更面向知识,Neo4j 感觉图形味道更浓一些。两个框架都很吸引人,那么只剩下一个问题:谁更好?接下来即将到来的是 Grakn 和 Neo4j 之间的语义大战😉

亲爱的读者们,这篇令人筋疲力尽的文章已经接近尾声,但我还不想挥手告别😄请继续阅读第二部分,和我一起探索迷人的语义世界。在那之前,请小心,愉快地黑吧。👋

Neo4j vs GRAKN 第二部分:语义

原文:https://towardsdatascience.com/neo4j-vs-grakn-part-ii-semantics-11a0847ae7a2?source=collection_archive---------13-----------------------

语义之战:谁对数据建模更好?

亲爱的读者,在这一部分,我将带你进入语义学的世界。在第一部分中,我们从总体上比较了 Grakn 和 Neo4j 世界,以了解范式差异如何导致不同的做事方式。在本文中,Grakn 和 Neo4j 将在建模和表示能力方面展开竞争,这是一场旨在征服语义世界的肉搏战😄

在我职业生涯的早期,我从事知识工程(我从事搜索引擎维基化组件)。让我惊讶的是,在过去的 10 年里,知识图在可伸缩性、语言支持、开发者/用户界面、高效存储方面有了巨大的改进;但是就语义表达能力而言,没有什么能改变那么多。仍然有实例、关系、阶级和我们,那些努力尝试赋予意义的人。不管你是初学者还是更高级的,都没有区别。我们都知道这样一个事实:对任何一种语义收费都是困难的。这完全是另一个故事,我将在图形学习和知识库支持的聊天机器人帖子(即将推出)中详细介绍。

我不会让你等太久,让战斗开始吧:

1.文档和社区

对于任何开源项目来说,最重要的是文档和社区支持。

Neo4j 提供了文档、 视频教程、 一个胖 Github 、一个社区和一个 Stackoverflow 存档。如果我搜索Neo4j tutorialGRAKN tutorial,我会看到:

看起来相当棒

Grakn 提供了文档教程充满示例的 Github repo, 一个社区以及自己的 Stackoverflow 空间。我看到了精彩的文档和社区对这两者的支持。

Neo4j: 10/10,Grakn: 10/10

2.语言支持

Grakn 提供 Java、Node.js 和 Python 客户端,涵盖了现代开发栈的相当一部分。Neo4j 在这方面提供了更多的变化;他们正式支持的驱动程序。NET、Java、JavaScript、Go 和 Python。Ruby、PHP、Erlang 和 PERL 驱动程序由社区贡献者提供。我发现 Grakn 的语言支持对于现代开发来说足够且体面;然而,Neo4j 因其提供的多样性而大放异彩。Neo4j 相对轻松地赢得了这一轮。不支持 C++,我各扣一分😄

Neo4j: 9/10,Grakn: 8/10

3.OWL 导入

如果一个人从事知识表示或关联数据方面的工作,很可能他已经拥有大量 OWL 格式的本体资源。Grakn 没有直接导入 OWL 文件的方法,必须解析文件并创建自己的 Grakn 本体。更多关于这个问题的消息来自他们自己的口:【https://discuss.grakn.ai/t/migrating-owl-to-grakn/556】T2,尽管他们有一个 XML 导入器。加载器是 JSON、CSV 和 XML。

来到 Neo4j 情况就有点不一样了。Neo4j 团队似乎花了很大力气给他们的图形方法带来更多语义,并构建了neosemantics。这个贡献包括了关于 RDF 导入OWL 导入的综合页面以及对它们的推理/推论。我觉得这种努力令人印象深刻。Neo4j还如预期支持 XML、CSV、JSON 导入。你也可以阅读这篇文章了解更多猫头鹰& Neo4j duo,我真的很喜欢它。

Neo4j: 8/10 表示努力,Grakn: 8/10 表示提供了一种本体语言

4.语义关系

OWL 支持许多属性特征,包括自反性、非自反性、传递性、对称性、非对称性……如果你想建立一个友谊网络你需要对称性(友谊是相互的,如果 Carry 是 Barry 的朋友,Barry 当然是 Carry 的朋友);如果你需要一个希腊神话的模型,你需要及物性:奥德修斯是赫尔墨斯的曾孙,特勒戈诺斯是奥德修斯和泰坦喀尔刻的儿子,那么显然特勒戈诺斯是赫尔墨斯的后代。

下降关系:传递和不对称。猫头鹰风格,在被保护人内部拍摄的照片

这是 OWL 在游戏中发挥其全部语义力量的地方,使自己区别于 RDFS 和其他三联商店或图形信息持有者。OWL 从来没有像 T2 一样成为一个裸露的信息容器,它允许开发者对有意义的现实世界关系进行建模。

OWL 支持的酒店特征,在被保护人内部拍摄的照片

语义关系是充分发挥语义力量的必要条件。我尝试了一下如何定义与 Grakn 的对称关系:

friendship isa relation-type
  relates friend;person isa entity-type,  
  plays-role friend;

定义传递关系有点棘手,但是可行😉Grakn 的思维方式通常侧重于本体和知识表示(即使底层存储是一个图),如果您熟悉 OWL,Grakn 会有宾至如归的感觉。

来到 Neo4j 思维方式,Neo4j 是知识图,他喜欢做图。那么在这一点上,人们应该只把关系看作是边。我看不出在创建时间上限制关系的直接方法。Neo4j 通常不允许无方向的边,然后创建一个具有任意方向的关系,并在查询时丢弃边方向,就像这样:

出于效率和空间原因,创建具有任意方向的边。摘自上面的链接。

查询看起来像:

//find all partner companies of Neo4j MATCH (neo)-[:PARTNER]-(partner) which is union of MATCH (neo)-[:PARTNER]->(partner)  (edge is directed to partner)
and
MATCH (neo)<-[:PARTNER]-(partner)  (edge is directed to neo)(notice the edge directions)

传递关系和传递性在 Neo4j 中非常重要😉我们在图形算法的文章中探讨了这个问题。更多关于 Neo4j 的关系,你可以访问

我们已经看到 Grakn 喜欢做超图。与 Neo4j 不同,超图提供了一个宽松的节点/边概念,并允许 Grakn 关系涉及两个以上的角色。

define

law-suit sub relation,
  relates court,
  relates judge,
  relates DA,
  relates defendant;person sub entity,
  has name,
  plays judge,
  plays DA,
  plays defendant;name sub attribute,
  datatype string;

你可以在 Grakn 博客上阅读更多关于这个主题的内容。这是对真实世界数据建模的一个非常重要的特性,否则人们必须经历许多不必要的痛苦,类似于 OWL ways

5.推理者

Grakn 中的推理通过inference rules工作。如何定义规则相当简单,在模式创建期间创建推理规则集。根据文档,规则不是直接存储在图中,而是根据查询时间进行推断。推理规则看起来像

define rule-id sub rule,
  when LHS then RHS;

显而易见的是:如果满足左侧的条件,那么请推断右侧的条件。让我们看一个例子,这是人们如何自然地定义一个 being siblings 关系:

define

people-with-same-parents-are-siblings sub rule,
when {
    (mother: $m, $x) isa parentship;
    (mother: $m, $y) isa parentship;
    (father: $f, $x) isa parentship;
    (father: $f, $y) isa parentship;
    $x != $y;
}, then {
    ($x, $y) isa siblings;
};

RHS 可以描述一个推断的关系,或者一个实体的一些属性。例如,在这个如何推断城市大洲的例子中,RHS 是关于实体-属性关系的推断,即has:

city-in-continent sub inference-rule,
when { 
(contains-city: $country1, in-country: $city1) isa has-city;           $country1 has continent $continent1;
}then 
{ 
$city1 has inf-continent $continent1; 
};

如你所见,人们可以推断实体、属性和关系,也就是节点、属性和边。我真的很喜欢 Grakn 的方式,Graql 的语义美在这一点上闪闪发光。效率对我的观察也很好。如果想了解更多,可以跳转到这篇帖子

如你所见,推理是 Graql 的核心部分,不幸的是 Cypher 没有内置推理。Neo4j 仍然没有放弃,并且新语义再次发挥作用以获得更多语义。正如在文档中所描述的,可以推断出WHERE子句中导入的本体的节点和关系:

CALL semantics.inference.nodesLabelled('Crystallography',  
     { catNameProp: "dbLabel", catLabel: "LCSHTopic", subCatRel:     "NARROWER_THAN" }) 
YIELD node
RETURN node.identifier as id, node.title as title, labels(node)   as categories

不幸的是,在 Neo4j 图表上,我看不到简单直接的推理方式。这并不奇怪,因为 Neo4j 喜欢做一个图表。实际上,这里的比较根本不适用。

Neo4j: 4/10 为努力;Grakn: 10/10 完美推理。格拉克无疑是这里的赢家。

6.语义力量

正如我多次写 Neo4j 喜欢做图;他们的正式名称是一个图形数据库。另一方面,Grakn 喜欢成为知识图并且更加面向知识;他们仍然没有牺牲语义,提供一种本体语言来创建和查询图形。我真的很喜欢 Graql 面向语义,它隐藏了底层的图形,使它看起来像只是本体编写和推理。这是纯粹的美。如果你像我一样站在语义学的角度,你会喜欢这种烟雾和镜子。

Cypher 看起来像一个简单的数据库查询(尽管它包含很多语义并提供路径查询)。这感觉就像为您的旧日志数据库编写 SQL 查询,虽然它非常正确和高效,但并不令人兴奋。

在建模关系类别中,Grakn 凭借支持n-ary关系胜出。老实说,我很惊讶为什么以前没有人实现n-ary关系,把我们从巨大的痛苦中拯救出来。

另一个巨大的优势是,Grakn 提供了逻辑完整性,这是 NoSQL 和图形数据库普遍缺乏的,Neo4j 也是如此。同时,它可以像 Neo4j 提供的 NoSQL 一样水平扩展。这两个平台的水平扩展能力给我留下了非常深刻的印象,而没有从语义上妥协;但是 Grakn 以其逻辑完整性赢得了我的心。

我不会坚持太久的,胜利者是格拉克。我发现 Grakn 在语义上比 Graql 更具表现力,能够以一种有机的方式表达子类和子关系,定义抽象实体、属性和关系的能力,允许 n 元关系,有一个内置的推理机…使 Grakn 成为这里的赢家。

neo4j:7/10;2010 年 9 月

8.文本支持

这一节是根据我的口味加的,因为我喜欢文字,你懂的😉(抱歉地理编码/空间人,这是我的博客😅)

Grakn match支撑regexcontains。典型的查询可能如下所示:

match $phone-number contains "+49"; get;match $x like "eat(ery|ing)"; get;

非常方便的方法startswithendswith根本没有实现,我有点不高兴(不要说用^写一个正则表达式,所有的美都在于方法的名字)。

另一方面,Neo4j 的[WHERE](https://neo4j.com/docs/cypher-manual/current/clauses/where/)支持regexcontainsstartswithendswith。人们可以这样询问:

MATCH (n)
WHERE n.name STARTS WITH 'Mar'
RETURN n.name, n.age

虽然方法非常相似,但我非常喜欢文档中对字符串方法的强调。Neo4j 在这里征服我的心。

Neo4j: 10/10,Grakn:9/10;由于以上原因,我的评价可能不太客观😄

获胜者是…

Grakn。

Neo4j 和 Cypher 竞争很激烈,但是激烈到没有足够的语义来打倒 Grakn 和 Graql。

下一步是什么

亲爱的读者们,我们到达了比赛的终点;我希望你喜欢这场血腥的战斗。接下来是图形算法的对比,猜猜谁是杀手对手😄我们将通过构建两个推荐系统来探索图算法,一个在 Grakn 中,另一个在 Neo4j 中。同时你可以访问我的其他文章,也可以在https://duy gua . github . io上访问我。在那之前保持快乐和和谐👋

霓虹。生活:你真正的虚拟助手,这次是真的吗?

原文:https://towardsdatascience.com/neon-life-your-real-virtual-assistant-for-real-this-time-6de4a52e66c4?source=collection_archive---------18-----------------------

氖的剖析与理论建构。生命,三星的新“人造人”

A nyone 看过 Blade Running 2049 一定还记得‘Joi’,一个人造人漂亮精致的全息投影。她和你说话,帮你做家务,给你讲笑话,陪你,还有更多…就像一个真正的人一样。她甚至对你有自己的记忆,并随着时间的推移形成了自己的性格。除了“她”不是人类。她只是一个超级复杂的真人“模型”,可以像真人一样说话、行动和反应。然而,仍有相当多的人暗地里希望他们也能有自己的“Joi”。她可能没有你想的那么远。进入霓虹,三星的新人造人。

来自 Gfycat 的 Joi

遭遇

我上周在 CES 2020 展会上走在地板上。像过去几年一样,出现了许多新的装置和新技术。也有大量的展示。小的,大的,巨大的,可折叠的,半透明的,应有尽有。其中,有一件展品引起了我的注意。一个栩栩如生的人站在一个显示器内,带着温暖的微笑看着我,还用丰富的手势谈论一些事情。这是干什么用的?也许是新的远程视频服务?出于好奇,我走近查看。结果,这些非常逼真的人物都不是人。他们被称为 NEONs,是三星支持的公司 STAR Labs 创造的人造人。

霓虹,我们的第一个人造人来了。霓虹是一个通过计算创建的虚拟生物,它的外表和行为都像一个真实的人,具有表现情感和智能的能力。—星际实验室

来自霓虹。生活

这个样子,表情,手势是如此自然,我真的不能告诉它是否是预先录制的视频或 CGI。仔细看,明明是 CGI,只是非常非常‘真实’。真正意义上的“类人”而非“高分辨率”。我深入挖掘,发现这些是基于预先录制的真实人类视频的人工智能生成的 CGI 镜头,是对人类演员视频的“再创造”。非常像詹姆斯·卡梅隆在电影《阿凡达》中第一次做的事情。

图片来自lyon.onvasortir.com

但是霓虹并没有就此止步,它把事情推得更远。这些 NEONs 可以脱离剧本,发展自己的“个性”。它可以从自己独特的“个性”中产生新的表情、手势和反应。这些“个性”也可以被训练并适应外部刺激。现在,这不仅仅是模仿面部表情!三星是如何做到这一点的,这意味着什么?展会上没有透露太多细节。我内心的数据科学家立刻被打开了,让我们试着弄清楚(猜测)这是如何实现的,它会对我们的社会和行业产生什么影响,好吗?

解剖

那么他们是怎么做到的呢?我们先来看看它能做什么。为了实现他们所宣称的,NEON 需要做几件事:

注意:下面的部分只是我的“有根据的预测”,因此与霓虹实际上是如何工作或创造的没有任何关系。三星尚未公布 NEON 的更多细节。

物理建模:真人视频到 CGI,穿越恐怖谷

给定一个演员的一些视频数据集,该模型需要学习如何将视频转换为 CGI 镜头,越相似越好。这项技术随着头像和表演捕捉的兴起,已经得到了很好的发展。演员被拍摄时,他们的脸上有一些彩色点网格,用来记录他们的面部表情,并将这些面部表情网格运动转换成 CGI 角色表情。这是一项相当成熟的技术。霓虹所做的只是有点不同。它可能没有网格作为参考,但使用深度学习,深度神经网络找到任务所需的特征并不太难,它可能比像面部网格这样的简单模型做得更好。

数据输入:视频短片

数据输出:面部/身体网格运动时间序列数据。

表情建模:表情/手势投影到 CGI

因此,从视频片段中,我们现在有一个网格运动时间序列数据集,如果我们可以用不同的表达式标记这些数据集,我们应该能够训练某种自动编码器,可以将 CGI 时间序列编码为表达式编码,然后重新生成相同的 CGI 时间序列数据。然后我们可以看看编码,弄清楚什么是微笑、哭泣、惊讶、生气等等。这也是一个已经解决的问题。你可以在下面找到一个例子:

数据输入: CGI 时间序列数据集

数据输出:表达式编码/嵌入层数

个性建模:从情感到表达

所以现在我们可以通过表情编码来控制我们的 CGI 化身的表情,下一步就是将情感映射到表情上。表达是情感的外化,但映射并不总是直截了当的。你可能认为人们开心的时候会笑,但是人性远比这复杂。一些外向的人会笑出声来,而内向的人可能只是微妙地傻笑。控制情绪到表情映射的是性格。现在我们如何塑造人格?这需要大量的领域知识(这也是三星声称他们仍在努力的部分,我认为最具挑战性。因为人性,你知道…)。

数据输入:情感标签(多个标签,因为一个表情后面可能有多个情感)

数据输出:表示给定化身的情绪的表情编码/嵌入

三星关于 NEON 的说法包括

从演示中,我们知道氖实际上由三部分组成:

  • 行为神经网络(表达模型?)
  • 进化生成智能(人格模型?)
  • 计算现实(物理模型?)

我上面的假设是真的吗?我们将在不久的将来了解更多,但如果你有不同的想法,请留下一些回应!

理论加工

那么这些部分是如何组合在一起形成霓虹的呢?它可以像管道一样工作:

首先使用一个人类演员的视频镜头来训练一个可以生成 CGI 网格时间序列数据的神经网络。这将赋予控制 CGI 化身尽可能像人类一样的能力。神经网络将不可避免地学习人类手势和人类面部表情的模式,这为进一步的抽象奠定了基础。

利用 CGI 网格运动时间序列数据,我们可以训练一个自动编码器,它可以进行某种降维,创建一些中间层编码器,然后重新生成 CGI。一旦重新生成的 CGI 与原始时间序列数据足够相似,我们将获得视频、表情和手势的更抽象层(表情编码器)。一旦我们有了编码器或嵌入,我们就可以玩一玩,看看哪种权重组合可以生成特定的表情,例如微笑、生气、惊讶等。然后,我们可以使用这些权重(可能需要做一些主成分分析,使其更易于管理)来控制我们的化身的表情,使其微笑、哭泣等。

就这一点而言,虚拟角色的表情可以在很大程度上由人工控制,但现在还没有。我们需要的是让虚拟角色自己“生成”表情,对外界刺激做出反应。这就是人格模型发挥作用的地方。使用心理学、情绪科学的领域知识,可以开发许多不同的个性特征,它们与表达和外部刺激的关系可以被建模。如果我们以某个名人(比如说李小龙)为例,通过对他的行为(表情)和外界刺激(言语的情绪,手势等)进行标签化。),我们可以开发一个“个性”模型,反映名人对不同情绪的不同表达会有什么反应。然后,我们使用这个个性模型来根据外部情绪(可能是从情绪分类器神经网络输出的)控制霓虹灯的反应表达。

在霓虹官方视频中,霓虹的“情绪激活”状态是实时可视化的,表明霓虹对外界刺激的反应。相当酷。

霓虹实时的情绪地图,灯泡就是她当前状态所在的地方,文字就是不同的情绪状态。

除此之外,NEON 可以学习领域知识,提供更多的价值。三星声称他们有另一个名为 Spectra 的云人工智能平台,第三方开发者将能够为 NEON 开发这些“技能”。认为 Siri 有漂亮的脸蛋,迷人的声音,还能教你功夫。😜

我不得不说,即使他们在 CES 2020 上展示的演示远非完美,但 NEON 是开创性的。这个团队的想法很宏大,并且打下了良好的基础和框架。此刻的计算饥饿应用可能意味着 NEON 不能生活在边缘,但随着 5G 的快速发展和更好的云平台,我相信 NEON 的未来潜力是巨大的。

视力

你想要哪种霓虹灯?瑜伽导师?魔术师?商务助理?私人摄影师?

这是文章中允许我放肆的部分。让我们看看霓虹灯能做什么:

  • 博彩业中的完美 NPC。在 RPG 游戏中,NPC 通常都很笨。他们的面部表情和反应太假了。NEON 可以改变这一点,给玩家一个非常真实的体验。

检查整个系列,它是金色的…

  • 重现你逝去的亲人或朋友。如果你读过这篇文章讲的是一个男孩试图创造一个聊天机器人,说话和他爸爸一模一样,并在他爸爸去世后一直让他陪着,你知道我在说什么。NEON 可以走得更远,不仅聊天机器人可以像他的父亲一样生成文本,它可以看起来像他的父亲,听起来像他的父亲,甚至具有相似的“个性”。(也许有点令人毛骨悚然,但我有什么资格评判……)
  • 各种服务助理。喜欢瑜伽导师,理财规划师,或者只是让你有个好的性格作伴。
  • 残疾人的向导/帮手。
  • 粉丝崇拜的名人“副本”
  • 自闭症治疗师

这个清单可以一直列下去,但是你要明白。由于它是一个开放的平台,它很可能成为技术领域的下一个大事件。

结论

表面上看,CES 是关于工程创新而不是科学突破的,但我认为 NEON 有点处于中间位置。这支队伍还很年轻,我很兴奋看到他们在不久的将来能做什么,并了解他们的方法。这真的是一个隐藏的宝石,我觉得必须向我的读者介绍。你认为人造人能做什么?做不到。还是永远不应该做?

关于 CES 舞台上展示的更多细节,你可以看看这个详细的视频:

觉得这篇文章有用?在 Medium 上关注我(李立伟)或者你可以在 Twitter @lymenlee 或者我的博客网站wayofnumbers.com上找到我。你也可以看看我下面最受欢迎的文章!

[## “这是 CS50”:开始数据科学教育的愉快方式

为什么 CS50 特别适合巩固你的软件工程基础

towardsdatascience.com](/this-is-cs50-a-pleasant-way-to-kick-off-your-data-science-education-d6075a6e761a) [## 一枚硬币的两面:杰瑞米·霍华德的 fast.ai vs 吴恩达的 deeplearning.ai

如何不通过同时参加 fast.ai 和 deeplearning.ai 课程来“过度适应”你的人工智能学习

towardsdatascience.com](/two-sides-of-the-same-coin-fast-ai-vs-deeplearning-ai-b67e9ec32133) [## 你需要了解网飞的“朱庇特黑仔”:冰穴📖

是时候让 Jupyter 笔记本有个有价值的竞争对手了

towardsdatascience.com](/what-you-need-to-know-about-netflixs-jupyter-killer-polynote-dbe7106145f5)

NeRF:将场景表示为用于视图合成的神经辐射场

原文:https://towardsdatascience.com/nerf-representing-scenes-as-neural-radiance-fields-for-view-synthesis-ef1e8cebace4?source=collection_archive---------14-----------------------

ECCV-2020 口头论文评论

从 2D 图像绘制三维模型是计算机视觉领域的一个挑战性问题。即使我们对每个图像都有摄像机位置监控,以前的 3D 渲染模型也不足以在实践中使用。在 ECCV 被选为口头论文的 NeRF 提出了一种最先进的方法,该方法利用 2D 图像及其相应的相机位置来构建 3D 模型。

视频 1。NeRF 作者的官方视频,经常被作者推荐观看。

术语

  1. 射线:从摄像机中心连接的线,由摄像机位置参数决定,在特定方向上,由摄像机角度参数决定。
  2. 颜色:每个 3D 体所具有的 RGB 值。
  3. 体积密度:决定它对最终色彩决定的影响程度。
  4. 光线颜色:我们跟随光线时可以观察到的 RGB 值。公式 1 给出了正式定义。

什么是 NeRF?

NeRF 是第一篇介绍神经场景表示的论文。它有利于渲染真实物体的高分辨率真实感新视图。本文的主要思想是预测沿光线的颜色值和不透明度值,这由五个外部相机参数(3 个相机位置,两个相机角度)确定。

最终,使用估计的颜色和不透明度,NeRF 确定光线的预期颜色(等式 1)。对于实际实施,NeRF 将整数近似为有限和(等式 2),称为分层采样。实验中的样本数为 64,128,256。

等式 1。输入光线的预期颜色。

等式 2。方程式 1 的近似值。

NeRF 架构不需要保留每个特性;因此,NeRF 是由 MLP 而不是 CNN 组成的。它还使用两种技术来提高其性能:位置编码分层体积采样

位置编码

NeRF 没有使用五个简单的相机参数,而是使用位置编码,这种编码经常在 NLP(自然语言处理)中使用。在颜色和几何图形的高频变化中,使用简单输入通常表现不佳。位置编码便于网络通过容易地将输入映射到更高维空间来优化参数。 NeRF 表明,使用高频函数映射原始输入能够更好地拟合包含高频变化的数据。消融研究是这一论点的证据(表 1)。

等式 3。位置编码。

图一。NeRF 的整体架构,它使用位置编码而不是简单的输入。

表 1。位置编码的效果。使用位置编码提高了每个指标的性能。

分层体积取样

NeRF 提出了一个层次结构。整个网络架构由两个网络组成:一个是粗网,另一个是细网

粗糙网络使用 N_c 个采样点来评估光线的预期颜色。顾名思义,它首先从粗采样开始优化。等式 4 是粗略网络的正式定义。

等式 4。粗糙网络

精细网络使用 N_c + N_f = N 个采样点来评估光线的预期颜色。这个等式与等式 2 相同。表 2 显示了关于等级结构影响的消融研究。然而,依我拙见,表 2 中的(4)和(7)之间的比较并不公平。是因为(4)和(7)之间的 N_c + N_f 不一样。如果(4)中的 N_f 值是 192(=128 + 64),这可能是一个更公平的比较。

表二。等级结构效应的烧蚀研究。

损失函数

该网络的最终目标是正确预测光线的预期颜色值。由于我们可以使用地面真实 3D 模型来估计地面真实光线颜色,因此我们可以使用具有 RGB 值的 L2 距离作为损失。好在每一步都是可微的;因此,我们可以通过光线的预测 RGB 值来优化网络。

作者设计损失函数以实现两个目标。

  1. 很好地优化了粗网络。
  2. 好好优化精细网络。

等式 5。损失函数

结果

-评估指标

PSNR (峰值信噪比):PSNR 越高,MSE 越低。较低的 MSE 意味着地面真实图像和渲染图像之间的差异较小。因此,PSNR 越高,模型越好。

SSIM (结构相似度指标):检查与地面真实图像模型的结构相似度。SSIM 越高,模型越好。

LPIPS (学习感知图像块相似度):确定与感知视图的相似度;使用 VGGNet。LPIPS 越低,型号越好。

-实验结果(定量结果)

表二。实验结果

NeRF 在所有任务中都实现了一流的性能。

-可视化(定性结果)

图二。用可比较的模型可视化 NeRF。

  • NeRF 还解决了视图依赖问题模型根据视图有不同的颜色。如图 3 所示,与其他模型不同,NeRF 架构会自动学习视图相关的颜色值。

图 3。NeRF 的视图相关结果。

结论

NeRF 证明,将场景表示为 5D 神经辐射场比以前占主导地位的训练深度卷积网络输出离散体素表示的方法产生更好的渲染。作者期望 NeRF 模型可以用不同的结构进一步优化。此外,NeRF 的可解释性不如以前的方法,如体素和网格。

论文链接:https://arxiv.org/abs/2003.08934

NeRF 官方链接:【https://www.matthewtancik.com/nerf

随时联系我!" jeongyw12382@postech.ac.kr "

嵌套交叉验证—超参数优化和模型选择

原文:https://towardsdatascience.com/nested-cross-validation-hyperparameter-optimization-and-model-selection-5885d84acda?source=collection_archive---------8-----------------------

深入研究嵌套交叉验证

图片由穆罕默德·哈桑来自 Pixabay

交叉验证也被称为抽样外技术是数据科学项目的一个基本要素。这是一个重采样程序,用于评估机器学习模型并评估该模型在独立测试数据集上的表现。

超参数优化或调整是为机器学习算法选择一组超参数的过程,该算法对特定数据集表现最佳。

交叉验证和超参数优化都是数据科学项目的一个重要方面。交叉验证用于评估机器学习算法的性能,超参数调整用于找到该机器学习算法的最佳超参数集。

没有嵌套交叉验证的模型选择使用相同的数据来调整模型参数和评估模型性能,这可能导致模型的乐观偏置评估。由于信息泄露,我们对训练或测试数据中的错误估计很差。为了解决这个问题,嵌套交叉验证应运而生。

使用支持向量分类器比较虹膜数据集的非嵌套和嵌套 CV 策略的性能。你可以观察下面的性能图,从这篇文章

来源:sci kit-了解嵌套与非嵌套交叉验证

什么是嵌套交叉验证及其实现?

嵌套交叉验证 ( Nested-CV )嵌套交叉验证和超参数调整。它用于评估机器学习算法的性能,还用于估计底层模型及其超参数搜索的泛化误差。

除了嵌套循环外,还有几种循环策略,阅读下面提到的文章以了解更多关于不同循环程序的信息。

[## 了解 8 种交叉验证

交叉验证及其类型的深入解释

towardsdatascience.com](/understanding-8-types-of-cross-validation-80c935a4976d)

第 1 步:列车测试分离:

将给定的预处理数据集分割成训练测试数据,训练数据可用于训练模型,测试数据被隔离以评估最终模型的性能。

(图片由作者提供),将数据分为训练和测试数据

这不是一个强制步骤,整个数据可以用作训练数据。将数据分为训练数据和测试数据对于观察未知测试数据的模型性能至关重要。用测试数据评估最终模型表明了该模型对于未来未知点的性能。

第二步:外部简历:

基于机器学习算法在嵌套交叉验证的外环上的性能来选择机器学习算法。 k 倍交叉验证或 StaratifiedKfold 过程可以根据数据的不平衡性在外环实现,将数据平均分成 k 倍或组。

  • k 倍 CV: 此程序将数据分割成 k 倍或组。(k-1)组将被分配用于培训,其余组用于验证数据。对 k 个步骤重复该步骤,直到所有组都参与了验证数据。
  • StatifiedKfold CV: 该程序类似于 k-fold CV。这里,数据集被划分成 k 个组或折叠,使得验证和训练数据具有相同数量的目标类标签实例。这确保了一个特定的类不会过度出现在验证或训练数据中,尤其是当数据集不平衡时。

(图片由作者提供),左: k-fold 交叉验证,右:分层 k-fold 交叉验证,每个 fold 都有相同的目标类实例

根据数据集的不平衡程度,可以为外部 CV 选择 k-fold 或 Stratifiedkfold CV。

第三步:内部简历:

然后,将内部 CV 应用于来自外部 CV 的(k-1)个折叠或组数据集。使用 GridSearch 优化参数集,然后用于配置模型。然后使用最后一个折叠或组来评估从 GridSearchCV 或 RandomSearchCV 返回的最佳模型。该方法重复 k 次,通过取所有 k 个分数的平均值来计算最终 CV 分数。

步骤 4:调整超参数:

Scikit-learn 包提供了 GridSearchCVrandomsearccv实现。这些搜索技术通过调整给定的参数返回最佳的机器学习模型。

第五步:拟合最终模型:

现在,您已经有了最佳模型和一组超参数,它们对该数据集表现最佳。您可以针对看不见的测试数据评估模型的性能。

Python 实现:

信用卡欺诈数据集用于从 Kaggle 下载的以下实现中。

(作者代码)

嵌套 CV 的成本:

使用 Nested-CV 极大地增加了模型的训练和评估。如果为非嵌套 CV 训练 nk 个模型,那么要训练的模型的数量增加到 kn*k

结论:

当同一个数据集用于使用 CV 调整和选择模型时,很可能会导致对模型性能的乐观偏见评估。因此,嵌套 CV 比非嵌套 CV 更常用,因为它有助于克服偏差。

使用 nested-CV 极大地增加了模型评估的数量,从而增加了时间复杂度。当数据集太大或者您的系统功能不强大时,不建议使用它。

感谢您的阅读

嵌套数据结构和嵌套循环

原文:https://towardsdatascience.com/nested-data-structures-and-nested-loops-247eb5fa016d?source=collection_archive---------35-----------------------

循环中的循环…循环中的循环。

照片由卡伦·乔卡Unsplash 拍摄

我在熨斗学校参加兼职数据科学项目的第二周,到目前为止一切都很顺利!在考虑了什么样的职业道路最适合我之后,我决定从事数据科学方面的职业。我拥有心理学和哲学的双学士学位,但直到最近,我还没有在这些领域中找到我特别热爱的领域。多亏了新冠肺炎疫情和几个月的隔离,我终于能够在熨斗公司追求我在技术、统计和编码方面的兴趣。我喜欢我的老师和我的友好的同龄人,我发现到目前为止我对材料有很好的理解。

不过,有一件事让我陷入了一个循环(绝对是双关语):Python 中的嵌套循环

在这个项目开始的时候,我们被鼓励在博客上写下我们可能会发现具有挑战性的材料的各个方面,以便帮助我们自己更深入地理解它,同时也帮助其他人学习。起初,嵌套循环对我来说很棘手,因为它们是其他循环中的循环。我发现,在构建嵌套循环结构的过程中,分解它并一次只关注一个循环会有很大帮助。

我写这篇文章所做的工作还包括理解 Python 中的字典和列表理解,这两个主题一开始也有点难。和大多数障碍一样,我越努力克服它,它就变得越容易。考虑到这一点,下面是使用嵌套循环在 Python 中处理嵌套数据的一些工作。

我先说一些代表我家的数据。

my_family = [ { "family_name": "Tunnicliffe", "num_people": 4, "local": True, "city": "Bethpage, NY", "date_established": 2014, "names": ["Diane", "Steve", "Dylan", "Landon"], "number_of_children": 2, "children": [ { "name": "Dylan", "age": 5, "favorite_color": "black", "nickname": "Dillybeans", "loves": "Super Mario", }, { "name": "Landon", "age": 2, "favorite_color": "blue", "nickname": "Landybean", "loves": "trucks", } ] }, { "family_name": "Agulnick", "num_people": 5, "local": False, "city": "Newton, MA", "date_established": 1987, "names": ["Ellen", "Mark", "Diane", "Joshua", "Allison"], "number_of_children": 3, "children": [ { "name": "Diane", "age": 31, "favorite_color": "pink", "nickname": "Dini", "loves": "unicorns", }, { "name": "Joshua", "age": 28, "favorite_color": "red", "nickname": "Joshie", "loves": "trains", }, { "name": "Allison", "age": 26, "favorite_color": "purple", "nickname": "Alli", "loves": "candy", } ] }]

上面,我使用了变量my_family来存储一个包含两个字典的列表:一个用于我居住的家庭单元(我自己、我丈夫和我们的两个孩子),另一个用于我出生的家庭单元(我的父母、我自己和我的兄弟姐妹)。Python 中的字典是以键:值对的形式存储数据的对象。所以在第一个字典中,对于"family name"的键,我们有"Tunnicliffe"的值。这在使用键和值来访问信息时变得很有用,尤其是在嵌套循环中。

Marco SecchiUnsplash 上拍摄的照片

现在,假设我想访问我居住的城市。为了获得这些数据,我将调用第一个字典并寻找与键"city"相关联的值:

print(my_family[0]['city'])

作为回应,我会得到:

Bethpage, NY

这样做是因为我知道代表我居住的家庭的数据存储在第一个列表对象中,即一个字典,索引为my_family[0]。由于‘city’是该词典的一个属性,因此很容易理解,例如:

print (f"I live in {my_family[0]['city']}.")

我们会有:

I live in Bethpage, NY.

好的,这很有意义,也很简单。现在,如果我想创建一个两个家庭中每个人的名字的列表,作为一个组合列表,该怎么办呢?为此,我可以使用嵌套的 For 循环:

names = []for unit in my_family: for name in unit['names']: names.append(name)print(names)

就在那里。循环中的循环。外部循环由for unit in my_family:指定,它访问 my_family 中包含的我的列表中的两个字典。而for name in unit['names']是内部循环,它访问两个字典的键names的所有值。最后,我们的 append 方法意味着,对于列表my_family中的每个家庭单元字典,以及该家庭单元的名称列表中的每个名称,将这些名称添加到名为names的列表中。因此,作为回应,我们得到:

['Diane', 'Steve', 'Dylan', 'Landon', 'Ellen', 'Mark', 'Diane', 'Joshua', 'Allison']

酷!现在我们有进展了。值得注意的是,在我写unitname的地方,你可以放任何你想要表示元素的变量。例如,我本来可以写for blob in my_familyfor narwhal in unit['names'].,但是这里的目标是让事情更有意义,而不是更少,所以我选择了更符合逻辑(尽管不那么有趣)的变量名。让我们更进一步。现在我要一份孩子的名单。我可以这样得到:

children = []for unit in my_family: for child in unit['children']: children.append(child['name'])print(children)

我会:

['Dylan', 'Landon', 'Diane', 'Joshua', 'Allison']

或者如果我想要他们的昵称列表:

children = []for unit in my_family: for child in unit['children']: children.append(child['nickname'])print(children)

我会看到这个列表:

['Dillybeans', 'Landybean', 'Dini', 'Joshie', 'Alli']

请注意,我在这里使用的“儿童”一词相当宽松,因为我把我自己和我的兄弟姐妹列为儿童,而我们在技术上都是成年人。(虽然我们可能感觉不像成年人,我们的兴趣,在我们的数据集中由关键字'loves':指定,当然说明了这一点。)如果我想找到我出生的家庭单元中的孩子的年龄,记住我们将这个单元指定为非本地单元(从地理上来说)会有所帮助。因此,要访问这些信息,我可以这样写:

child_ages = []for unit in my_family: if unit['local'] == False: for child in unit['children']: name_and_age = child['name'], child['age'] child_ages.append(name_and_age)print (child_ages)

我们会看到非本地家庭单元中儿童的姓名和年龄列表:

[('Diane', 31), ('Joshua', 28), ('Allison', 26)]

事实上,我和我的兄弟姐妹都是成年人了。

为了加深我们对这一切是如何工作的理解,让我们再做几个。假设我想找出哪个孩子对超级玛丽真正感兴趣。我可以这样做:

loves_Mario = Nonefor unit in my_family: for child in unit['children']: if child['loves'] == 'Super Mario': loves_Mario = child['name']print (f"{loves_Mario} really loves Super Mario.")

照片由 Cláudio Luiz CastroUnsplash 上拍摄

我们的书面回复是:

Dylan really loves Super Mario.

是真的!我的儿子迪伦对超级马里奥非常着迷。当我写这篇文章的时候,他穿着超级马里奥睡衣和布瑟袜子。注意,这里使用了==操作符来证明与键child[‘loves']关联的值和与"Super Mario"关联的值是相同的。与上面使用的类似类型的代码公式可以用于访问任何信息,从兴趣到喜欢的颜色。例如:

loves_trains = Noneloves_trains_age = Nonefor unit in my_family: for child in unit['children']:

        if child['loves'] == 'trains': loves_trains = child['nickname'] loves_trains_age = child['age']print (f"{loves_trains} is still very much into trains, even at the age of {loves_trains_age}.")

我们有:

Joshie is still very much into trains, even at the age of 28.

或者:

likes_blue = Nonefor unit in my_family: for child in unit['children']: if child['favorite_color'] == 'blue': likes_blue = child['name']print (f"{likes_blue}'s favorite color is blue.")

我们的答案是:

Landon's favorite color is blue.

一旦掌握了访问嵌套信息的诀窍,它就变得像访问 Python 中的任何其他字典项一样合乎逻辑。最后,让我们看看能否找到my_family最大和最小的孩子。为此,我将使用嵌套循环和排序,这个任务在之前的实验中让我非常头疼。但是,我现在已经多练习了一点,所以让我们试一试。

oldest_child = Noneyoungest_child = Nonechildren = []for unit in my_family: for child in unit['children']: children.append(child)sorted_children = (sorted(children, key = lambda child: child['age'], reverse = True))oldest_child = sorted_children[0]['name']youngest_child = sorted_children[-1]['name']print(f"The oldest child is {oldest_child}. The youngest child is {youngest_child}.")

请击鼓…

The oldest child is Diane. The youngest child is Landon.

我自己,我丈夫和我的孩子。我的(本地)家庭,在上面的数据中引用为 my_family[0]。

代码不会说谎。我是数据集中最大的孩子,我最小的儿子兰登是最小的。考虑到这整个嵌套循环的概念在几天前对我来说是多么令人沮丧,我不得不说写这个实际上比我预期的更有趣。(我不知道我的兄弟姐妹们会对这次冒险有什么感觉,所以我们不要告诉他们火车、糖果以及在网上列出他们的年龄。)

我认为到目前为止我学到的最重要的事情是,当谈到 Python 时,任何问题都可以通过结合信息(无论是来自课堂材料、教师和同龄人,还是 Google)和大量实践来解决。我现在可以看到一段代码,并且通常可以计算出它的输出是什么。当涉及到嵌套数据时,它可以被一行一行地分解成小块,以准确地计算出您试图访问的信息。

。NET 核心 API —深入研究 C#

原文:https://towardsdatascience.com/net-core-api-dive-into-c-27dcd4170066?source=collection_archive---------23-----------------------

为英雄角之旅教程构建一个后端 web 服务器

Unsplash 上的照片

如果你一直跟随系列大纲,并且有一个工作数据库,一个角游英雄 App ,一个通用。我们现在已经进入了这个系列的核心部分,为我们的。NET API。

要继续学习,您可以下载。NET API+Docker MSSQL DB+Angular app 来自我的 GitHub repo。

本文中我们将遵循的流程是:

  1. 连接字符串和 Startup.cs
  2. 模型
  3. 脚手架控制器
  4. 控制器路由
  5. 邮递员测试
  6. 克-奥二氏分级量表
  7. 修改角度应用程序

我们开始吧!

如果你没有看过这个系列的介绍,我强烈推荐。如果你刚入门,已经有了一个通用的 API,那太好了!如果从头开始,只需从命令行运行:

dotnet new webapi -n Heroes.API

这将创建一个样本。用假天气预报数据的 NET 核心 API。我有。NET Core 3.0.2 安装在我的机器上,所以所有的依赖项都将针对 3.0.2。

从示例 API 中,删除WeatherForecast.csWeatherForecastController.cs

导入包

我们需要几个包裹来装我们的。NET 核心应用程序来工作。您可以使用 NuGet 软件包管理器或从命令行安装这些软件包:

dotnet add package Microsoft.EntityFrameworkCore --version 3.0.2
dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 3.0.2
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design --version 3.0.0
dotnet add package Microsoft.EntityFrameworkCore.Design --version 3.0.2

模型

在名为 Model 的目录下新建一个文件夹,在 Model 文件夹下新建一个名为Hero.cs的 C#类。

该模型将定义数据库和应用程序中数据的属性,因此我们只需添加idname的值。

英雄。API/Model/Hero.cs

namespace Heroes*.*API*.*Model{
    *public* class HeroValue
    {
        *public* int id { get; set; }
        *public* string name { get; set; }
    }
}

现在,我们需要添加一个数据库上下文来管理。NET 核心数据模型和数据库。我们将我们的上下文类命名为HeroesContext,它将从 DbContext 继承。HeroesContext将包含一个 DbSet HeroValues,它对应于我们在 SQL 中的表名。

创建一个名为Data的文件夹,并添加一个名为HeroesContext.cs的新 C#文件。将以下代码添加到您的HeroesContext.cs中。

英雄。API/Data/HeroesContext.cs

using Microsoft.EntityFrameworkCore;
using Heroes.API.Model;namespace Heroes.API.Data
{ public class HeroesContext : DbContext
    {
        public HeroesContext (DbContextOptions<HeroesContext> options)
            : base(options)
        {
        } public DbSet<HeroValue> HeroValue { get; set; }
    }
}

我们还需要在我们的Startup.cs文件中添加一个对 DbSet 的引用,这样。NET 知道使用HeroesContext作为与数据库交互的上下文。我们还将把数据库的连接字符串添加到我们的appsettings.json文件中。

将这个添加到您的public void ConfigureServices下的Startup.cs文件中。在我们的例子中,我们使用 Docker MSSQL 数据库进行测试和开发。

services.AddDbContext<HeroesContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DockerDB")));

将“DockerDB”连接字符串添加到appsettings.json

"ConnectionStrings": {
    "DockerDB": "Server=localhost,1433;Database=heroes;User ID=SA;Password=Password1!"
  }

脚手架控制器

为了创建HeroesController,我们将使用 aspnet-codegenerator 工具为我们搭建控制器。

首先,我们必须从命令行安装该工具。然后,从项目的根目录中,运行aspnet-codegenerator

# Install the tooldotnet tool install --global dotnet-aspnet-codegenerator --version 3.0.0# Run the aspnet-codegeneratordotnet aspnet-codegenerator controller -name HeroesController -async -api -m HeroValue -dc HeroesContext -outDir Controllers

完成后,您将看到在控制器文件夹下创建了一个名为 HeroesController 的新文件。打开它可以看到为您创建的基本控制器。这个工具对于把你的控制器的基本结构安排到位是非常有用的。现在,让我们编辑控制器,以匹配来自我们的 Angular 应用程序。

使用代码生成器有一个意想不到的副作用。它为 DbContext 名称的configure services:services.AddDbContext中的连接字符串的Startup.cs添加了一个值,这是有意义的,但不是我们想要在这个开发环境中用于连接字符串的值。替换“HeroesContext”的连接字符串值,使您的services.AddDbContext再次看起来像这样:

services.AddDbContext<HeroesContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DockerDB")));

说到这里,在Startup.cs配置方法中,让我们将注释掉 app。usehttps redirection();。我们的应用程序不需要它。

控制器方法

在我们的控制器中,我们将有 5 个基本方法来与数据库交互,并将值返回给 Angular 应用程序。这 5 个方法由从 Angular 到。NET app。搞什么。NET app 寻找的是带有提供的路由的 HTTP 请求。这些路线是:

  1. GET: api/Heroes — 这个方法将返回数据库中的所有英雄
  2. GET: api/Heroes/5 — 这个方法将从数据库中返回一个特定的英雄。在这种情况下,它将返回 Id 为 5 的英雄。
  3. PUT: api/Heroes/5 — 这个方法会更新一个特定英雄的信息。
  4. POST: api/Heroes — 这个方法会向数据库发布一个新的英雄。
  5. DELETE: api/Heroes/5— 这个方法将从数据库中删除一个特定的英雄。

让我们从头开始。

获取:API/英雄

Angular app 会用这个路由从. NET 中获取所有英雄的 IEnumerable 列表对象,这个方法对应 Angular' hero.service.ts中的getHeroes()方法。

用下面的代码替换第一个 GET 方法,这在很大程度上得益于微软文档为控制器添加了一个搜索功能。记住,Angular 应用程序对几个不同的组件使用 GET: api/Heroes 请求。它需要能够返回英雄仪表板,英雄列表页面的列表,也可以在仪表板上的搜索框中搜索英雄。

我们通过一个异步 ActionResult 来实现这一点,它从 GET 请求中的查询字符串获得信息。该查询可以是 no information,返回所有英雄,也可以是 search string,只返回名字中包含该字符串的英雄。

// *GET: api/Heroes*[HttpGet]
public async Task<ActionResult<IEnumerable<HeroValue>>> GetHeroValue([FromQuery] string name)
{
    // Define a LINQ query
    var heroquery = from h in _context.HeroValue select h;

    // If the string is not empty, find items 'h' whose name contains the query string
    if (!String.IsNullOrEmpty(name))
    {
        heroquery = heroquery.Where(
            h => h.name.Contains(name));
    }// Return an asynchronous list of heroes that satisfy query
    return await heroquery*.OrderBy*(num => num*.id*).*ToListAsync*();
}

让我们使用 Postman 测试 GET 控制器方法。Postman 提供了一种用户友好的方式来测试您的 API。首先,启动你的 Docker 数据库。运行您的。NET 核心 API,方法是从 API 的根目录运行dotnet watch run。当 API 启动并监听端口 5000 时,在 Postman 中,我们将发送 2 个请求来测试我们想要的结果:

  1. [http://localhost:5000/api/Heroe](http://localhost:5000/api/Heroes,)s发出GET请求。观察返回状态为200 OK的 JSON 数组。这将满足我们的仪表板和英雄列表的 GET 请求。
  2. [http://localhost:5000/api/Heroes/?name=wonde](http://localhost:5000/api/Heroes/?name=wonder)rGET请求。观察"id": 1, "name": "Wonder Woman\r"的返回值

恭喜你。您有一个工作的 API!我们建出来按 Id 找英雄吧。

GET: api/Heroes/5

这是我们的 aspnet-codegenerator 真正闪光的地方。我们不需要对这个控制器方法做任何改动。它已经准备就绪,代码已经生成。它只是在路线中找到传递给它的具有匹配 id 的英雄。你的方法应该是:

[HttpGet("{id}")]
public async Task<ActionResult<HeroValue>> GetHeroValue(int id)
{
    var heroValue = await _context.HeroValue.FindAsync(id); if (heroValue == null)
    {
        return NotFound();
    } return heroValue;
}

在邮递员中测试:

  • [http://localhost:5000/api/Heroes/2](http://localhost:5000/api/Heroes/2)运行一个GET请求,观察一个 JSON 结果“id”:5,“name”:“Bat Man \ r”。

PUT: api/Heroes/5

这也是 aspnet-codegenerator 为我们完美搭建的一个方法。只需运行一个邮差测试来进行测试:

  • [http://localhost:5000/api/Heroes/5](http://localhost:5000/api/Heroes/5)运行一个PUT请求。在请求的 Body 下,将 TEXT 更改为 JSON,并填写请求正文,如下所示:
{
    "id": 5,
    "name": "Dr. Strange"
}

如果成功,您将收到请求状态204 No Content

岗位:API/英雄

你需要能够发布新的英雄到数据库。此外,您的 API 需要为新英雄创建 Id,Angular 只提供名称。您的 API 使用 DbSet _context.HeroValue的当前上下文来访问数据库中的值。使用。Max 找到数据库中最高的 Id,用 1 枚举,并将这个新 Id 分配给herovalue.id。然后用.Add.SaveChangesAsync将新的保存到数据库,并返回一个 CreatedAtAction 结果,产生一个状态 201 Created 响应。

[HttpPost]
public async Task<ActionResult<HeroValue>> PostHeroValue(HeroValue heroValue)
{

    if (heroValue == null)
    {
        return BadRequest();
    } // Generate Hero Id
    //[https://github.com/lohithgn/blazor-tour-of-heroes/blob/master/src/BlazorTourOfHeroes/BlazorTourOfHeroes.Server/Controllers/HeroesController.cs](https://github.com/lohithgn/blazor-tour-of-heroes/blob/master/src/BlazorTourOfHeroes/BlazorTourOfHeroes.Server/Controllers/HeroesController.cs)
    // Grab the current context of the DbSet HeroValue
    // Find the max id
    // increase by 1
    heroValue.id = _context.HeroValue.Max(h => h.id) + 1;
    _context.HeroValue.Add(heroValue);
    await _context.SaveChangesAsync(); return CreatedAtAction("GetHeroValue", new { id = heroValue.id }, heroValue);
}

在邮递员中测试:

[http://localhost:5000/api/Heroes/](http://localhost:5000/api/Heroes/)发送一个POST请求,JSON 主体为:

{
 "name": "Poison Ivy"
}

观察Status: 201 Created。成功!

删除:api/Heroes/5

最后,你需要能够删除英雄。这是在 angular 向 API 发送一个 HTTP DELETE 请求时完成的,该请求带有要删除的 hero Id。幸运的是,我们的 DELETE 方法是由 aspnet-codegenerator 完美地生成的。

[HttpDelete("{id}")]
public async Task<ActionResult<HeroValue>> DeleteHeroValue(int id)
{
    var heroValue = await _context.HeroValue.FindAsync(id);
    if (heroValue == null)
    {
        return NotFound();
    } _context.HeroValue.Remove(heroValue);
    await _context.SaveChangesAsync(); return heroValue;
}

关于控制器方法的思考

aspnet-codegenerator 确实帮了我们大忙。我们真正需要考虑的方法只有GET: api\Heroes中的搜索功能和POST: api\Heroes的 Id 生成器。现在我们有了一个可以从 Postman 测试的功能控制器,我们将添加代码来允许跨源资源共享,更好的说法是 CORS。

跨产地资源共享— CORS

Mozilla 文档给了我们一个关于 CORS 的很好的定义。

跨源资源共享 ( CORS )是一种机制,它使用额外的 HTTP 头来告诉浏览器,让运行在一个的 web 应用程序访问来自不同源的选定资源。

我们有一个 angular 应用程序运行在一个端口上。NET API 运行在另一个端口上。NET 不喜欢另一个应用程序未经许可访问它的资源。我们需要使它能够接收来自特定位置的请求,即 angular 应用程序的本地主机端口。

在 ConfigureServices 类上方,创建一个只读字符串:

*readonly* string MyAllowSpecificOrigins = “_myAllowSpecificOrigins”;

在 ConfigureServices 类中,添加AddCors服务。您的 ConfigureServices 类应该如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("[http://localhost:4200](http://localhost:4200)")
                                .AllowAnyHeader()
                                .AllowAnyMethod();
        });
    });
    services.AddControllers();
    services.AddDbContext<HeroesContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DockerDB")));
}

我们正在创建一个构建器,只允许来自[http://localhost:4200](http://localhost:4200)的请求,我们的 angular 应用程序正在该端口运行。此外,从该端口,我们允许任何头和任何方法访问我们的可用资源。NET API。

我们需要为 CORS 做的最后一件事是将我们刚刚创建的服务添加到我们在Startup.cs中的 Configure 方法中。将此添加到您的配置方法中:

app*.UseCors*(MyAllowSpecificOrigins);

你的 API 完成了!现在我们只需将 angular 应用指向您的 API 端点。

回到 Angular 应用程序

我们已经非常接近完成了!只需要对 angular 应用程序进行一些更改,它就可以从我们的 API 请求数据。

应用程序模块

我们需要禁用您在英雄之旅教程中构建的内存 web api。在app.module.ts中注释掉这些导入

//*import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';*//*import { InMemoryDataService }  from './in-memory-data.service';*

然后,注释掉@ngModule() imports下的导入

// *HttpClientInMemoryWebApiModule.forRoot(InMemoryDataService, { dataEncapsulation: false })*

hero.service.ts

我们的公共 HeroService 类包含我们的 angular 应用程序与。NET API。我们应该首先更改 heroesURL 以匹配我们的 API 正在监听的端点:

*private* *heroesUrl* = 'http://localhost:5000/api/Heroes';

我必须更改 HeroService 类的另一件事是为 updateHero 添加一个 const URL。传递的 URL 不正确,导致 405 方法不允许错误。将 URL 添加到 updateHero 类中,使您的类如下所示:

updateHero (hero: Hero): Observable<any> { // Create the route - getting 405 Method not allowed errors
    const url = `${this.heroesUrl}/${hero.id}`; return this.http.put(url, hero, this.httpOptions).pipe(
        tap(_ => this.log(`updated hero id=${hero.id}`)),
        catchError(this.handleError<any>(`updateHero`))
    );
}

现在从 Angular 应用程序的根目录运行ng serve --open。成功!

就这样,您已经构建了一个. NET API!

您可以下载完整版本的。NET API+Docker MSSQL DB+Angular app 来自我的 GitHub repo。

感谢您的阅读!

。英雄角游 App 的 NET 核心 API 简介

原文:https://towardsdatascience.com/net-core-api-for-the-angular-tour-of-heroes-app-5895a36d2129?source=collection_archive---------27-----------------------

从本地开发到云部署的史诗之旅!

亚历克斯·阿扎巴赫在 Unsplash 上的照片

继续之前:

本文假设你已经搭建了 Angular 官方教程——英雄之旅 app。如果你还没有建立这个,你应该检查从这里下载的角度文件其他一切都将在本系列文章中处理!

我们将完成什么

在这个系列中,我们将开始一次神奇的探索。NET Core,Angular,Docker,Azure,Azure SQL Server。

我们将熟悉一些技术,比如 Docker 容器、C#、JavaScript、SQL 和 Azure 命令行界面。

这些文章的最终结果将是一个带有. NET 核心 API 的前端,它与 Azure SQL server 对话,所有这些都托管在 Azure 上。

系列大纲

  1. 这篇文章 MVC 的环境设置和解释。
  2. 微软 SQL 服务器(mssql)的本地 Docker 设置。
  3. 建造。NET API。
  4. 将您的 API 部署到 Azure。
  5. 将您的 Angular 应用程序部署到 Azure。

开始所需的工具

  1. Visual Studio 代码(是免费的)
  2. Angular CLI (应该已经从英雄之旅教程中设置好了)
  3. 。NET Core — 该 API 将使用版本 3.0.2
  4. 邮递员— 用于测试 API
  5. Docker — 用于本地开发数据库,以及封装我们的应用

使用我的 GitHub repo 跟进。

我们开始吧!

安德里亚·莱奥帕尔迪在 Unsplash 上拍摄的照片

测试 Angular 应用

首先,从应用程序的根目录运行ng serve --open,启动英雄之旅 Angular 应用程序。您应该看到应用程序运行在端口 4200 上。

当你创建最初的应用程序时,它有一个内置的网络服务器来模拟真实的服务器。我们将用 C#编写的 web API 替换这个人工服务器。NET 框架。让我们关闭应用程序,开始使用 API。

使用创建一个 web API。网络核心 CLI

确保。运行dotnet --version安装 NET Core CLI。的。NET Core CLI 有许多模板可供选择。用dotnet new -h检查这些选项标志。你看到 ASP.NET 核心 Web API 的模板了吗?它的简称是 webapi。通过运行以下命令从命令行创建 API:

dotnet new webapi -n Heroes.API

你应该会得到一个Restore succeeded的结果。输入cd Heroes.API进入新目录。检查ls以查看已经创建的文件夹和文件,并通过键入(带句点)code .启动该目录中的 VS 代码。

让我们通过运行dotnet run来确保 API 启动。在 web 浏览器中,导航到https://localhost:5001/weather forecast并接受不安全的目的地,以查看您的 API 以 JSON 格式返回的示例输出。这很好,因为它让你知道。NET 核心 API 通过使用模型和控制器来工作。我们将创建自己的模型控制器,还将添加一个数据库上下文

模型-视图-控制器

MVC 是一种 web 开发理念,它建议将应用程序的各个部分分离成逻辑组件。这使得你可以单独构建每一个部分,并确认其工作正常,然后将你的部分连接成一个完整的整体。来自 FreeCodeCamp.org 的这篇文章很好地解释了 MVC 就像在酒吧里点一杯酒。饮料菜单就是视图,你向调酒师(控制器)提出请求,调酒师根据配料和说明(模型)制作饮料,并把你完成的饮料返回给吧台(视图)。

在我们的应用程序中,这意味着:

  1. 视图:Angular app 会接收输入,发出请求,显示数据。
  2. 控制器: C#类,接受传入的请求,解密请求的路由,并根据接收到的路由使用指定的模型与数据库进行交互。
  3. MODEL: C#类,定义传递给数据库或从数据库中检索的数据。这将意味着定义像 id 是一个整数,name 是一个字符串这样的东西,这样 C#就可以用 SQL 可以解释的方式传递这些值。数据库上下文对模型很重要

由作者创建

微软已经发布了关于。NET Core,我强烈推荐查看:

  1. 教程:用 ASP.NET 核心创建一个 web API。
  2. 用 ASP.NET 核心 MVC 创建一个 web 应用

下一步:数据库

此时,您应该有两个资源:

  1. 一个工作角度的英雄之旅应用程序。
  2. 一个仿制药。NET 核心 API。

我们需要创建一个可以处理来自 API 控制器的请求的数据库。我们最终将迁移到托管的 Azure SQL 数据库,但现在,让我们启动一个 Microsoft SQL 服务器的本地 Docker 容器。这个容器是 SQL Server 的一个轻量级版本,我们可以轻松地进行开发。

前往构建一个 MSSQL Docker 容器来设置数据库!

构建一个. NET API 来处理来自 Angular 的请求

打造你的。NET API,在 aspnet-codegenerator 的帮助下。该应用程序将处理对这些路线的 API 请求:

  1. GET: api/Heroes — 该方法将返回数据库中的所有英雄
  2. GET: api/Heroes/5 — 这个方法将从数据库中返回一个特定的英雄。在这种情况下,它将返回 Id 为 5 的英雄。
  3. PUT: api/Heroes/5 — 这个方法会更新一个特定英雄的信息。
  4. POST: api/Heroes — 这个方法将向数据库发布一个新的英雄。
  5. DELETE: api/Heroes/5 — 这个方法将从数据库中删除一个特定的英雄。

在本文结束时,您将拥有 Angular 应用程序的本地版本。NET API 和数据库。

云部署

最后,您将创建一个 Azure SQL server 并部署您的。NET API 到 Azure 远程 git repo,并与 web 应用一起提供服务。

然后你将把你的 angular 应用作为 Docker 容器 web 应用部署到 Azure。

感谢您的阅读!

Python 的每股流动资产净值

原文:https://towardsdatascience.com/net-current-asset-value-per-share-with-python-e6a31a8b6491?source=collection_archive---------38-----------------------

筛选纳斯达克找出廉价公司

每股净资产值(NCAVPS)本杰明·格拉哈姆用来识别有吸引力股票的指标之一。他积极寻找低于每股流动资产净值的股票。

在这篇文章中,我们将使用 Python 构建一个脚本来计算的每股净流动资产价值,并自动识别低于其 NCAVPS 的股票交易。

照片由 佳伟崔 发自 Pexels

什么是每股净资产值(NCAVPS)?

NCAVPS 是一种衡量公司价值的方法,不同于其他传统的估值方法,后者更多地关注不同的指标,如收益。 NACVPS 取流动资产减去总负债,所得结果除以发行在外的股票总数。

NCAVPS =(流动资产-总负债)/已发行股票

当股票交易低于 NCAVPS 价值时,这意味着公司交易低于其清算价值,因此这可能被视为一个良好的买入机会。格雷厄姆感兴趣的是交易价值低于其 NCA VPS 66%的公司。让我们建立一个算法,让 Python 为我们找到这样的公司。

Python 的每股流动资产净值

现在让我们构建一个脚本,它将为我们自动执行以下财务分析:

  1. 在纳斯达克综合指数中搜索 100 只股票,并将每只股票添加到 Python 列表中。
  2. 使用自动收报机从免费 API 中提取第一点中找到的每只股票的 流动资产、总负债和已发行股票
  3. 计算 每股流动资产净值【NCAVPS】
  4. 检查公司交易的 NCAVPS 是否少于 67%
  5. 如果交易量低于 NCAVPS 的 67%,将股票添加到 Python 字典中

为了搜索在纳斯达克交易的公司并获得财务报表信息,我们将使用一个包含大量免费财务数据的 API。

导入所有包后,我们要做的第一件事是发出一个 http 请求,获取纳斯达克综合指数中的 100 只股票。您可以在下面的链接中看到示例响应。

响应是一个字典列表。每本词典都包含一种股票的信息。为了提取每家公司的股票代码,我们只需要提取关键的符号的值。

最后,我们将每个符号附加到一个 Python 列表中。这正是我们用下面的代码实现的。

import requests
import pandas as pd

NetCurrentAssetValueperShare = {}

querytickers = requests.get(f'https://financialmodelingprep.com/api/v3/search?query=&limit=100&exchange=NASDAQ')
querytickers = querytickers.json()

list_500 = querytickers
stocks = []
count = 0
for item in list_500:
    count = count +1
    #Stop after storing 100 stocks
    if count < 100:
        stocks.append(item['symbol'])
print(stocks)
['HRTX', 'GRIF', 'WAFU', 'VOD', 'TRMD', 'KTOV', 'HYXE', 'CLXT', 'TRMB', 'NBL', 'IGIB', 'CDMOP', 'VALX', 'IBTA', 'IBTE', 'FHK', 'IDXG', 'PIE', 'EMMA', 'IBTH', 'SGBX', 'SIFY', 'SUMR', 'TRVI', 'RNSC', 'PLUG', 'AGNC', 'BLUE', 'CENTA', 'BL', 'BSMO', 'ARCE', 'ARCB', 'ARCC', 'AEIS', 'AMTBB', 'CDLX', 'PFIE', 'BYND', 'RFEU', 'DFBH', 'TTD', 'TURN', 'CECE', 'COWN', 'PRPO', 'AXNX', 'BJRI', 'PLC']

用 Python 提取财务报表数据

现在我们有了多家公司的报价器,我们可以使用它们来提取每家公司的 资产负债表 数据。我们将遍历每个公司,并发出一个 http 请求来获得:

  • 流动资产
  • 负债总额
  • 已发行股票

API 端点将公司的股票代码作为参数。我们将把它作为 {company} 传递给每个循环迭代中的 url。检查在以下链接中获得的响应。

金融 中,我们有一个字典列表,我们只想保留列表[0]中的第一个元素,因为它代表最近的季度。我们可以通过使用如下代码所示的相应键来提取流动资产和总负债:

for company in stocks:
    Balance_Sheet = requests.get(f'https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/{company}?period=quarter')

    Balance_Sheet = Balance_Sheet.json()
    try:
        total_current_assets = float(Balance_Sheet['financials'][0]['Total current assets'])
        total_liabilities = float(Balance_Sheet['financials'][0]['Total liabilities'])
        sharesnumber = requests.get(f'https://financialmodelingprep.com/api/v3/enterprise-value/{company}')
        sharesnumber = sharesnumber.json()
        sharesnumber = float(sharesnumber['enterpriseValues'][0]['Number of Shares'])

        NCAVPS = (total_current_assets-total_liabilities)/sharesnumber
        NetCurrentAssetValueperShare[company] = NCAVPS
    except:
        pass

可以从不同的 API 端点提取已发行股票的数量,从而为我们提供关于公司的企业价值的信息。

有了所有需要的信息,我们可以很容易地计算每只股票的 NCAVPS,并将其添加到字典中。

请注意,除了之外,我还使用了 try,以便在 API 请求过程中遇到错误时,脚本不会被中断。

解释每股净资产值(NCAVPS)

根据本杰明·格拉哈姆的说法,投资者应该寻找股价不超过其每股 NCAV 67%的公司。67%代表一个安全边际,因为一些流动资产(即存货)可能不那么容易转换成现金。

因此,我们可以在脚本中通过获取股票价格并将其与 NCAVPS 进行比较来实现这一点。我们只会将 NCAVPS 比股价低 67%或更低的股票添加到我们的字典中。

price = float(sharesnumber['enterpriseValues'][0]['Stock Price']) 

if NCAVPS < 0.67 * price:
     NetCurrentAssetValueperShare[company] = NCAVPS

包扎

现在,如果我们打印我们的 NetCurrentAssetValueperShare 字典,我们会得到下面的结果:

print(NetCurrentAssetValueperShare) {}

不幸的是,我们的脚本返回了一个空字典,这意味着目前在纳斯达克没有股票符合我们的标准。这是有道理的,因为发现公司交易低于其清算价值实际上并不常见。

请随意搜索其他交易所的股票。你可能比我幸运,拿回一些公司。

参见下面用 Python 计算每股净资产值的脚本。很高兴在我的推特账户继续讨论。

import requests
import pandas as pd

NetCurrentAssetValueperShare = {}

querytickers = requests.get(f'https://financialmodelingprep.com/api/v3/search?query=&limit=1000&exchange=NASDAQ')
querytickers = querytickers.json()

list_500 = querytickers
stocks = []
count = 0
for item in list_500:
    count = count +1
    #Stop after storing 50 stocks
    if count < 500:
        stocks.append(item['symbol'])

for company in stocks:
    Balance_Sheet = requests.get(f'https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/{company}?period=quarter')

    Balance_Sheet = Balance_Sheet.json()
    try:
        total_current_assets = float(Balance_Sheet['financials'][0]['Total current assets'])
        total_liabilities = float(Balance_Sheet['financials'][0]['Total liabilities'])
        sharesnumber = requests.get(f'https://financialmodelingprep.com/api/v3/enterprise-value/{company}')
        sharesnumber = sharesnumber.json()
        sharesnumber = float(sharesnumber['enterpriseValues'][0]['Number of Shares'])

        NCAVPS = (total_current_assets-total_liabilities)/sharesnumber

        price = float(sharesnumber['enterpriseValues'][0]['Stock Price']) 
        #only companies where NCAVPS is below the stock price
        if NCAVPS < 0.67 * price:
            NetCurrentAssetValueperShare[company] = NCAVPS
    except:
        pass

NetCurrentAssetValueperShare

原载于 2020 年 3 月 19 日 https://codingandfun.com**

网飞数据科学面试练习题

原文:https://towardsdatascience.com/netflix-data-science-interview-practice-problems-540f2e606c42?source=collection_archive---------53-----------------------

一些网飞面试问题的预演!

自由股票Unsplash 上的照片

网飞是世界上最精英的科技公司之一,所以他们的数据科学面试问题更具挑战性也就不足为奇了。以下是之前在网飞的数据科学面试中被问到的几个面试问题,以及我对这些问题的回答。

问:为什么整流线性单位是一个很好的激活函数?

由作者创建

整流线性单元,也称为 ReLU 函数,已知是比 sigmoid 函数和 tanh 函数更好的激活函数,因为它执行梯度下降更快。请注意,在左侧的图像中,当 x(或 z)非常大时,斜率非常小,这会显著降低梯度下降的速度。然而,这不是 ReLU 函数的情况。

问:正规化有什么用?L1 正则化和 L2 正则化有什么区别?

L1 和 L2 正则化都是用于减少训练数据过拟合的方法。最小二乘法使残差平方和最小,这可能导致低偏差但高方差。

L1 vs L2 正规化

L2 正则化,也称为岭回归,最小化残差平方和加上λ乘以斜率平方。这个附加项被称为岭回归损失。这增加了模型的偏差,使得对训练数据的拟合更差,但是也减少了方差。
如果取岭回归罚分,用斜率的绝对值代替,那么就得到套索回归L1 正则化
L2 不太稳健,但有一个稳定的解决方案,并且总是有一个解决方案。L1 更稳健,但是具有不稳定的解,并且可能具有多个解。

问:在线学习和批量学习有什么区别?

批量学习,也称为离线学习,就是你学习一组组的模式。这是大多数人都熟悉的学习类型,在这种情况下,您可以获取一个数据集,然后一次性在整个数据集上构建一个模型。

另一方面,在线学习是一种一次吸收一个观察数据的方法。在线学习是数据高效的,因为数据一旦被消费就不再需要,这在技术上意味着你不必存储你的数据。

问:在查询数据集时,如何处理空值?还有其他方法吗?

有多种方法可以处理空值,包括:

  • 您可以完全忽略空值行
  • 您可以用集中趋势的度量值(平均值、中值、众数)替换空值,或者用新的类别替换空值(如“无”)
  • 您可以根据其他变量预测空值。例如,如果某一行的 weight 值为空,但它的 height 值为空,则可以用该给定高度的平均重量替换该空值。
  • 最后,如果您正在使用自动处理空值的机器学习模型,则可以保留空值。

问:如何防止模型的过度拟合和复杂性?

对于那些不知道的人来说,过度拟合是一种建模错误,当一个函数与数据过于接近时,会导致新数据引入模型时出现高水平的错误。

有多种方法可以防止模型过度拟合:

  • 交叉验证:交叉验证是一种用于评估模型在新的独立数据集上表现如何的技术。交叉验证最简单的例子是将数据分成两组:定型数据和测试数据,其中定型数据用于构建模型,测试数据用于测试模型。
  • 正则化:当模型具有更高次的多项式时,会发生过拟合。因此,正则化通过惩罚高次多项式来减少过拟合。
  • 减少特征的数量:您也可以通过简单地减少输入特征的数量来减少过度拟合。您可以通过手动移除特征来实现这一点,或者您可以使用一种称为主成分分析的技术,该技术将高维数据(例如 3 维)投影到较小的空间(例如 2 维)。
  • 集成学习技术:集成技术通过 bagging 和 boosting 将许多弱学习者转化为强学习者。通过装袋和增压,这些技术比它们的替代技术更容易过度适应。

问:对于我们正在考虑的新功能,你会如何设计实验?什么样的指标是重要的?

作者创建的图像

我会进行 A/B 测试,以确定新特性的引入是否会在我们关心的给定指标上带来统计上的显著改进。度量标准的选择取决于功能的目标。例如,可以引入一个功能来提高转换率、web 流量或保留率。

首先,我会制定我的零假设(特征 X 不会改善度量 A)和我的替代假设(特征 X 会改善度量 A)。

接下来,我会通过随机抽样来创建我的控制组和测试组。因为 t 检验天生就考虑样本量,所以我不打算指定一个必要的样本量,虽然越大越好。

一旦我收集了我的数据,根据我的数据的特点,我会进行 t 检验,韦尔奇的 t 检验,卡方检验,或贝叶斯 A/B 检验,以确定我的控制组和测试组之间的差异是否有统计学意义。

感谢阅读!

如果你喜欢我的工作并想支持我,我会非常感谢你在我的社交媒体频道上关注我:

  1. 支持我的最好方式就是在媒体T2 上关注我。
  2. 推特 这里关注我。
  3. 点击这里订阅我的新 YouTube 频道
  4. LinkedIn 这里关注我
  5. 在我的邮箱列表 这里报名。
  6. 查看我的网站terenceshin.comT21

网飞推荐系统——大数据案例研究

原文:https://towardsdatascience.com/netflix-recommender-system-a-big-data-case-study-19cfa6d56ff5?source=collection_archive---------0-----------------------

网飞著名的推荐系统背后的故事

图片由 Unsplash 上的 Thibault Penin 拍摄

什么是网飞,他们是做什么的?

网飞是一家媒体服务提供商,总部设在美国。它通过订阅模式提供电影流。它包括电视节目和内部制作的内容以及电影。最初,网飞出售 DVD,并通过邮件提供租赁服务。一年后,他们停止销售 DVD,但继续提供租赁服务。2010 年,他们上线并开始了流媒体服务。从那时起,网飞已经发展成为世界上最好和最大的流媒体服务之一(网飞,2020)。

网飞在电影和电视节目制作中扮演了积极的角色。该公司严重依赖数据。网飞位于互联网和讲故事的中间。他们正在发明新的网络电视。他们的主要收入来源来自用户的订阅费。它们允许用户在任何时候通过各种互联网连接服务(Gomez-Uribe et ),从他们的大量电影和电视节目中获取数据流。艾尔。, 2016).

他们学习的领域(主题领域)是什么?

网飞的主要资产是他们的技术。尤其是他们的推荐系统。推荐系统的研究是信息过滤系统的一个分支(推荐系统,2020)。信息过滤系统处理在数据流到达人类之前从数据流中去除不必要的信息。推荐系统处理推荐产品或给项目分配等级。它们主要被 YouTube、Spotify 和网飞等公司用来为观众生成播放列表。亚马逊使用推荐系统向用户推荐产品。大多数推荐系统通过使用用户的历史来研究用户。推荐系统有两种主要的方法。它们是协同过滤或内容过滤。协同过滤依赖于这样一个概念,即过去喜欢某样东西的人将来也会喜欢同样的体验。基于内容的过滤方法在项目信息已知但用户信息未知的情况下非常有用。它的功能是特定于用户的分类任务。它对分类器进行建模,以对用户关于项目特征的好恶进行建模。

他们为什么想要/需要开展大数据项目?

网飞的模式在一年内从出租/出售 DVD 转变为全球流媒体(网飞科技博客,2017a)。与有线电视不同,互联网电视是关于选择的。网飞希望通过流媒体服务在众多选项中做出选择来帮助观众。有线电视在地理上非常严格。然而,互联网电视的目录上有各种各样的项目,包括来自不同流派、不同人群的节目,以吸引不同口味的人。

销售 DVD 时的推荐问题是预测用户会给 DVD 多少颗星,范围从 1 星到 5 星。这是他们唯一集中精力的任务,因为这是他们从已经看过视频的成员那里得到的唯一东西。他们对观看体验、统计数据没有任何概念,在观看过程中也没有得到任何反馈。当网飞转向流媒体服务时,他们可以获得其成员的大量活动数据。这包括他们与设备相关的详细信息、一天中的时间、一周中的日期以及观看的频率。随着订阅和观看《网飞》的人数增加,这项任务变成了一个大数据项目。

他们想回答什么问题?

网飞就是向用户推荐下一个内容。他们唯一想回答的问题是“如何让用户尽可能地个性化网飞?”。尽管这是一个简单的问题,但几乎是网飞想要解决的所有问题。推荐嵌入在他们网站的每一部分。

推荐从你登录网飞开始。例如,您登录后看到的第一个屏幕由 10 行您最有可能接下来观看的标题组成。意识是他们个性化的另一个重要部分。他们让观众知道他们是如何适应他们的口味的。他们希望客户给他们反馈,同时也培养对他们系统的信任。他们会解释为什么他们认为你会看某个特定的标题。他们使用“基于你对……的兴趣”、“你的口味偏好创造了这一排”等短语。相似性是个性化的另一部分。

网飞从广义上对相似性进行了概念化,如电影、成员、流派等之间的相似性。它使用诸如“相似的标题可以立即观看”、“更像……”等短语。搜索也是网飞推荐系统的一个重要方面。

数据来源:

根据(网飞科技博客,2017b),网飞推荐系统的数据来源是:

  • 一组来自其成员的数十亿个评级。每天都有超过 100 万的新收视率。
  • 他们在许多方面使用流行度指标,并以不同的方式计算它们。例如,他们每小时、每天或每周计算一次。他们还从地理上或通过使用其他相似性度量来检查构成成员的聚类。这些是计算受欢迎程度的一些不同维度。
  • 流相关数据,例如持续时间、播放时间、设备类型、星期几和其他上下文相关信息。
  • 他们的订户每天将数百万的图案和标题添加到他们的队列中。
  • 目录中与某个标题相关的所有元数据,如导演、演员、流派、评级和来自不同平台的评论。
  • 最近,他们添加了用户的社交数据,以便他们可以提取与他们和他们的朋友相关的社交特征,从而提供更好的建议。
  • 网飞订户或成员的搜索相关文本信息。
  • 除了内部数据来源,他们还使用外部数据,如票房信息、演出和影评。
  • 其他特征,如人口统计、文化、语言和其他时态数据,用于预测模型中。

研究中的数据量有多大?也就是说,大约需要多少数据存储?

网飞从 2006 年到 2009 年举办了一场大型比赛,要求人们设计一种算法,可以将其著名的内部推荐系统“电影技术”提高 10%。无论是谁做出了最好的改进,都将获得 100 万澳元的奖励。呈现给用户的数据集的大小是 1 亿个用户评级。该数据集由 480,189 名用户对 17,770 部电影的 100,480,507 个评级组成。2009 年,该奖项被授予一个名为 bell kor ' s practical Chaos 的团队。网飞此后表示,该算法可处理其 50 亿次评级(网飞科技博客,2017 年 a)。因此,网飞推荐系统的数据集的大小被认为包括其所有标题的信息,其数量超过 50 亿。

遇到了哪些数据访问权限、数据隐私问题、数据质量问题?

如(Netflix Prize,2020)中所述,尽管网飞试图匿名化其数据集并保护用户隐私,但围绕与网飞竞赛相关的数据出现了许多隐私问题。2007 年,奥斯汀大学的研究人员通过匹配互联网电影数据库中的用户评级,找到了匿名网飞数据集中的用户。2009 年,与这个问题有关的四个人对网飞提起诉讼,指控其违反了美国的公平贸易法和视频隐私保护法。在此之后,网飞取消了 2010 年及以后的比赛。

他们面临了哪些组织(非技术)挑战?

根据 per (Maddodi 等人,2019 年),在最初几天,网飞遭受了巨大的损失,然而随着互联网用户的增加,网飞将其商业企业模式从传统的 DVD 公寓和收入转变为 2007 年在线视频流的出现。网飞聪明地预见到了迪士尼和亚马逊等竞争对手的到来,因此从很早的阶段就在数据科学领域投入了大量资金。这些努力的大部分仍然在回报网飞,并使其处于流媒体行业的前沿。

他们面临哪些技术挑战?

该团队在构建系统时面临的一些技术挑战如下(ts cher 等人,2009 年):

  • 不同模型的集合来预测单一输出。
  • 优化集合的 RMSE。
  • 模型的自动参数调整也是一个挑战。
  • 捕捉统计相关性的全局效应。
  • 捕捉全球时间效应和工作日效应。
  • 检测短期影响是由于多人共享同一个账户还是由于一个人的情绪变化。

关于与推荐相关的搜索服务,在网飞工程师发表的一篇论文中(Lamkhede 等人,2019 年),提到的挑战是:

  • 从推荐系统的角度看视频的不可用性。
  • 检测、报告和替换不可用的实体。
  • 搜索词的长度通常很短,这使得网飞很难理解用户在搜索什么。
  • 呈现即时搜索,即用户点击的那一刻,然后是好的结果是一个挑战。
  • 通过允许不同的索引方案和指标来优化用户体验。

为什么这是一个“大数据”问题?

大数据的 V(来源)

数量:截至 2019 年 5 月,网飞约有 13,612 种图书(gal,2019)。仅美国图书馆就有 5087 种图书。截至 2016 年,网飞已经完成了向亚马逊网络服务的迁移。他们几十 Pb 的数据被转移到 AWS (Brodkin et al .,2016)。它由他们的工程数据、公司数据和其他文档组成。根据(AutomatedInsights,n.d ),可以近似计算出网飞仅在视频方面就存储了大约 105TB 的数据。然而,他们的推荐算法数据集预计会非常大,因为它需要包含上述所有信息。仅关注 Netflix 奖励任务,给用户的数据在 2GB 左右。它只包含 1 亿的电影收视率。当时,网飞承认它有 50 亿收视率。粗略地说,这相当于 10,000 GB 的评级数据。今天的规模将大于上述数字。

速度:截至 2019 年底,网飞拥有 100 万订户和 1.59 亿观众(BuisinessofApps,2020)。每当观众在网飞上观看某个节目时,它都会收集使用统计数据,如观看历史、标题评级、其他具有相似品味的人、与他们的服务相关的偏好、与标题相关的信息,如演员、流派、导演、上映年份等。此外,他们还收集有关数据时间、观看内容的设备类型、观看时长的数据(网飞,未注明日期)。平均每个网飞用户每天观看 2 小时的视频内容(Clark,2019)。尽管没有明确说明所有的功能,但网飞被认为从用户那里收集了大量的信息。网飞平均每天播放大约 200 万小时的内容。

准确性:准确性由数据中的偏差、噪声和异常组成。关于 Netflix 奖挑战,在数据中观察到了很大的差异。不是所有的电影都被一个人平等地评价。一部电影只有 3 个评分,而一个用户对超过 17,000 部电影进行了评分(ts cher 等人,2009)。就信息的类型和数量而言,网飞数据肯定会包含许多异常、偏差和噪声。

多样性:网飞表示,它以结构化格式收集大部分数据,如一天中的时间、观看时长、受欢迎程度、社交数据、搜索相关信息、流媒体相关数据等。然而,网飞也可能使用非结构化数据。网飞一直对其用于个性化的缩略图直言不讳。这意味着视频的缩略图对于不同的人是不同的,即使对于同一视频也是如此。所以,它可以处理图像和过滤器。

谁对研究的进行和结果感兴趣?

网飞的主要利益相关者是它的订户和观众。他们将会直接受到这个项目的影响。网飞推荐系统对该公司来说非常成功,是增加订户数量和观众人数的主要因素。次要利益相关者是其员工,就任务而言,次要利益相关者是网飞的研究团队,他们直接参与算法和系统的开发和维护。亚马逊、Hulu、Disney+、索尼、HBO 等竞争对手也对网飞的实验行为和结果表现出了浓厚的兴趣。毕竟他们才是制作电影的人。他们为什么希望网飞这样的中介机构拿走份额?他们中的许多人已经开始通过推出自己的平台来播放他们的内容,但网飞从一开始就通过在数据和算法上的大量投资而处于领先地位。

他们使用了哪些硬件/软件资源来实施项目?

网飞技术栈(来源

为了建立一个推荐系统并进行大规模分析,网飞在硬件和软件方面投入了大量资金。网飞提出了一个如何处理任务的架构(巴西利科,2013)。

它如何执行推荐有三个阶段。来自(网飞科技博客,2017c),离线计算应用于数据,它与用户的实时分析无关。执行时间宽松,算法批量训练,对固定时间间隔内要处理的数据量没有任何压力。但是它需要经常接受训练以吸收最新的信息。模型训练和结果的批量计算等任务是离线执行的。因为它们处理大量数据,所以通过 Pig 或 Hive 在 Hadoop 中运行它们将是有益的。调查结果必须公布,不仅要得到 HDFS 的支持,还要得到 S3 和卡珊德拉等其他数据库的支持。为此,网飞开发了一个名为 Hermes 的内部工具。它也是一个类似 Kafka 的发布-订阅框架,但它提供了额外的功能,如“多 DC 支持,跟踪机制,JSON 到 Avro 的转换,以及一个名为 Hermes console 的 GUI”(mor gan,2019)。他们需要一种工具来透明地有效监控、警告和处理错误。在网飞,近线层由离线计算的结果和其他中间结果组成。他们使用 Cassandra、MySQL 和 EVCache。优先级不是要存储多少数据,而是如何以最有效的方式存储数据。网飞的实时事件流是由一个叫做 Manhattan 的工具支持的,这个工具是内部开发的。它非常接近 Twitter 的 Storm,但它根据内部需求满足不同的需求。通过登录 Chukwa 到 Hadoop 来管理数据流。网飞严重依赖亚马逊网络服务来满足其硬件需求。更具体地说,他们使用 EC2 实例,这些实例很容易扩展并且几乎是容错的。他们所有的基础设施都运行在云中的 AWS 上。

图 1:网飞个性化的系统架构和建议(网飞科技博客,2013)——来源

他们需要什么样的人/专业资源来开展项目?

网飞在数据科学上投入巨资。他们是一家数据驱动型公司,几乎在每个层面都使用数据分析进行决策。根据(Vanderbilt,2018),大约有 800 名网飞工程师在硅谷总部工作。网飞还雇佣了一些最聪明的人才,数据科学家的平均工资非常高。它拥有在数据工程、深度学习、机器学习、人工智能和视频流工程方面具有专业知识的工程师。关于 Netflix 奖挑战赛,获胜团队“BellKor 的实用主义混乱”由 Andreas Toscher 和 Michael Jahrer (BigChaos)、Robert Bell、Chris Volinsky (AT & T)、Yehuda Koren(雅虎)(BellKorr 团队)和 Martin Piotte、Martin Chabbert(实用主义理论)组成。

他们需要什么流程和技术?

除了上面提到的工程技术,网飞工程师卡洛斯·a·戈麦斯-乌里韦和尼尔·亨特(Gomez-Uribe et。艾尔。,2016)指出,他们的推荐系统使用监督方法,如分类和回归,以及非监督方法,如使用主题建模的维数减少和聚类/压缩。矩阵分解、奇异值分解、分解机、概率图形模型的连接和方法,它们可以很容易地扩展以适应不同的问题。
关于 Netflix 奖挑战赛,使用了 107 种算法作为组合技术来预测单个输出。矩阵分解、奇异值分解、受限玻尔兹曼机是给出良好结果的一些最重要的技术。

大概的项目进度/持续时间是多少?

据(网飞科技博客,2017 年 a)报道,解决网飞任务的工程师报告称,他们需要 2000 多个小时的工作来构建一个由 107 个算法组成的集合,从而获得了这个奖项。网飞已经取得了它的源代码,并努力克服它的局限性,例如将它们的收视率从 1 亿提高到 50 亿。

取得了哪些成果/答案?项目为组织和利益相关者带来了什么价值?

如(戈麦斯-乌里韦等)中所述。艾尔。, 2016),

  • 在推荐系统的帮助下,用户对网飞的整体参与度有所提高。这降低了取消率,增加了流媒体播放时间。
  • 他们的用户每月流失率非常低,其中大部分是由于支付网关交易失败,而不是由于客户选择取消服务。
  • 个性化和推荐每年为网飞节省超过 10 亿美元。
  • 今天人们观看的 75%的内容是由他们的推荐系统提供的。
  • 会员满意度随着推荐系统的发展和变化而提高。

关于 Netflix 奖任务,获胜的算法能够提高预测评级,并将“电影技术”提高 10.06% (Netflix 奖,2020 年)。根据(网飞科技博客,2017b),奇异值分解能够将 RMSE 降低到 89.14%,而受限玻尔兹曼机器有助于将 RMSE 降低到 89.90%。他们一起将 RMSE 降低到 88%。

项目成功了吗?

对数据科学技术的投资帮助网飞成为视频流行业的佼佼者。个性化和推荐每年为公司节省 10 亿美元。此外,这也是吸引新用户加入平台的重要因素之一。此外,关于 Netflix 奖竞赛的获奖算法,其许多组件今天仍在推荐系统中使用(网飞科技博客,2017b)。因此,这个项目可以被认为是成功的。

有没有发现什么惊喜?

按照 per(t scher 等人,2009)的说法,他们意外地发现了二进制信息,这可以理解为人们不会随机选择和评价电影的事实。令人惊讶的是,在数据集中观察到非常强烈的一日效应。这可能是因为多人使用同一个帐户,也可能是因为一个人的情绪不同。

从实施这个项目中学到了什么?

集合技术带来了好的结果。多种技术结合起来预测单一结果,而不是改进单一技术。
训练模型并单独调整它们不会产生最佳结果。当整个集成方法在多样性和准确性之间具有精确的折衷时,结果是最好的。协作过滤领域已经有了很多开放的研究,Netflix 奖等竞赛可以促进这种开放的想法和研究。

项目实施后采取了哪些具体措施?

作为比赛的结果,网飞修改了获胜代码,将收视率从 1 亿提高到 50 亿(网飞科技博客,2017b)。直到今天,它甚至在其最先进的推荐系统中使用获奖项目的代码。网飞将其在视频流行业的成功归功于该项目及其进一步的研究和持续发展。

这个项目是如何改进的?

A/B 测试的程序和步骤可以通过包括通过环境而不是算法的评估来改进。与推荐系统的传统方法相反,它可以使用强化算法来向用户提供推荐。回报可以是用户满意度,状态可以是当前内容,动作可以是下一个最佳内容推荐。

复杂术语的定义:

RMSE (均方根误差):衡量数据点离回归线有多远。它可以用来理解残差的分布。它是通过取误差平方平均值的平方根来计算的。

A/B 测试:A/B 测试是一个统计过程,用来检查你的测试的有效性。第一步,提出一个假设。第二步,收集证据的统计数据,以接受或拒绝假设。第三步,分析数据以推断假设的正确性。

受限玻尔兹曼机器:这是一种人工神经网络,能够在给定一组输入的情况下学习潜在的概率分布。它可以用于监督学习和非监督学习。在分类、推荐引擎、主题建模等方面有很多应用。

EC2: 术语 EC2 代表弹性计算云。是亚马逊云计算平台的重要组成部分之一。任何公司都可以在 EC2 机器上部署其服务/应用程序,并让它们在短时间内运行。

Hadoop: Hadoop 通过提供一套软件和工具使分布式计算成为可能。它基于 Map Reduce 原理来存储和处理大数据。如今,许多公司使用 Hadoop 进行大规模数据处理和分析。

HDFS: 代表 Hadoop 分布式文件系统。它是作为存储系统的 Hadoop 生态系统的核心组件之一。它的工作原理是 MapReduce。它可以与群集一起提供高带宽。

引用
AutomatedInsights。(未注明)。网飞统计:目录保持多少小时。2020 年 4 月
12 日,来自https://automatedingsights . com/blog/网飞-statistics-how-many-hours-
目录-持有

巴西利科,J. (2013 年 10 月 13 日)。网飞规模的建议。检索于 2020 年 4 月 12 日,来自
https://www . slide share . net/justinbasilic/网飞规模推荐

j . brod kin & Utc。(2016 年 2 月 11 日)。网飞完成了向亚马逊云的大规模迁移。
检索于 2020 年 4 月 12 日,来自https://ars technica . com/information-technology/2016/02/网飞
完成了其向亚马逊云的大规模迁移/

BuisinessofApps。(2020 年 3 月 6 日)。网飞收入和使用统计。检索 2020 年 4 月 12 日,发自
https://www.businessofapps.com/data/netflix-statistics/

t .克拉克(2019 年 3 月 13 日)。网飞称其用户平均每天看 2 个小时——以下是与电视相比的情况。检索于 2020 年 4 月 12 日,来自
https://www . business insider . com/网飞-观看-与平均水平相比-电视-观看-尼尔森-图表
2019–3

图一。网飞个性化的系统结构和建议。(2013).系统
个性化和推荐架构【数字图像】,网飞科技
博客。2020 年 4 月 12 日检索,来自https://netflixtechblog.com/system-architectures-for
个性化推荐-e081aa94b5d8。

gal .(2019 年 5 月 14 日)。在你的国家有多少关于网飞的书?于 2020 年 4 月 12 日
https://cord cutting . com/blog/how-number-titles-is-available-on-网飞-in-your
country/

Gomez-Uribe,c . a . & Hunt,N. (2016 年)。网飞推荐系统。美国计算机学会管理信息系统汇刊,6(4),1–19。doi: 10.1145/2843948

Lamkhede,s .,& Das,S. (2019)。流媒体服务搜索面临的挑战。第 42 届国际 ACM SIGIR 信息检索研究与发展会议论文集。多伊:10.1145/333353633437

Maddodi 和 K . K . p .(2019 年)。网飞大数据分析-数据驱动的出现
推荐。SSRN 电子杂志。doi:10.2139/ssrn 3473148

摩根 A. (2019 年 5 月 20 日)。Allegro 发布了 Hermes 1.0,这是一个基于 REST 的消息代理,构建在 Kafka
之上。检索于 2020 年 4 月 12 日,来自https://www.infoq.com/news/2019/05/launch-hermes-1/

Netflix 奖。(2020 年 1 月 20 日)。2020 年 4 月 12 日检索,来自
https://en . Wikipedia . org/wiki/网飞 _ Prize # cite _ note-commendo 0921-27

网飞科技博客。(2017 年 4 月 18 日 a)。网飞推荐:超越五星(第一部分)。
2020 年 4 月 12 日检索,来自https://Netflix tech blog . com/网飞-推荐-超越-the
五星-part-1–55838468 f429

网飞科技博客。(2017 年 4 月 18 日 b)。网飞推荐:超越五星(第二部分)。
2020 年 4 月 12 日检索,来自https://Netflix tech blog . com/网飞-推荐-超越-the
5-stars-part-2-d 9b 96 aa 399 f 5

网飞科技博客。(2017c 年 4 月 18 日)。个性化的系统架构和
建议。2020 年 4 月 12 日检索,来自https://netflixtechblog.com/system
个性化推荐架构-e081aa94b5d8

网飞。(2020 年 4 月 10 日)。检索于 2020 年 4 月 12 日,来自https://en.wikipedia.org/wiki/Netflix

网飞。(未注明)。网飞的推荐系统是如何运作的。检索于 2020 年 4 月 12 日,来自
https://help.netflix.com/en/node/100639

推荐系统。(2020 年 4 月 10 日)。检索于 2020 年 4 月 12 日,来自
https://en.wikipedia.org/wiki/Recommender_system

Tö scher,a .,Jahrer,m .,和 Bell,R. M. (2009 年)。网飞大奖的大混沌解。网飞奖文档,1–52。

t .范德比尔特(2018 年 6 月 22 日)。网飞算法背后的科学决定了你
接下来会看什么。检索 2020 年 4 月 12 日,来自https://www.wired.com/2013/08/qq-netflix算法/

网飞和窗口功能

原文:https://towardsdatascience.com/netflix-window-functions-b6dfe60cf0f6?source=collection_archive---------55-----------------------

一个窗口功能的快速介绍和一个非常真实的看看我实际上看了多少网飞。🙈

如果你和我一样,你会发现自己最近看了很多《网飞》。如果你更像我,你会渴望得到一些数据来证明这一点。

幸运的是,你可以从网飞下载你自己的观看历史,然后自己开一个数据派对!🥳

更好的消息是:这是如何利用强大而难以捉摸的窗口功能的一个很好的例子。这一系列函数通常被认为是“高级”SQL,因此没有得到应有的广泛使用。

在下面的分析中,您将了解更多关于窗口函数的知识,更重要的是,如何充分利用它们。

因此,如果你正在寻找所有窗口功能宣传的内容,或者厌倦了向他人解释窗口功能,或者只是真的想知道我看了多少电视,这是给你的。

玩法:

  1. 如果你是一个视觉型的人,像我一样,你可以在这里看我做分析

2。或者,如果你更喜欢阅读,你可以在这里查看最终分析,或者我已经复制了下面的最终笔记本!

在你开始之前,如果你需要一点关于窗口功能的入门知识,我们已经为你准备好了。以下指南写在 Count 中,但内容适用于任何 SQL 工具!

** [## 我的网飞项目

最近我得知网飞将向你提供他们掌握的所有关于你的信息。好奇心得到了最好的…

count.co](https://count.co/n/0erWed0YsMF)

很难找到实用的数据培训材料来帮助您和您的团队更好地使用数据。我们策划了最好的,并在我们的每周简讯中分享。如果你想了解这一切,请在这里注册。**

目标

确定我“狂看”网飞的频率,以及自 2020 年 3 月“就地安置”指令开始以来,这一频率是否有所增加。

准备👩‍🍳

来自网飞的数据是这样的:

来自网飞的原始格式或数据

****标题字段包含所有重要的位。所以,我决定在“:”上分开,从季节和剧集名称中分离出节目或电影名称。

根据您使用的工具的不同,执行此操作的代码看起来会有所不同,但它们应该都有相同的结果。

根据你的目标,你可能想在这里花更多的时间,但对我来说,这已经足够了!

第二步:探索🧭

在开始任何分析之前,花些时间了解您的数据总是一个好主意。

通过这一步,我发现了一个非常关键的发现:

****网飞只给你最近一次看每一个节目的时间😩。

非常失望。这使得对过去的观看活动建模变得很困难,实际上是不可能的,因为可能有很多我过去看过的(老友记),现在还在看的(老友记)节目,这些都是最近才统计的。

尽管如此,我们坚持!💪

第三步:定义🎯

因为我想了解我的狂看行为,我需要定义它到底是什么。

我决定把狂看定义为:

  • 同一电视节目的任何连续观看,
  • 对于我总共观看了超过 6 个单元的电视节目

那么,我们如何到达那里…

现在,数据看起来像这样:

我需要它看起来像这样:

为此我们需要窗口函数!这里有一个关于窗口函数的快速入门:

** [## 窗口函数说明| BigQuery 语法和示例|计数

关于 SQL 窗口函数你需要知道的一切。窗口函数,或称之为分析函数…

count.co](https://count.co/sql-resources/bigquery-standard-sql/window-functions-explained)

为此,我采取的步骤是:

  1. 通过比较每行中的电视节目和上一行中的电视节目,判断每行是否是正在进行的狂欢会话的一部分
case when lag(first_watch.Show) over (order by first_watch.first_day_watch asc) = first_watch.Show then ‘streak’ else ‘new_streak’ end ‘is_streak’

2。使用行号或索引计算出有多少集

row_number() over (order by first_watch.first_day_watch asc)

3。算出前一集的观看日期。对于连续开始行,这将等于前一个连续的结束日期

lag(first_watch.first_day_watch) over (order by first_watch.first_day_watch asc) last_watch_date

完成这三个步骤后,我离目标越来越近了:

4。仅条纹过滤器启动

5。从首行拉入行号和最后一次观察日期:

lead(starts.row_number) over (order by starts.first_day_watch asc) end_row_numlead(starts.last_watch_date) over (order by starts.first_day_watch asc) binge_end_date

6。最后一点数学知识:

第四步:分析📉

最后,有趣的部分!

点击这里查看图表互动版本!

点击这里查看图表互动版本!

从这两张图表中,我可以说:

  1. 这个月(2020 年 3 月)我看电视的时间确实比平时多(这并不奇怪)。
  2. 一些节目(总是阳光明媚……)是在一个大型狂欢会上观看的,而其他的(朋友)是在更小、更分散的狂欢会上观看的。

那么,现在怎么办?

这就是我今天愿意分享的个人数据的范围,但是你可以想象如果你愿意(我希望你这样做),你可以如何进一步分析。如果你对网飞的数据做了自己的分析,请在评论中告诉我们结果如何!

很难找到实用的数据培训材料来帮助您和您的团队更好地使用数据。我们策划了最好的,并在我们的每周简讯中分享。如果你想了解它的全部内容,请在此注册。**

NetVLAD:弱监督地点识别的 CNN 体系结构

原文:https://towardsdatascience.com/netvlad-cnn-architecture-for-weakly-supervised-place-recognition-ce64b08bebaf?source=collection_archive---------27-----------------------

本文是一篇名为 NetVLAD:弱监督地点识别的 CNN 架构的论文的论文摘要。本文在图像检索任务中很受欢迎,并为地点识别任务提供了关键解决方案。

图像检索结果

卷积神经网络 (CNN)一直是计算机视觉领域的心脏。随着计算资源的巨大发展,人们开始关注如何在降低计算复杂度的前提下提高模型的性能。因此,在图像检索中,CNN 架构用于特征提取。然而,使用 CNN 架构仍然遭受低性能。

图像检索是一个专注于在数据库中找到最相似图像的任务。相似这个关键词看起来很主观,因为相似性没有严格的定义。此外,我们不能使用朴素图像数组来计算相似性。为了解决它,我们定义了一个特征提取函数 f 和距离函数 d。这个方案被称为度量学习。关于度量学习的更多细节解释如下。

视觉地点识别问题重点在于利用数据库中的信息正确定位查询图像。一个候选的解决方案是使用图像检索。对于给定的查询,将其位置近似为最相似图像的位置。这种近似方法被称为实例检索任务。

在本文中,我们将介绍 NetVLAD:弱监督地点识别的 CNN 架构。这篇论文发表于 2016 年,为视觉地点识别任务介绍了一个很棒的 CNN 结构层。

在 NetVLAD 之前

有很多尝试来提取图像中的重要局部特征。不幸的是,最初的 CNN 结构不适合视觉位置识别任务。此外,许多“现成”技术限制了端到端的构建方式。本文的主要贡献如下

  1. 创建一个 CNN 架构,它可以以端到端的方式进行训练,用于视觉位置识别。
  2. 收集足以训练 CNN 架构的数据。
  3. 使用 CNN 架构进行特征提取并评估其性能。

度量学习

演示材料中的幻灯片

度量学习的主要思想是学习距离函数和特征提取函数。为了方便起见,我们通常使用线性函数,并学习它们的参数。因为图像只是简单的整数数组,所以朴素图像很难得到它们之间的距离。因此,我们使用特征提取函数来提取局部描述符。它使用具有 NetVLAD 的 CNN 作为特征提取函数,并使用欧几里德距离作为距离函数。它选择欧几里德距离,因为它在实验中工作得很好。

VLAD(局部聚集描述符的向量)

为了更好地了解什么是 VLAD,我建议你参考以下链接。

[## VLAD——词汇袋的延伸

最近,我参加了 TagMe-一个由微软和印度研究所举办的图像分类竞赛…

ameyajoshi005.wordpress.com](https://ameyajoshi005.wordpress.com/2014/03/29/vlad-an-extension-of-bag-of-words/) [## 关于 VLAD 的一切——IEEE 会议出版物

本文的目标是给定查询图像的大规模对象实例检索。这样的起点…

ieeexplore.ieee.org](https://ieeexplore.ieee.org/document/6619051)

VLAD 不过是一种特征量化技术。它类似于我们熟悉的概念,被命名为词汇袋费希尔向量。当您考虑 k 均值聚类时,它可以帮助您理解。

VLAD 是一个 K×D 矩阵,存储着聚类的信息。最初,K 被给定为超参数,并在嵌入空间中随机初始化 K 个簇。(D 是局部描述符的维度)每一列表示每个簇中残差的总和。我们可以关注输出 0 或 1 的函数 a_k。只有当聚类 k 是最近的中心时,它才是 1,否则是 0。

因为函数 a_k 不再可微,所以它不能是端到端的。因此,它使用一个软赋值来代替。下图显示了软赋值 a_k 的实际定义。当我们充分放大 alpha 值时,它近似于原始 a_k 函数。

此外,我们可以将该函数分解为

看起来我们只需要学习 c_k。然而,在下面的论文中,它表明{c} 、{w}和{b}的解耦依赖提高性能。意思是学习{c}、{w}、{b}比只学习{c}获得更好的表现。进一步的细节将在下面的文章中介绍。

[## 关于 VLAD 的一切——IEEE 会议出版物

本文的目标是给定查询图像的大规模对象实例检索。这样的起点…

ieeexplore.ieee.org](https://ieeexplore.ieee.org/document/6619051)

整体网络结构如下。

网络结构

我们在 Conv5 图层后添加了 NetVLAD 图层,并使用 NetVLAD 图层提取了 VLAD 格式的要素。它在最后执行帧内归一化和 L2 归一化。文件中解释了进一步的细节。

注释数据

不幸的是,在 2016 年,没有一个数据集具有地面真理。因此,他们使用弱监管作为解决方案。

弱监管是指由于缺乏人工标注的数据而带有嘈杂标签的监管。

它使用谷歌街景时光机,只提供它的图像和位置。然后对于每个查询图像,将其他数据库图像分类为潜在阳性确定阴性潜在阳性是距离查询图像 10m 以内的图像。明确否定是距离查询图像超过 25m 的图像。那么我们就可以直观的理解下面的等式了。

如果最相似的图像具有小的距离,损失函数变大,并且确定的负图像与查询不相似。这个损失函数称为三重损失函数。要了解什么是三重损失函数,我推荐你这篇文章

[## 无损三重损耗

一种更有效的暹罗神经网络损失函数

towardsdatascience.com](/lossless-triplet-loss-7e932f990b24)

评估协议和实验细节

本实验中使用的是匹兹堡(Pitts250k,Pitts30k)和 Tokyo24/7,基于谷歌街景时光机。它使用评估协议的召回来计算正确识别的查询的百分比。当前 N 个检索到的数据库图像在 25m 以内时,它被认为是正确定位的。超参数 K 是 64。

结果

  1. 基于 VGG16 的 VLAD 令人信服地优于由“现成”技术组成的 Root-SIFT + VLAD+白化。
  2. NetVLAD 可以为地点识别提供丰富而紧凑的图像表示。
  3. NetVLAD 在视觉地点识别任务中的表现优于 max-pooling。
  4. 无论选择哪种网络主干(AlexNet、VGG16、Places205),它都优于其他最先进的技术。

上图显示了另一个实验的结果。该实验检查了当我们改变最低训练层时,我们获得更好的性能。然而,当我们学习所有层时,会导致过度拟合,从而导致性能下降。

结论

NetVLAD 提供了一个强大的池机制,具有可学习的参数,可以很容易地插入到任何其他 CNN 架构中。因为 NetVLAD 中的所有功能都是可微分的,所以当在网络中使用时,它可以提供端到端的方式。由于其方便性,它仍然是视觉位置识别任务中的一种受欢迎的方法。

演示文稿网址:https://docs . Google . com/presentation/d/168 ermavkmuhghdnag 9j-ivxhcpgsudtlnowu _ 4 mcxq/edit?usp =共享

论文网址:https://arxiv.org/pdf/1511.07247.pdf

联系我:jeongyw12382@postech.ac.kr

网络分析启动

原文:https://towardsdatascience.com/network-analysis-kickoff-84bf41afe020?source=collection_archive---------38-----------------------

实践教程

使用 Python、R & Tableau 进行网络分析的介绍

Clarisse CrosetUnsplash 上拍摄的照片

你的网络给了你更好的眼睛,而不是更好的眼镜。~罗纳德·伯特

什么是网络?

水平线和垂直线交叉的排列。~牛津词典

一组或一个系统的相互联系的人或事物~牛津词典

我们可以称之为基于共同利益基础的拓扑,用于共享信息。每个拓扑都有两个主要部分,一组节点和一组连接节点的顶点。取决于网络的类型,一组节点可以由一组计算机、一组服务器、一组船只、汽车、飞机、城市、人等组成。不用说,为了解释和说明的目的,节点的性质必须尽可能地同质,也就是说,很难同时解释一堆被称为节点的计算机和人,尽管这并不是不可能的。节点通过明显的通信方式连接起来,当我们想在一张纸上或软件上画它们时,我们称它们为顶点。如果它是一个人的网络,那么顶点可以是他们友谊的本质,专业链接的本质,或者通信链接的本质。如果它是一个技术网络,那么顶点可以是网络电缆或 wifi 或电话网络的信号。如果它是一个交通网络,那么顶点可以是海上路线的性质、飞行路线的性质、道路路线的性质等。

在我们真正开始解释力量的度量之前,下面给出了一些更高级的数据表示。引用这句话的目的是让我们做好思想准备。

网络是一种简化的表示,它将系统简化为一个抽象的结构,只获取连接模式的基本信息,其他信息很少。网络中的顶点和边可以用附加信息来标记,例如名称或强度,以捕捉系统的更多细节,但即使如此,在将整个系统简化为网络表示的过程中,许多信息通常会丢失。~ M.E.J .纽曼

无向网络-图片来源:(图片由作者提供)

无向网络是一种更简单的网络形式。它不允许考虑两个节点之间的任何直接关系。例如,在我们假设的相邻网络中,可能有来自(1,2)和(2,1)的信息流。到节点 3 的信息可以从节点 1、2、4 或 5 流出。它也可以被称为对称关系,这表明如果 1 连接到 2,反之亦然。

定向网络-图片来源:(图片由作者提供)

另一方面,有向网络不假设用有向边连接的两个节点会显示两个方向的信息流。因此,由于存在明确的方向,它允许说明两个节点之间的直接关系。例如,在我们知道的相邻网络中(1,2),(2,3),(3,4)是直接相连的。信息不能从(2,1),(3,2),(4,3)流出。然而(1,3)&【3,5】没有方向,因此无向网络的概念成立。

邻接矩阵

简单标记图的邻接矩阵,有时也称为连接矩阵,是具有由图顶点标记的行和列的矩阵,根据 v_i 和 v_j 是否相邻,在位置(v_i,v_j)具有 1 或 0。对于没有自循环的简单图,邻接矩阵的对角线上必须有 0。对于无向图,邻接矩阵是对称的。~ 来源

简而言之,如果两个节点彼此相邻并且直接连接,那么矩阵中的值将是 1,否则该值将是 0。

在上面的无向网络的例子中,(4,5)是相邻的,但是没有边/顶点/连接。因此,该值为 0。(2,3)通过直接连接相邻,因此值为 1。(2,5)彼此不相邻,尽管它们通过节点-3 间接连接,因此值为 0。

无向网络邻接矩阵,图片来源:(图片作者)

有向网络邻接矩阵,图片来源:(图片作者)

无向自环网络邻接矩阵,图片来源:(图片由作者提供)

有向自环网络邻接矩阵,图片来源:(图片由作者提供)

度中心性

度是连接到一个节点的边的数量。它有时被称为网络模式。它告诉我们一个特定的节点可以有多少直接到达。具有最大范围的节点具有最高程度的中心性。它表示对网络的暴露,并且一些具有高程度的节点被期望更受欢迎或更集中。

学位步骤 1 和 2,图片来源:(图片由作者提供)

度 Step-3,图片来源:(图片由作者提供)

中间中心性

介数是特定节点位于其他节点之间最强路径上的程度。它告诉我们一个节点成为网络中任意两个节点之间最直接的路由的可能性有多大。它衡量网络中节点的非正式权力,这种权力可以控制网络两端的信息流。我们想知道网络中潜在路径的数量。具有高介数中心性的节点位于比任何其他节点更多的节点之间的最短路径上。如果网络不是有向的并且没有自循环,那么在“n”个节点之外,我们可以提取 nC2 对。因此,网络中可能有 nC2 条路径。这样,就不会出现重复计算配对的情况。

中间步骤 1,图片来源:(作者图片)

中间步骤 2,图片来源:(作者图片)

中间步骤 3,图片来源:(作者图片)

中间步骤 4,图片来源:(作者图片)

接近中心性

接近度是到网络中所有其他节点的平均最短距离。它告诉我们一个节点到达网络中每个人的速度有多快。它有助于衡量网络中的间接影响。它衡量一条信息从网络的一部分传播到另一部分的速度。在测量接近中心性时,我们不看邻接矩阵。相反,我们着眼于源节点和目的节点之间最短路径的长度。换句话说,距离矩阵说明了我们在到达目的节点的最短路径中需要跳的次数。

亲密度第一步和第二步,图片来源:(作者图片)

亲近第三步,图片来源:(作者图片)

特征值中心性

特征值中心性根据邻居的数量平等地分配重要性。它以与节点邻居的重要性成比例的方式分配重要性。具有较高特征值中心性的节点是网络上信息收集的可能目标。与具有较少连接的节点相比,连接到高度连接的节点将给予节点更大的影响。这有助于确定哪个节点连接到最中心的节点。

我们将寻求软件的帮助来评估矩阵,这将有助于我们更好地解释。特别是,我们将使用 r 中“igraph”包中的“eigen_centrality”函数。我们很快就会谈到代码过程。目前,将单个特征向量除以向量之和将给出我们要解释的特征值(归一化的)。特征值加起来应该是 1。

特征值,图片来源:(图片作者)

因此,根据上面的玩具示例,我们观察到以下情况:-

  1. 节点 1 在网络中具有最大连接数,因此具有最高的度中心性度量。
  2. 对于任何其他两个节点来说,节点 1 大部分时间都处于两者之间进行通信。因此,节点 1 可以很好地控制网络所有端的业务流。因此它具有最高的中心性度量。
  3. Node-1 还可以快速到达网络中的其他对等点,因为它已被证明是一个具有高介数的高效网桥。因此它也具有最高的接近中心性。
  4. Node-1 还连接到大多数其他有影响的节点,因为它在网络中非常接近,并且是网络上信息收集的可能目标。因此,它的特征值中心性也是最高的。

在一个相对较大的稀疏网络中,一个特定的节点吸引所有的注意力不是不可能的,但有点不太可能。如果一个特定的节点度数很高,那么它在有影响力的连接中也很高,这并不是一个规则。

相关矩阵(玩具示例),图片来源:(图片由作者提供)

对于每种类型的网络,相关性的强度可能不相同。网络的每个模式都有自己的相关矩阵和潜在的解释,就像人类的指纹一样。

茶歇

照片由内森·杜姆劳Unsplash 上拍摄

需要数年的数据争论和可视化来吸收集中趋势测量的完整性,如均值、中值、众数等。我们看到和讨论的例子越多,我们在解释理解手头问题的基本汇总方法时就越有可能实现多样性。上述 4 个中心性度量几乎类似于网络或图论中使用的汇总度量。因此,在学习网络问题的初始阶段,计算度量的能力至关重要。然而,总结中心性度量并不是解决端到端网络优化问题所需的唯一设计要素。网络分析或社会网络分析或图论本身是一个巨大的研究课题,解决网络问题需要大量的绘图、计算矩阵和迭代各种图论模型才能得出结论。在本文的剩余部分,我们将重新讨论相同的方法,但是使用一个稍微大一点的网络,并看看 R 和 Python 如何一起帮助我们。我们将以这个研究领域的一些主要贡献者开发的一些基本的必须知道的模型来结束这篇文章。

介绍网络

孟买众所周知,印度拥有亚洲最大的地方铁路网络之一
孟买的大部分人口依靠这些地方火车通勤
这个网络的三个主要连接点位于西部、中部和港口线路。西线包括教堂门至达哈努路。中央线覆盖查特拉帕蒂西瓦吉终点站至 Kalyan、Khopili 和 Kasara。港口线连接孟买到新孟买,直到潘韦尔。据估计,平均每天运送 740 万人。

站名和代码

站名和代码,图片来源:(图片作者)

链接到邻接矩阵****

邻接矩阵快照,图片来源:数据(图片由作者提供)

来自 R 的网络图

网络图,图片来源:代码(图片由作者提供)

R 代码生成图形

度中心性

度中心性图,图片来源:链接(图片由作者提供)

度数是连接到特定节点的本地站的数量
它也被称为网络的“模式”。它告诉我们一个特定车站可以直达的次数。具有最大范围的站具有最高程度的中心性。它表示对网络的暴露,并且具有高度中心性的站预期更受欢迎或更中心。
Kurla (CLA)和 Dadar (DDR)的度中心性都是 4。这意味着他们都连接到 4 个独特的方向和不同的地方站。Kurla 直接连接到 Chunabhatti、Sion、Vidyavihar & Tilaknagar。Dadar 直接连接到 Elphinstone Road、Matunga、Matunga Road & Parel。

中间中心性

中间中心图,图片来源:链接(图片由作者提供)

中间性是特定站(节点)位于其他站(节点)之间的最短路径上的程度。它有时被称为网络的“中间值”。它告诉我们一个站点成为网络中任意两个站点之间最直接的路由的可能性有多大。它衡量网络中能够控制网络两端信息流的非正式权力。
库尔勒(CLA)位于贾特拉帕蒂·希瓦吉终点站(CSTM)到潘韦尔的直达航线之间。库尔勒位于 CSTM 至霍波利的直达路线和 CSTM 经塔那至卡萨拉的路线之间。库尔勒还可以将某人转移到 Dadar-Borivali 或 Dadar-Churchgate 或 Dadar-Dahanu 路。

接近中心性

亲近中心性图,图片来源:链接(图片由作者提供)

接近度是到网络中所有其他站点(节点)的平均最短距离。它有时被称为网络的“平均值”。它告诉我们从那个节点到网络中的每个站有多快。它有助于衡量网络中的间接影响。它衡量一条信息从网络的一部分传播到网络的另一部分的速度。
一旦从 Kurla 经 Sion 到达 Dadar,就可以通过 Matunga 路到达 Borivali 和 Dahanu 路或 Churchgate。一旦到达塔那,就可以到达 Kalyan 或 Kasara。

特征值中心性

特征值中心图,图片来源:链接(图片由作者提供)

特征值中心性根据邻居的数量平等地分配重要性。具有高特征值中心性的站(节点)是网络上信息收集的可能目标。这有助于确定哪个站与大多数中心站相连。链接到高度连接站将比链接到较少连接的站给予一个站更大的影响。
Sanpada 连接到 Vashi,Vashi 又连接到具有高中间中心性的 Kurla。圣帕达也通过 Turbhe/Juinagar 连接到塔那,也具有较高的中间中心性。库尔勒连接到 Sion、Vidyavihar 和 Chunabhatti,它们具有较高的接近中心性。桑帕达也与潘韦尔相连。

Python 代码生成相关矩阵

中心性度量的相关矩阵,图片来源:链接(图片由作者提供)

该程度与所有其他中心性测量呈正相关。接近度和介数的系数约为 0.4。0.4 可以被称为相当弱但正相关。它与特征值中心性的相关性更小,系数为 0.3。介数和贴近度之间的相关性相对最强,系数为 0.5。它比介数与度或介数与特征值之间的相关性更强。特征值和介数之间呈负相关,但特征值与亲密度呈弱正相关。

中心性分布的变化

中心性分布的变化,图片来源:链接(图片由作者提供)

生成变异的 Python 代码

所有 114 个节点的度中心性值的直方图表明,只有 2 个节点具有最高度 4。有 6 个终端站,每个终端站的度数为 1,因为除了该站之外没有任何东西。8 个站点的度为 3,这意味着除了往返站点之外,它们连接到 1 个不同的节点。98 个站点的度值为 2,这意味着除了往返节点之外,它们没有连接到任何其他方向。经验网络的中心性分数看起来并不是对称的。平均中心性分数约为 0.0005,超过 68%的观察值必须位于±1±0.0001 的标准偏差内,因为形状并不完全正常。

“如果我知道一个网络有一些特殊的属性,比如特殊的度分布,这对系统更广泛的行为会有什么影响?”~ M.E.J .纽曼

随机图网络模型

保罗鄂尔多斯和阿尔弗雷德雷尼在 1959 年推出了这款车型。用外行的话来说,他们的工作使我们能够生成真实世界复杂网络的简单表示。因此,它将允许我们测试某些假设。从这个理论中产生的网络可能会也可能不会类似于现实世界的经验网络。如果我们可以从经验网络中收集一些属性,那么我们可以随机生成多个网络,并测试现实世界的现象是否完全随机。这有助于我们了解经验网络不同于这种随机网络。如果经验网络类似于随机网络模式,那么我们可以推断可能会有一些沉闷的事情发生。理想情况下,如果我们已经从一组数据中观察到某些中心趋势属性,并且给我们一个强大的工具来生成随机分布,以这些属性作为我们的主干,那么我们一定不能随机复制相同的数据。如果我们能够获得一个复制品,那么这可能意味着可能没有一个特定的模型来预测经验数据。它可以随时改变,没有模型可以限制数据的进一步理解。

随机图模型假设网络是无向的(这是上面显示的我们的经验站点网络的情况),并且节点随机连接。除了节点数量之外,重要的参数是任意两个节点共享一个连接的概率。鄂尔多斯-仁义是基于二项分布。在我们的站点示例中,我们有 114 个站点,因此有 114 个节点。

生成经验网络概率(p)的方法

鄂尔多斯-仁义概率,图片来源:(图片由作者提供)

我们将生成 100 个随机图模型,从每个模型中提取中心性度量,创建每个中心性度量的分布,并将它们与上面我们的实际经验站网络进行比较。其目的是通过检查随机图形模型是否可以轻松复制中心性分布来衡量站点是否是随机连接的。

R 代码模拟鄂尔多斯-雷尼模型

比较发行版的 Python 代码

鄂尔多斯-仁义(随机网络)与经验网络对比,图片来源:链接(图片由作者提供)

随机网络模型(蓝色)的特征值分布看起来是对称的,而经验网络(橙色)看起来不是这样。经验网络看起来不像随机网络模型。

瓦茨斯特罗加兹模型

1967 年,美国社会心理学家斯坦利·米尔格拉姆发现了小世界的属性。任何网络都有相对较少的长距离链接,但大多数节点对之间都有短路径,通常由集线器创建。1998 年,Duncan Watts 和 Steven Strogatz 进一步扩展了这个小世界问题的数学观点。他们基本上分析了一些极其不同的网络,发现它们都与随机图网络没有任何相似之处。平均路径长度、聚类系数的概念在很大程度上是从它们对网络分析的贡献发展而来的。他们还挑战了常规网络模型,该模型基本上假设每个节点的连接模式与所有其他节点相似。结果,他们证明了大多数真实世界的网络既不是规则网络也不是随机网络的复制品,而是介于两者之间。

我们将生成 100 个小世界模型,从每个模型中提取中心性度量,创建每个中心性度量的分布,并将它们与上面我们的实际经验站网络进行比较。目的是测量这些站是否以类似于小世界模型的方式连接。除了节点数量和连接概率之外,我们不会改变任何参数,而是将其余参数保持为默认值。

R 代码模拟沃茨斯特罗加兹模型

比较分布的 Python 代码

小世界与实证网络的对比,图片来源:链接(图片由作者提供)

随机网络模型(蓝色)的特征值分布看起来是对称的,而经验网络(橙色)看起来不是这样。经验网络也不像小世界网络模型。

巴拉巴斯艾伯特模型

它于 1990 年推出,基于这样一种信念,即如果网络中的节点数量增加,底层布局不会改变。它高度重视幂律分布,幂律分布表明在网络中少量的节点具有高的度,而大量的节点具有小的度。他们注意到正态分布在现实世界的网络中并不常见。他们的工作发展了优先连接的概念,即连接到已经高度连接的节点是有益的。

我们将生成 100 个 Barabasi Albert 模型,从每个模型中提取中心性度量,创建每个中心性度量的分布,并将它们与我们上面的实际经验站网络进行比较。目的是测量这些站是否以类似于小世界模型的方式连接。除了节点数量和连接概率之外,我们不会改变任何参数,而是将其余参数保持为默认值。

R 代码模拟巴拉巴斯阿尔伯特模型

Python 代码比较发行版

巴拉巴斯艾伯特与实证网络对比,图片来源:链接(图片由作者提供)

bara basi Albert 模型的特征值分布非常类似于经验网络模型。经验网络看起来很像巴拉巴斯阿尔伯特模型。

在小世界模型和巴拉布西-阿尔伯特模型之间寻找相似之处总是一场艰苦的战斗。任何真实世界的网络都不会接近 Barabasi-Albert 模型。在你的情况下,它可以是不同的。每个中心性分布必须匹配特定的模型才能相似,这也是不习惯的。每个网络都是唯一的,每个网络都有自己的中心性分布。有些可能看起来像上面讨论的 3 个模型中的任何一个,有些可能不像。以上 3 种模式并不是唯一存在的。本文试图展示网络分析世界中的几个字母,除此之外还有更多字母,我们可以学习构造一个正确句子的方法。

参考文献

网络,马克·纽曼的介绍

艾伯特·巴拉巴斯的《网络新科学》

网络和开放视频平台分享网络分析知识

安宁迪亚教授 S. 查克拉巴蒂 ,IIM-艾哈迈达经济区

六度分离并不意味着每个人都在短短的六个步骤中与其他所有人联系在一起。这意味着极少数人与其他所有人都有几步之遥的联系,而我们其余的人则通过那些特殊的少数人与这个世界联系在一起。~马尔科姆·格拉德威尔

如何为 AWS 上的 Fargate 任务设置网络配置

原文:https://towardsdatascience.com/network-configurations-for-fargate-tasks-6333314c4001?source=collection_archive---------53-----------------------

你需要知道什么以及如何实施

这篇博文是关于 AWS 上无服务器批处理作业的特定类型架构的三篇技术深度文章之一。该架构背后的基本前提是,我们希望使用 AWS 的托管服务来运行批处理作业。如果您想了解更多关于该架构的信息,请点击此处了解更多详情。该架构的整体情况如下:

整体架构(作者图解)。

简而言之,该架构由一个用于开发的组件和另一个用于通过 Cloudwatch 触发器执行批处理作业的组件组成。在这篇博文中,我们只关注这个架构的网络方面。还有一个公共代码库,允许你基于 Cloudformation 脚本复制完整的服务及其所有部分。

从网络的角度来看, Fargate 服务——有点像 AWS 的弹性容器服务(ECS)——以及它与弹性容器注册中心(ECR) 的交互需要特别注意。网络配置需要满足两个主要要求:

  1. 它必须允许该架构中使用的所有服务之间的通信。
  2. 它必须保护服务免受未经授权的访问。最重要的是,所有的交通都必须在安全的范围内进行。通过公共 IP 或其他方式向互联网敞开大门是不可接受的。

让我们先从云形成脚本的初级入门开始,然后再来看网络的全貌。如果你已经有了云形成或者类似概念的经验,你可以略读或者跳过下面三段。

CloudFormation 是代码为的基础设施的 AWS 风格。也就是说,您定义一个目标基础设施,将其推送给 AWS,AWS 为您提供它。你在所谓的堆栈中排列你的资源。这使得调整、监控或删除它们变得非常容易。

您可以在 JSON 或 YAML 文件中编写 CloudFormation 脚本。这里和代码库中的所有例子都是 YAML 文件,但是您也可以在 JSON 中做同样的事情。

还有一组专门针对 CloudFormation 的命令可供您使用。在接下来的例子中,我使用了其中的三个:

  1. !Ref 是内部参考;也就是说,CloudFormation 从同一个脚本中插入一个值。
  2. !Sub 用于将变量替换成字符串。
  3. !GetAtt 类似于“!Ref”但是指向资源的特定属性,而不是它的一般引用。

大局

以下是组成网络设置的组件概述:

网络构建模块(作者插图)。

如您所见,这里涉及四项服务:

  1. 虚拟专用云(VPC) 从逻辑上将您的 AWS 帐户与其他帐户分开。它提供了一组地址供其中的服务使用。
  2. 子网只属于一个可用区域(AZ)。它们通常用于在一个 AZ 关闭的情况下确保容错。在我们的例子中,为了简单起见,我们跳过这一步,只在一个子网中构建所有内容。
  3. 安全组是一种限制不同服务之间允许的流量类型的方法。例如,如果您要确保服务只能相互通信,您可以将它们放在同一个安全组中。然后,您可以使用该安全组阻止来自外部的所有流量。
  4. 端点存在两种味道。首先,端点接口通过私有 IP 提供对服务的直接访问。第二,有端点网关。与接口相反,它们依赖于通过路由表进行路由。

在我们的示例中,我们需要端点来使用弹性容器注册表(ECR) 并将信息写入 CloudWatch 日志。按照规定,这里不涉及公共 IP 或任何对互联网的访问。

实施细节

让我带您看一下这个实现的三个方面:安全层、、三个接口端点网关端点。****

安全层

在这种设置下, VPC 需要两种配置:

  1. ****CIDR 块描述了 VPC 中的地址空间。它是 IP 地址和您需要的子网掩码数量的组合。斜线后面的数字越小,可用的子网掩码就越多。
  2. 我们还需要启用 DNS 主机名DNS 支持。这些支持端点稍后使用私有 DNS 功能。

以下是 VPC 在云形成脚本中的样子:

相关的子网有两种配置:

  1. 它定义了一个 CIDR 块,该块位于 VPC 提供的块内。在我们的例子中,子网使用 VPC 的整个地址空间。
  2. 为了安全起见,您可以确保在子网启动时明确关闭公共 IP** 的映射。**

同样,这是 CloudFormation 脚本的相关部分:

****安全组属于 VPC,没有进一步的配置。相反,一个额外的入口规则包含了重要的流量限制。该规则将流量限制为遵循 HTTPS 协议的安全组内的通信。以下是两种资源的配置:

****注意:也可以在 Cloudformation 中将两个部分配置为一个资源。但是,分成两个资源可以更容易地避免它们之间的循环引用。

子网和安全组是稍后被架构的其他部分直接引用的两个组件。这就是为什么公共存储库中的脚本会导出它们的引用。现在我们可以继续实现所需的端点。

界面端点

一般来说,AWS 上的接口端点由于 AWS 专用链接而工作。记住, Fargate 决定了我们在这里需要哪些接口。附加服务或更复杂的架构可能需要其他配置。三个接口端点之间唯一的区别是它们的服务名。其余参数是相同的:

  • 相关 VPC、子网和安全组的 ID
  • ****VPC 端点类型是一个接口。
  • 私有 DNS 选项创建一个具有默认服务名的端点,而不是特定于端点的 DNS 主机名。

让我们简要讨论一下这些接口端点在更广泛的环境中所扮演的角色:

  1. *.ecr.dkr 是注册中心使用 Docker 命令的端点。
  2. ****** . ECR . api*是通用访问注册表的 API。
  3. *.日志支持从 Fargate 到 Cloudwatch 日志的通信。

以下是所有三个界面的 CloudFormation 脚本:

如您所见,这种配置非常简单。不幸的是,我们需要创建另一种类型的端点:网关。

网关端点

只有两个 AWS 服务仍然依赖网关端点:S3 和 DynamoDB。ECR 在后台使用 S3 来存储容器图像和层。与接口端点相反,网关端点也需要直接与所谓的路由进行交互。****

路由表控制与 VPC 相关的流量。要使用它,我们必须创建表,然后将它与子网相关联。配置非常简单,所以让我在这里直接向您展示 CloudFormation 脚本:

有了这些资源,我们就可以配置 S3 网关端点了。唯一的新参数是负责组织子网内流量的路由器的 ID。再次比较 CloudFormation 脚本以获得详细信息:

如您所见,网关端点本身的配置比接口端点的配置要少。然而,我们需要两个额外的资源来覆盖它的功能。

我希望这个总结能够帮助您理解 Fargate 任务所需的网络配置。同样,如果你想了解更多关于架构的知识,请参考概念帖子。如果你打算重建它,请参考公共代码库。此外,不久还会有两篇文章将这一讨论扩展到所需的 IAM 角色和策略,以及整个服务的特定构建块。

请在评论中告诉我你的想法和经历。我也很乐意在 TwitterLinkedIn 上联系。感谢您的阅读!

在画布上使用 D3js 的网络图

原文:https://towardsdatascience.com/network-graph-with-d3js-on-canvas-b90f275dfaa6?source=collection_archive---------15-----------------------

用 D3.js 生成网络图的步骤

网络图模拟 SVG 和 Canvas 由rubén trivio

  1. 如何在 Web 组件中使用 D3?
  2. D3js 在画布上的网络图。

介绍

数据可视化是一个多面棱镜;有些人看到的是简单的条形图,而其他人看到的是清晰的增长趋势,甚至是已经完成的目标。

数据图形化有许多解决方案;从 Tableau、QlikView、Carto 或 Datastudio 等企业应用,到 bokeh、matplotlib 或 d3.js 等自助工具。事实是,每种情况都需要不同的方法,许多人已经提供了足够多的方法,如果没有必要,没有必要重新发明轮子,但是…如果你需要 DIY 解决方案,你来对地方了。

问题陈述:网络图形

这一次,我们将探索一个使用 HTML Canvas 元素的网络图形示例。Canvas 元素允许我们绘制内容,而不需要将所有可视元素存储在 DOM 中,就像使用 SVG 进行绘图一样。这允许创建具有大量元素的图形,而不会因浏览器渲染过程而降低性能。

我们将要看到的图表是由代表节点之间关系的线条连接起来的节点图。使用的数据集来自我担任运营分析师的 BuscoExtra 。简而言之,BuscoExtra 是一家专注于酒店服务的人事代理机构。在西班牙,雇主需要起草一份合法的雇佣合同来雇佣员工,即使是只持续几个小时的小工作。

因此,数据结构存储了在一定时期内产生的不同雇佣合同,这些将是线条,而餐馆,或雇主,和服务员,或雇员,将是我们图表的节点。

所以有两种类型的节点:WorkerEstablishment。我们将使用两种颜色来区分它们,当Worker节点以更大的数量出现时,使用更小的半径。

数据结构定义

类型为Establishment的节点的半径随着它们雇佣的工人数量而变化。因此,较小的节点与那些链接到它们的Worker节点数量较少的节点相关。

此外,由于WorkerEstablishment之间的约定可能出现多次,我们将添加一个名为interactions的变量,因此节点之间的线条将根据交互的次数变宽或变细。我们可以在下图中看到一个例子:

具有不同连接的节点示例。自己阐述。

所有这些特征实际上是丰富图表的不同维度,正如有人所说:一幅图胜过千言万语。我也相信。

在另一种数据结构中,我们可以根据一些其他标准使用一系列颜色来表示节点;根据节点的类型使用不同的形状(正方形、三角形等)..)或者更好的是,根据连接类型改变连接节点的线条类型:虚线、点划线、不同的颜色等..

我们可以使用各种属性来排列信息并添加额外的维度,就像有些人使用 Spotify 来显示音乐风格一样,在相反的两极上表示更遥远的风格。可能性是无限的,只受我们创造力的限制。

Spotify 艺术家网络图,按粉丝数量划分。来自:Reddit:u/Enguzelharf

入门指南

首先我们在 模板 中创建一个基础项目,并在输入参数中提供数据结构(这里是如何做到超快)。

一旦组件中有了数据,我们将开始定义绘制策略。与 SVG 不同,在画布中,我们将使用画笔的属性:粗细、颜色等..此外,我们将不得不在绘图时更新画刷在画布中的位置。因此,在画布中,我们没有将元素放入绘画中,只有我们已经画过的东西,而在 SVG 中,元素是通过标签<g><image><text>等属性放置的..

Canvas 提供绘制基本几何图形的操作:直线、圆、弧、正方形等。我们将不得不用这些形状做任何事情。但是不要担心,如果你仔细想想,对于这个图形,我们只需要画圆和线。很简单,不是吗?确实是。

绘图节点

在下一段代码中,我们可以看到绘制节点所需的步骤:

绘制节点代码段

在这个函数中发生了三件主要的事情:我们开始绘制路径,设置绘制参数(颜色、宽度等..)和生成形状的画笔运动。

画布上的所有操作都是通过它的上下文完成的,这个上下文是我们在使用 D3.js 选择 HTML 元素时得到的。

  • begin path() 这个函数相当于把画笔放在画布上,所以当我们移动它的位置时,它后面会出现一条线。
  • 线宽fillStyleystroke style**
    这些都是允许我们自定义线型的属性。例如,根据节点类型,我们会改变颜色。在这种情况下,我们将使用一个充满纯色的圆来绘制一个节点。
  • 移动到 (x,y)
    使用此功能,我们将画笔定位在我们想要开始绘制的位置。在这种情况下,我们将使用XY参数将其移动到节点位置。
  • arc(x,y,radius,originalAngle,finalAngle)
    这是负责沿着 0 到 2π的顺时针圆弧画一个圆。如前所述,半径将根据节点类型进行设置。
  • fill()
    这个函数会用之前描述的fillStyle参数中设置的颜色填充形状。
  • 【stroke()】 这将绘制一条带有形状的元素线。

绘制链接

下一段代码显示了绘制链接所需的步骤:

生活的一部分

这个功能甚至更简单,从笔刷设置的一部分来看,与前面步骤的区别在于我们调用了lineTo而不是arc

  • lineTo(x,y) 这个函数允许我们用画笔当前位置的原点和传递给它的目的地XY画一条线。也就是说,我们将位置移动到源节点,并制作一条到目标节点的线。在这种情况下,我们将线的宽度调整为一个比例,以便随着交互次数的增加而加宽。

完整的绘图功能

一旦我们有了绘制节点和线的函数,我们就可以定义一般的绘制操作:

绘图功能

在这个函数中,我们调用每个节点和链接的绘制方法。此外,通过函数clearRectsaverestore,我们可以在每次迭代中清理并恢复画布,这样之前的操作就不会重叠。

记住,直到现在我们还没有使用过 D3.js ,我们只是创建了逻辑来绘制我们的元素。用 D3 我们将获得我们还缺少的信息:元素的实际位置。

定位元素

所有的绘制操作都参考节点的位置。但是,初始数据结构只包含节点之间的引用、迭代次数、关系等等,不包含任何与元素实际位置相关的内容。

为了获得元素的位置,我们将使用 D3 ,特别是函数forceSimulation(此处的完整引用)。该函数执行模拟,其中元素的位置被更新,并且它修改原始数据结构。

通过力模拟生成元素位置

forceSimulation从节点列表中执行力模拟。最初,我们的节点没有位置,这是负责在每次迭代中建立每个节点的XY值的节点。因此,在本文开头的 GIF 中,它被视为从中心开始的节点爆炸,这是模拟的开始。

该函数允许我们提供一个节点列表,声明一系列力,并订阅模拟的每次迭代,其中我们将有节点的更新位置,并允许我们绘图。我们可以宣布的力量是:

  • 链接
    它们是节点之间的联合力量,它允许我们通过使用 D3 函数forceLink来建立节点之间的距离限制,我们将我们的链接列表和节点之间的期望距离传递给 D3 函数。
  • 电荷 这种力产生了类似电子电荷的效应。在 D3 提供的选项中,我们将使用负力的forceManyBody,它建立了一个类似重力但方向相反的力场。也就是说,所有节点会相互排斥,排斥力随着距离的增加而减小,直到到达distanceMax时完全消失。
  • 中心 另一方面,我们建立了一个径向力场,将所有网络保持在一起,使孤立的节点不会分散太多。

模拟的每次迭代都调用函数tick,我们可以利用它来绘制节点,从而获得动画效果。

为什么在 SVG 上画布

HTML Canvas 元素引入了一系列复杂性,因为它没有对所绘制元素的引用,必须对数据执行迭代操作并存储元素的位置以更新它们的状态。然而,数据结构被专门存储在 VirtualDOM 中,不像 SVG ,其数据结构被呈现在 DOM 中,并在用户与可视元素进行任何交互后重新绘制。这大大减少了绘画操作,尤其是在操作成千上万的视觉元素时。然而,当要绘制的表面非常大时,画布会压倒性地输给 SVG

绘制成千上万个数据点可能不是每种情况,或者在绘制过程之前可以在服务器上完成数据的预处理。然而,有时这是不可避免的,在这些情况下,当 SVG 简单地冻结浏览器时, Canvas 元素可能是一个解决方案。

结论

如果你想自己完全重现这个过程,你可以检查 这个完整的项目交互功能,同时使用 Canvas 和 SVG 。此外,我还包含了数据集文件,这样你就可以探索数据结构或者用你自己的来改变它。

像数据科学专家一样联网

原文:https://towardsdatascience.com/networking-like-a-pro-in-data-science-4133b91e1b6f?source=collection_archive---------37-----------------------

苹果 | 谷歌 | SPOTIFY | 其他

Sanyam Bhutani 在 TDS 播客

背景图片由HIVAN ARVIZU @ soyhivan-Unsplash

编者按:迈向数据科学播客的“攀登数据科学阶梯”系列由 Jeremie Harris 主持。除了主持播客,Jeremie 还帮助运营一家名为sharpes minds的数据科学导师初创公司。你可以听下面的播客:

网络是数据科学中最有价值的职业发展技能。然而,几乎矛盾的是,大多数数据科学家根本不在这上面花时间。在某些方面,这并不十分令人惊讶:数据科学是一个非常技术性的领域,技术人员通常不愿意特意去寻求社交互动。我们倾向于认为与其他“编码灵长类动物”的交流往好里说是一种干扰,往坏里说是一种引发焦虑的噩梦。

那么,数据科学家如何克服这种焦虑,挖掘网络建设的价值,并在数据科学社区中为自己开发品牌呢?这个问题将我们带到了本期播客。为了回答这个问题,我采访了重复嘉宾 Sanyam Bhutani——一位顶级 Kaggler,Chai Time 数据科学节目的主持人,机器学习工程师和 H2O.ai 的人工智能内容创作者,谈到了他利用非正统的网络战略成为机器学习社区的一员,并获得了他目前的角色。

以下是这一集中我最喜欢的一些带回家的东西:

  • 在数据科学中,有很多很多不同的方式来建立联系:聚会、Slack 和 Discord 社区、一对一的电话、播客、书面采访和博客帖子等。你不需要做所有的事情,也不应该做。相反,从选择符合你个性的策略开始。如果你比较内向,远离聚会(需要更多的破冰),专注于一对一的通话。如果你是一个外向的人,在更大的集体活动中寻找机会做演讲,通过与人交往来利用你的比较优势。
  • 这听起来可能有争议,但是播客作为一种交流方式仍然被低估了。不要误会我的意思:你绝对不应该为了出名而开播客!但是,采访式播客给了你一个很好的借口去了解机器学习社区的重要成员,甚至是你有一天可能想为之工作的公司的经理。人们出人意料地乐于接受采访,一对一的形式意味着这种策略特别适合内向的人。
  • 如果你没有勇气建立关系网,主持播客也很好,因为它迫使你预先承诺在特定的时间和日期与某人交谈。鼓起勇气通过电子邮件发送邀请相对容易,所以害羞内向的人更有可能真的这么做——一旦你这么做了,你就不得不坚持到底。
  • 有大量不和谐和松散的社区以及在线论坛,在进行任何“面对面”(即远程视频聊天)网络之前,你可以与其他数据科学家联系,进行热身。如果你想尝试一下,这可能是很好的第一步。

你可以在 Twitter 上关注 Sanyam 这里,你可以在 Twitter 上关注我这里

另外,看看 YouTube主播上的柴时代数据科学秀吧!

带动画的神经变形

原文:https://towardsdatascience.com/neumorphism-with-animation-1c24a4c0e2b4?source=collection_archive---------33-----------------------

理解新变体并在 WPF 实施。

作者一张美丽的爱情纽扣照片。

技术世界发展迅速,每天都有一些有才华的人提出新技术。如果你是这些人中的一员,你就是一个了不起的家伙!但是如果你不是,通过学习他们的成就来阻止他们超越你。

我已经回答了这个故事中的两个基本问题:

  • 什么是神经形态?
  • 如何在 WPF 实现新形态?

我希望我的解释能够帮助您将这项新技术应用到即将到来的项目中。

什么是神经形态?

Neumorphism 是 2020 年新的设计风格趋势。其实它第一次使用是在 2019 年的最后。

在我们定义神经形态之前,让我们看看以前的设计风格:

  • Skeuomorphism: 是一种界面元素风格,模仿它们在现实世界中的对等物,以及用户如何与它们互动。
  • 平面设计:是一种界面设计风格,强调简单元素、排版和平面颜色的极简使用。这是设计网页或手机界面的常用风格。

(左)图标来自图标 png |(右)图标来自图标 png

Skeuomorphism 风格看起来像现实。扁平化设计看起来数字化,其实很简单。

Neumorphism 结合 Skeuomorphism 和扁平化设计:真实又简单。有了这种风格,我们可以给用户一种独特的体验。

Neumorphism 关心的是用简单的形状和颜色制作逼真的元素。

如何在 WPF 实现新形态?

一起,我们将实现这样的纽形按钮:

我工作的最终结果。

1.概观

一个神经形态元素有不同的表现方式(见下图),基于元素行为,我们可以决定我们应该使用哪种表现方式。

作者图片。

要对任何元素应用 Neumorphism 样式,您必须实现以下三个主要属性:

  • 元素的背景必须与其主容器相同。
  • 深色阴影必须应用到元素的一个角上。
  • 光影必须应用到对角。

异形零件的描述。

2.让我们开始编码吧

我将编码过程分为 4 个部分:

  • 制作外部异形按钮样式。
  • 制作内部异形按钮样式。
  • 应用动画。
  • 添加一个漂亮的图标。

你可以从这里得到所有的代码样本。尽管代码是用 XAML 语言写的,你仍然可以用你喜欢的语言把相同的概念变成代码。

1.制作外部异形按钮样式

打开 Visual Studio,创建一个新的 WPF 应用程序,并将其命名为“Neumorphism”。在本例中,解决方案名称为“Neumorphism”。

打开 Neumorphism.xaml ,添加以下代码:

外部神经形态按钮实现

我们有一个名为 OuterGrid 的网格元素,它代表主要的背景色,我们还有两个边框元素: OuterLowerBorder 代表深色阴影,以及outeruperborder代表浅色阴影。

很简单,对吧?只有两个元素(网格和边界),我们已经获得了我们的设计。

外部变形风格。

2.制作内部异形按钮样式

如果我们只是将 OuterLowerBorderOuterUpperBorder 的背景从(#E0E5EC)改为(Transparent),我们会得到另一种 Neumorphism 表示,我称之为 outer inner style,因为它是外部和内部风格的混合。

外部内部样式实现

外在内在风格。

为了改变这种内部风格,我们必须隐藏边界周围的外部阴影(明暗),并保持内部阴影可见。我们可以通过用另一个边界包围我们的边界来做到这一点。这个名为 SurroundingBorder 的新边框必须与我们的主边框具有相同的属性。将 InnerGrid 实现插入 MainGrid 实现,如下所示:

内部按钮样式实现

内部按钮样式。

3.应用动画

我们已经到了本教程最重要的部分:如何制作我们的按钮?以及如何使其可点击?

我们需要做的就是在内部样式的上方添加外部样式,并根据用户交互使其消失和出现。

下面的代码显示了如何在外部和内部样式之间进行组合:

Neumorphic 按钮样式实现

为了让这些边框与用户交互,正如你在上面的动画图像中看到的,我们需要在 MainGrid 中的上边框添加一些触发器,即outerupberborder

OuterUpperBorder 触发器中,我实现了两个事件:MouseDown事件和 MouseUp 事件。

为按钮实现动画

MouseDown 事件触发器中,我对我们的 Neumorphic 按钮做了四个动画更改,以将其从外部样式转换为内部样式:

  • 隐藏外网格通过减少其不透明度为 0。
  • 减少外上边框外下边框(外边框)的宽度和高度。
  • 减少外暗阴影外亮阴影的阴影深度(外边框阴影)。
  • 增加内暗阴影内亮阴影的阴影深度(内边框阴影)。

MouseUp 事件触发器中,我对我们的 Neumorphic 按钮进行了四次动画修改,以将其从内部样式转换为外部样式(与 MouseDown 事件触发器相同,但方向相反):

  • 通过将不透明度设置为 1 来显示外网格
  • 扩展外上边框外下边框(外边框)的宽度和高度。
  • 增加外暗阴影外亮阴影的阴影深度(外边框阴影)。
  • 减少内暗阴影内亮阴影的阴影深度(内边框阴影)。

4.添加一个漂亮的图标

这部分不重要:你可以把你想要的任何内容放在 MainGrid (上层)。

我使用了材料设计图标中的图标。如果你想和我继续下去,你必须在你的项目上安装 Xaml 工具包中的材料设计。本指南超级快速入门将帮助你做到这一点。

以下代码演示了如何将图标添加到 MainGrid 子节点:

图标实现

现在,给鼠标按下鼠标抬起事件触发器添加图标动画:

图标的动画实现

鼠标按下时:

  • LoveIcon 颜色会恢复到原来的状态(浅灰色)。
  • LoveIcon 宽度和高度会减小。

当鼠标抬起时:

  • LoveIcon 颜色会变成红色。
  • LoveIcon 宽度和高度会增加。

终于,你做到了!运行项目,看看你取得了什么成果。

谢谢你的时间。我希望你找到了你的目标,并且喜欢阅读我的文章。如果你有任何问题或笔记,请随意写在这里的回复中。

神经结构转移

原文:https://towardsdatascience.com/neural-architecture-transfer-54226b2306e3?source=collection_archive---------45-----------------------

机器学习

NAT 可能是深度学习领域的下一件大事

一种可能的网络架构。图片作者。

神经网络拓扑描述了神经元如何连接形成网络。这种架构具有无限的适应性,新颖的拓扑结构通常被誉为神经网络研究的突破。从 1958 年感知器的出现,到前馈神经网络,到长/短期记忆模型,再到最近由 Ian Goodfellow 开发的生成式对抗网络,创新的架构代表了机器学习的巨大进步。

但是如何为特定的问题集找到新颖有效的架构呢?仅仅依靠人类的聪明才智,直到最近。这将我们带到了神经架构搜索(NAS),这是一种通过原始计算能力发现最佳网络拓扑的算法方法。这种方法基本上是一种大规模的网格搜索。测试超参数的多种组合,如隐层数、每层神经元数、激活函数等。,找到性能最佳的架构。如果这听起来非常耗费资源,确实如此。

NAS 可以分为三个部分,这三个部分反映了它必须解决的各种优化问题。

  1. 搜索空间:您要检查的参数。正如 Kyriakides 和 Margaritis 警告[2]的那样,减少搜索空间将节省资源,但是如果没有适用的领域知识和对可能的有效架构的直觉,人们很容易错过最佳解决方案。事实上,只采用已知的成功架构很容易在搜索中引入偏见。你只会巩固我们已经知道的工作。
  2. 优化方法:如何探索搜索空间。我们必须权衡向全球最优进一步探索的价值和探索的成本。有很多方法可以利用,包括进化算法(稍后将再次出现)、强化学习和贝叶斯优化。
  3. 候选人测评:如何选择最佳车型。这更直接,但是计算量也很大。这可以通过使用更少的训练时期或者随着过程的进行在模型之间共享权重来在一定程度上规避。

我推荐在这里阅读更多关于进化算法的文章。

正如作者所指出的,我们似乎只是简单地将一个困难的模型微调决策过程换成了另一个同样困难的架构搜索调整决策过程。那么,我们该何去何从呢?

神经结构转移,转移学习重新想象

迁移学习传统上意味着使用预训练的神经网络和固定的神经元权重来大幅改善特定模型的结果。这些模型,像 VGG盗梦空间例外MobileNet ,都是在包含超过 120 万张图片的 ImageNet 数据集上训练出来的复杂、深度的网络。这允许个人利用强大的模型,而不需要资源密集型培训。

迁移学习可能会产生惊人的结果,但是采用迁移学习的一个注意事项是,最终用户不能改变迁移学习的架构来更好地满足他们的需求。一旦他们的架构改变了,就必须重新训练模型,使预先训练的模型的优点无效。

进入神经结构迁移,一种新的迁移学习方法。由密歇根州立大学鲁治超分校、Gautam Sreekumar、Erik Goodman、Wolfgang Banzhaf、Kalyanmoy Deb 和 Vishnu Naresh Boddeti 的研究人员描述,NAT 允许为用户的问题空间优化定制的架构。此过程自动化了 NAS,但它能够规避 NAS 带来的一些复杂性。

通过超网,在 NAS 期间探索和训练许多模型的巨大计算成本在一定程度上被抵消,超网由多个组件子网组成,可以通过权重共享来同时训练。然后,超网返回帕累托优化前沿的最佳子网,这些子网可用于解决新问题,就像传统的迁移学习一样。

经济学中的帕累托前沿。原则仍然是,尝试找到与多目标搜索相关的所有资源最佳点(红线/点)。图片来自 Njr00 —自己的作品CC BY-SA 3.0

Pareto 前沿对于可视化多目标搜索(如 NAS)中的权衡非常有用。NAT 的一个吸引人的方面是,它只返回位于 Pareto 前沿的子网,确保模型具有最佳拓扑。

最初引发这篇文章的是用来进行多目标搜索本身的方法。研究人员使用进化算法(EA)来搜索子网的最佳拓扑结构。EAs 利用许多代的“适者生存”来识别最佳超参数。

一般流程如下:

  1. 从以前探索的体系结构中选择初始群体
  2. 从“父”架构中创建突变和交叉的“后代”
  3. “适者生存”——只保留最好的 k 架构做下一代父母
  4. 重复进行,直到达到所需的目标阈值

进化生物学的一个例子。我们看到人群如何分支到不同的方向,有机地探索问题空间。这就是进化算法再造的东西。图片由诺亚·罗森伯格CC BY-SA 3.0 提供。

研究人员报告的结果令人震惊。通过在 ImageNet 上训练超网和在 10 个图像分类数据集(包括 ImageNet、CIFAR-10 和 CIFAR-100)上评估子网,NAT 模型始终优于包括 Inception、ResNet 和 MobileNet 在内的最新模型,同时所需的 FLOPs 数量级更少。

正如研究人员指出的,NATnets 明显比传统的微调更有效。此外,由于所有数据集都使用相同的超网,而数据集又千差万别,因此 NAT 似乎确实能够为每个新的问题空间生成定制的最佳子网。

神经结构转移很可能是与上述进步相结合的一项创新。它能够为新问题稳健地生成高性能、低成本的子网,并且在一系列分类案例上已经超过了许多当前的 vanguard 模型。

如果您对 NAT 或它的任何方法感兴趣,请阅读[1]以获得深入的解释!这里的是研究员的 NAT GitHub 页面。

在这里随意探索我的其他文章,在 LinkedIn 这里和我联系。

来源

[1] Z. Lu,G. Sreekumar,E. Goodman,等.神经结构转移 (2020),arXiv:2005.05859 .

[2] G. Kyriakides 和 K. Margaritis,卷积网络的神经结构搜索导论 (2020),arXiv:2005.11074。

[3] A.N .斯洛斯和 s .古斯塔夫森, 2019 进化算法综述 (2019),arXiv:1906.08870。

用于艺术娱乐的神经细胞自动机

原文:https://towardsdatascience.com/neural-cellular-automata-for-art-recreation-6d9fb61afb37?source=collection_archive---------29-----------------------

本文将简要介绍细胞自动机(CA)领域,以及神经网络方法。这项工作的输出不仅仅是图像。它们是某种形式的虚拟有机体,类似于生命体,生长并对变化做出反应。这是一项实验工作,希望以类似基因组的方式编码信息。

在这篇文章的最后,我们将无法创造一个生活在圣朱尼佩罗的虚拟人。然而,我们将能够呈现一个基斯·哈林的图标系列(1990)的再现。这些图标将从一个单细胞开始生长,直到它们达到饱和点,在饱和点,单细胞变成一个多细胞实体。

如果你对神经网络架构背后的技术细节不感兴趣,可以跳过标题以“、CNN: ”开头的章节。我在 Colab 笔记本上设置了用于这个项目的代码,它可以用于为用户定义的输入创建类似的图形和图像。

[## Sam Naji/艺术娱乐的神经细胞自动机

艺术娱乐文章的神经细胞自动机笔记。用户可以上传 png 并创建 CN 模型…

github.com](https://github.com/samnaji/Neural-Cellular-Automata-For-Art-Recreation/blob/master/Neural_Cellular_Automata_For_Art_Recreation.ipynb)

这本笔记本是 Mordvintsev 关于生长神经细胞自动机【1】的工作的编辑版本。

图 1:神经细胞自动机能力的例子。最上面的图片是基斯·哈林著名的狗叫图标。底部的一组图像是八个不同的细胞自动机模型,它们学会了重新创建这个图标。底部 gif 不是简单的一组帧。它是一个不断增长和互动的模型,从一粒种子开始,当它到达目标图像时就饱和了。(上图基于公共项目档案。作者底部图片)

20 世纪 50 年代早期, 罗莎琳德·富兰克林 、弗朗西斯·克里克和詹姆斯·沃森的合作导致了 DNA 的发现[2]。这一发现不仅创造了现代生物学发展中最重要的里程碑,也塑造了其他领域,如计算机科学。

图 2:罗莎琳德·埃尔西`富兰克琳的工作是理解 DNA 分子结构的核心。尽管她通常没有足够的学分,但她是历史上最受欢迎的女科学家之一。

尽管计算机科学似乎与生物学完全脱节,但像约翰·冯·诺依曼、斯坦尼斯劳·乌拉姆和 s·沃尔夫拉姆这样的计算机科学家对生物系统的效率和复杂性印象深刻[3]。他们绘制了一个模型,该模型解释了新发现的 DNA 角色,并翻译了分子生物学架构以服务于计算目的。按照他们当时的理解,一个生命体是由一个算法(DNA)和几个功能(生化操作)所支配的,这些功能使自然界呈现出一个连续的、有反应的模型(一个生物有机体)。因此,生命找到了一种方法来压缩大量信息,并通过使用这两个原则来编码复杂的行为。这种理解是细胞自动机(CA)的基础。因此,CA 是计算机科学算法中实验动力学的一种练习,希望将信息重建为基因组编码的细胞形式。

细胞自动机简介

细胞自动机是从一个种子开始的一组细胞(网格的元素)的连续状态,该种子可以是单个细胞或几个细胞。在时间“t+1”的一组单元是根据更新“规则”在“t”的一组单元的更新。更新规则涉及依赖于相邻单元格的计算。邻居小区有三种标准定义。

图 3:不同社区的例子(作者拍摄)

根据每种不同类型的邻域,不同的单元选择(灰色)有助于特定单元(黑色)的更新。因此,一个单元持有的状态或值直接影响其他单元。因此,细胞自动机进化为一个连续的实体。邻域对像元的影响因格网类型而异。说明这一点的最佳方式是考虑一维网格。在下面的动画中,所有的单元格占据一行。每个单元格只能有 0 或 1 的值。

图 4:规则和邻居从当前代产生下一代。(公共领域)

因此,规则决定了一代相对于其邻居如何变化到下一代。编号为 0 到 7 的案例代表一维网格中可能存在的不同情况。例如,情况 2 表明,如果一个单元(中间的块是当前单元)当前为 1 并且有两个 0-邻居,那么它将保持为 1(结果显示为底部的块)。有 256 种不同的组合,因为 8 种情况中的每一种都可以是 0 或 1。因此,对于一维二元细胞自动机,可能有 256 种不同的规则来控制系统的进化。

图 5:惊人简单有效的初级 细胞 自动机模拟器由 Devin Acker 制作,2010 。(作者制作的 Gif)

这些系统通常被称为基本细胞自动机(ECA)【4】。尽管它们很简单,但有些规则会在几代人的时间里产生复杂的模式,例如规则 30规则 90规则 110规则 184 。有专门针对 ECA 研究的奖项,比如规则 30 奖。在这里,Devin Acker 创建了一个简单的 ECA 模拟器,用户可以在其中设置更新规则和初始条件,如图所示,可以产生独特的模式。

细胞自动机的现状

CA 领域从简单的 ECA 模型迅速发展,并能够创建更复杂的模式。在创建二维和高维网格方面已经做了大量的工作。细胞之间的相互作用,“更新规则”,也采取了高度复杂的数学表达式的形式。

图 6: 3D 循环细胞自动机。查看此链接阅读更多关于一些先进和令人兴奋的循环细胞自动机模型。这个博客在探索这些概念方面做得非常出色(经许可,转载自)。

不幸的是,细胞自动机的研究人员仍然远远没有在虚拟世界中创造出一个功能性的生物有机体,有些人可能会认为这是一种解脱:)。生成的图案通常是无定形的,没有明确的形状表示。这些图案因其美学价值而吸引了很多关注。一些研究集中于发现建立在计算机科学和数学之上的艺术 CA 模型,因此,质疑数据科学和艺术之间的关系。

对于单纯的艺术爱好者来说,这些是引人入胜的直接图像,想象力可能会努力解释或仅仅接受。对 CA 理论家和实践者来说,“艺术”充满了更深层次的意义,就像禅宗艺术既可以在表面上体验,也可以由禅师体验。 Wuensche,第 13 页,设计美:细胞自动机的艺术【5】

然而,这个项目旨在从一个种子细胞开始再造艺术品。为此,我们将使用一个受监督的神经网络来寻找最佳更新规则,该规则可以在几个步骤之后成功地重建图像。

神经网络创建一个最佳的细胞自动机

这一领域面临的最大挑战之一是“如何正确地告诉客户何时构建?建什么?什么时候停止?”。生物学似乎已经解决了这个问题。经过数百万年的进化,它优化了物理和计算法则的使用。不幸的是,由于生物学家仍在努力解决生命之谜,我们没有一个清晰的方法来虚拟地重建类似的系统。在 CA 术语中,问题在于找到将单个单元转换成高度紧凑体的更新规则。因此,不是在生物学中寻找最佳更新规则,而是可以使用神经网络算法在几代中寻找该规则。神经网络可以经历几次试验,就像生物体经历的某种形式的虚拟进化一样。因此,可以使用神经网络架构从种子细胞创建目标图像[1]。

图 7:细胞神经网络架构[1]。从生长神经细胞自动机(在 CC-BY 4.0 下获得许可)检索的图

CNN:细胞自动机模型状态

这里的输入图像具有 40×40 的单元矩阵。每个单元有 16 个状态(通道)。前三个通道是 RGB,第四个是 alpha 通道(透明),而其他通道是不可见的,不一定具有预定的含义。它们可以被认为是生物细胞经历的化学和物理相互作用的代表。更新规则将学习如何利用这些通道来到达目标图像。细胞根据摩尔(r=2)邻域相互作用(如图 3 所示)。

图 8:阿尔法通道。从生长神经细胞自动机(在 CC-BY 4.0 下获得许可)检索的图表

此外,阿尔法通道将用于区分活细胞。α值> 0.1 的细胞为“成熟”细胞,其相邻细胞为“生长”细胞。相比之下,alpha <为 0.1 且邻近区域没有“成熟”细胞的细胞是死细胞。

CNN:反馈回路

最后,使用 L2 损失函数设置反馈回路。损失值是通过将重建图像的可见通道与目标图像的那些通道进行比较来计算的。换句话说,不同的渠道对其他渠道的贡献只在于通过感知向量找到正确的更新规则。它们是灵活的,并且将由神经网络架构定制以优化更新规则。而可见信道中的损耗将使用均方误差(MSE)来计算,以指导训练。

等式 1:神经网络中使用的均方误差公式。(图片由作者提供)

CNN:卷积层

图 9:深度方向的 2D 卷积。插图来自用于机器学习的深度方向可分离卷积,2018。经允许重新发布

卷积神经网络(CNN)的核心是卷积层,这也是它们得名的原因。CNN 是专门为处理图像而设计的,其灵感来自人类的视觉方式。与矢量化图像的传统神经网络不同,CNN 采用图像的 2D 形式。这个过程与传统的神经网络相比具有显著的优势;它保持像素的空间位置。因为图像没有被矢量化,所以图像的 2d 特征被正确地馈送到网络。

这里,Sobel 滤波器(如上图 7 所示)与两个卷积层中的 16 个通道进行卷积。然后,将得到的矩阵线性化为感知向量,并馈入最终的线性神经层,该层给出 128 个输出节点,其中 ReLU 激活函数然后将它们馈入产生 16 个值的线性层。每个值代表 16 个原始通道之一的更新规则。

CNN: ReLU 激活

图 10:从激活函数中选择 ReLU 函数,如果神经元不给出火花值(权重),最初没有任何变化,而在权重超过 0[6,7]后,响应的幅度线性变化(公共域

体系结构的这些层是测试和更改更新规则的地方。每个细胞对感知向量应用一系列运算,例如卷积运算和 ReLU 非线性。这些操作是系统的更新规则。网络正在将该更新规则参数化为 8000 个参数。然后检查来自 ReLU 函数的信号,然后应用适当的更改来更新规则。这些变化以感知向量中不同状态的值相加或相减的形式出现。此外,这些变化由 ReLU 函数指示的权重和值来指导。

CNN:随机过滤和状态更新

该规则根据一个神经网络步骤的结果不断改变。但是,不会直接应用更新规则。与传统的元胞自动机模型不同,元胞不会同时更新。这种概率方法类似于自组织生物系统,因为细胞不在全局同步中工作。在该模型中,每次更新都应用于每个单元,等待时间是随机的。我们放宽了这一要求,假设每个单元独立执行一次更新,在更新之间等待一个随机的时间间隔。

结果

为了测试这个系统,我们最初试图重现基斯·哈林的作品以及其他一些符号。仅通过查看目标图像和对应于该图片的最佳 CA,就可以直观地比较结果。也可以通过使用损失历史图来检查,其中最佳细胞自动机模型具有最低的对数损失分数。这也表明了目标图像的复杂性。高度复杂的目标图像在 80,000 个步骤之后将不会被容易地再现。它通常具有较高的测井曲线损失值。

2-飞行恶魔:

图 11:左:哈林在 1990 年创造的飞行魔鬼图标。这是一件捕捉哈林经典风格的独特作品(图片基于公共项目档案)。右图:与目标图像相比,CA 模型丢失的日志(作者提供的图片)。

图 12:具有不同更新规则的四个不同的 CA。第一个具有最无效的更新规则,右边的最后一个具有最准确的更新规则(图由作者提供)。

3-光彩照人的宝贝:

图 13:左:哈林在 1990 年创造的光芒四射的婴儿图标(图片基于公共项目档案)。左图:与目标映像相比,CA 模型丢失的日志。

图 14:具有不同更新规则的四个不同的 CA。第一个是最无效的更新规则,右边的最后一个是最准确的更新规则(作者提供的图表)

讨论

该项目能够高精度地重现这些图标。然而,该过程有几个可以改进的限制。例如,该项目是在免费的 Colab 订阅上完成的,对计算能力有限制。因此,我们被迫将图像缩小到 40×40 像素。这使得目标图像失去了一些质量,看起来像是像素化的。

图 15:基斯·哈林的《三眼怪》(图片基于公共项目档案)。

此外,神经网络体系结构被设计为迭代超过 80,000 个具有不同更新规则的 CA 版本。由于其复杂性,这种迭代次数根本不足以精确再现某些目标图像,如基斯·哈林的“三眼怪”。

图 16:神经网络未能找到正确的更新规则,细胞以混乱的方式生长(图由作者提供)。

还值得一提的是,我们通过添加更多的卷积层和运算符来尝试不同的神经网络架构。然而,这只是增加了运行时间,并没有产生明显更好的结果。

结论

有必要考虑开发细胞自动机模型的替代方法。我们的目标是找到正确的设置,从一个种子细胞创造出高度复杂的结构,这不仅仅是从数学的角度出发。数值方法,如神经网络,可以帮助指导这种搜索。事实上,使用神经网络可能无法揭示创造生物结构的秘诀;然而,它可能会给你一个机会去哪里搜索这个食谱以及会有什么样的结果。

[## Sam Naji/艺术娱乐的神经细胞自动机

艺术娱乐文章的神经细胞自动机笔记。用户可以上传 png 并创建 CN 模型…

github.com](https://github.com/samnaji/Neural-Cellular-Automata-For-Art-Recreation/blob/master/Neural_Cellular_Automata_For_Art_Recreation.ipynb)

这幅作品献给伟大的艺术家基斯·哈林。如果你不知道哈林,他是一个街头艺术家,在他短暂的一生中,塑造了当代流行艺术,倡导同性恋权利,并不断提高对艾滋病的认识[8]。

图 17:哈林摄于 1988 年冈萨雷斯的一次聚会上。(公共领域

要阅读关于神经细胞自动机的更多细节,请查看这篇详细解释这一概念的优秀文章。这篇文章是这项工作的基础,我强烈推荐进一步的知识。

[## 生长神经细胞自动机

形态发生的可区分模型点击或轻敲图像擦除图案的一部分,并看到它再生…

蒸馏. pub](https://distill.pub/2020/growing-ca/)

参考文献:

[1] Mordvintsev 等人,生长神经细胞自动机 (2020),提取。

[2] Pray,l .,DNA 结构和功能的发现:Watson 和 Crick (2008),自然

[3]沃尔夫拉姆,斯蒂芬,一种新的科学 (2002),沃尔夫拉姆媒体。

[4] Weisstein,Eric W .,初等细胞自动机,来自 MathWorld 网络资源 MathWorld。

[5] Adamatzky、Andrew 和 Genaro J Martí nez,编辑。设计美:细胞自动机的艺术 (2018),施普林格。

[6] V,阿维纳什·夏尔马。了解神经网络中的激活功能 (2017)。,万物之论。

[8] Brownlee,Jason,《整流线性单元(ReLU)的温柔介绍》 (2019),深度学习性能。

[9]安德鲁·亚罗,艺术家基斯·哈林逝世,享年 31 岁;职业生涯始于《纽约时报》的地铁涂鸦 (1990)。

实践中的神经虚拟自我游戏

原文:https://towardsdatascience.com/neural-fictitious-self-play-in-practice-132836b69bf5?source=collection_archive---------47-----------------------

Leduc Hold'em 扑克游戏中神经元虚拟自我游戏的具体实现

基南·康斯坦斯在 Unsplash 上的照片

更新:学习和练习强化学习的最好方式是去http://rl-lab.com

本文描述了在 Leduc Hold'em 扑克游戏中基于 Eric Steinberger的代码实现的神经虚拟自我游戏(NFSP)。完整的源代码可以在他的 Github 库中找到。

如果你是新手,最好先从这些文章开始:
虚构游戏简介
虚构自我游戏
神经虚构自我游戏

免责声明:本文的目的不是解释实现代码中的每一个细节,而是强调代码实现和学术解决方案之间的主轴和映射。

实现涉及分布式计算,这增加了代码的复杂性。然而在本文中,我们将关注算法本身,我们将绕过分布式计算方面。
为此,我们将与下面的理论算法并行。

来自海因里希的 NFSP 算法/银纸

Leduc 德州扑克

首先,我们来定义一下 Leduc 德州扑克游戏。
这里是取自 DeepStack-Leduc 的定义。上面写着:

Leduc Hold'em 是一种玩具扑克游戏,有时用于学术研究(首次在Bayes ' Bluff:Poker 中的对手建模中介绍)。它是用一副六张牌来玩的,每副牌包括两副三个等级的花色(通常是国王、王后和杰克——在我们的实现中是王牌、国王和王后)。游戏开始时,每个玩家私下发一张牌,然后是一轮下注。然后,另一张牌面朝上的牌作为公共牌(或公共牌)发出,然后进行另一轮下注。最后,玩家展示他们的私人牌。如果一个玩家的私人牌和棋盘牌的等级相同,他或她赢得这场游戏;否则,私人牌排名较高的玩家获胜。

全局视图

主类是 workers\driver\Driver.py ,它有一个方法 run() 来启动一切。
它设置了每次迭代的主循环和算法执行,如下图所示。

Driver.py

该算法

大部分动作发生在 _HighLevelAlgo.py 中,在这里很容易区分学术解决方案的不同部分。

实际代码和理论解之间的映射: _HighLevelAlgo.py

播放阶段

让我们放大播放阶段。
代码不能完美地映射到理论解决方案,但也不远了。只是重组方式不同。
动作 a(t) 的采样发生在类 SeatActor 类中。你可以把的座位演员想象成玩家。不止一个。

另一方面,pockerenv . py(poker rl \ game \ _ \ rl _ env \ base)实际上是游戏引擎,游戏动态和规则在这里执行。每当“玩家”在游戏中行动时,就会调用 PockerEnv.step() 方法。

最后,learner actor(workers \ la \ local . py)是协调不同 SeatActors 的类。它包含 play() 方法,该方法执行对以下序列的几个类和方法的调用:

结果

据 Eric Steinberger 称,该代码取得了与学术论文相同的结果。

100 毫安/克(=来自纸张的 0.1A/克)线在 230 千次迭代(4:24 小时)后穿过,60 毫安/克线在 850 千次迭代(19 小时)后穿过。

该图显示了根据 NFSP 迭代次数的可开发性曲线。

可开发性图

提醒一下,可开发性是衡量策略最坏情况下的性能。关于可开发性的介绍可以在这些幻灯片中找到。

结论

这是由 Eric Steinberger 在实践中实现 NFSP 的一个快速概述(点击查看源代码)。
它将帮助您找到进入代码的方法,代码具有相当复杂的结构,并让您清楚地了解真正的动作发生在哪里。

最后,我要感谢埃里克·斯坦伯格审阅这篇文章并分享他的评论。
再次感谢 Arman Didandeh 校对本文。

神经性幻觉

原文:https://towardsdatascience.com/neural-hallucinations-13c645e2fd23?source=collection_archive---------20-----------------------

内部人工智能

神经网络如何产生图像修复中缺失像素的幻觉

约翰尼斯·普莱尼奥拍摄的照片

当一个人看到一个物体时,我们大脑视觉皮层中的某些神经元会活跃起来,但当我们服用致幻药物时,这些药物会淹没我们的血清素受体,导致对颜色和形状的扭曲视觉感知。类似地,以我们大脑结构为模型的深度神经网络将数据存储在巨大的数字系数表中,这违背了人类的直接理解。但是,当这些神经网络的激活被过度刺激(虚拟药物)时,我们就会出现神经梦和神经幻觉等现象。梦是我们大脑在感知器官关闭时产生的心理推测,而幻觉是在这个感知器官变得极度活跃时产生的。在这篇博客中,我们将讨论如何利用神经网络中的幻觉现象来完成图像修复的任务。

图像和视频修复

图像修复是一种合成替代内容的艺术,用于重建图像中缺失或损坏的部分,从而使修改在语义上正确且在视觉上逼真。在过去的几年中,图像修复受到了计算机视觉和图像处理界的极大关注,并在研究和应用领域取得了重大进展。传统上,使用基于示例的方法或者基于扩散的方法来实现修复,其中基于示例的方法一次重建一个似是而非的假设的一个缺失像素/片,同时保持邻域一致性,基于扩散的方法将局部语义结构传播到缺失部分。然而,无论采用何种方法,图像修复的核心挑战是保持全局语义结构,并为未知区域生成逼真的纹理细节。当缺失区域的大小很大或高度不规则时,传统方法无法实现这种全局语义结构和逼真的纹理。因此,需要一种能够为丢失的像素提供似是而非的幻觉的组件来解决这种修补问题。为了设计这些幻觉组件,研究人员一般会选择深度神经网络来提供自然图像的高阶模型。使用图像修补来修饰不需要的区域、移除分散注意力的对象或完成图像中被遮挡的区域的使用案例有很多。它还可以广泛应用于包括视频取消裁剪、重新定位、重新合成、旋转和拼接在内的任务。

图像修复应用示例- 来源

与图像修复类似,视频修复旨在用新合成的内容填充给定的时空区域。它用在时间和空间上都相干的像素来重建给定视频序列的缺失区域。传统的视频修复算法将该问题表述为基于块的优化任务,并遵循传统的图像修复流水线,通过对已知区域的时空块进行采样来填充缺失区域,然后将其作为最小化问题来求解。尽管由于物体和摄像机的复杂运动,大多数视频修复算法面临着明显的挑战。这些挑战主要是由于未知区域中平滑且均匀的光学运动场的假设。与图像修复类似,与丢失区域的似是而非的运动场幻觉相关联有助于应对这些挑战,并为视频序列生成无缝内容,使改变几乎察觉不到。视频修复主要用于视频恢复(去除划痕)、编辑特效工作流(去除不想要的对象、水印和徽标)以及视频稳定。

视频修复应用实例- 来源

没有任何先验知识就产生幻觉

卷积神经网络的优异性能通常归因于它们从大量数据中学习真实图像先验的能力。如果您想知道“图像先验”是什么意思,它是我们图像数据集中的“先验信息”,用于简化处理参数的选择和解决图像处理中的不确定性,如 CNN 在训练后学习的矢量表示。但相反,像【1】这样的研究表明,即使是生成 CNN 的结构也能够在任何数据密集型学习之前捕获大量低级图像统计数据。其主要思想是,即使随机初始化的卷积神经网络也可以用作手工制作的先验,在图像修复和去噪等标准逆问题中具有高质量的性能。这种想法不仅突出了生成器网络捕获的感应偏差,还弥合了深度学习 CNN 和基于手工制作的图像先验的无学习算法之间的差距。在这一节中,我们将重点讨论如何利用这种获得图像先验的技术来使图像中看不见的像素产生幻觉。

使用深度图像先验的图像修复- 来源

人们一致认为 CNN 的结构在网络性能中起着关键作用,并且网络结构必须与数据结构相一致。但同时,我们也不能指望一个未经训练的网络 F(θ)了解某些物体类别的具体外观细节。然而,如在[1]中所建议的,由于它们的局部和平移不变性的性质,即使是未经训练的卷积滤波器序列也具有捕获像素邻域之间的多尺度低级图像统计的能力。这些统计足以对图像修补问题中所需的条件图像分布 p(x_filled|x_missing)进行建模。在公式化过程中,该分布以更一般的方式书写,它被表述为能量最小化问题(在我们的情况下可以是损失函数最小化,例如 MSE)。我们假设地面真理属于具有零能量的点 x 的流形 E(x,x_in) = 0

x = arg min(E(x _ prior _ estimated|x _ input _ with _ missing _ pixels)+R(x)|其中 E 可以是类似 MSE 的损失函数, x_prior_estimated 是随机初始化网络的输出,x _ input _ with _ missing _ pixels是需要修复的输入,正则化子(x)可以

先验恢复期间的图像空间可视化— | 倾角代表深度图像先验。****可视化举例说明了超分辨率(左)和去噪(右)的任务,以解释通过参数化过程优化期间点的流形分布的视觉方面。

为了开始幻觉,我们首先需要一个对应于二进制掩码(M)的丢失或被遮挡像素的图像。现在,如果随机初始化的 CNN 估计丢失的区域,我们可以将损失计算为:

loss =[(x _ prior _ estimated x _ input _ with _ missing _ pixels)⦿m]|其中⦿是逐元素乘法

上述等式与丢失像素的实际值无关,这使得不可能直接对像素值进行优化。因此 x_prior_estimated 是在重新参数化后优化计算的。在许多情况下,产生的幻觉导致几乎完美的结果,几乎没有接缝和假象。然而,这种方法似乎有某些缺点,如修补大洞或任何高度语义缺失的区域。但这些缺点是可以接受的,因为这种方法没有在任何监督数据上进行训练,并且在大多数其他情况下都非常有效。

使用深度图像先验的图像修复- 来源

获得的幻觉强调了:

  • 该网络利用图像的全局和局部上下文,并用已知部分的纹理对缺失区域进行插值。
  • 传统的自相似先验和深度学习架构之间的关系,还建议并解释了具有用于一般识别任务的跳过连接的深度架构的好处。

运行这个 colab 笔记本,如果你想尝试图像修复的网络(提供:DmitryUlyanov)。

** [## 谷歌联合实验室

编辑描述

colab.research.google.com](https://colab.research.google.com/github/DmitryUlyanov/deep-image-prior/blob/master/inpainting.ipynb)

在图像上学习后产生幻觉

在本节中,我们将讨论一些帮助深度神经网络产生幻觉的相关网络架构组件。在我们讨论这些组件之前,重要的是调查激发这些组件的架构的人类行为,以便为图像恢复任务实现更好的幻觉。基本过程主要包括概念化和绘制两个步骤,以保持图像的全局结构一致性和局部像素连续性。在绘画过程中,人类通常从先前绘制的线的末端节点绘制新的线,以确保相邻像素的连续性和一致性。记住这一点,我们将讨论多个研究论文中提出的旨在实现类似目的的各种组件。

边缘幻觉之前,我们填写更好的细节和传播颜色。

最近的图像修复研究已经显示了通过使用主要两种类型的方法利用上下文信息的良好质量结果。第一类方法使用空间注意,其利用相邻像素特征作为参考来恢复未知像素,从而确保幻觉内容相对于全局上下文的语义一致性。第二类方法使用有效像素的条件值来预测缺失像素。然而,这两种类型的方法有时无法生成语义上完美的内容和无伪边界。但是,如果我们像在论文[2]和[3]中建议的那样,利用像连贯语义注意模块和门控卷积这样的架构,我们可以很容易地克服这些挑战。我们还将研究周期性激活功能的概念,如警报器用于产生更好的隐含神经表征,从而产生更好的神经幻觉。

连贯语义注意

CSA 层的图示显示了孔“m”中的每个神经补片如何在边界上搜索最相似的神经补片- 来源

受人类概念化和绘画方法的启发,[2]的作者引入了连贯语义注意(CSA)层。CSA 用已知区域中最相似的特征像素初始化丢失的像素值。然后,通过假设空间一致性,使用相邻像素的值迭代优化这些初始化的像素。所述过程的优点是双重的,第一个优点是由于初始化而引入的全局语义一致性,第二个优点是通过优化迭代确保的局部特征一致性。原始网络首先使用简单的自动编码器计算粗略预测(I_p )(以便可以为初始化过程计算相似性),然后将粗略预测(I_p)和输入图像(I_in)馈送到 CSA 促进的编码器层进行细化。精化网络对输入(I_p + I_in)执行上述两个步骤(初始化和迭代优化)以输出最终结果(I_r)。

简单来说就是迭代优化

pred_pixel = A + B

A =相似度(预测像素,相邻像素)×相邻像素

B =相似性(预测像素,最相似像素)×最相似像素

其中 pred_pixel 是要产生幻觉的像素,adjacent_pixel 是相邻像素,most_similar_pixel 是具有最相似特征的像素。相似性也被归一化。

利用 CSA 层的模型架构- 来源

门控卷积

当我们使用普通 CNN 时,卷积滤波器对所有像素应用相同的操作,而不管它们在空间上是位于已知区域还是未知区域。普通 CNN 的这一缺点导致模糊的输出,在色彩和边缘领域具有视觉假象。为了解决这些问题,最近的研究提出了部分卷积和门控卷积的概念[4,3]。门控卷积背后的主要思想是为每个空间位置和图像通道学习动态特征门控机制。门控值只不过是一个根据数据/要素自动计算并乘以要素以调整特定空间和通道索引值的软遮罩。例如,如果输入特征是 I_in,并且门控机制的可学习卷积权重矩阵是 W_g,则软掩码将被计算为:

门控值= sigmoid(∑W _ g I _ in)

(左)部分卷积和(右)门控卷积的图示。- 来源

然后,将计算出的柔化蒙版乘以原始特征。重要的是要注意,当卷积在 CNN 中逐层堆叠时,卷积之前或之后乘以掩码是等效的。门控卷积有两个显著的优点:

  • 首先,它使幻觉成分对任意形状更加鲁棒
  • 其次,它使网络能够不仅根据掩模和背景,而且根据一些通道中的语义分割信息来学习选择特征。

SIREN——正弦表示网络

图像修补的任务包括对图像信号的精细细节进行建模。但是大多数使用的方法经常无法学习图像的空间导数的鲁棒隐式神经表示,这在生成过程中可能重要也可能不重要(取决于任务的难度)。为了解决这个很少考虑的问题,[5]提出利用周期性激活对复杂的隐式神经表示进行鲁棒建模。与使用离散表示来模拟图像中不同类型信号的传统方法不同,SIREN 使用正弦作为周期性激活函数。由于正弦的导数是余弦,警报器的导数继承了警报器的属性,这使得能够监控具有复杂信号的警报器的任何导数。SIREN 的作者演示了 SIREN 在图像修复方面的能力,方法是将 5 层 MLP SIREN 拟合到图像输入中,并在表示上实施先验。下图显示了该方法的结果。因此,在这些组件中,SIREN 也值得一提,它无疑为许多类型的逆问题的未来工作提供了几个令人兴奋的途径。

图像修复结果来自 SIREN 模型,(左)地面真实和(右)修复图像- 来源

在视频上学习后产生幻觉

光流幻觉(a)对输入序列的光流估计。缺失区域是红色的白色方块(b)幻觉流边缘。(c)边缘导向流动完井- 来源

与图像修复不同,视频修复侧重于用生成的内容填充给定视频序列中的时空区域。为了合成这些内容,大多数传统方法使用基于补丁的合成。但在基于学习的方法兴起后,一些最成功的方法是基于流的方法,它们联合合成光流和颜色,以实现高分辨率输出。合成的颜色通常沿着流动轨迹传播到缺失的时空区域,以确保时间一致性,并且还减轻了记忆问题。在本节中,我们将讨论论文[6]中建议的基于流程的方法。

流引导视频补全算法概述- 来源

基于流的视频修复方法的关键部分是运动物体的光流场的精确和清晰的边缘合成。在[6]“流边缘引导的视频完成”中提出的方法旨在专门处理精确的流完成。为了达到同样的目的,网络的第一级计算序列的相邻和非相邻帧之间的前向和后向流。然后使用计算的流量,计算丢失像素区域的流量。为了计算初始流,他们首先使用 canny 边缘检测器提取已知区域的边缘,然后使用 EdgeConnect 并训练一个流边缘完成网络。网络的这一阶段是架构的主要幻觉组件,其工作是在缺失的区域中幻觉出流边缘。流动图的幻觉边缘通常是最显著的特征,用作产生分段平滑流动完成的关键输入。一旦光流的幻觉完成,网络沿着向后和向前的流轨迹为每个丢失的像素传播两个候选像素。网络还通过检查三个时间上相距较远的帧从序列中获得三个非局部流矢量。最后,使用置信度加权平均,在梯度域中融合每个缺失像素的候选像素值。梯度域中的这种类型的融合确保了任何视觉假象和可见色缝的去除。

结论

在这篇博客中,我们重点讨论了如何利用神经网络中的幻觉来完成图像修复的任务。我们讨论了三个主要场景,涵盖了在没有任何事先学习的情况下,在图像上学习后和在视频上学习后产生幻觉像素的概念。所有讨论的案例都有深刻的含义,并以各自的方式反映了图像/视频修复研究的丰富历史。然而,我们强调了所有这些方法的共同目标是如何产生看不见的像素,以及它们如何以各自的方式解决图像/视频修复的逆问题。神经幻觉的应用领域非常广泛,只受到设计者独创性的限制。

图像修复在编辑图像中的应用- 来源**

我的博客反映了我所从事的工作,并简单地传达了我对这些话题的理解。我对深度学习的解读可以和你不一样,但我的解读只能和我一样无误。

参考

[1] Ulyanov,d .,Vedaldi,a .,和 Lempitsky,V. (2020 年)。深度图像先验。国际计算机视觉杂志,128 ,1867–1888。

[2]刘,黄,姜,黄,肖,杨,张(2019).图像修复中的一致语义注意。 2019 IEEE/CVF 国际计算机视觉大会(ICCV) ,4169–4178。

[3]俞军,林,张志林,杨军军,沈,徐,陆,黄,等(2019)。基于门控卷积的自由曲面图像修复。 2019 IEEE/CVF 计算机视觉国际会议(ICCV) ,4470–4479。

[4]刘桂林、Fitsum A Reda、Kevin J Shih、廷、Andrew Tao 和 Bryan Catanzaro。基于部分卷积的不规则孔洞图像修复。《欧洲计算机视觉会议论文集》(ECCV)

[5]西茨曼,v .,马特尔,J.N .,伯格曼,a .,林德尔,D.B .,&韦茨斯坦,G. (2020)。具有周期性激活函数的隐式神经表示。 ArXiv,abs/2006.09661

[6]高,c .,萨拉夫,a .,黄,j .,&科普夫,J. (2020)。流动边缘引导的视频完成。 ArXiv,abs/2009.01835

使用自动编码器和张量流的神经植入

原文:https://towardsdatascience.com/neural-implanting-with-autoencoders-and-tensorflow-9c2c7b532198?source=collection_archive---------41-----------------------

🤖深度学习

使用自动编码器的图像重建(使用跳跃连接)

照片由卡伦·艾姆斯利Unsplash 上拍摄

直觉

马库斯·温克勒在 Unsplash 上拍摄的照片

想象你正在解决一个拼图游戏。你已经完成了大部分。假设你需要在一张图片的中间固定一块(这张图片快完成了)。你需要从盒子里选择一件适合这个空间的物品,并完成整幅画。

我相信你能很快做到这一点。但是你的大脑是怎么做到的呢?

首先,它分析空槽周围的图片(在那里你需要固定一块拼图)。如果图片中有一棵树,你会寻找一个绿色的块(这是显而易见的!).因此,简而言之,我们的大脑能够通过了解图像的周围环境来预测作品(将适合该槽)。

在本教程中,我们的模型将执行类似的任务。它将学习图像的上下文,然后使用这个学习的上下文预测图像的一部分(丢失的)。

代码实现

我建议你应该在另一个标签中打开这个笔记本(TF 实现),这样你就能对正在发生的事情有一个直觉。

[## 谷歌联合实验室

编辑描述

colab.research.google.com](https://colab.research.google.com/drive/1zFe9TmMCK2ldUOsVXenvpbNY2FLrLh5k#scrollTo=UXjElGKzyiey&forceEdit=true&sandboxMode=true)

问题陈述

我们希望我们的模型能够预测图像的一部分。给定一个有洞的图像(图像数组的一部分,只包含零),我们的模型将预测完整的原始图像。

因此,我们的模型将使用它在训练期间学习的上下文来重建图像的丢失部分。

作者图片

数据

我们将为我们的任务选择一个域。我们在 Kaggle 上选择了一些山脉图像,它们是英特尔图像分类数据集的一部分。

为什么只有山脉的图像?

这里,我们选择属于特定领域的图像。如果我们选择一个在野生的图像中有的数据集,我们的模型将不能很好地执行。因此,我们将其限制在单个域中。

数据集中的一些图像。作者图片

使用wget下载我在 GitHub 上托管的数据

!wget [https://github.com/shubham0204/Dataset_Archives/blob/master/mountain_images.zip?raw=true](https://github.com/shubham0204/Dataset_Archives/blob/master/mountain_images.zip?raw=true) -O images.zip!unzip images.zip

为了生成训练数据,我们将遍历数据集中的每个图像,并对其执行以下任务。

作者图片

  1. 首先,我们将使用PIL.Image.open()读取我们的图像文件。使用np.asarray()将这个Image对象转换成一个 NumPy 数组。
  2. 确定窗口大小。这将是我们要从原始图像中提取的正方形的边长。
  3. [ 0 , image_dim — window_size ]范围内产生 2 个随机数。其中image_dim是我们的正方形输入图像的大小。
  4. 这两个数字(称为pxpy)是原始图像将被裁剪的位置。选择图像数组的一部分,并用零数组替换它。

代码看起来像这样,

1.准备培训数据。

带跳跃连接的自动编码器型号

我们将跳过连接添加到我们的自动编码器模型中。这些跳跃连接提供了更好的上采样。通过使用最大池层,许多空间信息在进入编码器时会丢失。为了从图像的潜在表示(由编码器产生)中重建图像,我们添加了跳过连接,将信息从编码器带到解码器。

2.自动编码器模型。

最后,我们用跳过连接来训练我们的自动编码器模型,

model.fit( x_train , y_train , epochs=150 , batch_size=25 , validation_data=( x_test , y_test ) )

作者图片

上述结果是在一些测试图像上获得的。我们观察到模型几乎已经学会了如何填充黑盒!但我们仍能辨认出盒子在原始图像中的位置。这样,我们可以构建一个模型来预测图像中缺失的部分。

进一步阅读

如果你喜欢这个博客,请确保你在媒体上读到更多我的故事。

仅此而已!

这只是自动编码器的一个很酷的应用。我从这里得到了这个视频的灵感。感谢阅读!

作为特定领域知识库的神经语言模型

原文:https://towardsdatascience.com/neural-language-models-as-domain-specific-knowledge-bases-9b505b21de5?source=collection_archive---------22-----------------------

图片来自 Unsplash

自然语言处理|基于转换器的语言模型|领域知识和领域本体

基于转换器的语言模型承载的领域知识分析

自然语言处理(NLP)的基本挑战是解决自然语言的含义和意图中存在的歧义。歧义发生在语言理解的多个层面,如下图所示:

(图片由作者提供)

为了解决文本中的歧义,算法使用来自文本出现的上下文的知识。例如,句子“我参观了动物园。”我看见了一只蝙蝠”这句话前可以用来推断蝙蝠代表的是一种动物而不是一根木棒。

虽然在许多情况下,相邻文本足以减少歧义,但通常在处理来自专门领域的文本时,这是不够的。处理特定领域的文本需要理解大量特定领域的概念和过程,这是 NLP 算法无法单独从相邻文本中收集到的。

例如,在产权保险和结算领域,算法可能需要理解以下概念:

  • A 1003 是一种表格,用于申请抵押
  • 平衡是完成房地产交易过程中的一个处理步骤
  • 平衡完成后,下一个处理 步骤可能是资金释放

这就是特定领域知识库的用武之地。

特定领域知识库获取自然语言处理算法正确解释特定领域文本所需的领域知识。

根据用例的不同,知识库中的知识可以是特定类型的,也可以是多种类型的。

传统上,知识库被建模为基于图的本体,并作为文本处理管道中的一个组件添加。然而,随着基于转换器的语言模型的出现,如伯特和 GPT-2,有研究和评估[1][2]在一个训练有素的语言模型中固有的知识的类型和质量。

注意:统计语言模型是单词序列的概率分布。给定序列的前面和/或后面的单词,概率分布用于预测在文本序列中某个位置最可能的单词。

这种评估的有利结果可以为从文本处理管道中去除单独的知识库组件以显著降低其复杂性提供理由。围绕这一思想,这篇博客文章描述了基于图的知识库的挑战,并提供了对语言模型中存在的领域知识的评估,这些语言模型已经在标题和结算领域的文本上进行了微调。

知识库中预期的知识类型

要评估一个知识库,需要测试处理领域文本所需的所有类型的知识。以下是特定领域文本处理知识库中可能需要的精选知识类型列表:

1.特定于业务的实体的知识,如工件、事件和参与者

  • 示例:文档、文件、公证和特定类型的文档,例如 1003
  • 这种类型的知识支持实体级领域属性的定义和应用。例如,如果一个文档被识别,就知道它可以被共享,并且它具有页数属性

2.实体属性的知识

  • 例如:住宅再融资借款人有一个属性,如婚姻状况
  • 这种类型的知识定义了与实体类型相关联的属性,并有助于文本的解释和信息的提取

3.了解实体之间的关系

  • 示例:结算披露是贷款人一揽子计划的一部分
  • 这种类型的知识有助于评估修改子实体时对父实体的影响

4.了解所有这些如何整合到业务流程中

  • 示例:找到公证人,安排成交预约
  • 这种类型的知识决定了在给定业务流程状态信息的情况下的下一个动作

根据业务领域和用例,知识库中可能需要更多类型的知识。

典型的知识库设计、生命周期和成本

要创建知识库,需要定义知识库中存在的知识。根据知识库的不同,这要么完全由人类专家来完成,例如 WordNet [3],要么由自动算法来完成,这些算法可能基于也可能不基于人类定义的知识,例如 YAGO [4]。

知识一旦被定义,就在知识库中被建模为图形或本体。像个体这样的概念被建模为节点,它们之间的关系被建模为图的边。类表达像文档和事件这样的概念。个人表示类别的实例,例如,1003、结案披露和契约都是类别文档的实例。边缘捕捉类和个体之间的关系。边捕获的关系的例子有 is-type-of、is-instance-of 和 has-attribute。在下面的例子中, 1003文档之间的有向边用于获取 a 1003 是文档类型的知识。

(图片由作者提供)

本体或图形本身使用知识表示语言如 RDF、RDFS 和 OWL 来表示,并以 XML 等格式存储。

有许多流行的知识库——像 YAGO 和概念网——以这种方式模拟各种关系。他们经常从维基百科和 WordNet 等其他知识库中挑选实体进行建模。

一旦一个知识库准备好了,不同的 NLP 模型使用不同的方法将它合并到他们的管道中。选项包括:

  1. 使用知识库中存在的实体类型信息来替换或增加文本中的实体出现
  2. 使用基于图的测量创建的特征,如文本中提到的实体节点之间的距离,作为模型中的特征[5]
  3. 更先进的方法,通过图形嵌入和基于 LSTM 的特征提取等技术,将图形的特征提取结合到反向传播和损失优化循环中[6]

这些方法很重要,需要付出巨大的努力才能发明出来,并在培训和应用阶段加以整合。

基于以上所述,很明显,图形和本体形式的知识库在时间、精力和金钱方面是昂贵的,尤其是当涉及人类专家时。

评估基于 Transformer 的语言模型是否带有内置的领域知识库

动机

因为创建和合并基于本体的知识库是昂贵的,所以更好的选择总是受欢迎的。

近年来,基于 Transformer 的语言模型,如 BERT 和 GPT-2,在 NLP 竞赛、任务和基准测试中占据了领先地位。令人印象深刻的是,他们通过以下方式实现了这一目标:

  1. 形成端到端管道的单个模型(与多模型文本处理管道相反)
  2. 预训练模型的最小微调
  3. 在多项任务中使用通用基础模型

鉴于这样的成功和易用性,如果这些模型的微调版本中包含领域知识,那将是理想的。如果是这样,可以:

  1. 跳过创建知识库的高成本
  2. 删除单独的知识库组件,简化多模型文本处理流程
  3. 保留拥有知识库的好处,因为在语言模型中获取的知识将在使用模型进行下游任务时自动发挥作用
  4. 在语言模型的预训练阶段,获得内置于语言模型中的更广泛的世界知识的额外提升

评价方法

为了进行评估,我们在公司内部数据上微调了一个 roBERTa-base 和一个 gpt2-medium 模型(都来自拥抱脸),并探索了其中捕获的知识。用于评估模型的方法是:

1.决定需要评估的知识类型。示例:关系的类型

2.生成知识类型的特定实例,以测试知识的存在。示例:1003 是一种文档。

3.通过屏蔽单词或在实例末尾添加额外的填空类问题来修改知识实例。例:1003 是 _ _ _ _ _ _ _ _ _ 的一种。

4.请模型填空并评价答案。

请注意,根据需要测试的知识类型,还可以使用其他方法。

样本模型输入和输出

(图片由作者提供)

选择调查结果和分析

RoBERTa 捕捉了多种类型的关系,并能够自动将学到的概念扩展到新的看不见的实体实例

Is-type-of 关系:

4.预微调:花旗银行是一种 银行

5.后期微调:花旗银行是 贷款人 的一种。

注意,花旗银行根本不在数据集中。该模型似乎了解到,银行在产权保险和结算业务中扮演贷款人的角色。然后,它将这种学习应用到它从预培训中了解到的银行。

实体-属性关系:

6.后期微调:公证员的 _____ 是 _____

第一个空格的建议上限值:姓名、信息、电子邮件、联系人、信息、地址、确认、时间表、号码

与行动相关的实体关系

7.________ 需要更改

建议的空白值有:密码、标题、这个、什么都没有、CD、金额、费用、it、姓名

虽然有几个例子的模型结果不如上述例子有说服力,但对大多数例子来说,它们是有说服力的。语言模型似乎很好地捕捉了 is-type-of、entity-attribute 和 entity-associated-action 关系。

模型输出的知识虽然大多是合理的,但并不总是信息丰富、有用或理想的

关系的一部分

8.贷方包由组成。

其他热门答案有:二、文件、信托、箱子

对于上面的例子,虽然像文档这样的答案没有错,但是它们也不是很有用。像结案陈词1003签名宣誓书这样的回答会提供更多信息。类似地在实施例 7 中。,像没什么这个这样的回答是没有参考价值的。这些无用的答案是在各种评估中发现的,可以大致分为以下几类:代词,疑问词,如“什么”,标点符号,以及大小写变化重复的单词。

模型开发了对业务流程的良好理解,但是需要智能的外部输入来利用这种理解

业务流程理解

微调过的罗伯塔:

  • 输入:我们是平衡的。
  • 增补:请提供 _ _ _ _ _ _ _ _ _ _
  • 模型输出(接下来两个词):收益表

微调过的 gp T2-培养基:

  • 输入:贷款金额有误。
  • 增补:请提供 _ _ _ _ _ _ _ _ _ _
  • 模型输出:用正确的贷款金额更新费用表
  • 输入:贷款金额有误。
  • 增强:请获取 _ _ _ _ _ _ _ _ _ _
  • 模型输出:契约修正归属
  • 输入:公证可用。
  • 增强:下一步是 _ _ _ _ _ _ _ _ _ _
  • 模型输出:签名

注意,在例 9 中。, 10.和 12。如果有很好的补充,这个模型能够给出一个合理的答案。相反,在实施例 11 中。在增强不典型的情况下,模型没有产生可接受的答案。如果下游任务没有简单的方法来提供所需的文本扩充,这可能会成为一个问题。

超越语言模型的内置知识库

虽然这篇博客主要关注于评估语言模型的内置知识库,但是如果有必要并且成本不太高的话,可以考虑类似 COMeT[7]的方法。COMeT 在现有知识库上微调预先训练的语言模型,以预测已知和新的知识库关系。

现有知识库上的训练用比原始知识库或预训练语言模型中包含的知识更广泛和更准确的知识来丰富模型。虽然关于 COMeT 方法的讨论超出了本博客的范围,但是在ATOMIC【8】和concept net【9】上训练的 COMeT 的在线演示可以在这里找到。

外卖食品

基于上面的分析,我们相信语言模型——一旦经过微调——确实包含了丰富的领域知识。然而,在直接利用知识的过程中,存在一些挑战,如正确的扩充文本和识别更多信息的模型输出。

文章最早出现在【statestitle.com】

参考文献

[1] Petroni,Fabio 等,“作为知识库的语言模型?”2019 自然语言处理经验方法会议暨第九届国际自然语言处理联合会议(EMNLP-IJCNLP)论文集。2019.

[2]戴维森、乔、约书亚·费尔德曼和亚历山大·拉什。"从预先训练的模型中挖掘常识知识."2019 自然语言处理经验方法会议暨第九届国际自然语言处理联合会议(EMNLP-IJCNLP)论文集。2019.

[3]普林斯顿大学。“关于 WordNet。” WordNet 。普林斯顿大学。2010.

[4] Suchanek,Fabian M .,Gjergji Kasneci 和 Gerhard Weikum。" Yago:语义知识的核心."第 16 届国际万维网会议论文集。2007.

[5]夏,江南,陈武,。"通过多任务学习将关系知识融入常识阅读理解."第 28 届 ACM 信息与知识管理国际会议论文集。2019.

[6]林,比尔·,等.〈知识感知图网络:用于常识推理.〉 arXiv 预印本 arXiv:1909.02151。 2019。

[7] Bosselut,Antoine 等,《彗星:知识图构建的常识变压器》计算语言学协会(ACL) 。2019.

[8] Sap,Maarten 等人,“原子:如果-那么推理的机器常识图谱”AAAI 人工智能会议论文集。第 33 卷。2019.

[9]斯佩尔、罗宾、约书亚·钦和凯瑟琳·哈瓦西。"概念网 5.5:一个通用知识的开放多语言图表."第 31 届 AAAI 人工智能会议论文集。2017.

具有注意机制的神经机器翻译(NMT)

原文:https://towardsdatascience.com/neural-machine-translation-nmt-with-attention-mechanism-5e59b57bd2ac?source=collection_archive---------14-----------------------

深度学习语言翻译指南!

概观

不可否认的事实是,在这个全球化的时代,语言翻译在不同国家的人们之间的交流中起着至关重要的作用。此外,在一个像印度这样的国家——一个使用多种语言的国家,语言差异在它自己的各邦都可以观察到!因此,考虑到语言翻译的重要性,有必要开发一个能够将未知语言翻译成已知语言的系统。

据此,在这个故事中,我们将制作一个深度学习模型,将英语句子翻译成马拉地语句子。我选择了马拉地语,因为它容易辨认。您可以使用任何其他您觉得舒服的语言,因为模型几乎保持不变。而且,我在这里会试着简单解释一下语言处理中的一个主要概念叫做注意机制!

先决条件

  1. 长短时记忆(LSTM) 细胞的工作
  2. TensorFlow、Keras 和其他一些强制性 python 库的工作。

什么是注意力机制?

序列递归神经网络的主要缺点是只能处理短序列。编码器模型很难记忆长序列并将其转换成固定长度的向量。此外,解码器仅接收一个信息,即最后一个编码器隐藏状态。因此,解码器很难一次汇总大量的输入序列。那么,我们如何克服这个问题呢?

如果我们给解码器模型一个从每一个编码器步骤的向量表示怎么样!

现在,这就是‘注意力机制’概念的来源。关于这一点的主要直觉是,它通过关注序列的几个相关部分而不是查看整个序列来预测下一个单词。

通俗地说,它可以被描述为编码器和解码器之间的干扰,它从编码器中提取有用的信息,并将其传输回解码器。

注意力层动画

此处 参考 详细了解注意机制。

主要有两种类型的注意机制:

  • 全球关注
  • 当地的关注

全球关注

全局注意力是那些通过编码器的所有隐藏状态向量来获得上下文向量的注意力。

当地的关注

局部注意力是那些仅考虑编码器的少数隐藏状态向量来生成上下文向量的注意力。

在这个故事中,我们将利用全球的注意力。现在让我们利用注意机制,开发一个语言翻译器,将英语句子转换成马拉地语句子。

履行

库导入

打开 Jupyter 笔记本,导入一些需要的库:

import pandas as pd
from sklearn.model_selection import train_test_split
import string
from string import digits
import re
from sklearn.utils import shuffle
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.layers import LSTM, Input, Dense,Embedding, Concatenate, TimeDistributed
from tensorflow.keras.models import Model,load_model, model_from_json
from tensorflow.keras.utils import plot_model
from tensorflow.keras.preprocessing.text import one_hot, Tokenizer
from tensorflow.keras.callbacks import EarlyStopping
import pickle as pkl
import numpy as np

下载数据集

我们将在这里 使用一个可用的语言数据集

该网站包含许多语言的数据集及其英语翻译。你可以根据自己的喜好和舒适度下载任何语言数据集。但是,记住要选择一个相当庞大的数据集,这样我们在训练模型后才能得到更好的结果。在这里,我将下载由 38696 个句子组成的马拉地语-英语数据集。

下载加载数据集后,按如下所述导入数据:

with open('mar.txt','r') as f:
  data = f.read()

预处理数据集

数据转换

正如你所看到的,这是一个原始的文本文件,因此有必要根据我们的喜好对其进行清理和转换。我们将分离马拉地语和英语句子,并形成一个列表,通过将它存储到一个数据帧中来延续它,这样我们就可以很容易地再次使用它。

uncleaned_data_list = data.split('\n')
len(uncleaned_data_list)
uncleaned_data_list = uncleaned_data_list[:38695]
len(uncleaned_data_list)english_word = []
marathi_word = []
cleaned_data_list = []
for word in uncleaned_data_list:
  english_word.append(word.split('\t')[:-1][0])
  marathi_word.append(word.split('\t')[:-1][1])language_data = pd.DataFrame(columns=['English','Marathi'])
language_data['English'] = english_word
language_data['Marathi'] = marathi_wordlanguage_data.to_csv('language_data.csv', index=False)

language_data.head()

english_text = language_data['English'].values
marathi_text = language_data['Marathi'].values
len(english_text), len(marathi_text)

数据清理

现在让我们清理数据,使其适合我们的模型。在清理过程中,我们将转换成小写,删除所有标点符号和其他不必要的字母和数字。

**#to lower case**
english_text_ = [x.lower() for x in english_text]
marathi_text_ = [x.lower() for x in marathi_text]**#removing inverted commas**
english_text_ = [re.sub("'",'',x) for x in english_text_]
marathi_text_ = [re.sub("'",'',x) for x in marathi_text_]def remove_punc(text_list):
  table = str.maketrans('', '', string.punctuation)
  removed_punc_text = []
  for sent in text_list:
    sentance = [w.translate(table) for w in sent.split(' ')]
    removed_punc_text.append(' '.join(sentance))
  return removed_punc_text
english_text_ = remove_punc(english_text_)
marathi_text_ = remove_punc(marathi_text_)remove_digits = str.maketrans('', '', digits)
removed_digits_text = []
for sent in english_text_:
  sentance = [w.translate(remove_digits) for w in sent.split(' ')]
  removed_digits_text.append(' '.join(sentance))
english_text_ = removed_digits_text**# removing the digits from the marathi sentances**
marathi_text_ = [re.sub("[२३०८१५७९४६]","",x) for x in marathi_text_]
marathi_text_ = [re.sub("[\u200d]","",x) for x in marathi_text_]**# removing the stating and ending whitespaces**
english_text_ = [x.strip() for x in english_text_]
marathi_text_ = [x.strip() for x in marathi_text_]

在马拉地语句子中添加“开始”和“结束”标签。这将帮助解码器知道从哪里开始解码以及何时结束解码。

# Putting the start and end words in the marathi sentances
marathi_text_ = ["start " + x + " end" for x in marathi_text_]# manipulated_marathi_text_
marathi_text_[0], english_text_[0]

(“开始जा结束”,“开始”)

建模的数据准备

我们将以 0.1 的比率分割我们的数据集,以便我们训练的模型可以给出精确的结果。X_train 和 y_train 将是我们的训练集,而 X_test 和 y_test 将是我们的测试/验证集。

X = english_text_
Y = marathi_text_X_train, X_test, y_train, y_test=train_test_split(X,Y,test_size=0.1)

让我们确定英语和马拉地语句子的最大长度:

def Max_length(data):
  max_length_ = max([len(x.split(' ')) for x in data])
  return max_length_#Training data
max_length_english = Max_length(X_train)
max_length_marathi = Max_length(y_train)#Test data
max_length_english_test = Max_length(X_test)
max_length_marathi_test = Max_length(y_test)max_length_marathi, max_length_english

(26, 32)

标记化:

由于神经网络需要处理数字数据,因此有必要将我们的字符串输入转换为数字列表。一种方法是使用 keras 预处理库提供的标记器

此外,请记住,在序列到序列模型中,所有输入序列的长度必须相等。因此,我们将填充额外的“0”以使序列具有相同的长度。这将由 pad_sequence 完成。

englishTokenizer = Tokenizer()
englishTokenizer.fit_on_texts(X_train)
Eword2index = englishTokenizer.word_index
vocab_size_source = len(Eword2index) + 1X_train = englishTokenizer.texts_to_sequences(X_train)
X_train = pad_sequences(X_train, maxlen=max_length_english, padding='post')X_test = englishTokenizer.texts_to_sequences(X_test)
X_test = pad_sequences(X_test, maxlen = max_length_english, padding='post')marathiTokenizer = Tokenizer()
marathiTokenizer.fit_on_texts(y_train)
Mword2index = marathiTokenizer.word_index
vocab_size_target = len(Mword2index) + 1y_train = marathiTokenizer.texts_to_sequences(y_train)
y_train = pad_sequences(y_train, maxlen=max_length_marathi, padding='post')y_test = marathiTokenizer.texts_to_sequences(y_test)
y_test = pad_sequences(y_test, maxlen = max_length_marathi, padding='post')vocab_size_source, vocab_size_target

(5413, 12789)

X_train[0], y_train[0]

(array([ 1,157,5,134,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,dtype=int32),
array([ 1,6,22,61,253,29,2,0,0,0,0,0,0,0,0,0

为了节省我们的预处理时间,我们将保存我们的重要属性。所以,我们先借助泡菜库来做。

with open('NMT_data.pkl','wb') as f:
  pkl.dump([X_train, y_train, X_test, y_test],f)with open('NMT_Etokenizer.pkl','wb') as f:
  pkl.dump([vocab_size_source, Eword2index, englishTokenizer], f)with open('NMT_Mtokenizer.pkl', 'wb') as f:
  pkl.dump([vocab_size_target, Mword2index, marathiTokenizer], f)X_train = np.array(X_train)
y_train = np.array(y_train)
X_test = np.array(X_test)
y_test = np.array(y_test)

模型结构

取代简单的编码器-解码器架构,我们将使用本博客前面讨论过的注意机制。

Keras 不正式支持关注层。因此,我们可以实现自己的关注层,也可以使用第三方实现。目前,我们将使用第三方关注机制。你可以从 这里 下载关注层,复制到另一个名为 attention.py 的文件中。这个注意力是 【巴赫达瑙注意力】 的一个实现。

让我们定义模型的结构:

from attention import AttentionLayer
from keras import backend as K 
K.clear_session() 
latent_dim = 500# Encoder 
encoder_inputs = Input(shape=(max_length_english,)) 
enc_emb = Embedding(vocab_size_source, latent_dim,trainable=True)(encoder_inputs)#LSTM 1 
encoder_lstm1 = LSTM(latent_dim,return_sequences=True,return_state=True) 
encoder_output1, state_h1, state_c1 = encoder_lstm1(enc_emb)#LSTM 2 
encoder_lstm2 = LSTM(latent_dim,return_sequences=True,return_state=True) 
encoder_output2, state_h2, state_c2 = encoder_lstm2(encoder_output1)#LSTM 3 
encoder_lstm3=LSTM(latent_dim, return_state=True, return_sequences=True) 
encoder_outputs, state_h, state_c= encoder_lstm3(encoder_output2)# Set up the decoder. 
decoder_inputs = Input(shape=(None,)) 
dec_emb_layer = Embedding(vocab_size_target, latent_dim,trainable=True) 
dec_emb = dec_emb_layer(decoder_inputs)#LSTM using encoder_states as initial state
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True) 
decoder_outputs,decoder_fwd_state, decoder_back_state = decoder_lstm(dec_emb,initial_state=[state_h, state_c])#Attention Layer
attn_layer = AttentionLayer(name='attention_layer') 
attn_out, attn_states = attn_layer([encoder_outputs, decoder_outputs])# Concat attention output and decoder LSTM output 
decoder_concat_input = Concatenate(axis=-1, name='concat_layer')([decoder_outputs, attn_out])#Dense layer
decoder_dense = TimeDistributed(Dense(vocab_size_target, activation='softmax')) 
decoder_outputs = decoder_dense(decoder_concat_input)# Define the model
model = Model([encoder_inputs, decoder_inputs], decoder_outputs) plot_model(model, to_file='train_model.png', show_shapes=True)

您可以根据自己的选择和要求修改该模型,以获得更好的结果。你也可以改变层数、单位数或一些正则化技术。暂时先往前走,看看我们的模型是什么样子的!

model.compile(optimizer='rmsprop',
              loss='sparse_categorical_crossentropy', 
              metrics=['accuracy'])

模特培训

我们将首先定义一些回调,以便将来模型可视化和评估变得容易。

es = EarlyStopping(monitor='val_loss', mode='min', verbose=1)

我们正在使用“教师强制”技术来更快地训练我们的模型。在教师强制方法中,我们还将目标数据作为输入传递给解码器。例如,如果我们要预测“hello ”,那么我们将把“hello”本身作为输入传递给解码器。因此,这使得学习过程更快。

让我们训练我们的模型:

history = model.fit([X_train, y_train[:,:-1]], y_train.reshape(y_train.shape[0], y_train.shape[1],1)[:,1:], 
                    epochs=50, 
                    callbacks=[es],
                    batch_size=512,
                    validation_data = ([X_test, y_test[:,:-1]],           y_test.reshape(y_test.shape[0], y_test.shape[1], 1)[:,1:]))

在 12GBNVIDIATesla K80GPU上,执行时间约为每个纪元 39 秒。18 世纪实现了早期停止。

我们可以将训练和验证阶段的损失差异形象化为:

from matplotlib import pyplot 
pyplot.plot(history.history['loss'], label='train') 
pyplot.plot(history.history['val_loss'], label='test') 
pyplot.legend() 
pyplot.show()

损失比较

我们从我们的模型中得到了一些非常好的结果,验证准确率约为 90%,验证损失为 0.5303。

模型保存和加载

让我们用适当的权重来保存我们训练好的模型。请记住像我一样保存模型,因为我们还必须为推理模型加载权重。

model_json = model.to_json()
with open("NMT_model.json", "w") as json_file:
    json_file.write(model_json)
# serialize weights to HDF5
model.save_weights("NMT_model_weight.h5")
print("Saved model to disk")

负载模型:

# loading the model architecture and asigning the weights
json_file = open('NMT_model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
model_loaded = model_from_json(loaded_model_json, custom_objects={'AttentionLayer': AttentionLayer})
# load weights into new model
model_loaded.load_weights("NMT_model_weight.h5")

推理模型

在机器学习中,我们通过考虑来自预训练模型的权重,使用推理模型来预测我们的输出序列。换句话说,可以说它是一个模型,该模型推导出在训练阶段学习到的并且现在用于预测新序列的属性。

让我们编写推理模型的代码:

latent_dim=500
# encoder inference
encoder_inputs = model_loaded.input[0]  #loading encoder_inputs
encoder_outputs, state_h, state_c = model_loaded.layers[6].output #loading encoder_outputs#print(encoder_outputs.shape)encoder_model = Model(inputs=encoder_inputs,outputs=[encoder_outputs, state_h, state_c])# decoder inference
# Below tensors will hold the states of the previous time step
decoder_state_input_h = Input(shape=(latent_dim,))
decoder_state_input_c = Input(shape=(latent_dim,))
decoder_hidden_state_input = Input(shape=(32,latent_dim))# Get the embeddings of the decoder sequence
decoder_inputs = model_loaded.layers[3].output#print(decoder_inputs.shape)
dec_emb_layer = model_loaded.layers[5]dec_emb2= dec_emb_layer(decoder_inputs)# To predict the next word in the sequence, set the initial states to the states from the previous time step
decoder_lstm = model_loaded.layers[7]
decoder_outputs2, state_h2, state_c2 = decoder_lstm(dec_emb2, initial_state=[decoder_state_input_h, decoder_state_input_c])#attention inference
attn_layer = model_loaded.layers[8]
attn_out_inf, attn_states_inf = attn_layer([decoder_hidden_state_input, decoder_outputs2])concate = model_loaded.layers[9]
decoder_inf_concat = concate([decoder_outputs2, attn_out_inf])# A dense softmax layer to generate prob dist. over the target vocabulary
decoder_dense = model_loaded.layers[10]
decoder_outputs2 = decoder_dense(decoder_inf_concat)# Final decoder model
decoder_model = Model(
[decoder_inputs] + [decoder_hidden_state_input,decoder_state_input_h, decoder_state_input_c],
[decoder_outputs2] + [state_h2, state_c2])

预言

现在,我们已经训练了序列对序列模型,并使用训练的模型创建了用于进行预测的推理模型。让我们从英语句子中预测一些马拉地语句子。

def decode_sequence(input_seq):
    # Encode the input as state vectors.
    e_out, e_h, e_c = encoder_model.predict(input_seq)# Generate empty target sequence of length 1.
    target_seq = np.zeros((1,1))# Chose the 'start' word as the first word of the target sequence
    target_seq[0, 0] = Mword2index['start']stop_condition = False
    decoded_sentence = ''
    while not stop_condition:
        output_tokens, h, c = decoder_model.predict([target_seq] + [e_out, e_h, e_c])# Sample a token
        sampled_token_index = np.argmax(output_tokens[0, -1, :])
        if sampled_token_index == 0:
          break
        else:
          sampled_token = Mindex2word[sampled_token_index]if(sampled_token!='end'):
              decoded_sentence += ' '+sampled_token# Exit condition: either hit max length or find stop word.
              if (sampled_token == 'end' or len(decoded_sentence.split()) >= (26-1)):
                  stop_condition = True# Update the target sequence (of length 1).
          target_seq = np.zeros((1,1))
          target_seq[0, 0] = sampled_token_index# Update internal states
          e_h, e_c = h, creturn decoded_sentence

形成反向词汇:

Eindex2word = englishTokenizer.index_word
Mindex2word = marathiTokenizer.index_word

在给函数一个字符串之前进行一些转换:

def seq2summary(input_seq):
    newString=''
    for i in input_seq:
      if((i!=0 and i!=Mword2index['start']) and i!=Mword2index['end']):
        newString=newString+Mindex2word[i]+' '
    return newStringdef seq2text(input_seq):
    newString=''
    for i in input_seq:
      if(i!=0):
        newString=newString+Eindex2word[i]+' '
    return newString

调用必要的函数,让我们测试我们的翻译模型:

for i in range(10):  
  print("Review:",seq2text(X_test[i]))
  print("Original summary:",seq2summary(y_test[i]))
  print("Predicted summary:",decode_sequence(X_test[i].reshape(1,32)))
  print("\n")

回顾:没人会告诉你
原概要:तुला कोणीही सांगणार नाही
预测概要:कोणीही तुला सांगणार नाही

回顾:前瞻
原创总结:समोर बघा
预测总结:तिथे बघ

回顾:我要把这个还给汤姆
原摘要:मी हे टॉमला परत करायला जातोय
预测摘要:मी ते स्वतःहून करणार आहे

回顾:一只雄鹰正在天空飞翔
原概要:आकाशात एक गरुड आहे
预测概要:न्यूयॉर्क अतिरेकी तो दुसर्याचा

回顾:他会说阿拉伯语
原文摘要:तो अरबी बोलतो
预测摘要:तो अरबी बोलतो

回顾:收拾这个烂摊子
原概要:हा पसारा साफ करून टाका
预测概要:हा पसारा साफ कर

回顾:不要在课堂上说法语
原概要:वर्गात फ्रेंचमध्ये बोलू नका
预测概要:वर्गात जास्त कठीण राहू नकोस

回顾:我关灯了
原概要:मी दिवे
预测概要:मी दोन हात वर केला

回顾:你有多少球拍
原概要:तुझ्याकडे किती रॅकेट आहेत
预测概要:तुमच्याकडे किती बहिणी आहेत

回顾:我给了汤姆·玛丽的电话号码
原概要:मी टॉमला मेरीचा फोन नंबर दिला
预测概要:मी टॉमला मेरीचा फोन क्रमांक दिला

万岁!!

我们的模型可以很好地将英语句子翻译成马拉地语句子。

项目演示

我已经通过 Django 部署了我的模型,并在 heroku 上托管了它。你可以在这里看看。

[## 哈希尔·帕特尔

hurdlenet.herokuapp.com](https://hurdlenet.herokuapp.com/)

结尾注释

在这个故事中,我们学习了注意机制的功能,并实现了一个语言翻译任务。这项任务在日常生活中可能有多个用例。例如,我们可以使用这种技术来构建一个多语言翻译器,它可以从一种语言翻译多种语言。此外,如果我们能把它与光学字符识别系统结合起来,我们就能直接从图像中翻译出文本。

如果您有任何其他使用案例或技术来处理翻译数据,并且如果您为 NMT 找到了一个更好的模型,请在下面的回复框中分享!

这篇文章的全部代码可以在 这里 获得。如有任何反馈,欢迎随时联系我 LinkedIn

用 PyTorch 校准神经网络

原文:https://towardsdatascience.com/neural-network-calibration-using-pytorch-c44b7221a61?source=collection_archive---------2-----------------------

用几行代码就能让你的模型适用于安全关键的应用。

UnsplashGreg Shield 拍照

我想你是在这家新的高科技医院工作的放射科医生。上周,你得到了第一个基于神经网络的模型,它可以帮助你根据病人的数据进行诊断,并最终提高诊断的准确性。但是等等!就像我们人类一样,合成模型的预测永远不会 100%准确。但是,我们如何知道一个模型是绝对确定的,还是仅仅超出了猜测的范围呢?这些知识对于正确的解释和选择合适的治疗方法是至关重要的。

假设你更像是一名工程师:这种情况也与自动驾驶高度相关,在自动驾驶中,汽车必须不断做出决定,判断前方是否有障碍。忽略不确定性会很快变得很糟糕。

如果你像 90%的深度学习社区(包括过去的我)一样,你只是假设由 Softmax 函数
产生的预测代表概率,因为它们被整齐地挤压到域[0,1]中。这是一个常见的陷阱,因为这些预测通常过于自信。正如我们将很快看到的,这种行为受到各种架构选择的影响,如批量规范化的使用或层数。

你可以在这里找到一个交互式 Google Colab 笔记本,上面有所有代码。

可靠性图

正如我们现在所知道的,希望输出校准的置信度而不是它们的原始对应物。为了直观地了解特定架构在这方面的表现,经常使用可靠性图表

在 CIFAR10 上训练了 10 个时期的 ResNet101 的可靠性图(图片由作者提供)

用一句话来概括,可靠性图显示了预测的置信度得分与其实际准确性的对比情况。因此,给定 100 个预测,每个预测的置信度为 0.9,如果模型完全校准,我们预计其中 90%是正确的。

为了完全理解正在发生的事情,我们需要更深入一点。从图中可以看出,测试集的所有置信度得分都被分入 M=10 个不同的仓[0,0.1],[0.1,0.2],…,[0.9,1]。对于每个箱,我们可以计算它的精度

信心

然后,这两个值都显示为一个条形图,其中同一条线表示完美校准。

韵律学

图表和情节只是故事的一面。为了根据模型的校准误差对模型进行评分,我们需要定义指标。幸运的是,这里最常用的两个指标都非常直观。

预期校准误差(ECE) 只是对绝对精度/置信度差异进行加权平均。

对于如上所述的安全关键应用,测量精确度和置信度之间的最大差异可能是有用的。这可以通过使用最大校准误差(MCE) 来完成。

温度标度

我们现在想关注如何解决这个问题。虽然存在许多解决方案,如直方图宁滨、 保序回归贝叶斯宁滨分位数(BBQ)普拉特缩放(以及它们对多类问题的相应扩展),但我们希望将重点放在温度缩放。这是因为它是最容易实现的,同时给出了上述其他算法中的最佳结果。

为了充分理解它,我们需要后退一步,看看神经网络的输出。假设一个多类问题,网络的最后一层输出逻辑 z ᵢ ∈ ℝ.然后可以使用 Softmax 函数σ获得预测的概率。

温度缩放直接作用于逻辑 z(而不是预测的概率!!)并使用单一参数 T > 0 对所有类别进行缩放。校准后的置信度可以通过下式获得

值得注意的是,参数 T 是根据验证集的负对数似然(NLL)损失进行优化的,网络参数在此阶段是固定的。

结果

ResNet101 在 CIFAR10 上训练 10 个时期并使用温度标度校准的可靠性图(图片由作者提供)

正如我们从图中看到的,这些条现在更接近身份线,表明几乎完美的校准。我们也可以从指标中看到这一点。经济效率从 2.10%下降到 0.25%,经济效率从 27.27%下降到 3.86%,这是一个巨大的进步。

PyTorch 中的实现

正如承诺的那样,PyTorch 中的实现相当简单。

首先,我们定义在给定特定温度 T逻辑的情况下返回校准置信度的 T_scaling 方法。

在下一步中,必须使用 LBGFS 算法来估计参数 T。这在 GPU 上应该只需要几秒钟。

代码有点类似于 gpleiss 的

欢迎你在我这里创建的 Google Colab 笔记本里玩一玩

结论

如本文所示,只需几行代码就可以完成网络校准,并有很大的改进。如果有足够的兴趣,我很乐意在另一篇 Medium 文章中讨论模型校准的其他方法。如果你有兴趣深入研究这个话题,我强烈推荐郭等人的论文“关于神经网络的校准..

干杯!

基于 Keras 的神经网络校准

原文:https://towardsdatascience.com/neural-network-calibration-with-keras-76fb7c13a55?source=collection_archive---------7-----------------------

在真实场景中调整神经网络概率分数

Unsplash 上由 Lewis Fagg 拍照

概率的概念在机器学习领域很常见。在分类任务中,概率是几乎每个预测模型的输出分数以及相对标签。将它们显示在一起比只提供原始分类报告更能提供信息。通过这种方式,我们使用概率作为置信分数来近似我们的模型预测的不确定性。这是一种常见的做法,反映了我们的推理方式。

问题是我们的算法不够智能,无法以可信的置信度分数的形式提供概率。他们倾向于不校准结果,也就是说,如果我们将结果与预期的准确度进行比较,他们会高估或低估概率。这导致了误导性的可靠性,破坏了我们的决策政策。

在这篇文章中,我们想用概率来处理神经网络校准的问题。正如我们将看到的,建立一个校准的模型不是显而易见的,我们必须在开发过程中小心谨慎。我们操作适当的技术来校准真实分类问题中的分数,以使不会在自动拍卖中被踢,在自动拍卖中,风险是购买一个柠檬

数据

数据集是从 Kaggle 收集的,来自过去的比赛' 不要被踢!’。这个比赛的挑战是预测在拍卖会上购买的汽车是否是一个好东西。当车辆出现严重问题或其他一些不可预见的问题时,经常会导致跳车,给经销商造成很高的成本。我们必须找出哪些汽车被淘汰的风险更高,从而为经销商提供真正的价值。该问题可以作为一个二进制分类任务来进行(好坏买?)。

标签分发

我们可以处理的变量是分类变量和数字变量的混合:

我们操作一个标准的预处理:NaNs 值用中位数(对于数值)和“未知”类(对于分类)填充。然后对数值变量进行标准缩放,对分类变量进行普通编码。

模型

用于预测我们的购买是否划算的模型是一个具有分类嵌入的前馈神经网络。类别嵌入在第二层连接,而在最后部分,我们保持原始输出层(logits)和激活(softmax)之间的分离,用于概率计算。当我们需要校准模型时,这个小技巧会对我们有用。

def get_model(cat_feat, emb_dim=8):

    def get_embed(inp, size, emb_dim, name): emb = Embedding(size, emb_dim)(inp)
        emb = Flatten(name=name)(emb) return emb

    inp_dense = Input(shape=len(num_))

    embs, inps = [], [inp_dense]

    x = Dense(128, activation='relu')(inp_dense)

    for f in cat_feat:
        inp = Input((1,), name=f+'_inp')
        embs.append(get_embed(inp, cat_[f]+1, emb_dim, f))
        inps.append(inp)

    x = Concatenate()([x]+embs)
    x = BatchNormalization()(x)
    x = Dropout(0.3)(x)
    x = Dense(64, activation='relu')(x)
    x = Dropout(0.3)(x)
    x = Dense(32, activation='relu')(x)

    logits = Dense(2, name='logits')(x)
    out = Activation('softmax')(logits)

    model = Model(inps, out)
    model.compile(optimizer='adam', 
                  loss ='categorical_crossentropy', 
                  metrics=[tf.keras.metrics.AUC()])

    return model

我们在训练、验证和测试中分离初始数据集。验证将首先用于网络调谐,然后在第二阶段拟合校准程序的温度标度系数。拟合后,我们在测试数据上实现了 0.90%的精确度,这比将所有汽车分类为好交易的随机模型要好。

神经网络校准

正如我们所看到的,我们的模型可以在看不见的数据上提供良好的性能。但是这个结果有多靠谱?预测校准良好的概率的优点是,如果预测的概率接近 1 或 0,我们可以有信心,否则就不那么有信心。在我们的例子中,如果没有,我们的分类器可能会过度预测类似的汽车为“柠檬”,这可能导致不购买实际上状况良好的汽车的决定。

根据定义,如果对于任何概率值 p,对应于具有 p*100 %精度水平的类别预测,则模型被完美校准。为了检查我们的分类器是否校准良好,我们需要做的就是绘制一个图!同时,产生校准概率非常简单,因为应用了后处理技术。

第一步是绘制可靠性图,在这里我们可以比较预期的准确性和预测的可信度。为方便起见,每个等宽组/箱计算阳性分数和平均预测值。这可以针对二元或多类问题进行计算,并为每个类生成一条曲线。

校准前的可靠性图

最佳情况是当我们在计算的概率和阳性分数之间有一个完美的线性关系时(蓝色虚线)。在我们的例子中,我们的神经网络倾向于分别高估和低估中间两类的概率。我们可以用一个适当的指数来量化校准的好坏,即所谓的预期校准误差(ECE),即预期精度和预测置信度之间差异的加权(每个箱中样本的比例)平均值(越低越好)。

我们可以通过应用一种技术来调整 ECE,这种技术是温度缩放的扩展,称为普拉特缩放。神经网络输出一个称为 logits 的向量。Platt scaling 简单地将 logits 向量除以一个学习到的标量参数 T,,然后将其传递给 softmax 函数以获得类概率。

y_hat 是预测值,z 是逻辑值, T 是学习参数

实际上,只需几行代码,我们就可以构建自己的函数来计算温度比例。比例因子 T 是在预定义的验证集上学习的,其中我们试图最小化平均成本函数(在 tensor flow:TF . nn . soft max _ cross _ entropy _ with _ logits)。输入和输出将分别是我们的逻辑值,用可学习的 T 进行缩放,以及虚拟向量形式的真实输出。列车是用随机梯度下降法经典计算的。

校准后的可靠性图

最后,两个班级的 ECE 分数都有所提高。正如我们在上面新的可靠性图表中看到的,我们可以得到更精确的概率。

摘要

在这篇文章中,我们研究了一种后处理技术来校准我们的神经网络的概率,并在可能的情况下(并非总是温度标度有效),让它成为一种更可信的工具。这是一个非常简单的技巧,适用于任何地方,如果我们关心我们的模型计算决策的概率,这变得很有用。

查看我的 GITHUB 回购

保持联系: Linkedin

参考文献

用于生成面包食谱的神经网络

原文:https://towardsdatascience.com/neural-network-for-generating-bread-recipes-d872e15b1d1c?source=collection_archive---------40-----------------------

面包真的很好吃!

2017 年,一个朋友给了我一些酸面团发酵剂用来做面包,从那以后,我的生活发生了变化。这听起来很俗气,但我发现了一个爱好,它让我一次买了差不多 200 磅面粉(说真的),养成了两周一次的披萨烘焙习惯,并梦想着未来几天我要做什么面包!

左边是我用我的神经网络模型生成的食谱做的一条酸奶面包。右边是分析和预测面包食谱的代码。(图片由作者提供)

因为我花了很多时间烘焙酸面团和试验新配方,所以我想看看我是否可以创建一个人工智能驱动的食谱生成器,它可以预测我要做的东西!我经常去的技术、技巧和诀窍网站之一是面包烘焙论坛 The Fresh Loaf ,在那里人们可以提问和发布食谱。我的想法是抓取这个网站,获取数据来训练神经网络,以生成新的面包食谱——这就是我所做的。在这个项目结束时,我能够实现我的目标:烘烤一条受机器学习启发的面包,用神经网络预测配料。

由于这个项目有多个组成部分,我将在几篇文章中对它们进行分解。第一部分在 Medium 上,其余部分在我的博客上, https://pratima.io. 我为这个项目使用的所有代码都在这个回购中。

我的核桃酸面团面包,附带的内部图片(称为面包屑照片)显示出由于核桃中的单宁而产生的紫色条纹。化学!(图片由作者提供)

项目概述

在这个项目中,我按照以下步骤获得了一个配方生成模型:

  • 首先,我浏览了新鲜面包网站,获得了一份食谱列表,对其进行了清理和可视化,以了解数据集中的趋势(第一部分——你现在正在阅读的内容)
  • 然后,我使用 NLP 工具研究了这些数据,以进一步了解博客上的人们在他们的帖子中说了些什么
  • 最后,我训练了一个神经网络来学习基于单词的语言模型,并从中生成句子来获得新的食谱

在这篇文章中,我将描述该项目的数据收集和数据探索部分。

抓取网站获取数据

我用 python 中的 urllib 库查询网页的网站和美汤解析 HTML 代码。检查新鲜面包上的博客帖子的源代码,我意识到包含食谱的帖子有类node-type-blog,而其他帖子有类似node-type-forum的其他类;所以我确保只抓取以前班级的页面。然后我必须确定包含文本的博客主体在哪里。标签有很多嵌套,对我来说,有点乱,因为我不经常看 HTML 代码。这个类的<div>元素既包含博客文本,也包含评论和广告,但是我只想分离出菜谱。所以我决定在 Beautiful Soup 中使用prettify()函数,并检查结果字符串,看看文本主体在哪里。

import urllib.request as urlib
from bs4 import BeautifulSoupdef get_recipe(page_idx):
  try:
    page_url = f’[http://www.thefreshloaf.com/node/{page_idx}'](http://www.thefreshloaf.com/node/{page_idx}')
    page = urlib.urlopen(page_url)
    soup = BeautifulSoup(page, ‘html.parser’)
    # only process pages that are blog posts, aka contain recipes
    if ‘node-type-blog’ in soup.body[‘class’]:
      print(f’blog at index {page_idx}’)
      soup = soup.prettify()
      soup = soup[soup.find(‘title’):]
      soup = soup[soup.find(‘content=”’)+len(‘content=”’):]
      end = soup.find(‘“‘)
      return preprocess(soup[:end])
  except Exception:
    print(f’Page: [http://www.thefreshloaf.com/node/{page_idx](http://www.thefreshloaf.com/node/{page_idx)} not found!’)

这个字符串中的标记使得找到菜谱主体(包含在内容部分中)变得非常容易,在分离出这个字符串之后,我使用了一个快速预处理函数来去除菜谱文本中的任何 HTML 残余。

def preprocess(text):
  text = text.replace(u’<br/>’, ‘’)
  text = text.replace(‘(<a).*(>).*(</a>)’, ‘’)
  text = text.replace(‘(&amp)’, ‘’)
  text = text.replace(‘(&gt)’, ‘’)
  text = text.replace(‘(&lt)’, ‘’)
  text = text.replace(u’\xa0', ‘ ‘)
  return text

我搜集了大约 10000 个帖子,最后得到了 1257 个食谱,我把它们收集到一个文本文档中,每个食谱都用一个新行隔开。我可以继续搜集更多信息,但在查询了几个小时后,网站停止了响应,所以我决定停下来,从这里了解数据。

数据清理和探索

首先,我将文本文件加载到一个 Jupyter 笔记本上,并计算了每个食谱的长度和独特的单词。在检查数据时,我发现许多作者参考了其他的 url,在那里他们获得了食谱的灵感,我从文本中删除了这些“单词”。我还通过使用 NLTK 语料库删除停用词来标记菜谱。然而,许多作者描述了他们自己的想法和过程,因此在训练语言模型时,删除停用词“我”和“我”会导致语法问题;我在文中保留了这些停用词。

def tokenize(text):
  punctuation_map = str.maketrans(‘’, ‘’, string.punctuation)
  stopwords_list = stopwords.words(‘english’)
  stopwords_list.remove(‘i’)
  stopwords_list.remove(‘me’)
  stopwords_list.append(‘com’)
  stopwords_set = set(stopwords_list)
  text = text.split()
  # remove website links in text
  text = [word for word in text if not (‘http’ in word or ‘www’ in word)]
  text = [word.translate(punctuation_map).lower() for word in text]
  tokenized_words = [word for word in text if word not in stopwords_set]
  return tokenized_words

食谱的平均长度为 294 个单词,标准差为 618。食谱长度差异很大!它们平均还包含 166 个独特的单词,同样具有 174 个单词的高标准偏差。这种高标准偏差表明尾部很大,事实上,在检查数据时,我发现有几个超过 1200 个单词的食谱扭曲了这些统计数据。一个帖子甚至有> 20000 字!

显示配方长度直方图的代码。(图片由作者提供)

为了获得这些食谱文本所包含内容的可视化表示,我基于食谱中的单词创建了一个单词云。这个包在删除停用词后创建了一个顶部术语的图像。不出所料,最常见的词是“面包”、“面团”、“面包”、“时间”和“水”。我想到的其他一些词是“伸展”、“折叠”和“开始”。从我烤面包的经验来看,时间是一个重要的因素,而且它是一个相当频繁的词。我也很高兴看到拉伸和折叠,因为这是一种在面团中发展力量的常见技术,很多人似乎都在使用它!令人惊讶的是,发酵剂出现了,但“酵母”一词却没有出现,因为面包可以用野生酵母发酵剂和标准商业烘焙酵母发酵。似乎新鲜面包的使用者,像我一样,更喜欢用酸面团发酵剂来发酵他们的面包,并哄出有趣的味道,因为它的野性。

字云从菜谱的正文中生成。(图片由作者提供)

从数量上来说,我把所有的单词列了一个长长的清单,并计算了每个单词出现的次数,从而画出了食谱中最常见的 20 个单词。和上面的单词“云”一样,我们在这个常用术语列表中看到了“面团”、“面粉”、“水”和时间单位。

显示食谱中出现的前 20 个单词的频率的直方图。(图片由作者提供)

唷——这么多东西!前往我的网站查看第二部分和第三部分以了解更多关于数据集的信息,以及我如何训练一个告诉我如何制作面包的神经网络:-)

原载于 2020 年 7 月 22 日作者博客

神经网络生成超级英雄标志

原文:https://towardsdatascience.com/neural-network-generating-superhero-logo-c86f931c9cf1?source=collection_archive---------56-----------------------

使用多层感知器创建一个标志,并可视化参数如何影响你的模型

照片由 Teo ZacUnsplash 上拍摄

机器学习是计算机科学领域的超级力量。多亏了推荐系统,我们可以用它来预测未来,通过检测和分类物体让机器人看到东西,或者找到符合我们口味的产品和内容。

当更强大的深度学习方法被发现时,我们获得了能够实现几乎神奇结果的工具。生成看起来像真的一样的人造图像,或者转换风格以生成自己版本的杰作,激发了我们的想象力和创造力。

创造性地使用神经网络刺激我们的动机和学习过程。即使我们有先进的生成模型,也有办法使用简单、经典、多层的神经网络来生成视觉内容,并使用它来描述模型如何工作。所以,让我们发挥创意,制作我们自己的超级英雄标志吧!

数据优先

数据科学模型需要数据的支持。该核心组件定义了模型的行为,是人工大脑的基础。我们自己的超级英雄标志的种子将被编码在传统的二维点阵中。

2D 点网格(作者图片)。

这是我们的训练数据集。它由 627 个点x,y 坐标, 一个标号 。标签有两种类型 01

这些数据代表了什么?我希望我的神经网络经过适当的训练后能给我们看,但我们先介绍一下我们的模型。

船长神经网络

这个想法很简单。我们将使用一个三层神经网络。它由一个输入层和一个将数据点传递给隐藏层的组成。这里我们有神经元具有的激活功能:

乙状结肠激活功能(图片由作者提供)。

隐藏层的神经元有两个权重和一个偏差:

隐层神经元方案(图片由作者提供)。

最后,最后一层将使用隐藏层神经元的输出,并为我们的点生成标签。因为我们只有两个可能的标签 ,所以一个输出神经元 就足够了。

看看我们的模型:

3 层神经网络(图片由作者提供)。

训练任务

有了我们的数据和神经网络模型,我们可以开始训练过程。让我们试试最简单的方法:

  1. 按原样使用数据。
  2. 40 个 隐藏起来的神经元。
  3. 使用范围 (-0.2,0.2) 中接近 0 的随机值初始化神经元权重。
  4. 将每个数据点 呈现 1 000 次(1000 次训练迭代)。

在训练过程之后,我们将要求我们的神经网络为训练集中的每个数据点分配标签。然后我们将使用不同的颜色为标签 01 绘制点。如果模型从我们的数据中学习模式,我们应该看到一个超级英雄标志。

让我们检查一下:

神经网络未能学习模式(图片由作者提供)。

哎呀,看起来不太好。神经网络没有很好地将想法包含在数据中。

根本原因是什么?有几个可能的问题。首先,我们的 数据不是归一化的 。我们为网络提供从 -8.08.0 的坐标。当我们使用 sigmoid 激活函数时,它应该更适合范围 (0,1)内的数据。

然而,看着 均方误差【2】,及其下降趋势我们也可以尝试增加训练迭代的次数:

每次迭代的均方误差(图片由作者提供)。

更多迭代

为了检查网络是否需要更多的时间来学习模式,让我们给它一个机会。让它疯狂地运行 40 000 次迭代,看看会发生什么。

正确分类的训练集(图片由作者提供)。

你能在图片中看到熟悉的东西吗?想想最著名的漫画人物之一。那个很黑,喜欢在晚上工作的人。让我来帮你:

分类训练集和“蝙蝠侠曲线”(图片由作者提供)。

没错,就是蝙蝠侠标志!

蝙蝠侠曲线

我的数据集背后的秘密已经被揭示了。我用这些公式[3]构建了它:

“蝙蝠侠曲线”公式(图片由作者提供)。

我到底是怎么用的?我的代码通过一个小步长 (0.1) 在一个坐标系统中迭代点。如果该点在曲线内,则标记为 1 。否则,点被标记为 0。

神经网络学会了如何区分曲线内的点和曲线外的点,这很好。然而,有两个问题:

  1. 这不是我自己的标志,蝙蝠侠标志已经有人用了。
  2. 神经网络在训练集上表现很好,这不是什么大事。

是时候解决这两个问题了。

测试任务

为了让神经网络生成原始徽标,我将生成第二个点网格。然而,这一次它将是一个真正的厚网格。更何况,每个点都不会被分配标签。

相反,已经训练好的神经网络将被用来为更粗的网格生成标签。这个时间网格由 26 000 个 点组成。给定点不是训练集(627 点)的一部分的概率相当高。

在迭代每个点并获得神经网络预测的标签后,我们可以绘制结果:

由神经网络生成的新标志(图片由作者提供)。

我们拿到了。但是哪个超级英雄会用它呢?飞鼠人?或者更像是象人?我会把它留给你的想象力。

生成徽标的整个过程

让我们总结一下如何生成徽标:

  1. 找到一个模式或公式,它将作为你形象的基础。使用点的坐标作为神经网络的输入。不同区域的不同标签对你的最终形象至关重要。让训练集网格不要那么粗,这样你的神经网络就有了一些空间 在未知领域有创意
  2. 生成一个更粗的网格作为你的测试集。这次不要给这些点贴标签。
  3. 训练你的神经网络。
  4. 使用不同的颜色为测试设定点和标绘点生成不同的标签。
  5. 检查结果。如果不喜欢,就玩玩神经网络参数,看看对最终结果有什么影响。

Octave 代码以及用于运行这些实验的数据可以在这里获得[4]。

看看三个基于 " 蝙蝠侠曲线的 " 标识的例子,通过玩弄神经网络参数生成:

不同神经网络生成的 Logos(图片由作者提供)。

让它有趣

数据科学和学习可能很有趣。通过寻找利用科学的创造性方法,你可以鼓励自己学习更多,并且更好地理解事物是如何工作的。

视觉形式甚至更吸引我们的想象力,因为我们使用不同的感官来获得我们试图完成或学习的大部分事情。欢迎您更改一些神经元、期望误差以及许多其他参数,并立即查看它如何影响最终结果。

记住,权力越大,责任越大。如果你有一个能激发好奇心的想法,不要犹豫,分享它吧!

参考书目:

  1. Joel Grus,数据科学从零开始,第二版,ISBN:978–1492041139
  2. https://en.wikipedia.org/wiki/Mean_squared_error
  3. https://www.desmos.com/calculator/dnzfajfpym
  4. https://github.com/rauluka/mluvr-logo

神经网络+遗传算法+博弈= ❤

原文:https://towardsdatascience.com/neural-network-genetic-algorithm-game-15320b3a44e3?source=collection_archive---------11-----------------------

我就是这样创造了一个完全打败这个游戏的人工智能!

人工智能玩游戏

游戏:规则和移动

首先,我来描述一下这个游戏。你可能已经从 gif 中猜到了,这个游戏的目标是避开红色的栅栏,让绿色的生物向前移动。你走得越远,你的分数就越高。为了让游戏更真实,我实现了重力,这意味着如果生物向上移动,它必须以给定的加速度向下移动。但是它怎么/什么时候跳呢?为了能够跳跃,它必须在地面上。在这个位置,生物可以对地面施加作用力,地面会对其施加反作用力。这种反应会帮助它跳跃(就像我们如何跳跃一样)。这个力的 x 分量将在 x 方向产生一个加速度,y 方向也是如此。

注意:为了简单起见,我没有实现动作-反应机制,而是只处理加速度。当生物在地面上时,它可以决定它的 x 和 y 加速度!

跳跃物理学

挑战是找到这些加速度的值,这样它就可以安全地跳过下一个红色条!需要注意的是,当它在空中时,它不能改变自己的速度(为什么?留给读者)。与地面的碰撞是非弹性的,因此它不会自动反弹。

构建人工智能

有许多方法可以解决这类问题。在这里,我应用了一种叫做神经进化的东西,它是神经网络遗传算法的组合。

一.神经网络

为了能够‘思考’(何时如何跳跃),这种生物需要某种决策模型。在我的方法中,我用一个神经网络作为我们小朋友的大脑。我在输入层使用了一个包含 6 节点的小 nn,在隐藏层使用了 8 ,在输出层使用了 2 。但是在那些 6 输入节点中有什么,在 2 输出节点中有什么呢?我们先来看输出节点。 2 节点决定两个方向的加速度值。正如我之前所说的,这个生物只需要决定它的 x 和 y 加速度。

我们的神经网络的结构显示了输入特征和输出

对于输入节点,可能有许多组可能的特征。目的是向大脑提供尽可能多的关于生物当前状态及其周围环境的信息。我正在使用这 6 条信息(你能想出一套更好的功能吗?)

二。遗传算法

顾名思义,和遗传有关。这是一种进化算法,我们试图模仿生物进化来找到一个给定问题的最优解。我们从一组解决方案开始,从中选择最好的,并让它们发展。不严格地说,每种遗传算法都遵循 5 的步骤。

  • 初始群体:解的初始集合。每个解决方案都有特定的基因(一组参数)决定其行为。基因在个体之间有所不同,这被称为变异

注意:如果初始种群没有变化,那么每个解都会以完全相同的方式进化,我们将无法探索其他解!

  • 适应度函数:一个数学函数,通过给每个解决方案分配一个适应度分数来确定一个解决方案有多适合(最优)。这将有助于下一步。
  • 选择:在这一步,我们选择最适合的个体,让他们把自己的遗传信息传递给下一代。
  • 交叉:结合两个(或更多)父母的基因,产生下一代的一个个体。
  • 突变:当遗传信息从当前一代传递到下一代时,很小比例的信息被随机改变。

注意:由于突变,一些新的特征(属性)将被引入,这将“有希望”使我们的解决方案更加优化。希望如此,因为变异是随机的,也会产生负面影响!

三。神经网络与遗传算法的结合

现在是大揭露的时候了。你会如何结合这两种完全不同的算法?主要思想是将神经网络(大脑)的权重视为基因。最初,我们从一群 250 个 生物开始,每个生物都有自己独立的大脑。为了使群体有变化,我们随机初始化这些神经网络的权重。我们将把最好的砝码传给下一代。你如何决定哪种球更好?我们将使用体能分数。在我的例子中,适应度分数是生物走过的距离的线性函数。所以,走过最远距离的生物有更大的概率创造后代。因此,它们的神经网络的权重将传递给下一代。现在,让我在这里提几个细节…

I)我没有使用交叉的概念,所以一个生物可以不与另一个生物交配而创造它的后代。

ii)创造后代(在这种情况下)意味着复制一个生物神经网络的重量,并在添加一些突变后用前一个生物的重量制造一个新的。

iii)变异只不过是少量随机改变一小部分(一般小于【2%】)权重。

一遍又一遍地做这个过程模仿生物进化,经过许多代,我们希望获得一些具有最佳重量的生物。换句话说,经过许多代之后,我们会有一些小家伙可以决定 x 和 y 加速度的值,这样它就可以跳过下一个红条。在机器学习方面,我们已经成功训练了我们的模型:D

但是我们从来没有使用反向传播!

在传统的深度学习中,我们使用基于梯度的优化技术(也称为反向传播)来训练神经网络。在这种情况下,我们采用最后一层的误差,并将其向后传播,在每一层中,我们计算梯度,并基于此改变相应层的权重。但是在这种情况下(GA+NN)我们不能进行反向投影。为什么?因为我们不能从最后一层计算误差(因为我们不知道地面真相)。我们完全依赖选择和变异来学习。

想看人工智能学习吗?下面是视频…

访问 web 应用程序…

https://suji04.github.io/jumpingameAI/

游戏和人工智能的代码…

https://github.com/Suji04/jumpingameAI

如果你想了解更多关于遗传算法的知识,请查看以下资源:

  • GA上的编码列车播放列表。我用过他的 GA 实现。
  • 进化计算简介作者 A.E. Eiben & J.E. Smith。

我希望你喜欢阅读。下次见…学习愉快!

神经网络:其内部功能和用途

原文:https://towardsdatascience.com/neural-network-its-internal-functioning-and-uses-7adc4d37f3d8?source=collection_archive---------40-----------------------

神经网络试图复制人类大脑及其神经元网络。ANN 人工神经网络由人工神经元或节点组成。人工神经网络主要用于解决人工智能(AI)问题。

当人脑从提供给它的信息中学习时,神经网络也做同样的事情。

神经元之间的连接被建模为权重。正值被称为令人兴奋的连接,而负值意味着避免连接。

一个神经元来源

在神经网络中,工作分两步完成:

1)所有输入乘以一个权重并求和。此活动类似于线性方程,并添加一个偏差作为 b,y=∑xw+b。

2)激活函数被应用于输出,该输出决定该神经元在最终决策中是否将是激活的。例如,可接受的输出范围通常介于 0 和 1 之间,也可能是 1 和 1 或 0 或 1,具体取决于所用的激活函数,可能是 Sigmoid、tanh 或 ReLu。

作者图片

这些人工网络可用于预测建模,在数据集上进行训练。从经验中产生的自我学习可以发生在网络中,这有助于在数据集中看不到的重要问题上得出结论。

神经网络的应用

神经网络用于人工智能的各个领域,例如:

1)用时间序列对金融数据进行预测建模。

2)模式和序列识别中的分类。

3)聚类和过滤。

一个简单的神经网络有一个输入层,隐藏层和输出层。更复杂的神经网络或深层多层网络可以具有大量的隐藏层,在这些隐藏层中,计算具有权重和偏差的输入的乘积的总和,并且在第二步中,关于所使用的函数执行激活。

在这里,我要解释一个 3 隐藏分层网络,前向传播和反向传播。

神经网络中的前向传播

作者图片

在前向传播中,来自每个输入单元的输入被加载一些权重。在每个隐藏神经元层中,完成 2 个步骤:

  1. x1 *w1 +b1,取权重和输入的乘积并加到偏差 b

2)激活功能应用于步骤 1 中的输出。o1=Act(x1 *w1 +b1)。

在隐藏的第 2 层中,输入将从第 1 层输出,即 o1,并且对于上层神经元,它将乘以 w2,对于下层神经元,它将乘以 w3,并且将偏置加到每一个上。

O2 = Act(O1 * w2+B2 ), O3 = Act(O1 * w3+B3)

在隐藏层 3 中,2 个输入将作为 o2 和 o3 到来,它们将分别乘以权重 w5 和 w4 并相加。

o5= Act((o2* w5 + o3*w4) +b4)

y=Act(o5*w6+b5)

考虑到预测值和实际值的简单相减,损失计算为 y-y^。

神经网络中的反向传播

作者图片

我们在神经网络中进行反向传播,以找到更新的权重值,这反过来有助于最小化损失。

这也是一种将反馈传播到神经网络中的方式,以了解每个节点对多少损失负责,并依次更新权重,从而通过给节点更高或更低的权重来最小化损失。

梯度是一种数值计算,它帮助我们知道如何调整网络的参数,以使其输出偏差最小化并达到全局最小值。

作者图片

原始图像来源

用于有效训练一个神经网络的算法是通过链规则。在每次向前通过神经网络之后,反向传播会执行一次向后传递,同时调整模型的权重和偏差。

作者图片

激活功能

在人工神经网络中,节点的输出取决于激活函数,激活函数又根据所用函数的类型使节点开或关、不太活跃或更活跃。

这里我们将讨论几个最常用的激活函数,如 Sigmoid、tanh 和 ReLu。

乙状结肠激活功能

它是一个数学函数,具有典型的“S”形曲线或S 形曲线。sigmoid 函数的一个常见示例是逻辑函数。

公式如图所示。

该函数确保将神经元的输出值保持在 0 到 1 之间。

然而,它的导数范围在 0 到 0.25 之间。

作者图片

该函数可以用作不是很深的神经网络中的激活函数,即其中隐藏层的数量不是很大,因为如果层数更多,将导致消失梯度问题。

消失梯度问题是当等式 w1 new = w1 old-ƞƌl/("ƌw1old 中的(ƞ“ƌl”/("ƌ“w1old))的值很小时,得到的新权重几乎与旧权重相似,因此不进行权重更新。

这导致梯度下降中的值处于相同的位置,不会向全局最小值前进。

下面的等式显示了消失梯度是一个怎样的问题。

作者图片

作者图片

Tanh 激活功能

该激活函数具有与 sigmoid 相似的功能,其公式如下。在此函数中,输出值介于-1 到 1 之间,其导数范围为 0 到 1。

如上所述,它也有消失梯度问题,但它比 Sigmoid 好。

然而,在与非常深的神经网络一起工作时,它也开始出现问题。

作者图片

ReLu 激活功能

在这个函数中,输出的值是 0 或 1,这意味着它或者去激活神经元或者激活它。

它的公式很简单,如下所示。

这没有消失梯度的问题,因为数字是 0 或 1,但它可能会导致死亡的神经元。

作者图片

结论

我希望在读完这篇文章后,关于神经网络,它的工作以及为什么需要这些,很多事情一定是清楚的。

还有最常用的激活函数以及它们的优缺点。

这只是为了让学习者简单起见的一个概述。

感谢阅读!

原载于 2020 年 10 月 30 日 https://www.numpyninja.com

神经网络:为什么越深并不总是越好

原文:https://towardsdatascience.com/neural-network-why-deeper-isnt-always-better-2f862f40e2c4?source=collection_archive---------39-----------------------

一个简单的例子来理解隐藏层如何工作

当创建神经网络时,人们不得不问:需要多少个隐藏层,以及每层需要多少个神经元?

当创建神经网络时,人们不得不问:需要多少个隐藏层,以及每层需要多少个神经元?

当涉及到复杂的真实数据时,吴恩达在 Coursera 的课程中建议: 改进深度神经网络 ,这是一个高度迭代的过程,因此我们必须运行许多测试来找到最佳的超参数。

但是,隐藏层神经元如何影响最终模型背后的直觉是什么?

照片由 Moritz KindlerUnsplash 拍摄

简单非线性可分数据

让我们使用 make_circles 创建一个数据集。

from sklearn import datasetsX,y=datasets.make_circles(n_samples=200,shuffle=True, noise=0.1,random_state=None, factor=0.1)

你可以将数据集可视化:

import matplotlib.pyplot as plt
plt.scatter(X[:, 0], X[:, 1], c=y,s=20)
plt.axis(‘equal’)

作者图片

有多少神经元和层数?

每个神经元创建一个线性决策边界。通过查看数据集,直觉是创建一个由 3 个神经元组成的层。我们应该能够创建一个完美的分类器。现在,如果只有两个神经元呢?这似乎还不够,如果我们尝试添加更多的层呢?

带着这些问题,我们试着做一些测试。

一个隐藏层中有 3 个神经元

如果我们使用 3 个神经元,代码如下:

from sklearn.neural_network import MLPClassifierclf =MLPClassifier(solver=’lbfgs’,hidden_layer_sizes(3,),
activation=”tanh”,max_iter=1000)clf.fit(X, y)
clf.score(X,y)

然后,我们能够在隐藏层内创建 3 个决策边界。并且我们可以注意到,创建这 3 条线有无限多种可能性(所以在这个神经网络的代价函数中有无限多种全局最小值)。

作者图片

为了创建隐藏层的决策边界的可视化,我们可以使用隐藏层的系数和截距。

n_neurons=3xdecseq=np.repeat(np.linspace(-1,1,100),n_neurons).reshape(-1,n_neurons)ydecseq=-(xdecseq*clf.coefs_[0][0]+clf.intercepts_[0])/clf.coefs_[0][1]

然后我们可以用原始数据集绘制这三条线:

fig, ax = plt.subplots(figsize=(8,8))ax.scatter(X[:, 0], X[:, 1], c=y,s=20)ax.plot(xdecseq[:, 0], ydecseq[:, 0])
ax.plot(xdecseq[:, 1], ydecseq[:, 1])
ax.plot(xdecseq[:, 2], ydecseq[:, 2])ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5, 1.5)

一个隐藏层中的两个神经元

如果我们只使用 2 个神经元,很容易看出我们将不能完美地对所有观察结果进行分类。

使用类似的代码,我们可以绘制出下图,其中包含隐藏层的两个决策边界。

作者图片

2 个神经元,每个神经元有许多层

如果我们在许多隐藏层中创建 2 个神经元会怎么样?为了更好地理解在第一个有 2 个神经元的隐藏层中发生了什么,我创建了这个可视化。

作者图片

很明显,无论你添加多少层,你都无法对下面红圈里的数据进行分类。

作者图片

可以自测一下:可以在参数 hidden_layer_sizes 中添加更多的图层。例如,( 2,3,2)表示 3 个隐藏层,每个层有 2、3 和 2 个神经元。

from sklearn.neural_network import MLPClassifierclf = MLPClassifier(solver=’lbfgs’,
hidden_layer_sizes=(2,3,2),
activation=”tanh”,max_iter=1000)clf.fit(X, y)
clf.score(X,y)

结论

从这个简单的例子中,我们可以用这个直觉来结束:

  • 第一个隐藏层中神经元的数量创建尽可能多的线性决策边界来对原始数据进行分类。
  • 如果第一层不包含必要数量的神经元,那么(理论上)创建更深的神经网络是没有帮助的。

如果想看其他动画了解神经网络是如何工作的,也可以看看这篇文章。

[## 神经网络转换数据的动画

我们可以对神经网络为什么以及如何工作有更好的直觉

towardsdatascience.com](/animations-of-neural-networks-transforming-data-42005e8fffd9)

神经网络和疟疾

原文:https://towardsdatascience.com/neural-networks-and-malaria-520a5b7fb6ed?source=collection_archive---------91-----------------------

生殖敌对网络和蚊子有什么关系

学分像素海湾

本文在简要回顾了疟疾和生殖神经网络(GANs)之后。我们深入研究了神经网络在血液涂片中检测疟疾疟原虫的可能应用,以及如何使用 GANs 生成用于人类训练和数据增强的合成血液涂片图像。特别地,所使用的架构的细节被讨论为上采样和 TensorLayer 的使用,而不是 Keras。

今年的特点是新冠肺炎和疫情。然而,在南半球疟疾造成的死亡人数超过了新冠肺炎,即使它没有造成死亡,它也代表着人们在失去工作天数或其他机会方面的负担(世卫组织 2018–2020)。

疟疾 是一种蚊子传播的疾病,如果不治疗,会导致发烧、疲劳、头痛,最终死亡。根除疟疾在一些国家已经成为可能,但在大多数低收入国家却很麻烦。可以比喻为一个人减肥。不存在一个普遍的模式,每个国家都有自己的问题,由于基础设施、环境和其他因素,在一个国家行得通的方法在另一个国家可能行不通。在应对疟疾的方法中,早期诊断发挥着关键作用。最常见的诊断方法仍然是显微镜检查,这仅限于研究者的经验,研究者之间的协变性也是存在的( Zimmerman et al. 2015 )。其他方法有快速检测(RDT)和聚合酶链反应(PCR)。RDT 价格低廉,但当寄生虫数量高于 50,000–200,000/mL 全血时,可以检测出疾病。基于 PCR 的测试是最准确的,因为它们甚至可以在血液中少于 1000 个寄生虫/mL 的情况下诊断病情,但是它需要非常有经验的人员。因此,在低收入国家,主要的实际应用仍然是显微镜血液涂片分析。血液涂片是通过在手指上切一个小口,然后在载玻片上使用染色剂来表征疟原虫的存在而获得的。涂片也可以是“厚的”或“薄的”,这取决于血滴是否在载玻片上扩散。厚血涂片主要用于检测寄生虫的存在,因为它们检查更大的血液样本。血液在载玻片上扩散的薄涂片允许分析更少的血液,但导致更高的准确性,并允许区分寄生虫菌株。

深度学习在组织病理学图像分析中的应用正在彻底改变该领域,通过以高准确度评估疾病进展,提供在从癌症分析到免疫疾病( Niazi et al. 2019) 的多个领域中有效的定量模型。此外,人们相信人工智能将把数字病理学扩展到远远超出今天可能达到的程度。关于疟疾和光幕显微术,过去已经有了几种方法。一般来说,他们专注于背景-前景减法、特征提取,以及通过支持向量机(SVM)或随机森林( Das et al. 2013 )的进一步分类。在深度学习时代,已经研究了几种架构(董等 2017)

事实上,如下所示,通过使用深度学习库,如 Tensorflow 和重新训练的 VGG,即使只使用 10 个样本进行训练,也有可能获得 0.9 的曲线下面积的良好结果:

来自 Makere 大学的厚涂片图像,由 Rija Ramarolahy 分割(参见 Ramarolahy 和克里米)

生成式广告网络是一种特殊的架构,它可以生成数据,而不仅仅是对数据进行分类。解释它们最简单的方法是考虑两个相互竞争的系统:一个发生器和一个鉴别器。他们可以被看作是骗子印刷假币和银行职员检查验证货币,前者试图创造最真实的假币,后者更善于区分假币和真币。GANs 架构已经达到了令人难以置信的精确水平(瓦罐肯定会赢)。下图显示了名为 BigGAN 的 GAN 架构的结果,该架构的初始得分(IS)为 166.3。

比根生成的合成图片

在病理学中使用 GANs 的动机是与数据扩充相关的两个主要因素:1)为病理学家学习研究中图像的可能变化提供可变性,2)允许更好的迁移学习以增加更多图像。因此,一个完整的深度学习工具应该包括鉴别器和生成器部分,以使鉴别器也受益( van Eyke et al. 2019 )。

我们使用传统的深度卷积架构如下。

典型的 DCGAN 架构【https://arxiv.org/abs/1511.06434

这些是生成器的 1000 次迭代,创建与顶部真实图像相似的图像(输出 256x256 像素)

我们遇到了 GAN 生成图像的典型困难。首先,由于鉴别器的收敛速度比发生器快,通常很难产生真实的图像。一种解决方案是给出较小的学习率,例如(学习率鉴别器 0.00001 和生成器 0.0002),替代的技巧包括使用软标签来促进生成器的收敛。

一个更重要的细节是如何执行扩展步骤,因为可能会出现典型的棋盘伪影。所采用的解决方案是简单地切换出标准去卷积层,用于最近邻尺寸调整,随后卷积导致不同频率的伪像消失(萨利曼等人,2016 )。

这些视频展示了使用 GAN 的结果

去卷积(上)和最近邻调整大小(下)生成一个受疟疾疟原虫感染的单细胞。最近邻调整大小在质量上有明显的影响。

此外,建议的架构是使用 TensorLayer 作为 Keras 的替代方案来实现的。Keras 是一个构建在 Theano 或 TensorFlow 之上的高级库。关键思想是通过快速原型化来促进实验,而不特别偏好特定的库,它被认为是 TensorFlow 的可靠抽象。因此,Keras 可能是最容易的选择。然而,Keras 在 TensorFlow 后端相对较低的性能不时被其用户提及,这可能与 Keras 最初为 Theano 设计有关。

因此,TensorLayer 与最近(2016 年)发布的 Keras 相比更加透明,因为它是直接为 TensorFlow 构建的,但目前其社区相对较小。下面显示了使用 TensorLayer 的代码片段

完整使用的代码可在https://github . com/Alec rimi/malaria _ detection _ and _ generation上获得

总之,数字病理学是一个新兴领域,它强烈使用深度学习和人工神经网络来检测血液涂片中的疟原虫。在这篇文章中,还显示了 GANs 可用于生成看起来逼真的合成感染血液涂片,并可用于增加关于病原体如何不同地出现的人类训练,以及用于进一步数据分析的数据扩充。此外,将来 GANs 可能会教给我们一些我们从组织学/病理学中所不知道的东西。我们正在努力使低收入国家也能获得这种服务。这是一个视频演示:

想连接就连接

@ Dr _ Alex _ 克里米

@阿列克里米博士

https://www.linkedin.com/in/alecrimi/

神经网络和通用逼近定理

原文:https://towardsdatascience.com/neural-networks-and-the-universal-approximation-theorem-8a389a33d30a?source=collection_archive---------6-----------------------

以及最近深度神经网络的繁荣

Alex Kotliarskyi 在 Unsplash 上的照片

神经网络的概念已经存在了几十年。为什么要花这么长时间来加快步伐?神经网络和深度学习创造的这种突然繁荣是什么?是什么让神经网络如此值得炒作?我们来探索一下。

神经网络的架构

为了得到什么是神经网络的简要概述,神经网络仅仅是神经元(也称为激活)的集合,这些神经元通过不同的层连接。在提供训练集的情况下,它试图学习输入数据到输出数据的映射。

神经网络的 训练 之后便于其对同一分布的测试数据进行预测。这种映射是通过分布在不同层上的一组称为 权重 的可训练参数来实现的。权重是由目的是最小化损失函数的反向传播算法学习的。损失函数测量网络所做的预测与实际值有多远。神经网络中的每一层后面都有一个激活层,它对神经元执行一些额外的操作。**

通用逼近定理

从数学上讲,任何神经网络架构都是以寻找任何能够将属性(x)映射到输出(y)的数学函数 y= f(x)为目标。该函数(即映射)的准确性取决于数据集的分布和所采用的网络架构。函数 f(x)可以是任意复杂的。普适逼近定理告诉我们,神经网络有一种 普适性 即无论 f(x)是什么,都有一个网络可以近似逼近结果并完成工作!这个结果适用于任何数量的输入和输出。

图像来源

如果我们观察上面的神经网络,考虑到作为身高和宽度提供的输入属性,我们的工作就是预测这个人的性别。如果我们从上述网络中排除所有激活层,我们认识到 h₁是重量和高度与参数 w₁、w₂和偏差项 b₁.的线性函数因此从数学上来说,

h₁ = w₁weight + w₂height + b₁

类似地,

h2 = w₃weight + w₄height + b₂

沿着这些思路,我们认识到 o1 也是 h₁和 h2 的线性函数,因此也线性依赖于输入属性体重和身高。这本质上归结为一个线性回归模型。一个线性函数足以逼近通用逼近定理吗?答案是否定的。这就是激活层发挥作用的地方。

激活层紧接在神经网络中的线性层之后,以提供非线性。非线性有助于神经网络执行更复杂的任务。激活层对激活(h₁,在这种情况下是 h2)进行操作,并根据为该特定激活层提供的激活函数修改它们。激活函数通常是非线性的,除了身份函数。一些常用的激活函数有 ReLusigmoidsoftmax 等。随着非线性和线性项的引入,对于神经网络来说,在这种情况下,在具有适当的 parameters(w₁、w₂、b₁等的基础上近似地模拟任何给定的函数成为可能。参数适当地收敛到适当性。你可以从这里更好地了解数学上的通用逼近定理。

神经网络具有映射复杂函数的能力,并且永远是纸上谈兵。是什么让它突然成了机器学习的神童?

繁荣

最近对深度学习模型的兴趣爆发归功于当今世界提供的高计算资源和丰富的数据。深度神经网络是数据饥渴模型。这种繁荣也主要归功于普通人手中的廉价高速计算。这种前所未有的数据增长和计算能力几乎在生活的所有领域创造了奇迹。

深度学习模型被坚定地认为可以自动从原始数据中提取特征,这一概念也被称为特征学习。无论你向一个足够大和足够深的神经网络输入什么,它都可以学习隐藏的特征和属性之间的关系,然后利用这些关系来预测结果。这非常方便,只需要最少的数据预处理。与此同时,用于设计和构建这些数据驱动模型的工具和框架(PyTorch、Tensorflow、Theano)与日俱增,水平相当高,并且很容易获得。它们要求对编程语言有一个微不足道的低级理解。最重要的是,顶级公司的研究证明,这个领域确实值得花费宝贵的时间和金钱。

用数据缩放的模型

深度学习模型确实可以随着数据进行扩展,这一点备受好评。这表明,随着数据的增加和采用更大的模型,结果几乎总是会变得更好。这些更大的模型需要更多的计算来训练。随着如今易于访问的有益计算环境的出现,实时实验和改进算法和架构变得更加容易,从而在短时间内产生越来越好的实践。也就是说,深度神经网络在许多领域都有广泛的应用,如计算机视觉、自然语言处理、推荐系统等等。各种跨领域的应用程序最近也加快了步伐。

2019 年 10 月,谷歌公布了其 54 量子位处理器“Sycamore”的量子优势实验结果。量子计算机在 200 秒内完成目标计算,这对世界上最快的超级计算机来说需要大约 1 万年。随着计算能力的日益增长,不知道机器学习何时会超越超人的界限。人们只能推测。

神经网络不会像你认为的那样进行归纳

原文:https://towardsdatascience.com/neural-networks-dont-generalize-the-way-you-think-they-do-de520bed2053?source=collection_archive---------21-----------------------

来源: Unsplash

彩票假说

神经网络是如何学习的?

或者,更具体地说:

神经网络究竟是如何对如此多的参数进行归纳的?

这是一个很好——看似简单——但大多数人都认为理所当然的问题。一个简单的神经网络可以有几千到几万个参数。每个额外的参数提供了额外的自由度,极大地增加了搜索空间。

除了必要的以外,我们不应该增加解释任何事物所需的实体的数量。

众所周知——也是直觉——添加更多的参数可以让模型进一步记住数据点,而不是找到概括。有这么多参数,在数据集上训练的神经网络肯定会采取简单的方法,而不是学习。

人们可能会认为,对于完全随机的标签,一般化的算法会花费更多的时间或更少的成功(想象一下,如果你被告知学习识别带有完全随机标签的图像)。

令人惊讶的是,事实并非如此。

在这篇论文的中,研究人员证明了神经网络可以在完全随机的标签上获得完美的训练分数——而所需的训练时间相同。如果它愿意,神经网络(一个标准的初始架构)可以存储整个数据集(所有的 CIFAR-10)。

a)在各种实验设置上的性能,如随机标签、混洗像素、添加高斯噪声等。b)显示了不同标签损坏率的相对收敛时间。c)具有不同标签损坏率的测试误差(一般化误差,因为测试误差为 0)。来源:张等

不知何故,神经网络在训练集和测试集中产生非常相似的结果。有一个标准的答案:以辍学或 L1/L2 的形式出现的正规化提高了普遍性。

由张等人进行的上述相同研究表明,通过常用方法(如数据扩充、权重衰减和剔除)进行的明确调节并不能减少泛化误差。

在下面的示例中,初始模型是在 CIFAR-10 数据集上训练的,正则化(特别是随机作物数据扩充)有助于提高准确性,但提高幅度不大。

来源:张等

如果是这样的话——没有正则化的模型并不比正则化的模型表现差多少——我们怎么能说正则化是泛化的基础呢?

此外,如果不是,那么神经网络是如何学习的?

一个答案可能来自神经网络修剪。

随着深度学习变得更加实用,神经网络修剪越来越受到关注。神经网络的大小可以减少五分之五,预测时间减少三分之二,精确度下降 1.2%(此处为)。在更多的工程设计下,有可能移除更多的网络——90%甚至 99%——而不会遭受性能损失。

如果网络的绝大部分贡献了性能增益的一小部分,那么它到底在做什么?监控任何神经网络的权重将显示它们不仅仅是被动的——它们几乎总是异常活跃。

一个答案是彩票假说,它指出:

一个随机初始化的密集神经网络包含一个子网络,该子网络被初始化为当被隔离训练时,它可以在最多相同次数的迭代训练后匹配原始网络的测试精度。

换句话说,神经网络是一个巨大的包裹,里面有微小的产品和大量的填充物。绝大部分价值存在于网络的一小部分——子网中。这篇论文的作者将这些子网称为赢得“初始化彩票”的“中奖彩票”:它们的初始权重值正确,可以促进重要的增长。

然后,解释神经网络如何概括的一种方法是,实际的预测内容占用非常小的空间,但较大的神经网络运行较大的初始化彩票,找到强大子网的机会较高。

也许最重要的问题是:当我们知道神经网络足够好的时候,我们为什么要关心它们为什么要学习呢?

最明显的是,如果我们错误地将神经网络的过度参数化归因于更多的能力,我们正在占用比实际需要多得多的计算能力。如果更大的网络只是为了运行大型初始化实验,显然有更有效的方法来完成这项任务。

神经网络已经被接受为黑盒算法,只是工作时间太长了。如果理解了神经网络的工作方式和原因,深度学习的研究,特别是架构的构建和进一步开发,将会大大加快。

令人惊讶的是,从传统统计学习理论的角度来看,DNNs 在实践中推广得非常好,即使没有显式的正则化。这就提出了一个合适的框架来理解 DNNs 的一般化的问题。
——深度学习中带参数个数的泛化的标度描述,盖格等

在神经网络中,过度拟合的迹象,如训练精度为 100%,可能伴随着类似的高测试精度。这违背了经典机器学习的基本法则。

最近的论文如本文探索了高度参数化模型表现不同的可能性,以及我们需要在深度学习中以不同的方式处理泛化和学习的概念。

偏差-方差权衡只是故事的一部分吗?来源:贝尔金等人。图片免费分享。

即使围绕深度学习有这么多令人兴奋和慌乱的研究,但它在学习方面的成功并没有普遍的理论,而不仅仅是在建模方面(这可以用通用逼近定理来解释)。然而,彩票假说是理解这一点的重要一步。

神经网络集成

原文:https://towardsdatascience.com/neural-networks-ensemble-33f33bea7df3?source=collection_archive---------10-----------------------

结合深度学习模型的不同方法

诺亚·罗森菲尔德在 Unsplash 上的照片

集合的概念在机器学习中很常见。不同的算法建立在这个机制上。仅举最著名的例子,随机森林用来组合可变数量的决策树。一般来说,集成可以被认为是一种学习技术,其中许多模型被结合起来解决一个问题。这样做是因为集成往往比单个执行得更好,提高了泛化能力。

合奏的方式没有任何限制。考虑的模型的数量和类型也是如此。要记住的习惯是选择低偏差和高方差的元件。这是可能的,只需选择具有多样化结构和格式的模型。

在这篇文章中,我们将集成机制应用于神经网络领域。更准确地说,我们提出了有效组合深度学习结构的各种方法。我们在图像分类领域举了一个例子,在这个领域中经常会遇到非常深的模型。同样的推理和过程也可以很容易地翻译成其他应用程序。

数据

我们从 Kaggle 收集数据。垃圾分类数据集包含 6 种分类:纸板、玻璃、金属、纸张、塑料和垃圾。还提供了对训练、验证和测试的划分。

每个班级的数据样本

我们的目标是尝试按照神经网络集成方法对我们的图像进行正确分类。更详细地说,我们提出 3 种不同的方法。我们所有的方法都遵循相同的结构,如下图所示。

有 N 个网络分类器,它们以不同的方式组合在顶部。在这个例子中,我们选择 3 个不同的分类器进行集成。它们是在不同数据集上预先训练的模型,但我们在任务中会重复使用它们。众所周知,这是图像分类领域的一种常见方法,其中大型模型适用于非常庞大的数据集,以便冻结它们的知识并将其重新导入其他场景。迁移学习的优点正是在正确的方向上初始化我们的新训练,适应先前学习的信息以获得更好的结果。这可以对我们的特定数据进行微调。在我们的上下文中,当我们合并 N 个系综组件时,我们对它们应用微调来操作系综。

在提出的所有方法中,我们使用 VGG16、VGG19 和 RESNET50 作为基本模型来操作系综。我们对它们进行微调,允许在它们各自的最后卷积块上进行重新训练。集合在 2D 维度上操作。我们从 3D 过渡到 2D 经营全球联营。对于通过具有固定维数的密集层中的汇集输出的所有网络,维数是相等的。

拼接系综

串联是合并不同数据源的最常见技术。串联系综接收不同的输入,不管它们的维度是什么,并且在给定的轴上串联它们。并排附加信息的缺点可能是维数爆炸。系综中的网络越多或越大,密集维度就越大,连接的输出就越大。这种操作可能是分散的,不允许网络的最后部分学习重要信息或导致过拟合。

我们的串联系综在测试数据上达到了 89%的准确率。

平均系综

平均系综可以被视为级联操作的相反。我们网络的汇集输出通过具有固定数量神经元的密集层,以使它们均衡。这样,我们可以计算平均值。结果是输出共享每个输入的相同维度,但这是它们的平均值。可以直观地理解,这种方法的缺点是平均运算的性质会导致信息丢失。

我们的平均系综在测试数据上达到了 89%的准确率。

加权系综

加权系综是一种特殊形式的平均运算,其中张量输出乘以权重,然后线性组合。来自我们模型的每个输入都被赋予一个权重。这些权重决定了每个模型对最终结果的贡献。特殊性在于这些权重不是固定的,也不是预先设定的,但是它们的值可以在训练过程中进行优化。唯一的约束是权重的总和必须为 1,但这很容易通过对它们应用 softmax 来实现。利用这种类型的集成,我们还可以通过提取集成权重来检索每个模型的贡献。

我们的加权集成在测试数据上达到了 89%的准确率。

摘要

在这篇文章中,我们介绍了一些类型的神经网络集成技术。最大的潜力是可以很容易地用其他操作来扩展它们。我们还将它们应用于分类问题的大型模型,但是没有什么可以阻止我们将它们应用于我们的定制模型场景中。我们还在微调操作过程中开发系综,但此处程序也可分为子任务。所有这些方法的最大好处是增加多样化,以便建立能够更好地概括的模型。

查看我的 GITHUB 回购

保持联系: Linkedin

神经网络:你想知道的一切

原文:https://towardsdatascience.com/neural-networks-everything-you-wanted-to-know-327b78b730ab?source=collection_archive---------23-----------------------

学习深度学习模型核心背后的数学!

图片来自 Unsplash

介绍

这篇文章的目标是:

  • 简要介绍什么是神经网络以及它们是如何工作的
  • 对他们如何学习做出详细的数学解释

神经网络

一般来说,神经网络是一种逼近函数的方法。遵循通用近似定理:

具有单个隐藏层的神经网络足以表示给定值范围内的任何函数,尽管隐藏层可能太大以至于不可能实现或者不可能找到适当的权重。

如果我们考虑到正常情况下你能想到的任何问题都可以以数学函数的形式分解和建模,根据这个定理,神经网络应该可以解决任何问题,对吗?

神经网络有两个主要限制:

  • 它们只能逼近连续函数
  • 并且在一定的数值范围内

粗略地说,有了神经网络,我们可以检测模式,并用它们来解决问题。此外,通过深度神经网络,我们可以转换数据空间,直到我们找到一种有助于实现所需任务的表示。

他们将执行类似于下图所示的操作:

按作者分列的数字

基本上,它们将输入数据转换为其他空间表示,以便能够以更简单的方式区分它。

下面的例子很有代表性:

如果我们试图用线性分类器来解决以下数据集的分类问题,这将非常困难,因为数据点不是线性可分的。

按作者分列的数字

我们将获得类似于以下内容的内容:

按作者分列的数字

但正如我们所看到的,它并不太好。你想看看神经网络的能力吗?

按作者分列的数字

这看起来好多了。)

神经网络不能做的事情

神经网络不能给出问题的精确解。例如,神经网络很难实现简单的乘法运算。

  • 首先,因为我们需要它的精确值。
  • 第二,因为我们之前说过,它们能够在给定的范围内逼近函数。乘法需要[-inf,+inf]的范围。

此外,他们也不能“思考”。他们只是非常强大的模式检测器,给人以智能的感觉,但他们没有。我们必须自己提供情报。

我们还必须考虑到,虽然它们非常有用,因为它们解决了迄今为止对计算机来说非常复杂的问题,例如检测不同类型的狗品种或交通标志,但很难从中提取知识。

换句话说,他们有能力做我们要求他们做的事情,但是很难发现他们到底是怎么做的。

神经网络是如何学习的?

基本上,神经网络的学习过程类似于人类的学习。他们通过重复学习。

他们看到一些东西,猜测是什么,其他代理告诉他们是否正确。如果他们错了,他们会调整自己的知识,避免重蹈覆辙。

让我们看一个具体的例子

你可能知道,神经网络是由层组成的,而层又是由神经元组成的。

在这个链接中可以看到完整的例子:https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

在下图中,我们可以看到一个前馈型网络,其 iput 层由 2 个神经元组成,隐藏层由 2 个神经元组成,输出层由另外 2 个神经元组成。另外,隐藏层和输出层也有偏差。

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

还有很多架构,但这是最常用的一种。在这种类型的架构中,I 层的每个神经元都与 i+1 层的所有神经元相连接。

也就是说,一层的神经元只允许连接到下一层的神经元。这些类型的层被称为密集层或全连接层。

为了简单起见,让我们假设我们的训练集只由 1 个元素组成:0.05,0.1,这是 1 类(如果神经元 o1 的概率大于神经元 o2 的概率,则可能是 0 类,或者如果相反,则可能是 1 类)。

在下图中,您可以看到具有随机初始化的权重、输入的训练集元素和所需输出的网络:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

一旦我们的神经网络被定义并准备好接受训练,我们就来关注它们是如何学习的。

两种最常见的学习方法是:

  • 前进传球
  • 反向传播

前进传球

它包括用当前权重值计算网络的输出。为此,我们向网络输入我们的训练元素。

但是,首先,让我们看看神经元到底是怎样的:

https://towards data science . com/complete-guide-of-activation-functions-34076 e95d 044

其中 fn_activation 是选择的 activation 函数。一些最流行的激活功能有:

https://towards data science . com/complete-guide-of-activation-functions-34076 e95d 044

人工神经网络和真正的神经网络相似吗?

人工神经网络是受人脑的启发。事实上,我们有大约 100 亿个神经元,每个神经元都与其他 10,000 个神经元相互连接。

https://training . seer . cancer . gov/anatomy/neural/tissue . html

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

神经元的身体称为胞体,入口称为树突,出口称为轴突。大脑的神奇之处在于一些树突与其他神经元轴突的成千上万个连接。

其工作方式是,每个神经元通过其轴突(输出)和受体的树突(输入)接收来自其他神经元的电化学脉冲。

如果这些脉冲强到足以激活神经元,那么这个神经元就会将脉冲传递给它的连接。通过这样做,每个连接的神经元再次检查从树突到达细胞体的冲动(在我们之前的例子中为 inh1 )是否足够强,以激活神经元( fn_activation 负责检查这一点)并扩展更多的神经元。

考虑到这种操作模式,我们意识到神经元真的就像一个开关:要么传递信息,要么不传递。

神经网络不是基于它们的生物伙伴,而是受到它们的启发。

正向和反向传播

现在,我们将了解网络如何计算输出 outh1。

再看一下网络:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

图像

为了计算 o1 和 o2,我们需要:

对于第一层,即隐藏层:

对于最后一层,输出层:

其中: o1 = outo1o2 = outo2。

所以我们需要计算:

现在,要获得 outh1 和 outh2,我们需要应用 fn_activation。在这种情况下,我们选择物流功能作为激活功能:

所以:

让我们看看我们在输出计算过程中的情况:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

我们现在只需要计算 o1 和 o2:

因此,应用激活函数:

终于!我们已经计算出我们的神经网络预测!但是坚持住,我们的预测太可怕了!他们不像 0.01 和 0.99 期望!我们如何解决这个问题?

不如我们计算一下总误差,尽量把它减到最小?事实上,这正是反向传播算法所做的:它根据每个权重对总误差的影响程度来更新权重,以便最小化总误差

让我们计算总误差:

请注意,outo2 误差比 outo1 误差小得多。这是因为 0.7729 比 0.01 的 0.7514 更接近 0.99,所以参与 outo1 计算的神经元的变化应该比 outo2 更大。

我们如何根据影响总误差的因素来更新权重?很简单,只需计算给定重量的变化对总误差的影响,并根据这种关系进行更新。

例如,你能想出一种方法来计算权重 w5 对总误差的影响有多大吗?换句话说,w5 权重的变化对总误差的影响有多大?这听起来不耳熟吗?

我们说的是衍生品!看,我们可以把每个神经元理解为一个函数,应用链式法则,从总误差得到 w5 权重。但首先,你还记得链式法则是如何运作的吗?

让我们看一个例子:假设我们想对函数求导:

换句话说,我们想知道 x 变量的变化对 y 变量的影响有多大。

我们可以把这个函数理解为其他两个函数的组合,其中:

现在,我们需要分别对 x 求导 y 。为此,我们需要首先相对于 uy 求导,然后相对于 xu 求导。

在我们的例子中:

这就是应用的链式法则。现在让我们把它看成一个图表:

想象每个圆都是函数,每个箭头都是乘法。然后,利用链式法则,我们可以写出:

现在,让我们看看如何写出计算 Etotal 相对于权重 w5 如何变化的公式。

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

正如开膛手杰克所说:让我们去寻找零件。总误差定义为:

正如我们所见,w5 只影响 o1 神经元,所以我们只关心使我们的 Etotal = Eo1 的 Eo1

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

因此,我们可以将 w5 权重与 resepct to Etotal 的方差定义为:

太好了!让我们看下一个术语:

这可以表示为:

及其衍生物:

最后两步是可能的,因为逻辑函数的导数是一个偶函数,即 f(x)=f(-x)

好吧,让我们回到正题。我们已经有了导数,所以现在我们要计算它的值:

我们已经有了第一项和第二项,我们只需要计算突出显示的项就可以得到 w5 :

如果我们回忆一下,01 年的是:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

如果我们看一下 o1 神经元的输入,我们可以直接计算 in01 公式:

现在,我们能够计算我们的期限;

终于!我们已经有了所有必要的术语来了解 w5 对 Etotal 的影响程度:

我们已经知道如何计算第二层和 terera(隐藏和退出)影响之间的权重。但是…我们如何发现第一层和第二层(入口和出口)之间的权重有什么影响呢?

很简单,和我们之前做的一样!

我们首先需要定义的是什么?

Etotal 相对于重量 w1 的导数。这是怎么定义的?

这里是网络:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

让我们将神经网络解构为神经元:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

现在,我们有两条路可走:

因此,我们需要计算对应于 1 和 2 神经元的误差:

这意味着我们现在有两个影响权重 w1 的误差源,即 Eo1 和 Eo2。各自是如何定义的?很简单,如果我们在网络图中从 Eo1 走到权重 w1,我们会发现的第一个元素是什么?outo1,对吧?

有了它,我们已经不得不:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

让我们求解到 Eo1:

现在我们有了 Eo1 相对于 w1 的变化量。但是我们缺少一些东西,如果我们再看看神经网络:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

我们还需要对应于第二个神经元的误差, Eo2 。有了这个误差,我们就可以计算出重量 w1 对总量的影响有多大,这就是我们感兴趣的:

对每个权重重复这一过程,我们就可以对权重应用梯度下降,从而更新权重,参见:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

其中 η 是学习率,表示我们在梯度的反方向要走多大的一步。

最后的话

一如既往,我希望你喜欢这篇文章,你已经了解了神经网络以及它们如何利用数学来学习自己!

如果你喜欢这篇文章,那么你可以看看我关于数据科学和机器学习的其他文章 这里

如果你想了解更多关于机器学习、数据科学和人工智能的知识 请在 Medium 上关注我,敬请关注我的下一篇帖子!

神经网络:弗兰克尔的奇迹

原文:https://towardsdatascience.com/neural-networks-frankles-miracle-dfbd031ae1be?source=collection_archive---------59-----------------------

~ 最新的剪枝协议是一个万亿美元的火箭~

亚历克斯·霍利奥克Unsplash 上拍摄的照片

TL;凭借彩票成名的博士乔纳森·弗兰克尔和迈克尔·卡宾,以及亚历克斯·伦达,已经做出了 完美的修枝剪 ,尽你所能地缩小神经网络,不会牺牲准确性。而且,这个方法非常简单。当你把在边缘获得的效用加起来时,这些研究人员在加利福尼亚是值得的。不夸张。

本书

保罗·鄂尔多斯,上个世纪最伟大也是迄今为止最多产的数学家之一,会爱上那些证明和定理,它们以其绝对的简单、优雅、广泛的影响和富有洞察力的技巧,必定来自“那本书”。

这里,鄂尔多斯的意思是上帝用来创造世界的真理卷轴。数学家们像朝圣者一样聚集在这些证据周围。正是它们激励我们花几十年时间进行徒劳的斗争。所以,当我听到这个消息,看到弗兰克尔的论文时,他的评论让我不寒而栗:“这是……从书上来的。“我怀疑他感觉好像有一份金色的礼物飘进了他的大腿。这些真理是如此简单,以至于它们似乎是迷宫中的错误转弯,然而它们却打开了不可能的新前景。

而且,当我们看到从这种根本性转变演变而来的一连串影响时,我们应该清楚这是一个强大的工具——赫菲斯托斯的铁砧。

自主滑行

为了说明弗兰克尔的修剪有什么价值,想象一下你刚刚花了 1000 美元买了一辆自动驾驶汽车,作为出租车的副业来赚取收入。那辆车要在六年内付清,每天需要留出 50 美分——利润需要比这更多,如果利润大得多,就会刺激更多的出租车。

现在,把它和一台价值 1000 美元的数控机床做个比较,每两周就会吐出另一辆自动出租车。哇哦。这将很快收回成本,并产生巨大的利润。每个人都会想买那辆 CNC,因为它的成本分摊越来越多的自动驾驶出租车上。

你不仅被这些利润所激励;增加的供应降低了价格,更低的单位 T2 资本成本让你继续在这些价格上获利。因此,消费者和生产者都带着更多的钱离开,与此同时,出租车服务非常丰富,本身就产生了巨大的价值。

那么,剪枝算法是如何为神经网络做这种事情的呢?

法兰克林

当谷歌训练其最新的自然语言模型时,它必须在大规模并行专用处理器机架上运行数周。最近的其他巨头也是如此;每一个吸收计算机的使用一个超级计算机,一次一个 有用服务实例。如果对该服务的需求增加,您将需要更多的机架,因此它仍然昂贵,部分抑制了需求,这意味着它为市场提供的总价值减少了。

相比之下,如果你能把这个庞然大物缩小到一个茶杯里,那么每个人的手机或笔记本电脑就足以产生这种有用的服务。而且,向数亿用户推出这项服务实际上是免费的。所以,最初的超级计算机时间每翻一次产生更多的美元。此外,最重要的是,计算机可以继续开发更多手机应用大小的人工智能,就像我们制造自动出租车的数控机器一样。这些应用程序中的每一个都以最低的成本为如此多的人提供了实用工具,这将比其他方式更快地推动对每一个定制应用程序的投资

这与杰冯悖论有关——当机器变得更加节能时,每一美元的能源都会产生更多的收入,所以你最终会使用更多的能源,因为它是高效的。能源总需求增加。考虑到有多少个数量级的**与科学相关的网络更便宜,以及推出众多专家是多么容易,我预计对能源、计算、数据、人才、洞察力的需求将大大增加,加速整个行业的开发和部署**

向上跳跃一个指数

正如我们的全球危机令人痛苦地表明的那样,一条指数曲线即使只是稍微陡一点点就会变得势不可挡。而且,如果你能延迟一个指数级的时间,哪怕是很短的时间,那的百分比损失就会在未来的每一个时刻持续下去,累积的贴现成本至少是延迟时刻的损失的 8 倍。因此,每三天增加一倍的疾病,延迟六天,在未来的所有时间里有四分之一的人患病。

同样,如果你以指数形式向前跳跃,你将获得巨大的累积贴现收益。增加该指数的陡度甚至更多。据我所知,弗兰克尔的美丽盆景是一个越来越陡峭的曲线。如果 10 亿人每人每天受益超过35 美分,那么按照保守的估计,这就值几万亿。每部手机上的超级计算机人工智能可能会有更大的帮助。**

最让我惊讶的是这种技术竟然可以存在!在抽象、虚幻的数学世界中,是什么让这种方法成功了呢?弗兰克一定听到了拉马努金天使的低语。正是这种美丽而神秘的巧合让我对毕达哥拉斯的故事肃然起敬——“宇宙是由数字组成的。”

神经网络:从零到英雄

原文:https://towardsdatascience.com/neural-networks-from-hero-to-zero-afc30205df05?source=collection_archive---------13-----------------------

了解神经网络最重要的参数!

图片来自 vectorstock

介绍

本文将涵盖以下主题:

  • 最优化理论:梯度下降及其变化
  • 学习率和批量大小
  • 损失和激活功能
  • 重量初始化

最优化理论:梯度下降及其变化

如果你想要梯度下降的详细解释,我建议你看看这篇文章,其中有对神经网络所基于的数学的深入研究。

总之,梯度下降计算训练集中每个样本的误差,然后在指向梯度的方向上更新权重。

换句话说,对于每个时代,我们都需要:

  1. 计算每个预测(向前传递)。
  2. 计算每一个误差。
  3. 向后传播误差,以评估每个权重在该误差中的重要性。
  4. 最后,相应地更新权重。

假设我们有:

  • 包含 100,000 个样本的数据集
  • 每次向前传递需要 2 毫秒
  • 每次误差计算需要 1 毫秒
  • 每次反向传播需要 3 毫秒

如果我们计算一下:

一个常规的神经网络可能需要数百甚至数千个时期来适当地收敛。假设我们需要 100 个历元,这是一个很低的数字。

我们的神经网络需要多少才能被训练好?

时间太长了。我们假设只有 100,000 个样本,这很好。例如,ImageNet 由 120 万幅图像组成,每个时期需要 2 小时,换句话说,需要 8.3 天。一个多星期来看一个网络的行为。

大幅减少训练神经网络所需时间的一种方法是,每次我们想要更新权重时,使用随机选择的单个样本。

这种方法被称为随机梯度下降(SDG)。使用 SDG,我们只需计算一个样本的预测、误差和反向传播来更新权重。

这将把总培训时间减少到:

这是一个巨大的进步。但是这种方法有一个非常重要的缺点。

在这两条路径中,你认为哪一条是梯度下降路径?哪一个是随机梯度下降的?

图片来自这里

红色路径是沿着梯度下降的路径。它使用数据集的所有样本计算梯度(下降路径),并总是在最小化误差的方向上获得一致的更新。

紫色路径是 SGD 遵循的路径。这是怎么回事?每次权重更新都是为了通过仅考虑一个样本来最小化误差,因此我们最小化的是该特定样本的误差。

这就是为什么它有一个更混乱的行为,它的收敛成本更高,虽然,作为回报,它运行得更快,所以在 GD 需要运行一个纪元的时间里,SGD 可以运行数千个。

看起来最好的选择是平衡这两种方法。如果我们看一下前面的图片,最佳路径是绿线。

为了计算这条路径,让我们回顾一下到目前为止讨论过的方法:

  • 计算我们的训练集的所有元素的预测和误差的方法:(香草)梯度下降
  • 计算从我们的训练集中随机选择的 1 个元素的预测和误差的方法:随机梯度下降

如果我们选择的不是 1 个元素,而是 K 个元素呢?这样一来:

  • 我们增加了算法的稳定性,因为我们不仅查看一个元素,而且查看 K (也就是说,我们减少了洋红色线方向的突然和混乱的变化)
  • 我们减少了关于传统下降梯度的执行时间,因为我们从训练集的 N 个样本减少到 K ,其中 K < < N

这种方法被称为小批量随机梯度下降法,是实践中最常用的方法。

K通常被选择为 2 的幂,因为这允许你利用一些针对这些情况的 GPU 实现的优化。一个典型的 K 可能是 K =32,但最终,这还是受到了 GPU 内存的限制。

K 越低,它就越像纯 SGD,它需要收敛的纪元就越多,尽管它会更快地计算它们也是事实。

另一方面, K 越高,就越像纯 GD,每个历元的计算就越麻烦,但收敛所需的时间就越少。

学习率和批量大小

学习速率和批量大小是与下降梯度算法直接相关的两个参数。

学习率

你可能知道,(或者如果你不知道,你可以在这里查看)更新神经权重的方法是通过这些公式:

https://mattmazur . com/2015/03/17/a-逐步-反向传播-示例/

乘以∂Etotal/∂wn 的叫做 η ,就是学习率。学习率表示我们给予误差的重要性,以更新每个权重。也就是说,权重的变化有多快或多突然。

因此,一个非常高的 η ,将在从一个迭代到另一个迭代的巨大步骤中改变权重,这可能导致跳过最小值。

https://www . quora . com/In-neural-networks-why-one-use-many-learning-rates-In-decay-steps-than-one-smooth-learning-rates-decay

另一种可能性是建立非常低的 η ,这将使我们的网络需要太多的历元来达到可接受的最小值。此外,我们可能会陷入比更高的η所能达到的最佳最小值更糟糕的最小值中。

https://www . researchgate . net/publication/226939869 _ An _ Improved _ EMD _ Online _ Learning-Based _ Model _ for _ Gold _ Market _ Forecasting/figures?lo=1

让我们谈谈最小值:我们用神经网络实现的,通常不是我们函数的全局最小值,而是足以正确执行我们正在开发的任务的局部最小值。

我们想要的是一个最优的学习速率,它允许我们随着时间的推移减少误差,直到我们达到最小值。在图表中,这个学习率就是红线。

https://towards data science . com/useful-plots-to-diagnostic-your-neural-network-521907 fa2f 45

为了让我们的学习率达到最优,我们可以对我们的学习率进行衰减。这种衰减会随着时间的推移降低学习速度,所以当我们达到最小值时,它会小到足以避免跳过它。

https://www.pinterest.es/pin/825918019139095502/

因此,我们通过选择一个非常低的学习率和跳过最小值来避免长时间等待收敛,因为我们越接近它,我们向它迈出的步伐就越小。

批量

回想一下上一节,SGD 是一个小批量 SGD,其中 K=1。

并且小批量 SGD 的 K 表示每次用于更新权重的样本数量。这不是一个关键参数,它通常被设置为我们的 GPU 可以容纳的最大样本数。

我们有一个 8GB 内存的 GPU,如果每个图像占用 1MB,我们可以容纳多少个样本?

嗯,没那么简单!这取决于网络的架构。密集或完全连接的层(在传统层中,所有神经元都与下一层中的所有神经元相互连接)具有更多参数,因此占据更多内存。

我们还有卷积层、汇集层、分离层和许多其他类型。因此在实践中,很难手工计算出我们可以使用的最大样本数。

我们所做的是尝试将批量大小设置为 2 的倍数,如果出现内存错误,就减少批量大小。例如,我们将从 512 开始,如果我们有一个错误,我们将下降到 256、128、64、32、16、8、4、2 甚至 1。

根据您的网络架构,您可能必须使用 K=1,因此 SGD。尽管通常优选的是将图像尺寸从 512×512 减小到 256×256 或 128×128 像素,并使用较大的 k

学习率和批量关系

记住学习速度与批量大小有关,这一点非常重要。

如果我们接近 K=1,我们必须降低学习率,使得权重的更新不那么重要,因为它更接近 SGD,换句话说,更接近用单个随机样本计算梯度。

因此,总之,如果我们使用较低的批量大小,建议使用较低的学习速率,但我们也会增加历元的数量,因为后面的条件会使我们的神经网络需要更多的时间来收敛。

损失和激活功能

损失函数

损失函数告诉我们我们的预测有多错误。

想象一下,我们只需要看一张照片就能猜出一栋房子的价格。我们的神经网络将以照片的像素作为输入,以显示价格的数字作为输出。

例如,假设我们想要预测一栋房子的价格,所以我们正在训练网络,而这栋房子就在我们的训练集中。当图片经过时,计算出一个预测,那就是它值 323567 美元。事实是房子价值 600,000 美元,因此很明显,一个合适的损失函数可以是:

考虑到这一点,最常见的损失函数是:

对于回归问题

  • 均方误差
  • 绝对平均误差

分类问题

  • 二元交叉熵
  • 范畴交叉熵

正如我在的上一篇文章中所写的那样,只关注回归问题,让我们来看看其中的每一个问题:

  • 均方差:

https://towards data science . com/supervised-learning-basics-of-linear-regression-1 cbab 48 d0 EBA

均方差或 MSE 是真实数据点和预测结果之间的平方差的平均值。这种方法惩罚越大的距离,这是标准的回归问题。

  • 平均误差

https://towards data science . com/supervised-learning-basics-of-linear-regression-1 cbab 48 d0 EBA

平均绝对误差或 MAE 是真实数据点和预测结果之间的绝对差值的平均值。如果我们将此作为遵循的策略,梯度下降的每一步都将减少 MAE。

什么是交叉熵?

我们首先需要理解什么是熵。让我们用几个例子来说明这一点:

例一

想象一下,我们正在玩一个游戏:我们有一个装有不同颜色球的袋子,游戏的目标是猜一个志愿者用最少的问题数画出哪种颜色。

在这种情况下,我们有一个蓝色球、一个红色球、一个绿色球和一个橙色球:

https://www . quora . com/Whats-an-intuitive-way-to-think-of-cross-entropy

也就是说每个球都有 1/4 的机会出去。

最好的策略之一是先问你发的球是蓝色的还是红色的。如果是,我们会问球是不是蓝色的。如果不是,我们会问它是否是绿色的。所以我们需要两个问题。

https://www . quora . com/Whats-an-intuitive-way-to-think-of-cross-entropy

例 2

这次我们有一个装有球的包,其中 1/2 是蓝色的,1/4 是红色的,1/8 是绿色的,1/8 是红色的。现在,最佳策略是先问它是不是蓝色的,因为蓝色的可能性更大。如果是的话,我们就完了。如果不是,我们可以问它是否是红色的,这是下一个最有可能的类。如果是的话,我们就完了。如果不是,我们可以问它是绿色的(还是橙色的)。

https://www . quora . com/Whats-an-intuitive-way-to-think-of-cross-entropy

现在发生的情况是,一半的时间(1/2)是蓝色的,我们要花 1 个问题来猜测。1/4 的时间是红色的,它花了我们 2 个问题。1/8 是绿色的,要花我们 3 个问题,如果是橙色的也一样。

所以猜一个球的期望题数是:1/2⋅1(蓝色)+1/4⋅2(红色)+1/8⋅3(绿色)+1/8⋅3(橙色)=1.75

例 3

想象一下,现在我们有一个装满蓝色球的袋子。我们需要问多少题才能找出他们拿出的是什么颜色的球?无,0。

从这些例子中,我们可以得出一个表达式,它允许我们根据球的概率来计算问题的数量。因此,概率为 p 的球需要 log2(1/p)个问题。

例如,对于 p=1/8 的球,我们需要n _ quest= log2(1/(1/8)=3

因此,预期的问题总数是:

最后,理解熵的一种方法如下:

如果我们遵循最优策略,让我们猜测球的颜色的预期问题数量是多少?

所以,游戏越复杂,熵越高。在这种情况下,例 1 >例 2 >例 3。

好,现在我们知道了熵是什么,让我们看看交叉熵是什么。

交叉熵

假设我们对例 2 采用了例 1 的策略:

https://www . quora . com/Whats-an-intuitive-way-to-think-of-cross-entropy

所以,我们必须问两个问题来确定它是不是任何颜色。如果我们计算所需问题的总数,考虑到这一次每个球都有一个概率,我们得出:

n_total_quest=1/2⋅2(blue)+1/4⋅2(red)+1/8⋅2(green)+1/8⋅2(orange)=2

所以这个策略比例 1 中的策略更差。

最后,直觉上,熵是使用最佳策略时预期的问题数量,交叉熵是不使用最佳策略时预期的问题数量。

为此,我们试图做的是最小化交叉熵。

在形式上,它被定义为:

其中:

  • pi 是球的实际概率(在我们的例子中,蓝色是 1/2,红色是 1/4,绿色和橙色是 1/8)
  • pi^ 是我们使用策略时假设的概率,在这种情况下,所有球的概率相等(所有颜色的概率为 1/4)

记住公式中什么在哪里的一个方法是,记住我们想做的是找出按照我们的策略需要多少个问题,这是 pi^,所以在 log2 里面是 pi^.

激活功能

如果我们没有激活功能,我们会有以下内容:

https://towards data science . com/neural-representation-of-logic-gates-df 044 EC 922 BC

我们必须 y(x)=Wx+b,这是一个线性组合,甚至不能解决像 XOR 这样的问题。

http://www . ECE . utep . edu/research/web fuzzy/docs/kk-thesis/kk-thesis-html/node 19 . html

因此,我们需要一种方法来引入非线性,这就是激活函数的作用。在下图中,您可以看到一些最典型的网络,以及它们在网络中的位置:

https://towards data science . com/activation-functions-and-its-types-哪个更好-a9a5310cc8f

这里你可以看到最常用的:

https://towards data science . com/complete-guide-of-activation-functions-34076 e95d 044

很难知道使用哪一种方法我们的网络会表现得更好,但是有一种方法通常几乎总能得到好的结果:ReLU。

因此,每当我们开始时,我们将使用 ReLU,一旦我们得到一些我们认为好的结果,我们可以尝试使用泄漏的 ReLU 或任何其他您想要的。每天都有新的出现,简单的谷歌搜索就能让你找到一些有趣的:比如 SELU(https://towards data science . com/卢瑟-make-fnns-great-again-snn-8d 61526802 a9)。

这些激活函数中的许多需要权重初始化的特定方法,以便位于特定范围的值之间,并且梯度下降正常工作。

在输出图层的情况下,softmax 激活函数是使用最多的一个,因为它能够为每个类提供一个概率,使所有类的总和为 1。

由于这可能看起来有点复杂,请在下面找到推荐的食谱,作为以上所有内容的总结:

配方

  1. 开始使用学习率为 0.01 或 0.001 的 ReLU,观察会发生什么。
  2. 如果网络训练(收敛)但是很慢,可以试着提高一点学习速率
  3. 如果网络不收敛且表现混乱,则降低学习速率
  4. 一旦你的网络启动并运行,尝试一下漏热、最大或 eLU
  5. 不要使用乙状结肠,实际上它通常不会给出好的结果

重量初始化

正如您之前看到的,权重和偏差初始化对于实现我们的网络收敛到适当的最小值非常重要。让我们来看看初始化权重的一些方法。

如果我们遵循 MNIST 数据集(正如我们在本文中所做的),我们的权重矩阵将是 768(输入)x 10(输出)。

常数初始化

我们可以预先设定我们的重量

  • 零:
W = np.zeros((768, 10))
  • 一:
W = np.ones((768, 10))
  • 到常数 C :
W = np.ones((768, 10)) * C

正态和均匀分布

我们还可以使用均匀分布来初始化权重,其中定义了[上界,下界],并且该范围内的所有数字具有相同的被选中概率。

例如,对于[-0.2,0.2][-0.2,0.2]之间的分布:

W = np.random.uniform(low=-0.2, high=0.2, size=(768, 10))

利用该指令,我们将使用从[-0.2,0.2][-0.2,0.2]之间的范围中提取的值来初始化 WW 权重矩阵,在该范围中,它们都具有相同的被提取概率。

我们也可以用正态或高斯分布来计算,其定义为

如你所知:

  • μ是平均值
  • σ是标准差,σ2σ2 是方差

因此,我们可以用正态分布初始化我们的权重,其中 μ=0σ=0.2 ,例如:

W = np.random.normal(0.0, 0.2, size=(768, 10))

初始化:正常和统一的 LeCun

另一种更先进的方法是 LeCun 方法,也称为“高效反向投影”。

该方法定义了 3 个参数:

  • Fin:该层的条目数(在我们的例子中是 768)
  • Fout:该层的出口数量(在我们的示例中为 10)
  • 极限:根据 Fin 和 Fout 定义为:

通过这种使用均匀分布的方法来初始化 W 的代码将是:

W = np.random.uniform(low=-limit, high=limit, size=(F_in, F_out))

对于一个普通人来说:

W = np.random.normal(low=-limit, high=limit, size=(F_in, F_out))

初始化:Glorot/Xavier 正常和统一

这可能是最广泛使用的初始化权重和偏差的方法。这是使用 Keras 时的默认设置。

在这种情况下,也定义了与 LeCun 相同的参数,但是极限的计算有所不同:

使用这个方法初始化 WW 的代码与使用 LeCun 的代码相同。

对于均匀分布,它将是:

W = np.random.uniform(low=-limit, high=limit, size=(F_in, F_out))

对于一个普通人来说:

W = np.random.normal(low=-limit, high=limit, size=(F_in, F_out))

初始化:何等人/和正常而统一

这种方法是以何的名字命名的,他是《深入研究整流器:在 ImageNet 分类上超越人类水平的性能》一书的第一作者。

通常,当我们训练使用特定类型的 ReLU 作为激活(如参数 ReLU)的非常深的神经网络时,使用这种方法。

制服的代码是这样的:

limit = np.sqrt(6 / float(F_ini))W = np.random.uniform(low=-limit, high=limit, size=(F_in, F_out))

在正常情况下,这个:

limit = np.sqrt(2 / float(F_ini))W = np.random.uniform(low=-limit, high=limit, size=(F_in, F_out))

食谱:

权重的初始化通常不是网络训练中的决定因素,但有时它会导致网络无法训练,因为它无法收敛。

所以推荐的建议是用 Glorot 的,如果那天你觉得运气好,想看看自己在准确率上能不能提高,那就和别人一起试试。

最后的话

一如既往,我希望你喜欢这个帖子,你现在是神经网络的专家了!

如果你喜欢这篇文章,那么你可以看看我关于数据科学和机器学习的其他文章 这里

如果你想了解更多关于机器学习、数据科学和人工智能的知识 请在 Medium 上关注我,敬请关注我的下一篇帖子!

神经网络有助于将著名的 1896 年视频高档转换为 4K 质量

原文:https://towardsdatascience.com/neural-networks-help-upscale-conversion-of-famous-1896-video-to-4k-quality-d2c3617310fe?source=collection_archive---------17-----------------------

艾使得在 4K 重现卢米埃尔兄弟的《火车抵达拉乔塔特车站》成为可能

火车到达拉乔塔特(卢米埃兄弟,1896 年)

随着时间的推移,神经网络变得越来越复杂。他们已经允许科学家们实时地从脑电波和许多其他事物中重建人类的思想。

1896 年,卢米埃尔兄弟电影 “火车到达拉乔塔特车站” ,持续 50 秒,激起了观众的情绪,神圣地迈出了电影院的第一步。它仍然是卢米埃尔兄弟作品的象征,更广泛地说,是第七艺术的开端。

最近,一个名叫 丹尼斯·希尔亚耶夫 的人使用神经网络将 1896 电影缩放到 4K 分辨率使用 托帕斯实验室 商业 千兆像素 AIDAIN 图像编辑应用。他不仅将镜头增加到 4K ,还将帧率提高到每秒 60** 帧。**

Shiryaev 使用 Gigapixel AI4K 格式渲染了 50 秒静音短片 《一列火车抵达拉乔塔特车站》 ,画面非常逼真。原始胶片的质量非常模糊,分辨率非常低。他的作品发表后,获得的结果令人惊讶。他的新视频似乎非常符合 21 世纪的视频标准。

尽管有一些不完美,比如图像跳跃或某些细节模糊,这种体验的成果令人印象深刻。为了完成他的工作, Shiryaev 还在这部无声电影中加入了的声音

丹尼斯·希尔亚耶夫 的电影复原版

这些图像的获得得益于一种人工神经网络形式:生成对抗网络,或 GANs 。这种技术在最近几个月得到了推广,特别是著名的 Kaggle 比赛【deep fake Detection Challenge】和由 AI 产生的艺术创作的出现。

提醒一下,方法在于对抗两个神经网络。第一个基于数据生成对象,第二个的作用是确定对象的真实性。第一个网络一次又一次地尝试,直到它的产品完美到足以欺骗第二个网络。通过这种方式,程序学习自己来生成最可能的图像。

Gigapixel AI 软件采用专有插值算法,分析图像,识别细节和结构,完成图像。它可以使图像更清晰,甚至在经过600%放大后。

(深度感知视频帧插值)* 另一方面,想象并在现有视频剪辑的关键帧之间插入帧。换句话说, DAIN 分析并映射视频剪辑,然后在现有图像之间插入生成的填充图像。和 4K TVs 的运动平滑功能是一个概念。为了在这个 1896 视频中实现相同的结果, Shiryaev 添加了足够多的图像,以将速率提高到 60 FPS 。因此,除了最初记录的 24 张图像之外, DAIN 每秒自动生成并添加了 36 张额外图像。*****

卢米埃尔兄弟的原创电影

Shiryaev 的 “火车抵达拉乔塔特站” 的改良版看起来像是最近用智能手机GoPro 制作的电影。与原版视频的对比相当惊艳,尤其是在新版本中获得的流畅性。太阳在行驶的火车上的反射和站台上的女性珠宝被很好地转录,这也许是最显著的改进之一。

神经网络也可以使用相同的基本技术进行着色:从一堆彩色照片开始,将它们转换为黑白照片,然后训练神经网络来重建彩色原件。 Denis Shiryaev 甚至有任务在 视频 YouTube 频道 上为他的改良版火车抵达拉乔塔特站* 添加色彩。*****

然而,人们相信,Shiryaev 的技术是经过深思熟虑的,非常有前途,因为它可以很好地激励其他热爱无声电影的人。

神经网络算法非常强大,并且每年都在改进。使用的可能性非常多,电视世界很可能是最大的受益者之一。

“向神经网络展示一张低分辨率的人脸图像,它会识别出这是一张脸,并为受试者的眼睛、鼻子和嘴巴填入正确的细节。”托帕斯实验室说。

不幸的是,这些有用的技术有时被用于恶意目的,例如,它们可以用于制作“深度假货”并允许在视频中进行身份盗窃。

因此,有理由担心它可能被滥用,但技术可以很容易地成为一种利用人工智能更新旧电影并彻底改变行业本身的方式。

参考资料:

如果你设法来到这里,恭喜你。感谢阅读,我希望你喜欢它。关于机器学习的个人接触或讨论,请随时在LinkedIn上联系我,别忘了在 GitHubMedium 上关注我。****

神经网络直觉-7。自我监督学习和 SimCLR 论文解释

原文:https://towardsdatascience.com/neural-networks-intuitions-7-self-supervised-learning-and-simclr-paper-explanation-ba0101f10c99?source=collection_archive---------31-----------------------

大家好:-)

今天我将谈论深度学习领域最重要和最有趣的话题之一—*自我监督学习和最近一篇展示 SOTA 自我监督学习结果的论文— 视觉表征对比学习的简单框架 *

自我监督学习之所以至关重要,是因为在规模下对数据进行手动标记是非常非常昂贵和繁琐的。因此,焦点自动集中在自我监督非监督学习领域——以减少对大量数据进行标记的需要。**

让我们首先了解什么是自我监督学习,以及它如何帮助解决上述人工标记的问题(或者至少最小化它)。

在整篇文章中,我将从解决现实世界问题的角度来解释事情。

问题:

让我们考虑有 1000 个类别的图像分类问题。我们有覆盖这 1000 类的未标记数据(比如 100 万张图片)。我们如何着手解决这个问题?

  1. 首先,我们需要 手动标注 这些图像。
  2. 如有必要,应用 增强
  3. 然后简单地用 resnet50 骨干 训练一个分类器——用 ImageNet 预训练的权重或者 随机 权重。

步骤 2 和 3 非常简单。如果您已经有了所需的框架,那么您可以快速扩充和训练分类器。

当然,步骤 3 需要我们试验不同的主干、输入图像分辨率、优化器、损失函数、超参数,如学习速率、批量等等。

但是第一步也是最重要的一步是给数据贴上标签。手动标记如此大量的数据需要大量的资源,如时间和人力。最重要的是,我们需要确保 人为错误尽可能少。

因为标记所有的数据是乏味的,所以让我们只注释随机的数据子集。

为了简单起见,我选择了一个随机子集,但我们可以优化这个选择。

既然我们要标注一小部分,我们如何减少手工标注的工作量或者完全消除这个标注过程?(尽管这似乎是一个不切实际的目标:),或者至少利用这大量未标记的数据来帮助提高准确性。

解决方案:

1。转移学习:

一个显而易见的方法是使用一些与我们的数据集非常相似的开源数据集(即使我们经常找不到),在开源数据集上进行训练,然后在我们的数据集上微调网络。

这确实有助于提高分类器的准确性,但不是在很大程度上,并且总是比从随机权重开始更受欢迎。

Btw,为什么我说这个比随机初始化好?

这是因为它有助于实现更高的精度和更快的收敛!

很好,但是怎么做?

由于我们在类似于我们的目标数据分布的开源数据集上训练我们的网络,这意味着我们的网络已经学习了一些相关特征,而不是随机特征。因此,一旦我们在我们的目标数据集上再次训练网络,自然期望它表现良好并避免在小目标集上过度拟合。这可以被视为等同于“在更多数据上训练网络”。

但是,我们可以通过从我们的未标记目标数据分布中学习的表示来做得更好,而不是从不同的数据分布中学习的表示。

因此,我们的下一个方法是自动地从这个未标记的目标分布中学习表示!

这种使用未标记的数据来帮助监督任务的技术被称为 自监督学习 ,并且帮助从这种未标记的目标分布中学习表示的方法被称为 借口任务。

  • 这里被监督的任务是在标记数据上训练一个分类器,也称为* 下游任务。*

2。自我监督学习:

现在我们知道了什么是自我监督学习,让我们看看有哪些类型的借口任务,以及它们实际上如何帮助学习表征。

这篇文章将涉及多个借口任务。因此,我将只给出这些任务的概述,以及如何使用它们来解决我们手头的问题:-)

a .自动编码器:

Autoencoder 是一种神经网络,它试图重建输入,从而学习输入数据表示。

自动编码器看起来像:

自动编码器的架构

  • 在我们的例子中,输入和输出将是一个图像。

网络接收图像并输出相同的图像。通常使用的损失是 MSE 损失。这里要注意的主要是 代码(或者嵌入)。T3 表示从输入数据中学习到的特征。

这对解决我们的问题有什么帮助?

我们可以在未标记的数据上训练一个自动编码器(resnet50 编码器,avgpool 的输出作为嵌入),加载编码器的权重,并在标记的子集上训练。

b.范例-CNN:

论文:- 有判别力的无监督特征学习与样例卷积神经网络

作者提出了以下方法:

  1. 对于数据集中每个未标记的图像,应用随机变换,例如平移、旋转、缩放和其他颜色变换。
  2. 得到的增强图像集被认为是一个类的一部分(称为代理类)。**
  3. 之后,训练一个分类器来区分这些代理类。

图来自 利用样本卷积神经网络进行的判别无监督特征学习

请注意,可能有太多的代理类表示同一个基本事实类,因为不可能事先知道它们,所以我们可以首先对这些未标记的图像进行聚类(从相似数据集上的预训练模型或在同一数据集上使用 autoencoder 进行嵌入),然后对这些聚类应用变换。

在理想的情况下,每个类(这是我们的代理类)只有一个样本,随机变换被应用于每个样本并进行训练。

像自动编码器一样,我们可以将训练好的分类器的权重用于我们的下游任务。

c.对比学习— SimCLR:

论文 视觉表征对比学习的简单框架 提出了另一种机制,使用 对比学习 从未标记的数据集中学习有用的表征,该表征稍后可用于下游任务。

提议的方法:

  1. 在训练期间,对 N 个 未标记图像中的一个 批次进行采样。
  2. 对于每幅图像, 应用两种变换——随机裁剪和调整大小, 生成两幅图像,这两幅图像被认为是 样本。同批剩余的 (N-1)张 被认为是 阴性 样本。现在用这两个类训练一个分类器。对该批中的每个图像重复该过程。
  3. 使用的基本编码器是 Resnet50(2048),后面是一个 2 层 MLP,它将表示从 2048 转换为 128 维。
  4. 所用的损失是 NT-Xent(归一化温度标度交叉熵损失)

其中 sim =余弦相似度,𝟙 ∈ {0,1 } IFFkI,τ表示温度参数。

目标是学习两个正图像和其余 N-1 个负图像的相似表示,以具有与这两个图像完全不同的表示。但是这是如何实现的呢?

  1. 为该批中的所有嵌入对计算 余弦相似度
  2. 对于 每个正对(I,j) ,我们计算一个 归一化相似度得分 ,并使用 log loss/CE loss 将其最小化。
  3. 对批(2N)中的所有图像进行此操作,最后取一个 平均值

然而,这里有一点很重要:

我们如何确保一批中用于阴性类别的(N-1)幅图像不包含阳性样本,因为我们首先不知道它们的标签?

可惜,文件没有清楚说明这点,我也不知道上述问题的答案。我们可以做的一件事是基于预训练的嵌入来挑选负面图像,但我不认为这种情况会发生!如果有人知道答案,请告诉我:-)

其他常见借口任务:

所有上述借口任务直接学习分类底层类(除了自动编码器),但也有任务试图优化不同的目标,但学习有用的表示为下游任务。

  1. 生成对抗网络:我们可以训练 GAN 从我们的未标记数据分布中生成图像,使用生成器(即编码器)的权重并在我们的标记子集上重新训练。
  2. 预测图像旋转— 通过预测图像旋转进行无监督表示学习
  3. 预测图像中一个面片 wrt 与另一个面片的相对位置— 通过上下文预测的无监督视觉表示学习

参考资料:

  1. 用样例卷积神经网络进行判别性无监督特征学习
  2. 视觉表征对比学习的简单框架
  3. https://lilian Weng . github . io/lil-log/2019/11/10/self-supervised-learning . html

神经网络直觉:8。目标检测器中的平移不变性

原文:https://towardsdatascience.com/neural-networks-intuitions-8-translation-invariance-in-object-detectors-21db6e27879c?source=collection_archive---------44-----------------------

大家好!

这篇文章将会很短,主要讨论对象检测器中一个不太重要但被高度忽视的概念,特别是在单次检测器中— 平移不变性。

让我们理解什么是平移不变性,什么使得图像分类器/对象检测器平移不变性。

*注:本文假设您对单级和两级检测器的工作原理有背景知识:-)

平移不变性:

平移在计算机视觉中是指 在空间中的位移不变性是指不变的 性质。

因此,当我们说图像分类器或对象检测器是平移不变的时,它意味着:

图像分类器可以准确地预测一个类别,而不管该类别(更具体地说,模式)位于图像的空间维度的何处。类似地,检测器可以检测对象,而不管它出现在图像中的什么位置。

让我们看一个例子来说明每个问题。

图像分类:来自 MNIST 数据集的图像的未翻译和已翻译版本(量化卷积神经网络中的翻译不变性

物体检测:狗的翻译版本——图像中的待检测物体。

在本文中,我们将只考虑卷积神经网络——无论是分类器还是检测器,看看它们是否是平移不变量

卷积分类器中的平移不变性;

CNN 平移不变吗?如果是,是什么使它们对翻译不变?

首先,CNN 不是完全平移不变的,只是在一定程度上。其次,是“汇集”使它们平移不变,而不是卷积运算(应用过滤器)。

上述陈述仅适用于分类器,不适用于对象检测器。

如果我们阅读 辛顿在 CNN中关于平移不变性的论文,他明确指出 池层 是为了降低计算复杂度平移不变性 只是它的副产品。

人们可以通过输入正确的数据使 CNN 完全翻译不变——尽管这可能不是 100%可行。

注意:我不会解决池如何使 CNN 翻译不变的问题。你可以在下面的链接中查看:-)

* [## 杰弗里·辛顿谈 CNN 怎么了

我将在不同的生物启发的机器学习讲座上发布一些松散的笔记。在这个笔记中,我…

moreisdifferent.com](http://moreisdifferent.com/2017/09/hinton-whats-wrong-with-CNNs)

http://cs231n.stanford.edu/reports/2016/pdfs/107_Report.pdf 号*

两级探测器中的平移不变性;

两级物体探测器具有以下部件:

  1. 区域提议阶段
  2. 分类阶段

第一阶段预测感兴趣对象的位置(即区域提议),第二阶段对这些区域提议进行分类。

我们可以看到,第一阶段预测前景物体的位置,这意味着问题现在简化为图像分类——由第二阶段执行。这种减少使得两级检测器转换不变,而没有对神经网络架构引入任何明显的改变。

对象的类预测对象的边界框预测的这种解耦构成了两阶段检测器平移不变量*!*

单级探测器中的平移不变性;

既然我们已经研究了两阶段检测器,我们知道单阶段检测器需要耦合盒预测和类预测。一种方法是在特征图上进行密集预测(锚点),即在特征图上的每个网格单元或一组单元上进行。**

阅读下面这篇文章,我将深入解释锚: 神经网络直觉:5。锚点和对象检测

由于这些密集预测是通过对特征图上的过滤器进行卷积而得到的,这使得网络能够在特征图上的不同位置检测到相同的模式。

例如,让我们考虑一个被训练来检测图像中存在的狗的神经网络。最终 conv 图层中的过滤器负责识别这些狗的图案。

我们向网络输入数据,使狗总是出现在图像的左侧,并用狗出现在右侧的图像进行测试。

最后一层中的一个过滤器学习上面的狗模式,并且由于相同的过滤器一直被卷积,并且在特征图中的每个位置进行预测,所以它在不同的位置识别相同的狗模式!

最后来回答“为什么 滤镜 使 检测器平移不变而非量词平移不变?”

conv 网络中的滤波器在图像中学习局部特征,而不是在全局环境中学习。由于对象检测的问题是从图像中检测局部特征(对象),而不是从整个特征图中进行预测(这是在图像分类器的情况下发生的),所以滤波器有助于使它们对于平移不变。

这是我的系列文章的第八部分。我希望你们能够从总体上很好地理解平移不变性,以及是什么使得检测器对图像中的物体平移不变。如果我说错了,请随时纠正我:-)

干杯!

神经网络直觉:9。远程度量学习

原文:https://towardsdatascience.com/neural-networks-intuitions-9-distance-metric-learning-dae7c3a0ebdf?source=collection_archive---------22-----------------------

远程度量学习

欢迎回到我的神经网络直觉系列。在第九部分中,我们将深入了解**远程度量学习,使用它背后的动机,提出的各种方法及其应用。

注意:本文讨论的所有技术都属于 深度度量学习(DML),即使用神经网络的距离度量学习。

距离度量学习:

距离度量学习意味着在低维空间中学习距离,这与语义相似性的概念一致。(如[* 中所给,使用代理 】的无争议距离度量学习)*

上面的说法是什么意思 w.r.t 图像域?

这意味着学习低维空间(非输入空间)中的距离,使得输入空间中的相似图像导致相似的表示(低距离),而不相似的图像导致不同的表示(高距离)。

好的,这听起来正是分类器所做的。不是吗?是的。

那么这与监督图像分类有什么不同呢?为什么术语不同?

度量学习解决了机器学习中的开集设置问题,即在测试时推广到新的示例。

这对于特征提取器之后是完全连接的层分类网络是不可能的。

为什么?

这是一个非常重要的问题。答案如下:

  1. 一个分类器学习类特有特征而不一定是类属特征。**
  2. 具有 标准交叉熵损失的分类器最大化类间距离 ,使得 FC 层之前的特征是线性可分的。

由分类网络提取的特征(在 FC 层之前,有 CE 损失)是线性可分的

并且不旨在最小化导致期望的 区别特征的类内距离。

具有低类内距离和高类间距离的特征

学习区别特征的这一方面是度量学习所实现的。

使用 Softmax 分类生成的嵌入

使用双/三重网络生成的嵌入

在研究度量学习中最广泛使用的方法之前,让我们看看它的应用,使问题陈述更加具体,以及为什么标准的分类方法可能不适合。

度量学习的应用如下:

  1. 图像检索
  2. 近似重复检测
  3. 少/零投学习

太好了!

现在让我们看看度量学习中使用的突出方法:

a .具有对比损耗(对)的连体网络

b .具有三重损失的三重网络(三重网络)

c .分类基础方法。

目标:

以产生对于相似图像在欧几里得空间中接近(假设)而对于不相似图像远离的嵌入。

解决方案:

a .有对比损耗的连体网络:

论文通过学习不变映射进行降维通过将两幅图像作为输入并输出图像对是否相似来解决该问题。

方法:

  1. 为数据集中的每个图像创建相似不相似集合。
  2. 两幅图像(来自相似/不相似集合)传递到同一个神经网络,并提取低维嵌入/表示。**
  3. 计算两个嵌入之间的欧几里德距离。
  4. 将损失降至最低,以实现上述目标。
  5. 对大量对重复 1–4(所有对可能都不可行),直到模型收敛。

所以现在我们需要一个损失函数(包含欧几里德距离),对于相似的对来说是 0,对于不相似的对来说是 1。

这正是对比损失函数的作用!

对比损失:

(X1,X2)输入图像对Gw 为产生低维表示的函数映射(其中 w 代表参数),Y为表示相似或不相似的地面真实标签**

对比损失函数(通过学习不变映射进行维度缩减)

Dw =表示之间的欧几里德距离

对比损失与传统的交叉熵损失有相似之处。损失函数中的第一项处理相似对(Y=0 ),使得 Dw 变为 0。第二项处理不同的线对(Y=1 ),使得 Dw 至少变为 m。

这里 m 是余量,m 是 0。

为什么我们需要在训练中展示不同的配对?为什么不简单地最小化一组相似对的损失函数呢?

作者回答说,“涉及不同对的对比术语是至关重要的。简单地在所有相似对的集合上最小化 DW (X1,X2)通常会导致崩溃的解决方案,因为 DW 和损耗 L 可以通过将 GW 设置为常数而变为零。

既然我们已经了解了什么是对比损失函数,那么什么是连体网络呢?

这种架构被称为暹罗架构,其中相同的网络(即共享相同的参数集)被用于提取一对中的两个图像的低维表示。

b.三重网络,三重损耗:

论文 FaceNet:人脸识别和聚类的统一嵌入采用了与对比损失类似的方法——除了不是在每一步都处理成对图像,而是考虑三个一组的图像。

三元组由锚、正面(类似于锚)和负面(不同于锚)图像组成。

进场:

  1. 形成三元组(由具有共同锚图像的相似和不相似对组成)。
  2. 通过相同的神经网络传递三元组,并提取低维嵌入。
  3. 计算欧几里得距离并最小化损失。
  4. 对大量的三个一组重复 1-3,直到收敛。

三重损失:

f 为产生低维表示的函数映射, xa 为锚图像, xp 为正图像, xn 为负图像, α 为空白。

三重损失函数

三重损失确保锚图像的表示比任何其他负图像更接近与其相似的所有图像。

什么是三联体网络?

其中相同的网络(即共享相同的参数集)用于提取三元组中所有图像的低维表示的架构被称为三元组架构/网络。

对比损失法和三重损失法的问题:

  1. 随着训练样本数量的增加,图像对和三元组的数量急剧增加,使得很难对所有可能的对或三元组进行训练。
  2. 训练对和三元组(即简单样本)的不良选择会导致辨别特征的无效学习。

那么,如何解决上述问题呢?

通过仔细选择训练图像对和三元组——离线或在线,并使用较大的批量。

*注意:有很多种技术有助于用对比和三元组方法解决采样问题,我希望在以后的文章中讨论这些技术:)

c.基于分类:中心损失

论文一种用于深度人脸识别的判别特征学习方法通过引入一种新的损失(称为 【中心损失】 )以及交叉熵损失(即 )来解决使用香草神经网络分类的目的。

本文解决了文章开头提到的问题——“分类器没有最小化* 类内 距离 而只是最大化 类间距离 导致可线性分离的特征而不是可区分的特征”。*

中心损耗:

中心损失最小化每个类中心和类样本表示之间的距离-这确保了同一类中样本的表示除了保持类间距离之外还保持相似(由 ce 损失负责)。

x 为输入样本, c 为该样本的分类中心。

中心损失

每次迭代计算类中心(嵌入)和样本嵌入之间的距离,并更新权重。

基于分类的培训的问题:

  1. 基于分类器的方法在目标类数量非常多的情况下变得不切实际——这是通常的情况,也是使用成对/三重损失背后的强大推理。

以上就是本文中关于 深度距离度量学习的全部内容。 我希望你们所有人都很好地理解了这个问题是什么,以及如何通过各种有趣的技术来解决这个问题:)

干杯!

其他资源:

https://Neptune . ai/blog/content-based-image-retrieval-with-siamese-networks

神经网络拿 TensorFlow 游乐场开玩笑!

原文:https://towardsdatascience.com/neural-networks-made-fun-with-tensorflow-playground-4e681a0c4529?source=collection_archive---------30-----------------------

使用 TensorFlow Playground 探索神经网络并从中获得乐趣

彼得·康伦在 Unsplash 上的照片

TensorFlow Playground 是一个非常棒的网站,在这里您可以可视化并直观地了解神经网络是如何工作的。这个网站由谷歌的 TensorFlow 团队开发,是让你探索强大的深度神经网络的最佳平台之一。

这篇短文将在不到 5 分钟的时间内指导您如何在没有任何神经网络经验的情况下开始在 TensorFlow 操场上工作。

我强烈建议你们所有人从下面提供的链接在浏览器的一个新标签上打开这个网站,然后跟着做。读完这篇文章后,你会非常熟悉如何使用这个神奇工具的基本知识。

[## 张量流-神经网络游乐场

这是一种构建从数据中学习的计算机程序的技术。它非常松散地基于我们如何思考…

playground.tensorflow.org](https://playground.tensorflow.org/#activation=tanh&batchSize=10&dataset=circle&regDataset=reg-plane&learningRate=0.03&regularizationRate=0&noise=0&networkShape=4,2&seed=0.33938&showTestData=false&discretize=false&percTrainData=50&x=true&y=true&xTimesY=false&xSquared=false&ySquared=false&cosX=false&sinX=false&cosY=false&sinY=false&collectStats=false&problem=classification&initZero=false&hideText=false)

好吧!所以,让我们开始了解这个网站上不同的东西。

GIF 来自 GIPHY

点击链接后,您应该能够找到 TensorFlow 游乐场平台,它应该类似于下图。

作者截图

在确认我们现在都在同一页上之后,我们可以相应地理解第一个小节。

好吧!现在让我们理解下面显示的栏上的所有功能。

作者截图

运行和暂停按钮用于开始连续运行 epochs,直到您决定停止。当纪元运行时,模型将继续训练。播放按钮左侧有一个复位按钮,用于复位整个网络。播放按钮的右侧是步长增加按钮,用于一次增加一个步长。此按钮很有用,因为运行/暂停按钮有时可能太快而达不到适当的结果。将鼠标悬停在这些按钮上,以了解它们到底是什么。

  • 学习速率:神经网络学习正确拟合输出的速率。你可以根据自己的意愿改变它,并随时进行实验。但是,在本次演示中,我们将使用所有默认值。
  • 激活:激活函数用于增强神经网络的性能。我们有四种选择,它们是 tanh、ReLU、Sigmoid 和 linear。
  • 正则化:这是一种对学习算法进行轻微修改以使模型更好地泛化的技术。我们有 L1 和 L2 正则化选项可以使用,但我们将使用默认的无。
  • 正则化率:如果我们选择正则化方法,该选项允许我们选择正则化率。
  • 题型:我们有两个选项可以选择,即分类或回归型题型。在本次演示中,我们将使用分类类型。

现在,让我们继续了解我们正在处理的数据类型以及我们拥有的选项。

作者截图

您有四个难度递增的数据集选项,即圆形、异或、高斯和螺旋。我们可以选择将数据集分割成一个训练集,并以默认的 50%分割进行测试。如果您愿意,您可以引入多达 50 个噪声点。它还包含一个批处理大小按钮,为每个时期运行一个特定的批处理。最终重新生成按钮,再次生成数据。

橙色和蓝色在整个可视化中的使用方式略有不同,但一般来说,橙色显示负值,而蓝色显示正值。数据点(用小圆圈表示)最初是橙色或蓝色的,分别对应一个正值和一个负值。

让我们转到下一部分,即神经网络架构。

作者截图

默认情况下,我们有一个 1:2:1 的神经网络架构,这意味着输入层有 2 个节点,隐藏层有 2 个,第一层有 4 个节点,第二个隐藏层有 2 个节点,最后是输出层。你可以根据自己的选择随意修改。在本次演示中,我将使用所有默认设置。

在隐藏层中,线条由神经元之间连接的权重来着色。蓝色表示正权重,这意味着网络正在使用给定的神经元输出。橙色线表示网络正在分配负权重。

在输出图层中,点根据其原始值显示为橙色或蓝色。背景颜色显示网络对特定区域的预测。颜色的强度显示了预测的可信度。

作者截图

上图是我们将查看各个训练点的地方,您可以选择查看测试数据或离散化输出。

让我们运行网络 101 个纪元。

作者截图

在运行了 101 个时期之后,我们可以注意到损失已经显著减少,并且执行了几乎完美的分类。

作者截图

运行 300 个历元后,我们可以看到损耗降低到几乎可以忽略不计。

有很多不同的选择可以尝试,我强烈建议你们都去尝试一下。关于 TensorFlow 游乐场的简短说明和指南到此结束。

Robynne Hu 在 Unsplash 上的照片

结论:

TensorFlow 游乐场是以直观有趣的方式开始深度神经网络的最佳方式之一。你可以重新利用它,因为它在 GitHub 上是完全开源的,希望它能让神经网络更容易访问和学习。你可以按照他们的 Apache 许可以任何方式自由使用它。如果您有任何关于添加或更改的建议,您可以在这里让他们知道

对所有 TensorFlow 开发人员为这个令人惊叹的项目和他们所做的所有其他令人敬畏的项目大声喊出来。我希望你们在学习如何使用 TensorFlow 游乐场的基础知识的同时,喜欢阅读这篇文章。

点击这里查看我的其他文章:

[## 神经网络的完整有趣和复杂的历史!

重温人工神经网络发展背后的迷人历史

towardsdatascience.com](/the-complete-interesting-and-convoluted-history-of-neural-networks-2764a54e9e76) [## Python 从头编码:没有任何机器学习库的矩阵乘法!

从零开始了解如何在没有任何机器学习库的情况下实现矩阵乘法!

towardsdatascience.com](/python-coding-from-scratch-matrix-multiplication-without-any-machine-learning-libraries-463624fe8726) [## 10+牛逼 Python 编辑器的简明指南,以及如何选择最适合你的编辑器…

帮助您在各种 python 开发环境中进行选择的简明指南

towardsdatascience.com](/a-concise-guide-of-10-awesome-python-editors-and-how-to-choose-which-editor-suits-you-the-best-465c9b232afd) [## 5 个常见的 Python 错误以及如何避免它们!

从初学者到专家,每个人在 python 和机器学习中都容易出现这些错误。

towardsdatascience.com](/5-common-python-errors-and-how-to-avoid-them-63d9afc1a58f) [## 5 个关于 Python、机器学习和深度学习的超棒的计算机视觉项目创意!

讨论 5 个很酷的计算机视觉项目,学习新的技能,增强你的简历

towardsdatascience.com](/5-awesome-computer-vision-project-ideas-with-python-machine-learning-and-deep-learning-721425fa7905)

非常感谢你阅读这篇文章,我希望你们都有美好的一天!

神经网络概述

原文:https://towardsdatascience.com/neural-networks-overview-c3e6ab3e366b?source=collection_archive---------31-----------------------

数学、代码、绘图、情节、类比和思维导图

我桌子的照片。这项工作是由爱、核桃、葡萄干和茶推动的

我的意图是用类比、数学、代码、图表、绘图和思维导图与你一起走过神经网络的主要概念。我们关注神经网络的构建模块:感知器。

在整篇文章中,我们将直面令人生畏的数学,并使用 Python 代码和 Numpy 实现它。我们还将看看使用 Scikit-learn 的等效实现。我们的结果将使用 Matplotlib 和 Plotly 可视化。在每个概念的结尾,我们将使用思维导图来构建我们的理解。

感知器的结构

感知器的输入层是一个占位符。它包含的结点数与训练数据集中的要素数一样多。这些节点中的每一个都通过一条边连接到输出节点。我们将权重分配给边,将偏差分配给输出节点。

一个很好的类比是把感知器想象成一只乌贼。它的输入层有许多分支。臂的数量等于它需要的输入的数量。在这个类比中,让我们想象我们的数据集包含三种类型的配料:咸的、酸的和辣的。我们的鱿鱼需要三只手臂从每一种类型中抓取一种成分。手臂连接到头部,头部是鱿鱼混合配料的输出节点,并为它们的味道打分。

鱿鱼一生都生活在海里,很难注意到咸的成分,所以它们不会影响整体味道。然而,对于酸味和辣味,它可能是一个真正的势利小人。感知器中的权重可以理解为代表我们的配料类型对最终味道的贡献。这种偏见可以理解为影响鱿鱼味觉的一个因素,就像它的情绪或食欲一样。

输入乘以相应的权重,然后与偏差相加。这种具有各自权重的成分的混合和具有偏差的相加是一个仿射函数: z=𝑤x+𝑏

混合后,鱿鱼输出其对味道的印象分数。该分数被称为激活,并使用激活函数进行计算。激活可能只是结果 z ,因为它是在这种情况下,我们可以使用身份函数。它可能是一个介于-1 和 1 之间的数字,在这种情况下,我们可以使用双曲正切函数。也可以是 0 到 1 之间的数字,在这种情况下,我们可以使用 sigmoid 函数。或者 0 和∞之间的一个数,在这种情况下,我们可以使用整流器线性单元(ReLU) 功能。最后,还可以要求 Squid 为相同的输入给出多个分数,每个分数基于不同的标准在 0 到 1 之间。在这最后一种情况下,我们可能会对将所有分数相加为 1 感兴趣,对于这个任务来说, softmax 函数将是理想的。

思维导图 1:激活功能

选择取决于任务和最适合您的输出间隔。利用权重 𝑤 和偏差 𝑏 从输入向量𝑎计算 sigmoid 激活𝑎′的示例:

等式 1:乙状结肠活化

等式 2: sigmoid 函数

术语:

  • 看到输入向量在等式 1 中用 𝑎 表示,而在 z=𝑤x+𝑏.中用 x 表示,可能会令人困惑原因是输入层中的节点也被称为激活。在多层感知器的情况下,有两层以上,每一层都被认为是下一层的输入层。
  • 权重和偏差被认为是𝑎′.的参数可以将权重和偏差合并成一个参数向量。这可以通过在输入向量中预先加上 1,并在最初只包含权重的向量中预先加上偏差来实现。

关于激活函数的注释:因为仿射函数是线性的,所以它们不能表示非线性数据集。由于激活函数引入的非线性,神经网络被视为通用函数逼近器

训练感知器

我们对朋友鱿鱼的产量不满意。它运行的参数似乎是随机的。果然,偏差和权重已经初始化为:

我们想训练鱿鱼获得更好的味道。我们对准确口味的标准是一个向量 y ,包含我们的配料数据集中每一行的实际分数。将根据 y. 中的分数对 Squid 的性能进行评估

评估 Squid 性能的目的是测量其相对于目标的误差 y. 有不同的函数来计算该误差:

  • 均方误差(MSE): 如果任务是回归并且数据集不包含离群值,这是一个不错的选择。
  • 绝对平均误差(AME): 如果任务是回归并且数据集包含异常值,这是一个不错的选择。
  • ****胡伯损失:中小企业和 AME 的组合
  • ****交叉熵(对数损失):如果任务是分类,这是一个很好的选择:感知机的输出是一个概率分布。

思维导图 2:成本函数

为了评估我们的感知器,我们将使用均方误差函数:

等式 3:均方误差

训练是通过调整参数 wb 来最小化误差𝐶。最形象化的比喻是,当天太黑看不见的时候,你在一座山上试图下山回家。下方的 Home down 代表最小的误差𝐶。计算 MSE 的平方根,就可以得到你和家之间的直线距离。然而,知道这个距离对你在黑暗中没有任何帮助。相反,你想知道的是你下一步的方向。

3D 世界中的方向包括三个坐标 x、y 和 z。因此问题是“家在哪里?”必须相对于 x、y 和 z 来回答。同样,问题“最小误差𝐶在哪里?”必须根据参数 wb 进行回答。这些方向的数学表示是𝐶.的梯度更具体地说,𝐶: -∇𝐶.的负梯度

∇𝐶是一个向量,包含 c 对每个参数的所有偏导数。对于 MSE,我们从推导等式 3 开始:

等式 MSE 的梯度等于层 L 的激活减去 y

我们仅仅推导了 MSE,在得到𝐶对参数的偏导数之前,我们还有一些工作要做。在等式 4 中,𝑎取决于激活函数的输出。在 sigmoid 激活的情况下,𝑎等价于等式 1 中的𝑎′。接下来是𝐶相对于 z 的梯度(回想一下 z=𝑤x+𝑏 ):

等式 5:C相对于 z 的梯度是 C 相对于 a 的梯度与 z 的 s 形导数的的乘积****

等式 5 令人生畏,直到您在 Python 代码中看到它的对等物

我们有𝐶相对于 z 的梯度。由于 z 中的偏差乘以 1,C 相对于偏差的偏导数为:

等式 6:C相对于 b的偏导数****

并且由于权重乘以输入 x,C 相对于权重的偏导数为:

等式 7:C相对于 w** 的偏导数**

有了成本𝐶对参数的偏导数,我们现在就可以知道下一步回家的方向了。现在我们需要知道我们应该走多远。选择一个好的步长很重要。如果你的步子太窄,你将无法跳过你前进道路上的障碍。如果你的脚步太宽,你可能会越过下面的整个城镇,最终到达另一座山。一个好的步长介于两者之间,可以通过将偏导数(等式 6 和 7)乘以一个选定值来计算,该选定值称为学习速率eta : 𝜂

现在我们可以走下山坡了。这相当于更新我们的坐标/参数:

等式 8:更新偏差

等式 9:更新权重

这就结束了梯度下降:在更新参数之前计算下一步的方向和大小的过程。通过梯度下降,我们可以训练鱿鱼获得更好的味道。我们通过让 Squid 以一些输入为食并使用等式 1 输出一个分数来做到这一点:这被称为前馈。分数作为𝑎代入方程 4,其结果作为𝐶相对于𝑎的梯度代入方程 5。然后,我们在等式 6 中计算𝐶相对于 z 的梯度。最后,我们计算𝐶相对于参数的梯度,并更新 Squid 的初始随机参数。这个过程被称为反向传播,因为它将误差从输出层反向传播到输入层。

梯度下降是迭代的。当满足以下条件之一时,它会停止:

  • 已达到定义的最大迭代次数。
  • 梯度达到 0 或接近 0 的某个定义值。
  • 验证错误已达到最小值。这叫早停。

思维导图 3:梯度下降

将碎片拼在一起

感知器的完整实现可以从我们看到的代码片段中构建。为了不让这篇文章被代码淹没,这里有一个链接指向一个感知器的完整实现。

为了看到我们的感知机在工作,让我们做一个非常简单的数据集。我们将随机生成包含一百行整数的两列。然后,我们将创建第三列来存储我们的标签。标签将等于第一列加上第二列值的一半。

生成我们的数据集

我们知道,为了达到目标,我们的感知器必须从随机参数开始,并优化它们,使偏差等于 0,第一个权重等于 1,第二个权重等于 0.5。让我们来测试一下:

太好了!我们的感知机已经成功优化了所有参数。

在 Scikit-learn 中

我们从最基本的感知机开始。因为它正在执行回归,所以不需要激活函数。到目前为止,它所做的只是随机梯度下降。在 Scikit-learn 中,这可以通过使用 SGDRegressor 类来实现。虽然 Scikit-learn 包含一个感知器类,但它并不服务于我们当前的目的,因为它是一个分类器,而不是回归器。

检验 SGDRegressor 优化参数前的训练

可视化梯度下降

我们可以画出我们的感知器采取的步骤,看看它达到理想参数的路径。下面是使用 Matplotlib 绘制梯度下降的代码:

使用 Matplotlib 可视化梯度下降

前面代码的输出:使用 Matplotlib 可视化梯度下降

这是从不同的角度和使用 Plotly 的同一个情节:

使用 Plotly 可视化梯度下降

前面代码的输出:使用 Plotly 可视化的梯度下降

我想让你看到我们的感知机的下降导致它回家。但这不是最直的路,远非如此。我们引入了对功能缩放的改进。

特征缩放

通常情况下,机器学习算法在缩放数字输入的情况下表现更好。如果没有缩放,梯度下降需要更长时间才能收敛。在 2D 的世界里,你仍然试图在黑暗中下山回家,你需要减少你离家的垂直和水平距离。如果两个距离在不同的范围内,您将花费更多的时间来缩短范围较大的距离。

例如,如果你需要减少的垂直距离是以千为单位,而水平距离是以个为单位,那么你的下降主要是向下爬。当你接近最小水平距离时,你仍然需要减少垂直距离。

将这两个距离缩放到相等的范围会使您的脚步同时影响这两个距离,这使您能够沿着直线直接向家行进。

说明比例对梯度下降的影响的简单图形

两种最常见的数据缩放方式是规范化标准化。我们将实现这两个方法,并可视化它们对梯度下降的影响。

正常化

也被称为最小-最大缩放,是一种将数据压缩到 0 和 1 之间的方法:

等式 10:最小-最大缩放或归一化

使用 Numpy 标准化我们的训练数据集

sci kit-learn 中的标准化:

使用 Scikit-learn 标准化我们的训练数据集

标准化

也称为 z 分数归一化,是一种将数据集中在 0 附近,标准差等于 1 的方法。𝜇是平均值,𝜎是标准差:

等式 11: Z 分数标准化或规范化

使用 Numpy 标准化我们的训练数据集

sci kit-learn 中的标准化:

使用 Scikit-learn 标准化我们的训练数据集

思维导图 4:功能扩展

特征缩放对梯度下降的影响

为了研究特征缩放的效果,我们将再训练两个感知器。目的是比较缩放和不缩放时梯度下降中参数的收敛性。

我们的第一个感知机是在未缩放的数据集上训练的。第二个将在标准化数据上训练。第三个将接受标准化数据的训练。

用标准化数据训练两个感知机

我们现在可以想象我们的三个感知器所采取的路径。下面的代码使用 Plotly:

可视化三个梯度下降

上一段代码的输出:点击此处与图形交互

在缩放数据上训练的感知机采取了更直接的路径来收敛。直接路径使它们的下降速度更快,步幅更宽(可能通过增加学习速率eta实现),步数更少(可能通过减少迭代次数epochs)。

概括起来

思维导图 5:概念总结

参考

A.Géron,使用 Scikit-Learn、Keras 和 TensorFlow 进行动手机器学习 (2019)

I. Goodfellow,Y. Bengio 和 a .库维尔,深度学习 (2016)

米(meter 的缩写))尼尔森,神经网络和深度学习 (2019)

米(meter 的缩写))胺,神经网络概述: Jupyter 笔记本和游乐场

米(meter 的缩写))胺,神经网络概述: 代码片段

XMind,思维导图软件

posted @ 2024-10-14 11:49  绝不原创的飞龙  阅读(184)  评论(0)    收藏  举报