TowardsDataScience 博客中文翻译 2021(二百九十)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

通过人工智能驱动的内容营销寻找客户

原文:https://towardsdatascience.com/finding-customers-through-ai-powered-content-marketing-fcd294ec1667?source=collection_archive---------47-----------------------

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

[图像归属](https://pixabay.com/users/kevinking-289243/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=424521">Kevin King(Chandana Perera) from <a href="https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=424521)

有些事情看似显而易见,但当你问一个具体的问题时,却得不到明确的答案。其中一个问题是如何利用互联网做生意。我在咨询有关使用人工智能改善业务功能时提出了这个问题,大多数答案充其量是“模糊的”。

在深入本文的主题之前,让我们定义一个非详尽的使用互联网进行商业活动的方式列表,而不考虑行业或商业活动类型(例如,从创业到医疗保健实践)。)

利用互联网做生意的方法

电子商务
【客户访问网站,订购产品,通过支付网关付款,商品送货上门。

公司网站
·提供知名度、宣传、品牌、新闻、财务结果、支持等

软件即服务(订阅)
CRM
供应商和员工管理
组织、信息和沟通

市场调查
【新产品潜力、竞争对手、标准、产品评论

云托管
【外包 IT 需求】

广告
销售广告:新闻&社交媒体(如 NYT、脸书、推特、LinkedIn)
通过广告销售:内容营销(如博客、medium.com、影响者)

进一步分析这个概念,我们看到它不是一维的。如果考虑实施模式,则该概念最好在 3d 空间中建模。因此,这三个维度是网络、移动和即将到来的增强虚拟现实 IOT,反映了不同的交付和交互模式(见下图)

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

三维空间

在上述范围内,我们将重点关注内容营销

什么是内容营销
内容营销是一种营销方式,专注于持续创造和分享有价值的、高度相关的内容,以吸引和保留明确定义的受众,从而推动有利可图的客户行动。

没有人喜欢被直接卖给。无论是在数字上被追逐为“线索”或“潜在客户”,还是走进一家商店并被“我能帮什么忙”(翻译为“你不能只是浏览,你必须买些东西”)所困扰,它都没有很好的效果。

任何企业、服务或实践都需要能够快速回答的问题是“你如何找到客户?”。作为一个企业主,如果答案是“毫无头绪,事情就这么发生了”,那么至少还有显著改善的空间。通常的答案是“广告”,然后的问题是如何,在哪里和多少。

高效、有影响力的广告需要给广告“消费者”带来价值。如果一个广告要在寻找顾客或至少诱导顾客购买方面起作用,它需要对所花费的注意力有所回报。一个恼人的广告充其量只是不起作用,但在许多情况下会对品牌有害(以及成本影响)。

随着部分“生锈”的销售机制释放出被压抑的需求,在新冠肺炎危机爆发的一年内通过接种疫苗进行控制的可能性将导致增长反弹。因此,需求和购买的需要是存在的,企业需要为这个机会做好准备,部分是通过重新评估他们的销售业务。

广告类型和提供的价值
专注于任何营销传播中所需的附加值,一些广告的幽默内容提供了这种价值(见下文)。

其他人提供教育,而其他人则伪装成提供一些娱乐的文章,例如“申请世界上最好的工作”,实际上只是宣传一个加勒比海岛屿,或者“她错误地使用“xyz”消息平台向她的老板发送了一条 x 级消息”。

但是最强大的,有机的客户获取方法是内容营销。

与许多人可能相信的相反,网络和当前的技术并没有产生这个概念。内容营销至少从上个世纪就已经存在了。最近发生的变化是可访问性大大增强。

这同样适用于“免费增值”商业模式(“免费”和“溢价”是一种定价策略,通过这种策略,免费提供基本产品或服务,但金钱(溢价)是用于附加功能或服务)。

在讨论内容营销的未来之前,下面描述了一些有意义的历史例子来说明上述观点。

内容营销—约翰迪尔
1895 年,约翰迪尔开始出版一本名为《犁沟》的杂志,旨在教育农民如何有效地管理他们的作物。它是免费的,没有推广 John Deere 产品。当时没有电视、广播或互联网,但印刷机技术刚刚起步,并在世界各地被用于创作和接触观众。

不涉及销售,但通过向普通农民和牧场主提供这些内容,John Deere 成为了思想领袖,并使用内容营销将农业与品牌联系起来。《犁沟》现在在 40 多个国家以 12 种语言出版,完全在线,相关内容通过社交媒体渠道发布。这种内容营销方法使 John Deere 成为农业的同义词。

内容营销——米其林
“米其林指南”创作于 1900 年左右,是一本免费的车主指南(当时车主很少),教育他们如何使用和保养车辆。作为轮胎生产商,米其林并不关注轮胎,而是希望建立一个受众群体,为他们提供免费的旅行建议。这包括如何处理磨损、地图、如何换轮胎的信息、哪里可以找到汽油等等。汽车使用得越多,对新轮胎的需求就越大。

免费增值模式——杰克·丹尼尔的
1884 年,19 岁的杰克·丹尼尔买下了一家酒厂,开始了自己的威士忌生产。作为一名营销天才,他在几个月内建立了这个品牌,在整个田纳西州的销售中排名第二。他是第一批在瓶子上印上商标的人之一,并很快意识到把瓶子做成黑色和方形能使他的产品与众不同。

至少在 20 世纪 50 年代之前,杰克·丹尼尔(Jack Daniel)有意识地保持供应小于需求,将“稀缺”作为一种销售策略。他使用一种混合的“免费增值”模式来推广自己的品牌,创建了一个乐队,名为“杰克丹尼尔原创银短号乐队”,在当地一家酒吧免费演奏音乐,并与老板达成协议,将他的威士忌卖给他的客户。

人工智能驱动的内容营销人工智能驱动的内容可以改变任何企业的游戏规则。无论您想要理解您的数据,实现内容创作还是个性化内容,AI 都有能力提供帮助。

AI 在内容营销中是如何运用的
我们来探讨一下 AI 目前在内容营销中运用的最流行的方式。

1。基于对客户需求理解的个性化内容(包括电子邮件)更有可能作为间接的购买建议产生影响。

个性化内容必须写得很好,具有良好的视觉效果,必须提供真正的附加值。

满足并超越观众的期望能创造持久的纽带,让顾客的需求得到关注。

人工智能的最新进展使得内容个性化变得有效可行。机器学习有助于跟踪消费者的行为、偏好以及他们与内容的互动。这可以走得更远,一些人工智能系统使用多种数据源提供实时全面的访客资料。

2。预测分析
预测分析使用机器学习模型来预测未来事件。与内容营销相关的此类模型的示例有:

聚类模型
聚类是一种涉及数据点分组的机器学习技术。这些算法可以用于基于过去的品牌参与、过去的购买和人口统计数据的受众细分。

推荐模型
推荐系统是一类向用户提供个性化建议的机器学习算法。这些模型分为协作过滤和基于内容两类,帮助用户发现新产品和新服务,引导他们找到最有可能购买的产品。

倾向模型
这些模型试图预测访问者和客户采取某些行动的可能性,如对报价采取行动或退出。

3。客户细分客户细分是一种将客户划分为具有不同需求的不同群体的方式。K-means 聚类是一种流行的无监督机器学习算法,它可以找到不同的“聚类”(组),使它们尽可能小。目标是创建尽可能多的不同组。

然后,可以根据客户群的概况(例如,如何联系他们,通过邮件或短信等)对客户群进行不同的称呼。

上面描述的三种方法是最常用的,但是在营销中使用人工智能还有很多方法,包括:

媒体购买优化
对话式人工智能(聊天机器人)
增强和虚拟现实
面部识别
生物识别

通过网络、电子邮件和社交媒体,内容营销是获得客户的一种强有力的方法。但是,内容的创建和管理是一项重要的任务。

为了帮助这一点,各种人工智能技术可以并且正在被使用,如上所述。

内容营销的概念可以通过实际创建一个利基社交媒体平台来进一步发展,通过这个平台来创造观众和分享个性化的内容。

关于作者

尼古拉·费科斯

https://www.fortuitapps.com

使用 Python 查找重复图像

原文:https://towardsdatascience.com/finding-duplicate-images-with-python-71c04ec8051?source=collection_archive---------4-----------------------

在您的计算机上自动搜索重复图像

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

图片由 KissCC0 提供。

你有没有发现自己在经历过数百张,甚至数千张的图像后,才发现有些其实看起来有点太像?它们会是复制品吗?然后你可能检查了两个图像分辨率,然后删除了最低的一个。

我多次发现自己处于这种情况。很痛苦,很费时间,很累。特别是,如上所述,如果你必须通过成千上万的图像。此外,有些图像乍一看可能很容易被归类为重复的,但有些图像可能需要精确检查,也可能导致您删除图像,而实际上并没有重复。

那时我想:让我们自动化这个过程。

在今天的文章中,我将介绍为自动搜索本地计算机上文件夹中的重复图像编写一个 Python 3.8 脚本的过程。

GitHubPyPi**上查看 difPy 项目。**🎉

1 |理论上:将图像转换为数字数据

为了将图像相互比较,我们需要以某种方式将它们转换成可比较的、计算机可读的数据。你们中熟悉机器学习和计算机视觉的人可能已经知道,图像可以被转化为矩阵,或者更准确地说,转化为张量。一个张量是一个可以保存 n 维数据的容器。因此,矩阵是一个二维张量。

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

图片由 Mukesh Mithrakumar 从开发到

彩色图像中的每一个像素都可以用红色绿色蓝色的组合来表示。这三种颜色组成了这个像素的独特颜色。

如果我们有一个红色矩阵,一个绿色矩阵和一个蓝色矩阵来代表图像中的所有像素,我们可以将这三个矩阵相互叠加,最终得到一个张量。🎉

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

来自 Slideshare.net 的伯尔顿·恩肖的图片

这太棒了,因为这意味着我们可以用数字来表示我们的图像。现在应该已经敲响了警钟:数字很容易相互比较。假设一幅图像和另一幅图像由完全相同的张量组成,我们可以得出结论:这些是复制品!

很好,现在让我们继续,看看我们如何将理论应用于实践。

2 |实践:将图像转换为数字数据

让我们首先导入我们将用于这个脚本的 Python 库: skimagematplotlibnumpyopenCVosimghdr

我们将从编写函数 *create_imgs_matrix 开始。*这是我们的最后一个函数,但是您可以随意查看下面代码的详细解释:

该函数将为我们的算法在特定文件夹中找到的每幅图像创建一个张量。我们读入我们的计算机目录,遍历所有的文件,并确保我们的文件夹中的文件格式实际上是图像(即 JPG,PNG 等。).有一个非常方便的库叫做 imghdr 可以在这个过程中帮助我们。

我们首先检查文件是否可以通过以下方式访问:

os.path.isdir(directory + filename)

然后我们检查它是否是一个图像:

imghdr.what(directory + filename)

如果它不是一个图像,这个函数将返回 None ,并因此移动到目录中的下一个文件。如果两个输出都有效,该函数将继续下一行,在这里我们使用 opencv 库来解码我们的图像文件并将其转换为张量:

img = cv2.imdecode(np.fromfile(directory + filename, dtype=np.uint8), cv2.IMREAD_UNCHANGED)

然后,我们检查它是否已经成功地转换为一个 n 维数组,并确保我们的张量最多有 3 层。

在我们的最后一步,我们调整我们的图像张量的像素大小为 50,也就是说,我们希望它的像素宽度和高度为 50。我们这样做是为了加快图像的比较过程。如果我们有高分辨率图像,它们各自的张量也将非常大,因此导致与其他图像张量相比,一对一比较的计算时间更长。

最后,我们将调整后的张量添加到我们的 imgs_matrix 列表中,并继续处理我们目录中的下一个文件(如果存在的话)。

酷——在我们写完这个函数之后,我们得到了目录中所有图像的张量列表。现在,我们如何比较这些呢?为此,我们将使用一个名为 MSE 的指标。

图像相似性的 3 | MSE(均方误差)

统计领域经常使用 MSE均方误差 T5。对于我们的用例,我们将使用它来比较两幅图像的相似程度。

两幅图像之间的均方误差是两幅图像之间的平方差之和。误差越小,图像越“相似”。

MSE 计算如下:

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

图片来自维基百科

我不会详细介绍这个公式的作用,而是让我给你一个 Python 代码中的等价形式:

这个函数计算 imageA 和 imageB 之间的 MSE,并将返回一个浮点值,我们可以将它解释为这些图像之间的相似性。这个数字越低,这些图像越相似。

4 |查找重复项的最后提示和注意事项

在进入最后一章之前,让我给你一些我在这个项目中学到的技巧和思考。

A.选择什么目标 MSE?

因为我们寻找的是重复的图像,而不仅仅是相似的图像,我们可以假设 MSE 为 0 是我们确信图像是重复的目标吗?

总的来说,是的。但是在我们的例子中:还记得我们将图像的尺寸调整为 50 像素宽 x 50 像素高吗?这可能会导致给出具有不同初始分辨率或大小的图像的略微不同的张量。当我自己编写这个函数时,我看到一些确实是重复的图像,不知何故没有导致 MSE 为 0。因此,更好的做法是将我们的 MSE 阈值设置得高一点,这样我们就可以确保捕捉到所有重复的图像,即使没有完全相同的张量。

对于这个用例,我选择 200 的 MSE 作为最大阈值**。一旦两个图像的 MSE 低于 200,我们就认为它们是重复的。**

B.那些旋转的图像是怎么回事?

这也是我写完第一个初始函数后才意识到的。当然,根据我们的图像旋转,我们的图像的张量会看起来不同。因此,我们需要确保将我们的图像与第二幅图像的所有可能的旋转进行比较。

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

图片来自 KissCC0 由作者修改

借助内置的 rot90 函数,numpy 库可以让我们轻松地执行这个操作,这个函数可以将矩阵旋转 90 度。

C.比较图像分辨率

当然,除了寻找重复,我们还希望我们的算法帮助我们决定哪些可以删除。因此,我们希望比较图像的原始分辨率,并让我们的算法输出最低的文件名。

我们将通过使用 os.stat st_size 函数来完成这项工作,该函数将输出文件大小。具有较小大小的文件将被添加到单独的列表中。

5 |将所有这些放在一起

首先,祝贺你一直坚持到现在,并走了这么远。我们到了最后一章,我们将把所有的东西放在一起!

总结我们的步骤:

  1. 计算文件夹中所有图像的图像张量。
  2. 逐一检查所有图像张量并计算它们的 MSE。在此过程中,我们确保将图像旋转 90 度,这样即使这些图像没有相同的初始方向,我们也可以找到重复的图像。
  3. 如果我们的两个图像的 MSE< 200, classify them as duplicates.
  4. Check the file size of the original two files. The one having the lower size will be added to a list of images that can be deleted.

Instead of pasting the full code here, I will share with you the link to my GitHub 库,我已经上传了完全复制图像查找器(DIF)脚本

https://github.com/elisemercury/Duplicate-Image-Finder

*** | 2021 年 10 月更新**

DIF 现在也可以作为 Python 包 difPy 供您通过 pip 安装程序进行安装。

https://pypi.org/project/difPy/

您现在可以只使用pip install difPy并如下使用该库:

我希望这篇文章对您有所帮助,并且可以帮助您节省一些宝贵的图像比较和重复数据删除时间!至少对我个人来说是这样的。😜

如果您有任何问题或反馈,请随时联系我,或者在下面发表评论,让我知道您的想法。

参考资料:

[1] A. Rosebrock,如何:Python 比较两幅图像 (2014)

[2] J. Brownlee,用 NumPy 对用于机器学习的张量的温和介绍(2018)

在影像分类数据集中查找硬样本

原文:https://towardsdatascience.com/finding-hard-samples-in-your-image-classification-dataset-32d195b7ee52?source=collection_archive---------14-----------------------

挖掘硬样本是改进机器学习数据集的有效方法,本指南将向您展示如何自己去做

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

蒂姆·福斯特在 Unsplash 上的照片

假设你有一个数据仓库,里面有数百万张未标记的图片。您成功地标记了数据的子集,并在其上训练了图像分类模型,但它的表现不如您希望的那样好。你如何决定给哪些新样本添加注释并添加到你的训练集中?

您可以随机选择新的样本进行注释,但是有一个更好的方法。硬样本挖掘是一种屡试不爽的方法,可以将大量未标记的原始数据提取为更小的高质量标记数据集。

硬样本是指你的机器学习(ML)模型发现很难正确预测标签的样本。

在影像分类数据集中,硬样本可以是任何东西,从看起来像狗的猫到分辨率模糊的影像。如果您希望您的模型在这些硬样本上表现良好,那么您可能需要“挖掘”这些硬样本的更多示例,以添加到您的训练数据集中。在训练期间将您的模型暴露于更硬的样本将允许它在以后对这些类型的样本执行得更好。

硬样本不仅对训练数据有用,还必须包含在测试集中。如果您的测试数据主要由简单的样本组成,那么您的性能将很快达到上限,导致进度停滞。将硬样本添加到测试集将使您更好地了解模型在硬边缘情况下的表现,并可以更深入地了解哪些模型更可靠。

使用这款 Colab 笔记本,跟随您的浏览器!

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

这个演练在 Colab 中运行 (ipynb 链接在此)(图片由作者提供)

概观

这篇文章将带你了解如何使用我正在开发的新的开源 ML 工具 FiftyOne ,在你的数据集中寻找硬样本。为了使本演练易于理解,我们将使用现有的模型和数据集。即 ResNet50 在 CIFAR-10 数据集测试分裂中寻找硬样本。

它将指导您如何:

  • 将您的图像数据集加载到51
  • 将预训练网络中的逻辑添加到数据集中
  • 使用五十一计算每个样品的硬度
  • 探索您的数据集,找到最难和最容易的样本

设置

本演练将使用 GitHub 上的 PyTorchfiftone以及 PyTorch_CIFAR10 的模型。PyTorch 和 FiftyOne 的安装说明很简单:

pip install torch torchvision
pip install fiftyone

加载您的数据

对于本例,我们将使用影像分类数据集的测试分割, CIFAR-10 。该数据集包含 10,000 个测试图像,标记了 10 个不同的类别。这是51 数据集动物园中的几十个数据集之一,所以我们可以很容易地加载它。

我们可以使用 FiftyOne App 来看看这个数据集。

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

CIFAR-10 和地面真相标签在51 应用中可视化(图片由作者提供)

:也可以将自己的数据集加载到五十一中。它支持许多计算机视觉任务的标签,包括分类检测分割关键点更多。例如,如果数据集包含存储在每个类的目录中的图像,可以使用下面的代码来加载它。

添加逻辑

为了计算第五十一张图像的硬度,你首先需要使用一个模型来计算这些图像的对数。您可以使用任何您想要的模型,但理想情况下,它将是一个经过训练的类似数据,并且在相同的任务中,您将使用这些新图像。

在本例中,我们将使用来自 PyTorch CIFAR-10 库的代码,即预训练的 ResNet50 分类器。

# Download the software
git clone --depth 1 --branch v2.1 https://github.com/huyvnphan/PyTorch_CIFAR10.git

# Download the pretrained model (90MB)
eta gdrive download --public \
    1dGfpeFK_QG0kV-U6QDHMX2EOGXPqaNzu \
    PyTorch_CIFAR10/cifar10_models/state_dicts/resnet50.pt

您可以轻松地将带有逻辑的分类字段添加到 51 个数据集中的样本中。

计算硬度

第五十一个大脑包含了各种有用的方法,可以让你深入了解数据。此刻,你可以计算出你的数据的唯一性,最难的样本,以及注释的错误。这些都是在数据集上生成标量指标的不同方法,可让您更好地了解现有数据的质量,并选择高质量的新数据样本。

加载数据集并将 logits 添加到样品后,您可以在一行代码中计算硬度。硬度算法是闭源的,但基本思想是利用模型预测的相对不确定性,为每个样本分配一个标量硬度值。

探索和识别最难的样本

您可以使用 FiftyOne 应用程序可视化您的数据集,并探索硬度最高和最低的样品。

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

数据集排序以显示最难的样本(按作者排序的图像)

虽然这个例子使用的是 CIFAR-10 的小图像,但 FiftyOne 也可以处理高分辨率图像和视频。

我们可以编写一些查询来更深入地挖掘这些硬度计算,以及它们如何与数据的其他方面相关联。例如,我们可以分别在模型的正确和错误预测上看到硬度的分布。

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

正确和错误预测样品的硬度分布(图片由作者提供)

如您所料,上图显示正确预测的硬度分布偏向较低的硬度值,而不正确的预测在高硬度值时分布更均匀。这表明模型预测不正确的样本往往是更难的样本。因此,向训练集添加更难的样本应该会提高模型性能。

我们还可以看到样品的硬度如何分布在不同的类别中。

Average classwise hardness

cat: 0.703082
dog: 0.628436
airplane: 0.591202
bird: 0.588827
frog: 0.577954
truck: 0.573330
horse: 0.564832
deer: 0.561707
automobile: 0.554695
ship: 0.553041

看起来猫和狗是最难的职业,所以在其他职业之前添加更多的例子是值得的。

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

分类准确度与硬度(图片由作者提供)

我们可以看到,一个类中样本的平均硬度与该类上模型的精度存在反相关关系。

我们来看看最难类“猫”的错误预测样本。

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

最难的错误预测样本最难的类别“猫”(图片由作者提供)

现在让我们来看看硬度最低的猫的正确预测图像。

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

最难正确预测最难类别“猫”的样本(图片由作者提供)

将最难预测错误的猫图像与最容易预测正确的猫图像进行比较,我们可以看到,该模型在对直视相机的猫面部图像进行分类时要容易得多。模特最难处理的猫的图像是那些光线不好、背景复杂的猫的图像,以及它们没有坐着面对摄像机的姿势。现在,我们对添加到这个数据集中的猫图像的类型有了一个概念。

下一步是什么?

这个例子是在一个先前注释过的数据集上完成的,目的是展示硬度与数据集的其他方面的关系。在现实世界的应用程序中,您现在可以将此方法应用于新的未标记数据。

一旦确定了可用的最难样本,就该更新数据集了。您可以选择硬度值最高的 X 个样本发送出去,进行注释并添加到您的训练或测试集中。或者,您可以根据上面计算的每个等级的硬度按比例选择样本。

根据这些新数据重新训练你的模型现在应该可以让它在更困难的情况下表现得更好(我正在写一篇后续博文来展示这一点)。此外,如果模型在测试集上表现良好,将这些样本添加到测试集将使您对模型在新的未知数据上表现良好的能力更有信心。

使用 NMF 在数据中寻找模式

原文:https://towardsdatascience.com/finding-pattern-in-data-using-nmf-7b119555cb41?source=collection_archive---------7-----------------------

使用 Ecco 对文本数据进行非负矩阵分解

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

使用 EECO 的 NMF 可视化(来源:作者)

自然语言处理是人工智能领域最热门的话题之一。它有助于构建聊天机器人、语音助手、情感分析、推荐引擎等应用。这是一个新兴领域,大多数相关公司都在投资和研究创造下一代语音助手。

自然语言处理最重要的算法之一是主题建模,它有助于描述文本数据集中的数量趋势,并找出数据集的概要特征。换句话说,这是一种特征工程,我们在数据集中找出最重要的特征。

NMF 是一种无监督的主题建模技术,其中没有提供训练数据或数据标签。它将高维数据分解为低维表示。

Ecco 是一个开源的 Python 库,它提供了使用交互式可视化来探索和解释 NLP 模型的多种功能。

在本文中,我们将使用 Ecco 来执行 NMF,并为其创建一个交互式可视化。

让我们开始吧…

安装所需的库

我们将从使用 pip 安装 Ecco 开始。下面给出的命令可以做到这一点。

pip install ecco

导入所需的库

在这一步中,我们将导入所需的库和函数来创建 NMF 可视化。我们还将从 eeco 加载预训练的 Bert 模型。

import ecco
lm = ecco.from_pretrained('bert-base-uncased', activations=True)

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

加载预训练模型(来源:作者)

对文本进行标记

在这一步中,我们将对用于 NMF 可视化的数据进行符号化。你可以用任何你想要的文字,我正在写一篇关于萨钦·坦杜尔卡尔的文章。

text = ''' Sachin Tendulkar has been the most complete batsman of his time, the most prolific runmaker of all time, and arguably the biggest cricket icon the game has ever known. His batting was based on the purest principles: perfect balance, economy of movement, precision in stroke-making, and that intangible quality given only to geniuses - anticipation. If he didn't have a signature stroke - the upright, back-foot punch comes close - it's because he was equally proficient at each of the full range of orthodox shots (and plenty of improvised ones as well) and can pull them out at will.There were no apparent weaknesses in Tendulkar's game. He could score all around the wicket, off both front foot and back, could tune his technique to suit every condition, temper his game to suit every situation, and made runs in all parts of the world in all conditions.Some of his finest performances came against Australia, the overwhelmingly dominant team of his era. His century as a 19-year-old on a lightning-fast pitch at the WACA is considered one of the best innings ever to have been played in Australia. A few years later he received the ultimate compliment from the ultimate batsman: Don Bradman confided to his wife that Tendulkar reminded him of himself.Blessed with the keenest of cricket minds, and armed with a loathing for losing, Tendulkar set about doing what it took to become one of the best batsmen in the world. His greatness was established early: he was only 16 when he made his Test debut. He was hit on the mouth by Waqar Younis but continued to bat, in a blood-soaked shirt. His first Test hundred, a match-saving one at Old Trafford, came when he was 17, and he had 16 Test hundreds before he turned 25\. In 2000 he became the first batsman to have scored 50 international hundreds, in 2008 he passed Brian Lara as the leading Test run-scorer, and in the years after, he went past 13,000 Test runs 30,000 international runs, and 50 Test hundreds. '''
inputs = lm.tokenizer([text], return_tensors="pt")
output = lm(inputs)

使用 NMF 和 EECO 分解文本

这是最后一步,我们将创建 NMF 的可视化,我们将使用两种类型的因式分解,即所有层的因式分解和第一层的因式分解。

#All layers
nmf_1 = output.run_nmf(n_components=10)
nmf_1.explore()

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

NMF 所有层(来源:作者)

#First Layer
nmf_2 = output.run_nmf(n_components=8, from_layer=0, to_layer=1)
nmf_2.explore()

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

第一层 NMF(来源:作者)

在这里,我们可以清楚地看到只用一行代码创建的 NMF 可视化效果。这些可视化是互动的,高度可解释的。我们可以清楚地分析 NMF 在可视化中的不同主题和权重。

继续尝试不同的数据集,并创建美丽的可视化。如果您发现任何困难,请在回复部分告诉我。

本文是与 Piyush Ingale 合作完成的。

在你走之前

感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 。可以查看我的Github简介针对不同的数据科学项目和包教程。还有,随意探索 我的简介 ,阅读我写过的与数据科学相关的不同文章。

为您的数据科学项目查找卫星图像

原文:https://towardsdatascience.com/finding-satellite-images-for-your-data-science-project-888695361925?source=collection_archive---------28-----------------------

Sentinel Hub,为您的数据科学项目提供卫星图像的最佳资源之一

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

托拜厄斯Unsplash 拍摄的照片

如今,你可以用卫星图像做很多事情,无论是在你的地理分析系统中使用,还是在 R/Python 或任何其他编程语言上帮助你进行统计分析。

你将(也应该)问自己的第一个问题是:我在哪里可以找到这些卫星图像?这个问题的答案就在这里。我将向您展示您可以从世界任何地方找到高质量卫星图像的最佳资源。

接下来,我将展示如何从特定区域获取这些图像。我会选择波尔图——葡萄牙🇵🇹的一座美丽的海滨城市,作为我的工作区域,因为那是我居住的地方。IMO 获取卫星图像的最佳来源是:

**https://apps.sentinel-hub.com/eo-browser/

  1. 注册一个账户,简单快捷。使用最近创建的帐户登录,您将看到以下屏幕:

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

2.缩小地图,将地图移动到您希望获取卫星图像的位置。点击“搜索”,你会看到覆盖你所选区域的所有图片。

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

3.选择最适合你的图像,例如,云层最少的图像通常最适合进行任何类型的分析。当你找到你喜欢的,点击此按钮进入下载链接:

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

点击第二个链接开始下载。它将打开一个新的页面,并要求用户和密码。这和你几分钟前登录网站用的信息是一样的。输入用户和密码,下载将立即开始。

仅此而已。几分钟后,您将获得所需的卫星图像,并可以在您选择的软件中打开它们,无论是 SNAP、ArcGIS、RStudio 还是任何其他您想要的软件。

Sentinel Hub 的其他一些功能和注意事项

  • 你也可以选择从另一颗卫星上获取图像。Landsat 是另一个非常受欢迎的获取图像的选择(这里也有)

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

  • 日期过滤器将允许您选择一个月或一段时间:

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

您可以直接在 Sentinel Hub 的界面上使用地图,进行如下操作:

  • 放置标记,测量距离:

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

  • 计算面积:

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

还可以用你选择的地图制作延时视频或动画。

最后的想法

这就是你需要了解的关于哨兵枢纽的基本知识。我相信这是为您的数据科学项目下载卫星图像的最佳资源之一。

查看一些由阿卜迪沙库尔阿德里安·塞拉皮奥阿努巴夫·帕特奈克撰写的关于地理空间分析的好文章,为你的下一个项目提供灵感:

一有机会就去看看 Sentinel Hub,找到你需要的图片,在评论区让我知道你的想法!**

用 Python 在时间序列数据中发现季节性趋势

原文:https://towardsdatascience.com/finding-seasonal-trends-in-time-series-data-with-python-ce10c37aa861?source=collection_archive---------1-----------------------

理解不同种类的季节性以及如何将时间序列分解为趋势和季节的指南

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

照片由来自佩克斯克雷格·阿德利拍摄

为什么要探索季节性?

时间序列数据中的季节性指的是以固定间隔发生的模式。这不同于有规律的周期性趋势,如股票价格的上涨和下跌,这些趋势有规律地重复出现,但没有固定的周期。从了解数据中的季节性模式中可以获得很多洞察力,甚至可以将其用作比较时间序列机器学习模型的基线。

入门

快速提示:在这篇文章中,我将使用魁北克房地产经纪人专业协会发布的数据。该协会每月发布房地产统计数据。为了方便起见,我将魁北克省和蒙特利尔大都会区的每月公寓价格中值放入一个 CSV 文件中,可在此处获得:https://drive . Google . com/file/d/1 smrkzpaa 0 AAL-zhnllfbmdgymtxgpab/view?usp =共享

了解数据是否有季节性趋势的最快方法是绘制图表。让我们看看当我们按月绘制蒙特利尔的房价中值时会得到什么。

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

作者图片

敏锐的眼睛可能已经从这幅图中看出,价格似乎在新年前后下降,并在几个月前夏末左右达到峰值。让我们通过为每年的一月画一条垂直线来更深入地了解这一点。

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

作者图片

看起来这绝对是一种趋势。在这种情况下,季节性似乎有一年的周期。接下来,我们将研究一个工具,我们可以使用它来进一步检查季节性,并将我们的时间序列分解为趋势、季节性和剩余部分。不过,在我们这样做之前,你必须了解加性和倍增性季节性之间的区别。

加法与乘法季节性

在分析时间序列数据时,您可能会遇到两种季节性。为了理解它们之间的区别,让我们看一个具有完美季节性的标准时间序列,一个余弦波:

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

正弦波图— 作者图片

我们可以清楚地看到,波浪的周期为 20,振幅(从中心线到波峰顶部或波谷底部的距离)为 1,并且保持不变。

附加季节性

实际时间序列很少具有恒定的波峰和波谷值,相反,我们通常会看到某种总体趋势,如随着时间的推移而增加或减少。例如,在我们的销售价格图中,中间价格往往会随着时间的推移而上升。

如果我们的季节性幅度保持不变,那么我们就有了所谓的附加季节性。下面是一个附加季节性的例子。

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

附加季节性— 作者图片

一个很好的思考方式是,想象我们用标准余弦波,简单地给它添加一个趋势:

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

作者图片

我们甚至可以把之前的基本余弦模型想象成一个趋势不变的加性模型!我们可以使用下面的简单等式来模拟加性时间序列:

Y[t] = T[t] + S[t] + e[t]

Y[t]:我们的时间序列函数
T[t]:趋势(向上或向下移动的总体趋势)
S[t】:季节性(定期出现的循环模式)
e[t]:残差(趋势或季节性中没有考虑的数据中的随机噪声

倍增季节性

您可能在时间序列数据中遇到的另一种季节性是倍增性的。在这种类型中,我们季节性的幅度根据趋势变大或变小。下面是一个倍增季节性的例子。

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

倍增的季节性— 作者图片

我们可以采用与加法模型类似的思路,想象我们采用余弦波,但不是将趋势相加,而是将其相乘(因此得名乘法季节性):

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

倍增的季节性— 作者图片

我们可以用一个类似于加法模型的等式来建模,只需将加法换成乘法。

Y[t] = T[t] *S[t] *e[t]

分解数据集

现在我们已经对不同的模型有了一个清晰的了解,让我们看看如何将我们的房地产时间序列分解成它的趋势、季节性和剩余部分。我们将使用 statsmodels 库中的季节性分解模型。

季节性分解模型要求您选择季节性的模型类型(加法或乘法)。我们将选择乘法模型,因为看起来周期的幅度随着时间而增加。这是有道理的,因为影响房价的一个重要因素是贷款利率,贷款利率是房价的一个百分比。

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

作者图片

哒哒!趋势、季节和残差分量作为 Pandas 系列返回,因此您可以通过调用它们的 plot()方法来绘制它们,或者对它们执行进一步的分析。可能有用的一件事是衡量它们与外部因素的相关性。例如,您可以测量趋势和抵押贷款利率之间的相关性,或者您可以查看残差和城市新生儿数量之间是否有很强的相关性。

结论

从我们的分解中,我们可以看到这个模型在季节之间获得了 5%的差异。如果你想卖掉你的房子,如果你想卖个好价钱,你应该在春末而不是仲冬上市。

寻找与网络分析的协同作用

原文:https://towardsdatascience.com/finding-synergies-with-network-analysis-using-neo4j-to-identify-the-best-pokémon-teams-4ff89e791671?source=collection_archive---------31-----------------------

使用 Neo4J 确定最佳神奇宝贝团队

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

作者图片

在本文中,我们…

使用网络分析来确定在竞争游戏中哪些人是彼此的最佳队友。

讨论衡量团队绩效和队友合作的指标。

解释从 JSON 导入数据和使用 Neo4J 执行社区检测。

标签:Neo4J,CYPHER,JSON,Pokémon,Smogon。

摘要

Smogon.com 是一个在线竞技神奇宝贝战斗的平台,它每月发布一份关于比赛数据的 JSON。这是关于电子竞技中玩家行为的大量数据,让我们能够分析竞争对手如何制定策略。在这篇文章中,我们探讨了以下问题:“我能挑选的最好的团队是什么?”一个团队由六只神奇宝贝组成。为了回答这个问题,我们从普通玩家和高排名玩家的比赛中提取数据,并比较这两个群体如何不同地选择团队。因此,我们确定了高成就玩家倾向于选择的神奇宝贝集群。虽然没有一个“最佳”团队,因为每个策略都有一个反策略,但我们可以确定高绩效球员如何选择他们的团队,我们可以确定当前竞争环境中的顶级团队。

介绍

术语“元游戏”的意思是“关于游戏的游戏”,它指的是任何类型的游戏中的竞争者如何做出战略选择,以赢得一系列比赛。这方面的例子包括大联盟棒球俱乐部如何为一个赛季挑选他们的球队,或者教练如何计划他们球队的训练制度。在每种情况下,目标都不是赢得一场比赛,而是赢得一系列比赛。

电子竞技是探索元游戏的沃土,因为它们发生在数字空间,这意味着通过正确的工具,我们可以提取游戏中发生的几乎任何事情的数据。

电子竞技的另一个有趣的特点是,游戏的开发者可以而且确实会积极干预游戏的参数,以优化游戏的“平衡”这里的“平衡”是指在一场竞争性比赛中,某些策略可能比其他策略更好。‘失衡’的结果是一个非常无聊的竞技游戏,在这里只有少数策略是可行的选项。玩家和粉丝希望游戏中有各种有趣的策略可以使用,并对抗这些策略。当游戏平衡时,就有多样性和有趣的各种比赛可以享受。

在分析元博弈时,我们可以检查可行策略的多样性,并分析玩家如何达到这些策略。从这个分析中,我们可以回答诸如“在元博弈的当前状态下,什么是最佳策略选择?”

在本文中,我们探讨了关于 Smogon.com 的元游戏的两个问题:

考察成功的球员如何选择不同于一般球员的球队。我们假设游戏中表现最好的玩家选择的队伍是“最好”的队伍。

与 2015 年相比,2020 年的高技能玩家选择团队的方式有所不同,当时 Smogon.com 以不同的方式“平衡”了元游戏。

数据

在本文中,我们使用 Smogon.com 管理的“神奇宝贝对决”的数据,通过网络分析展示了元游戏分析。

我们的目标是创建一系列网络图,其中我们显示了不同级别玩家排名中神奇宝贝被一起选中的趋势。数据中的变量总结如下:

变量

对玩家技能的衡量:在这个分析中,我们使用‘Elo’分数来评估玩家技能。下面的例子解释了 ELO 的基本概念:新玩家从 1,500 Elo 点开始。如果玩家赢得一场比赛,他们将获得 25 分以及一个可变的数额,如果他们击败的对手具有更高的 Elo 分数,则该数额会更大。相反,失败的玩家会失去 25 点 Elo 点数,如果他们输给了级别较低的对手,还会失去更多。随着时间的推移,我们希望 Elo 分数较高的玩家比分数较低的玩家更擅长赢得更多、更艰难的游戏。

***对两个神奇宝贝一起被选中的一种衡量:*为此,我们使用了“队友权重”,即一个神奇宝贝的选择给另一个选择的后验概率的变化。例如,如果神奇宝贝“Scizor”出现在我们数据集中 40%的团队中,但出现在所有带有“Excadrill”的团队中的 60%,那么我们可以说 Scizor 带有 Excadrill 的“队友权重”为 20。这些权重也可以是负数,这表明拥有神奇宝贝 X 的团队倾向于积极避免选择神奇宝贝 y。

数据源

上述变量的来源由 Smogon.com 提供。每个月,Smogon 都会发布一个 JSON 文件,其中包含按技能等级和游戏类型划分的数据。在我们的分析中,我们使用:

“第 8 代,过度使用”(gen8OU)游戏类型:这是最平衡的竞争阶梯。在这种游戏类型中,一些太强大的神奇宝贝是不允许的,这样玩家可以从许多可行的策略中选择,而不是被迫只选择一小撮“被压制”的选择。“第 8 代”意味着玩家可以从第 8 版之前的所有神奇宝贝中进行选择。熟悉该系列的人可能知道,每一代大约会推出 150 个新的神奇宝贝。

我们正在比较两个 JSON 数据集:平均技能等级(这是一个新手会与之竞争的)和最高技能等级。

通过比较 2015 年和 2020 年的最高技能水平,我们还可以看到策略的选择如何随着时间的推移而变化。

本文中使用的数据是开放的,可从以下网址获得:

高技能玩家:1825 年 Gen8OU+ELO,2020 年 10 月

平均技能玩家:2020 年 9 月 0-1500 ELO Gen8OU

2015 年高技能玩家:2015 年 10 月 Gen5OU at 1760+ELO

方法学

为了直观显示技能等级中的玩家如何选择他们的团队,我们创建了一个网络图,然后进行了社区分析,以确定何时某些神奇宝贝集群被一起选择到了显著的程度。为了进行这种分析,我们设置了一个 neo4j 沙箱,然后创建了一个用 CYPHER 编写的分析管道(参见附录)。

我们执行此分析的步骤总结如下:

1.我们从 JSON 导入原始数据,并为数据集中的每个神奇宝贝创建一个节点。

2.根据相同的 JSON 数据,我们在每个神奇宝贝和其他神奇宝贝之间创建了一个名为“队友”的边(即关系)。这种关系有一个浮动属性,即“队友权重”变量(参见“变量”一节)。

3.我们删除了队友权重低于任意阈值(在本例中为 40)的所有关系。这是因为很难将每个节点与其他节点相关的图形可视化,我们只对神奇宝贝很可能被一起挑选出来的关系感兴趣。

4.我们实现了 Louvain 社区检测,类似于层次聚类,以识别更频繁一起选择的神奇宝贝集合。为此,我们将队友权重变量调整为 0 到 1 之间的浮动值。

5.最后,我们用由颜色分隔的社区形象化这个图。

结果

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

图 1:截至 2020 年 10 月的高技能玩家。图片作者。

在图 1 中,在高技能的玩家中,我们可以看到一些明确定义的团队起草策略。

在蓝色的中,我们有一个 12 个选项的社区,其中 cle 寓言、河马兽和 Toxapex 是最核心的。有经验的玩家可以识别出为什么这是一个强队:cle 寓言是一个强大的神奇宝贝,但对钢铁和毒药很弱。河马兽是对抗大多数钢铁和毒药的绝佳对手,包括广受欢迎的克理寓言,盔甲鸟。毒顶是一种适合对抗其他基于寓言的团队的毒药类型。

在 brown 中,Excadrill 似乎是许多团队所围绕的神奇宝贝。然而,Excardill 也可能出现在基于 cle 寓言的团队中,通常作为河马兽的替代品(因此河马兽<->Excardill 的队友权重相对较低)。

在 orange 中,Riabloom 是另一个热门的组队选择。在这个社区的左上角可以看到一个有趣的观察结果:Shuckle 似乎是 Riabloom 团队中最常见的角色,并且只有在与 Urshifu 配对时才出现。这告诉我们,在舒克尔和乌尔西弗之间可以发现一种有趣的协同作用。

绿色中,Genesect 是最中心的节点。有趣的是,没有节点将这个社区连接到其他社区,这告诉我们这个团队策略与其他选择相互排斥。

***红色,*我们有另一个孤立的集群,但只有三个神奇宝贝。这表明这三个经常一起出现,但他们团队中剩余的神奇宝贝是许多不同选择的混合,没有队友权重超过我们的阈值。

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

图 2:一般球员中的队友选择,2020 年 9 月。图片作者。

在图 2 中,我们创建了与图 1 中相同的网络图,但是是针对普通玩家的。从图 1 和图 2 中,我们可以比较普通玩家和高技能玩家的团队选择策略。通过比较这两个数字,我们发现:

社区的分离要少得多,这意味着普通玩家更频繁地混合来自不同社区的神奇宝贝。因此,被组织成典型团队的神奇宝贝的定义不太明确。这可能表明玩家做出了更多的实验性选择,而更熟练的玩家对队友的最佳组合有更敏锐的感觉。

这些社区中最核心的节点不同于高技能层中的节点。这表明普通玩家并没有和高技能玩家组成相同的队伍,而是高技能玩家选择了和普通玩家完全不同的队伍。这告诉我们,比赛前的团队选择,而不仅仅是比赛中熟练的决定,是成功的关键因素。

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

图 3:高技能选手中的队友选择,2015 年 10 月。图片作者。

比较 2020 年和 2015 年流行的团队也很有趣,当时第 6 代到第 8 代还没有出现。在图 3 中,我们为 2015 年排名靠前的玩家创建了一个网络图。从图中我们再次看到高排名的玩家比普通玩家有更清晰的社区定义。

一个有趣的观察是,尽管 cle 寓言和 Excadrill 在 2015 年都可用,但它们并不是团队建设的关键选择,就像我们在 2020 年看到的那样。这向我们表明了元博弈是如何随着时间而变化的。

结论

电子竞技中的元游戏是分析战略选择的一个极好的话题,因为我们有一个独特的机会来捕捉玩家如何在不同的战略背景下做出选择的非常详细的信息。在许多游戏中,也在许多其他环境中,单个组件如何协同工作与它们如何单独操作一样重要。这种对行动者之间协同作用的强调是分析由基因、营销活动以及游戏中队友组成的系统的重要方法。

在本文中,我们演示了如何使用共现来创建网络图,我们可以通过分析来辨别玩家采用的各种策略。我们可以识别出神奇宝贝的某些选项何时可能有互补的角色,或者何时它们服务于互斥的角色,因此玩家应该选择其中一个,而不是两个。像这样对高技能玩家行为的洞察可以帮助我们理解如何更快地在游戏中取得成功,并将这种方法应用到其他领域。

参考

https://www . smogon . com/forums/threads/everything-you-even-want-to-know-about-ratings . 3487422/

【https://www.smogon.com/stats/2015-10/chaos/gen5ou-1760.json 号

*【https://www.smogon.com/stats/2020-10/chaos/gen8ou-1825.json *

https://www.smogon.com/stats/2020-09/chaos/gen8ou-1500.json

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

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

附录:演练

您可以自己重新创建整个分析!完成下面的演练可能需要大约 20-30 分钟。这是一个初学者友好的演练,所以你不需要任何先前的经验。熟悉任何查询语言都有助于理解代码的作用。

准备一个环境

1.使用 Neo4J 创建一个免费帐户,并在此创建您自己的沙箱。

2.选择“新项目”,然后选择“空白沙盒”

3.选择“在浏览器中启动”

4.在屏幕的顶部,您会看到命令行,分块输入以下代码(不幸的是,neo4j 沙箱不够强大,无法一次执行所有代码!)

代码

分别执行每个注释部分。下面的代码从一个选定的 JSON 文件中提取数据。只需将 URL 更改为 smogon.com/stats,的不同设置,即可分析不同的技能等级或时间段。

*// Create Nodes and Relationships from JSONWITH “https://www.smogon.com/stats/2020-10/chaos/gen8ou-1825.json" AS urlCALL apoc.load.json(url) YIELD valueUNWIND value.data as dFOREACH (name in keys(d) | CREATE (Pokémon:Pokémon {id: name, teammates: keys(d[name].Teammates)}))With valueUNWIND keys(value.data) as nameMATCH (a:Pokémon) WHERE a.id = nameUNWIND a.teammates as tmMATCH (b:Pokémon) WHERE b.id = tmCREATE (a)-[r:Teammate {name: a.id +’<->’+b.id, weight: value.data[a.id].Teammates[b.id]}]->(b)// Cull Relationships where weight is below a thresholdWith 40 as thresholdMATCH p=()-[r:Teammate]->() WHERE r.weight < threshold DELETE r// Scaling weights before community detection algorithmMATCH ()-[r:Teammate]->() WITH toFloat(max(r.weight)) as maxMATCH ()-[r:Teammate]->() SET r.nweight = toFloat(r.weight) / max// Create a named graph with gdc packageCALL gds.graph.create(‘myGraph’,‘Pokémon’,‘Teammate’,{relationshipProperties: ‘nweight’})YIELD graphName// Call the Louvian community detetction algorithm on the named graphCALL gds.louvain.write(‘myGraph’, { writeProperty: ‘community’, relationshipWeightProperty: ‘nweight’ })YIELD communityCount// Name the community after most central nodeMATCH (p:Pokémon)WITH p, p.community as community, size( (p)-[:Teammate]-() ) as centrality ORDER BY community ASC, centrality DESCWITH community, (head(collect(p))).id as top, count(*) as size, collect(p.id)[0..6] as likleyTeam, collect(p) as allORDER BY size DESCFOREACH (p IN all | SET p.communityName = top)// Name the community after most central nodeMATCH (p:Pokémon)WITH p, p.community as community, size( (p)-[:Teammate]-() ) as centrality ORDER BY community ASC, centrality DESCWITH community, (head(collect(p))).id as top, count(*) as size, collect(p.id)[0..6] as likleyTeam, collect(p) as allORDER BY size DESCFOREACH (p IN all | SET p.communityName = top)// Add the community name as a label to each node, which will then color each node in the visualizationMATCH (p:Pokémon)CALL apoc.create.addLabels(p,[p.communityName]) yield node RETURN node// Before visualising, we remove the ‘Pokémon’ label, so neo4j will color code by communityMATCH (p:Pokémon)REMOVE p:PokémonRETURN p.name, labels(p)// Visualize the graphMATCH pkmn=()-[r:Teammate]->() RETURN pkmn*

寻找正确的数据分析策略

原文:https://towardsdatascience.com/finding-the-right-data-analytics-strategy-e90820970d0?source=collection_archive---------31-----------------------

如何构建有意义的 KPI 和仪表板

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

Unsplash 上由米米·蒂安拍摄的照片

KPI关键绩效指标的缩写。该术语指的是可用于确定公司活动绩效的关键数字。应该考虑哪些 KPI 来衡量成功或失败取决于公司目标[1]。这些 KPI 可以与其他事实和数字一起显示在所谓的仪表板上。微软 Power BI、Google Data Studio 或 Tableau 等先进的(自助式)BI 工具可用于此目的。在下面的文章中,我将描述如何战略性地开发这样的 KPI 和仪表板,以及实现这一点的两种方法。

自上而下方法

董事总经理和其他高管定义对他们来说有意义的 KPI。这些 KPI 和仪表板然后根据严格的规范实现,并且应该成为公司的准标准。

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

自上而下的方法流程—作者提供的图片

Pro: 流程和数字都是标准化的——这样你就知道数字是从哪里来的,可以让它们变得透明易懂。也使得部门、地区、国家具有可比性。

反对: 特殊的区域要求和环境不能或不应该被映射。

自下而上的方法

业务部门将借助自助 BI 工具构建 KPI 的任务分配给 IT 部门,或者自己使用这些工具。

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

通过 Google Data Studio 轻松使用 Self BI——图片由作者提供

这些不是从上面决定的,而是根据自己的需求迭代开发的。

Pro:
个别部门和地区完全可以根据自己的需求构建仪表盘。

反对:
供应可能会更加耗时,例如,可能需要提供额外的数据。此外,由于部分数据集成(尤其是仪表板的创建)没有标准化,因此很难进行比较。这也会导致更复杂的维护。

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

自下而上的方法流程—作者提供的图片

摘要

这两种方法在公司中经常同时出现。自下而上方法的缺点当然可以通过标准化部门中建立的 KPI 并将其推广到公司来抵消。这里的挑战是,有关各方必须就标准达成一致,但一旦达成一致,结果很可能会比自顶向下的方法更符合实际的操作需求。然而,有一点很清楚,前提是建立一个可扩展且易于使用的数据平台。有了它,这种分析首先成为可能。

“KPI 的使用意味着提高和转变组织的绩效。”― 朱【2】

资料来源和进一步阅读

[1]KPI.ORG,什么是关键绩效指标(KPI)? (2021)

[2]朱珍珠,性能大师:用整体方法开启数字性能 (2021)

查找曼哈顿每对位置之间与时间相关的旅行时间

原文:https://towardsdatascience.com/finding-time-dependent-travel-times-between-every-pair-of-locations-in-manhattan-c3c48b0db7ba?source=collection_archive---------37-----------------------

在这篇文章中,我将向您展示一种相对简单快捷的方法,使用完全开源的软件包和开放数据来计算一天中任何时间曼哈顿每个十字路口之间的旅行时间。代码完全是用 Python 写的,可以在 GitHub 上找到。这种方法可以推广到任何有数据的城市。

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

纽约市的平均交通速度是每小时 4.7 英里。勒隆·皮耶特斯Unsplash 上的照片

作为一名交通研究人员,我经常遇到利用纽约市的出租车和叫车出行记录来测试算法和假设的研究。需要多少辆自动驾驶汽车来取代整个出租车车队?城市空中出租车机场的最佳位置是哪里?该数据集在研究社区中很受欢迎,因为它是分类的,这意味着它包括每次旅行的记录,包括确切的接送时间和地点,因此可用于非常详细和现实的研究。

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

来自一篇题为:出租车司机是种族主义者吗?(来源:https://bennstancil.com/nyc-taxis-and-race)

使用这些数据的挑战之一是它代表了大量的起点和终点。如果您想要测试算法,或者想要为新的假设三轮车出租车服务设置模拟,您最终需要知道所有可能的上车、下车和闲置车辆位置之间的行驶时间。这是一个多对多的旅行时间问题,计算的次数等于可能位置的个数的平方。此外,如果您想要一天中不同时间或一周中不同天的行驶时间,这意味着重新计算每个时间段的行驶时间。

使用谷歌地图 API 是一种选择,但它不是免费的,如果需要多次调用,成本会很高。像 Valhalla 这样的其他路径包是免费的,但有一个学习曲线,可能需要大量的时间来完成大规模的旅行时间计算。相反,我决定利用 Python 中相对快速的图形分析算法,以及精彩的优步运动 (UM)数据,其中包括几十个城市中曼哈顿每条道路的行驶速度。完整的方法在下一节中描述。

首先,我需要创建一个网络来代表曼哈顿的街道。幸运的是,有一个 Python 库可以解决这个问题。 OSMnx 是对现实生活中的城市进行空间分析的天赐之物,它包括一个单线功能,可以创建世界上几乎任何城市的街道网络图(见下文)。它使用 OpenStreetMap 创建图表。

import osmnx as ox
G = ox.graph_from_place('Manhattan, New York, USA', network_type='drive')

该网络包括每个街道交叉口的结点以及每条道路每个方向的边。我们现在可以使用网络算法来寻找每对节点之间的最短路径(即网络中的每个交叉点)。 NetworkX 是一个通用且功能强大的库,内置最短路径函数,是 OSMnx 的构建模块之一。我们可以使用以下代码行创建一个 shortest_path 生成器:

import networkx as nx
path_enumerator = nx.shortest_path(G, weight='weight')

然后我们可以通过调用path_enumerator[origin][destination]找到包含任意节点对之间最短路径的边集。我们还可以使用单独的函数为最短路径的创建一个生成器:

*path_generator = nx.shortest_path_length(G, weight='weight')*

但是在这种情况下“最短”是什么意思呢?您会注意到,该函数采用一个“权重”输入参数,该参数可用于指定在确定“最短”路径时使用哪些属性。现在,我们的边包括距离属性,但没有旅行时间。

OSMnx 确实包括一个单独的功能来分配网络中每个链接的旅行时间,但它们是基于 OpenStreetMap 的自由流旅行速度。在曼哈顿几乎没有自由流动的流量,所以这对于大多数应用程序来说是行不通的。幸运的是,OSMnx 保留了网络中每条边的 OSM 路 ID 作为边属性。猜猜 OSM 路 ID 还索引了什么?UM 速度数据。我们需要做的就是导入 UM 数据,将速度作为一个新属性附加到每条边上,然后使用速度作为最短路径算法的权重。

UM 数据可以从网站上以 CSV 格式下载。下面是一个例子,说明如何使用 Python 从 CSV 导入 UM 数据,并使用方式 id 作为键,速度作为值创建一个字典。

*import pandas as pd
df = pd.read_csv('Data/nyc_avg_speeds_2019-06.csv') 
mydict = dict([(t.osm_way_id, t.speed) for t in df.itertuples()])*

现在,我们可以快速找到曼哈顿任何两个地点之间在任何时间段或任何感兴趣的一天的最短驾驶时间。如果使用滑行数据,请注意,OSMnx 包括将任何纬度/经度对捕捉到最近的图形节点的功能:

*pickup_node = ox.get_nearest_node(G, (lon, lat))*

这种方法不仅限于曼哈顿。OSMnx 覆盖了全球大部分地区,而 UM 包括了不同大洲的许多城市,因此它也可以用于开罗、悉尼或班加罗尔。

我希望这能对你有所帮助。如果你在自己的研究中使用这个作为资源,请让我知道。

[1]从 2016 年 6 月开始,这些位置实际上被汇总到了社区级别,在此之前,一些聪明人发现你可以使用准确的位置数据来跟踪城市中的名人,并确定脱衣舞俱乐部顾客住在哪里

[2] UM 速度数据基于优步驾驶员记录的行驶速度,可用于一周中任意一天或多天的 5 个时间段。

[3] OpenStreetMap 数据是 OpenStreetMap 贡献者。

在被低估的足球运动员中发现未开发的潜力

原文:https://towardsdatascience.com/finding-untapped-potential-in-undervalued-soccer-players-8de0f6e54263?source=collection_archive---------32-----------------------

世界级的足球运动员收入丰厚。

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

维也纳·雷耶斯在 Unsplash 上拍摄的照片

不出所料,世界级的足球运动员收入不菲。

据美国经济杂志 Forbes 报道,2020 年,阿根廷足球运动员莱昂内尔·梅西以 1.26 亿美元的收入排名世界第一。我使用了国际足联数据集中的统计元素来探究这些元素是如何影响球员工资的。我从 Kaggle 得到了 FIFA 数据集。

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

来自 Kaggle 的 FIFA 数据集

然后我分析了相对于能力被低估的球员(相对于能力领取低工资)。

换句话说,该分析的目标

  1. 根据球员 2020 年的特征数据预测 2021 年的工资,并模拟其与 2021 年实际工资的匹配程度
  2. 预测与他们的特征元素相比目前被低估的未来足球明星。

[目标# 1——根据球员 2020 年的特征数据预测 2021 年的工资,并模拟其与 2021 年实际工资的匹配程度]

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

照片由 Siora 摄影Unsplash 上拍摄

数据清理

有 65 个特征,但是我删除了具有“对象”类型和“标记”列的特征(由于大量的空值)。

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

为了从工资和价值列中删除“€”、“K”、“M”,我创建了几个函数来清理单词,如下所示。此函数还将“工资”和“价值”列的类型更改为 float,然后乘以 1,000,000 而不是“M”,乘以 1,000 而不是“K”。

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

用于删除字符串并将字符串数据转换为数字数据的函数

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

使用创建的函数清理数据(11,779 行和 47 列)

然后,我可视化了 Wage_2021(€)的信息,这是预测的目标。

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

直方图和箱线图

似乎有太多的局外人,因为著名的明星球员拿着巨额工资。

在这些特性中,我删除了“ID”和“Name”列,只选择数字数据,并为每个特性创建了直方图以便可视化。

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

每个特征的直方图

从直方图中,我意识到这些特征没有被缩放。所有要素都应进行归一化,以符合相同的单位。

我使用了来自 Scikit-learn 库StandardScaler()

首先,由于我使用原始值来预测工资,“Wage_2021(€)”应该从标准化中排除。

我设置w 2020 _ 21 _ picher . drop([’ Wage_2021(€)'],axis = 1)为 X 使用除 Wage _ 2021(€)以外的所有特性,然后使用 StandardScaler()。fit_transform()归一化所有要素。

完成这项工作后,所有缩放后的特征通过 pd.concat 函数与“Wage_2021(€)”的原始值相结合。最后,我将 Wage_2021(€)设为 y 进行线性回归。

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

所有特征都被规范化,如下所示。(y:工资 _2021(€))

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

数据帧’ picher_df ’

线性回归

对于线性回归,我将数据分为训练数据集和测试数据集。

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

为了评估该回归模型,使用了 R2 评分和RMSE 评分。

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

R2 分数和 RMSE 分数

然后,我训练并输出回归系数。打印出回归系数后,我想知道这 45 个特征中哪一个是最有影响的特征,于是我用 statsmodel 库进行了回归分析。我将结果可视化如下。

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

然后我创建了一个热图来进行关联分析。

首先,我计算了特征之间的相关系数矩阵,并用计算值生成了一个热图。

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

热图—相关系数矩阵

我检查了系数的多重共线性,作为提高回归预测性能的一种方法。

一般来说,如果 VIF 系数超过 10-15,就意味着出现了多重共线性问题。

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

VIF 系数

基于这个结果,我选择了

[‘弱脚’,‘国际声誉’,‘技能招式’,‘工资 _2020(€)’,‘沉着’,‘价值 _2020(€)’,‘年龄’,‘潜力’,‘最佳综合评分’,‘总体’] 作为有效特征。

从 VIF 因子的得分来看,多重共线性问题似乎发生在最佳总体评分(99.64)和总体评分(102.49)中。

我不得不删除“最佳总体评分”或“总体”来解决多重共线性问题,

当我在删除“总体”后再次计算系数的多重共线性时,另一个系数(“最佳总体评级”)从 99.64 更改为 7.73。

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

“最佳总体评价”从(99.64)变为(7.73)

完成这项工作后,我用选定的功能重置了 X。

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

然后用 R2 分数和RMSE 分数再次评估回归模型。

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

具有选定 VIF 系数的 R2 评分和 RMSE 评分

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

第一次得分与第二次得分的比较

可视化

具有选定特征的 X([‘弱脚’,‘国际声誉’,‘技能移动’,‘工资 _2020(€)’,‘沉着’,‘价值 _2020(€)’,‘年龄’,‘潜力’,‘最佳综合评分’]),

我用**predict _ 2021 _ wage = lr . predict(X)预测了 2021 年的工资。**然后将‘预测 _ 2021 _ 工资’和‘工资 _ 2021(€)’与 picher_df 结合。

连接数据框后,我将列**‘y’重命名为‘real _ Wage _ 2021’,****‘Wage _ 2020(€)’重命名为‘real _ Wage _ 2020’**。

并且只分析了续约后工资有变化的球员。

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

结果 _df:

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

结果可视化 _df:

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

用 Matplotlib 可视化

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

数据机器人可视化

【目标 2——预测与他们的特征元素相比目前被低估的未来足球明星。]

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

Andriyko Podilnyk 在 Unsplash 上拍摄的照片

为了找出那些年轻、身体状况良好但被低估的球员(目前工资较低,因此将有利于俱乐部),我重新加载了数据集,并使用了从系数的多重共线性中选择的列。对于守门员的数据集,我添加了[’ GK driving ‘,’ GKHandling ‘,’ GKKicking ‘,’ GKPositioning ‘,’ GKReflexes’]列,这是专门为守门员提供的。

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

我用 75% 作为条件的值来计算被低估的玩家。

对于年龄,我使用 25%的值作为标准,而不是 75%的值。这是因为与其他属性不同,年龄越小越好。此外,我没有使用工资和价值列,因为工资和价值应该在其他功能设置为确定的标准后进行评估。

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

用于生成描述性统计数据的描述函数

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

年龄使用 25%,其他特征使用 75%

以上所有条件,球员有 92 个结果,门将球员有 8 个结果。

我按照工资 _2021(€ 一栏升序排列结果。

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

92 名被低估的球员

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

8 名被低估的门将球员

从结果来看,我发现 92 名球员和 8 名门将的能力被低估了。

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

Md MahdiUnsplash 上拍摄的照片

结论

总之,从 Kaggle 数据集中有超过 50 个关于足球运动员的统计特征。基于数据集使用线性回归模型预测足球运动员的未来工资,在评价中显示出相当高的分数。

此外,VIF 系数有助于挑选最有用的特征。基于这些具体特征,用 describe 函数算出前 25%的数据,就能算出相对于能力被低估的球员。

根据结果,包括 N. Zaniolo、J. Kluivert、L. Ivanuš ec 和 A. Hlož ek 在内的 92 名球员与其能力相比被低估。8 包括 Pau López、D. Livakovi、A. Onana 和 P. Rajkovi 在内的守门员球员与其能力相比也被低估。

如果假设这些特征是基于真实球员的信息进行客观评估的,这些有天赋的年轻球员是转会市场上值得关注的人。

在 Python 中使用 TF-IDF 和余弦在术语上下文矩阵中从头开始查找单词相似度

原文:https://towardsdatascience.com/finding-word-similarity-using-tf-idf-in-a-term-context-matrix-from-scratch-in-python-e423533a407?source=collection_archive---------1-----------------------

嵌入是直接从单词在文本中的分布来表征单词的意思。这些表示被用在每一个利用意义的 NLP 应用中。

这篇文章的完整代码可以在这里找到。

词义的一个重要组成部分是词义之间的关系。例如,当一个单词的意思与另一个单词的意思相同或几乎相似时,我们说这两个单词的两个意思是同义词。如的关键 / 的命令式。

虽然单词没有很多同义词,但大多数单词都有很多相似的术语。不是的同义词,但是无疑是相近的词(都是食物)。在谈论词义之间的关系时,相似性是从同义词的一个有价值的转变;这将简化我们的任务。

我们将分析一系列莎士比亚的文本,并在我们的戏剧中寻找戏剧和文字之间的相似之处。我们的数据有一些来自不同莎士比亚戏剧的句子和戏剧的名字。

术语-文档矩阵

意义的向量或分布模型通常基于共现矩阵,这是一种表示单词共现频率的方法。我们将实现两个流行的矩阵;术语-文档矩阵和术语-上下文矩阵。

在术语-文档矩阵中,每行代表词汇表中的一个单词,每列代表文档集合中的一个文档。请看下面我们的实现:

def term_document(self, word_list):
    for play, word in word_list:
        if (play, word) in self.term_document_matrix:
            self.term_document_matrix[(play, word)] += 1
        else:
            self.term_document_matrix[(play, word)] = 1
    return self.term_document_matrix

我们矩阵中的数据示例如下:

('Twelfth Night', 'love'): 77
('Julius Caesar', 'come'): 75
('Romeo and Juliet', 'enter'): 74

上面的意思是单词 enter 在戏剧《罗密欧与朱丽叶》的句子中出现了 74 次,以此类推。

我们可以从上面的矩阵中计算出这些剧本之间的相似性,这可以使用余弦来完成。这基于线性代数中的点积运算符,可计算如下:

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

图片来自作者

余弦值的范围从指向相同方向的向量的 1 到正交向量的 0。

我们将利用 scipy 的空间库来实现这一点,如下所示:

def cos_sim(self, vector1, vector2):
    cosine_similarity = 1 - spatial.distance.cosine(vector1, vector2)
    print(cosine_similarity)

我们可以通过一个小样本轻松验证这一点:

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

图片来自作者

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

实现此功能以进行测试:

**apricot** = [1, 0, 0]
**digital** = [0, 1, 2]
**information** = [1, 6, 1]
print(self.cos_sim(apricot, digital))0.0

测试其他样本也返回有效结果,太好了,现在让我们测试我们的数据,我们将相互比较我们的每个文档:

def cal_cosine(self, docs):
    tf = self.read_csv()
    play_dict = {}
    for play in self.play_names:
        play_vec = []
        for word in self.vocab:
            play_vec.append(tf[(play, word)])
        play_dict[play] = play_vec

    scores = []
    for k1, v1 in play_dict.items():
        for k2, v2 in play_dict.items():
            if k1 <= k2: continue
            scores.append((self.cos_sim(v1, v2), (k1 ,k2)))
    scores.sort(reverse=True)
    print(scores[:25])

我们的顶级余弦相似点是:

(0.9885556994486011, ('Cymbeline', 'A Winters Tale')),(0.9817079988849085, ('Henry VI Part 2', 'Henry VI Part 1')),(0.9811981513422073, ('Alls well that ends well', 'A Winters Tale'))

术语上下文矩阵

对于我们上面的计算,我们使用了频率,但原始频率可能会非常倾斜,要知道我们的单词或文档共享哪些上下文,停用词在这里或任何其他频繁出现的单词形式都没有用,不知何故,在你关注的单词附近出现的单词的频率更重要。

这个问题的解决方案是使用 tf-idf 加权,这是两项的乘积:

TF——这是词频,即单词 t 在文档 *d、*中的出现频率,这是在日志空间中计算的:

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

图片来自作者

IDF -本逆文档频率N/df;其中 N 是集合中的文档总数,df 是一个术语出现在其中的文档数。这使得只在少数文档中出现的单词具有更高的权重。仅限于几个文档的术语有助于将这些文档与集合中的其他文档区分开来。术语出现的文档越少,权重越高,这也是在日志空间中计算的:

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

图片来自作者

TF-IDFTFIDF 的点积,因此计算为:

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

图片来自作者

让我们在当前的语料库上尝试一下,我们将从实现一个术语上下文矩阵开始,我们将查看每个单词和前后的 4 个单词,然后统计它在同一个单词周围出现的频率。

def term_context(self):
    term_context = defaultdict(lambda: defaultdict(lambda: 0))
    with open("ShakespearePlays_text.csv", "r") as f:
        # load csv
        reader = csv.reader(f, delimiter=";")
        # loop through line in csv
        for line in reader:
            play_name = line[1]
            if play_name not in self.play_names:
                continue
            tokens = line[5].split()
            sentence = []
            for term in tokens:
                token = self.clean(term)
                if token in self.vocab:
                    sentence.append(token)
            for i in range(len(sentence)):
                word = sentence[i]
                for j in range(max(0, i - 4), min(len(sentence), i + 5)):
                    if i == j: continue
                    term_context[word][sentence[j]] += 1
    return term_context

我们的术语上下文矩阵看起来像这样:

'**befortune**': ({'i': 1, 'wish': 1, 'all': 1, 'good': 1, 'you': 1})'**bohemia**': ({'chance': 1, 'camillo': 1, 'to': 4, 'visit': 1,'on': 1, 'difference': 1, 'betwixt': 1, 'our': 1, 'and': 5, 'your': 1, 'sicilia': 1, 'means': 1, 'pay': 1, 'the': 5, 'visitation': 1}

接下来,我们将构建我们的文档频率矩阵,我们将使用上面的术语上下文来完成这个任务,(以减少计算时间并使用更小的子集),

def cal_doc_freq(self, term_frequency):
    values_per_key = {}
    for k, v in term_frequency:
        values_per_key.setdefault(k, set()).add(v)
    counts = {k: len(v) for k, v in values_per_key.items()}
    return counts

我们将使用下面的公式计算术语上下文中所有单元格的文档频率:

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

图片来自作者

我们将计算 TF-IDF

 t = self.read_csv()
    counts = self.cal_doc_freq(t)
    tc = self.term_context()
    for i in tc:
        for j in tc[i].keys():
            tc[i][j] = tc[i][j] * (1 / counts[j])
    return tc

我们将在我们的 vocab 的一个小子集上进行测试,并找到单词罗密欧、朱丽叶、贵族、凯撒和朋友与其他单词的相似性。

def compute_word_similarity(self, words):
    tc = self.idf()

    def to_vec(w):
        vec = []
        for x in self.vocab:
            vec.append(tc[w][x])
        return vec

    for word in words:
        word_vec = to_vec(word)
        scores = []
        c = 0
        for k in tc.keys():
            if k == word: continue
            k_vec = to_vec(k)
            scores.append((self.cos_sim(word_vec, k_vec), k))
            c += 1
            # if  c > 10: break
        scores.sort(reverse=True)
        print("Top-5 matches for " + word + ": ", scores[:5])

我们的前 5 个相似词是:

**Top-5 matches for romeo**:  [(0.7349592582145151, 'dead'), (0.7291389527324256, 'he'), (0.7256033280986567, 'then'), (0.7237096963536124, 'it'), (0.719416236702853, 'where')]**Top-5 matches for juliet**:  [(0.7840722487008701, 'lucius'), (0.7700540752904482, 'servants'), (0.7692483251584336, 'soldiers'), (0.7682255792237922, 'warwick'), (0.7672900349518263, 'others')]**Top-5 matches for nobleman**:  [(0.8139265551526883, 'woman'), (0.813455008644156, 'soldier'), (0.808373550553078, 'little'), (0.8053083580334184, 'gentleman'), (0.8046068607590102, 'stranger')]**Top-5 matches for caesar**:  [(0.8897940437391335, 'him'), (0.8825311102107262, 'them'), (0.8718307075270313, 'that'), (0.8707738937545483, 'his'), (0.8674185090147457, 'me')]**Top-5 matches for friend**:  [(0.9280138220686541, 'wife'), (0.9239327316145367, 'daughter'), (0.9111186066627961, 'father'), (0.9091224168395339, 'brother'), (0.9086148854991047, 'mother')]

这看起来很合理,因为朋友——妻子、女儿、兄弟、父亲和母亲确实有一些相似之处。贵族和绅士或许还有士兵有一些相似之处,等等。

我确信有办法让我们的预测更准确,但这是一个好的开始。

期待问题、评论和反馈。谢了。

使用 Networkx 在 Spotify 上查找下一位最喜欢的艺术家

原文:https://towardsdatascience.com/finding-your-next-beloved-artists-37596d48f32c?source=collection_archive---------33-----------------------

你现在最喜欢的艺术家会如何影响你对新音乐人才的追求?

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

安托万·朱利安在 Unsplash 上拍摄的照片

一年来,我一直在查看 Spotify 的 Discover Weekly,尽管我很欣赏他们的选择,但我发现自己在推荐的 30 首歌曲中,最多只喜欢 5 首。我喜欢的那些人的共同点是,我会点击他们背后的艺术家的简介,阅读他们的简历,并查看他们的一些热门歌曲。

我意识到比起发现歌曲,我更喜欢发现艺术家。

我知道宝石是稀缺的,一个艺术家很少会有一首以上的热门歌曲,但有时一首歌并不能涵盖一个艺术家的全部,我们错过了探索他们的唱片目录的机会。

本文探讨了一种基于你的历史流媒体偏好在 Spotify 上寻找新艺术家的策略。每一步都伴随着一个使用 Spotify API 的 Python 实现。

下图是司徒迈(比利时艺术家)在 Spotify 上的个人资料页面。点击“粉丝也喜欢”,根据对 Spotify 社区收听历史的分析,你会找到多达 50 位与司徒迈相似的艺术家的列表。API 文档没有深入到相似性度量的细节,但我认为它是音乐特征和协作过滤的结合(即,如果两个艺术家拥有相同的粉丝群,那么他们很可能是相似的)。

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

Spotify 上的司徒迈个人资料(信用:https://www.spotify.com)

粉丝也喜欢”列表不够翔实,因为它只显示了与司徒迈相似的艺术家,而没有考虑我个人的历史流媒体偏好。换句话说,如果能知道“粉丝也喜欢”页面上的艺人和我的前 50 名歌手有多相似,那就更有帮助了。

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

与司徒迈相似的艺人名单(鸣谢:https://www.spotify.com)

例如, Black M 被认为是第四个与司徒迈相似的人物,但我很想知道,在我的年度前 50 名艺术家中,有多少人与 Black M 有关

第一步:检索 Spotify 流媒体数据

Spotify 上为开发者创建一个账户后,您将收到一个 API 令牌来访问您的流媒体历史记录。

Spotify 在三个不同的时间范围内跟踪您的前 50 位艺术家:

  • 短期:基于你上个月的流媒体
  • 中期:基于你过去六个月的流水
  • 长期:自你的 Spotify 账户创建以来

我们编辑了以下三个时间范围内的顶级艺术家列表:

第二步:创建一个你最喜欢的艺术家的网络

网络说明了我喜欢的艺术家是如何联系在一起的。大节点是我的前 50 名艺术家,小节点是与他们相关的其他艺术家。请注意 Black M 与我已经喜欢的 4 位艺术家联系在一起,这意味着我应该探索他的音乐,尽管就与司徒迈的相似性而言,他似乎是第四位。

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

Spotify 上我最喜欢的艺术家的网络可视化

第三步:排列艺术家

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

与我的前 50 名联系最多的艺术家列表

按照同样的逻辑,我们统计网络中每个艺术家的学位,然后排除前 50 名的艺术家。结果是一个表格,显示了与我的前 50 位艺术家联系最多的艺术家。艺术家之间的联系越多,我就越有可能觉得他们的音乐有趣,值得探索。

注: 我恰好只知道这一张表中 30%左右的艺人。但看到他们与我的前 50 名艺术家有如此紧密的联系还是很有趣的。

在 Spotify 上包含这一功能将允许用户根据他们的流媒体偏好发现更丰富的艺术家网络,这将改善我们的音乐发现体验,并让艺术家对他们的整个作品给予相当多的关注。

https://github.com/Tahahaha7

在机器学习中找到自己的位置

原文:https://towardsdatascience.com/finding-your-niche-in-machine-learning-f58275807d03?source=collection_archive---------13-----------------------

为什么以及如何找到“你的”领域

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

蒂姆·福斯特在 Unsplash 上的照片

机器学习可能会让人不知所措。我和我公司的一位研究科学家(也就是博士)聊过,她提到她对自己的 ML 技能感到不自信。有这么多事情要做。每天都有很多东西要学。这种感觉与你所处的职业阶段无关。无论你是刚开始,在读研,还是已经在这个行业工作。在职业生涯的任何阶段,你都需要有自己的定位或“自己的领域”。

首先,让我们试着理解为什么拥有自己的利基市场是重要的,并有助于导航 ML 职业选择。

在线课程不会增加价值

在线课程会增加你个人知识的价值,但不会增加你简历的价值。

从今天开始,每个人都在 Coursera 课程中构建图像检测分类器。

把它放在你的简历上不会增加多少价值。在学习方面,这些课程是结构化的,有利于起步。但是,最终,你需要建立自己的东西来更好地理解这个话题,并在面试中获得优势。

利基帮助你筛选研究生院和工作

我经常被问到这个问题-

我如何决定申请哪所研究生院?

按主题过滤永远是我的答案。大多数大学针对某一特定主题开设了范围广泛的课程。确保根据你的兴趣进行筛选。看看提供的课程,检查它们是否是你感兴趣的(因为你将投入大量时间学习这些)。

这也有助于筛选出你“适合”的工作类型,增加你被录用的机会。

帮你回答你在做什么?

在大多数面试中,我被问到的第一个挥之不去的问题是:你从事什么工作?

如果一个人从事过 10 个不同的主题,并且对每个主题都了如指掌,他该如何回答这个问题呢?

大多数面试官喜欢深入你的一个项目,并在面试的剩余时间谈论它。

例如,当我面试各种角色时,我在多模态学习和图形神经网络方面的经验帮助我获得了目前的角色,尽管我的工作与这些领域没有直接关系。

利基最终成为你的技能

今天每个人都是数据科学家。让你与众不同的是你的专业。如果一个人除了 ML 中的基本主题之外还知道主动学习,他可以在那个特定的领域使团队受益。它把你和其他人区分开来。所有关于这个特定领域的问题都会直接指向你,这有助于在你的团队中建立信任。

既然你已经有点确信为什么找到你的专业领域是重要的,那么让我们看看人们如何找到“他们的”?哈佛大学的助理教授伊马·拉卡拉朱博士在最近的一次采访中说

在 ML 中寻找最好的主题就像是在问我是否有办法优化我的生活(或我的研究主题)从而赢得图灵奖?简单的回答是

在这样一个快速发展的领域中,没有办法将你的主题优化到最令人兴奋的一个,这个主题在几年后仍然有用。趋势会随着时间而变化,这是一个持续的学习过程。但这是我多年来遵循的原则。

  • 获取主题列表- 您可以从研讨会、教程和会议中找到当前的*【热门】*主题。举个例子,今年我去了 ICML,我做的第一件事就是查看所有正在进行的研讨会和辅导课。工作坊通常展示未发表的作品,对于了解未来趋势非常有用。
  • 从教程中学习- 我认为进入主题的最佳方式之一就是从教程中学习。它们为正在进行的研究和之前完成的工作提供了一个很好的时间表。
  • 寻找代码实现- 我找到了该领域中广泛使用的库,并尝试了一些基本代码。然后我试着浏览一些基础论文的研究实现。这是非常个人化的,但是直到我做了这些,我对了解主题的实际工作流程并不感到完全满意。很明显,如果你从事理论方面的工作,这就不同了。
  • **第一个项目——**找到该领域最基本的问题,并实施。这有助于更好地了解问题的设置,并让您的手接触代码。假设您想深入研究图形神经网络。尝试访问广泛使用的图形数据,并在 Numpy 或 Torch Geometric 中构建最简单的 GNN。
  • 开始建立关系网- 最好的学习方法是向专家学习。联系现场的人,问他们相关的问题。也就是说,不要发送普通邮件和垃圾邮件,这对任何人都没有帮助。没有人回复垃圾邮件。你可以问一些问题,比如~‘你能评论一下这个领域的范围吗?’。“这个话题在行业中有哪些应用”,“你提出的方法的最小扩展是什么?”、‘关于这个话题,你最喜欢的论文是什么?’
  • Post starting up- 现在,有了你所学的一切,你就可以提出自己的想法并付诸实施了。

微调用于语法纠正的转换器模型

原文:https://towardsdatascience.com/fine-tune-a-transformer-model-for-grammar-correction-b5c8ca49cc26?source=collection_archive---------31-----------------------

学习如何训练一个名为 T5 的转换器模型成为你自己的语法校正器

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

作者图片

在本文中,我们将讨论如何训练一个最先进的转换器模型来执行语法纠正。我们将使用一个名为 T5 的模型,它目前在通用语言理解评估(GLUE)基准上的表现优于人类基准,使其成为现有的最强大的 NLP 模型之一。T5 由 Google AI 创建,并向全世界发布,供任何人下载和使用。

在本教程中,我们将使用我自己的 Python 包 Happy Transformer 。快乐变形金刚建立在拥抱脸的变形金刚库之上,只需几行代码就可以轻松实现和训练变形金刚模型。因此,理解本教程的内容不需要对 NLP 或 Python 有复杂的理解,即使我们将训练世界上最有能力的人工智能模型之一。

向下滚动到“预训练模型”部分,了解如何下载和使用我训练并上传到 Hugging Face 的模型分发网络的语法纠正模型。

装置

快乐变压器在 PyPI 上可用,因此可以 pip 安装。

pip install happytransformer

模型

T5 有几种不同的尺寸,我们将使用基本模型,它有 2.2 亿个参数。最大的可用模型有 110 亿个参数,而最小的有 6000 万个参数。

T5 是一个文本到文本的模型,意味着给定的文本,它根据输入生成一段独立的文本。因此,我们将从 Happy Transformer 导入一个名为 HappyTextToText 的类,我们将使用它来加载模型。我们将为第一个位置参数提供模型类型(T5 ),为第二个位置参数提供模型名称(t5-base)。

from happytransformer import HappyTextToText

happy_tt = HappyTextToText("T5", "t5-base")

数据收集

我们将使用一个名为 JFLEG 的著名数据集来训练该模型。根据其拥抱脸页面上的描述,它是“开发和评估 GEC 系统流畅度的黄金标准基准”(GEC 代表语法错误纠正。)此外,根据谷歌学术的说法,它的论文目前有 106 次引用,这表明它在 NLP 社区内确实受到尊重[1]。它受 CC BY-NC-SA 4.0 许可证的约束,这意味着您必须提供其归属,不得将其用于商业目的,并对任何衍生应用相同的许可证*。

*这不是法律建议。阅读 完全许可 了解更多信息

该数据集在 Hugging Face 的数据集分发网络上可用,并且可以使用他们的数据集库来访问。因为这个库是 Happy Transformer 的依赖项,所以我们不需要安装它,可以直接从库中导入一个名为 load_dataset 的函数。

from datasets import load_dataset

数据集的 id 是“jfleg ”,有两个分支“‌"validation”和“测试”我们将验证集用于训练,测试集用于评估。

train_dataset = load_dataset("jfleg", split='validation[:]') eval_dataset = load_dataset("jfleg", split='test[:]')

数据检查

我们刚刚成功下载了数据集。现在让我们通过迭代一些案例来探索它。训练和评估数据集都以相同的方式构造,并且具有两个特征,句子和修正。句子功能包含每个案例的单个字符串,而更正功能包含 4 个人工生成的更正列表。

for case in train_dataset["corrections"][:2]: 
    print(case)
    print(case[0]) 
    print("--------------------------------------------------")

结果:

【所以我认为如果我们的祖先没有发展科学技术,我们就不会活着……】

所以我认为如果我们的祖先没有发展科学技术,我们就不会活着。

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

[‘不适用于汽车’,‘不要在车里使用。’,‘车不能用’,‘不能用这辆车。’】

不适用于汽车。

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

数据预处理

现在,我们必须将处理成 Happy Transformer 的适当格式。我们需要将训练和评估数据组织成相同的格式,这是一个包含两列的 CSV 文件:输入和目标。输入列包含语法不正确的文本,而目标列包含来自目标列的文本的正确版本。

下面是将数据处理成适当格式的代码。我们必须通过给每个输入添加相同的前缀来指定我们希望执行的任务。在这种情况下,我们将使用前缀“grammar:”。这样做是因为 T5 模型能够用单个模型执行多项任务,如翻译总结,并且为每项任务使用唯一的前缀,以便模型学习执行哪项任务。我们还需要跳过包含空白字符串的情况,以避免微调时出现错误。

import csv

def generate_csv(csv_path, dataset):
    with open(csv_path, 'w', newline='') as csvfile:
        writter = csv.writer(csvfile)
        writter.writerow(["input", "target"])
        for case in dataset:
     	    # Adding the task's prefix to input 
            input_text = "grammar: " + case["sentence"]
            for correction in case["corrections"]:
                # a few of the cases contain blank strings. 
                if input_text and correction:
                    writter.writerow([input_text, correction])

generate_csv("train.csv", train_dataset)
generate_csv("eval.csv", eval_dataset)

我们只是生成我们的训练和评估数据!我们总共生成了 3016 个训练样本和 2988 个评估样本。

培训前评估

我们将使用一个称为损失的通用指标来评估微调前后的模型。损失可以描述为模型的预测与正确答案相比有多“错误”。因此,如果微调后损失减少,那么这表明模型学习了。重要的是,我们使用单独的数据进行训练和评估,以表明该模型可以概括其获得的知识,以解决看不见的情况。

你还可以使用其他指标来评估语法纠正模型。其中最流行的一个叫 GLEU,在这里可以了解更多https://www.researchgate.net/publication/283810389_Ground_truth_for_grammatical_error_correction_metrics【2】。Loss 是用 Happy Transformer 实现的最简单的方法,所以我们将使用它。

让我们在任何训练之前确定评估数据集上的模型损失。为此,我们将调用 happy_tt 的 eval()方法,并提供包含评估数据的 CSV 路径。

**before_result = happy_tt.eval("eval.csv")**

结果是一个 dataclass 对象,它只有一个名为 loss 的变量,我们可以如下所示对其进行隔离。

**print("Before loss:", before_result.loss)**

**结果:亏损前:1 . 54385 . 38383838661

培养

现在让我们训练模型。我们可以通过调用 happy_tt 的 train()方法来实现。为了简单起见,我们将使用默认参数,而不是批量大小,我们将把批量大小增加到 8。如果您遇到内存不足的错误,那么我建议您减少批量大小。您可以访问此网页了解如何修改各种参数,如学习率和时期数。

**from happytransformer import TTTrainArgs args = TTTrainArgs(batch_size=8) happy_tt.train("train.csv", args=args)**

培训后评估

像以前一样,让我们确定模型的损失。

**before_loss = happy_tt.eval("eval.csv") print("After loss: ", before_loss.loss)**

**结果:损失后:0 . 54687 . 68686868661

这就对了,你可以看到损失减少了!但是,现在让我们通过提供示例来更定性地评估该模型。

推理

现在让我们用这个模型来纠正我们将提供的例子的语法。为此,我们将使用快乐 tt 的 generate_text()方法。我们还将使用一种称为波束搜索的算法进行生成。您可以在这个网页上查看您可以修改的不同文本生成参数,以及您可以用于通用算法的不同配置。

**from happytransformer import TTSettingsbeam_settings = TTSettings(num_beams=5, min_length=1, max_length=20)**

示例 1

**example_1 = "grammar: This sentences, has bads grammar and spelling!" result_1 = happy_tt.generate_text(example_1, args=beam_settings) print(result_1.text)**

结果:这个句子有糟糕的语法和拼写!

示例 2

**example_2 = "grammar: I am enjoys, writtings articles ons AI." result_2 = happy_tt.generate_text(example_2, args=beam_settings) print(result_2.text)**

结果:我喜欢写关于人工智能的文章。

后续步骤

有一些方法可以潜在地提高性能。我建议将一些评估案例转移到训练数据中,然后通过应用网格搜索之类的技术来优化超参数。然后,您可以将评估案例包括在训练集中,以使用您的最佳超参数集来微调最终模型。

我还建议您应用基本的数据预处理。数据集中的某些案例包含多余的空间,如果不进行更正,模型将在不需要的时候生成空间。因此,您可以应用下面的代码来更正训练和评估数据的输入和输出文本。

**replacements = [
  (" .", "."), 
  (" ,", ","),
  (" '", "'"),
  (" ?", "?"),
  (" !", "!"),
  (" :", "!"),
  (" ;", "!"),
  (" n't", "n't"),
  (" v", "n't"),
  ("2 0 0 6", "2006"),
  ("5 5", "55"),
  ("4 0 0", "400"),
  ("1 7-5 0", "1750"),
  ("2 0 %", "20%"),
  ("5 0", "50"),
  ("1 2", "12"),
  ("1 0", "10"),
  ('" ballast water', '"ballast water')
]

def remove_excess_spaces(text):
  for rep in replacements:
    text = text.replace(rep[0], rep[1])

  return text**

现在,在 generate_csv()函数的底部进行以下更改。

**input_text = remove_excess_spaces(input_text)
correction = remove_excess_spaces(correction)
writter.writerow([input_text, correction])**

最后,您可以保存您的模型,并在其他时间加载它,如本网页所述。

测试你的技能:

你可以微调一个语法纠正模型,上传到 Hugging Face 的模型分发网络,增强学习。特别是,我建议你考虑使用谷歌新发布的语法纠错数据集,名为 C4_200M 语法纠错合成数据集 [3]*。然后,跟随这个教程在你训练完一个模特后,如何上传一个模特到拥抱脸的模特分销网络。

如果您使用本教程中讨论的技术发布了一个模型,请给我发电子邮件(eric@vennify.ca)。我可能会发表一篇如何使用它的文章。

*许可证: 知识共享署名 4.0 国际

预训练模型

在 Hugging Face 的模型发布网络上发布了一个模型,使用了本教程中介绍的数据集和技术。我还应用了后续步骤部分中的建议。我在下面包含了演示如何使用它的代码。

**happy_tt = HappyTextToText("T5", "vennify/t5-base-grammar-correction")

result = happy_tt.generate_text("grammar: I boughts ten apple.", args=beam_settings)print(result.text)**

结果:我买了十个苹果。

结论:

我希望你把你学到的东西应用到训练你自己的模型上,然后通过在拥抱脸的模型发布网络上发布给全世界。通过这样做,您将帮助许许多多渴望实现高质量语法纠正模型的人。或者,您可能只是滚动到本文的底部,以了解如何实现预训练模型。无论如何,希望你学到了有用的东西,并保持快乐!

资源

快乐变形金刚的 GitHub 页面

订阅我的 YouTube 频道观看即将发布的语法纠正视频。

加入 Happy Transformer 的 Discord 社区进行交流,并向阅读过这篇文章并对 NLP 充满热情的人提问

本教程中使用的代码

参考

[1] C .纳波莱斯,k .坂口,j .泰特劳特, JFLEG:一个流利度语料库和语法纠错的基准,EACL 2017

[2] C .纳波莱斯,k .坂口,m .波斯特,j .泰特劳特,语法纠错度量的基础真理,IJCNLP 2015

[3] F. Stahlberg,S. Kumar,利用标记的讹误模型进行语法纠错的合成数据生成,ACL 2021

原载于 2021 年 8 月 18 日https://www . venni fy . ai**

针对情感分类任务微调“LaBSE”

原文:https://towardsdatascience.com/fine-tuning-labse-for-a-sentiment-classification-task-56e34b74e655?source=collection_archive---------27-----------------------

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

照片由丹尼斯·莱昂Unsplash 上拍摄

一些背景

多语言语言模型(让我们称之为“MLM ”)由于其提供多语言单词嵌入(或句子、文档等)的能力,近来已经成为 NLP 领域的趋势。)在单个模型内。“预训练”是与 MLMs 一起出现的另一个术语,它告诉我们,模型已经在不同领域的大型语料库上训练过,因此我们不必从头开始再次训练它们,但我们可以针对所需的目标任务“微调”它们,同时利用来自预训练知识的“知识转移(转移学习)”。传销主要由谷歌、脸书、百度等科技巨头发布供公众使用,因为他们有资源来训练这些具有数百万、数十亿甚至数万亿参数的大型模型。LaBSE[1]就是 Google 发布的这样一个模型,基于 BERT 模型。

LaBSE 或“语言不可知的 BERT 句子嵌入”专注于双文本挖掘、句子/嵌入相似性任务。它使用“单词块”标记化,可以为 109 种语言生成句子嵌入([CLS]标记从模型的最终层嵌入表示句子嵌入)。虽然,他们还没有报道该模型在其他下游任务如分类或命名实体识别(NER)中的性能,也没有太多用于这类下游任务。LaBSE 的架构是一个“双编码器”模型(带附加余量 Softmax 的双向双编码器),这意味着它有两个基于“BERT-base”模型编码器的编码器模块。这两个编码器分别对源句子和目标句子进行编码,并提供给一个评分函数(余弦相似度)来对它们的相似度进行排序。LaBSE 的训练损失函数就是建立在这个评分的基础上的,这个评分就是前面提到的“加性边际 Softmax”。

设置事物

(我会尽量保持简单,同时包括重要的观点)LaBSE 的官方或原始模型由作者发布到“tensor flow Hub”(https://www.tensorflow.org/hub/),我将使用它。该模块依赖于 Tensorflow (2.4.0+将是伟大的,我正在使用 2.5.0)有其他必要的库,他们可以使用 pip 安装。

注意: 到目前为止(据我所知)Conda 环境不支持 tfhub 模型+ GPU。如果您尝试使用这样的设置,它将总是(自动)退回到 Tensorflow 的 CPU 版本或抛出错误。因此,如果使用 GPU,Conda 应该不在考虑范围内。()https://github.com/tensorflow/text/issues/644

首先,需要安装一些必要的库,(我用的是 Ubuntu 机器)

!pip install tensorflow-hub!pip install tensorflow-text # Needed for loading universal-sentence-encoder-cmlm/multilingual-preprocess!pip install tf-models-official

我们可以进口它们,

import tensorflow as tfimport tensorflow_hub as hubimport tensorflow_text as text from official.nlp import optimization 

显然,如果需要的话,你也应该导入其他的公共库(numpy,pandas,sklearn ),我不会在这里提到。

对于分类任务,我们可以使用预先训练的 109 种语言的任何标记数据集(或者也可以是不支持的,这没有关系!但是有一些性能下降)。我们要做的是对模型进行微调,即使用额外的数据集(与庞大的预训练数据集或语料库相比,较小的数据集)训练预训练模型,以便将模型微调到我们特定的分类(或任何其他)任务。作为起点,我们可以使用 IMDb 电影评论数据集。(https://ai.stanford.edu/~amaas/data/sentiment/)。因此,我们的任务将变成“二元情感分类”任务。数据集由 25k 训练和 25k 测试数据组成。

!wget -c [https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz](https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz) -O — | tar -xzAUTOTUNE = tf.data.AUTOTUNE
batch_size = 32 #8 #16
seed = 42raw_train_ds = tf.keras.preprocessing.text_dataset_from_directory(
 ‘aclImdb/train’,
 batch_size=batch_size,
 validation_split=0.2,
 subset=’training’,
 seed=seed)class_names = raw_train_ds.class_names
train_ds = raw_train_ds.cache().prefetch(buffer_size=AUTOTUNE)val_ds = tf.keras.preprocessing.text_dataset_from_directory(
 ‘aclImdb/train’,
 batch_size=batch_size,
 validation_split=0.2,
 subset=’validation’,
 seed=seed)val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)test_ds = tf.keras.preprocessing.text_dataset_from_directory(
 ‘aclImdb/test’,
 batch_size=batch_size)test_ds = test_ds.cache().prefetch(buffer_size=AUTOTUNE)

我们可以使用 Tensorflow 构建的数据管道作为输入数据。(如果使用 TF 的早期版本,该功能可能无法完全或至少不能直接使用。).接下来,我们需要“预处理”这些数据,然后输入到我们将要构建的模型中。之后,预处理的数据可以被编码或嵌入向量空间。为此,我们可以定义以下变量,我们将使用 LaBSE 的版本 2(https://tfhub.dev/google/LaBSE/2,版本 1 是发布到 TFhub 的初始模型)

tfhub_handle_preprocess=”[https://tfhub.dev/google/universal-sentence-encoder-cmlm/multilingual-preprocess/2](https://tfhub.dev/google/universal-sentence-encoder-cmlm/multilingual-preprocess/2)"
tfhub_handle_encoder=”[https://tfhub.dev/google/LaBSE/2](https://tfhub.dev/google/LaBSE/2)"

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

照片由斯蒂夫·约翰森Unsplash 上拍摄

建立模型

接下来,我们可以建立模型。下面,已经定义了一个函数来建立具有一些特定层的模型。

def build_classifier_model():
 text_input = tf.keras.layers.Input(shape=(), dtype=tf.string, name=’text’)
 preprocessing_layer = hub.KerasLayer(tfhub_handle_preprocess, name=’preprocessing’)
 encoder_inputs = preprocessing_layer(text_input)
 encoder = hub.KerasLayer(tfhub_handle_encoder, trainable=True, name=’LaBSE_encoder’)
 outputs = encoder(encoder_inputs)
 net = outputs[‘pooled_output’]
 net = tf.keras.layers.Dropout(0.1)(net)
 net = tf.keras.layers.Dense(1, name=’classifier’)(net)
 return tf.keras.Model(text_input, net)

你可以注意到模型中有一个术语“pooled_outputs ”,它指的是本文前面提到的句子的[CLS]令牌表示。(另一种输出形式是‘sequence _ outputs’)。编码器层上的“trainable = True”参数或标志意味着,在不使用数据集进行微调的同时,我们也可以更新原始模型的权重/参数的权重。(这也被称为“全局微调”)。

encoder = hub.KerasLayer(tfhub_handle_encoder, trainable=True, name=’LaBSE_encoder’)

net = outputs[‘pooled_output’]

如果我们希望保持原始模型的权重不变,那么它将被称为“基于特征的微调”或“固定维度方法”(在文献中有不同的术语)。此外,在充当模型的分类器层的编码器(下降和密集)之后添加了一些附加层。这是在文献中经常发现的这种分类的组合。

对于优化器,Adam 或 AdamW(更多)是首选,我们可以像下面这样设置。基于数据集或任务,学习率可能会改变(在大多数情况下会降低)。Keras(https://keras.io/guides/keras_tuner/)或类似“Wandb”(https://wandb.ai/site)的服务中已经提供的超参数优化方法也可用于寻找最佳参数,如学习速率和批量大小。

from tensorflow_addons.optimizers import AdamW
step = tf.Variable(0, trainable=False)
schedule = tf.optimizers.schedules.PiecewiseConstantDecay(
 [1000], [5e-5,1e-5])
lr = 1 * schedule(step)
wd = lambda: 1e-6 * schedule(step)
optimizer=AdamW(learning_rate=lr,weight_decay=wd)

接下来,可以用 mode.fit()方法对模型进行编译和训练。

classifier_model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
 optimizer=optimizer,
 metrics=tf.keras.metrics.BinaryAccuracy(threshold=0.0))history = classifier_model.fit(train_ds,validation_data=val_ds,
                               epochs=epochs, batch_size=32)

时期的数量可以设置为 3、4 或 5,这通常是足够的。我们也可以包括像“提前停止”这样的方法。对这样的大型模型使用“K-Fold 交叉验证”并不常见。相反,我们可以对输入数据选择使用不同的随机种子多次运行这个模型。从模型中构建、运行和获得结果是相当容易的。经过训练的模型可以被保存并用于预测新的数据等。如张量流模型通常所做的那样。

在我看来,与 XLM-R、等模型相比,LaBSE 模型在文本分类等任务上可能表现不佳,因为 LaBSE 最初是为双文本挖掘或句子相似性任务而构建和训练的,为了获得更好的结果,可能需要更多的训练数据(微调数据)。LaBSE 在文献中也没有太多用于分类任务(根据我的知识和论文本身对谷歌学术的 38 次引用)。对于这里的任务,我获得了略高于 50%的准确度、精确度、召回率和 f1 分数。这也是用一些随机选择的超参数完成的,因此如果超参数也被改变/调整,结果可能会得到改善。(使用 LaBSE 版本 1(https://medium . com/swlh/language-agnostic-text-classification-with-LaBSE-51 a4 f 55 dab 77)进行了一些类似的工作,但是使用了更大的训练数据集。)

无论如何,我希望听到反馈,评论或其他人的经验。所以。请随意评论您的想法和建议。感谢阅读!!!

https://github.com/VinuraD

参考文献

[1] —语言不可知的伯特语句嵌入,冯,杨,丹尼尔 Cer,纳文阿里瓦扎甘,,arXiv:2007.01852 v1【cs .CL]

微调语言模型容易乱说

原文:https://towardsdatascience.com/fine-tuning-language-models-the-easy-way-with-blather-870002312185?source=collection_archive---------14-----------------------

一个开源库,用几行代码训练和使用生成文本模型

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

赛义德·卡里米在 Unsplash 上的照片

如果您想跳过这一步,只看如何微调您自己的数据集,您可以跳过本文的其余部分,只查看 colab 笔记本!

https://github.com/bigthonk/blather

做客座演讲是我最喜欢的事情之一;没有任何责任的教学乐趣。我在讲座中的目标是让学生对机器学习感到兴奋,让他们玩实际的例子,然后走开。

本周,我有机会与亚利桑那大学网络项目的一些学生谈论机器学习。在一项关于问题的课前调查中,班上学生确定的一个主要问题是高保真机器人的威胁,这些机器人能够影响社交媒体上的对话。

创建能够影响选举或传播虚假信息的僵尸网络是一项范围广泛得多的任务,无论是从传播此类信息的道德问题还是从复杂性来看,都不是一个班级能够完成的。作为简单的第一步,我们可以从讨论如何让一个机器人用合适的内容和风格来表达帖子开始。这个子任务可以通过使用微调的自然语言模型来完成。像 GPT 家族,XLNet,或者我们芝麻街的朋友,BERT 和 ELMo 这样的语言模型,对于大多数个人来说,都是超出从头训练范围的强大模型。令人欣慰的是,开源社区已经加快步伐,开发了预先训练的模型,允许我们这些无法访问重要数据和计算的人进行实验。

不幸的是,这些模型的直接应用将提供对我们的开源朋友训练它们的训练数据集有强烈偏见的解决方案。对于我们提出的僵尸网络应用程序,这将使我们很难获得与我们试图模仿的理想人格接近的帖子。为了克服这个缺点,我们采用了一种称为微调的方法。微调模型是指采用在大型数据集上训练的模型,并在具有更好的样式和内容适用性的较小数据集上对模型进行一些部分再训练。这种方法允许我们使用模型,否则由于缺乏数据或计算资源,我们很难进行计算训练。

在这里,我遇到了一个问题,我想向学生介绍一些自然语言模型的高级概念,并给他们一些工具来训练和试验他们自己的模型,而不会让他们厌烦或以压倒性的方式暴露所有的细节。如果有一个简单的库,允许我训练模型,然后使用它们生成文本,而不必了解表面下发生的许多事情,那该多好。

这让我开发了 agough,这是一个简单的抽象库,位于奇妙的 huggingface 库之上。https://huggingface.co/

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

废话基本上就是这样,你的选择更少

ough 允许用户从文本文件中读取数据集,并训练模型(目前只支持 GPT-2,但我计划在未来添加对其他模型的支持),然后用户可以根据需要从模型中生成样本或保存/加载模型。

第一步。安装乱说

!pip install blather

第二步。进口废话

from blather import Blather

第三步。创建一个乱说对象

blather = Blather()

第四步。阅读一些文本

blather.read("prince.txt")

这将产生一个训练时间估计,并最终产生一些训练统计。您可以选择传递一个具有所需周期数的历元参数,因为它默认为仅训练一个历元。

Training...
Estimated Training time of 3 minutes 
Running Validation...
  Validation Loss: 1.62[{'Training Loss': 2.586719648164395,
  'Valid. Loss': 1.6193444598011855,
  'epoch': 1}]

第五步。写一些文字

blather.write("The fool was known to blather about")

这将调用模型为我们的提示文本生成一个结尾,在这种情况下,我们的马基雅维利式机器人说…

The fool was known to blather about it at every time, and I never heard a word of it," said the pope to Olivertronicus in the year 1543

摘要

我写乱说是为了给那些对微调自己的语言模型感兴趣,但又不想太深入了解这样做的细节的人提供帮助。我希望它对一些人有帮助,或者至少有娱乐性。如果你对这个项目感兴趣,或者只是想谈谈数据科学或 ML,请联系我们。

用于句子蕴含的微调预训练转换器模型

原文:https://towardsdatascience.com/fine-tuning-pre-trained-transformer-models-for-sentence-entailment-d87caf9ec9db?source=collection_archive---------7-----------------------

在 MultiNLI 数据集上微调 BERT 的 PyTorch 和 Hugging Face 实现

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

图片来自 PNGWING

在本文中,我将描述使用 MultiNLI 数据集(Bowman et al. 通过推理理解句子的大范围挑战语料库)对诸如 BERT 和 ALBERT 之类的预训练模型进行微调的过程。模型将使用拥抱人脸库加载,并使用 PyTorch 进行微调。

什么是蕴涵?

为了理解蕴涵,让我们从一个例子开始。
1。吉姆每天早上骑自行车去上学。
2。吉姆会骑自行车。

如果一个提出的前提是真的,就产生了蕴涵。在这个例子中,如果句子“吉姆每天早上骑自行车去上学。”是真的,那么前提是吉姆每天早上都去上学,吉姆也知道如何骑自行车。因此,这将使第二句话,或假设,也为真。

用简单的术语来定义蕴涵,如果 X 为真并且 Y 可以从其逻辑上导出,那么一个句子 Y 被称为蕴涵句子 X 。对于我使用的数据集,一对句子可以是相互依存的,可以是中性的,也可以是相互矛盾的——下一节将详细介绍数据集。

MultiNLI 数据集

多体裁自然语言推理(MultiNLI)语料库是一种设计用于开发和评估机器学习模型以理解句子的数据集。它有超过 433,000 个示例,是可用于自然语言推理(也称为识别文本蕴涵)的最大数据集之一。该数据集的设计还使得在斯坦福 NLI 语料库上训练的现有机器学习模型也可以使用 MultiNLI 进行评估。你可以在论文中了解更多关于这个数据集的信息——一个通过推理理解句子的覆盖面广的挑战语料库

作为训练过程的一部分,数据集中考虑了 3 列—“gold _ label”、“句子 1”(前提)和“句子 2”(假设)。“gold_label”是指示给予这对句子的标签的列。有三个标签——“蕴含”、“中性”和“矛盾”
训练集有 392702 个样本,验证集还剩 10000 个样本。

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

训练集。图片由作者提供。

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

验证集。图片由作者提供。

模特——伯特

BERT(Transformers 的双向编码器表示)是 Google 基于这篇论文中介绍的编码器-解码器 transformer 模型的语言模型。它使用变形金刚的注意力机制来学习单词的上下文含义以及它们之间的关系。伯特,以及它的改型如艾伯特罗伯塔等。在诸如问答和自然语言推理的各种自然语言处理任务上取得了最先进的结果。

与定向长短期记忆网络不同,变压器编码器一次读取整个单词序列。这使得模型可以根据一个单词的所有环境来学习它的上下文。转换器的编码器模块将令牌序列作为输入。这些首先被嵌入到向量中,并通过前馈神经网络进行反馈。这个神经网络的输出是一个向量序列,每个向量对应于一个给定索引的输入序列。

虽然我不会详细说明 BERT 的训练过程,但是你可以阅读这篇文章来获得关于它的工作以及训练它的程序的详细描述。

微调伯特

最后,进入使用拥抱脸和 PyTorch 微调预训练 BERT 模型的过程。在这个例子中,我使用了“bert-base”模型。由于计算限制和 Google Colab 上的训练时间,这是在从原始训练集中采样的 100,000 个训练样本上训练的。

第一步涉及到创建一个 DataLoader 对象来为模型提供数据。用于序列分类的 BERT 要求数据以一定的格式排列。每个句子的开始需要有一个***【CLS】标记存在,句子的结束需要一个【SEP】标记。因此,对于由两个句子组成的序列,需要将其格式化为【CLS】句子 1【SEP】句子 2【SEP】***。此外,每个序列都需要有与之相关联的 segment _ ids。序列中的第一句用[0]标记,第二句用[1]标记。最后,每个序列都需要一个注意力屏蔽来帮助模型确定输入序列的哪一部分不是填充的一部分。

创建 DataLoader 对象

既然已经创建了定型集和验证集的 DataLoader 对象,那么就可以加载模型及其优化器了。对于这种情况,我将使用 BertForSequenceClassification 预训练模型。这个模型提供了一个额外的参数来添加一个可选的分类头和所需数量的标签。对于这种情况,有三个类。因此,我将 num_labels 设置为 3。这增加了一个具有三个输出单元的分类头作为最终层。

加载预训练模型

既然已经加载了模型,那么是时候进入训练和验证循环了。作为训练过程的一部分,该模型被微调了 5 个时期。

培训和验证循环

定义了训练和验证循环后,我们可以在 MultiNLI 数据集上调整模型,以尝试实现预期的性能。

Epoch 1: train_loss: 0.5973 train_acc: 0.7530 | val_loss: 0.5398 val_acc: 0.7836 01:47:59.10 
Epoch 2: train_loss: 0.3623 train_acc: 0.8643 | val_loss: 0.5222 val_acc: 0.8072 01:48:18.70 
Epoch 3: train_loss: 0.2096 train_acc: 0.9256 | val_loss: 0.6908 val_acc: 0.7939 01:48:11.29 
Epoch 4: train_loss: 0.1295 train_acc: 0.9558 | val_loss: 0.7929 val_acc: 0.7891 01:47:59.77 
Epoch 5: train_loss: 0.0916 train_acc: 0.9690 | val_loss: 0.8490 val_acc: 0.7906 01:47:52.39

从上面的损失和精度值可以看出,模型似乎在学习,同时有点过度拟合。这可以通过用更多的数据而不是采样的 100,000 个样本进行训练来解决。

感谢您阅读本文!这个项目的全部代码,以及其他模型基准,可以在https://github.com/dh1105/Sentence-Entailment找到。

参考

  1. 通过推理理解句子的大范围挑战语料库
  2. 伯特:用于语言理解的深度双向转换器的预训练
  3. 注意力是你所需要的一切
  4. ALBERT:一个用于语言表达自我监督学习的 Lite BERT】
  5. RoBERTa:一种稳健优化的 BERT 预训练方法
  6. https://towards data science . com/Bert-explained-state-of-art-state-language-model-for-NLP-F8 b 21 a9 b 6270

使用 Huggingface 的训练器微调预训练的 NLP 模型

原文:https://towardsdatascience.com/fine-tuning-pretrained-nlp-models-with-huggingfaces-trainer-6326a4456e7b?source=collection_archive---------3-----------------------

无需原生 Pytorch 或 Tensorflow 即可微调预训练 NLP 模型的简单方法

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

克里斯托夫·高尔在 Unsplash 上拍摄的照片

动机:在参加一个数据科学竞赛时,我正在微调一个预先训练好的模型,并意识到使用原生 PyTorch 或 Tensorflow 来微调一个模型是多么乏味。我用 Huggingface 的训练器 API 进行了实验,并对它的简单程度感到惊讶。由于网上关于如何使用 Huggingface 的训练器 API 的例子很少,我希望提供一个简单的例子,说明如何使用训练器来微调你的预训练模型。

在我们开始之前,这里有一些理解本文的先决条件:

  1. 对 Python 的中级理解
  2. 对训练神经网络模型的基本理解
  3. 对迁移学习的基本理解

为了节省您的时间,我将只为您提供代码,这些代码可用于使用训练器 API 来训练和预测您的模型。然而,如果你有兴趣了解它是如何工作的,请继续阅读。

步骤 1: 初始化预训练模型和记号赋予器

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

代码所基于的示例数据集

在上面的代码中,使用的数据是 IMDB 电影情感数据集。这些数据允许我们训练一个模型来检测电影评论的情绪- 1 是积极的,而 0 是消极的。这是序列分类的 NLP 任务,因为我们想要将每个评论(文本序列)分类为正面或负面。

有许多预训练的模型可以用来训练我们的情感分析模型,让我们以预训练的 BERT 为例。预训练的 BERT 模型有很多变体, bert-base-uncased 只是其中一种变体。你可以从拥抱面部模型页面搜索更多预训练模型。

model_name = "bert-base-uncased"
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name, num_labels=2)

由于我们使用的是预训练模型,我们需要确保输入数据的形式与预训练模型的训练形式相同。因此,我们需要使用模型的名称来实例化记号赋予器。

既然已经初始化了模型和记号化器,我们可以继续预处理数据了。

步骤 2: 使用预训练的标记器预处理文本

X_train_tokenized = tokenizer(X_train, padding=True, truncation=True, max_length=512)
X_val_tokenized = tokenizer(X_val, padding=True, truncation=True, max_length=512)

让我们使用前面初始化的标记器对文本进行预处理。

我们用于标记器的输入文本是一个字符串列表。

我们已经设置了padding=True, truncation=True, max_length=512,这样我们可以为模型获得相同长度的输入——长文本将被截断为 512 个标记,而短文本将添加额外的标记,使其成为 512 个标记。

使用 512 个令牌,因为这是 BERT 模型可以采用的最大令牌长度。

对文本进行标记后,您将得到一个包含 3 个键的 python 字典:

  1. 输入标识
  2. 令牌类型标识
  3. 注意 _ 屏蔽

步骤 3: 创建 torch 数据集

训练器 API 要求模型在**torch.utils.data.Dataset** 类中。因此,我们需要创建一个从 torch Dataset 类继承的新类。

在继承的类中,我们需要有__getitem____len__方法,它们允许训练器创建批量数据并分别获得长度。

class Dataset(torch.utils.data.Dataset):    
    def __init__(self, encodings, labels=None):          
        self.encodings = encodings        
        self.labels = labels

    def __getitem__(self, idx):
        item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
        if self.labels:
            item["labels"] = torch.tensor(self.labels[idx])
        return item def __len__(self):
        return len(self.encodings["input_ids"])train_dataset = Dataset(X_train_tokenized, y_train)
val_dataset = Dataset(X_val_tokenized, y_val)

将默认 labels 参数设置为 None 的目的是,我们可以重用该类来预测看不见的数据,因为这些数据没有标签。

__getitem__方法基本上为每个文本返回一个值字典。通过运行该方法,当在训练过程中批量处理数据时,它为每个文本创建一个带有input_idsattention_masktoken_type_ids的字典。

__len__方法需要返回输入数据的长度。

步骤 4: 定义培训参数和培训师

def compute_metrics(p):    
    pred, labels = p
    pred = np.argmax(pred, axis=1)
    accuracy = accuracy_score(y_true=labels, y_pred=pred)
    recall = recall_score(y_true=labels, y_pred=pred)
    precision = precision_score(y_true=labels, y_pred=pred)
    f1 = f1_score(y_true=labels, y_pred=pred) return {"accuracy": accuracy, "precision": precision, "recall": recall, "f1": f1} # Define Trainer
args = TrainingArguments(
    output_dir="output",
    evaluation_strategy="steps",
    eval_steps=500,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=3,
    seed=0,
    load_best_model_at_end=True,)
trainer = Trainer(
    model=model,
    args=args,
    train_dataset=train_dataset,
    eval_dataset=val_dataset,
    compute_metrics=compute_metrics,
    callbacks=[EarlyStoppingCallback(early_stopping_patience=3)],)

# Train pre-trained model
trainer.train()

这就是培训师功能的神奇之处。我们可以在 TrainingArguments 和 Trainer 类中定义训练参数,也可以用一个命令训练模型。

我们需要首先定义一个函数来计算验证集的指标。由于这是一个二元分类问题,我们可以使用准确度、精确度、召回率和 f1 分数。

接下来,我们在 TrainingArgs 和 Trainer 类中指定一些训练参数,设置预训练模型、训练数据和评估数据。

在我们定义了参数之后,只需运行trainer.train()来训练模型。

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

培训师的培训示例

**第五步:**进行预测

# Tokenize test data
X_test_tokenized = tokenizer(X_test, padding=True, truncation=True, max_length=512) # Create torch dataset
test_dataset = Dataset(X_test_tokenized) # Load trained model
model_path = "output/checkpoint-50000"
model = BertForSequenceClassification.from_pretrained(model_path, num_labels=2) # Define test trainer
test_trainer = Trainer(model) # Make prediction
raw_pred, _, _ = test_trainer.predict(test_dataset) # Preprocess raw predictions
y_pred = np.argmax(raw_pred, axis=1)

训练完模型后,我们对测试数据重复相同的步骤:

  1. 使用预训练的标记器标记测试数据
  2. 创建 torch 数据集
  3. 负载训练模型
  4. 定义培训师

要从前面的步骤中加载已训练模型,请将 model_path 设置为包含已训练模型权重的路径。

为了进行预测,也只需要一个命令test_trainer.predict(test_dataset)

做了一个预测之后,你只会得到原始的预测。将它转换成可用的格式需要额外的预处理步骤。

因为这个任务只是一个简单的序列分类任务,所以我们可以只获得轴 1 上的 argmax。请注意,其他 NLP 任务可能需要不同的方式来预处理原始预测。

我希望这篇文章将有助于简化你微调预训练 NLP 模型的过程。请随意阅读官方的 Huggingface 文档,以更好地理解代码并了解它还能做什么。

Edit 1 (23/6/21): Removed save_steps parameter from TrainingArgument as it is ignored when load_best_model_at_end is set to True. Thanks 杨程 for the feedback!

参考

[1]https://huggingface.co/transformers/training.html

[2]https://hugging face . co/transformers/main _ classes/trainer . html

文本摘要 BART 大模型的优化

原文:https://towardsdatascience.com/fine-tuning-the-bart-large-model-for-text-summarization-3c69e4c04582?source=collection_archive---------1-----------------------

微调模型以总结世界新闻

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

来源:https://unsplash.com/photos/Mwuod2cm8g4

据《大西洋月刊》T4 报道,纽约时报每天发表 150 多篇文章,周日发表 250 多篇。《华尔街日报》每天刊登大约 240 篇报道。其他网站,如 Buzzfeed,每月发布 6000 多篇报道。

随着信息量的增加,摘要成为机器学习/自然语言处理(NLP)中一项非常受欢迎的任务也就不足为奇了。

总结有两种主要方法。第一种,抽取摘要,旨在识别最重要的句子,并使用那些精确的句子作为摘要。

更高级的方法是抽象概括。它包括以一种新的方式解释和总结信息。这是我们将在本文中使用的方法。

BART 大型模型

像任何 NLP 任务一样,存在可以用作起点的高级模型。这里的想法是使用预训练神经网络模型的所有权重,并将其用作初始点,以便加速训练并提高性能。

在本教程中,使用的模型被称为facebook/bart-large-cnn,由脸书开发。它包含 1024 个隐藏层和 406 个参数,并使用 CNN(一个新闻摘要数据集)进行了微调。

如你所见,这个模型非常庞大,所以我建议你使用 Google Colab 来运行代码。它是 100%免费的,并提供轻松访问 GPU,这将加快训练速度。

代码

1.导入和准备数据

让我们从导入数据(并稍微清理一下)以及微调模型所需的库开始。

我将使用可以在这里找到的数据。我将只使用数据集的一小部分来总结被归类为阴谋的新闻。

这里没什么特别的。blurr 库将 huggingface transformer 模型(就像我们使用的那个)与 fast.ai 集成在一起,fast . ai 是一个旨在使深度学习比以往任何时候都更容易使用的库。

正如您在第 22 行看到的,我在本教程中只使用了数据的一个子集,主要是因为内存和时间的限制。这是数据的样子。

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

这里,text 列将被用作我们想要总结的文本,而title列将被用作我们想要获得的目标。

我这样做是因为我没有实际的总结,但如果你有,当然你应该把它作为目标。

2.导入模型

在本节中,我们将导入预先训练的模型,并为训练准备数据。

这里有点复杂,所以让我们一行一行地看一下每件事是怎么做的:

  • 第 2–3 行:这是我们导入预训练 BART 大型模型的地方,我们将对其进行微调。
  • 第 7–15 行:这是处理创建小批量输入和目标的地方。我们还指定了任务是什么,以及一组超参数(在 text_gen_kwargs 字典中)。
  • 第 20 行:这一行包含创建数据集所需的内容。我们在这里提供什么是文本,什么是目标摘要。
  • 第 21 行:我们创建数据集并提供 batch_size。我建议保持这个数字很小,否则你可能会遇到CUDA OUT OF MEMORY错误。

要了解更多关于不同功能和参数的信息,我邀请您查看文档这里这里

3.培养

我们现在可以开始实际训练了。

  • 第 2–9 行:创建一个字典,其中包含一系列性能指标,这些指标将用于在训练期间评估模型。
  • 第 17–19 行:学习函数是我们指定数据、模型和损失函数的地方,这些将用于训练。
  • 第 26 行:使用 1cycle 策略来拟合一个模型,这是在这篇论文中介绍的,旨在使用较大的学习率非常快速地训练神经网络。我们在这一行中指定了历元数(3)和学习率。

4.生成预测

现在让我们看看如何给定一个文本生成摘要。

我只返回一个概要,但是你可以返回多个概要,并从给定的选项中选择最佳的概要。

作为一个例子,这里有一个文本和返回的摘要。

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

这就对了。考虑到我所做的训练是如此之少,仅仅使用了一个非常小的数据集,这是非常令人印象深刻的。当你想对一个给定的主题保持更新,而不需要阅读关于它的所有内容时,你肯定可以看到摘要的用途。

现在,您已经知道如何微调文本摘要的 BART large。非常感谢你的阅读,我希望我能有所帮助!

代码可以在这里找到。

成为会员:https://francoisstamant.medium.com/membership

用于发票识别的微调变压器模型

原文:https://towardsdatascience.com/fine-tuning-transformer-model-for-invoice-recognition-1e55869336d4?source=collection_archive---------5-----------------------

从注释到训练的逐步指南

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

安德烈·波波夫摄于 Dreamstime

介绍

基于我最近关于如何为 NLP 应用注释 pdf 和扫描图像的教程,我们将尝试在一个包含法语和英语发票的注释定制数据集上微调最近发布的微软布局 LM 模型。虽然之前的教程侧重于使用公开可用的 FUNSD 数据集来微调模型,但这里我们将展示从注释和预处理到训练和推理的整个过程。

LayoutLM 模型

LayoutLM 模型基于 BERT 架构,但增加了两种类型的输入嵌入。第一种是 2d 位置嵌入,表示文档内标记的相对位置,第二种是文档内扫描标记图像的图像嵌入。该模型在几个下游任务中取得了新的最先进的结果,包括表单理解(从 70.72 到 79.27)、收据理解(从 94.02 到 95.24)和文档图像分类(从 93.07 到 94.42)。有关更多信息,请参考原文

幸运的是,这个模型是开源的,可以在 huggingface 库中获得。谢谢微软!

对于本教程,我们将直接从 huggingface 库中克隆模型,并在我们自己的数据集上对其进行微调,下面是 google colab 的链接。但是首先,我们需要创建训练数据。

https://colab . research . Google . com/drive/1 nkvuyw 6 ne 25 hoz _ IApiv _ miyb 4 LX caq?usp =共享

发票注释

使用 UBIAI 文本注释工具,我已经注释了大约 50 张个人发票。我对提取实体的键和值感兴趣;例如,在下面的文本“日期:06/12/2021”中,我们会将“日期”注释为 DATE_ID,将“06/12/2021”注释为 Date。提取键和值将有助于我们将数值与它们的属性相关联。以下是所有已被注释的实体:

DATE_ID, DATE, INVOICE_ID, INVOICE_NUMBER,SELLER_ID, SELLER, MONTANT_HT_ID, MONTANT_HT, TVA_ID, TVA, TTC_ID, TTC

以下是一些实体定义:

MONTANT_HT: Total price pre-taxTTC: Total price with taxTVA: Tax amount

以下是使用 UBIAI 的注释发票示例:

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

作者图片:带注释的发票

标注后,我们直接从 UBIAI 中以正确的格式导出训练和测试文件,没有任何预处理步骤。导出将包括每个训练和测试数据集的三个文件,以及一个包含所有名为 labels.txt 的标签的文本文件:

培训/测试. txt

2018	O
Sous-total	O
en	O
EUR	O
3,20	O
€	O
TVA	S-TVA_ID
(0%)	O
0,00 €	S-TVA
Total	B-TTC_ID
en	I-TTC_ID
EUR	E-TTC_ID
3,20	S-TTC
€	O
Services	O
soumis	O
au	O
mécanisme	O
d'autoliquidation	O
-	O

Train/Test_box.txt(包含每个令牌的边界框):

€	912 457 920 466
Services	80 486 133 495
soumis	136 487 182 495
au	185 488 200 495
mécanisme	204 486 276 495
d'autoliquidation	279 486 381 497
-	383 490 388 492

Train/Test_image.txt(包含边界框、文档大小和名称):

€ 912 425 920 434 1653 2339 image1.jpg
TVA 500 441 526 449 1653 2339  image1.jpg
(0%) 529 441 557 451 1653 2339  image1.jpg
0,00 € 882 441 920 451 1653 2339  image1.jpg
Total 500 457 531 466 1653 2339  image1.jpg
en 534 459 549 466 1653 2339  image1.jpg
EUR 553 457 578 466 1653 2339  image1.jpg
3,20 882 457 911 467 1653 2339  image1.jpg
€ 912 457 920 466 1653 2339  image1.jpg
Services 80 486 133 495 1653 2339  image1.jpg
soumis 136 487 182 495 1653 2339  image1.jpg
au 185 488 200 495 1653 2339  image1.jpg
mécanisme 204 486 276 495 1653 2339  image1.jpg
d'autoliquidation 279 486 381 497 1653 2339  image1.jpg
- 383 490 388 492 1653 2339  image1.jpg

标签. txt:

B-DATE_ID
B-INVOICE_ID
B-INVOICE_NUMBER
B-MONTANT_HT
B-MONTANT_HT_ID
B-SELLER
B-TTC
B-DATE
B-TTC_ID
B-TVA
B-TVA_ID
E-DATE_ID
E-DATE
E-INVOICE_ID
E-INVOICE_NUMBER
E-MONTANT_HT
E-MONTANT_HT_ID
E-SELLER
E-TTC
E-TTC_ID
E-TVA
E-TVA_ID
I-DATE_ID
I-DATE
I-SELLER
I-INVOICE_ID
I-MONTANT_HT_ID
I-TTC
I-TTC_ID
I-TVA_ID
O
S-DATE_ID
S-DATE
S-INVOICE_ID
S-INVOICE_NUMBER
S-MONTANT_HT_ID
S-MONTANT_HT
S-SELLER
S-TTC
S-TTC_ID
S-TVA
S-TVA_ID

微调 LayoutLM 模型:

在这里,我们使用带有 GPU 的 google colab 来微调模型。以下代码基于原创 layoutLM 论文本教程

首先,安装 layoutLM 包…

! rm -r unilm! git clone -b remove_torch_save https://github.com/NielsRogge/unilm.git! cd unilm/layoutlm! pip install unilm/layoutlm

…以及将从其中下载模型的 transformer 包:

! rm -r transformers! git clone https://github.com/huggingface/transformers.git! cd transformers! pip install ./transformers

接下来,创建一个包含 labels.txt 中唯一标签的列表:

from torch.nn import CrossEntropyLossdef get_labels(path):
    with open(path, "r") as f:
        labels = f.read().splitlines()
    if "O" not in labels:
        labels = ["O"] + labels
    return labelslabels = get_labels("./labels.txt")
num_labels = len(labels)
label_map = {i: label for i, label in enumerate(labels)}
pad_token_label_id = CrossEntropyLoss().ignore_index

然后,创建 pytorch 数据集和数据加载器:

from transformers import LayoutLMTokenizer
from layoutlm.data.funsd import FunsdDataset, InputFeatures
from torch.utils.data import DataLoader, RandomSampler, SequentialSamplerargs = {'local_rank': -1,
        'overwrite_cache': True,
        'data_dir': '/content/data',
        'model_name_or_path':'microsoft/layoutlm-base-uncased',
        'max_seq_length': 512,
        'model_type': 'layoutlm',}# class to turn the keys of a dict into attributes
class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = selfargs = AttrDict(args)tokenizer = LayoutLMTokenizer.from_pretrained("microsoft/layoutlm-base-uncased")# the LayoutLM authors already defined a specific FunsdDataset, so we are going to use this here
train_dataset = FunsdDataset(args, tokenizer, labels, pad_token_label_id, mode="train")
train_sampler = RandomSampler(train_dataset)
train_dataloader = DataLoader(train_dataset,
                              sampler=train_sampler,
                              batch_size=2)eval_dataset = FunsdDataset(args, tokenizer, labels, pad_token_label_id, mode="test")
eval_sampler = SequentialSampler(eval_dataset)
eval_dataloader = DataLoader(eval_dataset,
                             sampler=eval_sampler,
                            batch_size=2)batch = next(iter(train_dataloader))input_ids = batch[0][0]tokenizer.decode(input_ids)

从 huggingface 加载模型。这将在数据集上进行微调。

from transformers import LayoutLMForTokenClassification
import torchdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")model = LayoutLMForTokenClassification.from_pretrained("microsoft/layoutlm-base-uncased", num_labels=num_labels)
model.to(device)

最后,开始训练:

from transformers import AdamW
from tqdm import tqdmoptimizer = AdamW(model.parameters(), lr=5e-5)global_step = 0
num_train_epochs = 50
t_total = len(train_dataloader) * num_train_epochs # total number of training steps#put the model in training mode
model.train()
for epoch in range(num_train_epochs):
  for batch in tqdm(train_dataloader, desc="Training"):
      input_ids = batch[0].to(device)
      bbox = batch[4].to(device)
      attention_mask = batch[1].to(device)
      token_type_ids = batch[2].to(device)
      labels = batch[3].to(device)# forward pass
      outputs = model(input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids,
                      labels=labels)
      loss = outputs.loss# print loss every 100 steps
      if global_step % 100 == 0:
        print(f"Loss after {global_step} steps: {loss.item()}")# backward pass to get the gradients 
      loss.backward()#print("Gradients on classification head:")
      #print(model.classifier.weight.grad[6,:].sum())# update
      optimizer.step()
      optimizer.zero_grad()
      global_step += 1

你应该可以看到训练进度和损失得到更新。

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

图片作者:布局 LM 训练进行中

训练后,使用以下函数评估模型性能:

import numpy as np
from seqeval.metrics import (
    classification_report,
    f1_score,
    precision_score,
    recall_score,
)eval_loss = 0.0
nb_eval_steps = 0
preds = None
out_label_ids = None# put model in evaluation mode
model.eval()
for batch in tqdm(eval_dataloader, desc="Evaluating"):
    with torch.no_grad():
        input_ids = batch[0].to(device)
        bbox = batch[4].to(device)
        attention_mask = batch[1].to(device)
        token_type_ids = batch[2].to(device)
        labels = batch[3].to(device)# forward pass
        outputs = model(input_ids=input_ids, bbox=bbox, attention_mask=attention_mask, token_type_ids=token_type_ids,
                        labels=labels)
        # get the loss and logits
        tmp_eval_loss = outputs.loss
        logits = outputs.logitseval_loss += tmp_eval_loss.item()
        nb_eval_steps += 1# compute the predictions
        if preds is None:
            preds = logits.detach().cpu().numpy()
            out_label_ids = labels.detach().cpu().numpy()
        else:
            preds = np.append(preds, logits.detach().cpu().numpy(), axis=0)
            out_label_ids = np.append(
                out_label_ids, labels.detach().cpu().numpy(), axis=0
            )# compute average evaluation loss
eval_loss = eval_loss / nb_eval_steps
preds = np.argmax(preds, axis=2)out_label_list = [[] for _ in range(out_label_ids.shape[0])]
preds_list = [[] for _ in range(out_label_ids.shape[0])]for i in range(out_label_ids.shape[0]):
    for j in range(out_label_ids.shape[1]):
        if out_label_ids[i, j] != pad_token_label_id:
            out_label_list[i].append(label_map[out_label_ids[i][j]])
            preds_list[i].append(label_map[preds[i][j]])results = {
    "loss": eval_loss,
    "precision": precision_score(out_label_list, preds_list),
    "recall": recall_score(out_label_list, preds_list),
    "f1": f1_score(out_label_list, preds_list),
}

只有 50 个文档,我们得到以下分数:

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

作者图片:培训后的评估分数

注释多了,肯定能得更高的分数。

最后,保存模型以供将来预测:

PATH='./drive/MyDrive/trained_layoutlm/layoutlm_UBIAI.pt'torch.save(model.state_dict(), PATH)

推论:

现在有趣的部分来了,让我们上传一张发票,对其进行 OCR,并提取相关实体。对于此测试,我们使用的发票不在培训或测试数据集中。为了解析发票中的文本,我们使用开源的 Tesseract 包。让我们安装软件包:

!sudo apt install tesseract-ocr!pip install pytesseract

在运行预测之前,我们需要解析图像中的文本,并将标记和边界框预处理为特征。为此,我创建了一个预处理 python 文件 layoutLM_preprocess.py ,这将使预处理图像更加容易:

import sys
sys.path.insert(1, './drive/MyDrive/UBIAI_layoutlm')
from layoutlm_preprocess import *image_path='./content/invoice_test.jpg'image, words, boxes, actual_boxes = preprocess(image_path)

接下来,加载模型并获得单词预测及其边界框:

model_path='./drive/MyDrive/trained_layoutlm/layoutlm_UBIAI.pt'model=model_load(model_path,num_labels)word_level_predictions, final_boxes=convert_to_features(image, words, boxes, actual_boxes, model)

最后,显示带有预测实体和边界框的图像:

draw = ImageDraw.Draw(image)font = ImageFont.load_default()def iob_to_label(label):
  if label != 'O':
    return label[2:]
  else:
    return ""label2color = {'data_id':'green','date':'green','invoice_id':'blue','invoice_number':'blue','montant_ht_id':'black','montant_ht':'black','seller_id':'red','seller':'red', 'ttc_id':'grey','ttc':'grey','':'violet', 'tva_id':'orange','tva':'orange'}for prediction, box in zip(word_level_predictions, final_boxes):
    predicted_label = iob_to_label(label_map[prediction]).lower()
    draw.rectangle(box, outline=label2color[predicted_label]) draw.text((box[0] + 10, box[1] - 10), text=predicted_label, fill=label2color[predicted_label], font=font)image

瞧吧:

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

作者图片:测试发票上的预测

虽然该模型犯了一些错误,如将 TTC 标签分配给购买的商品或不识别某些 id,但它能够正确地提取卖家、发票号码、日期和 TTC。鉴于带注释的文档数量很少(只有 50 个),结果令人印象深刻,非常有希望!有了更多带注释的发票,我们将能够达到更高的 F 分数和更准确的预测。

结论:

总的来说,LayoutLM 模型的结果非常有希望,证明了 transformers 在分析半结构化文本中的有用性。该模型可以在任何其他半结构化文档上进行微调,如驾照、合同、政府文档、财务文档等。

如果您有任何问题,请不要犹豫,在下面提问或发送电子邮件至 admin@ubiai.tools。

如果你喜欢这篇文章,请喜欢并分享!

在 Twitter 上关注我们 @UBIAI5订阅这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值