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

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何在 AutoML 和 MLFlow 之间建立集成

原文:https://towardsdatascience.com/how-to-build-an-integration-between-automl-and-mlflow-6d66d4bdc4d1?source=collection_archive---------30-----------------------

一个关于如何自动运行 MLFlow 的追踪和 H2O 的 AutoML 的教程

unspash.com

在本文中,我们将回顾 AutoML 的概念,它如何提高您的生产力,以及如何跟踪它的性能指标。

我们将使用以下技术:

什么是 AutoML,我为什么要使用它?

顾名思义,它是自动化机器学习管道的过程。我们可以自动化过程的各个阶段,如数据准备、特征工程、模型选择和超参数选择。在本教程中,我们将主要关注模型选择。

使用这种方法有许多好处,例如:

  • 通过提高数据科学家的工作效率来降低成本
  • 减少他们必须做的重复性工作和无聊任务的数量
  • 模型选择的性能可用作基准,并确定哪些模型最适合由数据科学家进一步研究

什么是 MLFlow?

MLFlow 是一个开源平台,用于在训练后监控和保存机器学习模型。它的伟大之处在于,它可以与 H2O 或 Spark 等其他框架集成,构建一个统一且易于使用的环境。

现在让我们深入到在实践中使用 AutoML 的步骤。

TL;DR:代码存储在Github中。

第一步:准备好环境

要准备好环境,我们需要安装项目文件夹中的新依赖项:

pip install -r requirements.txt

我们还需要通过在终端中键入以下命令来启动 MLFlow 服务器:

mlflow ui

我们现在可以通过在浏览器中运行来查看 MlFlow ui 了[http://127.0.0.1:5000](http://127.0.0.1:5000):

现在我们应该能够可视化我们运行的所有实验(训练步骤)。我们还可以启动Jupyter lab笔记本,这是我们编写代码的环境:

jupyter lab

第二步:启动 AutoML 框架

H2O 是一个分布式框架,为了在本地使用它,我们需要启动一个服务器。根据您的设置,这可能需要一分钟左右的时间:

h2o.init()

第三步:创建 MLFlow 实验

MLFlow 使用实验的概念来跟踪机器学习模型的进展。

try:
    experiment = mlflow.create_experiment(experiment_name)
except:
    experiment = client.get_experiment_by_name(experiment_name)
mlflow.set_experiment(experiment_name)

如果已经创建了实验,我们就重用它。

第四步:进行培训

我们已经到了最有趣的部分,使用 auto ml 来做训练。使用数据的独立子集并行训练和验证多个模型(6 重交叉验证)。每次新的训练运行都会保存一些验证指标和表现最好的模型(leader)。

with mlflow.start_run():
    model = H2OAutoML(max_models=10, max_runtime_secs=300, seed=24, nfolds=6)
    model.train(x=x_cols, y=y_cols, training_frame=train, validation_frame=valid) mlflow.log_metric("rmse", model.leader.rmse())
    mlflow.log_metric("log_loss", model.leader.logloss())
    mlflow.log_metric("mean_per_class_error", model.leader.mean_per_class_error()) mlflow.h2o.log_model(model.leader, "model")

    lb = model.leaderboard
    lb = get_leaderboard(model, extra_columns='ALL')
    print(lb.head(rows=lb.nrows))

我们已经决定运行 10 个模型。使用get_leaderboard函数,我们可以看到已经运行了哪些机器学习算法:

训练被记录在 MLFlow 中,我们可以与未来的实验进行比较:

第五步:做预测

最后一步是和新当选的领导人一起实际做预测。出于本教程的目的,我们将只使用验证数据,但实际上我们需要使用新的数据。

all_mlflow_runs = client.list_run_infos(experiment.experiment_id)
if len(all_mlflow_runs) > 0:
    run_info = all_mlflow_runs[-1]
    model = mlflow.h2o.load_model("mlruns/{exp_id}/{run_id}/artifacts/model/".format(exp_id=experiment.experiment_id,run_id=run_info.run_uuid))
    result = model.predict(valid)
else:
    raise Exception('Run the training first')

我们再次使用 MLFlow 读取实验中的最新运行,并加载GLM模型。如果我们从来没有运行过训练,我们可以抛出一个异常来通知用户他必须先这样做。

我们已经看到,通过几个简单的步骤,我们可以实现模型选择、跟踪和加载/保存给定数据集的最佳机器学习模型的自动化过程。虽然在 Kaggle 这样的比赛中,我们可以看到人类仍然可以轻松击败 AutoML 框架,但我们仍然可以将它们作为我们数据科学工具包中的另一个工具,来提高和改善我们的性能。

作为数据科学初学者如何建立在线投资组合?

原文:https://towardsdatascience.com/how-to-build-an-online-portfolio-as-a-beginner-in-data-science-12b7a345a561?source=collection_archive---------13-----------------------

为数据科学家建立在线投资组合的技巧。

图片来自 Pixabay 并由 AiArtist Chrome 插件风格化(由我构建)

作为一个数据科学的初学者,你很难凭借你的简历和大学项目在人群中脱颖而出。因此,越来越多的初级数据科学家有兴趣通过博客或 Youtube 视频建立在线投资组合,以便获得更多的关注。

但是作为一个初学者,如何为数据科学社区提供价值呢?他们能想到的每一个数据科学项目似乎都已经完成了,并且可以通过代码在线获得。还有,初学者通常没有任何繁重的计算资源来训练深度学习算法。

在这篇文章中,我们将看到一些增加价值和建立投资组合的方法,尽管我是数据科学的绝对初学者

1.像企业家一样思考

不要考虑一个项目,而是考虑一个产品。如果没有数据收集和培训,您能否将多种现有的预训练算法结合起来,构建一个满足需求的解决方案?

我们举个例子来理解这一点。如果你想到 GAN(生成对抗网络)的项目,网上有从生成人脸到生成动漫角色的项目。如果考虑光学字符识别(OCR)项目,有几个在线项目可以将 OCR 应用于法律、医疗、银行文档和提取文本。如果你想到一个语言翻译项目,那么有几个代码示例可以使用不同的序列到序列(seq2seq)技术进行训练,如 LSTM 的,transformers 等。

如果你正在考虑一个项目,那么你会遇到上述每个例子的障碍。相反,考虑一个产品。

你能建立一个图像转换器,将图像中的文本转换成不同的语言,并替换原始文本吗?例: Word lens 被谷歌收购

你可以使用同样的技术来构建一个迷因或引语翻译器。或者您可以使用相同的技术将一种语言的演示幻灯片转换成另一种语言。

引自罗伯特·弗罗斯特,图片由西班牙语翻译成英语。

结合上面讨论的三种算法 OCR,图像修复(GAN)和翻译,我们可以创建一个如下的管道来获得最终的翻译图像。

管道结合了所有算法,如 OCR、GAN 和翻译。

这可能是一个展示你的技能组合的项目。它是用预训练的模型开发的,不像 GPU 那样使用任何繁重的计算资源来训练。到今天为止,我在网上找不到任何有同样代码的项目。也许你可以构建一个 chrome 插件来翻译迷因和引语的图片,这样也能获得人气。

如果你正在 NLP 中寻找一个类似的例子,看看我的对或错问题生成算法,它完全是使用预先训练的 GPT2、句子 BERT 和选区分析器模型构建的。

应用创新技术,你可以建立一个引人注目的项目组合,而无需训练 AI 算法,只停留在应用的 AI 层。

2.利用该领域的前沿进展

如果你是初学者,你会觉得很难跟上前沿研究。虽然这是真的,但对于初学者来说,也有一个增加价值的稳赚不赔的方法。

由于这项研究是新的,通常文档很差,并且当其他初学者遇到困难时,没有在线资源可供他们搜索。你可以很容易地为一个新图书馆写入门指南,或者为一篇新发表的论文写研究总结等等。您还可以将现有技术应用到新发布的算法中,并展示您的结果。

一些例子是-

斯坦福大学的 NLP 中有一个新的图书馆叫做 Stanza 。因为这个库是新的,所以没有太多的资源来开始使用它。你可以探索图书馆,写一些初学者指南,获得在线流量。

ii) 在训练中,大量使用任何 NLP 分类算法,如情感分析或摘要、Glove 或 Word2vec 嵌入向量。如果一个新的单词/句子嵌入(例如:BERT)发布了,你可以用新的嵌入尝试相同的算法,并在线发布你的结果/表现。

3.微调或迁移学习

如果你的技能处于微调(NLP)或迁移学习(计算机视觉)的中级水平,那么你可以利用一些时间来收集和清理一个小数据集。然后,您可以使用数据集来微调预训练的 NLP 或计算机视觉模型,并将其用于更新的用例。

示例 1:您可以收集或创建一个真/假对数据集,并训练/微调任何序列以对 transformer 模型进行排序。

示例 2:您可以针对给定主题收集一些学生论文答案,并微调 BERT 模型来自动给论文评分。

如果你有时间收集数据并有一些计算资源,这些是你可以做的事情。

提示:有免费的计算资源来在线训练深度学习模型,如 Google Colab 和 Paperspace 。只要你的模型训练在几个小时内完成,你就可以利用这些。

4.核心培训或研究

如果你的技能属于这一类,那么你可以做以下事情来建立一个更深层次的专业知识组合。

  1. 计算——要解决计算资源问题,您可以在网上找到开发者倡导者和社区构建者,并解释您正在做什么来获得一些计算积分。例如:AWS 的员工(开发者倡导者)围绕 AI/ML 建立开发者社区,他们利用 AWS Sagemaker 和其他 AI 服务。你可以在 LinkedIn 上找到他们,试试运气:)
  2. 如果你对核心研究感兴趣,并对算法有更深的理解,那么就利用这一点来写关于给定主题的深度文章。例:写一写“文本摘要算法综述——过去现在和未来”。您可以讨论给定总结算法的优缺点,写下您认为该算法在未来将如何发展,等等。这显示了你对某一主题的理解,并帮助你作为该领域的专家建立一个稳固的投资组合。

祝人工智能探索愉快,如果你喜欢它的内容,请随时在推特上找到我。

如果你想学习使用变形金刚的现代自然语言处理,看看我的课程使用自然语言处理生成问题

如何建立和应用朴素贝叶斯分类进行垃圾邮件过滤

原文:https://towardsdatascience.com/how-to-build-and-apply-naive-bayes-classification-for-spam-filtering-2b8d3308501?source=collection_archive---------7-----------------------

数据科学模型

有效模型的简单实现

Mathyas Kurmann 在 Unsplash 上拍摄的照片

我相信,今天几乎每个人都有一部智能手机,很多人都留有一两封电子邮件。这意味着你必须熟悉大量的信息,包括大笔的钱、美妙的彩票中奖、精美的礼物和生活的秘密。我们每天都会收到几十条垃圾短信,除非你使用训练有素的过滤器。它们可能是有害的,只是令人讨厌或占用空间,但它们也可能包含病毒或钓鱼企图。无论如何,都不是我们要处理的内容。所以对好的垃圾邮件过滤器的需求总是很高。

让我告诉你(或者提醒你,如果你已经熟悉的话)一个非常有效的垃圾邮件过滤算法:朴素贝叶斯分类。虽然在 scikit-learn 包中已经有了实现,但我想从头开始重新创建算法。首先,我想揭示隐藏在实现背后的逻辑。其次,我想展示与数据集准备相关的算法。

1.一点理论

朴素贝叶斯分类是一种简单的概率算法,它基于这样一个事实,即模型的所有特征都是独立的。在垃圾邮件过滤器的上下文中,我们假设消息中的每个单词都独立于所有其他单词,并且我们在忽略上下文的情况下对它们进行计数。

我们的分类算法根据当前单词集的条件产生邮件是垃圾邮件还是非垃圾邮件的概率。概率的计算基于贝叶斯公式,并且公式的组成部分基于单词在整个消息集中的频率来计算。

那么,算法是如何工作的呢?

2.一点数学知识

首先,我们采用条件概率的贝叶斯公式,并将其应用于我们的任务:

包含单词(w1、w2、w3、…)的消息是垃圾邮件的概率与得到垃圾邮件的概率乘以消息中每个单词属于垃圾邮件消息的概率的乘积成比例。这是什么意思?对于邮件中的每个单词,我们计算它在垃圾邮件中被发现的概率。在我们的环境中:

  • P_spam —我们数据集中的垃圾邮件部分
  • P_wi_spam —在垃圾邮件中找到某个单词的概率。

根据同样的逻辑,我们定义:

  • P_not_spam —数据集中非垃圾邮件的一部分
  • P_wi_non_spam —单词在非垃圾邮件中出现的概率。

但是我们仍然不知道如何计算每个单词的概率。不过,我们有另一个公式:

我们这里有什么:

  • N_vocabulary —整个数据集中唯一单词的数量。
  • N_spam —垃圾邮件中的总字数。
  • N_wi_spam —一个单词在所有垃圾邮件中重复出现的次数。
  • Alpha —当消息中的某个单词在我们的数据集中不存在时的系数。

简而言之:一个单词属于垃圾邮件的概率是这个单词在我们的数据集的“垃圾邮件部分”中的出现频率。

同样,相同的公式(但是具有其他值)对于单词属于非垃圾邮件的概率是正确的。

数学已经结束,但是不要担心,我将显示数据集示例中的所有值和公式。

3.资料组

出于我们的目的,我们将使用 Tiago A. Almeida 和 José María Gómez Hidalgo 收集的短信。它是免费的,可以从 UCI 机器学习库下载。

数据集结构很简单。它包含两列——一列用于标签“spam/ham ”,另一列用于邮件文本。

它包含 5572 条不同消息的记录以及 747 条垃圾消息。

sms_data.groupby('Label').count()Out[6]:
ham 4825
spam 747

我们有足够的数据开始分析。

4.准备

在算法应用之前,我们需要准备数据。首先,我们将去掉标点符号。然后,我们将把所有的文本转换成小写字母,并把它分成独立的单词。

接下来的事情是将数据集拆分为训练和测试数据。但是我们还需要保持垃圾邮件和非垃圾邮件的分布。

最后,我们必须准备词汇,并计算每条信息中独立单词的数量。

将单词计数的结果表连接到我们的训练数据:

数据准备好了。

5.履行

我们将遵循上述公式并定义主要值:

  • 邮件是垃圾邮件的概率
Pspam = train_data[‘Label’].value_counts()[‘spam’] / train_data.shape[0]
  • 非垃圾邮件的概率
Pham = train_data[‘Label’].value_counts()[‘ham’] / train_data.shape[0]
  • 垃圾邮件中的字数
Nspam = train_data.loc[train_data[‘Label’] == ‘spam’, 
                       ‘SMS’].apply(len).sum()
  • 非垃圾邮件中的字数
Nham = train_data.loc[train_data[‘Label’] == ‘ham’,
                      ‘SMS’].apply(len).sum()
  • 词汇量的大小
Nvoc = len(train_data.columns - 3)
  • 设置 alpha = 1

6.结果呢

为了完成公式,我们将定义函数来确定给定单词属于垃圾邮件和非垃圾邮件的概率:

我们的分类功能:

函数应用后,我们在测试数据上看到了令人印象深刻的结果:99.1%的数据被成功分类。

出于兴趣,我们来看看未被正确识别的消息:

现在,您已经熟悉(或记忆犹新)了一种最有效的垃圾邮件分类算法。我希望它是有帮助的和描述性的。您可以在我的 GitHub 上找到带有工作示例的 Jupyter 笔记本:

[## 中级/中等 _jupyter_notes

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/Midvel/medium_jupyter_notes/blob/master/naive_bayes_filter/bayes-classificator.ipynb)

欢迎您分享其他呼吁与垃圾邮件斗争的算法。

如何用 FastAPI 构建和部署机器学习模型

原文:https://towardsdatascience.com/how-to-build-and-deploy-a-machine-learning-model-with-fastapi-64c505213857?source=collection_archive---------4-----------------------

保证在 10 分钟内部署您的第一个模型

建立机器学习模型只是其中的一部分。要在现实世界中发挥作用,用户和开发人员必须能够访问它。部署机器学习模型的最简单和最广泛使用的方法是将它们包装在 REST API 中。这正是我们今天要做的,用一个趋势库— FastAPI

Unsplash科普高清照片

那么,FastAPI 是什么?根据官方文档,它是一个用 Python 3.6+构建 API 的现代快速 web 框架。就性能而言,它与 NodeJSGo 在一起,这说明了一些问题。它也很容易学习,并带有自动交互文档,稍后会有更多介绍。

本文旨在涵盖足够多的库,以便从模型部署的角度帮助您入门。这不是一个明确的指南,因为这需要关于更高级主题的多篇文章,比如异步编程。阅读后,您将知道如何部署机器学习模型,并使用它从 Python、命令行或其他编程语言进行预测。

这篇文章的结构如下:

  • FastAPI 安装和构建第一个 API
  • 交互式文档探索
  • 训练机器学习模型
  • 构建完整的 REST API
  • 测试
  • 结论

FastAPI 安装和构建第一个 API

首先,你必须安装这个库和一个 ASGI 服务器——uvicon 和 Hypercorn 都可以。从终端执行这一行可以达到目的:

pip install fastapi uvicorn

现在,您可以为 API 创建一个文件夹,并在您喜欢的代码编辑器中打开它。要继续,创建一个名为app.py的 Python 脚本。您可以随意给自己的文件起不同的名字,但是在整篇文章中我将把这个文件称为app.py

下面是为了创建一个具有两个端点的简单 API 而必须做的事情的列表:

  1. 导入库——包括 FastAPIuvicon
  2. 创建 FastAPI 类的实例
  3. 声明第一个路由—在索引页面上返回一个简单的 JSON 对象(http://127.0.0.1:8000 —这是在步骤 5 中配置的)
  4. 声明第二条路线——返回一个包含个性化消息的简单 JSON 对象。name 参数直接来自 URL(例如http://127 . 0 . 0 . 1:8000/John
  5. uv icon运行 API

以下代码片段演示了如何实现这五个步骤:

就是这样!现在让我们运行我们的 API。为此,在app.py所在的位置打开一个终端窗口。现在键入以下内容:

uvicorn app:app --reload

并点击进入。在继续之前,让我们揭开这个说法的神秘面纱。第一个 app 指的是你的 Python 文件的名字,不带扩展名。第二个应用必须与您命名 FastAPI 实例的方式相同(参见上面列表中的步骤 2 或代码片段中的注释 2)。- reload 表示您希望 API 在您保存文件时自动刷新,而无需重新启动整个文件。

现在打开您选择的浏览器并转到http://127 . 0 . 0 . 1:8000—您应该会看到以下输出:

作者图片

第一个端点按照广告的方式工作。现在让我们检查另一个。转到以下 URL:http://127 . 0 . 0 . 1:8000/John—应该会出现以下消息:

作者图片

你可以输入任何一个名字来代替约翰,一切仍然可以工作。

现在你知道如何用 FastAPI 创建一个简单的 API 了——在进入机器学习之前,让我们看看还包括什么。暂时不要关闭终端窗口。

交互式文档探索

下面是使 FastAPI 成为 API 库之王的一个(或两个)特性——内置的交互式文档。我的意思是。打开下面的 URL:http://127 . 0 . 0 . 1:8000/docs—您会立即看到您的 API 的文档页面!它应该是这样的:

作者图片

您可以单击任何一个端点来进一步探索它,甚至执行实时的浏览器内测试。方法如下:

作者图片

这不是很神奇吗?您也可以使用这个文档页面来记录您的 API 端点。这是通过将文档字符串放在函数声明的正下方来实现的。以下代码片段演示了如何操作:

您的 API 文档现在看起来像这样:

作者图片

如果你不喜欢 Swagger UI (到目前为止你所看到的)的外观和感觉,还有另一个内置选项。要进行探索,请打开以下 URL:http://127 . 0 . 0 . 1:8000/redoc—将会出现此页面:

作者图片

现在您知道了如何构建和研究 API 文档。接下来让我们关注一个机器学习 API。

训练机器学习模型

这篇文章越来越长,所以我们不要在这部分浪费时间。我们将训练一个简单的模型,不需要任何数据准备和探索。这些不是今天主题的核心,也与模型部署无关。基于 Iris 数据集部署模型的过程与基于神经网络的过程相同。

我们就这么做——下载虹膜数据集并训练模型。嗯,没那么容易。首先,创建名为Model.py的文件。在其中,您将执行以下步骤:

  1. imports——您需要pandasscikit-learn中的RandomForecastClassifierpydantic中的BaseModel(您将在下一步中看到原因),以及【T6——用于保存和加载模型
  2. 声明一个继承自BaseModel的类IrisSpecies。该类仅包含用于预测单一花卉种类的字段(下一节将详细介绍)
  3. 声明一个类IrisModel-用于模型训练和进行预测
  4. IrisModel内部,声明一个名为_train_model的方法。它用于通过随机森林算法执行模型训练。该方法返回训练好的模型
  5. IrisModel内部,声明一个名为predict_species的方法。它用于根据 4 个输入参数(花朵测量)进行预测。该方法返回预测值(花卉种类)和预测概率
  6. IrisModel内部,修改构造函数,这样它会加载 Iris 数据集,如果文件夹中不存在该数据集,则会训练该模型。这解决了每次训练新模型的问题。joblib库用于保存和加载模型。

下面是完整的代码:

这需要编写相当多的代码,但是我希望上面的列表和注释能让它容易理解。现在让我们基于这个模型创建一个 REST API,并公开它的预测功能。

构建完整的 REST API

让我们回到app.py文件并删除所有内容。我们应该从一个空白文件重新开始,尽管样板文件将或多或少与您之前的文件相同。

这一次,您将只声明一个端点,用于预测花卉种类。这个端点通过调用前面部分声明的IrisModel.predict_species()方法来执行预测。另一个显著的变化是请求类型。POST 是机器学习 API 所需要的,因为用 JSON 而不是 URL 发送参数被认为是更好的做法。

如果你是一名数据科学家,上面这段话可能听起来像是胡言乱语,但没关系。构建和部署模型不需要精通 REST APIs 和 HTTP 请求。

app.py的待办事项列表很短:

  1. 导入——您将需要前面编写的Model.py文件中的uvicornFastAPIIrisModelIrisSpecies
  2. 制作FastAPIIrisModel的实例
  3. 声明一个用于进行预测的函数,位于http://127.0.0.1:8000/predict。该函数接受一个类型为IrisSpecies的对象,将其转换为一个字典,并将其传递给IrisModel.predict_species()方法。返回预测类别和预测概率
  4. 使用uvicorn运行 API

同样,这里是这个文件的完整代码和注释:

这就是你要做的。让我们在下一节测试 API。

测试

要运行 API,再次在终端中输入以下文本:

uvicorn app:app --reload

文档页面如下所示:

作者图片

同样,我们可以直接在浏览器中测试 API:

作者图片

这难道不会使测试变得容易吗?您可以从终端执行同样的操作:

作者图片

或者甚至通过任何编程语言(Python 示例):

今天到此为止。让我们在下一部分总结一下。

离别赠言

今天,您已经通过一个玩具 API 示例和一个玩具机器学习示例了解了什么是 FastAPI 以及如何使用它。此外,您还学习了如何为您的 API 编写和研究文档,以及如何测试它。对于一篇文章来说,这已经很多了,所以如果需要几篇阅读才能完全消化,不要沮丧。

FastAPI 还有更多的内容要介绍,比如它的异步功能,但这是另一天的主题。

你对 FastAPI 有什么看法?比起烧瓶你更喜欢它吗,为什么?在评论区告诉我。

加入我的私人邮件列表,获取更多有用的见解。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

[## 通过我的推荐链接加入 Medium-Dario rade ci

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

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

原载于 2020 年 10 月 28 日 https://betterdatascience.com

如何在一天内构建和部署一个机器学习 web 应用程序

原文:https://towardsdatascience.com/how-to-build-and-deploy-a-machine-learning-web-application-in-a-day-f194fdbd4a5f?source=collection_archive---------21-----------------------

构建 durian 分类器的一步一步的端到端指南(包括代码)

因此,我决定构建一个 web 应用程序来对榴莲进行分类,因为嘿,为什么不呢?点击查看

网络应用演示 (GIF 由作者创建)

对于我所有的国际读者来说,如果你不知道榴莲是什么,它是一种水果(在新加坡我们称它为水果之王),它有着奶油般的质地,刺鼻的气味(见下图)和尖尖的外表。这种说的刺鼻的气味,让人要么讨厌,要么绝对喜欢(我属于后一类,明显是)。如果你觉得它闻起来不错,那么它的味道可能会更好。

榴莲长什么样(照片由 Jim TeoUnsplash 上拍摄)

问题陈述

是的,这个项目的动力源于我对榴莲的热爱。你一定想知道,我们到底在分类什么?

你看,榴莲有很多种,它们的味道、质地和颜色都不一样。对于这个项目,我们将对四种不同类型的榴莲进行分类,即:

  • 猫山王
  • 金凤(金凤凰)
  • D24
  • 红对虾

这些榴莲的差异可以总结在下表中:

来源:https://www . you . co/SG/blog/types-of-durians-how-to-pick-the-best-durian/

那里有更多种类的榴莲(在这个链接中找到更多)但是我认为这些榴莲的细微差别可能已经证明我们的模型很难学习。

数据收集

每个项目都从数据收集开始。由于我们将部署的模型将用于个人和教育目的,我们将从 Google Images 获取图像。如果您将图像用于其他目的,请检查版权。

我们将使用这个 API 来获取我们的图像。只需按照回购上的说明安装软件包。在说明的步骤 3 中,我们将针对我们的特定用例运行该命令(替换到 chromedriver 的路径):

python3 bing_scraper.py --url 'https://www.bing.com/images/search?q=mao+shan+wang' --limit 100 --download --chromedriver <path_to_chromedriver>

在这里,我们将下载的图片数量限制为 100 张,因为没有多少特定的“茅山王”图片。我们重复上述步骤三次以上,用其他品种的榴莲代替搜索。请注意,由于我们正在 API 中修改搜索 URL,查询中的空格将被替换为“+”(即mao+shan+wangred+prawn+durian等)。

当然,您可以对任何想要分类的图像执行此步骤。

数据清理

在我们的使用案例中,由于公开可用的榴莲图像不多,许多下载的图像可能与正确的榴莲品种不对应(例如,在搜索“猫山王”时,您可能会找到一种普通的“未标记”榴莲)。因此,我需要手动检查所有下载的图像,以确保颜色和背景是正确的。毕竟,拥有高质量(即标签正确)的数据胜过数量,对吗?

这一步确实需要一些领域知识,可能会稍微费时。(但当然,数据清理是机器学习管道中的一个基本步骤,反映了数据科学家和人工智能工程师的现实。)

清理完数据后,我们剩下的是 55 D24、39 金凤、 59 毛山王和 68 红对虾的图像。

训练我们的榴莲分类器

我选择了使用 TensorFlow 框架,我相信大多数从业者都已经习惯了(当然,可以随意使用 Pytorch )。由于我们只有很少的图像,我们无疑必须使用预训练的模型,并在我们的数据集上对其进行微调。

首先,确保你有下面的文件夹结构,这是稍后flow_from_directory所需要的。

train
|-- d24
|-- golden-phoenix
|-- mao-shan-wang
|-- red-prawn
valid
|-- d24
|-- golden-phoenix
|-- mao-shan-wang
|-- red-prawn

让我们开始构建我们的分类器!

# Import relevant libraries we will be using
import numpy as npfrom tensorflow.keras.initializers import glorot_uniform
from tensorflow.keras.regularizers import l2
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import Xception
from tensorflow.keras.layers import (
    Flatten,
    Dense,
    AveragePooling2D,
    Dropout
)
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.preprocessing import image
from tensorflow.keras import Model
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.callbacks import (
    EarlyStopping,
    ModelCheckpoint,
    LearningRateScheduler
)

如上所述,我们将使用的基本模型是异常。让我们实例化这一点,并添加一些密集层。我们将使用较小的批量 8,因为我们有许多图像。我们还需要警惕过度适应我们的小数据集。

SHAPE = 224
BATCH_SIZE = 8model = Xception(
    input_shape=(SHAPE, SHAPE, 3),
    include_top=False,
    weights='imagenet'
)x = model.output
x = AveragePooling2D(pool_size=(2, 2))(x)
x = Dense(32, activation='relu')(x)
x = Dropout(0.1)(x)
x = Flatten()(x)
x = Dense(4, activation='softmax',
          kernel_regularizer=l2(.0005))(x)model = Model(inputs=model.inputs, outputs=x)opt = SGD(lr=0.0001, momentum=.9)
model.compile(loss='categorical_crossentropy',
              optimizer=opt,
              metrics=['accuracy'])

之后,让我们使用 TensorFlow 的ImageDataGeneratorflow_from_directory创建我们的图像生成器对象。由于我们没有足够的训练图像,图像增强比以往任何时候都更加重要。

train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=15,
    width_shift_range=0.1,
    height_shift_range=0.1,
    horizontal_flip=True
)valid_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=0,
    width_shift_range=0.0,
    height_shift_range=0.0,
    horizontal_flip=False
)train_generator = train_datagen.flow_from_directory(
    'train/',
    target_size=(SHAPE, SHAPE),
    shuffle=True,
    batch_size=BATCH_SIZE,
    class_mode='categorical',
)valid_generator = valid_datagen.flow_from_directory(
    'valid/',
    target_size=(SHAPE, SHAPE),
    shuffle=True,
    batch_size=BATCH_SIZE,
    class_mode='categorical',
)>>> Found 178 images belonging to 4 classes.
>>> Found 42 images belonging to 4 classes.

在我们的模型之前,让我们定义一些回调函数。

earlystop = EarlyStopping(monitor='val_loss',
                          patience=4,
                          verbose=1)checkpoint = ModelCheckpoint(
    "model-weights/xception_checkpoint.h5",
    monitor="val_loss",
    mode="min",
    save_best_only=True,
    verbose=1
)

最后,让我们开始训练我们的模型!

history = model.fit_generator(
    train_generator,
    epochs=30,
    callbacks=[earlystop, checkpoint],
    validation_data=valid_generator
)# Save our model for inference
model.save("model-weights/xception.h5")

不幸的是,由于我们拥有的图像数量有限,我们的模型在验证集上没有达到很好的准确性。然而,由于模型微调不是本文的主要焦点,我们不会过多地讨论这个问题。

选择我们的 Web 框架

对于这个项目,我选择了使用streamlit因为它可以实现机器学习应用程序的超级快速可视化,而且方便,它也是用 Python 编写的。在我们构建好之后,我们剩下要做的就是部署它。

首先,导入我们需要的库,并指定模型权重的路径。此外,由于我们使用了flow_from_directory,TensorFlow 按字母顺序分配类号。照此,D24 将是 0 类,以此类推。

import numpy as npfrom PIL import Image
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing import image
import streamlit as stPATH = "model-weights/"
WEIGHTS = "xception.h5"
CLASS_DICT = {
    0: 'D24',
    1: 'JIN FENG',
    2: 'MAO SHAN WANG',
    3: 'RED PRAWN'
}

接下来,我们创建一个函数,将上传的图像转换成模型可以使用的格式。我们特别使用来自PILImage类,因为上传的图像是BytesIO格式的。

def load_img(input_image, shape):
    img = Image.open(input_image).convert('RGB')
    img = img.resize((shape, shape))
    img = image.img_to_array(img)
    return np.reshape(img, [1, shape, shape, 3])/255

Streamlit 的工作方式是,给定用户指定的参数的每一个变化,脚本从上到下重新运行(因此其交互式 UI)。因此,它以st.cache的形式提供了一个cache装饰器来缓存加载的对象。缓存通常用于数据加载步骤或任何需要长时间计算/处理的步骤。请记住,我们使用allow_output_mutation=True参数,因为默认情况下这是False,如果输出对象以任何方式发生变化,应用程序将被重新加载。

在我们的例子中,模型对象在每次预测时都会发生变异。因此,我们将这个allow_output_mutation参数设置为True。我们想要缓存我们的模型的原因是因为我们不想在每次用户选择不同的图像时加载它(即模型加载只进行一次)。

[@st](http://twitter.com/st).cache(allow_output_mutation=True)
def load_own_model(weights):
    return load_model(weights)

最后,我们只需要一些代码添加到 UI 中:

if __name__ == "__main__":
    result = st.empty()
    uploaded_img = st.file_uploader(label='upload your image:')
    if uploaded_img:
        st.image(uploaded_img, caption="your sexy durian pic",
                 width=350)
        result.info("please wait for your results")
        model = load_own_model(PATH + WEIGHTS)
        pred_img = load_img(uploaded_img, 224)
        pred = CLASS_DICT[np.argmax(model.predict(pred_img))] result.success("The breed of durian is " + pred)

这就对了。我们的 web 应用程序是用 Python 创建的,代码不多。您可以通过在命令行中输入以下命令来确保它(假设它将被称为app.py)能够在本地运行:

streamlit run app.py

将我们的模型部署到 Heroku

就我个人而言,部署不是我最喜欢的部分,但是,嘿,如果它不在网络上,那它是什么呢?所以让我们开始吧。

有许多方法可以为 web 应用程序提供服务,也有许多云服务提供商来托管它。在这种情况下,我选择与 Heroku 合作主要是因为我以前没有尝试过。

什么是 Heroku?Heroku是一个云平台即服务(PaaS),支持多种编程语言,允许开发人员完全在云端构建、运行和操作应用。这篇文章解释的很清楚。

为了部署一个应用程序,我们总是需要某种版本控制来确保我们的应用程序运行在本地机器之外的另一个服务器上。为此,许多人使用 Docker 容器,指定所需的可运行的应用程序和包。

使用 Heroku 进行部署类似于同时使用 Docker 容器和 web 托管服务。但是,它使用 Git 作为部署应用程序的主要手段。我们不需要将所有需要的文件打包到 Docker 容器中,而是必须创建一个 git 存储库来进行版本控制,然后我们可以使用熟悉的git push,但是要使用heroku遥控器。

Heroku 然后使用相同的容器技术,但是以一个 dyno 的形式。每个应用程序都放在一个 dyno(或容器)中,每个应用程序消耗“dyno-hours”(更多信息请点击)。每个 Heroku 帐户都有一些可用的免费小时数,消耗的小时数取决于应用程序的活动/流量。首先,如果你没有预见到应用程序的大流量,你应该对免费层非常满意。

同样值得注意的是,当 Heroku 收到应用程序源代码时,它会启动应用程序的构建(如在requirements.txt中检索依赖项,创建必要的资产等),然后组装成 slug。

术语:slug 是您的源代码、获取的依赖项、语言运行时和编译/生成的构建系统输出的捆绑包——准备执行。

要在 Heroku 上部署,我们需要以下文件:

(1) setup.sh —创建必要的目录并将一些信息(如端口号)写入一个.toml文件

mkdir -p ~/.streamlit/echo "\
[server]\n\
headless = true\n\
port = $PORT\n\
enableCORS = false\n\
\n\
" > ~/.streamlit/config.toml

(2) Procfile —类似于 Dockerfile,包含我们想要执行的指令。我们将首先在setup.sh中执行一些 bash 命令,然后执行streamlit run app.py命令。

web: sh setup.sh && streamlit run app.py

(3) requirements.txt —包含我们的应用程序所需的所有包依赖关系。请注意,这些是我正在使用的版本。您可以通过终端中的conda list或者使用pip freeze > requirements.txt来获得您的环境当前使用的软件包的详细列表,从而找到您正在使用的软件包版本。

numpy==1.18.1
spacy==2.2.4
pandas==1.0.1
Pillow==7.1.2
streamlit==0.61.0
tensorflow-cpu==2.2.0

我们的文件夹目录应该如下所示:

app.py
Procfile
README.md
requirements.txt
setup.sh
model-weights
|-- xception.h5

如果您以前没有创建过 Github 存储库,以下是一些简单的步骤:

  1. 创建新的存储库<repo_name></repo_name>

2.复制红色框中的 URL

3.从终端运行以下命令:

# Clone the repository into our local machine
git clone <repo URL in step 2># Enter the directory we just cloned
cd <repo_name>

4.将之前创建的文件复制到该文件夹中,并在终端中运行以下命令:

# Add all the files we just copied over to be committed
git add .# Commit the files, along with a commit message
git commit -m "deploy app"# Push to master branch on our github repo
git push origin master

我们快到了!这是最后的步骤。

(1)创建一个 Heroku 账户并验证

(2)在这里安装 Heroku CLI

(3)通过终端登录您的 Heroku 账户。将会打开一个浏览器窗口进行身份验证。

heroku login

(4)创建一个 Heroku app

heroku create <project-name>

完成此步骤后,您将能够在终端中看到指向您的项目的链接。

(5)将我们的 git 回购推送到 Heroku remote。从 github repo 的同一个目录中,运行以下命令:

git push heroku master

我们完了!构建完成后,您应该能够在上面的链接中看到您的应用程序已部署!

结束语

希望这对每个试图从头到尾创建自己的迷你 ML 项目的人有用!请随时留下任何意见:)

支持我! —如果你喜欢我的内容并且没有订阅 Medium,请考虑支持我并通过我在这里的推荐链接订阅 ( 注意:你的一部分会员费将作为推荐费分摊给我)。

如何在本地机器上构建和部署 AWS 应用程序

原文:https://towardsdatascience.com/how-to-build-and-deploy-aws-applications-on-local-machine-562b112ecfb7?source=collection_archive---------23-----------------------

动手教程,云计算系列

在本地机器上构建和部署基于 AWS 的云应用程序

图片作者。由 Pixabay 通过 Canva 生成的原始图像

在我以前的文章中,我谈到了使用 ChaliceSAM 在 AWS 上构建和部署无服务器应用程序。这些是快速有趣的项目,利用了无服务器计算的能力,让我们在几分钟内就可以在 AWS 上部署无服务器应用程序。

但是由于没有 AWS 帐户,许多人不能完全利用这样的教程。设置 AWS 帐户和配置开发环境可能非常耗时,有时还会导致不必要的费用(如果配置不当)。

在本文中,我将带您完成构建和部署无服务器应用程序所需的步骤,而无需创建和设置实际的 AWS 帐户。

这一次,我们将使用 Amazon API Gateway、AWS Lambda 和 Amazon DynamoDB 创建一个样本宠物商店应用程序。这个应用程序将有 API 来添加一个新的宠物和获取可用宠物的列表。

先决条件

在本教程中,我们将使用 AWS SAM。您可以按照之前的文章中的指导来安装和配置 SAM。

如何创建项目

运行sam-init命令创建一个新项目。这将在当前目录下创建一个pet-store文件夹。

sam init -r java11 -d maven --app-template pet-store -n pet-store

关于传递的参数的更多细节,请参考之前的文章

让我们更改pom.xml,将模块名称更新为PetStore,并使用Java 11而不是Java 8

现在让我们创建一个Pet类来包含宠物的属性。我们将从简单的属性开始,如nameagecategory

因为我们将使用 Amazon DynamoDB 作为我们的数据存储,所以让我们在pom.xml中添加相应的 SDK 依赖项。

这将引入 AWS SDK for DynamoDB 和 Apache HTTP Client 的依赖项,这些依赖项将用于创建同步 DynamoDB 客户端。

如何读写项目

我们需要创建一个数据访问类来与 Amazon DynamoDB 交互,并运行我们的读/写查询。创建一个PetStoreClient类并添加对DynamoDbClient的依赖。

我们现在将在PetStoreClient类中创建两个函数来从 DynamoDB 中读取和写入项目。

写一个项目

在 DynamoDB 中添加一个条目是一个PUT请求。我们将创建一个PutItemRequest,并指定要添加的表名和项目属性。

然后我们将使用DynamoDbClient把这个项目放到 DynamoDB 中。

阅读项目

读取 DynamoDB 中的项目列表是一个SCAN请求。我们将创建一个ScanRequest并指定要扫描的表名。

然后我们将使用DynamoDbClient来扫描 DynamoDB 中的表,并返回一个条目列表。

注意:扫描请求会遍历表中的所有项目,因此不建议在真实情况下使用。

如何解决依赖关系

我们已经在我们的PetStoreClient类中添加了DynamoDbClient作为依赖项。作为一般的最佳实践,代码中的所有此类依赖都应该使用依赖注入(DI)来解决。

说起 DI,春天是我们脑海里第一个蹦出来的名字。然而,Spring 生态系统是巨大的,我们最终会引入很多它的框架,即使我们只想使用 DI 部分。喷射也在运行时完成,使得 Lambda 的冷启动时间更长。

Guice 是另一个很好的依赖注入框架,比 Spring 轻得多。但是就像 Spring 一样,它在运行时进行注入,因此也不适合 DI。

然后是 Dagger,一个纯 DI 框架,在编译时注入依赖项!!它的小尺寸和编译时注入使它成为在 Lambdas 中实现 DI 的完美选择。

我将更深入地研究 DI 的细节,并在另一篇文章中介绍 Dagger 的使用。然而在本文中,我们将使用静态工厂方法的永恒风格来提供依赖关系。

让我们创建一个类DependencyModule,并在其中声明我们所有的依赖项。

在这个类中,我们正在创建一个新的DynamoDbClient实例,并将其注入到我们的PetStoreClient中。我们还创建了一个ObjectMapper的实例来帮助我们处理 JSON 对象的序列化和反序列化。

如何更新 Lambda 和 API 端点

接下来,我们需要更新 Lambda 函数的入口点,并为添加和检索宠物添加特定的端点。

将下面的代码片段添加到template.yaml文件的Resources部分。

这更新了我们的函数来使用来自App类的handleRequest方法,并且还添加了两个 API 端点来添加和检索宠物。

更新Outputs部分以反映新的函数名。

如何整合客户端

既然我们已经准备好了与 DynamoDB 交互的代码,并且对依赖项进行了排序,那么我们需要在 Lambda 处理程序中进行一些更改来调用这些代码。

更新App.java中的代码,以调用PetStoreClient中的函数,并根据 API 请求执行动作。

由于我们使用静态工厂进行依赖注入,我们将不能有效地测试我们的代码。我将在另一篇文章中介绍云应用程序的单元测试。现在,我们需要删除单元测试来构建项目。

如何构建项目

pet-store文件夹中,运行sam build命令。

作者图片

这将编译您的源代码并构建您在应用程序中拥有的任何依赖项。然后,它将所有文件移动到.aws-sam/build文件夹中,这样它们就可以打包和部署了。

如何进行本地测试(第 1 部分)

在之前的文章中,我们讨论了 SAM CLI 如何提供sam local命令来本地运行您的应用程序。这在内部使用 Docker 来模拟 Lambda 的执行环境。如果没有安装 Docker,可以从这里获取。

这对 Daily News API 来说很好,因为它从互联网上获取数据,并且不依赖于任何其他 AWS 组件。然而,在当前的项目中,我们依赖 Amazon DynamoDB 作为我们的数据存储,并且需要访问它以便我们能够成功地运行我们的应用程序。

本质上,我们需要一种方法在本地机器上模拟 AWS 提供的服务,这样我们就可以在本地测试它们,而不需要使用实际的 AWS 帐户。

如何在本地运行 AWS

LocalStack 就是为了解决这个问题而产生的。用它自己的话说:

LocalStack 为开发云应用程序提供了一个易于使用的测试/模拟框架。它在您的本地机器上构建了一个测试环境,提供与真正的 AWS 云环境相同的功能和 API。

简而言之,LocalStack 将 AWS cloud 的所有功能都集成到一个 docker 容器中,该容器在我们的机器上本地运行。这使开发人员能够构建和测试他们的云应用程序,而不必在实际的 AWS 云帐户上部署它们。

对一个开发者来说意味着什么?

  1. 无需提供 AWS 帐户。
  2. 不需要设置开发环境和考虑安全性和其他配置。
  3. 不需要在开发期间产生不必要的 AWS 成本。
  4. 完全模拟实际 AWS 环境的透明本地环境。

如何设置本地堆栈

LocalStack 非常容易设置和开始使用。我们将使用 Docker 获取 LocalStack 的最新映像,并启动一个运行 Amazon DynamoDB 模拟版本的容器。

pet-store文件夹中创建一个docker-compose.yaml文件,并添加以下内容。

让我们来看看我们正在使用的一些配置:

  • 服务——因为我们只依赖 Amazon DynamoDB,所以我们将只启用这个特定的服务
  • DEFAULT_REGION —我们将使用 us-west-1 作为我们的 AWS 区域
  • LAMBDA _ EXECUTOR——将它设置为 local 意味着我们所有的 LAMBDA 函数都将在本地机器上的一个临时目录中运行
  • DATA_DIR —为 Amazon DynamoDB 等服务保存持久数据的位置

注意:所有的 LocalStack 服务都是通过端口 4566 上的 edge 服务公开的。这是我们需要使用的唯一端口。

现在,我们可以使用docker-compose在它自己的容器中启动我们本地版本的 Amazon DynamoDB。

作者图片

如何创建表格

既然我们已经运行了 Amazon DynamoDB 的本地设置,我们应该能够为我们的应用程序创建一个表。

我们在代码中使用了pet-store作为表名,所以让我们继续创建它。我们将使用 AWS CLI 访问运行在本地机器上的 Amazon DynamoDB,并创建所需的表。

运行下面的命令创建一个名为pet-store的表,并将属性id作为主键。

aws --endpoint-url "[http://localhost:4566](http://localhost:4566)" dynamodb create-table \
    --table-name pet-store \
    --attribute-definitions AttributeName=id,AttributeType=S \
    --key-schema AttributeName=id,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST

注意,我们使用了endpoint-url参数来指定我们指向本地运行的 AWS 实例,而不是实际的实例。

如何进行本地测试(第 2 部分)

对 DynamoDbClient 代码进行以下更改,使其指向本地运行的 Amazon DynamoDB 实例。

接下来,使用sam build构建项目,并运行以下命令在本地启动 API。

sam local start-api

这在内部创建了一个本地服务器,并公开了一个复制 REST API 的本地端点。

作者图片

现在,让我们通过添加一只新宠物来测试我们的应用程序。运行下面的命令,通过调用我们之前指定的/pets端点来添加一个新的宠物。

curl --location --request PUT '[http://127.0.0.1:3000/pets'](http://127.0.0.1:3000/pet') \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "Rocket",
    "age": 2,
    "category": "Dog"
}'

这创建了一个新的宠物记录,将其添加到我们的本地 Amazon DynamoDB,并在响应中返回生成的 UUID。

我们店里再添一只宠物吧。

curl --location --request PUT '[http://127.0.0.1:3000/pets'](http://127.0.0.1:3000/pet') \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "Candle",
    "age": 1,
    "category": "Pig"
}'

现在,让我们调用我们的/pets API 来获取数据存储中可用的宠物列表。我们应该会得到一个包含RocketCandle的宠物列表。

作者图片

结论

恭喜你!!您刚刚在本地机器上构建并部署了一个完全使用 AWS DynamoDB 的无服务器应用程序。

现在您可以继续对您的App.java文件进行任何修改。重新运行sam deploy来重新部署您的更改,运行sam local start-api来启动本地服务器并测试更改。

一旦您为部署做好准备,您只需要删除端点覆盖,就万事大吉了。在理想情况下,这将由环境变量控制,并且绝对不需要修改代码就可以投入生产。

本教程的完整源代码可以在这里找到。

如何使用 Python、Google Sheets 和 Vue.js 构建和部署您的仪表板

原文:https://towardsdatascience.com/how-to-build-and-deploy-your-dashboard-with-python-google-sheet-and-vue-js-c34140c1afc8?source=collection_archive---------5-----------------------

实践教程

部署仪表板的实用指南,无需服务器。

Stephen Dawson 在 Unsplash 上拍摄的照片

数据的可视化让我们能够快速洞察。但是,部署数据可视化解决方案可能会很困难,因为大多数时间都需要购买许可证或服务器。

在本文中,我们将看到如何使用免费工具构建一个仪表板来呈现一些虚假销售,您可以下载数据这里以便遵循教程。

首先,我们将使用 Python 来填充一个 Google sheet。然后,我们将使用 Vue.js 创建一个使用 apache EchartVuetify 的仪表板。最后,我们将使用 Github action 在 GitHub 页面上部署这个仪表板。

要求

要遵循本指南,您需要具备以下条件:

  • 一个谷歌账户
  • gcloud 命令行工具
  • Python 3.7 或更高版本
  • Github 账户

设置 Google cloud 帐户

我将使用 google cloud 命令行工具来设置 google cloud 帐户。如果你不熟悉 google cloud SDK,你可以在这里找到适合你平台的快速入门。

让我们来配置我们的谷歌云项目:

  1. 使用gcloud create project <project_id>创建新项目

  2. 将新创建的项目设置为其他命令的默认项目:gcloud config set project <project_id>

  3. 启用 google sheet API 和 Drive API:
    gcloud services enable sheets.googleapis.com

  4. 为 python 脚本创建一个服务帐户:gcloud iam service-accounts <name_of_service_account>

  5. 从服务帐户:
    gcloud iam service-accounts keys create <local_path_to_download.json> --iam-account <name_of_service_account>@<project_id>.iam.gserviceaccount.com创建并下载凭证

  6. 为 Vue.js 应用程序创建 API 密钥:

  • 导航到云控制台中的API&服务→凭证面板
  • 选择创建凭证,然后从下拉菜单中选择 API key
  • API 密钥创建对话框显示您新创建的密钥,保存它以备后用。
  • 然后点击“编辑”,在“限制 API”部分选中“限制关键字”选项,选择“Google 工作表 API ”,然后点击“保存”。

接下来,我们将创建一个脚本,使用 Python 将仪表板数据推送到 Google sheets。

将数据框架推送到 Google sheets

Python 脚本将需要一些依赖关系,以便将数据推送到 Google。用:pip install pandas pygsheets安装它们,然后创建一个目录和一个 Python 文件,并复制下面的脚本。

将数据框上传到新的谷歌工作表来源:作者

在这个脚本中,我们首先用前面创建的凭证文件初始化 Google sheets 客户机。然后,我们创建一个全新的谷歌表,我们与我们的谷歌帐户共享它,这样我们就可以在谷歌驱动可视化它。我们还公开了我们的工作表,以便 Vue 应用程序可以访问它。接下来,我们创建 3 个工作表,并为每个工作表上传一个熊猫数据框。最后,我们打印工作表 id,保存它,因为我们将在下一部分中需要它来构建 Vue.app。

构建仪表板

为了简单起见,我们将使用 Vue.js 构建仪表板,不使用任何构建工具。首先,在根目录下创建一个dist文件夹,在里面创建一个index.html文件,内容如下。

仪表板代码来源:作者

我们来破个码,Vue app 是从 161 行到 245 行定义的。首先,有一个数据部分,其中我们声明了包含来自 Google sheet 的数据的对象,以及一个包含与 Google sheet 数据匹配的指标的数组。

接下来,我们有一个允许我们通过 Google sheets API 恢复数据的函数。这个方法使用从第 80 行到第 160 行定义的类。这个类是在 mounted 部分初始化的,它在参数中接受工作表的 id 和您的 API 键,,所以请确保用您自己的替换这些值。

然后在计算部分,我们声明我们的图表变量。如你所见,它们都遵循相同的模式。我们首先引用数据所在的工作表,然后为每个图表声明列、行和不同的设置。

最后,我们使用 HTML 格式的数据可视化库电子图表,从第 26 行到第 45 行,根据我们声明的变量来呈现我们的图表。现在,如果你打开你的index.html文件,你应该会看到这样一个仪表板:

index.html 仪表板来源:作者

在 GitHub 页面上部署

我们现在将使用 Github 操作在 GitHub 页面上部署我们的仪表板。为此,您必须在您的 GitHub 帐户上创建一个新目录。然后,您将需要创建一个 GitHub 个人访问令牌以便能够使用 GitHub 操作,点击 此处 查看如何生成一个。

您需要选择您想要授予这个令牌的作用域,确保选择repo复选框以便能够在 GitHub 页面上部署。

现在,您需要在 GitHub 存储库中创建一个秘密,以便部署操作可以使用您创建的令牌。查看官方文档此处了解如何继续。命名秘密访问令牌。

一旦你配置好了,你就可以在你的项目的根文件夹中创建一个目录树.github/worflows,它将包含下面的main.yml文件。

GitHub 工作流来源:作者

现在您已经定义了您的工作流,在您的 GitHub 远程 repo 上推送您的项目。如果一切正常,你可以在以下网址看到仪表盘:
https:/<your-github-username>. github . io/<repo-name>/。

最后,转到您在谷歌云控制台上的凭证点击编辑您的 API 密钥,并在应用程序限制部分:

  • 选中选项:HTTP 推荐人(网站)
  • 点击添加一个项目
  • 在输入表单中输入你的 Github 页面的 URL:
    https:/<your-Github-username>. Github . io/<repo-name>/。

缺点和限制

API 密钥在这里被用作调用 Google APIs 的认证方法。这个方法只允许你读取公开的工作表,所以不要使用本教程来部署敏感数据。

对于这种用法,您必须通过本指南 中的 **所示的 oauth2 认证协议。**

结论

在本文中,我们看到了如何部署一个由 Google sheet 支持的简单仪表板。该仪表板读取引用工作表中的数据。如果您想更新数据,您只需更新 Google sheet 工作簿,单击刷新按钮,它就会反映在仪表板上。最后,由于 GitHub action,仪表板的部署是自动化的。

如果您有兴趣通过电子邮件发送您的仪表板或报告,请查看这篇文章。

[## 使用 Python、Vue.js 和 Gmail 自动化您的报告流程

一个具体的一步一步的例子,自动化您的报告,而不需要服务器。

medium.com](https://medium.com/swlh/automate-your-reporting-with-python-and-vue-js-15ef130fff8)

如何用 Python 构建和发布命令行应用程序

原文:https://towardsdatascience.com/how-to-build-and-publish-command-line-applications-with-python-96065049abc1?source=collection_archive---------9-----------------------

戴维·克洛德在 Unsplash 上的照片

关于如何用 Python 构建和发布命令行应用程序的全面指南。

命令行应用程序基本上是您在终端上运行的程序,并且您很可能已经尝试或考虑过构建一个。

构建命令行应用程序是一回事,将它发布到像 PyPI 这样的开放公共代码库是另一回事,不应该被视为一项困难的任务或过程。

我以前写过一篇文章,其中我深入解释了用 Python 构建命令行应用程序的各种方式和方法。

在本文中,我将解释如何用 Python 构建一个简单的 CLI 并将其发布到 PyPI。

入门指南

最近我一直在做一些关于开源漏洞的研究,我想有一个命令行工具,我可以用它来搜索和查找终端上的漏洞。开源漏洞通常发布在公共数据库中,可以在类似 CVENVD白源漏洞等网站上找到。

在本文中,我们将构建一个简单的刮刀来搜索和查找 CVE 网站上的漏洞,将其包装成一个简单的命令行应用程序,并将其发布到 PyPI。

酷吧?

要开始,您需要设置您的开发环境并安装所需的模块。我建议建立一个虚拟环境,因为它使事情变得更容易,并有助于避免模块版本的冲突。

要创建一个虚拟环境,你可以使用 python3 命令python -m venv <path/name>或者使用pip install virtualenvwrapper安装virtualenvwrapper并使用mkvirtualenv -p /path/topython <path/name>创建一个虚拟环境

设置并激活 virtualenv 后,您可以创建项目文件夹并安装所需的模块:

mkvirtualenv -p /usr/bin/python cvecli-env
mkdir cvecli && cd cvecli
mkdir cver && touch setup.py && touch README.md && touch cver/__init__.py && touch .gitignore
pip install requests beautifulsoup4 lxml twine click
pip freeze > requirements.txt

一旦一切运行成功,您可以在任何代码编辑器中打开该项目,您应该会看到如下所示的结构:

编写我们的网页抓取器

为了能够在 CVE 网站上搜索和查找漏洞,我们需要一个网页抓取器来帮助抓取漏洞细节。我们将根据要求制造铲运机和 Beautifulsoup,铲运机能够:

  1. 搜索漏洞
  2. 使用漏洞的 CVE 名称获取漏洞详细信息

现在在cver文件夹中,创建一个名为cve_scraper的文件,基本设置如下:

import requests
from bs4 import BeautifulSoupSEARCH_URL = "[https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=python)"CVE_URL = "[https://cve.mitre.org/cgi-bin/cvename.cgi?name=](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-8492)"def get_html(url):
    request = requests.get(url)
    if request.status_code == 200:
        return request.content
    else:
        raise Exception("Bad request")def search(s):
    passdef lookup_cve(name):
    pass

搜索漏洞

在 CVE 网站上搜索漏洞,URL 格式如下:[https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=python)=<keyword>。这样,您应该能够用关键字,

例如,我们可以使用 URL 来获取所有与 python 相关的漏洞:

为了提取数据,让我们打开开发人员控制台,检查呈现上述数据的 DOM 元素。您可以右键单击页面的任何部分,然后单击inspect element或按 Ctrl + F12。

如果您看一下上图中的 DOM 结构,您会注意到结果显示在一个表格中,每个结果都是表格下的一行。数据可以很容易地提取如下:

def search(s): url = f"{SEARCH_URL}{s}"
    results=[]    
    html = get_html(url)
    soup = BeautifulSoup(html, "lxml")
    result_rows = soup.select("#TableWithRules table tr") for row in result_rows: 
        _row = {}    
        name = row.select_one("td a")
        description = row.select_one("td:nth-child(2)") if all([name, description]): _row["name"] = name.text
            _row["url"] = name.get("href")
            _row["description"] = description.text results.append(_row)

    return results

在上面的代码中,我们:

  1. 使用请求向 SEARCH_URL 发送请求并获取 DOM 内容
  2. 将 dom 内容转换成漂亮的组对象,我们可以使用 CSS 选择器和其他类似 XPATH 的方法来选择 DOM 元素。
  3. 选择#TableWithRules表格下的所有tr,选择该行的第一列作为名称,第二列作为描述,然后提取文本。

查找漏洞详细信息

要查找漏洞详细信息,您需要提供漏洞的 CVE ID,并将其传递到以下 URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-ID

打开您的开发人员控制台,让我们检查一下 DOM 结构。

查看上面的结构有点复杂,因为表行没有用类名或 id 标识。我们需要遍历每一行,检查它是否是一个副标题,如果是,那么我们把下一个元素作为子内容。每个字幕在th中呈现,而内容在td中呈现

def lookup_cve(name):
    url = f"{CVE_URL}{name}"
    html = get_html(url)
    soup = BeautifulSoup(html, "lxml")
    result_rows = soup.select("#GeneratedTable table tr")subtitle = ""
    description = ""raw_results = {}for row in result_rows:
        head = row.select_one("th")
        if head:
           subtitle = head.text
        else:
            body = row.select_one("td")
            description = body.text.strip().strip("\n")
            raw_results[subtitle.lower()] = description   

    return raw_results

Tada!我们已经成功地创建了我们的 CVE 网络刮刀。你现在可以用两个函数(search 和 lookup_sve)来搜索漏洞,并使用漏洞的 CVE ID 来获取漏洞的详细信息。

构建我们的命令行应用程序

下一步是使用 Click 库构建我们的命令行应用程序。

Click 是一个 Python 包,用于以可组合的方式用尽可能少的代码创建漂亮的命令行界面。这是创建 CLI 的最佳 python 包之一,并且易于入门

使用 Click,您可以构建任何类型的简单或企业级 CLI,如 Heroku CLI。

在我们的 CLI 中,我们将实现两个命令:

  1. 搜索漏洞
  2. 查找漏洞

cver文件夹中创建一个名为__main__.py的文件,并输入以下基本代码:

import sys
import click[@click](http://twitter.com/click).group()
[@click](http://twitter.com/click).version_option("1.0.0")
def main():
    """A CVE Search and Lookup CLI"""
    print("Hye")
    pass[@main](http://twitter.com/main).command()
[@click](http://twitter.com/click).argument('keyword', required=False)
def search(**kwargs):
    """Search through CVE Database for vulnerabilities"""
    click.echo(kwargs)
    pass[@main](http://twitter.com/main).command()
[@click](http://twitter.com/click).argument('name', required=False)
def look_up(**kwargs):
    """Get vulnerability details using its CVE-ID on CVE Database"""
    click.echo(kwargs)
    passif __name__ == '__main__':
    args = sys.argv
    if "--help" in args or len(args) == 1:
        print("CVE")
    main()

搜索漏洞

为了实现这一点,我们将从 web scraper 导入搜索功能,并从命令行向其传递关键字参数,以搜索与该关键字匹配的漏洞:

from scraper import search as cve_search, lookup_cve[@main](http://twitter.com/main).command()
[@click](http://twitter.com/click).argument('keyword', required=False)
def search(**kwargs):
    """Search through CVE Database for vulnerabilities"""
    results = cve_search(kwargs.get("keyword"))
    for res in results:
        click.echo(f'{res["name"]} - {res["url"]} \n{res["description"]}')

要运行此命令:

python cver/__main__.py search python

查找漏洞

同样的事情在这里,我们将使用来自 web scraper 的lookup_cve,并从look_up命令传递给它 name 参数。

[@main](http://twitter.com/main).command()
[@click](http://twitter.com/click).argument('name', required=False)
def look_up(**kwargs):
    """Get vulnerability details using its CVE-ID on CVE Database"""
    details = lookup_cve(kwargs.get("name"))
    click.echo(f'CVE-ID \n\n{details["cve-id"]}\n')
    click.echo(f'Description \n\n{details["description"]}\n')
    click.echo(f'References \n\n{details["references"]}\n')
    click.echo(f'Assigning CNA \n\n{details["assigning cna"]}\n')
    click.echo(f'Date Entry \n\n{details["date entry created"]}')

要运行此命令:

python cver/__main__.py look-up CVE-2013-4238

Tada!我们已经成功构建了 CVE 查找命令行工具。

向 PyPI 发布我们的命令行应用程序

现在我们已经成功地构建了命令行应用程序,一切都运行良好,我们可以将它发布到 PyPI 供公众使用和安装。

PyPI 是 python 包的软件仓库,它保存了我们使用pip命令工具安装的大多数 Python 包。要在 PyPI 上发布一个包,你需要创建一个账户,这样你就可以去网站创建一个新账户,如果你已经有了一个,那么你就可以开始了。

配置我们的包

一旦你完成了这些,下一件事就是使用setup.py配置我们的 Python 包。为了将您的包上传到 PyPI,您需要提供一些关于包的基本信息。该信息通常在 setup.py 文件中提供。

因此,打开项目基本目录中的setup.py,并将它放在文件的开头:

from setuptools import setup, find_packages
from io import open
from os import pathimport pathlib
# The directory containing this file
HERE = pathlib.Path(__file__).parent# The text of the README file
README = (HERE / "README.md").read_text()# automatically captured required modules for install_requires in requirements.txt and as well as configure dependency links
with open(path.join(HERE, 'requirements.txt'), encoding='utf-8') as f:
    all_reqs = f.read().split('\n')install_requires = [x.strip() for x in all_reqs if ('git+' not in x) and (
    not x.startswith('#')) and (not x.startswith('-'))]
dependency_links = [x.strip().replace('git+', '') for x in all_reqs \
                    if 'git+' not in x]

在上面的例子中,我们将README.md文件的内容转换成字符串供以后使用。我们还从requirements.txt中捕获了所有需要的模块,并生成了它们的依赖链接。

您的 requirements.txt 文件应该如下所示:

click
requests
beautifulsoup4
lxml
twine

现在让我们看看我们的设置配置:

setup (
 name = 'cver',
 description = 'A simple commandline app for searching and looking up opensource vulnerabilities',
 version = '1.0.0',
 packages = find_packages(), # list of all packages
 install_requires = install_requires,
 python_requires='>=2.7', # any python greater than 2.7
 entry_points='''
        [console_scripts]
        cver=cver.__main__:main
    ''',
 author="Oyetoke Toby",
 keyword="cve, vuln, vulnerabilities, security, nvd",
 long_description=README,
 long_description_content_type="text/markdown",
 license='MIT',
 url='[https://github.com/CITGuru/cver'](https://github.com/CITGuru/cver/'),
 download_url='[https://github.com/CITGuru/cver/archive/1.0.0.tar.gz'](https://github.com/CITGuru/cver/archive/1.0.0.tar.gz'),
  dependency_links=dependency_links,
  [author_email='oyetoketoby80@gmail.com](mailto:author_email='oyetoketoby80@gmail.com)',
  classifiers=[
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 2.7",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.7",
    ]
)

在上面的代码中,我们添加了一些选项,这里我们将只介绍设置中可用的一些选项。设置工具文档很好地研究了所有细节。

  1. name:将出现在 PyPI 上的包的名称
  2. 版本:您的软件包的当前版本
  3. 包:包含源代码的包和子包。我们正在使用设置中的find_packages模块来帮助我们自动找到我们的子包。
  4. install_requires:这是用来列出你的包拥有的任何依赖项或第三方库。在cver中,我们使用了 requests、beautifulsoup4 和 click。它们必须包含在 install_requires 安装程序中。我们不需要手动放置它,因为我们已经阅读了requirements.txt来获取它们。
  5. entry_points:这用于创建调用包内函数的脚本。在我们的设置中,我们创建了一个新的脚本cver,它在 cver/main 中调用 main()。py 文件。我们的主入口是__main__.py,它调用main()函数来启动 click。

在向 PyPI 或公众发布您的包之前,您应该添加一些文档。如何记录包取决于您的项目。这可能是一个简单的README.md文件或Readme.rst文件,完全取决于你。

这里有一个典型的好听的README.md:

# CVERA simple commandline app for searching and looking up opensource vulnerabilities# Installation## Using Pip```bash
  $ pip install cver
```## Manual```bash
  $ git clone [https://github.com/citguru/cevr](https://github.com/citguru/cevr)
  $ cd cver
  $ python setup.py install
```# Usage```bash
$ cver
```## Search`search <keyword>````bash
$ cver search python

Lookup`search ````bash

$ cver look-up CVE-2020-2121

另外,创建一个.gitignore文件:

就是这样。

发布到 PyPI

一旦一切都成功完成,这个包就可以公开发布了,并发布在 PyPI 上。确保你已经创建了一个我前面提到的帐户,你还需要在 PyPI 测试服务器上创建一个测试帐户,以便在发布到实时服务器之前测试包。

我们将使用一个叫做 Twine 的工具来上传你的 python 包到 PyPI。它应该在前面的步骤中安装,但是如果你没有安装,你可以只做pip install twine

在本地和测试服务器上构建和测试包

PyPI 上发布的 Python 包不是以普通源代码的形式发布的,而是被打包成发布包。Python wheels 和源代码档案是分发 Python 包时最常见的格式。

Python wheels 本质上是一个包含您的代码的 zip 存档,并且包括任何可以使用的扩展。Source Archives 由您的源代码和任何支持文件组成,打包到一个 tar 文件中。

为了在本地测试我们的包,我们只需要运行:

python setup.py install

那么我们现在可以把它当作:

cver search python

为了在 PyPI 测试服务器上测试我们的包,我们需要为本地测试生成一个构建。创建一个构建将同时生成 python wheel 和源档案。

要创建构件:

python setup.py sdist bdist_wheel

这将在dist目录中生成两个文件:

cvecli/
│
└── dist/
    ├── cver-1.0.0-py3-none-any.whl
    └── cver-1.0.0.tar.gz

然后使用 twine,我们现在可以上传到服务器:

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

这将要求您输入用户名和密码,因此请确保输入正确。

如果上传成功,没有任何问题,这意味着我们可以在服务器上发布。你可以在这里查看。

要从 TestPyPI 安装,运行以下命令:

pip install -i [https://test.pypi.org/simple/](https://test.pypi.org/simple/) cver==1.0.0

从这里你可以尝试所有的命令,看看在我们发布到服务器之前是否一切顺利。

测试完所有命令并准备好发布到 live server 后:

twine upload dist/*

出现提示时,输入您的用户名和密码。就是这样!

您现在可以使用以下方式安装它:

pip install cver

恭喜你!你的包发布在 PyPI 上,你可以在这里查看!

结论

在本文中,我解释了如何用 Python 构建和发布下一个命令行应用程序的逐步过程。

如何使用 BigQuery ML 利用网站数据构建受众群

原文:https://towardsdatascience.com/how-to-build-audience-clusters-with-website-data-using-bigquery-ml-6b604c6a084c?source=collection_archive---------15-----------------------

理解大数据

收集受众见解和建立客户细分的技术指南

一个常见的营销分析挑战是理解消费者行为并开发客户属性或原型。随着组织更好地解决这个问题,他们可以激活营销策略,将更多的客户知识融入到他们的活动中。使用一种叫做聚类的技术,使用 BigQuery ML 构建客户档案比以往任何时候都容易。在这篇文章中,你将学习如何创建细分市场,以及如何利用这些受众进行营销活动。

为什么聚类算法如此重要?

聚类算法可以将相似的用户行为分组在一起,以建立用于营销的细分。随着我们进入个性化时代,聚类算法可以帮助公司通过基于网站行为的广告向现有客户或潜在客户发送专门的信息。

聚类算法是如何工作的?

在本教程中,我将提供对聚类算法的简单理解,然而,大部分内容将涵盖过程和实现,而不是幕后发生的事情。一般来说,聚类属于无监督机器学习的范畴。我们正在运行一个算法,具体来说,在这个过程中,我们将使用 k-means,在不给算法一个目标变量来训练的情况下,找出数据如何逻辑地分组在一起。例如,假设我们想根据年龄和估计收入这两个特征对您的受众进行分类。聚类是自动为您完成这一任务的过程。我们面临的唯一输入是我们的数据中存在多少个聚类。在下面的例子中,三个集群“感觉”正确。这个例子可能看起来很简单,但是您可以看到这个问题是如何变得无法手工处理更多的特性的。

作者图片

聚类的数量通常更难确定,并且通常是执行分析的人的主要挑战。我们将花时间给出一个示例工作流和流程来帮助应对这一挑战。现在,考虑将操作集群化,以自动将我们的数据分组在一起。

数据

我们将使用公开可用的 Google Analytics 360 样本数据集,它托管在 BigQuery 上,包含来自 Google 商品商店的 12 个月(2016 年 8 月至 2017 年 8 月)模糊的 Google Analytics 360 数据,这是一家销售 Google 品牌商品的真实电子商务商店。我们还将构建合成的 CRM 数据来展示线下+线上数据的力量,这将提供一个更加全面的用户行为视图。

来自谷歌商品商店的截图

这是来自谷歌分析 360 的一些原始数据的样本

处理数据

为聚类构建特征(我们关心的个人属性)完全取决于我们试图解决的问题。在花太多时间处理数据集之前,您应该首先确定业务挑战。为了做到这一点,请咨询您的业务利益相关者,以确定您想要解决的问题。例如,您可能会假设人口统计和地理数据、SKU 或产品类别、重复购买者或首次购买者以及当前客户价值之间的关系。你会注意到这包括了分类特征和连续特征的混合。通常,如果您使用 scikit-learn、statsmodels 或其他软件包,这意味着需要时间来规范化和在数据中创建一个热编码。BigQuery ML 的一个直接优势是这个需求不存在!您可以以原始格式传递要素,而无需预处理。当然,花时间做探索性的数据分析并理解您的数据集,但是享受使用 BigQuery ML 节省的时间。

本教程的一些问题和注意事项:

在本教程中,我们将做一些假设。例如,我们将简化方法,并假设当 pagetype = "EVENT "时发生购买。您的 Google Analytics 360 设置可能会有所不同,因此您可能需要进行相应的调整。我们还使用 fullVisitorID 作为我们的 cookie 标签。虽然这是正确的,但我们建议您将 clientID 设置为自定义维度,其中 clientID 只是 fullVisitorID 的哈希版本。当你想在以后的道路上激活观众时,这是一个要求。我们还假设您有可以映射到 fullVisitorID 的离线数据。我们将创建 3 个 BigQuery 视图。第一个视图是聚合 GA360 数据,第二个视图是聚合 CRM 数据,最后是连接在一起,最终用于建模。这样,我们就可以创建我们的第一个视图了(注意,SQL 很长,所以我会在这篇博客中将其缩短,但是完整的代码可以在这个 github repo 中找到)

*# We start with GA360 data, and will eventually build synthetic CRM as an example.* 
*# This block is the first step, which is just working with GA360
# I am cutting this code short for formatting.  See github for full code.*ga360_only_view = 'GA360_View'
shared_dataset_ref = client.dataset(DATA_SET_ID)
ga360_view_ref = shared_dataset_ref.table(ga360_only_view)
ga360_view = bigquery.Table(ga360_view_ref)ga360_query = '''
SELECT
  fullVisitorID,
  ABS(farm_fingerprint(fullVisitorID)) AS Hashed_fullVisitorID, 
  MAX(device.operatingSystem) AS OS, 
  SUM (CASE
       WHEN REGEXP_EXTRACT (v2ProductCategory, 
                           r'^(?:(?:.*?)Home/)(.*?)/') 
                           = 'Apparel' THEN 1 ELSE 0 END) AS Apparel,...
FROM
  `bigquery-public-data.google_analytics_sample.ga_sessions_*`,
  UNNEST(hits) AS hits,
  UNNEST(hits.product) AS hits_product
WHERE
  _TABLE_SUFFIX BETWEEN '20160801'
  AND '20160831'
  AND geoNetwork.country = 'United States'
  AND type = 'EVENT'
GROUP BY
  1,
  2
'''ga360_view.view_query = ga360_query.format(PROJECT_ID)
ga360_view = client.create_table(ga360_view)  *# API request*

视图以这种格式创建数据

现在我们有了利用网站行为的基线数据集,我们希望将它与我们可能也了解的用户的离线数据结合起来。为了最好地展示这一点,我们将简单地生成合成数据。如果您有更好的数据源,请随意用您自己的流程替换这一部分。如果没有,请遵循以下步骤:

*# Create synthetic CRM data in SQL*CRM_only_view = 'CRM_View'
shared_dataset_ref = client.dataset(DATA_SET_ID)
CRM_view_ref = shared_dataset_ref.table(CRM_only_view)
CRM_view = bigquery.Table(CRM_view_ref)*# Query below works by hashing the fullVisitorID, which creates a random distribution.* 
*# We use modulo to artificially split gender and hhi distribution.*CRM_query = '''
SELECT
  fullVisitorID,
IF
  (MOD(Hashed_fullVisitorID,2) = 0,
    "M",
    "F") AS gender,
  CASE
    WHEN MOD(Hashed_fullVisitorID,10) = 0 THEN 55000
    WHEN MOD(Hashed_fullVisitorID,10) < 3 THEN 65000
    WHEN MOD(Hashed_fullVisitorID,10) < 7 THEN 75000
    WHEN MOD(Hashed_fullVisitorID,10) < 9 THEN 85000
    WHEN MOD(Hashed_fullVisitorID,10) = 9 THEN 95000
  ELSE
  Hashed_fullVisitorID
END
  AS hhi
FROM (
  SELECT
    fullVisitorID,
    ABS(farm_fingerprint(fullVisitorID)) AS Hashed_fullVisitorID,
  FROM
    `bigquery-public-data.google_analytics_sample.ga_sessions_*`,
    UNNEST(hits) AS hits,
    UNNEST(hits.product) AS hits_product
  WHERE
    _TABLE_SUFFIX BETWEEN '20160801'
    AND '20160831'
    AND geoNetwork.country = 'United States'
    AND type = 'EVENT'
  GROUP BY
    1,
    2)
'''CRM_view.view_query = CRM_query.format(PROJECT_ID)
CRM_view = client.create_table(CRM_view)  *# API request*

综合 CRM 数据的输出

运行上面的作业后,我们现在有了前两个视图。要将两者结合在一起,并创建我们的最终视图,过程非常简单:

*# Build a final view, which joins GA360 data with CRM data*final_data_view = 'Final_View'
shared_dataset_ref = client.dataset(DATA_SET_ID)
final_view_ref = shared_dataset_ref.table(final_data_view)
final_view = bigquery.Table(final_view_ref)final_data_query = f'''
SELECT
    g.*,
    c.* EXCEPT(fullVisitorId)
FROM **{**ga360_view.full_table_id.replace(":", ".")**}** g
JOIN **{**CRM_view.full_table_id.replace(":", ".")**}** c
ON g.fullVisitorId = c.fullVisitorId
'''final_view.view_query = final_data_query.format(PROJECT_ID)
final_view = client.create_table(final_view)  *# API request*print(f"Successfully created view at **{**final_view.full_table_id**}**")

用于建模的最终数据集就是这个形状。我们现在可以开始建模了。

创建我们的初始模型

在这一节中,我们将建立我们的初始 k 均值模型。我们不会关注最优 k(我们构建的集群数量)或其他超参数。

一些附加要点:

  1. 我们删除了作为输入的 fullVisitorId,因为它不是一个有用的特性。请记住,高基数数据对分组没有用处。
  2. 我们既有分类特征,也有数字特征。
  3. 我们不需要规范化任何数字特征,因为 BigQuery ML 会自动为我们做这件事。
  4. 我们不为分类特征构建一个热编码,因为 BigQuery ML 也会为我们做这件事。

构建一个函数来构建我们的模型

我们将构建一个简单的 python 函数来构建我们的模型,而不是用 SQL 做所有的事情。这种方法意味着我们可以异步启动几个模型,让 BQ 并行运行。另一种方法是使用 BigQuery 脚本(虽然串行完成,因此速度较慢)。

我们将从构建一个简单的模型开始,确保一切看起来都是正确的,然后改进我们的流程。第一步如下:

**def** makeModel (n_Clusters, Model_Name):
    sql =f'''
    CREATE OR REPLACE MODEL `**{**PROJECT_ID**}**.
                             **{**DATA_SET_ID**}**.
                             **{**Model_Name**}**` 
    OPTIONS(model_type='kmeans',
    kmeans_init_method = 'KMEANS++',
    num_clusters=**{**n_Clusters**}**) ASSELECT * except(fullVisitorID, Hashed_fullVisitorID) 
    FROM `**{**final_view.full_table_id.replace(":", ".")**}**`
    '''job_config = bigquery.QueryJobConfig()
    client.query(sql, job_config=job_config)  *# Make an API request.*

这创建了一个函数,将为我们建立一个模型,并允许用户定义 k(我们将建立多少个集群)。为了测试,让我们调用 k=3 的函数。

makeModel(3, "test")

一旦训练完成,您现在就有了一个存储在 BigQuery 中的模型对象,您可以通过单击模型在 Bigquery UI 中查看和引用它。我们建议您在开始时回顾一下您的模型对象的细节、训练、评估和模式,以理解我们刚刚做了什么。在后面的小节中,我们将向您展示如何以编程方式检索最终模型的统计数据。

“模型评估”选项卡提供汇总统计数据

建立一个更好的模型

尽管我们刚刚完成了第一个 k-means 模型的构建,但我们仍然没有解决实现聚类过程时的主要问题——我们应该构建多少个聚类(k )?确定 k 的正确值完全取决于用例。有一些简单明了的例子可以告诉您需要多少个集群。假设您正在预处理手写数字——这告诉我们 k 应该是 10。或者,也许你的企业利益相关者只想开展三种不同的营销活动,并需要你识别三个客户群,那么设置 k=3 将是有意义的。但是,使用案例有时更加开放,您可能想要探索不同数量的聚类,以查看如何在每个聚类内以最小的误差将数据分组在一起。为此,我们可以使用肘方法,这是简单的图表损失对 k,以及戴维斯-波尔丁分数

下面我们将创建几个模型来执行肘法并得到戴维斯-波尔丁评分。您可以更改 low_k 和 high_k 等参数。我们的流程将在这两个值之间创建模型。还有一个名为 model_prefix_name 的参数。我们建议您保留其当前值。它用于为我们的模型生成命名约定。

*# Define upper and lower bound for k, then build individual models for each k.* 
*# After running this loop, look at the UI to see several model objects that exist.*low_k = 3
high_k = 15
model_prefix_name = 'kmeans_clusters_'lst = list(range (low_k, high_k+1)) *#build list to iterate through k values***for** k **in** lst:
    model_name = model_prefix_name + str(k)
    makeModel(k, model_name)
    print(f"Model started: **{**model_name**}**")

现在我们可以开始分析我们的模型了。这样做的目的是为我们的用例确定正确的模型。

*# This will create a dataframe with each model name, the Davies-Bouldin Index, and Loss.* 
*# It will be used for elbow method and to help determine optimal K*df = pd.DataFrame(columns=['davies_bouldin_index',           'mean_squared_distance'])
models = client.list_models(DATA_SET_ID)  *# Make an API request.*
**for** model **in** models:
    full_model_id = f"**{**model.dataset_id**}**.**{**model.model_id**}**"
    sql =f'''
        SELECT 
            davies_bouldin_index,
            mean_squared_distance 
        FROM ML.EVALUATE(MODEL `**{**full_model_id**}**`)
    '''job_config = bigquery.QueryJobConfig()*# Start the query, passing in the extra configuration.*
    query_job = client.query(sql, job_config=job_config)  
    df_temp = query_job.to_dataframe()  
    df_temp['model_name'] = model.model_id
    df =  pd.concat([df, df_temp], axis=0)

现在,我们将绘制我们的值与聚类数的关系图,并得到一些值得分析的东西!

*# Plot the dataframe above*df['n_clusters'] = df['model_name'].str.split('_').map(**lambda** x: x[2])
df['n_clusters'] = df['n_clusters'].apply(pd.to_numeric)
df = df.sort_values(by='n_clusters', ascending=**True**)
df.plot.line(x='n_clusters', y=['davies_bouldin_index', 'mean_squared_distance'])

作者图片

如果您选择了自己的数据,或者如果您使用了一组不同的初始化标准,那么您可能会得到一些不同的值。如果您希望一致地返回相同的集群进行延伸运行,您可以通过超参数选择明确选择您的初始化。

上图中有几个标注值得讨论。首先从我们的橙色线开始(loss vs n_clusters)。我们看到,一般来说,随着集群的增加,我们的损失会减少,这是意料之中的。该线也以相对稳定的速度下降。这很常见,也是为什么用肘法不够的原因。偶尔,你可能会惊喜地发现,在某个点上,损耗变平了,形成了肘部形状。如果是这样,这表明连续的集群没有提供额外的价值。

因为我们看不到这个形状,我们可以继续看蓝线,戴维斯-波尔丁指数。一个简单的描述是,您可能希望使用该得分最低的聚类数。我们看到,在 k=5 时,我们有一个相对较低的分数,直到 k=10 时才被击败。我们决定评估 10 个独立的消费者群是没有意义的,因此我们将在 k=5 处结束。

分析我们最后的集群

如前所述,您可以在前端检查模型性能。我们建议您从这里开始,但是,有些用例需要以编程方式检索结果。为了做到这一点,使用 ML.CENTROIDS。

model_to_use = 'kmeans_clusters_5' *# User can edit this*
final_model = DATA_SET_ID+'.'+model_to_usesql_get_attributes = f'''
SELECT
  centroid_id,
  feature,
  categorical_value
FROM
  ML.CENTROIDS(MODEL **{**final_model**}**)
WHERE
  feature IN ('OS','gender')
'''job_config = bigquery.QueryJobConfig()*# Start the query*
query_job = client.query(sql_get_attributes, job_config=job_config) 
df_attributes = query_job.result()
df_attributes = df_attributes.to_dataframe()
df_attributes.head()

我们还可以使用下面更多的 SQL 来计算额外的汇总统计数据。两种 ML 的组合。预测和 ML。质心是有帮助的。

*# get numerical information about clusters*sql_get_numerical_attributes = f'''
WITH T AS (
SELECT 
  centroid_id,
  ARRAY_AGG(STRUCT(feature AS name, 
                   ROUND(numerical_value,1) AS value) 
                   ORDER BY centroid_id) 
                   AS cluster
FROM ML.CENTROIDS(MODEL **{**final_model**}**)
GROUP BY centroid_id
),Users AS(
SELECT
  centroid_id,
  COUNT(*) AS Total_Users
FROM(
SELECT
  * EXCEPT(nearest_centroids_distance)
FROM
  ML.PREDICT(MODEL **{**final_model**}**,
    (
    SELECT
      *
    FROM
      **{**final_view.full_table_id.replace(":", ".")**}**
      )))
GROUP BY centroid_id
)SELECT
  centroid_id,
  Total_Users,
  (SELECT value from unnest(cluster) WHERE name = 'Apparel') AS Apparel,
  (SELECT value from unnest(cluster) WHERE name = 'Office') AS Office,
  (SELECT value from unnest(cluster) WHERE name = 'Electronics') AS Electronics,
  (SELECT value from unnest(cluster) WHERE name = 'LimitedSupply') AS LimitedSupply,
  (SELECT value from unnest(cluster) WHERE name = 'Accessories') AS Accessories,
  (SELECT value from unnest(cluster) WHERE name = 'ShopByBrand') AS ShopByBrand,
  (SELECT value from unnest(cluster) WHERE name = 'Bags') AS Bags,
  (SELECT value from unnest(cluster) WHERE name = 'productPrice_USD') AS productPrice_USD,
  (SELECT value from unnest(cluster) WHERE name = 'hhi') AS hhiFROM T LEFT JOIN Users USING(centroid_id)
ORDER BY centroid_id ASC
'''job_config = bigquery.QueryJobConfig()*# Start the query*
query_job = client.query(sql_get_numerical_attributes, job_config=job_config) *#API Request*
df_numerical_attributes = query_job.result()
df_numerical_attributes = df_numerical_attributes.to_dataframe()
df_numerical_attributes.head()

我们现在可以开始理解集群是如何基于上面提供的值构建的。我们看到以下内容:

第一类:服装购物者,他们也比平常购买得更多。这一部分(尽管是合成数据)偏向女性。

集群 2:最有可能按品牌购物,并对包感兴趣。该细分市场的平均购买量低于第一个集群,但是,这是价值最高的客户。

集群 3:人口最多的集群,这个购买量小,平均花费少。这部分人是一次性购买者,而不是品牌忠诚者。

群组 4:对配件最感兴趣,购买频率不如群组 1 和群组 2,但购买频率高于群组 3。

群组 5:这是一个异常值,因为只有 1 个人属于这个群组。

通过单击模型,还可以从 BigQuery 的 UI 中获得简单的输出。输出如下所示。

“模型评估”选项卡提供汇总统计数据

使用模型对新网站行为进行分组,然后将结果推送到 Google Analytics 360 进行营销激活

在我们有了一个最终确定的模型后,我们想用它来进行推理。下面的代码概述了如何对用户进行评分或将其分配到集群中。这些被标记为质心 ID。虽然这本身是有帮助的,但我们也推荐一个将这些分数吸收回 GA360 的过程。将您的 BigQuery ML 预测导出到 Google Analytics 360 的最简单方法是使用调制解调器(营销模型部署,https://github.com/google/modem)。MoDeM 帮助您将数据加载到 Google Analytics 中,以便最终在 Google Ads 中激活,显示&视频 360 和搜索广告 360。

sql_score = f'''
SELECT * EXCEPT(nearest_centroids_distance)
FROM
  ML.PREDICT(MODEL **{**final_model**}**,
    (
    SELECT
      *
    FROM
      **{**final_view.full_table_id.replace(":", ".")**}**
      LIMIT 1))
'''job_config = bigquery.QueryJobConfig()*# Start the query*
query_job = client.query(sql_score, job_config=job_config) *#API Request*
df_score = query_job.result()
df_score = df_score.to_dataframe()df_score

新的得分用户

清理:删除模型和表

下面的简单过程将删除所有模型和表格

*# Are you sure you want to do this? This is to delete all models*models = client.list_models(DATA_SET_ID) *# Make an API request.*
**for** model **in** models:
    full_model_id = f"**{**model.dataset_id**}**.**{**model.model_id**}**"
    client.delete_model(full_model_id)  *# Make an API request.*
    print(f"Deleted: **{**full_model_id**}**")*# Are you sure you want to do this? This is to delete all tables and views*tables = client.list_tables(DATA_SET_ID)  *# Make an API request.*
**for** table **in** tables:
    full_table_id = f"**{**table.dataset_id**}**.**{**table.table_id**}**"
    client.delete_table(full_table_id)  *# Make an API request.*
    print(f"Deleted: **{**full_table_id**}**")

把一切都包起来

在这个练习中,我们用 BigQuery ML 中的 k-means 完成了一些很酷的事情。最值得一提的是,我们能够将在线和离线用户级别的信息结合起来,以便更深入地了解我们客户的整体情况。我们已经对用户行为进行了建模,并详细介绍了一种确定最佳集群数量的方法。我们能够通过推理将这种洞察力应用到未来的行为中。最后,我们可以将这个推断分数导入 GA360,用于未来的营销活动。

想要更多吗?

请留下您的意见和任何建议或更正。

我是 Tai Conley,谷歌云平台的 AI/ML 专家客户工程师。你可以在 LinkedIn 上找到我。

感谢审稿人 : Abhishek Kashyap,Polong Lin 和 Oly Bhaumik。

如何构建让你作为数据科学家感到自豪的代码

原文:https://towardsdatascience.com/how-to-build-code-you-can-be-proud-of-as-a-data-scientist-19c4101752fc?source=collection_archive---------21-----------------------

入门

让你在竞争中脱颖而出

照片由 Unsplash 上拍摄

人们普遍认为数据科学家无法写出清晰易懂的代码。你不一定要这样。通过学习一些如何正确编写代码的原则,你可以将这种模式化运用到你的优势中,让你在竞争中脱颖而出。

为了找到最佳实践,我们应该只看软件工程的可靠实践。以下是一些软件工程原则,可以让你像数据科学家一样编写干净、易读、易操作的代码:

阅读文档

当谈到使用新技术时,我看到数据科学家犯的最大错误之一是忽略文档。工具或库的文档只是为了帮助用户更容易地将工具应用到他们的工作中。

当用户没有查阅文档时,开发阶段可能会花费太长时间,或者库可能没有被充分利用。

因此,当您准备使用一个从未使用过的工具时,请务必阅读并理解文档。这会让你的生活更轻松。

编写文档

既然说到这个话题,我也必须强调写文档的重要性。您可能没有开发出将被成千上万人使用的最先进的代码,但是简单地记下您的代码中的所有内容就足够了。

这对那些在你之后使用你的代码的人,对你的队友,对你几年后回头看你写的东西的时候都是有用的。

你的文档不必看起来超级专业。只要一个 word 文档描述这段代码做什么,输入是什么,输出是什么就足够了。

评论评论评论

类似于创建文档,对代码本身进行注释是一个救命稻草。养成一个习惯,在你写的每个函数的开头加上一两句话,解释这个函数做什么,预期的输入和输出是什么。如果函数中有一些复杂的逻辑,记下一些行做了什么。例如:“这行计算每列的平均值”,“这行删除平均值小于 10 的”,等等。

编码前设计

这不是颜色/布局设计。在设计中,您决定项目的总体流程。在我的脑海中,我将代码设计分为两类:

  • 知道你的输入和输出需要什么:对于你写的任何东西,都会有一个输入和输出。决定什么将被输入到你的代码中。这可能是您的业务利益相关者的需求,或者是您可以在网上找到的 JSON 类型。例如“我将从互联网上下载一个 CSV 文件”或“我将发送到数据库的 json 格式的查询答案”等。
  • 有目的地编写代码:当你开发代码时,在每一步,花些时间想想接下来会发生什么。你知道你更大的目标,但短期目标是什么?在项目的这个阶段,你想达到什么目的?在掌握数据科学方法上,规划步骤以内置任务的形式出现。在开始实现之前,您需要回答几个问题。以下是一名学生对这些作业的评价:

我发现,如果我不写下我的目标、假设或我想如何想象某件事的大纲……那么我的大脑很容易在设置这件事的过程中迷失或靠边站。这真的很容易忘记时间,甚至忘记我正在努力实现的具体具体的小步骤。喜欢这些有用的辅导问题!”—内森·埃克尔

点击此处了解课程的更多信息

清理您的代码

当然,说你需要清理你的代码有点抽象。我在这里的意思是,当你完成代码时,不要在代码中添加任何不必要的东西。这对数据科学家来说尤其是个问题。在 Jupyter 笔记本上,很可能尝试几行代码只是为了看看结果会是什么,然后忘记删除它,或者忘记跟踪哪些单元格是程序的一部分,哪些不再使用。

我所做的就是打开一个草稿本和一个最终本。我从在草稿本上编码开始。我在草稿笔记本上尝试了所有我想尝试的东西,并一步一步地实现了这些功能。而且每次我完成项目的一个阶段(比如数据探索),我都会审核并把代码转移到最终的笔记本上。这样,我总是保持我的代码有条理,在最终的笔记本上没有不必要的代码行。这也有助于将错误降到最低,因为我会在每个阶段结束时检查我的代码。

遵循命名惯例并清楚地命名

遵循严格的命名准则是软件工程中的一件大事。例如,根据您使用的语言或您工作的团队,这些可能是:

  • 变量名应该以小写字母开头,变量名的第一个字母应该大写(soLikeThis)或
  • 函数名应该以大写字母开头(FunctionNameXyZ)。

我不知道数据科学社区有严格的命名政策,老实说,我不认为强制执行这一政策是可行的。尽管如此,我认为与你自己的命名保持一致是个好主意。

只要决定你的风格是什么。在命名变量、类和函数时,有两种选择:大写字母(NewVariable)或无大写字母(newVariable)、下划线(new_variable)或无下划线(newVariable)。为每一种选择一种风格,并坚持下去。这将使你的代码更容易理解。

不过有一件事我很严格,那就是明确命名。你应该根据它们的角色来命名你的变量、函数和类,而不是随机的。数据帧 1 不可接受。尤其是当数据框在您的代码中起着关键作用时。这并不意味着您应该将其命名为 data frame _ where _ location _ and _ time _ is _ merged _ for _ model _ training。保持简短,让阅读你的代码的人能够理解。但是话说回来,当你获得一些经验时,命名会变得更容易,所以不要为了让它尽善尽美而给自己太大压力。

保持一个整洁的文件结构

根据我的观察,数据科学家倾向于下载数据,启动笔记本,编写代码片段,并把它们放在桌面上,只有在真正需要的时候,他们才会把所有东西放在一个文件夹中。这不仅看起来不专业,也是生产力的杀手。当他们知道他们需要首先在上周随机创建的 10 个笔记本中找到他们需要工作的笔记本时,他们想要开始工作。

将所有项目文件保存在一个地方。为你的数据准备一个文件夹,并清楚地给你的笔记本命名,这样你就知道哪一个是你需要处理的。仅此而已。没什么特别的。只要在项目开始的时候就开始这个结构,这样你就不用花几个小时去整合所有的东西。

使用版本控制

版本控制,或者换句话说,把你的代码保存在 GitHub 上会帮助你自信地做出改变,而不用害怕破坏一切。它将帮助你跟踪什么改变了,它将使你的代码在某个地方的服务器上保持愉快和舒适,这样它就不会仅仅因为有人离开你的公司而被删除。

我所说的“使用版本控制”不仅仅意味着你应该设置它。你也应该在你的项目中积极地使用它。每当你完成项目的一个新的部分时,把你的改变推送到 Git。让上传你的改变和工作成为一种日常习惯。这样,一切都保持良好和有组织的状态,对于新加入你的团队的人来说,继续工作是微不足道的。最重要的是,当某些东西崩溃时,恢复到最新的工作版本是很容易的。

有效地使用调试

调试是在代码中出现问题时找出问题所在的能力。如果没有编码背景,这是新数据科学家最常见的技能之一。但这没问题,因为就像其他事情一样,这只是一项你需要学习的技能。

调试不仅仅是盯着你的屏幕试图找出问题所在。您需要知道如何与您的代码交流,以及如何理解它在抱怨什么。这可能包括:改变变量值,注释掉行,打印变量值,看看是否一切如你所愿。如果没有,这意味着有问题,你应该解决它。

如果我能告诉你一件关于调试的事情,那应该是:调试时一次只改变一件事。当你考虑它的时候,它是科学的。如果你想知道为什么有些事情不工作,你有 5 个不同的变量,你需要一个一个地改变它们,看看哪一个影响结果。如果你同时改变两个,并看到结果的变化,你不能推断哪个是导致变化的原因。听起来很简单,但许多新数据科学家犯了一个错误,他们太急于修复错误,反过来让他们的调试持续更长时间。

总而言之,说到编码,没有人是完美的。但是如果你遵循软件工程师使用的一些简单规则,你将会改进你的编码。一旦你开始把每天编码作为你工作的一部分,你的习惯将会是最重要的,还有什么更好的方法来获得更好的习惯,然后从今天开始适应最佳实践!

🐼想更多地了解熊猫吗? 获取我的免费熊猫小抄。

如何在 5 分钟内构建新冠肺炎数据驱动的闪亮应用

原文:https://towardsdatascience.com/how-to-build-covid-19-data-driven-shiny-apps-in-5mins-2d7982882a73?source=collection_archive---------60-----------------------

利用新冠肺炎数据中心构建闪亮的应用程序。一个 20 行代码的全功能示例。

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

徽标由加里·桑多兹跟我说话提供。

与新冠肺炎系统相关的数据库很多,但目前没有一个虚拟平台整合了这些来源的很大一部分。这样就很难进行全面的分析,也很难将这些医学信息与外部因素,尤其是社会政治因素联系起来。考虑到这一点,新冠肺炎数据中心旨在开发一个统一的数据集,有助于更好地了解新冠肺炎。

在本教程中,我们将使用到新冠肺炎数据中心的 R 包 COVID19 : R 接口构建一个简单而完整的闪亮应用程序。

假设对闪亮的(网络应用)和情节性的(互动情节)有基本的了解,但是可以简单地通过复制/粘贴来构建一个全功能的应用。加载以下软件包以开始使用:

library(shiny)
library(plotly)
library(COVID19)

新冠肺炎(新型冠状病毒肺炎)

COVID19 R 包通过covid19()功能提供了与新冠肺炎数据中心的无缝集成。键入?covid19获取参数的完整列表。这里我们将使用:

  • country:国名或 ISO 代码的向量。
  • level:粒度级别;数据按(1)国家,(2)地区,(3)城市。
  • start:计息期的开始日期。
  • end:计息期的结束日期。

定义用户界面

定义以下输入…

  • country:国家名称。请注意,选项是使用covid19()功能自动填充的。
  • type:要使用的度量。其中一个是c("confirmed", "tests", "recovered", "deaths"),但还有许多其他的可供选择。完整列表见此处
  • level:粒度级别(国家-地区-城市)。
  • date:开始和结束日期。

…以及输出:

  • covid19plot : plotly 输出,将渲染一个交互的 plot。

把一切都包装成一个fluidPage:

# Define UI for application
ui <- fluidPage(

 selectInput(
  "country", 
  label    = "Country", 
  multiple = TRUE, 
  choices  = unique(covid19()$administrative_area_level_1), 
  selected = "Italy"
 ), selectInput(
  "type", 
  label    = "type", 
  choices  = c("confirmed", "tests", "recovered", "deaths")
 ), selectInput(
  "level", 
  label    = "Granularity", 
  choices  = c("Country" = 1, "Region" = 2, "City" = 3), 
  selected = 2
 ), dateRangeInput(
  "date", 
  label    = "Date", 
  start    = "2020-01-01"
 ),   

 plotlyOutput("covid19plot")

)

服务器逻辑

在 UI 中定义了反馈输入之后,我们将这些输入连接到covid19()函数来获取数据。以下代码片段显示了如何呈现交互式绘图(ly ),当任何输入发生变化时,该绘图会自动更新。请注意,covid19()功能使用内部内存缓存系统,因此数据不会被下载两次。多次调用该函数是非常高效和用户友好的。

# Define server logic
server <- function(input, output) { output$covid19plot <- renderPlotly({
  if(!is.null(input$country)){

   x <- covid19(
    country = input$country, 
    level   = input$level, 
    start   = input$date[1], 
    end     = input$date[2]
   )

   color <- paste0("administrative_area_level_", input$level)
   plot_ly(x = x[["date"]], y = x[[input$type]], color = x[[color]]) }
 })

}

运行应用程序

函数shinyApp从上面实现的uiserver参数构建一个应用程序。

# Run the application 
shinyApp(ui = ui, server = server)

https://guidotti.shinyapps.io/h83h5/有售

结束语

我们构建了一个与 R 包 COVID19 接口的简单应用程序,它代表了一个可重用的通用架构。示例应用程序可以用作更高级的新冠肺炎数据驱动应用程序的构建块。特别是,通过covid19()功能获得的数据集包括关于新冠肺炎案例、政策措施、地理信息和外部关键字的额外指标,这些指标允许使用世界银行公开数据谷歌移动报告苹果移动报告和当地政府数据轻松扩展数据集。参见完整数据集文档COVID19 代码片段

新冠肺炎数据中心是免费软件,没有任何担保。请确保同意使用条款

[1]吉多蒂,即阿尔迪亚,d .(2020)。新冠肺炎数据中心,《开源软件杂志》,5(51):2376

如何构建决策智能软件

原文:https://towardsdatascience.com/how-to-build-decision-intelligence-software-four-lessons-from-launching-my-first-product-49cffd2c432c?source=collection_archive---------37-----------------------

发布我的第一个产品的四个教训

我们淹没在数据中,努力应对我们可以越来越多地建模,但仍然难以解释的复杂问题。我们现在比以往任何时候都更需要在医疗、金融和基础设施等重要领域做出明智的决策。

软件在帮助我们理解世界方面发挥着关键作用。软件产品为我们提供了克服认知盲点、扩展认知和建立联系的方法。决策智能工具代表了我们周围信息的实际应用中的一个巨大飞跃。

应用新技术是棘手的部分。我们想要利用计算和算法进步的可扩展解决方案。这就是产品领导力的用武之地。我们需要指导软件的创建,这样用户就可以利用它来推动他们组织的进步。决策智能软件在提高公司绩效方面发挥着重要作用。利用最佳实践的产品领导者通过提供可被广泛采用的解决方案来塑造成果。

我们如何最好地利用新技术来提高我们决策的质量?

在本文中,我将阐述决策智能软件的重要性和意义,并根据我设计和推出新产品的经验,介绍构建决策智能软件时需要考虑的重要因素。我将讨论管理复杂系统(水网络)的决策者用户,但是这些技术适用于不同的领域。

我希望这些经验教训对开发分析、决策支持和其他面向数据的企业产品以提高决策质量的其他技术专业人员有所帮助。

课程

  1. 设计最大化人机合作关系
  2. 诬陷问题就是问题
  3. 为每个用户类型和数据流中的工作流程步骤量身定制
  4. 开放数据,方便连接(接口是关键)

总的来说,我们运用决策智能将信息转化为行动并改善结果。决策智能通常是数据科学、商业智能、决策建模和管理的结合。组合将取决于组织类型和问题背景。

在网络规划中,决策智能结合了三种方法。我们需要优化来生成最佳计划,需要数据科学来解释它们,需要决策分析来汇聚前进的方向。

这些网络是复杂的系统,需要产生复杂数据的软件。但是如果人们不能使用数据,那么数据又有什么用呢?

我定义了 Aperture 的愿景,这是我们今年在 Optimatics 推出的一款产品,它提供了一个由人工智能驱动的平台。Aperture 在优化结果和做出商业决策的用户之间提供了一座桥梁,因此他们充分认识到了多目标优化的好处。我们的算法允许用户考虑许多标准和决策,探索和评估数以千计的计划来改善他们的网络。有什么问题吗?没有一个最佳解决方案。

多目标优化解决方案探索过程。(图片由作者提供。)

用户从寻找解决方案到试图理解一系列策略,同时平衡相互竞争的目标。在这种平衡上的出色表现对我们的客户来说非常重要。他们的赌注很高,因为每个人都需要水。所以我们的挑战是:

我们如何将这些信息转化为行动?

用于优化结果的 Aperture 仪表盘。(图片由作者提供。)

用户需要一种筛选和理解优化数据的方法。为了满足这一需求,我们构建了 Aperture ,这是一个决策智能工具包,由交互式 web 仪表盘和基于云的数据平台组成。

技术只是等式的一面。如果一个系统很难建模,或者决策者努力实现相互竞争的目标,复杂性就会增加,这意味着没有一种方法是正确的。产品必须满足用户框架和决策的需要,需要决策者和软件之间的双向接口。为了实现人工智能提高决策质量的潜力,我们必须培养难以捉摸的人的因素。

(1)设计最大化人机伙伴关系

采用企业技术的主要驱动力是效率。客户希望增加他们的投资回报。优化是公司提升业绩的有效途径。

对于人类来说,分析结果数据的广度和深度以做出明智的决策通常是不可行的。算法可以获得人类通过纯粹的计算力无法获得的洞察力。但是我们这些普通人在我下面概述的简化的、迭代的工作流程的开始和结束阶段都扮演着关键的角色。

大局决策工作流程。(图片由作者提供。)

尽管预测分析令人兴奋,但机器学习只是整个人工智能的一种方法(优化器体现了搜索范式和规划问题域)。我认为人工智能最令人兴奋的前景是增强人类的判断力——帮助我们做我们不擅长的事情。当然,其中一部分是解析大量数据,但还有更多,比如扩展我们的视角。

我们需要分工和可解释的数据,以便决策者充分利用,在现实世界和数据流之间架起一座桥梁。

我们如何最好地利用这种伙伴关系?我们应该如何弥合分歧?

以我管理的产品 Optimizer 和 Aperture 为例,我们的决策堆栈包括工程判断和领域专业知识、应用的元启发式算法(发现工具)、高性能计算和用户界面。

我们可以将二分法简化为用户(人类)和工具包的计算端(算法)。我们遵循人类算法特异性的规则,让计算机做它们最擅长的事情,为我们的用户提供最大的价值。

  • [ 框架仍然需要人类来框架这个问题。即使是最先进的 AI 也无法定义自己的目标函数。人类以目标和标准的形式定义决策选项——可能性的领域——和期望的结果。
  • [ 探索 ]算法对信息进行编码,评估解决方案,解析模型和场景,将决策空间映射到目标空间,然后通过统计分析对数据进行后处理,如计算决策的概率和影响。
  • [ 决定 ]在工作流程的最后,由人类决定。他们使用判断和数据工具来平衡权衡,发现数据,并在统计、可视化和界面的帮助下研究一种方法。

值得注意的是,并不是所有的知识都包含在可用的数据中。模型中没有捕捉到许多现实世界的考虑因素,算法无法感知或访问这些因素。这就是为什么只有像谷歌这样的组织能够有机地充分利用数据:因为它们是建立在数据之上的。噪音——过量或质量可疑的数据——也是一个重要问题。

一个主要的难点是翻译人和计算机之间的逻辑,以及以有用的方式提取信息的方法。我希望我们的软件能够解决这个问题,解决整个工作流程,充分利用合作关系来帮助我们的用户做出决策。但是要做到这一点,我们要从框架开始。

(2)框定问题就是问题

一开始,一片寂静。然后是噪音。

客户使用软件来解决问题。对于决策智能软件来说,定义问题不仅是起点,也是最关键的一点。其他一切都取决于框架:纳入了哪些数据,可用的替代方案,以及决策者用来衡量进展的绩效指标。软件是一种工具,提供控制和定位,有时甚至是导航。高质量的决策是目的地。

用户需要能够描述约束、优先级和可用资源。数据收集和随后的解释必须以最终目标为动机,从而产生更现实和有用的结果。该框架还应该包括参考点,以便用户进行有用的比较,并指示在结果方面将集中在哪里。

技术本身并不是好的。数据并非天生有用。决策智能产品的新浪潮必须帮助指导用户定义他们的框架。有效的软件应该使决策者能够考虑全局并以最小的摩擦定义目标。但是,考虑到用户类型和他们在旅程中所处的位置,设计考虑会有所不同。

(3)根据数据流中的每个用户类型和工作流程步骤定制分析

正如我们呼吁人类和机器之间的专业化一样,我们也需要构建界面和分析内容来匹配用户及其工作流程步骤。当然,用户的旅程取决于产品应用。

我们构建 Aperture 来处理整个规划工作流程。Aperture 允许技术用户发现、比较和检查策略及其影响。他们策划优化程序计划,以便执行用户可以决定行动计划,并将其提交给利益相关者。

Aperture 技术用户旅程示例。(图片由作者提供。)

我受到启发,扩展用户工作流,为数据流中的决策者创造价值,使客户能够实现其软件订阅的全部潜力。每个工作流程步骤都是一个具有自己分析的仪表板。我们的设计原则是,每一个都应该易于共享、交互、适应和互连。仪表板数据反映了最新的优化结果,一个界面组件或仪表板中的计划选择反映在所有其他组件或仪表板中。

设计始于用户动机。高管用户希望理解数据,以做出合理的业务决策。他们的动机是追求清晰和透明,并最终管理风险。战略计划需要协调执行,并且经常是迭代的,因此它们使用预算阈值等控制点,用新的信息或优先级来细化框架。这意味着我们必须开放我们的软件。

(4)开放数据,方便连接(接口是关键)

开放数据为决策智能技术提供了一个影响放大器。通过将更多用户引入他们的生态系统,科技公司可以提高参与度,提供更多价值,并扩展他们的解决方案。

现在,我所说的开放,并不是指所有人都可以自由进入,没有任何顾虑。关键是将复杂转化为清晰。数据发现必须以上下文为基础,故事和界面要适合用户和目的,突出的数据要过滤掉可行性和噪音。所有这些都强调了监管的重要性——我将在下一篇文章中探讨这一点——以增加信息的相关性、有用性和可访问性

当着手开发后来成为 Aperture 的产品时,我注意到,对于每一个使用 Optimizer 的人来说,都会有更多的技术用户使用它产生的数据。对于这些技术用户中的每一个,下游会有其他利益相关者和决策者想要检查并提供反馈。

因此,我们有机会与从建模师和规划者到公用事业公司高管和公众的广大用户接触并向他们传递价值。为了实现这一目标,我们需要扩展我们的软件产品和工作流,为用户提供协作和共享计划的机会。是时候通过向一系列决策者开放规划过程来开放 Optimatics 了。

我们非常依赖数据可视化、映射和汇总统计来开放数据(大声喊出 d3.js传单熊猫scikit-learn )。我们的客户可以解释、实施和交流优化结果,从而在规划水网络时提高决策质量。但是每个产品领导者都会根据他们用户的需求组装他们自己的工具包。

一年前,我开始着手解决一个问题:帮助我们的客户理解他们的数据,以提高他们商业决策的质量。我最终发现了创建一个平台的机会,这个平台可以促进数据、工具和人之间的联系。我们通过开放产品来扩大我们产品的影响,现在随着我们的用户能够获得更丰富的见解,我们的产品得到了更广泛的采用。我希望您会发现这些课程对您自己的产品开发之旅有用。

软件和人工智能可以通过有价值的数据来帮助对抗熵。但是这需要深思熟虑的产品设计和工程来实现。创新工具改善重要领域复杂决策的潜力从未如此之大。我们去建吧。

如有任何问题或意见,请随时给我留言或评论。

请继续关注我的下一篇文章,关于构建决策智能产品用于数据故事和管理。它将涵盖我们如何通过允许用户集合观点、聚合知识、将信息转化为决策、将决策转化为行动来创造可扩展的价值。

如何构建决策树

原文:https://towardsdatascience.com/how-to-build-decision-trees-aa4c09114eba?source=collection_archive---------24-----------------------

使用 Python 示例从头构建简单的决策树

决策树是数据科学中进行预测的一种流行且强大的方法。决策树也形成了其他流行的集成方法的基础,如 bagging、boosting 和 gradient boosting。它的流行是由于该技术的简单性使其易于理解。我们将讨论为几个分类问题构建决策树。首先,让我们从一个简单的分类例子开始解释决策树是如何工作的。

代码

虽然本文主要描述构建和使用决策树的细节,但是在 my GitHub 中可以找到用于拟合决策树、使用决策树进行预测以及打印绘制决策树的点文件的实际 Python 代码。

简单的例子

假设我们有 10 个不同宽度和高度的矩形。五个长方形是紫色的,五个是黄色的。数据如下所示,X1 表示宽度,X2 表示高度,Y 表示紫色矩形的等级 0 和黄色矩形的等级 1:

矩形数据

画出矩形,我们可以很清楚地看到不同的类。

矩形图

基于矩形数据,我们可以构建一个简单的决策树来进行预测。决策树由决策节点和叶节点组成。在下面的决策树中,我们从最上面的方框开始,它代表了树的根(一个决策节点)。根中的第一行文本描述了基于宽度(X1)小于 5.3 来拆分树的最佳初始决策。第二行代表最初的基尼系数,我们将在后面详细讨论。第三行代表初始水平的样本数,在本例中为 10。第四行表示节点的每个类中的项数——紫色矩形为 5,黄色矩形为 5。

矩形决策树

在按小于 5.3 的宽度(X1)分割数据后,我们得到两个叶节点,每个节点中有 5 个项目。所有紫色矩形(0)都在一个叶节点中,所有黄色矩形(1)都在另一个叶节点中。它们相应的基尼系数、样本大小和数值都会更新,以反映这种差异。

在这个非常简单的例子中,我们可以通过简单地检查矩形的宽度是否小于 5.3 来预测给定的矩形是紫色还是黄色。

基尼指数

构建决策树的关键是确定每个决策节点的最优分割。使用上面的简单例子,我们如何知道在 5.3 的宽度(X1)处分割根?答案在于基尼指数或分数。基尼指数是一个用来评估收入差距的成本函数。其定义如下:

所有类的 p(1-p)之和,其中 p 是一个节点中一个类的比例。由于 p 的和为 1,所以公式可以表示为 1 — sum(p 的平方)。基尼指数计算随机选择时某一特定特征被错误分类的概率,在 0 到 0 . 5 之间变化。

使用我们简单的 2 类示例,根节点的基尼指数是(1 — ((5/10) + (5/10) )) = .5 —矩形在 2 类中的平均分布。所以这个节点上 50%的数据集被错误分类。如果基尼系数是 0,那么在这个节点上我们的数据集将 100%被正确分类(0%不正确)。我们的目标是使用最低的基尼系数来构建决策树。

确定最佳分割

为了确定最佳分割,我们需要遍历所有特征,并将相邻训练样本之间的中点视为候选分割。然后,我们需要评估分割的成本(基尼系数),并找到最佳分割(最低基尼系数)。

让我们看一个计算某项功能的基尼系数的例子:

  1. 将 X1 按升序排序,我们得到第一个值 1.72857131
  2. 让我们计算 X1 = 2.771245 的基尼系数
  3. 对于类别 0,拆分是向左 1,向右 4(一个项目<= 2.771245, four items > 2.771245)
  4. 对于类别 1,拆分为左侧 0 和右侧 5(零项目<= 2.771245, five items > 2.771245)
  5. 左侧基尼系数为(1 — ((1/1) + (0/1) ) = 0.0
  6. 右侧基尼系数为(1 — ((4/9) + (5/9) ) = 0.49382716
  7. 拆分的基尼是左右两边的加权平均值(1 * 0) + (9 * 0.49382716) = .4444444

对每一行运行该算法,我们可以得到每个特征的所有可能的基尼系数:

基尼系数

如果我们看基尼系数,最低的是 0.0000,X1 = 6.642(1 级)。我们可以使用 6.642 作为阈值,但更好的方法是使用小于 6.642 的相邻要素,在这种情况下,X1 = 3.961(类 0),并计算中点,因为这表示两个类之间的分界线。所以,中点阈值是(6.642 + 3.961) / 2 = 5.30!我们的根节点现在完成了 X1 < 5.30, a Gini of .5, 10 samples and 5 in each class.

Building the Tree

Now that we have the root node and our split threshold we can build the rest of the tree. Building a tree can be divided into two parts:

  1. Terminal Nodes
  2. Recursive Splitting

终端节点

终端节点或叶子是决策树分支上的最后一个节点,用于进行预测。我们如何知道何时停止生长决策树?一种方法是显式地声明树的深度——在我们的例子中,将深度设置为 1。第一次分裂后,我们停止构建树,两个分裂的节点变成了树叶。更深层次的树会变得非常复杂,使数据过度拟合。

一棵树停止生长的另一种方式是一旦基尼系数为 0——那么就没有必要再分裂了。在我们的示例中,两个叶子的深度为 1,基尼系数为 0,因此实现终止的两种方法都满足。如果我们看终端节点,我们可以看到我们的预测。如果矩形的宽度(X1)小于 5.30,那么移动到树的左边,我们看到预测的类是 0 或紫色矩形。如果矩形的宽度(X1)大于 5.30,那么移动到树的右边,我们看到预测的类是 1 或黄色矩形。

矩形决策树

递归分割

现在我们知道了何时停止构建决策树,我们可以递归地构建该树。一旦我们有了根节点,我们就可以递归地左右分割节点,直到达到最大深度。我们从简单的例子中获得了所有的基本构件,但是为了演示递归分割,我们需要一个更复杂的例子。让我们使用著名的、有点累的 Iris 数据集,因为它在 scikit 中很容易获得,用于比较目的。

通过绘制虹膜数据,我们可以清楚地看到三个类别(Setosa、Versicolor 和 Virginica ),涵盖四个特征中的两个——萼片长度和花瓣长度:

虹膜数据集-萼片长度 x 花瓣长度

让我们递归地创建一个决策树,看看结果是什么样的。

Iris 决策树

在根节点我们有第一个花瓣长度的分割< 2.6 creating a leaf node with a Gini of 0.0 for Setosa and a decision node requiring a new split. We can clearly see the Setosa split in the graph at the midpoint between Setosa and Versicolor (petal_length = 2.6). Since the Gini is 0 for the left node, we are done and the leaf node is created just as we did with our rectangles. On the right side however, our right node has a Gini of .495. Since we have the depth set to 5, we recursively split again on the right node. This continues until we hit a depth of 5, producing the decision tree we see in the graph.

Pruning a Decision Tree

One downside of decision trees is overfitting. With enough depth (splits), you can always produce a perfect model of the training data, however, it’s predictive ability will likely suffer. There are two approaches to avoid overfitting a decision tree:

  1. Pre-pruning — Selecting a depth before perfect classification.
  2. Post-pruning — Grow the tree to perfect classification then prune the tree.

Two common approaches to post-pruning are:

  1. Using a training and validation set to evaluate the effect of post-pruning.
  2. Build a tree using a training set, then apply a statistical test (error estimation or chi-squared test) to estimate whether pruning or expanding a particular node improves the results.

I welcome constructive criticism and feedback so feel free to send me a private message.

Follow me on Twitter @The_Jim_King

这篇文章最初出现在我的网站上

参考代码和数据的文章包括:

机器学习精通——如何用 Python 从零开始实现决策树算法,杰森·布朗利 2019 年 12 月 11 日

GitHub—Joachim valente/决策树-cart,2019 年 10 月 8 日

从头开始构建和部署一个无人监督的学习烧瓶应用程序

原文:https://towardsdatascience.com/how-to-build-deploy-an-unsupervised-learning-flask-app-from-scratch-afd3a18661a7?source=collection_archive---------36-----------------------

学习构建一个部署在 Heroku 上的 web 应用程序,它使用 k-means 算法从上传的图像中挑选调色板。

图片来源:蒂娜·库珀

在这篇博文中,我将详细解释如何设置调色板生成器 web 应用程序。我将介绍设置 flask 应用程序架构的基础知识,用 python 构建 k-means 无监督学习算法的后端,用 html、css 和 javascript 构建前端。我还将介绍使用 jQuery 库连接前端和后端,以及将最终的应用程序部署到 Heroku。

这是我们将要构建的一个快速演示。

调色板生成器应用程序

选择图像文件

获取调色板

该项目的完整代码可以在我的 GitHub 上找到:

[## saffafatima 12/调色板生成器应用程序

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/Saffafatima12/palette-generator-app)

你准备好了吗?让我们开始吧!

设置基本的 flask 应用程序架构

设置一个基本的 flask 应用程序很简单。只需遵循以下步骤:

  1. 用您的应用程序的名称创建一个文件夹。我称之为 demo_app
  2. 打开命令行并安装 flask 模块
  3. cd 到 demo_app 文件夹中,创建一个名为 application 的文件夹(所有的前端都在这个文件夹中)
  4. 现在创建。flaskenv、config.py、main.py、k-means.py 和 requirements.txt 文件(现在还不用担心这些奇怪命名的文件。我将在后面的段落中详细解释每个文件的功能)。
  5. 在应用程序文件夹中创建一个 routes.py 文件和一个 init。py 文件。另外创建两个文件夹 static 和 template。在 static 中,为 css、图像和 javascript 创建子文件夹。在 templates 文件夹中创建一个名为 includes 的子文件夹。
  6. 还可以使用以下命令安装 virtualenv 模块:pip install virtualenv。
  7. 现在要创建一个虚拟环境文件夹,在命令行中运行命令 py -m venv venv。这将在您的 demo_app 的根目录下创建一个名为 venv 的虚拟环境文件夹。

完成后,您的 demo_app 的结构应该如下所示:

demo_app 文件夹

应用程序文件夹

现在我们可以将注意力转向填充我们刚刚创建的文件。

The。flaskenv 文件:在这个文件中,我们将把 flask 环境变量设置为 development,并将该文件链接到 main.py 文件。

main . py 文件:在这个文件中,我们将从应用程序文件夹中导入我们的 flask 应用程序。

config . py 文件:在这个文件中,我们将为 cookies 创建一个密钥。一旦我们在 Heroku 上部署我们的应用程序,这将非常重要。

k-means.py 文件:我们的 k-means 算法将进入这个文件。

requirements.txt 文件:在这个文件中,您将记录应用程序运行所需的所有依赖关系。要填充这个文件,您首先需要进入虚拟环境。您可以通过简单地 cd 到根目录并从命令行运行 venv/scripts/activate 来实现这一点。现在在 venv 中运行 pip freeze > requirements.txt 来记录你当前所有的依赖关系。请记住,在构建应用程序时,您需要更新此文件及其所有依赖项。你可能会注意到烧瓶没有安装在 venv 内。只需使用 pip install flask 命令安装它,并更新 requirements.txt 文件。

_ _ init _ _。py 文件:这里我们只是初始化 app 对象并将其连接到 routes.py 文件

routes . py 文件:这里我们定义当用户路由到某个网址时运行的函数。为了检查一切是否正确,定义一个函数“run ”,返回字符串“flask app 正在运行!”当用户路由到本地服务器地址后的“/”时。

返回命令行(确保您在虚拟环境中,并运行命令‘flask run’。您应该得到一个输出,提供您的应用程序运行的地址。将它复制并粘贴到您的浏览器中,您应该会得到以下输出。

flask app 正在运行!

如果到目前为止一切正常,那么恭喜你!现在,您已经准备好进入构建调色板生成器应用程序的下一个阶段。

编写 k-means 算法文件并将其连接到应用程序

现在我们可以开始为调色板生成器应用程序编写 k-means 算法了。

K-means 算法是一种非常简单的无监督机器学习技术。该算法采用 n 个数据点,并根据数据点和聚类质心之间的距离将它们划分为 k 个聚类。该算法旨在最小化每个数据点到其所属聚类的质心的距离。聚类的数量通常由算法的外部输入来指定。对于调色板生成器应用程序,我们希望算法能够识别相似颜色的像素簇。

我们首先导入所有必要的依赖项,并创建一个 get_points 函数。get_points 函数接收一个图像,将其大小调整为 200×400 像素,并将其转换为 RGB 格式。然后,该函数为预处理图像中的每个像素创建一个 rgb 元组列表。下面给出了带注释的代码。

现在,首先我们将创建两个名为 Point 和 Clusters 的类,它们的属性如下面的代码所示。然后,我们将创建一个函数,根据两个像素的 rgb 值来计算它们之间的欧几里德距离。

现在,我们必须创建一个包含一些函数的 k-means 类。我们将首先有一个初始化器,其中包含该类的属性,即类的数量和每个类的最小差异。

然后,我们创建 calculate_center 函数,它主要计算一个聚类的平均 r,g,b 值,并将其转换为具有这些值的点类。

assign_points 函数计算图像中每个点与每个聚类的质心之间的欧氏距离,并将该点分配给与该点距离最小的聚类。它返回每个聚类的点列表。

拟合函数使用先前定义的函数从图像中的点列表中生成聚类。

最后,我们将使用我们到目前为止定义的所有东西来构造 get_colors()函数。该函数将接受一个图像和聚类数作为输入参数,并返回颜色的十六进制值列表。列表的长度将等于输入的聚类数。

用 html 和 css 构建前端

现在我们可以用 html 和 css 创建前端了。在模板文件夹中,创建一个 index.html 文件。您可以选择在 index.html 文件中编写完整的 html 代码,或者只在 index.html 文件中保留基本的 html 框架,而在 includes 文件夹中的小 html 文件中编写其余的代码。我更喜欢后一种选择,因为当代码是小片段而不是一个大文件时,编写和调试代码要容易得多。每当您希望将代码包含在一个小文件中时,只需将所有代码复制到新创建的文件中,并在 index.html 文件中包含{ % include ' file _ path _ to _ your _ html _ file ' % }。标题的例子是:

{ % include " Includes/header . html " % }。

对于 html,您需要创建三样东西:

  1. 允许用户上传图像的文件选择器
  2. 一个滑块/文本框,允许用户在调色板中输入他们想要的颜色数量
  3. k-means 算法输出中的颜色显示。

使用 css 添加一些样式。将 css 文件保存在静态文件夹的 css 文件夹中,并在 index.html 文件中引用它们。

您还可以通过链接您的。js 文件在 java script 文件夹中静态保存到 index.html 文件中。

使用 j-Query 连接前端和后端

现在您已经构建了前端,我们可以开始使用 routes.py 文件了。

在 route.py 文件中,我们将添加一个在路由到服务器地址时呈现页面的函数。

现在,我们需要有一种方法将用户输入传递给 k-means 算法,并将算法的结果返回给用户。我们将假设从页面中获得一个名为 message 的 json 对象,它有两个键:image 和 name。image key 的值是 base 64 编码的图像,而 name 的值是用户输入的颜色数。我们将把图像对象解码成 Python 可以处理的格式,然后将它传递给从 k-means.py 文件导入的 fit()函数。然后,我们将使用输出,如果你记得是一个十六进制代码的颜色列表,并将它转换成一个名为响应的字典。然后,我们将使用 jsonify 函数将字典转换成 json 对象。

完成 routes.py 文件后,我们可以将注意力转向 index.js 文件,我们将在其中编写所有的 jQuery 代码。

好的,jQuery 方面发生了很多事情,我将尽力以一种容易理解的方式来解释它。

我的想法是读取图像输入,并在应用程序上显示图像。当用户按下“Get color palette”按钮时,k-means 算法的输出用于显示颜色的名称以及调色板区域中的圆圈填充。

为此,我们首先需要定义一个函数来读取上传的图像。要理解下面的代码,您需要对 jQuery 有一些基本的了解。你的代码很有可能和我的不一样,因为我的 html 代码和你的 html 代码不一样,但是我觉得大致思路应该是一样的。因此,该函数基本上是在加载图像文件时读取图像文件输入,并从图像中剥离元数据。我已经为图像插入了一个 console.log()函数,只是为了看看是否一切正常。

我们还需要有一个功能来处理颜色和颜色名称的显示后,获得调色板按钮被点击。为此,我想出了下面的代码。

代码生成了我们在 routes.py 文件中使用的名为 message 的 json 对象。代码还引入了 routes.py 文件中的响应 json 对象,用于更改圆圈的颜色,并在应用程序的调色板区域显示颜色名称。

您可以对 jQuery 代码进行更多的调整,以进一步定制应用程序。

在 Heroku 上部署应用程序

一旦您对 jQuery 感到满意,您就可以将您的应用程序部署到 Heroku。为了部署到 Heroku,我们需要在根目录中创建一个 Procfile。

在您的虚拟环境中安装 gunicorn 包。

您还需要用以下代码创建一个 wsgi.py 文件:

另外,记得更新 requirements.txt 文件中所有添加的依赖项,并将发布地址更新为“您的应用程序名称”。herokuapp.com

现在用 git init 和 git add 命令创建一个 git 存储库(您也可以在早期创建它,并跟踪您在项目中所做的更改)

为了将内容上传到 Heroku,请在 Heroku 上创建一个帐户,并在您的机器上安装 Heroku CLI。通过键入 heroku login 并按照说明进行操作,从命令行登录 Heroku。完成后,使用命令创建一个新的 Heroku 应用程序:heroku create 。现在使用 git 命令将您的应用程序推送到 heroku:git push heroku master。您应该会收到一个很长的输出,包括您的应用程序的网址。

如果发现错误,可以使用 heroku logs-tail 命令进行调试。一旦你排除了任何错误(或者幸运的是没有任何错误),导航到网页找到你的应用程序部署在它的全部荣耀!

调色板生成器应用程序

鸣谢:

我的 k-means 算法的代码来自一个神奇的 Colab 笔记本,可以在 Venelin 的网站上找到:https://www.curiousily.com/。你绝对应该看看维尼林的博客。太棒了!😃

如何建立有效的人机交互:对机器学习和软件工程的思考

原文:https://towardsdatascience.com/how-to-build-effective-human-ai-interaction-considerations-for-machine-learning-and-software-409838d9b358?source=collection_archive---------15-----------------------

图片来源:微软研究院

为了帮助从业者设计更好的面向用户的基于人工智能的系统,微软最近发布了一套基于数十年研究并通过各种人工智能产品的严格用户研究验证的人机交互指南。这些指南涵盖了广泛的交互:从用户最初被引入人工智能系统开始,扩展到持续的交互,人工智能模型更新和改进,以及管理人工智能故障。

虽然指南描述了人工智能从业者应该创造什么来支持有效的人-人工智能交互,但这一系列帖子解释了如何在基于人工智能的产品中实施指南。**

我们关注机器学习和软件工程的含义,因为在大多数情况下,实施任何指南都不能仅仅通过前端接口调整来支持。例如,如果算法本身是不透明的,解释算法的行为(准则 11)是不可能的。在另一个例子中,如果记录基础设施和设备没有跟踪正确的信号,或者如果该信息是有噪声的,则根据用户的当前环境识别和定制信息(准则 3 和 4)可能是不可能的。

这一系列的帖子提出了机器学习从业者和软件工程师今天可以采取的行动,以实现指导方针所描述的有效的人机交互。

  1. 第一部分讨论了在用户与人工智能系统的初始交互过程中,你可以用来帮助他们设定正确期望的方法。
  2. 第二部分将讨论如何基于上下文处理和定时服务。
  3. 第三部分将集中在当前的方法,以减轻偏见和适应用户的社会规范。
  4. 第四部分将把注意力转移到系统可能出错时的处理情况。
  5. 第五部分将扩展支持交互体验的含义。

第一部分:最初设定正确的期望

在这一部分中,我们重点关注在人和人工智能系统之间的初始交互过程中设置正确期望的两条准则:

准则 1 :明确系统能做什么。
准则二:明确系统能做什么,做得有多好。

对于任何面向用户的软件来说,明确系统的功能和限制是非常重要的。这对于基于人工智能的系统来说可能尤为重要,因为人们通常对自己的能力抱有不切实际的期望。传递这些信息的传统技术包括用户手册、内置文档和上下文帮助。不幸的是,今天我们仍然不知道如何为人工智能软件生产这样的工件。以一个问题回答系统为例,比如你最喜欢的个人助理(比如 Alexa、Cortana、Google Assistant、Siri)。我们能精确描述它在哪些领域能回答问题,哪些领域不能吗?如果是这样,我们是否总是知道它在每个域中有多精确?如果助手能够回答历史问题,是否意味着它也能回答地理问题?机器学习工程师能自信地描述这些方面吗?膨胀的用户期望加上缺乏对人工智能系统能力的清晰了解,在最好的情况下会导致不满、不信任或产品放弃,在最坏的情况下会导致伤害、不公平和伤害。

下面,我们概述了工程师和模型开发人员现在可以采取的最佳实践和行动,以帮助终端用户清楚地了解人工智能系统的能力和局限性。

当评估一个人工智能模型的能力和局限性时,不要局限于总的、单一分数的性能数字。

弄清人工智能系统的能力和局限性,首先要对人工智能的潜在行为有一个更全面的理解。这需要重新思考当前依赖于综合、单一分数绩效数字的评估实践。

在机器学习评估中,通常使用诸如“ Model X 对于给定的基准有 90%的准确性”这样的声明来报告模型性能。这个总数很难告诉我们,我们是否应该期望整个基准测试的性能是一致的,或者在这个基准测试中是否有一些数据的准确性要低得多。在实践中,由于训练数据中的偏差或者因为一些概念可能比其他概念更难学习,后者发生得更频繁。这种行为的一个众所周知的例子是 GenderShades 研究,该研究表明,面部识别算法在性别检测方面的性能对于肤色较深的女性来说明显低于其他人口统计群体。如果系统工程师自己都不清楚这些差异,那么向最终用户和客户解释这些差异就更加困难了。

多方面、深入的误差分析可以帮助我们回答以下问题:该模型是否对所有人口统计群体都同样准确? 是否有任何环境或输入上下文使模型表现明显更好或更差? 在第 99 个错误百分点时,系统性能有多差?

要进行多方面、深入的错误分析,请考虑以下实践:

  • 检查不同粒度级别的故障模式Pandora 是一种可以帮助以概括的方式描述故障的方法。Pandora 提供了一组在不同抽象级别上运行的性能视图:全局视图(传达整体系统性能)、集群视图(针对单个数据区)和实例视图(解释单个数据点的性能)。对于每个视图,可以查看一个或多个输入要素的组合如何与模型性能相关联。在这些视图之间来回切换使开发人员能够更好地理解不同上下文中的失败,方法是根据出错的可能性来分割数据。例如,这项工作的结果表明,对于具有丰富和多模态输入空间的系统,不同区域的性能可能非常不同,并且这些差异可能因非常不同的原因而出现。
  • 检查不同数据切片的故障模式 —在语言领域, Errudite 工具允许开发人员以灵活的方式查询输入数据,并根据错误率描述结果集的特征。Errudite 通过引入具有语义意义的数据选择操作符,使数据切片变得更加容易。此外,该工具还支持临时数据编辑,从而支持反事实分析(即如果某个特定示例略有不同,会发生什么?)。

使用多个现实的基准进行评估。

使用任何指标评估人工智能的能力和局限性通常需要在一些数据上测试人工智能模型。在已知的公共基准上评估人工智能模型总是一种好的做法。与其他先进技术相比,它提供了系统性能的量化视角。然而,由于两个原因,它不应该是唯一的评价手段。

首先,在每个模型改进周期中,一次又一次地优化单个基准可能会导致隐藏的过度拟合。例如,即使模型没有在基准上训练或验证,建模决策的归纳偏差可能已经被导向基准改进。不幸的是,这种做法常常受到我们在大型比赛和学术文章中报告和奖励表现的方式的激励,这提出了一个重要的问题,即我们如何在使真实系统更加可靠的背景下重新思考这些做法。

其次,来自我们自己的应用程序的数据可能看起来与基准分布非常不同。基准人脸检测数据集可能不包括与您的应用程序将在其中操作的各种角度或光照条件相同的图像。此外,随着人们使用系统并使他们的行为适应系统,这些条件可能会随着时间而改变。

为了缓解这些问题,您可以:

  • 根据多个基准而不是一个基准来监控模型。这样,您可以检查模型改进和调整是否在不同的基准上通用。
  • 将基准划分为不同的用例集,并监控每个用例的性能,以便当泛化失败时,您可以将其映射回用例的类型。
  • 在评估中包括来自真实应用程序的数据。如果您担心没有足够的真实应用程序使用数据,那么好消息是,对于评估,您可能不需要培训所需的那么多数据。即使是少量的真实数据也可能暴露原本隐藏的错误。
  • 通过数据扩充(例如,视觉转换)、在合成对抗分布下进行测试,以及在评估过程中引入红队概念,以识别在已知基准中无法观察到的错误,来丰富您的评估数据。

还值得一提的是,任何类型的基准充实或评估都需要特别关注与隐私相关的问题,以便评估过程本身不会泄露用户敏感数据。

在检查人工智能的行为和性能时,包括以人为中心的评估指标。

为了更好地确保我们的人工智能以最终用户期望的方式行事,并与他们的价值观保持一致,我们需要在我们的评估中包括以人为中心的指标。最常用的评估指标之一是模型准确性。然而,准确性可能并不总是转化为用户满意度和成功的任务表现。对指标设计的调查表明,在机器翻译和图像字幕等领域,存在人们关心但当前指标无法代表的模型性能的隐藏维度。类似地,人们感知准确性的方式可能与计算的准确性大相径庭;这种差异取决于与存在的误差类型和向最终用户解释系统精度的方式相关的多种因素。

以人为中心的人工智能评估指标,与人类对质量的概念和期望更密切相关,正在不断出现。当在决策任务混合主动性系统中使用一个模型来帮助人类时,这样的指标尤其重要。可以考虑使用的一些指标包括:

  • 可解释性人类对模型如何决策的理解程度如何?
  • 公平性该模型在不同的人口统计群体上是否有可比较的表现?系统是否为这些小组分配了相当数量的资源?
  • 团队效用人类和机器合作表现如何?团队表现是否比任何一方单独表现更好?
  • 性能可说明性当系统出错时,人能提前预料到吗?(下一节将详细介绍)
  • 互补性——机器是简单地取代了人类,还是更专注于人类需要帮助的例子和任务?

这些度量标准的准确和正式的定义取决于领域,并且对于哪种定义最适合应用程序经常存在分歧。然而,这些讨论已经导致了一些开源贡献,以用于计算的库的形式,有时还优化了这种以人为中心的度量: InterpretMLFairLearnAI Explainability 360

请记住,在一天结束的时候,这些度量标准都不能代替实际人员的评估,例如用户研究。如果人工评估对于您的情况来说太耗费资源,那么至少可以考虑使用人工注释器来检查较小的数据分区,以了解您选择的代理度量与您的应用程序场景中的人工质量概念的一致性。

部署其性能更容易向人们解释的模型。

在模型优化和超参数搜索过程中,我们可能会有多个同样或类似精确的模型假设。在这些情况下,在决定部署哪个模型时,除了准确性之外,还要考虑性能的可解释性。性能可解释性使模型更加以人为中心,因为它使人们能够更好地理解和预测模型何时可能出错,以便人们可以在需要时接管。在最近的一项以人为中心的研究中,我们表明,当一个人与一个 ML 模型合作进行决策时,团队绩效会受到人们理解和预测模型错误界限的程度的显著影响(即,模型在哪里出错,在哪里成功)。

要确定一个具有更好的性能解释能力的模型,请考虑以下因素:

  • 选择具有高度简约性的模型(即,当系统出错时,你需要多少信息块来描述,错误解释有多复杂?)和低随机性(即,在多大程度上可以通过错误解释干净地将错误与成功实例分开?).
  • 为了测量感知的简约性和随机性,尝试通过训练简单的可解释的基于规则的分类器,如决策树或基于先前交互的规则列表,来逼近关于错误边界的人类心理模型(即,人类对错误边界的了解)。学习到的心智模型当然只是近似或模拟,但是如果它们足够简单,我们可以确保它们不会添加任何关于人们如何学习的误导性假设。

在未来,我们希望看到更多的工作来实现更好的模型选择,通过增加损失函数或通过约束最小化,作为模型优化和训练的一部分,目标是训练模型,使人类能够发展明智和合理的信任。

在调整模型参数时,考虑错误的成本和风险。

尽管一个给定的系统可能会犯许多类型的错误,但它们发生的可能性并不相同,而且它们还可能与不同的应用程序相关成本相关联。例如,在许多医学应用中,假阴性错误的成本可能比假阳性高得多,特别是如果在疾病存在时不治疗的后果比相应的副作用更危及患者的生命。正如你可能已经猜到的,明确地估计这样的成本和风险对于高风险的决策是特别必要的。风险评估的良好实践是在部署应用程序之前进行用户研究或试点研究,以预测潜在错误的影响。

成本估计可用于通知模型参数的调整。然而,目前大多数模型被训练得更一般,并且不针对与领域相关联的成本进行定制,主要是因为这些成本对于开发者来说通常是未知的,并且它们可能从一个消费者到另一个消费者而变化。因此,大多数模型都是在简单的 0/1 损失的标准近似值上训练的,希望它们能用于一般应用。意识到这样的成本估计困难,仍然有必要注意到,至少对于整个领域共享相似且已知的非均匀错误成本的情况,像成本敏感学习重要性采样这样的技术可以帮助捕捉不同示例的敏感性。例如,如果假阴性比假阳性代价更高,那么可以在优化过程中给这些情况分配更多的损失。其他技术包括过度(或不足)表示特定类别的实例,或者对接近决策边界的实例进行不同的加权。

当不同消费者的成本不同时,从长期来看,模型部署、编排和维护会带来额外的复杂性。然而,随着云部署服务的不断进步(例如,AzureML 上的MLOps),这项任务已经变得更加触手可及。这些服务通常倾向于将不同的模型版本容器化,并提供给不同端点的客户。

校准并解释不确定性。

到目前为止,我们介绍的技术更适合在全局级别或一组实例上描述和测量系统性能。然而,由于模型性能可以从一个实例到另一个实例而变化,在交互期间在单个实例上表达模型性能也可以帮助为最终用户设置适当的期望(例如,在单个实例上传达模型不确定性)。模型校准旨在将机器学习预测与仔细校准的置信度分数相关联,置信度分数反映了误差的概率分布。这将意味着,如果一个模型以 95%的置信度识别图像中的交通灯,如果您将模型预测准确性视为一个随机变量,则失败的可能性确实是 5%(在大量样本中)。

今天,许多开箱即用的机器学习算法都没有将校准的不确定性作为默认属性。一些例子包括朴素贝叶斯模型、支持向量机甚至神经网络。可用于不确定度校准的一些方法包括:

  • 后处理技术(如普拉特缩放保序回归),这些技术不会改变模型的训练方式,但会对模型不确定性预测进行后处理,以便输出概率最好地反映误差。幸运的是,这些技术在 scikit-learn 等流行的 ML 库中很容易得到。如果你在问自己这些技术如何应用于深度学习,这个调查提供了一个全面的总结。
  • 内置技术(如自举不确定性估计的放弃),通常适用于特定的模型类别,但也可用于更广泛的环境。例如,概念,如辍学正则化,自举和系综显示,以改善不确定性估计。虽然这些方法中的一些确实有更多的计算要求(例如,深度网络的集合),但考虑它们仍然是一个好主意,特别是对于高风险领域。
  • 当难以进行精细的不确定性估计时,如果数据稀疏,“粗略”和粗粒度校准可能比根本没有校准要好。毕竟,人们不会对 75%或 76%的信心有太大的区别。但是,如果信心从 75%变为 90%,他们的决定可能会发生巨大变化。通过将原始模型输出分数映射到更大的置信度桶,粗粒度校准可以与事后技术集成。区分这些情况仍将有助于在不确定时以不同的方式表达答案,例如,“我还不知道如何回答这个问题。我不确定,但我想答案可能是…

尽管模型置信度\不确定性是表达预期性能的一种简洁明了的方式,但重要的是要意识到实践中可能出现的两个主要挑战:

  1. 不确定性解释——生产中使用的不确定性分数可能并不总是容易解释,尤其是对于具有高维度和丰富输出的系统。以向视觉受损的用户提供场景描述的图像字幕系统为例。该系统已经向用户提供了下面的标题“一群人围坐在桌子旁吃晚餐”,并且 80%有把握。用户应该如何理解这种信心?这是否意味着场景中根本没有人?还是说他们不是在吃饭而是在干别的?在这种情况下,向用户详细说明输出分数的语义实际上是至关重要的。虽然总结更丰富产出的不确定性仍然不是一个很好理解的问题,但一个可能的替代方法是突出特定产出块的高度不确定性(如果可用),以将注意力引导到正确的方向。
  2. 训练数据与真实世界分布的对比——即使使用上述技术,重要的是要意识到,与其他学习问题一样,置信度分数只会与训练数据一样好。当真实世界的数据和模型在训练期间实际看到的数据之间存在较大差距时,尽管我们尽了最大努力进行校准,但置信度得分可能仍然与准确性不一致。为此,ML 社区正在朝着以下重要方向努力:检测不符合分布的示例(T0)或在数据集偏移下校准(T2)的示例(T1)和(T3),在人类参与的情况下识别未知的未知(T4)的示例(T5),以及恶意数据偏移的对抗性鲁棒性(T6)但这无疑仍是学习中最具挑战性的问题之一。

其他考虑

这篇文章提出了几个策略来更好地理解你的人工智能的性能和能力。但是在你的应用程序中部署 AI 之前,你还应该考虑如何最好地向你的目标用户呈现关于性能和功能的信息,这些用户很可能对 AI 知之甚少。例如,生产中使用的不确定性分数可能不总是容易被最终用户解释,尤其是对于具有高维度和丰富输出的系统。

在试图设定对人工智能系统的正确期望时,本帖中建议的大多数方法都侧重于基于解释的技术,这些技术由对人工智能的能力和局限性的更好理解来支持。然而,任何类型的文档都有一些重要的缺点。也就是说,大多数人不阅读文档!在高风险的场景中,人们可能会被要求或激励这样做,但这表明社区有机会在探索替代方法以设定人工智能系统的期望方面发挥创造力。例如,最近的工作已经研究了将模型参数直接暴露给最终用户,以允许他们试验人工智能的不同性能。这不仅可以让他们更好地了解人工智能在常规使用中的表现,还可以让人们在确定他们可能会受到人工智能的影响时有一种代理感。

最后,当人工智能随着时间的推移学习和改变时,弄清楚一个系统能做什么以及它能做得多好变得越来越具有挑战性。随着时间的推移,当人们与系统交互时,他们的期望可能会改变,甚至他们想要解决的任务的定义也可能会改变。这种动态很难用静态代理度量来跟踪,我们将在以后的文章中重点讨论如何处理随时间变化的挑战。

摘要

这篇文章介绍了机器学习和工程实践者可以用来设置正确的用户期望的实践,这些期望是关于人工智能系统可以做什么以及做得如何。因为很难区分虚构的宣传和实际的功能,所以负责任的做法是尽可能多地解释产品的预期质量。虽然对于数据密集型学习系统来说,这可能仍然很困难,但如上所述的机器学习和工程实践,以及未来可能出现的其他实践,可以帮助我们传递正确的信息,并建立合理的信任。

你有你自己的实践想与社区分享吗?欢迎在下面发表评论或给我们写信,地址是 aiguidelines@microsoft.com。

作者

贝斯米拉·努什萨勒玛·阿默什埃克斯·卡玛加甘·班萨尔丹·维尔德米哈拉·沃莱亚努埃里克·霍维茨

如何使用 TensorFlow 2.0 构建高效的音频数据管道

原文:https://towardsdatascience.com/how-to-build-efficient-audio-data-pipelines-with-tensorflow-2-0-b3133474c3c1?source=collection_archive---------12-----------------------

使用 TensorFlow 的数据集 API 消除培训工作流程中的瓶颈

罗迪翁·库察耶夫Unsplash 上拍摄的照片

GPU 可以大大加快你的训练时间。为了获得最佳性能,您需要为他们的每个训练步骤提供足够的数据。否则,事情会变得真的缓慢。💤

作为一名研究人员,看着一个几乎没有移动的进度条,看着你的 GPU 闲置,肯定是你最沮丧的经历之一。

至少对我来说是这样。

尤其是在你研究的早期阶段,关键是你能尝试新的想法并快速测试你的假设,以朝着正确的方向前进。当你脑子里满是想法时,没有什么比等待几个小时才有结果更糟糕的了。

面临的挑战是在当前步骤完成之前,及时将数据从硬盘传输到 GPU,以便进行下一步培训。这包括从磁盘加载和解码原始字节,预处理并可能增加数据,以及准备批处理。

这正是你的数据管道的工作。

这篇文章将带领你使用tf.data API 为音频数据构建一个高效的数据管道。

tf.data API 使得处理大量数据、读取不同的数据格式以及执行复杂的转换成为可能。— 张量流导

我找到了关于如何为分散在网络上的音频数据建立有效的数据管道的指导和提示。我将这些编译到这篇文章和代码示例中,供您开始构建自己的代码。

我会在这篇文章的最后链接到相关的资源。

首先,你真的需要一个数据管道吗?

看情况。

只要数据集足够小,能够放入内存,就可以在开始训练之前简单地加载一次,然后反复迭代。在我们开始处理更大的数据集之前,这是我们大多数人一直采用的标准方法。

当你无法再将所有数据放入内存时,你就需要按需加载数据,让你的 GPU 保持忙碌。但是,您仍然希望能够像以前一样对数据进行洗牌、批处理和预处理。

数据管道可以帮助你实现这一点。

如何用三个简单的步骤建立你的第一个数据管道

官方 TensorFlow 教程关于加载和预处理数据包含了很多有用的信息和例子。不幸的是,没有一个例子是关于音频数据的。

不过,一个好的起点是关于加载图像的部分。

基于本教程,您可以通过三个简单的步骤使用tf.data API 构建您的第一个数据管道:

  1. 创建一个由file_pathslabels组成的数据集
  2. 编写一个解析函数,从文件路径中加载并解码 WAV 文件
  3. 使用Dataset.map()创建一个[audio, label]对的数据集

把这些碎片放在一起,你可能会得到这样的结果:

使用 TensorFlow 数据集 API 的首个数据管道

很简单。

但这只是故事的一半。

不幸的是,对于任何合理大小的数据集,如果您遵循上面的方法,您的性能将会受到很大的影响。您的 GPU 和 CPU 将几乎闲置,但磁盘 I/O 达到最大。你的硬盘已经成为瓶颈。

让我解释一下。

你可能有一个强大的 GPU 和多核 CPU,但只有一个物理硬盘,只有一个磁头来读取数据。第 26 行的.map()调用在可用的 CPU 核上并行运行load_audio解析函数。

现在,有许多进程试图从磁盘上的随机位置读取数据,但仍然只有一个磁头进行读取。有了这些跳跃,这不会比一个单个读取过程快多少。

所以,如果你阅读成千上万的小文件,比如几秒钟长的 WAV 文件,寻找正确的位置和打开每个文件的开销将成为瓶颈。

但是不要担心,有一个解决办法。

使用 TFRecords 显著加快您的数据管道

TFRecords 可以存储二进制记录的序列。这意味着您可以将许多 WAV 文件放入一个 TFRecord 中,并增加每次磁盘读取的数据吞吐量。

理论上,你可以在一个单独的 TFRecord 文件中存储所有的 WAV 文件。TensorFlow 文档建议将数据分成多个 TFRecord 碎片,每个碎片的大小在 100 MB 到 200 MB 之间。实际上,为了利用并行化,拥有至少与 CPU 内核一样多的 TFRecord 碎片也是有意义的。

在一个 TFRecord 分片中有数百个 WAV 文件,您可以减少磁盘 I/O,因为您只需要打开一个文件来读取和访问许多音频文件。您增加了每次磁盘读取的数据吞吐量,并消除了磁盘 I/O 瓶颈。

这个概念实际上非常类似于在 web 和游戏开发中使用 sprite-sheets,将一堆小图像(sprite)组合成一个大图像(sheet),以提高性能和启动时间,并减少整体内存使用。

但是有一个问题。

转换成 TFRecord 格式(并读取它)需要相当多的样板文件。要转换,您需要:

  1. 打开一个 TFRecords 文件:out = tf.io.TFRecordWriter(path)
  2. 将数据转换为三种数据类型之一:tf.train.BytesListtf.train.Int64Listtf.train.FloatList
  3. 通过将转换后的数据传递给tf.train.Feature来创建一个feature
  4. 通过将feature传递给tf.train.Example来创建一个example协议缓冲区
  5. 序列化example并写入 TFRecords 文件:out.write(example.SerializeToString())

如果这还不够混乱的话,看看它在代码中的样子:

要转换为 TFRecord 格式的样板文件

这里有一个小脚本来展示如何将 WAV 文件转换成 TFRecord 碎片:

将 WAV 文件转换为 TFRecord 格式

在开始复制和粘贴上面的代码之前,有必要考虑一下 TensorFlow 文档中的这句话:

没有必要转换现有代码来使用 TFRecords,除非你正在使用*tf.data*并且读取数据仍然是训练的瓶颈。

如果您确实发现读取数据是您的瓶颈,您可能想要查看上面脚本的这个更精细的版本。它与可用的 CPU 内核并行编写 TFRecord 碎片,并估计每个碎片应该包含的文件数量保持在 100 MB 到 200 MB 之间。

最后,每个碎片中文件的数量很重要。它需要足够大,以消除磁盘 I/O 瓶颈。在我找到压缩 TFRecords 的选项之前,每个碎片只能容纳大约 100 个 WAV 文件。我最终得到了几千个碎片,这意味着对太少的数据进行了太多的读取。

使用tf.data.TFRecordDataset加载数据集

一旦你把 WAV 文件转换成 TFRecords,你需要对你的数据管道做一些调整:

  1. 列出所有 TFRecord 文件tf.data.Dataset.list_files('*.tfrecord')
  2. 将 TFRecord 文件读取为tf.data.TFRecordDataset
  3. 解析和解码每个序列化的tf.train.Example

因为每个示例都存储为二进制协议缓冲区,所以您需要提供一个解析函数,将这些消息转换回张量值。

以下是这种情况的一个示例:

使用 TFRecords 的数据管道

享受高效的数据管道

就这样。这就是你如何为音频数据建立一个有效的数据管道。

我们从一个简单的数据管道开始,它基于 TensorFlow 指南中的一个介绍性示例。我们发现了磁盘 I/O 瓶颈。我们把 WAV 文件转换成 TFRecords 来消除它。最后,我们更新了数据管道来读取 TFRecords 并从中加载音频数据。

如果你想更深入一点,我会给你一些启发和帮助创建这篇文章的资源链接。你可以在下面找到它们。

但首先,我想听听你的意见。你采取的是相似还是完全不同的方法?你有什么见解想与我和其他读者分享吗?请把它们贴在评论里。

记住,一个系统的速度取决于它最慢的组件。

如果你想更深入一点

如何使用 Streamlit 在 Python 中构建交互式仪表盘

原文:https://towardsdatascience.com/how-to-build-interactive-dashboards-in-python-using-streamlit-1198d4f7061b?source=collection_archive---------23-----------------------

借助交互式仪表盘提升您的数据科学项目

如果你正在做一个可视化项目,想要展示你的发现,或者如果你正在寻找工作,想要创建一些项目组合——交互式仪表盘是以一种容易理解的方式提供信息的好方法。

细流

今天,我们将在交互式仪表盘中使用 Python 和 Streamlit。

Streamlit 是一个开源应用程序框架,它通过一个漂亮的仪表板来探索和理解数据,使数据科学家的生活变得简单。

设置简化 it

让我们首先将 Streamlit 安装到我们的系统中,然后运行 hello 命令来验证一切正常。我们可以在终端中通过 Ctrl+c 随时杀死正在运行的 app。

$ pip install streamlit 
$ streamlit hello

导入库

安装 Streamlit 后,让我们导入我们将使用的所有库。

import streamlit as st 
import pandas as pd 
import numpy as np 
import pydeck as pdk 
import altair as alt 
from datetime import datetime

以不同的方式显示文本

Streamlit 使我们能够轻松清理、共享和可视化数据。我们可以用不同的方式写文章来解释我们的发现,比如给图表加标题,给出标题或副标题,或者我们可以解释图表或数据的细节。

标题:设置 app 的标题,可以使用 st.title()

标题:我们可以使用 st.header()作为标题,st.subheader()作为副标题

Text :为了编写特定图形或数据的描述,我们可以使用 st.text()。 Streamlit 也支持 markdown,所以如果我们想将文本显示为 markdown,我们可以使用 st.markdown()

Latex: Streamlit 还显示 Latex 格式的数学表达式。通过使用 st.latex()

:我们可以显示任何东西,如图形、数据框、函数、错误、模型等。通过使用 st.write()

取数据

现在我们已经安装了应用程序并导入了所有的库,下一步就是加载数据。这里我们将使用 Covid19 数据。

从 Github 获取这个数据集。

数据缓存

Streamlit 提供了一种缓存机制,使我们的应用程序即使在从 web 加载数据或处理大型数据集时也能保持高性能。

简化小部件

小工具可以帮助我们过滤数据,或者通过按钮、滑块、选择框等直接将数据可视化到应用程序中。让我们来看几个例子。

多选

我们可以从列列表中选择或删除行。在这里,我们创建国家名称小部件,我们可以选择国家/地区,以便只显示那些选定值的数据/图表。

选择框

图表和地图

Streamlit 支持许多流行的可视化库,如 Matplotlib、Altair、deck.gl 等等。这里是显示图表的更多细节。

条形图

牛郎星图表

动画地图

所有的代码

这个任务的所有代码都可以在这里找到:代码。

这是一个总结

这个帖子到此为止。在下一篇文章中,我们将讨论如何实时生产这些仪表板,以便其他人也可以访问您的仪表板。希望对你有帮助。

原载于 2020 年 6 月 11 日 https://confusedcoders.com

如何用 Python 从头开始构建 KNN

原文:https://towardsdatascience.com/how-to-build-knn-from-scratch-in-python-5e22b8920bd2?source=collection_archive---------2-----------------------

…嗯,至少没有 sklearn 的 KNeighborsClassifier。

Unsplash 上由 Breno Assis 拍照

k-最近邻

k-最近邻(KNN)是一种受监督的机器学习算法,可用于回归或分类任务。KNN 是非参数的,这意味着该算法不对数据的基本分布做出假设。这与线性回归等技术形成对比,线性回归是参数化的,需要我们找到一个描述因变量和自变量之间关系的函数。

KNN 的优点是非常直观易懂。当用于分类时,查询点(或测试点)基于最接近该查询点的 k 标记的训练点被分类。

有关简化的示例,请参见下图。左侧面板显示了一个包含 16 个数据点的二维图,其中 8 个数据点标为绿色,8 个数据点标为紫色。现在,右边的面板显示了当 k =3 时,我们如何使用 KNN 对一个新点(黑色十字)进行分类。我们找到三个最接近的点,并计算出在这三个点内每种颜色有多少张“选票”。在这种情况下,三个点中的两个是紫色的,因此,黑色十字将被标记为紫色。

当 k=3 时使用 KNN 的二维分类

计算距离

通过使用闵可夫斯基距离方程的几个版本之一来确定点之间的距离。闵可夫斯基距离的通用公式可表示如下:

其中 XY 为数据点, n 为维数, p 为闵可夫斯基幂参数。当 p =1 时,距离已知为曼哈顿(或出租车)距离,当 p =2 时,距离已知为欧几里德距离。在二维空间中,两点之间的曼哈顿距离和欧几里德距离很容易可视化(见下图),但是在更高阶的 p 处,闵可夫斯基距离变得更加抽象。

二维中的曼哈顿距离和欧几里德距离

蟒蛇皮 KNN

为了用 Python 实现我自己版本的 KNN 分类器,我首先想导入几个公共库来帮忙。

加载数据

为了测试 KNN 分类器,我将使用 sklearn.datasets 中的鸢尾数据集。该数据集包含 150 种鸢尾植物的测量值(萼片长度、萼片宽度、花瓣长度、花瓣宽度),平均分为三个物种(0 = setosa,1 = versicolor,2 = virginica)。下面,我加载数据并将其存储在一个数据帧中。

我还会将数据分为要素(X)和目标变量(y),后者是每种植物的物种标签。

建立 KNN 框架

创建一个有效的 KNN 分类器可以分为几个步骤。虽然《KNN》包含了更多的细微差别,但我还是列出了最基本的任务清单:

  1. 定义一个函数来计算两点之间的距离
  2. 使用距离函数获得测试点和所有已知数据点之间的距离
  3. 对距离测量值进行排序,以找到离测试点最近的点(即,找到最近的邻居)
  4. 使用那些最接近点的多数类标签来预测测试点的标签
  5. 重复步骤 1 到 4,直到所有测试数据点都被分类

1.定义一个函数来计算两点之间的距离

首先,我定义了一个名为 minkowski_distance 的函数,它接受两个数据点( a & b )和一个 minkowski 幂参数 p,的输入,并返回两点之间的距离。请注意,这个函数计算距离的方式与我之前提到的 Minkowski 公式完全一样。通过使 p 成为一个可调参数,我可以决定是要计算曼哈顿距离(p=1)、欧几里德距离(p=2)还是闵可夫斯基距离的更高阶。

0.6999999999999993

2.使用距离函数获得测试点和所有已知数据点之间的距离

对于第 2 步,我简单地重复 X 中所有标记点的 minkowski_distance 计算,并将它们存储在数据帧中。

3。对距离测量值进行排序,以找到最接近测试点的点

在第三步,我使用熊猫。sort_values() 方法按距离排序,只返回前 5 个结果。

4.使用那些最接近点的多数类标签来预测测试点的标签

对于这一步,我使用集合。计数器跟踪与最近邻点重合的标签。然后我使用。most_common() 方法返回最常出现的标签。注意:如果“最常见”标签的标题在两个或多个标签之间有关联,那么返回的将是 Counter() 对象首先遇到的那个标签。

1

5.重复步骤 1 到 4,直到所有测试数据点都被分类

在这一步中,我将已经编写的代码投入使用,并编写一个使用 KNN 对数据进行分类的函数。首先,我对数据执行train _ test _ split(75%训练,25%测试),然后使用 StandardScaler() 缩放数据。由于 KNN 是基于距离的,因此在将要素输入算法之前,确保对其进行适当的缩放非常重要。

此外,为了避免数据泄露,在执行完 train_test_split 之后,缩放特征是一个好的做法。首先,只缩放来自训练集的数据(scaler . fit _ transform(X _ train)),然后使用该信息缩放测试集(scaler . transform(X _ test))。这样,我可以确保不使用训练数据之外的信息来创建模型。**

接下来,我定义一个名为 knn_predict 的函数,它接受所有的训练和测试数据、 kp ,并返回我的 knn 分类器对测试集做出的预测( y_hat_test )。这个函数实际上并没有包含任何新的东西——它只是简单地应用了我在上面已经研究过的东西。该函数应该返回一个只包含 0、1 和 2 的标签预测列表。

*[0, 1, 1, 0, 2, 1, 2, 0, 0, 2, 1, 0, 2, 1, 1, 0, 1, 1, 0, 0, 1, 1, 2, 0, 2, 1, 0, 0, 1, 2, 1, 2, 1, 2, 2, 0, 1, 0]*

他们在那里!这些是这个自制的 KNN 分类器在测试集上做出的预测。让我们看看效果如何:

*0.9736842105263158*

看起来分类器在测试集上达到了 97%的准确率。一点也不差!但是我怎么知道它实际上是否工作正常呢?让我们检查 sklearn 的 KNeighborsClassifier 在相同数据上的结果:

*Sklearn KNN Accuracy: 0.9736842105263158*

不错!sklearn 的 KNN 分类器的实现给了我们完全相同的准确度分数。

探索不同 k 值的影响

我的 KNN 分类器在选择值为 k = 5 的情况下表现相当好。KNN 没有像决策树或随机森林等其他算法那样多的可调参数,但 k 恰好是其中之一。让我们看看当我改变 k 时,分类精度是如何变化的:

在这种情况下,使用几乎任何小于 20 的 k 值都会在测试集上产生很高的(> 95%)分类精度。然而,当 k 变得大于大约 60 时,精确度确实开始下降。这是有意义的,因为数据集只有 150 个观察值——当 k 那么高时,分类器可能会考虑离测试点太远的标记训练数据点。

每个邻居都有投票权——或者他们有吗?

在编写我自己的 KNN 分类器时,我选择忽略一个明显的超参数调整机会:每个最近的点在分类一个点时的权重。在 sklearn 的 KNeighborsClassifier 中,这是权重参数,可以设置为‘均匀’‘距离’,或者其他自定义函数。

当设置为‘uniform’时,k 个最近邻点中的每一个在标记新点时获得相同的投票。当设置为‘distance’时,距离新点最近的邻居的权重大于距离较远的邻居。当然,在某些情况下,通过“距离”进行加权会产生更好的结果,而找出答案的唯一方法就是通过超参数调整。

最后的想法

毫无疑问,sklearn 的实现无疑比我在这里拼凑的更加高效和用户友好。然而,我发现从头开始研究 KNN 是一个很有价值的练习,它只是巩固了我对算法的理解。我希望它对你也一样!

如何建立我们都可以信任的机器学习算法?

原文:https://towardsdatascience.com/how-to-build-machine-learning-algorithms-that-we-can-all-trust-cb00f1c055e1?source=collection_archive---------30-----------------------

内部人工智能

在几分钟内解释任何机器学习模型-充满信心和信任。

当哈姆雷特在莎士比亚著名的悲剧中说出这句话时,“生存还是毁灭”成了哲学领域中思想和自我反省的口头禅。在今天的商业世界中,在人工智能所做决策的驱动下,这句口头禅已经变成了“要么信任,要么不信任”。

https://imgs.xkcd.com/comics/machine_learning.png(消息来源 1)

随着最近人工智能的崩溃成为新闻,人工智能模型中缺乏透明度和越来越多的偏见的问题已经暴露出来。在最近的例子中,人工智能系统声称高度污染的空气可以安全呼吸,而在现实中,这是非常危险的;或者人工智能系统声称某个病人没有癌症,但事实上该病人确实患有癌症并已死亡;或者人工智能系统将某项交易识别为欺诈,而这是一项完全合法的交易,给客户带来了不必要的麻烦,这显然是有问题的。随着人工智能的广泛使用,这些崩溃每天都在增加,这是由我们盲目信任这些人工智能系统造成的,但现在是采取行动的时候了!

https://imgflip.com/i/2yc1nf

当谈到实施和信任这些人工智能系统时,当前的商业前景仍然非常怀疑。许多公司已经启动了这一过程,但尚未意识到其价值。这主要是由于数据科学团队和业务利益相关者之间的理解差距。在过去的几个月里,我们与许多商业利益相关者进行了交谈,他们是这些预测的接受者,我们发现数据科学家无法解释人工智能系统预测背后的原因和方式,这是对数据科学计划不信任和怀疑的最大因素。数据科学团队中的人技术含量很高,他们擅长用复杂性来表示他们的技能范围。然而,业务涉众有时是完全相反的:他们不关心使用的技术,而是模型生成的结果如何与他们的业务目标和 KPI 联系起来。

除非数据科学家能够回答这些基本问题,否则这是不可能实现的:

1.我为什么要相信模型生成的结果?

2.模型产生结果的基本原理是什么?

3.在生产中使用该模型的好处和坏处是什么?

4.结果是否符合业务逻辑?

只有回答了这些问题,数据科学家才能向业务用户提出建议,并期望取得一些进展。

为了解决这个问题,数据科学家有两个选择:

1.通过在黑盒模型之上构建一个可解释的模型来解释黑盒模型。这是莱姆 SHAP 公司背后的逻辑。SHAP 得到了更广泛的应用,因为它保证了每个变量的公平分配,并有大量的图表。遗憾的是,这种方法需要大量迭代,缺乏交互性,并且不可扩展,尤其是在处理敏感数据集和决策时。更重要的是,可视化没有吸引力和互动性。它们的静态性质在数据科学家和业务利益相关者之间造成了更大的分歧。缺乏动态和互动的图表使得从 SHAP 或莱姆产生价值变得极其困难,因此需要一种更好的方法来使用这些技术。

2.使用可解释的模型:数据科学家可以尝试优化逻辑回归或决策树等更简单的模型来进行预测,而不是使用深度神经网络等黑盒模型。在准确性和可解释性之间会有一个权衡,但是数据科学家需要决定什么是产生价值的重要因素,并且需要关注两种模型之间的边际收益。如果精确度之间的边际增加不显著,那么更理想的是实现更简单的模型,并将预测直接与业务 KPI 联系起来。可悲的是,随着我们今天收集的数据越来越复杂,简单的模型表现不佳。

所以问题来了:在我们的机器学习模型中,有没有更好的建立信任的方法?

mltrons 的 xAI 实验室正在研究一个 xAI 模块,旨在通过交互创新为 ML/DL 黑盒模型带来可解释性和透明性。目的是理解为什么决策是由人工智能系统做出的,并确保人工智能预测是公正的,准确的,没有任何逻辑矛盾。

该模块充当即插即用系统,适合任何 Jupyter 笔记本电脑——凭借自动化可视化和高度交互性,数据科学家将能够与业务利益相关者坐在一起,建立对人工智能系统的信任,并做出完全知情的决策。

图 1.1—m trons 模块示例工作流程。

这意味着数据科学家现在可以将他们的 Jupiter 笔记本、数据源(亚马逊、MySQL、HDFS 和使用 XGBoost、CatBoost、PyTorch、Tensorflow、SageMaker 的定制模型)引入 m trons 引擎,mltrons xAI 模块将接收输入,并将作为一个附加层,提供关于这些算法如何工作、思考和输出结果的可解释性。然后,数据科学家将能够通过交互式可视化、报告和可共享的仪表板,用简单的业务友好语言解释结果,任何人都可以很好地理解。

如果您对该技术有任何疑问,请通过以下表格联系我们:

https://raheelahmad453253.typeform.com/to/qa8QRB

关于作者: Raheel Ahmad 是 NYU·坦登可视化成像和数据分析(VIDA)中心的客座研究员,专注于 ML 模型的可解释性。他也是 mltrons 的联合创始人。

如何从零开始构建神经网络

原文:https://towardsdatascience.com/how-to-build-neural-network-from-scratch-d202b13d52c1?source=collection_archive---------35-----------------------

安妮·斯普拉特的照片

如何从头开始建立一个简单的神经网络的分步教程

介绍

在这篇文章中,我们将用一个隐藏层和一个 sigmoid 激活函数从头开始构建我们自己的神经网络。我们将仔细研究导数和链式法则,以便对反向传播的实现有一个清晰的了解。我们的网络将能够以与 Keras 模拟相同的精度解决线性回归任务。

你可以在这个 GitHub 库中找到这个项目的代码。

什么是神经网络?

我们曾经将神经网络视为神经元的互连层,左侧是输入层,中间是隐藏层,右侧是输出层。视觉上更容易消化,但最终,神经网络只是一个将其他函数作为输入的大函数;并且取决于网络的深度,这些内部函数也可以将其他函数作为输入,等等。那些内部功能实际上是“层”。让我们看一下我们将要构建的网络图:

神经网络体系结构

它有一个具有两个特征的输入层,一个具有三个神经元的隐藏层和一个输出层。隐藏层中的每个神经元是一个 sigmoid 激活函数,它将输入值(x1,x2)、权重(w1,…,w6)和偏差(b1,b2,b3)作为输入,并产生范围从 0 到 1 的值作为输出。

开始时,我们给权重和偏差分配从 0 到 1 的随机值。

隐藏层中的第一个神经元

输出层仅包含一个神经元,其工作与隐藏层的神经元相似。你可能已经猜到 ŷ 实际上是我之前提到的那个大函数。

我们上面描述的网络类型被称为 Dence Network ,因为神经元与来自前一层的元素完全连接,在我们的情况下是输入

我们如何训练一个神经网络?

需要理解的最关键部分是,神经网络仅通过调整权重和偏差来训练以最小化输出误差。训练过程由前馈反向传播组成。前馈预测输出,反向传播调整权重和偏差以最小化输出误差,即预测值和真实值之间的差异。

前馈

当我们想预测产量时,我们使用前馈函数。该函数采用输入 x1 和 x2,这些输入值与权重和偏差一起进入隐藏层中的神经元,每个神经元返回值[0–1];然后输出层获取这些值并产生输出。

让我们仔细看看隐藏层中的第一个神经元,了解它实际上在做什么。

前馈过程

正如我前面提到的,每个神经元只是一个 sigmoid 函数:

类似于线性回归,我们有斜率和截距等参数来进行预测,在神经网络中,我们有权重和偏差。

隐藏层中的第一个神经元

每个神经元将产生一个值[0-1],我们将用它作为输出层的输入。在一些神经网络中,没有必要将输出层作为 sigmoid 或任何其他激活函数,它可以只是来自前一层的值的总和。

输出层中的神经元

该函数的代码如下所示:

def sigmoid(x): return 1 / (1 + np.e**-x)def feedforward(x1, x2): n1 = sigmoid(x1 * w1 + x2 * w2 + b1)
    n2 = sigmoid(x1 * w3 + x2 * w4 + b2)
    n3 = sigmoid(x1 * w5 + x2 * w6 + b3)
    y_hat = sigmoid(n1 * w7 + n2 * w8 + n3 * w9 + b4) return y_hat

预测完值后,我们可以使用均方差(MSE)将其与真实值进行比较。

为什么使用偏见?

偏置的作用是为神经元提供一个不受前几层影响的额外参数,因为它与前几层没有任何联系。

反向传播

起初,我们的网络在预测方面做得很糟糕,因为权重和偏差只是随机数。现在反向传播开始帮助我们训练这些参数。

每次网络做出预测时,我们用 MSE 来与真实值进行比较,然后我们回过头来调整每个权重和偏差,以稍微减少误差。

均方误差(mean square error)

为了理解反向传播,我们应该知道几个要素:

  1. 导数——改变每个权重和偏差的方向
  2. 链式法则——如何获取每个重量
  3. 梯度下降——调整权重和偏差的迭代过程

派生物

感谢导数,我们总是知道我们在哪个方向改变每个参数(使它稍微变大或变小)。假设我们想要调整一个权重 (w = 0.75) ,以便使 MSE 稍微小一点。为了做到这一点,我们应该对这个重量取一个函数的偏导数。然后我们把数字代入导出函数,得到一个数字( 0.05 ),正数或者负数。然后我们从我们的重量中减去这个数字( w -= 0.05 )。调整就是这么做的。这应该发生在网络中的每个权重上。

因为网络最终是非常复杂的函数,很难找到隐藏在无数其他函数中的参数的导数。幸运的是,衍生品有一个链式法则,它简化了我们的这一过程。

链式法则

如果我们需要找到一个函数包含另一个函数的导数,我们使用链式法则。

这条规则说,我们对外部函数求导,保持内部函数不变,然后我们用内部函数的导数乘以所有的东西。

梯度下降

一旦我们知道了所有的导数,我们就可以在每次反向传播时逐渐调整每个权重和偏差。这里需要知道的重要一点是,梯度下降有一个学习率参数,它通常是一个很小的数字,我们将其添加到导数的结果中,以减慢或加快训练。

训练重量 1 的示例

让我们来练习一下如何对 w1 求偏导数。一旦我们理解了它对一种重量的工作原理,对其他重量的实现就很容易了,因为在大多数情况下,这几乎是完全相同的过程。

反向传播

现在,对 w1 求偏导数,我们应该从 MSE 函数开始。它是包含网络中所有其他函数的根函数。

举重训练

众所周知,MSE 是真实值和预测值的平方差 (y-ŷ) 。如果我们展开整个网络,看看 w1 在里面的位置,它看起来像这样:

神经网络的 Matryoshka

我们现在应该记住,网络是一个包含其他函数的函数,为了调整该函数中的每个参数,我们需要使用链式法则:

链式规则表示

剩下的就是对每个函数求导。对于 w1 它有四个导数,但是对于 w8 它只有三个,因为它位于 ŷ 并且我们不需要去那么深的地方。

关于 x1 的导数

最后,我们得到了这个看起来可怕的方程,它解释了 w1 如何影响 MSE。让我们详细说明每一步发生了什么。

首先,我们对 MSE (y-ŷ)求导,也就是 2(y-ŷ,因为 x 的导数是 2x,同样的规则也适用于这里。我们没有像链式法则要求的那样,接触平方函数内部的内容。

然后我们对(y-ŷ)对ŷ求偏导数,得到(0-sigmoid'(…))。记住ŷ是一个 sigmoid 函数。因为它是通向重量 w1 的主要路径。接下来,我们取另一个 sigmoid 函数关于 n1 的偏导数,最后是 x1*w1 的最后一个导数,也就是 x1 ,因为 w1 的导数是 1,系数 x1 保持不变。然后我们乘以每个导数,我们就可以开始了。

综上所述,我们得到:

权重 1 的反向传播

其中学习率是一个小数字,通常范围从 0.01 到 0.05,但也可以更大。同样的逻辑,我们适用于寻找所有其他的重量和偏见。

你可以想象,如果我们有数百个神经元,我们将有数千个权重和偏差,因此为了说明的目的,我们将神经元的数量保持得非常少。其余代码请看 GitHub

在真实数据上测试网络

我们的网络在根据两个参数预测房价方面做得非常好:收入中位数和平均房间数。数据取自 sklearn 图书馆的“california_housing”数据集。该网络收敛相当快,仅超过 6 个历元,结果 MSE = 0.028,与我从 Keras analog 得到的结果完全相同。

学习过程

结论

我们的网络非常适合教育目的,但它有局限性:我们不能改变隐藏层中神经元的数量,也不能向网络中添加另一层。我们只有一个激活函数,我们的网络只能解决简单的任务,如线性回归。如果我们想用它来解决分类问题,我们需要找到交叉熵或 Softmax 损失函数的导数。所有这些变化都可以在当前的设置中完成。

如果你有任何问题或难以理解的地方,请在评论中告诉我。

感谢您的阅读。

如何在 60 分钟内从源代码构建 Spark 并将其部署到 Kubernetes 集群

原文:https://towardsdatascience.com/how-to-build-spark-from-source-and-deploy-it-to-a-kubernetes-cluster-in-60-minutes-225829b744f9?source=collection_archive---------4-----------------------

通过这篇 Spark 教程,登上 Kubernetes 的大数据宣传列车

天作之合?来源: Spark Logok8s LogoEmoji

动机/前奏

在我的上一篇文章中,我解释了 Hadoop 生态系统的大致情况,你可以在这里阅读。那篇文章最重要的是结尾,我将公然抄袭我的另一篇文章,因为它也是这篇文章的开头:

现在,如果你在过去几年中一直在收听 Hadoop 的生态系统,你会看到市场上最大的两家公司——cloud era 和 Hortonworks — 在大约一年前Hadoop 大数据市场放缓时合并了。事实上,人们似乎对 Kubernetes 比对更老的 Hadoop 特定技术更感兴趣,如用于资源管理和编排的 YARN,对 PyTorch 等 DL 框架的快速采用,以及对老化的 Hadoop 堆栈的完美风暴的形成。尽管如此,像 Apache Spark 这样的项目仍在稳步前进,例如引入 Kubernetes 作为纱线的替代品。生态系统激动人心的时刻!

简介

本文的目标是向您展示 2020 年大数据生态系统中的一些酷孩子在做什么;它试图把东西塞进 Kubernetes(这是一件好事!).更具体地说,使用 Spark 的本地 Spark 驱动程序和执行器的实验性实现,其中 Kubernetes 是资源管理器(而不是 YARN)

…让我们在 60 分钟内完成这项工作:

  1. 从 GitHub 克隆 Spark 项目
  2. 用 Maven 构建火花分布
  3. 在本地构建 Docker 映像
  4. 使用多个执行器副本运行 Spark Pi 作业
  5. 使用端口转发在浏览器中显示 Spark UI,并检查 Spark 作业

如果这么简单,我们为什么需要这篇文章?!请继续阅读,看看我第一次是如何花了才弄明白的。

免责声明:您在 60 分钟内的里程数可能会有所不同,但在假设您通常知道如何在计算机上完成工作(包括设置本地 k8s 集群和运行 bash 脚本等)的情况下,这确实是可行的。此外,如果你有一台运行缓慢的计算机,构建 Spark 可能需要一段时间;)

既然大家都在船上,让我们在 Kubernetes 上部署 Spark。为此,您可以使用您的笔记本电脑运行的 mill minikube 设置,而不是在公共云中租用一台服务器来进行此练习。除非你想全押,在这种情况下,你刚刚被敬礼。

步骤 1–3(克隆回购、构建 Spark、构建 Docker 映像):

这实际上是乐趣的开始——在“最简单”的步骤上。好吧,系上安全带,看看这个(双关语):

如果你在这里克隆了官方的 Spark 库,在 k8s 这里天真的按照官方的 Spark 运行指南运行 Spark,你就会碰到我前几天在 Spark 的吉拉积压里开的这一期

也就是说,在 docker 文件中有多个错误的引用,因此简单地运行 docker 文件注释中描述的 docker 构建命令是行不通的。

更新:好吧,事实证明,你实际上可以运行文档中描述的东西,但前提是你必须非常注意。

而不是逃跑

./build/mvn -Pkubernetes -DskipTests clean package

你需要跑

dev/make-distribution.sh -Pkubernetes

这创造了一个火花发行版而不仅仅是普通的组装零件,但我想我跳过了他们教程中的细则,所以我相应地更新了这篇文章。

TL;灾难恢复要完成步骤 1-3,只需执行以下操作:

git clone [git@github.com](mailto:git@github.com):apache/spark.gitcd sparkdev/make-distribution.sh -Pkubernetescd distdocker build -t spark:latest -f kubernetes/dockerfiles/spark/Dockerfile .

此时,您应该在本地 Docker 注册表中有一个 Spark 的图像!

步骤 4:在 Kubernetes 中使用多个执行器副本运行 Spark Pi 作业:

我在上面链接的 Spark 文章中提到但没有解释清楚的事实是,由于 Kubernetes 的 RBAC(基于角色的访问控制),您不能简单地将 Spark 部署到您的集群中,因为 Spark 需要对您的 Kubernetes 集群拥有一些额外的权限来管理 pods。这是由于 Spark 的架构——您部署一个 Spark 驱动程序,然后它可以在 pod 中创建 Spark 执行器,然后在工作完成后清理它们:

Spark 在 Kubernetes 上的架构来自他们的文档

TL;dr 我们需要为 Spark 创建一个 kubectl 服务帐户:

kubectl create serviceaccount sparkkubectl create clusterrolebinding spark-role --clusterrole=edit  --serviceaccount=default:spark --namespace=default

接下来是使用我们本地构建的 Docker 映像运行 Spark Pi:

bin/spark-submit \
--master k8s://https://kubernetes.docker.internal:6443 \
--deploy-mode cluster \
--name spark-pi \
--class org.apache.spark.examples.SparkPi \
--conf spark.executor.instances=2 \
--conf spark.kubernetes.container.image=spark:latest \
--conf spark.kubernetes.container.image.pullPolicy=Never \
--conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \
local:///opt/spark/examples/jars/spark-examples_2.12-3.1.0-SNAPSHOT.jar 10000000

好吧,但是这里实际发生的事情。这就是如何将 Spark 驱动程序部署到 Kubernetes 集群中的方法!让我们来看看这些参数,这样你就可以自己动手了:

  • 定义 Kubernetes 集群(使用 kubectl cluster-info 查找)。是的,需要有点怪异的 k8s://前缀。
  • 定义部署模式(集群,duh)
  • 定义 Spark Driver 的名称(这也是您的 pod 名称的开头)
  • 定义火花 Pi 示例
  • 在 Kubernetes 上运行 Spark Executor,其中有 2 个副本将由 Spark 驱动程序生成
  • 使用我们的本地火花:最新图像
  • 将 Kubernetes 映像提取策略定义为 Never,这样就可以使用具有该名称的本地映像。如果你不太熟悉 k8s 的内部工作原理,这肯定需要一分钟才能弄明白…
  • 定义服务客户(还记得 RBAC 吗?)
  • 指向带有参数 10000000 的本地 jar 路径(它与 other 文件中的所有其他示例一起被复制到指定的路径中)(如果您不知道这个数字的用途,请查看 Spark Pi 源代码和文档)。是的,local:///是正确的,而且不是错别字。
kubectl get pods

现在应该会返回一个正在运行的 pod 列表!不要担心它们最终被终止——这是这个实现的默认设置。

第五步:使用端口转发显示 Spark UI

kubectl port-forward <insert spark driver pod name> 4040:4040

然后,您应该能够在浏览器中通过上面的第一个命令使用 localhost:4040 访问 Spark UI,如下所示:

这是我的 localhost:4040 带端口转发的截图

您也可以像这样查看您的日志:

kubectl -n=default logs -f <insert spark driver pod name>

结论

如果您非常了解 Spark 和 Kubernetes,那么使用配置文件和 docker 文件进行这种精确的设置可能会非常简单,如果您不了解,那么这可能会是一场噩梦。我希望这将有助于你在几分钟内做到这一点!

你从这里去哪里?任何你想去的地方。本文的目标是让您快速使用一个新的 Spark 资源管理器。我建议你下一步用其他 Spark 应用程序来试验这个设置——我可能会在将来写一篇关于一些更复杂的例子的文章(如果我应该的话,请告诉我)。

和 Kubernetes 玩得开心!

替代品

这是 2020 年 4 月 20 日的更新,您也可以使用 Google 的原生 Kubernetes 操作器,它似乎很有前途,可以将手动部署步骤删除到您的集群中:

[## Google cloud platform/spark-on-k8s-运营商

这不是官方支持的谷歌产品。如果您目前正在使用 v1beta1 版本的 API,请…

github.com](https://github.com/GoogleCloudPlatform/spark-on-k8s-operator)

它目前正被 Salesforce 和微软等公司用于生产,并且正在被优步和 Lyft 用于生产评估。未来要注意的事情!

如何在预算范围内构建终极数据科学电脑

原文:https://towardsdatascience.com/how-to-build-the-ultimate-data-science-pc-on-a-budget-69ee498dcdaa?source=collection_archive---------5-----------------------

让您的硬件更上一层楼

照片由来自 PexelsJosh Sorenson 拍摄

当开始进入数据科学领域时,您最终会发现您需要升级您的硬件。

你应该如何通过 Chromebook 运行数百万个数据点来训练你的深度学习模型?

你不能。你可以。但这可能需要几天,几周,甚至几个月。

这不是你生活的方式:等待你的过程完成。立即升级您的硬件!

然而,我必须警告你:如果你不负责,这些强大的计算机器可以很快在你的口袋里烧一个洞。

你很幸运,我已经对此负责,并活着讲述了这个故事!

经过大量的研究和购买,我组装了一台我认为是在数据科学领域起步的完美计算机。

目标

在预算有限(约 1000 美元)的情况下,为数据科学家打造完美的计算机。

我的零件

GPU:GTX 1660s(245 美元)

选择显卡可能是最艰难的决定。这是拥有有效的数据科学机器的最重要的部分之一。

我最终选择了更高层次的显卡,因为我不想受到这个组件的任何限制。

我用的是英伟达 GTX 1660。根据我的研究,我确定 1660 超级是一个相当不错的交易 245 美元。

通过获得“超级”版本,它提供了可比的性能到下一个水平(GTX 1660 Ti)。感觉我用这个得到了最大的回报,到目前为止,它没有让我失望。

一些关键规格:流处理器:1408

  • 提升时钟速度:1.83MHz
  • TDP:125 瓦
  • 内存:6GB

CPU: AMD 锐龙 7 2700X,带幽灵棱镜 LED 冷却器(130 美元)

我想要一个强大的处理器。

但是对于我的用途来说,我不需要过分的东西。没有超频是必要的(至少在我职业生涯的这个阶段);虽然,可以超频到 4.4GHz。

我选择了 AMD 处理器,而不是英特尔。为什么?似乎我可以用更低的价格获得类似的处理能力。此外,我什么时候才能有机会再次使用英特尔处理器以外的产品?

我很高兴看到我是否注意到了我的电脑上的 AMD 和我使用的其他电脑上的 Intel 之间的差异。到目前为止,我还没有。

此外,我在微中心以非常合理的价格(230 美元)获得了 CPU 和主板的捆绑包。同样的 CPU 单独在亚马逊上是 190 美元(写这篇文章的时候)。

一些关键规格:

  • 内核/线程数:8/16
  • 速度:3.2GHz — 4.1GHz(turbo)
  • TDP: 65W
  • 包括 HSF 股票:是

主板:微星 B450 游戏专业版(100 美元)

这个主板是处理器捆绑包的一部分,所以在了解到它与 AMD 处理器和我正在查看的所有其他部分兼容后,这似乎是一个显而易见的事情。此外,它有 WiFi 功能,这是我的必需品。

微星作为一个值得信赖的品牌也享有良好的声誉。这很有帮助。

一些关键规格:

  • 芯片组:AMD B450
  • 尺寸:ATX
  • 内存:4 个插槽,DDR4
  • PCIe: x16,PCIe 3.0
  • 端口:M.2(通过 PCIe)、USB 3.1、SATA 6Gb/秒

内存:技能 16GB DDR 4 3200(60 美元)

我读到 8 GB 应该足够了,但是 RAM 太便宜了,没有额外的内存看起来很傻。善待自己。

固态硬盘:IPSG 512GB 高级版(60 美元)

选择硬盘还是固态硬盘的决定最终并不困难。Micro Center 正在销售他们的一款 512GB 固态硬盘,读取速度比同类机型快 10 倍左右。所以这是一笔很好的交易。

512GB 的存储量并不算大,但如果我需要更多,我可以以相当便宜的价格购买。

一些关键规格:

  • 容量:512GB
  • 读取速度:3,100 MBps
  • 写入速度:1,900 MBps

电源:IPSG 650 w Semi ATX(85 美元)

IPSG 是微中心品牌。一个名牌的类似瓦数的电源单元要接近 130 美元。购买廉价品牌所牺牲的唯一东西就是效率。更贵型号的效率等级应该是 80 白金(这是 80 金)。

也许从长远来看,我最终会通过电费来偿还差额?我们会看到的。

一些关键规格:

  • 650 瓦
  • 冷却风扇:135 毫米风扇
  • 效率等级:80 金

案例:Corsair 275 r air flow(85 美元)

这个案例更多的是关于整体外观,而不是规格。一旦你找到一个有足够数量的风扇,足够的空间,合理的电缆管理,这归结为个人喜好。

我花了 85 美元,但我可以很容易地看到自己花了更多,因为一些案件实在是太酷了。

不管怎样,我对我选择的案例很满意。我喜欢钢化玻璃,这样我可以看到里面。

一些关键规格:

  • 端口:两个 USB 3.0 端口、3.5 毫米耳机/麦克风、电源/复位
  • 存储空间:可容纳两块 3.5 英寸硬盘和四块 2.5 英寸固态硬盘
  • 风扇:3 个包括 120 毫米风扇

操作系统:Windows 10(97 美元)

我喜欢 Windows 10,所以这不是一个很大的决定。我在微中心得到了一个好价格,因为我在亚马逊上做了价格匹配。

鼠标+键盘:惠普 C2500 有线(17 美元)

我选择了我能找到的最便宜的可信品牌(惠普)的鼠标+键盘。他们完成了工作,我喜欢两者的感觉。

显示器:两台宏碁 sb 220 q(~180 美元)

我已经有这些监视器了。只有两台相当便宜的 23 英寸显示器。

让我的显卡输出到两个显示器不是一件容易的事情,因为我总是买错显示器电缆。我终于让它与 HDMI 到 HDMI 和 DVI 到 DVI 一起工作。

专业提示:

我在这一过程中学到的一些东西可能对第一次使用 PC 的人有用。

我建议用他们商店里的东西和亚马逊上的东西做一个价格对比。通过这样做,我在 Windows 10 上节省了大约 25 美元,但如果我对所有部件都这样做,可能会节省大约 60 美元。

组装电脑时,确保你有足够的空间,并有一个漂亮、开放的工作空间。很容易丢失碎片。此外,我建议良好的照明,因为当你把那些细小的电缆插到你的主板上时,你需要所有你能得到的帮助。

打开你案子的所有房间。我差一点就能在亚马逊上买到新螺丝了,因为我没有这么做。制造商喜欢让你在寻宝游戏中找到所有的碎片。

当你在努力组装电脑时,请务必阅读手册。我一直试图寻找在线指南或视频,但手册最终是最有帮助的(我知道我很千禧一代)。

为每个硬件组件安装驱动程序。我发现,要充分利用这些软件,你必须安装各自的驱动程序。我会在下面解释,因为这是我不知道的事情。

什么是司机?一个设备驱动是一个允许你的硬件与你的操作系统通信的软件。这就是我们如何确保从我们的显卡、主板或任何硬件发送到 Windows 10 的信息是正确的。

每当您遇到硬件问题时,您首先应该检查控制面板中的设备管理器,以确保您不仅有设备驱动程序,而且它是最新的。

没有合适的设备驱动程序对于 PC 构建新手来说无疑是不明显的。我在双显示器上显示时遇到了问题,但当我安装了 NVIDIA 驱动程序后,它就工作了。

我的主板也是这样。我的 WiFi 连接非常不稳定,我知道这不是威瑞森的错,因为我所有的其他设备都连接得很好。有一次我下载了 Intel Wireless-AC 9260 驱动程序,嘣。成功了。

有用的资源

我找到了很多很棒的资源来帮助我完成这个项目。我将它们列举如下:

https://www.logicalincrements.com/——帮我弄清楚该选择什么零件。一开始可能会让人不知所措,因为太多了。这个网站可以帮助你根据你想花多少钱和你想让你的机器有多强大来缩小你想要的零件的范围。你在这个网站上找到的价格为你应该花多少钱提供了一个很好的基准。

https://pcpartpicker.com/——我看了几个其他人的版本,看看他们是如何选择角色的。大部分是为了游戏,我不是很喜欢,但仍然有助于确保组件之间的兼容性。

https://www.microcenter.com/——这是我去买作品的地方。我在黑色星期五大减价的时候去了,所以我买到了一些好东西。我只打算最初买我的 CPU 和主板那天,但最终买了一整套。微中心的员工知识渊博,乐于助人,我觉得他们引领我走上了正确的道路(他们的大多数建议与我之前所做的研究一致)。

https://www.youtube.com/watch?v=IhX0fOUYd8Q——这是我在组装电脑时跟随的视频。这家伙知道自己在做什么,对我这个不知道自己在做什么的人来说,这就足够了。

如果你读这篇文章是因为你想为你的电脑设计获得一些灵感,我祝你好运!如果您有任何问题、意见或担忧,请留下您的评论。

如何建立对人工智能解决方案的信任

原文:https://towardsdatascience.com/how-to-build-trust-in-artificial-intelligence-solutions-83ca20c39f0?source=collection_archive---------48-----------------------

来源: Adobe 股票

心理学家对人工智能中建立信任的观点,以及公司需要了解哪些机制来满足其客户和用户的需求。

我采访了玛丽莎·斯乔普,她是一名组织心理学家,从人文角度进行人工智能研究,重点关注心理和伦理问题。她还是位于苏黎士的科技和网络安全公司 scip AG 的企业研究员。她是驻瑞士大使。

请用两到三句话描述你是谁。

目前,我专注于对人工智能、自主武器系统和我们的 AIQ 项目的信任,这是一种测量数字助理(对话式人工智能)技能的心理测量方法,如 Siri 或 Alexa。

所以,很明显,我是一名研究人员,但我也是两个蹒跚学步的孩子的母亲,一个妻子,一个女儿,一个姐姐,一个排球运动员,希望是一个有趣的朋友,一个活动家,一个理想主义者,一个合作者,一个半职业的夏尔巴人(我喜欢在瑞士阿尔卑斯山徒步旅行,因此必须背着我的孩子!).

让我们从更好地理解信任开始。信任是什么,为什么它很重要,尤其是在人工智能的背景下?

在人工智能的背景下,有一个关键的潜在假设:“没有信任,就没有使用”。由于人工智能有很大的前景(也有危险),科技公司和人工智能爱好者特别关注如何建立对人工智能的信任,以促进采用或使用。

信任似乎是一种持久的、神秘的竞争优势。

没有信任,就没有家庭、房屋、市场、宗教、政治和火箭科学。

根据信托研究员雷切尔·博茨曼的说法,

信任是一种社会粘合剂,使人类能够通过相互之间以及与包括技术在内的环境的互动而进步。

信任可以被视为一种应对不确定性的心理机制,位于已知和未知之间。

图片:瑞秋·博茨曼

信任在我们的个性中根深蒂固。我们基本上生来就有信任或不信任人(或动物或任何其他事物)的倾向。

以一个女人的随机照片为例:你信任她吗?请在下面评分。

来源:聂难多斯

我们人类有独特的能力在一瞬间判断出我们是否信任这个人。我们看面部表情、身体姿势或环境(背景、周围环境等)。).我们在分秒之间将其与记忆或过去的经历进行比较,比如“她让我想起了我的祖母。”

总的来说,我们知道的是,我们更倾向于相信那些和我们更相似的人。一个原因是,我们更容易预测相似人的未来行为或反应,这降低了我们受到伤害的情感风险。

我们不知道的是,我们的直觉有多准确。你相信上面这个女人吗?也许是的,因为她在微笑,放松。也许不是,因为你已经在这里期待某种诡计,因为我是一个心理学家。

这个女人不太值得信任。她几年前死于狱中,是最著名的女性连环杀手之一。

在人工智能的背景下,如果你问我们能否信任人工智能作为一种技术的问题,那么与其他技术相比,理解人工智能(例如机器学习,比如图像分类)经常不完全按照预期的方式行事,犯错误,或者表现得不道德是决定性的。比如当黑人被归类为大猩猩或者鸟类被归类为导弹的时候。

过程和结果很难解释,有时根本不知道,因此,不太好预测。信任这项技术会带来更高的风险。

到目前为止,研究已经就建立信任需要回答的三个主要支柱达成一致,

1。)性能:表现好吗?安全吗?建的对吗?

2。)流程:它是否按照我们预期的方式执行?我们能预测结果吗?

3。)目的:我对程序和提供者的意图有好感吗?它是否符合道德标准?值得信赖吗?

人们常说,人工智能积极地改变了从医学到城市规划的几乎每个领域,但非常重要的是,它也带来了令人质疑甚至危险的影响。从数据平台的超精确黑客攻击到监控状态和没有机会获得公众同意的隐私损失。因此,除了缺乏可预测性和可解释性等技术问题之外,负面结果的概念、炒作、复杂性以及定义和应用中的分歧都会导致怀疑和不信任。

非专家和企业主等应该如何。走近这个话题?

人工智能已经成为我们日常生活的一部分,它已经越来越多地用于教育、警察、司法、招聘或卫生等决策。

我也没有技术背景,我是一名心理学家,所以我从不同的角度看问题,对我来说,可能更容易与大多数人产生共鸣,他们不知道如何编码或什么是算法。

最让我着迷并推动我研究的是一个问题,信任首先是如何建立的。你并不真正了解这个人或这个产品,它的价值或能力。第一次瞥见说“好的,我要去”。

这种信任最初是如何发展的,仍然有点神秘。

我们怎样才能最好地应对它?我认为这一切都与教育、沟通和批判性思维有关。但有一些东西限制了这些技能或我们参与人工智能讨论的意愿。

从心理学角度来看,这是一个大问题:我们缺乏选择的认知自由。我担心的是,我们正走向与人工智能的生死攸关的关系。摆脱人工智能几乎是不可能的,就像我们无法摆脱气候变化一样。

事实上,我们被迫或受到威胁,就像威胁性的终结者图像或不断输给机器新闻的人,会导致抵抗、否认、愤世嫉俗和淡化。这叫逆反,一种心理现象。当反抗发生时——我们选择这些行为——即使它们是完全不理性的——简单地恢复我们选择的认知自由,夺回我们的控制感。

这可能是一个很大的挑战,尤其是在消费者心理方面当你的目标是说服客户购买你的产品时,无论是汽车还是机器人吸尘器。

像所有人一样,消费者想要选择的自由,我们需要找到方法,让人们想要自己探索人工智能,而不是因为他们被迫这样做。

这就是为什么管理层经常在公司内部采用自下而上的方法,而不是自上而下的决策。

通过这种参与式的决策方式,你的目标是让所有人都参与进来,分享你的愿景和目标。

目前,关键问题之一是改变我们谈论人工智能的方式。我认为我们必须大幅改变关于人工智能的对话基调。我们必须远离炒作、威胁和恐惧,走向清晰的事实、愿景和原因,以创造我们自己与人工智能的关系,从而达到新的信任水平。

这也是我作为人工智能中的女性网络大使的愿景,这是一个致力于性别包容的人工智能,造福全球社会的非营利组织。

假设一家公司正在开发一款基于机器学习的产品,并且刚刚开始原型制作。从建立信任的角度来看,你有什么建议?

我从一个哲学家那里学到的是总是问为什么,从开始到结束,在项目的所有里程碑持续不断。

预期的后果是什么,并推测所有可能的意外后果?

从设计的角度来看,这一切都是为了让你的设计至少符合最低的道德标准,以确保你正在建造一个值得信赖的产品。但是,请记住,技术性能(质量)、安全性和安全性都是不可或缺的先决条件。

回到最初,在头脑中不断记住三大支柱流程、绩效、目的。人工智能中的伦理是关于完整性和真实性的。

最终,任务是建造一个伟大的、安全的、道德上正确的产品。焦点自然是首先建立一个好的产品,然后才是安全和道德的东西。

首先关注技术需求是很自然的,然而与直觉相反的是,应该首先关注后者。两年前,当我们开始我们的信任研究时,我们的想法是有一个质量证明,向用户或客户表明这是一个值得信赖的产品。这就是为什么我们发明了 AIQ,一种心理测量方法来陈述、比较和跟踪数字助理的技能。然而,我们有点太快了,因为市场仍处于发展阶段,而不是真正改善现有的对话式人工智能。我们一开始也关注技术技能,而不是如何建立和发展信任的实际决定性软因素。

来源:瑞士认知

这里有一集播客更详细地讨论了这个话题。

现在,我们后退一步,专注于在人工智能背景下影响信任建立的不太明显的因素。这些是微观感知水平上的良好影响因素,从个性特征到偏见,到过去的经历,到社会化和教养。我们只是在收集数据,通过关联、定性和定量的方法来探索人工智能中信任的这些前因。

来源:玛丽莎·特肖普

产品上市后有没有可能改变 AI 的形象或者影响消费者行为?

如果你想探索你的信任形象,你需要从各种角度看问题和定义:你可能想看个人(像你的目标群体或员工的特征),你可以从消费者的角度看建立、维持和发展信任的过程,以及破坏和重新获得信任。你必须清楚演员和角色(谁是可信的?)和情况:是像自动驾驶汽车这样的高风险情况,还是我们谈论的人工智能驱动的客服聊天机器人?

最后,答案是肯定的,然而,在两个方向上,无论是好是坏。当我们谈论人工智能时,我们必须非常敏感,中立,或者像汉斯·罗斯林所说的“实事求是”。关于做什么来维持一段关系或如何行动的研究非常清楚,如果你打破了信任关系,我不确定人工智能是否与其他技术有任何不同。违规就是违规,不管是脸书的数据违规还是导弹失误。

如果发生了信任违约,你必须立即、直接、清楚地沟通发生了什么,不要辩解地解释自己,要真实可信,并询问需要什么来获得另一次机会。

你会为企业主或产品经理推荐哪些书籍和其他资源来学习人工智能中的信任建设?

我建议检查一下欧洲高级人工智能专家组。他们刚刚发布了一个构建可信人工智能的框架。该框架有三个主要部分,包括合法人工智能、道德人工智能和健壮人工智能。报告讨论了后两者的要点。

另一套全面的众包标准来自于 IEEE 自主智能系统伦理全球倡议,它被称为伦理一致设计。

雷切尔·博茨曼:你能相信谁?她写了在数字时代信任是如何建立、失去和恢复的,她也有几个被强烈推荐的 TED 演讲。

这次采访是由来自 Omdena 的迈克尔·布哈特完成的,Omdena 是一个创新平台,人工智能工程师和领域专家在这里合作构建现实世界问题的解决方案。

如何像构建产品一样构建您的数据平台

原文:https://towardsdatascience.com/how-to-build-your-data-platform-like-a-product-6677e8abe318?source=collection_archive---------8-----------------------

从(标准开发。)零到真正的数据英雄

图片由 Unsplash 上的 Austin Distel 提供。

在过去的几年里,许多公司已经将数据平台作为大规模聚合、处理和利用数据的有效方式。尽管数据平台越来越受欢迎,但是,关于如何成功构建数据平台的文献却很少。

巴尔摩西 、CEO&蒙特卡洛 阿图尔古普特 、前 优步数据平台团队产品经理 分享设计数据平台的建议,最大化数据对您组织的价值和影响

你的公司喜欢数据。很多。你的老板要求今年增加人手,以加强你的数据工程团队(Presto 和 Kafka 和 Hadoop,哦,我的天!).你的数据副总裁经常潜伏在你公司的 Eng-Team Slack 频道,以了解人们对迁移到雪花的“感受”。你的 CEO 甚至想成为数据驱动型,不管这意味着什么。说数据是贵公司的重中之重是一种保守的说法。

为了满足贵公司对数据贪得无厌的胃口,您甚至可能正在构建一个复杂的多层数据生态系统:换句话说, 一个数据平台

数据平台的核心是所有数据的中央存储库,处理数据的收集、清理、转换和应用,以生成业务洞察。对于大多数组织来说,构建数据平台不再是一件美好的事情,而是一件必要的事情,许多企业从竞争中脱颖而出,因为他们能够从数据中收集可操作的见解,无论是改善客户体验、增加收入,还是定义自己的品牌。

就像许多人将数据本身视为产品一样,像优步LinkedIn脸书这样的数据优先公司也越来越多地将数据平台视为“产品”,拥有专门的工程、产品和运营团队。然而,尽管数据平台无处不在且广受欢迎,但在谁在使用它们、如何使用它们以及工程师和产品经理如何优化这些体验方面,数据平台往往缺乏远见。

无论您是刚刚起步还是正在扩展,我们都将分享五个最佳实践来避免这些常见的陷阱,并构建您梦想中的数据平台:

使你的产品目标与业务目标一致

将您的平台目标与您业务的总体数据目标保持一致非常重要。图片由 Unsplash 上的John Schnobirch提供。

几十年来,数据平台被视为达到目的的手段,而不是“目的”,也就是你正在构建的核心产品。事实上,尽管数据平台为许多服务提供了动力,为驱动我们生活的应用提供了丰富的见解,但直到最近,它们才得到真正应有的尊重和关注。

当您构建或扩展您的数据平台时,您应该问的第一个问题是:数据如何映射到您公司的目标?

要回答这个问题,你得戴上你的数据平台产品经理的帽子。与具体的产品经理不同,数据平台产品经理必须了解全局与特定区域的目标,因为数据会满足其他所有职能团队的需求,从营销和招聘到业务开发和销售。

例如,如果你的业务目标是增加收入(要么做大,要么回家!),数据是如何帮助你实现这些目标的?为了这个实验,考虑以下问题:

  • 哪些服务或产品推动收入增长?
  • 这些服务或产品收集哪些数据?
  • 在使用这些数据之前,我们需要对其做些什么?
  • 哪些团队需要这些数据?他们会用它做什么?
  • 谁将有权访问这些数据或其生成的分析?
  • 这些用户需要以多快的速度访问这些数据?
  • 平台需要解决哪些合规性或治理检查(如果有的话)?

通过回答这些问题,您将更好地了解如何确定产品路线图的优先级,以及您需要为谁(通常是工程师)构建,还是为谁(包括分析师在内的日常平台用户)设计。此外,这种 KPI 开发和执行策略的整体方法为您的平台设置了跨团队的更可扩展的影响。

从合适的利益相关者那里获得反馈和认同

不言而喻,在整个产品开发过程中接受预先认可和反复反馈是数据平台之旅的必要组成部分。没有被广泛理解的是你应该关心谁的声音。

是的,你需要你的 CTO 或 VP 对最终产品的数据进行最终确认,但是他们的决定通常是由他们信任的顾问告知的:员工工程师、技术项目经理和其他日常数据从业者。

在为她的公司开发新的数据编目系统时,我们采访的一位产品经理在一家领先的运输公司花了 3 个月试图说服她的工程副总裁接受她的团队的想法,结果却被他的参谋长在一封电子邮件中拒绝了。

根据你公司的 DNA 考虑不同的策略。我们建议同时遵循以下三个步骤:

  1. 销售愿景的领导力。
  2. 向你的实际用户推销基本原理和日常使用案例。
  3. 运用 以客户为中心的方法 ,不管你在和谁说话。将平台定位为在您的数据生态系统中为不同类型的人物角色赋能的一种方式,包括您的数据团队(数据工程师、数据科学家、分析师和研究人员)和数据消费者(项目经理、高管、业务开发和销售人员等)。一个伟大的数据平台将使技术用户能够轻松高效地完成他们的工作,同时也允许技术含量较低的人物角色利用丰富的见解,或者在没有工程师和分析师太多帮助的情况下,根据数据整合可视化。

在为公司构建数据平台时,你必须考虑各种各样的数据角色,包括工程师、数据科学家、产品经理、业务功能用户和总经理。(图片由 Atul Gupte 提供)

在一天结束时,重要的是,这种体验培养了一个数据爱好者社区,他们可以一起构建、共享和学习。既然你的平台有潜力服务于整个公司,每个人都应该对它的成功感到投资,即使这意味着在这个过程中做出一些妥协。

优先考虑长期增长和可持续性,而不是短期收益

考虑到短期可用性的数据解决方案通常更容易实施,但随着时间的推移,最终会比考虑到可持续性的平台更加昂贵。(图片由 Atul Gupte 提供。)

与其他类型的产品不同,数据平台的成功不仅仅是因为它们有利于“率先上市”。由于数据平台几乎完全是内部工具,我们发现最好的数据平台是在考虑可持续性而不是特定功能的情况下构建的。

记住:你的客户就是你的公司,你公司的成功就是你的成功。这并不是说你的路线图不会改变几次(它会),但是当你真的要改变时,要带着成长和成熟的想法去做。

例如,优步的大数据平台历时五年建成,并随着业务需求不断发展;Pinterest 已经经历了几次核心数据分析产品的迭代;领衔群雄的是, LinkedIn 自 2008 年以来一直在构建和迭代其数据平台!

我们的建议是:选择对您的组织环境有意义的解决方案,并根据这些期望和期限调整您的计划。有时,作为更大的产品开发战略的一部分,速赢可以帮助实现内部认同——只要它不是短视的。罗马不是一天建成的,你的数据平台也不是。

签署您的数据的基线指标以及您如何衡量它

如果您不能信任您的数据,那么您的数据平台有多好并不重要,但是数据质量对不同的利益相关者来说意味着不同的事情。因此,如果您和您的利益相关者在这个定义上不一致,您的数据平台就不会成功。

为了解决这个问题,重要的是为您的数据可靠性、设定基准预期,换句话说,就是您的组织在整个数据生命周期中提供高数据可用性和健康的能力。为软件应用程序可靠性设置清晰的服务水平目标(SLO)和服务水平指标(sli)是显而易见的。数据团队应该为他们的数据管道做同样的事情。

这并不是说不同的利益相关者会对“好数据”有相同的看法;事实上,他们可能不会,这没关系。与其将方钉安装到圆孔中,不如创建一个数据可靠性的基线指标,并在构建新的平台功能时,获得最小公分母的认可,这一点很重要。

我们建议选择一种新颖的测量方法(,就像这个用于数据停机,这将帮助整个公司的数据从业者在基线质量指标上保持一致。

知道何时构建与购买

您必须做出的第一个决定是,是从头开始构建平台,还是从供应商那里购买技术(或几种支持技术)。

虽然像优步、LinkedIn 和脸书这样的公司已经选择建立自己的数据平台,通常是基于开源解决方案,但这并不总是对你的需求有意义。虽然没有一个神奇的公式可以告诉你是建造还是购买,但我们发现购买是有价值的,直到你确信:

  • 该产品需要使用敏感/机密信息(例如,财务或健康记录)运行,出于法规原因,这些信息不能与外部供应商共享
  • 需要进行特定的定制,以便与其他内部工具/系统配合使用
  • 这些定制足够小,供应商可能不会优先考虑它们
  • 与购买相比,构建还有其他一些战略价值(例如,企业的竞争优势或有利于招聘人才)

我们采访的一家医疗保健初创公司的数据工程副总裁指出,如果他 20 多岁,他会想要建立。但是现在,在他快 30 岁的时候,他几乎只买。

“我有热情,”他说,“但是如果我有时间、精力和资源从头开始建立一个数据平台,那我就完了。我现在长大了,也更聪明了——我知道不该不相信专家。”

当谈到你可以把时间(更重要的是金钱)花在什么地方时,购买一个经过实践检验的真正解决方案,并有一个专门的团队来帮助你解决出现的任何问题,通常会更有意义。

下一步是什么?

从产品开发的角度来看,构建数据平台是一个令人兴奋的旅程,它将受益于应用。图片来自

将您的数据平台构建为一个产品将有助于您确保围绕数据优先级达成更大的共识,实现数据质量和其他关键 KPI 的标准化,促进更大的协作,从而为您的公司带来前所未有的价值。

除了作为有效数据管理、可靠性和民主化的工具,将数据平台构建为产品的好处还包括:

  • 指导销售工作(根据潜在客户的反应,让您了解应该将工作重点放在哪里)
  • 驾驶应用产品路线图
  • 改善客户体验(帮助团队了解您的服务难点是什么,什么有效,什么无效)
  • 在整个公司范围内标准化数据治理和合规性措施(GDPR、CCPA 等)。)

乍看之下,构建数据平台似乎势不可挡,但如果方法正确,您的解决方案有可能成为整个组织的力量倍增器。

想了解关于构建可靠数据平台的更多信息?向 巴尔摩西 和蒙特卡洛团队伸出援手。

本文由巴尔·摩西阿图尔·古普特共同撰写。

如何构建您的第一个 Python 包

原文:https://towardsdatascience.com/how-to-build-your-first-python-package-6a00b02635c9?source=collection_archive---------5-----------------------

让全世界都能方便地获得你的优秀代码,因为你也很优秀

在媒体上阅读此文,而不是使用此 好友链接 的媒体会员!

来自 PixabayVadim_P 的原始图像

这篇博文现在也有波兰语版本,请在bulldogjob . pl上阅读

大约两年前,我发表了第一篇与数据科学相关的博客。它是关于分类相关性,我真的认为没有人会觉得它有用。这只是实验性的,对我自己来说。1.7K 鼓掌后来,我明白了我不能决定其他人会发现什么是有用的,我很高兴我能在网上帮助其他人,就像其他人在网上帮助我一样。

当时我对 Python 和 Github 还很陌生,所以我也尝试着为我写的这些分类相关性编写代码,并将其发布在 Github 上。我给那段代码起了个名字: Dython ,就像 pYTHON 的数据工具里一样。

但这不是这篇博文的内容——它是关于在我刚刚提到的所有事情之后我做的最后一件实验性的事情:我创建了一个 Python 库并上传到 PyPI——你可能知道它是pip install。同样,这一切都是从学习练习开始的——但是随着每月大约 1.5K 的安装,我再次意识到我低估了自己对他人有用的代码能力。

但是为什么我要告诉这一切?因为几乎每个人的笔记本电脑或 Github 账户上都有一些很酷的代码。这段很酷的代码可能对其他人很有帮助——尽管我们大多数人认为这可能不是真的,还有“其他人能在我的一小段代码中找到什么价值”。我也是这么想的,结果发现我错了。你也可能是错的,我在这里劝你——并帮助你——只需几个步骤就可以把你漂亮的代码变成一个完整的 Python 包——这样你就可以用一个pip install节省其他人几个小时的编程时间。成为协助其他程序员的人——让我向你展示如何通过六个步骤来做到这一点。我们开始吧。

在我们开始之前:代码清理和源代码控制

我相信这是不言而喻的,但我还是想确保我们在同一页上。程序员分为两类:一类编写可读代码,另一类使用名为 x,x1,x2,yx,等变量。如果你属于第一种,可以直接跳过去。如果你是第二种类型——是时候转换到另一边了。记住其他人会阅读你的代码,所以要确保它是可读的。给事物起一个有意义的名字,把长函数分解成短编码的单一用途的方法,等等。你知道,就像他们教的那些编码课程一样。

另一件事,我假设你正在使用一些源代码控制,可能是 GitHub。虽然这并不是真正必需的,但比建议的要多。如果你以前从未使用过 GitHub,这是一个花几分钟学习如何使用的好机会——查看官方教程,或者这篇博文,然后开始使用。

步骤 1:选择您的 API

把你的代码变成一个包的第一步是决定用户应该如何使用它——并使它可导入。我们将把它分成两个动作:

#1:公共和私有方法

您的代码可能由几个函数和方法组成,但并不是所有的函数和方法都是供用户使用的——有些是内部函数,应该只供您的代码使用。虽然 Python 不支持私有方法,但约定是用下划线前缀def _private_function()标记私有方法。像这样重命名你所有的内部函数,这样用户会很容易理解什么应该向他们公开,什么不应该。

Pro 提示: 您可以使用特殊变量__all__来精确定义当用户使用from your_package import *时,哪些函数需要公开,哪些不需要公开。查看 StackOverflow 上的线程了解更多信息。

#2:添加__init__.py

如果您的代码由几个模块(文件)组成,如下所示:

your_package
  |-- module1.py
  |-- module2.py

您需要在您的包中添加另一个文件__init__.py,以便让 Python 将your_package目录解释为 Python 包。这意味着现在它应该是这样的:

your_package
  |-- __init__.py
  |-- module1.py
  |-- module2.py

您可以将文件留空作为起点,但它必须在那里,以便允许from your_package import module1

Pro 提示:__init__.py中的代码在你的包被导入后被执行,这允许你做各种很酷的事情。例如,你可以使用__init__.py来缩短你的 API。假设您的代码中最重要的方法imp_funcmodule1中。您可以允许用户将其作为from your_package import imp_func而不是from your_package.module1 import imp_func导入,只需添加:

from .module1 import imp_func

到您的__init__.py文件。

第二步:记录

文档就像排队——我们希望每个人都能简单地做这件事,但是我们倾向于尽可能地放松自己。步骤 2 这里与我们开始部分之前的相关,因为它意味着让其他人理解你的代码做什么。您需要添加两种类型的文档:

#1:文档字符串

库中的每个函数都应该有一个文档字符串,它总结了函数的内容。它应包含:

  • 用简单的语言解释这个函数应该做什么
  • 参数:解释什么是函数期望的参数和参数类型
  • 返回值:解释函数返回的内容
  • 示例:虽然不是必须的,但添加一个用法示例总是有用的

这里有一个例子:

你可以在 DataCamp 上的这篇超酷文章中了解更多关于文档字符串格式的信息。

#2:自述文件

自述文件是对软件包内容的总结。当放置在你的包的顶层目录时,GitHub 将它作为你的包的“登陆页”,作为访客看到的第一件东西显示给他们。

一个好的自述文件会有软件包的概述,安装信息(比如需求)和一些快速启动的例子,描述你的软件包的基本用法。

自述文件通常以一种被称为 MarkDown 的格式编写,你可以在这里了解更多关于的内容。这就是它们通常被命名为README.md的原因。

第三步:许可

当您的代码即将公开时,您应该为它附加一个许可证,向其他人解释他们应该如何使用您的代码。你可能想要使用一个普通的许可证,比如麻省理工学院的 许可证 或者阿帕奇 2.0 的 许可证 。GitHub 会通过点击 License 选项来帮助你选择一个,它会给你的包添加一个名为LICENSE的新文件。如果坚持不用 GitHub,可以手动添加文件。

第四步:重新整理包装

此时,您的包应该是这样的:

your_package  
  |-- README.md 
  |-- LICENSE
  |-- __init__.py
  |-- module1.py
  |-- module2.py

现在,我们将添加一个文件,从您的代码中构建一个可安装的 Python 包。为此,您必须添加一个名为setup.py的新文件,并按照以下方式重新排列您的文件:

your_package 
  |-- setup.py 
  |-- README.md 
  |-- LICENSE
  |-- your_package
        |-- __init__.py
        |-- module1.py
        |-- module2.py

安装文件规定了 Python 安装程序在安装软件包时需要知道的一切。一个非常基本的,你可以简单地复制粘贴,看起来像这样:

除了编辑你的个人信息,还有两件事你必须记录:

  • 版本:每次你发布 PyPI 的新版本(我们马上会讨论),你都必须修改你的版本号
  • 安装需要:这是你的包的所有外部依赖的列表。一定要在这里列出所有的东西,这样 Python 会把它们和你的包一起安装

第五步:注册 PyPI

我们快到了!接下来:去pypi.org创建一个账户。你需要它来上传你的新图书馆。

步骤 6:构建和部署!

我们差不多完成了。剩下的工作就是运行一些命令,从您的代码中构建一个可安装的 Python 包,并将其部署到 PyPI。

在开始之前,我们需要安装twine,这将允许我们部署到 PyPI。这很简单,因为:

pip install twine

接下来,我们将创建一个可安装包。转到setup.py文件所在的目录,运行:

python setup.py sdist bdist_wheel

这将创建几个新目录,如distbuildyour_package.egg-info。我们现在关心的是dist,因为它包含了我们想要部署到 PyPI 的安装文件。你会发现里面有两个文件:一个压缩的tar文件和一个轮子文件。很快,全世界都可以看到它们。

Pro 提示: 将这些目录添加到您的.gitignore文件中,防止将安装文件推送到您的 repo 中。(没听说过 .gitignore 读此 )

接下来,通过运行以下命令来验证您刚刚创建的分发文件是否正常:

twine check dist/*

是时候把你的包上传到 PyPI 了。我建议首先部署到PyPI测试域,这样您就可以验证一切是否如您所愿。为此,请使用:

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

test.pypi.org看看你的新图书馆。满意吗?太好了,让我们来看看真正的 PyPI:

twine upload dist/*

就是这样。从现在开始,每个人都可以使用pip install安装你的软件包。干得好!

Pro 提示: 您可以使用 Bash 脚本让您的生活变得更轻松,它将使用一个命令来构建、检查和部署您的包。在与setup.py相同的目录下创建一个名为build_deploy.sh的新文件。将以下代码复制粘贴到该文件中:

现在你需要做的就是跑:

./build_deploy.sh

从文件所在的目录,就是这样。您也可以运行:

./build_deploy.sh --test

上传到测试域。(注意,在第一次运行之前,您必须使脚本可执行。只需运行文件所在目录下的 chmod +x build_deploy.sh )

额外的一英里:写一篇博客

你的令人敬畏的代码现在可供每个人使用——但是人们仍然不知道你的令人敬畏的代码现在可供他们使用。你怎么能让他们知道?写一篇博文,告诉你为什么首先要编写这段代码,以及它的用例是什么。分享你的故事,这样其他人就会知道你刚刚用你出色的代码为他们节省了多少精力。

最后的话

让你的代码更上一层楼——向全世界发布——在第一次这么做的时候可能看起来很可怕,这既是出于个人原因(“谁会想要使用它?”)和技术原因(“我怎么做得到?”)。我希望在这篇文章中,我帮助你克服了这些挫折,现在你也可以帮助世界上成千上万的其他程序员。干得好,欢迎来到开源社区!

如何用 10 个步骤构建垃圾邮件分类器

原文:https://towardsdatascience.com/how-to-build-your-first-spam-classifier-in-10-steps-fdbf5b1b3870?source=collection_archive---------5-----------------------

如果你刚刚开始机器学习,很有可能你会进行一个分类项目。作为一个初学者,我建立了一个垃圾短信分类器,但做了大量的研究,知道从哪里开始。在本文中,我将用 10 个步骤向您介绍我的项目,让您更容易使用 Tf-IDF 矢量器和朴素贝叶斯模型构建您的第一个垃圾邮件分类器!

1.加载并简化数据集

如果您在 pandas 中阅读,我们的 SMS 文本消息数据集有 5 列:v1(包含每条文本消息的分类标签 ham/spam)、v2(包含文本消息本身)和三个没有使用的未命名列。我们将 v1 和 v2 列分别重命名为 class_label 和 message,同时去掉其余的列。

import pandas as pd
df = pd.read_csv(r'spam.csv',encoding='ISO-8859-1')
df.rename(columns = {'v1':'class_label', 'v2':'message'}, inplace = True)
df.drop(['Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4'], axis = 1, inplace = True)df

看看“5572 行 x 2 列”意味着我们的数据集有 5572 条短信!

2.浏览数据集:条形图

在开始处理数据之前,在分类问题中执行一些探索性数据分析(EDA)是一个好主意,以便可视化、从中获取一些信息或找到数据的任何问题。我们将查看我们有多少垃圾邮件,并为其创建一个条形图。

#exploring the datasetdf['class_label'].value_counts()

我们的数据集有 4825 封垃圾邮件和 747 封垃圾邮件。这是一个不平衡的数据集;火腿信息的数量远远高于垃圾信息的数量!这可能会导致我们的模型有偏差。为了解决这个问题,我们可以对我们的数据进行重新采样,以获得相同数量的垃圾邮件。

为了生成条形图,我们使用 Matplotlib 中的 NumPy 和 pyplot。

3.探索数据集:单词云

在我的项目中,我生成了垃圾邮件中最常出现的单词的单词云。

首先,我们将从数据集中过滤掉所有垃圾邮件。df_spam 是一个只包含垃圾消息的数据帧。

df_spam = df[df.class_label=='spam']df_spam

接下来,我们将把数据帧转换成一个列表,列表中的每个元素都是垃圾消息。然后,我们将列表中的每个元素连接成一个大的垃圾邮件字符串。该字符串的小写形式是我们创建单词云所需的格式。

spam_list= df_spam['message'].tolist()filtered_spam = filtered_spam.lower()

最后,我们将导入相关的库,并将我们的字符串作为参数传入:

import os
from wordcloud import WordCloud
from PIL import Imagecomment_mask = np.array(Image.open("comment.png"))
#create and generate a word cloud image
wordcloud = WordCloud(max_font_size = 160, margin=0, mask = comment_mask, background_color = "white", colormap="Reds").generate(filtered_spam)

显示后:

很酷吧。在我们的数据集中,垃圾短信中最常见的词是“免费”、“立即打电话”、“认领”、“中奖”等。

对于这个单词云,我们需要枕头库,只是因为我使用了遮罩来创建漂亮的语音气泡形状。如果您希望它是方形的,请省略 mask 参数。

类似地,对于业余消息:

4.处理不平衡的数据集

要处理不平衡的数据,您有多种选择。我在我的项目中得到了一个相当好的 f 值,即使是未采样的数据,但是如果你想重新采样,请看这个

5.分割数据集

首先,让我们将类标签从字符串转换成数字形式:

df['class_label'] = df['class_label'].apply(lambda x: 1 if x == 'spam' else 0)

在机器学习中,我们通常将数据分成两个子集——训练和测试。我们将训练集以及它的已知输出值(在本例中,0 或 1 对应于垃圾邮件或火腿)提供给我们的模型,以便它学习我们数据中的模式。然后,我们使用测试集来获得模型在这个子集上的预测标签。让我们看看如何分割我们的数据。

首先,我们从 sklearn 库中导入相关的模块:

from sklearn.model_selection import train_test_split

然后我们分开:

x_train, x_test, y_train, y_test = train_test_split(df['message'], df['class_label'], test_size = 0.3, random_state = 0)

现在,让我们看看我们的测试和训练子集有多少条消息:

print('rows in test set: ' + str(x_test.shape))
print('rows in train set: ' + str(x_train.shape))

所以我们有 1672 条消息用于测试,3900 条消息用于训练!

6.应用 Tf-IDF 矢量器进行特征提取

我们的朴素贝叶斯模型要求数据要么在 Tf-IDF 向量中,要么在单词向量计数中。后者是使用计数矢量器实现的,但我们将通过使用 Tf-IDF 矢量器获得前者。

Tf-IDF 矢量器为短信中的每个单词创建 TF-IDF 值。Tf-IDF 值的计算方式是为出现频率较低的词赋予较高的值,以便由于英语语法而出现多次的词不会掩盖出现频率较低但更有意义和有趣的词。

lst = x_train.tolist()
vectorizer = TfidfVectorizer(
input= lst ,  # input is the actual text
lowercase=True,      # convert to lowercase before tokenizing
stop_words='english' # remove stop words
)features_train_transformed = vectorizer.fit_transform(list) #gives tf idf vector for x_train
features_test_transformed  = vectorizer.transform(x_test) #gives tf idf vector for x_test

7.训练我们的朴素贝叶斯模型

我们将我们的朴素贝叶斯模型(也称为多项式)拟合到 x_train 的 Tf-IDF 矢量版本,并将真实输出标签存储在 y_train 中。

from sklearn.naive_bayes import MultinomialNB
# train the model
classifier = MultinomialNB()
classifier.fit(features_train_transformed, y_train)

8.检查精确度和 f 值

是时候传入我们对应于 x_test 的 Tf-IDF 矩阵,以及真实的输出标签(y_test)了,来看看我们的模型做得有多好!

首先,让我们看看模型的准确性:

print("classifier accuracy {:.2f}%".format(classifier.score(features_test_transformed, y_test) * 100))

我们的准确度很高!然而,如果我们的模型变得有偏差,这并不是一个很好的指标。因此,我们执行下一步。

9.查看混淆矩阵和分类报告

现在让我们看看我们的混淆矩阵和 f-measure 分数,以确认我们的模型是否正常:

labels = classifier.predict(features_test_transformed)
from sklearn.metrics import f1_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_reportactual = y_test.tolist()
predicted = labels
results = confusion_matrix(actual, predicted)
print('Confusion Matrix :')
print(results)
print ('Accuracy Score :',accuracy_score(actual, predicted))
print ('Report : ')
print (classification_report(actual, predicted) )
score_2 = f1_score(actual, predicted, average = 'binary')
print('F-Measure: %.3f' % score_2)

我们的 f 值是 0.853,我们的混淆矩阵显示我们的模型只做了 61 个错误的分类。在我看来相当不错😊

10.我们混淆矩阵的热图(可选)

您可以使用 seaborn 库创建一个热图来可视化您的混淆矩阵。下面的代码就是这么做的。

这就是制作你自己的垃圾邮件分类器!总而言之,我们导入了数据集并对其进行了可视化。然后我们把它分成 train/test,转换成 Tf-IDF 向量。最后,我们训练了我们的朴素贝叶斯模型,并看到了结果!如果你愿意,你可以更进一步,把它部署成一个 web 应用程序。

参考资料/资源:

[1] D. T,混淆矩阵可视化(2019),https://medium . com/@ dtuk 81/混淆-矩阵-可视化-fc31e3f30fea

  1. C.文斯,朴素贝叶斯垃圾邮件分类器(2018),https://www . code project . com/Articles/1231994/Naive-Bayes-Spam-Classifier
  2. H.Attri,使用 TF-IDF 算法的特征提取(2019),https://medium . com/@ hritikattri 10/Feature-Extraction-using-TF-IDF-algorithm-44 eedb 37305 e
  3. A.Bronshtein,Python 中的训练/测试拆分和交叉验证(2017),https://towardsdatascience . com/Train-Test-Split-and-Cross-Validation-in-Python-80 b 61 beca 4 b 6
  4. 数据集:https://www.kaggle.com/uciml/sms-spam-collection-dataset
  5. 完整代码:https://github . com/samimakhan/Spam-Classification-Project/tree/master/Naive-Bayes

如何使用 Python 构建地理编码 Web 应用程序

原文:https://towardsdatascience.com/how-to-build-your-geocoding-web-app-with-python-133e1e9e2d1a?source=collection_archive---------17-----------------------

易于遵循的指南和教程代码

格伦·卡斯滕斯-彼得斯在 Unsplash 上的照片

我们经常需要将地址转换为地理位置(纬度和经度),这称为地理编码。您可以使用几个免费地理编码 API(当然有限制)。在本教程中,我将向您展示如何创建免费的地理编码应用程序,您可以拖放带有地址的 CSV 文件,并以 CSV 格式获取(下载)地理编码地址。

我们使用 GeopandasStreamlit 用 Python 构建地理编码应用。可选地,你需要一个像 Visual studio 代码这样的 IDE 来运行应用程序。让我们开始吧。我们首先导入库。

下面这张 GIF 展示了我们将要构建的一瞥。它将允许用户上传文件,并通过选择正确的栏目进行互动。

地理编码应用程序-上传 CSV 文件

简化基础知识

web 应用程序使用 Streamlit。Streamlit 是一个简单易用的纯 Python 的 web 应用构建库。我创建了一个 python 文件(app.py ),我们将使用它来编写代码。

让我们首先导入我们需要的库

import time
import base64import streamlit as stimport pandas as pd
import geopandas as gpdimport geopy
from geopy.geocoders import Nominatim
from geopy.extra.rate_limiter import RateLimiterimport plotly_express as px

我们首先创建标题,然后运行应用程序来测试它是否有效。

st.image(“geocoding.jpg”)st.title(“Geocoding Application in Python”)st.markdown(“Uppload a CSV File with address columns (Street name & number, Postcode, City)”)

Streamlit 使用一个定义良好的 API,您可以简单地立即开始使用。看看上面的代码,我打赌你能猜到它是做什么的。在代码的第一行,我们使用st.image()显示一幅图像。在第二行中,我们还使用st.tittle()将测试显示为 tittle。最后,我们使用st.markdown()显示文本。现在,让我们运行应用程序。

运行 Streamlit 就像在终端上写一样简单:

streamlit run app.py

运行应用程序将启动浏览器,如果没有错误,您可以看到应用程序正在运行。图像、标题和文本都在那里(见下图)。我们将继续致力于这个界面。

使用 Streamlit 的地理编码应用程序

上传 CSV 文件

上传文件,我们可以用st.file_upoader()。我们创建一个函数,允许我们使用st.file_upoader()与本地数据进行交互。

我们创建主函数,并在其中上传一个 CSV 文件。一旦 CSV 被上传,我们就可以使用 Pandas 来读取数据并显示数据的前几行。我们将在开发应用程序的过程中编辑这个主菜单。你可以在最后一部分——应用程序中找到这个函数的最终代码。

创建或选择地址列

我们需要一个可能格式化的地址列,在这个应用程序中,因此我们设计,以便它可以接受一个格式良好的列和地理编码或从数据中的列创建地址列。下面是一个格式正确的地址示例。它有街道名称和号码,邮政编码,城市和国家。

Karlaplan 13,115 20,STOCKHOLM, Sweden

以下两个功能允许用户选择他们想要的选项,然后在主菜单功能下处理选择。第一个从 DataFrame 列格式化并创建一个地址列。

下面的第二个函数只是选择一个可能格式化的列作为地址列。

地理编码

我们现在可以开始地理编码,下面的功能使用 nomim 地理编码器。该函数返回包含纬度和经度列的地理编码数据框。

一旦我们对数据进行地理编码,我们就可以在地图上显示它。下面这个函数使用 Plotly Express。要将图形传递给 Streamlit,可以使用st.plotly_chart()。请记住,您可以使用其他库来绘制数据。

下载地理编码 CSV 文件

对数据进行地理编码后,应用程序会再次显示带有纬度和经度的数据框。这将是很好的,也能够下载地理编码的数据。

要下载文件,我们可以编写下面的函数,它允许我们右键单击并用给定的名称保存文件。

该应用程序

将所有代码放在一起,地理编码应用程序代码如下所示。

如果我们愿意,我们可以添加更多的功能,并在此基础上构建其他用例。以下是如何在应用程序中下载地理编码文件的一瞥。

地理编码应用程序-下载地理编码文件

代码也存放在这个 Github 存储库中。

[## shaka som/地理编码

Python 中的地理编码教程。通过在 GitHub 上创建帐户,为 shaka som/地理编码开发做出贡献。

github.com](https://github.com/shakasom/geocoding)

如何构建您的机器学习应用程序

原文:https://towardsdatascience.com/how-to-build-your-machine-learning-application-e2b94c4527b5?source=collection_archive---------78-----------------------

通过 Google App Engine 构建和部署 Dash 应用

这比造一匹马容易多了

今天的机器学习不再是一件新奇或神奇的事情。事实上,所有的在线教程都让它变得和以前一样可行。只需从互联网上抓取大量代码并稍加调试,您的模型就可以运行了。然而,网上几乎没有资源告诉你如何向他人展示你的机器学习进展。无论是为产品原型、你的投资组合,还是向非技术人群解释你的模型的作用,为你的机器学习项目构建一个应用程序总是一个很好的点睛之笔

什么是机器学习应用?让我给你举几个例子:

  • 虚拟个人助理,比如 SiriAlexa 。你的声音被用作输入,他们提取你的话语,并用相应的命令做出回应,通过他们用庞大的数据集训练的模型。
  • 垃圾邮件过滤。关于传入电子邮件的基本信息用于确定电子邮件是否可能是垃圾邮件。
  • 产品推荐。几天前,你在网上购买了一些运动鞋,突然,你和你室友的社交媒体开始收到运动鞋广告。你的浏览历史一些个人信息被用来为你推荐广告。

仔细想想,机器学习应用就在你身边。我必须承认,将一个应用程序工业化需要大量的时间和精力,但我们可以在云基础上构建我们自己的简单机器学习应用程序,而无需考虑所有的极限情况和负载测试。它可以作为一个完美的个人投资组合,或者用于开发测试。在谷歌云服务的帮助下,我们来构建一个应用吧!

第一部分。建立模型

我们将首先为这个应用程序建立我们的模型。让我们只使用虹膜数据集。我们从 Scikit-learn 加载 Iris 数据集,并在其上构建简单的逻辑回归:

第二部分。在本地构建应用程序

然后我们用破折号在本地构建 app。我们的目的是建立一个 web 界面,您可以在其中输入您为遇到的这种鸢尾花测量的不同值,它将返回基于输入预测的最可能的物种。

我们应用的工作流程

我知道这是一大段代码,但是请耐心听我说。首先,我们初始化应用程序。这里要介绍一下 flask,帮助用Google app Engine部署 App。

这里的第二部分是设置应用布局。代码在不同的部分进行了注释,并说明了它们的用途。如果你没有任何前端经验,阅读起来会有点困难,但一定要相信学习过程。这里我们不做任何计算,只是设置零件及其对应的 id。

这里的第三个部分是一个回调函数,它使得应用程序具有“交互性”。输出和输入是在实际函数之前说明的:我们有一个输出,对应于布局部分的输出区域。我们有五个输入,即 GO 按钮和 4 个花朵测量的数字输入。这里使用状态是为了确保应用程序只有在整个表单完成后才从用户那里获取值,你可以在这里了解更多信息。这里的按钮决定只有在你按下按钮后才开始工作。

现在,如果您将所有这些代码放在一个笔记本或 python 文件中,并在本地运行它,您将获得这样的信息作为输出。

代码的输出

只需点击 URL将其粘贴到您的浏览器中,即可访问您构建的应用。请注意,这是 localhost,这意味着其他人无法通过此链接访问它,除非您设置了特殊的防火墙规则。

如果您输入 1 作为值,然后单击 GO 按钮…

第三部分。部署应用程序

我们现在已经有了本地运行的应用程序,但是如果你要和别人分享它,你需要和那个人分享你所有的代码和数据,并让他运行它。仅仅是环境的差异就已经够难调试的了,更不用说如果你把它展示给你根本不会编码的老板。这就是为什么我们需要使用云基础平台来部署它:你只需要配置一次,并通过一个简单的 URL 来共享它,就像这样:https://frankxu.uc.r.appspot.com(你实际上可以点击它并访问这个应用程序)。我们更喜欢谷歌云平台,因为每个用户都有 300 美元/年的免费积分。

在此之前,因为我们需要谷歌云引擎,让我们确保每个人都在同一页面上。你需要设置一个活动的谷歌云项目,然后选择一个项目并启用计费。然后,在你的笔记本电脑上安装设置Google Cloud SDK 工具,这样你就可以通过几行代码轻松部署你的 app。

首先要做的是新建一个文件夹,在这种情况下,我们姑且称之为 破折号 。在 Dash 下我们希望有三个文件: main.py 包含你所有的源代码, app.yaml 包含云部署设置,以及requirements . txt包含所有需要的包。

创建我们需要的文件的代码示例

main.py 中,只需将上面的所有代码按同样的顺序粘贴到其中,或者你也可以在这里访问它。在 app.yaml 中,你会放入这样两行,分别指定你运行的环境和服务器名称。

app.yaml 的内容

requirements . txt中,简单放入一个你用过的 python 包的列表。

requirements.txt 内容

你可以在这里下载这三个文件。现在我们已经为部署做好了一切准备。

打开你的终端,进入 Dash 目录。根据您是否为此项目创建了应用程序,您可能需要先创建一个应用程序。选择应用程序所需的位置,然后在出现提示时输入 Y 继续,并等待几分钟以部署应用程序。

部署完成后,您可以进入 gcloud app 浏览 或者将网址粘贴到您的浏览器来浏览 app。加载需要几秒钟,但你应该会看到云服务的确切应用程序。该应用程序将一直运行,直到您禁用它(转到应用程序引擎下的设置),并且链接是可共享的,这意味着只要有互联网,您就可以将其发送给任何人使用。将应用程序添加到你的作品集也不错,这肯定比普通的简历或演示文稿更令人印象深刻。

下一步是什么?希望本教程结束后,你能够建立自己的机器学习应用程序。玩玩 main.py 就行了,不要改它的初始化和定型部分,有问题多向技术社区学习。整个项目及相关文件可以在 my Github 找到。

如何在 Discord 上构建自己的 AI 聊天机器人?

原文:https://towardsdatascience.com/how-to-build-your-own-ai-chatbot-on-discord-c6b3468189f4?source=collection_archive---------4-----------------------

为初学者创建一个简单的人工智能聊天机器人的最简单方法

亚历山大·奈特Unsplash 上拍照

参与项目是学习过程中最关键的阶段。在这一步,你必须能够将理论上所学的所有技能和知识运用到现实中。当涉及到人工智能或数据科学时,这变得更加重要。

随着我开始更深入地研究这个领域,我意识到找到应用项目并不是一件困难的事情。我们在很多领域几乎不用人工智能。因此,我们可以发现许多新的和不同的应用与其他领域,如医学,工程,会计等。尽管最困难的事情是知道为了完成这个特定的项目应该遵循什么样的步骤。

在这篇文章中,我将与你分享我在 Discord 上创建和构建自己的 AI 聊天机器人的亲身经历。

我在 Discord 上开发和部署的人工智能模型的例子

对于那些从未听说过 Discord 的人来说,这是一个流行的群聊应用,最初是为了给游戏玩家或极客提供一个建立社区和交谈的地方。关于 Discord 有趣的是它有一个开发者门户,在那里你可以做很多有趣的事情,比如部署你自己的 AI 聊天机器人。因此,您需要从这里注册并加入 Discord 开发者门户。

在我们开始真正的工作之前,我们先来谈谈,首先,我建造我的 AI 聊天机器人的步骤。实际上,这个项目是自然语言处理应用的一部分。NLP 或自然语言处理是一种通过人工智能让机器理解人类语言的技术。找出你需要知道的关于它的一切。

现在,我们准备好了。我们开始吧!

1.选择聊天机器人的功能

你的第一个任务是选择你希望你的聊天机器人提供什么服务。会不会只是一个简单的聊天机器人?能够回答正常问题并自己说话?还是希望它在日常工作中帮到你?或者建议每天吃一些健康的食物。好像很棒!不是吗?这第一步有助于了解您必须收集哪些具体数据。如果你的聊天机器人会回答一般的问题,并且是一个正常的说话者,那么你就不需要给它输入专门的文本数据。

照片由斯潘塞·戴维斯Unsplash 拍摄

我在这里提到了两个灵感来源:

  • 健康膳食聊天机器人:聊天机器人会根据你的营养需求(蛋白质、脂肪和碳水化合物)建议一餐。它必须与任何食物数据库相连接,这样它才能搜索到最适合你需求的食物。
  • 提醒聊天机器人:它给你一个关于你的会议和你添加到你的日程中的所有事情的概述。

2.收集或创建文本数据

在这一步中,您可以收集数据平台上可用的文本数据,也可以根据您想要制作的内容创建自己的数据。您可以下载许多开放数据集并根据您的项目进行调整。你可以从这里查看。

如果您想创建自己的数据,最好遵循以下格式,这样您就可以使用我的主代码毫无问题地训练您的模型:

只要遵守格式,您可以添加任意数量的标签。AI 聊天机器人通常会学习所有新句子的模式,并将它们与标签相关联,以获得响应。我们将在下一部分更详细地解释它是如何做到这一点的。

3.构建和训练模型

我们在这个项目中遵循的 NLP 管道如下所示:

当用户写下一个句子并发送给聊天机器人时。该模型遵循 3 个基本步骤。第一步(句子分割)包括将书面文本分成有意义的单元。这些单元是第二步(单词标记化)的输入,其中它们被分成称为“标记”的更小的部分。这些记号对于寻找这种模式非常有用,并且被认为是词干化和词汇化的基础步骤[3]。第三步,词汇化指的是为了分析文本而对文本进行的词汇处理。之后,该模型将预测句子的标签,以便它可以选择适当的响应。

你可以从 这里 查看与这一整部分相关的主要 python 代码。这段代码对于构建和训练模型非常重要。您可以修改它以满足您的项目需求。

4.在不和谐中部署您的模型

一开始,你必须在不和谐开发者门户上注册。完成后,访问Discord 应用页面,点击创建应用。然后写下你的应用程序的名字。

当您点击保存更改时,您现在可以通过点击添加机器人按钮来创建您自己的机器人。之后,您需要通过点击显示令牌来获取和复制您的令牌。

这个令牌在您的 bot 主文件中使用,以便调用它。你需要使用client:run('TOKEN'),用上面复制的令牌替换TOKEN

为了部署您的模型,您必须在主 python 文件的末尾添加以下代码:

不要忘记用您自己的代码来更改“TOKEN”。

一旦你运行了整个 python 代码,你就可以打开你的不和谐,开始和你的 AI 聊天机器人说话。只要你不中断 python 文件的运行,它就会保持在线。

很高兴有机会分享我构建一个简单有效的 AI 聊天机器人的经验。祝你好运!

参考

[1]德文·德尔菲诺,“什么是不和谐?”:关于流行的群聊平台 (2020),商业内幕,技术参考,你需要知道的一切。

[2] Bastien L,Traitement naturel du langage:tout savoir sur Le 自然语言处理 (2019),Le Big Data,杂志 de l'IA。

[3]奎师那,用 NLTK (2019),Guru99,全民教育。

如何使用 Python 构建自己的 AI 个人助理

原文:https://towardsdatascience.com/how-to-build-your-own-ai-personal-assistant-using-python-f57247b4494b?source=collection_archive---------0-----------------------

打造你的 AI 助手指南:

人工智能个人助理是一款理解口头或书面命令并完成客户分配的任务的软件。这是弱人工智能的一个例子,它只能执行用户设计的任务。

想像苹果 Siri、微软 Cortana、谷歌助手一样打造自己的个人 AI 助手?

你可以看看这个博客,通过几个简单的步骤就可以创建一个!

使用 python 编程语言,开发人员最常用的脚本可以用来构建您的个人人工智能助手,以执行用户设计的任务。

图片来源:Freepik

现在,让我们使用 python 为我们的个人语音助手编写一个脚本。

技能:

实现的语音助手可以执行以下任务,它可以打开 YouTube、Gmail、Google chrome 和 stack overflow。预测当前时间,拍摄照片,搜索维基百科以提取所需数据,预测不同城市的天气,从《印度时报》获得头条新闻,还可以回答计算和地理问题。

语音助手的以下查询可以根据用户需要进行操作。

所需软件包:

要构建个人语音助手,需要使用 pip 命令在您的系统中安装以下软件包。

  1. 语音识别 —语音识别是家庭自动化和人工智能设备中使用的一项重要功能。这个库的主要功能是试图理解人类所说的话,并将语音转换成文本。

  2. pyttsx3 — pyttxs3 是 python 中的文本到语音转换库。该软件包支持 Mac os x、Windows 和 Linux 上的文本到语音引擎。

  3. 维基百科 —维基百科是一个多语言的在线百科全书,许多人都在使用它,他们来自学术界,从大一新生到学生,再到希望获得某个特定主题信息的教授。python 中的这个包从维基百科中提取所需的数据。

  4. ecapture —此模块用于从您的相机中捕捉图像

  5. 日期时间 —这是 python 中的一个内置模块,它处理日期和时间

  6. os —该模块是 python 中的标准库,提供与操作系统交互的功能

  7. 时间 —时间模块帮助我们显示时间

  8. Web 浏览器 —这是 python 中的一个内置包。它从网上提取数据

  9. 子进程 —这是一个标准库,用于处理各种系统命令,如注销或重启你的电脑。

10)Json-Json 模块用于存储和交换数据。

  1. 请求 -请求模块用于发送所有类型的 HTTP 请求。它接受 URL 作为参数,并提供对给定 URL 的访问。

12)wolfram Alpha—Wolfram Alpha 是一个 API,它可以使用 Wolfram 的算法、知识库和 AI 技术来计算专家级的答案。Wolfram 语言使之成为可能。

实现:

导入以下库

设置语音引擎:

pyttsx3 模块存储在变量名引擎中。

Sapi5 是微软的文本到语音引擎,用于语音识别。

语音 Id 可以设置为 0 或 1,

0 表示男性声音

1 表示女声

现在定义一个函数 speak 将文本转换成语音。speak 函数将文本作为其参数,进一步初始化引擎。

runAndWait: 该函数在处理所有当前排队的命令时阻塞。它适当地调用引擎通知的回调,并在该调用之前排队的所有命令从队列中清空时返回。

启动问候用户的功能:

为人工智能助手定义一个函数 wishMe 来问候用户。

现在()。hour 函数抽象当前时间的小时。

如果小时数大于零小于 12,语音助手会提示您“早上好”。

如果小时数大于 12 小于 18,语音助手会用下面的消息祝您“下午好”。

否则它会发出“晚上好”的信息

为您的人工智能助手设置命令功能:

定义一个函数 takecommand 让人工智能助手理解并接受人类语言。麦克风捕获人类语音,识别器识别语音以给出响应。

异常处理用于处理运行时错误期间的异常,并且 recognize_google 函数使用 google audio 来识别语音。

主要功能:

主函数从这里开始,人类给出的命令存储在变量语句中。

如果在用户给出的语句中有以下触发词,它调用虚拟助理说出以下命令。

技能 1——从维基百科获取数据:

以下命令有助于从维基百科中提取信息。 wikipedia.summary() 函数有两个参数,用户给出的语句和需要从维基百科中提取多少句子存储在变量结果中。

技能 2——访问网络浏览器——谷歌浏览器、电子邮件和 YouTube:

网络浏览器从网络上提取数据。 open_new_tab 函数接受 URL 作为需要访问的参数。

Python 时间休眠函数用于增加程序执行的延迟。我们可以使用这个函数在给定的时间内暂停程序的执行。

技巧三——预测时间:

当前时间从 datetime.now() 函数中提取,该函数显示时、分、秒,并存储在变量名 strTime 中。

技能 4-获取最新消息:

如果用户想知道最新的新闻,语音助手被编程为通过使用网络浏览器功能从《印度时报》获取头条新闻。

技能 5-拍摄照片:

ec.capture() 功能用于从相机中捕捉图像。它接受 3 个参数。

摄像头索引 —第一个连接的摄像头将显示为索引 0,下一个摄像头将显示为索引 1

窗口名 —可以是变量,也可以是字符串。如果您不想看到该窗口,请键入 False

保存名称 —可以给图像命名,如果您不想保存图像,请输入 false

技能 6-从网上搜索数据:

网络浏览器中,通过将用户语句(命令)传递给 open_new_tab() 函数,您可以搜索所需的数据。

用户 : 嘿 G-One,请搜索蝴蝶的图片

语音助手打开谷歌窗口&从网络上获取蝴蝶图像。

技能 7-设置您的人工智能助手来回答地理和计算问题:

这里我们可以使用名为 Wolfram alpha API 的第三方 API 来回答计算和地理问题。Wolfram 语言使之成为可能。客户端是为 wolfram alpha 创建的实例(类)。 res 变量存储 wolfram alpha 给出的响应。

要访问 wolfram alpha API,需要一个唯一的应用 ID,可通过以下方式生成:

  1. 登录 wolfram alpha 的官方页面,如果您没有帐户,请创建一个帐户。

作者图片

2.使用您的 wolfram ID 登录

作者图片

3.现在你将看到网站的主页。前往右上角的帐户部分,在那里您可以看到您的电子邮件。在下拉菜单中,选择我的应用程序(API)选项。

作者图片

4.您将看到以下窗口,现在单击获取 APP_ID 按钮

作者图片

5.现在,您将看到以下对话框,给出一个合适的名称和描述,然后单击应用程序 ID 按钮,将生成一个应用程序 ID,这是一个唯一的 ID。使用 App Id use 可以访问 Wolfram alpha API。

作者图片

人类 :嘿 G-One,加州的首府是哪里?

G-One 语音助手: 美国萨克拉门托

技能 8-额外功能:

让你的人工智能助手回答以下问题会很有趣,比如它能做什么,谁创造了它,不是吗?

技能 9-预测天气:

现在,为了让你的人工智能助手检测天气,我们需要从打开的天气图中生成一个 API 键。

开放式天气地图是一项提供天气数据的在线服务。通过在官网生成一个 API ID,你可以使用 APP_ID 让你的语音助手在任何需要的时候检测所有地方的天气。这个天气检测需要导入的必要模块是 json 和 request 模块。

city_name 变量使用 takeCommand() 函数接受人类给出的命令。

请求模块的 get 方法返回一个响应对象。response 对象的 json 方法将 json 格式的数据转换成 python 格式。

变量 X 包含嵌套字典列表,该列表检查“COD”的值是否为 404,即是否找到了城市。

温度和湿度等数值存储在变量 Y 的主键中。

人类: 嘿 G-One,我想获取天气数据

G-One: 城市名是什么?

人类: 喜马偕尔邦

G-One: 开尔文单位的温度为 301.09,百分比湿度为 52,描述为小雨。

技能 10-注销您的电脑:

这里的 subprocess.call() 函数用于处理系统函数,以注销或关闭您的 PC。这将调用你的人工智能助手自动关闭你的电脑。

万岁,我们终于打造了自己的 AI 语音助手。此外,你还可以给你的人工智能语音助手添加更多的功能来执行更多的任务。

作者图片

查看我的 GitHub 个人资料以获取代码:

https://github . com/mmirthula 02/AI-Personal-Voice-assistant-using-Python

编码快乐!!

如何使用深度学习构建自己的聊天机器人

原文:https://towardsdatascience.com/how-to-build-your-own-chatbot-using-deep-learning-bb41f970e281?source=collection_archive---------0-----------------------

实现智能聊天机器人解决方案的全面分步指南

如果您对开发聊天机器人感兴趣,您会发现有很多强大的机器人开发框架、工具和平台可以用来实现智能聊天机器人解决方案。使用深度学习,而不是使用任何 bot 开发框架或任何其他平台,从零开始开发一个简单、智能的聊天机器人怎么样?在本教程中,您可以了解如何使用深度学习和 Keras 开发端到端的特定领域智能聊天机器人解决方案。

来自 flickr萨姆·伍德的照片

概念

在进入编码部分之前,首先,我们需要理解一些设计概念。由于我们要开发一个基于深度学习的模型,我们需要数据来训练我们的模型。但我们不会收集或下载任何大型数据集,因为这是一个简单的聊天机器人。我们可以创建自己的数据集来训练模型。为了创建这个数据集,我们需要理解我们要训练的意图是什么。“意图”是用户与聊天机器人交互的意图,或者聊天机器人从特定用户接收的每条消息背后的意图。根据您正在开发的聊天机器人解决方案的领域,这些意图可能会因聊天机器人解决方案的不同而不同。因此,了解你的聊天机器人与你将要工作的领域相关的正确意图是很重要的。

那为什么它需要定义这些意图呢?这是需要理解的非常重要的一点。为了回答问题、从领域知识库中搜索和执行各种其他任务来继续与用户对话,你的聊天机器人真的需要理解用户说什么或他们打算做什么。这就是为什么你的聊天机器人需要理解用户信息背后的意图(来识别用户的意图)。

如何让你的聊天机器人理解用户的意图,让用户觉得它知道他们想要什么,并提供准确的回答。这里的策略是定义不同的意图,并为这些意图制作训练样本,并使用这些训练样本数据作为模型训练数据(X)和意图作为模型训练类别(Y)来训练您的聊天机器人模型。

履行

必需的包

所需的 python 包如下,(这里我提到了我在开发中使用的包的版本)

定义意图

我将定义几个简单的意图和对应于这些意图的一堆消息,并根据每个意图类别映射一些响应。我将创建一个名为“intents.json”的 JSON 文件,包括如下数据。

数据准备

首先我们需要导入所有需要的包

现在我们加载 json 文件并提取所需的数据。

变量“ training_sentences ”保存所有的训练数据(即每个意图类别中的样本消息),变量“ training_labels ”保存每个训练数据对应的所有目标标签。

然后我们使用 scikit-learn 提供的“ LabelEncoder() ”函数将目标标签转换成模型可理解的形式。

接下来,我们通过使用“记号赋予器”类对我们的文本数据语料库进行矢量化,它允许我们将词汇量限制到某个定义的数字。当我们使用这个类进行文本预处理任务时,默认情况下,所有标点符号都将被删除,将文本转换为空格分隔的单词序列,然后这些序列被拆分为标记列表。然后它们将被索引或矢量化。我们还可以添加“oov_token ”,它是“out of token”的一个值,用于在推理时处理词汇表之外的单词(token)。

使用“ pad_sequences ”方法使所有的训练文本序列大小相同。

模特培训

让我们为提议的模型定义我们的神经网络架构,为此我们使用 Keras 的“顺序”模型类。

我们的模型架构如下所示。

现在我们准备训练我们的模型。简单地说,我们可以用训练数据和标签调用“ fit ”方法。

训练后,最好保存所有需要的文件,以便在推理时使用。以便我们保存训练的模型、拟合的记号赋予器对象和拟合的标签编码器对象。

推理

好吧!!!!现在是时候检查我们的模型表现如何了。😊

我们将实现一个聊天功能,与一个真正的用户互动。当收到新的用户消息时,聊天机器人将计算新文本序列和训练数据之间的相似度。考虑到每个类别的置信度得分,它将用户消息分类到具有最高置信度得分的意图。

你可以看到它的工作非常完美!!!

与聊天应用程序集成

此外,您可以将训练好的聊天机器人模型与任何其他聊天应用程序集成,以便更有效地与现实世界的用户打交道。

我已经使用 flask 开发了一个应用程序,并将这个经过训练的聊天机器人模型与该应用程序集成在一起。

最终的解决方案是这样的,

最后的想法

我们讨论了如何从头开始使用深度学习开发聊天机器人模型,以及我们如何使用它来与真实用户互动。通过这些步骤,任何人都可以实现自己的与任何领域相关的聊天机器人。

作为进一步的改进,您可以尝试不同的任务来增强性能和功能。

  • 使用更多数据进行训练:您可以向训练数据集中添加更多数据。一个包含大量意图的大型数据集可以产生一个强大的聊天机器人解决方案。
  • 应用不同的自然语言处理技术:您可以向您的聊天机器人解决方案添加更多的自然语言处理解决方案,如 NER (命名实体识别),以便为您的聊天机器人添加更多的功能。有了 NER 模型和你的聊天机器人,你可以很容易地找到任何出现在用户聊天信息中的实体,并使用它进行进一步的对话。你还可以添加一个情感 分析模型来识别用户信息背后不同的情感基调,它会给你的聊天机器人增添一些色彩。
  • 尝试不同的神经网络架构:你也可以用不同的超参数尝试不同的神经网络架构。
  • 添加表情符号:你也可以在建立你的模型时考虑表情符号。

您可以从 Github 资源库中找到本文的源代码。

希望你喜欢这篇文章,并继续关注另一篇有趣的文章。另外,我很高兴听到你的反馈。

如何为数据科学项目构建自己的数据集

原文:https://towardsdatascience.com/how-to-build-your-own-dataset-for-data-science-projects-7f4ad0429de4?source=collection_archive---------11-----------------------

听说过 BYOD:构建自己的数据集吗?

马库斯·斯皮斯克在 Unsplash 上的照片

当我们谈论数据科学时,排在前面的是数据。

当我开始我的数据科学之旅时,它是芝加哥犯罪数据集或葡萄酒质量或沃尔玛销售——我可以得到的常见项目数据集。接下来,当我进行 IBM 数据科学专家认证时,我了解了 API 和对健壮数据集的访问,但这是有代价的!

对于一个初学数据的科学家来说,困境肯定是——学完理论后该做什么?当然,有大量的数据集可用,但免费的数据集很少给你解决实际问题的务实见解,或者有时它们太小,无法用于深度学习应用。

你想从一个项目开始,构建一个模型,运行结果,并积极寻找一个数据集?为什么不构建自己的数据集呢?

不用说,第一个选择是网络抓取。因此,在这个故事中,我将从介绍数据科学项目的数据类型和公认的数据格式开始,接下来,我将说明一种古怪的方式来废弃 Google 的独家数据集(这本身就是一个项目!)

注意:这需要 Python 的工作知识,并理解在 Python 中读写不同的文件格式。

数据科学中的数据类型介绍

作者图片

a.数据

离散数据

离散数据具有不同且独立的值。例如:100 次抛硬币中的人头数。离散数据只有在具有确定值的情况下才会出现。这种类型的数据无法测量,但可以计数。

连续数据

连续数据表示可以测量的数据,具有单位,因此可以参与数学计算。例子:年龄,身高,体重,工资。连续数据可以用实数线上的区间来描述。

区间数据

区间值表示两个区间之间具有相同差值的有序单位。因此,当我们有一个包含有序数值的变量,并且我们知道这些数值之间的确切差异时,我们称之为区间数据。例如:60 度和 50 度之间的差是可测量的 10 度,80 度和 70 度之间的差也是可测量的 10 度。

比率数据

比率值也是具有相同差值的有序单位。比率值与区间值相同,不同之处在于它们有一个绝对零点。很好的例子是身高、体重、长度等。

比率数据可以相加、相减、相乘、相除,具有集中趋势的测量值—平均值、中值、众数、标准偏差和变异系数。

b.分类数据

分类数据代表数据的特征。它可以是任何像一个人的性别,语言,收入≥50K 或<50K etc. Categorical data can also take on numerical values like 1 for female and 0 for male. (Note that those numbers don’t have mathematical meaning).

Nominal Data

Nominal values represent discrete and unordered units and are used to label variables that have no quantitative value. When I say unordered, that means nominal data that has no order. Examples:

  1. Colors — red, green, yellow, blue, orange
  2. Seasons — Fall, Winter, Summer, Spring
  3. Type of bank accounts — Checking, Savings
  4. States — Illinois, New York, California, Michigan

Therefore, even if you change the order of values for nominal data, the meaning remains unchanged. A type of nominal data that contains only two categories (male and female) is called 二分法

序数数据

序数值表示离散的和有序的单位。因此,除了排序问题之外,它几乎与名义数据相同。示例:

  1. 字母等级— A、B、C、D、F
  2. 服装尺寸——XS,小号,中号,大号,大号,XXL
  3. 排名— 1、2、3
  4. 教育——小学、高中、学士、硕士

由于有序性,序数数据通常用于处理非数字特征,如快乐、客户满意度等。

数据科学中可以使用的其他数据类型有:

  1. 图像
  2. 声音的
  3. 录像
  4. 文本
  5. 时间序列

1.图像

a.自带设备

作者图片

我确信我们每个人都曾是图像的收藏者。小狗,猫,演员,异国旅行目的地。这里什么都能用😄

在一生中,你会没有项目可做。

问题陈述:

  1. 识别幼犬的品种
  2. 检测小狗的情绪

从你的硬盘里找出你一生中所有的小狗图片。从 OpenCV、Python 图像库或 matplotlib 库开始读取图像。确保所有的图片都是一种文件格式:jpeg 或 png。一旦读取了图像,您就可以像使用 Googled 数据集构建任何其他模型一样进行操作。分成 70%–30%的训练和测试数据集,使用一些进行验证,您就得到您的数据集了!

想过吗?

b.网页抓取

信不信由你,使用 Python 中的 google-image-downloader 下载一堆图像很容易

pip install googleimagedownloader

接下来,确保你有谷歌浏览器。获取与您正在运行的 Google Chrome 版本相对应的 Chromedriver 版本,并使用以下命令行代码从 Google Chrome 批量下载图像

$ googleimagesdownload -k "puppies" -s medium -l 200 -o dataset/train -i puppies -cd ~/chromedriver

该命令将使用关键字“小狗”从谷歌图片中抓取 200 张图片。它会将这些图像输出到:dataset/train/puppies/-cd参数指向我们之前下载的“chromedriver”可执行文件的位置。

声音好听吗?

2.声音的

泰勒·斯威夫特、阿里吉特·辛格、黑粉红、BTS、J·巴尔文——从全球范围内选择你最喜欢的。

问题陈述:从音频文件中识别语言。

要构建自己的音频数据集,请在一个地方收集歌曲(音频文件)。唯一乏味的事情是收集足够多的歌曲来建立一个基于训练数据的模型,验证并测试它。其次,在 Python 中导入 mp3 文件可能是一项任务。

为了方便起见,我建议先把 mp3 文件转换成 WAV。你可以按照文档中关于如何在 Python 中读写 WAV 文件来开始你的工作。wave模块为 WAV 声音格式提供了一个方便的接口。

获得多样化音频的另一种方法是从 soundcloud 获取文件。互联网上有一些工具可以用来从 Soundcloud 下载 mp3 格式的音频。这无疑是一条漫长的道路,但是一旦你有了音频文件,就按照你在 Python 中对音频文件项目的理想做法去做。

3.录像

猜猜任何数量的游戏日期编辑工作!😛

问题陈述:

  1. 识别一个人是否戴着口罩
  2. 确定是否遵循了社交距离衡量标准——人与人之间的距离
  3. 家庭安全系统——认识这个人吗?

对于视频,数据科学项目主要是面部识别项目,鉴于非常时期,许多类似于上述问题陈述的项目是由来自世界各地的数据科学家构建的。

为了建立一个视频数据集,你的来源可以是你的家庭视频,你戏弄你的兄弟姐妹,基本上是任何有人形和移动的东西。OpenCV 将再次成为你的英雄。OpenCV 提供了一个非常简单的接口来读取、写入和显示视频。

读取视频文件的第一步是创建一个 VideoCapture 对象。接受的视频格式是 mp4 ,我相信它不需要美国格式转换,除非在 iPhones 上拍摄。

接下来,您可以应用面部识别算法来解决问题。

4.文本

接下来是从你的 Fitbit 或 iWatch 获取数据。

在我的一篇博客中,一位读者对这个数据科学项目的想法发表了评论,我在这里写的是如何创建自己的数据集!

如果你使用任何可穿戴设备,这可能会成为一个有趣的数据集——按照一般数据保护法规汇编的公司应该以良好格式的 csv 文件发送你的所有个人数据。接下来你知道的就是分析你自己的数据!

我最近从 Fitbit 下载了两年的健康数据。您可以按照流程从这里导出您的 Fitbit 账户数据。

感谢您的阅读!我希望你喜欢这篇文章。请务必让我知道,在您的数据科学之旅中,您希望在这个夏天构建和处理哪些数据集。

快乐数据 Tenting!

免责声明:本文表达的观点仅代表我个人,不代表严格的观点。

了解你的作者

拉什是芝加哥伊利诺伊大学的研究生。她喜欢将数据可视化,并创造有见地的故事。当她不赶着赶学校的最后期限时,她喜欢喝一杯热巧克力,写一些关于技术、UX 等的东西。

如何建立自己的 YouTube 评论数据集

原文:https://towardsdatascience.com/how-to-build-your-own-dataset-of-youtube-comments-39a1e57aade?source=collection_archive---------8-----------------------

应用自然语言处理技术理解最新的黑粉色回归

使用 YouTube 数据 API 收集评论

基思·皮茨在 Unsplash 上的照片

这是涵盖文本数据收集、数据预处理和情感分析的系列文章的第一篇。在这篇文章中,我将具体谈谈为什么我想从 Blackpink 的最新音乐视频 中收集评论,你如何喜欢那个 ,然后向你介绍如何从任何你想要的视频中建立你自己的 YouTube 评论数据集。

如果你想切入正题,立即开始收集评论,你可以按照我的回购脚本:

[## xwillamy/custom _ yt _ comments _ dataset

你应该首先建立一个虚拟环境。您可以通过输入以下内容来创建 Python 3 虚拟环境…

github.com](https://github.com/XWilliamY/custom_yt_comments_dataset)

要不,我们开始吧!

为了这个项目,我对分析 Blackpink 最新音乐视频的 YouTube 评论很感兴趣,该视频于 2020 年 6 月 26 日发布,名为How You Like That。**

黑粉色——“你觉得那辆 M/V 怎么样?”

通过打破 24 小时内观看次数最多的 YouTube 剪辑、24 小时内观看次数最多的 K-Pop act、 和最快达到 2 亿观看次数的视频等记录,Blackpink 向世界展示了它是一个值得重视的团体。然而,在《你喜欢怎样》之前,该组合的最后一张专辑 Kill this Love 于一年多前的 2019 年 4 月 4 日发行。从那时起到 2020 年 6 月 26 日,只剩下一首歌,与 Lady Gaga 合作的一首名为“酸糖的歌曲。既然 Blackpink 已经为它的粉丝增添了更多关于他们自己的内容,我很想知道 blings(black pink 的官方粉丝名称)是如何回应的。

粉丝们对这四名成员和他们的经纪人 YG 有什么看法?他们对 Blackpink 的最新歌曲和个人成员有什么看法?这些情绪在不同的语言中有所不同吗?

这些指导性问题促使我对他们音乐视频的评论进行情感分析。我选择 YouTube 作为数据源,不仅因为它是一个受欢迎的社交媒体平台,还因为它是第二大搜索引擎,截至 2017 年每月有 30 亿次搜索。这使得它成为娱乐公司推广其艺人新单曲和专辑的宝贵资源。此外,由于每个视频都附有评论部分,这些宣传视频也成为粉丝与艺术家和其他粉丝直接接触的论坛。

除此之外,我还想挑战自己,从头开始构建和清理数据集。我鼓励您也这样做,原因如下:

  1. 接触网络抓取和使用 API:了解如何收集数据对于扩充现有数据集或创建新数据集来解决您可能对某个主题的疑问和假设非常有用。
  2. 对数据进行更好的自定义:您可以更好地控制要包含在自定义数据集中的要素,并且可以在分析数据时根据需要进行更改。
  3. 实践数据清理技术:通常情况下,公开可用的数据集已经被清理和修剪到一定程度。与此同时,由于俚语、缩写、拼写错误、表情符号以及讽刺和挖苦,YouTube 评论和一般社交媒体文本很难处理。清理这些类型的文本将迫使你考虑每种技术的有效性和后果。

对于这个项目,我选择通过 YouTube 的数据 API 查询评论来熟悉 API。下面几节将向您介绍我是如何收集感兴趣的评论的。假设您对 Python 有所了解。我还包含了对 API 和 JSON 的简短介绍。如果您已经熟悉它们,您可以直接跳到数据收集部分。

API 和 JSON 快速入门

什么是 API?

**资料来源:Scopus,【https://blog.scopus.com/file/what-is-an-apijpg **

API 是应用编程接口的缩写。它的作用是将用户的请求发送给服务提供者,然后将服务提供者生成的结果返回给用户。 Geeksforgeeks 使用了在在线网站上搜索酒店房间的例子;API 将用户的请求发送到酒店预订的网站,然后从网站返回最相关的数据给预定的用户。从这个意义上说,API,尤其是那些由大公司生产的 API,为用户提供了获取感兴趣的数据的工具。

JSON 是什么?

例子来自 https://www.shapediver.com/blog/json-objects-explained/shape diver

根据 w3schools,JSON,JavaScript Object Notation 的缩写,是一种存储和传输数据的轻量级格式。JSON 的语法与 Python 中的字典非常相似。JSON 用花括号表示,它的数据存储在用逗号分隔的 key:value 对中。

了解这种数据格式很重要,因为它是 API 响应的最常见格式。例如,YouTube 数据 API 提供的响应是一个 JSON 对象。

数据收集

关于设置 YouTube API 证书的快速教程

1.前往谷歌开发者控制台并创建一个新项目。

单击向下箭头按钮

选择新项目选项(或选择现有项目)

并给它一个名字!

2.一旦你建立了一个新的项目,选择+启用 API 和服务

4.搜索 YouTube 数据 API v3 并点击启用。

5.然后回到凭证。你可以点击汉堡菜单,☰

6.选择+创建凭据,然后选择 API 密钥。

根据开发者文档,我们不需要用户授权来获取关于公共 YouTube 频道的信息,所以我们只需要一个 API 密钥来收集视频评论。

7.最后,安装 Python 的 Google API 客户端。

**pip install --upgrade google-api-python-client**

如果你很好奇,你可以在这里阅读更多关于用 Python 设置 Google APIs 的内容:

** [## Python 快速入门| YouTube 数据 API | Google 开发者

本快速入门指南解释了如何设置一个简单的 Python 命令行应用程序,该应用程序向…

developers.google.com](https://developers.google.com/youtube/v3/quickstart/python)

使用 YouTube 数据 API v3 查询 YouTube 评论

设置好凭据后,我们现在就可以开始收集评论了!我们将首先构建调用 YouTube API 的服务:

现在让我们来看看感兴趣的资源。为了获得 YouTube 上对特定视频的所有评论,我们需要发送一个对 CommentThreads 的请求。Python 中对 commentThread 的请求示例如下所示:

# you only need to build the service once
service = build_service('path/to/apikey.json') response = service.commentThreads().list(
        part='snippet',
        maxResults=100,
        textFormat='plainText',
        order='time',
        videoId='ioNng23DkIM'
).execute()

在上面列出的参数中,有两个参数是必需的,**part**以及**allThreadsRelatedToChannelId****channelId****id****videoId**中的一个。对于**part**参数,我们需要传递一个由**id****snippet****replies**的任意组合组成的逗号分隔列表。**snippet** 关键字将返回关于评论线程和线程的顶级评论的基本细节,而 replies 包含对顶级评论的回复列表。

第二个必需的参数是一个过滤器,我们可以在**allThreadsRelatedToChannelId****channelId****id****videoId**之间选择。由于我只对 Blackpink 的你喜欢那个的 YouTube 评论感兴趣,所以我选择了按**videoId**过滤。

一个视频的 ID 可以从它的 YouTube 链接中获得。它们通常看起来像这样:

[https://www.youtube.com/watch?v=ioNng23DkIM](https://www.youtube.com/watch?v=ioNng23DkIM)

在这种情况下,视频 ID 将为 ioNng23DkIM。一般来说,视频 ID 跟在?v= '。

但有时链接可能如下所示,例如当您通过视频上的共享选项获得链接时:

[https://youtu.be/ioNng23DkIM](https://youtu.be/ioNng23DkIM)

在这种情况下,ID 将直接位于“youtu.be”之后。

我们可以用跟随函数的来处理这两种情况(尽管如果你要手动获取 YouTube 视频链接,这是不必要的。如果是这样的话,可以只复制链接的 ID 部分。)

决定感兴趣的项目

对于这个项目,我只对顶级评论、回复和喜欢的数量以及评论者是否也对视频进行了评级(喜欢)感兴趣,所以我只将字符串“snippet”传递给参数部分。

运行上面的代码后,您将得到一个 JSON 响应,其中的看起来像下面的:

{
  "kind": "youtube#commentThreadListResponse",
  "etag": etag,
  "nextPageToken": string,
  "pageInfo": {
    "totalResults": integer,
    "resultsPerPage": integer
  },
  "items": [
    [commentThread Resource](https://developers.google.com/youtube/v3/docs/commentThreads#resource)
  ]
}

感兴趣的项目是**nextPageToken****items**。先来说说**items**。关键字**items**包含一个**commentThreads**列表,每个**commentThread**由后面的组成:

{
  "[**kind**](https://developers.google.com/youtube/v3/docs/commentThreads#kind)": "youtube#commentThread",
  "[**etag**](https://developers.google.com/youtube/v3/docs/commentThreads#etag)": **etag**,
  "[**id**](https://developers.google.com/youtube/v3/docs/commentThreads#id)": **string**,
  "[**snippet**](https://developers.google.com/youtube/v3/docs/commentThreads#snippet)": {
    "[**channelId**](https://developers.google.com/youtube/v3/docs/commentThreads#snippet.channelId)": **string**,
    "[**videoId**](https://developers.google.com/youtube/v3/docs/commentThreads#snippet.videoId)": **string**,
    "[**topLevelComment**](https://developers.google.com/youtube/v3/docs/commentThreads#snippet.topLevelComment)": [**comments Resource**](https://developers.google.com/youtube/v3/docs/comments#resource),
    "[**canReply**](https://developers.google.com/youtube/v3/docs/commentThreads#snippet.canReply)": **boolean**,
    "[**totalReplyCount**](https://developers.google.com/youtube/v3/docs/commentThreads#snippet.totalReplyCount)": **unsigned integer**,
    "[**isPublic**](https://developers.google.com/youtube/v3/docs/commentThreads#snippet.isPublic)": **boolean**
  },
  "[**replies**](https://developers.google.com/youtube/v3/docs/commentThreads#replies)": {
    "[**comments**](https://developers.google.com/youtube/v3/docs/commentThreads#replies.comments[])": [
      [**comments Resource**](https://developers.google.com/youtube/v3/docs/comments#resource)
    ]
  }
}

因为我选择只将字符串**snippet**传递给 part 参数,所以我将只获得上面 JSON 资源的**snippet**部分。**snippet**是包含**channelId****videoId****topLevelComment****canReply****totalReplyCount****isPublic**的键和相应值的字典。

在这些资源中,我选择保存**topLevelComment****totalReplyCount**的值。然而,我们仍然没有访问到**topLevelComment**的实际文本内容。我们可以提取文本、顶级评论收到的赞数,以及评论者是否也通过索引到**topLevelComment**对象中对视频进行了评级。它是一个注释资源,看起来像这样:

{
  "[**kind**](https://developers.google.com/youtube/v3/docs/comments#kind)": "youtube#comment",
  "[**etag**](https://developers.google.com/youtube/v3/docs/comments#etag)": **etag**,
  "[**id**](https://developers.google.com/youtube/v3/docs/comments#id)": **string**,
  "[**snippet**](https://developers.google.com/youtube/v3/docs/comments#snippet)": {
    "[**authorDisplayName**](https://developers.google.com/youtube/v3/docs/comments#snippet.authorDisplayName)": **string**,
    "[**authorProfileImageUrl**](https://developers.google.com/youtube/v3/docs/comments#snippet.authorProfileImageUrl)": **string**,
    "[**authorChannelUrl**](https://developers.google.com/youtube/v3/docs/comments#snippet.authorChannelUrl)": **string**,
    "[**authorChannelId**](https://developers.google.com/youtube/v3/docs/comments#snippet.authorChannelId)": {
      "[**value**](https://developers.google.com/youtube/v3/docs/comments#snippet.authorChannelId.value)": **string**
    },
    "[**channelId**](https://developers.google.com/youtube/v3/docs/comments#snippet.channelId)": **string**,
    "[**videoId**](https://developers.google.com/youtube/v3/docs/comments#snippet.videoId)": **string**,
    "[**textDisplay**](https://developers.google.com/youtube/v3/docs/comments#snippet.textDisplay)": **string**,
    "[**textOriginal**](https://developers.google.com/youtube/v3/docs/comments#snippet.textOriginal)": **string**,
    "[**parentId**](https://developers.google.com/youtube/v3/docs/comments#snippet.parentId)": **string**,
    "[**canRate**](https://developers.google.com/youtube/v3/docs/comments#snippet.canRate)": **boolean**,
    "[**viewerRating**](https://developers.google.com/youtube/v3/docs/comments#snippet.viewerRating)": **string**,
    "[**likeCount**](https://developers.google.com/youtube/v3/docs/comments#snippet.likeCount)": **unsigned integer**,
    "[**moderationStatus**](https://developers.google.com/youtube/v3/docs/comments#snippet.moderationStatus)": **string**,
    "[**publishedAt**](https://developers.google.com/youtube/v3/docs/comments#snippet.publishedAt)": **datetime**,
    "[**updatedAt**](https://developers.google.com/youtube/v3/docs/comments#snippet.updatedAt)": **datetime**
  }
}

我们可以对响应进行如下索引:

comment = response['items']['snippet']['topLevelComment']['snippet']['textDisplay']

综上所述,我们可以使用下面的代码片段来获得感兴趣的数据点。

如果您对额外的数据点感兴趣,比如评论更新的时间,您可以这样写:

published_at = item['snippet']['topLevelComment']['snippet']['updatedAt']

对于**commentThreads**资源来说,另一个有趣的价值是**nextPageToken**。每当我们提交一个请求,我们就会在**items**列表中获得**maxResults** 个评论。我们可以获得的最大结果数限制在 1 到 100 之间。因此,如果一个视频有超过 100 条评论,我们将需要多次调用 API。**nextPageToken**帮助我们直接从下一页开始评论,而不是从头再来。我们只需要稍微修改一下我们的 API 调用:

response = service.commentThreads().list(
    part='snippet',
    maxResults=100,
    textFormat='plainText',
    order='time',
    videoId='ioNng23DkIM',
    pageToken=response['nextPageToken']
).execute()

注意,我们的第一次服务调用不需要**nextPageToken**。相反,我们使用从当前 JSON 响应中获得的**nextPageToken**来调用服务对象。

把所有的放在一起

下面的函数将帮助我们从 YouTube 视频中获取评论:

如果你觉得合适,可以随意改变功能!在导入必要的库(#1)之后,我更改了函数的参数,以包含一个额外的变量 csv_filename (#2)。#3、#5 和#6 中概述了保存感兴趣特征的列表、为这些数据点建立索引的代码以及将数据点保存到列表中的代码。然后,我将 JSON 响应中每一项的所需特性逐行保存到 csv 文件(#7)。在我们检查了 JSON 响应中的每一项之后,我们检查是否有 nextPageToken (#8)。如果没有,我们将以字典的形式返回我们感兴趣的数据点(#9)。

后续步骤

为了使这个程序更加模块化,我们还可以做更多的事情。例如,我们可以编写一个函数,接受一个关键字列表并返回一个包含每个给定关键字相关信息的字典,而不是为每个特性编写一个硬编码列表(#2、#5)。我们还可以编写一个字典来映射长的、复杂的索引,比如将published_at映射到速记。例如:

shorthand = {
    'updated_at' : item['snippet']['topLevelComment']['snippet']['updatedAt']
}

这将涉及到第一次的一些工作,以简化以后的事情。幸运的是,这些函数(以及更多)已经在包装器库中可用 youtube-data-api

然而,如果你想收集现成的评论,我的 repo 包含如何运行提供的脚本get _ comments _ of _ video _ id . py的说明。

请注意,Google 确实对您可以进行的 API 调用数量设置了每日限额。这个额度定在每天 1 万条左右,变成我一天能收集到的差不多 25 万条评论。为了解决这些限制,我创建了两个 API 键来收集更多的注释。

包扎

在本文中,我们了解了如何使用 YouTube 数据 API (v3)从感兴趣的视频中收集 YouTube 评论。在我的下一篇文章中,我们将遵循经典的 NLP 管道来预处理我们的数据以进行情感分析。

感谢您跟随我踏上数据科学之旅!**

如何从维基百科建立你自己的领域数据集或语料库

原文:https://towardsdatascience.com/how-to-build-your-own-datasets-or-corpora-from-wikipedia-3eb35d78baac?source=collection_archive---------35-----------------------

维基百科(Python 库)|美汤| MediaWikiAPI | DBpedia | SPARQL

Unsplash 上由 James L.W 拍摄的照片

维基百科是 21 世纪最值得信赖和众包的数字信息财富,如果有任何疑问,我们可以参考它来回答问题,了解网络系列的情节,找到电影演员的生物数据,了解更多关于世界伟大领袖或震撼地球的灾难,了解过去和未来。

太戏剧化了,是吧?

维基百科是一个创建丰富数据集或语料库的伟大平台,因为它有自然语言内容以及名为 DBpedia 的语义结构化数据库。

本博客讨论了两种简单、快速和轻量级的方法来管理特定领域的数据集或从维基百科构建 coropra 来训练机器学习模型。

那么,让我们来看看这些丰富的知识如何成为你下一个项目的输入数据。

方法 1:使用维基百科的传统抓取

这是你一定已经熟悉的东西——网络抓取。旁边还有美汤,维基百科现在有自己的刮痧库( pypi 链接)。

下面是一个简单的程序,使用维基百科,python 库,来抓取内容。

import wikipediaresults_list = wikipedia.search("<your_search_term>")wiki_search_results = []for each_result in results_list:
    wiki_page_result = {}
    wiki_page_obj = wikipedia.page(each_result)
    wiki_page_result['title'] = wiki_page_obj.title
    wiki_page_result['content'] = wiki_page_obj.content
    wiki_page_result['url'] = wiki_page_obj.url
    wiki_page_result['links'] = wiki_page_obj.links
    wiki_search_results.append(wiki_page_result)

限制:

这种方法的局限性是无论如何都不会刮擦表。

解决方案:

BeautifulsoupMediaWikiAPI

以下是使用 MediaWikiAPI 和 Beautifulsoup 从维基百科页面提取表格的示例代码:

from mediawikiapi import MediaWikiAPI
from bs4 import BeautifulSoupmediawikiapi = MediaWikiAPI()    
media_wiki_page = mediawikiapi.page(wiki_page_obj) # scrape the HTML with BeautifulSoup to find tables soup = BeautifulSoup(media_wiki_page.html(), 'html.parser')    
tables = soup.findAll("table", {"class": "wikitable"})print(tables[0])

我用维基百科、MediaWikiAPI 和 Beautiful Soup 创建了一个复合代码来抓取维基百科页面。这段代码抓取作为搜索词响应的页面,搜索词基本上是您感兴趣的主题或领域。更深入地说,这段代码还从所有搜索响应页面获取相关链接,并抓取它们的内容。

链接到 GitHub 知识库使用维基百科抓取维基百科内容。

方法 2: DBpedia 和 SPARQL

DBpedia

DBpedia 是通过从维基百科项目中提取实体及其关系创建的,并以 N-Triples 格式存储。换句话说,DBpedia 是一个 RDF 图数据库。这些数据库的特点是它们在存储数据的同时保留了嵌入的语义关系。

比如:“我叫纳芭妮塔,来自印度。我住在爱尔兰。”

N-triples 数据库会将您的这些信息视为:

entity:me    relation_type:name   "Nabanita"
entity:me    relation_type:country   "India"
entity:me    relation_type:residence   "Ireland"

一般来说,这种格式也称为:

**subject**          **predicate**                      **object**
*(about what?)*    *(what is the relationship?) *   *(the value.)*

SPARQL

SPARQL 是 RDF 数据库查询语言。语法与其他传统的查询语言非常不同,但是目标非常相似,因此可读性很强。

SPARQL 查询的快照

目标: 在维基百科上获取运动员的详细信息,如出生日期、姓名和国家。另外,我希望名字是英文的。此外,国家是一个可选变量,即即使“国家”为空,我也需要运动员的信息。出生日期和姓名是必填项。

结果 SPARQL 查询:

PREFIX foaf: <http://xmlns.com/foaf/0.1/>    
PREFIX dbo: <http://dbpedia.org/ontology/>    
PREFIX dbr: <http://dbpedia.org/resource/>    
PREFIX dbp: <http://dbpedia.org/property/>    
PREFIX ling: <http://purl.org/linguistics/gold/> SELECT DISTINCT ?a, ?dob, ?name, ?c    
WHERE{
   ?a a dbo:Athlete; 
      dbo:birthDate ?dob;
      foaf:name ?name.    
   OPTIONAL{?a  dbo:country ?c}    
   FILTER(LANG(?name) = "en").    
} 

查询解释:

所有的前缀都是已经存在的标准定义或 RDF 词汇表。把它们当作进口货。在主查询中,我们选择不同的运动员(?a)哪一个是主体;出生日期(?dob),名字(?姓名)和国家(?c)哪些是对象。在“WHERE”中,第一行表示—选择一个类型(用 a 或 rdfs:type 表示)dbo:athlete 的主题。rdfs:type 或 a 和 dbo:athlete 是预定义的词汇表。“;”是用来继续使用选定的主题,即'?一个。此外,我们选择 dbo:birthDate(预定义词汇),值/对象将被检索为“?dob”和 foaf:name 一样?姓名。在“可选”中,我们选择相同主题的国家(?a)使用词汇 dbo:country 作为谓语,但我们说它是可选的。换句话说,即使 dbo:county 没有关联的值,也要检索结果。最后一行“过滤器”,根据变量“过滤语言”?name”并指定它应该是英文的。如果没有指定语言,那么 SPARQL 将检索不同语言的对象。因此,除非需要解决特定的目标,否则我们将会有不需要的重复数据。

输出:

输出看起来有点像这个图像(当限制为 2 时)。您可以在这里尝试执行自己的 SPARQL 查询。使用 SPARQL 的一个很大的优点是可以选择多种响应类型,包括 HTML、JSON 和 csv 文件格式。

如何在 Python 中执行 SPARQL 查询:

Python 有一个包装 SPARQL 服务的包装器,叫做 SPARQLWrapper 。这可用于查询位于https://dbpedia.org/sparql的 SPARQL 端点并检索结果。在本例中,我检索了一个 json 对象,并将其规范化为 pandas 数据帧。

import pandas as pd
from SPARQLWrapper import SPARQLWrapper, JSON
from pandas.io.json import json_normalize# SPARQL query
query = '''PREFIX foaf: <http://xmlns.com/foaf/0.1/>    
PREFIX dbo: <http://dbpedia.org/ontology/>    
PREFIX dbr: <http://dbpedia.org/resource/>    
PREFIX dbp: <http://dbpedia.org/property/>    
PREFIX ling: <http://purl.org/linguistics/gold/>SELECT DISTINCT ?a, ?dob, ?ht, ?hpn, ?g, ?name, ?c    
WHERE{{
   ?a a dbo:Athlete; 
      dbo:birthDate ?dob;
      foaf:name ?name.    
   OPTIONAL{{?a  dbo:country ?c}}    
   FILTER(LANG(?name) = "en").    
}}'''# initialise the SPARQL endpoint
sparql = SPARQLWrapper('http://dbpedia.org/sparql')# set query
sparql.setQuery(query)# set the response format
sparql.setReturnFormat(JSON)# execute the query
results = sparql.query().convert()# normalize the json object to a pandas dataframe
df_results = json_normalize(results['results']['bindings'])

为了从维基百科中搜集所有运动员的数据,我创建了一个知识库,执行这个示例查询的稍微增强版本。

链接到 GitHub 存储库以使用 SPARQLWrapper 查询 DBpedia。

总之,这是我们搜集或查询维基百科内容并进行创作的两种方式

  • 丰富且设计精良的数据集
  • 训练自然语言处理模型的语料库
  • 试用 SPARQL
  • 为 DBpedia 项目做贡献

一些有用的资源:

要了解关于 RDF 数据库和链接数据的更多信息:

[## 学习 RDF

引言这一系列课程是对 RDF 的介绍,RDF 是语义网的核心数据模型,也是

www.cambridgesemantics.com](https://www.cambridgesemantics.com/blog/semantic-university/learn-rdf/) [## 什么是 RDF?让数据的力量增加两倍

RDF 代表资源描述框架,是 W3C 开发并同意的数据交换标准

www.ontotext.com](https://www.ontotext.com/knowledgehub/fundamentals/what-is-rdf/)

如何将 Tensorflow/Keras 模型构建到增强现实应用程序中

原文:https://towardsdatascience.com/how-to-build-your-tensorflow-keras-model-into-an-augmented-reality-app-18405c36acf5?source=collection_archive---------12-----------------------

照片由大卫·格兰穆金Unsplash 上拍摄

移动机器学习

在 AR 和 ML 这两个快速发展的领域中,集成这两者可能会令人困惑。这是一个将深度学习模型实现到 Unity/C#和 AR 基础中的指南(尽管它也适用于 Vuforia)。

这个过程很复杂,可能会随着时间的推移而略有变化。随着变化的出现,我会尽最大努力更新。我假设您已经设置了 Unity 和 Tensorflow。Unity 应该是 2017.x 或者更高版本,Tensorflow 应该可以用任何版本(我用的是 Unity 2019.3.3,还有 tf2.1)。在我目前的项目中,我还在想办法,所以这可能不是最好的方法,但绝对有效。随着我了解更多,我会更新这篇文章。

我们将按照以下平台方面的顺序进行,这看起来比实际情况更令人困惑:

经过训练的 Python/Tensorflow/Keras →转换为 ONNX →实现 bara cuda/tensor flow Sharp→Unity/c#→构建 Android 应用

保存和导出模型:

如果您有一个 Keras .h5文件,您首先需要将它保存到一个saved_model.pb中。我们现在将它转换成一个开放神经网络交换(ONNX)文件,使用 Tensorflow Sharp 将它读入 Unity。

然后,按照他们的自述文件(我克隆了他们的 repo,然后运行了 setup.py install)获取你的saved_model.pb Now install onnx 的文件路径。在同一个文件夹中运行下面的命令(它查找saved_model.pb,所以确保它是你的文件夹路径中的文件名)。

python -m tf2onnx.convert --saved-model tensorflow-model-path --output model.onnx

以下是 Barracuda 支持的内容,我们将使用这个包将.onnx文件读入 Unity。

支持的架构列表:

  • 所有 ML-agent 模型(强化学习)。
  • MobileNet v1/v2 图像分类器。
  • 微型 YOLO v2 物体探测器。
  • UNet 类型的模型。
  • 全卷积模型。
  • 全密集模型

支持操作列表:

https://docs . unity 3d . com/Packages/com . unity . barracuda @ 0.7/manual/index . html # getting-unity-barracuda

支持的激活功能列表:

https://docs . unity 3d . com/Packages/com . unity . barracuda @ 0.7/manual/index . html # getting-unity-barracuda

现在您已经有了.onnx文件,我们需要将 Unity mlagents 引入您的项目。最简单的方法是按照 Youtube 教程中的来做,它要求你在你的 Unity 包管理器中获取mlagents(启用预览包),并在视频描述中拉入 GitHub 文件夹。之所以这么做,是因为这些包里包含了梭鱼,Unity 就是用它来轻松的把.onnx文件作为.nn带进来,用 C#执行。我相信你也可以从软件包管理器中安装 mlagents 和 Barracuda,但是如果那不起作用,试试上面的指导。你就快到了!

。onnx 文件放入 Unity Assets 文件夹时应该是这样的

在 Unity 中加载模型、创建模型输入和读取模型输出

对于那些不熟悉 Unity 的人,我可能会在这里失去你。Unity 有很棒的文档,所以你应该能够搜索到任何让你困惑的东西。

我们将执行三个步骤:

  1. 逐帧访问摄像机画面
  2. 将该帧转换成(224,224,3)图像纹理 2D
  3. 从模型中读取 Softmax 层输出

首先在层级中右键单击创建一个AR Session OriginAR Session。要访问相机馈送,我们将通过右键单击项目文件夹来创建“渲染纹理”。点击纹理,并在检查器中改变其大小为 1080x1920(或任何你想它是)。如果你出于某种原因不想使用渲染纹理,那么这是另一个访问相机帧的变通方法。将渲染纹理放置在 AR 相机的相机组件的“目标纹理”字段中。这将移除正常的相机视图,并将其渲染到放置该渲染纹理的对象上。

我们将创建一个 UI RawImage,在“Rect Transform”组件中将它拉伸到画布上,然后将渲染纹理附加到它的 RawImage 组件上。它应该是这样的:

现在我们可以进入代码了。你可以在他们的 Unity 文档中熟悉一下 barracud a,但是我们基本上需要加载.nn 模型,然后创建一个执行该模型的方法。之后,我们要调用最后一层,把它从一个张量转换成一个浮点数组。

这是很多,但让我们走一遍。NNModel 将出现在检查器中,您可以从项目文件中拖放.nn。我们想加载它,而缓存在m_RuntimeModel的运行时开始。

之后,我们创建额外的输出来调用 softmax 层(正如我所做的那样,这样我就可以手动设置阈值,而不是只使用 argmax),并创建一个引擎来在设备 GPU 上执行模型。我们必须调整渲染纹理的大小以适应模型的输入,对我来说是(224,224,3)。我用来转换为 Texture2D 然后调整大小的两个函数如下:

代码的其余部分非常简单明了,不要担心dispose()方法,我们将在最后讨论它。有了这个,你应该能够连接到一个UI Text元素,而不是使用debug.log,并在你的手机上建立应用程序!我喜欢在我的 pc 上使用 Vuforia 的相机进行测试,然后在构建时将其更改为 AR Foundation 的相机。

如果构建不工作,你必须使用 android 调试器(adb) 。这将允许您使用adb logcat -s Unity查看构建的应用程序的崩溃日志。有时候,我的电脑网络摄像头上的东西不在我的手机上,这一切都非常依赖于版本!只要不断调整它,直到它的工作。

优化您的 AR 应用

太好了,现在你的模型可以在你的手机上工作了!但不幸的是,你会很快注意到帧速率很糟糕,我的第一次构建时大约是 3fps。即使使用微小的 yolov2,帧速率也不惊人(特别是对于你牺牲的地图)。你需要做的是在 Unity 的作业系统包中学习多线程和垃圾收集器。Barracuda 的功能已经类似于一个作业系统,具有 worker (handle)、execute (check out executeasync)和 disposal 方法。

当你在你的应用程序中构建更多的交互来使它真正成为 AR 时,你需要尽可能地保存所有的处理。 Unity Profiler 会帮助你,只要确保它设置为层次而不是时间线。对于这个简单的应用程序,我只是每 10-15 帧执行一次模型,而不是每一帧。

或者,你可以在你的模型上使用量化,但是那必须在它是一个.onnx文件之后完成(抱歉还没有tflite支持)。以下代码应该可以在 python 中运行,但请注意,量化会影响模型的准确性。

https://gist . github . com/andrewhong 5297/6601 e 7 e 48 fc 862 e 60 a 3843 CD 8 fcfe 480

现在你知道了!有很多移动和变化的部分,但都有很好的记录。不要害怕深入 Barracuda 和 Onnx GitHub 库或 Unity 论坛寻求帮助。

如果您有任何困惑或困惑,请留下您的评论。玩得开心!

如何构建您的终极数据科学投资组合

原文:https://towardsdatascience.com/how-to-build-your-ultimate-data-science-portfolios-ea0414d79a72?source=collection_archive---------18-----------------------

我对数据科学同事和低年级学生的建议

伟大的数据科学家创造重要的产品

建立你的投资组合

“我将建立一个健身跟踪器来分析我的健身/饮食指标”

“我设计了这些 Tableau 仪表盘。没有计划,只是为了好玩”

几天前,我和一家知名初创公司的数据科学家/ ML 工程师进行了一次交谈。作为一个刚完成学业的专业人士,他雄心勃勃,热情高涨。他要求在谷歌与我会面,并记下我们谈论的一切。他真的很高兴分享他的数据科学项目,并愿意通过任何有趣的技术书籍,让他在他的 side hustles 和 Kaggle 竞争中领先。

如果他让你想起你自己或你那些有抱负的数据科学家朋友,你并不孤单。事实上,我发现许多数据和技术行业的大三学生和专业人士一直在利用他们的空闲时间/周末来建立他们的投资组合。数据科学是一个快速发展的行业,每个季度都有不断发展的趋势。在投资组合方面,你的选择是建立还是输给你的同行。

但是你有没有问过自己:“这是正确的方法吗?”

不要误会我,我很佩服他用无限的热情跟他谈建设他的副业。他分享了他有趣的学习经历,我毫不怀疑他会学到更多。但不知何故,他为自己的副业项目推广复杂技术技能的方式让我无法理解。

他们缺乏影响力。

在你有限的时间里做重要的事情

如果我们有时间做最好的投资组合。为什么我们把大部分时间花在展示我们的技术技能上,而不是我们产生的影响上?为什么我们优先关注 Kaggle 比赛,而不是解决我们朋友的问题,而数据分析可以解决这些问题?与其说你在 Kaggle 竞赛中排名第 30 位,不如说你用你的选股模型帮助你的同行赚了钱。

在我看来,这正是优秀的数据科学家和伟大的数据科学家的区别。

优秀与伟大的数据科学家:构建具有影响力的产品

一个优秀的数据科学家有一个庞大的学习知识库。他知道如何制作漂亮的仪表板。他建立了更好的神经网络模型来分类 MNIST 数据集。他运行高度复杂的交易算法,这需要一个人多年才能学会。

这很好,但还不足以产生影响。

要成为伟大的数据科学家,你需要的是一个伟大的产品和影响力。产品表明用户从中受益的价值。这表明你的技能给社会带来了影响。最终,当你去参加数据科学面试时,你将需要证明你能够解决问题,并将价值带入表中

因此,一位伟大的数据科学家使用他的仪表板来建立预测公式,以阻止冠状病毒传播到数百万人。一位伟大的数据科学家使用他的神经网络模型对网络钓鱼攻击进行分类,以保护数百万用户免受劫持。本质上,一个伟大的数据科学家的投资组合中有受众、产品和影响。

你的产品将是你最终的投资组合

当你把你的产品作为一个投资组合进行交流时,不管你的教育背景如何,你都会成为一个主题专家(SME)。因此,Analytics 人力资源招聘人员会猎头你,而不是你寻找他们。当你去面试的时候,你会有令人兴奋的故事来讲述,而不是你所拥有的一系列无聊的技能/证书。

就我而言,我的投资组合让我接触到了谷歌、脸书、维萨等大公司。在我的每一个兼职项目中,我都教我的同事用它来解决他们朋友的业务问题。我为那些有志于购买股票的金融朋友们设计了价值投资仪表盘。我创建了 Twitter 提取和情感分析,以提取关键主题和情感,供营销朋友提出营销活动。

通过构建您的产品、了解您的受众并产生影响来构建您的最终产品组合。

打造终极投资组合的三大关键

1.以对受众有影响的简单解决方案为目标

谁是你的观众。这永远是第一个要问的问题

当你对培养自己的技能比对培养观众更感兴趣时,危险就来了。让我抓住那个制造头条新闻的家伙。他计划建立一个健身追踪器来分析他自己的健身/饮食指标。伟大的项目,但对任何人都没有影响,除了他自己。

同样,我认识的许多有抱负的数据科学家/年轻同事只专注于构建复杂的模型,而没有为他们的受众带来价值。在网飞竞赛中,获胜团队不考虑实施其推荐模型所需的工程工作。虽然他们以惊人的准确性获胜,但他们的解决方案太复杂了。结果,网飞浪费了 100 万美元来奖励一个他们无法采用的机器学习模型。

同样的,你应该把你的受众的需求放在心上来制作你的产品。这将迫使你建立一个更现实的数据分析管道。您分析真实的业务问题、提取脏数据、清理数据、特征工程、设计、部署和维护模型。

在大学和其他 MOOC 认证中,通常情况下,问题公式和干净的数据集已经为我们处理好了。因此,为真实受众构建解决方案将更具挑战性。但是,从长远来看,你会得到满意的建筑产品。在任何数据面试中,你积累故事来宣传你的真实项目,而不是吹嘘你的技术技能和 Kaggle 比赛。

2.根据您的领域知识构建解决方案

来源( Unsplash

我和很多从不同行业跳槽到数据/科技行业的大三学生和专业人士聊过。我曾与一位就读于新加坡国立大学(NUS)化学博士的女士交谈过,她向我寻求建议,在一家科技行业担任数据科学家。她从未在科技行业工作过,但她想学习 python 并从头开始发展她的编码技能。

虽然人们勇敢地跳到不同的专业领域是令人钦佩的,但我会强烈建议她在没有可靠计划的情况下不要这样做。毕竟,与成千上万已经完成 4 年学业的计算机科学或商业分析毕业生相比,她会有什么样的优势呢?当数据分析已经有这么多炒作的时候,你将如何赶上技术和竞争?

这是信仰的巨大飞跃。

因此,我建议她继续学习化学。我建议她先成为最好的化学家,然后冒险进入分析领域。为什么?因为她不需要从零开始。她已经拥有大量的化学领域知识,她可以学习制造化学产品和展示自己能力所需的必要分析技能。她不应该丢掉自己的专业知识。她应该把它作为一个平台,在分析领域找到自己的位置。

同样,如果你是金融专业的学生,建立股票研究工具。如果你是运营管理/工业工程专业的学生,建立六西格玛优化工具。这使您能够利用现有的知识来创建有意义的数据分析工作,而不是从第一天开始从头开始学习分析。

理想情况下,您应该达到帕累托比率,大多数数据分析工作都可以使用简单的模型(如线性回归和决策树)来解决。如果你正确使用你现有的领域知识,你 20%的努力应该已经产生了 80%的影响。

3.部署和交流您的解决方案

我在谷歌上关于 CNN 新加坡数据科学模型的演讲

如果你想成为一名伟大的数据科学家,你需要发表你的作品。开放你的解决方案,让其他人使用。让人们为你的 Github 做贡献。写并谈论它。越多的人在你的作品中发现价值,他们就越有可能传播你的产品。在未来,你将投入到建立你的投资组合和个人品牌中,同时在你的专业工作之外教育他人。

在我的例子中,我通常使用 Github 让人们访问我的代码和在线学习,使用 Youtube / Medium 以文字和视频的形式交流我的想法,最后使用 Heroku 启动我的 Python 应用程序。我从我的解决方案中获得了收入和流量,这增强了我的知识对他人有益的价值。随后,构建产品让我能够在构建个人品牌和故事的同时掌控自己的工作。

结论

如果你玩得好,你会有很多好处。首先,你要建立自己的投资组合,并乐在其中,看看你产生的影响。第二,你推广自我品牌和工作机会和会议机会的在线可见性。最后,你训练自己写作和讲述故事来激励你的观众采取行动。所有这些优势都将为您成为伟大的数据科学家创造机会。

总之,要实现这些结果,您需要:

  1. 以简单有效的解决方案为目标:专注于培养你的受众,而不仅仅是培养你的技能。
  2. 根据你的领域知识构建解决方案:不要从零开始追求数据科学。利用您现有的才能和领域知识,为您的同行构建数据科学产品。
  3. 部署和宣传您的解决方案:部署和推广您的产品。让许多人使用它,并记录你所产生的影响。作为一名伟大的数据科学家,它为您提供了更多的灵感和故事来增强您的学习。

索利·德奥·格洛丽亚

最后…

我真的希望这是一本很棒的读物,是你发展和创新的灵感来源。

在下面评论提出建议和反馈。就像你一样,我也在学习如何成为一名更好的数据科学家和工程师。请帮助我改进,以便我可以在后续的文章发布中更好地帮助您。

谢谢大家,编码快乐:)

关于作者

Vincent Tatan 是一名数据和技术爱好者,拥有在 Google LLC、Visa Inc .和 Lazada 实施微服务架构、商业智能和分析管道项目的相关工作经验。

Vincent 是土生土长的印度尼西亚人,在解决问题方面成绩斐然,擅长全栈开发、数据分析和战略规划。

他一直积极咨询 SMU BI & Analytics Club,指导来自不同背景的有抱负的数据科学家和工程师,并为企业开发他们的产品开放他的专业知识。

最后,请通过 LinkedIn Medium Youtube 频道 联系文森特

如何批量获取 arXiv 全文预印本

原文:https://towardsdatascience.com/how-to-bulk-access-arxiv-full-text-preprints-58026e19e8ef?source=collection_archive---------44-----------------------

使用 Python3 和 MacOS X 命令行

来源:西科夫,via 土坯股票

自 1991 年成立以来,arXiv(科学预印本的主要数据库)已经收到了近 130 万份投稿。所有这些数据在分析中都是有用的,所以我们可能希望能够批量访问全文。这篇文章讲述了我们如何使用 Python 3 和 MacOS X 命令行来实现这一点。

使用命令行批量访问全文的步骤

尽管数据就在服务器上,但由于服务器容量有限,不建议直接抓取 arXiv。然而,arXiv 已经承认了批量访问的需求,通过在亚马逊 S3 上提供所有全文,每月更新。

arXiv 将它们的源文件存储在arxiv桶中。请求者必须付费。数据存储在按日期排序的大 tar 文件中(该文件的最后修改时间)。这有点不方便,因为我们需要处理整个 arXiv 语料库,即使我们只对特定的类别感兴趣。

下面我们将介绍下载全文的步骤,目标是astro-ph类别。

1.设置一个 AWS 帐户。

为了能够从亚马逊 S3 下载任何东西,你需要一个亚马逊网络服务(AWS)账户。在这里报名。你必须注册一张信用卡。

2.创建您的配置文件。

创建一个名为config.ini的文件,并添加您的 AWS 配置:

[DEFAULT]
ACCESS_KEY **=** access**-**key**-**value
SECRET_KEY **=** secret**-**key**-**value

要获取您的键值,请按照这里的说明获取根访问键

不要公开此文件!

3.创建 S3 资源并设置配置。

创建一个将从命令行运行的 Python 文件。在其中,初始化一个 S3 资源,这是一个面向对象的服务接口,并将其配置为使用您的 root 访问。

4.检查arxiv桶元数据。

arXiv 在一个名为src/arXiv_src_manifest.xml的文件中维护它们的桶中数据的有用信息。下载这个文件,以便更好地理解我们在做什么。

注意:代码将只显示与当前步骤相关的新的或更改的部分,但是 Python 文件包含了从所有步骤到这一步的代码。完整的文件将显示在最后。

浏览清单文件中的存储桶元数据。

当我们运行这段代码时,我们将看到清单文件最后一次更新的时间,以及arxiv bucket 保存了多少 tar 文件和总大小。当我运行这段代码时(2018 年 6 月 10 日),这个桶包含 1,910 个 924 GB 大小的 tar。

5.下载astro-ph源文件!

请记住,每个 tar 都包含嵌套的 tar gzs,后者又包含特定类别的源文件。虽然我们必须下载每个 tar,但是我们可以提取这些源文件,而不需要解压缩所有 tar 和 tar gzs。我们还将筛选源文件,只提取标有astro-ph类别的文件,但也有其他类别可用。

完整代码

如果你想阅读更多我的文章或者探索数以百万计的其他文章,你可以注册成为中级会员:

[## 通过我的推荐链接加入 Medium-briena Herold

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

brienna.medium.com](https://brienna.medium.com/membership)

您还可以订阅我的电子邮件列表,以便在我发布新文章时得到通知:

[## 每当布蕾娜·赫罗尔德发表。

每当布蕾娜·赫罗尔德发表。通过注册,您将创建一个中型帐户,如果您还没有…

brienna.medium.com](https://brienna.medium.com/subscribe)

你可能会对我的其他一些故事感兴趣:

[## 如何免费下载 Twitter 好友或关注者

Python 中的简单指南

towardsdatascience.com](/how-to-download-twitter-friends-or-followers-for-free-b9d5ac23812) [## 如何批量获取 arXiv 全文预印本

使用 Python3 和 MacOS X 命令行

towardsdatascience.com](/how-to-bulk-access-arxiv-full-text-preprints-58026e19e8ef) [## 从《纽约时报》收集任何时期的数据

Python 中的简单指南

towardsdatascience.com](/collecting-data-from-the-new-york-times-over-any-period-of-time-3e365504004)

把针扔在地上怎么算π

原文:https://towardsdatascience.com/how-to-calculate-π-by-tossing-needles-on-the-floor-3e26ba027ab2?source=collection_archive---------36-----------------------

著名的布冯针问题

图片由皮克斯拜的 Gerd Altmann 提供

领先的进化生物学家和博学者恩斯特·迈尔描述法国博物学家、数学家和宇宙学家乔治-路易·莱克勒克,孔德·德·布丰(1707–1788),如是说:

“的确,[……]18 世纪下半叶自然历史中所有思想之父”

——恩斯特·迈尔

他的作品,尤其是他的一*36 卷的合集,受到了的高度影响,涵盖了广泛的主题,包括材料科学、物理、化学和动物自然史。*****

他对数学的贡献

乔治·路易·莱克勒克(后来的布丰伯爵)对数学的第一个重大贡献是他的《T21》一书,在书中他将微积分技术应用于概率理论。本文将要描述的著名问题布冯针就是以他的名字命名的(见图 2)。

图 1:乔治-路易·莱克勒克,布丰伯爵,由著名肖像画家弗朗索瓦-休伯特·德鲁艾(左)(来源)。在他的书《自然的问题》(1778 年)中,莱克勒克提出行星是在太阳和彗星碰撞后形成的。

问题陈述

这个问题的简化形式可以表述如下:

考虑一根 2长的针扔在一块 2宽的木板地板上。针落在其中一个平行裂缝上的概率是多少?****

针尺寸和曲柄之间距离的具体选择是不相关的。在解决了这个特殊的情况之后,概括就很简单了(如下所示)。

图 2:布冯问题初始提法的声明(来源)。

正如我们将看到的,这个问题的解决方案允许人们估计π的值,这是一个完全出乎意料的结果。

图 3:基于布冯针的问题寻找π的一个实验(来源)。

定义变量

图 4 和图 5 显示了描述针落在地板上时的位置和角度所需的变量( xθ )。变量 x 测量从针的中心到最近的平行线的距离。角度 θ 是针与扇形体 OP 之间的角度。

图 4:针落在其中一个裂缝上的情况。

( xθ )应该遵守两个限制,

等式 1:(xθ )变量遵守的两个限制。

图 5:针没有穿过裂缝的情况。

席梦思所述,这相当于在矩形中选择 xθ 的问题,例如:

图 6:描述针落在地板上时的位置和角度相当于在这三个()这样的矩形中选择 xθ

现在注意,当指针穿过平行线(曲柄)时,遵守以下条件:

等式 2:当指针落在曲柄上时,x 和θ所遵循的条件。

图形上我们有:

图 7:等式。2 用图形表示。纵轴测量 x ( )。

使用 Eq。2,或者等效地,图 7,我们可以计算针落在平行裂缝上的概率:

等式 3:指针落在曲柄上的概率。

一般化

等式给出的不等式。2 可以概括为尺寸为 L 的针落在由 d 分开的平行裂缝之一上的问题:

等式 4:等式的推广。2 当平行线的距离为 d. 时,尺寸为 L 的针落在平行裂缝上

新的概率为:

等式 5:当两条平行线之间的距离为 d. 时,尺寸为 L 的针落在平行线上的概率

但是,请注意,此计算仅对小于或等于 d 的 L 有效。一般问题可分为两种情况:小针和大针。

等式 6:问题可以分为这两种情况。

我们已经解决了第一个案子。让我们解决第二个问题。在这种情况下,我们可以利用 xθ 的联合概率。假设两个分布都是均匀的,那么 x 的概率密度是 2/ d (对于x∈【0, d /2】,因为概率必须积分为 1),并且 θ 的概率密度是 2/πθ∈【0,π/2】。因此联合概率是它们的乘积 4/(πd),只有当 xθ 的分布同时不为零时,联合概率才不为零。

整合联合分布后,我们得到:

等式 7:长针情况下的概率 L>d。

通过实验确定π

假设现在我们把 2 根 " 针扔到地板上,比方说,n= 10000 次。曲柄之间的距离也是 2。它落在曲柄上的次数百分比由 n / N 给出,其中 N 代表投掷的总次数,而 n 是针落在曲柄上的次数。我们的计算表明:**

等式 8:根据我们的计算,随着投掷次数的增加,针落在裂缝上的次数的百分比应该接近 2/π。

因此,我们可以用这个简单的实验来估计常数π的值,即:

等式 9:如果我们把针在地板上扔很多次,我们可以估计常数π的值。

下面的动画展示了我们刚刚描述的实验的模拟。

图 8:布丰针实验的模拟(使用 Python 3)。第二个图显示估计确实收敛于π ( )。

感谢您的阅读,再见!一如既往,我们随时欢迎建设性的批评和反馈!

我的 Github 和个人网站 www.marcotavora.me 有一些关于数学和其他主题的有趣材料,如物理、数据科学和金融。看看他们!

如何用 Python 计算贴现现金流

原文:https://towardsdatascience.com/how-to-calculate-discounted-cash-flows-with-python-a88f12a48d5c?source=collection_archive---------26-----------------------

面向金融的 PYTHON

用熊猫、考拉和派斯帕克

时间有价值

时间是有价值的——不仅仅是它给你的智慧,还有金钱的时间价值。

凯文·Ku 在 Unsplash 上的照片

你一定听说过这个:

今天的 100 美元比明天的 100 美元更有价值。

它如此简单,却揭示了我们许多行为和决定背后的潜在原则:

  • 投资或持有现金。投资让你赚取利息,而持有现金不会产生额外的价值。
  • 提前支付或延期支付。推迟付款能让你在付款前通过投资赚钱。
  • 是否进行一个项目。是的,如果项目的回报高于初始投资加上它本可以赚取的利息;

嵌入货币时间价值的其他领域包括保险定价、债券定价、企业估值等。

照片由 Aron 视觉效果Unsplash 上拍摄

时间与估值有什么关系?

为了回答这个问题,我们来输入一个模拟:坐好,挂紧。

你的彩票奖金决定

好消息!你刚刚中了一百万美元的彩票!

你有两个选择来得到现金。

  • 选择一:今天就获得 80 万美元。
  • 方案二:一年内获得 100 万美元。

假设你没有现金短缺,并假设你今天没有不合理地持有现金:你会选择哪个选项?

要回答这个问题,你肯定会问我:

如果我投资,我能期望的投资回报是多少?

问得好!比方说“ 银行幻想 ”提供一项年回报率为 10%的无风险投资。现在让我们为自己做出一个好的决定。

要比较这些选项,最简单的方法是通过考虑Interest Rate(投资回报)和投资期限(t),将Present Value(今天的价值)转换为Future Value(一年后的价值)。

用期权 1 今天(Present Value)的 80 万美元,可以投资银行幻想的投资产品,一年(Interest Rate)获得 10%的回报(t)。这是 80,000 美元的投资回报。有了最初的钱,你在年底会有 880,000 美元。当然,对比年底的现金数额,方案二的 100 万美元是显而易见的选择。

所以现在决定很清楚了,你将选择选项 2,一年后获得 100 万美元。

用公式表达我们讨论过的思维过程,它是:

80 万美元一年的价值是多少,这一点很清楚。现在让我问你另一个问题:

未来的 100 万美元今天值多少钱?

为了推导它,我们可以把前面的公式反过来求解 PV。让我们试试:

将 1,000,000 美元转换成今天的价值,得出 909,091 美元。这相当于说,今天有 909,091 美元,你会把它投资到 Bank Fantasy 的产品中,到年底会有 100 万美元(909,091 美元加上 90,909 美元的投资回报)。

现在我们可以比较选项 1 的 800,000 美元和选项 2 的 909,091 美元。这又给了你同样的决定:选择选项 2!

分解公式

您现在知道如何计算今天的价值了。而这个过程叫做 贴现

为了简化贴现流程,我们可以将其分为两步:

  1. 计算一个 折扣因子;
  2. 计算 的现值

折扣系数

从前面讨论的现值公式中取分母。我们会有折扣因素。现值公式并不复杂,但没有必要重复使用除法和指数。该系数可以计算一次,然后简单地乘以未来的现金支付。

计算折扣系数

现值

计算贴现因子后,将贴现因子应用于未来值将得到现值。

多重未来值

也可能有多个未来值:

假设您有一个选项 3:第一年收到 50 万美元,第二年收到 50 万美元。

在这种情况下,总现值是用贴现因子分别贴现的所有未来值的总和。

计算现值

商业案例

好了——到现在为止,你已经是用彩票资金做决策的专家了。让我们尝试一个商业案例。

这一次,你从事保险产品定价工作。你被要求估计一项保险产品的价格,该保险产品涵盖五年的洪水风险。

假设你写了一个合同,它:

  • 第一年年初从客户处收到 12,000 美元;
  • 五年内每年年底向客户支付约 2000 美元的索赔;
  • 你可以投资利率为 2.5%的美国政府债券;

为了计算现值,我们需要做以下事情:

  1. 计算每年的贴现因子Discount factor = 1 / (1 + r)^t

2.计算每年现金流量的现值Present value = discount factor * Cash flows

3.把所有现金流的现值加起来;

总计Present value栏,你将获得 2706 美元的利润。加上前期收到的 12,000 美元和贴现到今天的五项未来费用,我们最终保持了 2,706 美元的利润。

💰所以…是的!你的公司将出售这种产品。

最后用 Python 代码!

为什么不超越

到目前为止,我们看到的例子非常简单。在现实中,我们很少只有几个现金流在未来发生。

  • :如果你试图一次对多个产品估值,Excel 就变得有限;
  • 🤖自动化:Python 逻辑可以作为函数编写一次,自动应用于类似的未来现金流,避免人工错误;
  • 🚅速度:计算量大的时候 Excel 打开会比较慢,带收益率曲线的vlookup只会让它更容易崩溃,而 Python 可以轻松应对;

所以这是金融中最适合应用 Python 的领域之一。

照片由吕山德元Unsplash 上拍摄

介绍我们的例子

所有的资料和代码都可以在这个代码库中找到

现在,我们将使用稍微复杂一点的现金流文件和收益率曲线文件作为示例。

注意:这里我们不再使用统一利率。相反,我们使用收益率曲线:更高的利率出现在更长的期限内,以反映更高的回报,如果人们必须将现金投入一种产品更长的时间,通常会要求更高的回报。

  • 我们有两种产品:洪水险和火险;
  • 两者都是美元;

预计现金流如下表所示:

两种产品的现金流

按年份划分的现金流模式

用于贴现的收益率曲线:

收率曲线

来自熊猫的帮助🐼

由于 Pandas 是按列操作的,所以同样的公式可以一次应用于整个列。

步骤:

  1. 1 / (1 + df["Interest rate"])**df["Year"])计算折扣系数;
  2. 基于YearCurrency将收益率曲线文件与现金流文件合并;
  3. df["Cash flows"] * df["Discount factor"]计算每年现金流量的现值;
  4. 使用groupby汇总每个产品的Present value

⚡注 :在 merge 函数中,使用 left join 将确保在这个过程中没有现金流被丢弃。在收益率曲线信息不完整的情况下,我们可以在应用merge后检测现金流文件中的Null值。

完整的代码和结果:

计算熊猫的贴现现金流

通过几行代码,您可以在不到一秒的时间内获得贴现现金流。

熊猫的贴现现金流

一旦我们按产品汇总了Present value:

按产品划分的总贴现现金流

我们将看看我们的产品是否有望盈利:

产品现值

在这种情况下,是的又来了两个!

现在有了考拉🐨

Databricks koalas 可以让您非常轻松地从小型本地操作过渡到大数据的分布式计算。

除了导入一个不同的库(以及库的别名ks而不是pd),其余部分与上面的 Pandas 代码相同。

用考拉计算贴现现金流

闪亮的火花🌟

当数据变得足够大,熊猫无法再在内存中读取时,PySpark 就派上了用场。

要使用 PySpark 计算贴现现金流,您需要知道操作中涉及到广泛的转换。

join —加入 PySpark 是一个广泛的转变。这意味着在要连接的两个表匹配之前,有一个数据交换。

  • 默认情况下,要连接的表将被分割成 200 个更小的文件(所谓的分区)用于分布式计算;
  • 为了保证效率,我们将使用broadcast连接;
  • join 所做的是:它会将您选择的小表广播给大表的每个执行程序;
  • 这样避免了数据的交换,因为小表是作为一个整体被所有的执行者消耗的;
  • 要使用广播,您需要通过broadcast(small_table)small_table.hint("broadcast")给小桌子一个提示;
  • 这一步将在 Spark 3.0 的新版本中自动处理。但是在你安装新版本之前,我们不要忘记添加一个提示。💡

使用 PySpark 计算贴现现金流

这样,我们又一次得到了和以前一样的结果。

最后的话

贴现现金流的应用非常广泛:对你的商业项目、保险产品、债券、甚至公司进行估值。

由于容量和速度的限制,在 Excel 中贴现现金流比必要的要复杂得多&手动错误的几率更高。然而,使用 Python,它不超过十行代码。

现在你已经到了故事的结尾。你干得好!👏

如果你觉得这篇文章有用,请关注我的推特简介🐼。我会继续发布关于 Python 的文章🐍金融、保险和估价。

请给你的任何问题留言,我会直接回答或者通过以后的文章来回答。

最后,我想感谢德扬·西米奇和瑞秋帮我审阅我的帖子。

培养对学习的热情。如果你这样做了,你将永远不会停止成长。

—安东尼·j·德安杰洛

如何使用 SQL 计算特征重要性——基本指南

原文:https://towardsdatascience.com/how-to-calculate-feature-importance-with-sql-the-essential-guide-400b5366a88c?source=collection_archive---------33-----------------------

是的,SQL 可以做到这一点。需要 5 行代码。

机器学习不再仅仅是 PythonR 的专利。用大家都知道的语言——SQL,可以直接在数据库中做很多事情。今天我们将探索如何用它来计算特性的重要性,大约有五行代码。

照片由 Josiah WeissUnsplash

不想看书?看看我关于这个主题的视频:

在本文中,我们将使用 Oracle 云。这是免费的,所以请注册并创建一个 OLTP 数据库实例(版本 19c,有 0.2TB 的存储)。一旦完成,通过SQL Developer Web或任何其他工具建立连接。

至于数据集,我们将使用一个电信行业变动数据集,可从这里下载。我之所以选择这个数据集,是因为它有许多功能,不需要任何手动准备。

这篇文章的结构如下:

  • 什么是特征重要性?
  • 数据集加载
  • SQL 的特性重要性
  • 结论

什么是特征重要性?

要素重要性是一种根据输入要素(属性)对预测(用于预测目标变量)的有用程度为输入要素(属性)分配分数的技术。

这个概念对于预测建模是必不可少的,因为您希望只保留重要的特征,而丢弃其他特征。通过这样做,您可以减少维度和噪声。出于显而易见的原因,它还可以让您更好地理解您的数据。

此外,计算特征重要性可以提供对预测模型工作的洞察。通过了解重要性分数,您可以立即知道模型认为什么是最重要的,以及它为什么以这种方式进行预测。

此外,有一个定量的确认总是好的,不要工作在纯粹的假设上。

数据集加载

如果您正在跟进,您应该已经下载了数据集。你必须用你选择的工具将它加载到数据库中——我用的是 SQL Developer Web ,但是你可以使用几乎任何东西。

加载过程很简单——点击上传按钮,选择数据集,然后点击几次下一步:

图 1-使用 SQL Developer Web 加载数据集(图片由作者提供)

我的存储在churn表中。让我们通过执行一条SELECT * FROM churn语句来看看里面有什么:

图片 2-流失数据集的前 10 行(作者图片)

现在,您可以继续进行要素重要性计算。

SQL 的特性重要性

正如所承诺的,这将只需要几行代码。特征重要性通过DBMS_PREDICTIVE_ANALYTICS包的EXPLAIN过程获得。它需要三个参数:

  • data_table_name–存储源数据的地方
  • explain_column_name–目标变量的名称
  • result_table_name–存储特征重要性的新表格

下面是如何用代码实现它:

就是这样!现在,您可以用一个简单的SELECT语句来看看重要性。下面的表格对功能进行了排序,因此最重要的功能会首先显示:

结果如下:

图片 3-特征重要性(作者图片)

从前面的图像中,你可以立即看出什么是重要的,什么是不重要的。下一步是将这些信息用于预测模型。这有点超出了本文的范围,但是您可能希望继续进行分类建模。

事实证明,这也只能用 SQL 来执行!下面是如何

离别赠言

我想你没有想到用 SQL 计算特性重要性这么容易。但它是,就像数据库中的其他机器学习一样。SQL 仍然不是机器学习的语言,但我们可以说,随着这些最近的进步,未来看起来很有希望。

不要错过 SQL 系列的其他机器学习:

请在下面的评论区留下你的想法。

加入我的私人邮件列表,获取更多有用的见解。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

[## 通过我的推荐链接加入 Medium-Dario rade ci

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

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

原载于 2020 年 11 月 12 日 https://betterdatascience.com

如何用 Python 计算扑克概率

原文:https://towardsdatascience.com/how-to-calculate-poker-probabilities-in-python-75238c61421e?source=collection_archive---------4-----------------------

将扑克手变成扑克赔率

根据拉斯维加斯威尼斯人酒店一夜的真实故事改编

介绍

在本文中,我们将展示如何用 Python 表示基本的扑克元素,例如手牌和连击,以及如何计算扑克赔率,即在无限注德州扑克中赢/平/输的可能性。

我们提供了一个基于拉斯维加斯威尼斯人酒店之夜真实故事的实用分析。

内华达州拉斯维加斯威尼斯人酒店一日游。

我们将使用包 扑克 来代表手牌、连击和射程。我已经从曾圣耀扩展了扑克赔率计算器,因此它能够根据范围(一组可能的手牌)以及单手牌计算扑克概率。最终代码可在我的回购中获得。

失败

我拿到了黑桃国王和梅花杰克(♠J ♣).国王)我将使用 poker.hand 中的组合牌来构造我的牌。

我不记得翻牌前发生了什么,也不记得我的位置。但是,我记得翻牌前有人加注,翻牌后只剩下两个玩家:我和恶棍。

我们现在是单挑。翻牌圈出现了梅花 q、红心 10 和黑桃 9。是的,我翻到了顺子!

让我们在翻牌圈后计算我的赔率,假设事先不知道恶棍的牌,也就是说,在翻牌圈,我们将计算我的牌赢一对随机的底牌的可能性。

来自 holdem_calc 的函数 calculate_odds_villan 计算某一手德州扑克获胜的概率。这个概率是通过运行蒙特卡罗方法来近似计算的,或者是通过模拟所有可能的牌局来精确计算的。翻牌后计算确切的赔率很快,所以我们不需要蒙特卡洛近似法。这是我们的机会:

{'tie': 0.04138424018164999, 'win': 0.9308440557284221, 'lose': 0.027771704089927955}

在这一点上,我感觉非常好。面对一手随机牌,我只有 2.77%的机会输,超过 93%的机会赢。然而,那是乐观的。

翻牌。

考虑到翻牌前有人加注,翻牌圈后只剩下我和大坏蛋,所以大坏蛋很可能有牌,对吗?我们将这一组可能的牌称为范围。这是我们根据几个因素做出的推断,包括恶棍的行为、位置、赌注大小等。这个推论导致了一组我们认为恶棍可能有的组合。在这一点上,我在想这个恶棍:

  • 一对 7 或更好的
  • ace/10 或更好
  • 国王/杰克或更好

我们可以使用类别范围来表示此范围,如下所示:

这使得我们的反派组合从总共 51 * 52–1 = 2651 手牌减少到 144 种组合。让我们计算一下我的赔率,假设恶棍的范围。

{'tie': 0.11423324150596878, 'win': 0.8030711151923272, 'lose': 0.08269564330170391}

根据假设的范围,我的胜算从 93%降到了 80%。但是,我还是有 8.2%的极低输概率。在这一点上,我很舒服。但是我应该打赌吗?我当然希望大反派继续玩下去,不要弃牌。但他在翻牌圈拿到好牌的可能性有多大?让我们看看,如果我们一直玩到最后,他拿到一手牌的几率有多大。

High Card: 0.06978879706152433 
Pair: 0.3662891541679421 
Two Pair: 0.23085399449035812 
Three of a Kind: 0.09733700642791548 
Straight: 0.18498112437506367 
Flush: 0.0040608101214161816 
Full House: 0.04205693296602388 
Four of a Kind: 0.004560759106213652 
Straight Flush: 2.0406081012141617e-05 
Royal Flush: 5.101520253035404e-05 

如果我们一直玩到河牌圈,反派有很大机会做成一对(36%)甚至两对(23%)。他有很大的概率打顺子(18%),甚至做成一盘(9.7%)或满堂彩(4%)。由于恶棍很有可能拿到一手合理的牌,所以我决定下大注,大约是底池的 2/3。反派坦克最后跟注。

转弯处

转牌圈来了,是方块 2。基本上,这是一张空白牌,也就是说,它不会改变我们的游戏。

{'tie': 0.0233201581027668, 'win': 0.9677206851119895, 'lose': 0.008959156785243741}

假设恶棍随机抽牌,我现在有 96%的胜算。

转弯。

然而,考虑到我对反面角色的假设范围,我的胜算从翻牌圈的 80%上升到了现在的 86%。我又下了大注,恶棍跟注,河牌来了。

{'tie': 0.10123966942148759, 'win': 0.8615702479338843, 'lose': 0.0371900826446281}

这条河

梅花国王是河(k·♣).)河牌中的国王更有可能让坏人拿到顺子。所以这对我来说是个坏消息。

{'tie': 0.11818181818181818, 'win': 0.8696969696969697, 'lose': 0.012121212121212121}

现在,我对随机牌的胜算从 96%降到了 87%。但我还是仅以 1.2%的极低概率在输。好吧,坏河也没那么坏,对吧?

这条河。

嗯,还有一个额外的因素。在翻牌圈和河牌圈,恶棍跟了我的大注。他可能有比我想象中更好的东西…对吗?然后我应该调整我的假设范围。

现在,我认为反派不再有 77 或 88 的组合,否则鉴于我的高注,他不会走那么远。我想他可能有一对 99 或更好的牌,可以用 99、10 或 QQ 来凑成一组。他也可能有 JJ 的中对和顺子听牌。或者 KK 和 AA 在转牌圈之前都是顶级对子。我决定保留 a 10 或更好的组合和 Jack 或更好的组合,因为有一种叫做隐含赔率的东西。隐含赔率是对如果你出局了,你能从赌注中赢得多少钱的估计。所以反派可能粘粘的等着打和局(他现在可能刚打了??).因此,我将我的反派的更新范围定义如下:

现在反派的连击从 144 下降到 132。我们来计算一下更新后的赔率。

{'tie': 0.12, 'win': 0.72, 'lose': 0.16}

我现在有 72%的机会获胜(从 86%下降),与我们在回合中的范围分析相比,我失败的机会从 3.7%增加到 16%。我决定过牌,坏人全押,下注金额约为底池的 70%。

一个基本和标准的河流策略告诉你以下内容:

  1. 用你最弱的牌做河牌诈唬
  2. 把你最强的股票作为价值赌注
  3. 用中等强度的摊牌牌-值来检查牌,希望能摊牌
High Card: 0.0 
Pair: 0.5066666666666667 
Two Pair: 0.08 
Three of a Kind: 0.13333333333333333 
Straight: 0.28 
Flush: 0.0 
Full House: 0.0 
Four of a Kind: 0.0 
Straight Flush: 0.0 
Royal Flush: 0.0

根据赔率直方图,我们可以将恶棍可能的牌分为三种类型:

  1. 虚张声势:他拿着{大牌,对子},有 60.66%的几率
  2. 中等强度牌:他有 0.8%的机会拿着
  3. 价值下注(最大筹码):他有 41.33%的机会拿着

反派全押有道理,他的中强度手牌概率太低,无法过牌。因此,我认为他要么是在虚张声势,比如因为错过了听牌,要么他拿着坚果,这是一个价值型下注。这种要么在你持有最少的时候虚张声势,要么在你持有很多的时候价值下注的基本策略有时被称为两极分化下注。反派在这里就是这么干的。

回头看看每种类型(诈唬、中等强度牌、价值下注)的概率,我基本上应该至少赢 60.66%的时间,这是一个保守的衡量标准,因为恶棍可能是价值下注 3。但是我应该打电话吗?

这里出现了另一个概念,叫做底池赔率。底池赔率是指跟注的价格相对于底池的大小。总而言之,如果我赢得底池的概率高于跟注价格与跟注后底池大小的比值,我应该跟注。让我们做一些数学计算:

  1. 胜算≥ 60.66%(保守估计)
  2. 买入价格= 0.7 *底池大小
  3. 跟注后的底池大小= (1 + 0.7 + 0.7) *底池大小
  4. 底池赔率=买入价格/买入后底池大小= 29%

我赢的机会至少是底池赔率的两倍。因此,我开始打电话。结果呢?恶棍翻牌。牌桌一旦安静下来,大家都会发出“哇”的一声,同时盯着牌桌上的王牌杰克,做出一个直过直的局面,让恶棍拿走了我所有的筹码。

讨论和结论

在本文中,我展示了如何用 Python 表示基本的扑克元素(例如,手牌和连击)以及如何在假设随机手牌和范围的情况下计算扑克赔率,同时讲述了威尼斯人一夜的真实历史。

我们展示了扑克是多么令人兴奋(而且可能很有趣)。下面,我展示了我的赢率是如何从翻牌到转牌,然后是河牌,假设恶棍随机发牌,以及推断范围。

我们注意到,即使最后的结果对我不利,我还是最有希望赢得这一局对决。这就是为什么扑克玩家说

你应该把注意力放在你做出的决定上,而不是你得到的结果上。

当然,本文中的所有分析都假设了一些范围和基本的扑克策略,它们形成了我在玩扑克时的思维模型,这里用 Python 实现。我不是职业扑克玩家,这手牌有很多玩法。我认为我犯了几个错误,例如,在翻牌前加注的情况下,低估了恶棍手握 AJ 的机会。

我很好奇其他人会如何使用这里使用的 Python 框架来分析这手牌。你可以随意选择回购

如何计算数据停机的成本

原文:https://towardsdatascience.com/how-to-calculate-the-cost-of-data-downtime-c0a48733b6f0?source=collection_archive---------42-----------------------

介绍一种更好的方法来衡量不良数据对您公司的财务影响

图片由弗拉基米尔·苏哈契夫提供

除了浪费时间和不眠之夜, 数据质量问题 导致合规风险,每年损失收入达数百万美元*以及信任的丧失——但是坏数据真的让您的公司付出了什么代价?我创造了一个新颖的* 数据停机时间计算器 ,它将帮助你衡量坏数据对你的组织的真实财务影响。

什么东西又大又吓人,让最优秀的数据团队夜不能寐?

如果你猜到了“床下的怪物”,不错的尝试,但你错了。答案要真实得多,太普遍了,不管你是否意识到,你可能已经经历过了。

答案?数据停机。数据停机指的是数据不完整、错误、丢失或不准确的一段时间,范围从几个空值到完全过时的表。这些数据消防演习既费时又费钱,还会用垃圾数据破坏优秀的数据管道。

坏数据的真实成本

我最近采访过的一位 CDO 告诉我,他的 500 人团队每周花 1200 个小时处理数据质量问题,而这些时间都花在了推动创新和创造收入的活动上。

为了说明这个问题的范围,这里有一些快速的事实,说明数据团队在数据宕机上必须浪费多少时间:

  • 数据从业者 50 %- 80%的时间都花在收集、准备和修复“难以控制的”数据上。(纽约时报)
  • 数据分析师 40%的时间花在审查和验证数据质量问题的分析上。(福瑞)
  • 销售人员 27%的时间花在处理不准确的数据上。( ZoomInfo )
  • 数据从业者 50%的时间都花在识别、排除和修复数据质量、完整性和可靠性问题上。(哈佛商业评论)

根据这些数字,以及对 150 多个不同行业的数据团队进行的采访和调查,我估计数据团队花费 30–40%的时间处理数据质量问题,而不是从事创收活动。

坏数据的代价不仅仅是浪费的时间和不眠之夜;存在严重的合规性、财务和运营问题,可能会让数据领导者措手不及,从而影响您团队的 ROI 和您公司的利润。

合规风险

几十年来,医疗和金融服务部门肩负着保护个人身份信息(PII)和管理敏感客户数据源的责任,是法规遵从性的典范。

现在,几乎每个行业都在处理用户数据,从电子商务网站到狗粮分销商,从 GDPR 到 CCPA,所有公司都必须遵守严格的数据治理要求和其他隐私保护法规。

不良数据可能以多种方式出现,从错误的电子邮件地址到错误的财务报告,并可能导致严重的后果;例如,在佛蒙特州,关于客户是否想要更新其服务年度订阅的过时信息可能会造成无缝用户体验和集体诉讼之间的差异。这种错误会导致罚款和严厉的处罚。

收入损失

人们常说“时间就是金钱”,但对于任何寻求竞争优势的公司来说,“数据就是金钱”更为准确。

我发现数据宕机和收入损失之间最明显的联系之一是在金融服务业。事实上,一家从事消费贷款买卖的金融服务公司的数据科学家告诉我,一个字段名的改变可能导致 1000 万美元的交易量损失,相当于一周的交易额。

在这些数字的背后是一个现实,即消防数据停机事件不仅浪费了宝贵的时间,而且让团队远离创收项目。数据工程团队花时间调试和修复数据问题,而不是在构建可以为客户增加物质价值的新产品和服务上取得进展。对导致这些问题的原因缺乏了解只会让事情变得更糟。

数据信任的侵蚀

你从数据中获得的洞察力和数据本身一样准确。事实上,我坚信数字会撒谎,使用错误的数据比没有数据更糟糕。**

数据不会自己承担责任,但决策者会,随着时间的推移,坏数据会侵蚀组织对数据团队的信任成为组织的收入驱动力。毕竟,如果你不能依靠数据来支持你的分析,为什么你的 CEO 要依靠数据呢?就此而言,你的客户为什么要这么做呢?

为了帮助您缓解数据停机问题,我们整合了一个数据停机成本计算器,它会考虑您在处理数据停机消防演习而不是开展创收活动时可能会损失多少钱。

您的数据停机成本计算器

因此,数据宕机的年度成本可以通过解决它所需的工程或资源来衡量。

我建议,正确的数据停机时间计算器应考虑解决这些问题的劳动力成本、您的合规风险(在这种情况下,我们使用的是 GDPR 的平均罚款)以及失去利益相关方对您数据的信任的机会成本。根据之前的估计,你可以假设一个工程师大约 30%的时间将花在处理数据问题上。

综上所述,您的数据停机成本计算结果为:

人工成本:(【工程师人数】X【工程师年薪】)X 30%

+

合规风险:[2019 年收入的 4%]

+

机会成本:[如果你加快速度,发布 X 个新产品,获得 Y 个新客户,你本可以获得的收入]

= $数据停机的年成本

请记住,这个等式将因公司而异,但我们发现我们的框架可以让大多数团队开始工作。

衡量数据停机的成本是全面了解坏数据对您公司的影响的第一步。幸运的是,数据停机是可以避免的。通过正确的数据可靠性方法,您可以控制坏数据的成本并从一开始就防止坏数据破坏好的管道。**

有没有另一种方法来衡量数据宕机的影响?很乐意 接到你的

如何计算 Keras 模型中的参数个数

原文:https://towardsdatascience.com/how-to-calculate-the-number-of-parameters-in-keras-models-710683dae0ca?source=collection_archive---------8-----------------------

了解您的顺序 Keras 模型的摘要

照片由戈登·威廉姆斯Unsplash 上拍摄

介绍

尽管新的 ML 框架正在出现,keras 模型仍然是许多数据科学家的最爱。对于新的学习者来说,他们可能有的一个主要问题是通过遵循特定的教程来理解他们正在构建的模型。为了将我们的讨论放在一个环境中,让我们假设我们正在使用 MNIST 数据集构建一个 Conv2D 模型。以下代码向您展示了 Python 代码。

Keras Conv2D 模型

  • 如果你不熟悉 MNIST 数据集,它是由 0-9 位数字组成的图像集合。这些图像是灰度级的,因此每个图像可以用 28×28×1 的输入形状来表示,如第 5 行所示。
  • 请注意,本文的目的不是向您介绍卷积网络的工作原理,因此对这些主题的覆盖范围将是最小的。正如你所见,我们的模型包括一个堆栈的 2D 卷积网络层和最大池层。
  • 在模型的末尾,我们创建了一个密集层,最后输出 10 个激活了 softmax 的节点。节点数对应于模型预测的位数。
  • summary()函数将为模型创建一个摘要,这是本文的重点。

模型摘要

下图显示了summary()函数的输出。每一行代表一个层,每个层都有唯一的名称,这样我们可以毫无歧义地引用这些层。正如您所看到的,我们在前面的代码片段中添加到模型中的层都包含在下图中。

模型摘要

  • 每个层都有一个输出,其形状显示在“输出形状”列中。每一层的输出成为下一层的输入。
  • “Param #”列显示了为每层训练的参数数量。
  • 参数总数显示在最后,等于可训练和不可训练参数的数量。在这个模型中,所有的层都是可训练的。为了不使文章复杂化,我们不打算操纵某些层的可训练性。出于好奇,在 Keras 中,我们可以选择不训练特定的层,这样做的话,一定数量的参数将不可训练。

参数计算

MaxPooling2D 层

先说简单的。您可以注意到,所有 MaxPooling2D 层的参数数量都是 0。原因是这一层什么都不学。它的作用是降低模型的复杂性,并通过找到每个 2×2 池的最大值来提取局部特征。

如前所述,MaxPooling2D 层使用前一层的输出。因此,max_pooling2d层的输入具有从conv2d层输出的(26,26,32)形状。最大池应用于形状为(26,26)的每个过滤器(n=32)。在模型中,对于max_pooling2d层,池的大小是 2×2,因此数据的形状将变成(13,13),也就是(26 / 2,26 / 2)。

同样,对于第二个 MaxPooling2D 层(即max_pooling2d_1),输入形状为(11,11,64)。通过应用 2 x 2 池,产生的输出形状变为(5,5,64),如“输出形状”列所示。

Conv2D 层

在我们的模型中,我们有三个 Conv2D 层,这些层的参数计算遵循相同的原则,如下式所示。数字 1 表示与我们正在学习的每个滤波器相关的偏差。

param_number = output_channel_number * (input_channel_number * kernel_height * kernel_width + 1)

将此公式应用于第一个 Conv2D 层(即conv2d,我们可以用 32 * (1 * 3 * 3 + 1) = 320 计算出参数个数,与模型总结一致。输入通道号是 1,因为输入数据形状是 28 x 28 x 1,数字 1 是输入通道。

对于第二个 Conv2D 层(即conv2d_1),我们有如下计算:64 * (32 * 3 * 3 + 1) = 18496,与该层的模型摘要中显示的数字一致。这里需要注意的两件事是,输出通道号是 64,如模型构建中所指定的,输入通道号是来自先前 MaxPooling2D 层的 32(即max_pooling2d)。

以类似的方式,我们可以计算第三 Conv2D 层的参数数量(即conv2d_2 ): 64 * (64 * 3 * 3 + 1) = 36928,与模型摘要一致。

展平图层

展平的层不学习任何东西,因此参数的数量是 0。然而,知道如何确定输出是很有趣的。如你所见,flatten层的输入具有(3,3,64)的形状。展平层只是展平输入数据,因此输出形状是通过使用 3 * 3 * 64(即 576,与flatten层的输出形状中显示的数字一致)连接所有现有参数来使用它们。

致密层

我们的模型中有两个密集层。参数数值的计算使用以下公式。

param_number = output_channel_number * (input_channel_number + 1)

应用这个公式,我们可以计算致密层的参数数目。对于第一密集层(即dense),输入通道数是 576,而输出通道数是 64,因此参数数是 64 * (576 + 1) = 36928。

对于第二密集层(即dense_1),输入和输出通道数分别为 64 和 10。因此,参数的数量是 10 * (64 + 1) = 650,与模型摘要中显示的数量一致。

结论

在本文中,我们回顾了如何理解 Keras 模型中的参数数量。具体来说,我们使用 Conv2D 模型进行演示。虽然您的模型可能不同,但计算参数数量的原则是相同的-公式应该连接输入和输出数据,并定位模型的定型位置。

如何计算和使用 AUC 分数

原文:https://towardsdatascience.com/how-to-calculate-use-the-auc-score-1fc85c9a8430?source=collection_archive---------5-----------------------

从理论到应用

于尔根·舍夫在 Unsplash 拍摄的照片

受试者操作特征(ROC)曲线是一个图表,允许我们评估二元分类器的性能。对于不平衡数据集,曲线下面积(AUC)分数是根据 ROC 计算的,并且是不平衡数据集的一个非常有用的指标。

在这篇文章中,我们将回顾这个理论,并用 Python 3.x 代码实现它。内容改编自维多利亚大学 Maryam Shoaran 教授的数据挖掘(SENG 474)

数据集和模型

对于这个例子,我们将使用 sklearn 上的乳腺癌威斯康星州数据集。在开始对模型评分并进入本帖的主题之前,我们将做以下工作:

  • 在培训和测试之间拆分数据
  • 特征缩放
  • 拟合逻辑回归(LR)模型

阈值和预测

Photo by 炫铭 on Unsplash

当我们想到朴素贝叶斯(NB)或 LR 等分类器时,它们会产生实例概率或得分。该评分分类器可以与阈值一起使用,以生成诸如是或否的决定

因此,阈值分类是单调的,我们可以利用这一特性来创建 ROC 空间。关键思想表述如下:

相对于给定阈值被分类为阳性的任何实例对于所有较低的阈值也将被分类为阳性。

因此,对于 LR,如果分类器概率估计高于阈值,它将产生肯定的类别预测,否则它将产生否定的类别预测。

此外,许多离散分类器,如决策树或规则集,可以通过查看它们内部及其保存的实例统计信息来转换为评分分类器。例如,类比例可以作为一个分数,类决策只是最普遍的类。

在我们的示例中,我们在 LR 分类器上拟合数据,并在下表df_pred中总结结果:

建立 ROC 空间

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

ROC 图是从线性扫描创建的。根据上表中的信息,我们实施以下步骤:

  • 按降序排列正类的概率
  • 向下移动列表(降低阈值),一次处理一个实例
  • 一边走一边计算真阳性率(TPR)和假阳性率(FPR)

回想一下,TPR 和 FPR 的定义如下:

  • TPR =真阳性/所有阳性
  • FPR =假阳性/全部阴性

我们对上一节的数据帧进行了排序,并从中创建了一个名为df_roc 的新数据帧,如下所示:

信息排序后,我们运行下面的代码块,返回两个数组:一个用于 TPR,一个用于 FPR。

绘制我们的结果,我们得到熟悉的 ROC 曲线:

AUC 分数就是曲线下的面积,可以用辛普森法则计算。AUC 分数越大,我们的分类器就越好。

凸包

约翰·吉本斯在 Unsplash 的照片

给定两个分类器 A & B,我们期望两个不同的 ROC 曲线。考虑下面的情节:

资料来源:Maryam Shoaran

阴影区域被称为凸包,我们应该总是在位于凸包上边界的点上操作。

例如,如果我们想要在40% TPR 下操作,我们选择对应于大约5%的 FPR 的分类器 A。或者,如果我们想要覆盖 TPR 的80%,我们选择比 a 给出更好的 FPR 的分类器 B

组合分类器

Pablo garcía saldaa 在 Unsplash 拍摄的照片

假设我们是一家保险公司,希望向客户推销保险单。然而,由于预算限制,我们只能接触到4000条线索中的800个客户。预期回应率是6%,它的意思是240会说是,3760会说不是

假设我们有两个分类器 A & B,使得 A 的最佳点是(FPR=0.1,TPR=0.2),B 的最佳点是(FPR=0.25,TPR=0.6)。

如果我们的决定基于分类器 A,我们将期望以下候选数目:0.1*3760 + 0.2*(240) = 424。对于 B 来说就是:0.25*3760 + 0.6*(240) = 1084

使用分类器 A,我们接触的人太少,而使用分类器 B,我们超出了预算。这个问题的解决方案如下图所示:

资料来源:Maryam Shoaran

约束线上的点 C (0.18,0.42)位于 A 和 B 之间,它将给出我们期望的性能。我们将k计算为 C 位于 A & B 之间的比例距离,我们将其计算为k=(0.18–0.1)/(0.25–0.1)=.53

在实践中,这意味着对于我们希望分类的每个点,遵循此过程以获得 C 的性能:

  • 生成一个介于 0 和 1 之间的随机数
  • 如果该数字大于 k,则应用分类器 A
  • 如果数量小于 k,则应用分类器 B
  • 重复下一点

结论

与任何数据科学问题一样,一个指标不足以说明全部情况。除了 AUC 之外,准确性、辐射和 f1 分数等指标可以让我们更多地了解分类器的情况。

参考

[## SENG 474

数据挖掘导论。数据准备、模型构建和数据挖掘技术,如聚类…

网站 uvic.ca](https://web.uvic.ca/calendar2020-01/CDs/SENG/474.html) [## sk learn . datasets . load _ breast _ cancer-sci kit-learn 0 . 22 . 1 文档

sci kit-learn:Python 中的机器学习

scikit-learn.org](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_breast_cancer.html)

如何在 4 分钟内改变熊猫的数据类型

原文:https://towardsdatascience.com/how-to-change-datatypes-in-pandas-in-4-minutes-677addf9a409?source=collection_archive---------10-----------------------

在 pandas 中有几个改变数据类型的选项,我将向您展示最常见的选项

当我第一次使用 pandas 时,我一开始并没有对不同的数据类型有一个总体的了解,也没有进一步考虑它们。最迟当你想做第一个算术运算时,你会收到警告和错误信息,所以你必须处理数据类型。我们将看看以下命令:

1.to _ numeric()-将非数字类型转换为数字类型(另请参见 to_datetime())

2.astype()-将几乎任何数据类型转换为任何其他数据类型

我们将首先看一下用于转换非数字数据的to_numeric()astype()是瑞士军刀,几乎可以把任何东西变成任何东西。我们开始吧!

to_numeric()的使用

我们从创建数据帧开始:

>>> amount_list = [1,2,'3',2,'4',5]
>>> cost_list = [1,2,'3',2,'4',5]
>>> date_list = ['2020-01-03', '2020-02-03','2019-12-12','2019-11-14','2020-01-02','2020-02-03']
>>> category_list = ['XZ',1,3,'PT','LM',4]
>>> df = pd.DataFrame({'Date':date_list,'Items': 'Car Saxophone Curler Car Slingshot Duff'.split(),
 'Customer': 'Homer Lisa Marge Lisa Bart Homer'.split(),
 'Amount': amount_list, 'Costs': cost_list, 'Category':category_list})>>> df
         Date      Items Customer Amount Costs Category
0  2020-01-03        Car    Homer      1     1       XZ
1  2020-02-03  Saxophone     Lisa      2     2        1
2  2019-12-12     Curler    Marge      3     3        3
3  2019-11-14        Car     Lisa      2     2       PT
4  2020-01-02  Slingshot     Bart      4     4       LM
5  2020-02-03       Duff    Homer      5     5        4

我们的数据框架中有六列。第一列包含日期,第二和第三列包含文本信息,第四和第五列包含数字信息,第六列字符串和数字

让我们检查第四和第五列的数据类型:

>>> df.dtypes
Date        object
Items       object
Customer    object
Amount      object
Costs       object
Category    object
dtype: object

正如我们所看到的,数据集的每一列都有数据类型 Object。当有文本或文本和非数字值的混合列时,使用此数据类型。我们现在用pd.to_numeric()改变金额列的数据类型:

>>> pd.to_numeric(df['Amount'])
0 1
1 2
2 3
3 2
4 4
5 5
Name: Amount, dtype: int64

所需的列可以简单地作为函数的参数,输出是新生成的数据类型为 int64 的列。如果我们有相应的小数位,Pandas 将输出数据类型 float。重要的是,转换后的列必须用旧列替换,或者必须创建一个新列:

>>> df['Amount'] = pd.to_numeric(df['Amount'])
>>> df.dtypes
Date        object
Items       object
Customer    object
Amount       int64
Costs       object
Category    object
dtype: object

使用.apply方法,也可以一次转换多个列:

>>> df[['Amount','Costs']] = df[['Amount','Costs']].apply(pd.to_numeric)
>>> df.dtypes
Date        object
Items       object
Customer    object
Amount       int64
Costs        int64
Category    object
dtype: object

很简单,对吧?不过,你可能注意到我们漏掉了最后一栏。这里显然有非数字值,它们也不容易转换。如果我们像以前一样尝试,我们会得到一条错误消息:

>>> pd.to_numeric(df['Category'])
Traceback (most recent call last):
  File "pandas\_libs\lib.pyx", line 1897, in pandas._libs.lib.maybe_convert_numeric
ValueError: Unable to parse string "XZ"**During handling of the above exception, another exception occurred: [...]
ValueError: Unable to parse string "XZ" at position 0**

to_numeric()接受错误论点。我们可以用corceignore。使用强制时,所有不可转换的值都存储为 nan,而使用忽略时,原始值将被保留,这意味着我们的列仍将具有混合数据类型:

>>> pd.to_numeric(df['Category'], errors='coerce')

0    NaN
1    1.0
2    3.0
3    NaN
4    NaN
5    4.0
Name: Category, dtype: float64
>>> pd.to_numeric(df['Category'], errors='ignore')

0    XZ
1     1
2     3
3    PT
4    LM
5     4
Name: Category, dtype: object

您可能已经注意到,Pandas 会自动选择数值数据类型。在大多数情况下,这当然就足够了,在整数和浮点之间做出决定就足够了。然而,有时我们有非常大的数据集,我们应该优化内存使用。这可以通过向下浇铸来实现:

>>> pd.to_numeric(df['Amount'],downcast='integer')

0    1
1    2
2    3
3    2
4    4
5    5
Name: Amount, dtype: int8

在这个例子中,熊猫选择了可以容纳所有值的最小整数。

astype()的使用

使用astype()方法。您可以详细指定该列应该转换为哪种数据类型。参数可以简单地附加到列中,Pandas 将尝试转换数据。我们可以再举一次之前的例子:

>>> df['Amount'].astype(int)

0    1
1    2
2    3
3    2
4    4
5    5
Name: Amount, dtype: int32
>>> df['Amount'].astype(float)

0    1.0
1    2.0
2    3.0
3    2.0
4    4.0
5    5.0
Name: Amount, dtype: float64df['Amount'].astype(str)

0    1
1    2
2    3
3    2
4    4
5    5
Name: Amount, dtype: object

您可以专门定义数据类型:

>>> df['Amount'].astype(np.int64)

0    1
1    2
2    3
3    2
4    4
5    5
Name: Amount, dtype: int64

同样使用 astype()我们可以像以前一样一次改变几列:

>>> df[['Amount','Costs']].astype(int)

   Amount  Costs
0       1      1
1       2      2
2       3      3
3       2      2
4       4      4
5       5      5

to_numeric的不同之处在于,我们只能使用raiseignore作为错误处理的参数。Raise 是默认选项:显示错误,不执行任何转换。With ignore 错误将被忽略,无法转换的值将保持其原始格式:

>>> df['Category'].astype(int, errors='ignore')

0    XZ
1     1
2     3
3    PT
4    LM
5     4
Name: Category, dtype: object

结论

我们已经看到了如何用 to_numeric()和 astype()将列转换成熊猫。To_numeric()具有更强大的错误处理功能,而 astype()在转换方式上提供了更多的可能性。了解非数值会发生什么并明智地使用错误参数是很重要的。

如果您喜欢中级和高级数据科学,并且还没有注册,请随时使用我的推荐链接加入社区。

如何将半结构化文本转换成熊猫数据框架

原文:https://towardsdatascience.com/how-to-change-semi-structured-text-into-a-pandas-dataframe-ef531d6baab4?source=collection_archive---------17-----------------------

使用 Python 和 Pandas,我将面向人类读者的文本文档转换成机器可读的数据帧

左边是半结构化数据,右边是熊猫数据框和图表——图片由作者提供

如今,你在互联网上找到的许多数据都被很好地格式化为 JSON、Excel 文件或 CSV。但有些不是。

我需要一个简单的数据集来说明我在 PythonJulia 中关于数据可视化的文章,并决定使用英国气象局公开发布的天气数据(英国伦敦)。

问题是,这是一个文本文件,看起来像一个 CSV 文件,但它实际上是为人类读者格式化的。因此,我需要做一些清理和整理,以便能够创建一个熊猫数据框架和绘图。

这篇文章是关于我用来将这个半结构化文本文件转换成 Pandas 数据框架的不同技术,我可以用它来执行数据分析和绘制图表。

毫无疑问,我可以用文本编辑器转换文件——那会非常乏味。但是我认为用 Python 和 Pandas 编程会更有趣。此外,也许更重要的是,编写一个程序来下载和格式化数据意味着我可以自动更新数据,而不需要额外的努力。

有许多问题。首先,是文件的结构。数据被制成表格,但之前有一个自由格式描述,所以这是第一件必须要做的事情。其次,列名在两行中,而不是电子表格文件中常见的一行。然后,尽管它看起来有点像 CSV 文件,但没有分隔符:数据由数量可变的空格分隔。

最后,数据列的数量在文件中发生了部分变化。数据范围从 1948 年到现在,但 2020 年的数据在另一栏中被标注为“临时的”。

然后是数据的形式。早些年,一些数据丢失,丢失的数据用一串破折号表示。其他列有一个“#”附加到本来是数字的数据上。这些都不能被熊猫识别为数字数据。

为了让熊猫理解这些数据,这些问题都必须解决。

读取数据

这些数据属于公共领域,由英国气象局以简单的文本文件形式提供。您可以在本文顶部的图片中看到这种格式(以及生成的数据帧和从数据中绘制的图表)。

在 Pandas 中读取 csv 文件非常简单,虽然这不是一个传统的 csv 文件,但我将使用该功能作为起点。

Pandas 的函数 read_csv 通常用于读取本地文件或远程文件。不幸的是,这并不适用于 Met Office 文件,因为网站拒绝连接。我不是 100%确定,但我猜想这是因为它不喜欢该函数提供的 HTTP 头中的“用户代理”(用户代理通常是访问网页的浏览器的名称/描述——我不知道,随便,什么 read_csv 设置它)。

我不知道有什么机制可以让我更改 read_csv 的用户代理,但是有一个相当简单的方法:使用 requests 库。(请求库允许您设置包括用户代理在内的 HTTP 头。)

使用请求您可以将文件下载到一个 Python 文件对象,然后使用 read_csv 将其导入一个数据帧。这是代码。

首先导入我们将使用的库:

import pandas as pd
import matplotlib.pyplot as plt
import requests
import io

(如果您有任何缺失,您必须 conda / pip 安装它们。)

下面是下载数据的代码:

url = 'https://www.metoffice.gov.uk/pub/data/weather/uk/climate/stationdata/heathrowdata.txt'file = io.StringIO(requests.get(url).text)

等一下,我不是说要设置用户代理吗?好吧,碰巧的是,请求使用的默认设置似乎是 Met Office 网站可以接受的,所以没有任何进一步的调查,我只是使用了上面看到的简单函数调用。请求调用获取文件并返回文本。然后由 StringIO 转换成一个文件对象。

固定结构

现在我们差不多准备好读取文件了。我需要先看一下原始文件,它显示前 5 行是非结构化的文本。我需要跳过这些行来读取 csv 格式的文件。

接下来的两行是列名。我也决定跳过这些,提供我自己的名字。那些名字是‘年’,‘月’,‘Tmax’,‘Tmin’,‘AF’,‘雨’,‘太阳’。前两个很明显,Tmax 和 Tmin 是一个月的最高和最低温度,AF 是一个月中有空气霜冻的天数,Rain 是降雨量的毫米数,Sun 是日照的小时数。

我用这样的变量记录了这些事情:

col_names = ('Year','Month','Tmax','Tmin','AF','Rain','Sun')
comment_lines = 5
header = 2

这些将在 read_csv 调用中使用。

read_csv 需要为该特定作业设置一些其他参数。它需要知道文件中使用的分隔符,默认是逗号(还有什么?)但是这里的分隔符是一个空格字符,事实上不止一个空格字符。所以,我需要告诉熊猫这个(分隔符=` )。而且因为字段之间有几个空格,熊猫需要知道忽略这些( skipinitialspace=True )。

我需要告诉它应该跳过前几行(skiprows = comment _ lines+header),不要把文件中的任何一行当作标题( header= None)和列名( names=col_names )。

最后,我知道到了 2020 年,列数会发生变化。这通常会引发异常,并且不会返回任何数据帧。但是设置 error_bad_lines=False 会抑制错误并忽略坏行。

下面是创建数据帧天气的结果代码。

weather = pd.read_csv(file,
   skiprows=comment_lines + header,
   header=None,
   names=col_names,
   delimiter=' ',
   skipinitialspace=True,
   error_bad_lines=False)

这将产生一个 dataframe,其中包含第一个坏行(有额外列的行)的所有数据。

第一个数据帧—作者提供的图像

个别数据项需要修复,但下一步工作是追加文件的其余部分。这一次,我将使用类似的参数再次读取该文件,但我将找到我刚刚读取的数据帧的长度,并跳过所有这些行。文件的剩余部分包含 8 列,所以我也需要添加一个新的列名。否则对 read_csv 的调用与之前类似。

file.seek(0)col_names = ('Year','Month','Tmax','Tmin','AF','Rain','Sun', 'Status')
rows_to_skip = comment_lines+header+len(weather)weather2 = pd.read_csv(file,
   skiprows=rows_to_skip,
   header=None,
   names=col_names,
   delimiter=' ',
   skipinitialspace=True,
   error_bad_lines=False)

另外,请注意,我必须使用 seek(0) 将指针设置回文件的开头,否则将没有任何内容可以读取,因为我们已经到达了文件的末尾。

结果如下:

第二个数据框架—作者提供的图像

类似于其他数据帧,但增加了一列。

下一个技巧是合并两个数据帧,为了正确地完成这个,我必须使它们具有相同的形状。因此,我有一个选择,删除第二个数据帧中的状态栏,或者在第一个数据帧中添加一个。出于本练习的目的,我决定不丢失状态信息,并在第一个。额外的一列称为状态,对于 2020 年的数据,其值为“临时”。因此,我将在第一个数据帧中创建一个状态列,并将所有值设置为“Final”。

weather['Status']='Final'

现在,我将第二个数据帧追加到第一个数据帧,并添加参数 ignore_index=True ,以便不复制索引,而是为组合的数据帧创建一个新的索引。

weather = weather.append(weather2, ignore_index=True)

组合数据框架—作者提供的图像

修复数据类型

现在我们必须处理每一列中的数据。让我们来看看数据类型。

weather.dtypes

初始数据类型—按作者分类的图像

正如您所看到的,Pandas 已经尽了最大努力来解释数据类型:Tmax、Tmin 和 Rain 被正确地识别为 floats,Status 是一个对象(基本上是一个字符串)。但是 AF 和 Sun 也被解释为字符串,尽管实际上它们应该是数字。这是因为 Sun 和 AF 列中的一些值是字符串'— -'(表示没有数据)或者数字附有#符号。

只有太阳一栏的日照时数带有#符号,所以第一件事就是去掉那一栏中的那个字符。字符串替换完成了这项工作;下面的代码通过用空字符串替换来删除字符。

weather['Sun']=weather['Sun'].str.replace('#','')

现在,Sun 列中的数字格式正确,但 Pandas 仍然将 Sun 和 AF 列数据视为字符串,因此我们无法将该列读取为数字,因此无法使用该数据绘制图表。

改变数据的表示很简单;我们使用函数 to_numeric 将字符串值转换成数字。使用这个函数,字符串将把字符串“123.4”转换成浮点数 123.4。但是我们要转换的列中的一些值是字符串'— -',不能合理地解释为数字。

诀窍是将参数错误设置为强制。这将把任何不能被解释为数字的字符串强制转换为值 NaN (不是数字),这在 Python 中相当于空数值。这正是我们想要的,因为这个数据帧中的字符串“--”表示“没有数据”。

下面是更正这两列中的值的代码。

weather['AF']=pd.to_numeric(weather['AF'], errors='coerce')
weather['Sun']=pd.to_numeric(weather['Sun'], errors='coerce')

数据帧现在看起来像这样:

调整了数据类型的数据框架—按作者分类的图像

您可以看到 NaN 值,如果我们再次查看数据类型,我们会看到:

新的数据类型—按作者分类的图像

现在所有的数字数据都是浮点值——这正是我们所需要的。

使用数据

为了说明这就是我们想要的,这里画了一张 2000 年的降雨量图。

weather[weather.Year==2000].plot(x='Month', y='Rain')

一个简单的图形——作者的图像

任务完成。

如果你想知道这篇文章顶部的图表是从哪里来的,这是绘制 1950 年、1960 年、1970 年、1980 年、1990 年、2000 年和 2010 年每月最高温度的代码。

ax = weather[weather.Year==1950].plot(x='Month', y='Tmax',
   label='1950')
ax = weather[weather.Year==1960].plot(x='Month', y='Tmax', 
   label='1960',ax=ax)
ax = weather[weather.Year==1970].plot(x='Month', y='Tmax',  
   label='1970',ax=ax)
ax = weather[weather.Year==1980].plot(x='Month', y='Tmax', 
   label='1980',ax=ax)
ax = weather[weather.Year==1990].plot(x='Month', y='Tmax', 
   label='1990',ax=ax)
ax = weather[weather.Year==2000].plot(x='Month', y='Tmax', 
   label='2000',ax=ax)
weather[weather.Year==2019].plot(x='Month', y='Tmax', label = 
   '2010', ax=ax, figsize=(15,10));

稍微详细一点的图表——作者提供的图片

您不太可能会发现需要对我在这里演示的文本文件进行完全相同的操作,但是我希望您可能会发现我的经验很有用,并且您能够将我在这里使用的技术用于您自己的目的。

感谢阅读,如果你想了解我发表的文章,请考虑在这里订阅我的免费简讯。

更新:我在这里 写了一个新的更通用版本的上述程序

如何追踪一个项目想法

原文:https://towardsdatascience.com/how-to-chase-down-a-project-idea-8ea39e4f453c?source=collection_archive---------96-----------------------

当你想开始一个项目时,获得一个想法可能是最难的部分

龙凤在 Unsplash 上的照片

如果你曾经问过这个领域的人,“学习[编码/数据分析/计算机科学领域的任何其他东西]的最好方法是什么?”不可避免地,你会听到,“做一个你可以练习这些技能的项目。”当然,说起来容易做起来难。要做到这一点,你需要想出一个主意,弄清楚你将如何完成这件事(并确保这个主意是可以做到的),并坚持下去,直到你有一个成品。

我最近和我的合作伙伴完成了一个项目(实际上是一个仍在进行中的更大项目的分支),你可以在这里使用。它从一个著名的针织图案网站 Ravelry 获取一个图案 URL,并返回一个搜索 URL,显示与您输入的图案相似的图案。当然,这不是什么大事情,但是一个完成的小项目总比一个半途而废的庞然大物要好。我是这样得出我的项目想法的:

“你不能等待灵感。你必须用一个俱乐部去追求它。”杰克·伦敦

如果你只是等待一个完整的项目想法出现在你的脑海中,你可能会盯着天花板几个星期。也许你会运气好,想出一些绝妙的主意,但更有可能的是,你只会坐在那里一事无成。有许多不同的方式来达成项目想法,但这里是我实现我的想法的步骤:

思考技能

正如我在一开始提到的,项目是磨练你各方面技能的最佳方式。因此,当你考虑你想做什么样的项目时,想想你在哪些方面不稳定,在哪些方面需要改进。技能越集中,结果越好。如果你只是说,“我想成为更好的[编码员/数据科学家/软件工程师/等等。],“这可能意味着很多不同的事情,所以仅仅有这样的目标并不能帮助你完成一个有意义、有用的项目。就像你如何构思一个假设一样,你需要明确你的目标。例如,在我的项目中,我知道我想更好地调用 API。虽然我在技术上知道如何做到这一点,但我对自己的能力不是很有信心,所以我想改变这一点。现在,我有了项目想法的第一个拼图:从 API 获取数据。

思考领域

你可能会在这个项目上工作一段时间。如果你想被激励去工作并完成这个项目,你最好喜欢做它。不要仅仅因为你认为某个领域或某个数据集在简历上看起来不错,就选择它。选择一个你真正想从事的领域。也许你会使用你想从事的行业的数据做一个项目(例如,如果你想从事医疗行业,就使用癌症数据集)。或者也许你会像我一样,从你已经有的爱好中摆脱出来。就我而言,我从 10 岁或 11 岁起就开始编织。我有一个 Ravelry 账户已经有八年半多了。我看到 Ravelry 有一个我可以访问的 API,所以我决定用 Ravelry 的数据做一个项目。所以现在我有两块我的想法拼图:编织和 API 调用。

想想最终的产品

你想用你的项目完成什么?我知道我们已经讨论过你可能想如何提高某项技能,当然,你想增加你的项目组合,但是你具体想用这个项目做什么呢?同样,当你真的喜欢你正在做项目的领域时,这个问题就更容易回答了。也许你在你的领域里有一个特定的问题想要得到答案,比如吃冰淇淋是否会降低你患某种癌症的几率。或者你可能想开发一种预测运动结果的方法。或者你想开发某种工具,你希望它存在于这个世界上

就我个人而言,我是那种会因为花半个小时浏览网飞而不挑选一些值得看的东西而感到难以置信的内疚的人。我喜欢任何一种工具,它能向我展示与我正在看的东西相似的东西,或者根据我喜欢的东西向我推荐东西。Ravelry 实际上没有,所以我决定自己开始建立一个推荐系统。有了这些,我现在有了一个完整的项目想法,创建一个针织图案推荐系统。正如我所展示的,这个想法并不是突然出现在我脑海中的。我花了很多时间思考一个项目的不同方面,并决定如何将所有事情联系在一起。换句话说,我用球杆追逐灵感。

下周请继续关注,我将讨论我是如何回答这个问题的,“现在我该如何实际做到这一点?”

如何检查熊猫中缺失的值

原文:https://towardsdatascience.com/how-to-check-for-missing-values-in-pandas-d2749e45a345?source=collection_archive---------11-----------------------

如何发现和鉴定熊猫缺失值的介绍

每一位数据科学家在日常工作中都会遇到问题。有必要弄清楚是否有遗漏,在哪里可以找到遗漏,以及遗漏发生的频率。基于此,数据科学家必须决定如何在进一步分析中处理缺失数据。

1)寻找失踪人员

寻找缺失通常是数据分析的第一步。在开始时,问题是是否有任何遗漏,如果有,有多少。通常情况下,Pandas 提供了几种方法来确定错过的次数。根据数据帧的大小,性能会有很大的差异。首先,我们简单地期望结果为真或假,以检查是否有任何遗漏:

df.isna().any().any()
True

这正是我们想要的。现在我们知道有失踪,但执行花了多长时间?

%timeit df.isna().any().any()
47.8 ms ± 1.24 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

我们来比较几种方法:

%timeit df.isnull().any().any()
46.2 ms ± 899 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)%timeit df.isnull().values.any()
44.6 ms ± 731 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)%timeit df.isna().values.any()
41.8 ms ± 229 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)%timeit np.isnan(df.values).any()
41.3 ms ± 368 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

我们试过五种不同的方法,结果都一样。带 Numpy 的版本比最慢的版本快 14 %。

2)遗漏的频率(绝对)

我们已经在寻找丢失中看到了性能上的差异。第一步,我们只想知道是否有任何遗漏。现在我们还想知道我们的数据帧中有多少缺失。首先,我们再次看看我们期望的结果:

df.isna().sum().sum()
4600660

现在我们有了这样的信息,我们具有 2500 万个单元(5000*5000)的数据帧包含大约 460 万个缺失。

让我们看看这里的性能差异是否更大:

%timeit df.isna().sum().sum()
117 ms ± 2.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)%timeit df.isnull().sum().sum()
115 ms ± 1.41 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)%timeit np.isnan(df.values).sum()
89 ms ± 706 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

同样,Numpy 版本是最快的版本。这一次 Numpy 版本大约快了 24 %。

3)缺失的频率(相对)

有时,您可能只想确定每列缺失的相对频率,以决定是简单地删除还是替换缺失:

df.isna().sum()/(len(df))*100**0       17.98
1       18.90
2       18.66
3       18.02
4       18.70
        ...  
4995    18.88
4996    18.72
4997    18.68
4998    17.76
4999    19.32**
Length: 5000, dtype: float64

现在我们有了一个熊猫系列,我们可以随心所欲地处理它:

temp = df.isna().sum()/(len(df))*100print("Column with lowest amount of missings contains {} % missings.".format(temp.min()))
print("Column with highest amount of missings contains {} % missings.".format(temp.max()))**Column with lowest amount of missings contains 16.54 % missings.
Column with highest amount of missings contains 20.64 % missings.**

Pandas 还可以用于量化和分析大型数据集中的缺失。

4)确定有缺失的列

在某些情况下,确定缺失的列并将它们与其他列分开处理可能会很有用:

>>> df.loc[:, df.isnull().any()].columnsInt64Index(**[   0,    1,    2,    3,    4,    5,    6,    7,    8,    9,
            ...
            4990, 4991, 4992, 4993, 4994, 4995, 4996, 4997, 4998, 4999]**,
           dtype='int64', length=5000)

在这种情况下,结果当然不那么令人兴奋—我们在每一列中都有一个缺失。

5)显示缺失的行

在数据分析的最后一步,您可能希望查看单个案例,以了解为什么会有遗漏以及如何处理它们:

>>> df.dropna()
Empty DataFrame
Columns: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...]
Index: []**[0 rows x 5000 columns]**

如您所见,我们的数据集中没有每列都包含缺失的行。在下一步中,我们可以指定要检查缺失的列:

>>> df.dropna(subset=[1]).head(5)
     0     1     2     3     4     5     ...  4994  4995  4996  4997  4998  4999
10    NaN   0.0   NaN   NaN   NaN   NaN  ...   NaN   NaN   NaN   NaN   NaN   NaN
136   NaN   0.0   NaN   NaN   NaN   NaN  ...   NaN   NaN   NaN   NaN   NaN   NaN
431   NaN   0.0   NaN   NaN   NaN   NaN  ...   NaN   NaN   NaN   NaN   NaN   NaN
435   NaN   0.0   NaN   NaN   NaN   NaN  ...   NaN   NaN   NaN   0.0   NaN   NaN
474   NaN   0.0   NaN   NaN   NaN   NaN  ...   NaN   NaN   NaN   NaN   NaN   NaN**[5 rows x 5000 columns]**

如果不为 dropna 函数指定列,将得到只包含缺失的行。为了进一步分析,指定一个或多个列作为子集是有意义的。

结论

我们已经知道如何确定数据帧中是否有缺失,如果有,有多少。Numpy 变体在每种情况下都是最快的,尽管性能差异只有在数据帧非常大的情况下才变得明显。

我们还看到,我们有无数的可能性以其他方式量化和可视化错过的数量。此外,我们还可以检查个别案例,以决定如何进一步进行分析。

如果您喜欢中级和高级数据科学,并且还没有注册,请随时使用我的推荐链接加入社区。

如何选择预处理技术来减轻人工智能偏差

原文:https://towardsdatascience.com/how-to-choose-a-pre-processing-technique-to-mitigate-ai-bias-11ed9fc0f881?source=collection_archive---------49-----------------------

不同预处理技术的高级概述

拉奎尔·马丁内斯在 Unsplash 上拍摄的照片

早些时候,在我的博客关于如何处理人工智能偏差的系列文章中,我们探索了深度重新加权【1】,这是一种减少偏差的预处理技术。然而,这只是一种技术。预处理缓解措施的类型从简单的数据准备方法,如取样、按摩、重新称重[1]到更复杂的方法,如优化数据转换,以减少偏差和受保护或敏感属性的可预测性[2–3]。

在这篇文章中,我不想深入讨论任何一种技术,而是想讨论一个数据科学家在预处理阶段试图解决偏差时可能有的选择。也就是说,这些技术之间的区别是什么,以及它们中的每一种如何对数据科学家和 ML 实践者有益?在我开始讨论它们之前,理解 AI 偏见的来源是很重要的。

正如我在人工智能偏差系列的第一篇帖子中提到的,偏差可能会悄悄进入 ML 管道,并被各种来源的模型预测放大。数据不足、数据收集不一致以及数据中存在的不良做法会通过各种机制导致模型决策中的偏差。例如,模型可能无法为代表性不足的群体提供高度确定性的预测。或者,它可能从历史数据中的现有偏差中了解到歧视性行为,并因此延续甚至增加其预测中的偏差水平。

下面是两个数据缺陷的例子,这些数据缺陷会导致模型偏向某些群体:

  • 一个图像数据集被放在一起用于面部识别。模型未能正确识别某些群体的原因可能是数据集中这些群体的图像数量不足。
  • 数据集是根据一家公司的历史雇佣情况创建的。该模型不愿意给某些群体的候选人打高分,这可能不仅是因为数据不平衡,也是因为数据中隐含的历史性歧视性招聘做法。

当呈现偏斜的、不平衡的数据或缺乏多样性的数据时,例如上述面部识别数据集,模型对代表性不足的群体表现出歧视行为的倾向反映了模型不能对不同的群体同等地执行。在这些情况下,诸如采样和重新加权等技术可以通过调整数据中不同组的平衡来减少偏差,从而增加模型的学习机会。

另一方面,如果历史偏见和歧视是数据中偏见的根本原因,如招聘示例,重新标记或数据转换更可能是减少偏见的最佳方法。即使您已经确保数据中没有任何要素充当敏感属性的代理,有偏差的标注仍可能导致模型通过性能误差呈现偏差,例如组之间的假阳性或假阴性有显著差异。由于模型无法为相似但属于不同组且具有不同标记结果的记录找到有意义的模式,因此模型可能表现出不确定性。这些不稳定的预测会导致对某些群体的偏见。

例如,考虑来自不同群体(例如种族、性别)的两个候选人,他们具有相同的特征值集—他们上同一所大学,具有相同的工作经验和相同的技能集—并且他们已经从数据中删除了任何受保护或敏感的属性及其代理,但是他们每个人都具有不同的目标值,一个被雇用,一个没有被雇用。当相似的记录导致不同的标签时,模型将很难学习,因此将无法高度确定地预测结果。通过使用改变相似记录的标签的技术,你将因此改进模型的学习过程并减少预测中的偏差。

在不同的情况下,除了有偏差的标签,如果怀疑存在代理特征,转换数据以显著降低或消除敏感属性和其他特征以及目标之间的相关性更适用。当数据中包含代理要素时,基于排除敏感属性的要素列表构建的模型仍然可以间接推断出单个记录与这些敏感属性中不同组的关联。例如,如果邮政编码或运动是要素的一部分,模型可以从记录中推断出种族或性别。这种推断使模型能够从数据中学习歧视行为,并将其编码到预测中。为了减轻这种情况,同步的特征变换和标记对于降低模型的推理能力是至关重要的。

正如我们在这里和之前的博客中所讨论的,这些技术有可能减少训练数据中的偏差。对于数据科学家由于公司政策或法律限制而无法访问敏感属性的情况,可以与数据所有者共享这些技术,以便在与数据科学家共享之前应用于数据。

不幸的是,由于这些技术对模型的数据推断的盲目性,某种程度的偏差仍然会蔓延到模型预测中。在本系列的下一篇文章中,我将通过对处理中和处理后建模阶段的技术进行同样的概述来解决这个问题,在处理中和处理后建模阶段,模型的推理被直接访问。

参考资料:

[1]卡米兰,费萨尔和考尔德斯,图恩。无区别分类的数据预处理技术。知识与信息系统,33(1):1–33,2012

[2] Calmon,f .,Wei,d .,Vinzamuri,b .,Ramamurthy,K. N .,和 Varshney,K. R .为防止歧视而优化预处理。神经信息处理系统进展 30,2017。

[3] M. Feldman、S. A. Friedler、J. Moeller、C. Scheidegger 和 S. Venkatasubramanian。验证和消除不同的影响。2015 年在 KDD。

[5]“成人——UCI 机器学习。”5 月 1 日。1996 年,【http://archive.ics.uci.edu/ml/datasets/Adult】T4。

[6] R. K. E. Bellamy 等人,“AI Fairness 360:用于检测和减轻算法偏差的可扩展工具包”,载于《IBM 研究与发展杂志》,第 63 卷,第 4/5 期,第 4:1–4:15 页,2019 年 7 月 1 日-9 月。

如何为数据集选择线性回归还是非线性回归

原文:https://towardsdatascience.com/how-to-choose-between-a-linear-or-nonlinear-regression-for-your-dataset-e58a568e2a15?source=collection_archive---------12-----------------------

在线性和非线性回归之间进行选择以获得更好的模型拟合度和精确度的一般准则。

Justin Luebke 在 Unsplash 上拍摄的照片

任何数据科学家都从回归分析开始他们的旅程,因为它构成了所有预测建模的基础,人们可以轻松地联系到幕后的数学和统计数据,这对任何机器学习模型都是必不可少的。还需要了解在数据集上实施的各种不同的回归技术,以获得良好的准确性和最小的错误率 ✌️

在本文中,我们将通过一些图表和总结来确定哪些回归适合我们的数据集。此外,本文假设您事先了解回归概念及其假设。

👉线性回归

线性回归是一种非常常见的模型,用于对连续数据进行预测分析。下面是线性回归的方程式。

线性回归方程

让我们用下面的样本数据集来看一个例子。

线性回归数据集

根据周数(X 变量),我们需要预测售出的汽车数量。

下面是数据的散点图。

散点图的线性趋势线

从上面的原始散点图中,我们可以看到在末端有一个曲率,并且线性趋势线没有对该数据集进行公正处理。让我们建立一个回归模型并解释结果。

线性回归输出的汇总输出

根据上面的输出,R 平方为 0.80,标准误差为 45。我们也将尝试检查剩余的情节。

👉线性模型的残差图

观察值和观察值的平均值之差称为残差。这些对于回归非常重要,因为它们表明了模型在多大程度上解释了数据集中的变化。

残差图形成违反线性回归假设的曲线

从上面可以看出,残差形成了一个曲线模式,这违反了线性模型的一个主要假设。残差应该形成随机性,但不是导致基于一个误差预测另一个误差的任何类型的模式。因此,我们可以确定线性模型不适合我们的数据集。

👉非线性回归

多项式回归是线性回归的扩展,它拟合目标变量和独立变量之间的曲线关系。

多项式回归增加了额外的独立变量,这些变量是原始变量的幂。这里,我们将度取为 2,因此建立了一个二次回归模型。

非线性回归方程

下面是为二次回归模型创建的数据集。添加了一个额外的独立变量,即周数*2

为二次回归模型创建周数*2

让我们做一个散点图,并绘制一个多项式趋势线,以检查如何最好地拟合曲线。

散点图上的多项式趋势线

从上面可以看出,多项式趋势线试图比直线更好地拟合曲率。

让我们为之前创建的非线性数据集建立一个模型。

非线性回归模型的摘要输出

从上面的输出中,我们可以看到总体 R 平方值增加了 0.90,标准误差最小。

👉二次模型的残差图

具有随机误差的二次模型的残差图

从上面的图中,我们可以看到残差中存在随机性,这解释了方差,因此满足回归模型的假设。

比较线性和非线性回归输出

摘要

在本文中,我们了解了非线性回归模型如何更好地适用于由非线性回归输出和残差图确定的数据集。

在建立任何回归模型之前,查看散点图并检查回归线周围观察值的紧密拟合是非常重要的。此外,残差图在决策中也起着至关重要的作用。但是,应该记住,向非线性回归中添加更多的独立变量会使模型过度拟合。因此,在向非线性回归模型中添加更多变量时,需要格外小心。

感谢阅读,快乐学习!🙂

如何选择最佳的 Keras 预训练模型进行图像分类

原文:https://towardsdatascience.com/how-to-choose-the-best-keras-pre-trained-model-for-image-classification-b850ca4428d4?source=collection_archive---------6-----------------------

有疑问的时候,用数据来决定!

选择过多。由m . W .Unsplash 拍摄的照片

决定在你的深度学习任务中使用哪个预先训练的模型,与经典的两难问题处于相同的水平,比如在网飞上看什么电影,在超市买什么麦片(附注:买糖最少、纤维含量最高的那种)。这篇文章将使用 Python 中的数据驱动方法来为cats_vs_dogs 数据集找出最佳的 Keras 预训练模型。这篇文章和提供的代码也将帮助您轻松地为您的问题数据集选择最佳的预训练模型。

目录

  1. 背景
  2. 选择型号的标准
  3. 代码
  4. 资源

背景

迁移学习是机器学习中的一种技术,我们可以采用在一项任务中开发的模型,并将其作为其他类似但不同的任务的起点。迁移学习在深度学习中非常流行,因为知识从一个“父”模型“迁移”到“子”模型意味着“子”模型可以用比“父”模型小得多的数据集训练到高精度。你可以在这个优秀的【中帖】找到更多关于迁移学习的细节

像 TensorFlow 和 Pytorch 这样的高级深度学习框架通过在包本身中包含几个预先训练的模型,使得利用迁移学习的力量变得非常容易。例如,【tensor flow Keras API】包含了 18 个在 ["ImageNet"] 数据集上预训练的高度先进的模型架构。你可以把“ImageNet”想象成图像分类数据集的 SAT。

今天的大多数图像分类深度学习任务将从下载这 18 个预训练模型中的一个开始,稍微修改模型以适应手头的任务,并且仅训练自定义修改,同时冻结预训练模型中的层。由于“ImageNet”收集了许多真实世界的图像,因此这种方法在真实世界的图像分类任务中给出了非常高的准确度。

然而,选择使用 18 个预训练模型中的哪一个并不总是一门精确的科学。许多开发人员坚持他们熟悉的模型,并在过去给了他们很好的结果。作为一名数据科学家,我想知道是否有更好的、数据驱动的方法来选择预先训练的模型,不受个人偏见的影响。确实有!这篇文章的其余部分讨论了我的过程,代码可以直接用于你的项目。

选择模型的标准

一般来说,在行业中执行任何机器学习任务时,都有两个相互竞争的标准:

  1. 模型的准确性:越高越好
  2. 模型训练和预测的速度:越快越好

这两个标准非常简单。我们想要在验证数据上给我们最高准确度的模型,因为它可以做出有用的预测。我们还希望模型尽可能快地训练和预测,因为在生产中,我们可能需要每秒提供数百或数千个预测。

够简单吗?嗯,就像生活中的所有事情一样,我们不能鱼与熊掌兼得(因此有了这个标题图像)!一般来说,为了获得更高的精度,我们需要使用“更深”或更大的模型。但是更大的模型有更多的参数,这使得它执行起来更慢。我们可以从下图【参考】中看到模型的精度和规模/运算次数之间的权衡。

图像分类精度与模型大小/运算次数的关系。一般来说,较大的模型往往具有较高的精度,但需要更多的运算,这使得它们速度较慢。来源

因此,这是我们需要取得的平衡。对于行业中的大多数深度学习部署,我们选择最小的模型,为我们提供足够好的准确性。因此,我们需要在许多可用的模型中进行试验,以选择满足这些标准的模型。

另一方面,如果您只关心实现最高的精度,而不考虑对速度的影响,那么您的方法可以是使用集成技术来组合所有这些模型!事实上,在学术界和 ML 竞赛中,ensembling 非常受欢迎。

密码

我的方法很简单,如下图所示。我们将使用 Python 找到 Keras 中所有预训练的模型,然后逐个循环。在本文中,我们将在 tensor flow【cats _ vs _ dogs】数据集上训练模型。您可以用任何其他数据集替换它,包括您自己的自定义数据集。

选择最佳预训练 Keras 模型的步骤

第一步

第一步是导入必要的包。如果您缺少这些包,您可以使用pip install <package-name>来安装它们。我们还会为后续的模型训练设置一个batch_size。由于我使用的是低成本的 GPU,我将只使用 32 的小批量。

第二步

通过列出tf.keras.applications中的所有函数,自动从 Keras 获得所有可用预训练模型的列表。由于每个模型都是通过从tf.keras.applications调用一个函数来实例化的,当我们使用inspect.isfunction列出这个模块中的所有函数时,我们得到了所有模型的列表。截至本文撰写时,在【tensor flow 2.2】中,我们可以使用的模型共有 18 个。

您可以通过手动将元素添加到model_dictionary以及遵循语法model_dictionary["new_model_name"] = new_model_function()来将任何其他定制预训练模型添加到实验中,其中new_model_function()应该返回定制预训练模型,而不返回最终输出Dense层。如果您不想更改下面的任何其他代码,模型的输入形状应该是(224,224,3)。

第三步

下载一些图片来运行实验。当您为您的用例运行实验时,您应该修改这个步骤来加载您的数据。

输出:

Num train images: 16283         
Num validation images: 6979         
Num classes: 2         
Num iterations per epoch: 508

第四步

预处理输入图像。一些预先训练的模型要求图像的大小为(224,224,3),而一些要求为(331,331,3)。我们使用这个步骤来准备两种尺寸的图像,并通过将每个像素除以 255 来归一化它们。我们还一次性编码标签,这样我们就可以在训练中使用categorical_crossentropy loss。

第五步

通过下载没有输出层的预训练模型来循环每个模型,并冻结权重。然后,我们构建一个空的Sequential模型,并首先向其中添加预训练的模型。然后,我们添加一个带有softmax激活的单一输出密集层,并使用categorical_crossentropy损失对其进行编译。最后,我们通过为3 epochs调用model.fit来训练模型。我们将参数的数量(模型的大小)和每个模型的最终精度记录到一个字典中,以可视化结果。如果在模型下载AttributeError: 'str' object has no attribute 'decode'过程中出现以下错误,请安装一个较低版本的h5py【source】

pip uninstall h5py
pip install h5py<'3.0.0'

在谷歌云平台上的一个带有一个NVIDIA Tesla T4 GPU 的n1-standard-4 (4 个 vCPUs,15 GB RAM)上,整个过程需要大约 3 个小时。

第六步

让我们通过将其转换为数据帧并按num_model_params的升序排序来可视化结果,因为我们的目标是选择具有足够精度的最小模型。在这个例子中,MobileNet模型已经提供了97%精度;因此,我们可以直接使用它。MobileNetV2NASNetMobile是我们可以考虑进行微调实验的另外两个模型。如果我们选择的模型的准确性仍然不足以完成我们的任务,我们可以通过进一步微调这些选择的模型、添加数据扩充等来进行试验。我们将在一个已经被证明接近我们要求的模型上应用典型的深度学习模型改进实验。

输出:

| model_name        | num_model_params | validation_accuracy |
|-------------------|------------------|---------------------|
| MobileNetV2       | 2257984          | 0.9475569725036621  |
| MobileNet         | 3228864          | 0.9773606657981873  |
| NASNetMobile      | 4269716          | 0.9753546118736267  |
| DenseNet121       | 7037504          | 0.9273535013198853  |
| DenseNet169       | 12642880         | 0.95572429895401    |
| VGG16             | 14714688         | 0.9107322096824646  |
| DenseNet201       | 18321984         | 0.9419687390327454  |
| VGG19             | 20024384         | 0.8948273658752441  |
| Xception          | 20861480         | 0.9550078511238098  |
| InceptionV3       | 21802784         | 0.9859578609466553  |
| ResNet50V2        | 23564800         | 0.9802263975143433  |
| ResNet50          | 23587712         | 0.49620288610458374 |
| ResNet101V2       | 42626560         | 0.9878206253051758  |
| ResNet101         | 42658176         | 0.49620288610458374 |
| InceptionResNetV2 | 54336736         | 0.9885370135307312  |
| ResNet152V2       | 58331648         | 0.9840951561927795  |
| ResNet152         | 58370944         | 0.49620288610458374 |
| NASNetLarge       | 84916818         | 0.9795099496841431  |

标绘结果

模型精度与参数数量的结果

结论

总之,我介绍了一种数据驱动的方法,从 Tensorflow Keras API 中的一组预训练模型中选择最合适的模型。在大多数工业应用中,我们会选择参数数量最少的模型,为进一步研究提供足够好的精度。我们可以通过在[ 步骤 2 ]中手动将项目添加到model_dictionary中,轻松扩展这种方法,以包括 Keras 未提供的其他型号。

最后,广泛的实验和数据驱动的决策是所有机器学习应用程序成功的关键。我希望这篇文章能激发你思考如何在日常工作中做出更多数据驱动的决策。

资源

  • 你可以在【GitHub】找到这篇文章中用到的所有代码。
  • 您也可以使用 Google Colab 直接运行代码,无需任何设置。只需记得进入编辑→笔记本设置,选择一个GPU硬件加速器:【在 Colab 中打开】

感谢您的阅读!

编辑:更新了 GitHub gists 的代码片段

如何选择最佳线性回归模型——初学者综合指南

原文:https://towardsdatascience.com/how-to-choose-the-best-linear-regression-model-a-comprehensive-guide-for-beginners-754480768467?source=collection_archive---------11-----------------------

元件 5 数码Unsplash 拍摄的图像

如果你是数据科学或统计学的初学者,有一些线性回归的背景,并且正在寻找评估你的模型的方法,那么这个指南可能适合你。

本文将讨论以下用于选择“最佳”线性回归模型的指标:R 平方(R)、平均绝对误差(MAE)、均方误差(MSE)、均方根误差(RMSE)、赤池信息标准(AIC)以及考虑偏差的修正变量。将假定您了解线性回归。我希望你喜欢读这篇文章,觉得它有用,并学到一些新东西:)

R 平方(R )

y =因变量值,y_hat =模型预测值,y _ bar =的平均值

R 值,也称为决定系数,告诉我们用 y_hat 表示的预测数据,解释了用 y 表示的实际数据。换句话说,它代表了拟合的强度,但是它并没有说模型本身的任何事情-它没有告诉你模型是否好,你选择的数据是否有偏差,或者你是否选择了正确的建模方法。我将用下面的例子来说明这一点。

R 值的范围从 0 到 1,较高的值表示强拟合,较低的值表示弱拟合。通常,大家都同意:

R < 0.5 → Weak fit

0.5 ≤ R² ≤ 0.8 → Moderate fit

R² > 0.8 →强配合

注意:理论上 R < 0 是可能的,但是这些会出现在明显可怕的配合中,因此本文不会讨论。

你可能会想,如果 R 不代表模型有多好,那么“拟合强度”到底是什么意思?这意味着,平均而言,你的预测值(y_hat)与你的实际数据(y)偏差不大。下面的例子将说明这一点。

(左)线性预测的二次模型,(右)线性预测的线性模型

上面的两个模型都预测了给出“强”拟合的线,因为它们具有高 R 值,并且还捕捉了实际数据点与拟合线的小偏差。然而,很明显,尽管左边的模型具有更高的 R 值,但是右边的模型是更好的模型。事实上,最左边的模型很糟糕,因为它没有捕捉到数据的曲率。因此,高 R 并不意味着拟合良好或合适,它只是意味着实际点与拟合点的偏差平均来说很小。

有时,一个模型可能有一个低 R 值,但实际上是一个很好的数据模型。考虑下面的例子:

(左)用直线拟合正弦曲线,(中)用有小噪声的直线拟合故意偏斜的直线,(右)用有大噪声的直线拟合正确的直线

与前面的例子一样,左边的模型非常不适合,但“适合度”适中,因此与右边的模型相比,仅根据 R 值,人们可能会认为最左边的模型更好。如图所示,这是错误的。中间款呢?它的 R 是右边模型的三倍,而且,从视觉上看,似乎并不完全离谱。因此,有人可能会得出这样的结论:中间模式比正确模式好得多?

不对。

中间和右边模型中的数据点基于同一条线, y=x+e ,其中 e 是正态分布中随机产生的误差。它们之间的唯一区别是,误差幅度在最右边的图中被放大了。中间的模型比右边的更差,因为我故意扭曲了它,所以它的等式是这样的:

y_hat = 1.25*x-25

然而,右边的模型是正确的:它是 y_hat = x ,与生成数据点的线完全相同。为了直观地证实这一点,您可以看到中间模型的偏斜,而右边的模型似乎位于数据点的正中心,正如您所料。因此,具有低 R 的模型仍然可以正确地预测数据的形状,但是会遭受数据的较大变化。

尽管如此,如果问题的本质是预测值,那么中间模型可能会由于数据点的较低变化而表现得更好,但是这并不一定使它成为更好的模型。

R 总结

R 度量给出了模型与您的数据拟合程度的指示,但无法解释您的模型是否良好

优点:

  1. 给出模型拟合程度的指示

缺点:

  1. 向模型中添加预测值可能会由于偶然性而增加 R 的值,使结果具有误导性(参见调整后的 R
  2. 向模型中添加预测值会导致“过度拟合”,即模型试图预测数据中的“噪声”。这降低了它在以前从未见过的“新”数据上表现更好的能力。
  3. r 对于非线性模型没有意义

调整后的 R (Adj. R )

n =样本中数据点的数量,k =包括模型中变量的数量,不包括常数项(截距)

如前所述,即使模型的性能没有改善,向模型添加预测值也会导致 R 增加。对此的解决方案是使用调整后的 R 而不是 R 来衡量模型的表现。

从上式可以看出,多了两个变量: nk 前者代表模型中数据点的数量,后者代表模型中变量的数量,不包括常数项。

例如,如果模型的形式为:

y_hat =a0 + a1x1 + a2x2

然后你有 k = 2 既然你有两个预测器, a1a2。

那么为什么调整后的 R 平方比 R 平方好呢?

考虑以下两种模型:

y_hat = x

y _ hat = A0+a1 * x1+a2 * x+a3 * x+a4x⁴⁴+a5x⁵⁵+a6x⁶⁶+a7x⁷⁷

同样的数据,基于 y=x+e 被模型预测,结果如下所示:

如图所示,左边模型(有更多项)的 R 高于右边模型,这表明它是一个更好的模型。我们知道这不是真的,因为数据是建立在 y=x+e 之上的。

当我们检查调整后的 R 值时,我们看到最右侧模型的 R 值基本保持不变,而最左侧模型的 R 值发生了显著变化,这表明增加项数会对 R 值产生影响。在这种特殊情况下,人们可能会选择最左边的模型,因为即使考虑了额外的项,它也具有更高的调整后 R。我们知道这是错误的,它可能只是随机误差的结果。从本文第一部分我们也知道,R 越高并不代表型号越好!

我们可以通过使用相同的模型拟合“新数据集”来进一步检验这一点,从而消除“训练偏差”。

我们可以看到,线性模型的拟合度明显优于多项式模型(左),R 值和调整后的 R 值与之前的数据集相当。然而,多项式模型的表现很好,因为它“适合”误差和噪声,表现非常糟糕,当根据变量的数量进行调整时,R 甚至下降更多。

与往常一样,对于 R 和 Adj. R,绘制结果模型是一种很好的做法,以直观地检查结果是否有意义,如果结果没有意义,添加额外的数据点或使用不同的“测试”数据集可能会提供更多的洞察力。

调整后的 R 汇总

调整后的 R 在 R 的基础上有所改进,它让我们了解模型的 R 值是因为拟合度好,还是因为它的复杂性

优点:

  1. 对过度拟合问题有了更深入的了解
  2. 降低随机性对 R 值的影响(即,如果由于随机性而导致 R 值较高,调整后的 R 将会反映这一点)

缺点:

  1. 仍然存在与 R 相关的其他问题

平均绝对误差

n =点数,y =实际点,y_hat =预测点

MAE 是所有误差幅度的总和除以点数,因此本质上是平均误差。

因此,MAE 越低,模型中的误差越小。

均方误差

n =点数,y =实际点,y_hat =预测点

MSE 是所有误差的平方和除以点数。请注意,由于在每个实例中,误差实际上都是平方的,因此不能直接与 MAE 进行比较,因为它总是更高阶的。

因此,与 MAE 一样,MSE 越低,模型中的误差越小。

均方根误差(RMSE)

n =点数,y =实际点,y_hat =预测点

RMSE 是均方差的平方根。这在某种程度上是一个更有用的度量,现在因为梅和 RMSE 都有相同的误差“阶”,他们可以互相比较。

与 MAE 和 MSE 一样,较低的 MSAE →较低的误差。

那么,这在实践中是怎样的呢?

我这里有两个例子。

第一个非常简单,我已经创建了一条线 y_hat = 2x +5 ,还有一条带有噪声,所以 y = 2x + 5 + e.

在这里,我们可以看到平均寿命和 RMSE 彼此非常接近,都表明该模型具有相当低的误差(记住,平均寿命或 RMSE 越低,误差越小!).

但是你可能会问,梅和 RMSE 有什么不同?MAE 为什么更低?

这个是有答案的。

当我们看梅和 RMSE 的方程时,我们注意到 RMSE 有一个平方项…因此:大的误差将被平方,因此将增加 RMSE 的值。因此,我们可以得出结论,RMSE 更善于捕捉数据中的大误差,而 MAE 只是给出平均误差。由于 RMSE 在取平均值之前也对平方和进行求和,因此它必然会高于平均误差。

要在示例中看到这一点,请考虑以下情况:

橙色线代表我之前描述的等式y _ hat = 2x+5……然而‘y’现在的形式是:

y = y + sin(x)*exp(x/20) + e

其中 exp() 表示指数函数(因此我们看到点的偏差增加。

如您所见,RMSE 几乎是 MAE 值的两倍,因为它捕捉到了误差的“大”值(尤其是从 x = 80 开始的误差)。

所以你可能会想:总是使用 RMSE 不是更好吗?

号码

MAE 确实有一些优势。

首先,我们可能希望将小错误视为大错误。例如,假设您正在拟合除了一个大的异常数据点之外,一般没有大误差的数据。如果你选择基于最小 RMSE 的线性回归模型,你的模型可能会过拟合,因为你会尝试捕捉异常。

在这种情况下,假设您的数据通常是一致的,几乎没有明显的大误差,选择 MAE 最低的回归模型可能更合适。

除此之外,比较不同样本大小的模型的 RMSE 变得有点问题和不一致。

MAE、MSE 和 RMSE 总结:

MAE 是拟合的平均误差;MSE 是误差平方的平均值;RMSE 是均方差的平方根,用于比较。RMSE 惩罚重大失误。

梅/ RMSE 的优点:

  1. 两者都捕捉到了模型中的“错误”
  2. MAE 是“真正的”平均值,因为它是平均误差的度量;RMSE 稍微有点微妙,因为它被误差大小等因素扭曲了

美/ RMSE 的缺点:

  1. MAE 不会拾取非常大的错误;RMSE 会拾取较大的误差,因此对可能不想捕捉的异常值很敏感
  2. 两个都倾向于随着模型复杂度的增加而增加(即容易过度拟合),类似于 R 随着复杂度的增加而增加

请注意,也有这些修正的变体,例如 MSEc,其中 c 代表修正的。该等式的不同之处仅在于,平均值不再是 1/ n ,而是1/(n+k+1),其中 k 是预测数(不包括截距)。这类似于调整后的 R,因为它惩罚了模型的复杂程度。

赤池的信息准则(AIC)

k =预测值的数量(包括系数!),L =最大对数似然

AIC 有点难以解释:它是对数据符合模型的程度和模型的复杂程度的一种度量。因此,在某种程度上,它是 R 和调整后的 R 的混合。它所做的是因其复杂性而惩罚一个模型,但因其符合数据而奖励

这个值几乎总是负的。

从本质上讲,降低AIC(即更负),而更好模型如何拟合数据,以及它如何避免 overfitting⁴(记住,复杂性→过度拟合,所以如果 AIC 惩罚复杂性,那么它惩罚过度拟合)。

让我们看一个例子。

回想一下我们用于调整 R 的例子,我们有一个非常复杂的模型来模拟带噪声的线性线。

我重新运行了这个模型,这次还添加了一个 AIC 分数:让我们看看结果。

我们可以在这里看到很多东西,这也是很好的复习。

左图的 R 比右图的高,但是我们知道最右边的是正确的。对于更复杂的模型,这是 R 变大的一个征兆。

在这种情况下,我们调整后的 R 表明简单模型更好(请记住,由于随机性,情况并不总是如此,但我们仍然可以通过测量调整后的 R 和 R 之间的差异来了解模型有多好→更简单的模型损失更低)

我们也有 AIC 来帮助我们:AIC 越消极,就越适合,越不会过度适合。因此,仅从 AIC 参数,我们可以得出结论,越简单的模型越好(也就是说,记得总是勾画你的情节,并试图推理它们,不要只相信数字!).

让我们看看模型对测试数据的表现:

正如预测的那样,更复杂模型的 R 更高。这里我们还注意到,调整后的 R 也更高。我们也有精彩的 AIC,这再次表明,越简单的模式越好。

AIC 总结:

AIC 越低,模型在拟合度和避免过度拟合方面就越好。

优点:

  1. AIC 是模型质量的一个很好的指标,因为它既解释了拟合,也解释了模型过拟合的程度

缺点:

  1. 从数学上讲,AIC 只对无限数据集有效。在计算上,误差可以通过具有非常大的样本大小来抵消。对于较小的样品,必须添加校正系数。

结论:

我希望您已经了解了不同的参数、它们的使用案例以及它们是如何具有欺骗性的。

我想以一个真实的例子来结束这篇文章。

对于这个项目,我试图预测桥梁单位长度(Y)的维护成本,作为桥龄(X1)和长度(X2)的函数。

显示桥梁单位长度的维护成本与长度的图表

我想出了许多不同的模型,其中一些非常复杂。

注:部分数学表达式有误。X1 代表年龄,X2 代表长度

正如您所看到的,这里涉及到许多不同的东西,但我们看到大多数模型都有非常相似的指标。这就是将不同的指标结合起来使用的时候了,这就是为什么了解所有指标或者尽可能多的指标是好的。

最后,人们认为最差的模型是“二次”型,因为它具有最高的 AIC 和最低的 R 调整值

最佳模型被认为是“线性”模型,因为它具有最高的 AIC 和相当低的 R 调整值(实际上,它与 R 调整值最高的“poly31”模型的误差在 1%以内)。

读者注意:

我希望您喜欢阅读本文,并且对所描述的指标有更好的理解。由于这是我的第一篇文章,如果你能给我反馈,我将不胜感激:什么是好的?什么不好?少了什么?我能有什么不同的解释?

非常感谢,我希望你继续你的学习之旅:)

来源:

  1. https://www . investopedia . com/terms/R/R-squared . ASP #:~:text = R-squared % 20(R2),变量%20in%20a%20regression%20model。
  2. https://machine learning mastery . com/over fitting-and-under fitting-with-machine-learning-algorithms/#:~:text = over fitting % 20 refers % 20 to % 20a % 20 model % 20 that % 20 models % 20 training % 20 data % 20 too % 20 well。&text =这% 20 意味着% 20 那% 20 噪音% 20 型号% 20 能力% 20 到% 20 通用化。
  3. https://medium . com/human-in-a-machine-world/Mae-and-RMSE-metric-is-better-e 60 AC 3 bde 13d
  4. https://towards data science . com/the-a kaike-information-criterion-c 20 c8 FD 832 f 2

除非另有说明,所有图片均由作者提供。

如何为您的应用选择正确的机器学习算法

原文:https://towardsdatascience.com/how-to-choose-the-right-machine-learning-algorithm-for-your-application-1e36c32400b9?source=collection_archive---------9-----------------------

倾听你的数据,追随你的目标…

米格尔·Á拍摄的照片。来自佩克斯的帕德里纳

当我刚开始学习和实践数据科学和机器学习时,我会查找资源和教程来实现和使用特定的机器学习算法。

互联网上到处都是教你如何使用算法、算法如何工作以及如何应用于数据的资料。

然而,当我开始构建我的项目时,我会花很长时间来决定使用哪种算法。

看,大多数关于如何使用特定算法的文章都忽略了何时使用该算法以及如何为您的数据选择最佳算法。

在这篇文章中,我将尝试回顾我在为特定项目选择最佳机器学习算法时遵循的过程。

在开始之前,我们先来了解一下机器学习算法的类型。

机器学习算法的类型

机器学习算法可以大致分为三个主要类别:

监督学习

在监督学习中,算法从训练数据中建立数学模型,该模型具有输入和输出的标签。数据分类和 r 回归算法被认为是监督学习。

无监督学习

在无监督学习中,算法在只有输入要素而没有输出标签的数据上建立模型。然后对模型进行训练,在数据中寻找某种结构。聚类和 s 分割是非监督学习算法的例子。

强化学习

在强化学习中,模型通过执行一组自己即兴创作的动作和决策来学习执行任务,然后从这些动作和决策的反馈中学习。蒙特卡洛是强化学习算法的一个例子。

图片由作者提供(使用 Canva 制作)

选择正确的算法

所以,你知道不同的算法类型,你知道它们有什么不同,你知道如何使用它们。现在的问题是什么时候使用这些算法?

要回答这个问题,我们需要考虑我们试图解决的问题的 4 个方面:

№1:数据

了解您的数据是决定算法的第一步,也是最重要的一步。在开始考虑不同的算法之前,您需要熟悉您的数据。一个简单的方法是将数据可视化,并尝试从中找到模式,尝试观察数据的行为,最重要的是,观察数据的大小。

[## 数据可视化 101:有效可视化的 7 个步骤

用引人注目的视觉效果讲述您的数据故事。

towardsdatascience.com](/data-visualization-101-7-steps-for-effective-visualizations-491a17d974de)

了解数据的关键信息将有助于您对算法做出初步决定。

  1. 数据大小:有些算法在处理较大数据时比其他算法表现更好。例如,对于训练数据集,具有 bais/ 方差分类器的算法将比 方差分类器工作得更好。所以,对于小训练数据,朴素贝叶斯会比 kNN 表现更好。
  2. 数据的特性:这意味着你的数据是如何形成的。你的数据是线性的吗?那么也许线性模型最适合它,比如回归——线性和逻辑——或者 SVM (支持向量机)。但是,如果你的数据比较复杂,那么你就需要像随机森林这样的算法。
  3. 数据的行为:你的特征是顺序的还是链式的?如果是顺序的呢?你是想预测天气还是股市?那么如果你使用匹配的算法,比如马尔可夫模型决策树,那就最好了。
  4. 数据类型: 你可以对你的输入或输出数据进行分类。如果你的输入数据被标记为,那么使用一个监督的学习算法;如果不是,很可能是一个无人监督的学习问题。另一方面,如果你的输出数据是数值,那么就用回归,但是如果是一组,那么就是一个聚类的问题。

№2:准确性

既然您已经研究了数据,分析了数据的类型、特征和大小,那么您需要问自己准确性对您试图解决的问题有多重要?

模型的准确性是指它从给定的观察集预测答案的能力,该答案接近于该观察集的正确响应。

有时,对于我们的目标应用程序来说,获得准确的答案并不是必需的。如果一个近似足够好,我们可以通过选择一个近似模型来大大减少我们的训练和处理时间。近似方法避免或不执行对数据的过度拟合,例如对非线性数据的线性回归。

№3:速度

通常,准确性和速度是对立的;在决定一种算法时,您需要在这两者之间做出一些权衡。更高的精度通常意味着更长的训练和处理时间。

像朴素贝叶斯、线性和逻辑回归这样的算法很容易理解和实现,因此执行速度很快。更复杂的算法,如 SVM、神经网络和随机森林,需要更长的时间来处理和训练数据。

那么,哪个对你的项目更有价值呢?准确度还是时间?如果是时候,使用简单的算法会更好,而如果准确性是最重要的,那么选择更复杂的算法会更好地为您的项目工作。

图片由作者提供(使用 Canva 制作)

№4:功能和参数

你的问题中的 参数 是数字,它将影响你选择的算法的表现。参数是诸如误差容限或迭代次数之类的因素,或者算法行为方式的变量之间的选项。训练和处理数据所需的时间通常与您拥有的参数数量有关。

处理和训练模型所需的时间随着参数的数量呈指数增长。然而,拥有许多参数通常意味着算法更加灵活。

在机器学习——或者数据科学中,一般来说,一个 特征 是你试图分析的问题的一个可量化变量。

拥有大量的特征会降低一些算法的速度,使得训练时间相当长。如果你的问题有很多特征,那么使用 SVM 算法是最好的方法,它非常适合有很多特征的应用程序。

最后的想法

许多因素控制着选择算法的过程。我们主要可以把你的决策标准分为两个部分,数据相关方面,问题相关方面。

数据的大小、行为、特征和类型可以为您提供使用何种算法的初步想法。一旦你得到这个最初的决定,你的问题的不同方面将帮助你决定一个最终的决定。

图片由作者提供(使用 Canva 制作)

最后 ,永远记住两件事:

  1. 更好的数据比复杂的算法带来更好的结果;如果你可以用更简单的算法得到相似的结果,选择简单。
  2. 您可以牺牲更多时间来处理和训练数据,从而提高算法的准确性。根据具体项目的优先级做出决定。

在遵循项目目标的同时,始终倾听数据想要表达的内容。

如何为您的预测选择正确的 TS 模型

原文:https://towardsdatascience.com/how-to-choose-the-right-ts-model-for-your-prediction-3620ec547243?source=collection_archive---------44-----------------------

在时间序列模型丛林中寻找出路

为 TS 选择正确的模型总是一项繁琐的任务。图片由作者提供。

选择正确的模型来预测时间序列总是一件乏味的工作。在本文中,我们将浏览做出正确选择时需要考虑的要点。

每个时间序列都不同

不幸的是,当你面对真实世界的数据时,你会很快意识到你不会面对两次同样的数据,尤其是当你处理时间序列时。

这意味着没有单一的解决方案来建立精确的模型,给出精确的预测。

然而,有一些特征可以很容易地被识别和利用来帮助您更快地收敛到正确的模型。

连续性

当人们想到时间序列时,他们通常想当然地认为这些是平滑、连续的数据。让我们面对现实吧:生活没那么简单。

以风力涡轮机收集的数据为例。一些涡轮机在无风时不记录数据,以节省电力。或者风力涡轮机通常就是这种情况,它们位于人口稀少的地区,那里的互联网连接不稳定。连接丢失是很常见的,会导致数据出现缺口。

处理非连续数据不能用与连续数据相同的模型。ARIMA,萨里玛,指数平滑可能不起作用。在这些情况下,像 CatBoost 这样的梯度推进方法是很好的选择。

时间无关数据

处理时间序列时需要考虑的另一个方面是,通常需要在模型中添加外部的、与时间无关的数据,以实现高水平的精度。

接下来的问题是如何将这些与时间无关的数据整合到一个基于时间的模型中?简而言之,并不总是需要依赖基于时间的模型来实现良好的精度水平。在这些情况下,提取时间相关特征的良好预处理和像 SVM 这样的回归算法可以给出良好的结果。

另一个需要考虑的明显问题是您要处理的数据量。你不可能只用几百个数据点来训练 LSTM 神经网络。神经网络需要更多的数据。

平稳性

此外,您还必须考虑数据的平稳性:即,预测量的平均值和偏差是否随时间而变化?如果是这种情况,可能有必要对数据进行预处理,通常使用时间微分来确保情况如此。

那么,我如何挑选合适的型号呢?

您可以使用下面的简单图表。它依赖于我们在这方面的经验,并根据数据的性质总结了正确模型的选择:

快速收敛到适合您数据的模型。图片由作者提供。

这是一个很好的起点,以获得一个体面的模型。要走得更远,达到更高的精度水平,将需要一种更复杂的方法,混合在以前构建的集群上训练的各种模型。或者使用大型神经网络,构建为自动识别这些集群,并设计最佳特征。

通过将所有这些步骤组合在一个单一的全局优化问题中,您将不再需要选择模型。

如何选择范围最广的软件包?

原文:https://towardsdatascience.com/how-to-choose-the-software-package-with-the-widest-scope-a8851f29d8b7?source=collection_archive---------44-----------------------

从数据科学的角度来看。

TL;博士:

你对软件工具最大的愿望是什么?疯狂一下,问问自己如果我想拿这个拿那个,然后以最小的努力把它们组合/比较/组合在一起?最有可能的是,某个领域专家已经想出了解决这个问题的好办法。他们可能需要将它包装在花哨的软件结构下,这种结构从一开始就不直观,而且有自己的行话。是否值得学习它,并利用您将来可能会发现的大范围解决方案?大范围包还有什么特征?

图片来源

ML 示例:您运行一个机器学习预测分析,比如简单的线性回归,然后您希望将其与另一个模型进行比较,比如正则化回归(如 ridge,lasso)。你如何为此整合你的代码?最简单的方法可能是“复制- >粘贴”您的回归模型代码,更改模型部分,用唯一的名称保存输出,与以前的输出集成(假设您以统一的方式保存了列名和其他结构),并进行比较。但是有趣的事情仅仅从这里开始…如果您想要添加更多的模型,其中一些模型也需要调整(通过一些优化过程选择参数的最佳值),或者您想要尝试一些由多个模型组成的集成技术(打包、提升、堆叠),该怎么办?你还打算从头开始做所有的事情吗,复制粘贴,编织各种函数/包的结果,每个函数/包都有自己的名字和结构?希望不是…有人已经找到了这个挑战的解决方案,并编写了一个包来统一这个繁琐的过程,并将您最疯狂的愿望列表聚合到一个单一的、全面的生态系统中,这将为您完成这项脏工作。

时间序列示例:

你运行一个预测模型,比如说 ARIMA。你也希望将它与 ETS 进行比较。同上,在完全相同的假设、随机种子和其他约定下,通过简单地指定两次独立运行的输出名称来创建它们的系综有多容易?然后…您对数据集中的总体观察值运行它,但是您也希望对数据中的每个分层子组再次运行它。您可以在循环中执行此操作,但是如果工具的范围已经允许您指示嵌套组,并且在您对分析进行分层/重新折叠时也会考虑到它,该怎么办呢?

‘去过那里……做过那件事’

在这两个例子中,目标是识别已经完成这项工作的包,而不需要重新发明轮子,也不需要在争论、统一和其他您可以避免的繁琐工作上投入宝贵的时间。因为…其他人,一个领域专家,已经找到了更好的解决方法。是什么让他们成为领域专家?嗯,在花了很长时间处理这些挑战,并且对当前的解决方案不满意(当时)之后,激励他们写自己的最先进的解决方案。他们玩这些工具的时间已经够长了,这促使他们设计一种更好的方式来无缝地组合软件的各种组件。

如何识别具有你所需要的范围级别的包?我们来贪一下…如何识别范围最广的包?

当你学习一个新的领域(机器学习、时间序列……)时,除了你自己的任务之外,你可能不知道这个领域中存在的丰富工具,或者这个领域处理的常见问题。但是随着你了解的越来越多,你可能会遇到一些很酷的解决问题的方法,这些方法可能会在以后遇到。

对我来说,这就像…“你为什么不提前告诉我这是我们以后要做的…如果我以前知道,我可能会以不同的方式开始构建我的工具,这样我就可以添加这个新的功能/解决方案,而不必改变我的工具的设计(范围)”。

所以诀窍是…想象你想问/分析的下一步是什么。在上面的例子中,它是 ML 的集合,以及时间序列的加权分层/组分层。的确,您可能不需要这些花哨的解决方案来解决您当前的问题,但是通常来说,一个被设计来处理更高层次问题的包,对于简单的、核心的步骤/组件,也会有一个好的解决方案。

重点在哪里?没有免费的午餐

当然,这是有代价的。以一种内聚的方式识别和设计软件(方法)的核心模块并不简单。适应这些块的无缝组合通常需要一些更高层次的框架,这些框架有自己的学习曲线。它可以是由原子和非原子结构组成的对象结构(如面向对象的类、嵌套表/模型等)。他们通常会有自己独特的行话,你不熟悉,因为…嗯,他们必须发明它。毕竟这是个新事物。这些可能一开始并不直观,但通过设计被精心构造以满足独特的需求

取舍:

根据我的经验,值得花时间学习如此复杂的结构,并利用大范围的解决方案,而不是在以后面临类似挑战时重新发明一个次优的解决方案(是的,你会的!).

大范围包的典型特征是丰富的文档,以及对稳定的生态环境(包)的依赖,这将确保您的代码在扩展到新的极限时不会“中断”。

大范围的软件包也以作者自身经历的血统为特征,在艰难、多风的学习曲线中。说我迄今为止开发的工具有一个 范围蔓延 需要一些勇气,所以我将放弃它,并从零开始重新设计它,所以它更好地适合我当前的范围(这在回顾中可能再次受到限制,从现在起 5 年后,当该领域扩展到更广的范围时)。

当软件包文档中有一个比较不同竞争软件包特性的表格,明显地强调了它自己的优势时,问问你自己:这是我需要的范围吗?包范围的限制是什么?它依赖于哪些其他的生态环境,并且可以很容易地与它们整合?它能让我根据自己的需要扩展它,并为它添加新的特性吗?

警告:避免单一功能的疯狂包装包

如果一个包试图实现一个大范围功能,但它是一个带有太多参数的单一函数,将其他嵌套步骤包装在里面,那么它可能不是您的最佳选择。这个“包装器”功能与上面描述的大范围包的区别在于它的结构。疯狂包装器功能可能缺乏其组件的独立设计,以及它们的内聚结构。Crazy-wrapper 函数不能扩展到其他用途,并且只限于预定义的参数值。另一方面,宽范围函数由于其结构的复杂性而避免了这种陷井,这使它能够以与其他组件很好地集成的方式存储各种数据类型和参数值。

结论:

通过利用其他领域专家工具,让自己成为领域专家。当你问自己为什么他们要创造这个奇怪的复杂物体,并用一个新的词来命名它时,一定有一个很好的理由。要有耐心,学习它,并享受未来的花式技巧的成果。

查看我的其他博客文章和我的 GitHub 页面获得更多有趣的阅读。领英

设计连体神经网络时如何选择自己的损失?对比,三胞胎还是四胞胎?

原文:https://towardsdatascience.com/how-to-choose-your-loss-when-designing-a-siamese-neural-net-contrastive-triplet-or-quadruplet-ecba11944ec?source=collection_archive---------8-----------------------

彻底的比较

用于在 Quora 数据集 [1]上训练相似性学习算法的三种流行技术(对比、三重和四重损失)的性能比较

阿克塞尔·邦尼奥特Unsplash 上拍摄的照片

通过这篇文章,我将评估和比较深度相似性学习任务的三种不同损失。如果您仍然不能完全理解这个主题,我已经写了一篇文章,介绍了主要的概念和代码示例,以及一个完整的 GitHub 库,您可以查看:

[## 序列深度相似性学习简介

对用于相似性分类任务的深度学习技术的一系列深入评论的第一部分。

towardsdatascience.com](/introduction-to-deep-similarity-learning-for-sequences-89d9c26f8392)

目录

一、任务概述

二。暹罗循环网络:序列的相似性学习

三。深度相似性学习的损失

四。 具体应用:问题对检测

一.任务概述

我在这个任务中使用了著名的 Quora 问题对数据集,其主要目标是预测两个问题对是否有相同的意图。例如:

  • 什么能让物理变得简单易学?/怎样才能让物理变得简单易学?相似的意图
  • 网上赚钱最好的方法是什么?/网上要钱最好的方式是什么?有不同的意图

对于这项任务,可以使用不同的解决方案,但我们今天将看到的是:单词嵌入+暹罗循环网络。单词嵌入算法不是这里的重点(将使用 Word2Vec),但我们将专注于训练暹罗递归网络。因此,在谈论培训之前,我们将快速概述一下什么是暹罗循环网络(更多细节可以在我上面的另一篇文章中找到……)。

二。暹罗循环网络:序列的相似性学习

暹罗猫的形象

如上所述,连体递归神经网络是这样一种神经网络,其将两个数据序列和作为输入并将它们分类为相似不相似。****

编码器

为此,它使用一个编码器,其工作是将输入数据转换为特征** s 的向量,然后为每个输入创建一个向量,并将其传递给分类器。处理图像时,这个编码器往往会是一堆卷积层,而处理序列时,往往会是一堆rnn。在我们的例子中,我们使用了 3 个双向 LSTMs 的堆栈。**

分类器

分类器然后根据这两个输入计算、距离(距离函数可以是任何距离:L1、L2……)。这个距离然后被分类为相似或不相似数据实例的距离:这个过程就类似于找到正确的距离值阈值,超过该阈值两个数据对象被认为是不相似的。

训练一个连体神经网络

给定编码器和分类器的定义,人们可以认识到使用暹罗神经网络的所有困难在于特征向量的创建过程。事实上,这个向量需要以下特性:

  • 足够恰当地描述,使得两个相似的数据(具有可变性)将具有相似的向量(因此,距离小)
  • 具有足够的辨别力,使得两个不相似的数据具有不相似的矢量

数据比较过程的动画

因此,我们看到,训练这个网络就是训练它,一方面,识别相似的事物,,另一方面,识别不相似的事物:两者都有良好的信心。仅仅是教授一个模型什么是两个相似的数据是不够的,它会过度适应训练数据,并倾向于发现所有的数据都是相似的(高召回率但低精度):这也是关于训练它去识别不相似的数据** ( 因此,平衡它的召回率和精度)以及最终是什么产生了两个数据**

为了训练一个连体神经网络,最常用的损失函数是对比损失【2】(在我之前的文章中有更详细的介绍,你可以在上面找到)。然而,它并不是唯一存在的。我将通过详细描述这些损失背后的主要思想以及它们的 PyTorch 实现,将其与另外两个损失进行比较。

三。深度相似性学习的损失

对比损失

当训练具有对比损失[2]的连体网络时,在每个时间步将使用两个输入数据来比较。这两个输入数据可能相似,也可能不相似。这由二进制类变量 Y 建模,其值为:****

  • 如果不同,则为 0;
  • 1 如果相似。

这些类别显然可以改变,以适应损失函数的条件。

对比损失详情说明

你可以在下面找到对比损失的 PyTorch 代码:

三重损失

当训练具有三重损失[3]的连体网络时,在每个时间步需要三个输入数据来比较。与对比损失相反,输入有意采样关于它们的😗***

  • 我们对一个锚对象进行采样,用作其他两个数据对象的比较点;
  • 我们采样一个阳性物体,已知是类似于物体的
  • 然后,我们对一个负对象进行采样,已知它与对象不同

三重损失细节图

您可以在下面找到三联体丢失的 PyTorch 代码:

四联缺失

当训练一个有四个损失的连体网络[3]时,将需要个输入数据在每个时间步比较。就像三重丢失一样,输入再次被有意采样关于它们的😗***

  • 我们对一个锚对象进行采样,用作其他两个数据对象的比较点;
  • 我们对一个阳性对象进行采样,已知其对象相似;
  • 我们采样一个否定对象,已知是对象不相似的
  • 然后,我们对另一个否定对象进行采样,已知它是 3 个数据对象相异****

四联丢失详细信息的图示

你可以在下面找到四胞胎丢失的代码:

直观比较损失及其对网络的影响

三种损失的比较及其对暹罗网络架构的影响

在此图中, 3 损失并排比较。我们可以很容易地看到的差异的输入数中,取决于所使用的损耗。****

在每个编码器的右侧是计算损耗的图形表示。它可以提供关于如何使用编码器的输出来训练网络的更多见解,还可以显示损失之间的不同复杂程度。每个损失的输出是紫色的计算节点。****

四。具体应用

架构和损失定义(PyTorch)

我训练了三个不同的模型,每个模型对应一次损失。他们都使用相同的编码器来处理输入,他们之间的唯一区别是输入的数量:

  • 对比损失模型的 2 个输入;
  • 三重态损耗模型的 3 个输入;
  • 四联丢失模型的 4 个输入。

该编码器具有以下架构(内置于 PyTorch 中):

然后,每个模型将有一个单一版本的编码器,他们将使用它来为他们的输入生成特征向量。例如,对于四联丢失模型,我们有:

培训详情和结果

我使用以下超参数并行训练我的网络(使用相同的 for-loop ):

  • 25 个时代
  • 1e-3 的学习率
  • 批量为 64 件
  • 嵌入大小(Word2Vec 建模)为 40

我的三个算法的性能是在每个时期结束时使用 AUC 分数来测量的,在验证阶段之后,使用训练、验证和测试集来计算它们的相互 AUC 分数。总体而言,它们都遵循相同的进度,因此我将只显示测试结果:

每个模型的测试集上的 AUC 分数作为纪元编号的函数的图

我们在这里看到,在整个训练中,用四重损失训练的模型明显优于对比损失模型。虽然它们最终似乎都趋于一致,但这两种模型之间仍有 0.01 的 AUC 差异。这证明了四联缺失训练模型将数据转换为特征密集向量是多么有效。

我的 github 仓库里有这个项目的全部代码,在这里:

** [## 文本语义相似度

这是运行以下文章中介绍的实验的代码的存储库

github.com](https://github.com/dimartinot/Text-Semantic-Similarity)

dis claimer:Quora 数据集为了这个实验的目的被稍微修改了一下。虽然它最初包含相似和不相似的问题示例,但只有相似的问题被保留用于我的计算。然后,我会从数据集中随机抽取任何其他问题来创建不同的示例。原始数据集的全部困难在于,一些问题在意义上非常接近,但实际上是不同的。为这一挑战而构建的解决方案的关键不仅在于构建深度相似性网络,还在于手工创建将被使用的神奇特征,合并到向量中,用于分类。

额外资源

关于暹罗神经网络的另一个具体应用,我向你推荐这篇由劳尔·戈麦斯·布鲁巴拉发表在 Neptune.ai 博客部分的关于这个主题的广泛文章。它提出了通过相似嵌入内容的匹配进行图像检索的概念。

[## 用 PyTorch - neptune.ai 中的连体网络实现基于内容的图像检索

图像检索是寻找与给定查询相关的图像的任务。对于基于内容的图像检索,我们指的是…

海王星. ai](https://neptune.ai/blog/content-based-image-retrieval-with-siamese-networks)

参考

[1] Quora。2017. Quora 问题对Kaggle

[2] R .哈德塞尔,s .乔普拉,y .勒昆。通过学习不变映射进行降维。2006.

[3] F .施罗夫、d .卡列尼琴科、j .菲尔宾。FaceNet:人脸识别和聚类的统一嵌入。2015.

[4]陈文伟,陈晓霞,张军,黄国光.超越三重缺失:用于个人再识别的深层四重网络。2017.**

如何清理和组合列表的数据框列

原文:https://towardsdatascience.com/how-to-clean-and-combine-dataframe-columns-of-lists-ebd3542559b6?source=collection_archive---------23-----------------------

Joshua Rodriguez 在 Unsplash 上的照片

在 Metis 数据科学训练营的第二个项目中,我发现自己不得不处理熊猫数据框中的列表。我在谷歌搜索中没有找到这些信息,所以我把它放在这里作为有用的参考/起点。

一.问题

相关属性的列,充满列表

我需要完成几件事:

  • 包含其他列表栏中所有项目的合并栏,但没有重复项目。因此,第 1 列中有[A,B]而第 2 列中有[B,C]的条目将导致[A,B,C]的合并条目。
  • 将所有 NaN 值更改为空列表。
  • 从列表中的所有项目生成虚拟列的列表(按照下面的列)。

流派:包含分类特征列表的列

二。方法

我编写了下面的助手函数,我将一个一个地介绍它们。

a)基于列表列创建数据帧

  1. 数据帧本质上是一系列系列。所以给定一个列,我对每个列表项应用 pandas 系列转换。然后,我将这一系列序列分配给一个新的数据帧。
  2. 我用基于原始列名和列表索引的编号系统替换了默认的列名,格式为 _

将它应用到上面的流派专栏,我得到了以下结果:

b)列表中各列的虚拟变量

  1. 我可以使用前面的 helper 函数来获得列表条目的数据帧(让我们称之为 list_df)。
  2. 使用 pandas 的 get_dummies() ,我获得 list_df 的所有列的虚拟数据帧,然后将它们加在一起。这给了我一个整合的虚拟数据框架。

将此应用于“流派”列会得到以下结果:

仅显示了前几个流派虚拟列

c)合并列表的列

  1. 这里的逻辑类似于创建虚拟列的逻辑。我没有使用 add(),而是将所有的数据帧连接在一起成为一个大的数据帧。
  2. 将大数据帧转换成一个列表,所以它现在是一个列表的列表。这对于接下来的几个步骤很重要。
  3. 使用 list comprehension 来只包含列表列表中每个列表中与我们期望的类型相匹配的条目。在这种情况下,由于所需的类型是一个字符串,这也消除了我所有的 NaN 值。如果一开始只有 NaN 个值,我们最终得到的是一个空列表。完美!
  4. 最后,我将 set()和 list() 映射到 list 列表中。集合论的神奇之处在于,当应用 set()时,所有重复项都会自动丢弃。
  5. 注意,结果仍然是列表的列表。我有另一个如下所示的帮助函数,根据父数据帧的索引将它分配给数据帧列,并将其命名为:

三。结果

请注意附加的关联列,以及代替 NaN 的空列表

我们做到了!有可能的方法可以进一步收紧,所以请在你的评论中让我知道。

如何在命令行清理 CSV 数据

原文:https://towardsdatascience.com/how-to-clean-csv-data-at-the-command-line-4862cde6cf0a?source=collection_archive---------35-----------------------

关于使用命令行程序清理新冠肺炎 CSV 文件的深入教程:csvkit 和 xsv 比较各自的性能

疾控中心Unsplash 拍摄的照片

注意:这是在命令行清理 CSV 系列的第 1 部分。第二部分在这里:

[## 如何在命令行清理 CSV 数据|第 2 部分

关于在排序和连接时使用命令行程序 csvkit 和 xsv 清理大型 CSV 文件的教程…

medium.com](https://medium.com/the-brainwave/how-to-clean-csv-data-at-the-command-line-part-2-207215881c34)

您是否曾经处理过一个非常可怕的 CSV 文件,该文件包含许多您不想要的列和许多记录,从而降低了您过滤和获取所需信息的速度?

本教程是关于使用两个命令行程序来解决这些问题; csvkitxsv 。我们将在最后比较两者,看看各自的性能如何,以及在速度方面何时可以使用一个而不使用另一个,尤其是在处理大型 CSV 文件时。在上一篇博文中,我们讨论了如何在命令行中清理文本数据,我推荐大家看看:

[## 如何在命令行清理文本文件

关于使用命令行工具清理数据的基础教程:tr、grep、sort、uniq、sort、awk、sed 和 csvlook

towardsdatascience.com](/how-to-clean-text-files-at-the-command-line-ce2ff361a16c)

从 covidtracking 下载 COVID 数据

让我们首先从 COVID 跟踪项目下载美国各地最近的冠状病毒数据,该项目是一个志愿者组织,致力于收集和发布了解美国新冠肺炎疫情所需的数据。顺便说一下,这些数据是在 4.0 许可的知识共享 CC 下发布的。

让我们通过手动下载 CSV 文件或使用 curl 来完成:

$ curl -LO [https://covidtracking.com/data/download/all-states-history.csv](https://covidtracking.com/data/download/all-states-history.csv)

-LO-L-O 的组合

  • -L 用于确定 URL 是否已经更改到另一个位置, curl 将在新的重定向链接上重做请求
  • -O 该选项用于创建一个与所请求文件名同名的输出文件,此处为 all-states-history.csv

打印 CSV 文件头

让我们首先打印这个all-States . history . CSV文件的列名:

*$ csvcut -n all-states-history.csv 
  1: date
  2: state
  3: dataQualityGrade
  4: death
  5: deathConfirmed
  6: deathIncrease
  7: deathProbable
  8: hospitalized
  9: hospitalizedCumulative
 10: hospitalizedCurrently
 11: hospitalizedIncrease
 12: inIcuCumulative
 13: inIcuCurrently
 14: negative
 15: negativeIncrease
 16: negativeTestsAntibody
 17: negativeTestsPeopleAntibody
 18: negativeTestsViral
 19: onVentilatorCumulative
 20: onVentilatorCurrently
 21: pending
 22: positive
 23: positiveCasesViral
 24: positiveIncrease
 25: positiveScore
 26: positiveTestsAntibody
 27: positiveTestsAntigen
 28: positiveTestsPeopleAntibody
 29: positiveTestsPeopleAntigen
 30: positiveTestsViral
 31: recovered
 32: totalTestEncountersViral
 33: totalTestEncountersViralIncrease
 34: totalTestResults
 35: totalTestResultsIncrease
 36: totalTestsAntibody
 37: totalTestsAntigen
 38: totalTestsPeopleAntibody
 39: totalTestsPeopleAntigen
 40: totalTestsPeopleViral
 41: totalTestsPeopleViralIncrease
 42: totalTestsViral
 43: totalTestsViralIncrease*

如您所见,使用带有选项 -ncsvcut 可以列出我们拥有的所有标题及其相关顺序,这可以帮助我们选择一些我们感兴趣的特定列。

选择特定列

在本教程中,我们对四列感兴趣,这些是 COVID 跟踪项目报告的对它们的描述:

  1. 数据:COVID 跟踪项目收集数据的日期。
  2. 州:州或地区的两个字母缩写。
  3. 阳性:该州或地区报告的新冠肺炎确诊病例加上疑似病例总数
  4. 死亡:确诊或疑似新冠肺炎病例的死亡总数

让我们看看如何在命令行中获取 CSV 文件中这 4 列的前 10 行:

***$ csvcut -c date,state,positive,death all-states-history.csv | head | csvlook 
|       date | state | positive |  death |
| ---------- | ----- | -------- | ------ |
| 2020-10-26 | AK    |   14,413 |     68 |
| 2020-10-26 | AL    |  185,322 |  2,866 |
| 2020-10-26 | AR    |  106,727 |  1,833 |
| 2020-10-26 | AS    |        0 |      0 |
| 2020-10-26 | AZ    |  238,964 |  5,875 |
| 2020-10-26 | CA    |  901,010 | 17,357 |
| 2020-10-26 | CO    |   95,089 |  2,076 |
| 2020-10-26 | CT    |   68,099 |  4,589 |
| 2020-10-26 | DC    |   16,812 |    642 |***

所以这里使用了带有选项 -ccsvcut 来选择后面用逗号分隔的列。这 10 行看起来与 csvlook 对齐更好

请注意,我们可以使用以下命令之一来完成此操作:

***$ csvcut -c **1,2**,22,4 all-states-history.csv | csvgrep -c state -m CA |head | csvlook
$ csvcut -c **1-2**,22,4 all-states-history.csv | csvgrep -c state -m CA |head | csvlook
$ csvcut -c 1-2,**positive**,4 all-states-history.csv | csvgrep -c state -m CA |head | csvlook***

这意味着您可以选择带有编号或范围的列,或者将编号和列名的组合作为字符串。

如果您在撰写本教程之外的某一天使用 COVID 跟踪项目的最新数据,请注意这些 CSV 数据可能与您的不同。

过滤信息

现在让我们过滤掉加利福尼亚州的 COVID 数据:

***$ csvcut -c date,state,positive,death all-states-history.csv | csvgrep -c state -m AL | head | csvlook 
|       date | state | positive | death |
| ---------- | ----- | -------- | ----- |
| 2020-10-26 | AL    |  185,322 | 2,866 |
| 2020-10-25 | AL    |  184,355 | 2,866 |
| 2020-10-24 | AL    |  183,276 | 2,866 |
| 2020-10-23 | AL    |  180,916 | 2,859 |
| 2020-10-22 | AL    |  177,064 | 2,843 |
| 2020-10-21 | AL    |  174,528 | 2,805 |
| 2020-10-20 | AL    |  174,528 | 2,805 |
| 2020-10-19 | AL    |  173,485 | 2,789 |
| 2020-10-18 | AL    |  172,626 | 2,788 |***

我们在这里使用了带有选项 -ccsvgrep 来选择我们正在过滤的列,它是这里的状态来匹配 AL ,使用 -m 选项来匹配我们搜索的模式。**

我想确定这些数据,所以我去谷歌上问阿拉巴马州有多少病例,答案是:

作者图片

看起来 COVID 跟踪项目报告的数据接近谷歌报告的 186,000 例阳性病例和 2892 例死亡病例。

如果你还在另一栏显示前一天阳性病例的增加,你会发现:

***$ csvcut -c date,state,positive,24,death all-states-history.csv | csvgrep -c state -m AL | head | csvlook
|       date | state | positive | positiveIncrease | death |
| ---------- | ----- | -------- | ---------------- | ----- |
| 2020-10-26 | AL    |  185,322 |              967 | 2,866 |
| 2020-10-25 | AL    |  184,355 |            1,079 | 2,866 |
| 2020-10-24 | AL    |  183,276 |            2,360 | 2,866 |
| 2020-10-23 | AL    |  180,916 |            3,852 | 2,859 |
| 2020-10-22 | AL    |  177,064 |            2,536 | 2,843 |
| 2020-10-21 | AL    |  174,528 |                0 | 2,805 |
| 2020-10-20 | AL    |  174,528 |            1,043 | 2,805 |
| 2020-10-19 | AL    |  173,485 |              859 | 2,789 |
| 2020-10-18 | AL    |  172,626 |              964 | 2,788 |***

从 10 月 26 日到 10 月 27 日,967 个阳性病例增加了,这个数字正好与谷歌报告的低于上图中总病例数的(+967)相符。

连接两个 CSV

我不熟悉 state 列中的一些缩写,所以让我们使用第二个 CSV 文件,我们可以加入该文件以获得我们理解的 CSV 数据的更清晰的输出。让我们用 curl: 下载它

***$ curl -LO [https://gist.githubusercontent.com/afomi/8824ddb02a68cf15151a804d4d0dc3b7/raw/5f1cfabf2e65c5661a9ed12af27953ae4032b136/states.csv](https://gist.githubusercontent.com/afomi/8824ddb02a68cf15151a804d4d0dc3b7/raw/5f1cfabf2e65c5661a9ed12af27953ae4032b136/states.csv)***

这个States . CSV文件有两列:状态和*缩写*****

让我们看看如何在这里实现这种有趣的连接:

***$ csvjoin -c Abbreviation,state states.csv all-states-history.csv | csvcut -c date,State,Abbreviation,positive,death | head | csvlook 
|       date | State   | Abbreviation | positive | death |
| ---------- | ------- | ------------ | -------- | ----- |
| 2020-10-26 | ALABAMA | AL           |  185,322 | 2,866 |
| 2020-10-25 | ALABAMA | AL           |  184,355 | 2,866 |
| 2020-10-24 | ALABAMA | AL           |  183,276 | 2,866 |
| 2020-10-23 | ALABAMA | AL           |  180,916 | 2,859 |
| 2020-10-22 | ALABAMA | AL           |  177,064 | 2,843 |
| 2020-10-21 | ALABAMA | AL           |  174,528 | 2,805 |
| 2020-10-20 | ALABAMA | AL           |  174,528 | 2,805 |
| 2020-10-19 | ALABAMA | AL           |  173,485 | 2,789 |
| 2020-10-18 | ALABAMA | AL           |  172,626 | 2,788 |***

注意这里的 csvjoin 命令花费了很多时间,因为它将两个文件都读入内存。

在这里,我们将两个 CSV 文件放在一个列中,用于每个 CSV;缩写在第一个文件中,状态在第二个文件中,然后我们使用 csvcut -c 过滤出 5 列进行查看**

此外,请注意,您在加入时过滤掉的第二列已经消失,这意味着如果您过滤掉 state ( 是具有州的两个字母缩写的列),它将给出一个“state”无效的错误,这意味着该列不再存在。

xsv 和 csvkit 实用程序的比较

正如我们注意到的,使用 csvkit 命令行实用程序时,一些命令会花费很多时间。让我们快速比较一下它的命令行工具和 xsv 上的相关工具。

所有即将运行的命令都是相对于我的机器而言的,让我们逐一比较:

xsv 头与 csvcut -n

***$ time csvcut -n all-states-history.csv | head
  1: date
  2: state
  3: dataQualityGrade
  4: death
  5: deathConfirmed
  6: deathIncrease
  7: deathProbable
  8: hospitalized
  9: hospitalizedCumulative
 10: hospitalizedCurrentlyreal **0m0.307s**
user 0m0.224s
sys 0m0.077s***

csvkit 的 csvcut -n 时间:~307ms

***$ time xsv headers all-states-history.csv | head
1   date
2   state
3   dataQualityGrade
4   death
5   deathConfirmed
6   deathIncrease
7   deathProbable
8   hospitalized
9   hospitalizedCumulative
10  hospitalizedCurrentlyreal **0m0.013s**
user 0m0.008s
sys 0m0.007s***

xsv 的时间:约 13 毫秒**

xsv 选择与 csvcut -c

***$ time csvcut -c date,state,positive,death all-states-history.csv | head
date,state,positive,death
2020-10-26,AK,14413,68
2020-10-26,AL,185322,2866
2020-10-26,AR,106727,1833
2020-10-26,AS,0,0
2020-10-26,AZ,238964,5875
2020-10-26,CA,901010,17357
2020-10-26,CO,95089,2076
2020-10-26,CT,68099,4589
2020-10-26,DC,16812,642real **0m0.288s**
user 0m0.209s
sys 0m0.073s***

csvkit 的时间 csvcut -c : ~288ms

***$ time xsv select date,state,positive,death all-states-history.csv | head
date,state,positive,death
2020-10-26,AK,14413,68
2020-10-26,AL,185322,2866
2020-10-26,AR,106727,1833
2020-10-26,AS,0,0
2020-10-26,AZ,238964,5875
2020-10-26,CA,901010,17357
2020-10-26,CO,95089,2076
2020-10-26,CT,68099,4589
2020-10-26,DC,16812,642real **0m0.035s**
user 0m0.012s
sys 0m0.011s***

xsv 的选择的时间:~ 35 毫秒**

xsv 搜索与 csvgrep

***$ time csvcut -c date,state,positive,death all-states-history.csv | csvgrep -c state -m AL |head 
date,state,positive,death
2020-10-26,AL,185322,2866
2020-10-25,AL,184355,2866
2020-10-24,AL,183276,2866
2020-10-23,AL,180916,2859
2020-10-22,AL,177064,2843
2020-10-21,AL,174528,2805
2020-10-20,AL,174528,2805
2020-10-19,AL,173485,2789
2020-10-18,AL,172626,2788real **0m0.438s**
user 0m0.571s
sys 0m0.173s***

csvkit 的CSV prepcsvcut 的时间:~438ms**

***$ time xsv select date,state,positive,death all-states-history.csv | xsv search -s state AL |head 
date,state,positive,death
2020-10-26,AL,185322,2866
2020-10-25,AL,184355,2866
2020-10-24,AL,183276,2866
2020-10-23,AL,180916,2859
2020-10-22,AL,177064,2843
2020-10-21,AL,174528,2805
2020-10-20,AL,174528,2805
2020-10-19,AL,173485,2789
2020-10-18,AL,172626,2788real **0m0.038s**
user 0m0.026s
sys 0m0.015s***

选择进行 xsv 的搜索的时间:约 38 毫秒**

xsv 表与 csvlook

***$ time csvcut -c date,state,positive,death all-states-history.csv | csvgrep -c state -m AL | head | csvlook
|       date | state | positive | death |
| ---------- | ----- | -------- | ----- |
| 2020-10-26 | AL    |  185,322 | 2,866 |
| 2020-10-25 | AL    |  184,355 | 2,866 |
| 2020-10-24 | AL    |  183,276 | 2,866 |
| 2020-10-23 | AL    |  180,916 | 2,859 |
| 2020-10-22 | AL    |  177,064 | 2,843 |
| 2020-10-21 | AL    |  174,528 | 2,805 |
| 2020-10-20 | AL    |  174,528 | 2,805 |
| 2020-10-19 | AL    |  173,485 | 2,789 |
| 2020-10-18 | AL    |  172,626 | 2,788 |real **0m0.476s**
user 0m0.879s
sys 0m0.281s***

csvkit 的 csvlookCSV prepcsvcut 的时间:~476ms**

***$ time xsv select date,state,positive,death all-states-history.csv | xsv search -s state AL | head | xsv table
date        state  positive  death
2020-10-26  AL     185322    2866
2020-10-25  AL     184355    2866
2020-10-24  AL     183276    2866
2020-10-23  AL     180916    2859
2020-10-22  AL     177064    2843
2020-10-21  AL     174528    2805
2020-10-20  AL     174528    2805
2020-10-19  AL     173485    2789
2020-10-18  AL     172626    2788real **0m0.041s**
user 0m0.036s
sys 0m0.023s***

xsv 的工作台搜索选择的时间:~ 41 毫秒**

xsv join 与 csvjoin

***$ time csvjoin -c Abbreviation,state states.csv all-states-history.csv | csvcut -c date,State,Abbreviation,positive,death | head
date,State,Abbreviation,positive,death
2020-10-26,ALABAMA,AL,185322,2866
2020-10-25,ALABAMA,AL,184355,2866
2020-10-24,ALABAMA,AL,183276,2866
2020-10-23,ALABAMA,AL,180916,2859
2020-10-22,ALABAMA,AL,177064,2843
2020-10-21,ALABAMA,AL,174528,2805
2020-10-20,ALABAMA,AL,174528,2805
2020-10-19,ALABAMA,AL,173485,2789
2020-10-18,ALABAMA,AL,172626,2788real **1m5.788s**
user 1m5.293s
sys 0m0.462s***

csvkit 的 csvjoincsvcut 的时间:约 1.6 分钟

***$ time xsv join Abbreviation states.csv state all-states-history.csv | xsv select date,State,Abbreviation,positive,death | head
date,State,Abbreviation,positive,death
2020-10-26,ALABAMA,AL,185322,2866
2020-10-25,ALABAMA,AL,184355,2866
2020-10-24,ALABAMA,AL,183276,2866
2020-10-23,ALABAMA,AL,180916,2859
2020-10-22,ALABAMA,AL,177064,2843
2020-10-21,ALABAMA,AL,174528,2805
2020-10-20,ALABAMA,AL,174528,2805
2020-10-19,ALABAMA,AL,173485,2789
2020-10-18,ALABAMA,AL,172626,2788real **0m0.051s**
user 0m0.036s
sys 0m0.018s***

xsv 的加入选择的时间:~ 51 毫秒**

你看到刚才发生了什么吗?!51 毫秒 vs 1.6 分钟?!

嗯, xsv 在这里可以做得比 51 毫秒更好:

***$ xsv index all-states-history.csv***

像这样:

***$ time xsv join Abbreviation states.csv state all-states-history.csv | xsv select date,State,Abbreviation,positive,death | head
date,State,Abbreviation,positive,death
2020-10-26,ALABAMA,AL,185322,2866
2020-10-25,ALABAMA,AL,184355,2866
2020-10-24,ALABAMA,AL,183276,2866
2020-10-23,ALABAMA,AL,180916,2859
2020-10-22,ALABAMA,AL,177064,2843
2020-10-21,ALABAMA,AL,174528,2805
2020-10-20,ALABAMA,AL,174528,2805
2020-10-19,ALABAMA,AL,173485,2789
2020-10-18,ALABAMA,AL,172626,2788real **0m0.036s**
user 0m0.031s
sys 0m0.017s***

但是,如果我们正在调查的文件有更多的记录,我们可以感觉到 xsv 有多快。

最后的想法

根据我们对 COVID 跟踪项目 CSV 文件的 13269 条记录数据的调查,似乎 xsv 正在杀死它,并且它比 csvkit 更有性能。通过以下方式,我们发现清理数据的速度有了巨大的提高:

  • 使用 xsv 头文件了解 CSV 文件的头文件,并将其与 csvcut -n ‍进行比较
  • 使用 xsv select 过滤出我们想要的列,并与 csvcut -c 进行比较
  • 使用 xsv select 搜索特定模式,并与 csvgrep 进行比较
  • 使用 xsv 表csvlook 比较,更好地查找 CSV
  • 或者使用 xsv join 连接两个表,并与 csvjoin 进行比较

最后,您可以选择从 csvkitxsv 中选择您想要的任何东西,但是使用让我们的生活变得简单的东西是公平的,这是 xsv 尤其是当我们处理大型 CSV 文件时,如果速度和性能不是我们所追求的,尤其是当我们处理小型 CSV 时,我们可以选择 csvkit。

您可能已经注意到语法有点类似,只是在一些命令上有所不同,比如连接两个 CSV。所以你总是有选择的权利!

本教程主要是受命令行的数据科学的启发

来源:亚马逊产品

披露:这本书的亚马逊链接(在这一部分)是付费链接,所以如果你买这本书,我会有一个小的佣金**

这本书试图在您执行数据科学任务时吸引您对命令行功能的注意,这意味着您可以使用命令行获取数据、操作数据、探索数据并做出预测。如果你是一名数据科学家,渴望成为,或者想了解更多,我强烈推荐这本书。你可以从的网站上免费在线阅读,或者订购电子书或平装本。在本教程中,我们将重点关注使用命令行来清理我们的数据。

你可能会对我之前的教程感兴趣,关于为什么我们使用 docker 教程或者类似的关于如何在命令行清理文本数据的教程

*** [## Docker 中的企鹅——关于我们为什么使用 Docker 的教程

关于 docker 以及如何构建 docker 文件、挂载卷和运行 docker 映像的基础教程

medium.com](https://medium.com/swlh/penguins-in-docker-a-tutorial-on-why-we-use-docker-ce67cebf65f9) [## 如何在命令行清理文本文件

关于使用命令行工具清理数据的基础教程:tr、grep、sort、uniq、sort、awk、sed 和 csvlook

towardsdatascience.com](/how-to-clean-text-files-at-the-command-line-ce2ff361a16c)

大家注意安全,我们将在接下来的教程中再见;)

动机是

最初共享

[## 如何在命令行清理 CSV 数据

你有没有处理过一个大得吓人的 CSV 文件,它有很多你不想要的列和很多记录,会降低速度…

www.ezzeddinabdullah.com](https://www.ezzeddinabdullah.com/posts/how-to-clean-csv-data-at-the-command-line)***

如何在命令行清理 JSON 数据

原文:https://towardsdatascience.com/how-to-clean-json-data-at-the-command-line-a1f31803f6d?source=collection_archive---------29-----------------------

关于使用命令行程序 jq 清理 JSON 文件的教程

DISRUPTIVOUnsplash 拍摄的照片

jq 是一个用 c 语言编写的轻量级命令行 JSON 处理器。它遵循了 Unix 哲学,即它专注于一件事,并且能做得很好。在本教程中,我们将看到如何使用 jq 来清理 JSONs 并获取一些信息或去掉不需要的信息。

有些数据更适合 JSON 格式,而不是 CSV 或任何其他格式。大多数现代 API 和 NoSQL 数据库都支持 JSONs,如果您的数据是分层的,也很有用,可以认为是可以达到任何深度的树,本质上是任何维度,不像 CSV,它只是 2D,只能形成表格数据,而不是分层数据。

聊天机器人:意图识别数据集

今天,我们正在研究一个 JSON 文件(来自 Kaggle),它包含了意图识别数据。请下载它,因为这是我们在本教程中正在处理的文件。

先决条件

自制的

如果您使用的是 macOS,请尝试以下方法:

$ brew install jq

如果您想要最新版本,请点击此处:

$ brew install --HEAD jq

来自 GitHub

$ mkdir github		
$ cd github		
$ git clone https://github.com/stedolan/jq.git		
$ cd jq
$ autoreconf -i
$ ./configure --disable-maintainer-mode
$ make

带巧克力的窗户

$ choco install jq

如果你需要更多关于如何安装 jq 的信息,请查看 jq wiki 中的安装页面

通过索引过滤 JSONs

对于这些聊天机器人数据,我们有一些聊天机器人使用对话意图的概率,对于每个意图,我们有多个关键字,如用户可以键入的意图类型和文本,以及聊天机器人应该回复的响应等等。

标识运算符:。

现在让我们通过使用身份过滤器.来试验 jq

$ < intent.json jq '.' | head -n 20
{
  "intents": [
    {
      "intent": "Greeting",
      "text": [
        "Hi",
        "Hi there",
        "Hola",
        "Hello",
        "Hello there",
        "Hya",
        "Hya there"
      ],
      "responses": [
        "Hi human, please tell me your GeniSys user",
        "Hello human, please tell me your GeniSys user",
        "Hola human, please tell me your GeniSys user"
      ],
      "extension": {
        "function": "",

数组索引:。[0]

让我们看看第一个对象的内容:

$ < intent.json jq '.intents[0]'
{
  "intent": "Greeting",
  "text": [
    "Hi",
    "Hi there",
    "Hola",
    "Hello",
    "Hello there",
    "Hya",
    "Hya there"
  ],
  "responses": [
    "Hi human, please tell me your GeniSys user",
    "Hello human, please tell me your GeniSys user",
    "Hola human, please tell me your GeniSys user"
  ],
  "extension": {
    "function": "",
    "entities": false,
    "responses": []
  },
  "context": {
    "in": "",
    "out": "GreetingUserRequest",
    "clear": false
  },
  "entityType": "NA",
  "entities": []
}

对象标识符-索引:. foo.bar

我们也可以使用索引,让我们得到第一个意图类型:

$ < intent.json jq '.intents[0].intent'
"Greeting"

数组/对象值迭代器:。[]

如果我们想获得聊天机器人能够理解的所有意图类型,该怎么办:

$ < intent.json jq '.intents[].intent'
"Greeting"
"GreetingResponse"
"CourtesyGreeting"
"CourtesyGreetingResponse"
"CurrentHumanQuery"
"NameQuery"
"RealNameQuery"
"TimeQuery"
"Thanks"
"NotTalking2U"
"UnderstandQuery"
"Shutup"
"Swearing"
"GoodBye"
"CourtesyGoodBye"
"WhoAmI"
"Clever"
"Gossip"
"Jokes"
"PodBayDoor"
"PodBayDoorResponse"
"SelfAware"

筛选出特定值

select(布尔表达式)

jq 的一个有用功能是选择功能

我们可以用它来筛选一些有用的信息。例如,让我们得到感谢的对象的意图:

$ < intent.json jq '.intents[] | select(.intent=="Thanks")'
{
  "intent": "Thanks",
  "text": [
    "OK thank you",
    "OK thanks",
    "OK",
    "Thanks",
    "Thank you",
    "That's helpful"
  ],
  "responses": [
    "No problem!",
    "Happy to help!",
    "Any time!",
    "My pleasure"
  ],
  "extension": {
    "function": "",
    "entities": false,
    "responses": []
  },
  "context": {
    "in": "",
    "out": "",
    "clear": false
  },
  "entityType": "NA",
  "entities": []
}

让我们来看看它的反应:

$ < intent.json jq '.intents[] | select(.intent=="Thanks") | .responses'
[
  "No problem!",
  "Happy to help!",
  "Any time!",
  "My pleasure"
]

最后一个例子中的 intent 对象只有一个值。如果一个对象有多个值,比如文本,那么我们需要使用对象值迭代器。[]
比如,我们来看看任意对象中的一个文本是否有文字“你能看见我吗?”:

$ < intent.json jq '.intents[] | select(.text[]=="Can you see me?")'
{
  "intent": "WhoAmI",
  "text": [
    "Can you see me?",
    "Do you see me?",
    "Can you see anyone in the camera?",
    "Do you see anyone in the camera?",
    "Identify me",
    "Who am I please"
  ],
  "responses": [
    "Let me see",
    "Please look at the camera"
  ],
  "extension": {
    "function": "extensions.gHumans.getHumanByFace",
    "entities": false,
    "responses": [
      "Hi %%HUMAN%%, how are you?",
      "I believe you are %%HUMAN%%, how are you?",
      "You are %%HUMAN%%, how are you doing?"
    ]
  },
  "context": {
    "in": "",
    "out": "",
    "clear": false
  },
  "entityType": "NA",
  "entities": []
}

从 JSON 中过滤嵌套对象

jq 可以得到带有‘’的嵌套对象 标识操作员姓名前的按键:

$ < intent.json jq '.intents[] | select(.text[]=="Can you see me?").extension.responses'
[
  "Hi %%HUMAN%%, how are you?",
  "I believe you are %%HUMAN%%, how are you?",
  "You are %%HUMAN%%, how are you doing?"
]

所以. extension . responses等价于| . extension . responses**(最后一个过滤器的 stdout 被管道传输到嵌套的对象中)也等价于 。扩展名|。回复**

从 JSON 中删除特定的键

del(路径表达式)

让我们删除上下文、 扩展、实体类型、实体键:

**$ < intent.json jq '.intents[] | select(.text[]=="Can you see me?") | del(.context,.extension,.entityType,.entities)'
{
  "intent": "WhoAmI",
  "text": [
    "Can you see me?",
    "Do you see me?",
    "Can you see anyone in the camera?",
    "Do you see anyone in the camera?",
    "Identify me",
    "Who am I please"
  ],
  "responses": [
    "Let me see",
    "Please look at the camera"
  ]
}**

请注意,多个键可以用逗号分隔:

**del(.context,.extension,.entityType,.entities)**

最后的想法

从我们对 chatbot intent 的 JSON 数据的实验中,我们了解了如何通过以下方式清理 JSON 数据:

  • 通过使用标识操作符、数组索引、对象标识符索引和数组/对象值迭代器进行索引,从 JSON 中过滤出特定的信息
  • 使用选择功能过滤掉对象内部的特定值,我们也可以通过将标准输出传送到所需对象来过滤嵌套对象
  • 使用 del 函数从 JSON 中删除特定的键

我第一次看到 jq数据科学在命令行,我爱这本书!

来源:亚马逊产品

披露:这本书的亚马逊链接(在这一部分)是付费链接,所以如果你买这本书,我会有一个小的佣金

这本书试图在您执行数据科学任务时吸引您对命令行功能的注意,这意味着您可以使用命令行获取数据、操作数据、探索数据并做出预测。如果你是一名数据科学家,渴望成为,或者想了解更多,我强烈推荐这本书。你可以从网站上免费在线阅读,或者订购电子书或平装本

您可能对命令行中的一系列清理数据感兴趣:

** [## 如何在命令行清理 CSV 数据

关于使用命令行程序清理 CSV 文件的深入教程:csvkit 和 xsv 比较…

towardsdatascience.com](/how-to-clean-csv-data-at-the-command-line-4862cde6cf0a)

[## 如何在命令行清理 CSV 数据|第 2 部分

关于在排序和连接时使用命令行程序 csvkit 和 xsv 清理大型 CSV 文件的教程…

towardsdatascience.com](/how-to-clean-csv-data-at-the-command-line-part-2-207215881c34)

[## 如何在命令行清理文本文件

关于使用命令行工具清理数据的基础教程:tr、grep、sort、uniq、sort、awk、sed 和 csvlook

towardsdatascience.com](/how-to-clean-text-files-at-the-command-line-ce2ff361a16c)

或者我们为什么要用 docker 教程

[## Docker 中的企鹅——关于我们为什么使用 Docker 的教程

关于 docker 以及如何构建 docker 文件、挂载卷和运行 docker 映像的基础教程

medium.com](https://medium.com/swlh/penguins-in-docker-a-tutorial-on-why-we-use-docker-ce67cebf65f9)

保重,下次教程再见:)

和平!

点击此处 获取新内容到您的收件箱

资源

最初共享

[## 如何在命令行清理 JSON 数据

jq 是一个用 c 编写的轻量级命令行 JSON 处理器。它遵循 Unix 的理念,即它专注于一个…

www.ezzeddinabdullah.com](https://www.ezzeddinabdullah.com/posts/how-to-clean-json-data-at-the-command-line)**

如何在命令行清理文本数据

原文:https://towardsdatascience.com/how-to-clean-text-files-at-the-command-line-ce2ff361a16c?source=collection_archive---------32-----------------------

关于使用命令行工具清理数据的基础教程:tr、grep、sort、uniq、sort、awk、sed 和 csvlook

JESHOOTS.COMUnsplash 上拍照

清理数据就像清理你家的墙壁,你清除任何乱涂乱画,清除灰尘,过滤掉那些让你的墙壁变丑的不必要的东西,把它去掉。清理数据时也会发生同样的事情,过滤掉我们想要的,去掉我们不想要的,让原始数据变得有用而不再原始。您可以使用 Python、R 或任何您喜欢的语言进行清理,但在本教程中,我将通过一篇研究 clickbait 和非 clickbait 数据的论文来解释如何在命令行文件中清理文本文件。

提取并运行 docker 映像

为了消除下载我们处理的文件和我们需要的依赖关系的麻烦,我为你做了一个 docker 镜像,它包含了你需要的所有东西。你只需从 docker hub 中拉出它,就能找到你需要玩的东西,让你专注于清洁部分。所以让我们提取那个图像,然后交互地运行它以进入 shell 并编写一些命令行。

  • docker run 是运行 docker 镜像的命令
  • 选项— rm 设置为在容器存在后移除容器
  • 选项 -it-i-t 的组合,是为交互进程(shell)设置的
  • ezzeddin/clean-data 是 docker 图像名称

如果使用 docker 对你来说还不清楚,你可以看看为什么我们使用 docker 教程

[## Docker 中的企鹅——关于我们为什么使用 Docker 的教程

关于 docker 以及如何构建 docker 文件、挂载卷和运行 docker 映像的基础教程

medium.com](https://medium.com/swlh/penguins-in-docker-a-tutorial-on-why-we-use-docker-ce67cebf65f9)

清理文本文件

让我们清理两个文本文件,分别包含 16,000 篇文章的 clickbait 和非 clickbait headlines。这个数据来自于 2016 年 IEEE/ACM 社交网络分析与挖掘进展国际会议(ASONAM)上的一篇题为: 停止点击诱饵:检测和防止在线新闻媒体 中的点击诱饵的论文。我们的目标是获得点击诱饵和非点击诱饵标题中最常用的词。

如果您列出容器中的内容,您会看到两个文本文件,分别名为 clickbait_datanon_clickbait_data 。让我们先看看我们想要的最终输出是什么。对于 clickbait 数据,我们希望最常见的 20 个单词以如下方式表示,并给出它们的计数:

作者图片

非点击诱饵标题中最常见的 20 个单词:

作者图片

让我们看看如何通过命令行一步一步地获取这些直方图。运行 docker 映像后,我们现在处于一个新环境的新 shell 中。让我们首先通过获取文件的前 10 行来看看 clickbait_data 文件有什么:

$ head clickbait_data

如此看来,这个文件的标题被标记为 clickbait,正如您所看到的:

Should I Get BingsWhich TV Female Friend Group Do You Belong InThe New "Star Wars: The Force Awakens" Trailer Is Here To Give You ChillsThis Vine Of New York On "Celebrity Big Brother" Is Fucking PerfectA Couple Did A Stunning Photo Shoot With Their Baby After Learning She Had An Inoperable Brain Tumor 

如果您使用 head 获取 non_clickbait_data 的第一行,您会发现:

Bill Changing Credit Card Rules Is Sent to Obama With Gun Measure Included
In Hollywood, the Easy-Money Generation Toughens Up
1700 runners still unaccounted for in UK's Lake District following floodYankees Pitchers Trade Fielding Drills for Putting Practice
Large earthquake rattles Indonesia; Seventh in two daysColdplay's new album hits stores worldwide this weekU.N. Leader Presses Sri Lanka on Speeding Relief to War Refugees in Camps

我们感兴趣的是单词而不是短语,所以我们可以得到从 3 个字母到更多字母的单词:

$ head clickbait_data | grep -oE '\w{3,}'

这里使用 head clickbait_data 是因为我们在这里对文件顶部的几个标题进行统计,这些标题通过管道传送到下一个 grep 命令 grep -oE '\w{3,}'

**grep
   -oE -o** for getting only matching words and **-E** for using extended regular expression which is the next pattern
   **‘\w{3,}’** this pattern is like **‘\w\w\w+’** which matches whole words with 3 letters or more

为了获得每个单词的计数,我们需要首先获得唯一的单词,我们可以通过带有选项 -cuniq 命令获得这些单词,以便给你计数,但是要让 uniq 删除重复的单词,你需要首先排序:

$ head clickbait_data | grep -oE '\w{3,}' | sort | uniq -c

该命令在前 10 行执行,让我们在整个 clickbait 标题中执行:

$ cat clickbait_data | grep -oE '\w{3,}' | sort | uniq -c | sort -nr | head
  • cat clickbait _ data | grep-oE ' \ w { 3,}' | sort | uniq -c 我们现在将这个命令(获取 click bait 数据中的所有单词)放入下一个命令的标准输入中
  • sort -nr 以相反的顺序进行数字排序,首先得到最高的计数
  • 获取前 10 个常用单词

以下是前一个命令的输出:

 5538 You
   4983 The
   2538 Your
   1945 That
   1942 Are
   1812 This
   1645 And
   1396 For
   1326 What
   1242 Will

看起来我们现在很接近一个良好的状态,让我们看看我们能做些什么来更好地清理它。

如果我们深入观察

戴维·特拉维斯在 Unsplash 上拍摄的照片

我们可以看到我们遗漏了小写字母和全部大写字母。例如,对于“你”这个词,我们漏掉了“你”,我们也漏掉了“你”。让我们试着看看这些单词是否已经存在:

$ cat clickbait_data | grep -oE '\w{3,}' | sort | uniq -c | sort -nr | grep you
$ cat clickbait_data | grep -oE '\w{3,}' | sort | uniq -c | sort -nr | grep YOU

所以我们可以看到:

 1 your
      1 you
      1 YOUR
      1 YOU

我们少了两个单词,每个单词都有助于我们计算“You”和“Your”的出现次数,使它们分别为 5540 和 2540。

我们首先需要做的是使用 tr 将每个大写字母转换成小写字母,tr 是一个命令行实用程序,用于翻译字符:

$ cat clickbait_data | tr '[:upper:]' '[:lower:]'| grep -oE '\w{3,}' | sort | uniq -c | sort -nr | head

tr '[:upper:]' '[:lower:]' 这里将 clickbait_data 的内容翻译成小写。 ['upper'] 是代表所有大写字符的字符类,而 ['lower'] 是代表所有小写字符的字符类。

为了在标题前添加这些值,我们可以使用 sed 来放置两个列名来表示每一列:

$ cat clickbait_data | tr '[:upper:]' '[:lower:]'| grep -oE '\w{3,}' | sort | uniq -c | sort -nr | sed '1i count,word' | head

sed '1i count,word' 所以我们用 count 表示出现的次数,用 word 显然表示这个单词

此处使用 1i 将这两个字写在第一行,文件中的更改将会到位

输出:

count,word 
5540 you
4992 the
2540 your
1950 that
1944 are
1812 this
1653 and
1397 for
1326 what

为了以漂亮的形状打印出来,我们可以使用 csvlook 来得到这个:

| count        | word |
| ------------ | ---- |
|    5540 you  |      |
|    4992 the  |      |
|    2540 your |      |
|    1950 that |      |
|    1944 are  |      |
|    1812 this |      |
|    1653 and  |      |
|    1397 for  |      |
|    1326 what |      |

一点也不好看。发生这种情况的原因是 csvlook 的工作方式正如其名称所表明的那样,是为了更好地寻找 CSV 文件,所以我们应该先有一个 CSV(逗号分隔值)文件。然后,我们应该找到一种方法,用逗号分隔每行的每个值。在这一点上,我们可以使用 awk ,它是一种面向模式的扫描和处理语言:

**awk '{print $1","$2}'
'{
     print $1** here prints the first field (which is the count column)   followed by…
     **“,”** a comma followed by…
     **$2** the second field which is the word column
**}'**

看起来我们现在的情况好多了:

| count | word |
| ----- | ---- |
| 5,540 | you  |
| 4,992 | the  |
| 2,540 | your |
| 1,950 | that |
| 1,944 | are  |
| 1,812 | this |
| 1,653 | and  |
| 1,397 | for  |
| 1,326 | what |

如果我们想在第一个字段中得到 word 列,在第二个字段中得到 count 列,我们只需要颠倒 awksed 命令中的顺序:

$ cat clickbait_data | tr '[:upper:]' '[:lower:]'| grep -oE '\w{3,}' | sort | uniq -c | sort -nr | awk '{print $2","$1}' | sed '1i word,count' | head | csvlook

为了让非点击诱饵数据得到相同的输出,我们只需更改文件名:

$ cat **non_clickbait_data** | tr '[:upper:]' '[:lower:]'| grep -oE '\w{3,}' | sort | uniq -c | sort -nr | awk '{print $2","$1}' | sed '1i word,count' | head | csvlook

深入了解 clickbait 研究

在由论文报道的这项研究中,它解决了点击诱饵和非点击诱饵标题,以便能够检测这两种标题

大多数在线新闻媒体严重依赖读者点击产生的收入,由于众多此类媒体的存在,它们需要相互竞争以吸引读者的注意力。

因此,本教程中的内容是一种通过命令行清理数据的方法,以便我们可以对这篇论文的结果有所了解,并看看我们是否可以通过他们的研究获得这篇论文所声称的一些观点。

我们再来看一下这个数据的 clickbait 标题最常见的 20 个词的最终分布情况是:

作者图片

我们可以明显地看到所有格的过度使用,而没有使用第三人称指称像他,她,或一个特定的名字

还有你的可能会出现在 clickbait 常用的短语中,比如“Will Blow Your Mind”。此外,我们还可以找到常用的限定词,如这个、那个、哪个

让用户对所引用的对象好奇,并说服他们进一步探究文章。

另一方面,非点击诱饵标题的最常见的 20 个单词的分布是:

作者图片

我们可以在这里看到非所有格词,如澳大利亚人、总统、奥巴马以及其他一些在两者中都可能出现的词。

最后的想法

clickbait 论文建议进行比我们在这里所做的更深入的研究,但是我们可以通过命令行中的一行代码获得一些有价值的见解。我们学习了如何使用 tr 翻译字符,使用 grep 过滤出从 3 个字母开始的单词,使用 sortuniq 获得单词出现的直方图,使用 awk 在我们想要的位置打印字段,使用 sed 将标题放入我们正在处理的文件。

感谢您来到这里!

动机是

本教程主要由命令行的数据科学推动。

来源:亚马逊产品

披露:这本书的亚马逊链接(在这一部分)是付费链接,所以如果你买这本书,我会有一个小的佣金

这本书试图在您执行数据科学任务时吸引您对命令行功能的注意,这意味着您可以使用命令行获取数据、操作数据、探索数据并做出预测。如果你是一名数据科学家,渴望成为,或者想了解更多,我强烈推荐这本书。你可以从网站上免费在线阅读,或者订购电子书或平装本。在本教程中,我们将重点关注使用命令行来清理我们的数据。

最初发布

[## 如何在命令行清理文本数据

清理数据就像清理你家的墙壁,你清除任何乱涂乱画,清除灰尘,并过滤掉那些…

www.ezzeddinabdullah.com](https://www.ezzeddinabdullah.com/posts/how-to-clean-text-data-at-the-command-line)

如何清理杂乱的数据?

原文:https://towardsdatascience.com/how-to-clean-up-messy-data-9a8376475c67?source=collection_archive---------59-----------------------

使用 OpenRefine

图片来源:基思·麦纽提

我在 Linkedin 上看到一个帖子,提到了一个数据集,其中城市费城的拼写是 57(!)不同的方式,并询问数据科学家对处理数据质量问题的看法。来自同一个宾夕法尼亚州的 57 种亨氏酱有什么联系吗?😃

我看到另外两个的帖子也在讨论这个问题,评论从收集这些数据的应用程序应该有更好的验证到人们应该学习如何拼写。嗯,有时候在数据科学家/数据工程师的工作中,你确实会遇到这样的数据质量问题,你只需要处理它。也许您可以实现更好的控制,以便在将来获得更好的数据,但是如果您想要使用已经收集的数据,就必须对其进行清理。在这篇文章中,我将展示如何用免费数据辩论工具 open refine 解决这个问题。

OpenRefine

OpenRefine(原名 Google Refine)是一个强大的工具,无需任何编码就可以轻松转换数据。而如果你是程序员,你可以使用 GREL(Google Refine Expression Language,类似于 Excel 公式)来做一些复杂的数据转换。这个工具有趣的一面是,它是免费的、开源的,可以本地安装在你的笔记本电脑上,所有的数据处理都在本地完成。数据永远不会离开你的电脑。我在数据迁移项目中使用过 OpenRefine,遗留应用程序有包含地址、姓名等的自由文本字段,需要在迁移到目标系统之前进行标准化和转换,它工作得非常好。

我们可以在哪里使用 OpenRefine?

混乱文本的例子

当我们有杂乱的文本数据时,就像在这个例子中一样(顶部条目是正确的),同一个单词拼写错误,大小写字符混合,有些有前导或尾随空格,空白字符,扩展西文字符,名字和姓氏顺序混淆,日期以不同的方式书写,我们可以使用 Open Refine 来清理它。

PPP 数据集上的 open refine

  • 数据集:数据来自美国的 PPP(工资保障计划),包含新冠肺炎危机期间小企业贷款的数据。让我们以宾夕法尼亚州的数据集为例,获取 15 万美元以下的贷款。
  • OpenRefine:下载 OpenRefine v3.3 。安装完成后,运行 OpenRefine.exe 文件,这将在浏览器中打开一个指向 127.0.0.1:3333 的窗口。

创建一个项目
该工具会打开一个选项来创建一个项目。我们可以从不同的文件格式(JSON、CSV、固定宽度等)和来源(本地计算机和直接从网络)导入数据。

创建项目-加载数据

OpenRefine 读入文件内容,尝试自动识别不同的列和标题,并显示预览。如果需要,我们可以修改设置。一旦我们对预览感到满意,我们可以点击“创建项目”。

文件解析选项

OpenRefine 然后加载数据并显示一个类似于电子表格的视图。我们可以单击列顶部的向下箭头,查看我们可以对数据进行的各种数据转换。

数据被加载到项目中

让我们来看看列城。我们有兴趣看到费城拼写错误的条目。为了方便地查看分布情况,我们可以过滤以 ph 开头的行(假设至少前两个字符拼写正确:-))。我们可以使用正则表达式'ph'.字符''确保只显示以 ph 开头的城市。这并不是绝对必要的,但是这有助于限制我们在 facet 窗口中容易看到的条目的变化。

文本过滤器

然后,我们添加一个文本方面,它显示列“city”中每个不同值的行数。正如你所看到的,费城的拼写有相当多的变化。

添加文本方面

编辑文本 inline
如果有一个条目需要更正,我们可以直接点击该条目旁边的编辑并替换该值。如果我们要替换几个值,这没问题。

编辑单个条目

集群和编辑 但是如果我们有太多的变化需要用单个值替换,我们可以选择基于一些内置方法对条目进行集群,然后一次性编辑它们。

聚类和编辑

点击聚类按钮,打开一个窗口,其中的条目根据默认方法“按键碰撞”和功能“指纹”聚类在一起。我们可以改变键控函数,看到条目以不同的方式聚集。

聚类方法和函数

一旦我们对集群满意了,我们就可以继续为这些集群提供新的值。如果“键碰撞”没有得到想要的结果,我们可以尝试另一种方法“最近邻”。我们还可以重复聚类和编辑。我们不需要知道函数的所有内部工作原理来使用它,尽管如果你好奇的话,文档是一个有趣的读物。

随意试验不同的方法,选择最适合给定数据的方法。对于这个数据集,半径为 8 的 Levensthein 距离给出了最好的结果。

经过几次重新聚类,我们已经纠正了费城所有不正确的条目。

我们到目前为止所做的所有手动清洁动作都被记录。我们可以看到它们作为一系列步骤列在“撤销/重做”下面。我们可以返回到任何步骤,并在该步骤结束时看到结果。如果我们对某个特定的步骤不满意,我们可以只做另一个清洁动作,然后覆盖这个步骤。

一旦我们对结果满意,我们就可以导出干净的数据

以不同格式导出清理后的数据

总之,OpenRefine 是一个有效的数据辩论工具

  1. 你不需要成为一个程序员来使用它。它就像一个电子表格,很容易处理。
  2. 数据清理规则的交互式可视化规范有助于共同提出动态数据修正规则。当您需要从业务领域的主题专家那里获得意见时,这非常有用,因为他们更喜欢看数据而不是代码。
  3. 所有清洁动作都被记录为 JSON 脚本,这有助于再现性自动化(将在另一篇文章中具体阐述)

对于特定的数据清理来说,这听起来不错,但是我们能在自动化的数据清理管道中使用它吗?

当然,你可以!。

OpenRefine 有一些我们可以使用的客户端库。我会写一篇关于如何使用 Python 和 OpenRefine 建立数据清理管道的帖子。敬请关注…

资源

我们只讨论了 OpenRefine 的一小部分特性。它能提供更多的东西。伊利诺伊大学和杜克大学 T21 分校有很好的教程让你入门。

开始的方法是停止说话,开始行动——华特·迪士尼

如何在 SQL 中克隆表

原文:https://towardsdatascience.com/how-to-clone-tables-in-sql-dd29586ec89c?source=collection_archive---------0-----------------------

了解如何创建表的克隆

照片由卡斯帕·卡米尔·鲁宾Unsplash 上拍摄

在数据库操作中,有时您可能需要将一个现有的表克隆或复制到一个新表中,因为它们在列和属性上有相似性,或者是为了在不影响原始表的情况下执行测试,或者是出于其他个人原因。

我遇到了这种情况,我需要为我们正在集成的新特性创建一组新的表。这个表有相当多的列,并且非常类似于处理另一组特定特性的类似数据的现有表。

因为这个现有的表和新表非常相似,所以我的快速解决方案是克隆现有的表来创建新表。

在 SQL 中,这很容易做到,因为您可以轻松地运行几个命令来最大限度地满足您的克隆需求。

在本文中,我将向您展示如何在 SQL 中复制和克隆现有的表。

简单克隆

第一种方法称为简单克隆,顾名思义,它从另一个表创建一个表,而不考虑任何列属性和索引。

CREATE TABLE *new_table* SELECT * FROM *original_table*;

因此,如果我有一个名为users的表,我可以很容易地创建另一个名为adminUsers的表,而不用关心users表的列属性和索引。

下面的 SQL 命令创建了一个简单的users表副本。

CREATE TABLE *adminUsers* SELECT * FROM *users*;

使用它可以快速克隆任何只包含原始表的结构和数据的表。

浅层克隆

浅层克隆主要用于在不复制数据的情况下创建现有表数据结构和列属性的副本。这只会基于原始表的结构创建一个空表。

CREATE TABLE *new_table* LIKE *original_table*;

以下命令将基于原始表创建一个空表。

CREATE TABLE *adminUsers* LIKE *users*;

如果您只需要原始表的数据结构和列属性,请使用此选项

深度克隆

深度克隆与简单克隆有很大的不同,但与浅层克隆相似,只是数据不同,顾名思义,它创建原始表的深度副本。

这意味着新表将拥有现有表的每个列和索引的所有属性。如果您想维护现有表的索引和属性,这非常有用。

为此,我们必须根据原始表的结构和属性创建一个空表,然后从原始表中选择数据并插入到新表中。

CREATE TABLE *new_table* LIKE *original_table*;
INSERT INTO *new_table* SELECT * FROM *original_table*;

要轻松克隆我们的原件并复制其数据:

CREATE TABLE *adminUsers* LIKE *users*;
INSERT INTO *adminUsers* SELECT * FROM *adminUsers*;

现在另一件很酷的事情是,假设您不想要现有表中的所有数据,只想要一些数据,基于一些条件,然后微调您的SELECT查询是您的最佳选择。

例如,我们的users表中有带userType="admin"的用户,我们只想将这些用户复制到我们的新表中,您可以像下面这样轻松地完成:

INSERT INTO *adminUsers* SELECT * FROM *adminUsers where userType="admin"*;

酷吧?我知道。

如果您是 SQL 新手,下面是一些有用的资源:

[## SQL 教程

SQL 是一种在数据库中存储、操作和检索数据的标准语言。我们的 SQL 教程将教你…

www.w3schools.com](https://www.w3schools.com/sql/default.asp) [## HTML5 - Web SQL 数据库

实际上,Web SQL 数据库 API 并不是已发布的 HTML5 规范的一部分,它是一个规范…

siitgo.com](https://siitgo.com/pages/lhtml5z-8/1472/html5-web-sql-database)

如何基于视觉相似性对图像进行聚类

原文:https://towardsdatascience.com/how-to-cluster-images-based-on-visual-similarity-cd6e7209fe34?source=collection_archive---------1-----------------------

使用预训练的神经网络进行特征提取,并使用 K-means 对图像进行聚类。

Unsplash 上的 Pietro Jeng 拍摄

目标

在本教程中,我将指导您使用预训练的神经网络从图像中提取特征向量,并根据特征向量的相似程度对图像进行聚类。

车型

本教程将使用的预训练模型是 VGG16 卷积神经网络(CNN),它被认为是图像识别任务的最先进技术。我们将仅使用该模型作为特征提取器,这意味着我们将移除最终(预测)层,以便我们可以获得特征向量。

数据

这个实现将使用 Kaggle 的 flowers 数据集,您可以从这里下载。该数据集包含 10 种不同花卉的 210 张图片,这些图片将被下载为 png 文件。

进口

在我们开始之前,我们需要导入所需的模块,以便加载/处理图像以及提取和聚类我们的特征向量的模块。

导入报表

  • load_img 允许我们从文件中加载一张图片作为 PIL 对象
  • img_to_array 允许我们将 PIL 对象转换成 NumPy 数组
  • preprocess _ input用于将图像准备成模型要求的格式。您应该使用 Keras load_img 函数加载图像,以便确保您加载的图像与 preprocess_input 函数兼容。
  • VGG16 是我们将要使用的预训练模型
  • k 表示我们将要使用的聚类算法
  • PCA 用于降低我们特征向量的维数

加载数据

既然数据已经下载到您的计算机上,我们希望 python 指向图像所在的位置。这样,我们不用加载完整的文件路径,只需使用文件名即可。

加载数据

# view the first 10 flower entries
print(flowers[:10])output:
['0001.png', '0002.png', '0003.png', '0004.png', '0005.png', '0006.png', '0007.png', '0008.png', '0009.png', '0010.png']

现在我们已经将所有的文件名加载到花的列表中,我们可以开始预处理图像了。

数据预处理

这就是我们使用 load_img()preprocess_input() 方法的地方。加载图像时,我们将目标大小设置为(224,224 ),因为 VGG 模型期望它接收的图像是 224x224 NumPy 数组。

加载图像

目前,我们的阵列只有 3 个维度(行、列、通道),并且该模型在批量样本中运行。所以我们需要扩展我们的数组来增加维度,让模型知道我们给了它多少图像(样本数,行数,列数,通道数)。

图像整形

 Number of dimensions: 4 
Number of images (batch size): 1 
Number of rows (0th axis): 224 
Number of columns (1st axis): 224 
Number of channels (rgb): 3

最后一步是将整形后的数组传递给 preprocess_input 方法,我们的图像就可以加载到模型中了。

预处理输入

模型

现在我们可以加载 VGG 模型并手动移除输出层。这意味着新的最终层是具有 4,096 个输出节点的全连接层。这个 4,096 个数字的向量是我们将用来对图像进行聚类的特征向量。

现在,最后一层被删除,我们可以通过我们的图像通过预测方法来获得我们的特征向量。

下面是一个函数中的所有代码

特征提取流水线

现在我们可以使用这个 feature_extraction 函数从所有图像中提取特征,并将这些特征存储在一个以文件名为关键字的字典中。

Wall time: 56.2 s

降维(PCA)

由于我们的特征向量有 4000 多个维度,如果你将维度数量从 4000 减少到一个更小的数字,你的计算机会感谢你。我们不能简单地通过切片或使用它的子集来缩短列表,因为我们会丢失信息。如果有一种方法可以在保留尽可能多的信息的同时降低维度就好了。

进入主成分分析的领域。

我不打算浪费时间解释什么是 PCA,因为已经有成吨的文章解释它,我将在这里链接。

简单地说,如果您正在处理数据,并且有许多变量需要考虑(在我们的例子中是 4096),PCA 允许您减少变量的数量,同时尽可能多地保留原始数据集中的信息。

要减少的维度数量由您决定,我相信有一种方法可以找到最佳的组件数量,但在这种情况下,我只是选择 100 作为一个任意的数字。

print(f"Components before PCA: **{**f.shape[1]**}**")
print(f"Components after PCA: **{**pca.n_components**}**")Components before PCA: 4096
Components after PCA: 100

现在我们有了一个更小的特征集,我们可以对我们的图像进行聚类了。

k 均值聚类

您将定义一个目标数 k,它是指数据集中所需的质心数。质心是代表群集中心的虚拟或真实位置。

该算法将允许我们将我们的特征向量分组为 k 个簇。每个聚类应该包含视觉上相似的图像。在这种情况下,我们知道有 10 种不同的花,所以 k = 10。

kmeans.labels_

【6,6,8,6,6,5,4,6,5,6,4,6,3,3,5,6,6,4,4,8,1,
3,8,4,2,8,4,2,6,9,7,4,4,0,5,4,4,9,8,5,9,3,6,6,
5,1,3,9,6,5,0,1,3,9,6,7,4,4,5 5,0,5,1,2,9,5,4,8,1,
7,1,3,5,4,8,5,4,6,9,5,9,5,8,5,8,1,4,9,8,5,4,5,6,
4,1,8,9,4,6,5,7,5,6,4,8,1,4,5,5,8,6,5,2,4,8,8,
5,1,1,1,6,6,6 9,0,4,0,6,4,9,0,3,5,0,3,9,9,4,9,5,0,9,5,5,4,
5,1,8,3,6,4,5,2,6,6,9,5,0,3,3,5,4,5,0,9,4,
2,1,0,9,4,9,1,2,6,1,6,0

列表中的每个标签都是数据集中每个图像的聚类标识符。标签的顺序与每个图像的文件名列表平行。这样,我们可以将图像分组到它们的簇中。

# view the filenames in cluster 0
groups[0]output: 
['0035.png',
 '0051.png',
 '0080.png',
 '0149.png',
 '0150.png',
 '0157.png',
 '0159.png',
 '0163.png',
 '0166.png',
 '0173.png',
 '0189.png',
 '0196.png',
 '0201.png',
 '0210.png']

我们剩下要做的就是查看一个集群,通过检查集群来了解我们的模型表现如何。

群集 0

群组 1

群组 2

这里我们可以看到我们的模型在花的图像聚类上做得很好。我们甚至可以看到聚类 2 和聚类 0 都有黄色的花,但是每个聚类中的花的类型是不同的。

结论

下面是一个文件中的整个过程。

希望你们都学到了新的东西,如果有任何问题或有顿悟时刻,请留下评论:)

参考

如何用 PyTorch 编写一个简单的神经网络?—适合绝对的初学者

原文:https://towardsdatascience.com/how-to-code-a-simple-neural-network-in-pytorch-for-absolute-beginners-8f5209c50fdd?source=collection_archive---------11-----------------------

这是一个简单易懂的教程,使用 PyTorch 和 Kaggle 上流行的 Titanic 数据集来构建神经网络

图片来自 Unsplash

在本教程中,我们将看到如何使用 PyTorch 框架为分类问题构建一个简单的神经网络。这将帮助我们掌握基础知识和框架的基本语法。同样,我们将使用 Kaggle 的泰坦尼克号数据集。

安装 PyTorch

## For Windows
pip install torch===1.5.0 torchvision===0.6.0 -f [https://download.pytorch.org/whl/torch_stable.html](https://download.pytorch.org/whl/torch_stable.html)## For Linux
pip install torch torchvision

如果您的计算机配置不同(基于 Conda 的库或 Mac 系统),您可以从这个链接中检查合适的命令。

数据集准备

首先,通过参加比赛从 Kaggle 下载数据集,或者你也可以从其他来源获得(简单的谷歌搜索会有帮助)。一旦你设置好数据集和 PyTorch 包,我们就可以开始深入研究了。在设计架构之前,首先要做的是根据 PyTorch 的要求准备数据,这可以使用 PyTorch 本身提供的数据集模块来完成。如果你觉得很难理解,让我给你解释一下。您将处理的大多数数据都是 Numpy 结构。现在,这不能直接输入网络,因为它们不是张量。Pytorch 要求您以这些张量的形式输入数据,这类似于任何 Numpy 数组,只是它也可以在训练时移动到 GPU。你所有的梯度,你的网络处理的权重,都是相同的张量数据结构。随着你进一步阅读博客,你将能够得到更好的理解。现在,让我们加载数据。

现在我们导入Dataset模块来继承_ _ getitem _ _()len() 等库中预定义的各种函数。这些函数将帮助我们创建自定义类来初始化数据集。下面的代码显示了如何创建数据集类。

注意:在上面的代码中,我们的数据帧的最后一列包含目标类,而其余的是输入特征,因此我们将其拆分为到 self.inpself.oup 变量,如果我们要训练,我们需要输入和输出,否则只需要输入数据。

init() 函数读取。csv* 文件,我们稍后会对其进行一些预处理(这与本教程无关)。_ _ len _ _()函数返回示例的数量,而 _ _getitem _ _()用于通过使用其索引来获取数据。从上面这段代码中需要注意的重要一点是,我们已经使用 torch.tensor 函数将我们的训练示例转换为张量,同时使用它的索引调用它。所以在整个教程中,无论我们在哪里取例子,都是以张量的形式。*

现在,既然数据已经准备好了,让我们将它分批加载。这可以使用如下的 数据加载器 功能轻松完成。

您必须将前一个函数产生的数据集对象作为参数传递。根据批次的数量,结果将是一个形状为 (no_of_batches,batch_size,size_of_the_vector)的多维张量。 现在,对于其他类型的数据,如图像或序列数据,其维数会根据其性质而相应变化。但是现在,只要理解有多个批次,并且每个批次包含一些等于批次大小的示例(不管使用什么数据)。

现在深呼吸…你已经完成一半了。😃

神经网络体系结构

现在,既然我们已经为训练准备好了数据,我们必须在开始训练之前设计神经网络。任何具有常规使用的超参数的模型都可以(Adam 优化器、MSE 损失)。为了给我们的神经网络编码,我们可以使用 nn。模块创建相同。

nn。线性(),nn。继承 nn 后,BatchNorm1d() 全部变为可用。模块类()。然后你可以简单地通过调用它来使用它们。由于我们使用简单的表格数据,我们可以使用简单的密集层(或全连接层)来创建模型。对于激活,我使用了自定义定义的【swish()。你也可以选择雷鲁。ReLu 在nn . functional()模块中可用。你可以简单地用 F.relu() 替换 swish()由于这是一个二进制分类,所以没有必要在最后一层使用 softmax。我已经使用 sigmoid 函数对我的例子进行了分类。在上面的代码中, init() 帮助您在调用构造函数时立即初始化您的神经网络模型,并且 forward() 函数控制通过网络的数据流,使其负责前馈。当我们进入训练循环时,你将看到我们如何调用 forward 函数。**

训练模型

您的培训过程可以安排如下:

  • 你可以定义你的训练参数,比如次数,损失函数,优化器。所有的优化器在torch . optim()中都有。您的优化函数将网络的权重作为其参数。在下面的代码中,net 变量包含我们在上面的小节中创建的神经网络模型,net . parameters()引用网络的权重。

  • 每一批数据都被输入网络。基于损失函数,我们计算该特定批次的损失。一旦计算出损失,我们通过调用函数来计算梯度。一旦你计算出梯度,我们就更新现有的权重。每个时期的每个批次都会发生相同的过程。正如我前面提到的,我们可以简单地绕过神经网络的输入作为参数来进行前馈。(就像下面代码中的 型号(x) )。**

optimizer . step()用于使用计算出的梯度更新权重。

  • 在纪元结束时,我们对验证数据进行预测。最后,我们根据训练预测和验证数据计算准确度。

  • 为了得到一个整体的想法,我把我的整个训练循环贴在了下面。

  • 基于可用的计算资源,您可以使用下面的代码将您的数据和网络移动到 GPU。记住,无论你使用哪个设备,所有的输入、输出数据以及网络都应该在同一个设备上(否则,它会抛出一些愚蠢的错误:p)。

你完成了教程…:)为自己感到骄傲。

参考

[1]https://py torch . org/tutorials/beginner/deep _ learning _ 60min _ blitz . html

如何用 Python 编写不同类型的移动平均线?

原文:https://towardsdatascience.com/how-to-code-different-types-of-moving-averages-in-python-4f8ed6d2416f?source=collection_archive---------15-----------------------

用 Python 编写不同类型的移动平均线。

交易软件带有不同类型的移动平均线,已经预先安装并准备好了。但是理解如何计算这些移动平均线是很有趣的,以便在回测潜在策略时能够使用它们。

在 Python 的 新技术指标成功后,我刚刚出版了一本新书。它对复杂的交易策略进行了更完整的描述和补充,Github 页面致力于不断更新代码。如果你对此感兴趣,请随时访问下面的链接,或者如果你喜欢购买 PDF 版本,你可以在 Linkedin 上联系我。

[## 交易策略之书

亚马逊网站:交易策略之书(9798532885707): Kaabar,Sofien:书籍

www.amazon.com](https://www.amazon.com/gp/product/B09919GQ22/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B09919GQ22&linkCode=as2&tag=sofien-20&linkId=bc5df3f6ab0f3af2df79641c56b949ba)

如果你想要一个自己动手的方法,那么下面的肯定会让你感兴趣。所需要的只是 SPYDER 这样的 python 解释器。不同的“已知”移动平均线类型有:

  • 简单移动平均线。
  • 指数移动平均线。
  • 平滑移动平均线。
  • 线性加权移动平均线。

我们将逐一介绍,定义,编码,并绘制图表。

GBPUSD 每日图表。黑色的是 200 日均线,深红色的是 200 日均线,黄色的是 200 日平滑均线,粉色的是 200 日线性加权均线。

简单移动平均线

顾名思义,这是一个简单的平均数,在统计学和我们生活中的任何地方都会用到。它就是观察值的总和除以观察次数。

从数学上来说,它可以写成:

在 python 中,我们可以定义一个计算移动平均值的函数,如下所示:

def ma(Data, period, onwhat, where):

    for i in range(len(Data)):
            try:
                Data[i, where] = (Data[i - period:i + 1, onwhat].mean())

            except IndexError:
                pass
    return Data

该函数采用由数据变量表示的数据结构,移动平均周期(20、60、200 等。)由 period 变量表示,您希望对其应用什么(在 OHLC 数据结构上,选择 3 表示收盘价,因为 python 索引从零开始)由 what 变量表示, where 变量是您希望移动平均线列出现的位置。请注意,您必须有一个超过 4 列的数组才能工作,因为它不会自动创建一个新列,而是简单地填充它。

欧元兑美元每日时间跨度,200 天简单移动平均线。

指数移动平均线

与简单的移动平均线给所有的观察值相同的权重相反,指数移动平均线给最近的观察值更多的权重。它比简单的移动平均线对最近的变动反应更大。

从数学上来说,它可以写成:

平滑因子通常为 2。请注意,如果我们增加平滑因子(也称为 alpha ),那么最近的观测值将具有更大的权重。

在 python 语言中,我们可以定义一个函数来计算 EMA,如下所示:

def ema(Data, alpha, window, what, whereSMA, whereEMA):

    # alpha is the smoothing factor
    # window is the lookback period
    # what is the column that needs to have its average calculated
    # where is where to put the exponential moving average

    alpha = alpha / (window + 1.0)
    beta  = 1 - alpha

    # First value is a simple SMA
    Data[window - 1, whereSMA] = np.mean(Data[:window - 1, what])

    # Calculating first EMA
    Data[window, whereEMA] = (Data[window, what] * alpha) + (Data[window - 1, whereSMA] * beta)# Calculating the rest of EMA
    for i in range(window + 1, len(Data)):
            try:
                Data[i, whereEMA] = (Data[i, what] * alpha) + (Data[i - 1, whereEMA] * beta)

            except IndexError:
                pass
    return Data

该函数是不言自明的,因为它只是复制了上面介绍的 EMA 函数。

欧元兑美元每日时间跨度,200 天指数移动平均线。

平滑移动平均值

该移动平均线考虑了总体情况,受近期走势的影响较小。这是我最喜欢的趋势跟踪指标。从数学上来说,简单地将 EMA 函数中的 Days 变量乘以 2 再减去 1 就可以得到。这意味着,要将指数移动平均线转换为平滑移动平均线,我们需要遵循 python 语言中的等式,即将指数移动平均线转换为平滑移动平均线:

smoothed = (exponential * 2) - 1 # From exponential to smoothed

200 天平滑移动平均线的欧元兑美元每日时间范围。

线性加权移动平均

这是一个简单的移动平均线,更重视最近的数据。最近的观察值具有最大的权重,并且在它之前的每个观察值具有逐渐减小的权重。直觉上,它比其他移动平均线有更少的滞后,但它也是最少使用的,因此,它在滞后减少方面的收益,失去了受欢迎的程度。

从数学上来说,它可以写成:

在 python 语言中,我们可以定义一个计算移动平均值的函数,如下所示:

def lwma(Data, period): weighted = [] for i in range(len(Data)):
            try:
                total = np.arange(1, period + 1, 1) # weight matrix

                matrix = Data[i - period + 1: i + 1, 3:4]
                matrix = np.ndarray.flatten(matrix)
                matrix = total * matrix # multiplication
                wma = (matrix.sum()) / (total.sum()) # WMA
                weighted = np.append(weighted, wma) # add to array except ValueError:
                pass return weighted

200 天加权移动平均线的欧元兑美元每日时间范围。

基本上,如果我们有一个由两个数字[1,2]组成的数据集,并且我们想要计算一个线性加权平均值,那么我们将执行以下操作:

  • (2 x 2) + (1 x 1) = 5
  • 5 / 3 = 1.66

这假设数字为 2 的时间序列是最近的观察结果。

如果你也对更多的技术指标和使用 Python 创建策略感兴趣,那么我关于技术指标的畅销书可能会让你感兴趣:

[## Python 中的新技术指标

亚马逊网站:Python 中的新技术指标(9798711128861): Kaabar,Sofien 先生:书籍

www.amazon.com](https://www.amazon.com/gp/product/B08WZL1PNL/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B08WZL1PNL&linkCode=as2&tag=sofien-20&linkId=e3cb9716bb6a07cf6c8b9fb585412b07)

结论

那么,选哪个呢?这个问题留给交易者的风险状况和她对均线的熟悉程度。一些人更喜欢简单的移动平均线,而另一些人试图通过使用指数和平滑移动平均线的组合来深入研究。找到你最喜欢的一个完全取决于你。我的建议?考虑长期移动平均线。

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

https://pix abay . com/photos/trading-analysis-forex-chart-643722/

如何在 Java 中编写继承代码——面向对象的初学者教程

原文:https://towardsdatascience.com/how-to-code-inheritance-in-java-beginners-tutorial-in-oop-d0fc0a71be98?source=collection_archive---------19-----------------------

面向对象编程

让我们来理解面向对象编程中“继承”的概念

亨利&公司Unsplash 上拍摄的照片

韦氏在线词典将遗传定义为从过去几代人那里获得一种财产、条件或特征。面向对象设计中继承有相似(不完全相同)的内涵。继承意味着

  1. 以层次结构组织班级
  2. 较高层次从较低层次继承属性
  3. 把相似的东西归入同一类
  4. 等级越高,等级就从一般到特殊

层次结构看起来如何|由像素完美制作的图标来自www.flaticon.com

这意味着最基本的类,也称为基类,将是最通用的一个。它也被称为父类或超类。例如,“电子产品”是基类,它的子类将是“手机”或“音响系统”。

要了解更多关于构造类的基础知识,关于字段、方法和构造函数的细节,你可以参考这篇文章。

使用数学符号,手机是电子设备的子集,但却是固定电话的超集。级别之间的对应关系通常被称为 “是”关系 ,即电话是电子产品,座机是电话

是/是的层次关系

随着我们在等级中的地位越来越高,我们变得越来越具体。

等级和一般性

这种分层设计非常有用,因为它促进了代码的重用。共同的功能可以归入同一个类别,而不同的行为可以形成特定的情况或子类。

用专业术语来说,我们说子类 扩展了超类 。当使用继承时,子类自动从超类继承所有的方法(除了构造函数)。子类通过以下两种方法将其自身与其超类区分开来。

  1. 它可以 通过添加新字段和新方法来扩充 超类。
  2. 通过提供现有方法的新实现来覆盖 现有行为。

类—一组相似的对象
字段—类的属性
对象—类的实例
方法—可应用于对象的操作
构造函数—用于创建对象的操作

理论够了。我们来编码吧!

作为一个更简单的例子,让我们考虑下面的层次。图书作为基类,电子书和纸质书作为 2 个子类。

[图标来源](http://Icons made by Pixel perfect from www.flaticon.com)

  • 图书字段 —作者姓名、成本价、售价、书名和页数
  • 记账方法 —净利润()和 getTax()
  • 电子书字段 —下载网站和大小 MB
  • 电子书方法 — pageSize(),printTitle()和 getTax()

请注意,书籍字段是每本书都必须具有的属性。因为电子书将从 book 类继承,所以它将拥有 book 类的字段以及它自己的 2 个字段。

现在要注意的是,ebook 不仅可以访问 book 类的两个方法,即 netProfit()和 getTax(),而且还可以修改它们。请注意下面代码中对税收计算的修改。在下面的代码中,注意 EBook 是如何通过使用关键字 extends 来继承 Book 的。

  • 增强 — EBook 类通过添加字段 downloadSite 和 sizeMB 以及添加方法 pageSize()来增强 Book 类。注意,downloadSite 与纸质书无关,所以不能放在 Book 类中。此外,pageSize()是以 MBs 为单位测量的,因此它只适用于电子书。
  • 撤销— 除了 30%的利润税之外,电子书还要额外支付 2 美元的税。在这里,我们可以看到 EBook 类覆盖了原始的 getTax()方法,在原始税收计算的基础上增加了固定的 2 美元费用。

我们在上一篇文章中看到,当程序运行时,它是实际运行的主方法。因为我们在上面的两个类中没有包含任何 main 方法,所以我们将创建一个单独的测试文件来编写 main 方法并运行这两个类。

testbook 类的输出清楚地显示了继承的作用。我们甚至可以在电子书上打印图书类的字段。

注意事项

  • 继承通过使用关键字扩展来工作
  • 构造函数永远不会被继承,只有字段和方法会被继承
  • 即使一个类定义没有显式使用 extends 子句,它也会自动继承一个类, java.lang.Object ,它是 java 中的通用超类
  • 在 Java 中,使用关键字 super 调用超类的构造函数

看看 super()函数——它调用了超类的构造函数

完整的代码在这个 git repo 里。

如何从头开始编写线性回归代码

原文:https://towardsdatascience.com/how-to-code-linear-regression-from-scratch-9055a672eae0?source=collection_archive---------48-----------------------

基于正规方程的数值实现

样本线性回归拟合(图片由作者提供)

如今,很容易用一个或另一个库来适应你能想到的几乎任何模型,但是通过调用你能真正学到多少。fit()和。预测()?虽然使用像 python 的 statsmodels 或 scikit-learn 这样的框架对于正常用例来说肯定更实用,但在学习数据科学时,了解这些模型实际上是如何工作的也同样合乎逻辑。下面我们展示如何使用 numpy 从头开始实现一个基本的线性回归模型。我们开始吧!

这都是系数的问题

回想一下你的第一堂代数课:你还记得直线方程吗?如果你说“y = mx + b”,那你绝对是对的。我认为从二维开始也是有帮助的,因为不使用任何矩阵或向量,我们已经可以看到,给定输入 x 和输出 y,我们实际上寻找的不是一个,而是两个系数:m 和 b。

“但是等等!”你可能会说。这是斜率 m,截距 b,你又对了!但是为了找到最符合我们数据的线,我们不仅需要斜率,还需要截距,否则我们将会看到无限多条最佳拟合线,而不仅仅是我们要找的那一条。与其认为 b 被加到了 x 项上,不如将这个简单的等式改写为“y = mx + b1”。这使得下一点线性代数更容易理解。

关于矩阵和向量就足够了

让我们为我们的斜率截距方程设想一个非常简单的数据集,其中最佳拟合线实际上是完美的拟合。我们会说我们有要点:

(1, 3)

(2, 5)

(3, 7)

(4, 9)

我们想要求解系数 m 和 b,它们能最好地求解我们一会儿要定义的某个成本函数,但是为了更有效地完成这项工作,我们将首先再一次重写我们的方程。我们将定义一个向量 y = [3,5,7,9],我们将寻找一些系数(通常用θ,theta 或β,beta 表示)。我们的系数向量有多少个元素取决于我们的特征空间 X 中有多少个特征(注意,我们正在切换到大写的 X 来表示一个矩阵,我们现在将要讨论这个矩阵)。代替我们用来定义 y 项的向量,我们将在上面的 x 项列中增加一列 1。按照惯例,我们将在 X 值前面放置一列 1,因为您可以认为我们的常数系数比 X 的阶数低,看起来会像这样:

作者图片

现在我们的等式看起来像这样:

xθ=y

接下来我们要做的是使用一个小技巧,不是所有的矩阵代数都像你可能习惯的那样工作,但只要我们的维度兼容,在等式的两边乘以相同的项通常是公平的,这就是我们要做的。我们在两边加上 X 的转置,转置看起来像这样:

作者图片

我们的新方程可以写成这样:

(xᵀx)θ=xᵀy

这就是我们古怪操作的要点。这个方程叫做正规方程,它恰好有一些特殊的性质。 Wolfram 将这个方程定义为“使 Ax = b 的左右两边的平方距离之和最小化的方程”,虽然他们使用了一些不同的符号,但这正是我们要找的。

我们的最后一个技巧是分离θ,我们将通过取(XᵀX)的来完成,得到下面的等式,该等式将产生(XᵀX)可逆的所有情况下的解。我们将跳过一些细节,但是只要 X 的列是线性独立的,这应该是可行的。

θ=(xᵀx)⁻y

代码

这是我们用 Python 写的解决方案,请随意尝试!我认为这段代码的工作原理和 scikit-learn 的线性回归差不多。例如,它将在 Boston Housing 数据集上产生相同的结果,您可以使用sk learn . datasets . load _ Boston检索该数据集。你能想出一些它断裂的案例吗?(提示:查看上一节的最后一段)。

最后,对于那些想要一个简单方便的函数来测试该方法的输出与另一个库中的实现的人来说,可以随意使用它:

如何从头开始编写线性回归代码——快速而简单!

原文:https://towardsdatascience.com/how-to-code-linear-regression-from-scratch-quick-easy-cfd8c8f9eb9d?source=collection_archive---------57-----------------------

用不到 50 行 python 代码编写一个最流行的机器学习算法!

克莱姆·奥诺杰霍Unsplash 拍摄的照片

在本文中,我们将学习如何编写线性回归代码,即机器学习的“hello world”,在 python 的不到 50 行!数据科学家和程序员经常使用像 scikit-learn 这样的第三方库来整合机器学习算法,但却无法理解它们在幕后是如何工作的。

学习如何从头开始编写算法不仅会提高我们的编程能力,还会提供对当前主题的更深入的理解。

如果你需要了解什么是线性回归以及它是如何工作的,请随意查看我最近发表的直觉文章。话虽如此,让我们停止浪费时间,把我们的手弄脏吧!

建立

显然,我们从导入将要使用的库开始:

  • 我不知道你怎么想,但我肯定不想用普通的 python 来处理向量和矩阵数学
  • ***pandas*** Pandas 允许我们导入保存在同一目录下的 csv 数据
  • ***matplotlib***——这个库将帮助我们在本文后面可视化我们的算法

对于我们的初始数据集,我们将使用这个 kaggle 集合并基于某些特征来确定某样东西是否是巧克力!如果你打算继续下去,你应该这样做!),确保你 下载了。csv 并存储在你正在编码的同一个目录中。同样,请随意阅读 Kaggle 上的摘要,看看数据集中的每个要素代表什么。

正如承诺的,我们不会使用任何会使我们的旅程太容易的包装!那一点也不好玩。

数据

This dataset has 85 entries with 11 features 
The shape of X is: (85, 11) 
The shape of y is: (85, 1)

这里,我们使用熊猫将巧克力数据加载到我们的程序中;我们还删除了两个在计算中不使用的列: competitornamewinpercent

然后我们将数据分割成我们的 Xy 变量,分别代表我们的特征标签。我们的 y 成为数据集中的第一列,指示我们的特定甜食是巧克力( 1 )还是不是( 0 )。剩余的列用作变量/特征来预测我们的 y ,并因此成为我们的 X.

如果你对我们为什么在第 5 行使用…[:, 0][:,np.newaxis]感到困惑,这是为了将 y 变成一列。我们只需添加一个新的维度,将水平向量转换为垂直列!相信我,这将有助于以后的计算。

在第二个要点中,我们简单地看一下我们拥有的数据。正如所见,该块表示我们的数据集中有 85 个样本,每个样本具有 11 个特征。同样,我们的 X85 行和 11 列,我们的 y85 行和 1 列。

简单提醒一下,记住每一行代表一个单独的数据点,每一列是与之对应的一个特性。例如,我们在中有 85 个条目,其中一列表示该点是否为巧克力(1 或 0)* 。*

费用

这是我们模型的成本函数;我们选择了 (1/2) x 均方误差 来表示(第 5 行)。

  • **pred**代表通过将我们的特征(***X***)乘以我们的当前权重(***params***)并将它们相加而获得的预测
  • 然后,我们通过将预测值与预期值/正确值进行比较来计算总误差/成本(第 5 行)**

旁注:如果你不熟悉@命令,它只是点积(类似于np.dot)

梯度下降

考虑到成本,我们现在可以实现算法的核心:梯度下降。同样,如果你不熟悉梯度下降是如何工作的,或者需要一些补充,看看以前的文章!让我们看看代码在做什么:

  • **iterations** —我们将经历的梯度下降的迭代次数
  • **cost_history** —允许我们跟踪成本历史的数组;这将有助于我们可视化算法!

第 6 行*是梯度下降的核心,更新规则** (**learning_rate**/num_samples) * X.T @ (X @ params — y)代表代价函数相对于权重/参数偏导数。然后,我们取这个值,乘以我们的学习率(如前面粗体所示),并从我们的旧权重/参数值中减去它,以便更新它们!*

规范化和初始化

在我们把所有东西放在一起之前,我们必须规范化初始化我们的数据。

*规范化*是一种数据准备技术,它只是将数值重新调整为从 01 的数字。这样做是为了提高我们的准确性,同时降低我们的成本/误差。

旁注:如果你尝试实验,看看如果我们不正常化会发生什么,你会得到额外的荣誉!

如果你熟悉线性回归,你应该意识到现在还缺少一些东西:偏差项。事实证明,我们可以将偏差项添加到我们的特征矩阵 X 中。这就是你在第 9 行看到的:我们在我们的 X 前面堆叠一列 1,作为我们的偏置项。现在,我们不再只考虑 11 的初始特征,而是考虑 12 的偏差。很漂亮吧?

同样,我们也将我们的权重/* 参数 初始化为零(第 11 行)*

建立模型!

现在,是时候把所有的东西放在一起,整合我们之前做的功能了;让我们来看看当我们点击运行时会发生什么!

*Initial cost:  0.21764705882352942Optimal parameters are: 
[[ 0.43529399]
 [-0.26827445]
 [-0.03002024]
 [ 0.03246823]
 [-0.01615199]
 [ 0.03059432]
 [-0.01911575]
 [ 0.11609403]
 [-0.00797628]
 [ 0.01947274]
 [ 0.05175128]]Most important features determined by the algorithm: 
[('fruity', 0.43529399417329273), 
('caramel', -0.2682744491689681), 
('pluribus', 0.11609403084213005), 
('nougat', 0.032468233412292824), 
('hard', 0.03059432326508639), 
('peanutyalmondy', -0.03002024138032047), 
('pricepercent', 0.019472737570368572), 
('bar', -0.01911575068810122), 
('crispedricewafer', -0.016151994114632157), 
('sugarpercent', -0.00797628452755172)]Final cost:  0.04433152061220413*

然后,砰!我们做到了!正如您从输出中看到的,我们显著降低了成本,从 0.22 降至 0.04 。在上图中,您可以看到每次迭代的成本都在降低!

为了帮助进一步理解算法在做什么,我打印了最优权重。这表示对应于每个特征的权重,最终用于预测某物是否是巧克力。换句话说,如果我们有另一个看不见的数据点具有相同的特征,我们可以用这些权重乘以它的值,并确定它是否是巧克力!

同样,我也打印了一个最有影响力的功能的排序列表。这很有趣,因为你可以看到计算机认为什么是最重要的。不出所料,这表明味道是否是水果味是区分糖果和巧克力的一个很好的标准。第二名和第三名分别由焦糖pluribus 获得。Pluribus 只是一种指示,表明这种糖果是否是装在袋子或盒子里的许多糖果中的一种。

类实现

既然我们已经从零开始在不相交的部分中构建了线性回归,那么让我们把它们放在一起,稍微调整一下,并把它变成一个类!现在我们有了自己的线性回归模块:

战斗的时间到了!

好吧,没什么大不了的,我们从头开始做了一个线性回归实现。我们怎么知道它有多好?**

为什么不让我们班和 sklearn 的进行一场生死之战呢!让我们在他们自己的主场作战,使用他们的波士顿住房数据集,这样我们就可以为训练和测试集使用更多的数据样本!

 *Our's      Sklearn's
Training Acc.  0.724896   0.727084
Test Acc.      0.771918   0.772993*

我不知道你怎么想,但我认为保持精确度是一项相当可靠的工作!希望这能让你明白隐藏在引擎盖下的东西并不总是像看起来那么复杂。

我强烈建议您继续使用 battle and LinearRegression 类来试验不同的数据集,看看它能准确预测什么,另一方面,在这方面做得不太好。欢迎在下面的回复中链接或谈论你的结果和发现!

结论

克拉克·杨Unsplash 上的照片

希望你从零开始实现线性回归很有趣,因为我确实做到了!更重要的是,我真心希望你对线性回归的工作原理有更深的理解。

如果你对一些术语有点困惑,我强烈建议你去看看那篇用通俗的语言解释算法如何工作的文章

如果你想跟随一个完整解释的 jupyter 笔记本或者只是想在最后下载类,请随意查看 GitHub 库

我真诚地希望你喜欢阅读这篇文章,并希望很快见到你,这样我们就可以一起掌握 ML 和数据科学的世界!

如何用 NumPy 从头开始编写逻辑回归代码

原文:https://towardsdatascience.com/how-to-code-logistic-regression-from-scratch-with-numpy-d33c46d08b7f?source=collection_archive---------25-----------------------

学习逻辑回归的同时提高你的数字技能

作者图片

我们在 NumPy 中实现逻辑回归的计划是什么?

让我们首先考虑我们想要使用的底层数学。

有许多方法来定义一个损失函数,然后为它找到最佳参数,其中,这里我们将在我们的LogisticRegression类中实现以下 3 种学习参数的方法:

  • 我们将重写逻辑回归方程,以便将其转化为具有不同标签的最小二乘线性回归问题,然后,我们使用封闭形式的公式来寻找权重:

  • 如上所述,我们将逻辑回归转换为最小二乘线性回归,但我们使用具有以下梯度的随机梯度下降,而不是封闭形式的公式:

  • 我们使用最大似然估计(MLE)方法,编写似然函数,对其进行处理,将其重新表述为最小化问题,并应用具有以下梯度的 SGD:

在上述等式中,X 是包含行轴上的观察值和列轴上的特征的输入矩阵;y 是包含分类标签(0 或 1)的列向量;f 是误差平方和损失函数;h 是最大似然法的损失函数。

要了解以上方法的更多信息,请查阅本文:

[## 理解逻辑回归

这种方法的数学详细解释

towardsdatascience.com](/understanding-logistic-regression-81779525d5c6)

所以,这是我们的目标:把上面的方程翻译成代码。为此我们将使用 NumPy。

我们计划使用面向对象的方法来实现。我们将用 3 个公共方法创建一个LogisticRegression类:fit()predict()accuracy()

在 fit 的参数中,有一个将决定我们的模型如何学习。这个参数被命名为 method(不要与作为类的函数的方法相混淆),它可以将下列字符串作为值:“ols _ solve”(OLS 代表普通最小二乘法)、“ols_sgd”和“mle_sgd”。

为了不使fit()方法太长,我们想将代码分成 3 个不同的私有方法,每个方法负责一种寻找参数的方法。

我们将使用__ols_solve()私有方法来应用封闭公式。

在这种方法和其他使用 OLS 方法的方法中,我们将使用常量 EPS 来确保标签不完全是 0 或 1,而是介于两者之间。这是为了避免在上面的等式中对数的正负无穷大。

__ols_solve()中,我们首先检查 X 是否有完整的列秩,以便我们可以应用这个方法。然后我们强制 y 在 EPS 和 1-EPS 之间。ols_y变量保存普通最小二乘线性回归问题的标签,该问题等价于我们的逻辑回归问题。基本上,我们转换了逻辑回归的标签,使它们符合线性回归方程。之后,我们使用 NumPy 函数应用封闭形式的公式。

对于 2 个基于 SGD 的算法,将它们作为 2 个独立的方法是多余的,因为除了计算梯度的部分,它们几乎所有的代码都相同,因为它们有 2 个不同的梯度公式。

我们要做的是创建一个通用的__sgd()方法,它不依赖于计算梯度的特定方式。相反,它将期望一个函数作为参数,负责计算__sgd()方法将使用的梯度。

在此方法中,我们首先将权重初始化为一个随机列向量,其值取自均值为 0、标准差为 1/(要素数)的正态分布。这个标准差的直觉是,如果我们有更多的特征,那么我们需要更小的权重来收敛(并且不破坏我们的梯度)。然后我们检查所有的数据集,看是否有iterations次。在每次这样的迭代开始时,我们随机打乱数据集,然后对于每批数据,我们计算梯度并更新权重。

对于“ols_sgd”和“mle_sgd ”,我们将创建两个私有方法:__sse_grad()__mle_grad(),它们计算并返回这两种不同技术的梯度。

对于这两种方法,我们使用 NumPy 简单地应用∇f 和∇h 的公式。

所以,当fit()method=‘ols_solve’调用时我们叫__ols_solve(),当method=‘ols_sgd’grad_fn=self.__sse_grad调用__sgd(),当method=’mle_sgd’grad_fn=self.__mle_grad调用__sgd()

predict()中,我们首先通过寻找权重属性(fit 方法是创建它的唯一方法)来检查fit()是否被调用过。然后我们检查输入矩阵 x 和权重向量的形状是否允许相乘。否则,返回错误消息。如果一切正常,我们做乘法,并通过逻辑函数传递结果。

accuracy()中,我们使用上述方法进行预测。然后检查预测的形状是否与真实标签的形状相匹配,否则,我们会显示一条错误消息。之后,我们通过一个简单的规则来确保预测和真实标签的值都是 0 或 1:如果值是> = 0.5,则认为它是 1,否则为 0。

为了计算精度,我们检查 y 和 y_hat 之间是否相等。这将返回一个布尔值向量。然后将这些布尔值强制转换为 float (False 变为 0.0,True 变为 1.0)。那么,精度就是这些值的平均值。

下面是LogisticRegression类的完整代码:

现在,我们想用一些真实世界的数据来测试我们的LogisticRegression类。为此,我们将使用来自 Kaggle 的心脏病数据集。你可以在 Kaggle 上阅读关于这个数据集的更多信息,但主要思想是根据其他数据预测“目标”列(如果健康,则为 0,如果有心脏病,则为 1)。

下面的代码展示了我们的LogisticRegression类的作用(为了避免重复,下面没有显示单元格 1&2;如上面的代码片段所示)。

正如你所看到的,我们能够在训练和测试中获得相当不错的 80%+ 的准确率。

你可以在 Kaggle 上看到完整的笔记本。

我希望这些信息对您有用,感谢您的阅读!

这篇文章也贴在我自己的网站这里。随便看看吧!

如何与 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 都包含一个不断变化的值:

了解这一点后,我们可以创建一个简单的 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/文章-演练

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

如何将 Jupyter 笔记本连接到远程 spark 集群,每天运行 spark 作业?

原文:https://towardsdatascience.com/how-to-connect-jupyter-notebook-to-remote-spark-clusters-and-run-spark-jobs-every-day-2c5a0c1b61df?source=collection_archive---------8-----------------------

作为一名数据科学家,您正在开发笔记本电脑,用于处理不适合使用 Spark 的笔记本电脑的大量数据。你会怎么做?这不是一个微不足道的问题。

让我们从最简单的解决方案开始,不用在你的笔记本电脑上安装任何东西。

  1. “无笔记本”:SSH 进入远程集群,并在远程集群上使用 Spark shell。
  2. “本地笔记本”:对数据进行下采样,并将数据提取到您的笔记本电脑中。

“没有笔记本”的问题是开发者体验在 Spark shell 上是不可接受的:

  1. 你不能像在 Jupyter 笔记本或 Zeppelin 笔记本上那样轻易地修改代码并打印出结果。
  2. 很难显示 Shell 中的图像/图表。
  3. 在远程机器上用 git 进行版本控制是很痛苦的,因为你必须从头开始设置,并像 git diff 一样进行 git 操作。

火花壳截图

第二个选项“本地笔记本”:您必须对数据进行下采样,并将数据拖到您的笔记本电脑上(下采样:如果您的集群上有 100GB 的数据,您可以将数据下采样到 1GB,而不会丢失太多重要信息)。然后你可以在本地的 Jupyter 笔记本上处理数据。

它产生了一些新的令人痛苦的问题:

  1. 您必须编写额外的代码来缩减数据采样。
  2. 缩减采样可能会丢失有关数据的重要信息,尤其是在处理可视化模型或机器学习模型时。
  3. 你必须花费额外的时间来确保你的代码为原始数据。如果没有,就要花额外的时间来找出问题所在。
  4. 您必须保证本地开发环境与远程集群相同。否则,它很容易出错,并可能导致难以检测的数据问题。

好吧,“无笔记本”和“本地笔记本”显然不是最好的做法。如果您的数据团队可以访问云,例如 AWS,会怎么样?是的,AWS 在其 EMR 集群和 SageMaker 上提供 Jupyter 笔记本。笔记本服务器通过 AWS Web 控制台进行访问,当集群准备就绪时,它就可以使用了。

这种方法被称为“云上远程笔记本”。

AWS EMR 和由 AWS 提供的 Jupyter 笔记本电脑

“云上的远程笔记本电脑”的问题有

  1. 每次集群开始运转时,您都必须设置您的开发环境。
  2. 如果你想让你的笔记本运行在不同的集群或区域,你必须手动&重复地完成。
  3. 如果集群意外终止,您将丢失在这些集群上所做的工作。

具有讽刺意味的是,这种方法是可以访问 AWS 的数据科学家中最受欢迎的方法。这可以用最省力的原理来解释:它提供了对远程集群的一键式访问,以便数据科学家可以专注于他们的机器学习模型、可视化和业务影响,而无需在集群上花费太多时间。

除了“无笔记本”、“本地笔记本”和“云上的远程笔记本”,还有将笔记本电脑上的 spark 指向远程 spark 集群的选项。代码通过本地笔记本提交,并发送到远程 spark 集群。这种方法被称为“桥接本地和远程火花”。

创建 sparkSession 时,可以使用 set remote master

val spark = SparkSession.builder()
.appName(“SparkSample”)
.master(“spark://123.456.789:7077”)
.getOrCreate()

这些问题是

  1. 你必须找出如何认证你的笔记本电脑远程火花集群。
  2. 仅当 Spark 作为独立部署而不是 YARN 部署时,它才有效。如果您的 spark 集群部署在 YARN 上,那么您必须将远程集群上的配置文件/etc/hadoop/conf复制到您的笔记本电脑上,并重启您的本地 spark,假设您已经知道如何在您的笔记本电脑上安装 Spark。

如果您有多个 spark 集群,那么您必须通过复制配置文件来来回切换。如果集群在云上是短暂的,那么它很容易变成一场噩梦。

“桥接本地和远程火花”对大多数数据科学家来说并不奏效。幸运的是,我们可以把注意力转回到 Jupyter 笔记本上。有一个名为“Sparkmagic”的 Jupyter 笔记本内核,它可以将您的代码发送到远程集群,假设 Livy 安装在远程 spark 集群上。这一假设适用于所有云提供商,在 Apache Ambari 的帮助下,在内部 spark 集群上安装并不困难。

火花魔法建筑

看起来“火花魔法”是目前最好的解决方案,但为什么它不是最受欢迎的。有两个原因:

  1. 很多数据科学家都没有听说过“Sparkmagic”。
  2. 数据科学家很难解决安装、连接和认证问题。

为了解决问题 2,sparkmagic 推出了随时可用的 Docker 容器。Docker 容器确实解决了安装中的一些问题,但它也给数据科学家带来了新的问题:

  1. docker 容器是为航运应用程序设计的,它的学习曲线对数据科学家来说并不友好。
  2. 它不是为来自不同技术背景的数据科学家直观使用而设计的。

关于 docker 容器的讨论就到此为止,另一篇解释如何让 Docker 容器真正为数据科学家工作的文章将在几天后发表。

总而言之,我们有两类解决方案:

  1. 笔记本&笔记本内核:“无笔记本”、“本地笔记本”、“云上远程笔记本”、“Sparkmagic”
  2. Spark 本身:“连接本地和远程 spark”。

尽管存在安装和连接问题,“Sparkmagic”仍是推荐的解决方案。然而,通常还有其他未解决的问题会降低生产率并损害开发人员的体验:

  1. 如果需要其他语言 python 和 R 在集群上运行呢?
  2. 如果笔记本要每天运行会怎样?如果只有在另一台笔记本运行成功时才运行该笔记本,该怎么办?

让我们回顾一下当前的解决方案:

  1. 设置远程 Jupyter 服务器和 SSH 隧道(Rreference)。这肯定是可行的,但设置起来需要时间,而且笔记本电脑都在远程服务器上。
  2. 设置 cron 调度程序。大多数数据科学家都接受 cron scheduler,但是如果笔记本无法运行呢?是的,shell 脚本会有所帮助,但是大多数数据科学家都愿意编写 shell 脚本吗?即使答案是肯定的,数据科学家也不得不 1。访问已完成的笔记本 2。获取状态更新。即使有数据科学家乐于编写 shell 脚本,为什么每个数据科学家都要编写自己的脚本来自动化完全相同的东西呢?
  3. 设置气流。这是一个在数据工程师中非常受欢迎的解决方案,它可以完成工作。如果有数据工程师或数据平台工程师支持的 Airflow 服务器,数据科学家可以设法学习 Airflow 的操作人员,并让它为 Jupyter Notebook 工作。
  4. 设置 Kubeflow 和其他基于 Kubernetes 的解决方案。诚然,kubeflow 可以完成工作,但实际上有多少数据科学家可以访问 Kubernetes 集群,包括运行在云上的托管解决方案?

让我们重新定义这些问题:

  1. 如何在能够访问远程集群的本地笔记本电脑上进行开发?
  2. 如何在远程集群上操作?

Bayesnote 实施的解决方案可以在 5 分钟内完成所有工作。Bayesnote 是用于 Jupyter 笔记本的笔记本编排平台:

  • 在 5 分钟内协调不同集群上的笔记本电脑
  • 一键访问远程 Jupyter 笔记本电脑
  • 运行具有依赖性的 Jupyter 笔记本,然后重试
  • 一键查看输出笔记本

那儿有

  • 没有学习曲线。不需要学习抽象概念,也不需要 docker/Kubernetes 知识。
  • 无运营成本。没有额外的数据库安装,没有端口打开。它可以毫无困难地将自己安装到集群中。

Bayesnote

教程可以在 https://github.com/Bayesnote/Bayesnote找到

如何将 Python 连接到 Google Cloud 的文本到语音转换

原文:https://towardsdatascience.com/how-to-connect-python-to-google-clouds-text-to-speech-d918dc6a393b?source=collection_archive---------20-----------------------

布雷特·乔丹在 Unsplash 上的照片

所以你可能想知道谷歌云的文本到语音和其他文本到语音有什么不同。首先,由于人工智能的力量(这些被称为 wavenet voices),它可以将文本转换为听起来更自然的语音。

所以我实际上遇到了这项技术,因为我想在 YouTube 上制作教学视频。自从在家工作发生后,我一直无法创造一个可以创作画外音的空间。最棒的是它附带的免费层,所以任何人都可以尝试这段代码!

如果你想继续下去,谷歌 Colab 笔记本的副本可以在这里找到。

设置

没有任何进一步的犹豫,让我们继续前进,并开始设置它。我们要做的第一件事是登录我们的谷歌账户,然后进入谷歌云的文本到语音转换 API 。我们现在要通过单击“enable”来激活它。它会要求你付费,但不要担心,除非你超过免费层,否则它不会向你收费。

因为我是在 Google Colab 笔记本上运行的,所以您需要创建一个服务帐户并下载一个 JSON 密钥文件。这样做的指令将位于这里。我现在把 JSON 文件放在我的 Google Drive 中。请记住,我希望这完全在线。所以我想运行的第一部分代码是连接到 Google Drive。

from google.colab import drivedrive.mount('/content/drive')

一旦我连接到驱动器,我现在想找到那个 JSON 文件。我创建了一个名为 text2speech 的文件夹,放在那里。这是我们进行身份验证所需要的。

import osos.environ['GOOGLE_APPLICATION_CREDENTIALS'] = '/content/drive/My Drive/text2speech project/My Project-e0a97add923c.json'!echo $GOOGLE_APPLICATION_CREDENTIALS

我们现在想安装谷歌云文本到语音库。我们可以通过在代码块中运行 pip 安装来实现这一点。

pip install --upgrade google-cloud-texttospeech

所以谷歌云的文本到语音转换很酷的一点是我们可以定制它。从音高到音调,甚至翻译语言。点击查看语音演示。我勉强接受了Wavenet J的男声。既然我们已经选好了声音,剩下的就容易了。我们只需设置它并发送文本。我们将为此创建一个函数,它将文本输出到 mp3 文件。

def synthesize_text(text):"""Synthesizes speech from the input string of text."""from google.cloud import texttospeechclient = texttospeech.TextToSpeechClient()input_text = texttospeech.SynthesisInput(text=text)# Note: the voice can also be specified by name.# Names of voices can be retrieved with client.list_voices().voice = texttospeech.VoiceSelectionParams(language_code="en-US",name="en-US-Wavenet-J",ssml_gender=texttospeech.SsmlVoiceGender.MALE,)audio_config = texttospeech.AudioConfig(audio_encoding=texttospeech.AudioEncoding.MP3)response = client.synthesize_speech(request={"input": input_text, "voice": voice, "audio_config": audio_config})# The response's audio_content is binary.with open("output.mp3", "wb") as out:out.write(response.audio_content)print('Audio content written to file "output.mp3"')

非常容易。我们现在将向该函数发送一个文本字符串。这是文本字符串。

text = "Hello! My name is Wavenet J and I am running on Google Cloud's Text To Speech! Nice to meet you and thank you for reading my friend's article!"

现在我们把所有东西都装满了,准备好了。

mp3file = synthesize_text(text)

现在在最左边,我们想选择文件夹图标,现在可以下载我们的 mp3 文件,并听取一个舒缓的人工智能的声音!

结论

我向目前正在使用语音的人推荐这种方法。即使是从事自然语言处理的人。此外,如果你是一名教师,这将是一个完美的方式把讲座视频格式。这也很神奇,因为你可以翻译讲座和任何其他文本!

我是如何让学习数据变得有趣的!

原文:https://towardsdatascience.com/how-to-construct-a-bar-chart-that-looks-like-a-fork-8163c35536e2?source=collection_archive---------64-----------------------

那是叉子还是条形图?为什么不两者都要?!

当你想到你在教授数据可视化的研讨会、视频和网站上看到的数据例子时,你会想到什么主题?销售,利润,计算部件……唉。无意义、枯燥、枯燥的数据。我们肯定能做得更好?

为什么这么严肃?

为普通观众设计学习练习意味着你需要找到每个人都能理解的数据。这可能很棘手,我明白了——金融方面的例子很有意义——每个人都知道钱和买东西,金融听起来对培训课程来说足够公司化了。但是我真的在乎西北区销量比南方多吗?不。这门课的其他人也不知道。我们什么时候再吃午饭?

相比之下,任何看过汉斯·罗斯林展示数据的人都会同意,即使是最严肃的数据也能以鼓舞人心、引人入胜的方式展示。现在我并不是建议数据可视化培训应该像汉斯展示他的材料一样以同样的兴趣和热情来展示,没有人能持续 8 个小时!

但是我们如何找到教授数据技能的中间地带呢?我们是否有足够的勇气以一种不把自己看得太重的方式教授严肃的技能?我们可以!

数据技能是严肃的,但是学习它并不否定乐趣!

以学习仪表板设计为例。我可能想教授的常见技能和技术包括:

  • 比较数字(条形图)和整体部分(饼图或圆环图)的良好图表选择
  • 通过直接标注数据而不是使用图例来减少混乱
  • 有目的地使用颜色,例如用于不同图表中的共同元素

我可以使用以下简单的仪表板来演示这些内容:

运筹学

我可以用这个来做:

在每种情况下都需要同样的技能。两个仪表板展示了相同的关键数据可视化概念。但是制作一个更有趣!当你的同事问你在昨天的课程中学到了什么时,你更容易想起这些。

是的,我们可以坚持公司的颜色、严肃的展示风格,以及让首席财务官满意的东西。但是这有什么意思呢?把这些留到明天,当你在日常工作中运用新技能的时候。今天让我们享受自由吧!

所以,我们来学习一下如何做一个叉形条形图吧!

我在培训课程中使用这个练习作为我的基本条形图的补充练习。它旨在为已经在定期创建条形图或只想从数据中获得乐趣的学员增加一些新的技能。我通常不会像下面这样提供解决方案或步骤,因为我也喜欢把它作为创建可重用设计的一课。这使得这个练习更具挑战性!

如果你想挑战自己——不要继续读下去,现在就停下来,试着创建图表。不要使用任何文本框或形状(除了刀或叉子的手柄)。您应该能够自动更新类别名称或值和图形更新!然后回来看看你的解决方案是否和我的相似。 ]

让我们从构建一个基本条形图开始:

现在我想把条形的顶部做成圆形,但是如果只是使用圆形,当数据改变时它们不会移动。相反,我可以在图表上创建第二个系列,使用相同的数据,并用圆形标记绘制成折线图。

首先,通过单击条形复制图表系列,按 Ctrl-C,然后按 Ctrl-V。

然后,我可以通过右键单击第二个系列来更改其图表类型,选择“更改系列图表类型”:

对于第二个系列的图表类型,您需要选择“带标记线”并取消选中“次坐标轴”复选框。

现在让我们改进造型。单击条形,使用“格式化数据系列”面板将条形间距缩小到 50%。

在我们对折线图进行样式化之前,我们需要将整个图表区域重新调整到它的最终纵横比。当我们在这,让我们删除网格线,两个轴和边界。

我们快到了。现在调整折线图样式。使用“格式化数据系列”面板将标记类型更改为“内置”,选择一个圆形并调整标记大小,直到它与条形宽度匹配。当你在那里的时候,不要忘记移除连接线。

功能元素的最后一步是添加数据标签。我们可以利用我们有两个数据系列的事实来添加两组标签。我们将向圆圈添加标准数据标签,将标签放置在圆点上方:

对于类别标签,我们将使用类别名称作为条形图的数据标签,并将它们放置在“内部基准”处。

要将它们转向侧面,我们将单击此面板的对齐部分,并将文本方向更改为“将所有文本旋转 270 度”:

最后一些颜色和字体的调整:

请记住,您可以通过单击两次来改变单个数据点的颜色,第一次单击会选择整个系列,第二次单击只会隔离该数据点。您会注意到,只有该数据点被突出显示:

最后一步,添加形状来创建叉子的手柄。这里我展示了我在最终设计中使用的蓝色边框和间隔,然后重叠的形状:

就是这样。一个完全可重复使用的 12 步叉形条形图!谁知道 Excel 能做到这一点!

如何利用贝叶斯定理更智能地消费新闻

原文:https://towardsdatascience.com/how-to-consume-news-more-intelligently-using-bayes-theorem-a3273d0fff5e?source=collection_archive---------33-----------------------

基础利率、边际概率、敏感性和特异性

马库斯·斯皮斯克在 Unsplash 上的照片

当谈到在不确定的情况下更新信念和做出决策时,贝叶斯定理几乎是可用的最佳工具。然而,当它应该为我们的日常生活带来价值时,它却经常被归入学术教科书和机器学习应用程序。

这篇文章是写给那些熟悉贝叶斯定理,但在阅读诸如“红酒降低痴呆症风险”这样的标题时,可能难以记住哪些术语出现在哪里,并且不会立即想到它的人的。

首先,我将回顾贝叶斯定理,谈谈为什么我认为在确实不应该记住的时候很难记住,并根据敏感性和特异性(我将定义它)来阐述它。接下来,我将讨论几种使用该公式对新闻中经常出现的挑衅性言论做出适当反应的方法。最后,我将留给你一些关于在日常生活中使用贝叶斯定理的注意事项,以及其他最后的想法。

关键要点如下。我将定义所有出现的术语:

  1. 贝叶斯定理告诉我们,在给定一些新的条件下,如何修正一些结果的概率估计。在日常生活中,当有更多证据时,它可以简单地更新我们的信念,或者确定某个结果(如癌症)是否更有可能在某种情况下(如吸烟)出现。
  2. 你需要三条信息来正确更新你对结果的信念:结果的基本比率,证据的敏感性和特异性。新闻往往只会给你敏感。
  3. 在缺乏所有三条信息的情况下,尝试自己填补空白,并警惕极端(高/低)基本利率或证据的高边际概率的情况。

敏感性和特异性方面的贝叶斯定理

贝叶斯定理告诉我们,在给定新证据的情况下,如何计算结果的后验概率。这被表示为 P(A|B)形式的条件概率。

当公式被表示为一堆混乱的字母时,很容易把它们弄混,忘记分子和分母分别是什么。由于这个原因,我喜欢用结果和条件来写。

从数学上来说,没有理由把一个事件称为“结果”,而把另一个事件称为“条件”。但在现实生活中,有些事情我们想知道却无法直接测量——比如,你得癌症的概率。这将是一个结果。像医学诊断结果这样的证据是用来估计这种结果概率的条件。

p(结果)是我们感兴趣的事情的已知的先验概率基本概率。这是有道理的,它将与我们更新的概率成比例,因为否则,我们将在每次遇到新证据时翻转我们的信念。

p(条件)称为条件的边际概率,把它看作一个实体可能有点奇怪。它是在结果为真和不为真的两个世界中,观察到我们所观察到的条件或证据的总概率。

现在,我想再介绍两个术语:敏感性和特异性。假设你读到 70%的医学生弹钢琴。也就是说,弹钢琴作为学医的证据,其敏感度为 70%。

但是,是否是钢琴演奏者肯定不是一个人是否是医科学生的有力指标。其中一个原因是它的低特异性。也就是说,很多不是医学生的人也会弹钢琴。

为了使一个条件强烈地影响结果的概率,它必须同时具有高敏感性和高特异性。此外,为了得出一个后验概率估计,除了证据的敏感性和特异性,我们还必须对结果的基本比率有一个概念。下面是贝叶斯公式的改写,与这些直觉一致:

我发现新闻文章通常不会提供所有必要的细节来得出一个完全基于数据的观点。贝叶斯定理告诉我们调整信念的数量往往是反直觉的,尤其是在处理罕见事件时。在下一节中,我将描述如何避免对类似“90%的新冠肺炎病例发生在穿有鞋带的鞋子的人身上”的陈述反应过度

需要注意的场景

同样,计算结果的后验概率需要三条信息:结果的基础率、条件的敏感性和条件的特异性。特别是,如果敏感性或特异性没有什么特别的(~0.5),那么这就是后验概率不会与基础概率有太大差异的标志。在这种情况下,假设你当前的行为是基于你的信念,你可能不需要调整你正在做的事情来解释新的数据。

但是当新闻只提供一两条的时候,你该怎么办?好吧,你的选择是:

  1. 承认你不能有意义地吸收新数据,忽略它。
  2. 估计缺失的部分。

虽然有些情况下你真的无法估计缺失的部分,但是过分依赖这个选项是很危险的。我发现,敏感性通常是新闻中提供的信息,而基本利率和边际概率(以及特异性)可以毫不费力地找到。

在这种情况下,每当我的估计出现低基本利率、高边际概率或高基本利率时,我都学会了保持警惕。让我们使用虚构的例子依次检查每种情况。

低基本利率

" 90%有天才级智商孩子的母亲报告说在怀孕期间吃贝类."

在像上面例子这样的情况下,我们感兴趣的结果(有一个天才水平智商的孩子)是非常罕见的。这意味着,除非我们测试的条件在灵敏度和特异性方面非常精确(如果没有在科学杂志上直接报道,可能就不是这样),否则我们的后验概率也可能非常低。

高边际概率

"几乎每个寻求抑郁症咨询的美国大学生都拥有一部智能手机."

就像拥有带鞋带的鞋子一样,除了抑郁症咨询,拥有一部智能手机现在已经很普遍了。换句话说,拥有智能手机的边际概率很高。这可能是疾病特异性低的警告信号。

换句话说,我们可以假设几乎每一个没有寻求抑郁症咨询的大学生拥有一部智能手机,这意味着拥有一部智能手机本身并不是一个学生将寻求咨询的强有力指标。

高基本利率

“95%坐过飞机的人在 100 岁之前就去世了。”

在你读到这样的文章并决定你的飞行时代结束之前,考虑一下在 100 岁之前死亡已经很普遍了。在第 100 次旋转之前死亡的后验概率有可能比基本概率低。无论如何,后路可能不会有足够的不同来保证生活方式的改变。

警告和结论

我希望我已经设法提供了另一个角度来看待贝叶斯定理,这将使它在日常生活中更直观和更容易使用。但是权力越大,责任越大,所以要注意以下几点。

  • 即使你确定一些新的信息不足以调整你的信念来改变你的行为,那也不等于它根本没有调整你的信念。如果越来越多的证据指向同一件事,最终会改变你的整体观点。忘记每一个证据并回复到你之前的状态对你没有好处,因为你认为它是不充分的。
  • 再次提醒,不要断然拒绝新闻,因为它没有明确提供运行贝叶斯法则所需的所有要素。如果你只对你不喜欢的新闻应用这样的过滤器,这就有导致动机怀疑的风险。
  • 虽然在我上面的例子中,我直接做出了敏感性声明,但标题通常会直接对结果做出声明(例如,“智能手机增加了抑郁症的可能性”),但随后只报告了证据在体内的敏感性。看过去这样的标题,找到数字。

记住这几点,你应该准备好以一种更有分寸和数据意识的方式对你遇到的信息做出反应。干杯!

附注轶事证据在这个框架内仍然毫无价值。

如何将 Spark 中训练的模型容器化:MLLib、ONNX 等等

原文:https://towardsdatascience.com/how-to-containerize-models-trained-in-spark-f7ed9265f5c9?source=collection_archive---------21-----------------------

将 ML 运送到生产部门

以经济高效的方式包装 Spark 模型的替代方案

如果我们要说出现代应用中的两个趋势,其中一个应该提到容器机器学习。越来越多的应用程序正在利用容器化的微服务架构来提高弹性、容错能力和可扩展性,无论是在内部还是在云中。同时,机器学习越来越成为任何应用的基本要求。

然而,这两件事并不总是能和谐相处,Spark 就是这种情况。通过使用 Cloudera、Azure Databricks、AWS EMR 或任何其他工具,Spark 现在已经成为大数据分析的行业事实标准。但是如果您想在集群之外的某个地方使用您在 Spark 中训练的模型呢?

您的选择,按菜单点菜

对此有几个选项:

  1. 如果您使用 TensorFlow、PyTorch、Scikit-Learn 等工具训练您的模型,那么您可以将您的模型打包成不同的可移植格式。因为这些框架并不直接依赖于 Spark,所以您可以开始了。我不会在这篇文章中谈论这个选项。
  2. 如果使用 MLLib (比如在 pyspark.ml.*)训练模型,那么可以将模型导出为可移植的格式,比如 ONNX ,然后使用 ONNX 运行时来运行模型。这有一些限制,因为不是所有的模型都支持 ONNX。
  3. 如果您使用 MLLib 训练您的模型,那么您可以通过创建一个无集群 Spark 上下文对象来持久化您的模型并从容器内部加载它。
  4. (2022 年 2 月更新)使用 MLFlow 持久化您的模型,并使用 MLModel 规范打包它。MLFlow 目前支持 Spark,它能够使用 MLModel 规范打包您的模型。您可以使用 MLFlow 将您的模型部署到任何您想要的地方。关于这个策略的更多细节请看我的帖子:使用 MLFlow 轻松部署。

ONNX 是机器学习模型的序列化和规范的开放标准。由于该格式描述了计算图(输入、输出和操作),所以它是独立的。它专注于深度学习,主要由微软和脸书倡导。在 TensorFlow 和 PyTorch 等许多框架中得到支持。

Spark 中的模型是如何工作的?

在 Spark 中,一个 ML 模型由一个 [Transformer](https://spark.apache.org/docs/latest/ml-pipeline.html)表示,它将一个具有特征的输入DataFrame转换成另一个具有预测的DataFrame。一个Transformer还可以输出另一组特征。因为在机器学习中,你通常必须执行几个步骤来产生想要的预测,Spark 有一个PipelineModel对象,它是一系列步骤或Transformers(注意,管道对象有点复杂,但为了本文的简单起见,我们将假设它是这样)。它将多个Transformers链接在一起,以指定一个 ML 工作流。

考虑下面这个来自spark.apache.org的例子,其中我们有一个包含三个阶段的PipelineModel:一个标记器(获取文本并返回单词)、一个散列函数(获取单词并返回向量)和一个逻辑回归模型(获取特征并返回预测)。

文本分析的 PipelineModel 示例。来源:spark.apache.org

您可以通过使用方法fit()训练管道来获得 PipelineModel。这里有一个例子:

tokenizer = Tokenizer(inputCol="text", outputCol="words")
hashingTF = HashingTF(inputCol=tokenizer.getOutputCol(), outputCol="features")
lr = LogisticRegression(maxIter=10, regParam=0.01)
pipeline = Pipeline(stages=[tokenizer, hashingTF, lr])model = pipeline.fit(training)

现在的问题是,如何在 Spark 之外运行这个 PipelineModel 对象?

选项 1:导出到 ONNX 并使用 ONNX 运行时运行模型

ONNX 是为深度学习模型设计的,然而,它在某些方面支持更“传统”的机器学习技术。Spark 通常用于那些更传统的方法。在 Spark 中这包括:

  • 矢量器和编码(字符串索引、OneHotEncoding、Word2Vec)
  • 定标器(定标器、输入器、二进制化器、存储桶)
  • 模型:线性模型,随机森林,梯度推进,朴素贝叶斯,SVM,主成分分析

要将您的模型导出为 ONNX 格式,您需要首先安装 onnxmltools ,该工具目前仅适用于 PySpark 。安装库的方式取决于您使用的平台。在我的例子中,我使用的是 Azure Databricks,所以我将使用集群中的 Install library 选项来安装这个库。

一旦安装了库,就可以通过以下方式将管线模型导出到 ONNX 中:

from onnxmltools import convert_sparkml
from onnxmltools.convert.sparkml.utils import buildInitialTypesSimpleinitial_types = buildInitialTypesSimple(test_df.drop("label"))
onnx_model = convert_sparkml(model, 'Pyspark model', initial_types, spark_session = spark)

在哪里,

  • buildInitialTypesSimple函数创建一个来自模型(特征)的所有预期输入的列表。它接受一个样本数据帧作为参数。在我的例子中,我使用了 test_df 数据帧,删除了 label 列,只保留了所有的特性。
  • 型号是安装管道的名称(PipelineModel)
  • “Pyspark 模型”是模型的描述
  • initial_types 是预期的输入要素名称和类型。正如我所说的,这可以通过使用buildInitialTypesSimple函数来提供,或者通过手工构建来提供,比如[ ('education ',string sensortype([1,1])]
  • spark_session=spark将 SparkSession 上下文传递给该方法。

注意:这最后一个参数没有记录在 GitHub 库中,但是在调试之后,我需要指定它以避免使用空的 spark 上下文。在我的例子中,我使用的是 Azure Databricks,所以我不知道这是否特定于 Databricks。

一旦模型被转换,您可以通过以下方式将其保存到文件中:

with open(os.path.join("/tmp/", "model.onnx"), "wb") as f:
    f.write(onnx_model.SerializeToString())

您可以使用 Python 中的 ONNX 运行时轻松加载该模型,如下所示:

import onnxruntime 
session = onnxruntime.InferenceSession(model_file_path, None)
output = session.get_outputs()[0]
inputs = session.get_inputs()input_data= {i.name: v for i, v in zip(inputs, input_sample.values.reshape(len(inputs),1,1).astype(np.float32))}}results = session.run([output.name], input_data)

: input_data是以键为特征名,以张量(1,1)为值的字典。reshape函数将输入转换为一个形状为(feature_count,1,1)的张量数组,这是所期望的。将值转换为float32也很重要。

然后,您可以将这个模型放在 docker 容器中,并安装 Python 和以下库:

您的评分文件将使用onnxruntime.InferenceSession()方法加载模型。你通常只做一次。另一方面,您的计分例程将调用session.run()

在下面的 GitHub 链接中,我有一个样本评分文件。

ONNX 在 Spark 中的局限性:

在撰写本文时,Spark-ONNX 转换器缺少以下特性:

  • 缺少功能哈希、TFIDF、RFormula、NGram、SQLTransformer 和某些模型(聚类、FP、ALS 等)的导出程序
  • 仅支持 PySpark
  • 一些问题:ONNX 规范不支持 Tokenizer

选项 2:打包 PipelineModel 并使用 Spark 上下文运行它

在容器内部运行 PipelineModel 的另一种方法是导出模型,并在容器内部创建一个 Spark 上下文,即使没有可用的集群。

如果你想持久化这个 PipelineModel,这个对象实现了接口MLWritable,它扩展了方法save(path)write().overwrite().save(path)。此方法将模型保存在如下所示的文件夹结构中:

piepline 模型的文件夹结构,由 VectorAssembler 和 GradientBoostedRegressor 组成。

在这种结构中,PipelineModel 保存在一个文件夹结构中,其中详细描述了管道中的所有步骤。在这种情况下,我创建的这个模型有两个阶段:一个 VectorAssembler 和一个 GradientBoostedRegressor。与您可能习惯的相反,所有的结构都需要加载和恢复训练好的模型。如果你使用的是一个模型注册中心,比如 MLFlow 或者 Azure 机器学习服务,我建议你把目录压缩到一个归档文件中。下面一行有助于做到这一点:

import shutilmodel.write().overwrite().save(model_path)
path_drv = shutil.make_archive(model_name, format='zip', base_dir=model_path)

请注意shutil.make_archive将在本地文件系统的驱动节点中创建文件。

如何在您的容器内使用它?

因为您将直接加载 Spark 模型,所以您需要在容器映像中安装pyspark Python 库。然后,在您的评分脚本中,您将创建一个 spark 会话,将归档文件解压缩到一个文件夹中,并加载 PipelineModel 对象。

import pyspark
from pyspark.ml import PipelineModelspark = pyspark.sql.SparkSession
               .builder.appName("pyspark_runtime").getOrCreate()model_unpacked = "./" + model_name
shutil.unpack_archive(model_path, model_unpacked)trainedModel = PipelineModel.load(model_unpacked)

变量sparktrainedModel必须在所有程序中可用。我个人认为这两个变量是全局变量。

然后,通过以下方式运行您的模型:

input_df = spark.createDataFrame(pandas_df)predictions = trainedModel.transform(input_df).collect()
preds = [x['prediction'] for x in predictioprint('[INFO] Results was ' + json.dumps(preds))

我在下面的 GitHub 链接中有一个样本评分文件。

结论

在本文中,我们回顾了两种不同的方法来移植在 Spark 集群中训练的模型,以便在容器中运行它们。使用开放标准 ONNX 或在 Spark 上下文中加载持久模型。如果你想看到例子的完整代码,你可以查看 GitHub 库。还有一个 Databricks 记事本可以生成 ONNX 文件和 MLLib zip 文件。希望有帮助。

作为初级开发人员,如何为开源软件做出贡献

原文:https://towardsdatascience.com/how-to-contribute-to-open-source-software-as-a-junior-developer-1da705669bcb?source=collection_archive---------28-----------------------

意见

它帮助我获得了我的第一份软件工程工作

照片由马太·亨利发自突发

我谷歌了一下“作为初级开发者如何为开源做贡献”。

给的建议没那么好。

随着时间的推移,它并没有发生太大的变化。而且没有在我还是初级开发者的时候帮我背,跟着它。

我将根据我为开源做贡献的经验分享一些替代建议。

常见的建议(对我没有帮助)

  • 查找标有“初学者”的问题
  • 选择流行的代码库
  • 你不需要写代码

这不管用。尽管注册了邮件列表,发现了“初学者问题”,并试图找到有助于…

在发现一个小型机器学习库不允许导入自定义的停用词列表后,我偶然发现了我的第一个贡献。我正在从事的开发者组合项目需要这个特定的特性。

所以我给它写了代码,做了个 PR。经过 repo 维护者几个周期的反馈和修复,我的代码发布了。

事实证明,这比寻找回购协议要容易得多。原因如下。

为你实际使用的图书馆做贡献

如果你不使用你所贡献的库,你就是在黑暗中写代码。

使用一个库会给你一种幕后架构的感觉。如果你熟悉一个库的特性,你会更快地理解它的代码是如何组合在一起的。

外卖:

查看您使用的库中未解决的问题。如果出现一个简单的问题,尝试解决它并提交一份 PR!

向你喜欢的(或者认为很酷的)图书馆投稿

仅仅因为你使用一个库(见上),并不意味着你喜欢它到喜欢贡献。

如果你认为图书馆的工作很有趣,你会有更多的动力去贡献。你的第一次投稿终究不会轻松!

外卖:

每个人都使用像 pip,bundler,yum,yarn 这样的包...但是如果你觉得他们做的事情没意思,那就辛苦了。找一些你感兴趣的东西。

用一个贡献者来贡献小的包是可以的

这甚至可能是你第一次投稿的好主意。

如果代码库很小,你会更容易找到方向。

是的,将来有可能一个小图书馆不会被维护。但是大多数图书馆也是如此。

在这一点上,你的目标是参与其中。

外卖:

不要羞于为一个小小的利基图书馆做贡献。

不要寻找带有“初学者问题”的回购

一些回购特别为初学者标记容易的问题。

如果你要解决这些问题,我建议你至少使用图书馆,并认为它很有趣。

否则,贡献仍将是艰难的。你必须弄清楚如何使用这个库,同时代码如何工作。

许多软件包不时会出现简单的问题,它们可能只是没有被标记出来。

外卖:

不要把自己局限在为初学者标记容易问题的库中。

为自己做贡献

你可以通过写你想要的特写来最大化你成功投稿的机会。

您将确切地知道它应该如何工作,因为这是您自己的用例。在软件开发中,这通常是编写代码的一半。

这是我的第一个开源贡献如此平易近人的原因。否则我想我不会这么容易成功。

外卖:

如果一个图书馆没有做你想让它做的事情,那就制造一个问题,问问你是否可以自己去做!

不要将文档更新为您的贡献

我明白了。首次捐款令人望而生畏。任何贡献都有助于建立信心。

也就是说,你是一名软件工程师,而不是一名作家(对吗?).你的一部分可能想为你的事业做点贡献。

编辑文档是一种简单的方法。与实际贡献代码相比,困难就相形见绌了。因此,如果您必须这样做,那么请尽快开始贡献代码。

好的文档在软件工程中非常重要。但是我们的目标是让你尽快贡献代码。稍后再回到文档。

外卖:

贡献文档可能会建立信心,但这只是贡献代码的第一步。

它会变得更容易

随着你编写软件的经验越来越多,你会对库是如何编写的有所了解,包括公共架构。

当你这样做的时候,导航代码库和弄清楚如何做出贡献变得更加容易。

为此,我要求你破解你常用的库的代码,并研究你使用的函数是如何编写的。

结论

这不是为开源做贡献的指南。这只是我对你完成第一次贡献的建议。

为开源做贡献帮助我找到了第一份工作。那时候我不是一个很好的开发人员,所以我可以做,你也可以!

大多数开发者都不会为开源做贡献。但是我们无限依赖开发者的慷慨。

那么为什么不试一试呢?

如何控制 2048 的游戏板

原文:https://towardsdatascience.com/how-to-control-the-game-board-of-2048-ec2793db3fa9?source=collection_archive---------33-----------------------

用极大极小算法玩 2048

…并完成最小最大算法的实现

作者图片

在本文中,我们将完成玩 2048 游戏的 minimax 算法的实现,然后我们将使用这个实现来自动玩这个游戏的 web 版本,这个版本可以在 Github 页面上找到。

这里是之前关于这个主题的文章,我在其中展示了如何表现 2048 年的游戏状态。如果您错过了,请查看:

[## 如何表现 2048 年的游戏状态

…以及如何以面向对象的方式做到这一点

towardsdatascience.com](/how-to-represent-the-game-state-of-2048-a1518c9775eb)

为此,我们将首先创建GameDriver类,它将作为我们的 minimax 实现和网页上的游戏之间的中间人。GameDriver类负责与游戏交互。我们需要处理两个操作:获取游戏当前状态的数据,并做出一个动作:上、下、左、右。这两种操作通过以下方法实现:

  • .getGrid() —这将获取游戏状态数据,并将其作为Grid对象返回。
  • .move() —这将把移动方向代码作为参数,并模拟适当箭头键的按键。

我们在实施中选择的移动方向代码是:

  • 0 =向上
  • 1 =向下
  • 2 =左
  • 3 =右

对于这个GameDriver类的实现,我们将使用 Selenium,它是做这种事情的一个好库:与 web 浏览器交互。如果你不知道,看看这篇文章。

现在,我们开始导入一些东西。从 Selenium 库中,我们需要 webdriver 和 Keys,它们将用于为您想要的 web 浏览器创建一个驱动程序实例,分别用于使用箭头键。我们还将 int 类型的最大大小作为MAX_INTtime包导入;过一段时间我们就会知道我们需要什么了。

from selenium import webdriverfrom selenium.webdriver.common.keys import Keysfrom sys import maxsize as MAX_INTimport time

接下来,我们为GameDriver类创建实例化方法。我们存储游戏页面的 URL,创建 Chrome 驱动程序的实例,并打开游戏 URL。然后,我们需要存储对页面主体元素的引用,以便稍后能够发送箭头键命令。我们还存储了一个字典,将移动方向代码映射到相应的箭头键。

.getGrid()方法提取关于游戏状态的数据并返回一个Grid对象。我们将数据存储为一个矩阵,并在返回时将其传递给Grid的构造函数。首先,用 0 初始化矩阵,然后当我们在页面上找到瓦片时更新它。

稍微考察了一下,Chrome 开发者工具里的游戏页面(CTRL+SHIFT+I),我的结论是:

  • 图块可以通过“图块”类名来识别。
  • 网格上每个图块的位置(行号和列号)可以从每个图块的类属性中的“图块-位置- - ”形式的类名中提取。
  • 图块编号是可以从“tile- num ”形式的类名中提取的最大值,它位于每个图块的类属性中。

下面是实现上述想法的代码:

下面的.move()方法向 body 元素发送适当的箭头键信号,以便按照它所采用的参数指示的方向移动。然后,我们使用time.sleep(0.1)在移动信号发出后暂停 0.1 秒,以便页面有时间更新自己。

def move(self, moveCode): self.body.send_keys(self.moves[moveCode]) time.sleep(0.1)

下面是GameDriver类的完整代码:

现在是实现 minimax 算法的时候了,它由 3 个函数组成:maximize()minimize()getBestMove()。如果你不熟悉极大极小算法,你可以查看这篇文章,以确保你理解这里发生了什么。

maximize()函数取参数:state为网格对象,ab为来自α-β剪枝的α和β,d为最大允许深度。该函数返回一个形式为(maxChild, maxUtility)的元组,其中maxChild是使效用最大化的当前状态对象(在 minimax 算法树中)的子对象,maxUtilitymaxChild游戏状态的效用值。

maxUtility变量将保存到目前为止遇到的节点的最大效用。在函数开始时,我们不知道任何效用值,所以我们认为最大值比任何效用值都小。我选择了-1。

然后,我们检查当前状态是否是一个终端节点,或者我们是否达到了最大深度。如果是,我们返回 None 作为maxChild并评估当前状态的效用,否则,我们继续迭代当前状态的所有子节点。在每一次迭代中,我们复制当前的游戏状态,并在一个可用的移动中移动;for 循环中的child变量是一个移动方向代码,用于进行该移动。

然后我们让 Min 通过minimize()函数完成他的移动,并从这个函数中获得当前迭代的子状态的效用。如果我们选择移动到循环中的当前子节点,这就是我们将得到的工具。如果这个效用大于我们之前的maxUtility,那么我们相应地更新maxChildmaxUtility。在这之后,我们根据α-β剪枝算法再做 2 次检查,这样我们就跳过了博弈树中那些我们事先知道它们不会给出最佳走法的路径。

minimize()函数类似于maximize(),但现在我们处于最小玩家的位置,我们试图选择效用最小化的移动。

getBestMove()函数调用maximize()并返回我们必须采取的行动的代码,以最大化我们的分数/效用。

下面是我们的 minimax 实现的代码:

现在,是时候创建一个游戏循环了,在这个循环中,我们重复以下三件事,直到游戏结束:获取游戏数据,使用极大极小法来确定什么是最好的走法,并实际执行这个走法。

当我们运行这个游戏循环时,我们的屏幕上应该会出现一个 2048 年的游戏,它会像页面顶部的 GIF 那样自动播放。

你可以在 Github 上找到这个项目的完整代码。

我希望您对这些信息感兴趣,感谢您的阅读!

这篇文章也贴在我自己的网站这里。随便看看吧!

如何将二进制文件转换成张量流记录

原文:https://towardsdatascience.com/how-to-convert-binary-files-into-tensorflow-records-3150d7236341?source=collection_archive---------36-----------------------

使用 Apache Beam 大规模转换自定义二进制文件

如果你有 JPEG 或者 PNG 的图片,可以使用 tf.io.decode_image 直接读入 TensorFlow。如果您的数据是某种特定于行业的二进制格式,该怎么办?

为什么 HRRR 要做张量流记录?

高分辨率快速更新(HRRR)模式是一个数值天气模式。因为当世界各国汇集它们的观测数据时,天气模型工作得最好,所以天气数据的格式由世界气象组织决定,并且极难改变。所以,HRRR 的数据是以#@的方式传播的!$@&=称为 GRIB 的二进制格式。

不管你在哪个行业——制造、发电、制药研究、基因组学、天文学——你可能都有这样的格式。一种现代软件框架都不支持的格式。尽管这篇文章是关于 HRRR 的,但是这里的技术将适用于您拥有的任何二进制文件。

张量流训练最有效的格式是张量流记录。这是一种 protobuf 格式,使训练程序能够缓冲、预取和并行读取记录。因此,机器学习的第一步是将特定行业的二进制格式文件转换为 TensorFlow 记录。

阅读 HRRR 文件

阅读 HRRR·GRIB 文件最简单的方法是使用一个名为 cfgrib 的软件包。这个包将底层数据作为自描述的 numpy 数组返回,这些数组被打包成一种称为 xarray 的格式。要使用 cfgrib,您需要一个名为 libecccodes0 的 Linux 库,它通常不安装在任何 Linux 发行版上。非常棘手的事情,但底线是我们需要在 bog 标准的 Google 计算引擎虚拟机上进行以下设置:

sudo apt-get -y --quiet install libeccodes0
python3 -m pip install -q cfgrib xarray

一旦我们安装了这两个,我们可以读取一个 GRIB 文件,并提取其中一个感兴趣的图像(在一个文件中有许多预测字段),如下所示:

import xarray as xr
ds = xr.open_dataset(FILENAME, engine='cfgrib', backend_kwargs={'filter_by_keys': {'typeOfLevel': 'atmosphere', 'stepType': 'instant'}})
refc = ds.data_vars['refc']
refc.plot()

从云存储中读取

不幸的是,我们使用的 Python 包只适用于本地文件。它不读取云存储。谷歌云存储上有一个 HRRR 档案,网址如下:

gs://high-resolution-rapid-refresh/hrrr.20200811/conus/hrrr.*

预测文件非常庞大。我们希望从云存储中即时读取数据,这样我们就不必再为永久磁盘付费了。

要创建一个只处理从云存储中读取的本地文件的库,我们可以使用一个简单的技巧——创建一个临时目录,将文件从云存储中复制到本地磁盘,读取文件,并在完成后删除临时目录。这听起来有点拗口,但实际上很容易做到,因为 Python 的 tempfile 和 TensorFlow 的 tf.io.gfile 模块完成了所有繁重的工作:

import xarray as xr
import tensorflow as tf
import tempfile
import cfgrib**with tempfile.TemporaryDirectory()** as tmpdirname:
    TMPFILE="{}/read_grib".format(tmpdirname)
    **tf.io.gfile.copy**(FILENAME, TMPFILE, overwrite=True)

    ds = xr.open_dataset(TMPFILE, engine='cfgrib', backend_kwargs={'filter_by_keys': {'typeOfLevel': 'atmosphere', 'stepType': 'instant'}})
    refc = ds.data_vars['refc']
    refc.plot()

转换为张量流记录

我们不希望只是读取数据,我们希望将其转换为 TensorFlow 记录。为此,我们必须创建一个 tf.train.Example:

refc = ds.data_vars['refc']
size = np.array([ds.data_vars['refc'].sizes['y'],
                 ds.data_vars['refc'].sizes['x']])
tfexample = tf.train.Example(features=tf.train.Features(
      feature={
         'size': tf.train.Feature(int64_list=tf.train.Int64List(value=size)),
         'ref': _array_feature(refc.data),
         'time': _string_feature(str(refc.time.data)[:19]),
         'valid_time': _string_feature(str(refc.valid_time.data)[:19])
 }))

TensorFlow 记录只能保存 bytes、int64、floats 类型的要素。所以,我们必须把其他所有东西都转换成这些类型。它也不了解 IEEE 类型,如-inf 或 nan。因此,要将一个 2D 数组转换成一组浮点数,我们必须做:

def _array_feature(value):
    if isinstance(value, type(tf.constant(0))): # if value is tensor
        value = value.numpy() # get value of tensor

    value = np.nan_to_num(value.flatten())
    return tf.train.Feature(float_list=tf.train.FloatList(value=value))

使用 Apache Beam 缩放它

这很好,但它只是一个文件。对于 ML 训练,我们需要转换大量的文件。我们需要进行大规模的转换。一个好的方法是使用 Apache Beam。管道将如下所示:

它应该花费 27 个小时,但我只花了 1 个小时,因为管道扩展到了许多机器上(在云上,在一台机器上花费 27 个小时的管道和在 27 台机器上花费 1 个小时的管道成本是相同的)。

完整的代码是这里是,但它的核心是:

p | 'hrrr_files' >> beam.Create(
          **generate_filenames**(options['startdate'], options['enddate']))
  | 'create_tfr' >>
          beam.FlatMap(**create_tfrecord**)
  | 'write_tfr' >> **beam.io.tfrecordio.WriteToTFRecord**(
          os.path.join(options['outdir'], 'tfrecord')))

基本上,第一步是生成我想要转换的所有文件的名称(我可以列出 GCS 目录,但我想每小时对天气预报进行一次采样,因为天气在 15 分钟内不会发生太大变化):

def generate_filenames(startdate: str, enddate: str):
    start_dt = datetime.strptime(startdate, '%Y%m%d')
    end_dt = datetime.strptime(enddate, '%Y%m%d')
    logging.info('Hourly records from {} to {}'.format(start_dt, end_dt))
    dt = start_dt
    while dt < end_dt:
        # gs://high-resolution-rapid-refresh/hrrr.20200811/conus/hrrr.t04z.wrfsfcf00.grib2
        f = '{}/hrrr.{:4}{:02}{:02}/conus/hrrr.t{:02}z.wrfsfcf00.grib2'.format(
                'gs://high-resolution-rapid-refresh',
                dt.year, dt.month, dt.day, dt.hour)
        dt = dt + timedelta(hours=1)
        yield f

第二步是创建 TF 示例,最后一步是将示例写到云存储中。

现在,还记得我们为了让 cfgrid 在我们的机器上工作所做的所有恶作剧吗?我们必须告诉 Beam runner 如何在每个 worker 节点上安装它需要的包。我们通过指定一个 setup.py 来实现,并在那里声明:

CUSTOM_COMMANDS = [
    'apt-get update'.split(),
    'apt-get --assume-yes install libeccodes0'.split()
]

REQUIRED_PACKAGES = [
    'cfgrib',
    'xarray'
]

在数据流上运行它

要在 Dataflow 上运行上述代码,我们只需运行代码。它将负责提交代码,自动缩放工人,并在完成后关闭一切。

python3 -m wxsearch.hrrr_to_tfrecord -- \
        --startdate 20190101 --enddate 20200101 \
        --outdir gs://{BUCKET}/wxsearch/data/2019 \
        --project {PROJECT}

大约 60 分钟后,您将获得 2019 年 HRRR 反射率文件的相应 TF 记录。

链接

  1. 进行转换的代码: hrrr_to_tfrecord.py
  2. 在数据流工作器上安装必要软件的 setup.py
  3. 阅读本系列接下来的两篇文章:如何在 HRRR 数据上训练自动编码器,以及如何使用结果嵌入

尽情享受吧!

如何将 DB2 查询转换成 python 脚本

原文:https://towardsdatascience.com/how-to-convert-db2-queries-to-python-scripts-f46960ed8df9?source=collection_archive---------29-----------------------

提供一个简单的 3 步模板来提升技能并过渡到 python

克里斯蒂娜@ wocintechchat.com 在 Unsplash 上的照片

许多公司正在使用 python 脚本运行常见的数据分析任务。他们要求员工将目前可能存在于 SAS 或其他工具集中的脚本转换为 python。这个过程的一个步骤是能够用新技术获取相同的数据。本文是关于将 DB2 查询转换成 python 脚本的。

如何将查询转换成 python?这听起来很难,但比你想象的要简单。一旦有了数据源的模板,您需要做的就是更改查询和输出文件名。

有几种方法可以做到这一点,但是我将概述一个直观的模板,它允许您在本地笔记本电脑/台式机上运行 DB2 查询。

在 DiscoDonuts 使用您的 DB2 专业知识

让我们假设你在一家大型甜甜圈公司工作,DiscoDonuts。您需要对 DB2 运行以下查询。通常,您可能会使用 DataStudio 之类的工具。很简单。

SELECT store_id, donut_style, date, volume, net_sales
 FROM donutsdb.sales_data 
 WHERE date = '2020-08-16'
 WITH UR;

现在,您的经理要求您开始使用 python。深呼吸;没那么难。在设置好代码之后,您只需要更新两个字段,输出文件的名称和查询本身。然后你点击运行。这有多简单?

初始一次性设置

如果您还没有,您需要联系您的 IT 部门安装一个工具(“IDE”)(如 PyCharm、VSCode、Jupyter Notebooks)。

要连接到 DB2,您需要输入您自己公司的数据库、主机名和端口 id。最有可能的是,您在当前使用的任何工具中都已经有了这些信息。

模板

首先,填写数据库连接信息。现在你可以保存这个模板,以备不时之需。

对于您想要运行的每个查询,您需要更新输出文件名和实际的查询本身。该查询被传递给 DB2,因此它与您已经在使用的 DB2 格式相同。

import ibm_db
import ibm_db_dbi
import pandas as pd# name your output file (and path if needed)
output_filename = "donut_sales.csv"# enter your query between the triple quotes
query = """ SELECT store_id, donut_style, date, volume, net_sales
 FROM donutsdb.sales_data 
 WHERE date = '2020-08-16'
 WITH UR; 
 """# one way to do credentialing
import getpass as gp                                     
uid=input('Enter uid:   ')                                                  
pwd=gp.getpass('Enter password (hidden): ')# connect to your database
db = (
    "DRIVER = {IBM DB2 ODBC DRIVER - DB2COPY1};"
    "DATABASE=<your donut database>;"
    "HOSTNAME=<your db2 hostname>;"
    "PORT=<your db2 port ####>;"
    "PROTOCAL=TCPIP;"
    'UID='+uid+';'
    'PWD='+pwd+';')
ibm_db_conn = ibm_db.connect(db, "", "")
pconn = ibm_db_dbi.Connection(ibm_db_conn)#optional if you are using the accelerator #ibm_db.exec_immediate(ibm_db_conn, "SET CURRENT QUERY ACCELERATION = ALL") df = pd.read_sql(query, pconn)
df.to_csv(output_filename,index=False)

点击运行。您将被要求输入您的凭证,您的查询将在 DB2 上运行,数据将被传输回您的脚本,您的文件将被创建!

如果您愿意,所创建的数据框可作为您的数据在 python 脚本中进行进一步分析。

下一个查询的三个步骤

  1. 更新您的输出文件名
  2. 更新您的查询
  3. 点击运行!

结论

将 DB2 SQL 知识转移到 python 并不困难。这是一项很好的技能,可以与他人分享。

我总是欢迎反馈。如果你有另一种技巧,请在回复中分享。解决问题的方法有很多,我只介绍了其中一种。代码是不断发展的,所以今天有效的可能明天就无效了。

如何将 Jupyter 笔记本转换成 pdf

原文:https://towardsdatascience.com/how-to-convert-jupyter-notebooks-into-pdf-5accaef3758?source=collection_archive---------4-----------------------

用几行代码将 Jupyter 笔记本转换为 pdf(调试“500:内部服务器错误”)

照片由Cookie PomUnsplash 拍摄

如果你是许多正在找工作的数据科学家中的一员,你可能会发现自己正在从事数据科学的家庭作业。如果您能够转换笔记本并提交 pdf 版本,而不是共享您的 Jupyter 笔记本,将会更加整洁。在这篇博客中,我想分享你如何用几行代码将 Jupyter 笔记本变成 pdf 格式!

之前的一次课后作业让我学会了如何做这件事

安装 nbconvert 和 LaTeX

nbconvert 允许用户将笔记本转换成其他格式。安装 nbconvert 后你会想,你可以开始了…对吗?如果这么简单,我为什么要写这篇文章?

在我安装了 nbconvert 之后,我收到了一个错误,上面写着“500:内部服务器错误。”之所以会看到这个错误,是因为你还没有安装 LaTeX 或者 Pandoc 。我决定下载 LaTeX。下载 LaTeX 的好处是,它让你的分析看起来像一篇研究论文,这非常合法。

从命令行运行 nbconvert

安装这两个软件包后,您可以尝试使用以下命令行将笔记本转换为您想要的格式:

$ jupyter nbconvert --to FORMAT notebook.ipynb

这个命令行将把 Jupyter 笔记本文件转换成由FORMAT字符串给出的输出格式。出于本文的目的,我们将把它转换成 pdf,但是您也可以把它转换成 HTML、Markdown 等。如果你想把笔记本文件转换成 HTML,只需把pdf替换成html,反之亦然。

$ jupyter nbconvert --to pdf notebook.ipynb

根据您之前安装的软件包,您可能需要降级或升级其中的一些软件包。

例如,如果您看到以下错误消息…

spyder 3.3.6 has requirement pyqt5<5.13; python_version >= "3", but you'll have pyqt5 5.13.0 which is incompatible

您可以通过卸载 pyqt5 并安装 pyqt5==5.12.0 来解决此错误。

安装 nbconvert 模板

在我成功地将笔记本转换成 pdf 文件后,我意识到文件的边距是关闭的!幸运的是,我在提交之前仔细检查了文件!

下面是对比。默认情况下,我们可以看到保证金是非常关闭。默认的 pdf 格式会切掉页面的一边。

泰勒·马卡罗在他的 Github 上的照片

为了解决这个问题,我找到了一个由泰勒·马卡罗创建的模板。我首先通过运行命令行安装了他的nb_pdf_template:pip install nb_pdf_template.,然后我将cd放入 LaTeX 文件夹,并添加了 Tyler 创建的两个模板:classic.tplx 和 classicm.tplx。最后但同样重要的是,不要忘记从 LaTeX 文件夹中删除默认的 article.tplx。

完成后,您将能够通过运行以下命令行获得格式良好的 pdf:

$ jupyter nbconvert --to pdf notebook.ipynb --template classic

结论

以下是您需要的所有软件包:

  1. 安装 nbconvert
  2. 安装乳胶Pandoc
  3. 安装一个 nbconvert 模板

你有它!如果你觉得这很有帮助,请分享并关注我的博客,这样你就不会错过了!

下次见,快乐学习!👩🏻‍💻

如果你喜欢我的内容,请关注我❤️,看看我最近的博客:

[## 用例子理解和选择正确的概率分布

举例说明最常见的离散概率分布

towardsdatascience.com](/understanding-and-choosing-the-right-probability-distributions-with-examples-5051b59b5211) [## 作为分析师如何准备商业案例面试?

作为数据分析师或数据科学家,我们不仅需要知道概率和统计,机器学习算法…

towardsdatascience.com](/how-to-prepare-for-business-case-interview-as-an-analyst-6e9d68ce2fd8) [## 构建电子商务产品推荐系统:第二部分——模型构建

这个博客是我之前工作的延续,在我之前的工作中,我谈到了我是如何收集产品评论和…

medium.com](https://medium.com/@kessiezhang/building-a-product-recommendation-system-for-e-commerce-part-ii-model-building-8b23a9b3ac27) [## 为电子商务建立一个产品推荐系统:第一部分——网络搜集

今天,如果我们想到机器学习在商业中最成功和最广泛的应用,推荐者…

medium.com](https://medium.com/@kessiezhang/building-a-product-recommendation-system-for-e-commerce-part-i-web-scraping-798b6251ab51)

对于多元回归问题,如何将 Pandas 数据框架转换为 Keras RNN,然后再转换回 Pandas

原文:https://towardsdatascience.com/how-to-convert-pandas-dataframe-to-keras-rnn-and-back-to-pandas-for-multivariate-regression-dcc34c991df9?source=collection_archive---------10-----------------------

这篇文章提供了一个简单的 Python 代码,它采用熊猫数据帧中的数据,并使用 Keras RNN LSTM 模型以相同的格式输出预测。

我遇到的问题相当普遍(我认为):以pandas dataframe格式获取数据,并使用带有keras RNN 的时间序列回归模型进行预测,其中我有不止一个独立的X(也称为特征或预测器)和一个依赖的y。更准确地说,问题不是构建模型,而是将数据从pandas dataframe格式转换成 RNN 模型(在keras中)需要的格式,并从keras模型中获得预测作为pandas dataframe

感觉无论我在哪里寻找解决方案,我都能得到关于 RNN 如何工作的解释或者单变量回归问题的解决方案。因此,我会尽量保持这篇文章的简洁和集中。这里的编码假设您已经做了所有必要的预处理(例如,数据清理、特征工程等。)并以pandas dataframe格式准备好用于分析的时间序列。

不会在这里找到的:

理论解释

RNN 模型的精美插图

预处理技术

复杂或精密的模型

网上有很多资源可以很好地解释这些问题,我强烈推荐查看一下 StackOverflow 的问题和杰森·布朗利的博客帖子。

会在这里找到什么:

一个简单的 Python 代码,采用一个pandas dataframe并使用一个keras RNN LSTM 模型以相同的格式输出预测,用于多元回归问题。

这篇文章将描述代码片段和解释,并在最后提供完整的无缝代码。

让我们开始吧:

第一步,让我们导入所有需要的包并检查keras版本

如你所见,我的keras版本是2.3.1,所以如果你对我在这里发布的代码有一些问题,请检查你是否有相同或更高的版本。

第二步,读取数据

如你所见,我有 32,128 行 4 列,有一个y 和三个X。这里的代码可以在任意数量的X 上运行,包括一个X 注意,你需要定义你的y列,以使事情变得更简单和通用。

可选步骤-绘制数据

我知道,这里的分辨率不是很高,但是你可以想象我的数据是什么样子的。

第三步,拆分数据进行训练和测试

请注意第三行的注释。让我们再次策划,看看我们的分裂是否有意义。

还是那句话,不要介意分辨率,这不重要。图看起来不错,过去(蓝色)是我们的训练数据,最近的日期是我们的测试数据(橙色)。

第四步,只对训练数据分开Xy。我们将稍后处理测试数据。

现在,X_train看起来像这样:

y_train看起来是这样的:

步骤 5,为keras缩放并准备Xy数据

这部分需要一些解释。这里我们将数据从pandas数据帧转换成keras所需的numpy数组。在第 1–8 行中,我们首先使用sklearn MinMaxScaler模型缩放Xy,使它们的范围从 0 到 1。接下来的几行是对y的一些形状处理,以使其适用于keras。我们需要y的形状是(n, ),其中n是行数。第 12 行通过在第一个位置添加零将y数据向前“推”一步,第 13 行通过删除最后一个时间步(最后一行)保持y的形状。下面是第 12–13 行中发生的情况的一个简化示例:

#let's say y = [1,2,3,4]
# y = np.insert(y,0,0) --> [0,1,2,3,4]
# y = np.delete(y,-1) --> [0,1,2,3]

如果这个解释不够清楚,我建议你参考 Jason Brownlee 的博客文章。查找标题为:多元输入和相关系列示例的部分。

总结一下y的形状操控,让我们快速看一下发生了什么。我们从作为数据帧的y数据开始:

现在它应该是这样的:

array([0\.        , 0.12779697, 0.12401905, ..., 0.59237795, 0.6018512 , 0.61132446])

第六步,使用kerasTimeseriesGenerator组合Xy

TimeseriesGenerator将分离的Xy转换成样本结构,准备训练深度学习模型。我建议打印生成器对象的形状,以确保它能够工作。形状应该与第 8 行第 6 步中显示的完全一样。

将我们的数据从pandas dataframe转换成可用于深度学习模型的东西的困难部分已经过去了。现在我们可以进入第 7 步,实例化模型:

请注意,我在这里使用了一个非常简单的模型,只有一个隐藏层,没有脱落层。这是因为我想保持这篇文章的简洁,实际的模型架构不是这里的重点。但是可以随意尝试更多的层。

第八步,拟合模型并绘制损失图

同样在这里,我使用了简单的设置,只有 5 个时期,只是为了说明整个过程。

现在模型可以使用了,我们可以在测试集上进行预测。

第一行通过从测试集中删除y 来生成X_test数据,我们不希望y 数据包含在X中。然后我们根据之前安装在X_train上的MinMaxScaler模型来缩放X_test。第 3 行很重要,因为我们需要为测试数据创建一个TimeseriesGenerator。我很纠结这部分,因为在我看到的例子中,这里包含了y_test,但是我不希望模型有任何关于y_test数据的知识。我不希望有任何可能导致预测偏差的数据泄露。多亏了 Marco Cerliani 在 StackOverflow 上给了我很大的帮助,我明白了TimeseriesGenerator中的第二个参数,也就是y_test只是一种预测方法,并且y_test的实际值并不重要(在这个特定的地方),所以你可以插入一个虚拟的y_test →一个与实际y_test数据形状相同的零数组。TimeseriesGenerator的其余部分类似于训练数据,这里我也打印了形状以确保它没问题。

第 10 行调用预测方法,第 11 行重新调整预测。记住,我们之前在 0 和 1 之间缩放了y数据,所以我们需要将它缩放回来。在第 12 行,我们从y_truey_pred构造了一个dataframe。注意,我们只调用了y_true ( test[y_col].values[n_input:])的子集,这是因为模型需要n_input时间步长(行或观察值)来开始预测,所以它从X_test中取出这些n_input (在本例中为 25 个时间步长),然后才开始预测。例如,如果我们的测试集中有 50 个时间步长(或 50 行或 50 个观察值),那么我们将只有 25 个预测,因为前 25 个是模型根据我们设置的体系结构使用的。

现在我们有了一个很好的熊猫数据帧结构:

我们可以使用results.plot();来绘制它们:

就这样,我们以pandas dataframe格式的数据开始,以同样格式的预测结束。

这是一个块中的全部代码

我希望这是有用的,将有助于您的机器学习任务。如果你有任何意见,请写在下面给我。

如何将 SQL 查询结果转换为熊猫数据框架

原文:https://towardsdatascience.com/how-to-convert-sql-query-results-to-a-pandas-dataframe-a50f0d920384?source=collection_archive---------5-----------------------

使用 Python 读取 Jupyter 笔记本中的 SQL 查询来创建熊猫数据框架

Tobias Fischer 在Unsplash【1】上拍摄的照片。

目录

  1. 介绍
  2. 工具
  3. 例子
  4. 摘要
  5. 参考

介绍

作为一名数据科学家,您可能经常需要从数据库表中提取数据。建模过程中收集数据集的第一步通常是从 SQL 代码的结果中获取。SQL 通常不是成为数据科学家所需的主要语言;但是,在某些情况下,练习和利用来获取数据集是很重要的。不过,也有一些问题——来回使用 Python 代码、SQL,有时还有 Jupyter Notebook,可能会加重问题。有一个非常简单的过程可以帮助解决这个问题。解决方案是在 Jupyter 笔记本中编写 SQL 查询,然后通过将其转换为 pandas 数据帧来保存输出。下面,我将提供代码和一个例子来展示这个简单而有益的过程。

工具

照片由克里斯里德Unsplash【2】拍摄。

这个过程由几个关键工具组成。首先,您将使用您原来已经有的 SQL 查询,然后,使用 Python,将引用 pandas 库来将输出转换成数据帧,所有这些都在您的 Jupyter 笔记本中。

SQL —结构化查询语言,大多数数据分析师和数据仓库/数据库工程师使用这种语言来拉取数据,用于报表和数据集开发。

--return all columns from table
SELECT * FROM TABLE

Python —数据科学家使用的主要编程语言之一。

# display text
print('Hello, world!')

Pandas —数据科学家用来从各种来源读取数据的流行图书馆。静态数据可以作为 CSV 文件读入。还可以使用 pandas 连接一个活动的 SQL 连接,然后将其从输出转换为数据帧。在下面的例子中对此进行了解释。

# creating and renaming a new a pandas dataframe column
df['new_column_name'] = df['original_column_name']

Jupyter Notebook —为您的数据科学模型运行 Python 代码(以及 SQL)的平台/环境。

例子

在这个例子中,我将使用一个模拟数据库作为 SQL 查询将引用的存储环境。

首先,导入 pandas 库,如果需要,创建一个别名' pd' ,用于速记符号。接下来,创建一个凭据变量来存储:

  • 数据库/SQL 环境— PostgreSQL
  • 用户名:密码
  • 数据仓库:数据库 URL (IP 地址)
  • 通道数
  • 数据库名称

这个变量将是一个用引号括起来的长字符串。Jupyter 笔记本中的下一个单元格将是 SQL 查询本身。Pandas 将用于执行查询,同时将输出转换为数据帧。该查询的格式是包含带有三重引号的语句。在最后一个引号之后,逗号后面会跟一个连接参数,该参数将等于您的凭据变量。

以下是该示例的代码(您必须使用自己的凭据):

# import python library
import pandas as pd# assign a variable that contains a string of your credentials
credentials = "postgresql://username:password@your_sql_connection_url:port_number/database_name"# read in your SQL query results using pandas
dataframe = pd.read_sql("""
            SELECT column_1, column_2
            FROM Table
            WHERE column_1 > number
            ORDER BY column_1
            """, con = credentials)# return your first five rows
dataframe.head()

仔细看看 Jupyter 笔记本中的代码:

Jupyter 笔记本的例子(改为 read_dql 改为 read_sql)。作者截图[3]。

更多关于熊猫功能的文档,点击这里【4】。您还可以在那里找到更多关于参数的有益信息。

摘要

当创建将用作数据集的数据框时,有大量选项可用于收集该数据。有时读入 CSV,而数据帧可以通过定义列和值来生成。但是,在本例中,我们看到您可以使用 SQL 从数据库中查询,并将这些结果作为数据返回,最终作为新的数据帧读入。现在你有了数据框架,你就可以遵循数据科学的正常流程了。希望这篇文章对您有所帮助,感谢您的阅读!

参考

[1]照片由托比亚斯·菲舍尔Unsplash(2017)拍摄

[2]Chris Ried 在 Unsplash 上拍摄的照片,(2018)

[3] M.Przybyla,Jupyter 笔记本截图,(2020)

[4]熊猫,(2008 年至 2014 年)

如何用 PyTorch 烹饪神经网络

原文:https://towardsdatascience.com/how-to-cook-neural-nets-with-pytorch-7954c1e62e16?source=collection_archive---------19-----------------------

使用 PyTorch 的深度学习项目的诀窍

Icons8 团队Unsplash 上的照片

py torch 训练配方

好了,你已经决定了这道菜(你的神经网络),现在你需要用 PyTorch 来烹饪(训练)它。但是等等,这不是一个简单的“快餐”任务,不像其他流行的 python 机器学习库(例如 Scikit LearnKeras )那样运行fit()eval()方法的一些变体。你需要遵循一个食谱(过程)并自己定义这些方法。你可能会问,为什么?嗯,这里当然有一个权衡。虽然 PyTorch 以其可解释性、pythonic 式和可调试代码以及创建动态计算图的能力而闻名,但它不像 Keras 那样实用,因为它缺乏更高级别的 API,尤其是在训练和评估模型方面。同样,这是一个权衡:灵活性与实用性。PyTorch 侧重于前者,但也有让训练和评估更容易的库,比如 ignitefastailightning (举几个例子)。

所以回到我们的食谱…我们先看一下大图,然后放大到每一步。让我们后退一步,看看一个典型的 ML 过程可能是什么样子。原来有一个简单的食谱你可以遵循。事情是这样的:

  1. 加载和预处理数据
  2. 定义模型、优化器和损失
  3. 训练和验证模型
  4. 评估模型

现在让我们看看如何在 PyTorch 中实现这一点。我将向您展示一个包含一些样板代码(没有双关的意思)的菜谱,您可以按照它来开发和训练您自己的模型。然后,它将取决于你改变配料和香料的食谱在这里和那里!

1。数据加载和预处理

照片由凯蒂·史密斯Unsplash 上拍摄

定义变换(仅用于图像分类 )

如果您正在进行影像分类,您可能需要转换数据。PyTorch 的torchvision模块有一个很好的子模块叫做transforms,可以让你构建一个转换管道。不像在 Keras 中,这里你可以定义变换的顺序。这些变换可以包括图像增强技术,如调整大小、裁剪、颜色抖动、图像翻转等。转换的详细列表可以在 PyTorch 网站的这里找到。

如果你的数据集很好并且标准化了(所有的图像都有相同的大小,几乎都在中心,没有颜色变化,图像没有旋转或翻转),就像 MNIST 一样,那么你可能只需要将你的图像转换成张量并标准化它们。下面是一个简单的转换管道的例子,您可以使用transforms模块将它用于标准化数据集。

在上面的例子中,ToTensor()转换将图像作为输入,然后通过将每个通道的值除以 255,在 0 和 1 之间缩放每个像素值(我们正在处理上面的灰度图像,它只有一个通道)。接下来,张量被归一化,使得值在-1 和 1 之间(从 0.5 的平均值中减去先前缩放的像素,然后除以 0.5 的标准偏差)。这就像一个管道,对于预处理图像非常方便。

但是,如果您试图对猫和狗的图像或任何真实世界的数据集进行分类,您可能会从数据扩充中受益。主要思想是,当你的模型在更多种类的数据上被训练时,它将更好地概括。数据扩充是一种通过对原始内容进行变化(或转换)来利用现有数据的技术。这里有一个如何完成这项任务的例子:

变形金刚的名字非常直观,你可以通过浏览 PyTorch 文档查看这些和其他变形金刚的定义。请注意如何为训练集和测试集定义不同的转换。此外,请注意,在标准化步骤中,我们现在有三个通道,而不是一个。

下载数据集

PyTorch 为您提供了一些包含或下载数据集的选项。torchvision包包含预加载的数据集,如 CIFAR10MNIST ,如果你想对你的模型进行基准测试或只是想学习图像分类,这将非常方便。如果你想对你自己的图片进行分类或者从网上下载,你需要另一种方式来加载数据集。为此,PyTorch 提供了ImageFolder类,该类假设您已经将所有图像存储到以每个类标签命名的目录中(即文件夹‘dog’将包含狗的图像,文件夹‘cat’将包含猫的图像)。您应该有一个结构相同的 train 和一个 test 文件夹。这样,您可以像这样加载数据:

现在,假设您需要对您的图像进行一些清理和预处理,或者如果您不进行图像分类,而是需要编写一个基于文本的分类器,要求对文本进行预处理,或者您需要在表格数据集上预测销售额,要求在将数据输入模型之前进行清理或某种数据争论。对于这些情况,您可以通过从torch.utils.data扩展Dataset类来创建自己的数据集。您需要定义三个方法,遵循如下的模板:

这是一种更优雅、更灵活的定义数据集的方法,也是通用的,适用于任何类型的数据集。一旦定义了数据集,就可以实例化该类并为多个集合传递参数,比如 train 和 test。所以你会有类似于…

你可以在这里获得更多关于创建自定义类以及其他自定义数据相关类的信息。

创建验证集

好了,是时候拆分并创建一个验证集来帮助你实现目标了。注意这是一个可选步骤,但绝对是一个最佳实践,强烈推荐用于评估和优化您的模型。创建验证集的一种方法是使用torch.utils.data中的random_split函数。这非常简单,只需要您想要分割的数据集和每次分割的大小。

定义数据加载器

一旦定义了数据集,就需要将它们包装在一个名为DataLoader的类中。这个类基本上是一个简单的方法,可以让你加载批量数据,并且包括免费的并行处理,不需要做任何额外的编码。很酷的东西。让我们来看看:

2。定义模型、优化器和损失

照片由贝卡·泰普特Unsplash 上拍摄

很好,现在您已经准备好开始定义您的模型了。定义模型有几种不同的方法,我将在另一篇文章中介绍。但是现在,我们只选择类方法,因为它是 PyTorch 中最流行的方法之一,而且非常直观。这是你发挥创造力的地方。根据您的问题,您可以尝试不同类型的神经网络和架构。为了便于说明,我选择实现一个简单的 CNN。

你可以在这里找到更多关于创建你的定制模型的信息。好了,现在你已经定义了你的模型,你可以实例化它,并定义优化器和损失函数。这些都是一行程序,很容易实现。让我们先实例化模型。

输出:

MyCNN(
  (fc1): Linear(in_features=32, out_features=16, bias=True)
  (fc2): Linear(in_features=16, out_features=8, bias=True)
  (fc3): Linear(in_features=8, out_features=2, bias=True)
)

接下来,要定义优化器,您需要从 PyTorch 导入optim模块。PyTorch 有很多优化器,你可以在这里查找完整的列表来看看使用哪一个。每个优化器都有不同的参数,但是大多数都需要至少一个学习率,称为lr。为了让 PyTorch 优化您的网络,您首先需要传递模型参数。它应该是这样的:

然后,您需要定义 PyTorch 将使用的损失函数,以了解您的模型预测离实际目标有多远。损失函数的选择取决于你试图解决的问题的类型,你可以在这里找到更详细的损失列表。现在,我们将使用二元交叉熵损失,适用于二元分类问题。我们将该损失标准称为标准,如下所示:

3。训练并验证模型

Becca Tapert 在 Unsplash 上拍摄的照片

好了,现在你开始真正的烹饪了。如果与我之前提到的 sklearnkeras 相比,火车循环并不直接,但它非常直观,可以帮助您了解引擎盖下发生了什么,另外您可以通过插入跟踪来非常容易地调试它。你基本上只需几步就能完成一个火车环…

你在上面看到的是一个带验证的简单 PyTorch 训练循环。然而,在实践中,您可能希望累积精度或您选择的度量和/或在每个时期结束时应用早期停止。好的方面是这是完全可定制的。真的,天空才是极限。尽管出于本文的目的,我们将保持简单。

4。评估模型

斯蒂芬·约翰逊在 Unsplash 上拍摄的照片

训练完模型后,最后一步是预测和评估结果。测试循环与验证循环非常相似,但是相反,您将查询test_loader来读取测试数据,并且只运行一次测试数据来评估模型。换句话说,您不需要担心 epochs,因为您只想查看模型在每个实例上的执行情况。

结束语

既然您已经看到了它有多简单,那么您可以自己尝试用 PyTorch 构建一个神经网络!食谱基本上是一样的,但你可以在这里或那里改变一些成分,根据你的味蕾进行定制。还有其他方法可以实现这些步骤,但是我决定向您展示我认为最简单的一种方法。让我知道你的想法,我很想知道你是怎么做这道菜的!

如何在加密的 S3 桶交叉帐户之间复制

原文:https://towardsdatascience.com/how-to-copy-between-encrypted-s3-buckets-cross-account-e4e3096d1a8a?source=collection_archive---------6-----------------------

包括一步一步的教程

在加密存储桶、交叉帐户之间复制时涉及的所有资源的概述。用 Draw.io 创建

加密很棘手,即使你使用的是 AWS 这样的托管服务。

我的上一篇文章中,我讲述了你需要了解的关于 IAM 的内容,IAM 是 AWS 提供的身份和访问管理服务。在这篇文章中,我想更具体一点,介绍一个常见的场景,其中有大量不同的权限在起作用。在这里,您将看到我之前谈到的所有不同类型的资源都在运行,希望一切都会顺利。

如果你需要 AWS 中权限如何工作的基础知识,请阅读我的对 IAM 的介绍帖子

概观

假设我们使用几个 AWS 账户,我们想将某个 S3 桶中的数据从一个账户复制到某个目的地账户,如上图所示。此外,让我们想象我们的数据必须在静态下加密,出于监管目的;这意味着我们在账户中的桶也必须被加密。

在 AWS 上实现上述目标有很多方法,但我将讨论以下组合:

  • KMS 用于主密钥的加密/解密。一种替代方法是实现客户端加密并自己管理主密钥。
  • 使用客户管理密钥的 S3 服务器端加密适合您的使用案例。与 S3 托管密钥相比,客户托管密钥有几个优点,比如审计跟踪。
  • S3 默认加密适合你的桶对象;这意味着添加到 bucket 中的对象将被自动加密,而不需要您指定一个标志来加密它们。
  • 作为执行复制的身份的角色,与用户相对。

政策

这里有 5 个主要的资源:我们的两个处理桶加密的主密钥,我们的两个 S3 桶,以及我们的角色。这意味着您需要 4 个资源策略(不包括角色的信任策略)和 1 个身份策略才能正常工作。

注意:你不能复制/粘贴下面的所有内容。对于每个策略,您必须将资源 ARNs 和帐户 id 更改为属于您的源/目标的资源 ARNs 和帐户 id。

角色身份策略

这是我们将附加到我们的S3Porter角色的身份策略,以便让它联系 S3 和 KMS。这里有 4 个必要的语句:顶部图表中的每个资源一个。

  1. 从跨帐户来源时段复制。跨帐户访问要求发送方的身份策略和接收方的资源策略都允许访问。在本例中,我们允许发送者发出请求。
  2. 复制到同一个 AWS 帐户中的 bucket。请注意下面的策略是如何将资源限制在单个 S3 存储桶中的:作为一种最佳实践,重要的是将您的策略限制在它们绝对需要的资源上。
  3. 使用跨帐户 KMS 密钥来解密我们的源桶中的对象。
  4. 加密到我们的目的地账户。这可能看起来很有趣,我们仍然需要对我们的目的地 bucket 的kms:Decrypt权限,因为我们只是将数据复制到其中。我们需要kms:Decrypt 是因为,在幕后,S3 可能会把你的文件分成块,然后重新组合以便把它们复制到一个桶里。重组过程可能需要您的角色具有解密权限,因为文件的大部分在最初上传时将被加密,并且在重组前需要再次解密。您可能会注意到该策略需要kms:GenerateDataKey权限;之所以需要这些,是因为 S3 会用从你的主密钥导出的唯一密钥来加密你的每个对象,这个过程被称为信封加密。

目标存储桶资源策略

我们的目的地 bucket 不需要资源策略,因为对它的请求来自同一个 AWS 帐户中的 S3Porter 角色,并且我们已经在我们的身份策略中添加了对目的地 bucket 的s3:PutObject权限。

值得注意的是,我们还可以在目的地桶上添加一个资源策略,而不是在上面的S3Porter身份策略上添加它。

目标加密密钥资源策略

下面实际上是默认的密钥策略。有点无聊。

然而,值得注意的是,KMS 的关键政策不同于大多数资源政策。如果没有显式访问权限,则不允许仅身份策略上的 IAM 权限访问 CMK,即使在同一个 AWS 帐户中也是如此。在 KMS 密钥策略中,赋予帐户内策略访问密钥的能力的默认方式是允许根帐户用户访问密钥;这也将使其他 IAM 策略能够关键地采取行动,如下所示。

源时段资源策略

为了允许跨帐户访问 S3 存储桶,我们需要添加一个资源策略,称为存储桶策略,到我们的 S3 存储桶。这个策略相对简单:

  • 在主体部分中,我们指定要授予权限的交叉帐户角色的 ARN。
  • 在 actions 部分,我们提供了s3:GetObjects3:ListObject权限。这两个都是获取我们桶中所有内容所必需的。
  • 作为资源,我们指定了 bucket 本身arn:aws:s3:::source以及 bucket 中的所有对象 t arn:aws:s3:::source/*

缺少任何这些东西都可能导致一个相当模糊的 403(拒绝访问)。

更复杂的 bucket 策略可能使用条件来限制 IP 地址范围或缩小我们的S3Porter角色可以访问的对象。

授予以下权限的另一种方式是使用访问控制列表(ACL)。ACL 是 IAM 之前 S3 管理权限的“老方法”。ACL 没有被弃用,但是它们遗留的,并且 AWS 推荐使用桶策略来代替

源加密密钥资源策略

最后,我们还有一个策略,允许我们的S3Porter从我们的跨帐户源桶中解密数据。

漫游教程

下面我设置并执行两个桶之间的复制,交叉帐户。

我建议在自动化或使用基础设施即代码签入东西之前,自己完成下面的内容,以获得跨帐户存储桶访问的舒适性。

  • 为了隐私,我已经把所有的 id,ARNs,账户等等的名字都改了。
  • 当然,首先您必须拥有创建所有必要对象的权限。对于本教程,我假设您有两个概要文件:source-admindestination-admin。你可以看到我是如何用下面的~/.aws/credential文件建立这些档案的。

注意:这里值得一提的是,我们使用的是 AWS CLI 的第 2 版。AWS CLI 很棒,因为默认情况下,它使用 TLS 1.2 对我们传输中的数据进行加密,所以不用担心我们在这里通过网络发送明文。

为我们的教程创建和设置所有的资源。

接下来,我们需要编辑我们的~/.aws/credentials文件;这将让我们使用我们的搬运工角色作为个人资料。

这是 AWS 概要文件在设置了上述所有用户和 S3Porter 角色后的样子。请注意来自承担角色的凭证是如何手动添加的。

最后的步骤

如果你遵循了上面的例子,记得在这么做的时候拆掉你创造的任何资源!

感谢阅读!如果你想聊天或对帖子有反馈,你可以随时通过 Twitter、LinkedIn 或 evankozliner@gmail.com 联系我

笔记

[1]对信封加密的全面概述超出了本文的范围,但是信封加密是一个重要的(也是有趣的)话题。信封加密很方便的原因有很多:从简化主密钥的轮换并确保它们留在 HSMs 中,到通过允许使用不同的算法来存储对象和密钥来加速加密。

如何使用 Ceres Solver 创建一个 C++项目?

原文:https://towardsdatascience.com/how-to-create-a-c-project-using-ceres-solver-f3d67c8044f3?source=collection_archive---------49-----------------------

开始使用 Ceres 解算器的逐步步骤

使用 Ceres 优化的 3D 姿势图示例。来源:谷神星教程

我猜你们大多数人已经知道一点谷神星解算器是什么。对于那些没有听说过它的人来说, Ceres Solver 是最受欢迎的开源库之一,用于解决大型复杂的优化问题。Ceres Solver 的一个突出特点是能够解决带有边界约束的非线性最小二乘问题。它在机器人学中广泛用于解决束调整和 SLAM 等问题。用户和应用程序的集合可以在官方网站上找到。

尽管 Ceres Solver(在本文的其余部分称为 Ceres)有很好的文档和实践教程来帮助新用户入门。我发现关于如何使用 Ceres 创建一个新项目的信息隐藏在官方指南中。这正是这个故事的内容。

安装 Ceres

首先,我们需要安装 Ceres 才能使用。在这一节中,我们将讨论如何在 Ubuntu 机器上构建和安装 Ceres 作为静态库。如果您正在使用不同的操作系统,或者您更喜欢将 Ceres 构建为共享库,请遵循安装页面上的说明。

我们从推荐给 Ubuntu 的依赖项开始:

在 Ubuntu 上安装 Ceres 的依赖项

然后我们从 Ceres 的网站上获取源代码。在撰写本文时,最新的稳定版本是 1.14.0。请在以下命令中相应地调整版本:

将 Ceres 构建为静态库

现在我们已经成功编译了谷神星。我们应该能够运行谷神星的 HelloWorld 示例。

运行 Ceres 附带的 Hello World 示例

最后一步是将 Ceres 安装到之前指定的安装目录中:

根据安装目录,您可能需要也可能不需要sudo权限。

使用 Ceres-Solver 创建一个项目

在上一节中,我们已经讨论了将 Ceres-Solver 作为静态库来构建和安装。我们还运行了 Ceres 附带的 HelloWorld 示例。下一步是能够编译我们自己的 HelloWorld 程序,并开始探索谷神星的魔法世界。

为此,我们将创建一个简单的项目,如下所示:

my_project
├── CMakeLists.txt
└── helloworld.cc

helloworld.cc只是我们之前运行的 HellowWorld 示例的源代码。你可以从 Ceres 的 git 库获得。还有许多其他可用的示例,包括但不限于圆拟合示例、束调整示例、姿势图优化的 2D & 3D 示例等。

CMakeLists.txt包含关于如何使用CMake 构建系统构建我们的helloworld.cc的信息:

helloworld.cc 的 CMakeLists.txt

注意 Ceres 官方支持 CMake 2.8 向后兼容。但 2020 年采用 CMake 3.x 风格对我们来说并无大碍。

如果你不熟悉 CMake 构建系统,我强烈推荐 Aakash MallikC++应用开发系列

如果您想发布使用 Ceres 的项目,请参考安装/导出使用 Ceres 的项目了解更多信息。

希望这个简写版的 Ceres 安装指南对那些不熟悉 CMake 的人有所帮助。

参考

[## Ceres 求解器——一个大规模非线性优化库

Ceres Solver [1]是一个开源的 C++库,用于建模和解决大型复杂的优化问题。它…

ceres-solver.org](http://ceres-solver.org/index.html) [## 安装- Ceres 解算器

您可以从最新的稳定版本开始。或者如果你想要最新的版本,你可以克隆 git 库 git…

ceres-solver.org](http://ceres-solver.org/installation.html) [## C++应用程序开发(第二部分— CMakeLists.txt)

如果你曾经做过一个比较大的 C++项目,那么你一定听说过这个工具。它可能看起来会做一些…

medium.com](https://medium.com/heuristics/c-application-development-part-2-cmakelists-txt-e415b5b387dc) [## CMake 教程- CMake 3.17.3 文档

CMake 教程提供了一个分步指南,涵盖了 CMake 帮助解决的常见构建系统问题…

cmake.org](https://cmake.org/cmake/help/latest/guide/tutorial/index.html)

如何在不到一小时的时间内用 Python 和深度学习创建聊天机器人

原文:https://towardsdatascience.com/how-to-create-a-chatbot-with-python-deep-learning-in-less-than-an-hour-56a063bdfc44?source=collection_archive---------0-----------------------

显然不要指望会是 Siri 或者 Alexa…

希望有一天 BB-8 会成为现实…

有些人真的不喜欢人际交往。每当他们被迫参加社交活动或有很多人参加的活动时,他们会感到孤立和尴尬。就我个人而言,我相信我是最外向的,因为我从与其他人的互动中获得能量。在这个地球上有很多人恰恰相反,他们在社会交往中变得非常疲惫。

我想起了一部非常独特的电影,叫做她(2013) 。这部电影的基本前提是,一个遭受孤独、抑郁、无聊的工作和即将离婚的男人最终爱上了他计算机操作系统上的一个 AI(人工智能)。也许在当时这是一个非常科幻的概念,因为那时人工智能还没有先进到足以成为代理人,但现在呢?2020?事情发生了很大的变化。我担心人们会放弃在人类中寻找爱情(甚至是社会交往),转而在数字领域寻找爱情。不相信我?我不会告诉你这是什么意思,但只要搜索一下术语畏缩* 的定义就可以了。*

对于一个简单的机器学习项目,这难道不是一个过于冗长的介绍吗?可能吧。既然我已经详细描述了这个世界上许多男人(和女人)有理由实际关注的问题,让我们换个话题,做些简单有趣的事情吧!

这是成品的样子。

漂亮简单的界面

显然,这个聊天机器人的反应极其有限

议程

  1. 图书馆和数据
  2. 初始化聊天机器人训练
  3. 构建深度学习模型
  4. 构建聊天机器人 GUI
  5. 运行聊天机器人
  6. 结论
  7. 需要改进的地方

如果你想更深入地了解这个项目,或者如果你想添加代码,查看一下 GitHub 库

图书馆和数据

运行这个项目所需的所有组件都在 GitHub 存储库中。您可以随意派生存储库并将其克隆到您的本地机器上。下面是组件的快速分类:

  • train_chatbot.py —将自然语言数据读入训练集并使用 Keras 顺序神经网络创建模型的代码
  • chatgui.py —基于模型的预测清理响应并创建与聊天机器人交互的图形界面的代码
  • classes.pkl —不同类型的响应类别列表
  • words.pkl —可用于模式识别的不同单词的列表
  • intents . JSON—JavaScript 对象的集合,列出了对应于不同类型单词模式的不同标签
  • chatbot_model.h5 —由 train_chatbot.py 创建并由 chatgui.py 使用的实际模型

完整的代码在 GitHub 库中,但是为了透明和更好的理解,我将遍历代码的细节。

现在让我们从导入必要的库开始。(当您在终端上运行 python 文件时,请确保它们安装正确。我使用 pip3 来安装包。)

我们有一大堆库,如 nltk (自然语言工具包),其中包含一大堆用于清理文本并为深度学习算法做准备的工具, json ,它将 json 文件直接加载到 Python 中, pickle ,它加载 pickle 文件, numpy ,它可以非常高效地执行线性代数运算,以及 keras ,这是我们将使用的深度学习框架。

初始化聊天机器人训练

现在是时候初始化所有存储自然语言数据的列表了。我们有我前面提到的 json 文件,其中包含“意图”。下面是 json 文件的一个片段。

典型的 json 格式

我们使用 json 模块加载文件并将其保存为变量 intents。

如果仔细观察 json 文件,可以看到对象中有子对象。例如,“模式”是“意图”中的一个属性。因此,我们将使用一个嵌套的 for 循环来提取“模式”中的所有单词,并将它们添加到我们的单词列表中。然后,我们将每对模式添加到我们的文档中,列出它们对应的标签。我们还将标签添加到我们的列表中,并使用一个简单的条件语句来防止重复。

接下来,我们将获取单词列表,并对其中的所有单词进行词汇化和小写。如果你还不知道的话, lemmatize 的意思是把一个单词变成它的基本意思,或者它的引理。比如“走”、“走了”、“走了”这些词都有同一个引理,就是“走了”。将我们的词语词汇化的目的是将所有的东西缩小到尽可能简单的程度。当我们实际处理这些词进行机器学习时,它将节省我们大量的时间和不必要的错误。这与词干非常相似,都是将一个屈折的单词缩减到它的基础或词根形式。

接下来,我们对列表进行排序,并打印出结果。好了,看起来我们要建立我们的深度学习模型了!

构建深度学习模型

让我们用变量 training 初始化我们的训练数据。我们正在创建一个巨大的嵌套列表,其中包含每个文档的单词包。我们有一个名为 output_row 的特性,它只是作为列表的一个键。然后,我们洗牌我们的训练集,做一个训练-测试-分裂,模式是 X 变量,意图是 Y 变量。

现在我们已经准备好了我们的训练和测试数据,我们现在将使用来自 keras 的深度学习模型,称为 Sequential。我不想用深度学习模型如何工作的所有细节来淹没你,但如果你好奇,请查看文章底部的参考资料。

keras 中的序列模型实际上是最简单的神经网络之一,一个多层感知器。如果你不知道那是什么,我不怪你。这里是喀拉斯的文档

这个特定的网络具有 3 层,第一层具有 128 个神经元,第二层具有 64 个神经元,第三层具有作为神经元数量的意图数量。请记住,这个网络的要点是能够预测给定一些数据的选择意图。

模型会用随机梯度下降进行训练,这也是一个非常复杂的课题。随机梯度下降比正常梯度下降更有效,你只需要知道这些。

在模型被训练之后,整个东西被转换成一个 numpy 数组并保存为 chatbot_model.h5.

我们将使用这个模型来形成我们的聊天机器人界面!

构建聊天机器人 GUI

同样,我们需要从文件中提取信息。

下面是一些函数,包含了运行 GUI 的所有必要过程,并将它们封装成单元。我们有 clean_up_sentence() 函数,它清理输入的任何句子。这个函数用在 bow() 函数中,该函数提取被清理的句子,并创建一个单词包,用于预测类别(基于我们之前训练模型得到的结果)。

在我们的 predict_class() 函数中,我们使用 0.25 的误差阈值来避免过多的过拟合。这个函数将输出一个意图和概率的列表,以及它们与正确意图匹配的可能性。函数 getResponse() 获取输出的列表并检查 json 文件,以最高的概率输出最多的响应。

最后,我们的 chatbot_response() 接收一条消息(将通过我们的 chatbot GUI 输入),用我们的 predict_class() 函数预测类,将输出列表放入 getResponse() ,然后输出响应。我们得到的是我们聊天机器人的基础。我们现在可以告诉机器人一些事情,然后它会作出回应。

有趣的部分来了(如果其他部分还不有趣的话)。我们可以用 tkinter 创建我们的 GUI,tkinter 是一个 Python 库,它允许我们创建自定义接口。

我们创建了一个名为 send() 的函数,它设置了聊天机器人的基本功能。如果我们输入到聊天机器人的消息不是空字符串,机器人将根据我们的 chatbot_response() 函数输出一个响应。

之后,我们构建聊天窗口、滚动条、发送消息的按钮和创建消息的文本框。我们用简单的坐标和高度将所有组件放置在屏幕上。

运行聊天机器人

终于是时候运行我们的聊天机器人了!

因为我在 Windows 10 机器上运行我的程序,所以我必须下载一个名为 Xming 的服务器。如果你运行你的程序,它给你一些关于程序失败的奇怪错误,你可以下载 Xming

在运行你的程序之前,你需要确保你安装了 python 或者 python3 和 pip(或者 pip3)。如果您不熟悉命令行命令,请查看下面的参考资料。

一旦你运行你的程序,你应该得到这个。

结论

祝贺您完成这个项目!构建一个简单的聊天机器人会让您接触到各种数据科学和一般编程的有用技能。我觉得学习任何东西的最好方法(至少对我来说)就是建造和修补。如果你想变得擅长某件事,你需要大量的练习,而最好的练习方法就是亲自动手去做。

需要改进的地方

感谢您花时间通读这篇文章!请随意查看我的作品集网站我的 GitHub

1.尝试不同的神经网络

我们用的是最简单的 keras 神经网络,所以有很大的改进空间。你可以在你的项目中随意尝试卷积网络或递归网络。

2.使用更多数据

就各种可能的意图和响应而言,我们的 json 文件非常小。人类语言比这要复杂几十亿倍,所以从头开始创建 JARVIS 需要更多的东西。

3.使用不同的框架

深度学习框架不只是 keras,还有很多。有 tensorflow,Apache Spark,PyTorch,Sonnet 等等。不要把自己局限在一个工具上!

资源

如何在 CodaLab 上创建你的第一个比赛

原文:https://towardsdatascience.com/how-to-create-a-competition-on-codalab-85d69580f9c8?source=collection_archive---------23-----------------------

很洒脱!

来源:istockphoto.com(作者购买)

组织一次挑战可以让你众包最困难的机器学习问题。这也是学习数据科学的绝佳方式。这份简短的实践教程将为你提供创建你的第一个竞赛所需的一切——就在今天!

为什么是 Codalab?

Codalab 是一个开源网络平台,举办数据科学竞赛。这意味着你可以建立自己的实例,或者使用 codalab.lisn.fr 上的主实例。Codalab 强调科学,每年都有数百项挑战发生在科学上,挑战许多领域的极限:物理、医学、计算机视觉、自然语言处理甚至机器学习本身。它的灵活性允许解决各种各样的任务!

一旦你有了账号,你就可以发布你的第一场比赛了!唯一的限制是你的想象力。

开始

要创建你的第一个机器学习挑战,你需要做的就是上传一个竞赛捆绑包。竞赛包是一个ZIP 文件,包含竞赛的所有部分:数据、文档、评分程序和配置设置。

先从一个例子说起;这是最简单的方法。这里是 Iris Challenge 的比赛捆绑,基于著名的 Fisher 的数据集;只需点击链接: Iris 竞赛捆绑

现在只需将名为“iris _ competition _ bundle . zip”的文件上传到 Codalab 中,如下所示:

转到“我的比赛”,然后是“我正在参加的比赛”,最后是“创建比赛”

就是这样!您的竞争对手已经准备好接受提交。

定制您的比赛

这很酷,但我刚刚重新创建了虹膜挑战。我想设计我自己的任务,包括我的数据集!—你

要定制您的比赛,您需要更改捆绑包中包含的文件并重新上传。让我们仔细看看包里有什么。

HTML 文件

HTML 文件定义了参与者在参加比赛时可以看到的各种页面。使用它们来提供文档和规则,以及您认为重要的任何信息。

Iris 挑战赛主页。网页是由包中的 HTML 文件定义的。

标志;徽标

把“logo.png”换成你酷炫的 logo!

Iris 竞赛包中的“logo.png”

数据

如果你在设计一个机器学习问题,很可能你已经有数据了。公共数据(或输入数据)文件夹用于参与者将访问的数据,参考数据文件夹用于地面真相,通常是来自测试集的您想要保密的标签。您可以使用与提供的示例相同的数据格式,或者您喜欢的任何其他格式。为了确保兼容性,您需要更新评分程序——我们将在下一节讨论它。

如果你的问题不涉及数据,不用担心!Codalab 非常灵活,可以根据您的需要定义您的问题(例如强化学习任务)。

摄取和评分计划

摄取和评分程序是你的竞赛代码的主要部分:它们定义了提交的内容将被评估的方式。如果你想只允许成绩提交,那么你只需要评分程序;摄取程序对于代码提交很有用。

  • 摄取程序:定义如何训练模型并保存它们的预测。
  • 评分程序:定义如何将预测与实际情况进行比较。

启动套件

如果你已经作为竞争对手参加了挑战,你就知道拥有一套好的出发装备有多重要。在这里,您只需包括参与者轻松投入挑战所需的一切:一些提交的示例、Jupyter 笔记本等。他们可以从网页“参与>文件”下载。

用户可以从网页“参与>文件”下载启动工具包

competition.yaml 文件

最后但同样重要的是,competition . YAML文件定义了你挑战的设置。标题、描述、Docker 图片(只需输入 DockerHub 名称,提交的内容将在其中运行)、日期、奖品等等。

编辑现有竞赛

你的比赛开始了!但是,您希望编辑它。还是有可能的。作为您自己挑战的管理员,您可以访问“编辑”菜单;点击如下按钮:

管理功能包括编辑现有的竞争

然后,您将访问一个面板,在这里您可以编辑每个设置。如果您希望更改数据集或评分程序,首先需要从“我的数据集”页面上传新版本。

走得更远

恭喜你!你知道如何在 Codalab 上创造竞争!然而,我们仅仅触及了软件提供的所有可能性的表面。想了解更多,可以参考 Codalab 的 Wiki 。例如,您将了解如何将您的个人计算机工作人员(CPU、GPU)联系起来,或者如何使用多个标准定义复杂的排行榜。你甚至可以加入努力,发展自己的特色!

来源:codalab.org

如何使用机器学习创建简洁的图像表示

原文:https://towardsdatascience.com/how-to-create-a-concise-image-representation-using-machine-learning-20156c1e0c19?source=collection_archive---------30-----------------------

Keras 中 HRRR 图像自动编码器的设计与训练

互联网上的 Autoencoder 示例似乎要么是关于玩具示例(MNIST,28x28 图像),要么是利用了 ImageNet 瓶颈层的迁移学习。我将向您展示如何从头开始训练自动编码器,如果您有足够的数据和完全不同于 ImageNet 组成的照片的数据,您将会这样做。

在之前的一篇文章中,我展示了如何获取天气预报图像并从中创建张量流记录,以使它们为机器学习做好准备。

在本文中,我将展示如何对这些图像执行一项机器学习任务:使用自动编码器从高分辨率快速刷新(HRRR)模型创建雷达反射率“分析”场的简明表示。HRRR 的图像是 1059x1799,看起来像这样:

在 Keras 中设计自动编码器

自动编码器由通常如下所示的体系结构组成:

自动编码器架构。来源:维基百科上的 Chervinskii(https://commons . wikimedia . org/wiki/File:auto encoder _ structure . png)

编码器试图将输入图像表示为一个更小的数字数组。解码器从代码中重建图像。整个模型被训练以最小化输入和输出的差异。

有几个陷阱需要注意:

  1. 代码(或嵌入)需要比输入小得多。否则,ML 模型可以简单地将输入像素复制到代码中。不会有一概而论。
  2. 具有一百万像素输入的参数数量可能会失控。传统上,减少参数数量的方法是使用卷积层。
  3. 然而,卷积层保留位置信息。所以,从本质上来说,这些层所做的就是让图像越来越模糊。为了超越单纯的模糊,你应该在每个阶段增加卷积滤波器中“通道”的数量。这样,您就可以在各层之间保存信息。
  4. 此外,你至少需要一个密集的连接,在图像的不同部分之间带来“远程连接”。我选择在创建嵌入时这样做。
  5. 仔细考虑你是否需要短路层,注意力等。这取决于您正在处理的图像类型和层数。在我的例子中,这些是带有很强的位置约束的地理图像。所以,我决定不使用这些伎俩。
  6. 减小卷积滤波器大小的方法是使用池层。在解码器中,相反的操作是进行上采样。

这是我最后的建筑:

让我们用代码浏览一下(完整代码在 GitHub 上)。第一层是输入层:

input_img = tf.keras.Input(shape=(1059, 1799, 1), name='refc_input')

我更喜欢大小是 2 的幂,这样更容易得到更小的层。我可以将 1059 一直填充到 2048,但裁剪到 1024 似乎更合理——无论如何,HRRR 图像的边缘分辨率都很差。因此,第二层是一个裁剪层:

x = tf.keras.layers.Cropping2D(cropping=((17, 18),(4, 3)), name='cropped')(input_img)

我们不知道需要多少个卷积层,所以让层数(nlayers)成为一个超参数。此外,我们将使过滤器的数量(或通道的数量)成为超参数,因为这控制了从一层到下一层传递多少信息。最后,poolsize 也将是一个超参数,因为它控制着图像大小从一层到下一层的缩减量:

 last_pool_layer = None
    for layerno in range(**nlayers**):
        x = tf.keras.layers.Conv2D(2**(layerno + **numfilters**), poolsize, activation='relu', padding='same', name='encoder_conv_{}'.format(layerno))(x)
        last_pool_layer = tf.keras.layers.MaxPooling2D(**poolsize**, padding='same', name='encoder_pool_{}'.format(layerno))
        x = last_pool_layer(x)
    output_shape = last_pool_layer.output_shape[1:]

我还确保捕捉最后一层,以便在嵌入层之前获得输出形状(原因将变得明显)。

一旦卷积层完成,我们可以让它通过一个密集层。我还将密集节点的数量(本质上是嵌入的长度)作为一个超参数:

 # flatten, send through dense layer to create the embedding
        x = tf.keras.layers.Flatten(name='encoder_flatten')(x)
        x = tf.keras.layers.Dense(**num_dense**, name='refc_embedding')(x)
        x = tf.keras.layers.Dense(output_shape[0] * output_shape[1] * output_shape[2], name='decoder_dense')(x)
        embed_size = num_dense

请注意,我是如何使用输出形状预嵌入来恢复解码器第一层中的原始展平长度的。

然后,我们一个接一个地颠倒操作。首先是对解码器进行整形,以获得最后一个 conv 池块的输出形状:

x = tf.keras.layers.Reshape(output_shape, name='decoder_reshape')(x)

然后,创建一个解码器模块,由长度相反的卷积和上采样组成:

for layerno in range(nlayers):
        x = tf.keras.layers.Conv2D(2**(nlayers-layerno-1 + numfilters), poolsize, activation='relu', padding='same', name='decoder_conv_{}'.format(layerno))(x)
        x = tf.keras.layers.UpSampling2D(poolsize, name='decoder_upsamp_{}'.format(layerno))(x)
    before_padding_layer = tf.keras.layers.Conv2D(1, 3, activation='relu', padding='same', name='before_padding')
    x = before_padding_layer(x)
    htdiff = 1059 - before_padding_layer.output_shape[1]
    wddiff = 1799 - before_padding_layer.output_shape[2]

我们在编码器中进行裁剪的地方,现在需要进行零填充:

before_padding_layer = tf.keras.layers.Conv2D(1, 3, activation='relu', padding='same', name='before_padding')
    x = before_padding_layer(x)
    htdiff = 1059 - before_padding_layer.output_shape[1]
    wddiff = 1799 - before_padding_layer.output_shape[2]
    decoded = tf.keras.layers.ZeroPadding2D(padding=((htdiff//2,htdiff - htdiff//2),
                                                     (wddiff//2,wddiff - wddiff//2)), name='refc_reconstructed')(x)

现在,创建自动编码器:

autoencoder = tf.keras.Model(input_img, decoded, name='autoencoder')
autoencoder.compile(optimizer='adam',loss=tf.keras.losses.LogCosh())

为什么是 LogCosh?因为我们做的是回归,而 LogCosh 对异常值的容忍度比均方差高。

编写培训师

一旦模型写好了,培训师(完整代码:检查一下)就成了样板。我们所有的图像都是 TFRecord,所以我们创建一个 TF record 数据集,创建模型并调用 model.fit。

创建 TFRecord 数据集:

def parse_tfrecord(example_data):
    parsed = tf.io.parse_single_example(example_data, {
        'size': tf.io.VarLenFeature(tf.int64),
        'ref': tf.io.VarLenFeature(tf.float32),
        'time': tf.io.FixedLenFeature([], tf.string),
        'valid_time': tf.io.FixedLenFeature([], tf.string)
     })
    parsed['size'] = tf.sparse.to_dense(parsed['size'])
    parsed['ref'] = tf.reshape(tf.sparse.to_dense(parsed['ref']), (1059, 1799))/60\. # 0 to 1
    return parseddef read_dataset(pattern):
    filenames = tf.io.gfile.glob(pattern)
    ds = tf.data.TFRecordDataset(filenames, compression_type=None, buffer_size=None, num_parallel_reads=None)
    return ds.prefetch(tf.data.experimental.AUTOTUNE).map(parse_tfrecord)

要创建模型并对其进行训练:

def run_job(opts):
    def input_and_label(rec):
        return rec['ref'], rec['ref']
    ds = read_dataset(opts['input']).map(input_and_label).batch(opts['batch_size']).repeat()

    checkpoint = tf.keras.callbacks.ModelCheckpoint(os.path.join(opts['job_dir'], 'checkpoints'))

    strategy = tf.distribute.MirroredStrategy()
    with strategy.scope():
        autoencoder, error = create_model(opts['num_layers'], opts['pool_size'], opts['num_filters'], opts['num_dense'])

        history = autoencoder.fit(ds, steps_per_epoch=opts['num_steps']//opts['num_checkpoints'],
                              epochs=opts['num_checkpoints'], shuffle=True, callbacks=[checkpoint, HptCallback()])

        autoencoder.save(os.path.join(opts['job_dir'], 'savedmodel'))

这里有几点:

  1. 我获取 TFRecord 并返回与输入和标签相同的反射率图像数据。这是因为我们正在进行自动编码。
  2. MirroredStrategy 将允许我创建一个具有多个 GPU 的机器,并获得快速的分布式训练。
  3. 我创建模型检查点(检查点是机器学习设计模式书中的设计模式之一;这有助于使分布式培训更有弹性)
  4. 在 fit()方法中,我处理了 steps_per_epoch 和 epoch 的数量。这是检查点模式的虚拟纪元变体。再次,阅读这本书,了解为什么这很重要。
  5. 因为我们正在进行自动编码,所以我不会为验证数据集而烦恼。我们越能接近地表现输入,就越好。

批量过装

像我一样设计一个模型架构的最佳实践是确保最终的架构足够强大,能够学习我们需要它学习的东西。做到这一点的方法是有用的过度拟合(我们书中的另一个模式)。基本上,取一个非常小的数据集(我用了 4 张图片)并在这个数据集上过度拟合模型。如果你能让误差变得非常小,那么这个模型就足够强大了。

所以,我是这么做的。我写了我的 ML 模型,然后我在超参数空间上做了网格搜索,并选择了最小的嵌入大小,这允许我尽可能完美地学习 4 幅图像(这不会是完美的,因为图像表示将是模糊的)。

因此,还有一个超参数回调:

class HptCallback(tf.keras.callbacks.Callback):
    def __init__(self):
        self.hpt = hypertune.HyperTune()

    def on_epoch_end(self, epoch, logs):
        self.hpt.report_hyperparameter_tuning_metric(
            hyperparameter_metric_tag='final_loss',
            metric_value=logs['loss'],   #history.history['loss'][-1],
            global_step=epoch
        )

我现在可以在谷歌云人工智能平台上进行培训:

gcloud ai-platform jobs submit training $JOB_NAME \
        --package-path $PACKAGE_PATH \
        --module-name $MODULE_NAME \
        --job-dir gs://${BUCKET}/wxsearch/trained \
        --region $REGION \
        --config hyperparam.yaml \
        --input gs://${BUCKET}/wxsearch/data/2019/tfrecord-00000-* \
        --project ${PROJECT} \
        --batch_size 4 --num_steps 1000 --num_checkpoints 4

结果,我发现这个架构已经足够了:

--num_layers 4 --pool_size 4 --num_filters 4 --num_dense 50

仅仅 50 个数字代表 100 万像素!

训练自动编码器

一旦我们决定了小批量超拟合的超参数,我们就可以采用该模型并在整个 HRRR 2019 数据集上训练它:

gcloud ai-platform jobs submit training $JOB_NAME \
        --package-path $PACKAGE_PATH \
        --module-name $MODULE_NAME \
        --job-dir gs://${BUCKET}/wxsearch/trained \
        --region $REGION \
        --config train.yaml -- \
       ** --input gs://${BUCKET}/wxsearch/data/2019/tfrecord-* \**
        --project ${PROJECT} \
        --batch_size 4 --num_steps **50000** --num_checkpoints 10

train.yaml 在哪里:

trainingInput:
  scaleTier: CUSTOM
  masterType: n1-highmem-2
  masterConfig:
    acceleratorConfig:
      count: 2
      type: NVIDIA_TESLA_K80
  runtimeVersion: '2.2'
  pythonVersion: '3.7'
  scheduling:
    maxWaitTime: 3600s

这以 0.0023 的最终损失结束,实际上甚至比微小数据集上的过度拟合损失更好。

后续步骤:

试用一下(GitHub 的所有链接)

  1. 从 HRRR 图像创建张量流记录: hrrr_to_tfrecord.sh
  2. [可选] Overfit batch 查找最佳超参数集:overfit_batch.sh
  3. 在 2019 年 HRRR 数据集上训练自动编码器: train_autoencoder 。嘘
  4. 在我的系列的下一篇文章中,我将展示如何采用训练好的模型,并为整个 2019 数据集创建嵌入。然后做一个嵌入,告诉你如何从中重建 HRRR 图像。

如何在 Power BI 中创建控制图

原文:https://towardsdatascience.com/how-to-create-a-control-chart-in-power-bi-fccc98d3a8f9?source=collection_archive---------6-----------------------

在本文中,我将向您展示如何在 Power BI 中构建动态控制图,帮助您的团队查明任何异常值或失控的流程。

随着公司实施精益六适马实践,跟踪流程如何随着时间的推移而变化是必不可少的。控制图可以帮助企业可视化一段时间内的过程测量。

控制图(图片来自 r-bar.net)

对于不知道什么是控制图的人来说,首先要做的是。

🚩控制图由 4 个主要特征组成:

  1. X 轴和 Y 轴数值:数据值为 Y 轴。这可以是客户数量、票据数量、收入、成本或企业想要测量的任何数据值。时间将是 X 轴。
  2. 中心线 ( 又名平均值):这是数据点的平均值。它在图表的中间部分用实线表示。
  3. 控制下限 (LCL):低于平均值,称为-3 sigma 线,作为下限。
  4. 控制上限 (UCL):高于平均值,称为+3 sigma 线,作为上限。

这是我在 Power BI 中创建的控制图(图片由作者提供)

🚩让我们从在 Power BI 中构建控制图开始

为了实现控制图的主要特性,我们首先创建一些 DAX 度量:

对于平均值计算,您只需使用 Average 函数。我们包含了 ALLSELECTED 函数,以便根据用户在日期切片器中的选择进行动态计算。

AVERAGE CASES = CALCULATE(AVERAGEX(CONTROL_CHART_DATE,[TotalCases]), ALLSELECTED(CONTROL_CHART_DATE))

为了得出 UCL 和 LCL,我们首先需要计算标准差。标准差的语法如下:

STDEV = CALCULATE(STDEVX.P(CONTROL_CHART_DATE,[TotalCases]),ALLSELECTED(CONTROL_CHART_DATE[DATE]))

现在我们有了标准差,我们可以在 UCL 和 LCL 语法中输入这段。

对于 UCL,我们将“平均案例”度量与“标准偏差”度量相加,然后乘以 3(因此,3 sigmas)。

Upper Control Limit (UCL) = AVERAGE CASES + [STDEV]*3

对于 LCL,我们的做法与 UCL 相反。我们用 STDDEV 度量值减去 AVERAGE CASES 度量值,然后乘以 3。

Lower Control Limit (LCL) = AVERAGE CASES - [STDEV]*3

用度量创建折线图:

一旦创建了这些度量,就创建一个折线图。将 LCL、UCL 和平均案例拖到数值中。选择轴的日期。

下面的操作应该可以让您了解控制图的主要组成部分。别忘了带上你的日期切片器。日期切片器将允许用户根据历史日期查看下限和上限。

现在是剩下的部分:在仪表板上添加当前数据。您需要创建另一个独立的日期表,用于第二个日期切片器。这两个数据表应该连接到从中获取主值的表。

创建第二个日期表后,使用该表添加一个日期切片器。

现在是有趣的部分。你们中的一些人可能想知道如何将当年的数据反映在一个使用历史数据的带有日期轴的图表上?

该解决方案是一个创造性的变通办法。创建另一个折线图,将日期 2 作为 x 轴,并将正在分析的值作为 Y 轴。如果折线图中没有显示任何值,那么拍拍自己的背,因为 Power BI 正在工作。您将需要编辑日期切片器和图表之间的交互,方法是选择一个日期切片器,然后单击格式选项卡下的编辑交互

现在,您想选择第一个日期,在我的例子中是“控制图日期”,并在第二个日期通过选择右边的圆形图标点击“无”。

选择第二个日期切片器,并通过选择右边的圆形图标确保第一个日期没有被过滤。

在第二个日期切片器上选中时,您会希望在您创建的最后一个折线图上单击过滤器,方法是选择左侧图标,该图标看起来像旁边带有过滤器的图形。

确保在带有控制件的第一个图表上选择“无”。通过这些交互,您应该会看到第二个折线图最终出现。

现在,我们实际上有一个影响控制图(UCL、LCL、平均值)的日期限幅器和一个影响图表的日期限幅器,在本例中,它包含总计值。

相应调整折线图格式:

那么,如何让图表上下重叠呢?单击第二个图表,将背景设置为透明,这样它就能清楚地显示在第一个图表上。将图表放在另一个的上面。

确保调整两个图表,使 Y 轴具有相同的刻度,否则总值可能无法调整到控制图的刻度。

通过按住 CTRL 键选择两个图表并单击视图下的锁定对象,将两个图表锁定在一起以保持格式,这样缩放就不会受到影响。

瞧啊。这就是最终的结果。我能够选择 2019 年和 2018 年的日期范围,这些日期范围会影响控制图,同时将其与我当前的 2020 年数据进行比较。

最终结果是一个控制图,您可以将当前数据与历史平均值、控制上限和控制下限进行比较。因为日期切片器和图表相互独立,所以您可以比较不同的日期范围,而不像 SAMEPERIODLASTYEAR 之类的函数将用户限制为只能比较去年的数据。

报告愉快,希望这个创造性的解决方案可以帮助其他 Power BI 开发人员更轻松地制作控制图!

娜塔莉·加尔塞斯是一名来自大西雅图地区的数据分析师。她获得了华盛顿大学的商业和 MSBA 学士学位。她写作并热衷于数据可视化、投资和所有科技方面的东西。

如何创建 R 中变量过多的相关矩阵

原文:https://towardsdatascience.com/how-to-create-a-correlation-matrix-with-too-many-variables-309cc0c0a57?source=collection_archive---------8-----------------------

有效地过滤掉不相关的变量,以查看更相关的结果。

我使用了 Kaggle 房价数据集,它有 79 个解释变量。在我的分析中,我试图查看所有变量之间的相关性,并意识到有太多的变量使任何典型的视觉辅助工具变得有意义。

我尝试了几种不同的软件包和工具,并决定我可以操纵 corrplot 做我最想要的事情。没有任何处理,这就是相关矩阵的样子。这显然是一种非常无益的视觉化。肯定有方法可以改变包中内置的视图,但是没有一种方法可以真正处理这么多的变量。

library(corrplot)df_cor <- cor(df)
corrplot(df_cor)

corrplot 中的初始图表

经过大量的反复试验和对堆栈溢出的清理,我能够创建一个函数来简化这个过程。首先,它会将所有变量转换成数值(如果还没有)。然后,它会丢弃重复项并完善相关性(与自身的相关性)。这些显然是没用的。

corr_simple <- function(data=df,sig=0.5){
  #convert data to numeric in order to run correlations
  #convert to factor first to keep the integrity of the data - each value will become a number rather than turn into NA
  df_cor <- data %>% mutate_if(is.character, as.factor)
  df_cor <- df_cor %>% mutate_if(is.factor, as.numeric) #run a correlation and drop the insignificant ones
  corr <- cor(df_cor)
  #prepare to drop duplicates and correlations of 1     
  corr[lower.tri(corr,diag=TRUE)] <- NA 
  #drop perfect correlations
  corr[corr == 1] <- NA  #turn into a 3-column table
  corr <- as.data.frame(as.table(corr))
  #remove the NA values from above 
  corr <- na.omit(corr)   #select significant values  
  corr <- subset(corr, abs(Freq) > sig) 
  #sort by highest correlation
  corr <- corr[order(-abs(corr$Freq)),]   #print table
  print(corr) #turn corr back into matrix in order to plot with corrplot
  mtx_corr <- reshape2::acast(corr, Var1~Var2, value.var="Freq")

  #plot correlations visually
  corrplot(mtx_corr, is.corr=FALSE, tl.col="black", na.label=" ")
}corr_simple()

接下来,它将设置数据框以查看表中的原始相关性,因为原始数据可能会有所帮助。数据帧首先按照最高相关性排序。

相关表

为了减少变量的绝对数量(无需手动挑选),只选择高于特定显著性水平阈值的变量。初始默认值设置为 0.5。

生成表格后,它将返回以下经过筛选的相关矩阵图。只有显著性水平足够高的相关性才会有彩色圆圈。如果仍然有许多剩余变量,这进一步有助于去除噪声。

使用 corr_simple 函数过滤掉有用的相关矩阵

结论

这个“corr_simple”函数可以在一些特征工程之后反复运行,或者具有不同的显著性水平。这确实有助于更快的分析和只查看相关数据。对于更多的变量,可能需要使用不同的显著性水平和/或使用更多的特征工程来减少相关变量的数量,然后重新运行函数,直到结果可读且有用。

如何创建自定义损失函数| Keras

原文:https://towardsdatascience.com/how-to-create-a-custom-loss-function-keras-3a89156ec69b?source=collection_archive---------2-----------------------

对于神经网络

照片由艾萨克·史密斯Unsplash 拍摄

损失功能是神经网络的重要组成部分之一。损失无非是神经网络的一个预测误差。计算损失的方法称为损失函数。

损耗用于计算神经网络的梯度。并且梯度被用于更新权重。这就是神经网络的训练方式。

Keras 有许多内置的损失函数,我在之前的一篇 博客 中提到过。这些损失函数对于分类和回归等许多典型的机器学习任务来说已经足够了。

但是可能有一些任务我们需要实现一个自定义的损失函数,我将在这篇博客中介绍。

开始之前,让我们快速回顾一下如何在 Keras 中使用内置损失函数。

使用内置损失函数

下面是一个使用内置损失函数的简单例子。

克拉斯损失函数

这里我们使用内置的分类 _ 交叉熵损失函数,它主要用于分类任务。我们在model.compile()方法中传递损失函数的名称。

创建自定义损失函数

我们可以简单地如下创建一个定制的损失函数。

定制损失函数

构建自定义损失函数时,您必须遵循以下规则。

  • 损失函数应该只有两个参数,即目标值(y_true)和预测值(y_pred)。因为为了测量预测中的误差(损失),我们需要这两个值。这些参数是在拟合数据时从模型本身传递过来的。
  • 损失函数在计算损失时必须使用y_pred值,如果您不这样做,那么梯度表达式将不会被定义,您将得到一个错误。
  • 然后你可以简单地将这个函数插入到model.compile()方法中来使用它。

小心数据维度

  • 参数y_truey_pred的第一维总是与批处理大小相同。例如- 如果您正在拟合批量为 32 的数据,并且您的神经网络有 5 个输出节点,那么y_pred的形状将是(32, 5)。因为会有 32 个输出,每个输出有 5 个值。
  • 损失函数应该总是返回一个长度为batch_size的向量。因为你必须返回每个数据点的损失。例如- 如果您要拟合批量为 32 的数据,那么您需要从损失函数中返回一个长度为 32 的向量。

为了更好地理解,我们来看一个例子。

示例|自定义损失函数

比方说,你为某个回归任务设计了一个神经网络,它输出一个长度为 2 的向量[x1, x2]

假设值x2x1更重要,你希望它真正接近目标值。对于这种情况,您可以创建一个定制的 MSE (均方差)损失函数,该函数对x2的预测误差比对x1的预测误差更不利。

MSE 损失函数

这里我用权重 0.3 和 0.7 乘以损失值,给第二个值,也就是x2,更多的惩罚。您可以根据自己的需要决定重量。

我还写下了代码片段中变量的形状。您可以看到最终损失的形状是(batch_size,),这意味着每个数据点有一个损失值。

现在你可以简单地将这个损失函数插入到你的模型中。

model.compile(loss=custom_mse, optimizer='adam')

注意

  • 我建议您使用 Keras 后端函数,而不是 Numpy 函数,以避免任何意外。Keras 后端函数的工作方式几乎类似于 Numpy 函数。

奖金

现在,您已经知道如何构建自定义损失函数。您也可以以完全相似的方式创建定制的评估指标。这里,我创建了一个平均绝对误差(MAE)指标,并将其插入到model.compile()方法中。

MAE 度量

如果你想理解尺寸的概念和形状的概念。你可以阅读下面这篇文章,我会在其中详细解释这些概念。

[## 了解轴和维度| Numpy |熊猫

知道如何沿数据的不同轴应用函数。

towardsdatascience.com](/understanding-axes-and-dimensions-numpy-pandas-606407a5f950)

如何创建数据科学产品组合—由数据科学家讲述

原文:https://towardsdatascience.com/how-to-create-a-data-science-portfolio-by-a-data-scientist-2aed3f473cf0?source=collection_archive---------17-----------------------

展示数据科学项目的网站

尼古拉斯的作品集网站

读者您好,
我希望每个人都保持安全洗手。真的是在这样的时候,精神和身体健康对我们的前进极其重要。

正如我在之前的文章中提到的,
数据科学不会与经济发生碰撞。
数据行业仍然有需求,有些人甚至会说,由于环境的原因,现在需求很大。当事情开始变得棘手时,企业主开始向我们求助。

来源: reddit

也就是说,对数据科学职业的兴趣仍然很高。人们想进入这个领域,我明白。谁不想被称为 21 世纪最性感的工作?

21 世纪最性感的新工作,数据科学家——LinkedIn

然而并不全是彩虹和鲜花。你必须面对一些艰难的筛选和面试,那些你不知道会发生什么的面试。我已经在这里写下了所有的内容。看一看。

[## 数据科学面试问题—初学者指南

在数据科学面试中,你应该期待什么样的问题?

towardsdatascience.com](/data-science-interview-questions-beginners-guide-7b3034373ccb)

作为一个已经在这个领域工作了两年的人,我给我的初级数据科学家同事的第一个建议是拥有一个数据科学组合。没有什么比拥有一个展示你所有作品的网站更好的了。雇主会立刻对你的工作和专业素养有所了解,让你在获得这份工作时有额外的优势。

有趣的是,我是一个真正的伪君子。我自己没有投资组合,直到现在。

gif by chuber

等等,我有很好的理由来解释为什么我不得不推迟制作我的个人投资组合网站。先别生气。

有一个稳定的朝九晚五

我知道。我知道。谁没有呢?我不希望这成为“我没有足够的时间”的借口。然而,我必须平衡我的日常工作,同时也在媒体上写作。在过去的一年里,我已经写了 20 多篇文章。技术报道的制作并不简单。产生干净的代码并用通俗易懂的语言向读者解释需要时间。我会说这几乎就像一个侧面的骗局。

gif bybig brotherafterdark

网络开发新秀

我是一名精算毕业生。实习期间掌握了 SQL
我在做数据科学家期间,掌握了 Python 。在这么短的时间内,我能学的语言就这么多。

我全心全意地想用我自己写的代码来制作我的作品集网站。有好几个选择,比如 Wix 和 Squarespace,你可以简单地在运行中建立自己的网站,但是我更喜欢自己做。

说到这里,我的网站运行在 HTMLCSS、Javascript 上。我不得不自学所有的语言,这需要一些时间。

没有值得骄傲的工作

这个很有意思。作品集网站的唯一目的就是展示你的作品,但是如果你没有作品可以展示呢?

当你刚刚开始你的职业生涯时,这更令人沮丧。是的,你可以展示自己发起的项目,但是雇主喜欢看你在真实环境中的实际成就。此外,我对自己的工作感到自豪。我不会展示我不引以为豪的东西。

我花了很多时间来积累出色的工作。我越专注于我的工作,我做的工作就越多,因此就有了延迟

我的投资组合网站

[## 尼克的作品集

你好,我叫梁家杰。我是一名数据科学家,目前在一家在线分类广告技术公司工作。在我的…

nickefy.github.io](https://nickefy.github.io/porfoliosite/)

这是我的网站的样子。
简单明了,开门见山。

有 5 个主页。

主页

登录页面。你的名字总是被期待在这里。这个页面为整个网站定下基调。我已经默认使用一个设计,在中间有一些巨大的文本来吸引注意力。
我的名字和激情在这里展示。没什么。

投资组合

在这个页面上,我展示了我所有的作品,以及适当的文档代码。我只包括我认为有价值的项目。我还努力包含了各种各样的项目。我有项目在

  • 机器学习
  • ETL/ELT 管道
  • 数据可视化
  • 数据分析

这些都与数据科学有关。我很感激能够接触到许多类型的项目,这让我能够展示我工作中的多样性。各种各样的项目展示了我在数据方面的技能,从工程到可视化。它有助于设定对雇主的期望。

确保到文档代码的链接做得很好并且正常工作。你的代码应该是可读的。我们不期望雇主理解守则,但我们希望在面试时用通俗易懂的语言向雇主解释我们的守则。

确保在代码中包含注释空格和适当的缩进,以表明你知道自己在做什么。你永远不知道谁会阅读你的代码,可能是从产品经理到高级软件工程师。因此,请保持你的代码整洁和专业。

关于

关于部分。在这里,你可以讲一点关于你的故事。介绍你自己,谈谈你的激情、目标和成就。相反,雇主想知道他们在雇佣谁。

站在他们的角度想想。你会雇佣一个你一无所知的人吗?还是对自己的工作充满热情的人?公司是由人组成的,人们想知道他们在和谁一起工作。个性是你想在这里展示的,尽量简短。

出版物

这是我的额外部分。作为一名媒体作家,我有出版物可以炫耀。我写我感兴趣的东西,我想表现出来。再一次,这是为了显示我对工作的热情。

这也很容易成为话题的引子。雇主可能会问,你参与过自己的项目吗?你可以回答说,是的,我已经写了关于它的一切,你可以在这里找到它。这当然比只是说说要好,因为雇主可以实际看到你做了什么。

接触

浏览完网站后,你已经给访问者留下了好奇心。他/她想更多地了解你,甚至想和你一起工作。这一部分提供了联系你的方法,以便他们能进一步发展这种关系。

gif by 原稿

密码

我用 HTMLCSS、Javascript 对网站进行编码。
我用了 Bootstrap 一个免费和开源的 HTML CSS 框架来提供响应式布局。完成这个项目后,我发现 bootstrap 非常容易使用,因为它为你的网站提供了响应能力,你需要做的就是给元素分配正确的 CSS 类。这里有一个例子。

<div class="col-sm-4 col-xs-12>
    <p>Apache Airflow</p>
</div>

我在这里定义了一个 div,在这里我为每个项目插入了标题文本。
Bootstrap 的工作方式类似于网格系统,它将浏览器页面划分为页面上的行和列。设置类col-xs-12col-sm-4告诉浏览器,当屏幕很小时,这个 div 应该占据 4 列的宽度。当屏幕特别小时,它应该占据 12 列,这几乎是整个页面。

这意味着对于一个普通的桌面窗口,这个 div 将占据浏览器页面的 1/3。当你用手机浏览页面时,div 会展开并占据整个页面。这非常有用,因为你会希望一些元素在手机上显示得更大,因为这样看起来更好。

这是我的项目卡片在桌面上的样子。

项目卡(桌面)

这是我的项目卡在手机上的样子。

项目卡(手机)

巨大的差异。确保网页的手机版看起来不错是非常重要的,因为谷歌声称 70%的流量来自手机。在我看来, Bootstrap 是一个很好的起点,如果你想尝试 web 开发,因为它简单易学,容易实现,资源丰富。

java 描述语言

我还使用 javascript 在网站上添加一些动画、平滑滚动和页面导航。当你滚动到投资组合部分时,你看到的最明显的是淡入。

项目卡动画

这些动画很好,但不是必需的。这当然让网站看起来更漂亮,但是如果你在短时间内负担不起学习 Javascript 的费用,那就以后再来。你可以把整个网站布局好,以后再添加动画。

主办;主持

我使用 Github 页面 托管站点。
Github Pages 提供免费的解决方案来展示你的网站,而无需设置任何服务器和数据库。它在 git repo 的特定分支中查找项目内容。它还会为你生成一个唯一的网址,这样你就不必购买域名了。下面是怎么做的。

进入你的 Github 库->设置-> Github 页面->选择分支。在我的例子中,我只有一个主分支,所以这就是我运行的内容。

如果 SEO 是你的顾虑之一,我建议不要使用 Github 页面。
如果你想在谷歌上被发现,你会想要建立自己的域名,并手动建立搜索引擎优化。Github 页面有专门的搜索引擎优化插件,但是我不能保证它的有效性。我以前试过 WIX SEO ,它要复杂和有效得多。

恭喜

照片由 Cytonn 摄影Unsplash 上拍摄

现在我们有了。
建立自己的数据科学组合的简单、免费且有效的方法。

你基本上已经完成了向世界展示你有多有才华的第一步。剩下的其实就是做工作了。

此外,这是非常酷的。

在你走之前

我们的数据之旅还没有结束。在这个行业缺乏人才的情况下,用适当的数据和机器学习知识来教育自己将使你在获得数据角色方面具有优势。敬请关注,我正在撰写关于更多数据科学项目,以及更多数据行业的故事、指南和经验。与此同时,请随意查看我的其他文章来暂时填补您对数据的渴望。

像往常一样,我引用一句话作为结束。

世界是一个大数据问题。安德鲁·迈克菲,麻省理工学院项目的联合主任

订阅我的时事通讯,保持联系。

也可以通过 我的链接 注册一个中等会员来支持我。你将能够从我和其他不可思议的作家那里读到无限量的故事!

我正在撰写更多关于数据行业的故事、文章和指南。你绝对可以期待更多这样的帖子。与此同时,你可以随时查看我的其他 文章 来暂时填补你对数据的渴望。

感谢 的阅读!如果你想和我联系,请随时通过 nickmydata@gmail.com 联系我或者我的 LinkedIn 个人资料 。你也可以在我的Github中查看之前写的代码。

如何创建数据科学作品集网站

原文:https://towardsdatascience.com/how-to-create-a-data-science-portfolio-website-dcba6bf00994?source=collection_archive---------16-----------------------

从头开始构建和部署您自己的数据科学组合网站

照片由阿毛里·梅希亚在 Unsplash 上拍摄

如果你像我一样是一名有抱负的数据科学家,你已经知道拥有一个突出的数据科学组合的重要性。

您参加了在线课程,获得了一些技能,并参与了数据科学项目。你也偶尔写博客,展示你在 Medium 上的工作。

所有这些都会让你的简历看起来很棒。然而,在你的简历上放多个链接是很麻烦的,可能会让招聘人员很难找到并正确理解你的工作。

我强烈建议建立一个数据科学作品集网站,展示你所做的所有工作。当潜在的雇主正在寻找雇员时,他们所要做的就是点击你的网站链接来了解你的一切!

拥有自己的网站肯定会让你在找工作时更有优势,也是讲述自己故事的好方法。

本·科尔德在 Unsplash 上的照片

我一直在考虑为自己创建一个数据科学网站,几天前终于开始着手做了。以下是给你的一些建议:

从头开始构建

当决定创建一个数据科学组合网站时,我不确定是否要从头开始构建它。

作为数据科学家,我们的重点不是网页设计,而是开发模型。我们也不太熟悉 HTML 之类的标记语言,使用 Wix 之类的网站构建器要快很多。

但是,我决定以此为契机,学习一些网页设计,并决定使用 HTML,CSS 和 Jquery 从头开始构建。

从头开始构建也给了我很大的自由来定制我的网站,使它看起来完全像我想要的那样。如果你有时间,我建议你也从头开始。

学习新东西总是很有趣的!

此外,从头开始构建并不一定意味着你必须自己绘制出整个设计并写出 HTML 的每一行。我强烈推荐使用 Bootstrap ,一个开源的 HTML CSS 框架用于你的布局。

这将给你的网站一个响应性的设计和结构,你可以很容易地使用它。

以下是我发现的一些有用的教程:

  1. 如何用 HTML 和 CSS 制作网站
  2. 如何创建作品集画廊
  3. 用 HTML 和 CSS 编写一个时尚的作品集设计

您也可以使用具有漂亮、响应性设计的模板。HTML、CSS 和 Jquery 都为您提供了。你所要做的就是调整代码来满足你的需求。

一些我认为不错的模板:

  1. W3 CSS 模板
  2. 作品集网站模板
  3. 面向所有创意专业人士的 38 个免费作品集网站模板

一些参考网站获取灵感:

  1. 朱莉娅·尼库尔斯基的数据科学作品集
  2. 大卫·文丘里的数据科学作品集
  3. 我的数据科学作品集(我仍在调整和添加新的部分,并在此过程中学习新的东西)。

然而,比你的布局更重要的是你的内容。如果你只有一次机会给潜在雇主留下深刻印象,你会展示什么?

所有让你脱颖而出的地方都要突出出来。你最热衷于什么?为什么是数据科学?你拥有的最重要的技能是什么?你做过什么重要的项目吗?

这里有一个关于如何构建你的网站的建议:

  1. 首页:这是人们访问你的网站时看到的第一页。确保它能吸引人们的注意力,并提供一些关于网站内容的信息。例如:

作者图片

作者图片

作者图片

这是一个有三个页面的响应滑块,我用 Bootstrap 为我的主页创建的。

2.关于:这是你讲述自己故事的部分。简要描述你的技能、兴趣以及你能带来什么。保持简洁明了!

3.项目:这可能是最重要的一个板块。作为一名有抱负的数据科学家,我们中的许多人可能没有在大公司展示技能的工作经验。

这就是项目发挥作用的地方。它们是展示您作为数据科学家所获得的技能的绝佳方式。这样,你不仅是在告诉人们你有技能,而且是在展示给他们看。

我建议在这部分只展示有有趣发现的独特项目。不要把你刚开始做的简单项目,没有故事可讲的项目,或者其他人都在做的项目放在上面。

一些你不应该添加到你的投资组合中的项目的例子:泰坦尼克号卡格尔竞赛,鸢尾花数据集,MNIST 数字分类与张量流。

这些不会帮助你的简历脱颖而出,这正是你应该避免的。

此外,试着增加一些能帮助你展示各种技能的项目。例如,包括展示您在以下方面技能的项目:

  • 数据收集
  • 数据预处理
  • 数据可视化
  • 数据分析
  • ETL 管道
  • 机器学习

展示你在所有这些领域的能力将让招聘人员了解你能完成的各种任务。

例如:

作者图片

以上是我添加到我的作品集网站的一个项目的例子。我在媒体上发表了一篇关于我的项目的博文,并将代码放在 Github 中。

我把它们都链接到了我的网站上,并附上了我的项目简介。

4.认证:如果你是一名有抱负的数据科学家,但没有扎实的教育背景(比如数据科学的硕士或博士),那么你必须自学。

在你的作品集上添加任何在线课程、MOOC 或证书。这将显示你对学习这门学科的奉献精神。

5.技能:这是你告诉潜在雇主你能做什么的部分。添加您在此过程中获得的所有技能,如数据辩论、分析和可视化。

您可以用您在前面部分展示的项目来支持这些技能,以进一步突出您带来的东西。

6.联系:让潜在雇主尽可能容易地与你联系。在网站底部添加您的联系方式。

最后,在你的简历上添加你想添加的所有内容的链接。提供你的 Kaggle、LinkedIn、Github 或 Medium 个人资料的链接,以便于访问。

部署您的网站

托管网站的传统方式是首先购买一个域名。然后,你需要选择一个主机提供商,并上传你的网站。

一些受欢迎的虚拟主机提供商包括 Bluehost 和 T2 host gator,你可以查看他们的价格计划。

对于我的作品集网站,我决定使用 Github 页面作为主机。它是完全免费的。你不需要购买域名,它会为你生成一个网址。我的是:https://natassha.github.io/natasshaselvaraj/

如果你选择在 Github 页面上托管你的站点,你会发现 这个 教程很有用。你所需要做的就是创建一个新的存储库,并将你的代码添加到其中。

Github pages 将直接从您的存储库中获取文件,通过构建过程运行它,然后发布它。

还有…就是这样!

现在,您已经了解了如何创建和部署自己的数据科学产品组合。如果你有时间并且有兴趣学习新的东西,你一定要试一试。

从头开始创建自己的网站(即使只是一个简单、静态的网站)可能是一个令人沮丧且耗时的过程。

但是,我觉得满足感是值得的。另外,你现在有了一个展示你技能的新的很酷的方式,这很棒。

如何使用 Fastai-v2 为多光谱卫星图像分割创建数据块

原文:https://towardsdatascience.com/how-to-create-a-datablock-for-multispectral-satellite-image-segmentation-with-the-fastai-v2-bc5e82f4eb5?source=collection_archive---------9-----------------------

通过简单的编码和 Fastai 的深度学习 API,在您的地球观测任务中享受最先进的结果。

Jirau 水库(巴西)水域像素分割示例,使用 U-Net 架构和 Fastai-v2。

更新

关于课程科学家 Python 入门 ( 可在 YouTube ) 和其他类似文章的信息,请访问我的网站cordmaur.carrd.co

介绍

Fastai 是一个开源的深度学习库,它为 PyTorch 添加了更高级别的功能,并且更容易通过少量编码实现最先进的结果。

当我们需要快速创建图像数据集、应用数据扩充、调整大小、裁剪甚至覆盖分割蒙版时,视觉模块非常方便(图 1)。然而,所有这些简化都是有代价的。这些用于计算机视觉的高级 API 大多针对 RGB 图像进行了优化,这些图像库不支持多光谱或多通道图像。

图 1- Fastai 在分割任务上叠加遮罩的例子(来源:https://www.fast.ai/images/fastai_paper/show_batch_seg.png

近年来,由于数据可访问性的增加,地球观测研究人员一直非常关注深度学习技术,如图像识别、图像分割、物体检测等。[1].问题是卫星图像通常由许多不同的光谱带(波长)组成,不适合深度学习社区使用的大多数视觉库。出于这个原因,我直接与 PyTorch 一起工作来创建数据集(这里)并训练“自制”的 U-Net 架构(这里)。

随着 Fastai-v2(承诺在下周发布)[2]的即将到来,我想测试一下是否有可能使用它的数据块结构来创建一个多光谱图像数据集来训练 U-Net 模型。这比我以前的故事更高级,因为我们必须创建一些自定义子类,但我试图尽可能简单。包含所有代码的笔记本在 GitHub 项目中可用(笔记本此处)。

在我们开始之前,有必要按照 https://dev.fast.ai 上的安装指南安装 fastai2 库。

步骤 1 —准备数据

为了继续,我们将需要一些多光谱图像的训练补丁。这可能是一个 Kaggle 数据集,就像这个故事中使用的 38 云数据集一样,或者是一个全新的数据集。在故事使用谷歌地球引擎(GEE)为卫星(Sentinel 2)图像的深度学习图像分割创建训练补丁中,我展示了如何从谷歌地球引擎创建训练补丁,并将它们作为 NumPy 数组使用。

对于本教程,我在 GitHub 资源库(https://github.com/cordmaur/Fastai2-Medium),/data文件夹下的中提供了一些来自巴西 Orós 水库的示例补丁。数据被保存为 NumPy 的数组,并被分为两个文件夹/data/images用于多光谱补丁和/data/labels用于目标遮罩。

Checking number of files - images:40      masks:40
Checking shapes - image: (13, 366, 366) mask: (366, 366)

正如我们从输出中看到的,图像被裁剪为 366x366 像素,训练面片有 13 个通道。这是按顺序排列的 12 个 Sentinel-2 波段,我添加了一个额外的波段来表示“无数据”标志。通道被放在第一个轴上,因为这是 PyTorch 和 Fastai 的标准,与其他图像库不同。遮罩值为 0-无水,1-水和 2-水阴影。我们将使用 Matplotlib 检查一个图像样本。为此,我们需要使用 Numpy.transpose 将通道轴移动到最后一个位置,并选择相应的红色、绿色和蓝色轴。

代码输出

步骤 2——子类化TensorImage

现在我们已经检查了我们的图像,我们需要一种在 Fastai 中打开它们的方法。由于 Fastai 使用的是 Python 图像库(PIL ),它无法处理这样的多光谱图像。然后,我们将从原来的TensorImage 继承一个名为MSTensorImage 的新类,它能够打开.npy扩展并可视化地显示它。让我们来看看代码。

首先,我们定义一个打开 Numpy 数组并将其作为给定类返回的函数(open_npy 函数)。

然后,我们用一个create方法定义了MSTensorImage类,该方法接收文件名(或 numpy 数组,或张量)、所需的通道(如果我们不想加载所有 13 个通道的话)和一个指示通道是否在第一轴的标志。

最后,我们定义了一个显示方法来正确显示该图像。我们可以向 show 方法传递不同的通道来创建假彩色合成和 Matplotlib 轴,以便进行多重显示。在下面的例子中,我们可以看到图像被正确加载和显示。

代码输出

步骤 3 —张量掩码类

为了处理掩码,我们将使用已经在 Fastai2 中定义的TensorMask 类,而不是像以前那样创建一个新类。在这种情况下,唯一的区别是TensorMask不知道如何打开.npy 扩展。在这种情况下,我们将通过新定义的open_npy 函数的结果来创建它,就像这样。

代码输出

步骤 4-创建数据块

DataBlock 是一个抽象,为您的源数据提供转换以适应您的模型。记住,为了训练神经网络,我们必须为模型提供一组输入(x)和相应的目标(y)。成本和优化函数会处理剩下的事情。更复杂的架构可能有多个 x 作为输入,甚至多个目标,所以DataBlock 接受多个管道(图 2)。

图 2:数据块简化示意图。在本例中,我们获取第四个项目(项目 4)。

在我们的例子中,这是最常见的,我们需要创建一个DataBlock ,它只提供两个块,Xs 和 Ys。对于每个块,我们可以创建一个TransformBlock (就像一个处理管道)来操作每个组(Xs 或 Ys),直到它们达到加载到模型中所需的格式。

为了创建一个DataBlock,除了TransformBlocks之外,我们还必须提供一个函数负责获取给定来源的项目。在我们的例子中,由于文件已经保存在磁盘中,get_items 函数将只读取目录并返回文件名。文件列表将是我们转换管道的起点。

如果遮罩是从同一原始文件创建的(例如,如果遮罩是第 14 通道),则 X 变换管道将负责排除该通道,而 Y 变换管道将负责从原始图像中提取该信息。由于我们将文件分开保存,我们将提供一个名为get_lbl_fn的新函数,它将接收图像文件的名称,然后返回相应目标文件的名称。现在我们对数据块有了一些了解,让我们来看看代码。

最后一个命令DataBlock.summary,将检查是否一切正常,并给我们一个数据样本:

Setting-up type transforms pipelines
Collecting items from Data\images
Found 40 items
2 datasets of sizes 36,4
Setting up Pipeline: partial
Setting up Pipeline: get_lbl_fn -> partial

Building one sample
  Pipeline: partial
    starting from
      Data\images\Oros_1_19.npy
    applying partial gives
      MSTensorImage of size 13x366x366
  Pipeline: get_lbl_fn -> partial
    starting from
      Data\images\Oros_1_19.npy
    applying get_lbl_fn gives
      Data\labels\Oros_1_19.npy
    applying partial gives
      TensorMask of size 366x366

Final sample: (MSTensorImage: torch.Size([13, 366, 366]), TensorMask([[0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        ...,
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.]]))

Setting up after_item: Pipeline: AddMaskCodes -> ToTensor
Setting up before_batch: Pipeline: 
Setting up after_batch: Pipeline: 

Building one batch
Applying item_tfms to the first sample:
  Pipeline: AddMaskCodes -> ToTensor
    starting from
      (MSTensorImage of size 13x366x366, TensorMask of size 366x366)
    applying AddMaskCodes gives
      (MSTensorImage of size 13x366x366, TensorMask of size 366x366)
    applying ToTensor gives
      (MSTensorImage of size 13x366x366, TensorMask of size 366x366)

Adding the next 3 samples

No before_batch transform to apply

Collating items in a batch

No batch_tfms to apply

正如我们在结果中看到的,在处理完所有转换后,最终的样本由一个包含两个项目(X,Y)的元组组成。在我们的例子中(MSTensorImageTensorMask)。

最终-数据集和数据加载器

一旦我们完成了DataBlock的创建,那么DataSetDataLoader的创建就非常简单了。考虑到拆分器功能(在我们的例子中,随机拆分器有 10%用于验证),数据集将被拆分为训练和验证数据集,并且可以通过订阅直接访问数据:

代码输出

同样适用于DataLoaders。此外,show_batch方法自动理解我们正在执行分割任务(因为 TensorMask 类),并覆盖 Xs 和 ys:

代码输出

结论

在今天的故事中,我们看到了基本概念以及如何使用 Fastai 2 的DataBlock来准备多光谱卫星数据,以适应深度学习模型。TensorImage 类的子类化和open_npy 函数的使用足以处理多个通道。可以注意到,Fastai 创建数据加载器和显示批处理样本的基本功能被成功地保留了下来。

使用 Fastai 2 执行这些地球观测任务非常方便,与 Fastai 1 和其他高级 API 不同,Fastai 2 的内置视觉架构接受输入通道作为参数。但这是下一个故事的主题。

GitHub 资源库https://github.com/cordmaur/Fastai2-Medium提供了遵循该“操作方法”的笔记本和示例数据。

下一个故事再见。

参考

[1]t .赫泽,库恩泽,c .,2020 年。利用对地观测数据的深度学习进行目标探测和图像分割:综述-第一部分:发展和最近趋势。遥感 121667。https://doi.org/10.3390/rs12101667

[2]霍华德,j .,古格,s .,2020 年。fastai:深度学习的分层 API。信息 11108。【https://doi.org/10.3390/info11020108

如何通过云计算从 Twitter 中提取数据

原文:https://towardsdatascience.com/how-to-create-a-dataset-with-twitter-and-cloud-computing-fcd82837d313?source=collection_archive---------22-----------------------

通过使用 Python 和 Tweepy 库。

照片由 Unsplash 上的 dole777 拍摄

对于有抱负的数据分析师和数据科学家来说,Twitter 是一个很好的信息来源。它也是辩论和争论的场所。此外,Twitter 可以成为文本数据的良好资源;它有一个 API,凭证很容易获得,并且有许多 Python 库可以帮助调用 Twitter 的 API。

建立投资组合的一种方式是获得自己的自然语言处理项目,但就像每个项目一样,第一步是获得数据,然后通过使用亚马逊网络服务(AWS)将这些数据保存在本地计算机或云上。

总的来说,建立这个管道的资源是很棒的,但是它们有一些很容易让人头疼的怪癖。在本文中,我将向您展示如何建立一个简单的管道流程,并帮助您浏览该流程,避免那些令人头痛的问题。考虑这篇文章你的赛前泰诺!

这很好,对吗?所以,坚持住。

通过四个步骤,我将演示如何建立下面的管道。第一步包括使用来自 Twitter 的 API 收集数据,然后向您展示如何启动 EC2 实例,将其连接到 kinesis,最后使用 Python 脚本将数据传输到 AWS 上的 S3(数据湖)。

从 Twitter 到 S3 的管道

你准备好掌握所有这些了吗?

第一步:在 Twitter 上建立你的开发者账户,并获得你的证书

给自己弄一个账号:一个 Twitter 用户账号是拥有一个“开发者”账号的要求,所以要么注册一个新账号,要么登录一个现有账号,简直易如反掌。

创建 app:https://developer.twitter.com/en/apps注册 app。设置好之后,转到“令牌和密钥”来生成访问令牌和秘密令牌。连同消费者 API 密钥(已经生成),这些是我们将用来与 Twitter API 通信的凭证。我也将这些凭证用于 Python 脚本。我建议将凭证保存在文本文件中,因为我们将在后面的阶段使用这些凭证。

步骤 2:创建一个 AWS 帐户

在这个项目中,你需要使用来自亚马逊的三个不同的服务: EC2 实例Kinesis (数据流)和 S3 (数据湖)来建立管道。您需要创建一个帐户,并在此帐户下注册您的信用卡;亚马逊根据你对服务的使用情况收费。关于费用,不用担心。你在这个项目中使用的服务并不昂贵;在我的项目中,我每月花费不到5-6 加元。如果你需要使用其他服务,我建议你事先检查一下费用。请注意,偶尔查看一下您的账单总是一个好习惯,以确保您不会对此感到惊讶,并且如果您不再需要它,不要忘记终止服务或实例。

首先,在 EC2 管理控制台中,创建一个私钥对,您将使用它来设置 EC2 实例。此外,在接下来的步骤中,正确设置“安全组”以允许您的 IP 进行 SSH 访问。

接下来,通过 7 个步骤启动一个 EC2 实例。在我的项目中,我使用了一个简单的 t2.micro,它足以提取 tweets,你可以只使用一个实例,大小为 8gb。如果你想知道更多关于如何建立 EC2 的细节,我建议你看看下面 Connor Leech 的这篇好文章。请注意,您的第一年 EC2 t2.micro 实例将是免费的,直到达到某个阈值。

[## 如何启动 Amazon EC2 实例

在这篇文章中,我们将在 Amazon Web Services 托管的云中创建一个 Linux 虚拟机。我们打算…

medium.com](https://medium.com/employbl/how-to-launch-an-ec2-instance-de568295205d)

EC2 实例是一个处理器或 CPU,在这个项目中,我们通过使用 python 脚本来收集数据(我将在下面解释)。

EC2 实例是一个处理器或 CPU,在这个项目中,您的实例通过使用 Python 脚本从 Twitter 中提取数据来收集数据(我将在下面解释)。

S3 是一个数据湖,对于阅读本文的新手来说,这是存储由 EC2 实例收集的原始数据的服务。在我的项目中,我决定让我的 S3 公开,以便连接其他软件,比如 Apache Spark,并减少访问问题。我知道这不是最好的做法,因为其他人可以访问你的数据,但在这个项目中,这是可以的,我不处理敏感数据。

亚马逊 Kinesis 数据流 (KDS)是一个极具扩展性和可持续性的实时数据交付服务。该服务是 EC2 实例和 S3 之间的“管道”。因此,在设置此服务的过程中,您需要将其链接到您的 S3,方法是指明存储桶(即文件夹)的名称,并指明您希望如何保存收集的数据。

一旦所有的服务都准备好并链接起来,我们就可以进入下一步了。

第三步:了解 API 和 Tweepy

Twitter 上关于 API 的文档相当不错,但是对于该领域的初学者来说可能有点混乱。我有几个问题要理解 API 是如何工作的,我希望您在阅读完这一部分后会清楚。

您可以在下面的链接中找到开展这个项目的大部分信息:

[## 推文更新

本文档概述了开发者对已经到位的 Tweets 的更改的指导,以允许人们…

developer.twitter.com](https://developer.twitter.com/en/docs/tweets/tweet-updates)

Twitter 的 API 允许你提取不同的数据字段,包含每个用户的推文内容、用户名、位置、日期和关注者数量。在这个项目中,我将提取所有这些字段。

为了提取推文,你需要我们使用 Tweepy 包。这是一个 Python 库,可以方便地使用 Twitter API。首先,您需要使用之前创建并存储在文本文件中的身份验证凭证来设置 API 对象。这是一个带有数据和一些帮助方法的 Tweepy 模型类实例。

[## API 参考- tweepy 3.5.0 文档

本页包含 Tweepy 模块的一些基本文档。模块中直接提供了例外情况…

docs.tweepy.org](http://docs.tweepy.org/en/v3.6.0/api.html#tweepy-api-twitter-api-wrapper)

卢卡·布拉沃Unsplash 上拍摄

脚本的第一步包括加载您想要使用的不同 Python 库,它们是 tweepyjsonboto3time 。然后,您输入来自 Twitter 的凭证。

接下来,输入代码来解析 tweets 并将其导出到 json/text 文件中。该脚本分为两个主要部分。

第一部分叫做听众。正是在这个块中,我们从 API 中提取数据并打印出来。以下是脚本将为此项目记录的信息:

  • 用户名
  • 用户屏幕名称
  • 推特内容
  • 用户关注者计数
  • 用户位置
  • 地理定位
  • 推特时间

根据您进行的项目,我鼓励您根据自己的方便来修改这一部分(例如,删除不需要的字段)。

我在这个项目中了解到的一个奇怪的方面是,Twitter 最初限制其用户只能发 140 个字符的推文,2017 年 11 月,Twitter 开始允许其用户发最多 240 个字符的推文。

为了使 API 适应这一新变化,Twitter 创建了另一个新的字段,称为“extended tweet ”,其中显示了长 tweet 的所有内容。因此,如果一条 tweet 超过 180 个字符,并且您想要提取整个 tweet,您需要提取这个字段,而如果 tweet 少于 180 个字符,您需要提取最初的 tweet 字段,名为“text”。不完全是本能,对吧?

现在让我们回到剧本上。为了容纳和提取扩展的 tweet,我创建了一个 if/elif 条件。如果 API 有一个“extended tweet”字段(这意味着 tweet 超过 180 个字符),提取它;否则,提取“文本”字段。

第一部分是身份验证和与 Twitter 流媒体 API 的连接,然后在下面输入您的 AWS 凭据(请注意,这不是推荐的),并输入您在上一步中设置的 kinesis 的名称。

然后,你需要输入你想要追踪和收集的关键词,用哪种语言。在我的项目中,我决定用英语和法语关注包含#giletsJaunes 的推文。你可以追踪多个标签。

这里是完整脚本的链接。

步骤 4:使用 screen 在 AWS 上运行代码

现在,管道和 Python 脚本已经准备好了,您可以使用之前在步骤 2 中创建的 EC2 实例开始运行脚本。

首先使用下面的命令登录到 EC2:

然后,在你的 EC2 上安装几个包: python3tweepy ,以便顺利运行你的 python 脚本。然后,通过在终端上使用以下命令,将位于本地机器上的 Python 脚本上传到 EC2:

因为您需要长时间运行脚本,所以您可能希望在 EC2 上打开一个“屏幕”,在后台运行作业。这允许您关闭 EC2 的终端并运行它而不进行检查。

以下是使用屏幕的主要命令:

因此,一旦您的“屏幕”设置完毕,您只需通过输入以下命令来运行您的脚本:

python3 my_script.py

一旦您输入它,您应该看到 EC2 实例收集的所有 tweetss,这些 tweet 将保存在您的 S3 中。

第五步:监控你的渠道

通过登录 AWS,您将能够看到您的管道活动。一个很酷的功能是 kinesis 中的“监控”标签。

Kinesis 消防水管输送流中的输入记录

在该图中,您可以看到一段时间内收集的推文活动。在我的项目中,看起来#giletsjaunes 标签在周六和周日比平时更活跃。你也可以查看在你的 S3 数据湖中创建的文件,把文件下载到你的本地机器上,然后查看保存的推文。

现在,您已经准备好进入下一步,通过使用另一个 AWS 服务或 Apache Spark 来分析本地机器中的数据。

如何为你最喜欢的可视化工具创建下拉菜单和滑动条

原文:https://towardsdatascience.com/how-to-create-a-drop-down-menu-and-a-slide-bar-for-your-favorite-visualization-tool-3a50b7c9ea01?source=collection_archive---------8-----------------------

使用 Python Widget,您可以用 3 行代码升级可视化

动机

想象一下,我们正在分析世界各国从 1960 年到 2018 年的趋势人口,以预测未来几年的人口。

为了可视化国家的趋势,我们选择 Plotly,因为它简单而美丽的可视化。从“越南”开始

import pandas as pd 
import datapane as dp 
import plotly.express as pxdata = pd.read_csv('population.csv')fig = px.line(data.set_index('Countries').loc['Vietnam'],
              labels={'index': 'Year', 'value': 'Population'},
              title='Population Over Time',
             )
fig.show()

然后是美国

fig = px.line(data.set_index('Countries').loc['United States'],
              labels={'index': 'Year', 'value': 'Population'},
              title='Population Over Time',
              )
fig.show()

看起来曲线是线性增长的,但我们不确定曲线是否对每个国家都是线性的,所以我们想继续可视化更多的国家。有没有更快的方法来可视化这些国家,而不是在df.loc['location']?中更改国家的名称,如果有一个下拉菜单来选择您想要可视化的国家不是很好吗?

这可以通过一个小插件 Jupyter 小部件轻松完成。

Jupyter 小工具

Widgets 是多事件的 python 对象,可以提供像滑块、文本框等控件。我们可以使用小部件为我们的笔记本电脑构建交互式图形用户界面。

从安装开始

带 pip

pip install ipywidgets
jupyter nbextension enable --py widgetsnbextension

带康达

conda install -c conda-forge ipywidgets

查看此链接以获取关于安装的更多信息。

使用 Interact

导入有用的库

from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets

探索我们可以用interact做的基本事情。首先,定义一个您想要探索的函数。当参数 x 改变时,下面的函数返回 x。

def f(x):
    return x

通过向x传递一个元组(min, max)来创建一个滑动条

interact(f, x=(0.0,10.0))

通过传递字符串列表创建下拉菜单

interact(f, x=['love','hate'])

基于此,也许我们可以为我们的情节创建一个基于国家变化的函数?

def f(country):
    df.loc[country].iplot(
                    xTitle='Year', 
                    yTitle='Population of {}'.format(country),
                    title='Population Over Time'
                     )

df.index代表国家

df.index

用一个简单的代码创建交互。

interact(f, country=df.index)

厉害!似乎有些国家的人口曲线是线性的。但是我们也很好奇每年世界上人口的分布是如何变化的,我们能创造另一个函数作为参数吗?绝对的!

对我们之前的图表进行转置,将country改为year.

def f(year):
    fig = px.line(data.set_index('Countries').T.loc[str(year)],
              labels={'value':'Population in {}'.format(str(year))},
              title= 'Population over time')
    fig.show()

interact(f, year=list(data.T.index)[1:] )

如果我们喜欢滑动条,我们可以简单地将年份列表转换成元组(min year, max year)

interact(f, year=(1960, 2018))

就是这样!现在,我们可以有效地检查每年的分布,看看分布是否随时间而改变。

结论

恭喜你!您已经学习了如何利用 Python 小部件来创建滑动条和下拉菜单,以实现高效的可视化。我鼓励你用你最喜欢的可视化工具来尝试一下,比如 Matplotlib,Seaborn。只需在代码中做一点小小的改动,就可以为您节省大量时间,让您可以投入到数据科学项目的其他重要任务中。

this Github repo 中,您可以随意使用本文的代码。

我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以通过 LinkedInTwitter 与我联系。

如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:

[## 如何用 Ngrok 用 3 行代码分享你的 Jupyter 笔记本

想象一下,让你的朋友在远程机器上使用你的本地 Jupyter 笔记本

towardsdatascience.com](/how-to-share-your-jupyter-notebook-in-3-lines-of-code-with-ngrok-bfe1495a9c0c) [## 恐龙和圆圈的数据集可以有相同的统计数据吗?

它们有相同的中位数和标准差,但它们是两个明显不同的数据集!

towardsdatascience.com](/how-to-turn-a-dinosaur-dataset-into-a-circle-dataset-with-the-same-statistics-64136c2e2ca0) [## 如何使用 HyperDash 远程监控和记录您的机器学习实验

培训需要很长时间才能完成,但你需要去洗手间休息一下…

towardsdatascience.com](/how-to-monitor-and-log-your-machine-learning-experiment-remotely-with-hyperdash-aa7106b15509) [## 如何用 Faker 创建假数据

您可以收集数据或创建自己的数据

towardsdatascience.com](/how-to-create-fake-data-with-faker-a835e5b7a9d9) [## 如何在 10 分钟内为您的数据科学产品组合创建一个优雅的网站

你需要做的就是编辑

towardsdatascience.com](/how-to-create-an-elegant-website-for-your-data-science-portfolio-in-10-minutes-577f77d1f693)

如何创建以太坊定义实时仪表板

原文:https://towardsdatascience.com/how-to-create-a-ethereum-defi-realtime-dashboard-a60c23b527f7?source=collection_archive---------25-----------------------

使用图形和谷歌电子表格来存储数据,并使用谷歌数据工作室创建一个实时仪表板

获取区块链数据越来越容易,速度也越来越快。在本帖中,我们将看到如何从 DeFi(分散金融)协议中提取数据,用 Google 电子表格创建数据集。有了它,我们将创建一个仪表板,实时显示这些数据,为我们提供 Aave 协议中请求的贷款信息。

获取数据

为了获得数据,我们将使用图形的 Api,如这篇文章中所解释的。

我们要提取的是与所请求的贷款相关的数据,所有的历史记录,以便能够在以后进行分析。为此,我们必须创建如下所示的查询:

{
  borrows (first: 1000) {
    id,
    amount,
    reserve {
      id,
      symbol
    },
    borrowRate,
    borrowRateMode,
    timestamp
   }
}

通过这个查询,我们获得了前 1000 个结果,这是图形在一个数据块中允许的最大值,然后我们将继续迭代以获得以下结果,直到我们恢复所有结果。

如果我们在这个游乐场测试这个查询,我们看到它返回:

之后,我们将获得所有贷款的数据,包括请求的加密资产、金额、利息和利率。通过将这些数据直接导入到 Google Sheets 的文档中,我们将拥有一个实时数据集来构建我们的分析模型。

创建数据集

为了将数据保存在 Google excel 表中,我们将在其中创建一个脚本,选项为:

在这个脚本中,我们包含了以下代码:

让我们来看看每一行的细节:

  • 第 4–22 行:将被调用来填充数据集的函数。在这个函数中定义了要调用的端点以及用来获取数据和查询的查询。用这些,提取它的函数被调用,然后它们被写在 excel 中。
  • 第 30–37 行:函数构建将在 API 调用中传递的选项,每次迭代都调用一个动态参数“skip ”,用这个新参数创建选项。
  • 第 44–49 行:将数据写入 excel 表格的函数。接收数组形式的数据作为参数,并将其写入执行脚本的 excel。
  • 第 57–86 行:函数迭代历史中存在的所有数据块。创建一个从 api 请求数据的循环,在有数据时将 skip 参数增加 1,000 个单位。一旦接收到数据,它就将数据存储为一个数组,从 api 返回的 json 中检索该数组。

一旦创建了脚本,就必须执行它以便加载数据。我们以下列方式执行它:

我们可以看到 excel 是如何填充数据的

分析数据

使用填充的数据集,我们可以分析我们的数据。最快和最简单的方法是使用谷歌数据工作室仪表板。

我们创建一个新的报告,并指出数据源将是一个电子表格。

通过选择我们已经创建的表,我们可以使用 Google Data Studio 中存在的模板,并立即创建一个仪表板,以一种简单而非常有吸引力的方式向我们显示数据

通过这个简单的脚本,我们可以实时获得来自协议定义的数据,并分析来自整个贷款历史的数据,这是一个非常重要的信息,能够以完全可访问的方式创建模型。

此外,这些信息可以非常容易地共享。创建的仪表盘可以在这里查阅。

如何在 AWS 上创建免费的 VPN 服务器

原文:https://towardsdatascience.com/how-to-create-a-free-vpn-server-on-aws-655ca3b3ff32?source=collection_archive---------1-----------------------

一步一步的教程建立自己的免费 VPN 服务器

如果你想更安全地浏览网页,并且想创建对 VPC(虚拟专用云)的访问,VPN(虚拟专用网络)是很重要的。有时获得 VPN 会很困难,尤其是当你不得不付费使用服务的时候。在本文中,我将向您展示如何在 AWS 上建立一个有效的 VPN 服务器,并且您不必为使用它支付任何费用。让我们开始吧。

托马斯·詹森在 Unsplash 上的照片

要求

要开始学习本教程,您需要一个免费的 AWS 帐户,这样您就不会因为在 AWS 上运行 VPN 而被收费。如果您没有 AWS 帐户,不用担心,您可以在这里创建一个,它附带 12 个月的免费等级资格。

步骤 1:设置 OpenVPN 服务器

登录到您的 AWS 帐户,导航到 EC2 服务,然后单击启动实例。

作者图片

然后在页面上点击“AWS Marketplace ”,输入“openvpn ”,选择“OpenVPN Access Server ”,即带有“Free tier eligible”选项的服务器,然后点击“select”。

作者图片

OpenVPN 是一个开源 VPN 服务器,在这种情况下,我们使用 Ubuntu AMI(Amazon 机器映像)来运行 VPN,有时 AWS marketplace 会更好,如果你不想自己配置 OpenVPN 服务器的话。

点击“选择”后,您将进入以下页面。请记住,正如我之前所说,OpenVPN 是一个免费的开源 VPN,但它是一项商业服务,尽管我们可以使用自带许可证(BYOL)选项免费开设两个 VPN 帐户,这也是此处显示的页面的本质。之后,向下滚动并单击选择。

作者图片

然后,您将被定向到此页面,这是服务将运行的地方,选择包含“Free tier eligible”标记的 t2.micro,然后单击“Review and Launch”

作者图片

单击 Review and Launch 后,您会看到对您将要创建的实例的审查。如果你通读一遍,你会发现运行这项服务的成本是每小时 0.00 美元。点击启动

作者图片

然后您会看到一个弹出窗口,要求您创建或使用一个现有的密钥对,这一部分非常重要,因为您将需要它来 SSH 到您的服务器。如果您还没有密钥对,您可以创建一个新的密钥对,并将其下载到您的计算机上。然后单击启动实例。几秒钟后,您的实例将开始运行,您可以开始工作了。

作者图片

步骤 2:服务器配置

实例成功启动后。以 root 用户身份打开您的终端并通过 SSH 连接到您的服务器,以便配置 VPN 的管理端,为此使用以下命令:

ssh -i "<your-key-pair>" [root@](mailto:root@ec2-34-228-81-236.compute-1.amazonaws.com)<your-public-instance-domain>

您的密钥对是您最近下载的或者您的计算机上已有的密钥对,如果它在不同的目录中,也要确保您指定了密钥对的路径以使它工作。您的公共实例域可以在 EC2 仪表板上找到。如果输入正确,您应该会看到许可协议条款,键入 yes 并输入。

作者图片

接下来,你会被提示如何配置你的 VPN,保持默认设置,只需继续按下回车键,它会为你启动配置过程。完成后,您将看到一条指令,不再以 root 用户身份登录,而是以默认创建的用户“openvpnas”身份登录。

作者图片

现在,使用下面的命令再次对实例进行 SSH,但不是以 root 用户身份,而是以用户“openvpnas”身份:

ssh -i "<your-key-pair>" openvpnas[@](mailto:root@ec2-34-228-81-236.compute-1.amazonaws.com)<your-public-instance-domain>

当您成功登录后,为用户“openvpnas”创建一个密码,这将是访问 VPN 门户的管理员和客户端密码,您可以使用以下命令完成此操作:

sudo passwd openvpn

您将看到创建新密码的提示。就这样,您已经成功地配置了服务器。

步骤 3:使用 VPN 服务

祝贺您完成了本教程的这一部分,但是在我们开始使用它之前,我们只需要在我们的 VPN 中启用一个小功能。

复制您的实例的公共 DNS 或 IP 地址,并将以下内容粘贴到您的浏览器上:

http://<your-instance-public-DNS or IP address>:943/admin

您应该会看到以下页面:

作者图片

如果您看不到此页面,请尝试使用匿名浏览器打开该网页。对于用户名,输入“openvpnas ”,密码是您在前面的步骤 2 中创建的。如果成功,您将被要求接受许可协议条款,然后您将看到以下页面:

作者图片

现在在左边的页面,进入配置,点击“VPN 设置”

作者图片

然后向下滚动到路由并启用“客户端互联网流量应该通过 VPN 路由吗?”选项:

作者图片

向下滚动并点击保存设置。

作者图片

当你改变设置时,你需要更新服务器,所以点击“更新运行的服务器”就完成了!!!

现在让我们连接到 VPN…

转到 URL 并删除管理路径,它应该是这样的:

http://<your-instance-public-DNS or IP address>:943/

您应该看到用户登录页面,输入您用于登录管理员的相同凭证

作者图片

现在选择你想要使用 VPN 的操作系统,按照提示操作,你就可以开始了!!!

作者图片

仅此而已。感谢阅读,并保持安全😃。

如何在 5 分钟内创建一个谷歌数据工作室仪表板

原文:https://towardsdatascience.com/how-to-create-a-google-data-studio-dashboard-in-5-minutes-4f1c7af68de6?source=collection_archive---------15-----------------------

数据科学家的专家可视化方法。

照片由米切尔罗Unsplash

G oogle Data Studio 是一款简单易用的工具,任何拥有互联网连接和计算机的人都可以使用,但对业务分析师、数据分析师和数据科学家尤其有用。本文的目标是向您介绍如何创建 Google Data Studio 仪表板。该工具有利于通过交互式图表和表格直观地描述数据。商业中的很多问题都源于不恰当的沟通,包括从工程师到产品经理再到数据科学家。发现和结果很难传达给其他人。该工具可以通过以易于查看的格式呈现数据来帮助解决这些问题。下面,我将讨论一些简单的步骤来帮助您创建一个简单而有效的仪表板。

连接您的数据

第一步是获取你的数据。如果您想继续,但还没有数据,您可以通过命名一些列并在行中分配一些值,在 Google Sheets 中快速创建一些虚拟数据,然后连接到这些数据(我将使用虚拟数据)。下面提供的截图显示了如何连接到 18 个数据源,但我选择显示 Google Sheets,因为它是一个流行而简单的数据编辑工具。

连接您的数据源。作者截图。

然后,您很可能会看到您的编辑版本的仪表板,它会自动显示您的数据表。我有几个字段,包括一些数字字段和一些文本字段(分别用 a 123 和 ABC 表示的)。

你的第一次想象

您将会看到一个数据表,但是我在这里将我的数据表改为一个“带有热图的表”。它为您选择在图表中显示的指标着色。这个附加组件不仅可以用数字,还可以用颜色来显示列值的数量级。几分钟后,甚至几秒钟后,你就有了一张令人印象深刻的彩色图表。

选择了“带热图的表格”选项的可能图表。作者截图。

给你的观众(或你自己)留下深刻印象

让我们更进一步,用一个更独特的图表来可视化同样的数据。你可以从上面看到地图选项。我要用的是“地理图”。选择此图表意味着您必须确保您的数据具有地理要素组件,或者手动将其更改为地理要素组件。例如,您可以看到我的数据有一个名为“地区”的字段。您将希望确保图表知道地区的缩写实际上是正确的地区,在本例中是美国的州。现在,您已经创建了一个有意义的地图,可用于会议、演示、电子邮件等。

状态数据的“地理图”,用数量密度进行颜色编码。作者截图。

把所有的放在一起

完成两张图表后,您可以点击“查看”按钮,退出编辑模式,进入仪表板的查看模式。现在,您可以与他人共享您的仪表板,就像使用 Google Sheet 或 Doc 一样。下面的屏幕截图显示了带有热图的原始表格,按“已确认 _ 恢复”降序排列(虚构字段,用于示例目的—您也可以执行升序排列)。另一个简洁的功能是,一旦进入仪表板视图,您就可以将鼠标悬停在图表上,并获得有关数据的更详细的信息。例如,您可以看到我的鼠标悬停在 CA — California 上,它显示了“ Confirmed_Recovery ”指标的数量。地图还显示了显示数量范围的键(最小到最大,也用颜色编码)。此外,您可以移动图表并轻松更改其大小,以实现完美的仪表板布局。有几个“主题和布局”。左边的这个主题是默认的,右边的主题是星座模式(类似于黑暗模式)。

带有默认和黑暗模式主题版本的最终仪表板。作者截图。

这个仪表板很容易创建,而且是免费的。你不必下载任何工具或平台,只需使用一个谷歌账户——所以你可以看到这个工具是多么有益。虽然这个仪表板创建得很快,但您可以创建一个更加令人印象深刻的仪表板,更加注重时间,以及一些您想要突出显示的与您的业务相关的特定目标和指标。

这里的是 Google 自己做的一个更复杂的例子,突出了按国家进行广告数据会话的用例。它被标记为[样本]谷歌分析营销网站。

Google Data Studio 的仪表板示例——Google Analytics 营销网站。

最后的想法

创建一个仪表板可能看起来令人生畏,但是通过一些努力和指导,像这样,你可以很好地为无数目的创建一个强大而令人印象深刻的仪表板。作为一名数据科学家,我已经习惯于用 Python 编程语言创建可视化或图表,但是使用 Google Data Studio 更容易、更快,并且可以产生更令人印象深刻的交互式仪表板。可视化复杂的机器学习算法指标也可能是暗示,但使用这样的工具,数据科学家或类似角色的人可以以容易理解的格式显示分析。

感谢您的阅读!我希望你喜欢这篇来自数据科学家的文章。如果您在执行可视化时使用相似或不同的概念和代码,请在下面评论。

我不隶属于本文中提到的任何公司。

参考

谷歌, 谷歌数据工作室 ,【2020】

谷歌, 谷歌分析营销网站 ,【2020】

M.Przybyla,截图和仪表板,(2020 年)

如何使用 AWS AppSync 创建 GraphQL API

原文:https://towardsdatascience.com/how-to-create-a-graphql-api-using-aws-appsync-49fed1171780?source=collection_archive---------13-----------------------

什么是 GraphQL 以及如何使用 AWS AppSync 创建我们自己的 GraphQL API

图片由贝瑟尼·德鲁因皮克斯拜拍摄

什么是 GraphQL

如今,每当我们谈论或考虑创建/设计一个 API 时,首先浮现在脑海中的是 REST 。REST(REpresentationalSstateTtransfer)一直是开发 API 平台的首选标准。即使 REST 成为了标准,它也有自己的缺点。一个主要的缺点是对于将要消费它们的客户来说缺乏灵活性。因此,即使在开始时,我们根据客户需求创建 REST API,当客户需求快速变化时,该 API 的选项也很少。为了支持这些快速的变化,客户需要发送多个调用,并获得多个不必要的数据。

图片由 GraphQL 提供

GraphQL 的开发主要着眼于为客户提供这种灵活性。它最初是脸书内部的一个项目,但是后来他们把它变成了开源项目。主要概念是让客户端能够选择要查询的数据和需要返回的数据,而无需进行多次 API 调用。是的,正如你在 GraphQL 中读到的,它没有多个端点,而是只有一个端点。为了说明 GraphQL 是如何工作的,让我们尝试使用 node.js 和 express framework 实现一个简单的 GraphQL API。我们的 GraphQL 的数据模型将是一个用户。

下面的 npm 包将在我们的代码中使用。

express, express-graphql, graphql

一个 GraphQL API 主要由四个组件组成。

  • (计划或理论的)纲要
  • 问题
  • 突变
  • 下决心者

(计划或理论的)纲要

GraphQL 模式是我们定义客户端连接到 API 后可以执行的功能的核心元素。模式上的主要构建块是类型

如上图所示,使用积木类型,我们创建了三个积木。类型类型查询类型突变、类型用户。下面将描述查询和突变。对于类型用户,如您所见,我们已经定义了属性字段,当查询用户时,这些字段将对客户端可用。

询问

查询类型用于定义什么类型的查询将可用于要被访问的客户端。用 REST 术语查询类型可以映射到 GET 请求。在上面的模式中,我们定义了三个查询,它们接受的参数以及返回值的类型。(!代表必需的)

变化

任何导致数据变化的函数都应该作为 GraphQL 的变种来完成。对 REST 的 POSTPUT、DELETE 请求可以映射为 GraphQL 上的突变。正如我们定义查询一样,变异也是用参数和返回值类型定义的。

下决心者

在解析器中,我们定义了我们在模式中定义的查询突变的功能。解析器将模式定义的方法映射到我们正在执行的功能方法。

在上面你可以看到,对于我们定义的每个查询变异,我们已经映射了一个 Javascript 函数来执行功能逻辑。(getUser、getUserByName、getUserByStatus 和 updateUser 是 Javascript 函数)

好了,现在我们已经介绍了代码中的主要概念,下面是简单的 GraphQL API 的完整代码。如上所述,您需要安装提到的 npm 包,以便运行应用程序。

现在,您可以启动 node.js 服务器,并向我们的 API 发出查询,我们可以使用 graphql 工具,它将在http://localhost:4000/graph QL上运行

现在,如上所示,我们可以为我们创建的 API 执行查询。上面我们得到了 id 为 1 的用户,我们只请求返回姓名和年龄字段。

与查询一样,我们也可以发送变异来更新用户。上面我们已经将用户的年龄改为 25 岁。

AWS AppSync

图片来源 AWS AppSync

WS AppSync 是由 Amazon Web Services 提供的一项服务,它通过让开发人员在其基础设施上创建安全、灵活的 GraphQL API 来简化 API 应用程序开发。使用 AWS AppSync 的好处是,它还提供了额外的功能,如 Cognito、IAM permissions、API key 和许多其他 AWS 服务,以便与我们的 API 集成。

对于 AppSync,GraphQL 的主要概念基本保持不变,只是增加了一个类型订阅。订阅被调用到一个通过 API 完成的变异,因此它可以用来创建实时的 GrapgQL APIs。此外,在我们开始在 AWS AppSync 中创建自己的 GraphQL 之前,我们需要讨论 AWS AppSync 中的另外两个组件。

  • 数据源 —数据源可以是持久存储(关系数据库或 NoSQL 数据库)或触发器(AWS Lambda 函数或其他 HTTP API)
  • 解析器 —与 GrapQL 中的解析器有相同的概念,但是这里我们将请求负载映射到我们的数据源或触发器。这些解析器主要与包含执行逻辑的映射模板妥协。

在 AppSync 上创建 GraphQL API

让我们开始实现我们的 API。首先转到 AppSync 服务,如果您还没有创建 API,您将看到下面的屏幕。

点击创建 API ,这将把我们带到 API 创建页面。这里 AWS 将为我们提供几种选择。我们可以从已经创建的模板中选择一个,也可以从头开始。对于这篇文章,让我们选择从头开始构建,这样我们将能够了解场景背后的一切是如何连接的。

接下来,提供一个名称并创建我们的 API。然后,我们将转到一个屏幕,在这里我们可以选择编辑我们的模式并根据我们的 API 运行查询。

因为我们的 API 上还没有任何东西,所以让我们首先定义我们的模式。在本文中,我将讨论 AppSync 支持的两种类型的数据源。一个是 DynamoDB 另一个将是 AWS Lambda functions 。由于上面创建了简单的 GraphQL API,让我们假设我们的用户数据模型。

DynamoDB 作为数据源

假设我们需要将用户保存在 DynamoDB 表中。因此,对类型用户进行的所有查询和变更都将直接发生在我们的 DynamoDB 表上。所以首先让我们在模式中定义我们的用户类型。

在模式页面上,单击创建资源,我们将在其中定义我们的用户模式。

我们定义了用户的新类型,然后它将要求 DynamoDB 表的详细信息。在这里,我们可以提供表的名称,还可以配置我们需要创建的不同类型的索引。最后,它将显示为我们的类型 用户自动生成的模式块,这些模式块将被合并到我们的模式中。点击创建,它将创建 DynamoDB 表以及解析器。

现在让我们更深入地看看我们的模式。我们可以看到 AppSync 已经为我们自动生成了查询类型和突变,并且已经将这些查询和突变映射到解析器

让我们看一个解析器,以确定解析器如何在 AppSync 上工作。

点击创建用户突变。在这里,我们可以看到 AppSync 用于此突变的模板。在请求映射模板中,我们可以看到它将 id 作为我们的用户表的键,并在表中创建一个用户集合。 $ctx.args.input 是我们将传递给变异的参数。

响应映射定义了我们将发送回客户端的响应。在这里,它将直接发送来自 DynamoDb 的输出,这将是新创建的用户。

我们可以使用提供的查询工具测试我们的 API。让我们首先添加一个用户,并尝试使用 id 查询该用户。

AWS Lambda 用作数据源

到目前为止,我们创建的 API 可以直接在 DynamoDB 数据库上执行所有 CRUD 操作。但是 API 不仅仅包含 CRUD 操作。可以有不同种类的功能逻辑,如通过向队列发送消息来启动流程,或者我们可能需要使用不同的 AWS 资源,如 ElasticSearch,而不是在数据库上进行 CRUD 操作。为了迎合这种情况,我们可以使用 AWS lambda 函数作为数据源。

对于本文,让我们假设我们想从 AWS lambda 函数获取用户数据,而不是从 DynamoDb 获取。首先,让我们创建 lambda 函数。我们要映射为解析器的查询是

getUser(id: Int!): User

创建一个新的 lambda 函数,并为该函数添加以下代码。在这里,我们检查将通过解析器发送的 event.field 参数。因此,如果字段参数是 getUsers ,那么我们将返回过滤后的用户。

现在让我们为这个函数配置一个解析器。在此之前,我们需要在我们的 API 中将这个函数注册为一个数据源。为此,转到数据源选项卡,点击创建数据源

接下来,为数据源提供一个名称,选择 DataStorageType 作为 Lambda ,然后选择 region ,最后选择我们创建的 Lambda 函数。

下一步是在我们的模式中分配这个数据源。首先,当我们将模式映射到 DynamoDB 表时,删除已经映射到 getUser()解析器。

删除后,点击连接。然后选择数据源作为我们为 lambda 函数创建的数据源。接下来将为请求映射响应映射添加模板。

{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "getUser",
        "arguments":  $utils.toJson($context.arguments)
    }
}

将上述内容添加为请求映射模板。这里我们将字段指定为 getUser ,我们在 lambda 函数中使用它作为事件。对于响应映射,我们可以让它保持原样。

现在让我们试着从我们的 GraphQL API 中查询这个。

就是这样。尽管这里 lambda 函数只是用来返回一个用户,但我想你可能会发现 lambda 函数能做的任何事情都可以映射到我们的 GraphQL,这确实创建了一个无服务器 API。

我想你已经了解了更多关于什么是 GraphQL 以及如何使用 AWS AppSync 为我们创建一个 GraphQL。还有许多概念没有在本文中介绍。因此,如果你热衷于此,请确保遵循官方文档以及其他可用的精彩文章。谢谢你。

[## GraphQL:一种 API 查询语言。

在本系列文章中了解 GraphQL,它是如何工作的,以及如何使用它。寻找关于如何…

graphql.org](https://graphql.org/learn/) [## 欢迎

欢迎使用 AWS AppSync 开发人员指南。AWS AppSync 是一个企业级的完全托管的 GraphQL 服务,具有…

docs.aws.amazon.com](https://docs.aws.amazon.com/appsync/latest/devguide/welcome.html)

如何用 Python 中的 Plotly Express 创建分组条形图

原文:https://towardsdatascience.com/how-to-create-a-grouped-bar-chart-with-plotly-express-in-python-e2b64ed4abd7?source=collection_archive---------6-----------------------

Python melt 函数将数据帧从宽到长格式化

作者图片

**Table of Contents**[**Introduction**](#7b7f)1\. [Data](#4f79)
2\. [Preparing data](#010c)
3\. [Pandas melt function](#0bb4)
4\. [A grouped bar chart](#9c7d)
5\. [Bonus tip](#de73)[**Conclusion**](#b4e3)

介绍

创建分组条形图时,需要使用[plotly.graph_objects](https://plotly.com/python-api-reference/plotly.graph_objects.html#graph-objects)。在本文中,您将学习如何使用 Plotly.express 创建一个分组条形图。Plotly Express 是一个用于数据可视化的高级接口。

Plotly Express 提供了 30 多种功能来创建不同类型的图形。这些函数的 API 一致且易于使用。

你可以在这里找到如何安装 plot ly。

本文假设您已经熟悉 JupyterLab/Jupyter 笔记本的基本操作。

数据

我们使用美国人口普查局的数据。本页提供 2018 年以来的教育程度数据。在这篇文章中,我们主要关注种族和性别。你可以在这里找到下载的数据。

准备数据

import pandas as pd
import plotly.express as px

url='https://gist.githubusercontent.com/shinokada/f2ebf82eaa3cfa02106ae93c7fe9efbe/raw/3494b1e2ba9b1c0d8991e71483123f63b4bce559/educational+attainment.csv'

df = pd.read_csv(url)
display(df)

我们导入 Pandas 并创建一个变量url,它包含一个到逗号分隔文件(csv)的链接。

我们使用read_csv来读取 csv 文件并创建一个熊猫数据帧。

csv 文件有 70 行× 16 列。图片由作者提供。(图 1)

cols = [2,10,14]
rows = [33,36,39,42,45,48,51,57]

df =df.iloc[rows,cols].reset_index(drop=True)

df.columns=['race','Male','Female']
for col in ['Male', 'Female']:
    df[col]=pd.to_numeric(df[col].str.replace('%',''))

display(df)
print(df.dtypes)
  • csv 文件有 70 行 x 16 列。我们需要2, 10, 14的列号,其中包含种族名称、男性的估计百分比和女性的估计百分比。我们还使用行号33, 36, 36, 42, 45, 48, 51, 57,它包含不同种族的学士学位或更高学位的数据。
  • 我们将该列重命名为种族、男性和女性。
  • 我们使用 for 循环,使用pd.to_numeric函数将男性和女性列转换为数字,并使用str.replace方法删除%符号。

显示(df)和打印(df.dtypes)的输出。图片由作者提供。(图 2)

[## 如何在 Docker 上运行 Jupyter 笔记本

不再有 Python 环境和包更新

towardsdatascience.com](/how-to-run-jupyter-notebook-on-docker-7c9748ed209f) [## 如何用不到 15 行代码创建一个动画的 Choropleth 地图

在 Jupyter 上使用 Python 中的 Plotly Express

towardsdatascience.com](/how-to-create-an-animated-choropleth-map-with-less-than-15-lines-of-code-2ff04921c60b) [## 如何在 Jupyter 中创建动画条形图

使用 Plotly Python 显示最新美国失业率的数据可视化

towardsdatascience.com](/how-to-create-an-animated-bar-chart-in-jupyter-9ee1de8d0e80)

熊猫融化功能

上面的图像图 2 被称为宽格式。要使用 Plotly Express 分组条形图,我们需要将数据帧重新调整为长格式。

熊猫的[melt](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.melt.html)功能可以将一个数据帧从宽格式重塑为长格式。

df=pd.melt(df,id_vars=['race'],var_name='gender', value_name='value')
df

我们使用以下 pandas.melt 参数。

  • id_vars:用作标识符变量的列
  • var_name:用于变量的名称。默认为variable
  • value_name:要取消透视的列。如果未指定,则使用未设置为id_vars的所有列。我们用value

一种长格式数据帧。图片由作者提供。(图 3)

分组条形图

fig = px.bar(df, x="race", color="gender",
             y='value',
             title="A Grouped Bar Chart With Plotly Express in Python",
             barmode='group',
             height=600
            )

fig.show()

我们使用px.bar实例化一个plotly.graph_objects.Figure对象并定义参数。

  • data_frame:我们使用df数据帧。你可以像上面一样使用或不使用data_framedata_frame=df
  • x:用于 x 轴的data_frame中的一列的名称。我们使用列race
    -color:data_frame中一列的名称,用于给列分配颜色。
  • y:用于 y 轴的data_frame中的一列的名称。我们使用列value
  • title:一个图标题。
  • barmode:为groupoverlayrelative中的一种。在relative模式下,棒被堆叠。在overlay模式下,条形被绘制在彼此的顶部。在'group'模式下,条块并排放置。默认值为relative

因为我们正在创建一个分组条形图,所以我们使用group

barmode='overlay '。图片由作者提供。

barmode='relative '。图片由作者提供。

  • height:以像素为单位的图形高度。

额外小费

当你有一个像我们这样的宽格式数据帧时,你可以使用facet_colfacet_row来创建支线剧情。

fig = px.bar(df, x="race", color="gender",
             y='value',
             title="A Grouped Bar Chart With Plotly Express in Python",
             barmode='group',
             height=700,
             facet_row="gender"
            )

fig.show()

facet_row="gender "的输出图。图片由作者提供。

fig = px.bar(df, x="race", color="gender",
             y='value',
             title="A Grouped Bar Chart With Plotly Express in Python",
             barmode='group',
             height=700,
             facet_col="gender"
            )

fig.show()

facet_col="gender "的输出图。图片由作者提供。

结论

我们可以使用 Plotly Express 创建一个分组条形图。Plotly Express API 提供了我们可以利用的各种高级特性。barmode参数有不同的值可供您使用。

Pandas melt函数是将宽格式转换为长格式数据帧的最简单方法。

通过 成为 会员,获得媒体上所有故事的访问权限。

请订阅。

[## Jupyter 上 Plotly 的折线图动画

Plotly 统一悬停模式,按钮和更多

towardsdatascience.com](/line-chart-animation-with-plotly-on-jupyter-e19c738dc882) [## 如何在 Jupyter 中创建交互式下拉列表

用下拉菜单更新图表

towardsdatascience.com](/how-to-create-an-interactive-dropdown-in-jupyter-322277f58a68) [## 如何在 Jupyter 中创建一个有吸引力的气泡图

从 Github repo 抓取数据的分步指南

towardsdatascience.com](/how-to-create-an-attractive-bubble-map-5cf452c244e9)

如何使用 Plotly 创建轴辐式绘图

原文:https://towardsdatascience.com/how-to-create-a-hub-and-spoke-plot-with-plotly-d11d65a4200?source=collection_archive---------31-----------------------

用连接位置的线在地图上绘制纬度/经度数据

不久前,我需要在地图上绘制连接某些位置的纬度(lat)和经度(long)坐标的线。我需要画的是众所周知的“轴辐式图。知道 Plotly 已经有了一些样品,比如这里的,我能够很容易地完成它。但是现实生活中的数据并不总是完美地适用于 Plotly 的例子,而且可能还有其他开箱即用的例子不能满足的要求。

在这篇博客中,我将向你展示如何自己构建这些图表。特别是,我们将假设:

  • 数据并不总是来自同一个地区(如美国)。我们的地理空间数据可以是北美、南美或欧洲的。

  • 该图需要保存为 HTML 文件。

  • 图形应该是脱机的*。

  • 这实际上是在 Plotly 版本 4 之前需要更多努力的事情,特别是因为他们的文档强调在线模式,正如你在这里看到的**。但是版本 4 只离线。你可以在这里* 阅读更多关于在线特性 的迁移。*

一些关于神秘人物的背景

Plotly 中有多种表示图形的方法。两种最常见的方法是使用(a)字典或使用(b) 图形对象。虽然各有利弊,Plotly 推荐后者的额外好处,你可以在这里查看。

为了创建一个图形,我们需要两个主要组件:数据和布局。来自文档:

您可以通过将跟踪和布局规范传递给plotly.graph_objects.Figure构造函数来构建一个完整的图形。这些跟踪和布局规范可以是字典或图形对象。

**布局字典指定图形布局的属性,而数据是一个跟踪字典列表,带有各个跟踪的配置选项(跟踪是 Plotly 用来描述图形的一个词)。

既然我们知道了图形是如何构成的,我们就可以准备数据并把它们标绘在地图上。虽然下面的代码是针对 Plotly 版本 4 的,但是你可以在这个 Jupyter 笔记本中找到版本 3 和版本 4 的实现。

数据准备

数据(如您在此示例中所见。csv 文件)包含每个出发地和目的地的信息(即城市、州、国家、纬度和经度)。为了画出这个情节,我们只关心:

  • 始发地和目的地的纬度/经度。
  • 地图上的位置属性,例如大小、颜色和形状。
  • 以及任何其他关于某个位置的信息,或者我们希望在地图上显示的位置之间的路径。例如,当用户的鼠标悬停在每条路径上时,您可能想要显示每个位置的名称,或者每条路径的长度(以英里为单位)(这里我们只显示前者。)

首先,让我们加载数据:

***import** pandas **as** pd
**import** plotly.graph_objects **as** godata = pd.read_csv(**'sample_us.csv'**)*

接下来,使用所有需要的属性创建位置数据框架:

之后,我们可以将每个位置及其属性添加到图形中:

之后,我们可以将每条路径添加到图形中:

最后,让我们指定地图的布局:

因为我们希望将地图显示为 HTML 文件,所以我们还需要一行代码:

*fig.write_html(file=**f'{**title**}.html'**, auto_open=**True**)*

就是这样!这正如预期的那样起作用,但是只有当纬度/经度数据局限于美国时。为了让它对不同种类的底层数据(比如欧洲的位置)有更好的响应,我们需要做一个小小的改变。

一般数据

如果你仔细观察上面的代码,你会发现在layout字典中,我们指定了scope='usa'。根据 Plotly 的文档 , scope接受以下值之一:

**"world" | "usa" | "europe" | "asia" | "africa" | "north america" | "south america".**

为了决定使用什么范围,我们应该查看数据中纬度和经度的范围。

然后,我们可以将我们的范围与每个范围的大致范围进行比较,以决定使用哪一个(我通过在线搜索找到了它们——它们应该很好地服务于我们的目的。)

剩下要做的就是改变layoutscope=scope,我们就完成了。

瞧啊。我们完了。让我们在两个不同的数据集上测试这个方法。

这是一张用户数据的地图:

这是一张来自欧洲的照片:

注意,这个博客的样本数据和更详细的代码可以在 GitHub 上找到。

我希望这篇博客对你有用。可以通过TwitterLinkedIn联系到我,我欢迎任何反馈。**

如何创建文件、文件夹和子文件夹的列表,然后导出为 Excel

原文:https://towardsdatascience.com/how-to-create-a-list-of-files-folders-and-subfolders-and-then-export-as-excel-6ce9eaa3867a?source=collection_archive---------26-----------------------

一个生产力工具玛丽近藤你的文件夹

照片由 Pranav MadhuUnsplash 上拍摄

你能为我们的项目文件夹创建一个文件、文件夹和子文件夹的列表吗?

这个请求看起来似乎很简单,但是你已经可以想象一旦这个列表的第一个版本完成,可能会出现的其他修改。

你还能列出文件类型并给文件添加超链接吗?或许还可以增加文件的大小?

根据文件夹的大小、文件数量及其嵌套程度,您可以选择手动完成此任务,因为添加新字段可能很简单。现在,让我们考虑另一个请求:

我重新整理了一些文件夹,重命名了一些文件,你能更新一下列表吗?

别担心,蟒蛇来救你了!

os.walk()是主函数,我们将使用它来创建一个脚本来遍历主文件夹并列出所有子文件夹和文件。python 文档的链接是这里是。下面是代码的主要部分:

df = pd.DataFrame(columns=['File','File Type',
                           'Folder Location','Link', 'Path'])for root, dir, files in os.walk(path):
    files = [f for f in files if not f.startswith('~') and f!='Thumbs.db']
    paths = [os.path.join(root, f) for f in files]
    exts = [os.path.splitext(f)[1][1:] for f in files]
    filetypes = [ext_desc(ext) for ext in exts]
    file_links = ['=HYPERLINK("{}","link")'.format(p) if len(p) < 256 else '' for p in paths]
    folders = [os.path.dirname(p) for p in paths]
    df1 = pd.DataFrame({'File': files,
                        'File Type': filetypes,
                        'Folder Location': folders,
                        'Link': file_links,
                        'Path': paths})
    df = df.append(df1)

完整的代码可在故事的结尾。

代码解释:

1.创建一个空的数据框架,其中所需的列按所需的顺序排列:

df = pd.DataFrame(columns=['File','File Type',
                           'Folder Location','Link', 'Path'])

2.启动for循环:

for root, dir, files in os.walk(path):

path是指我们感兴趣的主文件夹路径。os.walk返回一个元组rootdirfiles。为此我们只需要rootfiles

3.用列表理解来构建每个专栏

# 'Files' columns
files = [f for f in files if not f.startswith('~') and f!='Thumbs.db']

临时文件以波浪号~开始,包含这些可能没有意义,因此 list comprehension 有一个if条件来排除这样的文件。类似地,Thumbs.db只是一个缩略图文件,并被明确排除。

# 'Path' column
paths = [os.path.join(root, f) for f in files]

paths是指向每个子文件夹中特定文件的路径列表。

文档推荐使用os.path.join而不是字符串连接,这里有一个 stackoverflow 回答为什么推荐这样做。

# 'File Type' column
exts = [os.path.splitext(f)[1][1:].lower() for f in files]
filetypes = [ext_desc(ext) for ext in exts]

exts是通过使用os.path.splitext()形成的扩展名列表,它返回一个没有扩展名和扩展名文件名元组。**

>>> os.path.split('some_filename.pdf')
('some_filename', '.pdf')

[编辑]以前,我通过右分裂rsplit文件名得到扩展名。exts = [f.rsplit('.',1)[-1].lower() for f in files]这不是一个好的做法。

filetypes是文件类型列表,ext_desc是将每个扩展名映射到适当名称的函数。

def ext_desc(ext):

    d_ext_desc = {'xlsx':'Microsoft Excel File',
                  'docx':'Microsoft Word Doc'}
    # additional extensions and descriptions can be added to d_ext_desc try:
        desc = d_ext_desc[ext]
    except KeyError:
        desc = ''     # Any file extensions not mapped will be empty.
    else:
        pass
    return desc

添加文件链接的方式略有不同。

file_links = ['=HYPERLINK("{}","link")'.format(p) if len(p) < 256 else '' for p in paths]

=HYPERLINK()是一个 Excel 公式,在给定链接位置(可以是网页或文件位置)时创建超链接。第二个参数link是可选的,用于缩短显示的文本。if条件len(p)<256是 Excel 中的一个限制,超过 255 个字符的链接无效。

# Folder column
folders = [os.path.dirname(p) for p in paths]

folders是一个文件夹列表,告诉我们每个文件的位置。这是通过使用os.path.dirname()方法获取路径的目录名获得的。

[已编辑]之前,我使用folders = [p.rsplit('\\',1)[0] for path in paths]来获取文件夹。同样,这不是一个好的做法。

4.附加到原始数据帧

df1 = pd.DataFrame({'File': files,
                    'File Type': filetypes,
                    'Folder Location': folders,
                    'Link': file_links,
                    'Path': paths})
df = df.append(df1)

由于每个列表理解都是一列,剩下的工作就是构建一个数据帧并附加到原始数据帧上。使用df.to_excel('some_filename.xlsx')可以将最终的数据帧写入 Excel

5.将其推广以备将来使用

  • 如果文件夹包含大量文件,生成完整的文件索引需要时间,因此当记录数量超过 500 时,我在for循环中添加了一个关键字参数。这在添加新列或修改最终输出的外观时特别有用,因为您不会希望遍历成千上万个文件才意识到最后几行代码中存在输入错误。
  • 在脚本中修改路径可能会很麻烦,因此我添加了一个tkinter.filedialog方法,如果没有提供路径,它会提示用户选择文件夹。

如何创建专业的 Github 数据科学库

原文:https://towardsdatascience.com/how-to-create-a-professional-github-data-science-repository-84e9607644a2?source=collection_archive---------14-----------------------

存储库结构、记录 jupyter 笔记本和编写信息丰富的自述文件方面的良好实践

马库斯·温克勒在 Unsplash 上的照片

作为一名数据科学家,你将利用许多不同的工具和技术来完成一个项目。Github 是一个出色而重要的工具,它让我们能够管理自己的代码、版本控制,并与其他人合作。不仅是数据科学家,任何为个人或工作项目编程的人都会使用 Github(或另一个 Git 存储库托管服务)。

除了使用存储库来推动您的工作之外,Github 还可以作为您的技术项目的一个很好的投资组合,或者作为您的同事在工作场所阅读您的代码和报告的一个很好的媒介。作为申请数据科学职位的候选人,展示你有项目经验的一个很好的方式是拥有一个到 Github 的链接,潜在的雇主可以在那里看到项目简介、你的代码和你参与的项目的成果。另一种情况是在你工作的公司里,你对一个项目的贡献可能会被一个非技术人员、一个高级技术人员或者一个比你级别低的人看到。对于所有这些不同的人群,你的知识库应该容易理解。

我想从编码实践、有效地使用 jupyter 笔记本以及详细的自述文件等方面来回顾一下如何创建一个优秀的 Github 资源库的技巧和提示。我将在希尔顿酒店 NLP 项目中使用 Github 存储库中的图片。这里有一个链接可以看到完整的知识库:【https://github.com/awesomeahi95/Hotel_Review_NLP

Jupyter 笔记本

Python 是数据科学中主要使用的语言,有许多不同的 ide 可以用来编写 Python 代码,但是要用干净的代码和注释创建一个结构化的报告,Jupyter 笔记本是前进的方向。以下是让您的笔记本更易于访问的一些提示:

使用标记:如果你的代码很长或者很复杂,对你正在编写的代码的标题、副标题和描述进行标记会非常有用。通过这样做,一个非技术人员或者像你一样不擅长编码的人可以理解为什么要采取这样的步骤,以及一些细胞在做什么。

将所有的导入放在顶部:如果有人需要知道什么库、python 脚本或数据集被导入到笔记本中,将它们放在顶部。这使得阅读你的笔记本的人在运行它之前,更容易知道该笔记本运行所需的库或回购文件。

用于导入的单元格

在 Seaborn 海报背景中使用可视化:在数据科学报告中,可视化是必不可少的——还有什么更好的方式来传达你的发现。但是我们可以用 seaborn 的上下文“海报”来改进这些可视化,这使得可视化更加大胆,文字更加清晰。这也使得 matplotlib 可视化看起来更好。

用于更好可视化的代码

使其易于理解和浏览:使用数字如 1.4.2 的副标题可以更容易地遵循笔记本上的步骤。对于给定的笔记本,您可能会对您的数据执行某些任务,如果有一系列单元格完成一项任务,将它们放在一个编号的小标题下有助于在笔记本中上下导航,并准确了解接下来的几个单元格致力于实现什么。

可消化代码的示例

一份报告使用多个笔记本:这可能并不适用于所有项目,因为一些公司可能有特定的编码规则,并且只选择使用一个笔记本,但在其他情况下,这可能非常有用。在构建数据科学项目时,通常有明确的阶段,如 EDA 和建模。对于所有这些阶段,你可以为每个阶段都写一个笔记本。这不仅使它更容易理解,而且其他人可以为特定阶段运行一个笔记本,而不是运行一个单独的长笔记本。

我还建议最后将每个数据框架/数据集或模型保存在笔记本中,并将其保存在 repo 中的数据或模型文件夹中,然后将其导入笔记本中,用于下一阶段。这有助于回到旧版本的操作数据和模型。

项目使用的笔记本列表

为函数和类创建 python 脚本:试着让你的笔记本更有目标性,更多地记录所采取的步骤和原因,因为这些部分是你快速浏览时想要看到的。将函数和类保存在脚本中,这些脚本可以导入到您的笔记本中使用。这并不意味着函数和类不重要,对于评估代码质量的技术人员来说,它们非常重要。所以要确保你的 python 脚本写得很好,并且有详细的文档。

带文档的类

自述文件

就简化和总结项目存储库中正在进行的一切而言,READMEs 是实现这一点的最佳方式。一旦有人打开你的存储库,在文件下,你首先看到的是你的自述文件。这对潜在的雇主,你的非技术同事和你的技术同事来说都是很好的参考。这是你解释你对这个项目的意图的地方,你可以包括为什么要做这个项目的背景。你可以详细说明你的文件的结构,采取的步骤,并添加一些可视化。

陈述你的商业案例:在继续讲述你的所作所为之前,给出一些背景会对任何读者都非常有益。这一部分使结果看起来更令人印象深刻,因为你可以在故事中讲述“过去是什么”,然后项目应该显示“可以做什么”和“如何做”。

商业案例

带导航链接的目录:目录很有用,尤其是当你的自述文件包含大量信息的时候。给读者一个在自述文件中可以阅读的内容的摘要,并且能够跳转到特定的部分,这是一个很大的方便。

目录示例

带有导航链接的文件描述:为每个文件添加一个小的描述也可以极大地帮助读者理解存储库的每个组件做什么或者包含什么。同样,添加链接来简化导航。

文件描述示例

使用下拉框 : Markdowns 可以使用下拉框,当有人想浏览你的自述文件时,这有助于缩短它的长度。您可以选择隐藏一些部分,并选择显示部分,反之亦然。

两种下拉状态的示例

执行摘要:这是自述文件的大部分内容,你可以在其中回顾项目的各个步骤,简要描述你在每个阶段做了什么和发现了什么,并附有可视化效果(图片格式)。确保描述不要太专业,因为自述文件是非技术人员查看您的项目的最佳地方,并且您不希望他们阅读函数中使用的代码细节。

执行摘要的开头

未来的改进:在结果之后,以一部分专用于这个项目的未来工作/改进,和/或关于项目或数据科学的主题,你将来可能计划做的其他事情来结束。

结束自述文件的好方法示例

我希望这能帮助你在 Github 上创建一个好的数据科学项目库。请评论您认为对创建一个好的资源库有用的任何其他技巧和技术。

如何在一行代码中创建一个种族栏动画

原文:https://towardsdatascience.com/how-to-create-a-race-bar-animated-plot-in-a-single-long-piped-r-line-of-code-6216f09ed844?source=collection_archive---------55-----------------------

也许这不是最优雅的方式,但为了吸引人的标题,这是值得的

长管道 R 命令…有些人喜欢它,有些人不喜欢!

当你想要拍摄一个令人印象深刻的复杂的多米诺骨牌视频时,你是要冒险在完成之前意外地翻转一个立方体,并毁掉整个东西,还是更喜欢将它分成独立的单元,更好地隔离,这也将允许你探索和测试它的功能,而不伤害其他部分?

https://pix abay . com/photos/domino-hand-stop-corruption-665547/

在 R 的情况下,管道操作符,最初来自包马格里特,允许你传递一个对象到下一个函数。所以从技术上来说,你可以在不中断链的情况下,或者通过避免可读性较差的嵌套函数,将对象传递给其他函数。

就像上面的多米诺类比一样,我不认为有一个规则,它应该基于您对使用管道的舒适程度以及您可能具有的其他限制(如连接到数据框的外部源(或其他输入参数)、计算内存等)来自我指导。

建议打破链主要是为了可读性和文档,但就性能而言,可能不需要。这就像在一个长句子中阅读一长串步骤(功能),而没有停下来喘口气。

在下面的例子中,为了便于演示,我创建了一个很长的 R 管道代码行,可以一次性运行。同样,这可能不是最推荐的风格,但为了吸引人的标题和{}中嵌套管道的使用,这种风格值得一试。

JSON_object %>% {setNames(data.frame(.$data), .$columns)}

我使用了新冠肺炎开放数据项目中美国各州的新冠肺炎累计死亡人数。

library(robservable)
library(jsonlite)
library(tidyverse)robservable::robservable(
  "[https://observablehq.com/@juba/bar-chart-race](https://observablehq.com/@juba/bar-chart-race)",
  include = c("viewof date", "chart", "draw", "styles"),
  hide = "draw",
  input = list(
  data = 
    fromJSON('[https://storage.googleapis.com/covid19-open-data/v2/epidemiology.json'](https://storage.googleapis.com/covid19-open-data/v2/epidemiology.json')) %>% 
    {setNames(data.frame(.$data), .$columns)}  %>% as_tibble %>% 
    filter(key %in% c("US", "US_AK", "US_AL", "US_AR", "US_AS", "US_AZ", "US_CA", 
"US_CA", "US_CO", "US_CT", "US_DC", "US_DE", "US_FL", "US_GA", 
"US_GA", "US_GU", "US_HI", "US_IA", "US_ID", "US_IL", "US_IN", 
"US_KS", "US_KY", "US_LA", "US_MA", "US_MD", "US_ME", "US_MI", 
"US_MN", "US_MO", "US_MP", "US_MS", "US_MT", "US_NC", "US_ND", 
"US_NE", "US_NH", "US_NJ", "US_NM", "US_NV", "US_NY", "US_NY", 
"US_OH", "US_OK", "US_OR", "US_PA", "US_PR", "US_RI", "US_SC", 
"US_SD", "US_TN", "US_TX", "US_UT", "US_VA", "US_VI", "US_VT", 
"US_WA", "US_WI", "US_WV", "US_WY")) %>% 
    separate(key, c('US', 'state'), sep = '_') %>% 
    mutate(month = month(date)) %>%
    arrange(date, state) %>% 
    select(id = state, date = date, value = total_deceased) %>% 
    filter(!is.na(value), value != 0),
        title = "COVID-19 deaths count",
        subtitle = "Cumulative number of COVID-19 deaths by US state",
        source = "Source : Johns Hopkins University"
    ),
  width = 700,
  height = 710
)

上面的代码将创建动画,以 HTML 文件格式保存。

HTML 动画文件可以在我的 GitHub repo 找到。下面是从我的屏幕上录制的视频,因此质量下降。

https://share.getcloudapp.com/6quPGBbN作者

这篇博文与我前一天发表的标题与新冠肺炎相关的博文非常相似。虽然侧重点不同,但发布类似帖子的原因是为了测试每个帖子会吸引多少“观众注意力”(掌声和观看次数)。当然,每篇文章都有不同的推广方式:在聚合出版物下发布,LinkedIn,脸书,Twitter,R-bloggers,发布日效应,等等。我很乐意稍后分享我的发现。

如何创建代表性的测试集

原文:https://towardsdatascience.com/how-to-create-a-representative-test-set-f0aa56adaf35?source=collection_archive---------19-----------------------

使用有代表性的测试数据集,满怀信心地评估您的模型的性能。

图片来自 Pixabayandrasgs

将数据集分割成训练测试集通常是机器学习流水线中的第一个处理步骤之一。在这一点上,只有一个不可侵犯的规则:搁置测试数据分割,只有当您的模型准备好进行最终评估时才再次引用它。但是,有没有一种方法可以让我们确信我们所做的拆分是正确的呢?我们如何确定测试集代表我们的总体?

我们必须确保测试集非常接近我们人口的复杂性。我们的验证集也是如此。

在这个故事中,我们讨论两种分裂方法:随机抽样和分层抽样。我们考虑它们的优点,并讨论在特定情况下使用哪一种。这个故事实际上是我发表的关于优秀的实践机器学习的笔记,作者是 Aurélien Géron,作者是 Scikit-Learn、Keras 和 TensorFlow:构建智能系统的概念、工具和技术

学习率是我每周给那些对 AI 和 MLOps 世界好奇的人发的简讯。你会在每周五收到我关于最新人工智能新闻、研究、回购和书籍的更新和想法。在这里订阅!

数据集

对于这个例子,我们使用 加州房价 数据集。这个数据集对于入门教程来说是极好的,因为它熟悉的性质、很少丢失的值、适度的大小和明确的目标。

该数据集基于 1990 年加州人口普查的数据。任务是在给定一组特征(如房龄、总房间数等)的情况下,预测特定地区房屋的中值。).目标变量或因变量(即中值房价)是一个数值。因此,我们有一个回归任务要处理。

数据集的特性是不言自明的,但是让我们使用pandas加载 CSV 文件并查看前五行。

我们可以执行更多的方法来获得对数据的感觉,如df.info()df.describe(),而每个数值实例的简单直方图——使用df.hist()方法——会给我们手中的信息提供更好的图片。但是,由于这不是本文的范围,让我们进入下一步,即将数据集分成训练集和测试集。

随意采样

理论上,创建一个测试集确实很容易;只需随机选择几行——通常是整个数据集的 10%或 20%——并将它们保存在一个新的单独的数据帧中。此外,为了可再现性,我们可以设置一个random_state数,这样每次我们运行一个实验,都会得到相同的测试集。这也有助于直接比较不同的方法,因为我们选择的每个算法都是在同一个测试集上评估的。

接下来,我们使用由 Scikit 提供的一个方便的方法——Learn命名为train_test_split()。该方法接受列表、numpy 数组、scipy 稀疏矩阵或 pandas 数据帧。我们还应该提供默认的分割百分比None和一个random_state数字。

我们可以看到该方法返回了一个tuple,我们可以将它直接解包成一个训练和一个测试集。因为我们将一个数据帧传递给该方法,所以得到的训练集和测试集也是数据帧。请记住,默认情况下,该方法首先打乱数据集,然后将其拆分。为了避免这种行为,我们可以将shuffle属性设置为False

通常,如果数据集足够大(特别是相对于属性的数量),随机分割就足够了。但如果不是这样,随机分裂可能会引入显著的采样偏差。

train_set, test_set = train_test_split(df, test_size=.2, random_state=42, shuffle=False)

我们现在有一个随机生成的测试集来评估我们的模型。但是这有什么好处吗?是否代表总体? 嗯,看情况。通常,如果数据集足够大(特别是相对于属性的数量),随机分割就足够了。但如果不是这样,随机分裂可能会引入显著的采样偏差。因此,让我们来看看如何解决这个问题。

分层抽样

假设我们正在美国进行一项调查,记录一个特定州的教育水平和收入中位数。如果我们只询问生活在昂贵地区的人,我们肯定会在样本中引入明显的偏见。因此,我们需要一种方法来选择任何经济地位的人,粗略地接近相应的人口分布。

在我们的例子中,让我们首先检查是否有一个变量与我们的目标变量高度相关。使用pandas.corr()方法很容易做到这一点。

我们将因变量的结果按降序排列,我们得到median_incomemedian_house_value有很强的正相关性。这肯定是意料之中的事情。

似乎以分层的方式分割数据集,使用median_income作为类别标签是一个好主意。首先,让我们创建一个新的变量,为这个属性创建类标签。

pd.cut将根据我们指定的分类创建五个类别,并将它们保存在一个新变量中,我们将其命名为income_cat用于收入类别。我们现在准备以分层的方式分割我们的数据集。

唯一的变化是我们现在用一个类似数组的对象设置了train_test_split()方法的stratify参数,该对象设置了标签类。还有另一种更复杂的方法,在下面的代码示例中指定,用于遗留目的。

无论如何,让我们看看我们做得怎么样。我们将在完整的数据集以及测试样本中检查每个收入类别的比率。

让我们并排比较两个结果。

可以看出我们很亲近。微小的差异真的微不足道。我们现在有了一个测试集,它遵循人口中收入类别的分布!

结论

创建测试集并不总是那么简单。我们必须确保测试集非常接近我们人口的复杂性。我们的验证集也是如此。例如,检查 Scikit-Learn 提供的[StratifiedKFold()](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.StratifiedKFold.html#sklearn.model_selection.StratifiedKFold)方法。

在这个故事中,我们看到了如何以分层的方式将数据集随机分为训练集和测试集。我们使用 Scikit-Learn 库在 Python 中实现了相应的解决方案。最后,我们提供了每种方法的细节和优点,以及何时使用每种方法的简单实用规则。

学习率是我每周给那些对 AI 和 MLOps 世界好奇的人发的简讯。你会在每周五收到我关于最新人工智能新闻、研究、回购和书籍的更新和想法。订阅这里

我叫 Dimitris Poulopoulos,是希腊比雷埃夫斯大学的机器学习研究员BigDataStack和博士(c)。我曾为欧洲委员会、欧盟统计局、国际货币基金组织、欧洲中央银行、经合组织和宜家等主要客户设计和实施人工智能和软件解决方案。如果你有兴趣阅读更多关于机器学习、深度学习和数据科学的帖子,请在 twitter 上关注我的 LinkedIn@ james2pl******

如何在 Azure 函数中创建 Selenium web scraper

原文:https://towardsdatascience.com/how-to-create-a-selenium-web-scraper-in-azure-functions-f156fd074503?source=collection_archive---------4-----------------------

了解如何使用自定义 docker 图像创建 Azure 函数,并将其作为 Python 中的 lenium web scraper

A.介绍

Selenium 是自动化 web 浏览器测试的标准工具。最重要的是,Selenium 是一个流行的网页抓取工具。在 Azure 中创建 web scraper 时,Azure Functions 是运行代码的理想选择。然而,默认的 Azure Functions 映像不包含 Selenium 所需的依赖项。在这篇博客中,Azure Functions 中的 web scraper 创建如下:

  • 使用 Selenium 创建并部署 docker 映像作为 Azure 函数
  • 定期抓取网站并存储结果

更新 2022–08–13:使用最新版本的 Azure Functions,Python 3.10 成功部署代码。Git 回购和博客是最新的。

web scraper 的架构如下所示。

A.构建 Selenium web scaper 的架构(图片由作者提供)

在剩下的部分,我们将讨论在 Azure Functions 中部署和运行 web scraper 的步骤。关于如何保护你的 Azure 功能的详细信息,请看这个博客。有关如何在 Azure 函数中使用 OpenCV 创建自定义 docker 映像的详细信息,请参见此处的和此处的 DockerFile

B0。用 Selenium 作为 Azure 函数部署 Azure 函数

基础 Azure 函数映像不包含运行 selenium webdriver 所需的 chromium 包。这个项目创建了一个定制的 docker 图像和所需的库,这样它就可以作为 Azure 函数运行。执行以下步骤:

  • B01。安装必备组件
  • B02。从 GIT 克隆项目
  • B03。使用 docker 桌面创建 docker 图像
  • B04。创建 Azure 函数并部署 docker 映像

另请参见下面的架构。

B0。运行 Selenium 的 Azure 函数(图片由作者提供)

B01。安装依赖项

需要安装以下先决条件:

B02。使用 docker 桌面创建 docker 图像

运行下面的命令从 git 克隆项目。如果您没有安装 git,也可以下载并解压缩 zip 文件。

git clone [https://github.com/rebremer/azure-function-selenium.git](https://github.com/rebremer/azure-function-selenium.git)

在此项目中,可以找到以下文件:

  • TimeTrigger/init。py: Python 文件,包含抓取网站的所有代码。这个 Azure 函数是时间触发的
  • HttpTrigger/init。py:与前面的项目符号相同,但是,这是 HTTP 触发的函数,可以从浏览器运行..
  • DockerFile:包含所有命令的文件,用于创建将在下一步中使用的 Docker 映像

B03。使用 docker 桌面创建 docker 图像

运行以下命令,在 Azure 函数基础映像上安装 chrome、chrome 驱动程序和 selenium。命令可以在 Visual Studio 终端或 PowerShell 终端中运行。对于<>、<>,您需要获取可以在访问键选项卡中找到的容器注册中心的凭证。

# Variables
$acr_id = "<<your acr>>.azurecr.io"# Create docker image using docker desktop
docker login $acr_id -u <<your username>> -p <<your password>>
docker build --tag $acr_id/selenium .# Push docker image to Azure Container Registry
docker push $acr_id/selenium:latest

B04。创建 Azure 函数并部署 docker 映像

运行以下命令创建一个 Azure 函数,并从 Azure Container Registry 部署 docker 映像。

# Variables
$rg = "<<your resource group name>>"
$loc = "<<your location>>"
$plan = "<<your azure function plan P1v2>>"
$stor = "<<your storage account adhering to function>>"
$fun = "<<your azure function name>>"
$acr_id = "<<your acr>>.azurecr.io"# Create resource group, storage account and app service plan
az group create -n $rg -l $loc
az storage account create -n $stor -g $rg --sku Standard_LRS
az appservice plan create --name $plan --resource-group $rg --sku P1v2 --is-linux# Create Azure Function using docker image
az functionapp create --resource-group $rg --os-type Linux --plan  $plan --deployment-container-image-name $acr_id/selenium:latest --name  $fun --storage-account $stor --docker-registry-server-user <<your acr user>> --docker-registry-server-password <<your acr password>>

B1。抓取网站并存储结果

上一步部署的 Azure 函数包含一个时间触发函数和一个 HTTP 触发器函数。在这一部分,该功能将被触发,刮网站和存储结果到一个数据湖帐户。执行以下步骤:

  • B11。创建数据湖帐户
  • B12。运行 HTTP 触发器功能

另请参见下面的架构。

B1_1。抓取网站(作者图片)

B11。创建数据湖帐户和更新功能

执行以下命令在 Azure 中创建一个数据湖帐户,并更新函数的设置。

# Variables
$rg = "<<your resource group name>>"
$fun = "<<your azure function name>>"
$adls = "<<your storage account>>"
$sub_id = "<<your subscription id>>"
$container_name = "scraperesults"# Create adlsgen2
az storage account create --name $adls --resource-group $rg --location $loc --sku Standard_RAGRS --kind StorageV2 --enable-hierarchical-namespace true
az storage container create --account-name $adls -n $container_name# Assign identity to function and set params
az webapp identity assign --name $fun --resource-group $rg
az functionapp config appsettings set --name $fun --resource-group $rg --settings par_storage_account_name=$adls par_storage_container_name=$container_name# Give fun MI RBAC role to ADLS gen 2 account
$fun_object_id = az functionapp identity show --name $fun --resource-group $rg --query 'principalId' -o tsv
New-AzRoleAssignment -ObjectId $fun_object_id -RoleDefinitionName "Storage Blob Data Contributor" -Scope  "/subscriptions/$sub_id/resourceGroups/$rg/providers/Microsoft.Storage/storageAccounts/$adls/blobServices/default"

B12。运行功能

时间触发功能将定期运行,以抓取网站。但是,还有一个 HTTP 触发的功能。获取 URL 后,可以在浏览器中复制并运行它,另请参见下文。

B12_1。运行 HTTP 触发功能(图片由作者提供)

运行该函数后,结果将存储在 data lake 帐户中,另见下文。

B12_2。存储在 ADLSgen2 帐户中的抓取结果(图片由作者提供)

C.结论

Selenium 是一个流行的网络抓取工具。然而,默认的 Azure Functions 映像不包含 Selenium 所需的依赖关系。在这篇博客中,Azure Functions 中创建了一个 web scraper 来安装这些依赖项,如下所示:

  • 使用 Selenium 创建并部署 docker 映像作为 Azure 函数
  • 定期抓取网站并存储结果

web scraper 的架构如下所示。

C.构建 Selenium web scaper 的架构(图片由作者提供)

如何创建一个简单的冠状病毒仪表板具体到您的国家在 R

原文:https://towardsdatascience.com/how-to-create-a-simple-coronavirus-dashboard-specific-to-your-country-in-r-732f87a9965f?source=collection_archive---------26-----------------------

了解如何在有限的时间内用 R 构建自己的冠状病毒仪表板。

介绍

新型新冠肺炎冠状病毒是目前最热门的话题。每天,媒体和报纸都在分享几个国家的新增病例和死亡人数,试图衡量病毒对公民的影响,并提醒我们呆在家里以保持安全。每个人都在谈论冠状病毒。

除了政府、媒体和公司在讨论这个问题之外,数据科学家和数据专业人员也在用他们的知识和时间为病毒服务。这导致应用程序、仪表盘、博客帖子、视频、数据集和代码的激增,以这样或那样的方式分析新冠肺炎的扩张及其如何在人群中传播。

冠状病毒的顶级资源

作为一名数据爱好者,我发现了大量关于冠状病毒的资源。然而,这些资源遍布互联网,并且通常被另一种类型的大量信息所隐藏(例如,令人担忧的头条新闻、受感染名人的姓名、炫耀他们如何帮助卫生保健机构的公司等)。).为了解决这个问题,我在之前的一篇文章中收集并分享了我遇到的关于冠状病毒的最佳资源。

注意,本文只分享 R 上的资源,因为 R 是我最喜欢的统计程序,也是我最熟悉的程序。事实上,我几乎每天都使用这个程序,这让我更容易意识到资源背后的复杂性和时间,并欣赏它的质量和潜力。我确信网上还有其他非常有趣的资源(例如约翰·霍普金斯冠状病毒资源中心的最受欢迎的仪表板)。尽管如此,许多人比我更有资格来评判用我不擅长的编程语言制作的资源的质量。

这篇文章让我发现了这么多关于冠状病毒的伟大资源,我不断收到来自世界各地科学家的数据可视化和数据分析,因此我将它们纳入了收集范围。正因如此,它不断提高了系列的质量和完整性。

除了接收 R 资源,读者经常问的一个问题是“我怎样才能自己创建一个仪表板?”或者“我如何构建一个特定于我所在国家的仪表板?”。因此,我认为,如果我创建一个针对我的国家(比利时)的仪表板,并详细说明如何创建它的步骤,会对一些人有所帮助。

关于如何开发这样的仪表板的问题大多来自 R 初学者,因为高级 R 用户很可能知道如何做,或者至少可以很容易地使用我在这里收集的资源作为他们自己工作的灵感来源。此外,为了应对对冠状病毒的狂热,感兴趣的用户非常着急,希望尽快拥有自己的仪表盘。

这些问题让我产生了创建一个简单的仪表盘的想法,而不是一个闪亮的应用。闪亮的应用程序的优势在于它们是交互式的,用户可以通过以用户友好的方式简单地改变一些输入来编辑输出和可视化,而仪表板是静态的,最终用户不能修改。另一方面,仪表板相对于闪亮应用的优势在于它更容易编码,尤其是如果你已经精通 R Markdown 的话。

冠状病毒仪表板:比利时的案例

在我到目前为止看到的所有可视化中,有一个因其简单性而突出,同时也因其完整性和可视化的质量而突出。因此,我决定在 Rami Krispin 已经存在的仪表板的基础上创建一个冠状病毒仪表板(它带有一个允许自由修改和共享的许可证),并对其进行修改,使其适用于比利时。请注意,我还从最初的仪表板中删除了一些可视化和表格,以保持其简单明了。

在进一步阅读之前,这里是我的冠状病毒仪表板适应比利时和以下主要部分的预览:

仪表板分为几个部分,可以在顶部选择:

  • 摘要部分提供了关于冠状病毒的关键指标(总病例数、活跃病例数和死亡数),以及一个显示从 2020 年 1 月 22 日到最近可用日期的活跃病例数和死亡数的图表。
  • “比较”部分显示了与其他欧洲国家(您也可以通过在代码中替换它们来更改这些国家)的每日新病例数(左图)和病例类型分布(右图)的比较。
  • 地图部分显示了确诊病例和死亡病例的世界地图。您可以取消选中一种或多种类型的案例(右上角)并放大或缩小(左上角)以使地图适应您的需求。
  • “关于”部分提供了有关数据、仪表板总体情况以及更新频率的更多信息。

我相信这个简单的仪表板很容易适应任何国家(以及从初学者到专家的任何人),并且仍然可以通过一些可视化来传达关于病毒的关键措施。值得一提的是,所有的图都是用{plotly}包生成的。这个软件包允许通过显示额外的相关信息来增强情节。).

如何创建自己的冠状病毒仪表板

如果您想构建自己的特定于某个国家的仪表板,请遵循以下步骤:

  1. 打开仪表板这里
  2. 通过位于仪表盘右上角的“源代码”按钮查看完整代码,或者查看 GitHub 上的代码。复制代码。
  3. 打开一个新的 R Markdown 文件(.Rmd),输入任何标题和作者(反正在下一步都会被替换),选择 HTML 作为输出格式,点击 OK:

4.删除已经存在的所有模板代码,并粘贴您在步骤 1 中复制的代码。

5.确保安装了所需的软件包:

install.packages(c("devtools", "flexdashboard", "leaflet", "leafpop"))
devtools::install_github("RamiKrispin/coronavirus", force = TRUE)

如果 R 问你想更新哪个包,应该没有必要更新它们:键入 3 表示“无”。

6.在代码中,将Belgium替换为您的国家。以下是数据集中所有可用国家的列表:

阿富汗阿尔巴尼亚阿尔及利亚安道尔安哥拉安提瓜和巴布达阿根廷亚美尼亚奥地利阿塞拜疆巴哈马巴林孟加拉 波黑巴西文莱保加利亚布基纳法索Cabo柬埔寨喀麦隆佛得角中非共和国乍得智利【T61 克罗地亚古巴塞浦路斯捷克吉布提多米尼加多米尼加东帝汶厄瓜多尔埃及萨尔瓦多【T93 冈比亚格鲁吉亚德国加纳希腊格林纳达危地马拉几内亚圭亚那海地以色列意大利牙买加日本约旦哈萨克斯坦肯尼亚韩国科索沃科威特吉尔吉斯斯坦 马耳他马提尼克毛里塔尼亚毛里求斯墨西哥摩尔多瓦摩纳哥蒙古黑山摩洛哥莫桑比克 **阿曼巴基斯坦巴拿马巴布亚新几内亚巴拉圭秘鲁菲律宾波兰葡萄牙卡塔尔塞尔维亚塞舌尔新加坡斯洛伐克斯洛文尼亚索马里南非西班牙斯里兰卡苏丹, **突尼斯土耳其乌干达乌克兰阿联酋乌拉圭乌兹别克斯坦委内瑞拉越南赞比亚****

请注意,如果您的国家/地区由两个或更多单词组成,您需要用反勾号将其括起来(但只能在代码中的一个特定行上,请参见英国的示例):

#----------------------------------------
# Plotting the datadaily_confirmed %>%
  plotly::plot_ly() %>%
  plotly::add_trace(
    x = ~date,
    y = ~`United Kingdom`,
    type = "scatter",
    mode = "lines+markers",
    name = "United Kingdom"
  ) %>%

不要在代码的其余部分添加反勾号,因为其他地方的国名都用双引号""括起来。

不要忘记更改文档顶部的标题和作者,并编辑文档底部的“关于”部分。最后但同样重要的是,正如你在摘要部分的图上看到的,箭头指向比利时不同的(sad)“里程碑”(即首例、首例死亡和新的遏制措施)。您需要为您的国家修改这些里程碑(如果您不想在图上显示任何里程碑,则删除它们)。在plotly::add_annotations()函数之后的代码中对此进行更改。

7.编织文档(如果您不熟悉 R Markdown,请参见此文章)。您的仪表板应该以 HTML 格式出现。

按照这 7 个步骤,您应该已经有了一个针对您所在国家的简单仪表板。我有意让它保持简单,这样每个人都可以在有限的时间内复制它并拥有自己的仪表板。

如果您熟悉用于仪表板界面和可视化的[{flexdashboard}](https://rmarkdown.rstudio.com/flexdashboard/)[{plotly}](https://plot.ly/r/)[{leaflet}](https://rstudio.github.io/leaflet/)包,以及用于数据操作的[{dplyr}](https://dplyr.tidyverse.org/)[{tidyr}](https://tidyr.tidyverse.org/)包,请根据您的需要随意编辑代码并改进您的仪表板。

附加注释

数据

这个仪表板的输入数据是从[{coronavirus}](https://github.com/RamiKrispin/coronavirus) R 包中获得的数据集。确保下载软件包的开发版本,以获得最新数据:

install.packages("devtools")
devtools::install_github("RamiKrispin/coronavirus")

要用最新的数据更新您的仪表板,您必须通过用devtools::install_github("RamiKrispin/coronavirus", force = TRUE)重新安装{coronavirus}包来手动更新数据。同样,如果 R 问你是否想更新其他包,输入 3 表示“无”。

这个问题经常被提出,所以我重复一遍,你的仪表盘不会每天自动更新,你需要手动更新。更新数据后,您可能还需要重新启动 R 会话,以便获得最新的可用数据。

原始数据来自约翰·霍普金斯大学系统科学与工程中心(JHU·CCSE)的冠状病毒

开放源码

这个仪表盘和 GitHub 上的代码都是开源的,所以你可以随意复制、改编和分享。

准确(性)

请注意,该仪表板主要用于教育目的。我尽可能频繁地更新仪表板,以保持其准确性。然而,关于新冠肺炎病例数存在一些不确定性,并且检测方法因国家而异,因此该仪表板上的数字与其他来源相比可能略有不同。目前,数据集的维护者每天都会更新它,但是将来更新的频率可能会降低。

发布您的仪表板

如果您想要共享您的仪表板,您可以:

  • 如果你有,把它上传到你的网站上(如果你还没有,我强烈建议你创建一个)
  • 通过 RPubs 发布(直接从 RStudio 发布你的作品是免费且容易的)

感谢阅读。我希望这篇文章能帮助你在 R 中建立你的第一个冠状病毒仪表板。如果你需要灵感来进一步增强你的仪表板,请查看这些关于冠状病毒的顶级 R 资源。

和往常一样,如果您有与本文主题相关的问题或建议,请将其添加为评论,以便其他读者可以从讨论中受益。

相关文章:

  1. 如果有人愿意用这种编程语言创建一个关于冠状病毒的资源集合,我会很高兴提到 Python 资源集合。如果是这种情况,请随时联系我

原载于 2020 年 3 月 23 日 https://statsandr.com

如何在简历中创建一个时间线

原文:https://towardsdatascience.com/how-to-create-a-timeline-of-your-cv-in-r-2528abaeb8db?source=collection_archive---------22-----------------------

简历时间线说明了你的教育、工作和额外活动的关键信息。

照片由hello queue拍摄

介绍

在这篇文章中,我将展示如何在简历中创建一份简历时间表。简历时间表展示了你的教育、工作经历和额外活动等关键信息。与普通简历相比,简历时间线的主要优势在于,它们通过视觉上的吸引力和更容易浏览,让你立刻脱颖而出。它还可以让你更好地展示你的“故事”,展示你的工作和活动的年表,从而解释你是如何走到今天的。(它也可以是你作品集的一部分,展示你的 R 技能。)

下面我们用一个最小的可重复的例子来展示如何在 R 中创建这样的 CV。请随意使用代码,并根据您的需要进行调整。更完整的例子(连同代码)你可以在这里查看我自己的 CV 时间轴。

请注意,我是在阅读了 Bernardo Lares 的这篇原帖之后写的这篇文章,特别是他的包,即[{lares}](https://github.com/laresbernardo/lares) 。特别感谢他的惊人工作,他的工作被用来创建一个稍微修改过的版本的[plot_timeline()](https://github.com/laresbernardo/lares/blob/master/R/other_plots.R#L19)函数!

最小可重复示例

下面是一个最小可重现示例的代码和结果:

如何个性化它

如果你想用你自己的学术、额外和工作经验来编辑这个例子,你基本上只需要编辑上面代码中名为cv的数据框架。数据集cv的每一行都是不同的学术项目、工作或活动。各行应包括:

  • 学术项目、职称或活动的名称
  • 大学、学校、公司或工作场所的名称
  • 类别:学术、工作经验或额外
  • 开始日期(日期必须采用yyyy-mm-dd的格式)
  • 结束日期。如果角色尚未结束,请键入today而不是日期。通过使用today,您的简历时间线将自动适应今天的日期

如果要添加或删除角色,请在数据框架中添加或删除一行。如果您不想指定任何工作场所,请注明NA(如同对Extra3所做的那样)。最后,不要忘记在代码末尾的时间线副标题中用你的名字替换我的名字。

有经验的 R 用户不妨根据自己的需求编辑plot_timeline2功能。然而,如果你对这个例子的模板和设计感到满意,你只需要改变上面提到的东西。

附加说明

除了直接在脚本中根据您的角色编辑代码,您还可以创建一个包含所需数据(职位、工作场所、类型、开始日期、结束日期)的 Excel 文件,然后将其导入 R 。编辑 Excel 文件更容易,也不容易出现编码错误。此外,如果您的职业生涯很长,代码可能会变得很长,而如果您导入 Excel 文件,它将始终保持简短和简洁。

感谢阅读。我希望这篇文章能帮助你在简历中建立一个时间表。如果你想看一个更完整和生动的例子,请看我的时间表简历

和往常一样,如果您有与本文主题相关的问题或建议,请将其添加为评论,以便其他读者可以从讨论中受益。

特别感谢 Job N Nmadu 教授关于创建保存数据的文件的建议。

相关文章:

原载于 2020 年 1 月 26 日 https://statsandr.com

如何用 Python 创建天气警报系统

原文:https://towardsdatascience.com/how-to-create-a-weather-alert-system-in-python-5fab4b42e49a?source=collection_archive---------15-----------------------

根据预测的天气数据发送电子邮件通知

Johannes Plenio 在 Unsplash 上拍摄的照片

通过阅读这篇文章,您将学会用 Python 创建一个天气警报系统,当它预测未来几小时内天空将下雨/下雪时,将向多个收件人发送电子邮件通知。电子邮件通知包含其他信息,如预测的温度和湿度。

本教程有 4 个部分:

  1. 设置
  2. 履行
  3. 结果
  4. 结论

让我们进行下一部分。

1.设置

天气 API

我将使用 ClimaCell 的 天气 API 来获取天气预报数据。它提供了相当多的有用和准确的数据,取决于你的需要。

在撰写本文时,它涵盖了过去 4 周的历史气象站数据以及未来 15 天的每日预报数据。此外,您可以轻松地实现它,因为官方文档提供了 4 种不同计算机语言的参考:

  • Java Script 语言
  • 红宝石
  • 结节
  • 计算机编程语言

一旦你注册了,你将被置于免费层,允许你每天打 1000 个电话,每小时 100 个。对于我们的用例来说,这应该足够了。

去注册一个新账户。完成后,您应该会看到下面的仪表板,其中概述了计划详情和您的通话活动。

作者图片

记下 API 键,因为我们将在后面的代码中使用它。

电子邮件配置

我将使用个人Gmail账户通过SMTP给自己发送电子邮件。为了使用它,您需要在帐户设置中更改配置,并打开Less secure app access

转到帐户设置,点击安全菜单。

作者图片

按如下方式打开Less secure app access

作者图片

完成后,在项目的根目录下创建一个名为config.ini的新文件。它将被用作我们项目的配置文件。将以下代码追加到其中。

[email]
email=your_email@gmail.com
host=smtp.gmail.com
port=587
password=your_password
  • email —您的电子邮件帐户名称
  • host—SMTP 服务器的主机名。根据电子邮件的 smtp 服务器对此进行修改
  • port—SMTP 服务器的端口。根据电子邮件的 smtp 服务器对此进行修改
  • password —您的电子邮件帐户的密码。确保不要将此文件或信息透露给其他人。

Python 模块

对于这个项目,强烈建议创建一个虚拟环境。在终端运行以下命令安装configparser模块。这对于从文件中加载配置设置非常有用。

pip install configparser

让我们转到小节部分,开始编写 Python 代码。

2.履行

在与config.ini相同的目录下创建一个名为weather_email.py的新文件。这个文件作为我们应用程序的电子邮件模块。

导入

在文件顶部添加以下导入声明

try:
    import configparser
except:
    from six.moves import configparserimport smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import requests

接下来,创建一个字典,代表下雨或下雪时我们将要发送的消息。您可以基于您的用例创建您自己的映射或定制消息。

weather_dict = {'freezing_rain_heavy': 'Heavy rain and snow', 'freezing_rain': 'Rain and snow', 'freezing_rain_light': 'Light rain and snow', 'freezing_drizzle': 'Light drizzle and snow', 'ice_pellets_heavy': 'Heavy ice pellets', 'ice_pellets': 'Normal ice pellets', 'ice_pellets_light': 'Light ice pellets', 'snow_heavy': 'Heavy snow', 'snow': 'Normal snow', 'snow_light': 'Light snow', 'tstorm': 'Thunder storm', 'rain_heavy': 'Heavy rain', 'rain': 'Normal rain', 'rain_light': 'Light rain'}

天气 API 的设置

初始化以下变量,这些变量是我们调用天气 API 时所需要的。

url = "[https://api.climacell.co/v3/weather/nowcast](https://api.climacell.co/v3/weather/nowcast)"querystring = {"lat":"1.29027","lon":"103.851959","unit_system":"si","timestep":"60","start_time":"now","fields":"temp,humidity,weather_code","apikey":"xxxx"}

我们将调用 nowcast API ,它有以下可以修改的参数:

作者图片

  • lat —纬度,-87°至 89°
  • lot —经度,-180°至 180°
  • unit_system —单位制,“国际单位制”或“美国单位制”
  • timestep —以分钟为单位的时间步长,1 到 60。将start_time设置为 now,将timestep设置为 60 将返回 7 个数据点。(现在,60 分钟后,120 分钟后,…)
  • start_time —您可以设置自己的时间或将其初始化为现在
  • end_time —限制结束时间的可选参数。默认情况下,它将返回自当前时间戳起 6 小时内的数据。
  • fields —从提供的数据层中选择的字段(如“降水”或“阵风”)。我在本教程中使用temphumidityweather_code
  • apikey —来自 Climacell 气象 API 仪表盘的 API 键。

EmailSender 类

我们将创建一个名为EmailSender的新类,并将其初始化如下。我们利用configparser 模块从config.ini读取数据,并将其分配给相应的变量。

def __init__(self):
    self.cf = configparser.ConfigParser()
    self.cf.read('./config.ini')
    self.sec = 'email'
    self.email = self.cf.get(self.sec, 'email')
    self.host = self.cf.get(self.sec, 'host')
    self.port = self.cf.get(self.sec, 'port')
    self.password = self.cf.get(self.sec, 'password')

在名为SendEmail的类中创建另一个函数,它接受一个接受者参数。它接受列表而不是字符串。这允许我们向多个电子邮件地址发送相同的电子邮件通知。

def SendEmail(self, recipient):

在函数内部,用下面的代码初始化一个新的MIMEMultipart对象

title = "Home Sweet Home"msg = MIMEMultipart()
msg['Subject'] = '[Weather Notification]'
msg['From'] = self.email
msg['To'] = ', '.join(recipient)

打电话给气象 API

下一步是通过请求模块调用 API,该模块将以 json 的形式返回结果。

response = requests.request("GET", url, params=querystring)
result = ""json_data = response.json()

您可以充分利用结果并将其映射到我们在上面指定的字典,以便创建所需的通知消息。然后,用它初始化一个MIMEText对象,并将它附加到MIMEMultipart对象上。最后,调用smtplib.SMTP上下文管理器发送电子邮件。

msgText = MIMEText('<b>%s</b><p>%s</p>' % (title, result), 'html')
msg.attach(msgText)with smtplib.SMTP(self.host, self.port) as smtpObj:
    smtpObj.ehlo()
    smtpObj.starttls()
    smtpObj.login(self.email, self.password)
    smtpObj.sendmail(self.email, recipient, msg.as_string())

查看以下要点获取完整代码。

您的根目录中应该有以下文件。

  • config.ini
  • 天气 _ 电子邮件. py

您可以在任何 Python 应用程序中轻松触发电子邮件提醒功能,只要这两个文件与您调用的 Python 文件位于同一个目录中。只需根据您的用例修改导入语句。以下示例概述了在未来 6 小时内下雨或下雪时向两个收件人发送电子邮件通知的代码。

import weather_emailemail_obj = weather_email.EmailSender()
email_obj.SendEmail(["email@gmail.com", "email2@gmail.com"])

结果

让我们看看我运行测试时的结果。我收到一个通知,告诉我我家正在下小雨。

作者图片

雨一停,我就运行同样的代码,它预测 6 小时后还会下雨。也许我应该回去,在下雨之前把我所有的衣服从晾衣架上拿走。

作者图片

结论

让我们回顾一下今天所学的内容。

我们从注册获取访问天气数据的apikey开始,并更改Gmail中的安全设置以允许Less secure app access用于我们的教程。此外,我们还创建了一个简单的配置文件来存储电子邮件认证数据。

接下来,我们实现了一个 Python 模块,该模块将调用天气 API,并在未来 6 个小时内无论何时有雪或雨时发送电子邮件通知。

到目前为止,您应该能够基于您拥有的用例创建自己的天气警报系统。感谢您阅读这篇文章,希望在下一篇文章中再次见到您!

参考

  1. 如何创建天气聊天机器人
  2. 用 Python 处理配置文件的技巧和诀窍

如何创建天气聊天机器人

原文:https://towardsdatascience.com/how-to-create-a-weather-chatbot-b8ef1b1d6703?source=collection_archive---------21-----------------------

集成 Rasa 堆栈的 React 天气聊天机器人

达拉斯·里德在 Unsplash 上拍摄的照片

通过阅读这篇文章,你将学会创建和部署你自己的天气聊天机器人。在本教程结束时,你应该有一个基本的聊天机器人,可以在用户询问时对当前的天气、温度和湿度做出适当的响应。

本教程有 4 个部分:

  1. 天气 API
  2. 罗砂
  3. 基于 React 的聊天室组件
  4. 结论

让我们进入下一部分

1.天气 API

为了获取天气数据,我将使用 ClimaCell 的天气 API 。它有一个免费层,每天最多可以打 1000 个电话,每小时 100 个电话,这对我们的使用案例来说绰绰有余。

前往登录页面并注册。登录到主页后,您应该会看到下面的仪表板。

作者图片

记住 API 键,因为我们稍后会用到它。

让我们继续下一部分,开始使用Rasa stack,这是一个开源的机器学习框架,用于自动化基于文本和语音的对话。

2.罗砂

装置

强烈建议您在继续安装软件包之前创建一个虚拟环境。通过以下命令安装Rasa

pip install rasa

通过运行以下命令,验证您已经安装了该模块

pip show rasa

初始化

确保终端位于项目目录的根目录下。通过运行以下命令初始化示例数据集:

rasa init

当它提示训练时,选择No (n),因为我们稍后需要再次训练它。目录中应该有以下文件。

作者图片

端点

取消对endpoints.yml中 action_endpoint 代码的注释

action_endpoint:
  url: "[http://localhost:5055/webhook](http://localhost:5055/webhook)"

NLU

nlu.md中添加一个名为ask_weather的新意图。提供几个里面的例子

## intent:ask_weather
- what is the weather now
- may i know the weather
- is it sunny outside
- is it raining now

领域

完成后,将domain.yml中的内容更改为以下内容。你可以在下面的要点中找到完整的代码。

故事

stories.md中追加以下代码。

## weather
* ask_weather
  - action_ask_weather

行动

如下更新actions.py中的代码。你可以在下面的要点中找到完整的代码。

您需要根据您的用例为querystring修改一些参数。我使用了当前位置的纬度和经度。我还指定了额外的字段,如temphumidity。请随意相应地修改它。

  • lat —纬度,-59.9 至 59.9
  • lot —经度,-180°至 180°
  • unit_system —单位制,“国际单位制”或“美国单位制”
  • fields —从提供的数据层中选择的字段(如“降水”或“阵风”)
  • apikey —来自 Climacell 气象 API 仪表盘的 API 键。

训练 Rasa 模型

接下来,我们将通过以下命令来训练它

rasa train

它可能需要一些时间来训练,您应该会看到一个名为 models 的新文件夹,其中包含一个以tar.gz结尾的文件。

运行 Rasa 和操作服务器

下一步是运行Rasa ServerAction server。让我们从Action Server开始。在现有终端中,运行以下命令启动操作服务器。它将默认为端口 5055。

rasa run actions

您应该在终端看到以下输出

作者图片

打开一个新的终端,激活同一个虚拟环境。将目录更改为与上一个终端相同的目录。运行以下命令启动服务器。默认端口是 5005。

rasa run --enable-api --cors "*"

需要cors以允许安全的数据传输,并防止您获得跨源资源共享错误。终端将显示以下输出。对于 Windows 用户,需要使用双引号来确保CORS 注册正确。

作者图片

让我们继续下一部分,实现天气聊天机器人的 UI。

3.基于 React 的聊天室组件

对于本教程,我将使用一个由Scalableminds团队开发的现成的 UI 框架。前往下面的 github 库并将其克隆/下载到您的机器中。将其解压缩,并将所有文件放在与Rasa文件不同的目录中。

github 官方页面提供的说明是基于yarn的,但我将在本教程中使用npm

确保你已经在你的机器上安装了Node.js。打开一个新的终端,更改到package.json所在的chatroom-master根目录。修改package.json中第 35 行的代码

"prepare": "yarn build",

"prepare": "npm build",

当且仅当您使用npm来安装软件包时,才需要此修改。

装置

接下来,运行以下命令来安装必要的模块。

npm install  //for npm user
yarn install //for yarn user

它将创建一个名为node_modules的新文件夹,并在其中安装所有列出的包。

chatroom-master中应该有以下文件和文件夹

作者图片

建设

在构建文件之前,确保 Rasa 服务器使用端口 5005。如果您正在使用其他端口,您需要更改index.html中的第 18 行。

host: "[http://localhost:5005](http://localhost:5005)",

通过运行以下命令来构建文件。

npm run build  //for npm user
yarn build     //for yarn user

服务

它将创建一个名为 dist 的新文件夹,并在其中创建所需文件的缩小版本。之后,你可以简单地通过跑步来发球

npm run serve //for npm user
yarn serve    //for yarn user

您应该在控制台上看到以下输出

作者图片

打开浏览器并转到以下 url

[http://localhost:8080/index.html](http://localhost:8080/index.html)

它应该加载 chatbot 界面供您测试。目前,它只能回答基本的问题,并为您提供天气信息。

作者图片

4.结论

祝贺您完成教程。让我们回顾一下今天所学的内容。

我们从注册获取访问天气数据的apikey开始。

然后,我们继续安装必要的包,比如Rasa。我们修改了数据集,增加了额外的意图和天气故事。一旦我们完成培训,我们就开始Action ServerRasa Server

对于聊天机器人 UI,我们使用了一个基于 React 的组件,并通过npm run serve正常提供服务。您可以根据自己的偏好和用例轻松扩展和修改它。

感谢你阅读这篇文章。希望在下一个教程中再见到你!

参考

  1. Rasa NLU 意向分类和命名实体识别入门指南
  2. 使用 Rasa 和自定义标记器的多语言聊天机器人
  3. 基于 React 的 Rasa Stack 聊天室组件
  4. Rasa 开源

如何用 10 步打造世界级人工智能国家战略

原文:https://towardsdatascience.com/how-to-create-a-world-class-ai-national-strategy-in-10-steps-eec5bc1f91fd?source=collection_archive---------52-----------------------

关于马耳他及其如何成为世界上人工智能排名前 10 位的国家的案例研究

照片由 MaximalfocusUnsplash 上拍摄

世界目前正在进行一场全球人工智能(AI)竞赛。各国每年投入数十亿美元试图获得全球霸权。他们很清楚,谁在这场游戏中处于领先地位,谁就会从巨大的经济利益中受益。因此,不同国家(如美国或中国)甚至经济集团(如欧盟)成为全球领导者的竞赛已经开始。

马耳他是地中海中部的一个小国,人口约 50 万。它是最小的欧盟国家之一,并渴望成为最终的人工智能发射台。以下是马耳他为制定战略而采取的步骤:

步骤 1:建立一个国家工作队

马耳他政府做的第一件事是任命一个旨在制定“马耳他. ai 战略”的国家工作队。工作队的成员来自各行各业,他们带来了经验和热情。人们可以找到经验丰富的学者、经验丰富的行政人员、法律专家、官僚、企业家和政策协调员等。此外,为了协助这个工作队,还有其他组织和各种小组委员会,它们的任务是侧重于具体的主题。

第二步:目标远大

当在一场全球竞赛中竞争时,一个人必须志存高远,然后找到实现目标的方法。就 Malta.ai 战略而言,国家工作队的任务是使马耳他成为全球 ai 前 10 名的国家之一。不是一个微不足道的任务!然而,该国在过去已经取得了相当大的成功。过去几十年见证了在线游戏、金融、医药和区块链行业的建立。所有这些对马耳他经济来说都非常成功。

第三步:现实点

设定高目标很容易,但需要脚踏实地。我们知道在金融战线上我们无法与其他国家竞争。未来十年,中国将在人工智能领域投资 1000 亿美元。德国、英国和美国紧随其后。所以我们决定找一个适合我们特殊情况的利基市场。AI launchpad 的想法来自于这样一个事实,即我们认为马耳他是一个岛国,具有典型国家的所有活力,但在地理上局限于一个小空间。这些条件使得测试新技术、验证新技术并将其部署到全球市场变得更加容易和便宜。

此外,马耳他是一个欧洲国家,拥有受过高等教育的劳动力,并且靠近北非和中东,这一事实使其更具吸引力。我们令人难以置信的 300 天的阳光,各种各样的历史和有趣的景点以及地中海的生活方式使这个岛屿对外国人才具有吸引力。因此,马耳他为任何想在全球部署人工智能解决方案的人提供了一个独特的包。

步骤 4:确定促成因素

促成因素是构成战略的基本组成部分。没有它们,我们就无法构建人工智能系统。这些包括底层基础设施(如宽带连接)、法律和道德框架以及教育和劳动力促进因素。我们相信,只有具备这些有利条件,我们才能建立一个坚实的人工智能战略。

步骤 5:确定利益相关者

任何战略要想成功,所有利益相关者都必须参与进来。工作队需要与不同的利益相关者建立信任关系,因为一旦政策到位,他们的帮助对政策的实施至关重要。因此,确定所有可能参与其中的组织或个人是至关重要的。

步骤 6:教育利益相关者

教育对于有效的战略至关重要。许多利益相关者可能听说过 AI,他们甚至可能知道缩写代表什么,但他们中的大多数人不知道它是什么。我们的调查显示,大多数人都不知道他们已经使用基于人工智能的系统几十年了。他们可以肯定的一件事是好莱坞大片喂给他们的,即邪恶的人工智能革命将接管世界,杀死所有人类。正因为如此,教育利益相关者,消除他们的恐惧,并让他们真正了解对人工智能的期待是至关重要的。

第七步:会见不同的利益相关者

一旦得到通知,工作队的小组委员会就与各利益攸关方组织各种一对一的会议。这些会议涉及多种讨论,涉及前进的道路,实现我们目标的路径,以及如何帮助那些可能受到人工智能崛起严重影响的人(如失业)。

步骤 8:全球盘点

除了当地情况之外,还必须了解我们周围正在发生的事情。我们知道今天有超过 50 个国家有他们自己的人工智能战略。正因为如此,我们想确保我们没有复制其他人的方法。此外,我们希望确保我们的提案具有独特的销售主张,因为毕竟,我们希望制定一项战略,为我们的小岛吸引投资。

第九步:整理信息

在所有这些工作之后,我们从当地和国际来源收集了所有数据。我们在一份文件中整理了所有的东西。因为我们需要一些额外的反馈(比如人工智能伦理框架),所以文本的一些部分被提前发布了。一旦我们拥有了一切,最终的文档经过了各种迭代,我们讨论了它的内容,并确保它满足我们最初的概要。

步骤 10:启动战略

所有这些工作之后剩下的最后一件事实际上是启动战略。政府接受了我们的文件,它通过国家预算提供资金,我们现在正与不同的利益攸关方和实体一起实施这一文件。

在一年内完成如此雄心勃勃的任务不是一个容易的目标,但我很高兴我们成功地做到了。此外,在其发布几个月后,就政府战略而言,Tortoise Media 将马耳他的国家人工智能战略在 54 个国家中排名第 10 位,大大超过了爱沙尼亚、瑞典和奥地利等国家。在如此短的时间内取得如此令人印象深刻的成绩,令人非常满意。然而,这并不意味着我们已经达到了目标。我们在其他方面还需要改进。该调查将马耳他在人才方面排在第 17 位,在研发方面分别排在第 36 位和第 25 位。然而,结果非常令人鼓舞;它将马耳他放在人工智能的国际地图上,并使我们朝着成为全球人工智能发射台的正确方向前进。

请在下面留下你的想法。如果你喜欢这篇文章,请跟我来🐦推特,🔗 LinkedIn 或者😊脸书

原载于 2020 年 3 月 2 日https://Howard . ai

阿列克谢·丁力教授 是马耳他大学的 AI 教授。二十多年来,他一直在人工智能领域进行研究和工作,协助不同的公司实施人工智能解决方案。他的工作被国际专家评为世界级,并赢得了几个当地和国际奖项(如欧洲航天局、世界知识产权组织和联合国等)。他出版了几本同行评审的出版物,并且是马耳他的一部分。由马耳他政府成立的人工智能特别工作组,旨在使马耳他成为世界上人工智能水平最高的国家之一。

如何创建基于代理的仿真模型

原文:https://towardsdatascience.com/how-to-create-an-agent-based-simulation-model-37bd7b4b0da7?source=collection_archive---------41-----------------------

根据电视剧《冰雪奇缘》改编

作者提供的图片(哈希可视化的屏幕上限)

需要模拟一个复杂的系统,包含许多自主运行的个体?那么一款 基于代理的型号 可能正是你所需要的!你可能听说过康威的生命游戏,这是这种模型的最早的例子之一,由传奇数学家约翰·何顿·康威创造。

为了建立这样一个模型,我们需要三样东西,每样东西都将在本文中解释:

  1. 概念:模型的超参数
  2. 框架:底层代码基础设施
  3. 行为:决定代理如何行动的顶层代码

概念:阶级斗争(在火车上!)

最近看了 扫雪者 电视剧;一部反乌托邦科幻小说,其中人类的最后残余存活在一列火车上,分成不同的阶级。这一系列提出了许多哲学问题,我认为最好通过建立一个基于代理的模拟模型来回答。

要建立一个火车社会的仿真模型,我们首先需要的是参数;列车有多大,有多少代理/乘客,他们在列车上是如何分布的?为了回答这些问题,并为我们的模型设置输入,我查看了我可以从电视剧中收集到的信息。

火车上有 3000 名乘客,分成四类:一等、二等、三等和“尾巴”(偷渡者)。我们被告知尾部有 400 人,三等舱有 1700 人。没有人告诉我们头等舱和二等舱的比例,所以我只能猜测是 250/650。

为了使数字更容易处理,我们的模型将有 1 个代理代表 10 名乘客,火车车厢也是如此。

我们被告知有 1001 节车厢,其中大部分用于种植作物或饲养牲畜。在没有任何进一步信息的情况下,我只能猜测大约只有一半的车厢用于人类居住,其余的车厢以 6/9/14/1 的比例分成一等车厢/二等车厢/三等车厢/尾部车厢。

虽然代理将能够在车厢之间移动,但是我们输入到模型中的这些初始值将意味着一些车厢比其他车厢更加拥挤(例如,尾部将比头等车厢更加拥挤)。

模型的目的是运行实验。鉴于 Snowpiercer 的主题是关于阶级划分,我们将运行两个场景;要么火车被分成上述四个等级,要么我们有一个单一的等级,所有乘客在车厢中平均分配。

作者图(哈希的屏幕盖)

框架:哈希平台

我很忙,我真的没有时间从头开始构建运行基于代理的仿真模型所需的代码。幸运的是,其他人已经为我做了这些,那些人是 HASH 的人,他们建立了一个平台,提供了我们需要的所有底层代理机制。再加上他们的支持者包括 KaggleStackOverflow 的创始人,这就让人放心了。

哈希框架提供了所有代理机制的基本构件;如何创建或删除它们,它们如何通过相互发送消息进行交互,以及将您自己的自定义行为附加到代理的简单方法(使用 Python 或 Javascript)。此外,它有一个漂亮的 3D 可视化模拟运行(如本文顶部所示)!

哈希项目就像 git 存储库,所以很容易派生或共享。例如,您可以通过单击下面的链接自己运行我的模拟(但是为了理解代码,您可能想先读完本文)。

[## 雪地穿刺器-哈希

这是一个基于智能体的模拟模型,模拟一个完全生活在一列火车里的社会。概念和超参数…

hash.ai](https://hash.ai/@gmorinan/snowpiercer)

尽管这个框架很棒,但我们仍然需要自己编写模型的细节,这些代码包含在这 14 个项目文件中:

因此,让我们深入了解对模拟运行至关重要的全局和行为文件的细节…

行为:快乐的乘客,快乐的火车

Snowpiercer 的一个关键主题是资源的差异,其中一个关键资源是空间。为了对此进行调查,我们将对乘客情绪进行建模,由此,如果乘客的空间有限,即如果他们所在的列车车厢过于拥挤,乘客的情绪将会下降。

为了解释这一点,让我们从查看全局输入开始。首先,我们有“拓扑”,这是一个特殊的关键字,哈希将自动转换为模拟发生的区域,以及代理用来确定其邻居是谁的搜索半径。

接下来,“设置”输入是我们在模拟开始时运行的两种行为所使用的输入,其中大部分包括与列车上的四个等级相对应的四个元素列表。例如,' class_numbers '告诉模型我们希望尾部有 40 个代理,三等舱有 170 个代理,依此类推。而‘car _ id’和‘wall _ id’告诉模型‘蓝图’中的哪些数字转换成用于哪些类的列车车厢和墙壁。

最后,“属性”输入决定了代理机制。代理人的颜色从红色到黄色不等,取决于他们有多开心。而三个情绪值是通用常数;“mood_incr”控制过度拥挤时情绪如何降低,“mood_baseline”控制没有过度拥挤时情绪如何增加,“mood_edge”控制每次迭代的最小随机性。

为了将这些全局变量放入上下文中,让我们看看行为脚本,从“create_passengers.py”开始,它只在第一次迭代中运行。该脚本执行以下操作:从 globals.json 中检索输入变量,使用火车蓝图来确定哪些位置属于哪些火车车厢,然后将代理放置到适当火车车厢内的随机空间中,同时使用三角形分布为它们分配随机的开始情绪(和相应的颜色)。最后,它向控制模拟的特殊“散列”代理发送一个“create_agent”消息,就这样我们创建了我们的乘客。

一旦你理解了这个脚本,理解“create_walls.py”就变得很简单了,它创建了静态的虚拟代理,只用来阻止乘客的移动。

现在设置好了,让我们看看控制代理如何操作每次迭代的行为;“move.py”将在每次迭代中对每个乘客运行。此函数的“状态”输入是它运行的乘客的状态,在这种情况下,我们使用它来获得代理的 xy 坐标,以计算它可能做出的所有可能的移动。乘客查看附近是否有墙,并相应地调整可能的移动以避免在墙中结束,然后从剩余的选项中随机选择一个移动。

“proximity.py”行为展示了内置于 HASH 中的消息传递机制。如果一名乘客靠近不止一名其他乘客,它会向所有乘客发送一条信息,抱怨过度拥挤,这些信息会反馈到下一个行为中…

最后,“update_mood.py”是数学发生的地方。乘客检查它有多少投诉消息。然后,使用决定情绪的全局变量,它创建一个三角形分布,从中随机选择一种新的情绪。越拥挤,情绪下降的机会就越大。虽然“情绪边缘”全局意味着即使乘客过度拥挤,情绪也有小的机会上升,反之亦然。

现在我们理解了代码,让我们看看结果…

结果

我们运行上面概述的两个场景(四个类或一个类),每个场景进行 365 次迭代,在下面的动画直方图中总结结果。在这两种情况下,乘客情绪开始时为单峰分布,约为 0.5,但几天后变为双峰分布,群集在 0 和 1 处。

按作者分列的数字

从这里我们可以得出什么结论?虽然动画看起来不错,但有时一个简单的时间序列能更清楚地显示结果。下面我们可以看到,在一个班级的情况下,平均情绪更高。这很大程度上是因为,在四个等级的情况下,由于过度拥挤,尾部乘客的情绪会迅速下降。

按作者分列的数字

我们需要记住基于代理的模拟是随机过程,这些结果只是模型的一次运行。在得出任何确定的结论之前,应该多次运行模拟模型,并一起查看所有运行的结果。

还应该对全局输入进行一些敏感性分析。例如,在这个模型中,将“mood_incr”常数加倍将会得到非常不同的结果。

模型的信息量取决于其假设的准确性。

不相信我?尝试用您喜欢的任何输入自己运行它:

[## 雪地穿刺器-哈希

这是一个基于智能体的模拟模型,模拟一个完全生活在一列火车里的社会。概念和超参数…

hash.ai](https://hash.ai/@gmorinan/snowpiercer)

如何创造一个像你一样聊天的人工智能

原文:https://towardsdatascience.com/how-to-create-an-ai-that-chats-like-you-cb3484824797?source=collection_archive---------9-----------------------

照片由帕特里克·福尔Unsplash 拍摄

实践教程

使用你的 WhatsApp 和 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 数据,与 GPT-2 神经网络进行训练和聊天

路标

本指南的目标是建立一个能够像你一样聊天的系统,使用你自己的 WhatsApp 和 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 聊天作为 ML 数据集。

我们要做的可以概括为以下步骤:

  1. 获取您的 WhatsApp 和 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 数据
  2. 解析它以构建一个 ML 就绪的数据集
  3. 列车 a GPT-2 型号
  4. 与模特聊天

所以让我们开始我们的冒险吧!

你想看到一些结果吗?查看官方网页,注意它们是基于我的个人聊天的意大利语

GIPHY 来源

⚠警告:

最好不要对个人信息(如个人聊天信息)运行随机脚本。

我保证没有漏洞,但你可以随时检查正在使用的本机代码: 消息传递-聊天-解析器pistoBot ,所有的源代码都是在 github 上开源的

1.获取数据

首先,我们需要从我们的聊天应用程序中收集数据。我们现在将学习如何从两个最常用的即时通讯应用程序中导出数据: WhatsApp丨t丨e丨l丨e丨g丨r丨a丨m丨s丨。

1.1 WhatsApp 导出

我们必须出口一辆。txt 文件,用于我们希望包含在最终数据集中的每个聊天。所以,正如WhatsApp 官方网站上描述的:

  1. 打开你的 WhatsApp 手机应用
  2. 选择个人聊天一个个人聊天(例如与一个朋友聊天)>点击“更多选项”(三个垂直点)
  3. 选择语音>多导出聊天语音
  4. 在弹出窗口中选择无介质的
  5. 选择一种电子邮件服务(如 Gmail 应用程序)并将您的电子邮件地址添加为收件人
  6. 等待以 txt 文件附件的形式接收带有聊天记录的邮件
  7. 下载 txt 附件并存储在计算机上
  8. 对您想要包含的每个个人聊天重复这些步骤

请注意,只允许一对一聊天(即个人),我们建议导出消息数量最多的聊天,以获得更大的数据集和更好的最终结果。

现在,您应该有更多的文件,每个文件的结构类似于下面的代码片段:

*12/12/19, 02:09 — <FriendName>: bla bla bla bla
12/12/19, 08:40 — <YourName>: bla bla bla bla*

记下您在导出的聊天中在 <您的姓名> 占位符下找到的文本。这个参数是 WhatsApp 应用程序的名称,我们稍后将使用这个值。

1.2 电报

这里的过程将比 WhatsApp 更快,因为 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 将在单个中导出所有内容。json 文件,没有一次导出一个聊天的限制。

所以,如官方电报网站所述:

  1. 打开电报桌面 app
  2. 打开屏幕左上角的菜单(三条水平线)
  3. 进入设置语音>点击高级>选择导出电报数据**
  4. 只能选择这些字段:
    账户信息、联系人列表、个人聊天、机器可读 JSON
  5. 确保在媒体导出设置下没有选择任何内容,并将尺寸限制设置为最大
  6. 启动导出并等待
  7. 将输出文件重命名为“ 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨_dump.json

现在你应该有一个名为 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨_dump.json 的文件,其结构如下:

*{
 "about": "Here is …",
 "personal_information": {
 "user_id": 123456789,
 "first_name": "your_name_here",
 "last_name": "",
 ....*

2.解析数据

为了训练一个 GPT-2 神经网络,首先我们需要预处理数据,以获得单个。txt 具有机器学习兼容结构。

2.1 谷歌可乐

为了简单起见,由于我们将使用的 ML 模型需要 GPU 来工作,我们将在下一步使用 Google Colab。

如果你不知道 Google Colab 是什么,可以看看这篇文章:

* [## Google Colab 入门

沮丧和困惑的基本教程

towardsdatascience.com](/getting-started-with-google-colab-f2fff97f594c)

2.2 启动笔记本

打开本 Colab 笔记本并遵循以下步骤:

  1. 运行“0️⃣初始化”章节下调用的第一个单元格块
  2. 在弹出窗口中按“无论如何都要运行”
  3. 确保第一个命令!nvidia-smi 显示连接了 GPU(建议 p100)
  4. 如果没有连接 GPU,转到运行时>更改运行时类型>硬件加速器> GPU

特斯拉 T4 GPU 正确连接时的输出示例。|作者图片

2.3 加载数据

为了处理这些数据,我们需要将它们上传到 Colab 上正确的文件夹中。

WhatsApp 聊天 选择你所有的。txt 文件,并将所有东西上传到下面的笔记本文件夹:
。/messaging-chat-parser/data/chat _ raw/whatsapp/

丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 JSON 获取文件 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨_dump.json 上传到以下笔记本文件夹:
。/messaging-chat-parser/data/chat _ raw/丨t丨e丨l丨e丨g丨r丨a丨m丨s丨/

聊天上传后的笔记本文件示例|作者图片

2.4 解析数据

现在,运行所有的单元格,直到块“2️⃣解析数据”。

这里我们需要把变量“whatsapp_user_name”替换成你的 whatsapp 名称,在 1.1 章节上叫做 < YourName >

如果由于本地时间格式,某些导出的数据显示不同的格式,您也可以更改日期格式解析系统。

用于设置用户名的单元格。|作者图片

例如,如果我的名字是“Bob ”,我来自美国,我应该使用以下代码:*

3.训练 GPT-2 模型

现在执行“3️⃣培训 GTP2 模型”笔记本章节下的单元,它将使用您提供的数据运行新的培训。

将显示一个进度条,培训可能需要 10 个小时,这主要取决于 Colab 运行的 GPU 类型以及提供了多少消息。

等待该过程结束。

常见的“我在等我的神经网络列车”姿势| GIPHY 来源

4.与模特聊天

训练完成后,运行所有剩余的笔记本单元格:最后一个单元格将显示一个左侧带有✍符号的文本块。

您可以使用这个文本框来插入您想要“发送”到 ML 模型的消息。所以写下你的信息,然后按下回车键。

在文本框上书写消息的示例。|作者图片

4.1 如何读取结果

第一条消息发出后,系统会提示一些关于对话的信息。

现在,您将看到最有趣的结果,显示为邮件列表:

  • 以标签【其他】 :开头的消息,您发送给模特的那些
  • 以标签【me】:
    开头的消息,由模型生成的
    消息。****

回复的消息生成后,您可以继续聊天,总共 5 条消息。在此之后,您可以重新运行单元,开始与模型的新对话。

我写的一些消息的例子(标签为【其他】)和由模型生成的消息(标签为【我】)。聊天是在意大利,因为模型是在我自己的聊天训练。|作者图片**

5.结论

因此,在本指南中,我们已经看到从头开始训练你的 GPT-2 模型是多么简单,任务是简单的(但不是微不足道的!)多亏了在活塞罩下运行的 aitextgen 软件包。

请注意,如果您的聊天信息是英文的,您可以轻松获得比我们用这种标准方法获得的结果更好的结果,因为您可以使用来自 GPT-2 预训练模型的迁移学习。**

pistoBot 资源库允许您训练(或微调)不同的模型,包括从 GPT-2 预训练模型开始的机会:查看资源库文件夹了解更多信息。

我们选择了标准的,未经训练的 GPT-2 模型,这样即使是非英语用户也可以使用这个人工智能。

如何在 Jupyter 中创建动画条形图

原文:https://towardsdatascience.com/how-to-create-an-animated-bar-chart-in-jupyter-9ee1de8d0e80?source=collection_archive---------28-----------------------

使用 Plotly Python 显示最新美国失业率的数据可视化

乔尔·士迪佛立在 Unsplash 上拍摄的主要照片。作者 Photoshop。

**Table of Contents**[**Introduction**](#dd46)1\. [Data preparation](#5e4a)
2\. [Animated Bar Chart](#52ad)
3\. [A line chart](#ecd9)[**Conclusion**](#6e8e)

介绍

每个新闻媒体都报道了新冠肺炎造成的经济困难。辐射尘不成比例地影响了黑人社区。

圣路易斯美联储银行更新了其失业率数据。观测范围因数据集而异,但最新数据是 2020 年 5 月的。我们将使用 Jupyter 上的一个生动的条形图来可视化一年来失业率是如何随着种族和性别而变化的。

本文假设您已经熟悉 JupyterLab/Jupyter 笔记本的基本操作。

精心安装

plotly.py 可以使用 pip 安装。

$ pip install plotly==4.8.1

对于 Conda 用户:

$ conda install -c plotly plotly=4.8.1

JupyterLab 支持(Python 3.5+)

使用画中画:

$ pip install jupyterlab "ipywidgets>=7.5"

对于 Conda 用户:

$ conda install jupyterlab "ipywidgets=7.5"

然后运行以下命令(您需要安装节点):

# JupyterLab renderer support 
$ jupyter labextension install jupyterlab-plotly@4.8.1  
# OPTIONAL: Jupyter widgets extension 
$ jupyter labextension install @jupyter-widgets/jupyterlab-manager plotlywidget@4.8.1

[## 如何在 Docker 上运行 Jupyter 笔记本

不再有 Python 环境和包更新

towardsdatascience.com](/how-to-run-jupyter-notebook-on-docker-7c9748ed209f) [## 如何用不到 15 行代码创建一个动画的 Choropleth 地图

在 Jupyter 上使用 Python 中的 Plotly Express

towardsdatascience.com](/how-to-create-an-animated-choropleth-map-with-less-than-15-lines-of-code-2ff04921c60b) [## Jupyter 上 Plotly 的折线图动画

Plotly 统一悬停模式,按钮和更多

towardsdatascience.com](/line-chart-animation-with-plotly-on-jupyter-e19c738dc882)

数据准备

所有数据源。图片作者

以上数据为 20 年。&超过(LNS 14000024)20 年。&结束,白人男子 (LNS14000028), 20 年。结束,白人女性(LNS 14000029)20 年。超过 20 岁的黑人或非裔美国人。超过 20 岁的黑人或非裔美国妇女。超过 20 岁的西班牙裔或拉丁裔男性。超过,西班牙裔或拉丁裔女性。

我们将连接所有数据集,添加一个具有适当名称的类别列,并按日期过滤,这样所有数据集将具有相同的长度,如下所示。

最终数据集。作者图片

import pandas as pd
import plotly.express as px over20='https://gist.githubusercontent.com/shinokada/dfcdc538dedf136d4a58b9bcdcfc8f18/raw/d1db4261b76af67dd67c00a400e373c175eab428/LNS14000024.csv'
over20_white_men='https://gist.githubusercontent.com/shinokada/dfcdc538dedf136d4a58b9bcdcfc8f18/raw/d1db4261b76af67dd67c00a400e373c175eab428/LNS14000028.csv'
over20_white_women='https://gist.githubusercontent.com/shinokada/dfcdc538dedf136d4a58b9bcdcfc8f18/raw/d1db4261b76af67dd67c00a400e373c175eab428/LNS14000029.csv'
over20_black_men='https://gist.githubusercontent.com/shinokada/dfcdc538dedf136d4a58b9bcdcfc8f18/raw/7d63e7a7495dfb8578120016c7a7dd4edc04e20d/LNS14000031.csv'
over20_black_women='https://gist.githubusercontent.com/shinokada/dfcdc538dedf136d4a58b9bcdcfc8f18/raw/d1db4261b76af67dd67c00a400e373c175eab428/LNS14000032.csv'
over20_hispanic_men='https://gist.githubusercontent.com/shinokada/dfcdc538dedf136d4a58b9bcdcfc8f18/raw/f693c9bdd76875b12a14033cc54931da894bd341/LNU04000034.csv'
over20_hispanic_women='https://gist.githubusercontent.com/shinokada/dfcdc538dedf136d4a58b9bcdcfc8f18/raw/f693c9bdd76875b12a14033cc54931da894bd341/LNU04000035.csv' df_over20 = pd.read_csv(over20)
df_over20_wm = pd.read_csv(over20_white_men)
df_over20_ww = pd.read_csv(over20_white_women)
df_over20_bm = pd.read_csv(over20_black_men)
df_over20_bw = pd.read_csv(over20_black_women)
df_over20_hm = pd.read_csv(over20_hispanic_men)
df_over20_hw = pd.read_csv(over20_hispanic_women) def prepare(dfs, datefrom):
    result=[]
    for item in dfs:
        item.columns = ['date','rate','category']
        item = item[item['date']>= datefrom]
        result.append(item)
    return result dfs = [df_over20, df_over20_wm, df_over20_ww, df_over20_bm, df_over20_bw, df_over20_hm, df_over20_hw]
datefrom='2017-01-01'
categories = ['Average', 'White men', 'White women', 'Black men', 'Black women','Hispanic men', 'Hispanic women'] i=0
while i < len(categories):
    dfs[i].loc[:,'category'] = categories[i]
    i = i+1 df=prepare(dfs, datefrom)    
df = pd.concat(df, ignore_index=True)
display(df)

我们导入必要的库,熊猫和 Plotly.express。

我们使用 Github URLs 为每个数据创建变量。

我们使用read_csv读取所有逗号分隔值文件(csv 文件)。

我们创建一个名为prepare的函数。这个函数有两个参数,dfs一个数据帧列表,datefrom一个日期字符串。

我们创建一个空列表result。我们遍历数据帧列表来重命名列,使用datefrom变量过滤date字段,并将每个数据帧附加到result

我们使用所有数据帧datefromcategories定义一个变量dfs

我们使用dfscategories添加一个新列。

我们使用prepare函数dfsdatefrom作为自变量。

我们使用[concat](https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html)ignore_index=True参数组合所有数据帧。每个数据帧都有自己的索引,这使得我们可以忽略它们,从 0,…,n-1 开始标记索引。df的输出具有以下结构。

准备好的数据集。图片由作者提供。

动画条形图

plotly.express 模块是 plotly 用于快速图形生成的高级 API。

fig = px.bar(df, x="category", y="rate", color="category",
   animation_frame="date", animation_group="category", 
   range_y=[0,20])fig.update_layout(
    height=600,
    title_text='Over 20 Unemployment Rate in USA from'+datefrom+' to May 2020'
)fig.show()

每个 Plotly Express 函数返回一个graph_objects.Figure对象,我们使用[plotly.express.bar](https://plotly.com/python-api-reference/generated/plotly.express.bar.html)实例化它。我们设置参数,xycolor等。

我们使用update_layout来设置heighttitle,然后显示动画条形图。

从 2017 年 1 月 1 日到 2020 年 5 月 1 日的动画条形图。图片由作者提供。

黑人或非裔美国男子和妇女的失业率一直是两倍左右,在某些时期,他们是白人男子和妇女的两倍以上。我们看到最后所有数据集的突然峰值,但是比率的差异变小了。

折线图

下图显示了从 1972 年 1 月 1 日到 2020 年 5 月 1 日的失业率。我们选择五个数据帧,并改变datefrom值。如果你想创建一个折线图动画,请看这个帖子

df = pd.concat([df_over20, df_over20_wm, df_over20_ww, df_over20_bm, df_over20_bw], ignore_index=True)datefrom='1972-01-01'fig = px.line(df, x="date", y="rate", color="category",range_x=[datefrom,'2020-07-30'])
# fig.update_layout(hovermode='x unified')
fig.update_layout(
    height=600,
    title_text='Over 20 Unemployment Rate in USA from'+datefrom+' to May 2020'
)fig.show()

从 1972 年 1 月 1 日到 2020 年 5 月 1 日的美国失业折线图。图片由作者提供。

结论

一个动画条形图是一个很好的工具来显示由于新冠肺炎的失业率的戏剧性变化。Pandas 和 Python 使得合并和修改原始数据变得很容易。

在不久的将来,我想回顾一下这篇文章,看看不同群体的失业率是如何变化的。

通过 成为 会员,可以完全访问媒体上的每一个故事。

https://blog.codewithshin.com/subscribe

[## 如何用 Python 中的 Plotly Express 创建分组条形图

Python melt 函数将数据帧从宽到长格式化

towardsdatascience.com](/how-to-create-a-grouped-bar-chart-with-plotly-express-in-python-e2b64ed4abd7) [## 如何在 Jupyter 中创建交互式下拉列表

用下拉菜单更新图表

towardsdatascience.com](/how-to-create-an-interactive-dropdown-in-jupyter-322277f58a68) [## 如何在 Jupyter 中创建一个有吸引力的气泡图

从 Github repo 抓取数据的分步指南

towardsdatascience.com](/how-to-create-an-attractive-bubble-map-5cf452c244e9)

如何用不到 15 行代码创建一个动画的 Choropleth 地图

原文:https://towardsdatascience.com/how-to-create-an-animated-choropleth-map-with-less-than-15-lines-of-code-2ff04921c60b?source=collection_archive---------24-----------------------

在 Jupyter 上使用 Python 中的 Plotly Express

动画 choropleth 地图的截图。作者图片

**Table of Contents**[**Introduction**](#1eac)1\. [Choropleth maps](#189e)
2\. [Data](#5d9c)
3\. [Animated choropleth USA map](#ced3)
4\. [Animated choropleth world map](#b595)[**Conclusion**](#fdec)

介绍

Plotly Express 可以轻松创建动画图形。官方文件称,“尽管 Plotly Express 支持许多图表和地图类型的动画,但平滑的帧间过渡目前仅适用于散点图和条形图。”

尽管没有提到 choropleth 地图,但在本文中,你会发现在 Jupyter 上使用 Plotly 和 Python 创建动画 choropleth 地图是多么容易。

本文假设您已经熟悉 JupyterLab/Jupyter 笔记本的基本操作,并且已经安装了

Choropleth 地图

choropleth 地图是由彩色多边形组成的地图。 Plotly Express ' px.choropleth函数和底层go.Choropleth graph 对象可以创建 choropleth 地图,你可以在官网上找到一些例子。您只能放大或缩小地图。

非动画choropleth map ([code](https://gist.github.com/shinokada/c192a2d25f1c3f8224bb8ee7e35ded8a)). Image by author.

数据

我们将使用美国的谋杀率。数据最初是由联邦调查局公布的,并由Julia Poncela-Casasnovas修改。你可以在这里找到它**

**import plotly.express as px
import pandas as pddf = pd.read_csv('[https://gist.githubusercontent.com/shinokada/f01139d3a024de375ede23cec5d52360/raw/424ac0055ed71a04e6f45badfaef73df96ad0aad/CrimeStatebyState_1960-2014.csv'](https://gist.githubusercontent.com/shinokada/f01139d3a024de375ede23cec5d52360/raw/424ac0055ed71a04e6f45badfaef73df96ad0aad/CrimeStatebyState_1960-2014.csv'))
df = df[(df['State']!= 'District of Columbia' )]
df**

数据集的屏幕截图。图片由作者提供。

DataFrame 的列具有以下值。

**df.columns# Output
Index(['State', 'Year', 'Population', 'Violent_crime_total',
       'Murder_and_nonnegligent_Manslaughter', 'Murder_per100000',
       'Legacy_rape_/1', 'Revised_rape_/2', 'Robbery',   'Aggravated_assault', 'State_code'], dtype='object')**

** [## Jupyter 上 Plotly 的折线图动画

Plotly 统一悬停模式,按钮和更多

towardsdatascience.com](/line-chart-animation-with-plotly-on-jupyter-e19c738dc882) [## 如何在 Jupyter 中创建动画条形图

使用 Plotly Python 显示最新美国失业率的数据可视化

towardsdatascience.com](/how-to-create-an-animated-bar-chart-in-jupyter-9ee1de8d0e80)

动画合唱团美国地图

import plotly.express as px
import pandas as pddf = pd.read_csv('[https://gist.githubusercontent.com/shinokada/f01139d3a024de375ede23cec5d52360/raw/424ac0055ed71a04e6f45badfaef73df96ad0aad/CrimeStatebyState_1960-2014.csv'](https://gist.githubusercontent.com/shinokada/f01139d3a024de375ede23cec5d52360/raw/424ac0055ed71a04e6f45badfaef73df96ad0aad/CrimeStatebyState_1960-2014.csv'))
df = df[(df['State']!= 'District of Columbia' )]px.choropleth(df, 
              locations = 'State_code',
              color="Murder_per100000", 
              animation_frame="Year",
              color_continuous_scale="Inferno",
              locationmode='USA-states',
              scope="usa",
              range_color=(0, 20),
              title='Crime by State',
              height=600
             )

第 1–5 行:

导入plotly.expresspandas。我们使用pd.read_csv创建一个数据帧。我们删除了State列下的哥伦比亚特区行。

第 7–17 行:

我们实例化[plotly.graph_objects.choropleth](https://plotly.github.io/plotly.py-docs/generated/plotly.graph_objects.Choropleth.html#plotly-graph-objs-choropleth)对象并设置参数。

  • location:此参数通过位置 id 或名称设置坐标。我们对locations使用State_code列值。
  • color:我们用Murder_per100000值来改变状态的颜色。
  • animation_frame:这允许我们制作动画,并在地图下添加播放和停止按钮。
  • locationmode:确定将locations中的条目匹配到地图上的区域。值为“ISO-3”或“美国各州”。
  • [scope](https://plotly.com/python/map-configuration/#named-map-scopes-and-country-subunits):将地图限制在此值。可用的范围有::'world''usa''europe''asia''africa''north america''south america'
  • rang_color:决定右边刻度的数值。使用 0 和最大值。
  • title:是地图的平铺。
  • height:是高度创建图。
  • color_continuous_scale:我们可以从以下列表中设置任意配色方案。
from textwrap import wrap named_colorscales = px.colors.named_colorscales()print("\n".join(wrap("".join('{:<12}'.format(c) for c in named_colorscales), 96)))# Output
aggrnyl     agsunset    blackbody   bluered     blues       blugrn      bluyl       brwnyl      bugn        bupu        burg        burgyl      cividis     darkmint    electric    emrld       gnbu        greens      greys       hot         inferno     jet         magenta     magma
mint        orrd        oranges     oryel       peach       pinkyl      plasma      plotly3     pubu        pubugn      purd        purp        purples     purpor      rainbow     rdbu        rdpu        redor       reds        sunset      sunsetdark  teal        tealgrn     viridis
ylgn        ylgnbu      ylorbr      ylorrd      algae       amp         deep        dense       gray        haline      ice         matter      solar       speed       tempo       thermal     turbid      armyrose    brbg        earth       fall        geyser      prgn        piyg
picnic      portland    puor        rdgy        rdylbu      rdylgn      spectral    tealrose    temps       tropic      balance     curl        delta       edge        hsv         icefire     phase       twilight    mrybm       mygbm

动画 choropleth 地图。作者图片

动画 choropleth 世界地图

让我们创建一个动画的 choropleth 世界地图。Plotly 有样本数据集,我们将使用 Gapminder

import plotly.express as px gapminder = px.data.gapminder()
display(gapminder)

输出:

gapminder 数据集。作者图片

import plotly.express as px
gapminder = px.data.gapminder()
px.choropleth(gapminder,               
              locations="iso_alpha",               
              color="lifeExp",
              hover_name="country",  
              animation_frame="year",    
              color_continuous_scale='Plasma',  
              height=600             
)

动画 choropleth 世界地图。作者图片

结论

官方网站没有动画 choropleth 地图的例子,但使用animation_frame和设置适当的参数很容易创建。

你有没有受到启发,在你的下一个项目中尝试一下?

通过 成为会员 获得媒体上所有故事的权限。

https://blog.codewithshin.com/subscribe

[## 如何用 Python 中的 Plotly Express 创建分组条形图

Python melt 函数将数据帧从宽到长格式化

towardsdatascience.com](/how-to-create-a-grouped-bar-chart-with-plotly-express-in-python-e2b64ed4abd7) [## 如何在 Jupyter 中创建交互式下拉列表

用下拉菜单更新图表

towardsdatascience.com](/how-to-create-an-interactive-dropdown-in-jupyter-322277f58a68) [## 如何在 Jupyter 中创建一个有吸引力的气泡图

从 Github repo 抓取数据的分步指南

towardsdatascience.com](/how-to-create-an-attractive-bubble-map-5cf452c244e9)**

如何使用 Python 创建动画图形?

原文:https://towardsdatascience.com/how-to-create-an-animated-graph-using-python-446f61bb88d3?source=collection_archive---------38-----------------------

呈现模拟/预测/预测模型的一种方式

史蒂文·洛艾扎的照片

用于预测的 Python 模拟图

你有没有想过展示模特表演的最佳方式是什么?我应该谈论 R-Square、RMSE、准确性,还是直接告诉我的经理,我把它放进了一个黑盒子,它工作得很好。

照片由丹尼尔·明戈金Unsplash 上拍摄

下面我将向你展示如何创建动画图形,以帮助呈现结果。不要被所有的代码弄得不知所措,大部分是轴、标签和字体大小的选项。

我的经历

我有一个项目,预测我们的一个顶级指标的频率。该程序每个月运行一次,预测下一年的指标。(我不会用模型来烦你,但我会向你展示我是如何展示它的)

我模拟了模型的使用。为了向我的管理团队展示这一点,我想用动画图来展示它。

最酷的是,我还可以显示程序运行的日期。

好的,让我们从导入一些我们将要使用的库开始。

数据

下面我们将创建一个数据框用于我们的图表。有四列:运行预测的日期、预测的日期、实际值和预测值

动画图表

接下来,我们将创建动画图形。

它从一些基础开始。它创建一个空图形,然后添加 x 轴和 y 轴的边界。

接下来,它为实际值创建一行。这条线会一直出现在图上。以及动画将迭代预测值的空行。

最后,我们创建两个函数 init()和 animate(),这是 matplotlib 中 FuncAnimation 所必需的。

请务必更改路径,这是保存 GIF 的位置。

结论

请随意使用上面的代码,并用您自己的数据替换它。请注意,您可以在图表中添加更多的线条。

附加参考:

[## Matplotlib . animation . func animation-Matplotlib 3 . 2 . 1 文档

通过反复调用函数 func 制作动画。参数:用于获取绘图的图形对象…

matplotlib.org](https://matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html)

感谢您的阅读!

如何创建芝加哥自行车租赁的动画地图

原文:https://towardsdatascience.com/how-to-create-an-animated-map-of-bike-rentals-in-chicago-fa2f8e7ce710?source=collection_archive---------45-----------------------

向使用 Python 包 Bokeh 创建的可视化添加动画

图片由作者上传至 gfycat

本文假设读者已经知道如何使用 Python 中的散景库绘制地理数据。关于精彩透彻的解释,请看这篇 文章 作者 科林·帕特里克·里德

您的数据已经过处理,并且您已经成功地改编了 Colin 的代码,在散景中创建了您自己的漂亮可视化效果,但是您希望传达比静态图像更多的信息。你来对地方了!

初始设置
我们将从这个已经处理过的数据开始,该数据结合了自行车租赁数据和芝加哥历史日平均气温以及以下代码:

这将生成以下静态图像:

作者图片

添加动画 要创建一个动画图形,我们需要添加一个周期性回调函数,在指定的时间过后更新数据。为此,代码需要引用从 Python 脚本自动创建的 JavaScript 文档。因此,我们需要更新到 curdoc(),而不是使用 show(p) 来显示我们的代码。add_root(列(p)) 。注意我们需要确保从 bokeh.plotting 导入 curdoc 并从 bokeh.layouts 导入。这一改变要求脚本从命令行运行,这将在下面进一步解释。

该数据集中的每一行代表从给定自行车站租赁的自行车数量,根据平均温度(四舍五入到最接近的 5°F)计算这些天的平均值。每次更新都将数据刷新到下一个 5 F 时段,从 30 F 到 80 F。图表数据存储在字典中,包含 x 和 y 坐标以及圆的大小。每次回调都会更新字典,以获得代表下一个温度桶的新圆圈尺寸。为了进行更新,将散景圆对象存储在一个变量中,然后用更新的数据字典更新variable _ name . data _ source . data

平滑和调步 数据被分组到 5°F 的桶中,以确保每个温度都有足够数量的数据点,并使总体趋势更容易解释。如果我们直接从一个温度区间过渡到下一个温度区间,动画会非常不连贯,很难从图表中获得洞察力。为了平滑动画,每一帧都会插入自行车租赁的数量以及上一桶和下一桶之间的温度(四舍五入到最接近的度数)。

我发现每桶 20 帧会产生平滑的动画。这相当于每度 4 帧(每 5f 20 帧=每 1f 4 帧)。每 80 毫秒刷新一次数据会导致每个温度显示 0.32 秒(0.08 秒* 4 帧),总运行时间为 16 秒(0.32 * 50 个温度)。

附加代码:

完整的代码可以在这里找到

创建 GIF 添加回调函数并通过 curdoc 方法调用图形足以创建一个将在您的浏览器中的 localhost 上运行的动画图形,但是如果您想要创建一个动画文件(可能包括在 PowerPoint 演示文稿中),那么您将需要创建一个. GIF 文件。

要创建 gif,通过 bokeh.io 中的 export_png 方法将动画的每一帧保存到一个. png 文件中(参见上面的代码)。然后使用 imageio 库中的 imread 函数从 png 文件创建 gif:

注意:我建议在保存任何 png 文件之前,完成你的散景服务器代码(包括平滑和调步)。保存所有的 png 文件比生成服务器要花更多的时间,所以对服务器进行错误检查比对生成的 gif 进行错误检查要快得多。

Bokeh 服务器 vs GIF 运行时
观察力敏锐的读者可能注意到了,我计算出 GIF 有 16 秒长,但本文开头的动画实际上运行了 20 秒。为什么会有差异?从这段代码创建的散景服务器确实运行了 16 秒,但是我没有在从 png 文件创建 gif 的代码中指定帧率。默认值为每秒 10 帧(fps),而在 Bokeh 服务器代码中使用的是每秒 12.5 帧(1 帧/80 毫秒回调周期),这解释了 gif 的 20 秒运行时间(gif 中的 12.5 fps/Bokeh 服务器中的 10 fps * 16 秒)。

如果散景服务器的速度与生成的 gif 不同,请记住这一点。您可以通过 fps 参数在 mimsave 函数中指定所需的帧速率,或者将周期性回调刷新率设置为 100 毫秒(相当于 mimsave 的默认值 10 fps)。

运行您的代码 静态图像可以直接从您的 IDE 中运行,但是如前所述, curdoc 方法需要从命令行中运行,这使散景能够在每次浏览器连接到服务器时创建一个新的绘图。若要运行代码,请从命令提示符运行以下代码:

散景服务-显示 AnimatedGraph.py

注意,我使用 Python 的 Anaconda 发行版,所以我实际上使用 Anaconda 提示符来运行这个命令。从您的计算机执行该命令可能需要一些额外的配置。

结果 制作图形动画的额外努力值得吗?我认为是的,因为它让我从数据中发现了我可能没有的洞察力,并以一种非常容易理解的方式来说明它。

您可能注意到,一旦温度达到大约 55°f,标记的湖岸位置的需求就会激增。这非常有意义,因为天气温暖时人们更有可能去海滩,但我不确定如果没有动画可视化,我是否会意识到这一点。我可能认为这些目的地总体上更受欢迎,就像河流南支以西的地方(芝加哥读者会认为这是来自郊区的通勤列车),与温度有线性关系。

根据这一认识,我能够证明这些湖岸位置的需求随温度呈二次方增长,而其他位置则呈线性增长:

作者图片

这是有用的信息,因为它表明估计海滩位置的需求可能应该使用不同于其他位置的模型,这可以改进补货策略。

如何在 Jupyter 中创建一个有吸引力的气泡图

原文:https://towardsdatascience.com/how-to-create-an-attractive-bubble-map-5cf452c244e9?source=collection_archive---------63-----------------------

将数据抓取到数据可视化的分步指南

图片来自 Pixabaystokpic

**Table of Contents**[**Introduction**](#f1e4)1\. [Libraries](#ca78)
2\. [Data Scraping with BeautifulSoup](#c249)
3\. [The Mapbox Token](#6bfe)
4\. [Plotly.express](#fb63)
5\. [Other Datasets](#1c1d)
6\. [Comparing to Plotly.graph_object](#f972)[**Conclusion**](#e370)

介绍

在本文中,我将向您展示如何从 CSSEGISandData 的新冠肺炎 Github repo 中抓取最新数据,并使用 Plotly 和 Mapbox 创建气泡图。

我们将使用 JupyterLab(或 Jupyter Notebook,如果你喜欢的话),Plotly express,BeautifulSoup 和 Mapbox。

以前在 JupyterLab 上安装 Plotly 很困难,但是现在安装起来很容易。你可以在这里找到

图书馆

import requests
from bs4 import BeautifulSoup
import plotly.express as px
import pandas as pd

我们使用 Python 的 HTTP 库,[requests](https://requests.readthedocs.io/en/master/)向网页发送get请求。 BeautifulSoup 是一个 Python 库,用于从 HTML 和 XML 文件中提取数据。

[plotly.express](https://plotly.com/python/plotly-express/)是 Plotly 的高级包装器。它使用更简单的语法,易于使用。[pandas](https://pandas.pydata.org/)是一个快速、强大、灵活且易于使用的开源数据分析和操作工具。

使用 BeautifulSoup 进行数据抓取

让我们开始写刮擦部分的代码。

我们设置变量githubURL

github = 'https://github.com'
URL = 'https://github.com/CSSEGISandData/COVID-19/tree/master/csse_covid_19_data/csse_covid_19_daily_reports_us'

我们使用request.get()获得一个网页,并通过解析页面内容创建一个Beautifulsoup对象。

page = requests.get(URL)
soup = BeautifulSoup(page.content, 'html.parser')

检查页面 HTML 后,您可以发现最新的报告总是倒数第四个链接。如果你需要确认,你可以打印最新的。

latest = str(soup.table.find_all('a')[-4]['href'])
# print(latest)

输出:

/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_daily_reports_us/06-04-2020.csv

我们创建指向最新数据的链接,并使用requests.get()再次获取网页内容。我们可以通过打印来确认。

latestURL = github + latest
latestPage = requests.get(latestURL, 'html.parser')
print(latestURL)

输出:

[https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_daily_reports_us/06-04-2020.csv](https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_daily_reports_us/06-20-2020.csv)

Github 有一个 id 为raw-url的 raw 页面。我们得到原始页面的 URL。我们可以通过打印rawURL来确认。

soup = BeautifulSoup(latestPage.content, 'html.parser')
raw = str(soup.find(id='raw-url')['href'])
rawURL = github + raw
print(rawURL)

输出:

[https://github.com/CSSEGISandData/COVID-19/raw/master/csse_covid_19_data/csse_covid_19_daily_reports_us/06-04-2020.csv](https://github.com/CSSEGISandData/COVID-19/raw/master/csse_covid_19_data/csse_covid_19_daily_reports_us/06-20-2020.csv)

现在原始页面是一个 CSV 格式,我们可以使用熊猫来阅读它。我们可以通过使用head()打印数据来确认。

df = pd.read_csv(rawURL)
print(df.head())

df.head()的输出。图片由作者提供。

我们删除了缺少Lat值的行(axis=0)。我们还用 0 填充缺少数据的字段。

df = df.dropna(axis=0, subset=['Lat'])
df = df.fillna(0)
print(df.head())

df.fillna(0)之后的 df.head()的 Out put。图片由作者提供。

我们从第三列的第一行获取日期和时间。(第一个索引为 0)

date, time = df.iloc[0, 2].split()
print(date)
print(time)

输出:

2020-06-04
04:33:37

[## 如何在 Docker 上运行 Jupyter 笔记本

不再有 Python 环境和包更新

towardsdatascience.com](/how-to-run-jupyter-notebook-on-docker-7c9748ed209f)

地图框标记

地图框创建一个账户。并创建一个令牌。

地图框标记。作者图片

在您的 JupyterLab/Jupyter 笔记本中,创建一个文件.mapbox_token,并将创建的令牌从 Mapbox 复制并粘贴到该文件中。

px.set_mapbox_access_token(open(".mapbox_token").read())

我们使用 Plotly express set_mapbox_access_token设置 Mapbox 令牌。如果您使用 Git,那么将.mapbox_token添加到您的[.gitignore](https://github.com/shinokada/covid-19-stats/blob/master/.gitignore)文件中。

Plotly.express

代码的最后部分是设置[plotly.express](https://plotly.com/python/plotly-express/)参数和布局。

以下列表包含plotly.express.scatter_mapbox的一些关键参数。

作者快速参考。更多详情,请参见本

我们用colorsize[color_continuous_scale](https://plotly.com/python/builtin-colorscales/)size_maxzoomcenterhover_datahover_name。如果您愿意,可以设置更多参数。

fig = px.scatter_mapbox(
    df, lat="Lat", lon="Long_",
    color="Deaths",
    size="Deaths",
    color_continuous_scale=px.colors.sequential.Jet,
    size_max=40,
    zoom=3, 
    center={"lat": 37.0902, "lon": -95.7129},              
    hover_data=["Confirmed"],
    hover_name='Province_State'
)

我们可以在fig.update_layout设置标题。和fig.show()显示图像。

fig.update_layout(
    title=f'COVID-19 Deaths in USA by states.  Date: {date}',
)
fig.show()

作者图片

所有代码:

其他数据集

我们可以将此用于其他 CSSEGISandData 的新冠肺炎页面。例如,使用全球每日报告链接:

URL = 'https://github.com/CSSEGISandData/COVID-19/tree/master/csse_covid_19_data/csse_covid_19_daily_reports'

要诀中的代码。作者图片

与 Plotly.graph_object 比较

以下 gif 图像是使用 Plotly.graph_object 创建的。你能看出区别吗?它不像地图框那样有州名、地形、河流和详细信息。你可以在这里找到代码

结论

你现在知道如何使用 Plotly.express 制作气泡图。使用 Mapbox 库是因为它给你一个更好的展示,你可以用各种参数控制地图。在你的数据科学项目中使用气泡图怎么样?

通过 成为 会员,获得媒体上所有故事的访问权限。

https://blog.codewithshin.com/subscribe

资源

相关故事

[## 如何在 Jupyter 中创建交互式下拉列表

用下拉菜单更新图表

towardsdatascience.com](/how-to-create-an-interactive-dropdown-in-jupyter-322277f58a68) [## 如何用 Python 中的 Plotly Express 创建分组条形图

Python melt 函数将数据帧从宽到长格式化

towardsdatascience.com](/how-to-create-a-grouped-bar-chart-with-plotly-express-in-python-e2b64ed4abd7) [## 如何用不到 15 行代码创建一个动画的 Choropleth 地图

在 Jupyter 上使用 Python 中的 Plotly Express

towardsdatascience.com](/how-to-create-an-animated-choropleth-map-with-less-than-15-lines-of-code-2ff04921c60b) [## Jupyter 上 Plotly 的折线图动画

Plotly 统一悬停模式,按钮和更多

towardsdatascience.com](/line-chart-animation-with-plotly-on-jupyter-e19c738dc882) [## 如何在 Jupyter 中创建动画条形图

使用 Plotly Python 显示最新美国失业率的数据可视化

towardsdatascience.com](/how-to-create-an-animated-bar-chart-in-jupyter-9ee1de8d0e80) [## 如何用 Python 中的 Plotly Express 创建分组条形图

Python melt 函数将数据帧从宽到长格式化

towardsdatascience.com](/how-to-create-a-grouped-bar-chart-with-plotly-express-in-python-e2b64ed4abd7) [## Jupyter 用户的生产力提示

使用 Jupyter 笔记本和 JupyterLab 让您的工作流程更加高效

towardsdatascience.com](/stepping-into-intermediate-with-jupyter-f6647aeb1184)

如何在 10 分钟内为您的数据科学产品组合创建一个优雅的网站

原文:https://towardsdatascience.com/how-to-create-an-elegant-website-for-your-data-science-portfolio-in-10-minutes-577f77d1f693?source=collection_archive---------15-----------------------

你需要做的就是编辑

动机

如果简历是展示你的经验和项目的唯一来源,那么你在求职中已经落后于许多其他候选人了。为什么?因为你需要把你所有的宝贵经验、课程、技能、社团活动、证书和奖励都限制在一张纸上!当你取得更多成就时,你会犹豫是否要修改你的简历,因为修改格式、字数等需要很多工作。因此,有一个网站来展示你的背景和技能是很重要的。

“是的,我知道网站很重要,但当我使用 Wordpress 或其他网站构建工具时,我发现有许多步骤需要设置,所以我决定甚至不尝试,而是坚持使用我的简历”

如果这是你的想法,如果你知道你可以在 10 分钟内创建一个像这样的投资组合会怎么样?

只需几个步骤,你就能拥有一个展示你潜在雇主的专业网站。

从 Glitch 访问模板

首先从 Glitch 这里进入模板。创建一个免费帐户,然后单击查看源代码。

点按页面最右边的“重新混合”进行编辑

将左上角的名称更改为您希望网站使用的名称。给你的网站命名最好的方法就是你的名字。

现在您可以通过 somename.glitch.me 访问您的网站!您现在需要做的就是更改_config.yaml部分的信息。重新运行网站以查看更改。

编辑信息

有八个部分可用

  1. 简介:
  • 你的名字,联系方式和你是谁的简短描述,你对什么有热情,你目前的任务。换句话说,简短的自我介绍。
  • 您可以通过将自己的照片拖到网站上或点击assets部分中的上传资产来插入您的图像

2.社交

  • 你的社交媒体和网站的链接。最棒的是它们用可点击的图标显示出来!

3.体验

您对职位、公司、时间段、描述和链接等相关信息的体验。

4.社区

你对你的学校、工作或周围的社区有什么贡献?这里是你可以展示你的领导技能的部分

5.工具

这部分展示你的技能。更好的是,用图标显示它们。如果有一些你正在寻找的其他技能不在图标列表中,在 Font Awesome 上找到更多图标。你需要做的就是找到你想要的图标,并在tools部分插入名字。

如果你找不到你想要的图标,你可以在 extra_skills 部分添加。

6.车间:

在这里,您可以展示您参加过或发表过的与数据科学相关的研讨会和活动。记下你参加过的研讨会能给你的简历带来巨大的变化。

7.项目

一份数据科学简历不能缺少项目。对于招聘人员来说,看到你做了什么以及你是如何做到的是很重要的。如果您的链接太长,您可以使用稍微缩短 URL。您还可以附加标签和图像,为您的项目添加可视化效果

附加图像的快速修复,以便显示您在资源中插入的图像。转到templates/index.html,这里是构建网站的 html 代码。放心吧!你不需要熟悉 html。你需要做的就是从<img src="static/img/{{ item.img }}"换到<img src="{{ item.img }}"

现在在这里!

8.奖项

您获得的奖项的占位符。即使是小奖项也值得一提。

但是我不需要所有的部分

你不希望你的网站有一个特定的部分,因为缺乏信息,但想增加信息,因为你实现更多的部分?你可以很容易地做到这一点,使部分不可见。假设你不希望工作坊出现在你的网站上。去templates/index.html.使用 Ctrl/Command + F 快速找到关键词。在搜索栏中,插入“车间”。你应该看看车间所在的区域。

您要注释掉的第一部分是菜单上的项目。在要隐藏的部分之前用<!--注释掉,在之后用— — ->注释掉。对 html 中出现工作室的另一部分做同样的事情。

现在你再也看不到车间部分了。整洁!

结论

我希望你能看到为你的作品集创建一个专业网站是多么容易。现在,当向潜在雇主或招聘人员介绍自己时,你可以自信地与他们分享你的网站。如果你的投资组合里还没有很多东西,不要着急!当你在网站上看到你的成就时,你会有动力去取得更多。注意微小的成就。随着时间的推移,即使是一件小事也很重要。

我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedInTwitter 上和我联系。

如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:

[## 当生活不给你喘息的机会,如何学习数据科学

我努力为数据科学贡献时间。但是发现新的策略使我能够提高我的学习速度和…

towardsdatascience.com](/how-to-learn-data-science-when-life-does-not-give-you-a-break-a26a6ea328fd) [## 高效 Python 代码的计时

如何比较列表、集合和其他方法的性能

towardsdatascience.com](/timing-the-performance-to-choose-the-right-python-object-for-your-data-science-project-670db6f11b8e) [## 字典作为 If-Else 的替代

使用字典创建一个更清晰的 If-Else 函数代码

towardsdatascience.com](/dictionary-as-an-alternative-to-if-else-76fe57a1e4af) [## 如何找到和 Python 很好的搭配

给定个人偏好,如何匹配使得总偏好最大化?

towardsdatascience.com](/how-to-match-two-people-with-python-7583b51ff3f9) [## 用这 6 个小窍门提高你的效率

并控制您的阵列

towardsdatascience.com](/boost-your-efficiency-with-these-6-numpy-tricks-29ca2fe81ecd)

如何使用 Yolov5 创建一个端到端的对象检测器?

原文:https://towardsdatascience.com/how-to-create-an-end-to-end-object-detector-using-yolov5-35fbb1a02810?source=collection_archive---------10-----------------------

是的,Yolov5 在这里

Ultralytics 最近在围绕其名称的争议中推出了 YOLOv5。作为背景,YOLO 的前三个版本(你只看一次)是由约瑟夫·雷德蒙创作的。在此之后,Alexey Bochkovskiy 在 darknet 上创建了 YOLOv4,它比以前的迭代拥有更高的平均精度(AP)和更快的结果。

现在,Ultralytics 发布了 YOLOv5,AP 相当,推理时间比 YOLOv4 更快。这让许多人不禁要问:一个新版本是否有理由获得与 YOLOv4 相似的精确度?无论答案是什么,这都是检测社区发展速度的一个明显标志。

来源 : Ultralytics Yolov5

自从他们首次移植 YOLOv3 以来,Ultralytics 已经使使用 Pytorch 创建和部署模型变得非常简单,所以我渴望尝试 YOLOv5。事实证明,Ultralytics 进一步简化了这个过程,结果不言自明。

在本文中,我们将使用 YOLOv5 创建一个检测模型,从创建我们的数据集并对其进行注释,到使用他们卓越的库进行训练和推理。 本帖重点介绍 YOLOv5 的实现,包括:

  • 创建玩具数据集
  • 注释图像数据
  • 创建项目结构
  • 培训 YOLOv5

创建自定义数据集

如果您有图像数据集,可以放弃第一步。由于我没有图像,我正在从开放图像数据集(OID)下载数据,这是获取可用于分类和检测的带注释图像数据的绝佳资源。请注意,为了便于学习,我们不会使用 OID 提供的注释,而是创建自己的注释。

1.OIDv4 下载图像:

为了从开放的图像数据集中下载图像,我们首先克隆 OIDv4_ToolKit 并安装所有需求。

git clone [https://github.com/EscVM/OIDv4_ToolKit](https://github.com/EscVM/OIDv4_ToolKit)
cd [OIDv4_ToolKit](https://github.com/EscVM/OIDv4_ToolKit)
pip install -r requirements.txt

我们现在可以使用这个文件夹中的main.py脚本来下载图像以及多个类的标签。

下面我正在下载板球和足球的数据来创建我们的自定义数据集。也就是说,我们将创建一个足球和板球数据集,学习任务是检测这些球。

python3 main.py downloader --classes Cricket_ball  Football --type_csv all -y --limit 500

以下命令创建一个名为“OID”的目录,其结构如下:

OID 目录结构。我们将只取图像文件(。jpg ),而不是标签,因为我们将手动注释以创建我们的自定义数据集,尽管如果不同的项目需要,我们可以使用它们。

在我们继续之前,我们需要将所有图像复制到同一个文件夹中,以便从头开始我们的标记练习。您可以选择手动完成,但也可以使用递归 glob 函数以编程方式快速完成:

import os
from glob import globos.system("mkdir Images")
images = glob(r'OID/**/*.jpg', recursive=True)
for img in images:
    os.system(f"cp {img} Images/")

2.用超级标签标记图像

我们将使用名为 Hyperlabel 的工具来标记我们的图像。过去,我使用过很多工具来创建注释,比如 labelimg、labelbox 等等。但从未遇到过如此简单且过于开源的工具。唯一的缺点是你不能在 Linux 上使用这个工具,只能在 Mac 和 Windows 上使用,但是我想这对我们大多数人来说都没问题。

1.创建项目,2,设置标签,3。添加本地图像数据源,4。给…作注解

这个工具最好的部分是它提供的各种输出格式。因为我们想获得 Yolo 的数据,所以我们将关闭 Yolo 格式,并在注释完成后导出它。但是如果您想获得 JSON 格式(COCO)或 XML 格式(Pascal VOC)的注释,您也可以选择使用这个工具。

5.出口

以 Yolo 格式导出实际上是为我们的每个图像创建一个. txt 文件,其中包含图像的 class_id、x_center、y_center、宽度和高度。它还创建了一个名为obj.names的文件,这有助于将 class_id 映射到类名。例如:

图像、其注释和 obj.names 文件

请注意,在注释文件中,坐标从 0 缩放到 1。另外,请注意,根据从 0 开始的obj.names 文件,板球的 class_id 为 0,足球的 class _ id 为 1。我们用它创建了一些其他的文件,但是我们不会在这个例子中使用它们。

一旦我们完成了这些,我们就基本上设置好了我们的自定义数据集,我们只需要重新排列其中的一些文件,以便在以后训练模型时进行后续的训练和验证分割。数据集目前是一个文件夹,如下所示,包含图像和注释:

dataset
    - 0027773a6d54b960.jpg  
    - 0027773a6d54b960.txt
    - 2bded1f9cb587843.jpg
    - 2bded1f9cb587843.txt
    --
    --

设置项目

为了训练我们的自定义对象检测器,我们将使用 Ultralytics 的 Yolov5。我们从克隆存储库和安装依赖项开始:

git clone [https://github.com/ultralytics/yolov5](https://github.com/ultralytics/yolov5) # clone repo
cd yolov5
pip install -U -r requirements.txt

然后,我们开始创建自己的名为 training 的文件夹,在其中保存我们的自定义数据集。

!mkdir training

我们首先将自定义数据集文件夹复制到这个文件夹中,并使用简单的train_val_folder_split.ipynb笔记本创建训练验证文件夹。下面的代码只是创建一些训练和验证文件夹,并用图像填充它们。

import glob, os
import random# put your own path here
dataset_path = 'dataset'# Percentage of images to be used for the validation set
percentage_test = 20!mkdir data
!mkdir data/images
!mkdir data/labels
!mkdir data/images/train
!mkdir data/images/valid
!mkdir data/labels/train
!mkdir data/labels/valid# Populate the folders
p = percentage_test/100
for pathAndFilename in glob.iglob(os.path.join(dataset_path, "*.jpg")):  
    title, ext = os.path.splitext(os.path.basename(pathAndFilename))
    if random.random() <=p :
        os.system(f"cp {dataset_path}/{title}.jpg data/images/valid")
        os.system(f"cp {dataset_path}/{title}.txt data/labels/valid")
    else:
        os.system(f"cp {dataset_path}/{title}.jpg data/images/train")
        os.system(f"cp {dataset_path}/{title}.txt data/labels/train")

运行之后,您的data文件夹结构应该如下所示。它应该有两个目录imageslabels

我们现在必须向training文件夹添加两个配置文件:

1。Dataset.yaml: 我们创建一个文件“dataset.yaml”,它包含训练和验证图像的路径以及类。

# train and val datasets (image directory or *.txt file with image paths)
train: training/data/images/train/
val: training/data/images/valid/# number of classes
nc: 2# class names
names: ['Cricketball', 'Football']

2。在创建我们的网络时,我们可以使用从小到大的多个模型。例如,yolov5/models 目录下的yolov5s.yaml文件是 7M 参数的小型 Yolo 模型,yolov5x.yaml是 96M 参数的最大 Yolo 模型。对于这个项目,我将使用有 50M 参数的yolov5l.yaml。我们首先将文件从yolov5/models/yolov5l.yaml复制到 training 文件夹,并根据我们的项目需求将nc的类数改为 2。

# parameters
nc: 2  # change number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple

火车

此时,我们的培训文件夹如下所示:

一旦我们完成了上述步骤,我们就可以开始训练我们的模型了。这就像运行下面的命令一样简单,在这里我们提供配置文件和各种其他参数的位置。您可以在train.py文件中查看不同的其他选项,但这些选项是我发现值得注意的。

# Train yolov5l on custom dataset for 300 epochs
$ python train.py --img 640 --batch 16 --epochs 300--data training/dataset.yaml --cfg training/yolov5l.yaml --weights ''

在这种情况下,在单个 GPU 上运行 PyTorch 版时,有时可能会出现错误:

# Train yolov5l on custom dataset for 300 epochs
$ python train.py --img 640 --batch 16 --epochs 300--data training/dataset.yaml --cfg training/yolov5l.yaml --weights '' --device 0

一旦开始训练,您可以通过检查自动创建的文件train_batch0.jpg来检查训练是否已经设置,该文件包含第一批的训练标签和test_batch0_gt.jpg,该文件包含测试图像的基本事实。他们就是这样找我的。

左:train_batch0.jpg,右:test_batch0_gt.jpg

结果

要使用 tensorboard 在浏览器中查看localhost:6006的训练结果,请在另一个终端选项卡中运行此命令

tensorboard --logdir=runs

以下是各种验证指标。在训练结束时,这些指标也会保存在文件results.png中。

预测

Ultralytics Yolov5 提供了许多不同的方法来检查新数据的结果。

要检测一些图像,您只需将它们放入名为inference/images的文件夹中,并根据验证 AP 使用最佳权重运行推理:

python detect.py --weights weights/best.pt

结果

您还可以使用 detect.py 文件在视频中进行检测:

python detect.py --weights weights/best.pt --source inference/videos/messi.mp4 --view-img --output inference/output

在这里,我指定我想使用— view-img标志来查看输出,我们将输出存储在位置 inference/output。这将在这个位置创建一个.mp4文件。令人印象深刻的是,网络可以看到球,在这里做出推断的速度,以及从未观察到的数据的惊人准确性。

还有,这是梅西…..

您也可以通过将--source指定为 0 来将网络摄像头用作信号源。您可以查看detect.py文件中的各种其他选项。

结论

在这篇文章中,我谈到了如何使用自定义数据集创建一个 Yolov5 对象检测模型。我喜欢 Ultralytics 让创建对象检测模型变得如此简单的方式。

此外,他们提供的查看模型结果的各种方式使它成为我很长时间以来看到的一个完整的包。

如果你想自己尝试定制数据集,你可以在 Kaggle 下载带注释的数据,在 Github 下载代码。

如果想详细了解各种 物体检测技术,运动估计,视频中的物体跟踪等 。,在此推荐这门关于计算机视觉深度学习的优秀课程。如果你想知道更多关于物体检测领域这些年是如何发展的,你也可以看看我上一篇关于物体检测的文章。

谢谢你的阅读。将来我也会写更多初学者友好的帖子。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系到我

这个故事在这里首次发表

posted @ 2024-10-15 13:41  绝不原创的飞龙  阅读(217)  评论(0)    收藏  举报