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

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何使用 Keras 扩充数据

原文:https://towardsdatascience.com/how-to-augmentate-data-using-keras-38d84bd1c80c?source=collection_archive---------18-----------------------

使用 Python 和 Keras 进行数据扩充

本·斯特恩在 Unsplash 上的照片

如果您想要扩充数据或增加训练或验证数据的数量,数据扩充非常有用。例如,如果你有 2000 张图片,你想得到其中的 5000 或 10000 张,那么这将非常有用。

但如果你有 5 或 10 张图像,不要指望从数据增强中获得 2000 或 10000 张图像,仍然能够从深度学习模型中获得不错的结果。因为深度学习模型会高度偏向这 5 张或者 10 张图片。

如果你的图片少于 100 张,我建议你使用传统的机器学习

使用单幅图像演示数据扩充过程。

test.jpg——图片来自 Pixabay维基图片

from keras.preprocessing.image import ImageDataGenerator
from skimage import iodatagen = ImageDataGenerator(        
            rotation_range=45,
            width_shift_range=0.2,  
            height_shift_range=0.2,    
            shear_range=0.2,        
            zoom_range=0.2,        
            horizontal_flip=True,         
            fill_mode='constant', cval=125)x = io.imread('test_image/test.jpg')x = x.reshape((1, ) + x.shape)
i = 0
for batch in datagen.flow(x, batch_size=16,
                          save_to_dir='augmented',
                          save_prefix='aug',
                          save_format='png'):    
  i += 1    
  if i > 20:        
     break

我们数据扩充需要的库是 Keras 的ImageDataGenerator。为了读取单个图像,我还从skimage导入了io。首先,我们需要为数据生成器创建一个实例。方法是创建一个名为datagen的变量(你可以给它取任何你喜欢的名字),并用内部参数使它等于ImageDataGenerator

rotation_range=45表示我想在 0 到 45 度之间随机旋转我的图像。width_shift_range=0.2height_shift_range=0.2表示将图像沿 X 轴移动 20%,沿 Y 轴移动 20%。shear_range=0.2表示将图像剪切 20%。zoom_range表示放大缩小 20%。对于镜面反射,我已经给出了horizontal_flip=TrueImageDataGenerator最重要的论点是fill_mode。当你的图像移动 20%时,会有一些剩余空间。您可以选择几种方法来填充该区域,

  • 常量——用黑色填充该区域。您可以通过给cval一个值来改变颜色
  • 最近的——用最近的像素填充该区域并拉伸它。
  • 反射——用图像的反射填充该区域。
  • 环绕 —通过环绕图像来填充该区域。

使用后,io.read我们可以读取图像。在读取图像后,您可以看到图像是(256, 256, 3),在对其进行整形后,您可以看到图像是(1, 256, 256, 3),因为当我们进入卷积层时,输入大小通常首先是图像的数量。其次是尺寸,最后是配色方案。

我们应用实例datagen的方式是使用datagen.flow。这里我们使用.flow ,因为只有一个图像。batch_size=16表示正在生成或放大 16 幅图像,并将图像保存在augmented文件夹中。由于datagen是在一个有限循环中,我们需要使用一个for-loop并在它到达 20 张图像时中断它。(类似于epochs)

现在我们知道了它是如何工作的,让我们看看不同fill_mode的例子,

cval=125 的常数

最近的

显示

使用多幅图像演示数据扩充过程。

test1.jpg——图片由提供。欢迎并感谢您的访问!来自 Pixabay 的ツ

test2.jpg——图片来自 Pixabay维基图片

from keras.preprocessing.image import ImageDataGenerator
from skimage import iodatagen = ImageDataGenerator(        
            rotation_range=45,
            width_shift_range=0.2,  
            height_shift_range=0.2,    
            shear_range=0.2,        
            zoom_range=0.2,        
            horizontal_flip=True,         
            fill_mode='reflect')import numpy as np
import os
from PIL import Imageimage_directory = 'test_folder/'
SIZE = 128
dataset = []my_images = os.listdir(image_directory)
for i, image_name in enumerate(my_images):    
   if (image_name.split('.')[1] == 'jpg'):        
       image = io.imread(image_directory + image_name)        
       image = Image.fromarray(image, 'RGB')        
       image = image.resize((SIZE,SIZE)) 
       dataset.append(np.array(image))x = np.array(dataset)i = 0
for batch in datagen.flow(x, batch_size=16,
                          save_to_dir='augmented',
                          save_prefix='aug',
                          save_format='png'):    
  i += 1    
  if i > 20:        
     break

我必须定义SIZE = 128,因为不管你的图像大小是多少,我们都可以把它调整到一个普通的大小。为了读取所有的图像,我将使用for-loop来读取图像。对于每幅图像,我们必须在.jpg时将其分割。最后,调整大小的图像将被添加到数组中。我们可以像上面所做的那样做其余的事情。现在我们有了test1.jpgtest2.jpg

输出

使用多类来演示数据扩充过程。

多类是你在大多数课程中所期望的。现在,我已经将每张图片按照它们的类别进行了分类,因为这就是数据在数据集中的表现方式。使用datagen.flow_from_directory将分别读取子文件夹中的图像。举个例子,如果你有猫,狗,车等类。然后将所有这些图像放入相应的文件夹中。

i = 0
for batch in datagen.flow_from_directory(directory='test_folder/',
                                          batch_size=16,
                                          target_size=(256, 256),   
                                          color_mode="rgb",     
                                          save_to_dir='augmented',   
                                          save_prefix='aug',    
                                          save_format='png'):    
   i += 1    
   if i > 31:        
     break

结论

文章到此为止。我希望你能学到新的东西。谢谢,注意安全!

资源

[## Sreeni 为显微镜专家开发的 Python

本频道将带您了解学习 Python 编码的整个过程;从基础到高级…

www.youtube.com](https://www.youtube.com/channel/UC34rW-HtPJulxr5wp2Xa04w)

如何自动检测数据集中的错误

原文:https://towardsdatascience.com/how-to-auto-detect-format-errors-in-a-dataset-6609a9e9aacc?source=collection_archive---------19-----------------------

引入泛化树和泛化语言来自动检测结构化数据集中的损坏值。

乔治·贝克在的照片

给定一个大型的结构化数据集,比如 excel 电子表格或 CSV 文件,有没有办法避免检测不可避免的错误这种令人疲惫不堪、影响工作效率的琐事

在这个故事中,我们应用黄志鹏和叶烨他在 “自动检测:表中数据驱动的错误检测” 中提出的思想,自动检测表格数据中的格式错误。

学习率是为那些对 AI 和 MLOps 的世界感到好奇的人准备的时事通讯。你会在每周五收到我关于最新人工智能新闻和文章的更新和想法。在这里订阅!

问题陈述

损坏的数据或丢失的值会对分析管道产生严重的负面影响。垃圾输入垃圾输出这个短语简洁地表达了这个问题。然而,由于这些错误的异质性,检测这些错误可能是一个非常具有挑战性的问题;简单的打字错误、格式错误、与陈旧数据的集成、拒绝约束等。

为了解决这个问题,数据科学家设计了许多技术,大致分为两类:单列方法,用于检测单个列中发生的错误;以及多列方法,用于识别诸如拒绝约束之类的违规。

错误检测技术大致分为两类:单列和多列方法。

在这个故事中,我们关注一个单列方法,并讨论如何自动检测格式错误。事实证明,格式错误不仅会影响下游分析结果的质量,还会彻底破坏自动化管道。假设有一个数据列,其格式为03/11/2020,并且有一个使用格式02.11.2020的值。最好的情况是提取日期的自动化作业会抛出异常。最坏的结果将会产生难以调试的逻辑错误。

让我们来讨论这个问题的定义。给定一个结构化数据集,我们构造一个包含其列的集合。我们想要的是检测单个列中存在低概率的值。在上述示例中,如果大部分日期符合第一种格式,我们希望为遵循不同日期模式的值分配低概率。

天真的解决方案

我们生活在大数据时代,因此,一个解决方案是收集大量的表格数据(如维基百科表格、公开可用的 excel 表格等)。)并提取一个集合C,它包含这个集合中存在的所有列。

我们希望这些列在很大程度上是干净的,因此,它们可以为两个值v, u的列内共现提供良好的统计测量。直觉上,如果两个值 **v,u** 在列中频繁共存,那么它们应该是兼容的。

为此,我们可以使用一种叫做逐点互信息 (PMI) 的统计度量。首先,我们计算在列中遇到值v的概率。

在该公式中,c(v)表示值为v的列数,而|C|是列数。相应地,我们计算两个值v,u同时出现的概率。

现在,c(u,v)表示包含uv的列数。我们现在准备计算值v,u的 PMI。

结果范围从负无穷大到正无穷大。因此,我们通过除以-log p(v,u)得到标准化的 PMI (NPMI)来标准化它。注意,如果 **v** **u** 是偶然同现 **p(u,v)** 等于 **p(v)p(u)** ,则比值为 **1** 和 PMI **0** 为无相关性。另一方面,如果这些值频繁地同时出现并且正相关,则 PMI 大于**0**;否则,PMI 取值小于 **0**

让我们看一个具体的例子。让v = 1u = 2。假设我们的集合C中有100M列,我们有c(v) = 1Mc(u) = 2Mc(u,v) = 500K。我们可以计算出p(v) = 0.01p(u) = 0.02p(u,v) = 0.005。有了这些值,我们可以计算出 NPMI 等于0.6,它大于0我们可以直观地说,价值观 **u** **v** 高度契合。如果这两个值中的一个是很少发生的错误,你可以试试会发生什么。

泛化树和泛化语言

我们有一个有希望的解决方案,但这是一个幼稚的方案。例如,假设我们有两个日期:03.17.201903.18.2019。这些看起来非常适合出现在同一列中,因为它们符合相同的日期模式。尽管如此,没有什么能保证我们会在同一列中看到这些精确的值,不管我们的列集|C|有多大。因此,我们的方法会将它们标记为导致许多假阳性的潜在错误。稀疏是这里的一个问题。

解决方案是将值概括成模式;我们可以将它们归纳为类似于\d{2}.\d{2}.\d{4}的模式,而不是让值为03.17.201903.18.2019。现在,只要一个具有这种日期格式的列就可以给出我们想要的信息。我们可以使用泛化树泛化语言来实现这种类型的泛化。下图给出了一个泛化树的示例。

泛化树

从那棵树,我们可以实例化许多泛化语言。我们可以认为泛化语言是一个将任意输入映射到泛化树任意层的函数。为了更好地理解它,让我们构建两个由图中的树派生的一般化语言。

第一种语言会将03.17.2019转化为\A{2}.\A{2}.\A{4}。看来我们已经解决了我们的问题,对吗?嗯,不完全是;让我们看看另一种语言的定义。

使用第二种语言03.17.2019变成了\D{2}\S\D{2}\S\D{4}。但是03-17-2019呢?泛化语言 2 将其转换成完全相同的模式。我们无法发现这里的问题。正如我们所见,选择正确的语言至关重要。

权衡取舍

上一节的例子展示了为每种情况选择正确语言的重要性。请注意,我们可以选择多种语言,然后找到一种巧妙的方法来汇总结果。

无论如何,有两个问题我们需要考虑:

  • 敏感性与鲁棒性:正如我们所看到的,一种语言越一般化,它就越能以牺牲敏感性为代价对抗稀疏性。例如,如果一种语言将所有东西都推广到根级别(All [A]),我们可以缓解稀疏性问题,但这样我们将无法捕捉任何格式差异。在另一个极端,如果我们将所有东西都推广到叶子级别,我们最终会得到一个高度敏感的语言,由于数据稀疏,它会产生许多误报。
  • 内存问题:很明显,不同的泛化语言消耗不同的内存量。一种语言越概括,它需要的内存空间就越少。另一方面,一种将一切都推广到叶子级别的语言需要数百千兆字节的内存。

因此,这个问题实际上是一个约束优化难题:给定一个泛化树,选择特定数量的泛化语言,这些语言可以捕获不同类型的格式错误,服从一个精度度量和内存预算。

结论

在这个故事中,我们提出了一个由和何提出的想法,并把它用于自动检测结构化数据集中的格式错误。我们展示了如何使用逐点互信息解决这个问题,并给出了泛化树和泛化语言的定义。

最后,我们得出结论,我们的问题归结为约束优化的挑战:给定一个泛化树,选择特定数量的泛化语言,这些语言可以捕获不同类型的格式错误,服从精度度量和内存预算。这个问题的建议解决方案可以在下面的故事中找到。

[## 如何使用泛化语言自动检测数据集中的错误

使用远程监督和汇总预测结果生成验证数据,就像大海捞针一样。

towardsdatascience.com](/how-to-auto-detect-errors-in-a-dataset-part-ii-683b114865be)

我叫 Dimitris Poulopoulos,是希腊比雷埃夫斯大学BigDataStack的机器学习研究员和博士(c)。我曾为欧洲委员会、欧盟统计局、国际货币基金组织、欧洲中央银行、经合组织和宜家等主要客户设计和实施人工智能和软件解决方案。如果你有兴趣阅读更多关于机器学习、深度学习和数据科学的帖子,请在 twitter 上关注我的**LinkedIn@ james2pl******

使用 LaTeX 时如何自动更新 PDF

原文:https://towardsdatascience.com/how-to-auto-update-pdf-when-working-on-latex-ad9eeabdb7a1?source=collection_archive---------8-----------------------

使用 latexmk 和 VSCode 自动更新 PDF 的指南

由 www.freepik.com 创作的照片

**Table of Contents**[**Introduction**](#de65)1\. [Installing LaTeX](#0781)
2\. [Creating PDF from a terminal using latexmk](#a506)
3\. [Installing LaTeX Workshop Extension to VS Code](#41d5)
4\. [Create your own snippets](#3a71)
5\. [Testing the snippet](#fe49)
6\. [LaTeX Workshop error](#97e9)
7\. [Automatically update PDF when you save](#0730)[**Conclusion**](#fab4)

介绍

我偶尔会使用 LaTeX。我用 Typora 写文章、报告、笔记等等。但是我不能完全控制 markdown 的布局。所以我重新开始使用乳胶。我想分享一下我学到的东西。本文展示了如何用 VS 代码设置 LaTeX,以便在保存 TeX 文件时自动更新 PDF。

安装 LaTeX

这次我装了mactex-no-gui

Mac:

# macOS MacTex Install
$ brew install --cask mactex-no-gui# Updating the packages
$ sudo tlmgr update --self && sudo tlmgr update --all

安装相当快,但需要很长时间来更新。
您可能需要重启终端并检查是否正常工作:

$ latex --version
$ latexmk --version
$ platex --version

如果它不起作用,那么你需要添加一个路径到你的~/.zshrc或者~/.bash_profile:

export PATH="/Library/TeX/texbin/:$PATH"

再次检查:

$ latex --version
pdfTeX 3.14159265-2.6-1.40.21 (TeX Live 2020)
kpathsea version 6.3.2
...
$ latexmk --version
Latexmk, John Collins, 29 September 2020\. Version 4.70b
...
$ platex --version
e-pTeX 3.14159265-p3.8.3-191112-2.6 (utf8.euc) (TeX Live 2020)
kpathsea version 6.3.2
...

Linux 安装:

# Arch Linux Family
sudo pacman -S texlive-most
# For Ubuntu, you might need a ppa:
sudo add-apt-repository ppa:jonathonf/texlive
sudo apt update && sudo apt install texlive-full
# Fedora
sudo dnf install texlive-scheme-full

对于 Windows 和其他 Linux 操作系统,请参见本页。

[## 创建 Dockernized LaTeX 环境的三种方法

LeTeX + Docker + VSCode 远程容器入门

towardsdatascience.com](/three-ways-to-create-dockernized-latex-environment-2534163ee0c4)

使用 latexmk 从终端创建 PDF

您通常需要多次运行 LaTeX。[latexmk](https://mg.readthedocs.io/latexmk.html)帮助您避免这种麻烦。Latexmk 是一个 Perl 脚本,你只需要运行一次,它就会为你做所有的事情。

latexmk 的使用方法如下:

$ latexmk -silent text.tex

当你保存一个 tex 文件时,它会自动更新 PDF 文件。我们可以通过修改您主目录中的.latexmkrc文件来改进它。

$ touch ~/.latexmkrc

并添加以下内容。

#!/usr/bin/env perl# LaTeX
$latex = 'latex -synctex=1 -halt-on-error -file-line-error %O %S';
$max_repeat = 5;# BibTeX
$bibtex = 'pbibtex %O %S';
$biber = 'biber --bblencoding=utf8 -u -U --output_safechars %O %S';# index
$makeindex = 'mendex %O -o %D %S';# DVI / PDF
$dvipdf = 'dvipdfmx %O -o %D %S';
$pdf_mode = 3;# preview
$pvc_view_file_via_temporary = 0;
if ($^O eq 'linux') {
    $dvi_previewer = "xdg-open %S";
    $pdf_previewer = "xdg-open %S";
} elsif ($^O eq 'darwin') {
    $dvi_previewer = "open %S";
    $pdf_previewer = "open %S";
} else {
    $dvi_previewer = "start %S";
    $pdf_previewer = "start %S";
}# clean up
$clean_full_ext = "%R.synctex.gz"
  • 我们使用platexdvipdfmx将一个 tex 文件转换成 PDF。
  • latexmk -pv text.tex构建后会显示一个 PDF。
  • latexmk -pvc text.tex保存 tex 文件时会更新 PDF 文件。(您需要单击 PDF 文件来查看更新。)
  • 您可以通过ctrl+C停止查看更新的文件。

将 LaTeX Workshop 扩展安装到 VS 代码

现在让我们转到 VS 代码。我们可以在 LaTeX 编辑器中使用 VS 代码。

VSCode 扩展 LaTeX 研讨会。作者图片

安装 LaTeX Workshop 后,您会在左侧边栏的末尾看到 TeX 图标。

LaTeX Workshop 扩展在保存时创建一个 PDF,您可以在 VS 代码或浏览器中查看 PDF。它具有格式化、智能感知完成、语法高亮、代码片段和快捷方式等功能。

LaTeX Workshop 菜单项。作者图片

您可以通过单击查看 LaTeX PDF 预览 PDF。

按 CMD/CTRL+SHIFT+P 打开 settings.json。

VS 代码 CMD/CTRL+SHIFT+P .图片作者

在 settings.json 中添加以下内容:

{
// your other settings
// ...
// ...
// ---------- Language ----------
    "[tex]": {
        // Enable intellisence/quick suggestions
        "editor.suggest.snippetsPreventQuickSuggestions": false,
        // Indentation size
        "editor.tabSize": 2
    },
    "[latex]": {
        // Enable intellisence/quick suggestions
        "editor.suggest.snippetsPreventQuickSuggestions": false,
        // Indentation size
        "editor.tabSize": 2
    },
    "[bibtex]": {
        // Indentation size
        "editor.tabSize": 2
    },
    // ---------- LaTeX Workshop ----------
    //  Enable command and environment completion for used package
    "latex-workshop.intellisense.package.enabled": true,
    // target file when deleting generated file
    // Add "* .synctex.gz" to default value
    "latex-workshop.latex.clean.fileTypes": [
        "*.aux",
        "*.bbl",
        "*.blg",
        "*.idx",
        "*.ind",
        "*.lof",
        "*.lot",
        "*.out",
        "*.toc",
        "*.acn",
        "*.acr",
        "*.alg",
        "*.glg",
        "*.glo",
        "*.gls",
        "*.ist",
        "*.fls",
        "*.log",
        "*.fdb_latexmk",
        "*.snm",
        "*.nav",
        "*.dvi",
        "*.synctex.gz"
    ],
    // dump generated files to "out" directory
    "latex-workshop.latex.outDir": "out",
    // Build recipe
    "latex-workshop.latex.recipes": [
        {
            "name": "latexmk",
            "tools": [
                "latexmk"
            ]
        },
    ],
    // Parts used in the build recipe
    "latex-workshop.latex.tools": [
        {
            "name": "latexmk",
            "command": "latexmk",
            "args": [
                "-silent",
                "-outdir=%OUTDIR%",
                "%DOC%"
            ],
        },
    ],
}

默认情况下,智能/快速建议不会在代码段内触发。要启用它们设置:

"editor.suggest.snippetsPreventQuickSuggestions": false,

创建您自己的片段

LaTeX Workshop 提供了许多片段和快捷方式。您也可以添加自己的代码片段。单击 VS 代码工具栏左下方的 cog,并选择 User Snippets。

用户片段。作者图片

并从菜单中选择 latex.json (LaTeX)。

选择 latex.json. Image by Author

让我们创建一个基本模板。以下是您可以添加的示例片段:

{
 "report": {
  "prefix": "report",
  "body": [
   "\\documentclass[${1:a4paper,11pt}]{${2:jsarticle}}",
   "",
   "",
   "% Math",
   "\\usepackage{amsmath,amsfonts}",
   "\\usepackage{bm}",
   "% image",
   "\\usepackage[dvipdfmx]{graphicx}",
   "\\usepackage[english]{babel}",
   "$3",
   "",
   "\\begin{document}",
   "",
   "\\title{$4}",
   "\\author{$5}",
   "\\date{${6:\\today}}",
   "\\maketitle",
   "",
   "",
   "$0",
   "",
   "",
   "\\end{document}"
  ],
  "description": "LaTeX Sample Template"
 }
}

您可以添加多个代码片段:

{
 "report": {
  "prefix": "report",
  "body": [
  ...
  "description": "LaTeX Sample Template"
 },
 "note": {
  "prefix": "note",
  "body": [
  ...
  "description": "Note format"
 },
  "exam": {
  "prefix": "exam",
  "body": [
  ...
  "description": "Exam format"
 }
}

测试代码片段

我发现 VScode 的 tabstop 不能与 Vim/vscodevim 一起使用,所以如果你正在使用它,你需要禁用它。

实际操作中的一个片段。作者图片

LaTeX 车间错误

当您保存一个 tex 文档时,如果您有以下错误,您需要安装一些 Perl 包。

LaTeX Workshop 错误。作者图片

首先安装最新的 Perl:

# For Mac
$ perl -v
This is perl 5, version 18, subversion 2 (v5.18.2) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)Copyright 1987-2013, Larry Wall
...
$ brew install perl

打开一个新标签或重启您的终端并检查安装的版本:

$ perl -vThis is perl 5, version 32, subversion 0 (v5.32.0) built for darwin-thread-multi-2levelCopyright 1987-2020, Larry Wall

您必须安装以下 Perl 包:

$ cpancpan[1]>install Log::Log4perl
Running install for module 'Log::Log4perl'
...
cpan[2]>install Log::Dispatch::File
Running install for module 'Log::Dispatch::File'
...
cpan[3]>install YAML::Tiny
Running install for module 'YAML::Tiny'
...
cpan[4]>install File::HomeDir
Running install for module 'File::HomeDir'
...
cpan[5]>install Unicode::GCString
Running install for module 'Unicode::GCString'
...

保存时自动更新 PDF

您可以通过单击 LaTeX Workshop 菜单中的“在 VSCode 中查看”或“在 web 浏览器中查看”来查看 PDF。

当您更新并保存 tex 文件时,它将自动更新 PDF 文件。

乳胶菜单。图片作者。

当您保存 tex 文件时,PDF 将被更新。图片作者。

结论

MacTeX 是一个巨大的文件,但是使用 macTeX-no-gui 和 VS 代码允许我们在保存一个 tex 文件时进行更新。

现在您知道了如何使用latexmk从终端创建 PDF。如果您喜欢用 GUI 将 LaTeX 转换成 PDF,LaTeX Workshop 是一个很好的工具。您可以在 VSCode 中创建自己的 LaTeX 代码片段。

我希望您发现这很有用,并且希望这将有助于您在编写 LaTeX 文档时的生产力。

参考

通过 成为 会员,获得媒体上所有故事的访问权限。

https://blog.codewithshin.com/subscribe

如何自动接收电子邮件中的 Excel 文件-提高您的工作效率

原文:https://towardsdatascience.com/how-to-automate-excels-received-on-email-increase-your-productivity-3d2f50ddc958?source=collection_archive---------19-----------------------

从电子邮件下载文件并按照我们的要求进行处理的分步指南

我们每天都会收到大量的电子邮件;有些是垃圾邮件,有些是促销邮件,有些很重要,有些非常重要(比如我的故事通知)。管理相同的内容是一个繁琐的过程。让我们把日常工作外包给电脑来减轻我们的负担。

假设多家银行通过电子邮件向我们发送每日交易摘要,我们需要在一个 excel 中整理这些摘要以执行现金流分析。现在,我们有很多这样的用例,比如来自多个供应商的发票、来自多个员工的 MIS(管理信息系统)、工作邀请电子邮件、多个新闻文章等等。

WebarooUnsplash 上拍摄的照片

外包这项活动不仅可以减轻我们的工作,还可以通过降低人工出错率来提高我们的生产率。我们将使用强大的 ETL 工具 Pentaho Data Integration (Kettle)来实现这种自动化。我们不必编写一行代码来执行这种自动化。是-没有代码!

如果你没有在你的系统中安装 PDI,那么我会建议你仔细阅读下面的分步指南。

[## Pentaho 数据集成安装指南-简单而强大的 ETL 工具。

使用简单的图形用户界面构建数据管道,无需编写一行代码。

medium.com](https://medium.com/ai-in-plain-english/pentaho-data-integration-installation-guide-easy-yet-powerful-etl-tool-80930cff46c6)

用户故事——让我们定义我们的用例

如果你一直在跟踪所有的故事,那么我观察到一个标准的模式,比如用简单的英语定义故事,编写测试用例,然后一步一步的过程。

  • 我想从我的 Gmail 下载银行对账单 CSV 文件。
  • 我想把收到的信息整理成一个文件。

输入数据

理解输入数据和细微差别是一个很好的实践。这有助于我们编写广义逻辑。

这些是从 Bank-1 和 Bank-2 接收的虚拟交易数据。我们总是可以摆弄真实的数据集。

银行 1 交易数据

Bank - 2 交易数据

正如您所观察到的,这两个库都遵循预定义的结构,唯一的区别是头的命名约定。我们可以在数据管道流中进行同样的管理。

请注意,在现实世界中,您不会看到结构相同的场景。然而,我们可以使用元数据注入插件来处理如此复杂的结构。

测试案例

让我们为这个管道定义我们的测试用例。

  • 检查输出文件格式。
  • 在输出文件中交叉验证两个供应商的报表中的几个行项目。

步骤 1:项目设置

理想情况下,建立项目的基本框架是一个很好的实践。正如我在之前的故事中提到的。我更喜欢把我所有的项目存放在一个名为 Work 的文件夹里。

  1. 输入- 这是我们下载报表的地方。
  2. 输出 -存储我们的输出文件
  3. 这是我们配置和下载电子邮件文件的地方。PDI 工作档案。
  4. Process-Bank-1-file . ktr&Process-Bank-2-file . ktr——这些是我们将在其中处理下载的 CSV 文件的转换文件。

项目文件夹结构

如果你有任何困难理解上述步骤或勺子(桌面应用程序),然后要求你通过下面的链接。

[## Pentaho 数据集成(Kettle)及其组件入门。

了解勺子、平底锅、厨房等关键部件将使我们对 PDI 工具有更好的了解

medium.com](https://medium.com/ai-in-plain-english/getting-started-with-pentaho-data-integration-kettle-and-its-components-ef1e71101323)

步骤 2: 设置应用程序密码

假设我们在 Gmail 账户中收到了银行对账单。这可以是任何帐户,我们可以阅读电子邮件,只要我们有相同的开放认证(OAuth) 细节。

我们需要设置一个应用程序密码,通过没有双重认证的应用程序读取 Gmail。我们需要遵循谷歌提供的指南。下面是截图指南。我们需要在您的个人资料图标中点击“管理您的 Google 帐户”。

点击安全标签,然后点击应用程序密码

在选择应用程序选项中选择“邮件”,然后选择设备其他(自定义名称)

您将收到一个弹出窗口,要求输入应用程序密码。复制并存储在安全的地方

请注意,我们不能使用我们的 Gmail 密码通过 PDI 或任何其他应用程序来验证或访问电子邮件。我们将不得不创建一个相同的应用程序密码。

第三步:让我们阅读 Gmail 并下载文件

一旦设置了应用程序密码,我们就可以从 Gmail 下载文件并对其进行分析。下面是我们需要观察的步骤。

  • 拖动步骤/插件:在 PDI main.kjb 作业文件中,我们需要搜索‘开始’,‘获取邮件(pop 3/IMAP)’,‘转换’和‘成功’步骤。

主作业流程

  • 编辑“获取邮件”步骤属性:我们需要双击“获取邮件(POP3/IMAP)”步骤并编辑属性。下面是我们需要编辑的属性。
  1. 我们需要使用 POP3 或 IMAP 来读取和获取文件。你可以通过下面的链接了解更多相同的内容。我们需要将步骤名称重命名为“download_bank_statements”。
  2. 源主机里,放上 imap.gmail.com。我们需要选中使用 SSL 复选框
  3. 我们需要使用端口993;这是特定于 IMAP 和 SSL 的。您可以参考第 1 点链接来了解各种端口。
  4. 填写你的用户名和 app 密码(不要用你的 Gmail 密码;就不行了)。请注意,medium.blog@gmail.com 是一个虚拟地址。
  5. 目标目录定义为输入路径。确保获取邮件附件和不同的文件夹被选中。
  6. 设置选项卡中,我们需要更改检索以获取所有消息选项。这是因为我们可能每天都会收到相同的命名约定文件。或者,我们还可以执行一些活动,比如将电子邮件移动到其他目录,比如“已处理”或删除电子邮件等。
  7. 过滤器选项卡中,我们需要使用接收日期过滤器添加一个过滤器。同样,我在这里硬编码了日期。但是,我们可以很容易地使用系统日期变量。我会写一个单独的博客解释 PDI 的变数。我们也可以去掉这个过滤器;这将获取所有的电子邮件

常规选项卡属性

设置选项卡属性

过滤器选项卡属性

带有电子邮件的收件箱截图示例

既然我们已经配置了电子邮件下载流程。让我们核对一下这两个文件。

第四步:整理信息

整理多个工作簿中的信息有多种方法。我们可以创造一个广义的流动;它迎合了多种类型的结构或者创建了一个简单的 case 转换。我们将使用后者。

如果你想推广多工作簿处理,那么我会推荐你阅读下面的指南。

[## 如何自动化多个 Excel 工作簿并执行分析

应用这个循序渐进的指南来解决问题,使用神奇的元数据注入 PDI。

towardsdatascience.com](/how-to-automate-multiple-excel-workbooks-and-perform-analysis-13e8aa5a2042)

Process-Bank1-Files.ktr 和 Process-Bank2-Files.ktr 转换是相同的,唯一的区别在于文件名的变化。

打开 Process-Bank1-Files.ktr,拖动“文本文件输入”和“Microsoft Excel Writer”。

  1. 文本文件中输入,我们将把名称改为 input。
  2. 文件页签中,浏览到‘D:\ Work \ automate mail \ Input \ Bank-1-transaction . CSV’;假设银行遵守相同的命名惯例。
  3. 内容页签中,将分隔符改为“,”,格式改为 mixed。
  4. 字段选项卡中,点击获取字段按钮,并将名称列更改为列 1、列 2、列 3..如下面的邮件所示。

文件选项卡属性

字段选项卡属性

在“Microsoft Excel writer”插件和文件&工作表标签中,添加输出文件的文件路径(D:\ Work \ automatemulelexcel \ Output \ consolidated statement),在扩展名字段中将扩展名更改为xlsx【Excel 2007 及以上】,如果输出文件存在字段,则在中选择使用现有文件写入,并选择写入现有工作表****

在“Microsoft Excel writer”插件和内容选项卡中,选择写入行时将中的现有单元格下移,勾选在工作表末尾开始写入(追加行),勾选省略标题字段,点击获取字段按钮。

文件和工作表标签属性

内容选项卡属性

现在,我们需要复制相同的转换,只需将输入文件名更改为 D:\ Work \ automate mail \ Input \ Bank-2-transaction . CSV

我们需要在输出文件夹中创建一个空的 excel (xlsx)文件,并将其命名为 ConsolidatedStatement.xlsx,标题如下。这里的想法是创建一个模板并定期覆盖它。

就这样,让我们看看它是否工作。

步骤 5:连接、执行作业和测试

在 Main.kjb 文件中,我们需要通过顺序浏览来连接作业文件中的两个转换。

我们所有的努力都会在这一步得到理想的实现;在那里我们执行并看到输出。让我们看看我们创建的管道是否按照我们的预期工作。

成功

在这里,我们可以执行前面定义的测试用例,并根据我们的需求分析文件。

结论

上面的数据管道有一些细微的差别,可以调整,也可以推广到多种结构和文件。因为我是根据我的便利来挑选用例的,这可能是也可能不是真实的情况。但是,您可以以此为平台进行构建。我们可以使用 PDI 执行许多类似的活动。接下来,我们将以如何使用 PDI 发送电子邮件通知为例。

欢迎在评论区提问。

下一篇文章再见。快乐的 ETL

如果你喜欢类似的内容,那么我会推荐你使用下面的链接订阅。

[## WryteEx -开发、数据工程、项目管理等

我写的博客有数据工程、金融、Python、Python Django、项目管理、Web 开发等等……

wryteex.com](https://wryteex.com/)

如何使用 API 和 Google Cloud 通过 Python 自动收集金融数据

原文:https://towardsdatascience.com/how-to-automate-financial-data-collection-with-python-using-tiingo-api-and-google-cloud-platform-b11d8c9afaa1?source=collection_archive---------4-----------------------

Python 程序员分析股票价格的教程

资料来源:联合国人类住区规划署

介绍

本文将向您展示在 Google 云平台上托管 Python 脚本的一种方法。对于希望自动化从 API 收集财务数据的过程,并且正在寻找一种高效、安全的方式将整个过程存储在云平台上的人来说,学习这样做尤其有用。

我将通过收集给定公司样本的每日股票价格的 API 数据来说明这一过程。这些数据可以用来进行金融建模。

步骤 1:获取感兴趣证券的股票代码列表

第一步是收集相关公司列表的股票代码列表(每种证券的股票标识符);在这种情况下,我使用的是 SP500 索引组件,它的列表很容易在维基百科的相关页面上在线获得。

在许多情况下,股票代码列表可能已经以 csv/excel 格式存在,并从其他来源自动下载;在这种情况下,请跳到第 2 步。

从该表中,您可以识别对应于每种证券的符号,稍后您将使用该符号从 API 中获取股票价格数据。这是一个有用的表,可以作为目标数据库中的参考,因为您可以定期运行脚本来从该表中收集数据,并获得 SP500 成员的最新视图。考虑到这些公司的市场资本总额,变化并不频繁,但最好定期更新,以考虑进入/退出指数的公司。对于这种用例,一个季度一次被认为是一个很好的更新频率。

在下面的步骤中,脚本将每月执行一次,但目标频率应适应您希望完成的任务。

为了收集成员公司的表格,您需要编写一个 Python 脚本。r equestsBeautiful Soup Python 包是抓取维基百科页面并从其 HTML 代码中提取表格元素的好选择。

现在让我们来看一下相关的 Python 代码部分,以便在脚本中实现这一点。

  1. 导入相关的包:作为第一步,您需要导入相关的 Python 包,并定义指向在线数据源的 url 变量。您还应该导入熊猫包(" import pandas as pd "),因为您稍后会需要它。
import requests
from bs4 import BeautifulSoup
import pandas as pdurl="[https://en.wikipedia.org/wiki/List_of_S%26P_500_companies](https://en.wikipedia.org/wiki/List_of_S%26P_500_companies)" 

2.抓取数据:然后你需要用 request.get 方法获取相关的 url 内容。然后,你可以用提取它的文本。文本方法,,最后把它解析成一个 Beatiful Soup 对象。

r = requests.get(url,timeout=2.5)
r_html = r.textsoup = BeautifulSoup(r_html, 'html.parser')
components_table = soup.find_all(id="constituents")headers_html = soup.find_all("th")
df_columns=[item.text.rstrip("\n") for item in headers_html]

为了在 HTML 中定位表格,您可以检查页面的代码(这可以通过在 Google Chrome 上单击 Ctrl + Shift + I 来完成),并看到您感兴趣的表格元素有一个由成分组成的 ID,,您可以使用它将表格内容存储到 components_table 变量中。然后就可以用了。find_all 用给定的 ID 定位页面中的所有元素。在这个特定的页面中,有两个具有该 ID 的表,由 components_table 对象引用。鉴于此,我们将只使用第一个,这是我们在步骤 3 中特别选择的。

您还可以使用相同的方法( soup.find_all) 来标识表格标题,您将在我们的数据集中使用这些标题作为列名,并将它们存储到一个名为 df_columns 的列表变量中。

3.将数据存储到 Pandas Dataframe: 接下来,您需要通过索引 components_table 对象(驻留在索引 0 处)来隔离第一个表,然后找到表体中的所有行,这些行不是标题;继续将结果存储到数据行中。

然后,您可以遍历这些行,将每一行的文本内容拆分到一个列表元素中,过滤掉空值并将其存储到一个名为 stock、的列表中,然后您必须将它追加到一个名为 rows 的列表中。

然后,您可以将转换为 pandas DataFrame 对象,将 component_headers 解析为列名。 Component_headers 只不过是 df_columns 的一个子列表,它标识了属于两个表中第一个表的列,这两个表的 ID 为 constituents。

components_headers=df_columns[:9]data_rows=components_table[0].find("tbody").find_all("tr")[1:]rows=[]for row in range(len(data_rows)):

    stock=list(filter(None,data_rows[row].text.split("\n")))
    rows.append(stock)S_P_500_stocks=pd.DataFrame(rows,columns=components_headers)

4。将数据集保存到 csv 文件:如下面的代码所示,然后您将删除名为 SEC Filings 的冗余列,并使用。to_csv 方法在本地保存数据集。现在可以使用这个表从 API 中获取股票价格数据。

S_P_500_stocks.drop("SEC filings",inplace=True,axis=1)S_P_500_stocks.to_csv(r"/home/edo_romani1/my-python-directory/SP500stocks.csv",index=False)

步骤 2:使用 Tiingo API 收集历史股票价格数据

Tiingo 是一个金融市场 API,它提供了与多个市场的上市公司相关的各种信息;在本例中,我们对收集每日历史股票价格信息(日期、开盘、收盘、盘高、盘低、成交量)感兴趣,因此将参考相关的 Tiingo API 文档

让我们一步一步地分解代码,看看如何收集每个 SP500 成员公司 20 多年的每日股票价格信息。

1。导入相关包:和之前一样,导入需要的包。这一次,您还需要导入 datetime 模块,因为稍后您将使用它来定义我们希望从 API 中提取数据的时间窗口。

import requests
import pandas as pd
import datetime
from datetime import datetime,timedelta

2.定义 API 令牌:要与 API 交互,您需要获得一个 API 密钥或令牌,以便将我们自己标识为注册的 Tiingo API 用户。使用 Tiingo,您可以轻松地建立一个帐户并获得您的令牌。一旦完成,您需要做的就是在代码中声明它,并将其设置为一个变量,如下图所示。

token1="123RUXBJKSJKFJD23Y348"

3.导入您在步骤 1 中保存为 csv 文件的 SP500 成员表;这可以通过轻松完成。熊猫里的 read_csv 方法。

SP=pd.read_csv(r"/home/edo_romani1/my-python-repository/SP500stocks.csv")

4.调用 Tiingo API 并获取历史股票价格数据

您首先必须建立一个要迭代的股票代码列表,以便对每个股票代码进行 API 调用,将它们存储在变量 ticker_symbols 中,您可以在下面一行中添加 SP500 索引值(“SPY”)来扩展这个变量。

您还可以设置想要从 API 调用数据的最晚日期( end_date 变量),因为对于每只股票,您将调用股票价格历史,因此必须设置一个时间窗口来划分。将 end_date 设置为昨天(下面使用 datetimetimedelta 模块计算得出— datetime.now.date() 得到今天的日期,使用 timedelta 函数减去 1 天,得到今天-1 天=昨天)。

注意:Tiingo 有每小时和每天的 API 调用限制 ,它们是通过使用作为上下文管理器的rate _ limiter包来处理的。知道你是否每小时/每天打很多电话是很重要的。

最后,您需要初始化一个空列表 data1 ,它将用于存储每个股票价格/ API 调用的历史数据集。

ticker_symbols=list(SP["Symbol"])
ticker_symbols.append("SPY")
end_date=str(datetime.now().date()-timedelta(days=1))

接下来的几行代码是您实际调用 Tiingo API 来获取每个感兴趣的股票代码的数据。首先需要在 Tiingo url 中设置符号、end_date 和 token 参数提交到 request.get 方法中;然后,您需要将响应存储到变量 r,中,该变量对应于包含给定股票行情自动收录器的股票价格历史的 csv 文件。下面代码中的几行代码将这些值转换成一个列表,然后是一个 dataframe df ,在以迭代的方式移动到下一个 ticker_symbol 之前,您将把它追加到 data1 集合中。

注意:try子句用于处理由请求包引起的超时错误,下面的 except 子句用延长的超时时间重复相同的代码来处理更长的响应;代码与下面的代码相同,唯一的区别是超时参数的值(是双精度的),因此为了简单起见,省略了它。

data1=[] for symbol in ticker_symbols:
        #with rate_limiter:
                try:
                        url = "[https://api.tiingo.com/tiingo/daily/{}/prices?startDate=2000-01-03&endDate={}&format=csv&token={](https://api.tiingo.com/tiingo/daily/{}/prices?startDate=2000-01-03&endDate={}&format=csv&token={)}".format(symbol,end_date,token1) r = requests.get(url,timeout=10) rows=r.text.split("\n")[1:-1] df=pd.DataFrame(rows)
                                                                        df=df.iloc[:,0].str.split(",",13,expand=True) df["Symbol"]=symbol
                        data1.append(df)

5。将数据集保存到 csv 文件:作为最后一步,您可以使用。concat 方法将数据帧列表连接成一个最终数据集,然后像前面一样将其保存到一个 csv 文件中。

df_final=pd.concat(data1)
df_final.drop(df_final.iloc[:,6:13],axis=1,inplace=True)df_final.to_csv(r"/home/edo_romani1/my-python-repository/historicalSP_quotes.csv",index=False)

下面是最终输出的 csv 视图,从中我们可以观察到样本中第一家公司的初始日期和相对价格数据。

输出包含 SP500 会员股票价格历史记录的 csv 文件;来源:作者

现在,您已经有了两个从 Tiingo API 获取股票数据的全功能 Python 脚本,让我们看看如何使用谷歌云平台(GCP)自动运行它们,以便每天开市时您都可以收集前一天的最新报价。我将展示我们如何利用 Google 的计算引擎、云功能、云存储和 GoogleBigQuery 来建立一个简单的数据摄取工作流,它将基于这两个运行在云上的脚本,从而远离我们的本地机器。

步骤 3:在 Google 云计算引擎上自动化和调度 Python 脚本

您可以使用 GoogleCloud ComputeEngine 启动一个 VM 实例,而不是在本地运行我们的两个 Python 脚本。您可以轻松地启动一个 Linux 虚拟机,并通过 SSH 连接到它。

连接后,您将看到以下终端视图:

GoogleCloud 计算引擎上的 Linux 虚拟机终端。来源:作者

此时,使用右上角的 settings 按钮,您可以选择“Upload file ”,在 VM 的文件系统中快速移动我们的 Python 脚本。

一旦完成,您的脚本将被存储在虚拟机上。当数据集保存为 csv 文件时,不要忘记更改 python 脚本中的本地路径引用;在终端上,您可以用 mkdir 命令建立一个新目录,并用 pwd 命令获取给定文件的文件路径。更多详细信息可在这里找到。您可以使用 python (或 python3 ,取决于您的 python 版本)命令,后跟要执行的 py 文件的位置,从终端启动并运行这两个脚本中的任何一个。

首先,您可能希望首先运行 SP500 成员集合脚本,以便第二个脚本能够正确导入从中提取股票代码列表的 csv 表。

最后,您可以使用 cron 作业直接从 linux 终端自动执行这两个脚本;您可以使用 crontab -e 命令访问 crontab,然后设置 cron 作业计划,随后执行 python 文件。

在这个设置中,我每月运行一次第一个脚本,以便在股票市场开放的每一天更新 SP500 组件和股票价格 API 脚本,因此是每周二到周六(以便获得每周星期一到星期五最后一天的数据)。下面是所描述的 crontab 的一个示例视图。

Crontab 计划视图。来源:作者

步骤 4:将输出表存储到 GoogleCloudStorage 中

现在您已经自动化了脚本的执行,下一步是将两个输出表(SP500 成员表和所有成员的股票价格数据表)移动到 GoogleCloud 中的一个存储位置以供参考。我已经使用 GoogleCloud Storage 实现了这一点,并将展示如何在将数据转移到数据仓库解决方案(在本例中是 GoogleBigQuery)之前,在 GoogleCloudStorage 中暂存数据。

在你这么做之前,你可以使用谷歌云的控制台为你各自的文件快速创建两个不同的存储桶。创建之后,您可以简单地将两个 csv 输出表上传到每个 bucket。

要与 GoogleCloud Storage 通信,您可以使用 GoogleCloud 提供的 p ython CloudStorage 客户端库;不要忘记设置认证凭证,以便与您的 GoogleCloud 帐户资源进行通信。

设置完成后,您只需将以下代码块添加到我们两个 Python 脚本的末尾,即可完成该过程:

import os
from google.cloud.storage.blob import Blobos.environ['GOOGLE_APPLICATION_CREDENTIALS']=r"/home/edo_romani1/My First Project-69347b3b5af2.json"storage_client = storage.Client()bucket = storage_client.get_bucket("spcomponents")
data=bucket.blob("SP500stocks.csv")data.upload_from_filename(r"/home/edo_romani1/my-python-directory/SP500stocks.csv")

前两行导入必要的包;然后,代码通过 os.environ、设置应用程序的 credentials,它指向包含我们的 GoogleCloud 个人凭证的 json 文件的位置(在 Linux VM 上)。

然后可以初始化存储客户机,用获取存储桶信息。get_bucket 方法,选择要用 bucket.blob 更新的对象,然后在每次 python 脚本运行时用更新对象。upload_from_filename 命令,指向相关文件的 Linux VM 位置。上面的示例只显示了第一个输出表的流程,您只需要更改必要的文件桶/路径/名称/位置细节,就可以复制股票价格数据集的流程。

现在,每次运行 python 脚本时,GoogleCloudStorage 上相应的存储桶都会更新最新的数据。

步骤 5:使用 CloudFunctions 自动将文件从 CloudStorage 传输到 GoogleBigQuery

云函数允许我们运行针对特定 GoogleCloud 资源的事件驱动代码,例如,在我们的例子中,GoogleCloud 存储桶。

让我们看看如何设置一个来完成以下任务:每次将 csv 输出表上传到 GoogleCloudStorage 时,您可以将这些表移动并上传到 GoogleBigQuery ,这是 GoogleCloud 的数据仓库解决方案(众多解决方案之一),非常适合处理关系数据,如本教程中的数据。

  1. 创建一个 GoogleBigQuery 数据集 作为必要的设置步骤。您可以将 GoogleCloudStorage 设置为我们两个表的表源,并临时加载我们最新的可用表。
  2. 编写将表格数据从 GoogleCloudStorage 上传到 GoogleCloudBigQuery 的代码;这将是每次在 GoogleCloudStorage 上生成更新时 CloudFunction 将运行的实际代码。该表的代码如下:
def csvloader(data,context):
    from google.cloud import bigquery client = bigquery.Client()
    table_ref = client.dataset("csm").table("SPhistorical") job_config = bigquery.LoadJobConfig()
    job_config.write_disposition =     bigquery.WriteDisposition.WRITE_TRUNCATE
    job_config.skip_leading_rows = 1

    job_config.source_format = bigquery.SourceFormat.CSV
    uri = "gs://csm_erat/Data/historicalSP_quotes.csv" load_job = client.load_table_from_uri(uri, table_ref, job_config=job_config)load_job.result()
    destination_table = client.get_table(table_ref)

代码定义了一个 csv_loader 函数,该函数导入必要的 BigQuery 客户端包,将其初始化为 c lient,连接到之前创建的 BigQuery 表(该示例仅针对历史股票价格数据,但对于我们要移动的每个文件,其结构都是相同的)作为 table_ref。然后,代码在下面几行代码中用某些配置参数建立一个加载作业(比如在加载新表时覆盖当前 BigQuery 表的指示,读取时跳过的 n 行数和源文件格式的指示- csv -)。然后,它定义源路径( uri ),在其中找到要上传的新数据,并用加载它。load_table_from_uri 方法及相关参数。uri 指向数据的 GoogleCloudStorage 位置。数据上下文参数与事件有效载荷和触发事件的元数据有关,但在这方面不是核心加载作业的一部分。更多信息可在这里找到。

关于如何使用 BigQuery 客户端库的完整细节可以在这里找到。它还包含有关如何设置身份验证的有用信息。

3.使用步骤 2 中定义的代码设置 Google CloudFunction

您最终可以从 GCP 控制台部署我们的云功能,方法是点击云功能资源,然后点击“创建功能”;然后可以输入函数名、触发器(在我们的例子中是云存储)和运行时(Python3)。完成后,您可以粘贴您的功能代码并部署它;该功能将启动并运行,您将能够通过 GCP 控制台中的事件日志对其进行监控。

第 6 步:在 BigQuery 中查看数据集和表

现在,您可以通过访问其 UI,选择我们的 GCP 项目>数据集>表格>预览,在 GoogleBigQuery 中直接从 API 访问最新的数据拉取。您也可以在详细信息部分查看最新更新时间。

后续步骤

您的工作流程已正式建立,从开始到结束只需 5 分钟。

这是一个非常简单的解决方案,你只需要几个 Python 脚本和 GCP 的免费等级账户就可以完成。

一个不错的下一步是只调用一次股票价格数据的整个历史,并修改 API 调用(url 变量中的)以只获取昨天的值。

希望这份循序渐进的指南将有助于您使用 GCP 的金融数据建立下一个 Python 项目!

[## 如何使用 Big Query & Data Studio 在 Google Cloud 上处理和可视化财务数据

GCP 从业者从金融数据开始的教程

towardsdatascience.com](/how-to-process-and-visualize-financial-data-on-google-cloud-with-big-query-data-studio-f37c2417d4ef)

访问我的免费数据科学资源清单 这里

[## 通过我的推荐链接加入 Medium-Edoardo Romani

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

edo-romani1.medium.com](https://edo-romani1.medium.com/membership)

如何用 Documenter.jl 自动化 Julia 文档

原文:https://towardsdatascience.com/how-to-automate-julia-documentation-with-documenter-jl-21a44d4a188f?source=collection_archive---------32-----------------------

没有文档,软件是没有用的,所以用 Documenter.jl 把文档的痛苦去掉吧

不管喜欢还是讨厌,文档创建在任何软件的创建中都是相当关键的一步。您可以构建人类已知的最伟大的模块,但是没有文档,没有人会知道如何使用它。当涉及到编程时,创建文档常常是事后的想法。制作模块和应用程序既费时又困难,还会让人非常沮丧。因为一般来说,编程通常是一个非常棘手的过程,并且可能比预期的要长得多,所以文档通常是编程过程中非常冗长、乏味的一部分。

对 Julia 开发者来说幸运的是,有 Documenter.jl. Documenter.jl 是一个模块,可以用来从代码中提取 Julia 文档字符串,并将它们编译成元信息、markdown 和 HTML。Documenter 不仅能够自动创建文档网站,而且还具有一些功能,可用于轻松地将文档推入存储库,以自动完成在 web 上加速文档的整个过程。

Julia 文档

像大多数其他语言一样,Julia 以文档字符串为特色,文档字符串记录了实际软件本身内部的代码。然而,与大多数其他语言不同,Julia 有一种非常酷的方式来研究这种文档,这使得使用模块变得轻而易举。首先,Julia 包含了一个帮助函数?(),它可以用在语言中的任何模块、类型、宏或函数上。

这本身就非常有帮助,如果你的模块有一个文档图,比如 Lathe,那么你就不需要去网站查看 Julia 语言的文档。

最重要的是,如果您碰巧使用 Juno 在中开发 Julia,那么您就可以利用出色的文档窗格。使用 documentation 窗格,您可以在文本编辑器中将 Julia 模块文档预编译到一个漂亮的 GUI 中,然后查看所有包的文档。

要在 Julia 中记录一个函数,只需在函数上方添加一个 docstring 即可。或者,您也可以使用@doc 宏来记录一些东西。

@doc"""
This is my docstring!\n
I like pizza.
"""
function thisisdocumented()
    continueend

设置您的文件系统

为了用 Documenter.jl 创建文档,我们首先需要设置一些目录供模块使用。我们将首先创建一个根目录来存储我们的文档。这通常是在 Julia 包的/doc 目录中完成的,但是,重要的是要记住,Documenter 使用的是您的全局 Julia 包,而不是您的本地包。因此记住这一点,您不一定需要将这些文件放入存储库的位置。但是,这有一个条件,因为为了构建文档,您必须有一个源目录。

cd Projects
mkdir HoneDox
cd HoneDox

现在我们在一个空的目录中,我们需要为 Documenter 创建一个基本的文件结构。在此过程中,我想创建的第一个文件是“index.md”。如果没有 Index markdown 文件,Documenter 将无法创建文档,因此该文件非常重要,并且不会自动生成。

touch index.md

接下来,我们将创建一个文件。您可以将它放在一个名为 Doc 的新目录中,或者放在几乎任何地方。

mkdir doccd doc
nano make.jl

在这个文件中,我们首先要做的是导入文档管理器。

using Documenter

接下来,我们想要导入我们想要为其制作文档的模块。对于这个例子,我将使用 Hone.jl。

using Hone

如果您想要文档化的包没有导出您想要文档化的函数,那么您也必须添加作为该模块的子模块的任何模块。当使用 auto-doc 时,这将使您更容易将不同模块的文档分开。我不会这样做,因为 Hone 的所有功能都包含在内,并且不需要使用任何附加模块就可以导出。

接下来,我们需要从文档管理器中调用 makedocs()方法。这个函数需要很多参数,所以我将逐一介绍:

root - Root will determine where the file-system root is for this project. This is equivalent to the top of the repository in Github, and most of the time is going to be "./"source - Source is the directory of your source files from the root directory.build - Build is the directory where you want Documenter to put your new HTML site from the root directory.clean - This is a boolean that will determine whether or not Documenter is going to clean the build after finishing.doctest - Doc test is another boolean that will determine whether or not Documenter will let you know of any problems with your module's docstrings, e.g. undocumented functions.modules - These are the modules that we imported before, they will be put into a list here for Documenter to process.repo - Repo will determine where your " edit on github" link will go. We will be ignoring this for now.sitename - Just a name for your site, this will appear in the title of your HTML document, as well as the upper left-hand corner of the default style documentation site.expandfirst - This parameter will take a page and expand it in the left side context menu. I usually leave this blank, as your current page will always be expanded.pages - This will be a mapped dictionary of all your documentation files (e.g. index.md) and their corresponding titles. The titles will fill into the menu (on the left with the default style.)

我的文件看起来是这样的:

现在我们需要用 ctrl + x 关闭 nano,我们可以继续创建我们的源目录。

mkdir src

然后,我们将把源文件复制到该目录中。接下来,我们将把 index.md 移动到 src 目录中。之后,我们可以继续运行 make.jl:

mv index.md src
cd doc
julia make.jl

过一会儿,一个新目录将出现在我们的根文件夹中,名为“build”如果我们打开那个文件夹,我们会看到一个绝对的文件巨兽。现在唯一对我们重要的是 index.html。如果您现在在浏览器中打开该文件,您可能会看到类似以下内容:

厉害!

创建文档

现在我们终于可以开始处理 index.md 文件了。这个文件当然只是简单的 Github markdown,所以我们可以添加一个带有标签的标题。

# This is an example title
## This is a smaller title
### This is an even smaller title

现在,如果我们再次运行 make.jl 文件并刷新页面,

请注意,右边的菜单现在已被填充。现在我们可以开始讨论一些宏,我们可以用它们来自动填充文档。宏的使用方式总是与 Github Markdown 中的代码使用方式相似,其中有三种方式:

`

打开,还有三个要关闭。

首先我们要看一下@meta 宏。这个宏用于界定需要由 Julia 运行的代码。这主要用于设置当前模块,如下例所示:

```[@meta](http://twitter.com/meta)
CurrentModule = ourmodule
DocTestSetup = quote
    using ourmodule
end

下一个重要的宏是@doc 宏,它将完成您可能会想到的功能。@doc 宏后面是您想要记录的函数、模块、宏或类型。

examplemodule.function

还有一个没有参数的上下文宏,它将为您的文档创建一个目录。


我要演示的最后一个重要的宏是@autodoc 宏,它是这个列表中最酷的一个。@autodoc 采用单个参数。这个参数只是一个为其创建文档的模块列表。对于这个例子,我将使用@contents@autodoc。首先,我将把@autodoc 添加到 Hone 模块的 index.md 中。

# 页

对于我的索引页面组合,我决定将所有文档存储在一个页面中。这是因为从 0.0.3 版本开始,Hone 中确实没有太多需要处理的事情,所以不需要太多的组织。如果你想查看更复杂的文档,你可以在这里查看车床的文档:

 [## 索引

### 车床可以使用 Pkg 添加。julia >使用 Pkg julia> Pkg.add("Lathe ")解析包版本...正在更新…

车床. ai](http://lathe.ai/doc) 

这是我的最后一份文件:

Adding Hone

Pkg Registry

using Pkg
Pkg.add("Lathe")

Unstable

julia> ]
pkg> add Hone#Unstable

Specified Versions```@example

julia> ]
pkg> add Hone#0.0.1

Modules = [Hone]
```
```

再次运行 make.jl 并刷新页面后:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fbba8569ac116eed8299b5161b6cd4f6.png)

> 很酷,对吧?

回到我们的源目录,让我们添加另一个 markdown 文件。对于这个例子,由于我的模块的文档已经非常完整,我将制作另一个页面来展示 contents 宏。

```
nano toc.md
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fb561ee42ef799900a3539e987c4efcc.png)

(忽略我不小心把它命名为 toc.jl 的事实,我做了一个 oopsie。)

现在,我们只需将该文件添加到 make.jl 文件中的 pages dictionary 参数中。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/511563e7e6fa03f592424872d7c355bb.png)

然后再次运行 make 文件:

```
julia make.jl
```

现在,我们将在左侧的导航栏上提供多个页面。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1e224f7c94c1eb59ff3ca049d44a624f.png)

# 结论

Documenter.jl 就不用说了,牛逼!我喜欢不用手动创建文档!创建网站以提供带有适当搜索的文档可能需要几个小时甚至几天,并且需要更多的工作来维护。拥有一个可以自动完成这项工作的包,甚至可以把你的新构建推送到一个存储库,这绝对是一个巨大的祝福!

# 如何:使用 Python 将实时数据自动化到您的网站

> 原文:<https://towardsdatascience.com/how-to-automate-live-data-to-your-website-with-python-f22b76699674?source=collection_archive---------12----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0d46ea614e679c951310e8cc73d882bb.png)

图片来自 Unsplash

本教程将有助于那些拥有一个在云服务上托管实时数据的网站,但不确定如何完全自动更新实时数据以使网站变得无障碍的人。例如:我托管了一个[网站](http://tsbloxsom.pythonanywhere.com/),它在一个交互式仪表板中显示了德克萨斯州 COVID 县的病例数,但我每天都必须运行一个脚本来从德克萨斯州 COVID 网站下载 excel 文件,清理数据,更新用于创建仪表板的 pandas 数据框,将更新的数据上传到我正在使用的云服务,并重新加载我的网站。这很烦人,所以我使用本教程中的步骤来展示我的实时数据网站现在是如何完全自动化的。

我将只介绍如何使用云服务 pythonanywhere 来实现这一点,但是这些步骤可以转移到其他云服务。另一件要注意的事情是,我是网站建设和维护的新手,所以请随时纠正我或给我建设性的反馈。我将假设你对 python、selenium for web scraping、bash 命令有基本的了解,并且你有自己的网站。让我们来看一下将实时数据自动化到您的网站的步骤:

1.  使用云服务的 selenium 网络抓取
2.  将. part 文件中的下载数据转换为。xlsx 文件
3.  使用操作系统 python 包重新加载您的网站
4.  安排 python 脚本在 pythonanywhere 中每天运行

我将不会浏览我将要展示的一些代码,因为我使用了上一篇教程中的许多相同的代码,这些代码是关于如何使用 python 创建和自动化交互式仪表盘的。我们开始吧!

1.  **使用云服务使用 selenium 进行网页抓取**

所以在你选择的云服务中(我的是 pythonanywhere),打开一个 python3.7 控制台。我将展示代码块,但所有的代码可以合并成一个脚本,这就是我所做的。此外,代码中的所有文件路径都必须更改为您自己的路径,代码才能正常工作。

```
from pyvirtualdisplay import Display
from selenium import webdriver
import time
from selenium.webdriver.chrome.options import Optionswith Display():
    # we can now start Firefox and it will run inside the virtual display
    browser = webdriver.Firefox()# these options allow selenium to download files
    options = Options()
    options.add_experimental_option("browser.download.folderList",2)
    options.add_experimental_option("browser.download.manager.showWhenStarting", False)
    options.add_experimental_option("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream,application/vnd.ms-excel")# put the rest of our selenium code in a try/finally
    # to make sure we always clean up at the end
    try:
        browser.get('[https://www.dshs.texas.gov/coronavirus/additionaldata/'](https://www.dshs.texas.gov/coronavirus/additionaldata/'))# initialize an object to the location on the html page and click on it to download
        link = browser.find_element_by_xpath('/html/body/form/div[4]/div/div[3]/div[2]/div/div/ul[1]/li[1]/a')
        link.click()# Wait for 30 seconds to allow chrome to download file
        time.sleep(30)print(browser.title)
    finally:
        browser.quit()
```

在上面的代码块中,我使用 pyvirtualdisplay 库在 pythonanywhere 中打开了一个 Firefox 浏览器。没有新的浏览器会在你的电脑上弹出,因为它运行在云上。这意味着您应该在没有 display()函数的情况下在您自己的计算机上测试这个脚本,因为在云服务器中很难进行错误处理。然后我下载了一个。xlsx 文件,并将其保存在 pythonanywhere 中的 my /tmp 文件中。要访问/tmp 文件,只需单击“文件”选项卡上的第一个“/”,然后点击“主页文件”按钮。这些都是在 try/finally 块中完成的,所以在脚本运行之后,我们关闭浏览器,这样我们就不会再使用服务器上的任何 cpu 时间。另外需要注意的是,pythonanywhere 只支持一个版本的 selenium: *2.53.6。*您可以使用下面的 bash 命令降级到 selenium 的这个版本:

```
pip3.7 install *--user selenium==2.53.6*
```

**2。** **将. part 文件中的下载数据转换为。xlsx 文件**

```
import shutil
import glob
import os# locating most recent .xlsx downloaded file
list_of_files = glob.glob('/tmp/*.xlsx.part')
latest_file = max(list_of_files, key=os.path.getmtime)
print(latest_file)# we need to locate the old .xlsx file(s) in the dir we want to store the new xlsx file in
list_of_files = glob.glob('/home/tsbloxsom/mysite/get_data/*.xlsx')
print(list_of_files)# need to delete old xlsx file(s) so if we download new xlsx file with same name we do not get an error while moving it
for file in list_of_files:
    print("deleting old xlsx file:", file)
    os.remove(file)# move new data into data dir
shutil.move("{}".format(latest_file), "/home/tsbloxsom/mysite/get_data/covid_dirty_data.xlsx")
```

当你下载时。在 pythonanywhere 中,xlsx 文件存储为. xlsx.part 文件。经过一些研究,这些。当您停止完成下载时,会产生零件文件。这些。零件文件不能用典型的工具打开,但是有一个简单的技巧可以解决这个问题。在上面的代码中,我在云目录中自动移动新数据和删除旧数据。需要注意的是,当我移动. xlsx.part 文件时,我将其保存为. xlsx 文件。这会神奇地转换它,当你打开这个新的。xlsx 文件,它有所有的实时数据,这意味着我的脚本下载完成。xlsx 文件,但是 pythonanywhere 在文件中添加了一个. part,这很奇怪,但是很有效。

**3。使用操作系统 python 包重新加载你的网站**

```
import pandas as pd
import relist_of_files = glob.glob('/home/tsbloxsom/mysite/get_data/*.xlsx')
latest_file = max(list_of_files, key=os.path.getctime)
print(latest_file)df = pd.read_excel("{}".format(latest_file),header=None)# print out latest COVID data datetime and notes
date = re.findall("- [0-9]+/[0-9]+/[0-9]+ .+", df.iloc[0, 0])
print("COVID cases latest update:", date[0][2:])
print(df.iloc[1, 0])
#print(str(df.iloc[262:266, 0]).lstrip().rstrip())#drop non-data rows
df2 = df.drop([0, 1, 258, 260, 261, 262, 263, 264, 265, 266, 267])# clean column names
df2.iloc[0,:] = df2.iloc[0,:].apply(lambda x: x.replace("\r", ""))
df2.iloc[0,:] = df2.iloc[0,:].apply(lambda x: x.replace("\n", ""))
df2.columns = df2.iloc[0]
clean_df = df2.drop(df2.index[0])
clean_df = clean_df.set_index("County Name")clean_df.to_csv("/home/tsbloxsom/mysite/get_data/Texas county COVID cases data clean.csv")df = pd.read_csv("Texas county COVID cases data clean.csv")# convert df into time series where rows are each date and clean up
df_t = df.T
df_t.columns = df_t.iloc[0]
df_t = df_t.iloc[1:]
df_t = df_t.iloc[:,:-2]# next lets convert the index to a date time, must clean up dates first
def clean_index(s):
    s = s.replace("*","")
    s = s[-5:]
    s = s + "-2020"
    #print(s)
    return sdf_t.index = df_t.index.map(clean_index)df_t.index = pd.to_datetime(df_t.index)# initalize df with three columns: Date, Case Count, and County
anderson = df_t.T.iloc[0,:]ts = anderson.to_frame().reset_index()ts["County"] = "Anderson"
ts = ts.rename(columns = {"Anderson": "Case Count", "index": "Date"})# This while loop adds all counties to the above ts so we can input it into plotly
x = 1
while x < 254:
    new_ts = df_t.T.iloc[x,:]
    new_ts = new_ts.to_frame().reset_index()
    new_ts["County"] = new_ts.columns[1]
    new_ts = new_ts.rename(columns = {new_ts.columns[1]: "Case Count", "index": "Date"})
    ts = pd.concat([ts, new_ts])
    x += 1ts.to_csv("/home/tsbloxsom/mysite/data/time_series_plotly.csv")time.sleep(5)#reload website with updated data
os.utime('/var/www/tsbloxsom_pythonanywhere_com_wsgi.py')
```

我在上一篇[帖子](/creating-and-automating-an-interactive-dashboard-using-python-5d9dfa170206)中解释了上面的大部分代码,这些代码使用熊猫来清理 excel 文件,以便输入到 plotly 仪表板中。本教程最重要的一行是最后一行。os.utime 函数显示文件或 python 脚本的访问和修改时间。但是当你调用 Web 服务器网关接口(WSGI)文件上的函数时,它会重新加载你的网站!

**4。在 pythonanywhere 中安排 python 脚本每天运行**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4b100566fcf0d2457431a18eba163085.png)

真实的你的形象

现在是最简单的部分!将上述代码合并成一个代码后。py 文件,您可以使用 pythonanywhere 的 Task 选项卡让它每天或每小时运行。您所要做的就是复制并粘贴 bash 命令,以及运行。py 文件到上面图片的栏中,点击创建按钮!现在您应该测试。py 文件,看看它是否正确运行。但是现在你有了一个完全自动化的数据抓取脚本,你的网站可以用它来显示每日或每小时更新的数据,而无需你按一个按钮!

如果你有任何问题或批评,请在评论中畅所欲言,如果你想在 LinkedIn 上关注我,你可以!

# 如何自动化多个 Excel 工作簿并执行分析

> 原文:<https://towardsdatascience.com/how-to-automate-multiple-excel-workbooks-and-perform-analysis-13e8aa5a2042?source=collection_archive---------5----------------------->

## 应用这个循序渐进的指南来解决问题,使用神奇的元数据注入 PDI。

假设您被分配了一项任务,研究微软或苹果的供应商,并进行分析以做出更好的决策。这意味着要研究数百个不同格式、结构、名称等的供应商。现在,整理来自不同供应商的信息、标准化并对其进行分析是一个非常耗时的过程,对吗?

此外,我们必须在一定的频率后执行相同的活动,以了解更新的趋势。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/be2ac1997af845531b29430ff468cbc5.png)

在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上由 [Carlos Muza](https://unsplash.com/@kmuza?utm_source=medium&utm_medium=referral) 拍摄的照片

这是我们自动化和构建数据管道的一个很好的用例。当今工业中使用了多种方法。有些人编写 python/java 程序,有些人使用 VBA 宏,有些人使用 ETL 工具等等。

我们将使用 Pentaho Data Integration (Kettle)这个强大的 ETL 工具来执行这个活动。如果你是这个工具的新手,那么我会推荐你浏览关于使用 PDI 构建第一个数据管道的帖子,这里有链接。

[](https://medium.com/swlh/build-your-first-data-pipeline-in-just-ten-minutes-2a490867b901) [## 仅用 10 分钟构建您的第一条数据管道

### 通过使用 PDI 的真实用例,逐步构建您的第一个数据管道。

medium.com](https://medium.com/swlh/build-your-first-data-pipeline-in-just-ten-minutes-2a490867b901) 

## 用户故事——让我们定义我们的用例

让我们为上述用例编写我们的用户故事。使用简单的英语编写用户故事和创建故事板是跟踪状态或理解整个流程的好方法。这也有助于我们定义架构。

正如上一篇文章中提到的,用户故事是从用户的角度写的,下面是我们用例的实例。

*   我想读取多个供应商的 excel 文件。
*   我想在同一个流程中处理不同的结构和定制。
*   我想以一种单一的标准化格式(xlsx)存储输出。

这是三个简单的用户故事。然而,对于大多数程序来说,这并不是一个简单的用例。因此,让我们通过下面的分步指南来了解如何实现这一点。

## **输入数据**

让我们了解我们的各种供应商和输入数据。这将有助于我们设计数据管道流。

1.  **Supplier-1 -** 我们有一张来自 ABC 公司的 excel 格式的发票收据,其中数据从第 7 行开始,有 5 列。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a4fb7beb5e3dc77970e06c3fc7f47448.png)

来自供应商-1 的假发票数据

1.  **供应商-2 -** 我们还有另一张来自 XYZ 公司的 excel 格式的发票收据,这里的数据从第 5 行开始,有 6 列。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7ab0d422861ac54125f82ea11f4fa245.png)

来自供应商-1 的假发票数据

你可以看到这两种数据结构,列顺序,命名规则是不同的。然而,两者都非常干净,在真实的场景中不会这样。

## 测试案例

让我们为这个管道定义我们的测试用例。

*   检查日志中的错误。
*   检查输出文件及其格式(xlsx)。
*   在标准化输出文件中交叉验证来自两家供应商的两个随机发票行项目。

# 步骤 1:项目设置

让我们为我们的项目创建一个框架。我们将创建以下文件夹和文件。我更喜欢将所有与工作相关的东西存放在一个名为 **Work 的普通文件夹中。**

1.  **输入-** 这是我们存储所有供应商文件的地方。我们可以在输入文件夹中创建两个子文件夹,即。**供应商 1****供应商 2** (这是完全可选的)
2.  **输出-** 显然用于存储输出文件。
3.  **元数据-** 这是我们存储文件元数据(关于文件结构的信息)的地方。
4.  **转换-** 这是我们存储转换的地方,我们需要创建三个转换 **ReadInputFiles.ktr,InjectMetadata.ktr****processeachinputfile . ktr**5.  **Main.kjb -** 我们的 PDI 作业文件,用于执行第 4 点中提到的所有转换。

所以,结构应该如下图所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3c1ea63e2618c45c871f7a5dddfa0d5c.png)

如果你有任何困难理解上述步骤或勺子(桌面应用程序),然后要求你通过下面的链接。

[](https://medium.com/ai-in-plain-english/what-is-the-pdi-client-spoon-in-pentaho-data-integration-kettle-df65b33879ac) [## Pentaho 数据集成(Kettle)中的 PDI 客户端(勺子)是什么?

### 了解勺子- PDI 桌面应用程序的各种功能。拖放 UI 有助于减少…

medium.com](https://medium.com/ai-in-plain-english/what-is-the-pdi-client-spoon-in-pentaho-data-integration-kettle-df65b33879ac) 

# 步骤 2:让我们阅读输入文件

根据这个故事,我们已经阅读了多个文件夹中的多个文件。所以,我们也这样做吧。这个想法是循环遍历每个文件并在每个文件级别执行操作,有意义吗?

1.  我们需要在 Spoon(桌面应用程序)中打开转换 ReadInputFiles.ktr
2.**设计**选项卡中,搜索插件/库‘获取文件名’并将其拖到画布上。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8c866c809603075e66ecfd3095edc6a1.png)

搜索“获取文件名”步骤

现在,双击小部件或右键单击并选择 edit 来添加我们的自定义属性。PDI 给了我们很多配置选项。

*   让我们把步骤名改成‘read _ input _ files’;遵守标准命名约定。
*   我们可以在**文件或目录**选项中浏览或直接粘贴输入文件夹路径(D:\ Work \ automatemuletipleexcel \ Input)。
*   因为我们必须阅读不同供应商的所有文件。我们将使用一个正则表达式。我将详细介绍相同的内容,但这是一种非常强大的文本搜索技术。在我们的**通配符(RegExp)** 字段中,我们将使用正则表达式' **a*。***;这意味着包括所有文本,然后点击**添加**按钮。
*   添加后,我们需要将**包含子文件夹**字段中的布尔值更改为‘Y’。

这个插件会给我们指定目录下的文件夹和文件列表;在我们的例子中**输入**目录。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e53c87b76399b2c35d33e249ec361e1d.png)

获取文件名配置

让我们通过点击**预览行**按钮来快速检查它是否给出期望的输出。您的预览行应该如下所示。如果匹配,那么您可以点击前几行的**关闭**和该步骤的**确定**来保存更改。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/49c17797085d959aba1c0c1ee72a0946.png)

读取输入文件步骤的预览行

正如您可能已经观察到的,我们既可以看到文件,也可以看到文件夹。我们只需要文件进行进一步处理。因此,让我们使用“过滤行”插件进行过滤;再次相同的过程在**设计**选项卡中搜索相同的,双击直接创建跳转。

> PDI 用最好的方式给插件命名,这样就不会有歧义了。

“过滤行”是应用条件逻辑的一个步骤,在我们的例子中,我们只想通过文件而不是文件夹的行。如果您观察我们上一步(获取文件名)的**预览行**输出,PDI 会给我们每行的“类型”列;我们可以用同样的逻辑。

*   我们需要更改名称以匹配我们的命名约定“filter_only_files”
*   我们需要选择“type”列作为第一个变量,然后选择 equals(我们还有许多其他选项),最后在 value 选项中键入硬编码单词“file ”,如下图所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a9d651d1ffd08bed5c3df95a03fd23ce.png)

筛选行步骤配置

现在我们有了一个文件名列表,我们需要将它传递给另一个转换,在那里我们将进一步处理相同的内容。

这里,我们需要使用步骤'复制行到结果'插件/步骤来复制内存中的列表。搜索步骤名称并双击该名称。我们不需要添加任何进一步的配置。

我们现在可以保存并执行**单元测试**这个读取文件模块的转换。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c81053ba42f9ffc75790c08b9bd603bb.png)

我们的阅读文件转换

# 步骤 3:创建模板

我们需要创建一个空白模板,包含我们想要用于数据操作的所有步骤/插件。因此,对于我们的用例,我们只需要两个步骤,一个是 excel 阅读器,另一个是 excel 编写器。我们需要在这里使用**processeeachinputfile . ktr**文件,并执行以下步骤。

我们将使用“Microsoft Excel input”、“Select value”和“Microsoft Excel writer”插件。

*   让我们将这些步骤分别重命名为 input、rename_and_remove 和 output,而不是 Microsoft Excel input、Select value 和 Microsoft Excel writer。
*   在“Microsoft Excel input”插件中,将**电子表格类型(引擎)**字段中的引擎更改为 **Excel 2007 XLSX (Apache POI)** 。在**附加输出字段**选项卡中,在**短文件名字段**中添加**供应商名称**。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f39369f94edce6db9f5c515fa586c26a.png)

*   在“Microsoft Excel writer”插件和**文件&工作表标签**中,添加输出文件的文件路径(D:\ Work \ automatemulelexcel \ Output \ supplier Output File),在**扩展名**字段中将扩展名更改为**xlsx【Excel 2007 及以上】**,如果输出文件存在字段,选择**使用现有文件写入**中的**,选择**写入现有文件****
*   在“Microsoft Excel writer”插件和**内容选项卡**中,选择**中的**在写入行**时将现有单元格下移**,勾选**在工作表末尾开始写入(追加行)**并勾选**省略标题**字段。
*   我们不需要触及“选择值”这一步。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/89bf265b4f2c74b911e2a95d99e06739.png)

带有核心逻辑的空白模板文件

就这样,我们准备好了模板。我们不需要添加任何额外的属性,我们将在运行时注入文件路径、工作表名称、字段名称等属性。

> 请注意,所有的 PDI 插件都不支持元数据注入。你可以在这里查看支持[的插件/步骤。](https://help.pentaho.com/Documentation/7.1/0L0/0Y0/0K0/ETL_Metadata_Injection/Steps_Supporting_MDI)

# 步骤 4:创建元数据

我们需要创建元数据来读写文件。元数据是“描述其他数据的数据”,例如描述我们的 excel 输入和输出的信息。我们将在一个 excel 文件中存储所有可配置的属性(这也可以从数据库中获得)。

我们将在 Metadata 文件夹中创建 Metadata.xlsx 文件,它有两个选项卡,如下所述。

1.  Master -我们将在此存储所有的主信息,如文件格式起始行、工作表名称等。
2.  source file meta——我们将存储每个源文件的所有字段级信息。这些列与 Microsoft Excel 输入步骤中的**字段**选项卡有些匹配。
3.  TargetFileMeta -我们将存储所有需要的输出字段。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/49cb1475790f9b699abc4a7e8d565346.png)

母版页信息

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ef28199f5deb8362c3c885b0776c7085.png)

源文件元工作表信息

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6cb8eb2f8b8d0bb767a0ac6a649ff517.png)

目标文件元工作表信息

> 请注意,PDI 从 0 开始按照行列索引读取文件。因此,我们需要确保元数据信息按照输入文件是正确的。

# 步骤 5:注入元数据

正如在我们的用户故事中提到的,我们将接收多种文件格式,但为了便于工作流维护;我们希望建立一个通用的数据管道来处理所有这样的场景。

在这里,我想介绍一下 PDI **极其强大的功能;ETL 元数据注入**。

元数据注入——顾名思义,将元数据/可配置属性注入到我们的核心逻辑步骤中。本质上,它有助于注入属性,如读取哪些文件(文件名),从哪里读取(开始和结束行/列),做什么(操作),如何保存..如此等等。

我们将使用 InjectMetadata.ktr 文件来注入元信息,如下所示。

*   如果您还记得,我们传递了文件列表,但没有获取它。这里是我们每次获取每个文件信息的地方。因此,我们的第一个插件是“从结果中获取行”。让我们快速地将其重命名,以匹配我们的命名约定“get_file_information”。
*   我们需要添加两个字段,即。从结果中获取行步骤中的文件名和短文件名。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fbce20bd45b65fdcf80d8204914929ac.png)

从结果中获取行将从上一步中获取信息

*   我们需要多个“Microsoft Excel 输入”和“连接行”步骤来读取元数据、主数据和输出数据。其思想是在执行过程中只从元数据 Excel 文件中获取相关信息。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c74e955f87bc970d6090fbbb3e45f1f6.png)

元数据注入器数据管道

*   我们需要在这里连接多跳。请观察跳跃的方向。另外,当从单步连接多跳时会给你下面的警告,请点击**复制**按钮。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/88cafc2edea4c29071068a41d00b2bef.png)

*   在 master_information 步骤中,我们需要在**文件或目录**中浏览 Metadata.xlsx。在**的**页签中,我们需要选择**主**作为我们的**页名****0** 作为我们的**起始行****起始列。****字段**选项卡中,点击**从标题行获取字段..**按钮。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/da89d614a9963fb0730c1dfc0ab13a2b.png)

主信息的字段选项卡

*   在 meta_information 和 select_value excel 步骤中,我们需要再次浏览**文件或目录**中的 Metadata.xlsx。在**工作表**页签中,我们需要选择**源文件元数据**作为我们的**工作表名称**,并选择相同的 **0** 作为我们的**开始行****开始列。****字段**选项卡中,点击**从标题行获取字段..**按钮。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3f60c7a330ff25dc2452cd7f780027e0.png)

元信息和选择值将具有相同的字段

*   在 target_information excel 步骤中,我们需要再次浏览**文件或**目录中的 Metadata.xlsx。在**工作表**页签中,我们需要选择 **TargetFileMeta** 作为我们的**工作表名称**和相同的 **0** 作为我们的**开始行**和**开始列。**在**字段**选项卡中,点击**从标题行获取字段..**按钮。
*   我们将在所有步骤中使用**Excel 2007 XLSX(Apache POI)**作为我们的引擎。
*   在 **join_meta** 、 **join_select_values** 和 **join_master、**中,我们将添加以下条件。这是为了过滤 Metadata.xlsx 文件中的行。我们使用了 **short_filename** 作为我们的唯一标识符(在现实世界中我们不会得到这样的额外津贴)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/07740f878dd1d17335731193b6b1a82c.png)

join_meta 和 join_master 联接行步骤条件

*   现在让我们搜索并拖动“ETL 元数据注入”插件到画布上。我们需要浏览我们的模板文件(D:\ Work \ automatemuletipleexcel \ Transformation \ processeeachinputfile . ktr)。
*   它将自动读取我们的模板转换并列出所有可配置的属性。现在,我们只需要用属性映射各自的元数据字段。下面是映射。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0f17e585502833f3f0543d3b94ad774e.png)

输入步骤映射

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7813aa3c2333f0c27b6bfdcd7a3a00e2.png)

移除并重命名步骤映射

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e8a0279cac579063fc5b417498bfbdbd.png)

输出步骤映射

这应该是注射器改造。让我们巩固和执行相同的。

# 第六步:连接圆点,创建主循环

最后,我们到了连接各个部分和执行主要工作的最后一步。如上所示,我们将使用一个作业文件(Main.kjb)来做同样的事情。

作业应该总是以名为“开始”的步骤/插件开始,以“成功”步骤结束。让我们用两个“转换”步骤来拖动这些步骤;一个用于 ReadInputFiles.ktr,另一个用于 InjectMetadata.ktr(因为我们已经在 injector 步骤中使用了 ProcessEachInputFile.ktr)。哦是的!我现在可以联系关系了。

*   在第一个转换中,浏览我们的 ReadInputFiles(D:\ Work \ AutomateMultipleExcel \ Transformation \ ReadInputFiles . ktr)转换。
*   在第二个转换中,浏览我们的 inject metadata(D:\ Work \ automatemuletipleexcel \ Transformation \ inject metadata . ktr)转换,并检查**执行每个输入行。**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5b0fd2931bdf0b1e50aee21f1bb503cf.png)

选中执行每个输入行以循环列表

执行每个输入行将为每个文件创建我们的主循环,注入元数据并进行相同的处理。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b02cb195379869c58ad7e55358ba74f3.png)

我们的主要工作是读取和执行文件

让我们开始行动,执行我们的数据管道。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/25cc8e967a06c5d6b361ac31774cad6a.png)

成功

我们现在可以在输出目录中检查我们的文件。让我们使用测试用例来执行测试。

我们现在可以根据我们的要求分析数据。

**结论**

自动化多个 excel 电子表格可能是一项有趣的活动。上述实现并不完美,但将解决我们的问题陈述。我们可以通过添加变量而不是硬编码的值来进一步推广这个管道。我们可以按照我们的要求类似地构建/定制这个管道,接下来我们将从电子邮件用例中下载数据。

# 下一篇文章再见。快乐的 ETL

如果你喜欢类似的内容,那么我会推荐你使用下面的链接订阅。

[](https://wryteex.com/) [## WryteEx -开发、数据工程、项目管理等

### 我写的博客涉及数据工程、金融、Python、Python Django、项目管理、Web 开发等等

wryteex.com](https://wryteex.com/)

# 如何自动发送电子邮件任务-发送媒体故事到您的列表

> 原文:<https://towardsdatascience.com/how-to-automate-sending-email-task-send-medium-story-to-your-list-2424e68c04ca?source=collection_archive---------43----------------------->

## 使用 PDI,我们可以创建一个发送电子邮件的数据管道。

我读了很多作者的博客,他们都是关于创建一个邮件列表来成功地为你的故事创造一个读者群的。到目前为止,我还没有邮件列表,想有一个。我喜欢向多个接收者发送故事的想法,这可以成为我们数据管道系列的一个很好的用例。

我们将在这个故事中回答“如何”这个问题。现在,有多种方式来做这项活动;您将在下面看到的(使用 [PDI](https://medium.com/ai-in-plain-english/pentaho-data-integration-installation-guide-easy-yet-powerful-etl-tool-80930cff46c6) )不一定是市场上最好的方法。我们可以构建类似的用例,例如发送日志文件、发送通知、发送状态报告等等。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/887d8154b15878d6badeb9c63ded368c.png)

[安德鲁·尼尔](https://unsplash.com/@andrewtneel?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍照

如果你是第一次来 PDI,那么建议你看看下面的故事。

[](https://medium.com/ai-in-plain-english/getting-started-with-pentaho-data-integration-kettle-and-its-components-ef1e71101323) [## Pentaho 数据集成(Kettle)及其组件入门。

### 了解勺子、平底锅、厨房等关键部件将使我们对 PDI 工具有更好的了解

medium.com](https://medium.com/ai-in-plain-english/getting-started-with-pentaho-data-integration-kettle-and-its-components-ef1e71101323) 

# 用户故事——让我们定义我们的用例

这是一个非常简单的用例,下面是我们的故事。

1.  我想阅读多个带有最新博客和电子邮件列表的 CSV 文件。
2.  我想合并这些 CSV 文件并创建一个单独的数据框。
3.  我想给每个收件人分别发邮件。我想将变量传递给子作业。

最简单的用例

# 输入数据

执行此活动需要两种类型的数据。一个是我们的邮件列表主。第二,我们要求的是我们最近的博文[的网址](/how-to-automate-excels-received-on-email-increase-your-productivity-3d2f50ddc958);我们想发送到电子邮件列表。同样,我们可以使用 RSS 提要服务获取这些信息。我会为此写一个单独的博客。

用下面提到的数据创建两个 CSV“EmailList”和“LatestPost”。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/18b0f0138765cd58b670225fb4b7e9d5.png)

样本 CSV 和我们的邮件列表

> 请注意,这些都是顶级板球运动员,我用了假的电子邮件地址。这些人不在我的邮件列表中。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f191f5dfc5beff6790ac94f101cfd2ec.png)

最新博客文章的链接和标题

# 测试案例

我更喜欢在构建数据管道之前定义我的测试用例。我强烈建议你也这样做。

*   测试向自己发送电子邮件
*   再次交叉验证内容和收件人详细信息

# 步骤 1:项目设置

像我以前所有的故事一样。我首先设置了项目文件夹,以匹配正确的命名约定。这有助于标准化过程,并最小化其他开发人员的学习曲线。

这里,我们需要输入、输出、转换文件夹。我们将为各种活动创建多个转换。

我们需要下面提到的结构。正如我所提到的,我更喜欢将所有与工作相关的东西存储在一个位置'**Work '**;帮助维护备份。(D:\Work\SendEmail)。

1.  **输入-** 这是我们下载报表的地方。
2.  **输出** -存储我们的输出文件
3.  这是我们将配置和集成多个转换的地方,用于遍历我们的邮件列表。
4.  在转换文件夹中,我们将创建这些文件。请注意,ReadFiles 是一个转换文件,SendEmail 是一个作业文件。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f676a1cc0b472e408af54ed8cef670d0.png)

项目文件夹结构

# 第 2 步读取文件

我们需要在一个转换中读取两个工作表。这个想法是阅读整个邮件列表,遍历每个成员,并发送一封带有自定义消息的电子邮件。

打开勺子上的 transformation ReadFile.ktr(桌面应用)。我们需要在这个转换中读取输入文件。

我们需要执行下面提到的步骤。

1.  通过右键单击“新建注释”,为转换添加描述。文档在任何编程语言中都是非常重要的。
2.  将两个“文本文件输入”,一个“连接行(笛卡尔乘积)”和“将行复制到结果”插件从转换设计选项卡拖到画布上。
3.  分别重命名相同的“read_email_list”(文本输入 1)、“read_latest_post”(文本输入 1)、“merge”和“copy_result”。
4.  在 read_email_list 步骤中,在**文件或目录**字段和**文件**选项卡中浏览文件(D:\ Work \ send email \ Input \ email list . CSV),在**内容**选项卡中,将**分隔符**字段改为逗号而不是半逗号,在字段选项卡中只需点击**获取字段**按钮。
5.  同样,在 read_latest_post 步骤中,在**文件或目录**字段和**文件**选项卡中浏览文件(D:\ Work \ send email \ Input \ latest post . CSV),在**内容**选项卡中,将**分隔符**字段改为逗号而不是半逗号,在字段选项卡中只需点击**获取字段**按钮。
6.  就是这样,join rows 步骤将在不改变任何参数的情况下发挥它的魔力。这里,我想展示使用 join rows step 无缝合并两个文件的能力。如果需要,我们也可以提供条件。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b6f0cff726657a1dc5ee307edb065373.png)

ReadFile 转换结构

我们可以通过运行转换和预览输出来测试这个单元。

# 步骤 3 传递变量

我们需要将变量传递给我们的子作业,以便逐个发送电子邮件。这将要求我们在配置 SendEmail 子作业文件之前设置父主作业文件。

在 PDI,传递变量是一个简单的过程。如果我们以“将行复制到结果”结束转换,那么在接下来的转换中,我们所有的变量都是可访问的。然而,我们将在作业级别以不同的方式传递变量。

我们需要执行下面的步骤来传递变量。

1.  在 Main.kjb 文件中,我们需要拖动'开始','转换','作业'和'成功'步骤。
2.  根据我们的命名惯例,将这些步骤重命名为“开始”、“读取文件”、“发送电子邮件”和“成功”。
3.  我们需要分别在 read_files 和 send_email 步骤中浏览我们的转换文件。
4.  在 send_email 作业步骤中,我们需要检查**选项**选项卡中的**执行每个输入行**字段。
5.  在**参数**选项卡中,我们需要添加四个参数,即。名字、电子邮件地址、头衔和博客帖子。现在,所有这些名称都应该与我们的输入文件字段相匹配。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f155327a380e151496bb4a579ecf539c.png)

点击执行每一个输入行来循环列表

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7a39b94d16fc32cd45c47043b5714e0e.png)

我们希望在子作业发送电子邮件中传递的参数/变量。

现在,我们需要获取子/子作业中的值。下面是步骤。

打开 SendEmail.kjb 文件,双击画布。Spoon 将打开作业属性窗口。我们还需要在**参数**选项卡中添加相同的字段。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9480ed508ee8aaaf88cde4c1488583a2.png)

作业属性的参数选项卡

# 发送电子邮件

我们现在可以设置和发送自定义电子邮件到我们的邮件列表。我们需要[开放认证(OAuth)](https://docs.servicenow.com/bundle/orlando-servicenow-platform/page/administer/notification/concept/c_OAuthEmailAuthentication.html) 来发送电子邮件。要在您的 Gmail 帐户上设置 OAuth,请参考下面的故事- **步骤 2**;我不会在这篇文章中重复整个过程。

[](/how-to-automate-excels-received-on-email-increase-your-productivity-3d2f50ddc958) [## 如何自动接收电子邮件中的 Excel 文件-提高您的工作效率

### 从电子邮件下载文件并按照我们的要求进行处理的逐步指南

towardsdatascience.com](/how-to-automate-excels-received-on-email-increase-your-productivity-3d2f50ddc958) 

让我们快速设置我们的 SendEmail 作业。

1.  添加作业文件的描述。在这里,我们将使用该作业文件发送电子邮件。
2.  从“设计”标签的插件列表中拖动“开始”、“邮件”和“成功”。
3.  根据我们的命名惯例,分别为 start、email 和 success 进行重命名。
4.  在电子邮件步骤中,我们需要配置下面提到的属性。

*   在**目的地址**字段中,我们需要使用变量${EmailAddress},它是从我们之前的转换和父作业中传递过来的。
*   在**发件人姓名和地址**字段,我们需要提供发件人的姓名和电子邮件地址;即我们的信息。
*   在**服务器**选项卡中,我们需要提供 OAuth 信息进行认证。这是一个外发服务器,我们需要 [SMTP 细节](https://www.siteground.com/kb/google_free_smtp_server/)而不是 IMAP。
*   在**电子邮件消息**选项卡中,我们需要选中“在邮件正文中使用 HTML 格式”,在消息部分,我们的主题字段将是${Title},并为邮件正文编写您的自定义消息。下面我用过。

```
Hi ${FirstName},I have published a new blog on Medium. Here's link. ${BlogPost}I hope you like it. Please feel free to provide your suggestions. Thanks,
Shravankumar Suvarna
```

> 看,我们如何在多个领域使用变量。PDI 不支持在所有字段中使用变量。关键是在田地旁边寻找一个蓝色的小美元标志。如果它存在,那么它接受或者不接受。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b514ef60693eead8f3b5e5fee63ad352.png)

发送电子邮件作业流程

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e0f6312d36ca9a3f908c4c904d027cd6.png)

在目的地址中使用变量

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1eebcda45ec431c959060baa8fcd3575.png)

要验证的 OAuth 详细信息。请注意,medium.blog@gmail.com 是一个虚拟的电子邮件地址。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/caa98d33248d18db7449895a126dec7f.png)

电子邮件选项卡—检查字段旁边的小美元符号

就这样,我们应该可以使用我们的自动化管道了。我们现在可以运行我们的主作业文件,并使用我们的测试用例对其进行测试。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9aa2506a00f3aedb5de32d2fdf5e638a.png)

成功

**结论**

这是最简单的数据管道。这里,我们的想法不是使用这种方法将博客发送到邮件列表,而是根据我们的方便使用这个案例研究。我们可以构建类似的管道来发送日志文件、状态报告等。因为我们的大部分管道将在服务器上运行。这将是一个很好的功能,包括来自作业/转换管道的实时状态报告。

如果你喜欢类似的内容,那么我会推荐你使用下面的链接订阅。

[](https://wryteex.com/) [## WryteEx -开发、数据工程、项目管理等

### 我写的博客涉及数据工程、金融、Python、Python Django、项目管理、Web 开发等等

wryteex.com](https://wryteex.com/) 

欢迎在评论区提问。

# 下一篇文章再见。快乐的 ETL

# 如何避免熊猫大混乱

> 原文:<https://towardsdatascience.com/how-to-avoid-a-pandas-pandemonium-e1bed456530?source=collection_archive---------18----------------------->

## [入门](https://towardsdatascience.com/tagged/getting-started)

## 深入探究熊猫的常见错误。第一部分:编写好的代码并发现无声的失败。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b4cf414a768ca378da4e65ce3c57c9e4.png)

由[凯文·Ku](https://unsplash.com/@ikukevk?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄

当你第一次开始使用熊猫的时候,最好是先把脚弄湿,然后在出现问题的时候处理。然后,几年过去了,你已经能够用它构建的惊人的东西开始积累,但是你有一个模糊的暗示,你一直在犯同样的错误,对于看起来很简单的操作,你的代码运行得非常慢。这是时候深入了解熊猫的内部工作原理,让你的代码更上一层楼了。与任何库一样,优化代码的最佳方式是理解语法下面发生了什么。

首先,在第一部分**中,我们将吃我们的蔬菜,并涵盖编写干净的代码和发现常见的无声故障。然后在 [**第二部分**](https://medium.com/@protagonistwu/how-to-avoid-a-pandas-pandemonium-part-ii-3426f53d7fba) 中,我们将开始加速你的运行时间并降低你的内存占用。**

我还做了一个 [Jupyter 笔记本,上面有整个课程](https://github.com/pambot/notebooks/blob/master/pandas-pandemonium.ipynb),包括两部分。

首先,让我们制造一些假数据来玩。我将制作一个大的数据框来说明更大的处理问题,并制作一个小的数据框来说明局部的点变化。

```
*# for neatness, it helps to keep all of your imports up top*
**import** **sys**
**import** **traceback**
**import** **numba**
**import** **numpy** **as** **np**
**import** **pandas** **as** **pd**
**import** **numpy.random** **as** **nr**
**import** **matplotlib.pyplot** **as** **plt**

% matplotlib inline*# generate some fake data to play with*
data = {
    "day_of_week": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] * 1000,
    "booleans": [**True**, **False**] * 3500,
    "positive_ints": nr.randint(0, 100, size=7000),
    "mixed_ints": nr.randint(-100, 100, size=7000),
    "lat1": nr.randn(7000) * 30,
    "lon1": nr.randn(7000) * 30,
    "lat2": nr.randn(7000) * 30,
    "lon2": nr.randn(7000) * 30,
}

df_large = pd.DataFrame(data)df_large.head()
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9d7ee7e5c3ef8ddcf6335614b966f1ac.png)

```
small = {
    'a': [1, 1],
    'b': [2, 2]
}df_small = pd.DataFrame(small)df_small
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2fabd0cb36157ecc7c6e57f179ef87e4.png)

太好了,现在我们都准备好了!

# 编写优秀的代码

在我们做“酷”的事情之前,比如编写更快、更优化内存的代码,我们需要在一些看起来相当平凡的编码最佳实践的基础上做这件事。这些都是小事情,比如有表达性地命名事物和编写健全性检查,这将有助于保持代码的可维护性和可读性。

## 健全检查很简单,完全值得

仅仅因为这大部分只是数据分析,并且为它建立一整套单元测试可能没有意义,并不意味着你根本不能做任何种类的检查。在你的笔记本代码中加入`assert`不需要太多额外的工作就可以走很长的路。

上面,我们制作了一个数据帧`df_large`,其中包含一些带有预定义规则的数字。例如,您可以通过修剪空白并检查条目数量是否保持不变来检查数据输入错误:

```
large_copy = df_large.copy()**assert** large_copy["day_of_week"].str.strip().unique().size == large_copy["day_of_week"].unique().size
```

如果运行这段代码,应该不会发生任何事情。但是,稍微修改一下,打破它,然后…

```
large_copy.loc[0, "day_of_week"] = "Monday "**assert** large_copy["day_of_week"].str.strip().unique().size == large_copy["day_of_week"].unique().size
```

**嘭!AssertionError。**假设您有一些丢弃重复项并将增量发送给客户端的代码。添加的少量空白会被遗漏,并作为它自己唯一的数据点发送出去。当是一周中的某几天时,这没什么大不了的,您可以很容易地对其进行抽查,但是如果是潜在的成千上万或更多的唯一字符串,这种检查可以让您省去一个大麻烦。

## 使用一致的索引

Pandas 在索引方面给了你很大的灵活性,但是如果你没有保持一致的风格,它会给你带来很多困惑。这是一个提议的标准:

```
*# for getting columns, use a string or a list of strings for* multiple columns
*# note: a one-column DataFrame and a Series are not the same thing*
one_column_series = df_large["mixed_ints"]
two_column_df = df_large[["mixed_ints", "positive_ints"]]*# for getting a 2D slice of data, use `loc`*
data_view_series = df_large.loc[:10, "positive_ints"]
data_view_df = df_large.loc[:10, ["mixed_ints", "positive_ints"]]*# for getting a subset of rows, also use `loc`*
row_subset_df = df_large.loc[:10, :]
```

这只是结合了我个人用的和我见过别人做的。这里有另一组方法来做与上面完全相同的事情,但是你可能会明白为什么它们要么没有被广泛采用,要么不被鼓励使用。

```
*# one way is to use `df.loc` for everything, but it can look clunky*
one_column_series = df_large.loc[:, "mixed_ints"]
two_column_df = df_large.loc[:, ["mixed_ints", "positive_ints"]]*# you can use `iloc`, which is `loc` but with indexes, but it's not as clear
# also, you're in trouble if you ever change the column order*
data_view_series = df_large.iloc[:10, 2]
data_view_df = df_large.iloc[:10, [3, 2]]*# you can get rows like you slice a list, but this can be confusing*
row_subset_df = df_large[:10]
```

这里有一个关于最后一个例子的小问题:`df_large[:10]`得到前 10 行,但是`df_large[10]`得到第 10 列。这就是为什么尽可能清晰地对事物进行索引是如此重要,即使这意味着你必须做更多的打字工作。

## 但是不要使用链式索引

什么是链式索引?当你分别索引列和行时,会对`__getitem__()`进行两次单独的调用(或者更糟,如果你正在赋值,一次调用`__getitem__()`,一次调用`__setitem__()`,我们将在下面演示)。如果您只是索引而不是赋值,这还不错,但是从可读性的角度来看,这仍然不理想,因为如果您在一个地方索引行,然后索引一列,除非您对变量命名非常严格,否则很容易丢失索引的确切内容。

```
*# this is what chained indexing looks like*
data_view_series = df_large[:10]["mixed_ints"]
data_view_df = df_large[:10][["mixed_ints", "positive_ints"]]*# this is also chained indexing, but low-key*
row_subset_df = df_large[:10]
data_view_df = row_subset_df[["mixed_ints", "positive_ints"]]
```

第二个例子不是人们通常想要做的,它经常发生在人们在嵌套的`for`循环中修改数据帧的时候,首先你遍历每一行,然后你想对一些列做一些事情。如果你得到了一个`SettingWithCopyWarning`,试着寻找这些类型的模式或者任何你可能分别切片行然后切片列(或者反过来)的模式,并用`df.loc[rows, columns]`替换它们。

# 常见的无声故障

即使你做了以上所有的事情,有时熊猫的灵活性会诱使你犯错误,而这些错误实际上并不会使你犯错。这些是特别有害的,因为你常常意识不到有问题,直到下游的事情没有意义,并且很难追溯到原因是什么。

## 查看与复制

数据框的视图和副本在其包含的值方面可能与您完全相同,但视图引用的是现有数据框的一部分,而副本则是完全不同的数据框。如果更改视图,则更改现有数据框架,但如果更改副本,则原始数据框架不受影响。当您认为正在修改副本时,请确保没有修改视图,反之亦然。

事实证明,你是在处理一个副本,还是一个观点是很难预测的!从内部来说,panases 会返回一个视图或一个副本,来尝试进行优化,具体取决于数据帧和您采取的操作。您可以使用`df.copy()`强制熊猫为您制作一份拷贝,也可以通过设置`inplace=True`强制熊猫在数据帧可用时就地操作。

何时进行复制,何时使用视图?这很难确定,但是如果您的数据很小,或者您的资源很大,并且您希望实现功能化和无状态化,您可以尝试为每个操作创建一个副本,就像 Spark 所做的那样,因为这可能是最安全的方法。另一方面,如果您有大量数据,并且有一台普通的笔记本电脑,您可能希望在适当的位置进行操作,以防止笔记本电脑崩溃。

```
*# intentionally making a copy will always make a copy*
small_copy = df_small.copy()small_copy
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/39ea68dffdd34b20a57172df30c2409f.png)

虽然它们看起来完全相同,但这实际上是一个完全独立的数据对象,不同于我们之前制作的`df_small`。

我们来看看`inplace=True`是做什么的。`df.drop()`是一个允许您从数据框架中删除列的方法,也是一个熊猫数据框架方法,它允许您指定是希望就地执行操作,还是希望操作返回新对象。返回一个新的对象,或者`inplace=False`始终是缺省值。

```
small_copy.drop("b", axis=1)small_copy
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/39ea68dffdd34b20a57172df30c2409f.png)

跌落发生了什么?它返回一个新对象,但您没有用变量指向它,所以它消失了。原文`small_copy`保持不变。现在让我们打开就地修改:

```
small_copy.drop("b", axis=1, inplace=True)small_copy
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9b2c20d2acf15c4efbd0d6e382b20e0a.png)

原来的`small_copy`,现在已经变了。好在我们做了一份拷贝!

让我们重新制作`small_copy`并做点修改,看看我之前所说的原始数据框架是一个不同的对象是什么意思。

```
*# let's see what happens if you assign to a copy*
small_copy = df_small.copy()*# you should always use `loc` for assignment*
small_copy.loc[0, 'b'] = 4small_copy
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4345716e7650717c697fafb2bda55f25.png)

```
*# original is unchanged*
df_small
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/39ea68dffdd34b20a57172df30c2409f.png)

## 注意无序处理

在 Jupyter 笔记本中,无序地更改和重新处理单元几乎是不可避免的——我们知道不该这样做,但最终总是会发生。这是 view vs. copy 问题的一个子集,因为如果知道要进行的更改从根本上改变了列的属性,就应该消耗内存成本并创建一个新的副本,否则可能会发生类似的情况,在此块中反复运行后两个单元格,看到最大值变得非常不稳定。

```
large_copy = df_large.copy()
large_copy.loc[0, "positive_ints"] = 120
large_copy["positive_ints"].max()> 120
```

记住,`positive_ints`被设置在 0 到 100 之间,这意味着将第一个值设置为 120 意味着现在最大值必须是 120。但是如果我运行几次这样的细胞会怎么样呢?

```
large_copy["positive_ints"] = large_copy["positive_ints"] * 3
large_copy["positive_ints"].max()> 360
```

第一次运行它时,它的行为与预期的一样,但是再次运行它…

```
large_copy["positive_ints"] = large_copy["positive_ints"] * 3
large_copy["positive_ints"].max()> 1080
```

这个例子看似显而易见,但让细胞不可逆地改变数据,并在每次重新运行时自动构建,这真的很容易。避免这个问题的最好方法是,当您开始一个将产生显著的就地数据突变的单元时,用新的变量名创建一个新的数据框架。

```
large_copy_x3 = large_copy.copy()
large_copy_x3["positive_ints"] = large_copy["positive_ints"] * 3
large_copy_x3["positive_ints"].max()> 360
```

无论你运行那个块多少次,它总会返回 360,就像你最初预期的那样。

## 切勿将错误设置为“忽略”

默认情况下,一些 Pandas 方法允许您忽略错误。这几乎总是一个坏主意,因为忽略错误意味着它只是将未解析的输入放在输出应该在的地方。让我们用两个正常的日期和一个未来的日期制作一个系列。

```
parsed_dates = pd.to_datetime(["10/11/2018", "01/30/1996", "04/15/9086"], format="%m/%d/%Y", errors="ignore")parsed_dates> array(['10/11/2018', '01/30/1996', '04/15/9086'], dtype=object)
```

请注意,在示例输出中,如果您不太熟悉 Pandas 输出应该是什么,那么看到`array`类型的输出对您来说可能并不奇怪,您可能只是继续您的分析,而不知道有什么地方出错了。

如果你关闭`errors="ignore"`,你会看到回溯:

```
Traceback (most recent call last):
  File "<ipython-input-22-12145c38fd6e>", line 3, in <module>
    pd.to_datetime(["10/11/2018", "01/30/1996", "04/15/9086"], format="%m/%d/%Y")
pandas._libs.tslibs.np_datetime.OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 9086-04-15 00:00:00
```

这里发生的事情是,Python 时间戳以纳秒为单位进行索引,该数字存储为一个`int64`,因此任何晚于大约 2262 年的年份都将超出其存储能力。作为一名数据科学家,你可能会被原谅不知道这一点点的秘密,但这只是隐藏在 Python/Pandas 中的许多隐藏的特质之一,所以忽略它会给你带来危险。

如果你想知道,这就是约会系列应该有的样子:

```
pd.to_datetime(["10/11/2018", "01/30/1996"], format="%m/%d/%Y")> DatetimeIndex(['2018-10-11', '1996-01-30'], dtype='datetime64[ns]', freq=None)
```

## `object` dtype 可以隐藏混合类型[](http://localhost:8888/notebooks/pandas-pandemonium.ipynb#The-object-dtype-can-hide-mixed-types)

每个熊猫列都有一个类型,但是有一个叫做`object`的超级类型,这意味着每个值实际上只是一个指向某个任意对象的指针。这使得熊猫有很大的灵活性(即列表或字典或任何你想要的东西的列!),但这可能会导致静默失败。

**剧透预警:**这不会是`object`型第一次给我们带来问题。我不想说你不应该使用它,但是一旦你进入生产模式,你绝对应该谨慎使用它。

```
*# we start out with integer types for our small data*
small_copy = df_small.copy()
small_copy.dtypes> 
a    int64
b    int64
dtype: object*# reset ones of the column's dtype to `object`*
small_copy["b"] = small_copy["b"].astype("object")
small_copy.dtypes>
a    int64
b    object
dtype: object
```

现在让我们再做一些恶作剧,用可能是最令人沮丧的无声失败之一来改变`b`专栏。

```
small_copy["b"] = [4, "4"]
small_copy
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/69d74abf2e4bde4bb8c3301233ce39be.png)

(我相信对你们中的许多人来说,这是黑板上的钉子的数据等价物。)

现在,假设您需要删除重复项并发送结果。如果您按列`a`放置,您将得到预期的结果:

```
small_copy.drop_duplicates("a")
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d95a55704263beb64af433ca936d800f.png)

但是,如果您按列`b`放置,您将得到以下结果:

```
small_copy.drop_duplicates("b")
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/69d74abf2e4bde4bb8c3301233ce39be.png)

## 谨慎对待熊猫模式推理

当你加载一个大的混合型 CSV 时,Pandas 给你设置`low_memory=False`的选项,当它遇到一些它不知道如何处理的数据时,它实际上正在做的只是使整个列`object`类型化,以便它可以转换为`int64`或`float64`的数字得到转换,但它不能转换的东西只是作为`str`放在那里。这使得列值暂时能够和平共存。但是一旦你尝试对它们做任何操作,你会发现 Pandas 一直试图告诉你,你不能假设所有的值都是数字。

**注意:**记住,在 Python 中,`NaN`是一个`float`!因此,如果您的数字列有它们,即使它们实际上是`int`,也将其转换为`float`。

让我们创建一个故意迟钝的数据帧,并把它保存在某个地方,以便我们可以读回它。这个数据帧有一个整数和一个字符串的组合,作者(很可能是人,可能在 Excel 中工作)认为这是一个 NaN 值的指示,但实际上缺省的 NaN 解析器并不包含它。

```
mixed_df = pd.DataFrame({"mixed": [100] * 100 + ["-"] + [100] * 100, "ints": [100] * 201})mixed_df.to_csv("test_load.csv", header=True, index=False)
```

当您读回它时,Pandas 将尝试进行模式推理,但它会在混合类型列上出错,并且不会试图对此过于固执己见,而是将值保留在`object`列中。

```
mixed_df = pd.read_csv("test_load.csv", header=0)
mixed_df.dtypes>
mixed    object
ints     int64
dtype: object
```

确保正确解释数据的最佳方法是手动设置 dtypes 并指定 NaN 字符。这是一件痛苦的事情,而且您并不总是必须这样做,但是打开您拥有的任何数据文件的前几行并确保它真的可以被自动解析总是一个好主意。

```
mixed_df = pd.read_csv("test_load.csv", header=0, dtype={"mixed": float, "ints": int}, na_values=["-"])
mixed_df.dtypes>
mixed    float64
ints     int64
dtype: object
```

# 结论,第一部分

熊猫可能是自切片列表以来最伟大的东西,但它是自动魔法,直到它不是。要了解何时以及如何让它掌控方向盘,何时必须手动超越,你要么需要对它的内部工作原理有一个扎实的了解,要么你可以像我一样,用头撞它们五年,并尝试从你的错误中吸取教训。俗话说,骗我一次,不要脸。愚弄我 725 次…不能再愚弄我了。

请查看[第二部分:加速和内存优化](https://medium.com/@protagonistwu/how-to-avoid-a-pandas-pandemonium-part-ii-3426f53d7fba)。

# 如何避免熊猫大混乱,第二部分

> 原文:<https://towardsdatascience.com/how-to-avoid-a-pandas-pandemonium-part-ii-3426f53d7fba?source=collection_archive---------43----------------------->

## 深入探究熊猫的常见错误。第二部分:加速和内存优化

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/722bc7b256ec58ac7dc3ce99c44bdd5e.png)

照片由 [Alex wong](https://unsplash.com/@killerfvith?utm_source=medium&utm_medium=referral) 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄

在 [**第一部分**](https://medium.com/@protagonistwu/how-to-avoid-a-pandas-pandemonium-e1bed456530) 中,我们回顾了如何编写干净的代码并找出常见的无声故障。在**第二部分**中,我们致力于加速你的运行时间并降低你的内存占用。

我还做了一个 [Jupyter 笔记本,上面有整个课程](https://github.com/pambot/notebooks/blob/master/pandas-pandemonium.ipynb),包括两部分。

这是前一部分的一些代码设置,但是我把它放在这里是为了让这一部分能够独立存在。

```
*# for neatness, it helps to keep all of your imports up top*
**import** **sys**
**import** **traceback**
**import** **numba**
**import** **numpy** **as** **np**
**import** **pandas** **as** **pd**
**import** **numpy.random** **as** **nr**
**import** **matplotlib.pyplot** **as** **plt**

% matplotlib inline*# generate some fake data to play with*
data = {
    "day_of_week": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] * 1000,
    "booleans": [**True**, **False**] * 3500,
    "positive_ints": nr.randint(0, 100, size=7000),
    "mixed_ints": nr.randint(-100, 100, size=7000),
    "lat1": nr.randn(7000) * 30,
    "lon1": nr.randn(7000) * 30,
    "lat2": nr.randn(7000) * 30,
    "lon2": nr.randn(7000) * 30,
}

df_large = pd.DataFrame(data)*# let's copy this pro-actively, copy vs. view is in part i*
large_copy = df_large.copy()df_large.head()
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9d7ee7e5c3ef8ddcf6335614b966f1ac.png)

# 启动你的熊猫

既然您已经有了很好的编码习惯,是时候尝试提升性能了。从矢量化到实时编译,您可以使用一系列方法来加快代码运行速度。为了测量瓶颈和量化性能增益,让我们介绍一下`timeit`,一个漂亮的 Jupyter 性能测量笔记本工具。你需要知道的是,将`%timeit`放在一行代码之前将测量该行代码的运行时间,而将`%%timeit`放在一个代码块中将测量整个代码块的运行时间。

对于这个例子,我选择了哈弗辛函数,因为它是一个很好的例子,这个函数看起来有点复杂,但实际上很容易优化。我在 [StackOverflow](https://stackoverflow.com/questions/4913349/haversine-formula-in-python-bearing-and-distance-between-two-gps-points) 上找到了这个示例函数。

```
**def** haversine(lat1, lon1, lat2, lon2):
    """Haversine calculates the distance between two points on a sphere."""
    lat1, lon1, lat2, lon2 = map(np.deg2rad, [lat1, lon1, lat2, lon2])
    dlat = lat2 - lat1
    dlon = lon2 - lon1
    a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
    c = 2 * np.arcsin(np.sqrt(a)) 
    **return** c %timeit haversine(100, -100, 50, -50)> 14.3 µs ± 308 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
```

## 遍历行的三种不同方式

您可能已经知道 Pandas 是在 Numpy 的基础上构建的,以利用仅由底层 C 代码提供的优化,同时保持其可访问的 Python 接口。然而,就像任何脚踏两个世界的事物一样,你需要知道边界在哪里,以充分利用它的双重性。根据迭代数据帧的方式,您可以充分利用或完全忽略这些优化。

如果您对 Pandas 完全陌生,并且只是将 DataFrames 视为嵌套 Python 列表的包装器,那么您的第一反应可能是一次遍历一行,比如使用`df.iterrows()`。

```
%%timeit# `iterrows` is a generator that yields indices and rows
dists = []
for i, r in large_copy.iterrows():
    dists.append(haversine(r["lat1"], r["lon1"], r["lat2"], r["lon2"]))large_copy["spherical_dist"] = dists> 736 ms ± 29.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
```

每个循环 740 毫秒是 3/4 秒,真的可以累加。100,000 行将花费您 20 个小时。

使用`df.apply()`方法有一个稍微优化的方法,它对 DataFrame 和 Series 对象都有效。您定义一个自定义函数并发送它,在某些情况下,它会尝试推断更快的方法来更快地处理 DataFrame 列。

```
large_copy["spherical_dist"] = large_copy.apply(
    lambda r: haversine(r["lat1"], r["lon1"], r["lat2"], r["lon2"]), axis=1
)> 387 ms ± 31.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
```

这是一种进步,但并不惊人。您需要做的是使用矢量化,简单地说,就是向 Numpy 兼容函数中输入一系列值,这些值通常一次取一个值,这样 C 代码就可以自由地在内部分割向量并进行并行处理。Numpy 函数通常可以接受单个值、一个向量或一个矩阵。如果内部处理可以在每一步都作用于单个值或值的向量,则可以使用现成的矢量化。

```
%timeit large_copy["spherical_dist"] = haversine(\
    large_copy["lat1"], \
    large_copy["lon1"], \
    large_copy["lat2"], \
    large_copy["lon2"] \
)> 2.17 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
```

这大约是 100 倍的速度提升——20 小时缩短到大约 4 分钟。请注意,我没有以任何方式更改原始函数。如果你去看代码,你可以自己追踪这些值是如何既可以是单个值也可以是一个序列的。

## 迭代的一些经验法则

与索引一样,Pandas 可以灵活地处理每行的值。以下是一些经验法则:

*   如果要对列的每个值应用相同的变换,应该使用矢量化。
*   如果需要条件矢量化,请使用布尔索引。
*   也适用于字符串!即`Series.str.replace("remove_word", "")`
*   你应该只对不能广播的特定功能使用`apply`。即`pd.to_datetime()`

## 用 Numba 进行实时编译

不能矢量化怎么办?这是否意味着你被`df.apply()`困住了?不一定——如果您的代码可以表示为纯 Python 和 Numpy 数组的组合,您应该尝试 Numba,看看您的代码是否可以为您加速。编写 Numba 与编写 Cython 完全不同,如果你只懂 Python,那么编写 cy thon 就很像编写一种全新的编程语言。同样,只要你的代码可以用纯 Python 和 Numpy 来表达,这实际上就是在现有函数的基础上添加一些装饰器。

这个例子基于一些函数,这些函数计算一个给定的复数是否是 Mandlebrot 集合的一部分,并通过尝试每个像素坐标来可视化产生的分形。取自 [Numba docs](http://numba.pydata.org/numba-doc/0.15.1/examples.html) 。

```
**def** mandel(x, y, max_iters):
    """
    Given the real and imaginary parts of a complex number,
    determine if it is a candidate for membership in the Mandelbrot
    set given a fixed number of iterations.
    """
    i = 0
    c = complex(x,y)
    z = 0.0j
    for i in range(max_iters):
        z = z*z + c
        if (z.real*z.real + z.imag*z.imag) >= 4:
            **return** i
    **return** 255**def** create_fractal(min_x, max_x, min_y, max_y, image, iters):
    height = image.shape[0]
    width = image.shape[1] pixel_size_x = (max_x - min_x) / width
        pixel_size_y = (max_y - min_y) / height
        for x in range(width):
            real = min_x + x * pixel_size_x
            for y in range(height):
                imag = min_y + y * pixel_size_y
                color = mandel(real, imag, iters)
                image[y, x] = color **return** image image = pd.DataFrame()
image["pixels"] = np.zeros(1, dtype=np.uint8)%timeit create_fractal(-2.0, 1.0, -1.0, 1.0, image, 20)> 30.5 ms ± 11.4 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
```

这里是完全相同的功能,但在顶部有 Numba 装饰。我不得不使输入数据非常非常小,因为`timeit`运行许多次迭代来测量速度。

```
@numba.jit **def** mandel(x, y, max_iters):
    """
    Given the real and imaginary parts of a complex number,
    determine if it is a candidate for membership in the Mandelbrot
    set given a fixed number of iterations.
    """
    i = 0
    c = complex(x,y)
    z = 0.0j
    for i in range(max_iters):
        z = z*z + c
        if (z.real*z.real + z.imag*z.imag) >= 4:
            **return** i
    **return** 255@numba.jit
**def** create_fractal(min_x, max_x, min_y, max_y, image, iters):
    height = image.shape[0]
    width = image.shape[1] pixel_size_x = (max_x - min_x) / width
        pixel_size_y = (max_y - min_y) / height
        for x in range(width):
            real = min_x + x * pixel_size_x
            for y in range(height):
                imag = min_y + y * pixel_size_y
                color = mandel(real, imag, iters)
                image[y, x] = color **return** image image = pd.DataFrame()
image["pixels"] = np.zeros(1, dtype=np.uint8)%timeit create_fractal(-2.0, 1.0, -1.0, 1.0, image, 20)> 1.63 ms ± 84 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
```

这是打字 5 秒钟速度的 18 倍。如果你的函数需要一些复杂的循环和条件混合在一起,看看你是否能运用一些 Numba 魔法还是值得的。

如果您感到好奇,这就是当您将`create_fractal`函数应用到全零的实际输入时它的样子:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c93fd41b66d75bbc193172c62b25036e.png)

# 管理你的记忆

如果您使用 Pandas 已经有一段时间了,那么您可能在某个时候遇到过中等大小的数据帧使您的 Python 进程崩溃的情况。令人困惑的是,当数据帧看起来没有那么大时,或者也许你记得上周在同一台笔记本电脑上处理更大的东西,但那台没有崩溃。怎么回事?

熊猫记忆问题的最大元凶可能是:

*   你的引用仍然附加在变量上,这意味着它们不会被垃圾回收。
*   你有太多的数据帧副本。
*   您可以进行更多的就地操作,这不会产生数据帧的副本。
*   `object`数据类型比固定数据类型占用更多的内存。

## 碎片帐集

垃圾收集是 Python 通过释放对程序不再有用的内存来释放内存的过程。您可以通过移除对该对象的引用来释放内存引用的对象。这将标记以前引用的对象以释放内存。

让垃圾收集帮助您管理内存的最佳方式是将您能做的任何事情包装到函数中。在函数中声明的变量只作用于函数,所以当函数结束运行时,它们会被丢弃。另一方面,全局变量(如`large_copy`)一直保留到 Python 进程结束(即笔记本内核关闭)。即使你`del`了一个变量,它也只是减少了 1 个引用,但是如果引用计数不是 0,被引用的对象实际上并没有被删除。这就是为什么全局变量会破坏你认为你的记忆。

只是为了好玩,您可以通过使用`sys.getrefcount(var_name)`来查看变量的引用计数。

```
*# `foo` is a reference*
foo = []sys.getrefcount(foo) # this temporarily bumps it up to 2> 2# yet another global reference bumps it up again 
foo.append(foo)sys.getrefcount(foo)> 3
```

此时,`del`将无法对其进行垃圾收集,全局范围内引用过多。

## 数据类型占用大量内存

又是那些讨厌的`object`dtype!毫不奇怪,告诉熊猫你需要能够在任何时间任何地方存储任何东西意味着它会为你存储的东西预先分配大量的初始内存。如果您存储的是复杂的东西,这没问题,但是如果您存储的是可以简单表示的东西,您可能想看看是否可以将 dtype 改为更适合您情况的类型。

检查数据帧占用了多少内存实际上比你想象的要容易。它已经内置到 DataFrame 对象中。

```
large_copy.info(memory_usage="deep")>
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7000 entries, 0 to 6999
Data columns (total 8 columns):
day_of_week      7000 non-null object
booleans         7000 non-null bool
positive_ints    7000 non-null int64
mixed_ints       7000 non-null int64
lat1             7000 non-null float64
lon1             7000 non-null float64
lat2             7000 non-null float64
lon2             7000 non-null float64
dtypes: bool(1), float64(4), int64(2), object(1)
memory usage: 773.5 KB
```

节约内存的一个常见做法是向下转换。例如,如果您知道您的整数不需要 64 位,就将它们转换为 32 位。但是,正如我们将会看到的,并不是所有的向下投射都具有同等的影响力。

```
large_copy["positive_ints"] = large_copy["positive_ints"].astype(np.int32)large_copy.info(memory_usage="deep")>
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7000 entries, 0 to 6999
Data columns (total 8 columns):
day_of_week      7000 non-null object
booleans         7000 non-null bool
positive_ints    7000 non-null int32
mixed_ints       7000 non-null int64
lat1             7000 non-null float64
lon1             7000 non-null float64
lat2             7000 non-null float64
lon2             7000 non-null float64
dtypes: bool(1), float64(4), int32(1), int64(1), object(1)
memory usage: 746.2 KB
```

3%的降幅其实并不显著。如果你有字符串列,并且它们被存储为一个`object`类型,那么它们总是比浮点数和整数更容易占用内存。

所有的`str`类型在熊猫中都被存储为`object`,因为它们可以是任意长度。您可以将字符串列向下转换为固定长度的`str`类型。例如,这个限制为 10 个字符:

```
large_copy["day_of_week"] = large_copy["day_of_week"].astype("|S10")large_copy.info(memory_usage="deep")>
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7000 entries, 0 to 6999
Data columns (total 8 columns):
day_of_week      7000 non-null object
booleans         7000 non-null bool
positive_ints    7000 non-null int32
mixed_ints       7000 non-null int64
lat1             7000 non-null float64
lon1             7000 non-null float64
lat2             7000 non-null float64
lon2             7000 non-null float64
dtypes: bool(1), float64(4), int32(1), int64(1), object(1)
memory usage: 636.8 KB
```

降价 18%并不坏,但是我们还能做得更多吗?你碰巧知道在`day_of_week`一周最多只有 7 天。有一种`category`类型可以利用由一小组重复元素组成的列。

```
large_copy["day_of_week"] = large_copy["day_of_week"].astype("category")large_copy.info(memory_usage="deep")>
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7000 entries, 0 to 6999
Data columns (total 8 columns):
day_of_week      7000 non-null category
booleans         7000 non-null bool
positive_ints    7000 non-null int32
mixed_ints       7000 non-null int64
lat1             7000 non-null float64
lon1             7000 non-null float64
lat2             7000 non-null float64
lon2             7000 non-null float64
dtypes: bool(1), category(1), float64(4), int32(1), int64(1)
memory usage: 315.2 KB
```

仅从一个专栏来看,就减少了 59%!

# 结论,第二部分

我几乎惭愧地承认,在我开始寻找优化之前,我花了几年时间使用 Pandas,即使在今天,我也没有对我制作的每一台笔记本进行优化。但是,通过一些简单的技巧,您可以看到几行代码的差异,甚至是如何处理单个列,会导致 10-100 倍的速度提升和 50%以上的内存减少。这绝对是一套不错的锦囊妙计。

如果您错过了它,请查看[第一部分:编写好的代码并发现无声的失败。](https://medium.com/@protagonistwu/how-to-avoid-a-pandas-pandemonium-e1bed456530)

# 如何避免潜在的机器学习陷阱

> 原文:<https://towardsdatascience.com/how-to-avoid-potential-machine-learning-pitfalls-a08781f3518e?source=collection_archive---------51----------------------->

## 理解并防止机器学习管道中固有的某些常见缺陷

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/240bfdd3b4f734977b8d6a7fac1e0f87.png)

迈克尔·波德格在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片

T 他的帖子是写给那些最近加入机器学习潮流的数据科学爱好者的。无论你是在大学里学习数据科学,还是自学成才,大多数有抱负的数据科学家在实际环境中尝试机器学习项目时,都会受到现实的检验。

我自己也曾与以下大部分潜在的绊脚石作斗争,但正如理查德·布兰森简洁地指出的:

> 你不能循规蹈矩地学习走路。你通过实践和跌倒来学习。

这里讨论的潜在缺陷会影响模型的准确性,并且一旦用于分析实时数据,还会影响模型的性能。人们通过实践学习这些东西,很快,当开发机器学习管道时,所有这些都将成为你的第二天性。我将尽可能让这篇文章实用,以便在从事实际的机器学习项目时,它可以作为一种清单。

简单回顾一下,**机器学习管道**包括机器学习项目中的所有单个工作流,包括但不限于:数据收集、探索性数据分析(EDA)、特征选择、特征工程、为训练准备干净的数据、训练/测试/验证数据分割、模型选择、训练&验证、生产部署和模型监控。

所以事不宜迟,让我们开始吧:

# 取样偏差

数据收集是任何机器学习项目的第一步,它充满了潜在的绊脚石,最关键的是采样偏差。简而言之,有偏样本是指在根据样本统计推断总体参数时,不能代表整个总体的样本,从而导致系统误差。

[采样偏差](http://www.scholarpedia.org/article/Sampling_bias)可以通过多种方式引入数据集,包括关注特定的真实区域(郊区、城市、乡村、大学等)。)only,自我选择偏差,排除偏差,生存偏差等。

**预防策略**:虽然收集一个完全无偏见的数据集有时可能有点棘手,但是,可以调整数据收集策略,以确保尽可能公正的样本。例如,数据收集应该纯粹是一种随机行为,每个数据点都有平等的机会被选中;使用来自内部数据库的整个数据集;避免数据收集过程中的判断、便利或成本因素等。

# 数据清理

处理输入要素中的缺失值是任何机器学习项目的关键组成部分,因为在实际设置中很少会有干净的数据集可供处理。处理缺失值的一种简单方法是丢弃所有缺失值的观测值,或者通过统计参数(如平均值、中值或众数)对其进行估算。但是,如果丢失的值真的是由设计或数据收集逻辑造成的呢?

**预防策略**:利用领域知识和主题专业知识理解数据集中缺失值的性质、原因和方式。只有这样,一旦你掌握了这些知识,就可以相应地利用适当的插补技术——可以是丢弃观察值,使用均值/中值/众数,或者应用专门用于插补目的的另一种 ML 算法,等等。

# 不适当的特征选择

特征工程和特征选择通常被吹捧为任何数据科学项目的支柱,因为模型验证和实际模型性能严重依赖于它们。为此,一些 ML 实践者陷入了对理想特征的追求,以至于他们无意中选择了不相关的特征作为模型训练的目的。

**预防策略**:这是深度领域知识派上用场的地方,以识别和选择只适合模型训练的特征。如果数据科学家缺乏深入的领域和行业知识,也可以利用主题专家。

# 数据泄露

ML 算法通常应用于训练数据集,然后在测试/保留数据集上进行验证。为此,完整的数据集被分成 2 个(有时是 3 个)集合,每个集合用于训练、测试(和验证)。如果所有的数据转换和准备步骤都在拆分前应用,那么很有可能在模型训练期间已经使用了来自测试数据集的一些信息。这种数据泄漏导致过度拟合,并且通常导致过度乐观和无效的模型。

作为一个简单的例子,考虑这样一个场景,我们通过使用变量的平均值来估算缺失值。如果我们使用整个数据集进行插补,那么我们的假设值也将基于测试数据集的值。测试数据集应该代表看不见的真实数据;因此,使用这些在生产中不可用的信息将导致模型偏差和过度拟合。

**预防策略**:简单,在应用任何数据准备、转换、特征选择、降维、特征工程技术之前,将数据集分成训练集和测试集。所有这些技术应该分别应用于训练和测试数据集。

# 走向未来

这一点是前两点的直接延续。在目标变量中的事件发生之前,您可能遇到的一些输入变量是无法观察到的。例如,直到客户拖欠贷款时才能知道 amount_recovered(用于预测贷款拖欠的模型),或者直到航班着陆时才能确定航班时间(用于预测航班延误的模型)。

**预防策略**:只要不使用任何这样的特征进行模型训练,在目标变量被观察到之前不可能发生。

# 需要时没有规范化或标准化

依赖于某种距离度量(例如,线性回归、SVM、kNN)的机器学习算法对度量尺度高度敏感,因为它们假设所有特征都在同一尺度上。因此,与其他数据(例如,年龄)相比,这些算法将为数值较大的数据(例如,年度支出)分配较高的权重。这显然是不可取的。

**预防策略**:在模型训练之前,对你的数据集应用某种统计变换,例如[标准化](https://statisticsbyjim.com/glossary/standardization/)或[规范化](https://en.wikipedia.org/wiki/Normalization_(statistics)),使所有变量处于一个等价的尺度上。请注意,这仅在使用假设统一测量比例的算法时需要。

# 异常值的处理

离群值是在特定数据集的上下文中不正常的单个数据点,但在现实生活中并不少见。每个最大似然算法处理它们的方式不同,应该小心识别和处理数据集中的异常值。某些算法适当地处理异常值(大多数基于树的方法都这样做,例如随机森林,XGBoost)。相比之下,线性回归等其他方法更容易受到它们的影响,并试图相应地拟合模型(也称为过度拟合)。

**预防策略**:通过绘图(例如,盒须图)或统计技术( [Z 值](https://en.wikipedia.org/wiki/Standard_score)),始终识别数据中的任何异常值。然后或者使用适当处理异常值的算法(例如,基于树的算法),消除异常值,或者应用 [winsorization 技术](https://en.wikipedia.org/wiki/Winsorizing)。

# 多重共线性

多重共线性是指两个或多个输入要素彼此高度相关的情况,即它们都以某种方式以相似的方式预测目标变量。这可能导致不利的后果,即模型不收敛,或者预测值的统计显著性被破坏。多重共线性通常发生在为分类变量创建哑变量而没有删除其中一个哑变量时,例如,性别 _ 男性和性别 _ 女性哑变量共线,因此任何一个哑变量都可以用于识别一个人的性别。

**预防策略**:通过计算所有独立变量的成对相关系数(通过相关矩阵或[变异膨胀因子](https://en.wikipedia.org/wiki/Variance_inflation_factor))来识别多重共线性,然后通过主成分分析或其他方法删除其中一个冗余变量或合并相关变量。

# 不平衡数据的验证指标

有几个验证指标,但并不是所有的都与不平衡数据相关。识别和应用合适的验证指标对于不平衡数据至关重要,否则,我们将错误地依赖模型的稳健性。

考虑欺诈检测的示例,其中训练数据集仅包含 2%的欺诈案例。天真地使用准确性指标并不能代表模型的真实预测能力。换句话说,如果我将所有的测试/现实案例都归类为非违约,那么我有 98%的正确率。

**预防策略**:使用更适合不平衡数据的验证指标,如[精度](https://en.wikipedia.org/wiki/Precision_and_recall)、[召回](https://en.wikipedia.org/wiki/Precision_and_recall)、 [F1 分数](https://en.wikipedia.org/wiki/F1_score)、[精度-召回(PR)曲线](https://machinelearningmastery.com/roc-curves-and-precision-recall-curves-for-imbalanced-classification/)、[受试者操作特征(AUROC)曲线下面积](https://machinelearningmastery.com/roc-curves-and-precision-recall-curves-for-imbalanced-classification/)、[基尼指数](https://en.wikipedia.org/wiki/Gini_coefficient#Relation_to_other_statistical_measures)。

# 结论

这就对了——注意上面的潜在陷阱,你将会在机器学习的道路上走得很好。

如果您想讨论任何与数据分析、预测分析和信用/财务评估相关的问题,请随时联系我。

# 如何避免停留在你的机器学习书单中第一本书的第一章

> 原文:<https://towardsdatascience.com/how-to-avoid-stopping-at-chapter-1-of-the-first-book-in-your-machine-learning-booklist-a38a41936735?source=collection_archive---------42----------------------->

## 读书比看书单更重要。如果你想完成你在机器学习方面的书单,我的策略大概可以帮到你。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/959010eb19cc43b7fd6b5bafc27dc999.png)

本·怀特在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片

Y 在你阅读这篇文章之前,你可能已经通读了数十份机器学习书目。但是你看完里面的书了吗?

我也没有。

我发现,当我对读一本新书充满热情时,这种热情会在我到达书的中心部分之前在某个地方耗尽。

大部分没看完的书我都卡在了 ***第 1 章*** 里。所以,那时候,我从书上读了几百遍的东西只有机器学习的历史和机器学习的基本概念。

大约半年前,我试图解决反复阅读第一章的问题。我制定了一个阅读策略,它对我很有效。

我以我自己的机器学习书目为例与你分享。如果你和我有同样的问题,希望这篇文章能帮到你。没有必要从我这里复制一切,但是值得一试把这个策略应用到你的书单上。

## 第一步:根据你的需求过滤你的书单。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a8e1a4d695d2263d14e2cf0e4329ecc3.png)

布莱克·理查德·弗多恩在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片

我之所以想看机器学习方面的书,可以用两层需求来解释。*首先,*我希望能够在我开始阅读书籍的时候就能输入我的机器学习代码。*二、*我想看完之后能够理解算法。

第一层是面向工程的,第二层是面向研究的。

基于这些需求,我在最终书单中保留了四本书:

1.  [使用 Scikit-Learn、Keras 和 TensorFlow 进行机器实践学习。](https://www.oreilly.com/library/view/hands-on-machine-learning/9781492032632/)
2.  [用 Python 进行深度学习。](https://www.manning.com/books/deep-learning-with-python)
3.  [统计学习的要素。](https://web.stanford.edu/~hastie/ElemStatLearn/)
4.  [深度学习。](https://www.deeplearningbook.org/)

动手项目编码选择书本***# 1******# 2***,数学理论学习选择书本***# 3******# 4***。

## 第二步:对你的过滤书单中的书籍进行分类。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f7b461598a2069ac0176ca55f6f34cf1.png)

安妮·斯普拉特在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 拍摄的照片

得到我的过滤书单后,我把它们按两个维度进行分组。

第一维是内容,第二维是功能,如下表所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0ef8c4fad81f7f74d2a4fa4007678ab7.png)

我的书单分类表(作者[俞峰](https://medium.com/@jianan.jay.lin)

我以自己喜欢的方式设计了分类。具体来说,我使用了“机器学习”和“深度学习”来拆分涵盖机器学习广泛主题的书籍和专注于深度神经网络的书籍。

我把那些有沉重方程式和数学解释的书定义为“字典”,把那些有数吨行代码的书定义为“手册”。

任意命名,但对我有用。

## 步骤 3.1:阅读一本手册和字典。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0208db4184706913a28fb06a4ba02fb4.png)

照片由 [Dmitry Ratushny](https://unsplash.com/@ratushny?utm_source=medium&utm_medium=referral) 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄

至于上一步归类为“机器学习”的书籍,我把书 ***#3*** 放在手边,开始阅读来自 ***第二章*** 名为*“端到端机器学习项目”*的书 ***#1*** 。

在阅读过程中,每当我想更深入地理解*书中解释的术语时,我就会查阅*书。**

**例如,当我读到第 ***#1*** 本书第 *#70* 页的 ***决策树回归器*** 时,我打开我的第 ***#3*** 本书,通读第 *#307 页 *9.2.2* 小节的 ***回归树****然后我又回到了第*本书的第 *#70* 页,把相关段落看了一遍。***

**这个策略的实施,一开始让我花了一些时间去熟悉,但是习惯之后我显著提高了阅读效率。**

**节省我开阖书时间的一个窍门就是下载一个电动版的书 ***#3*** 和一个纸质版的书 ***#1*** 一起使用。**

## **步骤 3.2:在您自己的数据上尝试相同的代码。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c3d7641b5a08c72073aac3ad6a9c403a.png)**

**照片由 [Hitesh Choudhary](https://unsplash.com/@hiteshchoudhary?utm_source=medium&utm_medium=referral) 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄**

**在学习了 ***#1*** 一书中*加州房屋数据*的分析后,我在 R 中的 [*汽车数据集*上应用了相同的代码。](https://stat.ethz.ch/R-manual/R-devel/library/datasets/html/mtcars.html)**

**我没有简单地将代码从一个数据集复制粘贴到另一个数据集。我在新的数据集上应用了从书 ***#1*** 中学到的基本数据可视化工具,并基于可视化提出了几个我想问的问题。**

**这些问题可能很简单。例如, *mpg* 能否通过其他特征预测,如*气缸数*和*总马力*?目的是训练第一眼看完资料后的提问能力。**

**接下来,根据这些问题进行建模。比如我在汽车数据集上构建了一个 [***随机森林回归器***](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html) ,以 *mpg* 为因变量。**

## **第 3.3 步:阅读第 1 章。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0e1b3905b07ede773934f5c325b69b13.png)**

**米歇尔·巴洛格在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片**

**我之所以把这一步放在这里,并不是因为我讨厌第 1s 章。**

**正如我所说,通常第 1 章描述了机器学习的历史,基本概念,以及对机器学习的社会行为(如机器学习研究投资随时间的变化)。随着这本书其他部分的完成,对我来说第一章看起来比以前更有内容*。***

***另外,把第一章作为最后一步阅读,帮我生成了我在机器学习方面的 ***新书目*** 。具体来说,在了解了将机器学习方法应用于我们日常生活的历史和挑战之后,我对人工智能的未来变得更加感兴趣。***

**因此,我制作了我的新书目录,如下所示:**

1.  **尼克·博斯特罗姆。[超智能。路径,危险,策略。](https://www.google.com/books/edition/Superintelligence/7_H8AwAAQBAJ?hl=en&gbpv=0)**
2.  ****最大标记**。[生活 3.0。](https://www.google.com/books/edition/Life_3_0/2hIcDgAAQBAJ?hl=en&gbpv=0)**

## **第四步:为你的代码编一个故事,并告诉其他人。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/76abe4f82c949a2daa28f7972c023024.png)**

**照片由[米米·蒂安](https://unsplash.com/@mimithian?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄**

**人们通常会低估机器学习领域讲故事的能力。**

**所有的技术本身不能形成一个故事,除非你的目的是开发新的算法,这远远不够阅读几本书。最佳实践是用你的领域知识将机器学习技能应用于现实世界的问题。**

**此外,从实践中获得的第一手经验在任何书中都找不到。这是我写的另一篇文章,详细描述了这样的经历。**

**[](/one-potential-cause-of-overfitting-that-i-never-noticed-before-a57904c8c89d) [## 我以前从未注意到的过度拟合的一个潜在原因

### 当训练数据中的性能比测试数据中的性能好得多时,就会发生过度拟合。默认…

towardsdatascience.com](/one-potential-cause-of-overfitting-that-i-never-noticed-before-a57904c8c89d)** 

**我真的希望我的阅读策略可以帮助你完成你的书单,并在数据科学方面更进一步。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/78736a3267480de2dcc4f78e9abbe4f0.png)**

**美国宇航局在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 拍摄的照片**

## **参考资料:**

1.  ****特雷弗·哈斯蒂****罗伯特·蒂布拉尼****杰罗姆·弗里德曼**。[统计学习的要素。](https://web.stanford.edu/~hastie/ElemStatLearn/)**
2.  **伊恩·古德菲勒、**约舒阿·本吉奥****亚伦·库维尔**。[深度学习。](https://www.deeplearningbook.org/)**
3.  **奥雷连恩·盖伦。[使用 Scikit-Learn、Keras 和 TensorFlow 进行机器学习。](https://www.oreilly.com/library/view/hands-on-machine-learning/9781492032632/)**
4.  **弗朗索瓦·乔莱。[用 Python 进行深度学习。](https://www.manning.com/books/deep-learning-with-python)**

# 如何避免编写草率的 SQL

> 原文:<https://towardsdatascience.com/how-to-avoid-writing-sloppy-sql-43647a160025?source=collection_archive---------12----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/26b958ddfbc733d642a81c198cfd8a55.png)

照片由[阿毛里·古铁雷斯](https://unsplash.com/@amaury_guti?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/sloppy?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄

## 更好的 SQL

## 让您的 SQL 代码更易读、更容易理解

SQL 简单易懂,易于使用。从查询中很容易得到正确的结果。然而,阅读其他人正确运行的查询并不容易。SQL 并不强制要求编写查询的全局格式标准(就像 Python 中的`PEP8`)。有类似于 [SQL 风格指南](https://www.sqlstyle.guide)的倡议,但是它没有广泛的追随者。因此,很难让人们以某种方式写作。此外,大多数 SQL IDEs 也不支持同样的查询美化。

> 任何傻瓜都能写出计算机能理解的代码。优秀的程序员编写人类能够理解的代码——马丁·福勒

然后,这就变成了一个需要通过自律来解决的问题。如何确保他们编写的 SQL 代码容易被其他人阅读和理解?有一些简单的步骤可以遵循。最重要的是,遵循一个风格指南会让一切变得简单得多。想想这个—

# 遵循风格指南

从一开始,Python 就倾向于简单易读。缩进的原理本身很好地解决了可读性问题。SQL 从一开始就没有任何可以强制执行的标准。让我们回头再来讨论这个问题。现在,请看这个例子,它演示了如何使用`PEP8`标准在 Python 中正确缩进

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/513e9420560f08e84b43861a92207b80.png)

摘自吉多·范·罗苏姆的 [PEP8 页](https://www.python.org/dev/peps/pep-0008/)

我遇到的最著名和最有用的风格指南是 Simon Holywell 的 SQL 风格指南。没有必要重复本风格指南中的内容,但值得强调的是,命名约定、别名和缩进大大有助于使代码更易于阅读和理解。这是风格指南的摘录—

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8e80902d24b68469ccfce5b4ca44b730.png)

摘自 Simon Holywell 的 [SQL 风格指南](https://www.sqlstyle.guide)

看,风格指南说的是最简单的事情。关注这些最简单的事情的每一点努力都会使你的代码更加整洁。

# 错认假频伪信号

SQL 是关于连接、表、cte 等等的。在一个数据库中,在给定的时间有如此多的对象。当编写一个查询时,我们确实需要访问很多这样的查询。有时候,说实话,太多了。如果发生这种情况,应该有一种访问这些数据库对象的简单方法。

在组织内部,这种简写应该很容易识别。例如,如果有一个名为`delivery_packages`的表,那么它的别名应该是`dp`。根据经验,对于 snake case 表名中的每个单词,只取表名的第一个字母。`order_feedback_comments`的别名应为`ofc`。确保这些表的别名也不要太短。确保它们有一定的意义。查看[这篇文章](https://sqlblog.org/2009/10/08/bad-habits-to-kick-using-table-aliases-like-a-b-c-or-t1-t2-t3)。

# 注释您的 SQL 代码

如果查询有很多行,将其分成 cte 或子查询,或者创建临时中间表。如果您不希望这样做,无论哪种方式,请确保以易于阅读和理解的方式注释您的 SQL 代码,并用尽可能少的词语解释您正在使用查询做什么。警告、问题、性能相关的东西——所有其他的都应该详细注释。

> 如果你的代码易于阅读,它就易于重用

如果没有适当的注释,通读千行查询可能并且应该是困难的。尽量不要让它变得困难。评论评论好。遵循一个风格指南。

# 小心子查询

最后,作为一般的经验法则,如果可能的话,将子查询保持在最少——不仅仅是因为性能原因。复杂的多级子查询可能会很快完成工作,但越来越难以维护。如果您的数据库支持 cte,请尽可能使用它们,而不是使用子查询。如果查询变得太复杂并且有太多的子查询,那么创建临时表(可能在内存中),然后从那里开始。

> 聪明的程序员和专业的程序员的一个区别是,专业的程序员明白清晰才是王道。专业人士善用他们的能力,写别人能理解的代码——罗伯特·马丁

[避免马虎。写出更好的 SQL](https://linktr.ee/kovid) 。

*专业的大声喊出来给 Vicky Boykis 作* [*写关于这个*](http://veekaybee.github.io/2015/06/02/good-sql/) *的方式早在 2015 年和 Simon Holywell 作准备的* [*SQL 风格指南*](https://www.sqlstyle.guide) *。*

# 如何抨击:对于我们这些不喜欢命令行的人来说

> 原文:<https://towardsdatascience.com/how-to-bash-for-those-of-us-who-dont-like-the-command-line-8cbf701356dd?source=collection_archive---------26----------------------->

## 80 年代的技术让你成为更快的程序员

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/20c3cee7ab32eecfbfc717219bcfd73d.png)

凯文·霍尔瓦特在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片

詹姆斯塔克。PyCaret。CI/CD 自动化。软件开发前沿的所有性感的前沿技术。

然后是巴什。伯恩又一个外壳,Unix 用户的默认外壳——Linux 和 Mac。对于在 Windows 上工作的软件开发人员来说是绝对必要的。(如果你没有在 Windows 上使用 WSL2,停止阅读这篇文章,进入`Windows Features`,打开 Linux 的 Windows 子系统…现在!)

Bash 可能看起来是一个不值得您花费时间的遗迹。而且肯定不会诱发寻找最新东西的开发者流口水。但是它*是*所有运行终端或者 Windows 终端的人都用的(或者应该是)。

运行上面提到的所有性感程序?巴什。

我也用鼠标,所以这不是命令行纯粹主义者的说教。然而,这个外壳的用途不仅仅是你现在使用的。在文件系统中导航。设置项目。运行 Python / Node / whatever 包管理器的命令。

在本文中,我想分享一些 Bash 的基本知识。如何从 Bash shell 中获得更多的东西,而不至于让自己疯狂地试图掌握它的许多怪癖。

最后,我将在我的 Windows 笔记本电脑上共享`.bashrc`文件。这个文件连同。`bash_aliases`,每天为我节省了大量的按键和认知压力。

# `.bashrc`文件

`.bashrc`文件位于您的主目录的根目录下。大多数终端和文件 ui 默认不显示“点文件”;它们是隐藏文件。您可以通过输入以下内容来查看您的:

```
$ ls -a ~/.bashrc
/c/Users/nicho/.bashrc*
```

`ls`命令上的`-a`开关告诉程序打印所有文件,甚至是点文件。

shell 程序启动时需要运行的任何东西的 Home base。

*   环境变量
*   功能
*   别名
*   设置
*   提示
*   自动完成

这是所有好东西的去处。我保持简单。虽然没有必要,但我的别名放在一个单独的文件中,`.bash_aliases`。Bash 将在您的`.bashrc`中加载这些代码。

```
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi
```

# Bash 别名

使用`alias`命令查看 shell 环境中可用的别名。

```
$ alias
alias avm='ssh -i ~/.ssh/digitalocean root@XXX.XX.XXX.XXX'
alias az='az.cmd'
alias ba='vim ~/.bash_aliases'
alias chrome='/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe'
alias clpr='cd /c/projects/CLIENTPROJECTS'
alias cls='clear'
alias cn='code -n .'
alias d='cd /c/Users/nicho/Downloads/'
alias day='touch ~/Downloads/$(date +%m%d%Y).txt; code ~/Downloads/$(date +%m%d%Y).txt'
alias dcu='docker-compose up -d'
alias default='export AWS_PROFILE=default && echo Using my default AWS account'
alias docs='cd /c/Users/nicho/OneDrive/Documents'
alias dpa='docker ps -a'
alias e='explorer .'
alias ee='exit'
alias es='/c/tools/elasticsearch/bin/elasticsearch.bat
...
```

别名只受你的想象力的限制。通过不接受参数。

```
# alias test="echo Hi, $1 $2"
$ test Jane Doe
Hi, Jane Doe
​
# alias test="echo Hi, $1 $2\. We are using aliases!"
$ test Jane Doe
Hi, . We are using aliases! Jane Doe
```

最好对带参数的命令使用 Bash 函数。

# 完成工作的基本功能

Bash 函数有足够简单的语法来声明:

```
function_name () {
  # logic here
}
```

示例:

```
test () {
  if [ -z "$1" ]; then # no argument
    echo "Hi, Anonymous!";
  else
    echo "Hi, $1 $2\. We are using aliases!";
  fi
}
```

编写 Bash 脚本的一个好处是,您可以直接从终端程序运行它们(在 Windows 上,当运行 [Git BASH](https://gitforwindows.org/) 时)。Bash 也是一种编程语言:

```
$ test () {
>   if [ -z "$1" ]; then # no argument
>     echo "Hi, Anonymous!";
>   else
>     echo "Hi, $1 $2\. We are using Bash functions!";
>   fi
> }
$ test
Hi, Anonymous!
$ test Nick B
Hi, Nick B. We are using Bash functions!
```

…但这也是我对 Bash 的 shell 脚本一无所知的地方。对于任何比上面的例子更复杂的东西——模板、大量变量、嵌套命令——请使用 Python。Python 彻底击败了 Bash 编写的易于理解的脚本。

# 快捷键

# 我的`.bashrc`

请击鼓!正如承诺的,这是我的`.bashrc`设置。在电脑上,没有比`.bashrc`更私人的文件了。(不,我没那么无辜。我们在这里谈论编程。)

你会发现这些对你没用。有些,我真心希望你能做到。拿一些你认为可以使用的部分,复制它们,然后自己动手做。自行添加。

请记住,您需要运行`.bashrc`文件来查看 shell 中的更改是否生效。

```
$ source ~/.bashrc
$ # or
$ . ~/.bashrc
```

我的`.bashrc`档案:

```
#!/bin/bash
​
export PATH="/c/scripts/:$PATH"
​
# virtualenvwrapper
export WORKON_HOME=$HOME/Envs
​
# Postgres
export PGCLIENTENCODING=UTF8
​
PATH=~/.local/bin:$PATH
​
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
​
# command completion for AWS CLI
complete -C '/c/Python36/Scripts/aws_completer' aws
​
# function to go to the designated projects folder
p() {
    cd /c/projects/$1
}
​
# function to cd to the scripts folder, then subfolder
s() {
    cd /c/scripts/$1
}
​
# function to cd to the startup folder
startup() {
    cd /c/Users/nicho/AppData/Roaming/Microsoft/Windows/Start\ Menu/Programs/Startup
}
​
# random number generator
rand() {
  if [ -z "$1" ] # no argument
    then
      range=4
    else
      range=$1 # will error if argument is not a number
  fi
  local num
  for ((i=0;i<$range;i++))
    do
    num=$num$((RANDOM%9))
    done
  echo $num
  printf "%s" $num | clip.exe
  echo "Number is on the clipboard."
}
​
# alias for cd change directory
a() {
  if [ -z "$1" ] # no argument
    then
      cd -
    else
      cd $1
  fi
}
​
# alias for choco install --confirm
ci() {
  if [ -z "$1" ] # no argument
    then
      echo "choco install needs a package name argument to run."
    else
      choco install --confirm $1
  fi
}
​
# get an AWS elasticsearch domain's endpoint to the clipboard
esdomain() {
  if [ -z "$1" ] # no argument
    then
      echo "need a domain name as an argument for this function"
    else
      ENDPOINT=$(aws es describe-elasticsearch-domain --domain-name $1 | jq '.DomainStatus.Endpoint' | tr -d \")
      printf "%s" $ENDPOINT | clip.exe
      echo "The endpoint for $1 is on the clipboard."
  fi
}
​
# open my date log files
week() {
  today=$(date +"%Y-%m-%d")
  lastSunday=$(date -d "$today -$(date -d $today +"%u") days" +"%Y-%m-%d")
  for ((i=1; i<=7; i++)); do
    code ~/OneDrive/Documents/$(date +"%m%d%Y" -d "$lastSunday +$i days").txt
  done
}
​
toobig() {
  if [ -z "$1"] # no argument
    then
      du -h --threshold=5000000 # show files 5MB or greater
    else
      du -h --threshold=$1
  fi
}
```

# 结论

Bash 并不新鲜。但正因为如此,它是您的软件开发环境的基础。如果像 Bash 别名或某个函数这样的新技巧节省了您通常在终端中导航所花费的一半时间,那么这意味着您只需要实现一两个新东西,就可以将命令行的工作效率提高一倍!

我很想知道你在系统中使用了哪些 Bash 特性。请对本文发表评论。谁知道呢?也许你发现的东西也能帮助我们其他人!

# 2020 年如何做一名数据分析师

> 原文:<https://towardsdatascience.com/how-to-be-a-data-analyst-in-2020-3b6f859cfa43?source=collection_archive---------18----------------------->

## 发展成为数据分析师所需技能的深入指南

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/841f5a9ad7e8a802929c8271544829a5.png)

[活动发起人](https://unsplash.com/@campaign_creators?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/data-analyst?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

# 目录

1.  [简介](#5e56)
2.  [什么是真正的数据分析师](#eaf8)
3.  [成为数据分析师所需的技能](#7550)

# 介绍

1995 年,不到 10%的世界人口使用互联网。现在,[互联网用户占全球人口的 58%](https://www.internetworldstats.com/emarketing.htm)并且[每天产生超过 2.5 **万亿**字节的数据](https://www.forbes.com/sites/bernardmarr/2018/05/21/how-much-data-do-we-create-every-day-the-mind-blowing-stats-everyone-should-read/#484635bd60ba)。随着技术进步继续超过拥有相关 STEM 知识的人数,对工程师、数据科学家和数据分析师的需求比以往任何时候都要多。对数据分析师的需求如此之大,以至于美国数据分析师的平均工资约为 7 万美元!

在本文中,我将向您介绍我对数据分析师工作的看法、成为数据分析师所需的技能,以及我的一些经验。

# 数据分析师到底是什么

我读过几篇文章,这些文章给了我一个数据分析师所做事情的清单,但从最简单的意义上来说,**您正在分析和可视化数据**。每个公司都有自己的数据库,你可以从中查询。这些公司也有自己的数据可视化工具,比如 Tableau,你可以用它来可视化你的见解和发现。

在商业中,有许多类型的数据,如产品数据、营销数据和运营数据,同样,也有几种类型的数据分析师,如产品分析师、营销分析师和运营分析师。这些工作的不同之处在于与每个类别相关的领域知识,但最终,它们与术语“数据分析师”同义。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/60a386482f044d41c2b585af2e781252.png)

数据分析师的一般工作流程

数据分析师的工作范围最终取决于你工作的公司,但一般来说,数据分析师会经历上图中的以下工作流程。让我们走一遍。

## 问题

每次分析都从一个问题或一项任务开始。这些任务的难度会有很大差异。一个简单任务的例子是,如果要求您编写一个查询来提供统计数据,比如昨天的销售额。更困难的任务的一个例子是当答案不清楚时,你被要求探索数据。例如,如果让你找出为什么上个月的销售额比其他月份差得多。

## 探索和查询

一旦您收到一个问题,您通常会编写一个或多个查询来探索和收集解决问题所需的信息。这意味着您可能需要了解 SQL 或 Python(或者两者都了解)来收集您需要的信息。

继续前面的例子,如果要求您找出为什么上个月的销售比其他月份差得多,您可能会查询上个月的平均客户评论评级,以查看产品是否有问题,或者您可能会查询上个月的营销支出与其他月份相比,以查看营销支出是否有显著减少。

## 收集见解

下一步是收集你的见解。有时,收集您的见解意味着将您的见解复制并粘贴到 Excel 表格中。其他时候,这意味着保存您用来查找下一步所需信息的查询。

## 可视化见解

一旦你收集了你的见解,你可能需要将你的发现形象化。有时,这就像在 Excel 中制作条形图一样简单。其他时候,这意味着创建一个广泛的仪表板,供高管们使用。这一步需要的技能取决于公司和项目。它包括但不限于 Powerpoint、Excel、Tableau、Matplotlib 等…

## 传达你的发现

最后,您需要传达您的结果,无论是通过带有几个静态图表的幻灯片还是带有几个 KPI 指标的仪表板。类似于回答行为问题的星形方法,你将走过问题、任务、你采取的方法和最终结果。

## 注意:

我知道我是通过简化来概括的,我知道这并没有涵盖数据分析师日常工作中的每一件事。然而,对于那些完全不知道数据分析师做什么的人来说,就像你们中的一些人不知道语言病理学家做什么一样,这为他们做什么提供了一个体面的想法。

# 成为数据分析师所需的技能

如果您对此感兴趣,那太好了!2020 年初,Jeff Hale 发表了一篇文章,“数据分析师最需要的技术技能”。通过搜集和分析几个招聘网站,他得出结论,数据分析师的前四项技能从最重要到最不重要依次是 SQL、Excel、Tableau 和 Python。

## **SQL**

**什么是 SQL?**

SQL 是一种用于访问和操作数据库的编程语言。可以把数据库想象成表的集合,表是具有相同变量的行的集合。想象一个 Excel 表格,如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b48f46deb98cb6d4da0247441ca44e7b.png)

表格示例

**查询**是从数据库表或表的组合中请求数据。使用上面的表格,如果我想找到所有大于 23 岁的病人,我将编写一个**查询**。作为一名数据分析师,您将频繁地查询数据,或者为其他员工检索信息,或者解决更复杂的问题。

**如何学习 SQL**

*   如果你想学习初学 SQL,可以看看我的文章《[5 分钟 5 步学会初学 SQL!是的,不同类型的 SQL 语言有不同的语法,但一般来说,它们遵循相同的格式。](/learn-beginner-sql-in-5-steps-in-5-minutes-c44c47fa39a1)
*   如果你在实践中学习得更好,Codecademy 有一个非常好的关于 SQL 的简明课程[在这里](https://www.codecademy.com/learn/learn-sql)。这就是我个人学习 SQL 的基础。
*   一旦你学会了基础知识,你就可以用[这些练习题](https://www.w3resource.com/sql-exercises/)来练习你所学的知识。

## **Excel**

**什么是 Excel?**

如果你还不知道,Excel 是一个电子表格程序,它允许你在表格的行和列中输入数据。你应该知道如何使用 SUMIF、IF 语句和 COUNT 等基本函数。此外,您应该知道如何创建图表和数据透视表。在实践中,因为公司重视协作,你可能会被要求使用 Google Sheets,这本质上是一回事。

**如何学习 Excel**

说实话,Excel 是我通过经验学到的东西。如果你没有机会边做边学,YouTube 上有一些很棒的视频(也是免费的)可以用来学习 Excel!见下文。

*   [Excel 初学者指南](https://www.youtube.com/watch?v=rwbho0CgEAE)
*   [微软 Excel 教程—初学者 1 级](https://www.youtube.com/watch?v=k1VUZEVuDJ8)

## **画面**

**什么是 Tableau?**

Tableau 是一种数据可视化工具,广泛应用于所有行业。通常,公司使用 Tableau 来创建仪表板,仪表板是显示实时指标供企业查看的工具。例如,营销团队可能会创建一个显示每日转换、每日营销支出和每日网站流量的仪表板。

**如何学习 Tableau**

*   如果你想学习如何使用 Tableau,他们有一系列的培训视频,你可以自己浏览[这里](https://www.tableau.com/learn)。他们还提供现场培训和电子学习体验。
*   或者,我在几年前购买了一门关于数据科学基础的课程,在这门课程中,它将指导您下载和使用 Tableau。如果这是你感兴趣的东西,你可以在这里查看课程。

## **Python**

**Python 是什么?**

Python 是一种通用的编程语言,深受数据分析师和数据科学家的欢迎。具体来说,在 Python 中,有各种各样的库可以用来执行数据分析,比如 NumPy、Pandas 和 Sci-kit Learn。

如果你想学习如何使用 Python 和这些库,你可以在网上利用一些资源,比如 DataCamp、Udemy、Coursera 和 Udacity。虽然我对学习 Python 没有任何特别的偏好,但我鼓励你选择一种资源并坚持下去!

# 感谢阅读!

如果你喜欢我的工作,想支持我…

1.  支持我的最好方式是在**媒体**上关注我[这里](https://medium.com/@terenceshin)。
2.  在 **Twitter** 这里[成为第一批关注我的人之一](https://twitter.com/terence_shin)。我会在这里发布很多更新和有趣的东西!
3.  此外,成为第一批订阅我的新 **YouTube 频道** [这里](https://www.youtube.com/channel/UCmy1ox7bo7zsLlDo8pOEEhA?view_as=subscriber)!目前还没有视频,但它就要来了!
4.  在 **LinkedIn** 上关注我[这里](https://www.linkedin.com/in/terenceshin/)。
5.  在我的**邮箱列表** [这里](https://forms.gle/UGdTom9G6aFGHzPD9)报名。
6.  看看我的网站,[**terenceshin.com**](https://terenceshin.com/)。

# 如何成为 2020 年的数据科学家

> 原文:<https://towardsdatascience.com/how-to-be-a-data-scientist-in-2020-9bc3cf4ff007?source=collection_archive---------44----------------------->

## 理解机器学习项目的生命周期并揭示成功项目的标准。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5ab73969e96e60a2977af46777532f48.png)

[来源](https://unsplash.com/s/photos/leader?utm_source=medium&utm_medium=referral)

数据科学团队是每个大公司的核心。一个成功的数据科学家需要成为业务战略的负责人,能够通过数据做出发现和愿景,能够通过沟通和可视化说服利益相关者。然而,如今的数据量呈指数级增长,这使得数据科学工作变得更加复杂。每个公司都开始理解数据的重要性,并尽可能多地收集数据。数据大小从几千兆字节增加到几千兆字节。云存储和计算变得更加流行。最终用户组织正在采用云存储解决方案作为主要存储选项。因此,2020 年的数据科学家需要具备大数据知识以及与之相关的工具。在这篇博客中,我将从 AWS 的角度介绍机器学习项目的生命周期。看完这个,我们就明白成为 2020 数据科学家需要什么了。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/de1e49fdc31415dc506cf4c8f28eef03.png)

机器学习项目生命周期。资料来源:Huy Bui

# I)检测问题

创建机器学习项目最重要的一步是检测业务问题。很多情况下,数据科学家迷失在数据中,浪费时间与大数据争论,解决一个对业务没有显著改善的非常困难的问题,甚至完成一个项目,感觉好像有人以前做过一样。每个数据科学项目都需要仔细规划。没有计划就是计划失败。了解业务环境和可能采取的业务行动将为数据科学家节省大量时间,并为您的公司节省大量资金。这对于参加商务会议、与高管员工聊天以及始终站在利益相关者的角度来看都很重要。

# II)数据收集

在弄清楚问题之后,数据科学家需要获得数据并适当地组织数据。数据收集可以在内部或外部进行。大多数结构化数据存储在关系数据库中。所以,学习 SQL 是必不可少的。SQL 可能很古老,但却无处不在。你甚至可以在 FAANG 公司或者非技术行业的高性能数据库系统中看到 SQL。

生产中的机器学习算法需要经常调整。因此,数据科学家需要找到一种高效的方法来处理大量数据,并自动化这一过程。**批处理**和**实时处理**是这方面的两个重要概念。它有助于以批处理(每日更新)或实时内容的方式向数据仓库交付数据输入。数据科学团队的一个职能是监控开发模型。因此,想要处理流数据的数据科学家需要熟悉 Spark 或 Hadoop 等大数据工具。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4fa90afa51bc7ee46c79cc014c750bca.png)

Spark 最初发布于 2014 年 5 月 26 日。[来源](https://en.wikipedia.org/wiki/Apache_Spark)

当从外部收集数据时,需要不断地重新评估数据集的相关性和可信度。没有确定最佳数据源的公式。这更像是探索未知的旅程,是数据科学过程中最有趣的部分。下面是我做的几个项目中的几个例子,来说明迷人的数据是如何引导我们的。

**场景 1** :一家非营利公司想了解孩子们如何学习实施他们的在线课程。从 PBS Kids Measure Up 等基于游戏的学习应用程序中收集数据!可能是个好主意。分析玩家的线性学习路径、他们对每个科目的专注程度以及他们在不同评估中的表现有助于改进教学方法。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c3b13b179c6ed5f7df7d6f7264a2b725.png)

孩子们倾向于选择位于屏幕中央的图像。资料来源: [Huy Bui](https://github.com/williamhuybui/Predicting-Kids-Learning-Outcome-Through-PBSKidsMeasureUp-app-Flatiron-School-Capstone-Project)

**场景 2** :一位石油和天然气客户希望了解机器学习如何帮助他们的石油和天然气公司。检测美国管道事故,并向他们展示 ML 如何防止设备故障,将激励客户投资该项目。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ac1c87fefd2b3b3f80245a211e654e90.png)

每个州的净损失都是由与石油相关的灾难造成的。来源: [Huy Bui](/rolling-in-the-deep-589f3460960f)

同样值得了解的是,数百万个数据点是如何存储的,以及我们如何安全地维护它们。亚马逊 S3 是目前最受欢迎的云服务。亚马逊 S3 将数据存储在多个位置,以便在事故发生时提供备份。出于安全目的,亚马逊 S3 可以定制不同级别的访问权限。您还可以控制日志历史记录、定义警报和自动化工作流,而无需管理额外的基础架构。最棒的是亚马逊 S3 连接了许多其他最先进的机器学习工具,与其他编程语言高度可比。

# III)评估指标

我们如何知道我们的策略是否有效?数据科学家需要考虑两个指标:

## 机器学习指标:

当想到指标时,我们通常会想到准确性、MSE、F1、kappa Cohen……然而,在这篇文章中,我将强调具有更多商业意义的指标。成本和精度的权衡。例如:

在二进制分类问题中,如果我们想预测设备故障,假设错误分类负面样本(不知道故障设备)的成本是错误分类正面样本(派技术人员检查状况良好的设备)的三倍以上,哪个模型的成本最低,召回率至少为 60%?

要回答这个问题,我们需要使用混淆矩阵,计算什么是假阳性和假阴性的阈值。通过与领域专家的交流了解每个错误预测的成本在利用机器学习方面发挥着重要作用。

## 2.业务指标。

**KPI**代表**关键绩效指标**。KPI 应该对每一个业务层面都是全面的,并且在任何项目的初始阶段之前就已经预先定义好了。一些关键绩效指标可能包括:提高客户满意度超过 7/10 或减少 20%的劳动力成本。选择正确的 KPI 依赖于对组织的重要性的良好理解。有很多不同的 KPI,但是我们需要知道的两个 KPI:**业务流程(BP)KPI**和**数据科学(DS)KPI**。为数据科学项目制定指标的流程通常首先从 BP KPIs 开始,然后转化为 DS KPIs。例如,如果 BP KPI 是将垃圾邮件的投诉减少一半,那么当转换为 DS KPI 时,我们的目标是将误报率降低到 x%。

理解项目的目标对于项目经理和数据科学家来说都很重要。数据科学项目不成功的标志是问题太广泛,无法解决,无助于业务,或者需要很长时间才能完成。需要有一个标准的程序来决定成功与否。一个流行的 KPI 标准是 **SMART。**这种型号被许多不同的行业广泛使用

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/779a0885285cad9fc4b1fc5d581f8682.png)

你也可以在这里阅读关于[敏捷方法](https://www.wrike.com/project-management-guide/project-management-basics/)的内容,它解释了关于项目管理的更多细节。

# III)算法选择

这是流程中最“数据科学”的部分。有两个主要步骤值得一提:**数据探索**和**机器学习**。

数据探索包括描述性统计、可视化和回答分析数据时出现的一系列逻辑问题。数据科学家不应该低估简单性。这一步中的许多商业洞察和发现,往往比应用机器学习有更多的好处。数据探索揭示隐藏的特征,并为特征工程打开新的思路。发现的一个例子是沃尔玛在假日周的需求分布:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c226e16bd3425db1584452986eab3fea.png)

资料来源:Huy Bui

数据被水平标准化。前三个节日有着相同的特点。消费者在超级碗、母亲节、父亲节前**消费很多。相比之下,消费者在新年和万圣节后花费更多的 T2。最后,平安夜**没有销售**,因为所有沃尔玛商店都关门了。**

下一步是选择正确的机器学习算法。一般来说,您选择的算法需要满足 DS KPI,并且是可解释的。

**选择合适的算法**:在本地大数据上训练多个算法并不容易。然而,云计算使这项任务变得非常容易。AWS 的 SageMaker Auto Pilot 是这项任务的主要工具之一。SageMaker Autopilot 自动检查原始数据,应用功能处理器,挑选最佳算法集,训练和调整多个模型,跟踪它们的性能,然后根据性能对模型进行排名,所有这些都只需几次点击。2020 年的数据科学家需要适应新技术,SageMaker 自动驾驶仪是你应该放在工具箱里的东西。

**可解释性**:在拥有了非常复杂的算法和高准确率之后,下一步就是通过用人类语言向项目经理解释你的机器学习算法来打动他们。数据科学家需要学习如何说服决定他们项目生命的人。理解利益相关者想要看到什么的一个方法是想象如果你是他们,你会问什么问题。想象一下,有人跟你说要买房子。他们会说什么来说服你?如果这个人能解释所有的因素,如房间数量、建造年份、位置、到最近超市的距离……并告诉你这些因素如何影响决策,这足以说服你吗?。在让机器学习变得可以理解的过程中,**特性重要性**是关键。展示机器学习模型如何为一个特征分配不同的权重,将使观众了解“黑盒”背后发生了什么。Parul Pandey[提到了三个重要因素来为 ML 模型带来透明度:](/interpretable-machine-learning-1dec0f2f3e6b)

*   最重要的特征是什么?
*   每个特征如何与单个预测相关联?
*   每个特征如何与多个预测相关联?

# IV)部署模型

当模型满足 KPI 标准时,数据科学家需要将其投入生产。因为各种不可预见的因素会对结果产生负面影响,所以总是比较 ML 模型和 KPI 是必要的。该模型需要定期调整,以适应数据特征的变化。有时,灾难(如冠状病毒)可能会完全改变趋势,你必须重新训练模型,甚至重复整个过程。AWS 提供了一项服务,我们可以监控性能,并在预测指标低于指定阈值时向您发送警报。

# 结论

数据科学中有许多主题,数据科学家只需要了解其中的几个。但是,市场是竞争的,需要适应性。理解技术的趋势并应用它们是对你的项目负责的好方法,有助于你在人群中脱颖而出。综上所述,有三件事我建议看一看:

*   业务 KPI 或[敏捷方法](https://www.wrike.com/project-management-guide/agile-methodology-basics/)
*   [火花](https://spark.apache.org/)
*   [AWS 贤者制造者](https://aws.amazon.com/sagemaker/)和自动驾驶仪

感谢您的阅读!

# 如何成为一名成功的博士生?

> 原文:<https://towardsdatascience.com/how-to-be-a-successful-phd-student-3f3a4eb48be8?source=collection_archive---------26----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ed7125eeb4f107235e4685df1b41b65b.png)

图片来自 [Unsplash](https://unsplash.com/photos/1VqHRwxcCCw) 。

## 博士生和早期职业研究者的最佳实践和成功原则

## 每当一个新的学生、实习生或研究助理加入我的实验室,我经常发现自己在重复我们实验室的许多最佳实践。最常见和最令人沮丧的事情之一是收到一封题为“亲爱的教授,请通读附件,截止日期是明天”的电子邮件。我在比利时安特卫普大学读博士的经历:在我目前的职位上,作为新加坡科技与设计大学[音频、音乐、情感计算和人工智能实验室(AMAAI)](https://dorienherremans.com/team) 的负责人,[科技与设计大学游戏实验室](http://gamelab.sutd.edu.sg)的主任,激励我为早期职业研究者写下一些最佳实践。

在过去的几年里,研究领域发生了很大的变化。我们通常不会花整个下午在图书馆的档案室里寻找那篇布满灰尘的文章。相反,通过无数的数字服务,我们的信息超载了,所有这些服务只需点击一个按钮就能提供高质量的手稿。随着这些技术的进步,博士生面临的挑战在过去十年里发生了巨大变化。此外,越来越多的学生选择读研,这使得找工作的竞争更加激烈,影响也更大。众所周知,这种竞争环境会给研究生带来心理压力。本文为现代博士生和研究人员提供了最佳实践或成功原则。请注意,这些来自我的个人经验,并不是绝对的真理。

作为一名成功的博士生,不仅仅需要发表论文。在整个研究生学习期间,与你的导师保持良好的关系是很重要的,同时做有影响力的出版,建立一个网络来利用你的工作,以及无数其他对你未来职业生涯至关重要的小事。我们将回顾一些简单的最佳实践,它们将帮助你成为一名优秀的博士生,给你的同事和导师留下深刻印象。

*   首先,找一个自己热爱的话题,努力去做。这样,下面所有的事情都会自然而然地发生在你身上。
*   不要给你的导师发这种太普通的邮件:“亲爱的教授,请通读附件,截止日期是明天”。在提交稿件之前,一定要提前提醒所有合作作者。虽然主管喜欢收到新论文(草稿)已经准备好的消息,但更好的方法是至少提前两周分享会议手稿,这样你的资深合著者就可以规划他们的时间。在期刊论文的情况下,需要更长的时间来适当地组织手稿和共同准备写作计划。
*   作为团队中的初级成员,与更高级的成员(最好是博士后)结对进行密切合作。虽然教授们很乐意帮助你,但他们在大学里有很多责任,由于时间限制,他们并不总是能够帮助低级编码和小决策。经常与这个人交流,并向你的主管报告更大的里程碑,以保持正确的研究方向。
*   在把你的手稿发送给导师或合作者之前,要彻底校对。参加学术写作课程,提高你的英语技能。如果英语不是你的第一语言,除了前者之外,利用校对服务或科技,使用像 **Grammarly** 这样的工具。这样你可以充分利用你教授的时间,毕竟,你希望他们给你研究输入,而不是花时间检查拼写。
*   手稿上列出的所有作者都需要对这项工作做出过重大贡献。这可以通过编码、构思、编辑、建议等等来实现。不要只把朋友作为合著者。此外,每个人都需要在提交前阅读最终版本的手稿。
*   如果你的手稿包含软件代码,让它可用,要么通过开源,要么通过有限许可(尽管开源会让你有更多的用户!).无论你是否在线提供你的代码,也要保留一个私有的库,与你所有的实验室同学共享。这将使你的队友能够利用你的工作。实验室应该是合作的,而不是竞争的。
*   预印还是不预印?由于传统出版渠道的缓慢周转和现代研究的快速发展。一旦你的手稿被接受,就提供预印本已经变得非常流行。预印本可以通过你所在大学提供的预印本服务发表,或者通过流行的预印本档案如 [ArXiv](https://arxiv.org/) 发表。然而,一旦你的手稿被出版商接受,就要在手稿的页脚清楚地注明原始引用信息。这样你就可以直接引用正确的(同行评议的)手稿。早期职业生涯的学生可能还没有意识到引用的重要性,但它们是推进你的科学生涯和证明你做有影响力的研究的关键。有人可能会说,一篇有 100 次引用的论文比一篇有 40 次引用的预印本和一篇有 60 次引用的论文要好。最后,一定要事先检查你的出版商是否允许你提供预印本。
*   在与你的研究主题相关的有影响力的期刊和会议上发表文章。虽然对此有很多争议,但如今许多大学使用的主要评估指标是出版物的(领域标准化)影响因子,如领先组织如 [Clarivate](https://clarivate.com/) 和 [Scopus](http://Scopus.com) 所定义的。在主要评估指标改变之前,高影响力出版将为你的职业发展创造最多的机会。在许多领域,会议主要是为了了解最新进展和建立网络,因此它们只需要简短的摘要。在计算机科学领域,情况有所不同,需要在会议上提交更长的论文。如果你决定为一个会议准备一篇论文,一定要事先检查它是否有[高核心排名:](http://portal.core.edu.au/conf-ranks/) A*是一个会议能获得的最有声望的排名。甚至当你在会议上发表你的工作时,考虑以后扩展论文,并向期刊提交更完整的研究。
*   为你的手稿使用协作写作工具。这将有助于从共同作者和联合写作会议的反馈。如果你是在一个比较技术性的领域,把你所有的稿子都写在 [LaTeX](http://www.latex-project.org) 里。LaTeX 提供了许多好处,包括容易的引用管理、稳定的工作环境(不会崩溃)、容易的交叉引用、自动标记和布局优化[ [1](#Xbaramidze2014latex) ]。协作撰写文章的在线工具包括背面的、 [Papeeria](https://papeeria.com/) 和 [Authorea](http://Authorea.com) 。
*   参加会议和网络。建立一个网络对于扩大你的合作和获得未来的工作机会是至关重要的!在会议上,你将了解到你所在领域的最新发展。如果你是志愿者,你经常可以免费进入。WikiCFP 是找到即将到来的会议的一种可能方式。
*   通过博客文章和学术网络分享你在社交网络上的研究,如 [Scopus](http://scopus.com) 、 [ORCID](https://orcid.org/0000-0001-8607-1640) 、[academia.edu](https://sutd.academia.edu/DorienHerremans)、[门德利](https://www.mendeley.com/profiles/dorien-herremans/)和 [researchgate](https://www.researchgate.net/profile/Dorien_Herremans) 和 [Twitter](https://twitter.com/dorienherremans) 。在媒体上写文章解释你的出版物也有助于把你的作品带出去。引用对你未来的职业生涯很重要,所以你需要把你的研究公之于众。
*   成为相关会议和期刊的审稿人。这将让你在你的领域的最新研究发表之前就能接触到它!当你审阅手稿时,提供详尽的评论(不仅仅是几句话)。记住,你自己的手稿也会被彻底审查。
*   加入专业组织,如 IEEE(工程)和 ACM(计算机科学)。这些将让你获得有价值的资源,如杂志、纸质档案和教程。
*   保持身心健康。锻炼有助于保持大脑的高度可塑性,也就是说,让你更容易学习新东西。
*   保持固定的办公时间。在 2019 年对 6300 名早期职业研究人员的调查中[ [7](#Xwoolston2019phds) ,他们中的许多人指出了工作与生活平衡的问题。经常有学生在一天结束时开始他们的研究,就像他们在攻读本科学位一样。这个在研究生院行不通。保持固定的办公时间也创造了一个结束时间,之后你可以出去放松而不会有负罪感。当然,你可能不得不保持更长的工作时间,尤其是在截止日期之前,但是严格的时间表会帮助你保持心理健康并尽早开始。
*   拥有你的项目。当你和你的主管见面时,带着所有完成的任务出现,理想的情况是,下一步已经想到或者已经开始。多读书,有创造力。不要期望你的主管给你一些预先考虑好的小任务。作为一名博士生意味着做研究,在文献中寻找空白,并解决这些问题。
*   回复邮件。它将促进协作,使工作更快,并帮助您更快地获得成功…

上面的列表远非详尽无遗,也没有假装提供适用于每个人的绝对真理,它们是基于作者的个人经验。希望这些建议能帮助你成为一名成功的研究人员。请在下面的评论中留下你自己的成功实践。

祝所有攻读博士学位的人好运!

# 参考

[1]维多利亚·巴拉米泽。用于技术写作的乳胶。*技术科学杂志* *与技术*,2(2):45–48,2014。

[2]安妮-玛丽·科里亚特。博士学位的价值不能仅仅由出版物来定义。*自然人类行为*,3(10):1007–1007,2019。

[3]克丘奇。是时候减少博士生的数量了,或者重新思考博士项目是如何运作的。*谈话*,2016 年第 18 期。

[4]基·埃里克森和阿瑟·F·克雷默。有氧运动对老年人认知和神经可塑性的影响。英国运动医学杂志,43(1):22–24,2009。

[5] Hossein Jenaabadi、Naser Nastiezaie 和 Hamideh Safarzaie。研究生学业倦怠、学业压力与学业自我效能感的关系。*新教育评论*,49(3):65–76,2017。

[6]肯德尔·鲍威尔。工作与生活的平衡:打破还是耗尽。*性质*,545(7654):375–377,2017。

7 克里斯·伍尔斯顿。博士:曲折的真相。*性质*,575(7782):403,2019。

# 如何做一个 AI 傻逼

> 原文:<https://towardsdatascience.com/how-to-be-an-ai-idiot-8559c65d91a8?source=collection_archive---------10----------------------->

## 7 种严重破坏你的机器学习项目的方法

上周,你和[憨豆先生一起经历了他的冒险](http://bit.ly/quaesita_mrbean),完成了基本的训练、验证和测试。从[的那个例子](http://bit.ly/quaesita_mrbean)中很自然地可以得出一些如何(不)成为 AI 白痴的规则,但让我明确地为你拼写出来。(如果它们听起来似曾相识,请节哀顺变。)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e97f416a03dd7d2939b05c9df82b7ca2.png)

图片:[来源](https://tenor.com/view/mr-bean-rowan-atkinson-funny-nose-tissue-in-the-nose-gif-15564255)。

# 故事到此为止

在上一集里,你扮演了憨豆先生耐心教授的角色。既然你越来越擅长,那就让你坚持下去吧。我经常说避免应用人工智能中最大陷阱的最好方法是永远不要忘记学习和教学的基础,所以我私下希望你永远保持憨豆先生教授的心态。

> 永远不要忘记学习和教学的基础!

三个阶段的快速提醒(在[上一篇文章](http://bit.ly/quaesita_mrbean)中有更详细的解释):

*   **训练阶段:**憨豆先生(你心爱的 AI 系统的占位符)在课堂上看到的例子中寻找模式,然后把这些模式变成模型(菜谱)。
*   **验证阶段:**看看憨豆先生的食谱在他没有明确研究的例子上表现如何。如果分数看起来不错,他就去考试,否则就重新开始训练阶段。
*   **考试阶段:**憨豆先生参加期末考试,学习是否允许去生产或者转专业。

训练阶段相当简单——你把例子塞给学生(把[数据](http://bit.ly/quaesita_hist)塞给机器学习[算法](http://bit.ly/quaesita_emperor)),并且大多抱着最好的希望(我只是半开玩笑)。点击了解更多关于它如何工作的信息[](http://bit.ly/quaesita_emperor)

在我们列出成为人工智能白痴的方法之前,让我们从你尊敬的教授的角度谈谈更微妙的阶段——验证和测试。

# 验证和测试之间的细微差别

如果你所关心的只是让不值得的学生不及格,你就不需要验证阶段。你需要的只是测试。可怜的憨豆先生训练,发现一个模式([这是一个愚蠢的模式](http://bit.ly/quaesita_mrbean)),冲向你的考试,考试失败,被数学专业开除。你抓住并处决了一个无知的人。干得好!

> 测试是关于守门的。只有有价值的人才能通过!测试让你免于发布糟糕的原型。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4673ca481178bd6e2e4dc1d79a7d353f.png)

一个好老师帮助学生进步。图片:[来源](https://www.gannett-cdn.com/presto/2019/07/09/USAT/95f3e51a-46d4-467c-9698-b8485e0a62c1-GettyImages-1005285232.jpg?crop=2120,1193,x1,y0&width=2120&height=1193&format=pjpg&auto=webp)。

但是你想帮助学生进步的愿望呢?你帮助他们变得更好的承诺呢?他们救赎和自我提升的机会在哪里?验证,那就是。

> 验证是关于救赎的。这是一个掸去灰尘再试一次的机会。验证允许你迭代出更好的原型。

如果你真的关心你的学生,当你发现他们对某个食谱的尝试是愚蠢的,但已经为时太晚,无法帮助他们时,你会感到难过。(关于期末考试本身。)你是什么,老师还是刽子手?

> 你是什么人,老师还是刽子手?

如果你的最终目标是培养合格有效的学生,你会希望提供练习题(来自验证数据集)来帮助你的学生在面对教授断头台之前提高。

# 如何不做 AI 傻逼

虽然人工智能项目的领导者可能有理由不知道他们的工程师和数据科学家处理的数学本质,但没有理由忘记学习和教学的基础。如果你曾经考虑过设置一个考试,你已经有了防止一些主要流程出错所需的大多数常识工具。这里有几个例子。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f8dad2fdb7e9474254fcacc4c7f214e7.png)

图片:[来源](https://i.kym-cdn.com/photos/images/newsfeed/000/129/577/How+About+No.jpg)。

## 永远不要忘记人工智能就是用例子来解释

如果你的例子不好,你应该感到难过。如果你不给学生足够多的高质量的例子来学习,你怎么能指望他们有效地学习呢?哦,如果你给你的学生[有偏见的例子](http://bit.ly/quaesita_aibias),你会得到一个有偏见的学生。那是你的错,教授。

## 不要根据测试数据进行训练

那种考试如果靠死记硬背就能通过,对你没什么好处。机器学习是为了在新的例子上取得成功——如果你只关心在旧的东西上表现良好,那么跳过 ML/AI 的头痛问题,使用查找表。为了保证你评估的是正确的事情(对新数据的表现)而不是记忆旧数据的能力,确保你的学生没有机会学习(呃,记忆)你的任何测试示例。

永远不要把培训或验证数据放在期末考试上,这只会降低你正确测试学生的能力。(哦,我有没有提到电脑是有史以来最好的记忆者?)

## 永远不要混淆你的数据集

如果你没有在开始之前仔细管理和拆分你的数据*,你将如何防止上述问题?[数据分割](http://bit.ly/quaesita_sydd)是最好的数据科学快速解决方案。在开始教学生之前,请确保将测试示例锁在一个安全的地方。*

## 在你设定考试标准之前,永远不要测试你的学生

即将面对 palm?停下你的手!虽然这一点似乎太明显而不值得一提,但你会惊讶地发现,领导力薄弱的真实项目团队经常进行测试,然后在测试后改变目标,因此无论如何,他们学生的分数最终都足够好。不要这样。(点击了解更多[。)](http://bit.ly/quaesita_dmguide)

## 永远不要重用测试数据

如果你忍不住对那些挑剔的统计学家们不屑一顾,他们坚持认为你不能使用一个测试数据集超过一次,让我们试着用不同的方式来说:“如果你给同一个学生两次相同的期末考试,不要相信他们第二次的表现。”考题不要重复使用!

## 永远不要跳过测试

测试将你从灾难中拯救出来。这是你对批准有毒原型的保护。如果你真的不在乎它(例如,如果你正在制作艺术作品),鼓起勇气把你的最低要求性能指标设为-inf。没有吗?好的,[那就好好测试一下](http://bit.ly/quaesita_donttrust)。

## 永远不要太相信自己

还有一个薄弱环节:你,教授。如果你没有意识到自己考得不好怎么办?它可能发生在我们当中最好的人身上。确保建立一些安全网,以防万一,让这个世界远离你刚毕业的学生。

# 如何做一个 AI 傻逼

当团队缺乏熟练的人工智能领导时,或者当他们过于沉迷于工程的本质时,他们的常识可能会被抛弃。他们可能看不到基本的东西,最终发布了非常糟糕的解决方案。我在现实生活中看到的几乎每一个令人讨厌的人工智能灾难都可以追溯到上面列表中的一个项目,所以如果你在寻找人工智能傻瓜帽,我给了你一个不错的错误列表供你选择,请自便!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7babdb8ab8f87199e83f3a76591bf7e4.png)

但是如果你更喜欢构建好的、有用的、有效的人工智能解决方案,那么就要时刻记住教授的观点。挪过去,机器学习……是时候考虑机器教学了!

# 感谢阅读!人工智能课程怎么样?

如果你在这里玩得开心,并且你正在寻找一个为初学者和专家设计的有趣的应用人工智能课程,这里有一个我为你制作的娱乐课程:

在这里欣赏整个课程播放列表:[bit.ly/machinefriend](http://bit.ly/machinefriend)

# 如何成为一名高效的数据科学家/研究员

> 原文:<https://towardsdatascience.com/how-to-be-an-effective-data-scientist-researcher-9fbfffe8d8d1?source=collection_archive---------23----------------------->

## 做正确的事情

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6853a3aaae4e0c7be209890268bc4e7f.png)

照片通过 [Pixabay](https://pixabay.com/photos/alarm-clock-coffee-cup-time-of-2132264/)

多年来,我参与了许多数据科学项目。我记得很容易迷路,在错误的方向上浪费了很多精力。随着时间的推移,我学会了什么对我更有效。这份清单是我尽力总结出来的:

1.  **先建一条工作管道**

虽然先从很酷的东西开始很有诱惑力,但是你要确保不要把时间花在一些小的技术上,比如加载数据、特征提取等等。我喜欢从一个非常基本的管道开始,但是一个有效的管道,也就是说,我可以端到端地运行它并得到结果。后来,我扩展了每一部分,同时保持管道工作。你可以在这里了解更多信息:

[](/5-reasons-logistic-regression-should-be-the-first-thing-you-learn-when-become-a-data-scientist-fcaae46605c4) [## 成为数据科学家的第一件事应该是学习“逻辑回归”的 5 个理由

### 学习逻辑回归首先要熟悉流水线,不要被花哨的算法淹没。

towardsdatascience.com](/5-reasons-logistic-regression-should-be-the-first-thing-you-learn-when-become-a-data-scientist-fcaae46605c4) 

**2。一次从简单和复杂的事情开始**

一旦你有了一个可用的管道,开始扩展和改进它。你必须一步一步来。理解什么导致了什么是非常重要的。如果你一次引入太多的变化,很难判断每个变化是如何影响整个模型的。尽可能保持更新的简单和整洁。不仅更容易理解它的效果,而且一旦你有了新的想法,重构它也更容易。

总结这两个主题,我推荐阅读这篇安德烈·卡帕迪的帖子,它主要是关于神经网络的,但其中一些步骤对任何模型都是正确的:

 [## 训练神经网络的方法

### 几周前,我发表了一篇关于“最常见的神经网络错误”的推文,列出了一些常见的问题,涉及…

karpathy.github.io](http://karpathy.github.io/2019/04/25/recipe/) 

**3。质疑一切**

现在你有很多事情要做,你有一个工作流程,并且你已经做了一些改变来改善你的结果。理解为什么很重要。如果你增加了一个新的特征,它帮助模型更好地概括,为什么?如果没有,为什么没有?也许你的模型比以前慢了,为什么?你确定你的每个特性/模块都像你想的那样工作吗?如果不是,发生了什么?

这类问题应该在你工作的时候出现在你的脑海里。为了得到一个非常好的结果,你必须理解你的模型中发生的一切。

**4。体验多,体验快**

在你质疑了一切之后,你陷入了…嗯,很多问题。回答这些问题的最好方法是实验。如果您已经做到了这一步,那么您已经有了一个工作管道和一个写得很好的代码,所以进行实验不应该浪费您太多的时间。理想情况下,你可以同时进行多个实验,这将帮助你回答问题,提高你对什么可行什么不可行的直觉。

实验内容:添加/删除特征,改变超参数(不仅仅是神经网络!矢量化参数、标准化或特征选择技术也是您需要调整的模型的超参数)、改变架构、添加/删除数据等等。

**5。分清轻重缓急,集中精力**

在这一点上,你做了很多工作,你有很多问题,一些答案,一些其他的任务,可能还有一些新的想法来改进你的模型(或者甚至是做一些完全不同的事情)。

但并非所有这些都同等重要。你要明白什么是对你最有利的方向。也许你想出了一个绝妙的主意,稍微改进了你的模型,但也使它变得更加复杂和缓慢,你应该继续这个方向吗?这取决于你的目标。如果你的目标是发布一个最先进的解决方案,也许是的。但是如果你的目标是将一个快速下降的模型部署到产品中,那么你可以将时间投入到其他事情上。工作的时候要记住自己的最终目标,努力理解什么任务/实验会让你更接近它。

**6。相信你的指标**

如前所述,了解什么可行,什么不可行非常重要。但是你怎么知道什么时候有用呢?您根据一些验证/测试数据评估您的结果,并获得一些度量!你必须相信这个标准!可能有一些理由不相信你的指标。例如,它可能是错误的。您的数据可能是不平衡的,因此准确性可能是您的错误指标。你的最终解决方案必须非常精确,所以也许你对精确比回忆更感兴趣。你的衡量标准必须反映出你想要达到的目标。另一个不相信你的度量标准的原因是当你的测试数据不干净或者有噪音的时候。也许你从网上的某个地方得到了数据,但你不知道那里到底有什么?

一个可靠的衡量标准对快速进步很重要,但是衡量标准反映你的目标也很重要。在数据科学中,我们可能很容易说服自己,我们的模型是好的,而实际上,它做得很少。

你可以在这里阅读更多关于我们如何欺骗自己相信我们的模型是好的,但实际上不是:

[](/how-to-lie-with-data-science-5090f3891d9c) [## 如何与数据科学撒谎

### 最近,我读了达雷尔·赫夫写的《如何用统计撒谎》一书。这本书讲述了如何利用统计学来…

towardsdatascience.com](/how-to-lie-with-data-science-5090f3891d9c) 

**7。发布/部署工作**

反馈是任何工作必不可少的一部分,数据科学也不例外。当你知道你的代码会被其他人审查时,你会写出更好的代码。当你工作时知道你需要向别人解释,你会理解得更好。它不必是一个花哨的期刊或会议或公司生产代码。如果你正在做一个个人项目,把它开源,写一篇关于它的文章,发给你的朋友,向全世界展示它!

并非所有的反馈都是积极的,但是你可以从中学习,并随着时间的推移不断提高。

**8。大量阅读并保持更新**

我可能不是第一个建议跟上最新进展以提高效率的人,所以与其谈论它,我只告诉你我是怎么做的——好的旧时事通讯!我发现他们非常有用,因为他们基本上是跟上最新文学的人,挑选最好的东西并发送给你!

一些例子:

*   数据科学周刊快讯【https://www.datascienceweekly.org/】——
*   塞巴斯蒂安·路德报道的 NLP 新闻—[http://newsletter.ruder.io/](http://newsletter.ruder.io/)
*   https://www.deeplearning.ai/thebatch/[吴恩达](https://www.deeplearning.ai/thebatch/)的那批

**9。好奇**

当阅读最新最酷的东西时,不要把自己局限在你感兴趣的领域,试着去探索其他(但相关的)领域。这在几个方面可能是有益的。你可以找到一种在一个领域有用的技术,这种技术在你的领域非常有用,你可以提高理解复杂想法的能力,你还可以找到另一个你感兴趣的领域,这样你就可以扩展你的技能和知识。

**结论**

如果你有效率,你会得到更好的结果并享受这个过程。虽然以上所有的话题都很重要,但如果我必须选择一个,那就是“优先和专注”。对我来说,所有其他的话题最终都会指向这个话题。成功的关键是做正确的事情。

# 作为一名数据科学家,如何应对 Docker 的危险

> 原文:<https://towardsdatascience.com/how-to-be-dangerous-with-docker-as-a-data-scientist-b9cf7153a206?source=collection_archive---------40----------------------->

## 您需要了解的术语、语法和 CLI 命令将您的项目提升到一个新的水平

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/219769bf878073db8121b785b3f1d86b.png)

来源:[https://www . docker . com/sites/default/files/D8/2019-07/horizontal-logo-monochronous-white . png](https://www.docker.com/sites/default/files/d8/2019-07/horizontal-logo-monochromatic-white.png)

Docker 将允许您打包并在任何地方部署您的数据科学解决方案(通常迁移到云中)。它可能是数据科学工具 bet 中的一个重要工具,可以将数据科学工作从理论和研究转变为实践,并为您的业务增值。

# Docker 是什么?

点击[这里](https://en.wikipedia.org/wiki/Docker_(software))查看来自维基百科的无聊的正式定义。然后继续我下面的描述。

> Docker 可以让你捆绑你的代码在一个完全可复制的环境中运行所需的一切,这个环境很容易带到其他机器上*(比如在云中运行)*。Docker *(以及像 Kubernetes 这样的容器管理系统)*将这些包相互隔离。这带来了额外的可靠性和安全性,因为如果我的代码被黑客攻击或崩溃,它不会影响你的代码。

那么 Docker 像虚拟机吗?

**是的,有点**。在互联网上了解 docker 很多的人会告诉你*它实际上不像一个虚拟机*因为一些令人困惑的计算机术语。然而,这是一个有用的类比。您可以在同一台电脑上运行多个不同的、完全隔离的应用程序。有了虚拟机,每个新应用程序都有了完整的操作系统;而 docker 只带你需要的东西。这是它轻量级、可伸缩、甚至更安全的原因。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e626715f1591714714175abbfab02dd7.png)

Docker 和虚拟机之间的架构差异

# 开始时你需要知道的

*   术语
*   流行的 Dockerfile 文件步骤
*   常见 CLI 命令

# 术语

**Dockerfile**
这只是一个文本文件,包含了构建 docker 映像的具体说明。使用该文件的一些常见操作包括:指定基本映像、复制所需文件、定义环境变量、安装第三方包,以及编写从该映像启动容器时将运行的默认命令。

**图像**
从 Dockerfiles 创建一个图像*,并用于*创建 Docker 容器*。图像一般存储在 Dockerhub ( [public](https://hub.docker.com/) )、Elastic Container Registry([AWS](https://aws.amazon.com/ecr/))和 Artifactory ( [other](https://cglcloud.jfrog.io/cglcloud/webapp/#/home) )这样的存储库中。*

容器这是实际完成工作的地方。创建新容器将运行您的代码。一些 docker 容器被构建为运行一段时间&之后关闭(如培训作业或数据处理作业);其他的已经启动并永远保持运行(像 web 服务、API 端点、web 应用仪表板)。

> 如果你熟悉面向对象编程,那么“图像”就像一个类定义,而“容器”则是那个类的一个实例。一旦你有了一个类定义,你可以创建任意多的类实例。

**注册表**
想到一个 GitHub 的储存库,但是对于 Docker 图片。您可以在本地使用 docker 文件来创建图像。一旦你完成了这些图像的开发,你可以把它们推到一个注册中心,在那里它们将启动容器,或者其他人可以把它作为他们项目的基础图像。

这是每当从映像启动容器时运行的 CLI 命令。它通常由 docker 文件末尾的`ENTRYPOINT`或`CMD`步骤指定,或者从基本映像继承。您希望该命令启动完成任务所需的任何脚本或代码。([阅读更多](https://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/))

**标签**
这是一种给图片版本命名的方式。这有助于跟踪一段时间内图像的版本历史(类似于 git 标签如何提交);或者只是用一个简单的名称来引用该图像。([阅读更多](https://www.freecodecamp.org/news/an-introduction-to-docker-tags-9b5395636c2a/))

**基础映像**
这是 docker 映像的起点,通常在 docker 文件的`FROM`语句中定义。几乎所有的东西都有一个基础图像。任何映像都可以是另一个映像的基础映像,只要它可以从注册表中访问。最基本的基础映像只是一个操作系统。

*一些可能有用的基础图像*:

*   [R 闪亮带潮](https://hub.docker.com/r/rocker/shiny-verse/dockerfile)
*   [带 Conda 的蟒蛇皮](https://hub.docker.com/r/continuumio/miniconda/)
*   [阿尔卑斯山](https://hub.docker.com/_/alpine)
*   [AWS Lambda](https://hub.docker.com/r/lambci/lambda/)
*   [Debian Linux](https://hub.docker.com/_/debian)

# 流行的 Dockerfile 文件步骤

`FROM`
这个命令在每个 Dockerfile 文件中都有。它定义了您将要构建的基础映像。您必须能够访问包含基本映像的注册表。

这将把文件从你的本地机器(或者你正在构建映像的地方)复制到 docker 映像(以及随后的容器)。这些文件应该相对于当前工作目录,您将从该目录构建 docker 映像。

`ENV`
这个为你的 docker 容器设置 OS 环境变量 **注意:用这个代替* `*RUN export*`。([下面是为什么](https://stackoverflow.com/questions/33379393/docker-env-vs-run-export))

`RUN`
这将运行 OS CLI 命令。通常,这样做是为了编辑基本文件系统或安装第三方软件包。

`WORKDIR`
设置执行入口点或 CMD 的起始目录。

`ARG`
允许您通过`docker build`命令将参数传递到 docker 文件中。

`EXPOSE`
这公开了一个端口,世界可以通过运行容器的机器访问这个端口。如果您有一个 web 应用程序、仪表板或 API 端点,那么您需要公开一个端口。很多时候这已经由你的基本形象来完成了。

`ENTRYPOINT`或`CMD`
新容器启动时将运行的 CLI 命令。这应该调用您希望 docker 容器做的所有其他事情。

ENTRYPOINT 和 CMD 的区别在于 CMD 可以被覆盖,而 ENTRYPOINT 不能被覆盖。([阅读更多](https://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/))

无论如何 ENTRYPOINT 都会运行。CMD 既可以单独运行,也可以用于向 ENTRYPOINT 添加额外的参数。CMD 将指定一些缺省值,在容器启动时运行,但是该参数或命令可以通过`docker run`覆盖。

# 常见 CLI 命令

## Docker 构建命令

最简单的版本就是在当前目录下构建 docker file:
`docker build .`

接下来你可能想做的是添加一个标签(注册表&版本名):
`docker build -t localRegistryName:TagName .`

然后,您可能想用`ARG`将一些参数传递到 docker 文件中:

```
docker build \
    -t localRegistryName:TagName \
    --build-arg DEPLOY_ENV=dev \
    .
```

复杂应用程序的另一个选择是,您可能将 docker 文件隐藏在一个文件夹中,或者想要从父目录中复制一些文件。您可以指定`-f`作为 docker 文件的路径。

```
docker build \
    -t localRegistryName:TagName \
    --build-arg DEPLOY_ENV=dev \
    -f path/to/the/Dockerfile \
    .
```

## Docker 运行命令

从映像运行容器的最简单方法:
`docker run localRegistryName:TagName`

**端口映射** 

*注意:第一个 PORTNUM 是您想要映射到的本地机器上的端口,第二个 PORTNUM 是您想要查看的来自 docker 容器的公开端口。端口号可以不同,但这只会使事情变得混乱。*

用 Bash
调试另一件你可能想做的事情是用 CLI 探索你的容器。您可以这样做来检查诸如:*我的代码文件被正确复制了吗?环境变量定义正确吗?*
`docker run -it localRegistryName:TagName /bin/bash`

注意:要实现这一点,有几件事必须是真的。1)您的映像需要安装 bash。所以这不能在 windows 容器上工作。2)你需要用 CMD 代替 ENTRYPOINT。 `*/bin/bash*` *用于在 docker 容器启动时覆盖 CMD。入口点仍然会运行并阻止您运行 bash 的尝试。*

## 多方面的

您可以使用
`docker image ls`
`docker container ls`轻松列出您当前的所有图像或正在运行的容器

您可能忘记标记图像,或者您只想添加另一个标记。您可以通过引用其他标签或其图像 ID 将标签添加到图像中。*(可以通过列出所有图像找到图像 ID)*

`docker tag OldRegistry:OldTag NewRegistry:NewTag`或
或`docker tag b25r13lkj89 NewRegistry:NewTag`

您可以通过
`docker stop ContainerName`或`docker kill ContainerName`停止当前正在运行的集装箱

**清理你的系统**
有不同的方法可以删除旧图像来清理你的工作空间。

`docker rmi RegistryName:TagName`将删除 1 幅图像
`docker system prune`将删除所有未标记的图像&不与运行中的容器关联
`docker system prune -a`将删除所有内容

# 结论

对于许多数据科学家来说,Docker 有一条陡峭的学习曲线,但是一旦你越过了这条曲线,你就会极大地提高你的工作生产能力。

感谢阅读!
*如果有任何我需要补充或修改的地方,请在评论中告诉我,欢迎反馈!*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/acfdd90c6b455792fe0d80c69a91c3c8.png)

# 如何有效地找工作

> 原文:<https://towardsdatascience.com/how-to-be-effective-in-your-job-search-38881bf20e24?source=collection_archive---------24----------------------->

## 从 IBM 过渡到 myTomorrows 的经验教训

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f7d09af67150789a8403d0d0bfc19b4d.png)

克里斯汀·休姆在 [Unsplash](https://unsplash.com/collections/4972363/design?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

上周,我离开了 IBM,加入了一家名为 myTomorrows 的公司。在这篇文章中,我将分解我在寻找、发现和申请一份新工作时的决策过程,以帮助你寻找工作。我还会谈谈我是如何设法找到一份我认为自己会非常开心的工作的。这个故事对任何想得到自己想要的工作的人都有借鉴意义。

首先,我所说的工作类型是什么意思?正如我在[上周的文章](https://www.soyouwanttobeadatascientist.com/post/a-guide-to-choosing-the-right-data-science-position)中提到的,数据科学以各种形式和规模出现。仅仅是“数据科学家”这个头衔可能不会让你开心。你的工作包括你的职责、你做的项目类型、你与人交往的次数以及它可能变得有多忙/有多有压力。每个公司和每个职位都有不同的层次。这就是为什么上周我将数据科学职位分为六个类别,每个标准的水平相似。

# 为什么我想离开?

直到上周一,我还在咨询行业。我及时意识到,尽管我喜欢参与各种行业的各种项目,但我并不快乐。我有两个不开心的原因:我没有雄心去成长为顾问角色提供给我的方向,我对我在这个世界上的影响力不满意。

当然,这些都是非常主观的价值观。你必须决定,什么对你来说是重要的。一开始你可能会弄错,就像我一样。我以为做很多不同类型的项目会让我开心。但事实证明,对我来说,产生积极的影响比做各种各样的项目更重要。

意识到这一点后,我的第一反应是去 LinkedIn 和类似的网站寻找空缺职位。过了一会儿,我一无所获。我对自己的求职感觉不太好,我觉得自己没有取得任何进展。这时我意识到记住你的优先事项和理由的重要性。

# 求职

我离开的主要原因是,我没有任何在公司职业阶梯上往上爬的野心,而且这些项目没有让我满意。但当我开始找工作时,我又一次申请了我知道情况会非常相似的地方。我简直忘了,我想做的不是“尽快离开”,而是“找到一个更适合我需要和想要的职位”。这是许多人在找工作时犯的一个错误。只是要确保记住你最初为什么进入这个搜索,记住你的优先事项,不要把它们延伸得太远。

例如,如果你想成为一名数据科学家的原因是从事机器学习工作,不要仅仅因为头衔是“数据科学家”,就申请一份可能让你从事简单的仪表板构建工作的工作。你的精力最好花在申请对你有利的地方。

当我第二次意识到我申请的地方都不对时,我改变了策略。我采用了自上而下的方法。这一次,我写下了我对一份工作的期望。首先是必需品:

*   我想对人们的生活产生积极的影响

然后是富人:

*   我想在医疗保健或相关行业工作
*   我想要一个能让我学习的团队
*   我想接受挑战
*   我想承担多重责任,而不仅仅是数据处理
*   我想要一个小一点的公司,那里的事情不是很官僚

从这一点开始,我想确保我有效地利用了我的精力。我想知道的是:专门为对人们的生活产生积极影响而创建的公司有名字吗?首先想到的是非营利组织。但我知道也有一些营利性公司专注于对世界产生积极影响。

显然,他们有一个名字,叫做社会企业。我从 Ekaterina Stambolieva 那里了解到这一点,她是一家社会企业的创始人,也是播客的嘉宾之一。我们聊了聊我想要什么,我为什么想要它,以及我如何在社会企业或非营利组织中使用我的技能(在这种情况下是数据科学技能)。这次谈话节省了我很多时间和精力,因为它证实了我对进入非营利领域的怀疑。因此,我更关注社会企业。

如果你认识的人在和你想去的地方相似的地方工作,向他们伸出援手,询问他们的旅程。你会学到很多关于如何找工作的知识。这就是为什么我在播客上向我的嘉宾询问他们的职业生涯。

我的下一步是找出符合我必须拥有和必须拥有的公司,看看我是否认识在那家公司工作的人。在我找到几个人后,我介绍了我自己和我要找的东西。这里的关键是我保持了非常诚实的对话。我确保尽我所能做好自己。我没有发千篇一律的介绍信息。我全力以赴,考虑我在职业生涯中的位置、我想要什么以及他们能如何帮助我。

我相信找到一个能让你快乐的地方的唯一方法是在开始时尽可能多地展示你的本色。我想在一个不需要像完美的专业工作者那样摆姿势的地方工作,所以我确保我的电子邮件和信息听起来不像是公司的。当你申请的公司以同样的语气回复时,神奇的事情就发生了。这时你就知道找到匹配的了。如果你不能认同一家公司的基调、性格或氛围,就没有什么理由去尝试成为它的一部分。几乎可以肯定的是,当你开始的时候,你不会觉得你属于那里。

当然,如果对你来说,在高度专业化和公司化的环境中工作是非常重要的,那就表现出来。寻找能给你带来渴望的公司生活的地方。

# 评估适合度

我找工作的最后一步是评估我的选择。正如我之前在另一篇文章中提到的,在面试中提问是个好主意。这正是我所做的。我问了很多问题。我这样做不仅仅是为了表示我感兴趣。我真的很想知道答案,想知道我将会陷入什么样的境地。

当我准备我的问题时,我把我必须拥有的和应该拥有的牢记在心。我想知道公司的主要使命是什么、文化、公司的规模、他们的商业模式是什么(比如他们如何赚钱)、对我的期望是什么等等……这是重要的信息,让我最终决定是继续发展公司还是继续寻找机会。

求职总是被描绘成人们拼命找工作,而公司在其中随心所欲地选择工作。但我不这么认为,我认为你也应该改变找工作的心态。归根结底,你不能让公司来决定是否选择你。接受或拒绝一个潜在的职位也取决于你。你需要拥有这个决定。把它看作是试图满足你要求的公司,如果你找到一家确实符合你要求的公司,全力以赴,展示你最大的努力。

我整个找工作的过程花了很长时间,有比我在这里提到的更多的起伏,我有时感到绝望,无用和无助,但最后一切都解决了。上周二我已经开始了我的新工作,我感觉非常适合。

简单回顾一下:

*   确定你离开的原因
*   确定你的优先事项并坚持下去
*   对你必须拥有和想要拥有的东西有一个明确的想法
*   向在你羡慕的地方工作的人寻求帮助,询问他们的旅程
*   与你想去的公司沟通时,做你自己
*   客观地评估你的选择

我希望这篇文章能给你一些如何找工作的建议,帮助你找到一份让你开心的工作。不要忘记对自己诚实,每一步都要诚实。

👉*对数据科学领域以及如何开始学习感到困惑?* [*免费参加数据科学入门迷你课程*](https://www.soyouwanttobeadatascientist.com/courses/data-science-kick-starter-mini-course) *!*

# 如何用 Python 花式

> 原文:<https://towardsdatascience.com/how-to-be-fancy-with-python-8e4c53f47789?source=collection_archive---------3----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/95c3a8f6a6d25579c9e1bb9b79b22859.png)

Python 很酷。真的很酷。然而,我们中的许多人都是从不同的编程语言开始的,尽管我们很容易就学会了 Python,但我们仍然不擅长 Python 的做事方式。这篇文章介绍了我这些年来学到的一些技巧和实际例子。希望你喜欢它。

## 更新(2020 年 6 月 25 日):

最新的技巧在 [Github](https://github.com/dipam7/Fancy-python) 上。启动存储库,与他们保持联系。你也可以在 LinkedIn 上关注我的标签。

## -1.有用的键盘快捷键

缩进代码`Press Tab.`

取消代码`Press Shift + Tab.`

要注释或取消注释一堆代码,选择它并为 Mac 选择`Press Contrl + / or Command + /`。

要给某物加上引号,选择它,然后`Press Shift + ' or Shift + ".`

## 0.活力

Zip 可以用来一起遍历两个列表。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/17aa3bb7780ddd31283e4be7880b0a3a.png)

## 1.列出理解

Python 最棒的地方在于,你可以用如此少的代码完成如此多的工作。以列表理解为例。如果您想创建某个范围内的数字列表,您可以按如下方式轻松完成:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7abd2a55057816b1c8a62609fe15ee6d.png)

您还可以非常容易地对其应用条件。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2d268a8a29ec22292e9579d89d2415fe.png)

**实际例子:**

列表理解的一个非常酷的用例是将一个数字转换成它的单个数字。诀窍是将数字转换为字符串,迭代单个字符,将它们转换为 int 并存储在一个列表中。我们可以遵循所有的步骤

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f340a7323484475eb7eef309ed59698b.png)

或者一起做

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5bd8a17809e7fff0e403876164faabc0.png)

这也让我想起了 ***map()*** 的功能。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f14b9d50734a954c193bbcef8ca158cc.png)

## 2.使用*运算符

*运算符可用于重复字符串。举个例子,

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/78677cb4d9c070d1c91176108af356dc.png)

现在你可能不想打印很多次“Python 很酷”,但是你应该用它来做这样的事情

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e7c66bc737c640e5b720ca6c22c36bbd.png)

*操作符也可以用来解包列表之类的可重复项。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ae640d8f7cc1f6e23456820e0c7dcf05.png)

你也可以做一些像

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fccdda590a0e1c92e7efab1a1092716b.png)

当我们有一个事先不知道参数个数的函数时,通常使用这个操作符。我们将它与*args 和**kwargs 一起使用。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6c172b11bab1e2d1de4d2eec176598fa.png)

我们传递给函数的参数存储在*args 中。**kwargs 将存储命名参数或字典。

## 3.分音

您可以对函数做的其他事情是创建部分函数。它们是什么?假设我们有一个计算单利的函数。我们可以为一些参数设置默认值(从右到左)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/46a103e847ead54acddb67c7e7af09dd.png)

但是,我们不能以这种方式**仅设置 **p** 的默认值。**

我们可以使用部分函数来实现。在部分函数中,我们从左到右为一些参数设置默认值,然后将其用作函数。让我们只为 ***p*** 设置一个默认值。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c1de086b98c3b47e71baf5448a25fe55.png)

尽管分部从左到右工作,我们也可以通过使用命名参数跳过中间的参数。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/54674d424822dfeb1ef0a8d8acf35ef3.png)

## 4.维护

测试驱动开发意味着你写测试,然后你写代码通过这些测试。您可以使用 ***断言在 Python 中编写迷你测试。*** 例如,你可能想确定某个物体的形状是你所期望的。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e5f7a63cd192a11ffbc781f2e4341d78.png)

您也可以在逗号后编写自定义错误信息。编写这些小测试对于确保你的代码部分按预期工作非常有帮助。它还将帮助您高效地调试东西。

## 5.发电机

我们可以用 Python 中的 ***yield*** 关键字代替 ***return*** 关键字来创建一个生成器。使用生成器的好处是它可以即时生成东西,然后忘记它们。这样可以节省内存。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cc046180bf900f27674bbe4d3eeb8899.png)

这就是本文的全部内容。这是一项正在进行的工作。当我遇到更多的东西时,我会不断地添加到 Github 库中。如果你有任何让你生活更轻松的建议,请在下面的评论区提出来,我们都会从中受益。

~快乐学习。

# 如何在 Python 中熟练使用 OOP

> 原文:<https://towardsdatascience.com/how-to-be-fancy-with-python-part-2-70fab0a3e492?source=collection_archive---------6----------------------->

## 本文基于 Python 中的神奇方法,通过 Python 中的 OOP 让我们的生活变得更加轻松。希望你喜欢它。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/95c3a8f6a6d25579c9e1bb9b79b22859.png)

如果你不熟悉 Python 中的 OOP,我强烈推荐科里·斯查费的 YouTube 播放列表。

## 什么是魔术方法?

魔术方法是 python 中的特殊方法,以 2 个下划线开始和结束。它们也被称为 ***邓德*** 。我们在 Python 中做的很多事情都是在幕后使用 ***dunder 方法*** 完成的。看看下面的例子。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f2dd6304c80c56e581f670e798ece615.png)

很酷,不是吗?我们将为我们的类实现这些方法,使它们更加直观。让我们看看怎么做。

## 1.__init__()

第一个神奇的方法是 init 方法。在 Python 中,它被用作类的构造函数。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/26e4657e1ccc648957e16f558158abf8.png)

## 2.__str__()

当我们创建类的对象时,我们希望能够看到它们内部的内容。我们希望我们的类有一个人类可读的表示。这就是邓德海峡的用武之地。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/621c5335a1f95b3e884393cc560ed709.png)

还有另一个方法叫做 ***__repr__()*** 可以用来返回对象的状态,但是在本文中我们将跳过它。

## 3.__len__()

现在假设我们有一个存储学生详细信息的班级学校。我们想要一种简单的方法来统计学校的学生人数。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d0c9ac1004f519a045f3b6eb27f62e7f.png)

## 4.__getitem__()

我们还希望有一种简单的方法来访问特定学生的记录…

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5654f853cab3a25cd2267bd4a08cc114.png)

## 5.__setitem__()

…并编辑它们

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e4f552a88ecaae00e70a768736cac628.png)

## 6.__getattr__()和 __setattr__()

当您创建一个类来获取和设置其属性时,这些方法在 Python 中自动可用。因此我们不需要定义它们。然而,如果我们想改变他们的行为,我们可以这样做。

例如,我们可以修改***_ _ setattr _ _()***的行为,以便在设置属性时将其存储在一个列表中,这样我们就可以轻松地访问所有属性。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4cad2f0b7ff01195d3cbc0200390b06d.png)

## 7.__iter__()

我们可以使用 ***__iter__()*** 方法创建一个迭代器。然后我们可以用它一次访问一个学生。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f04f6991b7c2714012b2d42a7697b63e.png)

## 8.__ 加 _ _()等数学方法

假设我们有一个名为 Cost 的类。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cbfd98f829bdf268ae0aa1ca0fc315c3.png)

能够对这些物体进行数学运算是有意义的。这将使我们的代码更加直观和优雅。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e32614732189859550eb50d0a86ccf56.png)

## 结论:

这些是我发现非常有用的一些简单的 dunder 方法。如果你想了解更多,下面列出了一些你可以研究的方法。如果你有任何建议,请在评论中提出来,我会把它们写进文章里。

## `More methods`

*   `__new__`
*   `__del__`
*   `__enter__`
*   `__exit__`

~快乐学习。

# 如何擅长算法?

> 原文:<https://towardsdatascience.com/how-to-be-good-at-algorithms-bb1dd19ab54b?source=collection_archive---------0----------------------->

## 我作为计算机科学本科生学习算法和数据结构的经历

如果你想让计算机做一件事,你必须告诉计算机怎么做。你必须编写一个计算机程序,一步一步地解释它必须完成什么任务以及应该如何完成这些任务。这就是**算法**发挥作用的地方。

> 算法是计算机用来解决给定问题以达到最终目标的一组指令。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/edea9a3bf6f58f5883b0fa35244a9ce9.png)

图片来自 [Flickr](https://www.flickr.com/photos/byzantiumbooks/42712550880/) 的[比尔·史密斯](https://www.flickr.com/photos/byzantiumbooks/)

根据我的经验,学习算法对于设计和开发高效的计算机程序至关重要。在这篇文章中,我想与你分享我在本科学习算法的经历,以及它如何让我在职业生涯和学术工作中受益。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c065247bb1df7914f36138e6a775bd08.png)

来自 [Pixabay](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=924920) 的 [StockSnap](https://pixabay.com/users/StockSnap-894430/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=924920) 图片

# 初次相遇

我在中学的时候开始编程,是用 Visual Basic,制作计算器和交通灯模拟器。后来,我学习了 HTML 和 Java。那时,我开发桌面应用程序和 web 应用程序。这仅仅是编码,有时我不知道底层的逻辑。

进入大学并选择计算机科学与工程作为我的专业后,我在第二年开始学习数据结构和算法。这是一门必修课,每个人都必须上。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f6fea756a4f119a308efc4afb5e564a3.png)

来自 [Pixabay](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=2344423) 的图片由[鲁迪和](https://pixabay.com/users/Skitterphoto-324082/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=2344423)彼得·斯基特里安拍摄

# 从程序员到软件工程师

数据结构和算法课程是我理解计算机编程的一个转折点,它让我更像一个软件工程师而不是程序员来思考。我为什么这样说呢?让我给你举几个例子。

## 示例 1:排序算法

假设我们正在制作一个在线购物应用程序。我们希望让用户以价格递增的顺序查看项目。为此,我们必须按价格对商品进行分类。作为一名程序员新手,我会将价格添加到一个记录了价格指数的数组(或列表)中,然后简单地调用数组的内置`sort()`方法。在`sort()`方法内部实际发生了什么?我以前申请的时候不知道具体的方法。

排序算法是大学数据结构和算法课程中首先教授的基本主题之一。

*   [插入排序](https://en.wikipedia.org/wiki/Insertion_sort)
*   [选择排序](https://en.wikipedia.org/wiki/Selection_sort)
*   [快速排序](https://en.wikipedia.org/wiki/Quicksort)
*   [冒泡排序](https://en.wikipedia.org/wiki/Bubble_sort)
*   [合并排序](https://en.wikipedia.org/wiki/Merge_sort)

在了解了不同的排序算法后,我意识到并不是每种排序算法都适合每项任务。它们具有不同的时间复杂度,并且随着数据的大小而变化。最重要的是,在开发应用程序时,它们的运行时间非常重要,即使只有几秒钟。此外,我还学习了**就地排序算法**(就地排序元素)和**非就地排序算法**(排序时需要额外的空间来存储元素)。这些事情让我深入思考,在考虑时间和内存限制的同时,我应该为特定的应用程序使用什么样的排序算法。

## 示例 2:解析数学表达式

当我们在计算器或 MS Excel 等电子表格软件的单元格中输入数学表达式时,它会自动计算并返回答案。你有没有想过这个表达式是如何被求值的?我们必须开发一个电子表格软件并实现一个表达式解析器。我就是在这里了解到流行的 [**调车场算法**](https://en.wikipedia.org/wiki/Shunting-yard_algorithm) 。它利用队列来存储值,利用堆栈来存储操作符。我了解了在数据结构和算法课程中学到的队列和堆栈数据结构的实际应用,并理解了这些选择背后的逻辑。在我自己实现了调车场算法后,我为自己感到非常自豪,尽管许多实现已经可用。😃

## 示例 3:使用列表、集合和字典

每当我需要存储一堆值时,我会使用一个列表。当时,我并不关心我是否需要保持订单或允许副本;我会简单地使用一个列表。在我学习了列表、集合和字典之后,我意识到这些可以用在不同的场景中,并且使用一个比另一个更能加速我的代码。例如,如果我想检查一个值的成员资格,在集合或字典中(花费常数时间)比使用列表(花费与列表长度成比例的时间)要快得多。此外,列表允许您保留重复项,而集合不允许重复项。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ad3d828095bbc4e07f735b2a38f5bcb2.png)

图片由[皮克斯拜](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=1327493)的 Gerd Altmann 提供

这是我开始从程序员转变为软件工程师的一些经历。当我改用合适的数据结构或更快的算法时,我的代码性能有了显著的提高。

# 如何入门?

## 学习编程概念

在学习计算机科学中的算法之前,我对编程概念有很好的理解,比如变量、函数、类,尤其是面向对象编程(OOP)的概念。这些概念是理解计算机科学中更高级概念的基础。

## 学习和理解算法及其概念

除了我的课程材料,我还遵循了我们推荐的教科书 [**托马斯·h·科尔曼、查尔斯·e·莱瑟森、罗纳德·里维斯特和克利福德·斯坦**](https://en.wikipedia.org/wiki/Introduction_to_Algorithms)的《算法导论》。您可以从基础开始,例如

*   时间和空间复杂性分析
*   大 O 符号
*   递归
*   数组、矩阵、链表、栈、队列、树等基本数据结构。
*   基本算法,如搜索算法和排序算法。

为了分析算法,时间和空间复杂性分析是一个非常重要的主题。然后,您可以进入更高级的算法,如图形算法。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0eefde44191b3ea92fc4ca3c8680ba68.png)

图片来自 [Pixabay](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=1052010) 的 [Dariusz Sankowski](https://pixabay.com/users/DariuszSankowski-1441456/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=1052010)

要记住的最重要的事情是,你必须清楚地理解算法内部发生了什么。我曾经举一些简单的例子,应用算法,看看每一步会发生什么。算出例子帮助我更好地理解算法中发生了什么,我从来不需要记忆算法。如果我被要求为一个算法写一个伪代码,我可以很容易地联系到一个例子并计算出来,而不是必须精确地记住每一步。

## 用代码弄脏你的手

在我们的课程中,我们被要求用它们的基本操作从零开始实现不同的数据结构。我还记得用 C++实现二分搜索法树(BST)时的操作,包括插入、删除、搜索、前序遍历、后序遍历和无序遍历。我们必须创建一个 BST 类,并将所有这些操作作为函数来实现。我们甚至被要求用不同大小的数据集来比较某些操作的运行时间。这是一次很好的学习经历。我从这次练习中学到了很多,并对操作有了很好的理解。这些体验式学习过程帮助我更好地掌握了算法的概念。

可以开始用支持 OOP 的语言编码了。我发现下面的代码非常容易学习和编写。

*   C++
*   Java 语言(一种计算机语言,尤用于创建网站)
*   计算机编程语言

如果你是初学者,我会推荐你从这些语言中的一种开始。

# 学习资源

## 在线课程

您可以从以下网站学习在线课程

1.  [**Coursera**](https://www.coursera.org/) : [算法专门化](https://www.coursera.org/specializations/algorithms),[数据结构与算法专门化](https://www.coursera.org/specializations/data-structures-algorithms),[算法,第一部分](https://www.coursera.org/learn/algorithms-part1),[算法,第二部分](https://www.coursera.org/learn/algorithms-part2)
2.  [**麻省理工学院开放课件**](https://ocw.mit.edu/index.htm) : [算法介绍](https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/)
3.  [**可汗学院**](https://www.khanacademy.org/) : [算法](https://www.khanacademy.org/computing/computer-science/algorithms)
4.  [**Udacity**](https://www.udacity.com/) : [算法简介](https://www.udacity.com/course/intro-to-algorithms--cs215),[数据结构与算法简介](https://www.udacity.com/course/data-structures-and-algorithms-in-python--ud513),[数据结构与算法简介](https://www.udacity.com/course/data-structures-and-algorithms-nanodegree--nd256),[研究生算法简介](https://www.udacity.com/course/introduction-to-graduate-algorithms--ud401),[可计算性,复杂度&算法](https://www.udacity.com/course/computability-complexity-algorithms--ud061)
5.  [**edX**](https://www.edx.org) : [算法:设计与分析,第一部分](https://www.edx.org/course/algorithms-design-and-analysis),[算法:设计与分析,第二部分](https://www.edx.org/course/algorithms-design-and-analysis-part-2-2),[算法与数据结构](https://www.edx.org/micromasters/ucsandiegox-algorithms-and-data-structures),[算法设计与技术](https://www.edx.org/course/algorithmic-design-and-techniques),[算法设计与分析](https://www.edx.org/course/algorithm-design-and-analysis),[图形算法](https://www.edx.org/course/graph-algorithms)

以及更多的平台。你可以尝试提供的练习来获得更好的理解。

## 交互式算法可视化器

您可以尝试算法可视化平台,例如:

1.  [数据结构可视化](https://www.cs.usfca.edu/~galles/visualization/Algorithms.html)
2.  [算法可视化器](https://algorithm-visualizer.org/)
3.  [VisuAlgo](https://visualgo.net/)
4.  [排序算法动画| Toptal](https://www.toptal.com/developers/sorting-algorithms)
5.  [动画算法](http://www.algomation.com/)
6.  [算法动画和可视化](http://www.algoanim.ide.sk/)

可以在网上找到,并且了解算法是如何一步一步工作的。

## 编程挑战

理解了基础知识之后,你可以通过尝试编程挑战来实践你所学到的东西。以下平台提供了不同难度级别的非常好的挑战。

1.  [项目欧拉](https://projecteuler.net/)
2.  [黑客排名](https://www.hackerrank.com/)
3.  [厨师长](https://www.codechef.com/)
4.  [代码字节](https://www.coderbyte.com/)
5.  [练习](https://exercism.io/)
6.  [代码大战](https://www.codewars.com/)
7.  [LeetCode](https://leetcode.com/)

你练习得越多,理解得就越好。尝试编程挑战是学习如何应用所学理论解决问题的好方法。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3a6f4c0c3ccf32ddd06194fc7b261068.png)

图片由 [Lukas Bieri](https://pixabay.com/users/lukasbieri-4664461/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=2452808) 来自 [Pixabay](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=2452808)

# 包裹

作为这篇文章的总结,我想根据我学习算法的经验总结以下 10 条建议。

1.  对基础有很好的理解。
2.  清楚地理解算法中发生的事情。
3.  用例子算出算法的步骤。
4.  彻底理解复杂性分析。
5.  尝试自己实现算法。
6.  记下重要的事情,以便日后参考。
7.  遵循学习平台上的在线课程。
8.  关注知名大学发布的在线讲座。
9.  尝试编程挑战。
10.  如果你在编程挑战中遇到难题,不要气馁。你可以阅读他们的教程,了解挑战结束后你卡在了哪里。

# 进一步阅读

如果你想了解更多关于数据结构和算法的内容,你可以看看下面的文章。

[](/8-common-data-structures-every-programmer-must-know-171acf6a1a42) [## 每个程序员都必须知道的 8 种常见数据结构

### 数据结构是一种在计算机中组织和存储数据的专门方法,以这种方式我们可以执行…

towardsdatascience.com](/8-common-data-structures-every-programmer-must-know-171acf6a1a42) [](/10-graph-algorithms-visually-explained-e57faa1336f3) [## 直观解释的 10 种图形算法

### 10 种基本图形算法的快速介绍,包括示例和可视化

towardsdatascience.com](/10-graph-algorithms-visually-explained-e57faa1336f3) [](/heuristics-what-why-and-how-68aafc7e1e4b) [## 启发式什么为什么和如何?

### 启发式算法在算法开发中的理解和应用

towardsdatascience.com](/heuristics-what-why-and-how-68aafc7e1e4b) [](/self-balancing-binary-search-trees-101-fc4f51199e1d) [## 自平衡二分搜索法树 101

### 自平衡二分搜索法树简介

towardsdatascience.com](/self-balancing-binary-search-trees-101-fc4f51199e1d) [](/8-useful-tree-data-structures-worth-knowing-8532c7231e8c) [## 值得了解的 8 种有用的树数据结构

### 8 种不同树形数据结构的概述

towardsdatascience.com](/8-useful-tree-data-structures-worth-knowing-8532c7231e8c) [](/data-structures-in-c-part-1-b64613b0138d) [## C++中的数据结构—第 1 部分

### 在 C++中实现通用数据结构

towardsdatascience.com](/data-structures-in-c-part-1-b64613b0138d) 

# 最后的想法

别忘了,

> 熟能生巧!

希望这篇文章对你有所帮助和启发。让我知道你的想法。

感谢您的阅读!

干杯!

# 如何在数据实习中取得成功

> 原文:<https://towardsdatascience.com/how-to-be-successful-in-your-data-internship-6ed718003df3?source=collection_archive---------48----------------------->

## 顶级数据专业人士为实习生提供了如何最大限度地利用机会的建议

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b4f75fa2598d2b71018b43c262d6681e.png)

马文·迈耶在 [Unsplash](https://unsplash.com/s/photos/student?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

随着实习季节的到来,我们联系了一些 [Alteryx ACEs](https://community.alteryx.com/t5/ACE-Program/bd-p/ace-program) ,顶级分析专家和 Alteryx 社区[的参与者](http://community.alteryx.com),看看他们会给数据分析和数据科学领域的实习生提供什么建议。

你如何充分利用实习经历?在这个独一无二的机会中,从可用的人员和资源中学到了什么?这些数据专家就如何在实习中和以后取得成功提供了他们的观点。

## Jason Mack ( [@dataMack](https://community.alteryx.com/t5/user/viewprofilepage/user-id/2784) ),Cigna 的分析主管

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/53d65c17ce0c37704ec5de5b7d8d01a6.png)

作为一名实习生,你的主要精力应该放在建立一个能帮助你获得下一份全职工作的人际网络上,或者在未来的某个时候提供帮助。让人们记住你的一个好方法是为他们解决一些问题,即使这些问题看起来很简单或很小。例如,帮助他们巩固每周电子表格的 Alteryx 工作流:如果它将他们从一周中最无聊和最可怕的 20 分钟中拯救出来,你就改善了他们的生活,他们会记住你。

## 妮可·约翰逊( [@NicoleJohnson](https://community.alteryx.com/t5/user/viewprofilepage/user-id/3824) ),T-Mobile 的高级顾问

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/777d5d78141de649b110a0cc76ebc0b4.png)

你应该不断地问自己,“如果呢?”无论任务或任务是什么,或者即使你只是被要求做笔记和观察,除了实习的基本职责之外,你总能找到机会扩展你的技能。例如:

*   如果你是被问问题的人,而不是仅仅观察或被告知做什么和如何做,会怎么样?如果让你自己决定,你会怎么做?
*   如果下次数据没有这么干净怎么办?
*   如果条件改变了呢?您的解决方案将如何发展并适应不确定性和不断变化的参数?
*   如果你的新观点和好奇心正是避免潜在问题或提出创造性解决方案所需要的呢?

当得到一个实习机会时,把它想象成得到了城堡的钥匙——它可能会让你越过护城河,但你仍然需要打开一些门,探索一些走廊,然后才能找到真正的宝石!

## AJ Guisande ( [@aguisande](https://community.alteryx.com/t5/user/viewprofilepage/user-id/1536) ),决策科学公司的服务总监

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9db570877847829a90cd866679be75aa.png)

*   永远保持好奇心!
*   每天学点新东西!
*   每次都要鞭策自己!
*   完成/完成事情,即使它们并不完美。
*   对你的技能进行深思熟虑的练习。

## 乔·瑟皮斯([@约瑟夫·瑟皮斯](https://community.alteryx.com/t5/user/viewprofilepage/user-id/6503)),Keyrus 的高级顾问

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/12b0fa282f528f1ed63f650d22319bda.png)

我对实习充满热情,因为我自己的职业生涯是由两次实习开始的,我有幸参加了这两次实习。我能给的最好的建议是充分利用时间。在实习期间,参与并要求参与任何能让你在数据分析或数据科学方面获得更多经验的事情。作为一名曾经实习过并一直支持实习的数据专业人士,表现出你渴望学习是至关重要的,因为这意味着你可能会在实习期间获得更多机会。利用你在实习期间获得的关系,因为它们可以帮助介绍或推荐你在分析领域获得一个永久的职位或角色。最后,利用你的实习机会来帮助决定你是否喜欢从事数据分析或数据科学方面的职业。

## Mike Barone ( [@mbarone](https://community.alteryx.com/t5/user/viewprofilepage/user-id/369) ),Paychex 的数据科学家

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b948b7aba2c4c345dcb1ba11ea80defa.png)

做一些你没有被要求做的事情。当你与其他团队成员或你的下属合作或听取他们的意见时,倾听你可以提供的一些东西,比如使用他们还没有想到或尝试过的数据。但是不要跟他们提。提前 15 分钟进来;迟到 15 分钟。拿一些你认为你可以用相对较少的开销实现的、还没有被要求的东西。也许是一个很酷的可视化。也许是一个预测模型。也许是执行过程的自动化方式。如果你能向他们展示你不仅有专业知识,而且有创新和自己解决问题的主动性和动力,这将大大有助于“哇,我们必须让这个人参与进来”的因素!

## Andy Uttley ( [@andyuttley](https://community.alteryx.com/t5/user/viewprofilepage/user-id/11935) ),标枪集团的咨询经理

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/368b734d38ab1730c74dfd8975ce4daa.png)

我的建议是,试着把你的经历塑造成“浅而广”,而不是“窄而深”。我的意思是,我鼓励人们尽可能多地去体验,这是以一开始就过于“深入”任何话题为代价的。数据科学是一个巨大的领域;现在是确定你想专攻哪个领域的最佳时机,在选择你最想专攻的领域之前,实习是体验各方面的最佳方式。也要像关注技术技能一样关注人际关系。这些关系对你的持续学习和进步至关重要;你很快就会知道,每天的一部分就是给予和请求别人的帮助!

## Chris Lewis ( [@cplewis90](https://community.alteryx.com/t5/user/viewprofilepage/user-id/29561) ),全食超市高级数据分析师/Alteryx 团队负责人

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bb525c2c8995de867ee30fe834e37d61.png)

享受你实习的每一天,因为它会飞逝而过!我希望有机会做的一件事是让实习生了解企业可以做的不同类型的分析,以及这些类型的角色需要什么。如果你正在实习商业分析师,学习营销分析,房地产分析,金融分析,以及任何其他听起来有趣的领域!当您与其他分析团队交流时,了解影响业务的分析用例以及如何将分析应用于业务。与分析团队的业务合作伙伴交流,以了解业务运营方式及其运营的业务模式。我认为实习的最后一个好处是建立你的品牌,并理解不同的分析人员是如何建立他们的品牌的。

关于这个话题的更多信息,请务必查看[本周的《改变一切》播客](https://community.alteryx.com/t5/Alter-Everything-Podcast/69-Alteryx-your-way-ahead/ba-p/627177)集,由艾斯·希瑟·哈里斯和卡梅隆·安东内尔主演。他们讨论了卡梅伦如何获得数据分析实习,并利用它成功地启动了他的分析师职业生涯。

对于实习生和其他寻求数据分析和数据科学新机会的人来说,一定要看看 [ADAPT](http://www.alteryx.com/adapt) ,它提供免费培训和来自 Alteryx 和 Udacity 的证书。

**原载于** [**Alteryx 社区**](https://community.alteryx.com/t5/Alter-Nation/Tips-for-Success-in-Data-Internships-Advice-from-Alteryx-ACEs/ba-p/618086) **。在** [**Alteryx 数据科学门户**](https://community.alteryx.com/t5/Alteryx-Data-Science-Portal/ct-p/ds-portal) **上找到更多资源。**

# 如何成为贝氏

> 原文:<https://towardsdatascience.com/how-to-become-a-bayesian-fcaaf6302d68?source=collection_archive---------35----------------------->

## 概率论

## 频率主义者和贝叶斯统计的根本区别

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fb7d20426c8b71118d88b9d32187d191.png)

贝叶斯方法和频率主义方法的区别在于对概率的解释。照片由[上的](https://unsplash.com/@burst?utm_source=medium&utm_medium=referral)爆裂[未爆裂](https://unsplash.com?utm_source=medium&utm_medium=referral)

贝叶斯统计方法是频率主义方法的有力替代。在这篇文章中,我们将探索贝叶斯观点的基础,以及它如何与频率主义观点相区别。我们不会以纯技术的方式推导贝叶斯定理,而是试图理解其背后的原理。

一切都从概率开始。概率论是统计学和数据分析的基础。它已经是概率的定义,或者说观点,在这里,贝叶斯方法和频率主义方法分裂了。你可能会问,概率怎么会有不同的观点。毕竟概率应该是客观的,而不是主观的。这只是部分正确。假设你被要求为下面两个硬币投掷系列的结果分配一个概率(正面 H,反面 T):

*   T T T T T
*   H T T H T

这个问题没有很好的定义,可能会有歧义。如果你想计算确切序列的概率,你会得出这样的结论:每一个 *n* 次抛硬币的序列都有一个概率(1/2)^n,在这个例子中是 1/32。然而,在我们的日常生活中,我们可能会对连续 5 条尾巴的结果感到惊讶。也许我们更想回答这个问题:观察到一定数量尾部的概率是多少?这个问题可以用二项式分布来解决。第一个序列的概率是 1/32,第二个序列的概率是 10/32。突然,第二种结果的可能性增加了十倍。在这个例子中,你可以看到一个问题没有内在的概率,但是它总是必须被指定,并且可能取决于个人的观点,或者你想要回答的特定问题。在这里,我们甚至没有谈到隐含的假设,即我们正在使用一个公平的硬币,或者它可能会落在一边。

我们确定,概率的解释可能取决于你想回答的问题。这在频率主义者和贝叶斯方法之间有什么不同?

*   频率主义者将这种概率视为在大量试验中相对频率的极限。
*   贝叶斯认为概率是一个**的信任度**。

这是什么意思?假设你想推断一枚硬币出现正面的概率。一个典型的频率主义者在实验后得出的结论是:

> 在观察了 100 次抛硬币中的 58 次正面后,我估计观察到正面的概率是 58%。

贝叶斯可能会说:

> 从以前的经验来看,我们很可能有一个公平的硬币。在观察到 100 次抛硬币中有 58 次正面朝上后,我更新了先前的信念。现在最有可能的值是 54%。

为了更清楚地说明这种区别,我们将看另一个例子。

## 抽奖问题

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6bff1ea61cd4c7bd22443fd782359e7e.png)

乔·耶茨在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片

想象一下,你参加了一个抽奖活动,人们可能会购买一定数量的彩票,其中一些将会获奖。你想观察比赛一段时间,以估计你的胜算。你观察到 10 个人买了一张票,其中 5 个人赢了。按照频率主义者的方法,合理的中奖概率估计为 50%(你将自己的数据考虑在内,用 5 张中奖彩票除以 10 张已购买的彩票得出结论)。但是如果你只观察到一个人买了一张票并且这张票赢了呢?你估计获胜的可能性有多大?很明显,以前使用的直观方法不再有效,因为你可能从经验中知道 100%的胜率是非常不可能的。

我们如何将这些先验知识融入到我们的评估中?1772 年,大卫·休谟得出结论[1]:

> 因此,如果我们忙于论证,相信过去的经验,并把它作为我们未来判断的标准,那么这些论证就只能是或然的[……]

这意味着如果我们想用先验知识更新我们的数据,我们需要一个概率观点。在下文中,我们将推导出如何在贝叶斯框架内实现这一点。为了解决我们的抽彩问题,朝着正确方向迈出的一步是提出这样一个问题:给定一个模型,观察到我们的数据的概率是多少?为了做到这一点,我们首先要建立一个模型。

## 可能性

抽彩问题可以用二项式模型来描述,我们可以将观察到从以中奖机会为条件的 *N* 张已购买彩票中 *r* 张彩票中奖的概率写成:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b0264700acd7baca7bb5032d37cd4095.png)

二项分布

给定一个模型,我们的数据的概率称为**似然**。对于上面的两种情况( *N=10**r=5**N=1**r=1* ),可能性如下:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6b30f20ed4225492ae8ade9ebb5ff9d4.png)

抽彩问题两种情形的可能性

在第一种情况下,具有最高可能性的 *q* 的值是 *q=0.5* ,这也是我们根据频率估计得出的结果,而接近 0 或 1 的极值具有低值。对于第二种情况,对于 *q=1* ,可能性最高,但是 *q* 的较低值也具有非零可能性。**需要注意的是,可能性不是概率分布**。你可以很容易地看到,显示的可能性的面积小于 1。

## 贝叶斯定理

我们谈完了吗?不,在给定我们的模型 *p(* data *|q)* 的情况下,可能性给出我们数据的概率
,而不是概率分布。**我们*真正*想知道的是给定我们的数据 *p(q|* 数据 *)*** *我们的模型的概率。这两者之间的差别是巨大的。在给定数据的情况下,您希望选择概率最高的模型,而不是最能描述数据的模型。为了将可能性转换成概率分布,我们需要贝叶斯定理:*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bad7e360879adf9751d0abbd32729e94.png)

贝叶斯定理

*p(* 数据 *)* 称为*边际似然*,或*模型证据*。而 *p(q)* 称为先验。先验正是我们可以将先验知识引入等式的地方,它将 *p(q|* data *)* 与可能性区分开来。边际可能性是正态分布。

## 结论

我们看到,频率主义者和贝叶斯统计方法之间的根本区别在于对概率的解释。为了用贝叶斯方法思考,你必须调整你解释概率的方式。频率主义者将概率定义为长期频率,而贝叶斯主义者将其视为一种信任程度。这意味着贝叶斯特别开放,可以通过先验知识将先前的知识纳入他的计算中,还可以为只发生一次的事件分配概率。我希望这些概念能帮助你成为真正的贝叶斯主义者。

你可以在这里找到贝叶斯分析的完整例子。

[](/performing-a-bayesian-analysis-by-hand-c589ab992916) [## 手动执行贝叶斯分析

### 现实生活中贝叶斯分析的逐步演练

towardsdatascience.com](/performing-a-bayesian-analysis-by-hand-c589ab992916) 

## 进一步阅读:

埃德温·t·杰恩斯*概率论*

## 参考资料:

[1]大卫·休谟,*一个关于人类理解的调查*,1772 年

# 如何成为一个更好的讲故事者:3 个要点

> 原文:<https://towardsdatascience.com/how-to-become-a-better-storyteller-3-key-points-1a204fb3b18b?source=collection_archive---------70----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/18646217063ee153b171875e90b6b158.png)

*照片由* [*农旺*](https://unsplash.com/@californong?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) ** [*下*](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

## 伟大的电影、演讲和商业展示都有一个共同点:情感弧线。它如何给你的故事增添趣味?

*更新:这篇文章你可以在* [*乌克兰语*](https://temy.blog/2020/11/13/як-стати-кращим-казкарем-3-ключові-моме/) *(感谢卡特琳娜·莫什科拉!)*

你在正在进行的疫情中发起了一个[数字化转型](https://enterprisersproject.com/what-is-digital-transformation)的倡议。您对这项巨额投资感到非常兴奋,它有可能解决您的组织面临的远程工作挑战。

然而,执行委员会对你的发言反应冷淡。你发现业务团队不能分享你的兴奋。您的技术团队背负着多重优先任务,担心这会导致更多的工作压力。

我们不是经常发现自己处于这样的情况吗?

即使是最好的计划也会因为无效的沟通而失败。行业报告称,糟糕的内部沟通每年会给组织造成超过 370 亿美元的损失。然而,我们并没有把太多的注意力放在解决我们的沟通问题上。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e105341735ddd66dfae3e27311a0a8f3.png)

[Icons8 团队](https://unsplash.com/@icons8?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/communication?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

让我们来看看大片、明星产品发布和成功的营销活动之间的相似之处。通过清晰的例子,我们将讨论技术领导者如何转变为故事讲述者。

# 技术领导者能从专业的故事讲述者身上学到什么?

想象一下你最喜欢的电影。很可能你很久以前就看过了。但我敢打赌,它对你记忆犹新,就像你几周前看到的一样。是什么让这些电影如此令人难忘?

研究人员称,伟大的电影、演讲和商业展示之间有着更深层次的联系。这是情感弧线,也称为“故事的形状”情感弧线是故事中的一系列情感起伏,像过山车一样吸引着观众。

说书大师[分析](https://www.youtube.com/watch?v=oP3c1h8v2ZQ)通俗故事的形态,构建它们的情感弧线。一个挣扎中的男孩与他的女孩重聚的情节已经是老生常谈,但它从未失败过。还记得《风月俏佳人》或者《恋恋笔记本》吗?他们玩弄久经考验的“男孩得到女孩”的情感弧线

这是它的形状:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5f07b3ab4cad7c8e1d2fc92202cecf2e.png)

图片重现自[库尔特·冯内古特的演讲](https://www.youtube.com/watch?v=oP3c1h8v2ZQ)

看起来很简单吧?注意情绪在 y 轴上的变化。作为观众,当事情变得消极时,我们会咬指甲。我们为英雄欢呼,因为他再次站起来夺回女孩,再次提升情绪。

冯内古特重建了许多其他有趣故事的形状,包括我们这个时代最著名的故事之一——灰姑娘!所有这些的共性是什么?他们每一个人都用不同的情感弧线带领观众经历起起落落。

# 证明情感弧线重要性的证据

麻省理工学院的社交机器实验室和麦肯锡消费者技术团队[研究了数千个 Vimeo 视频](https://www.mckinsey.com/industries/technology-media-and-telecommunications/our-insights/ai-in-storytelling),使用高级分析建立了联系。

使用计算机视觉和音频分析的算法每秒钟为每个场景打分。在勾勒出每个故事的情感弧线后,他们使用机器学习将它们分成八个家庭。

该分析的最后一部分是引入结果——用户参与度指标,如“喜欢”和“评论”研究人员发现,由人工智能算法生成的故事情感弧线可以预测观众是否会喜欢它。

# 你如何运用情感弧线来改善领导沟通?

将讲故事融入你的沟通有三个步骤:

## 1.超越技术

想想一项技术接触到的受众。在谈论技术时,我们往往更关注它的功能。我们在涵盖“什么”和“如何”方面做得很好,但却忽略了“谁”和“为什么”

当史蒂夫·乔布斯介绍 iPod 时,他没有谈论它的酷工程或时髦的设计。相反,他告诉观众,他们现在可以在口袋里携带 1000 首歌曲。焦点完全集中在用户和他们的愿望上。

史蒂夫·乔布斯是一个讲科技故事的大师。他最大的成功来自于对客户以及为什么他们的需求没有得到满足的深刻理解。

与你的听众建立联系的旅程必须从首先想到他们开始。你的用户的需求和偏好是什么?他们是如何完成工作的,他们最糟糕的噩梦是什么?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9d6938675975a9891d0afb4f8c600e6f.png)

*Photo by* [*林信行*](https://www.flickr.com/photos/nobihaya/) *on Flickr*

## 2.超越事实

让观众体验各种可能性。套用玛娅·安杰洛的话,人们可能会忘记你说过的话,但他们会记得你带给他们的感受。通常,我们的交流是对事实的枯燥背诵,这就是为什么他们没有联系。

认知心理学家杰罗姆·布鲁纳(Jerome Bruner)说,以故事形式传递的信息比事实更令人难忘 22 倍。好的故事必须生动地描述故事展开时的场景。他们必须用传达强烈情感的语言来打动人。

例如,在启动您的数字化转型时,不要仅仅量化痛点。选择一个(虚构的)用户,向我们展示她的世界。解释这些挑战不仅会导致失去商业机会,还会让用户深感沮丧。

以英雄的身份介绍你的计划,这样你就能扭转乾坤。描述结果并展示它将如何让用户摆脱痛苦。

## 3.超越传统叙事

引入变化来建立情感弧线。有了观众的清晰图片和与他们联系的体验信息,现在通过玩弄其情感弧线来使故事变得有趣。正如一个音符有高潮和低谷,你必须在你的交流中引入变化。

暂停一会儿,想想你上一次的商业演示。它有什么变化吗?你刚刚把好消息和坏消息排序了吗?你是怎么得出这个结论的?

我们大部分的报告都是信息性的,但是顺序性的,而且…无聊。这些见解在逻辑上是合理的,但在情感上却没有联系。

将你的交流视为一系列的部分,就像小说的章节一样。在每一部分,引入悬念的元素,梳理出解决方案。反复重复这个结构来吸引你的观众。

最后,以生动的行动号召结束演讲,激励听众采取下一步行动。

# 情感弧线的概念适用于各种商务交流。

每当你想抓住观众的注意力并让他们付诸行动时,这三个步骤都会很方便。

此外,记住所有的故事都是通过迭代改进的。花时间制作和评论它们。在朋友、同伴和样本观众身上测试它们。详细反馈哪些工作有效,哪些地方需要改进。然后融入变化,从头再来一遍。

祝你好运,让你的商务沟通变得生动有趣。

*这篇文章最初是由* [*发表在*](https://enterprisersproject.com/article/2020/8/how-improve-storytelling) *企业家项目上。增加了插图。*

# 2020 年如何成为数据分析师

> 原文:<https://towardsdatascience.com/how-to-become-a-data-analyst-in-2020-209d2ed9d130?source=collection_archive---------4----------------------->

## 遵循这 5 个简单的步骤,向数据分析领域进行职业转型

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c5618d1b4e79f24ed191ac7fa2bc109c.png)

弗兰基·查马基在 [Unsplash](https://unsplash.com/s/photos/data?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

# 对数据分析师的需求大幅增加

截至 2020 年,许多公司都采用了大数据和数据分析技术。由于这一点,对数据分析师的需求正在飙升。事实上,**许多研究预测数据分析是未来的工作**。

在我详细介绍如何将职业转型到分析领域之前,我将为您细分一下这个领域。许多人对什么是数据分析领域有误解,它经常与数据科学领域混淆。虽然这两个领域经常有重叠,但数据科学家的工作前景不同于分析师。

在这篇文章中,我将涉及以下主题:

1.  谁是数据分析师,他们做什么?
2.  为什么要成为数据分析师?
3.  数据分析师和数据科学家有什么区别?
4.  怎样才能成为一名数据分析师?

在开始之前,我只想放一个免责声明——*本文包含* ***无*** ***附属链接*** *。我建议的所有课程要么来自我自己的经验,要么似乎有可以帮助你在数据分析领域获得坚实基础的内容。*

# ***谁是 da*** ta 分析师,他们是做什么的?

简单来说,数据分析师是一个分解复杂见解以获得某种意义的人。这些见解需要回答做出商业决策所必需的问题。

## 例子——一个汉堡故事

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8d861aa0572b4ca6ab3f00548cb883d3.png)

[伊利亚·马什科夫](https://unsplash.com/@mashkov?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/burger?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

XYZ 餐厅卖汉堡。他们想分析访问他们公司的顾客的总体行为。

他们还想深入了解光顾 ABC 餐厅(他们的竞争对手)的人的行为。

有了这些信息,他们希望能够**更好地定位他们的公司,并鼓励更多的人光顾他们的餐厅**,而不是他们竞争对手的餐厅。

***一个数据分析师的任务一看:***

为了响应这样的请求,数据分析师可以执行以下操作:

*   **根据现有数据分析光顾 XYZ 餐厅的顾客的总体行为**。这可以包括人口统计数据、客户客流量和客户收入数据。
*   **制作对比参观 ABC 餐厅和 XYZ 餐厅的顾客行为的图表**。

这些见解需要被翻译,并且应该能够回答有助于商业决策的问题。这些见解包括:

*   **估计每天光顾 XYZ 餐厅和 ABC 餐厅的消费者人数**。
*   访问 XYZ 餐厅和 ABC 餐厅的顾客的**估计收入或富裕程度明细**可以找到。
*   这可以提供关于每个公司如何定位的见解。
*   总的来说,会有更多的顾客光顾 XYZ 餐厅。然而,尽管顾客较少,**ABC 餐厅可能拥有更多购买力较高的高端顾客**。
*   人口统计的细分也可以解释很多关于光顾每家餐馆的人的情况。
*   例如,XYZ 餐厅可能会有更多带孩子的家庭选择在这里用餐。ABC 餐厅可能会有更多没有孩子的夫妇在这里用餐。

利用这些见解,XYZ 餐厅可以决定推出折扣价格来吸引客户群。他们还可以提供家庭折扣和儿童餐。最后,他们可以选择为他们的客户群制作**定向广告**。

这是一个非常简单的例子,但是概括了数据分析师的工作。分析师需要提出类似上述的见解,然后公司可以利用这些见解更好地了解他们的客户群。在此之后,他们可以想出不同的营销计划,以不同的方式定位他们的公司。

# 为什么要成为数据分析师?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ae5e9d94cffdf159967b7a8f1545f6f2.png)

照片由[艾米丽·莫特](https://unsplash.com/@emilymorter?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/why?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄

如果你是一个很好的沟通者,也是一个精通技术的人,那么数据分析是适合你的。

成为数据分析师所需的技能(将在下面解释)并不难获得。你不需要花费数年时间去攻读学位或学习。

你可以很容易地在网上学到你需要知道的一切——在一年之内,甚至几个月之内。

对数据分析师的需求也非常高,不需要花费数年的严格学习就可以轻松过渡到该领域。

也就是说,这个领域确实需要你不断学习。这是一个持续的学习过程——你需要有足够的领域知识,以及从数据中查询和获得洞察力的技术知识。

您将使用的技术工具因公司而异,这意味着您需要随时学习新的工具和技术。

# 数据分析师与数据科学家—有什么区别?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/261cf48623a5a49a6e3c0ab43f51d4cb.png)

布鲁斯·马斯在 [Unsplash](https://unsplash.com/s/photos/think?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

术语*数据科学家*和*数据分析师*经常互换使用。然而,这两个领域是不同的。数据分析师和数据科学家之间的主要区别在于:

**数据分析师不必创建机器学习模型**。

与数据科学家的工作类似,分析师从数据中获得洞察力,需要具备一些编程和统计背景。数据分析和可视化方面的知识是必要的。然而,在创建预测模型时,分析师不需要具备任何类型的知识。

# 如何成为一名数据分析师?

现在,我将分解你可以采取的步骤和你需要学习的东西,以便成为一名数据分析师。

## 编程;编排

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/376c6b2223d00d7da978dda7bb6dba8a.png)

由 [Arian Darvishi](https://unsplash.com/@arianismmm?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 在 [Unsplash](https://unsplash.com/s/photos/programming?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

你需要自学如何编码。作为一名数据分析师,你不需要像软件工程师那样了解很多编程知识。

然而,你需要知道足够多的编码来操作数据和提出见解。您需要学习创建简单的函数来清理数据。

有时,数据分析师使用编程语言来实现可视化,并从数据中提取意义。

分析师使用的两种主要语言包括 **R 和 Python** 。

r 是一种**统计语言**,一般被数据科学家和统计学家用来挖掘数据。Python 更像是一种**多功能语言**,几乎每个人都在使用——从软件工程师到数据科学家。

你可以选择其中一种语言,然后开始学习。你可以阅读[这篇](/how-to-learn-coding-for-data-science-28df2705dac9)我写的关于如何自学编程的文章。如果你想知道学习如何编程的最佳在线课程,你可以阅读这篇文章。

## 查询语言

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1e633551f96d5f3b097a4c5ced6b57f3.png)

照片由[卡斯帕·卡米尔·鲁宾](https://unsplash.com/@casparrubin?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/sql?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄

很多时候,分析师需要学习一种查询语言。根据您所在公司的类型,您可以使用关系型或非关系型数据库。

我的建议是学习像 MySQL 或 Oracle 这样的语言。即使你工作的公司使用 NoSQL 数据库,**一旦你掌握了基本知识,你就可以很容易地学会语法。**

我在 Udacity 上找到了[这个](https://www.udacity.com/course/sql-for-data-analysis--ud198)免费课程,当我试图学习 SQL 进行数据分析时,它真的帮了我大忙。

## 领域知识

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/05b4c755b967bc0f49c370fa355a9a8b.png)

[Adeolu Eletu](https://unsplash.com/@adeolueletu?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 在 [Unsplash](https://unsplash.com/s/photos/business?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

根据你想合作的公司类型,需要一些领域的专业知识。

数据分析师通常被雇佣来帮助公司做出更好的商业决策。因此,你需要掌握一些商业和营销领域的知识。

你可以找到很多为数据分析师教授商业分析或营销的在线课程。我将在这里列出其中的一些:

1.  [2020 年商业分析课程](https://www.udemy.com/course/best-data-science-business-analytics-course/)
2.  【2020 年商业智能分析课程
3.  【2020 年商业分析简介

商业领域的知识很重要,我希望在进入数据科学和分析领域之前能够学到这些知识。然而,这绝对是你可以在过程中学习的东西,并且比作为分析师所需的技术技能更容易掌握。

## 通讯技能

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/03fd8ff7cd02a0ecacb8f6066eb0899f.png)

照片由[优 X 创投](https://unsplash.com/@youxventures?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/business?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

这可以说是最重要的,但也是最被低估的分析师需要具备的技能。

数据分析师需要能够**以非技术人员能够理解的方式有效地传达他们的见解**。

从可用数据中提取有用信息后,分析师需要能够向利益相关者或客户解释这些见解。

客户并不真正关心你用来获得洞察力的工具或技术。他们想知道如何将你的见解转化为商业决策,以及它给公司带来了什么样的价值。

弥合技术人员和非技术人员之间差距的能力非常重要。你需要**以简单的方式展示你的发现**,并向客户解释你的分析如何让他们受益。

类似于获得领域经验,这些沟通技巧可以在过程中得到磨练。你只需要有耐心,并愿意学习。

以上,我列出了成为数据分析师需要自学的技能。

这些不是唯一的要求,因为你将需要获得使用 Tableau 等**可视化工具的经验,以制作图表呈现给客户。你可能还需要获得一些**统计知识**,并理解抽样分布和 A/B 测试等概念。**

我将在下面提供一些链接供进一步阅读,以便您可以更好地了解成为数据分析师的要求。

正如我上面提到的,数据分析并不是一个很难进入的领域,因为它不是高度学术性的,而且你可以在这个过程中学习所需的技能。

然而,为了做好数据分析师的工作,你需要掌握各种各样的技能。

这意味着你需要每周花几个小时来学习这些技能,以实现有效的职业转型。

本文到此为止,感谢阅读。

# 进一步阅读

1.  [用于可视化的数据分析工具](https://www.forbes.com/sites/bernardmarr/2020/05/22/the-9-best-analytics-tools-for-data-visualization-available-today/#3a4c4d224743)
2.  [数据分析师统计(在线课程)](https://www.udemy.com/course/statistics-for-data-science-and-business-analysis/)
3.  [数据分析师 A/B 测试](https://www.kdnuggets.com/2017/05/data-analyst-guide-ab-testing.html)

# 如何在 10 个步骤中成为数据科学家…

> 原文:<https://towardsdatascience.com/how-to-become-a-data-scientist-in-10-steps-ae8698099508?source=collection_archive---------21----------------------->

## 只是为了好玩

## 注意:这篇文章应该是娱乐性的——请不要实际遵循这些步骤

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ac3f622885b3e17d660aa1e17822ac18.png)

丹尼尔·罗梅罗在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片

## **1。无意中从朋友那里(或者更可能是在网上,因为你是一个内向的人)听到数据科学是“21 世纪最性感的工作”**

https://HBR . org/2012/10/data-scientist-21 世纪最性感的工作。说够了,给我报名!

GIF 来自[Giphy.com](https://giphy.com/)([服务条款](https://support.giphy.com/hc/en-us/articles/360020027752-GIPHY-User-Terms-of-Service))

## **2。把你的 LinkedIn 标题改成数据科学家(这样人们就知道你很性感)**

还可以在 GitHub 上添加一个链接,现在它只包含一个“Hello World!”知识库。Git 兴奋!!

## **3。看太多的博客文章和开源教材(因为它们很无聊)**

GIF 来自[Giphy.com](https://giphy.com/)([服务条款](https://support.giphy.com/hc/en-us/articles/360020027752-GIPHY-User-Terms-of-Service))

这一步还包括订阅了太多的博客/出版物,然后被收件箱里的大量高质量内容淹没,因此实际上什么也没看。嘿,至少你是通过阅读头条来跟上行业发展的。

## **4。与自己进行一周的内部辩论,讨论应该参加哪个数据科学训练营**

Thinkful,跳板,熨斗,Metis,水平,数据营…这是两个音节的先决条件吗?

此外,要接受这样一个事实:谷歌和 LinkedIn 的每一个广告都将是你家用电脑上的一个在线数据科学项目。

## **5。在 LinkedIn 上过度发帖**

如果你使用表情符号和至少五个标签,会加分。👏🏼👏🏼👏🏼

## 6。将堆栈溢出的答案复制粘贴到您的项目中,并严肃地质疑您尝试数据科学的决定

见[“栈溢出症”](https://medium.com/developers-writing/the-stack-overflow-disease-other-related-illnesses-a1dfd48d86b1)亦作,“[冒名顶替综合症](https://en.wikipedia.org/wiki/Impostor_syndrome)”

来自 Giphy.com[的 GIF](https://giphy.com/)([服务条款](https://support.giphy.com/hc/en-us/articles/360020027752-GIPHY-User-Terms-of-Service))

## **7。在你的 2016 款 MacBook air 运行了 16.52 小时后,把它扔到客厅的另一头**

好吧,至少 MacBook 在你极简主义的家庭办公空间里看起来很好,而且足够轻,可以带到所有的咖啡店!

(另一种描述:如果我能跑得和我的模特一样长,我的身材会很棒!)

## **8。开始实际学习统计学**

…并且仍然经常用谷歌搜索 p 值到底是什么。

## **9。在为时已晚的情况下,你将花费 80%的时间清理数据**

GIF 来自[Giphy.com](https://giphy.com/)([服务条款](https://support.giphy.com/hc/en-us/articles/360020027752-GIPHY-User-Terms-of-Service))

我真的要再打扫一遍吗?我就不能放点垃圾进去吗?[为什么我拿到数据就不能干净点?](https://www.springboard.com/blog/data-cleaning/)

## 10。写一篇幽默的中型文章,就好像你是一个真正的数据科学家,而不是一个正在找工作的“数据科学学徒”

哦对了,这就是我现在正在做的!在 LinkedIn 上与我联系。或者更好,雇用我。

关注我的媒体账号,这样它就可以成为众多直接发送给你的博客之一!😊👩🏼‍💻📊📚

GIF 来自[Giphy.com](https://giphy.com/)([服务条款](https://support.giphy.com/hc/en-us/articles/360020027752-GIPHY-User-Terms-of-Service))

# 如何在 2020 年成为数据科学家—顶级技能、教育和经验

> 原文:<https://towardsdatascience.com/how-to-become-a-data-scientist-in-2020-top-skills-education-and-experience-afa306d3af02?source=collection_archive---------25----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b30368ae40cbb10a654e5a1ab415f157.png)

# 如何成为 2020 年的数据科学家:简介

在过去几年中,数据科学一直是最时尚的话题之一。但是在 2020 年成为一名数据科学家需要具备什么条件呢?

简而言之,以下是我们发现的最新研究成果:

> 典型的数据科学家是男性,至少会说一门外语,背着他们有 8.5 年的工作经验。他们很可能拥有硕士或更高的学位,并且在日常工作中肯定会使用 Python 和/或 R。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/28e4fe336a1cb80d485b264afbcbeb23.png)

但是这样的概括很少有帮助。不仅如此,它们可能会误导人,有时甚至令人沮丧。这就是为什么我们对数据进行了细分,以揭示许多不同的见解:

请使用上面的列表浏览文章,或者只是阅读整篇文章。为了让您尽可能地了解不同的要点,我们还将与前几年的调查进行比较。如果你首先想了解如何在 2018 年和 2019 年成为一名数据科学家,请点击这些链接:

[2019 数据科学家简介](https://365datascience.com/data-scientist-profile-2019/) [2018 数据科学家简介](https://365datascience.com/research-into-1001-data-scientist-profiles/)

# 我们如何收集和分析数据:

这份报告的数据基于 LinkedIn 个人资料中的公开信息,这些个人资料包含 1001 名专业人士,目前被聘为数据科学家。样本包括初级、专家和高级数据科学家。为了确保与前几年的可比性和有限的偏差,我们根据几个条件收集数据。

## 位置

40%的数据由目前在美国工作的数据科学家组成;30%是英国的数据科学家;15%目前在印度;15%来自不同国家的集合(“其他”)。

## 公司规模

50%的样本目前受雇于财富 500 强公司;剩下的 50%在未排名的公司工作。

这些配额是根据对数据科学最受欢迎的国家以及该行业的就业模式的初步研究而引入的。

好吧,不多说…

# 如何在 2020 年成为数据科学家:概述

连续第三年,判决结果出来了。

# 男性数据科学家的数量是女性的两倍。

这种趋势虽然不幸,但并不令人惊讶,因为数据科学领域遵循科技行业的总体趋势。

就语言而言,数据科学家通常会说两种语言——英语和一种其他语言(通常是他们的母语)。

# 说到职业经历,我们发现你不可能一夜之间真的成为数据科学家。

需要 8.5 年的整体工作经验。有趣的是,这比 2019 年的数据增加了半年。另一个有趣的观察是,数据科学家平均拥有他们享有盛誉的头衔 3.5 年。去年,这一指标为 2.3 年。虽然我们的研究不是基于面板数据,但我们可以断言,一旦你成为一名数据科学家,你很可能会一直做下去。

# 关于编程语言,2018 年,50%的数据科学家都在用 Python 或者 r。

这一数字在 2019 年增加到 73%,以彻底打破今年的所有记录。2020 年,90%的数据科学家使用 Python 或 r。不,你不是唯一一个觉得它很神奇的人。在如此短的时间内如此高的采用率对于任何行业的任何工具来说都绝对是一个惊人的壮举。

最后,当你试图成为一名数据科学家时,你的教育水平肯定会有所不同。大约 80%的学生至少拥有硕士学位。这相当于比去年增加了 6 个百分点。

# 以往的经验

每年,我们都会查看数据科学家以前的工作经历。事实证明,这部分结果对有抱负的专业人士最有用,可以找出成为数据科学家的常见职业道路。

重申一下,在 2020 年,数据科学家平均有 3.5 年的职称和 8.5 年的工作时间。

# 但是…数据科学家在成为数据科学家之前是做什么的?

根据我们的样本,他们…已经是数据科学家了!或至少一半的群体(52.4%)。如果我们将这个数值与往年进行比较,2018 年有 35.6%的此类案件,2019 年有 42%。因此,年复一年,这个职位变得越来越排外——我们可以从他们的平均工作经验中推断出这一观察结果。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4d2f613c0b35e306cbc4751d9ec3a28b.png)

# 这种观点表明,在成为数据科学家后,没有太多的职业选择。

换句话说,一次是数据科学家,永远是数据科学家。至少 2020 年是这种情况。

关于其他相关的职业道路,从数据分析师开始仍然是更可取的道路(总体 11%),其次是学术界(8.2%)和数据科学实习生(7.0%)。这一细分是我们自 2018 年以来年度研究中最一致的部分之一。因此,你可以把你的数据科学家生涯押在这上面。

# 教育

教育是大多数简历的三个主要部分之一,这一点不太可能改变。教育背景是给你未来雇主的一个信号,尤其是当你没有太多经验的时候。那么,如果你想成为一名数据科学家,什么样的教育能给出最好的信号呢?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ead6abc294dd3e41911edc36ac447da4.png)

# 根据我们的数据,2020 年的典型数据科学家拥有硕士学位(56%)、学士学位(13%)或博士学位(27%)作为他们的最高学历。

乍一看,这些统计数据似乎并不违背直觉。然而,与 2019 年(19%)和 2018 年(15%)相比,“只有学士学位”的数据科学家实际上有相当大的下降。数据科学需要高级专业知识。这通常是通过传统教育的研究生或研究生形式获得的,或者通过独立的专业学习获得的。

虽然专业化很重要,但过多的专业化,如博士学位,并不是进入数据科学的先决条件。事实上,博士持有人的比例多年来一直保持稳定,约占我们样本的 27%。

然而,硕士学位正在巩固其作为 2020 年成为数据科学家所必需的学术成就黄金标准的地位。

# 我们观察到,与 2019 年相比,拥有硕士学位的专业人士增加了 20%(2019 年为 46%,2020 年为 56%)。

硕士学位是学士专攻某一领域的绝佳途径。

一般来说,硕士学位有两种选择:

*   增加你的**深度**(深入挖掘一个话题)
*   或者增加你的**广度**(改变你的关注点,使你的技能多样化)。

一种假设是,拥有经济学、计算机科学或其他定量学士学位的人已经攻读了一个流行的数据科学硕士学位。这在我们关于研究领域的章节中得到进一步证实。

可以说,还有另一个因素在起作用,这就是这个领域越来越受欢迎。

# Glassdoor 的 50 份最佳工作等行业报告一致将数据科学评为 2016 年、2017 年、2018 年和 2019 年的赢家。

在过去五年中,谷歌对数据科学的搜索也至少翻了两番。这无疑有助于提高人们对数据科学职业的兴趣,并因此导致某些地区的招聘流程更具选择性([参见下面的](https://365datascience.com/become-data-scientist-2020/#9)国家和工作经验年限)。

最后,虽然数据科学正在成为一个竞争更加激烈的领域,但超过 10%的数据科学家仅凭借学士学位就成功渗透到该领域(13%)。这个数字确实低于我们在过去两年中观察到的数字(2019 年为 19%,2018 年为 15%)。尽管如此,数据科学仍然对学士学位持有者开放。事实上,如果我们看看具体国家的数据,就会发现一个更加微妙的画面。

# 国家和学位

正如我们在本文开头的方法部分所述,我们根据位置配额收集数据;美国的数据科学家组成了我们 40%的数据,英国的数据科学家贡献了我们 30%的观测数据;印度和世界其他国家各占 2020 年人口的 15%。

# 也就是说,在英国和美国,拥有硕士学位的数据科学家的数量都有所增加(分别为 54%和 58%,而 2019 年为 44%)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8e51f9f33306aee8a60a4ca927b42935.png)

在印度,2020 年拥有硕士学位的数据科学家数量也比往年增长了 16%(2020 年为 57%,2019 年和 2018 年为 49%)。

有趣的是,这并不对应于印度拥有本科学位的数据科学家的相应减少(2020 年为 32%,而 2019 年为 34%),这仍然是我们整个队列中学士学位持有者的最高比例。与前几年相比,在当前的研究中,博士毕业生和拥有“其他”学位的专业人士也越来越少出现。正如我们上面提到的,拥有“时尚”数据科学硕士学位的专业化正成为该领域许多人的首选职业道路,这似乎是合理的。

# 同样值得注意的是,在印度成为数据科学家并不需要博士学位。

事实上,拥有博士学位的研究生仅占印度数据科学家样本的 3%;这比美国的数据少 30%,也是印度代表性最少的群体。

因此,这些数据证实了两个初步结论。在学术上,硕士学位正在成为全球最受欢迎的数据科学家学位。而且,如果你只有学士学位,印度为你提供了在数据科学领域开始职业生涯的最佳机会。

# 研究领域

成为数据科学家最好的学历是什么?如果你在过去几年里一直关注这个行业(或者至少是我们的研究),你会倾向于用“计算机科学”或者“统计和数学”来回答。毕竟,数据科学是所有这些学科的宠儿。但你可能错了。

# 2020 年,成为数据科学家的最佳学位是…数据科学与分析!

“数据科学与分析”的毕业生终于登上了我们研究的巅峰!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/dd60c7474fd32d4bc73ddc973124790f.png)

在我们继续分析之前,先说明一下方法论。因为在学术界有大量独特的细微差别——以及相应的命名——学位,我们将我们的数据分为七组学术研究领域:

*   **计算机科学**,其中不包括机器学习;
*   **数据科学与分析**,其中包括机器学习;
*   **统计与数学**,包括以统计和数学为中心的学位;
*   **工程**;
*   **自然科学**,包括物理、化学、生物;
*   **经济和社会科学**,包括与经济、金融、商业、政治、心理学、哲学、历史、市场营销和管理相关的研究;
*   **其他**,包括我们样本中的数据科学家追求的所有其他学位。

# 因此,数据科学和分析最终是最有可能让你进入数据科学的学位。厉害!

与 2019 年(12%)和 2018 年(13%)相比,我们看到 2020 年毕业并获得数据科学专业学位的专业人士数量大幅增加(21%)。鉴于我们之前的观察(见上文教育),这些学位中的大多数都是硕士学位(数据科学和分析集群的 85%)并不令人惊讶。因此,数据科学似乎是任何定量学士的首选专业。

这一发现表明,传统大学开始对数据科学家的需求做出回应。与此相一致,提供培养数据科学家技能的课程。另一个明显的趋势是,数据科学和分析学位正在成为进入数据科学的公认学位,特别是如果你以前从不同的领域毕业。

# 例如,考虑数据科学家在 2019 年和 2020 年获得的前 3 个学位:

## 2019

*   计算机科学(22%)
*   经济学和社会科学(21%)
*   统计和数学(16%)

## 2020

*   数据科学与分析(21%)
*   计算机科学(18%)
*   统计和数学(16%)

# 数据科学和分析显然领先于计算机科学。

更重要的是,它的出现已经完全将经济学和社会科学从 top 3 排名中移除,即使这个专业在 2019 年是接近的第二名。

工程、自然科学和其他领域的毕业生各占我们数据的大约 11%。我们可以说,与前几年相比,这没有太大变化。

# 有趣的是,我们样本中的大多数女性很可能获得了统计学和数学相关的学位(女性群体中的 24%)。

相比之下,男性最有可能获得数据科学和分析学位(22%),计算机科学(19%)紧随其后。

总的来说,就进入该领域的最佳学位而言,数据科学相当平衡。

如果你有量化或编程背景,或者如果你进一步专攻数据科学和分析,你可以成为一名数据科学家。要做到这一点,要么通过传统的硕士学位,要么通过完成训练营培训或专门的在线培训项目。

# 如何在 2020 年成为数据科学家:在线课程和学位

数据科学家来自如此多不同的背景,我们可能会怀疑他们的大学学位是否足以胜任他们的工作。

# 即使没有研究,答案也是——不可能。没有一个单一的学位可以让一个人为数据科学的实际工作做好准备。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/42d6cce098a4241671d368ffdaeb87a5.png)

事实上,数据科学家更接近于“书呆子”而不是“摇滚明星”——这与其说是天赋,不如说是努力。因此,你可以打赌,他们会慢慢地自我准备。在我们的研究中,我们使用了最接近的 LinkedIn 代理——在线课程的证书。我们的数据表明,41%的数据科学家已经包括了一门在线课程,这与过去两年几乎相同(2018 年为 40%,2019 年为 43%)。

# 学位和直接聘用

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3ccb0c570b037ac73c765e1a58bf5adb.png)

一毕业就能成为数据科学家吗?虽然并非闻所未闻,但数据表明这不太可能。在我们的团队中,只有不到 1%的人在没有经验的情况下成功成为了数据科学家。他们要么有博士学位,要么有硕士学位(80%的男性和 100%的女性)。这些直接雇员中有四分之一还表示已经获得了在线认证。

我们发现有趣的是,我们团队中的直接雇员几乎完全反映了 2020 年典型数据科学家的特征(见上文)。

*注意,并不是所有的人都贴出自己所有的证书,所以这些结果实际上是轻描淡写。*

也就是说,让我们来讨论一下,如果你不是那幸运的 1%,你需要什么样的经历才能成为一名数据科学家。

# 多年的经验

到 2020 年,典型的数据科学家已经作为数据科学家工作了至少一年(我们队列中的 70%),人数最多的是 3-5 年的数据科学家(28%),其次是 2-3 年的数据科学家(24%),以及工作第二年的数据科学家(19%)。

# 工作第一年的数据科学家占我们 2020 年数据的 13%。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/74203a45c7261e955452619e3729581d.png)

这些都是有趣的统计数据,特别是在考虑 2019 年和 2018 年的数据时。更具体地说,我们观察到,与 2019 年和 2018 年开始职业生涯的数据科学家人数(25%)相比,2020 年刚刚开始职业生涯的数据科学家人数减少了近 50%(13%)。鉴于作为数据科学家的[平均经验的增加,我们可以得出结论,这些专业人士留在该领域,使得初级人员更难进入。](https://365datascience.com/career-data-science-ultimate-guide/)

# 第二个有趣的趋势是,与过去两年相比,在职 3-5 年和 2-3 年的数据科学家数量有所增加。

2018 年,25%的数据科学家拥有超过 3 年的经验,而在 2020 年,这一数字将达到 44%,在这一群体中增加了 76%。这表明数据科学专家和高级数据科学家正在留在该领域,而不是转移到其他行业。

尽管如此,我们提到了一些重要的跨国差异,需要进一步探索。所以,让我们在下一节更详细地考虑这些!

# 国家和经验年限

对数据科学家在职经历的跨国分析揭示了一个奇怪的趋势。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/66fe98c3bf7f6f96c9a2b12a0bff002d.png)

# 就资历而言,美国队列中的数据科学家无疑是我们数据中最有经验的。

超过 50%的人至少是第三年从事数据科学家工作,20%的人已经工作了 5 年以上。对于数据科学领域的职业新手来说,美国是最不友好的环境。在我们的美国同行中,只有 8%的人第一年是数据科学家,15%的人第二年是数据科学家。

## 根据我们的数据,英国的数据科学领域更容易渗透。

11%的英国样本是以数据科学家的身份开始他们的职业生涯的,而 20%已经是他们工作的第二年。尽管如此,该群体中最大的代表群体是工作第三或第四年的专业人士(29%)。

## 如果你在寻找一个能给职场新人提供最多机会的国家,数据显示这就是印度。

在我们的样本中,超过 50%的人是工作第一年或第二年的数据科学家。对于刚刚开始接触数据科学并希望将其专业知识融入职业生涯的人来说,这是一个好消息。

当然,这一数据并不令人惊讶,一些世界上最大的公司在班加罗尔和海德拉巴开设了办事处,包括亚马逊、沃尔玛、甲骨文、IBM 和宝洁。

世界其他地方,或者说我们的“其他”国家集群显示出数据科学专业人员在多年经验方面的分布更加均衡。不到 20%的人是第一年或第二年成为数据科学家,超过 20%的人是第三年或第四年,四分之一的人是 3-5 年。也就是说,值得一提的是,在我们的“其他”国家集群中,最大的参与者是瑞士、荷兰和德国。因此,我们可以试探性地说,数据科学正在成为西欧一个更加突出的领域,由于该领域尚未充斥着数据科学人才,初级和中高级专业人员都有需求。

# 数据科学家的编程技巧

当寻找编程语言能力时,我们不得不求助于 LinkedIn 技能“货币”——背书。虽然不是一个完美的信息来源,但它们是一个人擅长什么的良好代理。如果我主要是训练 ML 算法的话,我不会被同事们认可为 Power BI 吧?

澄清之后,让我们深入研究数据。Python 在一年左右前废黜了 R,所以我们不会过多评论这场竞争。此外,知道 90%的数据科学家使用 Python 或 R,我们可以完全结束这个话题,继续前进。

但是那就有点无知了,尤其是对 SQL!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3de4398f37d0d0238fc27157b34e6000.png)

74%的人“说”Python,56%的人知道 R,51%的人使用 SQL。这里特别值得注意的是,自 2019 年以来,SQL 的受欢迎程度增长了 40%(36%),仅次于 r,接近第三。现在,有各种因素可能导致这一数字。

一个可能的解释是,公司并不总是很好地理解数据科学家的职位。这导致他们雇佣数据科学家,并让他们承担过多的数据工程任务。例如,GDPR 的实施和数据仓库中数据源的大规模重组将一些数据科学家置于不利的位置,使他们无法领导或咨询此类项目。不可避免地,为了“完成工作”,必须将 SQL 添加到他们的工具箱中。

这种现象不仅在 SQL、[的上下文中,而且在与数据库管理相关的大数据结构中,正得到越来越多的关注。](/stop-making-data-scientists-manage-kubernetes-clusters-53c3b584cb08)因此,数据科学家获得了新的技能,代价是编写更少的机器学习算法。

# 支持 SQL 的另一个要点是,BI 工具如 Tableau 和 Power BI 严重依赖于 SQL,从而增加了它的采用。

这就是为什么 SQL 会进一步上升,甚至赶上 r。编程语言的情况是由 MATLAB (20.9%)、Java (16.5%)、C/C++ (15.0%)和 SAS (10.8%)完成的。再次,乳胶(8.3%)也在前 10 名。

为什么?

嗯,学术界不会损害你成为数据科学家[的机会,正如我们从我们这群人](https://365datascience.com/become-data-scientist-2020/#7)的背景中看到的那样。

# F500 和编码语言

我们怎么强调 Python 和 R 对于 2020 年的数据科学领域的重要性都不为过。然而,当涉及到大公司时,他们的优势就是他们的缺陷。Python 和 R 都是开源框架,不像 MATLAB 或 c 等成熟的语言,它们可能会有错误或没有很好的文档记录。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ccb19af8de8a2c97a8c20354fd2c73ab.png)

数据确实证实了这一说法。以 Python 为例,70%的 F500 数据科学家使用 Python,而 77%的非 F500 数据科学家使用 Python。这听起来像是令人不快的消息,但事实上并非如此。这些年来,Python 和 R 都在缩小差距。与 2018 年的数据相比,F500 公司似乎正在重新思考他们的组织,并更加包容新技术。

除了 Python 的不同使用率之外,编码语言的其余细分仍然保持着无趣的一致性。

# 国家和编码语言

在过去,你的就业国家将决定你的许多人生决定——学习什么语言,遵守什么规则,尊重或采纳什么习俗。但是这适用于编码语言吗?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/91f0c2fca5371565d67043bd5f2ac6e0.png)

自 2018 年以来,我们将目光投向美国、英国、印度和“世界其他地区”。我们的发现表明,在美国和印度,R 比 Python“赢得了民心”。另一方面,英国和“世界其他地方”已经在慢慢淘汰 R,转而支持 Python。

嗯,在 Python 的采用方面,美国和印度不再“落后”。换句话说,Python 现在是各国之王。因此,成为一名数据科学家的最佳选择是弯下膝盖,加入 Pythonistas 寻找数据驱动的真理。

根据记录,编码语言的细分在各国是一致的,R 和 Java 在 2020 年受到 Python 霸主地位的最大冲击。与前几年相比,SQL 没有受到影响,甚至有所增长。

# 如何在 2020 年成为数据科学家:结论

连续第三年,365 数据科学研究对 1001 名当前数据科学家的 LinkedIn 个人资料进行了研究,揭示了这是多么美好的一年!

这项研究表明,该领域正在不断发展,并适应企业的需求及其在学术界和周围越来越受欢迎。大学正在赶上需求,而硕士学位正在确立自己的黄金标准学位。

# Python 继续蚕食 R,但是 SQL 也在崛起!

与美国和英国相比,印度对初级数据科学家的需求更高,从而赢得了数据科学家最佳职业国家的称号。如果你只有学士学位,这也是你应该去的地方。

当然,我们对这些趋势在未来 2-5 年内将如何发展非常感兴趣。但同时,如果你认为我们错过了任何有趣的东西,请告诉我们!我们的使命是为数据科学家的工作以及它如何随时间而变化创建一个信息丰富且最终有帮助的账户。毕竟,做出对自己最有利的职业决定,就意味着知情!

因此,请保持好奇心,增长您的编程技能,祝您在数据科学职业生涯中好运!

**其他研究链接:** [2019 数据科学家简介](https://365datascience.com/data-scientist-profile-2019/); [2018 数据科学家简介](https://365datascience.com/research-into-1001-data-scientist-profiles/)。

*原载于 2020 年 2 月 25 日 https://365datascience.com**[*。*](https://365datascience.com/become-data-scientist-2020/)*

# 成为高产数据科学家的课程

> 原文:<https://towardsdatascience.com/how-to-become-a-highly-productive-data-scientist-from-online-drivers-9026331eaf9c?source=collection_archive---------42----------------------->

## 我对有抱负的数据专业人士的建议

## 您的在线驱动程序如何教会您提高工作效率,以达到您的关键指标

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e8b56be9f51deb7f958c1fdd6522b259.png)

来源: [Unsplash](https://unsplash.com/photos/S0tm3ZYljZk)

> "作为一名 GoJek 车手,你是如何成为顶尖选手的?"
> 
> “很简单,你需要通过定位自己获得许多好的旅行来获得你的每日奖金(主要目标)(次要目标)”——[Gojek 手册](https://lelogama.go-jek.com/DRIVER_HANDBOOK_16SEPT_DigitalVersion_1.pdf)

# 与网上司机的邂逅

那是一个炎热的日子。我拿出我的 Gojek 应用程序(类似于优步的网上司机服务),准备出发去我女朋友的住处。他带着微笑,穿着整洁的衣服,开始和我闲聊,聊了一个小时,激发了我写这篇文章的灵感。作为一名数据科学家,我觉得他的分享对我作为数据专家的职业生涯很有意义,希望对你也是如此。

# GoJek 在线司机的经济

## 他换工作的原因

*   **更高的薪水:**与之前的卡车司机工作相比,他的收入翻了一番。
*   弹性工作时间表:他早上 7:30 开始工作,晚上 8:00 回家。工作时间长,却是因为他的目的是领取**奖金(收入来源)。**
*   **社区**:有针对线上司机的事件。在每个雅加达市,都有“部落”和“团体”。这增加了 Gojek 车手的归属感和友情。

## 收入来源

1.  **每次出行的收入:**据他说,司机可以获得每次出行的 80%左右,另外 20%作为 Gojek 账户服务支付。这意味着,如果我们假设一次常规旅行约 5 万印度卢比(5 美元),司机每次旅行得到 4 万印度卢比(4 美元)。请记住,每次出行都需要考虑交通流量。如果交通状况不好,这段路程可能需要 3 个小时而不是 1 个小时。这意味着预期收入将从 4 万印度卢比/小时下降到 1.3 万印度卢比/小时。表现最好的司机将能够避免糟糕的交通,并最大限度地提高他们的收入/小时。
2.  **奖金**。这是很多网上司机长时间工作的主要原因。每天,司机需要完成至少 21 次旅行才能获得 26 万印度卢比奖金(26 美元)。这就是为什么网上司机每天可以工作 9-10 个小时(不包括休息时间)。

## 费用

1.  **油费**:Gojek 司机需要自己购买汽车燃油。这意味着每个好日子增加 20 万印度卢比(20 美元)。
2.  **租车**:他每天都需要租车。据他说,有许多在线司机的租车费用高达每天 12 万印尼盾(12 美元)。
3.  **事故**:事故偶尔发生,幸运的是,Gojek 司机可以使用租车/Gojek 保险。然而,对于小事故,由于机会成本,他会选择忽略损失:修复事故所花的时间可以用来赚取收入。

> 我为什么要修我的车?如果在一个小时内,我可以得到额外的 50K (5 美元)?

## **每天净收入**。

算上所有的收入,他每天大约有 60 万印度卢比(60 美元)的收入和 28 万印度卢比(28 美元)的净收入。最终,考虑到雅加达的平均工资是 25 万印度卢比(每天 25 美元),这是一笔不错的收入。

# 在线驱动程序关键目标

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9166f29d578faba20debc062327b6329.png)

[资料来源:Unsplash](https://unsplash.com/photos/3jBU9TbKW7o)

我很乐意把他的主要目标表述成这样。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8938d98c7599a9830fa9407d8b4c00e4.png)

> **用简单的英语说** : **在最短的时间内最大化旅行次数,直到达到奖金。为了做到这一点,他需要考虑许多不同的限制因素:交通堵塞、健康状况和事故。**

# 与数据科学家关键目标的相似性

同样,我希望将我的主要目标规划如下:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/26f3151ba4ccddcb93b25e66e45a8e28.png)

> **用简单的英语说** : **在最短的时间内最大化影响,直到达到某个最低目标(MVP-最低可行产品)。为了做到这一点,我需要考虑许多限制因素:团队会议、非优先任务的突发事件和不可预见的情况。**

我发现这个关键目标与我相关。在谷歌,我们有一个名为客观关键结果(OKR)的绩效系统,你的绩效完全由你的影响来衡量。以下是我用过的一些常见的 okr(伪装成不违反谷歌的博客政策)

> 利用[数据…]识别未知的网络钓鱼活动(目标)。每周撰写 X 个批准的活动,保护 X 个用户(主要结果)。在生产中推出新的 ML 模型,将其召回率提高 X%(主要结果)

简而言之,这些是影响指标(关键绩效指标)的示例:

1.  我们的滥用检测 ML 模型保护了多少用户?
2.  我们的检测质量(精确度、召回率等)有什么改进?
3.  你如何传达复杂性并让利益相关者(工程师、商业利益相关者、支持等)接受?

# 数据科学家的 3 个生产力策略:最大化您的影响

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e21521709bba00c6f3d0d2cccfd9d49f.png)

来源: [Unsplash](https://unsplash.com/photos/7tXA8xwe4W4)

## **1。了解你的优先事项**

网约车司机最大的敌人之一就是堵车。一个糟糕的司机会接受每一个请求。一个好的司机会优先考虑每次旅行每小时的收入。

同样,作为一名数据科学家,你能做的最糟糕的事情就是接受每一项任务和想法。你收到的大部分项目请求都会有未知的影响和可行性(想象项目调优 ML/做一个新的推荐者/集群多个站点组)。你需要评估每个项目。例如,您应该在现有模型的基础上进行构建吗?你应该生产或杀死它,然后继续前进吗?一旦你按影响/小时(低挂的果实)对它们进行了排序,你就要给自己定位在正确的项目中,并计划好你的一天来产生影响。

**我为什么要接这个项目?**

这个项目是否产生一个行动或支持来维持?如果没有,那就随它去吧。这个决定是你避免低效率和实现关键目标的最大资产。

我有一个朋友,他忘记了探索性数据分析(EDA)的重要性,结果浪费了几个小时来实现一个 ML 模型,否则可以用基于规则的(if-else)逻辑来代替。许多数据科学家专注于实现技术上复杂的模型,而没有很好地理解业务问题。我们经常忽视这些影响。[这不是如何建立你的投资组合](/how-to-build-your-ultimate-data-science-portfolios-ea0414d79a72)。

> 关注你所做的每件事的影响/小时。

## 2.约束和关键目标的博弈

这是 Gojek 司机的时间表。

*   05.30–10.00:市场和社区
*   10.00–16.00:城市地区
*   16.00–20.00:购物中心
*   20.00–21.30:主场

这个时间表背后有逻辑推理。首先,他最大限度地利用早上的短途旅行,将自己定位在市场上,以增加接受购物者请求的机会。由于大多数人会去他们家附近的市场,他可以在一大早积累他需要的出行量(吃大青蛙),同时避开高峰时间。

一旦高峰时间结束,他开始接受城市的要求,并站在市中心接受长途订单。最后,晚上 8 点以后,他会寻找一条能让他轻松回家的路。

> 通过了解他的目标,他就有了在不精疲力竭的情况下实现关键结果的策略。

**数据职业游戏计划**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/41408a76c9d97792a91246fc0e0c115f.png)

我在谷歌的数据专家日程概述

同样,游戏你的表现。如果你在一个开放的办公室工作,找到一个安静和隐蔽的地方进行深入的工作。寻找与你的兴趣和需求相关的项目。与利益相关者沟通,并尽早确认事实真相。如果你发现自己不堪重负,那就把任务委派出去。通过规划你的游戏计划,你可以避免不必要的浪费,并专注于提供影响

> 采取行动,最大化你达到关键目标的可能性。

## 3.投资于没有混乱的聪明关系

作为一名司机,他发现 Gojek 家族很重要,但很快发现自己被这些杂物淹没了。他退出了氏族,与一小群资深戈杰克驾驶员合作。这有助于他进行更明智的关系投资,让每个驱动因素在生产率方面互相帮助。

**投资合作**

同样,作为一名数据科学家,你的目标是在比你聪明的人中间找到自己。带着明确的目标与他们建立关系,不要让你的友谊和关系网影响你的工作效率。在你的密友和注重数据的同事身上投入时间。

我发现在像 Google 和 Visa 这样的大公司中,我们与商业利益相关者、工程师和其他数据分析师一起工作。确保你产生影响的最重要的步骤是说他们的语言,并说服他们支持你的想法。

令人惊讶的是,我有一些“数据科学家朋友”,他们连系统思维和 Dev Ops(开发运营)都不懂。他们不能很好地与同龄人合作。最终,这些项目完成了,但没有实施以产生生产影响。

因此,了解你的关键支持,并分配时间进行沟通,共同实现关键目标。记住,数据科学是团队合作。

> 寻找有动力的人来避免混乱,一起实现目标

# 结论

记住这些教训有很多好处。首先,您将使用关键目标,根据影响/小时对项目进行优先级排序。第二,你可以砍掉不重要的事情(不必要的会议、社交等)。最后,您会找到帮助实现关键目标的支持。

总之,在我们的数据分析职业生涯中,我们需要考虑三个关键因素:

1.  **优先考虑影响最大/小时的正确项目:**我们需要一个适当的策略来优先考虑我们的项目和积压的工作。
2.  **设定约束和关键目标:**给自己定位,以最大化实现关键目标的可能性。始终进行 EDA 以了解数据和业务目标。
3.  **投资于没有混乱的聪明关系:**寻找有动力的人一起实现目标。

保持专注和高效。

索利·德奥·格洛丽亚

# 最后…

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b2e7ff367b1be529cefb1db9c446c89e.png)

[来源(Unsplash)](https://unsplash.com/photos/w7ZyuGYNpRQ)

我真的希望这是一本很棒的读物,是你发展和创新的灵感来源。

请在下面的**评论**提出建议和反馈。就像你一样,我也在学习如何成为一名更好的数据科学家和工程师。请帮助我改进,以便我可以在后续的文章发布中更好地帮助您。

谢谢大家,编码快乐:)

# 关于作者

Vincent Tatan 是一名数据和技术爱好者,拥有在 Google LLC、Visa Inc .和 Lazada 实施微服务架构、商业智能和分析管道项目的相关工作经验。

Vincent 是土生土长的印度尼西亚人,在解决问题方面成绩斐然,擅长全栈开发、数据分析和战略规划。

他一直积极咨询 SMU BI & Analytics Club,指导来自不同背景的有抱负的数据科学家和工程师,并为企业开发他们的产品开放他的专业知识。

最后,请通过[**LinkedIn**](http://www.linkedin.com/in/vincenttatan/?source=post_page---------------------------)**[**Medium**](https://medium.com/@vincentkernn?source=post_page---------------------------)**或** [**Youtube 频道**](https://www.youtube.com/user/vincelance1/videos?source=post_page---------------------------) 联系文森特**

# 2020 年如何成为机器学习工程师

> 原文:<https://towardsdatascience.com/how-to-become-a-machine-learning-engineer-in-2020-1161aa29261e?source=collection_archive---------0----------------------->

## 机器学习工程

## 软件工程和数据科学的利基在于生产 ML 代码

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4b86c55a77e5f4991682fd69c90c6185.png)

尼克·希利尔在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片

“机器学习工程师”的头衔正迅速变得越来越受欢迎,因此,人们对试图进入数据科学领域产生了浓厚的兴趣。**这个**是什么样的职业道路,一个机器学习工程师需要具备什么样的**技能集**?有没有可能定义成为一名 ML 工程师需要采取的步骤?你能参加在线培训并获得认证吗?我想我应该写下我对这个领域现状的想法,以及它对那些寻求在这个领域发展的人来说是多么可行。

# 机器学习工程师

让我们先解决一个问题。一些人可能会看着这个职位,期望它是一个纯粹专注于模型构建的数据科学家——仅此而已。这是一个大忌;仅仅是因为大多数 ML 工程工作是在最初的模型建立之后开始的。虽然这通常是工作的一部分,但机器学习工程师不仅仅是建立模型。老实说,这部分只占工作的 5%到 10%。

看看这张模型生态系统中所有组件的图片。中间的黑色方块?那是真正的 ML 代码。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e8b5ed3ac24b4018a5ac229400c7da5c.png)

组成 ML 系统的只有一小部分是真正的 ML 代码(黑色方块)。摘自 Scully 等人(2015)的论文《机器学习系统中隐藏的技术债务》链接[此处](https://papers.nips.cc/paper/5656-hidden-technical-debt-in-machine-learning-systems.pdf)。

那么,机器学习工程师是一种什么样的生物,它在事物的大计划中处于什么位置?**我更喜欢 2018 年托马斯·杜德克的部分定义:**

> …一个被称为机器学习工程师的人断言,所有生产任务在实际执行和调度方面都正常工作,将机器学习库滥用到极致,经常添加新功能。(他们)确保数据科学代码可维护、可扩展和可调试,自动化和抽象出大多数机器学习任务中存在的不同的可重复例程。他们为数据科学团队带来了最佳的软件开发实践,并帮助他们加快工作速度…
> 
> *—托马斯·杜德克在*[*但是这个“机器学习工程师”到底在做什么呢?*](https://medium.com/@tomaszdudek/but-what-is-this-machine-learning-engineer-actually-doing-18464d5c699)

**本质上,ML 工程师是某种向导,以合理的方式将模型引入生产,能够改进数据科学家的模型,同时也是为数据科学团队铺平道路的架构师。这听起来不可思议地像是某种高级工程角色,然而它并不一定是。**

# **普通 ML 工程背景。**

**我见过的大多数其他 ML 工程师都属于两种类型之一。第一个群体受过高等教育,大多数人拥有计算机科学、人工智能、数据科学或软件工程的硕士甚至博士学位。令人惊讶的是,许多人是相对较新的毕业生,当他们成为 ML 工程师时,已经有 1-3 年的工作经验。还有第二组,由更有经验的开发人员组成,他们从软件工程或数据工程等邻近领域过渡到这个角色,当然还有数据科学。**

**这表明有一个熟练程度需要成为一个 ML 工程师,可以来自两个方向的任何一个组成的角色。你可以成为一名伟大的软件工程师,或者一名出色的机器学习大师。也许两者都有!如果你已经是其中之一,这可能是你的领域。如果你不是,这可能是一个可行的发展方向。**

**但是不要错误地认为软件工程师或数据科学家会自动成为优秀的 ML 工程师。我本人来自软件背景,我可以保证大多数 ML 概念和 API 对于软件工程师来说是完全陌生的。我记得几年前我为了解 TensorFlow 和 Theano 而进行的激烈斗争。尽管我十几岁就开始编程,但我从未见过这样的事情。这一经历令人羞愧。**

**初级水平的 ML 工程师不是初级程序员。这是一次至少总有人经历过的旅程。那么,没有经验或培训就不可能找到一份 ML 工程工作吗?**

**当然不是。然而,情况对你不利。当你有相似的背景时,进入这个利基市场要容易得多。然而,地平线上出现了一些曙光。**

**请记住,当数据科学开始变得流行时,我们对数据科学家也说了同样的话,因为当时从事数据科学的人是世界上最聪明、受教育程度最高的一些人。从那时起,数据科学变得更加容易获得,事实上,现在你不需要博士学位也可以成为一名伟大的数据科学家。我不确定这是否完全适用于 ML 工程,但我希望随着我们领域的成熟,进入门槛会变得更低。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0ede51ed0a6aaca27e10afd62ec5546b.png)**

**数据科学。软件工程。可能还有一些线性代数。这些都是被选择用来创造完美的 ML 工程师的成分。作者创建白板。**

**ML 工程师的工具带不仅仅是软件工程师的 IDE 和数据科学家 Jupyter Lab 之间紧张关系的产物。它有许多该领域固有的工具和技术。这就引出了下一部分…**

# **机器学习工程师的技能**

**技能列表在被写出来后很快就过时了,并且经常有自己的生命。然而,我在这里起草了一个非详尽的技能和研究课题清单!工具的前景是如此广阔,以至于任何一个 ML 工程师都不可能精通所有的语言、工具和概念。**请不要将此视为你在 ML 工程之旅中需要划掉的项目清单**就像许多在线资源会指导你做的那样。相反,请注意,并把这些看作是 ML 工程领域的主题。**

**我将尝试讨论概念而不是具体的工具。这样,大部分内容将在几个月或几年内保持相关性。**

## ****数据科学****

*   ****巨蟒。**研究一下编码标准和 Python 最近版本中一些很酷的东西。对 **R** 有一个基本的了解也是有用的,你的数据科学家会为此感谢你。**
*   ****统计。****
*   ****模型优化。****
*   ****模型验证。****
*   ****ML 框架**如 sci-kit learn**
*   ****深度学习**tensor flow、PyTorch 等框架**
*   ****ML 应用**如 NLP、计算机视觉、时间序列分析。**
*   ****数学**。不言而喻,你会用到大量的线性代数和微积分。**

**我选择 Python 而不是 R 或任何其他语言的原因主要是因为生产方面。虽然您可以用 R 做很多事情,但它通常不像 Python 那样受支持。这里还有时间方面的问题:通常用 Python 生产代码要比用 r 快得多。**

## ****软件工程****

*   **体验 python 之外的第二编程语言,如 Java、C++或 JavaScript。**
*   ****云祭**。稍后会详细介绍。**
*   ****分布式计算****
*   ****系统设计和软件架构****
*   ****数据结构和算法。****
*   ****数据库**及其附带的查询语言。**
*   ****集装箱化**(例如 Docker,KubeFlow)**
*   ****功能编程**概念**
*   ****设计模式****
*   ****大魔神****
*   ****API 开发****
*   **版本控制: **git****
*   ****测试****
*   ****项目管理**。可能是所有 SE 课程中最被低估的元素。**
*   ****CI/CD****
*   ****MLOps****

**那么,如果不在工作中,你是如何学习所有这些知识的呢?**课程和在线培训**可能很棒,但它们不会教你如何在现实生活中应用它们。对于像统计学这样的东西来说,这并不重要,但是对于技术学科来说,知道“关于”只是掌握的一半。只需快速浏览一下 Reddit 的 r/learnprogramming 就可以发现,有许多人正在努力从在线课程中受保护的 IDE 中编写代码过渡到在自己的机器上编写自己的项目。**

**我的经验是,最好自己着手一个项目来学习一项新技能,当你已经有了一些应用知识时,通过在线培训来补充你的知识。有许多在线教程可以帮助你,从制作你自己的时钟或计算器到一个完整的网络应用,而不是一体化的培训计划。注意任何承诺你可以在几周或几个月内从零到英雄的课程。**

****认证**也是类似的猛兽。如果你从事咨询工作,想向客户表明你的技能达到了一定的标准,那么证书会特别有价值。拥有与客户的技术组合相对应的认证会让您立即处于领先地位。然而,如果一开始就没有技能支持,证书是没有价值的。现在考虑一下,你可以获得许多认证,而不必为它们编码,你就会明白我的方向了。通常,花在获得认证上的时间最好花在构建应用程序上。**

**也就是说,对于 ML 工程师来说,有一些认证确实有一些价值,特别是对于云供应商来说。通常这些**需要几年在各自平台上部署应用的经验**,但是任何人都可以支付 100-300 美元并注册认证考试。截至 2020 年,有三家云供应商值得一提:Azure(微软)、GCP(谷歌)和 AWS(亚马逊)。这是一份他们提供的 ML 工程师感兴趣的认证清单。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/32a264d8a599f351b51672ec15b8e623.png)**

**通过认证考试时授予的 Microsoft Azure 协理级徽章。[来源](https://docs.microsoft.com/en-us/learn/certifications/azure-data-scientist)**

## **微软 Azure:**

**微软为数据科学家和人工智能工程师提供助理级认证,以及大约十几个其他认证。有些认证其实是需要多次考试的,但这不是(还不是?)数据科学家和人工智能工程师证书的案例。认证题目有点肤浅,但是考试不可小觑。**

*   **[微软认证:Azure AI 基础](https://docs.microsoft.com/en-us/learn/certifications/azure-ai-fundamentals)**
*   **[Azure 数据科学家助理](https://docs.microsoft.com/en-us/learn/certifications/azure-data-scientist)**
*   **[蔚蓝 AI 工程师助理](https://docs.microsoft.com/en-us/learn/certifications/azure-ai-engineer)**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/be89e134f7c704783bfebeb73bbaec35.png)**

**授予认证数据工程师的徽章。能够分享这样的徽章对个人品牌有很大的帮助。来源[这里](https://www.credential.net/a015b522-77d3-48c0-b7f7-16c9948a9ac4)。**

## ****谷歌云平台:****

**当谈到云服务时,谷歌是挑战者,他们的认证状态反映了这一点。目前 ML 工程师考试还在测试阶段,还没有颁发任何证书。考试考四(!)小时,但这是一个令人难以置信的关于 ML 工程师工作的全面列表。在这个认证推出之前,一些 ML 主题属于[数据工程师认证](https://cloud.google.com/certification/data-engineer),所以很多 ML 工程师,包括我自己,实际上都走了数据工程认证的轨道。**

**你也可以看看[谷歌云架构师](https://cloud.google.com/certification/cloud-architect)、[开发人员](https://cloud.google.com/certification/cloud-developer)或 [DevOps](https://cloud.google.com/certification/cloud-devops-engineer) 认证,但这些几乎没有涉及到它,可能会在你的简历上增加一点点噪音,让你适应不同的工作。我是作为一名认证云架构师这样说的,我从自己的经历中学到了这一点。另一方面,这会让你的个人资料更有吸引力。**

*   **[谷歌云认证专业数据工程师](https://cloud.google.com/certification/data-engineer)**
*   **[谷歌云认证专业机器学习工程师](https://cloud.google.com/certification/machine-learning-engineer)(目前在测试中)**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/034bb369567a56852585de80200b7855.png)**

**AWS 认证机器学习-专业的徽章。取自[这里](https://aws.amazon.com/certification/)。**

## ****AWS** :**

**Amazon 对分析角色和 ML 角色都有特定的路径。鉴于数据分析认证几乎完全专注于数据处理和报告,我认为只有 ML 专业才是 ML 工程师感兴趣的。他们的[机器学习专业的教学大纲](https://d1.awsstatic.com/training-and-certification/docs-ml/AWS-Certified-Machine-Learning-Specialty_Exam-Guide.pdf)涵盖了许多 ML 工程主题,尽管它不像谷歌认证那样详尽。**

*   **[AWS 认证机器学习—专业](https://aws.amazon.com/certification/certified-machine-learning-specialty/)**
*   **[AWS 认证开发人员助理](https://aws.amazon.com/certification/certified-developer-associate/)**

## **那么你应该买哪些呢?**

**目前,亚马逊是市场领导者,拥有大约 60%的市场份额。蓝色占 30%,GCP 占 10%。虽然整体市场增长很多,但 AWS 的市场份额正在慢慢输给谷歌和微软。谷歌可能看起来像一个失败者,但他们在人工智能创新和对 TensorFlow 的所有权方面有着非常好的记录。说到这里,[还有一个 TF 的证书。](https://www.tensorflow.org/certificate)如果你没有被雇主强迫使用一个云供应商而不是另一个,我建议用试用账户和部署一个宠物项目来测试所有三个。弄清楚你喜欢哪一个,也看看什么样的公司使用这些云供应商。**

**你到底为什么需要云技术?嗯,最终数据科学工作会进入生产阶段,并且大多数时候会部署在云平台上。你不需要比肩云工程师的技能,但你应该知道如何在你选择的平台上实现 ML 项目。他们通常不会在大学这样的正式场所教授如何操作{vendor}云控制台。**

**学习云平台也有不好的一面:**几乎没有一个星期没有这些巨头发布新的云产品**。跟上云产品的发展很难。拥有各种各样的证书也让人怀疑你是否真的符合所有的标准。**

**你可能已经注意到,到目前为止,我没有链接任何课程或教程。这方面已经有很多资源了。此外,我的主要观点是,成为 ML 工程师的道路是通过做项目和获得该领域的经验来走的,因为它不是一个入门级的工作。**

# **构成 ML 工作的变化**

**当你做了所有这些,你应该知道在小公司工作和做 ML 和在 FAANG 工作和做 ML 有天壤之别。同样,在“产品”公司工作和在咨询公司工作也有很多不同。同样,就技术适应性而言,银行和初创企业是两个不同的世界。**

**在小公司,你更有可能成为一个多面手,例如,被要求做数据工程、可视化和数据科学方面的工作,作为你日常活动的一部分。较大的公司更有可能雇佣专注于 ML 链特定部分的特定员工,甚至可能有不同类型的 ML 工程师四处奔波。如果你在一家做许多不同项目的公司,你可能永远不会深入到任何框架中,但是会经历许多种类的工具和领域。当你打算找你的第一份 ML 工作时,这些都是你要记住的具体考虑。**

# **准备失败**

**在计算机科学中有一个稍微有害的概念,即优秀的开发人员几乎不会犯错误,优秀的代码没有错误。这完全是胡说八道,它已经导致了 T2 冒名顶替综合症的流行。代码几乎从来没有一次写对,这是一个高度依赖于投入的时间和金钱的过程。你作为这个领域的工程师成长很多,但同时这个领域也会比你成长的更快。作为一名 ML 工程师,你必须不断地在工作中学习新的东西,并且由于身处一个跨学科的领域,你放弃了一些对编码的精通。**

**我定期回顾前一段时间写的代码,发现自己犯了错误。有时候,我会用我现在掌握的知识重写它,或者看看是否可以将旧模型更新为新版本的 API。一些开发人员发誓彻底扔掉密集的代码,从头开始重写。随着时间的推移,你会产生一种追溯性地检测代码气味的感觉,这就是工程的意义所在。**

**不要害怕犯错误。失败是很自然的,尤其是像 ML 这样的新生事物。**

# **机器学习工程师的阅读清单**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ddbde2d4c02721b19599c8d5678cece5.png)**

**一个机器学习工程师的书柜。注意线性代数及其应用的破旧拷贝。作者照片。**

**虽然这并不意味着是一个完整的列表,但我觉得这里有一些资源可以帮助那些想进入这个领域的人。**

****书籍:****

*   **罗伯特·c·马丁的《干净的代码》**
*   **[机器学习向往](https://www.deeplearning.ai/machine-learning-yearning/)吴恩达著**
*   **伊恩·古德菲勒、约舒阿·本吉奥和亚伦·库维尔的《深度学习》**
*   **戴维·托马斯和安德鲁·亨特的《实用程序员》**
*   **[设计数据密集型应用程序:可靠的、可伸缩的和可维护的系统背后的重要思想](https://www.amazon.com/Designing-Data-Intensive-Applications-Reliable-Maintainable/dp/1449373321)马丁·克莱普曼著**

****帖子/博客:****

*   **如何阅读 Christoph Schmidl 的科学论文**
*   **关于成为一名自学成才的 ML 工程师,你需要知道的一切。**
*   **拉胡尔·阿加文的《2020 年成为数据科学家》将吸引那些寻找在线资源列表的人。**
*   **Openai 的博客**

**论文:**

*   **[机器学习系统中隐藏的技术债务](https://papers.nips.cc/paper/5656-hidden-technical-debt-in-machine-learning-systems.pdf)**
*   **[机器学习的软件工程:案例研究](https://ieeexplore.ieee.org/abstract/document/8804457)**

# **会议、聚会和 ML 工程场景**

**有人恨他们,有人爱他们。有些人把它们作为最大限度地自我推销的方式,而其他人则分享绝对精彩的想法。我喜欢[meetups](https://www.meetup.com/),原因很简单,他们可以让你挑选你想了解的话题。你喜欢 Scala 吗?医疗保健中的人工智能?聚会。更喜欢贝叶斯优化?可能会有一个聚会。由于 Corona,大多数聚会已经完全在线,我预计这至少会持续到 2021 年上半年。**

****普罗提普**:如果你想找一份实习、工作或导师,它们非常适合社交。**

# **其他职业**

**对于那些考虑进入这个领域的人来说,还有一些其他的职业值得一提。**

*   ****数据工程**:任何涉及数据的东西都需要能够处理大规模和复杂的转换。你是专门连接数据管道的不同元素的人。对你的服务的需求通常比对机器学习工程师的需求高得多。**
*   ****数据科学家:**分析、讲故事、统计、机器学习并将其呈现给 CEO。你得到了一切。通常这份工作更加多样化,涉及的编程更少,但这真的取决于你最终在哪里工作——数据科学有如此多的风格,很难将其定义为一个单一的角色,一些数据科学家自己管理着一个完整的数据分析部门。**
*   ****云工程:**专注于集成不同的应用程序并将工作流迁移到云,你是数据和 ML 工程师的好朋友。**

# **结论**

**一个机器学习工程师需要从机器学习和软件开发中了解广泛的主题。到 2020 年,课程和证书并不能让你达到目标。该领域的正式培训或经验仍然是可取的,但我希望随着时间的推移,它会变得更容易获得,就像数据科学对新人变得更加开放一样。考虑到这一点,我觉得对于那些没有经过正式培训就想成为 ML 工程师的人来说,最好的途径是进入数据科学或软件工程,然后从那里转行,同时学习构成 ML 工程的元素。**

## **结束语**

**随着该领域的快速发展,我希望在未来的帖子中关注 ML 工程技能集和工具前景,通过收集招聘信息并对其进行一些变戏法,以便对 ML 工程师可能知道的东西进行更可靠的统计分析。想知道是否应该通过 PyTorch 学习 TensorFlow?敬请关注:)**

**通过这篇文章,我增加了越来越多的数据科学文章。希望你觉得有用。我想写一些对那些目前不在这个领域的人来说容易理解的东西,我希望我的两美分能帮助你弄清楚这个 ML 和工程的利基是否适合你。**

# 如果你是数据科学家,如何成为一名软件工程师

> 原文:<https://towardsdatascience.com/how-to-become-a-software-engineer-if-youre-a-data-scientist-2619ac1ef7e4?source=collection_archive---------6----------------------->

## 意见

## 从机器学习走向通才,在不确定的未来茁壮成长

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6f350993262bcc016f8cb479d3e56c0c.png)

来自 [Pexels](https://www.pexels.com/photo/woman-in-black-tank-top-3861962/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels) 的 [ThisIsEngineering](https://www.pexels.com/@thisisengineering?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels) 摄影

*免责声明:这是一篇观点文章。很想听听你下面的想法。*

**“我是一名数据科学家。我如何成为一名软件工程师?”**

我被问到的次数比你想象的要多。

有很多关于从软件工程师(SDE)到数据科学家(DS)的文章。但很少有人研究相反的情况。

我两者都做过。接受采访和被采访。在喝咖啡的时候遇见了几百个人。

下面是成功转换需要学习的内容。

*免责声明:并非每个人都需要学习所有这些。许多角色只需要一个子集。这与成为全栈开发者有关。*

# **学习后端(服务器端)web 框架**

这是发展的核心。你需要一个框架来构建应用程序。软件的现在和未来都在 web 上,所以我们只讨论 web 框架。

其中包括:Rails (Ruby)、Django (Python)、Express (Node)、Laravel (PHP)、Spring Boot (Java)…

你需要选择一个并提交。这是令人不安的,但在开始时,深入一个而不是广泛几个。

**专业提示:**你不需要选择现在最热门的框架。

公司在使用他们最初选择的框架时会陷入困境,因此选择几年前流行的框架可能会更有利。竞争将会减少,因为新的开发者将不再学习它。

如果你已经了解 Python,选择一个像 Django 一样使用它的框架是很有诱惑力的。也就是说,大多数数据科学家(大多数人?)都是黑客,写不出优质代码。因此,选择一个需要学习一门新语言的框架实际上并不困难。

我们开始选择框架,而不是语言,因为框架允许构建应用程序,即使编码技能很差。不要低估轻松取胜对自信和成功的重要性。

**作业:**选择一个框架。

# **学习你的框架语言**

你已经选择了一个框架。所以这里不需要做任何决定。学习你的框架语言。

如果你选择了 Rails,学习 Ruby。如果你选择了 Django,那就学 Python 吧。如果选择了 Express,那就学 JS 吧。

我用“学习”这个词很不严谨!

不要试图掌握语法。那会花太长时间。在 [Codecademy](https://www.codecademy.com/) 上学习基本语法,然后学习一些面向对象的编程。

1.  我们只是想在语言方面做得足够好,这样我们就可以有效地使用这个框架。
2.  你会忘记语法,无论如何都需要去查。

现在继续,在精神上区分语言和框架。它们不是一回事。不要犯那个新手的错误。

**作业:**学习基本语法,面向对象编程,用你的语言做几道[初学算法题](/3-algorithm-interview-questions-for-data-science-and-software-engineering-in-python-29fc86a07a6f)。

# **学习前端(客户端)web 框架**

这是 2020 年全栈发展的要求。

*免责声明:你可以通过学习在 jQuery 中组装响应性前端来暂时绕过这一步,然后在工作中获得一个前端框架。*

假设你选择学习一个前端框架,学 React 就好了。有许多框架都有自己的优势,但是有足够多的公司使用 React,您可以放心地选择它。

你不需要成为一个前台向导。但是要学会实现基本的设计模式,理解客户端和服务器端代码的区别。

**作业:**学习 React 基础知识,以及如何将其与你的后端框架集成。

# **学习造型**

学习一些 HTML 和 CSS。

**亲提示:**一个产品看起来怎么样,就是产品。让应用程序看起来漂亮被低估了。

你不需要从头开始创造美丽设计的能力。你只需要足够优秀就能从中汲取灵感(复制?)其他网站。

模仿是所有发明之母。无论如何,你加入的几乎所有公司都会有自己的风格指南。

作业:创建一个好看的启动页面,灵感来自你欣赏的其他公司的设计。

# 学习用于 web 开发的数据库

如果你在 DS 工作过,你可能对 SQL 没有问题。

但是大部分 web apps 很少直接使用 SQL。他们几乎总是使用框架或语言的 ORM 与数据库进行交互。

这是一个预定义的 API,用于执行常见的数据库事务,在高级编程语言中公开。

Rails 使用 ActiveRecord。Python 有 SQLAlchemy…

如果您没有设置特定的数据库,请选择 PostgreSQL。

1.  它功能丰富,很多公司都在使用它。
2.  这种体验将转化为使用其他关系数据库。
3.  暂时避开 NoSQL。大多数有用的数据本质上都是关系型的。NoSQL 数据库的一个很好的用例是例外而不是规则。

**家庭作业:**为你的语言或框架学习一个 ORM

# **学基础设施**

这里的门槛低。不要走得太深。

不需要掌握 GCP 或 AWS。你会在工作中更快地学会这些,而且它们因公司而异。

只要弄清楚如何在像 [Heroku](https://www.heroku.com/) 这样的平台即服务平台上部署你自己的应用程序。

**作业:**在 Heroku 上部署一个 app。

# **建立投资组合**

用你学到的知识构建一些应用程序。这是证明你知道如何做某事的最好方法。

比起“记忆”,更喜欢“做并记录”。

如果你需要重新查找你是如何做某件事的,这很好。软件工程师是索引,不是机器人。

有趣的是,投资组合比解决算法问题的能力更重要。除非你想在脸书或亚马逊工作。

专业提示:让你的应用程序变得漂亮是一个巨大的优势,即使你想成为一名后端开发者。这会不自觉地让面试官对你的看法产生偏差。

**家庭作业:**开发一些应用程序,展示你具备以上所有能力。

# **为什么你应该这样做**

如果你是人工智能博士,有能力做研究级的 ML,不要这么做。我在人力资源部的朋友告诉我,100 多万美元的薪水在等着你。

对于其他人来说,这很有意义。

随着 [ML 继续变得越来越容易](/machine-learning-is-getting-easier-software-engineering-is-still-hard-d4e8320bc046),它最终会被软件工程,也就是“产品”所吞噬。

1.  没有 ML 组件,[数据科学只是专注于决策和优化的高能业务分析](/data-scientists-are-the-new-investment-bankers-149e80d86ba2)。那就没那么有趣了,更有竞争力了。
2.  作为一个多面手,SDE 有更多的机会。没有 SDEs 就不能建立一个公司,哪怕是一个 AI 公司。
3.  了解完整的技术体系会让你更好地解决所有问题,因为你知道各个部分是如何组合在一起的。
4.  更容易推出自己的 AI 公司。

[学软件工程](/dont-become-a-data-scientist-ee4769899025)。

# 结论

这是故意非常固执己见。根据我的经验,这是成功转型的最佳方式。

也就是说,这不是福音,你应该根据你自己的研究行动。

如果您涵盖了所有这些,并且已经有了 DS 经验,那么您将远远领先于大多数开发人员。

最后,尽快找份工作。你会比自己学得更快。

# 如何在没有任何经验的情况下成为 Tableau 开发人员

> 原文:<https://towardsdatascience.com/how-to-become-a-tableau-developer-without-any-prior-experience-ad805f765b4a?source=collection_archive---------38----------------------->

## 成为 Tableau 开发者的简单指南

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/390012defa291bfcc3c515d5ede3e553.png)

*图片经由*[](http://Shutterstock.com)**授权给泰勒*罗杰斯。照片由[福克西·陋居](https://www.shutterstock.com/g/Foxyburow)拍摄。*

*Tableau 开发是一项伟大的事业。*

*首先,报酬丰厚。薪酬通常高于数据科学专业中其他更具技术挑战性的工作。根据 [Glassdoor](https://www.glassdoor.com/Salaries/us-tableau-developer-salary-SRCH_IL.0,2_IN1_KO3,20.htm) 的数据,Tableau 开发人员的平均工资为 81514 美元,高于数据库开发人员、统计人员和数据分析师。(更多薪资细节见脚注。)*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9052f6d3f046c9c48a9310bcb9d3b7a6.png)*

*数据取自 Glassdoor*

*工作生活平衡也不错。你可以经常远程工作,这个领域的工作很少需要加班。如果你变得非常优秀,并能有效地推销自己,你可以一份接一份地工作,从而提高灵活性和收入。*

*Tableau 开发也有很高的需求。作为 Tableau 开发人员工作一年后,你会经常接到招聘人员的电话。有时一周内会有多次电话。*

*最棒的是,这是商业智能中最具创造性的工作。在这个领域,没有其他工作比画面开发更能锻炼你的审美能力和讲故事的能力。*

## *成为 Tableau 开发人员不需要特殊的背景*

*你可能会想,如果这份工作这么好,需求量这么大,我有资格吗?做 Tableau 开发人员不需要计算机科学背景或者懂高级统计学吗?*

*这两样东西你都不需要!*

*虽然你通常需要一个大学学位,但什么学位并不重要。你有什么工作经验也不重要。*

*以下是我所知道的最有才华的 Tableau 开发人员的一些不同背景:*

*   *教育*
*   *英国文学*
*   *装帧设计艺术*
*   *营销*
*   *工商管理硕士*
*   *销售*

*如果你注意到,这些都不涉及计算机科学。*

*事实上,我认为具有传统文科背景的人在 Tableau 开发中具有优势,而许多其他数据科学学科确实需要 STEM 背景。*

## *作为 Tableau 开发者需要什么?*

*Tableau 是关于使用好的数据可视化和好的设计技术来用数据讲述故事。它包括善于与人相处,问正确的问题,以提供利益相关者真正理解并经常使用的仪表板。*

*编程方面往往很有限,也很好学。如果你能理解下面的步骤以及我是如何得出结论的,你就能学会 Tableau 所需的编程了:*

1.  *A = 3*
2.  *B = 6*
3.  *A = B*
4.  *A + B = 12*

*关于统计,Tableau 开发中涉及的计算也不先进。它通常局限于简单的概念,如平均值、最小值和最大值。*

## *我如何被聘为 Tableau 开发人员?*

*Tableau 内部人才缺口很大。这意味着许多经理不得不雇佣有能力和兴趣的人,而不能雇佣有经验的人。*

*如果你能展示出这种能力和兴趣,你将更容易找到一份 Tableau 开发人员的工作(或其他相关的角色,如报表开发人员或 BI 开发人员)。*

## *如何展示对画面开发的能力和兴趣*

*展示 Tableau 开发能力和兴趣的最佳方式是在业余时间开发 Tableau 仪表板,并参与充满活力的 Tableau 社区。*

*更具体地说,您可以执行以下操作:*

1.  *下载 Tableau Public 或 Tableau Desktop*
2.  *使用公开可用的数据构建和发布 Tableau 仪表板*
3.  *阅读关于数据可视化的好书*
4.  *上课*
5.  *获得认证*
6.  *参加 Tableau 用户组*
7.  *与 Tableau 用户组的人交谈*
8.  *邀请你在 TUG out 认识的人去喝咖啡或吃午餐*
9.  *学习(刚刚够)SQL*
10.  *了解优质工作是什么样的*

*请继续阅读,以获得对每一点的更详细的解释。*

## *#1:下载 Tableau Public 或 Tableau Desktop*

*要开始构建 Tableau 仪表盘和数据可视化,您需要下载 [Tableau Public](https://public.tableau.com/en-us/s/download) 或 [Tableau Desktop](https://www.tableau.com/products/desktop/download) 。*

*Tableau Public 免费。这是我推荐的开始。Tableau Public 不允许连接数据库,但是可以导入原始数据文件(XLSX、CSV、JSON 等。).此外,您构建和保存的任何内容都将保存在[public.tableau.com](https://public.tableau.com/)上。即使您可以更改您发布的仪表板上的设置,使其成为私有的,我仍然会避免使用任何带有机密或私有数据的内容。*

*如果你想花 840 美元,你可以购买 Tableau Desktop 的年度订阅,并使用其他类型的数据源进行练习。因此,如果你在一家拥有谷歌分析或 SQL Server 等数据源的公司工作,你可以连接到它们,并练习使用 Tableau Desktop 中的数据。*

## *#2:使用公开可用的数据构建和发布 Tableau 仪表板*

*随着您越来越擅长构建数据可视化和仪表板,您希望将它们发布到 [Tableau Public 的图库](https://public.tableau.com/en-us/gallery)上,供其他人查看。这可以让你展示你的能力和兴趣。*

*由于这个原因,你需要公开的免费的非机密数据。*

*幸运的是,你可以使用大量有趣的数据。你可以使用来自雅虎财经的金融市场数据。其他人用的是运动数据(不知道怎么找那种数据)。最好的资源是 [Kaggle](http://kaggle.com) ,它有许多免费的数据集可供数据科学专业人士练习。*

## *#3:阅读关于 Tableau 和数据可视化的好书*

*你认为你知道什么是好的仪表板或数据可视化吗?如果你不知道基本的规则(比如没有饼状图),那么就很容易搞砸。*

*幸运的是,有很多好书可以帮助你进行有效的数据可视化,避免这些错误并提供好的见解。*

*这里有三本强烈推荐的书:*

1.  *瑞安·斯勒伯的实用场景*
2.  *阿尔贝托·开罗的功能艺术*
3.  *爱德华·塔夫特对数量信息的直观展示*

## *#4:上课*

*没有什么比在 Tableau 上一堂课更能表现出对 Tableau 的兴趣了。如果你之前没有工作经验,这对招聘经理来说是一个信号,他们不需要花时间培训你的基础知识,你足够关心这个职业来参加课程。*

*此外,课堂可以让你通过自学学到你可能会错过的东西。即使你是一个很好的自我激励者,并且通常会自学大部分新技能,一堂课也会大大缩短你学习工具的时间。*

## *#5:获得认证*

*在 Tableau 中获得[认证](https://www.tableau.com/learn/certification)证明了资质。如果您以前没有构建 Tableau 仪表板的工作经验,建议您这样做。*

*招聘经理会看到你不仅学到了材料,还能从外界得到你知道自己在做什么的证明。*

*在你被雇佣后,不要浪费时间去获得更多的认证。事实上,从来没有人要求我获得认证,因为我已经展示了工作经验和 Tableau 仪表盘组合。*

## *#6:参加 Tableau 用户组*

*这是一个大问题,对寻找工作机会有很大帮助。*

*大多数大都市都有 Tableau 用户群(我们通常称之为“TUG”)。如果你想知道下一次 TUG 活动的时间和地点,请访问此处的链接[找到社区页面。](https://public.tableau.com/shared/JK8X9ZFP2?:display_count=yes&:origin=viz_share_link&:showVizHome=no)*

## *#7:与 TUG 的人交谈*

*Tableau 用户群体(像大多数专业技术群体一样)有一个安静的人的名声,他们站在角落里,什么都不说。*

*不要成为那种人。*

*走到人们面前打招呼。向其他听众和演讲者介绍你自己(演讲者喜欢听到对他们演讲的赞美,仅供参考)。*

*当你与这些人交谈时,要求在 LinkedIn 上与他们联系。(可以在这里连接我的 LinkedIn [。)](https://www.linkedin.com/in/taylor-rodgers-4b8632127/)*

## *#8:邀请你在 TUG Out 认识的人去喝咖啡或吃午餐*

*信不信由你,你不必等到下一次 TUG 活动再去和你遇到的人说话。你也可以在这些活动之外遇到他们!*

*随着你建立更多的联系,邀请你联系过的人一起喝咖啡或吃午餐。(确保你主动付款)*

*在这些聚会中,问他们关于他们自己职业的真诚问题,以及他们如何在他们的组织中使用 Tableau。你也可以寻求找工作的建议。他们可能知道谁在招聘,以及这些人在候选人身上寻找什么。*

*无论你做什么,不要直截了当地去找工作。你可以问他们是否有职位空缺,如果有就去申请,但是不要突然提出工作要求。*

*多年来,我经常和人一起吃午餐、喝咖啡。结果很多次,我都被要求去申请工作。有一次,我未经询问、申请或面试就直接得到了一份工作。*

*但是我从来没有——从来没有——去参加过这样的会议,并打算从中获得一份工作。*

*这些会议是关于在更广泛的分析社区内建立关系。把*建立关系*作为这些聚会的目标,好事就会随之而来。*

## *#9:学习(刚刚够)SQL*

*您将使用 Tableau 连接的大多数数据都存在于 SQL 数据库中。虽然情况并非总是如此,但许多公司将数据库开发和 Tableau 开发分成两个独立的角色。因此,不懂高级 SQL 不会妨碍你在这个职业领域工作。*

*但是,即使您不想编写高级脚本来操作数据,您仍然需要学习足够的 SQL 来应付。具体来说,您需要知道如何编写 SELECT 语句以及 WHERE 子句。您还应该知道 GROUP BY 和 ORDER BY 命令。*

*你可以在这个[链接](https://www.w3schools.com/sql/)上一些关于如何编写 SQL 的免费课程。*

*如果你想学习更多的 SQL,并将其与 Tableau 开发职业相结合,你可以担任一个名为*商业智能开发人员*的角色,这包括两种技能。这些角色在不需要专业化的低容量团队中更受欢迎。*

## *#10:了解优质工作是什么样的*

*数据团队的最佳实践是一个团队成员对另一个团队成员的工作进行质量检查。不是每个团队都这样。但是这仍然是你应该发展的一项技能(它也将帮助你改进你自己的仪表板)。*

*当你开发自己的仪表板并发布在 Tableau Public 上时,要善于对自己的工作持怀疑态度。*

*向自己证明你的数据和你的工作是准确的,并按预期工作。你可以通过反复检查你的工作来做到这一点。*

*如需仪表板质量检查的免费指南,请点击此[链接。](https://www.taylorrodgers.com/quality-checking-guide.html)*

## *最后一个提示?申请 Tableau 工作!*

*上面概述的所有步骤都会增加你找到 Tableau 开发人员工作的机会,但是你不必等到完成所有十个步骤后才开始申请。*

*走出去,开始在 LinkedIn、Ziprecruiter 等网站上提交 Tableau 职位的申请。一开始你可能会很幸运。*

*如果没有马上找到工作,也不要绝望。继续向雇主展示你对这个职业领域很感兴趣,并且有能力做好它。归根结底,大多数(聪明的)雇主更愿意和对工作充满热情的人一起工作,而不是和有丰富经验却毫无热情的人一起工作。*

***脚注**
如果你没有任何专业工作经验,40-50k 美元是 Tableau 开发的合理起薪。如果你有专业工作经验,但之前没有 Tableau 经验(或其他数据分析角色),55-65,000 美元是一个合理的起薪。
这些工资估算是基于我过去作为开发人员和经理的经验,以及来自 Glassdoor 的数据。虽然我不能保证你会赚到这些确切的数额。*

**原载于*[*https://www.taylorrodgers.com*](https://www.taylorrodgers.com/business-intelligence/how-to-become-a-tableau-developer-without-any-prior-experience)*。**

# 如何在 10 天内成为 AWS 认证云从业者

> 原文:<https://towardsdatascience.com/how-to-become-an-aws-certified-cloud-practitioner-in-10-days-83a08e316e72?source=collection_archive---------3----------------------->

## 学习时间有限的人 10 天通过 AWS 考试的详细学习计划

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/810b05be6a9094cb3d6af2bc702f3467.png)

艾萨克·奎萨达在 [Unsplash](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

最近我以 882/1000 的成绩通过了 **AWS 认证云从业者**考试。有限的云经验,我花了 10 天准备考试,每天大概学习 4 到 5 个小时。

在这篇文章里,我想和大家分享一下我的备考经验。如果你的学习时间有限,并且正在寻找一个高效的学习计划,这篇文章就是为你准备的。

# 为什么选择 AWS 认证云从业者?

如果你正在阅读这篇文章,你可能会同意云计算是未来的发展方向,AWS 是最受欢迎的云平台。

AWS 认证云从业者证书是 AWS 众多证书中的入门级别。它很好地介绍了广泛的 AWS 服务,包括许多最重要的服务,如 EC2 和 S3。因此,如果您是云新手,学习该考试将为您进一步学习 AWS 提供坚实的基础。

> 请记住,我们的目标是更好地了解 AWS 服务,**而不是**简单地获得认证!

# 10 天终极学习计划

就涵盖实际考试内容而言,我的考试准备非常有效。然而,当回头看时,仍然有几件事我会用不同的方式来更好地利用我的时间。

下面的学习计划涵盖了你需要的所有准备材料,我已经以最符合逻辑的方式对它们进行了排序,以增强你对内容的理解。让我们看一看。

## 1.“大局”——5 天

你想尽快了解考试要求的最重要的内容,这样你就可以优先安排你的学习时间,把重点放在你最薄弱的地方。最快最有效的方法是参加**在线考试准备课程**。这些课程结构良好,涵盖了适当的深度,有助于了解 AWS 的情况,而不会有学习不必要主题的风险。

网上有很多课程选择,你可以以非常便宜的价格或者免费试用。推荐 Linux Academy,一个云大师,还有 Udemy。只要确保课程有**至少 15 小时的内容和实验演示。**

> 动手经验对所有 AWS 考试都很重要!

在您的学习期间,**关注以下这些领域**,并在 AWS 网站上做**动手练习**。确保你把每一步都内化了。绘制图表是研究服务的一个非常好的方法。

> 这些领域没有“过度研究”:IAM、EC2、S3、定价和支持。
> 
> 画出自己的网络服务图:VPC、子网、路由表、NACL、互联网网关、NAT 网关、Route53、ELB、CloudFront 等。
> 
> 安全:什么是安全相关的服务,它们有什么区别?

## 2.模拟考试和文档— 1 天

到目前为止,您应该对主要服务有了较高层次的理解,所以是时候测试您的知识以获得基线了!在线课程通常有模拟考试。至少尝试一次考试,分数不高也不用担心——我第一次尝试只有 72%!目标是了解你应该花更多时间关注哪些领域。对于你做错的每一道题,不要只看模拟考试提供的正确答案,你应该去 AWS 网站检查为什么它是正确的,并从 AWS 全面详细的文档中找到原话。

## 3.不要吝啬白皮书!— 3 天

直到我阅读白皮书时,我才意识到许多模拟考试问题都是根据白皮书制作的。我怎么强调它们的重要性都不为过。有许多白皮书,但是对于该认证,AWS 网站推荐其中的 4 个:

[亚马逊网络服务概述](https://d0.awsstatic.com/whitepapers/aws-overview.pdf)

**90 页:**前 10 页是对云计算的介绍,其余是对每一个单独的 AWS 服务的介绍。

[云架构:AWS 最佳实践](https://d1.awsstatic.com/whitepapers/AWS_Cloud_Best_Practices.pdf)

**40 页:**有些内容超出了本次考试的范围,但是对于理解服务之间的关系并将其分组在一起非常有帮助。

[AWS 定价的工作原理](http://d1.awsstatic.com/whitepapers/aws_pricing_overview.pdf)

20 页:请把这篇文章的每一个字都读一遍。关于这个话题,我有数量惊人的问题!

[比较 AWS 支持计划](https://aws.amazon.com/premiumsupport/plans/)

只有一页:再一次,一个小文件,但却值得你在考试中打很多分!

> 我知道你在想什么——“要读的书真多!”这里有一个非常有用的小技巧拯救了我的眼睛:使用 PDF 自动语音功能!让电脑给你读,你会更好地记住内容,而不会睡着。

## 4.模拟考试和练习更新— 1 天

考试前一天,再试一次模拟考试;现在你应该有 80-100%的准确率。然后通过浏览 AWS 网站来刷新您的记忆。打开每个服务页面,观看 2-3 分钟的介绍视频,问问自己这项服务是做什么的,这并没有什么坏处。如果你发现对你的记忆有帮助的话,不要忘记再次练习核心服务!

> 考前一晚好好睡一觉,自信一点!

# 关于考试的杂事

1.  您可以通过 PearsonVUE 在家中使用自己的电脑在线参加考试。你将被要求测试你的电脑和网络,你需要在考试前和考试前分别测试一次。你需要从四个方向拍摄你的身份证和你的房间。考试当天,监考老师会在签到阶段通过 chatbox 和音频与你聊天。
2.  考试签到在预定考试时间前 30 分钟才会发生,考试最多只会比预定时间提前 15 分钟开始。所以不要太早登录系统——我不得不坐在我的笔记本电脑前,超过 20 分钟不能做任何事情!
3.  你不会在考试后马上知道你的分数,但完成后屏幕会立即告诉你是否通过。它说这可能需要 5 个工作日,但从我的经验来看,它只有大约 12 个小时,我收到一封电子邮件说我的分数是可用的。

# 下一步是什么?

我计划在未来通过参加另一个考试来进一步提高我的 AWS 知识。

祝好运,云学习愉快!

# 如何成为数据流机器学习的专家?

> 原文:<https://towardsdatascience.com/how-to-become-an-expert-in-machine-learning-for-data-streams-3ecbb612b641?source=collection_archive---------16----------------------->

## 实时分析和流学习概述和资源

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4b6ac0352db2c20cfb86e3c264ea29d7.png)

实时决策中心(图片来自[https://images.app.goo.gl/FZbmaM1XbT5fQQzn8](https://images.app.goo.gl/FZbmaM1XbT5fQQzn8)带许可证 CC BY 2.0)

大数据范式在过去十年获得了发展势头,因为它承诺为许多现实世界的应用提供有价值的见解。随着这种新兴模式的出现,不仅可用数据量增加,而且数据到达速度的概念也随之增加,即这些现实世界的应用程序实时生成数据的速度快于传统系统的处理速度。大数据范式的一个特例是数据流的*机器学习* ( *实时数据挖掘、实时分析**流学习)*,其中可能是无限的项目序列(数据流)连续到达,并且其中每个项目都有时间戳,因此有时间顺序。数据流一个接一个地到达,我们想要实时地建立和维护这些项目的模型(例如,预测器)。

这种情况使我们认为,我们必须处理潜在的无限和不断增长的数据集,这些数据集可能以批量实例或逐个实例的方式连续到达,这与传统系统(批量学习)形成对比,在传统系统中可以自由访问所有历史数据。这些传统的处理系统假设数据是静态的,并且是同时被访问的。例如,数据库系统可以存储大量数据,并允许用户运行查询或事务。基于批处理的模型不会不断地将新信息集成到已经构建的模型中,而是从零开始定期地重建新模型。然而,由*流学习*执行的增量学习通过不断地将信息结合到其模型中来呈现这种特定流处理的优势,并且传统上旨在最小化处理时间和空间。由于其连续大规模和实时处理的能力,增量学习最近在大数据背景下获得了更多的关注。*流学习*也提出了许多新的挑战,并提出了严格的条件:在每个时刻,只有单个样本(或一小批实例)被提供给学习算法,非常有限的处理时间,有限的内存量,以及在数据流的每次扫描中都有训练模型的必要性。此外,这些数据流可能会随着时间的推移而演变,并且可能偶尔会受到其数据分布变化的影响(*概念漂移*),迫使系统在不稳定的条件下进行学习。

我们可以找到许多真实世界*流学习*应用的例子,例如移动电话、工业过程控制、智能用户界面、入侵检测、垃圾邮件检测、欺诈检测、贷款推荐、监控和交通管理等。在这种背景下,物联网(IoT)已经成为*流学习*的主要应用之一,因为它正在持续实时地产生大量数据。物联网被定义为通过网络连接到计算系统的传感器和执行器,它实时监控和管理连接的对象或机器的健康和动作。因此,流数据分析正在成为从每时每刻发生的事情中提取有用知识的标准,允许人们或组织在出现不便或新趋势时快速做出反应,帮助他们提高绩效。

这篇文章声称是一个起点,以介绍在这个新潮的研究和应用课题。

## 推荐读物

有一组科学论文值得推荐,以给出该领域的广泛概述:

*   *面向流媒体数据的机器学习:现状、挑战和机遇* (2019)
*   *概念漂移下的学习:综述* (2019)
*   *表征概念漂移* (2016)
*   *概念漂移应用概述* (2016)
*   *大数据流分类器的高效在线评估* (2015)
*   *非稳定环境中的学习:一项调查* (2015)
*   *概念漂移适应调查* (2013)
*   *概念漂移下的学习:概述* (2010)

现在,我们可以在现有技术中找到几个具体的公开挑战。我想强调一下:

**1-增量学习**

*   *增量在线学习:对最先进算法的回顾和比较* (2018)
*   *评估和表征来自非平稳数据的增量学习* (2018)
*   *具有多级适应性的增量学习* (2011 年)

**2-漂移检测**

*   *流数据分类中的概念漂移检测没有免费的午餐定理:综述* (2019)
*   *概念漂移探测器大规模对比* (2018)
*   *概念漂移探测器的比较研究* (2014)
*   *关于特征漂移适应的调查:定义、基准、挑战和未来方向* (2017)

**3-组装**

*   *用于数据流分析的集成学习:调查* (2017)
*   *非平稳环境下的异构在线学习集成* (2019)
*   *在线和批量装袋和增压的实验比较* (2001)
*   *概念漂移系综的概述和综合比较* (2019)
*   *针对漂移和噪声数据流使用弃权分类器的在线集成学习* (2018)
*   *数据流分类集成学习综述* (2017)

**4-多样性**

*   *基于知识的系统多样性测量作为一种新的数据流漂移检测方法* (2019)
*   *数据流分类集成的新多样性度量* (2018)
*   *进化数据流中的集合多样性* (2016)
*   *存在概念漂移时多样性对在线集成学习的影响* (2010)
*   *多样性措施分析* (2006 年)
*   *切换类别标签生成分类集合* (2005)
*   *分类器集合中多样性的测量及其与集合准确度的关系* (2003)
*   *线性分类器装袋升压多样性实验研究* (2002)

**5-不平衡**

*   *概念漂移在线课堂不平衡学习的系统研究* (2018)

**6-预处理**

*   *数据流挖掘的数据预处理综述:现状与未来方向* (2017)

**7-评估**

*   *关于评估流学习算法* (2013)

**8-半监督学习**

*   *半监督学习的自我标记技术:分类、软件和实证研究* (2013)

**9-异常检测**

*   *网络异常检测综合调查* (2019)
*   *用于异常检测的深度学习:调查* (2019)
*   *非平稳数据流中的离群点检测* (2019)
*   *用于异常检测的实时大数据处理:调查* (2019)

**10-其他**

*   *数据流挖掘:处理概念漂移的方法和挑战* (2019)
*   *关于进化数据流和概念漂移适应的讨论和评论* (2018)
*   *如何在流数据挖掘中调整集成大小?* (2017)
*   *集成分类和回归:近期发展、应用和未来方向* (2016)
*   *针对概念漂移的数据流进行增量学习和遗忘的单类分类器* (2015)
*   *利用漂移流数据的主动学习* (2014)
*   *面向物联网的流数据融合* (2019)
*   *非平稳环境中的迁移学习* (2019)
*   *终身机器学习* (2018)

## 结论

随着所有这些现实世界的应用程序要求实时行为,这个领域每个月都在获得进步的势头。这绝对是当今机器学习领域最热门的话题之一。它充满了艰难的挑战。它需要新的想法和发展。它不仅是科学界最有前途的研究领域之一,也是机器学习从业者非常需要的技能。

# 如何通过三个简单的步骤毁掉你的第一份数据科学工作

> 原文:<https://towardsdatascience.com/how-to-bomb-your-first-data-scientist-position-in-3-easy-steps-25b85e2e4169?source=collection_archive---------12----------------------->

## 你可以既聪明又谦虚来避免这些陷阱。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d63461b9fdf1a86236f0b8171ff18e72.png)

蒂姆·高在 [Unsplash](https://unsplash.com/s/photos/frustrated?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

你做到了!你已经学习,完成了你的学位,并努力将公式翻译成代码。你已经在一些分析项目上崭露头角,并且记得清理你的 GitHub 账户。你成功通过了面试。你得到了梦寐以求的数据科学家的角色。是开始工作的时候了。你被选中是因为你聪明,你对自己的编码能力有信心,而且你很有效率。这些都是很好的品质,但是不要让它们把你引入歧途。如果你想避免一个充满挫败感和快速退出的世界,一定要避免这三个错误。

**你很聪明:忽略主题专家**

你有统计学硕士学位和物理学博士学位。你为开源项目做贡献。你摇滚酒吧智力竞赛之夜!你能行的。

是的,你得到了这个,但不是一个人。

你的中小企业将把你从难以置信的混乱和返工中拯救出来。他们会帮你准备好来自商业赞助人的难题。把它们赶走,后果自负。

项目中小企业了解业务问题。你们可以一起努力找出最合理的优化目标是什么。它们还可以帮助您衡量成果的成功(或“机会领域”)。

如果你非常幸运,你的主题专家会知道这些数据。他们知道 2018 年系统出现了一个漏洞,导致 3 月 12 日至 4 月 10 日之间的所有数据都无法使用。他们认为您的查询返回重复项是没有意义的(提示:您的一个连接有问题—不要只是删除重复项)。他们可以帮助评估主要特性,并确定它们对业务问题是否有任何意义。

你已经得到了编码印章:囤积你的代码

您的代码就像艺术品一样,包含您的个人偏好和商标。你想出了自己的新技术。你必须保护你的想法,把代码锁在你的个人图书馆里。当有人要代码时,你给他们发送代码片段。

这样不会受到同龄人的欢迎。囤积代码有各种各样的原因,但没有一个原因是自信或透明的。避免所有这些的建议是一样的。要谦虚。

第一次分享你的代码是令人生畏的。如果您在开发过程中要求反馈或审查一小部分代码,您将会建立与他人分享您的最终产品的信心。测试它也很有帮助。

另一方面,囤积代码让你的独特技能变得“不可或缺”不会像你想的那样奏效。你最多只能把自己挤到一个合适的位置。现在可能感觉安全,但从长远来看,对你的职业生涯来说通常不会有好结果。

**你富有成效:用详细的公式、统计数据和图表让你的商业赞助者大吃一惊**

你花了几个星期的时间开发了一个强有力的算法。它快速、准确、可解释。这是一件美好的事情。当被要求向商业赞助者展示你的发现时,你需要制作一个 20 页的幻灯片(当然还有一个附录),作为 NeurIPS 的演示。你在家对着镜子练习,你已经准备好了。

没那么快。你要确保吸引你的观众,让他们从手机和笔记本电脑上转移注意力。你需要眼神交流,希望他们能理解你在说什么。

如果你要向公司内的各种角色介绍你的工作,你需要为每一个观众量身定制你的信息。您可能需要创建具有不同细节级别的单独演示文稿。

这些年来我听到的反馈是,商业赞助者通常不理解数据科学家在做什么。一点都没有。具有讽刺意味的是,解决方案并不是去深入研究你的算法。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/eab992dc9401ec96a5db47f3854c5b9a.png)

谈论 ROC 图表,你会失去营销经理的注意力。(图为[](https://unsplash.com/@oviidaniel?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) [Unsplash](https://unsplash.com/s/photos/boring-meeting-sleeping?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的【羊内阿娇火】

如果你要在一个由商业赞助者举办的大型会议上演讲,保持简洁,关注商业成果。如果你没有展示你在解决业务问题上的进展,你可能会发现你的演示被打断了。将会提出困难的问题。稍后,您可能会被要求带着修改过的牌回来(如果您被要求回来的话)。

我建议让你的经理和一个值得信任的同事来审阅你的演示文稿以获得反馈。

如果您渴望深入研究不同的特征转换和算法,请与您的数据科学家同行安排一次会议。他们会问一些问题来帮助你验证你的结果,并提供有价值的反馈。你们可以一起研究选择激活功能。

显然,有很多方法可以毁掉一场演出。在下面分享你的经历,以警示他人。

# 利用 VSCode 上的定制代码片段提高效率

> 原文:<https://towardsdatascience.com/how-to-boost-your-efficiency-with-customized-code-snippets-on-vscode-8127781788d7?source=collection_archive---------26----------------------->

## 与其为同一段代码重新生成,为什么不把它保存起来供将来使用呢?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/320b6d68ab84683f95a581d9c3e85f79.png)

由[罗曼·辛克维奇](https://unsplash.com/@synkevych?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片

# 动机

对于数据科学从业者和程序员来说,不可能记住每一行代码来执行特定的任务。因此,忘记以前处理过的任务的代码是很常见的。

但是,与其多次搜索同一条信息,不如将代码片段保存在某个地方,然后在需要时访问它,这样不是更快吗?

我一直使用[要点](https://gist.github.com/khuyentran1401)作为占位符来保存我所有的片段

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5404e3229d15ab79b7ac8d6240f2f1f0.png)

但是我要花 30 多秒才能访问网站,找到我想要的代码片段,然后将代码复制并粘贴到我的脚本上。有没有一种方法可以让这个过程更快?有多快?**在 1s。**

例如,如果我想使用代码来创建动画,如果我可以像这样在我的脚本上键入,会不会很棒

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f026d911895611112cea7c7ae7024334.png)

代码片段显示在屏幕上?

这可以通过 VSCode 轻松完成。我喜欢 VSCode 不仅是因为它的键盘快捷键,还因为它提供了强大的扩展。在本文中,我将向您展示我用来毫不费力地创建和访问代码片段的方法。

# 轻松创建代码片段

要创建或编辑您自己的代码段,请在“文件”>“首选项”(“代码”>“macOS 上的首选项”)下选择“用户代码段”,然后选择语言。

例如,我的 Python 代码片段将被写入文件`python.json.`中。代码片段的结构包括标题、前缀(触发代码片段的单词)、正文(代码片段)和描述。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/81ac323a351ec046aac6161197729f6e.png)

这种创建 snippet 的方法工作得很好,但是创建一个 snippet 会花费相当多的时间,尤其是当代码很长的时候。

这就是你喜欢`Snippet Creator` 分机的原因。要启用创建代码片段扩展,请转到扩展- >键入代码片段创建器。

要创建代码片段,您需要做的就是

*   选择您想要保存的代码
*   键入 Ctrl + Shift + P,然后键入代码段创建者:创建代码段
*   为代码段键入前缀(触发代码段建议的单词)和描述

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/92a6464e9e1b1eb082a80e7956697c33.png)

现在,您可以创建自定义代码片段,只需选择您想要保存的代码并插入描述!

# 访问代码片段

要在键入前缀时访问代码片段,请进入设置->键入`editor.tabcompletion` - >选择`on`以启用制表符补全。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f425cb509f5895fc9abfd1be454f76a0.png)

现在,当您键入代码片段的前缀时,您应该能够看到代码片段的建议。选择您想要的代码片段,整个代码将内联在您的脚本中。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/709ab41a097b91ba592d4829b0d73b11.png)

# 编辑代码片段

如果您在代码片段中犯了错误,您可以编辑代码片段,方法是选择“文件”->“首选项”下的“用户片段”(macOS 上的“代码”>“首选项”),然后选择语言。

a(语言)。json 将显示该语言的所有代码片段。编辑代码片段,然后保存文件。你应该看到变化了!

# 结论

恭喜你!您刚刚学习了如何创建自己的代码片段并在 VSCode 上轻松访问它们。每个代码片段节省超过 30 秒将为您节省时间。

> 给我六个小时砍树,我会用前四个小时磨利斧头——亚伯拉罕·林肯

我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以通过 [LinkedIn](https://www.linkedin.com/in/khuyen-tran-1401/) 和 [Twitter](https://twitter.com/KhuyenTran16) 与我联系。

如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:

[](/how-to-organize-your-data-science-articles-with-github-b5b9427dad37) [## 如何用 Github 组织你的数据科学文章

### 被新信息淹没?现在,您可以轻松地跟踪文章并为其创建自定义注释

towardsdatascience.com](/how-to-organize-your-data-science-articles-with-github-b5b9427dad37) [](/how-to-share-your-python-objects-across-different-environments-in-one-line-of-code-f30a25e5f50e) [## 如何在一行代码中跨不同环境共享 Python 对象

### 为建立与他人分享你的发现的环境而感到沮丧?以下是如何让它变得更简单

towardsdatascience.com](/how-to-share-your-python-objects-across-different-environments-in-one-line-of-code-f30a25e5f50e) [](/how-to-create-reusable-command-line-f9a2bb356bc9) [## 如何创建可重用的命令行

### 你能把你的多个有用的命令行打包成一个文件以便快速执行吗?

towardsdatascience.com](/how-to-create-reusable-command-line-f9a2bb356bc9) [](/how-to-share-your-python-objects-across-different-environments-in-one-line-of-code-f30a25e5f50e) [## 如何在一行代码中跨不同环境共享 Python 对象

### 为建立与他人分享你的发现的环境而感到沮丧?以下是如何让它变得更简单

towardsdatascience.com](/how-to-share-your-python-objects-across-different-environments-in-one-line-of-code-f30a25e5f50e) [](/how-to-learn-data-science-when-life-does-not-give-you-a-break-a26a6ea328fd) [## 当生活不给你喘息的机会,如何学习数据科学

### 我努力为数据科学贡献时间。但是发现新的策略使我能够提高我的学习速度和…

towardsdatascience.com](/how-to-learn-data-science-when-life-does-not-give-you-a-break-a26a6ea328fd)

# 如何打破 GPU 内存界限,即使批量很大

> 原文:<https://towardsdatascience.com/how-to-break-gpu-memory-boundaries-even-with-large-batch-sizes-7a9c27a400ce?source=collection_archive---------4----------------------->

## 克服训练神经网络中的批量大小和可用 GPU 内存的问题

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/233739c4a937fb3c857c12e455b08d9d.png)

安妮·斯普拉特在 [Unsplash](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

在本文中,我们将讨论在使用大批量训练神经网络时可能会遇到的批量问题,并且受到 GPU 内存的限制。

# 问题:批处理大小受到可用 GPU 内存的限制

W 当建立深度学习模型时,我们必须选择批量大小——以及其他超参数。批量大小在深度学习模型的训练中起着主要作用。它对模型的结果准确性以及训练过程的性能有影响。

目前,批处理大小的可能值范围受到可用 GPU 内存的限制。随着神经网络变得越来越大,单个 GPU 上可以运行的最大批处理大小变得越来越小。如今,我们发现自己运行的模型比以往任何时候都大,批量大小的可能值变得更小,可能远离最佳值。

*梯度累积*是一种以琐碎的方式运行不适合 GPU 内存的批处理大小的方法。

# 什么是批量?

批量大小是在更新模型的可训练模型变量(权重和偏差)之前,用于训练模型的样本(例如图像)数量。也就是说,在每个单独的训练步骤中,一批样本通过模型传播,然后反向传播以计算每个样本的梯度。然后,所有样本的梯度将被平均或相加,并且该值将被用作计算可训练模型变量的更新的公式(取决于所选择的优化器)的输入。只有在更新参数后,下一批样品才会经历相同的过程。

# 确定最佳批量

批量大小对训练过程的收敛性以及训练模型的最终准确性具有关键影响。通常,每个神经网络和数据集的批量大小都有一个最佳值或最佳值范围。不同的神经网络和不同的数据集可能具有不同的最佳批量大小。

当使用不同的批量时,可能会产生严重的后果,在选择批量时应该考虑到这一点。让我们来看看使用小批量或大批量的两个主要潜在后果:

*   **泛化:**批量过大可能导致泛化能力差(甚至陷入局部最小值)。泛化意味着神经网络将在训练集之外的样本上表现得相当好。因此,糟糕的泛化能力——这相当于过度拟合——意味着神经网络在训练集之外的样本上表现不佳。
*   **收敛速度:**小批量可能导致学习算法收敛缓慢。使用一批样本计算的每一步中应用的变量更新将决定下一批样本的起点。每一步都从训练集中随机抽取训练样本,因此得到的梯度是基于部分数据的噪声估计。我们在单个批次中使用的样本越少,梯度估计就越嘈杂,越不准确。也就是说,批量越小,单个样本对应用的变量更新的影响就越大。换句话说,较小的批量可能会使学习过程更加嘈杂和波动,本质上延长了算法收敛的时间。

考虑到所有这些,我们必须选择一个既不太小也不太大,但介于两者之间的批量。这里的主要思想是,我们应该尝试不同的批量大小,直到我们找到一个最适合我们正在使用的特定神经网络和数据集的批量大小。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ed4e872a21884e2a72be6b560521feb6.png)

不同的批量有不同的结果。太小的批量可能会导致收敛缓慢。

# 批量大小对所需 GPU 内存的影响

虽然传统计算机可以访问大量的 RAM,但 GPU 的 RAM 要少得多,尽管 GPU 内存的数量正在增长,并且在未来将保持增长,但有时这还不够。训练批次大小对训练神经网络所需的 GPU 内存有着巨大的影响。为了进一步理解这一点,让我们首先检查一下在训练期间 GPU 内存中存储了什么:

1.  参数-网络的权重和偏差。
2.  优化器的变量—每个算法的中间变量(例如动量)。
3.  中间计算-前向传递的值临时存储在 GPU 内存中,然后在后向传递中使用。(例如,每一层的激活输出用于反向传递以计算梯度)
4.  工作区——内核实现的局部变量的临时内存。

*注意:虽然(1)和(4)总是需要的,但(2)和(3)仅在训练模式下需要。*

因此,批量越大,正向通过神经网络传播的样本就越多。这导致需要存储在 GPU 存储器中的更大的中间计算(例如,层激活输出)。从技术上讲,激活的大小线性依赖于批量大小。

现在很明显,增加批量大小将直接导致所需 GPU 内存的增加。在许多情况下,没有足够的 GPU 内存会阻止我们增加批量大小。现在让我们看看如何打破 GPU 内存的限制,同时仍然使用更大的批处理大小。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4a9c6bc28dd8309c8c3249bbf893a988.png)

较大的批量需要更多的 GPU 内存

# 使用更大的批量

克服 GPU 内存限制并运行大批量的一种方法是将一批样本分成更小的小批量,其中每个小批量需要一定量的 GPU 内存才能满足需求。这些小批量可以独立运行,在计算模型变量更新之前,应该对它们的梯度进行平均或求和。实现这一点有两种主要方式:

**数据并行** —使用多个 GPU 并行训练所有小批量,每个小批量在单个 GPU 上进行。来自所有小批量的梯度被累积,并且结果被用于在每一步结束时更新模型变量。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f4c0e436a19770e938b07349c25277f5.png)

数据并行性

**梯度累积** —连续运行小批量,同时累积梯度。累积的结果用于在最后一个小批量结束时更新模型变量。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3e6e71b9ffcffe39d5786e923366f08e.png)

梯度累积

# 数据并行性和梯度累积之间的相似性

数据并行度梯度累积有许多共同的特征和限制:

*   它们都不支持运行需要比可用的更多 GPU 内存的模型(即使只有一个样本)。
*   批处理规范化是在每个小批处理上单独完成的,而不是在全局批处理上,这导致它们不完全等同于使用全局批处理大小运行相同的模型。(*注意:尽管全局批处理的批处理规范化可以在 DP 中实现,但通常不是这样,它是单独完成的。*)
*   它们都允许我们增加全局批处理大小,同时仍然受到 GPU 内存的限制。

***虽然这两个选项非常相似,但梯度累积可以使用单个 GPU 按顺序完成,这对于无法访问多个 GPU 的用户或希望最小化资源使用的用户来说更具吸引力。***

此外,两者可以一起使用。这样,我们将使用几个 GPU,运行几个步骤并在每个 GPU 上累积梯度,并在步骤结束时减少所有 GPU 的累积结果。

我们以这种方式进行了一些实验,并将其称为弹性。 [Run:AI 产品](http://www.run.ai)利用这一特性来提高 GPU 集群的利用率,提高数据科学团队的工作效率。我们将在以后的文章中分享这些概念的更多细节。

尽管梯度累积和数据并行之间有相似之处,但它们的实现是完全不同的。我们将在接下来的文章中关注梯度累积。

# 结论

随着深度学习模型变得越来越大,单个 GPU 上可以运行的最大批量变得越来越小。

虽然数据科学家的目标是为特定的神经网络和数据集找到最佳的批量大小,但找到正确的批量大小,然后受到 GPU 内存的限制是一个常见的现象,也是我们试图并成功克服的问题。

# 后续步骤

在[的另一篇文章](/what-is-gradient-accumulation-in-deep-learning-ec034122cfa?source=friends_link&sk=28226e1d0ffa7e450d7dffa8d5b9cff6)中,我们将讨论梯度累积的技术和算法细节,并进一步演示如何用它来解决批量限制的问题。

在 [GitHub](https://github.com/run-ai/runai/tree/master/runai/ga) 上有一个开源的渐变累积工具,以及使用示例和更多资源。

# 如何打入数据科学与技术

> 原文:<https://towardsdatascience.com/how-to-break-into-data-science-and-tech-24a34a5e6aff?source=collection_archive---------46----------------------->

## 从一个自学成才的数据科学家变成人工智能顾问的角度

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/36a1bf0e4aed453f56a40a014c11cad1.png)

在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上由 [Nastuh Abootalebi](https://unsplash.com/@sunday_digital?utm_source=medium&utm_medium=referral) 拍摄的照片

数据科学是近代史上最引人入胜的突破故事之一。早在 2012 年,随着《哈佛商业评论》的一篇标志性文章[1]——,这一职业首次受到关注

> **T5 数据科学家:21 世纪最性感的工作 **

作为天生谦逊的人,每个人和他们的表亲突然都成了数据科学家——包括我自己,尽管晚了几年。

对数据科学的大肆宣传是真实的,但这并没有减损这样一个事实,即成为一名数据科学家伴随着一个绝佳的机会。

据我所知,没有其他职业能让那些愿意咬紧牙关努力工作的人有机会彻底改变他们的职业生活。

这是一个报酬丰厚、启发智力、受人尊敬的职业,有大量的空缺职位,而且还在不断增加。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b53a85e9efd39c197b48a92ed43e9872.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/aca52149a5476290edfa1fc5fd222ace.png)

2015 年至 2020 年数据科学职位的空缺数量(左)和平均基本工资美元(右)。数据来源于[玻璃门](https://www.glassdoor.com/List/Best-Jobs-in-America-LST_KQ0,20.htm)。

这篇文章是写给那些有抱负的数据科学家的。那些致力于掌握一门手艺的人,正在走许多自学成才的数据科学家自己走过的路。

我们将涵盖三个主要关注领域,我认为这三个领域对任何数据科学家都至关重要。

> ***>编程*** *— CompSci、Python、SQL*
> 
> ***>统计*** *—了解我们的数据以及如何传达结果*
> 
> ***>数据科学/机器学习*** *—学科本身*

我们将数据科学家称为一个总括术语,涵盖数据科学家、机器学习工程师、人工智能工程师和许多其他“数据专家”角色。

# 编程;编排

你们中的许多人可能已经开始了这段旅程。如果你正在做的事情有效,那就继续做下去。

Python 无疑是数据科学中的首选语言。但是除此之外,对于绝大多数数据科学角色来说,很好地掌握 SQL 是必不可少的。

学习 Python 和 SQL 的基础知识——以及计算机科学的基础知识——你就可以开始了。

## 哈佛的 CS50

简单的最好的编程和计算机科学入门。 [**CS50:计算机科学导论**](https://online-learning.harvard.edu/course/cs50-introduction-computer-science) 是所有哈佛计算机科学本科生开始学习的模块。

最棒的部分是什么?这一切都可以在网上免费获得**。**

**整个课程通过 edX 提供,可以免费旁听,也可以付费 90 美元获得认证。**

**如果你不确定要不要上这门课,试试看第一堂课——太不可思议了。**

## **代码集**

**我刚开始的时候, [**Codecademy**](https://www.codecademy.com/) 是我的救星——同时提供 Python 和 SQL 课程。甚至还有一个 [**数据科学**](https://www.codecademy.com/learn/paths/data-science) 学习路径,涵盖了所有的要点。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/32fb0147632e862eb0d908fe4ae4c579.png)**

**显示 Codecademy 上“技能路径”的屏幕截图。**

**Codecademy 是学习 Python/SQL 的好地方。有一个免费版本,但大多数材料都需要付费版本——Codecademy Pro。**

## **Sentdex**

**另一个很棒的资源是哈里森·金斯利的(更广为人知的名字是**sendex**)[YouTube 频道](https://www.youtube.com/sentdex)。**

**他的旧的*“Python 简介”*系列以及 Codecademy 是我开始工作所需要的全部。在他的频道上有一个更新的版本——[**学习用 Python 3**](https://www.youtube.com/watch?v=eXBD2bB9-RA&list=PLQVvvaa0QuDeAams7fkdcwOGBpGdHpXln) 编程。**

**如果有一个地方是你学习 Python 的地方,那就是这里!**

## **项目**

**在这第一步中最重要的是好奇心。贪得无厌的好奇心和创造价值的动力。**

**为了让火继续燃烧,只要跟随你的好奇心,在那个领域做一些个人项目——即使它与最终目标有一点偏离。一些简单的例子:**

> *****>*** *时间/生产力跟踪器***
> 
> *****>*** *游戏开发(* [*这个好看*](https://www.youtube.com/watch?v=XGf2GcyHPhc) *)***
> 
> *****>****Python for finance(*[*from send ex*](https://www.youtube.com/watch?v=2BrpKpWwT2A&list=PLQVvvaa0QuDcOdF96TBtRtuQksErCEBYZ)*)***
> 
> *****>*** *树莓派发展(*[*send ex 再*](https://www.youtube.com/watch?v=RpseX2ylEuw&t=29s) *)***

**如果你不想从头开始开发一个项目,YouTube 是一个寻找视频系列的绝佳资源,我们可以用它作为“指导”项目。**

## **其他的**

**[GitHub](https://github.com/) 是一个在线软件开发平台,最终是你的作品组合。如果投资订阅的话, [Codecademy 涵盖了 GitHub](https://www.codecademy.com/articles/f1-u3-git-setup)——或者在 YouTube 上使用[这个教程。](https://www.youtube.com/watch?v=sz6zfrQpCQg)**

**无论何时你的代码有问题——这几乎总是会发生——在[堆栈溢出](https://stackoverflow.com/)上找到解决方案。如果你找不到问题的答案,你可以问!**

## **摘要**

> **CS50 是您唯一需要的 CompSci 底漆。Python 和 SQL 很重要(但更 Python)。学习这两者的最佳资源是—**
> 
> *****>Codecademy****—交互 UI,教 Python 和 SQL***
> 
> *****>send ex****—YouTube 上的免费 Python 和数据科学教程***
> 
> *****>项目****——原创想法,或跟随项目上线***
> 
> ***把你的项目留在 GitHub 上,Stack Overflow 就是你的新家。***

# **统计数字**

**统计学是驱动数据科学各个方面的引擎。掌握统计学非常重要,但你不需要成为统计学家。**

**这有两个关键部分:**

1.  **学习如何进行分析和解释结果**
2.  **学习如何通过可视化交流结果**

**当然,统计学远不止于此,但这两点是数据科学家需要很好理解的基础。**

## **使用 R-Coursera 进行统计**

**由杜克大学提供,这是迄今为止我所见过的最全面的统计学课程。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1bdcb1443afdeaabd30b4791b5ce3efe.png)**

**它不仅涵盖了你需要了解的所有统计学知识,而且在完成后,你将获得该课程的 Coursera 认证——它可以添加到 LinkedIn 或简历中,以证明你理解该课程涵盖的概念。**

**专业化时间长,从开始到结束建议学习时间 7 个月。对大多数人来说,即使有一份全职工作,这也很容易在短得多的时间内完成,但仍然需要很大的投入。**

> **但是这门课是“R 统计学”,而不是“Python 统计学”**

**r 是数据科学家中第二受欢迎的语言。然而,由于 Python 在该领域的主导地位,我不建议有抱负的数据科学家专注于这种语言。**

**尽管标题如此,本课程对 r 的关注却很少。本课程的大部分内容仅仅集中在统计学上,偶尔会演示 r 的统计方法的应用。**

**这是一门统计学课程,带有 R 的味道。我们的重点是统计学,但 R 仍然是相关的。对这种语言的熟悉为我们的数据科学工具包增加了另一个工具。**

**该课程的一个出色的补充指南是[面向数据科学家的实用统计学](https://amzn.to/3fokXjM),它也关注统计学和 R (+ Python)。这当然不是本课程的必修课,但却是必不可少的。**

## **可视化库和软件**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/078bde0151a44d44095625f81e2f9828.png)**

**通常,我们是在学习其他东西的过程中接触到数据可视化的——在 R 的统计学课程中,或者在学习 Python 的时候。但是有一些库和软件包需要注意:**

*   **[matplotlib](https://matplotlib.org/)——Python 中数据可视化的鼻祖**
*   **[seaborn](https://seaborn.pydata.org/)——让 matplotlib 看起来很漂亮**
*   **[plotly](https://plotly.com/) —用 Python 实现更高级的可视化**
*   **[Tableau](https://www.tableau.com/) 和 [Power BI](https://powerbi.microsoft.com/en-us/) —商业智能数据可视化的领导者,两者都是数据可视化的“无代码”替代方案**

**如前所述, [Codecademy](https://www.codecademy.com/learn/data-visualization-python) 和[sendex](https://www.youtube.com/playlist?list=PLQVvvaa0QuDfefDfXb9Yf0la1fPDKluPF)也是学习 Python 数据可视化基础知识的绝佳资源。**

# **数据科学/机器学习**

**这一部分是最后一部分,因为扎实的编程和统计基础非常重要,应该是进入更具体的数据科学学习之前的重点。**

**不同的方法适用于不同的人,但这些绝对是我用来学习数据科学的最佳资源。**

## **开始**

**(1) [**安德烈·布尔科夫(Andriy Burkov)**](https://amzn.to/2APzANQ)撰写的 100 页的机器学习书籍真正击败了所有其他书籍,无论是对数据科学初学者还是更有经验的专业人士。如果你只用过一本书,那就选这本吧。**

**(2)[**Coursera**](https://www.coursera.org/learn/machine-learning)上的机器学习是大规模开放在线课程(MOOCs)中最著名的,这是有充分理由的——它成功地将极其复杂的 ML 算法简化为直观易学的概念。**

**[](/a-review-of-stanfords-machine-learning-certification-9614ebee2b06) [## 斯坦福大学机器学习认证述评

### 在快速变化的数据科学环境中,这仍然值得吗?

towardsdatascience.com](/a-review-of-stanfords-machine-learning-certification-9614ebee2b06) 

## 那就研究这些

(3) [**Kaggle** 是一个数据科学竞赛](https://www.kaggle.com/)的线上平台。现在,我们不会用它来与尖端 ML 研究人员的团队竞争,但它确实提供了一个友好的环境来练习我们在已经确定的数据科学问题上的技能。此外,我们可以向专业人士学习。

(4)

[](/a-review-of-ibms-advanced-machine-learning-and-signal-processing-certification-371bd937bb76) [## IBM 高级机器学习和信号处理认证综述

### Coursera 上的高级机器学习和信号处理课程的全面可视化指南

towardsdatascience.com](/a-review-of-ibms-advanced-machine-learning-and-signal-processing-certification-371bd937bb76) 

(5)[**Coursera**](https://www.coursera.org/specializations/deep-learning)上的深度学习专业化,同样来自吴恩达——这涵盖了深度学习的基础,是对 Python 中 TensorFlow 框架的完美介绍。

## 最后

学以致用。不要只是消费知识,而是应用和分享知识。

想出令人兴奋的项目创意——即使它们毫无用处,也要去尝试!享受这个过程。

做你的项目,创造一些很酷的东西,并与世界分享。

写下项目和你学到的东西。谈论你的工作和教导他人将极大地提高你的能力。

# 一致性是关键

学习一门新学科是一个漫长而艰苦的过程。与其说是短跑,不如说是马拉松——但对于那些愿意投入工作的人来说,这是完全可能的。

在整个过程中保持一致至关重要。很像关于龟兔赛跑的伊索寓言——如果像兔子一样,我们跑在前面却变得分心或懒惰——我们将会失败。相反,我们必须保持一致和专注。

如有任何问题或建议,请联系!

感谢阅读!

# 参考

[1] T. Davenport,D. Patil,[数据科学家:21 世纪最性感的工作](https://hbr.org/2012/10/data-scientist-the-sexiest-job-of-the-21st-century) (2012),哈佛商业评论**

# 如何轻松进入数据科学领域

> 原文:<https://towardsdatascience.com/how-to-break-into-data-science-the-easy-way-dd498995057f?source=collection_archive---------35----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a86231561a5c28f4ac68b0bb2aaa6bf8.png)

划掉那个;没有简单的方法。

在过去的几年里,数据科学已经和机器学习一起成为热门话题。机器学习的兴起让数据为王,也因此产生了对数据科学家的巨大需求。通过正规教育成为数据科学家是时代的产物,在现代进入这个行业需要一点努力。

# 传统路线

我是一名数据科学家,但是我没有数据科学的学位。由于与大量数据打交道,我成为了一名数据科学家。我拥有史前时代的博士学位,那时人们必须[阅读学术论文](https://www.linkedin.com/pulse/ode-red-ink-robert-mckeon-aloe)才能实现机器学习。[传统上](https://www.linkedin.com/pulse/farewell-computer-vision-robert-mckeon-aloe),如果你想成为数据科学家,你就成为了科学家。然后你处理如此多的数据,以至于你成为了一名数据科学家,能够[分析所有的数据](https://www.linkedin.com/pulse/abandon-ship-robert-mckeon-aloe)。你在大学开始主修 STEM,然后你会去读研究生课程。该计划并不专注于数据科学,但由于你的研究,你处理了大量的数据。

在研究生院积累了多年的数据,然后在你的相关领域做了一些工作,你将会成为一名敏锐的数据科学家。你将学会分析数据的技巧,并对结果充满信心。这种经验来自于撰写学术论文,然后将这些技能应用到工业中。

# 现代

现在行业火热!似乎每个人都想加入,纳米学位的流行给许多新人留下了成为数据科学家的捷径的印象。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/075941f0ec2db26f27c745bce61532eb.png)

成为一名数据科学家没有更容易、更轻松的方式。试图简化过程的一个问题是,你不知道如何看待数据。即使概念可以在短时间内教授,你也需要浏览大量数据,[设计数据收集](https://www.linkedin.com/pulse/design-experiment-data-collection-robert-mckeon-aloe),收集数据,清理数据,数据训练,分析数据,做[故障分析](https://www.linkedin.com/pulse/ml-examining-test-set-robert-mckeon-aloe),并重复。研究生院是这个过程的一个很好的载体,因为你必须做出比现在更好的东西。

# 没有捷径

如今,玩具数据集很容易获得,甚至[机器学习算法](https://www.linkedin.com/pulse/traditional-cv-pipeline-vs-cnn-robert-mckeon-aloe)也可以从货架上获得。当谈到能够将训练轮取下并将其应用于新数据集时,这给了人们一种轻松感。

问题就在这里:有了纳米学位,你可能会觉得自己完成了一些伟大的事情,学到了很多东西,但你只是被介绍到这个领域。对于那些由于读研或日常工作已经沉浸在数据中的人来说,数据科学的纳米学位是非常好的。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/755698f0f6755853bbdd3d3639899364.png)

许多人还获得了数据科学的硕士学位,虽然成为一名多面手很棒,但我仍然更喜欢至少在一个领域有深度知识的人。如果你想进入数据科学领域,考虑在你感兴趣并且使用大量数据的领域获得学位。你可以顺便或作为旅程的一部分学习许多数据科学的东西。

最好的[数据科学家](https://www.linkedin.com/pulse/day-life-data-scientist-robert-mckeon-aloe)是那些一生热爱数据的人。我知道这听起来像是有些人天生就有这种倾向;这是我的经历,尽管不是每个人的。我已经找到了利用数据改善生活的方法,比如做预算、[买车](https://medium.com/overthinking-life/buying-a-car-an-analysis-7bf7caf58e04)、[决定何时离开公司](https://www.linkedin.com/pulse/abandon-ship-robert-mckeon-aloe)、[制作浓缩咖啡](https://www.linkedin.com/pulse/progressive-refinement-purification-story-espresso-shot-mckeon-aloe),以及评估我所写文章的影响。这对我来说很自然,感觉不像工作。

# 需要考虑的事情

在过去的两三年里,大多数数据科学家都拥有硕士或博士学位。对他们(对我们)来说,我们可以看到拥有肤浅专业知识的人和拥有丰富领域知识的人之间的区别。

即使是刚毕业的博士,几年内也不会被称为[学长](https://www.linkedin.com/pulse/symptoms-promotion-robert-mckeon-aloe)。所以如果你硕士或者学士出来,做个纳米,一两年内有了[高级数据科学家](https://www.linkedin.com/pulse/wisdom-learning-from-others-robert-mckeon-aloe)的头衔,我是持怀疑态度的。尽管你可能想认为自己和这个领域的其他资深成员有着同样的深度,但很可能你没有。没关系;对自己的技术水平现实一点就好。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/211648d3177545fd5dd85f5ea5c506b7.png)

我在 2018 年招聘数据科学家失败的原因是:[我找不到一个好的](https://www.linkedin.com/pulse/lessons-hiring-robert-mckeon-aloe)。有人可能会说我忽略了优秀的候选人,但招聘通常是委员会一致同意的。我的面试小组中的每个人都有硕士学位,一半有博士学位。他们希望与他们信任的技能可靠的人一起工作,所以他们宁可说不。在 100 名申请人、40 次电话面试和 6 次面对面面试中,我最终一无所获。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e880954ae441dd5af77a4ca85fa6de9f.png)

在研究生院,我的导师告诉我,他们必须小心毕业的博士,因为一个新的博士可能会在几年内毕业。所以周期短,不合格的候选人会冲淡场。数据科学也是如此:随着资历较浅的人进入这个领域,他们会很乐意让更多能力相近的人进入。

# 最后

进入数据科学的部分困难在于,在人们信任你做数据科学家的工作之前,你需要磨砺多年。没有免费的午餐,也没有捷径,所以努力解决一些有趣的问题,吸收所有的数据,总有一天,你会形成一个茧,并弹出一只数据科学蝴蝶。

如果你愿意,可以在 [Twitter](https://mobile.twitter.com/espressofun) 和 [YouTube](https://m.youtube.com/channel/UClgcmAtBMTmVVGANjtntXTw) 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 [LinkedIn](https://www.linkedin.com/in/robert-mckeon-aloe-01581595) 上找到我。

[我的进一步阅读](https://www.linkedin.com/pulse/my-writing-sorted-topic-robert-mckeon-aloe/):

[数据科学:基础知识](https://www.linkedin.com/pulse/data-science-essentials-robert-mckeon-aloe/)

[弃船:一家初创公司如何倒闭](https://medium.com/overthinking-life/abandon-ship-how-a-startup-went-under-c5ca8e5bb970)

[论文遗憾](https://medium.com/overthinking-life/dissertation-regret-7109673b7437)

[团队的一部分](https://www.linkedin.com/pulse/part-team-robert-mckeon-aloe/)

如何面试一家公司

[关于离职的想法](https://www.linkedin.com/pulse/thoughts-leaving-robert-mckeon-aloe/)

[数据科学家的一天](/a-day-in-the-life-of-a-data-scientist-eb63cdd71edb)

[实验设计:数据收集](https://www.linkedin.com/pulse/design-experiment-data-collection-robert-mckeon-aloe/)

# 如何将您的现代数据管道投入生产

> 原文:<https://towardsdatascience.com/how-to-bring-your-modern-data-pipeline-to-production-2f14e42ac200?source=collection_archive---------13----------------------->

## 使用 Azure DevOps、Databricks Spark、Cosmos DB Gremlin API 和 Azure Data Factory

# A.介绍

创建数据管道是一回事;将其投入生产是另一个问题。对于使用多种服务进行高级分析的现代数据管道来说,尤其如此。例如将非结构化数据转换为结构化数据、训练 ML 模型和嵌入 OCR。多种服务的集成可能很复杂,并且必须控制生产部署。在这篇博客中,提供了一个示例项目如下:

*   1.为连续部署设置 Azure DevOps 项目
*   2.使用基础设施作为代码部署数据管道的 Azure 资源
*   3.运行和监控数据管道

项目的[代码](https://github.com/rebremer/blog-datapipeline-cicd)可以在这里找到,现代数据管道的步骤描述如下。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5646da5d9b6d5d50b4ddf2ad4762fb4e.png)

1.高级数据流,作者图像

这个项目的结构将在下一章讨论。随后,提供了如何部署和运行项目的教程。如果你想学习如何将数据科学项目投入生产,请参见我之前的[博客](/how-to-bring-your-data-science-project-in-production-b36ae4c02b46)。

# B.体系结构

在这个项目中,流行的 Azure 服务的功能被结合起来,以创建一个现代化的数据管道。数据管道的主要资源如下:

*   **Azure 数据工厂(ADFv2)** : ADFv2 允许你大规模移动数据。ADFv2 自带 90 个连接器,并具有许多企业就绪功能,如托管身份(MI)、自托管集成运行时(IR)以连接本地数据源、[VNET 中的 Azure IR](https://docs.microsoft.com/en-us/azure/data-factory/managed-virtual-network-private-endpoint)以及 git/Azure DevOps 集成。转换可以在 ADFv2 中使用数据流来完成,更复杂的转换可以在 ADFv2 中使用 Azure Databricks 来编排。另请参见[我的视频](https://demoignitemdwstor.blob.core.windows.net/demo30video/transforming_and_enriching_data.mp4)了解 ADFv2 的运行情况。
*   **Azure data bricks**:data bricks 是一个托管的 Spark 环境,使您能够大规模转换数据。Azure Databricks 在 Azure 中作为 PaaS 服务提供,并与 Azure AD 集成。可以从 ADFv2 协调笔记本电脑
*   **Cosmos DB Gremlin API**:Cosmos DB 是一个完全托管的多数据库服务,使您能够在全球范围内构建高度响应的应用程序。作为 Cosmos DB 的一部分,graph 数据库支持 Gremlin。
*   **Azure 存储** : ADLSgen2 可以让你以低成本存储你无限量的数据。它还支持使用 RBAC 和/或 Posix 的细粒度访问控制。

数据管道的内部工作和资源整合如下:

*   **数据流**:使用 ADFv2 将数据从 csv 转换为 ADLSgen2 中的 parquet。随后,ADFv2 触发 Databrick 笔记本,从 ADLSgen2 读取数据,并根据拼花数据创建图表。最后,Databricks 使用 Gremlin API 将数据写入 Cosmos DB
*   **访问** : ADFv2 托管身份(MI)用于访问 ADLSgen2 中的数据。ADFv2 MI 还用于 Azure 数据块来触发笔记本。Azure Databricks 使用一个 secret scope 来检索可以访问 ADLSgen2 以读取 parquet 数据的服务主体和可以访问 Cosmos DB 以写入图形数据的密钥。数据块秘密范围可以由数据块或 Azure 密钥库支持(参见下面详细架构中的步骤 3b2)
*   **防火墙:**adlsgen 2 和 AKV 防火墙中启用了可信的微软服务,这样 ADFv2 MI 就可以访问。此外,Databricks VNET 被列入 ADLSgen2 和 AKV 防火墙的白名单,所有其他流量均被拒绝。只有 VNET 的数据被列入了 Cosmos DB 防火墙的白名单。

另请参见下面的详细架构。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cbb7b1d84095fa4660be8288992fb455.png)

B.高层建筑,详细,作者图片

# C.部署和运行现代数据管道

在这一章中,项目开始运行,现代数据管道使用 b 章中描述的体系结构。

*   C0。先决条件
*   C1。设置 Azure DevOps 项目
*   C2。部署 Azure 资源
*   C3。监控数据管道

## C0。先决条件

本教程需要以下资源:

*   [Azure 账户](https://azure.microsoft.com/en-us/free/)
*   [蔚蓝 DevOps](https://visualstudio.microsoft.com/team-services/)
*   [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest) (推荐,也用于故障排除)

最后,转到 Azure 门户并创建一个资源组,所有 Azure 资源都将部署在该资源组中。这也可以使用以下 Azure CLI 命令来完成:

```
az group create -n <<your resource group>> -l <<your location>>
```

## C1。设置 Azure DevOps 项目

Azure DevOps 是一个工具,可以持续地构建、测试和部署你的代码到任何平台和云。按照本教程[在 Azure DevOps 中创建新项目。创建新项目后,单击存储库文件夹并选择导入以下存储库:](https://docs.microsoft.com/en-us/azure/devops/organizations/projects/create-project?view=azure-devops&tabs=preview-page&viewFallbackFrom=vsts)

```
[https://github.com/rebremer/blog-datapipeline-cicd](https://github.com/rebremer/blog-datapipeline-cicd)
```

另请参见下图:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f995e7f8a9c22d1701fbefb0cb251880.png)

C1.1 将存储库添加到您的 Azure DevOps 项目中,图片由作者提供

从 Azure DevOps 访问资源组中的资源需要服务连接。转到项目设置,服务连接,然后选择 Azure 资源管理器,另见下图。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/17cd7013d03dfd6345109e45c533e52f.png)

C1.2 按作者创建服务连接、图像

选择服务主体身份验证,并将范围限制到您之前创建的资源组,另请参见下图。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/866da9368741e509136aa45e83064b60.png)

C1.3 将范围限制为资源组,按作者分类的图像

默认情况下,服务连接的服务主体(SPN)拥有资源组的参与者权限。但是,对于此管道,SPN 需要对资源组的所有者权限(或贡献者旁边的附加用户访问管理员权限),因为 ADFv2 MI 需要获得对 ADLSgen2 帐户的 RBAC 权限。在 Azure DevOps 中点击你的服务连接上的“管理服务主体”时,可以找到应用 id。使用以下 Azure CLI 脚本向 SPN 分配所有者权限(也可以在门户中完成):

```
# get your subscriptioin id
az account list
# create role
az role assignment create --assignee "<<application id>>" --role "Owner" --scope "/subscriptions/<<your subscription Id>> /resourcegroups/<<resource group name>>"
```

最后,验证 SPN 是否在 Azure 门户中或使用下面的 CLI 命令为您的资源组分配了所有者角色。

```
az role assignment list --resource-group <<resource group name>>
```

## C2。部署 Azure 资源

转到您的 Azure DevOps 项目,选择管道,然后单击“新建管道”。转到向导,选择您之前创建的 Azure Repos Git 和 git repo。在“配置”选项卡中,选择“现有 Azure Pipelines YAML 文件”,然后选择可以在 git repo 中找到的 azure-pipelines.yml,另请参见下文。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9d3857a2c4a12a6e1a90278e98938257.png)

C2.1 .在管道配置向导中,选择现有的 Azure 管道 YAML 文件,按作者排序的图像

随后,需要用您自己的值替换以下变量:

```
variables: 
  # Azure DevOps settings
  AzureServiceConnectionId: '<<your service connection name>>'
  # Change environment variables used in bash scripts with your own
  RG: 'blog-datapipelineprod-rg'  
  SUB: '<<your subscription>>' 
  AKV: 'blogdatapipelineakv123' # unique value 
  STOR: 'blogdatapipelinestor123' # unique value
  COSMOSDBNAME: 'blog-datapipeline-cosmos123' #unique value
  DBRWORKSPACE: 'blog-datapipeline-dbr123' #unique value
```

一旦变量被替换,管道就被创建并立即运行,见下文

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/89859d4d3e193d1415c92c6724a8bad2.png)

C2.2 Azure DevOps 部署现代数据管道,作者图片

当一切都部署好了,你会看到下图:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9aa0f977754e588f8f5f6537bf59e0af.png)

C2.3 成功部署,作者图片

## C3。监控数据管道

azure-pipelines.yml 的最后一步是执行 ADFv2 管道。这样做是为了建立一个端到端的示例,但是,ADFv2 管道通常不是从 Azure DevOps 触发的,而是使用 ADFv2 自己的 schedular 或企业使用的另一个调度程序。Azure 数据工厂管道运行可以在 ADFv2 monitor pipelines 选项卡中进行验证,另请参见下图。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f2dab0ac7aa9cf43568dbb72e9136c1f.png)

c 3.1 . ADF v2 管道成功运行,作者提供图像

Azure Databricks 笔记本向 Cosmos DB Graph API 添加数据。当您在门户中打开 Azure Cosmos DB 帐户时,在防火墙规则中启用从门户的访问,然后转到数据浏览器,这可以被验证,见下文。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6868bdc5d9e3f2c8b02dbfc7bbaa2f2e.png)

c 3.2 . cosmos db gremlin API 中的图形数据,图片由作者提供

# D.结论

创建数据管道是一回事;将其投入生产是另一个问题。对于使用多种服务进行高级分析的现代数据管道来说,尤其如此。在这个博客中,提供了以下内容:

*   Azure DevOps 管道可以控制 Azure Databricks、Azure Data Factory 和 Azure Cosmos DB 的部署和集成
*   Architecute 和 [Github 项目](https://github.com/rebremer/blog-datapipeline-cicd)将 csv 文件转换为 parquet,创建图形数据并将其存储在 Cosmos DB Gremlin 中

该示例项目可用于将您的现代数据管道投入生产,参见下面的架构。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cbb7b1d84095fa4660be8288992fb455.png)

D.高层建筑,详细,作者图片

# 如何使用带有自定义数据集的 detector 2 检测图像和视频中的棒球

> 原文:<https://towardsdatascience.com/how-to-build-a-baseball-detector-using-detectron2-50b44edec6b7?source=collection_archive---------27----------------------->

## 使用自定义数据集的 Train Detectron2 对象检测。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3692696a45b7bd834f69eb8d7797fc47.png)

作者图片

# 介绍

作为一个业余棒球运动员,我总是想分析我的投球和挥杆,以量化我在练习中的技能。实际上有一些应用不同技术的商业工具可以做到这一点,但是,它们中的大多数都非常昂贵,并且需要额外的设备。

我想知道我是否可以从一个简单的手机视频中分析我的运动。为此,我需要从视频中收集信息。首先,我想检测棒球并确定它的位置,然后我可以做进一步的分析,如发射速度和角度。

在这篇文章中,我将展示如何创建一个定制的棒球数据集,训练一个对象检测模型,并使用 detectron 2([https://github.com/facebookresearch/detectron2](https://github.com/facebookresearch/detectron2))将其应用于棒球视频。

棒球检测器是按照三个步骤构建的,这将在本文中详细讨论:
1 .创建 COCO 格式的自定义棒球数据集
2。玩探测器 2,并在 Colab
3 训练模型。加载视频/图像并应用训练好的模型进行检测。

# 以 COCO 格式创建自定义棒球数据集

真实视频剪辑中的棒球图像通常不是清晰和完美的。它可能有点模糊和扭曲,如下所示。因此,不使用 Detectron 2 提供的预训练模型。为了更好地检测,我决定创建一个包含视频中真实棒球图像的数据集。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/043ac70945331367082292c8808cbdd0.png)

来自挥动棒球的视频截图(图片由作者提供)

首先,我在 Youtube 上使用了一些棒球比赛视频,并在第一次尝试中获得了 120 张包含棒球的图像。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1672d1d10eb9d0b8b04be0c777d438d8.png)

从视频剪辑中捕获的训练图像。

然后我用[标签](https://github.com/tzutalin/labelImg)手工给棒球贴标签。Labelimg 是一种方便的标记对象的工具。按照回购中的说明,它可以很容易地安装和使用。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0672f0477d16d7ba79d0153ce8d18f48.png)

使用标签标记棒球

1.  选择“PascalVOC”,这是默认的注释格式。
2.  打开包含图像的文件夹
3.  设置保存注释的文件夹
4.  标记球并保存注释

我花了大约 20 分钟来手动标记 120 张图片,然后将注释保存在您用 xml 设置的文件夹中。

然后我使用 Tony607 的 GitHub repo 中的这个 [voc2coco.py](https://github.com/Tony607/voc2coco/blob/master/voc2coco.py) 脚本将 PascalVOC xml 文件转换成一个 coco 格式的 JSON 文件。

现在,我必须用 COCO 格式的注释定制棒球数据集,为训练做好准备。

# 使用 Colab 中的 Detectron2 训练模型

我修改了 Detectron2 的好看又清晰的[教程 Colab 笔记本](https://colab.research.google.com/drive/16jcaJoc6bCFAQ96jDe2HwtXj7BMD_-m5)并训练了模型。

首先,我将我的 Google Drive 安装到笔记本上,并将我创建的数据集上传到上面。

```
from google.colab import drive
drive.mount('/content/gdrive', force_remount=True)
root_dir = 'gdrive/My Drive/Colab Notebooks/'
base_dir = root_dir + 'baseball_detection'
```

然后,我按照笔记本上的说明安装和设置 detectron2。

```
# install dependencies:
!pip install pyyaml==5.1 pycocotools>=2.0.1
import torch, torchvision
print(torch.__version__, torch.cuda.is_available())
!gcc --version
# opencv is pre-installed on colab# install detectron2: (colab has CUDA 10.1 + torch 1.5)
# See https://detectron2.readthedocs.io/tutorials/install.html for instructions
assert torch.__version__.startswith("1.5")
!pip install detectron2==0.2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu101/torch1.5/index.html# Some basic setup:
# Setup detectron2 logger
import detectron2
from detectron2.utils.logger import setup_logger
setup_logger()
# import some common libraries
import numpy as np
import os, json, cv2, random
from google.colab.patches import cv2_imshow
# import some common detectron2 utilities
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer
from detectron2.data import MetadataCatalog, DatasetCatalog
```

然后我将球数据集注册到 detectron2。输入注释文件路径(COCO json)和包含训练图像的文件夹路径。

```
from detectron2.data.datasets import register_coco_instances
register_coco_instances("ball", {}, path/'image'/'output.json', path/'image')
```

然后打电话

```
ball_metadata = MetadataCatalog.get("ball")
dataset_dicts = DatasetCatalog.get("ball")
```

然后我运行这个单元来查看训练图像

```
for d in random.sample(dataset_dicts, 3):
   img = cv2.imread(d["file_name"])
   visualizer = Visualizer(img[:, :, ::-1], metadata=ball_metadata,    scale=0.5)
   out = visualizer.draw_dataset_dict(d)
   cv2_imshow(out.get_image()[:, :, ::-1])
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/078b1e598f06e879d53b97d3114f2ac1.png)

标签图像。

我现在准备好训练了!

我在棒球数据集上微调了 COCO 预训练的 R50-FPN 面具 R-CNN 模型。我得到了配置和重量使用模型 _ 动物园的方法。记得换 cfg。模型。ROI_HEADS。NUM_CLASSES 设置为 1,因为我现在只有一个类。我花了几分钟在 Colab 上运行 2000 次迭代。

```
from detectron2.engine import DefaultTrainercfg = get_cfg()
cfg.merge_from_file(model_zoo.get_config_file("COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml"))
cfg.DATASETS.TRAIN = ("ball",)
cfg.DATASETS.TEST = ()
cfg.DATALOADER.NUM_WORKERS = 2
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml")   # Let training initialize from model zoo
cfg.SOLVER.IMS_PER_BATCH = 2
cfg.SOLVER.BASE_LR = 0.00025  # pick a good LR
cfg.SOLVER.MAX_ITER = 2000    # 300 iterations seems good enough for this toy dataset; you may need to train longer for a practical dataset
cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 128   # faster, and good enough for this toy dataset (default: 512)
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 1  # only has one class (ball)os.makedirs(cfg.OUTPUT_DIR, exist_ok=True)
trainer = DefaultTrainer(cfg)
trainer.resume_or_load(resume=False)
trainer.train()
```

我可以在 tensorboard 上看到训练表演

```
# Look at training curves in tensorboard:
%load_ext tensorboard
%tensorboard --logdir output
```

现在,我可以在球验证数据集上使用训练好的模型进行推理。首先,让我们使用我刚刚训练的模型创建一个预测器:

```
cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_final.pth")
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5   # set a custom testing threshold for this model
cfg.DATASETS.TEST = ("ball", )
predictor = DefaultPredictor(cfg)
```

选择一些测试图像来测试模型

```
im = cv2.imread('gdrive/My Drive/Colab Notebooks/baseball_detection/test/1.png')
outputs = predictor(im)
v = Visualizer(im[:, :, ::-1],
  metadata=ball_metadata,
  scale=1)
out = v.draw_instance_predictions(outputs["instances"].to("cpu"))
cv2_imshow(out.get_image()[:, :, ::-1])
```

且看结果!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/db93da3da060c69b724d8d46f7b0c411.png)

被训练模型检测到的棒球。

# 加载视频/图像,应用训练好的模型进行检测

现在我有了训练好的模型,我可以加载我想要进行检测的图像/视频。

我编写了一个脚本,使用 OpenCV 逐帧读取视频,并使用每一帧的模型检测棒球。所以我现在有了检测到的棒球的信息,例如每一帧的位置,以便进一步分析。我还可以输出棒球检测视频!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a675258d01d2b016bdcb918dc07cfeda.png)

# 未来工作:

1.  应用对象跟踪来跟踪球

[](/detect-and-track-baseball-using-detectron2-and-sort-6dd92a46e6f2) [## 检测和跟踪棒球使用探测器 2 和排序

### 当视频中有多个棒球时,我如何跟踪棒球。

towardsdatascience.com](/detect-and-track-baseball-using-detectron2-and-sort-6dd92a46e6f2) 

1.  计算球的速度和发射角度
2.  一些快速移动的球不能被识别,这可能有助于扩展训练数据集并包括一些快速移动的、扭曲的和模糊的球
3.  构建 web 应用程序

感谢阅读。欢迎反馈和建议!

# 如何构建基线模型

> 原文:<https://towardsdatascience.com/how-to-build-a-baseline-model-be6ce42389fc?source=collection_archive---------16----------------------->

## 探索性数据分析框架

## 构建基线模型以了解数据的实用方法

免责声明:您正在阅读本系列的第 2 部分。在 [*第 1 部分*](https://medium.com/@tatianasennikova/code-and-techniques-for-exploratory-data-analysis-a44c50953502) *中,我提出了一个探索性的数据分析框架,这是开始这里描述的建模部分之前的必要步骤。*

# 介绍

直接投入研究并实现尖端的深度学习解决方案是非常诱人的。然而,在这一点上,我通常告诉自己保持务实,首先建立一个体面的基线。许多数据科学家低估了基线的重要性。我喜欢基线模型,因为它们能够以 10%的努力交付 90%的价值。两天内 80%准确的模型比四周内 81.5%准确的模型要好,这是与客户合作时最重要的。一个像样的基线模型的美妙之处在于,它很难被击败,而前沿模型只能实现对它的微小改进。好的基线模型有几个要求:

1.  基线模型应该简单。简单模型不太可能过度拟合。如果你发现你的基线已经过度拟合了,那么去做更复杂的建模是没有意义的,因为复杂性会扼杀性能。
2.  基线模型应该是可解释的。可解释性将帮助你更好地理解你的数据,并为你指明特征工程的方向。

这两个原因让我们选择了我最喜欢的基线模型,它们是来自决策树家族的模型。关于树的另一个惊人的事实是,基于树的模型是非参数化的,不需要数据呈正态分布。

在决定了一个模型之后,让我们进入数据准备阶段。在[第 1 部分](https://medium.com/@tatianasennikova/code-and-techniques-for-exploratory-data-analysis-a44c50953502)中,我们对[道路安全数据集](https://data.gov.uk/dataset/cb7ae6f0-4be6-4935-9277-47e5ce24a11f/road-safety-data)进行了探索性数据分析。两部分的完整代码可在 [GitHub](https://github.com/tsennikova/road-accidents-analysis/blob/master/road_accidents_analysis.ipynb) 上找到。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/30d906c906db8ab35ef32c88076b5fc7.png)

马克·卡马洛夫**/**unsplash.com 摄影

# 问题陈述

最终目标是开发一个模型来预测警察参与事故的概率。我们还应该评估我们所掌握的数据的质量,并展示哪些因素对模型的决策有最大的影响。

# 数据准备

在第 1 部分中,我们创建了一些新变量:

勘探阶段产生的变量

为了简洁起见,我将这些变量从 data dataframe(我们在探索阶段使用的那个)复制到我们的原始 dataframe acc_df。在生产系统中,应该实现数据处理管道的相关步骤。

加入在勘探阶段设计的变量

我们最初在*上了 3 节课,警察出席了事故现场。*类别 2 和类别 3 需要合并到负面类别中,因为我们只对估计警察参与事故的概率感兴趣。

事故数据集中的响应变量包含两个不平衡的类。因此,我们以这样的方式分割数据集,即我们在训练和测试数据集中保留相同比例的否定类。

将数据拆分为训练数据集和测试数据集

现在让我们开始创建数据转换器,稍后我们将把它们加入数据处理管道。为了保持模型简单并避免过度拟合,我们需要删除带有相关变量的列。

移除相关变量

然后我们需要将*的 LSOA _ 事故 _ 地点*的类别名称编码为整数。此变量的某些值很少见,只包含在测试数据集中。与此同时,未来可能会突然出现新的未知类别。标准的 sklearn 实现没有解决这个问题,因此我们需要通过引入一个“未知”类别来实现另一个解决方案,所有以前不可见的值都将属于这个类别。为此,我使用了 Vinoj John Hosan 的实现。

编码分类变量

下一步是填充缺失的值。我实施了两个策略。缺省值表示带有特殊类别“-1”的缺失值。第二种策略是训练模型,根据数据集中存在的值来填充缺失值。在调整超参数时,我们可以通过随机搜索来测试这两种方法。

填充 NaN 值

我们应该注意的最后一件事是重新调整连续值。严格地说,对于树模型来说,这是不必要的,但是如果我们将来想要将这个管道与其他分类模型一起使用,那么拥有它是很好的。

重新缩放连续变量

现在,我们可以将所有预处理步骤加入到一个管道中,并运行它来准备训练和测试数据集。

准备训练和测试数据集

# 训练模型

RandomForest 分类器是所有决策树模型中最稳定的,不太可能过度拟合。因此,这是一个很好的选择。

模特培训

由于我们正在处理一个不平衡的数据集,我平衡了类权重,并使用加权 F1 分数作为超参数调整和模型评估的评分标准。

具有最佳超参数选择的验证集的平均 F1 分数为 0.785。现在,让我们检查训练和测试数据集的 F1 分数,以确保模型不会过度拟合。

使用最佳估计器评估训练和测试数据集

哎呀,我们的加权 F1 在训练数据集上是 0.96,在测试数据集上是 0.79,这意味着我们过度调整了超参数,模型严重过度拟合。我们需要规范这个模型。

RandomForest 分类器有相当多的参数需要调整。如何记住需要调整哪些参数以减少过拟合的一个小提示是,您通常需要降低以 *max_* 开头的参数值,并增加以 *min_ 开头的参数值。*我将减少树的深度,增加最小样本分割。

使用正则化估计器评估训练和测试数据集

现在,训练和测试数据集的 F1 分数看起来更好了。然而,仍有改进的余地。提高模型泛化能力的方法之一是使用[主成分分析](https://en.wikipedia.org/wiki/Principal_component_analysis) (PCA),这已被证明是树模型的一个非常有效的数据转换步骤。由于树模型喜欢正交的决策边界,旋转数据集可能有助于构建一个不太复杂的树。在训练之前对数据集应用 PCA 通常会导致特征的更好的定向和模型的总体更好的概括能力。我们在训练基线模型之前不应用 PCA 的原因是 PCA 将特征转换成失去其可解释性的主要成分。然而,可解释性是基线模型的主要要求。

现在,让我们检查一些其他评估指标,以确保分类有意义。

混淆矩阵

该模型正确分类了 66%的警官没有参与事故的情况和 81%的警官参与事故的情况。不出所料,少数类的查全率和查准率比多数类差。这可以通过增加数据集中负类样本的数量来改善,或者使用更高级的采样技术,如 [SMOTE](https://bmcbioinformatics.biomedcentral.com/articles/10.1186/1471-2105-14-106) 。但是,请记住,使用 SMOTE 进行过采样的计算开销很大,可能需要在云环境中运行。

让我们得到警察参与事故的概率,并检查基线模型的 ROC 曲线下的面积。

AUC ROC 曲线我们的随机森林分类器与随机

ROC 曲线下的面积为 0.83,这对于基线模型来说是相当不错的表现。

# 特征重要性

我谈了很多关于模型可解释性的重要性。在我们实际研究它之前,我想花点时间谈谈决策树模型中特征重要性的特征属性。决策树算法中衡量分裂质量的函数是基尼系数或熵。两者都旨在以一种获得的类样本尽可能纯净的方式分割树节点。因此,高基数分类特征以及连续特征具有很高的重要性,这仅仅是因为它们通过小而纯的类样本产生大量分裂。然而,由于我们的目标是了解每个特征对于做出分类决策的有用程度,我们需要使用另一种方法。一种方法是计算置换特征重要性。置换特征的重要性回答了这样一个问题:“如果我们随机置换一列数据,而将其他列留在原位,我们的模型的准确性会受到怎样的影响”。这听起来像是特性重要性的一个更有用的定义。

实现的分类器的特征重要性与探索性数据分析部分中提供的发现一致。 *Junction_Control、*Geo 变量和 *Ploice_Force* 是具有最高鉴别能力的特征。从设计特征来看,最重要的是*周期**高峰时间*。通过引入新的地理相关变量或提高 *Junction_Control* 变量的质量,我们可以将这些见解用于未来的特征工程。

# 结论

在这一部分中,我们看了好的基线模型的几个要求。然后,我们看到了如何利用定制转换器进行数据处理。训练了一个 RandomForest 分类器,我们看到了如何减少决策树模型的过度拟合。最后,我们计算了每个特征对于做出分类决策的重要性,并表明我们的模型做出的决策与之前执行的探索性数据分析一致。

[](https://skilled.dev) [## 编写面试问题

### 一个完整的平台,在这里我会教你找到下一份工作所需的一切,以及…

技术开发](https://skilled.dev)

# 如何从头开始构建一个基本的聊天机器人

> 原文:<https://towardsdatascience.com/how-to-build-a-basic-chatbot-from-scratch-f63a2ccf5262?source=collection_archive---------9----------------------->

## 从文本预处理、构建模型到使用 AJAX 的成熟 Flask web 应用程序

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2f8a3d0386bb1c3e3dda63d07b648528.png)

封面图片(来源:作者)

无论是 Whatsapp 聊天、丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 group、Slack channel 还是任何产品网站,我相信你都遇到过突然冒出来的这些机器人。你问一些问题,它会尽力解决你的疑问。今天,我们将尝试构建一个聊天机器人,它可以响应一些基本的查询并实时响应。

让我们假设我们将为一家餐馆建造一个聊天机器人。我们的客户对聊天机器人有一定的要求。

该机器人应该能够:

1.  问候网站上的访问者。
2.  预定座位。
3.  显示可用座位。
4.  显示菜单上有什么。
5.  显示工作时间。
6.  显示联系信息。
7.  显示餐馆的位置。

最终,我们的聊天机器人会是这样的:

聊天机器人演示(来源:作者)

如果你对自然语言处理(NLP)、深度学习中的全连接层和 Flask 框架有基本的了解,这个项目对你来说将是轻而易举的。即使你不熟悉这些术语,我也会尽力用简单的语言解释一切,并尽可能链接有用的资源。

话虽如此,让我们开始构建我们的聊天机器人。

# **训练数据**

现在是时候看看我们在这里处理什么样的数据了。构建聊天机器人所需的数据与我们通常看到的传统数据集略有不同。每台智能机器都需要它能看到和解释的数据。我们不会为这个项目下载任何特定的数据集。我们已经有了一小组数据。让我们来看看。

这是我们数据的一个例子。它是一个 JSON 格式的文件,通常用于存储和传输数据。这里需要注意的三个重要术语是**、【标签】、**、【模式】、**、【响应】、**。****

用户输入的让聊天机器人解释的任何查询都必须包含在**“模式”**中。

解释完用户的查询后,聊天机器人必须回复该查询,该回复将从**“响应”**中的一组预定义回复中随机选择。

**“tag”**将一组相似的模式和对特定类别的响应进行分组,以便模型更容易预测特定模式代表哪个类别。

您现在可以将下面给出的数据复制到一个文件中。我将我的文件命名为“intents.json”。

正如你所看到的,这里提供的数据符合我们客户的所有要求。我有意将标记“menu”、“book_table”和“available_tables”的响应设置为空列表。我将在我们的项目中稍后解释原因。

有了这些数据,我们现在可以训练我们自己的神经网络,它会预测并尝试将其分类到文件中的一个标签中。一旦标签已知,将从该标签中选择一个随机响应并显示给用户。您可以向该数据中添加任何其他标签。只要确保语法没有错。您提供的标签、模式和响应越多,聊天机器人就越强大。

现在您已经熟悉了数据,让我们使用 Python 将它加载到内核中。我使用的版本是 Python 3.6。

# 设置

在开始编写任何代码之前,建议设置一个虚拟环境,这样我们将要安装的任何库都不会与现有的库冲突,也不会导致任何冗余问题。

我将使用 conda 创建一个虚拟环境。([看这里](https://docs.anaconda.com/anaconda/install/windows/)关于如何安装 Anaconda。)

打开命令提示符并输入命令。

```
conda create -n simple_chatbot python=3.6
```

这里“simple_chatbot”是虚拟环境的名称。你可以给它起任何你喜欢的名字。

要激活这个虚拟环境,只需输入:

```
conda activate simple_chatbot
```

一旦激活,您的环境的名称应该显示在左侧,如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/904b7d8f5dda9c9e0cbe9eed2a2481d1.png)

括号中的环境名称(作者截图)

我们将使用 pip 来安装以下库:

*   numpy==1.16.5
*   nltk==3.4.5
*   张量流==1.13.2
*   tflearn==0.3.2
*   烧瓶==1.1.1

为了安全起见,我还添加了库的版本。

```
pip install packagename==version //Enter packages mentioned above
```

现在我们已经准备好了,让我们开始研究代码。

# 导入库和加载数据

现在,我们将导入一些加载、处理和转换数据所需的库,然后将其输入深度学习网络。只需记住将 JSON 文件保存在 python 文件所在的目录中。我将把我的文件命名为“main.py”。

# 文本预处理

现在,我们必须将“标签”和“模式”从文件中取出,并将其存储在一个列表中。我们还将收集模式中的独特单词来创建一个单词包(弓)向量。

在上面的代码中,我们创建了四个空列表。

1.  **单词:**保存了一个独特的单词列表。
2.  **标签:**保存文件中所有唯一标签的列表。
3.  **docs_x:** 保存模式列表。
4.  **docs_y:** 保存对应于 docs_x 中模式的标签列表。

当我们遍历数据时,我们将所有模式转换成小写,标记每个模式,然后将它们添加到各自的列表中。我们还同时将模式的标签添加到 docs_y 中。

## 堵塞物

既然我们已经把单词放在了列表中,是时候对它们进行词干分析了。词干基本上是试图找到一个词的词根。它删除了一个单词的所有前缀和后缀,因此我们正在构建的模型将获得该单词的大致概念,而不是陷入同一单词不同形式的所有错综复杂的关系中。有不同类型的茎干工,如波特·斯特梅尔、斯诺鲍·斯特梅尔、兰卡斯特·斯特梅尔等。我们将在代码中使用兰开斯特·斯特梅尔。(点击了解更多关于词干分析器的信息[。)](/stemming-vs-lemmatization-8b30c1d3795a)

## …向量化…

众所周知,机器学习和深度学习模型只接受数字输入。所以我们必须把这个词干列表转换成某种数字输入,这样我们就可以把它输入到神经网络中。这就是单词包、TF-IDF、Word2vec 等矢量化方法的用武之地。

我们将在代码中使用单词包(BoW)。它基本上描述了一个单词在文档中的出现。在我们的例子中,我们将用列表“words”中收集的所有独特单词的长度列表来表示每个句子。列表中每个位置将是“单词”中的唯一单词。如果一个句子由一个特定的单词组成,它们的位置将被标记为 1,如果一个单词不在那个位置,它将被标记为 0。

但是使用这种方法,模型只能理解句子中出现的单词。句子内单词的顺序会丢失,因此得名“单词包”。其他方法如 TF-IDF、Word2Vec 试图以自己的方式捕获这些丢失的语义。我建议您也尝试一下其他矢量化方法。

类似地,对于输出,我们将创建一个列表,它是 JSON 文件中标签/标记的长度。任何这些位置中的“1”表示该特定标签/标记中的图案的归属。

我们还将把所有处理过的数据保存在一个 pickle 文件中,以便以后可以用来处理来自用户的输入。

# 建立模型

既然我们已经完成了数据预处理,那么是时候构建一个模型并将预处理后的数据输入其中了。网络架构并不太复杂。我们将使用完全连接的层(FC 层),其中两个是隐藏层,一个给出目标概率。因此,最后一层将有一个 softmax 激活。

您可以随意摆弄架构和数字,以获得符合您需求的模型。您还可以选择在文本预处理中增加一些步骤,以便从数据中获得更多信息。试错的次数越多,你对架构的理解就越好。

我们现在要做的就是把数据输入这个模型,然后开始训练。我们将纪元设置为 200,批量设置为 8。同样,您可以试验这些数字,并为您的数据找到正确的数字。训练后,我们将把它保存在磁盘上,这样我们就可以在 Flask 应用程序中使用训练好的模型。

如果一切顺利,工作目录中应该有名为“model.tflearn.data”、“model.tflearn.index”和“model.tflearn.meta”的文件。

您的“main.py”文件应该如下所示:

# 建筑用烧瓶应用

现在我们已经训练了我们的深度学习模型,是时候将其集成到 web 应用程序中了。我们将在这里使用的框架是 Flask。现在解释如何构建 Flask 应用程序需要一系列的文章,所以我不会在这里做。然而,我将确保在下面的“参考资料”一节中包含我在构建这个应用程序时参考的所有资源。

这里有一个[链接](https://github.com/iampratheesh/Restaurant-Chatbot)到我的 GitHub 库,在这里你可以访问所有的文件来构建 Flask 应用程序。我建议您将所有文件复制到您的工作目录中,以便它可以访问已训练的模型和 pickle 文件。

我们将使用 AJAX 进行异步数据传输,也就是说,你不必每次向模型发送输入时都重新加载网页。web 应用程序将无缝地响应您的输入。让我们来看看 HTML 文件。

看看 JavaScript 部分,我们从用户那里获得输入,将其发送到“app.py”文件,在那里输入给训练好的模型,然后接收输出,在应用程序上显示它。

“app.py”文件是所有路线被提及的地方,输入数据被处理(词干和单词包),并被馈送到模型以进行输出。让我们来看看。

我们首先导入所有需要的库,然后加载保存预处理数据的 pickle 文件。这将需要为输入数据创建 BoW 矢量。然后,我们定义一个函数“单词包”,其中我们提供用户输入,并获得一个 BoW 向量作为输出。

还记得空响应的标签“menu”、“book_table”和“available_tables”吗?我们这样做是为了在这些标签中提供对问题的定制响应。

对于与菜单上有什么相关的问题,我们首先会检查今天是星期几,然后根据这个信息,聊天机器人会推荐当天的特色菜。

当用户请求预订一张桌子时,我们将计数器“seat_count”减 1。现在,当然,这不是预订的工作方式,但演示的目的是展示我们可以使用这个聊天机器人的可能性。你可以把这个机器人连接到一个数据库,并据此进行预订。或者您可以根据自己的需求添加任何其他任务。询问可用的桌子只是显示“seat_count”的当前值。每当您重置 Flask 服务器时,计数器都会回到 50。这样做是为了说明您不必总是依赖 JSON 文件来获得响应。

一旦设置完成,只需运行“app.py”文件,Flask 服务器就可以运行了。它应该是这样的:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a93513b9320d136efd17668ac403119d.png)

Flask Web 应用程序(来源:作者)

# 结论

这个项目终于完成了,并且像预期的那样工作。然而,这里有很多东西你可以调整和微调。我很想听听你能给这个聊天机器人增加什么额外的功能,或者你对这个项目做的任何其他修改。你可以将这个聊天机器人连接到一个数据库,或者将其与任何网站集成。除了使用单词包,您还可以使用其他矢量化方法,如 TF-IDF、Word2Vec 等。这些方法很有可能会提高模型预测标签的准确性。

正如承诺的那样,我还列出了我在构建这个应用程序时参考的所有博客和视频。这肯定会帮助你更深入地了解这个项目及其运作。

# 参考

1.  [带 Tensorflow 的上下文聊天机器人](https://chatbotsmagazine.com/contextual-chat-bots-with-tensorflow-4391749d0077)
2.  [烧瓶教程](http://youtube.com/playlist?list=PL-osiE80TeTs4UjLw5MM6OjgkjFeUxCYH)作者[科里·斯查费](https://www.youtube.com/user/schafer5)
3.  使用 Flask 在 Python 中构建聊天机器人
4.  [用 jQuery 和 Flask 提交 AJAX 表单](https://www.youtube.com/watch?v=IZWtHsM3Y5A)

# 如何在 D3.js 中构建基本行

> 原文:<https://towardsdatascience.com/how-to-build-a-basic-line-in-d3-js-38f67055043f?source=collection_archive---------46----------------------->

## 数据可视化

## 关于如何开始使用流行的 Javascript 库进行数据可视化的一些技巧。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e6023726ca87047fe0e9031819d7a3b6.png)

马库斯·温克勒在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片

在处理数据时,最重要的一个方面是数据的表示。因此,数据可视化有不同的工具和技术。在本教程中,我将向您展示如何在 [D3.js](https://d3js.org/) 中构建一个基本行。D3.js 是 javascript 中最强大的数据可视化库之一。在[这个链接](https://observablehq.com/@d3/learn-d3)你可以找到一些学习 D3.js 的基础教程。

代码可以从[我的 Github 库](https://github.com/alod83/dj-infouma/blob/master/DataVisualization/BasicLineChart.html)下载,它是从 d3 数据图库中提取的[这个例子](https://www.d3-graph-gallery.com/graph/line_several_group.html)的自由灵感。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/826fe45c717f825420fcd4c0db70998a.png)

# 入门指南

## HTML 页面的数据描述和构建

首先,我们从数据开始。我们考虑了 1990 年至 2019 年意大利、法国、西班牙、德国和英国游客人数的相关数据。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d8c75a1d7e56aa20e64a2789b038e758.png)

我们有一个日期列和另外 5 个列,每个国家一个。然后我们开始构建 HTML 代码:

```
<!DOCTYPE html>
<html>
  <head>
     <meta charset="utf-8">
     <script src="[https://d3js.org/d3.v4.js](https://d3js.org/d3.v4.js)"></script>
 </head>
 <body>
     <div id="line"></div>
 </body>
</html>
```

# 绘制基本的 SVG 对象

## 定义边距并将 SVG 对象追加到 HTML div 中

注意,我们使用 d3 的版本 4。在`body`中,我们创建了一个包含该行的`div`。现在我们可以写脚本了,它将被插入到`body`中。

我们设置图形的尺寸和边距:

```
var margin = {top: 50, right: 30, bottom: 30, left: 100},
    width = 600 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;
```

我们将一个`svg`元素添加到在 HTML 代码中创建的`div`中,并指定它们的尺寸。我们还将一个分组元素`g`添加到`svg`中,并将其转换为`margin.left`和`margin.top`:

```
var svg = d3.select("#line")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")");
```

# 加载和格式化数据

## 从 CSV 加载数据,并根据应用程序的使用情况对其进行格式化

现在我们可以通过使用函数`d3.csv(data, preprocessing_function, processing_function)`读取 CSV,其中`data`表示 CSV 数据,`preprocessing_function`允许根据一些标准格式化数据,`processing_function`执行构建图形所需的操作。

我们定义了下面的`preprocessing_function`(注意我们省略了函数名,因为我们将它放在`d3.csv`函数中,不需要名字):

```
 function(d){
    return { 
      date : d3.timeParse("%Y-%m-%d")(d.date), 
      IT : d.IT , 
      FR : d.FR, 
      DE : d.DE, 
      ES : d.ES, 
      UK : d.UK}
  },
```

我们所做的唯一有用的事情是将日期解析为对象日期。其他字段保持不变。现在我们可以定义`processing_function`。此功能需要 CSV 文件中包含的输入数据。

# 向图表添加轴和标题

## 将 X 轴和 Y 轴添加到图表中,并定义它们的范围和域。也添加一个标题

我们加上 X 轴,使用时间刻度。我们定义了域和范围,域包含轴的可能值的范围,范围包含轴在 svg 图像中的维度。

```
var x = d3.scaleTime()
      .domain(d3.extent(data, function(d) { return d.date; }))
      .range([ 0, width ]);
```

我们将轴附加在 svg 对象的底部:

```
svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x));
```

类似地,我们构建 y 轴,其中域由数据中的最大值指定。在我们的例子中,最大值由英国系列给出:

```
var y = d3.scaleLinear()
      .domain([0, d3.max(data, function(d) { return +d.UK; })])
      .range([ height, 0 ]);
```

我们将 y 轴附加到 svg 对象的左侧:

```
svg.append("g")
     .call(d3.axisLeft(y));
```

现在我们为 y 轴构建一个标签,我们将它旋转 90 度,并将其附加到 svg 对象上。

```
svg.append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 0 - margin.left)
      .attr("x",0 - (height / 2))
      .attr("dy", "1em") 
      .attr("font-size", "12px")
      .style("text-anchor", "middle")
      .text("Total Number of Tourists Arrivals");
```

我们还可以添加一个标题,只需在 svg 对象的顶部添加另一个文本:

```
svg.append("text")
      .attr("y", 0 - margin.top)
      .attr("x",(width / 2))
      .attr("dy", "1em")
      .attr("font-weight", "bold")
      .attr("font-size", "16px")
      .style("text-anchor", "middle")
      .text("Total Number of Tourists Arrivals for Italy");
```

# 向图表添加线条

## 为每个国家添加一行

我们可以为每个国家定义不同的颜色。这可以通过定义调色板来实现。我们定义了一个名为`countries`的数组,包含所有的国家标识符。

```
var countries = ['IT', 'FR','DE','UK','ES'];

var color = d3.scaleOrdinal()
     .domain(countries)
     .range(['#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00'])
```

我们可以为每个国家添加一行。我们使用名为`path`的 svg 元素,并定义它的属性。注意颜色因国家而异。

```
for(var i = 0; i < countries.length; i++)
 {
     svg.append("path")
       .datum(data)
       .attr("fill", "none")
       .attr("stroke", function(d){ return color(countries[i]) })
       .attr("stroke-width", 1.5)
       .attr("d", d3.line()

        .x(function(d) { return x(d.date) })
        .y(function(d) { return y(d[countries[i]]) })
        )
 }
```

# 向图表添加图例

## 画图例来理解线条

我们也可以画一个图例。图例由指定颜色的矩形和指定国家标识符的文本组成。

```
var lineLegend = svg.selectAll(".lineLegend").data(countries)
     .enter().append("g")
     .attr("class","lineLegend")
     .attr("transform", function (d,i) {
      position = width - margin.right
            return "translate(" + position + "," + (i*20)+")";
        });lineLegend.append("text").text(function (d) {return d;})
     .attr("transform", "translate(15,9)"); //align texts with boxeslineLegend.append("rect")
     .attr("fill", function (d, i) {return color(d); })
     .attr("width", 10).attr("height", 10);
```

# 摘要

在本教程中,我演示了用 d3.js 构建基本折线图的过程,这是一个低级 js 库,用于操作 HTML 和构建非常强大的 SVG 对象。总而言之,构建图表的步骤如下:

*   在 HTML 页面上,静态创建一个`div`标记,它将包含 JS 脚本中的图表
    :
*   例如从 CSV 文件中读取数据
*   根据数据的用途格式化数据
*   检索 div 并挂起一个`svg`对象
*   将 x 轴和 y 轴挂在`svg`对象上,并给它们分配域(一组可能的值)和范围(尺寸)
*   在`svg`对象上挂一条线、一个矩形或一个点作为每个数据
*   在`svg`物体上挂一个图例(可能)
*   在`svg`物体上挂一个标题。

# 相关文章

[](https://medium.datadriveninvestor.com/getting-started-with-d3-js-maps-e721ba6d8560) [## D3.js 地图入门

### 用流行的 Javascript 库构建交互式 Choropleth 地图的快速教程

medium.datadriveninvestor.com](https://medium.datadriveninvestor.com/getting-started-with-d3-js-maps-e721ba6d8560) [](/how-to-build-a-dynamic-bar-chart-in-observablehq-through-sqlite3-f8f8b6509ac8) [## 如何通过 sqlite3 在 Observablehq 中构建动态条形图

### 一个现成的笔记本,利用了 Observablehq 提供的最新 sqlite3 特性

towardsdatascience.com](/how-to-build-a-dynamic-bar-chart-in-observablehq-through-sqlite3-f8f8b6509ac8) [](/how-to-insert-an-observablehq-graph-into-a-html-page-57a9f4546ecf) [## 如何将 Observablehq 图形插入 HTML 页面

### 一个快速的教程,用你的观察制作精彩的 HTML 页面。

towardsdatascience.com](/how-to-insert-an-observablehq-graph-into-a-html-page-57a9f4546ecf) 

# 你知道你可以给你的 d3 图添加注释吗?

你可以使用 d3 注释库。

在这里继续阅读。

# 保持联系!

*   跟着我上[](https://medium.com/@alod83?source=about_page-------------------------------------)
*   注册我的[简讯](https://medium.com/subscribe?source=about_page-------------------------------------)
*   在 [LinkedIn](https://www.linkedin.com/in/angelicaloduca/?source=about_page-------------------------------------) 上连接
*   在推特上关注我
*   跟着我上[脸书](https://www.facebook.com/alod83?source=about_page-------------------------------------)
*   在 [Github](https://github.com/alod83?source=about_page-------------------------------------) 上关注我

# 如何使用 RASA 表单构建上下文助手

> 原文:<https://towardsdatascience.com/how-to-build-a-contextual-assistant-using-rasa-forms-82e014a10dea?source=collection_archive---------30----------------------->

## 一个超级简单的指南,创建一个带有表单集成的信息检索聊天机器人。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/07ea80a3f7fbd02650dedfd7de99d205.png)

我们非常清楚聊天机器人是这一代人的未来,我相信每个人都必须知道聊天机器人如何工作的基本知识。这正是我这篇文章的目的,我希望读完这篇文章后,你可以构建自己的机器人。

# 介绍

你可以在 RASA 上找到很多使用 RASA APIs 构建聊天机器人的教程。但是我最近没有发现任何详细讨论和简化我的研究的东西,比如对我来说最重要的安装问题。

在这篇文章中,我很乐意与你分享我用 Rasa 框架构建聊天机器人的旅程,在这个过程中,我们将从用户那里收集一些信息。我们将从安装部分开始,直到与机器人交谈。

# 目录

1.  信息检索聊天机器人
2.  RASA 框架概述
3.  安装 Rasa 及其依赖项
4.  构建使用表单接收用户信息的聊天机器人

# 信息检索聊天机器人

聊天机器人是一种计算机程序或人工智能,它通过听觉或文本方法进行对话。这类程序通常被设计成令人信服地模拟人类作为对话伙伴的行为。聊天机器人通常在对话系统中用于各种实际目的,包括客户服务或信息获取。一些聊天机器人使用复杂的自然语言处理系统,但许多更简单的系统会扫描输入中的关键词,然后从数据库中提取最匹配的关键词或最相似的措辞模式进行回复。关于聊天机器人定义的更多细节和更基本的理解,如*什么是意图?和实体?你可以在这个[链接](https://medium.com/analytics-vidhya/how-i-built-my-first-chatbot-for-slack-using-dialogflow-and-node-js-in-minutes-9ce7e5b81c8c) *查看我之前关于聊天机器人的文章。**

如今,大多数聊天机器人都用于一个特定的应用程序,从用户那里收集一些信息,以便提供一些东西(预订餐馆、搜索数据库等)。).这也叫**槽填充。这类机器人旨在提供类似人类的答案,无需人工干预。在这里,系统试图理解你想问什么问题。并给你这样的表格来保存你的具体信息。**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/953ea38f4b0f8615c53a5451e9ce3dd8.png)

网站注册表格示例:图片[来源](https://docs.easydigitaldownloads.com/article/959-frontend-submissions-registration-form-editor)

在本文中,我们将构建一个聊天机器人来填充这样一个简单的表格,以供学习之用。所以你要跟我到最后。

# RASA 框架概述

RASA 是一个开源的对话式人工智能框架。我最喜欢这个框架的是数据隐私,在这里你不需要担心把你的数据放在别人的云中——像微软 Luis 或者亚马逊 Lex。目前,有 3 种人工智能助手:

*   **通知助手:**能够发送简单的通知,如文本消息,推送通知。
*   **常见问题助手:**当今最常见的助手类型。它可以回答简单的问题,比如常见问题。
*   **上下文助手:**能够优雅地处理任何用户目标,并帮助尽可能好地完成它。这意味着它能够理解和响应不同的和意外的输入。

RASA 框架有三个主要组件,它们协同工作来创建上下文助手:

*   **拉莎·NLU:**是自然语言理解。假设用户说“我想订一本书”。NLU 的工作就是接受这些输入,理解用户的意图,并找到输入中的实体。比如上面这句话,意图是*订购*,实体是*一本书*。Rasa NLU 内部使用词袋(BoW)算法来查找意图,使用条件随机场(CRF)来查找实体。尽管您可以使用其他算法通过 Rasa 来查找意图和实体。
*   **RASA 核心:**核心是 RASA 的对话管理组件。它根据 ***【对话状态】*** 和 ***【上下文】*** 决定助理应该如何回应。Rasa Core 通过观察用户和助手之间的对话数据模式进行学习。它不是一堆 if/else 语句,而是使用一个经过示例对话训练的机器学习模型来决定下一步该做什么。
*   RASA X: 是一个工具集,开发人员可以用它来构建、改进和部署 RASA 框架的上下文助手。Rasa X 的好处在于,你可以与真实用户分享你的助手,并收集他们与机器人的对话,让你在不中断机器人在生产中运行的情况下改进它。

**用法:**安装 Rasa 后,你会发现 3 个文件,分别是:

```
domain.yml, stories.md, nlu.md
```

它们分别定义了你的机器人生活的世界,机器人必须遵循的对话主干,以及它被训练来分类意图和实体的数据。

**域:**定义你的机器人运行的宇宙。它准确地指定了:
-你期望对
做出哪些反应-你希望跟踪哪些槽
-你的机器人可以采取哪些行动
***什么是槽?***
**时段**是你想在对话中记录的东西。

**动作:**是你的机器人可以做的事情。例如,操作可以:
-响应用户。
-进行外部 API 调用。
-查询数据库。

**故事:**对话系统的训练数据样本称为故事。这向机器人展示了如何对用户的输入做出反应。它以一个名字开头,名字前面有两个哈希`##`

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7f5118a2b53f69de240f1fe6419fa83c.png)

我们的故事为这篇文章提供了入学查询的例子

**NLU 数据:**用来训练 NLU 的数据。这是它看起来的样子:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9f918973c2adaff28b4ca68f109454f6.png)

我们的 data/nlu.md 文件的屏幕截图

该模型根据这些示例进行训练。黄金法则是,例子越多(每个意图),预测就越准确。

因此,根据上述 3 个文件的定义和内容,您的机器人将被训练并相应地执行。

# 安装 Rasa 及其依赖项

我在 windows 10 和 Ubuntu 19.04 中都安装了 RASA。老实说,我一直认为开始用 RASA 构建人工智能助手的最快方法是在命令行上,步骤非常简单。
你可以用一个命令同时安装 Rasa (NLU 和内核)和 Rasa X,但是你需要先 ***升级你的 pip,*** 下面是 *Ubuntu 19.04* 中的安装步骤。

```
$python3 -m pip install --user --upgrade pip
$python3 -m pip install --user rasa --default-timeout=100
```

**空间相关性:**有关空间的更多信息,请查看[空间文档](https://spacy.io/usage/models)。您可以使用以下命令安装它:

```
$python3 -m pip install --user -U spacy
$python3 --user -m spacy download en_core_web_sm
```

**恭喜你!您已经成功安装了 Rasa 开源!** 🥳

您现在可以创建新项目了。为此,您只需运行:

```
$mkdir myfirst_Bot
$cd myfirst_Bot
$rasa init --no-prompt
```

`rasa init`创建 Rasa 项目需要的所有文件,并在一些样本数据上训练一个简单的机器人。如果你忽略了`--no-prompt`标志,你将会被问到一些关于你希望你的项目如何建立的问题。

现在,是时候了解一些更高级的 RASA 特性了。

# 构建使用表单接收用户信息的聊天机器人

我们现在知道,上下文助手不仅仅是简单的 FAQ 机器人。它需要收集在正确的上下文中回答用户问题所需的重要细节。在这篇文章中,我将向你展示如何建立一个简单的演示表格机器人,关于录取过程,它会问你的名字,你的 SSN 号码,以及你想学的科目。

那么,如何实现这个聊天机器人呢?🤔很高兴你问了。👇

首先,我们需要创建一个新文件夹,您可以随意命名。然后运行`rasa init`来创建一个 RASA 项目需要的所有文件。

这些表格最棒的地方在于,助理从一个单独的培训故事中学会了如何处理入学途径。为了简化事情,避免冗长乏味的文章,gif 中总结了创建这个聊天机器人的过程,并提供了详细信息。查看下面的 gif 以获得更多说明:💡 👇👇

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ab1964b9161147da8ef1c347bb4deea3.png)

现在,我们可以尝试 **Rasa X** 进行深入理解,并验证我们的验证函数是否工作正常。👇

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2748fe61c6c6b80ac2420fe5298c9676.png)

而且成功了!!🎉🎉 👏 👏

现在,你也可以创建一个简单但很好的像人一样的对话聊天机器人。😉😉

# 结论

> "一次好的谈话可以永远改变改变的方向." **—琳达·兰伯特。**

这是一个创建使用表单接收信息的对话聊天机器人的教程。现在,我认为你已经有了基本的东西,你可以添加尽可能多的交互性来创建你自己的聊天机器人,用于餐馆预订、医生预约等。

通过这篇文章,我想告诉你创建聊天机器人既不容易也不困难。我们利用 Rasa 的能力,用最少的训练数据创建了一个机器人。Rasa 是一个非常有用的库,你可以试验和修改它来创建一些真正有用的聊天机器人。不要止步于此,继续尝试更多。🤖👩‍💻

***快乐阅读,快乐学习,快乐编码。***

# 在你离开之前:

如果您有任何问题或任何不清楚的地方,请告诉我,如果您想要这个项目的源代码,可以通过我的*[*LinkedIn*](https://www.linkedin.com/in/amal-menzli-3ab655155/)联系我或给我发电子邮件。*

*您也可以查看我之前关于构建聊天机器人的文章:*

*[](https://medium.com/analytics-vidhya/how-i-built-my-first-chatbot-for-slack-using-dialogflow-and-node-js-in-minutes-9ce7e5b81c8c) [## 我如何在几分钟内使用 Dialogflow 和 Node.js 为 Slack 构建我的第一个聊天机器人

### 构建您的第一个货币转换器聊天机器人,并部署在 Slack。

medium.com](https://medium.com/analytics-vidhya/how-i-built-my-first-chatbot-for-slack-using-dialogflow-and-node-js-in-minutes-9ce7e5b81c8c) 

# 参考资料:

1.  RASA 文件( [Rasa 基础知识](https://rasa.com/docs/rasa/user-guide/rasa-tutorial/))。
2.  来自 Justina 的关于如何用 Rasa 构建上下文助手的教程[](https://blog.rasa.com/building-contextual-assistants-with-rasa-formaction/)*

# 如何为小说作者搭建一个可控的写作助手

> 原文:<https://towardsdatascience.com/how-to-build-a-controllable-writing-assistant-for-novel-authors-a9fa15b57c6a?source=collection_archive---------35----------------------->

## [实践教程](https://towardsdatascience.com/tagged/hands-on-tutorials)

## 使用迁移学习和 OpenAI GPT2 构建一个嵌入在开源接口中的最先进的文本生成工具

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/582698487e2921bd796d1d3e10aacbe0.png)

AITextGenerator —根据周围环境以及指定的实体、类型和大小生成文本—图片由作者提供

**几年前**,创造了一个写作工具,包括使用简单的概率模型和精心设计的语法规则,以便在已知前一个世界的基础上选择下一个世界。除了冗长和挑剔之外,结果极其有限。

随着最近在 NLP 深度学习方面的**进展,我们现在可以摆脱这种琐碎的工作,建立更加强大的文本生成算法🌟正如您将在本教程中看到的。这一进展与**变压器**架构的出现相一致(Vaswani 等人)🏭,实现了在巨大文本语料库上训练的大规模语言模型(Devlin et al .,2018;戴等,2019)达到卓越的性能,产生接近人类会写的东西。**

> 如果你不相信我,我会建议你去看看刚刚发布的 [GPT-3](https://openai.com/blog/openai-api/) **,**,它展示了众多令人惊叹的功能。

然而,这些强大的模型呈现出⛔.的几个缺点训练他们是非常困难和昂贵的。他们仍然很难在长段落中保持连贯的上下文。最后,用户还不能操纵生成和控制所生成文本的某些特定方面。

**为了解决这些限制**,我们的秘密武器是使用大规模预训练语言模型[,开放人工智能 GPT-2](https://openai.com/blog/gpt-2-1-5b-release/) 🦄[1],结合创新的迁移学习微调技术——用于受控和情境化的文本生成。

> 从这个角度来看,我们的工作类似于[拥抱脸的最先进的对话式人工智能](https://medium.com/huggingface/how-to-build-a-state-of-the-art-conversational-ai-with-transfer-learning-2d818ac26313) **,**在以往历史和机器人“个性”的语境化对话方面做了出色的工作。

更具体地说,我们的**目标**🏆是让用户在写小说的任何时候,能够自动生成与文章其余部分一致的新章节,尤其是前面和后面的段落。我们给他们选择实体的机会(角色、地点等)。)👤他们已经在小说中介绍了,并希望包含在新的章节中。同样,他们可以指定所需文本的大小📝,其内容通过一个小摘要或关键词💬甚至他们正在写的书的类型📗。

开源平台的缺乏促使我们将我们的工具集成到一个**用户友好的交互式开源网络服务**中,让任何作者都能从中受益——简单、直观且免费。

> 一定要去[看看](http://textgen.thomas-lamson.com/)!🎮
> *更新*:我们已经关闭了服务器,因为我们快没钱了——抱歉*😅但是你仍然可以在你的电脑上运行它。*

**最后**,我们提出了一个**易用的** **写作助手**,它自动做出几个建议,用户可以从中选择并编辑。目标是在遵守以下限制的情况下,产生为作者提供想法的创造性输出:

*   确保流利和正确的语法
*   在符合周围环境的同时,始终如一地填补作者指出的空白
*   尊重想要的长度和类型
*   使用选定的实体并反映所需内容的摘要

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bdf3b2b6af8f81722983538cda4050ed.png)

卢卡斯·布拉塞克的图片来自[unpalsh](https://unsplash.com)

📆以下是我们今天要学习和玩的内容:

*   如何使用**迁移学习**来构建一个基于**open ai**GPT-2transformer 语言模型的**最先进的文本生成工具**。
*   如何从头开始创建此类任务所需的复杂数据集。暗示了**多种型号的综合使用**。虽然核心代基于 OpenAI GPT-2,但我们采用了其他几个模型,如 BERT、BART、T5 等。在项目的不同阶段。
*   如何在云实例上为不到 100 美元的**培训这个模型。**
*   如何在开源 JavaScript/Python web 服务中使用我们的**创新用户界面** (UI)作为实用的创作生成工具。

> 和这篇文章一起,我们发布了我们的代码!查看 [Github](https://github.com/WeazelDev/AITextGenerator) 回购这里✈️
> 我们还写了一篇论文在 EACL,[链接](https://arxiv.org/abs/2101.03216)。

我们到了,让我们开始吧🚀

# 受控和语境化的文本生成

在深入这个过程的细节之前,让我们先弄清楚我们的方法背后的**直觉。💡**

**理想情况下**,我们希望**从头开始训练** **一个模型**来生成与上下文和用户特定输入一致的段落。在实践中,我们会教我们的模型使用前一段和后一段(P1 和 P3)以及用户提供的附加信息来重新生成每本书的段落(P2)。

当然,这意味着**使用特定的数据集**📁数百部小说被分成段落,还有关于它们的大小、它们展示的实体、它们的内容摘要以及它们所属的书的类型的信息。但是我们稍后会回到这个话题。

然而,这将是一个重大的挑战🙈!这将涉及训练一个拥有数百万参数的巨大语言模型,让它有足够的时间学习产生一致且语法正确的句子,这些句子还应该是语境化和可控的。

> [](https://grover.allenai.org/)**【3】例如,一个出色的假新闻文章生成器,拥有 15 亿个参数,需要用 256 个 TPU 进行两周的训练,花费了 35000 美元。💸**

**为了解决这个问题,我们将走一条在过去几个月/几年里引起极大兴趣的道路:**迁移学习**💯**。这种方法背后的想法很简单:****

*   ****在一个非常大的**文本语料库**上预先训练**一个语言模型开始,以便能够生成长段连续连贯的文本。**
*   ****微调**这个语言模型,使其适应我们的最终任务:语境化和可控的文本生成。**

**由于**预训练**语言模型是一个昂贵的操作,通常最好从已经预训练和开源的模型开始。在这个项目中,我们决定使用现有的语言模型 **Open AI GPT2** ,它已经经过训练,可以生成流畅的句子,并以特定的方式对其进行微调,以产生更具情境性和可控性的输出。**

**让我们快速浏览一下🔎**

# **🦄打开人工智能 GPT-2**

**在 2018 年和 2019 年,亚历克·拉德福德、杰弗里·吴和他们在 OpenAI 的同事开源了两个语言模型,对非常大量的数据进行了训练:GPT 和 GPT-2(其中 GPT 代表生成式预训练变压器)。它们是两个非常相似的基于语言模型的转换器,被称为 T2 解码器,因为它们使用左上下文来预测下一个单词。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7767d5e2515c15255cafe5ea4325bb70.png)**

**图片来源:[图文并茂的 GPT-2(可视化变压器语言模型](http://jalammar.github.io/illustrated-gpt2/)**

**许多论文和博客帖子描述了**变形金刚**模型以及它们如何使用注意力机制来处理顺序输入,所以我不会花时间详细介绍它们。如果你对这些模型不熟悉,可以指点一下: [Emma Strubell 的 EMNLP 幻灯片](https://people.cs.umass.edu/~strubell/doc/lisa-final.key)是我个人最喜欢的,Jay Alammar 的“ [Illustrated Transformer](https://jalammar.github.io/illustrated-transformer/) ”是非常详细的介绍。**

**出于我们的目的,语言模型将只是一个模型,它将一系列标记作为输入,并且**为输入序列**之后的下一个标记生成词汇表上的概率分布。语言模型通常以并行方式训练,即预测长输入序列中每个标记后面的标记。**

# **🎯调整语言模型**

**一个经典的语言模型是用一个单一的输入来训练的:一个单词序列。但是正如我们之前看到的,我们的模型将不得不使用**上下文*的几种类型***来生成输出序列:**

*   **所需段落的*长度***
*   **所需段落的*风格/主题***
*   **要包括的*实体*列表**
*   **(各种形式的)内容的简短总结**
*   ***过去的**后面的*段**

> **我们如何从这些不同的上下文中为我们的模型构建输入呢?**

**一个简单的答案就是****上下文片段连接成一个序列,将真正的段落放在最后。然后,我们可以**通过继续该序列来逐词生成段落的完成**。因此,每个数据点将具有以下形式:**

```
[P3] P3 [Sum] Sum [T] Theme [Ent] Entities [Size] [P1] P1 [P2] P2 <|endoftext|>
```

**其中[P 1]、[P 2]、[P 3]、[Sum]、[T]和[Ent]表示模型接收到的输入类型(特殊标记)。请注意,输入的顺序并不重要。你只需要坚持下去。我们只是把 P1 放在最后,这样 GPT-2 就可以从那里继续,因为它已经被训练这样做了。更具体地说,我们有这样的东西:**

```
[P3] And he decided to join the guild... [Sum] Josh thinks about his application to the guild [T] Fantasy [Ent] Josh, the guild, Ella [Size-Large] [P1] Ella has asked Josh to join the guild long before... [P2] ... <|endoftext|>
```

> ****技术说明:**通常,在训练期间,GPT-2 将一个完整的文本文件作为输入,对其进行标记化并分成大小=块大小的块,这是小型 GPT-2 模型的最大输入大小,1024 个标记。然后,它将它们保存在 torch 数据集中的内存中,并通过数据加载器加载它们。很明显,我们在这方面必须有所不同。我们不想给 GPT-2 提供一个连续的文本,这个文本将根据它的最大输入容量被分割,而是我们上面指定的块,一次一个。因为它们很可能不会完全填满 GPT-2 的输入空间,所以我们在必要时在右边填充。当输入样本太大时,我们截断左边的 P1 和右边的 P3,以便留在 P2 周围。这并不平均,因为我们将剩余空间的 2/3 分配给 P1,1/3 分配给 P3,因为我们认为 P1 比 P3 *更重要。***

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d29cc3087284f2350243b96139164655.png)**

**我们训练一个模型,使用前一个和后一个段落(P1 和 P3)以及关于 P2 的信息,重新生成每本书的段落(称为 P2):它的大小,它所属的书的流派,它展示的实体和它的内容摘要。如前所述,我们不是从零开始训练模型,而是微调预训练的 GPT-2 模型,教导它使用上述上下文信息和已经生成的单词来预测下一个单词。这有助于我们的模型学习如何生成与提供的上下文一致的段落。因为它是在许多书籍上训练的,所以希望它能够概括并满足引言中提到的目标——作者的图像**

**这个简单的设置有两个**问题**:**

*   ***我们的变压器是色盲*🎨*!分隔符标记只能给它一个每个单词属于哪个片段的微弱的概念。我们应该添加更多关于段的信息,这意味着我们应该指定这个标记说明生成的段落的大小,以及要包含的实体。***
*   ***我们的变压器是位置盲的*👣*!*注意力是对称的点积,所以**我们应该为每个标记添加位置信息。****

****添加此信息**的一个简单方法是为*字**位置**段*构建三个并行输入序列,并将它们融合在一个序列中,将三种类型的嵌入相加:**

1.  ***单词嵌入*:单词的矢量表示,在训练中学习。**
2.  ***位置嵌入*:向量表示(固定的或学习的),包含输入的顺序性质,告诉模型单词具有时间属性。它们对单词在输入句子中的位置进行编码。**
3.  ***片段嵌入*:帮助模型区分不同输入片段的向量表示。它们标记每个令牌所属的段。在这种情况下,P1,P2,P3,主题,大小,摘要和实体。**

> **我们如何实现这一点?**

**F 首先,我们将添加**特殊令牌** 💥分隔符和段指示符([P1]、[S]、[T])。这些令牌不是我们模型预训练的一部分,所以我们需要**为它们创建**和**训练新的嵌入**。**

> **这些特殊标记方法分别将我们的特殊标记添加到标记器的词汇表中,并在模型中创建五个额外的嵌入。**

**总的来说,我们使用**GPT 2 字节对编码(BPE)标记器**【4】对传递给模型的整个输入进行标记。因此,这个长度为 n 的符号化输入具有三个不同的表示/嵌入,都是形状(1,n,768),其中 768 是小 GPT-2 的嵌入维度,我们将它们加在一起以创建单个输入嵌入。**

**我们现在已经初始化了我们的预训练模型👻并且建立了我们的培训投入,剩下的就是选择一个**损失**到**优化**🎯在微调期间。**

**为此,请注意,我们还给网络一个维度为(1,n,768)的**标签向量**,除了属于 P2 的令牌,它在任何地方都等于-100。这最终用于逐个令牌地计算仅在生成的和原始的 P2 之间的*交叉熵损失*函数。实际上,我们并不训练模型来重现全部输入,而是只训练我们感兴趣的段落 P2,如上图所示。想法是该模型利用所提供的上下文信息来学习感兴趣段落 P2 的正确重建。**

# **在新数据集上训练**

**既然我们已经描述了框架,我们需要训练我们的模型🏋🏻‍♂️.因此,让我们回到项目的关键部分:数据集。事实上,如上所述,我们需要创建一个非常具体的数据集来以这种方式调优模型。**

> **让我们强调充分数据生成阶段的一些关键方面,因为预训练的 GPT 新协议的情境化强烈依赖于它。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9852fe94906341c19c6f91e2dff1343d.png)**

**数据预处理管道-按作者分类的图像**

****小说数据**:我们使用著名的开放图书图书馆[项目古腾堡](https://www.gutenberg.org/)来训练模型。对于 Gutenberg 上现有的每本书,我们创建一个 json 文件,其中包含干净的文本内容及其相关元数据:作者、标题、主题和流派。注意,每本书的独特流派是从非结构化主题信息中手动定义的。然后,我们将每本书的正文分成不同长度的段落,有最小和最大的界限,小心不要在中间切掉一个句子,也不要将核心部分如章节分开,甚至将大段分成不均匀的片段。我们将每个段落的大小存储为一些字符,然后将用于将它们分类为*小**中**大*。**

****实体提取**:一旦每本书都按照上面的细节进行了处理,我们就使用一个预先训练好的[伯特 NER 大型模型](https://github.com/kamalkraj/BERT-NER)【5】来检测每个段落的实体。分为四类:*人员**地点**机构**其他*。用此数据训练模型使其能够生成包含已建立实体的文本。它允许作者指定他们想要合并到生成中的内容。**

****摘要**:类似地,为了让作者能够通过给出想要的内容的信息来指导生成,我们使用最先进的摘要器为每个段落导出了四个非常不同的摘要:**

*   **如果作者对他们的想法提供了一个详细或简要的总结。[6, 7]**
*   ***BertSum* ( *摘录摘要)*如果用户给出所需段落的第一句话或关键句。[8]**
*   ***KW* 如果用户提供一个非结构化的单词序列作为内容的摘要。更多详情[此处](https://medium.com/analytics-vidhya/automated-keyword-extraction-from-articles-using-nlp-bfd864f41b34)。[9]**

****使用各种汇总类型**有助于使我们的模型对作者提供这种类型信息的可能方式更加稳健。参见 r [资源](http://nlpprogress.com/english/summarization.html)了解不同类型的总结。**

**O 数据集建立后,我们**进行微调**🏋🏻来自[拥抱脸](https://huggingface.co/transformers/)的预训练 *GPT2LMHeadModel* (小-117 米)——一个顶部带有语言建模头部的 GPT-2 模型转换器,这是一个线性层,权重与输入嵌入相关联——使用他们的训练脚本的定制版本。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/257a032dbf84ae969e21545b158e3eb1.png)**

**训练期间损失函数的演变——作者图片**

**我们在 313 本预处理过的书上训练它,使用拥抱脸的所有**训练设置** ⚙️.如前所述,我们受到资源的限制,无法真正大规模地运行这个项目。使用 CUDA 在一个 *AWS 的 p 3.2x 大型实例*(包含一个 NVidia Tesla V100 GPU)上进行训练,花费约 100 美元。总的来说,该模型每个时期接收 134k 个样本,并且有 10 个时期。然而,我们使用的其他指标表明,更少的时期可能足以达到良好的性能。💯**

# **与模特交谈**

**文本生成模型的神奇之处在于你可以使用它🤗**

**为了与我们的模型进行交互,我们需要添加一个东西:一个**解码器**,它将从我们模型的下一个令牌预测中构建完整的序列。**

> ****技术说明**:与培训不同,我们不输入 P2。然而,我们需要为它的生成留出足够的空间,因为模型的输出等于模型的输入加上生成的序列。因此,输入不能超过小于 1024 个令牌的特定限制,这是我们基于置信区间确定的。如果输入太大,我们截断它,类似于在训练中所做的。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4ef4eb1a40ae7b87e71bd37b4dc718fd.png)**

**在这种模式下,在对输入进行编码之后,我们使用嵌入在 transformers 生成函数中的精心选择的解码策略来生成适当的新段落 P2。更准确地说,为了生成新单词(或令牌),该模型输出单个向量,并将其乘以所学习的嵌入矩阵。它为词汇表中的每个单词产生一个唯一的分数,这个分数最终决定了每个单词被生成的概率。参见图 4。选择最佳的解码策略和超参数是获得好的生成文本的关键步骤,因为它对作者生成图像有很大的影响**

**在过去的几个月里,解码器有了非常有趣的发展,我想在这里快速展示一下,让你了解最新情况。**

**用于语言生成的两个最常见的解码器曾经是**贪婪解码**和**波束搜索**。⚜️⚜️⚜️**

***贪婪解码(Greedy-decoding)是生成句子最简单的方法:在每个时间步,我们根据模型选择最有可能的下一个记号,直到我们到达序列结束记号。贪婪解码的一个风险是*高概率*令牌可能隐藏在*低概率*令牌之后而被错过。***

******波束搜索*** 试图通过保持我们逐字构建的几个可能序列的波束来缓解这个问题[10]。在这个过程的最后,我们从这些句子中选出最好的句子。在过去的几年里,beam-search 已经成为几乎所有语言生成任务的标准解码算法。总的来说,它会产生更流畅的输出,但经常会重复,这在故事生成中是特别不理想的。***

***除此之外,Ari Holtzman 等人[11]最近发表的研究表明,使用*波束搜索*和*贪婪解码*生成的文本中的单词分布与人类生成的文本中的单词分布非常不同。显然,*波束搜索*和*贪婪解码*无法再现人类文本的某些分布方面,因此被当前最有前途的两种方法 ***top-k*** 和 ***细胞核(或 top-p)采样*** **所取代。这两种方法的一般原理是在过滤下一个记号分布以仅保留前 k 个记号( *top-k* )或累积概率刚好高于阈值的前 k 个记号( *nucleus/top-p* )之后,从该分布中采样。***

***换句话说, **top-k sampling** 建立在采样的基础上,它简单地选择 k 个最可能的单词,并跨 k 个所选单词重新调整概率质量分布。这种方法产生了非常好的结果(拉德福德等人,2019)。它的唯一限制是,无论是窄分布还是宽分布,k 都是固定的,而我们可能希望区分这两种情况。***

***这就是为什么**核心采样**被创建为单词集的大小(也称为集合中的单词数)可以根据下一个单词的概率分布动态增加和减少。***

***注意降低**温度**🌡️使提高概率质量分布成为可能。增加它促进了多样性,更适合我们,因为我们想要创造性的输出,给作者提供想法,即使有些错误。***

***我们现在可以开始玩我们的模型了🚀***

# ***网络服务***

***对于这个项目,我们也想创新,并给出一个关于人工智能增强界面在用户体验方面看起来会是什么样子的建议。因此,我们设计了一个接口,并将其链接到后端的弹性实例。然后,我们向一小部分公众开放,以测试我们的模型。*🎬****

> ***由于资源有限,我们现在**关闭了它**——是的,它很贵。但是你仍然可以在你的本地计算机上运行并使用它。***

***![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1f963468372485a4c58dccf86388fa50.png)***

***建筑——作者的图像***

> *****技术说明**:为了在选择执行繁重计算的实例时获得灵活性,并允许在几个实例上实现负载平衡,我们将*主*实例(服务于 javascript 前端和一般数据)与计算实例(按需执行 NER 和文本生成)分离。客户端也可以在本地运行服务器,以避免延迟和服务器过载。下图给出了我们服务的总体架构。***

*****在这个界面**,🏝️ ️users 被邀请在一个简单的编辑器中写一些文本。命名的实体,如人物,地点,组织和其他被 NER 后端即时检测,并显示在左边的面板上。如果需要,用户可以很容易地手动编辑它们。***

***用户有**的可能性**来选择几个选项:所需段落的长度、他们写作的风格以及他们希望在这一代中看到的实体列表。他们还可以突出显示文本的一小部分,作为摘要(或关键字列表)。当他们准备好了,他们只需要按下*生成*按钮,让奇迹发生。***

***![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d913254da41e3e42dc8abc77ec43a2c8.png)***

***AITextGenerator 菜单指南快照—作者图片***

# ***进一步发展和结论***

***在总结中,我们展示了一个来自古登堡计划库的原始文本文件的**端到端管道**📚给写书人的网络服务。后者嵌入了一个可控的和情境化的 GPT-2,用于特定于小说的文本生成,这是根据我们在十个时代期间数百部小说的管道进行微调的🎳。总的来说,尽管计算资源有限,我们还是设法建立了一个最终模型,它能够考虑用户指定的上下文。***

***随着计算能力的不断提高和最近旨在减少模型大小而不损害生成能力的研究趋势,我们坚信这种可控的生成框架将在未来的**中很容易实现,并将大大增强作者的创造力。*****

***一些**曲目甚至更进一步**:***

*   ***在我们微调过的 GPT-2 模型的基础上增加一个 PPLM 模型,进一步引导这一代人,例如控制段落的主题和情绪。***
*   *****改变损失**来惩罚一个实体的缺席***
*   ***使用一个**大 GPT-2** 模型来提高生成文本的质量。***

***W 我们已经到了这篇文章的**结尾**描述了如何使用迁移学习和 OpenAI GPT2 这样的大规模语言模型,为小说作者构建一个最先进的受控和情境化的写作工具。***

***务必检查相关的**演示****代码**:***

*   ***这里的接口是*(你现在需要在本地运行它,因为我们剪切了我们的实例)****
*   ***开源代码和预训练模型在这里是。***

> ***与托马斯·拉姆森和盖尔·德·莱塞勒一起写的***

# ***参考***

***[1] *语言模型是无监督的多任务学习器,*亚历克·拉德福德等人(2019)*[https://D4 mucfpksywv . cloudfront . net/better-Language-models/Language-models . pdf](https://d4mucfpksywv.cloudfront.net/better-language-models/language-models.pdf)****

****[2] *关注是你所需要的一切,*作者 A 瓦斯瓦尼等人(2017)[https://arxiv.org/pdf/1706.03762.pdf](https://arxiv.org/pdf/1706.03762.pdf)****

****[3] *防御神经性假新闻,*罗文·泽勒斯、阿里·霍尔茨曼等人(2019)[https://grover.allenai.org/](https://grover.allenai.org/)****

****[4] *具有子词单元的罕见词的神经机器翻译,*作者森里奇(Sennrich,r .),哈道(Haddow,b .),&伯奇(Birch,a .)(2015)[https://arxiv.org/pdf/1508.07909.pdf](https://arxiv.org/pdf/1508.07909.pdf)****

****[5] *伯特:语言理解的深度双向变压器预训练,*作者雅各布·德夫林等人 2018[https://arxiv.org/abs/1810.04805](https://arxiv.org/abs/1810.04805)****

****[6] *Bart:自然语言生成、翻译和理解的去噪序列间预训练,*https://arxiv.org/abs/1910.13461 迈克·刘易斯等 2019****

****[7] *用统一的文本到文本转换器探索迁移学习的极限*科林·拉弗尔等人 2019 年【https://arxiv.org/abs/1910.10683 ****

****[8] *微调伯特进行提炼总结*作者刘洋。2019.[https://arxiv.org/abs/1903.10318](https://arxiv.org/abs/1903.10318)****

****[9] *Textrank:将秩序带入文本*作者拉达·米哈尔恰和保罗·塔劳。2004.[https://www.aclweb.org/anthology/W04-3252/](https://www.aclweb.org/anthology/W04-3252/)****

****[10] *神经对话建模中搜索和评估策略的重要性*,伊利亚·库利科夫等人 2019。[https://arxiv.org/abs/1811.00907](https://arxiv.org/abs/1811.00907)****

****【11】*阿里·霍尔茨曼、简·布伊斯、麦斯威尔·福布斯、叶筋·崔([https://arxiv.org/abs/1904.09751](https://arxiv.org/abs/1904.09751))撰写的《神经文本退化的奇特案例》*****

# 如何推动有效人工智能/人工智能的实验文化

> 原文:<https://towardsdatascience.com/how-to-build-a-culture-of-experimentation-for-effective-ai-ml-de843752dae9?source=collection_archive---------57----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4c3efe0a6c6b75c19ef72a3faa7fa5c2.png)

实验产生持续的改进(图片来自 [Adobe](https://stock.adobe.com/) 的 [VectorMine](https://stock.adobe.com/contributor/201457013/vectormine?load_type=author&prev_url=detail)

据[哈佛商业评论](https://hbr.org/2020/03/productive-innovation)报道,许多创新公司的一个众所周知的秘密是他们能够每天使用数据科学进行成千上万次实验,以了解他们客户的需求。仅举几个例子,Expedia,Spotify,Bookings.com,扩大了他们的数据科学管道,进行将影响他们底线的测试。然而,仅仅建立一个数据科学管道是不够的;你需要将实验文化融入其中才能成功。

实验文化的瓶颈

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f4254337da0b6839291f21af5e1d47b1.png)

为什么实验这么难?(图片由 [Adobe](https://stock.adobe.com/) 的 [VectorMine](https://stock.adobe.com/contributor/201457013/vectormine?load_type=author&prev_url=detail) 提供)

在大型组织中,大量的工作流、应用程序和数据平台可能会垄断您的所有开发资源。简单的修补-修补-发布项目不会产生长期收入。在不稳定的整合工作基础上构建数据科学管道可能会对数据治理造成严重破坏。当将数据从管道的一部分移动到另一部分时,延迟甚至会阻碍最好的数据科学成果。

即使在拥有高效团队的组织中,数据科学的努力也取得了回报,但在运营系统和分析系统之间往往存在隔阂。例如,设想一家保险公司,其中一个小组开发和维护核保应用程序,另一个小组开发模型来确定客户在保单应用程序上是否诚实。运营和分析工作负载的分离只是传统文化的一个例子,它阻止了新的实验文化在整个组织中蔓延。

数据科学团队经常无意中在独立于组织内所有其他团队的专用孤岛中工作。应用程序开发人员和业务部门专家没有在项目中与基层的数据科学团队合作。相反,他们只有在需要彼此的东西(通常是数据)时才会一起工作。最终结果是,当数据科学家获得实时数据时,这些数据往往已经过时。通过多层计算,数据经常在混乱中丢失。

**数据科学民主化**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/32bb69dff03a7c6a9a3edb283bf5aaab.png)

打破数据科学孤岛(图片来自 [Adobe](https://stock.adobe.com/) 的 [VectorMine](https://stock.adobe.com/contributor/201457013/vectormine?load_type=author&prev_url=detail)

公司真正收获创新时代回报的唯一方式是发展一种实验文化,从组织内的数据工程和数据科学团队民主化开始。数据科学必须集成到业务部门专家和应用程序开发团队的工作中,数据科学项目应该从一开始就优先考虑扩大规模。应用程序开发人员、数据科学家、数据工程师和业务部门专家应该在数据科学管道中协同工作,以确保持续改进业务成果。如果数据不能自由共享,并且数据科学家在应用程序的生命周期中没有积极参与,数据管道就会受到损害。

数据科学民主化可以解决三个问题:

1)整合数据源以消除延迟,并采取更准确的业务行动

2)创造值得信赖的数据科学,通过持续创新对底线产生积极影响

3)维护数据血统以改善 AI/ML 的共享治理。

我们相信一个集成的数据库和机器学习平台是在整个组织内实现数据科学民主化所必需的。借助这一新框架,数据科学家、业务部门专家、操作员和应用程序开发人员从数据科学研究的一开始就协同工作,并持续协作。

*   应用程序开发人员可以利用更多数据并提供实时分析,而无需 ETL。
*   数据工程师可以轻松地为数据科学家提供实时特征管道。
*   数据科学家可以自由试验,以优化预测准确性,从而带来更好的业务成果。

每个人都可以访问与生产同步的数据。对算法如何处理实时数据没有限制,也没有在机器之间来回传输数据集。通过与应用程序开发人员合作,数据科学家可以实现治理和部署,以确保数据和算法的完整性。

应用程序开发人员拥有生产基础架构的很大一部分,并成为与其支持的业务部门相关的数据科学项目的真正利益相关者。他们的角色越来越成为治理者。随着时间的推移,随着应用程序开发人员扩大其数据科学知识,他们可以使用一组透明的测试和流程来监控和治理模型。

独立运行的团队,如 DevOps、DBOps 和 MLOps,也可以聚合在实验和治理的保护伞下。应用程序开发人员可以与基础设施团队紧密合作,消除沟通障碍,实现更顺畅的部署、监控和生产管理。

**利用精选数据—特征商店**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/39ac72b5aaca3598be07e76b75efd767.png)

重复使用费力的数据管理,无需重复劳动(图片由来自 [Adobe](https://stock.adobe.com/) 的 [VectorMine](https://stock.adobe.com/contributor/201457013/vectormine?load_type=author&prev_url=detail) 提供)

一个释放实验文化的新创新是采用特色商店。正如在之前的[博客](https://medium.com/swlh/5-minimum-requirements-of-an-operational-feature-store-ab1436ca1a2c?source=friends_link&sk=11eb65fa5d460cd663040d69c451fe52)中所总结的那样,功能库使数据科学家能够共享从原始数据转换而来的精选数据。人们常说,数据科学家 80%的时间花在特性工程上,只有 20%的时间花在模型实验上。要素存储使数据科学家能够重复使用数据工程师和数据科学家执行的繁重任务,以创建提供预测信号的要素。最佳要素存储使要素能够通过复杂的分析管道基于事件进行更新,从而创建强大的预测模型。它还使数据科学家能够创建从模型实验到特征实验的明确谱系。

有了聚合 SQL 数据平台上的功能存储,数据科学家可以在过去所需时间的一小部分内运行数百或数千次测试。通过与业务单位专家的紧密合作,以及与 it 组织的合作,测试可以在许多模型上连续地、跨功能地运行。例如,销售模型可以通过测试消费者群体的总体消费行为来优化。类似地,为了实现企业内的最佳财务目标,测试风险或欺诈模型可能是必要的,但同时测试消费者情绪的变化也可能是必要的。当使用特征库时,所有这些组都能够重用特征,使得实验更有效率。在这个框架中,数据科学家更接近管理层,使用最新的创新技术来分析数据,这些数据用于支持组织级别的“宏观”决策。如果没有功能存储,数据科学家必须花费宝贵的时间和资源来集成计算元素和处理数据。

实验文化最终允许你的组织从一个 ***使用*** 技术的组织转变为一个 ***通过技术授权*** 的组织。它成为进一步创新的基石,尤其是在需要企业人工智能的时候。

**遍布整个企业—易于供应、管理和操作**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f4277eb3c5d3f0fced3b1e3c47f0524f.png)

在任何地方创建实验沙盒(图片由来自 Adobe 的 VectorMine 提供)

创建实验文化的最大挑战之一是计算资源的无摩擦供应和管理。但现在有了 Kubernetes,可以轻松地调配和编排自我修复的计算和存储资源,根据工作负载的需求扩展和缩小平台,甚至在不使用时暂停平台。例如,我们的新拼接机 Kubernetes [Ops Center](https://splicemachine.com/product/ops-center/) ,这是一套 Kubernetes 操作员和掌舵图表,一个小型 DevOps 团队可以供应、管理和操作许多不同的 SQL 和 ML 平台,每个平台甚至支持数百个小型到大型分布式 SQL 数据库。借助 OpCenter,运营商可以轻松搜索日志和监控指标,以保持平台健康。团队可以快速高效地在整个企业以及开发、测试和生产集群中构建沙盒。这消除了创造实验环境的摩擦。

**结论**

大多数组织仍然停留在专家孤岛的思维模式中。应用程序开发人员、数据工程师和数据科学家都需要计算资源,如今他们在他们之间移动数据并执行重复的工作。如果这些孤岛能够在预集成和优化的基础架构上共享数据以消除延迟,会怎么样?如果团队可以重用彼此策划的特性和模型来消除不必要的重复工作,会怎么样?如果每个团队都可以利用真正敏捷的计算资源,会怎么样?你可以打破这些壁垒,将人工智能/人工智能有效地注入到流程中,真正将现有的基础设施升级为智能平台。通过这一过程,您正在构建一个融合了实验文化的数据科学管道。这种文化不仅能让您的数据科学项目获得回报,还能不断让您的组织更快地创新,适应业务环境的变化,并根据预测将要发生的事情而不是对已经发生的事情做出反应来采取行动。

要观看 Kubernetes 架构数据和 ML 平台如何通过功能商店形成实验文化的基础的演示,请点击[此处](https://info.splicemachine.com/machine-learning-feature-store-webinar-recording.html)。

# 如何使用 TensorFlow 对象检测 API 构建和部署自定义对象检测器和分类器?

> 原文:<https://towardsdatascience.com/how-to-build-a-custom-object-detector-classifier-using-tensorflow-object-detection-api-811b7bcd31c4?source=collection_archive---------16----------------------->

## 了解如何构建交通灯检测器和分类器,用于对真正的自动驾驶汽车进行编程。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/edeaf77c1138eee55e54a41ec16249ca.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5a1924bfe14eebc346b74bff95dde07a.png)

交通灯分类器:现场(左)和模拟器(右)

# 动机:

使用 [TensorFlow 对象检测 API](https://github.com/tensorflow/models/tree/master/research/object_detection) 实现一个交通灯分类器——这可以用于使用边界框检测图像和/或视频中的对象,使用一些可用的预训练模型或通过您可以自己训练的模型。

# 应用:

编程一辆真正的自动驾驶汽车。解决自主车辆视觉和感知问题的尝试。

# 代码和实现:

请在我的 [**GitHub 库**](https://github.com/SandeepAswathnarayana/traffic-light-classifier_faster-r-cnn) 中找到与这篇博文相关的所有必要文件、代码、模块和结果。

这个交通灯分类器是 Udacity 的自动驾驶汽车工程师 Nanodegree 的关键部分。我带领一个 4 人团队(合作的有 w/ [阿伦·萨加尔](https://medium.com/u/c1d76c218ce6?source=post_page-----811b7bcd31c4--------------------------------)、[马里斯·p·拉纳维拉](https://www.linkedin.com/in/prasanga-ranaweera/)和李爽),每个成员都有着不同的背景和经验,来编写一辆真正的自动驾驶汽车。请在 [**GitHub**](https://github.com/SandeepAswathnarayana/Udacity-SDCND-Programming-a-Real-Self-Driving-Car) 上找到这个项目资源库。

# 为什么选择 TensorFlow 物体检测 API?

TensorFlow 的对象检测 API 是一个强大的工具,可以轻松构建、训练和部署对象检测模型。在大多数情况下,从头开始训练整个卷积网络非常耗时,并且需要大型数据集。这个问题可以通过使用 TensorFlow API 的预训练模型利用迁移学习的优势来解决。

# 构建分类器:

安装入门:找到 [TensorFlow 对象检测 API 库](https://github.com/tensorflow/models/tree/master/research/object_detection)上的说明,转到路径:`tensorflow/models/object_detection/g3doc/installation.md`。

*   克隆或下载 [TensorFlow 模型](https://github.com/tensorflow/models)库。在终端/cmd.exe 中导航到该目录
*   转到`[https://github.com/protocolbuffers/protobuf/releases/tag/v3.4.0](https://github.com/protocolbuffers/protobuf/releases/tag/v3.4.0)`并下载 protocol-3 . 4 . 0-win32 . zip(根据您的操作系统和要求选择合适的版本)
*   从上面的连续步骤中提取两个下载的文件。现在,在`models`(或`models-master`)目录中,您可以使用`protoc`命令:

**在 Windows 上:**

```
"C:/Program Files/protoc/bin/protoc"object_detection/protos/*.proto --python_out=.
```

**在 Ubuntu 上:**

```
protoc object_detection/protos/*.proto --python_out=.export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
```

*   运行朱庇特笔记本`[object_detection_tutorial.ipynb](https://github.com/tensorflow/models/blob/master/research/object_detection/colab_tutorials/object_detection_tutorial.ipynb)`。这会为您下载一个预先训练好的模型。这里的预训练模型是 COCO(上下文中的公共对象)。在笔记本上,注释掉`get_ipython().magic('matplotlib inline')`行。
*   接下来,使用`import cv2`引入 Python Open CV 包装器
*   实际的检测过程发生在“for”循环中(在最后一个单元格中),我们需要根据我们的需要相应地修改它。当然,我们还可以做更多的代码清理工作,比如去掉 Matplotlib 导入,如果你愿意,可以随意清理。
*   加载您的自定义图像:在 jupyter 笔记本中,进行必要的导入以从目录中加载您的图像,修改笔记本以满足您的需要,然后运行它。

# 如何使用 TensorFlow 对象检测 API 建立红绿灯检测模型?

将您感兴趣的对象添加到预训练的模型中,或者使用该模型的权重来给自己一个训练这些新对象的良好开端。Tensorflow 对象检测 API 基本上是准确性和速度之间的折衷。考虑到我正在处理的数据集,我选择使用`*faster_rcnn_inception_v2_coco*`。请查看 [TensorFlow 检测模型动物园](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md)下可用模型的完整列表。

步骤:

1.  收集大约 500 张(或者更多,如果你愿意)自定义交通灯图像。对于这个项目,我选择的图片来自——Udacity 模拟器、uda city 的卡拉测试网站和网络
2.  使用“labelImg”注释自定义图像
3.  将它们分成训练测试集
4.  为列车测试分割生成 TFRecord
5.  设置配置文件
6.  训练实际模型
7.  从新训练的模型中导出图表
8.  引入冻结推理图对交通灯进行实时分类

# 步骤 1:收集自定义交通灯图像

*   模拟器:在相机打开的情况下运行模拟器,并按照指示从模拟器中收集交通灯图像

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b08bb263513bed608d132b29310b4f4c.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3494bef4accafe650b9a3fe14921c9da.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/068e8b4c62c8094b1cd66f703047e91b.png)

从 Udacity 模拟器中收集的一些示例图像

*   站点:从 Udacity 提供的 ROS 包中下载卡拉站点的红绿灯图像

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c2757095565191e7fe8524b117df24c1.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d2149b4722e0b2964857cc18d580162c.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/07770a4e09616424b7dcbf1321728b46.png)

从 Udacity 的卡拉网站收集的一些样本图像

# 步骤 2:注释自定义交通灯图像

使用[‘label img’](https://github.com/tzutalin/labelImg)手工标记交通灯数据集图像。
步骤:

*   克隆 [labelImg](https://github.com/tzutalin/labelImg) 库
*   遵循符合您的 python 版本要求的安装步骤。但是,对于 Ubuntu 上的 Python3:

```
sudo apt-get install pyqt5-dev-toolssudo pip3 install lxmlmake qt5py3python3 labelImg.py
```

*   运行`python labelImg.py`
*   打开保存了所有交通灯图像的目录
*   对于每个图像,在您想要检测的交通灯周围创建一个矩形框,并相应地添加标签(在我们的例子中是红色、绿色、黄色)
*   将它们保存在您选择的目录中。按照以下步骤定制所有图像的标签

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/06aeede8794158d10e363d63ed611390.png)

“labelImg GUI ”,其中示例交通灯被标注为“红色”

# 步骤 3:训练-测试分割

进行 90-10 分割:将带注释的图像及其匹配的 XML 注释文件添加到两个独立的文件夹中,分别命名为“train”(90%的图像)和“test”(10%的图像)。

# 步骤 4:为训练测试分割生成 TFRecords

我们需要一些来自 GitHub 的 Dat Tran 的[浣熊数据集](https://github.com/datitran/raccoon_dataset)仓库的帮助器代码。我们只需要从这个回购 2 脚本:`xml_to_csv.py`和`generate_tfrecord.py`。

**(1) xml_to_csv.py** :

*   对该文件的 main 函数进行必要的修改。这将遍历训练和测试,以创建那些单独的 CSV,然后从这些 CSV 中,我们创建 TFRecord

在`xml_to_csv.py`脚本中,我替换了:

```
def main():
    image_path = os.path.join(os.getcwd(), 'annotations')
    xml_df = xml_to_csv(image_path)
    xml_df.to_csv('raccoon_labels.csv', index=None)
    print('Successfully converted xml to csv.')
```

使用:

```
def main():
    for directory in ['train','test']:
        image_path = os.path.join(os.getcwd(), 'images/{}'.format(directory))
        xml_df = xml_to_csv(image_path)
        xml_df.to_csv('data/{}_labels.csv'.format(directory), index=None)
        print('Successfully converted xml to csv.')
```

*   运行`python3 xml_to_csv.py`命令。现在,您已经准备好了 CSV 文件:`train_labels.csv`和`test_labels.csv`

**(2)generate _ TF record . py**:

*   接下来,我们需要抓取 TFRecord:转到`[datitran/raccoon_dataset/blob/master/generate_tfrecord.py](https://github.com/datitran/raccoon_dataset/blob/master/generate_tfrecord.py)`
*   这里您需要做的唯一修改是在`class_text_to_int`函数中。您需要将此更改为您的特定类。在这种情况下,在 if-elif-else 语句中为红色、绿色和黄色各添加三个“row_label”值

```
# TO-DO replace this with label map
def class_text_to_int(row_label):
    if row_label == 'Red':
        return 1
    elif row_label == 'Yellow':
        return 2
    elif row_label == 'Green':
        return 3
    else:
        None
```

记得使用相同的 id 值

```
%%writefile training/labelmap.pbtxt
item {
  id: 1
  name: 'Red'
}
item {
  id: 2
  name: 'Yellow'
}
item {
  id: 3
  name: 'Green'
}
```

*   确保已经安装了 Object Detection(GitHub 上的 installation.md)。运行`generate_tfrecord.py`的“使用”部分中的两个命令,分别用于训练和测试。

对于列车 TFRecord:

```
python3 generate_tfrecord.py --csv_input=data/train_labels.csv --output_path=data/train.record --image_dir=images/
```

对于测试 TFRecord:

```
python3 generate_tfrecord.py --csv_input=data/test_labels.csv --output_path=data/test.record --image_dir=images/
```

现在我们已经准备好了训练和测试记录文件。我们需要 TFRecord 文件的原因是将任何会生成数据的文件(比如 PASCAL VOC 格式)转换成 TFRecord,这样我们就可以在对象检测 API 中使用它们。

# 步骤 5:设置配置文件

为了训练我们的模型,我们需要设置一个配置文件(连同 TFRecord 和一个预训练的模型)。请在 [Tensorflow 对象检测 API](https://github.com/tensorflow/models/tree/master/research/object_detection) 上找到所有相关文件、安装信息、预训练模型等。

步骤:

*   去 GitHub 上的`[https://github.com/tensorflow/models/tree/master/research/object_detection/samples/configs](https://github.com/tensorflow/models/tree/master/research/object_detection/samples/configs)`
*   从 TF 模型检测动物园下载 faster _ rcnn _ inception _ v2 _ coco 模型的配置文件(`[faster_rcnn_inception_v2_coco.config](https://github.com/tensorflow/models/blob/master/research/object_detection/samples/configs/faster_rcnn_inception_v2_coco.config)`)和检查点(. tar.gz 文件)
*   运行两个命令,分别下载配置文件和更快的 R-CNN 模型(同时提取下载的模型)。将配置文件放在`training`目录下,提取`models/object_detection`目录下的`faster_rcnn_inception_v2_coco`
*   修改配置文件以满足您的要求,包括但不限于`PATH_TO_BE_CONFIGURED`、`num_classes`、`batch_size`、`checkpoint name`、到`fine_tune_checkpoint`、`label_map_path: “training/object-detect.pbtxt”`的路径
*   添加带有红色、黄色和绿色的项目和 id 值的标签映射文件(如步骤 4 所示)

# 步骤 6:训练实际模型

*   在`models/object_detection` 中,使用 python 命令运行您的模型,同时包含保存模型的路径,配置文件的管道

```
python3 train.py --logtostderr --train_dir=training/ --pipeline_config_path=training/faster_rcnn_inception_v2_coco.config
```

*   此时,除非出现错误,否则您应该会看到模型摘要,其中包含步骤及其相应的损失值,如下所示

```
INFO:tensorflow:global step 11788: loss = 0.6717 (0.398 sec/step)
INFO:tensorflow:global step 11789: loss = 0.5310 (0.436 sec/step)
INFO:tensorflow:global step 11790: loss = 0.6614 (0.405 sec/step)
INFO:tensorflow:global step 11791: loss = 0.7758 (0.460 sec/step)
INFO:tensorflow:global step 11792: loss = 0.7164 (0.378 sec/step)
INFO:tensorflow:global step 11793: loss = 0.8096 (0.393 sec/step)
```

你的步骤从 1 开始,亏损会高很多。根据你的 GPU 和你有多少训练数据,这个过程将需要不同的时间。你希望平均损失约为 1 英镑(或更低)。

*   您可以加载 Tensorboard 来可视化这些值,包括损耗、准确度、步数和训练时间
*   现在,您已经准备好了经过训练的模型。接下来,通过检查点加载模型

**更快的 R-CNN 模型架构:**
更快的 R-CNN 最初发表于 [NIPS 2015](https://arxiv.org/abs/1506.01497) 。它的结构很复杂,因为它有几个移动的部分。

这是该模型的高级概述。这一切都始于一幅图像,我们希望从中获得:

*   边界框列表
*   分配给每个边界框的标签
*   每个标签和边界框的概率

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4834bf30ce4daab88b0a2e94534dae71.png)

[特色图片致谢](https://www.mdpi.com/2076-3417/10/1/83) : [阿塔坎·科雷兹](https://sciprofiles.com/profile/862933)和[内卡阿丁酒吧](https://sciprofiles.com/profile/358417)

由[哈维尔·雷](https://tryolabs.com/blog/authors/javier-rey/)撰写的博客很好地解释了物体检测如何在更快的 R-CNN 上工作,这可以在 [Tryolabs](https://tryolabs.com/blog/2018/01/18/faster-r-cnn-down-the-rabbit-hole-of-modern-object-detection/) 上找到。
要快速了解更快的 R-CNN 及其地区提案网络,请参考[高昊](https://medium.com/u/8b44cbadef3a?source=post_page-----811b7bcd31c4--------------------------------)在[媒体](https://medium.com/@smallfishbigsea/faster-r-cnn-explained-864d4fb7e3f8)上的博文。

*注*:

*   在尝试了包括 SSD Inception V2、更快的 R-CNN 和 Nvidia 的卷积神经网络在内的不同模型后,我们最终决定使用更快的 R-CNN,因为我们发现它的性能对于我们的交通灯数据集来说非常有吸引力。归根结底,选择合适的型号是在“准确性”和“速度”之间进行权衡,以满足您的要求。
*   请在代码为的[纸上找到对象检测的最新模型。我决定选择更快的 R-CNN,因为它的性能满足目标检测过程中“准确性”而不是“速度”的要求。此外,TensorFlow 没有通过将 SOTA 模型添加到其 TensorFlow 对象检测 API 存储库中来与它们保持同步。](https://paperswithcode.com/task/object-detection)

# 步骤 7:从新训练的模型中导出图表

*   在这一步,我们将测试我们的模型,看看它是否如我们所愿。为了做到这一点,我们需要导出推理图。在`models/object_detection`目录中,有一个脚本为我们完成了这项工作:`export_inference_graph.py`
*   转到`installation.md`([https://github . com/tensor flow/models/blob/master/research/object _ detection/g3doc/installation . MD](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/installation.md))中的“Protobuf 编译”部分,按照给出的说明导出路径。这就加载了 TensorFlow,然后制作图表并保存
*   使用 API 附带的笔记本`object_detection_tutorial.ipynb`进行物体检测

# 第八步:引入冻结推理图对交通灯进行实时分类

*   修改`export_inference_graph.py`来满足你的要求。要运行这个,您只需要传入您的检查点和您的管道配置,然后在任何您想要放置推理图的地方。例如:

```
python3 export_inference_graph.py \
    --input_type image_tensor \
    --pipeline_config_path training/faster_rcnn_inception_v2_coco.config \
    --trained_checkpoint_prefix training/model.ckpt-10856 \
    --output_directory traffic_lights_inference_graph
```

*   运行安装命令导出推理图([https://github . com/tensor flow/models/blob/master/research/object _ detection/g3doc/installation . MD](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/installation.md))。现在,您已经准备好了`frozen_inference_graph.pb`和检查点文件
*   您的检查点文件应该在`training`目录中。只要找一个步长最大的(破折号后最大的数字),那就是你要用的。接下来,确保将`pipeline_config_path`设置为您选择的任何配置文件,然后最后选择输出目录的名称,比如说`traffic_lights_inference_graph`

从`models/object_detection`运行上述命令。如果您得到一个关于没有名为“nets”的模块的错误,那么您需要重新运行:

```
# From tensorflow/models/
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
# switch back to object_detection after this and re run the above command
```

*   打开`object_detection_tutorial.ipynb`笔记本。在笔记本上进行必要的修改,包括但不限于`MODEL_NAME`、`PATH_TO_CKPT`、`PATH_TO_LABELS`、`NUM_CLASSES`、`TEST_IMAGE_PATHS`。运行笔记本以查看带有边界框的交通灯及其预测精度

**结果:**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d4e2728fde8221775582d91fa37c7a0c.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3e988bc40938fbf1ae5e277f0a02d6ca.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2f3eacde7e4a9142f5827f0b4766149d.png)

来自模拟器的图像用边界框和预测精度分类

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a0f99072c5ac42e2a28791e0dc1e651f.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b2e21dc789ebbd668a8a78e0da909d5b.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/22bc898853edf7dfcb5203a3f657f510.png)

使用边界框和预测精度分类的站点图像

**限制:**

*   鉴于这个项目的范围,除了模拟器和 CARLA 网站上的图片,我只使用了网上的一些图片。而且,这个模型还没有在一个新的未知网站上测试过。
*   该模型在独特的光照和天气条件下的表现尚不清楚,因为这里使用的大多数图像都是在典型的晴朗天气拍摄的。
*   随着该领域的不断研究,还有其他[最先进的物体检测模型](https://paperswithcode.com/task/object-detection)可能具有相对更好的性能精度。

**致谢:**

感谢巴斯蒂安·特龙和大卫·斯塔文斯(创始人, [Udacity](https://medium.com/u/2929690a28fb?source=post_page-----811b7bcd31c4--------------------------------) )、[大卫·西尔弗](https://medium.com/u/8190c86ea791?source=post_page-----811b7bcd31c4--------------------------------)、[瑞安·基南](https://medium.com/u/a878b47f7040?source=post_page-----811b7bcd31c4--------------------------------)、[塞尚·卡马乔](https://medium.com/u/14fba6c89ce?source=post_page-----811b7bcd31c4--------------------------------)对课程材料和指导的帮助,以及官方合作伙伴的演讲嘉宾,包括[英伟达 AI](https://medium.com/u/ab69c39a85e1?source=post_page-----811b7bcd31c4--------------------------------) 、 [UberATG](https://medium.com/u/4275c7808cea?source=post_page-----811b7bcd31c4--------------------------------) 、梅赛德斯-奔驰、宝马、迈凯轮、滴滴出行,他们提供的专业知识极大地帮助了研究。

如果你有任何意见想与我分享(或)对我的写作或想法提供任何相关的反馈,我会很高兴收到你的来信。请随时在[***Twitter***](http://twitter.com/ThisIsSandeepA)*[***LinkedIn***](https://www.linkedin.com/in/sandeep-a/)*上与我联系,或者在*[***GitHub***](https://github.com/SandeepAswathnarayana)*上关注我。**

# 如何使用 TPOT 构建 Dask 分布式集群进行自动管道搜索

> 原文:<https://towardsdatascience.com/how-to-build-a-dask-distributed-cluster-for-automl-pipeline-search-with-tpot-34ab6cf6bf65?source=collection_archive---------18----------------------->

## [实践教程](https://towardsdatascience.com/tagged/hands-on-tutorials)

## 这是一个深入的教程,指导您通过开源 python 库(即 Dask 和 TPOT)建立可扩展的自动化机器学习模型管道搜索所需的所有步骤。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/063877875e7bf3ba0dc6dc6f88010c62.png)

[法比奥](https://unsplash.com/@fabioha?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片

您是否曾经遇到过这样的情况:您知道自己已经尽了最大努力清理数据集,但却无法选择最佳模型?你有很多 CPU,但是它们在不同的主机上吗?那么这就是给你的指南!我们将探索 [Dask](https://dask.org/) ,特别是 Dask 的分布式[](https://distributed.dask.org/en/latest/),不仅并行化我们的 TPOT 管道搜索,而且将它们分布在不同的机器上。

# Dask 是什么?

[Dask](https://github.com/dask/dask-tutorial) 是一个开源并行计算库,可以扩展现有的 Python 生态系统。它与通用数据科学堆栈集成良好; [NumPy](https://numpy.org/) 、[熊猫](https://pandas.pydata.org/)和 [scikit-learn](https://scikit-learn.org/) 。有了 Dask,我们可以从笔记本电脑到整个集群进行大规模计算。我们将关注后者。

# Dask 分布式是什么?

**Dask.distributed** :是一个轻量级的开源 Python 分布式计算库。

架构: Dask.distributed 是一个集中管理的、分布式的、动态的任务调度器。它有三个主要过程:

1.  **dask-scheduler:***中央 dask-scheduler 进程协调分布在多台机器上的多个 dask-worker 进程的动作以及多个客户端的并发请求。*
2.  ***dask-worker:***dask-worker 分布在多台机器上,处理多个客户端的并发请求。**
3.  ****dask-client:**dask-client 是 dask.distributed 用户的主要入口点**

****设置调度程序和工人的步骤:****

**在本例中,我们将使用 [VMware ESXi](https://www.vmware.com/products/esxi-and-esx.html) 在一台主机上创建 3 台虚拟机。一个是调度程序,同时运行 [jupyter 笔记本](https://jupyter.org/),另外两个是工人。这只是一个概念验证设置。不可否认,这不是启动集群工作者的最有效的方法。尽管如此,这将提出一个更通用的流程,然后可以采用云解决方案和/或 [Dask Kubernetes](https://kubernetes.dask.org/en/latest/) 。**

**我们将从调度程序实例开始。首先点击**创建/注册虚拟机>创建新的虚拟机>然后****

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/007dc42b111e7d6697272fe08f1320d8.png)**

**您可以选择任何名称,但我建议指定一个容易识别的名称,如 cluster-master。对于这个例子,我在所有机器上都使用了 Ubuntu 20.04.1 live server 。这不是强制性的,但强烈建议*在所有机器中使用相同的分布。这些机器将用于对大型数据集进行计算。因此,*强烈建议*为每台机器分配大量 RAM,如果不可能,至少[设置交换内存](https://linuxize.com/post/how-to-add-swap-space-on-ubuntu-18-04/)。对于本例,我们将在每台机器上使用 24 Gb 的 RAM 和 8 个 vCPUs。***

> *在本教程中,我们将使用熊猫数据帧。对于特别大的数据集,我们可以使用 Dask 的[数据框架](https://docs.dask.org/en/latest/dataframe.html#dataframe)对象。达斯克。数据帧是一个大型并行数据帧,由许多较小的数据帧组成,沿着索引分割。这些 Pandas 数据帧可能存在于磁盘上,用于单台机器或集群中许多不同机器上的大内存计算。*

*这是我们虚拟机规格的快照。你可以根据你的需要改变这些。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f13deac7e878eec82f51f9cffb681ffa.png)*

*对工作机器重复该过程。我们选择相同的规格,但这不是强制性的。在每台机器上安装操作系统后,我们将通过 SSH 安装必要的软件。对于这样的小集群,我们选择 [ClusterSSH](https://github.com/duncs/clusterssh) 。ClusterSSH 是围绕 XTerm 和 SSH 等标准 Linux 工具的 Tk/Perl 包装器。我们将使用它同时向所有机器复制命令。事不宜迟,言归正传。*

*运行以下命令在本地机器上安装 ClusterSSH。在本教程中,我们将通过 SSH 从我们的个人计算机管理集群。我们将不配置集群。我们将通过在 CLI 中传递用户名和 IP 地址来连接到机器。对于更大或多个集群,建议编辑位于`~/.csshrc`的配置文件。*

```
*sudo apt-get install clusterssh
clusterssh cluster-master-name@cluster-master-ip cluster-worker1-name@cluster-worker1-ip cluster-worker2-name@cluster-worker2-ip*
```

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/95a448749db0fd169f47b47cd638467b.png)*

*在上图中,您在 CLUSTERSSH 灰色窗口中键入的任何内容都将被复制到所有机器上。您也可以在每个窗口上分别键入单独的 shell 命令。我们希望将以下命令复制到所有计算机上:*

```
*sudo apt-get update
sudo apt-get upgrade -y
wget [https://repo.anaconda.com/archive/Anaconda3-2020.07-Linux-x86_64.sh](https://repo.anaconda.com/archive/Anaconda3-2020.07-Linux-x86_64.sh)
chmod 755 Anaconda3-2020.07-Linux-x86_64.sh
bash Anaconda3-2020.07-Linux-x86_64.sh
conda init*
```

*然后我们必须重启 shell,这非常简单,我们可以通过 ClusterSSH 断开连接并重新连接。如果您将 [Anaconda3](https://www.anaconda.com/) 安装到不同的位置,只需导出路径并运行`./anaconda3/condabin/conda init`。重新连接后,运行以下命令来安装 [TPOT](https://github.com/EpistasisLab/tpot) 和 Dask 的必要先决条件。请注意,除了 [PyTorch](https://pytorch.org/) 之外,我们还为 TPOT 的额外功能安装了所有可选的依赖项。*

```
*conda install -c conda-forge tpot xgboost dask distributed dask-ml scikit-mdr skrebate -y
conda update conda
conda update --all*
```

***建立分布式集群的步骤:***

*首先,我们需要设置调度程序,这样我们可以稍后连接其余的机器。尽管所有这些机器都驻留在同一个主机中,但为了涵盖一般情况,我们不会通过 LAN 连接它们。我们开始吧!我们将使用一个名为 [screen](https://linux.die.net/man/1/screen) 的终端复用器来管理一个 ssh 会话中的多个 shells。这里有一个你需要的选项的快速备忘单:*

```
*screen -S session_name #Starts a new screen named session_name
screen -r #Resumes a screen session
screen -ls #Returns the session IDs of running screens
screen -X -S <id or name> kill #Kills the specified screen
While inside an attached screen: Ctrl+a d #Detaches the current screen*
```

*太好了!现在我们准备在屏幕中设置调度程序!单击主/调度程序虚拟机实例 SSH 窗口,并键入以下内容:*

```
*screen -S schedulerdask-scheduler*
```

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/36e394f3f1cbb82bf6fe788cb5c210b2.png)*

*您应该会看到这个输出!*

*当然,调度程序的 IP 地址会有所不同。调度程序本身位于`8786`港口,这是我们将所有工人指向的地方。`8787`端口托管 dask [仪表板](https://docs.dask.org/en/latest/diagnostics-distributed.html)。在我们连接所有的工人之后,我们将稍后回到这一点。现在,按下`Ctrl+a d`分离屏幕。现在让我们设置我们的 jupyter 笔记本:*

```
*screen -S notebookjupyter notebook --no-browser --port=8888*
```

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9f16ceb8a3a9b054c4328d21c8e43831.png)*

*保存令牌!你以后会需要它的。*

*保存令牌,分离屏幕并关闭 SSH 连接。不要关闭到其他机器的 SSH 连接。我们现在必须将主虚拟机实例中远程笔记本的端口转发到本地端口,以便我们可以从浏览器访问它。我们可以使用以下命令来实现这一点:*

```
*ssh **-**N **-**f **-**L localhost**:**8003**:**localhost**:**8888 remoteuser**@**remotehost#Forwards the port 8888 of our remote machine to port 8003 of our local machine. We can now access it in our browser at localhost:8003*
```

*在指定的端口(我们选择 8003)上转到您的本地主机,输入您保存的令牌,瞧!笔记本在远程机器上运行,而我们在本地机器上编辑它。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/311794609d231d56f63152af20cfdb62.png)*

*现在,我们可以继续设置所有工作线程来指向调度程序。这很简单。我们通过灰色的 ClusterSSH 终端创建一个屏幕,这次是在所有的 workers 中,并将它们指向主 VM 实例中的调度程序。*

```
*screen -S workerdask-worker IP-of-the-scheduler:8786 --nprocs 1 --nthreads 8*
```

*拆下屏幕,一切就绪。客户端已连接,调度程序已启动并正在运行,您还有一个仪表板来检查一切!使用 nprocs 和 nthreads 参数分别选择每个工作线程的进程数和线程数。这个选择取决于工作量。Dask 的主要撰稿人 Matthew Rocklin 建议如下:*

> *如果您主要处理数字工作负载,比如 Numpy、Pandas 和 Scikit-Learn 代码中常见的,每个进程使用几个进程和多个线程是很好的,这不受 Python 的[全局解释器锁](https://wiki.python.org/moin/GlobalInterpreterLock) (GIL)的影响。但是,如果您将大部分计算时间花在处理纯 Python 对象(如字符串或字典)上,那么您可能希望通过用更少的线程处理更多的进程来避免 GIL 问题。使用更多的进程避免了 GIL 问题,但是由于进程间的通信而增加了成本。如果您的计算需要大量的内部通信,您可能希望避免许多进程。来源:MRocklin - [StackOverflow](https://stackoverflow.com/questions/49406987/how-do-we-choose-nthreads-and-nprocs-per-worker-in-dask-distributed/49407253)*

***什么是 TPOT?***

*[TPOT](http://epistasislab.github.io/tpot/) 是一个 Python 自动机器学习(AutoML)工具,它使用遗传编程来优化机器学习管道。TPOT 构建在 scikit-learn 库之上,就像 Dask 一样,它使用现有的 Python APIs 和数据结构。这意味着对于 scikit-learn 用户来说,它的用法应该非常直观。它还可以很好地与 Dask 集成!*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/14e06224c336d01064a8433ea609f9c5.png)*

***机器学习管道示例** —来源:[文档](http://epistasislab.github.io/tpot/)*

***TPOT 快速概览:***

*TPOT 使用进化算法来寻找最佳管道。但是*什么是管道*?在机器学习项目中,你很少有理想的数据格式来创建一个性能模型。您可以执行多种转换,如[输入](https://en.wikipedia.org/wiki/Imputation_(statistics)),特征缩放和标准化或分类变量编码——其本身有多种实施方式,即一键编码或目标编码。然后你可以通过装袋、助推或堆叠模型来创造一个整体。最终的模型将使用上述部分或全部的组合。这叫做管道。TPOT 尝试了各种管道,让它们“随机变异”,就像活的有机体一样(或者病毒和染色体外 DNA,如果你想卖弄学问的话),直到它找到一个性能更好的管道。你可以在这里阅读完整的 TPOT 论文。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0e9e0cf4bd7fa4a33fa67d1d37964e72.png)*

***TPOT 管道**的一个例子——来源:[文档](http://epistasislab.github.io/tpot/)*

*最后,让我们使用我们的集群来寻找数据集的最佳管道。下面的笔记本大部分摘自文档,有一些细微的改动。*

*当 TPOT 运行时,你可以在调度器的`localhost:8787`查看仪表盘。如果您不在远程调度器中,您可以在本地机器的`IP-of-scheduler:8787`处检查它。仪表板提供了对每一代进程的洞察、对工作人员和整个集群的基本系统监控、每个工作人员的日志和调用堆栈,以及一个非常,*非常*酷的图表。以下是 dask 仪表板运行时的外观:*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/22bbc92ad763fa9964a26e1c72c8035c.png)*

*最后,我想提一下,Dask 的主要贡献者成立了一家名为 [coiled](https://coiled.io/) 的公司,为托管 Dask 集群和 python 扩展提供云和企业解决方案。他们目前处于测试阶段,并在云中提供多达 100 个免费 CPU 来演示他们的平台。*

# 如何建立一个有气流的数据管道

> 原文:<https://towardsdatascience.com/how-to-build-a-data-pipeline-with-airflow-f31473fa42cb?source=collection_archive---------24----------------------->

## 开始在 Python 中使用 Airflow 时需要知道的一些基础知识

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/435eae324e0113cd62efca84ef3ef01b.png)

图片来自 [Pixabay](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=3382863) 的 [Nico Wall](https://pixabay.com/users/VanVangelis-7215570/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=3382863)

**简介**

Airflow 是一个允许调度和监控数据管道的工具。这个工具是用 Python 编写的,它是一个开源的工作流管理平台。

Airflow 可以用来编写机器学习管道、ETL 管道,或者一般来说用来调度作业。因此,感谢气流,我们可以自动化工作流程,避免许多无聊的手动任务。

在 Apache Airflow 中,工作流中的各种任务形成了一个图表。这些任务通过依赖关系链接在一起。连接一个任务和另一个任务的箭头有一个特定的方向,没有循环,因此在气流中我们有 DAGs,意思是有向无环图。

**第一部分:如何创建 DAG 和操作符来执行任务?**

当我们想要创建 DAG 时,我们必须提供名称、描述、开始日期和间隔,如下所示。

```
from airflow import DAGfirst_dag = DAG( ‘first’, 
            description = ‘text’, 
            start_date = datetime(2020, 7, 28),
            schedule_interval = ‘@daily’)
```

操作符是 DAG 的构造块。它们定义了 DAG 将执行的实际工作。我们需要通过设置 task_id、python_callable 和 dag 来参数化操作符。

```
from airflow import DAGfrom airflow.operators.python_operator import PythonOperatordef my_func():
   print('done')first_dag = DAG(...)task = PythonOperator(
     task_id = 'first_task',
     python_callable=my_func ,
     dag=first_dag)
```

其他常见的运算符有:

```
- PostgresOperator- RedshiftToS3Operator- S3ToRedshiftOperator- BashOperator- SimpleHttpOperator- Sensor
```

计划是可选的,默认情况下,如果我们忽略计划间隔,我们的 DAG 将从开始日起每天运行一次。无论如何,在下面你可以找到设置你的时间间隔的所有选择。

```
@once →run a DAG only once time@hourly → run the DAG every hour@daily → run the DAG every day@weekly → run the DAG every week@monthly → run the DAG every month@yearly → run the DAG every year
```

**第二部分:任务依赖和气流挂钩**

在 Airflow 中,每个有向无环图都由节点(即任务)和边来表征,这些节点和边强调了任务之间的顺序和依赖性。

我们可以使用双箭头操作符“> >”来描述依赖关系。所以:

*   **a>b**表示 a 在 b 之前
*   **甲< <乙**的意思是乙先于甲

另一种方法是使用**设置 _ 下游**和**设置 _ 上游:**

*   **a.set_downstream(b)** 表示 a 在 b 之前
*   **a.set_upstream(b)** 意思是 a 在 b 之后

为了与我们的数据存储和其他外部系统(如 Redshift、Postgres 或 MySQL)进行交互,我们可以配置**气流挂钩。**下面用举例说明一下它的样子。

```
from airflow import DAGfrom airflow.hooks.postgres_hook import PostgresHookform airflow.operators.python_operator import PythonOperatordef load():
    #create  a PostgresHook option using the 'example' connection
     db_hook = PostgresHook('example')
     df = db_hook.get_pandas_df('SELECT * FROM my_table')load_task = PyhtonOperator(task_id='load',                                     python_callable=my_func_name, ...)
```

上面你可以看到我导入了一个 PostgresHook,我通过给它命名为‘example’来初始化它。

然后通过函数**db _ hook . get _ pandas _ df(' SELECT * FROM my _ table '**)我请求给我一个 pandas 数据框。因此,Airflow 开始运行 SQL 语句,最后结果被加载到 pandas 数据框中并返回给 Airflow。

然而,气流还有其他的挂钩,比如:

```
- HttpHook- MySqlHook- SlackHook
```

**第三部分:上下文和模板**

气流提供了几个特定于运行时给定 DAG 和任务的执行的上下文变量。在处理之前访问或分割数据的过程中,上下文变量非常有用。你可以在这里找到一个变量列表,可以作为夸尔格包含在内。

下面,我们有一个函数叫做 **my_func。**函数中有*args 和**kwargs(即关键字参数列表)。此外,您可以注意到,在**任务**中,**提供 _ 上下文**被设置为 True。

```
from airflow import DAG
from airflow.operators.python_operator import PythonOperatordef my_func(*args, **kwargs): 
     logging_info(f"start{kwargs['ds']}")first_dag = DAG(...)
task = PythonOperator(
     task_id = 'date',
     python_callable = my_func,
     provide_context = True,
     dag=first_dag)
```

**结论**

现在,您已经具备了构建气流管道的基础。我认为理解这些概念的最好方法是建立你的气流环境并自己尝试。

我发出一份期刊简讯。如果您想加入,请通过此链接 注册。

除了我的**简讯**,我们还可以在我的电报群 [**数据科学初学者**](https://t.me/DataScienceForBeginners) **中取得联系。**

# 如何建立能让你找到工作的数据科学投资组合

> 原文:<https://towardsdatascience.com/how-to-build-a-data-science-portfolio-that-can-get-you-a-job-9f8d113739b3?source=collection_archive---------39----------------------->

## [职业](https://towardsai.net/p/category/careers),[数据科学](https://towardsai.net/p/category/data-science)

## 如何制作一个强有力的关于你的作品集!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f2d70fcf2c0b5c3ff3c7d7c8caa3056d.png)

[安德鲁·尼尔](https://unsplash.com/@andrewtneel?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/portfolio-website?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍照

这些人日以继夜地努力工作,仍然在找工作,然后两手空空地着陆!这是寻找数据科学和机器学习领域职业的求职者最常见的问题之一。

> 如何获得数据科学工作的聘用?
> 
> 我的作品集应该在招聘人员面前展示什么?

答案很简单:“你的作品集应该展示你做了什么!”是的,听起来就是这么简单。你的作品集可以展示很多东西,实际上你应该展示那些只与你的领域相关的东西。如果我们考虑数据科学,无论是机器学习还是深度学习,有一点是共同的,那就是关于你的技术能力和非技术能力之间的化学反应。

请记住,投资组合可以是任何东西,可以是你的**简历****LinkedIn** 个人资料,也可以是你的 **Kaggle** 个人资料或你的 **GitHub** 个人资料,也可以是你正在参加的不同类型的**比赛**。任何能照亮你的东西!

## 技术能力

在这个领域,每个人都知道自己的技术能力,比如作为一名数据科学家,你需要知道什么是**机器学习**,什么是**深度学习**,你需要知道**统计****各种算法**,它们如何工作,以及它们背后的数学原理。你需要了解**数据清理**流程,以及与你在行业中必须做的工作相关的一切。你需要知道如何使用任何编程语言编程,不管是 Python、R、Julia、Java 还是 T11 等等。看你选了哪一个,学了哪一个。你需要对各种云架构有一个基本的了解,比如 AWS、GCP、IBM Cloud 等。以及如何在服务器上部署功能齐全的数据科学项目。

> 一般来说,您需要了解完整的数据科学生命周期及其在现实生活数据中的实施,并为数据科学应用程序开发端到端系统。

## 非技术能力

数据科学更多的是关于理解数据和交流你从研究和分析中所理解的东西。它是关于在世界面前贡献你的理解。总的来说,我们可以说,一个优秀的数据科学家应该善于交流结果,能够与不同类型的团队成员协作,并能够从数据中理解和推理。因此,您需要展示讲故事的艺术,这是数据科学概要文件的核心基础之一。

从数据中理解和推理更多内容、分析数据、从数据中提出更多问题并解决这些现实问题的能力是驱动数据科学行业的好奇心。

## 那么我们应该做些什么呢?

对于正在大学学习的学生或正在积极找工作的新生来说,最重要的是:

> 争取拿到一个 ***“实习”。***

实习是一个人在完成核心领域的概念学习后应该寻找的最重要的事情之一。数据科学领域的实习将为你的投资组合增加更多价值,向招聘人员展示你在该行业有一些工作经验,并且对现实世界的问题有很好的了解。

现在你已经实习过了,所以你可以加上你完成的项目和解决的问题,所有这些你都可以在简历中自豪地提及。所以这是你应该做的第一件也是最重要的事情。

## 如果我们得不到实习机会呢?

假设你是一名大学生,正在努力争取实习机会,但通过某种方式,你最终一无所获。那该怎么办呢?

或者

假设你是一名在职专业人士,你一直在某公司的不同领域工作,现在你想转向数据科学职业,但你没有在现有公司获得关于数据科学的实习或任何项目。那么在这种情况下该怎么办呢?

> 打造自己的**“项目”。**

是的,这是真的。接受你在这个世界上看到的任何问题,如果你有机会解决它,你知道你可以带来改变。正是时候!接手一个项目,并为其构建完整的端到端解决方案。相信我,一个完全由你完成的个人项目会给你的作品集增加很大的价值,有时这相当于实习。

你可以从像 Kaggle 这样的网站上收集你感兴趣的数据集,那里有大量免费的数据集。然后你就可以开始你的项目了。建立一个端到端的系统来解决您的问题,并在任何云服务上部署您的项目,如 AWS、GCP 等。请记住,您需要确保您正在进行一个完整的端到端项目,而不仅仅是从数据收集到交流结果并最终在云上部署即用型系统的一部分。

## 接下来,参加数据科学竞赛

有各种网站定期举办数据科学竞赛,如 **Kaggle** 每个月都有一些竞赛在网站上直播。HackerRank 是另一个这样的好网站,它定期举办招聘竞赛和长期挑战,在那里你可以通过应用你的技能和努力提高你的模型的准确性或诸如此类的事情来解决问题。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7ca9f5f889fccdbb5be9a3f8db8df3b9.png)

Kaggle 排名[排行榜](https://www.kaggle.com/rankings)

所以这样的网站仅限于提高机器学习模型的准确性,但你并不止步于此。从那里拿数据集,自己搭建一个完整的端到端系统。这样做,你会学到很多新东西,这对你在某个领域知识的全面增长非常有用,并能在面试中让你受益匪浅。现在,你需要考虑如何利用特定网站(如 Kaggle)的资源,并使用它来制作一个完全准备好的工作系统,可以添加到你的投资组合中。

> **注意**:即使你没有任何现实行业的工作经验,一个项目也能创造奇迹!

## 一个强大的投资组合必须做的事情

你需要在 GitHub、LinkedIn、Kaggle 等公开个人资料上多下功夫。给招聘人员留下好印象,如果简历写得好,他们肯定会对你印象深刻。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/450406cbcaef6a4ce78c01e204c6657e.png)

[pv009](https://github.com/paras009) GitHub [仓库](https://github.com/paras009/COVID-19-EDA-tutorial)

1.  **GitHub** :让你的 GitHub 个人资料来讲述你吧!每当您创建一个项目时,在您的 GitHub 帐户上共享它,并用最新的项目文件更新存储库。保留您工作的适当文档,并定期更新您的 README.md 文件,它是您项目的发言人。是的,证明你的*非技术能力*通过记录项目和解释你如何在项目中实现每个管道的完整架构,并在自述文件中漂亮地解释它,这大大提升了你的个人资料。
2.  LinkedIn 是最大的职业招聘网站之一,它可以帮你找到潜在的雇主。不断更新你的 LinkedIn 个人资料,清楚地提及你所有的经历和项目。你可以尝试联系招聘经理,如果他们喜欢你的投资组合,他们可以为你安排面试,或者你可以联系在特定公司工作的人,了解公司的工作暴露和数据科学文化。
3.  **写博客**:写至少一篇关于你的大项目实施的博客,交流它的见解、结果和工作,期望你的读者是一个门外汉,你希望他从头开始解释你项目的一切。数据科学是一个开放的社区,在这里分享你所知道的知识,并通过撰写文章的方式为社区做出贡献,可以为你的投资组合增加更多价值。这无疑会给招聘人员留下非常好的印象,因为你更愿意分享知识和研究成果。

这些东西肯定会帮助你建立一个更好更强大的投资组合。让自己与新技术保持同步,假以时日,你一定会成功的!

## 更多关于数据科学的文章,作者: [Paras Varshney](https://medium.com/@pv009) :

[](https://medium.com/@pv009/how-to-become-super-powerful-and-successful-cdf65722a765) [## 如何变得超级强大成功?

### 释放你内心的超能力!

medium.com](https://medium.com/@pv009/how-to-become-super-powerful-and-successful-cdf65722a765) [](https://medium.com/analytics-vidhya/the-powers-of-normal-distribution-4cbb06e4a955) [## “正态分布”的功效

### 理解钟形曲线背后的科学!

medium.com](https://medium.com/analytics-vidhya/the-powers-of-normal-distribution-4cbb06e4a955) [](https://medium.com/@pv009/q-q-plots-explained-5aa8495426c0) [## Q-Q 图解释

### 探索 Q-Q 图的力量。

medium.com](https://medium.com/@pv009/q-q-plots-explained-5aa8495426c0) 

还有更多在 [Paras Varshney](https://medium.com/u/22b31444736c?source=post_page-----9f8d113739b3--------------------------------) 的。

我希望你能从这篇文章中有所收获!

如果你喜欢它并且**与你的朋友分享**它,帮助社区变得更好更强大。在 [Linkedin](https://www.linkedin.com/in/blurred-machine/) 上与我联系。

**谢谢你!**

# 如何建立数据科学作品集网站

> 原文:<https://towardsdatascience.com/how-to-build-a-data-science-portfolio-website-335b0f253822?source=collection_archive---------6----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/dd0f84b00ad32b97543192512090107e.png)

来源: [200 度](https://pixabay.com/users/200degrees-2051452/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1624028)来自 [Pixabay](https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1624028) 。

## 展示您的作品——从零开始创建网站

你的代码在 GitHub 上,你的博客文章在 Medium 上,你的比赛结果在 Kaggle 上,你的职业简介在 LinkedIn 上。然而,在你的简历上添加四个甚至更多的链接,让潜在雇主不得不逐个查找,这是浪费时间和空间。一个月前,我决定从头开始创建一个网站——没有 WordPress 或 Squarespace 或任何其他模板——在一个地方展示我的项目和我的个人资料。我不确定从哪里或如何开始,特别是因为作为数据科学家,我们不经常使用 HTML、CSS、JavaScript 或 Flask。所以我想给**提供一个指南,希望也能帮助你创建自己的数据科学组合网站**。

# 从哪里开始

在你开始编码之前,你应该有一个大致的结构,并且对你的网站应该是什么样子有一个想法。考虑你的受众:潜在雇主可能有兴趣了解你和你的数据科学职业的哪些方面?我发现有用的一点是看看其他人的投资组合网站。显然,你想确保没有他们的允许你不会复制他们。但是看看他们如何展示他们的工作和他们自己可以给你一个想法从哪里开始。一些伟大的网站是由

*   大卫·文丘里
*   [哈里森·詹斯马](https://harrisonjansma.com/)
*   布兰登·沃克

你也可以看看[我的网站](https://julianikulski.com)寻找灵感(*编辑:我给网站增加了双语功能,所以现在除了德语*还有英语。

# 包括什么

根据上面的研究,一个好的开始是在你的网站上包括以下页面/部分:

*   一个**登陆页面**,上面有一些关于你的简要信息和你网站其他部分的参考。
*   一个**投资组合页面**,提供你的项目的概述。给你的代码、博客文章和网站添加简短的描述和链接。
*   一个**关于页面**,在这里你可以谈论你的资历、教育背景、技能或者任何你想让你的观众了解你的事情。
*   例如,**博客区/页面**,包含你网站上的博客文章或者链接到你的媒体简介。
*   关于联系方式和您在线状态的**部分**。在你的 GitHub、LinkedIn、Kaggle、Twitter 或任何其他可能与你网站的受众相关的在线个人资料中添加链接。

你还记得其他章节或页面吗?太好了!包括他们。这只是一个起点,只有最少的信息。你也可以使用你的网站来托管你的实际项目,无论是[机器学习模型](/deploying-a-deep-learning-model-on-heroku-using-flask-and-python-769431335f66)还是 [Plotly Dash](/how-to-create-your-first-web-app-using-python-plotly-dash-and-google-sheets-api-7a2fe3f5d256) 实现。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f6bee008584bed88b99e9853b444c0d4.png)

来源:[咖啡豆](https://pixabay.com/users/coffeebeanworks-558718/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=2017980)来自 [Pixabay](https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=2017980) 。

# 如何构建它

## 需要考虑的事项

你想从头开始。这是否意味着一个空白的 HTML 文件,空白的 CSS 文件和空白的 Python 文件?其实不需要从 0 开始。

*   [**Bootstrap**](https://getbootstrap.com/) 是一个集成了 JavaScript 的 CSS 框架,让你的网站反应灵敏、美观,无需太多手工 CSS 工作。您可以使用这个 [Bootstrap](https://getbootstrap.com/docs/4.4/getting-started/introduction/) starter 模板,并向其中添加您自己的 HTML 代码。
*   使用[**Jinja**](https://jinja.palletsprojects.com/en/2.11.x/)——一种模板语言——它允许你动态地向你的 HTML 文件添加内容(而不是硬编码)并创建你的其他页面可以引用的模板(在下一个要点中有更多内容)。关于 Jinja 是什么以及我们为什么需要它,有一个很好的 5 分钟总结。
*   使用一个**layout.html 文件**,它在你的其他 HTML 页面中被引用。这将是您的父模板。在你的其他 HTML 文件(子模板)中,你可以[引用 layout.html](https://jinja.palletsprojects.com/en/2.11.x/templates/),比如你的导航条会显示在每一页上,但是你只需要实现一次。
*   看看你喜欢的网站的**源代码(关于如何做这件事的指导,检查一下 [Chrome](https://www.lifewire.com/view-html-source-in-chrome-3466725) 、 [Firefox](https://developer.mozilla.org/en-US/docs/Tools/View_source) 和 [Safari](https://www.lifewire.com/view-html-source-in-safari-3469315) )。记住,没有网站创建者的许可,不要复制任何东西,但看看其他人是如何实现某些东西并从中获得灵感是没问题的。**
*   使用一个**微型 web 框架**来帮你完成服务器通信的重担。我更喜欢 Flask,因为它易于实现,有丰富的文档和强大的社区,但是你也可以使用你选择的另一个 Python 框架。

请随意查看我的网站的[代码,以了解如何实现上述要点。](https://github.com/julianikulski/portfolio-website)

## 起始文件

为了给您一个实际的起点,您可以创建以下文件,然后在此基础上进行构建:

*   **layout.html**→这包含了引导启动模板、导航栏和页面页脚。所有这些都摘自[引导文档](https://getbootstrap.com/docs/4.1/components/navbar/)。

*   **index.html**→这是你的登陆页面,扩展了 layout.html 模板。

*   **styles.css** →在这里你可以添加额外的 css 样式来调整你正在使用的引导内容或者创建你自己的样式。

*   **app.py** →你需要[用 pip](https://flask.palletsprojects.com/en/1.1.x/installation/) 安装烧瓶,这个代码才能工作。这个文件将呈现你的 html 模板。

## 测试它

确保您的*网站项目有一个本地文件夹。在里面,创建一个文件夹*模板*来包含 layout.html 和 index.html 的文件。为 styles.css 文件创建另一个文件夹 *static* 。app.py 文件需要直接在*项目文件夹*中。在你的 shell 中(我用的是 Git Bash),移动到网站项目文件夹,输入`flask run`。这将输出一个 http 地址,您可以在浏览器中输入,它将显示您的基本网站。从那里,你可以添加内容,功能,调整设计和布局;它应该让你开始。基于上面的代码,它看起来应该是这样的:*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8d2c79deaaabad902fb48f8df03c2416.png)

上述代码片段的第一个实现。资料来源:朱莉娅·尼库尔斯基。

# 如何部署它

当您对您的网站满意时,您可以部署它并使其可在线访问。请遵循以下步骤:

*   **选择一个平台来托管你的网站**。我在所有的项目中使用 Heroku,因为它们可以从 GitHub repos 中方便地部署。你可以免费主持你的前 5 个项目。然而,需要考虑的是,30 分钟没有流量之后,他们会让你的网站进入睡眠状态。如果有人访问您的网站,它会在短暂的延迟后再次唤醒。为了避免这段睡眠期,你可以升级到 Heroku 的爱好计划,或者使用一种变通方法,定期 ping 你的网站来保持清醒。
*   **创建一个** `**requirements.txt**` **文件。如果你已经为你的项目创建了一个虚拟环境,你可以运行`$ pip freeze > requirements.txt`,或者你可以使用`[pipreqs](https://pypi.org/project/pipreqs/)`来获得托管平台需要为你的网站正常运行安装的软件包列表。**
*   **创造出** `**Procfile**` **。**这个文件应该只包含`web: gunicorn app:app`。注意,您需要安装`[gunicorn](https://docs.gunicorn.org/en/stable/install.html)`包,它也应该包含在您上面的`requirements.txt`文件中。
*   **创建一个** [**Heroku 账号**](https://signup.heroku.com/) **并部署你的网站。**你需要在 GitHub repo 中有上面提到的所有文件。关于 Heroku 上部署过程的更多细节,查看他们的文档[这里](https://devcenter.heroku.com/articles/github-integration)和[这里](https://devcenter.heroku.com/articles/git)。我也在[这篇中帖](https://medium.com/@julia.nikulski/building-a-job-listings-web-scraper-that-sends-out-丨t丨e丨l丨e丨g丨r丨a丨m丨s丨-notifications-830763890a92)中描述了这个过程(文章末尾的第 5 点)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/71f170c305376896cc12ef6f528982b8.png)

来源: [200 度](https://pixabay.com/users/200degrees-2051452/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1606951)来自 [Pixabay](https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1606951) 。

# 如何改善呢

一旦你创建了你的 MVP,考虑一下你可以添加什么功能来传达额外的信息或者使你的网站更加用户友好。

*   为什么不加一个 [**时间线**](https://www.w3schools.com/howto/howto_css_timeline.asp) 展示你的学习历程呢?
*   添加一个[**技能部分**](https://www.w3schools.com/howto/howto_css_skill_bar.asp) 显示你的专业领域。
*   创建一个**内容管理系统**,这样你就不必在 HTML 模板或 Python 文件中添加你的网站上显示的所有内容/文本。我在 Heroku 上创建了一个 [PostgreSQL 数据库](https://devcenter.heroku.com/articles/heroku-postgresql),这个数据库是由[输入我的内容的 Excel 文件](https://github.com/julianikulski/portfolio-website/blob/master/database_feeder.py)。

我希望这个指南对你有用。它应该可以帮助你开始建立自己的网站,这在一开始可能看起来有点吓人。我不是 web 开发人员,但我的重点是数据科学,所以我欢迎对上述指南的任何反馈!

你想在媒体上阅读更多高质量的故事吗?考虑注册一个支持我和其他媒体作者的会员。

[](https://medium.com/@julia.nikulski/membership) [## 通过我的推荐链接加入 Medium-Julia Nikulski

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

medium.com](https://medium.com/@julia.nikulski/membership) 

如果您正在寻找一个新的项目创意来添加到您的投资组合中,请查看**我的指南,了解如何开发新的独特的数据科学项目创意。**

[](/5-steps-to-develop-unique-data-science-project-ideas-6c2b3a0014b) [## 开发独特数据科学项目创意的 5 个步骤

### 帮助您识别值得一试的新颖独特的数据项目的指南

towardsdatascience.com](/5-steps-to-develop-unique-data-science-project-ideas-6c2b3a0014b)

# 如何用 Python 构建数据科学 Web 应用程序

> 原文:<https://towardsdatascience.com/how-to-build-a-data-science-web-app-in-python-61d1bed65020?source=collection_archive---------7----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/50bc8c9d987cad78f1bc2f3413d33190.png)

由 [YummyDs](https://elements.envato.com/user/YummyDs) 从 [Envato 元素](https://elements.envato.com/)使用许可图像创建

## [数据科学](https://towardsdatascience.com/tagged/data-science/)

## 第 1 部分:您的第一个 Web 应用程序,只有几行代码

在本文中,我将向您展示如何使用 streamlit Python 库,只用几行代码,快速构建一个简单的数据驱动的 web 应用程序。

作为一名数据科学家或机器学习工程师,能够部署我们的数据科学项目非常重要。使用 Django 或 Flask 等已建立框架的机器学习模型的传统部署可能是一项艰巨和/或耗时的任务。

这篇文章基于我在 YouTube 上制作的同一主题的视频(T21,如何用 Python 构建你的第一个数据科学 Web 应用,你可以边看边读这篇文章)。

# 我们正在构建的股票 web 应用程序概述

今天,我们将构建一个简单的 web 应用程序来显示股票价格和交易量。这将需要使用两个 Python 库,即`streamlit`和`yfinance`。从概念上讲,该应用程序将从雅虎检索历史市场数据。来自`yfinance`图书馆的资金。该数据被保存到一个数据帧中,并且`streamlit`将使用该数据作为输入参数,将其显示为一个折线图。

# 安装必备库

在本教程中,我们将使用两个需要安装的 Python 库。其中包括`streamlit`和`yfinance`。您可以通过如下的`pip install`命令轻松安装`streamlit`:

```
pip install streamlit
```

对`yfinance`也进行如下操作:

```
pip install yfinance
```

# web 应用程序的代码

让我们来看看我们今天正在构建的 web 应用程序的代码。您将会看到少于 20 行的代码(**如果不计算注释,那么它将减少到 14 行代码,其中 3 行是出于美观目的的空行)。

# 对代码的逐行解释

让我们花点时间对上面的代码做一些了解。

*   ***第 1 行和第 2 行*** 导入`yfinance`并赋予其别名`yf`以及导入`streamlit`并赋予其别名`st`。
*   ***第 4–7 行***
    使用`st.write()`功能打印出文本。这些打印出来的文本是以减价的形式写的。
*   ***第 9–16 行***
    使用`yfinance`库从 Yahoo!金融。
    * *第 11 行—* 将股票代码定义为`GOOGL`。
    * *第 13 行* —使用`yf.Ticker()`函数创建`tickerData`变量,顾名思义,该函数允许访问股票行情自动收录器数据。应该注意,tickerData 是一个 *Ticker 对象*,如果我们将 tickerData 作为一个命令运行,我们会得到下面的输出`yfinance.Ticker object <GOOGL>`。
    * *第 15 行* —创建`tickerDf`数据帧并定义日期范围(从 2010 年 5 月 31 日至 2020 年 5 月 31 日)和时间段(1 天)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1ca11ae167dd2017643faa4365e364e2.png)

*   ***第 18 行和第 19 行***
    使用`st.line_chart()`函数绘制折线图(使用第 15 行定义的`tickerDf`数据框中的*收盘价*和*成交量*列)。

# 运行 web 应用程序

将代码保存到名为 myapp.py 的文件中后,启动命令提示符(或 Microsoft Windows 中的 Power Shell)并运行以下命令:

```
streamlit run myapp.py
```

接下来,我们应该会看到以下消息:

```
> streamlit run myapp.pyYou can now view your Streamlit app in your browser.Local URL: [http://localhost:8501](http://localhost:8501)
Network URL: http://10.0.0.11:8501
```

很快,一个互联网浏览器窗口将弹出,引导您进入创建的 web 应用程序,如下图所示的`[http://localhost:8501](http://localhost:8501.)`。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/72be1cbe6658e9db97dc63b7f2eeee0c.png)

股票价格 web 应用程序的屏幕截图。

# 恭喜你!您已经用 Python 创建了您的第一个 web 应用程序!

# 自定义 web 应用程序

好吧,所以你可能想加点料,定制 web 应用程序。

让我们花点时间对上面的代码做一些了解。

*   ***第 6 行*** 注意,我们加粗了*【收盘价】*,在短语前后使用了两个星号,如下:`**closing price**`。还要注意的是,我们通过在单词前后使用三个星号,使单词“volume”变成了粗体和斜体形式,如下所示:`***volume***`。
*   ***第 18–20 行和第 22–25 行*** 这里我们在*收盘价*和*成交量*图之前添加了一个降价格式的标题。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ab8682bd4969595cd8de1b0678be787b.png)

更新后的 web 应用程序的屏幕截图。

# 瞧吧!

现在,我们有了一个更新的 web 应用程序,它会在你眼前自动更新。

## 订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!

# 关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名[数据教授](http://bit.ly/dataprofessor/))制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本([数据教授 GitHub page](https://github.com/dataprofessor/) )。

[](https://www.youtube.com/dataprofessor?sub_confirmation=1) [## 数据教授

### 数据科学、机器学习、生物信息学、研究和教学是我的激情所在。数据教授 YouTube…

www.youtube.com](https://www.youtube.com/dataprofessor?sub_confirmation=1) 

## 在社交网络上与我联系

YouTube: [http://youtube.com/dataprofessor/](http://youtube.com/dataprofessor/)

[LinkedIn:](https://www.linkedin.com/company/dataprofessor/)[https://www.linkedin.com/company/dataprofessor/](https://www.linkedin.com/company/dataprofessor/)

[https://www.linkedin.com/company/dataprofessor/](https://twitter.com/thedataprof)

[【HTTP://facebook.com/dataprofessor/】](https://www.youtube.com/redirect?redir_token=w4MajL6v6Oi_kOAZNbMprRRJrvJ8MTU5MjI5NjQzN0AxNTkyMjEwMDM3&q=http%3A%2F%2Ffacebook.com%2Fdataprofessor%2F&event=video_description&v=ZZ4B0QUHuNc)
【GitHub:[【HTTPS://github.com/dataprofessor/】](https://github.com/dataprofessor/)
[Instagram:【HTTPS://www.instagram.com/data](https://www.instagram.com/data.professor/)

# 如何用 Python(企鹅分类器)构建数据科学 Web 应用

> 原文:<https://towardsdatascience.com/how-to-build-a-data-science-web-app-in-python-penguin-classifier-2f101ac389f3?source=collection_archive---------8----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/146efec7ff65de2387a258a304c54059.png)

## [数据科学](https://towardsdatascience.com/tagged/data-science/)

## 第 3 部分:ML 支持的 Web 应用程序,代码 100 多行

T 这是**第三部分**和**我将向您展示如何使用 Streamlit 库用 Python 构建一个机器学习驱动的数据科学 web 应用程序,代码只有 100 多行。**

我们今天要构建的 web 应用程序是企鹅分类器。我们正在构建的这个[企鹅分类器网络应用](http://dp-penguins.herokuapp.com/)的演示可以在[http://dp-penguins.herokuapp.com/](http://dp-penguins.herokuapp.com/)获得。

之前,在本 Streamlit 教程系列的第 1 部分 中,我已经向您展示了如何用 Python 构建您的第一个数据科学 web 应用程序,它能够从 Yahoo!财务,然后显示一个简单的折线图。在 [**第二部分**](/how-to-build-a-simple-machine-learning-web-app-in-python-68a45a0e0291) 中,我已经向你展示了如何使用 Iris 数据集构建一个机器学习 web 应用。

正如本 *Streamlit 教程系列*的前几篇文章中所解释的,模型部署是数据科学生命周期的基本和最终组成部分,有助于将数据驱动的洞察力的力量带给最终用户,无论是业务利益相关者、经理还是客户。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/50252d9e5ceae97fc7bc66e7caa91a04.png)

数据科学生命周期。由 Chanin Nantasenamat 绘制。

这篇文章基于我在[数据教授 YouTube 频道](https://www.youtube.com/dataprofessor?sub_confirmation=1) ( [如何用 Python](https://youtu.be/Eai1jaZrRDs) 构建企鹅分类 Web 应用)上制作的同一主题的视频,你可以边看边看这篇文章。

# 企鹅分类网络应用概述

在本文中,我们将构建一个*企鹅分类器* web 应用程序,作为 4 个定量变量和 2 个定性变量的函数,预测企鹅物种的分类标签是阿德利企鹅、下巴颏企鹅还是巴布亚企鹅。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/441fa709a751e94bd28089cc8b44a441.png)

艺术作品 [@allison_horst](http://twitter.com/allison_horst)

## 企鹅数据集

这个机器学习驱动的网络应用程序中使用的数据被称为 [*帕尔默企鹅*数据集](https://github.com/allisonhorst/palmerpenguins),它是由艾利森·霍斯特作为 R 包发布的。特别地,该数据来源于 Kristen Gorman 博士及其同事发表的题为 [*南极企鹅(Pygoscelis 属)*](https://doi.org/10.1371/journal.pone.0090081) 群落内的生态性二态性和环境可变性的工作。

数据集由 **4 个定量变量**组成:

*   票据长度(毫米)
*   票据深度(毫米)
*   脚蹼长度(毫米)
*   体重(克)

和 **2 个定性变量**:

*   性别(男性/女性)
*   岛屿(比斯科/梦幻/托格森)

让我们来看看企鹅数据集(下面显示的是一个截短的版本,只显示了 3 种企鹅中每一种的前 3 行条目):

`*(Note: The full version of the* [*Penguins dataset is available on the Data Professor GitHub*](https://github.com/dataprofessor/data/blob/master/penguins_cleaned.csv)*)*`

## 企鹅分类器 web 应用程序的组件

*企鹅分类器 web app* 由**前端**和**后端**组成:

***前端*** —这是我们加载 web app 时看到的。前端可进一步分解为**侧面板**和**主面板**。web 应用程序的截图如下所示。

**侧面板**位于左侧,标签标题为*“用户输入特性”*。在这里,用户可以上传包含输入特征(2 个定性变量和 4 个定量变量)的 CSV 文件。对于 4 个定量变量,用户可以通过调节滑动条手动输入这些输入特征的输入值。对于 2 个定性变量,用户可以通过下拉菜单选择输入值。

这些用户输入特征用作将在后端讨论的机器学习模型的输入。一旦做出预测,产生的类别标签(企鹅种类)连同预测概率值被发送回前端,以显示在**主面板**上。

***后端*** —用户输入的特征将被转换成数据帧,并发送给机器学习模型进行预测。在这里,我们将使用一个预先训练的模型,该模型之前被保存为一个名为`penguins_clf.pkl`的 pickle 对象,该对象可以由 web 应用程序快速加载(无需在用户每次加载 web 应用程序时构建机器学习模型)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a673adc8761a5501440a4392c1cb9c41.png)

企鹅分类器 web 应用程序的屏幕截图。

# 安装必备库

对于本教程,我们将使用 5 个 Python 库:`streamlit`、`pandas`、`numpy`、`scikit-learn`和`pickle`。如果您的计算机中尚未安装前 4 个库,则必须安装前 4 个库,而最后一个库是内置库。

要安装这些库,您可以通过如下的`pip install`命令轻松完成:

```
pip install streamlit
```

然后,重复上述命令,首先将`streamlit`替换为其他库的名称,如`pandas`,使其变成`pip install pandas`,依此类推。

或者,您可以使用这个一行程序一次性安装它们:

```
pip install streamlit pandas numpy scikit-learn
```

# web 应用程序的代码

现在,让我们看看 web 应用程序的内部。您将看到 web 应用程序由两个文件组成:`penguins-model-building.py`和`penguins-app.py`。

第一个文件(`penguins-model-building.py`)用于构建机器学习模型,保存为 pickle 文件,`penguins_clf.pkl`。

随后,第二个文件(`penguins-app.py`)将应用经过训练的模型(`penguins_clf.pkl`)通过使用来自 web 应用前端的侧边栏面板的输入参数来预测类别标签(企鹅的种类是阿德利企鹅、下巴颏企鹅还是巴布亚企鹅)。

# 对代码的逐行解释

## 企鹅-建模. py

让我们从第一个文件的解释开始,它本质上允许我们在运行 web 应用程序之前预先构建一个经过训练的机器学习模型。我们为什么要这么做?从长远来看,这是为了节省计算资源,因为我们最初只构建一次模型,然后应用它对 web 应用程序侧边栏面板上的用户输入参数进行不确定的预测(或至少直到我们重新训练模型)。

企鹅-建模. py

*   ***行 1***
    导入别名为`pd`的`pandas`库
*   ***第 2 行***
    从 CSV 文件中读取清理后的企鹅数据集,并将其赋给`penguins`变量
*   ***第 4-19 行***
    对目标 **Y** 变量(`species`)和 2 个 **X** 变量(`sex`和`island`)组成的 3 个定性变量进行顺序特征编码。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f8b3b9562adc862d0e665703741faca1.png)

在执行序数特征编码之前。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d87e05ded199a3b3b19e469dddb133ed.png)

执行顺序特征编码后。

*   ***第 21–23 行***
    将`df`数据帧分隔成`X`和`Y`矩阵。
*   ***第 25–28 行***
    训练一个随机森林模型
*   ***第 30–32 行***
    将训练好的随机森林模型保存到一个名为`penguins_clf.pkl`的酸洗文件中。

## 企鹅-app.py

第二个文件将服务于 web 应用程序,该应用程序将允许使用从 pickled 文件加载的机器学习模型进行预测。如上所述,web 应用程序接受来自两个来源的 inout 值:

1.  滑动条中的特征值。
2.  上传的 CSV 文件中的特征值。

企鹅-app.py

*   ***行 1–5***
    分别导入别名为`st`、`pd`和`np`的`streamlit`、`pandas`和`numpy`库。接下来,导入`pickle`库,最后从`sklearn.ensemble`导入`RandomForestClassifier()`函数。
*   ***第 7–13 行***
    编写 web 应用程序标题和介绍文本。

**侧边栏面板**

*   ***第 15 行***
    侧边栏面板的页眉标题。
*   ***第 17–19 行***
    链接下载一个示例 CSV 文件。
*   ***第 21–41 行***
    采集特征值并放入数据帧。我们将使用条件语句 if 和 else 来确定用户是否上传了 CSV 文件(如果是,则读取 CSV 文件并将其转换为 dataframe ),或者通过滑动其值也将被转换为 dataframe 的滑动条来输入特征值。
*   ***第 43–47 行***
    将用户输入特征(来自 CSV 文件或滑动条)与整个企鹅数据集相结合。这样做的原因是为了确保所有变量包含最大数量的可能值。例如,如果用户输入包含 1 只企鹅的数据,那么序数特征编码将不起作用。原因是因为代码将只检测定性变量的 1 个可能值。为了使序数特征编码起作用,每个定性变量都需要有所有可能的值。

**情况一**

在第一个场景中,定性变量`island`只有一个可能的值,即`Biscoe`。

上述输入特征在编码后将产生以下序数特征。

**情况 B**

上述输入特征将产生以下序数特征。

*   ***第 49–56 行***
    以与上述模型构建阶段(`penguins-model-building.py`)类似的方式执行序数特征编码。
*   ***第 58–65 行***
    显示用户输入特征的数据帧。条件语句将允许代码自动决定是显示 CSV 文件中的数据帧,还是显示滑动条中的数据帧。
*   ***第 67–68 行***
    从酸洗文件中加载预测模型,`penguins_clf.pkl`。
*   ***第 70–72 行***
    应用加载的模型对 df 变量进行预测,该变量对应于来自 CSV 文件或滑动条的输入。
*   ***第 74–76 行***
    预测的企鹅种类的类标签显示在这里。
*   ***第 78–79 行***
    这里显示了 3 种企鹅中每一种的预测概率值。

# 运行 web 应用程序

现在我们已经完成了 web 应用程序的编码,让我们首先启动您的命令提示符(终端窗口)并键入以下命令来启动它:

```
streamlit run penguins-app.py
```

然后,命令提示符中应该会显示以下消息:

```
> streamlit run penguins-app.pyYou can now view your Streamlit app in your browser.Local URL: http://localhost:8501
Network URL: http://10.0.0.11:8501
```

企鹅分类器 web 应用程序的屏幕截图如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5644c5b1cff11435bfc17e47575f1e3a.png)

在 Heroku 上部署企鹅分类器 web 应用程序。

# 部署和展示 web 应用程序

干得好!您现在已经创建了一个基于机器学习的 web 应用程序。让我们将 web 应用程序部署到互联网上,以便您可以与朋友和家人分享。本 *Streamlit 教程系列*的下一部分将深入介绍如何在 Heroku 上部署 web 应用程序。与此同时,请观看以下视频:

*   [如何将数据科学 Web App 部署到 Heroku](https://www.youtube.com/watch?v=zK4Ch6e1zq8)

与此同时,您可以将它纳入您的数据科学投资组合。

*   [使用 GitHub 构建您的数据科学组合](https://www.youtube.com/watch?v=fCXBaEnPzgo)
*   [如何用 Hugo & Github Pages 建立数据科学作品集网站【壮举。【数据教授】](https://www.youtube.com/watch?v=mEZ1Hj5yQ-8))。

## [订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费内容)!](http://newsletter.dataprofessor.org/)

# 关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名[数据教授](http://bit.ly/dataprofessor/))制作关于数据科学的在线视频。在我做的所有教程视频里,我也分享 GitHub 上的 Jupyter 笔记本([数据教授 GitHub page](https://github.com/dataprofessor/) )。

[](https://www.youtube.com/dataprofessor?sub_confirmation=1) [## 数据教授

### 数据科学、机器学习、生物信息学、研究和教学是我的激情所在。数据教授 YouTube…

www.youtube.com](https://www.youtube.com/dataprofessor?sub_confirmation=1) 

## 在社交网络上与我联系

YouTube: [http://youtube.com/dataprofessor/](http://youtube.com/dataprofessor/)

[LinkedIn:](https://www.linkedin.com/company/dataprofessor/)[https://www.linkedin.com/company/dataprofessor/](https://www.linkedin.com/company/dataprofessor/)

[https://www.linkedin.com/company/dataprofessor/](https://twitter.com/thedataprof)

[【HTTP://facebook.com/dataprofessor/】](https://www.youtube.com/redirect?redir_token=w4MajL6v6Oi_kOAZNbMprRRJrvJ8MTU5MjI5NjQzN0AxNTkyMjEwMDM3&q=http%3A%2F%2Ffacebook.com%2Fdataprofessor%2F&event=video_description&v=ZZ4B0QUHuNc)
【GitHub:[【HTTPS://github.com/dataprofessor/】](https://github.com/dataprofessor/)
[Instagram:【HTTPS://www.instagram.com/data](https://www.instagram.com/data.professor/)

# 如何从头开始为图像分类器构建数据集(与汽车相关)

> 原文:<https://towardsdatascience.com/how-to-build-a-dataset-for-an-image-classifier-from-scratch-d2506e30468d?source=collection_archive---------15----------------------->

## 设计一个过程来收集网络上的数据,并使其可用于图像分类项目(使用 Beautifulsoup,Selenium)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a6d51fea8dfebe2116f9d576845e387e.png)

乔纳森·加莱戈斯在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片

在这篇文章中,我将介绍我几周前构建的从网站 [Turo](https://turo.com/fr-ca) 收集数据(文本和图片)的管道,以及清理收集的数据以在图像分类器项目中使用它的过程。

**免责声明:这些数据是供我使用的(我不拥有它),所以我不会分享它。**

# 项目的概念

几周前,我开始思考在深度学习中更详细地潜水,我想围绕图像分类启动一个项目。

我在这个主题中阅读的大多数文章都使用了与 [mnist](http://yann.lecun.com/exdb/mnist/) 数据集(手写数字)、 [deepfashion](http://yann.lecun.com/exdb/mnist/) (贴有标签的衣服集合)或[狗品种分类器](https://medium.com/@paul.stancliffe/udacity-dog-breed-classifier-project-walkthrough-e03c1baf5501)相同的数据集。

这些数据集是合适的,但此时此刻我想研究一些不同的东西:

*   我同时发现了 [Turo platform](https://turo.com/) 这是一个人们可以从北美其他人那里租车的平台(它似乎运行得很好)。
*   我开始从[游乐场游戏](https://www.playground-games.com/)在 PC 上玩《极限纵横 4》。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/572a522be835f01b0fefe6cad0146cf3.png)

[https://compass-SSL . Xbox . com/assets/2c/D7/2cd 7061 a-3d3b-4319-9d 75-8ac 4628 CBC 77 . jpg?n = 8888888884 _ Gallery _ 1154 x649 _ 09 . jpg](https://compass-ssl.xbox.com/assets/2c/d7/2cd7061a-3d3b-4319-9d75-8ac4628cbc77.jpg?n=8888888884_Gallery_1154x649_09.jpg)

几周前,我发现了两个相同主题的数据集

*   [斯坦福的一张](https://ai.stanford.edu/~jkrause/cars/car_dataset.html)通过阅读[巴努耶拉](https://towardsdatascience.com/@bhanuyerra?source=post_page-----39692e445a14----------------------)的这篇[文章](/classifying-car-images-using-features-extracted-from-pre-trained-neural-networks-39692e445a14)与汽车图片相关
*   Nicolas Gervais 的 GitHub 知识库

但是我想在抓取方面增加我的游戏,所以我决定建立我的 Turo 网站的抓取器。

在一份 Turo 的报价中,我才意识到有标注了车型的图片。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5694ceb2a83337affeb0edb6b9f48a81.png)

Turo 网站

因此,为什么不使用该网站作为图像分类数据集的来源来构建汽车检测系统呢?

为了执行从网站中提取数据,我不能使用与我在 Crossfit open 上的[文章](http://the-odd-dataguy.com/crossfitopen)中的[美汤](https://www.crummy.com/software/BeautifulSoup/)相同的方法,因为:

*   URL 不是很容易填充,所以我需要自动完成我的 Turo 研究
*   要让所有广告都显示在结果页面上,需要进行一些滚动操作

我仍然可以使用 Beautiful Soup 从源页面获取数据,但是我需要将这个包与另一个名为 Selenium 的包关联起来,以自动化对 Turo 的研究。

# 包装的展示

在这一部分,我将简单介绍一下我一直在 Turo 上爬行的库。

# 美味的汤

[美汤](https://www.crummy.com/software/BeautifulSoup/)是一个从 HTML 和 XML 文件中提取数据的包*。它与您喜欢的解析器一起工作,提供导航、搜索和修改解析树的惯用方式。它通常为程序员节省数小时或数天的工作。*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a002b34a8b0ca17aa13c6e948b975f84.png)

[https://info python . files . WordPress . com/2007/03/beautiful soup . jpg](https://infopython.files.wordpress.com/2007/03/beautifulsoup.jpg)

有了这个包之后,收集网页在线的源码,你就可以分段所有的 HTML 标签,并在里面研究收集你需要的信息。在我看来,这个包是开始使用 Python 进行 web 抓取的一个很好的开端,在这个主题上有很多有用的资源。

# 硒

这个包可以看作是一个 web 浏览器自动化包。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/35adeac79baa3ba178c8df69f3299ec4.png)

[https://huddle . eurostarsoftware testing . com/WP-content/uploads/2017/02/selenium . png](https://huddle.eurostarsoftwaretesting.com/wp-content/uploads/2017/02/Selenium.png)

这个包允许 Python 脚本打开像 Firefox 这样的网络浏览器,在网页上填充字段,在网页上滚动,像人类一样点击按钮。
让我们深入了解数据管道。

# 数据管道的介绍

# 概观

在数据收集方面,我决定将我的数据收集集中在北美最重要的城市,所以我选择了:

*   美国各州的中心城镇,至少有一百万人口
*   加拿大人口最多的 15 个城市

有一张我正在搜集数据的城市面板地图。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2c69f2674c267263e392a9b06dc6a246.png)

谷歌地图

它代表了 60 个城市(蓝色的美国和红色的加拿大),就像我有多种类型的环境(山,海)和不同的天气可以诱导各种类型的车辆。

这个想法是每 6 个小时收集一次从城市列表中随机挑选的 5 个城市的新报价。接收数据的存储是这样进行的:

*   在本地,所有的图片都保存在刮板机上
*   在 [AWS](http://the-odd-dataguy.com/p/9d736496-0ed3-4a92-bd04-6e7fa03bcb41/Build%20a%20webscraper%20with%20Selenium%20and%20BeautifulSoup) 中,我使用了一个 [dynamodb](https://aws.amazon.com/dynamodb/?sc_channel=PS&sc_campaign=acquisition_CA&sc_publisher=google&sc_medium=dynamodb_hv_b&sc_content=dynamodb_e&sc_detail=dynamodb&sc_category=dynamodb&sc_segment=73324893176&sc_matchtype=e&sc_country=CA&s_kwcid=AL!4422!3!73324893176!e!!g!!dynamodb&ef_id=Cj0KCQjw9fntBRCGARIsAGjFq5GS7soTVsB8NP__REd9JX7GRF7S_zjDYZW-Swn0ik_5shVH39KzOCsaAnOOEALw_wcB:G:s) 表来存储从搜索到的报价信息(id,报价的详细信息),以便总是保存报价的可用信息

我用了大约两周的时间运行这个管道,下载了大约 164000 张图片。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7dd0473db668d54058d4b3d497ab1f43.png)

[https://media.giphy.com/media/3NtY188QaxDdC/giphy.gif](https://media.giphy.com/media/3NtY188QaxDdC/giphy.gif)

现在让我们更详细地看看用 Selenium 和 Beautiful Soup 进行数据收集的脚本。

# 收集报价

首先,为了收集这些数据,我需要有一种方法来给出一个城市,并获得当前可用的优惠。
有一个代码可以收集蒙特利尔市的报价。

我们可以看到:

*   Selenium 的用法是通过一个驱动程序的声明,该驱动程序可以控制 web 浏览器在网站上进行导航
*   使用对象驱动程序,我可以设置我的脚本来填充由 id 定义的特定字段(在本例中为“js-searchformexpandlocationinput ”),并将键发送到该特定输入(在本例中为城市字段中的位置)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d65986a187603ee66d9352e71fa6a64e.png)

turo 首页检查

*   Selenium 的另一部分是与页面上的按钮的直接交互(需要找到页面上的按钮并激活它)。

对于页面上的滚动,这有点棘手;我用[迈克尔·J·桑德斯](https://michaeljsanders.com/2017/05/12/scrapin-and-scrollin.html)的方法在“无限页”上滚动。

在每一次滚动之间,我都使用 Beautiful Soup 来收集页面上的所有报价。

有一个脚本的动画。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e4b13e1d0d45f3eb42e6e4d07def6d1a.png)

之后,我只是对以前从未见过的报价(不在我的 dynamodb 表中)进行过滤,并使用一个新的流程从一个特定的报价中收集数据。

# 收集图片

有一个为要约收集数据的脚本。

这个脚本的棘手部分是收集报价上图片的 URL。下面的屏幕截图说明了图片存储在一个转盘中。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a9737112d93332ea845fe2e9fe7bed32.png)

我使用同样的技巧,然后在首页上使用验证按钮,这样,我可以很容易地收集所有图片的 URL,并通过 GET 请求,将它们下载到我的机器上。有一个先前脚本的动画在运行。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/500db7ab6a721e9e7bfa99068ebd5d01.png)

如果你想运行脚本,我邀请你用 Github 库(在一台 Linux 机器上)上的[配置设置一个 python 环境。](https://github.com/jeanmidevacc/example_webscraper)

现在让我们看一下数据集的数据准备。

# 从 ze(原始)数据集到图像分类器的 hero 数据集

用我的刮刀,我在 Turo 网站上收集了很多(164000 左右)与他们的汽车报价相关的图片。这是一个很好的开始,但所有这些图片都是不可用的,例如,汽车的内部。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/97f90b0d612f3b789bfde740db8e68fd.png)

Turo 广告图片

有很多这样的图片,所以我需要对这个原始数据集做一些清理。

# 清洗管道的描述

该管道背后的流程是:

*   检测原始数据集图像上的所有对象
*   根据图片中检测到的对象应用一些规则来选择正确的图像
*   裁剪图像上的车辆,并将其存储在新文件中

有一个过程的简要说明

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c6a12f1d6898d338cb77d12b829b3cc2.png)

这个管道中最棘手的部分是检测引擎;对于管道的这一部分,我决定我可以使用一个预先制作的模型。可以在线找到大量的模型来执行检测图像上的对象的任务。

看起来最有效的实现是由[克里斯·福塔什](https://towardsdatascience.com/@chrisfotache)在 [Pytorch](/object-detection-and-tracking-in-pytorch-b3cf1a696a98) 上实现的。

对于过滤规则,这很简单;一幅好的汽车图片可以定义为:

*   图像上只有一辆车(汽车或卡车)
*   车辆检测的置信指数应高于 90%

过滤规则后,碰巧只有 57000 张图片可用。

让我们看看这些图片的标签。

# 最后一步:调整大小和标签

完成数据集的最后一步是调整图片的大小,并为分类添加标签。

# 调整大小

从所有这些被选中的照片中,有两件事是值得注意的

*   它们有不同的尺寸(就高度和长度而言)
*   它们是彩色的(因此有 3 个原色通道)

下图显示了图片的高度和长度。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6f7269650d115bf576c9f10526d428e3.png)

这些图片有适当的分辨率,但我需要使它们一致,以便每个管道都可以用于分类。我构建了下面这段代码来调整图片的大小(这个函数可以将图片变成黑白的)。

我根据高度和长度的像素尝试了数据集的多种大小配置。

现在让我们看看标签。

# 贴标签于

该数据集有两个明显的标签:

*   有 51 种可能标签的制造商
*   有 526 个可能标签的模型

下图显示了每个制造商的型号数量。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cef48534a51887610f887a8a205dc321.png)

我们可以看到,有很多厂商和型号,有这么多标签(我觉得)是一个很难的开始。我决定建立我的“标签机制”

我建立了两种标签:

*   一个用于二元分类器
*   一个用于多类分类器

对于二元分类器,我选择一个特定的制造商和一个特定的型号。对于厂商,我决定选择特斯拉;第一个原因是它在网上很流行,第二个原因是特斯拉的图片数量与可用车型数量之间的比例不同寻常,如下图所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bab622dd2835cc46241ecf64d096a29f.png)

对于车型,我决定选择福特野马,是因为我喜欢福特野马,不是别的。但老实说,这是数据集中最受欢迎的模型之一,正如我们在下图中看到的 10 大最受欢迎的模型。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/095ee5b9e3554893ad4af03667c79f73.png)

让我们谈谈多类分类器;在这种情况下,我使用一种简单的方法来标记。这个想法就是取前 X 个最受欢迎的厂商/型号,如果图片的厂商/型号不在前 X,那么他分配的标签就是 other。我为以下产品创建标签:

*   十大制造商/型号
*   前 25 名制造商/型号
*   前 50 名制造商/型号
*   前 100/200/400 型号

现在有很多不同的图片标签。尽管如此,对于我在图像分类器上的第一个工作,我将把我的测试集中在二进制标签和前 10 名制造商/型号上。

为了完成这篇文章,我只想谈一些事情,它是关于数据集的平衡。对于我选择的标签,我可以告诉你,要预测的类根本不是平衡的。下图显示了数据集的不平衡。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ed249b9052dce4deced768628b44bf53.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bd06ced6503e437a0d4e1f1feb0f63d7.png)

当我使用这些标签进行图像分类时,我将测试影响以平衡训练的类别。

请继续关注,不要犹豫,请给我们一些反馈。

*原载于 2020 年 1 月 18 日*[](http://the-odd-dataguy.com/build-a-webscraper-with-beautifsoup-and-selenium/)**。**

# 如何用 PyTorch 构建 DCGAN

> 原文:<https://towardsdatascience.com/how-to-build-a-dcgan-with-pytorch-31bfbf2ad96a?source=collection_archive---------16----------------------->

## GAN 入门教程

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cb58c8d3f87be24182f2ce117314c920.png)

图片来源: [Pixabay](https://pixabay.com/photos/light-lamp-warm-kind-mellow-focus-4297386/)

在本教程中,我们将在 PyTorch 中构建一个简单的 [DCGAN](https://arxiv.org/abs/1511.06434) ,并训练它生成手写数字。作为本教程的一部分,我们将讨论 PyTorch 数据加载器,以及如何使用它将真实图像数据输入 PyTorch 神经网络进行训练。PyTorch 是本教程的重点,所以我假设您熟悉 GANs 的工作方式。

# 要求

1.  Python 3.7 以上版本。再低的话,你就要重构 f 弦了。
2.  PyTorch 1.5 不确定怎么安装?这可能会有所帮助。
3.  Matplotlib 3.1 或更高版本
4.  大约 22 分钟。

这不是必需的,但我建议先阅读我的[香草甘教程](/pytorch-and-gans-a-micro-tutorial-804855817a6b);它解释了一些本教程认为理所当然的事情。我还建议你在配有 CUDA GPU 的电脑上完成本教程,或者准备一本厚厚的数独书。

# 手头的任务

> *创建一个函数 G: Z → X 其中 Z~N₁* ₆ *(0,1)和 X~MNIST。*

也就是说,训练一个 GAN,它采用 16 维随机噪声并产生看起来像来自 [MNIST](https://en.wikipedia.org/wiki/MNIST_database) 数据集的真实样本的图像。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e7620493a3de60425cfd89c7d99be1f0.png)

来自 MNIST 数据集的数字样本(来源:[约瑟夫·斯特潘](https://commons.wikimedia.org/wiki/File:MnistExamples.png)

# 但是在我们开始之前…

…让我们做一点家务。如果您还没有,请安装所需版本的 Python 和上述库。然后,创建您的项目目录。我把我的叫做`DCGAN`。在该目录中,创建一个名为`data`的目录。然后,导航到[这个 GitHub repo](https://github.com/myleott/mnist_png) 并下载`mnist_png.tar.gz`。这个压缩文件包含 70000 个独立的 png 文件形式的 MNIST 数据集。当然,我们可以使用 PyTorch 的内置 MNIST 数据集,但这样你就不会知道如何实际加载图像数据进行训练。解压文件并将`mnist_png`目录放到你的`data`目录中。创建一个名为`dcgan_mnist.py`的文件,并将其放在您的 DCGAN 目录中。您的项目目录应该如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e0cb515e5693f248f64c049c922f7b28.png)

我们的项目目录,包括图像文件和 Python 脚本。0/、1/等中的数千个图像文件。未示出。

最后,将以下内容添加到您的`dcgan_mnist.py`脚本中:

```
import osimport torch
from torch import nn
from torch import optim
import torchvision as tv
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
```

好了,现在我们准备开始了。

# 发电机

将以下内容添加到您的`dcgan_mnist.py`脚本中:

生成器继承了`nn.Module`,它是 PyTorch 神经网络的基类。生成器有三种方法:

## 发电机。__init__

构造函数,存储实例变量并调用`_init_layers`。这里不多说了。

## 发电机。`_init_modules`

这个方法实例化 PyTorch 模块(或者其他框架中称为“层”)。其中包括:

*   线性(“全连通”)模块,用于将潜在空间映射到 7*×*7*×*256 = 12544 维空间。正如我们将在`forward`方法中看到的,这个 12544 长度的张量被整形为(256,7,7)“图像”张量(通道 *×* 高度×宽度)。在 PyTorch 中,与 TensorFlow 不同,通道出现在空间维度之前。
*   一维批处理规范化模块(如果指定)。
*   泄漏的 ReLU 模块。
*   二维卷积层。
*   两个 2 维转置卷积层;这些用于放大图像。请注意,一个卷积层的输出通道是下一个卷积层的输入通道。
*   两个二维批处理规范化层(如果指定)。
*   一个 Tanh 模块作为输出激活。我们将重新调整我们的图像到范围[-1,1],所以我们的发生器输出激活应该反映这一点。

这些可以在`__init__`方法中实例化,但是我喜欢将模块实例化与构造函数分开。对于这么简单的模型来说,这是微不足道的,但是随着模型变得越来越复杂,这有助于保持代码的简单。

## 发电机。`forward`

这是我们的生成器用来从随机噪声中生成样本的方法。输入张量传递给第一个模块,其输出传递给下一个模块,*的输出传递给下一个模块,依此类推。这相当简单,但我想提醒您注意两个有趣的特性:*

1.  注意线`intermediate = intermediate.view((-1, 256, 7, 7))`。与 Keras 不同,PyTorch 不使用显式的“整形”模块;相反,我们使用 PyTorch 操作“视图”手动重塑张量。其他简单的 PyTorch 操作也可以在向前传递的过程中应用,比如将一个张量乘以 2,PyTorch 不会眨一下眼睛。
2.  注意在`forward`方法中有多少`if`语句。PyTorch 使用运行定义策略,这意味着计算图是在向前传递的过程中动态构建的。这使得 PyTorch 极其灵活;没有什么可以阻止你向前传球添加循环,或者随机选择几个模块中的一个来使用。

# 鉴别器

将以下内容添加到您的`dcgan_mnist.py`脚本中:

我不会对这个做太多的描述,因为它和发生器非常相似,但方向相反。通读一遍,确保你明白它在做什么。

# DCGAN

将以下内容添加到您的`dcgan_mnist.py`脚本中:

## DCGAN。__init__

让我们一行一行地检查构造函数:

```
self.generator = Generator(latent_dim).to(device)
self.discriminator = Discriminator().to(device)
```

构造函数的前两行(非 docstring)实例化生成器和鉴别器,将它们移动到指定的设备,并将它们存储为实例变量。该设备通常是“cpu”,或者“cuda”,如果你想使用 gpu。

```
self.noise_fn = noise_fn
```

接下来,我们将`noise_fn`存储为一个实例变量;`noise_fn`是一个以整数`num`作为输入,以 PyTorch 张量的形式返回`num`潜在向量作为 shape (num,latent_dim)输出的函数。这个 PyTorch 张量必须在指定的设备上。

```
self.dataloader = dataloader
```

我们将一个 torch.utils.data.DataLoader 对象 dataloader 存储为实例变量;稍后将详细介绍。

```
self.batch_size = batch_size
self.device = device
```

将批次大小和设备存储为实例变量。简单。

```
self.criterion = nn.BCELoss()
self.optim_d = optim.Adam(self.discriminator.parameters(), lr=lr_d, betas=(0.5, 0.999))
self.optim_g = optim.Adam(self.generator.parameters(), lr=lr_g, betas=(0.5, 0.999))
```

将损失函数设置为[二进制交叉熵](/understanding-binary-cross-entropy-log-loss-a-visual-explanation-a3ac6025181a),并为生成器和鉴别器实例化 Adam 优化器。PyTorch 优化器需要知道他们在优化什么。对于鉴别器,这意味着鉴别器网络内的所有可训练参数。因为我们的 Discriminator 类继承自 nn。模块中,它有`parameters()`方法,该方法返回所有实例变量中的所有可训练参数,这些变量也是 PyTorch 模块。发电机也是如此。

```
self.target_ones = torch.ones((batch_size, 1), device=device)
self.target_zeros = torch.zeros((batch_size, 1), device=device)
```

训练目标,设置到指定的设备。记住,鉴别器试图将真实样本分类为 1,将生成的样本分类为 0,而生成器试图让鉴别器将生成的样本错误分类为 1。我们在这里定义并存储它们,这样我们就不必在每个训练步骤中重新创建它们。

## DCGAN.generate_samples

生成样本的辅助方法。注意,使用了`no_grad`上下文管理器,它告诉 PyTorch 不要跟踪梯度,因为这种方法不用于训练网络。还要注意,不管指定的设备是什么,返回的张量都被设置为 cpu,这是进一步使用所必需的,比如显示样本或将样本保存到磁盘。

## DCGAN.train_step_generator

该方法执行生成器的一个训练步骤,并以浮点形式返回损失。让我们一步一步来:

```
self.generator.zero_grad()
```

清除发生器的渐变。这是必要的,因为 PyTorch 自动跟踪梯度和计算网络。我们不希望一个训练步骤影响下一个。

```
latent_vec = self.noise_fn(self.batch_size)
generated = self.generator(latent_vec)
classifications = self.discriminator(generated)
loss = self.criterion(classifications, self.target_ones)
```

获得一批潜在向量,用它们生成样本,区分每个样本的真实程度,然后使用二进制交叉熵准则计算损失。请注意,通过将这些网络链接在一起,我们创建了一个单一的计算图,从潜在向量开始,包括发生器和鉴别器网络,并在损耗处结束。

```
loss.backward()
self.optim_g.step()
```

PyTorch 的主要优点之一是它自动跟踪计算图形及其梯度。通过对损失调用`backward`方法,PyTorch 应用反向传播并计算损失相对于计算图中每个参数的梯度。然后通过调用生成器的优化器的`step`方法,生成器的参数(只有**生成器的参数)在梯度的负方向上被轻微推动。

```
return loss.item()
```

最后,我们归还损失。使用`item`方法很重要,这样我们将返回一个浮点数而不是 PyTorch 张量。如果我们返回张量,Python 垃圾收集器将无法清理底层的计算图形,我们将很快耗尽内存。

## DCGAN.train_step_discriminator

这种方法与`train_step_generator`非常相似,但是有两个显著的不同。首先:

```
with torch.no_grad():
    fake_samples = self.generator(latent_vec)
```

上下文管理器`no_grad`在这里用来告诉 PyTorch 不要担心跟踪渐变。这是不必要的,但减少了不必要的计算。第二:

```
loss = (loss_real + loss_fake) / 2
```

这条线真的很酷。`loss_real`是鉴别器对真实样本的损耗(并附上其计算图),而`loss_fake`是对假样本的损耗(及图)。PyTorch 能够使用`+`操作符将这些组合成一个计算图。然后,我们将反向传播和参数更新应用于该组合计算图。如果你不认为这非常简单,尝试在另一个框架中重写。

## DCGAN.train_epoch

该函数为一个时期训练发生器和鉴别器,这是对整个数据集的一次遍历。在短暂的迂回之后,我们将回到这个问题上。

# 主要的

将以下代码添加到您的脚本中:

该功能构建、训练和展示 GAN。

```
import matplotlib.pyplot as plt
from time import time
batch_size = 32
epochs = 100
latent_dim = 16
```

导入`pyplot`(用于可视化生成的数字)和`time`(用于训练计时)。将训练批次大小设置为 32,将时期数设置为 100,将潜在维度设置为 16。

```
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
```

该行检查 cuda 设备是否可用。如果是,`device`被指定为该设备;否则,`device`被分配 cpu。

```
transform = tv.transforms.Compose([
            tv.transforms.Grayscale(num_output_channels=1),
            tv.transforms.ToTensor(),
            tv.transforms.Normalize((0.5,), (0.5,))
            ])
```

数据加载器使用这种复合转换来预处理图像。我们之前下载的 MNIST 数据集是。png 文件;当 PyTorch 从磁盘加载它们时,它们必须经过处理,以便我们的神经网络可以正确使用它们。这些转换依次为:

*   `Grayscale(num_output_channels=1)`:将图像转换成灰度。加载时,MNIST 数字为三通道 RGB 格式。`Greyscale`把这三个减为一个。
*   `ToTensor()`:将图像转换为 PyTorch 张量,尺寸为 channels × height × width。这也会重新调整像素值,从 0 到 255 之间的整数到 0.0 到 1.0 之间的浮点数。
*   `Normalize((0.5,), (0.5,))`:从范围[0.0,1.0]到[-1.0,1.0]缩放和平移像素值。第一个参数为μ,第二个参数为σ,应用于每个像素的函数为:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e162ed144bd9e8ebbbec4998a0f7b010.png)

μ和σ是一元组的原因是这种变换是针对每个通道应用的。到 RGB 图像的等效变换将是`Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))`

```
dataset = ImageFolder(
            root=os.path.join("data", "mnist_png", "training"),
            transform=transform
            )
```

在这里,我们通过指定它的根和要应用的转换来创建数据集。这用于创建数据加载器:

```
dataloader = DataLoader(dataset,
            batch_size=batch_size,
            shuffle=True,
            num_workers=2
            )
```

DataLoader 是一个对象,它从数据集中加载数据。在这里,我们指定我们的批处理大小,告诉数据加载器在不同的时期之间混洗数据集,并使用两个工作进程的多处理(如果您使用的是 Windows,这会导致问题,请将`num_workers`设置为 0)。您可以遍历这个数据加载器,每次迭代都会返回一个元组,其中包含:

1.  形状为(32,1,28,28)的 PyTorch 张量,对应于一批(32 个样本)灰度(1 通道)MNIST 图像(28×28 像素)。
2.  数字 0 到 9 的形状(32)py torch 张量,对应于该图像的标签(数字)。这些类标签取自目录结构,因为所有的 0 都在目录`0`中,所有的 1 都在`1`中,等等。

```
noise_fn = lambda x: torch.rand((x, latent_dim), device=device)
```

产生随机正态分布噪声的函数。

```
gan = DCGAN(latent_dim, noise_fn, dataloader, device=device)
start = time()
for i in range(10):
    print(f"Epoch {i+1}; Elapsed time = {int(time() - start)}s")
    gan.train_epoch()
```

建立和训练 GAN。

## DCGAN.train_epoch,再来一遍:

既然我们已经讨论了什么是数据加载器,让我们再来看看这个。该方法非常简单明了,尽管有些冗长,但我想重点介绍两行代码:

```
for batch, (real_samples, _) in enumerate(self.dataloader):
   real_samples = real_samples.to(self.device)
```

这里,我们遍历数据加载器。我们将数据加载器包装在一个枚举器中,这样我们就可以跟踪批号,但是正如您所看到的,数据加载器确实像承诺的那样返回了一个元组。我们将一批图像张量分配给`real_samples`,并忽略标签,因为我们不需要它们。然后,在循环中,我们将`real_samples`移动到指定的设备。模型的输入和模型本身在同一个设备上是很重要的;如果你忘记这样做,不要担心,PyTorch 一定会让你知道的!此外,不要担心数据加载器“耗尽”。一旦我们遍历了整个数据集,循环将会结束,但是如果我们再次尝试遍历它,它将会从头开始(首先洗牌,因为我们在制作数据加载器时指定了这一点)。

# 让我们试着运行它?

如果复制和粘贴正确,运行脚本应该会显示几分钟的训练统计数据,然后是一些生成的数字。希望它看起来像这样:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/83340ca62217bd65620ced28cb4f1618.png)

如果它们看起来很糟糕,你的损失暴增,试着再跑一次(甘的不稳定性是出了名的)。如果它*仍然*不工作,请在下面留下评论,我们看看是否能调试它。

只是为了好玩,我修改了脚本,看看在每 10 个训练步骤之后,生成器能够做什么。这是结果。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cf615f2788a0cf313cc6daf4bc524564.png)

我觉得只走 1000 步就已经很不错了。这是那些训练步骤的损失,分成 10 步“时期”。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1b00a0372761da406b07f2ecbfe4f5dc.png)

# 结束语

*   本教程中描述的 DCGAN 显然非常简单,但应该足以让您开始在 PyTorch 中实现更复杂的 GAN。
*   在我制作一个教程之前,你能修改这个脚本来制作一个[条件句](https://arxiv.org/abs/1411.1784)吗?
*   完整的脚本可在[这里](https://github.com/ConorLazarou/pytorch-generative-models/blob/master/GAN/DCGAN/dcgan_mnist.py)获得。
*   所有未引用的图片都是我自己的。请随意使用它们,但请引用❤的这篇文章

[](https://github.com/ConorLazarou/pytorch-generative-models/blob/master/GAN/DCGAN/dcgan_mnist.py) [## ConorLazarou/py torch-生成模型

### 产生 MNIST 数字的简单 DCGAN 实现。

github.com](https://github.com/ConorLazarou/pytorch-generative-models/blob/master/GAN/DCGAN/dcgan_mnist.py)

# 如何用 10 行构建深度学习模型

> 原文:<https://towardsdatascience.com/how-to-build-a-deep-learning-model-in-10-lines-4f4c351d5da?source=collection_archive---------13----------------------->

# 快速沉浸在深度学习中的指南

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0d418fe3c62b671b011ce0906fbad548.png)

Alex Kotliarskyi 在 [Unsplash](https://unsplash.com/s/photos/%22deep-learning%22?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

本文将通过一个案例研究向读者介绍神经网络的基础知识,该案例研究仅使用 10 行 Python 代码创建并训练了一个神经网络,该网络通过 3 个基本步骤识别手写数字:

**1-加载并预处理数据**

**2-定义模型**

**3-训练模型**

为此,我们将使用目前深度学习社区中最流行的库 [TensorFlow Keras API](https://www.tensorflow.org/guide/keras/overview) 。让我们去吧!

# 手写数字

作为一个案例研究,我们将创建一个允许我们识别手写数字的模型,例如下列数字:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d0883dd8588ea842a38e94d6bd0d55ba.png)

目标是创建一个数学模型,给定一幅图像,该模型识别它所代表的数字。例如,如果我们向模型输入第一张图片,我们会期望它回答这是一张 5。下一个是 0,下一个是 4,以此类推。

## 分类问题

实际上,我们正在处理一个分类问题,给定一幅图像,模型将其分类在 0 到 9 之间。但有时,甚至我们会发现自己有某些疑问,例如,第一个图像代表 5 还是 3?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8174958424a600fcc0044d98276ef9aa.png)

为此,我们将创建的神经网络返回一个具有 10 个位置的向量,指示 10 个可能数字中每一个的可能性:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0a8549f476c5cc7874279f63c3984044.png)

## 只有 10 行代码

是的,只需 10 行 python 代码,您就可以创建并训练一个对手写数字进行分类的神经网络模型:

```
**1:** import tensorflow as tf
**2:** from tensorflow.keras.utils import to_categorical**3:**(x_train, y_train), _ = tf.keras.datasets.mnist.load_data()**4:** x_train = x_train.reshape(60000, 784).astype('float32')/255
**5:** y_train = to_categorical(y_train, num_classes=10)**6:** model = tf.keras.Sequential()
**7:** model.add(tf.keras.layers.Dense(10, activation='sigmoid', 
            input_shape=(784,)))
**8:** model.add(tf.keras.layers.Dense(10, activation='softmax'))**9:** model.compile(loss="categorical_crossentropy", optimizer="sgd", 
                 metrics = ['accuracy'])**10:** model.fit(x_train, y_train, epochs=10, verbose=0)
```

我们使用了 TensorFlow **的 [API Keras。](https://www.tensorflow.org/guide/keras)**它是推荐给初学者的库,因为它的学习曲线与其他库相比非常平滑,并且目前它是实现神经网络的流行中间件之一。Keras 由来自谷歌的工程师[Fran ois Chollet](https://twitter.com/fchollet)开发和维护,目前收录在 Tensorflow 库中。

## 环境设置

如果你想执行这篇文章中描述的代码,我建议使用谷歌提供的[](https://colab.research.google.com/)**。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2b97dd5add10eb94f375b6b0e779e423.png)**

**这是谷歌的一个研究项目,旨在帮助传播机器学习教育和研究。这是一个 Jupyter 笔记本环境,不需要任何配置,完全在云中运行,允许使用不同的深度学习库,如 [TensorFlow 和 PyTorch](/tensorflow-vs-pytorch-the-battle-continues-9dcd34bb47d4) 。Colab 区别于其他免费云服务的最重要的特点是;Colab 提供 GPU(或 TPU)并且完全免费。关于这项服务的详细信息可以在 [faq 页面](https://research.google.com/colaboratory/faq.html)找到。**

**默认情况下,Colab 笔记本运行在 CPU 上。你可以切换你的笔记本电脑运行与 GPU(或 TPU)。为了访问一个 GPU,我们需要选择标签运行时间,然后选择“更改运行时间类型”,如下图所示:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6950191e4361cdecdef6df22881b25b3.png)**

**当弹出窗口出现时,选择 GPU。确保“硬件加速器”设置为 GPU(默认为 CPU)。**

**然后,确保您已连接到运行时(在菜单功能区中“已连接”旁边有一个绿色复选标记):**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0aca5d06a9b73163d529bcf26f240160.png)**

**现在你可以运行这篇文章中的代码了。我建议将这篇文章的代码复制粘贴到一个 colab 笔记本上,以便在你阅读这篇文章的同时看到执行过程。**

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

> **[该帖子的代码可从 GitHub 获得](https://colab.research.google.com/github/jorditorresBCN/Medium/blob/master/How-to-DL-model-10lines.ipynb)**

# **1.加载和预处理数据**

**首先,我们需要导入一些 Python 库,以便在 TensorFlow 中对我们的神经网络进行编程:**

```
**import tensorflow as tf
from tensorflow.keras.utils import to_categorical**
```

**下一步是加载将用于训练我们的神经网络的数据。我们将使用 MNIST 数据集,该数据集可以从*[*MNIST 数据库*页面](http://yann.lecun.com/exdb/mnist)下载。该数据集包含 60,000 个手工制作的数字图像来训练模型,对于首次进入模式识别技术来说是理想的,无需花费大量时间预处理和格式化数据,这在数据分析中是非常重要和昂贵的步骤,并且在处理图像时具有特殊的复杂性。***

**在 TensorFlow 中,这可以通过下面这行代码来实现(第 3 行):**

```
**(x_train, y_train), _ = tf.keras.datasets.mnist.load_data()**
```

****可选步骤:**如果需要,您可以使用以下代码验证加载的数据:**

```
**import numpy as np
import matplotlib.pyplot as pltfig = plt.figure(figsize=(25, 4))
for idx in np.arange(20):
   ax = fig.add_subplot(2, 20/2, idx+1, xticks=[], yticks=[])
   ax.imshow(x_train[idx], cmap=plt.cm.binary)
   ax.set_title(str(y_train[idx]))**
```

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0dc7880da6e80e99f2e7833871d229d1.png)**

**这个黑白图像(包含灰度级的图像)的数据集已经归一化为 20×20 像素,同时保留了它们的纵横比。随后,将图像居中,计算这些图像的质心并移动图像,以便将该点定位在 28×28 视场的中心。**

**这些 28×28 像素的 MNIST 图像被表示为一个数字数组,其值的范围从类型`uint8`的[0,255]开始。但是通常将神经网络的输入值调整到一定的范围。在这篇文章的例子中,输入值应该在区间[0,1]内换算成类型为`float32`的值。**

**另一方面,为了便于将数据输入到我们的神经网络中,我们必须将输入(图像)从二维(2D)转换为一维(1D)向量。也就是说,28×28 个数字的矩阵可以由 784 个数字(逐行连接)的向量(数组)表示,这种格式接受密集连接的神经网络作为输入,就像我们将在本文中看到的那样。**

**我们可以用下面的代码行(第 4 行)实现这些转换:**

```
**x_train = x_train.reshape(60000, 784).astype('float32')/255**
```

**此外,数据集对每张图像都有一个标签,表明它代表什么数字(在`y_train)`下载)。在我们的例子中,0 到 9 之间的数字表示图像代表哪个数字,也就是说,它与哪个类相关联。**

**如前所述,我们需要用 10 个位置的向量来表示每个标签,其中对应于表示图像的数字的位置包含 1,其余的包含 0。这个将标签转换成与不同标签的数量一样多的零的向量,并将 1 放入对应于标签的索引中的过程被称为*一键编码*。例如,数字 7 将被编码为:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6b73714558c13ec67d39c420b7b967c2.png)**

**我们可以用下面的代码行(第 5 行)实现这种转换:**

```
**y_train = to_categorical(y_train, num_classes=10)**
```

# **2.定义模型**

**为了用 Keras 的 API 定义模型,我们只需要这些代码行(第 6–8 行):**

```
**model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(10,activation='sigmoid',
          input_shape=(784,)))
model.add(tf.keras.layers.Dense(10,activation='softmax'))**
```

**然而,在解释这些代码行之前,让我先介绍一些基本的神经网络概念。**

## **普通的人工神经元**

**为了展示基本神经元是怎样的,让我们假设一个简单的例子,其中我们在二维平面中有一组点,并且每个点已经被标记为“正方形”或“圆形”:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8adcbfa817ac155ee916a6c0eae82c3e.png)**

**给定一个新的点“ *X* ”,我们想知道它对应什么标号:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3cae736b76402ac9d1afe7738352571c.png)**

**一种常见的方法是画一条线将两个组分开,并使用这条线作为分类器:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3cefcabf4e6bc1cead5ad81d9f529352.png)**

**在这种情况下,输入数据将由( *x1,x2* )形式的向量表示,这些向量表示它们在这个二维空间中的坐标,我们的函数将返回‘0’或‘1’(在线的上方或下方),以知道它应该被分类为“正方形”还是“圆形”。它可以定义为:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e3e244fd3d25becba1d452d7b7ce74f7.png)**

**更一般地说,我们可以将这条线表示为:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/83fa3f5017ebdd7d26cd2be7b94a8d70.png)**

**为了对输入元素 X(在我们的例子中是二维的)进行分类,我们必须学习一个与输入向量维数相同的权重向量 W,即向量( *w1,w2* )和一个 *b* 偏差。**

**有了这些计算值,我们现在可以构建一个人工神经元来对新元素 *X* 进行分类。基本上,神经元将计算出的权重的向量 *W* 应用于输入元素 *X* 的每个维度中的值,并在最后添加偏差 *b.* ,其结果将通过非线性“激活”函数来产生结果“0”或“1”。我们刚刚定义的这种人工神经元的功能可以用更正式的方式来表达,例如:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/90730ab34ecb729215d5bd3a3ba0ea92.png)**

**现在,我们将需要一个函数,它对变量 *z* 进行转换,使其变成‘0’或‘1’。虽然有几个函数(“激活函数”),但在本例中,我们将使用一个称为 *sigmoid* 函数的函数,该函数针对任何输入值返回 0 到 1 之间的实际输出值:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85214ebdf0652ce5a99869d6968f9bd4.png)**

**如果我们分析前面的公式,我们可以看到它总是倾向于给出接近 0 或 1 的值。如果输入 z 相当大且为正,则在负 *z* 处的“e”为零,因此 *y* 取值为 1。如果 *z* 具有大的负值,那么对于“e”的大正数,公式的分母将是一个大的数字,因此 *y* 的值将接近 0。从图形上看,sigmoid 函数呈现如下形式:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/36014fac0f665699320b24e78074cfa0.png)**

**到目前为止,我们已经介绍了如何定义人工神经元,这是神经网络可以拥有的最简单的架构。具体来说,这种架构在本主题的文献中被命名为感知器(也称为*线性阈值单元* (LTU)),由 Frank Rosenblatt 于 1957 年发明,并在视觉上概括为以下方案:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2245e8de2df0f869f77365f389a01511.png)**

## **多层感知器**

**但是在继续讨论这个例子之前,我们将简要介绍当神经网络是由我们刚刚介绍过的感知器构造而成时,它们通常采用的形式。**

**在该领域的文献中,当我们发现神经网络具有一个*输入层*,一个或多个由感知器组成的层,称为*隐藏层*,以及具有几个感知器的最后一层,称为*输出层*时,我们称之为多层感知器(MLP)。一般来说,当基于神经网络的模型由多个隐藏层组成时,我们称之为*深度学习*。在视觉上,它可以用以下方案来表示:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/72d219d12a06da2e1b3056064ffaab99.png)**

**MLP 通常用于分类,特别是当类别是排他性的时,如在数字图像分类的情况下(从 0 到 9 的类别)。在这种情况下,由于一个名为 softmax 的函数,输出图层返回属于每个类的概率。视觉上,我们可以用以下方式表示它:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/771cc5e6d1511521471f2e4799906745.png)**

**正如我们提到的,除了 *sigmoid* 之外,还有几个激活函数,每个都有不同的属性。其中一个是我们刚刚提到的 *softmax* 激活函数,它将有助于提供一个简单的神经网络的例子来分类两个以上的类。目前,我们可以把 *softmax* 函数看作是 *sigmoid* 函数的推广,它允许我们对两个以上的类进行分类。**

## **Softmax 激活功能**

**我们将以这样的方式来解决这个问题:给定一个输入图像,我们将获得它是 10 个可能数字中的每一个的概率。这样,我们将有一个模型,例如,可以预测图像中的 5,但只有 70%的把握是 5。由于这幅图中数字上半部分的笔画,看起来它有 20%的几率变成 3,甚至有一定的概率变成其他数字。虽然在这种特殊情况下,我们会认为我们的模型的预测是 5,因为它是概率最高的一个,但这种使用概率分布的方法可以让我们更好地了解我们对预测的信心程度。这在这种情况下很好,因为数字是手工制作的,当然在很多情况下,我们不能 100%确定地识别数字。**

**因此,对于这个分类示例,我们将为每个输入示例获得一个输出向量,该输出向量具有在一组互斥标签上的概率分布。也就是说,10 个概率的向量(每个概率对应于一个数字)以及所有这 10 个概率的总和导致值 1(概率将在 0 和 1 之间表示)。**

**正如我们已经提出的,这是通过在我们的神经网络中使用具有 *softmax* 激活函数的输出层来实现的,其中该 *softmax* 层中的每个神经元取决于该层中所有其他神经元的输出,因为所有这些神经元的输出之和必须为 1。**

**但是 *softmax* 激活功能是如何工作的呢? *softmax* 函数基于计算某一图像属于特定类别的“证据”,然后将这些证据转换为它属于每个可能类别的概率。**

**一种测量某一图像属于特定类别的证据的方法是对属于该类别的每个像素的证据进行加权求和。为了解释这个想法,我将使用一个可视化的例子。**

**假设我们已经学习了数字 0 的模型。目前,我们可以把模型看作是“某种东西”,它包含了知道一个数是否属于某一类的信息。在这种情况下,对于数字 0,假设我们有一个如下所示的模型:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5f0baa2700488a5228930babb57118fa.png)**

**在这种情况下,具有 28×28 像素的矩阵,其中红色像素表示负权重(即,减少其所属的证据),而蓝色像素表示正权重(其证据是更大的增加)。白色代表中性值。**

**假设我们在上面画了一个零。一般来说,零点的轨迹会落在蓝色区域(请记住,我们讨论的是归一化为 20×20 像素的图像,后来以 28×28 的图像为中心)。很明显,如果我们的笔画越过红色区域,很可能我们写的不是零;因此,使用基于如果我们通过蓝色区域则相加,如果我们通过红色区域则相减的度量标准似乎是合理的。**

**为了确认它是一个好的度量,现在让我们想象我们画了一个三;很明显,我们用于零的前一个模型中心的红色区域会影响前面提到的指标,因为,正如我们在下图的左部看到的,当我们写 3 时,我们忽略了:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0caa4a4068b932db3875c7837fd027d3.png)**

**但另一方面,如果参考模型是对应于数字 3 的模型,如上图右侧所示,我们可以看到,一般来说,代表数字 3 的不同可能走线大多位于蓝色区域。**

**我希望读者看到这个直观的例子后,已经直觉地知道上面提到的权重的近似值是如何让我们估计出它是多少的。**

**一旦属于 10 个类别中的每一个的证据被计算出来,这些必须被转换成概率,其所有成分的总和加 1。为此,softmax 使用计算证据的指数值,然后将它们归一化,使总和等于 1,形成概率分布。属于类别 *i* 的概率为:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bcb0de50b88978af4316c08c39e06a28.png)**

**直观地说,使用指数得到的效果是,多一个单位的证据具有乘数效应,少一个单位的证据具有反效应。关于这个函数有趣的事情是,一个好的预测在向量中有一个接近 1 的值,而其余的值接近 0。在弱预测中,将有几个可能的标签,它们将具有或多或少相同的概率。**

## **Keras 中的顺序类**

**Keras 中的主要数据结构是*序列*类,它允许创建一个基本的神经网络。Keras [还提供了一个 API](https://keras.io/getting-started/functional-api-guide/) ,允许以图形的形式实现更复杂的模型,可以有多个输入,多个输出,中间有任意连接,但这超出了本文的范围。**

**Keras 库的 [*序列*类](https://keras.io/models/sequential/)是 Keras 提供的序列神经网络模型的包装器,可以通过以下方式创建:**

```
**model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(10,activation='sigmoid',
          input_shape=(784,)))
model.add(tf.keras.layers.Dense(10,activation='softmax'))**
```

**在这种情况下,Keras 中的模型被视为一系列层,每一层都逐渐“提取”输入数据以获得所需的输出。在 Keras 中,我们可以找到所有需要的层类型,这些层可以通过`add()`方法轻松添加到模型中。**

**在这里,神经网络已经被定义为密集连接(或完全连接)的两层序列,意味着每层中的所有神经元都连接到下一层中的所有神经元。视觉上,我们可以用以下方式表示它:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c7b1fad769b32d57d270739af6d4c574.png)**

**在前面的代码中,我们在第一层的 *input_shape* 参数中明确表达了输入数据是什么样的:一个张量,表示我们有 784 个模型特征。**

**Keras 库的一个非常有趣的特点是,它会在第一个张量之后自动推导出层间张量的形状。这意味着程序员只需要为其中的第一个建立这些信息。此外,对于每一层,我们指出它所具有的节点数量以及我们将在其中应用的激活函数(在本例中, *sigmoid* )。**

**本例中的第二层是由 10 个神经元组成的 *softmax* 层,这意味着它将返回代表 10 个可能数字的 10 个概率值的矩阵(通常,分类网络的输出层将具有与类一样多的神经元,除了在二元分类中,只需要一个神经元)。每个值将是当前数字的图像属于它们中的每一个的概率。**

****可选步骤:**Keras 提供的一个非常有用的方法是`summary()`:**

```
**model.summary()_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 10) 7850
_________________________________________________________________
dense_2 (Dense) (None, 10) 110
=================================================================
Total params: 7,960
Trainable params: 7,960
Non-trainable params: 0**
```

**对于我们的简单示例,我们看到它指示需要 7960 个参数(列 *Param #* ),这对应于第一层的 7850 个参数和第二层的 110 个参数。**

**在第一层中,对于每个神经元 *i* (在 0 和 9 之间),我们需要 784 个参数作为权重 *wij* ,因此需要 10×784 个参数来存储 10 个神经元的权重。此外还有 10 个附加参数,分别对应于 10 个 *bj* 偏置。在第二层中,作为 *softmax* 函数,需要将所有 10 个神经元与前一层的 10 个神经元连接。因此,需要 10×10 个 *wi* 参数,另外还需要 10 个 *bj* 偏置对应于每个节点。**

**我们可以为`dense` [](https://keras.io/layers/core/#dense)指出的参数细节可以在 Keras 手册中找到。在我们的例子中,最相关的出现在例子中。第一个参数表示层中神经元的数量;下面是我们将在其中使用的激活函数。在[这篇文章](/learning-process-of-a-deep-neural-network-5a9768d7a651)中,我们将更详细地讨论除了这里介绍的两个激活功能之外的其他可能的激活功能: *sigmoid* 和 *softmax* 。**

# **3.训练模型**

**我们差不多完成了,我们只需要解释最后两行代码:**

```
**model.compile(loss="categorical_crossentropy", optimizer="sgd", 
                 metrics = ['accuracy'])model.fit(x_train, y_train, epochs=10, verbose=0)**
```

## **学习过程**

**神经网络如何学习神经元的权重 *W* 和偏差 *b* 的方式是对所有已知标记输入示例的迭代过程,将通过模型估计的其标记值与每个元素的标记的期望值进行比较。在每次迭代之后,以这样的方式调整参数值,使得图像的估计值和实际值之间的不一致(误差)变得更小。下面的方案希望以一种通用的方式直观地总结一个感知器的学习过程:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/12d4b5988cfc7348246e7dac474d042c.png)**

## **学习过程的配置**

**我们可以用`compile()`方法配置这个学习过程,使用它我们可以通过方法参数指定一些属性。**

**第一个参数是*损失函数*,我们将使用它来评估训练数据的计算输出和期望输出之间的误差程度。另一方面,我们指定一个*优化器*,这是我们必须指定的优化算法,允许神经网络根据输入数据和定义的损失函数计算参数的权重。**

**最后,我们必须指出我们将用来监控神经网络学习过程的度量标准。在第一个例子中,我们将只考虑*准确度*(被正确分类的图像的比例)。例如,在我们的例子中我们可以在 *compile()* 方法中指定以下参数来测试它:**

```
**model.compile(loss="categorical_crossentropy", 
              optimizer="sgd", 
              metrics = ['accuracy'])**
```

**在本例中,我们指定损失函数为*分类 _ 交叉熵*,使用的优化器为*随机梯度下降(sgd)* ,度量标准为*准确度*,我们将使用它来评估正确猜测的百分比**

**在一篇新文章中,读者可以了解学习过程的更多细节。**

## **模特培训**

**一旦我们的模型被定义,学习方法被配置,它就可以被训练了。为此,我们可以通过调用模型的 *fit()* 方法,将模型训练或“调整”为可用的训练数据:**

```
**model.fit(x_train, y_train, epochs=10, verbose=0)**
```

**在前两个参数中,我们已经以 Numpy 数组的形式指出了用于训练模型的数据。 *batch_size* 参数表示我们将在每次更新模型参数时使用的数据数量,而 *epochs* 表示我们将在学习过程中使用所有数据的次数。**

**这种方法通过我们提到的迭代训练算法找到网络的参数值。大致来说,在该算法的每次迭代中,该算法从 *x_train* 中获取训练数据,将它们通过神经网络(具有它们的参数在该时刻的值),将获得的结果与预期的结果(在 *y_train* 中指示)进行比较,并计算*损失*以指导模型参数的调整过程。 其直观地包括应用上面在 *compile()* 方法中指定的优化器,以减少损失的方式计算每次迭代中每个模型参数(权重和偏差)的新值。**

**正如我们将看到的,这种方法可能需要更长时间,Keras 允许我们使用*冗长的*参数(默认情况下等于 1)来查看其进度,此外还指示每个*时期*花费的估计时间:**

```
**Epoch 1/5
60000/60000 [========] — 1s 15us/step — loss: 2.1822 — acc: 0.2916
Epoch 2/5
60000/60000 [========] — 1s 12us/step — loss: 1.9180 — acc: 0.5283
Epoch 3/5
60000/60000 [========] — 1s 13us/step — loss: 1.6978 — acc: 0.5937
Epoch 4/5
60000/60000 [========] — 1s 14us/step — loss: 1.5102 — acc: 0.6537
Epoch 5/5
60000/60000 [========] — 1s 13us/step — loss: 1.3526 — acc: 0.7034
10000/10000 [========] — 0s 22us/step**
```

# **使用模型**

**为了使用该模型,我们可以使用以下代码下载另一组图像(不同于训练图像):**

```
**_, (x_test_, y_test_)= tf.keras.datasets.mnist.load_data()
x_test = x_test_.reshape(10000, 784).astype('float32')/255
y_test = to_categorical(y_test_, num_classes=10)**
```

## **可选步骤:模型评估**

**此时,神经网络已经完成训练,现在可以使用`evaluation()`方法评估其在新测试数据下的行为。此方法返回两个值:**

```
**test_loss, test_acc = model.evaluate(x_test, y_test)**
```

**这些值表明我们的模型在处理从未见过的新数据时表现得如何。当我们执行了 *mnist.load_data()* 时,这些数据已经存储在 *x_test* 和 *y_test* 中,我们将它们作为参数传递给方法。在本帖的范围内,我们将只关注其中之一,准确性:**

```
**print(‘Test accuracy:’, test_acc)
Test accuracy: 0.9018**
```

**准确性告诉我们,我们在这篇文章中创建的模型,应用于该模型从未见过的数据,正确分类了 90%。**

## **生成预测**

**最后,读者需要知道我们如何使用上一节中训练的模型进行预测。在我们的例子中,它包括预测哪个数字代表一幅图像。为了做到这一点,Keras 提供了`predict()`方法。**

**让我们选择一个图像(并绘制它)来预测数字:**

```
**image = 5_ = plt.imshow(x_test_[image], cmap=plt.cm.binary)**
```

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a7369ed07ecc7e0a504b195a230d7d0a.png)**

**为了预测这个数字,我们可以使用下面的代码:**

```
**import numpy as np
prediction = model.predict(x_test_)
print("Model prediction: ", np.argmax(prediction[image]) )**
```

**仅此而已!**

# **下一步?**

**现在你已经准备好学习如何编程一个更高级的神经网络(本文中的):卷积神经网络。准备好了吗?**

**[](/convolutional-neural-networks-for-beginners-using-keras-and-tensorflow-2-c578f7b3bf25) [## 卷积神经网络初学者使用 Keras 和 TensorFlow 2

### 边做边学:包含 GitHub 代码的实用指南

towardsdatascience.com](/convolutional-neural-networks-for-beginners-using-keras-and-tensorflow-2-c578f7b3bf25) 

> [GitHub](https://colab.research.google.com/github/jorditorresBCN/Medium/blob/master/How-to-DL-model-10lines.ipynb)上有这个帖子的代码

*于 2020 年 5 月 02 日*[*https://Torres . ai*](https://torres.ai/como-construir-un-modelo-deep-learning-en-10-lineas/)*以西班牙语原文发表。***

# 我如何建立一个动态定价系统

> 原文:<https://towardsdatascience.com/how-to-build-a-dynamic-pricing-model-5544151e8bce?source=collection_archive---------2----------------------->

## [现实世界中的 DS](https://towardsdatascience.com/data-science-in-the-real-world/home)

## 众所周知,在商业中有这样一条真理:价格高,数量少。高容量,低价格。或者是?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a421238553bbb66857881eecd3df3a1d.png)

由[本杰明·夏普](https://unsplash.com/@benjaminsharpe?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片

在本文中,我将与您分享我为一家长途火车公司构建动态定价系统的经验,以及我们如何通过应用非常基本的微观经济学原理,在不改变我们的时间表,也不降低每个座位的平均价格的情况下,增加售出座位的数量。

这种实现也适用于其销售的服务与火车座位共享一些特征的任何商业,也就是说:

*   多卖一个单位的成本,或者说边际成本,接近于零。
*   如果一个可用的单元在提供服务时没有卖出去(例如,一列火车离开车站),那么它就不能保存在库存中,它的潜在价值就永远失去了。

酒店房间、航空公司、长途汽车票、电影院、剧院、音乐会、动物园、游轮、体育赛事等都是如此。

为了建立模型,我们首先需要回答以下问题:

*   顾客购买多少商品或服务?
*   顾客付多少钱?
*   客户什么时候购买?

# 顾客买了多少

让我们先来看看一个典型的需求函数:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5f729004341ac72f6c4d2555e04d5942.png)

需求函数是商品或服务的价格与你能以给定价格出售的所述商品或服务的数量之间关系的数学表达式。如前所述,对于正常商品,价格越高,售出的商品数量越少。这导致需求函数向下倾斜。当你在水平轴上向右移动时,你增加了你要销售的产品的数量,那么你需要降低你的价格来达到销售的数量。

所以,顾客想买多少商品或服务将取决于价格。在其他条件不变的情况下,你降低价格,就会有更多的顾客愿意为服务付费。

# 顾客愿意付多少钱

上面的图表也能告诉我们,在给定你想要出售的单位数量的情况下,我们可以收取多少费用。

为了简化,让我们假设一个客户只能购买一个单位的服务(在这种情况下是一张火车票)。那么如果你把票的价格定在€9,那么就有 30 个人愿意买票。如果你把价格定在€3,那么有 90 个人愿意买票(30 个人愿意在€9 买,另外 60 个人愿意在€3 买)。

# 收入最大化

如果一个公司只能向所有顾客收取同一个价格,因为收入等于价格乘以数量,那么如果公司每张票收费 6 欧元,那么它将出售 60 张票,总收入为€360。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c87c170432f9946e954ce423fdf4e000.png)

尽管有时公司有能力对不同的顾客收取不同的价格。经济学家称这种能力为*价格歧视,*,这使得公司能够通过获取需求曲线函数下的更多价值来增加收入。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/99a3beb7a058333979c000bfb66b942c.png)

在上面的例子中,如果我们的火车公司可以对成人和儿童乘客收取不同的价格,那么他们可能会增加收入,从他们可以以单一价格达到的最高€360 到€440(每个成人 40 张€8 的票,加上每个儿童 20 张€6 的票)。

需求曲线下的面积代表特定商品或服务交付给客户的价值。因此,如果你不仅可以对两种不同类型的客户收取两种不同的价格,而且可以对几种不同类型的客户收取几种不同的价格,那么你就可以抓住需求曲线下的大部分区域,并完全从你的定价策略中大幅增加收入,而不必承担增加航班、改变座位安排、增加广告或在飞机上提供额外服务的成本。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3f7d9d8030b08e8ebfe24671bf50d079.png)

正如我们已经确定的那样,在一列无论如何都将空着的火车上出售一个座位几乎没有额外的成本,并且未出售的座位的价值将永远失去,只要你有空座位,以高于零的任何价格出售任何空座位都是有意义的。

要是我们知道如何根据客户对价格的敏感度来对他们进行细分就好了。

# 顾客什么时候购买

我们都会拖延,消费者也一样。人们通常会尽可能推迟购买决定。在火车票的例子中,我们发现这种行为创造了一种模式,即在很久以后才零星地购买火车票。然后,在出发前一个月左右,购买变得更加频繁,在出发前一周加速,并且在出发前一天达到购买机票的高峰。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/83bd28a7fafc78e3003d49d97d0bc680.png)

如果我们在横轴上画出剩余待售车票的百分比,在纵轴上画出火车离站的剩余天数,那么我们得到一个向下倾斜的函数。随着离出发时间越来越近,售票速度加快,因此剩余的待售票数量也相应减少。

我们还发现,越晚购票的乘客对价格越不敏感。因此,我们找到了允许我们进行价格歧视的变量:时间。

# 把它放在一起

现在,我们需要找到在特定时间需要收取的特定价格,因为我们有特定数量的门票要出售。幸运的是,我们有两个共享两个变量的方程,可以同时求解:

*   *价格需求函数:P = g(Q)
    其中价格(P)是数量(Q)的函数(g)。*
*   *和剩余的票数:Q = h(T)
    其中数量(Q)是时间(T)的函数(h)。*

这给了我们一个新的函数,价格是时间的函数。

*   *P = f(T) = g(h(T))*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a33a1c09f97362947dc8a7f93ce97746.png)

在上图的右上象限中以图形方式显示。这个函数告诉我们在任何特定时间每张票的价格,给定我们还有多少票要卖。

使用这个函数,我们还可以计算时间 T 和数量 Q 的任何给定值的预期价格 P,以填充一个矩阵,并以表格形式显示这个函数。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a2df894e9f8a933b9f090cdff18d80c0.png)

# 当事情不按计划进行时

有时事情不会像预期的那样发生,例如,与我们的功能预测相反,我们卖出了更多或更少的票。

如果在任何给定的时间(T)和价格(P),售出的商品数量高于预期,那么这意味着更多的人愿意在当时的时间和价格购买一张票。

我们可以把这种变化表示为需求函数的上移。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c127c8aa2b70b24c29dcd6080175f34c.png)

如果需求函数在上图的左上象限向上移动。然后,为了有剩余的票在以后出售,当我们可以收取更高的价格时,价格现在就需要上涨。这导致在右上象限中代表作为时间函数的价格的曲线中类似的平行上移。都用红色表示。

同样,如果我们卖出的票比预期的少,那么这意味着在给定的时间和价格下,售出的数量比预期的少。这导致向下移动的曲线为绿色。为了填满火车,价格需要下降。

如果随着时间的推移,我们发现预期售出的门票数量与实际售出的门票数量之间存在进一步的差异,我们可以将它们视为需求函数的进一步变化。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a713eeb334f5dd0ffd5d0f96afeb30b1.png)

想象一下,我们一直发现我们卖出的票比预期的多。这些可以被视为门票价格需求函数的连续向上移动,以及价格/时间函数的匹配平行向上移动,如上图中向上移动的红色曲线所示。

计算这些向上和向下移动的需求函数给我们的所有价格 P 的所有值,给定时间 T 和数量 Q 的组合,以填充我们假设的火车出发的全部价格矩阵,向我们显示我们在出发前*时间*和出售离开的座位的*的任何给定组合下需要收取的价格,这将最大化该出发的收入。*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b221af3155e8552c9ed4a07b071cb475.png)

# 履行

在实施过程中,我们必须做出一些政策决定,以简化向新系统的过渡。

考虑到对铁路网络中的不同旅行段进行定价是一项相当复杂的工作,我们没有对现有的定价模型进行太大的修改,而是在现有模型的基础上实施了价格矩阵,以标价的百分比表示。

我们现在有两种定价等级(不要与运输等级混淆):新的、动态定价的折扣票,不可退款;和全价票,全价票可以作为可全额退款的机票在任何时候以相同的固定全价购买。

需要做的第一个决定是将每次出发的座位分配给这两种机票等级,这最初是手动完成的,但后来是自动完成的,使用历史数据作为参考。

为了简化营销沟通,我们决定不收取高于所列全价票的费用,有效地限制了我们可以收取的最高价格,即使火车会非常满。同样,我们也决定永远不收取低于全价 20%的费用。

我们还必须对不同的偏离进行分组,并为不同的分组实现不同的矩阵。下面是我们实现的一个矩阵的例子。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/77a21bfb9f79d05432822698abfc86c5.png)

# 最后的想法

这种定价系统的引入使我们能够淘汰依赖于更多变量、需要大量手动输入和昂贵的软件许可费用的更老、更复杂的系统。取而代之的是一个更简单、更稳健、更便宜的模型,它需要更少的、事实上只有两个输入:(1)出发时间和(2)售出的座位数量。

经济学家通常说,所有的信息最终都会反映在价格中。在这种情况下,结果就是这样。我们实际上用更少的输入做出了更准确的预测,所以模型需要更少的维护。简单性的维护成本更低。

我们还取消了几个复杂的折扣机票等级。这种单一的、与时间相关的定价允许我们更换它们,同时获得更广泛的价格范围,不仅在较低的价格点(如果您较早购买了机票),而且在较高的价格点,通过引入更细微的定价,随着出发时间的临近,更接近需求函数。实际上,它大大提高了我们辨别价格的能力。

在我们使用这些价格矩阵后,我们看到售出的门票数量增加了 5%。不仅是因为打折票的额外销售,有趣的是,还因为全价票的增加,因为该系统允许我们更准确地预测我们可以销售的全价票的数量。

由于售出的额外门票的边际成本接近零,所有相关的收入增长都直接进入了底线,因为在我们的票务系统中实施矩阵后,不会产生额外的可变成本,从而导致利润率的纯增长。

[![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7679973e586db21de78180e8e558f76d.png)](https://eyuan.org/membership)

[支持](https://eyuan.org/membership)艾蒂安和其他数千名作家的作品

# 如何构建快速迭代的主动学习数据管道

> 原文:<https://towardsdatascience.com/how-to-build-a-fast-iterative-active-learning-data-pipeline-3c83a8838a5a?source=collection_archive---------52----------------------->

在计算机视觉的深度学习领域,有效利用主动学习可以显著提高构建 ML 模型的速度。还可以降低建立 ML 模型的成本。

# **主动学习数据管道**

主动学习数据管道有四个主要部分:

1.  在第一部分中,使用神经网络(NN)版本 n 对新的训练数据进行推理
2.  主题专家评估在步骤 1 中执行的推理的结果。基于这个评估,由主题专家团队发现边缘案例(就像放射学 AI 中的放射科医生)。
3.  人们使用标注工具标注边缘案例。
4.  包括在步骤 2 中发现的边缘情况的新训练数据用于训练 NN 版本 N+1。

[**图片来源:AI 最先进**](https://lexfridman.com/files/slides/2020_01_06_deep_learning_state_of_the_art.pdf)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2d51f64609a009542e789194f5fd0ef9.png)

**主动学习数据管道(** [**来源:人工智能最新技术**](https://lexfridman.com/files/slides/2020_01_06_deep_learning_state_of_the_art.pdf) **)**

# 标记工具在边缘案例发现中的作用

创建地面实况(标注数据集)的过程包括标注专家使用标注工具创建精确的标注。除了提供标注功能,标注工具还可以通过提供其他功能在构建主动学习数据管道中发挥非常重要的作用,例如:

*   允许主题专家查看新训练数据的推断结果。
*   允许主题专家识别和标记当前神经网络版本(版本 N)失败的边缘案例。

标注工具可以通过两种不同的方式提供此功能:

## 选项 1:上传由神经网络版本 N 生成的预注释(PNG 掩码)

数据科学家可以上传显示神经网络版本 N 对新数据推断结果的 PNG 掩码。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/09de87fa00e1a981616f6e199c9ac0e9.png)

上传 PNG 蒙版

## 选项 2:导入神经网络版本 N

导入神经网络版本 N,并允许使用神经网络版本 N 对新的定型数据运行推理。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/63137d6917413bf1786d161594f8d861.png)

标记工具允许边缘案例发现

# 利用 TrainingData.io 构建您的主动学习数据管道

[TrainingData.io](https://www.trainingdata.io) 有一个 SaaS 解决方案,允许主题专家以两种方式查看神经网络的结果:

1.  SaaS 解决方案能够导入您的神经网络,并使用导入的神经网络对新的训练数据进行推理。一旦推理的结果可用,主题专家可以评估结果。
2.  SaaS 解决方案可以导入由神经网络推理生成的 PNG 蒙版。这允许主题专家评估神经网络的结果。

一个好的注释平台不仅能满足注释者的需求,还能帮助人工智能团队与组织中的以下角色协作:

1.  数据科学家
2.  数据经理
3.  注释者(内部和外部)
4.  主题专家(审核者)

[TrainingData.io 使用 NVIDIA Clara 为放射学(DICOM / NIFTI)提供主动学习数据管道。](https://www.trainingdata.io/blog/active-learning-with-nvidia-clara/)

# 如何在 SpaCy 中建立快速的“最相似词”方法

> 原文:<https://towardsdatascience.com/how-to-build-a-fast-most-similar-words-method-in-spacy-32ed104fe498?source=collection_archive---------6----------------------->

## [NLP-in-Production](https://pedram-ataee.medium.com/list/nlpinproduction-98dbb687a868)

## 以及对新发布的名为 Owl 的单词相似性 API 的介绍

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/468e5e6fdbaee795eaac28cf943f99fd.png)

[哈雷戴维森](https://unsplash.com/@harleydavidson?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上的照片

自然语言处理(NLP)的最新发展引入了在生产中必须谨慎使用的语言模型。例如 spaCy 大型英文模型,[*en-core-we b-LG*](https://spacy.io/models/en#en_core_web_lg)**包含 60 多万个 300-d 向量。或者说,预先训练好的[*word 2 vec-Google-news-300*](https://code.google.com/archive/p/word2vec/)模型包含 300 万个 300-d 的单词和短语向量。当您想要计算这些高维向量的度量时,解决方案可能很容易受到计算能力的影响。**

**在这篇文章中,我想分享我是如何加速 spaCy 库以用于单词相似性 API 的。与 Gensim 相反,spaCy 不支持高效的最相似方法。我最近发布了一个单词相似度 API,名为 Owl。这个 API 允许您使用包括 spaCy 在内的各种 word2vec 模型提取与目标单词最相似的单词。给定一个单词,这个 API 返回一个单词组列表,这些单词组与预定义上下文中的原始单词相似,比如 News 或 General。一般语境使用 spaCy 大英语模式。**

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

**[](/word2vec-models-are-simple-yet-revolutionary-de1fef544b87) [## Word2Vec 模型简单而具有革命性

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

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

## —如何使用 spaCy 提取最相似的单词?

没有捷径可走。我必须计算目标单词的向量与 word2vec 模型中存储的大量向量之间的距离。然而,我可以用过滤器**细化搜索空间**,用优化的计算库**加速计算**。

我不需要恢复所有向量。我可以使用 spaCy 提供的`.prob` 属性来修剪向量(即细化搜索空间)。该属性有助于选择英语中最常用的单词`w.prob >= -15`。在这里,您可以使用任何适合您的问题的过滤器。例如,您可能想要使用代表一个单词的阳性或阴性的`.sentiment`属性来过滤向量池。下面的代码展示了如何为 spaCy 构建一个最相似的方法。不过,这段代码并没有进行快速运行的优化。

[来源:**堆栈溢出**](https://stackoverflow.com/questions/57697374/list-most-similar-words-in-spacy-in-pretrained-model)

## —如何使用 spaCy 加速最相似的单词?

延迟是 API 服务中的一个重要因素。我负担不起哪怕 1 秒钟的额外计算时间。因此,我优化了上面解释的最相似的方法,以满足我希望我的 API 满足的需求。

我进行了大量实验,以确定实现中哪些部分最耗时。首先,我怀疑`sort`方法必须修改。对代码进行分析后,我发现`.similarity`方法是延迟的主要来源,必须进行优化。

SpaCy 使用后端的余弦相似度来计算`.similarity`。因此,我决定在上面的`most_similar`方法中,用它的优化的对应物替换`word.similarity(w)`。优化的方法`cosine_similarity_numba(w.vector, word.vector)`使用 Numba 库来加速计算。结果得到了显著改善,即延迟从约 5 秒(API 不可接受)降至约 1.5 秒(API 可接受)。您应该用下面的行替换`most_similar`方法中的第 12 行。

```
by_similarity = *sorted*(queries, key=*lambda* w: **cosine_similarity_numba(w.vector, word.vector)**, reverse=*True*)
```

下面,您可以使用 Numba 库找到余弦相似性的优化实现。根据其文档介绍, [Numba](https://numba.pydata.org/) 是一个开源的 JIT (Just In Time)编译器,可以将 Python 和 NumPy 代码翻译成快速机器码。**这个功能对于以最小的改动加速一个人的代码是至关重要的。**

[来源-媒介](https://medium.com/analytics-vidhya/speed-up-cosine-similarity-computations-in-python-using-numba-c04bc0741750)

## —最好的最相似单词服务是什么?

必须根据结果的上下文和粒度来选择最相似的单词服务。**上下文**由 word2vec 模型表示**,而**粒度**由聚类质量**决定。

[spaCy 大型英语模型](https://spacy.io/models/en#en_core_web_lg)包含在斯坦福大学手套项目培训的[手套普通爬行 word2vec 模型](https://nlp.stanford.edu/projects/glove/)。人们可能希望使用在特定数据语料库上训练的上下文化 word2vec 模型。所以,根据项目需求,必须选择 word2vec 模型。Owl API 让您有机会使用各种 word2vec 模型。

结果的粒度是最相似服务的一个重要特征。在下面,我想比较我在上面介绍的最相似方法和 Owl API 的最终结果。您将看到后一种方法的结果更加细化,因此更加有用。

```
"Owl (en-core-web-lg)": **{** 
0: **[**"seattle", "portland", "washington"**]**,
1: **[**"denver", "chicago", "nashville"**]**,
2: **[**"toronto", "montreal", "ontario", "sydney"**]**  
**}**"spaCy (en-core-web-lg)": **[**
"toronto","seattle","montreal","portland","ontario","denver",
"washington","chicago","sydney","nashville"
**]**
```

[Owl API](https://rapidapi.com/pedram.ataee/api/word-similarity) 建立在一系列 word2vec 模型之上,包括 spaCy *en-core-web-lg* 和高级聚类技术,以创建革命性的单词相似性服务。这个 API 可以用于各种项目,包括语言理解或推荐系统。你可以在这里找到更多关于 Owl API [的信息](https://rapidapi.com/pedram.ataee/api/word-similarity)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f99c0c790510f721656f9ed41925004d.png)

[词语相似度 API (Owl)](https://rapidapi.com/pedram.ataee/api/word-similarity)

[](https://www.amazon.com/gp/product/B08D2M2KV1/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0) [## 人工智能:非正统的教训:如何获得洞察力和建立创新的解决方案

### 亚马逊网站:人工智能:非正统课程:如何获得洞察力和建立创新的解决方案电子书…

www.amazon.com](https://www.amazon.com/gp/product/B08D2M2KV1/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0) 

## 临终遗言

当您想要在生产中使用 NLP 模型时,您必须使用子例程的优化实现来加速计算。例如,在自然语言处理中,余弦相似度经常为各种任务计算。因此,您必须确保它被有效地实现和编译,例如使用 Numba 库。另外,我强烈推荐使用 Owl API。根据需要,您可以从上下文化和粒度化的结果中受益。

# 感谢阅读!

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

*   *跟我上* [*中*](https://medium.com/@pedram-ataee) *!*
*   *在* [*亚马逊*](https://www.amazon.com/Pedram-Ataee/e/B08D6J3WNW) *上查看我的书!*
*   *成为* [*中的一员*](https://pedram-ataee.medium.com/membership) *!*
*   *连接上*[*Linkedin*](https://www.linkedin.com/in/pedrama/)*!*
*   *关注我* [*推特*](https://twitter.com/pedram_ataee) *!*

[](https://pedram-ataee.medium.com/membership) [## 通过我的推荐链接加入 Medium—Pedram Ataee 博士

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

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

# 如何在 10 分钟内构建一个令人惊叹的交互式仪表盘

> 原文:<https://towardsdatascience.com/how-to-build-a-great-dashboard-ee0518c3d3f7?source=collection_archive---------3----------------------->

## 我给有抱负的数据科学家和数据分析师的建议

## 谷歌数据工作室免费提供快速和惊人的可视化!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ceb125fa35f575c24dc050e9ebeb3fd0.png)

使用 Google Data Studio 构建您的交互式仪表盘

> 获得交互式仪表盘的会员资格非常昂贵
> 
> 我在与同事合作我的本地变更时遇到困难
> 
> 仪表盘版本太多,不知道分享哪个

对于数据科学家和分析师来说,将我们的数据和结果传达给非技术用户非常重要。我们需要制作和分享令人惊叹的仪表板,使其易于交互。

虽然 Tableau 和 Qlikview 等 BI 产品有一个简单的界面来产生这种可视化效果,但技术许可费用很高。他们要求会员在你的同事之间私下分享。对于 Tableau,每月花费 50 美元。

> 现在,改变游戏规则的是
> 
> 如果我告诉你,你可以在你的 Google Drive 中使用一个免费的、直观的、可共享的交互式仪表盘工具。
> 
> 欢迎来到谷歌数据工作室

# 谷歌数据工作室是什么?

Google Data Studio 是一个数据可视化工具,用于生成交互式仪表板。借助 Data Studio,您可以:

1.  **导入—可靠地提供实时数据** : JSON/CSV、BigQuery、Sheets 等。
2.  **互动——产生洞察力**:使用拖放方法开发交互式仪表盘。
3.  **分享——提升您的技能**:通过 Google Drive 私下存储、协作和推广您的仪表盘。

> 全部免费。

本教程将帮助您准备使用实时数据开发仪表板。请随意跟随本教程或直接访问[仪表板,在这里](https://datastudio.google.com/reporting/9f6b7856-aa66-4ae0-8864-8abef1e77f6a)您可以复制并亲自尝试..

**附言:**如果您想要一种简单的方式来开发和部署您的仪表板即服务。[我也为 Dash & Plotly 提供一个教程。它们是构建在 Matplotlib 和 Flask 之上的 python 库,是构建 web 的有用框架。](/build-your-own-data-dashboard-93e4848a0dcf)

> 就这样,让我们开始吧。

# 导入:使用 BigQuery 可靠地提供实时数据

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/750e69cdf165aef8c25126917bb95c7f.png)

使用大查询导入实时 JHU 数据

Google BigQuery 提供了一个无服务器的、免费的、高度可扩展的数据仓库系统,可以在几秒钟内分析万亿字节的数据。它易于使用,可扩展,并准备好扫描数据。Google Data Studio 将您的数据连接到许多不同的来源。

在本教程中,我们将导入 JHU(约翰·霍普斯金大学)的 Covid 数据表到我们的仪表板。方便的是,谷歌已经为我们准备好了 JHU 实时数据连接。

在私有设置中,您希望为 BigQuery 设置有限的访问权限,以防止泄漏给您的用户。但是,一旦发布了仪表板,您的用户就可以访问您的报告和见解中的聚合数据。

# 互动:快速产生见解

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/eab1a50bdc985df1d4ea63237b5fd605.png)

构建 Data Studio 仪表板

在 Google Data Studio 中,您可以插入图表并用相关数据(日期/地区)自动填充图表。很多时候,除了滤镜和风格,你不会需要接触规格。

交互分配是自动的。默认情况下,每个日期/组件选择器已经将交互分配给其他可视化。这允许您在一个仪表板中进行切片和切块。

您还可以通过将组件分组来配置交互。

# 分享:跟踪和推广您的惊人仪表板!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d3b9f430f7272e72c404ca83685acbdf.png)

共享定期电子邮件报告

共享 Google Data Studio 仪表板与共享 Google Drive 链接是一样的。您不再需要为您的同事和经理创建本地工作版本。

有了 Google Drive Storage,你将拥有一个私人的真相来源。您可以轻松链接到板载合作者或审阅者。这是通过指定收件人访问的访问链接来实现的,就像使用 Google Docs 一样。

此外,Google Data Studio 使得向您的利益相关者发送重复的电子邮件报告变得更加容易。您可以自由设置定期报告调度和发送您的生活数据给他们。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a42caa936eff5b80a2bcb3a603d7def6.png)

跟踪所有更改的版本历史

云中另一个有用的功能是**版本历史**。在协作中,您可能会忘记我们随着时间的推移所做的更改。版本历史通过为您提供一个统一的版本历史功能来跟踪所有更改,从而防止了这种情况。

有了这个,您可以轻松地审计和恢复到一个稳定的版本,并像往常一样协作。

# 最后的想法

在本教程中,我们了解了 Google Data Studio 的三大优势:

1.  **导入:使用 BigQuery 提供可靠的实时数据**
2.  **互动:快速产生见解**
3.  **分享:跟踪和推广您令人惊艳的仪表盘!**

有了它,您可以将实时数据导入 dashboard,拖放交互式可视化和令人惊叹的样式,并与您的同事和经理轻松分享。

一如既往,如有任何问题,请通过 Linkedin[联系我。如果时间允许,我很乐意回答你的问题。](http://www.linkedin.com/in/vincenttatan/?source=post_page---------------------------)

索利·德奥·格洛丽亚

# 关于作者

文森特用 ML @ Google 对抗网络滥用。文森特使用高级数据分析、机器学习和软件工程来保护 Chrome 和 Gmail 用户。

除了在谷歌的工作,Vincent 还是《走向数据科学媒体》的特约撰稿人,为全球 50 万以上的观众提供有抱负的 ML 和数据从业者的指导。

在空闲时间,文森特在佐治亚理工学院攻读硕士学位,并为铁人三项/自行车旅行进行训练。

最后,请通过 [**LinkedIn**](http://www.linkedin.com/in/vincenttatan/?source=post_page---------------------------) **** [**Medium**](https://medium.com/@vincentkernn?source=post_page---------------------------) **** [**Youtube 频道**](https://www.youtube.com/user/vincelance1/videos?source=post_page---------------------------) 联系文森特

# 与 GatsbyJS 和 Netlify 一起构建一个超棒、超快的数据科学组合

> 原文:<https://towardsdatascience.com/how-to-build-a-kickass-blazing-fast-portfolio-with-gatsbyjs-and-netlify-d1a06cb66712?source=collection_archive---------20----------------------->

## 我如何将我的旧博客转移到一个新的现代网络堆栈

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/01946757275d1a99aa285dfbd2b7f878.png)

今年我想完成的第一件事就是完全重新设计我的博客。这一个是使用基于 Python 的静态站点生成器结合 Flex 主题构建的。

总而言之,它包含了有趣的功能——比如移动响应和 Disqus、AddThis 和 Google Analytics 的插件。而且,最重要的是,它很容易与 Markdown 文件集成,这对于文章写作来说很方便。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5fb43ebd40862b0b47c33250a2839590.png)

我以前的博客

一切正常,直到我注意到一些问题:

## **慢速加载页面**

随着我的帖子越来越长,加载时间也在不断增加。虽然这在桌面上通常不是问题,但移动设备却深受其害。这影响了我的大部分观众——他们主要使用移动设备。

## 有限的主题模板

我使用的模板不允许我展示个人项目和我正在开发的开源工作。添加新页面也不容易。事实上,我不得不深入主题的 HTML 代码,并对其进行调整以满足我的需求。我发现将主题的逻辑从博客的引擎中分离出来是很乏味的。

## 一些代码突出显示问题

嵌入代码片段是我的帖子的重要部分。不幸的是,我注意到一个令人沮丧的呈现问题出现在移动设备上,比如长行代码的换行。说真的,谁愿意读那种代码?

## 一组有限的插件

Pelican 有各种各样的插件,但是其中一些已经过时或者只适用于 Pelican 的特定版本——还有一些功能缺失了。

# 寻找替代方案

所以我开始寻找鹈鹕的替代品。我想的是一个框架,它允许我构建快速加载和响应的页面,同时保持高度的定制化。

那时我听说了盖茨比。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fabe1e28cc5d33a43d44d9a1b79e61c6.png)

盖茨比

> “Gatsby 是一个基于 React 的免费开源框架,可以帮助开发人员构建速度极快的网站和应用。”—gatsbyjs.org

我觉得官方的描述总结的很好。除此之外,让我转而看盖茨比的原因是:

*   它建立在最新的 web 技术之上,比如 React 和 webpack:因此,建立一个新的组合是学习新的前端框架的一个机会
*   Gatsby 可以连接到各种数据源,包括 Markdown 文件、API、数据库等。
*   Gatsby 通过在`public`文件夹中以静态文件的形式构建您的站点,使站点部署变得非常容易,这些文件随后可以被推送到 GitHub、Netlify 或 Amazon Amplify
*   它只加载渲染网站内容所需的关键 HTML、CSS 和 JS,所以点击速度非常快

我们可以继续下去,但说服你自己的唯一方法是尝试,对吗?

# 盖茨比入门

我的目标不是给你一个如何使用 Gatsby 的完整教程:事实上,互联网上有大量的资源。你可以查一下[的官方文件,比如](https://www.gatsbyjs.org/docs/)。

但是这里有一些快速开始的步骤:

## 准备您的环境

*   安装节点和 npm。例如,如果你使用的是 Mac,假设你有自制软件,你可以启动这个命令。

```
brew install node
```

如果你使用的是 Windows 或 Linux 发行版,你可以查看[文档](https://www.gatsbyjs.org/tutorial/part-zero/#-install-nodejs-and-npm)。这很简单。

*   安装 Git
*   通过启动以下命令安装 Gatbsy CLI

```
npm install -g gatsby-cli
```

以下部分借用自[文档](https://www.gatsbyjs.org/tutorial/part-zero/#create-a-gatsby-site):

> 现在您已经准备好使用 Gatsby CLI 工具来创建您的第一个 Gatsby 站点。使用该工具,您可以下载“启动者”(带有一些默认配置的部分构建的站点),以帮助您更快地创建某种类型的站点。您将在这里使用的“Hello World”启动程序是一个启动程序,具有 Gatsby 站点所需的基本要素。
> 
> 打开你的终端。
> 
> 经营盖茨比新 hello-world[https://github.com/gatsbyjs/gatsby-starter-hello-world](https://github.com/gatsbyjs/gatsby-starter-hello-world)。(注意:根据您的下载速度,所需的时间会有所不同。为了简洁起见,下面的 gif 在安装过程中暂停了)。
> 
> 运行`cd hello-world`。
> 
> 运行`gatsby develop`。

差不多就是这样。现在,您有了一个在本地运行的静态网站。尝试修改它的内容,你会看到(保存后)你的修改被实时更新。

## 使用预先存在的模板

如果你不是我这样的前端忍者,可以在官网的 [Showcase 标签](https://www.gatsbyjs.org/showcase/)中查找自己喜欢的模板。

有大量的开源网站和作品集都是使用 Gatsby 构建的。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8b57a84f77b33d828a66b4de045ac5f1.png)

使用 Gatsby 建立的网站和作品集示例

## 盖茨比插件

现在盖茨比框架中最有趣的部分:[盖茨比插件库](https://www.gatsbyjs.org/plugins/)。

如果你想扩展网站的功能,比如添加图像响应、搜索引擎优化、谷歌分析、离线支持、网站地图、robot.txt 等等,你可以在这里找到你需要的一切。

社区充满活力,插件得到了很好的支持。您可以在搜索栏中搜索它们。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/686a2579cad5e51be0fa03b40c7c31fc.png)

盖茨比插件

如果你想让你的博客或作品集有很好的 SEO,我发现了这个 [repo](https://github.com/garrynsk/gatsby-seo-starter) 列举了一系列有用的 Gatsby 插件。

## 部署

一旦您对您的网站满意了,您就可以通过运行项目根目录下的 build 命令来生成准备部署的静态文件。

```
gatsby build
```

这个命令创建一个静态版本的网站,它可以在互联网上运行,并驻留在`public`文件夹中。你既可以把它复制到你的服务器,推送到 GitHub 页面,也可以使用部署服务(比如 [Netlify](https://www.netlify.com/) )。我个人选择 Netlify 是因为我发现它很容易使我的工作流程自动化。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a247c5ef9446b9f86feaaa734d6c080e.png)

网络生活主页

文档很棒,您可以找到许多博客文章,带您完成在 Netlify 上部署 Gatsby 站点的过程。这里有一个来自 gatsbyjs.org 的很棒的[和一个来自 netlify.com 的](https://www.gatsbyjs.org/docs/deploying-to-netlify/)[和一个](https://www.netlify.com/blog/2016/02/24/a-step-by-step-guide-gatsby-on-netlify/)。

## **您可能会有的几个问题**

**那么你以前的帖子会怎么样?**

我的博客从 2016 年就开始直播了,所以我肯定不会把以前的帖子扔掉。幸运的是,在《盖茨比》中把它们改写成减价文件很容易,所以我这样做了。这甚至是一个更好地重组文件夹结构的机会。

**新博客的 URL 结构不同。如果用户点击一个旧的链接会发生什么?**

我使用`gatsby-plugin-netlify`通过指定新旧 URL 之间的映射来创建永久的 URL 重定向(使用 301 HTTP 代码)。当执行构建命令时,这个插件在`public`文件夹的根目录下生成一个`_redirects`文本文件,该文件写下这个映射并告诉 Netlify 正确执行这些重定向。我发现这个解决方案非常方便。

下面是一个`_redirects`文件的例子:

新旧 URL 之间的映射

**你以前的 Disqus 评论怎么了?他们会迷路吗?**

希望不会。Disqus 提供名为 URL Mapper 的迁移服务,需要手动输入新旧 URL 之间的 CSV 映射。

这里有一个[教程](https://help.disqus.com/en/articles/1717129-url-mapper)带你完成这个过程。

**谷歌分析怎么样?你是创建一个新账户还是保留旧账户?**

我搜索了一下这个问题的答案,发现一个堆栈溢出[线程](https://stackoverflow.com/questions/21351113/how-to-keep-stats-of-changed-urls-structure-in-google-analytics)在谈论这个问题。

推荐的解决方案是…什么都不做。你只需要在你的新网站上重复使用你的旧账户。

你的 AddThis 账户怎么样?你会失去之前在社交分享上的统计数据吗?

很遗憾,是的。AddThis 以不同的方式处理每个 URL,它无法判断新的 URL 应该被视为旧的 URL。

# 那么新网站看起来怎么样呢?

可以在 GIF 中查看。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/76ff8746e159dd84b9149b129879f221.png)

如果你想建立自己的网站,你知道你现在要做什么。

感谢阅读!

📝将这个故事保存在[期刊](https://usejournal.com/?utm_source=medium.com&utm_medium=noteworthy_blog&utm_campaign=tech&utm_content=guest_post_read_later_text)中。

👩‍💻每周日早上醒来,你的收件箱里会有本周最值得关注的科技新闻。[阅读科技简讯](https://usejournal.com/newsletter/noteworthy-in-tech/?utm_source=medium.com&utm_medium=noteworthy_blog&utm_campaign=tech&utm_content=guest_post_text)中值得注意的内容。

# 如何从头开始构建 KNN 分类模型,并使用 Streamlit 对其进行可视化

> 原文:<https://towardsdatascience.com/how-to-build-a-knn-classification-model-from-scratch-and-visualize-it-using-streamlit-9fe8059cc418?source=collection_archive---------29----------------------->

## 虽然像 sklearn 这样的图书馆让我们的生活变得更加容易,但是从头开始制作一个模型总是一个好的实践。在本教程中,我们将从头构建一个 KNN 分类模型,并使用 Streamlit 构建一个 web 应用程序对其进行可视化。下面是最终应用程序的演示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7ee15d192cfac0c3943c37bc28a9bfe3.png)

最终 Streamlit 应用的截屏

# KNN 概述

KNN 或 K 近邻用于分类和回归。在本教程中,我们将使用它进行分类。由于目标标签是已知的,所以这是一种有监督的算法。它本质上接受一个输入,并找到 K 个最接近它的点。然后检查最近点的标注,并将输入分类为出现次数最多的标注。假设我们想要建立一个模型,根据输入的体重、身高将动物分类为狗或猫。如果 K = 3,我们找到离输入最近的 3 个点并检查它们的标签。如果 3 个最近点中的 2 个有标签“狗”,我们的模型将输入分类为“狗”。如果 3 个最近的点中的 2 个有标签“猫”,我们的模型将输入分类为“猫”

## 步伐

*   标准化数据集并存储它,即确保所有值都在 0 和 1 之间。
*   取一个输入数据点,并从数据集中的所有记录中找出距离。将距离存储在列表中。
*   对包含距离的列表进行排序,并检查排序列表中前 K 条记录的标签
*   将输入分类为在前 K 条记录中出现次数最多的标签

> 首先,我们将创建所有我们需要的助手函数。然后我们再把它们结合起来,加入一些 streamlit 函数,构建一个 web app。

为了便于理解和可视化,我们将使用具有 2 个要素和二进制标签(即“0”和“1”)的数据集。

# **助手功能**

## 标准化数据的函数

为了规范化一个值列表,我们迭代每个值,并找到列表中的值和最小值之间的差。然后我们将它除以列表中最大值和最小值的差。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bec07d2d5ded925871d00b1eb7794c5d.png)

标准化数据的方程式

```
*def* **min_max_normalize(*lst*)**:
    minimum = min(lst)
    maximum = max(lst)
    normalized = [(val - minimum)/(maximum - minimum) for val in 
    lst]                               
    return normalized
```

该函数接受一个值列表,并返回规范化的值

## 计算欧几里德距离的函数

该函数将用于计算两个给定点之间的距离。我们将使用欧几里德公式来计算距离。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7159b9c266355dcde8c1d35559084213.png)

计算欧几里德距离的公式

```
*def* **distance(*element1* , *element2*):**
    x_distance = (element1[0] - element2[0])**2
    y_distance = (element1[1] - element2[1])**2
    return (x_distance + y_distance)**0.5
```

该函数接受两个 2D 点,并返回它们之间的欧几里得距离。由于我们考虑的数据集只有两个要素,因此我们只考虑 x 和 y 坐标。随着特征数量的增加,该函数将需要改变以找到所有指数之间的平方差。

## **查找输入点和数据集中所有点之间距离的函数**

我们迭代数据集中的每个值,并使用上面的 ***距离*** 函数来计算两点之间的距离。然后,我们存储距离并进行排序。

```
*def* **find_nearest(*x* , *y* , *input* , *k*):** distances = []
    for id,element in enumerate(x):
        distances.append([distance(input , element),id])
    distances = sorted(distances)
    predicted_label = get_label(distances[0:k] , y)
    return predicted_label, distances[0:k] , distances[k:]
```

该函数将以下参数作为输入:

*   **x:** 这是包含这两个特征的数据集
*   **y:** 这包含了 **x** 中每一行的标签。它们是分别映射的,即 **x[i]** 的标签是 **y[i]**
*   **输入:**这是一个 2D 数组,包含我们想要分类的点的特征
*   k: 我们希望模型考虑的最近邻的数量

首先,我们创建一个空数组来存储距离。我们需要在数据集中存储记录的距离和索引。该索引可以在 **y** 数组中使用,以找到该记录的标签。

然后我们对距离进行排序。接下来,我们使用 **get_label** 函数(将在下面讨论)来获取最常出现的标签。

由于**距离**数组被排序,前 k 个元素,即**距离【0:k】**是我们输入的 k 个最近邻。我们返回输入的预测标签、k 个最近的邻居和其余的邻居。

## **查找最常出现的标签的功能**

我们基本上得到 k 个最近的邻居,检查每个邻居的标签。在我们的例子中,我们只有两个标签“0”和“1”。如果邻居的标签是“0 ”,我们对“0”的出现增加计数,并对“1”进行同样的操作。我们比较两个标签出现的次数,并返回计数较高的标签。

```
*def* **get_label(*neighbours*, *y*):** zero_count , one_count = 0,0
    for element in neighbours:
      if y[element[1]] == 0:
         zero_count +=1
      elif y[element[1]] == 1:
         one_count +=1
    if zero_count == one_count:
         return y[neighbours[0][1]]
    return 1 if one_count > zero_count else 0
```

该函数将 k 个最近邻作为输入。**邻居**中的每条记录都包含距输入点的距离及其原始 id。我们使用 id 和 y 数组来获取记录的标签。然后我们检查标签并返回预测的标签。

> 我们已经创建了所需的助手函数。现在我们将它们与一些 streamlit 函数结合起来。令人兴奋的东西!😎

# 必需的库

我们将使用 Plotly 来绘制我们的图形,因为 Plotly 绘制交互式图形。对于我们的数据集,我们将从 sklearn.datasets 导入一个数据集。

```
import streamlit as st
import pandas as pd
from sklearn.datasets import make_blobs
import plotly.express as px
import plotly.graph_objects as go
```

我将把教程的剩余部分分成三个部分

1.  用户输入
2.  导入数据集并将其可视化
3.  可视化预测

# 用户输入

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a22fc0a36f18bf9b7f985c58cf50c664.png)

App 截图

我们将使用 streamlit 的 **title** 方法显示一个标题,使用 **slider** 方法创建一个数字滑块来获取用户的输入。由于我们的数据是标准化的,我们希望输入也是标准化的。因此,我们限制用户输入 0 到 1 之间的值。我们还可以从用户那里获取输入,并使用数据集中的最小和最大值来规范化输入。

```
st.title("KNN Visualize")x_input = st.slider("Choose X input", *min_value*=0.0, *max_value*=1.0,*key*='x')y_input = st.slider("Choose Y input", *min_value*=0.0, *max_value*=1.0,*key*='y')k = st.slider("Choose value of K", *min_value*=1, *max_value*=10,*key*='k')input = (x_input,y_input)
```

每次滑块值更改时,整个 python 脚本都会重新运行,变量将根据滑块包含新值。

# 导入数据集并将其可视化

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4861da26ee8af2e7edc4c203ad2f28cc.png)

App 截图

```
x , y = make_blobs(*n_samples* = 100 , *n_features* = 2 , *centers* = 2, *random_state*= 2)
```

**make_blobs** 函数为我们创建了一个数据集,它看起来类似于上图中的分布。在现实世界中,数据集不会如此合作,但这个数据集现在已经足够了。我建议你使用 **matplotlib** 绘制一个散点图,看看数据的分布情况。

**x** 包含特性, **y** 包含各自的标签

```
# Normalizing Data
x[:,0] = min_max_normalize(x[:,0])
x[:,1] = min_max_normalize(x[:,1])# Dataframe
df = pd.DataFrame(x , *columns* = ['Feature1' , 'Feature2'] )
df['Label'] = yst.dataframe(df)
```

首先,我们使用之前创建的规范化辅助函数来规范化我们的数据。然后我们结合 x 和 y 数组来创建一个数据帧。我们使用 streamlit 的**数据帧**方法来查看数据帧。

```
# Initial Data Plotfig = px.scatter(df, *x* = 'Feature1' , *y*='Feature2', *symbol*='Label',*symbol_map*={'0':'square-dot' , '1':'circle'})fig.add_trace(
    go.Scatter(*x*= [input[0]], *y*=[input[1]], *name* = "Point to  Classify", )
)st.plotly_chart(fig)
```

你可以阅读 [Plotly 的文档](https://plotly.com/python/line-and-scatter/)来更好的理解上面的代码。我们用刚刚创建的数据帧的散点图创建一个图形。我们还添加了输入点,以便更好地理解它相对于数据集中其他点的位置。Streamlit 的 **plotly_chart** 方法以 plotly 图形为参数,在我们的 app 上绘制交互图形。

# **预测并可视化它**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0e541cd7f8e958ae75956d8e05b4a1d5.png)

App 截图

```
#Finding Nearest Neighbourspredicted_label , nearest_neighbours, far_neighbours = find_nearest(x ,y , input ,k)st.title('Prediction')st.subheader('Predicted Label : {}'.format(predicted_label))
```

我们使用我们之前创建的 find_nearest 函数来获得预测的标签和 id、k 个最近邻居和远邻居的距离。

我们显示预测的标签 us streamlit 的**子标题**方法

```
nearest_neighbours = [[neighbour[1],x[neighbour[1],0],x[neighbour[1],1],neighbour[0],y[neighbour[1]]] for neighbour in nearest_neighbours]nearest_neighbours = pd.DataFrame(nearest_neighbours , *columns* = ['id','Feature1','Feature2','Distance','Label'])st.dataframe(nearest_neighbours)
```

上述代码基本上使用最近邻的 id,并将 id、距离与记录及其标注的 feature1、feature2 值相结合。我们使用组合列表来创建包含最近邻居信息的数据帧。然后我们使用 streamlit 的 dataframe 方法来显示它。这个数据框架将帮助我们理解下面的图表。

```
far_neighbours = [[neighbour[1],x[neighbour[1],0],x[neighbour[1],1],neighbour[0],y[neighbour[1]]] for neighbour in far_neighbours]far_neighbours = pd.DataFrame(far_neighbours , *columns* = ['id','Feature1','Feature2','Distance','Label'])fig2 = px.scatter(far_neighbours,*x*='Feature1',*y*='Feature2',*symbol*='Label',*symbol_map*={'0':'square-dot' , '1':'circle'})
```

我们为远邻居创建一个类似的数据帧。我们使用 Plotly 来绘制散点图。我们现在将添加输入和将输入连接到其 k 个最近邻居的线。

```
for index,neighbour in nearest_neighbours.iterrows():
    fig2.add_trace(
       go.Scatter( *x*=[input[0], neighbour['Feature1']], *y*=[input[1],
       neighbour['Feature2']],*mode*='lines+markers' , *name* = 'id
       {}'.format(*int*(neighbour['id'])) )
    )st.plotly_chart(fig2)
```

我们迭代每个邻居,并在邻居和我们创建的图形的输入点之间添加一条线。最后,我们使用 **plotly_chart** 方法绘制图形。

> 就这样👏我们从头开始创建了一个 KNN 分类器,并创建了一个 Streamlit 应用程序来可视化它

如果您有兴趣部署您的 streamlit 应用程序,请查看我的教程。

你可以在这里找到 GitHub 回购[](https://github.com/rahulbanerjee26/KNN-Streamlit)

**我对机器学习的世界还是相当陌生的,如果你发现任何错误或任何可以优化的代码,请让我知道!我总是乐于接受反馈😃**

我最近用 WordPress 创建了一个博客,如果你能看看的话,我会很高兴的😃

 [## Python 项目教程-使用这些 Python 项目教程改进您的简历/作品集。

### 使用 Streamlit 共享部署您的机器学习 Web 应用程序在我以前的文章中,我谈到过构建一个…

realpythonproject.com](https://realpythonproject.com/) 

在 LinkedIn 上与我联系

[](https://www.linkedin.com/in/rahulbanerjee2699/) [## Rahul baner JEE——产品工程实习生——EY | LinkedIn

### 查看 Rahul Banerjee 在世界上最大的职业社区 LinkedIn 上的个人资料。拉胡尔有 4 个工作列在他们的…

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

在 Twitter 上与我联系

# 如何建立机器学习模型

> 原文:<https://towardsdatascience.com/how-to-build-a-machine-learning-model-439ab8fb3fb1?source=collection_archive---------4----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4d4bf6e6b97eea54f2e1df56bc0ed66c.png)

**关于建立机器学习模型的卡通信息图。**(由 Chanin Nantasenamat 绘制)

## [数据科学](https://medium.com/tag/data-science) | [机器学习](https://medium.com/tag/machine-learning)

## 学习数据科学的可视化指南

学习数据科学可能看起来令人生畏,但事实并非如此。让我们让学习数据科学变得有趣而简单。因此,挑战在于我们如何让学习数据科学变得既有趣又简单?

漫画很有趣,既然“*一张图胜过千言万语”*,那么为什么不制作一部关于数据科学的漫画呢?带着这个目标,我开始在我的 iPad 上涂鸦构建机器学习模型所需的元素。过了几天,上面显示的信息图是我想出来的,也发表在了 LinkedIn 和[数据教授 GitHub](https://github.com/dataprofessor/infographic) 上。

# 资料组

数据集是您构建机器学习模型之旅的起点。简单地说,数据集本质上是一个 **M** × **N** 矩阵,其中 **M** 表示列(特征),而 **N** 表示行(样本)。

列可以分解为 **X** 和 **Y** 。首先, **X** 是特征、自变量、输入变量等几个相似术语的同义词。其次, **Y** 也是类标、因变量、输出变量几个术语的同义词。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/229515eecf702ca414e372a1ff23e380.png)

**一个数据集的卡通插图。**(由 Chanin Nantasenamat 绘制)

应当注意,可用于*(可执行回归或分类)的数据集将包含 **X****Y** ,而可用于 ***无监督学习*** 的数据集将只有 **X** 。*

*此外,如果 **Y** 包含定量值,则数据集(由 **X****Y** 组成)可用于*任务,而如果 **Y** 包含定性值,则数据集(由 **X** 和 **Y** 组成)可用于 ***分类任务*****

# **探索性数据分析**

**进行探索性数据分析(EDA)是为了获得初步的理解,并让我们熟悉数据集。在一个典型的数据科学项目中,我首先要做的事情之一就是**执行 EDA 来“目测数据”*,以便更好地理解数据。***

**我通常使用的三种主要 EDA 方法包括:**

*   ****描述性统计** —均值、中位数、众数、标准差**
*   ****数据可视化** —热图(识别特征内部相关性)、箱线图(可视化组差异)、散点图(可视化特征之间的相关性)、主成分分析(可视化数据集中呈现的聚类分布)等。**
*   ****数据整形** —透视数据、分组数据、过滤数据等。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/80ca47e4696e5deb76735c474e67ad24.png)**

****NBA 球员统计数据的示例方框图。**从 [Jupyter 笔记本上获得的关于 GitHub 教授的数据](https://github.com/dataprofessor/code/blob/master/python/pandas_exploratory_data_analysis.ipynb)。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f175d8d20363ada2d74538ff3e1be851.png)**

****NBA 球员统计数据的示例关联热图。**从 [Jupyter 笔记本上获得的剧情数据 GitHub 教授](https://github.com/dataprofessor/code/blob/master/python/pandas_exploratory_data_analysis.ipynb)。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e2c077cbe46fbf72246af7f0cda6a4b3.png)**

****NBA 球员统计数据的柱状图示例。**从 [Jupyter 笔记本上获得的剧情资料 GitHub](https://github.com/dataprofessor/code/blob/master/python/pandas_exploratory_data_analysis.ipynb) 教授。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8a592fa8afb623d27b9cf2560cad052f.png)**

****NBA 球员统计数据散点图示例。**从 [Jupyter 笔记本上获得的剧情资料 GitHub 教授](https://github.com/dataprofessor/code/blob/master/python/pandas_exploratory_data_analysis.ipynb)。**

**要获得更多关于用 Python 执行这些[探索性数据分析的分步教程,请查看我在](https://www.youtube.com/watch?v=9m4n2xVzk9o) [Data Professor YouTube 频道](https://www.youtube.com/dataprofessor/)上制作的视频。**

# **数据预处理**

**数据预处理(也称为数据清理、数据争论或数据篡改)是对数据进行各种检查和审查的过程,以便纠正缺失值、拼写错误、标准化/标准化值以使其具有可比性、转换数据(如对数转换)等问题。**

> **“垃圾进,垃圾出。”
> —乔治·富希塞尔**

**正如上面的引用所表明的,数据的质量将对生成的模型的质量产生很大的影响。因此,为了实现最高的模型质量,应在数据预处理阶段投入大量精力。据说,数据预处理很容易占据数据科学项目所用时间的 80%,而实际的模型构建阶段和随后的模型后分析占据了剩余的 20%。**

# **数据分割**

## **列车测试分离**

**在机器学习模型的开发中,希望经过训练的模型在新的、看不见的数据上表现良好。为了模拟新的、看不见的数据,可用数据经受*数据分割,由此它被分割成 2 部分(有时称为 ***训练测试分割*** )。特别地,第一部分是较大的数据子集,用作*(例如占原始数据的 80%),第二部分通常是较小的子集,用作*(剩余的 20%数据)。应当注意,这种数据分割被执行一次。*****

***接下来,训练集用于建立预测模型,然后将这样的*训练模型*应用于测试集(*即*用作新的、未见过的数据)以进行预测。最佳模型的选择是基于模型在测试集上的性能做出的,并且在努力获得最佳可能模型的过程中,也可以执行超参数优化。***

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/98dec057a2776700a45f3371a6e2869a.png)**

## **训练-验证-测试分割**

*****数据拆分*** 的另一种常用方法是将数据拆分成 3 部分:(1)训练集,(2)验证集,(3)测试集。与上文所述类似,训练集用于构建预测模型,也在*验证集上进行评估,从而进行预测、模型调整(例如超参数优化)并根据验证集的结果选择最佳性能模型。正如我们所看到的,类似于上面对测试集执行的操作,这里我们对验证集执行相同的过程。注意 ***测试集*** 不涉及任何模型的建立和准备。因此,测试集可以真正充当新的、看不见的数据。谷歌的机器学习速成班对这个话题进行了更深入的探讨。***

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c6b0e0a7736aa1b81b4ef3930aa0cc68.png)**

## **交叉验证**

**为了最经济地使用可用数据,通常使用*N 重交叉验证(CV),从而将数据集划分为 *N 重*(**通常使用 5 重或 10 重 CV)。在这样的 *N* 褶皱 CV 中,其中一个褶皱被遗漏作为测试数据,而剩余的褶皱被用作建模的训练数据。***

**例如,在一个 5 折 CV 中,1 折被遗漏并用作测试数据,而剩余的 4 折被汇集在一起并用作建模的训练数据。然后将训练的模型应用于前述的遗漏折叠(*即*测试数据)。这个过程反复进行,直到所有的折叠都有机会作为测试数据被忽略。因此,我们将构建 5 个模型(即,5 个折叠中的每一个都作为测试集被排除),其中 5 个模型中的每一个都包含相关的性能指标(我们将在接下来的部分中讨论)。最后,指标值基于从 5 个模型中计算出的平均性能。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9b1f77577c3058d34ebb851cf3d7a1e4.png)**

**在 *N* 等于数据样本数的情况下,我们称之为 ***留一交叉验证*** 。在这种类型的 CV 中,每个数据样本代表一个折叠。例如,如果 *N* 等于 30,则有 30 个折叠(每个折叠 1 个样本)。与任何其他 *N* 折叠 CV 一样,1 个折叠被排除作为测试集,而剩余的 29 个折叠用于构建模型。接下来,应用建立的模型对遗漏褶皱进行预测。如前所述,该过程迭代执行总共 30 次;并且计算 30 个模型的平均性能并用作 CV 性能度量。**

# **模型结构**

**现在,有趣的部分来了,我们终于可以使用精心准备的数据来建立模型了。根据目标变量(通常称为 **Y** 变量)的数据类型(定性或定量),我们将建立一个分类(如果 **Y** 是定性的)或回归(如果 **Y** 是定量的)模型。**

## **学习算法**

**机器学习算法可以大致分为三种类型:**

1.  ***监督学习* —是一个机器学习任务,它在输入 **X** 和输出 **Y** 变量之间建立数学关系。这样的 **X** , **Y** 对构成了用于建模的标记数据,以学习如何从输入预测输出。**
2.  ***无监督学习* —是一项机器学习任务,仅利用输入的 **X** 变量。这种 **X** 变量是学习算法在建模数据的固有结构时使用的未标记数据。**
3.  ***强化学习* —是一种机器学习任务,它决定下一步的行动,并通过试错学习来实现这一点,以努力实现回报的最大化。**

## **超参数优化**

**超参数本质上是直接影响学习过程和预测性能的机器学习算法的参数。由于不存在适用于所有数据集的“一刀切”的超参数设置,因此需要执行 ***超参数优化*** (也称为*超参数调整*或*模型调整*)。**

**我们以随机森林为例。在使用 **randomForest** R 包时,通常需要进行优化的两个常见超参数包括`mtry`和`ntree`参数(这对应于`RandomForestClassifier()`中的`n_estimators`和`max_features`以及 **scikit-learn** Python 库中的`RandomForestRegressor()`函数)。`mtry` ( `max_features`)表示在每次分割时随机抽样作为候选的变量的数量,而`ntree` ( `n_estimators`)表示要生长的树的数量。**

**另一种流行的机器学习算法是支持向量机。要优化的超参数是径向基函数(RBF)核的`C`和`gamma`参数(即,线性核只有`C`参数;多项式内核的`C`和`exponential number`)。`C`参数是限制过拟合的惩罚项,而`gamma`参数控制 RBF 核的宽度。如上所述,通常进行调整以达到用于超参数的最佳值集,尽管如此,仍有研究致力于寻找`C`和`gamma`参数的良好初始值( [Alvarsson 等人,2014 年](https://pubs.acs.org/doi/10.1021/ci500344v))。**

## **特征选择**

**顾名思义,特征选择就是从最初的大量特征中选择特征子集的过程。除了实现高度准确的模型之外,机器学习模型构建的一个最重要的方面是获得可操作的见解,为了实现这一点,能够从大量特征中选择重要特征的子集是很重要的。**

**特征选择的任务本身可以构成一个全新的研究领域,在这个领域中,人们正在努力设计新的算法和方法。在众多可用的特征选择算法中,一些经典方法基于*模拟退火*和*遗传算法*。除此之外,还有大量基于*进化算法*的方法(如粒子群优化、蚁群优化等)。)和*随机方法*(如蒙特卡洛)。**

**我们自己的研究小组也探索了在醛糖还原酶抑制剂的定量结构活性关系建模研究中使用蒙特卡罗模拟进行特征选择( [Nantasenamat 等人,2014](https://doi.org/10.1016/j.ejmech.2014.02.043) )。在我们的课题 [*遗传算法搜索空间拼接粒子群算法作为通用优化器*](https://doi.org/10.1016/j.chemolab.2013.08.009) ( [李*等* 2013](https://doi.org/10.1016/j.chemolab.2013.08.009) )中,我们还设计了一种基于结合两种流行的进化算法即遗传算法和粒子群算法的新的特征选择方法。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6483e07b8ce75732c35245aa108035d9.png)**

****遗传算法搜索空间拼接粒子群优化(GA-SSS-PSO)方法的原理示意图,如在 2 维中使用 Schwefel 函数所示。**“原搜索空间(a)*x*∈[–500,0]在每个维度上以 2 的固定间隔拼接成子空间(图中一个维度等于一个横轴)。这产生了四个子空间(b–e ),其中每个维度上的 *x* 的范围是原来的一半。GA 的每个字符串编码一个子空间的索引。然后,GA 启发式地选择一个子空间(e ), PSO 在那里启动(粒子显示为红点)。PSO 搜索子空间的全局最小值,并且最佳粒子适应度被用作编码该子空间的索引的 GA 串的适应度。最后,遗传算法进行进化,选择一个新的子空间进行探索。重复整个过程,直到达到令人满意的误差水平。”(转载自化学计量学与智能实验室系统,第 128 卷,遗传算法搜索空间拼接粒子群优化作为通用优化器,第 153–159 页,版权(2013),经爱思唯尔许可)**

# **机器学习任务**

**监督学习中两个常见的机器学习任务包括分类和回归。**

## **分类**

**经过训练的分类模型将一组变量(定量或定性的)作为**输入**,并预测**输出**类别标签(定性的)。下图显示了由不同颜色和标签表示的三个类别。每个彩色小球代表一个数据样本,每个样本**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/600d58d59d33c5933aa9532734a00a20.png)**

****多类分类问题示意图。**三类数据样本以二维方式显示。此图显示了数据样本的假设分布。这种可视化图可以通过执行 PCA 分析和显示前两个主成分(PCs)来创建;或者,也可以选择并可视化两个变量的简单散点图。(由 Chanin Nantasenamat 绘制)**

## **示例数据集**

****企鹅** **数据集**(最近被提议作为大量使用的**虹膜数据集**的替代数据集)为例,其中我们将 ***定量*** (喙长、喙深、鳍长以及体重)和 ***定性*** (性别和岛屿)特征作为输入,这些特征唯一地描述了企鹅的特征,并将其分类为三个 ***物种*** 中的一个数据集由 344 行和 8 列组成。先前的分析显示,数据集包含 333 个完整病例,其中 19 个缺失值出现在 11 个不完整病例中。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f62bab2345c540bd142775fd05fd8c46.png)**

**[@allison_horst](http://twitter.com/allison_horst) 作品**

## **性能指标**

**我们如何知道我们的模型何时表现好或坏?答案是使用性能指标,评估分类性能的一些常用指标包括准确性(Ac)、敏感性(Sn)、特异性(Sp)和马修相关系数(MCC)。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d45ac4caf0738e1c83d57a3b7998bff8.png)**

**计算精度的公式。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2a1d70b22d2371639dfbe5a5b3086624.png)**

**计算灵敏度的公式。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/376395b54ec1d0636a790fdc8e743cb5.png)**

**计算特异性的方程式。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2e7e8043322c02e7e9ec580edf6fd563.png)**

**计算马修斯相关系数的方程式。**

**其中 TP、TN、FP 和 FN 分别表示真阳性、真阴性、假阳性和假阴性的情况。应当注意,MCC 的范围为 1 至 1,MCC 为 1 表示最差预测,值为 1 表示最佳预测。此外,0 的 MCC 表示随机预测。**

## **回归**

**简而言之,一个训练好的回归模型可以用下面的简单等式来最好地概括:**

**`Y=f(X)`**

**其中 **Y** 对应于定量的**输出**变量, **X** 指的是**输入**变量, **f** 指的是映射函数(从训练模型中获得),用于计算作为输入特征函数的输出值。回归示例的上述等式的本质是,如果已知 **X** ,则可以推导出 **Y** 。一旦计算出 **Y** (我们也可以称之为“预测”),可视化结果的一个流行方法是绘制一个实际值与预测值的简单散点图,如下所示。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/268dab48e1b1ecf060f80f576020fbe6.png)**

****实际值与预测值的简单散点图。**(由 Chanin Nantasenamat 绘制)**

## **示例数据集**

**波士顿住房数据集是数据科学教程中常用的示例数据集。数据集由 506 行和 14 列组成。为简明起见,下面显示的是标题(显示变量的名称)加上数据集的前 4 行。**

**在 14 列中,前 13 个变量被用作**输入**变量,而中值房价(`medv`)被用作**输出**变量。可以看出,所有 14 个变量都包含定量值,因此适合于回归分析。我还做了一个一步一步的 YouTube 视频,展示了如何用 Python 构建一个[线性回归模型。](https://www.youtube.com/watch?v=R15LjD8aCzc)**

**在视频中,我首先向您展示了如何读取波士顿住房数据集,将数据分离为 X 和 Y 矩阵,执行 80/20 数据分割,使用 80%子集构建线性回归模型,并应用训练好的模型对 20%子集进行预测。最后,显示了实际值与预测值`medv`的性能指标和散点图。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0c6c1875daf2cabfa43747b54f543c06.png)**

****测试集(20%子集)的实际与预测 medv 值的散点图。**剧情摘自 [Jupyter 笔记本上的数据 GitHub 教授](https://github.com/dataprofessor/code/blob/master/python/linear_regression.ipynb)。**

## **性能指标**

**执行回归模型的性能评估是为了评估拟合模型能够准确预测输入数据值的程度。**

**评估回归模型性能的常用度量是 ***决定系数*** (R)。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fbe2078ad91503141b0011fb5912848f.png)**

**从等式中可以看出,R 基本上等于 1 减去残差平方和与总平方和之比。简而言之,它可以说是解释方差的相对度量。例如,如果 R = 0.6,则意味着该模型可以解释 60%的方差(**,即 60%的数据符合回归模型),而未解释的方差占剩余的 40%。**

**另外,*以及 ***均方根误差【RMSE】***也是预测残差或误差的常用度量。***

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e2622f44d94dfe00be455a9287630b2e.png)**

**从上式可以看出,MSE 顾名思义,通过取误差平方的平均值就可以很容易地计算出来。此外,MSE 的简单平方根产生 RMSE。**

# **分类过程的直观解释**

**现在让我们再来看看分类模型的整个过程。以企鹅数据集为例,我们可以看到,企鹅可以由 4 个定量特征和 2 个定性特征来表征,这些特征然后被用作训练分类模型的输入。在训练模型时,需要考虑的一些问题包括:**

*   **用什么机器学习算法?**
*   **超参数优化应该探索什么样的搜索空间?**
*   **使用哪种数据拆分方案?80/20 分成还是 60/20/20 分成?还是 10 倍 CV?**

**一旦模型被训练,产生的模型可以用于对类别标签进行预测(*即*在我们的例子中是企鹅种类),其可以是三种企鹅种类中的一种:阿德利、下巴带或巴布亚企鹅。**

**除了仅执行分类建模,还可以执行主成分分析(PCA),这将仅利用 X(独立)变量来辨别数据的潜在结构,这样做将允许固有数据聚类的可视化(如下所示为假设图,其中聚类根据 3 个企鹅物种进行颜色编码)。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5b21678a1b792770d53ea58ec53bf20e.png)**

****建立分类模型的流程示意图。**(由 Chanin Nantasenamat 绘制)**

## **[订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费内容)!](http://newsletter.dataprofessor.org/)**

# **关于我**

**我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名[数据教授](http://bit.ly/dataprofessor/))制作关于数据科学的在线视频。在我制作的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本([数据教授 GitHub 页面](https://github.com/dataprofessor/))。**

**[](https://www.youtube.com/dataprofessor?sub_confirmation=1) [## 数据教授

### 数据科学、机器学习、生物信息学、研究和教学是我的激情所在。数据教授 YouTube…

www.youtube.com](https://www.youtube.com/dataprofessor?sub_confirmation=1) 

## 在社交网络上与我联系

✅YouTube:[http://youtube.com/dataprofessor/](http://youtube.com/dataprofessor/)
♇网站:[http://dataprofessor.org/](https://www.youtube.com/redirect?redir_token=w4MajL6v6Oi_kOAZNbMprRRJrvJ8MTU5MjI5NjQzN0AxNTkyMjEwMDM3&q=http%3A%2F%2Fdataprofessor.org%2F&event=video_description&v=ZZ4B0QUHuNc)(在建)
♇LinkedIn:[https://www.linkedin.com/company/dataprofessor/](https://www.linkedin.com/company/dataprofessor/)
♇Twitter:[https://twitter.com/thedataprof](https://twitter.com/thedataprof)
♇Facebook:[http://facebook.com/dataprofessor/](https://www.youtube.com/redirect?redir_token=w4MajL6v6Oi_kOAZNbMprRRJrvJ8MTU5MjI5NjQzN0AxNTkyMjEwMDM3&q=http%3A%2F%2Ffacebook.com%2Fdataprofessor%2F&event=video_description&v=ZZ4B0QUHuNc)
♇github:[https://github.com/dataprofessor/](https://github.com/dataprofessor/)
♇insta gram:**

# 如何通过 5 个步骤建立一个识别信用卡欺诈的机器学习模型

> 原文:<https://towardsdatascience.com/how-to-build-a-machine-learning-model-to-identify-credit-card-fraud-in-5-stepsa-hands-on-modeling-5140b3bd19f1?source=collection_archive---------19----------------------->

## 使用 Kaggle 数据集的实际建模指南

随着电子商务和数字交易的激增,身份欺诈也已上升到每年影响数百万人。2019 年,仅美国的欺诈损失估计约为 169 亿美元,其中很大一部分包括信用卡欺诈损失。

除了加强网络安全措施,金融机构越来越多地转向机器学习,以在欺诈交易发生时识别和拒绝欺诈交易,从而限制损失。

我在 Kaggle 上偶然发现了一个[信用卡欺诈数据集](https://www.kaggle.com/mlg-ulb/creditcardfraud),并建立了一个分类模型来预测欺诈交易。在本文中,我将通过 5 个步骤来构建一个有监督的机器学习模型。下面是五个步骤的概要:

1.  探索性数据分析
2.  列车测试分离
3.  建模
4.  超参数调谐
5.  评估最终模型性能

# 一.探索性数据分析

当开始一个新的建模项目时,为了理解数据集,从 EDA 开始很重要。在这种情况下,来自 Kaggle 的信用卡欺诈数据集包含 284,807 行 31 列。这个特定的数据集不包含空值,但是请注意,在处理现实中的数据集时,情况可能并非如此。

我们的目标变量被命名为`class`,它是 0 和 1 的二进制输出,1 代表欺诈交易,0 代表非欺诈交易。剩余的 30 列是我们将用来训练我们的模型的特征,其中绝大多数已经使用 PCA 进行了转换,因此是匿名的,而只有两列(`time`和`amount`)被标记。

## 目标变量

我们的数据集非常不平衡,因为数据集中的大多数行(99.8%)都是非欺诈性交易,并且有一个`class = 0`。欺诈交易仅占数据集的约 0.2%。

这种类别不平衡问题在欺诈检测中很常见,因为欺诈(希望如此)很少发生。由于这种类别不平衡的问题,我们的模型可能没有足够的欺诈案例可供学习,我们将通过在建模阶段试验抽样方法来缓解这一问题。

## 国际银行特征

为了初步了解我们的功能,我发现 seaborn 的 pairplot 函数非常有用,特别是因为如果我们引入`hue='class'`参数,我们可以通过目标变量绘制出分布。下图按标签显示了数据集中的前 10 个要素,橙色代表 0 或非欺诈性交易,蓝色代表 1 或欺诈性交易。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/29e17ed1125503ebb48d90e745fbaf66.png)

按目标变量值划分的数据集中前十个要素的成对图。

正如您在 pairplot 中看到的,一些特征的分布因标签而异,这表明这些特征可能对模型有用。

# 二。列车测试分离

由于数据集已经被清理,我们可以继续将数据集分成训练集和测试集。这是重要的一步,因为您无法根据模型训练的数据有效地评估模型的性能!

我使用 scikit-learn 的`train_test_split`函数将我们数据集的 75%分割为训练集,剩下的 25%作为测试集。值得注意的是,我将`stratify`参数设置为等于标签或`train_test_split`函数中的`y`,以确保在训练集和测试集中有我们标签的比例示例。否则,如果在我们的训练集中没有标签为 1 的例子,模型将不会学习欺诈交易是什么样的。同样,如果在我们的测试集中没有标签为 1 的例子,我们就不知道模型在遇到欺诈时会有多好的表现。

```
X_train, X_test, y_train, y_test = train_test_split(X, y, shuffle=True, stratify=y)
```

# 三。建模

由于我们的数据集是匿名的,所以没有特征工程要做,所以下一步是建模。

## 三. a .选择 ML 模型

有不同的分类模型可供选择,我尝试构建简单的模型来选择最佳的模型,稍后我们将调整超参数来进行优化。在这种情况下,我训练了一个逻辑回归模型、随机森林模型和 XGBoost 模型来比较它们的性能。

由于类别不平衡,在这种情况下,准确性不是一个有意义的度量。相反,我使用 AUC 作为评估指标,取 0 到 1 之间的值。AUC 测量模型将随机正例(`class = 1`)排在随机负例之上的概率。

为了评估模型性能,我使用分层 K-Fold 交叉验证按类别标签分层采样,因为我们的数据集是高度不平衡的。使用模型 AUC 分数,我做了一个箱线图来比较模型的 AUC 分数范围。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0124a5acf279a254d4793f2c2056d406.png)

不同分类模型的 AUC 分数箱线图

毫不奇怪,XGBoost 似乎是我们三个选择中的最佳模型。XGBoost 模型的 AUC 中值为 0.970,相比之下,随机森林模型为 0.944,逻辑回归模型为 0.911。因此,我选择 XGboost 作为我未来的模型。

## 比较取样方法

如前所述,我还试验了不同的采样技术来处理类不平衡问题。我试用了`imblearn`的随机过采样、随机欠采样和 SMOTE 功能:

*   *随机过采样*使用替换对少数类进行采样,直到达到定义的阈值,我将其保留为默认值 0.5,因此我们的新数据集在 0 和 1 的标签之间有 50/50 的分割。
*   *随机欠采样*对多数类进行采样,默认情况下没有替换,但是您可以将其设置为使用替换进行采样,直到我们的数据集在 0 和 1 的标签之间有 50/50 的分割。
*   *SMOTE(合成少数过采样技术)*是一种数据扩充方法,它从少数类中随机选择一个示例,找到其最近邻居的 *k* (通常为 *k* =5),选择一个随机邻居,并在该随机邻居和原始示例之间的特征空间中创建一个合成新示例。

我使用`imblearn.pipeline`中的管道函数来避免泄漏,然后使用分层 K-Fold 交叉验证来比较 XGBoost 模型与上面列出的三种不同采样技术的性能。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/882b30e8be4af8adce618c737462fb97.png)

使用不同抽样方法比较 XGBoost 模型的 AUC 分数

三种取样方法的中值 AUC 分数非常接近,在 0.974 到 0.976 之间。最终,我选择了 SMOTE,因为它在 AUC 分数上的范围更小。

# 四。超参数调谐

我选择用一个叫做`hyperopt`的包来使用贝叶斯超参数调优,因为它比网格搜索或随机搜索等其他方法更快、更有见识。我想为我的 XGBoost 模型调优的超参数是:

*   `max_depth`:一棵树的最大深度;介于 4 到 10 之间的值。
*   `min_child_weight`:构成叶节点或分支末端的样本的最小权重之和;1 到 20 之间的值。
*   `subsample`:每棵树随机抽样观察;0.5 到 0.9 之间的值。
*   `colsample_bytree`:每棵树的柱或特征的随机样本;0.5 到 0.9 之间的值。
*   `gamma`:分割一个节点所需的最小损耗减少,用于防止过拟合;介于 0 和 5 之间的值。
*   `eta`:learning _ rate;介于 0.01 和 0.3 之间的值。

为了使用 hyperopt,我首先用超参数和它们各自的界限来设置我的搜索空间,以进行搜索:

```
space = {
    'max_depth': hp.quniform('max_depth', 4, 10, 2),
    'min_child_weight': hp.quniform('min_child_weight', 5, 30, 2),
    'gamma': hp.quniform('gamma', 0, 10, 2),
    'subsample': hp.uniform('subsample', 0.5, 0.9),
    'colsample_bytree': hp.uniform('colsample_bytree', 0.5, 0.9),
    'eta': hp.uniform('eta', 0.01, 0.3),
    'objective': 'binary:logistic',
    'eval_metric': 'auc'
}
```

接下来,我定义了一个目标函数来最小化将从先前定义的搜索空间接收的值:

```
def objective(params):
    params = {'max_depth': int(params['max_depth']),
              'min_child_weight': int(params['min_child_weight']),
              'gamma': params['gamma'],
              'subsample': params['subsample'],
              'colsample_bytree': params['colsample_bytree'],
              'eta': params['eta'],
              'objective': params['objective'],
              'eval_metric': params['eval_metric']}

    xgb_clf = XGBClassifier(num_boost_rounds=num_boost_rounds, early_stopping_rounds=early_stopping_rounds, **params)

    best_score = cross_val_score(xgb_clf, X_train, y_train, scoring='roc_auc', cv=5, n_jobs=3).mean()

    loss = 1 - best_score 

    return loss
```

下面列出了返回的最佳超参数,我们将用它来训练我们的最终模型!

```
best_params = {'colsample_bytree': 0.7,
               'eta': 0.2,
               'gamma': 1.5,
               'max_depth': 10,
               'min_child_weight': 6,
               'subsample': 0.9}
```

# 动词 (verb 的缩写)最终模型性能评估

为了训练最终的模型,我使用了`imblearn`的管道来避免泄漏。在管道中,我首先使用`SMOTE`来扩充数据集,并包含更多的正面类供模型学习,然后用第四步中找到的最佳超参数训练一个 XGBoost 模型。

```
final_model = imblearn.pipeline.Pipeline([
                   ('smote',SMOTE(random_state=1)), 
                   ('xgb', XGBClassifier(num_boost_rounds=1000, 
                                         early_stopping_rounds=10,                                                     
                                         **best_params))])
```

## **退伍军人指标**

以下是评估最终模型性能的一些指标:

**AUC**

最终模型的 AUC 得分为 0.991!这表明我们的最终模型能够很好地对订单欺诈风险进行排序。

**分类报告**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6e2483859545f4becd0a4e9c75f4594b.png)

测试集分类报告

**精度**

`True Positives/(True Positives + False Positives)`

类别 0 的精度为 1,表示所有标记为属于类别 0 的项目确实是非欺诈性交易。类别 1 的精度是 0.86,这意味着 86%被标记为类别 1 的项目确实是欺诈交易。换句话说,最终的模型正确地预测了 100%的非欺诈交易和 86%的欺诈交易。

**召回**

`True Positives/(True Positives + False Negatives)`

类别 0 的召回为 1,这意味着所有非欺诈性交易都被标记为 1,即属于类别 0。第 1 类的召回率为 0.9,因此我们的最终模型将 90%的欺诈交易标记为属于第 1 类。这意味着最终的模型能够捕捉到 90%的欺诈交易。

**F1 得分**

`2 * (Recall * Precision)/(Recall + Precision)`

F1 分数是精确度和召回率的加权调和平均值。类别 0 的测试集上的最终模型预测的 F1 分数为 1,而类别 1 的最终模型预测的 F1 分数为 0.88。

## V.b .功能重要性

为了理解该模型,查看 Shap 摘要和特征重要性图是有用的。不幸的是,该数据集中的大多数特征都被匿名化了,但是图中显示 v14、v4 和 v12 是最终模型中最重要的前 3 个特征。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a2256de51e7462c90fcef40592c566c7.png)

最终 XGBoost 模型的特性重要度图

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5fdaae6daddcf12b4b7eaeffabd39306.png)

最终 XGBoost 模型测试集的 Shap 摘要图

# 最后的想法

在仅仅五个步骤中,我们构建了一个 XGBoost 模型,该模型能够基于该数据集中提供的 30 个特征来预测交易是否是欺诈性的。

我们的最终模型的 AUC 值为 0.991,高得令人难以置信!但是,值得注意的是,这是使用预先清理(和处理)的数据集完成的。事实上,特征工程是建模中至关重要的一步,但由于使用匿名数据集的限制,我们在这里没有机会这样做。

我希望这个使用真实数据集的动手建模练习能够帮助您更好地理解创建机器学习模型来预测欺诈背后的机制。我很想知道匿名化的特征是什么,尤其是最具预测性的特征。如果你对它们有什么想法,请在下面评论!

要查看代码,请查看我在 Github 上的 [jupyter 笔记本文件](https://github.com/claudian37/DS_Portfolio/blob/master/credit_card_fraud/01_kaggle_creditcardfraud_modeling_final.ipynb)。谢谢大家!

## 参考

*   [Kaggle 信用卡诈骗数据集](https://www.kaggle.com/mlg-ulb/creditcardfraud)
*   [朱庇特笔记本文件](https://github.com/claudian37/DS_Portfolio/blob/master/credit_card_fraud/01_kaggle_creditcardfraud_modeling_final.ipynb)

## 脚注

[1]:标枪策略。2020 年身份欺诈研究:身份欺诈危机的起源。[https://www . javelin strategy . com/coverage-area/2020-身份-欺诈-研究-起源-身份-欺诈-危机](https://www.javelinstrategy.com/coverage-area/2020-identity-fraud-study-genesis-identity-fraud-crisis)

# 如何尽快用 Python 构建地图仪表盘

> 原文:<https://towardsdatascience.com/how-to-build-a-map-dashboard-with-python-asap-e278945fbd6d?source=collection_archive---------13----------------------->

## 使用几行 python 代码创建可共享地图仪表盘的一种非常简单、直接、容易且快速的方法。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a586150f1a2a179a72d43159e7c7cb4d.png)

机场仪表板

我们已经[看到了](/how-to-visualize-data-on-top-of-a-map-in-python-using-the-geoviews-library-c4f444ca2929)使用 python 和 geoviews 库在地图上绘制一些数据是多么容易。然而,说实话,每次当你想改变图中显示内容的特定方面时,编辑代码行会非常令人沮丧。因此,构建一个地图仪表板通常更有用、更方便,即使是最没有经验的用户也可以通过点击几下鼠标来更改地图。幸运的是,有一种简单的方法可以实现这一点,使用 Panel 和 Param。

[*Panel*](https://panel.holoviz.org/) *是一个开源的 Python 库,它允许您通过将用户定义的小部件连接到绘图、图像、表格或文本来创建自定义的交互式 web 应用程序和仪表盘。Panel 也可以与单独的*[*Param*](http://param.pyviz.org)*项目一起使用,以完全声明的方式创建带有或不带有关联可视化的交互式可配置对象。*

出于本教程的目的,我们将构建一个地图仪表板来可视化我国希腊和邻国土耳其最繁忙机场的客流量,以便进行比较,就像我们在 geoviews 的[演示](/how-to-visualize-data-on-top-of-a-map-in-python-using-the-geoviews-library-c4f444ca2929)中所做的那样。积分模块。这一次,数据集更新了 2019 年的客运量,现在包含 2018 年和 2019 年的数据,以及伊斯坦布尔的新机场。

数据集可以在[这里](https://www.dropbox.com/s/mymlk9cljj8nniq/airports_2019.csv?dl=0)找到。

首先,我们需要导入我们将要使用的必要的库和模块。

```
import pandas as pd
import numpy as np
import geoviews as gv
from geoviews import opts, dim 
import param, panel as pn
gv.extension('bokeh')
```

我们将前面提到的数据集读作`airports_df`,看起来像这样。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/578b1f1d92bfaca12a9269c22db14ebe.png)

机场 _df

现在让我们做一些准备工作。

我们创建 HoverTool 来指定当我们将鼠标悬停在这些点上时显示的信息。

```
from bokeh.models import HoverTool
tooltips = [('IATA', '[@IATA](http://twitter.com/IATA)'),
            ('Passengers', '[@passengers](http://twitter.com/passengers){0.000 a}m'),
            ('City', '[@city](http://twitter.com/city)'),
            ('Country', '[@country](http://twitter.com/country)'),
            ('Longitude', '$x'),
            ('Latitude', '$y'),
            ('Year', '[@year](http://twitter.com/year)')
            ]
hover = HoverTool(tooltips=tooltips) 
```

我们创建了一个列表,其中包含所有的国家和值" *All"* 。所以在这种情况下,它包含值['GR ',' TR ',' All']。我们将在仪表板参数“国家”中使用该列表。

```
country_list = airports_df['country'].unique().tolist() 
country_list.append('All')
country_list
```

我们还创建了一个字典,其中包含我们使用的 tilemap 的主要选项,因此也包含整个地块的主要选项。

```
topts = dict(width=1100, height=680, xaxis=None, yaxis=None, \    show_grid=False)
```

现在让我们使用**参数****面板**构建仪表板。结构如下。首先,我们使用 Param 定义主对象,在这里我们设置仪表板选项的参数。在 Param 对象内部,我们还定义了绘图,在这里我们传递用户设置的参数。

现在,我们所要做的就是将上述对象传递给`dashboard`,并使用 Panel 连续显示`dashboard.param`和`dashboard.plot`,即左边是参数,右边是绘图。

```
dashboard = Airports(name="Airports Dashboard")
DashboardPanel = pn.Row(dashboard.param, dashboard.plot)
```

最后,有两种方式来运行仪表板。或者在同一个 jupyter 笔记本中,或者在单独的标签中。

对于第一个选项,只需键入

```
DashboardPanel.servable()
```

而对于第二个选项,只需键入

```
DashboardPanel.show()
```

仪表板将如下所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ed1a1cc6680ac2dd47b7601f5d3fd0cb.png)

当然,用户可以在仪表板上添加更多的参数和图表。这个只是为了演示的目的。

今天到此为止。希望你觉得有用。下次见!

点击[这里](https://www.linkedin.com/in/christoszeglis/),你可以随时在 LinkedIn 上找到我。

# 如何从头开始构建矩阵模块

> 原文:<https://towardsdatascience.com/how-to-build-a-matrix-module-from-scratch-a4f35ec28b56?source=collection_archive---------6----------------------->

## 如果您一直在为矩阵运算导入 Numpy,但不知道该模块是如何构建的,本文将向您展示如何构建您自己的矩阵模块

# 动机

Numpy 是一个有用的库,它使您能够轻松地创建矩阵和执行矩阵操作。如果你想知道用 Numpy 创建矩阵的技巧,请查看我的博客[这里](https://medium.com/@khuyentran1476/comprehensive-numpy-tutorials-for-beginners-8b88696bd3a2)。但是如果您想创建一个具有 Numpy 库中没有的特性的 matrix 类呢?为了能够做到这一点,我们首先应该了解如何构建一个矩阵类,使我们能够创建一个矩阵,该矩阵具有矩阵的基本功能,如打印、矩阵加法、标量、元素或矩阵乘法,具有访问和设置条目。

本教程结束时,您应该已经具备创建自己的矩阵模块的基础。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1f0959dee9be95dacb13e469e46a4b6f.png)

Joshua Sortino 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片

# 为什么上课?

创建一个类允许创建一类对象的新实例。每个类实例可以有不同的属性和方法。因此,使用一个类将使我们能够创建一个具有矩阵属性和多种功能的实例。比如 A = [[2,1],[2,3]],B = [[0,1],[2,1]],A + B 应该给我们一个矩阵[[2,3],[4,4]]。

`__method__`是私有方法。即使您不能直接调用私有方法,Python 中的类中的这些内置方法将让编译器知道当您执行特定的函数或操作时要访问哪个方法。你只需要为你的目标使用正确的方法。

# 构建一个矩阵类

我将从我们想要创建的开始,然后根据我们的目标找到创建类的方法。我建议您在添加更多方法时测试您的类,看看该类的行为是否如您所愿。

## 创建并打印矩阵对象

我们希望我们的班级达到的目标如下

```
 >>> A = Matrix(dims=(3,3), fill=1.0)
	>>> print( A )
	------------- output -------------
	|   1.000,    1.000,    1.000| 
	|   1.000,    1.000,    1.000| 
	|   1.000,    1.000,    1.000| 
	----------------------------------
```

因此,我们想要创建一个带有参数`dims`和`fill`的`Matrix`对象。

```
class Matrix: 

  def __init__(self, dims, fill):    
     self.rows = dims[0]  
     self.cols = dims[1]   
     self.A = [[fill] * self.cols for i in range(self.rows)]
```

我们使用`__init__`作为构造函数来初始化我们类的属性(行、列和矩阵 A)。行和列由矩阵的第一和第二维指定。用`fill`作为值,用`self.cols`和`self.rows`作为矩阵的形状来创建矩阵 A。

我们还应该创建一个`__str__`方法,使我们能够打印如上所示的可读格式。

```
def __str__(self): 

  m = len(self.A) # Get the first dimension 

  mtxStr = '' mtxStr += '------------- output -------------\n'     

  for i in range(m):

     mtxStr += ('|' + ', '.join( map(lambda x:'{0:8.3f}'.format(x), self.A[i])) + '| \n') mtxStr += '----------------------------------' return mtxStr
```

## 缩放器和矩阵加法

目标:

标准矩阵-矩阵加法

```
 >>> A = Matrix(dims=(3,3), fill=1.0)
	>>> B = Matrix(dims=(3,3), fill=2.0)
	>>> C = A + B
	>>> print( C )
	------------- output -------------
	|   3.000,    3.000,    3.000| 
	|   3.000,    3.000,    3.000| 
	|   3.000,    3.000,    3.000| 
	----------------------------------
```

标量矩阵加法(逐点)

```
 >>>A = Matrix(dims=(3,3), fill=1.0)
	>>> C = A + 2.0
	>>> print( C )
	------------- output -------------
	|   3.000,    3.000,    3.000| 
	|   3.000,    3.000,    3.000| 
	|   3.000,    3.000,    3.000| 
	---------------------------------- 
```

我们使用`__add__`方法来执行正确的加法。

由于加法是可交换的,我们也希望能够在矩阵的右边进行加法。这可以通过调用左边的加法很容易地完成。

```
def __radd__(self, other):  
  return self.__add__(other)
```

## 逐点乘法

目标:

矩阵-矩阵逐点乘法

```
 >>> A = Matrix(dims=(3,3), fill=1.0)
	>>> B = Matrix(dims=(3,3), fill=2.0)
	>>> C = A * B
	>>> print( C )
	------------- output -------------
	|   2.000,    2.000,    2.000| 
	|   2.000,    2.000,    2.000| 
	|   2.000,    2.000,    2.000| 
	----------------------------------
```

标量矩阵逐点乘法

```
 >>> A = Matrix(dims=(3,3), fill=1.0)
	>>> C = 2.0 * A
	>>> C = A * 2.0
	>>> print( C )
	------------- output -------------
	|   2.000,    2.000,    2.000| 
	|   2.000,    2.000,    2.000| 
	|   2.000,    2.000,    2.000| 
	----------------------------------
```

使用`__mul__`方法和`__rmul__`方法进行左右点动

## 标准矩阵-矩阵乘法

目标:

```
 >>> A = Matrix(dims=(3,3), fill=1.0)
	>>> B = Matrix(dims=(3,3), fill=2.0)
	>>> C = A @ B
	>>> print( C )
	------------- output -------------
	|   6.000,    6.000,    6.000| 
	|   6.000,    6.000,    6.000| 
	|   6.000,    6.000,    6.000| 
	----------------------------------
```

矩阵乘法可以通过矩阵乘法专用的`__matmul__` 方法实现。

## 具有访问和设置条目的权限

目标:

```
 >>> A = Matrix(dims=(3,3), fill=1.0)
	>>> A[i,j]
	>>> A[i,j] = 1.0
```

使用`__setitem__`方法设置矩阵索引值,使用`__getitem__`方法获取矩阵索引值。

## 把所有东西放在一起

# 创建和使用模块

创建完类矩阵,就该把它变成一个模块了。将包含该类的文本重命名为`__init__.py`。创建一个名为`Matrix`的文件夹。将`main.py`和另一个名为`linearAlgebra`的文件放在这个文件夹中。将`__init__.py`文件放入`linearAlgebra`文件中。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4a948b802c0de8f72f105ed61ce6dff0.png)

文件夹矩阵包含 main.py 和 linear 代数

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2e590c7478ff8baf49e42e543a3adb90.png)

文件夹 linearAlgebra 包含 __init__。巴拉圭

使用`main.py`导入并使用我们的矩阵类。

# 结论

厉害!你已经学会了如何从头开始创建一个矩阵类。Python 类中还有其他方法可以让您为矩阵添加更多要素。因为你有创建一个类的基本知识,你可以创建你自己的符合你兴趣的 Matrix 版本。在[这个 Github repo](https://github.com/khuyentran1401/Numerical-Optimization-Machine-learning/tree/master/matrix) 中,您可以随意派生和使用本文的代码。

我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedIn 和 Twitter 上与我联系。

如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:

[](https://medium.com/@khuyentran1476/how-to-produce-creative-product-without-hitting-your-head-to-the-wall-86eb93207058) [## 如何生产创意产品(不碰壁)

### 创意是创造伟大产品的关键,但并不总是容易的。这个博客会给你策略去克服…

medium.com](https://medium.com/@khuyentran1476/how-to-produce-creative-product-without-hitting-your-head-to-the-wall-86eb93207058) [](/step-by-step-tutorial-web-scraping-wikipedia-with-beautifulsoup-48d7f2dfa52d) [## 用美丽的声音抓取维基百科

### 关于如何使用 Beautiful Soup 的分步教程,这是一个用于 web 抓取的简单易用的 Python 库

towardsdatascience.com](/step-by-step-tutorial-web-scraping-wikipedia-with-beautifulsoup-48d7f2dfa52d) [](/find-common-words-in-article-with-python-module-newspaper-and-nltk-8c7d6c75733) [## 用 Python 模块 Newspaper 和 NLTK 查找文章中的常用词

### 使用 newspaper3k 和 NLTK 从报纸中提取信息和发现见解的分步指南

towardsdatascience.com](/find-common-words-in-article-with-python-module-newspaper-and-nltk-8c7d6c75733) [](/choose-stocks-to-invest-with-python-584892e3ad22) [## 用 Python 选择要投资的股票

### 您计划在未来 3 年投资几只股票,每只股票的每一美元都有不同的预期回报…

towardsdatascience.com](/choose-stocks-to-invest-with-python-584892e3ad22) [](https://medium.com/@khuyentran1476/comprehensive-numpy-tutorials-for-beginners-8b88696bd3a2) [## 为您的数据科学项目提供 Numpy 技巧

### 创建数组、矩阵、执行矩阵运算、解决线性代数问题和常见数据科学的技巧…

medium.com](https://medium.com/@khuyentran1476/comprehensive-numpy-tutorials-for-beginners-8b88696bd3a2)

# 如何使用 Python Surprise 构建基于内存的推荐系统

> 原文:<https://towardsdatascience.com/how-to-build-a-memory-based-recommendation-system-using-python-surprise-55f3257b2cf4?source=collection_archive---------8----------------------->

## 使用 Python 中的 Surprise 库实现 kNN 风格推荐引擎的分步指南,从数据准备到预测。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9323cb34e866449a0efa1c2ecd44fdd6.png)

照片由[阮一](https://unsplash.com/@happychan?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/cupcake-selection?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄

啊,我们舒适的现代生活的极度痛苦,纸杯蛋糕看起来都很诱人,但你不可能都尝一尝,所以你应该吃哪一个?不管平台如何,您的选择通常几乎是无限的,但遗憾的是,作为消费者,您的资源并非如此。不要担心,推荐系统会来救你!

框架推荐系统是,我们有一组用户和一组项目,对于给定的用户,我们希望筛选出该用户可能喜欢的项目子集(评价高、购买、观看等。取决于确切的问题)。推荐系统无处不在,所有基于内容的非常成功的科技公司,如网飞、亚马逊、脸书,都非常依赖复杂的推荐系统来增加他们产品的消费。

在作为这篇文章基础的特定项目中,我专注于来自 [boardgamegeek](https://boardgamegeek.com/browse/boardgame) (截至 2020 年 3 月 31 日)的前 100 款游戏,处理我从该网站收集的 230 万个人用户评级。我主要使用了 [surprise](https://surprise.readthedocs.io/en/stable/index.html) ,这是一个专注于推荐系统的 Python scikit 库,其结构非常类似 scikit-learn。

在这篇文章中,我们将讨论基于记忆的模型。我们将讨论如何导入和准备数据,使用什么相似性度量,如何实现三个内置的 kNN 模型,如何应用模型验证,最后进行预测。关于这个项目的细节,请参考我的 [GitHub 库](https://github.com/MatePocs/boardgame_recommendation/blob/master/02_modelling_neighbours.ipynb),我们将在这篇文章中涉及的工作大致对应于文件`02_modelling_neighbours.ipynb`中的代码。

## 目录

推荐系统
数据导入
数据准备
模型参数
KNN 模型
测试
预测
交叉验证
综合考虑
可能的改进

## 推荐系统

让我们从推荐系统家族的快速总结开始,这样我们就可以放置最近邻模型。

有两条主要的推荐路线可供您选择:

*   **基于内容的过滤**模型基于项目的描述和用户的历史偏好,我们不需要其他用户的意见来推荐。
    *举例:用户喜欢 Vlaada Chvátil 设计的三款游戏,所以我们推荐他设计的第四款游戏。*
*   **协同过滤**模型试图通过共同评级/拥有的项目来发现项目/用户之间的相似性。
    *例如:用户喜欢卡文纳,从我们对人群的分析中我们知道,那些喜欢卡文纳并知道奥丁盛宴的用户也倾向于喜欢第二款游戏,所以我们向用户推荐 FfO。*

在这个项目中,我们将采用协同过滤。在协作过滤组中,两种最著名的不同方法是:

*   **基于记忆的**模型根据用户-项目评分对计算用户/项目之间的相似度。
*   基于模型的模型(不可否认,一个古怪的名字)使用某种机器学习算法来估计收视率。一个典型的例子是用户项目评分矩阵的奇异值分解。

在这篇文章中,我们主要关注基于记忆的模型。所以再一次,推荐系统内部是协同过滤,而协同过滤内部是基于记忆的模型。

## 数据导入

首先,我们需要安装`surprise`包:

```
pip install scikit-surprise
```

完成后,您需要一个数据集,其中包含三个变量:用户 id、商品 id 和评级。这一点很重要,不要试图以用户项目评分矩阵的形式传递评分。从有 3 列且行数等于个人评分总数的数据开始。

如果你只是想练习,可以随意使用我的 GitHub 上的数据集。我个人将这些收集在一个`csv`文件中,分为三列,但是您也可以使用其他数据结构,或者直接从`pandas`T3 加载。

为了导入数据,您需要库中的这些类:

```
from surprise import Dataset, Reader
```

然后定义`file_path`(显然改成你的文件了):

```
file_path = './data_input/games_100_summary_w_testuser.csv'
```

最后,我们创建一个`Reader`对象,具有以下属性:

*   `line_format`:确保订单与您的文件匹配。
*   如果我们使用 csv,这是一个逗号。
*   `rating_scale`:具有最低和最高可能范围的元组。获得正确的参数很重要,否则部分数据将被忽略。如果你使用的是二进制数据,例如,用户喜欢/不喜欢的物品,你可以放入(0,1)。

```
reader = Reader(
    line_format='user item rating', sep=',', rating_scale = (1,10)
    )
```

要导入数据,使用`load_from_file`方法:

```
data = Dataset.load_from_file(file_path, reader=reader)
```

就这样,你应该有一种`surprise`可以使用的数据格式!现在,您可以将数据想象成一个稀疏矩阵,其中用户/项目是行/列,个人评级是该矩阵中的元素。大多数单元格可能是空的,但这完全没问题。在我使用的数据中,我有 230 万的收视率,大约 23 万用户,这意味着用户平均对 100 个游戏中的 10 个进行评分,因此矩阵中大约 90%是空的。

## 数据准备

这就是`surprise`第一次变得有点奇怪的地方,这个过程与`scikit-learn`中的分类器模型不相似,在那里你有一个大矩阵,你可以将它分成训练/验证/测试集,以你认为合适的方式进行交叉验证,因为它们本质上仍然是相同类型的数据。不,在`surprise`中,有三种不同的数据类,每一种都有其独特的用途:

*   `Dataset`:用于直接或通过交叉验证迭代器分割成训练集和测试集。后者意味着如果您在交叉验证中将一个`Dataset`作为参数传递,它将创建许多训练测试分割。
*   `Trainset`:作为模型`fit`方法中的一个参数。
*   `Testset`:作为模型`test`方法中的一个参数。

在我看来,`surprise`是一个相对有据可查的库,但还是有些古怪。例如,`Dataset`对象有一个方法`construct_testset`,但是除了在以前版本的文档页面中找到代码之外,没有解释它做什么,或者参数应该是什么。

我坚持在我的项目中使用记录良好的方法。我们正在准备两种不同的方法,它们的目的将在下面的章节中变得更加清楚。

我们将使用`model_selection`包中的以下内容:

```
from surprise.model_selection import train_test_split
```

首先,我们将数据分为`trainset`和`testset`,`test_size`设置为 20%:

```
trainset, testset = train_test_split(data, test_size=0.2)
```

同样,它与分类器/回归模型的工作方式有点不同,`testset`包含随机选择的用户/项目评级,而不是完整的用户/项目。一个用户可能在数据中有 10 个评级,其中 3 个现在被随机选择用于`testset`,不用于拟合模型。当我第一次注意到这一点时,我发现这很奇怪,但不完全忽略某些用户是完全合理的。

第二种方法是使用完整的数据和交叉验证进行测试。在这种情况下,我们可以通过`build_full_trainset`方法使用所有评级构建一个`Trainset`对象:

```
trainsetfull = data.build_full_trainset()
```

您可以使用`n_users`和`n_items`方法获得项目/用户的数量(同样的方法适用于`trainsetfull`,因为它们是同一类型的对象):

```
print('Number of users: ', trainset.n_users, '**\n**')
print('Number of items: ', trainset.n_items, '**\n**')
```

当 surprise 创建一个 Trainset 或 Testset 对象时,它获取`raw_id`(您在导入的文件中使用的那些),并将它们转换成所谓的`inner_id`(基本上是一系列整数,从 0 开始)。你可能需要追溯到最初的名字。以条目为例(您可以对用户使用相同的方法,只需在代码中用`uid`替换`iid`,要获得`inner_iid`的列表,您可以使用`all_items`方法。要从原始 id 转换到内部 id,您可以使用`to_inner_iid`方法,然后使用`to_raw_iid`转换回来。

如何保存内部和原始项目 id 列表的示例:

```
trainset_iids = list(trainset.all_items())
iid_converter = lambda x: trainset.to_raw_iid(x)
trainset_raw_iids = list(map(iid_converter, trainset_iids))
```

我们的数据准备工作到此结束,接下来是时候研究一些模型参数了!

## 模型参数

当我们使用 kNN 类型的推荐算法时,有两个超参数可以调整:k 参数(是的,与模型类型名称中的 k 相同)和相似性选项。

**k 参数**相当简单,类似于它在一般 k 近邻模型中的工作方式:它是我们希望算法考虑的类似项目的上限。例如,如果用户评价了 20 个游戏,但是我们将 k 设置为 10,当我们估计对新游戏的评价时,将只考虑 20 个游戏中最接近新游戏的 10 个游戏。您还可以设置 **min_k** ,如果用户没有足够的评分,将使用全局平均值进行评估。默认情况下,它是 1。

我们在上一段中提到了彼此靠近的项目,但是我们如何确定这个距离呢?第二个超参数**相似性选项**定义了计算方法。

先来看看`sim_option` [配置](https://surprise.readthedocs.io/en/stable/prediction_algorithms.html#similarity-measure-configuration)。该参数是一个字典,具有以下键:

*   `shrinkage`:不需要基本的 kNN 型号,只在`KNNBaseline`型号中出现。
*   `user_based`:基本上,当你想要估计相似性时,有两条不同的路线。您可以计算每个项目与其他项目的相似程度,也可以对用户进行同样的计算。对于我的项目,我使用了`False`,考虑到我有 100 个项目和 23 万个用户。
*   `min_support`:相似度设为 0 的最小公共点数。例如:如果 min_support 为 10,并且有两个游戏,只有 9 个用户对这两个游戏进行了评级,则无论评级如何,这两个游戏的相似度都将为 0。我没有在我的项目中试验过这个,考虑到数据的范围,它似乎并不重要,所以我使用了默认的 1。
*   `name`:公式的类型,将在下面进一步讨论。

所有的相似性函数将返回一个介于 0 和 1 之间的数字给一个特定的 *(i,j)* 项目对。1 表示评级完全一致,0 表示两个项目之间没有联系。公式中, *rᵤᵢ* 是用户 *u* 对项目 *i* 的评分, *μᵢ* 是项目 *i* 的平均评分, *Uᵢⱼ* 是对项目 *i* 和 *j* 都进行了评分的用户集合。以下是`surprise` [相似性模块](https://surprise.readthedocs.io/en/v1.1.0/similarities.html)中的三个相似性指标:

`cosine`:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0d8108f1a95d72b591e353c5b21e0830.png)

`MSD`:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b9a22d8632e4d0f8e8bc77926a265e3d.png)

其中 *msd(i,j)* 为:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a470b716af78d4c297e9fa8c5b35922d.png)

`pearson`:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2fd5eead2121205b93cba41bcb7cd56f.png)

没有明确的好与坏的选择,虽然我很少看到`MSD`在例子中被使用,而且在我的数据中,`pearson`和`cosine`的表现确实明显更好。可以看出,`pearson`公式基本上是`cosine`公式的均值中心版本。

如何定义`sim_option`参数的示例:

```
my_sim_option = {
    'name':'MSD', 'user_based':False, min_support = 1
    }
```

现在我们做了所有的准备工作,我们终于可以训练一些模型了。

## KNN 模型

在`surprise`中有三种基本 [KNN 模型](https://surprise.readthedocs.io/en/v1.1.0/knn_inspired.html?highlight=knn)(我们不考虑第四种,`KNNBaseline`在这篇文章中)。它们定义了如何在预测中估计用户 *u* 对项目 *i* 的评价 *rᵤᵢ* 。下面的公式主要使用我们在上一节中讨论过的符号,一些新符号: *σᵢ* 是项目 *i* 的标准偏差, *Nᵤᵏ(i)* 是来自用户 *u* 评价的最接近项目 *i* 的项目的最大 *k* 项目。

事不宜迟,公式如下:

`KNNBasic`:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8839c3a1a6fa138e8fffb2b06a5609bf.png)

估计评级基本上是用户给相似项目的评级的加权平均值,由相似性加权。

`KNNWithMeans`:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7f31c157dc86d4eb23d3656daa348cf0.png)

根据项目的平均评分调整`KNNBasic`公式。

`KNNWithZScore`:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4a56d277a5d2f05095657281bce50bd5.png)

更进一步,也根据评分的标准偏差进行调整。

在下面的例子中,我们用三个 my_ parameters 来拟合一个`KNNWithMeans`模型。根据我的经验,如果你的项目的平均评分不同,你几乎不会想用`KNNBasic`。您可以随意更改这些参数,所有三种型号都使用完全相同的参数。您可以在下面的代码中将`KNNWithMeans`更改为`KNNBasic`或`KNNWithZScore`,其工作方式是一样的。

```
from surprise import KNNWithMeansmy_k = 15
my_min_k = 5
my_sim_option = {
    'name':'pearson', 'user_based':False, 
    }algo = KNNWithMeans(
    k = my_k, min_k = my_min_k, sim_option = my_sim_option
    )algo.fit(trainset)
```

因此,我们的模型是合适的。从技术上讲,在这一点上发生的所有事情就是模型计算相似性矩阵和均值/标准差(如果您选择它的话)。

您可以使用 sim 方法请求相似性矩阵,如下所示:

```
algo.sim()
```

它将是一个`numpy`数组格式。除非你想自己做一些预测,否则你可能不需要这个矩阵。

## 测试

一旦你训练好了你的模型,就该测试了,对吧?性能指标保存在`surprise`的[精度模块](https://surprise.readthedocs.io/en/stable/accuracy.html)中。这里有四种度量标准(RMSE、FCP、MAE、MSE),但据我所知,行业标准是均方根误差,所以我们只使用这一个。这是我们今天最后的数学公式:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/40e55cb0b45b196f6f29a61418ec1d04.png)

这个分数大致告诉你你的估计评分与实际评分的平均偏差。要获得测试分数,您所要做的就是使用您已经适应的算法上的测试方法创建一个`predictions`对象:

```
from surprise import accuracypredictions = algo.test(testset)accuracy.rmse(predictions)
```

假设根据我的数据,测试数据中的 RMSE 分数是 1.2891。这意味着在 1 到 10 的范围内,估计的评分平均比实际评分高或低约 1.2891。不伟大,也不可怕。

## 交叉验证

在前两节中,我们遵循了一种非常直接的方法:我们留出一个测试数据,训练模型,然后测试其性能。但是,如果您进行多次运行,使用交叉验证来测试您的模型的性能以及它是否过度拟合可能是一个更好的主意。

如前所述,在`surprise`中,测试和验证的工作方式有点不同。你只能在你的原始数据集对象上进行交叉验证,而不能为最终测试留出单独的测试部分,至少我找不到这样做的方法。所以我的过程基本上是这样的:

*   用不同的参数交叉验证了许多模型类型,
*   选择具有最低平均测试 RMSE 分数的配置,
*   整体训练那个模型`Dataset,`
*   用它来预测。

让我们讨论一下`cross_validate`方法的几个参数:

*   `cv`是我们定义模型使用的折叠类型的地方,类似于`scikit-learn`中的工作方式。我将通过输入一个整数来使用一个基本的 K 倍,你可以在[文档](https://surprise.readthedocs.io/en/stable/model_selection.html?highlight=cross%20validation#module-surprise.model_selection.split)中读到不同的 K 倍。
*   `n_jobs`:并行计算的折叠次数,如果你能腾出内存,将其设置为-1 将意味着所有的 CPU 并行工作。然而,当我在本地机器上这样做时,它崩溃了。我最终将它保留为默认的 1。

在下一部分中,我们将交叉验证的结果保存在`results`变量中:

```
from surprise.model_selection import cross_validateresults = cross_validate(
    algo = algo, data = data, measures=['RMSE'], 
    cv=5, return_train_measures=True
    )
```

请注意,运行这个可能需要几分钟,测试需要一段时间,交叉验证需要 5 次。

一旦完成,您就可以挖掘`results`变量来分析性能。例如,要得到平均测试 RMSE:

```
results['test_rmse'].mean()
```

很自然,你会这样做一段时间,尝试不同的模型,并以较低的`RMSE`分数为目标。一旦你对性能感到满意,并创建了一个你满意的`algo`模型,就该在整个数据集上训练算法了。你需要这一步,因为正如我提到的,你不能从交叉验证中做出预测。与上述未满车列相同的代码:

```
algo.fit(trainsetfull)
```

下一步,我们继续预测!

## 预言

最后,这就是我们做整个项目的原因,对吗?关于`surprise`的两个重要注意事项可能与您的期望不符:

*   只能对已经在数据集中的用户进行**预测。这也是为什么我认为在过程结束时根据整个数据训练模型是有意义的原因。**
*   您不会直接从模型中获得输出列表,只需一次调用,**您就可以请求一个特定用户对一个特定项目的估计评级**。但是,有一个解决方法,我们稍后将回到这个问题。

为了进行一次预测,您可以使用原始 id,因此要获得 id 为`161936`的游戏的`TestUser1`(在数据中至少有`min_k`个其他评分的用户)的估计评分,您需要您训练过的算法的`predict`方法:

```
algo.predict(uid = 'TestUser1', iid = '161936')
```

`predict`方法将返回这样一个字典:

```
Prediction(uid='TestUser1', iid='161936', r_ui=None, est=6.647051644687803, details={'actual_k': 4, 'was_impossible': False})
```

`r_ui`是`None`,因为用户没有该项目的实际评分。我们最终感兴趣的是第`est`项,即估计评分,在我们的例子中,我们估计评分为 6.647。

这一切都很好,但是我们如何为用户获得前 N 个推荐呢?您可以在文档中找到详细的解决方案[,我不打算在此复制,这些是基本步骤:](https://surprise.readthedocs.io/en/stable/FAQ.html)

*   `trainsetfull`上的列车模型。
*   用`build_anti_testset`方法创建一个“反测试集”。这基本上是我们原始数据集的补充。因此,如果用户对 100 款游戏中的 15 款进行了评级,我们的`testset`将包含用户没有评级的 85 款游戏。
*   用`test`方法在`anti_testset`上运行预测(其结果与`predict`方法的结构相似)。通过这一步,我们得到了数据中缺失的所有用户-项目评分对的估计评分。
*   对每个用户的估计评分进行排序,列出具有最高估计评分的 N 个项目。

## 把所有的放在一起

我认为将我们讨论的内容包含在一个连续的块中是有意义的。我们在下面的代码中采用的方法是交叉验证途径,因此我们使用交叉验证来测试性能,然后在整个数据集上拟合模型。

请注意,你很可能不会停止一个交叉验证,应该尝试不同的模型,直到你找到最好的。您可能还想促进前一节中链接的前 N 条建议。

从数据准备到惊喜预测

## 后续步骤

当谈到与`surprise`合作时,你有许多额外的选择,我打算在未来的博客文章中探索它们。

一个相当明显的下一步是用`SVD`和`SVDpp`方法探索基于模型的方法。这些使用矩阵分解来估计评级。此外,您可能已经注意到,在这个场景中,我没有使用`GridSearchCV`进行超参数调优。我发现使用`cross_validate`就足够了,考虑到我们只有几个参数,但是当涉及到更复杂的模型时,你肯定想使用`GridSearchCV`。

*更新:*如果你对实现基于模型的方法感兴趣,可以看看我系列的下一篇文章 [**如何使用 Python Surprise**](/how-to-build-a-model-based-recommendation-system-using-python-surprise-2df3b77ab3e5) 构建基于模型的推荐系统。

另一个有趣的领域是预测。有时,您只想在一些用户评级上运行您的模型,而不将它们集成到底层数据库中。例如,我从 boardgamegeek 收集数据,当我只想快速向某人展示模型时,我不希望那些评级与“官方”评级混在一起。为一个用户重新运行整个模型也是没有效率的。现在,对于我们讨论的三个 KNN 模型,完全可以仅从相似性矩阵、平均值和标准偏差进行预测。我会在以后的文章中描述这个过程,或者你可以看看我的 [GitHub](https://github.com/MatePocs/boardgame_recommendation/blob/master/recomm_func.py) 中的`recomm_func.py`脚本。

*更新:*如果你想了解更多关于这个自定义预测代码,看看 [**我的 Python 代码灵活推荐**](/my-python-code-for-flexible-recommendations-b4d838e9e0e0) 。

## 参考

[](https://en.wikipedia.org/wiki/Collaborative_filtering) [## 协同过滤

### 协同过滤(CF)是推荐系统使用的一种技术。协同过滤有两个含义,一个是…

en.wikipedia.org](https://en.wikipedia.org/wiki/Collaborative_filtering) 

接下来的三个链接是`scikit-surprise`的不同文档,我主要用的是第一个。

 [## 欢迎使用“惊喜”文档!-惊喜 1 文档

### 如果您对惊喜感到陌生,我们邀请您看一看入门指南,在那里您会找到一系列…

surprise.readthedocs.io](https://surprise.readthedocs.io/en/stable/index.html) [](https://pypi.org/project/scikit-surprise/) [## scikit-惊喜

### Surprise 是一个 Python scikit,它构建并分析处理显式评级数据的推荐系统。惊喜…

pypi.org](https://pypi.org/project/scikit-surprise/)  [## 主页

### Surprise 是一个 Python scikit,它构建并分析处理显式评级数据的推荐系统。惊喜…

surpriselib.com](http://surpriselib.com/)

# 如何使用 Python Surprise 构建基于模型的推荐系统

> 原文:<https://towardsdatascience.com/how-to-build-a-model-based-recommendation-system-using-python-surprise-2df3b77ab3e5?source=collection_archive---------30----------------------->

## 使用 Python 中的 Surprise 库实现潜在因素推荐引擎的分步指南。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5e7edf2d24a1ca5acdba3466078e2b1e.png)

德瓦·威廉姆森在 [Unsplash](https://unsplash.com/s/photos/cupcake?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

这篇文章是我的 Python 惊喜推荐系列的最后一篇,在这篇文章中,我展示了我在 boardgame 推荐引擎项目中使用的技术。(整个项目看我的 [GitHub 回购](https://github.com/MatePocs/boardgame_recommendation)。)

该系列的前几篇文章:

**第 1 部分** : [如何使用 Python Surprise 构建基于内存的推荐系统](/how-to-build-a-memory-based-recommendation-system-using-python-surprise-55f3257b2cf4):如果您不熟悉这个主题,尤其是数据导入和数据准备步骤,我建议您先阅读这篇文章,因为它们对于基于内存和基于模型的方法是相同的。

**第 2 部分** : [我的灵活推荐 Python 代码](/my-python-code-for-flexible-recommendations-b4d838e9e0e0):这篇文章包含了我为推荐框架编写的额外代码,它使人们无需重新训练整个模型就能创建预测。然而,这种方法只适用于 KNN 风格的简单模型。

我还愚蠢地用纸杯蛋糕做了一个类比,以封面图片为依据。在第一个帖子中,我们有许多纸杯蛋糕,不知道如何选择,在第二个帖子中,我们有一个奇怪的新来的纸杯蛋糕,努力整合它,现在…我想现在纸杯蛋糕排成一行,代表矩阵分解。这是我能想到的最好的了。

在这篇文章中,我们将讨论潜在因素模型如何工作,如何通过超参数调整来训练这样一个模型,以及我们可以从结果中得出什么其他结论。

## 基于模型的推荐系统

快速回顾一下我们的现状。在[推荐系统](https://en.wikipedia.org/wiki/Recommender_system)中,有一组被称为[协同过滤](https://en.wikipedia.org/wiki/Collaborative_filtering)的模型,它试图根据记录的用户项目偏好或评级来发现用户之间或项目之间的相似之处。在我之前的文章中,我们讨论了协作系统的一个子群,称为基于[记忆的](https://en.wikipedia.org/wiki/Collaborative_filtering#Memory-based)模型。它们被称为基于内存的,因为算法并不复杂,但需要大量内存来跟踪结果。

在这篇文章中,我们将讨论协作过滤模型的另一个子群:[基于模型的](https://en.wikipedia.org/wiki/Collaborative_filtering#Model-based)模型(这是一个相当愚蠢的名字)。与基于记忆的方法相反,这种方法使用某种机器学习算法。这一组中有许多不同的变体,我们将集中讨论奇异值分解方法。

在[惊喜](https://surprise.readthedocs.io/en/stable/matrix_factorization.html)中,有三种这样的模式:`SVD`、`SVDpp`、`NMF`,其中我只打算讨论`SVD`。`NMF`是一个简化版本,忽略了用户和项目的偏见。`SVDpp`增加了一个非常酷的功能,你还可以单独跟踪用户是否对项目进行了评级,这当然也应该是相关的信息,但我发现它并没有提高我的效率,同时增加了大量的计算时间。

## 数学公式

在 SVD 模型中,用户 *u* 对项目 *i* 的估计评分计算如下:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ee0fa1558dc6541de7039585aa42b818.png)

其中 *μ* 是总体平均评级,其他所有参数通过梯度下降法从模型中计算得出。因此,该模型将尝试在所有已知评级上拟合该估计评级,最小化 MSE,并返回最接近的拟合。

*bᵤ**bᵢ* 是标量,它们代表用户 *u* 或项目 *i* 的偏向。例如,用户 *u* 倾向于 *bᵤ* 偏离大平均评级。这些偏差可以在拟合模型时关闭,这基本上就是`NMF`模型。

*pᵤ**qᵢ* 是向量,它们的长度是模型的超参数 *n* 。它们是模型的实际[矩阵分解](https://en.wikipedia.org/wiki/Matrix_factorization_(recommender_systems))部分,这就是神奇之处。每个用户和物品将由他们的向量来表示,向量试图用 *n* 个数字来捕捉他们的本质。我们通过乘以项目-用户对(当然,加上平均值和偏差)来获得评级。

把这 n 个维度看作是人类可以理解的东西可能很有诱惑力。例如,如果我们处理棋盘游戏,第一个维度可以衡量规则手册有多复杂。现在,一个高度重视复杂性的用户(这意味着他们在*qᵢ*[*1*)*会给一个高复杂性的游戏一个高评级(这意味着高 *pᵤ* [ *1* )。然而,根据我的经验,这种情况很少发生,很难将意义与模型中的各个坐标相匹配。*

## *在惊讶中训练模型*

*假设您已经导入并设置了数据库(同样,如果您不确定如何做,请参考我的[上一篇文章](/how-to-build-a-memory-based-recommendation-system-using-python-surprise-55f3257b2cf4)),使用`SVD`类似于在 Surprise 中使用其他模型。首先,您需要导入模型:*

```
*from surprise import SVD*
```

*然后,您可以在列车组上安装模型,并使用`RMSE`分数(代表均方根误差,越低越好)测试模型性能:*

```
*SVD_model = SVD()
SVD_model.fit(trainset)
predictions = SVD_model.test(testset)
accuracy.rmse(predictions)*
```

*与基于内存的模型类似,为了预测特定用户的评级,您可以使用 predict 方法,但该用户需要在您的数据库中:*

```
*SVD_model.predict(uid = 'TestUser1', iid = '161936')*
```

## *分析模型*

*如您所见,拟合 SVD 模型很简单,但是分析结果有点复杂。*

*使用一个`SVD`对象的`pu`、`qi`、`bu`和`bi`方法,可以从数学公式中得到相应的值。在我的项目中,我发现`qi`是最有趣的:在已经拟合的`SVD`模型上调用`qi`方法将返回一个二维数组,其中高度是项目的数量,宽度是模型的`n_factor`参数(我们将在下一节讨论这些参数)。每行代表一个有`n_factor`个因素的项目,这些是模型发现的所谓潜在因素,它们代表评级计算中的项目。*

*正如我之前提到的,试图在这些坐标中找到容易理解的意义是很诱人的,但以我的经验来看,这并不会真的发生。然而,我认为一个真正有趣的方法是将这些潜在的因素作为聚类分析的基础,看看是否能从中发现什么有趣的东西。您可以使用`n_factor`潜在因素作为特征,并基于它们计算项目的距离,就像您在任何常规聚类分析中所做的那样。*

## *我们的超参数是什么?*

*任何机器学习过程的一个重要部分是调整超参数。在本节中,我们将惊奇地看一下`SVD`参数。*

*在我们开始之前,请注意,对于我的项目,默认参数下的 RMSE 分数是 1.332,在我的 GCP 虚拟机运行了几个小时之后,我设法将 RMSE 分数降到了 1.3210。这不是一个很大的改进…可能只是我的数据库,可能是因为默认参数在惊奇中被有效地设置。尽管如此,我认为考虑超参数仍然很重要。*

*我优化了四个超参数:*

*   *`n_factors`:我们在上一节已经简单的提到了这一点,这个参数决定了你的 *pᵤ* 和 *qᵢ* 向量的大小。这决定了模型将试图找到多少潜在因素。该数字越高,模型的能力越强,但也有更高的过度拟合几率。*
*   *`n_epochs`:该因子决定梯度下降计算重复的次数。增加该数值会使预测更加准确,但需要更长的计算时间。*
*   *`lr_all`:所有参数的学习率系数。这些是模型将用于最小化成本函数的步长,请参见[惊喜文档](https://surprise.readthedocs.io/en/stable/matrix_factorization.html)中的更多信息。*
*   *`reg_all`:所有参数的正则化因子。Surprise 使用 L2 正则化,这大致意味着它将尝试最小化参数平方值之间的差异。(参数为所有 *bᵤ、bᵢ、pᵤ* 和 *qᵢ* 。)*

*还有许多其他参数可以使用,其中大多数是不同的学习率或调整参数设置。从技术上讲,您可以为每四种模型参数设置不同的学习率或正则化,而`…_all`参数涵盖了所有这些参数。我认为没有必要详述这些细节。*

## *超参数调谐*

*我们将使用`GridSearchCV`来调整超参数。它的工作方式很像它在 scikit-learn 中的对应物,顾名思义,它将使用交叉验证在超参数网格上搜索所有可能的组合。*

*首先,我们需要一个字典,其中的键是超参数名称,值是您想要检查的不同项目的列表:*

```
*param_grid = {
    'n_factors':[5, 10,20],
    'n_epochs': [5, 10, 20], 
    'lr_all': [0.002, 0.005],
    'reg_all': [0.4, 0.6]}*
```

*你必须小心设置这些参数,因为每个可能的组合都会被检查。在我们的例子中,有 3 * 3 * 2 * 2 = 36 种不同的组合,对于其中的每一种,模型将运行多次,这取决于您选择的交叉验证。我将`cv`参数设为 5 倍,这意味着总共 36 * 5 = 180 次模型运行。*

*这可能需要很长时间,现在可能是开始考虑使用云计算的时候了。我最近写了一篇关于如何在 Google 云平台上快速设置免费[虚拟机的帖子。](/google-cloud-virtual-machine-for-data-science-work-7622579c5b0d)*

*一旦你有了你的参数网格,你可以像这样设置`GridSearchCV`对象:*

```
*gs_model = GridSearchCV(
    algo_class = SVD,
    param_grid = param_grid,
    n_jobs = -1,
    joblib_verbose = 5)*
```

*第一个参数`algo_class`是您想要使用的模型类型。`n_jobs` = -1 简单地告诉模型它可以使用所有可用的处理器,当您有一个可并行化的操作时,这是非常理想的。您可能想要更改的另一个参数是`cv`,我只是将其保留为默认值,它进行 5 重交叉验证。*

*然后你可以简单地拟合数据:*

```
*gs_model.fit(data)*
```

*请再次注意,surprise 处理数据库的方式有点不同,您只能将您的`GridSearchCV`放在整个数据集上,不能将其分为训练和测试。*

*最后,您可以从参数网格中获得导致最佳`RMSE`分数的参数列表:*

```
*gs_model.best_params*
```

## *我的过程*

*我和`GridSearchCV`一起工作的过程如下:*

*   *在整个数据上拟合一个`GridSearchCV`模型,其参数网格覆盖范围很广*
*   *计算交叉验证的`RMSE`分数*
*   *对不同的参数网格重复该过程,如果最佳参数似乎在中间,则向下钻取到较低的级别,或者如果最佳参数似乎在前一参数网格的边界,则探索较高/较低的参数*
*   *一旦`RMSE`得分下降最小,保存最佳超参数并在接下来的步骤中用于`SVD`模型*
*   *因为我想将结果与我之前的 KNN 型模型进行比较,所以我在`trainset`上运行了`SVD`模型,并在`testset`上计算了测试`RMSE`分数*

*另一种方法是简单地依赖 GSCV 分数,并在整个训练集中仅拟合最终模型一次。*

## *结论*

*我的推荐系统项目系列到此结束。*

*与所有这些不同的方法一起工作是很有趣的,尤其是他们的表现是如此的接近。我花了很多时间来确定最好的模型,但事实是,即使是最简单的 KNN 模型表现也相对较好。*

*我认为这部分是因为我的数据远没有推荐系统通常的那么稀疏。10%的可能用户项目评级被填充,这被认为是非常高的比率。想象一下,如果人们平均购买了亚马逊上所有产品的 10%!这个比例很高是因为我只关注了有史以来最受欢迎的 100 款桌游,这些游戏自然都很受欢迎。作为一个额外的奖励,平均评分非常接近和高,因为这些都是普遍认为是好游戏。*

## *参考*

*惊喜文档:*

 *[## 欢迎使用“惊喜”文档!-惊喜 1 文档

### 如果您对惊喜感到陌生,我们邀请您看一看入门指南,在那里您会找到一系列…

surprise.readthedocs.io](https://surprise.readthedocs.io/en/stable/index.html)* 

*我在该系列中的前几篇文章:*

*[](/how-to-build-a-memory-based-recommendation-system-using-python-surprise-55f3257b2cf4) [## 如何使用 Python Surprise 构建基于内存的推荐系统

### 使用 Python 中的 Surprise 库实现 kNN 风格推荐引擎的分步指南,来自 data…

towardsdatascience.com](/how-to-build-a-memory-based-recommendation-system-using-python-surprise-55f3257b2cf4) [](/my-python-code-for-flexible-recommendations-b4d838e9e0e0) [## 我的灵活推荐 Python 代码

### 我的额外定制 Python 代码,使您能够基于惊喜库运行更灵活的推荐…

towardsdatascience.com](/my-python-code-for-flexible-recommendations-b4d838e9e0e0)*

# 如何建立电影推荐系统

> 原文:<https://towardsdatascience.com/how-to-build-a-movie-recommendation-system-67e321339109?source=collection_archive---------4----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/32ae87302415c9a2d67b45b2b7b32faf.png)

Noom Peerapong 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片

## [动手教程](https://towardsdatascience.com/tagged/hands-on-tutorials),机器学习

## 构建简单推荐系统的逐步指南

你有没有想过 YouTube 是怎么推荐内容的,或者脸书是怎么推荐你的,新朋友?也许你已经注意到了 LinkedIn connections 的类似推荐,或者当你在浏览时亚马逊将如何推荐类似的产品。所有这些推荐都是通过推荐系统的实现而成为可能的。

推荐系统包括一类可以向用户建议“相关”项目的技术和算法。他们通过包括矩阵分解在内的多种技术,根据过去的数据预测未来的行为。

在这篇文章中,我将看看为什么我们需要推荐系统和不同类型的在线用户。然后,我将向您展示如何使用开源数据集构建您自己的电影推荐系统。

## 内容

*   为什么我们需要推荐系统?
*   推荐系统的类型
    A)基于内容的电影推荐系统
    B)协同过滤电影推荐系统
*   数据集
*   电影推荐系统的设计
*   实现
    步骤 1:基于矩阵分解的算法
    步骤 2:创建手工制作的特征
    步骤 3:为我们的电影推荐系统创建最终模型
*   性能指标
*   摘要

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 为什么我们需要推荐系统?

我们现在生活在一些人称之为“富足时代”的时代。对于任何给定的产品,有时有成千上万的选项可供选择。想想上面的例子:流媒体视频、社交网络、网上购物;这样的例子不胜枚举。推荐系统有助于个性化平台,帮助用户找到他们喜欢的东西。

最简单易行的方法就是推荐最受欢迎的单品。然而,要真正通过个性化推荐提升用户体验,我们需要专门的推荐系统。

从商业角度来看,用户在平台上找到的相关产品越多,他们的参与度就越高。这通常会增加平台本身的收入。各种消息来源称,多达 35-40%的科技巨头的收入仅来自推荐。

现在我们已经了解了推荐系统的重要性,让我们来看看推荐系统的类型,然后用开源数据构建我们自己的推荐系统!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 推荐系统的类型

推荐系统中的机器学习算法通常分为两类:基于内容的系统和协同过滤系统。现代推荐系统结合了这两种方法。

让我们看看他们是如何使用电影推荐系统作为基础的。

# a)基于内容的电影推荐系统

基于内容的方法是基于电影属性的相似性。使用这种类型的推荐系统,如果用户观看一部电影,相似的电影被推荐。例如,如果用户观看亚当·桑德勒主演的喜剧电影,系统将向他们推荐相同类型或相同演员主演的电影,或者两者都推荐。考虑到这一点,构建基于内容的推荐系统的输入是电影属性。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d7d7afb2898bc765fcdaf6c6ff4f5c8c.png)

图 1:基于内容的推荐系统概述(图片由作者创建)

# b)协同过滤电影推荐系统

通过协同过滤,该系统基于用户和电影之间过去的交互。考虑到这一点,协同过滤系统的输入由用户与他们观看的电影的交互的过去数据组成。

例如,如果用户 A 观看 M1、M2 和 M3,而用户 B 观看 M1、M3、M4,我们向相似的用户 c 推荐 M1 和 M3。为了更清楚地参考,您可以在下图中看到这种情况。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/57af64f12d7a7be8b23e24c6ce0893bf.png)

*图 2:协同过滤电影推荐系统的示例(由作者创建的图像)*

这些数据存储在一个名为用户-电影交互矩阵的矩阵中,其中行是用户,列是电影。

现在,让我们使用上面讨论的概念来实现我们自己的电影推荐系统。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 数据集

对于我们自己的系统,我们将使用来自 GroupLens 的开源 [MovieLens 数据集](https://grouplens.org/datasets/movielens/)。这个数据集包含各种电影和用户的 100K 个数据点。

我们将使用三列数据:

*   使用者辩证码
*   电影 Id
*   等级

您可以在下面的图 3 中看到数据的快照:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/14832bbf3c7c1feeea2ccc5a2579ebda.png)

图 3:数据快照(图片由作者提供)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 设计我们的电影推荐系统

为了获得对用户的推荐,我们将预测他们对尚未观看的电影的评分。然后基于这些预测的评级,电影被编入索引并被推荐给用户。

为此,我们将使用电影和用户评级的过去记录来预测他们未来的评级。在这一点上,值得一提的是,在现实世界中,我们很可能会遇到没有历史的新用户或电影。这种情况被称为冷启动问题。

让我们简单看看如何解决冷启动问题。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 冷启动问题

冷启动问题可以通过基于元信息的建议来处理,例如:

*   对于新用户,我们可以使用他们的位置、年龄、性别、浏览器和用户设备来预测推荐。
*   对于新电影,我们可以用流派、演员、剧组来推荐给目标用户。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 履行

对于我们的推荐系统,我们将使用上面提到的两种技术:基于内容的和协同过滤。对于我们的基于内容的方法,为了找到电影之间的相似性,我们将使用余弦相似性函数。对于我们的协作过滤方法,我们将使用矩阵分解技术。

第一步是创建一个基于矩阵分解的模型。我们将使用这个模型的输出和一些手工制作的功能来为最终的模型提供输入。基本流程如下所示:

*   步骤 1:构建基于矩阵分解的模型
*   步骤 2:创建手工制作的特征
*   步骤 3:实现最终模型

我们将在下面详细讨论这些步骤。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 步骤 1:基于矩阵分解的算法

[矩阵分解](https://datajobs.com/data-science-repo/Recommender-Systems-[Netflix].pdf)是一类用于推荐系统的协同过滤算法。由于非常有效,这一系列方法在[网飞奖挑战赛](https://netflixprize.com/index.html)期间广为人知。

矩阵分解算法通过将用户-电影交互矩阵分解成两个较低维度的矩形矩阵(比如 U 和 m)的乘积来工作。分解以这样的方式完成,使得乘积产生与用户-电影交互矩阵几乎相似的值。这里 U 代表用户矩阵,M 代表电影矩阵,n 代表用户数,M 代表电影数。

用户矩阵的每一行代表一个用户,电影矩阵的每一列代表一部电影。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/034d3d1eea1185f934746b97aff3a1ff.png)

图 4:矩阵分解(图片由作者创建)

一旦我们获得了 U 和 M 矩阵,基于用户-电影交互矩阵中的非空单元,我们执行 U 和 M 的乘积,并预测用户-电影交互矩阵中非空单元的值。

为了实现矩阵分解,我们使用了一个简单的名为 Surprise 的 Python 库,用于构建和测试推荐系统。数据帧被转换成训练集,一种被惊喜库接受的数据集格式。

```
from surprise import SVD
import numpy as np
import surprisefrom surprise import Reader, Dataset
# It is to specify how to read the data frame.
reader = Reader(rating_scale=(1,5))# create the traindata from the data frame
train_data_mf = Dataset.load_from_df(train_data[['userId', 'movieId', 'rating']], reader)# build the train set from traindata. 
#It is of dataset format from surprise library
trainset = train_data_mf.build_full_trainset()svd = SVD(n_factors=100, biased=True, random_state=15, verbose=True)
svd.fit(trainset)
```

现在模型准备好了。我们将存储这些预测,并作为附加特征传递给最终模型。这将有助于我们将协同过滤整合到我们的系统中。

```
#getting predictions of train set
train_preds = svd.test(trainset.build_testset())
train_pred_mf = np.array([pred.est for pred in train_preds])
```

请注意,我们还必须对测试数据执行上述步骤。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 步骤 2:创建手工特征

让我们将数据帧格式的数据转换成用户-电影交互矩阵。在这类问题中使用的矩阵通常是稀疏的,因为用户很可能只对几部电影进行评级。

数据的稀疏矩阵格式(也称为 CSR 格式)的优点如下:

*   高效的算术运算:CSR + CSR,CSR * CSR 等。
*   高效的行切片
*   快速矩阵向量乘积

scipy.sparse.csr_matrix 是一个实用函数,可以有效地将数据帧转换为稀疏矩阵。

```
# Creating a sparse matrix
train_sparse_matrix = sparse.csr_matrix((train_data.rating.values, (train_data.userId.values, train_data.movieId.values)))
```

‘train _ sparse _ matrix’是 train_data 数据帧的稀疏矩阵表示。

我们将使用此稀疏矩阵创建 3 组特征:

1.  代表全球平均值的特征
2.  代表前五名相似用户的功能
3.  代表前五部类似电影的特写

让我们更详细地了解一下如何准备每一项。

## 1.代表全球平均值的特征

我们将采用的三个全球平均值是:

1.  所有用户对所有电影的平均评分
2.  所有用户对特定电影的平均评级
3.  特定用户给出的所有电影的平均评级

```
train_averages = dict()
# get the global average of ratings in our train set.
train_global_average = train_sparse_matrix.sum()/train_sparse_matrix.count_nonzero()
train_averages['global'] = train_global_average
train_averagesOutput: {‘global’: 3.5199769425298757}Next, let’s create a function which takes the sparse matrix as input and gives the average ratings of a movie given by all users, and the average rating of all movies given by a single user.# get the user averages in dictionary (key: user_id/movie_id, value: avg rating)
def get_average_ratings(sparse_matrix, of_users):# average ratings of user/axes
ax = 1 if of_users else 0 # 1 - User axes,0 - Movie axes# ".A1" is for converting Column_Matrix to 1-D numpy array
sum_of_ratings = sparse_matrix.sum(axis=ax).A1# Boolean matrix of ratings ( whether a user rated that movie or not)
is_rated = sparse_matrix!=0# no of ratings that each user OR movie..
no_of_ratings = is_rated.sum(axis=ax).A1# max_user and max_movie ids in sparse matrix
u,m = sparse_matrix.shape
# create a dictionary of users and their average ratings..
average_ratings = { i : sum_of_ratings[i]/no_of_ratings[i]for i in range(u if of_users else m)
if no_of_ratings[i] !=0}#return that dictionary of average ratings
return average_ratings
```

平均评级由用户给出:

```
train_averages['user'] = get_average_ratings(train_sparse_matrix, of_users=True)
```

电影的平均评级如下:

```
train_averages['movie'] = get_average_ratings(train_sparse_matrix, of_users=False)
```

## 2.代表前 5 名相似用户的功能

在这组功能中,我们将创建对特定电影进行评级的前 5 名相似用户。使用用户之间的余弦相似度来计算相似度。

```
# compute the similar Users of the "user"user_sim = cosine_similarity(train_sparse_matrix[user], train_sparse_matrix).ravel()
top_sim_users = user_sim.argsort()[::-1][1:] # we are ignoring 'The User' from its similar users.# get the ratings of most similar users for this movie
top_ratings = train_sparse_matrix[top_sim_users, movie].toarray().ravel()# we will make it's length "5" by adding movie averages to
top_sim_users_ratings = list(top_ratings[top_ratings != 0][:5])
top_sim_users_ratings.extend([train_averages['movie'][movie]]*(5 -len(top_sim_users_ratings)))
```

## 3.代表前 5 部相似电影的特征

在这组特征中,我们获得了由特定用户评价的前 5 部相似电影。使用电影之间的余弦相似度来计算该相似度。

```
# compute the similar movies of the "movie"
movie_sim = cosine_similarity(train_sparse_matrix[:,movie].T,
train_sparse_matrix.T).ravel()
top_sim_movies = movie_sim.argsort()[::-1][1:]# we are ignoring 'The User' from its similar users.
# get the ratings of most similar movie rated by this user
top_ratings = train_sparse_matrix[user, top_sim_movies].toarray().ravel()# we will make it's length "5" by adding user averages to
top_sim_movies_ratings = list(top_ratings[top_ratings != 0][:5])
top_sim_movies_ratings.extend([train_averages['user'][user]]*(5-len(top_sim_movies_ratings)))
```

我们为每个电影用户对添加所有这些特征,并创建一个数据框。图 5 是我们的数据框的快照。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9211cb31b90ba96974264ad86d08ed1a.png)

图 5:包含 13 个特性的数据概述

以下是其内容的更详细的分类:

*   GAvg:所有评分的平均评分
*   这部电影的相似用户评分:sur1、sur2、sur3、sur4、sur5(对这部电影评分的前 5 名相似用户)
*   此用户评价的相似电影:smr1、smr2、smr3、smr4、smr5(用户评价的前 5 部相似电影)
*   用户平均评分
*   MAvg:这部电影的平均评分
*   分级:此用户对此电影的分级。

一旦我们准备好这 13 个特性,我们将添加矩阵分解输出作为第 14 个特性。在图 6 中,您可以看到添加步骤 1 的输出后的数据快照。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/082385593060acddfe0cf8665a89b74c.png)

图 6:具有 13 个特征和矩阵分解输出的数据概述(图片由作者提供)

最后一列名为 mf_svd,是包含步骤 1 中执行的模型输出的附加列。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 步骤 3:为我们的电影推荐系统创建一个最终模型

为了创建我们的最终模型,让我们使用 [XGBoost](https://xgboost.readthedocs.io/en/latest/) ,一个优化的分布式梯度增强库。

```
# prepare train data
x_train = final_data.drop(['user', 'movie','rating'], axis=1)
y_train = final_data['rating']
# initialize XGBoost model
xgb_model = xgb.XGBRegressor(silent=False, n_jobs=13,random_state=15,n_estimators=100)
# fit the model
xgb_model.fit(x_train, y_train, eval_metric = 'rmse')
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 性能指标

评价推荐系统的性能主要有两种方法:均方根误差(RMSE)和平均绝对百分比误差(MAPE)。RMSE 衡量的是平方损失,而 MAPE 衡量的是绝对损失。较低的值意味着较低的错误率,因此性能更好。

两者都很好,因为它们允许简单的解释。让我们来看看它们分别是什么:

# 均方根误差(RMSE)

RMSE 是误差平方平均值的平方根,由下式给出。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8c32ab579da3e354df19074d2df9e4c0.png)

其中:
r 是实际收视率,
r^是预测收视率,
N 是预测总数

# 平均绝对百分比误差(MAPE)

MAPE 用百分比来衡量误差。它由下面的公式给出:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ae8019ca1093cca129432f029febcb8c.png)

其中:
r 是实际收视率,
r^是预测收视率,
N 是预测总数

```
#dictionaries for storing train and test results
test_results = dict()
# from the trained model, get the predictions
y_est_pred = xgb_model.predict(x_test)
# get the rmse and mape of train data
rmse = np.sqrt(np.mean([ (y_test.values[i] - y_test_pred[i])**2 for i in
range(len(y_test_pred)) ]))
mape = np.mean(np.abs( (y_test.values- y_test_pred)/y_true.values )) * 100
# store the results in train_results dictionary
test_results = {'rmse': rmse_test, 'mape' : mape_test, 'predictions' : y_test_pred}
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4b9b4ae85b61a151b326ad27f66a9aba.png)

我们的模型在看不见的测试数据上得到 0.67 的 RMSE 和 19.86 的 MAPE,这是一个很好的模型。小于 2 的 RMSE 值被认为是好的,小于 25 的 MAPE 是极好的。也就是说,这种模式可以通过添加功能来进一步增强,这些功能将根据位置或流派的最佳选择进行推荐。我们还可以通过 A/B 测试实时测试各种模型的功效。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

# 摘要

在本文中,我们学习了推荐系统的重要性,正在实现的推荐系统的类型,以及如何使用矩阵分解来增强系统。然后,我们构建了一个电影推荐系统,它考虑了用户-用户相似性、电影-电影相似性、全局平均值和矩阵分解。这些概念可以应用于任何其他用户-项目交互系统。

感谢阅读!如果你想自己试验这个自定义数据集,你可以在 [GroupLens](https://grouplens.org/datasets/movielens/) 下载带注释的数据,并在 [Github](https://github.com/RamyaVidiyala/MovieRecommenderSystem) 查看我的代码。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85ae43ab2bc681c76ea69fc1b64ac999.png)

谢谢你的阅读。本文原载[此处](https://lionbridge.ai/articles/step-by-step-guide-to-building-a-movie-recommendation-system/)。我也将在未来写更多初学者友好的帖子。请在[媒体](https://medium.com/@ramyavidiyala)上关注我,以便了解他们。我欢迎反馈,可以通过 Twitter [ramya_vidiyala](https://twitter.com/ramya_vidiyala) 和 LinkedIn [RamyaVidiyala](https://www.linkedin.com/in/ramya-vidiyala-308ba6139/) 联系我。快乐学习!

# 如何用 std::async 在 C++中构建多线程管道

> 原文:<https://towardsdatascience.com/how-to-build-a-multi-threaded-pipeline-in-c-with-std-async-78edc19e862d?source=collection_archive---------15----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6e0c674cb20cd2076fabb4e5db04e67d.png)

由[凯文·Ku](https://unsplash.com/@ikukevk?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄

今天我们要弄清楚如何在 C++11 中创建一个能够处理流数据的多线程应用程序。更重要的是,我们不会自己创建任何 std::thread-s,相反,我们将采用未来和异步调用的新功能范式。

本教程的代码可以在 Github 上找到:

[](https://github.com/Obs01ete/async_pipeline) [## OBS 01 远程/异步管道

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

github.com](https://github.com/Obs01ete/async_pipeline) 

这项工作的动机是,当您想要在 CPU 上执行一些繁重的计算时,您不可避免地想要在多线程中运行它。否则,数据研磨的带宽将被限制在一个线程内。例如,如果你有一个来自网络摄像头的图像流,你想对它应用几个过滤器:颜色调整,调整大小,甚至可能是一些人工智能,比如人脸检测,运行所有这些处理步骤可能需要数百毫秒。当源帧速率为 30 fps 时,您可能会在可视化窗口中得到令人失望的 5–10 fps。我们通过 <future>header 和 stdlib 的内容来看看如何处理。</future>

然后让我们创建我们的处理函数`func1`和`func2`。在本教程中,我们不会运行真正的计算,因此作为概念验证,让我们设置模拟线程繁忙的睡眠。

最后,我们希望可视化处理的结果,比如调用 OpenCV 的 cv::showImage()。为了简单起见,我们在这里放置了一个简单的 std::cout 打印输出。

现在我们准备好准备我们的主要应用程序。

是时候推出我们的应用程序,看看我们有什么。

```
Enqueued sample: 0
Enqueued sample: 1
Sample 0 output: ‘input_string_0 func1 func2’ finished at 1851
Sample 1 output: ‘input_string_1 func1 func2’ finished at 2851
Enqueued sample: 2
Sample 2 output: ‘input_string_2 func1 func2’ finished at 3851
Enqueued sample: 3
Sample 3 output: ‘input_string_3 func1 func2’ finished at 4851
Enqueued sample: 4
Enqueued sample: 5
Sample 4 output: ‘input_string_4 func1 func2’ finished at 5851
Sample 5 output: ‘input_string_5 func1 func2’ finished at 6851
Enqueued sample: 6
...
Enqueued sample: 98
Sample 98 output: 'input_string_98 func1 func2' finished at 99862
Enqueued sample: 99
Waiting to finish...
Sample 99 output: 'input_string_99 func1 func2' finished at 100862
Finished!
```

太神奇了,管道成功了!请注意样本可视化时刻之间的时间差:为 1000 毫秒。如果没有多线程管道,则为 900+950=1850 毫秒。

std::async 的一个优点是它在幕后管理一个线程池。所以不用担心每次我们调用 std::async 时都会启动一个新线程。后续调用会重用线程,因此操作系统不会因为启动和终止大量线程而过载。

人们可能会注意到代码中的一些缺陷:

*   std::cout 不受互斥体保护。
*   异常不由处理函数处理。
*   我们正在向`func#`,尤其是`visualize`传递大量的争论。值得考虑将代码组织成一个类。

这些我将在下一篇文章中讨论。

谢谢你看我的教程,下期再见!

# 从数据抓取到结果分析,构建完整的容器化机器学习解决方案

> 原文:<https://towardsdatascience.com/how-to-build-a-museum-attribute-collection-and-attribute-analysis-system-82a6a9a840a?source=collection_archive---------61----------------------->

## 这篇文章解释了如何一步一步地构建一个 ML 项目

# 介绍

在这里,我将描述如何建立一个系统来从维基百科中检索数据,将它们存储在 Postgres 数据库中,最后执行线性回归算法来预测城市人口和游客涌入之间的相关性。

> 在我的工作面试过程中,我被要求建立一个系统,从维基百科收集数据,并将其存储在数据库中。最后,我被要求执行一个小的线性回归 ML 算法来检查数据之间的关系。我正在分享我的过程和想法,关于我如何为任何可能有兴趣做类似项目的人建立这个系统。该项目可以很容易地扩展或适用于任何其他领域。

我为采访准备的演示文稿和代码可以在我的 [Github](https://github.com/ShiNik/wiki_ml) 上找到。

# **系统管道**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/31d779f10372ae51f86ad7a40fc7e455.png)

# Docker 编写模块

*   提供一致的执行环境
*   启动系统的单一命令
*   包含多个容器
*   在容器之间提供一个隔离的网络环境
*   根据依赖关系按顺序管理启动容器的协调

docker-compose 环境包含 4 个容器: [Postgres 数据库](https://hub.docker.com/_/postgres)、 [PgAdmin](https://www.pgadmin.org/download/pgadmin-4-container/) 、 [Python 3.7.6 应用主机](https://hub.docker.com/_/python)和 [Jupyter 笔记本](https://hub.docker.com/u/jupyter/)

要查看最终的 docker-compose 文件,请参考我的 [Github](https://github.com/ShiNik/wiki_ml/blob/master/docker-compose.yml) 。

# 数据提取器模块

数据提取是从万维网上自动挖掘数据或收集信息的过程。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7a34911bfbfee2e587de55b8c3eb368d.png)

数据提取器模块-类图

本项目中使用的两个数据来源是[世界城市文化论坛 wiki 页面](http://www.worldcitiescultureforum.com/data/number-of-international-tourists-per-year)和[参观最多的博物馆 wiki 页面](https://en.wikipedia.org/wiki/List_of_most_visited_museums)。

结合使用 [wiki-api](https://en.wikipedia.org/w/api.php?action=help&modules=parse) 和 Python [请求](https://requests.readthedocs.io/en/master/)库来访问维基百科页面和检索信息。请求库以 wikitext 的形式获取文本。需要对 Wikitext 进行解析,以便从中提取完整信息的含义。

有许多库可用于解析 wikitext。在分析了几种之后,我决定使用 [wikitextparser](https://github.com/5j9/wikitextparser) 。然而,并不是所有的文本在经过解析器后都会变得非常清晰。为了解决这个问题,我编写了一个[后处理](https://github.com/ShiNik/wiki_ml/blob/master/src/my_package/parser.py)模块,使用 [Wiki 表规则](https://en.wikipedia.org/wiki/Help:Table)和[正则表达式](https://en.wikipedia.org/wiki/Regular_expression)在将文本存储到数据库之前对其进行更多的清理。

这些数据总共包括了 33 个城市和 46 个博物馆的信息。检索每个城市的以下特征:名称、人口、规模、报告年份、游客总数。对于每个博物馆,检索以下特征:名称、游客、类型、公共交通、位置、建立、建造、报告年份。

然而,一些维基页面有丢失的数据。下图显示了检索到的数据。缺失的数据用紫色标记。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f03f3034f9857ddb0195c860930512ca.png)

检索到的数据和缺失的数据

# 数据库模块

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c0b36ad2458f309c45302b65ed991d71.png)

数据库模块-类图

我使用了 [postgres](https://www.postgresql.org/) 开源数据库,它与 [SQLAlchemy](https://www.sqlalchemy.org/) 一起支持这个项目。SQLAlchemy 是一个 Python SQL 工具包,它为开发人员提供了 SQLRelational Mapper 的全部功能和灵活性。如果你需要了解更多关于 AQLAlchemy 的知识,请参考他们的教程[](https://www.sqlalchemy.org/library.html#tutorials)

因为数据是为博物馆和城市提取的,所以这个项目只需要 2 个表。每个博物馆和城市都有一个唯一的 id 作为主键。城市 id 是博物馆表中的外键。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/82b88a8a89f530238bb6caa00b80443a.png)

数据库表

有关该项目的数据库的详细信息,请参考我的 [Github](https://github.com/ShiNik/wiki_ml/blob/master/src/my_package/database_manager.py) 。

# 记录器、配置和可视化模块

记录器记录应用程序中发生的详细事件。日志有助于解决应用程序和基础设施性能问题。用户可以设置不同的日志记录级别。logger 模型在内部使用 python [日志](https://docs.python.org/3/library/logging.html)库。

该配置用于设置系统不同模块的参数,并避免使用任何硬编码设置。当前系统使用的一些配置包括主维基页面名称、数据库配置以及维基页面和数据库字段之间的翻译器。

可视化工具是一个独立的模块。它的工作是为了可视化的目的生成不同的图。

关于[记录器](https://github.com/ShiNik/wiki_ml/blob/master/src/my_package/log_manager.py)、[配置](https://github.com/ShiNik/wiki_ml/blob/master/src/my_package/config.py)和[可视化器](https://github.com/ShiNik/wiki_ml/blob/master/src/my_package/visualizer.py)的详细信息可以在我的 Github 中找到。

# 机器学习模块

机器学习模块的目标是创建一个线性回归算法,以探索城市人口和游客涌入之间的相关性。该模块由以下几个阶段组成:

*   数据清理
*   评估数据分布
*   线性回归
*   相互关系
*   模型评估
*   实验
*   结果分析

关于[机器学习模块](https://github.com/ShiNik/wiki_ml/blob/master/src/my_package/machine_learning_manager.py)的详细信息可以在我的 Github 中找到。

## 数据清理

为了获得更准确的预测结果,数据质量很重要。数据清理用于改善和提高数据质量。在本项目中,执行以下清理程序来清理和纠正数据,使其可用:

1-使用正则表达式从总体中删除不需要的字符,如逗号(",")

2-使用正则表达式从年份中提取数字

3-将数字数据从字符串转换为数字

4-删除丢失的数据

## 评估数据分布

数据分布是更好地理解数据的一个很好的工具。有许多方法可以评估数据分布,如直方图、箱线图等。在这个项目中,数据的分布用直方图和概率图来表示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/715bcef486528a5058e2078d13d11ba8.png)

博物馆游客数据分布

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/304c4fcf890a74152c5b8bdc8d8ab31d.png)

城市人口数据分布

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4b615d87c8e7e6222fd1ae439be41dd6.png)

概率图博物馆游客

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6fa5ee652bbd47677c500084f69c62b8.png)

城市人口概率图

## 线性回归

L [线性回归](https://en.wikipedia.org/wiki/Linear_regression)是一种[线性](https://en.wikipedia.org/wiki/Linearity)方法,用于模拟一个[因变量](https://en.wikipedia.org/wiki/Dependent_variable)和一个或多个[自变量](https://en.wikipedia.org/wiki/Independent_variable)之间的关系。下图说明了线性回归方程和图表。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8a718dce3535699bdabc79855c35d97d.png)

线性回归公式

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0bb60a3e31378ce6802cb380d0442f56.png)

[线性回归](https://www.analyticbridge.datasciencecentral.com/profiles/blog/show?id=2004291:BlogPost:317210)

## 相互关系

当两组数据具有高相关值**时,它们被强有力地链接在一起。**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/04604d22ee1afb19c1054d6beebb9cd0.png)

[相关性](https://www.mathsisfun.com/data/correlation.html)

相关性可能有价值:

*   1 是完美的正相关
*   0 表示没有相关性(这些值看起来根本没有关联)
*   -1 是完美的负相关
*   当值一起增加时,相关性为正,并且
*   当一个值随着另一个值的增加而减少时,相关性为负

## 模型评估

模型评估是用于选择最佳模型的方法,而不考虑架构或参数。估计模型对样本外数据的推广程度的过程称为模型评估过程。

最常见的模型评估程序是训练/测试分割程序。这是一个非常快速和简单的程序,并提供了非常精确的样本外性能估计。最佳实践之一是将数据随机分为训练集和测试集。我使用 Scikit 包中的 train_test_split 函数进行数据拆分。我选择 80%的数据用于训练,20%用于测试。

您总是需要一个评估指标来配合您选择的过程。度量标准的选择取决于您要解决的问题的类型。对于回归问题,平均绝对误差、均方误差和均方根误差通常用作评估指标。

## 实验

因为我的数据的值的范围是变化的,所以我也执行了数据标准化。

> 当要素具有不同的范围以将数据的值更改为通用范围时,数据规范化是一种经常作为机器学习的数据准备的一部分而应用的技术。

为了验证因变量(博物馆游客)和自变量(城市人口/城市游客)之间的相关性,散点图生成如下:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b58a07c0fb46577f873c5fb35be2a8be.png)

城市人口与博物馆游客

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b88f1704e865bcdd93f627234e67c7b7.png)

城市游客与博物馆游客

下图显示了模型评估程序:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/805df732cd579e9d0f94cac05b162966.png)

城市人口实际值与预测值对比结果

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/427c714b7fce9d38a63a40e3f6153680.png)

城市游客实际值与预测值对比结果

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/902644489d3f29296f1d19c58aa71938.png)

预测数据与测试数据

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e098e507577da9c3222899b9b0d5d736.png)

预测数据与测试数据

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/135f2342c4ebce6985066e393e733a95.png)

城市人口残差图

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7406c7e1b07973ad87938aaf1aa234ac.png)

城市游客残差图

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7d9bb58d8c6d300f533295e9f25b9a01.png)

城市人口和城市游客误差评估

C.p:城市人口

C.v:城市游客

博物馆参观者

EV:解释的差异

PCC:皮尔逊相关系数

MSLE:均方对数误差

R2:决定系数(R)

平均绝对误差

MSE:均方差

RMSE:均方根误差

进行的另一个实验是为了找出最大游客量的城市人口、每个城市博物馆的所有游客和每个博物馆的游客之间的相关性。用城市游客代替城市人口进行了同样的分析。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2e5ecc8d46b47e55f2e3f214e5345545.png)

实验结果

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/790dfb481fc72729327079786d95ada1.png)

Li 回归分析,最差结果用黄色标记,最佳结果用橙色标记

## 结果分析

1.  人口与博物馆参观者没有显著的相关性。
2.  单一的特征并不能很好地预测博物馆的参观者。
3.  由于需要更多的数据、错误的假设或较差的特征,模型不符合数据。
4.  数据收集不符合真实的数据分布,例如数据年份不匹配,博物馆游客仅涵盖 2018 年,但城市人口和城市游客属于任何一年。

# 改进

我认为将来可以对该项目进行一些改进:

## **系统级**

*   使用 NLP 为 wiki 提取信息
*   拥有一个交互系统来获取用户输入以进行关联
*   使用 JSON 文件而不是配置文件
*   使用 Django 和 Flask python 库添加 web 界面,以通过浏览器显示用户界面
*   分析数据库以提高性能

## **数据等级**

*   为了有效地提取特征,回顾关于游客和博物馆之间关系的现有方法
*   获取更多数据,如博物馆到公共交通、餐馆等的距离。
*   有了更多的数据,通过使用多元线性回归找到最相关的要素
*   执行决策树以找到访客最多时最有效的功能

# 结论

希望这篇文章对那些想知道如何做类似项目的人有所帮助。帖子的代码可以在我的 [Github](https://github.com/ShiNik/wiki_ml) 上找到。

# 如何建立用于语音分类的神经网络

> 原文:<https://towardsdatascience.com/how-to-build-a-neural-network-for-voice-classification-5e2810fe1efa?source=collection_archive---------8----------------------->

## Python 的完整代码演练

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f95aa8e8de7e1d62e35d9c40417dde91.png)

[图片来自 Adobe Stock281653938 作者 korkeng](https://stock.adobe.com/search?k=neural&search_type=default-asset-click&asset_id=281653938)

如果能将我们的 Zoom 会议记录下来,用纯文本的形式告诉我们谁在会议中说了什么,这不是很好吗?这个项目诞生于记录会议告诉你每个人说了什么的想法。我们有许多将语音转换为文本的转录工具,但没有多少工具可以识别每个说话者。为此,我们将使用这里包含的所有代码从头开始构建一个 python 语音分类器。

首先,一如既往,我们需要数据。这个数据来自 [OpenSLR](http://www.openslr.org/12/) 。对于我们的训练数据,我们将使用 30 个不同的说话者和每个说话者 4 个样本,给我们 120 个样本。每个样本平均 15 秒,因此每个说话者大约一分钟用于训练。对于我们的问题陈述来说,30 个演讲者是一个很好的数量;因为我已经进行了这个项目,我可以断言一分钟足够给我们带来好的结果。

除了用于训练的 120 个样本,我们还需要验证和测试数据。我们将对 3 个样品进行验证,并对 3 个样品进行测试。由于我们有 30 个扬声器,我们需要 90 个样品进行验证,90 个样品进行测试。因此,我们将需要每个发言者的 10 个语音剪辑。

为了总结样本,我们将使用 120 个语音剪辑作为训练数据,90 个语音剪辑作为验证数据,90 个语音剪辑作为测试数据,总共 300 个语音剪辑。

一旦我们在三个不同的文件夹中有了用于训练、验证和测试的语音剪辑,我们就可以创建我们的熊猫数据框架了。我们需要导入*操作系统*,这样我们就可以从文件夹中的文件创建一个数据框架(我在 mac 上工作,对于其他操作系统,这个过程可能会有点不同)。我训练的文件夹叫 *30_speakers_train* 。

```
import os#list the files
filelist = os.listdir('30_speakers_train') #read them into pandas
train_df = pd.DataFrame(filelist)
```

这将为我的训练数据创建一个数据框架。检查数据帧的大小非常重要,这样可以确保它与文件夹中的文件数量相匹配。

让我们将文件列命名为“文件”。

```
# Renaming the column name to file
train_df = train_df.rename(columns={0:'file'})
```

有时一个[*’。DS_Store'*](https://en.wikipedia.org/wiki/.DS_Store) 文件已创建,我们必须找到并删除该特定文件才能继续。之后,我们需要重置数据帧的索引。这里有一个例子:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4f0f2b0ae2555dd80a49ae088cc44bee.png)

如何删除'的示例。“DS_Store”文件

```
# Code in case we have to drop the '.DS_Store' and reset the index
train_df[train_df['file']=='.DS_Store']
train_df.drop(16, inplace=True)
train_df = train_df.sample(frac=1).reset_index(drop=True)
```

现在,我们需要确定每个发言者。在我的文件名中,第一组数字是发言者 ID,因此我写了一点代码来创建一个具有该 ID 的列。

```
# We create an empty list where we will append all the speakers ids for each row of our dataframe by slicing the file name since we know the id is the first number before the hashspeaker = []
for i in range(0, len(df)):
    speaker.append(df['file'][i].split('-')[0])# We now assign the speaker to a new column 
train_df['speaker'] = speaker
```

我们的数据帧应该是这样的:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7ee763b923ba111d630c9b3fdc513431.png)

我们对验证和测试文件做同样的工作,得到三个不同的数据帧。

现在我们有了数据帧,我们需要写一个函数来提取每个音频文件的音频属性。为此,我们使用 librosa,这是一个很好的用于音频操作的 python 库。我们需要 pip 安装 librosa 并导入 librosa。下面是解析我们文件夹中的每个文件并从每个文件中提取 5 个数字特征的函数,即 mfccs、chroma、mel、contrast 和 tonnetz。

```
def extract_features(files):

    # Sets the name to be the path to where the file is in my computer
    file_name = os.path.join(os.path.abspath('30_speakers_train')+'/'+str(files.file))# Loads the audio file as a floating point time series and assigns the default sample rate
    # Sample rate is set to 22050 by default
    X, sample_rate = librosa.load(file_name, res_type='kaiser_fast')# Generate Mel-frequency cepstral coefficients (MFCCs) from a time series 
    mfccs = np.mean(librosa.feature.mfcc(y=X, sr=sample_rate, n_mfcc=40).T,axis=0)# Generates a Short-time Fourier transform (STFT) to use in the chroma_stft
    stft = np.abs(librosa.stft(X))# Computes a chromagram from a waveform or power spectrogram.
    chroma = np.mean(librosa.feature.chroma_stft(S=stft, sr=sample_rate).T,axis=0)# Computes a mel-scaled spectrogram.
    mel = np.mean(librosa.feature.melspectrogram(X, sr=sample_rate).T,axis=0)# Computes spectral contrast
    contrast = np.mean(librosa.feature.spectral_contrast(S=stft, sr=sample_rate).T,axis=0)# Computes the tonal centroid features (tonnetz)
    tonnetz = np.mean(librosa.feature.tonnetz(y=librosa.effects.harmonic(X),
    sr=sample_rate).T,axis=0)return mfccs, chroma, mel, contrast, tonnetz
```

每个 mfcc 是长度为 40 的数组,色度为 12,mel 为 128,对比度为 7,tonnetz 为 6。总的来说,从我们选择的音频特征中,每个语音片段有 193 个数字特征。如果你愿意,请随意尝试不同的方法:l [ibrosa 特征提取](https://librosa.github.io/librosa/0.6.0/feature.html)。我们将该函数应用于每个单独的音频文件,并存储该信息。请注意,这确实需要几分钟,甚至可能需要几个小时,这取决于您使用的数据量和您的计算能力。

```
train_features = train_df.apply(extract_features, axis=1)
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/44d1e63e93d55b7b0f8076044d22f625.png)

现在,我们将每个文件的所有这些数字特征连接起来,这样我们就有一个包含 193 个数字的单个数组来输入我们的神经网络。

```
features_train = []
for i in range(0, len(train_features)):
    features_train.append(np.concatenate((
        train_features[i][0],
        train_features[i][1], 
        train_features[i][2], 
        train_features[i][3],
        train_features[i][4]), axis=0))
```

现在,我们可以将 X_train 设置为我们的特性的 numpy 数组:

```
X_train = np.array(features_train)
```

类似地,我们从一开始就为我们的验证和测试数据做同样的步骤。我们应该得到一个 *X_val**X_test* 。

现在,我们完成了我们的 *X* 数据。对于 *Y* ,我们需要演讲者的 id。请记住,我们正在进行监督学习,因此我们需要目标数据。我们从原始数据帧中得到这些,因此我们只得到这些值。

```
y_train = np.array(train_df['speaker'])
y_val = np.array(val_df['speaker'])
```

我们需要对 y 进行热编码,以便能够将其用于我们的神经网络。您需要从 *sklearn* 中导入 *LabelEncoder* ,从使用 *Tensorflow**keras* 中导入*to _ categorial*。

```
from sklearn.preprocessing import LabelEncoder
from keras.utils.np_utils import to_categorical# Hot encoding y
lb = LabelEncoder()
y_train = to_categorical(lb.fit_transform(y_train))
y_val = to_categorical(lb.fit_transform(y_val))
```

现在我们需要扩展我们的 *X* :

```
from sklearn.preprocessing import StandardScalerss = StandardScaler()
X_train = ss.fit_transform(X_train)
X_val = ss.transform(X_val)
X_test = ss.transform(X_test)
```

最后,我们准备好了有趣的部分:构建神经网络!我们将使用一个简单的前馈神经网络。输入将是我们的 193 个特征。我摆弄了一下辍学率,但是如果你愿意,你可以改变这些数值。使用 relu 是相当标准的。输出是 softmax,因为我们有 30 个不同的类,并且因为不同的类,我们使用分类交叉熵。

```
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.callbacks import EarlyStopping# Build a simple dense model with early stopping and softmax for categorical classification, remember we have 30 classesmodel = Sequential()model.add(Dense(193, input_shape=(193,), activation = 'relu'))
model.add(Dropout(0.1))model.add(Dense(128, activation = 'relu'))
model.add(Dropout(0.25))model.add(Dense(128, activation = 'relu'))
model.add(Dropout(0.5))model.add(Dense(30, activation = 'softmax'))model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')early_stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=100, verbose=1, mode='auto')
```

现在,我们用训练和验证数据拟合模型:

```
history = model.fit(X_train, y_train, batch_size=256, epochs=100, 
                    validation_data=(X_val, y_val),
                    callbacks=[early_stop])
```

这是一些代码,用于查看训练和验证准确性的图表:

```
# Check out our train accuracy and validation accuracy over epochs.
train_accuracy = history.history['accuracy']
val_accuracy = history.history['val_accuracy']# Set figure size.
plt.figure(figsize=(12, 8))# Generate line plot of training, testing loss over epochs.
plt.plot(train_accuracy, label='Training Accuracy', color='#185fad')
plt.plot(val_accuracy, label='Validation Accuracy', color='orange')# Set title
plt.title('Training and Validation Accuracy by Epoch', fontsize = 25)
plt.xlabel('Epoch', fontsize = 18)
plt.ylabel('Categorical Crossentropy', fontsize = 18)
plt.xticks(range(0,100,5), range(0,100,5))plt.legend(fontsize = 18);
```

它应该是这样的:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/dabf6808b303fe77eaf53b5902a8efdc.png)

看起来我们得到了一些很好的准确性!让我们用测试数据来检查这些值。我们可以用神经网络的结果生成预测,并将它们与实际值进行比较。

```
# We get our predictions from the test data
predictions = model.predict_classes(X_test)# We transform back our predictions to the speakers ids
predictions = lb.inverse_transform(predictions)# Finally, we can add those predictions to our original dataframe
test_df['predictions'] = predictions
```

现在,我们的测试数据 dataframe 应该是这样的:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a6bebd5a808081390b940b0bd9df932b.png)

```
# Code to see which values we got wrong
test_df[test_df['speaker'] != test_df['predictions']]# Code to see the numerical accuracy
(1-round(len(test_df[test_df['speaker'] != test_df['predictions']])/len(test_df),3))*100
```

您应该得到这样的结果:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c86aa67cd890475a0b03582ed48b6b67.png)

98.9%的正确预测!我不得不运行神经网络四次,最终得到一个错误的预测。在前三次运行中,神经网络得到了所有正确的预测,但我想展示如何找到一个错误的预测。因此,通过一分钟的训练音频,神经网络对于 30 个扬声器来说近乎完美!

这证明了一个简单的神经网络有多么强大!希望对你有帮助!

这里是我的 [jupyter 笔记本](https://github.com/jurgenarias/Portfolio/blob/master/Blogs/Code/Voice_Classification_full_code_for_blogpost.ipynb)的链接,里面有所有的代码。我也使用卷积神经网络(CNN)做了这个和类似的项目,如果你感兴趣,你可以在这里 看到我的另一篇解释那个过程的帖子 [*。*](/voice-classification-with-neural-networks-ff90f94358ec)

## **来源:**

数据集:[http://www.openslr.org/12/](http://www.openslr.org/12/)

[1]大卫·卡斯帕,亚历山大·贝利,帕特里克·富勒, [Librosa:一个 Python 音频库(2019)](https://medium.com/@patrickbfuller/librosa-a-python-audio-libary-60014eeaccfb)

[2] Rami S. Alkhawaldeh,[DGR:使用一维常规神经网络的人类语音性别识别](https://www.hindawi.com/journals/sp/2019/7213717/) (2019)

[3]科里·贝克尔,[使用机器学习识别声音的性别](http://www.primaryobjects.com/2016/06/22/identifying-the-gender-of-a-voice-using-machine-learning/) (2016)

[4] [乔纳森·巴拉班](https://towardsdatascience.com/@ultimatist?source=post_page-----1ef708ec5f53----------------------),[深度学习技巧和窍门](/deep-learning-tips-and-tricks-1ef708ec5f53) (2018)

[5] [Youness Mansar](https://medium.com/@CVxTz?source=post_page-----b0a4fce8f6c----------------------) ,[音频分类:一种卷积神经网络方法](https://medium.com/@CVxTz/audio-classification-a-convolutional-neural-network-approach-b0a4fce8f6c) (2018)

[6] [Faizan Shaik](https://www.analyticsvidhya.com/blog/author/jalfaizy/) h,[使用深度学习开始音频数据分析(附案例研究)](https://www.analyticsvidhya.com/blog/2017/08/audio-voice-processing-deep-learning/) (2017)

[7] [麦克·斯梅尔斯](https://medium.com/@mikesmales?source=post_page-----8bc2aa1990b7----------------------),[利用深度学习的声音分类](https://medium.com/@mikesmales/sound-classification-using-deep-learning-8bc2aa1990b7),(2019)

[8] [Aaqib Saeed](http://aqibsaeed.github.io/) ,[城市声音分类,第 1 部分](http://aqibsaeed.github.io/2016-09-03-urban-sound-classification-part-1/),(2016)

[9] Marc Palet Gual,[使用运行在 FPGA 上的深度神经网络进行声音性别识别](https://upcommons.upc.edu/bitstream/handle/2117/86673/113166.pdf),(2016)

[10] [Kamil Ciemniewski](https://www.endpoint.com/team/kamil_ciemniewski) ,[在 TensorFlow](https://www.endpoint.com/blog/2019/01/08/speech-recognition-with-tensorflow) ,【2019】中使用扩展卷积和 CTC 从零开始进行语音识别

[11] [Admond Lee](https://towardsdatascience.com/@admond1994?source=post_page-----81d0fe3cea9a----------------------) ,[如何用 Python 构建语音识别机器人](/how-to-build-a-speech-recognition-bot-with-python-81d0fe3cea9a) (2019)

[12] [阿德里安·易捷·许](https://medium.com/@adrianitsaxu?source=post_page-----486e92785df4----------------------),[利用卷积神经网络结合 Keras 进行城市声音分类:理论与实现](https://medium.com/gradientcrescent/urban-sound-classification-using-convolutional-neural-networks-with-keras-theory-and-486e92785df4),【2019】

[13] Sainath Adapa,K [aggle freesound 音频标记](https://github.com/sainathadapa/kaggle-freesound-audio-tagging) (2018)

[14] [歌词特征提取](https://librosa.github.io/librosa/0.6.0/feature.html)

# 如何为 Twitter 建立一个(准)实时仇恨言论分类器

> 原文:<https://towardsdatascience.com/how-to-build-a-quasi-real-time-hate-speech-classifier-for-twitter-286d7cc440c2?source=collection_archive---------56----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7cc598128aff7632d41366810d5c2614.png)

资料来源:联合国人类住区规划署

## 从培训到新推文中的模型部署

社交平台上的网络欺凌和攻击性语言是我们现代的瘟疫之一。网上言论自由很容易演变成对性、政治和宗教信仰的攻击性、不合理和无建设性的批评。机器学习分类器和社交平台上可用的大量数据为缓解这一问题提供了有效的解决方案。

在这个项目中,一系列分类器,如逻辑回归、决策树和 CNN,在 40000 万条人类标记为冒犯性或非冒犯性的推文中进行了训练。这 4 万条推文是通过合并两个不同的数据集汇编而成的。其中一个最初取自于一个 [Analytics Vidhaya](https://datahack.analyticsvidhya.com/contest/practice-problem-twitter-sentiment-analysis/) 竞赛,而第二个数据集是在这个 [Github](https://github.com/t-davidson/hate-speech-and-offensive-language/tree/master/data) 回购上发现的 20000 条攻击性推文的集合。

整个项目可以在这个 [Github](https://github.com/matteomm/twitter_sentiment_analysis_hatespeech) 页面上找到。

仇恨言论的定义取自《剑桥词典》:“基于种族、宗教、性别或性取向等因素,针对某个人或群体表达仇恨或鼓励暴力的公开言论”。这个项目的主要目标是建立一个能够识别 Twitter 上仇恨言论的模型。在最后一部分,获胜的模型运行了每天从英国和美国的 Twitter API 收集的新推文,显示了被标记为攻击性语言或仇恨言论的推文占总推文的百分比。可以在[这里](https://shrouded-sands-52273.herokuapp.com/) *找到最终仪表板的链接(如果没有任何东西出现,给它 20 秒的时间来加载和刷新页面)。*

我曾尝试手动复制任何数据科学家在将模型投入生产时都会经历的流程(例如在 AWS SageMaker 上):

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5cd30a268df81dfcf7b5cbd3bdaebe13.png)

亚马逊 Sagemaker 上的典型循环来源:AWS 文档

项目的整体结构分为 5 个主要部分:

*   Tweets 和 EDA 的数据清理
*   模特培训
*   Twitter API 获取新数据到本地 MySQL 数据库
*   使用离线模型对新推文进行预测
*   通过 Streamlit 应用展示结果

# 数据清理

在循环的最开始,有必要处理我们可用的推文,并对它们进行一些转换,以便我们的算法能够以可理解的方式理解文本。与此同时,我们需要合并两个不同的数据集,以便获得负面和正面推文的例子。从最初的数据集中,我有意从每个类别(负面/正面)**中选择了大约 20000 条推文,这样最终的数据集就已经平衡了。**

现在一切就绪,预处理步骤可以应用于我们所有的最终推文。下面我分解了所有的预处理步骤(每个步骤的所有代码都可以在 data_cleaning.ipynb 笔记本中找到):

*   降低推文中的所有单词
*   删除重复
*   删除转发
*   移除 Twitter 句柄并计数*
*   移除特殊字符并测量推文长度
*   词类词汇化
*   在引理化之后重新格式化所有的空间和 ashtags
*   移除停用字词和短于 3 个字符的字词
*   删除不必要的列并保存最终的数据帧用于探索性数据分析

(在 Twitter 中,句柄用于在推文中指代某人,例如“今天塔图因阳光明媚,我们去喝杯奶昔吧@LukeSkywalker”。)

# **探索性数据分析**

从这一点来看,所有这些 tweets 都准备好进行标记化,我们还可以对它们执行一些其他操作。下面是我创建的一些代码片段,用于创建最常见单词的数据框架,并根据词频构建单词云:

在这个阶段,已经有一些潜在的模式和初步的见解可以揭示出来:

*你能从一条微博的长度来判断它吗?*

推特的答案是肯定的!推文是否具有攻击性和长度似乎有关系。更具体地说,更长的推文与更积极的信息相关联。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9693dd95d1976877e7cd339934777045.png)

基于推文长度的比率(正 0/负 1)

如上图所示,负面推文似乎比正面推文平均要短。1 代表负面推文,0 代表正面推文。可以看到,大多数负面推文集中在图表的左侧,对应于较短的长度。简单的 t 检验证实,p 值小于 0.001 时,平均差异显著。

*手柄越多的推文攻击性越强吗?*

答案似乎是肯定的。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cfcdb64103fb1be63eacb8c75455a970.png)

基于每条推文的句柄数量的比率(正 0/负 1)

在最后一节中,手柄数量和攻击性之间的关系通过再次绘制正/负手柄数量与手柄总数的关系来衡量。绝大多数推文的句柄介于 0 和 3 之间,0 和 1 句柄推文之间存在明显差异,后者的攻击性推文比例明显高于 2 和 3 类。这可以解释为人们通过使用把手对某人咆哮。

**由于敏感语言,在 EDA 笔记本上可以找到更多 EDA 和 wordclouds】*

# 模特培训

我在建模中使用的唯一预测器只是文本本身。用 tf-idf 方法对我们文本的词条化和精炼版本进行矢量化。Tf-idf 优于词袋(B-o-w ),因为在这种情况下词的稀有性非常重要。

tf-idf 矩阵用于所有模型,除了 CNN(它只将单词的符号化序列作为输入)和 Naive Bayes,在 Naive Bayes 中,我还尝试使用 B-o-w 框架来查看性能是否会受到影响。

CNN 的性能没有添加到下面的图表中,但是,它非常低,在验证集上的准确率刚刚超过 50%。在神经网络部分还需要做更多的工作,我可能会在低性能的 CNN 上实现 RNN。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/88819aeb5c4d4ed06c80b449cefa36da.png)

跨培训和验证的所有模型的性能概述

所有模型都用 GridSearch CV 进行了调整和优化。如前所述,最终表现最好的模型是一个逻辑回归,在测试集上有 98%的 f-1 分数。由于初始数据集从一开始就被设计为平衡的,因此上述任何指标在这种情况下实际上都是有意义的。如果数据集是不平衡的,ROC 曲线或宏观/微观精度将是更好的拟合。

**最后,获胜模型的高性能可以用缺乏中立类别的推文来解释。**f1 如此高的分数是因为该模型可以轻松识别非常令人不快的推文和非常积极的推文。在这种情况下,引入第三类中性推文肯定会降低性能,也有助于模型拾取既不一定非常积极也不一定非常消极的推文。

# Twitter API 获取和 MySQL 存储

现在我们已经有了一个分类推文的离线模型,我们还需要一个基础设施来收集和处理实时和新鲜的推文。

为了连接到 Twitter API,Twitter 开发团队需要批准您的登录请求。这可以通过点击链接[这里](https://developer.twitter.com/en)来完成,并给出一些关于你打算如何使用 Twitter 数据的基本信息。Twitter 团队通常需要 2-3 个工作日才能获得最终批准和登录凭证。

在请求访问 Twitter 开发者门户后,可以在本地 MySQL 数据库上定期收集新的推文,该数据库的创建只是为了容纳推文的输入流。python 库 Tweepy 用于创建与 Twitter API 的连接。我们从原始 JSON 流中存储在 SQL 数据库上的唯一信息是:

*   Twitter ID
*   推文时间
*   Twitter 文本

所有文本都必须去掉表情符号,才能存储在数据库中。Tweepy 的流监听器可以基于特定主题和其他过滤器(如语言)收集信息。在这种情况下,所有标签为“冠状病毒”的词都被跟踪,以确保大量的推文流。同时,为了方便起见,只选择了英语。

请在下面找到用于此项目的 Tweepy 监听器对象的代码片段:

下面是 Listener 对象的实现,它只流式传输带有“冠状病毒”的标签,也是英文的。Wait_on_rate_limit 还确保不会达到每天的流媒体 tweets 限额。

在与数据库建立连接后,使用以下函数将数据传递并存储到 MySQL 数据库:

# 使用离线模型对新推文进行预测

有了基本的管道,我们现在可以在一个单独的笔记本上从 MySQL 数据库中提取批量的新流推文,在那里应用完全相同的预处理和数据清理(下面的 fresh_tweets_to_df 笔记本)。下图描述了管道的整体结构:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ce88a83b699491d52938c8e301067e35.png)

数据管道

在 df_to_heroku 部分,召回最终获胜的模型和 tf-idf 酸洗对象。唯一合适的 tf-idf 对象被转换到新的 tweets 上,以便生成每次都具有完全相同数量的列(9000 个单词)的矩阵。在这种情况下,单词之外的词汇被丢弃,而其余的由矩阵保留。

随后,将 predict_proba 函数应用于矢量化矩阵,并且仅过滤高于 0.9 的值,希望仅收集模型认为非常令人不快的推文。最后一步,绘制攻击性推文和大多数重复出现的词随时间的波动。这个数字然后通过 Streamlit 上传到 Heroku 上。

*使这些笔记本运行的整个过程是通过一系列* ***cron*** *命令自动完成的,这些命令每隔 4 小时定期执行这些笔记本,使用 papermill 和 nbconvert 来触发和转换笔记本(下面的示例显示了计划在每天晚上 8.52 到 9.09 之间执行一次的整个过程):*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/873cd793945896b81fb8f13be87427b7.png)

自动化管道的 Cron 命令

请注意,nbconvert 和 papermill 的超时命令(设置为 150 秒)是一种额外的安全措施,以防止 Tweepy 对象随着时间的推移下载大量的 Tweepy。

# **通过 Streamlit 应用展示结果**

在 df_to_heroku 笔记本中,一些非常高级的数据被汇总并保存到 matplotlib 图中,如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e36ab7f1ccff4afc10cad7af26f0e65c.png)

添加到 Streamlit 的 Matplotlib 图形的快照

最终仪表板应用程序的底层结构由几行代码构建而成:

# 局限性和未来工作

虽然最终的模型性能即使在我们数据集的测试结果上也非常好,但这个项目的一个主要限制是测量模型在新推文中的性能。实际上,我们可以只看一些被贴上负面标签的推文,就主观地认为它们是否具有攻击性。这最后一点提出了这个框架中的另一个重要问题,它与人类手动标记推文的固有偏见有关。

用来标记最初的基本事实的判断也是谬误的,因为对一些人来说是冒犯性的,对另一些人来说可能不是冒犯性的。单词以外的词汇可能是这种模式的主要缺点之一。该算法不能很好地处理包含大量单词的句子,这些单词不包含在我们最初的 9000 万单词长的词汇表中。递归神经网络可能是处理词汇外单词的最佳选择。

感谢阅读!

# 如何使用 Apache Beam、Pub/Sub 和 SQL 为在线商店构建实时数据管道

> 原文:<https://towardsdatascience.com/how-to-build-a-real-time-data-pipeline-for-an-online-store-using-apache-beam-pub-sub-and-sql-6424f33eba97?source=collection_archive---------9----------------------->

## 为虚拟在线商店(我们也将创建)构建实时数据管道的分步指南,以便稍后对其进行分析。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6a0a5058eaf60e1de7b17645fd45c17b.png)

我的设置正在运行

看到我们的数据变得如此具有可塑性是一件令人着迷的事情。如今,我们有工具可以将高度嵌套的复杂日志数据转换为简单的行格式,有工具可以存储和处理数 Pb 的事务数据,还有工具可以在原始数据生成后立即捕获原始数据,并从中处理和提供有用的见解。

在本文中,我想分享一个这样的一步一步的过程,从我们自己的虚拟在线商店生成、摄取、处理并最终利用实时数据。

## 先决条件

1.  谷歌云平台账户(如果你没有账户,请在此注册[获得 3 个月的免费试用,可使用 300 美元的信用点数)。](https://cloud.google.com/)
2.  Linux 操作系统。
3.  Python 3。

## 体系结构

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/af673edd29df00959ebbdb734f319f88.png)

我在白板上设计流程图的技巧,当然还有一些编辑😉

## 步骤 1:创建发布/订阅主题和订阅者

Pub/Sub 是谷歌云平台中可用的消息服务。可以认为是 Apache Kafka 或者 Rabbitmq 的托管版。

消息服务基本上将产生数据的系统(在我们的例子中是虚拟存储应用程序)与处理数据的系统(在我们的例子中是 Apache beam on Dataflow)分离开来。

首先,我们需要在 GCP 创建一个服务帐户,允许我们从应用程序和 Apache beam 访问 Pub/Sub:

登录你的 GCP 控制台,从左侧菜单中选择 **IAM & Admin** :

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cbe6f54967e0c18519ac86066d92d936.png)

创建服务帐户。

选择**服务账户**选项并创建一个新的服务账户:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/152095545a71b5970955d78335bc3c49.png)

插入新的服务帐户详细信息。

为我们的服务帐户提供**发布/订阅管理**角色:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a9b296ffccd107b337d0f4cfc4be84e9.png)

提供访问发布/订阅所需的角色。

最后,**创建一个密钥**并下载私钥 JSON 文件以备后用:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b18860b8d99b844c82609cf7b901b834.png)

正在下载服务帐户密钥。

接下来,我们将在 Pub/Sub 中创建一个主题,将我们的虚拟商店数据发布到其中,并创建一个订阅者,使用 Apache Beam 从其中提取数据。

从 GCP 控制台的左侧菜单中选择**发布/订阅**。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f442a0c986e8934b37ac45ea8a5dfa67.png)

从控制台选择发布/订阅工具。

从子菜单中选择**主题**。从顶部选择**创建主题。**输入合适的名称,点击**创建主题**。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d66f779947f72eecaf395fbddef6d719.png)

创建新主题。

现在,从左侧选择**订阅**选项,从顶部选择**创建订阅。**输入一个合适的名称,从下拉列表(我们在上一步中创建的)中选择订阅者将监听数据流的主题。之后点击**在最后创建**,保持其他选项不变。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e432d6dee2e580f3b90c6d7007ababa5.png)

为已创建的主题创建新的订阅者。

## **第二步:为生成实时数据创建一个虚拟存储**

现在,我们将创建一个虚拟在线商店,将交易数据推送到我们在前面步骤中创建的发布/订阅主题中。

我使用过 [Dash](https://dash.plotly.com/introduction) ,这是一个由 Plotly 创建的工具,使用不同的预构建 UI 组件(如按钮、文本输入等)快速构建 web 应用程序。构建 web 应用程序的完整教程超出了本文的范围,因为我们的主要焦点是构建实时管道。所以你可以在这里 **从 GitHub repo [**下载完整的应用。**](https://github.com/aakashrathore92/gcp-realtime-pipeline-project)**

唯一重要的是将我们的数据发布到发布/订阅主题的脚本:

让我们开始我们的在线虚拟商店,从 Git 下载项目后,创建一个虚拟 python 环境,并使用 ***需求安装所有的包。txt*文件。现在打开终端中的文件夹,运行 ***app.py*** 文件。您将看到以下输出:**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a6fcb5b58b9fc96b46622b91beef0dc4.png)

正在运行虚拟存储 dash 应用程序服务器。

进入你的网络浏览器,打开 ***localhost:8085。*** 你会看到虚拟商店的主页。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2c47bb8c3439ae7239e64eb49c8e5b52.png)

我自己的虚拟商店😜。如果你有密码,你可以改名字😉。

现在有趣的部分让我们订购一些商品,看看我们的数据是如何被发布到发布/订阅主题中,然后被我们之前创建的订阅者获取的。为每个项目添加一些数量,然后点击**提交**:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f2d0ac4765432b6a95938f6a9adfa8ab.png)

通过下单进行测试。

您可以在终端中看到,每次下订单时,都会打印出 JSON 格式的一些交易数据。同样的 JSON 数据也被推送到发布/订阅主题。让我们从我们的订户那里获取数据,进入 GCP 的发布/订阅仪表板,从左侧菜单中选择**订阅**选项,然后点击顶部的**查看消息**,然后点击**获取**以查看发布的数据:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3858d697a2cb919a19acfdc85a519fd3.png)

在酒吧/酒馆登记。

## 步骤 3:创建 Apache Beam 管道并在数据流上运行它

在这个阶段,我们从虚拟在线商店向我们的发布/订阅用户实时获取数据。现在,我们将在 Apache Beam 中编写我们的管道,以解除数据嵌套,并将其转换为类似行的格式,以将其存储在 MySQL 服务器中。最后,我们将使用 GCP 数据流运行器运行我们的管道。

在我们开始编写数据管道之前,让我们在 GCP 创建一个云 SQL 实例,这将是我们存储已处理数据的最终目的地,您也可以使用其他云 SQL 服务,我已经为 MySQL 服务器编写了管道。

在 GCP 控制台上,从左侧菜单中选择 **SQL** 选项:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ee8c2a79ba7d2c365f9bdce9e37d011d.png)

从 GCP 控制台选择 SQL 工具。

选择**创建实例:**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/038765d33735a5f1b831b6bb3c4c3d3d.png)

正在创建云 SQL 实例。

选择 MySQL:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f80cb8d002ff6409e366de581cbd6f9d.png)

选择 MySQL 服务器。

为 root 用户输入**实例名****密码**,将其他设置保留为默认设置,然后单击**创建,**现在可以休息了,启动实例需要 5-10 分钟:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0c5b8e389c94ce078a7fa9e9d8d49632.png)

插入细节并创建云 SQL 实例。

数据库启动并运行后,我们需要创建一个数据库和表。使用任何 SQL 客户端连接您的 MySQL 实例,并运行以下查询:

```
CREATE DATABASE virtual_store;CREATE TABLE transaction_data(
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` VARCHAR(255),
`timestamp` INT(11),
`item_id` VARCHAR(255),
`item_name` VARCHAR(255),
`category_name` VARCHAR(255),
`item_price` FLOAT,
`item_qty` INT,
PRIMARY KEY(`id`)
);
```

到目前为止,我们已经创建了我们的源(发布/订阅用户)和接收器(MySQL),现在我们将创建我们的数据管道。

下面给出了我们管道的目录表示,你可以从我的 GitHub repo [**这里**](https://github.com/aakashrathore92/gcp-realtime-pipeline-project) 克隆完整的目录:

```
├── dataflow_pipeline
│   ├── mainPipeline.py
│   ├── pipeline_config.py
│   ├── requirement.txt
│   └── setup.py
```

让我们首先从配置文件 ***pipeline_config.py、*** 开始。该文件包含所有配置,如发布/订阅订户详细信息、服务帐户密钥路径、MySQL DB 连接详细信息和表详细信息。

接下来是主管道文件,***main pipeline . py***,这是不同运行者(本地、数据流等)运行管道的入口点。在这个管道脚本中,我们从发布/订阅中读取数据,取消数据嵌套,并将最终数据存储在关系数据库中。稍后,我们将使用谷歌数据工作室可视化它。让我们看看代码:

首先,让我们在本地运行管道:

```
python mainPipeline.py
```

您将看到下面的输出,这意味着我们的管道现在正在侦听传入数据的发布/订阅。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/af3b12cc482a4f20ee48f3f25cedb757.png)

本地运行管道的输出。

让我们从我们的虚拟在线商店下一些订单,看看管道的输出。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/664564da0622e398d49c91488da9b70d.png)

下样品订单。

单击提交后,您将立即在管道终端中看到输出:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/db6de26a12f7c86c580d606068647163.png)

通过下订单测试管道。

如您所见,我们的输入是嵌套数据,其中所有项目都嵌套在一个对象中,但是我们的管道将数据非嵌套到行级别。

让我们检查一下我们的数据库表:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f0a1b64b2d263fa61cecfde13a4a6509.png)

检查最终目的表。

正如预期的那样,我们的单个订单被转换成项目式的行级数据,并实时地插入到我们的数据库中。

现在,我们将在 GCP 数据流中运行我们的管道,为此,我们需要运行以下命令:

```
python mainPipeline.py --runner DataflowRunner \
--project hadooptest-223316 \
--temp_location gs://dataflow-stag-bucket/ \
--requirements_file requirement.txt \
--setup_file ./setup.py
```

确保像我一样在 GCP 创建一个 staging bucket,并在上面的命令中的" **temp_location** "选项下提供链接,并在您的目录中创建一个包含以下内容的 ***setup.py*** ,这将防止 *ModuleNotFoundError* **。**

高枕无忧,启动 GCP 数据流管道需要 5-10 分钟。现在转到 GCP 数据流仪表板,检查服务器是否启动。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6d17289eb0f61d86b7a0651c131e7241.png)

检查在 GCP 运行的数据流作业。

您还可以看到管道的不同阶段,单击正在运行的作业可以查看详细信息。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7678738795272eb29d13dd602b3023ac.png)

数据流中管道所有阶段的可视化表示。

从虚拟商店下一些订单,并测试数据是否进入数据库。在我的情况下,它像预期的那样工作。MySQL 表中的数据行被实时插入:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3d6d286a0374e066dc02ed4c2a4133d0.png)

最终测试检查数据流处理的数据。

*注意:关闭我们在 GCP 部署管道的本地终端不会影响管道在 GCP 数据流中的运行。确保从 GCP 也终止管道。*

## 步骤 4:创建 Datastudio Dashboard 以可视化我们的实时数据

Google Data Studio 是一款免费的数据可视化工具。它使用户能够从不同的数据源非常快速地创建一个交互式的、有效的报告仪表板。

让我们将我们的接收器(MySQL 服务器)连接到 Data Studio,并在我们的实时数据上创建一个仪表板。

转到[https://datastudio.google.com](https://datastudio.google.com)。点击**创建**并选择**数据源。**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/740f4b3f8bc20b05b40a7de94dbba7f3.png)

正在为 data studio 仪表板创建数据源。

在左上角为您的源命名,并选择 **Cloud SQL for MYSQL** 作为源(如果您的 MYSQL 数据库不在 GCP,请仅选择 **MySQL**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/14007d46012f6cf60752b426ad8bb79c.png)

命名我们的数据源并选择云 SQL 进行连接。

输入您的数据库凭证并点击**验证。**之后选择**自定义查询**,进入查询,选择右上角的**连接**。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ef25fbffa459ca53eba25351e6969c52.png)

放入所有需要的细节和一个自定义查询从数据库中提取数据。

Data Studio 将连接到云 SQL 实例,并向我们显示我们的表的模式。现在点击右上角的**创建报告**:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f010f9e247d30e460e720958b07ba644.png)

Data Studio 提取的表架构。

根据您的要求添加图表和图形。您可以在这里 了解更多数据工作室 [**:**](https://analytics.google.com/analytics/academy/course/10)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/89578b5f0ef3fbc36bcf0839bd1ddee6.png)

在 data studio 中添加图表和图形的选项。

我已经创建了一个基本的,2 图表仪表板,显示 ***项目销售数量*** 和 ***项目销售。***

我的最终控制面板会在收到订单后立即更新:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/becd3ebf0544e5064e8649913d58371e.png)

最终控制面板,查看我们实时数据的见解。

## 结论

在本文中,我解释了实时管道是如何工作的。我们已经创建了数据管道的所有组件,一个实时生成数据的源应用程序,一个接收数据的缓冲区,一个在 Google 云平台中处理数据的实际管道,一个存储已处理数据的接收器,以及一个显示最终数据的仪表板。

请在下面留下您对本文的评论,如果您在上面指定的任何步骤中遇到问题,您可以通过[**insta gram**](https://www.instagram.com/_aakash.rathore/)**和[**LinkedIn**](https://www.linkedin.com/in/aakash-data-engineer)**联系我。****

# 如何使用 Faust 和 MLFlow 构建实时欺诈检测管道

> 原文:<https://towardsdatascience.com/how-to-build-a-real-time-fraud-detection-pipeline-using-faust-and-mlflow-24e787dd51fa?source=collection_archive---------17----------------------->

## 关于使用类似 Kafka Streams 的 python 库(Faust)和使用 MLFlow 服务的欺诈检测模型构建低延迟 ML 管道的教程

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/15cfc3dcea3cc24fa1abe0444a1d221a.png)

照片由[杰佛森·桑多斯](https://unsplash.com/@jefflssantos?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/fraud?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄

在本教程中,我们将学习在本地启动一个 Kafka 集群,编写一个发送消息的生成器,创建一个简单的欺诈检测机器学习训练流程,通过 REST 接口公开模型,并进行实时预测。

我们将使用的主要框架是:

*   [Faust](https://github.com/robinhood/faust/) :流处理库,使用 [async/away](https://en.wikipedia.org/wiki/Async/await) 范例,需要 python 3.6 以上版本
*   [Kafka](https://www.confluent.io/) :我们将使用 Kafka 的融合版本作为我们的流媒体平台
*   [MLFlow](https://www.mlflow.org) :一个开源平台,用于监控和保存训练后的机器学习模型
*   Jupyter 实验室:我们运行代码的环境

我们还需要一些数据来进行培训。我们可以使用来自 [Kaggle 信用卡欺诈竞赛](https://www.kaggle.com/mlg-ulb/creditcardfraud/data#)的 CSV 源。

**TL;DR:代码在**[**GitHub**](https://github.com/BogdanCojocar/medium-articles/tree/master/realtime_fraud_detection)**上。**

## 第一步:进行培训

让我们首先构建我们的欺诈检测模型。我们将读取代表信用卡交易的 CSV 数据,并在两个类`0(not fraud)`和`1(fraud)`之间应用简单的二元逻辑回归分类。

```
df = pd.read_csv('creditcard.csv')df.dtypesTime      float64
V1        float64
V2        float64
V3        float64
V4        float64
V5        float64
V6        float64
V7        float64
V8        float64
V9        float64
V10       float64
V11       float64
V12       float64
V13       float64
V14       float64
V15       float64
V16       float64
V17       float64
V18       float64
V19       float64
V20       float64
V21       float64
V22       float64
V23       float64
V24       float64
V25       float64
V26       float64
V27       float64
V28       float64
Amount    float64
Class       int64
```

正如我们所看到的,我们读取的大多数列都是`float`,除了`Class`,它是我们的目标变量。现在让我们开始训练:

```
x_name = df.iloc[:, 1:30].columns
y_name = df.iloc[:1, 30: ].columnsdata_x = df[x_name]
data_y = df[y_name]train_x, test_x, train_y, test_y = train_test_split(data_x, data_y, train_size=0.7, test_size=0.3)model = LogisticRegression()
model.fit(train_x, train_y.values.ravel())
```

对于特征,我们使用`V1 — V28`和`Amount`。我们在`train`和`test`数据之间进行分割,并拟合模型。我们可以检查一些性能指标:

```
pred_y = model.predict(test_x)accuracy_score(test_y, pred_y)
0.9993094811745842f1_score(test_y, pred_y)
0.7773584905660378precision_score(test_y, pred_y)
0.8272727272727273recall_score(test_y, pred_y)
0.6776315789473685
```

如果我们仅仅使用准确性作为衡量标准,我们可能会搬起石头砸自己的脚。始终使用更好的绩效指标,如`f1_score`、`precision`和`recall`。

## 步骤 2:通过 REST 服务模型

培训结束后,我们可以保存新的欺诈检测模型:

```
mlflow.sklearn.save_model(model, path='./fraud_model')
```

我们在 MLFlow 中使用`sklearn`模块,因为这将帮助我们处理 servis 部分。

让我们在项目的根目录下启动一个终端,并键入以下命令:

```
mlflow models serve -m fraud_model
```

这需要一点时间,因为除了部署微服务之外,还会创建一个`conda`环境。这是为了确保下次我们进行部署时,我们将依赖关系锁定在某个版本和单独的虚拟环境中。如果一切运行正常,我们会注意到我们的服务有了一个 url:

`Listening at: [http://127.0.0.1:5000](http://127.0.0.1:5000)`

我们可以使用`cURL`从终端进行快速测试:

```
curl [http://127.0.0.1:5000/invocations](http://127.0.0.1:9999/invocations) -H 'Content-Type: application/json' -d '{
    "columns":["V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17","V18","V19","V20","V21","V22","V23","V24","V25","V26","V27","V28","Amount"],
    "data":[[12.8,0.029,0.48,0.98,6.2,29.1,3.33,1.2,0.39,75.1,0.66,1.2,1.3,44.2,12.8,0.029,0.48,0.98,6.2,29,3.33,1.2,0.39,75.3,0.66,1.2,1.3,44.2,1.1]]
}'
```

我们使用包含特性列和一组值的`JSON`对象发送一个`POST`请求。我们将从分类器`[0]`中得到答案。

## 步骤 3:运行 docker compose 来启动 kafka 集群

为了构建集群,我们将使用一个`docker-compose`文件来启动所有需要的 docker 容器:zookeeper 和一个代理。

现在简单地说,kafka 是一个分布式流媒体平台,能够处理大量的消息,这些消息被组织或分组到主题中。为了能够并行处理一个主题,必须将它分成多个分区,来自这些分区的数据存储在称为代理的独立机器中。最后,zookeeper 用于管理集群中代理的资源。为了读写 kafka 集群,我们需要一个代理地址和一个主题。

`docker-compose`将启动端口`2181`上的`zookeper`,端口`9092`上的`kafka broker`。除此之外,我们使用另一个 docker 容器`kafka-create-topic`的唯一目的是在 kafka broker 中创建一个主题(称为 test)。

要启动 kafka 集群,我们必须在定义 docker compose 文件的同一文件夹中运行以下命令行指令:

```
docker-compose up
```

这将启动所有带有日志的 docker 容器。我们应该在控制台中看到类似这样的内容:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0e50dc642cabd20bf4d0fee9bac6930f.png)

## 第四步:运行卡夫卡制作程序

为了能够实时消费数据,我们首先必须将一些消息写入 kafka。我们将使用 python 中的`confluent_kafka`库来编写一个生产者:

我们将发送格式如下的`JSON`消息:

```
{
    "columns":["V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17","V18","V19","V20","V21","V22","V23","V24","V25","V26","V27","V28","Amount"],
    "data":[]
}
```

这与我们用于 MLFlow web 服务的格式相同,其中`data`可以包含多个特性值列表。

对于我们写入队列的每条消息,我们还需要分配一个键。我们将根据`uuid`随机分配一个,以在集群中实现良好的分布。最后,我们还运行一个`flush`命令来确保所有的消息都被发送出去。

一旦我们运行`confluent_kafka_producer`,我们应该会收到一个日志,告诉我们数据已经正确发送:

```
we’ve sent 6 messages to 127.0.0.1:9092
```

## 第五步:经营浮士德消费者

我们已经到达了教程的最后一步。使用 Faust 框架,我们将运行一个简单的 worker,它将使用来自 Kafka 的数据,并将预测应用到新功能上。我们需要为此创建一个单独的 python 脚本。首先,我们定义我们的 Faust 应用程序,以及主题:

```
app = faust.App(
    'fraud_detection_app',
    broker='kafka://localhost:9092',
    value_serializer='raw',
)kafka_topic = app.topic('test')
```

我们定义从中读取数据的代理和序列化程序格式。我们很乐意使用`raw`,因为我们只是将数据传递给机器学习算法。

现在,让我们定义协程。在浮士德框架中,它被称为`agent`:

代理是一个异步进程。我们连接到 Kafka 主题,对于我们读取的每个值,我们调用 REST 服务并获得结果。正如预期的那样,在 Kafka 中有了新的值之后,它会立即运行。

剧本定稿了。姑且称之为`fraud_detection_worker.py`。现在我们可以运行它了。从项目根目录的终端开始,我们需要键入:

```
faust -A fraud_detection_worker worker -l info
```

这将启动一个 worker,它是应用程序的一个实例。如果我们需要更多的计算能力,我们可以启动额外的工人。

如果一切运行正常,我们将开始看到以下日志:

```
Input data: b'{"columns": ["V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18", "V19", "V20", "V21", "V22", "V23", "V24", "V25", "V26", "V27", "V28", "Amount"], "data": [[12.8, 0.029, 0.48, 0.98, 6.2, 29.1, 3.33, 1.2, 0.39, 75.1, 0.66, 11.2, 1.3, 0.2, 12.8, 0.029, 0.45, 0.98, 6.2, 29, 3.33, 1.2, 0.39, 75.3, 0.3, 2.2, 1.3, 2.2, 1.01]]}'Fraud detection result: [0]
```

我们已经到了本教程的结尾。我希望你喜欢它,并发现它有用。我们看到了现在如何选择使用纯 python 框架来进行实时数据处理。这是一个很大的优势,因为这种编程语言中有很多数据科学工作。

# 如何使用潜在因素模型在图形数据库中建立推荐系统

> 原文:<https://towardsdatascience.com/how-to-build-a-recommendation-system-in-a-graph-database-using-a-latent-factor-model-fa2d142f874?source=collection_archive---------3----------------------->

## 数据库内训练避免了将数据从 DBMS 导出到其他机器学习平台,从而更好地支持连续的模型更新

# **什么是推荐系统?**

推荐系统是基于可用数据预测个人偏好选择的任何评级系统。推荐系统被用于各种服务,例如视频流、在线购物和社交媒体。通常,系统基于其对用户将给予项目的评级的预测向用户提供推荐。推荐系统可以从两个方面进行分类,利用的信息和预测模型。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1c6b41a8833512eb58099fd70f174ce9.png)

图。1(图片作者)。这个示例数据集包括两个用户,Alice 和 Bob,两部电影,*玩具总动员*和*钢铁侠*,以及三个评级记录(实线)。每个用户和电影都标有其属性。

## **内容过滤与协同过滤**

两种主要的推荐方法,内容过滤和协作过滤,主要根据用于评级预测的信息而不同。图 1 显示了一组电影分级数据以及一些用户和电影的标签。注意用户对电影的评分来自一个图结构:用户和电影是图的顶点,评分是图的边。在这个例子中,内容过滤方法利用电影和用户的标签属性。通过查询标签,我们知道爱丽丝是漫威电影的忠实粉丝,而*钢铁侠*是漫威电影,因此*钢铁侠*系列将是对她的一个很好的推荐。内容过滤评分系统的一个具体例子是 TF-IDF,用于对文档搜索进行排名。

用户和电影上的标签可能并不总是可用。当标签数据稀疏时,内容过滤方法可能不可靠。另一方面,协同过滤方法主要依赖于用户行为数据(例如,评级记录或电影观看历史)。在上面的例子中,爱丽丝和鲍勃都喜欢电影*玩具总动员*,他们分别给这部电影打了 5 分和 4.5 分。基于这些评级记录,可以推断这两个用户可能共享相似的偏好。现在考虑到鲍勃喜爱*钢铁侠*,我们可以预期爱丽丝也会有类似的行为,向爱丽丝推荐*钢铁侠*。k-最近邻( [KNN](https://docs.tigergraph.com/v/2.6/dev/gsql-examples/common-applications#example-1-collaborative-filtering) )是一种典型的协同过滤方法。然而,协同过滤有所谓的冷启动问题——它不能为没有评级记录的新用户产生推荐。

**基于内存与基于模型的对比**

根据所使用特征的隐含性,推荐系统还可以分为基于记忆的方法和基于模型的方法。在上面的例子中,所有的用户和电影特征都是显式给出的,这使得我们可以根据他们的标签直接匹配电影和用户。然而,有时需要深度学习模型来从用户和电影的信息中提取潜在特征(例如,基于电影的轮廓对电影进行分类的 NLP 模型)。基于模型的推荐系统利用机器学习模型进行预测。而基于记忆的推荐系统主要利用显式特征。

不同类型的推荐系统的一些典型例子如下所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/10f946ec1b7bf848b32aaa6ae9fb06a3.png)

(图片由作者提供)

# **图因子分解如何为推荐系统工作**

如上所述,诸如 KNN 的协作过滤方法可以在不知道电影和用户属性的情况下预测电影评级。然而,当评级数据稀疏时,即典型用户只对几部电影进行了评级时,这种方法可能不会产生准确的预测。在图 1 中,如果鲍勃没有对*玩具总动员*评分,KNN 无法预测爱丽丝对*钢铁侠*的评分,因为爱丽丝和鲍勃之间没有路径,爱丽丝本身也没有“邻居”。为了应对这一挑战,图分解方法[1]将基于模型的方法与协作过滤方法相结合,以提高评级记录稀疏时的预测准确性。

图 2 说明了图分解方法的直觉。图分解也称为潜在因素或矩阵分解方法。目标是获得每个用户和电影的向量,该向量代表他们的潜在特征。在这个例子中(图 2),向量的维数被指定为 2。电影向量的两个元素 *x* ( *i* )表示这部电影的浪漫程度和动作内容,用户向量的两个元素 *θ* ( *j* )分别表示用户对浪漫和动作内容的偏好程度。对用户 *j* 将给予电影 *i* 的评价的预测是 *x* ( *i* )和 *θ* ( *j* )的点积,因为我们预期这两个向量的更好的对齐表示用户对电影的更高程度的偏好。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d2a16facb32adc830f1080b8d40d5e97.png)

图。2(图片由作者提供)。该表显示了由 4 个用户给出的 6 部电影的评级记录。等级在 0 到 5 的范围内。缺失的评级用问号表示。 *θ(j)* 和 x(i)代表潜在因子向量。Alice 的评级预测是根据潜在因素计算得出的,并在真实值旁边显示为橙色。

图 2 中的例子仅仅是为了说明图分解方法的直观性。实际上,每个矢量元素的含义通常是未知的。向量实际上是随机初始化的,并通过最小化下面的损失函数得到“训练”[1]。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3ef7fe5a28608581d48911320d586667.png)

其中 *M* 为评分记录数, *n* 为潜在因子向量的维数, *y* ( *i* , *j* )为用户 *j* 给电影 *i* 的评分,𝝀为正则化因子。第一项本质上是预测的平方误差(k 上的 *θ(j)_k* 和x(i)_k 之和),第二项是避免过拟合的正则化项。损失函数的第一项也可以用矩阵的形式表示,

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/82d65b013b060b5086697d22bc2510b9.png)

其中 *R* 是以 *y* ( *i**j* )为元素的评分矩阵, *U**V* 分别是由用户和电影的潜在因素向量构成的矩阵。最小化预测的平方误差等价于最小化 *R* - *UV^T* 的 Frobenius 范数。因此,这种方法也被称为矩阵分解法。

您可能想知道为什么我们也将这种方法称为图分解方法。如前所述,评级矩阵 *R* 很可能是一个稀疏矩阵,因为不是所有的用户都会给所有的电影评级。基于存储效率的考虑,这种稀疏矩阵往往存储为一个图,其中每个顶点代表一个用户或一部电影,每个边代表一条评分记录,其权重作为评分。如下所示,用于优化损失函数并由此获得潜在因子的梯度下降算法也可以表示为图形算法。

*θ(j)_k* 和 x(i)_k 的偏导数可以表示如下:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1e9ad7632caaf369af09ac7af754d659.png)

上面的等式表明,顶点上的潜在向量的偏导数只取决于它的边和邻居。对于我们的例子,用户向量的偏导数仅由用户之前已经评级的电影的评级和潜在向量来确定。这一特性允许我们将评级数据存储为图表(图 5 ),并使用图表算法来获取电影和用户的潜在因素。用户和电影特征可通过以下步骤获得:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4abd91eb88a06063297002709951538d.png)

(图片由作者提供)

值得一提的是,计算导数和更新潜在因子可以在 Map-Reduce 框架中进行,其中步骤 2 可以针对每个*边* _( *i**j* )(即评级)并行进行,步骤 3 也可以针对每个*顶点 i* (即用户或电影)并行进行。

# **为什么您需要一个图表数据库来进行推荐**

对于工业应用程序,数据库可以容纳数亿用户和电影,以及数十亿条评级记录,这意味着评级矩阵 A、特征矩阵 U 和 V,加上其他中间变量,在模型训练期间可以消耗万亿字节的内存。这种挑战可以通过在图形数据库中训练潜在特征来解决,其中评级图形可以分布在多节点集群中并且部分存储在磁盘上。此外,图形结构的用户数据(即评级记录)首先存储在数据库管理系统中。数据库内模型训练还避免了将图形数据从 DBMS 导出到其他机器学习平台,从而更好地支持对进化训练数据的连续模型更新。

## **如何在 TigerGraph 中构建推荐系统**

在这一部分,我们将在 TigerGraph Cloud 上提供一个图形数据库(免费),加载一个电影评级图,并在数据库中训练一个推荐模型。按照下面的步骤,你将在 15 分钟内拥有一个电影推荐系统。

按照[创建您的第一个 TigerGraph 实例](https://www.tigergraph.com/2020/01/20/taking-your-first-steps-in-learning-tigergraph-cloud/)(前 3 步)到**在 TigerGraph Cloud** 上提供一个免费实例。第一步,选择*数据库内机器学习推荐*作为入门套件。第三步,选择 TG.Free。

按照[tiger graph 云门户](https://www.tigergraph.com/2020/01/20/taking-your-first-steps-in-learning-tigergraph-cloud/)入门和**登录 GraphStudio** 。在*将数据映射到图形*页面,您将看到数据文件是如何映射到图形的。在这个初学者工具包中, [MovieLens-100K](https://grouplens.org/datasets/movielens/) 文件已经上传到实例中。 [MovieLens-100K](https://grouplens.org/datasets/movielens/) 数据集有两个文件:

*   movieList.csv 有两列显示每部电影的 id 和电影名称(电影年份)。
*   rating.csv 是用户对电影的评级列表。这三列包含用户 id、电影 id 和分级。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d82726280422d785d120eebee5ea4720.png)

图 3(图片由作者提供)。*将数据映射到图形*页面

**进入加载数据页面,点击开始/恢复加载**。加载完成后,您可以在右侧看到图表统计信息。MovieLens-100K 数据集有 944 个用户对 1682 部电影给出的 100,011 条评级记录。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/554de5fce31bb1ae929482c32111cb49.png)

图 4(图片由作者提供)。*加载数据*页面。

加载完成后,您可以在右侧看到图表统计信息。在 *Explore Graph* 页面中,您可以看到我们刚刚创建了一个二分图,其中每个电影和用户的信息存储在顶点中,评级记录存储在边中。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c734aefdb977009833d5b7d3212f1888.png)

图 5(图片由作者提供)。*探索图*页面。

在*编写查询*页面中,您会发现我们的推荐系统所需的查询已经添加到数据库中。这些查询是用 TigerGraph 的查询语言 GSQL 编写的。**点击安装所有查询**将所有 GSQL 查询编译成 C++代码。您还可以在此页面上看到自述文件查询。按照下面的步骤用电影分级记录建立一个推荐。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/89bb2e592a92027b589354884b01b30e.png)

图 6(图片由作者提供)。*编写查询*页面

**运行 splitData 查询**

该查询将评级数据分为验证集和训练集。测试数据的分数默认设置为 30%。(即 30%的评级数据将用于模型验证,其余 70%将用于模型训练)。该查询还输出总数据集、验证数据集和训练数据集的大小。

**运行规范化查询**

该查询通过用电影的平均评分减去每个评分来标准化评分。每部电影的平均评级是根据训练数据计算的。

**运行初始化查询**

该查询初始化用户和电影的潜在因素向量。潜在因素向量中的元素由正态分布随机数生成器初始化。查询输入是标准偏差和正态分布的平均值。

**运行培训查询**

该查询使用梯度下降算法训练推荐器模型。默认情况下,特征数量设置为 19。该数字必须与初始化查询中的 num_latent_factors 相同。查询输入是学习率、正则化因子和训练迭代次数。该查询输出每次迭代的均方根误差(RMSE)

计算出潜在因素后,我们可以测试并使用该模型进行推荐。

**运行测试查询**

该查询输出用户提供的真实评级以及模型预测的评级。查询输入是一个用户 id。查询输出是用户给出的所有评级和评级预测

**运行推荐查询**

该查询输出推荐给用户的前 10 部电影。基于评级预测推荐电影。

# 结论

在图数据库中训练机器学习模型有可能实现推荐模型的实时更新。在本文中,我们介绍了图分解方法的机制,并展示了一个使用 TigerGraph 云服务构建自己的电影推荐系统的分步示例。一旦您熟悉了这个例子,您应该有信心根据您的用例定制这个推荐系统。

# **参考**

[1] Ahmed,Amr 等.“分布式大规模自然图分解”*第 22 届国际万维网会议论文集* (2013)

# 如何构建递归神经网络检测假新闻

> 原文:<https://towardsdatascience.com/how-to-build-a-recurrent-neural-network-to-detect-fake-news-35953c19cf0b?source=collection_archive---------12----------------------->

在一个联系越来越紧密的世界里,谎言更容易传播。事实证明,有了由被分类为可靠或不可靠的新闻文章组成的数据集,就有可能检测出假新闻。在本教程中,我们将建立一个具有卷积和 LSTM 细胞的神经网络,在 [Kaggle 假新闻挑战](https://www.kaggle.com/c/fake-news/)中给出前 5 名的性能。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/eac57a34d7f758933f8a09ff97b073bc.png)

由 [u/Borysk5](https://www.reddit.com/r/MapPorn/comments/aotm0b/which_countries_ban_fake_news/) 制作的地图

**我们试图探测什么?** 如上图所示,假新闻是全世界的问题。中国对假新闻的定义可能与中东或美国有很大不同。数据决定了检测假新闻的定义。我们在这个例子中使用的数据集来自 Kaggle,一个举办机器学习竞赛的网站。数据集由带有可靠或不可靠标签的新闻文章组成。如果一条新闻不可靠,它就被认为是假新闻。

数据集中的假新闻文章示例:

> *被证明是真的五大阴谋论因为唐纳德·特朗普在每个选举年都竞选总统,媒体上对他偏袒的指控飞来飞去,这和共和国本身一样古老。但今年,阴谋论者声称,MSM 不仅是不诚实的希拉里的囊中之物,而且还积极努力,通过虚假的民调、虚假的故事以及与候选人的猖獗和非法勾结来确保她的当选。谢谢你,维基解密(……)我知道希拉里克林顿删除的邮件在哪里,也知道如何合法获取。*

数据集中一篇可靠文章的例子:

> 美国职业棒球大联盟的春季训练又开始了,纽约大都会队的游击手路易斯·吉约莫已经给这个大联盟俱乐部留下了深刻的印象。周四,迈阿密马林鱼队的游击手 Adeiny Hechavarria 挥棒丢掉了球棒。球棒飞向大都会队的休息区,队员们争先恐后地躲开。然而,吉约姆没有离开他的位置,而是在蝙蝠飞过他的头时抓住了它。

**算法如何工作** 文本有多种格式。推特上的文字可能真的很乱。新闻文章可以使用大量的空行。每个自然语言处理任务的第一步是清理文本,删除空行和不必要的标点符号。

下一步是将单词转换成数字,因为计算机不能阅读单词。有多种方法可以做到这一点。最简单的方法是为每个独特的单词分配数字,然后将其用作模型的输入。因此,句子“去年夏天,歌手游览了美国西海岸”将变成[1 2 3 4 5 3 6 7 3 8]。如你所见,每个独特的单词都被赋予了一个新的编号。另一种更常见的方法是使用预训练的单词嵌入。单词被转换成张量表示,而不是转换数字中的每个单词。因此,当使用四维嵌入时,每个(唯一的)单词都被转换成四个数字的组合。单词嵌入工作得如此好是因为单词的语义被捕获,具有相同含义的单词具有相似的张量值,并且与其他单词组的差异也是相似的。下面的例子形象地说明了这一点。正如你所看到的,当单词是阴性时,所有的单词都有更大的 Y 值。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/21b1720640a1e28f15e48c93be707219.png)

来源:斯坦福大学

在单词被转换成单词嵌入之后,单词被输入到神经网络中。这个神经网络由不同的层组成。第一层是卷积层。卷积是一种可以从数据中提取要素的过滤器。例如,在图像检测中,卷积可用于检测边缘或形状。在自然语言处理中,卷积也可以提高性能。下面的示例显示了一个过滤器,它提取中间有一个单词的两个单词之间的关系。在每一步中,滤波器与字嵌入值相乘。过滤值 1 乘以单词嵌入值得到单词嵌入值,而过滤值 0 得到 0。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d13eafb6024d308418a1f65db4a5c57f.png)

下一层是最大池层。这一层在张量上迭代并取最大值。这样,特征空间被压缩。这一步确保重要的特征被保留,而空白被删除。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/179e47411147aa51ec8a1184610189f5.png)

下一层是长短期记忆(LSTM)层。普通的 LSTM 单元由一个单元、一个输入门、一个输出门和一个遗忘门组成。细胞在任意的时间间隔内记忆数值,三个门调节进出细胞的信息流。更多关于 LSTM 层的信息可以在这里找到。

进行预测之前的最后一层是完全连接的层。这是一个常规的神经网络层,其中所有节点都相互连接。整体网络架构如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cf3b27c3c25147d1408b6cd0772973ca.png)

**代码** 代码是在 Google Colab 中编程的。数据可在此下载:

[https://www.kaggle.com/c/fake-news/data](https://www.kaggle.com/c/fake-news/data)

Google Colab 环境可以在以下位置找到:

[https://github . com/matdekoning/FakeNewsClassifier/blob/master/FakeNewsClassifier . ipynb](https://github.com/matdekoning/FakeNewsClassifier/blob/master/FakeNewsClassifier.ipynb)

这个 Google Colab 环境将引导你通过编码递归卷积神经网络。在代码中,首先导入所需的库(即 Keras 和 Tensorflow)。该代码检查是否安装了 Tensorflow 2.0,如果安装了旧版本,将进行更新。如果您更新了 Tensorflow,请重新启动网页。在第二个单元格中,您可以填充您的 Google Drive 环境。这是一种连接数据集的简单方法。将数据集上传到 Google drive 上的主文件夹,挂载 Google drive,在 cell 3 中可以在 Google Colab 环境中导入数据集。

**结果** 结果如下图所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7271c733d2aff2de8712c2e326e51ecc.png)

经过 5 分钟的训练,该模型达到了 0.9041 的验证精度,这意味着 10 篇新闻文章中有超过 9 篇被正确分类为可靠与否。在 Kaggle 的提交数据集上进行预测后,该算法获得了 0.96 的分数。这个分数是前 5 名的表现。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cf944fe3d042eb953b26595357dcee98.png)

事实证明,这种架构对于假新闻检测非常有效。具有池层的卷积的优点是执行时间短得多,而性能保持不变。这种架构在其他自然语言分类任务中也很有用。该模型在有毒评论分类以及情感分析方面给出了良好的结果。

# 如何用 Python 构建回归模型

> 原文:<https://towardsdatascience.com/how-to-build-a-regression-model-in-python-9a10685c7f09?source=collection_archive---------3----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ba131f733aec6c76266630444631b716.png)

## 数据科学

## 详细直观的分步演练

如果你是一名有抱负的数据科学家或资深数据科学家,这篇文章就适合你!在本文中,我们将使用 Python 构建一个简单的回归模型。为了增加一点趣味,我们将不会使用广受欢迎且无处不在的*波士顿房屋*数据集,而是使用一个简单的生物信息学数据集。特别是,我们将使用 ***德莱尼溶解度*** 数据集,它代表了计算药物发现中一个重要的物理化学性质。

有抱负的数据科学家会发现逐步教程特别容易获得,而经验丰富的数据科学家可能希望找到一个新的具有挑战性的数据集,以尝试他们最先进的机器学习算法或工作流。

# 1.我们今天在建造什么?

一个回归模型!我们将使用 Python 来完成这项工作。在此过程中,我们将使用一个生物信息学数据集(从技术上讲,它是化学信息学数据集)来建立模型。

特别是,我们要预测小分子水溶性的对数值。水溶性值是分子溶于水的能力的相对量度。它是有效药物的重要理化性质。

有什么比卡通插图更好的方式来了解我们今天正在建造的概念呢?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9644740cdaec82996bc91829a927a9ea.png)

**化学信息学数据集的机器学习模型构建的示意性工作流程的卡通图示,其中目标响应变量被预测为输入分子特征的函数。**从技术上讲,这一过程被称为*定量构效关系* (QSAR)。(由 Chanin Nantasenamat 绘制

# 2.德莱尼溶解度数据集

## 2.1.数据理解

顾名思义, ***德莱尼溶解度*** 数据集由一组 1144 个分子的 ***水溶性*** 值及其相应的化学结构组成。对于这些,在生物学领域之外,有一些术语我们将花一些时间来澄清。

***分子*** 或有时被称为小分子或化合物是由原子组成的化学实体。让我们打个比方,让我们把原子想象成乐高积木,1 个原子就是 1 个乐高积木。当我们用几块乐高积木来建造某样东西时,不管是房子、汽车还是某个抽象的实体;这样构建的实体可与分子相媲美。由此,我们可以将原子形成一个分子的具体排列和连接方式称为 ***化学结构*** 。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/046c8d0660faa59ffa318bab6f85ee45.png)

**把分子的构造比喻成乐高积木。**这个黄色的房子来自乐高 10703 创意建造者盒子。(由 Chanin Nantasenamat 绘制)

那么你正在构建的每个实体有什么不同呢?它们的不同之处在于区块的空间连通性(即各个区块是如何连接的)。在化学术语中,每个分子的化学结构不同。因此,如果你改变了积木的连接性,那么你就有效地改变了你正在建造的实体。对于分子,如果原子类型(例如碳、氧、氮、硫、磷、氟、氯等。)或原子团(例如羟基、甲氧基、羧基、醚基等。)被改变,那么分子也将被改变,从而成为新的化学实体(即产生新的分子)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/eec4a41faebbaf7c4e112a9ccb4f1516.png)

**一个分子模型的卡通插图。**红色、蓝色、深灰色和白色代表氧、氮、碳和氢原子,而连接这些原子的浅灰色是键。每个原子都可以媲美一块乐高积木。上面显示的构建分子可与构建的乐高实体(如本文上面显示的黄色房子)相媲美。(由 Chanin Nantasenamat 绘制)

要成为一种有效的药物,分子将需要被人体吸收和分布,这种特性直接由 ***水溶性*** 决定。溶解性是研究人员在设计和开发治疗药物时考虑的一个重要特性。因此,由于溶解性差而不能到达所需目的地的有效药物将是差的候选药物。

## 2.2.正在检索数据集

Delaney 在名为 [ESOL:从分子结构直接估算水溶性](https://pubs.acs.org/doi/10.1021/ci034243x)的研究论文中进行的水溶性数据集可作为[补充文件](https://pubs.acs.org/doi/10.1021/ci034243x)获得。为了您的方便,我们还下载了整个 [**德莱尼溶解度数据集**](https://github.com/dataprofessor/data/blob/master/delaney.csv) ,并在[数据 GitHub 教授](https://github.com/dataprofessor)上提供。

**Delaney 溶解度数据集原始版本的预览。**[完整版](https://github.com/dataprofessor/data/blob/master/delaney.csv)可在[数据教授 GitHub](https://github.com/dataprofessor) 上获得。

**代码练习**

我们开始吧,好吗?

启动 Google Colab 或您的 Jupyter 笔记本,运行以下代码单元。

**代码解释**

现在让我们来看看每个代码单元的含义。

第**个编码单元**,

*   正如代码字面上所说,我们将把`pandas`库作为`pd`导入。

**第二代码单元**:

*   将德莱尼溶解度数据集所在的 URL 分配给`delaney_url`变量。
*   通过`pd.read_csv()`函数读入德莱尼溶解度数据集,并将结果数据帧分配给`delaney_df`变量。
*   调用`delaney_df`变量返回输出值,该输出值实际上打印出包含以下 4 列的数据帧:

1.  **化合物 ID** —化合物的名称。
2.  **实测对数(溶解度:mol/L)**—Delaney 在原始研究文章中报告的实验水溶性值。
3.  **ESOL 预测对数(溶解度:mol/L)**—Delaney 在原始研究文章中报告的预测水溶性值。
4.  **SMILES** —化学结构信息的一维编码

## 2.3.计算分子描述符

需要注意的一点是,作者最初提供的上述数据集还不能开箱即用。特别是,我们将不得不使用 ***SMILES 符号*** 通过 *rdkit* Python 库来计算 ***分子描述符*** ,这在以前的媒体文章( [*如何使用机器学习进行药物发现*](/how-to-use-machine-learning-for-drug-discovery-1ccb5fdf81ad) )中以逐步的方式进行了演示。

需要注意的是, ***微笑符号*** 是对分子化学结构信息的一维描绘。 ***分子描述符*** 是对分子独特的物理化学性质的定量或定性描述。

让我们将分子描述符视为一种以数字形式唯一表示分子的方法,机器学习算法可以理解这种方法,以学习、预测和提供关于 ***结构-活性关系*** 的有用知识。如前所述,原子的特定排列和连接产生不同的化学结构,从而决定了它们将产生的最终活性。这种概念被称为结构-活性关系。

包含计算的分子描述符及其相应响应变量(对数)的数据集的处理版本如下所示。这个处理过的数据集现在准备好用于机器学习模型构建,其中前 4 个变量可以用作 **X** 变量,而对数变量可以用作 **Y** 变量。

**德莱尼溶解度数据集处理版本的预览。**实际上,原始版本中的 SMILES 符号被用作计算 4 个分子描述符的输入,这在之前的[媒体文章](/how-to-use-machine-learning-for-drug-discovery-1ccb5fdf81ad)和 [YouTube 视频](https://www.youtube.com/watch?v=VXFFHHoE1wk)中有详细描述。[完整版](https://github.com/dataprofessor/data/blob/master/delaney.csv)可在[数据教授 GitHub](https://github.com/dataprofessor) 上获得。

4 个分子描述符和响应变量的快速描述如下:

1.  **cLogP** —辛醇-水分配系数
2.  **MW** —分子量
3.  **RB**—可旋转债券数量
4.  **AP** ** 芳香比例=芳香原子数/重原子总数
5.  **日志** —水溶性的日志

**代码练习**
让我们继续读入包含计算出的分子描述符的 CSV 文件。

**代码解释**

现在让我们来看一下代码单元的含义。

*   将 Delaney 溶解度数据集(带有计算的描述符)所在的 URL 分配给`delaney_url`变量。
*   通过`pd.read_csv()`函数读入德莱尼溶解度数据集(带有计算出的描述符),并将结果数据帧赋给`delaney_descriptors_df`变量。
*   调用`delaney_descriptors_df`变量返回输出值,该输出值实际上打印出包含以下 5 列的数据帧:

1.  莫洛格普
2.  MolWt
3.  NumRotatableBonds
4.  芳香比例
5.  日志

前 4 列是使用`rdkit` Python 库计算的分子描述符。第五列是响应变量*日志*。

# 3.数据准备

## 3.1.将数据分离为 X 和 Y 变量

在使用`scikit-learn`库构建机器学习模型时,我们需要将数据集分成输入特征( **X** 变量)和目标响应变量( **Y** 变量)。

**代码练习**

遵循并实现以下 2 个代码单元,将包含在`delaney_descriptors_df`数据帧中的数据集分成 **X****Y** 子集。

**代码解释**

让我们来看看这两个代码单元。

***第一个编码单元格:***

*   这里我们使用 drop()函数专门“删除”logS 变量(这是 **Y** 变量,我们将在下一个代码单元格中处理它)。因此,我们将有 4 个剩余变量分配给 **X** 数据帧。特别是,我们将`drop()`函数应用于`delaney_descriptors_df`数据帧,如在`delaney_descriptors_df.drop(‘logS’, axis=1)`中,其中第一个输入参数是我们想要删除的特定列,而`axis=1`的第二个输入参数指定第一个输入参数是一列。

**第二编码单元:**

*   这里,我们通过`delaney_descriptors_df.logS`从`delaney_descriptors_df`数据帧中选择一列(‘logS’列),并将其分配给 **Y** 变量。

## 3.2.数据分割

在评估模型性能时,标准做法是将数据集拆分为 2 个(或更多分区)分区,这里我们将使用 80/20 的拆分比率,其中 80%的子集将用作训练集,20%的子集将用作测试集。由于 scikit-learn 要求将数据进一步分离到它们的 **X****Y** 组件,因此`train_test_split()`函数可以轻松执行上述任务。

**代码练习**

让我们实现以下两个代码单元。

**代码解释**

让我们看看代码在做什么。

***第一个编码单元格:***

*   这里我们将从 scikit-learn 库中导入`train_test_split`。

***第二个编码单元格:***

*   我们首先定义`train_test_split()`函数将生成的 4 个变量的名称,这包括`X_train`、`X_test`、`Y_train`和`Y_test`。前 2 个对应于训练和测试集的 X 数据帧,而后 2 个对应于训练和测试集的 Y 变量。

# 4.线性回归模型

现在,有趣的部分来了,让我们建立一个回归模型。

## 4.1.训练线性回归模型

**代码练习**

这里,我们将使用 scikit-learn 中的`LinearRegression()`函数,使用普通的最小二乘线性回归建立一个模型。

**代码解释**

让我们看看代码在做什么

**第一个编码单元:**

*   这里我们从 scikit-learn 库中导入了 linear_model

**第二编码单元:**

*   我们将`linear_model.LinearRegression()`函数赋给`model`变量。
*   使用命令`model.fit(X_train, Y_train)`构建模型,由此 model.fit()函数将把`X_train`和`Y_train`作为输入参数来构建或训练模型。特别是,`X_train`包含输入特征,而`Y_train`包含响应变量(日志)。

## 4.2.应用经过训练的模型来预测来自训练和测试集的日志

如上所述,`model.fit()`训练模型,训练后的模型保存在`model`变量中。

**代码练习**

我们现在将应用经过训练的模型对训练集进行预测(`X_train`)。

我们现在将应用训练好的模型对测试集进行预测(`X_test`)。

**代码解释**

让我们开始解释。

以下解释将仅涵盖训练集(`X_train`),因为通过执行以下简单调整,完全相同的概念可以同样地应用于测试集(`X_test`):

*   将`X_train`替换为`X_test`
*   将`Y_train`替换为`Y_test`
*   将`Y_pred_train`替换为`Y_pred_test`

其他一切都完全一样。

***第一个编码单元格:***

*   通过调用`model.predict()`并使用`X_train`作为输入参数来执行对日志值的预测,这样我们就可以运行命令`model.predict(X_train)`。产生的预测值将被赋给`Y_pred_train`变量。

***第二个编码单元:***

模型性能指标现已打印。

*   回归系数值从`model.coef_`获得,
*   y 轴截距值从`model.intercept_`获得,
*   使用`mean_squared_error()`函数计算均方误差(MSE ),使用`Y_train`和`Y_pred_train`作为输入参数,因此我们运行`mean_squared_error(Y_train, Y_pred_train)`
*   使用`Y_train`和`Y_pred_train`作为输入参数,使用`r2_score()`函数计算决定系数(也称为 R ),因此我们运行`r2_score(Y_train, Y_pred_train)`

## 4.3.打印出回归方程

线性回归模型的方程实际上是模型本身,您可以插入输入特征值,方程将返回目标响应值(对数)。

**代码练习**

现在让我们打印出回归模型方程。

**代码解释**

***第一个编码单元格:***

*   回归模型方程的所有组成部分都是从`model`变量中导出的。在`model.intercept_`、`model.coef_[0]`、`model.coef_[1]`、`model.coef_[2]`和`model.coef_[3]`中提供了 y 截距和 LogP、MW、RB 和 AP 的回归系数。

***第二码单元格:***

*   在这里,我们通过`print()`功能将组件放在一起并打印出方程式。

# 5.实验测井与预测测井的散点图

现在,我们将通过散点图来直观显示实验与预测测井曲线的相对分布。这样的情节可以让我们很快看到模型的性能。

**代码练习**

在接下来的例子中,我将向你展示如何不同地布置 2 个子图,即:(1)垂直图和(2)水平图。

**代码解释**

现在让我们看看实现垂直和水平图的底层代码。在这里,我提供了两个选项供您选择,让您选择是在垂直布局还是水平布局中使用这个多点图的布局。

***导入库***

两者都从导入必要的库开始,即`matplotlib`和`numpy`。特别是,大部分代码将使用`matplotlib`来创建绘图,而`numpy`库在这里用于添加趋势线。

***定义图尺寸***

接下来,我们通过`plt.figure(figsize=(5,11))`为垂直绘图指定图形尺寸(图形的宽度和高度),通过`plt.figure(figsize=(11,5))`为水平绘图指定图形尺寸。特别是,(5,11)告诉 matplotlib,垂直图的图形应该是 5 英寸宽和 11 英寸高,而水平图则使用相反的图形。

***定义子图*** 的占位符

我们将告诉 matplotlib,我们希望有 2 行和 1 列,因此它的布局将是垂直绘图。这是由`plt.subplot(2, 1, 1)`指定的,其中`2, 1, 1`的输入参数指的是 2 行 1 列以及我们在它下面创建的特定子图。换句话说,让我们把使用`plt.subplot()`功能看作是通过为图形包含的各种子图创建占位符来构建图形的一种方式。垂直图的第二个子图由`plt.subplot()`功能的第三个输入参数中的值 2 指定,如`plt.subplot(2, 1, 2)`所示。

通过应用相同的概念,通过容纳 2 个子图的`plt.subplot(1, 2, 1)`和`plt.subplot(1, 2, 2)`创建水平图的结构为 1 行 2 列。

***创建散点图***

既然图的一般结构已经就绪,现在让我们添加数据可视化。分别使用`plt.scatter(x=Y_train, y=Y_pred_train, c=”#7CAE00", alpha=0.3)`中的`plt.scatter()`函数添加数据散点,其中`x`指的是用于 *x* 轴的数据列,`y`指的是用于 *y* 轴的数据列,`c`指的是用于散点数据的颜色,`alpha`指的是 alpha 透明度级别(散点数据的透明度,数值越低,透明度越高)。

***添加趋势线***

接下来,我们使用来自`numpy`的`np.polyfit()`和`np.poly1d()`函数以及来自`matplotlib`的`plt.plot ()`函数来创建趋势线。

```
*# Add trendline*
*# https://stackoverflow.com/questions/26447191/how-to-add-trendline-in-python-matplotlib-dot-scatter-graphs*
z = np.polyfit(Y_train, Y_pred_train, 1)
p = np.poly1d(z)
plt.plot(Y_test,p(Y_test),"#F8766D")
```

***添加 x 和 y 轴标签***

为了给 *x* 和 *y* 轴添加标签,我们使用了`plt.xlabel()`和`plt.ylabel()`功能。需要注意的是,对于垂直图,我们省略了顶部子图的 x 轴标签(*为什么?因为对于底部子图*,x 轴标签是多余的。

***保存图***

最后,我们将把构建好的图形保存到文件中,我们可以使用来自`matplotlib`的`plt.savefig()`函数,并指定文件名作为输入参数。最后,以`plt.show()`结束。

```
plt.savefig('plot_vertical_logS.png')
plt.savefig('plot_vertical_logS.pdf')
plt.show()
```

**视觉解释**

上一节提供了基于文本的解释,在这一节中,我们将对这个视觉解释做同样的解释,它利用颜色高亮来区分情节的不同组成部分。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b23a06d752a7b00248f46fce23d6f49f.png)

**创建散点图的可视化说明。**这里我们用颜色高亮显示特定的代码行和它们对应的绘图组件。(由 Chanin Nantasenamat 绘制)

# 需要您的反馈

作为一名教育工作者,我喜欢听我如何改进我的内容。请在评论中告诉我:

1.  可视化插图有助于理解代码是如何工作的,
2.  视觉插图是多余的和不必要的,或者是否
3.  可视化插图补充了基于文本的解释,有助于理解代码是如何工作的。

## 订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!

# 关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名[数据教授](http://bit.ly/dataprofessor/))制作关于数据科学的在线视频。在我制作的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本([数据教授 GitHub page](https://github.com/dataprofessor/) )。

[](https://www.youtube.com/dataprofessor?sub_confirmation=1) [## 数据教授

### 数据科学、机器学习、生物信息学、研究和教学是我的激情所在。数据教授 YouTube…

www.youtube.com](https://www.youtube.com/dataprofessor?sub_confirmation=1) 

## 在社交网络上与我联系

✅YouTube:[http://youtube.com/dataprofessor/](http://youtube.com/dataprofessor/)
♇网站:[http://dataprofessor.org/](https://www.youtube.com/redirect?redir_token=w4MajL6v6Oi_kOAZNbMprRRJrvJ8MTU5MjI5NjQzN0AxNTkyMjEwMDM3&q=http%3A%2F%2Fdataprofessor.org%2F&event=video_description&v=ZZ4B0QUHuNc)(在建)
♇LinkedIn:[https://www.linkedin.com/company/dataprofessor/](https://www.linkedin.com/company/dataprofessor/)
♇Twitter:[https://twitter.com/thedataprof](https://twitter.com/thedataprof)
♇Facebook:[http://facebook.com/dataprofessor/](https://www.youtube.com/redirect?redir_token=w4MajL6v6Oi_kOAZNbMprRRJrvJ8MTU5MjI5NjQzN0AxNTkyMjEwMDM3&q=http%3A%2F%2Ffacebook.com%2Fdataprofessor%2F&event=video_description&v=ZZ4B0QUHuNc)
♇github:[https://github.com/dataprofessor/](https://github.com/dataprofessor/)
♇insta gram:【t2t

# 如何使用 Python 和 Heroku 从 CSV 文件构建关系数据库

> 原文:<https://towardsdatascience.com/how-to-build-a-relational-database-from-csv-files-using-python-and-heroku-20ea89a55c63?source=collection_archive---------8----------------------->

## 通过三个简单的步骤免费构建您自己的 PostgreSQL 数据库

对于较小的项目,CSV 是存储数据的好格式。但是,如果您想升级您的数据管理游戏呢?关系数据库为组织和管理您的数据提供了一种更可靠的方式。在这篇文章中,我展示了如何通过三个简单的步骤将 CSV 文件转换成 PostgreSQL 数据库。我还将讨论使用关系数据库的一些优点。

# 关系数据库的优势

关系数据库是一种将数据划分到具有共享数据点的链接表中的数据库。这些共享的数据点允许我们通过一个简单的查询来组合信息并创建新颖的表或视图。流行的关系数据库包括 [MySQL](https://www.mysql.com/) 、 [SQLite](https://www.sqlite.org/) 和 [PostgreSQL](https://www.postgresql.org) 。

构建一个合适的关系数据库需要时间和精力。但是,如果做得好,它有许多优势。

首先,关系数据库使您能够更容易地看到数据不同部分之间的关系。数据被划分到表中,并且可以使用包含简单数学运算的结构化查询语言(SQL)查询来组合(“联接”)。

其次,关系数据库提供了更好的数据管理,具有更高的一致性和灵活性。CSV 文件等其他格式很快变得难以管理,即使对于较小的项目也是如此。关系数据库允许您使用模式强制数据类型,从而减少了主要的潜在错误源。关系数据库还提供了更大的灵活性,因为您可以使用复杂的查询从相对简单的表中生成更复杂的数据。

第三,关系数据库解决了数据冗余的问题:一个好的关系数据库是围绕最小化数据重复和不一致的依赖关系而设计的,通过一个称为“规范化”的过程。[标准化是组织数据库中数据的过程](https://docs.microsoft.com/en-us/office/troubleshoot/access/database-normalization-description),包括创建表格和定义表格之间的关系。

第四,关系数据库已成为行业标准,数据库管理系统(DBMS)通常会提供一组您希望用于任何数据库的高级功能,如备份、故障转移和镜像。

阅读下面的说明时有一个重要的警告:这篇文章是*而不是*用来解释如何为你的关系数据库设计和建立一个生产级架构。在为生产环境设计数据库时,您需要更仔细地考虑权限、创建只读版本还是写版本、版本控制等等。相反,我将展示如何快速、轻松地创建自己的数据库供个人使用。

记住这一点,让我们开始使用 Heroku 和 Python 从 CSV 文件构建一个关系数据库。

# 步骤 1:在 Heroku 上设置 PostgreSQL 数据库

我们将从在 [Heroku](http://www.heroku.com) 上设置 PostgreSQL 实例开始。Heroku 是基于亚马逊网络服务(AWS)的平台即服务(PaaS),而[为 PostgreSQL](https://www.heroku.com/postgres) 提供了一个免费层。free 计划限制为 10,000 行,最大并发数为 20。您也将无法使用回滚和故障转移等更高级的功能,这两种功能对于任何生产级数据库都是可取的。它有一个手动备份功能,允许您生成和下载数据库的备份。

要在 Heroku 上设置 PostgreSQL 实例,首先登录您的 Heroku 帐户,从下拉菜单中创建一个新的应用程序。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/698adf3ce5933ab404f201d30fdf7094.png)

创建一个新的应用程序(由作者创建)

为你的应用程序选择一个名称和地区,然后点击“创建应用程序”按钮。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f58cffc5e04b09f495c860d7997b87d7.png)

为你的应用程序选择一个名字和地区

为您的新应用程序配置 PostgreSQL 数据库。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a344ffe1a715f3711529d7ea822e4f42.png)

为你的 Heroku 应用提供一个数据库

最后,找到并复制您的数据库凭证(您将需要它们来设置 Python 中的连接)。就这样,您拥有了自己的 PostgreSQL 数据库并正在运行!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/945c9f06f54226870c32f4ba1b7cb775.png)

在 Heroku 上找到并复制你的数据库凭证

# 步骤 2:定义您的模式

在本例中,我们将构建一个由随机生成的*媒体作者及其文章组成的数据库,并将这些数据存储为两个 CSV 文件。第一个 CSV 文件(或:“表”)是“作者表”,第二个 CSV 文件包含他们的帖子的数据。这些 CSV 文件和用于生成它们的脚本[可以在 Github](https://gist.github.com/ngoet/1b0e8b14a4169e42d9192a9b18e73afa) 上获得。*

让我们来看看这些表的模式。“模式”是数据库中表的正式语言表示。它定义了列、它们的名称和类型、分区规则等等。

**authors** 表包含条目写入表中的时间戳(`row_timestamp`)、作者的通用唯一标识符(UUID(`author_id`)、作者的名和姓(`author_first_name`);`author_last_name`),以及他们的电子邮件地址(`email`)。

```
row_timestamp TIMESTAMP NOT NULL,
author_id VARCHAR PRIMARY KEY NOT NULL,
author_first_name VARCHAR NOT NULL,
author_last_name VARCHAR NOT NULL,
email VARCHAR NOT NULL
```

**posts** 表还包括一个`row_timestamp`,每篇文章的唯一标识符(`post_id`),一个引用回`authors`表中`author_id`列的二级键,以及每篇文章的标题(`article_title`)。

```
row_timestamp TIMESTAMP NOT NULL,
post_id VARCHAR PRIMARY KEY NOT NULL,
author_id VARCHAR REFERENCES authors(author_id),
article_title VARCHAR NOT NULL
```

稍后在 PostgreSQL 数据库中设置表时,我们将使用这些模式。

# 第三步:一点 Python 的魔力

在我们的第三步也是最后一步,我们需要一些 Python 代码来使用 [psycopg2](https://www.psycopg.org) 库建立与 PostgreSQL 数据库的连接。我们首先创建三个函数,将表添加到数据库中,并将数据注入到数据库中。第一个函数`run_syntax`是一个助手函数,它使用数据库连接执行语法。第二个函数`create_table`接受模式定义、表和数据库名称,并将表添加到我们的数据库中。第三个函数`populate_table`获取一个 pandas 数据帧,并用该数据填充数据库中指定的表。

注意,我使用[环境变量](https://www.askpython.com/python/environment-variables-in-python)作为数据库访问凭证。即使对于较小的(非生产)项目,也不要在代码中包含这样的凭证,这是一个很好的做法。当您将代码推送到 Github 时,您可能会忘记删除它们,从而将您的数据库暴露给其他用户。

## 把所有的放在一起

要在 PostgreSQL 实例中设置表,您必须添加我们之前定义的模式定义,并添加一些代码来执行下面脚本中所示的`create_table`函数。

要将数据从 CSV 文件注入到这些表中,请使用以下脚本:

## 使用 IDE 或终端

要在 IDE 中使用上述代码,您必须将您的凭证作为环境变量添加到 Python 配置中(我使用 Pycharm)。或者,如果您想从终端运行上述脚本,您需要采取一些额外的步骤。首先,通过运行以下语法,将凭证作为环境变量添加到终端中,用您之前从 Heroku 获得的数据库凭证替换占位符。

```
hostname = <my_hostname>
user = <my_user>
password = <my_password>
database = <my_database>
```

第二步,您需要将环境变量传递给 Python 进程,方法是将以下代码添加到上面所示的`db_management`模块中:

```
os.environ["hostname"] = hostname
os.environ["user"] = user
os.environ["password"] = password
os.environ["database"] = database
```

最后,使用下面的命令,使用上面显示的`create_tables.py`和`populate_table.py`脚本,从终端执行 Python 代码来填充数据库:

```
python create_tables.py
python populate_tables.py
```

# 后续步骤:使用您的数据库

现在您有了一个可以连接和查询的 PostgreSQL 数据库。让我们检查一下这是否有效。Heroku 有一个简洁的数据剪辑功能,你可以用它在你的网站上嵌入查询输出,或者与合作者分享。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/abbf313be5e216d256448328db190bb9.png)

一个 Heroku 数据剪辑,显示了我们的数据库中前 5 名最多产的作者(语法:SELECT author_id,COUNT(post _ id)AS number _ of _ posts FROM posts GROUP BY author _ id ORDER BY number _ of _ posts desc 限制 5) (i *mage by author* )

准备好数据库后,您可以继续使用 [psycopg2](https://www.psycopg.org) 库直接在 Python 中管理数据,或者开始使用免费的数据库工具,如 [DBeaver](https://dbeaver.io) 。现在,您可以使用一系列简单的 SQL 命令来查看、管理您的数据并从中获得新的见解,或者将您的数据库用于其他应用程序,如仪表板或网站。

感谢阅读!

[](https://medium.com/@ndgoet/membership) [## 用我的推荐链接加入媒体。

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

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

**如果你喜欢这篇文章,这里还有一些你可能喜欢的文章:**

[](/creating-and-managing-elasticsearch-indices-with-python-f676ff1c8113) [## 使用 Python 创建和管理弹性搜索索引

### 从 CSV 文件创建 ES 索引以及使用 Python Elasticsearch 管理数据的实践指南…

towardsdatascience.com](/creating-and-managing-elasticsearch-indices-with-python-f676ff1c8113) [](/automating-unit-tests-in-python-with-hypothesis-d53affdc1eba) [## 使用假设在 Python 中自动化单元测试

### 单元测试是产生高质量代码的关键。以下是如何自动化测试 Python 代码。

towardsdatascience.com](/automating-unit-tests-in-python-with-hypothesis-d53affdc1eba) [](https://medium.com/python-in-plain-english/how-to-improve-your-python-code-style-with-pre-commit-hooks-e7fe3fd43bfa) [## 如何用预提交钩子改进 Python 代码风格

### 实施代码风格是简化开发过程的关键,下面是如何实现自动化。

medium.com](https://medium.com/python-in-plain-english/how-to-improve-your-python-code-style-with-pre-commit-hooks-e7fe3fd43bfa) 

*请仔细阅读* [*本免责声明*](https://medium.com/@ndgoet/disclaimer-5ad928afc841) *中的任何内容后再依托* [*我的 Medium.com 文章*](/@ndgoet) **

# 如何构建简历解析工具

> 原文:<https://towardsdatascience.com/how-to-build-a-resume-parsing-tool-ae19c062e377?source=collection_archive---------4----------------------->

## 我发现的最有效的方法

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f8569cd34ac81f80282f7387b3aa58c2.png)

照片由 [Pexels](https://www.pexels.com/photo/graphs-job-laptop-papers-590016/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels) 的 [Lukas](https://www.pexels.com/@goumbik?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels) 拍摄

当我还是一个大学的学生时,我很好奇简历的自动化信息提取是如何工作的。我将准备各种格式的简历,并将它们上传到求职门户网站,以测试背后的算法实际上是如何工作的。我总是想自己造一个。因此,在最近几周的空闲时间里,我决定构建一个简历解析器。

起初,我认为这相当简单。只是用一些模式去挖掘信息**但是事实证明我错了**!建立一个简历解析器是很困难的,你可以想象简历的布局有很多种。

例如,有些人会把日期放在简历标题的前面,有些人不写工作经历的时间,有些人不在简历中列出公司。这使得简历解析器更加难以构建,因为没有固定的模式可以捕获。

经过一个月的工作,根据我的经验,我想分享一下哪些方法效果很好,以及在开始构建自己的简历解析器之前应该注意哪些事项。

在进入细节之前,这里有一个视频短片,展示了我的简历解析器的最终结果。

# 数据收集

我刮了多个网站检索了 800 份简历。简历要么是 PDF 格式,要么是 doc 格式。

我使用的工具是谷歌的 Puppeteer (Javascript ),从几个网站收集简历。

数据收集的问题之一是找到一个好的来源来获取简历。在您能够发现它之后,只要您不太频繁地访问服务器,抓取部分就不会有问题。

之后我选择了一些简历,手动将数据标注到各个字段。标记工作已经完成,这样我就可以比较不同解析方法的性能。

# 预处理数据

剩下的部分,我用的编程是 Python。有几个软件包可以将 PDF 格式解析成文本,如 [PDF Miner](https://pypi.org/project/pdfminer/) 、 [Apache Tika](https://tika.apache.org/) 、[PDF tree](https://pypi.org/project/pdftotree/0.2.13/)等。让我比较一下不同的文本提取方法。

使用 PDF Miner 的一个缺点是当你处理的简历与 Linkedin 简历的格式相似,如下所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/086a15702218feeeb7ad8b7da5cc0cb0.png)

PDF Miner 在 PDF 中的读取方式是逐行读取。因此,如果发现左右部分的文本在同一行,它们将被组合在一起。因此,你可以想象,在随后的步骤中,你将更难提取信息。

另一方面,pdftree 将省略所有的' \n '字符,因此提取的文本将类似于一大块文本。因此,很难将它们分成多个部分。

所以我用的工具是 Apache Tika,这似乎是解析 PDF 文件的更好选择,而对于 docx 文件,我用 [docx](https://pypi.org/project/python-docx/) 包解析。

# 数据提取流程概述

这是棘手的部分。有几种方法可以解决这个问题,但是我会和你分享我发现的最好的方法和基线方法。

## 基线方法

先说基线法。我使用的基线方法是首先为每个部分(这里我指的部分是`experience`、`education`、`personal details`和`others`)抓取关键字,然后使用 regex 来匹配它们。

比如我要提取大学的名字。所以,我先找一个包含大部分大学的网站,把它们刮下来。然后,我使用 regex 来检查这个大学名称是否可以在特定的简历中找到。如果找到,这条信息将从简历中提取出来。

这样,我就能够构建一个基线方法,用来比较我的其他解析方法的性能。

## 最佳方法

另一方面,这是我发现的最好的方法。

首先,我将把纯文本分成几个主要部分。比如`experience`、`education`、`personal details`、`others`。我所做的是为每个主要部分的标题设置一组关键字,例如,`Working Experience`、`Eduction`、`Summary`、`Other Skills`等等。

当然,你可以尝试建立一个机器学习模型来进行分离,但我选择了最简单的方法。

之后,将有一个单独的脚本来分别处理每个主要部分。每个脚本将定义自己的规则,利用抓取的数据提取每个字段的信息。每个剧本里的规则其实都挺脏挺复杂的。由于我想让这篇文章尽可能简单,我不会在这个时候披露它。如果有兴趣了解详情,在下面评论!

我使用的机器学习方法之一是区分`company name`和`job title`。我在这里使用机器学习模型的原因是,我发现有一些明显的模式来区分公司名称和职位名称,例如,当你看到关键词“ **Private Limited”或“Pte Ltd”,**时,你肯定这是一个公司名称。

我从哪里得到数据来训练?

我从[绿皮书](http://www.thegreenbook.com/)上搜集数据,得到公司名称,并从[这个 Github 回购](https://github.com/fluquid/find_job_titles)上下载职位名称。

得到数据后,我只是训练了一个非常简单的朴素贝叶斯模型,它可以将职称分类的准确率提高至少 10%。

简而言之,我解析简历解析器的策略是通过**分而治之**。

# 估价

我使用的评估方法是 fuzzy-wuzzy 令牌集比率。比方说

*   s = #个公共令牌
*   S1 = Sorted _ tokens _ in _ intersection
*   S2 = Sorted _ tokens _ in _ intersection+Sorted _ rest _ of _ str 1 _ tokens
*   S3 = Sorted _ tokens _ in _ intersection+Sorted _ rest _ of _ str 2 _ tokens

并且 token_set_ratio 将被计算如下:

token _ set _ ratio = max(fuzz.ratio(s,s1),fuzz.ratio(s,s2),fuzz . ratio(s,s3))

我使用 token_set_ratio 的原因是,如果解析后的结果与带标签的结果相比有更多的公共标记,这意味着解析器的性能更好。

如果你对评估绩效的指标有其他想法,也欢迎在下面发表评论!

# 最终想法

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c4e94cae0d01b60b14303a545d299611.png)

安德烈亚斯·韦兰在 [Unsplash](https://unsplash.com/s/photos/happy?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

非常感谢你一直读到最后。这个项目实际上消耗了我很多时间。然而,如果你想解决一些具有挑战性的问题,你可以尝试这个项目!:)

# 关于作者

[Low 魏宏](https://www.linkedin.com/in/lowweihong/?source=post_page---------------------------)是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。

他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问[这个网站](https://www.thedataknight.com/)查看他的作品集,也可以联系他获取**的抓取服务**。

你可以在 [LinkedIn](https://www.linkedin.com/in/lowweihong/?source=post_page---------------------------) 和 [Medium](https://medium.com/@lowweihong?source=post_page---------------------------) 上和他联系。

[](https://medium.com/@lowweihong?source=post_page-----6bef8cb1477a----------------------) [## ●伟鸿-中等

### 在媒体上阅读低纬鸿的作品。数据科学家|网络抓取服务:https://www.thedataknight.com/.每…

medium.com](https://medium.com/@lowweihong?source=post_page-----6bef8cb1477a----------------------) 

# 你可能喜欢的故事

[](/brutal-truths-that-nlp-data-scientists-will-not-tell-you-7f387de66cd5) [## NLP 数据科学家不会告诉你的残酷事实

### 由数据科学家分享

towardsdatascience.com](/brutal-truths-that-nlp-data-scientists-will-not-tell-you-7f387de66cd5)

# 如何构建可扩展的大数据分析管道

> 原文:<https://towardsdatascience.com/how-to-build-a-scalable-big-data-analytics-pipeline-7de18f8be848?source=collection_archive---------11----------------------->

## 大规模建立端到端系统

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ea02dde5535ab5f1601790cccf73a0c5.png)

照片由 [Pexels](https://www.pexels.com/photo/person-writing-on-notebook-669615/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels) 的 [Lukas](https://www.pexels.com/@goumbik?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels) 拍摄

D ata 是当今创新企业的重要元素。数据驱动的决策使企业能够适应不可预测的世界。*报告数据的能力是商业分析的支柱*。随着 21 世纪数据的空前增长,大数据不再是一个时髦词,而是企业必须面对的现实。

> 你应该像爱自己一样爱你的数据

数据呈指数级增长,这要求数据系统始终具有可扩展性。构建大规模的**大数据管道**以及整合到现有的分析生态系统中,对于那些不熟悉这两者的人来说将是一个巨大的挑战。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/aaa28c5cbacb4c73b7af74e01131837a.png)

由[弗兰基·查马基](https://unsplash.com/@franki?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/photos/1K6IQsQbizI?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

要构建可扩展的大数据分析渠道,您必须首先确定三个关键因素:

> **输入数据**

*无论是时间序列还是非时间序列,你都必须知道你的管道输入数据的性质。它将决定以何种格式存储数据,当数据丢失时如何处理,以及在管道的其余部分使用何种技术。*

> **输出数据**

构建分析渠道时,你需要关心终端用户。数据分析师使用您的管道来构建报告仪表板或可视化。鉴于最终用户可能缺乏数据工程方面的强有力的技术专长,输出数据需要是可访问和可操作的。如今,著名的分析引擎简化了大数据生态系统和分析仓库之间的集成。

> **管道可以摄取多少数据?**

*您的数据系统的可扩展性可以决定企业的长期生存能力。一天处理 100 GB 和 1 TB 之间没有什么相似之处。硬件和软件基础设施必须跟上数据量的突然变化。由于业务的有机增长,您不想让您的数据系统过载。以最佳方式扩展您的数据管道!*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5b18d82ed790ee5cb12a21da334061cb.png)

典型的大数据分析渠道。作者署名

# 数据收集

数据收集是数据管道的第一个也是最重要的模块,在这里您必须评估数据的来源。它们是来自另一个数据源还是顶级应用程序?数据是结构化的还是非结构化的?您需要执行任何数据清理吗?*我们可能认为大数据是一堆杂乱无章的数据,但实际上,大多数大数据都是结构化的*。非结构化数据需要额外的技术来构建数据管道。

您的管道架构将因您选择的数据收集方法而异:批处理或通过流服务。批处理流水线需要一个高效的存储系统来进行 I/O 操作,而流处理流水线更喜欢容错传输协议。

说到结构化数据,无论是文本、数字还是图像,要将它们输入管道,都必须经过一个必不可少的过程:**数据序列化**。[数据序列化是将结构化数据转换为一种格式的过程,这种格式允许以允许恢复其原始结构的形式共享或存储数据。](https://docs.python-guide.org/scenarios/serialization/)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2b254f7e3f1b50ec27ceb8350beea03a.png)

来源:[https://devopedia.org/data-serialization](https://devopedia.org/data-serialization)

数据串行化导致跨管道的同质数据结构,从而保持所有数据处理模块的一致性。 **XML****CSV****YAML****JSON** 是数据序列化中最流行的一些格式。序列化数据在存储和传输方面更加优化。*将数据从一个系统传输到另一个系统可能会遇到不兼容的问题,因此逐位通信可以确保没有信息丢失。*

JSON 对于处理互联网上的平面和嵌套数据结构来说非常方便。它提供了人类可读的格式和与 JVM 系统的高度集成。然而,在大数据处理中,JSON 的使用不如其他方法受欢迎,因为它没有经过优化的存储和缺乏结构验证。

一个 JSON 例子来模拟一个地址簿

[**【proto buf】**](https://en.wikipedia.org/wiki/Protocol_Buffers)协议缓冲区是 Google 内部序列化结构化数据的机制。使用 protobuf,您可以定义一个通用模式,然后用您喜欢的编程语言执行读/写操作。*想想像 XML 这样的语言神经格式,但是更快更小*。除了非人类可读的缺点,protobuf 的执行速度比 JSON 快 6 倍。

来源:[https://developers . Google . com/protocol-buffers/docs/Java tutorial](https://developers.google.com/protocol-buffers/docs/javatutorial)

```
***Key takeaways:***- Storage is essential for batch processing while the transmission is critical for streaming service
- Serialization maintains a stable communication transferring between systems
- Use protobuf to serialize data for a better performance
```

# 数据存储

假设您已经启动并运行了数据收集模块,那么您将在哪里存储所有这些数据呢?取决于很多东西:*硬件资源、数据管理专业知识、维护预算等。在决定把钱花在哪里之前,你需要下定决心,因为这是一场长期的比赛。*

> 数据是新的石油,所以最好把石油放在你的后院

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3c78a6358d712eaa336eb246efdbd735.png)

资料来源:https://architecht.io/what-happened-to-hadoop-211aa52a297

如果你有大笔资金,最好的办法是建立自己的数据基础设施。*数据是新的石油,所以最好把石油放在你的后院*。雇佣最好的硬件工程师,组装一个合适的数据中心,并在此基础上构建您的管道。 **Hadoop 文件系统(HDFS)** 一直是内部数据架构的首选。它提供了一个紧密集成的生态系统,包含所有可用于数据存储和 ETL 的工具和平台。设置一个可行的 Hadoop 堆栈只需付出最少的努力。它的强大之处在于横向扩展的能力,这意味着并排捆绑商用硬件以最大化性能和最小化成本。

您甚至可以通过优化存储格式来更进一步。将文件存储在。txt 或者。在 HDFS 的领导下,csv 格式可能不是最明智的想法。 [**Apache Parquet**](https://parquet.apache.org/) 是一种列格式,适用于 Hadoop 中的任何项目,并且是每个数据工程师都推荐的格式。作为一种基于列的存储格式,Parquet 提供了更好的压缩,从而优化了 I/O 操作。它唯一的缺点是模式修改的限制,例如,添加或删除一列需要花费更多的精力。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7c76f51e6bbf5ecd58c3d702f3910b9e.png)

这是你的数据在 Hadoop 分区下的样子。照片由 [Kolar.io](https://unsplash.com/@jankolar?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 在 [Unsplash](https://unsplash.com/s/photos/database?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄

来自 SQL 后台,也可以建立一个更易访问的查询系统。 [**Apache Hive**](https://hive.apache.org/) 数据仓库软件有助于使用 SQL 读取、写入和管理驻留在分布式存储中的大型数据集。 [Hive 提供了一种类似 SQL 的查询语言(HiveQL)来直接在 HDFS 上执行查询。](https://en.wikipedia.org/wiki/Apache_Hive)尽管 HiveQL 没有遵循所有的 SQL 标准,但它仍然简化了那些不懂 Hadoop 的人的查询过程。另一个常见的查询引擎是由脸书工程师开发的[](https://prestodb.io/)**。**

**同样,如果你没有足够的资源来构建自己的数据仓库,[你可以将整个系统外包给基于云的平台](https://www.g2.com/products/hadoop-hdfs/competitors/alternatives)。许多著名的科技公司都提供一体化的大数据架构,如 [**【谷歌大查询】**](https://cloud.google.com/bigquery)[**亚马逊 AWS**](https://aws.amazon.com/)[**微软 Azure**](https://azure.microsoft.com/) 。通过外包,你不必费心建立或维护生态系统,但这带来了无法控制你的管道的风险。*在高成本、低维护和低成本、高维护之间有一个折衷方案*。然而,你可以把赌注压在科技巨头管理你的管道的专业技能上。**

```
***Key takeaways:***-If you have big money, go for DIY data architecture, if not, our-sourcing is your answer
- Use parquet to store files in Hadoop ecosystem
- Setup a query system upon Hadoop for easy access
```

# **分析引擎**

**Hadoop 生态系统及其替代品有利于大数据存储系统,但它们不适合作为分析引擎。它们不是为执行快速查询而构建的。*出于分析目的,我们经常执行特别查询,因此需要一个能快速返回结果的系统。*从属存储需要建立在分析引擎之上。**

**[**Vertica**](https://www.vertica.com/) 是一个数据库管理系统,专为大规模分析和快速查询性能而设计。*它以列格式存储数据,并创建投影以将数据分布在其节点上,用于高速查询*。由于其提供强大的分析引擎和高效的查询系统的声誉,Vertica 被许多科技公司广泛使用。由于使用 **Java** 、 **Scala** 、 **Python** 、 **C++** 的简单集成,Vertica 可以为众多与数据相关的外部应用程序扮演数据库的角色。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/08f10ebb6c27e2f938056a395958bd0f.png)**

**分析仪表板示例。[卢克·切瑟](https://unsplash.com/@lukechesser?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/chart?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片**

**[然而,Vertica 显示了处理实时数据或高延迟分析的一些缺点](https://imply.io/post/compare-apache-druid-to-vertica)。它对更改模式或修改投影的约束限制了它对快速转换数据的使用。 [**德鲁伊**](https://druid.apache.org/) 是一个开源的分析数据库,专门为***【OLAP】***在线分析处理而设计。时间序列数据需要优化的存储机制和快速的聚集器。它主要包含时间戳和指标。 *Druid 将指标存储为列,并基于索引和指标对数据进行分区,以便快速访问,因此提供了敏捷的聚合操作。***

```
***Key takeaways:***- Vertica is great for low-latency analytics but requires much expertise to scale
- Druid is built for time series data and provide a fast access system
- Choose analytics database with maximum integration to visualization tools
```

# **监控和质量**

**完成数据收集、存储和可视化集成后,您可能想要即插即用。但是还有最后一件事就是万一发生事故该怎么办。当您的管道无缘无故崩溃时,您会向谁求助?这就是整个监控过程的目的。它可以帮助您跟踪、记录和观察系统的健康状况和性能。一些工具甚至允许你动态调试。也就是说,如果你想建立一个持久的数据管道,一个合适的监控系统是必不可少的。这里我们区分两种: **IT 监控**和**数据监控**。**

**IT 监控对于任何软件开发都是必要的。它显示各种与系统相关的指标,如 CPU、磁盘使用、资源消耗、分配的内存等。您可以查看 IT 监控,看看能否将管道的容量增加一倍或两倍。借助 Hadoop 或 Vertica 等预优化的生态系统,我们不需要太担心 IT 性能。你可以选择[任何基本的 IT 监控工具](https://searchitoperations.techtarget.com/feature/Compare-Grafana-vs-Datadog-for-IT-monitoring),如 [**Grafana**](https://grafana.com/) 或 [**Datadog**](https://www.datadoghq.com/) 来建立一个简单的仪表板,跟踪你的指标。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/978a3d841e1463c13167482466c7122b.png)**

**Grafana 仪表板示例。来源:[佩尔科纳](https://www.percona.com/blog/2016/10/25/monitoring-os-metrics-amazon-rds-grafana/)**

***数据监控与大数据分析管道中的其他模块一样重要。*它检测与数据相关的问题,如延迟、数据缺失、数据集不一致。数据管道的质量反映了系统内数据流通的完整性。这些指标确保从一个地方传输到另一个地方的数据丢失最小或为零,而不会影响业务成果。我们无法说出数据监控工具记录的所有指标,因为每个数据管道都有其特定的需求,因此需要特定的跟踪。*如果你正在建立一个时间序列数据管道,关注延迟敏感指标。如果您的数据是成批出现的,请确保正确跟踪传输过程*。一些数据监控工具可以帮助您构建一个简单的数据监控仪表板,但是为了适合您的特定用途,最好自己构建一个。**

```
***Key takeaway:***- Monitoring tools are indispensable in a data pipeline, but not all metrics are equally important *-* Data pipeline quality means the integrity of your data
```

# **结论**

**我们花了相当多的时间讨论基本的端到端大数据分析管道,我希望您已经获得了一些有用的知识。构建这样的管道没有万能的公式,但是您可以基于基本的蓝图来创建自己的管道。**

# 如何建立一个搜索引擎

> 原文:<https://towardsdatascience.com/how-to-build-a-search-engine-9f8ffa405eac?source=collection_archive---------3----------------------->

## 用几行代码在 Python 中创建健壮的全文搜索

这篇文章概述了当今使用的最重要的搜索算法之一,并展示了如何用几行代码用 Python 实现它。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/232f489843ad71dc6a325183aa7abe43.png)

来源:作者

## 搜索的价值

我们认为搜索数据的能力是理所当然的。现代搜索引擎现在如此复杂,以至于我们的大部分搜索“刚刚好”。事实上,我们经常只注意到网站或应用程序上的搜索没有执行。我们对这一领域的期望从未如此之高。

搜索引擎的智能一直在增长,原因很简单,一个有效的搜索工具能给企业带来的价值是巨大的;一项重要的知识产权。搜索栏通常是客户和企业之间的主要界面。因此,一个好的搜索引擎可以通过改善用户体验来创造竞争优势。

MckKinsey 估计,2009 年这一价值在全球范围内总计达到 7800 亿美元。这将使每次搜索的价值为 0.50 美元[1]。当然,自 2009 年以来,这一数值无疑有了大幅增长…

考虑到这一点,创建一个现代搜索引擎超出了大多数开发团队的能力,需要大量的资源和复杂的算法,这是可以理解的。然而,有点令人惊讶的是,大量的企业业务搜索引擎实际上是由非常简单和直观的规则驱动的,这些规则可以使用开源软件轻松实现。

例如,优步、Udemy Slack 和 Shopify(以及 3000 家其他企业和组织[2])都在使用 Elasticsearch。直到 2016 年,这个搜索引擎都是由极其简单的*词频、逆文档频率*(或 tf-idf)单词分数驱动的。[3](关于这是什么的更多细节,我已经在这里和这里写了关于 tf-idf [。](/supercharging-word-vectors-be80ee5513d)

在这之后,它切换到更复杂(但仍然非常简单)的 BM25,这种 BM25 一直沿用至今。这也是 Azure 认知搜索中实现的算法[4]。

## BM25:你从未听说过的最重要的算法

那么 BM25 是什么呢?它代表“最佳匹配 25”(其他 24 次尝试显然不太成功)。它是在 1994 年第三届文本检索会议上发布的,是的,的确有一个致力于文本检索的会议…

它可能被认为是 tf-idf 的“兴奋剂”,实现了两个关键的改进:

*   **项频率饱和**。BM25 为与文档匹配的术语数量提供递减的回报。这是相当直观的,如果你想搜索一个在文档中非常常见的特定术语,那么这个术语的出现次数对搜索来说就变得不那么有用了。
*   **公文长度。** BM25 在匹配过程中考虑文档长度。同样,这是直观的;如果一篇较短的文章包含与一篇较长的文章相同数量的匹配项,那么这篇较短的文章可能更相关。

这些改进还引入了两个超参数来调整这些项目对排名函数的影响。“k”用于调整术语饱和的影响,“b”用于调整文档长度。

综上所述,BM25 的计算公式为:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0afbc8f5d11492648f98830c5ba612a0.png)

简化的 BM25 算法。来源:作者

## 实施 BM25,一个成功的例子

实现 BM25 非常简单。多亏了 *rank-bm25* Python 库,这可以用几行代码实现。

在我们的示例中,我们将创建一个搜索引擎来查询英国公共部门组织发布的合同通知。

我们的起点是一个 dateset,它包含合同通知的标题、描述以及通知本身的链接。为了简单起见,我们将标题和描述组合在一起,在数据集中创建“文本”列。我们将使用该列进行搜索。我们想要搜索 50,000 个文档:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/59b164f43b6c238e3cf3ab3b048e3639.png)

要在搜索引擎中使用的数据格式(50,000 行中的前两行)。来源:作者

在本文的底部可以找到数据和代码的链接。

本练习的第一步是提取该数据集的“文本”列中的所有单词,以创建一个由每个文档及其单词组成的“列表列表”。这被称为标记化,可以由优秀的空间库来处理:

```
import spacy
from rank_bm25 import BM25Okapi
from tqdm import tqdm
nlp = spacy.load("en_core_web_sm")text_list = df.text.str.lower().values
tok_text=[] # for our tokenised corpus#Tokenising using SpaCy:
for doc in tqdm(nlp.pipe(text_list, disable=["tagger", "parser","ner"])):
   tok = [t.text for t in doc if t.is_alpha]
   tok_text.append(tok)
```

构建 BM25 索引只需一行代码:

```
bm25 = BM25Okapi(tok_text)
```

查询这个索引只需要一个已经标记化的搜索输入:

```
query = "Flood Defence"tokenized_query = query.lower().split(" ")import timet0 = time.time()
results = bm25.get_top_n(tokenized_query, df.text.values, n=3)
t1 = time.time()print(f'Searched 50,000 records in {round(t1-t0,3) } seconds \n')for i in results:
   print(i)
```

这将返回与搜索查询“防洪”高度相关的前 3 个结果:

```
*Searched 50,000 records in 0.061 seconds:*Forge Island Flood Defence and Public Realm Works Award of Flood defence and public realm works along the canal embankment at Forge Island, Market Street, Rotherham as part of the Rotherham Renaissance Flood Alleviation Scheme. Flood defence maintenance works for Lewisham and Southwark College **AWARD** Following RfQ NCG contracted with T Gunning for Flood defence maintenance works for Lewisham and Southwark College Freckleton St Byrom Street River Walls Freckleton St Byrom Street River Walls, Strengthening of existing river wall parapets to provide flood defence measures
```

我们可以根据执行搜索的用户的预期偏好来微调“k”和“b”的值,但是默认的 k=1.5 和 b=0.75 在这里似乎也很好。

## 最后

希望这个例子突出了用 Python 实现健壮的全文搜索是多么简单。这可以很容易地用来驱动一个简单的 web 应用程序或智能文档搜索工具。还有很大的空间来进一步提高这方面的性能,这将在下面的后续帖子中介绍!

[](/how-to-build-a-smart-search-engine-a86fca0d0795) [## 如何建立一个智能搜索引擎

### 用 Python 创建智能搜索服务

towardsdatascience.com](/how-to-build-a-smart-search-engine-a86fca0d0795) 

**参考文献:**

这篇文章的代码和数据可以在这个 [Colab 笔记本](https://colab.research.google.com/drive/1vtBleNUwj4a29vCjzFMKheaBO1Du0fwq?usp=sharing)中找到。

[1]麦肯锡对网络搜索的评论:[https://www . McKinsey . com/~/media/McKinsey/dot com/client _ service/High % 20 tech/pdf/Impact _ of _ Internet _ technologies _ search _ final 2 . aspx](https://www.mckinsey.com/~/media/mckinsey/dotcom/client_service/High%20Tech/PDFs/Impact_of_Internet_technologies_search_final2.aspx)

[2] [据 StackShare 报道,2020 年 8 月。](https://stackshare.io/elasticsearch#:~:text=Who%20uses%20Elasticsearch%3F&text=3034%20companies%20reportedly%20use%20Elasticsearch,Uber%2C%20Udemy%2C%20and%20Shopify.)

[3]从 Elasticsearch v5.0 开始,BM25 成为默认搜索:[https://www.elastic.co/blog/elasticsearch-5-0-0-released](https://www.elastic.co/blog/elasticsearch-5-0-0-released)

[4][https://docs . Microsoft . com/en-us/azure/search/index-ranking-similarity](https://docs.microsoft.com/en-us/azure/search/index-ranking-similarity)

# 如何用 Transformers 和 Faiss 构建语义搜索引擎

> 原文:<https://towardsdatascience.com/how-to-build-a-semantic-search-engine-with-transformers-and-faiss-dcbea307a0e8?source=collection_archive---------2----------------------->

## [实践教程](https://towardsdatascience.com/tagged/hands-on-tutorials)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/54212bf2076d6803aa511e6458e3289c.png)

图片由 Kostas Stathoulopoulos 提供

# 介绍

您是否想过如何使用 Transformers 创建最先进的句子嵌入,并将其用于下游任务,如语义文本相似性?

在本教程中,你将学习如何用[句子变形器](https://github.com/UKPLab/sentence-transformers/)和 [Faiss](https://github.com/facebookresearch/faiss) 构建一个基于向量的搜索引擎。如果你想直接进入代码,看看 [GitHub repo](https://github.com/kstathou/vector_engine) 和 [Google Colab notebook](https://colab.research.google.com/drive/11WBCrwNzbNWN7QbMEwzy-8MZROOVQFnZ?usp=sharing) 。

在本教程的第二部分,您将学习如何在一个 Streamlit 应用程序中服务搜索引擎,使用 Docker 和 AWS Elastic Beanstalk 部署它。

# 为什么要建立一个基于向量的搜索引擎?

基于关键字的搜索引擎易于使用,并且在大多数情况下都工作得很好。你查询*机器学习*论文,它们会返回一堆结果,这些结果包含与查询完全匹配或相近的变体,比如*机器学习*。其中一些甚至可能返回包含查询同义词或出现在相似上下文中的单词的结果。其他的,如 [Elasticsearch](https://www.elastic.co/elasticsearch/) ,以快速和可扩展的方式做所有这些事情,甚至更多。然而,基于关键字的搜索引擎通常会遇到以下问题:

*   复杂的查询或具有双重含义的单词。
*   长查询,如论文摘要或博客中的段落。
*   不熟悉某个领域的行话的用户或希望进行探索性搜索的用户。

基于向量的(也称为语义的)搜索引擎通过使用最先进的语言模型找到文本查询的数字表示,在高维向量空间中索引它们,并测量查询向量与索引文档的相似程度来解决这些缺陷。

# 索引、矢量化和排序方法

在深入本教程之前,我将简要解释基于关键字和基于向量的搜索引擎如何(1) **索引文档**(即以易于检索的形式存储它们),(2) **对文本数据进行矢量化**和(3) **测量文档与查询的相关性**。这将有助于我们突出两个系统之间的差异,并理解为什么基于向量的搜索引擎可能会为长文本查询提供更有意义的结果。

## **1。基于关键词的搜索引擎**

让我们用一个过于简化的版本 [Elasticsearch](https://www.elastic.co/elasticsearch/service) 作为例子。Elasticsearch 使用一个[标记器](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenizers.html)将一个文档分割成标记(即有意义的文本单元),这些标记被映射成数字序列并用于构建一个[倒排索引](https://en.wikipedia.org/wiki/Inverted_index)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/befbeb4d6a6ab58b5356823925897c71.png)

*倒排索引:倒排索引使我们能够一次查找一个术语并检索包含该术语的所有文档的列表,而不是遍历每个文档来检查它是否包含查询术语。* [*图片*](https://www.elastic.co/blog/found-indexing-for-beginners-part3/) *作者:*[Morten Ingebrigtsen](https://www.elastic.co/blog/author/morten-ingebrigtsen)

与此同时,Elasticsearch 用一个高维的加权向量来表示每个索引文档,其中每个不同的索引项都是一个维度,它们的值(或权重)用 [TF-IDF](http://www.tfidf.com/) 来计算。

为了找到相关的文档并对它们进行排序,Elasticsearch 结合了布尔模型(BM)和向量空间模型(VSM)。BM 标记哪些文档包含用户的查询,VSM 对它们的相关程度进行评分。在搜索期间,使用相同的 TF-IDF 管道将查询转换为向量,然后文档`d`对于查询`q`的 VSM 分数是加权查询向量`V(q)`和`V(d)`的余弦相似度。

> 这种度量相似性的方式非常简单,并且不可扩展。Elasticsearch 背后的主力是 Lucene,它采用了各种技巧,从增强字段到改变向量的标准化方式,来加速搜索并提高搜索质量。

Elasticsearch 在大多数情况下都很有效,然而,我们也想创建一个关注单词上下文的系统。这就把我们带到了基于向量的搜索引擎。

## 2.基于向量的搜索引擎

我们需要创建考虑单词上下文的文档表示。我们还需要一种高效可靠的方法来检索存储在索引中的相关文档。

**创建密集文档向量**

近年来,NLP 社区在这方面取得了长足的进步,许多深度学习模型都是开源的,并由像 [Huggingface 的变形金刚](https://huggingface.co/)这样的软件包分发,这些软件包提供了对最先进的预训练模型的访问。使用预训练模型有许多优点:

*   它们通常产生高质量的嵌入,因为它们是在大量文本数据上训练的。
*   他们不要求你创建一个定制的标记器,因为变形金刚有他们自己的[方法](https://github.com/huggingface/tokenizers)。
*   根据您的任务微调模型是很简单的。

这些模型为文档中的每个**标记**生成一个固定大小的向量。但是,我们如何获得文档级向量呢?这通常是通过平均或汇集单词向量来完成的。然而,这些方法[产生低于平均水平的句子和文档嵌入,通常比平均手套向量](https://arxiv.org/abs/1908.10084)更差。

为了构建我们的语义搜索引擎,我们将使用[句子转换器](https://github.com/UKPLab/sentence-transformers)来微调基于 BERT 的模型,以生成语义上有意义的长文本序列嵌入。

**建立指数和衡量相关性**

检索相关文档最简单的方法是测量查询向量和数据库中每个文档向量之间的余弦相似性,并返回得分最高的那些向量。不幸的是,这在实践中非常慢。

首选的方法是使用 **Faiss** ,一个用于高效相似性搜索和密集向量聚类的库。Faiss 提供了大量的[指数](https://github.com/facebookresearch/faiss/wiki/Faiss-indexes)和[综合指数](https://github.com/facebookresearch/faiss/wiki/Faiss-indexes-(composite))。此外,给定一个 GPU,Faiss 可以扩展到数十亿个向量!

# 教程:用句子转换器和 Faiss 构建基于向量的搜索引擎

在这个实际例子中,我们将使用真实世界的数据。我通过用 [Orion](https://github.com/orion-search/orion) 查询[微软学术图](https://www.microsoft.com/en-us/research/project/academic-knowledge/),创建了一个包含 2010 年至 2020 年间发表的 8430 篇关于错误信息、虚假信息和假新闻的学术文章的数据集。

我检索了论文的摘要、标题、引文、出版年份和 ID。我做了最少的数据清理工作,比如拿走没有摘要的文件。数据如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/23afd636c1d8b869daae3834aa3d2d79.png)

图片由 Kostas Stathoulopoulos 提供

## **导入 Python 包并从 S3 读取数据**

让我们导入所需的包并读取数据。该文件是公开的,所以你可以[在 Google Colab](https://colab.research.google.com/drive/11WBCrwNzbNWN7QbMEwzy-8MZROOVQFnZ?usp=sharing) 上运行代码,或者通过[访问 GitHub repo](https://github.com/kstathou/vector_engine) 在本地运行代码!

## **使用句子转换器对文档进行矢量化**

接下来,让我们对论文摘要进行编码。[句子变形器](https://github.com/UKPLab/sentence-transformers)提供了许多预训练的模型,其中一些可以在这个[电子表格](https://docs.google.com/spreadsheets/d/14QplCdTCDwEmTqrn1LH4yrbKvdogK4oQvYO1K1aPR5M/)中找到。这里,我们将使用在语义文本相似性任务中表现出色的`distilbert-base-nli-stsb-mean-tokens`模型,它比 BERT 快得多,因为它要小得多。

在这里,我们将:

1.  通过将模型名称作为字符串传递来实例化转换器。
2.  如果可用,切换到 GPU。
3.  使用`. encode()'方法对所有论文摘要进行矢量化处理。

> 使用转换器对文档进行矢量化时,建议使用 GPU。Google Colab 免费提供一个!**如果你想在 AWS 上运行它,请查看我的指南** [**如何在 AWS 上启动用于机器学习的 GPU 实例**](https://medium.com/@kstathou/how-to-set-up-a-gpu-instance-for-machine-learning-on-aws-b4fb8ba51a7c) **。**

## **用 Faiss 索引文档**

Faiss 包含在任意大小的向量组中搜索的算法,甚至是不适合 RAM 的向量组。要了解 Faiss 的更多信息,你可以阅读他们在 arXiv 或 wiki 上的论文。

Faiss 是围绕`Index`对象构建的,该对象包含可搜索向量,有时还对其进行预处理。它处理固定维度的向量集合`d`,通常是几十到 100 个。

> Faiss 只使用 32 位浮点矩阵。这意味着我们必须在构建索引之前改变输入的数据类型。

这里,我们将使用执行强力 L2 距离搜索的`IndexFlatL2`索引。它适用于我们的数据集,但是,对于大型数据集,它可能会非常慢,因为它与索引向量的数量成线性关系。Faiss 还提供[快速索引](https://github.com/facebookresearch/faiss/wiki/Faster-search)!

为了用抽象向量创建索引,我们将:

1.  将抽象向量的数据类型更改为`float32`。
2.  建立一个索引,并向它传递它将操作的向量的维数。
3.  将索引传递给`IndexIDMap`,这个对象使我们能够为索引向量提供一个定制的 id 列表。
4.  将抽象向量及其 ID 映射添加到索引中。在我们的例子中,我们将把向量映射到 Microsoft Academic Graph 中的论文 id。

为了测试索引是否按预期工作,我们可以用一个索引向量查询它,并检索它最相似的文档以及它们的距离。第一个结果应该是我们的查询!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3941a72bfc5dbc6bc3cb800fa8baaa3a.png)

因为我们使用索引向量查询 Faiss,所以第一个结果必须是查询,并且距离必须等于零!图片由 Kostas Stathoulopoulos 提供

## **使用用户查询进行搜索**

让我们尝试为一个新的、看不见的搜索查询找到相关的学术文章。在这个例子中,我将使用 [*的第一段来查询我们的索引。WhatsApp 可以从被揭穿的事实核查的故事中受益以减少错误信息吗?*](https://misinforeview.hks.harvard.edu/article/can-whatsapp-benefit-from-debunked-fact-checked-stories-to-reduce-misinformation/) 发表在《HKS 误传评论》上的文章。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9298a02d6a787d752390666a75d54895.png)

图片由 Kostas Stathoulopoulos 提供

要为新的查询检索学术文章,我们必须:

1.  用我们用于抽象向量的相同的句子蒸馏模型对查询进行编码。
2.  将其数据类型更改为`float32`。
3.  使用编码的查询搜索索引。

为了方便起见,我将这些步骤包装在了`vector_search()`函数中。

这篇文章讨论了错误信息、事实核查、WhatsApp 以及巴西和印度的选举。我们希望基于向量的搜索引擎能够返回这些主题的结果。通过检查论文标题,大多数结果看起来与我们的查询非常相关。我们的搜索引擎工作正常!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ad3e3be5805fef48a3ff47b41f5accfd.png)

图片由 Kostas Stathoulopoulos 提供

# 结论

在本教程中,我们使用句子转换器和 Faiss 构建了一个基于向量的搜索引擎。我们的索引运行良好,但相当简单。我们可以通过使用领域特定的转换器来提高嵌入的质量,比如 SciBERT 已经在来自 semanticscholar.org 语料库的论文上进行了训练。我们还可以在返回结果之前删除重复项,并尝试使用其他索引。

对于那些使用 Elasticsearch 的人,Open Distro 引入了一个[近似 k-NN 相似性搜索特性](https://opendistro.github.io/for-elasticsearch/blog/odfe-updates/2020/04/Building-k-Nearest-Neighbor-(k-NN)-Similarity-Search-Engine-with-Elasticsearch/),它也是 [AWS Elasticsearch 服务](https://aws.amazon.com/about-aws/whats-new/2020/03/build-k-nearest-neighbor-similarity-search-engine-with-amazon-elasticsearch-service/)的一部分。在另一篇博客中,我也会深入探讨这个问题!

最后,你可以在 GitHub 上找到[代码,然后用 Google Colab](https://github.com/kstathou/vector_engine) 试一试[](https://colab.research.google.com/drive/11WBCrwNzbNWN7QbMEwzy-8MZROOVQFnZ?usp=sharing)

# 参考

[1]n . tha kur,n . Reimers,n . daxen Berger,j .和 Gurevych,I .,2020 年。增强 SBERT:用于改进成对句子评分任务的双编码器的数据增强方法。 *arXiv 预印本 arXiv:2010.08240* 。

[2]j .约翰逊,m .杜泽和 h .杰古,2019 年。用 GPU 进行亿级相似性搜索。 *IEEE 大数据汇刊*。

# 如何使用 AWS Chalice 构建无服务器应用程序

> 原文:<https://towardsdatascience.com/how-to-build-a-serverless-application-using-aws-chalice-91024416d84f?source=collection_archive---------21----------------------->

## [动手教程](https://towardsdatascience.com/tagged/hands-on-tutorials),云计算系列

## 立即构建和部署基于 Python 的无服务器 REST API

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8b43d965db41188ac8858418d7345172.png)

图片作者。由 [Pixabay](https://www.canva.com/p/pixabay/) 通过 [Canva](https://www.canva.com/media/MADQ4_ajPZc) 生成的原始图像

我最近偶然发现了 AWS Chalice,并被它提供的简单性和可用性迷住了。AWS Chalice 是一个无服务器框架,允许您使用 Python 构建无服务器应用程序,并使用 Amazon API Gateway 和 AWS Lambda 将它们部署在 AWS 上。

我决定尝试一下,并在几分钟之内在 AWS 上创建和部署了一个示例 REST API。在本文中,我将带您了解构建和部署一个无服务器应用程序所需的步骤,该应用程序使用 AWS Chalice 从 Google News 获取最新新闻。

# 先决条件

本教程需要一个 AWS 帐户。如果你还没有,那么[创建一个](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)。我们的应用程序将只使用自由层资源,因此成本应该不是问题。您还需要配置安全性,并为您的访问创建用户和角色。

# 配置 AWS 凭据

Chalice 在幕后使用 AWS 命令行界面(CLI)来部署项目。如果您以前没有使用过 AWS CLI 来处理 AWS 资源,您可以按照这里的指南[安装它](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)。

安装完成后,您需要[配置](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html)您的 AWS CLI,以使用来自您的 AWS 帐户的凭证。

```
$ aws configure                       
AWS Access Key ID [****************OI3G]:
AWS Secret Access Key [****************weRu]:
Default region name [us-west-2]:
Default output format [None]:
```

# 安装圣杯

接下来,你需要安装圣杯。在本教程中,我们将使用 Python 3,但是您可以使用 AWS Lambda 支持的任何 Python 版本。

## 验证 Python 安装

```
$ python3 --version
Python 3.8.6
```

## 安装圣杯

```
$ python3 -m pip install chalice
```

## 验证圣杯安装

```
$ chalice --version
chalice 1.20.0, python 3.8.6, darwin 19.6.0
```

# 创建项目

接下来,运行`chalice`命令创建一个新项目:

```
$ chalice new-project daily-news
```

这将在当前目录下创建一个`daily-news`文件夹。你可以看到 Chalice 在这个文件夹中创建了几个文件。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a2faefcfc58eb71754c51833382a7977.png)

作者图片

让我们看看`app.py`文件:

`new-project`命令创建了一个定义单一视图的示例应用程序,`/`在被调用时返回 JSON 主体`{"hello": "world"}`。您现在可以修改这个模板并添加更多代码来阅读来自 Google 的新闻。

我们将使用 Google 的 RSS 提要,并且需要一个名为 Beautiful Soup 的 Python 库来解析 XML 数据。您可以使用`pip`安装 Beautiful Soup 及其 XML 解析库。

```
$ python3 -m pip install bs4
$ python3 -m pip install lxml
```

接下来将下面的导入添加到`app.py`。这实际上增加了从`urllib`进行 HTTP 调用的导入和从`bs4`解析 XML 的导入。

接下来,您需要添加一个方法来从 Google 获取 RSS 提要,解析它以提取新闻标题和发布日期,并创建一个新闻条目列表。为此,将以下代码添加到您的`app.py`中

更新`app.py`中的 index 方法来调用它并返回新闻条目列表作为结果。

请注意,您安装了一些依赖项来使代码工作。这些依赖项是本地安装的,在运行时对 AWS Lambda 容器不可用。为了使它们对 AWS Lambda 可用,您需要将它们与您的代码打包在一起。为此,将以下内容添加到`requirements.txt`文件中。在构建期间,Chalice 将这些依赖项打包成代码的一部分,并作为 Lambda 函数的一部分上传。

# 部署项目

让我们部署这个应用程序。从`daily-news`文件夹中,运行`chalice deploy`命令。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/65dff192010e1eb38f29782ff7dc50b9.png)

部署(图片由作者提供)

这将使用 Amazon API Gateway 和 AWS Lambda 在 AWS 上部署您的 API。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cbae5a4c35fa6a9e7e704dface10d458.png)

API 网关中的每日新闻 API(图片由作者提供)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e5196aade3091dad6ed869c2929125d3.png)

每日新闻-dev Lambda 函数(图片由作者提供)

您现在可以尝试访问 API 了。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f5f9bd17d170a62dd195569a593c8218.png)

调用新闻 API(图片由作者提供)

# 清理

您还可以使用`chalice delete`命令删除运行`chalice deploy`命令时创建的所有资源。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/dc9ed972434e081542bd9e59429c8024.png)

删除资源(作者图片)

# 结论

恭喜你!!您刚刚使用 Chalice 在 AWS 上部署了一个无服务器应用程序。这并不太难,是吗?

现在,您可以继续对您的`app.py`文件进行任何修改,并重新运行`chalice deploy`来重新部署您的更改。

您还可以使用 Chalice 将您的无服务器应用程序与亚马逊 S3、亚马逊 SNS、亚马逊 SQS 和其他 AWS 服务集成在一起。看看[教程](https://aws.github.io/chalice/tutorials/index.html)继续探索。

本教程的完整源代码可以在[这里](https://github.com/theawesomenayak/daily-news)找到。

# 如何使用 AWS SAM 构建无服务器应用程序

> 原文:<https://towardsdatascience.com/how-to-build-a-serverless-application-using-aws-sam-b4d595fe689f?source=collection_archive---------8----------------------->

## [动手教程](https://towardsdatascience.com/tagged/hands-on-tutorials),云计算系列

## 立即构建和部署基于 Java 的无服务器 REST API

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d7c5f0c500ac3e9b1b34e8d7f527edda.png)

图片作者。原始图像由 [Pixabay](https://www.canva.com/p/pixabay/) 通过 [Canva](https://www.canva.com/media/MADQ4_ajPZc)

在我之前的[文章](/how-to-build-a-serverless-application-using-aws-chalice-91024416d84f)中,我谈到了 AWS Chalice,以及我们如何快速构建一个基于 Python 的无服务器应用程序,并在几分钟内将其部署到 AWS 上。

虽然 Python 是一个快速而有趣的原型,但在运行大规模生产应用程序时,它可能不是许多人的首选语言。许多组织使用 Java 作为他们的主要开发语言,许多开发人员也在转向更新的语言,如 Go。

在本文中,我将带您了解构建和部署从 Google News 获取最新新闻的无服务器应用程序所需的步骤。但这一次,我们将使用 AWS 无服务器应用程序模型(SAM)和 Java 进行开发。像 Chalice 一样,AWS SAM CLI 提供了一组丰富的工具,使开发人员能够快速构建无服务器应用程序。

# 先决条件

本教程需要一个 AWS 帐户。如果你还没有,那么[创建一个](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)。我们的应用程序将只使用自由层资源,因此成本应该不是问题。

您还需要配置安全性,并为您的访问创建用户和角色。

# 如何配置 AWS 凭据

SAM 在幕后使用 AWS 命令行界面(CLI)来部署项目。如果你以前没有使用过 AWS 的 CLI 来使用 AWS 资源,你可以按照这里的指南[来安装它。](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)

安装完成后,您需要[配置](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html)您的 AWS CLI,以使用来自您的 AWS 帐户的凭证。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1d028650323410b20ab9267817849e16.png)

作者图片

# 如何安装 SAM

接下来,您需要安装 SAM。我们将在本教程中使用 Java,但是您可以使用 AWS Lambda 支持的任何语言运行时。

## 验证 Java 安装

```
$ java --versionopenjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)
```

## 安装 SAM CLI

根据您的操作系统,SAM CLI 的安装说明会有所不同。本文介绍了在 MacOS 上安装它的说明。

在 macOS 上安装 SAM CLI 的推荐方法是使用 Homebrew 软件包管理器。

确认你是否安装了自制软件。

```
$ brew --versionHomebrew/homebrew-core (git revision fe68a; last commit 2020-10-15)
Homebrew/homebrew-cask (git revision 4a2c25; last commit 2020-10-15)
```

如果没有,您可以使用以下命令安装 Homebrew。

```
$ /bin/bash -c "$(curl -fsSL [https://raw.githubusercontent.com/Homebrew/install/master/install.sh](https://raw.githubusercontent.com/Homebrew/install/master/install.sh))"
```

接下来,使用以下命令安装 SAM。

```
brew tap aws/tap
brew install aws-sam-cli
```

## 验证 SAM 安装

```
$ sam --versionSAM CLI, version 1.6.2
```

# 如何创建项目

接下来,运行`sam-init`命令创建一个新项目。

```
sam init -r java11 -d maven --app-template hello-world -n daily-news-java
```

默认情况下,SAM 会创建一个 Python 项目。因为我们想要创建一个 Java 项目,所以我们需要传递一些额外的参数。

**参数:**

*   `-r java11`:使用 Java 11 运行时
*   `-d maven`:使用 maven 作为依赖管理器
*   `--app-template hello-world`:使用 HelloWorld 快速入门模板
*   `-n daily-news-java`:我们项目的名称

这将在当前目录下创建一个`daily-news-java`文件夹。您可以看到 SAM 在这个文件夹中创建了几个文件。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/90623c0775c06257a6671be520586b24.png)

作者图片

我们来看看`App.java`文件。

`sam-init`命令创建了一个简单的 Lambda 函数,该函数在被调用时返回 JSON 主体`{"message": "hello world"}`和机器的 IP 地址。我们现在可以更改这个模板并添加更多代码来阅读来自 Google 的新闻。

现在我们来看看`template.yml`文件。

这包含了创建我们的 Amazon API 网关和 AWS Lambda 资源的 CloudFormation 模板。

Lambda 配置指定我们有一个运行在`Java 11`和`512 MB`内存上的`HelloWorldFunction` lambda。

API 网关配置定义了一个带有`/hello`路径的`GET`方法,我们将使用它来调用 API。

我们将使用 Java 的内部 HTTP 和 XML 解析库,所以我们不需要向我们的`pom.xml`文件添加任何依赖项。请注意,作为样板代码的一部分提供的默认`pom.xml`带有设置为`1.8.`的编译器源代码,我们需要将其更新为`11`,这样我们就可以使用 Java 11 中的新 HTTP 库。

按照 Java 面向对象的方式,让我们也创建一个包含新闻标题和出版日期的`NewsItem`类。

注意,我们已经覆盖了`toString`方法。这是为了创建对象的 JSON 表示,避免使用任何 JSON 解析库。

接下来,您需要添加一个方法来从 Google 获取 RSS 提要,解析它以提取新闻标题和发布日期,并创建一个新闻条目列表。为此,将以下代码添加到您的`App.java`

现在让我们更新`App.java`中的`handleRequest`方法来调用这个方法并返回新闻条目列表作为结果。

不要忘记更新单元测试。编写它们是为了测试响应中是否存在“hello world ”,它们将在我们更改后开始失败。

# 如何构建

从`daily-news-java`文件夹中,运行`sam build`命令。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/74114e7e91f972d677d18e9478a16d84.png)

作者图片

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

# 如何在本地测试

这是萨姆最精彩的部分。您可以在本地部署和测试您的应用程序!!在开发阶段,当您想测试代码而不必将它部署到 AWS 时,这非常有用。

SAM CLI 提供了`sam local`命令来本地运行您的应用程序。这在内部使用 Docker 来模拟 Lambda 的执行环境。如果没有安装 Docker,可以从[这里](https://docs.docker.com/get-docker/)获取。

我们可以用两种方式在本地测试我们的应用程序:

*   本地托管 API
*   直接调用 Lambda 函数

让我们来看看这两个选项。

## 本地托管

使用以下命令在本地启动 API。

```
sam local start-api
```

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

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ec163322c0e79dba518cdd319856f0b8.png)

作者图片

一旦 Docker 容器被加载,您就可以访问`localhost`上的 api。

```
curl [http://127.0.0.1:3000/hello](http://127.0.0.1:3000/hello)
```

## 直接调用

使用以下命令调用 Lambda 函数。

```
sam local invoke "HelloWorldFunction" -e events/event.json
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b63222fd56f6dbecf3640dc34ee70366.png)

作者图片

这直接调用 Lambda 函数(就像我们调用`main`方法一样)并将`event.json`文件作为有效载荷传递。

# 如何部署项目

让我们部署应用程序。从`daily-news-java`文件夹中,运行`sam deploy --guided`命令。遵循提示并提供所需的输入(或按 Enter 键接受默认值)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/88103a78b97a7cdda8a46be3fd1c92d4.png)

作者图片

这将使用 Amazon API Gateway 和 AWS Lambda 在 AWS 上部署我们的应用程序。它采用我们用`sam build`命令构建的部署工件,打包并上传到由 AWS SAM CLI 创建的亚马逊 S3 桶,并使用 AWS CloudFormation 部署应用程序。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2b8ad964e0be372f90447e09161a5b08.png)

作者图片

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/53f2cab74b610bdc4c98523c0f72b3c3.png)

API 网关中的每日新闻 API(图片由作者提供)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2ebe0529c56ba0ea35b68e7b4bec8774.png)

每日新闻 Lambda 函数(图片由作者提供)

我们现在可以尝试使用上面提供的端点 URL 来访问 API。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bbf668ee010014557f7c8e296144449e.png)

作者图片

# 如何清理资源

我们可以使用`aws cloudformation delete-stack` 命令删除 AWS CloudFormation 堆栈以及我们运行`sam deploy`命令时创建的所有资源。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f8efa5f9593d93f03011f6ee8439727a.png)

作者图片

# 结论

恭喜你!!您刚刚使用 AWS SAM 在 AWS 上部署了一个无服务器应用程序。它确实比之前的多做了一点工作,但也不太难。

现在,您可以继续对您的`App.java`文件进行任何修改,并重新运行`sam deploy`来重新部署您的更改。

本教程的完整源代码可以在[这里](https://github.com/theawesomenayak/daily-news-java)找到。

# 如何用 Python 构建一个简单的机器学习 Web 应用

> 原文:<https://towardsdatascience.com/how-to-build-a-simple-machine-learning-web-app-in-python-68a45a0e0291?source=collection_archive---------0----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/10b2570b0c05420d66115aad5694576d.png)

## [数据科学](https://towardsdatascience.com/tagged/data-science/)

## 第 2 部分:不到 50 行代码的 ML 支持的 Web 应用程序

在本文中,我将向您展示如何使用 streamlit 库在不到 50 行代码中用 Python 构建一个简单的基于机器学习的数据科学 web 应用程序。

*(快速提示:你可能还想看看这个 streamlit 教程系列的第一部分*[](/how-to-build-a-data-science-web-app-in-python-61d1bed65020)**来构建你的第一个 web 应用。大喊到* [*西门*](https://medium.com/@smutama) *为提示提及第 1 部分。)**

*数据科学生命周期本质上由数据收集、数据清理、探索性数据分析、模型构建和模型部署组成。如需了解更多信息,请查看 [Ken Jee](https://www.youtube.com/channel/UCiT9RITQ9PW6BhXK0y2jaeg) 关于 [*不同数据科学角色的精彩视频(由数据科学家)*](https://www.youtube.com/watch?v=BZFfNwj7JhE) 。此生命周期的摘要信息图如下所示:*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8abbf4404cc18483a2bbe0a4382343ce.png)*

*数据科学生命周期。由 Chanin Nantasenamat 绘制。*

*作为一名数据科学家或机器学习工程师,能够部署我们的数据科学项目极其重要,因为这将有助于完成数据科学生命周期。使用 Django 或 Flask 等已建立框架的机器学习模型的传统部署可能是一项艰巨和/或耗时的任务。*

*这篇文章基于我在[数据教授 YouTube 频道](https://www.youtube.com/dataprofessor?sub_confirmation=1) ( [如何用 Python](https://www.youtube.com/watch?v=8M20LyCZDOY) 构建一个简单的机器学习 Web 应用)上制作的同一主题的视频,你可以边看边看这篇文章。*

# *鸢尾花预测应用概述*

*今天,我们将构建一个简单的基于机器学习的 web 应用程序,用于预测鸢尾花的分类标签,如 setosa、versicolor 和 virginica。*

*或许,你已经在教程和机器学习的例子中看到过太多臭名昭著的 Iris 数据集的使用。在这一点上请原谅我,因为 Iris 数据集仅用作一种" *lorem ipsum"* (通常用作书写内容中的填充词)。我向您保证,在本系列教程的后续部分中,我将使用其他示例数据集。*

*这将需要使用三个 Python 库,即`streamlit`、`pandas`和`scikit-learn`。*

*让我们来看看应用程序的概念流程,它将包括两个主要组件:(1)前端和(2)后端。*

*在 ***前端*** 中,左侧的侧边栏将接受与鸢尾花的特征相关的输入参数(*即*花瓣长度、花瓣宽度、萼片长度和萼片宽度)。这些特征将被传递到后端,在后端,经过训练的模型将根据输入参数来预测分类标签。预测结果送回前端显示。*

*在 ***后端*** 中,用户输入的参数将被保存到一个数据帧中,该数据帧将被用作测试数据。同时,将使用来自`scikit-learn`库中的随机森林算法构建分类模型。最后,该模型将被应用于对用户输入数据进行预测,并将预测的类别标签作为三种花类型之一返回:setosa、versicolor 或 virginica。此外,还将提供预测概率,这将允许我们辨别预测类标签中的相对置信度。*

# *安装必备库*

*在本教程中,我们将使用三个 Python 库,即`streamlit`、`pandas`和`scikit-learn`。您可以通过`pip install`命令安装这些库。*

*要安装 streamlit:*

```
*pip install streamlit*
```

*要安装熊猫:*

```
*pip install pandas*
```

*要安装 scikit-learn:*

```
*pip install -U scikit-learn*
```

# *web 应用程序的代码*

*好的,让我们看一下幕后,我们会看到我们今天要构建的应用程序不到 50 行代码(*即*或确切地说是 48 行)。如果我们删除空行和注释(*即*占 12 行),我们可以把数字减少到 36 行。*

# *对代码的逐行解释*

*好的,那么让我们解码,看看每一行(或代码块)在做什么。*

## *导入库*

*   ****第 1–4 行***
    分别导入别名为`st`和`pd`的`streamlit`和`pandas`库。具体来说,从 scikit-learn 库(`sklearn`)导入`datasets`包,我们随后将利用 loader 函数加载 Iris 数据集(第 30 行)。最后,我们将专门从`sklearn.ensemble`包中导入`RandomForestClassifier()`函数。*

## **侧面板**

*   ****第 11 行***
    我们将使用`st.sidebar.header()`函数添加侧边栏的标题文本。注意在`st`和`header`之间使用`sidebar`(*即*因此`st.sidebar.header()`函数)告诉 streamlit 您想要将标题放在侧边栏面板中。*
*   ***值得注意的是,每个输入参数将通过滑块按钮接受用户指定的值,如`st.sidebar.slider(‘Sepal length’, 4.3, 7.9, 5.4)`中的萼片长度。四个输入参数中的第一个对应于将在滑动按钮上方指定的标签文本,在我们的例子中是`‘Sepal length’`,而接下来的两个值对应于滑动条的最小值和最大值。最后,最后一个输入参数表示加载 web 应用程序时将选择的默认值,该值设置为 5.4。***

## *模型结构*

*   ****第 25 行***
    如前所述,数据帧形式的综合用户输入参数信息将被赋给`df`变量。*
*   ****第 30–38 行***
    该代码块属于实际的模型构建阶段。
    * *第 30 行—* 从`sklearn.datasets`包加载 Iris 数据集,并将其赋给`iris`变量。
    * *第 31 行—* 创建包含`iris.data`中提供的 4 个花特征(**萼片长度、萼片宽度、花瓣长度和花瓣宽度)的`X`变量。
    * *第 32 行—* 创建与`iris.target`中提供的虹膜类标签相关的`Y`变量。
    * *第 34 行—* 将随机森林分类器,尤其是`RandomForestClassifier()`函数,分配给`clf`变量。
    * *第 35 行—* 使用`X`和`Y`变量作为输入参数,通过`clf.fit()`函数训练模型。这实质上意味着将通过使用 4 个花特征(`X`)和类别标签(`Y`)来训练分类模型来构建分类模型。*

## *主面板*

*   ******第 27–28 行*** 第一部分将被赋予`‘User Input parameters’`的副标题文本(通过使用`st.subheader function`分配)。在下一行中,我们将通过使用`st.write()`函数显示`df`数据框的内容。***
*   ******第 40–41 行***
    在主面板的第二部分,打印出类别标签(** setosa、versicolor 和 virginica)及其相应的索引号(** 0、1 和 2)。***
*   ******第 43–44 行***
    预测类标签显示在主面板的第三部分。这里应该注意的是,`prediction`变量(第 45 行)的内容是预测的类别索引号,对于要显示的类别标签(** setosa、versicolor 和 virginica),我们需要使用`prediction`变量作为`iris.target_names[prediction]`括号内的参数。***
*   ******第 47–48 行***
    在主面板的第四个也是最后一个部分,显示预测概率。该值允许我们辨别预测类别标签的相对置信度(**概率值越高,我们对该预测的置信度越高)。***

# ***运行 web 应用程序***

***因此,web 应用程序的代码保存在 iris-ml-app.py 文件中,现在我们可以运行它了。您可以通过在命令提示符(终端窗口)中键入以下命令来运行该应用程序:***

```
***streamlit run iris-ml-app.py***
```

***之后,您应该会看到以下消息:***

```
***> streamlit run iris-ml-app.pyYou can now view your Streamlit app in your browser.Local URL: [http://localhost:8501](http://localhost:8501/)
Network URL: http://10.0.0.11:8501***
```

***几秒钟后,应会弹出一个互联网浏览器窗口,并通过将您带到如下所示的`[http://localhost:8501](http://localhost:8501./)`来引导您找到创建的 web 应用程序。***

***![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f151820c1a8b5eba6d6cf7d469eee442.png)***

***鸢尾花预测 App 截图。单击左上角的按钮(顶部窗口),我们将看到侧面板将被显示(底部窗口)。***

# ***恭喜你!您已经用 Python 创建了 ML 驱动的 web 应用程序!***

***现在,是时候表扬一下自己了,因为你已经创建了一个基于机器学习的 web 应用程序。现在是时候在您的数据科学产品组合和网站中展示这一点了(**您可能希望通过使用您感兴趣的数据集来定制 web 应用程序)。请务必查看这些关于指针和建议的视频([使用 GitHub 建立您的数据科学组合](https://www.youtube.com/watch?v=fCXBaEnPzgo)和[如何使用 Hugo & Github Pages 建立数据科学组合网站【壮举。【数据教授】](https://www.youtube.com/watch?v=mEZ1Hj5yQ-8))。***

## ***订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!***

# ***关于我***

***我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名[数据教授](http://bit.ly/dataprofessor/))制作关于数据科学的在线视频。在我制作的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本([数据教授 GitHub 页面](https://github.com/dataprofessor/))。***

***[](https://www.youtube.com/dataprofessor?sub_confirmation=1) [## 数据教授

### 数据科学、机器学习、生物信息学、研究和教学是我的激情所在。数据教授 YouTube…

www.youtube.com](https://www.youtube.com/dataprofessor?sub_confirmation=1) 

## 在社交网络上与我联系

✅YouTube:[http://youtube.com/dataprofessor/](http://youtube.com/dataprofessor/)
♇网站:[http://dataprofessor.org/](https://www.youtube.com/redirect?redir_token=w4MajL6v6Oi_kOAZNbMprRRJrvJ8MTU5MjI5NjQzN0AxNTkyMjEwMDM3&q=http%3A%2F%2Fdataprofessor.org%2F&event=video_description&v=ZZ4B0QUHuNc)(在建)
♇LinkedIn:[https://www.linkedin.com/company/dataprofessor/](https://www.linkedin.com/company/dataprofessor/)
♇Twitter:[https://twitter.com/thedataprof](https://twitter.com/thedataprof)
♇Facebook:[http://facebook.com/dataprofessor/](https://www.youtube.com/redirect?redir_token=w4MajL6v6Oi_kOAZNbMprRRJrvJ8MTU5MjI5NjQzN0AxNTkyMjEwMDM3&q=http%3A%2F%2Ffacebook.com%2Fdataprofessor%2F&event=video_description&v=ZZ4B0QUHuNc)
♇github:[https://github.com/dataprofessor/](https://github.com/dataprofessor/)
♇insta gram:***

# 如何构建一个简单的网络爬虫

> 原文:<https://towardsdatascience.com/how-to-build-a-simple-web-crawler-66082fc82470?source=collection_archive---------1----------------------->

## 一步一步的指南刮出最好的全球大学排名

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c335d158292e565d24fb698ebc3ec354.png)

[图片来源](https://unsplash.com/photos/wbXdGS_D17U)

三年前,我在新加坡 NTU 大学的机构统计部门担任学生助理。

我被要求通过手动从网站上复制并粘贴到 excel 表格中来获得最佳全球大学排名。我很沮丧,因为我的眼睛累了,因为我长时间连续看着电脑屏幕。因此,我在想是否有更好的方法来做这件事。

那时,我在谷歌上搜索自动化,找到了答案——网络抓取。从那以后,我设法创建了 100 多个网络爬虫,这是我的第一个网络爬虫,我想和大家分享一下。

之前我做的是用 requests 加 BeautifulSoup 来完成任务。然而,三年后,当我再次访问同一个网站时,我发现有一种方法可以获取 JSON 数据,而且速度更快。

如果你正在考虑自动化你的无聊和重复的任务,请向我保证你会读到最后。您将学习如何创建网络爬虫,以便您可以专注于更多增值任务。

在这篇文章中,我想分享我如何建立一个简单的爬虫来抓取 usnews.com 大学的排名。

# 检查网站

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c9a82bf92c5a5ce90be0830facb0598a.png)

当你想抓取[网站](https://www.usnews.com/education/best-global-universities/search?region=africa&subject=arts-and-humanities&name=)时,首先要做的是检查 web 元素。为什么我们需要这样做?

这实际上是为了发现是否存在更可靠的方法来获取数据或获得更清晰的数据。对于前者,我这次没有深究去挖掘 API。然而,我确实找到了提取更干净数据的方法,这样我就可以**减少数据清理时间**。

如果您不知道如何检查 web 元素,您只需导航到网页的任意位置,右键单击,单击检查,然后单击网络选项卡。之后,刷新您的页面,您应该会看到一个网络活动列表逐一出现。让我们来看看我在上面的截图中使用光标选择的特定活动(即`"search?region=africa&..."`)。

之后,请参考上面截图中的紫色框,突出显示浏览器将向其发送请求的 URL,以便获得要呈现给你的数据。

嗯,我们可以通过向那个 URL 发送请求来模仿浏览器的行为,并获得我们需要的数据,对吗?但是在这之前,为什么我选择调用请求网址而不是原来的网站网址?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1ff25cbf4920a97d1aa239723d08168c.png)

让我们点击预览选项卡,你会注意到我们需要的所有信息,包括**大学排名****地址****国家等..**都在蓝色框中突出显示的结果字段中。

这就是我们勉强通过网址的原因。URL 返回的数据是一种非常好的格式——JSON 格式。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/79f3e745ff8c82e8e2d68537439bdf02.png)

上面的截图显示了今天和 3 年前的代码对比。3 年前,当我还是一个网络抓取新手时,我只是使用请求、漂亮的页面、大量的 XPATH 和繁重的数据清理过程来获取我需要的数据。然而,如果你比较我今天写的代码,我只需要使用 httpx 来获取数据,不需要清理数据。

供您参考,httpx 是建立在请求之上的,但是它支持额外的功能,比如提供异步 API,使用 httpx,您可以发送 HTTP/2 请求。更完整的对比,你可以参考[这篇文章](https://medium.com/@factoryhr/http-2-the-difference-between-http-1-1-benefits-and-how-to-use-it-38094fa0e95b)。

**请求网址:**

[https://www . us news . com/education/best-global-university/search?区域=非洲&主题=农业科学&格式=json](https://www.usnews.com/education/best-global-universities/search?region=africa&subject=agricultural-sciences&format=json)

所以现在,让我们来关注一下如上图所示我们将要使用的链接。您会注意到,您可以更改 region 和 subject 的值,因为它们是 URL 的参数。(关于 URL 参数的更多信息,这里的[是一个很好的阅读)但是,请注意,它们的值仅限于网站提供的区域和主题。](https://www.searchenginejournal.com/technical-seo/url-parameter-handling/#close)

例如,您可以将**地区=非洲**改为**地区=亚洲**或者**科目=农业科学**改为**科目=化学。**如果你有兴趣了解支持的地区和题材有哪些,可以访问[我的回购](https://github.com/M140042/us_news)了解一下。

在了解了如何查询这个 URL 来获取你需要的数据之后,剩下的部分就是对于一个特定的地区和主题的组合,你需要查询多少个页面。

那么,我们就以[这个网址](https://www.usnews.com/education/best-global-universities/search?region=africa&subject=agricultural-sciences&format=json)为例,将网址复制粘贴到你的浏览器中并回车,然后用`command+f`搜索关键词“last_page”,你会发现类似如下的截图。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/37cf585a06e799b68e8e3d1268abf090.png)

*请注意,我已经安装了一个 [chrome 扩展](https://chrome.google.com/webstore/detail/json-formatter/bcjindcccaagfpapjjmafapmmgkkhgoa),它可以帮助我将普通数据美化成 JSON 格式。这就是为什么您可以看到我的浏览器中显示的数据打印得很好。

恭喜你,你成功找到了如上所示的 last_page 变量。现在,剩下的唯一过程是,如果 last_page 大于 1,如何转到下一页并获取数据。

下面是我如何找到导航到第 2 页的方法。以[这个环节](https://www.usnews.com/education/best-global-universities/search?region=asia&subject=agricultural-sciences)为例。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9a7daf341bd3b02b5bd3210513da4396.png)

首先,点选页码 2,然后检视右边的面板。请注意紫色的框,您会注意到在请求 URL 中添加了 page=2。这意味着您只需要将`&page={page_number}`附加到原始请求 URL 上,以便在不同的页面间导航。

现在,您已经对如何创建一个 web scraper 来从网站获取数据有了一个整体的想法。

如果你想看完整的 Python 代码,请随意访问这里的。

# 最终想法

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6de67412d83c7b18815dc322b22b03b3.png)

[图像来源](https://unsplash.com/photos/4K2lIP0zc_k)

非常感谢你一直读到最后。

以下是我想让你看完这篇文章后得到的收获。

1.  知道有许多不同的方法可以从网站上抓取数据,例如获取 JSON 格式的数据链接。
2.  花一些时间检查网站,如果你设法找到检索数据的 API,这可以节省你很多时间。

我之所以将我三年前写的代码和我今天写的代码进行比较,是为了让你知道如何通过不断的练习来提高你的网页抓取和编码技能。

努力吧,结果一定会来的。——低伟鸿

如果你有任何问题或想法要问或补充,欢迎在下面评论!

# 关于作者

[Low 魏宏](https://www.linkedin.com/in/lowweihong/?source=post_page---------------------------)是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。

他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问[这个网站](https://www.thedataknight.com/)查看他的作品集,也可以联系他获取**的抓取服务**。

你可以在 [LinkedIn](https://www.linkedin.com/in/lowweihong/?source=post_page---------------------------) 和 [Medium](https://medium.com/@lowweihong?source=post_page---------------------------) 上和他联系。

[](https://medium.com/@lowweihong?source=post_page-----6bef8cb1477a----------------------) [## ●伟鸿-中等

### 在媒体上阅读低纬鸿的作品。数据科学家|网络抓取服务:https://www.thedataknight.com/.每…

medium.com](https://medium.com/@lowweihong?source=post_page-----6bef8cb1477a----------------------)

# 如何构建智能搜索引擎(下)

> 原文:<https://towardsdatascience.com/how-to-build-a-smart-search-engine-a86fca0d0795?source=collection_archive---------2----------------------->

## 用 Python 创建智能搜索服务

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ff376dcadf11b0f4e9de6044960253c0.png)

*作者所有图片*

[在本系列的第一篇文章](/how-to-build-a-search-engine-9f8ffa405eac)中,我们只用了几行代码就构建了一个搜索引擎,该引擎采用了当今许多大型企业搜索引擎中使用的 BM25 算法。

在这篇文章中,我们想超越这一点,并**创造一个真正智能的搜索引擎**。这篇文章将描述这样做的过程,并提供在任何数据集上实现这一点的**模板代码。**

但是我们所说的“聪明”是什么意思呢?我们将它定义为一个能够:

*   向用户返回相关结果,即使他们没有在这些结果中搜索特定的单词。
*   注意位置;了解英国邮政编码和英国城镇的地理关系。
*   能够扩展到更大的数据集(我们将迁移到一个更大的数据集,而不是上一个示例中的 212k 记录,但是我们需要能够扩展到更大的数据)。
*   比我们上次的实施快几个数量级,甚至在搜索大型数据集时也是如此。
*   以明智的方式处理拼写错误、打字错误和以前“看不见”的单词。

为了实现这一点,我们需要结合多种技术:

*   快速文本单词向量。我们将在我们的数据集上训练一个模型来创建单词的向量表示(更多信息[在这里](/supercharging-word-vectors-be80ee5513d))。
*   BM25。我们仍将使用这种算法来支持我们的搜索,但我们需要将它应用到我们的词向量结果中。
*   使用轻量级和高效的[非度量空间库(NMSLIB)](https://github.com/nmslib/nmslib) 超快速搜索我们的结果。

这将看起来像下面这样:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/964ff59472cdef7a40c664f2f7a3e180.png)

我们将在本帖中创建的管道概述

本文将逐一介绍这些领域,并描述如何将它们结合起来创建一个智能搜索引擎。

## **1。设置;预处理和标记文本**

创建搜索引擎的第一步是将我们的文档分割成单独的单词或“记号”。spaCy 库使这变得非常简单和快速。提醒一下,我们在本文中使用的例子与上一篇文章中的例子相同。它包含发布在 [Contracts Finder](https://www.contractsfinder.service.gov.uk/Search) 平台上的英国公共部门合同通知。但是,出于本练习的目的,我们增加了数据集的大小(现在是 212k 记录,以前只有 50k)。除此之外,我们还将位置数据引入了我们的数据集。在进行任何处理之前,我们使用的数据框如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/acf03e9853a5ae796f8d412f3f36a0ce.png)

数据集的一些示例记录(总共 212k 记录)

我们将在搜索引擎中使用的列是“文本”列,它是每个通知的自由文本和位置字段的合并。

我们可以使用 spaCy 库,对这个列进行清理和标记。以下代码通过使用 spaCy 管道来实现这一点,这使得处理尽可能高效,并且还允许我们仅选择我们想要使用的令牌化器引擎的部分(再次确保该过程尽可能快):

上面的代码将我们的文档分割成一个令牌列表,同时执行一些基本的清理操作,删除标点符号、空白并将文本转换为小写。在 Colab 笔记本上运行,每秒钟可以处理 1800 多个通知。

## **2。创建单词向量;建立一个快速文本模型**

***为什么字矢?为什么不是伯特/GPT-3/[最新的 SOTA NLP 模型]?***

自从引入像 BERT 这样复杂的变压器模型以来,单词向量模型似乎已经过时了。然而,由于以下原因,它们今天仍然具有相关性:

*   与 transformer 模型相比,它们在创建可伸缩服务的所有重要方面(模型大小、训练时间、推理速度)都是“轻量级”的。
*   由于上述原因,他们可以在特定领域的文本上从头开始训练。除此之外,它们可以在相对较小的数据集上被训练(即,数千个文档,而不是通常用于训练变压器模型的数百万个文档)。
*   它们更容易解释,因为单词向量将保持一致,并且不会根据周围文本的上下文而改变(这既是优点也是缺点,稍后将详细介绍)。

除此之外,使用 Gensim 库实现它们非常简单。这里我们正在构建一个快速文本模型:

***回顾绩效:***

现在我们已经训练好了我们的模型,让我们看看它的表现如何。

fastText 在捕获语料库中单词之间的关系方面的有效性一直让我感到惊讶。有几个例子可以很好地说明这一点:

**与‘M4’最相似的单词:**

```
ft_model.wv.most_similar("m4", topn=20, restrict_vocab=5000)
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/97add396fc1319bdf6d3c482f81f51b5.png)

与“m4”最相似的单词。该模型理解与英国高速公路命名的联系。分数越高,相似性越大

这真的令人震惊,该模型已经清楚地了解到 M4 与英国高速公路相关,并理解其他大型英国高速公路与此类似(M1、M5、M3、M60)。

它还了解到,LRN 也密切相关(这代表当地的道路网络)我甚至不知道这一点!

“9AT”标记看起来很奇怪,但是快速搜索就会发现这是英国高速公路的邮政编码。

在单词向量模型中包含邮政编码和位置信息是经过深思熟虑的设计选择。基本原理是该模型将理解英国邮政编码和位置如何相互关联。让我们来测试一下:

**与‘约克郡’最相似的单词:**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5d9bb114afd5eae7d0a0ed27e1868a05.png)

与“Yorkshire”最接近的单词的相似性得分越高,表示相似性越大

该模型了解到约克郡是英国的一个地区(位于西北部)以及其中的主要城镇。它还理解该区域和其子区域之间的关系;这里的“骑马”指的是约克郡境内的北/东/西骑马。但是邮政编码呢?

**与‘RG9’最相似的词:**

RG9 是英国境内与亨利镇相关的邮政编码。这是一个棘手的例子,因为亨利是一个很小的城镇,RG 邮政编码也用于附近其他更大的城镇(如雷丁)。该模型能够正确地将此邮政编码与 Henley 关联起来吗?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/35d5e1b7a2debfe5a028b0b6d75bd2ed.png)

该模型知道 RG9 邮政编码与亨利镇相关

它出色地通过了!Henley 是最相似的单词,其他结果也高度相关,代表邻近的城镇和邮政编码。

显然,我们的词向量模型表现良好,在下一步中,我们将使用 BM25 算法来增强我们的词嵌入。

## **3。将 BM25 应用于单词向量**

现在我们有了单词向量,我们需要找到一种方法,在搜索引擎中为每个文档组合这些向量。

最简单的方法是对每个文档的单词向量进行平均(这是可行的),但是已经证明将单词向量与 BM25 算法相结合可以产生更高质量的搜索结果[1]

下面是 BM25 的简单回顾,但是请回顾我的第一篇文章,以获得更多关于其内部工作的细节:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/95eb77279a8019b946021ecc8366ec1e.png)

BM25 内部运作的回顾

虽然这看起来很复杂,但用我们的单词 vectors 实现它实际上非常简单,只需要几行代码(就像本文中的所有其他步骤一样!)

将我们的单词向量转换成使用 BM25 加权的文档向量

这个输出将为我们的搜索引擎中的每个文档提供一个向量。

## **4。使用 NMSLIB** 创建超快速搜索索引

我们现在已经有了数据集中每个文档的向量列表。我们还可以使用上面概述的技术为用户的搜索查询创建一个向量。

但是我们如何根据这个搜索查询返回相关的结果呢?我们需要能够找到与我们的搜索向量最近的向量。鉴于我们的向量中有大量的维度(100 ),这是我们的方法可能开始失败的地方。搜索引擎需要很快,在超过 20 万条记录的数据集中搜索超过 100 个维度是非常耗费资源的。

**NMS lib:**

令人欣慰的是,这是计算机科学中一个相当普遍的挑战,并且已经有解决方案来大规模加速相似性搜索问题。NMSLIB 是最快的解决方案之一[2]。使用这个库,我们可以创建一个搜索索引,这将比使用暴力方法查找相似向量快几个数量级:

## 将所有这些放在一起;更智能的搜索引擎:

现在我们有了搜索索引,只需创建一个搜索向量并从索引中返回最接近的匹配项:

使用与我们上一篇文章中相同的查询 ***【洪水防御】*** ,我们现在得到以下结果(前 5 名):

```
Searched 212,447 records in 0.0005 seconds:Q3172 PROPERTY FLOOD MITIGATION SCHEME WASH GREEN, WIRKSWORTH, DERBYSHIRE SUPPLY AND INSTALL CERTIFIED FLOOD PROTECTION PRODUCTS INCLUDING  FLOOD DOORS, FLOOD BARRIERS, AIR BRICKS AND OTHER WORKS IDENTIFIED IN THE PROPERTY LEVEL FLOOD PROTECTION SURVEY REPORTS, AS WELL AS SKIMMER PUMPS AND HOSES. Matlock DE4 3AG WHIMPLE FLOOD DEFENCE IMPROVEMENTS CONSULTANCY SERVICES FOR PREPARATION OF CONTRACT FOR CONSTRUCTION OF FLOOD ALLEVIATION SCHEME. Sidmouth EX10 8HL FLOOD RISK ASSESSMENT FLOOD RISK ASSESSMENT Woolwich SE186HQ PAPERMILL DYKE FLOOD DEFENCE WALL CONSTRUCTION OF FLOOD DEFENCE Doncaster DN1 3BU MVDC - JS - LEVEL 2 STRATEGIC FLOOD RISK ASSESSMENT LEVEL 2 STRATEGIC FLOOD RISK ASSESSMENT TO SUPPORT PREPARATION OF THE FUTURE MOLE VALLEY LOCAL PLAN Surrey RH4 1SJ
```

一些伟大的成果。此外,搜索在 0.0005 秒内完成。这比我们之前的搜索引擎快了 122 倍,尽管数据集的大小超过了 4 倍。

同样值得强调的是,许多结果虽然高度相关,但并不包含“防御”一词。使用单词向量的方法意味着现在不再需要精确的单词匹配来返回相关的结果。

考虑到地理信息也应该在搜索索引中进行编码,让我们尝试搜索一个在特定区域授予的合同。为此,我们将使用 NR2 邮政编码进行搜索,以查找诺里奇的通知: ***“审计服务 NR2”。*** 以下是前 3 名的结果:

```
Searched 212,447 records in 0.0004 secondsPROVISION OF EXTERNAL AUDIT SERVICES THE CONTRACT IS A SINGLE LOT FOR THE PROVISION OF EXTERNAL AUDIT SERVICES. Norwich NR4 6TJGB-NORWICH: EXTERNAL AUDIT ANNUAL AUDIT OF TRUST FINANCIAL & QUALITY ACCOUNTS AND ANNUAL REPORT. Norwich NR6 5BEGB-NORWICH: 18-022 - INTERNAL AUDIT SERVICES BROADLAND HOUSING GROUP WISHES TO ENTER INTO A CONTRACT FOR INTERNAL AUDITING. Norwich NR1 1HU
```

有用!返回诺里奇的内部和外部审计服务的所有结果,请注意,即使我们使用 NR2 邮政编码进行搜索,它也知道这与其他诺里奇的 NR4、NR6 和 NR1 邮政编码类似……非常聪明!

最后,让我们输入一个错别字,看看它是否还能以智能的方式处理这个问题。 ***《审计服务在诺维奇》:***

```
Searched 212447 records in 0.0005 secondsPROVISION OF EXTERNAL AUDIT SERVICES THE CONTRACT IS A SINGLE LOT FOR THE PROVISION OF EXTERNAL AUDIT SERVICES. Norwich NR4 6TJGB-NORWICH: EXTERNAL AUDIT ANNUAL AUDIT OF TRUST FINANCIAL & QUALITY ACCOUNTS AND ANNUAL REPORT. Norwich NR6 5BEGB-NORWICH: 18-022 - INTERNAL AUDIT SERVICES BROADLAND HOUSING GROUP WISHES TO ENTER INTO A CONTRACT FOR INTERNAL AUDITING. Norwich NR1 1HU 0.13
```

同样的结果再次出现,尽管城镇名称拼写错误。

## **总之:**

在这篇文章中,我们已经看到了如何将单词向量与 BM25 结合起来,并通过快速相似性搜索索引对其进行增压,从而创建一个智能的、可伸缩的和高性能的搜索引擎。

尽管如此,考虑这是否对最终用户有益总是很重要的。例如,我们可能会发现用户更喜欢简单的关键字搜索,因为他们可以很容易地解释结果。这也凸显了创造“更智能”服务的最大风险之一;它们通常会变成:

*   不太容易预测,
*   学习搜索数据中存在的偏见;
*   由于复杂性的增加,调试会更加困难。

由于这些原因,它们需要大量的测试,以确保一旦投入生产,它们就能按预期运行。

随着搜索变得越来越复杂,随着时间的推移,我们无疑会看到更复杂的解决方案出现。[看到这一领域如此快速的发展是一件好事,但同样重要的是要记住,通常最简单的问题解决方案是最好的。](https://en.wikipedia.org/wiki/Occam%27s_razor)

## [笔记本包含数据和代码](https://colab.research.google.com/drive/10ZrZaLBmhEqKSSEoe_cos783m2junUdr?usp=sharing)

[](https://colab.research.google.com/drive/10ZrZaLBmhEqKSSEoe_cos783m2junUdr?usp=sharing) [## 智能搜索

### 用 Python 创建智能搜索引擎的代码

colab.research.google.com](https://colab.research.google.com/drive/10ZrZaLBmhEqKSSEoe_cos783m2junUdr?usp=sharing) 

## **参考文献:**

[1]搜索引擎中的词嵌入,质量评测[https://ad-publications . cs . uni-freiburg . de/themes/学士 _ 埃内科 _Pinzolas_2017.pdf](https://ad-publications.cs.uni-freiburg.de/theses/Bachelor_Eneko_Pinzolas_2017.pdf)

[2]相似性搜索库的基准[https://github.com/erikbern/ann-benchmarks](https://github.com/erikbern/ann-benchmarks)

链接到本系列的第一部分:

[](/how-to-build-a-search-engine-9f8ffa405eac) [## 如何建立一个搜索引擎

### 用几行代码在 Python 中创建健壮的全文搜索

towardsdatascience.com](/how-to-build-a-search-engine-9f8ffa405eac) 

*一如既往,非常感谢 TDS 编辑团队!*

# 如何构建一个 Streamlit UI 来分析葡萄酒、虹膜和乳腺癌数据集上的不同分类器

> 原文:<https://towardsdatascience.com/how-to-build-a-streamlit-ui-to-analyze-different-classifiers-on-the-wine-iris-and-breast-cancer-25c03c482a27?source=collection_archive---------18----------------------->

## 让我们使用 Streamlit 和 sklearn 构建一个 web 应用程序

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bdad5e2b4f7e24f1535e601a97325f6a.png)

作者的屏幕截图

在本教程中,我们将使用三个数据集(虹膜、乳腺癌、葡萄酒)

我们将使用 3 种不同的模型(KNN,SVM,随机森林)进行分类,并让用户能够设置一些参数。

# 安装并导入必要的库

## 设置虚拟环境

```
pip install virtualenv  /* Install virtual environment */
virtualenv venv         /* Create a virtual environment */
venv/Scripts/activate   /* Activate the virtual environment */
```

## 安装库

安装库之前,请确保您的虚拟环境已激活

```
pip install streamlit, seaborn, scikit-learn
```

## 导入库

```
import streamlit as st
from sklearn.datasets import load_wine, load_breast_cancer, load_iris
from  sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
```

我们导入 streamlit,来自 sklearn 的数据集,来自 sklearn 的各种模型,制作我们的地块和熊猫所需的库。

# 助手功能

## 函数来获取数据集

```
def return_data(dataset):
    if dataset == 'Wine':
        data = load_wine()
    elif dataset == 'Iris':
        data = load_iris()
    else:
        data = load_breast_cancer()
    df = pd.DataFrame(data.data, columns=data.feature_names , index=None)
    df['Type'] = data.target
    X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, random_state=1, test_size=0.2)
    return X_train, X_test, y_train, y_test,df,data.target_names
```

*   该函数接受一个字符串,该字符串包含用户选择的数据集的名称
*   它加载相关的数据集
*   我们创建了一个可以在 UI 中显示的数据帧
*   我们使用 sklearn 的 **train_test_split()** 来创建训练集和测试集
*   该函数返回训练集、测试集、数据帧和目标类

## 函数返回模型

我们将使用 streamlit 的**滑块**组件从用户那里获取参数输入。

**st.sidebar.slider(label = ' ',min_value = 1,max_value = 100)** 在侧边栏中创建一个滑块。

```
def getClassifier(classifier):
    if classifier == 'SVM':
        c = st.sidebar.slider(label='Chose value of C' , min_value=0.0001, max_value=10.0)
        model = SVC(C=c)
    elif classifier == 'KNN':
        neighbors = st.sidebar.slider(label='Chose Number of Neighbors',min_value=1,max_value=20)
        model = KNeighborsClassifier(n_neighbors = neighbors)
    else:
        max_depth = st.sidebar.slider('max_depth', 2, 10)
        n_estimators = st.sidebar.slider('n_estimators', 1, 100)
        model = RandomForestClassifier(max_depth = max_depth , n_estimators= n_estimators,random_state= 1)
    return model
```

*   和前面的函数一样,这个函数接受一个参数,这个参数是一个包含模型名称的字符串。
*   基于所选的模型,我们要求用户给出参数值。
*   对于 SVM,我们将 C 参数作为用户的输入
*   对于 KNN,我们在进行预测时考虑模型的最近邻居的数量
*   对于随机森林,我们取决策树的数目和决策树的最大深度
*   然后,我们创建模型的实例并返回模型

## PCA 的功能

```
def getPCA(df):
    pca = PCA(n_components=3)
    result = pca.fit_transform(df.loc[:,df.columns != 'Type'])
    df['pca-1'] = result[:, 0]
    df['pca-2'] = result[:, 1]
    df['pca-3'] = result[:, 2]
    return df
```

我们用的是 sklearn 的 PCA。我们将 3 个组件添加到数据帧中并返回它。

# 构建用户界面

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4bb67e8a8b35611684d27e0c451255ae.png)

作者截图

```
# Title
st.title("Classifiers in Action")

# Description
st.text("Chose a Dataset and a Classifier in the sidebar. Input your values and get a prediction")

#sidebar
sideBar = st.sidebar
dataset = sideBar.selectbox('Which Dataset do you want to use?',('Wine' , 'Breast Cancer' , 'Iris'))
classifier = sideBar.selectbox('Which Classifier do you want to use?',('SVM' , 'KNN' , 'Random Forest'))
```

我们使用 streamlit 的 **selectbox** 组件创建一个下拉菜单,供用户选择数据集和模型

```
# Get Data
X_train, X_test, y_train, y_test, df , classes= return_data(dataset)
st.dataframe(df.sample(n = 5 , random_state = 1))
st.subheader("Classes")
for idx, value in enumerate(classes):
    st.text('{}: {}'.format(idx , value))
```

*   我们使用助手函数来获取数据
*   我们使用 streamlit 的 **dataframe** 组件来显示数据集的一个示例
*   我们还使用 helper 函数返回的最后一个变量来显示这些类

我们将使用 seaborn 和 matplotlib 在 2d 和 3d 中可视化 PCA。

streamlit 的 **pyplot** 组件接受一个图形作为参数,并在 UI 中显示该图形。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/615e11ce7b6767f147bcd67a06687392.png)

作者截图

```
# 2-D PCA
df = getPCA(df)
fig = plt.figure(figsize=(16,10))
sns.scatterplot(
    x="pca-1", y="pca-2",
    hue="Type",
    palette=sns.color_palette("hls", len(classes)),
    data=df,
    legend="full"
)
plt.xlabel('PCA One')
plt.ylabel('PCA Two')
plt.title("2-D PCA Visualization")
st.pyplot(fig)
```

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f9bc739ced4671801680358f96c24e9b.png)

作者截图

```
#3-D PCA
fig2 = plt.figure(figsize=(16,10)).gca(projection='3d')
fig2.scatter(
    xs=df["pca-1"],
    ys=df["pca-2"],
    zs=df["pca-3"],
    c=df["Type"],
)
fig2.set_xlabel('pca-one')
fig2.set_ylabel('pca-two')
fig2.set_zlabel('pca-three')
st.pyplot(fig2.get_figure())
```

最后,我们将对模型进行训练,并得到训练、测试的准确率分数。

```
# Train Model
model = getClassifier(classifier)
model.fit(X_train, y_train)
test_score = round(model.score(X_test, y_test), 2)
train_score = round(model.score(X_train, y_train), 2)

st.subheader('Train Score: {}'.format(train_score))
st.subheader('Test Score: {}'.format(test_score))
```

> 你已经成功地建立了一个项目,你可以展示你的投资组合👏 👏 👏

我最近用 WordPress 创建了一个博客,如果你能看看的话,我会很高兴的😃

 [## Python 项目教程-使用这些 Python 项目教程改进您的简历/作品集。

### 使用 Streamlit 共享部署您的机器学习 Web 应用程序在我以前的文章中,我谈到过构建一个…

realpythonproject.com](https://realpythonproject.com/) 

在 LinkedIn 上与我联系

[](https://www.linkedin.com/in/rahulbanerjee2699/) [## Rahul baner JEE——产品工程实习生——EY | LinkedIn

### 查看 Rahul Banerjee 在世界上最大的职业社区 LinkedIn 上的个人资料。拉胡尔有 4 个工作列在他们的…

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

在 Twitter 上与我联系

# 使用 TensorFlow.js 通用句子编码器的文本相似性

> 原文:<https://towardsdatascience.com/how-to-build-a-textual-similarity-analysis-web-app-aa3139d4fb71?source=collection_archive---------10----------------------->

## 从学者到构建相似句子分组网络应用的旅程

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cae44bcd2f3af564dc6debc0a6c4a491.png)

一些布赖顿的沐浴盒比其他的更相似。“给我看看那些红色的”[照片由 [me](https://medium.com/@jinglesnote) 拍摄]

你想知道搜索引擎是如何理解你的查询并检索相关结果的吗?聊天机器人如何从你的问题中提取你的意图,并提供最恰当的回应?

在这个故事中,我将详细介绍构建文本相似性分析 web 应用程序所需的每个部分,包括:

*   单词嵌入
*   句子嵌入
*   余弦相似性
*   构建文本相似性分析网络应用
*   结果分析

试试[文本相似性分析网络应用](https://jinglescode.github.io/demos/nlp-sentence-encoder),在下面的评论中让我知道它是如何为你工作的!

# 什么是单词嵌入?

单词嵌入**启用** **知识表示,其中向量表示单词**。这提高了神经网络从文本数据集学习的能力。

在单词嵌入成为自然语言处理的事实标准之前,处理单词的一种常见方法是使用一次性矢量化。每个单词代表向量空间中的一列,每个句子是一个由*个 1*和*个 0*组成的向量。**表示单词在句子中的存在。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4c58296db21f60e80c4b2ed30073ed55.png)

一键矢量化[摘自[文本编码:综述](/text-encoding-a-review-7c929514cccf)

结果,这导致了一个巨大而稀疏的表示,因为零*比一*多得多。当一个词汇表中有很多单词时,它会创建一个很大的单词向量。这可能会成为机器学习算法的一个问题。

一键矢量化也无法捕捉单词的含义。比如“*饮料*”和“*饮料*”,虽然这是两个不同的词,但是定义却差不多。

通过单词嵌入,语义相似的单词具有相似的向量表示。因此,当出现类似“*我想点一杯饮料*”或“*一杯饮料*”的短语时,点餐系统可以以同样的方式解释该请求。

## 过去的单词嵌入

早在 2003 年, [Yoshua Bengio 等人](http://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf)引入了语言模型概念。那篇论文的重点是学习单词的表示,这允许模型预测下一个单词。

这篇论文是至关重要的,并导致了单词嵌入的发展和发现。约舒厄与杰弗里·辛顿和扬·勒昆一起获得了图灵奖。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c0d357e3584247d059a9e4429af44b1c.png)

将单词的特征向量序列输入到单词的条件概率分布中,以预测下一个单词[图片取自[论文](http://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf)

2008 年,[罗南和杰森](https://thetalkingmachines.com/sites/default/files/2018-12/unified_nlp.pdf)研究了一个可以学习识别相似单词的神经网络。他们的发现为自然语言处理开辟了许多可能性。下表显示了单词列表以及十个最相似的单词。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0875bbf63b53efda8686f7d87c298cd1.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f0542f75fd1f2a5ad1eb496ec8b9dde0.png)

左图:给定输入句子的神经网络结构,输出类别概率。右表:选出的 5 个单词和 10 个最相似的单词。[资料来源于[论文](https://thetalkingmachines.com/sites/default/files/2018-12/unified_nlp.pdf)

2013 年, [Tomas Mikolov 等人](https://arxiv.org/pdf/1301.3781.pdf)介绍了从拥有数十亿单词的数据集学习高质量的单词向量。他们将它命名为 *Word2Vec,*它包含了词汇中的数百万个单词。

Word2Vec 从此开始流行。如今,单词嵌入层在所有流行的深度学习框架中。

## 单词嵌入示例

在谷歌预训练的 Word2Vec 模型上,他们从谷歌新闻数据集中训练了大约 1000 亿个单词。单词“**”与“**”、“**”、“*老鼠*”、“*宠物*”的意思最接近。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f417423792233b28dc070872eede8cad.png)

“**这个词在几何上更接近于“**”、“**”、“*老鼠*”、“*宠物*”。【摘自[嵌入式投影仪](http://projector.tensorflow.org/)

单词嵌入还设法识别单词之间的关系。一个经典的例子是单词之间的性别角色关系。比如,“**之于“**”就好比“**”之于“**”。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/436e5d71c4c681c2a4b00e43c5f3602a.png)

从手套无监督学习算法学习到的单词之间的有趣关系[ [图像源](https://nlp.stanford.edu/projects/glove/)

## 深入挖掘单词嵌入

加利纳·奥莱尼克在描述单词嵌入的动机方面做得非常出色。从一键编码和 TF-IDF 到手套和庞加莱。

[](/word-embeddings-exploration-explanation-and-exploitation-with-code-in-python-5dac99d5d795) [## 单词嵌入:探索、解释和利用(带 Python 代码)

### 单词嵌入讨论是每个自然语言处理科学家都在谈论的话题

towardsdatascience.com](/word-embeddings-exploration-explanation-and-exploitation-with-code-in-python-5dac99d5d795) 

这里有一篇由[迪潘然(DJ)萨卡尔](https://medium.com/u/6278d12b0682?source=post_page-----aa3139d4fb71--------------------------------)撰写的 29 分钟的关于各种语言模型的综合文章。他涵盖了 Word2Vec、GloVe 和 FastText 如果你打算研究单词嵌入,一定要看看这个。

[](/understanding-feature-engineering-part-4-deep-learning-methods-for-text-data-96c44370bbfa) [## 文本数据深度学习方法的直观实践方法— Word2Vec、GloVe 和 FastText

### 驯服非结构化文本数据的更新、高级策略

towardsdatascience.com](/understanding-feature-engineering-part-4-deep-learning-methods-for-text-data-96c44370bbfa) 

## 项目的 Word 嵌入资源

TensorFlow 在这个 [Colab 笔记本](https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/text/word_embeddings.ipynb)中提供了一个关于单词嵌入和代码的[教程](https://www.tensorflow.org/tutorials/text/word_embeddings)。您可以尝试使用这些代码,并用它来训练您在数据集上的单词嵌入。这个绝对可以帮你入门。

对于喜欢动画的人来说,在[嵌入投影仪](http://projector.tensorflow.org/)上有一个很酷的嵌入可视化。每个点代表一个单词,你可以在三维空间中可视化语义相似的单词。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a0b9d3d8e1b0795b80d3060f390cb50e.png)

一个截屏[嵌入投影仪](http://projector.tensorflow.org/)。你看到的每个点代表一个单词。

我们有单词向量来代表单词的意思;句子怎么样?

# 什么是通用句子编码器?

像单词嵌入一样,[通用句子编码器](https://arxiv.org/pdf/1803.11175.pdf)是一个通用的句子嵌入模型,它将文本转换成有语义意义的固定长度向量表示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8735956e0f15f32bcf0ef78a6a118d36.png)

通用句子编码器将文本编码成高维向量[取自 [TensorFlow Hub](https://tfhub.dev/google/universal-sentence-encoder/1)

由通用句子编码器产生的这些向量捕获丰富的语义信息。我们可以将它用于各种自然语言处理任务,训练分类器,如[分类](https://en.wikipedia.org/wiki/Sentiment_analysis)和[文本相似性分析](https://en.wikipedia.org/wiki/Semantic_similarity)。

Google 有两个通用的句子编码器模型。其中一个基于**变压器**架构,另一个基于**深度平均网络****Transformer** ,句子嵌入为每个单词创建上下文感知的表示,以生成句子嵌入。它是为更高的精度而设计的,但是编码需要更多的内存和计算时间。这对于情感分类是有用的,在情感分类中,像‘not’这样的词可以改变意思,并且能够处理像‘不错’这样的双重否定。

**深度平均网络**,单词的嵌入首先一起平均,然后通过一个前馈深度神经网络产生句子嵌入。不幸的是,通过平均向量,我们在这个过程中失去了句子的上下文和句子中的单词序列。它是为了速度和效率而设计的,牺牲了一些准确性(尤其是在讽刺和双重否定上)。一个很好的主题分类模型,将长文章分类。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c6ef255c7959ec5cb7ede0ab6637c565.png)

如果句子可以得到相同的回答,那么它们在语义上是相似的。[摘自[论文](https://arxiv.org/pdf/1804.07754.pdf)

[杨等人](https://arxiv.org/pdf/1804.07754.pdf)介绍了一种利用会话数据学习句子表征的方法。

比如,“*你多大了?*、*你多大了?*”,两个问题语义相似,一个聊天机器人可以回复同一个答案“*我 20 岁*”。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a0eaf6fa001ff16134eae4be20502c48.png)

“你好吗?”以及“你多大了?”即使有相同的单词也有 33%的相似度[ [demo](https://jinglescode.github.io/demos/nlp-sentence-encoder)

相比之下,虽然"*你好吗?*、*你多大了?*“包含相同的单词,两个句子有不同的意思。聊天机器人必须理解问题并给出适当的回答。

这是一张显示三个句子相似度的热图“*你多大了?*、*你多大了?*、*你好吗?*”。

“*你好吗?**你多大了?*“即使具有相同的单词,也具有低相似度分数。

[Logeswaran 等人](https://arxiv.org/abs/1803.02893)引入了一个从无标签数据中学习句子表征的框架。在本文中,现有方法中使用的解码器(*橙色框*)被从一组候选句子(*绿色框*)中选择目标句子的分类器所取代;它提高了问答系统的性能。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d5879ed8a79ee97d5999efcc6d03fbd8.png)

用从一组候选句子中选择目标句子的分类器代替先前方法中的解码器[摘自[论文](https://arxiv.org/pdf/1803.02893.pdf)

## 深入了解通用句子编码器

[Dipanjan (DJ) Sarkar](https://medium.com/u/6278d12b0682?source=post_page-----aa3139d4fb71--------------------------------) 解释了各种嵌入模型的发展。如果您热衷于构建文本分类器,他的文章详细介绍了在电影评论数据集上执行情感分析的每个步骤。

[](/deep-transfer-learning-for-natural-language-processing-text-classification-with-universal-1a2c69e5baa9) [## 面向自然语言处理的深度迁移学习——通用文本分类…

### 揭秘通用句子编码器指南

towardsdatascience.com](/deep-transfer-learning-for-natural-language-processing-text-classification-with-universal-1a2c69e5baa9) 

如果你好奇探索其他语言模型, [Pratik Bhavsar](https://medium.com/u/c0101388583?source=post_page-----aa3139d4fb71--------------------------------) 对比了 BERT、ELMo、USE、Siamese、InferSent 等各种语言模型的性能。学会选择正确的答案会改善你的结果。

[](https://medium.com/modern-nlp/on-variety-of-encoding-text-8b7623969d1e) [## NLP 中的各种编码器

### 文本的主特征工程

medium.com](https://medium.com/modern-nlp/on-variety-of-encoding-text-8b7623969d1e) 

## 为您的项目提供通用句子编码器资源

TensorFlow 提供了关于通用语句编码器的[教程](https://tfhub.dev/google/universal-sentence-encoder/1),预训练模型和[笔记本](https://colab.research.google.com/github/tensorflow/hub/blob/50bbebaa248cff13e82ddf0268ed1b149ef478f2/examples/colab/semantic_similarity_with_tf_hub_universal_encoder.ipynb)。如果你正在考虑构建自己的文本分类器,一定要看看这个。

有了每个句子的语义向量,我们如何衡量句子之间的相似性呢?

# 余弦相似度是什么?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8aa7e1f2f837681eb2610920914886c8.png)

Photo by [浮萍 闪电](https://unsplash.com/@vsmilelx?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)

[余弦相似度](https://en.wikipedia.org/wiki/Cosine_similarity)是通过计算**两个向量**之间的余弦角来衡量相似度。如果两个向量相似,则它们之间的角度较小,余弦相似值更接近 1。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/099a43a2a2c85d08526c1e16949cac3c.png)

给定两个向量 *A**B* ,余弦相似度 cos(θ)使用[点积](https://en.wikipedia.org/wiki/Dot_product)和[幅度](https://en.wikipedia.org/wiki/Magnitude_(mathematics)#Euclidean_vector_space)来表示【来自[维基百科](https://en.wikipedia.org/wiki/Cosine_similarity)

在这里,我们将句子输入通用句子编码器,它返回给我们句子嵌入向量。

有了向量,我们就可以得到向量之间的余弦相似性。对于每一个句子对, *A**B* ,我们可以计算出 *A**B* 向量的余弦相似度。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6f37a5168b6d58018820a84ee242564f.png)

语义相似度是衡量两个文本表达相同意思的程度。[摘自 [TensorFlow Hub](https://tfhub.dev/google/universal-sentence-encoder/1)

我们可以确定将句子分组在一起最小阈值。当相似性得分在 0 到 1 之间时,也许我们可以选择 0.5,在中间点。这意味着任何相似度大于 0.5 的句子都将被聚集在一起。

## 深入挖掘衡量相似性的方法

[Euge Inzaugarat](https://medium.com/u/5515433d5913?source=post_page-----aa3139d4fb71--------------------------------) 介绍了六种度量向量间相似性的方法。每种方法都适用于特定的环境,因此了解它们就像了解您的数据科学工具箱一样。

[](/how-to-measure-distances-in-machine-learning-13a396aa34ce) [## 机器学习中如何测量距离

### 这完全取决于你的观点

towardsdatascience.com](/how-to-measure-distances-in-machine-learning-13a396aa34ce) 

# 文本相似性分析网络应用的构建模块

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/676befaee9cb7bf10b1f52d476111eb1.png)

照片由 [Ryan Quintal](https://unsplash.com/@ryanquintal?utm_source=medium&utm_medium=referral) 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄

在这个项目中,我将使用这些库:

*   TensorFlow.js
*   通用句子编码器
*   有角的

## TensorFlow.js

TensorFlow.js 是 Google 建立的一个框架,支持 JavaScript 的机器学习。我们可以**开发机器学习模型,并将它们部署在网络浏览器和 Node.js** 中。

*因为我喜欢开发 web 应用程序,所以当 TensorFlow.js 在 2018 年发布时,我非常高兴。*

很容易上手,我们可以用 [npm](https://www.npmjs.com/) 安装 TensorFlow.js。

```
$ npm install @tensorflow/tfjs
```

简单线性回归模型的示例如下。

```
import * as tf from '@tensorflow/tfjs';const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);model.fit(xs, ys, {epochs: 10}).then(() => {
  model.predict(tf.tensor2d([5], [1, 1])).print();
});
```

## 通用句子编码器

我将使用的是来自 [TensorFlow.js](https://www.tensorflow.org/js) 的[通用句子编码器包](https://github.com/tensorflow/tfjs-models/tree/master/universal-sentence-encoder)。我们可以使用 [npm](https://www.npmjs.com/) 安装通用语句编码器。

```
$ npm install @tensorflow-models/universal-sentence-encoder
```

这个例子展示了我们如何使用通用句子编码器从每个句子中提取嵌入内容。

```
import * as use from '@tensorflow-models/universal-sentence-encoder';use.load().then(model => {
  const sentences = [
    'Hello.',
    'How are you?'
  ];
  model.embed(sentences).then(embeddings => {
    embeddings.print(true /* verbose */);
  });
});
```

## 有角的

[Angular](https://angular.io/) 是 Google 为创建动态单页应用而构建的 web 应用框架。

对于这个项目,我使用的是 Angular 8.0。我喜欢在 Angular 的[模型-视图-控制器设计模式](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)的基础上构建。从 Angular 的第一个版本开始,我就一直在使用它,在我的大部分 web 开发中也是如此。但由于他们每半年推出一次主要版本,感觉我的工作会变得过时(也许?我不知道)。React 是一个流行的 UI 框架,所以也许有一天我会改用 React。谁知道呢?

## 余弦相似性

创建一个函数,使用[余弦相似性公式](https://en.wikipedia.org/wiki/Cosine_similarity)计算两个向量的相似性。

```
similarity(a, b) {
  var magnitudeA = Math.sqrt(this.dot(a, a));
  var magnitudeB = Math.sqrt(this.dot(b, b));
  if (magnitudeA && magnitudeB)
    return this.dot(a, b) / (magnitudeA * magnitudeB);
  else return false
}
```

计算每个句子对的相似性得分的另一个函数如下。

```
cosine_similarity_matrix(matrix){
  let cosine_similarity_matrix = [];
  for(let i=0;i<matrix.length;i++){
    let row = [];
    for(let j=0;j<i;j++){
      row.push(cosine_similarity_matrix[j][i]);
    }
    row.push(1);
    for(let j=(i+1);j<matrix.length;j++){
      row.push(this.similarity(matrix[i],matrix[j]));
    }
    cosine_similarity_matrix.push(row);
  }
  return cosine_similarity_matrix;
}
```

## 将一切结合在一起

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8129abde6d5dccdbea3150400f805ee7.png)

照片由 [Amélie Mourichon](https://unsplash.com/@amayli?utm_source=medium&utm_medium=referral) 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄

我已经介绍了这个项目所需的所有主要组件。现在我们只需要把它们像乐高积木一样堆叠起来,打包并部署到 Github。

瞧啊。我们得到了一个用于现场演示的 web 应用程序。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/16cec8d6403944bf7dbe28373d1c17f8.png)

输入语义相似的句子列表[ [演示](https://jinglescode.github.io/demos/nlp-sentence-encoder)

我们有一个句子列表,这些将被输入到通用句子编码器中。它将输出每个句子的嵌入。然后我们计算每个句子之间的相似度。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5bddf7ea6d6f7020f6f146dd774db996.png)

## 结果

这些是我们将测试我们的通用句子编码器的句子。目的是把意思相似的句子组合在一起。我挑了几个比较难的案例,让我们看看它的表现如何。

> 明天会下雪吗?
> 最近许多飓风袭击了美国
> 全球变暖是真的
> 
> 一天一个苹果,医生远离我吃草莓有益健康
> 
> 你多大了?
> 你多大了?你好吗?
> 
> 约翰尼被狗咬了
> 
> 猫吃了老鼠
> 老鼠吃了猫

这张热图显示了每个句子与其他句子的相似程度。绿色越亮,表示相似度越接近 1,这意味着句子之间越相似。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/072215637bd3fe7caef9e281ccc86593.png)

12 个句子对的语义相似度[ [demo](https://jinglescode.github.io/demos/nlp-sentence-encoder)

我们可以调整该值来确定一个最小相似度阈值,以便将句子组合在一起。这些是以大于 0.5 的相似性值分组在一起的句子。

> 最近许多飓风袭击了美国全球变暖是真的
> 
> 每天一个苹果,医生远离我吃草莓是健康的
> 
> **第三组**
> 你多大了?你多大了?
> 
> **第四组**
> 狗咬了约翰尼
> 约翰尼咬了狗
> 
> **第五组**
> 猫吃了老鼠
> 老鼠吃了猫

我们的 web 应用程序出色地识别出了“ *Group 1* ”是*天气相关问题*。即使两个句子没有任何重叠的单词。

它成功地识别出“*飓风*”和“*全球变暖*”与天气有关,但不知何故未能将“*雪*”归入这一类别。

可惜,“*强尼咬了狗”和“狗咬了强尼”有着* 87%的相似度。可怜的约翰尼,我不知道哪个更好。

同样,对于“*猫吃了老鼠*”和“*老鼠吃了猫*”,我希望这两个向量有相反的相似性。

感谢您到目前为止的阅读!

再一次,试试[文本相似性分析网络应用](https://jinglescode.github.io/demos/nlp-sentence-encoder),在下面的评论中让我知道它是如何为你工作的!

如果您想构建类似的东西,请查看 web 应用程序的[代码](https://github.com/jinglescode/demos/tree/master/src/app/components/nlp-sentence-encoder)。

# 我构建的其他机器学习网络应用

因为我喜欢构建 web 应用程序,所以我开发了这些 web 应用程序来展示 web 上的机器学习能力。一定要跟随我的媒体([广告歌](https://medium.com/u/641197e9ee36?source=post_page-----aa3139d4fb71--------------------------------)),因为我会建立更多这样的。

使用 TensorFlow.js 进行时间序列预测。

[](/time-series-forecasting-with-tensorflow-js-1efd48ff2201) [## 使用 TensorFlow.js 进行时间序列预测

### 从在线 API 中提取股票价格,并使用 RNN 和 LSTM 以及 TensorFlow.js 进行预测(包括演示和代码)

towardsdatascience.com](/time-series-forecasting-with-tensorflow-js-1efd48ff2201) 

一个学习玩井字游戏的强化代理。

[](/reinforcement-learning-value-function-57b04e911152) [## 强化学习价值函数

### 代理使用价值函数学习井字游戏的强化学习算法——带网络演示

towardsdatascience.com](/reinforcement-learning-value-function-57b04e911152) [![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7820823f18c088b934fefc4fcbe5e6db.png)](https://www.linkedin.com/in/jingles/)[![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ed2857d42868ce52ed8f717376bc4cc7.png)](https://towardsdatascience.com/@jinglesnote)[![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c6faf13786230940c1756ff46938c471.png)](https://jingles.substack.com/subscribe)

# 参考

[1] Bengio,Yoshua,等.[一种神经概率语言模型。](http://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf)(2003)

[2]科洛波特、罗南和杰森·韦斯顿。"[自然语言处理的统一架构:具有多任务学习的深度神经网络。](https://thetalkingmachines.com/sites/default/files/2018-12/unified_nlp.pdf)(2008)

[3] Mikolov,Tomas,等.[向量空间中单词表示的高效估计。](https://arxiv.org/pdf/1301.3781.pdf)(2013)

[4] Cer,Daniel 等.[通用语句编码器。](https://arxiv.org/pdf/1803.11175.pdf)(2018)

[5]杨,,等.[从会话中学习语义文本相似度.](https://arxiv.org/pdf/1804.07754)(2018)

[6] Logeswaran、Lajanugen 和 Honglak Lee。"[学习句子表征的高效框架。](https://arxiv.org/pdf/1803.02893.pdf)(2018)

# 如何用 RNN 和喀拉斯建立翻译管道

> 原文:<https://towardsdatascience.com/how-to-build-a-translation-pipeline-with-rnn-and-keras-57c1cf4a8a7?source=collection_archive---------27----------------------->

## 你有没有想过一台计算机是如何能够如此快速地学习多种语言的?按照这个逐步指南创建您的第一个翻译模型。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6762f9c358e1c15a5d200911c72c758e.png)

巴别塔,老彼得·布鲁盖尔的画

在上一篇文章中,我们看到了 FFNN 在增益上下文方面的局限性。对于这些情况,更好的方法是 RNN,它可以管理上下文并生成状态,以便更好地理解跨时间步长的数据。**在本文中,我们将通过使用 keras 创建翻译模型来实践我们所学的内容**。

更准确地说,我们将开发一种多对多类型的 RNN,也称为序列对序列或 Seq2Seq。更高级的 Seq2Seq 结构包括编码器-解码器或注意力模型。我们将构建的模型如下所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a0d5816b561e729eaf6b23e01a67fa9e.png)

*作者图片*

输入层接收英语句子,每个单词是一个时间步长。然后,隐藏层(RNN)计算每个时间步长的状态,该状态将用于下一个时间步长,输出将用于密集层。

# 数据清理

样本数据可以在[manythings.org](http://www.manythings.org/bilingual/)下载,来自 [Tatoeba](https://tatoeba.org/spa) 。它由你需要的语言中的句子对组成。在我们的例子中,我们将使用西班牙语-英语对。

我们需要做的第一件事是导入库:

然后我们将读取文件并解析数据。

为了不让计算机处理大量的线对并保持例子的简洁,我们将只处理少量的数据。让我们来看看几双。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7e55628c322c40eeeaa4a38bc656c4ee.png)

从上一个片段打印。*作者图片*

句子包含有大写字母和标点符号的单词,所以让我们清除它。在本文中,我们将看到每个步骤的代码片段和示例。最后,所有内容都将合并到一个文件中。

它将打印“我今天要冲浪”。

## 标记器

机器学习模型不能阅读单词,只能阅读数字,为了给模型提供数据,我们需要将单词转换成数字。我们从 Keras 导入 Tokenizer 并应用两种方法。首先我们实例化这个类,然后用完整的文本调用方法 *fit_on_texts* 。得益于此,我们将**创建一个字典,我们将一个单词映射到一个索引**,每个唯一的单词都有一个唯一的索引。我们已经创建了一个名为 *text_examples* 的例子列表,我们有 3 个句子。这三个句子是我们的完整数据集,所以当我们调用这个方法时,它会为每个单词创建一个新的索引。让我们看看通过打印 *word_index.items()* 我们创建了什么。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b33f0f0b12d79fe1024896f8042dd9d8.png)

从上一个片段打印。*作者图片*

每个单词都有自己的索引,例如单词“beach”即使出现了两次,也只是在索引为 5 的情况下创建一次,对于索引为 3 的“to”也是如此。**我们已经创建了映射,但是我们还没有将句子转换成那些索引**。为此,我们需要调用方法 *texts_to_sequences* ,它的作用不再是创建映射,而是应用它。它采用句子“我今天将冲浪”,并将“我”更改为 1,“将”更改为 2,“冲浪”更改为 6,“今天”更改为 7。因此,句子“我今天将冲浪”变成了[1,2,6,7]。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4803fd7163c546623ec3ee3938abf266.png)

从上一个片段打印。*作者图片*

看起来很奇怪,电脑读数字更舒服,因为它失去了单词的所有意义。当两个单词是同义词时会发生什么?**一个模型如何知道 234 和 67 是否有相似的含义?**它来了**嵌入,不是把一个单词映射到一个索引,而是把一个单词映射到一个向量。**计算这些向量可以保留单词的意思,并创建一个空间表示。当我们表示这些向量时,具有相似意义的单词也将具有相似的坐标。这种技术被称为嵌入,将在下一篇文章中讨论。

我们创建一个函数来返回向量和映射。

让我们把我们到目前为止所看到的应用到句子对而不是例子中,并探索结果。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9166b1f420dac6f1c232d55f91bc2160.png)

从上一个片段打印

西班牙语有 7198 个独特的单词,而英语只有 3736 个。此外,另一个区别是句子的最大长度,而西班牙语由 12 个单词组成,英语的最大长度是 6 个单词。等等,到目前为止,我们已经看到,两个句子应该是相同的长度,以适应 RNN 结构,我们如何处理不同的长度?

## 填料

为了使所有的句子长度相同,我们使用 Keras 的 T2 填充序列。这个类的作用非常简单,对于那些长度小于最大长度的句子,它会加一个 0。回到我们的列表 *text_examples* ,最大长度是 8,而第一个句子的长度是 4,那么当我们应用填充时,我们有[1 2 6 7 0 0 0 0]。添加了 4 个零,使其长度为 8。其他两个句子的长度已经是 8,则不应用任何更改。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8314f841373c605150a353495dcf9e36.png)

从上一个片段打印。*作者图片*

一个更直观的例子如下。对于时间步长为 8 的 RNN,我们要翻译句子“鸟儿歌唱”它变成了“los pájaros están cantando”

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/66e272084dfcb3837d1998519337996b.png)

RNN 结构,*作者图片*

我们将在构建模型时参考这个图像。我们将相同的代码应用于西班牙英语对。

我们准备好了,句子已经被清理了,它们也变成了向量,由于填充,它们的长度是一样的。我们的训练数据准备好了。

# 模型创建

我们需要定义的第一层是输入层,图像' *RNN 结构'*中的蓝色层。在 Keras 中,RNN 的**输入形状是 3D(批量大小,时间步长,特征)**。输入层有两个元素(时间步长,特征),我们已经知道时间步长,从我们的最大句子长度 12,和特征是在时间步长的观察数量,在我们的例子中只有一个。然后 batch_size 被定义为对象*模型*的方法 *fit* 的一个参数,Keras 假设它为 1 或更大。

我们添加的第二层是 RNN,更准确地说,在这种情况下,我们处理的是长短期记忆(LSTM)。需要注意的一个重要参数是***return _ sequences***,默认设置为 False,该图层的输出将只是最后一个时间步的矢量,如下图所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/88695441632ae479d1f8cde134412b85.png)

情感分析(多对一)。RNN 在最后一步输出矢量,*作者的图片*

我们不需要在每个时间步获得输出,只需要在最后获得输出,这样密集层就可以做出预测。但是在我们的例子中,正如我们在图像' *RNN 结构* ' **中看到的,在每个时间步**都有一个预测,所以 RNN 层在最后不会输出一个矢量,而是在每个时间步**输出一个矢量。**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/94d643bf43bb8b27ede1711384d7ad1a.png)

多对多。当 return_sequences=True 时,RNN 层在每个时间步长输出一个矢量

在这个解释之后是介绍时间分布的时候了。尽管概念上非常简单,但当你第一次面对它时,它会引起一些混乱。我们刚刚在 RNN 层中设置了 *return_sequences=True* ,所以我们在每一步都有一个输出向量。那我们该怎么办?**应用一个密集层,**所以最后用一个激活层我们可以做一个预测。这个致密层是什么样子的?

**输入层接收一个形状为 256** 的矢量,它相当于 LSTM 层中的 256 个单位。**输出层有一个 7198** 的形状,代表我们词汇中唯一西班牙语单词的总数( *spanish_vocab* )。**预测字将是 7198 中已经激活的单元**。因此,如果最终向量除了单元 324 之外都是零,其中我们有一个 1,我们将索引 324 映射到标记化器,并获得翻译的单词。这是在每个孤立的时间步完成的。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/873d6345acc45377492bbab353bcb7b5.png)

*作者图片*

我们刚刚看到了如何应用密集层,但是**时间分布**有什么用呢?**这仅仅意味着我们在每个时间步**应用先前解释的层。因为我们使用 *return_sequence=True* ,RNN 层在每个时间步输出一个矢量,因此我们需要在每个时间步应用相同的密集层。如果我们放大模型的输出层,它看起来如下。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bf57a992dbe94e70bed58d964ca7a462.png)

*作者图片*

总而言之,为了创建模型,我们应用以下代码。

该模式的总结是:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cd32c1a8dc0d7989fa5a70f74ff35782.png)

最后,我们训练我们的模型。参数尚未优化,本文的目的是了解和创建管道。

一旦我们完成训练,让我们做一些预测。正如我们之前看到的,模型在每个时间步长的输出是形状 7198 的向量,其中激活的单元是预测的单词,因此例如,如果在我们的第一次预测之后,我们有输出 324,我们需要将索引映射到西班牙语单词。下面的函数将为我们完成这项工作。

为了检查最终的预测,我们使用下面的代码。

*你可以在* [*下面的链接*](https://github.com/NechuBM/rnn_tutorial/tree/feature/simple-rnn/tutorials/simple_rnn) 中找到一个 jupyter 笔记本,里面有完整的代码

## 摘要

在这篇文章中,我们把学到的关于 RNN 的概念付诸实践。

我们让 c **学习数据****创建了一个索引**来将每个单词映射到一个向量,并将所有的**句子转换成**那些**向量**,这要感谢*分词器*。然后我们使用 *pad_sequences* 让所有的句子都有**一样的长度。**

为了创建模型,我们定义了输入形状,我们用 *return_sequences=True* 创建了一个 LSTM 层,然后由于 **TimeDistributed** ,在每个时间步应用了一个密集层。

在下一篇文章中,我们将详细阐述模型架构,以创建一个更好的执行翻译。从理论的角度来看,我们将讨论不同类型的 RNN 建筑,如 LSTM,并分析之前介绍的术语,如嵌入。

# 如何使用 Memgraph、Cypher 和 Python 构建旅行规划应用程序

> 原文:<https://towardsdatascience.com/how-to-build-a-travel-planning-application-with-memgraph-cypher-python-a1b0b346d529?source=collection_archive---------42----------------------->

## 了解如何利用广度优先搜索(BFS)和 Dijkstra 算法,用 Memgraph、Cypher 和 Python 构建一个简单的旅行规划应用程序。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/43396d0de8a9491ee60bb2fd867e15fe.png)

*Christopher Czermak 在 Unsplash 上拍摄的照片*

# 介绍

背包旅行是一种在预算范围内探索世界的好方法。凭借其良好的交通网络、经济实惠的住宿条件和数以千计的景点,欧洲是背包客的完美旅行目的地。

在本教程中,您将学习如何利用 Memgraph、Cypher 和 Python 构建一个简单的旅行规划应用程序。您将学习如何使用图形数据库,以及如何使用 Python 语言驱动程序查询它。您还将学习如何利用流行的图形算法,包括[广度优先搜索(BFS)](https://en.wikipedia.org/wiki/Breadth-first_search) 和 [Dijkstra 的算法](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)。

# 先决条件

要跟进,您需要以下内容:

*   运行 Linux 的机器。
*   Memgraph 的本地安装。您可以参考[Memgraph 文档](https://docs.memgraph.com/memgraph/quick-start)。
*   Python 内存图客户端。
*   Python 编程语言的基础知识。在本教程中,我们将使用 Python 3。
*   Cypher 查询语言的基础知识。

# 步骤 2 —构建数据模型

首先,我们必须定义我们将用来构建您的应用程序的数据模型。用于图形分析的最常见的数据模型之一是标签属性图(LPG)模型。这个模型被定义为一组顶点(即节点)和边(即关系)以及它们的属性和标签。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7a06783b033f791ed1b55791eddbddb1.png)

在本教程中,您将使用欧洲背包客指数(2018)数据集,该数据集包含位于 36 个欧洲国家的 56 个城市的信息。您的模型将包含两个类型为`City`和`Country`的顶点,三个类型为`Inside`、`CloseTo`和`Borders`的边,以及一些属性,如名称、排名、当地货币等。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/44b0b96e1b988d11767d36cf4395c02b.png)

既然已经定义了数据模型,下一步就是将数据导入 Memgraph。

# 步骤 3—使用 Cypher 和 Python 将数据导入 Memgraph

为了将数据导入 Memgraph,您将通过 Python 客户端`pymgclient`使用 Cypher 查询。

pymgclient 是 Python 编程语言的 Memgraph 数据库适配器,符合 PEP 249 描述的 DB-API 2.0 规范。

Cypher 是一种声明式查询语言,被许多人认为是处理属性图数据库的行业标准。

在开始之前,你必须安装`pymgclient`。这将允许您连接到 Memgraph 并运行您的查询。为此,我们将运行以下命令:

```
pip install pymgclient
```

现在我们已经安装了`pymgclient`,我们准备导入它并连接到 Memgraph 数据库。为此,我们将使用以下 Python 代码:

```
import mgclient# Connect to the database
connection = mgclient.connect(
    host='127.0.0.1',
    port=7687,
    sslmode=mgclient.MG_SSLMODE_REQUIRE)
connection.autocommit = True
```

既然我们的 python 客户机已经连接到 Memgraph,我们就可以开始运行查询了。为了加速数据导入,我们在`City`和`Country`顶点的`id`属性上创建索引。这将有助于 Memgraph 在创建边时快速找到城市和国家。注意,我们可以在另一个属性上创建索引,比如`name`,我们将获得相同的结果。

[注意]数据库索引实质上是创建数据库中某些数据的冗余副本,以提高索引数据的搜索效率。然而,这是以额外的存储空间和更多的写入为代价的,因此决定索引什么和不索引什么是一个重要的决定。

为了创建索引,我们将执行以下查询:

```
connection.cursor().execute("""
CREATE INDEX ON :City (id)
""")
connection.cursor().execute("""
CREATE INDEX ON :Country (id)
""")
```

既然我们的索引已经创建,我们将开始导入我们的,从国家开始。为此,我们将运行下面的[查询](https://download.memgraph.com/dataset/europe-backpacking/python/countries.txt)。

正如您所看到的,这个查询使用了`CREATE`子句来创建一个带有一个标签`Country`和两个属性`id`和`name`的顶点。

接下来,我们将添加`City`节点及其所有属性,如当地货币、餐饮的平均价格、交通费用等。为此,我们将使用下面的[查询](https://download.memgraph.com/dataset/europe-backpacking/python/cities.txt)。

如您所见,该查询使用相同的`CREATE`子句创建标签为`City`的节点,以及 14 个不同的属性。

现在我们已经创建了图表中的所有节点,我们准备开始添加边。为此,我们将运行下面的[查询](https://download.memgraph.com/dataset/europe-backpacking/python/edges.txt)。

在这个查询中,我们首先使用`MATCH`子句获取两个`City`节点,我们将在这两个节点之间创建一条边,然后使用`CREATE`子句创建一条标签为`CloseTo`的边和一个值为`True`或`False`的属性`eu_border`。

恭喜你。现在,您已经将所有数据集导入 Memgraph。现在,您可以开始执行查询和算法了。

# 步骤 4—用 Python 运行简单的密码查询

首先,我们可以运行一些简单的查询,比如获得旅馆最便宜的前 10 个城市。为此,您将运行以下查询:

```
cursor = connection.cursor()
cursor.execute("""
MATCH (n:City)
RETURN n.name, n.cheapest_hostel, n.cost_per_night_USD, n.hostel_url
ORDER BY n.cost_per_night_USD LIMIT 10
""")
print(cursor.fetchall())
```

该查询匹配所有标签为`City`的顶点,并返回城市名称、最便宜的旅馆名称、该旅馆每晚的费用以及旅馆 URL。然后,它根据最便宜的旅馆每晚的费用对结果进行排名,并返回前 10 个结果。

如果你去意大利旅游,想知道哪些城市适合背包客,哪家旅社对他们来说最便宜,该怎么办?要获得答案,您将运行以下查询:

```
cursor = connection.cursor()
cursor.execute("""
MATCH (c:City)-[:Inside]->(:Country {name: "Italy"})
RETURN c.name, c.cheapest_hostel, c.total_USD
ORDER BY c.total_USD;
""")
print(cursor.fetchall())
```

如您所见,该查询类似于我们之前使用的查询,但是我们没有匹配所有城市,而是只匹配通过类型`Inside`的边缘连接到意大利的城市

# 步骤 5—使用广度优先搜索算法查找和过滤路径

尽管这些查询给了我们一些有趣的见解和结果,但它们并不是图数据库特别感兴趣的东西。当我们开始询问涉及遍历任意数量的边的更复杂的问题时,图数据库变得很有价值。这些类型的寻路查询对于传统数据库来说可能会有问题,因为它们通常需要多个连接。

假设您想要从西班牙旅行到俄罗斯,但是您想要选择穿过最少边界的路线。这就是像广度优先搜索(BSF)这样的图算法派上用场的地方。要获得答案,您将使用以下查询:

```
cursor = connection.cursor()
cursor.execute("""
MATCH p = (n:Country {name: "Spain"})
          -[r:Borders * bfs]-
          (m:Country {name: "Russia"})
UNWIND (nodes(p)) AS rows
RETURN rows.name;
""")
print(cursor.fetchall())
```

该查询使用类型为`Borders`的边评估西班牙和俄罗斯之间的所有可能路径,计算每条路径的过境次数,并返回过境次数最少的路径。

如果您想根据特定标准过滤路径,该怎么办?假设您想从布拉迪斯拉发开车到马德里,并想计划您的路线以尽量减少停靠站的数量。你也想只去那些把欧元作为当地货币的国家,因为那是你唯一剩下的货币。为此,您将使用以下查询:

```
cursor = connection.cursor()
cursor.execute("""
MATCH p = (:City {name: "Bratislava"})
          -[:CloseTo * bfs (e, v | v.local_currency = "Euro")]-
          (:City {name: "Madrid"})
UNWIND (nodes(p)) AS rows
RETURN rows.name;
""")
print(cursor.fetchall())
```

如您所见,我们向查询`(e, v | v.local_currency = "Euro")`添加了一个特殊的语法。这被称为过滤λ函数。过滤器λ取一个边符号`e`和一个顶点符号`v`,并通过返回 true 或 false(或 Null)来决定该边和顶点对在广度优先扩展中是否应该被认为是有效的。在本例中,如果城市顶点`v`的类型`v.local_currency`的属性值等于 Euro,lambda 函数返回 true。一旦确定了最佳路径,查询将返回该路径上的城市列表,并且`UNWIND`子句将该列表解包到单独的行中。

# 步骤 6-使用 Dijkstra 算法寻找最短路径

到目前为止,您使用了广度优先搜索算法来查找穿过最少边数的路径。但是,如果你想找到一条最短的路径,并考虑到沿途每个城市的住宿价格,那该怎么办呢?换句话说,如果你想找到最短最便宜的路径呢?这是广度优先搜索算法达到极限的地方。只有当所有的边和顶点都没有权重或者具有相同的权重时,BFS 才会准确地计算最短路径。

当涉及到在图中寻找边和顶点不具有相同权重的最短路径时,您将需要使用 Dijkstra 算法。

例如,假设你想从布鲁塞尔旅行到雅典,而你的预算很紧。为了找到最便宜的路线,您可以使用以下查询:

```
cursor = connection.cursor()
cursor.execute("""
MATCH p = (:City {name: "Brussels"})
          -[:CloseTo * wShortest (e, v | v.cost_per_night_USD) total_cost]-
          (:City {name: "Athens"})
WITH extract(city in nodes(p) | city.name) AS trip, total_cost
RETURN trip, total_cost;
""")
print(cursor.fetchall())
```

如您所见,语法几乎与我们的 BFS 查询相同。我们使用加权最短路径`wShortest`并指定`cost_per_night`属性类型作为我们的权重。权重 lambda 表示使用给定边`v.cost_per_night_USD`扩展到指定顶点的成本,`total cost`符号计算行程成本。extract 函数仅用于显示城市名称。要获得完整的城市信息,您应该返回`nodes(p)`。

# 结论

你有它!您刚刚学习了如何使用图形数据库、Cypher 和 Python 构建一个简单的旅行路线规划应用程序。您还了解了如何使用广度优先搜索算法和 Dijkstra 算法在复杂的互联数据网络中导航,并使用强大而灵活的 lambda 函数过滤结果。

# 如何建立扭曲线性回归模型

> 原文:<https://towardsdatascience.com/how-to-build-a-warped-linear-regression-model-3e778e30a201?source=collection_archive---------49----------------------->

## [优化和机器学习](https://towardsdatascience.com/tagged/optimization-and-ml)

## 我们使用模块[峰值引擎](https://github.com/rnburn/peak-engines)对数据进行单调转换

[普通最小二乘法](https://en.wikipedia.org/wiki/Ordinary_least_squares) (OLS)将线性回归模型拟合到数据集,以便在误差正态分布的假设下最大化似然性。当误差项分解成独立同分布分量的和时,正态性自然会出现,但对许多问题来说,这种假设是不现实的。

例如,考虑一个目标值表示百分比的回归数据集。对于一个给定的特征向量,OLS 可能会预测一个这样的分布

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7c6e503526cfe851d7f1c4e9e77350a9.png)

这里怎么了?分布显示目标值可能大于 100%。当目标空间是有界的时,关于末端附近预测的正态分布误差是没有意义的。

如果不满足正态假设,我们有时可以通过转换目标空间来解决问题。假设 *f* 是单调递增函数。让 X 和 y 表示特征矩阵和目标向量。放 *z = f(* y *)。*虽然 OLS 可能无法很好地模拟原始数据集,但它有可能适合 X 和 z

我们如何找到这样一个函数 *f* ?这就是翘曲帮助我们的地方。弯曲从一族参数化单调函数开始。该族足够一般,可以近似任意变换。如果 *ψ* 表示弯曲函数的参数向量,那么我们使用优化器来调整 *ψ* 以最大化训练数据的可能性。

[Peak-engines](https://github.com/rnburn/peak-engines) 是一个 python 模块,用于构建这种扭曲的线性回归模型。我们将使用它为一个示例数据集构建一个模型,并展示我们如何改进 OLS。

我们将使用的示例是波士顿房屋数据集,其任务是根据社会经济和地理属性预测房屋的中值。像百分比一样,房屋价值是有限的(你不会找到免费的房屋),因此有理由认为目标空间可以从扭曲中受益。

首先,让我们设置数据集。Boston housing 附带 sklearn,便于组装。

在我们建立扭曲线性回归模型之前,我们需要安装峰值引擎

```
pip install peak-engines
```

然后我们可以拟合一个扭曲的线性回归模型。

Peak-engines 在 OLS 之前搜索要应用的扭曲函数空间,直到找到最大化可能性的变换。为了可视化转换的样子,我们将它绘制在目标值的范围内。

翘曲函数在较低的住房价值更陡峭。它在目标空间的低端展开点,在高端压缩点。

为了比较扭曲线性回归和 OLS,让我们运行留一交叉验证。对于每个数据点,我们形成一个去除了该点的训练数据集和一个只包含该点的测试数据集。我们拟合 OLS 和扭曲的线性回归模型,并衡量对数似然性能。

结果显示验证点更有可能是扭曲线性回归。我们将查看一些随机预测示例,以更好地理解为什么它做得更好。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/122f3a96369f9b53edadcf2b78f885ab.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/87f233d2e93f86733599d6f4d50982c0.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/566b1211008c2d53aa430079321b7bab.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e773d4a5cb79a8a8f2cf21836ec2399c.png)

扭曲函数导致概率密度函数在较低的目标值处逐渐变小,从而允许概率质量被重新分配到值更可能出现的区域。

完整示例的代码可从[这里](https://github.com/rnburn/peak-engines/blob/master/example/boston_housing.ipynb)获得。

## 摘要

当面临回归问题时,OLS 通常是我们寻求的第一个模型,然而许多数据集并不满足其对正态分布误差的强假设。扭曲线性回归建立在 OLS 的基础上,通过引入额外的变换步骤来扭曲目标空间,以校正误差中的非正态性。它保留了 OLS 模型的许多简单性,但更通用,并经常导致更好的性能。

参考

[1]: *E .斯尼尔森,CE Rasmussen,Z . Ghahramani。* [*【扭曲高斯】突起*](https://papers.nips.cc/paper/2481-warped-gaussian-processes.pdf) *。神经信息处理系统的进展 16,337–344*

[2]: [当您的模型具有非正态误差分布时该怎么办](https://medium.com/p/what-to-do-when-your-model-has-a-non-normal-error-distribution-f7c3862e475f?source=email-f55ad0a8217--writer.postDistributed&sk=f3d494b5f5a8b593f404e7af19a2fb37)

# 使用 Keras 和 OpenCV 的自定义对象检测

> 原文:<https://towardsdatascience.com/how-to-build-a-weapon-detection-system-using-keras-and-opencv-67b19234e3dd?source=collection_archive---------4----------------------->

## 建立一个可以在给定的图像或画面中识别武器的系统

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d6ed2371c633413380d2cb601ec82fe7.png)

武器探测系统([原图](https://www.pxfuel.com/en/free-photo-ovfsz))

我最近完成了一个令我非常自豪的项目,我想我应该分享它,以防其他人有兴趣实现类似于他们特定需求的东西。在我开始本教程之前,我想对 [PyImageSearch](https://www.pyimagesearch.com/) 的创建者 Adrian Rosebrock 博士表示深深的感谢。我是一个自学成才的程序员,所以没有他的资源,这个项目的大部分是不可能的。他是一个典型的*男人-* 我非常感激他在自己的网站上提供的资源。如果你想学习先进的深度学习技术,但发现教科书和研究论文很枯燥,我强烈建议访问上面链接的他的网站。

在大多数与武器分类相关的项目中,我只能找到最多 100-200 张图片的数据集。这提出了一个问题,因为根据我的经验,很难用这么少的图像得到一个工作模型。为了收集图像,我用我的树莓皮刮了一下[IMFDB.com](http://www.imfdb.org/wiki/Main_Page)——一个枪支爱好者张贴照片的网站,照片中的模型枪出现在一部电影的画面或剪辑中。如果你访问网站,这一点会更清楚。要访问我用过的图片,你可以访问我的 [Google Drive](https://drive.google.com/file/d/1EZZKhCk0DK3S9zB53o3nWhKrZUbmN2Up/view?usp=sharing) 。在这个 zip 文件中,您将找到所有在这个项目中使用的图像和相应的。边界框的 xml 文件。如果你需要一个大数据集的边界框,我强烈推荐 [ScaleOps。AI](https://scaleops.ai/) ,一家专注于机器学习算法数据标注的公司。目前,我有来自 IMFDB 网站的 120,000 张图片,但是由于时间和资金的限制,我只使用了大约 5000 张。

现在,让我们来看看逻辑。这个项目的架构遵循[这个](https://www.pyimagesearch.com/2020/07/13/r-cnn-object-detection-with-keras-tensorflow-and-deep-learning/)网站上显示的逻辑。虽然我们在这里实现了这个逻辑,但是在许多领域它是不同的,因此它可以用于我们的特定问题——检测武器。该项目使用 6 个基本步骤:

1.  使用 OpenCV 选择性搜索分割构建数据集
2.  建立一个 CNN 来检测你想要分类的物体(在我们的例子中,0 =没有武器,1 =手枪,2 =步枪)
3.  在根据选择性搜索分割构建的图像上训练模型
4.  为新图像创建边界框时,通过选择性搜索分割运行图像,然后抓取图片的每一部分。
5.  通过算法运行图像的每一部分,每当算法预测到你要寻找的对象时,用边界框标记位置
6.  如果标记了多个边界框,应用非最大值抑制,只包括具有高置信度/感兴趣区域的框(这部分我还在弄清楚…你将在下面看到我的问题)

下面是展示算法如何工作的 gif。对于给定的图像,每个方块将被输入到神经网络中。如果一个正方形被预测为阳性(手枪或步枪),我们将标记我们输入到原始图像的区域。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/daff86c61340da4ecff35a0c6971a067.png)

滑动窗口方法:对象检测(作者图片)

如果你想看这个项目的完整代码,请访问我的 GitHub Repo,在那里我会更深入地解释这些步骤。

我上面链接的数据包含了很多文件夹,我需要解释一下,以便理解正在发生的事情。解压文件夹后,这些文件和文件夹对项目很重要:AR、FinalImages、Labels、Pistol、Stock_AR、Stock_Pistol 和 PATHS.csv。所以对于 AR 文件夹,你会发现里面有突击步枪的图片。在标签文件夹中,您会看到。类文件夹中所有图像的 xml 标签。最后,PATHS.csv 将指向算法中使用的每一张图像。出于本教程的目的,这些是您唯一需要担心的文件夹/文件:

1.  最终图像/NoWeapon
2.  最终图像/手枪
3.  最终图像/步枪

这些文件夹中的图像制作方式如下。

*   对于每个有边界框的图像,提取边界框并将其放入相应的类文件夹中。因此,对于一个人拿着手枪的图像,手枪周围的边界框将变成正的,而边界框以外的每个部分都将变成负的(没有武器)
*   在下图中,想象一个包围左侧图像的边界框。在提取边界框内的像素(右边的图像)后,我们将该图像放入另一个文件夹(FinalImages/Pistol),同时将边界框周围的所有空白区域放入 NoWeapons 文件夹。
*   虽然右边的图像看起来像是左边图像的调整版本,但它实际上是一个分段图像。想象在左边的枪周围有一个边界框。右边的图像是*仅仅是*边界框,没有别的(移除框外的所有东西)。这种技术被称为感兴趣区域(ROI)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0627843f536a1e6d9eb16862f872287f.png)

ROI 提取(图片由作者提供)

在收集数据集(可以在 Separated/FinalImages 中找到)后,我们需要为我们的算法使用这些文件,我们需要以这样的方式准备它,我们有一个 RGB 值列表和相应的标签(0=没有武器,1 =手枪,2 =步枪)

如果您运行上面的代码,在当前目录的之外有一个单独的文件夹*,您会看到一个 tqdm 窗口,显示它正在加载图像。该过程完成后,您应该会看到以下内容:*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2fc90d073971beebe825061d53afacbb.png)

(图片由作者提供)

现在是神经网络的时候了。在下面的代码中,该函数将返回一个给定维度大小的模型。如果您在上面的代码中注意到,照片的尺寸被调整为(150,150,3)。如果您希望使用不同的尺寸,请确保您更改了上面的变量 dim,以及下面函数中的 DIM

上面返回的模型将具有如下所示的体系结构:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b901a3b77b56612ca4c0416e4d1f3dc8.png)

CNN 架构(图片由作者提供)

一旦我们有了训练集和测试集,我们需要做的就是把它放到我们的模型中。运行下面的代码将开始训练过程。

如果运行代码时没有任何错误,您应该会看到如下窗口:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6cc8f837010c89616e2c684de6b479ac.png)

我想指出的是,我将历元设置为 1000,但提前停止将防止算法过度拟合,因此它不应运行超过 30–50 个历元。模型完成后,您应该会在您的目录中看到一个名为 ModelWeights.h5 的. h5 文件。该文件是模型生成的权重,因此将它们加载到模型中会在模型开始溢出之前加载模型。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e6c57cedbec073a6d9762fd7a0a79615.png)

模型的准确性(图片由作者提供)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e14e470d67271529b56c9c1708557c44.png)

每个班级的 ROC(图片由作者提供)

考虑到一个平衡的数据集,这个精确度是相当不错的。查看 ROC 曲线,我们还可以假设每个类别下的面积非常接近 1,这是一个非常好的分类。

现在是物体探测的时间了!以下逻辑用于创建边界框:

1.  输入视频中的图像或帧并检索基本预测
2.  应用选择性搜索分割来创建数百或数千个包围盒命题
3.  通过训练的算法运行每个边界框,并检索预测与基本预测相同的位置(在步骤 1 中)
4.  检索到算法预测与基本预测相同的位置后,在算法运行的位置上标记一个边界框
5.  如果选择了多个边界框,则应用非最大值抑制来抑制除一个框之外的所有框,留下具有最高概率和最佳感兴趣区域(ROI)的框

*   注意:非最大值抑制仍在进行中。在某些情况下,它只能检测枪的特征,而不是整个枪本身(见下面的模型比较)。

在运行上面的代码之前,创建一个文件夹 Tests,从互联网上下载任何图像,并将该图像命名为您想要预测的类。运行上面的代码将搜索 Tests 文件夹中的每张图片,并使用上面构建的 CNN 通过我们的对象检测算法运行该图片。

我测试的图像如下:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d850da695de8ec8028b5c2ce2a554c72.png)

基础图像

运行上面的代码后,这些是算法输出的预测。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1009660bddd33d96feb677af24560c38.png)

模型结果(图片由作者提供)[点击[此处](https://github.com/HeeebsInc/NN_Weapon_Detection/blob/master/Figures/ModelComparisons/Normal/Normal.png)查看大图]

正如您在上面看到的,非极大值抑制并不完美,但在某种意义上确实有效。我这里的问题是,有多个具有 100%置信度的边界框,所以很难选择哪一个是最好的**此外,当帧中没有武器时(绵羊图像),该算法无法检测非武器。

使用上面实现的逻辑,[这里的](https://www.youtube.com/watch?v=e6tFxT-BpFg&t=1s&ab_channel=SamuelMohebban)是我将代码应用到视频的一个很酷的视觉效果。

演示武器检测(视频由作者提供)

基于上面的例子,我们看到这个算法离完美还有一段距离。这没什么,因为我们仍然创建了一个非常酷的模型,只用了 5000 张图片。就像我之前说的,我从 IMFDB.com 收集了总共 120,000 张图片,所以随着我们在培训期间传递更多的图片,这只会变得更好。

## 石灰:特征提取

构建和测试神经网络的一个困难部分是,它的工作方式基本上是一个黑盒,这意味着你不明白为什么权重是它们的样子,或者算法在图像中使用什么来进行预测。使用 [LIME](https://github.com/marcotcr/lime) ,我们可以更好地理解我们的算法是如何执行的,以及图片中的哪些内容对于预测是重要的。

石灰预测

运行上面的代码将创建一个如下所示的图像:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5b333506989220f1b119dadbb4dfb8be.png)

石灰(图片由作者提供)

绿色区域是算法认为“重要”的区域,而红色区域则相反。考虑到我们希望算法检测枪的特征,而不是手或图像的其他部分,我们在上面看到的是好的。

现在我们可以说我们创造了我们自己的有意识的生物…是时候面对现实了。与现有的工具相比,我们制作的模型微不足道。这使我转而学习…我们看到了一些很酷的结果。为了这个教程,我不会把代码放在这里,但是你可以在我的 [GitHub Repo](https://github.com/HeeebsInc/NN_Weapon_Detection) 上找到它

## Mobilenet

*   在下面的例子中,mobilenet 更擅长预测不是武器的物体,并且在正确的区域周围有边界框。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/97224139d9c2d2816e0f3fc8b53f7d6b.png)

Mobilenet(图片由作者提供)[点击[此处](https://github.com/HeeebsInc/NN_Weapon_Detection/blob/master/Figures/ModelComparisons/Mobilenet/Mobilenet.png)查看大图]

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0072bd665c380d9958e1e7123497e74a.png)

Mobilenet LIME(图片由作者提供)

## VGG16

*   在下面的例子中,VGG16 无法像我们自己构建的架构那样区分非武器。它错误地将 3 张手枪图像中的 1 张归类,而将其余的正确归类为手枪
*   尽管它错误地将手枪归类为无武器(右边第四个),但边界框并不在枪上,因为它停留在握枪的手上。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7f8102b3a27d36cc5b9d3ef07a8c9cfb.png)

VGG16(图片由作者提供)[点击[此处](https://github.com/HeeebsInc/NN_Weapon_Detection/blob/master/Figures/ModelComparisons/VGG16/VGG16.png)查看大图]

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/616f86c657dd9a606c6f88d7512c1e6a.png)

VGG16:石灰(图片由作者提供)

## 结论

*   这个项目的目标是创建一种算法,它可以将自己集成到传统的监控系统中,并比人更快地防止糟糕的情况(考虑到当今社会的不幸情况)。
*   虽然这很酷,但我的电脑中的硬件还没有。分割图像并处理图像的每个部分大约需要 10-45 秒,这对于直播视频来说太慢了。
*   我上面展示的视频演示是一个 30 秒的剪辑,大约需要 20 分钟来处理。
*   然而,尽管使用 RX 580 进行视频直播是不可行的,但使用新的 Nvidia GPU (3000 系列)可能会有更好的效果。
*   此外,这种技术可用于追溯检查事件,如人体摄像机镜头或抗议。

**注意**如果您想了解整个项目,请访问我的 [GitHub](https://github.com/HeeebsInc/WeaponDetection) **

# 如何为您的数据科学项目构建 Web 应用程序

> 原文:<https://towardsdatascience.com/how-to-build-a-web-app-for-your-data-science-project-9b10190d3962?source=collection_archive---------28----------------------->

## 如果你在电脑上处理数字,它会发出声音吗?

我最近使用深度强化学习为哲学家足球建造了一个人工智能球员,以纪念已故的约翰·康威。我想要一种向人们展示结果的方式,所以我创建了一个网站[哲学家。足球](http://philosophers.football/)在那里你可以和机器人或其他人比赛。

你可以在那里和人工智能对战,感受一下它和游戏,尽管人工智能还在训练中——可能需要几个星期才能变好。

一路走来,我不得不处理一个弄清楚大量的技术,让我的模型从 Jupyter 笔记本代码到部署。现在,如果我每读一个“教程”就有一美元,我不能安装谁的软件,我不能运行谁的代码,或者那些没有告诉我如何部署任何东西,我会…嗯,我不会很富有,但是我可以负担更多的硬件来训练我的模型。我的人工智能播放器现在会更好。

我尤其感到沮丧的是,一行一行的代码示例都在做作者所做的事情。一旦你想做一些不同的事情(比如你自己的项目),他们就不那么有帮助了。(我的意思是,我仍然使用它们)。

所以,我的解决方案是给你写一本一体化的*指南*,作为相关技术的地图,它们做什么的感觉,以及要使用的资源。希望有了这个,你能想象出把你的项目变成一个网络应用的途径。以我的经验,这永远是第一步。

作为奖励,感谢 Docker,我能够保证,如果你克隆我的 [github repo](https://github.com/rcharan/phutball) 并按照指令操作,代码就能保证运行。至关重要的是,这意味着你可以修改它并了解它的功能。

特别是,当我开始的时候,我真的对互联网的运作只有一个粗略的了解,对我的项目如何在互联网上结束没有一个清晰的概念。

所以,说清楚一点,这是*不是*

*   这不是关于工业级部署技术的教程。这是一个业余爱好项目。你将会学到很多关于那些工业级技术解决了什么问题。
*   这不是一个逐行走查的教程。
*   这绝对不包括安全。我的网站肯定有密码和一些内置的安全功能,但只是很好,好吗?
*   这绝对不是开发 web 应用程序的最佳实践。我不是网页设计师或开发人员。我做的东西甚至不能在你的手机上运行。但它肯定能在你的电脑上运行,就像你自己看到的一样。加上你大概(?)不会吐槽你的配色。
*   这不是关于如何创建模型或使用数据库(核心数据科学的东西)。这是关于如何部署您的模型,可能使用数据库。

# “堆栈”

也就是我使用的所有技术的可怕列表。下面我会解释重要的,我保证。这是目录。

## 核心技术

这些是我真正花时间思考和编写代码的事情。

1.  (后端/API) [Django](https://www.djangoproject.com/) ,一个 Python web 框架/包,使得处理数据库和构建 API 变得轻而易举。在这里添加相关但技术上独立的标准 API 的 [Django REST 框架](https://www.django-rest-framework.org/)和支持 WebSocket 连接和异步计算的 [Django 通道](https://channels.readthedocs.io/en/latest/)(模型与服务器并行运行)。
2.  一个来自脸书的 JavaScript web 框架/库,可以在浏览器中制作漂亮的图片。
3.  (机器学习) [PyTorch](https://pytorch.org/) 一个用于神经网络的机器学习框架/Python 包 thingamajig。也来自脸书。
4.  (部署/虚拟化) [Docker](https://www.docker.com/) 一个虚拟机,它通过发誓自己不是虚拟机来定义自己。出于我们的目的,它的功能有点像类固醇(ish)上的 conda(或 pip)——它神奇地解决了安装软件的所有问题。
    非常重要,因为你可能希望以后在服务器上运行你的代码,而重新安装所有的软件将是一件痛苦的事情。(你的服务器运行 Linux,没有鼠标)。

## 其他花哨的词语

我使用过但几乎不用接触的技术

1.  (数据库) [PostgreSQL](https://www.postgresql.org/) :好看,免费,开源,是一个数据库。Python 的内置 [SQLite](https://www.sqlite.org/index.html) 不能做一些稍微不太基本的事情,太糟糕了。
2.  (键值存储) [Redis](https://redislabs.com/) 不完全是 SQL 数据库。在这个应用程序中,它充当一个队列,这样您的模型就可以与面向 web 的服务器应用程序并行运行。当您的模型完成时,它会让实际的服务器知道。
3.  (网络服务器) [nginx](https://www.nginx.com/) 一个免费的开源网络服务器。Django 也是一个 web 服务器;回想起来,我可能会使用 in。
4.  (托管)[数字海洋](https://www.digitalocean.com/)它就像谷歌云或亚马逊网络服务(AWS)或微软 Azure,但复杂性大大降低。非常容易设置。而且(至关重要的)非常便宜。
5.  (培训)[用于 GPU/TPU 访问的 Google Colab](https://colab.research.google.com/) 和用于支持它的持久存储的 [Google Drive](https://www.google.com/drive/) 。同样,比其他选择便宜得多(我已经花了 300 美元在免费的谷歌云(GCP)上)。注意:我确实花了很多时间在这个上面,但是它的功能就像一个没有任何好的键盘快捷键的 Jupyter 笔记本。所以没什么工作量。

## 二等奖;荣誉奖;H 奖

1.  决定事物实际外观的语言。出于某种原因,设计用户界面(比如网站)的准则[最小惊奇原则](https://en.wikipedia.org/wiki/Principle_of_least_astonishment)并不适用于制作用户界面的语言。
2.  来吧,你知道这个。你以前在 Neopets 或 Myspace 上做过主页,对吗?

好了,是时候开始真正的指导了。这个计划是从结束时的样子到如何开始逆向工作

# 完成的应用程序

最后,你的代码将如何与你的用户联系起来,用户会认为你的网站“哇,太酷了”

你要付钱给某人(很便宜,大概 5 美元/月)让他帮你运行一台电脑。据你所知,这是一台真正的电脑。但实际上它是一台虚拟计算机,这是一个运行在具有 Pinnochio 复合体的真实计算机上的程序(它也认为它是一台真实的计算机)。美就美在无所谓;它很擅长伪装。

不像你的电脑,那台电脑将有一个真正的互联网连接,人们可以找到它。而且它会 24/7 全天候开机,足不出户,不出 wifi 范围。

那台计算机将运行 Docker,Docker 将运行你的代码。你也可以不使用 Docker,直接在电脑上运行,但这很麻烦。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4772d7a367e816df7cc7cc6735deecd2.png)

客户端-服务器架构,又名互联网

好了,你的代码要做什么?互联网上唯一发生的事情就是电脑获取信息,接收信息。就像使用美国邮政署​(USPS)一样,但它没有破产,它以光速加上交通速度移动(总是有交通)。在互联网上,这些消息被称为“数据包”

数据包大致有不同的类型,称为*协议*,就像 USPS 的东西(第一类,垃圾邮件,认证邮件,包裹,媒体邮件等。).现在我们只担心常规的旧 HTTP。你从像[http://哲学家.足球](http://philosophers.football)这样的网址开始就知道的那个。

当有人访问你的网站时,他们会发送一个 HTTP GET 请求,如下图中的#1 所示。简而言之,他们会发送一封邮件,上面写着“请把你的网页发给我。”返回的是一堆要显示的东西(超文本标记语言——HTML),如何显示的指令(层叠样式表——CSS),最重要的是一堆要运行的代码(JavaScript)。浏览器基本上只运行 JavaScript,所以你必须写一些 JavaScript 来运行。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/084a65535fb7ec2ef07b036eb298f885.png)

你的网站拿起“收音机”说“罗杰,200,这是网站。”数字(200)表示“好的”你可能在各种场合都遇到过老好人[404](http://google.com/covfefe)(400 和 500 的意思是:事情不妙,请别烦我)。[代码 418](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/418) “我是一把茶壶”意味着服务器不会煮咖啡,因为它永远是一把茶壶。(说真的。如果是我编的,我现在会站着说话)。

注意到站在你的网站和左边的笔记本电脑之间的那个盒子了吗?这是真正的网络服务器。在工业级应用中,它可以做各种新奇的事情。在我们的例子中,它只是接收消息并决定将它们发送到哪里。就像办公楼里的收发室。我使用了 nginx,但是 Django(见下文)也完全能够做到。我只是不想把所有的前端代码放在后端代码里面。看起来很尴尬。

好了,现在你在别人的笔记本上运行代码了。你被录取了。不要试图对他们的电脑做任何坏事,这是可笑的过度起诉的联邦罪行。(而且浏览器有相当好的安全性;它不会让你**做太多坏事)。你的 JavaScript 代码能做什么?它可以在笔记本电脑上渲染动画,当用户点击页面上的某个地方时,它可以决定做任何它想做的事情,**它可以自己与你的服务器对话。

# 姜戈

很好,现在你知道你的代码将如何运行了。那密码到底是什么?第一部分是服务器。

Django 是 Python 中的一个 web 框架。Django [教程](https://docs.djangoproject.com/en/3.0/intro/tutorial01/)相当不错,所以我不会深入讲解。它是做什么的?

1.  它处理建立数据库(创建表)以及写入和查询它。它构建的抽象非常好,所以您不需要直接编写 SQL 查询(如果您愿意,也可以编写更复杂的查询)。
2.  它处理“服务器端路由”这意味着,例如,如果有人导航到 www.yoursite.com/page1,,他们会得到你决定的第一页应该是什么。相反,如果他们去 www.yoursite.com/page2,,他们会得到别的东西。
3.  它允许您运行 python 代码来决定页面上的内容。例如,如果有人访问某个页面,您可以在数据库中查询他们的用户名,并显示他们的帐户信息(如他们的生日,如果他们之前告诉过您)。
4.  它处理所有的 HTTP 诡计,比如读取传入的消息并发送适当类型的响应。
5.  它还能做很多其他的事情,比如安全、认证等等。

除了普通的 Django 之外,您可能希望建立一个 api 来返回数据*而不是网页。可以用 [djangorestframework](https://www.google.com/search?q=djangorestframework&oq=djangorest&aqs=chrome.1.69i57j0l6j69i60.2185j0j7&sourceid=chrome&ie=UTF-8) 来做这个(教程也挺好的)。这提供了两个关键的扩展:*

1.  **串行化器。**这些将数据从数据库中的数据结构转换成可以发送给浏览器和客户端应用程序的数据结构(通常是 Javascript-object notation — JSON)。
2.  **API 视图**。一个简单的装饰器,用于处理不同类型的 HTTP 请求,比如 GET ("send me some data ")、POST("这里有一些与数据库中已有内容相关的数据"),或者 PUT(" upload/create a whole record to database。")

最后,你可能希望一些事情快点发生。HTTP 协议被设计成每当客户端发送一条消息时,它应该几乎立即得到响应。如果它不发送信息,它就不能接收信息。如果您需要等待,这是一个问题,因为您的模型需要一点时间来处理传入的数据。Websockets 是这方面的一个解决方案,并得到 Django [频道](https://channels.readthedocs.io/en/latest/)的支持(也有很好的教程)。有了 Websockets,你可以随时发送消息,甚至可以发送多条消息。

# 反应

[React](https://reactjs.org/) ,脸书的一个产品,是另一个用于编写在客户端运行的代码的“网络框架”。同样,它有一个很好的教程,所以我不会进入太多的细节。

基本结构是你看到的一切都是一个“组件”组件可以是无状态的,也可以不是。如果是无状态的,它们就像一个函数:它们接受参数并产生一个输出,即一些将由客户端浏览器显示的 HTML。它们也可以是有状态的。有状态对象可以记住事情。例如,如果你正在构建一个棋盘游戏,状态可以是棋盘的位置以及该轮到谁了。

另一件要记住的事情是 [react-router](https://reacttraining.com/react-router/web/guides/quick-start) 提供的“客户端路由”。这样做是为了让你只需要给你的用户发送一页。然后当他们去 www.yoursite.com/page1,时,你的 React 应用程序查看 URL 并决定呈现第 1 页。同样,对于 www.yoursite.com/page2,,他们得到第二页渲染。但是他们不需要每次都与服务器对话:他们只需要得到一个知道查看 URL 并决定显示什么的页面。

# 码头工人

Docker 是我发现最讨厌缠头的技术。我认为这是因为它坚持使用自己的词汇,并且通过不是虚拟机来定义自己,即使它解决了完全相同的问题。

Docker 的要点是,有了这项技术,你可以用代码定义一个你的代码将在其中运行的环境。有点像类固醇的虚拟环境。用简单的英语来说,这些说明可能是这样的:

1.  创建新的“虚拟”计算机
2.  安装 Python 3.6
3.  从我的 Github 库复制我的 Django 代码
4.  运行命令启动 Django 服务器

这些指令放在 Dockerfile 文件中。Docker 文件被构建到 Docker **映像中。**最后,你可以基于这个图像创建一个**容器**。它是运行代码的容器。

Docker 的关键点是这段代码在每台计算机上都是一样的。让你的主机提供商(比如 Digital Ocean)给你一个已经安装了 Docker 的服务器是非常容易的。然后你所要做的就是根据你想要的图像启动一个 docker 容器。

此外,您可能想要一个以上的图像。例如,一个映像可以运行数据库,一个映像可以运行后端服务器,一个映像可以运行前端服务器。

# **Nginx**

我最终使用 Nginx 作为主要的网络服务器。因此,当你访问客户端时,nginx 首先会查看你试图访问的 URL,然后将它路由到 Django,或者提供一组 React 文件来决定客户端路由呈现的内容。

您也可以用 Django 来完成这个任务,这可能会更容易。

# 结论

如果你心中有一个项目,并通过 Django 和 React 教程来完成,你应该会遇到你需要做的其他事情,并能够泰然自若地处理它们。希望这个路线图能给你一个好主意,告诉你从哪里开始!

# 如何使用 Plotly 和 Dash 用 50 行代码构建 Web 应用程序

> 原文:<https://towardsdatascience.com/how-to-build-a-web-based-app-in-50-lines-of-code-using-plotly-and-dash-3953f039b217?source=collection_archive---------19----------------------->

## 构建企业级应用从未如此简单

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8058ff61d4522304ba2b6bd26db77f85.png)

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

有很多工具可以实现数据可视化。然而,很少有工具能够让您轻松构建基于 web 的交互式高质量绘图应用程序,从而将您的数据可视化游戏提升到一个新的水平。

这就是 Plotly 和 Dash 所提供的,全部用 Python 编写。这就是为什么你要 100%了解它!

在本文中,我将展示如何使用 Plotly 创建基本的交互式绘图,以及如何使用 Dash 将它们集成到基于 web 的应用程序中。

使用的数据将是商店的每日销售额,以及 7 天的预测。每日销售数据如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0d845a07f19df29b91c03cfc9449df24.png)

# 1.PLOTLY

Plotly 是一个图形库,可以制作高质量的交互式图形。关键词是**互动**。下面是绘制两行的代码,一行用于每日销售额,另一行用于预测。

```
**#Import plotly** import plotly.graph_objects as go**#Initialize the plot** fig_totalsales=go.Figure()**#Add the lines** fig_totalsales.add_trace(go.Scatter(x=sales[sales.columns[0]], y=sales[sales.columns[1]], visible=True, name='Sales'))fig_totalsales.add_trace(go.Scatter(x=fore['Date'],y=fore[fore.columns[0]],visible=True, name='Forecast'))**#Add title/set graph size** fig_totalsales.update_layout(title = 'Daily Sales', width=850, height=400)fig_totalsales.show()
```

很漂亮吧? ***append.traces*** 函数允许我们轻松地向图形中添加其他线条。

Plotly 提供了更多。在本文中,我将把它留在这里,因为我想更多地关注 Dash。尽管如此,我还是强烈推荐你查看 Plotly 文档:[https://plotly.com/python/](https://plotly.com/python/)。

# 2.破折号

Dash 平台允许我们这些新手开发高质量的企业级分析应用程序,而不需要开发人员、JavaScript 或任何超出基本 Python 技能的东西。

有了 Dash 开源(免费版),Dash 应用可以在本地工作站上运行。你不能分享应用程序本身,但你可以分享代码。

每个完整的 Dash 应用程序都有三个部分:

1.  **布局**,它描述了应用程序的外观。
2.  **Dash 核心组件**(称为 dcc),基本就是应用的内容(图形、下拉菜单、复选框等)。).
3.  **回调**,通过组件之间的交互,使应用程序具有交互性。

下面是创建包含我们之前创建的表的 Dash 应用程序所需的所有代码:

```
**#Import libraries** import dash
import dash_core_components as dcc
import dash_html_components as html**#Create the app** app = dash.Dash()
app.layout = html.Div([
    dcc.Graph(figure=fig_totalsales)
])

app.run_server(debug=True, use_reloader=False)
```

仅此而已!越简单越好。我们看到这个应用程序包含一个布局和一个核心组件,即图。

**html.div** 标签定义了应用程序中的一个新部分,我们可以在其中添加任何我们想要的 Dash 核心组件(dcc。图在这里)。下面是这个“应用程序”现在的样子:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d2cd73e98b0492c2a69cf7f82ba45f90.png)

当然,如果有人想创建一个应用程序,这并不是展示一个单独的情节。任何 python 库都可以做到这一点。Dash 的伟大之处在于,你可以让不同的组件相互交互。这就是 Dash 的第三部分,回调,发挥作用的地方。

回调请求一个输入,让它通过一个函数并给出一个输出。让我们看看如何改进我们当前的应用程序(我们可以做一百万件事情,这里有一些)。

## 最终应用创意

> ***1。添加标题。***
> 
> **2*。添加过滤我们的数字的功能,以便只显示特定日期范围的数据点。***
> 
> ***3。添加一个交互式文本框,显示所选期间的销售总额。***

Dash 有一个核心组件叫做 **DatePickerRange** 。我们所需要的只是一个回调,将图形和文本与这个新的核心组件链接起来。

下面是实现这一点的完整代码。

下面是对代码的逐块描述:

*   第一个 html.div 用于创建标题为应用程序的部分。
*   第二个 html.div 添加了 DateRangePicker 组件以及将通过回调链接到它的两个输出(一个文本元素和一个图形)。
*   最后一部分是回调。它要求两个输入,即两个日期,并给出两个输出,即图形和文本。在 update_output 函数中,根据提供的日期选择数据。然后,计算销售总额并创建数字。

下面是一个简短的视频,展示了这个应用程序现在的样子:

现在你有了它,一个不到 50 行代码的体面的基于 web 的应用程序!查看更多关于 Dash 的信息:[https://dash.plotly.com/](https://dash.plotly.com/)。

非常感谢你的阅读!

# 如何用 Python 构建 Web Scraper

> 原文:<https://towardsdatascience.com/how-to-build-a-web-scraper-in-python-c75563ee60b7?source=collection_archive---------27----------------------->

## 快速抓取、汇总谷歌搜索引擎结果

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bc0a192c647e9243d73f864f93a352ae.png)

照片由[像素](https://www.pexels.com/photo/pattern-branches-tree-design-39494/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels)的[皮克斯拜](https://www.pexels.com/@pixabay?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels)拍摄

# 网页抓取

网络抓取是分析师筛选和收集大量公共数据的绝佳工具。通过使用与讨论主题相关的关键词,一个好的网页抓取器可以非常快速地收集大量数据,并将其聚集成一个数据集。Python 中有几个库使得这一点非常容易实现。在这篇文章中,我将展示一个架构,我一直用它来抓取和总结搜索引擎数据。这篇文章将被分成以下几个部分…

*   链接抓取
*   内容抓取
*   内容总结
*   建设管道

所有的代码都将在这里提供。

# 链接抓取

首先,我们需要一种方法来收集与我们收集数据的主题相关的 URL。幸运的是,Python 库 googlesearch 使得收集响应初始 google 搜索的 URL 变得很容易。让我们构建一个类,使用这个库来搜索我们的关键字,并将固定数量的 URL 附加到一个列表中,以便进一步分析…

# 内容抓取

这可以说是 web scraper 最重要的部分,因为它决定了网页上的哪些数据将被收集。使用 urllib 和 beautiful soup (bs4)的组合,我们能够在链接抓取器类中检索和解析每个 URL 的 HTML。Beautiful soup 让我们指定想要从中提取数据的标签。在下面的例子中,我建立了一个 URL 请求,用 bs4 解析 HTML 响应,并存储在段落(

)标签中找到的所有信息…

# 内容总结

在这里,我们创建了一个文本摘要,它是从驻留在我们的内容抓取器中的每个页面的 HTML 中提取的。为此,我们将使用库的组合,主要是 NLTK。我们生成摘要的方式相对来说很简单,有很多方法可以改进这种方法,但这是一个很好的开始。在对填充词进行一些格式化和无效化之后,单词被标记化并按频率排序,生成一些旨在准确概括文章的句子…

# 建设管道

这是我们把所有东西放在一起的部分。一个类将根据需要实例化每个其他组件的实例,以构建和实现我们的 web scraper。WebScraper 类有几个参数…

*   **搜索** —字符串,搜索引擎查询
*   **n** —整数,要分析的 URL 源的数量
*   **sl**—整数,总结的句子长度
*   **fall_through** — Boolean,是否多线程化进程
*   **Write _ file**—布尔型,将摘要写入文件

现在让我们实例化并运行这个 WebScraper 类的一个实例…

```
Analyst(‘AAPL’, 10, 3, False, False)
```

运行前面的代码会产生以下输出…

```
Analyzing:  http://t1.gstatic.com/images?q=tbn:ANd9GcSjoU2lZ2eJX3aCMfiFDt39uRNcDu9W7pTKcyZymE2iKa7IOVaIAnalyzing:  https://en.wikipedia.org/wiki/Apple_Inc.
Analyzing:  https://www.bloomberg.com/news/articles/2020-08-26/apple-plans-augmented-reality-content-to-boost-tv-video-serviceAnalyzing:  https://www.marketwatch.com/story/apple-stock-rises-after-wedbush-hikes-target-to-new-street-high-of-600-2020-08-26Analyzing:  https://www.marketwatch.com/story/tesla-and-apple-have-had-a-great-run-heres-why-theyre-poised-to-rocket-even-higher-in-the-next-year-2020-08-26Analyzing:  https://finance.yahoo.com/quote/AAPL/Analyzing:  https://seekingalpha.com/article/4370830-apple-sees-extreme-bullishness
Analyzing:  https://seekingalpha.com/news/3608898-apples-newest-street-high-price-target-700-bull-caseAnalyzing:  https://www.marketwatch.com/investing/stock/aaplAnalyzing:  https://stocktwits.com/symbol/AAPLencoding error : input conversion failed due to input error, bytes 0x9D 0x09 0x96 0xA3
encoding error : input conversion failed due to input error, bytes 0x9D 0x09 0x96 0xA3Value Error***For more information you can review our Terms of Service and Cookie Policy.For inquiries related to this message please contact our support team and provide the reference ID below.***URL ErrorValue Error"China remains a key ingredient in Apple's recipe for success as we estimate roughly 20% of iPhone upgrades will be coming from this region over the coming year."
Ives points to recent signs of momentum in China, which he expects will continue for the next six to nine months.
Real-time last sale data for U.S. stock quotes reflect trades reported through Nasdaq only.***By comparison, Amazon AMZN, +0.58% has split its stock three times, rallying an average of 209% the following year.
Apple�s history isn�t quite as stellar as all those, with its four previous splits resulting in an average gain of 10.4% in the following year.
Real-time last sale data for U.S. stock quotes reflect trades reported through Nasdaq only.***The truck and fuel cell maker �could be a major horse in the EV race,� wrote the analyst, while voicing concerns about the stock�s valuation.
stocks edged lower Wednesday, a day after the S&P 500 set its first record close since February, after Federal Reserve officials highlighted the uncertainties facing the economy.
stock-market benchmarks mostly opened higher on Wednesday, pushing the key benchmarks to further records after an economic report came in better than expected.***Apple is the world's largest information technology company by revenue, the world's largest technology company by total assets, and the world's second-largest mobile phone manufacturer after Samsung.
Two million iPhones were sold in the first twenty-four hours of pre-ordering and over five million handsets were sold in the first three days of its launch.
The same year, Apple introduced System 7, a major upgrade to the operating system which added color to the interface and introduced new networking capabilities.***Howley also weighs in on Nintendo potentially releasing an upgraded Switch in 2021.***[Finished in 5.443s]
```

我们已经成功地从关于 AAPL 的热门搜索结果中提取了一些摘要。如控制台输出所示,一些站点阻止了这种类型的请求。然而,这是一个全面的 Python web 抓取入门指南。

# 如何用 Python 构建 wordcloud

> 原文:<https://towardsdatascience.com/how-to-build-a-wordcloud-in-python-2f9222414fc6?source=collection_archive---------39----------------------->

## 一个简单快速的建立文字云的教程

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/c9583479ebfe7dd42336c460655684e9.png)

图片由安吉莉卡·洛·杜卡(作者)提供

在本教程中,我将向你展示如何使用`wordcloud`包在 Python 中构建文本的单词云。

在示例中,我将构建圣奥古斯丁的*忏悔*的词云,可以从[Gutenberg 项目页面](https://www.gutenberg.org/files/3296/3296-h/3296-h.htm)下载。这部杰作被分成 13 本书。我们将每本书存储在不同的文件中,名为 number.text(例如 1.txt 和 2.txt)。每个文件的每一行只包含一个句子。

本教程的源代码可以从[我的 Github 资源库](https://github.com/alod83/papers/tree/master/aiucd2021)下载。

# 入门指南

## 安装并熟悉 wordcloud 软件包

创建 word cloud 的第一步是通过命令`pip install wordcloud`安装 [wordcloud](https://pypi.org/project/wordcloud/) 包。然后你可以导入`WordCloud`这个类以及`STOPWORDS`的列表。

```
from wordcloud import WordCloud, STOPWORDS
```

如果需要,您可以将其他停用字词添加到列表中。

```
stopwords = set(STOPWORDS) 
stopwords.add('thou')
```

`Wordcloud`函数需要一个句子作为输入,其中包含应该计算单词云的所有单词。在我们的例子中,我们应该将杰作的所有文本存储到一个变量中。我们可以通过打开相关文件来读取每本书的文本,并将其存储到一个全局变量中,这个变量叫做`all_text`。

```
all_text = ""
for book in range(1,14):
    file = open('sources/' + str(book) + '.txt')
    lines = file.readlines()

    for line in lines:
        all_text += " " + line
```

# 构建单词云

## 为你的文本创建世界云

现在我们已经准备好构建 wordcloud 了。我们可以创建一个`WordCloud`对象,向它传递单词云的大小、停用词列表、背景颜色和最小字体大小。

```
wordcloud = WordCloud(width = 800, height = 300, stopwords = stopwords,background_color ='white',  min_font_size = 10)
```

一旦构建了`WordCloud`对象,我们就可以调用方法`generate()`来计算作为参数传递的文本的 worcloud。

```
wordcloud.generate(all_text)
```

# 绘图结果

## 将单词云保存到图片中

最后,我们准备绘制结果。我们可以利用`matplotlib`库提供的`imshow()`函数。

```
import matplotlib.pyplot as plt

plt.figure(figsize = (8, 3), facecolor = None) 
plt.imshow(wordcloud) 
plt.axis("off") 
plt.tight_layout(pad = 0) 
plt.savefig('plots/word_cloud.png')
plt.show()
```

# 吸取的教训

用 Python 构建一个文本的单词云非常简单。这可以通过`wordcloud`包完成

*   第一步是定义一个字符串变量,它包含所有需要计算单词云的文本。
*   然后,`Wordcloud`对象可以通过指定一些参数作为实参以及向其方法`generate()`传递文本来定义
*   最后,利用`matplotlib`包可以完成一个 wordcloud 的情节。

# 如何为时尚图像构建人工智能

> 原文:<https://towardsdatascience.com/how-to-build-ai-for-fashion-images-b081311fa099?source=collection_archive---------24----------------------->

## 现实世界中的数据科学

## **为什么每个时尚网站都应该接受机器学习,如何使用分类法和数据,以及如何使用 Flows 构建图像识别系统**

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/10ff85574e406f83d9902d0d79512b14.png)

由[托马斯·塞勒](https://unsplash.com/@jesusance?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/s/photos/shoes?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

在这篇文章中,我将向你展示如何建立你的时尚识别系统。我将重点介绍**鞋类**,不过这种方法也适用于其他服装。这种方法不仅适用于时尚领域。好消息是这个教程是免费的!

**为什么机器学习和时尚?**

有几个原因:更好的用户体验,不断增加的点击率,参与度,收入…这里有一个大的研究,在时尚零售中,每个商店都应该具备的最重要的特征是什么:

*   [https://www.fashion-research.com/top-features](https://www.fashion-research.com/top-features)

正如你所看到的,一些功能纯粹基于机器学习和视觉 AI。因为新冠肺炎的隔离,世界上大多数的时装店都关门了,所以电子商务现在是零售业最重要的部分。如果你有一个时装店网站,那么考虑采用一些机器学习功能。它也可以帮助您的业务!这是改进您的数字产品的最佳时机。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d03b299de7a17e55ada71e46efce3eae.png)

插图由[维塔·瓦尔卡](https://vitavalka.com/)创作

**视觉人工智能在时尚领域最常见的使用案例:**

*   **搜索** : *向你的客户展示最相似的产品*
*   **标记** : *通过更好的分类,让您的产品集合更易于搜索*
*   **抓拍&获取** : *允许您的顾客拍摄服装照片,并在您的店铺中找到它*
*   **虚拟试衣间** : *我穿这件衣服怎么看?*
*   **测脚** : *这双鞋适合我吗?*
*   和许多其他人

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8a0dab8de07ac83a02158af22c2af3dc.png)

最好的功能之一是向您的客户展示视觉上相关的备选方案。这些备选方案可以由预测的标签生成/过滤。

# **分类学**

> 思考分类是最重要的步骤之一!这是一个非常困难的问题!

在开始之前,我们应该定义鞋类识别系统的分类->换句话说,我们想要识别哪种标签。当我们在做鞋的时候,有数千种款式,数百种不同的图案。例如,有适合休闲时间的运动鞋,也有适合跑步的运动鞋。整个鞋类分类可能很复杂,因为我们可以识别**的款式、颜色、品牌、图案、鞋跟尺寸**、…。我们之前说过,仅仅是风格本身就可以有很多选择。**总是从简单的事情开始!**

每当你在有成千上万种选择的领域工作时(时尚、房地产等等),要非常小心。 ***时尚分类的问题在于没有统一的标准*** 。每家服装店都使用不同的名称和分类。看看 urbanoutfitters.com 的 [ASOS](https://www.asos.com/) 网站或者[就知道了。我的建议是不要发明轮子。只要看看一些最著名的服装店,看看他们是怎么做的,就会受到启发。](https://www.urbanoutfitters.com/?ref=logo)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/989d85b05bb906f09ebe0ddec9b4dd3b.png)

优雅的蓝色高跟鞋。[安德鲁·唐劳](https://unsplash.com/@andrewtanglao?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

**风格**:可以说我们可以识别优雅、休闲、运动。如果我们认可优雅,那么我们可以根据性别来划分这个类别。大多数时候,女人优雅的鞋子看起来和男人的有点不同。在休闲类中很难说,在运动/教练类中就更难说了。大多数女性优雅的鞋子也可以通过鞋跟的高度来识别。

**子类**:如果我们认出了优雅的鞋类,那么我们可以说是否有休闲鞋、靴子或高跟鞋。如果我们谈论运动,那么我们可以把它们分为运动鞋,跑步,徒步旅行。

**颜色**:红色、绿色、蓝色、黄色、黑色、白色、橙色……我建议只预测基本颜色。你引入的颜色越多,你的标签和图片就越不一致。用颜色给产品贴标签可能会很棘手!每张图片在不同的屏幕上都会有一点不同。新的 MacBooks 拥有 true tone 技术,可以根据环境照明将显示器的颜色调整为暖色。如果你在一个团队中工作,人们看到的颜色会有点不同。

**品牌**:品牌在一些运动鞋中很容易辨认。阿迪达斯、耐克、彪马运动鞋大部分时间都含有大的标志或其他视觉特征。穿优雅的鞋子会困难得多。也许来自汤米·席尔菲格的优雅的鞋类可能更容易,因为品牌标志几乎总是可以在鞋上看到。

把所有这些放在一起,我们简单的鞋类分类可以写成层次结构,并通过**层次分类**来解决。分级分类意味着我们将调用多个模型,如果我们预测一些标签,我们也可以根据预测的标签调用另一个模型。例如,如果我们预测优雅的标签,那么我们将调用预测鞋跟尺寸的模型。如果我们预测运动品牌,那么我们可以调用其他模型。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0fb0b05a9c59b5284efce19f483286ea.png)

我们对鞋类的简单分类。您可以根据需要以任何方式扩展或调整它。在 Miro 应用程序中绘制。

# **数据和机器学习**

> 机器学习系统对他们看到的数据有偏见。

简单地说,机器学习是一种优化技术,它试图从你的数据中学习重要的知识。

在使用人工智能/机器学习时,思考这一点也是另一个关键步骤。你的系统将仅用于产品照片:背景大部分时间是清晰的,还是照片由专业相机拍摄?那么您的数据集应该包含类似的图像。

如果你正在使用一个移动应用程序来拍摄真实背景下的鞋子图片,那么就在你的数据集中包含这种图片。*获得"* ***真实世界*** *"图片可能会困难得多,但是,如果您的产品能够在"质量较差"的图片上表现良好,它可能会更有价值*。您的应用程序应该在所有可能的环境中工作吗?那么你应该有高质量和平衡的数据集。

我们需要下载我们的数据。我们可以使用谷歌或必应搜索并从图片页面手动下载一些数据。如果你知道如何编程,那么你可以写一个从 google 或 bing 下载图片的脚本。例如,您可以使用 [scrapy](https://scrapy.org/) 库从商店页面抓取图像。对于非编码人员来说,使用 Chrome 或 Firefox 插件从网站上获取图片也是一个很好的选择。

**我们应该为每个标签下载多少张图片?**

关注迭代方法,如果你正在使用[迁移学习](https://www.tensorflow.org/tutorials/images/transfer_learning)技术,每个标签 50 张图像对于开始训练你的模型是相当不错的。如果效果不好,那么继续增加图像的数量。你的分类法越复杂,你需要的图像就越多。有时每个标签需要数百张图像。

# **创建你的模型**

因为这是针对没有机器学习和编程经验的人的教程,所以我们准备用 Ximilar 平台创建一个识别系统。别担心,做起来很容易。

登录 [**Ximilar App**](https://app.ximilar.com/) 然后点击图像识别服务。转到“任务”页面,创建一个新任务。然后选择分类任务,并为该任务创建和连接标签。Task 代表了一个机器学习/深度学习模型。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2e600a4c72eb867516c127438f7696f3.png)

创建标签为优雅、休闲和运动的识别任务/模型。

下一步是训练你的模型。只需点击火车按钮。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/17c929b29df75ca2df636ea3c3f38f60.png)

您的鞋型模型包含三个需要识别的标签/类别。

这样,我们可以为颜色、材料、图案等创建其他任务

**通过流程将您的任务/模型连接到层级**

现在,我们将使用一个创新的功能,允许您通过几次点击将机器学习模型连接到分类/层次结构中。从仪表板转到流服务并创建新的流。然后创建一个“列表操作”作为第一步。然后在带跟任务的*样式*识别任务上添加“分支选择器”。最后,将颜色、类别、性别和品牌任务添加到列表中。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3d571ede2e2cf29c51cc80f4c543262d.png)

建立具有流程的鞋类分级分类系统

**展开**

您的整个系统都部署在一个易于使用的 API 端点和流之后!您可以将移动应用程序或网站连接到 API。**最终的 app 可以是这样的**:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/25755d67943da664fedf9f76e643c579.png)

这是一个[示例](https://demo.ximilar.com/fashion/fashion-tagging),展示了鞋类产品的图像识别是如何工作的。

**总结**

机器学习在零售业无处不在,有助于增加收入和改善用户体验。

*   在构建机器学习系统时,请始终考虑您的分类法和标签。
*   与您的数据和标签保持一致。进行增量开发,从简单的开始,然后继续开发更复杂的解决方案。
*   你可以使用[](https://www.ximilar.com/flows-the-game-changer-for-next-generation-ai-systems/)来构建一个层次分类系统。

查看我们的视觉时尚人工智能系统的 [**演示**](https://demo.ximilar.com/fashion/fashion-tagging) 。如果你想创造一个时尚服装探测器,请看下一篇博文(关于微控制器,但同样适用于时尚):

[](/detecting-microcontrollers-with-cnn-ced688a8a144) [## 用 CNN 检测微控制器

### 根据 Kaggle 竞赛数据检测微控制器的简单教程

towardsdatascience.com](/detecting-microcontrollers-with-cnn-ced688a8a144)

# 如何为 Twitter、Pinterest 和亚马逊构建 AI

> 原文:<https://towardsdatascience.com/how-to-build-ai-for-twitter-pinterest-and-amazon-c3d048c738af?source=collection_archive---------49----------------------->

## 从做过所有(或至少是大部分)事情的人那里得到的教训

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/709f8cf926e7a8f4832323a7817745ac.png)

高耀太科学公司首席执行官道格拉斯·梅森——图片来源:作者

我们采访了 [**道格拉斯·梅森**](https://www.linkedin.com/in/douglas-mason-9a500713/) ,[高耀太科学](https://www.koyotescience.com/)的数据科学家兼首席执行官,他正在建立机器学习模型来预测新冠肺炎疫情。他自由地分享了他从十多年的数据科学工作中学到的智慧和经验,从他在哈佛的博士学位到他在 Pinterest、Twitter 和 AWS(亚马逊)等大公司的时间。

# 道格拉斯的背景

道格拉斯走上了成为数据科学家的独特道路。虽然在成长过程中,计算机一直是他家庭的一部分,但他认为它们很无聊,他告诉家人他将“永远不会学习计算机科学”

相反,道格拉斯去了南加州大学学习电影制作,认为他会跟随他的梦想成为一名电影导演。很快,他意识到电影制作学校并不像他想象的那样,于是他选择了古典吉他。从那里,他意外地发现了对理论物理的热情,他觉得这很迷人(而且报酬比弹吉他高)。

不久之后,道格拉斯发现了自己对数据科学的兴趣,并一路攀升,直到他成为 Twitter、Pinterest 和 AWS 的工程和数据科学团队的负责人。他形容在这个领域工作就像生活在科幻电影里一样。

> “当我从事这类工作时,我感觉自己就像奇异博士——仿佛我在多元宇宙中。你真的可以过瑞克和莫蒂的平行宇宙生活。”

但是道格拉斯并不满足于利用他的专业知识来提高大公司的收入,所以他继续创立了自己的公司,高耀太科学公司。他目前专注于建立新冠肺炎模型来预测疾病爆发。

# 从航运机器学习项目中吸取的经验教训

道格拉斯的成功并非没有一些来之不易的教训。他向我们讲述了他在参与的许多团队和项目中遇到的一些挑战。

# 第一课:使用机器学习与用户合作,而不是接管

在推特上,道格拉斯制作了一个名为“关注谁”的专题。这为 Twitter 用户提供了个性化的推荐,告诉他们哪些账户可能会让他们感兴趣。作为一名数据科学家,道格拉斯发现人们大量使用这一功能。起初,它似乎很棒——人们几乎追随了它推荐的每一个人。但从长远来看,使用这一功能的人访问 Twitter 的次数更少了。

他们的订阅源充满了由算法选择的推文,而不是他们自己选择的人的推文,这些推文实在是太多了。

通过减少“跟随谁”的建议数量,道格拉斯提高了**的长期**参与度。

众所周知,长期目标和短期目标经常发生冲突,但道格拉斯在这里发现了更深刻的教训。随着机器学习解决方案变得越来越强大,使用它们做太多事情往往很有诱惑力。这几乎总是一个错误。道格拉斯说:

> *“我的目标是打造与用户一起工作的产品,而不是试图取代用户。”*

科幻小说中描绘的人工智能——具有人类水平的智能——可能是许多人试图用机器学习做太多事情的原因。在许多情况下,它最好用于增强人类的行动,而不是取代它们。

# 第二课:数据管道和好的工程比数学和算法更重要

人们对新的机器学习算法感到非常兴奋。首先,我们有神经网络(NNs),然后是卷积神经网络(CNN),然后是生成对抗网络(GANs),变压器,等等。谈论和探索算法是有趣和令人兴奋的。

但是道格拉斯,一个自称的数学呆子,已经知道数学和算法往往会得到太多的关注,而真正的成功来自于**好的数据,好的工程,专注于客户的问题,**和**不被数学所困。**他说:

> “算法能产生不同的结果是非常非常罕见的。几乎总是数据管道。在我的工作中,我已经能够通过数据管道减少 90%的错误,相比之下,通过更好的算法可以减少 75%。然而,每个人都想和我谈论算法,但没有人想谈论数据管道。”

我们使用隐喻将机器学习算法与神经科学家联系在一起,将数据管道与管道联系在一起,因此哪个引起普遍关注并不奇怪。道格拉斯通过专注于机器学习不那么迷人的方面获得了成功。在大多数情况下,决定**使用什么数据**以及**如何将其呈现给算法**比算法本身更重要。

## 关注客户的目标

如今,许多“人工智能初创公司”谈论的更多的是他们提供的解决方案,而不是他们解决的问题,道格拉斯已经学会了保持对客户目标的高度关注。有时这意味着将自己从机器学习更具吸引力的理论方面抽离出来。他说:

> “作为一名数学家,我热爱数学的所有细微差别,很容易迷失其中。但事实是,有无穷多的数学有待学习。在专注于客户目标之前,把自己关在房间里学习所有的数学知识是不可行的。”

许多数据科学家不想听到的事实是,成功的机器学习解决方案通常不是关于创造新的、强大的和令人兴奋的东西。更多的时候,你需要的是从正确的角度看问题,并使用屡试不爽的方法。

## 与经验丰富的工程师一起工作并向他们学习

道格拉斯亲自设计了许多成功的机器学习解决方案,并领导了软件工程师团队,但他对自己的工程能力保持谦虚,并强调了**固体工程** 的[重要性。](https://datarevenue.com/en-blog/hiring-machine-learning-engineers-instead-of-data-scientists)

> *“在亚马逊,我让工程师做尽可能多的事情,因为他们在工程方面比我强。我很想给你另一个答案,但他们很有效率,他们很有想法,他们以前见过这些结构,所以他们知道实现细节。”*

然而,这并非一帆风顺。道格拉斯承认让不同的专家一起工作的困难,特别是当高技术人员往往对微小的决定有非常强烈的意见时。

他发现的让所有人达成一致的最好方法是不断发布最小可行产品(MVP ),这将带我们进入下一课。

# 教训 3:总是构建最小可行产品(MVP)

Douglas 对 MVP 深信不疑,MVP 展示了解决方案的核心部分,即使缺少许多功能。在开发机器学习解决方案时,他的目标是每周交付一个新的 MVP ****

他用这些来:

*   **避免陷阱:**如果一个项目耗时太长,构建 MVP 的难度甚至可以用来证明该项目应该在多年的努力付诸东流之前尽早结束。道格拉斯说:

> “如果事情变得更加困难,而我继续做 MVP,却从未达到目标,那么这就给了我们关于我们试图做的事情的难度的信息。”

*   **沟通**:无论是技术人员还是非技术人员,都倾向于更好地理解他们能看到和使用的东西,而不是抽象的想法。

“人们对事物抽象概念的反应,往往与他们看到真实事物时的反应完全不同。这就是为什么我总是推出 MVP。从更高层次的角度看问题的人可以获得必要的直觉,给我反馈。”

浪费两周的工作总比浪费两个月要好,MVP 可以帮助你做到这一点。

MVP 还有其他好处。通过发布解决方案的精简版本,道格拉斯经常发现少即是多。

> “你最终交付的东西通常比你最初打算做的要简单得多,但它是精炼的。”

当然,当事实证明最佳解决方案是最简单的解决方案时,客户有时会不高兴。道格拉斯将构建机器学习解决方案比作创造艺术:这是关于投入开发的时间,而不是最终产品所需的努力。

> *“有一个经典的禅宗故事,讲的是一个国王雇佣了一位艺术家。这位艺术家工作了一年,但只用了三秒钟就完成了最后一幅画。当国王抱怨时,艺术家说,“哦,我花了一年时间试图画更难的东西。””*

MVP 让你能够找到更好、更简单的**解决方案,即使是在开发过程的后期,保持敏捷是很重要的,这样你就可以在必要时转向这些更好的解决方案。**

人们经常认为某件事必须变得复杂才能变得强大,但事实上恰恰相反。

# 第四课:控制和精度比大小和力量更重要

大型机器学习模型,如 GPT-3,令人兴奋,经常成为头条新闻。但是道格拉斯将大型模型与早期(失败的)建造飞机的尝试相比较。这些飞机与莱特兄弟制造的著名的、成功的飞机竞争。是什么让他们与众不同?莱特兄弟专注于**控制**、****而他们的竞争对手则追求**规模和力量。**

> 莱特兄弟的独创性在于他们没有追求更大的引擎。他们是自行车修理工。他们甚至没有使用大功率发动机。相反,他们关注的是控制。”

这类似于机器学习模型。正如道格拉斯所说:

> “我们做了一个最大的模型,可以做所有这些事情。但人们会问,‘我该如何解读这些东西?’“我怎么控制它,”我如何确保我的模型不会出轨?”

大型机器学习模型可能通常更强大,但除非它们解决了真正的问题,否则它们没有用。如果一个模型不可预测地产生惊人的结果**并且只是在某些时候产生**,那就没用了。如果一个模型产生准确的结果,但我们不明白为什么,也不能确定结果是否总是准确的,那么这也是没有用的。****

****相反,更小、更简单、功能更弱的模型提供了更多的可解释性和 T2 一致性,在几乎所有情况下都更有价值。就像飞行一样,我们需要能够驾驶和着陆,而不仅仅是快速飞行。****

# ****成功运送机器学习项目****

****在我们与道格拉斯的交谈中,他分享了许多经验教训,但这些是他成功推出机器学习解决方案的最重要规则:****

*   ****使用机器学习**与**用户合作:不要超越并试图接管他们。****
*   ****多关注**问题、数据、**和**工程**而不是数学和新颖的算法。****
*   ****专注于**控制**你产生的解决方案,而不是让它尽可能的宏大。****
*   ******制造 MVP**和**定期运送较小的零件。即使他们没有所有的功能,紧密的反馈循环在这里比在软件工程中更重要。******

****我们(数据营收)已经出货了几十个成功的项目。如果你需要帮助,不要犹豫,与[联系](https://datarevenue.com/en-contact)。****

# 如何使用 SQLite 构建会计系统

> 原文:<https://towardsdatascience.com/how-to-build-an-accounting-system-using-sqlite-2ce31f8b8652?source=collection_archive---------3----------------------->

## 逆向工程 Xero 教 SQL

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/96f7af9ba081102cedb941f0a43f6eef.png)

在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上[科学高清](https://unsplash.com/@scienceinhd?utm_source=medium&utm_medium=referral)拍摄的照片

***搔自己的痒处。***

这是每当有人问我如何学习编程时,我总是给出的建议。实际上,这意味着你必须解决与你相关的事情或选择与你相关的项目——无论是在你的工作还是个人生活中。

盲目地去 Youtube 上的教程,阅读编程书籍,从 Reddit 帖子上复制代码等等。如果你开始学习编程,将一事无成。

# 学习 SQL 的最好方法

在这篇文章中,我将向您展示如何使用 SQLite 构建一个简单的会计数据库。

> 那么,为什么要创建一个会计数据库呢?为什么不直接复制公共数据,把它们推到 SQLite 中,然后从那里开始练习呢?

原因是创建一个会计数据库已经足够先进,可以涵盖数据库和 SQL 的所有方面——从查询到连接到视图和 cte。

作为一名会计出身的人,我认为这是学习 SQL 的最佳项目。毕竟编程是解决问题的工具。因此,不妨“解决”一个难点来全面学习 SQL。

通过观察 Xero 的工作方式,我获得了使用 SQL 创建会计系统的灵感。对于不熟悉的人来说,Xero 是一款起源于新西兰的云记账软件。它现在已经扩展到澳大利亚、美国、加拿大和英国。

Xero 的好处是它有一个漂亮干净的界面和许多可供选择的应用程序来扩展它的功能。

*免责声明:我不是 Xero 的工程师或开发人员,这些观察可能不完全符合系统的工作方式,因为它总是在更新。当然,这里给出的 SQL 并不是 Xero 使用的 SQL 设计,因为他们的系统需要扩展。但这是一个非常有趣的项目,所以让我们做吧!*

# 会计 101

在你兴奋过度之前,我们先来上一堂会计速成课。

基本的会计等式是

***资产=负债+权益***

这个等式基本上有三个部分

*   资产是实体的所有资源。
*   负债是公司所欠的。
*   而股权,是所有所有者的投资、图纸、盈利或亏损的积累。

右边描述了资产的融资方式——通过负债或权益。

我们可以扩展上面的等式来分解股权

***资产=负债+期初权益+收入—费用***

这 5 个账户——资产、负债、权益、收入和费用——是会计系统中常见的账户类型。

然后是借贷的概念。我可以继续深入讨论这两个问题,但在这篇文章中,你需要知道的是,在每笔交易中:

***借方=贷方***

这两个等式通常支配着整个会计周期中发生的事情。这两个等式也将作为创建我们自己的会计数据库的指南。

> 作为一名会计出身的人,我认为这是学习 SQL 的最佳项目。毕竟编程是解决问题的工具。因此,不妨“解决”一个难点来全面学习 SQL。

# Xero 的会计实现

需要记住的重要一点是,Xero 的设计是为了让它在企业的日常运营中对企业主(而不是会计)有用。

*因此,它围绕交易周期和内部控制进行设计。*

## 交易周期

基本交易周期如下

*   销售周期
*   采购周期
*   资金周转周期

Xero 按如下方式实现这些循环

**销售周期** 销售使用发票输入 Xero。想象一下企业为销售(现金销售或赊账)开具实际的纸质发票。这正是 Xero 想要复制的东西。

发票可以直接从软件中打印出来,并按升序自动编号。

*在引擎盖下,发票增加销售账户和应收账款(AR)账户。*

**采购周期** 票据进入 Xero 使用票据。再一次,想象企业为购买(现金购买或赊账)出具实际的账单。这是公用事业和库存的通常情况。这也是 Xero 想要复制的东西。

这些账单可以直接从软件中打印出来,并可用于补充企业完成的任何审批程序。

*在这个引擎盖下,账单增加了采购账户和应付账款(AP)账户。*

**现金周期** 这涉及所有与现金有关的交易。有 4 种类型

*   **发票付款** —未付发票的付款
*   **账单支付** —未支付账单的支付
*   **收到的款项** —不是发票付款的现金收据。这可能涉及现金销售,但如果你要开发票,请使用发票功能。
*   **支出款项** —不属于票据支付的现金支出。这可能涉及现金购买,但如果你要开账单,使用账单功能。

这是关于交易周期的部分。

## 内部控制

对于内部控制,你需要了解**系统账**的概念。

Xero 有一篇理解系统账户的综合文章[在这里](https://central.xero.com/s/article/Locked-and-system-accounts-in-your-chart-of-accounts)。但出于我们的目的,我们将只讨论以下系统帐户

*   应收帐款
*   应付账款
*   银行账户(链接到银行馈送)

这些科目不能用在手动日记帐中。这意味着 Xero 希望您使用发票、账单和现金交易(发票支付、账单支付、收到的钱和花费的钱)来支持这些账户的余额。如果你愿意,这是 Xero 内部控制的实施。

当然,您可以通过在会计科目表(COA)中创建 AR、AP 和银行帐户来使用它们的非系统版本。但是,您不能对它们使用 AR、AP 和银行帐户类型。

> 需要记住的重要一点是,Xero 的设计是为了让它在企业的日常运营中对企业主(而不是会计)有用。

# 警告:我们不会掉进兔子洞

设计一个账户是非常复杂的。光是这个话题就需要多篇博文。因此,为了简单起见,我们将创建以下假设(不完全是 Xero 如何实现这些)

*   **发票和账单支付** 发票支付可以一次性支付两张或多张发票*。也就是说,我们不允许部分付款。账单支付也是如此。*
*   ***库存** 我们不打算在这里使用库存项目。对于销售或采购,我们将直接使用库存帐户,而不是创建映射到库存帐户的库存项目。*

*我们的假设就是这样。设计完我们的数据库后,读者可以解除这些假设,尽可能多地模仿 Xero。*

# *SQL 基础知识*

*现在,在重建我们版本的 Xero 数据库结构之前,让我们先来上一堂数据库速成课。*

***数据库是表的集合。**每个表都由称为**记录**的数据行组成。这些列被称为**字段**。*

*处理数据库的程序被称为数据库管理系统或 DBMS。打个简单的比方,DBMS 之于 Excel 程序,数据库之于 Excel 工作簿,表格之于 Excel 工作表。*

*数据库和 Excel 工作簿有两个主要区别。*

## *数据表示与数据存储是分开的。*

*也就是说,您不能通过直接查看数据并对其进行编辑来编辑数据库中的数据。(其他 DBMS 程序有 GUI,允许您直接访问数据库中的数据,并像编辑电子表格一样编辑它。但是在幕后,该操作发出一个 SQL 命令)。*

## *表通常相互链接以形成关系。*

*关系可以是一对一、一对多或多对多。*

***一对一**关系意味着“一个表中的一行只与另一个表中的一行相关,反之亦然”。一个例子是雇员姓名到纳税标识号。*

*这种类型通常包含在单个表 Employees 中,因为将数据分成两个表并没有什么好处。*

***一对多**表示“一个表格中的一行只与另一个表格中的一行或多行相关,而不是相反”。一个例子是发票到发票行。一张发票可以有多个行,但一个发票行只属于一张特定的发票。*

*您可能已经猜到了,**多对多**意味着“一个表行只与另一个表中的一行或多行相关,反之亦然”。实现部分支付的系统就是一个例子。*

*一张发票可以通过不同的付款交易来部分支付,并且一次付款可以部分支付不同的发票。*

***数据库如何知道这些关系?** 很简单。它是通过使用主键和外键实现的。*

***主键**是区分不同行所必需的。它们唯一地标识表中的每一行数据。*

***另一方面,外键**是另一个表的主键。因此,通过关联主键和外键,数据库关系得以保持。*

**对于一对多,“一”方包含主键,“多”方包含该主键作为其外键。*在上面的例子中,为了获得属于一张发票的所有行,我们查询 InvoiceLines 表,其中外键等于特定的发票号。*

**对于多对多,通过使用称为“联接”表的第三个表,关系被分解为两个一对多关系。*例如,我们的部分付款系统将发票表、付款表和 InvoicePayments 表作为连接表。InvoicePayments 表的主键将是一个组合键,由 Invoices 和 Payments 表的主键组成,如下所示*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7c1963b7fa68f88131987a65f8229fc5.png)*

*用于实施部分发票付款的表*

*请注意,连接表不包含任何其他数据,因为除了连接发票和付款表之外,它没有任何其他用途。*

*为了获得某个支付交易支付的发票,比如说`PAY 1`,我们通过连接表连接发票和支付表,并查询`payment_id = “PAY 1”`。*

*这就是数据库的基础知识。我们现在准备设计我们的数据库。*

> *打个简单的比方,DBMS 之于 Excel 程序,数据库之于 Excel 工作簿,表格之于 Excel 工作表。*

# *设计我们的 Xero 实现*

*现在我们对 Xero 有了基本的了解,可以开始创建它的数据库结构的草图了。请注意,我将使用`Table_Name`格式。这是由下划线分隔的首字母大写单词。我还将对表名使用复数名称。*

*对于销售周期,我们将有以下表格*

*   ***发票***
*   ***客户** —一个客户可以有多张发票,但一张发票不能属于多个客户*
*   ***Invoice_Payments** —记住我们现在的假设,Invoice_Payments 和 Invoices 分别是一对多的关系(没有部分付款)*
*   ***Invoice_Lines** —这是发票和 COA 之间的连接表。一个账户可以出现在多张发票中,一张发票可以有多个账户。*
*   ***会计科目表(COA)***

*对于购买周期,我们将有以下表格*

*   ***票据***
*   ***供应商** —一个供应商可以有多个票据,但是一个票据不能属于多个供应商*
*   ***Bill_Payments** —记住我们现在的假设,Bill_Payments 和 Bill 之间分别是一对多的关系*
*   ***Bill_Lines** —这是票据和 COA 的连接表。一个账户可以出现在多张票据中,一张票据可以有多个账户。*
*   ***COA** —与销售周期中的上述内容相同。这里只是为了完整性。*

*对于现金周期,我们将有下面的表(我们已经在上面创建的付款表)*

*   ***Received _ money**——可能有一个可选客户*
*   ***Received_Money_Lines** —这是 Received_Money 和 COA 之间的连接表*
*   ***spend _ money**—可能有一个可选的供应商*
*   ***支出款项行** —这是支出款项和 COA 之间的连接表*

*从概念上讲,我们的数据库结构如下*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/45a09948406408a2aed677edd0ce171c.png)*

*会计数据库模型*

*这个图用数据库的说法叫做**实体关系图**或者 **ERD** 。一对多关系由*1-M*指定,多对多关系由*M-M*指定。*

*上图中没有显示连接表,因为它们隐含在具有多对多关系的表中。*

# *用 SQL 实现我们的版本*

*现在是时候用 SQL 实现我们的模型了。我们先从定义一些约定开始。*

*主键的字段/列名为`id`,外键的格式为`table_id`,其中`table`是单数形式的“多”方的表名。例如,在发票表中,外键将是`customer_id`。*

*SQL 代码的时间到了。在这里。*

```
*DROP TABLE IF EXISTS `COA`;CREATE TABLE IF NOT EXISTS `COA` (
    id INTEGER PRIMARY KEY,
    name TEXT
);DROP TABLE IF EXISTS `Customers`;CREATE TABLE IF NOT EXISTS `Customers` (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    contact_person TEXT,
    email TEXT,
    phone TEXT,
    fax TEXT,
    address TEXT
);DROP TABLE IF EXISTS `Invoice_Payments`;CREATE TABLE IF NOT EXISTS `Invoice_Payments` (
    id INTEGER PRIMARY KEY,
    tran_date DATE NOT NULL,
    description TEXT,
    reference TEXT,
    total DECIMAL(20,2) NOT NULL,
    coa_id INTEGER NOT NULL, -- automatically Bank
    FOREIGN KEY(`coa_id`) REFERENCES `COA`(`id`)
);DROP TABLE IF EXISTS `Invoices`;CREATE TABLE IF NOT EXISTS `Invoices` (
    id INTEGER PRIMARY KEY,
    tran_date DATE NOT NULL,
    due_date DATE,
    description TEXT,
    reference TEXT,
    total DECIMAL(10,2) NOT NULL,
    status BOOLEAN,
    customer_id INTEGER,
    invoice_payment_id INTEGER,
    coa_id INTEGER NOT NULL, -- automatically AR
    FOREIGN KEY(`customer_id`) REFERENCES `Customers`(`id`),
    FOREIGN KEY(`invoice_payment_id`) REFERENCES `Invoice_Payments`(`id`),
    FOREIGN KEY(`coa_id`) REFERENCES `COA`(`id`)
);DROP TABLE IF EXISTS `Received_Moneys`;CREATE TABLE IF NOT EXISTS `Received_Moneys` (
    id INTEGER PRIMARY KEY,
    tran_date DATE NOT NULL,
    description TEXT,
    reference TEXT,
    total DECIMAL(20,2) NOT NULL,
    customer_id INTEGER,
    coa_id INTEGER NOT NULL, -- automatically Bank
    FOREIGN KEY(`customer_id`) REFERENCES `Customers`(`id`),
    FOREIGN KEY(`coa_id`) REFERENCES `COA`(`id`)
);DROP TABLE IF EXISTS `Invoice_Lines`;CREATE TABLE IF NOT EXISTS `Invoice_Lines` (
    id INTEGER PRIMARY KEY,
    line_amount DECIMAL(20,2) NOT NULL,
    invoice_id INTEGER,
    line_coa_id INTEGER NOT NULL,
    FOREIGN KEY(`invoice_id`) REFERENCES `Invoices`(`id`),
    FOREIGN KEY(`line_coa_id`) REFERENCES `COA`(`id`)
);DROP TABLE IF EXISTS `Received_Money_Lines`;CREATE TABLE IF NOT EXISTS `Received_Money_Lines` (
    id INTEGER PRIMARY KEY,
    line_amount DECIMAL(20,2) NOT NULL,
    received_money_id INTEGER,
    line_coa_id INTEGER NOT NULL,
    FOREIGN KEY(`received_money_id`) REFERENCES `Received_Moneys`(`id`),
    FOREIGN KEY(`line_coa_id`) REFERENCES `COA`(`id`)
);DROP TABLE IF EXISTS `Suppliers`;CREATE TABLE IF NOT EXISTS `Suppliers` (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    contact_person TEXT,
    email TEXT,
    phone TEXT,
    fax TEXT,
    address TEXT
);DROP TABLE IF EXISTS `Bill_Payments`;CREATE TABLE IF NOT EXISTS `Bill_Payments` (
    id INTEGER PRIMARY KEY,
    tran_date DATE NOT NULL,
    description TEXT,
    reference TEXT,
    total DECIMAL(20,2) NOT NULL,
    coa_id INTEGER NOT NULL, -- automatically Bank
    FOREIGN KEY(`coa_id`) REFERENCES `COA`(`id`)
);DROP TABLE IF EXISTS `Bills`;CREATE TABLE IF NOT EXISTS `Bills` (
    id INTEGER PRIMARY KEY,
    tran_date DATE NOT NULL,
    due_date DATE,
    description TEXT,
    reference TEXT,
    total DECIMAL(10,2) NOT NULL,
    status BOOLEAN,
    supplier_id INTEGER,
    bill_payment_id INTEGER,
    coa_id INTEGER NOT NULL, -- automatically AP
    FOREIGN KEY(`supplier_id`) REFERENCES `Suppliers`(`id`),
    FOREIGN KEY(`bill_payment_id`) REFERENCES `Bill_Payments`(`id`),
    FOREIGN KEY(`coa_id`) REFERENCES `COA`(`id`)
);DROP TABLE IF EXISTS `Spent_Moneys`;CREATE TABLE IF NOT EXISTS `Spent_Moneys` (
    id INTEGER PRIMARY KEY,
    tran_date DATE NOT NULL,
    description TEXT,
    reference TEXT,
    total DECIMAL(20,2) NOT NULL,
    supplier_id INTEGER,
    coa_id INTEGER NOT NULL, -- automatically Bank
    FOREIGN KEY(`supplier_id`) REFERENCES `Suppliers`(`id`),
    FOREIGN KEY(`coa_id`) REFERENCES `COA`(`id`)
);DROP TABLE IF EXISTS `Bill_Lines`;CREATE TABLE IF NOT EXISTS `Bill_Lines` (
    id INTEGER PRIMARY KEY,
    line_amount DECIMAL(20,2) NOT NULL,
    bill_id INTEGER,
    line_coa_id INTEGER NOT NULL,
    FOREIGN KEY(`bill_id`) REFERENCES `Bills`(`id`),
    FOREIGN KEY(`line_coa_id`) REFERENCES `COA`(`id`)
);DROP TABLE IF EXISTS `Spent_Money_Lines`;CREATE TABLE IF NOT EXISTS `Spent_Money_Lines` (
    id INTEGER PRIMARY KEY,
    line_amount DECIMAL(20,2) NOT NULL,
    spent_money_id INTEGER,
    line_coa_id INTEGER NOT NULL,
    FOREIGN KEY(`spent_money_id`) REFERENCES `Spent_Moneys`(`id`),
    FOREIGN KEY(`line_coa_id`) REFERENCES `COA`(`id`)
);*
```

*这里有几件事:*

*   *SQL 命令不区分大小写,`CREATE TABLE`与`create table`相同*
*   *`IF EXISTS`和`IF NOT EXISTS`是可选的。我只是用它们来防止我的 SQL 命令中的错误。例如,如果我删除一个不存在的表,SQLite 会给出一个错误。此外,我将`IF NOT EXISTS`放在 create table 命令上,这样我们就不会意外地覆盖任何现有的表。*
*   *小心使用`DROP TABLE`命令!它将删除一个现有的表,而不发出警告,即使它有内容。*
*   *表名也可以全部大写或不大写。如果表名有空格,应该用反斜杠(`)括起来。它们不区分大小写。`SELECT * FROM Customers`与`select * from customers.`相同*

*尽管 SQL 在语法方面有些宽松,但是您应该努力保持 SQL 代码一致性。*

*还要注意上面 ERD 中显示的关系。还要记住,外键位于多侧。*

*顺序很重要,因为由于外键的存在,一些表会成为另一个表的依赖项。例如,您必须先在发票表之前创建 first Invoice_Payments,因为前者是后者的依赖项。这里的技巧是从 ERD 的边缘开始,因为这些边缘具有最少的外键。*

*您还可以下载一个 SQLite 中的示例数据库,这个[链接](https://github.com/kennethjhim/medium_acctg_database_design/blob/master/db_blank.db)中没有任何内容。*

*要查看它,您可以使用免费的开源 SQLite 浏览器。在这里下载!*

# *向我们的数据库添加内容*

*现在我们有了示例数据库,让我们向它输入数据。样本数据可以从[这里](https://github.com/kennethjhim/medium_acctg_database_design/blob/master/new_data-services.xlsx)下载——只需根据需要将其分解为 CSV。*

*请注意,学分显示为正数,学分显示为负数。*

*对于这篇文章,我只是使用了 DB Browser 的导入功能从上面的 Excel 文件中导入 CSV。例如,导入 *Customers.csv**

*   *选择“客户”表*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/85eb036e1d61675334837288d916ebee.png)*

*   *转到文件>导入> CSV 文件中的表格,并选择*客户. csv**

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e6e4a79a62a6cb5de188ffbbd94dc6c8.png)*

*   *对于所有后续提示,单击“确定/是”以导入数据。*

*如果您发出下面的 SQL 命令,它应该显示我们数据库中的所有客户*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fa66d391e67bed97e0796e80ea6d646c.png)*

# *从我们的数据库创建财务报告*

*为了证明我们的数据库作为一个粗略的会计系统工作,让我们创建试算平衡表。*

*第一步是为我们的发票、账单、Received _ Moneys 和 Spent _ Moneys 事务创建事务视图。代码将如下所示*

```
*DROP VIEW IF EXISTS Invoice_Trans;CREATE VIEW IF NOT EXISTS Invoice_Trans ASwith recursiveitrans as (SELECT
    'INV'||i.id as `tran_id`,
    i.tran_date,
    i.coa_id as ar_account,
    -- ABS(total) as `total`,
    'Accounts Receivable' as `coa_name`,
    i.total,
    il.id  as `line_id`,
    il.line_coa_id,
    il.line_amount,
    ip.id,
    ip.coa_id as bank_account,
    'Business Bank Account' as `bank_name`,
    i.status
from Invoices as i
left join Invoice_Lines as il on i.id = il.invoice_id
left join COA as c on i.coa_id = c.id
left join Invoice_Payments as ip on i.invoice_payment_id = ip.id
)select
itrans.*,
c.name as `line_coa_name`
from itrans
left join COA as c on itrans.line_coa_id = c.id;SELECT * from Invoice_Trans;********************************************************************DROP VIEW IF EXISTS Bill_Trans;CREATE VIEW IF NOT EXISTS Bill_Trans ASwith recursivebtrans as (SELECT
    'BILL'||b.id as `tran_id`,
    b.tran_date,
    b.coa_id as ap_account,
    -- ABS(total) as `total`,
    'Accounts Payable' as `coa_name`,
    b.total,
    bl.id  as `line_id`,
    bl.line_coa_id,
    bl.line_amount,
    bp.id,
    bp.coa_id as bank_account,
    'Business Bank Account' as `bank_name`,
    b.status
from Bills as b
left join Bill_Lines as bl on b.id = bl.bill_id
left join COA as c on b.coa_id = c.id
left join Bill_Payments as bp on b.bill_payment_id = bp.id
)select
btrans.*,
c.name as `line_coa_name`
from btrans
left join COA as c on btrans.line_coa_id = c.id;SELECT * from Bill_Trans;********************************************************************DROP VIEW IF EXISTS Received_Money_Trans;CREATE VIEW IF NOT EXISTS Received_Money_Trans AS
SELECT
    'RM'||rm.id as `tran_id`,
    tran_date,
    coa_id,
    'Business Bank Account' as `coa_name`,
    total,
    rml.id  as `line_id`,
    rml.line_coa_id,
    c.name as `line_coa_name`,
    rml.line_amount
from Received_Moneys as rm
left join Received_Money_Lines as rml on rm.id = rml.received_money_id
left join COA  as c on c.id = rml.line_coa_id;SELECT * from Received_Money_Trans;********************************************************************DROP VIEW IF EXISTS Spent_Money_Trans;CREATE VIEW IF NOT EXISTS Spent_Money_Trans AS
SELECT
    'SM'||sm.id as `tran_id`,
    tran_date,
    coa_id,
    'Business Bank Account' as `coa_name`,
    total,
    sml.id  as `line_id`,
    sml.line_coa_id,
    c.name as `line_coa_name`,
    sml.line_amount
from Spent_Moneys as sm
left join Spent_Money_Lines as sml on sm.id = sml.spent_money_id
left join COA  as c on c.id = sml.line_coa_id;SELECT * from Spent_Money_Trans;*
```

*在前两条语句中,我使用了 CTE(带有关键字`recursive`)。cte 很有用,因为我将 4 个表组合在一起,以获得发票交易和相应付款的单一视图。你可以在 SQLite [这里](https://sqlite.org/lang_with.html)了解更多关于 CTEs 的内容。*

*执行上述命令后,您的数据库应该有以下 4 个视图。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6392d502d8edfe4925afc1333e306731.png)*

*交易视图*

*最后,我们创建试算平衡表(简称 TB)的代码。请注意,TB 只是我们的交易余额的集合,记录了我们在设计数据库时制定的规则。*

*代码如下所示*

```
*DROP VIEW IF EXISTS Trial_Balance;
CREATE VIEW IF NOT EXISTS Trial_Balance as
-- CREATE TB
-- select all sales
select
    line_coa_id as acct_code,
    line_coa_name as acct_name,
    (case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as debit_bal,
    (case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as credit_bal
from Invoice_Trans
group by line_coa_id-- select all purchases
union allselect
    line_coa_id as acct_code,
    line_coa_name as acct_name,
    (case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as debit_bal,
    (case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as credit_bal
from Bill_Trans
group by line_coa_id-- select all received money
union allselect
    line_coa_id as acct_code,
    line_coa_name as acct_name,
    (case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as debit_bal,
    (case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as credit_bal
from Received_Money_Trans
group by line_coa_id-- select all spent money
union allselect
    line_coa_id as acct_code,
    line_coa_name as acct_name,
    (case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as debit_bal,
    (case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as credit_bal
from Spent_Money_Trans
group by line_coa_id-- select all AP
union allselect
    ap_account as acct_code,
    coa_name as acct_name,
    -(case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as debit_bal,
    -(case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as credit_bal
from Bill_Trans
where status = "0"-- select all AR
union allselect
    ar_account as acct_code,
    coa_name as acct_name,
    -(case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as debit_bal,
    -(case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as credit_bal
from Invoice_Trans
where status = "0"-- select all bill_payments
union allselect
    bank_account as acct_code,
    bank_name as acct_name,
    -(case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as debit_bal,
    -(case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as credit_bal
from Bill_Trans
where status = "1"-- select all invoice_payments
union allselect
    bank_account as acct_code,
    bank_name as acct_name,
    -(case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as debit_bal,
    -(case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as credit_bal
from Invoice_Trans
where status = "1"-- select all received_money
union allselect
    coa_id as acct_code,
    coa_name as acct_name,
    -(case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as debit_bal,
    -(case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as credit_bal
from Received_Money_Trans-- select all spent_money
union allselect
    coa_id as acct_code,
    coa_name as acct_name,
    -(case when sum(line_amount) < 0 then sum(line_amount) else 0 end) as debit_bal,
    -(case when sum(line_amount) > 0 then sum(line_amount) else 0 end) as credit_bal
from Spent_Money_Transorder by acct_code*
```

*上面的代码包含由命令`union all`连接的多个 SQL 查询。我已经对每个查询进行了注释,以显示每个查询试图实现的目标。*

*例如,第一个查询试图获取发票交易的所有信用(主要是销售额)。第二个用于账单交易(主要是购买)的借项等等。*

*执行它应该会产生下面的 TB。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fe6cb65107f5ddbd09cb50eb84d903d0.png)*

*你可以把它放入 Excel 来检查借贷是否相等(我就是这么做的)。借项和贷项合计分别为 14115 和-14115。*

# *万岁!你成功了*

*创建一个会计系统是非常复杂的。我们基本上探索了数据库设计的整个领域——从概念到 ERD 到创建再到查询。为自己走到这一步感到自豪。*

*请注意,我们故意限制了我们的数据库,以便更多地关注概念。你可以解除这些,并尝试建立另一个没有限制。*

*就是这样!你现在是 SQL 忍者了!恭喜你!*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0734997ba694f800d17d820c0bbba00f.png)*

*Ian Stauffer 在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄的照片*

****查看我的第二本书*** [***会计数据库设计***](https://leanpub.com/accountingdatabasedesign) ***即将在 Leanpub 上出版!****

****还我第一本书*** [***PowerQuery 熊猫指南***](https://leanpub.com/powerqueryguidetopandas) ***上***[***Leanpub***](https://leanpub.com/powerqueryguidetopandas)***。****

****跟我上***[***Twitter***](https://twitter.com/iamkennethcpa)***和***[***Linkedin***](https://www.linkedin.com/in/kennethinfante/)***。****

# 如何建立人工智能增强的劳动力

> 原文:<https://towardsdatascience.com/how-to-build-an-ai-augmented-workforce-c922c315f3c2?source=collection_archive---------64----------------------->

## 如何成为一名“增强工作者”的指南

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7842d74e906a2967f36658cfb14deb1a.png)

Alex Kotliarskyi 在 [Unsplash](https://unsplash.com/s/photos/open-space?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

大多数与人工智能有关的公司都处于根本性的转变之中。事实上,自动化将深刻影响劳动力,这主要归功于人工智能解决方案。**因此,如何实现人机协作的问题成了当务之急**。

不幸的是,许多决策者继续低估调整他们的劳动力的需要和复杂性。另一方面,许多工人(包括经理)仍然不觉得有必要了解人工智能,尽管自动化也会影响他们。

在我最近的任务中,我们实施了一个与我们众多的人工智能计划和长期愿景相关的“增强劳动力”战略。

在这篇文章中,我将解释为什么人工智能培训对长期自动化战略的成功至关重要,以及如何可能将你自己转变为“增强的工人”或者将你的团队转变为“增强的劳动力”。**我将介绍我们创建的一些指导原则以及一个使用案例。**

# 今天的情况

由于预先构建的算法和开源机器学习库,自动化重复任务和获得新见解变得“更容易”。出于多种原因,如定制需求、短产品周期、降低成本计划等,自动化正成为优先考虑的问题。然而,大量可以自动化的任务仍然需要**人工参与**。

事实上,达到 80%的准确率很容易,但达到 99%却非常复杂吗?最好的机器学习策略是让人类来处理剩下的那部分。这就是为什么计算机和人类之间的关系对于准确的结果和可扩展的人工智能解决方案至关重要。

> **80%的准确率**对于大多数现实世界的商业应用来说是不可接受的。

我们的主要目标是创造人类和机器之间的共生关系。为了达到这个战略水平,你需要重新想象工人角色和业务流程,使人和人工智能能够协作。**这种人与机器的完美融合,是一种“增强的劳动力”。**

> *“增强”这个词和 AI 没有必然联系。它可以作为帮助员工更安全、更高效地工作的任何辅助系统的参考。*

事实上,创造一个“增强的劳动力”需要新的战略以及一个准备好接受变化的内部文化。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/295280d63ec50c6f0c8f81e370b01460.png)

人工智能培训策略提案(取决于行业、策略和使用案例)

## 人工智能的最新发展

几个“新”元素让人工智能培训对公司来说变得有趣。AI 厂商、AIaaS 的激增,AI PoCs(概念验证)的高失败率等等。然而,我确实相信**低/无代码人工智能平台**的发展凸显了快速更好地理解人工智能如何工作的需要。

> **营销经理可以轻松构建概念验证来测试一个新想法的想法可能会改变游戏规则。**

我相信工人可以简单地使用人工智能来改善它,成为某种程度上的人工智能培训师,一个教人工智能如何执行和迭代的角色。这种转变将要求人力资源领导考虑定义“基本的人类技能和可以由机器管理的非必要任务”之间的区别。

许多员工将不得不发展不同的技能组合来保持相关性,而不是被取代。我们将从仅仅根据正式学位来招聘员工,转变为更加注重通过持续培训来培养技能和能力。

> **预测:**在不久的将来,无法与 AI 共生的管理者将被新一代管理者所取代。“增强的”经理将更加了解人工智能,并有使用低代码/无代码人工智能工具的经验。

需要人机共生的另一个原因可能与机器学习模型缺乏可解释性有关。像人类一样,神经网络也会犯错误,而且很难理解它们为什么会失败,因为人工智能本身无法沟通决策过程。人类(专家)必须参与进来,定期检查人工智能解决方案背后的准确性和逻辑,同时帮助数据科学家改进他们的模型。

在最好的情况下,数据科学家和设计师需要密切合作,创建以人为中心的共生人工智能系统,使人类专家/工人能够训练、互动和持续改进系统,而无需自己进行大量培训。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7af1bedbcc760f532ba7da7259e998a7.png)

理想情况下,数据科学家将利用他们的时间从事更复杂的项目,或(与经理一起)在组织的流程中识别额外的商业机会,而不是运营和维护现有的人工智能系统。

# 适应的需要

如果没有人理解或知道如何使用人工智能解决方案,那么实现这些解决方案是没有用的。因此,员工/用户必须在这些新的基于人工智能的工具方面接受适当的培训。

这意味着重新思考工人的角色,重新定义工作场所,使其变得更加数字化和协作化,“事实上,重新设计工作职能本身,使其更适合人类特有的技能**(**[](https://move.mantu.com/insight/augmented-worker/)****)****关键的想法是从自动化过渡到人机协作。****

**这种转变对所有公司都非常重要,因为自动化也会影响中小型公司。他们可能会发现让员工为自动化做好准备的任务比大公司更困难,因为他们的管理层可能没有完全预见到自动化的使用方式。**

**自动化策略可能是一项昂贵的投资。因此,如果一家公司对使用哪种人工智能解决方案做出了错误的决定,这不仅意味着浪费任何资源,还可能导致本可避免的失业。**

> ****预测:**我预计会有越来越多的咨询公司试图在人工智能培训/劳动力适应以及决策者在线培训方面发展独特的专业知识。在人工智能工具和“增强工人”之间建立完美共生关系的能力将成为竞争优势的主要来源之一。**

****此外,我认为不向员工提供再培训或跳槽机会的企业可能会损害他们的形象(雇主品牌)。****

**针对经理(针对最近部署了人工智能解决方案的公司)的人工智能培训应包括:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/dc11924c6412bb00838461489eea848c.png)**

# **竞争优势**

**如前所述,我认为,只有公司设法在人类智能和人工智能之间找到正确的平衡,人工智能战略才能成功。不愿扩张或无法找到正确平衡点的公司将面临风险。根据我的经验,未来 AI 相关的主要竞争优势有:**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5194cc59054d7b1c695af57c1230787e.png)**

**成功的长期人工智能自动化战略的支柱**

**我还预计,公司的劳动力将成为机器人、人工智能和自由职业者的混合体,这些人根据需要从世界各地参与项目。因此,我们可能会转向在线的劳动力即服务。**

# **指导方针**

**根据我在实施扩大劳动力战略方面的经验,我列出了以下一些关键步骤。**

1.  **公司必须确定他们应该自动化什么过程(战略决策)。此外,我建议公司建立一个内部自动化工作组(由经理、最终用户和高管组成),负责监督自动化战略的执行。**
2.  **检查有助于任务自动化的所有类型的技术。它包括机器人技术、认知技术和人工智能技术。人工智能并不总是完美的解决方案。机器人流程自动化可能是启动您的“扩大劳动力”战略的理想解决方案。**
3.  **确定哪些员工需要再培训或提高技能。基于您的自动化策略,识别哪些角色需要再培训将会更加容易。**
4.  **一旦你确定了人和人工智能可以共生的过程,确保所有的利益相关者从一开始就一起工作和实验。关键是要确保人类员工完全参与到你的人工智能/自动化解决方案中来。如果可能的话,我建议让设计师和数据专家尽早合作,创建用户友好的系统。在部署之前和之后,评估人们如何使用该解决方案,不仅测量生产力,还测量体验的质量方面。**
5.  **一旦实施了第一批自动化工具,您应该创建一个长期战略和年度运营劳动力路线图和规划。将人力资源、It、采购和财务等几个部门结合起来,制定一个“增强劳动力”路线图是非常关键的。**

****不考虑人力投入的自动化战略在短期内将会失败。**对于人工智能应用程序,将人排除在外会妨碍您获得丰富的增值资源和专业知识。为了建立一个扩大的劳动力队伍,决策者需要投资于三到五年后**的角色和职责。****

## **技术成熟度**

**即使这篇文章主要与人工智能有关,我还是建议公司用其他技术开始他们的自动化战略。事实上,人工智能需要一定程度的数据成熟度,而大多数公司仍未达到这一水平。因此,像机器人流程自动化(RPA)这样的技术在自动化战略的开始阶段更容易实施。**

> **RPA:模仿人类动作的软件机器人,而 AI 是机器对人类智能的模拟。([**X**](https://medium.com/@cfb_bots/the-difference-between-robotic-process-automation-and-artificial-intelligence-4a71b4834788)**)**
> 根据我的经验,RPA 解决方案无法自动适应流程变化(RPA 无法从新数据中学习/自行检测模式)。此外,RPA 解决方案只适用于不需要人工判断的重复性、基于规则的任务**

**此外,通过人工智能解决方案实现自动化通常只能归功于其他技术。例如,涉及制造业的公司需要物联网基础设施(wifi、云等)。)来建立灵活性并收集将由增加的劳动力使用的数据。传感器收集的数据通过物联网进行通信,从而产生一个人类和机器可以提高效率的工厂。**

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/72a4f8a4e4adc5490a818415fa2cdc62.png)**

**可能会因行业/使用情形的不同而有很大差异**

# **扩充工作人员—使用案例**

**您将在下面找到一个用例,它说明了自动化和增强劳动力的战略重要性。**

****用例——亚马逊&机器学习培训**
最近,亚马逊宣布计划对其三分之一的员工进行再培训,以帮助减轻自动化的影响。这个大胆的计划包括六个程序,亚马逊任何一个地方的员工都可以使用。**

**亚马逊技术学院(Amazon Technical Academy)将向非技术员工传授向软件工程师角色过渡所需的技能。**一个叫做机器学习大学的实体会给有一些技术背景的员工增加机器学习技能的能力(** [**4**](https://www.businesswire.com/news/home/20190711005341/en/Amazon-Pledges-Upskill-100000-U.S.-Employees-In-Demand) **)。****

**![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fd9498561df50d7e59051210e942c653.png)**

**基于这篇[文章](https://www.businesswire.com/news/home/20190711005341/en/Amazon-Pledges-Upskill-100000-U.S.-Employees-In-Demand)**

**总的来说,我认为对于那些愿意获得新技能,愿意加入人工智能解决方案的工作,与它一起工作,管理它,或者做一些他们不能做的事情的员工来说,有一个光明的未来。**

## **要了解更多信息,我推荐以下链接:**

*   **[创造未来共生的人工智能劳动力](https://sloanreview.mit.edu/article/creating-the-symbiotic-ai-workforce-of-the-future/)**
*   **[人+机器:重新想象人工智能时代的工作](https://www.goodreads.com/book/show/36465763-human-machine)**
*   **[智能自动化的兴起:如何利用增加的劳动力](https://enterprise-cio.com/news/2019/oct/17/rise-intelligent-automation-how-take-advantage-augmented-workforce/)**
*   **[协作智能:人类和人工智能正在联手](https://hbr.org/2018/07/collaborative-intelligence-humans-and-ai-are-joining-forces)**
*   **未来的改进:未来十年人类和人工智能将如何共同进化**

# 如何在 AWS 中构建 API—使用 AWS Lambda 和 API Gateway

> 原文:<https://towardsdatascience.com/how-to-build-an-api-in-aws-using-aws-lambda-and-api-gateway-22a8dee7c8e1?source=collection_archive---------13----------------------->

## 因为 API 就是未来!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e3e4dcdc9f647a0da5b2129c16583a40.png)

如何在 AWS 中构建 API—使用 Lambda 和 API Gateway。Emile Perron 在 [Unsplash](https://unsplash.com/s/photos/api-programming?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

API 是应用编程接口的缩写,是允许不同(部分)计算机程序交换数据的连接点。使用 API 来交付软件服务可以使您的代码组织得更好,更容易重用。

在本文中,我将介绍使用 AWS Lambda 和 API Gateway 创建 API 的基本步骤。

该示例是一个非常短的代码示例,它将根据给定的长度、一些大写字母和一些数字字符创建一个随机密码。其他字符将是小写字母。您可以让 API 背后的服务变得尽可能大和先进,从出售数据到使用先进的人工智能模型进行预测。

让我们开始吧:

# 1.创建 lambda 函数

在 AWS 管理控制台上,转到 Lambda:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d93627927df3c06d73df19361f9aabc2.png)

创建新功能:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b907c1cc5abd39f55eb2db5b448a752a.png)

选择*“作者从零开始”*,给你的函数起个名字。在这种情况下,api 将生成安全的密码。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/10f3f4f50b1b9ae7f6e7ea98024260ed.png)

# 2.编写 lambda 函数

在新创建的 lambda 函数中,转到函数代码:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a462687ff55c30fc2189b5575a2dd0ff.png)

并编写您的函数:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8b577f7c699e3ab0967aba6b0e54a529.png)

我使用的代码如下:

# 3.配置测试

进入测试菜单,点击配置测试。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/deb7bf43d1bd9b1d4e37184fecd9953f.png)

单击 create new test event,并在单击 create 之前在字典中为您的测试指定输入:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/dc869d0c19d964ba0f5a50618b5c9de1.png)

通过点击测试来测试你的 Lambda 函数:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/174350f4c5c5e7605013e7480ae1498b.png)

您会看到它在字典(或 json)的“主体”中发回了一个密码。

# 4.构建 API 网关

通过 AWS 管理控制台转到 API 网关。点击 REST API。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/22f970a55bb51f70da40091d40e19251.png)

单击新建 API 并选择一个名称:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/434bb3f4e0a7c8bb9852b7db70f237ef.png)

创建一个 POST 方法,并选择集成类型“Lambda Function”。然后选择 Lambda 函数的名称。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e0b35abce5c9afb68292538b5f742e91.png)

您现在应该会看到:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/16dfc4bb27f6ccc2459db0bea5567f6b.png)

最后一步,部署您的 API:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b9930fcbfee1eb831760e3d0da42c237.png)

可以命名为“ *prod* ”例如:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/77c18578a89221b4cd2ce143f3c7b2d3.png)

API 网关现在应该告诉您找到 API 的 URL:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d525b7c1800c46d1f9677e84b4bc6fc3.png)

# 5.真正测试你的 API

现在,您可以使用 Python 笔记本或任何您喜欢的东西来测试您的 API。

如果你把它复制粘贴到一个笔记本上,API 会给你发送一个新的密码!

# 如何在 Julia 中从零开始构建人工神经网络

> 原文:<https://towardsdatascience.com/how-to-build-an-artificial-neural-network-from-scratch-in-julia-c839219b3ef8?source=collection_archive---------8----------------------->

## 如何在没有机器学习库的情况下建立神经网络模型

我经常从喜欢“*从零开始构建算法*”系列的读者那里收到的一个流行的请求是关于深度学习或神经网络的报道。神经网络模型可能非常复杂,但在其核心,大多数架构都有一个共同的基础,从这个基础上出现了新的逻辑。这个核心架构(我称之为*香草神经网络*)将是这篇文章的主要焦点。因此,这篇文章旨在构建一个香草神经网络 ***,而不是*** 任何 ML 包,而是用 Julia(一种我觉得是数值计算的完美伴侣的语言)实现这些数学概念。目标是从头实现一个神经网络模型来解决二分类问题。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/96ddc8d8544452376e5ab29bdf25247c.png)

作者拥有的版权

## 神经网络的简要背景

那么什么是神经网络呢?神经网络的起源被广泛归因于沃伦麦卡洛克(神经病学家)和沃尔特皮茨(数学家)在 1934 年的论文。在这篇论文中,他们利用电路模拟了一个简单的神经网络,灵感来自人类大脑的工作方式。

## 什么是神经网络?

在某种基础水平上,神经网络可以被视为一个系统,它试图从生物神经元如何相互共享信息中获得灵感,以试图在一些提供的数据中发现模式。神经网络通常由互连的层组成。香草神经网络的层是:

*   输入层
*   隐藏层
*   输出层

输入层接受传递到隐藏层的原始数据,隐藏层的工作是试图在原始数据中找到一些潜在的模式。最后,输出层将这些学习到的模式结合起来,得出一个预测值。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/83ef4d054657987f6cd83c1f64c8f915.png)

从 [NN-SVG 生成的图像](http://alexlenail.me/NN-SVG/LeNet.html)

这些互连的层如何共享信息?神经网络的核心是神经元的概念。所有这些层都有一个共同点,它们都由神经元组成。这些神经元负责信息在网络上的传输,但是这种数据传输使用的是什么样的机制呢?

## 神经元——神经网络的构建模块

与其絮絮叨叨地用一些机器学习理论来解释这种机制,不如让我们简单地用一个涉及单个神经元的非常简单而实用的例子来解释它。假设我们有一个简单的例子,我们想训练一个神经网络来区分海豚和鲨鱼。幸运的是,我们从世界各地的海豚和鲨鱼那里收集了成千上万的信息。为简单起见,我们假设为每个被观察对象记录的唯一变量是'***【X1】***'和' ***【重量】【X2】***'。每个神经元都有自己的参数——‘*权值(W1)*‘和’***偏差(B1)***’——这些参数用于用这些参数处理传入的数据( **X1** & **X2** ),然后与下一个神经元共享这个过程的输出。这一过程直观地表示如下:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e06a922e139c0dc78e93edd691febf91.png)

作者拥有的图像版权

一个典型的网络由许多层神经元组成(数十亿,在 GPT-3 的例子中)。这些神经元的集合构成了普通神经网络的主要参数。好吧,我们知道神经元是如何工作的,但是一大群神经元是如何学习如何根据一些提供的数据做出好的预测的呢?

## 标准神经网络的主要组件

为了理解这个学习过程,我们将构建自己的神经网络架构来解决手头的任务。为此,我们需要在一个典型的普通网络中通过 5 个组件分解操作序列;

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/20a368edd5d7c43a43a38bf00c6398cf.png)

作者拥有的图像版权

网络设计要解决的问题的性质通常决定了这 5 个组件的可用选择范围。在某种程度上,这些网络就像乐高系统,用户插入不同的激活函数、损失/成本函数、优化技术。毫不奇怪,这种深度学习是科学计算中最具实验性的领域之一。记住所有这些,现在让我们跳过有趣的部分,实现我们的网络来解决二进制分类任务。

> **NB** :该实现将用维度为 **(n,m)** 的输入数据进行矢量化,映射维度为 **(m,1)** 的一些输出目标,其中 **n** 是数量,是特征的数量, **m** 是训练样本的数量。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cdc85ee97b3f6001c0b1812a30156226.png)

从 [NN-SVG 生成的图像](http://alexlenail.me/NN-SVG/LeNet.html)

*   **模型参数的初始化**

这些网络通常由许多层神经元堆叠而成。层和神经元的数量是固定的,并且这些神经元的元素(权重和偏差)最初通常填充一些随机值(用于对称破坏,因为我们有一个优化问题)。这个片段随机初始化给定网络维度的参数:

*   **正向传播算法**

初始化模型/网络的参数后,让我们构建通过网络运行输入数据以生成预测值的函数。如前所述,激活功能在这种信息流中起着至关重要的作用。我们的网络将使用 ReLU activator 来激活输出层和 sigmoid activator。这些激活剂如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/65852631869783fecd6dacac4f5f0508.png)

作者拥有的图像版权

这两个函数实现了这些激活器;

随着我们的激活器的实现,我们的注意力现在转移到通过正向传递或传播序列将数据从输入层移动到输出层。首先,计算线性输出,然后使用一个激活函数将线性输出转换为非线性输出。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cd26a6f3b38271b820bb985604eca4df.png)

作者拥有的图像版权

> **注意**:激活的输入和输出被“缓存”或保存,以备以后检索和使用。

下面这两个函数提供了通过网络移动数据的实用程序:

整个前向传播算法的顺序非常简单。我们简单地在网络维度上循环,使得一层的输出成为下一层的输入,直到最后一层给出预测值或分数(使用 sigmoid 激活时的概率分数)。下面的代码片段实现了这个序列;

*   **成本/损失函数**

我们现在有了一个网络,它能够根据随机初始化的参数对我们的训练样本进行一些预测。下一步是看看这些预测有多准确。为此目的,网络需要一个*成本* *或损失函数*。此成本/损失函数有一个简单(关键)的任务,即总结所有训练示例的预测值与实际输出值的接近程度。*对数损失(二元交叉熵)*函数适用于二元分类问题,因此下一个函数实现了成本函数;

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3dd5068b8a542e22772bc9a71c85357d.png)

作者拥有的图像版权

*   **反向传播算法**

我们的网络可以生成一些随机值作为预测,它也可以知道这些预测与实际输出有多远,所以下一个合乎逻辑的步骤将是找出如何提高其决策能力,而不仅仅是进行随机预测,对吗?

使用神经网络的' ***'学习*** '过程的核心是反向传播算法。不出所料,这是新手最难理解的部分。在我们的网络中实现这一步骤之前,让我们尝试用一些高层次的直觉来解释这一步骤。

反向传播序列的目标是理解网络的每个参数( ***所有层*** 的所有权重&偏差)如何相对于成本/损失函数变化。但是我们为什么要这么做呢?这个过程允许我们将学习策略转化为最小化目标,我们希望成本/损失输出尽可能低。此外,我们还知道并能够测量网络中螺栓和旋钮(**权重和偏差**)的变化如何影响损失函数。思考一下这个简化的类比,并意识到这个概念是多么强大!最终,我们所要做的就是调整网络的**参数** — *权重和偏差*,使其在损失/成本函数方面提供最低值,瞧,我们就像在科幻电影中一样做出预测了!

反向传播实现方面的核心是从多元微积分学借用的链规则的概念。事实上,反向传播的整个序列可以被视为每一层的偏导数(以及它们的权重' **W** '和偏差' **b** '以及线性输出, **Z** )相对于成本/损失函数的长链。顾名思义,这个序列链通过从输出层到输入层的反向*T21,使用正向传播序列期间存储的缓存来计算偏导数。为了简洁起见,这里是在我们的网络中实现反向传播所需的矢量化公式。*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/be37e2185c606971a0f3a26d06274fda.png)

作者拥有的图像版权

这两个效用函数实现了我们的 sigmoid 和 ReLu 激活的导数:

利用激活函数的导数,让我们集中于对线性激活输出的存储分量(权重、偏差和前一层的激活输出)进行解包,并利用这两个函数计算它们中的每一个相对于损失函数的偏导数。

结合激活函数的导数和各层激活输出的存储分量,构成具有该函数的网络的反向传播算法。

*   **优化技术**

我们快到了!我们的网络正在形成。当给定一些层作为体系结构时,它可以随机地初始化这些层的参数/权重,生成它们的一些随机预测,并使用该函数量化它与地面事实的总体正确或错误程度;

此外,反向传播步骤现在允许网络测量这些权重中的每一个如何相对于损失函数变化。因此,所有网络需要做的就是调整这些不同的权重,使其预测尽可能与提供给该网络的数据的实际输出相匹配。

理论上,可以尝试网络中所有参数的所有可能范围,并选择给出最佳可能损耗的网络(由损耗函数的输出值确定)。实际上,这种低效的方法是不切实际的,原因很简单:对于寻找具有如此多参数的网络的最佳参数来说,计算成本太高。由于这个和其他原因,使用优化技术来寻找最佳参数。梯度下降是寻找这种网络的最佳参数的最流行的优化技术之一。现在让我们用一个简单的实际类比来解释这种优化技术。

假设你被放在珠穆朗玛峰的顶端,给你一个戴着眼罩寻找山的最低部分的挑战(在那里放了一个装满黄金的袋子作为价格)。一个人能得到的唯一帮助是,在这个旅程的每一个点,他/她都可以通过对讲机与向导交谈,只需要询问在那个点相对于山的最高点(*坡度*)的当前方向。梯度下降作为一种优化技术,提出了一种简单而有效的方法来帮助人们应对这一挑战(给定约束)。这项技术提供的一个潜在的解决方案是,一个人从某个点开始,在不同的步骤使用步话机获得到珠穆朗玛峰最高点的相对方向,然后在给定的相反方向上移动一些步骤(*学习速率*)。重复这些技巧,直到到达珠穆朗玛峰最低处的那袋金子。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/038132da601d38d107f49f926ee1c50c.png)

作者拥有的图像版权

这个代码片段在我们的网络中应用梯度下降来更新网络的参数。

## 培训我们的网络

神经神经的训练基本上是一系列的序列,其中输入数据通过使用该网络的可用参数、与实际训练数据预测相比较的预测,以及最后作为改进预测的方法的参数调整,通过网络被转发。在机器学习行话中,这个序列的每次运行都被称为一个“*时期*”。这个训练阶段的核心思想是试图在各种尝试或迭代(*时期*)中改进网络生成的预测。这个代码片段结合了我们到目前为止已经生成的所有不同的组件:

所有组件就绪后,是时候测试实现是否工作了。为了简洁起见,让我们为这个演示生成一些简单的合成二进制分类数据。这很容易做到,因为:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/90e41b3f8f795bb234fcd6b5413788e5.png)

训练模型的输出。作者拥有的图像版权

## 结论

如曲线图所示,网络以低精度和高成本值开始,但是随着它不断学习和更新网络的参数,精度上升(而成本稳定),直到它在这个超级简单和完美的虚拟数据集上获得完美的分数。可悲的是,数据集在现实生活中很少如此完美!

一如既往,期待反馈!直到下一篇文章,继续玩这个实现,也许实现其他损失函数和优化算法。在下一篇文章中,我们将以这个实现为例,介绍制作和注册一个 Julia 包的过程。

# 如何通过 Python 和 Keras 使用 LSTM 构建一个编码器解码器翻译模型

> 原文:<https://towardsdatascience.com/how-to-build-an-encoder-decoder-translation-model-using-lstm-with-python-and-keras-a31e9d864b9b?source=collection_archive---------4----------------------->

## *按照这个逐步指南建立一个编码器解码器模型,并创建自己的翻译模型*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/189ec4595ea277aefe6a38d65c1a836e.png)

由[迈克尔·泽兹奇](https://unsplash.com/@lazycreekimages?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)在 [Unsplash](https://unsplash.com/@lazycreekimages?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上拍摄的照片

*先决条件:理解本文之前关于*[*【RNN】*](https://medium.com/swlh/introduction-to-recurrent-neural-networks-rnn-c2374305a630)*[*编码器解码器*](/what-is-an-encoder-decoder-model-86b3d57c5e1a) *的知识是有价值的。**

*本文是关于如何使用 Python 和 Keras 开发编码器/解码器模型的实用指南,更准确地说是 Seq2Seq。在上一个教程中,我们开发了一个类似于下图的多对多翻译模型:*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4aa271a733e6d6078422d36290833e42.png)*

*多对多 RNN。作者提供的图片*

*这种结构有一个**重要的限制,**序列长度。正如我们在图中看到的,**输入序列和输出序列必须具有相同的长度。如果我们需要不同的长度怎么办?例如,具有不同序列长度的模型是接收单词序列并输出数字的情感分析,或者输入是图像而输出是单词序列的图像字幕模型。***

*如果我们想要开发输入和输出长度不同的模型,我们需要开发一个编码器解码器模型。通过本教程,我们将看到如何开发模型,将其应用于翻译练习。模型的表示如下所示。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/146590d3fcbcedbf3ca145b5c30daa5c.png)*

*编码器解码器结构。作者图片*

***我们将模型分成两部分,**首先,我们有一个**编码器**,它输入西班牙语句子并产生一个隐藏向量。编码器由一个嵌入层和一个递归神经网络(RNN)构成,嵌入层将单词转换为矢量,递归神经网络计算隐藏状态,这里我们将使用长短期记忆(LSTM)层。*

*然后编码器的输出将被用作**解码器**的输入。对于解码器,我们将再次使用 LSTM 层,以及预测英语单词的密集层。*

# *亲自动手*

*样本数据可以在[manythings.org](http://www.manythings.org/bilingual/)下载,来自[塔图埃巴](https://tatoeba.org/spa)。它由你需要的语言中的句子对组成。在我们的例子中,我们将使用[西班牙语-英语组合](http://www.manythings.org/anki/spa-eng.zip)。*

*为了建立模型,我们需要做的第一件事是预处理数据,并获得西班牙语和英语句子的最大长度。*

## *1-预处理*

**先决条件:理解 Keras 中的类“tokenizer”和“pad_sequences”。如果你想详细回顾它们,我们在* [*之前的教程中已经讨论过这个主题。*](/how-to-build-a-translation-pipeline-with-rnn-and-keras-57c1cf4a8a7)*

*首先,我们将导入库,然后读取下载的数据。*

*一旦我们读取了数据,我们将保留第一个例子,以便更快地训练。如果我们想开发一个更高性能的模型,我们需要使用完整的数据集。然后,我们必须通过删除大写字母和标点符号来清理数据。*

*接下来,我们对句子进行分词并分析数据。*

*创建完函数后,我们可以进行预处理:*

*上面的代码打印出以下结果*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bc4b9f37f9723ba4c0135570e0b44127.png)*

*根据之前的代码,西班牙语句子的最大长度为 12 个单词,英语句子的最大长度为 6 个单词。在这里,我们可以看到使用编码器/解码器模型的优势,以前我们有处理等长句子的限制,所以我们需要对多达 12 个英文句子应用填充,**现在是一半。**因此,更重要的是,它还减少了 LSTM 时间步长的数量,从而降低了计算需求和复杂性。*

*我们应用填充以使每种语言中句子的最大长度相等。*

*现在我们已经准备好数据,让我们建立模型。*

# *双模型开发*

*在接下来的部分中,我们将创建模型,并解释我们在 python 代码中添加的每一层。*

## *2.1-编码器*

*正如我们在模型图像中看到的,要定义的第一层是嵌入层。为此,我们首先必须添加一个**输入层,**这里要考虑的唯一参数是**“形状”,**这是西班牙语句子的最大长度**,在我们的例子中是 12。***

*然后我们将它连接到[嵌入层](/introduction-to-word-embedding-and-word2vec-652d0c2060fa),这里要考虑的参数是**‘input _ dim’**,它是西班牙语词汇的**长度,以及**‘output _ dim’**,它是嵌入向量****形状。该层会将任何西班牙语单词转换为输出维度形状的矢量。***

*这背后的概念是以空间表示的形式提取单词的含义,其中每个维度将是定义单词的特征。例如,世界“sol”将被转换成形状为 128 的矢量。输出维度越高,从每个单词中提取的语义就越多,但所需的计算和处理时间也就越长。**需要在速度和性能之间找到平衡。***

***接下来我们将添加大小为 64 的 LSTM 图层**。尽管 LSTM 的每个时间步都输出一个隐藏向量,我们将注意力集中在最后一个上,因此参数 **return_sequences 为‘False’。**我们将看到解码器在 return_sequences=True 的情况下 LSTM 层是如何工作的。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/80418f61a1748e5489b65241b7d8f0ba.png)*

*当 return_sequences 为“假”时,输出是最后一个隐藏状态。作者图片*

## *2.2-解码器*

*编码器层的输出将是最后一个时间步长的隐藏状态。然后我们需要将这个向量输入解码器。让我们更精确地看看解码器部分,了解它是如何工作的。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a46a468816652f1f78cdb83c1bb5d692.png)*

*解码器在每个时间步长接收相同的输入。作者图片*

*正如我们在图像中看到的,隐藏向量重复了 n 次,因此 LSTM **的每个时间步长都接收到相同的向量**。为了让每个时间步都有相同的矢量,我们需要使用层 RepeatVector,顾名思义,它的作用是重复它接收的矢量,我们需要定义的唯一参数是 n,即重复的次数。这个数等于解码器部分的时间步长数,换句话说,等于最大英语句子长度 6。*

*一旦我们准备好输入,我们将继续与解码器。这也是用 LSTM 层构建的,不同的是参数 **return_sequences,在这种情况下为“真”。**这个参数是干什么用的?在编码器部分,我们期望在最后一个时间步只有一个向量,忽略所有其他的,这里**我们期望在每个时间步**有一个输出向量,这样密集层可以进行预测。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2fe31be18c63e0e11b6fa5bd35b7bf7d.png)*

*解码器:LSTM 计算密集层的输入。作者图片*

*我们还有最后一步,预测翻译的单词。为此,我们需要使用一个密集层。我们需要定义的参数是单位的数量,这个单位的数量是输出向量的形状,它需要与英语词汇的长度相同。为什么?**向量将是所有接近零的值,除了接近 1** 的一个单位。然后,我们需要将输出 1 的单元的索引映射到一个字典中,我们将每个单元映射到一个单词。例如,如果输入是单词“sol ”,输出是一个向量,其中所有都是零,那么单元 472 是 1,我们将这个索引映射到包含英语单词的字典,并且我们得到值“sun”。*

*我们刚刚看到了如何应用密集层并预测一个单词,但我们如何对整个句子进行预测呢?因为我们使用 return_sequence=True,LSTM 层在每个时间步输出一个向量,所以我们需要在每个时间步应用前面解释的密集层,一次预测一个单词。为了做到这一点,Keras 开发了一个名为时间分布的特定层,**它将相同的密集层应用于每个时间步。***

*最后,我们堆叠这些层来创建模型并添加功能损失。*

*一旦我们定义了模型,我们只需要训练它。*

*当模型被训练后,我们可以进行第一次翻译。您还会发现将密集层的输出与英语词汇进行映射的函数“logits_to_sentence”。*

## *结论*

*编码器解码器结构允许**不同的输入和输出序列长度**。首先,我们使用一个**嵌入层来创建单词**的空间表示,并将其输入输出隐藏向量的 LSTM 层,因为**我们只关注最后一个时间步骤**的输出,我们使用 return_sequences=False。*

*这个输出向量需要重复与解码器部分的时间步长相同的次数,为此我们使用 RepeatVector 层。解码器将使用 LSTM 图层和参数 return_sequences=True 构建,因此时间步长的每个输出都由密集图层使用。*

*尽管这个模型已经是对之前教程的一个很好的改进,我们仍然可以提高精确度。我们可以增加模型中 LSTM 层的数量,而不是编码器中只有一层,解码器中只有一层。我们也可以使用预先训练的嵌入层,如 word2vec 或 Glove。最后,我们可以使用注意机制,这是自然语言处理领域的主要改进之一。我们将在下一个教程中介绍这个概念。*

****附录:不使用重复矢量的编码器-解码器****

*在本教程中,我们已经看到了如何使用 RepeatVector 层构建一个编码器解码器。还有第二个选项,我们使用模型的输出作为下一个时间步的输入,而不是重复隐藏向量**,正如我们在这个图像中看到的。***

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/76add741a0161d71bc13acab913605ea.png)*

*作者图片*

*实现这个模型的代码可以在 [Keras 文档](https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html)中找到,它需要对 Keras 库有更深的理解,开发也相当复杂。*

# 如何在不赔钱的情况下建立一个有道德的数据科学体系?

> 原文:<https://towardsdatascience.com/how-to-build-an-ethical-data-science-system-without-losing-money-b5a72015ea8f?source=collection_archive---------56----------------------->

## 数据科学指南缺乏现实可行的道德实施

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2534829619981bcd2cdc3ac01cd38b28.png)

[来源:Needpix,公共领域图片](https://www.needpix.com/photo/download/1589183/technology-city-globalisation-business-digital-internet-network-communication-future)

受 Google DeepMind 的团队、Shakir Mohamed、William Isaac 和 Implikit 的创始人 Marie-Therese Png 的文章、 [Decolonial AI](https://arxiv.org/abs/2007.04068) 、我在数据科学和阅读方面的经验的启发,我将尝试提出一种生产策略,以补偿数据科学系统中缺乏可扩展的道德规范,并从开发开始就将其嵌入,从而节省以后的变化成本。

# **问题**

我要解决的主要问题可能是显而易见的。

> 数据科学没有实施高效且可扩展的道德准则。至少目前是这样。

但是,我认为,可以重新表述如下:

> 如今,数据科学不再以客户为中心。

原因,我将沿着文章详细说明是:

> 不言而喻,当我们推出基于数据的产品时,在丰富客户体验的表象下,我们的工作可能仅仅是为了优化收入、成本、人力和非人力运营资源。

这说起来复杂,做起来也复杂。

但是我将解释它,并在这篇文章中指出,根据软件工程的架构原则,隧道的尽头可能会有一线光明。

不损失金钱(或我们的工作,为了生产力)。

# 背景

我们看到我们活着,这很清楚。

数据科学和软件工程创新带来了大量创新和机会,但也加剧了社会不平等和不诚实。

例如,由于社交网络推荐系统,激进的怀疑主义几乎成了在网上消费信息的一种必要做法。

而且不应该是这样的,因为这样做很累人,不是每个人都愿意做的。

如果我们中的一些人这样做,我们会感到厌倦,我们已经厌倦了其他消费周期、个人问题以及当前的国际医疗和政治危机。

不幸的是,谁认可这种情况,特别是在信息领域?

在我看来,我们这些数据从业者。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/703579dabe3f90c8b51c91a4494837fa.png)

可能,这就是现在的你。

我同意,这不像是我们做的,但坦白说,我们让事情失去了控制。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/23487885e0d1ccefdcfc7f05ba385cb3.png)

你也是。

我们就像企业中的软件工程师一样。

建立稳定和良好的实践确实让他们付出了代价,但最终,他们得到了回报。通常,他们被视为独立工作者,有自己的做法和道德规范。实际上,我们几乎使用了所有的实践和伦理。

但是,对于数据从业者来说,这种独立性还没有实现。

我们从软件工程中引入了许多实践,但是我们的依赖有非常不同的行为,因为我们处理的是个人数据工件。

正如我从其他公司、采访、与该领域的朋友交谈中看到的,生产周期的思路最终是“它会为公司或我的团队带来回报吗?”。

事情是这样的,我们通常只把顾客放在过程的开始和结束。

我们应该在整个过程中考虑它们。

例如,最近由像 OpenAI 这样的大公司制造的 GPT-3,我没有看到任何生产中道德实践的证据。这个模型太复杂,太庞大,无法有效地无偏置。

可能他们在模型中使用了可解释技术,但是这就足够了吗?

这能避免 GPT-3 制造复杂的假新闻吗?

不发达国家能有效对抗这些吗?或者他们会服从精英阶层的意志,而精英阶层会按照他们的道德规范行事?处于战争状态的国家“想要”发现对方的消息是否是假的,或者他们会用假消息来煽动对对方的愤怒吗?

一个不发达国家能让自己的 GPT-3 模型和 OpenAI 竞争吗?

我的观点是,也许我们没有充分考虑我们的模型的含义。

虽然我们继续受到政府及其法律的教育,但我们在这方面还不够成熟。

该领域良好的职业道德应该超越我们的局部领域问题,我们应该开始在我们的实践中有效地嵌入和倡导**道德** **关注点**。

首先,仅仅因为我们使用来自用户的数据,或者因为我们不时地与他们交谈,并不意味着我们真的关心,或者我们正在考虑用户,以客户为中心。

也许这是产品中心主义和直接营销的混合物,但不是以客户为中心的。

对我来说,以客户为中心是指客户在整个生产周期中出现在我们的脑海中,给予关心,希望他们成功,而不是因为我们用他们来生产。

我们应该真正了解我们工作的积极或消极影响,而不是让道德成为积极、人性化营销的修辞工具。

# 我们正在成为技术官僚吗?

这种言论可能会得到该领域占主导地位的技术官僚观点的支持。

虽然我们过度重视数据科学的技术方面,纯粹的数据作为我们的指南,对复杂的机器学习模型进行建模,但我们并没有认真对待我们的社会责任。

我们许多人认为我们的工作是中立的,但在我看来:

> 数据=人。

不这样想对我来说是一种倒退,尤其是当我们建立道德准则的时候。道德开始看起来像是我们系统的一个细节,一个营销工具。

你知道那个圣诞装饰品吗?我们放在结尾的那个?看起来我们在道德上做了些什么。

> 但是,不应该吗?

我不这么认为。

为了展示我们的工作缺乏中立性,在每种关系下权力是如何存在的,我将尝试用两个在社会上通常被视为中立的主题来总结我的观点,这两个主题在数据科学中关系非常密切,包括科学和语言。

## 第一,科学。

像任何其他机构一样,受利益和欲望的驱动。有些人根据不同的标准来决定什么是相关的或者不相关的,什么可以发表或者不发表。

Kevin C. Elliott 和 Daniel J. McKaughan 在科学哲学论文“非认知价值和科学的多重目标”中描述得很好。

总之,他们认为非认知价值(那些与知识本身无关的价值)也引导着科学的发展,而不仅仅是纯粹的和高质量的知识,因为它们依赖于某人来认可什么是“纯粹”和“质量”的定义。

## 第二,语言。

另一个例子是数学语言。如果我们认为数学是一种语言,一种现象的模型,就像在任何其他模型和说这种语言的人群中一样,有一个信息过滤器。

我们可以问:

> 谁通常练习数学?
> 
> 数学界的黑人女性和白人男性的比例是多少?LGBTQI+?
> 
> 按国家划分,美国的情况如何?在巴西?在委内瑞拉?在阿根廷?在中国?

语言的另一个方面是地域性的:

> 《科学》杂志中引用次数超过 1000 次的葡萄牙语数学文章相对于英语的比例是多少?
> 
> 英语有那么“通用”吗?还是“显性”?
> 
> 如果我们假设英语是“通用的”,这对大约 95%不说英语的巴西人来说意味着什么?
> 
> 他们低人一等吗?还是他们缺乏机会和基础设施?

当我们质疑,质疑,权力结构开始显露,甚至是语言本身。

在数据科学的背景下——当然——贫穷的、不知情的、少数人掌权的**可以**产生数据科学。

但是,他们根据自己的环境制定最佳实践的可能性有多大呢?他们有可持续的基础设施来实践吗?

或者他们会遵循国际准则,而这些准则可能不会考虑他们?从长远来看,在他们的背景下实施的解决方案可能弊大于利?

对我来说,很明显:

> 数据科学远非中立。

如果我们是认真的,这应该是我们需要采取行动的事情。

如果我们继续仅仅基于技术评估和概念,基于纯粹的数据来行动和思考,我们将不可避免地排除其他人,排除我们工作流程中的少数人,并产生有偏见的产品和体验。

这就是道德和以客户为中心的理念对于可持续数据科学实践非常重要的原因。

**对我来说,这种情况一直持续到今天,有两个原因:**

1.  数据实践的方式是围绕公司环境中的运筹学建立的,以及它如何没有解决以客户为中心的模型;
2.  因为我们今天是如何在敏捷实践中实现我们的系统的。

# **1 理由:“数据科学”出于什么目的?**

我们有可能继承了另一个基于数据的领域——运筹学——没有解决的问题。

对于那些不知道的人来说,自第二次世界大战以来,运筹学是被使用的主要基于数据的技术,专注于优化资源分配以赢得战争。

最大化和最小化某些特定目标的资源,或者我们可以称之为目标函数。

最佳生产的哲学,独立于环境的性能,在当时和 60 年代后期非常有吸引力。

它的成功并不令人惊讶。从此成为企业生产中优化成本收益关系的有力工具,直到今天。

通常,运筹学模型由三个属性构成:

*   我们将用于实现目标的决策变量或资源变量;
*   目标函数,通常是我们希望最小化或最大化的决策变量的函数;
*   限制,这将使我们的问题的解决方案空间的轮廓。

有一些公司的解决方案,如 IBM 的 ILOG CPLEX,Gurobi Solvers,它们使用对偶单纯形法、内点法和其他方法对每种问题应用特定的方法,以在最佳时间内获得最佳解决方案。

极其简化的 OR 工作流程是这样的:

(拜托还是武者,不要杀我)

> 首先,你对问题进行建模。就像我们希望在收入共享模式中为某些用户提供最佳份额。
> 
> 第二,指定达到最优的决策变量。
> 
> 第三,基于企业资源定义模型的限制。
> 
> 在规划求解中编写模型,然后按 enter:)

在实践中,这有看起来那么简单吗?

不,一点也不容易。基于 MILP(混合整数线性规划)制定高效的企业解决方案需要时间,但也取决于问题。我只是需要总结一下,这样我就不会写一部完整的史诗。

我不知道你怎么想,但是这个过程对我来说肯定不是以客户为中心的。

**100%以产品、资本、企业为中心。**

这是运筹学的核心。

> 但是我们怎样才能使建模过程更加以客户为中心呢?

一个解决方案可能是实施限制,考虑人类健康、年龄、生产时间和精神状况。所有这些都可以用数学建模,我们只需要让它成为解决方案开发的一部分。

当我们应用或对工厂、企业的生产力进行优化时,我们可以考虑人类及其必需品对于福祉的限制。

但通常情况下,事实并非如此。

在实践中,通常操作研究人员将数据作为纯资源来处理。

与客户打交道的数据科学家应该将数据视为活生生的行为。

但并非巧合的是,它们今天都有相同的作用域。

优化、扩展流程、获得最先进的技术。但是客户在这个过程中处于什么位置呢?

在我看来,我们今天处理数据的方式是,如果它只是资源,而不是行为。最后,我们在某种程度上复制了运筹学思考数据的方式。

我们在考虑速度,优化指标。

我们是敏捷的,但是在错误的意义上。

通常,对敏捷生产模式有两种常见的误解:

## 1.速度:

敏捷意味着持续的迭代,进化的设计,它并不意味着一定要快速生产。

当我们认为数据科学是纯技术的东西时,实现全速和指标优化应该是我们艺术的顶峰。但正如我们已经讨论过的,它不是。

当我们将这种敏捷曲解与将数据科学视为纯技术的东西联系在一起时,与客户的良好职业道德通常是一种“很好的东西”,而它应该是预先的。

## 2.缺乏长期规划:

迭代,但是它们应该有多小呢?

在多大范围内,我们才不会过度设计,或者我们才不会忘记什么是真正符合职业道德的价值?

从架构的角度来看,这可能是当今数据科学工程实践中所缺乏的。并且可能是降低在我们的数据平台中实施道德原则的成本的秘密。

# 2 原因:我们的敏捷没有那么敏捷

从一开始,敏捷和极限编程哲学就提倡增量和持续开发。当问题出现时,YAGNI 和亲吻。

这是有成效的,但是当一个系统没有架构的长期指导方针时,它们可能是一个问题。

特别是在数据科学领域,我们**很少有**好的架构参考。

> 我们不是有很多数据管道和机器学习过程吗?

在我看来,这些是运营管道,而不是架构项目。

敏捷架构应该以增量的方式构建,通过小而完整的迭代,最大化价值交付并保持与客户的密切联系。

他们称之为进化设计,我认为这完全有道理。

一个好的软件架构师(或者数据架构师)应该尽快在头脑中有一个系统的视野,因为架构将引导他通过系统的约束。

如果我们没有这一点,我们将推迟看不见的问题,这些问题通常在开始时无法衡量,最终会以高昂的代价出现。

在我们的案例中,我们已经通过最新的事件看到了基于数据的平台如何在冠状病毒危机中影响社会行为,最近的选举是基于假新闻和自动化机器人以及其他后果而赢得的。

这些看不见的问题越来越大。但即便如此,直到现在,由于变革成本的限制,企业不想或不能有效地解决这些问题。

> 那么我们如何解决这个问题呢?

# 解决方案:了解客户,然后围绕他建立系统

一个可能的解决方案可能基于软件架构的中心:

> 领域层。

对于那些已经学习了软件系统的干净体系结构模型(六角形、端口和适配器等)的人来说,知道系统中最稳定的部分是它的域部分。

我们程序员、数据科学家所遵循的业务规则是由定义用例的客户体验、问题和愿望所决定的。

系统的其余部分是围绕它开发的。

如果客户是系统领域的中心,这意味着伦理也应该在我们架构的领域中。

在今天的生产模式中,这可能是一个好的、可持续的解决方案。

因为当我们把以客户为中心、道德规范作为一个细节来委派时——正如罗伯特·马丁在《清洁建筑》中所说——我们正在让系统越来越少地依赖它,这意味着我们在含蓄地说:

> 现在这没关系,我们可以委托。

而这从专业角度来看其实是不对的。

我们告诉客户,我们希望让他们的数据带来最佳体验,但在这个过程中,我们没有考虑他们,我们工作的社会影响,仅仅为了我们自己的生产和利润优化而使用他们的信息和行为,这是在撒谎。

如果我们不把道德作为我们开发周期的核心部分,我们就不会体验到我们给客户的真正具体的建议。我们只是为了利润,为了他们的数据资产而使用他们,而他们在使用我们的产品时也会以某种方式受益。

在不久的将来,很有可能有人会吹嘘这样的系统,并说:

> 他们怎么没想到这一点?我必须想办法解决这个烂摊子…

新的数据使用法规即将出台,我们可能已经为此做好了准备。

这与软件工程在生产环境中已经发生的事情有些相似。

当程序员推迟检测 bug、实现测试、构建整体系统时,如果他们需要重构、修复 bug、在生产中实现业务规则的简洁和可伸缩的实现,就会有奇怪的变更成本。

直到历史上的某一点,他们习惯于委派责任,而其他人,谁来解决这个烂摊子,会有这样的感觉:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b34058e48efeef289a37e1aa7b6e7513.png)

因为这些问题,特别是在生产环境中,测试驱动开发被形式化了,并且一直被传播到今天。

他们在实践中嵌入了职业道德和预期,如果实施得好,不会增加软件生产时间。

> 没有经过测试,你不能发布产品代码。

那些对自己的过去感到羞耻的人会说:

> 我们不知道。这在当时不是一个好的做法…

但是我想你可能知道,就像我们数据科学家知道的一样多。

就像我们害怕生产引擎的速度。我明白了,这是相当可怕和巨大的。

如果你不配合,如果你没有他们认为的那么快,它会夺走你的工作,薪水,所以你推迟了看不见但很重要的事情,如测试和伦理数据使用,特征工程。

最终,这种情况不会持续下去。这是不可持续的,同样的事情正在数据科学领域再次发生,其后果很快就会显现出来。

**但是**,如果我们将伦理逻辑嵌入系统的核心,领域层,在我们的核心实践中,我们不仅在我们的数据平台中,而且在我们的日常实践中实施伦理价值观。

这可能是我们的策略。

# 为什么以及如何工作?

架构上的原因是,理想情况下,系统的核心既抽象又稳定。

这意味着大多数模块依赖于业务规则,在我们的例子中,所有数据产品依赖于客户问题、用例以及业务规则。

如果我们将客户道德纳入这一领域,我们会保护它,并使它几乎成为一项义务。

总之,你需要做的就是在领域层包含一个客户伦理。然后,我们将有一个伦理数据科学平台。

一旦你让道德成为领域层的一部分,它就不再是一个细节,没有逃避的余地,因为它将成为系统中最稳定的部分。

> 但是我将如何统一它们呢?
> 
> 创建一个名为 Ethics 的接口,CustomerEthics 实现它,并与客户一起编写?还有什么?

你可以这样做,但我还不认为有这个必要,也许这是一个我没有想到的解决方案,在未来可能是好的。

现在,我认为你需要构建一个系统,考虑围绕用户建立一种文化。

直接或间接地从客户那里收集知识,理解他们的痛苦,并理解权力不平等会如何影响他们。

了解用户的社会经济状况、比例、设计以及产品优先级,让道德成为商业规则的一部分。

这应该加强生产思路,在数据系统中包含最佳道德实践。

将数据平台开发从 100%的技术、功能纯数据转移到 50%的技术和 50%的用户配置、体验(或类似的东西),设计开始改变,团队的思考方式也将开始改变。

在领域中实现它,系统的自然发展会照顾到它,良好的数据架构和敏捷会使它正确。

这就是数据科学系统如何开始自然地与道德进化,而不必在以后实施大的改变,你已经在第一时间做出了改变。

对于参考和不同的用例,有一个很好的目录可以帮助你构思和定义基于这种架构方法的具体策略。

由于企业领域千差万别,了解对用户可能造成的偏见可能会有助于改变你的文化中的数据文化,使数据驱动的理念更加成熟。

也许与 UX 团队联合会非常有效,因为他们是用户故事的专家,新的策略可能会出现在你的公司,因为道德准则会因用例而异。

# 结论

就这样,读了很长时间后,我希望我对讨论做出了一些贡献,我的观点是,我们如何才能实现一个高效的数据科学系统,而不会受到后来的伦理问题的困扰。

目标是将伦理放在系统架构视角的领域层中,并围绕它用负责任的敏捷开发来构建。

与 UX 的研究人员、你的项目经理和数据研究员聚在一起,了解用户的概况,因为你的工具直接与他们互动。

这就是为什么我们应该

> 让数据产品以客户为中心。

数据是不稳定的,因为它与客户有双向关系,这就是为什么我们应该投资深入了解他们。

我们越认识到这一点,我想我们的实践就会越成熟,我们在专业上的形象也会越好。

如果你同意,不同意,认为文本中有任何历史的,逻辑的误解,想以某种方式做出贡献,我将很高兴讨论,你可以在 victor.souza@passeidireto.com 给我发电子邮件,或在我的 [LinkedIn 页面](https://www.linkedin.com/in/victor-mariano-leite/)和我交谈。

[1] Mohamed,s .,Png,M. & Isaac,W. [非殖民化 AI:作为人工智能中的社会技术预见的非殖民化理论](https://link.springer.com/article/10.1007/s13347-020-00405-8) (2020), *Philos。技术。*

[2] Kevin C. Elliott 和 Daniel J. McKaughan,[非经验主义价值观和科学的多重目标](https://www.journals.uchicago.edu/action/showCitFormats?doi=10.1086%2F674345) (2014),科学哲学 81:1,1–21

[3]罗伯特·c·马丁,[干净的架构:软件结构和设计的工匠指南](https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164) (2017),普伦蒂斯霍尔

# 如何在 24 小时内建立一个图像自动旋转器

> 原文:<https://towardsdatascience.com/how-to-build-an-image-automatic-rotator-in-24-hours-3137769f240c?source=collection_archive---------46----------------------->

## 神经网络和 Keras 工具的简单性

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b4f7f5f03ea34c31c8086571316fd59f.png)

由[乌列尔 SC](https://unsplash.com/@urielsc26) 在 [Unsplash](https://unsplash.com/) 上拍摄的照片

最近,我接受了这个[任务](https://gist.github.com/csaftoiu/9fccaf47fd8f96cd378afd8fdd0d63c1)的挑战,主要是要求使用神经网络来预测图像的方向(垂直、上下颠倒、向左或向右),并根据预测将图像旋转到正确的位置(垂直),所有这一切都要在 24 小时内完成!

到目前为止,我在神经网络方面的经验是使用 Scikit-learn 内部的多层感知器,我从未处理过图像处理。这意味着是时候把我的头往墙上撞了!

训练集由大约 5 万幅图像组成,它们的标签存储在 csv 中,如下所示:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5be57252a5b9597879d20d4207b83fe7.png)

在挑战描述中,暗示使用 CIFAR10 模型和 Keras 上的相应示例。因此,对于像我这样的神经网络初学者来说,这是一个巨大的飞跃。

神经网络的有利一面是,没有必要重新发明轮子,已经有许多用于不同目的的预训练网络,它们可供任何人使用。

随着一个问题的解决,但仍然与时间赛跑,我把注意力集中在图像处理上。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/29e4ac713a3661162a6eeb7a51487c53.png)

来源[got 魔兽](https://gotwarcraft.com/ten-tips-earning-more-gold-wow/)

好了,几个小时后,stackoverflow 发布了图像处理测试函数,我终于能够将这些图像转换成矢量,但是我仍然需要给每个矢量贴上标签。此时,绝望占据了我的心头。

我需要一个过程:读取文件,将文件名转换为字符串,读取与文件匹配的条目的 csv,然后读取标签并将其添加到图像转换向量中。

然而,即使缩小到 32x32 的图像也代表 3072 大小的向量(32x32x3,你必须记住每个像素都有一个绿色、红色和蓝色的值),这意味着在每大约 50,000 行矩阵的 3073 个特征(向量+标签)中重复上述过程,这足以让我的普通本地机器在角落里哭泣。这只会增加绝望。

但我决定,至少我要在剩下的 16 个小时里学会如何解决这个问题。经过进一步的调查和几次失败的测试后,我找到了 Keras 的图像数据生成器,让我告诉你:这是一个多么令人愉快的工具!

由于图像处理的规模和复杂性,它有一系列的含义,但是使用这个工具,一切都可以用正确的参数来解决。

我们可以简单地转换带有图像标签的文件,并将其存储到 pandas dataframe 中,设置图像的路径,设置图像转换的大小,设置它是训练集还是验证集,我们甚至可以为此过程设置批处理大小,从而解决我们的本地机器问题。这是许多其他选项中的一个,比如通过不同的文件夹读取图像的标签,或者将图像转换成灰度。

我们对训练集和验证集重复这一过程,我们只需要十几行代码就可以训练一个神经网络,如下所示。

```
import keras
from keras.preprocessing.image import ImageDataGenerator

# create a data generation with the train truth images and dataframe
datagen = ImageDataGenerator(validation_split=0.2)

train_generator=datagen.flow_from_dataframe(
dataframe=train_truth,
directory="train/",x_col="fn",y_col="label",                                           subset="training",batch_size=32,seed=42,shuffle=True,                                         class_mode="categorical",target_size=(32,32)
)

validation_generator=datagen.flow_from_dataframe(
dataframe=train_truth,
directory="train/",x_col="fn",y_col="label",                                         subset="validation",batch_size=32,seed=42,shuffle=True,                                      class_mode="categorical",target_size=(32,32)
)
```

这时我终于看到了隧道尽头的光明。

还有 10 个小时,但我仍然不得不运行模型,评估它,并用它来校正测试集中的图像(没有标签)。

在设置了历元和每个历元的步骤之后,就到了用神经网络和图像处理来“睡眠”做梦的时候了,同时模型在运行。

还剩 3 个小时,准确率 95.94%是时候开始包装东西,建立一个图像旋转器,一个存储库,记录一切以完成挑战。

离比赛结束还有 1.5 个小时,检验旋转器的关键时刻到了:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/41869119b4ef27d13dc71eb811dc6407.png)

很好,看起来很有效!💪

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/475b5bf3c10e1757eced145cedd9cc08.png)

不仅如此,它是完美的!✨

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bee97c14576b8d7c4d85d6b08de40ead.png)

好吧,没那么多!😅

之后,我保存了修改过的图片,组织了知识库,并在只剩 3 分钟的时候提交了挑战。

直到今天,没有人回复我,告诉我模型在测试集中的表现,但有一点是肯定的,我学到了两个重要的教训:

首先,Keras 的图像数据生成器是一个优秀的工具,其次,在数据科学挑战的解决过程中,很大一部分是找到解决该问题的正确工具。

我对这个挑战的解决方案可以在这里找到。

# 如何以神经网络的思维方式使用逻辑回归构建图像分类应用程序

> 原文:<https://towardsdatascience.com/how-to-build-an-image-classification-app-using-logistic-regression-with-a-neural-network-mindset-1e901c938355?source=collection_archive---------21----------------------->

## 在这个循序渐进的教程中,您将学习使用 Streamlit 构建一个带有交互式 web 应用程序的 Cat 分类器。一切从零开始。

# 介绍

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0477c4cc79ae1cfcfcc115a4c6e5399b.png)

图片由作者设计,左图由来自 [Pixabay](https://pixabay.com/) 的 [Pexels](https://pixabay.com/users/Pexels-2286921/) ,中间图由来自 [Pixabay](https://pixabay.com/) 的 [Ahmed Gad](https://pixabay.com/users/ahmedgad-9403351/) ,右图由来自 [Pixabay](https://pixabay.com/) 的 [Wokandapix](https://pixabay.com/users/Wokandapix-614097/)

前几天,我在想我应该做什么项目?为我写下一篇辅导博客。过了一段时间,我想我大脑中的一群神经元做了一些计算并发出了一个信号,这让我想到了👇

用神经网络算法做一个项目怎么样?

所以我们设定了目标:

1.  了解神经网络
2.  用它创建一个项目
3.  写一篇关于它的教程,并与在线社区分享

所以现在的关键问题是:

## 应该从哪里了解神经网络?

作为一个基于项目的学习者,我正在寻找一个关于神经网络的一些基本理论知识的实践课程/教程。所以我选择报读神经网络和深度学习课程。

只是想让你知道,这是通过 Coursera 提供的 deeplearning.ai 专业化的第一门课程,由吴恩达教授讲授。Coursera 的联合创始人,斯坦福大学计算机科学的兼职教授。

最近,我完成了这门课程,还写了一篇文章,分享我对这门课程的全面见解。所以,如果你对学习神经网络感兴趣,那么看看这个👇

[](https://medium.com/datadriveninvestor/are-you-also-interested-in-learning-about-neural-networks-356a6592662) [## 你也对学习神经网络感兴趣吗?

### 这是吴恩达教授讲授的神经网络和深度学习课程的综合指南。

medium.com](https://medium.com/datadriveninvestor/are-you-also-interested-in-learning-about-neural-networks-356a6592662) 

所以我完成了课程,学习了解决图像分类问题,现在是时候写一个初学者友好的教程了!

# 你会学到什么?

## 1)对问题的理解

首先,我们将通过提出以下问题来理解图像分类的问题👇

*   什么是图像?
*   图像中的特征是什么?
*   图像在计算机上是如何表现的?
*   为什么图像分类很重要?…

## 2)学习并实现学习算法的构建模块

其次,在这个主要部分,我们将学习带有神经网络思维的逻辑回归算法。此时,我们将开始编码并实现学习算法的基本构件。

经过这一步,你将能够使用自己的图像来分类它是否包含猫。

我们将实现的一些功能有:

*   初始化参数
*   向前和向后传播
*   最佳化
*   主模型…

最后,我们将所有的功能合并到我们的主模型中。

在本教程中,我们将使用 **Python 编程语言**。是的,所有的代码都包括了全面的解释!

## 3)使用 Streamlit 制作交互式 Web 应用程序

最后,在最终确定模型后,我们将了解:

*   什么是 Streamlit?
*   使用 Streamlit 构建一个简单的交互式 Cat 分类器 web 应用程序
*   你还可以玩 Heroku 平台上的猫图像分类应用程序

这不是最后一步,但还有一个更有趣的东西👇

## 4)试验参数并分析结果

这是我最喜欢的部分,因为我们将通过尝试不同的值来玩我们的模型参数,如学习率,迭代次数。并将分析我们模型的性能。

在这一部分,我还将分享一些额外的步骤,通过这些步骤,你可以发挥、发现和分析你的学习算法的结果。

现在让我们开始吧!

# 目标

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ca1d720ab068dc0aad43797a5916b204.png)

作者的形象设计。左猫照片由 [Ty_Swartz](https://pixabay.com/users/Ty_Swartz-617282/) 在 [Pixabay](https://pixabay.com/) 上拍摄

我们的目标是解决图像分类问题。具体来说,在输入中我们有一个图像,我们需要找出某种方法来分类它是猫的图像还是非猫的图像。

要实现我们的目标,首先,我们来了解一下什么是形象?

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3a6689e2864afcf2d58d4e6315da97df.png)

2D 阵列的三维和一维通道示例

图像不过是一个 2D 数字阵列,这些数字代表颜色的强度值。如果它是一个灰度图像,那么只有一个 2D 数组的一维通道,其中包含代表黑色和白色阴影的值。

如果它是一个彩色图像,就像你在上面看到的,那么 2D 数组总共有 3 维通道,包含代表红、绿、蓝颜色的值。

在本教程中,我们将使用彩色图像!

你可以了解更多关于 i [法师和计算机如何存储图像的知识?](https://www.youtube.com/watch?v=EXZWHumclx0)在 Youtube 上传的教程里。

## 为什么图像分类很重要?

你一定听说过人工智能在机器人、计算机视觉、医疗诊断、商业和许多其他领域的应用。

在这里,我想分享两个图像分类发挥重要作用的例子。

1.  **医学诊断** 图像分类可用于检测疾病,例如
    从胸部 x 光图像预测新冠肺炎病例,…
2.  **自动驾驶汽车** 在计算机视觉的应用中,解决图像分类的相关问题在自动驾驶汽车中起着重要的作用。例如
    行人检测,交通信号,…

# 实现学习算法的构建模块

## 逻辑回归

我们的目标是建立一个模型/算法/函数,可以对猫和非猫图像进行分类。具体来说,这是一个二元分类问题。

给定一幅图像,如果模型预测“这是一幅猫的图像”,那么输出应该是 1,如果模型预测“这不是一幅猫的图像”,那么输出应该是 0。

那么有没有什么函数可以给我们想要的输出呢?

是的,这个函数被称为**逻辑/Sigmoid** 函数。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7110f2c5544aaa3b2c5f0a442bbda0c9.png)

Sigmoid 函数的图形

如上图所示,sigmoid 函数的属性如下:

*   如果 z 值是大的正数,那么输出越来越接近 1
*   如果 z 值是很小或很大的负数,那么输出越来越接近 0
*   如果 z=0,则输出为 0.5

逻辑回归算法将评估猫
在作为输入的给定图像中的概率。首先,如果 sigmoid 函数的输出为> 0.5,我们可以在算法中设置一个阈值来预测 cat 图像,反之亦然。

顺便说一下,选择一个好的阈值是玩机器学习算法的许多事情之一!

嘿,但是等一下!。这个教程的标题是不是:

“如何用神经网络的思维模式,使用逻辑回归构建一个图像分类应用?”

**神经网络在哪里?**

是的,我们将使用带有神经网络思维的逻辑回归来建立我们的图像分类模型。别担心!(安德鲁教授的对话)

首先,我们来谈谈神经网络!

## 什么是神经网络?

神经网络是另一种学习算法,但它与其他机器学习算法非常不同。受大脑结构的启发,人工神经网络试图模拟人脑中的神经元网络。ANN 是一种基于层的架构,由输入层、隐藏层和输出层组成。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/79e0c837d3e3cce3ae91709d2693ff1f.png)

图片由作者设计,左侧神经网络图片由 [Gordon Johnson](https://pixabay.com/users/GDJ-1086657/) 来自 [Pixabay](https://pixabay.com/)

在上述神经网络中,总共有 4 个隐藏层和 20 个隐藏单元/人工神经元,并且每个单元与下一层单元连接。因此,为了开始并更好地理解神经网络过程,我们将使用逻辑回归和神经网络思维来构建我们的 cat 分类器。

神经网络应用于计算机视觉、自然语言处理、推荐系统等领域

## 只是猜测👇

也许你正在阅读的这篇教程是由 medium articles 推荐系统背后的某个神经网络推荐给你的!

## 神经网络思维下的逻辑回归方法

使用这种方法有两个好处:

1.  我们将学习逻辑回归模型
2.  我们还将学习和实现神经网络编程的基本过程和构建模块

现在,在开始编码之前,让我与您分享这个过程的概述,然后我们将一步一步地处理学习算法的每个构建模块。

## 构建 Cat 分类器概述

**特征** 如果我们需要在任何照片中认出一只猫,我们将能够很快识别它,我认为这是因为我们学会了区分猫和其他动物的特征。

但是让计算机在任何照片中识别一只猫是非常困难的。因为在图像中,我们只有一串数字,代表不同深浅的红、蓝、绿颜色。这些数字被称为图像的特征,这就是猫分类器的输入。

因此,我们需要建立一个系统,能够识别一只猫在照片中可能的不同样子,这就是**学习算法**的由来👇

顾名思义,学习算法的工作是学习图像中猫的特征,但我们不希望我们的模型只预测单一/特定类型照片中的猫,而是希望我们的模型以这样一种方式进行推广,即我们的模型考虑猫在不同照片中可能出现的各种可能性。

为了使我们的模型一般化,我们需要给出许多不同类型的猫和非猫图像作为学习算法的输入。以便我们的学习算法可以学习猫图像与非猫图像之间的特征!

**但是一个学习算法学什么呢?**

好问题。在我的理解中,学习算法只是使用数学方程进行一些计算,并给出参数值。我们的模型需要这些参数值来以最小的误差正确地对猫进行分类。

我们将在这个过程中使用的算法被称为**梯度下降**。
你将在本教程的后半部分优化算法标题下了解到更多信息!

下图解释了我们将要实现的过程和数学表达式!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1185d33d25e14e20316e7c87ea6add02.png)

作者形象设计, [Ty_Swartz](https://pixabay.com/users/Ty_Swartz-617282/) 在 [Pixabay](https://pixabay.com/) 上的猫咪照片

变量的表示:

*   z 方程
    x 表示图像的特征, **w****b** 是我之前说的优化算法学习到的参数。
*   yhat=a=sigmoid(Z)
    Z 可以是任意实值,所以 sigmoid(Z)会给我们一只猫在图像中的概率。介于 0 和 1 之间的值。
*   L(a,y)
    这是一个损失函数,给出了预测值和实际值之间的误差量。
*   J
    这是计算所有训练示例/图像的预测值和实际值之间的误差量的成本函数。

我知道在上述过程中发生了很多事情。那么首先让我们通过单个训练例子来了解这个过程!

让我们用 **m** 来代表一个训练的例子。所以现在 **m** =1。

考虑到我们在算法中输入了猫的图像。

1.  首先,我们将参数值 w 和 b 初始化为 0,然后将图像的输入特征传递给 z 方程。
2.  z 表达式将任意实数值计算为 sigmoid 函数。比方说,sigmoid(z)计算出猫出现在该图像中的概率为 0.73。
3.  现在,损失函数计算了我们的模型预测和图像的实际值之间的误差量。然后,它开始计算总成本函数,但由于我们只有单个训练示例,因此损失函数和 J 值是相同的。

现在观察模型预测依赖于参数 w 和 b 的值,对吗?

因此,对**训练集**中的所有其他图像重复上述过程,然后优化算法尝试调整正确的参数值,以使我们的模型预测误差最小!

现在让我们开始编码

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7c787a75dffc77df5ea1d10d4f133d36.png)

[免费照片](https://pixabay.com/users/Free-Photos-242387/)在 [Pixabay](https://pixabay.com/) 上拍摄的照片

## 推荐的开发环境

*   Jupyter 笔记本

**注意:**你可以在我的 [Github 仓库](https://github.com/jalalmansoori19/Cat-Classifier)中找到所有必要的文件和代码

# 1.包装

首先,让我们导入所有对实现我们学习算法的构建模块非常有帮助的包。

这些包装就像你在制作某种食物的过程中需要的不同配料!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ca4e391fc677038cb812281f598d993a.png)

马丁·范·登·霍维尔在 [Unsplash](https://unsplash.com/s/photos/cooking?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上的照片

*   [**numpy**](http://www.numpy.org) 是使用 python 进行科学计算的基础包,我们将使用一些高效的内置函数,如 np.log、np.exp、…
*   [**h5py**](http://www.h5py.org/) 是一个通用包,用于与存储在 H5 文件中的数据集进行交互。[数据集文件上传到 Github](https://github.com/jalalmansoori19/Cat-Classifier/tree/master/datasets) 上。
*   [**matplotlib**](http://matplotlib.org/) 是 python 中著名的图形绘制库。
*   [**PIL**](http://www.pythonware.com/products/pil/) 和 [**scipy**](https://www.scipy.org/) 这里用你自己的图最后来测试你的模型。

如果你正在使用 Jupyter 笔记本,然后导入上述软件包,如果你面临任何问题,然后确保软件包安装正确。

现在按下 **Shift +回车键**运行 Jupyter 笔记本中的单元格。

# 2.数据集的加载和概述

让我们更熟悉数据集!

在下面的代码中,我们加载了由猫和非猫图像组成的数据集。

**训练集** 我们的猫分类器模型将使用这个训练集来学习猫与非猫特征之间的差异。

train_set_x_orig:这是一个存储猫和非猫图像特征值的矩阵。这些值介于 0-255 之间,代表红色、蓝色和绿色的不同色调。

train_set_y:这是一个向量,它存储了 train_set_x_orig 中图像特征的相应输出值。
1 表示它是一个猫图像。0 表示它不是猫的形象。

**测试设置**

在我们的模型在训练集上训练后,我们将使用测试集检查我们的模型性能,这是我们的模型没有看到的数据!

## 数据集输出概述:

```
**Number of training examples**: m_train = 209
**Number of testing examples**: m_test = 50
**Height/Width of each image**: num_px = 64
**Each image is of size**: (64, 64, 3)
**train_set_x shape**: (209, 64, 64, 3)
**train_set_y shape**: (1, 209)
**test_set_x shape**: (50, 64, 64, 3)
**test_set_y shape**: (1, 50)
```

因此,我们有 209 个训练示例和 50 个猫与非猫图像的测试示例。每幅彩色图像的尺寸都是 64 X 64。

## 可视化训练集中的图像示例

train_set_x_orig 和 test_set_x_orig 的每一行都是代表一个图像的数组。随意更改**索引值**并重新运行以查看其他图像。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/8cc48ed85966d996d26457f70ce7cd00.png)

训练集中的猫和非猫图片示例

## 重塑训练和测试集

为了方便起见,现在我们需要在形状(num_px*num_px*3,1)的 numpy 数组中对形状(num_px,num_px,3)的图像进行整形。在这之后,我们的训练(和测试)数据集是一个 numpy 数组,其中每一列代表一个展平的图像。

**输出:**

```
train_set_x_flatten shape: (12288, 209)
train_set_y shape: (1, 209)
test_set_x_flatten shape: (12288, 50)
test_set_y shape: (1, 50)
```

现在,我们的训练和测试集处于计算目的的正确维度。train_set_x_flatten 和 test_set_x_flatten 中的每一列都表示图像的特征。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/60613c777992a4e39a8eec3e6959068b.png)

整形后存储在训练集中的数据的可视化。(图片由作者提供)

例如:
train_set_x_flatten[:,209]将输出存储训练数据集中最后一幅图像的 12288 个值的特征向量。

test_set_x_flatten 也一样!

# 3.预处理步骤

机器学习中的一个常见步骤是预处理/标准化数据集。

> "具有相似尺度的特征可以帮助梯度下降更快地向最小值收敛. "

简而言之,这意味着当数据集中的要素具有相似的比例时,优化算法将更容易了解那些有效的参数 **w****b** 值。有许多不同种类的技术可用于此目的。

但对于图片数据集,更简单、更方便的方法是将数据集的每一行除以 255(像素通道的最大值),效果几乎一样好。

在预处理之前,训练和测试集中的特征值在 0 和 255 之间。

预处理后,现在训练和测试集中的特征值在 0.0 和 1.0 之间。

## 到目前为止我们做了什么👇

*   算出问题的维度和形状(m_train,m_test,num_px,…)
*   重塑数据集,使每个示例现在都是一个大小为(num_px * num_px * 3,1)的向量
*   将数据“标准化”

现在是时候设计一个简单的算法来区分猫图像和非猫图像了。

# 4.构建我们算法的各个部分

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1185d33d25e14e20316e7c87ea6add02.png)

作者图像设计,猫的照片由 [Ty_Swartz](https://pixabay.com/users/Ty_Swartz-617282/) 在 [Pixabay](https://pixabay.com/) 上拍摄

首先,我们将实现 sigmoid 之类的辅助函数,初始化参数,…然后我们将这些函数合并到我们的主 cat 分类器模型中。

## 4.1 Sigmoid 和初始化参数功能

如上图所示,首先我们需要计算𝑠𝑖𝑔𝑚𝑜𝑖𝑑(z 来进行预测。

首先,我们将参数 w 和 b 初始化为零。您还可以用随机值初始化这些参数,以检查零和随机初始化之间的差异!

## 4.3 向前和向后传播

现在我们已经准备好 sigmoid 和初始化函数,下一个任务是计算学习参数的向前和向后传播步骤。

我们将在名为 **propagate()** 的函数中实现以下等式,该函数计算成本函数及其梯度。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/29b6aa42493a9b6d3e18f2297c8ed55b.png)

计算梯度和成本的方程式

成本函数将给出代表我们的模型预测和实际值之间的误差量的值。

我们的目标是最小化成本函数,这就是为什么我们需要计算关于参数 **w****b**的成本梯度或变化

## 4.4 优化算法

是时候实现一个函数了,它将为我们的模型提供有效的参数,以最小的误差做出预测。

这里的目标是通过最小化成本函数𝐽.来学习𝑤和𝑏使用梯度下降算法,更新规则是:

*   *w*=*w*−𝛼𝑑*w*
*   *b*=*b*−𝛼𝑑*b*

其中,𝛼是学习率, *dw,db* 是我们在 propagate()函数中计算的梯度。

梯度下降给了我们两个超参数来玩,**学习速率****迭代次数。**我们将使用这些2 超参数做进一步的分析,并改进我们模型的性能。

## 4.5 预测功能

前面的优化函数将给出 w 和 b 参数。然后,我们可以使用这些参数来预测图像 X 是否包含一只猫。

# 5.将所有功能合并到一个模型中

最后,我们现在将了解如何按照正确的顺序将所有的构建模块(在前面的部分中实现的功能)组合在一起,从而构建整个模型。

让我们使用 num_iterations 和 learning_rate 中的随机值来观察我们的 cat_classifier 模型的性能:

```
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 1000, learning_rate = 0.005, print_cost = True)
```

输出:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fa797e141194ea5753fdbb022e1c1dfb.png)

模型的训练和测试精度

因此,我们的模型能够正确分类训练数据集中大约 96%的图像和测试数据集中 72%的图像。我希望你知道,我们的模型是在训练数据集上训练的,这就是为什么训练集的精度比测试精度高得多。

但是,72%的测试准确率还是不错的。让我们绘制学习曲线图,以便更好地了解培训过程!

# 学习曲线图

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/db5a64b41bf511bb1ea5fbc77a27cff9.png)

学习曲线图

你可以看到成本在下降。这表明参数正在学习中。尝试增加上面单元格中的迭代次数,然后重新运行这些单元格。您可能会看到,训练集的准确性提高了,但测试集的准确性却降低了。这叫做过度拟合。

以下是通过更改 num_iterations 值得到的模型结果:

```
# **num_iterations = 2000**d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 2000, learning_rate = 0.005, print_cost = False)**Output:****train accuracy**: 99.04306220095694 %
**test accuracy**: 70.0 %# **num_iterations = 3000**d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 3000, learning_rate = 0.005, print_cost = False)**Output:****train accuracy**: 99.52153110047847 %
**test accuracy**: 68.0 %
```

上述性能结果表明,当我们增加 num_iterations 值时,我们的模型训练精度会增加,但测试精度会略有下降!

在这里,我们看到模型过度拟合训练数据,这意味着模型将只能根据它正在训练的数据进行正确预测。称为正则化的技术用于减少过拟合。

提高模型性能的可能性有很多,因此在本教程中,我将使用训练精度约为 100%且测试精度为 70%的 cat 分类器模型,这对于我们正在使用的这个小数据集来说是不错的!

# 让我们研究一下学习率参数,并做一些进一步的分析

过去,我也写过一篇关于梯度下降算法中学习率分析的深入教程👇

[](https://medium.com/towards-artificial-intelligence/effect-of-learning-rate-in-gradient-descent-algorithm-using-python-bb45eb0f26bf) [## Python 中梯度下降算法的学习速率分析

### 在本教程中,你将学习,实施,通过尝试不同的梯度下降的性能可视化…

medium.com](https://medium.com/towards-artificial-intelligence/effect-of-learning-rate-in-gradient-descent-algorithm-using-python-bb45eb0f26bf) 

让我们进一步分析我们的猫分类器模型,并检查学习率𝛼.的可能选择

**学习率的选择**

为了让梯度下降有效,你必须明智地选择学习率。学习率𝛼决定了我们更新参数的速度。

*   如果学习率太大,我们可能会“超过”最佳值。
*   同样,如果它太小,我们将需要太多的迭代来收敛到最佳值。

这就是为什么使用一个合理的学习率是至关重要的。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/38017e2d0dd8134cb5e6638f3f9a590c.png)

收敛和发散的直观可视化。图片由[亚当哈雷](https://www.cs.ryerson.ca/~aharley/neural-networks/)

让我们比较一下我们模型的学习曲线和几种学习率的选择。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cba555a714f134fe0e72e509b384e4ce.png)![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b4a377f0afdd476e478266535b43fca1.png)

学习率的输出选择

观察结果:

*   不同的学习率给出不同的成本,从而得到不同的预测结果。
*   如果学习率过大(0.01),成本可能会上下振荡。它甚至可能会发散(尽管在这个例子中,使用 0.01 最终仍然是物有所值的)。
*   更低的成本并不意味着更好的模式。你必须检查是否有可能过度配合。当训练精度大大高于测试精度时,就会发生这种情况。

# 可选:可以用来改进模型的东西

我们只玩了一个超参数学习率,所以如果你想通过尝试不同的东西来获得更好的理解,我鼓励你玩以下东西,并观察你的模型性能的变化:

*   如果您记得我们用零初始化参数,您可以尝试不同的初始化方法并比较结果。
*   玩弄学习率和迭代次数
*   测试其他预处理方法,优化算法,…

# 6.用你自己的图像测试

恭喜你建立了你的第一个图像分类模型。现在,您可以使用自己的图像并查看模型的输出。

*   将您的图像添加到 Jupyter 笔记本的“图像”文件夹中
*   在下面的代码中更改图像的名称
*   运行代码,检查算法是否正确(1 =猫,0 =非猫)

Cat 分类器预测:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fbbae2eab705281f72699702e90597cd.png)

亚历山德鲁·兹德罗布在 [Unsplash](https://unsplash.com/) 上拍摄的照片

让我们检查算法是否正确预测非猫图像👇

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0d08035f1a1f0735ebca0d08bada4ec5.png)

(图片由[ale ha va](https://pixabay.com/users/Ale%C5%A1H%C3%A1va-5318775/)在 [Pixabay](https://pixabay.com/) 上拍摄)。我们的模型预测正确:这不是一只猫的形象

是时候使用 streamlit 制作一个交互式 web 应用程序了!

但是在开始使用 streamlit 之前,首先,我们需要完成并保存我们的 cat 分类器模型。

## 如何最终确定并保存 Cat 分类器模型?

> 在进行预测之前,必须训练一个最终模型。
> 
> 您可能已经使用 k-fold 交叉验证或数据的**训练/测试分割**训练了模型。这样做是为了让您对模型在样本外数据(如新数据)上的技巧有一个估计。
> 
> 这些模型已经达到了它们的目的,现在可以丢弃了。
> 
> 现在,您必须根据所有可用数据训练最终模型。

由(杰森·布朗利)创办的[机器学习大师](https://machinelearningmastery.com/)

运行以下代码,在整个数据集(而不是在定型集和测试集)上定型最终模型👇

## 如何保存猫分类器模型?

使用 Joblib,我们可以轻松地保存我们的模型,现在我们可以在 streamlit 应用程序中使用它。

```
import joblib# Save the final Cat classifier model as a pickle in a file
joblib.dump(cat_clf, "Cat_Clf_model.pkl")
```

# 使用 Streamlit 的交互式猫图像分类应用程序

在开始使用我们的 app 编码之前,您还可以使用 Heroku 平台上的一个
[猫图像分类 app。](https://cat-clf-app.herokuapp.com/)

现在让我们了解一下 streamlit!

## 什么是 Streamlit?

Streamlit 是一个开源框架,用于创建一个交互式的、漂亮的可视化应用程序。全部用 python!

Streamlit 提供了许多有用的特性,对数据驱动项目的可视化非常有帮助。

## 为什么我应该使用 Streamlit?

*   创建交互式用户界面的简单易行的方法
*   不需要开发经验
*   在数据驱动的项目中使用不同的功能很有趣
*   全面的文档

## 使用 Streamlit 的 Face-GAN explorer 示例

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d2d97f9b4f694b0a2380816bdea4fa06.png)

这个 Streamlit 应用程序使用[关的 TL-GAN](https://blog.insightdatascience.com/generating-custom-photo-realistic-faces-using-ai-d170b1b59255)【6】演示了 [NVIDIA 名人脸 GAN](https://research.nvidia.com/publication/2017-10_Progressive-Growing-of)【5】模型。

我们的[猫图像分类应用](https://cat-clf-app.herokuapp.com/)的最终版本将会是这样的👇

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/233a42093f6bba6c0dce56ccc86d08fb.png)

使用 Streamlit 的交互式猫图像分类应用程序

我们开始吧!

## 安装程序

## **针对 Linux 的**

你只需要在你的终端中写下下面的命令来安装 Streamlit 包。

```
pip install streamlit
```

## **用于 Windows**

你可以在他们的[官方文档页面](https://docs.streamlit.io/en/latest/troubleshooting/clean-install.html#install-streamlit-on-windows)找到 Windows 的安装程序

现在,创建一个新文件,键入下面几行代码,并将其另存为**。py** 扩展。

下面是[猫图像分类 app](https://cat-clf-app.herokuapp.com/) 的代码👇

## app 怎么运行?

打开一个终端,并确保您位于保存文件的同一个工作目录中。

键入以下命令,然后按 enter 键:

```
streamlit run nameofyourfile.py
```

祝贺您使用 Streamlit 构建了您的第一个图像分类应用程序!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/69f823560581e2ddee159b553203f22c.png)

照片由 [StartupStockPhotos](https://pixabay.com/users/StartupStockPhotos-690514/) 在 [Pixabay](https://pixabay.com/) 上拍摄

# 源代码和必要的文件

你可以在我的 Github
[Cat-Classifier 资源库中找到所有必要的文件/文件夹和源代码。](https://github.com/jalalmansoori19/Cat-Classifier)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3d4b9dcfbc60233fbbfc93141408b195.png)

[皮特·佩德罗萨](https://unsplash.com/@peet818)在 [Unsplash](https://unsplash.com/) 上的照片

# 结论

在本教程中,首先我们分别实现了每个函数:sigmoid()、propagate()、optimize()、…然后构建 Cat 分类器模型。最后,我们使用 streamlit 库构建了一个交互式猫图像分类应用程序。

我希望你喜欢从本教程中学习!

如果您在本教程中遇到任何问题或有任何疑问,请随时联系我们!

Gmail:jalalmansoori19@gmail.com
Twitter:[https://twitter.com/JalalMansoori19](https://twitter.com/JalalMansoori19)LinkedIn:[https://www.linkedin.com/in/jalal-mansoori-44584a177/](https://www.linkedin.com/in/jalal-mansoori-44584a177/)Github:[https://github.com/jalalmansoori19](https://github.com/jalalmansoori19)

# 参考

1.  通过 Coursera 提供的 deeplearning.ai 专业化的神经网络和深度学习课程,
    [https://www . Coursera . org/learn/neural-Networks-Deep-Learning](https://www.coursera.org/learn/neural-networks-deep-learning)
2.  揭秘深度卷积神经网络, [https://www.cs.ryerson.ca/~aharley/neural-networks/](https://www.cs.ryerson.ca/~aharley/neural-networks/)
3.  deepai.org,什么是神经网络,
    [https://deepai . org/machine-learning-glossary-and-terms/Neural-network](https://deepai.org/machine-learning-glossary-and-terms/neural-network)
4.  机器学习的特征缩放:了解规范化与标准化的区别,
    [https://www . analyticsvidhya . com/blog/2020/04/feature-Scaling-Machine-Learning-Normalization-Standardization/](https://www.analyticsvidhya.com/blog/2020/04/feature-scaling-machine-learning-normalization-standardization/)

# 如何使用 IBM Watson NLC 服务构建图像分类器

> 原文:<https://towardsdatascience.com/how-to-build-an-image-classifier-using-watson-autoai-ab1ffda25bab?source=collection_archive---------45----------------------->

## 建立一个没有编码的图像分类模型

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/78e2ebb9c3c9d7011ff48ef9e188e146.png)

图片由 [ipet photo](https://unsplash.com/@ipet_photo) — Unsplash 提供

## 图像分类

图像分类是计算机视觉中的任务之一,其目标是根据图像的内容对图像进行分类。例如,给定下图,预期输出是“*狗”*(例如,如果训练数据集是针对狗和猫的)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9bc737f100bc7f6832407d0d4b0af25a.png)

由[贾斯汀·维内玛](https://unsplash.com/@justinveenema)拍摄的图片——Unsplash

## 让我们建立分类器

我们将使用包含来自世界各地的 120 种狗的图片的斯坦福狗数据集。

首先,转到 Watson AutoAI 并创建一个项目。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/17b2f45d76d0cffb19f441a76a1453f1.png)

单击项目名称,您应该会被定向到项目主页。点击*“添加到项目”*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/e0ebd05cdf3d03a4276610ef0b6aec5d.png)

然后选择*【视觉识别模式】*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4a7413e888af54a9f390a5d2fb24acad.png)

如果是第一次,您需要创建一个服务。点击*【此处】*

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ce194628122b70eb8d11cbd82d6424b4.png)

选择一个符合你需求的计划。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5729e4e0c311d92dfa69b1e22628ac9b.png)

您可以选择更改区域、计划、资源组等。我更喜欢默认设置。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ec70bb8a9e3b8d558f9863c225de6158.png)

点击*“分类图像”*创建分类模型

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/25c4d269ac8f76fbc73f2568f75b1bc0.png)

这是构建模型的主页。单击右侧的“浏览”上传数据集(zip 文件,其中文件夹的名称是类名)。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d72a84d052fd6dc3f1cfc38d4cb2da8f.png)

我上传了三个数据集(澳洲野狗、大丹犬和西伯利亚哈士奇),每个数据集有 50 张图片。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d1438a5e42a2781618f7b82e2f092b66.png)

单击“训练”开始训练模型。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/f50c20e50c8cc7e913a867e605df07e2.png)

培训完成后,您将收到通知。单击“此处”可重定向至项目概述。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/05a94292d69967614b37b7769a5602b2.png)

将提供关于该模型的信息列表。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/cf33a6f25ffe99b2b997363d78c45d69.png)

点击“测试”来推断模型。上传一张图片,模型会预测该图片的类别。您可以从左侧选择显示的类别及其可信度。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/a4222359ac834e1210150bc4c1b7835f.png)

最后,单击“Implementation ”,您将获得远程推断模型的 API。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/06cffd710298b7d653ec916b7185ee0c.png)

资源

*   [IBM Watson AutoAI 文档](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/autoai-overview.html)
*   [Youtube 上的 IBM Watson 学习中心](https://www.youtube.com/watch?v=DBRGlAHdj48&list=PLzpeuWUENMK3u3j_hffhNZX3-Jkht3N6V&index=1)
*   [斯坦福狗数据集](http://vision.stanford.edu/aditya86/ImageNetDogs/)

# 如何:使用 Plotly 构建身临其境的地理气泡图

> 原文:<https://towardsdatascience.com/how-to-build-an-immersive-geo-bubble-map-with-plotly-bb20eb70414f?source=collection_archive---------24----------------------->

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/bb2b2080226ff312d89f071b721d952c.png)

gif 由你真诚地

在本教程中,我将使用 Plotly 创建得克萨斯州新冠肺炎案例的县级地理气泡图。以上 gif 中的情节可以在我的[网站](http://tsbloxsom.pythonanywhere.com/)底部找到。我的网站最好用笔记本电脑而不是移动设备访问。我还制作了另一个教程,讲述我如何使用 dash [在这里](/creating-and-automating-an-interactive-dashboard-using-python-5d9dfa170206)创建另一个交互式 plotly 图形和网站。我用来创建这张地图的所有代码和数据都可以在我的 [Github](https://github.com/tsbloxsom/Texas-census-county-data-project/tree/master/county%20map%20notebooks%20and%20data) 上找到。[。ipynb](https://github.com/tsbloxsom/Texas-census-county-data-project/blob/master/county%20map%20notebooks%20and%20data/medium_tutorial_for_geo_map.ipynb) 文件包含了所有的代码和图形,但是您必须拥有所有的。csv 和。下载 xlsx 文件,自行创建图形以及相关的 plotly 库。我将假设你有一些关于 python、熊猫和 plotly 的知识。让我们回顾一下我创建这张漂亮地图的步骤:

1.  加载数据并用熊猫清理数据
2.  将相关数据框合并在一起并清理
3.  用 groupby()格式化要输入到 plotly 图形中的数据
4.  使用 plotly.express.chorograph()和 plotly.graph_objects 创建图形。散点图()

关于代码片段需要注意的一点是,在运行代码之前,您可能需要更改数据文件所在的目录。好了,我们开始吧!

1.  **加载数据,并使用熊猫清理数据**

```
import pandas as pd
import plotly.express as px
from urllib.request import urlopen
import json
import plotly.graph_objects as go# read in data
fips_data = pd.read_excel("PHR_MSA_County_masterlist.xlsx", dtype={'FIPS #': str}) #need this to plot counties on map, source: [https://www.dshs.texas.gov/chs/info/info_txco.shtm](https://www.dshs.texas.gov/chs/info/info_txco.shtm)
fips_df = fips_data[["County Name", "FIPS #"]]#add 48 to end of each county fips so it can be input into plotly to geo graph data
def add_48(s):
    return "48" + str(s)
fips_df["FIPS #"] = fips_df["FIPS #"].map(add_48)cities_df = pd.read_csv("uscities.csv") #need for plotting texas cities, source: [https://simplemaps.com/data/us-cities](https://simplemaps.com/data/us-cities)# for plotting major texas cities
mask = cities_df["state_id"] == "TX"
texas_cities = cities_df[mask]
mask2 = texas_cities["population"] > 200000
big_texas_cities = texas_cities[mask2]
cities_for_map = big_texas_cities[["city", "lat", "lng"]]# load in additional data with long and lat of each county as well as covid-19 case counts for new bubble graph
ts_df = pd.read_csv("time_series_plotly.csv").drop("Unnamed: 0", axis = 1) # I created this data from a previous medium post
county_loc = pd.read_csv("Texas_Counties_Centroid_Map.csv") #source: [https://data.texas.gov/dataset/Texas-Counties-Centroid-Map/ups3-9e8m/data](https://data.texas.gov/dataset/Texas-Counties-Centroid-Map/ups3-9e8m/data)
```

第 1 步非常简单明了,但如果能看到我加载的所有 4 个数据框是什么样子就更好了。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/4a0650cc9e93f0d674eb51451a391cf7.png)

真实的你的形象

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/54aade498a51d3daff25c2df1c1335b6.png)

真实的你的形象

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/10af1dcb5342e3da59dfa280257f228a.png)

真实的你的形象

fips_df 仅包含德克萨斯州每个县的所有 fips 代码,可以使用 plotly 绘制每个县的图形。ts_df 是一个长格式的数据帧,包含自 3 月以来每个县每天的所有新冠肺炎病例计数。county_loc 具有每个县的经度和纬度,但是它们是颠倒的:Y (Long)列具有纬度而不是县的经度,这在绘图时很容易解决。city _ for _ map 具有德克萨斯州人口超过 200,000 的城市的经度和纬度数据。

**2。将相关数据帧合并在一起并清理**

```
#merge covid-19 case counts with county longitude and latitude data
ts_df2 = ts_df.merge(county_loc, how = "left", left_on = "County", right_on = "CNTY_NM")#merge above df with fips data
ts_df3 = ts_df2.merge(fips_df,how = "left", left_on = "County", right_on = "County Name")
def extract_month(s):
    return s[5:7]
ts_df3["month"] = ts_df3["Date"].map(extract_month)# only extract last 4 months of data
mask = ts_df3["month"].astype(int) > 4
ts_df4 = ts_df3[mask]
```

关于上面的代码,需要注意一些事情:

1.  我使用县名作为主键/外键来合并所有三个数据框
2.  我也不必合并 fips_df,但是在使用 county_loc 数据框 fips 列来绘制图表时遇到了问题。
3.  我将只使用最近 4 个月的数据,因为这是最重要的

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/6b52916656e81deb1b6f83f3070a4c03.png)

真实的你的形象

因此,现在数据中每天都有一行,得克萨斯州每个县在过去 4 个月都有新冠肺炎病例计数。

**3。用 groupby()** 格式化要输入到 plotly 图形中的数据

```
df = (ts_df4.groupby(["month", "County", "X (Lat)", "Y (Long)", "FIPS #"])["Case Count"].max()).reset_index()df["month"] = df["month"].astype(int)
```

好了,这就是事情变得有点复杂的地方。我需要按月、县、经度、纬度和 FIPS 分组,然后获得最大案例数。这将为我提供一个数据框,其中包含每个县每个月的总病例数。数据框如下所示。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/b472a68066ea034b78adbfc22fb625f9.png)

真实的你的形象

**4。使用 plotly.express.chorograph()和 plotly.graph_objects 创建图形。散射地理()**

这个图表的绘制需要大量的编码和理解,所以我将分块进行。

```
with urlopen('[https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json'](https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json')) as response:
    counties = json.load(response)fig = px.choropleth(df, geojson=counties, locations='FIPS #',
                           hover_name = "County",
                           scope = "usa",
                           title = "Total Cases"
                          )
```

首先,我们将从绘制德克萨斯州所有县地图的基础数据开始。为此,我们使用 plotly.express.chorograph()函数并输入我们刚刚创建的数据框。然后指定我们希望使用 geojson 库来映射使用 df 中的 FIPS #列的县。Plotly 有关于这个[的很棒的文档。如果我们只是用 fig.show()绘制它,它看起来会像下面的图像。](https://plotly.com/python/choropleth-maps/)

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/3e2143dbcf8f8a1911667f7d4bd1e6f0.png)

```
colors = ['rgb(189,215,231)','rgb(107,174,214)','rgb(33,113,181)','rgb(239,243,255)']
months = {5: 'May', 6:'June',7:'July',8:'Aug'} #plot the bubble cases for each month and each county
for i in range(5,9)[::-1]:
    mask = df["month"] == i
    df_month = df[mask]
    #print(df_month)
    fig.add_trace(go.Scattergeo(
            locationmode = 'USA-states',
            lon = df_month['X (Lat)'],
            lat = df_month['Y (Long)'],
            text = df_month[['County','Case Count']],
            name = months[i],
            mode = 'markers',
            marker = dict(
                size = df_month['Case Count'],
                color = colors[i-6],
                line_width = 0,
                sizeref = 9,
                sizemode = "area",
                reversescale = True
            )))
```

好了,最难的部分来了。首先,我们创建一个颜色列表,其中包含每个月要使用的颜色。我们还为图表的图例创建了一个月份字典。

接下来是 for 循环,每个月循环 4 次。对于每个月,它使用 plotly.graph_objects 根据位置为每个县绘制一个气泡图。Scattergeo()函数。您会注意到 lon 和 lat 变量被交换了,但那是因为我导入的数据有这个问题。我使用变量 sizeref 来归一化气泡点,因为有些县的案例数非常大,如果不进行归一化,这些案例数将在地图上占主导地位。Plotly 建议使用 sizeref:

```
sizeref = 2\. * max(array of size values) / (desired maximum marker size ** 2)
```

但是我发现这个函数并不好用,他们甚至没有在他们的文档示例中使用它。我发现 9 最适合我,但数字非常敏感,我尝试了 0-10 的范围,在选择 9 之前,许多数字使图不可读。以下是当前形式的图:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/66ed91cdf1d6e1fbb7f362ffcee2b2e8.png)

真实的你的形象

所以我们离最终产品越来越近了,但是我们还需要一些东西。

```
# to show texas cities on map
fig.add_trace(go.Scattergeo(
    locationmode = 'USA-states',
    lon = cities_for_map['lng'],
    lat = cities_for_map['lat'],
    hoverinfo = 'text',
    text = cities_for_map['city'],
    name = "Major Cities",
    mode = 'markers',
    marker = dict(
        size = 4,
        color = 'rgb(102,102,102)',
        line = dict(
            width = 3,
            color = 'rgba(68, 68, 68, 0)'
        )
    )))fig.update_geos(fitbounds="locations")
fig.update_layout(title_text='Total Cases per month for last 4 months', title_x=0.5)
fig.show()
```

在上面的代码块中,我们使用经度/纬度数据和 plotly.graph_objects 绘制了德克萨斯州的主要城市。Scattergeo()函数,但没有 for 循环。然后我们更新图表的方向,这样德克萨斯州就很好地适合图表的框架。然后我们更新图表的标题并使其居中。最后,我们可以可视化它的完整形式!

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/0110041ef703f883645edbb520cd8a5b.png)

感谢阅读并可能跟随我的教程!如果你想在 medium 或 LinkedIn 上关注我,请随意。我也一直在寻找对我的帖子和编码的反馈,所以如果你有任何给我,我会非常感谢。

# 如何建立一个强大的商业指数?

> 原文:<https://towardsdatascience.com/how-to-build-an-index-452f5018d5aa?source=collection_archive---------19----------------------->

## 经济学

## 避免阅读中最常见的陷阱

指数是全球和特定国家经济的有力指标。政府和商人大量使用它们来制定经济政策、完善对外贸易和衡量货币价值的变化。

指数旨在反映一个变量(或一组变量)在时间或地理位置等方面的变化。这就是为什么它们通常被用来比较某一天某一现象的水平与前一天****同一天不同地方某一现象的水平。

*ex。将 2020 年 3 月的石油价格与 2019 年 3 月的价格相比较作为基准年。*

那么,为什么索引如此重要呢?他们的主要功能是提供一个基准来衡量你的业绩/投资组合或其他人的选股。这通常被称为“基准”。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/7185e5aa9f2672abe5c58acbbffc10e3.png)

照片由[亚当·诺瓦克斯基](https://unsplash.com/@adamaszczos?utm_source=medium&utm_medium=referral)在 [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral) 上拍摄

# 如何构建它们?

*让我们举一个例子:考虑到 2020 年新冠肺炎的情况,您预计汽车的使用率会比往年有所下降。你想建立一个反映这些变化的指数。*

**1-时间基线的选择**

建立指数的第一步是选择一个合适的年份作为基线。

> **基线**是一个已知值,可以用来比较以后的测量和性能。

基线应该反映“常规和常规”条件。换句话说,它应该没有像战争、饥荒、洪水、政治不稳定……新冠肺炎这样的异常情况!

基准年有两种选择方式:
(a) [**固定基准法**](https://www.emathzone.com/tutorials/basic-statistics/fixed-base-method.html) 基准年不变
(b) [**链基法**](https://www.emathzone.com/tutorials/basic-statistics/chain-base-method.html) 基准年不断变化

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/439ec5c1c99f32e891373d8f32905360.png)

来源:[丹亚尔·艾哈迈德](https://www.slideshare.net/DanyalAhmad10/index-number-79783201)

在该示例中,2007 年的基准年将是 2006 年,2006 年的基准年将是 2005 年,依此类推。

在选择基准年时要特别小心,因为所有的结果都取决于此。从对数据的探索性分析开始并回顾过去是一个好主意。寻找趋势和模式,因为它们包含了你正在寻找的常规和常规条件。避免出现太多异常值或极端“事件”的年份,因为它们可能无法反映正常情况。

**2-变量选择**

建立索引的第二步是选择变量。仅应选择代表性变量 ***,注意指数的用途和类型。*** 代表变量应该是:

> -可识别,
> -随着时间的推移质量稳定,
> -数量相当大,
> -最后反映您想要衡量变化的习惯、习俗或功能。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/1369ca0995cba493280243f444cee3ff.png)

*(来源:*[Gab Pili](https://unsplash.com/@gabpili?utm_source=medium&utm_medium=referral)on[Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral))

*在我们的例子中,我们可以使用燃料消耗量或发动机总小时数作为汽车利用率的代表变量*

**3-平均值的选择**

由于指数是一个特殊的平均数,选择一个合适的平均数是建立一个准确指数的重要一步。

> 平均值有多种类型,如算术平均值、调和平均值、几何平均值、平均值、中间值、众数。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ab8aa48370c077c8f00ccab663cb0324.png)

数据分布对不同平均方法的影响的可视化(来源: [Minitab 博客)](https://blog.minitab.com/blog/quality-business/common-assumptions-about-data-part-2-normality-and-equal-variance)

显然,根据数据的分布,它们很可能产生不同的结果。 ***因此,非常谨慎地选择方法*** 至关重要。从理论上讲,几何平均值最适合这个目的。但是,在实践中,算术平均值是最常用的,因为它最容易遵循和理解。一般将算术方法与基于链的方法相结合,使索引更加一致。

**4-重量的选择**

大多数情况下,指数构建中包含的变量并不具有同等的重要性。因此,应根据变量的相对重要性为其分配适当的权重。权重应该是无偏的,不能任意选取。使用了两个常用的加权指数:
- **基于每个变量价格的价格加权指数**。对于这个指数,价格最高的变量(股票)会比价格较低的变量对指数的走势产生更大的影响。
- **基于各变量数量的价值加权指数**。

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ad767c5dd06b00bd85a0868967d7be08.png)

最受欢迎的价格加权指数之一是道琼斯工业平均指数(DJIA)

*在我们的例子中,燃料消耗可以用汽车总数来加权。*

**5-方法选择**

选择合适的方法是建立索引的最后一步。有很多方法可以计算指数,所以让我们来看看这 3 种流行的方法。

> **简单聚合方法**

在这种方法中,指数等于目标年遵循的变量之和除以基准年的变量之和:

> 指数=[总和(目标年的变量值)/总和(基准年的变量值)] x 100

我们举这个例子来说明一下:

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/9c1d4a49ed1d1a6ca4435bc75089cbe0.png)

> **综合指数的简单平均值**

在这种方法中,指数等于综合指数的平均值:

> 指数=总和(综合指数)/变量计数

![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5b025e25cbc5bce9c429312556c44bfa.png)

> **加权聚合方法**

前两种方法实现起来既简单又快速。但是他们没有考虑到每一项的相对重要性。每个项目在全局索引中具有相同的权重。但是如果公共汽车比卡车多得多呢?为什么卡车会对全球指数产生同样的影响?

在那种情况下,我们宁愿使用加权方法。这些方法允许根据项目的相对重要性分配不同的权重。已经开发了许多方程来根据数量权重估计指数。以下是一些最受欢迎的:

*   *拉斯派尔斯指数是以基准年(q0)的固定权重建立的。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/2318eb28ab2ea2ca67ee74eff7ea4f79.png)*

*来源:作者*

*   ****帕舍指数*** 以当年(q1)的固定权重构建。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/45cfe7a0169b14b291b07bae6c1a0a2a.png)*

*来源:作者*

*   ****Dorbish 和 Bowley 指数*** 是上述两种方法的平均值,因此考虑了这两年的影响。使用算术平均值。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/ac5f1d72bd963edd013822234ba21b02.png)*

*来源:作者*

*   ****费雪理想指数*** 也是拉佩尔指数和帕舍指数的平均值,但使用几何平均值。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/d76748240fc1490d407ebc4de1e503c7.png)*

*来源:作者*

*因此,用同样的例子我们得到:*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/fc3ced6df4d5b2397410f1fd154fbaff.png)*

*来源:作者*

# *选择哪个指数?*

*下表汇总了上述方法的结果和主要优缺点。*

*![](https://gitcode.net/OpenDocCN/towardsdatascience-blog-zh-2020/-/raw/master/docs/img/5b5c6e21c01b355947475f4c8eca1c09.png)*

*来源:作者*

*作为选择使用哪个指数的指导方针,确保:
——它反映了目标市场或细分市场的全面代表性;
-它响应不断变化的市场
-它反映数据质量、分布和随时间的变化(趋势、季节性、变化……)
-它的构建方式是透明和客观的;
-您可以根据您的可用计算时间和机器性能定期重新平衡并轻松维护它。*

# *结论*

*在评估一个指数的适当性时,分析师应该采取一种全面的方法,研究数据,以便建立一个适合其目标的指数,并尽可能地捕捉最大范围的趋势。*

*记住 4 个关键步骤:*

*   ***选择合适的基准年:**一切都取决于此。基线应能捕捉到您想要追踪的特征的季节性和所有常规事件。*
*   ***选择适当的变量**:确保变量反映了您想要测量的变化。*
*   ***选择权重参数和平均法:**很多时候我们分别挑数量和算术平均值。*
*   ***选择索引方法:**这一步取决于您的数据探索结果以及您必须对资源做出的妥协。*

**感谢阅读!如果你喜欢这篇文章,一定要按住按钮鼓掌支持我的写作。我总是愿意聊天和喝杯“虚拟”咖啡,所以来关注我的*[*Linkedin*](https://www.linkedin.com/in/aureliegiraud9000/)*。**

*[](https://agiraud.medium.com/subscribe) [## 不要错过我接下来的文章!

### 不要错过我接下来的文章!我写了关于如何使用数据科学的文章——侧重于提供可操作的见解给…

agiraud.medium.com](https://agiraud.medium.com/subscribe)* 

***参考文献:***

*[](https://www.sentryone.com/white-papers/performance-baselines-and-benchmarks-for-microsoft-sql-server) [## SQL Server 的性能基线和基准

### 进行数据库性能测试以建立基线测量和工作负载性能的能力…

www.sentryone.com](https://www.sentryone.com/white-papers/performance-baselines-and-benchmarks-for-microsoft-sql-server) [](https://www.thebalance.com/different-types-of-weighted-indexes-1214780) [## 价格、价值和未加权指数之间的差异

### 许多交易所交易基金(ETF)使用指数作为其基础基准,因此了解…

www.thebalance.com](https://www.thebalance.com/different-types-of-weighted-indexes-1214780) [](https://www.ftserussell.com/education-center/how-are-indexes-weighted) [## 指数是如何加权的?

### 领先的基准、分析和数据解决方案全球提供商,具有多种资产能力

www.ftserussell.comom](https://www.ftserussell.com/education-center/how-are-indexes-weighted) [](http://www.economicsdiscussion.net/price/index-number/index-numbers-characteristics-formula-examples-types-importance-and-limitations/31211) [## 指数:特征,公式,例子,类型,重要性和局限性

### 广告:在本文中,我们将讨论:- 1。索引号 2 的含义。索引号 3 的特征…

www.economicsdiscussion.net](http://www.economicsdiscussion.net/price/index-number/index-numbers-characteristics-formula-examples-types-importance-and-limitations/31211)*
posted @   绝不原创的飞龙  阅读(57)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示