TowardsDataScience 博客中文翻译 2020(四百六十五)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何与 TPU 合作

原文:https://towardsdatascience.com/how-to-colab-with-tpu-98e0b4230d9c?source=collection_archive---------8-----------------------

在谷歌实验室 TPU 上训练一个拥抱脸伯特

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

TPU 演示通过谷歌云平台博客

TPU(张量处理单元)是专门为处理矩阵而优化的专用集成电路(ASICs)。

云 TPU 资源加速了线性代数计算的性能,线性代数计算在机器学习应用中被大量使用

云 TPU 文档

Google Colab 免费为 TPUs 提供实验支持!在本文中,我们将讨论如何在 Colab 上使用 TPU 训练模型。具体来说,我们将训练 伯特 进行 文本分类使用变形金刚包通过 huggingface 上一个 TPU。

什么时候该用什么时候不该用 TPU

重要的事情先来。由于 TPU 针对一些特定的操作进行了优化,我们需要检查我们的模型是否实际使用了它们;即我们需要检查 TPU 是否真的帮助我们的模型训练得更快。以下是我们可能希望使用云 TPU 文档中提到的 TPU 的一些用例:

  • 由矩阵计算主导的模型
  • 主训练循环中没有自定义张量流运算的模型
  • 训练数周或数月的模特
  • 有效批量非常大的较大和非常大的模型

如果你的模型使用了云 TPU 支持的张量流运算中没有的自定义张量流运算,你可能宁愿使用 GPU 加速器来代替。

初始化

TPU 在云上工作,不像 GPU 或 CPU 在本地工作。因此,我们需要在开始之前进行一些初始化:

TPU 用途的设置

如果您观察上面代码片段的输出,我们的 TPU 集群有 8 个能够并行处理的逻辑 TPU 设备(0–7)。因此,我们定义了一个分布策略,用于在这 8 个设备上进行分布式培训:

strategy = tf.distribute.TPUStrategy(resolver)

有关分布式培训的更多信息,请参考:https://www.tensorflow.org/guide/distributed_training

训练模型

在本节中,我们将实际了解如何在 TPU 上训练 BERT。我们将通过两种方式做到这一点:

  1. 使用 model.fit()
  2. 使用自定义训练循环。

使用 model.fit()

由于我们使用的是分布策略,因此必须在每个设备上创建模型以共享参数。因此,需要在战略范围内创建和构建模型:

在分销战略的范围内创建和构建模型

然后,我们简单地根据数据拟合模型,就像在常规训练设置中所做的那样:

训练模型

要保存模型权重:

model.save_weights("checkpoint/tpu-model.h5")

在下一小节中,我们将讨论如何使用自定义训练循环来做同样的事情。

使用自定义训练循环

这里,我们只需要手动调整 TensorFlow 在前面的方法中在后端为我们做的一些事情。

首先,我们使用 tf.data API 创建一个数据管道:

构建 tf.data 管道

现在,我们在前面的部分中不必担心这个的原因是 TensorFlow 自己处理了这些事情;也就是我们调用 model.fit()的时候。同样,这次,我们需要在 TPU 设备之间手动分发数据集:

在 TPU 之间分配数据

接下来,我们以与前面方法完全相同的方式创建和构建模型。或者,我们可以在策略范围中添加一些指标,用于手动损失和准确性监控:

在战略范围内定义指标

现在是最重要的部分,即训练步骤功能。但是首先,让我们为分布式数据集创建一个迭代器:

train_iterator = iter(train_dataset)

然后我们编写 train_step 函数,并像平常一样用@tf.function 修饰它。我们使用 strategy.run()来执行训练步骤:

训练阶跃函数

最后,我们在训练循环中运行这个 train_step 函数几次:

训练循环

这一次,让我们尝试使用检查点保存模型。现在这里有一个问题。我们不能就这样拯救这个模型。

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

本地文件系统访问错误

错误非常明显,它说急切执行时,您不能访问本地文件系统,因为执行被带到云中,以便 TPU 执行其操作。

因此,为了克服这一点,我们需要将检查点保存在 GCS 桶中。您可以在此创建一个自由级 GCP 账户。首先,我们需要创建一个云存储桶。这里有一个来自官方文档的关于创建 GCS bucket 的教程

接下来,我们需要使用我们的 GCP 凭据登录,并将 GCP 项目设置为活动配置:

from google.colab import authauth.authenticate_user()!gcloud config set project <project-id>

gcloud config set 仅在您的活动配置中设置指定的属性。

谷歌云文档

完成后,我们只需使用以下命令即可访问我们的存储桶:

gs://<bucket-name>/<file-path>

现在,检查点看起来像这样:

保存检查点

而这一次,它会成功地将模型检查点保存到您的桶中!

结论

在本文中,我们看到了为什么以及如何调整为训练模型而编写的原始代码,使其与 TPU 兼容。我们还讨论了什么时候使用 TPU,什么时候不使用。

参考

[## 使用 TPUs | TensorFlow 核心

目前 Keras 和 Google Colab 提供了对云 TPU 的实验性支持。在你运行这个 Colab 之前…

www.tensorflow.org](https://www.tensorflow.org/guide/tpu) [## 每个 ML 从业者必须知道的 10 个张量流技巧

为什么 TensorFlow 是完整的 ML 包

towardsdatascience.com](/10-tensorflow-tricks-every-ml-practitioner-must-know-96b860e53c1) [## 伯特:语言理解变形金刚的前期训练

了解基于变压器的自监督架构

medium.com](https://medium.com/swlh/bert-pre-training-of-transformers-for-language-understanding-5214fba4a9af) [## BERT -变压器 3.0.2 文档

BERT 模型是在 BERT:用于语言理解的深度双向转换器的预训练中提出的…

huggingface.co](https://huggingface.co/transformers/model_doc/bert.html)

如何在本地托管的 Jupyter 笔记本上进行协作

原文:https://towardsdatascience.com/how-to-collaborate-on-your-locally-hosted-jupyter-notebook-28e0dcd8aeca?source=collection_archive---------18-----------------------

让 Jupyter 笔记本协作成为一个无缝的过程

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

约翰·施诺布里奇在 Unsplash 上的照片

背景

不久前,我接到一个正在学习数据科学的好朋友的电话,希望得到一些帮助。由于我们在学习数据科学时经常被告知 Jupyter 笔记本,所以他使用 Jupyter 笔记本并不奇怪,但这立即让我大吃一惊。我们如何在笔记本上合作?

我们最后打了一个缩放电话,他授权我控制他的屏幕,但等待时间比手头的问题更让我抓狂。

两个月过去了,风水轮流转,我现在是需要帮助的人。我联系了一位资深数据科学家(在本文中我们称他为 Billy ),告诉他我的苦恼:

比利:那很好,你想做一些结对编程吗?

我:好的,那太好了。松了一口气

比利:你在用谷歌 Colabs 吗?

注意:事实证明 Colab 非常容易合作。

**我:**不,我在本地使用 Jupyter 笔记本

比利:那很好。我们可以用 Ngrok

我:啊,是的,当然!

老实说,我不知道 Ngrok 是什么,但我相信我的谷歌搜索技能。

:这个解决方案只有在你希望在本地服务器上协作时才有效。如果你希望在云中合作,请查看 土星云

Ngrok

Ngrok 通过安全隧道将 NAT 和防火墙后面的本地服务器暴露给公共互联网。随后,我们能够向 web 服务器的端口提供我们的本地服务器,这使我们能够获得我们指定的本地地址——如果这对您没有意义,请不要担心。我要说的是,我们将获得本地托管的 Jupyter 笔记本的公共 URL,我们可以共享并用于合作。

安装 Ngrok

设置 Ngrok 包括 3 个简单的步骤:

  1. 报名

你可以通过点击“注册”轻松创建一个免费账户。只需填写您的证书,您就可以开始了——链接到注册页面 这里

2.下载

下载适合你的操作系统的 Ngrok,下载后解压。

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

注意:在 Linux 或 Mac OS X 上,您可以使用以下命令从终端解压缩 ngrok。在 Windows 上,只需双击 ngrok.zip 即可将其解压缩。

unzip /path/to/ngrok.zip

3.连接您的帐户

下一步只是验证您的 Ngrok 代理,只需要做一次,因为 Authtoken 保存在默认配置文件中。

您的身份验证令牌可以通过转到边栏上的身份验证,然后转到您的身份验证令牌来访问,见下图。

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

我更喜欢命令行设置,它包括简单地告诉 Ngrok 您的身份验证令牌。

./ngrok authtoken 1g3Zd5XeTdmRTYIvOZmGVBW3hAH_2873ypJDaDf6ybyUzmSUj

太好了!您现在已经设置好了,但是现在您必须学会共享您的 Jupyter 笔记本。

共享笔记本

对于要远程访问的 Jupyter 笔记本,我们必须对我们的 Jupyter 笔记本配置进行一些调整,为了额外的安全性,我们将添加一个密码。

jupyter notebook --generate-config

这将把链接地址返回到 Jupyter 笔记本的配置文件中。

Writing default config to: C:\Users\Kurtis\.jupyter\jupyter_notebook_config.py

复制链接地址并运行以下命令

echo "NotebookApp.allow_remote_access = True" >> C:\Users\Kurtis\.jupyter\jupyter_notebook_config.py

然后我们添加一个密码…

jupyter notebook password

现在,我们已经具备了运行和连接 Jupyter 笔记本所需的一切,这样就可以远程共享它了。

提示:在下一部分中,我们需要两个独立的终端连接到我们的遥控器,因为一旦我们运行 jupyter,它将占用一个记录日志的窗口。您可以打开第二个终端并再次进入 ssh,或者您可以使用类似于 tmux 的工具在单个终端中管理它们。(来源:人工智能 Github )

在你的终端输入jupyter notebook打开你的 Jupyter 笔记本。

jupyter notebook

在我们访问我们的 Jupyter 笔记本之后,我们告诉 Ngrok 我们的 web 服务器正在监听哪个端口。

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

上图突出显示了港口。因此,我们会告诉 Ngrok 端口是 8888。

ngrok http [port] -host-header="localhost:[port]"

您的结果应该如下所示

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

复制转发地址,并与您想与之合作的任何人共享—如果您按照我们的步骤操作并设置了密码,那么您必须告诉他们密码。

太好了,现在你们可以合作了!

但是,如果您希望在云中协作,该怎么办呢?我掩护你。土星云是一个免费可扩展的数据科学平台,专为团队和个人打造。

结论

宏伟!现在,每当您需要与本地机器(或您的机器)上的 Jupyter 笔记本电脑上的某人协作时,您不必被踩踏或忍受糟糕的延迟(因为您已经在 zoom 上共享了您的屏幕),您现在知道如何共享您的 Jupyter 笔记本电脑并在不同的机器上工作。

我喜欢与人交流,我在 LinkedIn 上最容易联系到——联系并了解我正在学习的任何新东西(也可以随意分享你正在学习的东西)。

[## Kurtis Pykes -人工智能作家-走向数据科学| LinkedIn

在世界上最大的职业社区 LinkedIn 上查看 Kurtis Pykes 的个人资料。Kurtis 有一个工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/kurtispykes/)

如何从《纽约时报》的任何一篇文章中收集对熊猫数据框架的评论

原文:https://towardsdatascience.com/how-to-collect-comments-from-any-new-york-times-article-to-a-pandas-dataframe-a595ec6a1ddf?source=collection_archive---------53-----------------------

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

Unsplash视觉的照片

《纽约时报》( NYT)最精彩的部分是他们对文章积极且高度节制的评论部分。

这确实是一个奇妙的社区,来自世界各地的读者都做出了高质量的贡献。24 小时开放评论,由人类高度管理,因此不存在巨魔评论。一个我在其他出版物上看不到复制的社区。

我喜欢 NYT 评论区的是它目前的组织方式。

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

有三个标签,NYT 选择,读者选择,和所有。

  • NYT 选择下,NYT 将突出代表一系列观点的评论,并被认为是关于文章主题的最有趣或最有用的评论。
  • 读者选择,通常按最高社区投票排序。NYT 上的向上投票被视为“推荐”。
  • 使用 All 选项卡,允许您按最新或最早的评论进行排序。

我最近发现纽约时报发布了一个新的 API,目前处于测试阶段,它可以帮助我们轻松地查询这些精彩的评论。

步骤 1:创建一个 NYT 开发者网络帐户来获得你的 API 密匙

  1. 转到https://developer.nytimes.com/
  2. 登录或创建一个帐户
  3. 将鼠标悬停在您的帐户名称上,即可进入应用程序。
  4. 创建新应用程序
  5. 提供名称和描述
  6. 激活社区 API ( 目前处于测试阶段)
  7. 将您的 API 密钥复制到剪贴板以备将来使用

步骤 2:在 Python 中进行设置

注意:我们每天只限 4000 个请求,每分钟 10 个请求。

注意:我们需要指定偏移量,因为每次我们请求 API 时,它一次只会得到 25 条注释。因此,从 25 到 49 的注释需要我们将偏移量设置为 25。

注:对于本教程,我将使用这篇 NYT 文章

一旦获得了数据,这些数据将看起来像这样。

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

您从 NYT 社区 API 中收集的 JSON 数据示例

仅从屏幕截图来看,我们可以很容易地看出,如果我们要制作一个数据集,我们可以尝试一些有趣的功能。

有趣的功能:

  • 备注
  • 用户显示名称
  • 用户位置
  • 评论主体
  • 建议
  • 回复计数
  • 回复
  • 编辑选择
  • 推荐标志
  • 匿名

步骤 3:提取我们想要的数据到熊猫数据框架中

注意:注释位于我们数据的“结果”键中。

第 4 步:简单直观的功能来检索一篇文章的所有评论,包括评论回复。

注意:每次您提交请求时,建议让您的功能等待 6 秒钟,因为我们每分钟仅限 10 个请求。

最终的数据帧将如下所示。

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

质疑 NYT 文章的评论。

但是,NYT 社区 API 有一个单独的请求链接,用于回复特定意见的评论。下面是你如何设置它。

注意:每个请求仍然被限制为一次 25 个评论回复,我们必须指定我们想要从哪个评论中提取回复。为了指定哪个注释,我们需要输入 commentSequence,它与 commentID 相同,这是我目前所了解的。

然而,你将会浪费你当天的请求配额,并且你已经从先前的函数中提取了那些回复,并且那些对你的评论的回复不受父评论限制。

这就对了。现在你知道如何从《纽约时报》的一篇文章中提取所有评论了!

我如何使用 Python 从任何网站收集数据

原文:https://towardsdatascience.com/how-to-collect-data-from-any-website-cb8fad9e9ec5?source=collection_archive---------1-----------------------

用 Python 和 BeautifulSoup 实现简单的网页抓取

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

法比安·伊尔萨拉在 Unsplash 上的照片

在工作中,有些时候你会意识到你可能需要在短时间内获得大量数据。这些可能是当你的老板或客户想要从一个特定的网站得到一组特定的信息。也许他们想让你从上述网站收集一千多条信息或数据。那你是做什么的?

一种选择是查看这个网站,手动输入所需的每一条信息。或者更好的是,您可以让 Python 为您完成所有繁重的工作!

利用 Python 最有用的库之一, BeautifulSoup ,我们可以通过编写一些相对简单的代码来收集任何网站上显示的大多数数据。这个动作叫做。在接下来的几个部分中,我们将学习和解释 BeautifulSoup 的基础知识,以及如何使用它从几乎所有网站收集数据。

在这里注册一个中级会员,可以无限制地访问和支持像我这样的内容!在你的支持下,我赚了一小部分会费。谢谢!

挑战

为了学会如何使用 BeautifulSoup,我们首先要有一个使用它的理由。让我们假设,你有一个客户正在寻找名人的报价。他们希望下一年每周都有新的报价。他们让我们负责向他们展示至少 52 条引文及其作者。

要刮的网站

我们或许可以去任何网站找到这些报价,但我们将使用 这个网站 作为报价列表。现在,我们的客户希望将这些报价格式化成一个简单的电子表格。因此,现在我们可以选择在电子表格中键入 52 条引文及其各自的作者,或者我们可以使用 Python 和 BeautifulSoup 来为我们完成所有这些工作。所以为了时间和简单起见,我们宁愿用 Python 和 BeautifulSoup。

开始美丽的 Soup

让我们从打开你喜欢的 IDE 开始,但是我们将使用 Jupyter Notebook。(所有这些的 Github 代码将在文章的最后提供)。

导入 Python 库

我们将从导入 BeautifulSoup 所需的库开始:

from bs4 import BeautifulSoup as bs
import pandas as pd
pd.set_option('display.max_colwidth', 500)
import time
import requests
import random

访问网站

接下来,我们必须通过运行以下代码来实际访问 BeautifulSoup 的网站以进行解析:

page = requests.get("[http://quotes.toscrape.com/](http://quotes.toscrape.com/)")page# <Response [200]>

这将返回一个响应状态代码,让我们知道请求是否已经成功完成。在这里,我们正在寻找响应[200],这意味着我们已经成功到达该网站。

解析网站

这里我们将使用 BeautifulSoup 解析网站。

soup = bs(page.content)soup

运行此代码将返回类似 HTML 代码中的打印文本文档,如下所示:

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

我们可以使用 BeautifulSoup 浏览上面解析过的文档。

在汤里导航

现在我们需要在解析后的 HTML 文档中找到我们想要的东西。让我们从寻找引语开始。

找到我们要找的东西的一个简单方法是:

  • 进入网页,找到想要的信息(在我们的例子中是报价)。
  • 突出显示这条信息(报价)
  • 点击右键,选择检查****

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

这将打开一个新窗口,如下所示:

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

突出显示的部分是我们要寻找的报价。只需单击突出显示部分左侧的箭头,就可以看到代码中的引用。

用于导航的 HTML 信息

基于我们看到的突出显示的 HTML 代码,我们可以使用该信息来导航汤。我们将在自己的代码中使用.find_all()属性来潜在地找到我们正在寻找的报价。这个属性将能够根据我们给它的任何参数返回我们想要的代码行。因为我们可以看到报价的 HTML 代码包含class=“text”,所以我们可以在我们的 BeautifulSoup 代码中使用它:

soup.find_all(class_='text')

运行此代码将返回以下结果:

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

由此我们可以看到,我们能够成功地定位和检索包含所需报价的代码和文本。

为了只检索文本并排除不必要的代码,我们必须在每个结果中使用.text属性。为此,我们将使用一个 “for” 循环来遍历列表:

quotes = [i.text for i in soup.find_all(class_='text')]quotes

这将为我们提供没有各自 HTML 代码的报价列表:

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

现在我们知道了如何访问网站中的报价,并根据我们的目的检索它们。重复前面提到的步骤来检索每个报价的作者姓名:

authors = [i.text for i in soup.find_all(class_='author')]

访问多个页面

现在我们知道了如何从特定的网页中检索数据,我们可以继续下一组页面中的数据。正如我们从网站上看到的,所有的报价都不是存储在一个页面上。我们必须能够导航到网站的不同页面,以便获得更多的报价。

请注意,每个新页面的 url 都包含一个不断变化的值:

  • http://quotes.toscrape.com/page/2/
  • http://quotes.toscrape.com/page/3/
  • 等等。

了解这一点后,我们可以创建一个简单的 URL 列表来迭代访问网站中的不同页面:

urls=[f"[http://quotes.toscrape.com/page/{i}/](http://quotes.toscrape.com/page/{i}/)" for i in range(1,11)]urls

这将返回我们可以使用的网站列表:

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

从这个列表中,我们可以为“创建另一个”循环来收集必要数量的引用及其各自的作者。**

避免网页抓取检测

需要注意的一点是:一些网站不支持网络抓取。这些网站会执行一些方法来检测你是否在使用一个网页抓取工具,比如美丽的汤。例如,一个网站可以检测是否在短时间内有大量的请求,这就是我们正在做的。为了避免潜在的检测,我们可以随机化我们的请求率,以密切模仿人类的互动。我们是这样做的:

生成值列表:

rate = [i/10 for i in range(10)]

然后在每个循环结束时,输入下面这段代码:

time.sleep(random.choice(rate))

这里,我们从我们创建的列表中随机选择一个值,并在循环再次开始之前等待选定的时间。这将减慢我们的代码,但会帮助我们避免检测。

将这一切结合在一起

现在我们已经有了所有的片段,我们可以构建最后的“for”循环,它将收集至少 52 条引用及其各自的作者:

整个代码检索至少 52 个报价及其作者

一旦我们运行上面的代码,我们将得到一个引用列表和一个作者列表。但是,我们的客户想要电子表格中的报价。为了满足这个请求,我们将不得不使用 Python 库:熊猫

将列表输入熊猫数据框架非常简单:

# Creating a DataFrame to store our newly scraped information
df = pd.DataFrame()# Storing the quotes and authors in their respective columns
df['Authors'] = authorsdf['Quotes'] = quotes

因为引文和作者是按顺序刮出的,所以很容易输入到数据框中。

一旦我们完成并运行了上面的代码,最终的 DF 将如下所示:

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

太棒了。DF 看起来很棒,完全符合客户要求的格式。然后,我们可以将 DF 保存为 excel 电子表格文件,然后发送给客户。

关闭

我们希望你从这个循序渐进的教程中学到了一点关于网络抓取的知识。尽管我们使用的例子可能非常简单,但是所使用的技术仍然适用于互联网上的许多不同的网站。需要大量用户交互的更复杂的网站将需要另一个名为 Selenium 的 Python 库。然而,大多数网站将只需要 BeautifulSoup 来抓取数据。我们在这里完成的演练应该足以让您开始。刮的开心!

开源代码库

** [## Marcos an 93/文章-演练

permalink dissolve GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码,管理…

github.com](https://github.com/marcosan93/Article-Walkthroughs/blob/master/WebScraper.ipynb)**

如何从抖音收集数据(教程)

原文:https://towardsdatascience.com/how-to-collect-data-from-tiktok-tutorial-ab848b40d191?source=collection_archive---------3-----------------------

如何抓取用户发布或喜欢的视频,从种子帐户滚雪球般地收集大量用户列表,以及收集流行视频,所有这些都只需一个简单的 API。

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

Kon Karampelas 在 Unsplash 上拍摄的照片

正如 The Information 所说,抖音已经“像火箭一样在美国和全世界起飞,创造了一种新的移动视频体验,让 YouTube 和脸书争相跟上。”

仅看看 18 岁以上的美国用户,根据康姆斯克提供给《广告周刊》的数据,抖音的独立访客从 1 月份的 2220 万增加到 4 月份的 3920 万。

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

该平台不仅仅是一个很酷的新应用程序:正如最近的事件所表明的那样,其算法传播的视频可能会产生现实世界的后果。举几个突出的例子,

  • 韩国流行乐迷利用抖音在塔尔萨的集会上恶作剧,买了票却没有露面
  • 抖音的青少年在 Trump 的商品网站上组织了“放弃购物车”活动,试图向其他人隐藏库存
  • 一些用户鼓励特朗普的反对者点击特朗普的广告,以便抬高竞选的广告成本
  • 这款应用已经传播了乔·拜登的视频

简而言之,抖音及其驾驶算法现在具有相当大的现实世界影响力,特别是考虑到一个典型的用户每天花近一个小时在平台上观看视频。考虑到这一点,了解抖音每天向数百万人展示什么是很重要的,为此,我们需要一些数据。

下面,我包含了如何以各种方式收集抖音数据的代码。我试图保持它的通用性并对大多数用例有帮助,但是你可能需要根据你正在做的事情来调整它。这篇文章的剩余部分讲述了如何做到以下几点:

  1. 👤收集用户发布的视频
  2. ❤️收集用户喜欢视频
  3. ⛄️像滚雪球一样扩大了用户名单
  4. 📈收集热门视频

(给书呆子们一些提示:如果你打算提出几十个以上的请求,我建议设立一个代理。我还没有测试过,但是我在这里演示的 API 应该很容易与您的代理集成。第二,如果您想跟踪流行程度,您将需要在统计数据中添加时间戳。)

1.👤收集用户发布的视频

一个好的起点是从给定的用户那里收集视频。我将使用由大卫·蒂瑟开发的抖音-Api (运行pip3 install TikTokApi以获得软件包)。

要从《华盛顿邮报》抖音账户(我最喜欢的账户之一)收集视频,以下是你在 Python 中需要做的所有事情:

from TikTokApi import TikTokApi
api = TikTokApi()n_videos = 100
username = 'washingtonpost'user_videos = api.byUsername(username, count=n_videos)

user_videos对象现在是 100 个视频字典的列表(这里的示例字典是)。您可能最感兴趣的只是一些统计数据,您可以使用下面的函数从完整的字典中提取这些数据:

def simple_dict(tiktok_dict):
  to_return = {}
  to_return['user_name'] = tiktok_dict['author']['uniqueId']
  to_return['user_id'] = tiktok_dict['author']['id']
  to_return['video_id'] = tiktok_dict['id']
  to_return['video_desc'] = tiktok_dict['desc']
  to_return['video_time'] = tiktok_dict['createTime']
  to_return['video_length'] = tiktok_dict['video']['duration']
  to_return['video_link'] = 'https://www.tiktok.com/@{}/video/{}?lang=en'.format(to_return['user_name'], to_return['video_id']) to_return['n_likes'] = tiktok_dict['stats']['diggCount']
  to_return['n_shares'] = tiktok_dict['stats']['shareCount']
  to_return['n_comments'] = tiktok_dict['stats']['commentCount']
  to_return['n_plays'] = tiktok_dict['stats']['playCount'] return to_return

然后,我们可以从 API 输出的user_videos列表转到一个漂亮、干净的表格(即 Pandas 数据框),只有三行代码:

user_videos = [simple_dict(v) for v in user_videos]
user_videos_df = pd.DataFrame(user_videos)
user_videos_df.to_csv('{}_videos.csv'.format(username),index=False)

下面是输出文件的样子(为了便于阅读,我删除了一些行和列):

2.❤️收集用户喜欢视频

在这种情况下,您可能对给定用户“喜欢”的视频感兴趣。这很容易收集。来看看抖音官方账号最近都喜欢哪些视频:

username = 'tiktok'
n_videos = 10liked_videos = api.userLikedbyUsername(username, count=n_videos)
liked_videos = [simple_dict(v) for v in liked_videos]liked_videos_df = pd.DataFrame(liked_videos)
liked_videos_df.to_csv('{}_liked_videos.csv'.format(username), index=False)

输出文件看起来与上次的相似,因为它也保存了一个视频列表:

3.⛄️像滚雪球一样扩大了用户名单

假设您想要创建一个大型用户列表,从中您可以收集他们发布的视频和他们喜欢的视频。你可以使用 50 个最受关注的抖音账户,但 50 个账户可能无法产生足够广泛的样本。

另一种方法是使用建议的用户从一个用户滚雪球式地增加用户列表。首先,我们将为四个不同的帐户执行此操作:

  • tiktok是 app 的官方账号
  • washingtonpost是我最喜欢的账户之一
  • charlidamelio是抖音最受欢迎的账户
  • chunkysdead在 app 上领导一个自称“邪教”的人

以下是我使用的代码:

seed_users = ['tiktok', 'washingtonpost', 'charlidamelio', 'chunkysdead']seed_ids = [api.getUser(user_name)['userInfo']['user']['id'] for user_name in seed_users]suggested = [api.getSuggestedUsersbyID(count=20, startingId=s_id) for s_id in seed_ids]

以下是推荐的用户:

值得注意的是,washingtonpostchunkysdead的推荐列表是相同的,其他推荐之间有很多重叠,所以这种方法可能无法满足您的需求。

创建大型用户列表的另一种方法是使用getSuggestedUsersbyIDCrawler来保持雪球滚动。要使用tiktok作为种子帐户创建 100 个建议帐户的列表,您只需要以下代码:

tiktok_id = api.getUser('tiktok')['userInfo']['user']['id']suggested_100 = api.getSuggestedUsersbyIDCrawler(count=100, startingId=tiktok_id)

这将创建一个包含各种不同名人账户的列表,以下是一些:

@lizzo (lizzo, 8900000 fans)
@wizkhalifa (Wiz Khalifa, 1800000 fans)
@capuchina114 (Capuchina❗️👸🏼, 32600 fans)
@silviastephaniev (Silvia Stephanie💓, 27600 fans)
@theweeknd (The Weeknd, 1400000 fans)
@theawesometalents (Music videos, 33400 fans)
...

从我的观察来看,getSuggestedUsersbyIDCrawler方法开始扩展,寻找更小、更小众的账户,这些账户拥有数万名粉丝,而不是数十万或数百万。如果您想要一个有代表性的数据集,这是一个好消息。

如果您想从抖音收集广泛的数据样本,我建议从推荐的用户爬虫开始。

4.📈收集热门视频

最后,也许你只是想收集流行视频进行简单的内容分析,或者只是为了跟上潮流🙂。API 使这变得非常简单,如下所示:

n_trending = 20trending_videos = api.trending(count=n_trending)
trending_videos = [simple_dict(v) for v in trending_videos]
trending_videos_df = pd.DataFrame(trending_videos)
trending_videos_df.to_csv('trending.csv',index=False)

以下是周四下午(2020 年 7 月 2 日)趋势视频的输出文件:

本教程到此结束,感谢您的阅读!这里有一个文件,里面有我使用的所有代码。

如何提出令人惊叹的 AI、ML 或数据科学项目创意?

原文:https://towardsdatascience.com/how-to-come-up-with-amazing-ai-ml-or-data-science-project-ideas-53bae19b5fa0?source=collection_archive---------35-----------------------

作为一个狂热的学习者,构建项目应该是让你兴奋的事情。这里有一些方法可以让你自己想出很棒的项目点子,而不是一直重建现有的项目。

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

米卡·鲍梅斯特在 Unsplash 上的照片

不管人们告诉你什么,语言和思想可以改变世界。—罗宾·威廉姆斯

这个领域的初学者已经习惯于将现有的项目作为他们投资组合项目的一部分,这不是一件好事。是什么让你在数百名与你建立的项目相同的学习者中脱颖而出?作为一名数据科学家、AI 或 ML 工程师,是什么让你脱颖而出?在这篇文章中,我将与你分享一些关于“生成”你的数据科学、人工智能或人工智能项目的技巧,以在你所做的事情上显得独特。

重新发明,但是要有风格

这一点旨在探索你的创新技能。成为一名创新者是每个数据科学家、人工智能或人工智能工程师都需要的一项非常重要的技能。你采用现有解决方案并进一步开发它以产生更好的结果或见解的能力将大大有助于你作为数据科学家、人工智能或 ML 工程师的职业生涯。例如,你可以选择一个流行的项目“预测波士顿房价”,并根据你所在的城市重建这个项目。测试您的创新技能,探索新的数据集,使用更好的算法,并调整超参数以更好地适应您的模型。通过对现有项目做这些事情,你给他们一种新的感觉,并创造一个专业的形象。

如果你想要新的东西,你必须停止做旧的东西。彼得·德鲁克

召唤你内在的创造性自我

创造力包括打破预期的模式,以不同的方式看待事物。—爱德华·德·波诺

要想出令人敬畏和独特的人工智能、人工智能或数据科学想法,一个人必须有创造力,并愿意尝试从未做过的事情。你应该渴望生下一些大多数人会贴上“荒谬”或“不可能”标签的东西。是的,有时一些想法相当荒谬,不值得花时间,但这里有一些方法可以让你想出值得一试的想法。

  • “如果我能制造……”会怎么样

这是想出点子最常见的方式。这通常意味着你有一个现存的问题,你正在想办法解决它。在这种情况下,在您继续下一步之前,请对问题进行一些背景调查,并查看当前是否存在解决方案。如果有能完美解决你的问题的解决方案,就没有必要再进一步了。如果没有,看看你如何最好地解决这个问题。

  • “如果是这样会更好”

在这里,您知道一个现有的解决方案,并试图以一种或两种方式对其进行改进。放手去做吧,不要让现有解决方案的存在阻止你把它变得更好。尽你最大的努力,可能会有成百上千的人和你有同样的问题,而你可能最终通过接受这个项目帮助了这么多人。在我随后的故事中,我将讲述我是如何想到编写我的第一个 python 机器学习包的想法的。

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

Unsplash 上的创意交流

检查可行性

这可能是在开始任何项目工作之前要考虑的最重要的事情。你需要知道项目想法是否可执行。在开始实施之前,问自己几个关于你的想法的问题。

  • 我的想法能解决真正的问题吗?

除非你是为了好玩而构建项目,否则你构建的每个项目都应该旨在解决一个真正的问题。一个值得解决并会对现有方法产生影响的问题。如果你对这个问题的回答是肯定的,你可以继续回答下一个问题。

  • 利用现有技术,我的想法可能实现吗?

即使人工智能今天处于非常先进和未来的水平,我们仍然可以做更多的事情,但由于某些形式的技术的不可用性,我们受到了限制。在这种情况下,我们所能做的就是发展理论和概念,希望技术能很快赶上我们,我们的理论和概念能付诸实践。

  • 我具备构建这个项目所需的技能吗?

在你开始实施一个项目想法之前,考虑你当前的技能是非常重要的。如果你缺乏所需的技能,你可以花一些时间来学习必要的技能。你也可以和一群志趣相投的人组成团队,一起建设这个项目。

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

久尼尔·费雷拉在 Unsplash 上的照片

一个被开发并付诸行动的想法比一个仅仅作为想法存在的想法更重要。
——佛陀

把你的想法付诸实施很难,但也不是不可能。相信你的想法,即使你是唯一相信的人。努力实现你的目标,你一定会成功。

感谢您抽出时间阅读这个故事。我希望你学到了新的东西,这对你有所帮助。欢迎你在回复部分分享你的想法和观点,你可以直接在 TwitterLinkedIn 上联系我。黑客快乐!

非常感谢 安娜·阿依库 为我校对并纠正了我写这篇文章时犯的许多错误。

如何提出有趣的数据科学项目

原文:https://towardsdatascience.com/how-to-come-up-with-original-data-science-projects-e38e2e868ae2?source=collection_archive---------42-----------------------

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

照片由 Aaron BurdenUnsplash

我总是努力想出有趣的 ML/DS 边项目。问题是我在做落后的事情。我通常从一个解决方案,一个算法开始,然后试图为它找到一个问题,一个应用程序。

据我所见,这是数据科学家中一个非常普遍的问题。看看你能否在这里表明自己的身份:

  1. 您了解了最新的 ML/DL 算法,并对此感到非常兴奋
  2. 你开始寻找可以应用它的地方
  3. 你很难想出一个原创的应用程序。所以你最终会做其他人都在做的项目,或者干脆放弃这个项目。

当你学习某样东西时,很难忽视你学习它的背景。我们没有找到新的应用,而是默认在非常相似的环境中应用这些新知识,如果不是相同的话。难怪如此多的数据科学家最终预测谁在泰坦尼克号中幸存,或者使用 MNIST 数据集建立数字识别器。

相反的方法效果更好:从问题、疑问或应用开始,然后尝试找到解决方案、算法。更好的是,从一个你真正感兴趣的问题开始。这样,就更容易找到潜在客户,你也增加了找到让别人感兴趣的东西的机会(很少会发现只引起你注意的问题)。

那么,你如何做到这一点呢?这里有一个简单的方法:

  1. **选择一个问题:**想出一个你可能用数据解决的问题。试着用一个你真正感兴趣的话题来做。看看你的爱好,你在社交媒体上关注什么,或者你在新闻上看到什么。
  2. 寻找数据:找出你能用来解决这个问题的数据。
  3. **调整问题(如有必要)😗*如果数据不能帮助你解决问题,看看稍微修改一下问题是否可行
  4. **选择一种算法:**选择一种你可以用来解决这个问题的算法。
  5. **如果不满意,重新开始:**如果对第 3 步或第 4 步的结果不满意,回到第 1 步。

仅此而已。这很简单,但我发现它非常有效。

我在最近的项目中采用了这种方法,效果很好。当我推出polituits.com时,我在 LinkedIn 上有超过 300 次互动, GitHub 上有 40 颗星,其网站有数百次访问

希望这对你有用。请在评论中告诉我你的想法。

在我继续构建数据驱动的应用程序时,您可以跟随我到这里

如何比较大文件

原文:https://towardsdatascience.com/how-to-compare-large-files-f58982eccd3a?source=collection_archive---------4-----------------------

了解如何使用 Python 比较大文件

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

在这篇博客中,我们将学习如何比较两个大文件,同时创建一个快速而有意义的差异摘要。我已经以这样一种方式组织了这个博客,你可以按照端到端解决方案中的一步一步的指导。

一般来说,比较两个数据集并不是很难。主要的困难来自于能够快速获得有意义的见解。虽然前面提到的困难可以通过预先存在的比较库(如 dataComPy)快速解决,但当数据变得如此之大,以至于无法保存在内存中时,问题就会变得更加严重。

[## 构建用于比较数据的 Python UI

如何快速让您的非技术团队能够比较数据

towardsdatascience.com](/building-a-python-ui-for-comparing-data-13c10693d9e4)

令我失望的是,我找不到一个现有的数据比较库来处理更大的数据集。我找到的所有这些都要求所有的数据都在内存中。

看到这是一个需要解决的问题,我开始寻找解决这个问题的最佳方法。

确定解决方案

为了帮助确定解决方案,我从清楚地定义问题开始。我希望能够比较大文件。问题是数据太大了,我无法在内存中保存所有的数据。我也希望解决方案是简单的。

说得好的问题是解决了一半的问题。

—查尔斯·凯特林

我考虑过的解决这个问题的一个方法是将部分内容加载到内存中。这意味着比较内存中的数据;找出匹配的和不匹配的(内存外),然后转移到更多的数据上。这些类型的操作是一个完整的后勤噩梦,需要复杂的逻辑来跟踪一切。

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

我希望有一种更简单的做事方法。抱着看看;我想到了另一个主意。如果我使用一个 SQL 数据库来进行所有的比较会怎么样。

毕竟,这不是数据库的主要目的吗?持有数据,快速进行以数据为中心的操作?

构建比较脚本,利用 SQL 的强大功能

我希望比较的结果易于理解,并提供有意义的见解。这意味着我更感兴趣的是一个快速总结,和一些例子比较突破。如果需要,我总是可以深入研究数据。

[## SQL 简介

通过示例学习 SQL 的基础知识

towardsdatascience.com](/an-introduction-to-sql-4c9eb27995df)

那么,它是如何工作的呢?

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

在我们运行完整的比较之前,我们应该快速查看文件是否 100%相似。为此,我们可以进行校验和检查。

校验和:用 SHA1 比较数据

import hashlibdef sha1(fname):
    sha1hash = hashlib.sha1()
    with open(fname) as handle: #opening the file one line at a time for memory considerations
        for line in handle:
            sha1hash.update(line.encode('utf-8'))
    return(sha1hash.hexdigest())

def comparefiles(files,datakey):
    print('########################################')
    print('Checking the files\' hash.')
    if sha1(files[0]) == sha1(files[1]):
        print('100% Match')
    else:
        print('Hash not matched. Proceeding to detailed checks.')comparefiles(files, datakey)

仔细观察上面的脚本,我们实际上是一行一行地加载文件,并计算出它们的 SHA1 输出。然后在两个文件之间进行比较。

要运行上面的脚本,我们只需传入:

comparefiles(['path2file1', 'path2file2'], '')

假设文件之间存在差异,那么我们想知道差异是在记录的数量上还是在它们的值上。因此,我们可以研究做一些快速计数。

[## 在 Python 中比较数据的 3 种快速方法

对于任何从事分析工作的人来说,收到比较数据的请求都太熟悉了。不管那是…

medium.com](https://medium.com/financeexplained/3-quick-ways-to-compare-data-in-python-65201be10b6)

将数据加载到 SQL

首先,我们需要在不超出可用内存的情况下将数据加载到 SQL 中,并创建索引来加快查询操作。

从下面的脚本中,您可以看到我们首先需要定义我们的输入:

  • 文件:我们要比较的两个文件的文件路径列表
  • colsep:两个文件的分隔符列表
  • 数据键:我们数据集的键列表
  • conn:我们将用于比较的连接;它可以在内存中,也可以在物理数据库中

下面的脚本中需要注意的另一件事是,我们正在逐块加载文件以避免耗尽内存,并且我们用下划线替换了所有的列空格。

import sqlite3, pandas as pd#################Set Up#############
files = [r'C:\Temp\FL_insurance.csv', r'C:\temp\FL_insurance - Copy.csv']
colsep = [',',',']
datakey = ['policyID', 'statecode', 'county']conn = sqlite3.connect(':memory:')
#conn = sqlite3.connect('meh.sqlite3')
#####################################cur = conn.cursor()
static = ['Table1','Table2']def loadDataToSQL(files, static):
    chunksize = 10000
    i=0
    createindexfortable = lambda a, b : f'CREATE INDEX  {a} Index ON {b} ({a})'
    for file in files:
        i = i+1
        for chunk in pd.read_csv(file, chunksize=chunksize, delimiter=colsep[i-1]): #load the file in chunks in case its too big
            chunk.columns = chunk.columns.str.replace(' ', '_') #replacing spaces with underscores for column names
            chunk.to_sql(name= static[i-1], con=conn, if_exists='append')
    for item in datakey: #create indexes so it runs faster
        createindexfortable(item, 'Table1')
        createindexfortable(item, 'Table2')

假设数据现在已经全部加载到 SQL DB 中,接下来要做的事情就是执行计数。为了控制命令的执行和输出,我们可以创建一个可以调用的函数。

def returnSQLresults(statement, noprint = 0):
    cur.execute(statement)
    i=0
    temp = []
    for row in cur:
        if noprint == 0 and len(row) > 1:
            if i == 0: #if there are multiple records, only print the header once
                names = list(map(lambda x: x[0], cur.description)) #column names
                print(names)
            print(row)
        else:
            temp.append(row)
        i=i+1
    if noprint == 1 and i != 0:
        return(temp)
    elif i==0: return(None)

分解上面的脚本:

  1. 我们检查光标中是否有任何结果返回,以及是否已经定义了 noprint
  2. noprint 本质上导致函数返回数据而不是打印
  3. 如果光标返回任何结果,我们在打印任何内容之前打印结果中的列名

完成上述设置后,我们现在可以开始比较操作了。

总计数

现在是时候利用我们到目前为止在程序中定义的所有函数,开始构建数据比较摘要了。然后,让我们通过定义一个可以调用的新函数来大致了解一下总计数。

def SQLComp(files, keys, compDegree):
    print('########################################')
    print('Checking Counts across the two data sets:')
    print('Total Counts')    
    statement_counts =   '''SELECT "Table1" AS "TABLE", COUNT(1)                                                                                               FROM Table1
                            UNION
                            SELECT "Table2" AS "TABLE", COUNT(1) FROM Table2'''
    returnSQLresults(statement_counts)

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

照片由沙哈达特·拉赫曼Unsplash 上拍摄

比较行(根据预定义的键)

此时,我们知道这两个文件不是 100%匹配,并且我们也知道每个文件的计数。我们现在需要看得更深一点,了解是否有任何条目与我们预定义的键不匹配。

也就是说,我们需要做一个完整的外部连接,并突出显示不在一个文件或另一个文件中的记录(按照我们预定义的键)。从技术上讲,进行这种连接的 SQL 查询并不复杂;然而,由于我们希望从我们的输入中自动生成查询,所以我们需要有创造性。

为此,我使用了一个循环和 f 字符串。让我们更详细地看看这一点。

def SQLComp(files, keys, compDegree):
    for key in keys:
        if key == keys[0]:
            joinstatement = f'x.{key} = y.{key}'
            wherestatement = f' WHERE y.{key} IS NULL'
            wherenotstatement = f' WHERE y.{key} IS NOT NULL'
        else: 
            joinstatement += f' AND x.{key} = y.{key}'
            wherestatement += f' AND y.{key} IS NULL'
            wherenotstatement += f' AND y.{key} IS NOT NULL'print('########################################')
    print('Checking Rows based on data Key.')
    statement1 = f'''SELECT * FROM Table1 x
                    LEFT JOIN Table2 y ON {joinstatement} {wherestatement}'''
    statement2 = f'''SELECT * FROM Table2 x
                    LEFT JOIN Table1 y ON  {joinstatement} {wherestatement}'''

    if returnSQLresults(statement1) is None and returnSQLresults(statement2) is None:
        print('No differences found.')
    else:
        print('Data in file 1, but not in file 2')
        returnSQLresults(statement1)

        print('Data in file 2, but not in file 1')
        returnSQLresults(statement2)

我们通过左右连接来实现完全的外部连接,在每个点突出显示孤立条目。

比较标题(列)

接下来,是列检查。我们想知道这些文件的头是否有差异。

我们可以通过 PRAGMA 命令在 SQLite 中检索头,所以这是相对简单的。

def SQLComp(files, keys, compDegree):
    print('########################################')
    print('Checking Columns between the two files.')
    statement3 = lambda a : 'PRAGMA TABLE_INFO(' + a + ')'
    statement3Table1results = returnSQLresults(statement3('Table1'),1)
    statement3Table2results = returnSQLresults(statement3('Table2'),1)
    if (statement3Table1results == statement3Table2results):
        print('No differences found.')
    else:
        print('Columns in one but not the other.')
        print(set(statement3Table1results)-set(statement3Table2results))

这里唯一值得强调的是集合上减法运算的使用,它允许我快速比较列表。

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

阿诺·弗朗西斯卡在 Unsplash 上的照片

详细的值比较

完成上述检查后,我们现在要开始探索一些价值差异。为此,我们首先要确定两个文件之间的共同列,这将允许我们对它们进行比较。

def list2csv(l1):
    for i, item in enumerate(l1):
        if i == 0:
            csvlist = 'x.' + item
        else:
            csvlist += ', x.'+ item
    return(csvlist)def SQLComp(files, keys, compDegree):
    print('########################################')
    print('Differences identified in the following columns.')
    columnsInCommon1 = list(set(statement3Table1results).intersection(set(statement3Table2results)))
    columnsInCommon = []
    for cols in columnsInCommon1:
        columnsInCommon.append(cols[1])
    columnsInCommon.remove('index')
    cols2select = list2csv(datakey)for item in columnsInCommon:
        statement4 = f'''SELECT {cols2select}, x.{item}, y.{item} FROM Table1 x
                      JOIN Table2 y ON {joinstatement} {wherenotstatement}
                      AND x.{item} <> y.{item}'''
        returnSQLresults(statement4)

对其进行测试

为了帮助我测试上面的脚本并展示结果,我取了一个样本数据文件,克隆它并做了一些修改。您可以在这里看到不同之处:

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

您可以看到,我更改了标题结构下的一个值,并删除了其中一列。

运行脚本,返回以下内容:

########################################
Checking the files' hash.
Hash not matched. Proceeding to detailed checks.
########################################
Checking Counts across the two data sets:
Total Counts
['TABLE', 'COUNT(1)']
('Table1', 36633)
('Table2', 36633)
########################################
Checking Rows based on data Key.
No differences found.
########################################
Checking Columns between the two files.
Columns in one but not the other.
{(18, 'point_granularity', 'INTEGER', 0, None, 0)}
########################################
Differences identified in the following columns.
['policyID', 'statecode', 'county', 'construction', 'construction']
(448094, 'FL', 'CLAY COUNTY', 'Masonry', 'wut')

结论

总之,上面的脚本允许您将无法保存在内存中的大型数据集进行比较,同时最终为您提供一个漂亮的摘要视图。

将来可以通过以下方式轻松扩展它:

  • 详细的值比较可以扩展为每个数据键的列表,而不是返回多行结果
  • 包括特定属性的忽略标志
  • 引入公差(绝对、相对)
  • 包括一个用户界面

如果我继续使用它,我会努力扩展它,但请随意扩展它或评论您的建议。

完整的剧本

import hashlib, sqlite3, pandas as pdconn = sqlite3.connect(':memory:')
#conn = sqlite3.connect('meh.sqlite3')
cur = conn.cursor()files = [r'C:\Temp\FL_insurance.csv', r'C:\temp\FL_insurance - Copy.csv']
colsep = [',',',']
datakey = ['policyID', 'statecode', 'county']
static = ['Table1','Table2']def list2csv(l1):
    for i, item in enumerate(l1):
        if i == 0:
            csvlist = 'x.' + item
        else:
            csvlist += ', x.'+ item
    return(csvlist)def sha1(fname):
    sha1hash = hashlib.sha1()
    with open(fname) as handle: #opening the file one line at a time for memory considerations
        for line in handle:
            sha1hash.update(line.encode('utf-8'))
    return(sha1hash.hexdigest())def loadDataToSQL(files, static):
    chunksize = 10000
    i=0
    createindexfortable = lambda a, b : f'CREATE INDEX  {a} Index ON {b} ({a})'
    for file in files:
        i = i+1
        for chunk in pd.read_csv(file, chunksize=chunksize, delimiter=colsep[i-1]): #load the file in chunks in case its too big
            chunk.columns = chunk.columns.str.replace(' ', '_') #replacing spaces with underscores for column names
            chunk.to_sql(name= static[i-1], con=conn, if_exists='append')
    for item in datakey: #create indexes so it runs faster
        createindexfortable(item, 'Table1')
        createindexfortable(item, 'Table2')def returnSQLresults(statement, noprint = 0):
    cur.execute(statement)
    i=0
    temp = []
    for row in cur:
        if noprint == 0 and len(row) > 1:
            if i == 0: #if there are multiple records, only print the header once
                names = list(map(lambda x: x[0], cur.description)) #column names
                print(names)
            print(row)
        else:
            temp.append(row)
        i=i+1
    if noprint == 1 and i != 0:
        return(temp)
    elif i==0: return(None)def sha1(fname):
    sha1hash = hashlib.sha1()
    with open(fname) as handle: #opening the file one line at a time for memory considerations
        for line in handle:
            sha1hash.update(line.encode('utf-8'))
    return(sha1hash.hexdigest())def SQLComp(files, keys, compDegree):
    for key in keys:
        if key == keys[0]:
            joinstatement = f'x.{key} = y.{key}'
            wherestatement = f' WHERE y.{key} IS NULL'
            wherenotstatement = f' WHERE y.{key} IS NOT NULL'
        else: 
            joinstatement += f' AND x.{key} = y.{key}'
            wherestatement += f' AND y.{key} IS NULL'
            wherenotstatement += f' AND y.{key} IS NOT NULL'
    print('########################################')
    print('Checking Counts across the two data sets:')
    print('Total Counts')    
    statement_counts =   '''SELECT "Table1" AS "TABLE", COUNT(1) FROM Table1
                            UNION
                            SELECT "Table2" AS "TABLE", COUNT(1) FROM Table2'''
    returnSQLresults(statement_counts)
    print('########################################')
    print('Checking Rows based on data Key.')
    statement1 = f'''SELECT * FROM Table1 x
                    LEFT JOIN Table2 y ON {joinstatement} {wherestatement}'''
    statement2 = f'''SELECT * FROM Table2 x
                    LEFT JOIN Table1 y ON  {joinstatement} {wherestatement}'''
    if returnSQLresults(statement1) is None and returnSQLresults(statement2) is None:
        print('No differences found.')
    else:
        print('Data in file 1, but not in file 2')
        returnSQLresults(statement1)
        print('Data in file 2, but not in file 1')
        returnSQLresults(statement2)
    print('########################################')
    print('Checking Columns between the two files.')
    #statement3 = 'PRAGMA table_info(Table1);'
    statement3 = lambda a : 'PRAGMA TABLE_INFO(' + a + ')'
    statement3Table1results = returnSQLresults(statement3('Table1'),1)
    statement3Table2results = returnSQLresults(statement3('Table2'),1)
    if (statement3Table1results == statement3Table2results):
        print('No differences found.')
    else:
        print('Columns in one but not the other.')
        print(set(statement3Table1results)-set(statement3Table2results))
    print('########################################')
    print('Differences identified in the following columns.')
    columnsInCommon1 = list(set(statement3Table1results).intersection(set(statement3Table2results)))
    columnsInCommon = []
    for cols in columnsInCommon1:
        columnsInCommon.append(cols[1])
    columnsInCommon.remove('index')
    cols2select = list2csv(datakey)
    for item in columnsInCommon:
        statement4 = f'''SELECT {cols2select}, x.{item}, y.{item} FROM Table1 x
                      JOIN Table2 y ON {joinstatement} {wherenotstatement}
                      AND x.{item} <> y.{item}'''
        returnSQLresults(statement4)
        #print(statement4)def comparefiles(files,datakey):
    print('########################################')
    print('Checking the files\' hash.')
    if sha1(files[0]) == sha1(files[1]):
        print('100% Match')
    else:
        print('Hash not matched. Proceeding to detailed checks.')
        loadDataToSQL(files, static)
        SQLComp(files, datakey, [])comparefiles(files, datakey)

如果你喜欢这个故事,你可能也会喜欢:

[## 构建用于比较数据的 Python UI

如何快速让您的非技术团队能够比较数据

towardsdatascience.com](/building-a-python-ui-for-comparing-data-13c10693d9e4) [## 在 Python 中比较数据的 3 种快速方法

对于任何从事分析工作的人来说,收到比较数据的请求都太熟悉了。不管那是…

medium.com](https://medium.com/financeexplained/3-quick-ways-to-compare-data-in-python-65201be10b6)

如何比较机器学习算法

原文:https://towardsdatascience.com/how-to-compare-machine-learning-algorithms-ccc266c4777?source=collection_archive---------4-----------------------

“当你改变看待事物的方式时,你所看待的事物也会改变。”―马克斯·普朗克

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

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

T 人类已经发明了不计其数的机器学习(ML)算法。当然,大多数时候只有一小部分用于研究和工业。然而,对于一个人来说,理解和记住所有这些 ML 模型的所有本质细节仍然有点困难。有些人可能还会有一个错误的印象,认为所有这些算法都是完全不相关的。更重要的是,当两种算法看起来都是有效的算法时,人们怎么可能选择使用算法 A 而不是 B 呢?

本文旨在为读者提供不同的角度来看待最大似然算法。有了这些观点,算法可以在共同的基础上进行比较,并且可以很容易地进行分析。写这篇文章的时候考虑了两个主要的 ML 任务——回归和分类。

时间复杂度

在 RAM 模型[1]下,算法所花费的“时间”是通过算法的基本运算来衡量的。虽然用户和开发人员可能更关心算法训练模型所需的挂钟时间,但使用标准最坏情况计算时间复杂性来比较模型训练所需的时间会更公平。使用计算复杂性的好处是忽略运行时使用的计算机能力和架构以及底层编程语言等差异,允许用户专注于算法基本操作的基本差异。

请注意,在训练和测试期间,时间复杂度可能会有很大的不同。例如,像线性回归这样的参数模型可能需要很长的训练时间,但它们在测试期间是有效的。

空间复杂性

空间复杂度根据输入大小来衡量算法运行需要多少内存。如果 ML 算法将过多的数据加载到机器的工作存储器中,那么 ML 程序就不能成功运行。

样本复杂性

样本复杂度测量训练网络所需的训练样本的数量,以保证有效的概括。例如,深度神经网络具有高样本复杂性,因为需要大量训练数据来训练它。

偏差-方差权衡

不同的 ML 算法将具有不同的偏差-方差权衡。偏差误差来自于模型偏向于特定的解决方案或假设。例如,如果线性决策边界适合非线性数据,则偏差会很高。另一方面,方差度量来自模型方差的误差。它是一个模型的预测和期望模型的预测的均方差[2]。

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

偏差-方差权衡,摘自[2]。

不同的模型做出不同的偏差-方差权衡。例如,朴素贝叶斯被认为是一个高偏差、低方差的模型,因为它做出了过于简单的假设。

线上和线下

线上线下学习是指一个机器学习软件学习更新模型的方式。在线学习意味着训练数据可以一次呈现一个,以便当新数据可用时参数可以立即更新。然而,离线学习需要在出现新数据时重新开始训练(重新训练整个模型),以便更新参数。如果算法是在线算法,那么它将是高效的,因为生产中使用的参数可以实时更新,以反映新数据的影响。

ID3 决策树算法是离线学习的一个例子。ID3 的工作方式是全局查看数据,并进行贪婪搜索以最大化信息增益。当新的数据点出现时,整个模型需要重新训练。相比之下,随机梯度下降(SGD)是一种在线算法,因为当新数据到达时,您可以随时使用它来更新训练模型的参数。

并行性

并行算法是指一个算法可以在给定的时间内完成多个操作。这可以通过将工作负载分配给不同的工作人员来实现,比如一台机器或多台机器上的处理器。像梯度推进决策树(GBDT)这样的顺序算法很难并行化,因为下一个决策树是基于上一个决策树所犯的错误构建的。

k-最近邻(k-NN)模型的性质允许它容易地同时在多台机器上运行。这是在机器学习中使用 MapReduce 的一个经典例子。

参数化

参数化概念被广泛应用于统计学习领域。简单地说,参数模型意味着模型的参数数量是固定的,而当更多的数据可用时,非参数模型的参数数量会增加[3]。定义参数模型的另一种方式是基于其关于数据概率分布形状的基本假设。如果没有提出假设,那么它就是一个非参数模型[4]。

参数模型在机器学习中非常常见。例子是线性回归、神经网络和许多其他 ML 模型。另一方面,k-NN 和 SVM(支持向量机)是非参数模型[5]。

方法、假设和目标

本质上,所有的机器学习问题都是优化问题。机器学习模型背后总有一种方法论,或者一个底层的目标函数需要优化。算法背后的主要思想的比较可以增强对它们的推理。

例如,线性回归模型的目标是最小化预测和实际值的平方损失(均方误差,MSE),而 Lasso 回归旨在最小化 MSE,同时通过添加额外的正则化项来限制学习参数,以防止过度拟合。

机器学习模型的一些分类包括 a)生成性对鉴别性,b)概率性对非概率性,c)基于树对非基于树,等等。

总之,可以基于不同的标准来分析最大似然算法。这些标准实际上有助于衡量不同 ML 模型的有效性和效率。

🚀🚀你能想到其他角度来比较 ML 算法吗?🤗🤗

参考

[1]计算的 RAM 模型https://www 8 . cs . umu . se/kur ser/tdba 77/VT06/algorithms/BOOK/BOOK/node 12。HTM

[2]第 12 讲:偏倚-方差权衡https://www . cs . Cornell . edu/courses/cs 4780/2018 fa/lectures/Lecture note 12 . html

[3]拉什卡。"参数学习算法和非参数学习算法有什么区别?"https://sebastianraschka . com/FAQ/docs/parametric _ vs _ parametric . html

[4] T. Hoskin,“参数和非参数:揭开术语的神秘面纱”,载于梅奥诊所,2012 年,第 1–5 页。

[5]第十七讲:决策树https://www . cs . Cornell . edu/courses/cs 4780/2018 fa/lectures/Lecture note 17 . html

如何用 CUDA 11.1 编译 TensorFlow 2.3

原文:https://towardsdatascience.com/how-to-compile-tensorflow-2-3-with-cuda-11-1-8cbecffcb8d3?source=collection_archive---------5-----------------------

当一切都不工作时,将它用作 TensorFlow 安装的最后手段

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

照片由罗伯特拜拜Unsplash

TensorFlow 是一个用于构建机器学习项目的框架,非常易于使用。然而,这并不意味着它总是很容易设置,尤其是当你在玩前沿功能的时候。

这篇文章是为了将来的参考

在过去几年中,我多次遇到 TensorFlow 在某些环境下无法工作的情况。每次发生这种情况,我都要花几个小时在网上搜索支离破碎的信息,还要额外花几个小时把碎片拼在一起。这一次,我决定写一个详细的教程,以挽救未来的情况下,没有工作。

这次出了什么问题?

今天早些时候,我用一个基于 GAN 的网络构建了一个快速实验,我发现实验性的 Keras 预处理 API 很有帮助,但不幸的是,它刚刚被添加到 2.3 版中(我是在 2.2 版上):

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

对于一个普通的 Python 包,一个简单的pip install -U tensorflow就可以了,如果没有,conda install tensorflow将是备份,但是,不幸的是,TensorFlow 一点也不普通。

在完成了pip install -U之后,各种 CUDA 和 TensorRT“未找到”的错误开始出现,更糟糕的是,ANACONDA 还在之前的版本中。

在努力修复这些库一段时间后,我决定从源代码编译 TensorFlow 可能是挽救这种局面的唯一方法。

如果我们要从源代码编译,为什么不同时使用最新的 CUDA 和 tensort(那些是 TensorFlow 依赖的 Nvidia 库),所以计划是安装 TensorFlow 2.3 和 CUDA 11.1、CuDNN 8.0 和 TensorRT 7(预编译 TensorFlow 使用 CUDA 10.1、CuDNN 7.6 和 TensorRT 6)。

步骤 1:安装开发库

因为我们正在编译 Python 库,所以需要开发库和头文件。我们可以得到那些带有sudo apt install python3-dev python3-pip的。

同时,我们还需要 TensorFlow 的纯 Python 部分,是外挂而不是编译的。我们可以安装它们:

我们还需要 Nvidia 库:

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

注意:你不必得到确切的版本,因为本教程是关于安装任何最新版本。

最后需要的是 Bazel,TensorFlow 使用的构建系统,你可以在这里找到如何安装它

注意:到目前为止,您需要 Bazel 3.1.0 来编译 TensorFlow,但是 TensorFlow 会在编译设置期间提示您更改 Bazel 版本的命令。

步骤 2:配置安装并开始编译

由于我们是从源代码编译,所以需要先用git clone [https://github.com/tensorflow/tensorflow.git](https://github.com/tensorflow/tensorflow.git)获取源代码。

为了配置编译,我们需要在克隆的存储库中运行./configure

该命令将提示我们一些选项,我们需要选择 CUDA 为版本 11,TensorRT 为版本 7,并提供以下路径来查找 Nvidia 库:

注意:列表中的最后一个是 TensorRT 7.2 zip 文件解压缩到的位置。

完成配置后,我们可以使用以下命令开始编译 TensorFlow:

步骤 3:修复错误

不幸的是,一旦开始编译,各种错误就会开始出现,但最有可能的是,您会看到类似这样的内容:

这就是说,没有找到所需的特定版本的 Nvidia 库。如果您严格遵循了上面的库安装步骤,那么您应该能够排除它确实丢失的可能性,剩下的只是 TensorFlow 正在对它们如何版本化做出一些假设。

对我来说,就是抱怨libcudart.so.11.1不见了。用locate libcudart.so快速搜索发现,不是 11.1,我有libcudart.so.11.0。这意味着,尽管 CUDA 在 11.1 版本中,但libcudart.so可能没有变化,所以它仍然是 11.0。

为了解决这个问题,我们需要打开third_party/gpus/cuda_configure.bzl(感谢 Pwuertz 指出一个错别字!)并替换以下代码:

注意:如果您遇到问题的库不是cudart,您仍然可以通过修改其他组件的配置来修复它。

修复后,它应该开始编译(编译需要一段时间,所以要准备好过夜)。

要点是,对于 TensorFlow 安装,您应该总是从 Anaconda 或 Virtualenv 安装开始,如果它不起作用,并且您可以忍受一直使用 docker,那么使用官方 Docker 映像,但是如果所有这些都不起作用,请将这篇文章作为您的最后手段,这样至少您可以开始构建东西。

更新

感谢 Pwuertz 指出,有时你也必须为libcublas指定“11”,因为 Nvidia 将后缀减少为libcublas.so.11,但 TensorFlow 使用libcublas.so.11.2.1.74或其他变量,这取决于确切的版本。

参考

感谢来自以下人员的精彩建议:

如何压缩神经网络

原文:https://towardsdatascience.com/how-to-compress-a-neural-network-427e8dddcc34?source=collection_archive---------17-----------------------

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

作者图片

权重修剪、量化和知识提炼导论

现代最先进的神经网络架构非常庞大。例如,你可能听说过 GPT-3,OpenAI 最新的革命性 NLP 模型,能够写诗和互动讲故事。

GPT 3 号有大约 1750 亿个参数。

为了让您了解这个数字有多大,请考虑以下情况。一张 100 美元的钞票大约有 6.14 英寸宽。如果你开始把钞票一张一张地放在一起,这条线将会延伸 169,586 英里。相比之下,地球的周长是 24901 英里,沿着赤道测量。所以,在我们用完钱之前,大约需要 6.8 次往返。

不幸的是,与金钱相反,当涉及到参数的数量时,有时并不是越多越好。当然,更多的参数似乎意味着更好的结果,但也意味着更大的成本。根据原论文,“GPT-3”需要 3.14E+23 flops 的训练时间,计算成本本身就在数百万美元。

GPT-3 是如此之大,以至于它不容易被转移到其他机器上。它目前可以通过 OpenAI API 访问,所以你不能只是克隆一个 GitHub 库并在你的计算机上运行它。

然而,这只是冰山一角。部署小得多的模型也可能给机器学习工程师带来重大挑战。在实践中,小而快的模型要比笨重的模型好得多。

正因为如此,研究人员和工程师在压缩模型上投入了大量的精力。通过这些努力,出现了几种解决问题的方法。

为什么和如何

如果我们重温一下 GPT-3,我们可以看到参数的数量和训练时间是如何影响性能的。

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

GPT-3 模型不同变体中验证损失与计算时间的关系。颜色代表参数的数量。来源:汤姆·布朗等人的《语言模型是很少出手的学习者》

趋势似乎很明显:更多的参数导致更好的性能和更高的计算成本。后者不仅影响培训时间,还影响服务器成本和环境影响。(训练大型模特比一辆汽车一生排放的二氧化碳还多。)然而,训练只是神经网络生命周期的第一部分。从长远来看,推理成本占了上风。

为了通过压缩模型来优化这些成本,出现了三种主要方法:

  • 权重剪枝,
  • 量化,
  • 知识的升华。

在本文中,我的目标是向您介绍这些,并概述它们是如何工作的。

我们开始吧!

权重修剪

减少神经网络规模的最古老方法之一是权重修剪,消除神经元之间的特定连接。实际上,消除意味着被去除的重量被零代替。

乍一看,这个想法可能令人惊讶。这难道不会消除神经网络所学习的知识吗?

当然,去除所有的联系无疑会导致失去所有学到的东西。另一方面,只删除一个连接可能并不意味着准确性的降低。

问题是,在预测性能开始下降之前,你能去除多少?

最佳脑损伤

最先研究这个问题的是 Yann LeCun、John S. Denker 和 Sara A. Solla,他们在 1990 年发表的论文 最佳大脑损伤 。他们开发了以下迭代方法。

  1. 训练一个网络。
  2. 通过观察重量扰动后损失如何变化来估计每个重量的重要性。较小的变化意味着不太重要。(这个重要性被称为显著性。)
  3. 移除重要性较低的权重。
  4. 回到步骤 1。并且重新训练网络,永久地将去除的权重固定为零。

在他们为 MNIST 分类修剪 LeNet 的实验中,他们发现可以移除很大一部分权重,而不会明显增加损失。

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

来源: 最佳大脑损伤 作者 Yann LeCun,John S. Denker 和 Sara A. Solla

然而,修剪后的再培训是必要的。这被证明是相当棘手的,因为较小的型号意味着较小的容量。此外,如上所述,训练量占计算成本的很大一部分。这种压缩只对推理时间有帮助。

有没有一种方法需要较少的修剪后训练,但仍能达到未修剪模型的预测性能?

彩票假说

麻省理工学院的研究人员在 2008 年取得了一项重要突破。在他们题为 彩票假说 的论文中,Jonathan Frankle 和 Michael Carbin 在他们的假说中指出

一个随机初始化的密集神经网络包含一个子网络,该子网络被初始化为当被隔离训练时,它可以在最多相同次数的迭代训练后匹配原始网络的测试精度。

这样的子网叫做中奖彩票。让我们假设你买了 10 张⁰⁰⁰彩票。(这比可观察到的宇宙中的原子数量还要多,但我们暂且不谈这个。)因为你有那么多,所以有极小的概率没有一个是赢家。这类似于训练神经网络,我们随机初始化权重。

如果这个假设是真的,并且可以找到这样的子网络,训练可以更快更便宜地完成,因为单个迭代步骤将花费更少的计算。

问题是,假设成立吗,如果成立,我们如何找到这样的子网?作者提出了以下迭代方法。

  1. 随机初始化网络并存储初始权重以备后用。
  2. 按照给定的步数训练网络。
  3. 移除一定百分比的具有最低幅度的权重。
  4. 将剩余重量恢复到第一次初始化时给出的值。
  5. 转到步骤 2。并迭代修剪。

在基于简单数据集训练的简单架构上,如 MNIST 的 LeNet,这种方法提供了显著的改进,如下图所示。

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

来源:彩票假说:寻找稀疏的、可训练的神经网络,作者乔纳森·弗兰克尔和迈克尔·卡宾

然而,尽管它很有前途,但在像 ResNets 这样更复杂的体系结构上表现不佳。此外,修剪仍然发生在训练之后,这是一个显著的问题。

合成流

最近一次在训练前进行修剪的算法发表于 2020 年。(这是我写这篇文章的年份。在他们的论文中,来自斯坦福的田畑秀则·田中、丹尼尔·库宁、丹尼尔·l·k·亚明斯和 Surya Ganguli 开发了一种方法,这种方法走得更远,可以在没有训练的情况下进行修剪*。*

首先,他们引入了层塌陷的概念,

整个层的过早修剪使得网络不可跟踪,

这在理论中起着重要的作用。任何修剪算法都应该避免层折叠。困难的部分是确定一类满足这个标准的算法。

为此,作者在网络中引入了给定权重的突触显著性得分,定义如下

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

其中 L 是网络输出给定的损失函数, w 是权重参数。每个神经元保持这个量:在激活函数的某些约束下,传入突触显著性得分的总和等于传出突触显著性得分的总和。

该分数用于选择修剪哪些权重。(回想一下,为了这个目的,最佳大脑损伤方法使用了基于扰动的量,而彩票假设论文的作者使用了量级。)

事实证明,突触显著性分数在层之间是守恒的,粗略地说,如果迭代剪枝算法尊重这种逐层守恒,就可以避免层崩溃。

SynFlow 算法是一种类似于前面算法的迭代剪枝算法,但是选择是基于突触显著性分数的。

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

来源:通过迭代保存突触流,在没有任何数据的情况下修剪神经网络作者:田畑秀则·田中、丹尼尔·库宁、丹尼尔·l·k·亚明斯和 Surya Ganguli

然而,工作远未完成。正如 Jonathan Frankle 和他的合作者在他们最近的论文中所指出的,不存在通用的解决方案。每种方法在特定的场景中表现出色,但在其他场景中表现出色。此外,预训练剪枝方法优于基线随机剪枝,但仍不如一些后训练算法,尤其是基于幅度的剪枝。

履行

修剪在 TensorFlow 和 PyTorch 中都可用。

[## 修剪教程- PyTorch 教程 1.6.0 文档

作者:Michela Paganini 最先进的深度学习技术依赖于过度参数化的模型,这些模型很难…

pytorch.org](https://pytorch.org/tutorials/intermediate/pruning_tutorial.html) [## TensorFlow 模型优化工具包-修剪 API

2019 年 5 月 14 日——自从我们推出了模型优化工具包(Model Optimization Toolkit)以来,这是一套开发人员(无论是新手……

blog.tensorflow.org](https://blog.tensorflow.org/2019/05/tf-model-optimization-toolkit-pruning-API.html?hl=es-uy)

接下来,我们要来看看神经网络压缩的另一个工具:量化

量化

本质上,神经网络只是一堆线性代数和一些其他运算。默认情况下,大多数系统使用 float32 类型来表示变量和权重。

然而,一般来说,其他格式的计算比如 int8 比 float 32 T21 更快,内存占用更少。(当然,这些可以取决于硬件,但我们在这里并不试图额外具体。)

神经网络量化是一套旨在利用这一点的方法。例如,如果我们想要从上述的 float32int8 ,并且对于某个实数 a ,我们的值在范围 *[-a,a】*内,我们可以使用转换

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

转换权重并以新的形式继续计算。

当然,事情没那么简单。两个 int8 数相乘很容易溢出到 int16 ,以此类推。在量化过程中,必须小心避免由此产生的误差。

与所有压缩方法一样,这也带来了信息的损失,并可能影响预测性能。问题和之前一样:要找到一个最优的取舍。

量化有两种主要风格:训练后量化量化感知训练。前者更简单,但会导致比后者更大的精度损失。

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

TensorFlow Lite 中的量化方法及其性能。来源: TensorFlow Lite 文档

正如您在上表中看到的,在某些情况下,这可以将推断时间缩短一半。然而,从 float32 转换到 int8 并不是一个平滑的转换;因此,当渐变景观杂乱无章时,可能会导致次优结果。

有了量化感知训练,这种方法也有可能改善训练时间。

履行

与权重修剪类似,量化在 TensorFlow 和 PyTorch 中也可用。

[## 模型优化| TensorFlow Lite

边缘设备通常具有有限的内存或计算能力。可以对模型进行各种优化,以便…

www.tensorflow.org](https://www.tensorflow.org/lite/performance/model_optimization) [## 量化- PyTorch 1.6.0 文档

警告量化处于测试阶段,可能会有变化。量化指的是执行计算的技术…

pytorch.org](https://pytorch.org/docs/stable/quantization.html)

在撰写本文时,PyTorch 中的这个特性还处于试验阶段,这意味着它可能会发生变化。所以,你应该期待在即将到来的版本中会有突破性的变化。

到目前为止,我们看到的方法都有一个共同的原理:训练网络,丢弃一些信息进行压缩。正如我们将会看到的,第三种,即知识提炼,与这些有显著的不同。

知识的升华

虽然量化和修剪可能是有效的,但它们最终是破坏性的。Geoffrey Hinton、Oriol Vinyals 和 Jeff Dean 在他们的论文提取神经网络中的知识中开发了一种替代方法。

他们的想法很简单:训练一个大模型(老师)来获得最佳表现,并用它的预测来训练一个小模型(学生)。

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

知识的升华。(图片由作者提供。)

他们的工作表明,通过这种方式,大型集合模型可以用更简单的架构压缩,更适合生产。

**知识提炼提高了提炼模型的推理时间,而不是训练时间。**这是其他两种方法的本质区别,因为培训时间通常成本很高。(如果我们回想一下 GPT-3 的例子,它是数百万美元。)

你可能会问,为什么不从一开始就使用紧凑的架构呢?秘方是通过使用学生模型的预测,教会学生模型像老师一样进行归纳。在这里,学生模型不仅可以看到大模型的训练数据,还可以看到新的数据,这些数据可以用来近似老师的输出。

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

从 Geoffrey Hinton、Oriol Vinyals 和 Jeff Dean 的论文中提取神经网络中的知识中的语音识别问题中提取知识

模型越小,就需要越多的训练数据来很好地概括。因此,它可能需要一个复杂的架构,如一个集合模型,以达到最先进的挑战性任务的表现。不过,它的知识可以用来推动学生模型的性能超过基线。

知识提炼的第一个用例是压缩集合,使它们适合生产。在卡格尔比赛中,合奏是臭名昭著的。几个获奖的模型由几个较小的模型组成,提供了出色的结果,但在实践中无法使用。

从那以后,它被成功地应用于其他架构,最著名的是 BERT,NLP 的著名变压器模型。

[## 🏎更小,更快,更便宜,更轻:介绍伯特,伯特的精华版本

你可以在这里找到代码来重现呆伯特的训练以及呆伯特的预训练权重。

medium.com](https://medium.com/huggingface/distilbert-8cf3380435b5)

除了 Hinton 等人的基线蒸馏方法,还有其他几种方法,试图推动技术的发展。如果您想了解这些方法的概况,我推荐下面的调查报告。

[## 知识蒸馏:一项调查

近年来,深度神经网络在工业界和学术界都取得了很大的成功,特别是在神经网络领域

arxiv.org](https://arxiv.org/abs/2006.05525v1)

履行

由于知识提炼不需要像修剪或量化那样操纵权重,因此它可以在您选择的任何框架中执行。

这里有一些例子让你开始!

[## Keras 文件:知识蒸馏

作者:Kenneth Borup 创建日期:2020/09/01 最后修改时间:2020/09/01 描述:实现经典…

keras.io](https://keras.io/examples/vision/knowledge_distillation/) [## aber Hu/知识-提炼-动物园

Pytorch 实现了各种知识蒸馏(KD)方法。这个库是一个简单的参考,主要是…

github.com](https://github.com/AberHu/Knowledge-Distillation-Zoo)

结论

随着神经网络变得越来越大,压缩模型变得更加重要。随着问题和架构复杂性的增加,计算成本和环境影响也在增加。

这种趋势似乎只会加速:GPT-3 包含 1750 亿个参数,与以前的巨型模型相比,这是 10 倍的数量级。因此,压缩这些网络是一个基本问题,这在未来将变得更加重要。

你准备好迎接这个挑战了吗?

如果你喜欢把机器学习概念拆开,理解是什么让它们运转,我们有很多共同点。看看我的博客,我经常在那里发表这样的技术文章!

[## 你能移除 99%的神经网络而不损失准确性吗?

权重剪枝简介

towardsdatascience.com](/can-you-remove-99-of-a-neural-network-without-losing-accuracy-915b1fab873b) [## 如何用量化加速和压缩神经网络

从浮点数到整数

towardsdatascience.com](/how-to-accelerate-and-compress-neural-networks-with-quantization-edfbbabb6af7) [## 一个神经网络可以训练其他网络吗?

知识提炼导论

towardsdatascience.com](/can-a-neural-network-train-other-networks-cf371be516c6)

如何使用 BERT 和 Word2Vec 计算句子相似度

原文:https://towardsdatascience.com/how-to-compute-sentence-similarity-using-bert-and-word2vec-ab0663a5d64?source=collection_archive---------6-----------------------

NLP-生产中

以及防止计算句子嵌入时常见错误的一些见解

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

卡蒂亚·奥斯丁在 Unsplash 上拍摄的照片

我们经常需要将文本数据,包括单词、句子或文档编码成高维向量。句子嵌入是各种自然语言处理任务中的一个重要步骤,例如情感分析和文摘。需要一个灵活的句子嵌入库来快速原型化,并针对各种上下文进行调整。

过去,我们大多使用 one-hot、term-frequency 或 TF-IDF(也称为归一化 term-frequency)等编码器。然而,在这些技术中没有捕获单词的语义和句法信息。最近的进步使我们能够以更有意义的形式对句子或单词进行编码。word2vec 技术和 BERT 语言模型是其中两个重要的技术。注意,在这个上下文中,我们交替使用嵌入、编码或矢量化。

开源的 sent2vec Python 库可以让你高度灵活地编码句子。您目前可以访问库中的标准编码器。更高级的技术将在以后的版本中添加。在本文中,我想介绍这个库,并分享我在这方面学到的经验。

如果您不熟悉 Word2Vec 模型,我推荐您先阅读下面的文章。你会发现为什么 Word2Vec 模型在机器学习中既简单又具有革命性。

[## Word2Vec 模型简单而具有革命性

Gensim 还是 spaCy?不了解 Word2Vec 机型的基础知识也没关系。

towardsdatascience.com](/word2vec-models-are-simple-yet-revolutionary-de1fef544b87)

—如何使用“sent 2 vec”Python 包

如何安装

由于 sent2vec 是一个高级库,它依赖于 spaCy (用于文本清理) Gensim (用于 word2vec 模型) Transformers (用于各种形式的 BERT 模型)。因此,确保在使用下面的代码安装 sent2vec 之前安装这些库。

pip3 install sent2vec

如何使用伯特方法

如果要使用BERT语言模型(更确切地说是distilbert-base-uncased)为下游应用程序编码句子,必须使用下面的代码。目前, sent2vec 库只支持 DistilBERT 模型。未来将支持更多型号。由于这是一个开源项目,您还可以深入研究源代码,找到更多的实现细节。

sent 2 vec**——**如何使用 BERT 计算句子嵌入

你可以用句子的向量来计算句子之间的距离。在示例中,正如所料,vectors[0]vectors[1]之间的距离小于vectors[0]vectors[2]之间的距离。

注意,默认的矢量器是distilbert-base-uncased,但是可以传递参数pretrained_weights来选择另一个BERT模型。例如,您可以使用下面的代码来加载基本的多语言模型。

vectorizer = Vectorizer(pretrained_weights='distilbert-base-multilingual-cased')

如何使用 Word2Vec 方法

如果您想使用 Word2Vec 方法,您必须向模型权重传递一个有效的路径。在引擎盖下,使用来自Splitter类的sent2words方法将句子拆分成单词列表。该库首先提取句子中最重要的单词。然后,它使用与这些单词相对应的向量的平均值来计算句子嵌入。你可以使用下面的代码。

sent 2 vec**—**如何使用word2vec计算句子嵌入

可以通过在默认列表中添加或删除来自定义停用词列表。当调用矢量器的方法.run时,必须传递两个附加参数(两个列表):remove_stop_wordsadd_stop_words。在进行任何计算之前,研究停用词表是至关重要的。在这一步中稍有变化,最终结果很容易出现偏差。

请注意,您可以使用预先训练的模型或定制的模型。这对于获得有意义的结果至关重要。你需要一个上下文化的向量化,Word2Vec 模型可以解决这个问题。你只需要在初始化矢量器类的时候,把路径发送给 Word2Vec 模型(即PRETRAINED_VECTORS_PATH)。

—什么是最好的句子编码器

句子编码或嵌入技术的最终结果植根于各种因素,如相关的停用词表或语境化的预训练模型。你可以在下面找到更多的解释。

  • 文本清理— 假设您将 spaCy 用于文本清理步骤,因为我也在 sent2vec 库中使用了它。如果您错误地忘记从默认停用词表中删除“Not ”,那么句子嵌入结果可能会完全误导。一个简单的“不”字,就能彻底改变一句话的情调。每个环境中的默认停用词表都不同。因此,在进行任何计算之前,您必须根据您的需求来筛选这个列表。
  • 情境化模型— 你必须使用情境化模型。例如,如果目标数据是金融数据,则必须使用在金融语料库上训练的模型。否则,句子嵌入的结果可能不准确。所以,如果用word2vec的方法,想用一般的英文模型,句子嵌入结果可能会不准确。
  • 聚合策略— 当您使用word2vec方法计算句子嵌入时,您可能需要使用更高级的技术来聚合单词向量,而不是取它们的平均值。目前,sent2vec 库只支持“平均”技术。使用加权平均来计算句子嵌入,是一种可以改善最终结果的简单增强。未来的版本将支持更高级的技术。

为了强调 word2vec 模型的重要性,我使用两种不同的 word2vec 模型对一个句子进行编码(即glove-wiki-gigaword-300fasttext-wiki-news-subwords-300)。然后,我计算两个向量之间的余弦相似度:0.005这可能解释为“两个独特的句子非常不同”。不对!通过这个例子,我想证明如果我们使用两个不同的 word2vec 模型,句子的向量表示甚至可以是垂直的。换句话说,如果你用一个随机的 word2vec 模型来盲目计算句子嵌入,你可能会在过程中大吃一惊。

— Sent2Vec 是一个开源库,所以…

sent2vec 是一个开源库。这个项目的主要目标是加快 NLP 项目中概念验证的构建。大量的自然语言处理任务需要句子矢量化,包括摘要和情感分析。所以,请考虑贡献力量,推动这个项目向前发展。我也希望你能在你激动人心的 NLP 项目中使用这个库。

[## pdrm83/Sent2Vec

在过去,我们主要使用,例如,一个热点,术语频率,或 TF-IDF(标准化术语…

github.com](https://github.com/pdrm83/Sent2Vec)

感谢阅读!

如果你喜欢这个帖子,想支持我…

[## 通过我的推荐链接加入 Medium—Pedram Ataee 博士

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

pedram-ataee.medium.com](https://pedram-ataee.medium.com/membership)

如何计算词语相似度——比较分析

原文:https://towardsdatascience.com/how-to-compute-word-similarity-a-comparative-analysis-e9d9d3cb3080?source=collection_archive---------14-----------------------

NLP-in-Production

Owl API 是一个强大的单词相似性服务,使用高级文本聚类技术和各种 word2vec 模型

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

Unsplash 上由zdenk macha ek拍摄的照片

在自然语言处理或 NLP 中,大多数任务都是基于提取单词、句子或文档的语义而构建的。例如,我们通过提取句子的语义并基于它们在文档中的重要性对它们进行聚类来构建提取摘要。或者,我们通过提取最能表征一组文档的词组来构建主题建模解决方案。

有意义的语言的第一个要素是单词。所以,你可以猜测在 NLP 任务中正确提取单词的语义关系有多重要。**提取单词语义最强大的工具之一是 word2vec 模型。**这些 word2vec 模型针对不同的上下文进行训练,并提供单词的高维向量表示。然而,由于高维空间和结果缺乏质量,分析是复杂的。

在这篇文章中,我想介绍一个强大的单词相似性 API,名为 Owl,它可以帮助您提取与目标单词最相似的单词。与 NLP 项目非常需要的当前解决方案相比,该 API 以更大的粒度提取最相似的单词。

owl——一个强大的词语相似度 API

这个 Owl API 使用各种 word2vec 模型和高级文本聚类技术来创建比行业标准更好的粒度。事实上,它将 spaCy 创建的最大的 word2vec 英文模型(即 en-core-web-lg )用于通用上下文,并将斯坦福大学创建的 word2vec 模型之一(即glove-wiki-gigaword-300)用于新闻上下文。

在这里,我比较了这三个模型引入的最相似服务的结果。这有助于你找出为什么 Owl 是你的答案

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

Owl——一个强大的单词相似度 API

一、word2vec 模型(spaCy 或 Glove)哪个更好提取最相似的词?

答案是没有。为什么?因为这些模型是在使用不同文本语料库的各种上下文中训练的。要提取最相似的词,首先必须确定上下文,如新闻、体育或一般。根据上下文,最相似的服务的结果可能完全不同。当您选择上下文时,您应该选择更适合您的问题的 word2vec 模型。

en-core-web-lg 模型已经在通用英语语料库上接受了训练,而 glove-wiki-gigaword-300 已经在维基百科和 gigaword 数据集(新闻专线文本数据的综合档案)上接受了训练。它们在两个不同的文本语料库上被训练,目的是提取不同的语义关系。下面,您可以看到使用这两种不同模型的单词“apple”的单词相似度的结果。

"spaCy (en-core-web-lg)": 
**[**"apples","blackberry","iphone","fruit","blueberry","strawberry",
"ipad","pineapple","pear","cider"**]**"Glove (glove-wiki-gigaword-300)": 
**[**"iphone","macintosh","ipod","microsoft","ipad","intel","ibm",
"google","imac","software"**]**

我们需要一个粒度更细的最相似的单词服务,它可以系统地区分子组。这正是 Owl 介入并解决问题的地方。

正如你所看到的,spaCy 的结果更多的是关于日常用语,而 Glove 的结果更多的是关于你能在新闻上找到的东西。现在,你可以很容易地理解为什么结果是不同的,而两者都是正确的。为了更好地阐明这一点,我们来看看对“丰田”最相似的词的结果。

"spaCy (en-core-web-lg)": **[**"honda","subaru","ford","bmw","chevy","volvo","jeep","prius",
"mercedes","dodge"**]**

"Glove (glove-wiki-gigaword-300)":**[**"honda","nissan","automaker","camry","prius","mazda","lexus",
"motor","automakers","ford"**]**

您可以看到这两个服务的结果是与原始单词相关的单词的组合,但不能在桶中报告。例如,spaCy 报告了两种不同类型的“苹果”词:水果和小工具。或者,Glove 报告了“丰田”的两种不同类型的词:型号和制造商。我们需要一个粒度更细的最相似的服务,可以系统地区分子群。这正是 Owl 介入并解决问题的地方。

二。为什么 Owl API 可以成为单词相似度服务的行业标准?

word2vec 模型通常在高维空间中生成向量。虽然这些模型保留了许多关于内部语言的信息,但它们很难分析。这就是为什么当前最相似单词服务的结果还不成熟的原因。Owl API 使用先进的文本聚类技术来改进当前的工具。

你可以找到 Owl API 使用下面的 glove-wiki-gigaword-300 模型生成的与“Toyota”最相似的单词的结果。你可以看到结果被很好地划分为模型、制造者和一般子群;一个你在原始模型中找不到的粒度。

"Owl (glove-wiki-gigaword-300)": **{**
0: **[**"camry","prius","lexus"**],** 1: **[**"honda","nissan", "mazda", "motor", "ford"**],** 2: **[**"automaker", "automakers"**]
}**

此外,您可以找到 Owl API 使用 en-core-web-lg 模型生成的与“apple”最相似的单词的结果。你可以看到结果被很好地分成代表水果、小工具和浆果的组。

"Owl (en-core-web-lg)": **{**
0: **[**"apples","fruit","pineapple", "pear", "cider"**],** 1: **[**"iphone","ipad"**],** 2: **[**"blueberry", "strawberry", "blackberry"**]
}**

三。如何使用 Owl API 提取最相似的单词?

很简单。首先,你需要从 RapidAPI 获取自己的 API 密匙。然后,您必须选择符合您需求的端点。目前,Owl API 公开列出的端点为您提供了以下服务。

  • Top_10_G :一般语境下最相似的前 10 个词
  • Top_50_G: 一般语境下最相似的前 50 个词
  • Top_10_N :新闻语境中最相似的前 10 个词
  • Top_50_N :新闻语境中最相似的前 50 个词

然后,您必须提交请求并等待您的回复🙂。如果您使用 Python,您可以在下面找到 Top_10_N 端点的代码。

import requests

url = "https://word-similarity.p.rapidapi.com/news/10/apple"

headers = {
    'x-rapidapi-host': "word-similarity.p.rapidapi.com",
    'x-rapidapi-key': *** YOUR API KEY ***
    }

response = requests.request("GET", url, headers=headers)

print(response.text)

你可以在 RapidAPI 上找到使用 Python 和许多其他编程语言的 Owl API 的完整说明。

外卖食品

有很多工具可以提取最相似的单词,来定位单词。然而,上述工具是最常见的。我强烈建议尝试一下 Owl API ,因为它是建立在最好的 word2vec 模型之上的,与它的祖先相比,它能生成更有意义的结果。

感谢阅读!

如果你喜欢这个帖子,想支持我…

[## 通过我的推荐链接加入 Medium—Pedram Ataee 博士

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

pedram-ataee.medium.com](https://pedram-ataee.medium.com/membership)

如何进行 A/B 测试?

原文:https://towardsdatascience.com/how-to-conduct-a-b-testing-3076074a8458?source=collection_archive---------8-----------------------

如何执行 A/B 测试的分步指南

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

作者图片

A/B 测试的想法是向不同的变体(用户组)呈现不同的内容,收集他们的反应和用户行为,并使用结果来构建未来的产品或营销策略。

A/B 测试是一种比较功能、页面、按钮、标题、页面结构、表单、登录页面、导航和定价等多个版本的方法。通过向客户或潜在客户展示不同的版本,并通过某种度量标准(点击率、购买、任何行动号召等)评估交互质量。).

在一个数据驱动的世界里,这变得越来越重要,因为商业决策需要事实和数字的支持。

如何进行标准的 A/B 测试

  1. 阐明你的假设
  2. 决定拆分和评估指标
  3. 创建您的对照组和测试组
  4. A/B 测试的长度
  5. 进行测试
  6. 得出结论

1.阐明你的假设

在进行 A/B 测试之前,您需要陈述您的零假设和替代假设:

无效假设 是指对照组和变异组之间没有差异。 替代假设 是一种说法,即 对照组和变异组之间的一种区别。**

想象一下,一家软件公司正在想方设法增加为他们的软件付费的人数。该软件目前的设置方式是,用户可以免费下载和使用该软件,试用期为 7 天。该公司希望改变主页的布局,用红色标志而不是蓝色标志来强调该公司的软件有 7 天的试用期。

**这里举一个假设检验的例子:
**默认动作:**批准蓝色标志。
**替代动作:**批准红色标志。
**无效假设:**蓝色标志 不会导致 比红色标志至少多 10%的许可购买量。
**替代假设:红色标识 确实导致 比蓝色标识至少多 10%的许可购买量。

需要注意的是,在执行 A/B 测试时,所有其他变量都需要保持不变。

2.决定拆分和评估指标

我们应该考虑两件事:在进入网站时,我们应该在哪里以及如何将用户分成实验组,以及我们将使用什么指标来跟踪实验操作的成功或失败。转移单位的选择(我们将观察结果分组的点)可能会影响我们可以使用的评估指标。

控制组或“A”组将看到旧的主页,而实验组或“B”组将看到强调 7 天试验的新主页。

三种不同的分裂度量技术:

a)基于事件的转移
b)基于 Cookie 的转移
c)基于账户的转移

一个基于事件的转移(像一个页面视图)可以提供许多观察结果来得出结论,但是如果每个页面视图的情况发生变化,那么访问者可能会在每次主页访问中获得不同的体验。当用户不容易看到变化时,基于事件的转移更好,以避免体验中断。

此外,基于事件的转移可以让我们知道每个条件下下载页面被访问了多少次,但不能进一步跟踪每个条件下实际产生了多少次下载。

****基于账户的可以稳定,但不适合这种情况。由于访问者在到达下载页面后才注册,所以现在向应该被分配到实验条件下的人介绍新主页已经太晚了。

因此,这就剩下了考虑基于 cookie 的转移**,这感觉像是正确的选择。Cookies 还允许跟踪每个访问者访问每个页面的情况。基于 cookie 的分流的缺点是,如果用户通过匿名窗口、不同的浏览器或在下载前过期或被删除的 cookie 进入网站,会导致计数不一致。然而,作为一种简化,我们将假设这种分配稀释很小,并忽略其潜在的影响。**

评估指标方面,我们更倾向于使用相对于 cookie 数量的下载率** (# downloads / # cookies)和购买率 (# licenses / # cookies)作为评估指标。**

产品使用统计数据,比如软件在试用期间的平均使用时间,是潜在的有趣特性,但与我们的实验没有直接关系。当然,这些统计数据可能会帮助我们在实验完成后更深入地挖掘观察到的效应的原因。但是就实验的成功而言,产品的使用不应该被认为是一个评估标准。

3.创建您的对照组和测试组

一旦你确定了你的无效假设和替代假设,下一步就是创建你的控制和测试(变量)组。这一步有两个重要的概念需要考虑,抽样和样本大小。

抽样
随机抽样是最常见的抽样技术之一。总体中的每个样本都有均等的机会被选中。随机抽样在假设检验中很重要,因为它消除了抽样偏差,而**消除偏差很重要,因为你希望你的 A/B 检验的结果能代表整个群体,而不是样本本身。
**

A/B 测试的一个问题是,如果你没有恰当地定义你的目标群体,或者你处于产品的早期阶段,你可能不太了解你的客户。如果你不确定他们是谁(试着创建一些用户角色开始吧!)那么你可能会得到误导性的结果。了解哪种采样方法适合您的使用案例非常重要。

样本量 在进行 A/B 测试之前,您必须确定最小样本量,这样您就可以消除覆盖偏差,即由于采样太少而产生的偏差。

4.A/B 测试的长度

这个这样的计算器可以帮助你确定从你的 A/B 测试中获得任何真正意义所需要的时间长度。

示例案例

我们现在将带您看一个例子。历史数据显示,每天大约有 3250 个独立访问者。每天大约有 520 个软件下载(比率为. 16**)和大约 65 个许可证购买(比率为**. 02**)。在理想情况下,下载率和许可证购买率都应该随着新主页而增加;统计上显著的负面变化应该是不部署主页变化的标志。然而,如果我们的指标中只有一个显示出统计上显著的积极变化,我们应该很乐意部署新的主页**

使用上面的链接进行测试天数的计算: 估计的现有转化率(%): 16%
您想要检测的转化率的最小改善(%): 50/520
100 %
变化/组合的数量(包括控制): 2
平均每日访客数量: 3250 测试中包含的访客百分比? 100% (3250) 运行测试的总天数: 6 天
*

预计现有转化率(%): 2 %
你要检测的转化率最小提升(%): 10/65
100 %
变异/组合数(含对照): 2
日均访客数: 3250 测试中包含的访客百分比? 100% (3250) 运行测试的总天数: 21 天
*

对于具有 Bonferroni 校正和 80%功率的 5%的总体类型 I 错误率,我们应该需要 6 天来可靠地检测每天 50 下载增加和 21 天来检测每天 10 许可证购买增加。以 0.05 的错误率执行两个单独的测试会带来犯太多 I 型错误的风险。因此,我们将应用 Bonferroni 校正,以 .025 的错误率运行每个测试,以防止出现太多错误。

在基本实验长度计算中没有考虑到的一点是,用户下载软件和实际购买许可证之间会有一段时间的延迟。也就是说,当我们开始实验时,在与 cookie 相关联的用户帐户实际回来进行购买之前,可能有大约七天的时间。在第一周内观察到的任何购买行为可能都不能归因于任何一种实验条件。考虑到这一点,我们将再运行大约一周的实验,让那些在第三周进入的用户有机会回来,并被计入许可证购买记录。

至于偏见,我们并不期望用户定期回到主页。下载和许可证购买是我们希望每个用户只发生一次的行为,所以没有真正的“回报率”需要担心。不过有一种可能是,如果新首页下下载软件的人多了,那么扩大的用户群就和原来首页下来页面的人有了质的不同。这可能会导致在网站上寻找支持页面的人更多地点击主页,从而导致每种情况下唯一 cookies 的数量不同。如果我们确实在不变指标(cookies 的数量)中看到了一些错误或不合适的地方,那么这可能是一个需要在进一步调查中探索的领域。

5.进行测试

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

一旦你进行了实验并收集了数据,你想确定你的控制组和变异组之间的差异是否有统计学意义。确定这一点有几个步骤:

  • 首先,你要设置你的 alpha 值。阿尔法是犯第一类错误的概率。通常,alpha 设置为 5%或 0.05
  • 其次,您希望通过首先使用上面的公式计算 t 统计量或使用 z 得分(也称为标准得分**)来确定 p 值(概率值),这可以让您了解数据点离平均值有多远…).**
  • 最后,比较 p 值α值**。如果 p 值大于 alpha,不拒绝 null!**

5.1 使用实际统计数据比较结果

不要依赖简单的一对一比较指标来决定什么可行,什么不可行。"版本 A 产生 20%的转换率,而版本 B 产生 22%的转换率,因此我们应该切换到版本 B!"请不要这样做。使用实际的置信区间、z 分数和统计显著性数据。

5.2 产品增长

改变颜色和布局可能会对您的关键绩效指标产生轻微影响。然而,这些成果似乎很短暂。产品的增长并不是因为把一个按钮从红色变成蓝色,而是来自于制造一个人们想用的产品。

不要选择你认为可能有效的特性,你可以使用 A/B 测试来知道什么有效。

5.3 分析数据

对于第一个评估指标,下载率,有一个非常令人信服的效果。从 0.1612 到 0.1805 的绝对增加导致 z 值为 7.87 (z 值= 0.1805–0.1612/0.0025),p 值小于 0.00001,远远超过任何标准显著性界限。但是,第二个评估指标,即许可证购买率,仅显示出从 0.0210 到 0.0213 的小幅增长(假设只有前 21 天的 cookies 占所有购买量)。这导致 p 值为 0.398 (z = 0.26)。

6.得出结论

尽管购买许可证的数量没有达到统计学意义,但新主页似乎对下载数量有很大的影响。基于我们的目标,这似乎足以建议用新主页替换旧主页。无论是通过购买率还是通过主页访问量的增加来确定许可证购买数量是否有显著增加,都需要等待进一步的实验或数据收集。

我们可能会做出的一个推论是,新主页吸引了通常不会尝试该程序的新用户,但这些新用户并没有以与现有用户群相同的速度转化为购买者。这是一个很好的故事,但根据给定的数据,我们实际上不能这么说。为了做出这个推论,我们需要更多关于个人访问者的详细信息,而这些信息是不可用的。然而,如果软件确实有报告使用统计的能力,这可能是一种查看某些配置文件是否更有可能购买许可证的方式。这可能会带来更多增加收入的想法。

如何进行人员分析成熟度模型评估

原文:https://towardsdatascience.com/how-to-conduct-a-people-analytics-maturity-model-assessment-569275eae5f8?source=collection_archive---------30-----------------------

使用埃克尔森的分析成熟度模型评估人员分析成熟度

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

约书亚·厄尔在 Unsplash 上的照片

本文改编自我在西北大学数据科学硕士项目中的商业领导力和沟通课程。这是一种分析任何组织的分析智商的方法。我希望通过我的工作,我也能够强调一些在一个组织中推动分析成功的关键因素。

本文包含以下几个部分:

  1. 介绍
  2. 埃克森的分析成熟度模型综述
  3. 人员分析成熟度模型概述
  4. 如何衡量人员分析功能的分析成熟度
  5. 如何衡量数据成熟度、人员分析计划的范围和规模
  6. 衡量分析文化以进一步支持人员分析计划
  7. 关键要点

简介

作为一名咨询出身的人,我记得我参加了那些强制性的在线培训课程,这些课程侧重于项目管理、交付原则和客户满意度。当我 2000 年开始职业生涯时,很少有公司关注内部事务。2008 年,谷歌启动了Project oxy gen——一种数据驱动的分析方法,用来回答关于他们自己的人的问题,例如:

  • 怎样才能成为一名优秀的经理
  • 我们如何解锁员工敬业度
  • 我们如何理解自己的员工,并帮助他们在工作中表现出色

根据 Bersin 关于人员分析的文章,自过去几年以来,随着越来越多的公司开始关注人力资本,叙事已经发生了变化。人力资本代表着我们员工的天赋、技能和经验 (Arena,M 2018),它们是公司在当今颠覆性领域取得成就的核心。公司开始探索的一个大问题是,我们如何利用数据、分析工具和方法来更好地了解和开发我们的人力资本,并为企业获得最佳价值。本文的目的是展示一种进行成熟度模型评估的方法,以确定他们在分析成熟度模型中的位置。

埃克森的分析成熟度模型

在他的名著《分析型领导者的秘密》中,Wayne Eckerson 描述了一个分析成熟度模型,该模型有 4 个主要的分析智商维度:数据成熟度、分析成熟度、分析文化以及规模和范围。他说,当公司从左下象限移到右上象限时,它们会获得更高的商业价值。 特别感谢韦恩·埃克森准许我使用这张图片

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

照片由韦恩·埃克森通过埃克森

左侧的分析成熟度涵盖了公司的分析能力,例如从标准报告到预测报告的使用。

数据成熟度是一个具有挑战性的象限,因为它涉及到从整个组织的各个部门收集数据并将其整合以实现企业级分析的集成策略。为了让一家公司能够在分析上竞争(像亚马逊、谷歌等),企业数据仓库战略至关重要。

分析文化在公司内部成功交付分析项目的过程中发挥着重要作用。因此,就像我们传统的转型计划一样,强大的赞助商、变革倡导者和管理层的支持为公司的分析工作定下了基调。

随着公司开始在整个企业内以协调的方式交付分析,组织内分析项目的规模和范围会增加。换句话说,人员分析不仅仅是关于人力资源部门可用的数据。为了了解业务驱动因素,我们还需要来自财务、销售、IT 和采购部门的数据。

人员分析成熟度模型

有几种方法可以在线获得人员分析成熟度模型。Josh Bersin 和他的团队在 2012 年提出了一个被广泛阅读的方法。根据我的调查研究,我试图重现下图中的关键级别。人员分析成熟度模型与左侧象限中埃克尔森的分析成熟度 4 个关键维度紧密相关。对于这项工作,我假设人员分析成熟度模型的第 1 级和第 2 级与埃克森的左下象限相关,而第 3 级和第 4 级将与埃克森的左上象限相关。

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

作者照片

现在,让我们来看看如何衡量公司人员分析功能的有效性。这是一个基于问卷的评估方法,包含一系列问题来支持我们的目标。所有问题的答案选项都是——强烈不同意、不同意、同意、强烈不同意

衡量人员分析的分析成熟度

为了衡量一个组织的分析成熟度,我们收集了对 3 个问题的回答(你可以和你的团队一起讨论更多的问题) :

  • 问题 1 :人力资源部门是否向经理和高管提供员工总数、离职、调动、休假、招聘等相关指标的仪表板(回答选项:完全不同意、不同意、同意、完全同意)
  • 问题 2 :人力资源部能否根据员工的表现、服务年限等,分析不同员工群体的多样性、薪酬和流失率。如果人员流失不是公司的问题,你可以将问题转化为对多样性的研究(回答选项:强烈不同意、不同意、同意、强烈不同意)
  • **问题 3:**HR 是否对员工数据进行外部对标,如职位分级、薪酬调查(答案选项:强烈不同意、不同意、同意、强烈不同意)
  • 问题 4 :人力资源不断开发预测模型以支持战略决策,例如进行 A/B 测试以测试人力资源干预是否有效。专家小组将研究为期 2 天的面对面入职培训与在线入职培训计划的有效性。请看我的文章这里

测量数据成熟度,规模&范围

以下一组问题有助于衡量任何组织内的数据成熟度、规模和范围:

  • 问题 5 : 您是否在数据库中捕获员工数据
  • 问题 6 : 人力资源部门是否与其他部门合作收集和利用数据,以提供企业范围的分析,例如去年的 7 大支柱学习计划如何帮助个人或团队提高销售业绩
  • 问题 7 : 人力资源部门是否与其他部门合作,通过组织或部门范围的调查、入职或离职调查、视频来获取数据,并能够进行高级分析,如主题建模、情感分析,以了解主题和通过员工反馈提出的主题

测量分析文化

我在这里引入了一个问题来理解组织内的赞助,但人们可以围绕变革管理添加更多这样的问题。

  • 问题 8 : 公司在董事会中是否有人力资源代表(人力资源主管)

计算分数

对于每个问题,适用以下点数分配:

a.强烈不同意:0 分

b.不同意:1 分

c.同意:2 分

d.非常同意:3 分

基于人员分析成熟度模型的组织分析成熟度级别可以根据以下分布进行计算:

  1. 0–4 分:人员分析模型的第 1 级和埃克尔森模型的左下象限
  2. 5-10 分:人员分析模型的第 2 级和埃克尔森模型的左下象限
  3. 11- 16 分:人员分析模型的第 3 级和埃克尔森模型的左上角象限
  4. 17 分及以上:人员分析模型的第 4 级和埃克尔森模型的左上角象限

关键要点

从我的研究中得到的关键是,在一个组织内建立一种分析文化是一个迷人的旅程,需要时间。从左下角象限(埃克尔森模型)或基于 excel 的报告的第 1 级(人员分析模型)开始,并在几年内上升到第 4 级,这一挑战令人生畏,但却非常令人兴奋。在我的演讲中,我经常听到和感受到人力资源专业人士的问题,他们后悔数据的混乱状态,缺乏赞助,缺乏来自单一数据库的国家级员工数据。我想告诉他们,通过最初的繁重工作和基于简短原型的分析方法的小小推动,随着时间的推移,也可以极大地帮助奠定分析文化的关键基础。去年在救世军,我们开始了一个疯狂的想法,将数据从多个工资系统到一个系统工作日的整个数据迁移过程自动化。那时,我们谁也不知道如何实现这一壮举。我对类似工作的搜索导致了一篇在线研究论文,激励我们继续这个想法。今天,我们有来自不同部门的人来找我们,了解更多关于这个工具的信息,以及他们如何在其他项目中利用它。在一家了不起的公司里,成为构建数据文化的一部分,这的确是一次美好的经历。点击这里,了解我们的数据之旅

引用:

Arena,M (2018)适应性空间

Eckerson,W (2012)分析型领导者的秘密

AIHR 分析:发现您组织的人力资源分析成熟度等级

Bersin 的人才分析成熟度模型方法

如何进行市场篮子分析

原文:https://towardsdatascience.com/how-to-conduct-market-basket-analysis-f14f391a8625?source=collection_archive---------17-----------------------

通过关联分析研究消费者偏好和生活方式

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

罗布·麦克斯韦在 Unsplash 上的照片

购物篮分析是大型零售商用来发现商品之间隐藏关联的关键技术之一。市场购物篮分析使用交易数据,即客户在一次购买中购买的所有商品的列表,来确定一起订购或购买的商品,并确定共现模式。这种强有力的分析有助于揭示消费者的偏好,而通过在线调查获取这些偏好是非常具有挑战性的。零售商使用市场购物篮分析的结果来指导商店中的产品放置、跨类别和联合营销促销等。

介绍

我上次购物的经历相当不可预测。我在一家亚洲商店买了一些东西。这是我的购物篮。

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

该列表将与其他顾客的数千次购物或购物篮一起进入商店数据库的一行。关联规则挖掘是从存储在数据库中的交易数据中提取有用信息的最流行的方法之一。项目集是从杂货店所有待售项目中选择的项目集合。一个项目集可以包含 2、3 个项目,依此类推。关联规则确定项目集中项目之间的关系。然后,这些关系被用于构建包含所购买商品的 IF-Then 规则的配置文件。

这些规则可以写成:

If {A} Then {B}

规则的 IF 部分称为前提,规则的 THEN 部分称为结果。因此,前因是条件,结果是结果。关联规则有三个共同决定规则强度的关键度量:支持度、置信度和提升度。

让我们假设有 100 个客户。其中 10 个人带了牛奶,8 个人买了黄油,6 个人两个都买了。如果我们要评估关联规则“如果有人买牛奶,他们也会买黄油”,那么关联规则的支持度可以计算为:

(牛奶和黄油的概率)或者换句话说(包含牛奶和黄油的篮子的数量)/(总篮子的数量)

Support = (Probability of Milk and Butter) = 6/100 = 0.06

0.06 的支持标准意味着每一百个市场篮子中有六个既有牛奶又有黄油。

置信度 =前件中项目集的支持度除以项目集的支持度。换句话说,它是条件概率 P(黄油|牛奶),计算如下:

Confidence of P(B|A) = P(AB) / P(A) => (Probability of Milk and Butter) / (Probability of Milk)
OR
Confidence = Support / P (Milk)
OR
Confidence = 0.06 / (10/100) = 0.06/0.1 = 0.6

最后, lift 是相对预测置信度的度量。在关联规则“如果牛奶那么黄油”中,假设顾客已经购买了牛奶,我们可以用这种信心来预测他将购买黄油。

Lift = P(B|A) / P(B)
or
Lift = Confidence / P(Butter) = 0.6 / (8/100) = 0.6/0.08 = 7.5

提升值大于 1 反映了更强的关联性。

数据集和探索性数据分析

为了这个分析,我利用了一个由 Hahsler,Hornik 和 Reutterer (2006)分析的食品杂货数据集。总共有 9835 笔交易,包含 169 个不同的杂货项目。

grocery_data = data("Groceries")
#Show dimensions of the dataset
print(dim(Groceries))
print(dim(Groceries)[1]) # 9835 market baskets for shopping trips
print(dim(Groceries)[2]) # 169 initial store itemssummary(Groceries)

仔细观察数据集,可以发现每一行都有一个项目子集。

# Let's take a look at the first 5 transactions
inspect(Groceries[1:5])
    items                                                                
[1] {citrus fruit,semi-finished bread,margarine,ready soups}             
[2] {tropical fruit,yogurt,coffee}                                       
[3] {whole milk}                                                         
[4] {pip fruit,yogurt,cream cheese ,meat spreads}                        
[5] {other vegetables,whole milk,condensed milk,long life bakery product}

让我们看一下频率图,以确定商品出现在市场购物篮中的频率。我们将支持度设置为 0。确保地块中的每个项目至少出现在每 10 个购物篮中

itemFrequencyPlot(Groceries, support = 0.025, cex.names=0.8, xlim = c(0,0.3),type = "relative", horiz = TRUE, col = "dark red", las = 1,
xlab = paste("Proportion of Market Baskets Containing Item",
"\n(Item Relative Frequency or Support)"))

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

R 中的项目频率图

让我们来看看购物篮中最常出现的 20 种商品。

# Plot the frequency of top 20 items
itemFrequencyPlot(Groceries,topN = 20)

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

R 中的项目频率图

所以全脂牛奶、蔬菜、面包卷、苏打水和酸奶是商店里最常购买的五种商品。

关联规则挖掘

R 中 arules 包实现的 Apriori 算法有助于挖掘关联规则。通过将支持度和置信度的阈值设置为 0.025 和 0.05,获得一组 344 个规则。

rules <- apriori(groceries, parameter = list(support = 0.025 , confidence = 0.05))AprioriParameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target  ext
       0.05    0.1    1 none FALSE            TRUE       5   0.025      1     10  rules TRUEAlgorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUEAbsolute minimum support count: 245set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[55 item(s), 9835 transaction(s)] done [0.03s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.01s].
checking subsets of size 1 2 3 4 done [0.00s].
writing ... [344 rule(s)] done [0.00s].
creating S4 object  ... done [0.00s].> rules
set of 344 rules

让我们研究一下按提升值排序的前 10 个关联规则。

inspect(sort(rules,by="lift")[1:10])

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

手动检查所有 344 个关联规则将是极其令人厌烦的,并且不是可行的选择。使用 R 包 arulesViz,我们将实现可视化技术来探索这些关系。

关联规则可视化

可以查看水平轴为支撑、垂直轴为提升的散点图。点的颜色编码与置信度有关。

plot(rules,measure = c("support","lift"),shading="confidence")

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

Unwin、Hofmann 和 Bernt (2001)介绍了一种特殊版本的散点图,称为双键图。这里,支持度和置信度分别代表 X 轴和 Y 轴,色点用于指示“顺序”,即每个规则中包含的项目数。

plot(rules,shading="order",control=list(main="Two-Key plot"))

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

从上面的情节可以清楚地看出,顺序和支持度是成反比的。

下图以矩阵气泡图的形式提供了已识别关联规则的更清晰视图。关联规则的前件(左侧)中的项目表示在矩阵顶部的标签中,而关联规则的后件(右侧)中的项目表示在矩阵的右侧。支持度由每个气泡的大小表示,提升度由颜色强度反映。

plot(rules,method="grouped",control=list(col=rev(brewer.pal(9,"Greens")[4:9])))

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

现在,如果我要确定哪些产品是通常与蔬菜一起购买的,我可以从总体关联规则中过滤并报告数据。下面我按照 lift 对这些规则进行排序,并找出前 10 个关联规则。

vegie.rules <- subset(rules,subset=rhs %pin% "vegetables")
inspect(sort(vegie.rules,by="lift")[1:10])

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

接下来,我在下面的网络图中表示了经常购买的蔬菜产品的关联规则。

plot(top.vegie.rules,method = "graph",control = list(type="items"),shading = "lift" )

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

从网络图中可以明显看出,顾客在购买蔬菜时可能会购买牛肉、奶制品、农产品、面包和香肠。

结论

作为相对频率或概率估计,支持值位于 0 到 1 之间。只要不是非常低,较低的支持值是可以的。置信度也取 0 到 1 之间的值,因为它是一个条件概率度量。更高的置信度值通常是优选的。最后,提升值需要大于 1.0 才能被管理层重视。

我们上面所做的分析本质上是描述性的,因为分析购物数据是为了研究购物行为。将这一分析带入下一步,就是在商场和地面上实施这项研究的见解。

零售商经常使用关联规则的发现来做出关于商店布局、产品捆绑或交叉销售的决策。商店经理也在进行地面实验,如 A/B 测试,以研究购物者对新商店布局的反应。这是一项正在进行的令人着迷的研究,旨在真正测试购物篮预测模型的性能。

所以下次你走进当地超市,发现安排已经改变,你现在知道为什么了。

参考

我要特别感谢米勒教授的指导和启发。我在西北大学攻读数据科学硕士课程期间曾在他的课上学习过,他的书和他的课对我的数据科学生涯产生了深远的影响。我的工作借鉴了以下文献:

托马斯·w·米勒(2014) 预测分析中的建模技术

米(meter 的缩写))Hahsler,S. Chelluboina (2015) 可视化关联规则:R-extension aruleviz 简介

Rstat 构建菜篮子模型

如何在 AWS 上为 Fargate 任务配置 IAM 角色

原文:https://towardsdatascience.com/how-to-configure-iam-roles-for-fargate-tasks-on-aws-76ad54f11314?source=collection_archive---------18-----------------------

基本思想和具体实现

这篇博文是关于 AWS 上无服务器批处理作业的特定类型架构的三篇技术深度文章之一。如果你想了解更多关于云设置的背景,请点击这里了解更多细节。已实现服务的总体情况如下所示:

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

完整的架构(作者插图)。

简而言之,该架构由一个用于开发的组件块和另一个用于执行批处理作业的组件块组成。对于这篇博文,我们只关注这个架构的角色和策略。还有一个公共代码库,允许你基于 Cloudformation 脚本复制完整的服务及其所有部分。

当我们谈到角色和策略时,我们会谈到身份和访问管理(IAM) 。It 构成了每个 AWS 云架构的主要安全块。IAM 限制了在给定的云环境中哪个实体可以做什么。对于这篇博文,您需要理解两个概念:角色策略

当用户或服务想要在云中做一些事情时,他们承担角色。当您指定一个角色时,您可以限制可以使用它的实体的类型。例如,您可以为人类用户定义一个角色,允许他们查看所有内容,但不能更改任何内容。如果 AWS 服务试图使用该角色,它会失败。将角色视为用户或服务在您的云环境中可以做什么的组织保护伞。

策略,相反,列出了角色可以执行的具体动作。与角色限制哪个实体可以承担它们一样,策略也限制它们可以使用哪些资源。

当你设计你的角色和政策时,坚持最小特权原则。也就是说,只允许服务需要的访问和操作。超出这个范围的任何扩展都是潜在的安全问题。例如,如果服务需要将数据写入 S3 存储桶,您不应该实现允许所有 S3 操作的策略。

在我们进入大图之前,让我们先从云形成脚本的小入门开始。如果你已经有了云形成或者类似概念的经验,你可以略读或者跳过下面三段。

CloudFormation 是针对基础设施的 AWS 服务,代码为。也就是说,您定义一个目标基础设施,将其推送给 AWS,AWS 为您提供它。您将资源组织在所谓的堆栈中,这使得调整、监控或删除它们变得非常容易。

您可以在 JSON 或 YAML 文件中编写 CloudFormation 脚本。这里和代码库中的所有例子都是 YAML 文件,但是您也可以在 JSON 中做同样的事情。

还有一组专门针对 CloudFormation 的命令可供您使用。在接下来的例子中,我使用了其中的三个:

  1. !Ref 是内部参考;也就是说,CloudFormation 从同一个脚本中插入一个值。
  2. !Sub 用于将变量替换成字符串。
  3. !GetAtt 类似于“!Ref”但是指向资源的特定属性,而不是一般的引用。

大局

从角色和策略的角度来看,我们必须考虑服务的两个组成部分。对于每个部分,我们需要确定哪些服务需要与其他服务进行交互。没有传出交互的服务,如 S3 或代码库,可以保持原样。需要与其他组件进行交互的服务需要允许它们这样做的策略。

对于开发组件,我们需要确保我们可以构建一个容器映像并将其推送到注册表中。对于批处理作业组件,我们需要确保触发器可以运行来自注册表的最新容器映像。

为了避免抽象的思考,让我们深入实现细节。我为每个构建块提供了一个概览图,以便您可以直观地了解。

实施细节

如前所述,角色是策略的组织保护伞。为了简单起见,本例中的每个角色都只与一个策略相关。在我们研究每个策略之前,让我向您介绍一下角色的两个主要属性:

  1. AssumeRolePolicyDocument 定义了哪个服务可以承担这个角色。文档的主体部分(参见下面的代码片段以了解详细信息)描述了这一点。动作部分的 stsAWS 安全令牌服务的缩写。该服务提供临时凭据来验证操作。
  2. ManagedPolicyArns 指的是与该角色相关联的策略文档。ARN 是一个亚马逊资源名称,作为在 AWS 上创建的资源的 ID。

下面是以 CodeBuild 角色为例的 CloudFormation 中的情况:

最佳实践是为架构的每个组件定义一个角色。从技术上讲,您可以将策略嵌入到您的角色定义中。但是,如果创建一个单独的策略资源,阅读和维护起来会更容易。

发展部分的政策

开发工作流中涉及到两个服务:代码管道代码构建。CodePipeline 是一个编排工具,每当开发人员将新版本的主分支推送到代码存储库时,它就会触发 CodeBuild 项目。

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

代码管道策略(作者举例说明)。

首先,让我们看看代码管道。在我们的场景中,服务需要与三个服务交互:

  • 它需要从 CodeCommit 接收更新,以在主分支中注册更改。
  • 反过来,它需要触发相关的 CodeBuild 项目的新运行。
  • 它需要能够保存和收集从 S3 工件。

下面是 CodePipeline 在 CloudFormation 中的角色和相关策略:

**注意:**为了简单起见,在这个例子和下面的例子中,我没有限制资源。在现实世界的实现中,最小特权原则也要求您最小化被访问的资源!

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

代码构建策略(作者举例说明)。

其次,还有 CodeBuild 。它涉及四种不同的服务。

  • 它需要从 CodeCommit 中克隆存储库。
  • 它需要读写来自 S3 的工件。
  • 它需要将新图像推送到弹性容器注册中心(ECR)
  • 它需要将日志信息写入 CloudWatch

最后一点是可选的,但是我保证如果你漏掉了它,你会后悔的。相应的 CloudFormation 脚本如下所示:

开发组件的两个角色应该是不言自明的。现在事情变得有点复杂了。

批处理作业组件的策略

我们现在要为批处理作业定义角色和策略。也就是说,对于 Fargate 任务和触发它的 CloudWatch 规则。让我们先从稍微令人困惑的一个开始:Fargate 任务。

虽然在架构图中一个盒子代表了 Fargat 任务,但是它需要两个角色。想想你和老板的关系。你的老板有权给你分配任务。你需要工具来完成指定的工作。这也是你为法盖特所需要的。一个执行角色,也称为“老板角色”,一个任务角色,也称为“员工角色”

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

Fargate policies(作者插图)。

执行角色包含对两个服务的访问:

  • 它需要访问弹性容器注册表(ECR) 中的容器图像。否则,它将无法加载和启动批处理作业的容器映像。
  • 与 CodeBuild 类似,它需要将日志信息写入 CloudWatch

下面是 CloudFormation 中执行角色及其策略的样子:

任务角色的重要策略取决于开发人员在容器映像中放入了什么。也就是说,不知道开发人员实现了什么,您就不能决定正确的策略集。让我们假设该任务从 S3 加载一些数据,对其进行转换,并将其写回到另一个桶中。在这个简单的例子中,您需要为任务角色配置两个服务:

  • 它需要访问 S3 桶来获取数据并保存输出。
  • 它需要将日志信息写入 CloudWatch

有关详细信息,请查看 CloudFormation 规范:

同样,特定的资源和操作完全取决于容器映像中实现的业务逻辑。

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

CloudWatch 政策(作者插图)。

最后是 CloudWatch 规则,它触发批处理作业。它的角色和政策也很简单,涉及两种服务:

  • 如果需要,它需要访问 IAM 来将角色传递给 Fargate 任务。
  • 它需要访问弹性容器服务(ECS) ,这是 Fargate 背后的编排服务。

这是云形成规范:

在这一点上,一个自然的问题是:为什么有几个地方允许访问 CloudWatch 日志?为什么不为日志记录定义一个策略,并将它附加到所有需要它的角色上呢?

避免这种情况的一个主要原因是:共享策略增加了资源之间的依赖性。这些依赖会在以后反噬你。如果您更改由几个角色承担的策略,您可能会在没有意识到的情况下破坏东西。

我希望这篇文章能帮助你更好地理解如何思考和构建 IAM 角色和策略。同样,如果你想了解更多关于架构的知识,请参考概念文章。如果你打算重建它,看看公共代码库。此外,很快还会有一篇文章将这一讨论扩展到整个服务的具体构建块。如果你对这种服务的网络方面更感兴趣,我已经给写了一篇关于这个的博文。

请在评论中告诉我你的想法和经历。我也很乐意在 TwitterLinkedIn 上联系。感谢您的阅读!

如何从 python 连接搜索应用程序并与之交互

原文:https://towardsdatascience.com/how-to-connect-and-interact-with-search-applications-from-python-520118139f69?source=collection_archive---------59-----------------------

一个 pyvespa 图书馆概述:连接、查询、收集数据和评估查询模型。

Vespa 是目前可用的更快、更具扩展性和更先进的搜索引擎,imho。它有一个原生张量评估框架,可以执行近似最近邻搜索并部署 NLP 建模的最新进展,如 BERT 模型

这篇文章将通过 pyvespa 库 向您概述 Vespa python API。 该库的主要目标是允许更快的原型开发,并促进 Vespa 应用的机器学习实验。

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

大卫·克洛德Unsplash 上的照片

我们将连接到 CORD-19 搜索应用,并在此将其作为示例。您可以稍后使用自己的应用程序来复制以下步骤。未来的帖子将会更深入地讨论本概述教程中描述的每个主题。

你也可以从 Google Colab 运行这里包含的步骤。

安装

警告:库正在开发中,可能会发生向后不兼容的变化。欢迎反馈和贡献。

这个库可以在 PyPI 上获得,因此可以和pip一起安装。

!pip install pyvespa

连接到正在运行的 Vespa 应用程序

我们可以通过使用适当的 url 创建一个 Vespa 的实例来连接到一个正在运行的 Vespa 应用程序。产生的app将用于与应用程序通信。

from vespa.application import Vespa

app = Vespa(url = "https://api.cord19.vespa.ai")

定义查询模型

轻松定义匹配和排名标准

在构建搜索应用程序时,我们通常希望尝试不同的查询模型。一个查询模型由匹配阶段和排序阶段组成。匹配阶段将定义如何基于发送的查询匹配文档,排名阶段将定义如何对匹配的文档进行排名。这两个阶段都可能变得相当复杂,能够轻松地表达和试验它们是非常有价值的。

在下面的例子中,我们将匹配阶段定义为weakANN 操作符的联合WeakAnd将根据查询术语匹配文档,而近似最近邻(ANN)操作符将根据查询和文档嵌入之间的距离匹配文档。这说明了在 Vespa 中结合术语和语义匹配是多么容易。

from vespa.query import Union, WeakAnd, ANN
from random import random

match_phase = Union(
    WeakAnd(hits = 10), 
    ANN(
        doc_vector="title_embedding", 
        query_vector="title_vector", 
        embedding_model=lambda x: [random() for x in range(768)],
        hits = 10,
        label="title"
    )
)

然后,我们定义由已经在应用程序模式中定义的bm25 rank-profile 完成的排名。在本教程的后面,我们将list_features=True设置为能够收集排名特征。在定义了match_phaserank_profile之后,我们可以实例化Query模型。

from vespa.query import Query, RankProfile

rank_profile = RankProfile(name="bm25", list_features=True)

query_model = Query(match_phase=match_phase, rank_profile=rank_profile)

查询 vespa 应用程序

通过查询 API 发送查询。更多示例参见查询页面

我们可以使用刚刚定义的query_model通过query方法向应用程序发出查询。

query_result = app.query(
    query="Is remdesivir an effective treatment for COVID-19?", 
    query_model=query_model
)

我们可以看到 Vespa 检索到的文档数量:

query_result.number_documents_retrieved1121

以及返还给我们的文件数量:

len(query_result.hits)10

标记数据

如何构造标签数据

我们经常需要通过 ML 评估查询模型或者收集数据来改进查询模型。在这两种情况下,我们通常需要带标签的数据。让我们创建一些带标签的数据来说明它们的预期格式以及它们在库中的用法。

每个数据点包含一个与查询相关的query_id、一个queryrelevant_docs

labelled_data = [
    {
        "query_id": 0, 
        "query": "Intrauterine virus infections and congenital heart disease",
        "relevant_docs": [{"id": 0, "score": 1}, {"id": 3, "score": 1}]
    },
    {
        "query_id": 1, 
        "query": "Clinical and immunologic studies in identical twins discordant for systemic lupus erythematosus",
        "relevant_docs": [{"id": 1, "score": 1}, {"id": 5, "score": 1}]
    }
]

默认分配"score": 0不相关的文档。如果标签数据中缺少该字段,相关文档将默认分配"score": 1。相关和不相关文档的默认值都可以通过适当的方法进行修改。

收集培训数据

收集培训数据以分析和/或改进排名功能。更多示例参见收集训练数据页面

我们可以根据具体的查询模型,用 collect_training_data 方法收集训练数据。下面我们将为每个查询收集两个文档,以及相关的文档。

training_data_batch = app.collect_training_data(
    labelled_data = labelled_data,
    id_field = "id",
    query_model = query_model,
    number_additional_docs = 2,
    fields = ["rankfeatures"]
)

默认情况下,会返回许多等级要素。我们可以选择其中的一些进行检查:

training_data_batch[
    [
        "document_id", "query_id", "label", 
        "textSimilarity(title).proximity", 
        "textSimilarity(title).queryCoverage", 
        "textSimilarity(title).score"
    ]
]

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

评估查询模型

定义度量并评估查询模型。更多示例参见评估页

我们将定义以下评估指标:

  • 每次查询检索到的文档百分比
  • 每次查询召回 10 次
  • 每次查询 MRR @ 10
from vespa.evaluation import MatchRatio, Recall, ReciprocalRank

eval_metrics = [MatchRatio(), Recall(at=10), ReciprocalRank(at=10)]

评估:

evaluation = app.evaluate(
    labelled_data = labelled_data,
    eval_metrics = eval_metrics, 
    query_model = query_model, 
    id_field = "id",
)
evaluation

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值