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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

外部产品

原文:https://towardsdatascience.com/exterior-product-ecd5836c28ab?source=collection_archive---------16-----------------------

为什么线性代数可能不是最后的空间数学形式

线性代数

在使用线性代数一段时间后,你开始忘记一些小东西并没有真正的意义。

决定因素

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

之字形图案起初令人困惑,但你被告知要放心。你可以认为矩阵 A 的行列式等于它的向量所覆盖的面积。

好的,那么下面矩阵的行列式呢?

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

原来,行列式只为方阵定义。🤔

好吧,但是如果你有两个矩阵 A 和 B 的面积,你当然可以把它们加起来!

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

不,结果是没有人知道 lhs 是否是 rhs 的一个功能。

交叉乘积

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

几何学上,叉积指的是两个向量 a 和 b 的平行四边形所跨越的面积。

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

https://en.wikipedia.org/wiki/Cross_product

但是由于某种神秘的原因,叉积只定义在ℝ上。🤔

想想看,当你处理任何类型的数据集时,你都在处理比ℝ大得多的维度,所以为什么你会在深度学习代码中看到内积,而不是叉积,尽管它确实计算了一些有用的东西。

老实说,挥动你的手指并根据你的选择改变你的计算结果也很奇怪。如果你维护一个物理相关的代码库,你需要确保你正在使用的所有库都有足够的方向转换。

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

https://en.wikipedia.org/wiki/Cross_product#/media/File:Right_hand_rule_cross_product.svg

我们能做得更好吗?

原来,线性代数只是在麦克斯韦公布了他著名的方程之后才变得流行起来,但是还有其他人,比如格拉斯曼和克利福德,正在用不太为人所知的形式来工作,使得某些空间运算变得更加简单。

虽然现在研究几何代数的细节可能看起来很深奥,但考虑到在可预见的未来,我们将与深度模型和制造机器人一起工作,因此我们的数学工具自然会进化以更好地适应我们。

外部产品

为了体验用几何代数可以做的事情,我们将看看外部产品。

外积定义为某个向量空间 V 中的 a ∧ b,其中 a,b ∈ V。

它需要满足两个属性

1.反对称 : a ∧ b =-b ∧ a

2.双线性 : a ∧ (b + λ c) = a ∧ b + λ a ∧ c

到目前为止,这两个性质似乎很抽象,但让我们看一个反对称和双线性成立的例子。几何!

决定因素

我们取一个平行四边形,边向量为 a 和 b。

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

问:如果我们将 b 加倍,平行四边形的面积如何变化?

a:面积(a,2b) = 2 面积(a,b)

问:如果我们将 b 乘以-2,平行四边形的面积会如何变化?

a:面积(a,-2b) =面积(a,2b) = 2 面积(a,b)

问:如果我们把 c 加到 b 上,平行四边形的面积如何变化?

a:面积(a,b + c) =面积(a,b) +面积(a,c)

区域也有一个方向,这是我们在线性代数中通常忽略的,但对于像计算机图形中的碰撞检测和剔除这样的问题是有用的。

面积(a,b)是旋转远离屏幕的面积,面积(b,a)是旋转朝向屏幕的面积,它们的关系是面积(a,b)=-面积(b,a)

我们可以把这些例子归纳成 3 条定律

1.面积(a,b)=-面积(b,a)

2.面积(λ a,b) = λ面积(a,b)

3.面积(a,b + c) =面积(a,b) +面积(a,c)

现在,如果我们将 Area(a,b)重命名为 a ∧ b,你会看到平行四边形的面积只是楔形积的一个特殊应用

  1. a ∧ b =-b ∧ a

2.(λ a) ∧ b = λ (a ∧ b)

3.a ∧ (b + c) = a ∧ b + a ∧ c

在线性代数中,我们通常认为向量或矩阵是保存ℝ元素的容器,因此一个 n 维向量保存 n 个ℝ.元素相反,我们可以把一个 n 维向量看作ℝ^n 的一个元素,并在这个更高层次的结构上执行我们的计算。

任何向量都可以用基向量来表示。在二维空间中,我们有两个基向量:

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

我们可以用它们的基向量来表示 a 和 b

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

楔形积∧有一个重要的性质

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

现在如果我们取 a ∧ b

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

我们拿回行列式公式!在任何时候我们都没有把自己局限在方阵中。

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

交叉乘积

叉积通常定义在ℝ上,这意味着我们需要计算 3 个基本向量

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

我们想用两个向量 a 和 b。

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

如果我们取他们的楔形积∧

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

如果我们看看这些系数,它们看起来和典型的叉积是一样的。

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

这个定义没有理由只适用于ℝ,我们可以很容易地把它推广到ℝ⁴和更远的地方。

但是我们不用 I,j,k 作为基本向量,而是用 e ∧ e,这是一个更高维的空间。这是几何代数中的一个普遍主题。

在线性代数中,我们通常认为向量是矩阵,是保存ℝ元素的容器,所以一个 n 维向量保存 n 个ℝ.元素相反,我们可以把一个 n 维向量看作ℝ^n 的一个元素,并在这个更高层次的结构上执行我们的计算。

下一步

几何代数是一种数学语言,用于规划几何问题。

由于深度学习和机器人技术变得如此流行,我们极有可能在未来做更多的几何。如果线性代数不能像几何代数那样自然地表达几何问题,为什么要选择它这样一种流行的形式主义呢?

我只讨论了一个运算符,即 wedge product∧——它还有很多应用,了解它们的一个好方法是查看下面的参考资料。

  • 计算机科学的几何代数—这本书令人惊奇的地方在于,它详细介绍了构建一个高效的几何代数库和渲染器的所有细节,你可以随意摆弄。这是我最喜欢的几何代数书,但不可否认它很难阅读,据我所知,没有教科书对初学者非常友好,但这应该改变,因为越来越多的人开始注意形式主义的优点。
  • R 上的几何代数介绍 —伟大的几何代数第一次介绍。我强烈建议你在检查动画时也检查源代码,看看一切是如何工作的。
  • 线性代数做对了在我看来是我读过的线性代数理论方面最好的介绍。(比 Strang 清晰)。它将帮助你把矩阵看作线性映射,这简化了对矩阵所有性质的理解。
  • 应用线性代数简介:向量、矩阵和最小二乘专注于数值线性代数及其在优化和机器学习中的应用。它附带了一个免费的在线指南,介绍了 Julia 中的所有算法,大约和主书一样长。
  • 通过外积的线性代数是一个很好的参考,它使用外积重新证明了线性代数的所有主要定理。
  • ganja . js-Javascript 中的几何代数库,有疑问的时候看看代码。通过查看示例,你会学到很多东西。
  • 几何代数在 66 页中给出了严格的介绍。
  • 游戏引擎开发基础,第 1 卷:数学——涵盖了 3D 图形所需的所有数学知识,这本书的最后一部分致力于 Clifford 和 Grassman 代数。这本书简洁明了,附有大量精美的插图

承认

我从来没有想过我会最终研究像几何代数这样的东西,但是亚当·尼梅克多次坚持认为这是值得的,他是对的。他维持着一个有趣而活跃的图形研究人员和数学家的不和谐社区,讨论如何更广泛地使用几何代数。我还要感谢 u/muntoo 仔细校对了这篇文章。

使用 Apache Jena (SPARQL 引擎)提取和查询知识图

原文:https://towardsdatascience.com/extract-and-query-knowledge-graphs-using-apache-jena-sparql-engine-5c66648797a4?source=collection_archive---------28-----------------------

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

Image by LTDatEHU — Pixabay

在本文中,我们将使用 Apache Jena 下载、提取和查询 AGROVOC 三元组

AGROVOC 是一个受控词汇,涵盖了联合国粮食及农业组织( FAO )关注的所有领域,包括粮食、营养、农业、渔业、林业、环境等。

AGROVOC 由资源描述框架(RDF)三元组组成。每个三元组由 3 个部分(主语、谓语和宾语)组成,如“Alice — knows — Bob”,其中“Alice”是主语,“knows”是谓语或关系,“Bod”是宾语。然而,由于我们可能有不止一个人的名字叫“爱丽丝”,那么最好给主题添加一个统一的资源标识符(URI ),使其唯一。例如,“http://Google . com/developers/teamA/Alice”现在更容易区分不同的主题。称为知识图的 RDF 三元组的集合。

为什么我们需要提取三元组?

如果你观察水的 URI<http://aims.fao.org/aos/agrovoc/c_8309>,你会注意到最初的实体c_8309代表“水”。然而,我们把它的 ID 而不是真正的单词“water ”,因为它也可能存在于其他语言中(查看下图)。因此,我们需要提取实际的单词,而不是 id,这是第一个查询的目的。

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

The page for the entity “c_8309”, notice the entity names in different languages on the right bar

下载要求

  • 首先,你需要下载 AGROVOC 数据集。点击这里或在谷歌上搜索 AGROVOC,然后点击“发布”并下载文件“agro VOC LOD nt(zipped-44 MB)”,扩展名“nt”告诉你这是一个三重文件。
  • 您还需要下载 Apache Jena,以便我们可以使用 SPARQL 引擎提取和查询数据集。点击这里或者谷歌搜索 Apache Jena 然后下载"Apache-Jena-3 . 13 . 1 . zip(sha 512PGP )"

提取三元组

下载 Apache Jena 后,我们将使用两个主要命令:tdbloader2tdbquery.,第一个命令为三元组创建索引以使将来的查询更快,第二个命令允许我们运行 SPARQL 查询。请注意:为了能够使用这些命令,您需要导航到apache-jena-<version>/bin/然后运行命令,或者您需要提供其位置的路径,例如apache-jena-<version>/bin/tdbloader2

为三元组建立索引

tdbloader2 --loc Indices agrovoc_2019-06-03_lod.nt

注意:Indices是存储索引的目录(给出任何名称)。agrovoc_2019-06-03_lod.nt是我们从 AGROVOC 下载的输入文件(triples)的名称。

之后,创建一个新文件(我更喜欢扩展名为.sparql)并编写以下 SPARQL 查询,该查询只提取英语对象:

**SELECT** ?subject ?predicate ?object
**WHERE** {
?subject ?predicate ?object
**FILTER**(lang (?object) = 'en')
}

最后,使用以下命令执行查询:

tdbquery --loc Indices --query English_Query.sparql 

English_Query.sparql是查询文件的名称。可以使用 Linux >命令将输出定向到一个文件,如下所示:

tdbquery --loc Indices --query English_Query.sparql > output.txt

其他查询示例

另一个简单的查询是返回整个知识图(所有三元组)而不进行任何过滤:

**SELECT** ?subject ?predicate ?object
**WHERE** {
?subject ?predicate ?object
}

运行以下查询以返回所有以“水”为主题的三元组(不要忘记在水之前包括 URI):

**SELECT** ?predicate ?object
**WHERE** {
<water> ?predicate ?object
}

注意,在这个例子中,我们没有在查询中包含?subject,因为我们的目标是返回与<water>主题相关的谓词和对象。

您可以使用非常有用的命令,比如与 SQL 语法非常相似的FILTER, GROUP BY, HAVING, etc.。然而,其他数据集可能由四元组而不是三元组组成。四元组由三元组组成,第四部分称为上下文。比如“Alice—knows—Bobs—Google dev department”。您仍然可以使用包含上下文部分的精确查询,因为图中可能有多个上下文。以下查询将返回上下文为“GoogleDevDepartment”的所有四边形:

**SELECT** * **WHERE** {
**GRAPH** ?GoogleDevDepartment {
?subject ?predicate ?object
}
}

恭喜你,现在你应该能够提取和查询知识图了!

从在线评论中提取热门话题

原文:https://towardsdatascience.com/extract-trending-topics-from-user-reviews-9d6c896451d7?source=collection_archive---------27-----------------------

文本中频繁项集挖掘的实验

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

Photo by Rock Staar on Unsplash

顾客在选择餐馆时依靠在线用户评论。当一群评论者开始发布关于一个共同话题的评论时,评论可以保持趋势。这个话题可以是一家餐馆新增加的特色,一家新餐馆在城里开张,或者是关于菜单上一个受欢迎的食物。这个共同话题可以解释为趋势性话题。然后顾客开始追随新的潮流。我的方法是通过使用频繁项集挖掘技术来获得评论者每月的趋势主题。我要使用的数据集是来自 Yelp 挑战赛 2019 的 Yelp 数据集。

频繁项集挖掘与关联规则挖掘

频繁模式在数据集中反复出现。频繁项集由这些模式之一组成。频繁项集挖掘发现超过最小阈值的有趣的频繁项集。此阈值是一个度量值,它指示项集中包含的最小项数。频繁模式挖掘的概念是随着购物篮分析而发展起来的。购物篮分析可以作为当今最流行的例子。这里对一起销售的产品进行分析。简单地说,频繁项集挖掘显示哪些项在一个事务中一起出现。

关联规则挖掘就是寻找这些项目之间的关系。鉴于购物篮分析,它计算购买一个或多个产品后购买某个产品的概率。然而,当应用于问题时,这两个概念是一起的。正在使用的流行算法有 先验FP-GrowthEclat

支持和信心

对于频繁项集挖掘,有两种主要的度量方法。他们是支持和信心。这两个度量评估模式有多有趣。支持度是绝对频率的量度,信心是相对频率。支持指示项目在所有事务中一起出现的次数。置信度表示有多少交易遵循某一规则。基本上,支持度是不考虑项目之间关系的频繁项目的度量,而置信度是项目之间关联规则的度量。以下是注释。

Support(A-> B)= Support _ count(AB)

置信度(A -> B) =支持计数(AB)/支持计数(A)

文本中的频繁项集挖掘

文本通常被称为非结构化数据。大多数时间频繁项集挖掘算法都可以应用于结构化数据。然而,文本可以转化为结构化数据,数据挖掘技术可以应用。为了输出数据的结构化版本,需要遵循几个预处理步骤。这种结构化数据可以分为两类:单个单词和多个单词。一个单词叫做单词包。包词和多重词的主要区别在于多重词保留了词与词之间的关系,从而保持了句子的语义。

另一方面,一个句子可以被看作是单词的集合。多个句子之间可以有常用词。类似地,段落由单词组成,并且多个段落具有频繁的单词集。这些常用词可以看作是一个频繁项集。Word 将成为项目集中的一个项目。所以频繁模式可以由多个单词组成。挖掘这些模式将给出句子或段落中常见单词的基本概念,而不是从文本中提取单个关键词。说到用户评论,这些常用词可以认为是趋势话题。该实验的主要目的是使用频繁项集挖掘来导出用户评论中的趋势主题。

履行

为了实现上述想法,选择来自特定餐馆的最新评论,并提取每个月的趋势主题。以下是筛选出最方便解决问题的餐厅的标准。

数据集有各种类型的业务。为了过滤掉餐馆,我在类别字段中选择了包含“餐馆”的企业。对于最新的评论,我选择了 2018 年发布的评论。当比较美国各州的餐馆数量时(图 1 ),我们看到亚利桑那州的餐馆数量最多。然后通过计算和比较 2018 年每个餐厅的评论数,选出了“亚利桑那州”最受好评的餐厅。

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

Figure 1 : Number of restaurants in each state in the USA according to Yelp Data set (Yelp Challenge 2019)

一开始,数据是从 Yelp 提供的 JSON 文件中提取的,并存储在关系数据库中以便于访问。我遵循的预处理步骤是转换成小写,删除标点符号,删除空格,标记单词和删除停用词。以下是代码片段。

**import** string**import** pandas **as** pd
**from** nltk.tokenize **import** word_tokenize
**from** sklearn.feature_extraction.stop_words **import** ENGLISH_STOP_WORDS**def** preprocess_reviews(reviews: pd.DataFrame):
    word_token_list = []
    **for** _, r **in** reviews.iterrows():
        formatted_review = r[**'review_text'**].lower()
        formatted_review = formatted_review.translate(str.maketrans(**""**, **""**, string.punctuation))
        formatted_review = formatted_review.strip()
        tokens = word_tokenize(formatted_review)
        result = [i **for** i **in** tokens **if not** i **in** ENGLISH_STOP_WORDS]
        word_token_list.append(result)

    **return** word_token_list;

用于检索趋势主题的算法是 先验 ,支持度是 0.3。下面是代码片段。(我提到的文章位于本文末尾的参考资料部分,以了解更多详细信息)

**import** pandas **as** pd
**from** mlxtend.frequent_patterns **import** apriori
**from** mlxtend.preprocessing **import** TransactionEncoder**def** get_trending_words_from_reviews(preprocess_reviews: []):
    transaction_encoder = TransactionEncoder()
    transaction_encoder_array = transaction_encoder.fit(preprocess_reviews).transform(preprocess_reviews)
    df = pd.DataFrame(transaction_encoder_array, columns=transaction_encoder.columns_)

    frequent_itemset = apriori(df, min_support=0.3, use_colnames=**True**)

    **return** frequent_itemset

请注意,在这个实验中没有推导出关联规则。下面的代码解释了如何调用上述函数以及要传递的审核列表的格式。

reviews = pd.DataFrame([{**'review_text'**: **'good food'**}, {**'review_text'**: **'great food'**}, ])reviews = preprocess_reviews(reviews)
frequent_itemset = get_trending_words_from_reviews(reviews)
print(frequent_itemset)

结果和讨论

下表(表 1 )显示了上述实验的结果。

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

Table 1 : Frequent words derived from frequent itemset mining for each month using reviews of most reviewed restaurant in Arizona by year 2018

所选餐厅在类别字段中描述自己为’三明治、意大利早餐&早午餐、美式(传统)'。我们可以看到“肉丸”、“酱”和“意大利面”这些词在一月份很流行。在二月,人们只谈论这三个术语中的两个。它们是“肉丸”和“酱”。当谈到三月时,“酱”和“意大利面”都消失了,而“肉丸”这个词幸存了下来。尽管这三个项目都是今年年初的流行趋势,但只有一个项目可以继续流行。此外,调查结果显示,术语“肉丸”已经成为全年的热门话题。“意大利面”在八月又成了一个热门话题。我们可以观察到的另一件事是,年底的复习次数一直在减少(图 2 )。

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

Figure 2 : Monthly review count of most reviewed restaurant in Arizona by year 2018

这可以解释为餐馆正随着时间的推移而失去它的名声。原因可能是,尽管餐馆的服务和位置得到了好评,但对于常客来说,没有什么新鲜和令人兴奋的东西可以分享。如果一家餐馆能推出新的食品,并提高逐渐消失的食品的质量,它就能挽回声誉。

每个餐厅的结果都不一样,应该据此做出解释。可以通过增加更多的预处理步骤来改善结果。在这种情况下,词干、词汇化和词性标注等概念会有所帮助。此外,可以通过将该方法分别应用于好评和差评来改进预测。

参考

[## 文本频繁项集挖掘的概念

频繁项集挖掘是一种流行的具有频繁模式或频繁项集的数据挖掘技术。

iopscience.iop.org](https://iopscience.iop.org/article/10.1088/1757-899X/434/1/012043) [## Python 中的关联分析

Python 中基于 Apriori 算法的频繁项集挖掘

medium.com](https://medium.com/analytics-vidhya/association-analysis-in-python-2b955d0180c) [## Python 中基于 Apriori 算法的关联规则挖掘

关联规则挖掘是一种识别不同项目之间潜在关系的技术。举一个例子…

stackabuse.com](https://stackabuse.com/association-rule-mining-via-apriori-algorithm-in-python/)

使用 OpenCV 和 Python 从图像中提取形状

原文:https://towardsdatascience.com/extracting-circles-and-long-edges-from-images-using-opencv-and-python-236218f0fee4?source=collection_archive---------7-----------------------

利用 OpenCV 从图像中高效提取已知形状的物体

欢迎阅读本系列博客中关于使用 OpenCV 和 Python 从图像中提取特征的第一篇文章。

图像和视频的特征提取是计算机视觉领域的一个常见问题。在本帖中,我们将考虑识别台球桌上的球和桌边的任务。

考虑下面这个在线台球游戏的例子。

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

Screenshot from an online game of pool (image source author)

假设我们想要标记这个图像中每个球的位置以及桌子的四个内边。有多种方法可以做到这一点,对于给定的图像,有些方法比其他方法效果更好。然而,一个有用的方法是尝试根据图像的颜色组成来分离出图像的内容。

例如,在上面的图像中,我们可以看到桌面、球和图像背景都有不同的颜色。

因此,如果我们能够分离出图像中的颜色,我们就离解决问题更近了一步。

一种简单的方法是将 RBG 图像转换成 HSV 格式,然后找出与感兴趣的对象相对应的 H、S 和 V 值的范围。

关于这一步的细节,请参考我的关于 HSV 提取的博客(即将发布)。

一旦我们有了桌面的 HSV 颜色图,我们可以使用 OpenCV “inRange()” 函数来获得提取的遮罩的可视化,如下所示。

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

Image mask generated using OpenCV (image source author)

正如我们所见,这一步骤有助于实现以下目标:

  1. 表格对象(白色)与图像背景(黑色)明显不同
  2. 球(黑色)与桌面(白色)清晰可辨

作为第一步,我们需要从图像中提取表格对象,以便将注意力集中在表格及其内容上,而忽略图像中的其他对象,例如背景、外部对象等。

现在是应用边缘检测技术从图像中识别和提取所需成分的正确时间。有多个选项可用,如 Canny 和 Sobel 函数,每个都有其优点和缺点。

我们将使用 OpenCV**“find contours()”**函数进行边缘检测,以提取掩模图像中的所有轮廓。面积最大的轮廓是对应于桌子本身的轮廓。

为了实现桌子的平滑提取,我们将找到桌子轮廓的外接矩形(OpenCV “boundingRect()” 函数),并使用其坐标从仅包含感兴趣对象的原始图像中提取子图像,在这种情况下,桌子表面和球如下图所示。

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

Extracted only the region of interest using OpenCV (image source author)

现在剩下的任务是提取单个的球并识别球台的内边缘。

为了实现这一点,我们将再次使用先前使用的基于 HSV 的提取方法来获得遮罩,首先聚焦于球,然后聚焦于桌子边缘。

探测球

球的遮罩图像看起来将与我们之前用于桌子的图像相同。从获得的掩模图像中,我们将再次使用 OpenCV “findContours()” 函数提取球轮廓。这一次我们感兴趣的只是那些类似圆的给定大小的轮廓。

同样,有许多方法来检测球的轮廓,但是最有效的一种方法是为每个检测到的轮廓找到最小的外接矩形,并且选择最类似正方形并且也位于期望的区域范围内的那些。在这种情况下,我们将使用 OpenCV 函数**“minarerect()”**。

在选定的一组轮廓上,我们将进一步应用 OpenCV**“minEnclosingCircle()**”函数来获得每个球上统一大小的圆。

现在我们只需要使用 OpenCV “circle()” 函数用我们选择的任何颜色绘制每个检测到的球。

检测表格边缘

这是一个分两步走的方法,因为表既有外边缘又有内边缘,我们只对后者感兴趣。

第一步是使用基于 HSV 的方法得到桌子边缘的遮罩。得到的面具看起来像下面,其中所有的四个方面都可以很容易区分。

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

Mask for table edges detection obtained using OpenCV (image source author)

有了这个遮罩,我们现在可以通过定位离图像中心最近的两条水平线和两条垂直线来提取内部边缘。

我们将使用 OpenCV “HoughLines()” 函数来查找图像中的所有线条,并只选择我们感兴趣的 4 条。

一旦检测到 4 条线,我们只需要使用 OpenCV “line()” 函数来绘制相应的表格边缘。

然后可以将获得的图像覆盖在原始图像上,以完成如下所示的任务。

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

Identified all the balls and four table edges with high accuracy (image source author)

希望你喜欢阅读这篇文章。

在我的下一篇文章中,我将介绍另一个有趣的特征提取的例子,请继续关注。

重要免责声明:

这篇博文中使用的方法,尤其是用于检测球和桌子边缘的 HSV 值,不一定适用于每张图像。每幅图像的特征都是独一无二的,并且需要正确的参数集,以使特征提取按预期工作。这正是计算机视觉如此有趣和具有挑战性的领域。

为机器学习提取数据

原文:https://towardsdatascience.com/extracting-data-for-machine-learning-f90b97a97f4c?source=collection_archive---------13-----------------------

为下一个机器学习项目获取数据的三种方法

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

Photo by Matthieu Oger on Unsplash

任何机器学习项目最重要的第一步就是获得优质数据。作为一名数据科学家,您经常需要使用各种不同的方法来提取数据集。您可能使用公开可用的数据、通过 API 可用的数据、在数据库中找到的数据,或者在许多情况下这些方法的组合。

在下面的帖子中,我将简要介绍 python 中提取数据的三种不同方法。在这篇文章中,我将讲述如何在 Jupyter 笔记本中提取数据。我以前在早先的文章中报道过如何从命令行使用这些方法。

结构化查询语言

如果您需要从关系数据库中获取数据,很可能需要使用 SQL。您可以使用名为 SQLAlchemy 的库将 Jupyter 笔记本连接到最常见的数据库类型。这个链接提供了支持哪些数据库以及如何连接到每种类型的描述。

您可以直接使用 SQLAlchemy 来查看和查询表,也可以编写原始查询。要连接到您的数据库,您需要一个包含您的凭据的 URL。然后,您可以使用create_engine命令来创建连接。

from sqlalchemy import create_engine
engine = create_engine('dialect+driver://username:password@host:port/database')

现在,您可以编写数据库查询并返回结果。

connection = engine.connect()
result = connection.execute("select * from my_table")

Web 抓取用于从网站下载数据,并从这些页面中提取所需的信息。有很多 python 库可以用来做这件事,但是最简单的一个是 Beautiful Soup

你可以通过 pip 安装这个软件包。

pip install BeautifulSoup4

让我们通过一个简单的例子来说明如何使用它。我们将使用 Beautiful Soup 和 urllib 库从猫途鹰网站获取酒店名称和价格。

让我们导入将要使用的所有库。

from bs4 import BeautifulSoup
import urllib.request

接下来,我们要下载我们要抓取的页面内容。我将收集希腊克里特岛酒店的价格,所以我使用一个包含该目的地酒店列表的 URL。

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

TripAdvisor

下面的代码将 URL 定义为一个变量,使用 urllib 库打开页面,使用 Beautiful Soup 读取页面,并以易于阅读的格式返回结果。代码下面显示了部分输出。

URL = '[https://www.tripadvisor.co.uk/Hotels-g189413-Crete-Hotels.html'](https://www.tripadvisor.co.uk/Hotels-g189413-Crete-Hotels.html')
page = urllib.request.urlopen(URL)
soup = BeautifulSoup(page, 'html.parser')
print(soup.prettify())

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

接下来,让我们获取页面上的酒店名称列表。我们将使用find_all函数,它允许您提取文档中您感兴趣的部分。您可以使用find_all以多种方式过滤文档。通过传入字符串、正则表达式或列表。您还可以过滤标签的一个属性,这就是我们将在这里使用的方法。如果你不熟悉 HTML 标签和属性,这篇文章给出了一个很好的概述。

要了解如何最好地访问数据点,您需要检查 web 页面上该元素的代码。要查找酒店名称的代码,我们右键单击列表中的名称,如下图所示。

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

当您点击inspect时,代码将出现,包含酒店名称的部分将高亮显示,如下所示。

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

我们可以看到酒店名称是名为listing_title的类中唯一的一段文本。下面的代码将这个属性的类和名称传递给find_all函数,以及div标签。

content_name = soup.find_all('div', attrs={'class': 'listing_title'})
print(content_name)

这会以列表形式返回包含酒店名称的每一段代码。

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

为了从代码中提取酒店名称,我们可以使用 Beautiful Soup 的getText函数。

content_name_list = []
for div in content_name:
    content_name_list.append(div.getText().split('\n')[0])
print(content_name_list)

这会以列表形式返回酒店名称。

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

我们可以用类似的方法得到价格。检查价格代码,我们可以看到它有以下结构。

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

所以我们可以用非常相似的代码提取这一段。

content_price = soup.find_all('div', attrs={'class': 'price-wrap'})
print(content_price)

价格有点复杂,如果我们运行下面的代码,我们会看到它。

content_price_list = []
for div in content_price:
    content_price_list.append(div.getText().split('\n')[0])
print(content_price_list)

输出如下所示。当酒店列表显示降价时,除了一些文本之外,还会返回原始价格和销售价格。为了使这个有用,我们只想返回酒店的实际价格,如果我们今天预订的话。

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

我们可以使用一些简单的逻辑来获得文本中显示的最后价格。

content_price_list = []
for a in content_price:
        a_split = a.getText().split('\n')[0]
        if len(a_split) > 5:
            content_price_list.append(a_split[-4:])
        else:
            content_price_list.append(a_split)  

print(content_price_list)

这给出了以下输出。

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

应用程序接口

API 代表应用程序编程接口,就数据提取而言,它是一个基于 web 的系统,为数据提供一个端点,您可以通过一些编程连接到该端点。通常,数据将以 JSON 或 XML 格式返回。

在机器学习中,你可能需要用这种方法获取数据。我将给出一个简单的例子,说明如何从一个公开可用的名为 Dark Sky 的 API 中获取天气数据。要访问这个 API,你需要注册,每天免费提供 1000 个电话,这应该足够尝试了。

为了访问来自黑暗天空的数据,我将使用requests库。首先,我需要获得正确的 URL 来请求数据。“黑暗天空”提供预报和历史天气数据。对于这个例子,我将使用历史数据,我可以从文档中获得正确的 URL。

该 URL 具有以下结构。

https://api.darksky.net/forecast/[key]/[latitude],[longitude],[time]

我们将使用requests库来获取特定纬度和经度以及日期和时间的结果。让我们想象一下,在获得克里特岛酒店的每日价格后,我们想要找出价格是否以某种方式与天气相关。例如,让我们为列表中的一家酒店选择坐标。

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

Google.com

首先,我们用我们需要的正确坐标和日期时间构造 URL。使用requests库,我们可以访问 JSON 格式的数据。

import requestsrequest_url = '[https://api.darksky.net/forecast/fd82a22de40c6dca7d1ae392ad83eeb3/35.3378,-25.3741,2019-07-01T12:00:00'](https://api.darksky.net/forecast/fd82a22de40c6dca7d1ae392ad83eeb3/35.3378,-25.3741,2019-07-01T12:00:00')
result = requests.get(request_url).json()
result

我们可以将结果标准化到一个数据框架中,以便于阅读和分析。

import pandas as pddf = pd.DataFrame.from_dict(json_normalize(result), orient='columns')
df.head()

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

Part of the resulting data frame

使用这些方法,您可以做更多的事情来自动提取这些数据。对于 web 抓取和 API 方法,可以编写函数来自动执行该过程,以便轻松提取大量日期和/或位置的数据。在这篇文章中,我想简单地给出一个概述,用足够的代码来探索这些方法。在以后的文章中,我将会写一些更深入的文章,介绍如何构建完整的数据集并使用这些方法进行分析。

感谢阅读!

从金融 pdf 中提取数据

原文:https://towardsdatascience.com/extracting-data-from-financial-pdfs-dc2fa0b73169?source=collection_archive---------8-----------------------

如何从市政债券 CAFR 报告中快速提取文本和数据

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

Photo by Markus Spiske on Unsplash

什么在传播

财务的很大一部分是用来写和读财务报表的。在美国,财务报表必须是 PDF 格式,才能被认为是官方的。这给以后使 pdf 成为机器可读的文件带来了挑战。

在过去,银行和金融机构常常雇佣整个团队来阅读 PDF 格式的财务报表,并将其输入到银行的数据库中。这些职位是数据输入,表格输入。然而,其他团队会将输入的值映射到银行常用的值。这一系列的任务被称为金融传播

例如,一个申请贷款的大型家庭农场会在农场的存货清单中列出诸如彼得比尔特卡车之类的项目。但是,当银行的财务人员读取财务数据时,他们需要将卡车归类为子类别“车辆”下的非流动(非货币)资产。这使得银行可以减少财务不确定性,因为它可以将这种特定的卡车映射到银行已经处理多年的其他类似车辆。用金融术语来说,它允许银行将这种情况映射到更广泛的、标准化的帐户集合。

在不久以前,这些吊具位于低成本地区和离岸地区。今天,许多金融机构已经以某种形式采用了人工智能,以减轻人工阅读每一份金融 PDF 文件的人类负担。

我们来讨论一下 AI 是如何读取和处理这些 pdf 的。

用机器提取 PDF

我们将查看综合年度财务报告(CAFR ),这是市政债券的主要年度披露文件。CAFRs 往往主要是 PDF 格式的扫描文档。这里是纽约州市 CAFR 的一个例子。

美国大多数城市都有未偿债券,有义务通过 CAFRs 披露年度财务状况。这是一张很好的幻灯片,展示了城市总体规模和 CAFR 覆盖率。让我们来看一个来自 CAFR 的样本页面,我们将使用它来运行光学字符识别(OCR)数据提取—

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

CAFR from City of Hoboken, NJ, page 150

如果你仔细看,你会注意到这是一个扫描页面,保存为 PDF 格式,所以它还不是机器可读的。

CAFR 文件包含了非常有趣的关于市政规划、预算和运作的信息。它们包含了公立学校、警察部门、消防部门的信息。比如公立医院有多少病床,每张病床的收入和其他运营成本。

引擎盖下发生了什么

那么 AI 如何让上面的文档成为机器可读的文本呢?

在核心部分,人工智能试图隔离有黑色墨迹的区域和没有黑色墨迹的区域。然后,另一个人工智能,像小学生一样,观察单个墨迹来辨认单词和字符。而另一个人工智能试图理解所有检测到的文本是否被组织成表格、表格或自由形式的文本。

更具体地说,PDF 是作为图像被机器读入的。然后,一种算法试图在它看到的任何文本周围画出方框。每一个单词或字符组会得到它的盒子。一旦算法覆盖了边界框中的每一段文本,则下一组算法可以继续进行。这是边界框的样子—

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

Bounding box detection algorithm at work

接下来,另一种算法——光学字符识别(OCR)开始对每个边框内的文本进行解码。该算法接收文本图像,并将它们转换成包含在该图像中的计算机可理解的文本。

最后,另一种算法查看所有这些边界框和其中的文本,以了解每个单词是构成一行还是表格的一部分。

例如,最上面一行写着“霍博肯市”,边界框算法检测到 3 个带有文本的区域——“城市”、“OF”、“霍博肯”,并为它们分配置信度得分和唯一 id——

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

然后,合并器算法获取 3 个单词的输出,并根据文本在页面上的位置将它们组合在一起

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

Notice Confidence: 95 of Text: “CITY OF HOBOKEN”

最后一种合并算法还对表格、自由格式文本或表单等页面区域进行分类。这是它放在一起的样子—

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

Machine interpretation of the PDF table on the right

今天,上面提到的每个算法都是一个深度神经网络,用单独的训练数据进行训练,并由人类进行注释。我们可以看到每一步的置信度得分,因此我们可以通过主动学习来修正算法。

如果您对在 AWS 上建立端到端 OCR 即服务感兴趣,请点击这里

结论

由于人工智能的最新进展,我们现在可以将 PDF 文档一起读入我们的数据湖,并执行下游机器学习和分析来揭示 alpha。

新的创业公司正在涌现,从金融领域的大量文件中收集见解,这在过去是极其昂贵的。

OCR 只是金融文档如何被摄取、处理和显示以供投资专业人员获得货币优势(alpha)的一小部分,但却很重要。

利用 OpenCV 人脸检测神经网络提取人脸

原文:https://towardsdatascience.com/extracting-faces-using-opencv-face-detection-neural-network-475c5cd0c260?source=collection_archive---------9-----------------------

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

Photo by Maxim Dužij on Unsplash

最近,我偶然发现了 https://www.pyimagesearch.com/的网站,那里有一些关于 OpenCV 的很棒的教程。在通读它的众多文章时,我发现 OpenCV 有自己的人脸检测神经网络,准确率非常高。

所以我决定用 OpenCV 的这个神经网络做一个项目,从图像中提取人脸。每当有人处理人脸并需要从大量图像中提取人脸时,这样的过程就会很方便。

完整的项目可以作为 GitHub 库获得。为了这篇文章,我从我的 Instagram 账户上拍了一张照片。

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

Image used for extracting face

目标

这个项目有两个基本要素。**包围人脸的方框:**在图像中识别的所有人脸周围显示白色方框。Python 文件是data _ generator . py2。**提取的人脸:**从一个文件夹中的所有图像中提取人脸,并将每个人脸保存到一个目标文件夹中,以创建一个方便的数据集。Python 文件是 face_extractor.py

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

Face detection and extraction

首先,让我们执行这两个部分的共同步骤,即导入库、加载人脸检测模型、创建输出目录、读取图像和检测人脸。

项目

导入库

我导入os来访问目录中的各种文件。然后,cv2将用于处理图像。numpy有助于轻松处理多维数组。

定义路径和负载模型

OpenCV repo 本身提供了模型的prototxtcaffemodel。我使用了相同的方法,并将它们放在我的项目中的model_data目录中。prototxt文件包括网络的文本描述,而caffemodel包括权重。我读取了这两个文件,并使用cv2加载了我的model

创建目录

如果存储结果图像的目录不存在,我将创建一个目录。输出文件夹为更新 _ 图像

在提取人脸时,我会将人脸保存到目录 faces 中。如果它不存在,我将创建它。

读取图像

我遍历了图像文件夹中的所有图像。提取扩展名后,我检查文件是否属于类型.png.jpg,并且只对这些文件进行操作。

检测人脸

使用cv2.imread,我读取图像,并使用cv2.dnn.blobFromImage创建一个斑点。然后,我将这个斑点输入到模型中,并使用model.forward()从页面中获取检测结果。

通用步骤现在已经完成。对于第一个任务,我将在人脸周围绘制白色矩形,并将它们保存在 updated_images 目录中。对于第二个任务,我将把提取的人脸保存在 faces 目录中。

1.在面周围创建方框

我一个接一个地迭代图像中检测到的所有人脸,并提取它们的起点和终点。然后,提取检测的置信度。如果算法有超过 50%的把握检测到的是人脸,我会在它周围显示一个矩形。

然后,使用cv2.imwrite,我将图像保存到同名的updated_images文件夹中。

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

Image with white rectangle around face

2.提取人脸

如上所述,我迭代所有人脸,计算检测的置信度,如果超过 50%,我提取人脸。注意这条线frame = image[startY:endY, startX:endX]。它从图像中提取人脸。

然后,我将这个新图像转储到faces文件夹中,名称为 face number,后跟_,然后是文件名。如果我们从名为sampleImage.png的图像中提取第一张人脸,人脸文件的名称将为0_sampleImage.png。对于每个面,我递增count并在完成执行后,将计数打印到控制台。

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

Extracted face

终于,项目准备好了。您可以输入尽可能多的图像,并生成可用于后续项目的数据集。

结论

在本文中,我讨论了使用 OpenCV 人脸检测神经网络来检测图像中的人脸,用白色矩形标记它们,并将人脸提取到单独的图像中。

一如既往,我很想听听你的想法和建议。

从 Scikit-Learn 管道中提取特征重要性

原文:https://towardsdatascience.com/extracting-feature-importances-from-scikit-learn-pipelines-18c79b4ae09a?source=collection_archive---------6-----------------------

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

Photo by Thomas Ashlock on Unsplash

评估管线中特征重要性的简单方法

Scikit-learn 管道提供了一种非常简单的方法来将机器学习开发中的预处理步骤与模型拟合阶段链接在一起。使用管道,您可以嵌入这些步骤,以便在一行代码中,模型将在拟合模型或调用 predict 的同时执行所有必要的预处理步骤。

除了减少项目中的代码行之外,这样做还有很多好处。使用标准管道布局意味着同事或未来的自己很容易快速理解您的工作流程。这反过来意味着你的工作更具可复制性。此外,通过管道,您可以强制执行转换发生的顺序。

然而有一个缺点,尽管 scikit-learn 模型具有高度可解释的优点。一旦您将模型嵌入到管道中,就很难提取元素,例如使这些模型如此可解释的特性重要性。

我最近花了一些时间研究这个问题。在下一篇文章中,我将展示一个我发现的简单方法,使用 python 库 ELI5 从管道中提取特性重要性。

简单管道

在本文中,我将使用来自机器学习竞赛网站 drivendata.org 的数据集。数据集可以在这里下载。

首先,我将导入我正在使用的所有库。

import pandas as pd
import numpy as npfrom sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.metrics import f1_score
from sklearn.preprocessing import OneHotEncoder
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.metrics import classification_report
from sklearn.linear_model import LogisticRegressionimport eli5

然后,我使用 pandas 库读取我之前下载的数据集。特征和目标标签在单独的 CSV 文件中,所以我也使用熊猫合并功能将它们合并到一个数据框中。

train_values = pd.read_csv('train_values.csv')
train_labels = pd.read_csv('train_labels.csv')
train_data = train_values.merge(train_labels, left_on='building_id', right_on='building_id')

如果我们检查数据类型,我们可以看到数字和分类数据的混合。因此,我们需要在训练模型之前应用一些预处理。因此,管道对于该数据集将是有用的。

train_data.dtypes

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

在构建管道之前,我删除了“building_id”列,因为它不需要用于训练,将数据分成测试集和训练集,并定义一些变量来标识分类列和数字列。

train_data = train_data.drop('building_id', axis=1)numeric_features = train_data.select_dtypes(include=['int64', 'float64']).drop(['damage_grade'], axis=1).columns
categorical_features = train_data.select_dtypes(include=['object']).columns
X = train_data.drop('damage_grade', axis=1)
y = train_data['damage_grade']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

我将构建一个简单的管道,将预处理和模型拟合步骤连接在一起。此外,我将为任何缺失值添加一个估算器。虽然我在这里使用的数据集没有任何丢失的数据,但在这一步添加是明智的。这是因为在现实世界中,如果我们将它部署为一个机器学习应用程序,我们试图预测的新数据可能会丢失值。因此,将它添加为安全网是一种良好的做法。

下面的代码构建了一个管道,用于估算任何缺失值,将标准缩放器应用于数字特征,将任何分类特征转换为数字特征,然后拟合分类器。

numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())])
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
    ('one_hot', OneHotEncoder())])
preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numeric_features),
        ('cat', categorical_transformer, categorical_features)
    ])pipe = Pipeline(steps=[('preprocessor', preprocessor),
                      ('classifier',  LogisticRegression(class_weight='balanced', random_state=0))])

model = pipe.fit(X_train, y_train)

我们可以通过运行下面的代码来检查管道的质量。

target_names = y_test.unique().astype(str)
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred, target_names=target_names))

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

我们可以看到,就模型的性能而言,很可能还有改进的空间。除了模型选择和超参数优化之外,我们想探索的一个领域是特征工程。然而,为了决定设计哪些新功能,我们首先需要了解哪些功能最具预测性。

ELI5

从这条管道中提取特征重要性并不容易。然而,有一个叫做 ELI5 的 python 库使这变得非常简单。这个库以俚语“像我 5 岁一样解释”命名,是一个提供简单方法来解释和解释机器学习模型的包。它兼容大多数流行的机器学习框架,包括 scikit-learn、xgboost 和 keras。

该库可以通过 pip 或 conda 安装。

pip install eli5conda install -c conda-forge eli5

让我们使用 ELI5 从管道中提取特性重要性。

ELI5 需要知道所有的特性名称,以便构造特性重要性。通过对管道中的分类变量应用一次性编码,我们引入了许多新特性。因此,我们首先需要提取这些特征名称,并将它们添加到已知的数字特征列表中。下面的代码使用 scikit-learn 管道中内置的“named_steps”函数来实现这一点。

onehot_columns = list(pipe.named_steps['preprocessor'].named_transformers_['cat'].named_steps['one_hot'].get_feature_names(input_features=categorical_features))
numeric_features_list = list(numeric_features)
numeric_features_list.extend(onehot_columns)

为了提取特性的重要性,我们只需要运行这行代码。

eli5.explain_weights(pipe.named_steps['classifier'], top=50, feature_names=numeric_features_list)

这给出了一个格式良好的输出。

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

ELI5 库还提供了解释单个预测的能力,但管道尚不支持这一功能。在本文中,我演示了一种从 scikit-learn 管道中提取特性重要性的简单方法,这为调试和改进机器学习模型提供了一个良好的起点。

感谢阅读!

使用 R Regex 从文本中提取关键字(简单)

原文:https://towardsdatascience.com/extracting-information-from-a-text-in-5-minutes-using-r-regex-520a859590de?source=collection_archive---------10-----------------------

我们可以从美国的职位描述中提取相关信息,并将其可视化。

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

photo credit to Jason from unsplash

当您有大量文本文件时,只提取相关信息并不容易。这既复杂又耗时。出于这个原因,我想向您展示我是如何使用 Regex 从美国职位描述中提取位置的。

文本文件

以下是工作描述的结构。我的目标是从这个文本列中只提取州。

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

Preview of the job description

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

Example of one job description

第一步。去掉标点符号和尾随空格

状态有一个尾随空格,它位于一行的末尾,后面没有任何字符。如果不删除它(\n),将会提取出多余的单词。

此外,保持州名缩写为大写字母也很重要(对于加利福尼亚,用‘CA’而不是‘CA’),因为如果你不这样做,它将提取所有包含‘CA’的单词。

# deleting punctuations
description$text<-gsub("[[:punct:][:blank:]]+", " ", description$text)# deleting trailing space
description$text<-gsub("\\n"," ", description$text)

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

Job description after cleaning

第二步。使用正则表达式

清理后,您可以按空格分割工作描述文本,并找到与州缩写列表(字典)匹配的字符串。完成后,您可以将其分配到 location 列,如下所示。

#creating a location columndescription$location <- NA #using for loop to extract all the states for (i in 1:length(description$text)){ #split the text by space  
split <- strsplit(description$text[i]," ")[[1]] #comparing split with the state abbreviation   
state <- match(split, stateabbreviation$Abbreviation) #if it matches, get the position of each state  
state <- which(!is.na(state)) #extract the state based on the position  
state_split <- split[state] #adding states to the new column   
description$location[i] <- state_split[1]  
}

为了找到职位描述中的州缩写,我使用了自己创建的字典“stateabbreviation”。

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

和…瞧啊。这是结果。

如果还想提取城市,只需使用相同的代码和’ which(!idspnonenote)即可。is.na(位置))-1 '。你用“-1”是因为城市在州的前面。

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

第三步。可视化

现在你可以把它形象化,以便更好地理解你的发现。

library(ggplot2)state_count<-table(description$location)state_count<-as.data.frame(state_count)ggplot(state_count, aes(x = as.character(state_count$Var1), y = state_count$Freq)) + geom_bar(stat="identity") + theme(axis.text.x = element_text(angle = 60, vjust = )) + labs(y = "Frequency", x= "States")

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

这是我工作的一部分,以便更好地了解当前的数据科学就业市场。根据这一结果,加利福尼亚州、纽约州和德克萨斯州非常需要精通数据/技术的专业人员。

关于我的文本挖掘项目的更多细节,请随时访问我的 GitHub 页面。感谢您的阅读!

另外,请随意查看我的其他文章:

如何获得关于货币汇率的 Twitter 通知:Web 抓取和自动化

数据块:如何在本地计算机上将数据帧保存为 CSV 文件

使用脸书 Pytorch BigGraph 从知识图中提取知识。

原文:https://towardsdatascience.com/extracting-knowledge-from-knowledge-graphs-e5521e4861a0?source=collection_archive---------6-----------------------

机器学习让我们有能力训练一个模型,它可以将数据行转换成标签,以这样的方式将相似的数据行映射到相似的或相同的标签。

例如,我们正在为电子邮件构建垃圾邮件过滤器。我们有很多电子邮件,其中一些被标记为垃圾邮件,一些被标记为收件箱。我们可以建立一个学习识别垃圾邮件的模型。将被标记为垃圾邮件的消息在某些方面类似于那些已经被标记为垃圾邮件的消息。

相似度的概念对于机器学习来说至关重要。在现实世界中,相似性的概念对于主题来说是非常具体的,它取决于我们的知识。

另一方面,大多数数学模型假定相似性的概念是确定的。通常,我们将数据表示为多维向量,并测量向量之间的距离。

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

https://www.quora.com/Why-do-we-use-cosine-similarity-on-Word2Vec-instead-of-Euclidean-distance

特征工程是将我们对现实世界物体的知识转换成这种物体的数字表示的过程。我们认为相似的物体被表示为邻近矢量。

例如,我们正在估算房价。我们的经验告诉我们,房子是由卧室的数量、浴室的数量、年龄、面积来决定的。镜头、位置等。位于同一街区、大小和年龄相似的房子,价格应该差不多。我们将我们对住房市场的了解转化为表征房屋的数字,并用它来估计房屋的价格。

不幸的是,如上所述,手动特征工程在我们将知识转化为描述性特征的能力方面存在局限性。

有时我们的知识仅限于相似性原则,而不是使物体相似的确切特征。我们对现实世界的了解往往比简单的表格形式更复杂。这是一个典型的相互联系的概念和关系的图表。

嵌入模型允许我们获取原始数据,并根据我们的原理知识自动将其转换为特征。

Word2Vec

Word2Vec 可能是最著名的嵌入模型,它为单词构建相似性向量。在这种情况下,我们关于世界的知识是以叙事的形式呈现的,表现为文本,文本是一系列的单词。

几十年来,人们努力尝试使用人工定义的特征来表征单词,但成效有限。在有限的情况下,这些解决方案通常不能扩展到全部知识或工作。

当托马斯·米科洛夫和他在谷歌的团队决定建立一个基于众所周知的相似性原理的模型时,一切都改变了。在相似的上下文中使用的单词通常是相似的。在这种情况下,上下文是由位于附近的单词定义的。

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

Graph representation of the sequence of words.

我们看到的是,牢记这些原则,我们可以通过简单地在预定义的窗口(通常是 5 个单词)内将每个单词与其邻居连接起来,从我们的文本中构建一个图表。

现在我们有了一个基于我们的知识连接成图的真实单词对象(单词)的图。

最简单/复杂的单词表示

我们仍然无法建立任何模型,因为单词不是用形式或向量来表示的。

如果我们需要的只是将单词转换成数字,有一个简单的解决方案。让我们拿起字典,给每个单词指定它在字典中的位置。

比如我有三个词:猫,毛毛虫,小猫。

我的向量表示将如下:猫-[1],毛毛虫-[2]和小猫-[3]。

不幸的是,这不起作用。通过像这样分配数字,我们隐含地引入了单词之间的距离。猫和毛毛虫之间的距离是 1,猫和小猫之间的距离是 2。我们在说,猫更像毛毛虫,而不是小猫,这与我们的知识相矛盾。

替代表示也称为一键编码可以做到这一点:

猫— [1,0,0]

卡特彼勒— [0,1,0]

小猫— [0,0,1]

这个模式认为所有的单词都是相互正交的。我们承认对词语相似性没有先入为主的概念。我们将依靠我们的知识图(如上所述)来构建嵌入,该知识图结合了我们的单词相似性原则。

在现实世界中,字典的大小比 3 大得多。典型的维数从数万到数百万。不仅这些向量不能真正代表我们的相似性概念,而且这些向量非常庞大,不能真正用于实践。

构建单词嵌入

我们的知识图为我们提供了大量的图边,每条边都可以被解释为输入数据作为边的起点,标签作为边的终点。我们正在构建一个模型,它试图使用单词周围的单词作为标签来预测单词。通常有两种方式。我们或者从它的邻居的总和中重建单词向量,或者我们通过尝试从单词中预测邻居来做相反的事情。

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

https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf

该模型的细节不在讨论范围内,在许多其他帖子中有详细描述。从根本上说,该团队使用基本的编码器/解码器模型来学习从高维空间(数百万维)到有限维空间(通常为 300 维)的投影,然后再回到高维空间。训练的目标是在压缩过程中保留尽可能多的信息(最小化交叉熵)。

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

http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/

这种将低维投影从稀疏正交数据集学习到更密集的低维空间的概念是许多其他嵌入训练模型的基础。

该模型通常在 google crawl、twitter 数据集或维基百科等来源上进行训练。我们正在消费世界知识,并以此为基础构建我们的词汇。

Word2Vec 嵌入的属性

Word2Vec 的重要属性是保留关系和暴露结构等价的能力。

下面的图表显示了国家和首都之间的联系。

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

或者其他不同的概念。

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

https://www.tensorflow.org/tutorials/representation/word2vec

本质上,它允许对这样的单词进行代数运算:

国王——男人+女人=王后。

使用单词嵌入

单词嵌入极大地改善了文本分类、命名实体识别、机器翻译等任务。

以下是更多信息:http://www . wild ml . com/2015/11/understanding-convolutionary-neural-networks-for-NLP/

Node2Vec

由 A. Grover 和 J. Leskovec 设计的 Node2Vec 。是模型,它通过扩展 Word2Vec 的思想来分析同质加权图。这篇论文背后的思想是,我们可以通过探索它的周围来表征图节点。我们对世界的理解基于两个原则——同质性和结构等效性。

同质性

类似的节点位于附近。

示例:

  • 社交网络——我们和像我们一样的人联系更加紧密。
  • 商业位置——金融公司、诊所或营销公司似乎通常位于同一条街道上
  • 组织结构——同一个团队的人拥有相似的特质

结构等价

不同的社区共享相同的结构:

  • 组织结构——虽然团队之间的联系可能很弱,但团队的结构(经理、高级成员、新人、初级成员)在团队之间是重复的。

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

https://arxiv.org/pdf/1607.00653.pdf

为了将这两个原则结合到我们的嵌入中,Node2Vec 论文的作者提出了一种随机行走方法,该方法结合了广度优先采样来捕获同伦性,以及深度优先采样来捕获结构等价性。

正如我们可以看到的,节点(u)充当组(s1,s2,s3,s4)中的集线器,这类似于 s6 是(s7,s5,s8,s9)的集线器。我们通过做 DFS 发现了 BFS 的(s1,s2,s3,s4)社区和(u) (s6)相似性。

我们通过探索周围环境来了解每个节点。这种探索将图形转换成由随机游走产生的大量序列(句子),随机游走结合了 BFS 和 DFS 探索。BFS 和 DFS 混合由图边的权重以及模型的超参数控制。

一旦我们有了完整的序列(句子),我们就可以像应用于文本一样应用 Word2Vec 方法。它产生图节点嵌入,这是基于我们定义的原则以及来自图的知识。

Node2Vec 属性

Node2Vec 表示改进了节点的聚类和分类模型。学习到的嵌入的相似性将有助于像欺诈检测这样的任务。

node2vec 生成的 Les Misérables 共生网络的补充可视化,标签颜色反映了同质性(上图)和结构等价性(下图)。—https://arxiv.org/pdf/1607.00653.pdf

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

https://arxiv.org/pdf/1607.00653.pdf

Node2Vec 在链路预测方面表现出显著的改进。它能够提高重建图形的能力,其中一些百分比的边被删除。链接预测评估过程将在本文中进一步讨论。

知识图表

下面我们要讨论的是 PYTORCH-BIGGRAPH:一个大规模图嵌入系统论文进一步命名为 PBG 以及相关的论文家族。

知识图是特殊类型的图,它包含已知的实体以及不同类型的边。它代表结构知识。

在知识图中,节点通过不同类型的关系连接。

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

https://arxiv.org/pdf/1503.00759.pdf

训练的目标是产生代表我们知识的嵌入。一旦我们有了节点的嵌入,应该很容易确定相应的节点在我们的知识图中是否通过特定类型的关系被连接(或者应该被连接)。

不同的模型提出了不同的比较嵌入的方法。最简单的模型使用余弦或矢量积距离来比较嵌入矢量。更复杂的模型在比较之前对向量的元素应用不同的加权方案。加权方案被表示为矩阵,并且特定于关系的类型。作为培训的一部分,我们可以学习加权矩阵。

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

https://www.sysml.cc/doc/2019/71.pdf

我们需要找到一种方法来测量边之间的相似性得分,并使用该得分来估计这些节点连接的可能性。

知识图的表示

知识图可以表示为邻接张量。为了建立它,我们将有一个正方形矩阵来代表每一种关系。每个矩阵都有与图中节点一样多的列或行。矩阵的值将是 1,这些节点通过这种类型的关系连接,如果不是,则为 0。很明显,这个矩阵会非常大,非常稀疏。

为了学习我们的嵌入,我们需要将每个节点转换成固定大小的向量。让我们讨论“好”嵌入的性质。

好的嵌入表示我们以图边的形式表达的知识。位于“附近”的嵌入向量应该代表更可能连接的节点。基于这一观察,我们将以这样的方式训练我们的模型,即在邻接张量中标记为 1 的连接节点的相似性得分将更高,而在邻接张量中标记为 0 的连接节点的相似性得分将更低。

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

https://arxiv.org/pdf/1503.00759.pdf

我们正在训练我们的嵌入以 用最小的信息损失从节点嵌入中重建 知识图的边。

负采样

我们的训练方法有点问题。我们正在尝试使用图形数据来区分 1(节点已连接)和 0(节点未连接)。然而,我们实际拥有的唯一数据是连接在一起的节点。这就像学习只看猫来区分猫和狗一样。

负采样是一种通过使用非常简单的观察来扩展我们的数据集并提供更好的训练数据的技术。任何随机选择的节点,不作为我们的图的一部分连接,将代表一个标签为 0 的样本数据。出于训练的目的,PBG 的论文提出读取图的每条边,然后提出一个负样本,其中一个节点被随机选择的节点代替。

对于每个边,我们可以分配一个正的相似性得分和一个负的相似性得分。基于节点嵌入和边关系类型权重来计算正相似性得分。以相同的方式计算负的 相似性得分,但是边的一个节点被破坏并被随机节点替换。

排名损失功能,将在训练中优化。它被构造成在图中所有节点和所有关系类型的正和负相似性得分之间建立可配置的余量。排序损失是节点嵌入和关系特定权重的函数,这将通过找到最小排序损失来学习。

培养

现在,我们拥有了训练嵌入模型所需的一切:

  • 数据—负边缘和正边缘
  • 标签— (1 或 0)
  • 要优化的函数(可以是排序损失、更传统的逻辑回归损失或 word2vec 中使用的交叉熵 softmax 损失)
  • 我们的参数是相似性得分函数的嵌入和权重矩阵。

现在的问题是使用微积分找到参数——嵌入,优化我们的损失函数。

随机梯度下降

随机梯度下降的本质是逐渐调整损失函数的参数,使得损失函数逐渐减小。为此,我们以小批量读取数据,使用每一批来计算损失函数的参数更新,以使其最小化。

有多种方法可以实现随机梯度下降。PBG 论文使用 ADAGrad,这是随机梯度下降的一种风格来寻找参数,使我们的损失函数最小化。强烈推荐这篇博客了解梯度下降的所有味道:http://ruder . io/optimizing-gradient-descent/index . html # adagrad

像 tensorflow 和 pytorch 这样的软件包提供了不同风格的现成实现。

梯度下降的关键要素是多次更新模型参数的过程,直到我们最小化损失函数。在训练结束时,我们期望有嵌入和评分功能,这满足了整合我们的知识的目标。

HogWild —分布式随机梯度下降

使用随机梯度下降进行分布带来了挑战。如果我们同时通过调整参数来最小化损失函数,那么就需要某种锁定机制。在传统的多线程开发中,我们通过悲观或乐观锁定在更新期间锁定数据。锁定减慢了进度,但确保了结果的正确性。

幸运的是,的论文证明了我们不需要一个锁定机制。我们可以简单地批量读取数据,计算参数调整,并将其保存在共享参数空间中,而不考虑正确性。霍格维尔德算法就是这么做的。训练可以是分布式的,每个 HogWild 线程可以更新我们的参数,而不用考虑其他线程。

我推荐这个博客来获得更多关于 HogWild 的信息:https://medium . com/@ Krishna _ SRD/parallel-machine-learning-with-hog wild-f 945 ad 7 e 48 a 4

分布式培训

当图形跨越数十亿个节点和数万亿条边时,很难在一台机器的内存中容纳所有参数。如果我们要等到每一批结束时才开始下一批计算,也会花费很多时间。我们的图表如此之大,以至于能够并行化训练并同时学习参数将是有益的。这个问题被脸书团队解决了,他们发布了 PBG 论文。

节点按实体类型拆分,然后组织成分区:

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

https://torchbiggraph.readthedocs.io/en/latest/data_model.html

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

https://torchbiggraph.readthedocs.io/en/latest/data_model.html

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

https://www.sysml.cc/doc/2019/71.pdf

  1. 节点被划分成 P 个桶,边被划分成 PxP 个桶。基数小的实体类型不必分区。
  2. 训练与以下约束并行进行:

对于每个边缘桶(P1;p2)除了第一个,重要的是边缘桶(P1;)或(;p2)在先前的迭代中被训练。

只要在不相交的分区集上操作,就可以并行训练多个边缘桶。

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

https://www.sysml.cc/doc/2019/71.pdf

训练在多台机器上并行进行,每台机器上有多个线程。每个线程根据分配的桶和数据批次计算参数更新。锁服务器根据建立的约束分配训练桶。请注意,锁服务器只控制数据批次在 hogwild 线程中的分布,而不控制参数更新。

PBG 嵌入的特征

知识嵌入可以以两种方式使用:

  • 链接预测。链接预测通过找到可能连接或即将连接的节点来帮助填补我们知识中的空白。
    示例:图表代表客户和客户购买的产品。边是采购订单。嵌入可以用来形成下一个购买建议。
  • 学习节点的属性
    嵌入可以用作特征向量,作为各种分类模型的输入。学习过的类可以填补我们关于物体属性知识的空白。

使用 MRR/Hits 评估链接预测 10

这个过程在论文中有所描述——“学习知识库的结构化嵌入”,后来在包括脸书·PBG 在内的许多其他论文中被用作衡量嵌入模型质量的方法。

该算法采用测试边缘的子集,并执行以下操作:

  1. 通过用负采样边替换边的开始或结束来破坏边。
  2. 在部分损坏的数据集上训练模型
  3. 计算测试数据集中边的聚合 MRR 和 Hits10 度量。

平均倒数等级

MRR 或平均倒数排名是对搜索质量的衡量。我们选取一个未损坏的节点,并使用定义为相似性得分的距离来查找“最近的邻居”。我们通过相似性得分对最近的邻居进行排序,并期望被连接的节点出现在排序的顶部。如果节点不在顶部倾斜,MRR 会降低准确度分数。

另一个度量是 Hits10,我们期望被破坏的节点出现在前 10 个最近的邻居中。

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

https://www.sysml.cc/doc/2019/71.pdf

PBG 的论文表明,在许多数据集上,随着我们将资源分配到训练中,MRR 度量逐渐增加。并行性在一定程度上不会影响排序的质量,但会节省大量时间。

通过简单地探索和可视化图形,可以执行进一步的评估。

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

https://ai.facebook.com/blog/open-sourcing-pytorch-biggraph-for-faster-embeddings-of-extremely-large-graphs/

上图是从 Freebase 知识图构建的嵌入的 2d 投影。如我们所见,相似的节点被组合在一起。国家、数字、科学期刊、专业人士甚至在精心准备的二维投影上似乎都有集群。

知识图模型的局限性。

如上所述的知识图表代表了我们知识的静态快照。它没有反映出知识是如何积累起来的。在现实世界中,我们通过观察时间模式来学习。虽然可以了解节点 A 和节点 B 之间的相似性,但很难看出节点 A 和节点 C 之间的相似性,就像 3 年前一样。

例如,如果我们观察森林一天,我们会看到两棵大红杉之间的相似之处。然而,如果不对森林进行长期观察,很难理解哪棵树苗会长成一棵大红杉。

理想情况下,我们需要探索在不同时间点构建的一系列知识图,然后构建嵌入,这将包含代际相似性。

来自 Twitter 的患者对药品的看法

原文:https://towardsdatascience.com/extracting-patient-sentiment-for-pharmaceutical-drugs-from-twitter-2315870a0e3c?source=collection_archive---------38-----------------------

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

Photo by Pixabay on Pexels

制药公司面临的一个常见问题是根据患者的旅程预测患者是否会更换药物。指示寻求转换处方药的患者的信息可以出现在社交媒体帖子中。分析患者在关于处方药的推文中表达的情绪,可能是朝着解决这个问题的正确方向迈出的一步。

在本帖中,我们将提取美国一些最常见处方药的患者情绪。我们将关注在美国开出的前 10 种药物中的 5 种:

  1. 维柯丁:一种用于治疗中度至重度疼痛的药物
  2. 辛伐他汀:一种 HMG-CoA 还原酶抑制剂(他汀类),用于降低中风和心脏病发作的风险
  3. 赖诺普利:一种血管紧张素转换酶(ACE)抑制剂,用于降低高血压和预防糖尿病引起的肾衰竭
  4. 立普妥:一种用于预防冠心病患者中风和心脏病发作的他汀类药物
  5. 二甲双胍:治疗二型糖尿病的药物

首先,你需要申请一个 Twitter 开发者账户:

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

Source

您的开发人员帐户获得批准后,您需要创建一个 Twitter 应用程序:

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

Source

申请 Twitter 开发者账户和创建 Twitter 应用程序的步骤在这里列出

为了访问 Twitter API,我们将使用免费的 python 库 tweepy。tweepy 的文档可以在这里找到。

  1. 安装

首先,确保您已经安装了 tweepy。打开命令行并键入:

pip install tweepy

2.导入库

接下来,打开您最喜欢的编辑器,导入 tweepy 和 pandas 库:

import tweepy
import pandas as pd

3.认证

接下来,我们需要我们的消费者密钥和访问令牌:

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

Source

请注意,该网站建议您保持您的密钥和令牌私有!这里我们定义了一个假的密钥和令牌,但是在创建 Twitter 应用程序时,您应该使用真正的密钥和令牌,如上所示:

consumer_key = '5GBi0dCerYpy2jJtkkU3UwqYtgJpRd' 
consumer_secret = 'Q88B4BDDAX0dCerYy2jJtkkU3UpwqY'
access_token = 'X0dCerYpwi0dCerYpwy2jJtkkU3U'
access_token_secret = 'kly2pwi0dCerYpjJtdCerYkkU3Um'

下一步是创建 OAuthHandler 实例。我们传递上面定义的消费者密钥和访问令牌:

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

接下来,我们将 OAuthHandler 实例传递给 API 方法:

api = tweepy.API(auth)
  1. TWITTER API 请求

接下来,我们为我们有兴趣分析的字段初始化列表。现在,我们可以查看推文字符串、用户和推文时间。接下来,我们在一个 tweepy“Cursor”对象上编写一个 for 循环。在“Cursor”对象中,我们传递“api.search”方法,为我们想要搜索的内容设置查询字符串,并设置“count”= 1000,这样我们就不会超过 twitter 的速率限制。在这里,我们将搜索关于维柯丁的推文,维柯丁是一种用于治疗中度至重度疼痛的止痛药。我们还使用“item()”方法将“Cursor”对象转换为 iterable。

为了简化查询,我们可以删除转发,只包含英文推文。为了了解该请求返回的内容,我们还可以打印附加到每个列表的值:

twitter_users = []
tweet_time = []
tweet_string = []
for tweet in tweepy.Cursor(api.search,q='Vicodin', count=1000).items(1000):
            if (not tweet.retweeted) and ('RT @' not in tweet.text):
                if tweet.lang == "en":
                    twitter_users.append(tweet.user.name)
                    tweet_time.append(tweet.created_at)
                    tweet_string.append(tweet.text)
                    print([tweet.user.name,tweet.created_at,tweet.text])

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

我们也可以看看辛伐他汀的微博:

twitter_users = []
tweet_time = []
tweet_string = []
for tweet in tweepy.Cursor(api.search,q='Simvastatin', count=1000).items(1000):
            if (not tweet.retweeted) and ('RT @' not in tweet.text):
                if tweet.lang == "en":
                    twitter_users.append(tweet.user.name)
                    tweet_time.append(tweet.created_at)
                    tweet_string.append(tweet.text)
                    print([tweet.user.name,tweet.created_at,tweet.text])

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

为了实现可重用性,我们可以将它封装在一个函数中,该函数将药物关键字作为输入。我们还可以将结果存储在数据帧中并返回值:

def get_related_tweets(key_word):twitter_users = []
    tweet_time = []
    tweet_string = [] 
    for tweet in tweepy.Cursor(api.search,q=key_word, count=1000).items(1000):
            if (not tweet.retweeted) and ('RT @' not in tweet.text):
                if tweet.lang == "en":
                    twitter_users.append(tweet.user.name)
                    tweet_time.append(tweet.created_at)
                    tweet_string.append(tweet.text)
                    print([tweet.user.name,tweet.created_at,tweet.text])
    df = pd.DataFrame({'name':twitter_users, 'time': tweet_time, 'tweet': tweet_string})

    return df

当我们可以用药物名称‘赖诺普利’调用函数时,我们得到:

get_related_tweets('Lisinopril')

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

对于“立普妥”:

get_related_tweets('Lipitor')

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

最后是“二甲双胍”:

get_related_tweets('Metformin')

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

为了获得情感分数,我们需要导入一个名为 textblob 的 python 包。textblob 的文档可以在这里找到。要安装 textblob,请打开命令行并键入:

pip install textblob

下次导入 textblob:

from textblob import TextBlob

我们将使用极性得分作为积极或消极感觉的衡量标准。极性得分是一个从-1 到+1 的浮点数。

例如,如果我们定义一个 textblob 对象并传入句子“我喜欢 Aetna 的健康保险计划”,我们应该得到一个正值的极性得分:

sentiment_score = TextBlob(“I love my health insurance plan with Aetna”).sentiment.polarity
print("Sentiment Polarity Score:", sentiment_score)

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

让我们给关于“维柯丁”的推文打分:

df = get_related_tweets("Vicodin")
df['sentiment'] = df['tweet'].apply(lambda tweet: TextBlob(tweet).sentiment.polarity)
print(df.head()

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

我们也可以计算积极和消极情绪的数量:

df_pos = df[df['sentiment'] > 0.0]
df_neg = df[df['sentiment'] < 0.0]
print("Number of Positive Tweets", len(df_pos))
print("Number of Positive Tweets", len(df_neg))

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

同样,对于代码重用,我们可以将其全部封装在一个函数中:

def get_sentiment(key_word):
    df = get_related_tweets(key_word)
    df['sentiment'] = df['tweet'].apply(lambda tweet: TextBlob(tweet).sentiment.polarity)
    df_pos = df[df['sentiment'] > 0.0]
    df_neg = df[df['sentiment'] < 0.0]
    print("Number of Positive Tweets about {}".format(key_word), len(df_pos))
    print("Number of Negative Tweets about {}".format(key_word), len(df_neg))

如果我们用“立普妥”调用这个函数,我们得到:

get_sentiment(“Lipitor”)

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

如果我们能以编程方式可视化这些结果,那将会很方便。让我们导入 seaborn 和 matplotlib 并修改我们的 get _ 情操函数:

import seaborn as sns
import matplotlib.pyplot as pltdef get_sentiment(key_word):
    df = get_related_tweets(key_word)
    df['sentiment'] = df['tweet'].apply(lambda tweet: TextBlob(tweet).sentiment.polarity)
    df_pos = df[df['sentiment'] > 0.0]
    df_neg = df[df['sentiment'] < 0.0]
    print("Number of Positive Tweets about {}".format(key_word), len(df_pos))
    print("Number of Negative Tweets about {}".format(key_word), len(df_neg))
    sns.set()
    labels = ['Postive', 'Negative']
    heights = [len(df_pos), len(df_neg)]
    plt.bar(labels, heights, color = 'navy')
    plt.title(key_word)get_sentiment(“Lipitor”)

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

其他四种药物的结果是:

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

如您所见,维柯丁、辛伐他汀、二甲双胍和立普妥的积极情绪多于消极情绪,赖诺普利的消极情绪略多于积极情绪。我鼓励读者对其他药物进行同样的分析,看看推特上对该药物的普遍看法。收集几年的数据来观察某些药物的情绪得分是否存在任何时间依赖性(季节性)将是有趣的。也许我会把它留到以后的文章里。

感谢您的阅读。这篇文章的代码可以在 GitHub 上找到。祝好运,机器学习快乐!

注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

从图像中提取感兴趣区域

原文:https://towardsdatascience.com/extracting-regions-of-interest-from-images-dacfd05a41ba?source=collection_archive---------3-----------------------

利用 OpenCV 从图像中高效提取感兴趣区域

欢迎来到本系列的第二篇文章,我们将讨论使用 OpenCV 和 Python 从图像中提取感兴趣区域(ROI)。

回顾一下,在本系列的第一篇文章中,我们介绍了从台球桌的图像中提取球和球台边缘的步骤。我们使用简单的 OpenCV 函数,如 inRange,findContours,boundingRect,minAreaRect,****mineclosing Circle,circle,HoughLines,line 等来实现我们的目标。

对于 OpenCV 的初学者,我建议浏览一下的帖子,以便熟悉上述函数的用法。

在这篇文章中,我们将着眼于一个更复杂的问题,并探索一些我们可以用来获得预期结果的方法。

我们今天的任务是从包含患者大脑活动图快照的图像中提取所需的片段。然后,所提取的片段可以用于许多应用中,例如可以诊断任何健康异常的机器学习模型中。

让我们从输入图像本身开始。这是神经科学领域中使用的医疗仪器生成的典型报告,这些仪器使用传感器来检测来自患者大脑的信号,并将它们显示为彩色图。通常有四幅地图,每幅地图都描绘了某个特征,并一起进行分析以进行诊断(进一步的细节不在当前范围内)。

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

Our target image for this exercise containing the four brain maps (image source author)

从上面的图像中,我们只想提取对应于四个地图(头部扫描)的区域,其他的都不提取。所以我们走吧。

第一步是检测我们想要提取的片段的边缘。这是一个多步骤的过程,如下所述:

  1. 使用**“CVT color()”**将 RGB 图像转换为灰度
  2. 通过应用模糊函数**“Gaussian blur()”**去除灰度图像中的噪声
  3. 最后对模糊图像应用**“Canny()”**函数以获得边缘

边缘检测过程的输出如下所示:

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

Edge detection output using Canny algorithm (image source author)

请注意,虽然识别了脑图片段,但是有许多不需要的边缘需要消除,并且一些边缘之间有间隙需要闭合。

用于此目的的一种常用方法是形态变换,它涉及到在图像上使用一系列的膨胀和腐蚀来移除不需要的边缘和闭合间隙。

我们在多次迭代中使用 OpenCV 函数“explain()”和“erode()”来获得如下输出。

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

Some enhancements in the edges using OpenCV (image source author)

正如你所看到的,边缘现在是完整的,比以前平滑多了。

现在,我们可以使用 OpenCV 函数**“find contours()”**提取该图像中的轮廓,并仅选择具有以下属性的轮廓:

  1. 几何形状是圆形或椭圆形
  2. 面积高于某个阈值(在本例中,值 7000 很好)。

对于第一部分,我们将使用 OpenCV“bounding rect()”检测每个轮廓的外接矩形,并检查纵横比(高度与宽度之比)是否接近 1。

看起来我们的任务已经完成,但是还需要一点微调。

通常情况下,在一个片段上检测到多个重叠的轮廓,而我们只对一个感兴趣。

使用非最大值抑制解决了这个问题,即我们查看所有重叠的轮廓,并选择具有最大面积的轮廓作为最终候选轮廓。逻辑非常简单,因此我们不需要任何内置的 OpenCV 或 Python 函数。

另一个重要的逻辑是分别识别四个部分,即左上、右上、左下和右下。

这也非常简单,包括识别图像中心坐标以及我们检测到的每个片段的质心。分段轮廓的质心检测需要在轮廓上应用 OpenCV “moments()” 函数,然后使用下面的公式计算中心 X,Y 坐标:
center_x,center _ Y =(int(M[" M10 “]/M[” m00 “]),int(M[” m01 “]/M[” m00 "])

将分段质心坐标与图像中心坐标进行比较,可以让我们将四个分段放置在它们各自的位置。

现在我们已经确定了四个部分,我们需要建立图像蒙版,它将允许我们从原始图像中提取出想要的特征。

我们将使用 OpenCV 函数 “drawContours()” ,使用白色(R,G,B=255,2555,255)和填充厚度(-1)在黑色背景上绘制所有四个分段轮廓。结果如下所示:

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

Mask for extracting our ROIs (image source author)

在原始图像上应用这个蒙版可以在我们选择的背景(例如黑色或白色)上得到我们想要的片段。

对于黑色背景,我们创建一个黑色画布,然后使用 OpenCV 函数**“bitwise _ and()”**使用之前获得的蒙版在其上绘制。

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

Extracted ROIs over a black background (image source author)

对于白色背景,我们首先创建一个白色画布,然后创建一个彩色反转遮罩,如下图所示,使用 OpenCV 函数 “drawContours()” 以黑色(R,G,B = 0,0,0)绘制轮廓,填充厚度为(-1)。

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

An alternative Inverted mask for ROI extraction (image source author)

然后,我们使用 OpenCV**“add()”**函数将这个反转的蒙版与之前获得的黑色背景相加,得到相同的结果,但背景为白色。

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

Extracted ROIs over a white background (image source author)

这篇文章到此结束,在这篇文章中,我们研究了几种方法,使用这些方法可以很容易地从图像中提取感兴趣的区域。

应当注意,在具有不同复杂度的其他图像的情况下,上面使用的方法可以进行修改。然而,上面讨论的基础知识将为解决此类问题所需的任何高级技术奠定基础。

[## 2019 年 10 月 11 位最佳自由职业 OpenCV 开发者——Toptal

自 2013 年 10 月 28 日起成为会员 Ivan 是一名算法开发人员和研究科学家(博士),具有很强的数学…

www.toptal.com](https://www.toptal.com/opencv)

极端深度因子分解机器(xDeepFM)

原文:https://towardsdatascience.com/extreme-deep-factorization-machine-xdeepfm-1ba180a6de78?source=collection_archive---------5-----------------------

推荐系统领域的新热点

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

Photo by Nathan Dumlao on Unsplash

我们生活在一个被选择宠坏的时代。无论是食物、音乐还是娱乐,我们拥有的选择之多简直令人难以置信。但是由于推荐引擎为这些应用/网站提供了燃料,这些备选方案以排名列表的形式提供给我们。在这篇博客中,我们将讨论一种新的推荐算法,称为极端深度分解机器(xDeepFM)。

本博客组织如下:

  1. 当前生产中的推荐系统
  2. 介绍 xDeepFM
  3. 介绍 CIN(xDeepFM 的核心支柱)
    3.1 CIN 特性
    3.2 CIN 隐层
    3.3 与 RNN 相似
    3.4 与 CNN 相似
    3.5 隐层的池化与串接
    3.6 xDeepFM 的输出
  4. CIN 复杂度
    4.1 空间复杂度
    4.2 时间复杂度

5。使用 deepCTR 库的编码示例

6。参考文献

7。概要

开始吧!!

1.当前推荐系统

当前的推荐格局由基于 FM/DNN 的模型主导。但是也出现了一些融合 FM 和 DNN 系统的混合架构。

1。基于因式分解机(FM)的方法

  • +ve:自动学习组合特征的模式
  • +ve:很好地概括看不见的特征
  • -ve:试图捕获所有导致无用交互学习的特征交互。这可能会引入噪声。
  • 示例:推荐领域最受信任的主力

2。基于深度神经网络(DNN)的方法

  • +ve:学习复杂和选择性的功能交互
  • -ve:功能交互是在元素级别上建模的。一种热编码用于分类变量,以在维度 d 中表示它们。这将被馈送到完全连接的层中。这与基于 FM 的方法形成鲜明对比,基于 FM 的方法在向量级别(用户向量*项目向量)对特征交互进行建模。
  • 例如:神经协同过滤的 DNN 部分(NCF),Youtube 推荐的 DNN

3。DNN +调频(混合)方法

  • +ve:学习低/高阶特征交互
  • 例如:宽深度网络(Youtube)、神经协同过滤(NCF)、深度和交叉网络(DCN)、深度分解机(DeepFM)和极端深度分解机(xDeepFM)

你可以看看这篇文章,了解一下神经协同过滤(NCF)的概况。这是所有混合动力车型中被引用最多的。

[## 神经协同过滤

基于神经网络的增压协同过滤

medium.com](https://medium.com/@abhisheksharma_57055/neural-collaborative-filtering-96cef1009401)

所有混合类别的例子都使用 DNN 来学习隐式的按位特征交互。它们的不同之处在于如何学习高阶特征相互作用。

2.xDeepFM 简介

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

Figure 1: The architecture of xDeepFM

xDeepFM 由 3 部分组成:

  1. 线性模型(直接在原始输入要素上工作)
  2. 普通 DNN(在密集要素嵌入的基础上工作)
  3. CIN(在密集特征嵌入之上工作)

在这三个国家中,CIN 是 xDeepFM 独有的。

3.介绍***【CIN】***压缩互动网络

基于 DNN 的系统的问题是它们隐含地学习高阶交互。在 xDeepFM 中,通过压缩交互网络(CIN)学习显式高阶特征交互。

3.1 CIN 的特点

xDeepFM 推荐 CIN 是因为以下好处:

  • 它在向量层次上学习功能交互,而不是在逐位层次上。
  • 它明确地测量高阶特征相互作用。
  • 它的复杂性不会随着相互作用的程度呈指数增长。

3.2 CIN 隐藏层

CIN 通过其隐藏层(图 4 中的每个 x 是一个隐藏层)学习显式特征交互,其定义如下

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

Equation 1

X(k-1,i) : 第 k 层(k-1 隐层)第 I 个场的嵌入向量
X(0,j) :第 k 层第 j 个场的嵌入向量(基嵌入/原始特征嵌入)
W(k,H,I,j) :维数为 m * H(k-1)的可学习参数

X(k) 中的每一行仅用 W(k,h)来区分。与 DNN 相反,没有激活来转换隐藏层。

3.3 与 RNN 相似

等式 1 类似于基于 RNN 的模型,因为 CIN 的输出取决于最后一个隐藏层和附加输入。

3.4 与 CNN 相似

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

Figure 2: Outer products along each dimension for feature interactions

m: 原始特征矩阵的行数
H(k): 隐藏层 k 的特征矩阵的行数

Z(k+1)是一个中间张量,它是隐藏层 X(k)和原始特征矩阵 X(0)的外积。Z(k+1)可以看作一种特殊类型的图像,W(k,h)可以看作一种滤波器。

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

Figure 3: The k-th layer of CIN. It compresses the intermediate tensor from H(K)*m to H(k+1)

当你沿着维度 D(每个嵌入特征的大小)滑动权重矩阵时,你得到一个隐藏向量 X(k+1,I)。

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

Figure 4: This is the expansion of CIN component of Figure 1

T: 网络的深度

3.5 隐藏层的汇集和连接

隐藏层的结果按行相加,然后在馈送到输出层之前连接在一起。

  1. 每个隐藏层都与输出单元有联系
  2. 总和池应用于每个隐藏层,以创建一个池向量,如下所示:

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

Equation 2:

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

Pooling Vector of length H(k) at layer k

隐藏层中的所有池向量在连接到输出单元之前被连接:

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

Concatenation of pooling vectors of all layers

3.6 xDeepFM 的输出方程

线性、CIN 和 DNN 都是用如下输出等式并行训练的:

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

Equation 3: Output Function of CIN

***适马:***s 形函数
a: 原始特征
W,b: 可学参数

基于 DNN 和 CIN 的层可以很好地互相补充,一起学习

1.隐式(DNN)和显式(CIN)特征交互。

2.低阶(DNN)和高阶(两者)特征相互作用。

4.CIN 空间和时间复杂性

4.1 空间复杂度

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

Space Complexity of CIN

第一项表示输出层的参数数量
第二项表示每层 k
的参数数量,如果我们假设所有隐藏层具有相同数量的特征向量 H。参数数量可以表示为 O(mHH*T)

4.2 时间复杂度

时间复杂度相当于 O(mHD * H * T)。
mhd: 计算 1 行 Z(k+1,H)的成本
***H:***H 层的特征向量(行数)
***T:***CIN 的隐藏层数

至此,我们完成了 xdeepfm 的理论。是时候看看它的实际效果了。

5.编码示例

我使用了 deepCTR 库中的 xDeepFM 实现。对于其他一些实现,请查看参考部分。

这里下载样本数据,然后使用以下代码读取数据并将特征分为密集或稀疏。

稀疏特征需要嵌入,而密集特征需要归一化。我们使用 MinMax scaler 进行标准化,而 LabelEncoder 进行特征编码。

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

This is how sparse_feature_columns[0] look

# creating a dense feat
dense_feature_columns = [DenseFeat(feat, 1) for feat in dense_features]

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

This is how dense_feature_columns[0] looks like

在下一个代码 blob 中,我们将使用 xDeepFM 进行初始化、编译、训练和预测

6.参考

  1. xDeepFM 论文
  2. 一些现成的 xDeepFM 实现有:-
    1。代码来自论文作者 xDeepFM
    2。来自微软推荐库
    3 的代码。 deepctr 用于以下实施

7.摘要

xDeepFM 是混合架构的一个例子。它将 MF 和 DNN 结合起来,以得到更好的性能。这是通过使用 CIN(压缩交互网络)实现的。CIN 有两种特殊的美德:

  1. 它可以有效地学习有界度特征交互。
  2. 它在向量水平上学习特征交互。

像其他流行的混合方法一样,xDeepFM 将 CIN 和 DNN 结合在一起。
由此可以显式和隐式地学习高阶特征交互。这减少了手动特征工程的需要。

我会敦促你尝试一下微软的库或 xDeepFM 作者的 T2 代码,尝试不同的 xDeepFM 实现。

你也可以看看这篇帖子来简要了解 NCF,这是另一种流行的混合架构。

[## 神经协同过滤

基于神经网络的增压协同过滤

medium.com](https://medium.com/@abhisheksharma_57055/neural-collaborative-filtering-96cef1009401)

请在评论区分享你的想法和主意。

用 LSTM 自动编码器预测极端事件

原文:https://towardsdatascience.com/extreme-event-forecasting-with-lstm-autoencoders-297492485037?source=collection_archive---------10-----------------------

提高预测性能开发强大的神经网络架构

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

Photo by Nur Afni Setiyaningrum on Unsplash

处理极端事件预测是每个数据科学家经常做的噩梦。环顾四周,我发现了处理这个问题的非常有趣的资源。就我个人而言,我简直爱上了优步研究人员发布的方法。在他们的论文中(这里有两个版本这里有这里有),他们开发了一个 ML 解决方案来预测未来的日常出行需求。他们的方法因其友好、解释清楚和易于实施而吸引了我的注意力。所以我的目的是用 pythonic 语言重现他们的发现。我对这个挑战非常满意,最终,我提高了回归预测的知识。

这篇文章最重要的收获可以总结为:

  • 开发一个稳定的方法来评估和比较 Keras 模型(同时避免权重种子生成器的问题);
  • 实现一个简单聪明的 LSTM 自动编码器用于新功能的创建;
  • 用简单的技巧提高时间序列的预测性能(见上一步);
  • 处理嵌套数据集,即我们的观察数据属于不同实体的问题(例如不同商店/引擎/人员的时间序列等)……从这个意义上说,我们只开发了一个适用于所有人的高性能模型!

但是保留 Kalm,让我们一步一步来。

问题概述

在优步,对已完成行程的准确预测(特别是在特殊活动期间)提供了一系列重要的好处:更有效的司机分配,从而减少乘客的等待时间,预算规划和其他相关任务。

为了实现对驾驶员拼车需求的高精度预测,优步的研究人员开发了一个高性能的时间序列预测模型。他们能够用来自不同地点/城市的大量异类时间序列来拟合(一次性)单一模型。这个过程允许我们提取相关的时间模式。最终,他们能够预测需求,针对不同的地点/城市进行归纳,优于传统的预测方法。

数据集

在这项任务中,优步利用了不同城市间日常出行的内部数据集,包括附加功能;即天气信息和城市级信息。他们的目标是从过去的固定观察窗口预测第二天的需求。

不幸的是,我们没有这种数据,所以作为 Kaggle 的粉丝,我们选择了不错的鳄梨价格数据集。该数据显示了两种不同品种鳄梨的历史价格,以及在多个美国市场的销量。

我们的选择是因为需要一个具有时间依赖性的嵌套数据集:我们有每个美国市场的时间序列,总共 54 个,如果我们考虑每种类型(传统和有机)的一个时间序列,这个数字将增长到 108。优步的研究人员强调这种数据结构的重要性,因为它允许我们的模型发现重要的不可见关系。此外,序列之间的相关性为我们的 LSTM 自动编码器在特征提取过程中带来了优势。

为了建立我们的模型,我们利用了截至 2017 年底的价格时间序列。2018 年的前 2 个月被存储并用作测试集。对于我们的分析,我们还将考虑所有提供的回归变量。观察结果以微弱的频率显示,因此我们的目的是:给定一个固定的过去窗口(4 周)的特征,预测即将到来的微弱价格。

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

Train (blue) Test (orange) overview of avocado prices

由于没有指数增长和趋势行为,我们不需要调整我们的价格系列。

建模

为了解决我们的预测任务,我们复制了优步提出的新的模型体系结构,它为异质预测提供了单一的模型。如下图所示,该模型首先通过自动特征提取启动网络,训练一个 LSTM 自动编码器,这对大规模捕捉复杂的时间序列动态至关重要。然后将特征向量与新输入连接起来,并馈送给 LSTM 预测器进行预测。

我们的预测工作流程很容易想象:我们有不同市场的每周价格的初始窗口(加上其他功能)。我们开始在它们上面训练我们的 LSTM 自动编码器;接下来,我们移除编码器并将其用作特征创建器。训练用于预测的预测 LSTM 模型所需的第二步也是最后一步。基于真实/现有的回归变量和之前人工生成的特征,我们能够提供下周的鳄梨价格预测。

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

from Time-series Extreme Event Forecasting with Neural Networks at Uber

我们很容易用 Keras 重新创建这个逻辑。

我们的 LSTM 自动编码器由一个简单的 LSTM 编码器层组成,后面是另一个简单的 LSTM 解码器。在评估期间你会明白辍学的效用,在这一点上他们是无害的,相信我!

inputs_ae = Input(shape=(sequence_length, n_features))
encoded_ae = LSTM(128, return_sequences=True, dropout=0.5)(inputs_ae, training=True)
decoded_ae = LSTM(32, return_sequences=True, dropout=0.5)(encoded_ae, training=True)
out_ae = TimeDistributed(Dense(1))(decoded_ae)
sequence_autoencoder = Model(inputs_ae, out_ae)

我们计算特征提取,并将结果与其他变量连接起来。在这一点上,我做了一点偏离优步的解决方案:他们建议操纵由我们的编码器提取的特征向量,通过集成技术(例如,平均)聚集它们。我决定让他们原创和免费。我做这个选择是因为它允许我在实验中获得更好的结果。

最后,预测模型是另一个简单的基于 LSTM 的神经网络:

inputs = Input(shape=(sequence_length, n_features))
lstm = LSTM(128, return_sequences=True, dropout=0.5)(inputs, training=True)
lstm = LSTM(32, return_sequences=False, dropout=0.5)(lstm, training=True)
dense = Dense(50)(lstm)
out = Dense(1)(dense)

估价

最后,我们几乎准备好看到一些结果,并作出预测。最后的步骤包括创建一个竞争模型和一个用于结果比较的稳健预测方法的结果定义。

就个人而言,评估两种不同程序的最佳方式是尽可能地复制它们,以便只在真正感兴趣的地方引起注意。在这个实现中,我想展示 LSTM Autoencoder 作为时间序列预测相关功能创建工具的能力。从这个意义上来说,为了评估我们方法的优劣,我决定开发一个新的价格预测模型,其结构与我们以前的预测神经网络相同。

它们之间的唯一区别是它们作为输入接收的特征。第一个接收编码器输出加上外部回归量;第二个接收过去的原始价格加上外部回归量。

不确定性估计和结果

时间序列预测在本质上对于感兴趣领域的极端可变性是至关重要的。此外,如果你试图建立一个基于神经网络的模型,你的结果也会受到内部权重初始化的影响。为了克服这个缺点,存在许多不确定性估计的方法:从贝叶斯到基于 bootstrap 理论的方法。

在他们的工作中,优步的研究人员结合了 Bootstrap 和 Bayesian 方法,产生了一个简单、健壮和紧密的不确定性界限,具有良好的覆盖范围和可证明的收敛特性。

这项技术非常简单和实用…间接我们已经实现了它!如下图所示,在前馈过程中,丢弃应用于编码器和预测网络中的所有层。因此,编码器中的随机丢失智能地干扰了嵌入空间中的输入,这说明了潜在的模型错误设定,并通过预测网络进一步传播。

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

from Time-series Extreme Event Forecasting with Neural Networks at Uber

Pythonic 说,我们只需在我们的神经网络中添加可训练的辍学层,并在预测期间重新激活它们(Keras 用于在预测期间减少辍学)。

对于最终的评估,我们必须迭代调用预测函数并存储结果。我还计算每次交互的预测得分(我选择平均绝对误差)。我们必须设置计算求值的次数(在我们的例子中是 100 次)。有了存储的分数,我们就能够计算 MAE 的平均值、标准偏差和相对不确定性。

我们对仅由 LSTM 预测网络制作的“对手模型”重复同样的程序。在平均分数和计算不确定性后,LSTM 自动编码器+ LSTM 预测器的最终结果比单一的 LSTM 预测器更好。

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

Performance (MAE) comparison on test data

摘要

在这篇文章中,我复制了一个在优步开发的用于特殊事件预测的端到端神经网络架构。我想强调:LSTM Autoencoder 在特征提取器角色中的力量;这种解决方案的可扩展性可以很好地概括,避免为每个时间序列训练多个模型;为神经网络评估提供稳定且有利的方法的能力。

我还注意到,当您拥有足够数量的共享共同行为的时间序列时,这种解决方案非常适合…这些行为是否立即可见并不重要,Autoencoder 为我们实现了这一点。

查看我的 GITHUB 回购

保持联系: Linkedin

参考文献

[1]对时间序列的深刻而自信的预测:,朱,拉普捷夫

[2]用神经网络进行时间序列极端事件预测:Nikolay Laptev,Jason Yosinski,Li Erran Li,Slawek Smyl

极端罕见事件分类:现实世界数据集的直接解决方案

原文:https://towardsdatascience.com/extreme-rare-event-classification-a-straight-forward-solution-58a20ef56ef5?source=collection_archive---------8-----------------------

用于检测造纸厂罕见事件(断纸)的预测模型。

首先,感谢 Chitta Ranjan 为我们提供了一个造纸厂的真实数据集。这是一个具有挑战性的时间序列数据集,也是预测维护领域的一个常见问题。本文针对该问题提出了一个可行且直截了当的解决方案。我强烈推荐阅读奇塔以前的文章(链接)。

在预测性维护领域,许多公司面临的挑战是根据设备行为(基于状态的维护)在故障发生之前预测故障。目前,维护人员使用的常用工具是 APM(资产性能管理),它基于风险和可靠性技术(例如威布尔曲线)。

**总结:**这种类型曲线的思想是将概率曲线上的故障分为三个不同的区域:过早故障、随机故障和寿命终止故障。

这是一个简单的想法,可以让我们了解这个领域中重要的特性,比如运行时间(计数器)。

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

Figure 1 — Weibull curve showing three tipical parts of probabilistic failure [Source: https://www.weibull.com/hotwire/issue14/relbasics14.htm]

预处理

首先,您需要使用以下代码创建问题的框架:

df['y_1'] = df['y'].shift(-1)
df['y_2'] = df['y'].shift(-2)
df = df.loc[df.y==0] #deleting the downtime eventdf['y'] = df.apply(lambda x: 1 if ((x['y_1'] == 1) | (x['y_2'] == 1)) else 0, axis=1)features = df.columns.tolist()# adding delayed info
features.remove('time')
features.remove('y_1')
features.remove('y_2')
features.remove('x61')
target = 'y'
features.remove(target)

一些亮点:由于数据周期(不到一个月)不能证明任何新功能的创建(小时、天、班次、季度、星期几等),所以时间功能被取消了。).另一个被排除的变量是完全冻结的 x61。

少数类约占所有数据的 1.3%。有一个很简单的方法可以稍微改善一下,就是确定活动前 6 分钟和 4 分钟一样好。所以,它将改善 50%的少数阶级,而且可以公平地断言,这不是一种可怕的罪恶:

df['y'] = df.apply(lambda x: 1 if ((x['y_1'] == 1) | (x['y_2'] == 1) | (x['y_3'] == 1) ) else 0, axis=1)

现在称为 count_y 的计数器(运行时间)是为将模型的时间流逝联系起来而创建的特性。

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

Figure 2 — The counter reset after the failure (y=1)

一类策略的异常检测

异常检测的最简单策略是使用一类算法,如 SVM 或马哈拉诺比斯距离,来了解数据中哪些是正常的,哪些是不正常的。

首先,数据将被分为训练和测试。

#Splitting
from sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(df[features],df[target],shuffle=True,
random_state=10)#Scalling
from sklearn.preprocessing import StandardScaler
scale = StandardScaler()x_train = pd.DataFrame(data=scale.fit_transform(x_train),columns=features,index=y_train.index)
x_test = pd.DataFrame(data=scale.transform(x_test),columns=features,index=y_test.index)

数据分离后,SVM 成为候选模型:

from sklearn.svm import OneClassSVM
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrixsvm1 = OneClassSVM(kernel='rbf', gamma='auto',nu=0.05)svm1.fit(x_train_pos[features])y_pred = pd.DataFrame(data=svm1.predict(x_test[features]))
# need to convert to the same standard, 0 == normal and 1 for break
y_pred.loc[y_pred[0]==1] = 0 # normal 
y_pred.loc[y_pred[0]==-1] = 1 #breakprint(classification_report(y_test,y_pred,digits=3))
confusion_matrix(y_test,y_pred)

结果低于基准(F1<0.1)

precision    recall  f1-score   support

           0      0.984     0.947     0.965      4486
          ** 1      0.040     0.123     0.061        81**

   micro avg      0.933     0.933     0.933      4567
   macro avg      0.512     0.535     0.513      4567
weighted avg      0.967     0.933     0.949      4567

Mahalabonis 距离提供了类似的结果:

clf_total = MahalanobisOneclassClassifier(x_train_pos[features], significance_level=0.001)mahalanobis_dist_total = clf_total.predict_proba(x_test_pos[features].values)print(classification_report(y_test,clf_total.predict(x_test[features].values),digits=3))precision    recall  f1-score   support

           0      0.984     0.886     0.932      4486
 **1      0.032     0.210     0.056        81**

   micro avg      0.874     0.874     0.874      4567
   macro avg      0.508     0.548     0.494      4567
weighted avg      0.967     0.874     0.917      4567

使用一类异常检测的小特征组

两种算法都使用所有的特性作为输入进行了基准测试。对于这种类型的算法来说,问题的规模肯定是复杂的。一种可能的策略是将特征分成相似组。

通常,与领域专家进行一次良好的工作会谈会有所帮助。另一种方法是使用 GradientBoost 树(要素重要性)来支持此定义。

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

Figure 3— Fragment of feature importance from XGBoost used to create the 1-class groups

通过使用前 20 个标签,将它们分成 2 个标签组,并在一个类别方法中计算 Mahalanobis 距离,我们人工创建了 10 个新特征,它们代表了与训练数据的标准操作的距离。

df['maha_dist'] = clf.predict_proba(df[feat_maha].values)
df['maha_dist2'] = clf2.predict_proba(df[feat_maha2].values)
df['maha_dist3'] = clf3.predict_proba(df[feat_maha3].values)
df['maha_dist4'] = clf4.predict_proba(df[feat_maha4].values)
df['maha_dist5'] = clf5.predict_proba(df[feat_maha5].values)
df['maha_dist6'] = clf6.predict_proba(df[feat_maha6].values)
df['maha_dist7'] = clf7.predict_proba(df[feat_maha7].values)
df['maha_dist8'] = clf8.predict_proba(df[feat_maha8].values)
df['maha_dist9'] = clf9.predict_proba(df[feat_maha9].values)
df['maha_dist10'] = clf10.predict_proba(df[feat_maha10].values)

问题框架的新功能:

['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8', 'x9', 'x10', 'x11', 'x12', 'x13', 'x14', 'x15', 'x16', 'x17', 'x18', 'x19', 'x20', 'x21', 'x22', 'x23', 'x24', 'x25', 'x26', 'x27', 'x28', 'x29', 'x30', 'x31', 'x32', 'x33', 'x34', 'x35', 'x36', 'x37', 'x38', 'x39', 'x40', 'x41', 'x42', 'x43', 'x44', 'x45', 'x46', 'x47', 'x48', 'x49', 'x50', 'x51', 'x52', 'x53', 'x54', 'x55', 'x56', 'x57', 'x58', 'x59', 'x60', 'count_y', 'maha_dist', 'maha_dist2', 'maha_dist3', 'maha_dist4', 'maha_dist5', 'maha_dist6', 'maha_dist7', 'maha_dist8', 'maha_dist9', 'maha_dist10']

它将使用 GradientBoostClassifier 作为接收这个新特性的主要分类器(图 4)。

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

Figure 4 — Simplied model structure

应注意避免使用相同的随机状态混合训练样本和测试样本:

x_train, x_test, y_train, y_test = train_test_split(df[features],df[target],shuffle=True,
random_state=10)gbc = XGBClassifier(n_estimators=1000,subsample=0.9,max_depth=6,random_state=10, max_features=0.9, n_jobs=2)**%**time gbc.fit(x_train,y_train)**Wall time: 1min 4s**

少数类 0.5 的 F1 结果高于问题的基准。

precision    recall  f1-score   support

           0      0.989     1.000     0.994      4486
 **1      0.968     0.370     0.536        81**

    accuracy                          0.989      4567
   macro avg      0.978     0.685     0.765      4567
weighted avg      0.988     0.989     0.986      4567

每个特征的异常检测

一个更简单的策略是使用第一个 XGBoost 特性重要性所指向的前 20 个标签为模型输入中的每个特性创建 AD(异常检测器)。

#top 20 tags
original_features = ['count_y','x51', 'x28','x26', 'x43','x60', 'x8','x54', 'x50','x14', 'x18','x24', 'x53','x23', 'x15','x22', 'x52','x42', 'x21', 'x36', 'x3']features_individual_ad = original_features.copy()
ad_maha = []
for feat in original_features:
    if not feat == 'count_y':
        _model = MahalanobisOneclassClassifier(x_train_pos[[feat]], significance_level=0.01)
        ad_maha.append(_model)
        _ad_name = feat + '_ad'
        df[_ad_name] = _model.predict_proba(df[[feat]].values)
        features_individual_ad.append(_ad_name)

并且结果甚至比成对特征的组合更好。

precision    recall  f1-score   support

           0      0.992     0.998     0.995      4486
 **1      0.865     0.556     0.677        81**

    accuracy                          0.991      4567
   macro avg      0.929     0.777     0.836      4567
weighted avg      0.990     0.991     0.990      4567

结论

使用人工特征(运行时间特征和 Mahalanobis 距离)和良好的 ML 分类器算法(梯度增强)的非常直接的解决方案为该问题提供了高于初始基准的结果(F1>0.1)。对于少数类,算法的最佳拓扑能够实现 0.67 F1。建议在训练和测试之间进行更稳健的分离(交叉验证),以验证该结果,并对模型参数进行微调。

完整的代码可以在 GIT 上找到。

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

Figure 5 — Featured image : All starts here … [source: pexels]

极端罕见事件分类:使用 Keras 中的 LSTM 估计剩余使用寿命

原文:https://towardsdatascience.com/extreme-rare-event-classification-remaining-useful-life-estimation-using-lstm-in-keras-81c9b5aa15f0?source=collection_archive---------10-----------------------

一种基于回归的估计造纸厂剩余使用寿命(RUL)的方法,用于纸幅断裂预测问题。

这篇文章中提出的观点、见解和工具是由之前发表在 Medium 上的两篇文章激发的。第一篇(链接)由奇塔·兰詹撰写,简要介绍了极端事件分类问题,并使用 LSTM 自动编码器方法来检测异常。通过分析自动编码器重建步骤中的误差,我们可以识别造纸厂中可能的卷筒纸断裂。第二篇(链接)由 Roberto Mansur 撰写,简要概述了基于状态的维护,并展示了威布尔曲线在概率故障分类中的应用。与 Ranjan 的文章不同,后者通过创建基于变量对之间的 Mahalanobis 距离的新特征来进行异常检测。

结合两篇文章中提出的观点,我们可以创建一个模型,根据造纸厂的历史条件来估计其 RUL。为了获得这种估计,使用具有长短期记忆(LSTM)结构的递归神经网络(RNN)作为回归模型。

图 1 通过显示锂离子电池在连续充电和放电循环中的容量曲线,举例说明了 RUL 的使用情况。为了估计该电池的 RUL,有必要在真实数据点上训练模型,并确定电池将在哪个充电和放电循环中产生其最小可接受容量,或者也称为其故障阈值。

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

Figure 1 — RUL Prediction for Lithium-Ion Batteries Based on Gaussian Processes Mixture [Source: https://journals.plos.org/plosone/article/figure?id=10.1371/journal.pone.0163004.g002]

这个问题用到的源代码和数据集可以在我的 GitHub 上找到(链接)。

概观

断纸是所有垂直造纸行业都会遇到的非常复杂的问题,由于其复杂性,很难找到断纸事件的具体原因。此外,中断纸张生产过程来调查和定位可能出现的问题非常耗时且成本高昂。以这种方式,许多直接处理预测性维护的公司利用 RUL 技术来安排老化部件和系统的维护,并监控设备的健康状况。

围绕极端罕见事件(如网页中断)的问题是不平衡类(中断和工作区),这导致在使用标准监督学习算法时对少数类的预测不准确。因此,为了避免这种情况,我们可以通过创建一个代表每个工作区RUL 的回归计数器,将二元分类问题转化为回归问题。在用先前的特征和新的目标计数器变量训练 LSTM 模型之后,我们可以预测剩余的使用寿命并确定小的故障阈值(取决于所需的响应时间),该阈值用于将每个事件分类为网断裂或不断裂。

逐步实施

预处理

在创建中断事件之前,从数据帧和新的 6 分钟区域中移除中断。此外,为了避免在创建这个新区域时出现问题,所有持续时间少于 6 分钟的工作区都从数据帧中删除。此外,由于缺少针对该问题给出的信息,所有冻结的标签也被从数据集中移除。

target = 'y'
# Creating 3 time shifts to build the region before break
df['y_1'] = df['y'].shift(-1)
df['y_2'] = df['y'].shift(-2)
df['y_3'] = df['y'].shift(-3)# First generated feature
df = count_change(df,'y','count_y')# Creates an ID for each counter reset
df = count_pikes(df,'y','count_id', True)
# ID Value adjustment - Starts at 0
df['count_id'] = df['count_id'] - df['count_id'].min()# Deleting the downtime events and the working zones with less than 6min
df_grouped = df.groupby('count_id').max()[['count_y', target]]
ids = df_grouped.loc[(df_grouped[target] == 0) & (df_grouped['count_y'] >= 3)].index
df = df.loc[df['count_id'].isin(ids)]# Building the region before the break
df['y'] = df.apply(lambda x: 1 if ((x['y_1'] == 1) | (x['y_2'] == 1) | (x['y_3'] == 1)) else 0, axis=1)# Removing target and unused columns
features = df.columns.tolist()
features.remove('time') # Unused column
features.remove('y_1')      # Aux columns
features.remove('y_2')      # ''
features.remove('y_3')      # ''
features.remove('count_id') # ''
features.remove('x61') # Freezed variable
features.remove(target)

特征工程

为了创建包含新目标的列,我们使用了在上一步中创建的辅助列: count_y 和 *count_id。*RUL 变量基本上是一个递减计数器,从最大剩余使用寿命值到零,这发生在断裂事件之前。

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

Figure 2 — Break target variable with the auxiliary columns.

总之,参见图 2,可以得出结论,新的目标 RUL 变量与 count_y 相反。因此,为了反转计数方向,我们找到了每个 count_id 的最大值 count_y ,并创建了一个名为 MAX_RUL 的新辅助列。

max_rul = df.groupby('count_id').max()['count_y'].reset_index()
max_rul.rename(columns={“count_y”:”MAX_RUL”}, inplace=True)

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

Figure 3 — New dataframe created with the MAX_RUL and the count_id information.

下一步是使用 *count_id 在原始数据帧上执行新创建的数据帧的左连接。*最后,从 MAX_RUL 中减去 count_y 得到新的目标 RUL 列。

# Left join on the count_id
df = pd.merge(df,max_rul,how='left',on='count_id')df['RUL'] = df['MAX_RUL'] - df['count_y']# Setting the new target
target = 'RUL'

应用所有更改后,数据帧应如下所示:

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

Figure 4— Dataframe with the RUL variable created as the new target.

拆分数据

对于这个问题,选择了 5 个时间步长,并使用 train_test_split 函数提供的默认测试大小分割数据。应用于数据帧的时移使得在 shuffle 参数设置为 True 的情况下拆分数据成为可能。

from sklearn.model_selection import train_test_splittimesteps = 5# List of shifted dataframes according to the number of timesteps
df_list = [df[features].shift(shift_val) if (shift_val == 0) 
                                else df[features].shift(-shift_val).add_suffix(f'_{shift_val}') 
                                for shift_val in range(0,timesteps)]# Concatenating list
df_concat = pd.concat(df_list, axis=1, sort=False)df_concat = df_concat.iloc[:-timesteps,:]# Default train_test_split - test_size=0.25
x_train, x_test, y_train, y_test = train_test_split(df_concat, df[target].iloc[:-timesteps], random_state=10, shuffle=True)

标准化数据

考虑到在这个问题中使用的递归神经网络(如 LSTM)的尺度敏感性,有必要对数据进行标准化。因此,通过使用 Scikit-Learn 库提供的标准定标器,对数据进行了定标。

from sklearn.preprocessing import StandardScalerscaler = StandardScaler()# Scaling and transforming the array back to the dataframe format
# Training
x_train_lstm = pd.DataFrame(data=scaler.fit_transform(x_train), columns=x_train.columns)# Test
x_test_lstm = pd.DataFrame(data=scaler.transform(x_test), columns=x_test.columns)

使用 LSTM 的回归方法

在这种方法中,我们将使用 Tensorflow 中的 LSTM 和 Keras 层来操作它。考虑到来自少数类的少量样本,使用 LSTM 方法作为不平衡类的分类器太具有挑战性(它使得模型不太专门用于预测中断事件)。也就是说,这个问题可以通过应用剩余使用寿命方法来解决。

因此,定义神经网络架构之前的第一步是格式化数据形状,使其符合 LSTM 的要求:【样本、时间步长、特征】。为此,创建了一个名为到 3D 的新函数。

def to_3D(X, features, timesteps=5):
    '''
        Shapes the dataset so it can fit into 
        LSTM's format requirement.
    '''
    # Creating an empty tridimensional array
    X_trans = np.empty((X.shape[0], timesteps, 0)) # Adjusting the shape of the data
    for feat in features:
        # Regular expressions to filter each feature and
        # drop the NaN values generated from the shift
        df_filtered = X.filter(regex=f'{feat}(_|$)')
        df_filtered=df_filtered.values.reshape(df_filtered.shape[0],
                                               timesteps, 1)
        X_trans = np.append(X_trans, df_filtered, axis=2)

    return X_trans

定义 LSTM 模型架构

这个模型由 5 层组成:2 层 LSTM,2 层辍学,1 层致密。代码和摘要如下所示:

from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, LSTM
import kerasmodel = Sequential()
model.add(LSTM(input_shape=(timesteps, len(features)), units=15, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(input_shape=(timesteps,len(features)), units=10, return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(units=1, activation = 'relu'))
model.compile(loss='mean_squared_error', optimizer='adam')
print(model.summary())

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

Figure 5 — Model architecture summary.

训练 LSTM 回归模型

model_path = 'lstm_model.h5'history = model.fit(to_3D(x_train_lstm, features), 
                    y_train, 
                    epochs=1000, 
                    batch_size= 8, 
                    validation_split=0.2, 
                    verbose=1, 
                    callbacks = [
                        keras.callbacks
                             .EarlyStopping(monitor='val_loss',
                                                     min_delta=0, 
                                                     patience=200,
                                                     verbose=1,
                                                     mode='min'), keras.callbacks
                             .ModelCheckpoint(model_path, 
                                              monitor='val_loss',
                                              save_best_only=True, 
                                              mode='min',
                                              verbose=1)])

评估回归模型

在用均方误差损失训练模型之后,我们获得了以下损失val_loss 曲线:

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

Figure 6 — Curves representing the validation loss and the loss of mean squared error through epochs.

该模型的 R2 分数为 0.9926,这代表了一个很好的结果。但是,我们不得不考虑到,数据是非常不平衡的,高分几乎完全是由于多数阶级造成的。预测值和实际值的比较如下所示:

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

Figure 7 — True and predicted RUL values.

将回归问题转化为分类问题

如前所述,通过选择目标的失效阈值,可以将 RUL 回归问题转化为分类问题。在这种情况下,每 2 分钟采集一次数据,因此在休息前选择 10 分钟的间隔(5 个样本)。检查图 8 中的性能。

y_test_class = df.y.reindex(y_test.index)
print(classification_report(y_test_class,rul_pred<=5,digits=3))
confusion_matrix(y_test_class,rul_pred<=5)

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

Figure 8— Classification report for a 10-minute failure threshold.

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

Figure 9— Confusion matrix for a 10-minute failure threshold.

故障阈值优化

之前选择了 10 分钟的故障阈值,但是在给定特定指标的情况下,我们如何找到最佳的故障阈值呢?首先,我们需要选择一个分数或指标来优化,对于这个问题,它是 F1 分数,它携带了关于精确度和召回分数的信息。

接下来,创建了一系列不同的故障阈值。我们选取了[1,30]个样本或[2 分钟,60 分钟]的间隔,并计算了每个值的 F1 值。

from sklearn.metrics import f1_scorefail_thresh = np.arange(1,31)f1_scores = np.array([])for ft in fail_thresh:
    f1_scores = np.append(f1_scores, round(f1_score(y_test_class,
                                                   rul_pred<=ft),4))

计算出每个给定阈值的 F1 分数后,我们通过用 f1_scores 数组绘制一个简单的图表,并确定曲线峰值的对应参数,找到了最大值。

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

Figure 10— Plotting the F1 scores to optimize the failure threshold value.

从图 10 所示的图中,我们可以看到最佳阈值是 3 个样本(或实际中断前 6 分钟)。完整的分类报告和混淆矩阵如下所示:

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

Figure 11— Classification report for a 6-minute failure threshold.

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

Figure 12— Confusion matrix for a 6-minute failure threshold.

从图 11 中的分类报告中,我们还可以看到少数民族类别的 f1 分数有所提高,大约为 2.88%。对于更大的数据集,行为可能会发生剧烈变化,优化过程将比针对该问题获得的改进百分比更重要。此外,f1 分数已经从 Chitta 文章的基准(f1 分数0.072)提高了248%,验证了用于 RUL 问题的方法。

使用类别权重的 LSTM 分类

在成功实现 RUL 回归模型之后,我们仍然可以尝试一种分类方法,通过将类权重寻址到 LSTM 来补偿类之间的不平衡。

为了实现分类问题,我们首先需要将中断指示器变量 y 设置为我们的目标,因为它最初是在问题表述中定义的。

用于该问题的 LSTM 拓扑与 RUL 回归方法相同(图 5),但由于其分类性质,现在使用不同的指标来编译模型。

model_class = Sequential()
model_class.add(LSTM(input_shape=(timesteps,len(features)), units=15, return_sequences=True))
model_class.add(Dropout(0.2))
model_class.add(LSTM(input_shape=(timesteps,len(features)), units=10, return_sequences=False))
model_class.add(Dropout(0.2))
model_class.add(Dense(units=1, activation = 'sigmoid'))
model_class.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())

用于拟合模型的参数如下所示:

model_path = 'lstm_model_classification.h5'
class_weight = {0: 1,
                1: 50} #2% are breaks ...history = model_class.fit(to_3D(x_train_lstm, features),
                          df['y'].reindex(y_train.index),  
                          epochs=1000, 
                          batch_size= 8, 
                          validation_split=0.2, 
                          verbose=1, 
                          class_weight=class_weight,
                          callbacks = [        
                             keras.callbacks
                                  .EarlyStopping(monitor='val_loss',
                                                        min_delta=0,
                                                       patience=200,
                                                          verbose=1,
                                                        mode='min'),                                                                                                               

                            keras.callbacks
                                  .ModelCheckpoint(model_path, 
                                           monitor='val_loss',
                                          save_best_only=True, 
                                                   mode='min',  
                                                   verbose=1)])

在这种情况下,将类权重应用于神经网络会通知模型:类 1 的 1 个实例(中断)表示类 0 的 50 个实例(无中断)。因此,模型将为少数类样本分配较高的值,将损失函数转换为加权平均值,其中样本权重在 class_weight 字典中指定。

评估分类模型

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

Figure 13- Curves representing the validation loss and the loss for the classification problem.

通过分析少数类的分类报告,我们可以看到 0.544 的出色 f1 得分结果,表明与之前的回归方法相比,模型性能提高了一倍以上。与上一份报告相比,精确度和召回分数也有所提高,这意味着该模型得到了充分优化,并且没有出现性能折衷。

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

Figure 14 — Classification report for the LSTM model using class weights.

模型之间的比较

为了进行方法比较,选择了四种不同的模型:来自 Chitta 文章的 LSTM 自动编码器模型、Roberto 的成对 Mahalanobis 距离模型、RUL 优化模型以及最后的类权重分类模型。用于比较模型的指标有:精确度、召回率和 f1 分数。

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

Figure 15 — Evaluating the models with different classification metrics.

我们可以在上面的柱状图中看到,Mahalanobis 距离模型在其他模型中脱颖而出,表现出最高的 f1 分数和精确度。同时,类权重模型在分析召回(敏感度)分值时克服了。

为了更好地理解用于评估模型的分类度量,我推荐阅读下面的文章:(链接)。

结论

Web 中断检测是一个非常复杂的问题,主要是因为类之间的不平衡、特征的质量以及收集的数据量。从这个意义上来说,这两个模型,从这篇文章和之前引用的文章,在分类一个真正的造纸厂的断纸方面做了非常好的工作。

RUL 回归模型仍然可以通过微调参数和收集更多数据来优化。还可以通过为每个类别选择最佳权重来改进类别权重模型。当然,为罕见事件检测选择正确的模型是困难的,并且性能可能会根据问题的性质以及数据的大小和质量而变化。考虑到本文中分析的方法,如果目标是实现高精度,最合适的模型是使用 Mahalanobis 距离的模型,但是如果目标是获得高灵敏度,则类权重模型是最佳选择。

RUL 和重量级模型表现出色,f1 值分别为 0.25 和 0.54。它们不仅可以用于 web 中断预测,还可以用于任何罕见的事件检测问题。

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

Figure 16 — Image used on the story preview of this article [Source: https://pxhere.com/en/photo/1558069?utm_content=shareClip&utm_medium=referral&utm_source=pxhere]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值