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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

ELMo:上下文语言嵌入

原文:https://towardsdatascience.com/elmo-contextual-language-embedding-335de2268604?source=collection_archive---------4-----------------------

使用 ELMo 的深度语境化语言表示创建语义搜索引擎,以及为什么在 NLP 中语境就是一切

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Semantic sentence similarity using the state-of-the-art ELMo natural language model

本文将探索自然语言建模的最新进展;深层语境化单词嵌入。重点在于如何使用最先进的 ELMo 模型来检查给定文档中的句子相似性,并创建一个简单的语义搜索引擎。完整的代码可以在 Colab 笔记本这里查看。

语境在自然语言处理中的重要性

众所周知,语言是复杂的。上下文可以完全改变一个句子中单个单词的意思。例如:

他踢了桶一脚。

我还没有划掉我的清单上的所有项目。

水桶装满了水。

在这些句子中,虽然单词 bucket 总是相同的,但它的意思却非常不同。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Words can have different meanings depending on context

虽然我们可以很容易地破译语言中的这些复杂性,但创建一个能够理解给定环境文本中单词含义的不同细微差别的模型是困难的。

正是由于这个原因,传统的单词嵌入(word2vec、GloVe、fastText)有所欠缺。每个单词只有一种表达方式,因此它们不能捕捉每个单词的意思是如何根据周围的环境而变化的。

介绍 ELMo 深层语境化的词汇表征

输入 ELMo。它由 AllenNLP 在 2018 年开发,超越了传统的嵌入技术。它使用深度的双向 LSTM 模型来创建单词表示。

ELMo 不是一个单词及其对应向量的字典,而是在单词使用的上下文中分析单词。它也是基于字符的,允许模型形成词汇表外单词的表示。

因此,这意味着 ELMo 的使用方式与 word2vec 或 fastText 完全不同。ELMo 没有在字典中“查找”单词及其相应的向量,而是通过将文本传递给深度学习模型来动态创建向量。

一个可行的例子,ELMo 的实际使用不到 5 分钟

我们开始吧!我将在这里添加主要的代码片段,但是如果您想要查看完整的代码集(或者确实想要通过点击笔记本中的每个单元格来获得奇怪的满足感),请在这里查看相应的 Colab 输出

根据我最近的几篇帖子,我们将使用的数据是基于现代奴隶制的回报。这些都是公司的强制性声明,以传达他们如何在内部和供应链中解决现代奴隶制问题。在这篇文章中,我们将深入探究 ASOS 的回归(一家英国在线时装零售商)。

如果你有兴趣看到在这个数据集上进行的 NLP 实验的迷你系列中的其他帖子,我在本文的结尾提供了这些的链接。

1。获取文本数据,清理并标记

令人惊讶的是,使用 Python 字符串函数和 spaCy 做到这一点是多么简单。这里我们通过以下方式进行一些基本的文本清理:

a)删除换行符、制表符、多余的空格以及神秘的“xa0”字符;

b)使用空格将文本分成句子。sents 的迭代器。

ELMo 既可以接收句子字符串列表,也可以接收列表(句子和单词)列表。这里我们选择了前者。我们知道 ELMo 是基于字符的,因此对单词进行标记不会对性能产生任何影响。

nlp = spacy.load('en_core_web_md')#text represents our raw text documenttext = text.lower().replace('\n', ' ').replace('\t', ' ').replace('\xa0',' ') #get rid of problem chars
text = ' '.join(text.split()) #a quick way of removing excess whitespace
doc = nlp(text)sentences = []
for i in doc.sents:
  if len(i)>1:
    sentences.append(i.string.strip()) #tokenize into sentences

2。使用 TensorFlow Hub 获取 ELMo 模型:

如果您还没有接触过 TensorFlow Hub,它可以为 TensorFlow 提供大量预先训练好的模型,从而节省大量时间。对我们来说幸运的是,其中一个模特是埃尔莫。我们只需要两行代码就可以加载一个完全训练好的模型。多么令人满意…

url = "[https://tfhub.dev/google/elmo/2](https://tfhub.dev/google/elmo/2)"
embed = hub.Module(url)

为了在 anger 中使用这个模型,我们只需要多几行代码来将它指向我们的文本文档并创建句子向量:

# This tells the model to run through the 'sentences' list and return the default output (1024 dimension sentence vectors).
embeddings = embed(
    sentences,
    signature="default",
    as_dict=True)["default"]#Start a session and run ELMo to return the embeddings in variable x
with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  sess.run(tf.tables_initializer())
  x = sess.run(embeddings)

3。使用可视化来检测输出

令人惊讶的是,观想作为一种更好地理解数据的方式经常被忽视。图片说明千言万语,我们将创建一个一千字的图表来证明这一点(实际上是 8511 个字)。

这里,我们将使用主成分分析和 t-SNE 将 ELMo 输出的 1024 个维度减少到 2 个,以便我们可以查看模型的输出。如果你想了解更多,我在文章的最后提供了关于如何实现这一点的进一步阅读。

from sklearn.decomposition import PCApca = PCA(n_components=50) #reduce down to 50 dim
y = pca.fit_transform(x)from sklearn.manifold import TSNEy = TSNE(n_components=2).fit_transform(y) # further reduce to 2 dim using t-SNE

使用神奇的 Plotly 库,我们可以在任何时候创建一个美丽的,互动的情节。下面的代码显示了如何呈现我们的降维结果,并将其连接到句子文本。根据句子的长度,还添加了颜色。当我们使用 Colab 时,最后一行代码下载 HTML 文件。这可以在下面找到:

[## 句子编码

交互式句子嵌入

drive.google.com](https://drive.google.com/open?id=17gseqOhQl9c1iPTfzxGcCfB6TOTvSU_i)

创建它的代码如下:

import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplotinit_notebook_mode(connected=True)data = [
    go.Scatter(
        x=[i[0] for i in y],
        y=[i[1] for i in y],
        mode='markers',
        text=[i for i in sentences],
    marker=dict(
        size=16,
        color = [len(i) for i in sentences], #set color equal to a variable
        opacity= 0.8,
        colorscale='Viridis',
        showscale=False
    )
    )
]
layout = go.Layout()
layout = dict(
              yaxis = dict(zeroline = False),
              xaxis = dict(zeroline = False)
             )
fig = go.Figure(data=data, layout=layout)
file = plot(fig, filename='Sentence encode.html')from google.colab import files
files.download('Sentence encode.html')

探索这种可视化,我们可以看到 ELMo 在根据语义相似性对句子进行分组方面做了出色的工作。事实上,该模型的有效性令人难以置信:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Download the HTML for yourself (link above) to see ELMo in action

4。创建语义搜索引擎:

现在我们确信我们的语言模型运行良好,让我们将它应用到语义搜索引擎中。这个想法是,这将允许我们通过搜索查询的语义接近度而不是关键字来搜索文本。

这实际上很容易实现:

  • 首先,我们获取一个搜索查询,并对其运行 ELMo
  • 然后,我们使用余弦相似度将它与文本文档中的向量进行比较;
  • 然后,我们可以从文档中返回与搜索查询最接近的“n”个匹配项。

Google Colab 有一些很棒的特性来创建表单输入,非常适合这个用例。例如,创建一个输入就像在变量后添加 #@param 一样简单。下面显示了字符串输入的情况:

search_string = "example text" #@param {type:"string"}

除了使用 Colab 表单输入,我还使用了“IPython.display.HTML”来美化输出文本,并使用一些基本的字符串匹配来突出显示搜索查询和结果之间的常见单词。

让我们来测试一下。让我们看看 ASOS 在他们现代奴隶制的回归中,在道德准则方面做了些什么:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A fully interactive semantic search engine in just a few minutes!

这太神奇了!匹配超越了关键词,搜索引擎清楚地知道‘伦理’和道德是密切相关的。我们发现符合诚信准则以及道德标准和政策的内容。两者都与我们的搜索查询相关,但不直接基于关键字链接。

我希望你喜欢这篇文章。如果您有任何问题或建议,请留下您的意见。

延伸阅读:

以下是我在 NLP 和探索公司现代奴隶制回归的迷你系列中的其他帖子:

[## 使用无监督的机器学习清理您的数据

清理数据不一定是痛苦的!这篇文章是一个如何使用无监督机器学习的快速例子…

towardsdatascience.com](/clean-your-data-with-unsupervised-machine-learning-8491af733595) [## 增压词向量

一个在你的 NLP 项目中提升快速文本和其他单词向量的简单技术

towardsdatascience.com](/supercharging-word-vectors-be80ee5513d)

为了找到更多关于降维过程的信息,我推荐下面的帖子:

[## 在 Python 中使用 PCA 和 t-SNE 可视化高维数据集

任何与数据相关的挑战的第一步都是从探索数据本身开始。这可以通过查看…

medium.com](https://medium.com/@luckylwk/visualising-high-dimensional-datasets-using-pca-and-t-sne-in-python-8ef87e7915b)

最后,要想了解更多关于最新语言模型的信息,下面的内容值得一读:

http://jalammar.github.io/illustrated-bert/

雪花数据仓库中的 ELT 数据流水线——使用流和任务

原文:https://towardsdatascience.com/elt-data-pipelining-in-snowflake-data-warehouse-using-streams-and-tasks-ae6eb7c083de?source=collection_archive---------5-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在我之前的帖子中:

使用 Azure Portal Web UI 为雪花数据仓库在 Azure Blob 存储上构建 Snowpipe

https://medium . com/@ qiuyujx/building-snow pipe-on-azure-blob-storage-using-azure-portal-we b-ui-for-snow flake-data-warehouse-f0cdd 7997250

Snowpipe 被引入用于自动发现云存储(例如 Azure Blob 存储)中的新数据文件,然后将数据加载到某个表中。

Snowpipe 是实现上述目的的一个非常方便的工具。然而,Snowpipe 本身只被认为是 ELT 的“E”(提取),因为在 Snowpipe 创建语句中只允许使用COPY INTO命令。换句话说,我们可以用它轻松实现以下目标:

  • 加载不同格式的数据文件,如 CSV、JSON、XML、Parquet 和 ORC
  • 采用和调整数据源以获得更好的兼容性,比如剥离 JSON 的外部数组和 XML 的外部元素
  • 更改列名
  • 更改列顺序
  • 省略列
  • 将数据/时间字符串解析为数据/时间对象

因此,出于以下原因,数据流水线的其余部分需要流和任务:

  1. 一些数据转换可能是必要的,比如数字计算和字符串连接。
  2. 数据源不是典型的三范数格式,需要根据一定的关系加载到多个表中。
  3. ELT 作业可能不限于追加表,还包括更复杂的需求,如要实现的 SCD(渐变维度)。

因此,我们不得不在雪花中涉及其他对象来完成数据管道。

雪花溪流

雪花流对象用于跟踪对表的任何更改,包括插入、更新和删除,然后可以被其他 DML 语句使用。steam 对象的一个典型用法是 CDC(变更数据捕获)

标准视频点播附加流

我们可以在 Snowflake 中定义两种类型的流,标准流和仅附加流。标准流将捕获对表的任何类型的更改,而仅追加流只捕获插入的行。前者可用于一般目的,而后者可用于典型的 ELT 模型中,当我们只对摄取的新行感兴趣时。

例如,我们可以使用 Snowpipe 从云存储中的 CSV 文件自动获取数据,并复制到临时表中。然后,一个流将捕获这个批量插入动作,并记录这些新行的偏移量

流偏移

雪花流在物理上不存储、包含或复制任何数据。它只是在当前时间拍摄跟踪表的快照(例如,在创建流时),然后流会将对此表所做的每个更改记录为附加元数据。表格的前一版本和当前版本之间的差异称为偏移

当其他 DML 语句使用流的偏移量时,偏移量将被重置,并且流将所使用的数据视为表的“先前”版本。典型的消耗流偏移量的 DML 语句是INSERT INTO ... SELECT ... FROM STREAM

以下是流消费流的一个示例:

  1. 假设一个表中已经有一百万行。我们在这个表上创建一个流,这个流没有偏移量,因为这个表的当前版本是快照。
  2. 假设有 1000 行从 Snowpipe COPY INTO语句插入到表中。
  3. 该流将这 1000 行记录为其偏移量。
  4. 假设现在我们从流中读取这 1000 行,并将它们插入到另一个表中。
  5. 该流现在将没有偏移量,因此它将是空的,因为我们已经消耗了先前的偏移量。

很明显,雪花流是为英语教学过程设计的。例如,我们有一个高频率的数据被接收到数据库中,我们每 5 分钟消耗一次数据。该流将保证我们每次使用新数据时没有遗漏和重叠。这确实是一个在其他数据库管理系统中实现起来很复杂的逻辑,或者我们可能需要使用额外的编程语言来实现这一点。

流列

因为 stream 实际上是原始表的快照,所以原始表中的所有列也可以在 stream 中访问。例如,如果原始表有 3 列名为col1col2col3,那么我们可以简单运行

SELECT col1, col2, col3
FROM the_stream;

检索此流中的偏移量。

此外,还有 3 个额外的列是专门针对流对象的元数据:

  • METADATA$ACTION表示该行的更改类型。可以是INSERT也可以是DELETE。请注意,没有“更新”操作。一行的更新将由两行表示,一行是前一行的DELETE,另一行是新行的INSERT。您会发现这非常方便,因为通过比较这两行,您可以在流中获得关于更新了哪些特定字段的信息。
  • METADATA$ISUPDATE表示该行是否因更新而生成。这个列是一个额外的指示器,它允许您获得所有带有INSERTDELETE的行,但实际上是因为更新而生成的。
  • METADATA$ROW_ID是特定行的唯一 ID。即使该行被更新,它也不会改变,并且在将来的任何进一步的偏移更新中保持不变。

这是一张来自官方文档的图片,非常清晰地展示了数据流。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image courtesy: https://docs.snowflake.net/manuals/user-guide/streams.html

雪花任务

雪花任务就是这样一种对象,它可以安排 SQL 语句作为重复事件自动执行。

是的,我对每个任务都使用“an”SQL 语句。目前,这是雪花任务的一个限制。希望在未来的更新中,它将支持事务适当的BEGINCOMMIT关键字,以便我们可以在一个事务中执行一系列 SQL 语句,并利用任务来调度该事务。

尽管有这样的限制,雪花确实提供了多 SQL 语句调度的方法,这被称为任务树。顾名思义,我们可以在一个树形结构中定义多个任务。几个小贴士:

  • 一个任务可以有多个任务作为其子任务,所以子任务将在父任务完成时执行。
  • 一个任务只能有一个父任务。
  • 因此,任务树实际上只是一棵树,而不是 DAG。所以,你可以考虑它可以做“fork”,但是没有“join”。

下面是一个简单任务树的图表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image courtesy: https://docs.snowflake.net/manuals/user-guide/tasks-intro.html

触发任务

触发任务有两种方式,一种是通过定义计划,另一种是通过另一个任务触发。

雪花支持两种类型的任务调度定义,“CRON”表达式和时间间隔。CRON 表达式可以定义任务将被触发的确切日期/日期/时间,它非常强大,可以实现任何简单到复杂的需求,例如

  • 在每天的特定时间运行任务
  • 在一周中某一天的某个时间运行任务
  • 支持时区
  • 支持夏令时

关于 CRON 表达式的具体语法,请访问这个免费网站进行详细的解释和实验:

[## 免费在线克隆表达式生成器和描述-FreeFormatter.com

使用易于使用的在线界面生成 quartz cron 表达式。将 cron 表达式转换成可读文本…

www.freeformatter.com](https://www.freeformatter.com/cron-expression-generator-quartz.html)

另一种调度定义的方法要简单得多,就是简单的定义时间间隔。例如,如果我希望任务每 5 分钟触发一次,那么就这样定义它:

SCHEDULE = '5 MINUTE'

触发任务的另一种方式是定义父任务,这被认为是构建任务树。例如,如果我们想在TASK1结束时触发TASK2,只需简单定义:

CREATE TASK TASK2
...
AFTER "TASK1"
AS
<SQL>

有条件的任务

可以通过“WHEN”子句用条件来定义任务,该子句用于决定是否应该执行该任务。

这是一个非常方便的功能。例如,如果您用您的“根任务”设置一个条件,当条件不满足时,整个任务树将根本不会运行。

此外,如果这种“条件测试”发生在雪花的云服务层(使用元数据而不是对表的 SQL 查询),则这种条件测试的成本为零,因此如果条件不满足,则没有成本。

通过流使用任务

雪花任务和流被一起用来构建数据管道是非常常见的。一个非常典型的使用模式是:

  1. Snowpipe 将原始数据加载到临时表中。
  2. 雪花流是在 staging 表上创建的,因此被摄取的新行将被记录为偏移量。
  3. 然后,雪花任务通过一些 DML 语句消耗流偏移量,以进一步将数据加载到生产表中,可能包括一些更复杂的转换。
  4. 在实践中,会有一个任务树来执行多个 SQL 语句,以便执行复杂的转换,有时会将转换后的条目填充到多个生产表中。
  5. 一些中间表可能需要由任务树中的任务创建。
  6. 在任务树的最后可能会有一些任务来清理一些临时表。

我们已经介绍了需要集成 Snowpipe 和 Stream 的典型场景。现在,对于流和任务,还有一个非常典型的使用模式,那就是系统变量SYSTEM$STREAM_HAS_DATA

具体来说,变量SYSTEM$STREAM_HAS_DATA将返回一个布尔值,表明在可消费的流中是否存在偏移。因此,我们可以简单地将这个条件放在任务定义的“WHEN”子句中。因此,如果流中没有新内容,任务将不会被执行。例如:

CREATE TASK mytask1
  WAREHOUSE = mywh
  SCHEDULE = '5 minute'
WHEN
  SYSTEM$STREAM_HAS_DATA('MYSTREAM')
AS
  INSERT INTO ... ;

在这个例子中,只有当流“MYSTREAM”中存在消耗性偏移时,才会执行任务“mytask1”。否则,将跳过该任务,并在 5 分钟后再次检查状况。

还有一个提示

请记住,默认情况下,刚刚创建的任务将被暂停。有必要通过如下方式“改变”任务来手动启用此任务:

ALTER TASK mytask1 RESUME;

未来作品

本文从理论上介绍了雪花流和任务。画出了使用 Snowpipe -> Stream -> Task 构建 ELT 数据管道的概貌。在下一部分中,我将使用一个真实的示例数据源来构建 ELT 数据管道,使用这些雪花组件和必要的 SQL 脚本演示,这将更具实践性。

[## 通过我的推荐链接加入灵媒-陶

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@qiuyujx/membership)

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)

资源

雪花溪流官方文档:【https://docs.snowflake.net/manuals/user-guide/streams.html

雪花任务官方文档:
https://docs . snow flake . net/manuals/user-guide/Tasks-intro . html

免费在线 CRON 表达式生成器:
https://www . free formatter . com/CRON-expression-generator-quartz . html

阐释强化学习中的策略迭代——杰克的租车问题

原文:https://towardsdatascience.com/elucidating-policy-iteration-in-reinforcement-learning-jacks-car-rental-problem-d41b34c8aec7?source=collection_archive---------12-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

[1]: Generalized Policy Iteration

在这篇博文中,我将尝试通过使用强化学习中的策略迭代算法来解决 Jack 的租车问题,从而阐明该算法。这个问题和它的变体分别在萨顿和巴尔托的书(强化学习:导论,第二版)中的例子 4.2 和练习 4.5 中给出。

问题陈述

杰克为一家全国性的汽车租赁公司管理着两个地点。每天,都会有一定数量的客户来到每个地点租车。如果杰克有一辆车,他就把它租出去,国家公司给他 10 美元。如果他在那个位置没有车,那么生意就没了。汽车在归还的第二天就可以出租了。为了帮助确保汽车在需要的地方可用,Jack 可以在两个地点之间连夜移动汽车,每移动一辆汽车的费用为 2 美元。

我们假设每个位置请求和返回的汽车数量是一个泊松随机变量。回想一下,如果 X 是泊松随机变量,那么

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

假设第一个和第二个位置的租赁请求的λ是 3 和 4,返回请求的λ是 3 和 2。

为了稍微简化问题,我们假设每个位置不能超过 20 辆汽车(任何额外的汽车都返回给全国性的公司,因此从问题中消失),并且在一个晚上最多可以将五辆汽车从一个位置移动到另一个位置。我们将贴现率γ设为 0.9,并将其公式化为一个连续的有限马尔可夫决策过程,其中时间步长为天,状态为一天结束时每个位置的汽车数量,而行动为一夜之间在两个位置之间移动的汽车净数量。

但是解决这个问题意味着什么呢?

解决这个问题意味着解决两件事,首先,杰克应该在一夜之间在每个地点之间移动多少辆车,以最大化他的总期望回报,即,在给定的情况(状态)下,他的策略(政策)应该是什么;其次,如果杰克知道这个策略,他如何比较哪些情况比其他情况更好(价值)?

初始设置

让我们先用代码写出我们知道的最初的东西。从问题中,我们知道杰克可以获得两种类型的奖励,第一种是他租车时的 10 美元奖励,第二种是他从一个位置移动到另一个位置的每辆车的-2 美元奖励(注意,后一种奖励是负的)。

现在我们定义一个 poisson_ class,它取一个参数λ,计算对应的概率质量函数。它有两个数据成员α和β,表示 pmf 值大于ε(此处为 0.01)的 n 值的区间[α,β]。我们将ε以下的 pmf 值设置为零,然后对结果分布进行归一化。

例如,对于λ = 3,数据成员α、β和 val 的值为:

策略迭代算法

在我们继续之前,为了确保所有的读者都在同一页上,让我们快速修改一下这里的术语价值和策略的含义。

在我们的汽车租赁示例中,系统在任何时候的状态都是一对两个数字,第一个和第二个位置的汽车数量。给定一个状态,杰克必须选择一个动作,即他可以从第一个位置移动到第二个位置的汽车数量,反之亦然。根据问题,可以在-5 到+5 之间变化,其中+n 代表 Jack 将 n 辆车从第一个位置移动到第二个位置。

策略是从状态到行动的映射,例如,给定一个状态,Jack 应该在一夜之间移动多少辆车。现在,假设杰克有某个策略π,那么给定这个π,一个状态(比如 s)的值就是杰克从 s 出发,之后跟随π时会得到的期望回报。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

[1]: The Policy Iteration Algorithm

如上图所示,策略迭代算法由三部分组成。让我们在解决租赁问题的背景下分别讨论这些组件。

第一部分是初始化。如上图所示,我们任意初始化值和策略矩阵。将它们初始化为零也可以。请注意,给定一个策略,我们为每个状态定义一个值,因为我们的状态是一对两个数字,其中每个数字取 0 到 20 之间的值,因此我们用形状矩阵(21 x 21)来表示值。策略取一个状态,输出一个动作;因此,它也可以用相同形状的矩阵来表示。

第二个组成部分是政策评估。通过政策评估,我们的意思是遵循这个政策,任何国家的价值应该是什么。如上所述,给定一个政策π,一个状态(比如 s)的值就是杰克从 s 出发,之后跟随π时会得到的期望回报。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这种与状态值相关联的期望概念可以写成上图所示的形式,由此可以推导出贝尔曼方程,如图所示。

这个贝尔曼方程形成了在策略评估组件中显示的值更新的基础。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Value Update

在许多这样的更新之后,V(s)收敛到一个几乎满足(最多有一些θ误差)贝尔曼方程的数,因此代表状态 s 的值。

第三个组成部分是政策改进。给定一个状态(比如 s),我们指定π(s)等于使期望报酬最大化的动作。我们说,当任何状态下的行动最大化步骤都没有引起策略的变化时,策略变得稳定。

我们循环运行策略评估和改进组件,直到策略变得稳定。

结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图以热图的形式显示了通过评估和改进后的策略。回想一下,策略由包含[-5,5]范围内的动作值的矩阵表示。

给原来的租赁问题增加了非线性

让我们看看,如果我们在上面的问题中加入一些非线性因素,会发生什么:

  1. Jack 在第一个地点的一名员工每天晚上乘公交车回家,并且住在第二个地点附近。她很乐意免费接送一辆车到第二个地点。每增加一辆车仍然要花 2 美元,所有向相反方向移动的车也是如此。
  2. 此外,Jack 在每个位置都有有限的停车位。如果超过 10 辆汽车在一个地点过夜(在任何汽车移动之后),那么使用第二个停车场必须产生 4 美元的额外费用(与有多少辆汽车停在那里无关)。

可以很容易地添加这些条件来修改原始代码。如果需要,我们将有一个额外的奖励-第二个停车场 4 美元(注意,这个奖励是负的)。

生成的策略(通过评估和改进)如下图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论

我们使用动态规划解决了上述问题。我们存储了中间值和策略矩阵,并在策略评估和改进功能中使用它们。然而,为了使用贝尔曼更新,我们需要知道环境的动态,就像我们在租赁示例中知道奖励和下一个状态的概率一样。如果只能从底层分布中采样,不知道分布本身,那么可以用蒙特卡罗方法来解决相应的学习问题。

Github 库:https://github.com/thunderInfy/JacksCarRental

参考

[1]萨顿和巴尔托(2017 年)。强化学习:导论。剑桥,麻省理工学院出版社

[2] S. David 关于通过动态规划进行规划的讲座(【https://www.youtube.com/watch?v=Nd1-UUMVfz4】T2)。

电子邮件自动化、分析和可视化

原文:https://towardsdatascience.com/email-automation-analytics-and-visualization-53b022e0f9a0?source=collection_archive---------8-----------------------

使用 Python 的 Imapclient、Smtplib、Pandas 和 Matplotlib 库的详细教程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image by ribkhan on Pixabay

介绍

阅读、回复甚至整理电子邮件往往会耗费大量时间。虽然今天有许多电子邮件客户端竭尽全力使这方面的生活变得更容易,但如果能够以编程的方式执行与电子邮件相关的任务,这将非常有用。让我们考虑一个这种方法可以派上用场的场景——电子邮件混乱。现在,可以说互联网上充斥着如何减少电子邮件混乱的建议。虽然所有这些技巧都有可能帮助你今后更有效地使用你的电子邮件,但如果目前你的收件箱已经到了无法恢复的地步,手动清理几乎是不可能的,那该怎么办?一个典型的例子是——我妻子的收件箱里有来自 300 多个不同发件人的 35000 多封电子邮件。她确信这些邮件大多与营销有关,但她认为,单独退订这些邮件太费力了,这也是有道理的。本文的第一部分讨论了这个问题,并解释了如何使用 python 的 imapclient 和 smtplib 库发送、检索、分类、删除和取消订阅电子邮件。

另一方面,让我们假设你是一个电子邮件组织忍者,完全控制着你的收件箱,一丝不苟地给每一封邮件贴上标签并归档。你可能会对一些关于你的电子邮件的统计数据感兴趣,比如谁给你发的电子邮件最多,你的流量是多少,或者你典型的电子邮件回复时间是多少。这篇文章的第二部分正是为了这个目的,演示了如何使用 Pandas 分析电子邮件数据,以及如何使用 Matplotlib 创建可视化工具

请注意,虽然这里使用 Gmail 来说明各种概念,但代码可以通过一些小的修改与任何电子邮件客户端一起工作,因为大多数情况下只使用通用 Python 库,而不是客户端特定的 API。此外,请记住,这里显示的教程只是这些 Python 电子邮件库所能实现的一小部分。所以我强烈建议您以此为起点,然后扩展它以满足您的需求。我们将只看运行这个项目所需的关键代码片段。你可以在我的 GitHub 库中找到完整的代码。

第 1 部分:自动化

步骤 1:连接到服务器并登录

在使用 Python 访问您的电子邮件之前,您需要更改您的 google 帐户设置,以允许访问不太安全的应用程序。否则,google 将阻止您的代码尝试登录该帐户。现在,出于安全原因,我建议在运行完代码后,将该设置改回默认状态。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Less secure app access in Gmail

完成后,我们可以使用该帐户的用户名和密码登录到服务器。在运行时接受您的用户名和密码作为用户输入,而不是硬编码,这总是一个好的做法。

Establishing connection to the IMAP and SMTP servers

IMAP (Internet 邮件访问协议)是一种标准协议,它指定了如何与电子邮件服务器通信以检索邮件。由 RFC3501 定义。Imapclient 是一个 python 第三方库,它在底层使用 python 的标准 imaplib 库,但提供了一个更干净、更易于使用的 API,特别是在解析和错误处理方面。SMTP(简单邮件传输协议)和 Smtplib 相当于发送邮件的 IMAP 和 Imapclient。

导入这些库之后,我们连接到服务器并创建一个 IMAP 对象和一个 SMTP 对象。对于不同的电子邮件服务,这里使用的服务器名称是不同的。根据许多提供商的要求,我们为 IMAP 启用了安全套接字层(SSL)加密,为 SMTP 启用了传输层安全性(TLS)加密。同样,加密类型和端口号取决于提供商。

步骤 2:搜索和检索电子邮件

我们可能希望对多个文件夹执行搜索操作。为此,让我们首先获取可用文件夹的列表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

List of email folders

我们使用 pprint 模块使文件夹列表看起来更易读。您可以看到,用户创建的文件夹和 Gmail 自己的文件夹(技术上来说,是标签)都显示出来了。您可以选择遍历多个文件夹来搜索电子邮件,但是对于本教程,只使用收件箱文件夹。

Searching for emails

这里,我们首先告诉 Python 将内存分配从默认值 10,000 字节增加到 10,000,000 字节。如果没有这一点,万一我们的搜索返回大量的电子邮件,Python 可能会引发一个异常。注意 _MAXLINE 命令属于 Imaplib 库,而不是 Imapclient 库。在下一行中,我们使用 select_folder()方法选择要搜索的文件夹。将 readonly 关键字设置为 true 可防止此文件夹中的邮件被意外删除。

然后我们搜索四个月时间范围内的电子邮件。search()方法接受各种各样的搜索关键字,允许您按发件人、收件人、主题或正文内容、可见、不可见、已回答或未回答的标志等进行搜索。例如,要搜索来自特定发件人的邮件,搜索关键字应为[‘FROM ‘,’ sender@example.com’]。IMAPClient 类的文档包含了更多关于这个的信息。

搜索结果存储在 UIDs 变量中,该变量是符合搜索条件的每封电子邮件的唯一整数 id 列表。这个 ID 稍后将用于检索相应的消息。

步骤 3:对检索到的邮件进行分类

Categorizing emails

一旦我们有了 uid 列表,我们就使用 get_gmail_labels()方法根据它们的标签对邮件进行分类。请注意,这个特殊的方法是专门针对 Gmail 的。要在其他电子邮件客户端实现这一点,我建议循环遍历之前获得的文件夹列表,并基于此进行分类。这里使用的分类完全是任意的,主要是为了说明这个过程。例如,一封邮件可以被分配所有三个标签——“已加星”、“重要”和“收件箱”。此处的代码会将该邮件归入“已加星”类别。

步骤 4:提取消息属性

Extracting email attributes

在这个片段中发生了很多事情。首先,我们创建几个列表,用于保存电子邮件的不同属性。然后,我们遍历 uid 列表,并使用 fetch()方法检索对应于特定 ID 的消息体。当我们使用 pprint()打印 raw_message 的内容时,看起来是这样的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Contents of the raw message

我们可以看到,这打印出了一个嵌套的字典,并且“Body[]”键的内容是一种非常模糊的格式。实际上,它是 RFC 822 T1 格式的,用于 IMAP 服务器。另一个模块 pyzmail——可以用来解析这些原始消息,并将它们转换成 PyzMessage 对象,从这些对象中可以找到“发件人”、“收件人”、“主题”、“正文”等字段。可以很容易得到。Pyzmail 是一个高级库,可以解析 imapclient 下载的电子邮件,并将其转换为简单的字符串值。它本质上掩盖了相当复杂的 MIME 结构和编码/解码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The PyzMessage object

请记住,在某些邮件中,日期的格式可能略有不同。如果你想把它分成日、年、时间等,你需要写适当的代码。get_decoded_header()方法在这里特别有用,因为它可以用来从任何消息头中提取信息。为了理解这里到底发生了什么,我们显示了电子邮件的原始内容,如下所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Displaying the original email contents in Gmail

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Some of the headers in the original message

这些是 get_decoded_header()方法正在访问的头。例如,get_decoded_header('Subject ')将产生与 get_subject()相同的输出。我们将所有这些不同的属性存储在列表中,以便在以后的分析代码中使用它们。

关于列表-取消订阅标题的注意事项—包含此标题并使取消订阅变得简单和一键操作过程被认为是良好的电子邮件实践,但它可能不会出现在所有邮件中。如果没有链接,这里给出的逻辑将不起作用。这篇是一篇很棒的文章,详细解释了这一点。我们这里的目的是提取退订链接,然后使用其中的信息自动退订不必要的电子邮件。我们只关心那些带有退订邮件地址的退订链接,而不关心那些带有需要点击才能退订的 http 链接的链接。

最后,请记住,检索消息和提取不同的属性不是一个超快的过程。处理大约 1000 封邮件大约需要 2-3 分钟。

步骤 5:删除和取消订阅

提取了各种电子邮件属性后,我们可以根据使用这些属性构建的一个或多个条件删除多封邮件或取消订阅邮件列表。例如,我们可以选择删除过去六个月收到的所有邮件,或者退订来自特定发件人的电子邮件或主题中包含特定单词的电子邮件。

Deleting messages

在上面的代码片段中,我们在收件箱中搜索主题中包含单词“Best Buy”的所有邮件,并获取它们的唯一 id。然后,我们使用 delete_messages()方法将所有这些消息标记为\Deleted,并使用 expunge()方法删除它们。请注意,有些客户端会在没有等待 expunge()调用的情况下删除邮件。由于 Gmail 标签的设置方式,这里的情况略有不同。我们将标签\Trash 添加到邮件中,以便立即将它们移动到 Trash 文件夹中。如果我们遵循前面的方法,邮件将被存档,但不会被删除。

自动退订需要一些额外的代码,因为它涉及到发送电子邮件到从退订链接提取的地址。必须进行一些解析工作,从链接的“mailto”部分提取地址,从“subject”部分提取主题(如果适用)。具体来说,它展示了如何从退订链接中提取相关信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Extracting information from the unsubscribe link

您可以看到退订链接是 html 格式的。所以用 Python 的 urllib 模块和 re 模块从中分离出地址和主题。一旦我们有了这个,我们就可以使用 smtplib 模块发送退订电子邮件。

Unsubscribe from emails

让我们来看一下这段代码。首先,电子邮件库 MIMEmultipart 方法允许我们构造多部分消息。然后,我们遍历 uid 列表,根据搜索条件找到退订链接。在本例中,我们尝试取消订阅 Groupon 电子邮件。如前所述,一旦我们从取消订阅链接中提取了地址和主题,我们就创建消息对象,并为其分配“to”和“subject”属性。最后,我们使用 send_message 方法发送退订电子邮件。如果返回一个空字典,则表明发送成功,并且没有电子邮件发送失败的地址。

步骤 6:断开与服务器的连接

Disconnecting from the IMAP and SMTP servers

一旦我们完成了各种电子邮件操作,我们断开与服务器的连接。这是通过对 smtp 对象使用 quit()方法和对 imap 对象使用 logout()方法来实现的。

第 2 部分:分析和可视化

熊猫数据框

在本节中,我们将使用 Pandas 和 Matplotlib 模块来分析一些统计数据并将其可视化。在此之前,让我们将在上一节中获得的数据写入 excel 表中。如果您想在 Python 之外执行任何分析,这可能会很有用。我们将使用如下所示的 openpyxl 库来完成这个任务。

Writing email data to excel

这里,我们首先创建一个 workbook 对象,然后创建一个 worksheet 对象。接下来,我们编写各种标题,如日期、时间、发送者等。进入表格的第一行。然后,我们用上一节中的电子邮件数据列表填充相应的列。最后,我们保存电子表格。如果你想了解更多关于通过 Python 使用 excel 的信息,请参考这些文档页面,它们解释了用于读取编写电子表格的模块。

接下来,我们用熊猫来读这个 excel 表。Pandas 是一个强大的 Python 模块,提供了大量的数据分析工具。它通常被称为 Python 语言的 SQL。你可以在这里阅读更多信息

Using Pandas to read an excel sheet

这里的数据变量包含 DataFrame,它本质上是一个二维或多维的结构。以下代码片段不言自明,显示了如何从该结构中选择、过滤和打印数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Printing the whole dataframe

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Printing the first five rows

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Printing the last five rows

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Printing only two columns from a random sample of ten data points

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Filtering based on substring match

使用 Matplotlib 进行可视化

本教程的最后一节展示了如何使用 matplotlib 库来创建一些有助于更好地理解数据的可视化。为此,我们使用了包含 3000 多封电子邮件的数据集

  1. 每周邮件流量

Weekly email traffic

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这张图向我们展示了一周中不同日子的电子邮件总量分布情况。我们在这里看到一些周一忧郁的迹象,然后电子邮件数量在接下来的四天里或多或少地稳定下来,最终在周末逐渐减少。这里的第一行代码用于按照正确的顺序排列不同的类别(一周中的每一天)。如果没有这个,默认情况下将使用字母顺序对类别进行排序。

2。每小时的电子邮件流量

Hourly email traffic

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这个图中,我们看到了一天中收到的电子邮件的分布。不知什么原因,中午似乎有一个明显的高峰。在这里的代码中,我们首先根据发送/接收来过滤电子邮件。然后,我们在排序之前提取时间戳的小时部分。

3。热门发送者

Top senders

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此条形图显示了特定时间段内前二十名发件人及其发送的电子邮件数量。value_counts()方法用于计算特定条目的出现次数,nlargest()方法用于输出出现次数最多的条目。tolist()方法将一个数据序列转换成一个列表。Groupon 似乎是这里最大的罪犯!

4。主题词统计直方图

Subject word count

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是一个直方图,显示了电子邮件主题中使用的字数分布。看起来大约五到十个单词是这里的首选范围。为了对单词进行计数,主题字符串被分割成单词列表,并且该列表的长度作为单独的列存储在数据框中。

5。主题行中的常用词

Common subject words

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是一个有趣的条形图,显示了电子邮件主题行中经常出现的单词。这里的代码稍微有点复杂。首先,使用 split()方法分隔主题中的单词。使用 fillna()方法将空的主题条目转换为字符串“none”是一个好主意,因为空条目可能会在以后产生问题。接下来,我们将 2d 列表转换成一个小写单词列表。在这个分析中,我们对诸如“the”、“is”等常用词不感兴趣。因此,我们使用这些单词创建了一个例外列表,并过滤掉所有包含三个或更少字母的单词。最后,我们将单词和它们的频率分成两个不同的列表,并绘制它们。这里出现频率高的词表明大多数被分析的电子邮件都与营销相关。

结论

到目前为止,我们已经很好地理解了如何使用 Python 执行与电子邮件相关的任务,使用 Pandas 分析电子邮件统计数据,并使用 Matplotlib 可视化它们。这些概念可以扩展到各种应用,包括一些涉及机器学习的应用。以下是一些可能的使用案例:

  • 使用电子邮件的内容构建和训练一个垃圾邮件分类器,并将其性能与 Gmail 或 Outlook 中的内置分类器进行比较。
  • 使用 K-means 等聚类算法对相似的电子邮件进行分组。
  • 使用自然语言处理技术的情感分析
  • 电子邮件营销分析—点击率、跳出率、响应时间等。

资源

用于拼写纠正的嵌入

原文:https://towardsdatascience.com/embedding-for-spelling-correction-92c93f835d79?source=collection_archive---------15-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Da Nina on Unsplash

尽管自 70 年代以来一直在进行自动拼写纠正,但在缺乏大量用户数据的情况下,仍然很难解决。

噪声文本对于许多 NLP 任务来说是有问题的,因为它导致基于机器学习的技术的准确性降低,并且增加了诸如 Word2Vec 或 GloVe 之类的流行技术不能处理的词汇表外(OOV)单词的数量。

因此,作为管道预处理的一部分,我们探索了几种方法来主动纠正输入数据的拼写,以提高下游任务的准确性。在这里,我们将重点讨论如何通过字符级嵌入来解决这个问题。我们的工作可以从头开始训练,使用和可视化,可以通过点击【1】链接下载和实验。

介绍

拼写错误可以分为三类,需要不同的处理方法:

  1. ****实词错误 : ’ 三个’拼成’有’

真实的单词错误是最难纠正的,因为它们依赖于上下文,为了纠正它们,我们必须分析所有的数据来检查语义一致性和语法。根据所使用的算法,我们引入了错误地纠正准确句子的可能性,并增加了大量的处理时间。处理这个问题最常见的方法是 seq2seq 模型或使用统计数据,如 ngram 令牌。

2。简短形式 : ’ you’ 拼写为’ u’

简写形式的特点是与想要表达的单词共用几个字母。就 编辑距离 而言,“u”比“你”更接近“我”,因此基于字典的方法不太有效。

3非单词错误 : ’ fast’ 拼写为’ fsat’

非单词错误是最常见的,大多是由错别字引起的,这将是我们这里的重点。

拼写纠正可以分为三个主要任务:

  1. 以一个句子作为输入,确定哪些单词拼写错误。
  2. 从拼写错误的单词中,查找替换的候选列表。
  3. 从列表中选择合适的候选人。(在自动校正的情况下)

因为我们只对非单词错误感兴趣,所以确定哪些单词拼写错误只需对照字典进行检查,尽管必须特别注意专有名词。

候选人选择

有几种不同的方法来选择候选人:

  • 最简单的方法是计算你的单词和整个词典之间的编辑距离。虽然这种方法很准确,但是非常昂贵。
  • 语音算法【2】如 Soundex、Phonex 或 Metaphone。这些算法将任何字符串编码成一个短序列,允许字符串索引的发音。“hurry”和“hirry”都将返回“H600”。通过预处理您的整个词典并按语音代码索引,您可以很容易地找到发音相似的候选词。运行时很快,但它只纠正语音错误。
  • 计算你的单词的可能拼写错误列表(插入、删除、换位或替换),并将其与你的字典匹配。虽然这比简单的方法要好,但是由于拼写错误的集合以 54 * length+25 的速率增加,所以速度非常慢。更多解释见Peter nor vig【3】的优秀文章。
  • 对称拼写校正采用前面的想法,并通过计算字典和拼写错误的单词的拼写错误来扩展它。详见 符号拼写【4】。这种技术既准确又非常快,但代价是大量的预计算和磁盘空间,并且需要字典的频率列表。

字符级嵌入

我们已经探索了解决这个问题的另一种方法,即使用单词嵌入在字符级别表示单词。流行的单词嵌入方法,如 Word2Vec,试图通过语义来表示单词,因为这对各种任务非常有用。然而,通过使用基于字符的模型,有可能基于单词拼写来构建单词嵌入。

这个想法类似于语音算法,其目的是在相同的单一度量(字符串或浮点数)下表示相似的单词,但是我们通过使用 n 维嵌入来扩展这个想法。

我们的方法如下:

  • 训练模型以产生字符级单词嵌入
  • 向量化我们的整个字典,并建立一个有效的搜索索引
  • 矢量化拼写错误的单词并查找最近的邻居

该模型使用两层 LSTM 来构建选定大小的嵌入。更高的维度以更长的计算时间为代价提供更精确的结果,对于我们的使用,我们已经满足于维度 150。该模型通过向其传递一组单词来训练,这些单词要么是两个完全不同的单词,要么是单词及其拼写错误。训练目标是使相似元组的两个嵌入之间的差异的范数最小化*,并使不同单词的差异最大化。*****

已经使用 600k 单词的字典生成了训练数据,并且为每个单词生成了编辑距离 1 或 2 的几个拼写错误。我们对 AZERTY 键盘上原始字符附近的拼写错误赋予了更高的概率(因为我们是用法语工作的),以便模型支持这些错误。由于缺乏明确的训练指标,很难准确知道何时停止训练,但在经历了几百万次训练后,我们对结果感到满意。

一旦经过训练,该模型就可以用于向量化单词。通过使用 PCA 将它们投影到 2D 平面上,我们可以获得以下可视化:

**python usage_visualisation.py**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The original model we used was developed by IntuitionEngineering.

成功!相似的单词似乎在向量空间中被分组在一起。

这本身不是很有用,所以现在我们要对整个 60 万单词字典进行矢量化。在现代 CPU 上,这个过程大约需要 10 分钟。

最后一步是构建一个索引,它允许有效地搜索最近的向量。由于我们不需要 100%的准确性,更关心计算速度,我们将使用NMS lib【5】,一个专门用于 ANN(近似最近邻)搜索的库。

这个库允许我们在索引中搜索给定向量的 k 个最近邻。我们可以调整 k 个最近邻的数量,以恢复计算时间与精确度之间的平衡。一旦我们得到了最近邻的列表,我们可以使用编辑距离进一步过滤,只保留相关的建议。

这为我们提供了以下输出(法语):

**python usage_correction.py 'langqge'**

编辑距离 1:
langqge:[’ langage ']

编辑距离 2:
langqge : [‘langages ‘,’ lange ‘,’ langé’,’ langage’]

结果

我们已经在通过我们的拼写错误生成器生成的语料库(大约 4k 个句子)上测试了我们的模型。我们的衡量标准是准确性,我们将准确性定义为在候选列表中找到正确单词的百分比。

在整个语料库中,chars2vec 模型的准确率为 85%,而标准语音算法的准确率约为 40%。结合这两种方法,我们有 90%的准确率。主要的瓶颈是 4 个字符或更少的单词,它们的性能不好。

这是意料之中的,因为:

  • 那么大的单词在短编辑距离内有很多邻居。
  • 3 个字母的单词中的打字错误比 10 个字母的单词更有影响力,这使得模型更难在向量空间中正确地映射单词。

校正选择

虽然我们前面的例子直接给出了我们想要的答案,但在编辑距离内经常有几个候选人,必须做出选择。

我们尝试了两种不同的方法:

  • 概率性:使用建立在大型语料库上的频率列表,选择最常用的词。明显的缺点是一些不常用的单词可能永远不会被选择,虽然这种方法非常简单,但却提供了很好的准确性。
  • 语义:根据候选词与句子中周围单词的语义相似性对候选词进行排序。这可以通过取一个预先训练的跳格词 2Vec 并计算嵌入的候选词和周围词(或整个句子)之间的平均距离来完成。虽然计算量很大,但这对于具有良好语义的单词给出了非常好的结果,尽管对于可以在任何上下文中使用的单词如“there”、“I”、“are”不是非常有效。

根据经验,我们发现语义方法对于较长的、不常用的单词非常有效,而概率方法对于较短的单词更好。将这两种方法与手工制作的规则相结合,我们在随机生成的语料库上获得了大约 70 %的正确率。

未来工作:N-grams 令牌

理想的方法是将两者结合起来,而不是在语义和频率之间进行选择。这可以通过使用单词 N 元语法的频率表来实现。

为了建立这些表,在非常大的语料库上对 N 个单词的连续序列进行计数和编译。对此可用的最佳资源是 谷歌图书 N-gram【6】**,它是通过分析各种语言的大约500 万本图书而构建的。****

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

‘Spelling Correction’ bi-gram occurrences

原始数据可通过此 链接【7】获得,尽管由于文本数量庞大,下载并将其编译成可用状态需要大量时间。

结论

使用字符级嵌入可以获得良好的整体性能,尤其是对于较长的单词。通过手工制作的预处理规则和适当的候选项选择,这为现有的拼写校正解决方案提供了一种体面的替代方案。

进一步的工作将包括与预先存在的流行解决方案和 n-gram 令牌的使用适当的基准。在此期间,这个包可以免费试用:char 2 vec【1】。

[1]https://github.com/Lettria/Char2Vec

[2]https://en.wikipedia.org/wiki/Phonetic_algorithm

[3]https://norvig.com/spell-correct.html

https://github.com/wolfgarbe/SymSpell

https://github.com/nmslib/nmslib

https://books.google.com/ngrams/

[7]http://storage . Google APIs . com/books/n grams/books/datasetsv 2 . html

利用深度学习嵌入图

原文:https://towardsdatascience.com/embedding-graphs-with-deep-learning-55e0c66d7752?source=collection_archive---------9-----------------------

稀疏表示是分类器的天然杀手。当前的图形数据结构,如邻接矩阵和列表,都受到这种稀疏性的困扰。本文将讨论矩阵分解、DeepWalk 和 Node2Vec 等技术,这些技术将稀疏图数据转换成低维连续向量空间。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Converting Adjacency Matrices to low-dimensional continuous vector spaces.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This diagram shows the results of embedding a graph on the left into a 2-dimensional representation which can be plotted and clustered based on metrics such as Euclidean distance

历史上,矩阵分解一直是降低图形数据维数的流行方法。这包括 SVD(奇异值分解)和 MDS(多维标度)等技术。这些技术的问题在于,它们本质上具有矩阵乘法的运行时间(通常为 n,尽管是 n^(2.37)和 n^(2.77,这些都可以通过诸如库珀史密斯-维诺格拉德或斯特拉森算法之类的巧妙技巧来实现。

对于许多问题来说,n 次运行时间并不太可怕。然而,对于有数千甚至数百万用户的图形表示来说,这是灾难性的。此外,当新用户和连接添加到图表中时,必须重新计算。twitter 转发或媒体关注者等社交网络图是动态的,不断发展的。

我们可以使用深度学习,而不是使用矩阵分解来表示图形!

DeepWalk(链接如下)是第一篇优雅地阐述深度学习用于表示图的论文之一。

[## 深度行走:社交表征的在线学习

我们提出了 DeepWalk,一种学习网络中顶点潜在表示的新方法。这些潜在的…

arxiv.org](https://arxiv.org/abs/1403.6652)

DeepWalk 的灵感来自于图形表示和文本标记之间的相似性。天真地说,文本标记被编码为一个热点向量。例如,你可以用一个很长的向量来表示词汇表的大小,并为每个单词保留一个索引。单词“tiger”的编码如下:

One-hot encoding of text
[ 0 0 .. 0 0 1 0 0 .. 0 0 ] = "tiger"

自然,这些文本的稀疏表示破坏了下游任务(如情感预测)的分类模型。拯救者是跳格模型的引入(如下图所示):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Skip-gram 模型的工作原理是在句子之间滑动上下文窗口,并建立一个深度神经网络,该网络将单词标记作为输入,并将其映射到上下文窗口中出现的其他单词的预测。中间表示(在上图中表示为“投影”)是文本标记的低维表示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

DeepWalk 采用了这个想法,并将其扩展到图形数据。然而,文本数据自然包含某种非常适合上下文窗口的结构。DeepWalk 的作者通过随机行走构造邻域来模拟这种结构,因此得名“DeepWalk”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图用于描述随机漫步。从节点“Connor”开始,我们以概率 a、b、c 和 d 前往 Erika、Daniel、Ben 或 James。在 DeepWalk 中,a = b = c = d,但在 Node2Vec 中,这些概率在整个行走过程中都是参数化的。

沿着图随机行走会产生如下邻域:

Examples of Vertex Neighborhoods
(Connor, James, Jon, Bob, Joe)
(Connor, James, Jon, James, Connor)
(Connor, Erika, Connor, Daniel, Connor)

然后,上下文窗口滑过这些邻域,并训练一个跳格模型。

训练跳格模型的两个重要想法是分层 Softmax负采样。该图像突出了分层 Softmax 的思想。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image taken from Galina Olejnik’s explanation: “Hierarchical softmax and negative sampling: short notes worth telling” which can be found on towards data science: https://towardsdatascience.com/hierarchical-softmax-and-negative-sampling-short-notes-worth-telling-2672010dbe08

想象一下一个 facebook 网络,其中有数百万用户需要预测顶点邻域。这将导致 softmax 层具有数百万个隐藏单元。这种灾难可以通过在二叉树中构造顶点空间并预测沿树的路径来避免。例如,如果网络中有 8 个用户,那么只需要 3 个值就可以从根节点遍历到任何一个单独的节点。

下一个想法(在 Word2Vec 中是至关重要的想法)是负采样。负采样基本上抛弃了直接预测上下文窗口中的单词的思想,而是将上下文预测任务视为二元分类问题。一旦你有了一个上下文对,你就随机抽样否定对,然后让模型标注这个单词是否出现在上下文中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Example of negative sampling, coffee and Gorilla do not appear in the context window and are thus labeled as ‘0’ in the binary classification task.

另一个在 DeepWalk 上构建的有趣的论文是 Node2Vec(链接如下):

[## node2vec:可扩展的网络特征学习

网络中节点和边上的预测任务需要在学习所使用的工程特征方面进行仔细的努力

arxiv.org](https://arxiv.org/abs/1607.00653?context=cs)

Node2Vec 分解了使用随机行走来构造顶点邻域的思想。首先看两种遍历图形的极端方法,面包优先和深度优先搜索:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

他们发现,如果你在深度优先搜索中遍历节点,得到的嵌入将捕捉到同质性。同向性指的是具有小的最短路径距离的节点应该在新的表示中彼此靠近地嵌入。他们还发现,如果在广度优先搜索中遍历节点,得到的嵌入将捕获结构等价。上图中的结构等价很容易解释,尽管 u 和 s6 没有共享任何邻居,但它们都是各自社区的中心。

Node2Vec 的作者因此建议将随机游走参数化,以便它可以构建更多的语义顶点邻域:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总之,本文介绍了 DeepWalk 和 Node2Vec,并展示了它们如何使用深度学习将图形嵌入到低维表示中。与必须重新计算的矩阵分解方法相比,跳跃图模型方法具有适应网络变化的优点。感谢您的阅读,如果您想回顾这篇文章,请查看下面的视频!

无嵌入深度学习 NLP 模型

原文:https://towardsdatascience.com/embeddings-free-deep-learning-nlp-model-ce067c7a7c93?source=collection_archive---------20-----------------------

什么是单词嵌入

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Edward Ma on Unsplash

单词嵌入(例如 word2vec,GloVe)在几年前被引入,并从根本上改变了 NLP 任务。有了嵌入,我们不需要在大多数 NLP 任务中导致非常高维特征的一键编码。我们可以用 300 个维度来代表超过 100 万个单词。

不同种类的嵌入,如字符嵌入,句子嵌入(如跳读推断),上下文嵌入(如 ELMoBERT )是近年来发展起来的。我们一直都需要嵌入层吗?有时这可能不可行,因此 Ravi S .和 Kozareva Z .引入了无嵌入深度学习模型。

设备上

我们可以在云中或内部轻松分配 1 GB 内存和 16 个 CPU 来部署 sexy 模型。我们不需要牺牲模型准确性来减少模型占用空间,也不需要在大多数企业级基础架构中产生大量的大型模型。

有时,我们别无选择,只能将模型部署到设备,而不是利用云基础架构。原因可以是

  • Sensitive Data:数据可能无法从设备发送到云端
  • Network:高速网络可能无法覆盖。

因此,如果我们将模型部署到智能 Swatch 或物联网设备等设备,则需要一个非常小的模型。没有人想在你的 Android Wear 操作系统中加载 1 GB 的型号。将模型部署到设备时面临的挑战:

  • Small memory footprint
  • Limited storage
  • Low computational capacity

自治神经网络

因为目标是将模型部署到小型设备。它不能是高资源需求的。因此,SGNN 的目标是:

  • Tiny memory footprint:加载预训练嵌入时没有初始化。
  • On-the-fry:将输入文本实时转换为低维特征。

投影神经网络

Ravi S .和 Kozareva Z .利用投影神经网络模型架构来减少内存和计算消耗,而不是使用具有高占用空间的原始神经网络。

其思想是在训练阶段训练两个神经网络(即训练器网络和投影网络)。全网优化教练机网络损耗、投影网络损耗和投影损耗。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Projection Neural Network Architecture (Ravi S. 2017)

模型架构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SGNN Model Architecture (Ravi S. and Kozareva Z., 2018)

  • On-the-fry Computation:将(函数 F 和 P)文本实时转换为中间结果和项目层,无需查找预定义的矢量。
  • Hash Function Projection:通过修改版本的位置敏感散列 (LSH)将高维特征减少到低维特征,这允许将相似的输入投射到相同的桶。
  • Model Optimization:在投影层使用二进制特征(0 或 1)实现非常低的内存占用。

实验

Ravi S .和 Kozareva Z .通过Switchboard Dialog Act Corpus (SwDA)和ICSI Meeting Recorder Dialog Act Corpus (MRDA)对 SGNN 进行了评估,结果非常好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SwDA Data Result (Ravi S. and Kozareva Z., 2018)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

MRDA Data Result (Ravi S. and Kozareva Z., 2018)

拿走

  • 越来越多复杂的模型架构被发布,以在不同的学科中实现最先进的结果。然而,它可能不适合小型设备,如物联网设备或移动设备,因为这些设备中资源有限。
  • 当交付一个令人惊叹的模型时,准确性并不是唯一的关注点。在某些情况下,必须考虑速度和模型复杂性。我们可能需要牺牲精确性来得到一个轻量级的模型。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。你可以通过媒体博客LinkedInGithub 联系我。

参考

拉维…2017. ProjectionNet:使用神经投射学习高效的设备上深度网络

拉维 s 和科扎列娃 z,2018。用于设备上短文本分类的自治神经网络

在非 NLP 上下文中嵌入 Word2Vec 详细信息

原文:https://towardsdatascience.com/embeddings-with-word2vec-in-non-nlp-contexts-details-e879b093d34d?source=collection_archive---------12-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Charles Gao on Unsplash

探索使用基于 Word2Vec 的模型在业务上下文中创建项目嵌入的细节。

本文档要求熟悉 wor2vec[1,2,3]类模型和深入学习的文献。

在本文档中,我们将探讨在非 NLP 业务上下文中使用 Word2Vec 类模型创建嵌入向量的细节。我们将使用 Instacart Dataset[4,31]创建产品嵌入,评估模型体系结构/参数,并将生成的嵌入用于项目/购物篮相似性/互补性预测。

示例代码[31]可从 Gensim 获得。

为什么是 Word2Vec?

正是计算效率、可扩展性和“带负采样的 SkipGram”(SGNS)体系结构[2]使它变得特别。当您还将 SGNS 可视化为双编码器模型[5]时,正是输入层的易扩展性使其更加特殊。

对 SGNS 体系结构和参数有扎实的了解是:

  • 评估业务上下文中的嵌入创建[6]
  • 在进一步的下游模型/任务中使用这些嵌入[12,13]
  • 评估其他嵌入模型(Node2Vec、Graph 神经网络、Transformers、FastText、Bert…)。

为什么要用 Word2Vec 创建嵌入?

大家可能已经知道,嵌入可以作为具有不同输入和输出的复杂多层监督模型的副产品来生成。这不是最佳的嵌入生成模型。原因何在?

您希望嵌入能够真正反映数据集中存在的目标/业务功能(例如,协作过滤)。要实现这一点,您可能希望模型中的嵌入参数仅参与模型输出的计算,而不涉及其他层或参数。在 SGNS 模型中,唯一的参数是嵌入参数,而模型输出只是 Target(In)和 Context(Out)嵌入参数的点积。所以你的目标函数仅仅用这些嵌入参数来表示。这是将目标函数语义注入到嵌入向量参数中的最佳方式;因此,您可以按原样有效地使用/评估嵌入,或者将它们用作其他下游模型的输入。

相反,在具有附加输入参数或嵌入层之上的层的模型中,目标函数与嵌入参数和模型中的其他参数一起表示。因此,在这种情况下,仅评估嵌入参数(例如,嵌入向量空间中的相似性)将是目标函数的次优表示。

从技术上来说,并加以总结;在网络中,您不希望将具有可学习参数的附加层放在嵌入层之上(或附近)。在嵌入层的上方应该有相似性函数(例如,点积> sigmoid)。见下文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Embedding Generation Model Architectures

作为补充说明;与上述架构相比,对于一些业务案例,您可能希望您的嵌入反映多个任务(例如,点击概率和喜欢概率)。如果任务是相关的,你可以通过创建多任务学习模型的嵌入来实现更好的概括[22,23,24]。选择取决于您的架构设计。

非 NLP 设置中的 word 2 vec

Word2Vec 和 Doc2Vec 的非 NLP 改编的标志性论文有;分别是 Prod2Vec[7]和 Meta-Prod2Vec[8]。您可以嵌入任何对象,只要您可以为该对象定义相应的上下文/环境;无论是顺序的(例如搜索日志、产品交互序列[7])还是图表9,10,27。正确定义你的上下文的能力[11]是你的模型最关键的部分,其次是你的其他 SGNS 参数。

根据订单生成产品嵌入(Instacart 数据集)

Instacart 数据集[4]包含来自 200,000 多个 Instacart 用户的超过 300 万份杂货订单,其中每个订单包含一系列购买的产品。我们将为每个产品创建嵌入向量。我们将不使用任何产品/用户侧信息,并且仅将数据集中固有的协同过滤语义嵌入到嵌入向量中。尽管这些生成的产品嵌入可以单独用于对产品相似性/互补性和当前/下一篮子/项目推荐进行建模;理想情况下,为了获得更高的模型精度,您应该考虑具有附加输入功能的更高级的模型。与检索/排名架构一样,您也可以简单地考虑并使用这些嵌入作为检索阶段模型(向量相似性搜索),并进一步使用选择的嵌入作为具有附加输入特征的更复杂的排名模型的输入。(检索/排名模型[12])。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对偶嵌入空间

SGNS 为每个对象学习两个不同的嵌入向量;入和出向量(也称为目标和上下文向量)。为什么每个对象需要两个不同的向量?许多人在下游任务[26]中通过平均输入和输出向量来使用单个向量,或者丢弃输出向量而只使用输入向量。还可以通过在训练时在模型中使用共享嵌入参数层来学习单个嵌入向量(具有共享参数的暹罗网络[25])。

那么为什么要为每个对象创建两个单独的向量呢?让我们检查技术和逻辑推理。

**技术:**让我们把心态从 NLP 转移到 Instacart 数据集;“词”变成了“产品”,“句”变成了“订单筐”。产品的上下文是当前订单篮中的其他产品。对于产品“一袋香蕉”,考虑我们对目标(入)和上下文(出)使用相同向量的情况。“一袋香蕉”在语义上不会出现在其自身的上下文中(上下文是订单篮)。通过对“一袋香蕉”使用相同的向量 v;分配一个低概率的 p(“一袋香蕉”|“一袋香蕉”)是不可能的,因为给 v v 分配一个低值是不可能的。

**逻辑:**使用双重输入输出向量使我们能够评估产品在目标或上下文环境中的概率。因此,我们可以计算乘积相似性(输入向量中的余弦相似性)或乘积互补性(输入和输出向量之间的余弦相似性)。最终,这种“双重嵌入空间”架构形成了用于生产的更高级的相似性/互补性预测模型的基础[16,17,18,19,20]。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Word2Vec Model in Tensorflow(Also refered as Dual Encoder Model, Siamese Networks or Dual Tower Networks)

模型参数

让我们评估 SGNS 参数;

**窗口大小:**设置窗口大小取决于任务。在 Airbnb 案例[11]中,列表嵌入是通过用户的列表点击会话序列生成的,在会话中被连续点击的列表可能比在会话中第一个和最后一个被点击的列表在语义上更相关。因此,设置一个小的窗口大小(3-6)可能适合于缩小序列中的相关性窗口。数据越多,可以使用的窗口越小。

然而,在 Instacart 数据集的情况下,订单购物篮中的产品与购物篮中的所有其他产品相关,因为我们的目标函数是“购物篮级别”内的相似性/互补性预测。因此,我们的窗口大小是每个订单的篮子大小计数。作为一个额外的理论说明,如果您的数据集足够大,并且如果您在每个时期的订单篮中打乱产品的顺序,您可以使用较小的窗口大小;并且可以实现与使用更大的窗口尺寸相同的结果。

**数据集生成:**目标上下文 ( In-Out)数据对是使用窗口大小参数从数据集构建的。对于每个目标,您可以为以下目标向数据集添加额外的数据对:

  • 添加目标元数据以实现更好的泛化(Meta-Prod2Vec)[8]。例如,目标产品类别
  • 将其他对象嵌入到相同的嵌入空间中,例如品牌[8],例如目标品牌
  • 添加额外的目标-上下文对以影响或添加额外的关联到嵌入向量[11]

**纪元:**纪元的数量对结果没有边际影响,您可以通过离线收敛评估轻松决定。但是,请注意,原始 Word2Vec 代码[36]和 Gensim 等库不使用小型批处理(没有小型批处理,模型参数会随数据集中的每个数据更新),因此与使用小型批处理的模型相比,增加历元数不会产生相同的效果。

**候选采样:**候选采样算法实现了高效的任务学习架构,而无需计算整个标签类的完整 softmax,29]。由于 SGNS 使用负抽样方法[2],抽样分布生成和相关抽样参数在建立成功的 SGNS 模型中起着至关重要的作用。那么,如何设置负采样架构呢?

  • 一般采样-使用采样分布参数从相同的输入数据集中提取负样本(详见下文)。
  • 特定于上下文的采样—使用目标上下文选择阴性样本。在 Instacart 案例中,对于特定产品,您可以从相同的产品类别/通道中选择阴性样品。这种“硬否定”技术使模型能够更快更好地收敛。然而,你需要在这方面投入资源,因为你需要能够为每个目标选择否定。可以在小批量训练期间检索负分布,或者可以预先生成静态负分布数据集。这种选择取决于您的培训硬件、分布式培训架构和成本。

负采样噪声分布参数( α ): 使用频率平滑参数(α)从您的分布中采样负样本,其中项目的频率被提升到α的幂。使用α,您可以调整选择流行或稀有物品作为否定的概率。

  • α=1 是均匀分布-使用数据集中的原始项目频率。
  • 0
  • α=0 is unigram distribution — item frequency is 1 in dataset.
  • α<0 — low-frequency items are weighted up.

阴性样本数(k): 对于我们抽样分布中的每个目标,选择 k 个阴性样本。在下一节中,我们将评估 k 和α之间的相关性。

评估-订单篮中的下一个产品预测

我们将使用 Instacart 数据集,通过预测当前订单篮中的下一个商品来评估模型参数(k,α)。

样本代码[31]。(为清楚起见,使用 Gensim。)

在训练数据集上训练我们的模型之后,使用测试集,我们将在客户的订单篮子中隐藏一个随机产品,并通过使用篮子中的其他产品来预测隐藏的产品。我们将通过平均篮子中产品的目标嵌入来计算“篮子向量”。然后,利用计算出的“篮子向量”,我们将在上下文(外部)向量空间中搜索最近的项目,并将最近的项目作为推荐呈现。这个推荐基本上就是“这里有推荐给你的产品,以你已经放在篮子里的东西计算”。下面是采用不同 k 和α的命中率@10 分析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Hitrate@10

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们看到高α (α=0.75,α=1)时精度低。直觉存在;在高α的情况下,流行的高频项目/用户支配分布,并降低模型的泛化能力。

随着α的降低,我们预测更多“不太频繁”的产品,这导致更好的模型得分,在α=0 时达到最大值。那么你会为这个模型选择哪个α呢?我会选择α=-0.5,因为尽管它的得分低于α=0,但我会认为它在在线评估中的得分会更高,假设它会为客户提供更多样化的推荐(意外发现,新奇)。

α和 k 的相关性:

与高α(α>0);增加 k,会降低精度。直觉是;在高α的情况下,你推荐的是不能反映真实分布的流行/高频项目。如果你在这种情况下增加 k,你会选择更多的流行/高频项目作为负项,这导致进一步过度拟合不正确的分布。端点是;如果想推荐高α的热门单品,没必要进一步增加 k。

**用低α(α<0);**增加 k,增加精度。直觉是;α值较低时,你会从尾部推荐更多不同的商品(不常见的商品)。在这种情况下,如果增加 k,就会从尾部选择更多的负样本,使模型能够看到更多不同的项目,从而很好地适应多样化的分布。端点是;如果你想推荐不同的低α的项目(新奇的,意外的),你可以进一步增加 k 直到它开始过量。

注意:不要忘记使用余弦距离进行评估(标准化向量的点积)。如果使用欧氏距离,可能会过分强调数据集中的频繁项;并且还可能由于您嵌入的初始化值而错误地表示不常见的项目。

进一步分析

到目前为止,我们已经分析了 Word2Vec。它的优势在于简单性和可伸缩性,但这也是它的弱点。使用 Word2Vec,不容易合并项目属性或项目-项目关系属性(图形结构)。这些额外的项目/交互特征对于更好的模型概括/准确性以及缓解冷启动问题是必需的。

是的,您可以使用 Meta-Prod2Vec [8]添加项目功能,使用图随机游走模型([9,10])也可以添加节点功能。但问题是,所有这些添加的‘特征’都是 id,而不是矢量;也就是说,它们是存储在后端的特性的 id。对于最先进的模型,您可能希望使用矢量作为项目特征(例如,编码的项目图像矢量)。此外,添加的项目特征没有加权,因此,每个项目属性对项目和模型输出的影响不会作为参数学习。

Word2Vec 的另一个缺点是它是直推式的;这意味着当一个新项目被添加到可用项目列表中时,我们必须重新训练整个模型(或者继续训练模型)。

使用相对较新的归纳图神经模型[34,35],我们可以添加项目/关系特征作为可学习的向量,并且还可以获得训练模型看不到的新项目的嵌入。

图形神经网络研究是未来几年令人兴奋的领域。

结论

本文档的主要要点;

  • 非自然语言处理环境下基于 Word2Vec 的模型分析。
  • 模型参数分析,主要是α和 k 之间的相关性,用于业务上下文的相似性/互补性预测。

未来的文档将继续探索更高级的嵌入模型和下游深度模型。

[1]向量空间中单词表示的有效估计(【https://arxiv.org/abs/1301.3781】T2

[2]词和短语的分布式表征及其组合性(【https://arxiv.org/abs/1310.4546】

[3] word2vec 解释:推导 Mikolov 等人的负采样单词嵌入法(https://arxiv.org/abs/1402.3722)

[4]2017 年 Instacart 在线杂货购物数据集”(https://www.instacart.com/datasets/grocery-shopping-2017)

[5]万物嵌入:神经网络时代的搜索(https://youtu.be/JGHVJXP9NHw)

[6]Embeddings @ Twitter(https://blog . Twitter . com/engineering/en _ us/topics/insights/2018/embeddingsattwitter . html)

[7]收件箱中的电子商务:大规模的产品推荐(【https://arxiv.org/abs/1606.07154】T2

[8] Meta-Prod2Vec —使用边信息进行推荐的产品嵌入(【https://arxiv.org/abs/1607.07326】T4)

[9]深度行走:在线学习社交表征(https://arxiv.org/abs/1403.6652)

[10] node2vec:网络的可扩展特征学习(https://cs.stanford.edu/~jure/pubs/node2vec-kdd16.pdf)

[11]在 Airbnb 使用搜索排名嵌入的实时个性化(https://www . KDD . org/KDD 2018/accepted-papers/view/Real-time-personal ization-using-embedding-for-Search-Ranking-at-Airbnb)

[12]深度神经网络为 YouTube 推荐(https://ai.google/research/pubs/pub45530)

[13]推荐接下来看什么视频:多任务排名系统(https://dl.acm.org/citation.cfm?id=3346997)

[14] Word2vec 适用于建议:超参数问题(https://arxiv.org/abs/1804.04212)

[15]用于信息检索的神经模型(https://youtu.be/g1Pgo5yTIKg

[16]从购物篮和浏览会话中推断互补产品(https://arxiv.org/pdf/1809.09621.pdf

[17]使用四元组网络的互补相似性学习(https://arxiv.org/abs/1908.09928)

[18]推断可替代和互补产品的网络(https://arxiv.org/abs/1506.08839)

[19]用于互补产品推荐的上下文感知双表征学习(https://arxiv.org/pdf/1904.12574.pdf)

[20]指数家族嵌入(【https://arxiv.org/abs/1608.00778】T2

[21]大规模网络中的袖珍结构嵌入(【https://youtu.be/B-WFdubGkIo】T4)

[22]在 Pinterest 学习视觉搜索的统一嵌入(https://arxiv.org/abs/1908.01707)

[23]深度神经网络中多任务学习的概述(https://ruder.io/multi-task/)

[24]利用多门混合专家对多任务学习中的任务关系进行建模(https://www . KDD . org/KDD 2018/accepted-papers/view/Modeling-Task-Relationships-in-Multi-Task-Learning-with-Multi-gate-Mixture-)

[25] DeepFace:缩小与人脸验证中人类水平性能的差距( DeepFace:缩小与人脸验证中人类水平性能的差距)

[26] GloVe:单词表示的全局向量(https://nlp.stanford.edu/projects/glove/)

[27]图卷积网络:综合评述(https://rdcu.be/bW6sK)

[28]关于单词嵌入—第 2 部分:逼近软最大值(https://ruder.io/word-embeddings-softmax/)

[29]候选抽样-张量流(https://www.tensorflow.org/extras/candidate_sampling.pdf

[30]使用负采样优化 Skip-Gram 的计算效率(https://aegis 4048 . github . io/Optimize _ Computational _ Efficiency _ of _ Skip-Gram _ with _ Negative _ Sampling)

[31]https://github . com/boraturant/word 2 vec _ insta cart _ Similarity _ complementary

[32] CS224W:带图的机器学习(【http://web.stanford.edu/class/cs224w/】T2

[33]图的节点嵌入算法(【https://youtu.be/7JELX6DiUxQ】T4)

[34]大型图上的归纳表示学习(https://arxiv.org/abs/1706.02216)

[35]关系归纳偏差、深度学习和图形网络(https://deep mind . com/research/open-source/graph-nets-library)

https://code.google.com/archive/p/word2vec/

在 Jupyter 笔记本/Google 联合实验室上使用 Rasa 的紧急聊天机器人

原文:https://towardsdatascience.com/emergency-chatbot-using-rasa-on-jupyter-notebook-google-colaboratory-2be9059f87cc?source=collection_archive---------13-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Picture by the author

聊天机器人是典型的人工智能工具,广泛用于商业目的。

通过这篇文章,我的目标是解释紧急聊天机器人的目的,如何将一个想法发展成一个空机器人,作为一个有优点和缺点的堆栈,以及为什么我使用 Jupyter 笔记本来解决它。

在 2018 年夏天,我和另外两个家伙有了建造聊天机器人的想法,尽管在最初的几个月合作之后,我已经和 Rasa 单独进行了这个项目。我的紧急聊天机器人的想法是在夏天意大利发生恶劣天气悲剧后产生的。在这些情况下,人们需要紧急帮助,同时他们也处于恐慌状态。因此,首先,紧急聊天机器人将是一种在危险情况下使用的社交工具,开发技术将有助于及时挽救生命。也许有机会在一起出售保险的应用程序中部署这个紧急聊天机器人。

我们开始用 python 编写一些脚本,但在那之后,我们发现了 Rasa,并决定使用这个框架,因为 Rasa 是一个用 python 编写的开源 NLP 工具包,具有预构建的架构,可以根据您的需要进行定制。Rasa Stack 是为短消息构建的,能够执行任务,所以只要有一个想法,你就可以开始用句子填充这个框架,形成用于训练你的机器人的数据集,然后你配置 NLU 模型,创建对话模式和对话的框架。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Picture by the author

为了这个项目,我遵循了"Justina petraiyte "Jupyter 笔记本的步骤。选择使用 Jupyter 笔记本电脑是因为它有助于数据科学家之间的工作共享,尽管不可能在生产中使用它来部署机器人,但可以在网络上共享笔记本电脑并在云上运行它。有几个工具,但谷歌合作实验室表现很好,是我的最佳选择。

要理解机器人如何工作,必须知道对话的基本流程:用户给出一个输入,代理解析这个输入并运行一个 NLP 任务,代理根据从对话中提取的实体给用户一个答案。

意图将用户输入映射到响应。它可以被视为对话中的一个对话回合。在每个意图中,都定义了用户话语、实体和如何响应的示例。

实体是用于从输入中识别和提取有用数据的关键字。意图让你的机器人理解特定用户输入背后的动机,而实体则用来挑选用户提到的特定信息,包括链接到实体的实体值

现在的问题是,Rasa 堆栈是如何工作的?

Rasa 框架分为 Rasa NLURasa 核心 python 库。第一个是自然语言理解模块,用于意图分类和实体提取,目的是教会聊天机器人如何基于机器学习理解用户输入。

使用 Rasa Core,您可以通过训练基于深度学习设置的对话管理来教聊天机器人如何做出响应。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Picture by the author

当用户输入到来时,它被传递给 i 解释器(拉萨·NLU),目的是提取意图、实体和其他结构化信息。后续步骤由 Rasa 核心管理。跟踪器用于在内存中存储对话历史,它维护对话状态。策略决定在对话的每一步采取什么行动。它是与一个特征器一起生成的,该特征器创建了跟踪器给出的当前对话状态的向量表示。最后,执行一个动作,向用户发送一条消息并传递一个跟踪器实例。

让我们开始紧急聊天机器人之旅吧!!!

Rasa _ Emergency _ Chatbot _ Colab笔记本。

首先,让我们安装 Rasa 库:我已经使用了 Rasa NLU 0.12.3 和 Rasa 核心 0.9.6,虽然在此期间更新版本已经实现。

现在我们准备使用保存在“ nlu.md ”文件中的数据集开始自然语言理解过程(***“# #”***代表意图的开始)。

在该数据集中,用户输入示例按意图分组。在紧急聊天机器人中,数据集包含以下意图:

“问候”、“确认”、“紧急 _ 空中 _ 救援”、“紧急 _ 保险 _ 号码”、“紧急 _ 道路 _ 求助”、“紧急 _ 消防”、“紧急 _ 救护车”、“紧急 _ 警察”。

拥有六个实体:“警察”、“道路 _ 救助”、“救护车”、“空中 _ 救援”、“消防”、“保险”。

实体和实体值(同义)使用降价链接 syntex 进行标记:实体值

在 Rasa NLU 模型中,传入消息由一系列组件处理。这些组件在所谓的处理流水线中一个接一个地执行。有用于实体提取、意图分类、预处理等的组件。每个组件处理输入并创建输出。

在文件“ config.yml ”中嵌入了处理管道:Spacy 库提供了标记化和词性,Spacy featuriser 为每个标记查找手套向量,并将这些集合起来以生成整个句子的表示。Scikit-learn 分类器训练支持向量机模型,ner_crf 训练条件随机场来识别实体。使用支持向量机是因为它们是短信的一个很好的分类器,正如 Kaggle competition 所展示的那样:“在煮什么?”。

用混淆矩阵对模型进行评估,并用一个新句子测试其性能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Picture by the author

此时,Rasa 核心用于教导聊天机器人如何使用深度学习模型做出响应:在 Keras 中实现的 LSTM 神经网络。

在这一步中,两个文件是相关的:“ stories.md 和“ domain.yml ”。

第一个表示对话管理模型的训练数据:实际对话的草稿,包括用户的意图和实体以及机器人的动作。在一个典型的故事中:

“##”代表一个故事的开始;

“*”代表用户以意图形式发送的信息;

“-”代表机器人采取的行动。

动作是你的机器人作为对用户输入的回答而运行的表达式。在 Rasa 核心中,有三种类型的操作:

  • 默认动作 (action_listen,action_restart,action _ default _ fallback);

  • utter actions ,以“utter_”开始,用作发送给用户输入的消息;

  • 自定义动作(任何其他动作),可用于任意代码。

在紧急情况下,具有 API 的聊天机器人创建定制动作,该定制动作使聊天机器人能够根据用户输入为救护车实体、警察实体或消防实体检索答案。聊天机器人将通过从槽“组”中检索值来知道应该给出哪种类型的答案。

domain.yml ”代表对话的框架,它有预期的用户输入、机器人应该预测的动作、如何响应以及存储什么信息。

领域由五部分组成:意图、槽、实体、动作和模板。

模板中有链接到机器人动作的消息。

插槽代表机器人的记忆,它们存储用户或外界收集的键值。在紧急情况下,聊天机器人槽通过返回动作中的事件来设置;由实体及其值表示的分类槽。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Picture by the author

现在,对话管理模型将被训练,创建一个代理,并包括决定在对话的每一步采取何种行动的策略。

用于训练历史的模型是长短期记忆(LSTM ),这是一种奇特的递归神经网络,基本上扩展了它们的记忆。由于有内部存储器,RNN 的算法是第一个记住输入的算法,这使得它非常适合处理顺序数据的问题。苹果 Siri 和谷歌语音搜索都使用它们。

经过 10-15 分钟的训练(取决于是否使用 GPU ),你就可以玩紧急聊天机器人了。

虽然 Rasa 有广泛的文档,但我很难找到 Rasa NLU 关于支持向量机实现的文档。Rasa 的另一个弱点是当机器人不理解用户输入时使用的回退操作,因此机器人应该向用户发送默认模板消息,并恢复到导致回退的用户消息之前的对话状态。

我还没有使用这种类型的行动,因为它没有以一种适当的方式工作,机器人将继续建议不正确的答案;网站上使用的 Rasa 机器人“Sara”也是如此。

尽管有这些缺点,我认为 Rasa 是非常通用的,有机会用许多工具将其部署到生产中,并不断发展。

特别感谢 Lorenzo Invernizzi 和 Frenk Locmelis 为这个项目做出的最初贡献。

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

我的 Github 库:https://github.com/claudio1975/chatbot

参考文献:

【https://github.com/RasaHQ/rasa-workshop-pydata-berlin

https://github.com/RasaHQ/rasa-workshop-pydata-dc

https://arxiv.org/abs/1712.05181

https://rasa.com/docs/

使用 Flask +容器化+在 AWS 上部署的机器学习 Web 应用程序

原文:https://towardsdatascience.com/emojify-machine-learning-web-app-using-flask-containerization-deployment-on-aws-14a9bdb75535?source=collection_archive---------8-----------------------

构建和部署机器学习 web 应用的直观指南。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

PC: Unsplash

在本教程中,我将分享我在使用 Flask 构建一个简单的端到端机器学习 web 应用程序并随后将其部署到 AWS 上的学习。只有当用户可以通过 web 应用程序交互地使用 ML 模型时,它的目的才能得到很好的服务。传统的 Jupyter 笔记本电脑只提供了一个交互式控制台,对于将它应用到 web 应用程序上没有多大用处。

Flask 是一个用 Python 编写的微框架,可以帮助我们快速开始构建应用程序。我们将使用 Keras 中的长短期记忆(LSTM)单元来训练来自深度莫吉数据集的数据。然后,我们将最终模型保存为 HDF5 文件,并在以后用于预测目的。最终的应用程序将像这个 链接 中提到的那样工作。让我们更深入地探讨如何使用 Docker 容器在 AWS 中构建和部署整个 web 应用程序。这个项目的代码可以在我的 Github repo 中找到。

内容

  1. 数据

2.数据提取和处理

3.嵌入层

4.双向 RNN 模型

5.训练模型

6.构建 Flask 应用程序

7.使用码头集装箱的集装箱化

8.将 Docker 映像推送到 AWS ECR

9.在 AWS EC2 上部署 Flask 应用程序

数据

我们将使用 深度莫吉 数据集,特别是 PsychExp 数据集来构建模型。数据集由 7840 个样本组成,其中每一行包含一条文本消息和编码为一个热点向量的标签。这些标签属于这 7 类中的一类——快乐、恐惧、愤怒、悲伤、厌恶、羞耻、内疚。数据集中的一行示例如下:[ 1\. 0\. 0\. 0\. 0\. 0\. 0.] I am very happy today.

数据提取和处理

Extracting text and labels from the pickled dataset.

在这个函数中,我们从 pickle 文件中提取文本和标签,然后将它们写入一个文本文件。

Separating Labels and Texts

在读取文本文件函数中,我们返回一个包含文本消息和标签的列表。然后,我们将消息和标签分离到单独的列表中。

对于任何 ML 模型,我们都必须以数字格式输入数据,以便进行处理。类似地,为了在 7 个类别中分类我们的输入文本,我们必须将我们的输入句子转换成单词向量表示。为此,我们将使用预先训练的 50 维手套单词嵌入。

上面的“read_glove_vector”函数返回给定单词的索引列表、给定索引的单词以及每个单词对应的 50 维表示。

嵌入层

在构建嵌入层之前,让我们知道为什么要使用嵌入层。让我们考虑我们有 1000 个单词的文本语料库。文本中每个单词的一个热编码将是具有 999 个零和 1 个非零值的向量。这些向量非常稀疏,不太适合大型数据集。在单词嵌入中,单词由密集向量表示,其中每个向量是单词在连续向量空间中的投影。因此,单词嵌入帮助将单词投影到一个更低的维度,而不是将单词投影到一个更高的维度。此外,单词嵌入帮助我们捕捉单词之间的关系,否则使用一个热编码向量难以捕捉。让我们看看如何为我们的应用程序实现这个嵌入层:

这里,嵌入层的第一个参数是手套单词嵌入中的单词总数,第二个参数是每个单词在向量空间中表示的维度。

双向 RNN 模型

双向 RNN 有两个网络,一个正向训练信息,另一个反向训练信息。因此,这些模型可以访问过去和未来的数据,而标准的 LSTM 模型只能访问过去的数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Bi-Directional LSTM

让我们在使用 Keras 的应用程序中看到它的实现。

LSTM Model

在这里,我们正在构建一个深度递归神经网络,它包含一个具有批量归一化和丢失的双向 LSTM。此处使用 Softmax 激活来获得跨 7 个类别的概率分布。

这是一个简化的图像,显示了我们整个 LSTM 模型的架构。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Architecture of our Neural Network

训练模型

我们将使用分类交叉熵作为损失函数,因为我们将在 7 个类别中对输出进行分类。我们将试图在每个时期最小化这种损失,以便它在测试数据上表现良好。Adam optimizer 用于帮助我们加快训练过程。准确性是我们在这里用来评估模型的性能指标。

X_train = pad_sequences(train_tokenized, maxlen = maxlen)
X_test = pad_sequences(test_tokenized, maxlen = maxlen)model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])model.fit(X_train, np.array(y_train), epochs = 30, batch_size = 32, shuffle=True)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后,我们将使用 Tensorflow 的 save_model 来保存 Keras 模型,以便我们稍后可以加载它来给出预测。经过 30 个周期的训练,准确率达到了 86%。

model.save('emoji_model.h5')
model = load_model('emoji_model.h5')

构建 Flask 应用程序

首先我们必须使用命令- **pip install flask** **安装 flask。**然后创建一个名为 application.py 的文件,这是我们应用程序的主要后端文件。

首先,我们必须实例化 Flask 类的一个对象。然后,我们使用 load_model 函数加载已经训练好的模型。我们还为文本标记器保存了一个 pickle 文件,以便它可以用于标记未来的文本输入。有两条路线-预测和更新。“预测”路由接收输入文本字段中输入的值,我们使用 tokenizer 对象对文本进行标记。我们使用加载的模型对输入文本进行预测,然后以 JSON 格式返回响应。“更新”路线用于在预测值不正确时更新预测值,以便针对新输入对模型进行微调。虽然这可能不是在大规模系统中更新模型的正确方法,但我想尝试一下模型再训练是如何工作的。为了返回预测的正确表情响应,创建了以下 Javascript 文件。

另一个 Javascript 文件可以通过从下拉列表中选择值来帮助我们进行更新操作,并向“update”路由发送 POST 请求来更新值。我不太擅长构建 UI,因此前端部分可以根据我们的需要进行更改。

我们将使我们的应用程序在主机 0.0.0.0 和端口 5000 上运行。我们也将在 Docker 文件中对此进行配置。这是在我们的 localhost 中运行后的最终应用程序的样子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用码头集装箱的集装箱化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Docker 是一个开源应用程序,允许用户使用容器创建、管理和部署应用程序。使用 Docker 运行的应用程序驻留在它们自己的环境中,并且拥有运行应用程序所需的依赖关系。Docker 可以使用以下 链接 安装在 Mac 上。 安装 docker 后移动到我们终端中的应用文件夹。创建一个 docker 文件,指导 docker 安装依赖项并在构建 Docker 映像时执行其他命令。

上面的 docker 文件指示 Docker 从 Docker hub 安装 python,然后创建一个‘app’目录来复制我们 web app 的所有内容。然后它会安装 requirements.txt 文件中提到的所有包。则暴露端口 5000 以从容器外部访问应用程序。默认情况下,使用 CMD 命令运行 application.py 文件。我们将把 docker 图像命名为“flaskapp”。现在我们必须使用以下命令构建 docker 映像。

docker build -t flaskapp:latest .

“.”在这个命令的末尾,复制当前目录中的所有文件来构建镜像。然后,我们将使用上面创建的 docker 映像在端口 5000 运行 docker 容器。该命令如下所示:

docker run -p 5000:5000 flaskapp

通过在浏览器的端口 5000 上启动应用程序,检查应用程序是否可在容器外部访问。

将 Docker 映像推送到 AWS ECR

我假设在 AWS 中已经创建了一个帐户。如果没有,任何人都可以按照这个 链接 免费上手。 我们必须使用**pip install awscli --upgrade --user**在桌面上安装**awscli**,以便直接从终端执行 AWS 中的操作。我们必须从我们的终端使用命令**aws configure** 来配置我们的 AWS 凭证,在这里我们输入我们的访问密钥 ID、秘密访问密钥、默认区域和输出格式。

我们将使用 AWS 弹性容器注册表来存储和部署我们的 docker 容器映像。为了存储 Docker 图像,我们必须首先在 AWS ECR 中创建一个存储库。这是使用以下命令完成的:

aws ecr create-repository --repository-name ml_flask_app

然后,为了获得访问 AWS ECR 的权限,我们输入以下命令-

$(aws ecr get-login --region region_name --no-include-email)

然后,我们在本地用创建的存储库标记我们的 flaskapp 容器。在这里,每个用户的 account_id 和 region name 是不同的。

docker tag flaskapp:latest aws_account_id.dkr.ecr.region_name.amazonaws.com/

然后,我们必须将本地 docker 映像推送到在 AWS ECR 中创建的存储库中。

docker push aws_account_id.dkr.ecr.region_name.amazonaws.com/ml_flask_app

在 AWS EC2 上部署 Flask 应用

将图像推送到 AWS ECR 后,我们必须创建一个 EC2 实例,在其中我们可以为 web 应用程序提供服务。AWS 在免费层范围内提供了许多实例,我们可以利用这一点。我们将启动一台 Linux 机器,其中大部分配置都是默认设置的,只有安全组进行了如下更改:

SSH ->仅从我们的 IP 和

自定义 TCP ->端口 5000。

这些安全组规则是我们的 web 应用程序运行所必需的。一旦实例启动并运行,我们可以通过在终端中的‘PEM’文件所在的同一文件夹中输入以下命令来 ssh 到实例中。

ssh -i "test_ml_app.pem" [ec2-user@ec2-12-345-67-89.us-east-1.compute.amazonaws.com](mailto:ec2-user@ec2-18-191-94-75.us-east-2.compute.amazonaws.com)

一旦我们登录到实例中,我们可以使用下面的命令安装 docker 并启动它。

sudo yum install -y docker
sudo docker service start

我们必须像以前一样通过再次输入 aws configure 命令来配置 AWS 凭证。然后输入以下命令,以便添加 ec2 用户来在 Linux 机器上执行 docker 命令。

sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo service docker restart

然后退出该实例,并再次使用 ssh 进入该实例。运行以下命令从 AWS ECR 中提取 docker 映像,然后在 Linux 机器中运行 docker 容器。

docker pull account_id.dkr.ecr.region_name.amazonaws.com/ml_flask_app_:latestdocker run -p 5000:5000 account_id.dkr.ecr.region_name.amazonaws.com/ml_flask_app

从实例详细信息页面获取实例的公共 IP,并在浏览器中启动时添加端口 5000。瞧啊。!!这款应用终于在 AWS 上运行了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们检查一些给出错误预测的输入。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,我们将为上述输入更新标签为“Sad”的模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在那里!!该模型已经更新了其对新输入文本的响应,并将尝试改进其对未来输入的预测。

因为这是我的第一个博客,我请求你们分享你们对这个博客的内容和质量的看法。如果有任何疑问,我非常乐意帮忙。你可以在 Linkedin @Sri ram Muralishankar上和我联系。

参考资料:

  1. 深度莫吉数据集-【https://github.com/bfelbo/DeepMoji/tree/master/data
  2. Coursera 序列模型教程-https://github . com/kul bear/deep-learning-coursera/blob/master/Sequence % 20 Models/Emojify % 20-% 20 v2 . ipynb
  3. AWS 文档-https://docs.aws.amazon.com/
  4. 码头文件-https://docs.docker.com/

情绪检测:一个机器学习项目

原文:https://towardsdatascience.com/emotion-detection-a-machine-learning-project-f7431f652b1f?source=collection_archive---------0-----------------------

一个关于情感检测的计算机视觉项目

情绪检测( n.):

识别人类情感的过程

如果有人给你看一张某人的照片,并让你猜猜他们的感受,你很可能会有很好的想法。如果你的电脑也能做到这一点会怎么样?如果它能变得比你更好呢?这似乎是一个荒谬的想法,对不对?

在我的上一篇博客(读作: 揭秘人工智能 )中,我说过我会解释一个项目,展示所讨论的概念是如何应用的。

下面的博客包含了我们在 InspiritAI 项目期间所做的一系列事情的回忆,虽然它确实显示了进行情绪检测所需的大量代码,但这绝不是训练模型的最快方法。使用多个 ML 和 AI 模型来查看它们之间的差异。

情绪检测的三个主要组成部分如下:

  1. 图像预处理
  2. 特征抽出
  3. 特征分类

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

面部检测:

人脸检测是情感检测中的一个重要步骤。它会删除图像中不相关的部分。这里有一种在图像中检测人脸的方法。

import dlib
import numpy as npfrontalface_detector = dlib.get_frontal_face_detector()def rect_to_bb(rect):
    x = rect.left()
    y = rect.top()
    w = rect.right() - x
    h = rect.bottom() - y
    return (x, y, w, h)def detect_face(image_url):
    try:
        url_response = urllib.request.urlopen(image_url)
        img_array = np.array(bytearray(url_response.read()), dtype=np.uint8)
        image = cv2.imdecode(img_array, -1)rects = frontalface_detector(image, 1)if len(rects) < 1:
    return "No Face Detected"for (i, rect) in enumerate(rects):
    (x, y, w, h) = rect_to_bb(rect)
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)plt.imshow(image, interpolation='nearest')
plt.axis('off')
plt.show()

另一种方法是使用 dlib 的预训练人脸检测器模型,该模型也将在下一点中使用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

面部标志:

面部标志是人脸图像上的一组关键点。这些点由它们在图像上的(x,y)坐标定义。这些点用于定位和表示面部的显著区域,例如眼睛、眉毛、鼻子、嘴和下颌线。

我们使用的面部标志模型是 Dlib 的预训练面部标志检测模型,它检测人脸上的 68 个二维点。

您可以像这样加载模型:

import dlib
import numpy as npfrontalface_detector = dlib.get_frontal_face_detector()landmark_predictor=dlib.shape_predictor('./shape_predictor_68_face_landmarks.dat')def get_landmarks(image_url):
    try:
        url_response = urllib.request.urlopen(image_url)
        img_array = np.array(bytearray(url_response.read()), dtype=np.uint8)
        image = cv2.imdecode(img_array, -1) except Exception as e:
        print ("Please check the URL and try again!")
        return None,None
    faces = frontalface_detector(image, 1) if len(faces):
        landmarks = [(p.x, p.y) for p in landmark_predictor(image, faces[0]).parts()] else:
        return None,None

    return image,landmarksdef image_landmarks(image,face_landmarks):
    radius = -1
    circle_thickness = 4
    image_copy = image.copy()
    for (x, y) in face_landmarks:
        cv2.circle(image_copy, (x, y), circle_thickness, (255,0,0), radius)
        plt.imshow(image_copy, interpolation='nearest')
        plt.axis('off')
        plt.show()

使用该模型后,您的输出应该如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这个模型中,面部特征的具体标志是:

Jawline = 0–16
Eyebrows = 17–26
Nose = 27–35
Left eye = 36–41
Right eye = 42–47
Mouth = 48–67

区分两种情绪的一种方法是看这个人的嘴和眼睛是否张开。我们可以找到嘴部各点之间的欧几里德距离,如果一个人感到惊讶,这个距离会比他们没有惊讶时更大。

数据预处理

在使用数据之前,重要的是要经过一系列被称为预处理的步骤。这使得数据更容易处理。

我们将使用由五个情感标签组成的 fer2013 数据集的修改版本。

数据集存储在 CSV 文件中。CSV 文件中的每一行都代表一个实例。每个实例都有两个列属性:

  • 以字符串格式存储的图像像素
  • 目标标签的整数编码

共有 20,000 个图像平均分布在五种情绪中。这些图像是 48*48 灰度的裁剪图像。CSV 文件由以字符串形式存储的图像的扁平数组组成

The target labels are integer encoded in the csvfile. They are mapped as follows:0 — -> Angry
1 — -> Happy
2 — -> Sad
3 — -> Surprise
4 — -> Neutral

加载数据集

import pandas as pd
import numpy as np
import matplotlib.pyplot as pltlabel_map={"0":"ANGRY","1":"HAPPY","2":"SAD","3":"SURPRISE","4":"NEUTRAL"}df = pd.read_csv("./ferdata.csv")df.head()

该数据集包含图像的原始像素值。

拆分数据

正如上次讨论的那样,数据需要分成两个不同的集合:

  1. 训练集:算法会一遍又一遍地读取或“训练”它,以尝试和学习它的任务。
  2. 测试集:算法在这些数据上进行测试,看看它的效果如何。
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(dataX, dataY, test_size=0.1,random_state=42,stratify =dataY)

使数据标准化

标准化是将不同的变量放在同一尺度上的过程。它重新调整数据,使平均值为 0,标准差为 1。这种转换以数据为中心。

from sklearn.preprocessing import StandardScalerscaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

线性模型

k-最近邻

KNN 是一种非参数学习算法,这意味着它不对数据的分布做出任何假设。我们使用点之间的欧几里得距离作为数据。

from sklearn.neighbors import KNeighborsClassifierknn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, Y_train)
predictions = knn.predict(X_test)

要确定模型的准确性:

from sklearn.metrics import accuracy_scoreprint(accuracy_score(Y_test, predictions)*100)

我们的准确率约为 50%,所以我们尝试了一些非线性模型。

您可以尝试将原始像素值输入到模型中,并查看它如何影响模型的准确性。

非线性模型

多层感知器

MLPs 是神经网络的一个子类。它们由一层或多层神经元组成。输入层是输入数据的地方,之后可能有一个或多个隐藏层。预测来自输出层。

from keras.models import Sequential
from keras.utils import to_categorical
from keras.layers import Dense, Dropout, Flatten, Activation
from keras.losses import categorical_crossentropy
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras.models import load_model
from keras.optimizers import Adam, SGDmlp_model = Sequential()mlp_model.add(Dense(1024, input_shape = (2304,), activation = 'relu', kernel_initializer='glorot_normal'))mlp_model.add(Dense(512, activation = 'relu', kernel_initializer='glorot_normal'))mlp_model.add(Dense(5, activation = 'softmax'))mlp_model.compile(loss=categorical_crossentropy, optimizer=SGD(lr=0.001), metrics=['accuracy']) checkpoint = ModelCheckpoint('best_mlp_model.h5',verbose=1,
monitor='val_acc', save_best_only=True,mode='auto')mlp_history = mlp_model.fit(X_train, y_train, batch_size=batch_size,
epochs=epochs, verbose=1, callbacks=[checkpoint], validation_data(X_test, y_test),shuffle=True)

我们使用像素的准确率大约是 50%,当我们使用面部标志之间的距离而不是像素值时,准确率有所提高。然而,我们想要更精确的模型,所以我们决定使用 CNN。

卷积神经网络

width, height = 48, 48X_train = X_train.reshape(len(X_train),height,width)X_test = X_test.reshape(len(X_test),height,width)X_train = np.expand_dims(X_train,3)X_test = np.expand_dims(X_test,3)cnn_model = Sequential()cnn_model.add(Conv2D(5000, kernel_size=(4, 4), activation='relu', padding='same', input_shape = (width, height, 1)))cnn_model.add(BatchNormalization())cnn_model.add(MaxPooling2D(pool_size=(3, 3), strides=(4, 4)))cnn_model.add(Dropout(0.2))cnn_model.add(Flatten())cnn_model.add(Dense(2000, activation='relu'))cnn_model.add(Dropout(0.2))cnn_model.add(Dense(5, activation='softmax'))checkpoint = ModelCheckpoint('best_cnn_model.h5', verbose=1, monitor='val_loss',save_best_only=True, mode='auto')cnn_model.compile(loss=categorical_crossentropy,
optimizer=Adam(lr=0.001, beta_1=0.9, beta_2=0.999), 
metrics=['accuracy'])cnn_history = cnn_model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, callbacks=[checkpoint], 
validation_data=(X_test, y_test),shuffle=True)cnn_model.save('cnn_model.h5')

为了提高性能,你可以改变下降,密集层的数量和激活功能。我们还使用名为 VGG 的 CNN 进行迁移学习,这是一种用于图像分类的预训练卷积神经网络。

E 估价

使用 VGG 得到的结果最好,其正确率约为 68–70 %,但即使是线性模型也做得非常好。虽然 50%的准确率看起来不算多,但这仍然比你随机选取一张图片和一个标签要高。在这一点上,你大约有 20%的几率是正确的。

然而,在这个特定的数据集中,VGG 的表现甚至比人类更好。CNN 和 MLP 之间的区别在于,CNN 提取他们自己认为重要的特征,而我们将像素或界标作为特征提供给 MLP。

更多关于 KNNs、CNN、MLPs 和其他基本机器学习主题的信息,请点击此链接

特别感谢 Adeesh Goel 组织了这次令人惊叹的研讨会,查看 facebook 页面【InspiritAI】,感谢 Tyler Bonnen 担任如此出色的导师并指导我们完成该计划,并感谢我的团队成员 Khushi 和 Harsh。

基于图卷积网络的情感识别

原文:https://towardsdatascience.com/emotion-recognition-using-graph-convolutional-networks-9f22f04b244e?source=collection_archive---------9-----------------------

使用图形对对话进行分类

最近,深度学习在自然语言处理(NLP)方面取得了很大进展。随着许多新发明(如注意力和变形金刚)的出现,BERT 和 XLNet 等先进模型应运而生,许多任务(如文本情感识别)变得更加容易。本文将介绍一种新的方法,利用图形从对话中进行情感识别。

什么是情感识别?

简单地说,情绪识别(ERC)是对一项书面任务背后的情绪进行分类的任务。给定一段文字,你能说出说话者是生气、高兴、悲伤还是困惑吗?它在医疗保健、教育、销售和人力资源方面有许多广泛的应用。在最高层面上,ERC 的任务是有用的,因为许多人相信,它是构建能够与人对话的智能人工智能的垫脚石。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

An example of using ERC to power a health assistant (image taken from [1])

目前,大多数 ERC 所基于的两个主要创新是递归神经网络(RNN)和注意力机制。LSTMs 和 GRUs 等 rnn 按顺序查看文本。当文本很长时,模型对开始部分的记忆会丢失。注意力机制通过对句子的不同部分进行不同的加权很好地解决了这个问题。

然而,RNNs+Attention 仍然很难从相邻序列和说话者(基本上任何对话的所有非常重要的部分)中考虑个性、主题和意图的上下文。再加上缺乏个性/情感的标记基准数据集,不仅难以实施,而且难以衡量新模型的结果。本文将总结最近的一篇论文,该论文通过使用一种相对较新的称为图卷积网络的创新解决了大部分问题: DialogueGCN:一种用于对话中情感识别的图卷积神经网络 [1]。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

背景很重要

在对话中,上下文很重要。一个简单的“还好”可以表示“还好吗?”,“好的!”或者“好吧…”取决于你和对方之前说了什么,你现在的感觉如何,对方的感觉如何,紧张程度以及其他许多事情。有两种类型的上下文很重要:

  1. 顺序语境:一个句子在一个序列中的意义。这种语境处理过去的词如何影响未来的词、词的关系以及语义/句法特征。在 RNN 模型中,顺序上下文被考虑在内。
  2. 说话人层面的语境:说话人之间和说话人内部的依赖。这种语境涉及说话者之间的关系以及自我依赖性:即你自己的个性会改变并影响你在对话过程中的说话方式。

正如你可能猜到的,大多数模型很难考虑说话者级别的上下文。事实证明,使用图形卷积神经网络可以很好地模拟说话者级别的上下文,这正是 DialogueGCN 采用的方法。

用图形表示对话

一段对话中有 M 说话人/当事人分别表示为***【1】p【2】,。。。,p【M】。每一个话语(有人发的一段文字)都表示为u【1】u【2】,。。。,【N】*。ERC 的最终目标是准确地预测每个话语是高兴、悲伤、中立、愤怒、兴奋、沮丧、厌恶还是恐惧。

整个对话可以构建成一个有向图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A conversation graph with 2 speakers and 5 utterances. [CORRECTION IN BOTTOM RIGHT IMAGE: For the arrow going from U1 to U2, one of the labels should be W1->2, not W2->1]

G = (V,E,R,W)

  • 话语是节点( V )。边是节点*【E】之间的路径/连接。关系是边的不同类型/标签【R】。权重代表一条边的重要性【W】*
  • 两个节点*v【I】v【j】*之间的每条边都有两个属性:关系( r )和权重( w )。我们稍后会详细讨论这个问题。
  • 图形是指向的。所以,所有的边都是单向的。从*v【I】v【j】的边缘不同于从v【j】v【I】*的边缘。

从图中可以注意到的一点是,每个话语都有一条边与其自身相连。这代表了话语与其自身的关系。用更实际的话来说,这就是一个话语如何影响说话者的思想。

上下文窗口

图形表示的一个主要问题是,如果一个会话非常长,那么一个节点可能有许多条边。因为每个节点都与其他节点相连,所以随着图形大小的增加,它的比例是二次方的。这在计算上非常昂贵。

为了解决这个问题,在 DialogueGCN 中,图形的边是基于具有特定大小的上下文窗口构建的。所以对于一个节点/话语 i ,只有过去的大小和未来的大小话语连接在一个图中(在 i- 大小i+ 大小范围内的任意节点)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A context window of size 1 around the third utterance

边缘权重

使用注意函数来计算边权重。设置注意函数,使得对于每个节点/话语,输入的边权重总和为 1。边权重是常数,在学习过程中不会改变。

简而言之,边权重表示两个节点之间连接的重要性。

关系

边的关系取决于两个因素:

  • 说话人依赖:谁说了 【我】 ?谁说出了v【j】
  • 时态依存:是*【I】【j】*之前说出,还是反过来?

在一次对话中,如果有MM***(说话人***【j】)M(说话人【j】) 2(是否**【I】*【T57)*****

我们可以列出上面示例图中的所有关系:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A table of all the possible relations in our example

这是同一张图,根据表格标注了边的关系:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Edges are labelled with their respective relation (refer to table above)

在我们例子中,我们有 8 种不同的关系。在高层次上,关系是 edge 的一个重要属性,因为在对话中谁说了什么以及何时说了什么非常重要。如果彼得问一个问题,珍妮回答,这与珍妮先说答案,然后彼得问问题(时间依赖)是不同的。同样,如果 Peter 问 Jenny 和 Bob 同样的问题,他们可能会有不同的回答(说话者依赖)。

将关系视为定义连接的类型,边权重表示连接的重要性。

将关系视为定义连接的类型,边权重表示连接的重要性。

模型

DialogueGCN 模型使用一种称为图形卷积网络 (GCN)的图形神经网络。

就像上面一样,所示的例子是针对 2 个说话者 5 个话语的图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3 from [1]

在阶段 1 中,每个话语*【I】被表示为特征向量,并被给予顺序上下文编码。这是通过在顺序上下文编码器中使每个话语通过一系列 gru 来完成的。阶段 1 不需要图形结构。具有连续语境的新话语表示为【g【1】***……。***g【N】*文中。这是对 GCN 的输入。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在阶段 2 中,该模型构建了一个类似于上一节中讨论的图,并且将使用特征变换将说话者级别的上下文添加到该图中。具有连续语境和说话者层次语境的话语由*【1】***……***h【N】*表示。这是 GCN 的产量。

边和节点的外观差异(虚线与实线,不同的颜色)代表不同的关系。例如,绿色的g【1】到绿色的g【3】,用绿色的实边表示表中的关系 1。

特征变换—嵌入说话者级上下文

GCN 最重要的步骤之一是特征转换——基本上是 GCN 如何将说话者级别的上下文嵌入到话语中。我们将首先讨论所使用的技术,然后描述它的直觉来自哪里。

特征转换有两个步骤。在步骤 1 中,对于每个节点*【h[I],聚集相邻节点信息(上下文窗口大小内的节点)以创建新的特征向量【h[I]*

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

该函数可能看起来很复杂,但其核心只是将它想象为网络中的一层,具有由*【0】W【r】表示的可学习参数。添加的一个东西是常数c【I,r】*它是一个归一化常数。可以提前设置,也可以用网络自己学习。

如前所述,边权重是恒定的,不会在过程中改变或学习。

第二步,同样的事情基本上再做一遍。聚集邻居信息,并将类似的函数应用于步骤 1 的输出。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Equation 2 (Step Two)

再次, W*W【0】*表示在训练过程中修改的可学习参数。

在高层次上,这一两步过程实质上是对每个话语的所有相邻话语信息进行归一化求和。在更深的层次上,这种两步转换植根于简单的可区分的消息传递框架 [2]。这项技术被从事图形卷积神经网络工作的研究人员用于关系数据建模【3】。如果你有时间,我强烈推荐你按照这个顺序阅读这两篇论文。我相信 DialogueGCN 的特性转换过程所需的所有直觉都在那两篇论文中。

GCN 的输出由*h【1】表示……【N】*图上。

在阶段 3,原始顺序上下文编码矢量与说话者级别上下文编码矢量连接。这类似于将原始层与后来的层组合起来,以“总结”每一层的输出。

然后,连接的特征向量被送入全连接网络进行分类。最终输出是模型认为话语是不同情绪的概率分布。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用具有 L2 正则化的分类交叉熵损失来完成模型的训练。使用这种损失是因为模型正在预测多个标签(情感类别)的概率。

结果

基准数据集

之前我们提到缺乏基准数据集。这篇论文的作者能够通过使用标记的多模态数据集(文本以及视频或音频)来解决这个问题,然后提取文本部分,并完全忽略任何音频或视频数据。

DialogueGCN 在以下数据集上进行评估:

  • IEMOCAP: 视频格式的十个不同说话者的双向对话。话语被标记为快乐、悲伤、中性、愤怒、兴奋或沮丧。
  • AVEC:人类和人工智能代理之间的对话。话语有四个标签:化合价([-1,1])、唤醒([-1,1])、期待([-1,1])和力量([0,无穷大])。
  • MELD: 包含电视剧《老友记》中的 1400 段对话和 13000 句话语。MELD 还包含补充的听觉和视觉信息。话语被标记为愤怒、厌恶、悲伤、喜悦、惊讶、恐惧或中性之一。

MELD 具有预定义的培训/验证/测试分割。AVEC 和 IEMOCAP 没有预定义的分割,所以 10%的对话被用作验证集。

DialogueGCN 与 ERC 的许多基线和最新模型进行了比较。一个特殊的艺术模型状态是 DialogueRNN 由同一论文的作者。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

DialogueGCN vs. other models on the IEMOCAP dataset (table taken from [1])

在 IEMOCAP 的 6 个类别中的 4 个类别中,DialogueGCN 相对于包括 DialogueRNN 在内的所有模型显示出显著的改进。在“愤怒”类别中,DialogueGCN 与 DialogueRNN 基本持平(GCN 在 F1 得分上仅差 1.09)。只有“兴奋”类别显示出足够大的差异。

DialogueGCN 能够在 AVEC 和梅尔德上产生类似的结果,击败现任 DialogueRNN。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

DialogueGCN vs. other models on the AVEC and MELD datasets (table taken from [1])

从结果中可以清楚地看出,将说话者级别的上下文添加到对话图内在地提高了理解。DialogueRNN 很好地捕捉了连续上下文,但缺乏对说话人上下文进行编码的能力。

分析

实验的一个参数是上下文窗口的大小。通过扩展尺寸,能够增加特定话语的边数。人们发现,尽管计算成本更高,但尺寸的增加改善了结果。

作者做的另一个有趣的实验是消融研究。一次拆除一个编码器,并重新测量性能。发现说话者级别的上下文编码器(阶段 2)比顺序上下文编码器(阶段 1)稍微重要一些。

还发现错误分类往往发生在两种情况下:

  • 类似的情绪类如“沮丧”和“愤怒”,或“兴奋”和“高兴”。
  • 像“好的”或“是”这样的简短话语。

因为使用的所有数据集都是多模态的,并且包含音频和视频,所以可以通过集成音频和视觉多模态学习来提高这两种情况下的准确性。虽然分类错误仍然会发生,但值得注意的是,DialogueGCN 仍然在准确性方面带来了非常显著的提高。

关键要点

  • 背景很重要。一个好的模型不仅要考虑对话的连续语境(句子的顺序,哪些单词与其他单词相关),还要考虑说话者层面的语境(谁说了什么,他们什么时候说的,他们如何受到其他说话者和他们自己的影响)。与传统的基于顺序和注意力的模型相比,整合说话者级别的上下文是一大进步。
  • 序列不是表示对话的唯一方式。如果这篇论文展示了一件事,那就是数据的结构可以帮助捕捉大量的上下文。在这种情况下,说话者级别的上下文更容易以图形格式编码。
  • 图神经网络是自然语言处理中一个很有前途的研究方向。聚合邻居信息的关键概念虽然在概念上很简单,但在捕捉数据关系方面却非常强大。

感谢阅读!

你可以在Linkedin 或【kshen3778@gmail.com】与我联系

原文:https://arxiv.org/abs/1908.11540

来源:

[1]戈萨尔、迪潘威&马朱姆德、纳沃尼&茯苓、苏扬亚&恰亚、尼亚提&格尔布克、亚历山大。(2019).DialogueGCN:用于对话中情感识别的图形卷积神经网络。

[2] Michael Schlichtkrull、Thomas N Kipf、Peter Bloem、Rianne Van Den Berg、Ivan Titov 和 Max Welling。2018.用图卷积网络建模关系数据。欧洲语义网会议,593-607 页。斯普林格。

[3]贾斯汀·吉尔默、塞缪尔·舍恩霍尔茨、帕特里克·F·赖利、奥里奥尔·维尼亚尔斯和乔治·E·达尔。2017.量子化学的神经信息传递。《第 34 届机器学习国际会议论文集》第 70 卷,第 1263-1272 页。JMLR。org。

为硬件设计和制造领域的公民数据科学家提供支持

原文:https://towardsdatascience.com/empowering-a-citizen-data-scientist-for-hardware-design-manufacturing-6f5af585594?source=collection_archive---------25-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

利用先进的人工智能工具提高硬件设计和制造专业人员的工作效率

作者:帕萨·德卡和罗希特·米塔尔

什么是公民数据科学家?

专家数据科学家依靠自定义编码来理解数据。用例可以是数据清理、数据插补、创建分段、查找数据中的模式、构建监督模型以预测目标、分类/回归问题的特征重要性分析、了解结果的可能原因、查找可能影响结果的可调参数,甚至深度学习问题的图像预处理等。

如上所述,公民数据科学家是高级分析的超级用户。但公民数据科学家的特质不同于专家数据科学家。他们的主要职责在统计和分析领域之外,他们是专家数据科学家的补充。公民数据科学家更有背景,对业务领域有独特的视角,更关注应用分析技术的业务问题,对与业务优先级相关的问题有更大的兴趣,并有能力证明业务价值。

在制造组织中,硬件设计工程师或工厂车间制造工程师也可以戴上公民数据科学家的帽子。优化设计流程或提高工厂的生产能力/产量可能是他们的目标,以便从流程中获得更多商业价值。

利用内部构建的硬件工具自动执行高级分析:

我们为硬件专业人员构建了一个高级分析工具。所谓硬件,我们指的是半导体和电路板级系统。我们的目标是使包括 AI 和 ML 在内的分析民主化,以便公民数据科学家可以更加专注于商业价值,而无需花费时间编写程序/代码来执行高级分析。我们的工具在不断发展,我们已经在工具中内置了一些功能:

自动数据预处理和数据清理

自动特征分析包括但不限于:

过滤方法,如皮尔逊相关、方差分析、线性判别分析、卡方检验

递归特征消除

主成分分析(PCA) &了解特性的影响→了解数据中具有各自过载特性的片段

主成分分析降维

无监督学习问题的各种聚类技术

深度学习能力:

图像识别:使用流行的 CNN 模型创建像素特征,并在 ImageNet 图像上预先训练权重(【http://www.image-net.org/】T2)

使用上一步中的特征自动寻找分类问题的最佳模型

通过对数据训练各种模型,自动找到最佳监督模型(分类/回归)。这是一个关键特性,使未经培训的专业人员能够利用 ML 解决他们的问题。

可以根据特定的制造需求增加额外的功能。例如,通过超参数调整或 ROC 阈值来微调模型的假阳性和假阴性。不太常见的用例特定建模。

以下是关于 ML 功能的模块化流程:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

深度学习能力的模块化流程如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据集内的搜索模式示例:

我们的“分析模式/片段”模块(内置于我们的工具中)可自动洞察数据中与特征权重相关的现有片段。我们的工具自动对数据进行主成分分析,并自动绘制一个由特征权重解释的信息方差图。此外,它还提供关于数据中现有模式/聚类的智能自动建议。我们发现这种能力在根据特性重要性寻找产品测试失败模式时非常有用。下面是使用我们的工具进行模式分析的流程:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论:

我们已经建立了一个先进的分析工具,并不断增强其功能。我们的目标是在我们组织的硬件工程/制造社区中普及 AI & ML 的使用。借助我们的工具,我们在许多设计和制造用例上实现了良好的投资回报,例如产量提高、生产量优化、硬件材料缺陷检测、识别优化硬件设计的可调参数等。我们看到越来越多的人采用我们的工具,并设想引入特定但通用的可重用分析,这将满足我们组织内各种子组织的关键业务用例。

参考资料:

https://scikit-learn.org/stable/

【https://www.tensorflow.org/

http://www.image-net.org/

启用 ML 实验

原文:https://towardsdatascience.com/enable-ml-experiments-4ba8c3c8bdc2?source=collection_archive---------17-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

向前

最近受到 Dmitry Petrov 关于机器学习模型和数据集版本化实践机器学习项目中数据版本化的演讲的启发。

在大多数当前的 ML 系统中,缺乏有效和系统的方式 s 来以敏捷、持续和可维护的方式通过数据科学将数据的价值传递到市场中。

马丁·福勒关于连续交付机器学习 (CD4ML)的优秀著作中已经指出了一个解决方案。

这篇文章提出了一个关于系统地进行 ML 实验的思路,这是机器学习应用程序持续交付的重要一步。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

工作流程—模型

数据科学与软件开发的不同之处在于它是基于实验的,而不是基于特性的。

工作流模型的核心思想是 ML 实验的编码和随之而来的优势(版本化、可再现性、自动化)。

实验

ML 实验被建模为位于 git 分支中的 ML 管道代码

ML 实验的组件视角是:

ML Experiment = Code + Data + Model

所有这三个元素都可以编码成“管道代码”或元数据。

所以 ML 实验的另一个角度:

# ML experiment can be perceived as procedure which takes data as input and ML model as output along with a score telling how good the model performsroutine ML Experiment(data):
body        
    pipeline code
    ...return ML Model, score

一般来说,这个过程遵循常见的模式,例如,Olson 的一篇论文中的所示的模式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

【压缩】数据和模型—元数据

git 系统很难跟踪大型数据集。解决方法是通过为每个数据和模型创建一个元数据文件来“分而治之”。

元数据很小(因此适合 git 系统),同时包含恢复原始数据和模型的所有信息。[参见:版本控制 ML 模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

“管道”代码— DAG

ML 管道代码通常用 DAG ( 有向无环图 )建模,这也是 Apache Spark、Apache Airflow 和大多数现代数据操作工具的基础数据模型。

这就是为什么 dvc 管道 也可以整合成 阿帕奇气流

工作空间

Workspace 是 ML 实验的快照,建模为 git 分支上的提交。可以用 git 标签做书签。ML 实验是工作空间的进化。

工作空间包括我们在给定的时间点重现实验所需的所有信息。

工作区有两种常见的操作。

  • 改变一个工作区

这可能是数据更改:

# first create metadata
$ dvc add dataset.csv
# then put metadata under version control
$ git add dataset.csv.dvc

这可能是管道代码更改:

$ dvc run new-pipeline-script
$ git add new-pipeline-script.dvc
  • 恢复一个工作区

检查代码和元数据,使用元数据恢复数据集

$ git clone [https://gitlab.com/wutianchen/blog-enable-ml-experiments.git](https://gitlab.com/wutianchen/blog-enable-ml-experiments.git)
$ git checkout tags/baseline
# Now we have code and metadata restored, to completely restore the workspace from that.
# dvc looks for metadata and checkout data according to the path stored in metadata.
$ dvc checkout
$ dvc pull

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

工作流—示例

工作区的结构,例如 ML 实验,如上图所示。工作区应该一直使用 s3 这样的远程云 BLOB 作为后端存储。但是在这个演示中,local-remote 被用作远程存储的模拟,因此云提供商帐户不是重现它的必要条件。(git repo for demo 可以在 这里找到 )

此外,工作空间可以“安装”到远程计算单元,如 AWS EC2、AWS Sagemaker 来进行计算,但是本地桌面也足够了。

实验:基线

快速浏览基线实验(存储库/标签:基线)。包括三个流水线步骤( data_preparation.dvcmodel_selection.dvcmodel_evaluation.dvc )。

数据准备步骤将整个数据集作为输入,并输出四个数据集 iris_train_X.csv、iris_train_Y.csv、iris_test_X.csv、iris_test_Y.csv。这些信息记录在管道元数据(data_preparation.dvc)中

基线模型的性能被写入一个名为 auc.metric 的文件,该文件稍后可用于 e 实验比较。跟踪 ML 实验度量和管理模型比较的更好选择是MLflowtracking(其中不在本文的讨论范围内)。

实验:特征多模型

现在,从基线实验开始,我们想通过进行另一个实验来探索和提高系统的性能,尝试新的想法。

  1. 恢复基线实验工作空间在另一个分支进行新实验 【特征-多模型】
$ git clone [https://gitlab.com/wutianchen/blog-enable-ml-experiments.git](https://gitlab.com/wutianchen/blog-enable-ml-experiments.git)# checkout baseline and create feature branch
$ git checkout -b feature-multiple-models tags/baseline# restore remote dataset into workspace
$ dvc checkout
$ dvc pull

22。添加更改

通过尝试一堆模型来试验增强 model_selection.dvc 的新想法,并最终选择在训练数据集上具有最佳性能的模型。

3。在特征多模型分支 上运行新的 ML 实验

$ dvc run -d data/iris_X_train.csv -d data/iris_Y_train.csv -o model/model.pickle -f model_selection.dvc python code/model_selection.py# keep model_selection.dvc under git control
$ git add model_selection.dvc
$ dvc run -d data/iris_X_test.csv -d data/iris_Y_test.csv -d model/model.pickle -M auc.metric -f model_evaluation.dvc python code/model_evaluation.py
$ git add model_evaluation.py

现在,我们有了一个新的模型和分数来衡量新模型在测试数据集上的性能。

4。比较两个实验(基线和特征多模型)

$ dvc metrics show -a

产出:

working tree:
        auc.metric: 0.896551724137931
feature-multiple-models:
        auc.metric: 0.8275862068965517
master:
        auc.metric: 0.8275862068965517

在新想法上观察到性能提升,因此我们希望保留它。

5。存储工作区

$ dvc add
$ dvc push
$ git add .
$ git commit -m “add feature-multiple-models”
$ git tag -a "improved-multiple-models" -m "feature-multiple-models"
$ git push origin feature-multiple-models --tags

6。合并回发布分支

因为我们现在有了一个得分更高的模型,我们可以通过将它合并到主分支中来发布新的模型。

$ git checkout master
$ git merge master feature-multiple-models

在它被合并回主版本后,我们有两个选择:

  1. 保留特征多模型以供进一步分析
  2. 删除特征-多模型分支

编后记

我们以系统的方式建立了进行 ML 实验的基本工作流程,并用一个例子展示了它的可用性。但它只是触及了这个领域的表面。这一行还可以包含更多的主题,例如:

  1. 高级实验场景:特征-pca 和特征-滤波器-噪声

想象一下,两个数据科学家在两个实验分支上协同工作,但又分开工作(程序与实验相同:特征多模型)。数据科学家 1 希望对要素运行 PCA。数据科学家 2 想要过滤原始数据集的记录以清理数据。

问题是我们如何解决这两个实验的合并冲突。

谁打谁?

  • 分数较好的实验总是赢吗?那会不会太合适了?
  • 有没有可能把两个实验的方法结合起来?

2。实验对比、管理和自动化**

对于大型项目,我们可能会有成百上千个实验分支。可视化,比较实验和合并实验将变得越来越困难。

有为 ML 实验管理搭建的商业解决方案,比如 Neptune。向他们学习会很有趣。

[## 海王星-机器学习平台

2016 年 1 月,deepsense.ai 在 Kaggle 上赢得了露脊鲸识别大赛。竞赛的目标是自动化…

deepsense.ai](https://deepsense.ai/neptune-machine-learning-platform-post/)

3。AutoML

最后但同样重要的是,由于 ML 实验的编纂,实验过程也可以以某种方式自动化,这导致了一个热门的研究领域 autoML[参见:自动化机器学习的过去、现在和未来 ]。

快乐实验!😃

结论

  • 机器学习是基于实验的
  • ML 实验=代码+模型+数据
  • ML 实验可以首先被编码,然后被版本化和自动化
  • 使用 git 分支对 ML 实验建模
  • 使用 git commit 对 ML 实验工作区建模
  • 使用 git 标记来标记实验,以便进一步恢复和比较

更聪明地编码:如何轻松地将分类编码集成到您的机器学习管道中

原文:https://towardsdatascience.com/encode-smarter-how-to-easily-integrate-categorical-encoding-into-your-machine-learning-pipeline-89debe3ce24c?source=collection_archive---------26-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

自动化特征工程通过简化 ML 管道中一个关键的、但手动密集的步骤,解决了应用机器学习中最大的问题之一。然而,即使在特征工程之后,处理非数字数据以供机器学习算法使用也是不可避免的,并且提出了自己的一系列独特挑战。

这篇文章既是分类编码的指南,也是对用于自动分类编码的 Python 库的介绍,Python 库的设计考虑到了易于集成到 T2 特征工程工作流程中。

分类编码:是什么/为什么

当谈到自动机器学习时,传统上主要关注的是选择特定的算法或细化模型的参数,但应用机器学习的大部分工作往往源于过程中的其他步骤。例如,必须首先从原始数据中提取相关的预测变量、特征——这一步被称为特征工程,是必不可少的,但它也可能是应用 ML 过程中最需要手动操作的步骤之一。

类似地,处理非数字数据几乎是每个机器学习过程的关键组成部分。在应用机器学习中,两种最常见的数据类型是数字数据(如年龄:5、17、35)和分类数据(如颜色:红、蓝、绿)。处理数字数据通常比处理分类数据更容易,因为机器学习算法对不知道上下文的数学向量进行操作。

相比之下,许多机器学习模型无法直接处理分类数据。分类值没有任何内在的数学关系,因此我们必须先对数据做一些工作,然后才能将其输入到机器学习模型中。将分类数据转化为可用的、机器学习就绪的数学数据的过程称为分类编码。

分类编码 API:在哪里

为了创建普遍适用于任何机器学习流水线的编码器,必须考虑需要对数据进行分类编码的三种不同情况:训练数据、测试数据和我们训练的 ML 模型将对其执行预测的新输入数据。

分类编码库旨在处理所有三种情况,以便与其相邻的特征工程和机器学习模型训练步骤无缝集成。下面的流程图说明了在机器学习管道中使用分类编码的典型工作流程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在标准的机器学习管道中,在对数据集执行特征工程后,您会得到一个数据表,称为特征矩阵,其中包含与手头的预测问题相关的特征。在机器学习管道的这一点上,我们必须首先对我们的数据执行训练测试分割——我们需要训练数据来训练我们的模型,并测试数据来验证它。

下面是我们代码的基本设置。你可以在这个 Jupyter 笔记本上获得完整的代码。

import categorical_encoding as ce
import featuretools as ft
from featuretools.tests.testing_utils import make_ecommerce_entitysetes = make_ecommerce_entityset()
f1 = ft.Feature(es["log"]["product_id"])
f2 = ft.Feature(es["log"]["purchased"])
f3 = ft.Feature(es["log"]["value"])
f4 = ft.Feature(es["log"]["countrycode"])features = [f1, f2, f3, f4]
ids = [0, 1, 2, 3, 4, 5]
feature_matrix = ft.calculate_feature_matrix(features, es,
                                             instance_ids=ids)print(feature_matrix)product_id  purchased  value countrycode
id                                          
0    coke zero       True    0.0          US
1    coke zero       True    5.0          US
2    coke zero       True   10.0          US
3          car       True   15.0          US
4          car       True   20.0          US
5   toothpaste       True    0.0          ALtrain_data = feature_matrix.iloc[[0, 1, 4, 5]]
print(train_data)product_id  purchased  value countrycode
id                                          
0    coke zero       True    0.0          US
1    coke zero       True    5.0          US
4          car       True   20.0          US
5   toothpaste       True    0.0          ALtest_data = feature_matrix.iloc[[2, 3]]
print(test_data)product_id  purchased  value countrycode
id                                         
2   coke zero       True   10.0          US
3         car       True   15.0          US

我们必须分别处理这两组而不是直接编码整个特征矩阵的原因是因为在转换数据之前必须训练许多编码器。例如,目标编码器依赖于某个类别的平均值——将测试数据的值合并到我们的编码中会导致标签泄漏。

因此,在用我们选择的方法初始化我们的编码器之后(见上面如何决定选择哪个编码器),我们拟合(和转换)我们的训练数据,并且我们只转换而不拟合我们的测试数据。在我们对数据进行编码后,我们当然会得到编码后的数据,我们还会生成特征。

enc = ce.Encoder(method='leave_one_out')

train_enc = enc.fit_transform(train_data, features, train_data['value'])

test_enc = enc.transform(test_data)print(train_enc)PRODUCT_ID_leave_one_out  purchased  value  COUNTRYCODE_leave_one_out
id                                                                       
0                       5.00       True    0.0                      12.50
1                       0.00       True    5.0                      10.00
4                       6.25       True   20.0                       2.50
5                       6.25       True    0.0                       6.25print(test_enc)PRODUCT_ID_leave_one_out  purchased  value  COUNTRYCODE_leave_one_out
id                                                                       
2                       2.50       True   10.0                   8.333333
3                       6.25       True   15.0                   8.333333

在机器学习管道的最后一步,我们将获得新的数据,我们现在使用我们训练的模型来执行预测。为此,我们利用上一步生成的特征,利用 Featuretools 的calculate_feature_matrix()功能立即创建编码数据——我们不必创建单独的编码器,也不必再次经历整个编码过程。现在,我们有数据可以立即应用到我们的机器学习模型中。

fm2 = ft.calculate_feature_matrix(features, es, instance_ids=[6,7])
print(fm2)product_id  purchased  value countrycode
id                                          
6   toothpaste       True    1.0          AL
7   toothpaste       True    2.0          ALfeatures_encoded = enc.get_features()

fm2_encoded = ft.calculate_feature_matrix(features_encoded, es, instance_ids=[6,7])

print(fm2_encoded)PRODUCT_ID_leave_one_out  purchased  value  COUNTRYCODE_leave_one_out
id                                                                       
6                       6.25       True    1.0                       6.25
7                       6.25       True    2.0                       6.25

分类编码:何时/如何

分类编码最难的部分有时可能是找到正确的分类编码方法——有许多研究论文和研究致力于分析分类编码方法对不同数据集的性能。通过汇编使用相同编码方法的数据集所共有的所有公共因素,我创建了以下流程图,作为找到最适合您的数据的方法的指南。请注意,这个流程图是一个起点,您可以随意尝试不同的编码方法,甚至是这里没有列出的方法,看看哪种方法最适合您的特定数据和机器学习问题。

也就是说,这个流程图反映了常用分类编码方法的基本原则。此外,如果你想要一个更全面的分类编码指南,这里有一个 Jupyter 笔记本,它涵盖了每种分类编码方法及其更详细的应用场合。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分类编码方法

编码方法可以大致分为几类。

经典编码器

经典编码器是最简单易懂的,这使得它们在 ML 从业者中非常有用和受欢迎。

如果您不确定使用哪种编码方法,一键编码几乎总是一个好的起点。由于其易于使用和理解、通用性和准确性,它是分类编码的首选方法。

已经位于分类编码库中的经典编码器有:顺序编码器、一键编码器、二进制编码器和散列编码器。下面是代码示例,详细说明了每一个是如何实现的。如果你想继续学习,这些例子也可以在 Jupyter 笔记本中找到。

# Creates a new column for each unique value. 
enc_one_hot = ce.Encoder(method='one_hot')
fm_enc_one_hot = enc_one_hot.fit_transform(feature_matrix, features)
print(fm_enc_one_hot)product_id = coke zero  product_id = car  product_id = toothpaste  \
id                                                                      
0                        1                 0                        0   
1                        1                 0                        0   
2                        1                 0                        0   
3                        0                 1                        0   
4                        0                 1                        0   
5                        0                 0                        1   

    purchased  value  countrycode = US  countrycode = AL  
id                                                        
0        True    0.0                 1                 0  
1        True    5.0                 1                 0  
2        True   10.0                 1                 0  
3        True   15.0                 1                 0  
4        True   20.0                 1                 0  
5        True    0.0                 0                 1# Each unique string value is assigned a counting number specific to that value.
enc_ord = ce.Encoder(method='ordinal')
fm_enc_ord = enc_ord.fit_transform(feature_matrix, features)
fm_enc_ordPRODUCT_ID_ordinal  purchased  value  COUNTRYCODE_ordinal
id                                                           
0                    1       True    0.0                    1
1                    1       True    5.0                    1
2                    1       True   10.0                    1
3                    2       True   15.0                    1
4                    2       True   20.0                    1
5                    3       True    0.0                    2# The categories' values are first Ordinal encoded,
# the resulting integers are converted to binary,
# then the resulting digits are split into columns.
enc_bin = ce.Encoder(method='binary')
fm_enc_bin = enc_bin.fit_transform(feature_matrix, features)
fm_enc_binPRODUCT_ID_binary[0]  PRODUCT_ID_binary[1]  PRODUCT_ID_binary[2]  \
id                                                                     
0                      0                     0                     1   
1                      0                     0                     1   
2                      0                     0                     1   
3                      0                     1                     0   
4                      0                     1                     0   
5                      0                     1                     1   

    purchased  value  COUNTRYCODE_binary[0]  COUNTRYCODE_binary[1]  
id                                                                  
0        True    0.0                      0                      1  
1        True    5.0                      0                      1  
2        True   10.0                      0                      1  
3        True   15.0                      0                      1  
4        True   20.0                      0                      1  
5        True    0.0                      1                      0# Use a hashing algorithm to map category values to corresponding columns
enc_hash = ce.Encoder(method='hashing')
fm_enc_hash = enc_hash.fit_transform(feature_matrix, features)
fm_enc_hashPRODUCT_ID_hashing[0]  PRODUCT_ID_hashing[1]  PRODUCT_ID_hashing[2]  \
id                                                                        
0                       0                      0                      0   
1                       0                      0                      0   
2                       0                      0                      0   
3                       0                      1                      0   
4                       0                      1                      0   
5                       0                      0                      0   

    PRODUCT_ID_hashing[3]  PRODUCT_ID_hashing[4]  PRODUCT_ID_hashing[5]  \
id                                                                        
0                       0                      1                      0   
1                       0                      1                      0   
2                       0                      1                      0   
3                       0                      0                      0   
4                       0                      0                      0   
5                       1                      0                      0   

    PRODUCT_ID_hashing[6]  PRODUCT_ID_hashing[7]  purchased  value  \
id                                                                   
0                       0                      0       True    0.0   
1                       0                      0       True    5.0   
2                       0                      0       True   10.0   
3                       0                      0       True   15.0   
4                       0                      0       True   20.0   
5                       0                      0       True    0.0   

    COUNTRYCODE_hashing[0]  COUNTRYCODE_hashing[1]  COUNTRYCODE_hashing[2]  \
id                                                                           
0                        0                       0                       1   
1                        0                       0                       1   
2                        0                       0                       1   
3                        0                       0                       1   
4                        0                       0                       1   
5                        0                       1                       0   

    COUNTRYCODE_hashing[3]  COUNTRYCODE_hashing[4]  COUNTRYCODE_hashing[5]  \
id                                                                           
0                        0                       0                       0   
1                        0                       0                       0   
2                        0                       0                       0   
3                        0                       0                       0   
4                        0                       0                       0   
5                        0                       0                       0   

    COUNTRYCODE_hashing[6]  COUNTRYCODE_hashing[7]  
id                                                  
0                        0                       0  
1                        0                       0  
2                        0                       0  
3                        0                       0  
4                        0                       0  
5                        0                       0

贝叶斯编码器

贝叶斯编码器和经典编码器之间最显著的区别在于,贝叶斯编码器除了使用分类变量之外,还使用因变量的信息。此外,它们只输出一列,这消除了有时会影响其他编码器的任何高维度问题。

除了 One-Hot 编码,LeaveOneOut 编码是我强烈推荐的另一种分类编码方法。

已经在分类编码库中实现的贝叶斯编码器有:Target 和 LeaveOneOut。我在下面提供了它们的代码示例:

# Replaces each specific category value with a weighted average of the dependent variable.
enc_targ = ce.Encoder(method='target')
fm_enc_targ = enc_targ.fit_transform(feature_matrix, features, feature_matrix['value'])
print(fm_enc_targ)PRODUCT_ID_target  purchased  value  COUNTRYCODE_target
id                                                         
0            5.397343       True    0.0            9.970023
1            5.397343       True    5.0            9.970023
2            5.397343       True   10.0            9.970023
3           15.034704       True   15.0            9.970023
4           15.034704       True   20.0            9.970023
5            8.333333       True    0.0            8.333333# Identical to target except leaves own row out when calculating average
enc_leave = ce.Encoder(method='leave_one_out')
fm_enc_leave = enc_leave.fit_transform(feature_matrix, features, feature_matrix['value'])
fm_enc_leavePRODUCT_ID_leave_one_out  purchased  value  COUNTRYCODE_leave_one_out
id                                                                       
0                   7.500000       True    0.0                  12.500000
1                   5.000000       True    5.0                  11.250000
2                   2.500000       True   10.0                  10.000000
3                  20.000000       True   15.0                   8.750000
4                  15.000000       True   20.0                   7.500000
5                   8.333333       True    0.0                   8.333333

您可能会发现,在某些情况下,您会更喜欢当前位于库中的编码器的不同实现(例如,对于我的目标编码实现,我有一个用于平均值计算的特定权重)。如果您希望进行修改,比如采用不同的权重来计算平均值,请随意创建一个新的编码器类,进行修改,并使用编码器 API 调用您的新类。

替代编码器

第三组编码器是对比编码器——它们通过在类别中寻找数学模式来工作。您可以考虑常见的对比度编码方法,如赫尔默特、求和、后向差分或多项式编码。

此外,还存在其他贝叶斯编码器,例如 James-Stein、M-Estimator 或证据权重。请随时尝试编码方法,找到最适合您的数据的方法。然而,如果你需要一个好的起点,看看库中已经实现的默认经典/贝叶斯编码器。One-Hot 和 LeaveOneOut 编码是最流行的编码器,这是有原因的。

摘要

分类编码是特征工程和机器学习中的一个重要步骤,但处理分类数据可能会很棘手且耗时。利用上述指南来确定如何开始更智能地编码,以及如何将分类编码库应用于任何功能工具机器学习管道。请随时尝试多种分类编码方法 API 为您提供了灵活性,让您可以调整自己版本的通用编码器,使其最适合您的特定数据集。

最终,分类编码通过与特征工程以及模型创建、训练和应用的无缝集成,使您更容易处理机器学习管道中的分类数据。

试试分类编码库,并在 Github 上留下任何反馈!我们总是欢迎任何新的编码方法实现。有关更多信息和说明,请查看自述文件指南

原载于 2019 年 8 月 26 日https://blog.featurelabs.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值