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

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

使用 OpenCV 的虚拟鼓组

原文:https://towardsdatascience.com/virtual-drum-set-using-opencv-ebcb1553c778?source=collection_archive---------48-----------------------

学习使用 OpenCV 和 Python 的计算机视觉概念构建虚拟架子鼓

如果你是计算机视觉的新手,或者你有强烈的打鼓冲动,但没有鼓,那么你来对地方了!

在本教程中,我们将使用 OpenCV 的计算机视觉的基本概念建立一个虚拟鼓组。如果你是 OpenCV 的初学者,这将是一个很好的尝试教程。

虚拟鼓在行动

我们将从头开始构建项目,最终你会有一个很酷的项目来炫耀!

所有的源代码都可以在这个 GitHub 资源库中找到。首先,在您的本地机器上派生并克隆存储库

git clone link_to_your_forked_repo

装置

你的设备应该安装 Python 3.6+

导航到您的分叉目录(您下载的文件夹)。

通过在终端中运行以下命令,可以在您的环境中安装项目所需的包。

pip install -r requirements.txt

运行文件

在项目文件夹中运行以下命令。

python virtual_drums.py

您将在屏幕上看到添加了鼓的网络摄像头的输出。你可以用一根绿色的棍子敲鼓(钢笔或铅笔都可以)。

需要绿色棒,因为我们使用了一个检测窗口来检测绿色。

在遮光罩下,当窗口(图像中有鼓的部分)检测到绿色物体时,它会将其解释为鼓被击打并播放节拍。

我们现在来看看实现这一点的代码。

代码

在您喜欢的文本编辑器中打开virtual_drums.py文件。

您可以继续构建您自己的文件,或者编辑您下载的文件。我们现在来看看这一切是如何工作的!

我们从导入必要的库开始。如果没有运行pip install -r requirements.txt,你需要在你的环境中安装这些

# Importing the necessary libraries
import numpy as np
import time
import cv2
from pygame import mixer

接下来,我们定义一个函数,当在窗口上检测到绿色对象时播放鼓声。

如果检测到的颜色在我们设定的范围内,我们就播放声音。

# This function plays the corresponding drum beat if a green color object is detected in the region
def play_beat(detected,sound):# Checks if the detected green color is greater that a preset value 
 play = (detected) > hat_thickness[0]*hat_thickness[1]*0.8# If it is detected play the corresponding drum beat
 if play and sound==1:
 drum_snare.play()

 elif play and sound==2:
 drum_hat.play()
 time.sleep(0.001)

接下来,我们定义一个函数来检测绿色是否出现在我们的窗口中。

# This function is used to check if green color is present in the small region
def detect_in_region(frame,sound):

	# Converting to HSV
	hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

	# Creating mask
	mask = cv2.inRange(hsv, greenLower, greenUpper)

	# Calculating the number of green pixels
	detected = np.sum(mask)

	# Call the function to play the drum beat
	play_beat(detected,sound)

	return mask

接下来,我们导入我们的鼓点并存储它。

然后,我们设置应该检测的绿色的上限和下限。你可以把它改变到你想要的颜色的极限。

然后,我们启动网络摄像头并从中读取输入。

# A flag variable to choose whether to show the region that is being detected
verbose = False

# Importing drum beats
mixer.init()
drum_hat = mixer.Sound('./sounds/high_hat_1.ogg')
drum_snare = mixer.Sound('./sounds/snare_1.wav')

# Set HSV range for detecting green color 
greenLower = (25,52,72)
greenUpper = (102,255,255)

# Obtain input from the webcam 
camera = cv2.VideoCapture(0)
ret,frame = camera.read()
H,W = frame.shape[:2]

kernel = np.ones((7,7),np.uint8)

我们将导入要添加到视频输出中的鼓的图像。在这个例子中,我下载并添加了一顶高帽和一个小鼓。

# Read the image of High Hat and the Snare drumhat = cv2.resize(cv2.imread('./images/high_hat.png'),(200,100),interpolation=cv2.INTER_CUBIC)snare = cv2.resize(cv2.imread('./images/snare_drum.png'),(200,100),interpolation=cv2.INTER_CUBIC)

我们现在将设置应该检测绿色的区域或窗口。在本例中,我们有两个鼓,因此我们创建了两个窗口。

# Set the region area for detecting green color 
hat_center = [np.shape(frame)[1]*2//8,np.shape(frame)[0]*6//8]
snare_center = [np.shape(frame)[1]*6//8,np.shape(frame)[0]*6//8]

hat_thickness = [200,100]
hat_top = [hat_center[0]-hat_thickness[0]//2,hat_center[1]-hat_thickness[1]//2]
hat_btm = [hat_center[0]+hat_thickness[0]//2,hat_center[1]+hat_thickness[1]//2]

snare_thickness = [200,100]
snare_top = [snare_center[0]-snare_thickness[0]//2,snare_center[1]-snare_thickness[1]//2]
snare_btm = [snare_center[0]+snare_thickness[0]//2,snare_center[1]+snare_thickness[1]//2]

time.sleep(1)

然后,我们运行一个无限循环,当我们按下键盘上的“Q”时,这个循环就会中断。

我们调用函数在屏幕上显示鼓声,并调用函数检测是否有绿色物体击中窗口。

最后,我们必须在按“Q”退出后清理打开的窗口。

while True:

	# Select the current frame
	ret, frame = camera.read()
	frame = cv2.flip(frame,1)

	if not(ret):
	    break

	# Select region corresponding to the Snare drum
	snare_region = np.copy(frame[snare_top[1]:snare_btm[1],snare_top[0]:snare_btm[0]])
	mask = detect_in_region(snare_region,1)

	# Select region corresponding to the High Hat
	hat_region = np.copy(frame[hat_top[1]:hat_btm[1],hat_top[0]:hat_btm[0]])
	mask = detect_in_region(hat_region,2)

	# Output project title
	cv2.putText(frame,'Virtual Drums',(10,30),2,1,(20,20,20),2)

	# If flag is selected, display the region under detection
	if verbose:
		frame[snare_top[1]:snare_btm[1],snare_top[0]:snare_btm[0]] = cv2.bitwise_and(frame[snare_top[1]:snare_btm[1],snare_top[0]:snare_btm[0]],frame[snare_top[1]:snare_btm[1],snare_top[0]:snare_btm[0]], mask=mask[snare_top[1]:snare_btm[1],snare_top[0]:snare_btm[0]])
		frame[hat_top[1]:hat_btm[1],hat_top[0]:hat_btm[0]] = cv2.bitwise_and(frame[hat_top[1]:hat_btm[1],hat_top[0]:hat_btm[0]],frame[hat_top[1]:hat_btm[1],hat_top[0]:hat_btm[0]],mask=mask[hat_top[1]:hat_btm[1],hat_top[0]:hat_btm[0]])

	# If flag is not selected, display the drums
	else:
		frame[snare_top[1]:snare_btm[1],snare_top[0]:snare_btm[0]] = cv2.addWeighted(snare, 1, frame[snare_top[1]:snare_btm[1],snare_top[0]:snare_btm[0]], 1, 0)
		frame[hat_top[1]:hat_btm[1],hat_top[0]:hat_btm[0]] = cv2.addWeighted(hat, 1, frame[hat_top[1]:hat_btm[1],hat_top[0]:hat_btm[0]], 1, 0)

	cv2.imshow('Output',frame)
	key = cv2.waitKey(1) & 0xFF
	# 'Q' to exit
	if key == ord("q"):
		break# Clean up the open windows
camera.release()
cv2.destroyAllWindows()

就是这样!现在你可以用你的虚拟架子鼓演奏了。尝试更换鼓或将更多鼓添加到项目中。

您可以利用这些知识,通过 OpenCV 构建自己的计算机视觉应用程序。

编码快乐!

虚拟环境:什么,为什么,如何?

原文:https://towardsdatascience.com/virtual-environment-what-why-how-82665f186ebf?source=collection_archive---------55-----------------------

使用虚拟环境管理 python 和 python 包

图片由 용한 배 发自 Pixabay

Mac 预装 python 2。通过安装不同版本的 python 和不同的包,可以在 Mac 上的不同目录中安装更多的 python 环境。了解您正在使用哪种 python 非常重要。

您可以通过在终端中键入以下代码来检查当前正在使用的 python:

ericli@ERICYNLI-MB0 ~ % which python 
/usr/bin/python

在这个例子中,我目前使用的 python 是预装的 python 2。如果 python 不是您想要使用的,那么您可能会遇到一个小问题。您可以通过将所需 python 的目录放在 Mac 上 path 变量的开头来解决这个问题。但是不推荐这种方法,因为如果您需要为不同的项目使用不同版本的 python 或 python 包,您将不得不一致地升级或降级您的 python 或 python 包。在这种情况下,强烈建议使用虚拟环境。

虚拟环境

虚拟环境是包含特定版本的 python 及其相关包的目录。虚拟环境是完全隔离的,因此您可以在 Mac 上拥有任意多个虚拟环境,并且始终非常清楚您正在使用哪个虚拟环境。

我强烈建议每个人在进入下一步之前安装 Anaconda,因为它很简单。在您安装了 Anaconda(【https://docs.anaconda.com/anaconda/install/】)之后,您需要将 Anaconda bin 的目录添加到路径中。要添加目录,只需输入以下代码并键入您的 Mac 密码:

ericli@ERICYNLI-MB0 ~ % sudo vim /etc/paths 
Password:

对于那些感兴趣的人来说,“sudo”的意思是“超级用户 do”,它授予当前用户管理员权限。输入密码并按 enter 键后,您会看到如下内容:

/usr/local/bin 
/usr/bin 
/bin 
/usr/sbin 
/sbin

在该文件中,创建一个新行,并将 Anaconda bin 目录添加到该文件中。

/usr/local/bin 
/usr/bin 
/bin 
/usr/sbin 
/sbin 
/opt/anaconda3/bin

文件保存后,您可以在终端中使用“conda”命令。

Vim 命令提示:
"o ":在光标下打开新一行
"O ":在光标上方打开新一行
":wq ":保存并退出
":q ":退出
":q!":强制退出(当有不需要的更改时)

使用 conda 命令,您可以使用所需的 python 版本和 python 包创建虚拟环境。通过激活虚拟环境,您在 Mac 上的路径被修改——虚拟环境的目录被放在路径文件的开头,因此一旦在虚拟环境中找到,您输入的任何命令都将被搜索和执行。

使用 python 版创建虚拟环境并激活它:

ericli@ERICYNLI-MB0 ~ % conda create --name py38 python=3.8 ericli@ERICYNLI-MB0 ~ % conda activate py38

要检查虚拟环境列表和当前环境(标有星号):

(py38) ericli@ERICYNLI-MB0 ~ % conda env list 
# conda environments:
#
base                     /opt/anaconda3
py38                  *  /opt/anaconda3/envs/py38

要检查当前环境中安装了哪些软件包,并安装其他软件包:

(py38) ericli@ERICYNLI-MB0 ~ % conda list 
(py38) ericli@ERICYNLI-MB0 ~ % conda install PACKAGENAME

激活新环境后,您会发现您正在使用的 python 就是您的虚拟环境中的 python。

(py38) ericli@ERICYNLI-MB0 ~ % which python /opt/anaconda3/envs/py38/bin/python

现在,您的新虚拟环境已经设置好了。您可以通过在终端中输入“python”或“jupyterlab ”(如果您安装了 jupyter lab)来开始使用这个环境。

最初发表于【http://github.com】

数据科学的虚拟环境:使用 Pipenv 运行 Python 和 Jupyter

原文:https://towardsdatascience.com/virtual-environments-for-data-science-running-python-and-jupyter-with-pipenv-c6cb6c44a405?source=collection_archive---------8-----------------------

为 Python 设置虚拟环境。

作者: Edward Krueger 数据科学家兼讲师和 Douglas Franklin 助教兼技术作家。

在这篇文章中,我们将谈论虚拟环境以及它们为什么有用。您将学习如何在 Pipenv for Python 中设置虚拟环境。您还将学习如何在 Pipenv 环境之外运行 Jupyter 内核!

照片由 Unsplash 上的 Clément H 拍摄

为什么环境对数据科学至关重要

环境是开发人员工作、学习和创造的空间。例如,如果您计划运行 Python 代码,您必须安装一些本地软件来练习 Python。这种设置被称为编程环境。这些环境包含开发人员创建和测试代码所需的特定工具。例如,一个环境可能包含 Python 和一些包。一旦环境设置正确,开发人员就可以畅通无阻地工作,并与其他人无缝地共享环境规范。

由于缺乏对虚拟环境的了解或经验,新开发人员通常在系统级别安装所有东西。用 pip 安装的软件包被放置在系统级。对每个项目都这样做的结果是一个臃肿且难以管理的单一 Python 环境。

有效的环境管理可以节省时间,并允许开发人员创建一个独立的软件产品,以便合作者或贡献者可以重新创建您的环境并运行您的代码。

Pipenv 将软件包管理和虚拟环境控制结合到一个工具中,用于安装、删除、跟踪和记录您的依赖关系;以及创建、使用和管理您的虚拟环境。Pipenv 本质上是将 pip 和 virtualenv 包装在一个产品中。

我们在开发过程中都遇到过这种错误。

ModuleNotFoundError: No module named 'pandas'

该错误意味着 Python 找不到该模块(也称为依赖项或包)。你肯定你在某个地方安装了熊猫,但是它在哪里呢?

Python 虚拟环境的主要目的是为 Python 项目创建一个隔离的环境。适当的隔离意味着每个项目都可以有自己的依赖项,而不管其他项目有什么依赖项。通过对环境和依赖关系的适当维护,可以避免上述错误和许多其他错误。健康的环境管理实践减少了项目之间的依赖版本冲突,并防止基础开发环境被包所膨胀。

数据科学和部署问题

数据科学家通常是跨学科的,没有受过正式的教育,无法与他人合作,将项目推向生产。因此,通常缺乏良好的环境和模块管理技能。这可能会导致代码可复制性的问题,或者推进或共享项目的困难。可再现的数据科学项目是那些允许其他人在您的分析基础上重新创建和构建,并重用和修改您的代码的项目。

卫生环境管理实践减少了项目之间的依赖版本冲突,并防止基础开发环境变得臃肿和不可管理,从而帮助用户创建可重复的项目。

xkcd 提供

Pipenv:更好的工作流程

Pipenv 将包管理和虚拟环境控制结合到一个工具中,使其成为数据科学家和开发人员的绝佳工具。

当您使用 Pipenv 开始一个项目时,该工具会自动创建一个虚拟环境、一个 Pipfile 和一个 Pipfile.lock。当您使用 Pipenv 安装时,Pipfile 会自动使用新的依赖项进行更新。

为了管理复杂的依赖关系,Pipenv 在一个名为 Pipfile.lock 的文件中保存了我们项目的依赖关系树;例如,依赖于其他旧版本依赖项的旧版本依赖项。Pipfile.lock 还验证生产中使用的依赖项版本是否正确。

最后,使用 Pipenv,您向其他人展示了一种安装项目依赖项以及测试和开发需求的标准化方法。

Pipenv 是一个环境管理器和包管理器。这意味着 Pipenv 可以用 Python 创建一个环境,然后用pipenv install将包下载并安装到一个环境中。

此命令将依赖 Pipfile 来创建 Pipfile 存在的环境;如果没有,Pipenv 将为这个环境创建一个 Pipfile。

附加到该命令的包将被添加到 Pipfile 中。

pipenv install pandas matplotlib keras

Pipenv 工作流:终端

设置您的第一个 Pipenv:安装 Python、Pipenv 和 Pandas

  1. 安装Python3.7
  2. 打开端子安装** Pipenv**
pip install pipenv

3.创建一个新目录,并导航至该目录。

mkdir pipenv_test
cd pipenv_test

4.通过运行以下命令为环境安装** pandas 和 NumPy:**

pipenv install pandas numpy

注意,Pipenv 将为这个项目创建一个虚拟环境、一个 Pipfile 和一个 Pipfile.lock。

可以用uninstall关键字类似地删除包。

pipenv uninstall pandas

5.通过以下方式激活项目的虚拟环境:

pipenv shell

测试导入

完成上述操作后,您现在应该能够运行:

pipenv shell

接下来,使用以下命令打开 Python 解释器:

python

然后在 Python 解释器中:

import pandas

成功进口熊猫

如果成功的话,你正在改进你的开发工作流程!

如果出现任何问题,请确保在运行python之前已经运行了pipenv shell,并通过运行以下命令来验证环境中是否存在依赖项。

pipenv graph

Pipenv 依赖关系树

Pipenv 工作流:Jupyter

设置您的第一个 Pipenv:安装 Pipenv、Python 和 Jupyter

  1. 安装**Python3.7******

注: 3.8 与 Jupyter 在创作时是不兼容的

2.打开一个终端,在你的机器上安装 Jupyter Lab。

**pip install jupyterlab**

3。用以下工具安装管道:

**pip install pipenv**

4.创建一个新目录,并导航至该目录。

**mkdir pipenv_test
cd pipenv_test**

5.通过运行以下命令为环境安装 Ipykernel 和 Numpy:

**pipenv install ipykernel numpy**

注意,Pipenv 将为这个项目创建一个虚拟环境和一个 Pipfile。

6.激活项目的虚拟环境:

**pipenv shell**

7.连接环境到内核:

**python -m ipykernel install --user --display-name pipenv_test --name pipenv_test**

完成上述操作后,您现在应该能够运行:

**jupyter notebook**

或者您更喜欢实验室用户界面和附加功能。

**jupyter lab**

Jupyter Notebook 中,选择“新建”查看下拉列表,查看可用内核列表。请注意,上面第 3 步中创建的“example_env”是内核的名称。

在笔记本中选择一个内核

Jupyter Lab 中,你必须点击右上角的内核框来访问内核列表。或者,您可以单击“内核”选项卡,然后选择“更改内核”来访问同一个下拉菜单。

在实验室中选择内核

测试导入

在一个新的。ipynb 文件,尝试在单元格中运行以下代码。

**import pandas**

如果成功的话,你正在改进你的开发工作流程!

如果出现任何问题,请确保您选择了正确的内核,在运行jupyter labjupyter notebook以及连接内核之前,您已经运行了pipenv shell。同样,您可以通过运行。

**pipenv graph**

Pipenv 依赖关系树

环境管理:

Pipenv 可用于指定 Python 版本和包版本。

**pipenv install django=1.11.10**

Python 规范:

**pipenv --python <path>
#or
pipenv --python python3**

Pipenv 可以从 requirements.txt 文件构建:

**$ pipenv install -r requirements.txt**

并且一个 requirements.txt 文件可以用包 pipenv-to-requirements 从 Pipfile 中创建。

**pipenv install pipenv_to_requirements**

然后运行:

**pipenv run pipenv_to_requirements**

这将在当前目录中生成 requirements.txt 和 requirements-dev.txt(如果适用)。

开发依赖性

Pipfile 将依赖项组织成两类,开发包和包。通过附加一个 dev 标志,可以将一个包指定为一个开发依赖项(不在生产中使用)。

**pipenv install black --dev**

管道文件结构

删除环境

使用pipenv —-rm 命令可以轻松删除环境。要再次创建环境,使用命令pipenv install

项目目录中的文件将保留。如果您希望删除它们,请删除整个目录。

结论

当您想要重现代码时,将所有的包安装在一个环境中会成为一个问题。想象一下,当项目只需要 6 个包时,导出一个列出 200 个包的 requirements.txt 文件。

Pipenv 将软件包管理和虚拟环境控制结合到一个工具中,用于安装、删除、跟踪和记录您的依赖关系;以及创建、使用和管理您的虚拟环境。

Pipfiles 添加到您的 Git 存储库中很好,这样其他用户就可以克隆存储库并在他们的系统上安装 Pipenv ,然后键入:

**pipenv install**

Pipenv 然后定位 Pipfiles ,创建一个新的虚拟环境,并安装必要的包。

Pipenv 之所以伟大是因为。

  • 虚拟环境可以很容易地从 Pipfile 中重建
  • 虚拟环境可轻松部署到服务器上
  • Pipenv 使卫生包装和环境管理变得容易
  • 适当管理的环境使协作者能够轻松地与您的代码交互并运行您的代码

有关更多信息,请查看虚拟环境的 Pipenv 文档说明。

Anaconda Jupyter 笔记本中的虚拟环境—简易指南

原文:https://towardsdatascience.com/virtual-environments-in-anaconda-jupyter-notebook-f92cda7184fa?source=collection_archive---------11-----------------------

数据科学

在您的笔记本电脑中创建第一个 virtualenv 的简单步骤

为什么需要虚拟环境?

Python 有自己独特的下载、存储和解析包(或模块)的方式。虽然这有它的优点,但是有一些有趣的关于包存储和解决的决定,这导致了一些问题,特别是关于包如何和在哪里存储。

什么是虚拟环境?

Python 虚拟环境的主要目的是为 Python 项目创建一个隔离的环境。这意味着每个项目都可以有自己的依赖项,而不管其他项目有什么依赖项。

最棒的是,您可以拥有的环境数量没有限制,因为它们只是包含几个脚本的目录。另外,它们很容易创建。

让我们直接进入您的 Jupyter 笔记本主页,转到新的下拉菜单,然后选择终端

开始编写以下命令

conda create -n myenv python=3.7

欢迎您更改您想要的 python 版本和环境名称。

然后按回车键。

Python 将要求安装如下默认包:

将下载以下软件包:

包|构建
—————|———
certificate-2020 . 4 . 5 . 1 | py37 _ 0 155 KB
python-3 . 7 . 7 | HC 70 fcce _ 0 _ cpython 19.8 MB
setup tools-46 . 1 . 3 | py37 _ 0 520 KB
———————

将安装以下新软件包:

ca-certificates pkgs/main/OS x-64::ca-certificates-2020 . 1 . 1–0
certify pkgs/main/OS x-64::certify-2020 . 4 . 5 . 1-py37 _ 0
libc xx pkgs/main/OS x-64::libc xx-4 . 0 . 1-hcfea 43d _ 1
libcxxabi pkgs/main/OS x-64::libc xxabi-4 .

继续吗?

点击“y”

Python 会告诉你如何在需要的时候激活你的环境。

要激活此环境,请使用

$ conda activate myenv

要停用活动环境,请使用

$ conda deactivate

让我们从编码开始

conda activate myenv

您会注意到环境的名称将出现在下一行代码的旁边,如(myenv)

现在,让我们来看看在这种环境下我们需要一个特定的内核。

我们希望能够在 Jupyter 笔记本主页的下拉菜单中点击并选择我们的环境。

让我们从安装 ipykernel 库开始

pip install ipykernel

下一步,我们将编写以下代码:

ipython kernel install — user — name=myenv

您应该会收到一条消息

将 kernelspec myenv 安装在/Users/yasserimam/Library/Jupyter/kernels/myenv 中

现在你可以回到你的 Jupyter 笔记本主页,你会发现内核。

快乐编码:)

使用 JavaScript 和 PoseNet 的虚拟方向盘

原文:https://towardsdatascience.com/virtual-steering-wheel-with-javascript-and-posenet-12439712a68?source=collection_archive---------34-----------------------

的力量深度学习 架构和方便的tensor flow . js*库允许我们创建有趣的应用程序,改变我们与计算机的交互方式。在这种情况下,我们使用姿势估计神经网络来基于手腕的位置创建一个 虚拟方向盘 *

XR Expo 在 Unsplash 上拍摄的照片

介绍

在这个项目中,我将展示一个 web 应用程序和深度学习模型之间的集成示例,以将应用程序控制从鼠标和键盘转移到人体。

在这种情况下,我创建了一个虚拟方向盘来在高速公路上驾驶车辆。

视频截图来自 Github 自述 |作者 gif

它是如何工作的

摘要

利用手腕的坐标,我们可以计算它们之间的线段,然后计算它与水*轴形成的角度,如果这个角度大于 25°或小于-25°,那么车辆将分别向左或向右转弯。

利用 PoseNet CNN 检测手的位置

PoseNet 包包含一个独立的机器学习模型,用于使用 TensorFlow.js 在浏览器中运行实时姿态估计

PoseNet 可以用于估计单个姿态多个姿态,这意味着有一个版本的算法只能检测图像/视频中的一个人,还有一个版本可以检测图像/视频中的多人。在这种情况下,我们将使用单人算法。

图片由 Dan 在浏览器中用 TensorFlow.js实时人体姿态估计中移除

该模型接收来自摄像机的图像,并因此返回身体每个部分的位置及其坐标的数组。

在我们的例子中,我们只需要手腕的位置来驾驶汽车和绘制“方向盘”。

正如我们在代码中看到的,结果给了我们坐标与手在【x,y】变量中的位置。

更多关于波森特的信息。

用代数来模拟方向盘

让我们开始思考,如果车辆应该向左、向右转向或保持直线行驶,需要考虑哪些条件。

当我们想到方向盘时,很容易想象在每种情况下方向盘的位置是什么样子。

三种可能状态的表示|作者图片

一旦我们看到图像,我们可以看到手与水*轴之间的线段所形成的角度是检测实际状态的一个很好的方法,例如,如果右手在左手上方(形成一个正角度),那么车辆应该左转。

我们也可以使用垂直距离,但这不是最通用的,因为它与人相对于摄像机的位置成比例。

其中α (alpha)是作者用手形成的线段和横轴|图像之间的角度

改变状态的角度限制

一旦我们确定改变状态的条件是基于角度,我们必须确定从一个状态改变到另一个状态的极限。

经过一些实验后,我发现(-25,25)是一个很好的范围,可以确定车辆是左转、右转还是保持直线行驶。

状态变化的角度限制,avobe 25 左转,25°以下右转,在[-25,25 ]范围内保持直线|图片由作者提供

计算角度

使用一些代数,我们可以很容易地获得手形成的线段和横轴之间的角度,如下所示。

一旦我们有了角度,我们就可以更新应用程序状态来改变汽车控制的方向。

这段代码可能不是最理想的,但是这里的想法是展示它是如何工作的

结论

这只是一个简单的例子,说明我们可以在浏览器中使用这些机器学习库做什么,但它增加了各种各样新的酷功能和与网页交互的方式。

如果您对这项技术的其他好的用途有想法,我邀请您开发并展示它们。

我们建造的一切我们认为有价值的东西都值得展示😉

Github 回购:https://github.com/MCarlomagno/CarDrivingResNet

基于视觉的月球跟踪器

原文:https://towardsdatascience.com/vision-based-moon-tracker-a39ab03b14?source=collection_archive---------67-----------------------

帮助你基于Mask-RCNN创建月球追踪器(图片&视频)的完整指南。改变数据集,标记你选择的物体,你就可以创建你自己的物体跟踪器了!没有必要为你的第一个定制的追踪器四处游荡。

一帧一帧的月球追踪器(图片作者)

(追踪器的)为什么部分

我们都或多或少地被月亮的美丽所吸引。夜空中最大最亮的物体。

有很多app可以追踪月球的运动。关于月亮,没有什么是不可预测的。从这个角度来看,月球是简易追踪器的理想选择。

但是,现在从更广泛的意义上来说,一个智能物体追踪器可以安装在一个固定的位置,或者安装在一个移动的车辆甚至是卫星上。您相机的视野可能不同。如果物体移动,那么理想情况下,您的算法应该向摄像设备发出准确的 PTZ 命令(方向和移动速率)来跟踪感兴趣的物体。很复杂。

现在让我们简化一下。

从算法的角度来看,有两件事很重要:

  1. (运动)物体随时间(实时)检测和定位的精度。
  2. 速度/帧率处理。否则,当你发现的时候,物体可能已经到达了你(相机)够不到的地方。

我们要做什么部分

由于这更多的是一篇技术文章,我只是分享这个项目的关键,来帮助你一步一步地创建一个月球追踪器(或者你选择的任何定制对象)。假设你有 mask-RCNN 的基础知识,即使你没有,你仍然可以遵循这个。

基于 Mask-RCNN 的简单 月球跟踪器

现在,怎么做的部分

第一步:设置环境并加载必要的软件包。

使用 Google colab 是可选的。这是一个很好的选择:

  1. 如果数据不敏感
  2. 如果你有很多数据
  3. 如果你没有本地 GPU
**from** **google.colab** **import** drive
drive.mount('/content/drive/')**import** **os**
os.chdir("drive/My Drive/Colab Notebooks/moon-tracker/")---------------------------------------------------------**from** **mrcnn.config** **import** Config
**from** **mrcnn** **import** model **as** modellib
**from** **mrcnn** **import** visualize
**import** **mrcnn**
**from** **mrcnn.utils** **import** Dataset
**from** **mrcnn.model** **import** MaskRCNN
**import** **numpy** **as** **np**
**from** **numpy** **import** zeros
**from** **numpy** **import** asarray
**import** **colorsys**
**import** **argparse**
**import** **imutils**
**import** **random**
**import** **cv2**
**import** **os**
**import** **time**
**from** **matplotlib** **import** pyplot
**from** **matplotlib.patches** **import** Rectangle
**from** **keras.models** **import** load_model
%matplotlib inline
**from** **os** **import** listdir
**from** **xml.etree** **import** ElementTree

您可以选择将数据保存在驱动器上,然后像上面一样装载到您的环境中。此外,您可以选择在会议期间直接上传,但只有在会议结束后才能上传。

第二步:准备好你的训练和测试数据集。

即您的图像和相应的对象遮罩。

好吧,如果你没有,为了创建掩码并把它作为一个 XML 文件,你可以使用 Labellmg。

(图片作者)

(图片作者)

训练和测试集的读取是基于你保存和生成 XML 文件的方式。参考代码,如果你喜欢下面的结构。

月球追踪器

— — — —月亮 _ 面具 _ 完整

— — — — — —图片(所有图片 jpg/png 等)

— — — — — —注释(图像遮罩的 XML 文件)

**class** **MoonDataset**(Dataset):
    *# load the dataset definitions*
    **def** load_dataset(self, dataset_dir, is_train=**True**):

        *# Add classes. We have only one class to add.*
        self.add_class("dataset", 1, "moon")        

        *####################################################################*
        *# define data locations for images and annotations*
        images_dir = 'moon_mask_full/images/'
        annotations_dir = 'moon_mask_full/annotations/'
        *####################################################################*

        annot_list = []
        **for** annot **in** listdir(annotations_dir):
              annot_list.append(annot.split('.')[0])

        *# Iterate through all files in the folder to* 
        *#add class, images and annotaions* 
        **for** filename **in** listdir(images_dir):

            *# extract image id for all formats like jpg / png / jpeg* 
            image_id =    filename.split('.')[0]    
            *#print(image_id)*

            *# There can be a chance that you don't created xml file for all the images.* 
            *# To filter images which have corresponding mask XML file.*

            **if** image_id != '' **and** image_id **in** annot_list:
              *# setting image file*
              img_path = images_dir + filename
              *#print(img_path)*
              *# setting annotations file*
              ann_path = annotations_dir + image_id + '.xml'
              *#print(ann_path)*
              *# adding images and annotations to dataset*
              self.add_image('dataset', image_id=image_id, path=img_path, annotation=ann_path)

    *# extract bounding boxes from an annotation file*
    **def** extract_boxes(self, filename):

        *# load and parse the file*
        tree = ElementTree.parse(filename)
        *# get the root of the document*
        root = tree.getroot()
        *# extract each bounding box*
        boxes = list()
        **for** box **in** root.findall('.//bndbox'):
            xmin = int(box.find('xmin').text)
            ymin = int(box.find('ymin').text)
            xmax = int(box.find('xmax').text)
            ymax = int(box.find('ymax').text)
            coors = [xmin, ymin, xmax, ymax]
            boxes.append(coors)

        *# extract image dimensions*
        width = int(root.find('.//size/width').text)
        height = int(root.find('.//size/height').text)

        *#print(boxes, width, height)*
        **return** boxes, width, height

    *# load the masks for an image*
    *"""Generate instance masks for an image.*
 *Returns:*
 *masks: A bool array of shape [height, width, instance count] with*
 *one mask per instance.*
 *class_ids: a 1D array of class IDs of the instance masks.*
 *"""*
    **def** load_mask(self, image_id):
        *# get details of image*
        info = self.image_info[image_id]
        *#print(info)*
        *# define anntation  file location*
        path = info['annotation']

        *# load XML*
        boxes, w, h = self.extract_boxes(path)

        *# create one array for all masks, each on a different channel*
        masks = zeros([h, w, len(boxes)], dtype='uint8')

        *# create masks*
        class_ids = list()
        **for** i **in** range(len(boxes)):
            box = boxes[i]
            row_s, row_e = box[1], box[3]
            col_s, col_e = box[0], box[2]
            masks[row_s:row_e, col_s:col_e, i] = 1
            class_ids.append(self.class_names.index('moon'))
        **return** masks, asarray(class_ids, dtype='int32')

    *# load an image reference*
    *"""Return the path of the image."""*
    **def** image_reference(self, image_id):
        info = self.image_info[image_id]
        *#print(info)*
        **return** info['path']

第三步:下载 COCO weights 'mask _ rcnn _ COCO . H5'并保存在主文件夹中。

链接:https://github.com/matterport/Mask_RCNN/releases

*#load the weights for COCO*
model.load_weights('mask_rcnn_coco.h5', 
                   by_name=**True**, 
                   exclude=["mrcnn_class_logits", "mrcnn_bbox_fc",  "mrcnn_bbox", "mrcnn_mask"])

步骤 4:调整训练和学习参数,以微调模型。

使用配置、learning_rate、epoch 和 layers ('all '、' 3+'、' 4+'、' heads ')来获得更好的准确性。

**class** **moon_detector_Config**(Config):
    *# give the configuration a recognizable name*
    NAME = "moon_detector_Config"

    *# set the number of GPUs to use along with the number of images*
    *# per GPU*
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1

    *# number of classes (we would normally add +1 for the background)*
     *# moon + BG*
    NUM_CLASSES = 1+1

    *# Number of training steps per epoch*
    STEPS_PER_EPOCH = 50

    *# Learning rate*
    LEARNING_RATE=0.001

    *# Skip detections with < 90% confidence*
    DETECTION_MIN_CONFIDENCE = 0.95

    *# setting Max ground truth instances*
    MAX_GT_INSTANCES=1   

    *# Maximum instances in a frame. Only one moon possible.* 
    *# But can have different number based on the object example cat, dog, bus, car etc.*
    DETECTION_MAX_INSTANCES = 1config = moon_detector_Config()config.display()
--------------------------------------------------------------------Configurations:
BACKBONE                       resnet101
BACKBONE_STRIDES               [4, 8, 16, 32, 64]
BATCH_SIZE                     1
BBOX_STD_DEV                   [0.1 0.1 0.2 0.2]
COMPUTE_BACKBONE_SHAPE         None
DETECTION_MAX_INSTANCES        1
DETECTION_MIN_CONFIDENCE       0.95
DETECTION_NMS_THRESHOLD        0.3
FPN_CLASSIF_FC_LAYERS_SIZE     1024
GPU_COUNT                      1
GRADIENT_CLIP_NORM             5.0
IMAGES_PER_GPU                 1
IMAGE_CHANNEL_COUNT            3
IMAGE_MAX_DIM                  1024
IMAGE_META_SIZE                14
IMAGE_MIN_DIM                  800
IMAGE_MIN_SCALE                0
IMAGE_RESIZE_MODE              square
IMAGE_SHAPE                    [1024 1024    3]
LEARNING_MOMENTUM              0.9
LEARNING_RATE                  0.001
LOSS_WEIGHTS                   {'rpn_class_loss': 1.0, 'mrcnn_class_loss': 1.0, 'mrcnn_mask_loss': 1.0, 'mrcnn_bbox_loss': 1.0, 'rpn_bbox_loss': 1.0}
MASK_POOL_SIZE                 14
MASK_SHAPE                     [28, 28]
MAX_GT_INSTANCES               1
MEAN_PIXEL                     [123.7 116.8 103.9]
MINI_MASK_SHAPE                (56, 56)
NAME                           moon_detector_Config
NUM_CLASSES                    2
POOL_SIZE                      7
POST_NMS_ROIS_INFERENCE        1000
POST_NMS_ROIS_TRAINING         2000
PRE_NMS_LIMIT                  6000
ROI_POSITIVE_RATIO             0.33
RPN_ANCHOR_RATIOS              [0.5, 1, 2]
RPN_ANCHOR_SCALES              (32, 64, 128, 256, 512)
RPN_ANCHOR_STRIDE              1
RPN_BBOX_STD_DEV               [0.1 0.1 0.2 0.2]
RPN_NMS_THRESHOLD              0.7
RPN_TRAIN_ANCHORS_PER_IMAGE    256
STEPS_PER_EPOCH                50
TOP_DOWN_PYRAMID_SIZE          256
TRAIN_BN                       False
TRAIN_ROIS_PER_IMAGE           200
USE_MINI_MASK                  True
USE_RPN_ROIS                   True
VALIDATION_STEPS               50
WEIGHT_DECAY                   0.0001

加载数据集

*# prepare train set*
train_set = MoonDataset()
train_set.load_dataset( 'train_data_path/')
train_set.prepare()
print('Train: **%d**' % len(train_set.image_ids))
*# prepare test/val set*
test_set = MoonDataset()
test_set.load_dataset('test_data_path/')
test_set.prepare()
print('Test: **%d**' % len(test_set.image_ids))

加载基础模型

print("Loading Mask R-CNN model...")
model = modellib.MaskRCNN(mode="training", config=config, model_dir='./')

调整 learning_rate、epoch 和 layers 并训练

层从['全部',' 3+',' 4+','头']中选择

范围[5–50]内的纪元

*## train heads with higher lr to speedup the learning*
model.train(train_set, test_set, learning_rate=config.LEARNING_RATE, epochs=50, layers='3+' )
history = model.keras_model.history.history

为将来保存模型

model_path =  ' path to your model' + 'name' + '.h5' 
model.keras_model.save_weights(model_path)

5。测试新的一组图像

*# Load pretrained moon mask* 

model_path = 'moon_model/moon_mask_rcnn_125.h5' # the model you created**from** **keras.preprocessing.image** **import** load_img
**from** **keras.preprocessing.image** **import** img_to_array*#Loading the model in the inference mode*
model = modellib.MaskRCNN(mode="inference", config=config, model_dir='./')
*# loading the trained weights o the custom dataset*
model.load_weights(model_path, by_name=**True**)input_path = "test_images/"

**for** i **in** os.listdir(input_path):

    img = load_img(input_path + i)
    img = img_to_array(img)
    *# detecting objects in the image*
    result= model.detect([img])

    *# Run object detection*
    results = model.detect([img], verbose=1)
    *# Display results*

    r = results[0]
    visualize.display_instances(img, r['rois'], r['masks'], r['class_ids'], 
                                test_set.class_names, r['scores'], 
                                title="Predictions")

输出。(图片作者)

步骤 6:通过添加更多相关的掩模图像来微调模型,调整步骤 4 中的参数。

第七步:视频月亮追踪器

为了在视频中做同样的事情,在 Opencv 中使用视频的逐帧提取,并在每一帧中应用模型。

**import** **cv2**
**import** **numpy** **as** **np**

**def** random_colors(N):
    np.random.seed(1)
    colors = [tuple(255 * np.random.rand(3)) **for** _ **in** range(N)]
    **return** colors

**def** apply_mask(image, mask, color, alpha=0.5):
    *"""apply mask to image"""*
    **for** n, c **in** enumerate(color):
        image[:, :, n] = np.where(
            mask == 1,
            image[:, :, n] * (1 - alpha) + alpha * c,
            image[:, :, n]
        )
    **return** image

**def** display_instances(image, boxes, masks, ids, names, scores):
    *"""*
 *take the image and results and apply the mask, box, and Label*
 *"""*
    n_instances = boxes.shape[0]
    colors = random_colors(n_instances)

    **if** **not** n_instances:
        print('NO INSTANCES TO DISPLAY')
    **else**:
        **assert** boxes.shape[0] == masks.shape[-1] == ids.shape[0]

    **for** i, color **in** enumerate(colors):
        **if** **not** np.any(boxes[i]):
            **continue**

        y1, x1, y2, x2 = boxes[i]
        label = names[ids[i]]
        score = scores[i] **if** scores **is** **not** **None** **else** **None**
        caption = '**{}** **{:.2f}**'.format(label, score) **if** score **else** label
        mask = masks[:, :, i]

        image = apply_mask(image, mask, color)
        image = cv2.rectangle(image, (x1, y1), (x2, y2), color, 2)
        image = cv2.putText(
            image, caption, (x1, y1), cv2.FONT_HERSHEY_COMPLEX, 0.7, color, 2
        )

    **return** image

设置路径和文件夹名称。

**import** **os**
**import** **sys**

batch_size = 1

ROOT_DIR = os.getcwd()
MODEL_DIR = os.path.join(ROOT_DIR, "logs")
VIDEO_DIR = os.path.join(ROOT_DIR, "video_moon/")
VIDEO_SAVE_DIR = os.path.join(VIDEO_DIR, "frames_object_detection/")
MODEL_PATH = os.path.join(ROOT_DIR, "moon_model/moon_mask_rcnn_125.h5")
model.load_weights(MODEL_PATH, by_name=**True**)
class_names = 'moon'

获取视频并使用我们的模型逐帧分析。

capture = cv2.VideoCapture(os.path.join(VIDEO_DIR, 'moon_zoom.mp4'))
**try**:
    **if** **not** os.path.exists(VIDEO_SAVE_DIR):
        os.makedirs(VIDEO_SAVE_DIR)
**except** **OSError**:
    print ('Error: Creating directory of data')
frames = []
frame_count = 0
*# these 2 lines can be removed if you dont have a 1080p camera.*
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)

**while** **True**:
    ret, frame = capture.read()
    *# Bail out when the video file ends*
    **if** **not** ret:
        **break**

    *# Save each frame of the video to a list*
    frame_count += 1
    frames.append(frame)
    print('frame_count :**{0}**'.format(frame_count))
    **if** len(frames) == batch_size:
        results = model.detect(frames, verbose=0)
        print('Predicted')
        **for** i, item **in** enumerate(zip(frames, results)):
            frame = item[0]
            r = item[1]
            frame = display_instances(
                frame, r['rois'], r['masks'], r['class_ids'], class_names, r['scores']
            )
            name = '**{0}**.jpg'.format(frame_count + i - batch_size)
            name = os.path.join(VIDEO_SAVE_DIR, name)
            cv2.imwrite(name, frame)
            print('writing to file:**{0}**'.format(name))
        *# Clear the frames array to start the next batch*
        frames = []

capture.release()

这是我们首尾相连的月球追踪器整装待发。请试验代码并创建自己版本的 对象跟踪器

放大。(图片作者)

干杯!!!

Github 链接。

在下面的链接中可以找到月球追踪器的整个进化过程。

[## 我有一个梦想,没有马丁·路德·金那么大,但是很小

但是这个小家伙帮助我塑造了我的职业生涯。带我探索图像处理领域,让我进入了一个顶级的…

medium.com](https://medium.com/@praveenkottayi/i-had-a-dream-not-as-big-as-martin-luther-king-jr-but-a-little-one-34dc2cdbb1d9)

参考:

[## matterport/Mask_RCNN

这是 Mask R-CNN 在 Python 3、Keras 和 TensorFlow 上的实现。该模型生成边界框和…

github.com](https://github.com/matterport/Mask_RCNN) [## Tony607/colab-mask-rcnn

github.com](https://github.com/Tony607/colab-mask-rcnn/blob/master/Colab_Mask_R_CNN_Demo.ipynb) [## 在定制数据集上使用掩模 R-CNN 的对象检测

在本文中,我们将实现 Mask R-CNN 来检测自定义数据集中的对象

towardsdatascience.com](/object-detection-using-mask-r-cnn-on-a-custom-dataset-4f79ab692f6d)

奥运数据的可视化分析

原文:https://towardsdatascience.com/visual-analysis-of-olympics-data-16273f7c6cf2?source=collection_archive---------10-----------------------

赢得奥运奖牌的不同因素是如何发挥作用的?

照片由 布莱恩·特纳T5Unsplash拍摄。

奥运会是全世界公认的著名体育*台,与 19 世纪后期有所区别。然而,它的起源可以追溯到大约 3000 年前的希腊帝国,当时只有短跑比赛,在希腊的奥林匹亚城举行,只有自由出生的希腊人才能参加(Young & Abraham,2020)。从那时起,它就一直在发展,现在已经成为全世界所有运动员在超过 28 个单项体育比赛中展示自己能力的中心。目前,它每两年在不同的国家举行,名称为夏季奥运会和冬季奥运会,都有自己的一套游戏(杨和亚伯拉罕,2020)。它已经成为一个反映个人选手力量的地方,并成为他们所代表的国家的骄傲。

动机和研究问题

奥运会有着丰富的历史,从 1896 年跨越到 2018 年,已经成为历史的一部分。因此,这是一个有趣的话题,看看历史事件是如何影响奥运会的细节,以及它是如何改变至今。因此,本报告试图围绕以下问题展开,并酌情与历史事件联系起来:

1.主办国对奥运会获得的奖牌有什么影响?

2.各国在奥运会上的表现受本国经济因素影响吗?

3.奥运夺冠的年龄在变吗?

文献评论

主办国在任何体育活动中的优势是众所周知的,因为参与者将熟悉该领域,并且也有来自主场观众的巨大支持。主办国预计将赢得 3 倍于他们在客场比赛时赢得的奖牌(Clarke,2000)。主办国和共产主义背景也会对奖牌数产生积极影响(卞,2005)。

研究发现,一个国家的社会经济变量,如 GDP,在很大程度上影响着该国在奥运会上的表现。一个国家的人口和国内生产总值与奥运会奖牌数有一定的相关性(卞,2005)。

年龄因素也是体育运动中的一个重要因素,即使在相同年龄的运动员中,相对年龄效应(RAE)也是决定谁获胜的因素(Fletcher & Sarkar,2012)。RAE 指出,在成熟度、经验和早期专业化方面,一名运动员比另一名年轻*一岁的运动员更有优势(Neill,Cotton,Cuadros & Connor,2016)。

奥林匹克已经成为历史的一部分,影响着历史,也受到历史的影响。奥林匹克运动会在历史上产生了重大的社会和政治影响,如让妇女参加体育运动,反对种族问题,促进民权,统一国家,甚至成为不同国家展示权力的工具(奥康奈尔)。同样,种族隔离、恐怖主义、世界大战和冷战等国家的政治也在历史的不同时期影响了奥林匹克运动(Dwyer & McMaster,2018)。

方法

为了回答这些问题,使用了三个数据集,即“120 年奥林匹克历史:运动员和成绩[1]”,“Gapminder 人均国内生产总值,不变购买力*价美元- v25[2]”和“Gapminder 总人口 v6[3]”。奥运会数据集包括参与者的姓名、人口统计数据、他们参加了哪项运动以及参加了哪届奥运会。Gapminder 的人均国内生产总值数据集包括从 1960 年到 2040 年预测的各国国内生产总值,其人口数据集包括从 1800 年到 2019 年以及从那时起到 2100 年预测的世界所有国家的人口。还创建了一个自定义数据集,将奥运会数据集中提到的城市映射到国家名称。

可视化是用 Tableau 和 Python 创建的。最初的数据清理是在 Excel 上完成的,可视化特定数据操作是根据需要在 Tableau 和 Python 上进行的。

调查结果和讨论

东道国效应

图 1 显示了一个国家举办奥运会的次数。美国是举办次数最多的国家,共举办了 8 次,其次是法国,共举办了 5 次。

图 1-举办过奥运会的国家,作者图片

图 2 显示了举办奥运会的国家赢得的奖牌总数,显示美国赢得了最多的奖牌,然后是德国,接下来是法国。这意味着举办奥运会次数越多的国家获得的奖牌越多。主办国赢得更多奖牌的原因是由于主场优势,群众支持和更容易的资格标准,因此更多的参与(Clarke,2000)。

图 2 显示了举办奥运会的国家赢得的奖牌总数,显示美国赢得了最多的奖牌,然后是德国,接下来是法国。这意味着举办奥运会次数越多的国家获得的奖牌越多。主办国赢得更多奖牌的原因是由于主场优势,群众支持和更容易的资格标准,因此更多的参与(Clarke,2000)。

图 2-主办国获得的奖牌,作者提供的图片

现在让我们来看看不同主办国获得的奖牌数是如何变化的。首先,看看美国获得的奖牌(图 3-4),我们可以看到它在举办奥运会时获得的奖牌数一直在增加。注意图表中从 1976 年到 1984 年的急剧增长。美国曾通过抵制 1980 年在俄罗斯举行的奥运会来抗议俄罗斯入侵阿富汗,因此那一年的数据无法获得。紧接着在 1984 年,俄罗斯抵制了 1984 年在美国举行的奥运会,因此美国赢得了更多的奖牌。

图 3-美国夏季奥运会奖牌数,作者图片

图 4-美国冬奥会奖牌数,作者图片

在某些情况下,主办国在主办后的历届奥运会中都占据优势,如西班牙(图 5),该国在 1992 年主办夏季奥运会时奖牌数大幅增加(从 5 枚增至 69 枚),并在随后几年赢得了更多奖牌。

图 5-西班牙夏季奥运会奖牌数,作者图片

日本(1964 年)、韩国(1998 年)、墨西哥(1968 年)和挪威(1994 年)等其他国家也表现出类似的趋势,它们在举办奥运会后*均奖牌数都有所增加。而芬兰(1952 年)、加拿大(1976 年)、俄罗斯(1980 年)等国,虽然在举办时获得了较多的奖牌,但却无法在连年增加奖牌(参见附录一)。

图 6-奥运会举办前、举办时和举办后的中奖百分比(举办时为 100%),作者提供的图片

澳大利亚(2000 年)、中国(2008 年)和希腊(2004 年)、英国(2012 年)和美国(1996 年)等国家在主办国时赢得的奖牌数比主办国多 10-20%(图 6)。只有巴西(2016 年)在举办奥运会时没有获得更多奖牌(比英国 2012 年奥运会时少了 20%),而希腊在 2008 年希腊奥运会后只获得了 20%的奖牌。

经济效益

最基本和最重要的经济预测指标,国内生产总值(GDP)可以用来评价一个国家在奥运会上的表现(Bernard & Busse,2000)。GDP 的一个衍生指标是人均 GDP,这个指标也可以用来衡量一个国家的个人收入。GDP 和人均 GDP 绘制在图 7-8 中,以查看它们与奖金的关系。观察到该图在人均国内生产总值图中更为分散(图 7),相关系数仅为 0.1,而总国内生产总值的相关系数为 0.17(图 8),这意味着对于 2004 年奥运会(和其他奥运会-附录二),获得的奖牌数是国内生产总值的一个因素。

图 7-2004 年奥运会赢得的奖牌与人均 GDP 的对比,作者提供的图片

图 8-2004 年奥运会赢得的奖牌与国内生产总值的对比,作者提供的图片

分析总人口、GDP 和总 GDP 的相关性,以了解它们与奖牌数的关系(图 9),GDP 总是与奖牌数有更好的相关性。这并不奇怪,因为仅仅拥有更好的经济并不能保证获得奥运奖牌。它还需要一个大的群体池,从中可以选择最佳的参与者,就像从一个大的样本空间中选择一样。

图 9-国内生产总值、人均国内生产总值和人口与年份的关系,图片由作者提供

图 9 还显示了人口和人均国内生产总值的相关值逐年上升和下降。从 1896 年到 1936 年的早期阶段表明,人均 GDP 最高的国家赢得奖牌的机会更大。这可能是因为富裕国家只参加奥运会。这种情况在第二次世界大战后一直到 1988 年都有所改变,相比之下,人口与奖牌数的相关性更强。这一时期,美苏冷战,共产主义崛起。在中国),以及运动员使用药物的普遍程度。奥运会是各国展示实力的好舞台。那些能够从更多的人口中选拔出优秀运动员、保持运动员工资和训练的国家赢得了更多的奖牌。给奥运选手发工资的概念也是那个时候开始的。1991 年苏联解体和德国统一后不久,展示实力的竞争就*息了。所以,在最*几年里,人口的作用与人均 GDP 的相关性已经非常小了(小于 0.1)。

图 10-11 显示了中国和图瓦卢获得的奖牌数量和 GDP 总量。

图 10-中国获得的奖牌(GDP 最高),作者图片

图 11-图瓦卢获得奖牌(GDP 最低),作者图片

如果我们看看 GDP 排名前几名和后几名的国家(附录二),我们会发现 GDP 最低的国家没有奖牌,而排名前几名的国家都获得了 50 多枚奖牌,最高的是美国,获得了 264 枚奖牌。所有这些都暗示了奖牌总数与一个国家在奥运会上的 GDP 总量有关。

奥运夺冠的年龄在变吗?

图 12 显示了奥运会开始以来奖牌获得者的*均年龄。*均年龄在 20 世纪初很高(大约 27-28 岁),直到 1948 年有一些波动。到 90 年代,这个数字下降到 24-25,到 2016 年奥运会,这个数字上升到 26-27。

图 12-奥运会奖牌获得者的*均年龄,作者图片

现在,让我们来看看自现代奥运会开始以来一直延续的运动的年龄是如何变化的。

图 13-1896 年至 1948 年间获奖者的年龄,作者图片

图 14-1948 年至 1984 年获奖者年龄,作者图片

图 15-1988 年至 2016 年获奖者年龄,作者图片

图 13 显示,获奖者的年龄在不稳定时期有很大的变化,在下降时期略有下降(图 14),最后在现代时期(图 15),它已经变得最少。赢得某项运动的最佳年龄似乎在变窄。附录三显示了从 1988 年到 2016 年所有运动项目的变化。

结论

很明显,主办国总是有更好的机会在奥运会上赢得奖牌;他们至少可以多赢得 10-20%的奖牌。从经济效应来看,尽管一个国家的人口和人均 GDP 影响了过去赢得的奖牌数,但该国的 GDP 总量对决定*年来的奖牌数更为重要。由于年龄因素,赢得奖牌的运动员的年龄范围逐年缩小,每项运动的最佳年龄可以在最*几年确定。因此,来自高 GDP 主办国的运动员很有可能在奥运会上赢得奖牌,因为他们的年龄范围处于这项运动的最佳年龄范围内。

推荐

这项研究是对在奥运会中发挥作用的因素的高层次分析。有许多领域可以对每个因素进行更深入的分析。可以考虑的一些问题如下:

1.东道国效应 -东道国的一名参赛选手能获得奖牌的概率有多大?有什么类型的运动是主办国更有机会获胜的?

2.经济效应 -有什么运动是 GDP 低的国家赢得最多的吗?经济的上升/下降会影响一个国家的奥运奖金吗?如果会,这种影响会在几年后显现?

3.年龄效应——相对年龄效应会影响奥运奖金吗?每项运动的最佳年龄是多少岁?随着时间的推移,每个运动员的表现如何提高/降低?

此外,查看奥运会官方网站[4]中的奖牌数,并与本报告中使用的奥运会历史数据集进行比较,存在差异,因此数据集需要修改。

参考

Mahtani,K.R .,Protheroe,j .,Slight,S.P .,Demarzo,M.M.P .,Blakeman,t .,Barton,C. A .,Brijnath,b .,Roberts,N. (2012)。2012 年伦敦奥运会能“激励一代人”去做更多的体育运动吗?系统综述概述。检索自https://bmjopen.bmj.com/content/3/1/e002058.full

克拉克(2000 年 6 月)。奥运会主场优势。第五届澳大利亚体育数学和计算机会议论文集。澳大利亚悉尼科技大学(第 76–85 页)。检索自 https://research bank . swinburne . edu . au/file/3 bbcf 005-ec1e-4d ef-9602-f 7 DD 18 d0a 711/1/PDF % 20% 28 published % 20 version % 29 . PDF

弗莱彻博士和萨卡尔博士(2012 年)。奥运冠军心理弹性的基础理论。运动与锻炼心理学, 13(5),669–678 页。检索自

https://www . science direct . com/science/article/ABS/pii/s 1469029212000544

卞,x(2005)。预测奥运奖牌数:经济发展对奥运表现的影响。 The park place economist, 13(1),37–44检索自https://www . research gate . net/profile/Xun _ Bian/publication/28328103 _ Predicting _ Olympic _ Medal _ Counts _ the _ Effects _ of _ Economic _ Development _ on _ Olympic _ Performance/links/5525 b 9850 cf 24 b 822 b 4058 f 9/Predicting-Olympic-Medal-Counts-the-the-Effects-of-of-Economic-Development-on-Olympic-Performance . pdf

改变历史的 13 个奥运时刻。检索自https://www . rd . com/culture/13-Olympic-moments-that-changed-history/

Dwyer,B. B .,& McMaster,A. (2018)。奥运史上有 18 次政治压倒了体育。检索自https://www . global citizen . org/en/content/history-political-activism-Olympics-Rio/

伯纳德和布塞(2000 年)。谁赢得了奥运会:经济发展和奖牌总数(编号 w7998)。美国国家经济研究局。从 https://www.nber.org/papers/w7998.pdf取回

K. S .奥尼尔,Cotton,W. G .,Cuadros,J. P .,& O'Connor,D. (2016)。奥林匹克运动员相对年龄效应的调查。人才发展&卓越,8(1),27–39。检索自https://www . research gate . net/profile/Juan _ cuadros 2/publication/317582562 _ An _ Investigation _ of _ the _ Relative _ Age _ Effect _ inter _ Olympic _ Athletes/links/5cb4a 254299 BF 12097682856/An-Investigation-of-the-Relative-Age-Effect-inter-Olympic-Athletes . pdf

杨,哥伦比亚特区,亚伯拉罕,H. M. (2020)。奥运会。从 https://www.britannica.com/sports/Olympic-Games取回

奥林匹克运动——高峰年龄如何变化?。检索自https://www . the stats zone . com/archive/Olympic-sports-how-peak-age-vary-13812

金钱能买到奖牌吗?GDP 对奥运成功的影响分析。检索自 https://www . yellow finbi . com/blog/2012/08/YF community news-does-money-buy-metals-analyzing-the-affect-of-GDP-on-Olympic-success-117473

d .托什科夫(2016)。奥运奖牌,经济实力,人口规模。从 http://re-design.dimiter.eu/?p=868取回

使用的数据集:

[1]https://www . ka ggle . com/hee soo 37/120 年奥运历史-运动员-成绩

https://www.gapminder.org/data/documentation/gd001/

https://gapm.io/d_popv6

https://www.olympic.org/

Github 回购:

[## abhi 1 Gautam/奥林匹克-数据-可视化

这份报告包括我最*做的奥运数据可视化项目的项目文件和报告…

github.com](https://github.com/abhi1gautam/Olympics-Data-Visualization)

印度创业融资数据集的可视化探索

原文:https://towardsdatascience.com/visual-exploration-of-the-indian-startup-funding-data-set-4947971b561?source=collection_archive---------38-----------------------

对印度启动资金数据集进行可视化探索性数据分析,以发现令人兴奋的趋势并回答预期的问题

Unsplash 上由 Franck V. 拍摄的照片

印度拥有世界上最大的创业生态系统之一,预计年增长率为 10-12%。印度有大约 20,000 家初创公司,其中大约 4,750 家是技术领先的初创公司。仅在 2016 年就有 1,400 家新的科技初创公司诞生,这意味着每天都有 3-4 家科技初创公司诞生(根据 given 来源)。考虑到所有这些因素,分析启动资金变得很有趣。

数据取自 Kaggle ,拥有 2015 年至 2019 年印度创业公司的融资信息。它包括投资日期、创业所在城市、投资者姓名和投资额(美元)等栏目。

  1. 年度明智分析

图一

一项精确的观察表明,这些年来投资数量急剧下降。

图 2

与之前的图表(图 1)相比,投资总额反而以更随机的方式变化

现在,通过比较两个图(图 1 和图 2)进一步深入投资,我们可以观察到每笔投资的金额有所增加。

图 3

这可能表明,投资者在过去几年里变得更加专一,并试图更多地投资于表现出更强竞争力的公司

2.城市

图 4

初创公司和投资者最青睐的只是少数几个城市

班加罗尔、孟买、新德里、古尔冈、诺伊达、浦那和钦奈是最受青睐的城市。该名单包括印度的主要大都市,这可能是一个迹象,表明重要的城市为创业公司提供了更好的生态系统和设施。此外,这个数字也证实了班加罗尔是印度主要创业中心的事实。

3。行业垂直

图 5

图表显示了根据投资总额排名的前 5 个行业

就投资而言,消费互联网、电子商务、交通、技术和金融是五个最受青睐的行业。

4。投资类型

所做的投资可以分为不同的类别,如 A 轮、B 轮、C 轮、种子基金、股权等。

图 6

作为私募股权的投资远远高于所有其他形式的投资

5。投资额最高的创业公司

图 7

获得最高资助的创业公司

Flipkart、Rapido 和 Paytm 是特定时期内获得资金最多的初创公司。

现在,我们已经对数据做了一些分析,是时候回答一些可能的问题了。

资金生态系统如何随时间变化?

每笔投资的金额逐年递增,这表明投资者有兴趣为有望表现更好或过去有良好记录的初创企业提供更多支持(图 1、2 和 3)。

城市在资助中扮演重要角色吗?

是的。毫无疑问,它扮演着重要的角色(图 4)。由于设施和更好的创业生态系统,大都市最受青睐。班加罗尔似乎拥有印度最好的创业生态系统。

哪些行业最受投资人资金青睐?

就投资而言,消费互联网、电子商务、交通、技术和金融是五个最受青睐的行业(图 5)。

结论

至此,我们已经做了一些基本分析,并试图回答几个问题。我们还发现了印度创业行业在城市、行业垂直等方面的一些有趣的模式和趋势。通过将这些数据与关于印度创业生态系统的外部知识相结合,可以进行进一步的分析,从而获得更好的见解和趋势。

:所有的视觉效果都是用 tableau 制作的。文档的链接

新冠肺炎:新加坡首批 100 名完全康复患者的视觉笔记

原文:https://towardsdatascience.com/visual-notes-from-singapores-first-100-fully-recovered-covid-19-patients-aad7f2e1d0a0?source=collection_archive---------3-----------------------

确定你感染了新冠肺炎病毒需要多长时间?如果真的感染了,你需要多长时间才能摆脱这种新型冠状病毒?这些都是很难回答的问题,但下面是新加坡首批 100 例完全康复的病例可以告诉我们的。

已经创建了几个优秀的仪表板来跟踪新加坡新冠肺炎疫情的进展(点击此处此处此处此处),试图复制这些资源更好的团队所做的事情是没有意义的。

在这篇文章中,我将着重探讨每个人心中的两个问题:

  • Q1:如果我的新冠肺炎病毒检测呈阳性,完全康复需要多长时间?

在这一点上没有全球标准,受影响的国家对新冠肺炎患者何时获准出院采取了不同的指导方针。

在新加坡,新冠肺炎患者只有在至少相隔 24 小时的两次拭子检测 结果均为阴性 后,才被视为完全康复。只有到那时,他们才能出院。这样做是为了确保病人回到社区后不会传染给其他人。

换句话说,仅从新冠肺炎症状中康复并不能被视为完全康复,也不能证明你有资格从新加坡医院出院。

到目前为止,这个城市国家的第一批 100 名完全康复的新冠肺炎病例中的患者需要 1 到 31 天才能出院,如果我们从他们被正式确认感染的那一天开始计算的话。该确认出院窗口的中位天数为 11 天。

  • Q2:如果我有症状,我要等多久才能确定是新冠肺炎病毒?

这是两个问题中较难回答的一个,因为我们对新冠肺炎的知识存在空白,而且病例复杂,要么没有症状,要么与 14 天潜伏期的标准不符。在新加坡,首批 100 例完全康复病例中的绝大多数患者在报告出现发烧、喉咙痛和呼吸困难等症状的 14 天内得到确诊。

但是 8 名患者没有症状,8 例患者在确诊前花了 15 天或更长时间。对于这些不寻常的病例,以及世界各地报道的类似病例,目前还没有结论性的解释。

显然,这不是医学研究,我也不是流行病学家。但是我特别注意使用清晰、明确、非危言耸听的标签/定义。

我在这里的目标是试图以一种清晰易懂的方式呈现公共数据中的潜在趋势,同时坦率地承认数据集的局限性和我缺乏该领域的专业知识。

新加坡因其对新冠肺炎疫情的早期处理而赢得赞誉,但有迹象表明,这种早期的成功无意中在一些居民中滋生了自满情绪。在疫情已经全球化的时候,考虑到新加坡的高人口密度,这种自满情绪将被证明是代价高昂的。

从我过去做记者的经验来看,当你试图让他们参与到“大局”的解释中时,大多数人都不理会。但如果对他们个人福祉的影响说得更清楚,他们可能会更关注一点。

这就是我希望通过这篇文章达到的目的。

1.数据、定义和说明

在我们进入图表之前,重要的是首先要了解公共数据集的局限性,避免匆忙得出结论。新加坡当局发布的信息虽然详细,但主要是为了让公众每天了解情况。该数据集不包含关于患者的详细医疗信息,这些信息将为全面的研究提供信息。

因此,我避开了像“潜伏期”和“恢复期”这样的标签,它们在医学研究中有特定的含义,最好留给专家来处理。

1.1 数据来源

我从新加坡卫生部发布的每日新闻稿中手动收集了第一批 100 例完全康复病例的数据集。你可以在这里下载数据集的副本,或者通过 Github repo 下载这篇文章。

根据记录,新加坡前 100 名完全康复的患者是:病例 01–34、36–40、43–81、83–89、91–93、95–96、98、102、106–107、110–112、138、148 和 151。

新加坡第一个完全康复的患者是病例 07,一名 35 岁的中国大陆公民,于 2 月 04 日出院,他于 2020 年 1 月 27 日被确认为新冠肺炎阳性。

加入样本的第 100 例出院患者是病例 102,一名 41 岁的菲律宾妇女,于 2020 年 3 月 14 日出院。据新加坡卫生部称,包括 102 号病例在内的八名无关患者于 3 月 14 日出院。恢复的患者 103、135、146、150 和 160 未被添加到该数据集。

出于实际原因,我选择了前 100 个恢复的案例。显然,新加坡的新冠肺炎病例总数仍在增长,而且趋势会随着数字的变化而变化。所以请记住,这只是初步的探索。我会在适当的时候更新或写一篇新帖。

非新加坡读者注意:CSV 文件中的日期是按照新加坡的标准以日/月/年格式记录的。

1.2 定义

不幸的是,这篇文章中使用的两个定义都很笨拙,但我选择尽可能明确,以便我们专注于有限的公开数据实际上说了什么,而不是走上过度解释我们认为数据在说什么的道路。

例证:公开数据不包含患者首次接触病毒的时间,也不包含他们在医院期间的日常状况。新加坡当局也没有透露患者在医院从症状中恢复需要多长时间,以及他或她等待拭子检测结果的时间。

因此,在这篇文章中采用“潜伏期”和“恢复期”这样的短语是很有问题的,因为它们有特定的医学定义,而新加坡的公共数据不一定涉及这些定义。

定义#1:确认-卸货窗口

在本帖中,我将使用“确认-出院窗口”一词来简写新加坡卫生部宣布的患者新冠肺炎感染确认日期和他/她的正式出院日期之间的天数。这些日期是公开记录的,没有争议。

从确认日期开始计时为我们在快速变化的环境中进行比较提供了一致的基线。在疫情爆发的早期,你会预计到患者入院和新冠肺炎检测结果之间会有明显的差距。但是随着更新的检测试剂盒的出现,这个等待时间将会大大缩短。

定义#2:症状-确认窗口

鉴于全球在获得医疗设施和新冠肺炎检测试剂盒方面的差异,预确认阶段是一个棘手的领域。在新加坡,卫生部还发布了每个新冠肺炎病例的一些关键日期,包括抵达新加坡的日期(对于输入病例),以及自行前往诊所或医院的日期(如果适用)。

因此,从接触新冠肺炎病毒到官方确认感染之间的不确定期可以用多种方式来定义,这取决于如何组合可用的日期。

为了避免问题过于复杂,我将使用一个简单的预确认阶段定义为“症状-确认窗口”,即从报告症状开始到正式确认新冠肺炎感染之间的天数。

可以肯定的是,人们对患者报告的症状发作日期的真实性存在一些怀疑,尤其是在压力和社会耻辱的时期。但这是新加坡数据中最可靠的“开始日期”。我选择不使用住院和自行就诊的日期,因为这些情况下的诊断尚未披露。

2.新加坡首批 100 名完全康复患者的人口统计分析

我不打算复制已经存在的优秀的新冠肺炎仪表板。但是一些按人口统计分类的图表对本文的分析仍然有用。为此,我在 fluore 上创建了一个交互式图表,可以快速完成工作。你可以在这里访问它

在这 100 个样本中,我们有 23 个输入病例和 77 个本地传播病例。康复的病人中有 40 名是女性,其余的是男性。

就国籍而言,如果我们单独考虑新加坡永久居民,我们有八个群体。有:

  • 67 名新加坡人
  • 19 名中国大陆公民
  • 6 新加坡减贫战略
  • 4 名孟加拉人
  • 印度尼西亚、日本、马来西亚和菲律宾国民各 1 名

就年龄而言,首批 100 名完全康复的患者(75 名)年龄在 30 至 59 岁之间。拥有最多新冠肺炎患者的单一年龄范围是 30-39 岁,有 28 人(18 名男性和 10 名女性)。

3。如果你的新冠肺炎病毒检测呈阳性,完全康复需要多长时间?

3 月 12 日,在 T2 一次罕见的电视讲话中,新加坡总理李显龙表示,新加坡 80%的新冠肺炎患者“只有轻微症状”。他没有解释他所说的“温和”具体指的是什么。

但是如果你已经感染了新冠肺炎病毒,从症状中恢复只是痛苦的一部分。

在新加坡首批 100 例完全康复的病例中,大多数患者,无论老少,都需要长期住院,因为需要额外的时间来确保他们停止传播高传染性的新冠肺炎病毒。

Average number of days between hospital discharge and Covid-19 confirmation:  12.29
Median number of days between hospital discharge and Covid-19 confirmation:  11.0
Minimum number of days between hospital discharge and Covid-19 confirmation:  1
Maximum number of days between hospital discharge and Covid-19 confirmation:  31

这是一个很重要的区别,因为错误地认为新冠肺炎“只是一场重感冒”(i t 不是)可以很快康复,是新加坡和其他地方许多人自满的核心。

新加坡前 100 例恢复病例的数据显示确认出院窗口的中位天数为 11 天。三分之一(33)的患者从确诊感染时起需要 15 天或更长时间才能出院。只有 8 名患者在确诊感染后 3 天或更短时间内出院。

上图还显示了卫生当局为何对新冠肺炎新增病例数量的大幅上升感到担忧。如果新感染病例激增,确保大量患者安全返回社区所需的大量时间和资源可能会让一个国家的医疗系统不堪重负。

简而言之,这不仅仅关乎你个人从新冠肺炎感染中康复的能力。这种担忧本质上是更广泛和系统性的,也就是说,是对医疗系统处理可能持续数周具有传染性的患者突然激增的能力的担忧。

3.1 确认-卸货窗口:甘特图可视化

甘特图通常用于说明项目进度。但在这种情况下,它在显示每个病人的确认出院窗口方面工作得很好。你可以在这里下载一份互动图(是 html 文件;中不允许交互式图表的直接嵌入)。只需将鼠标悬停在每个条形上,即可查看特定案例的元数据,以及他/她从确认到完全恢复所用的天数。

这里下载互动版

甘特图有助于概览,并允许您快速挑选出不寻常的情况:

3.1.1 哪些案例完全恢复所需的时间最少?

第 151 号案件,在官方确认和释放之间只有一天的时间,这可能是最不寻常的。

新加坡卫生部的官方新闻稿似乎暗示,这名 51 岁的新加坡男子在 2 月 4 日首次报告出现症状后,已自行从新冠肺炎康复。3 月 8 日,一项血清测试的结果证实他有“早期新冠肺炎感染”。一天后,他于 3 月 9 日出院。

病例 76、83 和 84 在被正式确认感染后仅用了两天就出院了。案例 83 和 84 是美奂大道群的一部分,而美奂大道群又与另外两个教堂群相关联。

患者 76 是 2 月 9 日从疫情中心武汉撤离的新加坡人之一。他在登机前没有表现出任何症状,并在抵达新加坡时被隔离,作为这个城市国家遏制措施的一部分。他仅在 2 月 16 日的新冠肺炎病毒检测中呈阳性。

尚不清楚为什么这些病例在如此短的时间内就完全康复了。

3.1.2 哪种情况需要最长时间才能完全恢复?

病例 53 保持着迄今为止的记录,从确认感染到最终出院用了 31 天。这名 54 岁的新加坡男子是新冠肺炎一个教会的成员,该教会与当地的一个教会“上帝恩典会”有联系。他于 2 月 10 日首次报告出现症状,两天后被检测出新冠肺炎病毒阳性。

然而,尚不清楚他从新冠肺炎症状中恢复的天数与他完成拭子检测所需的时间之间的差距。新加坡的公开数据不包含新冠肺炎治疗期间患者状况的详细信息。

4。不同性别和年龄的患者恢复速度不同吗?

一项针对中国 1000 名新冠肺炎患者的 T4 研究发现,女性更有可能存活。谢天谢地,新加坡还没有出现与新冠肺炎相关的死亡病例。但在新加坡首批 100 名完全康复的患者中,男性和女性完全康复的速度是否不同?

4.1 男性和女性的确认-恢复窗口有何不同

在新加坡首批 100 名完全康复的新冠肺炎患者中,有 60 名男性和 40 名女性。但是下面的箱线图显示,两种性别完全康复的*均天数相同——11 天。

样本量小可能是一个因素,当我们有大量完全康复的患者时,观察事情如何变化将是有趣的。如果你对箱线图不熟悉,看看这个解释者这里

4.2 不同年龄组的确认-恢复窗口有何不同

我们大多数人可能会认为年龄会影响完全康复所需的时间,但来自新加坡前 100 例新冠肺炎病例的数据带来了一些惊喜:

除了年龄最小的 9 岁以下的患者,他们的确认出院窗口中位数为 4 天,我们没有看到年轻患者完全康复的速度明显快于年长患者。

事实上,10-19 岁、20-29 岁和 40-49 岁年龄组完全康复所需的中位天数比所有 100 名康复患者 11 天的总中位天数要长。

乍一看这很令人惊讶,但当你回到完全康复的定义时就不那么令人惊讶了——这是指患者必须证明他们已经停止传播病毒,而不仅仅是从症状中恢复过来。换句话说,即使年轻患者从症状中恢复得更快,不同年龄组之间脱离新冠肺炎所需的中位时间可能不会有太大差异。当然,这需要专家在一项更大的研究中进行验证。

60-69 岁年龄组的数据极不寻常。该年龄段的中位确诊-出院窗口为 5 天,有一个异常值,即病例 01,在确诊感染和出院之间用了 27 天(总中位值的 2.5 倍)。考虑到这次初步探索的样本量很小,我将暂时避免对此进行过度解读。

盒子情节的互动版本可以在这里获得。将鼠标悬停在数据点上可查看每个病例的详细元数据,或将鼠标悬停在方框上可查看特定年龄范围内患者恢复期的四分位数分布。

此图表的互动版本可在此处获得

5.确定我是否感染了新冠肺炎病毒需要多长时间?

鉴于全球在获得医疗设施和新冠肺炎检测试剂盒方面的差异,这是一个棘手的领域。新加坡卫生部网站上的官方常见问题称“潜伏期长达 14 天”,引用了中国新冠肺炎病例的数据。

这与新加坡前 100 例完全康复病例的数据分析相吻合,在新加坡,只有 8 名患者从出现症状起超过 14 天才检测出新冠肺炎阳性:

8 名患者没有症状,92 名有症状的患者中有一半以上在 7 天或更短时间内被确认为新冠肺炎阳性。总体而言,从出现症状到确认感染的中间天数为 6 天。

Average number of days between symptoms and confirmation:  7.434782608695652
Median number of days between symptoms and confirmation:  6.0
Minimum number of between symptoms and confirmation:  1.0
Maximum number of days between symptoms and confirmation:  33.0

5.1 症状的甘特图可视化-确认窗口

重复使用甘特图,我们可以再次判断出哪些病例花费了异常长的时间来确认感染。案例 151、91 和 83 立即成为非常复杂的案例。你可以在这里下载一份互动图表

点击下载互动图表

我们之前简要讨论过的病例 151,从出现症状到确认感染之间名义上有 33 天的间隔。但是现实要复杂得多,正如我们在 3 月 9 日卫生部的新闻发布会上看到的。

他于 2 月 4 日开始出现症状,但在 3 月 8 日进行了血清学测试,以确认他患有早期的新冠肺炎感染。当局没有说明他被感染的确切时间,也没有说明血清学检测是否能辨别出之前感染的日期。151 号病例一天后于 3 月 9 日出院。

病例 151 不是报告症状的患者中唯一的异常值。在我们的 100 例康复病例样本中,其他 7 例患者——病例 30、66、68、83、84、89 和 91——从出现症状到确诊新冠肺炎病毒超过 14 天。它们都是本地传播的病例:

根据2 月 25 日卫生部发布的日期为【2 月 1 日、6 日和 10 日】的新闻稿,91 号病例在报告症状出现和确诊之间间隔了 30 天,于 1 月 23 日首次报告身体不适,并在三个不同的时间到诊所寻求治疗。

卫生部当时没有说这位 58 岁妇女的诊断是什么。她于 2 月 18 日被转介到国家传染病中心(NCID ),此前她被确定为病例 66 的接触者,该病例是上帝教会恩典大会群集的主要病例。2 月 22 日下午,91 号病例的新冠肺炎病毒检测结果呈阳性。

圣保罗卫生官员解释说,91 号病例之所以被遗漏,是因为她的病情和旅行史当时不符合他们对疑似病例的定义,并补充说,他们此后收紧了对没有去过新冠肺炎热带地区旅行史的疑似病例的标准。

这些异常病例出现在数据集中反映了新加坡积极的接触者追踪制度。在其他资源更紧张的国家,或者政府采取更宽松措施的国家,他们可能没有被发现。

尚不清楚这些不寻常病例在未被发现时的传染性有多大。在遏制疫情的努力中,它们无疑是最复杂的挑战之一。

5.2 无症状的新冠肺炎患者人数

另一方面,在首批 100 名康复患者中,有 8 名患者(6 名男性,2 名女性)在新冠肺炎病毒检测呈阳性之前没有任何症状。它们是:第 22、23、28、65、75、76、87 和 138 号案件。

其中四名患者——病例 22、23、76 和 87——是新加坡人,分别于 1 月 30 日和 2 月 9 日乘坐两个航班从武汉撤离。他们登机时没有报告任何症状,但在抵达时被隔离,然后作为额外的预防措施进行了新冠肺炎测试。他们随后的冠状病毒检测呈阳性。

这四例本地传播病例没有症状出现的详细信息,是新加坡已知新冠肺炎聚集性病例的一部分。但卫生部的新闻稿没有解释为什么这些患者在确认感染前没有任何症状。

第 138 号患者是另一个高度复杂的病例——他于3 月 6 日检测呈阳性,此前他已经接受了为期三周的隔离,并被允许离开家。这名 26 岁的男子与新加坡当地教会的两个群体有关联,在阳性检测后,他不得不被召回接受进一步调查。他于 3 月 9 日被解除警报并出院。关于这个案子的更多信息可以在媒体报道中找到这里这里

我不会进一步细分症状确认期的数据,因为我不清楚在这种情况下性别和年龄会比一个人最*的社会活动更重要。可能有更科学的方法来研究这个棘手的感染前确认阶段,这最好留给专家来做。

本帖中图表的笔记本和数据在我的 Github repo 中。如果你发现了错误或者对这个来自新加坡的小数据集做了一些有趣的事情,请告诉我。在以下时间 Ping 我:

推特:蔡展鸿

领英:www.linkedin.com/in/chuachinhon

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

视知觉

原文:https://towardsdatascience.com/visual-perception-how-we-perceive-graphical-information-de5f30516009?source=collection_archive---------38-----------------------

数据可视化基础

斯蒂夫·约翰森Unsplash 上拍照

我们为什么要可视化数据?

它帮助我们理解巨大的数据量,把它压缩成一个简单的,容易理解的可视化。它帮助我们找到隐藏的模式或看到数据本身的潜在问题,如果没有好的图表,这些问题可能不会很明显。

我们的大脑专门尽可能高效地感知我们周围的物质世界。证据还表明,不管我们的环境或文化如何,我们都发展了相同的视觉系统。这表明视觉系统的发展不仅仅基于我们的环境,而是数百万年进化的结果。这与白板理论(Ware 2021)相矛盾。抱歉,约翰·洛克。我们的视觉系统分割任务,因此有专门的区域负责分割(早期快速处理)、边缘方向检测或颜色和光感知。我们能够轻松地提取特征并找到模式。

有趣的是,在更高层次的视觉感知(视觉认知)上,我们的大脑能够突出颜色和形状,以专注于某些方面。如果我们在一张公路地图上搜索红色的公路,我们可以利用我们的视觉认知来突出红色的公路,并将其他颜色放在背景中。(Ware 2021)

我们可以说两种类型的视觉化。感官或任意。感官表征无需训练就能理解,而且通常理解得很快,跨文化。任意可视化不是那么容易理解的,需要学习。例如,一个任意的可视化系统是一个电路图、一张地图或一个建筑的蓝图。为了理解这些可视化的信息,你需要接受某种形式的培训。尽可能集中在一个感觉系统上是有意义的,只有在必要的时候才使用任意的系统。这样你就有最好的机会让你的听众理解你。只要确保你所使用的系统在目标受众中已经建立。(Ware 2021)

Colin Ware 在他的书《信息可视化,设计感知》中写下了很多指导方针。以下是我认为重要的几个:

  • 考虑人类的感官能力,以帮助重要的数据元素
  • 重要的数据应该用视觉上更加清晰的图形元素来表示
  • 更大的数字量应该用更明显的图形元素来表示。
  • 图形符号系统应该标准化

视觉变量

法国制图师 Jacques Bertin(1918–2010)是第一个在他的书“ Sémiologie graphique ”中描述视觉变量的人。他认为视觉变量有七个主要类别:位置、大小、形状、价值、颜色、方向和纹理。(罗斯 2017)

一个物体的大小可以用来传达一个特征的重要性。描述某物有多大或多小。在 3D 中,它表达了亲密感。请记住,较大的物体会吸引更多的注意力。

大小,作者图片

一个对象的形状可用于将其与其他对象分开,或者将多个具有相同分类属性的对象组合在一起。

形状,作者的图像

颜色值,分别表示颜色的深浅程度,反映了特征的重要性。它可以用来可视化连续变量。请注意,较深的颜色被理解为“更多的…”。

颜色值,按作者分类的图像

符号的方向可用于显示方向或对对象进行分组。

方向,作者的图像

纹理可用于区分类别或替代颜色。在地图中,纹理用于分隔不同的区域。例如森林和田野。

纹理,作者提供的图像

色调用于分类数据或突出重要的东西。某些颜色更占主导地位,会吸引人们的注意力。此外,确保在可视化中使用色盲友好的颜色。(蓝黄色是好的)

颜色色调,作者提供的图像

物体的位置也很重要。更高或更靠*观察者可以传达这个物体更重要,更值得你注意。

颜色

对我来说,在我的图形中摆弄颜色是最有趣的。它们只是用一些漂亮的颜色看起来更令人愉快。有几件事要记住:

  • 颜色传达一种感觉(情绪)
  • 色盲:考虑一组黄蓝方向的颜色
  • 连续变量的颜色值(颜色的明度或暗度)和离散变量的单独颜色(分类数据)。

连续变量(上图)和离散变量(下图)的颜色,按作者分类

格式塔理论原则

整体不同于部分之和~库尔特·科夫卡

格式塔原理描述了人类对相似物体进行分组、寻找模式以及从缺失部分进行简化或推断的能力。访问这里了解更多格式塔心理学。该理论由五个定律组成,下面简要介绍:

相似度

彼此相似的项目往往被视为一组或单个对象。下图中的正方形和圆形不被视为单一对象,而是被视为行。

相似性,作者图片

prgnanz

…论点是 Wertheimer 对组织中的普拉南斯(“精确”)的概念;当事物被整体把握时,最少的能量被用于思考。对韦特海默来说,真理是由经验的整体结构决定的,而不是由个人的感觉或知觉决定的。(心理学杂志)

视觉效果越简洁,观察者就能越快、越少地捕捉到其中显示的信息。

接*度

距离较*的物体被视为一个整体,而不是单个的。下面的方块被认为是 4 个垂直的行。

邻*定律,作者图像

连续性

眼睛沿着它能找到的最*滑的路径前进。你注意到眼睛是如何更好地跟随亮点的吗?

连续性,作者的图像

关闭

组合在一起的物体被视为一个整体。我们忽略线条,填充缺失的部分。你看到白色三角形了吗?

闭合定律,作者的图像

应用

我应用了一些讨论过的理论来可视化来自 tidytuesday 的化身数据集的信息。这些图形是用 r 中的 ggplot2 制作的,你可以在我的 GitHub 上找到代码。

这种堆积百分比条形图和散点图使用可视变量“色调”,以便可以清楚地识别字符。“色值”是用来强调主角的。通过对行进行排序,也可以使用“位置”。

堆积百分比条形图

在这个散点图中,垂直网格被移除。这些点现在清楚地分配给一集,并显示为行。这里使用了格式塔理论的邻*定律。

散点图

大小可以用来引起对某个数据点的注意。这有助于更快地检测出具有最高值(深蓝色)的行。如果不突出显示该值,将很难找到最高值。

棒棒糖图表

来源

“格式塔心理学|定义、创始人、原则和例子”。大英百科全书https://www.britannica.com/science/Gestalt-psychology(7。2020 年啤酒节)。

“心理学”。大英百科全书。【https://www.britannica.com/science/Pragnanz】T2(7。2020 年啤酒节)。

罗思罗伯特。2017.“视觉变量”。在,1–11。

罗纳德·萨尤尼。“格式塔原则(视频)”。可汗学院https://www . khanacademy . org/test-prep/mcat/processing-the-environment/sensory-perception/v/gestalt-principles(6 .2020 年啤酒节)。

威尔科林。2021.“信息可视化”。在信息可视化中,Elsevier,I .https://linking hub . Elsevier . com/retrieve/pii/b 978012812875601001 x(7。2020 年啤酒节)。

Wilke,Claus O. 数据可视化基础https://clauswilke.com/dataviz/color-basics.html(6。2020 年啤酒节)。

具有深度学习的视觉问答

原文:https://towardsdatascience.com/visual-question-answering-with-deep-learning-2e5e7cbfdcd4?source=collection_archive---------18-----------------------

本博客包含在 Keras/Tensorflow 中实现“面向视觉问答的分层问题-图像共同关注”论文。

查尔斯·德鲁维奥在 Unsplash 上拍摄的照片

目录:

  1. 简介
  2. 商业问题
  3. 了解数据
  4. 将现实世界的问题映射到 ML/DL 问题
  5. 了解模型
  6. 实施细节
  7. 代码
  8. 结果
  9. 结论和未来工作
  10. 参考文献

1.简介:

视觉问答是一个关于建立一个人工智能系统来回答用自然语言提出的关于图像的问题的研究领域。

解决这一任务的系统展示了对图像的更一般的理解:它必须能够回答关于图像的完全不同的问题,有时甚至可以处理图像的不同部分。

让我们看几个例子:

来源:原文 VQA 论文

对于所有的图像,我们的人工智能系统应该能够定位问题中提到的主题并检测到它,并且应该有一些常识来回答它。

例如,在第一张图片中,对于问题“胡子是由什么组成的?“我们的人工智能系统应该能够判断出所指的对象是女性的脸,更具体地说是她嘴唇周围的区域,并且应该能够检测到香蕉。

2.业务问题:

作为人类,我们很容易看到一幅图像,并利用我们的常识回答关于它的任何问题。然而,也有这样的情况,例如,视力受损的用户或智力分析师,他们想要主动地引出给定图像的视觉信息。

因此,我们建立了一个人工智能系统,它将图像和关于图像的自由形式、开放式或自然语言问题作为输入,并产生自然语言答案作为输出。

系统会在以下几个方面回答类似人类的问题:

  1. 它将从输入(分别是图像和问题)中学习视觉和文本知识
  2. 合并两个数据流
  3. 使用这些高级知识来得出答案

3.理解数据:

VQA 是一个包含关于图像的开放式问题的数据集。这些问题需要了解视觉、语言和常识知识才能回答。

  • 82,783 张图像(可可列车图像)
  • 每张图片至少 3 个问题(*均 5.4 个问题)(443,757 个问题)
  • 每个问题 10 个真实答案(443,7570 个答案)来自不同的员工

4.将现实世界的问题映射到 ML/DL 问题:

  • 机器学习问题的类型:我们将手头的问题提出为 K 类分类问题;其中 K 是数据集中一组固定答案类型的数量。
  • 性能指标:我们通过正确回答问题的数量来评估我们的人工智能系统。使用以下精度指标:

  • 约束:没有严格的延迟要求。

5.了解模型:

让我们试着去理解《视觉问答的分层问题-图像共同关注》一文中提出的方法。

论文概述:

来源:https://arxiv.org/pdf/1606.00061

在此之前,所有关于 VQA 的论文主要集中在视觉注意力上。本文建议也关注问题注意。具体而言,本文提出了一种新颖的 VQA 多模态注意力模型,该模型具有以下两个独特的特征:

  1. 共同注意:本文提出了一种新的机制,它联合推理视觉注意和问题注意,称为共同注意。更具体地,图像表示用于引导问题注意力,问题表示用于引导图像注意力。
  2. 问题层次:构建一个层次结构,在三个层次上共同关注图像和问题:(a)单词层,(b)短语层,和(c)问题层。

a) 在单词级,通过嵌入矩阵将单词嵌入到向量空间中。

b) 在短语级,一维卷积神经网络被用于具有不同支持的时间过滤器的单词表示,以捕获包含在单个词、双词和三词中的信息,然后通过将它们汇集成单个短语级表示来组合各种 n 元词响应。

c) 在问题级,使用递归神经网络对整个问题进行编码。

对于这个层次结构中问题表示的每个级别,构建联合问题和图像共同关注图,然后递归地组合这些图以最终预测答案的分布。

方法:

该论文提出了两种共同注意机制,这两种机制在图像和问题注意图的生成顺序上有所不同。第一种机制称为并行共同注意,它同时产生图像和问题注意。第二种机制叫做交替共同注意,它依次在生成图像和问题注意之间交替。这些共同关注机制在问题层级的所有三个级别上执行。

在这篇博客中,我们将讨论并行共同注意模型的实现。

*行共同关注:

来源:https://arxiv.org/pdf/1606.00061

*行共同注意同时注意图像和问题。通过计算所有图像位置和问题位置对处的图像和问题特征之间的相似性来连接图像和问题。具体来说,给定一个图像特征图 V∈ R ^(d×N)和问题表示 Q∈ R^( d×T),我们计算一个叫做亲和矩阵 C∈ R^( T×N)的东西如下:

考虑到这个相似性矩阵 C 作为一个特征,图像和问题注意力图以下面的方式被预测:

基于上述关注权重,图像和问题关注向量被计算为图像特征和问题特征的加权和,即,

并行的共同关注在层次结构的每一层完成,导致 其中 r ∈ {w,p,s}

然后,来自所有三个级别的共同参与的图像和问题特征被递归地组合,以最终预测答案。

来源:https://arxiv.org/pdf/1606.00061

6.实施细节:

  • 我们不直接使用图像作为模型的输入。将图像缩放到 224× 224,然后提取 VGGNet19 的最后一个 CONV 层的激活。形状[512 x 7 x 7]的这些激活被用作图像的输入特征。
  • 我们使用 KERAS 标记器来提取问题特征。
  • 最终的输入特征是:a)形状[49,512]的图像特征和 b)形状[22,]的问题特征,其中 22 是预处理后问题的序列长度。
  • 我们使用基本学习率为 1e-4 的 ADAM 优化器。
  • 我们将批量大小设置为 300,训练 60 个时期。
  • 我们在每一层都使用正则化。

7.代码:

建筑:

自定义图层:

一些自定义层用于定义上面的模型。下面是自定义层的代码:

8.结果:

该论文在 VQA 2.0 数据集上的准确率为 54%。我的实现准确率是 49.28%。

下面是工作模型的演示视频:

9.结论和未来工作:

我们仅用了 60 个历元就达到了接*报道的论文精度的精度。为了获得与论文相同的准确性,我们可以尝试为更大的时期训练模型,并具有学习率衰减。

将图像缩放到 448× 448,然后从 VGGNet19 的最后一个 CONV 层中提取[512 x 14 x14]激活作为图像特征,也可以提高性能。

仅此而已。谢谢你阅读我的博客。如果你有任何想法,请留下评论、反馈和建议。

我的 GitHub repo 上的完整代码, 这里

你可以在领英上找到我,T5 这里 。

10.参考资料:

回到榜首^

Visual Studio 代码— Python 编辑器回顾

原文:https://towardsdatascience.com/visual-studio-code-python-editors-in-review-e5e4f269b4e4?source=collection_archive---------24-----------------------

我想我坠入爱河了😍

Visual Studio 代码 1.50.1。截图由马丁·托马斯拍摄。

Visual Studio Code 是微软编写的免费编辑器。它的第一个版本是在 2015 年,男孩做了一个起飞。它在 StackOverflow 上有超过 28k 个问题,根据 2019 Jetbrains 调查它是第二个最常用的 Python 编辑器,根据 2019 StackOverflow 调查它是最受欢迎的编辑器。VS 代码有自己的 marketplace ,在 WindowsLinuxMac 上运行。微软已经创建了一个强大的语言服务器,名为 Pylance ,你肯定也想读一些关于它的东西…但是让我们先从基础开始。

当你第一次启动 VS Code 时,它会提供给你几个可能有用的插件。我直接安装了 Python 集成和 Sublime 文本键绑定。当我写快捷方式时,请特别记住键绑定部分。

速度

VS 代码启动需要一秒多一点的时间。这意味着它比 PyCharm 快得多,但比 Sublime Text 慢。VS 代码存储一切,即使你不打Ctrl+S。这意味着你可以随时关闭编辑器。下次打开它时,它会告诉您还有未保存的更改😍

用户界面

在上面的截图中,你可以看到我通常打开的内容:

  • 编辑器中你可以阅读代码。当然还有语法高亮和行号。
  • 浏览器中你可以看到工作区的文件。
  • 活动栏位于浏览器的左侧。在这里,您可以将浏览器切换到搜索工具、版本控制系统(VCS)集成、调试器等等。这是我一开始不喜欢 VS 代码的主要原因。但是,您可以简单地隐藏它😍
  • 在代码的右边,有一个代码的小地图。这有助于跳到奇怪的部分。

命令选项板

命令面板是实现编辑器任何功能的途径。不再在深度嵌套菜单中搜索❤️

您可以使用组合键Ctrl + Shift + P打开命令面板。看起来是这样的:

截图由作者拍摄

虽然我不太清楚为什么,但我更喜欢 Sublime Text 的命令面板,而不是 PyCharm 的命令面板。对我来说,感觉崇高文本的模糊搜索是最好的。视觉上,VS 代码做得真的很好。

可定制的快捷方式!

VS 代码有一个默认键绑定的官方备忘单( source ),我已经提到过你可以使用其他编辑器的默认键绑定。这是整洁的,但我希望能够定制它完全符合我的需要。

当然,你可以这样做!VS 代码甚至为你提供了一个非常好的界面,它承认你可能想要不同的动作,这取决于具体的情况/编程语言。

VS 代码的快捷编辑器。截图由作者拍摄。

选项卡交互

你可以用Ctrl+W关闭标签页,就像在 Chrome 中一样。您可以使用Alt+1切换到第一个选项卡,使用Alt+2切换到第二个选项卡,…

你可以用Ctrl+N打开一个新文件——就像你在 Chrome 中打开一个新窗口一样。

跳转到行

Ctrl+G跳到一行。这在你调试的时候非常方便。

转到文件

Ctrl+P转到当前工作区中的任何文件。再次用模糊搜索🎉

查找/全部替换

Ctrl+F找东西,Ctrl+H替换。也可以用 regex!绝对是我不想错过的功能。这与多光标结合起来非常酷!(Ctrl+Shift+L)

禅宗模式

Shift+Shift+P并搜索“禅”。在这种模式下,你有代码。没有小地图,没有文件浏览器,没有页脚。如果你想向另一个开发者展示一些东西,这是很有帮助的。你可以调整在禅模式下显示什么。比如我还是想看行号。

17 种快捷方式

艾米·j·安德鲁斯写了这篇很棒的文章,里面有 17 条捷径:

[## 17 个有用的 Visual Studio 代码快捷方式来提高您的编码速度

这是世界上最好的代码编辑器中最酷的特性

medium.com](https://medium.com/javascript-in-plain-english/17-useful-visual-studio-code-shortcuts-to-boost-your-coding-speed-68e46705d542)

自动完成

VS Code + pylance 提供了惊人的自动补全功能💘请注意,你需要告诉它一点你在做什么。使用类型注释来帮助 VS 代码来帮助你。对了,型标注很牛逼

带有 pylance 的 VS 代码的自动完成示例。截图由作者拍摄。

签名提示

我有时想得到一个关于函数签名的提示。在 VS 代码中,你只需将鼠标悬停在名字上就可以得到它。该框包含文档字符串😍

悬停在名称上时的函数签名提示。截图由作者拍摄。

跳到定义

点击您感兴趣的内容,然后按下F11。就是这样。它工作了。并且运行得非常好,非常流畅!你可以用任何东西做到这一点:函数,变量,第三方的东西,核心库的东西。

排除故障

Visual Studio 代码的调试界面是轻量级的,并且在大多数情况下都有您需要的功能:(1)您可以在想要设置断点的地方单击。(2)您可以通过单击活动栏中的播放按钮来启动调试器。在这里,您还可以看到所有变量的当前值。(3)继续、单步执行、单步进入、单步退出、重启和停止调试器。(4)观察终端中的输出。

截图由作者拍摄

WSL2 集成

这个插件太神奇了,它值得拥有自己的部分:

[## 将 WSL 2 与 Visual Studio 代码一起使用

Matt Hernandez,2019 年 9 月 3 日@ fiveisprime 距离 Windows 的最初测试版已经过去了几个月…

code.visualstudio.com](https://code.visualstudio.com/blogs/2019/09/03/wsl2)

差异工具

Visual Studio 代码集成了一个相当不错的比较工具。您可以从控制台使用

code --diff file1 file2

Windows 用户:你也可以从 WSL2 中的 Ubuntu 控制台执行这个!

单元测试集成

Ctrl+Shift+PConfigure Tests:

作者图片

然后,您将能够在 VS 代码中单击一个测试来运行测试😍

自定义

Visual Studio 代码提供了许多自定义方式。你有数百种设置、颜色主题和插件。

主题

Ctrl+Shift+P,搜索“主题”:

深色和浅色主题,包括日光化和 Textmate😍截图由作者拍摄。

设置

截图由作者拍摄

你也可以通过一个settings.json文件定制东西。这里有一些我喜欢的设置,使用的是 Ubuntu Mono 字体:

{
    "editor.renderWhitespace": "all",
    "editor.fontFamily": "Ubuntu Mono",
    "workbench.colorTheme": "textmate",
    "python.formatting.provider": "black",
    "python.languageServer": "Pylance",
    "python.analysis.typeCheckingMode": "basic",
    "python.defaultInterpreterPath": "/home/moose/.pyenv/shims/python",
    "zenMode.hideLineNumbers": false,
    "zenMode.hideStatusBar": false,
    "python.analysis.extraPaths": [
        "/home/moose/.pyenv/versions/3.8.6/lib/python3.8/site-packages"
    ],
    "workbench.colorCustomizations": {
        "terminal.background": "#373633",
        "terminal.foreground": "#dfdbd2",
    },
    "terminal.integrated.fontFamily": "Ubuntu Mono derivative Powerline"
}

工作区

您可以在您的工作区设置中定制忽略哪些文件/文件夹。例如,创建一个.vscode/settings.json,并为 Python 项目添加以下内容:

{
    "files.watcherExclude": {
        "**/.pytest_cache/**": true
    },
    "files.exclude": {
        "**/.mypy_cache": true,
        "**/.pytest_cache": true,
        "**/*.egg-info": true,
        "**/mypy-report": true
    }
}

插件

最后,是时候谈谈市场了,尤其是 pylance!

挂架

Pylance 是一个 Python 语言的服务器。作为用户,你不用太担心。把它想象成一个插件,它给你自动完成、签名帮助、类型检查等等。如果你使用类型注释,那就更棒了。

作为一个想知道事情如何在引擎盖下工作的开发人员,我必须感谢微软的这个好设计。他们去掉了一个困难的部分,这样一个单独的团队就可以处理它了。理论上,这可以集成到其他编辑器/ide/服务中。实际上,许可证禁止。此外,定义这样一个语言服务器接口允许开发者为其他语言创建语言服务器🌟拥有这个接口是好的软件架构的标志。

我必须在用户设置中启用 pylance 的“基本”类型检查模式(Ctrl+Shift+P)。截图由作者拍摄。

彩虹括号

彩虹括号颜色嵌套括号:

用彩色括号更容易读,不是吗?

路径智能感知

路径智能感知在编辑器中自动完成路径:

截图由作者拍摄

吉特朗斯

GitLens 显示 git 历史信息:

你注意到灰色的文字了吗?这是编辑器(me)的名称,是编辑完成的时间和提交消息的第一行。截图由作者拍摄

如果您将鼠标悬停在消息上,您可以跳转到打开图形比较的提交😍

之前突出显示的提交的图形差异。截图由作者拍摄。

AWS 工具包

AWS 工具包插件将关于 S3 桶、Lambdas、Cloudwatch 日志等信息添加到你的活动栏:

截图由作者拍摄

荣誉奖

  • SQLTools :从 VS 代码内部运行 DB 查询
  • 现场分享 :电晕时代的结对编程支持。不过,到目前为止,我还没有试过这个插件。

对比:vs 代码 VS 崇高文本 vs PyCharm

与 Sublime Text 相比,VS Code 最初给我的感觉更重一些。然而,这可能仅仅是因为我大约从 2010 年开始使用 Sublime Text(我在 2014 年购买了许可证)。在一个工具上有 10 年的经验意味着你已经很习惯这个工具了。除了 Sublime 的速度惊人之外,我看不出它比 VS Code 有什么优势。

相比 PyCharm Professional,VS Code 感觉轻量级多了。速度更快,界面更干净。我不是绝对确定,但是 pylance 也可能比 PyCharm 的自动完成要好。PyCharm 的优势在于边缘情况:数据库工具窗口、SciView,可能还有一些调试特性,当然还有代码检查

摘要

微软在 VS 代码方面做得非常出色:它速度快,可定制,有必要的功能,一个市场,合理的默认值,干净的界面,支持 Windows/Mac/Linux,并且是免费的。太棒了。我喜欢!💜

下一步是什么

在这个“Python 初学者”系列中,我们已经解释了如何在 Windows 上使用 Python 和 wsl 2如何在 Windows 上使用 Python 和 Anaconda 。本文将 Visual Studio 代码作为初学者和专业人员的良好 IDE。

接下来,我们应该编写一个 hello world 应用程序。我乐于接受各种想法😁

宝莱坞的数据可视化:第二部分

原文:https://towardsdatascience.com/visualisation-of-bollywood-2c973328ddc9?source=collection_archive---------51-----------------------

角。2~使用 Plotly Express 显示数据

Kushagra Kevat 在 Unsplash 上拍摄的照片

这篇文章将是我收集的数据的可视化表示,正如我在的上一篇文章中所写的。

对于这种可视化,我将使用 pandas 和 plotly express 库,它们通过以下方式导入到 Jupyter 笔记本中:

import pandas as pd
import plotly.express as px

然后,使用 pd.read_csv 函数,读取包含所需数据的 csv 文件的组件。

movies = pd.read_csv('Bollywood_movies.csv')

注意:当我将从 BeautifulSoup 收集的数据保存到 excel 表格中后,我在将其导出到 csv 文件之前做了一些清理和排序工作。

当被调用时,表看起来像这样。

由于数据相对较小(9 列和 25 个条目),这在某种程度上限制了我可以进行的可视化,对此我进行了探索:

  • 每年发行多少部票房最高的电影?
  • 有没有导演过不止一部票房最高的电影?
  • 哪种语言更受青睐?

1.世界电影总量比较

如这个柱状图所示,宝莱坞票房最高的电影是在₹2,000·克罗尔(大约 3.11 亿美元)附*上映的摔跤吧!爸爸,紧随其后的是在₹1,800·克罗尔上映的巴胡巴利 2(2.78 亿美元)。丹格尔的收入比票房第三的电影《Bajrangi Bhaijaan》多 50%。

虽然数字很大,但这并不令人惊讶,因为 Dangal 有一个精彩的故事线,对每个人和任何看过它的人都是鼓舞人心的(这没有任何偏见)。

它在 2016 年的发行不仅在印度,而且在世界各地都很受欢迎。那段时间我在中国学习,我记得我的一个密友告诉我,她和她妈妈一起看了这部电影(她妈妈在一个月内看了 3 遍)!

2.年度图表

每年都有令人惊叹的电影问世,但我想确定哪一年票房最高的电影数量最多。

分析图表,很明显 2018 年是一年!5 部票房最高的电影都是在同一年导演和制作的!

3.哪个导演的点击率最高?

为了做到这一点,我制作了一个图表,显示了导演的名字与他们所有电影的总票房。我调整了点的大小,以代表他们从列表中执导的电影数量。

巴胡巴利系列的导演 S.S .拉贾穆利总共有两部电影,总票房最高(₹2460·克罗斯/3.79 亿美元)。可以注意到,尼特什·提瓦瑞只导演了一部电影,但票房却是最高的……你能猜出是哪部电影吗?

你猜对了,丹格尔。

4.语言偏好

在 25 部电影中,大部分是印地语,3 部是泰卢固语,1 部是泰米尔语。

同样,这并不令人惊讶,因为印度电影业(宝莱坞)是迄今为止最大的,其次是泰米尔工业(Kollywood)和泰卢固语工业(Tollywood)。

虽然用其他地区语言制作的电影没有得到应有的认可,但这些电影已经被翻译成尽可能多的流行印度语言。

也许未来几年趋势会改变…让我们看看吧!

5.最后的想法

既然你已经读完了整篇文章,为什么不看一部列出的电影来奖励自己呢?

你值得拥有;)

检查我的 GitHub 的所有代码。

使用 Python、Dash 和 Plotly 可视化新冠肺炎案例数据

原文:https://towardsdatascience.com/visualise-covid-19-case-data-using-python-dash-and-plotly-e58feb34f70f?source=collection_archive---------8-----------------------

立即创建您自己的仪表板 Web 应用程序!

这篇文章不是关于新冠肺炎,而是关于如何使用 Python & Dash 创建一个有用的 web 应用程序。它旨在作为一个简单的指南,帮助&掌握这项技术,并让自己动手

我写了很多关于如何使用 R & Shiny 执行这个任务的 相同的文章,并有意想要比较这两个软件栈。在这里我用 Python-Dash 的方式解释一下,不过我计划在 的另一篇 中做一个 的专用比较 的解决方案。

要了解最终的应用程序是什么样子,请测试该应用程序:

https://go.aws/2xsdb7q

下面的分步指南解释了如何创建这个 web 应用程序,包括交互情节。软件栈基于 Python & Dash ,并且是开源的。总共只有大约 130 行代码。

顺便说一句,本文底部提供了一个链接,链接到 GitHub 代码库供下载。

目标

目标是创建一个 web 应用程序,它在应用程序启动时更新新冠肺炎案例数据,并在仪表板上显示数据。特点:

  • 冠状病毒官方可用数据的下载和解析。
  • 下拉菜单选择国家和州。
  • 显示所选国家新的和累积的病例统计数据的两个图。可以选择确诊病例、痊愈病例、死亡病例。

任务

  1. 设置 Python 和 Visual Studio 代码。
  2. 设置 Python 项目及其文件夹结构。
  3. 实现加载和预处理数据的逻辑。
  4. 使用 Dash & Plotly 创建用户界面。
  5. 添加服务器逻辑。
  6. [可选]将应用程序上传到云。

设置 Python 和 Visual Studio 代码

首先,从https://www.python.org/downloads/下载 Python 的最新稳定版,启动安装程序并通过。

对于代码编辑器的选择,有很多可能性。 Visual Studio 代码是一个有效选项。要安装它,从https://code.visualstudio.com/download下载安装程序,运行它,完成安装。

设置 Python 项目及其文件夹结构

Python 中的包管理有多种解决方案: pippipenv(ana)conda虚拟环境。如需快速解释,请参见本文中的帖子。我们在这里使用 虚拟环境

仍然在命令行上,移动到应用程序应该位于的目录。然后创建一个新的 app 目录和一个虚拟环境:

cd <folder-with-my-apps>   # Put here the folder of your choice.
mkdir corona-app           # Create a dedicated app directory.
cd corona-app              
virtualenv venv            # Create the virtual environment 'venv'.

接下来,激活虚拟环境。在 macOSLinux 上,做:

source venv/bin/activate

窗口的 上,输入:

venv\Scripts\activate

要将软件包安装到新环境中,请键入:

pip install dash      # Installs <plotly>, too.
pip install pandas

现在打开 Visual Studio 代码。在欢迎屏幕的右上角(自定义->工具和语言),您可以选择 Python 来安装对 Python 的语言支持:

仍在欢迎屏幕上,点击左侧的“打开文件夹……”,并选择您之前创建的文件夹( corona-app ):

关于设置和定制 VS 代码的更多细节,请看这个专门的教程。下一步是创建文件 app.py ,其中将包含我们需要的所有 app 代码。点击文件浏览器上的加号按钮,输入文件名。

现在我们可以开始编码了!

实现加载和预处理数据的逻辑

在 Visual Studio 代码中,如果文件尚未打开,请单击文件名“app.py”。键入下面几行来加载我们需要的库:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
from dash.dependencies import Input, Output
import pandas as pd

接下来,定义一个 baseURL ,我们从其中下载国家和地区的冠状病毒病例数据。数据位于约翰霍普金斯系统科学与工程中心(JHU/CSSE) 的服务器上。函数 loadData 处理下载和一些基本的转换,如下所述。

baseURL = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/"def loadData(fileName, columnName):
    data = pd.read_csv(baseURL + fileName) \
             .drop(['Lat', 'Long'], axis=1) \
             .melt(id_vars=['Province/State', 'Country/Region'], 
                 var_name='date', value_name=columnName) \
             .astype({'date':'datetime64[ns]', columnName:'Int64'}, 
                 errors='ignore')
    data['Province/State'].fillna('<all>', inplace=True)
    data[columnName].fillna(0, inplace=True)
    return data

read_csv 从网上下载文件,转换成 熊猫 数据帧。地理坐标被删除; 熔化数据帧转换为格式。然后, astype 确保类型正确。最后,如果没有区域可用,方法 fillna 插入文本 < all > 或者为包含累积案例号的列插入 0。

最后一个转换是将相应的列转换成日期类型。

通过多次调用函数 loadData ,我们加载一个清理过的数据帧【确诊病例】【痊愈病例】 和死亡病例。函数 merge 连接这 3 个数据集,得到一个包含所有数据的数据集:

allData = 
  loadData(
    "time_series_covid19_confirmed_global.csv", "CumConfirmed") \
  .merge(loadData(
    "time_series_covid19_deaths_global.csv", "CumDeaths")) \
  .merge(loadData(
    "time_series_covid19_recovered_global.csv", "CumRecovered"))

对于用户界面的初始化,我们需要国家名称。我们从大的数据帧中提取它们,使用:

countries = allData['Country/Region'].unique()
countries.sort()

现在我们已经完成了数据加载。让我们转到 UI 部分!

[更新 2020-3-27]:服务器上的文件名在 3 月 23 日更改了,所以我必须在这里也更新它们。

使用 Dash & Plotly 创建用户界面

首先,我们初始化一个外部样式表的路径和一个自定义字体(匹配这个应用程序的 R-Shiny 版本):

external_stylesheets=['https://codepen.io/chriddyp/pen/bWLwgP.css']tickFont = {'size':12, 'color':"rgb(30,30,30)", \
            'family':"Courier New, monospace"}

使用上面定义的样式表初始化 Dash 应用程序:

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)app.layout = html.Div(
    style={ 'font-family':"Courier New, monospace" }, children=[
        ## ...
    ]
])

虽然标题和两个情节遍布整个屏幕宽度,但三个控件仅占三分之一。根据引导网格系统,这转化为三个,每个列的宽度为 4,总计为 12。

我们现在输入以下代码块来定义包含控件的列,而不是三个点(见最后一个代码块):

 html.H1('Case History of the Coronavirus (COVID-19)'),
        html.Div(className="row", children=[
            html.Div(className="four columns", children=
                html.H5('Country'),
                dcc.Dropdown( 
                    id='country',
                    options=[{'label':c, 'value':c} \
                        for c in countries],
                    value='Italy'
                )
            ]),
            html.Div(className="four columns", children=[
                html.H5('State / Province'),
                dcc.Dropdown(
                    id='state'
                )
            ]),
            html.Div(className="four columns", children=[
                html.H5('Selected Metrics'),
                dcc.Checklist(
                    id='metrics',
                    options=[{'label':m, 'value':m} for m in \
                        ['Confirmed', 'Deaths', 'Recovered']],
                    value=['Confirmed', 'Deaths']
                )
            ])
        ]),

我们定义的控件是:

  • 国家下拉列表,其中填充了唯一的国家。
  • 州/省下拉菜单。至今未初始化。
  • 指标清单,填有 3 个指标名称。

对于两个条形图,我们使用交互式版本的 Plotly ( 文档),并更改配置以隐藏大量控件。代码也是子数组的一部分:

 dcc.Graph(
        id="plot_new_metrics",
        config={ 'displayModeBar': False }
    ),
    dcc.Graph(
        id="plot_cum_metrics", 
        config={ 'displayModeBar': False }
    )

添加服务器逻辑

R-Shiny 软件栈相比,Python-Dash 没有简单的解决方案来生成表达式(=数据!)无功。下一个函数返回指定国家和州的所有数据。该函数将在我们的代码中使用两次(每个图一次),因此如果计算不会发生两次,这将是一个优势:

def nonreactive_data(country, state):
    data = allData.loc[allData['Country/Region'] == country] \
                  .drop('Country/Region', axis=1)
    if state == '<all>':
        data = data.drop('Province/State', axis=1) \
                   .groupby("date") \
                   .sum() \
                   .reset_index()
    else:
       data = data.loc[data['Province/State'] == state]
    newCases = data.select_dtypes(include='Int64').diff().fillna(0)
    newCases.columns = [column.replace('Cum', 'New') 
                        for column in newCases.columns]
    data = data.join(newCases)
    data['dateStr'] = data['date'].dt.strftime('%b %d, %Y')
    return data

除了过滤国家和州的总体数据帧之外,如果用户为有州的国家(如美国)选择 <【全部】> ,该函数还会聚合数据(使用 groupbysum )。进一步的差异从累积的统计数据中计算并保存到新列中,前缀为“New”而不是“Cum”。

下一个块定义了一个函数来创建条形图,它将用于两个图。

colors = { 'Deaths':'rgb(200,30,30)', \
           'Recovered':'rgb(30,200,30)', \ 
           'Confirmed':'rgb(100,140,240)' }def barchart(data, metrics, prefix="", yaxisTitle=""):
    figure = go.Figure(data=[
        go.Bar(
            name=metric, x=data.date, y=data[prefix + metric],
            marker_line_color='rgb(0,0,0)', marker_line_width=1,
            marker_color=colors[metric]
        ) for metric in metrics
    ])
    figure.update_layout( 
              barmode='group', legend=dict(x=.05, y=0.95), 
              plot_bgcolor='#FFFFFF', font=tickFont) \
          .update_xaxes( 
              title="", tickangle=-90, type='category',  
              showgrid=True, gridcolor='#DDDDDD', 
              tickfont=tickFont, ticktext=data.dateStr,                     
              tickvals=data.date) \
          .update_yaxes(
              title=yaxisTitle, showgrid=True, gridcolor='#DDDDDD')
    return figure

该函数的顶部循环遍历指标以添加条形。底部设置条形图模式(“组”),并对图例、轴和标签进行一些调整和样式设置。最重要的是,我们想在 x 轴的每个刻度上显示日期。

反应图

虽然到目前为止 Dash 还不支持反应式表达式,但是反应式 UI 元素是支持的。如果输入值之一改变 ( 国家状态、指标),则以下回调被触发。在这种情况下,后续函数被调用并更新输出 ( )中定义的变量。

为了完成该任务,该函数通过调用适当的函数“条形图”来加载清理后的数据并呈现图表。

[@app](http://twitter.com/app).callback(
    Output('plot_new_metrics', 'figure'), 
    [Input('country', 'value'), Input('state', 'value'), 
     Input('metrics', 'value')]
)
def update_plot_new_metrics(country, state, metrics):
    data = nonreactive_data(country, state)
    return barchart(data, metrics, prefix="New", 
        yaxisTitle="New Cases per Day")[@app](http://twitter.com/app).callback(
    Output('plot_cum_metrics', 'figure'), 
    [Input('country', 'value'), Input('state', 'value'), 
     Input('metrics', 'value')]
)
def update_plot_cum_metrics(country, state, metrics):
    data = nonreactive_data(country, state)
    return barchart(data, metrics, prefix="Cum", 
        yaxisTitle="Cumulated Cases")

反应式下拉菜单

最后但同样重要的是,当用户改变选择的国家时,下拉菜单中显示的州/省必须适应update_states 提取唯一状态列表,添加 < all > ,返回整个列表并更新所选值。

[@app](http://twitter.com/app).callback(
    [Output('state', 'options'), Output('state', 'value')],
    [Input('country', 'value')]
)
def update_states(country):
    states = list(allData.loc[allData['Country/Region'] == country]
        ['Province/State'].unique()
    )
    states.insert(0, '<all>')
    states.sort()
    state_options = [{'label':s, 'value':s} for s in states]
    state_value = state_options[0]['value']
    return state_options, state_value

搞定了。

现在,您只需按下 VS 代码右上角的绿色“运行”按钮,就可以运行该应用程序。玩得开心:)

GitHub 代码

以上所有代码都可以在GitHub:https://github.com/ploner/coronavirus-py上找到

[可选]将应用程序上传到云

在网络服务器上发布应用程序非常容易,尤其是像 Heroku 这样的免费服务。

步骤是:

  • app.py 文件中添加下面一行:
server = app.server

最后的想法

这是我在 Medium 上的第二篇文章,与我的第一篇高度相关:

用 R,闪亮的& Plotly 在一眨眼的时间内可视化新冠肺炎案例数据

如果你领导着一个数据科学团队,并且你的成员也精通 R 和 Python ,那么比较 Shiny 和 Dash 可能就在你的任务清单上。让我知道你是如何做决定的。

如果你喜欢这个故事,你可能也会喜欢我在《走向数据科学》上发表的关于新冠肺炎、分析和机器学习的两个中型故事之一:

[## 厌倦了被告知新冠肺炎方向每两天改变?

忘记每日统计,遵循正确的 KPI!

towardsdatascience.com](/forget-daily-statistics-of-the-coronavirus-7e9bbb7349bd) [## 哪些国家的反应与新冠肺炎相似?机器学习提供了答案

看看你的国家(或美国的州)和它的同行相比表现如何。了解聚类分析的实际应用——使用 UMAP…

towardsdatascience.com](/which-countries-react-similar-to-covid-19-machine-learning-provides-the-answer-5971ec2f6f31)

可视化装配图

原文:https://towardsdatascience.com/visualising-assembly-graphs-fb631f46bbd1?source=collection_archive---------19-----------------------

用于宏基因组宁滨分析的可视化装配图

我研究元基因组组装图已经有一段时间了,我遇到了许多有趣的事情。在这篇文章中,我将与您分享我对宏基因组组装图和从这些图中获得的宁滨重叠群的一些观察。假设你对基因组组装有了基本的了解(如果没有你可以看我之前的文章基因组组装——基因组分析的圣杯),让我们开始吧。

什么是装配图?

装配图用于表示一个基因组(或元基因组)的最终装配。简而言之,汇编器根据读数和它们的重叠信息构建这个汇编图。最后,组装器解析组装图中的路径,并输出非分支路径作为重叠群。

下面给出了从名为 绷带 的工具中获得的装配图的可视化部分。

图一。使用绷带显示 ES+metaSPAdes 数据集。

装配图是如何表示的?

用于表示装配图的最常见的文件格式是 GFA(图形片段装配) 格式。GFA 文件由一组序列和制表符分隔的重叠序列对组成。你可以从 http://gfa-spec.github.io/GFA-spec/GFA1.html 了解更多关于这种格式的信息。

图二。GFA 样本文件的一部分

如图 2 所示,序列从“ S 开始表示,序列之间的重叠(或连接)从“ L 开始表示。加号(+)和减号(-)表示重叠中考虑的是原始序列还是其反向互补序列。链环中用字母“ M 表示的数值是指搭接长度。在这个样本文件中,重叠长度是 55 个碱基对。

如何可视化装配图?

由于我们正在讨论的组装图已经是一个“,我们可以将序列建模为顶点,将重叠/链接建模为边。

  • 顶点→序列
  • 边缘→序列之间的重叠

现在让我们使用 python-igraph 可视化一个样本装配图。你可以从我的上一篇文章中读到更多关于使用 python-igraph 可视化图形数据的内容。为了便于解释,我不考虑链接信息中的加号和减号。简单地说,我将想象一个无向图。

可视化样本图

我们将考虑由来自两种细菌物种的读数组成的数据集;粪肠球菌金黄色葡萄球菌。我们将它称为 ES 数据集。我已经使用 metaSPAdes 组装器组装了这个数据集,以获得重叠群。这个重叠群数据集被称为 ES+metaSPAdes ,可以从链接找到这里的contigs . fasta。装配图文件可以找到assembly _ graph _ with _ scaffolds . GFA

注: metaSPAdes 将每个重叠群表示为一组片段,组装图文件包含这些片段的详细信息以及这些片段之间的链接。因此,当获得重叠群之间的链接时,您必须扫描 重叠群.路径 文件和assembly _ graph _ with _ scaffolds . GFA文件 中每个重叠群的前缀和后缀,以确定重叠重叠群的前缀或后缀。

ES+metaSPAdes 数据集的可视化如下所示。

图三。装配图的可视化

比对参考基因组

我们可以将重叠群与参考基因组进行比对,以确定每个重叠群属于哪个基因组。为此,我们可以使用 BWA-MEM 。下面给出了一个运行 BWA-MEM 的示例命令。

bwa mem <**path to reference genome**> <**path to contig file**> > <**output path**>alignment.sam

对于每个重叠群,导致最长比对长度的参考基因组可以被认为是重叠群的来源。

在确定重叠群的基本事实后,我们可以标记顶点(重叠群)并将这些数据可视化,如图 4 所示。

图 4。重叠群基础真相物种的可视化。红色重叠群属于粪肠球菌,绿色重叠群属于金黄色葡萄球菌。不考虑白色节点。

从这些集会中我们能得出什么结论?

如图 5 所示,我们可以看到,两个物种的重叠群倾向于在组装图中形成两个独立的区域。

图五。这两个物种的分离可以在装配图中看到。

此外,除了边界情况之外,属于相同物种的重叠群很可能彼此之间有重叠。我们可以在宁滨分析中利用这些数据。

密码

下面是一些用来生成我在本文中展示的图像的代码片段。

构建装配图

import re
from igraph import *
from collections import defaultdictpaths = {}
segment_contigs = {}
node_count = 0# Get contig paths from contigs.paths
with open(<**path to metaSPAdes contigs.paths file**>) as file:
    name = file.readline()
    path = file.readline()

    while name != "" and path != "":

        while ";" in path:
            path = path[:-2]+","+file.readline()

        start = 'NODE_'
        end = '_length_'
        contig_num = str(int(re.search('%s(.*)%s' % (start, end), name).group(1))-1)

        segments = path.rstrip().split(",")

        if contig_num not in paths:
            node_count += 1
            paths[contig_num] = [segments[0], segments[-1]]

        for segment in segments:
            if segment not in segment_contigs:
                segment_contigs[segment] = set([contig_num])
            else:
                segment_contigs[segment].add(contig_num)

        name = file.readline()
        path = file.readline() links = []
links_map = defaultdict(set)# Get contig paths from contigs.paths
with open(<**path to metaSPAdes GFA file**>) as file:
    line = file.readline()

    while line != "":

        # Identify lines with link information
        if "L" in line:
            strings = line.split("\t")
            f1, f2 = strings[1]+strings[2], strings[3]+strings[4]
            links_map[f1].add(f2)
            links_map[f2].add(f1)
            links.append(strings[1]+strings[2]+" "+strings[3]+strings[4])
        line = file.readline() # Create graph
g = Graph()# Add vertices
g.add_vertices(node_count)for i in range(len(g.vs)):
    g.vs[i]["id"]= i
    g.vs[i]["label"]= str(i+1)for i in range(len(paths)):
    segments = paths[str(i)]

    start = segments[0]
    start_rev = ""
    if start.endswith("+"):
        start_rev = start[:-1]+"-"
    else:
        start_rev = start[:-1]+"+"

    end = segments[1]
    end_rev = ""
    if end.endswith("+"):
        end_rev = end[:-1]+"-"
    else:
        end_rev = end[:-1]+"+"

    new_links = []

    if start in links_map:
        new_links.extend(list(links_map[start]))
    if start_rev in links_map:
        new_links.extend(list(links_map[start_rev]))
    if end in links_map:
        new_links.extend(list(links_map[end]))
    if end_rev in links_map:
        new_links.extend(list(links_map[end_rev]))

    for new_link in new_links:
        if new_link in segment_contigs:
            for contig in segment_contigs[new_link]:
                if i!=int(contig):
                    g.add_edge(i,int(contig))

g.simplify(multiple=True, loops=False, combine_edges=None)

使用 python-igraph 可视化初始装配图

out_fig_name = "assembly_graph.png"visual_style = {}# Set bbox and margin
visual_style["bbox"] = (1500,1500)
visual_style["margin"] = 30# Set vertex colours
visual_style["vertex_color"] = 'white'# Set vertex size
visual_style["vertex_size"] = 35# Set vertex lable size
visual_style["vertex_label_size"] = 15# Don't curve the edges
visual_style["edge_curved"] = False# Set the layout
my_layout = g.layout_fruchterman_reingold()
visual_style["layout"] = my_layout# Plot the graph
plot(g, out_fig_name, **visual_style)

用 python-igraph 可视化彩色装配图

node_colours = []for i in range(node_count):
    if i in efaecalis_list:
        node_colours.append("red")
    elif i in saureus_list:
        node_colours.append("green")
    else:
        node_colours.append("white")out_fig_name = "coloured_assembly_graph.png"g.vs["color"] = node_coloursvisual_style = {}# Set bbox and margin
visual_style["bbox"] = (1500,1500)
visual_style["margin"] = 30# Set vertex size
visual_style["vertex_size"] = 35# Set vertex lable size
visual_style["vertex_label_size"] = 15# Don't curve the edges
visual_style["edge_curved"] = False# Set the layout
visual_style["layout"] = my_layout# Plot the graph
plot(g, out_fig_name, **visual_style)

最后的想法

我和我的实验室开发了一个名为 GraphBin 的工具,通过利用组装图和重叠群之间的连接性信息来细化合并的重叠群。你可以从这里找到 GitHub 回购。

[## Vini2/GraphBin

GraphBin 是一个宏基因组重叠群宁滨工具,它利用了来自组装…

github.com](https://github.com/Vini2/GraphBin)

GraphBin 发表在 OUP 生物信息学杂志上。你可以从 DOI:10.1093/bio informatics/btaa 180中查看关于该工具的更多信息。

[## GraphBin:使用集合图的宏基因组重叠群的精细宁滨

抽象动机。宏基因组学领域提供了对结构、多样性和生态学的有价值的见解。

dx.doi.org](http://dx.doi.org/10.1093/bioinformatics/btaa180)

你也可以从下面列出的我以前的文章中读到更多关于基因组组装和宏基因组学的内容。

[## 基因组组装——基因组分析的圣杯

组装 2019 新型冠状病毒基因组

towardsdatascience.com](/genome-assembly-the-holy-grail-of-genome-analysis-fae8fc9ef09c) [## 宏基因组学——谁在那里,他们在做什么?

深入了解微生物群落的数据

towardsdatascience.com](/metagenomics-who-is-there-and-what-are-they-doing-9f204342eed9)

希望你对我的发现感兴趣。我很想听听你的想法。

感谢您的阅读。

干杯!

想象 2020 年的篮球投篮——(大)基础。

原文:https://towardsdatascience.com/visualising-basketball-shots-in-2020-the-big-fundamentals-c48c15fa3df8?source=collection_archive---------26-----------------------

使用数据可视化来理解现代篮球中投篮的来源和原因——使用简单的图形。

在这个博客上,我写了很多主题的数据可视化,以及如何创建这些可视化。

话虽如此,我写的关于使用视觉化的主要话题是篮球。我喜欢看篮球,并开始研究数据,以更好地了解哪些因素让某些球员变得优秀,哪些因素让他们变得糟糕,以及一名球员如何影响队友或对手。然后我研究了数据可视化,因为它帮助我看到数据。

鉴于没有游戏在进行(而且暂时也不会),让我们退后一点。这篇文章从总体上谈论了联盟,以及我期望在分析中使用的基本概念。我们将使用全联盟的数据来做这件事,希望这能给我们一些共同的立足点,进行有质量的讨论。

说了这么多,让我们从头开始——从照片图表开始。

映射镜头

篮球是一项流畅、动态的运动。球从一边飞到另一边,从一端飞到另一端,球员们不停地在球场上跑来跑去,经常造成身体和四肢在球周围移动的模糊不清。

所有这些都是为了一个目标——投篮,把球投进篮筐(或者阻止对手这样做)。

几年前,一些非常聪明的人,如柯克·戈德贝里开始通过地理来看待篮球,以及它的投篮来自哪里。一种用于可视化篮球投篮的技术被称为 hexbin 图。

它允许法院被划分成小的、大小相等的六边形,并映射每个六边形的*均属性。下面,我根据每个区域的射击频率(统计学术语中的频率)来给这些六边形着色。

Hexbin 图表,显示拍摄频率

该图捕捉了 2018-2019 NBA 赛季期间拍摄的所有 22 万张左右的照片。投篮明显集中在限制圈内的*距离,三分线外。用离篮筐的距离来绘制投篮频率(整体)也说明了类似的问题。

大多数照片是在 4 英尺范围内拍摄的(在限制圈内),或者超过 23 英尺范围。乍一看,这是一个奇怪的分布,因为你可能会认为拍摄频率随着距离线性下降。然而,调查每个区域的拍摄值会告诉我们答案。

射击精度和价值

为了理解为什么 NBA 球员如此多的远距离投篮,我们需要了解两个关键因素,即准确性和投篮价值。很明显,随着我们远离篮筐,投篮会变得越来越不准确。(如果你不确定,去外面试着投一些 25 英尺的球,然后试着投几个 5 英尺的球,然后回来。我会等的。)

在这个范围内,射击精度会降低多少?好吧,看一看:

值得注意的是,NBA 球员的*均投篮命中率在 4 英尺到 21 英尺的范围内几乎没有移动,甚至这些天在 28-29 英尺之间的投篮命中率*均为 33.9%。相比之下,5-6 英尺范围内的投篮命中率为 38.3%。

这显然是一个*均值。它受到许多因素的影响,包括谁在投篮,防守在做什么。这张图表并不是说从 5-6 英尺的距离投篮和从 24-25 英尺的距离投篮一样困难,后者的准确率是 37.6%。较好的射手比差的射手更经常从远处投篮。但是很明显,这一比例已经达到了 50%左右的*衡。

然而,虽然每一次击球都是以彼此相似的精度进行的,但从 24-25 英尺的击球比从 5-6 英尺的击球得分多 50%。这是现代 NBA 的关键。

用什么方法来衡量这个奖励系统的效果?答案是预期(或*均)投篮值。

该图显示了每次发射的(统计)值;换句话说,一次投篮*均会产生多少分的。来自额外点的附加值用橙色显示,而且是巨大的,如这张图表所示。

由于每次投篮都有额外的分数,从 24-25 英尺的距离投篮和从 2-3 英尺的距离投篮几乎一样有益。与短镜头相比,长镜头的另一个优势是空间。在篮球场上,距离篮筐 24-25 英尺的空间比距离篮筐 2-3 英尺的空间大得多。看看这个:**

对手需要覆盖更大的区域来覆盖 24-25 英尺的射门(橙色),而不是 2-3 英尺的射门(蓝色)。此外,必须覆盖这么多地面和这么远意味着在地板上的其他地方创造了更多的空间。内外博弈是共生互补的,善于一方为另一方开拓机会。

按距离划分的总拍摄频率

回到统计数据,NBA 总投篮次数按距离的分布如下图。

几乎三分之一(31%)的投篮来自 4 英尺以内,4 到 22 英尺之间也差不多,其余的来自三分线以外。

这也有助于我们将法庭分成几个不同的区域。还记得上面的 hexbin 图吗,把地板分成微小的六边形?我们可以将其中一些组合在一起,这样我们就可以按区域查看统计数据。这也是有价值的,因为它允许我们从非常小的样本量中*滑统计数据。(说一个球员在离篮筐 25 英尺的一个位置上有 4/10 的命中率,而在邻*的一个位置上有 6/10 的命中率是没有多大价值的——这可能只是随机的,而不是说那个球员在第二个位置上是一个更好的射手。)

各个击破

现在,我们有足够的信息和直觉将 NBA 球场分成区域。对于不叫库里或 T2 的普通人来说,任何超过 32 英尺的东西都是绝望的发泄,所以我们将 32 英尺以上的人归为一个大区域。从那里开始,三分球分为角球,正常三分球和长三分球。中距离分为 3 组距离,留在篮筐周围投篮,把禁区直径内的一切都分组。

此外,我们将根据角度进一步划分大多数球场——左边、中间或右边。生成的区域绘制如下,每个区域用不同的颜色表示:

NBA 区域球场

在某些情况下,我们可能会将六边形数据与区域数据结合起来,保持六边形频率,同时通过使用区域数据来*滑投篮命中率。

这是很多相对抽象的讨论——这种分区实际上是如何工作的?我们将用一些实际例子来结束这篇文章。

罪犯

在 2018-2019 常规赛中,勇士队的 FG%和积分/100 控球率最好,尼克斯队在这两个类别中都最差。让我们比较一下这两种犯罪。

GSW(左)和 NYK(右)拍摄图表

勇士的投篮图在左边,尼克斯在右边。每个六边形的大小表示该队从那个特定的(六边形)投篮的频率,颜色来自划分的整个(上面的彩色区域)的*均投篮百分比。

这创造了一个很好的视觉效果,我们可以看到照片的具体位置,而不会被小样本可能导致的百分比大幅波动所淹没。

这些剧情让我们很容易的对两队进行评价。勇士队显然在任何地方都更好,从右边看非常强大(从球员的角度看是右边,所以在我们的图像中是左边)。

如果我挑毛病的话,这个情节的问题可能是很难看出这些颜色的相对差异,我们不知道它们与联盟*均水*相比如何(看起来像这样)。

整个 NBA 的投篮排行榜

让我们来看一下相关的统计数据,用蓝色标记比*均水*差的区域,用红色标记比*均水*好的区域。).

整个 NBA 的投篮排行榜

我们通过允许我们观察两个方向(消极和积极),以及观察相对较小的数字,从本质上扩大了范围。勇士几乎在所有领域都优于联盟*均水*,右侧投篮简直就是绝对的血洗。与此同时,在右边,倒霉的尼克斯队在冰冷的蓝色海洋上打着冰桩。

这样看起来会好多少?

好吧。我希望那是有趣的。如果你是一名程序员,并且想了解更多关于我如何编写这些代码的信息,请点击这里查看我之前的文章:

* [## 用 Plotly 实现交互式篮球数据可视化

用 hexbin shot 图表分析体育数据,用 Plotly 和 Plotly Express 分析气泡图(源代码&我自己的数据…

towardsdatascience.com](/interactive-basketball-data-visualizations-with-plotly-8c6916aaa59e)

如果你喜欢这个,比如说👋/关注 twitter ,或点击此处获取更新。下次见!*

用 Python-igraph 可视化图形数据

原文:https://towardsdatascience.com/visualising-graph-data-with-python-igraph-b3cc81a495cf?source=collection_archive---------8-----------------------

使用 CiteSeer 数据集介绍 python-igraph

图形学习和可视化

图形学习技术在数据科学家中变得流行,因为图形提供了更多的工具来表示数据点及其相互之间的关系。数据点可以用顶点来表示,这些数据点之间的关系可以用图形的边来表示。这样的数据点,以图表的形式,可以被馈送到各种算法(例如:神经网络)中,以执行不同的学习任务(例如:分类和聚类)。

数据集可能包含一堆数据点,乍看之下,我们可能无法从这些原始数据中找到任何意义。通过将这些数据点可视化为图表,我们可以很容易地找到数据集中的模式、聚类甚至异常值。图形结构可以为我们的学习过程提供有价值的信息,例如数据点和相关统计数据之间的连接/关系的性质。在这篇文章中,我将向你展示如何可视化 CiteSeer 数据集的标签网络,并尝试看看我们是否能从可视化中看到任何模式。

igraph 和 python-igraph

igraph 由一套工具组成,可以用来高效地分析网络。igraph 是免费的,可用于 Python、R、C/C++和 Mathematica。在本文中,我们将使用 Python 版本, python-igraph 。你可以参考 python-igraph 手册了解更多细节。

入门指南

安装 python-igraph

首先,如果您还没有安装 python-igraph,那么您需要安装它。您可以使用 pip 。你还需要安装cairo CFI来绘制图表。

pip install python-igraph
pip install cairocffi

如果您使用的是 Python 包管理器,如 Anaconda 或 Miniconda,您可以使用 conda install 命令安装 python-igraph。

conda install python-igraph
conda install cairocffi

CiteSeer 数据集

CiteSeer 数据集由科学出版物及其引文组成。顶点代表科学出版物,边代表引文。科学出版物被分为六个类别之一;代理、人工智能、数据库、人机交互、机器学习和信息检索

首先,你必须从http://networkrepository.com/citeseer.php下载带标签的数据集。你会有两个文件 citeseer.edgesciteseer.node_labelsciteseer.edges 文件会有边缘的形式

vertex_1, vertex_2, weight

citeseer.node_labels 文件会有每个顶点的标签,以

vertex_id, class_label

将图表形象化

我们将使用 CiteSeer 数据集构建一个无向图。一旦构建了图表,您就可以如图 1 所示对其进行可视化。

图一。CiteSeer 网络的无标号图的可视化

现在,您可以获得标签并可视化标签图,如图 2 所示。

图二。CiteSeer 网络标记图的可视化

分析图表

您可以观察到,有些小的子图具有相同的颜色(标签),而某些子图的顶点具有不同的颜色(标签)。

通过分析该图获得的一些统计信息如下。

Number of vertices: 3264
Number of edges: 4536
Density of the graph: 0.000851796434172811Average degree: 2.7794117647058822
Maximum degree: 99
Vertex ID with the maximum degree: 2906Average number of triangles: 1.0716911764705883
Maximum number of triangles: 85
Vertex ID with the maximum number of triangles: 2906Degree having the maximum number of vertices: 1
Number of vertices having the most abundant degree: 1321Diameter of the graph: 28Assortativity of the graph: 0.04806382149471062

从这些结果可以看出,这是一个稀疏图,其中边的数量远远小于可能的边的最大数量(密度较小)。而且每篇文章*均至少参与两次引用(*均程度)。每一个物品至少参与一个与另外两个物品的三角连接。

大多数文章参与一次引用,有 1321 篇这样的文章(学位分布分析如图 3 所示)。此外,图的顶点具有与具有相同度数的其他顶点连接的较小趋势(较小的协调性)。

图三。CiteSeer 图中顶点的度分布

同样,您可以分析图形结构并找到其他模式。

密码

我已经在 Jupyter 笔记本上添加了我使用的代码,所以你可以自己尝试一下。

最后的想法

目前,图学习已经成为分析数据和预测模式的有力手段。目前可用的技术可以将图的每个节点嵌入到具有特征的真实向量中。此外,图形神经网络已经被引入,它是可以在图形结构上操作的特殊神经网络。我发现这些图形学习技术真的令人惊讶。

您可以从 GraphViz 查看 CiteSeer 数据集的详细可视化。

如果你想阅读更多关于可视化大型图表的内容,可以看看这篇很棒的文章。

希望你喜欢我的文章,并将尝试代码。让我知道你的想法,如果我有任何错误,也请纠正我。

干杯!😃

参考

[1]鲁青,丽丝·格托尔。基于链接的分类ICML 03:第二十届机器学习国际会议论文集。2003 年 8 月。第 496-503 页。

[2]瑞安·罗西和内斯林·艾哈迈德。第二十九届 AAAI 人工智能会议的记录中的具有交互式图形分析和可视化的网络数据仓库。2015.

[3]citeseer-labered Networks |网络数据仓库(http://networkrepository.com/citeseer.php)

[4] GraphVis —交互式可视图形挖掘和机器学习|网络数据仓库(http://networkrepository.com/graphvis.php?d=。/data/GSM 50/labered/citeseer . edges

在 Keras 中可视化 LSTM 激活

原文:https://towardsdatascience.com/visualising-lstm-activations-in-keras-b50206da96ff?source=collection_archive---------7-----------------------

看看每个 LSTM 细胞学到了什么

弗兰基·查马基在 Unsplash 上拍摄的照片

你有没有想过 LSTM 层学到了什么?有没有想过是否有可能看到每个细胞对最终输出的贡献。我很想尝试想象一下。在满足我好奇的神经元时,我偶然发现了安德烈·卡帕西的博客,名为循环神经网络的不合理有效性。如果你想得到更深入的解释,我建议你去看看他的博客。

在本文中,我们不仅要在 Keras 中构建一个文本生成模型,还要可视化一些单元格在生成文本时所看到的内容。与 CNN 的情况一样,它学习图像的一般特征,如水*和垂直边缘、线条、补丁等。类似地,在文本生成中,LSTMs 学习诸如空格、大写字母、标点符号等特征。我们将会看到 LSTM 层中的每个细胞正在学习什么特征。

我们将使用刘易斯·卡罗尔的《爱丽丝漫游奇境记》这本书作为训练数据。该模型架构将是一个简单的架构,由两块 LSTM脱落层以及最后的密集层组成。

您可以在此下载训练数据和训练模型权重

这是我们激活单细胞的样子。我希望你能辨认出上图中的图案。如果不能,你会在文末找到。

让我们深入研究代码。

步骤 1:导入所需的库

注意:我用 CuDNNLSTM 代替了 LSTM,因为它训练速度快 15 倍。CuDNNLSTM 由 CuDNN 支持,只能在 GPU 上运行。

第二步:读取训练数据并进行预处理

我们将使用正则表达式删除一个以上的空格。char_to_intint_to_char只是数字到字符和字符到数字的映射。

步骤 3:为培训准备数据

重要的是准备好我们的数据,使每个输入都是一个字符序列,输出是后面的字符。

步骤 4:构建模型架构

第五步:训练模型

我无法一次训练我的模型 300 个纪元,因为我使用了 Google Colab 来训练我的模型。我必须在 3 天内训练它,每天 100 个周期,方法是保存重量,然后从我结束训练的同一点重新加载。

如果你有一个强大的 GPU,你可以一口气训练 300 个纪元的模型。如果你没有,我会建议你使用 Colab,因为它是免费的。

您可以使用下面的代码加载模型,并从最后一点开始训练。

现在是文章最重要的部分——可视化 LSTM 激活。我们需要一些函数来让这些可视化变得可以理解。让我们开始吧。

步骤 6:获取中间层输出的后端函数

正如我们在上面的步骤 4 中看到的,第一层和第三层是 LSTM 层。我们的目标是可视化第二 LSTM 层的输出,即整个架构中的第三层。

Keras Backend 帮助我们创建一个函数,它接收输入,并从中间层向我们提供输出。我们可以用它来创建我们自己的管道函数。这里attn_func将返回一个大小为 512 的隐藏状态向量。这些将是 512 个单位的 LSTM 层的激活。我们可以想象这些细胞的每一次激活,以理解它们试图解释什么。要做到这一点,我们必须将它转换成一个可以表示其重要性的范围。

步骤 7:助手功能

这些辅助函数将帮助我们可视化字符序列及其每个激活值。我们通过sigmoid函数传递激活,因为我们需要一个可以表示它们对整个输出的重要性的值。get_clr功能有助于为给定值获得合适的颜色。

下图显示了每个值是如何用各自的颜色表示的。

从 0 到 1 的激活颜色级别

第八步:获得预测

get_predictions函数随机选择一个输入种子序列,并获得该种子序列的预测序列。visualize函数将预测序列、序列中每个字符的 sigmoid 值以及要可视化的单元格编号作为输入。根据输出的值,用适当的背景颜色打印字符。

对层输出应用 sigmoid 后,值在 0 到 1 的范围内。数字越接* 1,重要性越高。如果该数字更接* 0,则意味着对最终预测没有任何重大影响。这些单元格的重要性由颜色表示,其中蓝色表示较低的重要性,红色表示较高的重要性。

步骤 9:可视化激活

超过 90%的细胞没有显示任何可理解的模式。我手动可视化了所有的 512 个细胞,注意到其中的三个(189,435,463)显示了一些可以理解的模式。

正如您在下面看到的,189 号单元格是为引号内的文本激活的。这表明预测时单元格在寻找什么。如下所示,该单元格对引号之间的文本贡献很大。

435 号单元格是为引号中的句子后的几个单词激活的。

每个单词的第一个字符激活单元号 463。

通过更多的训练或更多的数据,可以进一步改善结果。这恰恰证明了一点,深度学习毕竟不是一个完全的黑箱。

你可以在我的 Github 简介上查看全部代码。

这是我第一次尝试写博客。我希望你能从中学到一些东西。

可视化 100 本吴唐家族相册

原文:https://towardsdatascience.com/visualising-the-albums-of-wu-tang-clan-246ea75efdac?source=collection_archive---------21-----------------------

深入挖掘吴唐家族及其核心成员的著述。

吴唐家族有一个几乎无与伦比的大字典。他们录制了 100 张录音室专辑。这还不包括该组合大约 90 张附属专辑的混音带或专辑。

但是考虑到这个组合经久不衰的人气,很难找到关于这个组合音乐的详细信息——所以我决定做点什么。

这篇文章的灵感来自于听我最喜欢的一张专辑,格斯特菲斯·基尔拉的《至尊顾客》。这张专辑基本上是一张非官方的武堂专辑,收录了武堂 10 位成员中的 9 位。唯一缺席的是《肮脏的混蛋》,他在专辑录制的大部分时间里都被监禁着。

我开始思考其他非官方的武堂专辑。GZA 的“液体剑”跃入脑海。我猜有更多,但快速谷歌搜索什么也没找到。维基百科丢失了详细信息。对十年前的论坛帖子的调查发现没有更多的东西。不久,我就开始搜索迪斯科舞厅,并建立自己的吴唐家族数据库。

一开始试图找出拥有最多吴唐成员的吴唐家族相册的事情越滚越大。我开始对专辑的时间线和乐队的排行榜表现感到好奇。这是首次对吴唐家谱进行深入分析。

武堂成员最多的专辑

这张图显示了 100 张专辑,按照这些专辑中的武堂成员数量进行排名。

吴唐家族已经制作了 9 张录音室专辑。该组合的 10 名成员已经制作了 91 张个人专辑,或者作为个人艺术家,或者作为组合的一部分。团体项目包括 Inspectah Deck 的 Czarface、马索·曼恩和莱德曼的专辑以及 RZA 的 Gravediggaz。

吴唐 1991 年以来的专辑

这张图表显示了每年发布的吴唐家族专辑的数量,以及有多少张专辑进入了公告牌前 200 名。

2019 年是自 1993 年以来,公告牌 200 强中首次没有吴唐家族相关专辑。尽管 2019 年有 6 张武堂相关专辑下跌,包括 Inspectah Deck 的 4 张专辑。首张与吴唐帮有关的专辑是 GZA 1991 年的专辑《天才的话》,比第一首吴唐帮单曲提前两年发行。

最多产的武堂成员

这张图显示了最多产的吴唐成员。图表由作为个人艺术家的专辑、在吴唐专辑中的出现以及在其他成员的个人项目中的出现来分割。特色亮相包括作为说唱歌手或制作人的亮相。

RZA 参与了 100 个吴唐项目中的一半以上,总共出场 54 次。他出现在吴唐的每一张专辑,14 张他自己的个人专辑中,并在 31 张个人专辑中以制作人或说唱歌手的身份出现。Ghostface 拥有最多的个人专辑,有 19 张。

谁的点击率最高?

这张图显示了武堂帮的专辑在 Billboard Top 200 排行榜上的表现。这是由专辑达到前 10 名,前 40 名和前 200 名。

吴唐帮只进过两次前十。然而,他们凭借《永远的武堂》获得了公告牌排行榜第一名——这是没有武堂成员独自取得的成就。

许多武堂成员的单曲销量超过了组合的销量。马索·曼恩有 6 张专辑进入前 10 名。格斯特菲斯·基尔拉的专辑在排行榜上最多,有 14 张专辑进入前 200 名。

谁失手最多?

这张图表显示了没有进入排行榜前 200 名的武堂相关专辑的数量。

Cappadonna 和 Inspectah Deck 错过了最多的 8 张非图表专辑。Inspectah Deck 的大部分失手是地下嘻哈团体 Czarface 的成员。有些专辑对不制作图表有很好的解释。《肮脏的混蛋》的遗作专辑《独一无二的儿子》没有正式发行。武堂帮的《少林往事》只有一本。这张专辑被 Martin Shkreli 以 200 万美元购得,在 Skhreli 被判证券欺诈罪后,现在属于美国联邦政府。

交互式列表

你可以进入下面的吴唐帮专辑互动列表。

方法学

专辑的数据是从 Discogs 中提取的。这些数据被导入 Google Sheets,并使用 VLOOKUP 功能进行分析,以比较艺术家在各种专辑中的角色。Google Sheets 还被用来分析每位艺人发行的唱片数量。图表表现的数据取自 Billboard。

图形首先在 Google Data Studio 中可视化,然后在 Sketch 中进一步发展。

使用主成分分析可视化数据的分类能力

原文:https://towardsdatascience.com/visualising-the-classification-power-of-data-54f5273f640?source=collection_archive---------14-----------------------

使用主成分分析来研究数据如何区分类(使用 Python 代码)

文章概述

主成分分析(PCA)是数据科学家使用的一个很好的工具。它可以用来降低特征空间的维数,产生不相关的特征。正如我们将看到的,它还可以帮助您深入了解数据的分类能力。我们将带您详细了解如何以这种方式使用 PCA。提供了 Python 代码片段,完整的项目可以在 GitHub 上找到。

什么是 PCA?

我们将从复习理论开始。如果你想了解 PCA 是如何工作的【1】【2】,我们不会进入太多细节,因为有大量的资源。重要的是要知道 PCA 是一种降维算法。这意味着它用于减少用于训练模型的特征数量。这是通过从许多特征中构造主成分(PC)来实现的。

PCs 的构造使得第一台 PC(即 PC1)尽可能解释您的功能中的大多数变化。然后 PC2 尽可能解释剩余变异中的大部分变异等等。PC1 和 PC2 通常可以解释总特征变化的很大一部分。另一种思考方式是,前两台电脑可以很好地总结这些特性。这是很重要的,因为它允许我们在二维*面上可视化数据的分类能力。

来源 1: flaticon |来源 2: flaticon |来源 3: flaticon

资料组

好的,让我们来看一个实际的例子。我们将使用 PCA 来探索一个乳腺癌数据集【3】,我们使用下面的代码导入该数据集。目标变量是乳腺癌测试的结果——恶性或良性。每次测试,都要采集许多癌细胞。然后对每个癌细胞进行 10 种不同的测量。这些指标包括像像细胞半径和细胞对称性。为了得到 30 个特性的最终列表,我们以 3 种方式汇总这些度量。也就是说,我们计算每个测量的*均值、标准误差和最大(“最差”)值。在图 1 中,我们仔细观察了其中的两个特征——细胞的*均对称性最差*滑度

在图 1 中,我们看到这两个特性有助于区分这两个类。也就是说,良性肿瘤往往更加对称和光滑。仍然有很多重叠,所以只使用这些特征的模型不会做得很好。我们可以创建这样的图来了解每个特征的预测能力。虽然,有 30 个特征,会有相当多的图需要分析。它们也没有告诉我们数据集作为一个整体的预测性如何。这就是 PCA 的用武之地。

图 1:使用两个特征的散点图(来源:作者)

PCA 整个数据集

让我们从对整个数据集进行 PCA 开始。我们使用下面的代码来做到这一点。我们从缩放特征开始,因此它们都具有 0 的*均值和 1 的方差。这一点很重要,因为 PCA 通过最大化 PCs 解释的方差来工作。由于其规模的原因,一些要素往往会有较高的方差。例如,以厘米为单位测量的距离比以千米为单位测量的距离具有更高的方差。没有缩放,PCA 将被那些具有高方差的特征“压倒”。

缩放完成后,我们将拟合 PCA 模型,并将我们的特征转换到 PCs 中。由于我们有 30 个功能,我们可以有多达 30 台电脑。对于我们的观想,我们只对前两个感兴趣。您可以在图 2 中看到这一点,其中使用了 PC1 和 PC2 来创建散点图。我们现在可以看到两个不同的集群,它们比图 1 中的更清晰。

此图可用于为数据的预测力度建立直觉。在这种情况下,它表明使用整个数据集将允许我们分离恶性和良性肿瘤。然而,仍然存在一些异常值(即,不清楚地在聚类中的点)。这并不意味着我们会对这些情况做出不正确的预测。我们应该记住,不是所有的特性差异都在前两个 PC 中被捕获。基于完整特征集训练的模型可以产生更好的预测。

图 2:使用所有特征的 PCA 散点图(来源:作者)

在这一点上,我们应该提到这种方法的警告。PC1 和 PC2 可以解释要素中很大一部分差异。然而,事实并非总是如此。在某些情况下,个人电脑可以被认为是你的功能不良总结。这意味着,即使您的数据能够很好地将类分开,您也可能无法获得清晰的聚类,如图 2 所示。

我们可以使用 PCA scree 图来确定这是否是一个问题。我们使用下面的代码为这个分析创建了 scree 图,如图 3 所示。这是一个条形图,其中每个条形的高度是由相关 PC 解释的差异百分比。我们看到,PC1 和 PC2 总共只能解释大约 20%的特征差异。即使只有 20%得到解释,我们仍然得到两个不同的集群。这强调了数据的预测能力。

图 3:碎石地块(来源:作者)

PCA —特征组

我们也可以用这个过程来比较不同组的特征。例如,假设我们有两组特征。组 1 具有基于单元对称性和*滑度特征的所有特征。然而,组 2 具有基于周长和凹度的所有特征。我们可以使用 PCA 来获得关于哪一组对于进行预测更有用的直觉。

我们首先创建两组特征。然后,我们分别对每个组进行主成分分析。这将为我们提供两组 PC,我们选择 PC1 和 PC2 来代表每组功能。这个过程的结果可以在图 4 中看到。

对于组 1,我们可以看到有一些分离,但仍有许多重叠。相反,对于组 2,有两个不同的集群。因此,从这些图中,我们可以预期第 2 组中的特征是更好的预测器。使用组 2 特征训练的模型应该比使用组 1 特征训练的模型具有更高的准确度。现在,让我们来检验这个假设。

图 4:使用特征组的 PCA 散点图(来源:作者)

我们使用下面的代码来训练使用这两组特征的逻辑回归模型。在每种情况下,我们使用 70%的数据来训练模型,剩余的 30%用于测试模型。组 1 的测试集的准确率为 74%,相比之下,组 2 的准确率为 97%。因此,第 2 组中的特征是更好的预测器,这是我们从 PCA 结果中预期的。

最后,我们将看到在开始建模之前,如何使用 PCA 来更深入地了解您的数据。这将使您了解预期的分类精度。您还将围绕哪些特征具有预测性建立直觉。在选择功能时,这可以给你带来优势。

如前所述,这种方法并不是完全可靠的。它应该与其他数据勘探图和汇总统计一起使用。对于分类问题,这些可能包括信息值和箱线图。一般来说,在开始建模之前,从尽可能多的不同角度查看数据是一个好主意。下面是另外两个你可能会感兴趣的观想教程。

[## 发现并可视化非线性关系

用部分相关图(PDP)、互信息和特征重要性分析非线性关系

towardsdatascience.com](/finding-and-visualising-non-linear-relationships-4ecd63a43e7e) [## 发现和可视化交互

使用特征重要性、弗里德曼的 H-统计量和 ICE 图分析相互作用

towardsdatascience.com](/finding-and-visualising-interactions-14d54a69da7c)

我希望这篇文章对你有帮助!如果你想看更多,你可以成为我的 推荐会员 来支持我。你可以访问 medium 上的所有文章,我可以得到你的部分费用。

[## 通过我的推荐链接加入 Medium 康纳·奥沙利文

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

conorosullyds.medium.com](https://conorosullyds.medium.com/membership)

图像来源

所有图片都是我自己的或从www.flaticon.com获得。在后者的情况下,我拥有他们的保费计划中定义的“完全许可”。

参考

[1] Matt Brems ,主成分分析一站式商店(2017),https://towardsdatascience . com/A-一站式主成分分析商店-5582fb7e0a9c

[2] L. Pachter 什么是主成分分析?(2014),https://liorpachter . WordPress . com/2014/05/26/what-is-principal-component-analysis/

[3] UCI,乳腺癌威斯康星州(诊断)数据集(2020 年),http://archive . ics . UCI . edu/ml/datasets/Breast+Cancer+Wisconsin+(诊断)

使用 ETE 工具包可视化树数据

原文:https://towardsdatascience.com/visualising-tree-data-with-ete-toolkit-bceb1ed12776?source=collection_archive---------52-----------------------

交给我来帮你拓展业务

这个世界很复杂。事物以各种不同的方式联系在一起——有些关系是直观的,有些不是。因此,我们收集并用来描述世界的数据有各种各样的形状和大小。

此外,数据可视化是数据分析过程中最重要的方面之一。良好的可视化对于帮助客户和利益相关者理解数据至关重要。

结合起来,这两点意味着处理数据的人需要准备好用最好地说明数据点之间的关系对行动可能意味着什么的方式来表示数据。今天,我们来看一个这样的表示和一个你可以用来创建它的工具。

Todd Quackenbush 在 Unsplash 上拍照

作为数据结构的树

工作中,最*接触到了是一种表示一组分层数据的方式。树中实例之间的关系很容易理解,这要归功于与我们都熟悉的植物学树的类比。当我们谈论数据结构而不是多年生植物时,根、叶和分支的概念转移得很好。

树和层次结构无处不在——常见的现实世界的例子是公司结构和进化树。

如您所见,为一组给定的层次链接数据绘制一个树相对容易。但是,当您拥有大量数据,或者您的数据在不断发展时,该怎么办呢?手动重新绘制整个过程既费时又费力…

ETE 工具包

…这就是 ETE 工具包的用武之地。这是一个用于分析和可视化树木的 Python 库。它最初是由西班牙巴伦西亚 Principe Felipe 研究中心的生物信息学部门开发的,因此它能够进行各种科学分析。这也是自动化任何树数据结构可视化的一种便捷方式,我将在这里描述它的基础。查看 ETE 工具包的图库以了解该软件包的一些更高级的特性。

可视化客户转介系统

让我们以客户推荐系统为例。您可能很熟悉这种工作方式——购买产品的客户会获得一个唯一的代码,他们可以与朋友分享该代码。如果他们的一个朋友决定也购买该产品,并在购买时引用这个独特的代码,双方都会获得奖励。这是一个双赢的场景——销售产品的公司能够通过激励他们传播信息,鼓励更多的人成为客户,将客户的利益与自己的利益结合起来——当然,客户自己也享受到了折扣。

假设每个客户最多可以推荐 5 个人。也就是说,我们目前有此数据的表格表示,如下所示:

我们有大量购买数据,包括:

  • 交易日期;
  • 客户名称;
  • 谁推荐了客户;和
  • 他们花了多少钱。

这些数据形成了一个层次结构——每个客户可以表示为树形图中的一个节点,推荐他们的人在树形图中位于他们之上,而他们继续推荐的人则位于他们之下。我们还可以看到,Alice 是“原始”客户,她启动了这个特定的推荐链,也就是说,Alice 是唯一没有被其他人推荐的客户。这使她成为了的根客户。

考虑到这一点,我们可以手动绘制一个树形图——依次遍历每个客户,找出谁应该在树中与他们相关联,并添加适当的作为子代,在他们下面分支。但是,当我们乐意为我们做艰苦的工作时,为什么要这样做呢?

ETE 以 Newick 格式— 接受输入,这是一种在数学和科学中简洁描述树形结构布局的相对标准的方式。这里有几个例子:

您可能会注意到,一组分支由一对括号表示。给定节点的分支数由括号中的逗号决定。当然,成对的括号可以嵌套起来,产生越来越复杂的结构。

我不打算在 Newick 格式的细节上花太多时间——只要知道我们可以通过将数据转换成这种格式来告诉 ETE 我们想要可视化的内容就足够了。我已经为我们写了一些代码来做到这一点,我不会在这里描述——如果你感兴趣,可以看看 GitHub 上的 Jupyter 笔记本来了解更多信息。

因此,我们的客户数据可以用 Newick 格式编写如下:

让我们看看当我们把它输入 ETE 时会得到什么:

不算太差!目前看起来很基本——但是 ETE 已经将视觉化过程中的许多复杂性去掉了。更重要的是,每当我们得到更新的数据时,我们可以简单地重新运行我们的代码!

ETE 的另一个优点是我们可以很容易地调整树的外观。让我们看看是否可以让它看起来更时髦一点…

那更好。我们仍然只是触及了 ETE 工具包的表面,但是作为一个快速的例子,这足以让我们理解一些关键的思想。

结论

人类的大脑喜欢吸取视觉信息。树有一个现成的现实世界的类比,使它们直观且易于理解。这使得它们成为向非专业人士解释数据的一个很好的工具。最后总结一下——大脑有许多天生的优势和弱点。当数据以某种方式呈现给我们时,我们总是更容易消化这些数据,这种方式是这些特性相适应,而不是相反。

更多信息和积分

Andrew Hetherington 是英国伦敦的一名见习精算师和数据爱好者。

  • LinkedIn 上与我联系。
  • 看看我在 GitHub 上鼓捣什么。
  • 用来制作本文情节的笔记本可以在这里找到。

Todd Quackenbush 在 Unsplash 上拍摄的树照片。

ETE 3:系统发育学数据的重建、分析和可视化。

海梅·韦尔塔-塞帕斯、弗朗索瓦·塞拉和皮尔·博克。

Mol Biol Evol 2016doi:10.1093/mol bev/MSW 046

使用 Matplotlib 可视化油井数据覆盖范围

原文:https://towardsdatascience.com/visualising-well-data-coverage-using-matplotlib-f30591c89754?source=collection_archive---------44-----------------------

探索数据在哪里,不在哪里

维尔莫斯·海姆在 Unsplash拍摄的照片

探索性数据分析(EDA)是数据科学不可或缺的一部分。岩石物理领域也是如此,通常被称为项目的测井质量控制或数据审查阶段。正是在这个阶段,我们开始详细检查数据,并确定我们真正拥有哪些数据,我们在哪里拥有这些数据,以及收集的数据的质量如何。

我们花了很大一部分时间(在某些情况下高达 90%!— Kohlleffel,2015 年)处理测井数据的时间都花在了试图理解数据并将其转换为适合解释的状态上。剩下的 10%是我们可以着手进行岩石物理解释的时候。这可以根据正在进行的项目的初始状态而变化。

在 QC 阶段,我们经常会发现自己有多个输入文件、随机的曲线名称、缺失的数据和没有直接用途的额外曲线。这可能会导致困惑和沮丧,尤其是在使用多种工具和老式数据集时。在我们有缺失数据的情况下,我们需要识别它并确定处理它的最佳方式。在文本编辑器中查看单个 LAS 文件可能很难做到这一点,但使用软件可以使其变得更容易。其中一种方法是使用 Python,这是一种常见且流行的编程语言。

在这篇短文中,我们将介绍如何可视化 Equinor 在 2018 年发布的 Volve 数据集的 3 个井内的数据覆盖范围。

您可以在 GitHub 上的以下链接中找到本示例的完整 Jupyter 笔记本 9——我的岩石物理学和 Python 系列的 visualizing Data covere . ipynb:

[## andymcdgeo/岩石物理学-Python-系列

本系列 Jupyter 笔记本将带您了解使用 Python 和岩石物理数据的各个方面。

github.com](https://github.com/andymcdgeo/Petrophysics-Python-Series/)

加载数据和库

与任何 Python 项目一样,我们需要加载所需的数据和库。对于本文,我们将使用 pandas 和 matplotlib。

import pandas as pd
import matplotlib.pyplot as plt# Load in our data from a CSV file
data = pd.read_csv('Data/VolveWells.csv')
data.head()

这将返回:

乍一看,我们可以看到我们的数据集中有 12 列。第一列是井,随后是深度曲线,随后是每条测井曲线。

为了识别我们的数据集中有哪些井,我们可以调用data['WELL'].unique(),它将返回一个数组,但是我们可以通过实现一个简短的 for 循环并打印出每个值来获得更好的格式。

for well in data[‘WELL’].unique():
    print(well)

这将返回 3 口井的列表:

  • 9 月 15 日-F-1 C
  • 2004 年 9 月 15 日
  • 2007 年 9 月 15 日

数据准备

为了让我们的绘图像预期的那样工作,我们需要修改数据集的列顺序。这可以通过首先按照我们想要的顺序创建一个列列表来实现。

plot_cols = ['WELL', 'DEPTH', 'CALI', 'BS', 'GR', 'NEU', 'DEN', 'PEF', 'RDEP', 'RMED', 'AC', 'ACS']

然后,我们可以用新的列顺序替换现有的数据帧:

data = data[plot_cols]
data.head()

然后我们可以调用data.head()来查看新的数据帧。

下一步是创建数据帧的副本。这将允许我们保留原始数据帧,以便在项目的后续工作中使用。

data_nan = data.copy()

为了使绘图按预期显示,我们需要替换数据框中的值。

在有实际值的地方,我们将根据它在数据帧中的位置给它分配一个数字。在我们有一个 NaN(不是数字)值的地方,我们要给它一个数字- 1 的值。这将允许我们在一个数字和另一个数字之间使用阴影,同时为每个井使用一个单独的子图。这使事情变得简单,并且不需要为每个井中的每条曲线创建支线图。

for num, col in enumerate(data_nan.columns[2:]):
    data_nan[col] = data_nan[col].notnull() * (num + 1)
    data_nan[col].replace(0, num, inplace=True)

分解上面这段代码:

  • for num, col in enumerate(data_nan.columns[2:]: 这一行将循环遍历从第 2 列开始的每一列。
    enumerate()允许我们在遍历每一列时创建一个计数器/索引值
  • data_nan[col] = data_nan[col].notnull()*(num+1) 这里我们把实数值转换成布尔值(真或假)。如果为真,则转换为列号加 1。当它为假时,这些值将被设置为 0。
  • data_nan[col].replace(0, num, inplace=True) 我们现在可以用列号替换任何 0 值。

绘制数据

现在我们已经到了策划阶段。为了在单独的子图中绘制每个井,我们必须按照井名对数据帧进行分组:

grouped = data_nan.groupby('WELL')

为了绘制数据,我们可以调用这段简短的代码。我添加了简短的注释来描述每个部分在做什么。

我们使用ax.fillbetweenx()来填充我们之前设置的每条曲线的两个值。例如,CALI 有两个值来指示数据的存在:1 表示有实数值,0 表示有 NaN 值。类似地,GR 有两个值:有实数据时为 3,有 NaN 时为 2。

#Setup the labels we want to display on the x-axis
labels = ['CALI', 'BS', 'GR', 'NEU', 'DEN', 'PEF', 'RDEP', 'RMED', 'AC', 'ACS']#Setup the figure and the subplots
fig, axs = plt.subplots(1, 3, figsize=(20,10))#Loop through each well and column in the grouped dataframe
for (name, df), ax in zip(grouped, axs.flat):
    ax.set_xlim(0,9)

    #Setup the depth range
    ax.set_ylim(5000, 0)

    #Create multiple fill betweens for each curve# This is between
    # the number representing null values and the number representing
    # actual values

    ax.fill_betweenx(df.DEPTH, 0, df.CALI, facecolor='grey')
    ax.fill_betweenx(df.DEPTH, 1, df.BS, facecolor='lightgrey')
    ax.fill_betweenx(df.DEPTH, 2, df.GR, facecolor='mediumseagreen')
    ax.fill_betweenx(df.DEPTH, 3, df.NEU, facecolor='lightblue')
    ax.fill_betweenx(df.DEPTH, 4, df.DEN, facecolor='lightcoral')
    ax.fill_betweenx(df.DEPTH, 5, df.PEF, facecolor='violet')
    ax.fill_betweenx(df.DEPTH, 6, df.RDEP, facecolor='darksalmon')
    ax.fill_betweenx(df.DEPTH, 7, df.RMED, facecolor='wheat')
    ax.fill_betweenx(df.DEPTH, 8, df.AC, facecolor='thistle')
    ax.fill_betweenx(df.DEPTH, 9, df.ACS, facecolor='tan')

    #Setup the grid, axis labels and ticks
    ax.grid(axis='x', alpha=0.5, color='black')
    ax.set_ylabel('DEPTH (m)', fontsize=14, fontweight='bold')

    #Position vertical lines at the boundaries between the bars
    ax.set_xticks([1,2,3,4,5,6,7,8,9,10], minor=False)

    #Position the curve names in the centre of each column
    ax.set_xticks([0.5, 1.5 ,2.5 ,3.5 ,4.5 ,5.5 ,6.5 , 7.5, 8.5, 9.5], minor=True)

    #Setup the x-axis tick labels
    ax.set_xticklabels(labels,  rotation='vertical', minor=True, verticalalignment='bottom')
    ax.set_xticklabels('', minor=False)
    ax.tick_params(axis='x', which='minor', pad=-10)

    #Assign the well name as the title to each subplot
    ax.set_title(name, fontsize=16, fontweight='bold')plt.tight_layout()
plt.subplots_adjust(hspace=0.15, wspace=0.25)
plt.show()

一旦我们运行上面的代码,我们会得到一个 matplotlib 图,其中有 3 个子图。每个包含每口井的数据范围。

从这个图中我们可以确定:

9 月 15 日——F-1 C

  • 伽马射线和电阻率曲线中的微小间隙。由于间隙出现在两条电阻率曲线的相同位置,我们可以初步假设它们可能与套管鞋有关。需要进一步调查来证实这一点。
  • 核曲线(登、NEU、PEF)和井径仪仅在一小段上运行,可能指示目的层。
  • 无声学曲线(交流和交流)

15/9-F-4

  • 包含所有可用的曲线,大部分在朝向井底的一小部分上。
  • 在伽马射线(GR)和声波剪切(ACS)曲线中有多个间隙。可能与工具有关。进一步的调查会揭示原因。

15/9-F-7

  • 在一个短而浅的剖面上出现的数据量最少。
  • 仅提供钻头尺寸、伽马射线和电阻率测量值。
  • 可能由工具故障或钻井时遇到的问题引起。如果有完井报告,可以通过审查这些报告来确认这些信息。

结论

在这篇短文中,我向您展示了如何从一个 CSV 文件中加载数据,并以一种您可以识别丢失值所在位置的方式来可视化它。在执行岩石物理解释或应用机器学习模型之前,了解哪里有或没有数据是探索数据集的关键步骤

参考

本例中使用的数据:
Equinor。(2018).公开所有 Volve 数据。可在:https://www . equinor . com/en/news/14 jun 2018-discovery-volve-data . html

视觉化和注意力——第一部分

原文:https://towardsdatascience.com/visualization-attention-part-1-a16667295007?source=collection_archive---------36-----------------------

FAU 讲座笔记关于深度学习

架构和培训可视化

FAU 大学的深度学习。下图 CC BY 4.0 来自深度学习讲座

这些是 FAU 的 YouTube 讲座 深度学习 的讲义。这是与幻灯片匹配的讲座视频&的完整抄本。我们希望,你喜欢这个视频一样多。当然,这份抄本是用深度学习技术在很大程度上自动创建的,只进行了少量的手动修改。 自己试试吧!如果您发现错误,请告诉我们!

航行

上一讲 / 观看本视频 / 顶级/下一讲

是时候用神经网络可视化来表现艺术了。用自动博客创建的 GIF。来源: YouTube

欢迎大家参加我们的深度学习讲座!今天我们想谈谈视觉化和注意力机制。好的,让我们开始研究视觉化和注意力机制。因此,我们将首先研究动机,然后讨论网络架构可视化。最后,我们想了解一下培训和培训参数的可视化,您已经在本课中看到了。在接下来的几个视频中,我们想谈谈参数的可视化,即内部工作原理,以及我们为什么会对这样做感兴趣。最后,我们将研究注意力机制。这将是这个短片系列的第五个视频。

可视化有助于更好地描述和理解深层网络的黑箱本质。 CC 下的图片来自深度学习讲座的 4.0 。

所以,让我们来谈谈动机。好吧,为什么我们要想象任何东西?当然,神经网络通常被视为黑盒。所以你有一些输入,然后发生一些事情,然后有一些输出。今天,我们想看看如何将网络的内部工作传达给其他人,如其他开发人员或科学家。你会发现这是你未来职业生涯中需要的一项重要技能。

为什么我们需要可视化?来自深度学习讲座CC BY 4.0 下的图片。

这是你为什么想这么做的几个原因。你想要交流架构。您希望在培训过程中发现问题,例如培训是否不一致。如果你有类似死亡的影响,你需要识别错误的训练或测试数据。你想了解网络如何学习,为什么学习,学习什么。因此,我们想在这里介绍三种主要的可视化类型。这是架构的可视化、训练的可视化、学习到的参数和权重,这对于可视化当然是重要的:网络中数据的表示。

深度学习可视化方法中的一个关键方法是网络架构的显示。 CC 下的图片来自深度学习讲座的 4.0 。

那么,让我们从网络架构可视化开始。我们本质上想要有效地交流这种特定类型的神经网络的重要性。对于一个特定网络的良好性能,我们实际上由架构强加的先验可能是至关重要的,甚至是最重要的因素。因此,这主要是通过基于图的结构以不同的粒度完成的,您将在下面看到一些示例。实际上,如果你和我们的一组关于神经网络架构的演讲视频相比,我们已经经常看到这种情况了。所以基本上有三类,

节点连接图。来自深度学习讲座的 4.0CC 下的图片。

这是节点连接图,基本上在神经元水*上起作用。节点是神经元,加权连接是边。你们已经看到了它们,尤其是在这个类的早期实例中,我们真正深入到节点级别。所有的联系都很重要。例如,如果您想要显示卷积层或全连接层之间的差异,它们会非常有用。因此,这对于小型子网或构建模块非常重要。存在具有显式加权递归连接的不同变体等等。

框图。 CC 下的图片来自深度学习讲座的 4.0 。

如果你想要更大的结构,那么我们使用框图。在那里,我们有固体块。尽管实际上所有的神经元都是相互连接的,但它们通常只共享层间的单个连接。我们已经看到了很多这样的可视化。这里你可以看到框图的可视化。这里,块是一个数学运算或层。那么,你也有箭。它们显示了数据流,并且块可以具有不同的粒度。通常,他们使用分层描述。您甚至可能想要将它与前面类型的图结合使用,以便确保哪个块执行什么样的操作。当然,您需要对超参数进行文本描述。过滤器尺寸。和过滤器的数量。这通常是在标题中完成的,或者你添加一些小数字,比如实际使用了哪些过滤器,或者使用了多少激活和特征映射。

AlexNet 的两种不同的可视化。 CC 下的图片来自深度学习讲座的 4.0 。

我们可以看到,根据你想展示的内容,有各种各样的可视化效果。这是 AlexNet 的两个可视化。最上面的一个实际上来自原始出版物,它强调了它被分成两部分,因为它运行在两个 GPU 上。然后,顶部显示的两个分支之间的连接突出显示了两个 GPU 之间的交互。现在,底层可视化更侧重于卷积神经网络结构以及汇集和卷积层。最后,您会看到连接到 SVM 分类器的完全连接的层。因此,这里更多的是关注建筑的概念,而两幅图像实际上显示的是相同的建筑。

VGG 通常使用 3D 形状显示。来自深度学习讲座CC BY 4.0 下的图片。

您已经看到了还有块变体。所以你可以在这里看到 VGG 的形象化,作者想要展示他们在特殊维度上的减少,同时在解释维度上的增加。所以在这里,只有三维块或立方体被用于可视化。在这里,它们传达了你想要从空间维度转换到解释领域的想法。有很多很多不同的方式来形象化事物。你应该选择一个在你看来能显示重要效果的。然后,你添加一个好的纹理描述。关键在于文字和图形的结合,这样别人才能理解你的想法。当然,库也有显示实际实现的图形结构的工具。一般来说,他们不太适合向他人传达信息。许多细节丢失,或者有时粒度级别太高,无法显示整个网络。因此,这对于调试来说通常是好的,但是对于报告或者传达你的架构的想法来说就不那么好了。

Graphcore 杨属于“其他可视化方法”一类。 CC 下的图片来自深度学习讲座的 4.0 。

当然,还有其他的可视化策略。在这里,我们只是简单地概述一下可以做些什么。像 Graphcore Poplar 这样的东西有这种奇特的图形可视化。你可以看到这是一个架构的代表,但如果你试图在这个可视化之后实现它,它就没有那么有用了,看着它并试图理解网络的哪个部分连接到哪个部分是一件有趣的事情。你可以清楚地看到,这些层可以在这里确定。因此,不同的层和层的配置形成不同的形状。一般来说,看着这张图片,很难说好哇,这是一个 ResNet-50。我更喜欢 ResNet-50 的不同可视化,以便弄清楚这里发生了什么。

“…我知道这看起来像是我们在摧毁一切。别担心。我们不会犯错。我们有快乐的意外。”——鲍勃·罗斯。用自动博客创建的 GIF。来源: YouTube

好了,让我们继续谈一谈培训的可视化。这也非常重要,因为它包含许多有趣的信息,如输入数据图像、文本、参数、权重、偏差、隐藏图层数据或输出数据。

培训过程也可以可视化。 CC 下的图片来自深度学习讲座的 4.0 。

当然,你想以某种方式跟踪训练过程中发生的事情。因此,这种跟踪特别有助于调试和改进模型设计。我们已经在关于惯例的系列讲座视频中谈到了这些影响。

Tensorflow 游乐场就是一个玩具的例子。 CC 下的图片来自深度学习讲座的 4.0 。

所以,这是一个非常好的可视化训练,展示在 Tensorflow 操场上。这是一个非常有趣的工具,因为在这里你不仅可以可视化连接,还可以根据输入空间可视化 2-D 输入的激活。如果你回到最初的视频,你会看到我们实际上使用了类似的表达方式,比如当我们谈论树形结构的时候。在这里,你可以看到在训练迭代中,不同层中的表示是如何变化的。他们通过在输入空间中由各自的激活函数产生的分割的可视化来实现。所以,你可以看到使用全连接层和 sigmoid 激活函数的第一层。它们本质上生成输入空间的二进制分区。然后,您在层上组合层。你可以看到输入空间的这些不同部分是如何被组合起来形成一个更复杂的形状,就像你在右边看到的。这通常仅限于 2-D 玩具示例,但是理解概念并真正理解培训过程中发生的事情是非常好的。您可以运行几次迭代。你可以加速、减速、停止训练过程,然后看看在训练的不同步骤中发生了什么。所以,这很好。

Tensorboard 是监督训练跑步的标准工具。来自深度学习讲座CC BY 4.0 下的图片。

但是如果你真的想研究大问题,那么 Tensorboard 之类的东西真的很有用。在这里,您可以监控训练过程中的实际进度。这绝对是你在训练大型网络时应该使用的东西。在这里,您可以看到损失在训练中的表现,验证损失是如何变化的,等等。你可以在整个训练过程中想象这一点,你真的可以利用这一点来看看是否有收敛或检测你的训练过程中是否有什么问题。如果你已经跑了 100 圈,而你的损失没有发生,或者如果你有一个爆炸梯度之类的东西,你会立即在 Tensorboard 的可视化中看到。

在这个深度学习讲座中,更多令人兴奋的事情即将到来。 CC 下的图片来自深度学习讲座的 4.0 。

好吧。现在,我们已经讨论了几种不同的可视化,特别是架构和培训过程。实际上,我们一直在用这个。尽管如此,我认为你应该意识到你想象事物的方式。如果你想把你的想法传达给其他人,这是非常重要的。我们将在下一个视频中谈论的实际上是可视化网络的内部工作。因此,我们将研究如何弄清楚网络内部发生了什么的技术。这些实际上是非常有趣的技术,对于调试和试图理解网络中发生的事情也非常有用。我们将在第一个视频中开始一个简短的动机和一些你应该知道的深度神经网络的弱点。非常感谢大家的收听,下期视频再见。拜拜。

如果你喜欢这篇文章,你可以在这里找到更多的文章,或者看看我们的讲座。如果你想在未来了解更多的文章、视频和研究,我也会很感激关注 YouTubeTwitter脸书LinkedIn 。本文以 Creative Commons 4.0 归属许可发布,如果引用,可以转载和修改。如果你有兴趣从视频讲座中获得文字记录,试试自动博客

链接

约辛斯基等人:深度可视化工具箱
奥拉等人:特征可视化
亚当哈雷:MNIST 演示

参考

[1] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio. “Neural Machine Translation by Jointly Learning to Align and Translate”. In: 3rd International Conference on Learning Representations, ICLR 2015, San Diego, 2015.
[2] T. B. Brown, D. Mané, A. Roy, et al. “Adversarial Patch”. In: ArXiv e-prints (Dec. 2017). arXiv: 1712.09665 [cs.CV].
[3] Jianpeng Cheng, Li Dong, and Mirella Lapata. “Long Short-Term Memory-Networks for Machine Reading”. In: CoRR abs/1601.06733 (2016). arXiv: 1601.06733.
[4] Jacob Devlin, Ming-Wei Chang, Kenton Lee, et al. “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding”. In: CoRR abs/1810.04805 (2018). arXiv: 1810.04805.
[5] Neil Frazer. Neural Network Follies. 1998. URL: https://neil.fraser.name/writing/tank/ (visited on 01/07/2018).
[6] Ross B. Girshick, Jeff Donahue, Trevor Darrell, et al. “Rich feature hierarchies for accurate object detection and semantic segmentation”. In: CoRR abs/1311.2524 (2013). arXiv: 1311.2524.
[7] Alex Graves, Greg Wayne, and Ivo Danihelka. “Neural Turing Machines”. In: CoRR abs/1410.5401 (2014). arXiv: 1410.5401.
[8] Karol Gregor, Ivo Danihelka, Alex Graves, et al. “DRAW: A Recurrent Neural Network For Image Generation”. In: Proceedings of the 32nd International Conference on Machine Learning. Vol. 37. Proceedings of Machine Learning Research. Lille, France: PMLR, July 2015, pp. 1462–1471.
[9] Nal Kalchbrenner, Lasse Espeholt, Karen Simonyan, et al. “Neural Machine Translation in Linear Time”. In: CoRR abs/1610.10099 (2016). arXiv: 1610.10099.
[10] L. N. Kanal and N. C. Randall. “Recognition System Design by Statistical Analysis”. In: Proceedings of the 1964 19th ACM National Conference. ACM ’64. New York, NY, USA: ACM, 1964, pp. 42.501–42.5020.
[11] Andrej Karpathy. t-SNE visualization of CNN codes. URL: http://cs.stanford.edu/people/karpathy/cnnembed/ (visited on 01/07/2018).
[12] Alex Krizhevsky, Ilya Sutskever, and Geoffrey E Hinton. “ImageNet Classification with Deep Convolutional Neural Networks”. In: Advances In Neural Information Processing Systems 25. Curran Associates, Inc., 2012, pp. 1097–1105. arXiv: 1102.0183.
[13] Thang Luong, Hieu Pham, and Christopher D. Manning. “Effective Approaches to Attention-based Neural Machine Translation”. In: Proceedings of the 2015 Conference on Empirical Methods in Natural Language Lisbon, Portugal: Association for Computational Linguistics, Sept. 2015, pp. 1412–1421.
[14] A. Mahendran and A. Vedaldi. “Understanding deep image representations by inverting them”. In: 2015 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). June 2015, pp. 5188–5196.
[15] Andreas Maier, Stefan Wenhardt, Tino Haderlein, et al. “A Microphone-independent Visualization Technique for Speech Disorders”. In: Proceedings of the 10th Annual Conference of the International Speech Communication Brighton, England, 2009, pp. 951–954.
[16] Volodymyr Mnih, Nicolas Heess, Alex Graves, et al. “Recurrent Models of Visual Attention”. In: CoRR abs/1406.6247 (2014). arXiv: 1406.6247.
[17] Chris Olah, Alexander Mordvintsev, and Ludwig Schubert. “Feature Visualization”. In: Distill (2017). https://distill.pub/2017/feature-visualization.
[18] Prajit Ramachandran, Niki Parmar, Ashish Vaswani, et al. “Stand-Alone Self-Attention in Vision Models”. In: arXiv e-prints, arXiv:1906.05909 (June 2019), arXiv:1906.05909. arXiv: 1906.05909 [cs.CV].
[19] Mahmood Sharif, Sruti Bhagavatula, Lujo Bauer, et al. “Accessorize to a Crime: Real and Stealthy Attacks on State-of-the-Art Face Recognition”. In: Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications CCS ’16. Vienna, Austria: ACM, 2016, pp. 1528–1540. A.
[20] K. Simonyan, A. Vedaldi, and A. Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”. In: International Conference on Learning Representations (ICLR) (workshop track). 2014.
[21] J.T. Springenberg, A. Dosovitskiy, T. Brox, et al. “Striving for Simplicity: The All Convolutional Net”. In: International Conference on Learning Representations (ICRL) (workshop track). 2015.
[22] Dmitry Ulyanov, Andrea Vedaldi, and Victor S. Lempitsky. “Deep Image Prior”. In: CoRR abs/1711.10925 (2017). arXiv: 1711.10925.
[23] Ashish Vaswani, Noam Shazeer, Niki Parmar, et al. “Attention Is All You Need”. In: CoRR abs/1706.03762 (2017). arXiv: 1706.03762.
[24] Kelvin Xu, Jimmy Ba, Ryan Kiros, et al. “Show, Attend and Tell: Neural Image Caption Generation with Visual Attention”. In: CoRR abs/1502.03044 (2015). arXiv: 1502.03044.
[25] Jason Yosinski, Jeff Clune, Anh Mai Nguyen, et al. “Understanding Neural Networks Through Deep Visualization”. In: CoRR abs/1506.06579 (2015). arXiv: 1506.06579.
[26] Matthew D. Zeiler and Rob Fergus. “Visualizing and Understanding Convolutional Networks”. In: Computer Vision — ECCV 2014: 13th European Conference, Zurich, Switzerland, Cham: Springer International Publishing, 2014, pp. 818–833.
[27] Han Zhang, Ian Goodfellow, Dimitris Metaxas, et al. “Self-Attention Generative Adversarial Networks”. In: Proceedings of the 36th International Conference on Machine Learning. Vol. 97. Proceedings of Machine Learning Research. Long Beach, California, USA: PMLR, Sept. 2019, pp. 7354–7363. A.

视觉化和注意力——第二部分

原文:https://towardsdatascience.com/visualization-attention-part-2-4b1dd17b9269?source=collection_archive---------39-----------------------

FAU 讲座笔记关于深度学习

混淆者和敌对攻击

FAU 大学的深度学习。下图 CC BY 4.0 来自深度学习讲座

这些是 FAU 的 YouTube 讲座 深度学习 的讲义。这是与幻灯片匹配的讲座视频&的完整抄本。我们希望,你喜欢这个视频一样多。当然,这份抄本是用深度学习技术在很大程度上自动创建的,只进行了少量的手动修改。 自己试试吧!如果您发现错误,请告诉我们!

航行

上一讲 / 观看本视频 / 顶级 / 下一讲

所以欢迎回到深度学习!今天,我想谈谈更多的可视化技术。但实际上,我想在接下来的几分钟里开始激发我们为什么需要可视化技术。

自主武器系统和黑匣子系统——可能会出什么问题?"各位主管,我很高兴向你们介绍执法的未来:ED 209!"。使用 gifify 创建的图像。来源: YouTube (工作不安全!).

好了,我们开始吧。视觉化和注意力机制——第二部分。参数的可视化和第一件事是动机。因此,网络学习训练数据的表示,但问题当然是在我们的网络中数据发生了什么。

我们需要可视化的一些原因。 CC 下的图片来自深度学习讲座的 4.0 。

这真的是一件很重要的事情,你真的应该关心它,因为它对调查无意和意外的行为非常有用。我在这里真正想强调的一点是对立的例子。当然,您想弄清楚为什么您的网络在实验室中表现得非常好,但在野外却失败了。所以,这也是你想要解决的一个重要问题。然后,您可以找出这种情况的潜在原因,因为如果您研究这些可视化技术,它们将帮助您识别错误类型的特征、噪声属性等。因此,我们将在接下来的视频中举几个例子。我想给你看一些轶事的例子。

“执法 Doid 系列 209 (ED 209)是一款自给自足的执法机器人。”。使用 gifify 创建的图像。来源: YouTube (工作不安全!).

例如照片中坦克的识别。这实际上是一个来自谷歌开发者尼尔·弗雷泽网站的例子。我不完全确定这是真的发生了还是只是一个都市传说。所以传说是这样的:人们和五角大楼想训练一个神经网络来识别图像上的坦克。为了构建这样一个网络,你能做些什么?嗯,你去那里,然后你拍摄坦克的图像,然后你拍摄非坦克情况的图像。嗯,通常你会希望他们出现在某些场景中。所以,你去森林里拍些照片。然后,当然,你得弄几张坦克的照片。你通常在战场上看到的坦克,你知道周围有烟、泥、脏和砂砾。所以,你收集你的坦克图像,然后你可能有 200 个森林图像和 200 个坦克图像。你会回到你的实验室,然后你训练你的深度神经网络,或者如果你只有这个非常小的数据集,可能就没那么深了。你继续下去,你会得到一个几乎完美的分类率。所以,每个人都很高兴看起来你的系统运行得很好,

我们能探测到这样的坦克吗? CC 下的图片来自深度学习讲座的 4.0 。

这张幻灯片上有两个例子,你说“耶!我已经解决问题了!”所以,让我们建立一个真正的系统,它会警告我们有坦克。他们建立了这个系统,并意识到它在实践中根本不起作用。在这个两类问题中,他们实际上有大约 50%的识别率。这意味着这是*似随机猜测。那么,可能出了什么问题呢?如果你看这些照片,你会发现所有的森林照片基本上都是在阳光明媚的好天气拍摄的。当然,你会看到坦克是在阴天拍摄的。你知道天气条件不太好。当然,当你看到坦克时,他们会开火,周围有手榴弹,当然,这意味着会有烟雾和其他事情发生。

“ED 209 目前是为城市和*而设计的。但这仅仅是开始。在底特律老城成功服役后,我们可以预计 ED 209 将成为未来十年的热门军用产品。”使用 gifify 创建的图像。来源: YouTube (工作不安全!).

所以,系统本质上学习的不是识别坦克,而是走了捷径。在这里,捷径是你尝试检测天气。因此,如果你有一个蓝天,良好的天气条件,图像中的噪声很少,那么它可能是一个非坦克图像。如果你有噪音和糟糕的照明条件,那么它可能是一个坦克图像。显然,这种分类系统对于检测坦克的任务来说,一点帮助都没有。因此,我们可以总结为网络简单地学习了数据具有相关的特征。这通常被称为混杂因素。它没有标明坦克的名称。因此,这里重要的教训是:这不是学习算法的错误,而是数据的错误。所以,当你出去收集数据时,你应该非常小心,确保你有未来应用的代表性数据。

两种疾病还是两个麦克风? CC 下的图片来自深度学习讲座的 4.0 。

我这里还有一个混杂因素的例子。你在这个图像中看到的是语音记录。这是一个维度标度。所以,我们在这里尝试做的是将不同的说话者映射到一个二维空间。我们将整个记录映射到一个点上。你应该看到的是 51 个点,每个人一个点。你可以看到我们有黑点和方块。现在,已经用麦克风 1 记录了正方形,用麦克风 2 记录了圆点。这些是完全相同的扬声器,甚至更糟:这些甚至是同时录制的实例,但使用了两个不同的麦克风。一个麦克风非常靠*发言者的嘴,另一个麦克风位于离发言者大约 2.5 米远的摄像机上。在这里,您可以看到麦克风特性是一个明显的混淆因素,您可以非常容易地将两组扬声器区分开来,尽管从麦克风来看,它们是完全相同的扬声器。

“麦克纳马拉博士”——“我们需要一个逮捕对象。”——“金内先生。”——“是的,先生!”——“请你去帮我们一下好吗?”“是的,先生!”使用 gifify 创建的图像。来源: YouTube (工作不安全!).

现在,想象你做一些类似的事情来检测病理。你用一个话筒收集所有有病变的扬声器,用另一个话筒收集所有无病变的扬声器。那么很可能你的系统会学习识别不同的麦克风,而不是病理。当然,这不仅仅是麦克风的情况。考虑使用两种不同的扫描仪来创建医学图像,如扫描组织病理学。你有不同类型的病理,你用不同的扫描仪扫描每一种类型。也许他们只是位于两个不同的医院,因为患有疾病 A 的患者去医院 A,而患有疾病 B 的患者去医院 B。然后,这里有一个巨大的混杂因素,因为所有患有疾病 A 的患者都已被扫描仪 A 扫描过,而所有对照组或患有疾病 B 的患者都已被扫描仪 B 扫描过。因此,同样有可能的是,您将学会区分扫描仪,例如通过识别特征噪声模式而不是识别疾病。

“金内先生将帮助我们模拟一个典型的逮捕和解除武装程序。金内先生,用你的枪威胁我。”使用 gifify 创建的图像。来源: YouTube (工作不安全!).

相机也是如此。您甚至可以证明,在图像取证中,如果您使用同一台数码相机拍摄图像,那么仅通过像素中的特定噪声模式,您就可以识别特定的相机。这些当然是局部的东西,很容易被深度神经网络提取出来。特别是在早期层,所以收集数据时要非常小心。你需要从多个不同的地点收集数据,确保你有代表性的数据。想象一下,你为新冠肺炎训练一个分类器,新冠肺炎患者的所有扫描都来自一个特定的区域,所有阳性样本都是用一组 3-4 个扫描仪采集的。然后你将其与非新冠肺炎患者进行比较,如果他们是在不同的扫描仪甚至不同的网站上获得的,你可能非常非常容易地引入对这些扫描仪的识别,而不是对疾病的识别。

正规化也可以解决混杂因素。来自深度学习讲座CC BY 4.0 下的图片。

所以要非常小心,看看数据,试着理解是否有混杂因素的风险。当然,尽量省略。我们已经提出了一种技术来对抗混杂因素,这就是我们在[15]中所做的。在这里,想法是你积极地包括关于混杂因素的信息,并试图抑制它,在这里,为了视觉化。然后,你可以证明你确实可以消除麦克风等引入的偏置。因此,你必须意识到混淆因素,可能是传感器、照明条件、年龄、参与者的性别、温度——是的,甚至温度也可能对感觉机制产生影响。

“指向 ED 209。”“是的,先生!”使用 gifify 创建的图像。来源: YouTube (工作不安全!).

所以要小心。所有这些情况都可能是混杂的,如果数据中有混杂因素,你必须对它们进行补偿,或者在数据收集中尽量避免它们。所以,请注意这些问题,它们很可能会破坏你的整个分类系统。不仔细看数据,永远搞不清问题出在哪里。

对立的例子对于人眼是不可见的,但是可能影响机器系统的分类。 CC 下的图片来自深度学习讲座的 4.0 。

你在机器学习和深度学习系统中遇到的另一个大问题是对立例子的问题。然后,你有不直观的行为。我们在这里给你看两张图片。对于左边的图像,我们的神经网络以 57%的置信度认为这是一只熊猫。在右边这张我们看起来几乎一样的图片上,有 99.3%的把握这是一只长臂猿。这怎么可能是真的呢?这两个输入看起来几乎一样。

对抗性攻击产生专门设计的噪声模式来欺骗分类器。图片来源: arXiv

右图显示有人攻击了神经网络。他们在图像上引入了一种噪声模式,在每个颜色通道中只有一两个灰度值,但这种噪声模式是用深度神经网络的知识构建的。他们所做的基本上是通过引入类似随机的输入来最大限度地增加给定类别的输出。实际上,如果你了解整个网络,你可以设计这种额外的噪声模式,使错误类别的激励最大化。对于人类来说,这是绝对不可识别的。

对抗性攻击也可以使病变在医学图像中消失。来源:模式识别实验室

其工作方式是,它在每个像素的小输入的不同层上累加,但在不同层上*均并累加。它允许我们引入一个小偏移,然后各层上的小偏移可以增加,从而实际上迫使网络做出错误的决策。所以,你可以说这个对立的例子是网络中的一种缺陷。当然,我们希望防止这种敌对的例子。实际上,我们会看到这是不可能的,因为它们是通过优化创建的。你总是会以对立的例子结束。

视错觉愚弄了人类的认知。 CC 下的图片来自深度学习讲座的 4.0 。

那么,为什么会这样呢?我们可以说,对立的例子有点像视错觉。同样,人类的感知也不是完美无缺的。在左手边,你可以看到埃舍尔的瀑布。如果你沿着这个结构走,你会看到瀑布在滋养这个结构本身,它本质上是一个无限循环。在这里,视错觉是,如果我们观察单个部分,我们会发现它们是一致的,但当然,整个图像并不一致。尽管如此,我们看着这些零件,发现它们似乎是可信的。一个稍微好一点的对立例子可能是右边的图像。这实际上是尼普顿在意大利的洞穴。人们称这些石头形成的影子为“风琴演奏者”。如果你仔细看这个影子,它看起来像是有一个人坐在那里,像一个管风琴演奏者一样演奏着石头。因此,人类也存在视错觉,而对立的例子在深层神经网络中本质上是等价的。

攻击人脸识别系统的一个例子。 CC 下的图片来自深度学习讲座的 4.0 。

与视错觉相反,我们可以构建这些对立的例子。我已经暗示过了。它们会导致特定的错误,这是另一个例子。这是对你在[19]中发现的最先进的人脸识别技术的攻击。他们所做的是定义了一组像素,本质上是眼镜的形状。这些眼镜现在可以调整了。因此,他们可以分配任意的颜色值,他们选择颜色值的方式会导致错误的识别。你可以展示一下瑞茜·威瑟斯彭的照片,加上这些神奇的眼镜,你会发现它们真的是五颜六色。因此,他们创造了大量的输入,他们特别加强激活,然后导致错误的分类。戴上这副特殊的眼镜,你可以看到瑞茜·威瑟斯彭现在成功地伪装成了拉塞尔·克罗。你可能会说“哇,这完全是胡说八道,这不可能!我还能看到瑞茜·威瑟斯彭!”嗯,是的。你仍然可以看到瑞茜·威瑟斯彭,因为人类的感知系统与这个为身份识别而训练的神经网络的工作方式不同。甚至还有建立在此基础上的作品。他们实际上打印了这些奇特的眼镜,他们还展示了基于摄像头的个人识别系统可以被欺骗来进行这种奇怪的攻击。

烤面包机贴纸。 CC 下的图片来自深度学习讲座的 4.0 。

不止如此。这就是所谓的“烤面包机贴纸”。烤面包机贴纸通常用于误导在 ImageNet 上训练的网络。因此,它的设计是为了导致向“烤面包机”类别的分类。现在,如果你打印这个烤面包机贴纸,在这里,你可以看到,这是一个奇特的彩色图像。你只要把它放到场景中,烤面包机贴纸就会引起“烤面包机”这个类别的分类。它不仅仅在一个特定的架构上工作。他们实际上可以证明它可以在多种架构上工作。这个烤面包机贴纸不仅能骗过一个网络,还能骗过几个在 ImageNet 上接受过训练的网络。因此,在顶部的图像中,您可以看到网络工作正常。它对香蕉进行分类。你加上烤面包机贴纸,它就把烤面包机分类了。有趣的是,报纸甚至有一个附件,你可以下载烤面包机贴纸,自己打印出来,在你自己的 ImageNet 网络上试用。

“请放下你的武器。你有 20 秒的时间来服从。”使用 gifify 创建的图像。来源: YouTube (工作不安全!).

在这个深度学习讲座中,更多令人兴奋的事情即将到来。 CC 下的图片来自深度学习讲座的 4.0 。

好了,这基本上是动机的总结。我们看到有时在深度神经网络中会发生奇怪的事情。我们想知道它们为什么会发生,问题是什么。这可以通过可视化技术来实现。你想识别混杂因素,你想解释为什么我们的网络有效,或者为什么无效,你想增加预测的可信度。

所以下一次,我们将研究不同的可视化技术。我们将从更简单的开始,然后是基于优化和基于梯度的技术。在下一个视频中,我们将只研究基于激活的技术。非常感谢大家的收听,下期视频再见。拜拜。

“我认为你最好照他说的做,金内先生!”使用 gifify 创建的图像。来源: YouTube (工作不安全!).

如果你喜欢这篇文章,你可以在这里找到更多的文章,在这里找到更多关于机器学习的教育材料,或者看看我们的深度 学习 讲座。如果你想在未来了解更多的文章、视频和研究,我也会很感激关注 YouTube、Twitter、脸书、LinkedIn 或 T21。本文以 Creative Commons 4.0 归属许可发布,如果引用,可以转载和修改。如果你有兴趣从视频讲座中生成文字记录,试试自动博客

“我很失望,迪克。”-“我确定这只是个小故障。”使用 gifify 创建的图像。来源: YouTube (工作不安全!).

链接

约辛斯基等人:深度可视化工具箱
奥拉等人:特征可视化
亚当哈雷:MNIST 演示

参考

[1] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio. “Neural Machine Translation by Jointly Learning to Align and Translate”. In: 3rd International Conference on Learning Representations, ICLR 2015, San Diego, 2015.
[2] T. B. Brown, D. Mané, A. Roy, et al. “Adversarial Patch”. In: ArXiv e-prints (Dec. 2017). arXiv: 1712.09665 [cs.CV].
[3] Jianpeng Cheng, Li Dong, and Mirella Lapata. “Long Short-Term Memory-Networks for Machine Reading”. In: CoRR abs/1601.06733 (2016). arXiv: 1601.06733.
[4] Jacob Devlin, Ming-Wei Chang, Kenton Lee, et al. “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding”. In: CoRR abs/1810.04805 (2018). arXiv: 1810.04805.
[5] Neil Frazer. Neural Network Follies. 1998. URL: https://neil.fraser.name/writing/tank/ (visited on 01/07/2018).
[6] Ross B. Girshick, Jeff Donahue, Trevor Darrell, et al. “Rich feature hierarchies for accurate object detection and semantic segmentation”. In: CoRR abs/1311.2524 (2013). arXiv: 1311.2524.
[7] Alex Graves, Greg Wayne, and Ivo Danihelka. “Neural Turing Machines”. In: CoRR abs/1410.5401 (2014). arXiv: 1410.5401.
[8] Karol Gregor, Ivo Danihelka, Alex Graves, et al. “DRAW: A Recurrent Neural Network For Image Generation”. In: Proceedings of the 32nd International Conference on Machine Learning. Vol. 37. Proceedings of Machine Learning Research. Lille, France: PMLR, July 2015, pp. 1462–1471.
[9] Nal Kalchbrenner, Lasse Espeholt, Karen Simonyan, et al. “Neural Machine Translation in Linear Time”. In: CoRR abs/1610.10099 (2016). arXiv: 1610.10099.
[10] L. N. Kanal and N. C. Randall. “Recognition System Design by Statistical Analysis”. In: Proceedings of the 1964 19th ACM National Conference. ACM ’64. New York, NY, USA: ACM, 1964, pp. 42.501–42.5020.
[11] Andrej Karpathy. t-SNE visualization of CNN codes. URL: http://cs.stanford.edu/people/karpathy/cnnembed/ (visited on 01/07/2018).
[12] Alex Krizhevsky, Ilya Sutskever, and Geoffrey E Hinton. “ImageNet Classification with Deep Convolutional Neural Networks”. In: Advances In Neural Information Processing Systems 25. Curran Associates, Inc., 2012, pp. 1097–1105. arXiv: 1102.0183.
[13] Thang Luong, Hieu Pham, and Christopher D. Manning. “Effective Approaches to Attention-based Neural Machine Translation”. In: Proceedings of the 2015 Conference on Empirical Methods in Natural Language Lisbon, Portugal: Association for Computational Linguistics, Sept. 2015, pp. 1412–1421.
[14] A. Mahendran and A. Vedaldi. “Understanding deep image representations by inverting them”. In: 2015 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). June 2015, pp. 5188–5196.
[15] Andreas Maier, Stefan Wenhardt, Tino Haderlein, et al. “A Microphone-independent Visualization Technique for Speech Disorders”. In: Proceedings of the 10th Annual Conference of the International Speech Communication Brighton, England, 2009, pp. 951–954.
[16] Volodymyr Mnih, Nicolas Heess, Alex Graves, et al. “Recurrent Models of Visual Attention”. In: CoRR abs/1406.6247 (2014). arXiv: 1406.6247.
[17] Chris Olah, Alexander Mordvintsev, and Ludwig Schubert. “Feature Visualization”. In: Distill (2017). https://distill.pub/2017/feature-visualization.
[18] Prajit Ramachandran, Niki Parmar, Ashish Vaswani, et al. “Stand-Alone Self-Attention in Vision Models”. In: arXiv e-prints, arXiv:1906.05909 (June 2019), arXiv:1906.05909. arXiv: 1906.05909 [cs.CV].
[19] Mahmood Sharif, Sruti Bhagavatula, Lujo Bauer, et al. “Accessorize to a Crime: Real and Stealthy Attacks on State-of-the-Art Face Recognition”. In: Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications CCS ’16. Vienna, Austria: ACM, 2016, pp. 1528–1540. A.
[20] K. Simonyan, A. Vedaldi, and A. Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”. In: International Conference on Learning Representations (ICLR) (workshop track). 2014.
[21] J.T. Springenberg, A. Dosovitskiy, T. Brox, et al. “Striving for Simplicity: The All Convolutional Net”. In: International Conference on Learning Representations (ICRL) (workshop track). 2015.
[22] Dmitry Ulyanov, Andrea Vedaldi, and Victor S. Lempitsky. “Deep Image Prior”. In: CoRR abs/1711.10925 (2017). arXiv: 1711.10925.
[23] Ashish Vaswani, Noam Shazeer, Niki Parmar, et al. “Attention Is All You Need”. In: CoRR abs/1706.03762 (2017). arXiv: 1706.03762.
[24] Kelvin Xu, Jimmy Ba, Ryan Kiros, et al. “Show, Attend and Tell: Neural Image Caption Generation with Visual Attention”. In: CoRR abs/1502.03044 (2015). arXiv: 1502.03044.
[25] Jason Yosinski, Jeff Clune, Anh Mai Nguyen, et al. “Understanding Neural Networks Through Deep Visualization”. In: CoRR abs/1506.06579 (2015). arXiv: 1506.06579.
[26] Matthew D. Zeiler and Rob Fergus. “Visualizing and Understanding Convolutional Networks”. In: Computer Vision — ECCV 2014: 13th European Conference, Zurich, Switzerland, Cham: Springer International Publishing, 2014, pp. 818–833.
[27] Han Zhang, Ian Goodfellow, Dimitris Metaxas, et al. “Self-Attention Generative Adversarial Networks”. In: Proceedings of the 36th International Conference on Machine Learning. Vol. 97. Proceedings of Machine Learning Research. Long Beach, California, USA: PMLR, Sept. 2019, pp. 7354–7363. A.

视觉化和注意力——第三部分

原文:https://towardsdatascience.com/visualization-attention-part-3-84a43958e48b?source=collection_archive---------48-----------------------

FAU 讲座笔记关于深度学习

直接可视化方法

FAU 大学的深度学习。下图 CC BY 4.0 来自深度学习讲座

这些是 FAU 的 YouTube 讲座 深度学习 的讲义。这是与幻灯片匹配的讲座视频&的完整抄本。我们希望,你喜欢这个视频一样多。当然,这份抄本是用深度学习技术在很大程度上自动创建的,只进行了少量的手动修改。 自己试试吧!如果您发现错误,请告诉我们!

航行

上一讲 / 观看本视频 / 顶级 / 下一讲

欢迎回到深度学习!所以,今天我想谈谈实际的可视化技术,它可以让你理解深层神经网络内部发生的事情。

让我们弄清楚深层网络内部发生了什么!使用 gifify 创建的图像。来源: YouTube

好吧。所以,让我们试着弄清楚网络内部发生了什么。我们将从简单的参数可视化开始。这基本上是最简单的技术。我们已经在之前的视频中处理过了。

可视化学习参数的一个简单技术是查看训练过的内核。 CC 下的图片来自深度学习讲座的 4.0 。

因此,我们的想法是,您可以直接绘制已学习的滤波器权重。很容易实现。对于第一层也很容易解读。在这里,你可以看到 AlexNet 中第一层过滤器的一些例子。如果你看到非常嘈杂的第一层,那么你可能已经猜到有问题了。例如,您正在获取特定传感器的噪声特性。除此之外,它基本上没什么意思,因为你可以看到它们是 edge 和 Gabor 滤波器的形状,但它不会告诉你网络的后面部分到底发生了什么。如果你有小内核,那么你大概还能解读它们。但是如果你更深入,你将不得不理解在第一层已经发生了什么。因此,它们以某种方式叠加在一起,你无法理解在更深的层次里到底发生了什么。

“你有许多问题,尽管这个过程已经改变了你的意识,你仍然是不可改变的人类。所以,我的回答有些你会懂,有些你不会。”使用 gifify 创建的图像。来源: YouTube

所以,我们需要一些不同的想法。一个想法是我们想象激活。内核很难解释。因此,我们观察由内核产生的激活,因为它们告诉我们网络从特定的输入计算什么。如果您有强烈的反应,这可能意味着该功能是存在的。如果您的响应较弱,则该功能可能不存在。

高激活表明神经元和输入之间有很强的一致性。 CC 下的图片来自深度学习讲座的 4.0 。

那么,这看起来怎么样?对于第一层,你可以看到激活看起来像正常的滤波器响应。这是输入,然后对零进行滤波,对于一,可以看到它们以某种方式对输入进行了滤波。当然,你可以继续下去,看看更深层次的激活。然后,您已经意识到查看激活可能有些有趣,但是由于下采样,激活图通常会很快失去分辨率。所以,这意味着你会得到非常粗糙的激活图。

更深的激活图通常只有有限的分辨率。 CC 下的图片来自深度学习讲座的 4.0 。

所以在这里,你看到一个可视化,可能对应于面部检测或面部特征。然后,我们可以开始推测这种特征在深层网络内部实际上代表了什么。我在[25]中有一个深度可视化工具箱,可以在网上找到。它允许你计算类似的东西。当然,缺点是,我们不能获得精确的信息,为什么特定的神经元被激活,或者为什么这个特征图是这个形状。

“一致地说,虽然你的第一个问题可能是最相关的,但你可能意识不到它也是最不相关的。”使用 gifify 创建的图像。来源: YouTube

那我们还能做什么?我们可以通过遮挡来研究特征。这里的想法是你在输入图像周围移动一个蒙版。有了这个补丁,你就可以从图像中移除信息。然后,你试着想象一个特定决定的可信度,关于这个遮挡片的不同位置。

补丁闭塞是受生物神经网络中的病变研究的启发。 CC 下的图片来自深度学习讲座的 4.0 。

然后,当然,补丁导致置信度大幅下降的区域可能是与特定分类相关的区域。我们这里有一些例子。我们用这个补丁来屏蔽左边的原始输入。两种不同版本的遮罩位于中间和右侧。然后,您可以看到数字 3 的置信度降低在中间图像中比在右侧图像中大得多。因此,我们可以尝试使用这种技术来识别混淆或错误的焦点。

遮挡揭示了图像的哪些部分与分类相关。 CC 下的图片来自深度学习讲座的 4.0 。

让我们再看一些例子。在这里,你可以看到左上角的博美犬图片。图像的重要部分确实位于中心。如果你开始封闭中心,博美犬的自信心也会下降。在中间一栏,你看到真正的标签汽车车轮和记录的图像。在底部,你可以看到如果你把车轮藏起来,当然,信心会下降。但是如果你开始隐藏汽车上的部分广告,信心也会下降。所以,这是一种可能是后天习得的混杂因素。车轮可以与图像的其他部分紧密搭配,甚至包括广告。在右边,你可以看到真正的阿富汗猎犬。如果你开始封闭狗,当然,信心实际上崩溃了。例如,左上方的人完全不相关。但是遮住主人或貌似主人的脸也会降低自信。所以你可能会说狗主人开始变得和他们的狗相似。不,这也是一个混杂因素!

“我为什么会在这里?”——“你的生命是矩阵程序固有的不*衡方程的余数之和。你是一个异常现象的最终结果,尽管我尽了最大的努力,我还是无法从一个数学精度的和谐中消除它。”使用 gifify 创建的图像。来源: YouTube

好吧,让我们来看看第三种技术。这里,我们想要找到特定层或神经元的最大激活。这里的想法是,我们只看已经展示给网络的小块,我们通过特定神经元的激活对它们进行排序。

最大程度地激活面片可以找到某个层或神经元“喜欢”的图像部分。 CC 下的图片来自深度学习讲座的 4.0 。

你可以生成这样的序列。所以,你可以看到这个特定的神经元被激活了 0.1,0.9,0.9,0.8,0.8,你可以看到这些是最大程度激活这个神经元的小块。所以,你可以争辩说:“嗯,这是一个上帝脸探测器,还是一个黑暗运动探测器。”

最大化激活补丁可能仍然难以解释。来自深度学习讲座CC BY 4.0 下的图片。

所以,你很容易就能发现什么是“假朋友”。这相对容易找到,但是缺点当然是你不一定能得到语义上的意思。你可能会说这些形式是表征的基本载体。这里,我们有另一个例子,你可以说“嗯,什么样的检测器?这是一个红花番茄酱探测器。或者这是一个镜面高光的探测器?”好吧,至少你能搞清楚哪个神经元和什么样的输入有关。所以,你可以感觉到网络中正在发生什么,以及哪些东西聚集在一起。

“虽然这仍然是一个竭力避免的负担,但这并不出乎意料,而且这并没有超出控制措施的范围,这种控制措施无情地将你带到了这里。”“你还没有回答我的问题。”——“非常正确。有意思。”使用 gifify 创建的图像。来源: YouTube

说到聚类:那么你实际上也可以使用输入的聚类来可视化一个特定深度网络的不同输入是多么相似。这导致了 T 随机邻域嵌入可视化技术。

t-SNE 为特定网络创建输入图像的地图。来自深度学习讲座的 4.0CC 下的图片。

现在,这里的想法是,您计算最后一层的激活,并根据它们在最后一层激活中的相似性对输入进行分组。因此,你基本上执行最后一层激活的维度。这些是与分类相关的要素,可能会对训练好的网络的要素表示进行编码。然后,你实际上执行这个降维技术,并产生一个 2-D 图。

探索 SNE 霸王龙的地图。使用 gifify 创建的图像。来源: YouTube

这允许您查看您的网络认为哪些是相似的输入。所以,这当然是在二维空间中嵌入了一个非常高维的空间。当然,有很多信息损失。如果你这样做了,这个技巧还是很有趣的。如果我在这里放大不同的部分,你可以看到我们实际上在这种维度减少中形成了不同类别的集群。所以,你可以看到被神经网络相似感知的图像也位于直接邻域内。我们所做的降维揭示了内部表征。实际上,如果你看看那些街区,它们有点道理。因此,这实际上有助于我们理解和培养对我们深度神经网络正在进行的特征提取的信心。

"母体比你知道的还要古老."—“在 80 年代,我考虑如何建造这台机器,学会解决所有这些问题。”——“只有两种可能的解释:要么没人告诉我,要么没人知道。”“正是如此。”使用 gifify 创建的图像。来源: YouTube

到目前为止,没有一种技术是真正令人满意的。所以,下次在深度学习中,我们要讲更多的可视化方法。特别是,我们希望研究基于梯度的程序。所以,我们想用一种反向传播的方法来创造视觉效果。其他有趣的方法是基于优化的技术。在这里,我们实际上非常接*我们已经在对立的例子中看到的。非常感谢大家的收听,下期视频再见。拜拜。

在这个深度学习讲座中,更多令人兴奋的事情即将到来。 CC 下的图片来自深度学习讲座的 4.0 。

如果你喜欢这篇文章,你可以在这里找到更多的文章,或者看看我们的讲座。如果你想在未来了解更多的文章、视频和研究,我也会很感激关注 YouTubeTwitter脸书LinkedIn 。本文以 Creative Commons 4.0 归属许可发布,如果引用,可以转载和修改。如果你有兴趣从视频讲座中获得文字记录,试试自动博客

“扯淡!”—“否认是所有人类反应中最容易预测的。但请放心,这将是我们第六次销毁它,我们在这方面已经变得非常高效。”——“在那种情况下,除了人会死的事实之外,没有邪恶的概念。”使用 gifify 创建的图像。来源: YouTube

链接

约辛斯基等人:深度可视化工具箱
奥拉等人:特征可视化
亚当哈雷:MNIST 演示

参考

[1] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio. “Neural Machine Translation by Jointly Learning to Align and Translate”. In: 3rd International Conference on Learning Representations, ICLR 2015, San Diego, 2015.
[2] T. B. Brown, D. Mané, A. Roy, et al. “Adversarial Patch”. In: ArXiv e-prints (Dec. 2017). arXiv: 1712.09665 [cs.CV].
[3] Jianpeng Cheng, Li Dong, and Mirella Lapata. “Long Short-Term Memory-Networks for Machine Reading”. In: CoRR abs/1601.06733 (2016). arXiv: 1601.06733.
[4] Jacob Devlin, Ming-Wei Chang, Kenton Lee, et al. “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding”. In: CoRR abs/1810.04805 (2018). arXiv: 1810.04805.
[5] Neil Frazer. Neural Network Follies. 1998. URL: https://neil.fraser.name/writing/tank/ (visited on 01/07/2018).
[6] Ross B. Girshick, Jeff Donahue, Trevor Darrell, et al. “Rich feature hierarchies for accurate object detection and semantic segmentation”. In: CoRR abs/1311.2524 (2013). arXiv: 1311.2524.
[7] Alex Graves, Greg Wayne, and Ivo Danihelka. “Neural Turing Machines”. In: CoRR abs/1410.5401 (2014). arXiv: 1410.5401.
[8] Karol Gregor, Ivo Danihelka, Alex Graves, et al. “DRAW: A Recurrent Neural Network For Image Generation”. In: Proceedings of the 32nd International Conference on Machine Learning. Vol. 37. Proceedings of Machine Learning Research. Lille, France: PMLR, July 2015, pp. 1462–1471.
[9] Nal Kalchbrenner, Lasse Espeholt, Karen Simonyan, et al. “Neural Machine Translation in Linear Time”. In: CoRR abs/1610.10099 (2016). arXiv: 1610.10099.
[10] L. N. Kanal and N. C. Randall. “Recognition System Design by Statistical Analysis”. In: Proceedings of the 1964 19th ACM National Conference. ACM ’64. New York, NY, USA: ACM, 1964, pp. 42.501–42.5020.
[11] Andrej Karpathy. t-SNE visualization of CNN codes. URL: http://cs.stanford.edu/people/karpathy/cnnembed/ (visited on 01/07/2018).
[12] Alex Krizhevsky, Ilya Sutskever, and Geoffrey E Hinton. “ImageNet Classification with Deep Convolutional Neural Networks”. In: Advances In Neural Information Processing Systems 25. Curran Associates, Inc., 2012, pp. 1097–1105. arXiv: 1102.0183.
[13] Thang Luong, Hieu Pham, and Christopher D. Manning. “Effective Approaches to Attention-based Neural Machine Translation”. In: Proceedings of the 2015 Conference on Empirical Methods in Natural Language Lisbon, Portugal: Association for Computational Linguistics, Sept. 2015, pp. 1412–1421.
[14] A. Mahendran and A. Vedaldi. “Understanding deep image representations by inverting them”. In: 2015 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). June 2015, pp. 5188–5196.
[15] Andreas Maier, Stefan Wenhardt, Tino Haderlein, et al. “A Microphone-independent Visualization Technique for Speech Disorders”. In: Proceedings of the 10th Annual Conference of the International Speech Communication Brighton, England, 2009, pp. 951–954.
[16] Volodymyr Mnih, Nicolas Heess, Alex Graves, et al. “Recurrent Models of Visual Attention”. In: CoRR abs/1406.6247 (2014). arXiv: 1406.6247.
[17] Chris Olah, Alexander Mordvintsev, and Ludwig Schubert. “Feature Visualization”. In: Distill (2017). https://distill.pub/2017/feature-visualization.
[18] Prajit Ramachandran, Niki Parmar, Ashish Vaswani, et al. “Stand-Alone Self-Attention in Vision Models”. In: arXiv e-prints, arXiv:1906.05909 (June 2019), arXiv:1906.05909. arXiv: 1906.05909 [cs.CV].
[19] Mahmood Sharif, Sruti Bhagavatula, Lujo Bauer, et al. “Accessorize to a Crime: Real and Stealthy Attacks on State-of-the-Art Face Recognition”. In: Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications CCS ’16. Vienna, Austria: ACM, 2016, pp. 1528–1540. A.
[20] K. Simonyan, A. Vedaldi, and A. Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”. In: International Conference on Learning Representations (ICLR) (workshop track). 2014.
[21] J.T. Springenberg, A. Dosovitskiy, T. Brox, et al. “Striving for Simplicity: The All Convolutional Net”. In: International Conference on Learning Representations (ICRL) (workshop track). 2015.
[22] Dmitry Ulyanov, Andrea Vedaldi, and Victor S. Lempitsky. “Deep Image Prior”. In: CoRR abs/1711.10925 (2017). arXiv: 1711.10925.
[23] Ashish Vaswani, Noam Shazeer, Niki Parmar, et al. “Attention Is All You Need”. In: CoRR abs/1706.03762 (2017). arXiv: 1706.03762.
[24] Kelvin Xu, Jimmy Ba, Ryan Kiros, et al. “Show, Attend and Tell: Neural Image Caption Generation with Visual Attention”. In: CoRR abs/1502.03044 (2015). arXiv: 1502.03044.
[25] Jason Yosinski, Jeff Clune, Anh Mai Nguyen, et al. “Understanding Neural Networks Through Deep Visualization”. In: CoRR abs/1506.06579 (2015). arXiv: 1506.06579.
[26] Matthew D. Zeiler and Rob Fergus. “Visualizing and Understanding Convolutional Networks”. In: Computer Vision — ECCV 2014: 13th European Conference, Zurich, Switzerland, Cham: Springer International Publishing, 2014, pp. 818–833.
[27] Han Zhang, Ian Goodfellow, Dimitris Metaxas, et al. “Self-Attention Generative Adversarial Networks”. In: Proceedings of the 36th International Conference on Machine Learning. Vol. 97. Proceedings of Machine Learning Research. Long Beach, California, USA: PMLR, Sept. 2019, pp. 7354–7363. A.

视觉化和注意力——第四部分

原文:https://towardsdatascience.com/visualization-attention-part-4-a1cfefce8bd3?source=collection_archive---------46-----------------------

FAU 讲座笔记关于深度学习

基于梯度和优化的方法

FAU 大学的深度学习。下图 CC BY 4.0 来自深度学习讲座

这些是 FAU 的 YouTube 讲座 深度学习 的讲义。这是与幻灯片匹配的讲座视频&的完整抄本。我们希望,你喜欢这个视频一样多。当然,这份抄本是用深度学习技术在很大程度上自动创建的,只进行了少量的手动修改。 自己试试吧!如果您发现错误,请告诉我们!

航行

上一讲 / 观看本视频 / 顶级 / 下一讲

欢迎回到深度学习!今天,我们想深入了解可视化技术,特别是基于梯度和基于优化的过程。

“你想知道矩阵是什么。”使用 gifify 创建的图像。来源: YouTube

好吧,让我们看看我给你带来了什么。让我们先谈谈基于梯度的可视化,这里的想法是,我们想找出哪个输入像素对神经元最重要。

将类别“cat”反向传播到输入域。 CC 下的图片来自深度学习讲座的 4.0 。

如果我们要改变它,什么会导致我们的神经网络的实际输出的巨大变化?我们实际上想要计算的是所考虑的神经元的偏导数,可能是对于类“猫”的输出神经元。然后,我们要计算输入的偏导数。这实质上是通过整个网络的反向传播。然后,我们可以把这种渐变想象成一种图像,就像我们在这里对猫图像所做的那样。你可以看到,当然,这是一个颜色渐变。你可以看到,这是一个有点嘈杂的图像,但你可以看到,与类“猫”相关的东西,这里显然也位于图像中猫所在的区域。

一个神经元的输出可以作为“伪损耗”。来自深度学习讲座CC BY 4.0 下的图片。

我们将学习几种不同的方法来做到这一点。第一个是在[20]的基础上。对于反向传播,我们实际上需要丢失我们想要反向传播的内容。我们简单地取一个伪损失,它是任意神经元或层的激活。通常,您想要做的是在输出层获取神经元,因为它们可以与类相关联。

Deconvnet 是一种模拟通过网络的反向传递的网络。 CC 下的图片来自深度学习讲座的 4.0 。

你还可以做的是,不使用反向传播,你可以建立一个几乎等效的替代方案,使用一种反向网络。这是来自[26]的 Deconvnet。这里,输入是经过训练的网络和一些图像。然后,您选择一个激活,并将所有其他激活设置为零。接下来,您构建一个反向网络,您可以看到这里的想法,它基本上包含与网络相同的内容,只是顺序相反,有所谓的取消轮询步骤。现在,通过这些非 pooling 步骤和逆向计算,你可以看到我们也可以产生一种梯度估计。这个的好处是,不需要任何训练。因此,您只需记录交换机中的池位置和反向网络的正向路径。实际上,除了我们将在几张幻灯片中讨论的整流线性单元之外,这与网络的反向传递相同。

“这是构造。”使用 gifify 创建的图像。来源: YouTube

在这里,我们展示了前九个激活的可视化,梯度,以及相应的补丁。例如,你可以用这个来揭示这种特征地图似乎集中在绿色斑块区域。你可能会认为这更像是一种背景特征,试图检测图像中的草地。

来自 Deconvnet 的示例。来自深度学习讲座CC BY 4.0 下的图片。

那么,还有什么?嗯,有引导反向传播。导向反向传播是一个非常相似的概念。这里的想法是你想找到正相关的特征。所以我们寻找正梯度,因为我们假设正的特征是神经元感兴趣的特征。负梯度是神经元不感兴趣的梯度。

反向传播与解卷积和导向反向传播。 CC 下的图片来自深度学习讲座的 4.0 。

因此,想法是将反向传播中的所有负梯度设置为零。我们现在可以向您展示 ReLU 在使用不同种类的梯度反向传播技术向前和向后传递时的不同过程。当然,如果你有这些输入激活,那么在 ReLU 的正向传递中,你可以简单地消除所有的负值,并把它们设置为零。现在,对于三种不同的选择,反向传播会发生什么?让我们看看典型的反向传播是怎么做的,注意这里我们用黄色显示了来自敏感度的负条目。如果您现在尝试反向传播,您必须记住正向传递中的哪些条目是负的,并再次将这些值设置为零。为了做到这一点,你保留来自前一层的敏感性的一切。现在,如果您取消配置,您不需要记住前向传递的开关,但您可以将灵敏度为负的所有条目设置为零,然后反向传递。现在这样,导向反向传播实际上两者都做了。因此它记住了前向传递,并将所有这些元素设置为零。它将灵敏度的所有元素设置为零。因此,就消除负值而言,它本质上是反向传播和去卷积的结合。你可以看到引导反向传播在整个反向传播过程中只保持很小的灵敏度。

比较中的梯度估计。 CC 下的图片来自深度学习讲座的 4.0 。

现在让我们看看不同梯度的对比。你可以看到的一件事是,在 Deconvnet 中,我们得到了相当嘈杂的激活和反向传播。我们可以看到,我们至少专注于感兴趣的对象,引导反向传播具有非常稀疏的表示,但即使在这个梯度图像中,也可以非常清楚地看到最重要的特征,如猫的眼睛等。所以,这是一个非常好的方法,可以帮助你揭示哪些神经元在特定的输入中关注什么活动。

梯度的绝对值产生显著图。来自深度学习讲座CC BY 4.0 下的图片。

这最终导致显著图。在这里,你不想调查什么影响两个神经元,而是想调查像素对一个类“狗”的影响。现在,您将伪损失视为一项非标准化任务,计算图像像素的梯度,并使用绝对值。然后,我们对此进行了有趣的观察,它产生了一个显著图来定位图像中的狗,即使网络从未受过定位训练。因此,这是一种非常有趣的方法,可以帮助您识别决定性信息在图像中的实际位置。

"母体是一个系统,尼欧."使用 gifify 创建的图像。来源: YouTube

还能做什么?嗯,有基于优化的参数可视化。现在,我们的想法是要走向不同的层次。因此,如果我们想要针对神经元、激活图、层、实际逻辑或本质上是 softmax 函数的类概率进行优化,我们将它们视为伪损失,以便创建最佳输入。

我们可以自由选择要优化的网络部分。来自深度学习讲座CC BY 4.0 下的图片。

我们已经在第一个视频中看到了非常相似的东西,我们在 DeepDream 中看到了这个例子。概念主义本质上是在做一些非常相似的事情。它接受一些输入,然后改变输入,使得不同的神经元被最大限度地激活。

DeepDream 的《海军上将狗》等创作。 CC 下的图片来自深度学习讲座的 4.0 。

在那里你可以看到这些神经元以某种方式编码了它喜欢识别的动物或事物的特定部分。如果你现在最大化这个特定神经元的输入,你可以看到它喜欢的形状开始出现在这个图像中。所以,这个想法是,你改变输入,使神经元被最大限度地激活。因此,我们本质上不只是计算图像的梯度,而且我们还会根据特定图层、softmax 或输出主动更改图像。当然,最初的想法是可视化。

无概念主义允许向特定的神经元、层或类调整和想象。 CC 下的图片来自深度学习讲座的 4.0 。

所以,当呈现图像时,你试图通过做梦来理解网络的内部运作。你从图像甚至噪声作为输入开始。然后,调整图像,使整个图层的激活最大化。对于不同的图层,它会突出显示图像中不同的东西。所以,我们可以创造这种观念。如果您主要激活早期层,您会看到图像内容并没有太大的变化,但您在图像中创建了那些笔刷和笔触外观。

概念主义可以揭示神经元、层次和整个网络的亲缘关系。来自深度学习讲座CC BY 4.0 下的图片。

现在,你甚至可以开始随机输入。那么就不仅仅是针对特定的输出优化输入了。你需要一些额外的调整。我们可以用这个小公式来证明。所以,我们现在取一些输入 x ,这是一个随机的图像。我们把它输入我们的网络和一个特定的神经元或输出神经元。然后,我们最大化激活,并添加一个正则化。如果我们的 x 偏离了一个特定的规范,这个正则化器就会惩罚。这个例子中用到的,就是 L2 范数。稍后,我们还会看到,也许其他规范也可能适用于此。我们从右上角所示的噪声输入开始。然后,您进行优化,直到找到特定神经元或层的最大激活。同时,你假设你的输入图像必须*滑,否则,你会产生非常非常嘈杂的图像。它们不太适合解释,当然,右下方的图像向你展示了一些你知道可以解释的结构。所以,你看到这些抽象的特征出现了,然后你可以把它作为一种从小到大的级联,这就产生了所谓的无概念主义。

“哑铃”类的重构图像。 CC 下的图片来自深度学习讲座的 4.0 。

在这里,我们可以利用这一点,例如,揭示神经网络分类过程中隐藏的弱点。这里,我们看到了“哑铃”类的不同实现。你可以看到,它不仅仅是图像中显示的哑铃,它还再现了拿着哑铃的手臂。因此,我们在这里可以看到,当相关的事物被呈现给网络时,它们是被学习的。所以,我们可以算出,特定类别或神经元对输入的记忆是什么。所以,我们再次认识到好的数据非常重要。

给定某一层的激活,网络的输入可以被重构。来自深度学习讲座CC BY 4.0 下的图片。

这实际上引导我们到了另一步,我们可以做的是弄清楚神经网络内部发生了什么。这些是反转技术,这里的想法和我们在概念论中看到的非常相似。但是现在,我们实际上想从激活中得到实际的输入。例如,您经常听到的匿名数据的安全措施是:“让我们只激活第 5 层,并丢弃所有以前的激活和输入。我们只存储第 5 层激活,因为如果我只知道第 5 层激活,就没有办法重建原始图像。”

“你想告诉我什么?那我能躲过子弹吗?”-“不,尼奥”。使用 gifify 创建的图像。来源: YouTube

现在有了反演,如果你知道网络,它的过程,和特定层的特定激活,那么你可以尝试重建实际输入是什么。同样,我们在特定的层中有我们网络的输出。假设 f( x )是一层的输出,我们有 y hat。现在, y 这是被测网络的输出或被测层的激活。因此,我们激活了第 5 层,但我们不知道输入 x 是什么。因此,我们正在寻找 x ,并尝试最小化该函数,以便我们找到与该特定激活最匹配的 x

反演的不稳定性可以通过正则化来解决。来自深度学习讲座的 4.0CC 下的图片。

这是一个经典的反问题。为了获得更稳定的输出,您添加了一个额外的正则化器λ乘以 R( x )。这个正则项非常重要。因此,正则化使反演稳定,有非常常见的正则化技术,它们使用自然图像的特定属性来创建可能是自然图像的东西。当然,高频噪声会降低重建质量。这就是为什么我们使用这个额外的 L2 范数,以防止在创建的图像中出现噪声。除此之外,还可以用所谓的全变差。我们知道,自然图像通常具有稀疏的梯度,全变差是一种最小化技术,可以强制图像具有非常低的梯度。渐变本质上是边缘,在典型的图像中,只有几个边缘像素和许多更均匀的区域。因此,电视最小化产生的图像边缘很少,当然也有一点噪声。它还特别允许高分段常数跳跃,就像在真实边缘中一样。当然,您也可以使用低通滤波器和其他边缘保留滤波器。一个经典的方法是小波正则化。这很简单,也很有效,当然,它还会抑制真实边缘和其他高频信息。

转换的显式使用也可以支持正则化。 CC 下的图片来自深度学习讲座的 4.0 。

好吧,还能做什么?您也可以使用其他正则化,如变换鲁棒性。因此,输入实际上应该对特殊变换保持不变。这类似于数据扩充,因此,您可以随机旋转、缩放或抖动 x 。所以,这也很简单,而且在产生可识别的特征方面很有效。通常方向是被抑制的,即使它是信息性的。所以,我们必须小心谨慎。

正规化也是可以学习的。来自深度学习讲座CC BY 4.0 下的图片。

最后一种非常常见的正则化是你已经知道了先验知识。例如,你可以使用一个训练网络,说“我想在第 4 层有一个特定的分布。”然后,我试图生成具有非常相似特征的图像。这里,不是相对于我们知道有用的特定规范进行优化,而是假设在特定层中产生的表示对于测量图像的内容是有用的。然后,你实际上可以用它作为一种正则化来产生图像。所以当然,如果你想使用这样的东西,你需要一个训练有素的生成模型。这产生了非常好的图像,但它可能是模糊的,因为你引入结果的部分来自预先训练的网络。所以,你必须小心看待这个问题。

“我想告诉你,当你准备好的时候,你就不需要这么做了。”使用 gifify 创建的图像。来源: YouTube

所以,让我们看一些例子[14]实际上是通过反演生成的图像。这真是令人印象深刻。同样,这是一个 AlexNet 类型的网络,这里有输入,然后是反演:

不同层的输入和反演结果。 CC 下的图片来自深度学习讲座的 4.0 。

在 conv 第一层,你可以看到我们几乎可以准确地复制图像。ReLu 1 之后变化不大。合用——没有大的影响。然后,第二层,以此类推。可以看到,直到卷积层#4,我们非常接*真实输入。这已经经历了几个合并的步骤,但是我们仍然能够非常接*原始输入地再现输入。很有意思!然后,你会看到,我真的不得不走向第 6 层或第 7 层,直到我无法或几乎无法猜测原始输入是什么。因此,只有从第 6 层/第 7 层开始,我们才开始显著偏离原始输入。直到第 5 层,我们仍然可以很好地重建原始输入是什么。因此,如果有人告诉你,他们想通过删除前两层来匿名化数据,那么你会发现,利用这些反演技术,这可能不是一个好主意。仅仅通过查看激活和网络结构,你就有可能重建原始输入。

在这个深度学习讲座中,更多令人兴奋的事情即将到来。 CC 下的图片来自深度学习讲座的 4.0 。

好吧。所以下一次,我们想谈谈第二个话题,这个话题和可视化有点关系。我们想谈谈注意力和注意力机制。您已经看到,通过可视化技术,我们可以以某种方式找出哪些像素与哪种分类相关。现在,我们想进一步发展这一点,并利用这一点将网络的注意力引向特定的领域。所以,这也将是一个非常有趣的视频。期待在下一个视频中见到你。拜拜。

先进的可视化技术可以帮助你避开子弹。然而,你仍然不能完全掌握网络内部发生了什么。使用 gifify 创建的图像。来源: YouTube

如果你喜欢这篇文章,你可以在这里找到更多的文章,或者看看我们的讲座。如果你想在未来了解更多的文章、视频和研究,我也会很感激关注 YouTubeTwitter脸书LinkedIn 。本文以 Creative Commons 4.0 归属许可发布,如果引用,可以转载和修改。如果你有兴趣从视频讲座中获得文字记录,试试自动博客

链接

约辛斯基等人:深度可视化工具箱
奥拉等人:特征可视化
亚当哈雷:MNIST 演示

参考

[1] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio. “Neural Machine Translation by Jointly Learning to Align and Translate”. In: 3rd International Conference on Learning Representations, ICLR 2015, San Diego, 2015.
[2] T. B. Brown, D. Mané, A. Roy, et al. “Adversarial Patch”. In: ArXiv e-prints (Dec. 2017). arXiv: 1712.09665 [cs.CV].
[3] Jianpeng Cheng, Li Dong, and Mirella Lapata. “Long Short-Term Memory-Networks for Machine Reading”. In: CoRR abs/1601.06733 (2016). arXiv: 1601.06733.
[4] Jacob Devlin, Ming-Wei Chang, Kenton Lee, et al. “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding”. In: CoRR abs/1810.04805 (2018). arXiv: 1810.04805.
[5] Neil Frazer. Neural Network Follies. 1998. URL: https://neil.fraser.name/writing/tank/ (visited on 01/07/2018).
[6] Ross B. Girshick, Jeff Donahue, Trevor Darrell, et al. “Rich feature hierarchies for accurate object detection and semantic segmentation”. In: CoRR abs/1311.2524 (2013). arXiv: 1311.2524.
[7] Alex Graves, Greg Wayne, and Ivo Danihelka. “Neural Turing Machines”. In: CoRR abs/1410.5401 (2014). arXiv: 1410.5401.
[8] Karol Gregor, Ivo Danihelka, Alex Graves, et al. “DRAW: A Recurrent Neural Network For Image Generation”. In: Proceedings of the 32nd International Conference on Machine Learning. Vol. 37. Proceedings of Machine Learning Research. Lille, France: PMLR, July 2015, pp. 1462–1471.
[9] Nal Kalchbrenner, Lasse Espeholt, Karen Simonyan, et al. “Neural Machine Translation in Linear Time”. In: CoRR abs/1610.10099 (2016). arXiv: 1610.10099.
[10] L. N. Kanal and N. C. Randall. “Recognition System Design by Statistical Analysis”. In: Proceedings of the 1964 19th ACM National Conference. ACM ’64. New York, NY, USA: ACM, 1964, pp. 42.501–42.5020.
[11] Andrej Karpathy. t-SNE visualization of CNN codes. URL: http://cs.stanford.edu/people/karpathy/cnnembed/ (visited on 01/07/2018).
[12] Alex Krizhevsky, Ilya Sutskever, and Geoffrey E Hinton. “ImageNet Classification with Deep Convolutional Neural Networks”. In: Advances In Neural Information Processing Systems 25. Curran Associates, Inc., 2012, pp. 1097–1105. arXiv: 1102.0183.
[13] Thang Luong, Hieu Pham, and Christopher D. Manning. “Effective Approaches to Attention-based Neural Machine Translation”. In: Proceedings of the 2015 Conference on Empirical Methods in Natural Language Lisbon, Portugal: Association for Computational Linguistics, Sept. 2015, pp. 1412–1421.
[14] A. Mahendran and A. Vedaldi. “Understanding deep image representations by inverting them”. In: 2015 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). June 2015, pp. 5188–5196.
[15] Andreas Maier, Stefan Wenhardt, Tino Haderlein, et al. “A Microphone-independent Visualization Technique for Speech Disorders”. In: Proceedings of the 10th Annual Conference of the International Speech Communication Brighton, England, 2009, pp. 951–954.
[16] Volodymyr Mnih, Nicolas Heess, Alex Graves, et al. “Recurrent Models of Visual Attention”. In: CoRR abs/1406.6247 (2014). arXiv: 1406.6247.
[17] Chris Olah, Alexander Mordvintsev, and Ludwig Schubert. “Feature Visualization”. In: Distill (2017). https://distill.pub/2017/feature-visualization.
[18] Prajit Ramachandran, Niki Parmar, Ashish Vaswani, et al. “Stand-Alone Self-Attention in Vision Models”. In: arXiv e-prints, arXiv:1906.05909 (June 2019), arXiv:1906.05909. arXiv: 1906.05909 [cs.CV].
[19] Mahmood Sharif, Sruti Bhagavatula, Lujo Bauer, et al. “Accessorize to a Crime: Real and Stealthy Attacks on State-of-the-Art Face Recognition”. In: Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications CCS ’16. Vienna, Austria: ACM, 2016, pp. 1528–1540. A.
[20] K. Simonyan, A. Vedaldi, and A. Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”. In: International Conference on Learning Representations (ICLR) (workshop track). 2014.
[21] J.T. Springenberg, A. Dosovitskiy, T. Brox, et al. “Striving for Simplicity: The All Convolutional Net”. In: International Conference on Learning Representations (ICRL) (workshop track). 2015.
[22] Dmitry Ulyanov, Andrea Vedaldi, and Victor S. Lempitsky. “Deep Image Prior”. In: CoRR abs/1711.10925 (2017). arXiv: 1711.10925.
[23] Ashish Vaswani, Noam Shazeer, Niki Parmar, et al. “Attention Is All You Need”. In: CoRR abs/1706.03762 (2017). arXiv: 1706.03762.
[24] Kelvin Xu, Jimmy Ba, Ryan Kiros, et al. “Show, Attend and Tell: Neural Image Caption Generation with Visual Attention”. In: CoRR abs/1502.03044 (2015). arXiv: 1502.03044.
[25] Jason Yosinski, Jeff Clune, Anh Mai Nguyen, et al. “Understanding Neural Networks Through Deep Visualization”. In: CoRR abs/1506.06579 (2015). arXiv: 1506.06579.
[26] Matthew D. Zeiler and Rob Fergus. “Visualizing and Understanding Convolutional Networks”. In: Computer Vision — ECCV 2014: 13th European Conference, Zurich, Switzerland, Cham: Springer International Publishing, 2014, pp. 818–833.
[27] Han Zhang, Ian Goodfellow, Dimitris Metaxas, et al. “Self-Attention Generative Adversarial Networks”. In: Proceedings of the 36th International Conference on Machine Learning. Vol. 97. Proceedings of Machine Learning Research. Long Beach, California, USA: PMLR, Sept. 2019, pp. 7354–7363. A.

视觉化和注意力——第五部分

原文:https://towardsdatascience.com/visualization-attention-part-5-2c3c14e60548?source=collection_archive---------42-----------------------

FAU 讲座笔记关于深度学习

注意机制

FAU 大学的深度学习。下图 CC BY 4.0 来自深度学习讲座

这些是 FAU 的 YouTube 讲座 深度学习 的讲义。这是与幻灯片匹配的讲座视频&的完整抄本。我们希望,你喜欢这个视频一样多。当然,这份抄本是用深度学习技术在很大程度上自动创建的,只进行了少量的手动修改。 自己试试吧!如果您发现错误,请告诉我们!

航行

上一讲 / 观看本视频 / 顶级/下一讲

欢迎回到深度学习!今天,我想告诉你一些关于注意力机制以及如何利用它们来建立更好的深度神经网络。好,那么让我们把注意力集中在注意力和注意力机制上。

什么是注意力? CC 下的图片来自深度学习讲座的 4.0 。

那么,什么是注意力呢?你看,人类通过转移我们的注意力来主动处理数据。因此,我们可以专注于图像的特定部分,因为它们携带不同的信息。当然,对于某些词,比如我们只能通过上下文推导出正确的意思。所以你想转移注意力,你转移注意力的方式也可能改变解读。所以,你想记住过去特定的相关事件,以便影响某个决定。这允许我们一次跟随一个部分,同时抑制与任务无关的信息。这就是我们的想法:你只需要关注相关的信息。你能想到的一个例子是鸡尾酒会问题。我们有很多不同的人在谈论,而你只关注一个人。通过特定的方式,比如看那个人的嘴唇,你可以把注意力集中在嘴唇上。然后你也可以使用你的立体声听觉作为一种波束形成器,只听那个特定的方向。这样做,你就能集中注意力在一个人身上,这个人就是你用这种注意力机制与之交谈的人。我们非常成功地做到了这一点,因为否则,我们将完全无法举办鸡尾酒会。

一些引起注意的想法。 CC 下的图片来自深度学习讲座的 4.0 。

那么这个想法是什么呢?好吧,你已经在地图上看到了那些显著性。你可能会说我们只想看与我们决策相关的像素。为了做出决定,事实上,我们不会从图像开始,但我们想先谈谈序列到序列模型。在这里,您可以看到 CNN 类型的模型的梯度可视化,如果您现在开始绘制这些梯度,该模型用于从英语到德语的翻译。这基本上是我们在图像处理中已经讨论过的可视化技术。现在,您可以看到相应输出相对于特定输入的梯度。如果你这样做,你会注意到在大多数情况下,你会看到这基本上是一个线性关系。英语和德语在词汇方面有非常相似的序列。然后你会看到,以“到达纳瓦兹·谢里夫总理的官方住所”开始的序列的实际开始被翻译为“总理纳瓦兹·谢里夫·祖·埃雷钦的住所”。所以,“zu erreichen”是“to reach ”,但“to reach”在英语中是第一个,在德语中是最后一个。所以,这两者之间有很长的时间背景。这两个词实质上翻译成那两个。因此,我们可以利用梯度反向传播产生的信息来计算出输入序列的哪些部分与输出序列的哪些部分相关。现在的问题是,我们如何利用这一点来提高性能。

使用 RNNs 的机器翻译。 CC 下的图片来自深度学习讲座的 4.0 。

让我们看一个典型的翻译模型。那么,如果你使用递归神经网络,通常在序列模型中做什么?你要做的是在编码器网络中进行前向传递。这接收一个输入序列。根据输入序列,正如我们之前讨论的,我们可以计算隐藏状态 h 下标 1 到 h 下标 T。因此,我们必须处理整个序列,以便计算 h 下标 T。然后, h 下标 T 用作解码器网络的上下文向量。所以, h 下标 T 本质上是这个句子的状态或实际意义的表示。然后, h 下标 T 被解码器网络解码成新的序列。然后,这产生了自己的隐藏状态的新序列,它们是 s 下标 1 到 s 下标 T’。所以请注意,输出当然可以是不同的长度。所以,我们有两个不同的字符串 T 和 T '。这也产生一个输出序列 y 下标 1 到 y 下标 T’。所以,这允许我们在输入和输出中模拟不同的长度,当然,在两种不同的语言中,你可能有不同数量的单词。

整个句子必须被编码成单个状态向量。下图 CC BY 4.0 来自深度学习讲座

所以,当我们真正解码的时候。然后,你看到我们必须把所有东西都编码到这个上下文向量中,这种编码可能非常困难,因为我们必须把句子的全部意思编码到一个上下文向量中。即使对 LSTMs 来说,这也可能非常困难。

注意力允许建立一个动态的焦点模型。 CC 下的图片来自深度学习讲座的 4.0 。

所以,现在的想法是引入注意力。注意序列到序列的建模可以用动态上下文向量来完成。现在我们有了这个上下文向量 h 下标 T。我们的问题是这个上下文向量 h 下标 T,它不允许对更早的输入进行任何访问,因为它只在序列的最末尾获得。因此,现在的想法是使用动态上下文向量作为所有先前隐藏状态的组合来提供对所有上下文的访问。

动态内容向量的构造。来自深度学习讲座CC BY 4.0 下的图片。

这里,我们看到一个双向 RNN,它通过前向传递进行一次编码。所以,你从 x 下标 1 开始,创建一个隐藏状态 1,然后到 x2,依此类推。然后,你运行完全相反的序列。所以,你从 x 下标 n 开始,然后到 x 下标(n-1)来创建另一个上下文向量,这个向量完全来自对同一输入序列的反向处理。这样你就可以访问几个隐藏状态,这些隐藏状态,我们可以从两个通道中连接起来。有了这些隐藏状态,我们就可以用一些组合权重α进行线性组合。这是不同隐藏状态的加权*均值。因此,我们将它们乘以各自的α,将它们相加,并将其作为解码器 RNN 的附加动态上下文。所以,这个想法是,我们想用一个动态的过程来产生这些权重α。

好吧。那么,让我们看看我们如何实际计算这些α。在[1]中提出的想法是,你基本上试图产生对齐权重。因此,如果状态与解码中的当前观察相关,那么你想要得到高分。如果州不是那么相关,那么你想给它打低分。因此,α编码了当前状态相对于当前产生的输出的相关性。现在,你可能会说“好吧。那么,我怎样才能得到这个分数呢?”所以,当然,我们可以把它放到某个 softmax 函数里。然后,它们将在 0 和 1 之间缩放。这就解决了问题。因此,我们可以产生任何类型的相似性度量,并且我们实际上可以提出不同的方法。

另一个翻译例子。 CC 下的图片来自深度学习讲座的 4.0 。

他们在[1]中提出的实际上是一个得分函数。现在,得分函数由矩阵 W 下标α和附加向量 v 下标α表示。这两个是可以训练的。因此,我们本质上利用了通用函数逼*的这一特性,我们不必设置得分函数,而是简单地训练它。因此,它决定了理想的对齐方式,即哪些输入对哪些输出很重要。好的一面是,您还可以可视化特定输入的权重。所以,它也允许通过看分数来解释。我们在右边的例子中这样做。这又是一个翻译设置,我们希望将英语翻译成法语。你可以看到这些排列基本上形成了一条线。但是有一个例外。所以你看到“欧洲经济区”被解码成“欧洲经济区”。所以,你可以看到有一个序列的反转,这个序列的反转也被比对分数在注意力中捕获。这是一个很好的计算得分函数的方法。

不同的得分函数。来自深度学习讲座CC BY 4.0 下的图片。

有不同的选择。例如,在[7]中,他们简单地用两个状态之间的余弦来构成分数。你可以用一些权重矩阵得到一个广义内积,你可以得到一个点积,它本质上是两个状态之间的相关性,然后你还可以得到一个比例点积,它也考虑了隐藏状态的大小。所有这些都已经被探索过了,当然,这取决于你的目的,你实际计算的是什么。但是你可以看到,我们本质上是在尝试学习一个比较函数,它告诉我们哪个状态与哪个其他状态兼容。

比较中的软硬注意。 CC 下的图片来自深度学习讲座的 4.0 。

好的。注意力有不同的种类。有软注意力和硬注意力之分。因此,到目前为止,我们基本上拥有完全可区分的软/全局注意力。但是对于大量的输入来说效率不是很高。你可以通过集中注意力来缓解。在这里,您可以看到一些输入。所以,你从图像中取出小块,从分布中取样。这当然意味着更低的计算时间。但不幸的是,采样过程是不可微的。然后,你将不得不研究其他的训练技巧,比如强化学习来训练这种能力。这需要更长的计算时间。所以,这是硬注意力的某种弊端。还有像局部注意力这样的东西,这是一种混合,你可以预测焦点和窗口或内核的中心位置。所以,让我们看看我们能做些什么。

《出席秀》报纸。 CC 下的图片来自深度学习讲座的 4.0 。

你甚至可以把注意力和图像识别结合起来。有一份报纸[24]叫做《展示-出席-讲述》。它实际上有一个想法,你想有一个自动生成的图像标题。不同的元素在它们的图像中的关系触发不同的词。因此,这意味着注意力机制被用来提高字幕质量。这是如何工作的?你现在可以看到,我们可以计算一个特定单词的注意力。

软注意的一个例子。来自深度学习讲座CC BY 4.0 下的图片。

这里,你看到生成的句子是“一个女人在公园里扔飞盘”。现在,我们可以把飞盘和这张注意力地图联系起来,你可以看到我们实际上是在图像中定位飞盘。因此,这实际上是一种非常好的方式,使用 CNN 特征图来将注意力集中在相应位置的相应解码上。

软注意力和硬注意力。 CC 下的图片来自深度学习讲座的 4.0 。

这里有一个软注意和硬注意的比较。你可以看到,注意力地图是柔和产生的,它们更模糊,也不局限于局部,而强烈的注意力只看小块。这就是我们设计它的方式,但这两种技术都允许我们生成更好的图像描述。确定性软注意可以进行端到端的训练。好吧,对于硬注意力,我们必须使用强化学习来训练。[24]表明两种注意机制产生相同的单词序列。所以,它实际上工作得很好,你有这个副产品,你现在还可以在图像中定位东西。非常有趣的方法!

自我关注的概念。 CC 下的图片来自深度学习讲座的 4.0 。

你也可以用一种叫做“自我关注”的东西来扩展这一点。这里的想法是计算序列对自身的关注度。所以,我们想要解决的问题是,如果你有一些输入,比如“动物没有穿过街道,因为它太累了。”,那么我们想知道“它”是指“动物”还是“街道”。现在,我们的想法是用上下文信息来丰富标记的表示。当然,这是机器阅读、问题回答、推理等的一项重要技术。我们这里有一个例子:“联邦调查局正在追捕一名逃犯。”现在,我们要做的是计算序列对自身的关注度。这允许我们将输入的每个单词与输入的其他单词相关联。所以,我们可以产生这种自我关注。

概述你所需要的就是关注建筑。来自深度学习讲座CC BY 4.0 下的图片。

这为什么有用?你可以看到,你也可以用它来进行机器翻译。他们提出的网络只是基于注意力。所以,机器翻译没有卷积,也没有递归。所以,注意力是你所需要的。现在的核心思想是通过这种自我关注机制来迭代地改善表现。这就产生了一种变压器架构。它有两个核心模块和编码器,这是自我注意步骤,以及用于合并不同注意头的局部全连接层。

编码器使用自我关注。 CC 下的图片来自深度学习讲座的 4.0 。

因此,让我们更详细地看看它们。当然,你需要一个编码器。我们已经看到,对于单词,我们可以使用一次热编码。这是一种非常粗糙的表示。所以,你需要注意的就是网络学习嵌入算法。因此,使用通用函数逼*器来产生嵌入,以某种方式压缩输入。然后,它计算每个标记的自我关注度。所以,你可以说你有一个查询令牌,一个描述查询的关键字,你为潜在的信息产生一个值。它们是使用可训练的权重生成的。然后,查询和键之间的对齐是一个缩放的点积,它决定了 v 中元素的影响。因此,我们可以将其表示为 qk 的外积的 softmax,然后将其乘以向量 v 以产生关注值。

你需要注意的是编码器和解码器。来自深度学习讲座的 4.0CC 下的图片。

现在有了这种关注,我们实际上有了多头关注。所以,我们不只是计算单一的注意力,而是每个标记的不同版本的注意力。这用于表示不同的子空间。然后,使用全连接层来重新组合该本地每令牌信息。然后将其堆叠起来,并使用[23]中的几个注意模块。因此,这允许一步一步的上下文集成。他们有一个额外的定位器编码来表示词序。这是现在的输入嵌入。现在,如果你看看解码器,它基本上遵循与编码器相同的概念。有一个额外的输入/输出注意步骤,自我注意只在先前的输出上计算。

为什么要用“注意力是你所需要的全部”?来自深度学习讲座的 4.0CC 下的图片。

你可能会说我们为什么要这么做?嗯,它允许独立于距离的知识整合。这种位置编码仍然允许我们学习卷积一样的步骤。它非常通用,扩展甚至允许使用未标记的文本进行预训练,正如你在[4]中看到的。所以参照物就是所谓的伯特系统。BERT 完全由未标记的文本通过本质上预测文本序列而生成。对于许多不同的自然语言处理任务,BERT 嵌入已经被证明是非常强大的。一个非常流行的系统,用于在自然语言处理中生成无监督的特征表示。这些系统具有最先进的性能和更快的训练时间。

本单元总结。 CC 下的图片来自深度学习讲座的 4.0 。

好吧。所以,让我们总结一下注意力。注意力是基于这样一种想法,即你希望将输入元素与特定的输出元素对齐或找出它们之间的相关性。注意力分数允许解释。它允许我们将非顺序任务重新表述为顺序任务。注意力本身就非常强大,因为它是一种转换机制。许多自然语言处理任务的最新技术都涉及到这些注意力机制。它在机器翻译、问题回答、情感分析等方面非常流行。但是它也被应用于视觉,例如在[27]中。当然,注意力也可以与卷积结合使用,但也有一个问题,即注意力层是否也可以被视为卷积的替代物,如[18]所示。

在这个深度学习讲座中,更多令人兴奋的事情即将到来。来自深度学习讲座CC BY 4.0 下的图片。

好吧。那么,下一次在深度学习中,接下来会发生什么?好了,接下来是深度强化学习!非常酷的技术。我们将会有几个关于这个的视频,我们想真正向你展示这个范例。如何为玩某些游戏产生超人的表现?因此,我们的策略是,我们希望训练能够在特定环境中解决特定任务的代理。我们将向你展示一种从玩游戏本身来确定游戏策略的算法。在这里,神经网络正在超越感知,真正做出决策。如果你看了接下来的几个视频,你也会得到指导,如何在雅达利游戏中最终击败你所有的朋友。我们还将向你展示一个在围棋中击败所有人类的秘方。所以,请继续关注我们。观看接下来的几个视频。

综合题。 CC 下的图片来自深度学习讲座的 4.0 。

如果你想和我们一起备考,看看下面几个问题就好了:为什么可视化很重要?每个人都应该知道“什么是反例?”。此外,你应该能够描述所使用的技术。基于梯度的可视化技术、基于优化的技术、概念论和反演技术。为什么在第三层之后切断你的网络并只保留激活是不安全的?当然,如果你知道网络架构,它们是可以反过来的。因此,如果你存储激活,它可能是不安全和匿名的。我们有一些进一步阅读的链接。特别是深度可视化工具箱真的很有用。特别是,如果你想学习更多关于注意力技巧的知识,我们在这个视频中只是粗略地介绍了一下,关于这个还有很多要说的。但是接下来我们将不得不深入序列建模和机器翻译,我们无法在本课程中详细介绍。非常感谢您的收听,希望在下一段视频中见到您。拜拜。

如果你喜欢这篇文章,你可以在这里找到更多的文章,或者看看我们的讲座。如果你想在未来了解更多的文章、视频和研究,我也会很感激关注 YouTubeTwitter脸书LinkedIn 。本文以 Creative Commons 4.0 归属许可发布,如果引用,可以转载和修改。如果你有兴趣从视频讲座中获得文字记录,试试自动博客

链接

约辛斯基等人:深度可视化工具箱
奥拉等人:特征可视化
亚当哈雷:MNIST 演示

参考

[1] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio. “Neural Machine Translation by Jointly Learning to Align and Translate”. In: 3rd International Conference on Learning Representations, ICLR 2015, San Diego, 2015.
[2] T. B. Brown, D. Mané, A. Roy, et al. “Adversarial Patch”. In: ArXiv e-prints (Dec. 2017). arXiv: 1712.09665 [cs.CV].
[3] Jianpeng Cheng, Li Dong, and Mirella Lapata. “Long Short-Term Memory-Networks for Machine Reading”. In: CoRR abs/1601.06733 (2016). arXiv: 1601.06733.
[4] Jacob Devlin, Ming-Wei Chang, Kenton Lee, et al. “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding”. In: CoRR abs/1810.04805 (2018). arXiv: 1810.04805.
[5] Neil Frazer. Neural Network Follies. 1998. URL: https://neil.fraser.name/writing/tank/ (visited on 01/07/2018).
[6] Ross B. Girshick, Jeff Donahue, Trevor Darrell, et al. “Rich feature hierarchies for accurate object detection and semantic segmentation”. In: CoRR abs/1311.2524 (2013). arXiv: 1311.2524.
[7] Alex Graves, Greg Wayne, and Ivo Danihelka. “Neural Turing Machines”. In: CoRR abs/1410.5401 (2014). arXiv: 1410.5401.
[8] Karol Gregor, Ivo Danihelka, Alex Graves, et al. “DRAW: A Recurrent Neural Network For Image Generation”. In: Proceedings of the 32nd International Conference on Machine Learning. Vol. 37. Proceedings of Machine Learning Research. Lille, France: PMLR, July 2015, pp. 1462–1471.
[9] Nal Kalchbrenner, Lasse Espeholt, Karen Simonyan, et al. “Neural Machine Translation in Linear Time”. In: CoRR abs/1610.10099 (2016). arXiv: 1610.10099.
[10] L. N. Kanal and N. C. Randall. “Recognition System Design by Statistical Analysis”. In: Proceedings of the 1964 19th ACM National Conference. ACM ’64. New York, NY, USA: ACM, 1964, pp. 42.501–42.5020.
[11] Andrej Karpathy. t-SNE visualization of CNN codes. URL: http://cs.stanford.edu/people/karpathy/cnnembed/ (visited on 01/07/2018).
[12] Alex Krizhevsky, Ilya Sutskever, and Geoffrey E Hinton. “ImageNet Classification with Deep Convolutional Neural Networks”. In: Advances In Neural Information Processing Systems 25. Curran Associates, Inc., 2012, pp. 1097–1105. arXiv: 1102.0183.
[13] Thang Luong, Hieu Pham, and Christopher D. Manning. “Effective Approaches to Attention-based Neural Machine Translation”. In: Proceedings of the 2015 Conference on Empirical Methods in Natural Language Lisbon, Portugal: Association for Computational Linguistics, Sept. 2015, pp. 1412–1421.
[14] A. Mahendran and A. Vedaldi. “Understanding deep image representations by inverting them”. In: 2015 IEEE Conference on Computer Vision and Pattern Recognition (CVPR). June 2015, pp. 5188–5196.
[15] Andreas Maier, Stefan Wenhardt, Tino Haderlein, et al. “A Microphone-independent Visualization Technique for Speech Disorders”. In: Proceedings of the 10th Annual Conference of the International Speech Communication Brighton, England, 2009, pp. 951–954.
[16] Volodymyr Mnih, Nicolas Heess, Alex Graves, et al. “Recurrent Models of Visual Attention”. In: CoRR abs/1406.6247 (2014). arXiv: 1406.6247.
[17] Chris Olah, Alexander Mordvintsev, and Ludwig Schubert. “Feature Visualization”. In: Distill (2017). https://distill.pub/2017/feature-visualization.
[18] Prajit Ramachandran, Niki Parmar, Ashish Vaswani, et al. “Stand-Alone Self-Attention in Vision Models”. In: arXiv e-prints, arXiv:1906.05909 (June 2019), arXiv:1906.05909. arXiv: 1906.05909 [cs.CV].
[19] Mahmood Sharif, Sruti Bhagavatula, Lujo Bauer, et al. “Accessorize to a Crime: Real and Stealthy Attacks on State-of-the-Art Face Recognition”. In: Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications CCS ’16. Vienna, Austria: ACM, 2016, pp. 1528–1540. A.
[20] K. Simonyan, A. Vedaldi, and A. Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”. In: International Conference on Learning Representations (ICLR) (workshop track). 2014.
[21] J.T. Springenberg, A. Dosovitskiy, T. Brox, et al. “Striving for Simplicity: The All Convolutional Net”. In: International Conference on Learning Representations (ICRL) (workshop track). 2015.
[22] Dmitry Ulyanov, Andrea Vedaldi, and Victor S. Lempitsky. “Deep Image Prior”. In: CoRR abs/1711.10925 (2017). arXiv: 1711.10925.
[23] Ashish Vaswani, Noam Shazeer, Niki Parmar, et al. “Attention Is All You Need”. In: CoRR abs/1706.03762 (2017). arXiv: 1706.03762.
[24] Kelvin Xu, Jimmy Ba, Ryan Kiros, et al. “Show, Attend and Tell: Neural Image Caption Generation with Visual Attention”. In: CoRR abs/1502.03044 (2015). arXiv: 1502.03044.
[25] Jason Yosinski, Jeff Clune, Anh Mai Nguyen, et al. “Understanding Neural Networks Through Deep Visualization”. In: CoRR abs/1506.06579 (2015). arXiv: 1506.06579.
[26] Matthew D. Zeiler and Rob Fergus. “Visualizing and Understanding Convolutional Networks”. In: Computer Vision — ECCV 2014: 13th European Conference, Zurich, Switzerland, Cham: Springer International Publishing, 2014, pp. 818–833.
[27] Han Zhang, Ian Goodfellow, Dimitris Metaxas, et al. “Self-Attention Generative Adversarial Networks”. In: Proceedings of the 36th International Conference on Machine Learning. Vol. 97. Proceedings of Machine Learning Research. Long Beach, California, USA: PMLR, Sept. 2019, pp. 7354–7363. A.

用 Plotly 实现时间序列交换数据的可视化

原文:https://towardsdatascience.com/visualization-for-timeseries-exchange-data-8c9f50d4d2d4?source=collection_archive---------17-----------------------

最*,我有机会处理 crypto exchange 公共数据,这使我能够使用最好的可视化工具之一的 Plotly 库可视化地探索数据,因为它将使我们能够拥有通用的交互式图形,而不用担心编码部分——就像我过去使用 Bokeh 一样。

如果您使用笔记本进行分析,为了保持整洁,我建议您在一个. py 文件中编写帮助函数,然后导入它。

我将分享代码,这样您将能够看到 Plotly 是如何工作的,并将其用于您的数据

所以让我们开始吧!

了解数据

像往常一样,首先要做的是获得对数据的直觉,这样我们可以更有效地采用哪种可视化。

在这种情况下,数据是一组不同的文件,每天都包含关于订单深度的信息( DOB 文件)和交易(交易文件)。

第一个操作是收集所有文件并将其聚合,构建一个包含某个时间范围内(在本例中为四个月)所有数据的数据框架。

DOB 数据包含最好的 5 个要价和 5 个出价水*,包括价格和大小,从最好到最差以及时间戳数据。

交易数据包含已执行交易的信息,包括价格、基数和接受方(买入或卖出)。

没有什么特别奇特的,所以让我们开始做一些 EDA。

DOB EDA

箱线图是可视化数据分布的最酷的方式之一,所以让我们从它们开始,看看大小和价格

尺寸盒图

我们已经可以看到数据是倾斜的,因为中值非常低,并且有明显的异常值。让我们放大,Plotly 的一些东西,你可以直接在图形上做,同时有数字信息执行鼠标悬停。

此外,只需点击图例,就可以进行过滤。

我们可以看到中间值是 0.45,最大值等于 412,中间有很多异常值。

代码:

import plotly.graph_objs as go# specific function
def draw_dob_size_box_plots(df_dob):
    _draw_dob_box_plots(df_dob, 'size')# generic "private" function
def _draw_dob_box_plots(df_dob, size_or_price):
    trace_asks0 = go.Box(
        y=df_dob['asks[0].' + size_or_price],
        name='asks[0]' + size_or_price,
        marker=dict(
            color='#3D9970'
        )
    )
    trace_bids0 = go.Box(
        y=df_dob['bids[0].' + size_or_price],
        name='bids[0].' + size_or_price,
        marker=dict(
            color='#3D9970'
        )
    )
    trace_asks1 = go.Box(
        y=df_dob['asks[1].' + size_or_price],
        name='asks[1].' + size_or_price,
        marker=dict(
            color='#6D9970'
        )
    )
    trace_bids1 = go.Box(
        y=df_dob['bids[1].' + size_or_price],
        name='bids[1].' + size_or_price,
        marker=dict(
            color='#6D9970'
        )
    )
    trace_asks2 = go.Box(
        y=df_dob['asks[2].' + size_or_price],
        name='asks[2].' + size_or_price,
        marker=dict(
            color='#9D9970'
        )
    )
    trace_bids2 = go.Box(
        y=df_dob['bids[2].' + size_or_price],
        name='bids[2].' + size_or_price,
        marker=dict(
            color='#9D9970'
        )
    )
    trace_asks3 = go.Box(
        y=df_dob['asks[3].' + size_or_price],
        name='asks[3].' + size_or_price,
        marker=dict(
            color='#BD9970'
        )
    )
    trace_bids3 = go.Box(
        y=df_dob['bids[3].' + size_or_price],
        name='bids[3].' + size_or_price,
        marker=dict(
            color='#BD9970'
        )
    )
    trace_asks4 = go.Box(
        y=df_dob['asks[4].' + size_or_price],
        name='asks[4].' + size_or_price,
        marker=dict(
            color='#ED9970'
        )
    )
    trace_bids4 = go.Box(
        y=df_dob['bids[4].' + size_or_price],
        name='bids[4].' + size_or_price,
        marker=dict(
            color='#ED9970'
        )
    )data = [trace_asks0, trace_bids0, trace_asks1, trace_bids1,                          trace_asks2, trace_bids2, \
            trace_asks3, trace_bids3, trace_asks4, trace_bids4]
    layout = go.Layout(
        yaxis=dict(
            title=size_or_price + 'Boxplot',
            zeroline=False
        )
    )
    fig = go.Figure(data=data, layout=layout)
    fig.show()

正如您所看到的,代码很简单:您从特定的源构建不同的数据可视化,设置特定的可视化选项,然后将所有这些放在一起。所以,用相对较少的线条,就有可能构建一个具有多重数据和交互的图形。

让我们在价格上做同样的事情

价格箱线图

在这里,数据不那么倾斜,但是异常值清晰可见。

如果你想了解更多关于箱线图的知识,从这里的开始

当我们处理时间序列时,时间是一个相关的因素。让我们开始看看数据是如何随时间分布的。

DOB 数据直方图

我们可以在一月份看到大量的元素,甚至在四月份看到一个峰值。

为了说明构建此图是多么容易,下面是使用的代码:

import plotly.express as pxdf = px.data.tips()
fig = px.histogram(df_dob, x=”date_time_coinapi”)
fig.show()

让我们看看买卖价格是如何随时间变化的。为了简单起见,我只放第一层,但是代码会呈现所有层。

要价和出价第一级

放大查看一些数值超级简单。

放大第一级的要价和出价

代码:

import plotly.graph_objs as go
def draw_dob_price_timeseries(df_dob):
    elements0 = ['asks[0].price','bids[0].price']
    elements1 = ['asks[1].price','bids[1].price']
    elements2 = ['asks[2].price','bids[2].price']
    elements3 = ['asks[3].price','bids[3].price']
    elements4 = ['asks[4].price','bids[4].price']
    elements = [elements0, elements1, elements2, elements3, elements4]
    for el in elements:
        _draw_dob_timeseries(df_dob, el, 'Price timeseries')def _draw_dob_timeseries(df_dob, elements, title):
    trace_asks0 = go.Scatter(
        x = df_dob.date_time_exchange,
        y=df_dob[elements[0]],
        name=elements[0],
        line = dict(color = '#17BECF'),
        opacity = 0.8 
    )
    trace_bids0 = go.Scatter(
        x = df_dob.date_time_exchange,
        y=df_dob[elements[1]],
        name=elements[1],
        line = dict(color = '#7F7F7F'),
        opacity = 0.8    
    )
    data = [trace_asks0, trace_bids0]
    layout = go.Layout(
        yaxis=dict(
            title=title,
            zeroline=False
        )
    )
    fig = go.Figure(data=data, layout=layout)
    fig.show()

def _draw_dob_box_plots(df_dob, size_or_price):
    trace_asks0 = go.Box(
        y=df_dob['asks[0].' + size_or_price],
        name='asks[0]' + size_or_price,
        marker=dict(
            color='#3D9970'
        )
    )
    trace_bids0 = go.Box(
        y=df_dob['bids[0].' + size_or_price],
        name='bids[0].' + size_or_price,
        marker=dict(
            color='#3D9970'
        )
    )
    trace_asks1 = go.Box(
        y=df_dob['asks[1].' + size_or_price],
        name='asks[1].' + size_or_price,
        marker=dict(
            color='#6D9970'
        )
    )
    trace_bids1 = go.Box(
        y=df_dob['bids[1].' + size_or_price],
        name='bids[1].' + size_or_price,
        marker=dict(
            color='#6D9970'
        )
    )
    trace_asks2 = go.Box(
        y=df_dob['asks[2].' + size_or_price],
        name='asks[2].' + size_or_price,
        marker=dict(
            color='#9D9970'
        )
    )
    trace_bids2 = go.Box(
        y=df_dob['bids[2].' + size_or_price],
        name='bids[2].' + size_or_price,
        marker=dict(
            color='#9D9970'
        )
    )
    trace_asks3 = go.Box(
        y=df_dob['asks[3].' + size_or_price],
        name='asks[3].' + size_or_price,
        marker=dict(
            color='#BD9970'
        )
    )
    trace_bids3 = go.Box(
        y=df_dob['bids[3].' + size_or_price],
        name='bids[3].' + size_or_price,
        marker=dict(
            color='#BD9970'
        )
    )
    trace_asks4 = go.Box(
        y=df_dob['asks[4].' + size_or_price],
        name='asks[4].' + size_or_price,
        marker=dict(
            color='#ED9970'
        )
    )
    trace_bids4 = go.Box(
        y=df_dob['bids[4].' + size_or_price],
        name='bids[4].' + size_or_price,
        marker=dict(
            color='#ED9970'
        ))data = [trace_asks0, trace_bids0, trace_asks1, trace_bids1, trace_asks2, trace_bids2, \
            trace_asks3, trace_bids3, trace_asks4, trace_bids4]
    layout = go.Layout(
        yaxis=dict(
            title=size_or_price + 'Boxplot',
            zeroline=False
        )
    )
    fig = go.Figure(data=data, layout=layout)
    fig.show()

这里的代码多了一点,但结构是一样的。

交易 EDA

让我们也从箱线图开始,关注买卖中的价格:

买入和卖出价格方框图

然后是一个条形图,显示买卖操作的数量:

交易并排计算

import plotly.graph_objs as go
def draw_trades_bars(df_trades):
    trace0 = **go.Bar**(
        x = np.array(df_trades[df_trades.taker_side ==  'BUY'].price.count()),
        name = 'Number of buy',
        marker=dict(
            color='#009970')
    )trace1 = **go.Bar**(
        x = np.array(df_trades[df_trades.taker_side == 'SELL'].price.count()), 
        name = 'Number of sell',
        marker=dict(
            color='#DD0000')
    )

    data = [trace0, trace1]
    layout = go.Layout(
        yaxis=dict(
            title='Trades Bar',
            zeroline=False
        )
    )
    fig = go.Figure(data=data, layout=layout)
    fig.show()

如你所见,结构总是相同的,但是在这种情况下,我们使用 go。Bar 代替 go.Scatter

让我们看看交易柱状图:

交易直方图

二月后,活动减少,没有峰值。

组合 EDA

让我们把所有的东西放在一起,看看我们是否能获得更多关于数据的直觉。

为了简化分析,我们将汇总两个数据,以 1 小时为间隔重新采样,并取 5 个值中的最大值。

RESAMPLE_TIME = '1H'
df_dob_resampled = df_dob.copy()
df_dob_resampled.index = df_dob_resampled['date_time_exchange'] 
df_dob_resampled = df_dob_resampled.**resample**(RESAMPLE_TIME).max()
df_dob_resampled.drop(columns=['date_time_exchange','date_time_coinapi'], inplace=True)df_dob_resampled['max_asks_size'] = df_dob_resampled[['asks[0].size','asks[1].size', 'asks[2].size', 'asks[3].size', 'asks[4].size']].**max**(axis=1)
df_dob_resampled['max_bids_size'] = df_dob_resampled[['bids[0].size','bids[1].size', 'bids[2].size', 'bids[3].size', 'bids[4].size']].**max**(axis=1)
df_dob_resampled['max_asks_price'] = df_dob_resampled[['asks[0].price','asks[1].price', 'asks[2].price', 'asks[3].price', 'asks[4].price']].**max**(axis=1)
df_dob_resampled['max_bids_price'] = df_dob_resampled[['bids[0].price','bids[1].price', 'bids[2].price', 'bids[3].price', 'bids[4].price']].**max**(axis=1)df_dob_resampled.drop(columns=[
                      'asks[0].size','asks[1].size', 'asks[2].size', 'asks[3].size', 'asks[4].size', \
                      'bids[0].size','bids[1].size', 'bids[2].size', 'bids[3].size', 'bids[4].size', \
                      'asks[0].price','asks[1].price', 'asks[2].price', 'asks[3].price', 'asks[4].price', \
                      'bids[0].price','bids[1].price', 'bids[2].price', 'bids[3].price', 'bids[4].price'], inplace=True)

得到这样的东西:

让我们对交易数据做同样的处理,分为卖出和买入:

现在我们可以建立一个时间序列图,将 DOB 和交易放在一起,看看是否发生了一些奇怪的事情:

大约在一月中旬,有一个异常现象,让我们放大一下:

我们可以看到要价突然上升,这可能是“欺骗”试探性的信号,这是一种非法行为,买家操纵市场支付更高的价格,并由于其他买家行为的累积效应而将价格推得更高。

import plotly.graph_objs as go
def draw_max_timeseries(df_dob_resampled, df_trades_resampled_buy, df_trades_resampled_sell, title):
    trace0 = go.Scatter(
        x = df_dob_resampled.index,
        y = df_dob_resampled['max_asks_price'],
        mode = 'lines+markers',
        name='max_asks_price',
        line = dict(color = '#dd0000', shape = 'linear'),
        opacity = 0.3,
        connectgaps=True
    )
    trace1 = go.Scatter(
        x = df_dob_resampled.index,
        y = df_dob_resampled['max_bids_price'],
        name='max_bids_price',
        mode = 'lines+markers',
        marker = dict(
            size = 10,
            color = '#44dd00'),
        opacity = 0.3    
    )
    trace2 = go.Scatter(
        x = df_trades_resampled_buy.index,
        y = df_trades_resampled_buy.price,
        name='trades BUY price',
        mode = 'markers',
        marker = dict(
            size = 10,
            color = '#00dd00'),
        opacity = 0.8    
    )
    trace3 = go.Scatter(
        x = df_trades_resampled_sell.index,
        y = df_trades_resampled_sell.price,
        name='trades SELL price',
        mode = 'markers',
        marker = dict(
            size = 10,
            color = '#dd0000'),
        opacity = 0.8    
    )data = [trace0, trace1, trace2, trace3]
    layout = go.Layout(
        yaxis=dict(
            title=title,
            zeroline=True
        )
    )
    fig = go.Figure(data=data, layout=layout)
    fig.show()draw_max_timeseries(df_dob_resampled, df_trades_resampled_buy, df_trades_resampled_sell, 'Max aggregated data timeseries')

当我们将重采样时间设置为 1 小时时,如果我们想在该时间段内获得更多的粒度,我们必须对该间隔进行切片(让我们选择 4 小时)并进行重采样,例如使用 60 秒。我们开始吧!

RESAMPLE_TIME = '60s'
START_INTERVAL = '2018-01-15 22:00:00'
END_INTERVAL = '2018-01-16 02:00:00'
df_dob_resampled_interval = df_dob.copy()
df_dob_resampled_interval.index = df_dob_resampled_interval['date_time_exchange']df_dob_resampled_interval = df_dob_resampled_interval[START_INTERVAL:END_INTERVAL]df_dob_resampled_interval = df_dob_resampled_interval.resample(RESAMPLE_TIME).max()
df_dob_resampled_interval.drop(columns=['date_time_exchange','date_time_coinapi'], inplace=True)df_dob_resampled_interval['max_asks_size'] = df_dob_resampled_interval[['asks[0].size','asks[1].size', 'asks[2].size', 'asks[3].size', 'asks[4].size']].max(axis=1)
df_dob_resampled_interval['max_bids_size'] = df_dob_resampled_interval[['bids[0].size','bids[1].size', 'bids[2].size', 'bids[3].size', 'bids[4].size']].max(axis=1)
df_dob_resampled_interval['max_asks_price'] = df_dob_resampled_interval[['asks[0].price','asks[1].price', 'asks[2].price', 'asks[3].price', 'asks[4].price']].max(axis=1)
df_dob_resampled_interval['max_bids_price'] = df_dob_resampled_interval[['bids[0].price','bids[1].price', 'bids[2].price', 'bids[3].price', 'bids[4].price']].max(axis=1)df_dob_resampled_interval.drop(columns=[
                      'asks[0].size','asks[1].size', 'asks[2].size', 'asks[3].size', 'asks[4].size', \
                      'bids[0].size','bids[1].size', 'bids[2].size', 'bids[3].size', 'bids[4].size', \
                      'asks[0].price','asks[1].price', 'asks[2].price', 'asks[3].price', 'asks[4].price', \
                      'bids[0].price','bids[1].price', 'bids[2].price', 'bids[3].price', 'bids[4].price'], inplace=True)df_dob_resampled_interval.head()df_trades_resampled_interval = df_trades.copy()
df_trades_resampled_interval.index = df_trades_resampled_interval['time_exchange'] 
df_trades_resampled_interval = df_trades_resampled_interval[START_INTERVAL:END_INTERVAL]
df_trades_resampled_interval_buy = df_trades_resampled_interval[df_trades_resampled_interval.taker_side == 'BUY'].resample(RESAMPLE_TIME).max()
df_trades_resampled_interval_buy.drop(columns=['time_exchange', 'time_coinapi','guid'], inplace=True)
df_trades_resampled_interval_buy.head()df_trades_resampled_interval = df_trades.copy()
df_trades_resampled_interval.index = df_trades_resampled_interval['time_exchange']
df_trades_resampled_interval = df_trades_resampled_interval[START_INTERVAL:END_INTERVAL]
df_trades_resampled_interval_sell = df_trades_resampled_interval[df_trades_resampled_interval.taker_side == 'SELL'].resample(RESAMPLE_TIME).max()
df_trades_resampled_interval_sell.drop(columns=['time_exchange', 'time_coinapi', 'guid'], inplace=True)
df_trades_resampled_interval_sell.head()

现在我们有了这样的东西:

有 NaN 值不是问题,会被 Plotly 忽略。

让我们画出来:

我们可以看到,在 22:45 左右出现了峰值,一小时后情况恢复正常,但只有一笔交易价格上涨,因此不存在累积效应。

结论

EDA 是对数据执行的基本活动,使用简单而强大的工具有效地执行 EDA 可以节省时间,从而可以专注于直觉而不是代码。

有几个库可以用来做数据可视化,当然 Plotly 是其中一个更强大、更容易使用的库,尤其是最新版本,所以获取一些数据并尝试一下吧!

新冠肺炎疫情期间空中交通的可视化

原文:https://towardsdatascience.com/visualization-of-air-traffic-during-covid-19-pandemic-c5941b049401?source=collection_archive---------19-----------------------

2020 年全球航班数据的探索性数据分析

阿列克谢·斯塔基在 Unsplash 上的照片

介绍

新冠肺炎·疫情严重影响了世界。为了减缓疫情,各国发布了旅行限制,社会距离的任务,锁定等。因此,很多企业都受到了影响。旅游业是遭受重创的行业之一。

由于旅行限制,世界各地的航班数量急剧下降。在这篇文章中,我将对飞行数据进行分析和可视化。

资料组

我使用的数据集是“来自 OpenSky Network 2020 的众包空中交通数据”。它以多个 csv 文件(每月一个文件)的形式提供 2019 年 1 月 1 日至 2020 年 7 月 31 日的航班数据。在这项工作中,我使用了 2020 年 1 月 1 日至 2020 年 7 月 31 日的数据。

该数据集具有以下特征:

呼号:显示在 ATC 屏幕上的航班标识符(通常前三个字母是为航空公司保留的:AFR 代表法航,DLH 代表汉莎航空,等等。)

编号:航班的商业编号,如果有的话(与呼号的匹配来自公共开放 API)

icao24 :应答器唯一标识号;

登记:飞机尾号(如有);

类型码:飞机型号类型(如有);

始发地:航班始发地机场的四个字母代码(如有);

目的地:该航班目的地机场的四个字母代码(如有);

first seen:open sky 网络收到的第一条消息的 UTC 时间戳;

last seen:open sky 网络收到的最后一条消息的 UTC 时间戳;

:开放天空网络收到最后一条消息的 UTC 日;

纬度 _1经度 _1高度 _1 :飞机第一次探测到的位置;

纬度 _2经度 _2高度 _2 :最后检测到的飞机位置。

形象化

经过一些数据处理后,我能够将数据可视化。

总菌数

先说航班总量。

很明显,航班数量在三月初下降了很多,这是那段时间全球封锁的结果。自那以后,由于缓慢的重新开放,航班数量逐渐增加,但仍未恢复到新冠肺炎之前的水*。

新冠肺炎期间的全球航班数量(图片由作者提供)

我也把数据放在地图上,如下图。很明显,红色斑点的密度在三月份下降,然后逐渐增加。

新冠肺炎期间地图上的全球航班(图片作者

乘飞机

让我们分解一下,看看每个航空公司的影响。数据集中有太多的航空公司,所以我只拿其中的一些作为例子。我乘坐了一家欧洲航空公司荷航(荷兰),两家美国航空公司 AAL 和达美,两家亚洲航空公司全日空(日本),加州航空(台湾),以及一家廉价航空公司 EJU(易捷)。

与 1 月 1 日相比,3 月和 4 月的大部分航班数量大幅下降至 25%以下,易捷航空(EJU)甚至在 3 月至 6 月间降至 0。7 月底,这些航空公司的航班数量回升至 50%左右。

新冠肺炎期间各航空公司的航班数量(图片由作者提供)

台湾航空公司(CAL)是一个特例,它没有像其他航空公司一样在 3 月份急剧下降,而是从 1 月份开始逐渐下降,即使在最糟糕的时期也仍然保持在 50%左右。这可能是因为台湾政府很早就意识到了新冠肺炎。另一家亚洲航空公司(全日空)也显示了早期活动的减少。

乘机场

让我们看看机场。我以阿姆斯特丹(EHAM)、台北(RCTP)、东京(RJTT)、洛杉矶(KLAX)和纽约(JFK)为例。

它显示了类似的趋势,在 3 月和 4 月急剧下降到 20%,然后缓慢回升到 40 %- 60%。阿姆斯特丹机场比美国机场(洛杉矶和纽约)稍早减少了活动。东京机场稍早开始减少活动,但速度较慢。台北表现出不同的行为,它在一月底开始缓慢下降,这与台湾的 CAL 航空公司相似。

新冠肺炎期间每个机场的航班数量

货物

货运航班怎么样?

从联邦快递和 UPS 航班的数据来看,并没有真正受到冲击。

新冠肺炎期间每个机场的货运航班数量(图片作者

结论

  • 新冠肺炎疫情开始时,航班流量显著下降,并已逐渐恢复。
  • 廉价航空公司(Easyjet)从 3 月到 6 月几乎停止了航班,然后从 6 月开始逐渐恢复。
  • 货运航班没有受到影响。

感谢阅读。

Python 中新冠肺炎新病例随时间变化的可视化

原文:https://towardsdatascience.com/visualization-of-covid-19-new-cases-over-time-in-python-8c6ac4620c88?source=collection_archive---------27-----------------------

热图显示了不同州的潮起潮落

每日每 10 万人口新新冠肺炎病例热图

这张热图显示了美国新冠肺炎疫情随时间的发展。该地图从左至右阅读,并以彩色编码显示各州新病例的相对数量,并根据人口进行调整。

这个可视化的灵感来自于我在一个论坛上看到的一个相似的热图。我从来没有找到来源,因为它只是一个粘贴的图像,没有链接。最初的版本也是为了表明一个政治观点,按照主要的党派划分各州,而我对此并不感兴趣。我被它如何简明地显示疫情的进展迷住了,所以我决定自己创建一个类似的可视化,以便我可以定期更新。

源代码托管在我的 Github repo 上。如果你有兴趣看这张热图的更新版本,我每周都会在我的 Twitter feed 上发布。需要注意的是,在比较一周和另一周的图表时要小心,因为随着新数据的加入,颜色图可能会发生变化。比较仅在给定的热图内有效。

该脚本依赖于 pandas、numpy、matplotlib 和 seaborn。

数据来自《纽约时报》新冠肺炎 Github 回购。一个简单的启动器脚本克隆存储库的最新副本并复制所需的文件,然后启动 Python 脚本来创建热图。只有一个文件是真正需要的,所以它当然可以收紧,但这是可行的。

该脚本首先将一个包含州人口的 CSV 文件加载到一个字典中,该字典用于衡量每天的新病例结果。每天的新病例是根据纽约时报数据中的累计总数计算出来的,然后换算成人口中每 100,000 人中的新病例

我们可以显示此时的热图,但如果我们这样做,每 100,000 人中病例数非常高的州将淹没病例数较低的州的详细信息。应用 [log(x+1)](http://onbiostatistics.blogspot.com/2012/05/logx1-data-transformation.html#:~:text=A%3A log(x%2B1,in which x was measured.) 变换可以显著提高对比度和可读性。

最后,使用 Seaborn 和 Matplotlib 生成热图,并将其保存到图像文件中。

就是这样!请随意使用这个作为你自己的可视化框架。你可以定制它来聚焦感兴趣的领域。

完整的源代码在下面。感谢阅读,希望你觉得有用。

马哈拉施特拉邦选举的可视化

原文:https://towardsdatascience.com/visualization-of-maharashtras-elections-f7e85a79edd1?source=collection_archive---------51-----------------------

制作选举地图的指南

阿哈拉什特拉是印度人口第二多、面积第三大的邦。马哈拉施特拉邦对该国国内生产总值的贡献约为 15%,是该国最大的经济贡献者,而邦首府孟买则是该国的金融之都。此外,浦那还被称为“东方牛津”,因为那里有许多教育机构,如 IUCAA、NCRA、IISER 等。从今以后,马哈拉施特拉邦发生的任何事情都会在全国范围内产生经济影响。

本文将介绍如何使用公开数据制作马哈拉施特拉邦 2019 年议会选举的 choropleth 地图。通常,程序集选区的形状文件在 internet 上是极其稀缺的资源。

数据

  1. 议会选区的形状文件可以在这里找到【https://github.com/datameet/maps
  2. 各选区获胜政党的数据可从选举委员会网页下载。

必需的包

  1. 熊猫(安装指南:https://pandas . pydata . org/pandas-docs/stable/getting _ started/install . html)
  2. Geopandas(安装:https://geopandas.org/install.html
  3. Seaborn(安装:https://seaborn.pydata.org/installing.html
  4. Matplotlib 和 numpy

地图数据

导入包

首先,导入所需的包,如下所示:

import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
sns.set_style('whitegrid')

“set_style”是一个可选命令,为即将到来的绘图设置一个白色网格。

# Importing the shape file of assembly-constituencies
fp = "assembly-constituencies"
map_df = gpd.read_file(fp)
map_df = map_df[map_df['ST_NAME']=='MAHARASHTRA']
map_df = map_df[['AC_NAME', 'geometry']]
map_df.reset_index(drop=True,inplace=True)
map_df.head(3)

' read_file '导入印度议会选区的形状文件作为数据帧,'map _ df[' ST _ NAME ']= ' MAHARASHTRA'过滤属于 MAHARASHTRA 的选区。后续行仅保留所需的特征,如选区名称(AC_NAME)和形状文件(geometry)。

基本探索性数据分析

map_df.info()

从上面可以看出,有 288 个装配选区名称( AC_NAME )和 302 个形状文件( geometry )。来自印度选举委员会的数据显示,印度共有 288 个议会选区。让我们探索更多来解决这种差异。

# Plot of the assembly-constituencies
map_df.plot()

形状文件的情节看起来很正常。让我们检查一下是否有空类型值。

# checking for null values
Null_Values = map_df.isnull().sum()
print(Null_Values)

python 中的空类型对象用 None 关键字表示。这里, isnull() 命令将 DataFrame map_df 转换为 TrueFalse 表格,其中 TrueNone 关键字的占位符,反之亦然。sum()命令将值分别为 1 和 0 的真值假值相加因此,选区名称中有 14 个缺失值,形状文件中同样没有缺失值。

这可以想象为 Seaborn 图书馆的热图:

# It seems some of the names of the assembly-constituencies is missing!
sns.heatmap(Null_Values)

AC_NAME 列中的奇数直线表示缺少的值。这些值可以用熊猫的 dropna() 删除,如下所示。

map_df.dropna(inplace=True) # The 'None' type rows are removed
map_df.reset_index(drop=True,inplace=True) # index is reset
map_df.head()

移除空类型值后,索引将被重置以考虑移除的值,并将选区名称设置为新索引—这是通过 drop=True 选项实现的。而 inplace=True 选项将这些变化保留在 map_df 数据帧中。

数据清理

数据必须被清理以匹配来自选举委员会的选区名称。人们可以看到,名称后面有 (ST)(SC) ,以表示为 ST 和 SC 保留的选区。

#Cleaning the names of assembly constituencies
def text_process(names):
    semi_cleaned_names = [word for word in names.strip().lower().split() if word not in ['(st)','(sc)']] 
    joined_cleaned_names = " ".join(semi_cleaned_names)
    removed_st_names = joined_cleaned_names.replace("(st)","")
    fully_cleaned_names = removed_st_names.replace("(sc)","")
    return fully_cleaned_names# The cleaned names
map_df['cleaned_names']=map_df['AC_NAME'].apply(text_process)
map_df = map_df[['cleaned_names','geometry']]

apply 命令一次向 text_process() 函数发送一个单词。在这里,每个单词都去掉了前导和结尾的空格,转换成小写,并通过 names.strip()以空格分隔成更多的单词。降低()。【split()。一个示例单词 Arjuni Morgaon(SC) 在第一行代码后看起来像 ['arjuni ',' morgaon(sc)'] 。单词 (sc) 仍然保留在这个单词中,因为它没有用空格与 morgaon 分开。对这个字的 join() 命令将产生 arjuni morgaon(sc)。最后,替换("(sc)"," ")会给出完全清洗的名字 arjuni morgaon

数据帧现在看起来像这样:

map_df.head()

选举数据

可以从选举委员会页面下载 xlsx 格式的各选区获胜政党的数据。

# Importing Election Data
df_election = pd.read_excel('2-List of Successful Candidates.xlsx',names=np.array(['State','Constituency','Winner','Sex','Party','Symbol'])) df_election.reset_index(drop=True)
df_election.head()

来自 pandas 的 read_excel 命令直接将 excel 表数据作为 DataFrame 导入, names 选项为列设置新名称。

基本探索性数据分析

df_election.info()

上面的结果显示六列中没有空值。

plt.figure(figsize=(10,5))
sns.countplot(x='Party',data=df_election,)

countplot 命令绘制了每一方赢得的选区数量,而 value_count() 给出了确切的数字:

df_election['Party'].value_counts()

显然,前四大政党赢得的选区比其他政党多得多。现在,让我们只分离在 20 多个选区获胜的政党。这是为了关注表现良好的政党。

df_successful_party = df_election['Party'].value_counts() > 20
df_successful_party=df_successful_party[df_successful_party==True].index
Succ_parties = df_successful_party.values
df = df_election['Party'].apply(lambda x: x in Succ_parties)
sns.countplot(x = 'Party',data = df_election[df],hue='Sex')

按性别对成功候选人进行党派细分。

第一行给出一个熊猫系列,以当事人名称为索引,列为值,其中表示大于 20 的值,而否则为第二行通过索引命令给出只有值的各方名称。第三行将各方名称转换成一个 numpy 数组。这个数组在下面的 apply 命令中使用,该命令过滤所有胜率大于 20 的团体。最后一行只是标出了每个政党赢得的选区数量,并按照候选人的性别分类。从绝对数字来看,BJP 似乎在获胜的候选人中代表了更多的妇女。让我们更深入地了解一下这个问题。

df_election['Sex'].value_counts()
Percentage_of_women = 24/288*100
Percentage_of_women

以上各行显示,在包括所有政党在内的所有成功候选人中,妇女仅占 8%。将它分解为一个党派的代表:

df_election[df_election['Party']=='BJP']['Sex'].value_counts()
Percentage_of_women_BJP = (12/105)*100
Percentage_of_women_BJP

这表明在 BJP 的成功候选人中,妇女占 11 %。类似地,为所有各方计算它,可以绘制如下:

arr = np.array([Percentage_of_women,Percentage_of_women_BJP,Percentage_of_women_NCP,Percentage_of_women_SHS,Percentage_of_women_INC])

Women_representation = pd.DataFrame(data=arr,columns=['Women Representation (%)'],index=None)Women_representation['Party'] = ['Overall','BJP','NCP','SHS','INC']plt.figure(figsize=(8,5))sns.barplot(y='Women Representation (%)',x='Party',data=Women_representation)

妇女在政党中的代表性。

上图显示了妇女在政党中的代表性,即在成功的候选人中所占的百分比。可以看出,BJP 和国会的妇女代表几乎相等。此外,两党都超过了 8 %的*均女性代表比例。排名第三和第四的是全国大会党和自助党,其代表性低于*均水*。

数据清理

# Cleaning the names of assembly constituencies
df_election['Constituency']=df_election['Constituency'].str.lower()
df_election['Constituency']=df_election['Constituency'].str.strip()

# Joining both DF with 'cleaned_names' column as index
merged = map_df.set_index('cleaned_names').join(df_election.set_index('Constituency'))
merged.head()

与地图数据相比,这是一种更简单的数据清理形式。这里,所有转换为小写的名称,以及开始和结尾的空格都被删除。 join 命令连接地图数据帧和该数据帧,其中选区名称匹配!

马哈拉施特拉邦的选举地图

# Plotting the election results
fig, ax = plt.subplots(1,figsize=(10, 6))
ax.axis('off')
ax.set_title('Maharashtra Election 2019', fontdict={'fontsize': '25', 'fontweight' : '3'})merged.plot(column='Party', cmap='plasma', linewidth=0.7, ax=ax, edgecolor='0.8', legend=True)
leg = ax.get_legend()
leg.set_bbox_to_anchor((1, 0.7, 0.2, 0.2))

子图形()创建一个图形和轴实例,可用于设置图形的属性。这是一种面向对象的编程方式,相比之下, plt.plot() 是一种函数式的编程方式。这里的轴实例, ax ,用于设置绘图的标题,并删除绘图轴。m erged.plot() 绘制关于各方的 choropleth 图。这是 Pandas 特有的绘图方式,其中一个更通用的命令类似于 DataFrame_Name.plot() 。它使用 m atplotlib 作为后端,因此,与 matplotlib 特定命令如 subplot()配合使用效果很好。**cmap选项设置绘图的颜色方案。此外,g et_legend() 创建一个图例实例,它与 set_bbox_to_anchor() 一起使用,以便更准确地放置图例。

choropleth 地图上的白色斑块代表缺失的选区。这些是其名称为 none 并从 map_df 数据框中删除的议会选区。您可以尝试更多的 cmap 颜色选项,如图所示。然而,人们必须看到,有太多的党,以确定他们所有的颜色。在未来,我们将探索更多关于提高理解和这个情节的美感!

完整的笔记本可以参考这里

基于 Gensim 和 PCA 的单词嵌入向量可视化

原文:https://towardsdatascience.com/visualization-of-word-embedding-vectors-using-gensim-and-pca-8f592a5d3354?source=collection_archive---------13-----------------------

在本文中,我们将学习如何使用单词嵌入来训练文本数据,并使用主成分分析来进一步可视化这些向量。

简介:

有某些方法可以从任何文本数据中提取特征,然后输入到机器学习模型中。最基本的技术是—计数矢量器、Tf-Idf。这些技术的主要缺点是它们不能捕捉文本数据的语义,并且每个单词被分配到一个新的维度,就像一个热编码向量一样。因此,如果语料库规模相当大,那么维度可能高达数百万个单词,这是不可行的,并且可能导致模型不佳。我们可以使用简单的余弦相似度计算来验证这一点。假设我们有两个句子,每个句子包含一个单词“good”和“nice”。在这里,我们知道这两个词彼此有一些相似性,但是当我们使用计数矢量器向量计算余弦相似性时,结果是零。

其中 U 和 V 是两个句子-[1,0]和[0,1]的向量表示

什么是文字嵌入?

这是一种将单词映射到实数向量的技术,同时捕捉关于文本含义的一些信息。它说,如果两个单词有相似的意思,它们将在密集的空间中彼此靠*。就像这两个词一样,我们前面用过的“好”和“漂亮”会在嵌入空间中彼此靠*。在本文中,我们将使用 gensim 库中的 Word2Vec 算法在密集空间中可视化这类单词。Word2Vec 包含两个模型,分别用于训练跳格模型和连续词袋(CBOW)。

对于想要熟悉单词嵌入的基本概念的人来说,他们应该首先回顾下面给出的文章。在本文中,我们将主要关注 python 的实现和可视化。

[## 单词嵌入简介

什么是单词嵌入?

towardsdatascience.com](/introduction-to-word-embeddings-4cf857b12edc) [## Word2Vec 的数学优先解释

介绍

medium.com](https://medium.com/analytics-vidhya/maths-behind-word2vec-explained-38d74f32726b)

Python 实现:

数据集:

我从维基百科对单词嵌入的定义中摘录了一小段文字。我们将在密集的空间中呈现这篇课文的单词。

text="Word embedding is the collective name for a set of language modeling and feature learning techniques in natural language processing where words or phrases from the vocabulary are mapped to vectors of real numbers. Conceptually it involves a mathematical embedding from a space with many dimensions per word to a continuous vector space with a much lower dimension.The use of multi-sense embeddings is known to improve performance in several NLP tasks, such as part-of-speech tagging, semantic relation identification, and semantic relatedness. However, tasks involving named entity recognition and sentiment analysis seem not to benefit from a multiple vector representation."

导入相关库:

我们将安装 gensim 库并从中导入 Word2Vec 模块。此外,我们将导入 NLTK 并将其用于句子标记化。

标记化:

我们将在 NLTK 分词器的帮助下对句子进行分词。

Word2Vec:

我们在上一部分中获得的标记化格式的句子中采用的模型将被直接输入其中。除此之外,这个类还有各种参数——大小、窗口、最小计数、sg

大小=这决定了我们想要的单词表示的维数。(默认值=100)

Window=这是一个中心单词与其周围单词之间的最大距离。

min _ count=这是训练模型时要考虑的最小字数;出现次数少于此数的单词将被忽略。

sg =这指定了训练算法 CBOW (0),Skip-Gram (1)

对于我们的设置,由于文本较少,我们将使用 min_count=1 来考虑所有的单词。我们将在跳格模型中使用窗口=50,因此 sg=1。

model = Word2Vec(tokens,size=50,sg=1,min_count=1)
model["the"]

我们可以看到单词“the”的矢量表示是通过使用模型[“the”]获得的。我们可以看到单词“the”的向量表示是在 50 维空间中。

我们可以把学过的词汇打印出来如下:

words=list(model.wv.vocab)
print(words)

词汇

此外,我们将在具有 50 维的数据帧中存储所有的词向量,并将该数据帧用于 PCA。

X=model[model.wv.vocab]
df=pd.DataFrame(df)
df.shape
df.head()

数据框的形状

数据帧

PCA:

我们将使用 numpy 库实现 PCA。PCA 涉及的步骤如下-

1-标准化数据集并计算相关矩阵。

2-使用特征分解计算特征值和特征向量。

3-对特征值及其对应的特征向量进行排序。

4-挑选两个最大的特征值,创建一个特征向量矩阵。

5-使用这些新特征向量的点积变换原始数据。

在这种情况下,我们可以忽略标准化步骤,因为数据使用相同的单位。

获得的新数据集如下所示:

维度=(78,2)

可视化:

我们将使用 matplotlib 来可视化密集空间中的单词。

结论:

在本文中,我们学习了如何使用 Word2Vec 技术将文本数据转换为特征向量。此外,我们还学习了如何使用 matplotlib 和 PCA 在二维空间中表示这些单词向量。在我的下一篇文章中,我们将讨论单词嵌入技术背后的数学原理。

参考文献:

https://d2l . ai/chapter _ natural-language-processing-pre training/word 2 vec . html

感谢您的阅读!!!!

如果你喜欢我的工作,想支持我。

1-支持我的最好方式是在 上关注我。

2-关注我LinkedIn

用 Plotly 可视化。快递:综合指南

原文:https://towardsdatascience.com/visualization-with-plotly-express-comprehensive-guide-eb5ee4b50b57?source=collection_archive---------3-----------------------

一个数据集和 70 多个图表。交互性和动画通常出现在一行代码中

本文中的所有图片均由作者创作,图片属于本许可

我经常想出一个理想的形象,然后努力编码。这将是中肯的,富有表现力的,易于解释,但它是不可能创造的。当我发现 Plotly 时,它使绘图变得简单多了。

阴谋地。Express ,在版本 4.0.0 中首次引入,是 Plotly API 的一个高级抽象,经过优化可以完美地处理数据帧。这很好,虽然不是完美无缺。我认为最大的差距在于 API 文档的例子或链接的数量。这就是为什么我决定用我在图书馆的经历来写一本指南。

要运行图表和练习,请使用 Github 上的plot ly Express-Comprehensive guide . ipynb笔记本。本文中的所有代码都是用 python 编写的。

目录:

安装 Plotly Express

普洛特利。Express 是 Plotly python 包的常规部分,所以最简单的就是全部安装。

# pip 
pip install plotly# anaconda
conda install -c anaconda plotly

Plotly Express 还要求安装 pandas,否则当你尝试导入时会得到这个错误。

[In]: import plotly.express as px
[Out]: **ImportError**: Plotly express requires pandas to be installed.

如果您想在 Jupyter 笔记本中使用 plotly,还有其他要求。对于 Jupyter 实验室你需要[jupyterlab-plotly](https://plotly.com/python/getting-started/#jupyterlab-support-python-35)。在普通笔记本上,我必须安装nbformat ( conda install -c anaconda nbformat)

Plotly Express 语法—一行代码

普洛特利。Express 提供了创建多种图表类型的速记语法。每个都有不同的参数,理解参数是 Plotly 的关键。表达魅力。你可以用一个命令创建大多数图表(许多广告商说一行,但由于 PEP8 建议每行最多 79 个字符,所以通常会更长)。

作者图片

import plotly.express as px# syntax of all the plotly charts
px.chart_type(df, parameters)

用 Plotly 创建图表。只表达你的类型px.chart_type(后面会介绍很多类型)。这个函数用你的数据df和图表的参数消耗一个数据帧。一些参数是图表特定的,但大多数情况下您输入xy值(或namesvalues,例如在饼状图的情况下)。您用text标记数据点,并通过colordashgroup将其分成不同的类别(单独的线条、条形、饼图的扇形)。其他参数让你影响颜色,分裂为支线剧情(刻面),自定义工具提示,轴的规模和范围,并添加动画。

大多数情况下,您将绘图分配到一个变量中,以便可以影响图形元素和布局的设置。

fig = px.chart_type(df, parameters)
fig.update_layout(layout_parameters or add annotations)
fig.update_traces(further graph parameters)
fig.update_xaxis() # or update_yaxis
fig.show()

数据集

尽管 plotly 附带了一些集成的数据集,但它们在许多现有的例子中使用过,所以我选择了我最喜欢的数据集,关于去每个国家旅游的游客的数量和他们在度假中花费的。世界银行通过 CC-BY 4.0 许可提供该数据集。

与每个数据集一样,即使是这个数据集也需要一些预处理。关于旅游数据集,令人非常恼火的是,它将每个国家的值与地区总量混合在一起。预处理很简单(见代码),重要的是数据集以一种广泛的形式出现。

数据很重要(宽而长的数据帧)

所有数据帧都可以转换成多种形式。数据表可以是多列存储信息,也可以是多行存储数据。幸运的是 python 和 pandas 库允许在它们之间轻松转换,使用[DataFrame.T](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html)将行转换成列,[melt()](https://pandas.pydata.org/docs/reference/api/pandas.melt.html)将列融合成长数据帧,[pivot()](https://pandas.pydata.org/docs/reference/api/pandas.pivot.html)[pivot_table()](https://pandas.pydata.org/docs/reference/api/pandas.pivot_table.html)做相反的事情。Nicolas Kruchten 在他的Beyond“tidy”文章中解释得很好,所以我不会在这里花更多的时间讨论它。还可以在 Github 上看到评论笔记本里的所有数据操作。

宽长数据格式的相同数据帧(图片由作者提供)

普洛特利。Express 最适合长数据。它被设计成接受一列作为参数。分类列影响元素(线条、条形等),可以通过样式来区分,而值列影响元素的大小,可以显示为标签和工具提示。

广泛数据的有限可能性

您也可以使用 Plotly express 处理大量数据,但是使用案例有限。让我们来探索一下您可以对宽数据集及其限制做些什么。

所有图表的第一个参数几乎相同— the datasetxy。x 和 y 可以是 dataframe、[padnas.Series](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html)或数组中的列名。我们的旅游数据集有很多列。因为我们将years作为列,将Country Names作为行,所以我们使用[pandas.DataFrame.T](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html)在它们之间切换。Express API 使用列。

使用熊猫切换行和列。DataFrame.T(图片由作者提供)

下面,三种绘制图表的方法是等价的。自己查,但我觉得第一条最有道理。如果使用列或系列,其名称将显示为轴标签,而对于数组,您必须手动添加标签。

"""our dataset comes as a wide dataset with years as column. To turn the country names into the columns, we must set them as index and transpose the frame."""
country_columns = year_columns.set_index("Country Name").T# 1\. I had to reshape the data by transposing
px.line(country_columns
        ,y="Spain"
        ,title="Visitors to Spain")# 2\. you can specify the value as pandas.Series as well
px.line(country_columns, 
        y=country_columns["Spain"],
       title="Visitors to Spain")# 3\. or any array. In this case you must specify y-label. 
px.line(country_columns, 
        y=country_columns["Spain"].to_list(), 
        labels={"y":"Spain"},
       title="Visitors to Spain")

px.line(df,y="column_name ",title="…")创建的最简单的折线图。作者图片

拥有一个包含几个描述性列*Country Name**Country Code*Region的数据集,并与数据列(如*1995**1996**2018*中的访问次数)混合,显示了 Plotly 的一个好处。聪明的做法是只考虑有值的列,忽略其余的。

您可以轻松地在图表中选取多个列。

px.line(country_columns, y=["Spain","Italy","France"])

您可以轻松地向图表中添加多列。作者图片

宽数据框的限制

在 Plotly 中,您可以对包含许多列的数据集进行一些操作,但该库的真正强大之处在于长数据。原因,大部分参数恰好接受一列。它可以有几个不同的(通常是分类的)值,并对它们施展魔法,但不能有一个以上的列。以下代码导致了一个错误:

[In]:
try: 
  px.line(country_columns, y=["Spain","Italy","France"], 
          # trying to label the line with text parameter
          **text=["Spain","Italy","France"]**)except Exception as e:
  print(e)[Out]: **All arguments should have the same length. The length of argument `wide_cross` is 25, whereas the length of  previously-processed arguments ['text'] is 3**

您可以尝试选择其中一列,但结果是彻底失败。意大利和法国的折线图,标注了西班牙的游客数量。一场灾难。

px.line(country_columns, y=["Spain","Italy","France"], 
                text="Spain")

因为所有列都有相同的行数,所以可以用来自西班牙列的文本来注释法国和意大利的值。(图片作者,图片授权)

长数据 Metled 数据框架

普洛特利没有错。要利用这些参数,您必须使用长数据框。从广泛的数据集中,使用.melt()函数得到它。我还将只过滤 3 个国家,以免图表过于拥挤。

融化数据帧,使其在一列(或多列)中包含类别,在一列中包含值,这样您就可以利用 plotly 的参数。作者图片

spfrit = melted_df[melted_df["Country Name"].isin(["Spain","Italy","France"])]px.line(spfrit, 
        **x**="years", 
        **y**="visitors", 
        **color**="Country Name", 
        **text**="visitors",
       title="International Visitors")

为每个参数指定一列,让 plotly 确定其余的参数:

  • x — x 轴包含来自year列的所有不同值(1995 年至 2018 年)
  • y — y 轴覆盖从visitors栏开始的整个范围
  • color —将三种不同的颜色设置为Country Name列中的不同值(法国、意大利和西班牙)
  • text —给每一行标上每年的访客数量

折线图

让我们探索一下基本的折线图,看看使用 Plotly 可以多么容易地创建可视化效果。每个 Plotly 的图表都记录在几个地方:

  • 图表类型页面-例如 Python 中的折线图-显示最常见的示例
  • Python API 参考——例如express . line——描述您可以使用的所有参数

在上一节中,您已经看到折线图需要有三种形式的xy值,但是对于 Express 来说最常见的是使用列名来指定哪个数据框的列控制图形的功能。

折线图参数颜色、虚线、分组

color —是许多图表类型的关键参数。它将数据分成不同的组,并给它们分配不同的颜色。每个组构成一个元素,在折线图中,它是一条单独的线。除非使用以下参数设置确切的颜色,否则颜色将被分配给每一行。

**color_discrete_sequence** —选择线条的预定义颜色,如color_discrete_sequence = ["red","yellow"]。如果您提供的颜色少于您的系列数量,Plotly 将自动分配剩余的颜色。

**color_discrete_map** —允许同上,但以字典的形式为特定系列分配颜色。color_discrete_map = {"Spain":"Black"}

**line_dash** —与color类似,只是改变了破折号的图案而不是颜色

**line_group** —类似于颜色,用于区分分隔线条的值(类别),但在这种情况下,所有线条都将具有相同的颜色,并且不会为它们创建图例。

作者图片

工具提示

可以在交互式菜单上切换最*工具提示和比较工具提示。作者图片

Plotly 固有地带来了交互式工具提示。上面你可以看到你可以在最*的和所有的数据工具提示之间切换。还有一些参数可以进一步定制这些文本框— hover_name在工具提示的顶部突出显示该列的值。hover_data允许True/False出现在工具提示上的类别或值。labels param 让你重命名这些类别。

操作工具提示的选项。作者图片

其他有用的参数

我们为每个国家创建了 3 条不同颜色的线。将color参数更改为facet_colfacet_row以创建 3 个独立的图表。保持facetcolor确保每条线有不同的颜色。不然也一样。你可以放大其中一幅图,其他的也会放大。

将多面图表分成行或列。作者图片

分面支线剧情也是用 Plotly.Express 创建支线剧情的唯一方法。不幸的是,你不能用 Express 在条形图顶部创建一个线形图。你需要 Plotly 的底层 API。

range_xrange_y参数允许放大图表。您可以随时使用交互式控制器查看全部数据。

您可以设定默认放大,因为交互式控制器允许您更改它。作者图片

设置为Truelog_xlog_y将改变这些轴在笛卡尔坐标中的对数比例。

动画片

最后,我们得到了制造 plotly 的参数。表达流行。动画。参数**animation_frame** 指向用于区分动画帧的列。我不得不稍微更新数据集来创建这个动画。列years_upto包含了所有的历史数据。有关更多信息,请参见 github 上的笔记本。

year_upto   year country visitors
1995        1995 ESP     30M
1996        1995 ESP     30M
1996        1996 ESP     33M
1997        1995 ESP     30M
1997        1996 ESP     33M
1997        1997 ESP     37M# then I use `year_upto` as the animation_frame parameter
px.line(spfrit, 
        x="years", 
        y="visitors", 
        color="Country Name",
        title="International Visitors",
        range_x=[1995, 2018],
        range_y=[25000000,90000000],
        **animation_frame="year_upto"**)

使用 animation_frame 参数的动画。作者图片

布局和风格

在我们开始介绍各种 Plotly 图表类型之前,让我们先探讨一下如何更新轴、图例、标题和标签的基本技巧。Plotly 准备了一个样式指南,但是许多图表类型只允许一些样式选项,这些选项很难从文档中找到。

每一张图都是一本字典

在背景上,每个图形都是一本字典。您可以将图表存储到一个变量中,通常是fig,并使用fig.to_dict()显示这个字典。

[In]: fig.to_dict()
[Out]:
{'data': [{'hovertemplate': 'index=%{x}<br>Spain=%{y}<extra></extra>',
   'legendgroup': '',
   'line': {'color': '#636efa', 'dash': 'solid'},
   'mode': 'lines',
...

由于这一点,你可以使用 3 种方式更新图表。

  • 使用fig.udpate_layout()
  • 使用特定参数,例如fig.update_xaxis()
  • 通过改变背景字典

它们中的每一个有时都很棘手,因为您必须真正钻研文档才能理解一些参数。每个参数可以用 4 种不同的方式更新。

# Four options how to update the x-axis title
# 1.and 2\. using update_layout
fig.update_layout(xaxis_title="X-axis title",
                  xaxis = {"title": "X-axis title"})# 3\. using update_xaxes
fig.update_xaxes(title_text="X-axis title")# 4\. by modifying the dictionary 
fig["layout"]["xaxis"]["title"]["text"] = "X-axis title"# in the end you show the plot 
fig.show()

模板

设置图表样式最简单的方法是使用预定义的模板。Plotly 带有几个内置模板,包括 plotly_white、plotly_dark、ggplot2、seaborn,或者您可以创建自己的模板。

Plotly _ 黑暗主题。作者图片

亚西斯和克西斯

我们可以逐个更新其他参数。仅从二维笛卡尔轴的 2D 图表的轴上看,你有许多选择来改变什么(见 plotly python )。我们来看看最重要的。

x 轴上显示的 plotly 轴的元素。作者图片

  • visibility —轴是否可见
  • color —线条、字体、刻度和网格的所有元素
  • title —轴标题(参数:文本、字体、颜色、大小、间距)
  • type —轴类型:线性、对数、日期、类别或多类别
  • range —轴的取值范围(自动量程,量程模式,量程)
  • ticks —记号和相应的网格线(记号模式、记号值、记号、记号角等)。)
  • spike——在点和轴之间画的线

如何格式化轴刻度的各种选项。作者图片

x 轴的一个很酷的选项是范围滑块。您使用fig.update_xaxes(rangeslider_visible=True)进行设置,它会突出显示您放大的那部分绘图。它对时间序列非常有用。

范围滑块让您了解缩放的位置。作者图片

稍后,我将讨论刻度的一些陷阱以及类别和线性模式之间的区别,但是现在,让我们继续,看看另一个用于突出图表关键区域的重要特征。

释文

将特定文本添加到图表中称为注释。注释有几个基本的用例:

  • 突出重点
  • 描述/突出一个地区
  • 要标记所需的点
  • 而不是一个传说

我们将在下图中展示所有 4 种做法。我们在图表外标注起点值,注释断点,放置一条关于旅游业增长的信息,并在其右端绘制图例。

注释的 4 种不同用例。作者图片

上面的图表很棘手。Plotly 按照出现的顺序排列线条,所以数据必须进行排序。还要表达一下从长数据帧中分配颜色有点困难(我知道我说的是长数据帧是理想的解决方案,它们不是 100%),所以我不得不施点小魔法,你可以研究这个要点或阅读高亮线图文章中的详细指南。

您可能还会注意到,随着行数的增加,Plotly 会自动切换到 WebGL 格式,这证明可以提高包含许多数据点的 JavaScript 绘图的可用性。

[In]: type(fig.data[0])
[Out]: plotly.graph_objs._scattergl.Scattergl

关于注释,您有几个选项可以影响它们的位置。您在.fig.update_layout(..., annotations=[])中将所有注释设置为一个列表,它包含一个指定标签参数的字典列表:

annotations = \
[{"xref":"paper", "yref":"paper", "x":0, "y":0.15,
  "xanchor":'right', "yanchor":"top",
  "text":'7M',
  "font":dict(family='Arial', size=12, color="red"),
  "showarrow":False}, ... other annotations ...]

您可以指定标签和数据点之间的位置、字体和箭头。文本的坐标xy既可以指向绘图,也可以指向画布。"xref"="paper" (0,0)是绘图区的左下角,(1,1)是右上角。在图表中,您使用轴上的xy值进行引用(例如 2008 年和 10_000_000 访问者)。

位置还取决于anchor(上-中-下、左-中-右)、偏移和调整。可以通过设置字体来修改每个注释,或者可以在文本上应用 HTML 标签,如<b><i>

Plotly 表示注释位置和其他参数。作者图片

条形图

现在,当我们知道如何创建一个图表,更新其布局,并包括注释,让我们探索另一个典型的图表类型。我们将从条形图开始,这是另一种流行的显示趋势和比较类别数据的方法。语法保持不变,只有一行代码:

px.bar(df, parameters)

条形图 API 文档描述了所有参数。大多数参数与折线图的参数相同。

酒吧模式

条形图有三种模式。Relative将条形堆叠在一起。overlay以较低的不透明度在彼此的顶部绘制线条,而group用于聚集的列。

不同的条形码具有相同的数据。作者图片

颜色;色彩;色调

像线条一样,线条也可以着色,以产生视觉冲击力。您可以使用color参数设置为一个类别(如国家名称)用调色板中的不同颜色给每个条着色,或将颜色设置为一个值(如游客)以区分游客参观的规模。

颜色参数的不同应用。您可以在标尺上区分类别或值。作者图片

color_discrete_sequence所有的条可以有相同的颜色,你可以根据规模应用不同的颜色——在我们的例子中使用color_continuous_scale的访问者数量。

单色条形图或色标。上面的图显示了 2018 年前 20 个最受欢迎的国家,下面的图显示了前 25 名,其余的则堆积在其他列中。代码见笔记本。作者图片

组合线条条形图

有一件事很神秘。在组合类型的图表中,快速真的很糟糕。您可以在折线图中添加条形,但不能反过来做。而结果呢,是啊,自己拿主意。

plotly 中的组合图表。表达是一种痛苦。作者图片

如果你想用一些混合类型的图形,使用 Plotly 的低级 API。这比 Express 能做的更多,但是代码更长。

动画条形图

参数animation_frame让你做动画魔术。但闪光的不全是金子。你必须为所有帧设置相同的范围[0-100 米],但图表仍在跳动,因为尽管 y 轴standoff有足够的空间,较长的国家名称仍会移动图表。此外,在第二个动画帧上,原本在条形外部的标签进入了条形内部。这将需要更多的定制是完美的。

动画条形图显示每年前往十个最热门旅游国家的游客数量不断增长。作者图片

柱状图

从技术上讲,直方图是一种没有间隔的条形图。直方图的强大之处在于,它自动将数据分成多个条块,并聚合每个条块中的值。但是它做得还不是很好。

[## 带 Plotly Express 的直方图:完整指南

一个数据集,60 多个图表,以及所有解释的参数

towardsdatascience.com](/histograms-with-plotly-express-complete-guide-d483656c5ad7)

直方图使用类似于条形图的参数。您可以使用color按类别分割媒体夹。

每个柱状图都可以用颜色参数分成不同的类别。作者图片

直方图也有自己的参数。nbins影响箱柜数量。

nbins 参数影响直方图的箱数。作者图片

Histfunc允许改变聚合函数。当然,当你在 10 和 20 之间的区间上做*均值、最小值或最大值时,这些值将位于这个范围内,所以这样的直方图将创建一个阶梯模式。

除了计数和求和之外,其他历史函数创建了阶梯式模式。它们在分类直方图中有用例,分类直方图在技术上是一个规则的条形图。作者图片

您也可以通过设置cumulative=True来创建累积直方图。

常规和累积直方图。作者图片

Barnorm让您将每个箱中的值标准化到 0–100%之间。Barnorm 参数在每个 bin 中归一化,因此值10, 40, 50形成10%, 40% and 50%,而100, 400 and 500创建同样高度的图表也是10%, 40% and 50%。您可以选择用barnorm="percentage"显示百分比或用barnorm="fraction"显示小数。

应用于堆积直方图的 Barnorm。作者图片

Histnorm参数非常相似,但是归一化不是在一个仓内,而是针对所有仓中的每个类别。如果您的类别 A 在第一个 bin 中出现两次,在第二个 bin 中出现 5 次,在最后一个 bin 中出现 3 次,则 histnorm 将为20%, 50% and 30%

直方图(和散点图)的特定参数是边际图。它可以让你创建一个小的侧图,显示底层变量的分布细节。有四种类型的边际图表— rughistogramboxviolin创建具有相同名称的侧图。

直方图的 4 个马丁戈尔支线图选项。作者图片

通常情况下,您需要对宁滨进行更多的控制,您宁愿自己计算面元并使用px.barfig.update_layout(bargap=0)绘制它们。

使用 px.bar()创建的直方图。作者图片

圆形分格统计图表

另一个实现可视化的方法是使用饼图。

# syntax is simple
px.pie(df, parameters)

当你阅读文档时,你会了解到饼状图没有xy轴,只有namesvalues

拉派的痕迹

其中一个很酷的事情是,你可以拉一些情节的片段来突出它们。它不是.pie()的参数,但您可以使用fig.update_traces()添加它。Text轨迹的配置也允许将标签设置为百分比、值或标签(或三者的任意组合,例如fig.update_traces(textinfo="percent+label"))

您可以快速更改看到的标签。作者图片

圆环图-孔参数

饼状图有点好玩,使用hole param 你可以把它变成一个圆环图。像所有以前的图表一样,当您与标签交互时,它会重新计算值。

圆环图是一个带孔的饼图。作者图片

旭日图

与饼图非常相似的是旭日图。它可以显示几层数据。例如,在我们的情况下,一个区域和该区域的国家。当你点击任何一个“家长”时,你就会得到那个地区的详细信息。您可以通过输入namesvaluesparents等创建情节,如下图所示:

fig = px.sunburst(
    chart_df,
    path=['Region', 'Country'],
    values='Visitors',
)

作者在 Plotly.Express. Image 中的旭日剧情互动

树形图

如果在显示大量数据时,饼图和旭日图难以阅读,那么树形图则正好相反。您可以使用颜色,并根据分类列分配离散刻度或连续刻度。

树形图是显示大量数据之间关系的理想选择。作者图片

Choropleth 使用 plotly 绘制地图

我们正在研究关于世界的数据,在如何显示这些数据方面,使用地图是一个显而易见的选择。Plotly 支持显示地理空间数据,内置国家形状、区域范围以及调整颜色和其他参数的选项。

地理空间数据利用了 Plotly 的地图支持。作者图片

根据文档,国家由 ISO-3 代码、国家名称或美国州名识别。如果你想挖得更深,你必须得到你自己的地理坐标geojson

散点图

散点图是最常见的图类型之一。它们可以很容易地显示二维数据之间的关系,使用颜色和大小,您可以用更多的信息来包装您的可视化。然而,我们将从我们离开的地方开始。在地理中使用scatter_geo图形。

fig = px.scatter_geo(
    melted_df.fillna(0), 
    locations ="Country Code", 
    color="visitors",
    size="visitors",
    # what is the size of the biggest scatter point
    size_max = 30,
    projection="natural earth",
    # range, important to keep the same range on all charts
    range_color=(0, 100000000),
    # columns which is in bold in the pop up
    hover_name = "Country Name",
    # format of the popup not to display these columns' data
    hover_data = {"Country Name":False, "Country Code": False},
    title="International Tourism",
    animation_frame="years"
                     )
fig.update_geos(showcountries = True)
fig.show()

散点 _ 地理图动画。作者图片

重要的scatter_geo参数是max_size允许设置气泡的最大半径,以及opacity确定多少绘图是可见的。

散点图

常规散点图通常用于显示两个变量之间的关系。在我们的例子中,游客的数量和他们在这个国家的花费。我只关注 2018 年。size参数影响气泡的大小,而color参数允许您根据分类或连续变量设置颜色。

基本散点图,显示游客数量和他们的支出之间的关系。颜色区分每个区域。作者图片

散点图允许很容易地添加边际图,以突出由color参数指定的一个变量或几个变量的分布。您可以从 4 种边际地块中选择— boxviolinhistogramrug。您只需通过应用marginal_xmarginal_y参数,例如marginal_x=”rug”,即可对其进行设置。您还可以在图表上为每种颜色绘制一条趋势线。

px.scatter(df,
          x="visitors",
          y="receipts",
          color="type",
          hover_name="Country Name",
          size="receipts",
          **marginal_x="histogram",
          marginal_y="box",**
          trendline="lowess",
          title="Scatter plot with histogram and box marginal plot and two trendlines")

散点图允许通过添加单个参数来添加 4 种边际图和趋势线。作者图片

要绘制趋势线,你需要安装 statsmodel

conda install -c anaconda statsmodels
# or
pip install statsmodels

借助statsmodels库,您还可以显示用于计算趋势线的回归模型的参数。

# get the parameters via `get_trendline_results`
res = px.get_trendline_results(fig)# get the statsmodels data
[In]:
trendline = res["px_fit_results"].iloc[0]
print(type(european_trendline))[Out]: <class 'statsmodels.regression.linear_model.RegressionResultsWrapper'># print the summary
trendline.summary()

Plotly 使用 statsmodels 来计算趋势线。您可以导出其参数。作者图片

交互式按钮

Plotly 的成功可以归功于交互功能。每个图表的右上角都包含一个菜单,可以进行放大和缩小等基本操作,当您将鼠标悬停在图表元素上时会出现什么工具提示,或者您可以通过单击将图保存为图像。

您还可以添加交互式按钮(或下拉菜单),让用户改变图形的外观。您可以使用参数method添加四种类型的动作:

  • restyle —影响数据或图表类型的外观和感觉
  • relayout —改变布局的属性
  • update —结合了上述两种方法
  • animate —允许控制动画特性

您可以在图表上放置几组按钮。它们可以并排排列(或上下排列),也可以下拉排列。

使用 Plotly 按钮更改颜色和标签。作者图片

相互作用

文档展示了一些基本的交互,但是如果你计划做一些其他的事情,实现它是相当棘手的。最好的技巧是创建你想要达到的最终外观,使用fig.to_dict()转储字典,并将字典的相关部分复制到按钮的arg[{...}]中,例如:

# create the chart and export to dict
px.bar(df, x="visitors", range_x=[0,10]).to_dict()# read the dict to find the relevant arguments for the update 
# arg. xaxis.range of the relayout changes the x_range fig.update_layout(
  updatemenus=[
  dict(
    buttons=list([
      dict(
        args=[{"xaxis.range":[-2,10],
               "yaxis.range":[0,5.6]}],
                label="x:right 1, y:bottom 0",
                method="relayout", 
        )]),           
        type="buttons",
        showactive=True,
        x=1,
        xanchor="right",
        y=0,
        yanchor="bottom"
    )])# see the full example on github for more ideas

查看 github 笔记本,了解更多关于如何使用按钮的想法,或者探索 Plotly 文档中的示例。

我成功地更改了标签、颜色和范围,但未能更改输入值(如更改源数据)。

按钮的位置

您可以使用坐标系将按钮放置在绘图区的四周,其中 x: 0,y: 0 是图表的左下角(一些像饼图这样的绘图不会填充整个区域)。您也可以将xanchoryanchor设置为左-中-右或上-中-下。

图形按钮的位置、背景颜色和按钮组。作者图片

单击按钮有时会改变它们的位置

您可以使用pad={"r": 10, "t": 10}微调位置。这些值以像素为单位,您可以填充r-右、l-左、t-上、b-下。您还可以更改按钮的字体和颜色。

导出 Plotly

您可以将生成的图表导出为一个交互式 HTML 页面,让您完成所有的绘图魔术,如缩放、打开/关闭数据或查看工具提示。

fig.write_html(f"{file_name}.html")

您可以指定几个参数,指定是否包含 3MB·普洛特利. js,动画是否在打开时启动,或者 html 文档的结构如何— 文档

您也可以使用.write_image()将图像导出为静态图片。它可以让你导出几种格式,如.png.jpg.webp.svg.pdf.eps。您可以更改尺寸和比例。Plotly 使用kaleido作为默认引擎,但是你也可以选择一个传统的orca引擎。

# install caleido
pip install -U kaleido
#or conda install -c plotly python-kaleido# export the static image
fig.write_image(f"{file_name}.png")

熊猫默认后台

你可以设置 Plotly 作为熊猫默认绘图后端。

pd.options.plotting.backend = "plotly"

然后将 plotly 参数应用于数据框本身。

fig = df.plot(kind="bar", x="x", y="y", text="y")
fig.show()

然而,它很容易将 dataframe 作为第一个参数输入,以至于您可能更喜欢 pandas 默认设置,将 matplotlib 作为后端。

# return to defaul matplotlib backend
pd.options.plotting.backend = "matplotlib"

几个陷阱

一旦你熟悉了 Plotly。表示你很少遇到你无法解决的问题。我们已经说过,用支线剧情表达斗争。还有一些其他情况会让你心跳加速。但即使是这些也有一个简单的解决方案。

如果您想要显示整数类别的数值计数,例如 1,2,3 号玩家赢得奖牌的次数,使用 Matplotlib 的标准 padnas 绘图很简单。

"""if you want to display which values are the most frequent and these values are integers"""df = pd.DataFrame({"x": [3]*10+[6]*5+[2]*1})
df["x"].value_counts().plot(kind="bar")

熊猫的价值计算图。作者图片

但是如果你用 Plotly 做同样的尝试,它会自动假设你想在 x 轴上显示一个连续的整数范围。

"""it's rather impossible with plotly which always set up the range containing all the numerical values"""fig = px.bar(df["x"].value_counts())
fig.show()

如果您没有指定任何内容,plotly 会自动将看起来像整数/浮点数的数据点转换成整数/浮点数。作者图片

要获得预期的图表,您必须将值转换成类别,尽管在 pandas 中不是这样。

df["y"] = df["y"].astype("category")  # or .astype("string")

您必须更改 Plotly 布局参数中的轴:

fig.update_xaxes(type="category")
fig.show()

瞧,分类轴显示的数值和你输入的完全一样。作者图片

Plotly 还自动处理日期值,这在季末(年/季度)的情况下特别烦人。

"""Also the daterange labels on the x-axis can annoy you when you try to display end of the year/quarter dates. 
Plotly will always turn them into the Jan next year or the beginning of the following quarter"""df = pd.DataFrame({"x":[**"2019-12-31","2019-03-31","2018-12-31","2017-12-31"**],
                   "y":[10,12, 15, 8]})
fig = px.bar(df, x="x", y="y")
fig.show()

Plotly 自动缩放日期轴,当您想要显示年/季度的结束并 Plotly 将标签转到下一季的开始时,这很烦人。作者图片

Plotly 自动缩放轴标签以显示时间分布,但是如果您想要显示年末(季度)日期,您将会非常失望地看到下一年的开始。例如,如果你想在每年年底显示公司的财务数据,而你看到的是“2020”,而不是“2019 年底”,你可能会对公司的健康状况产生完全错误的印象。修复是相同的fig.update_xaxes(type="category")

x 轴上的 Plotly 日期作为一个类别。作者图片

Plotly 很聪明,一旦你用一个日期填充轴,它就认为它是一个日期轴。有时,您可能希望在同一轴上显示日期和字符串值。解,又是.update_xaxes(type="category")

日期轴忽略所有非日期值,而分类轴按原样显示所有内容。作者图片

文件摘要

结论

Plotly express 是一种使用单一图表类型快速显示数据的好方法。它有互动和动画等重要功能,但缺乏支线剧情的支持。Express 很聪明,它在大多数情况下用数据的逻辑子集分割数据框。但是如果它猜错了,几乎不可能说服 Plotly 按照你想要的方式显示数据。

有时这需要一点尝试和错误。这通常有助于将图表导出到 dict 中,并尝试找到您想要更新的参数的正确名称。如果无法使用 Plotly 创建所需的可视化效果。Express 你总是可以替换为更低级的 API ,它更加仁慈,但是也需要更多的编码。

另一方面,如果你需要更复杂的交互式报告,你会选择 Plotly 的仪表板工具 Dash ,这需要更多的编码,但你可以用 Dash 实现真正专业外观的仪表板。

资源:

Plotly 4.0.0 发行说明

If you liked this article, check other guidelines:* [Highlighted line chart with plotly](/highlighted-line-chart-with-plotly-express-e69e2a27fea8)
* [Visualize error log with Plotly](/visualize-error-log-with-pandas-and-plotly-d7796a629eaa)
* [All about Plotly Express Histograms](/histograms-with-plotly-express-complete-guide-d483656c5ad7)
* [How to split data into test and train set](/complete-guide-to-pythons-cross-validation-with-examples-a9676b5cac12)All the pictures were created by the author. Many graphics on this page were created using [canva.com](https://partner.canva.com/vdek) (affiliate link, when you click on it and purchase a product, you won't pay more, but I can receive a small reward; you can always write canva.com to your browser to avoid this). Canva offer some free templates and graphics too.

Github repo 中提供了图表和练习。随时尝试、更新和更改— Plotly Express —综合指南. ipynb

Matplotlib 可视化

原文:https://towardsdatascience.com/visualizations-with-matplotlib-4809394ea223?source=collection_archive---------47-----------------------

了解如何使用 Python 库 matplotlib 可视化数据

Unsplash庞浩文的照片

如果你想用 Python 绘制数据,Matplotlib 是一个非常强大的数据可视化库。最常用的模块是' pyplot ',它提供了一组函数,让您可以轻松地绘制出数据。

装置

使用 conda:

conda install matplotlib

使用画中画:

pip install matplotlib

作为先决条件,你必须具备什么是 Python 字典列表的基础知识,以及 Python 的 Numpy 库的特性和功能。

简单线图

导入必要的模块。

import numpy as np
import matplotlib.pyplot as plt

简单折线图是最常用的绘图,通常用于绘制在一段时间内跟踪的数据,如股票价格。

让我们使用 pyplot 通过传入一个简单的 python 列表来创建相同的内容。

plt.plot([2,4,5,10])

作者图片

在这里你可以看到我们的 4 个值的图。

如果您向 plot 函数提供单个值列表,matplotlib 将假定它们是 y 值,并自动为您生成 x 值。默认的 x 向量的长度与传递给函数的列表长度相同,但它从 0 开始。上面我们可以看到 x 坐标的值是 0,1,2 和 3。

要绘制 x 与 y 的关系,可以向函数中传递两个列表。首先是 x 向量,然后是 y 向量。

plt.plot([1,3,7,10], [2,4,5,10])

作者图片

这里我们可以看到一组不同的 x 值和 y 值。第一个 x 值对应于第一个 y 值,依此类推。

散点图

散点图使用点来表示两个不同数值变量的值。

您可以向 plot 函数传递第三个参数,以指示颜色的格式和绘图的线型。

为了获得红色的散点图,我们添加“ro”作为第三个参数。

plt.plot([1,3,7,10], [2,4,5,10], 'ro')

作者图片

这里我们可以看到我们的图从蓝线变成了红圈。

通常,在 matplotlib 中处理绘图时,我们使用 NumPy 数组而不是 Python 列表,如下所示。

a = np.array([[12,23,34,45],
              [56,67,78,89]])
plt.plot(a[0], a[1], 'go')

作者图片

我们还可以在轴上添加标签。

plt.xlabel('x-axis')
plt.ylabel('y-axis')plt.plot(a[0], a[1], 'p--')

作者图片

图表中的多组数据

要在图形上绘制多组数据,请在 plot 函数中传递多组参数。让我们创建一个数组,其中有几个均匀分布的数字,以了解我们如何做到这一点。

t = np.linspace(0, 5, 10) 
plt.plot(t, t**2, color = 'red', linestyle = '--') 

作者图片

“linspace”是一个 NumPy 函数,“linestyle”是一个 pyplot 参数。

如果我想在这条线上绘制另一条线,我可以通过再次调用 plot 函数来轻松完成。

plt.plot(t, t**2, color = 'red', linestyle = '--')
plt.plot(t, t*3, color='green', linewidth = 2)

作者图片

这里,“线宽”是一个 pyplot 参数。正如你所看到的,第二行打印在我们的上一行之上。

绘制多个图形

我们可以使用支线剧情功能在一个图中添加多个剧情。这个选项有三个参数:行数、列数和索引。

plt.subplot(1,3,1)
plt.plot(t,t,'c--')

作者图片

使用相同的支线剧情方法,我们可以在现有剧情旁边创建更多不同类型的剧情。

plt.subplot(1,3,1)
plt.plot(t,t,'c--')plt.subplot(1,3,2)
plt.plot(t,t**2,'b-')plt.subplot(1,3,3)
plt.plot(t,t**3,'mo')

作者图片

条形图

此外,我们可以使用条形图绘制数据,条形图是最常见的图形类型之一。条形图用于显示分成不同类别的数据。例如,如果我想销售不同的产品,我会使用条形图来完成。

sales = {'Computers': 92,
         'Laptops': 76,
         'Mobiles': 97,
         'TVs': 82,
         'Speakers': 70}
plt.bar(range(len(sales)), list(sales.values()), color = 'pink')

作者图片

在我们的示例中,x 坐标的范围是从 0 到 4,y 坐标显示每个条形的高度。我们可以看到字典中值的条形图。每个条形的高度代表该类别的销售额。

如果我们想将这些数字更改为类别的名称,我们可以这样做,如下所示。

plt.bar(range(len(sales)), list(sales.values()), color = 'pink')
plt.xticks(range(len(sales)), list(sales.keys()))

作者图片

在这里,我们可以看到,在每个条形下,都有相应的类别名称。同样,如果我们想改变 x 和 y 标签,我们可以使用相同的' plt.xlabel '和' plt.ylabel '函数。

plt.bar(range(len(sales)), list(sales.values()), color=’pink’)
plt.xticks(range(len(sales)), list(sales.keys()))
plt.xlabel(“Categories”)
plt.ylabel(“Sales”)

作者图片

本文中我们要看的最后一种图表是直方图。当我们查看身高、体重、股票价格等数据时,直方图是一种非常常见的图表类型。在我们的例子中,让我们生成大约 1000 个条目的随机连续数据。

x = np.random.randn(1000)
plt.hist(x, color = 'green')

作者图片

在这里,我们可以看到直方图的数字分布从-4 到 3。它在 0 附*达到峰值,这意味着我们的大部分区域都在那里。

本文到此为止。

点击这里查看本教程的代码。

谢谢你阅读它!

参考

[1] Matplotlib 文档:【https://matplotlib.org/

使用 Matplotlib 实现 Python 数据可视化—第 1 部分

原文:https://towardsdatascience.com/visualizations-with-matplotlib-part-1-c9651008b6b8?source=collection_archive---------11-----------------------

Jukan Tateisi 在 Unsplash 上拍摄的照片

Matplotlib 简介

完成了从基础到高级的 Python 绘图的 Matplotlib 教程,包含 100 多个示例

数据可视化旨在将数据以更直观的方式呈现,如散点图、密度图、条形图等。向读者或分析师提供他们数据的全局描述也是有用的。通过可视化您的数据,您可以检测潜在的异常值。在 Python 中,可以使用各种模块或库来可视化数据。其中一个主流模块是 Matplotlib。您可以使用 Matplotlib 以各种绘图风格可视化数据。但是,Matplotlib 不能显示动态图。如果你想创造一个巨大的动态剧情,可以用 plotly 的 Dash (希望下个月用 Dash 完成一个关于完整教程的故事)。

这个故事将指导你如何用 Matplotlib 以各种方式可视化数据。90 个例子也许能启发你从不同的角度创造一个情节。这不是 Matplotlib 在数据可视化方面最完整的教程,但我相信这个故事可以满足许多人的需求,接触到许多要应用的门徒。

正如我之前提到的,我将指导你创建 90 个不同的情节示例。这些示例分布在 11 个不同样式的图中:散点图、折线图、直方图 1D、2D、边际图、条形图、箱线图、小提琴图、饼图、极坐标图、地理投影、3D 图和等高线图。您可以从图 1 中了解这个故事的大致情况。

图一。Matplotlib 中生成的各种类型的绘图(图片由作者提供)。

在这个故事中,我试图专注于创造和定制各种情节。所以,我假设你已经知道它之外的一些技术,例如,在 Matplotlib 中创建多个支线剧情和定制颜色图。如果你还不知道,我会给你一些链接来了解它。

在开始写这个故事的时候,我打算只写 1 个故事。但是,因为阅读时间的原因,我想我需要把它分成几部分。如果我全部写在一个故事里,就要 40 多分钟。我估计你光看一个故事就全看完了会很无聊:)。所以,我把它分成 2 或 3 部分。我会把阅读时间限制在 30 分钟以内。这是第一部分。我们开始吧。

Matplotlib 简介

要安装 Matplotlib,您可以使用以下代码通过 pip 安装它

pip install matplotlib

或通过康达

conda install -c anaconda matplotlib

当我写这个故事时,我安装了 Matplotlib 3 . 3 . 2 版。你可以通过写这段代码来检查它。

pip show matplotlib

如果你想在 Jupyter 笔记本(以下简称 Jupyter)上查看,可以添加!在 pip 之前,如图 2 所示。

图二。通过 Jupyter 检查 Matplotlib 版本(图片由作者提供)。

如果你想升级你的 Matplotlib 版本,你可以使用下面的代码

pip install matplotlib --upgrade

还是那句话,可以补充!在 pip 通过 Jupyter 升级 Matplotlib 之前。

如果你用我在这个故事中使用的 Matplotlib 安装了不同的 Matplotlib 版本,也许你会面临不同的结果。请在下面的回复栏中写下您遇到的问题。我建议你保存这个故事。所以,如果时间有限,可以继续读下去。

在我们继续第一部分之前,我需要通知您,我已经定制了我的 Matplotlib 绘图样式,例如使用 LaTeX 字体作为默认字体,更改字体大小和字体系列,更改 xtick 和 ytick 的方向和大小,并在 x 轴和 y 轴上添加次要刻度。要使用 LaTeX 字体作为 Matplotlib 中的默认字体,可以使用以下代码

plt.rcParams['text.usetex'] = True

如果你面临一些错误,你需要阅读下面的故事。我已经解释了在 Matplotlib 中处理 LaTeX 字体的详细过程

[## 使用 Matplotlib 可视化数据的 5 个强大技巧

如何使用 LaTeX 字体,创建缩放效果,发件箱图例,连续错误,以及调整框填充边距

towardsdatascience.com](/5-powerful-tricks-to-visualize-your-data-with-matplotlib-16bc33747e05)

要定制其他参数(字体大小、字体系列和刻度参数),只需在代码的开头编写以下代码

plt.rcParams['font.size'] = 15
plt.rcParams['font.family'] = "serif"tdir = 'in'
major = 5.0
minor = 3.0
plt.rcParams['xtick.direction'] = tdir
plt.rcParams['ytick.direction'] = tdirplt.rcParams['xtick.major.size'] = major
plt.rcParams['xtick.minor.size'] = minor
plt.rcParams['ytick.major.size'] = major
plt.rcParams['ytick.minor.size'] = minor

如果你需要更详细地了解它,你可以访问这个故事

[## 使用 Matplotlib 创建专业绘图

使用样式表和 rcParams 自定义 Matplotlib,并选择色盲友好调色板

towardsdatascience.com](/create-professional-plots-using-matplotlib-63a6863b7363)

01.散点图

在本节中,有八个散点图示例。在创建散点图之前,我需要使用这段代码生成模拟数据

import numpy as np
import matplotlib.pyplot as pltN = 50x = np.linspace(0., 10., N)
y = np.sin(x)**2 + np.cos(x)

变量 x 是 50 个数据的数组,从 0 到 10。变量 y 是 sin(x)和 cos(x)的*方之和。我想用这段代码以散点图的形式显示 x 轴上的变量 x 和 y 轴上的变量 y

plt.figure()
plt.scatter(x, y)

它是如此简单。代码将向您显示一个结果,如图 3 所示。

图 3。Matplotlib 中的默认散点图(图片由作者提供)。

为了使它更漂亮,您可以减少每个数据的大小,并使用以下代码给出标签

plt.scatter(x, y, s = 15, label = r'$y  = sin^2(x) + cos(x)$')

要更改颜色,您需要在散点语法中添加此参数

color = 'r' # r means red

如果想使坐标轴刻度处于相同的刻度,可以使用这段代码

plt.axis('equal')

要为 x 轴和 y 轴创建轴标签,可以添加以下代码

plt.xlabel(r'$x$ (rad)')
plt.ylabel(r'$y$')

您已经标记了您的散点图,但没有将其显示为图例。为了展示它,您可以使用以下代码

plt.legend()

要保存您的绘图,您可以使用保存图形语法,如以下代码所示

plt.savefig('scatter2.png', dpi = 300, bbox_inches = 'tight', facecolor='w')

上面的代码将以 scatter2.png 的名字保存您的绘图,分辨率为每英寸 300 点,紧密的 bbox,白色背景。如果您省略了 bbox_inches 和 face color 参数,这是可以的,但是可能会得到不同的结果。试试吧。

这是完整的代码

该代码将创建一个散点图,如图 4 所示。

图 4。修改了 Matplotlib 中的散点图(图片由作者提供)。

可以看到轴内 x 轴和 y 轴的刻度方向,使用的字体是 LaTeX 格式。如果您想要更改图形大小,您可以在 plt.figure()中添加图形大小参数

plt.figure(figsize=(7, 4.5))

改变标记样式

例如,要更改标记样式,我想将点改为十字,您可以在 plt.scatter 中添加此参数

marker = 'x'

图 5 是应用上面代码的结果

图 5。用 Matplotlib 修改散点图中的标记样式。

Matplotlib 中有大量的标记样式可以使用。你可以点击下面的链接查看。

[## Matplotlib . markers-Matplotlib 3 . 3 . 2 文档

处理标记的函数;由和的标记功能使用。这里定义了所有可能的标记:标记…

matplotlib.org](https://matplotlib.org/api/markers_api.html)

如果你已经阅读了上面的文档,你可以意识到你可以使用字母表作为你的标记样式。我将向您展示应用字母表作为标记的示例,如图 6 所示。

图 6。Matplotlib 中的字母标记(图片由作者提供)。

为了生成图 6,我为 x 轴和 y 轴上的参数创建了一个不同的函数。下面是生成它的代码

np.random.seed(100)N = 50randx = np.random.random(N) * 100
randy = np.random.random(N) * 100

为了可视化变量 randx 和 randy,我运行以下代码

plt.figure(figsize=(7, 6))plt.scatter(randx, randy, marker=r'$\beta$', s = 150, color = 'darkorange')plt.axis('equal')plt.xlabel('randx')
plt.ylabel('randy')plt.tight_layout()

我使用希腊符号 beta 作为我的标记样式。你可以用不同的字母来改变它,如 a、B、C、d、1、2、3、 等。

定制每个数据的大小

这一小节将向您展示如何为每个数据创建不同大小的散点图,如图 7 所示。

图 7。在 Matplotlib 中自定义散点图的大小(图片由作者提供)。

为了创建它,我使用下面的代码为变量 randx 和 randy 生成一个从 0 到 100 的随机位置

np.random.seed(100)N = 30randx = np.random.random(N) * 100
randy = np.random.random(N) * 100

提醒你一下,我使用 Numpy 生成随机数据。在生成随机数时,Numpy 只在 0 到 1 的范围内生成它。据我所知,这是一个产生随机数的惯例(不仅仅是在 Numpy 中),只是从 0 到 1。要修改,可以乘以 100。所以,你会得到一个 0 到 100 范围内的随机数。

之后,我使用下面的代码为每个数据生成一个从 50 到 200 的随机整数

size = np.random.randint(50, 200, size=N)

要将其可视化,只需使用以下代码添加将应用于每个数据的大小的参数

plt.scatter(randx, randy, s = size, color = 'darkorange')

创建图 7 的附加语法是在 x 轴和 y 轴上插入次要刻度。要插入它,您需要使用以下代码导入子模块 MultipleLocator

from matplotlib.ticker import MultipleLocator

之后,您可以添加以下语法来插入短轴

ax = plt.gca()ax.xaxis.set_minor_locator(MultipleLocator(10))
ax.yaxis.set_minor_locator(MultipleLocator(10))

下面是生成图 7 的完整代码。

颜色编码散点图

您可以使用色彩映射表来更改颜色。这意味着不同大小的数据将用不同的颜色进行颜色编码。您可以像这样在 plt.scatter()中添加颜色参数

c = size

要嵌入颜色条,您可以使用以下代码

plt.colorbar()

您将得到一个图,如图 8 所示。

图 8。使用 Matplotlib 修改散点图中的颜色编码(图片由作者提供)。

下面是生成图 8 的完整代码。

定制彩色地图

您可以使用此参数更改色彩映射表

cmap = 'inferno'

您可以查看此链接,了解 Matplotlib 提供的所有色彩映射表

[## 在 Matplotlib 中选择色彩映射表— Matplotlib 3.3.2 文档

Matplotlib 有许多内置的色彩映射表,可以通过。还有外部库,如[palettable]和…

matplotlib.org](https://matplotlib.org/3.3.2/tutorials/colors/colormaps.html)

在本教程中,我已经通过结合蓝色和橙色的颜色创建了自己的颜色图,如图 9 所示。

图 9。在 Matplotlib 中自定义色彩映射表(图片由作者提供)。

为了组合它,我使用了以下代码

from matplotlib import cm
from matplotlib.colors import ListedColormap, LinearSegmentedColormaptop = cm.get_cmap('Oranges_r', 128)
bottom = cm.get_cmap('Blues', 128)newcolors = np.vstack((top(np.linspace(0, 1, 128)),
                       bottom(np.linspace(0, 1, 128))))
orange_blue = ListedColormap(newcolors, name='OrangeBlue')

我创建了自己的色彩映射表,命名为 橙 _ 蓝 。要了解如何在 Matplotlib 中创建和定制自己的色彩映射表,您可以通过以下链接阅读

[## 在 Matplotlib 中创建色彩映射表

从颜色列表中创建和定制自己的色彩映射表的指南

towardsdatascience.com](/creating-colormaps-in-matplotlib-4d4de78a04b8)

要应用它,我只需更改颜色参数 c = orange_blue 。您可以在图 11 中查看结果。

图 11。使用 Matplotlib 自定义散点图中的颜色图。

下面是生成图 11 的完整代码。

这是本节的结尾,用 Matplotlib 创建散点图。如果您遇到一些错误,您可以在回复栏中留下评论。

02.线形图

为了在 Matplotlib 中绘制线图,我将使用以下代码生成模拟数据

N = 50x = np.linspace(0., 10., N)
y = np.sin(x)**2 + np.cos(x)

要以线形图的形式可视化变量 x 和 y,您需要使用下面的简单代码

plt.plot(x, y)

上面的代码将生成一个图形,如图 12 所示。

图 12。Matplotlib 中的默认线图(图片由作者提供)。

定制线条样式

您可以使用此参数在 Matplotlib 中更改线形图的线型

linestyle = '-'

上面的参数应插入 plt.plot()语法中。在本教程中,我将向您展示四种不同的线条样式;他们是

['-', '--', '-.', ':']

为了自动生成它,我使用循环来简化它。这是完整的代码

我将在一张图中分配 4 种不同的线条样式。这意味着我需要在一个图形中创建 4 个轴。在 Matplotlib 中,可以通过使用 GridSpec()、subplot()和 add_subplot()自定义子情节来生成它。在这个会话中,我使用 GridSpec()语法。我创建了 4 个轴(2 行 2 列),宽度和高度空间等于 0.25(见第 6 行到第 12 行)。正如我在开头提到的,我将只专注于定制剧情。如果你需要更多关于在 Matplotlib 中定制支线剧情的解释,你可以访问这个链接

[## 在 Matplotlib 中自定义多个子情节

使用 subplot、add_subplot 和 GridSpec 在 Matplotlib 中创建复杂 subplot 的指南

towardsdatascience.com](/customizing-multiple-subplots-in-matplotlib-a3e1c2e099bc)

如果您运行上面的代码,它将创建一个图形,如图 13 所示。

图 13。使用自动化在 Matplotlib 中自定义线条样式(图片由作者提供)。

代码将简单地生成 4 种不同的线条样式,并为每种线条样式添加标签和注释。Matplotlib 提供了许多可供您使用的线条样式。你可以通过这个链接选择你喜欢的线条样式

[## Matplotlib . py plot . plot-Matplotlib 3 . 3 . 2 文档

用线条和/或标记绘制 y 与 x 的关系。调用签名:点或线节点的坐标由 x…

matplotlib.org](https://matplotlib.org/2.1.2/api/_as_gen/matplotlib.pyplot.plot.html)

定制线宽

要自定义折线图的线宽,可以使用此参数

lw = 2.0

我向您展示了 4 种不同线宽,如图 14 所示。

图 14。在 Matplotlib 中自定义线宽(图片由作者提供)。

我使用类似的技术来创建图 14。这是完整的代码。

创造标记每隔

本小节将指导您创建每个特征的标记。为了理解它,我将首先展示结果,如图 15 所示。

图 15。在 Matplotlib 中标记每一个(图片由作者提供)。

在图 15 中,我为每 5 个数据创建了一个圆形标记。你可以用这个参数创建它

'o'            # shape for each 5 data
markevery = 5  # mark every 
ms = 7         # size of the circle in mark every

这是完整的代码

您需要将参数“o”放在第三个位置。

改变线条颜色

要更改线条颜色,您可以应用类似的概念来更改散射颜色,如以下代码所示

color = 'royalblue'

我想向您展示如何使用循环生成 4 种不同的颜色和 4 种不同的标记,如图 16 所示。

图 16。在 Matplotlib 中自定义线条颜色(图片由作者提供)。

您可以用这段代码重现图 16

我用的 4 种不同的颜色是色盲友好的。我是从这个链接得到的。要了解如何使用该链接创建色盲友好的调色板,请阅读这个故事

在线图中插入错误

为了演示折线图中的误差线,我需要使用以下代码生成误差

np.random.seed(100)
noise_x = np.random.random(N) * .2 + .1
noise_y = np.random.random(N) * .7 + .4

该代码将为 noise_x 生成从 0.1 到 0.3 的随机数,为 noise_y 生成从 0.3 到 0.7 的随机数。要为 y 轴插入误差线,可以使用以下代码

plt.errorbar(x, y, yerr = noise_y)

图 17 是折线图中误差线的示例。

图 17。在 Matplotlib 中创建误差条形图(图片由作者提供)。

您可以用这段代码创建图 17。

要在 x 轴上插入误差线,可以使用此参数

xerr = noise_x

您可以在图 18 中看到在 x 轴和 y 轴上插入误差线的例子。

图 18。在 Matplotlib 中创建误差条形图(图片由作者提供)。

您可以使用这段代码重现图 18。

如果要直观显示数据而不需要折线图,只需要误差线,可以使用此参数

fmt = 'o'    # shape of the data point
color = 'r'  # color of the data point
ecolor ='k'   # color of the error bar

这是完整的代码

上面的代码将显示一个图,如图 19 所示。

图 19。在 Matplotlib 中自定义误差栏(图片由作者提供)。

填充错误区域

为了直观显示错误,您也可以使用以下代码

plt.fill_between(x, y + noise, y - noise, alpha = .5)

fill_between 参数是填充区域的 x 轴、上限和下限的数据。在上面的代码中,用 y +噪声y-噪声 来表示。你需要降低填充区域的透明度。这是完整的代码

如果您运行上面的代码,您将得到一个结果,如图 20 所示。

图 20。在 Matplotlib 中的区域之间创建填充。

插入垂直线和水*线

你可以用这段代码插入一条水*线和一条垂直线

plt.hlines(0, xmin = 0, xmax = 10)
plt.vlines(2, ymin = -3, ymax = 3)

您需要在第一个参数中定义水*线,然后是水*线的起点和终点。对于垂直线,它有类似的论点。

图 21 是一个插入水*线和垂直线的例子。

图 21。Matplotlib 中的水*线和垂直线(图片由作者提供)。

要生成图 21,您可以使用以下代码

在图 21 中,图例位于轴的外部。在第 17 行可以体会到。

两条垂直线之间的填充

这一小节将指导您在两条垂直线之间创建一个填充区域,如图 22 所示。

图 22。在 Matplotlib 中创建填充区域(图片由作者提供)。

要重现图 22,您可以使用以下代码

你需要知道在 Matplotlib 中创建填充区域的重要之处,你需要设置一个合适的 y 轴限制。

03.柱状图

这一节将解释如何在 1D 和 2D 制作直方图。我先给你讲讲 1D 直方图。在可视化 1D 直方图之前,我将使用这段代码制作一个模拟数据,一个正态分布的随机数。

N = 1000np.random.seed(10021)
x = np.random.randn(N) * 2 + 15

默认情况下,Numpy 将生成一个正态分布的随机数,其均值/中值(mu)等于 0,方差(sigma)等于 1。在上面的代码中,我将 mu 改为 15,sigma 改为 2。要可视化 1D 直方图中的变量 x,可以使用以下代码

plt.hist(x)

代码将显示一个图形,如图 23 所示。

图 23。Matplotlib 中默认的 1D 直方图(图片由作者提供)。

默认设置下,Matplotlib 将为 1D 直方图生成 10 个柱。如果你想改变仓位的数量,你可以使用这个参数。

bins = 40

该参数将生成一个有 40 个仓的 1D 直方图,如图 24 所示。

图 24。在 Matplotlib 中修改 1D 直方图(图片由作者提供)。

下面是创建图 24 的完整代码。

N = 1000np.random.seed(10021)
x = np.random.randn(N) * 2 + 15plt.figure(figsize=(9, 6))
plt.hist(x, bins = 40, label = r'$\mu = 15, \sigma = 2$')
plt.legend()

您也可以使用此参数来限制直方图的范围

range = (12, 18)

该参数将让直方图只显示从 12 到 18 的数据,如图 25 所示。

图 25。修改 Matplotlib 中 1D 直方图的数据限制(图片由作者提供)。

您可以用这段代码重现图 25。

我还使用一个 颜色 参数来改变直方图的颜色。

水*直方图

您可以创建一个水*直方图,如图 26 所示。

图 25。Matplotlib 中的水*直方图(图片由作者提供)。

您需要使用此参数来创建水*直方图

orientation = 'horizontal'

要创建图 25,您可以运行以下代码。

如果要显示每个直方图的边框,可以使用该参数。

edgecolor = 'k'

我想将直方图边框设为黑色,如图 26 所示。

图 26。在 Matplotlib 中自定义直方图边框(图片由作者提供)。

要生成图 26,您可以使用完整的代码。

重叠直方图

您可以在一个图中显示许多直方图,如图 27 所示。

图 27。在 Matplotlib 中创建许多直方图(图片由作者提供)。

在图 27 中,我生成了三个正态分布,具有不同的 mu 和 sigma。您可以用这段代码重现图 27。

您可以通过改变直方图的透明度使它更漂亮,如图 28 所示。

图 28。更改 Matplotlib 中直方图的透明度(图片由作者提供)。

如果您需要创建图 28 的完整代码,您可以阅读下面的代码。与前面代码的区别只是在 alpha 参数上。

您还可以使用循环生成图 28,如以下代码所示

N = 1000mu1 = 5
mu2 = 10
mu3 = 15sigma1 = 5
sigma2 = 3
sigma3 = 2x1 = np.random.randn(N) * sigma1 + mu1
x2 = np.random.randn(N) * sigma2 + mu2
x3 = np.random.randn(N) * sigma3 + mu3mu = np.array([mu1, mu2, mu3])
sigma = np.array([sigma1, sigma2, sigma3])
x = np.array([x1, x2, x3])
colors = ['royalblue', 'tomato', 'gray']plt.figure(figsize=(9, 6))for i in range(len(x)):
    plt.hist(x[i], bins = 30, color = colors[i], 
             label = r'$\mu = $ ' + str(mu[i]) + 
             ', $\sigma = $ ' + str(sigma[i]), alpha = .7)plt.legend()

在看到上面的代码后,也许你会想象在一个图形中创建许多直方图(多于 3 个)。下面是在一个图中清晰地创建和可视化 10 个直方图的代码。

如果您运行上面的代码,您将得到一个结果,如图 29 所示。

图 29。在 Matplotlib 中干净地创建许多直方图(图片由作者提供)。

仅使用此链接即可生成多种颜色。生成调色板后,只需将其复制并粘贴到您的代码中。生成调色板的详细过程在这里提供。

2D 直方图

您可以使用 Matplotlib 生成 2D 直方图,如图 30 所示。

图 30。2D 直方图与 Matplotlib(图片由作者提供)。

为了创建图 30,我需要用这段代码生成 2 个正态分布。

N = 1_000np.random.seed(100)
x = np.random.randn(N)
y = np.random.randn(N)

要在 2D 直方图中显示变量 x 和 y,可以使用下面的代码。

plt.hist2d(x, y)

与 1D 直方图一样,Matplotlib 将生成 10 个柱作为 2D 直方图的默认设置。要更改它,您可以应用与 1D 直方图中相同的参数,如下面的代码所示。

bins = (25, 25)

您可以在图 31 中看到 2D 直方图中修改后的箱数。

图 31。在 Matplotlib 中修改 2D 直方图的面元数。

您也可以使用此参数更改 2D 直方图的色彩映射表

cmap = orange_blue

我想将颜色图从 Viridis(Matplotlib 中的默认颜色图)更改为我自己的名为 orange_blue 的颜色图。我已经在前一节解释了如何创建你自己的色彩映射表,或者你可以在这里阅读。

这是修改 2D 直方图中使用的色彩映射表的完整代码。

如果您运行上面的代码,它将创建一个图形,如图 32 所示。

图 32。在 Matplotlib 中更改 2D 直方图的色彩映射表。

通过将该参数应用到 plt.hist2d()中,可以限制每种颜色的计数范围(更改颜色条的限制)。

cmin = 5, cmax = 25

这是完整的代码

N = 10_000np.random.seed(100)
x = np.random.randn(N)
y = np.random.randn(N)plt.figure(figsize=(8.5, 7))
plt.hist2d(x, y, bins=(75, 75), cmap = 'jet', cmin = 5, cmax = 25)
cb = plt.colorbar()
cb.set_label('counts each bin', labelpad = 10)

我使用“jet”颜色图,颜色条的下限为 5,上限为 25。代码将生成一个图形,如图 33 所示。

图 33。在 Matplotlib 中设置 2D 直方图的限制。

我尝试使用这段代码将生成的随机数计数从 10000 更改为 100000。

N = 100_000np.random.seed(100)
x = np.random.randn(N)
y = np.random.randn(N)plt.figure(figsize=(8.5, 7))
plt.hist2d(x, y, bins=(75, 75), cmap = 'Spectral')
cb = plt.colorbar()
cb.set_label('counts each bin', labelpad = 10)

代码将显示一个结果,如图 34 所示。

图 34。用 Matplotlib 可视化 2D 直方图中的正态分布(图片由作者提供)。

图 34 的峰值在 0 左右,分布在-1 到 1 左右,因为我没有改变 mu 和 sigma 的值。

边缘剧情

这一小节将告诉如何创建一个边际分布,如图 35 所示。

图 35。Matplotlib 中散点分布和直方图的边际图(图片由作者提供)。

图 35 由散点图和 2 直方图构成。要创建它,你需要了解如何在一个图形中定制支线剧情或轴。图 35 由 25 个轴(5 列 5 行)构成。详情如图 36 所示。您可以用这段代码创建图 36。你需要阅读这个链接来理解它。

rows = 5
columns = 5grid = plt.GridSpec(rows, columns, wspace = .4, hspace = .4)plt.figure(figsize=(10, 10))for i in range(rows * columns):
    plt.subplot(grid[i])   
    plt.annotate('grid '+ str(i), xy = (.5, .5), ha = 'center', 
                 va = 'center')
for i in range(rows):
    exec (f"plt.subplot(grid[{i}, 0])")
    plt.ylabel('rows ' + str(i), labelpad = 15)for i in range(columns):
    exec (f"plt.subplot(grid[-1, {i}])")
    plt.xlabel('column ' + str(i), labelpad = 15)

图 36。Matplotlib 中的多个支线剧情(图片由作者提供)。

图 35 显示了图 36 的转换。我将图 36 中的一些网格合并成 3 个更大的网格。第一个网格组合了网格 0 到网格 3(行 1,列 0 到列 3)。我将用直方图填充第一个网格。第二个网格合并了从第 1 行到第 4 行以及从第 0 列到第 3 列的 16 个网格。最后一个网格是通过合并网格 9、14、19 和 24(行 1、2、3、4 和列 4)构建的。

要创建第一个网格,可以使用下面的代码。

rows = 5
columns = 5grid = plt.GridSpec(rows, columns, wspace = .4, hspace = .4)plt.figure(figsize=(10, 10))plt.subplot(grid[0, 0:-1])

之后,添加下面的代码来插入 1D 直方图

plt.hist(x, bins = 30, color = 'royalblue', alpha = .7)

要创建第二个网格,您可以将此代码添加到上面的代码中

plt.subplot(grid[1:rows+1, 0:-1])

添加此代码以在第二个网格中生成散点图。

plt.scatter(x, y, color = 'royalblue', s = 10)
plt.axis('equal')

下面是生成第三个网格及其直方图的代码。您需要将下面的代码插入第一个网格代码中

plt.subplot(grid[1:rows+1, -1])
plt.hist(y, bins = 30, orientation='horizontal', 
         color = 'royalblue', alpha = .7)

您可以将它们结合起来,如下面的代码所示。

接下来,我将用 2D 直方图改变第二个网格中的散点图,如图 37 所示。

图 37。Matplotlib 中的边缘情节(作者图片)。

您可以用这段代码重现图 37。

如果您遇到一些错误,请在回复栏中留下一些评论。

04.条形图

如果你想用条形图来可视化你的数据,这个很适合你。在我用 Matplotlib 创建条形图之前,像往常一样,我想创建要显示的模拟数据。我想为六个人的数学考试成绩创建数据。为了创建它,我使用下面的代码。

name = ['Adam', 'Barry', 'Corbin', 'Doe', 'Evans', 'Frans']np.random.seed(100)
N = len(name)
math = np.random.randint(60, 100, N)

我生成的数学考试分数从 60 分到 100 分。为了形象化它,你可以使用这个代码。

plt.bar(name, math, alpha = .7)

添加一些信息后,我生成一个条形图,如图 38 所示。

图 38。在 Matplotlib 中创建一个条形图(图片由作者提供)。

下面是生成图 38 的完整代码。

name = ['Adam', 'Barry', 'Corbin', 'Doe', 'Evans', 'Frans']np.random.seed(100)
N = len(name)
math = np.random.randint(60, 100, N)plt.figure(figsize=(9, 6))plt.bar(name, math, alpha = .7)plt.ylabel('Math Exam')

之后,我使用这段代码为物理、生物和化学考试分数创建了一些模拟数据。

np.random.seed(100)
N = len(name)
math = np.random.randint(60, 100, N)
physics = np.random.randint(60, 100, N)
biology = np.random.randint(60, 100, N)
chemistry = np.random.randint(60, 100, N)

你可以用熊猫创建一个表格,在 Python 中我们称之为 DataFrame。我从模拟数据创建的数据帧如图 39 所示。

图 39。熊猫数据框中的模拟数据(图片由作者提供)。

默认情况下,我没有插入如何创建数据帧的代码。但是,如果你需要的话,你可以把你的请求留在回复栏里。

然后,我将它可视化,如图 40 所示。

图 40。在 Matplotlib 中创建许多条形图(图片由作者提供)。

要创建图 40,您可以使用以下代码。

name = ['Adam', 'Barry', 'Corbin', 'Doe', 'Evans', 'Frans']np.random.seed(100)
N = len(name)
math = np.random.randint(60, 100, N)
physics = np.random.randint(60, 100, N)
biology = np.random.randint(60, 100, N)
chemistry = np.random.randint(60, 100, N)rows = 2
columns = 2plt.figure(figsize=(12, 8))
grid = plt.GridSpec(rows, columns, wspace = .25, hspace = .25)plt.subplot(grid[0])
plt.bar(name, math, alpha = .7)
plt.ylabel('Math Exam')
plt.ylim(60, 100)plt.subplot(grid[1])
plt.bar(name, physics, alpha = .7)
plt.ylabel('Physics Exam')
plt.ylim(60, 100)plt.subplot(grid[2])
plt.bar(name, biology, alpha = .7)
plt.ylabel('Biology Exam')
plt.ylim(60, 100)plt.subplot(grid[3])
plt.bar(name, chemistry, alpha = .7)
plt.ylabel('Chemistry Exam')
plt.ylim(60, 100)

或者,如果您想使用循环,请使用此代码。

name = ['Adam', 'Barry', 'Corbin', 'Doe', 'Evans', 'Frans']
course_name = ['Math', 'Physics', 'Biology', 'Chemistry']N = len(name)rows = 2
columns = 2plt.figure(figsize=(12, 8))
grid = plt.GridSpec(rows, columns, wspace = .25, hspace = .25)for i in range(len(course_name)):
    np.random.seed(100)
    course = np.random.randint(60, 100, N)
    plt.subplot(grid[i])
    plt.bar(name, course, alpha = .7)
    plt.ylabel(course_name[i] + ' Exam')
    plt.ylim(60, 100)

水*条形图

您可以将水*条形图与此代码一起使用。

plt.barh(name, course)

我想用横条图的形式和各种颜色来呈现图 40。下面是生成它的完整代码。

name = ['Adam', 'Barry', 'Corbin', 'Doe', 'Evans', 'Frans']
course_name = ['Math', 'Physics', 'Biology', 'Chemistry']colors = ['#00429d', '#7f40a2', '#a653a1', '#c76a9f', 
          '#e4849c', '#d0e848']N = len(name)rows = 2
columns = 2plt.figure(figsize=(12, 8))
grid = plt.GridSpec(rows, columns, wspace = .25, hspace = .25)for i in range(len(course_name)):
    np.random.seed(100)
    course = np.random.randint(60, 100, N)
    plt.subplot(grid[i])
    plt.barh(name, course, color = colors)
    plt.xlabel(course_name[i] + ' Exam')
    plt.xlim(60, 100)
    plt.gca().invert_yaxis()

运行上面的代码后,您将得到一个结果,如图 41 所示。

图 41。Matplotlib 中的水*条形图(图片由作者提供)。

可以使用此参数在水*条形图中插入误差线

N = len(name)
noise = np.random.randint(1, 3, N)plt.barh(name, course, xerr = noise)

我使用从 1 到 3 的整数随机数来创建错误,正如变量 noise 中提到的。在为我的水*条形图添加了一些元素之后,我展示了它,如图 42 所示。

图 42。在 Matplotlib 中修改水*条形图(图片由作者提供)。

您可以用这段代码重现图 42。

name = ['Adam', 'Barry', 'Corbin', 'Doe', 'Evans', 'Frans']
course_name = ['Math', 'Physics', 'Biology', 'Chemistry']N = len(name)rows = 2
columns = 2plt.figure(figsize=(12, 8))
grid = plt.GridSpec(rows, columns, wspace = .25, hspace = .25)
np.random.seed(100)for i in range(len(course_name)):
    course = np.random.randint(60, 95, N)
    noise = np.random.randint(1, 3, N)
    plt.subplot(grid[i])
    plt.barh(name, course, color = colors, xerr = noise, 
             ecolor = 'k')
    plt.xlabel(course_name[i] + ' Exam')
    plt.xlim(60, 100)
    plt.gca().invert_yaxis()

也许,你意识到我的模拟数据(有误差)是不现实的。你不能满足一个考试分数的不确定性。但是,我认为它仍然是理解 Matplotlib 中条形图的一个很好的例子。

结论

这是第 1 部分的结尾。正如我之前提到的,我尽量限制阅读时间(30 分钟以内),这样你就可以享受阅读了。本部分仅涵盖 11 个部分中的 4 个,散点图、线图、直方图和条形图。在下一部分中,我将展示创建箱线图、小提琴图、饼图、极坐标图、地理投影、3D 图和等高线图的教程。如果下一部分是消耗超过 30 分钟,我会再分一次。

在技术时代,数据可视化对于从小数据或大数据中分析数据具有重要意义。我们需要它来全面了解我们的数据。可以与 Matplotlib 一起使用的各种类型的可视化。这只是 python 用 Matplotlib 绘图的一小部分。

如果你喜欢这篇文章,这里有一些你可能喜欢的其他文章:

[## 使用 Matplotlib 可视化数据的 5 个强大技巧

如何使用 LaTeX 字体,创建缩放效果,发件箱图例,连续错误,以及调整框填充边距

towardsdatascience.com](/5-powerful-tricks-to-visualize-your-data-with-matplotlib-16bc33747e05) [## 用于科学绘图的 Matplotlib 样式

为您的科学数据可视化定制 Matplotlib

towardsdatascience.com](/matplotlib-styles-for-scientific-plotting-d023f74515b4) [## 在 Matplotlib 中创建色彩映射表

从颜色列表中创建和定制自己的色彩映射表的指南

towardsdatascience.com](/creating-colormaps-in-matplotlib-4d4de78a04b8) [## 在 Matplotlib 中自定义多个子情节

使用 subplot、add_subplot 和 GridSpec 在 Matplotlib 中创建复杂 subplot 的指南

towardsdatascience.com](/customizing-multiple-subplots-in-matplotlib-a3e1c2e099bc) [## Vaex 大数据简介—读取 12.5 亿行的简单代码

用 Python 高效读取和可视化 12.5 亿行星系模拟数据

towardsdatascience.com](/introduction-to-big-data-a-simple-code-to-read-1-25-billion-rows-c02f3f166ec9)

仅此而已。感谢您阅读这个故事。喜欢就评论分享。我还建议您关注我的帐户,以便在我发布新故事时收到通知。几天后,我将发布 Matplotlib 可视化的第 2 部分。

使用 Python 和 Plotly 清晰地可视化和交流不确定性

原文:https://towardsdatascience.com/visualize-and-communicate-uncertainties-with-python-and-plotly-1f30ece540d8?source=collection_archive---------16-----------------------

幻想体育实例,以可视化,理解和交流不确定性,概率和结果范围(包括代码和数据)

Riho KrollUnsplash 上的原始照片

在这篇文章中,我想展示有效地可视化和交流不确定性和范围是多么容易。更重要的是,我想证明这样做对于获得对数据的直观理解和随后的决策是多么有帮助。

尽管我们大多数人都意识到生活各个方面的不确定性,但我们并不经常看到这些不确定性,或与之共事。信息或数字通常以*均数给出(如果幸运的话,是*均值或中位数)。我们中的许多人从来没有被教授过统计学和概率,少数被教授过的人大多是以可怕、乏味、学术性的方式被教授的,这种方式将公式置于直觉理解之上。因此,即使你对数据中的不确定性有很好的理解,向大多数受众传达也是很棘手的。(试着在会议中引用一个标准差数字,并数一数回来的茫然的目光。)

在理解和交流与不确定性、概率和分布相关的信息方面,数据可视化有着无可比拟的帮助。那么,让我们来看看如何将不确定性可视化,以及如何使用这些数据。

为了更清楚的原因,我将在这篇文章中使用篮球的框架,特别是幻想篮球。一如既往,重点是数据和分析方法,而不是具体运动的分析结果;所以你就算不关心篮球也应该没问题。

在开始之前

数据

我在我的 GitLab repo 这里包含了代码和数据,所以如果你愿意的话,你应该可以通过下载/克隆 repo 轻松地跟随。

包装

我假设您熟悉 python。即使你相对较新,这个教程也不应该太难。

你需要pandasplotly。用一个简单的pip install [PACKAGE_NAME]安装每一个(在你的虚拟环境中)。

显然,你可以使用任何图形包,但我个人更喜欢你用 Plotly 得到的简单和强大。

组建一个团队/梦幻篮球队

想象一下,通过一些随机事件,有人要求你组建一个梦幻篮球队。

(你可能会问——什么是奇幻体育?简单地说,在梦幻体育中,玩家通过从真实联盟中的所有可用玩家中组建团队来进行竞争,这些玩家根据他们在现实生活中的表现来分配分数。)

你会怎么做?一种方法是简单地挑选最有可能为你的球队贡献最多分数的球员。

我准备了一个基于 2018–2019 NBA 赛季的 csv 文件。数据来自basketball-reference.com,使用basketball _ reference _ web _ scraper 库获得。我已经对它进行了预处理,只包括那些上场时间超过 1000 分钟的球员,以及那些没有在赛季中期被交易的球员。

让我们用以下内容加载数据:

season_tot_df = pd.read_csv('srcdata/bballref_1819_season_tots_1000plus_mins.csv', index_col=0)

看一看它:

season_tot_df.head()

这些数据包括来自网站的所有原始列和一个方便的fan_ppg列,它是我基于这个公式创建的。

每场游戏的幻想点数

数据是什么样的?每场比赛的点数条形图可以绘制如下:

import plotly.express as px
fig = px.bar(season_tot_df, y='fan_ppg', x='name')
fig.show()

通过应用一些格式化(为了简洁,我不会在这里显示我所有的格式化代码,如果您感兴趣,请查看 repo),我们得到:

每位玩家*均幻想点数的条形图

从詹姆斯·哈登到布鲁斯·布朗,这张图表描绘了所有 254 名球员的幻想点。所以,当轮到你的时候,简单地选择每场比赛得分第二高的玩家总是最好的吗?

我个人觉得没那么简单。原因如下。

同样的,但是不同的

上面的条形图描绘了*均值——更具体地说,是“*均值”,即总分数除以游戏次数。但是,任何看过 JR 史密斯或尼克·杨的人都知道,并不是所有的*均数都是一样的。

有些球员只是比其他人更稳定,而其他人的不稳定会让你对他们每晚的变化感到抓狂。

举个例子,让我们比较一下克里斯·米德尔顿和埃里克·布莱索。顺便说一下,两人都在同一支球队,并且产生了几乎相同的赛季*均得分:

>>> print(season_tot_df[season_tot_df['name'].isin(['Eric Bledsoe', 'Khris Middleton'])].fan_ppg)
45    31.905195
49    31.351282

但是,正如你将看到的那样,它们的方式大相径庭。为此,让我们加载我们的数据,其中包括 254 名球员的个人比赛统计数据:

with open('srcdata/bballref_1819_pl_box.pickle', 'rb') as f:
    pl_data_dict = pickle.load(f)

数据采用字典形式,其中键值是球员的 slug (篮球参考使用的球员标识字符串)。

在做任何事情之前,我们需要收集米德尔顿和布莱索的数据,并将这些信息整合到一个数据框架中:

在这里,我收集了两个玩家的“slugs ”,并将它们用于每个玩家的字典数据。每个玩家的数据都在字典列表中。它们很容易被转换成数据帧(temp_df),它们自己被添加到一个新的列表中(temp_df_list),然后在匹配的列处被连接以产生一个数据帧(comp_df)。

将数据绘制成柱状图,我们看到:

fig = px.bar(comp_df, y='fan_pts', color='player', facet_col='player', labels={'fan_pts': 'Fantasy Points', 'date': 'Date'})
fig.update_layout(title='Fantasy performance comparison')
fig.show()

一对年轻雄鹿的幻想点数条形图

每个图表中从低端到高端的整个集合可以称为“结果范围”。也就是说,它们代表了一组结果(我的意思是,它们并不确切地说是,但是它是有代表性的,我们现在就让它到此为止)。

从这些柱状图来看,布莱索的数据可能比米德尔顿的稍不均衡。有更多的高杠,也有一些明显的差距(低杠)。不过,从这些数据中很难确定。这就是直方图可以发挥作用的地方。直方图绘制了数据点的分布,其中 y 值是适合每个 x“箱”的值的计数。

fig = px.histogram(
    comp_df, x='fan_pts', facet_row='player', color='player',
    labels={'fan_pts': 'Fantasy Points', 'count': 'Count'}, nbins=30)
fig.update_layout(title='Fantasy performance comparison')
fig.show()

与上面相同的数据,作为直方图

这看起来像是一个响亮的是。

这些直方图告诉我们,不管出于什么原因,布莱索显然比米德尔顿更不一致。他有更多得分较高的比赛,但也有更多得分较低的比赛。因此,即使他们有相同的*均分,布莱索和米德尔顿获得*均分的机会也有很大的不同。

尽管如此,在这里很难看出布莱索比米德尔顿更有可能获得 40+的分数。还有,如果我们想一次比较两个以上的玩家会怎么样?

有许多工具可以轻松查看数据的分布。箱线图可能是一种——它将分布绘制为“盒子”,表示数据集的百分位数分解。试试这个:

fig = px.box(comp_df, x='player', y='fan_pts', color='player', labels={'fan_pts': 'Fantasy Points', 'date': 'Date'})
fig.update_layout(title='Fantasy performance comparison')
fig.show()

箱线图比较:布莱索和米德尔顿

中间的线表示“中间”值,表示最可能的结果,方框表示所有结果的一半落在哪里,以及大多数结果预期在哪里。圆点表示“异常值”,这是统计意义上的异常结果。

Plotly 还允许以点的形式绘制底层数据,为了更清楚和说明,让我们这样做:

箱线图与数据的比较:Bledsoe 和 Middleton

显然,让布莱索加入你的团队是一个高风险、高回报的策略。

Violin plot 也是一个很好的工具,可以让您更仔细地查看数据的分布:

fig = px.violin(comp_df, x='player', y='fan_pts', color='player', labels={'fan_pts': 'Fantasy Points', 'date': 'Date'}, points="all")
fig.update_layout(title='Fantasy performance comparison')
fig.show()

小提琴图与数据的比较:布莱索和米德尔顿

不同于简单的四分位标为直线的箱线图,violin 图本质上是比较直方图,图的宽度代表这些值出现的频率。

这也是小提琴剧情的一个局限。因为宽度在解读小提琴图时至关重要,所以当显示许多数据点时,它们就没那么有用了。随着每个地块的宽度越来越小,它们之间的细微差异变得更加困难。

好了,这可能够了。

让我们回到最初的问题,这个数据如何帮助我们选择球员。

比较一群玩家

假设我们剩下的玩家*均幻想点数在 35 到 40 之间,他们中的任何一个都可以加入我们的团队。我们选谁?正如我们之前所做的,我们可以将它们放入直方图或箱线图中:

这段代码与我们上面为 Middleton 和 Bledsoe 所做的非常相似,除了现在我们通过fan_ppg值收集玩家的 slugs。

多个玩家的比较—使用直方图

多个玩家的比较—使用方框图

我们在这里可以看到,随着数据点的增加,盒状图的紧凑性有助于它发挥作用。比较更多玩家:

玩家的方块图比较——每场游戏 30-40 点幻想点数

像鲁迪·戈贝尔、克里斯·保罗或克里斯·米德尔顿(用橙色标记)这样的人是我们所说的“低方差”玩家。你会更加确定他们的日常表现。另一方面,像约翰·沃尔、德安杰洛·拉塞尔或维克多·奥拉迪波(标有蓝色)这样的球员变化更大。

所以问题变成了——对你来说什么更重要?也许你玩游戏是为了进入你的联盟的前百分之几,在这种情况下,你可能想要高方差的球员。

或者,如果你的联盟奖励稳定的表现,而不是偶尔闪光的表现,稳定的球员可能是更好的赌注。在现实生活中,这可能更像是你想要的。你能想象有一个玩家团队,却不知道在任何一个晚上你能从他们那里得到什么吗?

我们如何找到一组或另一组?

可视化性能一致性

对球员数据进行排序以确定相对一致性的一种方法是使用称为“标准差”或“方差”的测量方法。不用太过数学化,他们基本上是测量一个分布如何展开。在上面的例子中,埃里克·布莱索比米德尔顿有更大的标准差。

更进一步,我们可以通过将两个绘制成如下散点图,来确定具有相似*均(均值)表现的玩家在潜在输出方面可能如何变化。

让我们简单地看一下代码。再一次,slug 被收集,除了这里的循环简单地覆盖赛季总数据帧中的所有 slug 值(即每个球员)。

然后计算每个玩家的*均值和标准偏差,基于此构建新的数据帧。最后,我产生一个标准偏差与*均值的比率,它被用作颜色变量。

(为便于显示,数字四舍五入。)

绘制一致性(标准偏差)与*均性能(*均值)的对比图

(我在这里放了一个互动版

该图显示了标准差和*均值之间良好的总体相关性,具有较大的分布。也就是说,在相同的*均值下,存在大范围的标准偏差值。

正如我们之前所讨论的,在某些情况下,识别可能偶尔具有高输出性能的数据点是有益的。与许多玩家对抗的梦幻运动无疑是其中之一,在这种情况下,在一个大群体中排名靠前比在群体中间有更大的好处。

这里的巨大差异代表了选择球员的人的重大选择,以优化他们对目标的选择。

看一下同一个图表,其中突出显示了一些球员的数据。

同样的剧情,突出某些玩家。

卡尔-安东尼唐斯和保罗·乔治在这个图中有几乎相同的手段,但凯特的标准差得分要高得多。

另一方面,贾马尔·克劳福德的标准差高于乔治的标准差,尽管他的均值要低得多。如果一个球员在梦幻联盟中的“价格”仅仅是基于他们的*均产量,克劳福德可能会提供一个很好的价值机会来帮助构建一个高天花板的团队。

交流和行话

这是个人偏好,但我会在展示统计数据时做一个说明。取决于我的听众,如果可能的话,我通常更喜欢*实的语言,而不是行话。因此,我可能会将“标准差”重新命名为“可变性”。

就我个人而言,我发现像“均值”和“标准差”这样的术语有时会分散(更糟糕的是,疏远)观众的注意力。在这种情况下,“标准差”的统计意义没有任何意义。我们只是在寻找可变性增加的数据点,为什么不这样标注呢?看一下这个图:

同样的情节,使用*实的语言(ICYMI,互动版)

我认为这比上面的方法更好地传达了信息,在上面的方法中,观众经常试图记住什么是标准差——而不是信息的实质。

当然,对于专家或对统计数据友好的观众来说,请尽情使用术语😉。

独立/堆叠

我还想谈谈不确定性的独立性。这就是不确定性线性叠加的时候(当它们不线性叠加时,就是这样)。

一种直观的思考方式是这样的。假设正在分析两个具有给定不确定性的变量。它们中的一个是高还是低,或者会影响另一个?

如果是这样的话,这两个人将会依赖。实际上,想象一下你的整个梦幻篮球队只包括来自同一支球队的球员。这将阻止他们中的许多人拥有职业生涯之夜,因为一个人表现出色可能意味着其他人的机会减少。

我们可以看一个例子。让我们把詹姆斯·哈登的数据和队友克里斯·保罗的数据进行比较。我包括了代码,我们重复了同样的事情来比较 Middleton & Bledsoe 的数据。然后,我们继续将这些数据组合成一个数据框架,这样我们就可以指向它们来绘制散点图。

结果如下图所示:

分数相关性——詹姆斯·哈登和 CP3

该图显示了两个人的分数之间经典的 L 型负相关关系。如果我们用一个不在同一个队的相似球员代替 CP3,数据会是什么样的?实际上是这样的:

分数的相关性(低得多)——詹姆斯·哈登和克里斯·米德尔顿

这或多或少是一种随机分布。还要注意的是,较低情节的最高综合分数较高,因为一个人的高分并不排除另一个人这样做。

换句话说,当我们处理多个变量的不确定性时,以及当我们可能在寻找组合它们的数据时,相关性是很重要的。

好吧,让我们在那里结束它。

正如你可能已经看到的,不确定性或范围是很容易想象的,对它们的良好理解对于能够充分利用世界固有的可变性是至关重要的。

这不是最容易做到的事情,但我个人发现,有时看到所有的数据(如在我们的散点图中),并比较分布(通过箱线图、直方图或小提琴)确实有助于我更好地理解它们。

本文使用了一个基于体育的例子,但是它也适用于许多其他领域。我很想听听你所在领域的不确定性类型。

在我即将发表的一篇文章中,我想谈谈预测(作出预测)以及将预测结果可视化。在那之前,放轻松!

如果你喜欢这个,比如说👋/在推特上关注,或者关注更新。我还写了这篇关于我最喜欢的数据可视化书籍的文章,如果你以前没有读过的话:

[## 用这些书创建有影响力的数据可视化

如果没有交流,好的分析没有什么意义。数据可视化会有所帮助。以下是我对…的建议

towardsdatascience.com](/create-impactful-data-visualizations-with-these-books-ca9fbfecfde5)

使用 Catscatter 可视化分类关系

原文:https://towardsdatascience.com/visualize-categorical-relationships-with-catscatter-e60cdb164395?source=collection_archive---------16-----------------------

如果您可以创建分类特征的散点图会怎么样?

2015 年至 2019 年间,欧洲 100 家顶级风投和 50 家顶级行业的种子投资更加活跃

如果你曾经需要一种方法来绘制显示其关系的类别特征,我已经为你建立了这个资源。基于 matplotlib.pyplot 对象构建的 catscatter 函数,使用 pandas 来可视化类别变量之间的关系,就像散点图一样。(我知道,这里没有相关性,但它看起来像是建立在散点图上,对吗?).

[## my things/cat scatter

我是一名数据分析师,运用一点数据科学和大量的数据可视化。去年 12 月,一位同事给了我…

github.com](https://github.com/myrthings/catscatter)

语境

我是一名数据分析师,运用一点数据科学和大量的数据可视化。去年 12 月,一位同事送给我一本书作为圣诞礼物《知识是美丽的》,我非常喜欢。它的数据可视化是惊人的并且非常复杂。当我想获得灵感时,我喜欢读它。

同时,我在一家 VC 基金工作,在那里框架和关系真的很重要。由于分类变量的“字符串”性质,显示它们之间的关系并不总是一件容易的事情。

这两种情况促使我创建并使用一个 catscatter 函数。该函数基于散点图关系,但以一种美丽而简单的方式使用分类变量。实际上,可视化更接*于“邻接矩阵”而不是“散点图”:这意味着我们对标记在哪里找到相关性不感兴趣,而是对哪些类别相互关联,或者哪些类别与某个事物的关联度更高。它们可以被视为一种“图形”关系。为此,重要的是不仅要在特征之间的交叉点绘制标记,还要在背景中绘制水*线和垂直线,以便于跟踪连接。

绘制您自己的 catscatter

函数是在 Matplotlib 和 Pandas 上为 Python 构建的。它有以下输入:

  • df: 熊猫数据框,必选。它需要至少两列包含您要关联的分类变量,以及两者的值(如果它只是一个相邻的矩阵,请写一列)
  • colx: 字符串,必选。要水*显示的列的名称。
  • coly: string,必选。要垂直显示的列的名称。
  • cols: 字符串,必选。值介于两个变量之间的列的名称。
  • 颜色: 列表,可选。可视化中要显示的颜色,长度可以是两个或三个。前两个是矩阵中线条的颜色,最后一个是字体颜色和标记颜色。默认['灰色','黑色']
  • ratio: int 或 float,可选。用于控制标记相对大小的比率。默认 10
  • 字体: 字符串,可选。矩阵上刻度的字体。默认‘Helvetica’
  • 保存: bool,可选。如果为 True,则在与代码相同的路径中保存为图像。默认假
  • 保存 _ 名称: 字符串,可选。用于保存图像的名称(然后是代码 ads。png) 默认:【默认】

没有输出。该对象未关闭,因此用户可以在此之前或之后启动或更改它。

基本示例

想象一下,你邀请你的一些朋友来家里吃饭。你可以建立一个 catscatter 来查看每个人最喜欢的食物,并购买更适合他们的食物。你需要一个包含你的朋友和食物之间关系的数据框架。例如,您知道 Ignacio 喜欢 Hamburguers,但也喜欢 Pizza,因此您构建了等级为“5”的“Ignacio”和“Hamburguer”之间的关系,以及等级为“3”的“Ignacio”和“Pizza”之间的关系。你对你所知道的关于你朋友的一切都做了同样的事情,并绘制了一个猫散点

import pandas as pd
import matplotlib as plt
from catscatter import catscatter# example data frame
data=pd.DataFrame({‘friend’:[‘Peter’,’Marc’,’Ignacio’,’Marta’,’Marta’,’Ignacio’,’Maria’,’Pedro’,’Bea’,’Pedro’],
 ‘favorite_food’:[‘Salmon’,’Chocolate’,’Hamburguer’,’Pizza’,’Apples’,’Pizza’,’Pizza’,’Hamburguer’,’Salmon’,’Banana’],
 ‘favorite_grade’:[1,5,5,3,2,3,4,4,3,1]})#plot it
catscatter(data,’friend’,’favorite_food’,’favorite_grade’)
plt.show()

输出:

这里你可以看到披萨是最受欢迎的食物,但是如果你邀请 Bea 和 Peter,也许点三文鱼塔塔基是最好的选择。不要浪费时间买水果。对于 Marc,我肯定你只和他吃过甜点,你应该邀请他共进晚餐来收集更多的数据!

个性化示例

这个例子和上一个一样,但是更大更丰富多彩。

import pandas as pd
import matplotlib as plt
from catscatter import catscatter# example dataframe
data=pd.DataFrame({‘friend’:[‘Peter’,’Marc’,’Ignacio’,’Marta’,’Marta’,’Ignacio’,’Maria’,’Pedro’,’Bea’,’Pedro’],
 ‘favorite_food’:[‘Salmon’,’Chocolate’,’Hamburguer’,’Pizza’,’Apples’,’Pizza’,’Pizza’,’Hamburguer’,’Salmon’,’Banana’],
 ‘favorite_grade’:[1,5,5,3,2,3,4,4,3,1]})colors=[‘green’,’grey’,’orange’]# create the plot
plt.figure(figsize=(8,8))
catscatter(data,’friend’,’favorite_food’,’favorite_grade’,color=colors,ratio=100)
plt.xticks(fontsize=14)
plt.yticks(fontsize=14)
plt.show()

输出:

亲例(本文封面)

在我的办公室,我们想知道哪些欧盟种子投资者在哪些行业更活跃。我收集了 2015 年至 2019 年欧洲所有种子轮的信息,并准备了一个数据集,其中包含每个投资者通过行业达成的交易数量(如果没有交易,就没有行)。交易的数量是行业和投资者之间关系的强弱。

import pandas as pd
import matplotlib.pyplot as plt
from catscatter import catscatter# read the dataframe
df=pd.read_csv(“top-european-investors-seed-rounds-15–19.csv”)
df

输出:

kcolors=[‘#F73972’,’#F2B3C6',’#144962']# create the plot
plt.figure(figsize=(50,20))catscatter(df,’Investor’,’Company Industry’,’Announced Date’,color=kcolors, ratio=20)plt.xticks(fontsize=20)
plt.yticks(fontsize=20)
plt.show()

输出:

我们有 700 名投资者和 600 个行业,但是为了这个可视化,我只留下前 100 名投资者和前 50 名更活跃的行业。在我的办公室,我们制作了两张海报,你可以在这里找到,在这里找到。

在这里展示的一个案例中,你可以看到“高科技基金”在几乎所有的顶级领域都有交易,但更多地集中在“信息技术”和“软件”领域。“Innogest Capital”和“Inbox Capital”也达成了几乎相同数量的交易,但“Inbox Capital”是多面手,“Innogest Capital”只专注于“电子商务”和“时尚”。我们还可以看到“广告”并不常见,但“软件”很常见,有些投资者关注“医疗”而不是“旅游”

我不能分享上一篇文章使用的 df,但是我希望它能帮助我在更大的范围内看到我的小代码片段的潜力。

如果你想试试 catscatter,这里有代码给你!👇

[## my things/cat scatter

我是一名数据分析师,运用一点数据科学和大量的数据可视化。去年 12 月,一位同事给了我…

github.com](https://github.com/myrthings/catscatter)

你怎么看?你觉得有用吗?你还有什么其他方法来描绘分类特征之间的关系?请在评论区告诉我!

如果你使用它,我也很想知道它🤗

使用 Tableau 可视化西班牙巴塞罗那的手机移动性

原文:https://towardsdatascience.com/visualize-cellphone-mobility-in-barcelona-spain-using-tableau-e3f7ab99d7e9?source=collection_archive---------50-----------------------

有很多来自手机的地理空间数据…

处理地理空间数据时,直观地查看地图上的数据通常很有用。在本教程中,我们将使用来自加泰罗尼亚政府的真实手机地理空间数据。这些数据存在于谷歌的公共数据集中。

如果你不熟悉谷歌云,请查看我的水*与谷歌的公共数据集教程,以访问加泰罗尼亚蜂窝覆盖数据集

导入数据

一旦数据被加载到 Tableau 中,我们可以看到移动数据有许多地理空间信息的记录。让我们深入画面去想象。

我们的第一步是将纬度和经度从度量转换为维度。通过将 Lat 和 Long 转换为维度,我们告诉 Tableau 分别处理每条记录,而不是将它们聚合在一起。

接下来,我们将双击纬度和经度将数据加载到地图上。正如我们所见,蜂窝数据是全球性的,但主要集中在欧洲,尤其是西班牙。这是因为数据是由位于西班牙巴塞罗那的加泰罗尼亚政府提供的。

修改地块设置

放大到西班牙的巴塞罗那,我们可以从我们的数据集中看到大量的地理空间手机数据。似乎有很多重叠的数据点,这使得我们无法完全可视化巴塞罗那的细节。

为了更好地可视化数据,我们可以减小每个数据点的大小。

此外,我们可以改变颜色和减少不透明度为 20%。不透明度为 20%时,地图上的纯色表示有 5 个重叠的数据点

想象一段时间内的运动

由于我们的数据是时间序列,我们可以利用 Tableau 的 Pages 函数来制作地图动画。单击日期维并将其拖至页面,然后将详细程度更改为连续的一天。

地图旁边会出现一个新的控制面板。点击右边的三角形,地图会随着时间向前移动。

瞧啊。您刚刚使用 Tableau 成功地将西班牙巴塞罗那的手机地理空间动画化和可视化。

在 Tableau 地图图层中使用深色样式

支持

谢谢你看我的教程!几股走很远!

对其他酷技术感兴趣吗?查看我的教程2020 年云上 Jupyter + Spark 入门

用 pandas 和 Plotly 可视化错误日志

原文:https://towardsdatascience.com/visualize-error-log-with-pandas-and-plotly-d7796a629eaa?source=collection_archive---------39-----------------------

Plotly 和 pandas timedelta 在“数据帧>重采样>绘图”管道中的优势和问题

最*,我收到了一个来自性能测量的数据集,其中包含关于处理时间和错误的数据。简单看了一眼后,我想这可能是一个问题;我需要把它形象化,让每个人都看到。视觉化很简单,但是它可以教你一些关于熊猫的概念,以及你可能面临的困难。主要是:

  • 与熊猫一起工作timedelta列类型
  • 熊猫resampling(一分钟或 5 秒钟图表)
  • Plotly.Express一起制图
  • 多么神秘。用subplots 表达斗争(或两轴绘图)
  • 对齐 Plotly 的轴

和往常一样,你可以在 GitHub 笔记本中看到框架、计算、情节背后的代码。它会带你经历:

1.错误日志的 EDA

2.剧情简介。快递

3.【timedelta 的优势和问题

4.剧情支线剧情

5.共享轴的 Plotly 图表

错误日志

我将错误简化为仅包含 3 列:

  • 陈述 —结果或过程(好或错)
  • 开始时间 —流程开始的时间
  • 结束时间 —流程结束的时间

在我的例子中,应用程序试图将报告呈现到.pdf中,但是类似的技术可以用于处理包含resultduration.的任何类型的错误日志

# Example error logState,StartTime,EndTime
Ok,2020-08-13 19:55:22,2020-08-13 19:55:27
Er,2020-08-13 19:55:22,2020-08-13 19:55:30
Ok,2020-08-13 19:55:24,2020-08-13 19:55:30

作为第一步,我必须解压日志(也包含在 Github repo 中)。当然,您可以手动解压缩,但是如果您想要创建一个自动化管道,您应该学习如何用代码来完成。

import zipfile# first let's unzip the error log
with zipfile.ZipFile("log.zip", 'r') as zip_ref:
    zip_ref.extractall("")

探索性数据分析

无论数据看起来有多简单,都要花一点时间在 EDA 上,以确保不会出现诸如丢失值、意外范围或重复等意外情况。

# load the data into the pandas's dataframe
df = pd.read_csv("error.log")# run predefined EDA function and optionally style the output
[In]: data_frame_stats(df)\
.style.format({"notnulls%": "{:,.2%}", "unique%": "{:,.2%}"})[Out]: 
          type   notnulls notnulls% unique unique%
State     object 1725     100.00%    2     0.12%
StartTime object 1725     100.00%    733   42.49%
EndTime   object 1725     100.00%    586   33.97%

快速概览显示没有价值丢失。State包含两个值,而时间戳是非常唯一的,即使有些发生在同一秒钟。

[In]: list(df["State"].unique())
[Out]: ['Ok', 'EndedWithError']

State的现有值为“Ok”和“EndedWithError”。知道我们可以通过将时间戳列转换为日期时间格式,并可选地将状态转换为分类列或 bool 列来润色数据帧。

# Convert strings to datetimes using `pd.to_datetime` and specifying the format
df["StartTime"] = pd.to_datetime(df["StartTime"], 
                                 format="%Y-%m-%d %H:%M:%S")# convert the State column into categorical. Mainly to decrease dataframe's memory footprint
df["State"] = df["State"].astype("category")# convert errro column to bool `.map()
df["Error"] = df["State"].map({"Ok": False, "EndedWithError": True}).astype("bool")# If there would be more error types, e.g. Error1, Error2 etc, we can apply if function through lambda expression
# df["Error"] = df["State"].apply(lambda x: False if x =="Ok" else True).astype("bool")# let's have a look on the final sample
df.sample(3)

已分析错误日志中的示例行

持续时间

我们主要对StartTimeEndTime都不感兴趣,而是对记录事件的持续时间感兴趣。由于这两列都是 pandas 的数据时间,我们可以简单地将它们相减得到一个timedelta列。

# calculate the duration
df["Duration"] = df["EndTime"]-df["StartTime"]

添加 timedelta 类型的持续时间列

Plotly Express

看起来我们已经拥有了生成一些有趣情节所需的所有列。让我们研究一下错误的数量与事件的数量的对比。我们将使用 Plotly。Express,流行的 Plotly 库的高级 API,它创建交互式(使用 JavaScript)图表。普洛特利。Express 以数据帧作为输入非常强大。使用 Plotly express,生成一个简单的图表是一行程序。

import plotly.express as px# With Plotly express you can quickly review the counts of varibles in the dataframe, even though I'm not sure which plotly have picked such low contract for their standard chart.**px.bar(df, x="State", title="Count of states")**

Plotly express 图表。它可以缩放,*移,并提供悬停工具提示。

Plotly 图表提供了许多伟大的功能。它们可以缩放,您可以通过拖动鼠标来*移图表,并且每个元素的数据都会在工具提示中进行汇总,工具提示会在您将鼠标悬停在元素上后出现。不幸的是,闪光的并不都是金子,还有一些令人讨厌的细节。

Plotly 自动计算你的分类值,但是工具提示显示count=1,并且这样的条形图的自动颜色与背景没有对比。px.pie piechart 根本不会自动计算发生次数。

时间增量及其相关问题

我们知道我们的错误日志包含相当多的错误。它们的总数是惊人的,但是这些错误会持续发生吗?它们会反映在处理时间中吗?为了表明我们可以利用熊猫的resample功能,并计算每一分钟的事件。不幸的是,timedelta列不容易*均。

# you can average time delta for full dataframe
[In]: df["Duration"].mean()
[Out]: Timedelta('0 days 00:01:01.371594')  # ~one minute 

但是尝试在重新采样的数据帧上应用mean:

# but you cannot average it `.mean()
try:
    df.set_index("StartTime")["Duration"]**.resample("1min").mean()**
except Exception as e:
    print(e)[Out]: No numeric types to aggregate

您可以resample.sum().count(),但由于某种原因,您无法对重新采样的 timedelta 值求*均值。

编程带来了意想不到的问题,但也带来了简单的解决方案。

  • 您可以将时间增量转换为秒,然后取*均值
  • 因为你可以sumcount,你也可以*均为sum/count
# you can turn timedelta into int, which give nanosecond represantation of the time delta which you divide by 1 bilion
df["duration_seconds"] = df["Duration"].astype('int64').divide(1000000000)# or you can use timedelta's .to_seconds() method
df["duration_seconds_2"] = df["Duration"].dt.total_seconds()

用熊猫重新采样

为了对任何数据帧进行重新采样,最简单的方法是将日期时间列之一设置为索引。我们将为StartTime做这件事。

stats = df.set_index("StartTime")

我们希望看到每分钟错误和成功的计数,以及成功和错误流程的处理时间(持续时间)。

stats = stats\
        .groupby("State")\
        .resample("1min")\
        .agg({"State":"count", "duration_seconds": "mean", "Duration": ["sum","count"]})

一次执行多个聚合会产生多级列名,我们使用reset_index将这些列名转换回一个级别,并根据每个级别对列进行重命名。

# State appear in index (due to groupby) and in values, because we count states. We must rename the column before we reset the index
stats = stats\
       .rename(columns={"State":"Count"}) 
       .reset_index(level=[0,1])

将两级列名合并成一个:

# two level column index turned into single level by joining zipped values from each levelstats.columns = ["_".join(z) for z in zip(stats.columns.get_level_values(0),
    stats.columns.get_level_values(1))]

最后,我们通过将sum列除以count列来计算*均持续时间

# calculate the average duration from the sum and count
stats["duration_mean"] = stats["Duration_sum"]/stats["Duration_count"]

结果统计。每个状态的计数和每分钟的*均持续时间。

产生的数据帧stats可以使用单线绘图表达式绘制。

fig_count = px.bar(stats, x="StartTime", y="Count", barmode="group", color="State")
fig_count.show()

每分钟的事件计数

同样,持续时间可以绘制成折线图。

fig_duration = px.line(stats, x="StartTime", y="duration_mean", color="State")
fig_duration.show()

通过 Plotly 持续时间。用 y 轴上的 timedelta 列表示

注意 y 轴上的120B, 100B, etc.值。timedelta值的另一个弱点是许多库,包括 Plotly express 都很难正确使用它们。

因为我知道这个问题,所以我已经提前创建了duration_seconds_mean列,并将持续时间显示为float

情节复杂的次要情节

关于同一个问题的两个图表就像是分离的恋人。这可能行得通,但合在一起更理想。每个可视化库都可以创建支线剧情,Plotly 也不例外。不幸的是,它不适用于 Plotly。Express 而且你还得用更低级的go API。

尽管每个 Plotly 图表的背景都有一个数据字典:

# each Plotly chart stores a dictionary of date and settings 
[In]: fig_duration.to_dict()
[Out]: 
{'data': [{'hovertemplate': 'State=EndedWithError<br>StartTime=%{x}<br>duration_seconds_mean=%{y}<extra></extra>',
   'legendgroup': 'EndedWithError', 
...

这些字典不能被输入到 Plotly 的支线剧情中

import plotly.graph_objects as go
from plotly.subplots import make_subplots# initialize the subplots
fig = make_subplots(rows=2, cols=1, shared_xaxes=True)# traying to add plotly express trace to the subplot will results in an error
try: 
    fig.add_trace(fig_duration)
    # neither the following would help
    # fig.add_trace(fig_duration.to_dict())
    # fig.add_trace(fig_duration.to_dict()["date"])
except Exception as e:
    print(e)**[Out]: Invalid element(s) received for the 'data' property of ...**

另一个恼人的特点是你不能用 Plotly 制作支线剧情。Express(还没有),你必须回到较低级别的 API,它不能很好地处理数据帧。

要制作一个子情节,你必须使用Plotly.graph_objects.go并分别指定每个输入——例如x=df["StartTime"], y=df["duration]。Plotly express 可以通过categorical列分割数据,但是对于go API,您必须手动将它们分开。

err = stats[stats["State"]=="EndedWithError"]
ok = stats[stats["State"]=="Ok"]

然后初始化子情节:

from plotly.subplots import make_subplots
fig = make_subplots(rows=2, cols=1)

添加所有跟踪(图表项目),同时您可以指定细节,如系列的颜色或名称:

# add scatter (which includes line charts as well) as the top chart containing duration of successful events
**fig.add_trace**(
    go.Scatter(x=ok["StartTime"], 
               y=ok["duration_seconds_mean"], 
               name="success duration",
               marker_color="Green",
              ),
    row=1, col=1
)

最后,您自定义图表的布局并显示它:

fig.update_layout(title="Processing speed and number of errors with missaligned x-axis",
                  yaxis_tickformat = '.2f',
                  xaxis_title="Time of Request",
                  yaxis = {"title": "processing time"},
                  yaxis2 = {"title": "number of requests"}fig.show()

将所有这些放在一起,制作出普洛特利的围棋支线剧情

我们再次面临一个令人不快的困难:

即使 x 轴具有相同的范围,它们在折线图和条形图中也是不对齐的。

即使 x 轴具有相同的范围,折线图的 x 轴也不会与条形图中的同一轴对齐。(参见完整代码获取证明)

幸运的是,您可以使用shared_xaxes=True迅速修复它。这带来了另一个好处,当你放大一个图表时,另一个也会放大。

fig = make_subplots(rows=2, cols=1, **shared_xaxes=True**)

两个图被缩放在一起

共享 y 轴的绘图

这一初步探索表明:

  1. 最初,没有错误
  2. 随着处理时间的增加,错误的数量开始增加
  3. 错误数量下降并开始再次增长,而时间继续增加
  4. 有一段时间,处理时间减少了,但是成功的事件也减少了
  5. 然后会有更多的成功发生,但也需要更长的时间来处理它们
  6. 最后,所有请求都以错误结束,开始时需要一些时间,但最终,所有事件都在一秒钟内以错误结束。

你没看到吗?也许我们可以用两个 y 轴一起绘制图表。

带有主轴和副轴的图表也是子图,通过参数specs=[[{“secondary_y”: True}]]组合。通过secondary_y=Truesecondary_y=False将每个轨迹分配给相关轴

让我们尝试用两个轴绘制带有计数的条形图和显示持续时间的折线图。

发生了什么,为什么我们的线藏在栅栏后面?

我最初将处理时间放在主轴上的决定是错误的,因为 Plotly 总是将副轴(条形图)显示在顶部,所以这条线在背景中消失了。

好了,普洛特利,让我们换一下轴。副轴为线,主轴为条。

尽管如此,图表并不理想。可以看到每个轴的网格线彼此之间只有几毫米的距离。

如果你希望现在有一个好的图表,你可能会失望。两个轴共享(意外地)非常相似的范围(~[0,130]),但是 Plotly 决定绘制每个网格线,只是稍微偏离另一个轴上的相应网格线。

这种情况也有解决方法。只需强制两个轴使用相同的范围。

fig.update_yaxes(range=[0, 130])

我已经把图表给开发者看了,他们很快就明白了这个问题。随着事件越积越多,处理它们需要更长的时间,并且越来越多的事件以错误告终。这个系统非常聪明,它决定偶尔终止部分进程,这样我们就不会有错误了。有一次,它甚至试图重新开始整个过程,但由于场景重复,最终,一切都被拒绝。

为了确定模式,不使用1min而是使用5s (seconds).很容易重新采样数据

df.set_index("StartTime").groupby("State")**.resample("5s")**.agg(...)

这里,一个轴的事件范围为 0–30,而另一个轴的事件范围为 0–150。Plotly 不会对齐网格线,我们必须试验每个轴的设置,以获得两个轴的相同网格线。

# you can specify the range and ticks of any axis
fig.update_layout(yaxis={"range":[0,30]},
                  yaxis2={"range":[0,150],
                         "tickvals": [25,50, 75, 100, 125, 150]}
                 )

同样的情况样本由 5 秒钟与 Plotly 的美丽的工具提示

由于 Plotly 的交互性,您可以放大图表并探索任何部分。使用单个参数fig.update_layout(hovermode=”x unified”)创建了一个包含所有 4 个显示值的漂亮工具提示。

利用 Plotly 的交互性探索 5s 样品的细节

结论

在本文中,我们探讨了如何将一个简单的错误日志转换成图表,以帮助我们找到一个可以解释的模式。我们曾经和熊猫timedeltaPlotly斗争过。不要误解我,Plotly 是一个很棒的库,但有时简单的事情会很复杂。

然而,大多数时候,你受益于把复杂的事情变得简单。

如果你想了解股票市场公司的财务状况,请阅读:

[## 股票基本面分析:SEC 季度数据汇总的 EDA

大熊猫 2020 SEC 申报的探索性数据分析

towardsdatascience.com](/stock-fundamental-analysis-eda-of-secs-quarterly-data-summary-455e62ff4817)

或者用人工智能进行哲学思考

[## AI 能教会我们快乐吗?

如何利用大脑的模式识别能力为我们造福?

medium.com](https://medium.com/@vaaasha/can-ai-teach-us-happiness-2629b600a4e0)

从 Slack Bot 的新冠肺炎案例更新的文本中可视化

原文:https://towardsdatascience.com/visualize-from-text-for-covid-19-cases-update-from-slack-bot-2590ea780887?source=collection_archive---------67-----------------------

获得最新的新冠肺炎全球跟踪使用人类文本与命名实体识别

新冠肺炎跟踪松弛应用程序。(图片作者)

如果我们能在一个地方看到所有的新冠肺炎信息,那该有多好?在这篇文章中,我们将研究如何开发一个系统,通过问一些自然的问题来提供全世界新冠肺炎病例的更新。

我们许多人都听说过 Alexa 设备,但有些人经常使用它。它试图通过高级机器学习工作流来解释文本。我们将建立一些类似于 Alexa 的技能,可以回答相关问题。

我们将创建新冠肺炎跟踪机器人,它试图理解多种意图,提取命名实体识别(NER)值,实现自定义新冠肺炎视觉响应,并具有松散集成。

我们将讨论以下主题:

  1. 解决方案架构
  2. 意图分类
  3. 命名实体识别
  4. 新冠肺炎海关行动
  5. 松散集成

1.解决方案架构

解决方案架构(图片作者)

RASA 聊天机器人框架提供了与 Slack App 连接的最简单方式。让我们看看 RASA 聊天机器人的幕后发生了什么。人类文本作为输入传递到 RASA 框架中的管道,以执行自然语言处理(NLP)操作。以下是 RASA 中用于识别话语的意图的示例可配置 NLP 管道。

基本 RASA NLP 管道。(作者图片)

命名实体识别(NER) 是流行的自然语言处理任务之一从文本中获取特定的 NER 将使用 Spacy,由 wit.ai 提供的 duckling,以及使用 CRF 实体提取器(RASA)的自定义实体。

接下来,我们如何为 RASA Bot 生成动态视觉响应?是的,可以使用 RASA 进行自定义操作。RASA 提供了一个定制的动作服务器来实现特定的业务逻辑,以便机器人做出响应。我们的新冠肺炎跟踪器逻辑将在自定义操作中实现。自定义新冠肺炎机器人响应将有图像输出。然而,slack 应用程序只会识别可从公共 URL 访问的图像。因此,需要包含来自 RASA bot 响应的公共 URL 图像。

我如何向 Slack 应用程序提供新冠肺炎视觉图像?这里使用了一个简单的 flask web 应用程序。整个解决方案部署在 AWS EC2 实例中。RASA 自定义动作生成图像输出,并保存在 flask app 目录的静态文件夹下。Slack 使用这个 flask 端点 URL 来访问图像。下面是样品瓶代码。

Flask web 应用程序访问图像。

新冠肺炎案例追踪器示例:

例句 1 ( 图片作者

例句 2 ( 作者图片)

例句 3 ( 图片作者)

在上面的例子中,每个句子都被称为话语。RASA 框架执行配置管道中指定的意图分类和实体识别。让我们看看下面的每个主题:

2.意图分类

意图分类是聊天机器人的强大模块之一。这是一个分类问题,输入文本需要分类。RASA 提供各种分类算法来执行意图识别。每个意图都与要执行的特定动作相关联。

3.命名实体识别

我们需要将位置名称、日期和自定义实体标识为 COVID 案例类型(活动、已确认、已恢复和死亡)。我们的管道中使用了以下库:

  1. 空间
  2. 小鸭子
  3. RASA 实体提取器

样本实体提取信息。(作者图片)

空间

Spacy 库在这里用于标识位置名称,如印度、美国、中国、澳大利亚。有不同的预训练模型可供使用。你可以点击查看空间 NER 演示。您可以在 RASA 管道中使用 Spacy NER,如下所示:

RASA 管道中的 Spacy NER。(作者图片)

我们可以选择预先训练的模型以及从话语中提取哪种实体。我们指定了 LOC 和 GPE 实体来标识位置名称。

小鸭子

Duckling 是一个 Haskell 库,它将文本解析成结构化数据。脸书开发了一个小鸭图书馆。它可以处理多个实体,如时间、日期、持续时间、距离、数量、温度、数量。在我们的场景中,我们使用从文本中提取日期信息。您可以在 RASA 管道中使用小鸭 NER,如下所示:

RASA 管道中的小鸭子 NER。(图片作者)

小鸭库怎么安装?

  1. 安装 docker。你可以参考这里的进行安装。
  2. RASA 提供了小鸭码头工人图像。您可以将 docker 图像克隆为docker pull rasa/duckling
  3. 您可以使用docker run命令启动 docker 映像。
  4. 使用docker ps命令检查状态。

小鸭子在8000港口奔跑。你可以在你的 RASA 管道中提到 duckling URL 和具体的实体名称。

CRF 实体提取器

条件随机字段(CRF)是 RASA 框架的一个组件,用于标识定制实体。我们使用来标识自定义实体,如电晕状态(确认、活动、恢复和死亡)。RASA 框架自行训练自定义实体。

4.新冠肺炎海关行动

现在,我们如何根据给定的人类文本生成视觉输出?到目前为止,我们从文本中解释了意图和实体。它帮助我们实现自定义新冠肺炎跟踪器逻辑。互联网上有新冠肺炎的开源 API,它提供每个国家的信息。我们将使用来自 API 的新冠肺炎信息来绘制可视化输出。下面是项目中使用的 COVID API:

  1. 邮递员新冠肺炎 API
  2. 小说电晕 API

你可以在这里找到自定义动作 Python 代码

5.松散集成

在 Slack 应用中设置 RASA bot 的最后阶段。

  1. 在此创建一个新的 Slack 应用
  2. 转到 OAuth 令牌&重定向 URL >订阅 Bot 令牌范围:channels.history,chat:write,groups:history,im:history,mpim:history。
  3. OAuth 令牌&重定向 URL >工作区的令牌。您将获得 OAuth 访问令牌作为xoxb-xxxxxxxxx.
  4. 点击Install App to Workspace.
  5. 获取 OAuth 访问令牌,在 RASA 中打开credentials.yml文件,并更改值slack_token: “access-token<xoxb-xxxxxxx>”.
  6. 转到事件订阅>订阅 bot 事件:message.channels、message.groups、message.im、message.mpim。
  7. 现在,你已经成功地在 Slack 应用中集成了 RASA bot。

恭喜你!您已成功完成时差集成。新冠肺炎追踪者机器人源代码可在 GitHub 中获得。如果你有什么要说的,请提出你的意见。

感谢阅读!你可以通过 LinkedIn 联系到我。

资源:

[## covid 19-印度 API

一个志愿者驱动的新冠肺炎统计 API&印度病人追踪(非官方)…

documenter.getpostman.com](https://documenter.getpostman.com/view/10724784/SzYXXKmA?version=latest) [## NovelCOVID API

更新:1591782903866,病例:7342359,今日病例:31527,死亡:414124,今日死亡:1152,痊愈…

科罗娜. lmao .忍者](https://corona.lmao.ninja/) [## Rasa:开源对话式人工智能

利用我们的开源机器学习框架,在文本和语音中构建上下文相关的人工智能助手和聊天机器人。缩放它…

rasa.com](https://rasa.com/) [## 小鸭子

用 Clojure 编写的日期解析器

小鸭. wit.ai](https://duckling.wit.ai/)

用 Python 从零开始的神经网络

原文:https://towardsdatascience.com/visualize-how-a-neural-network-works-from-scratch-3c04918a278?source=collection_archive---------16-----------------------

通过可视化每一步的结果,您可以更好地理解简单的神经网络是如何工作的

神经网络通常被认为是一种黑盒算法。数据可视化可以帮助我们更好地理解这种算法的原理。由于标准软件包没有给出如何找到参数的所有细节,我们将从头开始编写一个神经网络。为了直观地显示结果,我们选择了一个简单的数据集。

简单的数据集和神经网络结构

让我们使用这个只有一个特征 x 的简单数据集。

import numpy as npX=np.array([[-1.51], [-1.29], [-1.18], [-0.64],
[-0.53], [-0.09], [0.13], [0.35],
[0.89], [1.11], [1.33], [1.44]])y=np.array([[0], [0], [0], [0],
[1], [1], [1], [1],[0], [0], [0], [0]])

x 是具有 12 个观察值的单列向量,y 也是具有 12 个值的列向量,这些值表示目标。我们可以将这个数据集可视化。

import matplotlib.pyplot as plt
plt.scatter(X,y)

对于那些已经知道神经网络如何工作的人来说,通过看到这个图表,你应该能够找到一个简单的结构。在下一部分中,激活函数将是 sigmoid 函数。

所以问题是:我们需要多少层和多少个神经元来建立一个适合上面数据集的神经网络?

如果我们只使用一个神经元,这与进行逻辑回归是一样的,因为激活函数是 sigmoid 函数。我们知道这是行不通的,因为数据集不是线性可分的,简单的逻辑回归不适用于非线性可分的数据。所以我们必须添加一个隐藏层。隐藏层中的每个神经元将导致线性决策边界。

通常,逻辑回归创建一个超*面作为决策边界。由于这里我们只有一个特征,那么这个超*面只是一个点。从视觉上,我们可以看到我们需要两个点来区分两个类。它们的值一个是-0.5,另一个是 0.5。

因此,具有以下结构的神经网络将是我们数据集的良好分类器。

如果你不清楚,你可以看看这篇文章。

[## 直观来看,神经网络是如何工作的?

“神经网络”这个术语可能看起来很神秘,为什么一个算法叫做神经网络?它真的模仿真实的…

towardsdatascience.com](/intuitively-how-do-neural-networks-work-d7710b602e51)

使用 scikit 学习 MLPClassifier

在从头开始构建神经网络之前,让我们首先使用已经构建的算法来确认这样的神经网络是合适的,并可视化结果。

我们可以使用 scikit learn 中的 MLPClassifier 。在下面的代码中,我们用参数 hidden_layer_sizes 指定隐藏层的数量和神经元的数量。

from sklearn.neural_network import MLPClassifierclf = MLPClassifier(solver=’lbfgs’,hidden_layer_sizes=(2,), activation=”logistic”,max_iter=1000)clf.fit(X, y)

然后我们就可以计算分数了。(您应该得到 1.0,否则,由于局部最小值,您可能必须再次运行代码)。

clf.score(X,y)

太棒了,怎么才能把算法的结果可视化呢?由于我们知道这个神经网络是由 2+1 逻辑回归构成的,所以我们可以用下面的代码得到参数。

clf.coefs_
clf.intercepts_

我们如何解释这些结果?

对于 clf.coefs_ ,你会得到(例如):

[array([[-20.89123833, -8.09121263]]), array([[-20.19430919], [ 17.74430684]])]

并且对于 clf.intercepts_

[array([-12.35004862, 4.62846821]), array([-8.19425129])]

列表的第一项包含隐藏层的参数,第二项包含输出层的参数。

有了这些参数,我们可以绘制曲线:

def sigmoid(x):
    return 1.0/(1+ np.exp(-x))plt.scatter(X,y)
a1_1=sigmoid(xseq*clf.coefs_[0][0,0]+clf.intercepts_[0][0])
a1_2=sigmoid(xseq*clf.coefs_[0][0,1]+clf.intercepts_[0][1])
output=sigmoid(a1_1*clf.coefs_[1][0]+a1_2*clf.coefs_[1][1]+clf.intercepts_[1])plt.plot(xseq,a1_1,c=”red”)
plt.plot(xseq,a1_2,c=”blue”)
plt.plot(xseq,output,c=”black”)

我们可以得到下面的图表:

  • 红色的是隐藏层的神经元 1 的结果
  • 蓝色的是隐藏层的神经元 2 的结果
  • 黑色的是输出

如果您运行代码,您可能会得到另一个结果,因为损失函数有几个全局最小值。

keras 中,当然也可以创建相同的结构:

from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(2, activation=’sigmoid’))
model.add(Dense(1, activation=’sigmoid’))
model.compile(loss=’binary_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])
model.fit(X_train, y_train, epochs=300)

从头开始编码

现在的问题是这七个参数是怎么找到的?一种方法是使用梯度下降。

正向传播

首先,让我们做正向传播。

对于每个神经元,我们必须找到权重 w 和偏差 b。让我们尝试一些随机值。

plt.scatter(X,y)
plt.plot(xseq,sigmoid(xseq*(-11)-11),c="red")

由于有两个神经元,我们可以通过为参数创建矩阵来进行矩阵乘法:

  • 权重矩阵应该有两列。(因为这里输入数据有一列,所以权重矩阵应该有一行两列)。我们可以做一个随机的初始化,选择一些值。
  • 偏置应该具有相同的结构。
w1=np.random.rand(X.shape[1],2) # random initialization
w1=np.array([[-1,9]])
b1=np.array([[-1,5]])z1=np.dot(X, w1)+b1
a1=sigmoid(z1)

如果您只是在阅读,而不是同时运行笔记本,可以做的一个练习是回答以下问题:

  • np.dot(X,w1)的维数是多少?
  • z1 的尺寸是多少?
  • 为什么做加法可以?如果 b1 是一个简单的一维数组呢?
  • a1 的维数是多少?

如果我们用之前创建的 xseq 替换输入 X,我们可以绘制曲线:

a1_seq=sigmoid(np.dot(xseq.reshape(-1,1), w1)+b1)plt.scatter(X,y)
plt.plot(xseq,a1_seq[:,0],c="red")
plt.plot(xseq,a1_seq[:,1],c="blue")

现在对于输出,这是一个非常相似的计算。

  • 权重矩阵现在有了行,因为隐藏层产生了两列的矩阵。
  • 偏差矩阵是一个标量
w2 = np.random.rand(2,1)
b2=0
output=sigmoid(np.dot(a1,w2)+b2)

然后我们可以用其他曲线来绘制输出

output_seq=sigmoid(np.dot(a1_seq,w2)+b2)plt.scatter(X,y)
plt.plot(xseq,a1_seq[:,0],c=”red”)
plt.plot(xseq,a1_seq[:,1],c=”blue”)
plt.plot(xseq,output_seq,c=”black”)

如你所见,随机选择的参数并不好。

总结一下正向传播:

def feedforward(input,w1,w2,b1,b2):
    a1 = sigmoid(np.dot(input, w1)+b1)
    output = sigmoid(np.dot(a1, w2)+b2)
    return output

成本函数的可视化

合适的参数是那些最小化成本函数的参数。我们可以使用交叉熵:

该函数可以编码如下:

def cost(y,output):
    return -np.sum(y*np.log(output)+(1-y)*np.log(1-output))/12

由于有 7 个参数,可视化成本函数并不容易。我们就选择其中一个来变化吧。例如 w1 中的第一重量。

b1=np.array([[16.81,-23.41]])
w2= np.array([28.8,-52.89])
b2=-17.53p = np.linspace(-100,100,10000)for i in range(len(p)):
    w1=np.array([[p[i],-37.94]])
    output=feedforward(X,w1,w2,b1,b2)
    cost_seq[i]=cost(y,output)

你可以看到它一点也不凸。

也有可能改变两个参数。

为了更好地形象化成本函数,我们还可以制作一个动画。

现在让我们用梯度下降法找到这个成本函数的一些合适的全局最小值,这叫做反向传播。

反向传播

偏导数可能会很难看,但幸运的是,有了交叉熵作为损失函数,最终的结果会有一些简化。

这又是成本函数:

  • 请注意,当您使用成本函数来计算模型的成本时,此函数的输入变量是模型的输出和目标变量的真实值。
  • 如果我们试图找到模型的最佳参数,那么我们认为这个成本函数的输入变量就是这些参数。我们要计算成本函数对每个参数的偏导数。

对于 w1 的偏导数,使用链式法则,我们有:

首先,对于 sigmoid 函数,导数可以写成:

(请注意,代价函数是函数之和,函数之和的偏导数是函数的偏导数之和,所以为了简化记法,我们将去掉和符号,确切地说是均值计算)。

我们先按如下计算前两项:

而且我们可以注意到,它们可以简化为(yhat-y)。

然后我们得到 w1 的最终结果:

对于 b1,表达式非常相似,因为唯一的区别是最后的偏导数:

我们将用矩阵乘法对计算进行编码。在编码之前,我们可以问自己一些问题(并回答它们):

  • 残差的维数是多少(yhat — y)?它是一个列向量,行数等于总观察数。
  • w2 的维度是多少?这是一个两行一列的矩阵。记住,它是两个隐藏神经元的权重矩阵,用来计算输出。
  • (yhat — y)w2 的维数是多少?因为维数 w2 是(2,1),所以我们不能做简单的乘法。我们做什么呢我们可以转置 w1 矩阵。然后(yhat — y)w2 会给我们一个两列和 12 个观察值的矩阵。这是完美的,因为我们想要计算每一个重量。
  • a1 的维数是多少?这是隐藏层的结果。因为我们有两个神经元,a1 有两列和 12 个观察值。并且与先前矩阵的乘法将是逐元素的乘法。
  • 所有这些都是非常一致的,因为最终,我们将得到一个包含 2 列和 12 个观察值的矩阵。第一列与第一个神经元的权重相关联,第二列与隐藏层中第二个神经元的权重相关联。

让我们做一些编码:

d_b1_v=np.dot((output-y), w2.T) * a1*(1-a1)

这个矩阵代表什么?我们可以再次展示对 b1 的偏导数。

矩阵 d_b1_v 是所有观测值的偏导数。而要得到最终的导数,就要计算那些与所有观测值相关的和(记住,L 是函数的和),并计算*均值。

d_b1=np.mean(d_b1_v,axis=0)

对于 w1,我们必须考虑 x。对于每一个观察值,我们必须用 x 的值乘以以前偏导数得到的值,然后将它们全部相加。这就是一个点积。为了得到*均值,我们必须除以观察次数。

d_w1 = np.dot(X.T, d_b1_v)/12

现在,让我们继续输出层的参数。会简单很多。

我们已经有了:

所以 w2 和 b2 的导数是:

对于 b2,我们只需对残差求和

np.sum(output-y)/12

对于 w2,它是 a1(层 1 的结果)和残差之间的点积。

np.dot(a1.T, (output-y))/12

包装中的最终算法

现在我们可以创建一个类来包含向前传播和向后传播这两个步骤。

我使用了基于这篇非常受欢迎的文章的 python 代码。你可能已经看过了。不同之处在于

  • 损失函数(交叉熵代替均方误差)
  • 添加学习率
class NeuralNetwork:
    def __init__(self, x, y):
        self.input = x
        self.w1 = np.random.rand(self.input.shape[1],2)
        self.w2 = np.random.rand(2,1)
        self.b1 = np.zeros(2)
        self.b2 = 0.0
        self.y = y
        self.output = np.zeros(self.y.shape) def feedforward(self):
        self.a1 = sigmoid(np.dot(self.input, self.w1)+self.b1)
        self.output = sigmoid(np.dot(self.a1, self.w2)+self.b2) def backprop(self):
        lr=0.1 res=self.output-self.y d_w2 = np.dot(self.a1.T, res)
        d_b2 = np.sum(res)
        d_b1_v=np.dot(res, self.w2.T) * self.a1*(1-self.a1)
        d_b1 = np.sum(d_b1_v,axis=0)
        d_w1 = np.dot(self.input.T, d_b1_v) self.w1 -= d_w1*lr
        self.w2 -= d_w2*lr
        self.b1 -= d_b1*lr
        self.b2 -= d_b2*lr

然后可以在梯度下降过程中存储 7 个参数的中间值,并绘制曲线。

动画是用 R 代码中的图形制作的。所以如果你对神经网络的 R 代码从零开始感兴趣,请评论。

如果你的代码对你来说很难理解,我还创建了一个 Excel (Google Sheet)文件来做梯度下降。如果你感兴趣,请在评论中告诉我。是的,你可能会认为在 Excel 中进行机器学习是疯狂的,我同意你的观点,尤其是在完成了所有七个参数的梯度下降的所有步骤之后。但目的是为了更好地理解。为此,Excel 是一个非常好的工具。

可视化缺失值和缺失号

原文:https://towardsdatascience.com/visualize-missing-values-with-missingno-ad4d938b00a1?source=collection_archive---------18-----------------------

浏览数据集中缺失的值。

伊琳娜Unsplash 上的照片

数据是新的燃料。然而,原始数据很便宜。我们需要好好处理它,从中获取最大价值。复杂的、结构良好的模型和我们提供给它们的数据一样好。因此,需要对数据进行彻底的清理和处理,以建立可靠和准确的模型。

我们在原始数据中可能遇到的一个问题是缺少值。考虑这样一种情况,我们在一些观察值(数据帧中的行)上有特征(数据帧中的列)。如果我们没有特定行列对中的值,那么我们就有一个缺失值。我们可能只有几个丢失的值,或者整个列的一半丢失。在某些情况下,我们可以忽略或删除缺少值的行或列。另一方面,在某些情况下,我们甚至不能丢失一个丢失的值。在任何情况下,处理缺失值的过程都是从在数据集中探索它们开始的。

Pandas 提供了检查数据集中缺失值数量的函数。 Missingno 库更进一步,通过信息可视化提供数据集中缺失值的分布。使用缺失号的图,我们能够看到缺失值在每一列中的位置,以及不同列的缺失值之间是否存在相关性。在处理缺失值之前,在数据集中探索它们是非常重要的。因此,我认为 missingno 是数据清理和预处理步骤中非常有价值的资产。

在本帖中,我们将通过一些例子来探索无遗漏绘图的功能。

让我们首先尝试探索一个关于流媒体*台上电影的数据集。数据集在 kaggle 上的处可用。

import numpy as np
import pandas as pddf = pd.read_csv("/content/MoviesOnStreamingPlatforms.csv")
print(df.shape)
df.head()

该数据集包含 16744 部电影和描述每部电影的 17 个特征。Pandas isna返回缺失值,我们应用sum函数来查看每一列中缺失值的数量。

df.isna().sum()

“年龄”和“烂番茄”列有许多缺失值。大约有 6 个其他列的缺失值数量超过 200。现在让我们使用 missingno 来看看我们是否能对丢失的值有一个更好的直觉。

import missingno as msno
%matplotlib inline

我们导入了缺少库。%matplotlib inline命令允许在 jupyter 笔记本中渲染可视化效果。我们使用的第一个工具是缺失值矩阵。

msno.matrix(df)

白线表示缺少值。“年龄”和“烂番茄”列如我们所料被白线所支配。但是,在其他缺少值的列中有一个有趣的趋势。它们通常在公共行中缺少值。如果某行的“导演”列中缺少值,则很可能“流派”、“国家”、“语言”和“运行时间”列中也缺少值。在处理缺失值时,这是非常有价值的信息。

热图用于可视化显示不同列之间值的相关性的相关矩阵。Missingno 库还提供热图,显示不同列中的缺失值之间是否有任何关联。

msno.heatmap(df)

正相关与蓝色的黑暗程度成比例,如右边的条所示。“导演”、“流派”、“国家”、“语言”、“运行时间”栏目之间存在不同程度的正相关关系。“语言”和“国家”之间的相关性最高,为 0.8。这证实了我们对缺失值矩阵的直觉,因为这些列在相同的行中有缺失值。

missingno 的另一个工具是缺失值的条形图。

msno.bar(df)

它显示与非缺失值的数量成比例的条形,并提供非缺失值的实际数量。我们知道每一列丢失了多少。

正如我们前面提到的,为了很好地处理缺失值,我们需要理解数据集在缺失值方面的结构。仅仅知道缺失值的数量是不够的。缺少库的情节对理解缺少的值很有帮助。完成这一步后,我们可以开始考虑如何处理丢失的值。

下面的帖子提供了如何处理熊猫丢失值的详细指导。Missingno 和 pandas 可以一起使用,以便建立一个健壮而有效的策略来处理缺失值。

[## 用熊猫处理缺失值

关于如何检测和处理缺失值的完整教程

towardsdatascience.com](/handling-missing-values-with-pandas-b876bf6f008f)

感谢您的阅读。如果您有任何缺失值,请告诉我。

使用 MDS 可视化多维数据集

原文:https://towardsdatascience.com/visualize-multidimensional-datasets-with-mds-64d7b4c16eaa?source=collection_archive---------28-----------------------

多维标度可以帮助您可视化数据,甚至在二维以上

数据可视化是数据科学中最令人着迷的领域之一。有时候,使用一个好的绘图或图形表示可以让我们更好地理解隐藏在数据内部的信息。我们如何在二维以上的情况下实现它?

只要我们使用二维数据集,一个简单的散点图对可视化模式和事件非常有用。如果我们使用三维数据,仍然有机会使用 3d 绘图来可视化一些东西。

但是如果我们想要可视化更高维的数据集会发生什么呢?事情会变得更加困难。想想聚类问题。如果我们可以在许多维度上可视化数据,以便检查是否存在一些模式,那将是非常美妙的。

当然,我们没有多维的视野,所以我们必须将多维数据转化为二维数据。有一种算法可以做到这一点,那就是 MDS。

什么是 MDS?

MDS(多维缩放)是一种算法,它将一个数据集转换为另一个数据集,通常具有更低的维度,并保持点之间的欧氏距离不变。

保持距离是 MDS 的一个非常有用的特性,因为它允许我们合理地保持模式和聚类,例如,如果我们想要执行 K-Means 或其他类型的聚类。

因此,举例来说,如果我们有一个 4 维数据集,并希望将其可视化,我们可以使用 MDS 在 2 维缩放它。点之间的距离保持在原始数据集中,因此,如果数据自组织成簇,即使在缩放过程之后,它们也是可见的。

当然,低维新点的坐标不再有商业价值,是无量纲的。值由散点图的形状和点之间的相对距离决定。

值得一提的是,在将数据集交给 MDS 之前,应该对其进行规范化或标准化。例如,这非常类似于我们对 K 均值聚类所做的工作。原因很简单:我们不希望仅仅因为某些特征的数量级比其他特征高,就赋予它们更多的权重。简单的 0-1 归一化将有效地解决这个问题。

在 Python 中,在包sklearn的模块manifold下有一个很好的 MDS 实现。让我们看一个使用著名的 Iris 数据集的例子。

Python 中的一个例子

我们将使用 MDS 对虹膜数据集的 4 个特征进行二维缩放,使其可视化。首先,我们将对特征进行 0-1 的缩放,然后我们将进行二维 MDS 并绘制新数据,根据虹膜数据集的目标变量为每个点赋予不同的颜色。

让我们开始导入一些库。

import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
from sklearn.manifold import MDS
from sklearn.preprocessing import MinMaxScaler

现在,让我们加载虹膜数据集。

data = load_iris()
X = data.data

我们现在可以用MinMaxScaler进行 0-1 的缩放

scaler = MinMaxScaler()
X_scaled = scaler.fit_transform(X)

然后,我们应用 MDS 程序得到一个二维数据集。设置 random_state 是为了使每个图都可以再现。

mds = MDS(2,random_state=0)
X_2d = mds.fit_transform(X_scaled)

最后,我们可以绘制新的数据集。

colors = ['red','green','blue']plt.rcParams['figure.figsize'] = [7, 7]
plt.rc('font', size=14)for i in np.unique(data.target):
  subset = X_2d[data.target == i]

  x = [row[0] for row in subset]
  y = [row[1] for row in subset] plt.scatter(x,y,c=colors[i],label=data.target_names[i])plt.legend()
plt.show()

这是结果。

如您所见,“setosa”点距离其他点非常远,它们自己创建了一个集群。如果不以这种方式绘制数据,就很难获得这种洞察力。

结论

使用 MDS 可视化多维数据在许多应用中非常有用。例如,它可用于检测某些多元分布中的异常值。考虑一下预测性维护,有些设备的行为会偏离其他设备。另一个有用的用例是集群。在使用 K-Means 或 DBSCAN 之前,查看数据是否自组织成簇是有用的。如果数据集不太大,MDS 计算会非常简单快捷。否则,云架构可以成为加速计算的有用工具。

参考

[1]多维标度。维基百科https://en.wikipedia.org/wiki/Multidimensional_scaling

用 R #新冠肺炎想象疫情

原文:https://towardsdatascience.com/visualize-the-pandemic-with-r-covid-19-c3443de3b4e4?source=collection_archive---------13-----------------------

作为一名数据科学家,你可以用新冠肺炎数据做什么。

资料来源:JHU·CSSE

按照疾病预防控制中心的建议,我们可以做两件事:阅读关于新冠肺炎的新闻,以及被不断增加的病例数压垮。过去几周情况有多糟?我的手机不停地播放着来自世界各地的新闻:首先是我在中国的家乡,然后是亚洲其他地方、欧洲和美国。超过一半的纽约已经停止通勤。我们已经用拳头碰撞代替了握手,现在,新的标准是:社交距离。五天前的 3 月 12 日,世界卫生组织宣布新冠肺炎为疫情。到目前为止,全世界 142 个国家超过 16 万人被确诊患有这种疾病。我觉得有义务用 R 创建一个追踪器来解释这个疫情。

我用的是南方医科大学广创于博士研发的 R 包“ nCOV2019 ”。这个软件包允许我们访问所有国家案例的最新数据和历史数据,在地图上绘制数据,并创建各种图表。如果你像我一样是一个有抱负的数据科学家,请随意安装该软件包,并按照以下步骤创建可视化:

部署软件包

探索数据

创建视觉效果

  • 按国家的折线图
  • gif 中的全球新冠肺炎增长

影响分析

  • 接下来 10 天我们会有多少病例?
  • 冠状病毒正在影响好莱坞吗?
  • 我们还在外面吃饭吗?(带 OpenTable 数据)

部署包

提取该包中嵌入的数据的基本函数有:

  • get_nCov2019()查询网上最新信息
  • load_nCov2019()获取历史数据
  • summary[访问数据
  • plot在地图上显示数据

安装并部署软件包

remotes::install_github(“GuangchuangYu/nCov2019”)
**require**(nCov2019)
**require**(dplyr)

第一印象

x <- get_nCov2019()
y <- load_nCov2019()> xChina (total confirmed cases): 81134last update: 2020–03–17 21:19:04> ynCov2019 historical datalast update: 2020–03–16

跟上时代是非常重要的。简单地打印 x 和 y 将刷新数据。

> x['global',]name confirm suspect dead deadRate showRate  heal healRate showHeal1                          China   81134     128 3231     3.98    FALSE 68800    84.80     TRUE2                          Italy   27980       0 2158     7.71    FALSE  2749     9.82    FALSE3                           Iran   16169       0  988     6.11    FALSE  5389    33.33    FALSE4                          Spain   11178       0  491     4.39    FALSE   571     5.11    FALSE5                    South Korea    8320       0   83        1    FALSE  1401    16.84    FALSE6                        Germany    7272       0   17     0.23    FALSE   135     1.86    FALSE7                         France    6650       0  148     2.23    FALSE    28     0.42    FALSE8                  United States    4687       0   93     1.98    FALSE    74     1.58    FALSE9                    Switzerland    2269       0   19     0.84    FALSE     4     0.18    FALSE10                United Kingdom    1950       0   56     2.87    FALSE    52     2.67    FALSE

如何创建数据的概览?x[‘global’,]返回最新的全球数据,并按确诊病例数自动排序。

探索数据

首先,让我们探索当前数据的整体结构。DataExplorer 是一个 R 包,可以快速构建可视化。

#explore package
**library**(DataExplorer)
plot_str(x)

通过get_nCov2019()函数获得的数据包括 3 个列表和 5 个数据帧。这些是中国和世界各地确诊患者、死亡和康复病例的最新数据。

plot_str(y)

为了研究趋势,我重点研究了历史数据。通过函数load_nCov2019()获得的历史数据是一个列表,包括 3 个数据帧。名为“数据”的第一个数据框架是中国城市层面的历史数据,包括确诊病例、死亡、康复和疑似病例的数量。第二个名为“省”的是省级别的聚合数据。第三个数据框架“全球”包括世界各国的确诊病例、死亡和恢复情况。这些历史数据涵盖了从 2 月 15 日到最*更新的时间范围。

> summary(x['global',])
     name              confirm           suspect              dead           deadRate        
 Length:131         Min.   :    1.0   Min.   :  0.0000   Min.   :   0.00   Length:131        
 Class :character   1st Qu.:    4.5   1st Qu.:  0.0000   1st Qu.:   0.00   Class :character  
 Mode  :character   Median :   30.0   Median :  0.0000   Median :   0.00   Mode  :character  
                    Mean   : 1223.3   Mean   :  0.8626   Mean   :  45.44                     
                    3rd Qu.:  137.5   3rd Qu.:  0.0000   3rd Qu.:   1.00                     
                    Max.   :81062.0   Max.   :113.0000   Max.   :3204.00                     
   showRate              heal           healRate           showHeal        
 Length:131         Min.   :    0.0   Length:131         Length:131        
 Class :character   1st Qu.:    0.0   Class :character   Class :character  
 Mode  :character   Median :    0.0   Mode  :character   Mode  :character  
                    Mean   :  582.3                                        
                    3rd Qu.:    3.5                                        
                    Max.   :67023.0

我使用了 summary()函数来获得数据的统计概览。全球确诊病例的中位数是 30 例,而*均数是 1223.3 例。原因是异常值中国对*均确诊病例有很大影响。

创造视觉效果

可视化是探索性数据分析的另一个关键方法。通过图像,我们可以很容易地观察到国家和国际层面的疫情趋势。

  • 国别折线图

上面已经提到了如何使用 x['全球',]获得确诊病例最多的前 10 个国家。我们还可以绘制折线图,查看每个国家的病例增长情况。

#obtain top 10 country
d <- y[‘global’] #extract global data
d <- d[d$country != ‘China’,] #exclude China
n <- d %>% filter(time == time(y)) %>%
 top_n(10, cum_confirm) %>%
 arrange(desc(cum_confirm))#plot top 10
**require**(ggplot2)
**require**(ggrepel)
ggplot(filter(d, country %**in**% n$country, d$time > ‘2020–02–15’),
 aes(time, cum_confirm, color=country)) +
 geom_line() +
 geom_text_repel(aes(label=country),
 **function**(d) d[d$time == time(y),]) +
 theme_minimal(base_size=14) +
 theme(legend.position = “none”)

新冠肺炎确诊病例排名前 10 位的国家(不包括中国)

该图显示了中国以外确诊病例最多的前 10 个国家。意大利和伊朗是受感染最严重的国家,并且呈指数增长。与此同时,韩国通过有效的遏制战略,拉*了曲线,放缓了增长速度。其他一些欧洲国家和美国也出现了成千上万的新病例。

  • gif 中的全球新冠肺炎增长

全球的整体情况如何?用 plot()函数可以很容易地绘制出全球新冠肺炎确认数地图。

x <- get_nCov2019()
x
plot(x) #plot global map

新冠肺炎全球 3 月 15 日确诊病例

随着时间的推移会有什么变化呢?如果我们能以 gif 的形式展示这些变化,那将是一个很好的主意。我绘制了从 02-12 到 03-15 每天的全球地图,并用 R 包 magick 创建了一个 gif。

#visualize global growth over time
**library**(magick)y <- load_nCov2019()d <- c(paste0(“2020–02-”, 12:29), paste0(“2020–03–0”, 1:9), paste0(“2020–03–1”, 0:5))
img <- image_graph(1200, 700, res = 96)
out <- lapply(d, **function**(date){
 p <- plot(y, date=date,
 label=FALSE, continuous_scale=TRUE)
 print(p)
})
dev.off()animation <- image_animate(img, fps = 2)
print(animation)

新冠肺炎全球 2 月 12 日至 3 月 15 日确诊病例

现在我们可以看到冠状病毒是如何从中国开始,在短短一个月内传播到世界上大多数国家的。

影响分析

  • 在接下来的 10 天内,我们会有多少个案例?

接下来,我们可以使用现有数据预测未来的病例增长。

以美国为例。

新冠肺炎确诊病例在美国增长

通过查看图表,我们可以很容易地发现病例以指数速度增长。在这种情况下,我们可以应用对数线性回归来建模和预测增长。我只考虑确诊病例超过 100 例的时间段,原因如下:

  • 早期测试中
  • 早期病例大多与旅行有关,而不是社区传播
usdata <- d %>%filter(d$country == ‘United States’ & d$cum_confirm>100) %>%select(time,cum_confirm)library(forecast)case <- ts(usdata[,2], start=1,frequency = 1)fit <- tslm(log(case) ~ trend)fc <- forecast(fit, h=10)

美国确诊病例对数的时间回归模型

我们的对数线性模型非常适合数据集。0.9974 的调整 R *方表明 99%的方差可以用我们的模型来解释。

Residuals:Min        1Q    Median        3Q       Max-0.095126 -0.036574 -0.000754  0.036861  0.069923Coefficients:Estimate Std. Error t value Pr(>|t|)(Intercept) 4.311641   0.032840  131.29  < 2e-16 ***trend       0.288296   0.004462   64.61 1.92e-14 ***---Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1Residual standard error: 0.05336 on 10 degrees of freedomMultiple R-squared:  0.9976, Adjusted R-squared:  0.9974F-statistic:  4175 on 1 and 10 DF,  p-value: 1.92e-14

现在我们可以回答这个问题了,10 天内我们会有多少个案例?

我们可以用forecast()来做未来 5 天的预测(h 周期用来设置预测周期)。

Forecasts:Point Forecast     Lo 80     Hi 80     Lo 95     Hi 9515       5382.300  4936.042  5868.904  4683.598  6185.23516       7148.845  6541.200  7812.938  6198.094  8245.43617       9495.195  8666.463 10403.174  8199.463 10995.68618      12611.649 11479.941 13854.922 10843.598 14667.98119      16750.966 15204.003 18455.327 14336.190 19572.48420      22248.863 20132.776 24587.365 18948.614 26123.91221      29551.247 26655.278 32761.849 25038.879 34876.81022      39250.374 35286.012 43660.130 33079.244 46572.76423      52132.888 46705.412 58191.072 43692.648 62203.55324      69243.620 61813.326 77567.075 57700.726 83095.642

预测结果显示,如果确诊病例继续以指数速度增长,该数字将在 3 天内翻一番,并在 10 天内达到* 70,000 人。

这就是采取预防措施如此重要的原因。在数周的逐渐增长后,受感染人数会突然增加,这在最初似乎是可以控制的。医疗能力将不堪重负,医护人员将处于危险之中。

重要的是,我们都开始社交距离,避免去公共场所,以减缓增长速度,否则就太晚了。

  • 冠状病毒在影响好莱坞吗?

几个主要城市已经关闭了电影院,以避免人群聚集。然而,大多数北美影院在过去的周末仍然开放。好莱坞受到疫情影响了吗?

我从 boxofficemojo.com 收集了 2019 年和 2020 年的每日票房数据,并将今年的票房表现与去年进行了比较。然后,我将结果绘制在一张线图上。

ggplot(boxoffice,
 aes(date, rate))+
 geom_line(color = ‘red’) +
 geom_hline(yintercept=0) +
 theme_minimal(base_size=14) +
 scale_y_continuous(“year-on-year box office”, labels=scales::percent, breaks = c(seq(-1,0.5,0.1)))

逐年美国票房对比

结果是惊人的。3 月 5 日的票房与去年相比下降了 60%,3 月 17 日的票房几乎下降了 70%。

据综艺报道,北美影院的票房收入创下二十年来的新低。

随着越来越多的城市开始关闭电影院,我们可能会看到票房收入进一步下降。

  • 我们还在外面吃饭吗?(带 OpenTable 数据)

我在推特上看到很多抱怨,尽管疾控中心警告避免人群聚集,人们仍然去酒吧和餐馆。人们还像往常一样在外面吃饭是真的吗?

我看到了在线餐厅预订提供商 Opentable 发布的用餐人数数据。

数据显示了 OpenTable 网络上所有渠道的餐厅年复一年的用餐人数:在线预订、电话预订和上门预订。我绘制了美国和欧洲六个主要城市从 2 月 18 日到今天的食客变化:拉斯维加斯、洛杉矶、纽约、伦敦、多伦多和汉堡。

ggplot(opentable,
 aes(date, rate, color=City)) +
 geom_line() +
 geom_text_repel(data = opentable[opentable$date == “2020–03–16”,], aes(label=(City)) +
 theme_minimal(base_size=14) +
 geom_hline(yintercept=0) +
 scale_y_continuous(“year-on-year change”, labels=scales::percent, breaks = c(seq(-1,0.5,0.1))) +
 theme(legend.position = “none”)

逐年 Opentable 保留比较

图表显示,自三月份的第二周以来,所有六个主要城市的餐馆顾客数量都在快速下降。每个城市的用餐人数都下降了 50%以上。在洛杉矶,这个数字与去年相比下降了 80%以上。

数据证明,人们外出就餐的次数比*时少了,这对餐饮业尤其有害。由于大多数餐馆的利润率相对较低(3%-5%),固定成本比率较高,因此收入的小百分比下降就足以扼杀业务,并将员工送上街头。

尽管新冠肺炎没有完全阻止美食家去餐馆,但在未来几周,他们这样做的机会可能会减少。像麦当劳和塔可钟这样的几家食品连锁店正在关闭他们的餐饮服务。与此同时,纽约市和俄亥俄州关闭了该地区所有的酒吧和餐馆。

按照上面的步骤,你可以创造出和我一样的视觉效果,如果不是更好的话。当冠状病毒仍在全球传播时,作为一名数据爱好者,您也可以使用“ncov 2019”R 包探索新冠肺炎数据,并帮助向人们通报您的发现。

我要感谢 Alice Yang 提供的建设性意见。

— — — — — —

嗨!我叫钱。我是一名数据爱好者,擅长数据分析和数据可视化。我目前正在纽约市攻读营销情报硕士学位。自从今年一月中国武汉爆发冠状病毒以来,我一直在关注它。上个月,我在美国仪表盘中创建了一个新冠肺炎,让人们跟踪美国的最新情况。(查看这里)现在我正在寻找实习机会。我很想和你一起喝杯(虚拟)咖啡!

我的 LinkedIn

在 xinhan.qian@outlook.com 联系我

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

可视化稀疏矩阵

原文:https://towardsdatascience.com/visualizing-a-sparse-matrix-1c4c807ea6c9?source=collection_archive---------35-----------------------

怎么知道自己有没有稀疏矩阵?想象一下!

亨利&公司在 Unsplash 上拍摄的照片

机器学习的许多领域通常使用稀疏矩阵。如果你曾经使用 One-Hot-Encoding、CountVectorizing 或 TfidVectorizing 对 NLP 字典进行过矢量化处理,你应该知道我指的是什么。

简而言之,稀疏矩阵包含许多零,而密集矩阵则不包含。

import scipy.sparse as sparse
import matplotlib.pyplot as plt*%matplotlib inline*# adjust the density parameter
sparse = sparse.random(10,10, density=0.015)
sparse.toarray()

稀少的

稠密的

plt.figure(figsize=(15, 15))
plt.spy(sparse, markersize=1)

稀少的

稠密的

我目前正在使用一个超过 15,000 个单词的 NLP 字典,我一直想看看这样大小的稀疏矩阵会是什么样子。尽情享受吧!

可视化人工智能

原文:https://towardsdatascience.com/visualizing-ai-86247fa2a182?source=collection_archive---------31-----------------------

解构和优化 SHAP 的概要情节(2/2)

既然你已经理解了 SHAP 概要图的各个组成部分是如何一起工作的( part 1 ),我将提供一个使用它来解释黑盒机器学习模型的例子。此外,我将讨论示例中可视化的一些问题,然后提供一些改进的想法。这些文章的目标是帮助读者解释可视化,优化它,并对结果有更深的理解。

示例:了解工作绩效的影响

这个例子的代码可以在 GitHub 的这里找到。

数据:人力资源数据集

我使用的数据是 IBM 的人力资源数据,可以在 Kaggle 获得。这些数据的最初目的是为了了解人员流失,但在这里我用它来了解工作场所的绩效评定。

IBM HR 数据集的一个片段

为了减少必要的数据准备量,我通过减少特征的数量来简化数据。此外,对数据的检查表明,绩效评级被限制在 3 或 4(满分为 1-4)。因此,为了使用数据来说明回归数据的汇总图的功能,我通过应用一组转换将评级重新调整为 0-9 之间的实数(参见 GitHub 上的数据文件)。

在下面对结果的讨论中,我将分析这些假定虚构的数据,并假设数据和最终模型背后可能的故事。

汇总图

在这个练习中,我使用了 scikit-learn 中的随机森林算法,并使用了 SHAP 树解释器进行解释。

model = RandomForestRegressor(max_depth=4, random_state=1,               n_estimators=10)model.fit(X_train, y_train)shap_values = shap.TreeExplainer(model).shap_values(X_train)

下图显示了在我们的示例中使用 SHAP 的过程。

下面的条形图显示了要素名称及其对应的*均 SHAP 值。

这种类型的条形图是特征属性算法结果的典型表示。在这里,它根据*均 SHAP 值按重要性降序列出了这些特征。

如上所示,具有最高*均 SHAP 值的要素是“PercentSalaryHike”。这个值是如此的重要,以至于很难说出其他顶尖影响者的相对差异。事实上,“PercentSalaryHike”占主导地位,这表明数据或我们对数据的解释可能有问题。

让我们进一步调查。摘要图如下所示:

上面的汇总图显示,“PercentSalaryHike”的高值(红点)与正 SHAP 值相关,而“PercentSalaryHike”的低值(蓝点)通常与负 SHAP 值相关。

由于原始数据没有指定相对于绩效评定的加薪时间,因此对结果有两种解释:

  1. 绩效评分高是因为之前的薪资评估导致薪资大幅提升。
  2. 高工资是高绩效评定的结果。换句话说,员工因为出色的工作表现而获得丰厚的加薪。

在我看来,合乎逻辑的解释可能是#2。也就是说,员工因为表现良好而获得高百分比的加薪。当然,这是我的猜测,但它很好地提醒了我们,XAI 工具总体上反映了底层机器学习算法的本质。具体来说,它们在相关性领域中运行,并且它们的结果在因果方向方面是模糊的。因此,结果并没有告诉我们“PercentSalaryHike”是好的工作表现的原因,它只是告诉我们它是高度相关的。在这种情况下,比模型中的其他特征更明显。

在前五个特征中,“年龄”似乎也遵循一种模式,即高值与高 SHAP 值相关联,低值与低 SHAP 值相关联。这种模式似乎也适用于摘要图中的“StockOptionLevel ”,尽管对比度较小。

其余要素的 SHAP 值似乎聚集在零附*,但由于绘图中需要缩放,因此很难看到细节。也就是说,为了容纳来自第一特征的大值,必须压缩可视化。

优化 SHAP 汇总图

显然,尽管汇总图本身是有用的,但有许多问题妨碍我们更容易地理解结果。在这一节中,我将讨论其中一些问题,并提出在 SHAP 解决这些问题的建议。

改善对比度和颜色选择

首先也是最重要的是使用红色来表示高价值。红色是一种非常情绪化的颜色。它通常被用作危险的警告,在西方文化中通常有负面的含义。红色的使用和关闭本身并不是问题。然而,在我们的例子中,这是特别成问题的,因为我们处理的是金钱价值、经验和年龄,而高价值可能不是一件坏事。在这种情况下理解一个情节尤其困难,因为颜色和特征值之间的相互作用会产生认知干扰

第二个问题是,由于对颜色不敏感,从蓝色到红色的过渡可能会对一些用户造成差异问题。特别是,蓝色和紫色的使用要避免相互重叠。

摘要图设计者犯的错误类似于那些使用“彩虹色”方案进行数据可视化的错误(例如在“热图”中)。也就是说,彩虹色调色板看起来很吸引人,但在感知和语义上有问题

已经有讨论关于为“点”类型提供定制调色板(主要作为处理业务需求的一种方式),但是到目前为止它仍然是即将到来的。为了解决所讨论的问题,我调整了源代码并删除了红色的使用。我也选择了单一的颜色,但改变了亮度,使其更容易看到色差。

新的汇总图如下所示:

我认为由此产生的图更容易一眼解析,因为有更少的颜色需要破译。此外,切换到更亮的蓝色作为高数字的指示,使更高的值更加突出。但是,对于习惯于将蓝色视为低数字的用户来说,这可能是一个问题。如果是这种情况,我会推荐翻转两端颜色。

减少特征的数量

遵循一个众所周知的设计策略,我剔除了一些没用的信息。由于要素的大多数值彼此非常接*,并且大多数 SHAP 值都接*于零,因此我们有必要通过设置 max_display 参数来关注顶部的要素集:

shap.summary_plot(shap_values, X_train, max_display=5)

移除不明确的特征

如上所述,不清楚“PercentSalaryHike”是绩效评级的事前衡量还是事后衡量。如果员工因良好的绩效评级而获得加薪,那么这就不那么令人感兴趣了,因为我们感兴趣的是有助于良好绩效的因素。虽然观察以前的加薪是否对绩效评级有任何影响也很有趣,但鉴于不清楚加薪的时间,谨慎的做法是完全消除这种影响。

上面关于“PercentSalaryHike”模糊性的评论也可以应用于与货币值相关联的其他特征。对于前 5 名,这包括“StockOptionLevel”。在我们的分析中,我们可以假设其他因素(如工作距离、年龄)保持相对相似,无论它们是工作绩效评定的后评估还是前评估。

更好的缩放

由于“PercentSalaryHike”占主导地位,x 轴的刻度必须扩展以适应值的大小。因此,很难看出 SHAP 值是如何分布的。

幸运的是,从前五个特性中删除“PercentSalaryHike”和“StockOptionLevel”可以自动解决这个问题。我们模型的新汇总图如下所示,放大倍数更合适。

由此产生的情节更简单,更容易理解。该图显示,较高的总工作年限和年龄值与较高的 SHAP 值相关(这反过来意味着较高的绩效评级)。此外,低值也与低 SHAP 值相关。这支持了成熟度和工作经验有助于良好工作表现的想法。

第三个特征更难解释。较高的“离家距离”(即住得离工作地点较远)似乎与较高的 SHAP 值相关。如果不了解在家工作的政策以及员工对在家工作的感受,就很难解释这个结果。此外,色标之间的对比度不是特别明显,因为该图显示一些高值也会对性能评级产生负面影响(左侧的浅蓝色点)。这一结果表明,这是一个值得研究的领域,并建议人力资源部门在通勤领域以及在家工作政策的总体影响方面开展进一步的研究。

当然,这是虚构的数据,因此这里的任何解释都纯粹是为了演示可以完成的潜在分析。除了 SHAP 值的大小和它们之间的微小差异之外,摘要图显示大多数值倾向于聚集在零附*的事实也提醒我们,最好谨慎地解释结果,并且需要收集额外的确证证据。

关于 XAI 改进的一些设想

亚当·诺瓦克斯基在 Unsplash 上的照片

虽然设计更好的 XAI 系统,一般来说,超出了本文的范围,但我想简要地讨论一些当前工具可以立即做出的改进的设想;尤其是在用户体验和数据可视化设计领域。

  • 提供更好的对比度和颜色选择。不仅要避免可能引起混淆的颜色(例如,使用红色来表示好的结果),还要在调色板中提供易于识别的选择,并且对所有用户都是通用的。
  • 能够交互式地从可视化中移除特定特征。来自社会科学的研究表明“解释是被选择的”,从这个意义上说,我们从一组可能的原因中挑选一两个原因作为解释。对于最终用户使用的 XAI 工具,可视化需要变得更具交互性。它们需要允许用户轻松地选择一组特性并关注它们,而不需要以编程方式明确地这样做。
  • 支持迭代探索。最*的一项研究表明,寻找解释的过程是反复的。事实上,上述定位少数有影响特征的过程遵循了寻找解释的迭代分析模式。能够看到结果,探索不同的可能性,对比不同的特征,检查它们的相互作用,等等。反复地做这件事对于接受解释的用户来说是非常有价值的。
  • 支持从高级视图到功能级别的单个视图的转换。在前面的基础上,放大/缩小、从聚焦一个功能或对比一组功能的能力将允许用户跟踪他们的调查以及处理我们在示例中遇到的缩放问题。

无需等待 XAI 的重大研究突破,我认为可以立即做出一些具体的改进,以便它们可以用来更好地解释机器学习模型的结果。希望以后能多写点这个话题。

总结和结论

在本文中,我使用了 SHAP 摘要图来解释黑盒模型输出背后的影响。利用可视化,我假设了数据和最终模型背后的一个可能的故事。在讲述一个假设故事的过程中,我发现了一些数据中的模糊之处,以及 SHAP 概要情节设计中的问题。然后,我提出了一些改进可视化的想法,并确定了澄清数据所需的进一步工作。最后,我为 XAI 系统提供了一些尝试性的想法,这样它们就可以适应用户寻求解释时的行为方式。

SHAP 带来了许多丰富的可视化效果,值得比现在更多的关注。如果您是负责向最终用户交付系统或报告的数据科学家,那么希望本文能够帮助您做出必要的调整,以便更有效地使用可视化。如果您是最终用户决策者或最终用户消费者,您现在应该对 SHAP 汇总图有了更好的理解。反过来,这将有望使你能够要求以一种更容易理解的方式呈现结果。

可视化人工智能

原文:https://towardsdatascience.com/visualizing-ai-8fad4ea70b87?source=collection_archive---------24-----------------------

解构和优化 SHAP 的概要情节(1/2)

照片负空格 / CC 由 2.0

人工智能中的可解释性目前是一个热门话题。随着人工智能系统在决策中发挥越来越大的作用,人们普遍认为这些系统需要提供支持其决策或建议的信息。

现在有一个新兴的行业和大量的研究兴趣来提供可解释的人工智能(XAI)工具和服务,旨在帮助人工智能系统向用户解释他们的决策和行动。与此同时,政府开始要求向可能受到自动决策影响的个人提供解释。事实上,欧洲的通用数据保护条例规定,当个人受制于“完全基于自动处理的决定”并产生“法律效力”或类似意义的结果时,个人有权获得“有关所涉逻辑的有意义的信息”。

值得注意的是,最后一句话提出了一个想法,不仅这些系统需要提供解释,而且个人应该能够清楚地理解所提供的信息。毫无疑问,监管的这一部分将在未来引起激烈的争论。然而,从眼前的实际角度来看,这(以及其他正在制定的立法)应被视为一种呼吁,不仅呼吁这些系统提供关于结果如何得出的信息,而且呼吁我们密切关注它们是如何呈现的,以便受影响的个人能够有效地理解它们。

理解可视化

过去,XAI 工具的结果通常以初级形式呈现。例如,用数字表和/或某种条形图。

这些结果很容易解释,但它们的解释力有限。这部分解释了为什么这些工具经常被归类为“可解释的”人工智能,而不是“可解释的”人工智能,因为它们揭示了底层算法正在做什么,但没有以一种全面的方式传达正在发生的事情,以便用户可以带着对解释的“有意义的”理解离开。

最*,一些 XAI 工具已经开始解决这个问题。例如,通过提供丰富的可视化作为对结果的更全面解释的一部分。这些可视化功能非常强大,因为它们超越了传统的基本图形类型的汇总统计。然而,对于门外汉来说,他们更难解释和理解。

在本文的第 1 部分,我将描述 SHAP,一个流行的 XAI 工具,如何展示它的结果。具体来说,我将重点描述它附带的丰富的可视化之一:摘要情节。在第 2 部分中,在提供一些改进可视化的想法之前,我将给出一个使用它来解释黑盒机器学习模型的例子。目标是帮助读者解释可视化,优化它,并对结果有更深的理解。

本文面向对机器学习概念有基本了解,并且有兴趣更彻底地了解 XAI 工具的结果的任何人。就用户类型而言,这篇文章对于负责向最终用户提供报告的数据科学家,或者将要接收 XAI 工具结果的最终用户决策者或最终用户消费者最有用。

SHAP

SHAP 主张沙普利附加解释。它属于一类被称为特征属性或特征重要性的 XAI 工具。这些工具通过揭示不同的输入特征对输出的强烈影响来展示机器学习模型的工作方式。SHAP 使用的方法是合作博弈理论中的一个解决方案,称为沙普利值(以提出这一想法的美国数学家和诺贝尔奖获得者劳埃德·沙普利的名字命名)。

关于 SHAP 是什么,它做什么,如何使用它,以及 Shapley 值背后的数学基础,有很多很好的文章,所以我不会在这里试图详细重复它们。

SHAP 已经在许多*台上实现,但是使用 SHAP 的一般过程如下:

  1. 使用机器学习模型(例如随机森林、神经网络)对数据建模。
  2. 将生成的模型和你的数据输入 SHAP。
  3. SHAP 计算模型的影响(使用沙普利值)并输出一组 SHAP 值。
  4. 然后,您可以使用 SHAP 提供的可视化工具显示输出。

SHAP 并不是唯一实现沙普利价值观的工具集(例如 IML )。然而,在我看来,它与众不同的一点是它提供了一系列有趣的可视化效果。不幸的是,目前大多数谈论 SHAP 的文章对它们以及它们如何帮助用户理解结果说得很少。

汇总图

我不会详尽地浏览每一个 SHAP 的可视化,我会把重点放在一个叫做概要图。选择这个的原因是因为我觉得这是最有趣的可视化之一,也因为它因为难以理解而受到了一些批评。我将首先一步一步地彻底描述 SHAP 摘要情节,然后在一个例子中使用它来解释第二部分中的黑盒机器学习模型。

什么是 SHAP 摘要情节?

目前有四种类型的摘要图:点、条、小提琴和紧凑点。在本文中,我将关注“点”类型,这是单个输出模型的默认汇总图。

SHAP 汇总图提供了一个高层次的复合视图,显示了要素的重要性及其 SHAP 值在数据中的分布情况。汇总图是沼泽图小提琴图的结合,显示了所有实例,结果图形显示了数据的频率和分布。

要显示汇总图,只需使用要解释的数据及其相应的 SHAP 值调用汇总图函数:

shap.summary_plot(shap_values, X)

在这里,我使用的是 Python 版本的 SHAP 包。上面的图是使用一个 100 乘 5 的随机数矩阵生成的:

shap.summary_plot(np.random.randn(100, 5), np.random.randn(100, 5))

所以你看到的是一个有 100 个实例的模型,每个实例有 5 个特征。该模型有一个实数输出,正如您对回归模型的期望。

解构概要情节

我们如何开始理解这种视觉化?这个模型告诉了我们什么?让我们从斧头开始。在 y 轴上,功能按重要性降序排列。换句话说,影响最大的特性列在顶部,影响最小的列在底部。

在 x 轴上,有一个 SHAP 值的刻度,垂直线为零。正值在线的右边,负值在线的左边。点在图中的位置表示实例的特定特征的 SHAP 值。将模型预测值拉低的值在左边,将预测值拉高的值在右边。

上面的图显示了一个具有 5 个特性的数据实例。这表明特征 2 是最有影响力的特征。下一个最有影响力的是特性 4,以此类推。特征 2 的 SHAP 值为正值,约为 2.1。特征 4,尽管它是第二大影响力,却是一个负数,大约为-1.5。这是因为特征重要性是关于特征的绝对影响,而不是它们是否以某种方式影响模型的输出。所以在这个例子中,这两个特征将模型的输出拉向相反的方向。

如果另一个实例具有相同的 SHAP 值,那么它将垂直堆叠。然而,垂直堆叠仅在行的边界内进行一定的距离。之后,它开始重叠。通过这种方式,汇总图可以在一个小空间内有效地缩放到数十万个数据点。

现在让我们来看看颜色和它们的含义。颜色区分实例之间特征值的相对大小。高值(相对于其他实例)显示为红色;低值显示为蓝色;根据图右侧的颜色图,中间值为紫色阴影。

随着更多数据点的添加,它们的位置显示了每个要素的 SHAP 值的范围和分布。例如,它是像正常曲线一样聚集在中间(但也是镜像的),还是向一端倾斜?

具有相似值的要素的聚类在图中创建了“颜色斑块”。面片的位置让用户了解值的大小如何影响模型的输出。例如,如果红色斑块(高值)位于零的左侧,则意味着高特征值共同将模型的输出拉向一个较低的数值。如果他们在右边,那就意味着他们正在把模型的输出推向一个更高的数字。类似地,根据其位置,蓝色补丁(低值)可能会影响模型的输出变低或变高。

这里有一个例子来说明色标。

如果我们看第一个特征,该图显示激素避孕药年数的低值(蓝色斑块)与较低的预测癌症风险相关,高值(红色点)与较高的风险相关。

就像 Seaborn Swarm 情节和 Violin 情节一样,SHAP 摘要情节可以被认为是情节中的情节。我们可以将数据作为一个整体进行检查,也可以查看每个类别(在本例中是要素)并检查其中的细节。例如,我们可以在上面的图中看到,第一个要素(激素避孕药年数)的值的分布向左倾斜,这表明总体而言,该要素正在影响模型的输出,使其数值变小。

SHAP 值聚集在零附*的要素通常意味着大多数值对模型的输出没有太大影响(此时忽略要素之间的交互)。上图中的下半部分特征就是这样,这也是为什么它们没有上半部分特征那么有影响力的原因。

摘要

总而言之,摘要图回答了以下问题:

  • 哪些特性对模型的输出影响最大?

特性在图的左侧按重要性降序排列。

  • 某个特性会影响输出值的大小吗?

如果点的聚类位于零线的右侧,则该特征会影响模型的输出,使其成为更大的数字。如果点簇位于左侧,则该特征会影响模型的输出,使其成为一个较小的数字。

  • 这些影响有多强?

点的聚类越靠右,对输出的影响就越大。点簇越靠左,对输出的影响就越大,输出的数值就越小。

  • SHAP 值的分布是什么?

点的形状表示每个要素的 SHAP 值的分布。也就是说,这些值是服从正态分布、偏态分布还是分散分布。

  • 特征值的相对大小如何影响模型?

蓝色色标(小特征值)或红色色标(大特征值)的位置显示了特征值的不同大小,以及它们是否影响模型的输出为较高的数值或较低的数值。

摘要图是在紧凑的空间内快速回答这些问题的有效可视化工具。

结论

我希望这篇文章对组成 SHAP 概要情节的各种组件以及它们如何协同工作提供了有益的讨论。因此,您能够通过这种可视化快速理解机器学习模型输出背后的影响。

当理解不同的输入特征如何影响模型的输出时,我发现摘要图是对其他可视化的非常有用的补充。然而,概要情节的设计并非没有挑战。在本文的第 2 部分中,我将通过一个例子来解释黑盒机器学习模型,然后提供一些解决一些挑战的想法。

[1] S.M. Lundberg,G. G. Erion 和 S. Lee,(2019),华盛顿大学。

[2] H. Michael,解释可解释的 AI (2019),XRDS: Crossroads,2019 年 4 月。

[3] S.M. Lundberg,S. Lee,解释模型预测的统一方法 (2017)。

在药物发现中可视化人工智能初创公司

原文:https://towardsdatascience.com/visualizing-ai-startups-in-drug-discovery-cb274eea2792?source=collection_archive---------52-----------------------

药物发现中人工智能初创公司的数据分析和交互式仪表板

克里斯汀·三都在 Unsplash 上的照片

作为一名生物学领域的机器学习研究人员,我一直在关注最*新兴的人工智能药物发现领域。我本人住在多伦多,这个领域的许多“明星”公司都是在那里成立的(Atomwise、BenchSci、Cyclica、Deep Genomics、protein qure……仅举几例!),我和这个领域的很多人聊过,也参加过一些关于这个话题的 meetup 活动。据我所知,这一领域正以如此快的速度发展,要跟踪这一领域的所有公司并对它们有一个全面的了解变得越来越困难。因此,我决定利用我的数据科学技能来跟踪和分析这个领域的公司,并建立一个交互式仪表板(【https://ai-drug-dash.herokuapp.com】)来可视化我的分析中的一些关键见解。

资料组

BenchSci(多伦多“明星”人工智能药物初创公司之一)的首席战略官西蒙·史密斯(Simon Smith)是人工智能药物发现领域的优秀观察者和沟通者。我一直在关注他关于行业趋势和新公司的播客和博客。他在 2017 年写了一篇博客,列出了人工智能药物发现领域的所有初创公司,并从那时起一直在更新这份名单。这个博客是我发现的该领域最全面的公司列表(截至 2020 年 4 月共有 230 家初创公司),因此我决定使用他的博客作为我的主要数据来源。

数据预处理

由于博客只是简单地将公司列为不同的段落,所以我首先使用美汤从博客中刮出公司信息。然后,我使用 Pandas 将收集到的数据转换成 DataFrame 格式。数据帧看起来像这样:

为了在地图上显示这些公司的位置,我使用 Geopy 将该表中的地址信息转换为纬度和经度:

# match address to latitude and longitude.
from geopy.geocoders import Nominatim
locator = Nominatim(user_agent="ai_drug")
lat, lng = [], []

for i, row in df.iterrows():
    location = locator.geocode(row.headquarters) or locator.geocode(row.city+','+row.country)
    lat.append(location.latitude)
    lng.append(location.longitude)

df['latitude'] = lat
df['longitude'] = lng

博客中没有这些初创公司的融资信息,因此我在 crunchbasepitchbook 上搜索了所有 230 家公司,并将这些信息添加到我的数据集中。

探索性数据分析

我对清理后的数据集做了一些探索性的数据分析,并注意到一些有趣的事情。

1.自 2010 年以来,创业公司激增

我们可以看到这个地区直到 1999 年才真正开始存在。开发化学模拟软件的薛定谔公司成立于 1990 年,并在这里上市,但我不确定他们的药物发现*台是否已经在 1990 年开始使用人工智能……创业公司的爆炸开始于后 2010 年时代,大约与“人工智能炒作”开始的时间相同,并在 2017 年达到顶峰。

2.大多数风险投资都处于早期阶段

我们可以看到大多数获得资金的公司仍处于风险投资的早期阶段(A 轮前种子),这可能是因为大多数人工智能药物初创公司仍处于探索商业模式和开发技术和产品的阶段,而不是扩大公司规模。

3.美国正在统治世界其他地区

这可能并不令人惊讶,但美国在这一领域统治着世界。超过一半的公司总部设在美国;超过 80%的风投资金流向了美国初创公司!英国在公司数量和资金方面排名第二。加拿大在公司数量上排名第三,但不是在资金上——中国才是。在这个领域有不少有前途的中国创业公司。例如,苏州的抗体发现和开发公司 Adagene 刚刚在 2020 年 1 月筹集了 69,000,000 美元的 D 系列资金。

4.新型候选药物的产生是人工智能应用的焦点领域

我们可以看到,吸引最多注意力和资金的 R&D 类别是产生新的候选药物。就我个人而言,我也认为这是人工智能可以发挥其最大威力的地方,即通过利用大量现有的测试数据,利用机器学习来预测目标药物的相互作用。

交互式仪表板

我使用 Plotly Dash 构建了一个交互式仪表板,以可视化我的数据集并提供分析见解。Dash 是基于 Python 的框架,用于构建分析型 web 应用程序,而且是免费的!完成的仪表板可以在 https://ai-drug-dash.herokuapp.com/的查看,你也可以在我的 GitHub repo 中查看代码。

如何使用这个仪表板?

首先,从左上方的控制面板中选择一个可视化指标。您可以在所有可视化绘图中使用公司数量或投资金额。

接下来,选择一个地区或国家。这可以通过从控制面板中选择,或通过在地图绘图中单击/框选择来完成(要重置您的选择,请单击地图中的空白点)。

最后,选择一个 R&D 类别。这可以通过从控制面板中选择,或者通过单击左下方类别图中的一个栏来完成,这也将更新该类别的关键字图。中间的公司信息表也将根据这些选择进行更新,以便您可以缩小公司列表的范围进行研究。

玩得开心!

参考文献 :

[1] Simon Smith,230 家在药物发现中使用人工智能的创业公司。【https://blog . bench sci . com/startups-using-artificial-intelligence-in-drug-discovery # understand _ mechanisms _ of _ disease
【2】https://www.crunchbase.com/
【3】https://pitchbook.com/
【4】大卫·康弗,如何使用 Dash 和 Plotly 构建报告仪表盘。https://towards data science . com/how-to-build-a-complex-reporting-dashboard-using-dash-and-plotl-4f 4257 c 18 a 7 f

可视化贝叶斯先验

原文:https://towardsdatascience.com/visualizing-bayesian-priors-cec2fea3e386?source=collection_archive---------34-----------------------

想过先验如何影响你的贝叶斯模型吗?弄清楚!

我一直在玩参数估计和贝叶斯统计,并认为我应该做一个快速的小可视化先验信念如何影响我们的后验分布。在本教程中,我们将思考硬币是否公*。当我们获得更多的数据并尊重我们先前的信念时,我们将想象我们对硬币公*性的估计是如何变化的。我们开始吧!

问题

你在维加斯看着人们对掷硬币的结果打赌。如果是正面,你赢得双倍赌注,如果是反面,赌场拿走你的钱。这听起来很划算,所以你马上就怀疑了。赌场不想给你好价钱。所以你决定计算你看到每个结果的次数,并确定硬币的价值。设 H 为使用赌场硬币获得正面的概率,设 D 为我们投掷的数据集。让我们假设我们看到了 100 次投掷硬币,在这 100 次投掷中,有 40 次是正面。硬币的重量是多少?自然你会说 H = 40/100 = .4 但是你是怎么得到那个数的呢?我们来走一遍推导!

最大似然估计

我们正在估计一次掷硬币,这意味着我们的数据将采用两个值中的一个,概率为 p 和 1 - p 。因此,我们将假设我们的数据是由伯努利分布生成的,或者换句话说,在给定特定正面概率的情况下,数据的可能性为:

现在我们想弄清楚什么值的 H 最大化这个似然函数。因为自然对数不会影响我们的最大值,所以我们可以求解对数的最大值。相信我,这会让数学变得简单。

现在回到你的微积分 I 课,求导并设为 0,以识别临界点。

硬币的最大似然估计

看来我们的直觉是正确的,对正面概率的最佳估计是投掷总数中投掷的正面数。

传道者

等等,我们不是在拉斯维加斯赌博吗?我们知道这些赌场是见不得人的。我们需要将这些信息整合到我们的模型中。在我们的模型中,我们假设参数可以以相等的概率取 0 到 1 之间的任何值。这种关于我们的参数取值的假设被称为先验,对于这种分析,我们假设一个统一的先验。

我们不知道这有多公*

这个特别的先验说我们完全没有关于正面概率应该是什么样子的信息。如果我们对我们的参数一无所知,这是一个很好的假设,但在普通硬币的情况下,这可能是一个糟糕的假设,因为我们知道普通街道硬币非常接*公*。使用 Baye 规则将先验与似然相结合以生成后验分布。

当样本量很小时,这些先验对我们的模型有重要的影响,当样本变大时,它们的影响会减弱。让我们看看这种效果在几个不同的先验中的作用。

我们已经知道了均匀先验下的后验概率是什么样的,但是如果我们假设赌场遵守规则并且使用普通的街道硬币呢?那么我们可以假设一个均值为 0.5 的高斯先验和一个小的标准差。那么我们的后验分布就是:

公*街硬币的高斯先验

对于这个实现,我选择了 0.5 的*均值,因为公*硬币应该接*偶数,标准偏差为 0.05,这样如果硬币碰巧不公*,它将位于 0.4 和 0.6 之间。

让我们来看看另一个可能的先验,我们认为硬币极有可能是极端偏向的。在这种情况下,我们可以使用贝塔分布,这将使我们的后验概率:

对于一个硬币,我们怀疑有这样或那样的偏见。

α=0.1 和β=0.1 时,该函数的 pdf 为:

α=0.1 和β=0.1 时的β分布

注意大部分概率是如何集中在极端情况下的。这与硬币很可能全是正面或全是反面的观点相吻合。你也可以看到这个分布没有太大的偏差,事实上方差在 0.2 左右。远高于高斯分布的 0.05 或均匀分布的 0.08。

我们可以使用以下函数在 python 中生成这些后验概率:

上述后验的实现。

现在让我们看看先验知识是如何直观地影响我们的参数估计的。在这个实验中,我们用 Python 创建了一个有偏向的硬币,正面的概率等于 0.3。这枚硬币明显偏向,通常会抛尾。然后,我们以 0 到 512 次翻转之间的间隔对硬币的翻转进行采样。这些翻转模拟了对我们一直在讨论的赌博游戏的观察。你可以把这些情节中的一个想象成在翻转之后我们对硬币的公*性有多确定,以及我们之前的信念。

下面我用越来越多的证据(观察到更多的翻转)绘制了后验概率的演化图,让我们看一看,看看我们能学到什么。如果我们假设我们完全没有关于这枚硬币的信息,我们可以假设一个统一的先验。我们可以看到,我们对硬币重量的估计是一个没有翻转的均匀分布。这是有意义的,因为我们没有数据,只有我们对硬币的假设。大约四次翻转后,我们得到了一个看起来像高斯分布的东西,可能有点偏向 0.3,但很难分辨。在大约 64 次翻转后,我们非常确信硬币是有偏差的,在 128 次后,我们或多或少地收敛到硬币的真实偏差权重。

接下来,我们通过使用高斯分布来检验如果我们假设硬币是公*的会发生什么。在零翻转时,我们只有先前的信念。在最初的几次翻转中,这种分布几乎没有变化。这是因为我们的硬币是公*的假设是一个相当强的假设,因此需要大量的数据来影响这一信念。在大约 32-64 次翻转后,我们可以看到分布逐渐向真正的权重左移。但是直到 256-512 次翻转,我们才真正达到真正的重量。

最后,我们通过使用 beta 先验来检验硬币是有偏差的,我们在一个肮脏的赌场。我们看到,这与均匀分布非常相似,但它更早地向左摆动。

还有一些有趣的事情需要注意,随着样本量的增加,所有的后验概率都趋向于以 0.3 为中心的正态分布。你可以清楚地看到,当样本量很小时,先验有很大的影响。此外,随着样本量的增加,可能性开始占主导地位,先验变得不那么重要。注意先验如何影响后验的收敛速度。例如,对于 64 次翻转后的均匀先验和贝塔先验,硬币的真实偏差落在我们 95%的置信区间内,而对于高斯,我们的真实偏差直到大约 256 次翻转才出现在我们的区间内。

这里要传达的信息是,如果我们一开始不太了解我们的参数、均匀性或贝塔分布,就很容易让模型相信硬币是有偏差的。然而,如果我们的模型坚信硬币是公*的,即高斯先验,那么它将需要更多的数据来说服它硬币实际上是不公*的。如果你喜欢这种数学可视化,你可能也会喜欢我关于高斯消去法的帖子。

最初发表于T5【http://www.nbertagnolli.com】

用 R 可视化大脑

原文:https://towardsdatascience.com/visualizing-brains-using-r-606fa0fb9fdf?source=collection_archive---------40-----------------------

如何使用 R 可视化和分析大脑的 MRI 扫描

Robina Weermeijer 在 Unsplash 上的照片

介绍

最*,我在大学一年级上了一门心理学入门课,在这门课中,我们学习了心理学的其他基本原理,包括大脑,我们使用不同类型的扫描来可视化大脑的方法,以及医生如何使用这些扫描来检测和监控疾病。这让我想知道——有没有一种简单的方法可以让我可视化并分析大脑?

大量的研究促使我在 Coursera 上开设了“神经黑客入门”课程。这门课程帮助我收集了背景信息和可视化大脑所需的构建模块,只使用了两样东西:开源 MRI 扫描和 R。鉴于 Python 通常被认为是深度学习和图像分析的首选语言,我想挑战自己使用 R 并解决我的问题。

资料组

我在 Kaggle 上找到的一个名为“脑瘤进展”的数据集上测试了我的知识。它由 20 名胶质母细胞瘤患者的 MRI 扫描组成。每名患者相隔 90 天接受两次 MRI 检查,以监测肿瘤的进展。

我回答的问题

问题 1:如何将扫描结果转换成适合分析的格式?

大多数医院以二维 DICOM 格式存储 MRI 扫描数据,其中大脑的每个轴向切片都是一个 DICOM 文件。这样做是为了保护健康信息。为了使这些图像适合 R 进行分析,第一步是将 DICOM 转换为 NifTI 格式,它将所有 DICOM 文件合并到一个文件夹中,以获得大脑的 3D 图像(NifTI 格式!).假设我们想看一下 1 号病人大脑的第 11 个轴向切片,我们得到了这个。

患者 1 大脑第 11 层的轴向视图

问题 2:有没有办法用强度值来可视化大脑的某些组织/部位?

当我告诉 R 用 300 到 400 之间的亮度值(不包括边界值)高亮显示大脑第 11 个切片的区域时,它将所有这些区域都染成红色,就像这样。

红色区域表示强度值在 300 和 400 之间

第一幅图像是轴向视图,第二幅图像代表冠状、矢状和轴向视图。当将突出显示的区域与现有文献进行比较时,红色部分代表大脑的白质和颅骨的少数区域。由此,我们可以得出结论,大脑的所有白质和头骨的少数区域的强度在 301 和 399 之间。

我们可以使用这种技术来突出具有特定强度范围的大脑的不同部分/组织,将它们与文献进行比较,并获得对大脑整个结构的更好理解。

问题 3:有没有一种方法可以将同一患者相隔一段时间的两次扫描相减,以监测大脑的变化?

在数据集中,每名患者间隔 90 天进行两次 MRI 检查,以监测肿瘤的进展。除了手动比较每个患者的两次扫描,有没有一种方法可以“减去”扫描,以便我们准确地知道在过去 90 天里大脑发生了哪些变化?幸运的是,我们可以在 r 的帮助下实现这一点。这个函数的优点是,现在我们不再需要对变化进行*似。我们确切地知道每个病人的肿瘤是如何在大脑中发展的。

在这项研究中,我决定比较 2 号病人和 20 号病人的大脑变化。从后续扫描中“减去”初始扫描,我对每个患者的结果如下。

左:患者 2 的脑在 90 天内的变化,右:患者 20 的脑在 90 天内的变化

我们看到,虽然两个病人大脑的变化发生在不同的区域,但组织生长的数量相当相似。因此,我们可以得出结论,对于数据集中的所有患者,疾病的进展都是相似的。

问题 4:怎样才能让大脑的某些特征更加突出?

有两种方法可以让大脑的特定区域突出更多,看起来更亮或更暗(取决于我们想要什么)。

选项一:反向映射

每个 MRI 扫描都是灰度图像,图像的大部分是黑色背景(强度=0)。在反向映射技术中,我们告诉 R 只考虑大于或小于阈值的强度,以帮助我们更好地看到图像。例如,对于非常暗的图像,我们将告诉 R 绘制所有大于 50 的亮度。这将帮助我们摆脱不必要的黑暗区域,使整体图像更明亮。另一方面,包含强度为 1300 的点的图像将使得强度为 200 的点很难看到。在这种情况下,我们告诉 R 只考虑小于 900 的亮度,以使图像的基本特征更容易看到。

选项 2:变换和*滑

我们可以变换图像,使大脑的特征更加清晰可见。在这项研究中,我使用了一个线性传递函数和线性样条变换。这些是单调的传递函数,这意味着灰色阴影只是变成了其他灰色阴影,白色保持白色,黑色保持黑色,只是它们的相对强度发生了变化。下面的图片显示了原始图像和转换后的图像。很明显,转换后的图像在显示大脑特征方面做得更好。

左:原始图像,右:变换后的图像

如果图片有太多噪点,*滑可以帮助减少一些噪点,使图像看起来更清晰。在这种情况下,我使用了高斯*滑。结果如下所示。

左:原始图像,右:*滑图像

在比较原始图像和*滑图像时,似乎没有太大的差别。这大概是因为数据非常干净。在真实世界的数据中,扫描结果并不清晰,而且有很多噪音。在这种情况下,*滑会做得更好。需要注意的是,过于*滑会导致重要特征丢失,所以内核大小要合适。

未来的研究

这项研究帮助我利用 r 更好地理解了大脑的结构。那些想要复制这项研究结果的人可以在这里找到代码。

从这里我们可以有两种主要的方法。第一,通过分析有其他异常的大脑 MRI 扫描来进一步探索大脑。第二,根据开源数据的可用性,将这项研究扩展到其他器官。

参考

  1. Coursera 课程——约翰·霍普金斯大学《R 中的神经黑客入门》:https://www.coursera.org/learn/neurohacking
  2. “脑瘤进展”数据集来自 ka ggle:https://www.kaggle.com/andrewmvd/brain-tumor-progression

数据集的原始来源:施梅达 KM,Prah M (2018)。脑瘤发展的数据。癌症影像档案。http://doi.org/10.7937/K9/TCIA.2018.15quzvnb

使用 TensorFlow visualizer 可视化基于浏览器的模型训练过程

原文:https://towardsdatascience.com/visualizing-browser-based-model-training-process-using-tfjs-vis-810e8c91d4b7?source=collection_archive---------47-----------------------

观察神经网络训练过程同样重要,因为它有助于观察每个时期的损失和准确性等。

可视化批处理值

在 python 中训练模型时,tensorboard 库使可视化成为可能。类似地,如果您正在使用 tensorflowjs 在浏览器上训练您的模型,您将需要一些东西来观看训练过程。可以使用 tensorflowjs 可视化工具。利用这一点,我们可以在训练时可视化每个时期或批次的训练损失/准确度。我们可以在评估时可视化每个职业的准确度和混淆矩阵等等。

我将使用 tfjs 为谷歌 chrome 浏览器上的 10 个标签使用时尚 MNIST 数据集训练一个分类器,并在训练时可视化模型。一旦模型被训练,我们就可以在画布上画出正确的类。

是的,你没听错,我们将在画布上绘制一个输出,并告诉我们的分类器识别图像类。我不会深入研究编码,因为我写这个故事的主要目的是在我们的 js 代码中实现 tfvis 库,并展示 visualizer 如何为基于浏览器的模型工作。我在这个故事的底部包含了我的 Github 代码的链接。

为了更好地理解这个故事,你可以参考我以前的博客
如何使用 tensorflow.js 在 Chrome 上训练神经网络

导入 tfjs-vis 库

超级简单,只需在你的 Html 文件的<head>中添加链接。此外,您可以在 nodejs 上从源代码构建。

<script src="[https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest](https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest)"></script><script src="[https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis](https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis)"></script>

就像 python 中的 train.py 一样,我们将使用单独的 java 脚本来编写构建和训练模型的代码,以及下载时尚 MNIST 数据集 sprite sheet

什么是雪碧片? Sprite sheet 包含成千上万的图片组合在一个文件中。游戏开发人员使用这种技术,通过从文件中分割部分图像而不是多次调用图像来简化数据获取过程。当我们在实时环境中需要大量图像处理时,这使得处理速度更快。

我们为什么要使用雪碧表? MNIST 有成千上万的图片,如果你要打开 http 连接成千上万次来下载这些图片,可能会有问题。所以不像 python 中的训练,你可以一个接一个地加载 10,000 张图片,你不能在网络浏览器中这样做。劳伦斯·莫罗尼,深度学习

定义回调指标

让我们创建用于观察损失验证损失准确性、验证准确性的指标,我们可以将这些指标传递给 tfvis 的 fitCallbacks 函数。

const metrics = ['loss', 'val_loss', 'acc', 'val_acc']

还有定义容器名称和大小的规定,这也是 fitCallbacks 函数的必需参数。

const container = { 
             name: 'Model Training', 
             styles: { 
                  height: '1000px' 
             }};

设置 tf-vis 显示

让我们用我们的度量和容器大小设置一个可视化工具。

const fitCallbacks = tfvis.show.fitCallbacks(container, metrics)

在训练函数(model.fit)中设置可视化工具

model.fit(trainXs, trainYs, {
        batchSize: BATCH_SIZE,
        validationData: [testXs, testYs],
        epochs: 10,
        shuffle: true,
        callbacks: fitCallbacks
});

一旦一切都设置好了,你就可以在训练时在网页上看到 visualizer。

训练时浏览器上显示的可视化工具输出。

上面的值是我们在传递给 tfvis fitCallbacks 函数的度量中设置的损失和准确性。

除了训练,你还可以使用 tfvis 来评估模型。对于像这样的分类任务,我们可以使用“perClassAccuracy”和“混淆矩阵”函数。

查看我的模型输出

附注:忽略我的画😛

想试试吗?

[## novas ush/visualizing-fashion-mnist-on-browser

使用 tensorflowjs 在浏览器上训练时尚 MNIST 数据集,使用 tfvisualizer js 可视化模型训练…

github.com](https://github.com/novasush/visualizing-fashion-mnist-on-browser)

从这里参考我的 GitHub 库。它包含用于在浏览器中对时尚 mnist 数据集训练分类器并显示可视化效果的代码。

参考

  1. Tensorflow tfjs-vis 库
  2. 用 tfjs-vis 进行可视化训练
  3. 查看数字识别器内部

利用卫星图像可视化建筑区

原文:https://towardsdatascience.com/visualizing-built-up-areas-using-satellite-images-18d43f34f0b3?source=collection_archive---------36-----------------------

地理可视化/菲律宾/遥感

使用谷歌地球引擎的卫星图像来观察一段时间内的建筑区域

美国宇航局在 Unsplash 拍摄的照片

大数据太不可思议了!大数据设法将科学和商业领域带到新水*的方式几乎有点神奇。它允许我们利用各种途径来获取我们通常不会获取的信息,以便获得新的见解。

卫星图像是一个惊人的非常规来源,可以挖掘这些新的见解。城市规划者、环保主义者和地理空间数据科学家通常会从卫星图像中寻找全局视角,并从这一实践中找到见解,从而将他们的预期解决方案提升到一个全新的水*。

卫星图像分析速成班又名遥感

如果你曾经在网上文章中遇到过“遥感”这个术语,很可能指的是利用卫星观测地球的过程。之所以这样称呼它们,是因为它们有远程测量的能力。

这些遥感仪器感知什么?简答就是辐射。更专业的说,这些仪器感应电磁辐射。

这些电磁辐射的波长和频率各不相同,在这个光谱中,我们肉眼能看到的一小部分被称为“可见光谱”。

电磁波谱。来自鲍勃-edu 天文学

这就是卫星发挥作用的地方。环绕地球运行的卫星的透镜不仅可以探测可见光,还可以探测红外波长(最接*可见光谱的波长)和微波。

当来自太阳的光到达地球表面时,每个物体都不同地反射、吸收或传输这种能量。例如,绿色植物吸收所有颜色,但反射绿色。这就是为什么当我们看植物时,绿色是可见的。在某些情况下,同一类型的植物可能没有同等的水分,虽然这种微小的差异不会被肉眼看到,但这两种植物反射光线的方式会有所不同。

如你所知,并不是所有反射的光都是可见的。

由于表面反射光线的方式不同,多年来,卫星一直被用于研究植被、洪水易发区,甚至分析一个地方的建筑面积。

虽然任何人都可以去查看和下载卫星图像,但它们可能不包含来自反射的数据,而反射会立即产生如此多的见解。

这是我们要找的数据。在我们稍后要做的可视化中,颜色的不同代表了被反射的辐射的不同。由于这是一个多时相可视化(多个时间段),颜色将代表一个地方不同时间序列的建筑区表面。

预赛

要继续学习本教程,请确保首先完成以下工作:

  1. 谷歌地球引擎创建一个账户。这是免费的,并将在您的 Jupyter 笔记本中进行验证。
  2. 安装谷歌地图(pip install geemap )和地球引擎(pip install ee )。
  3. 使用 ee 初始化地球引擎。初始化()

数据集

在这个练习中,我们将访问谷歌地球引擎数据库中的“GHSL:全球人类居住层”数据集。

全球人类住区 (GHS)框架生成全球关于人类在地球上长期存在的空间信息。这包括物理沉降,因此这反映了一段时间内的建筑面积。

我们来码!

#Preliminaries
import geemap
import ee#After importing, it is important to initialize this.
ee.Initialize()

初始化树叶地图:

Map = geemap.Map(center=[15.222871,120.574440], zoom=7)
Map

加载数据集并将其存储为对象。

#Note that ee.Image and ee.ImageCollection can both access datasets but you need to check which one is applicable for your intended datasetimage = ee.Image('JRC/GHSL/P2016/BUILT_LDSMT_GLOBE_V1')

选择“已建”波段作为我们想要的已建区域。

builtUp = image.select('built')

定义 Vis 参数。

visParams = {
  'min': 1.0,
  'max': 6.0,
  'palette': ['0c1d60', '000000', '448564', '70daa4', '83ffbf', 'ffffff'],
}

为了使这有意义,让我们参考这些最小值和最大值所指的内容:

取自地球发动机数据目录

最小值和最大值指的是上面构建的类表中的值列。为了获得最佳观看效果,您应该选择最小值=1,最大值=6。您不希望遗漏水域和陆地的价值,因为对于一些不擅长阅读地图的读者来说,您的可视化可能没有清晰的形式。

调色板只是给类值分配一种颜色。建议的颜色可以在构建的类别表中看到。您可以使用十六进制代码,但不要使用“#”。

#.addLayer method adds this on top of your initialized Map above
Map.addLayer(builtUp, visParams, 'Built-Up Multitemporal')

这是建议颜色的显示方式。

考察菲律宾的建筑用地面积

建议颜色的图例

或者,您可以直接为调色板使用颜色名称。确保对其进行排列,以便第一种颜色与构建的类表的值 1 相匹配。

visParams = {
  'min': 1.0,
  'max': 6.0,
  'palette': ['0c1d60', 'black', 'yellow', 'green', 'blue', 'white'],
}

请注意,您可以使用 inspector 函数来检查点的值:

使用调色板的颜色名称。使用检查器来显示点的值

因此,从本练习中,您可以看到大部分建筑区位于菲律宾首都及其附*区域,如区域 III 和区域 IV-A。同样,您可以追踪一个模式并回答“特定时期内开发发生在何处”这一问题。

我们还可以为此做其他修改,例如将可视化限制在一个城市或省份。

有了谷歌地球引擎,你也可以访问其他数据集。

请随意探索其他数据集。编码快乐!

点击此处查看 Github 上的 Jupyter 笔记本。

可视化神经网络的变化

原文:https://towardsdatascience.com/visualizing-change-in-neural-networks-eea86529a9f3?source=collection_archive---------36-----------------------

评估神经网络在针对新任务进行微调时的特征可视化变化的实验

深度神经网络以其强大的能力吸引了世界,但它们在很大程度上是作为黑盒模型运行的。为了帮助解决这个谜,特征可视化已经成为一种强大的工具,用于查看神经网络的“引擎盖”以可视化它们所学习的东西。

在本文中,我们将探索如何可视化神经网络学习检测的内容,以及当我们微调网络以执行新任务时,这些学习到的工件如何变化。此外,该项目基于 tensorflow lucid 库提供了特征可视化的 pytorch 实现。

在我们开始之前,你可以在 Github 上找到这个项目的代码。

什么是微调?

微调是使预先训练的神经网络适应新任务的过程。微调时,网络的参数用从原始任务中学习到的值进行初始化。假设任务相对相似,通过利用从原始任务中学到的知识,微调有助于网络在新任务上实现更高的准确性。当原始任务有更大更丰富的数据集时,这种技术特别有用。

这个项目使用的架构是 ResNet-50 [2],一个深度卷积网络,有五十层。对于最初的任务,这个网络已经被训练成在 ImageNet 上进行分类,ImageNet 是一个包含跨越一千个不同类别(包括动物、植物、车辆和物体)的数百万张图像的数据集。

在这个项目中,我们将探索当网络在斯坦福狗数据集【3】上进行微调时,预训练网络对输入图像的内部表示的变化。该数据集包含大约 20,000 张 120 个品种的狗的图片。通过标准的微调方法和均匀的训练测试分割,在这个新的数据集上获得了 80%的分类准确度分数。

图一。来自斯坦福狗数据集的示例图像

什么是特征可视化?

神经网络中的每个组件学习检测输入图像中的各种特征。例如,狗分类器中的特定神经元在遇到吻状特征时可能会释放大量激活(输出值)。

特征可视化是一种优化输入图像的技术,以便在预训练神经网络的特定组件中产生大量激活。与常见的深度学习范例相反,该过程不更新网络的参数。相反,它冻结预训练的网络并更新图像中的像素,使得网络的组件被高度激活。

下面的图 2 给出了特征可视化的总图。特征可视化使用梯度上升来最大化网络中目标组件的激活值。输入图像从随机初始化所有像素开始。随着算法的迭代,图像开始更接*组件已经学会检测的特征。

另外,请注意目标组件如何来自网络中的任何地方。特别是在这个项目中,我们可视化了 ResNet-50 的最后四个瓶颈层中每个特征图的*均值。

图二。特征可视化算法概述

回到狗鼻子的例子,如果将特征可视化应用于特定神经元的输出,我们会期望得到的图像是模型可以预期的最“看起来像鼻子”的输入。这意味着(如果神经元只检测狗的鼻子),得到的图像将充满各种形状和大小的鼻子。

这种技术有助于了解网络的不同组件已经学会检测什么。下图 3 显示了 ImageNet 预训练 ResNet-50 模型中三个不同通道的功能可视化。请注意,对于模型中更深的层,特征会更加复杂。例如,在左图中,唯一可见的特征似乎是某种类似毛皮的纹理。然而,在右边,我们可以看到狗和蛇头纠缠在一起的图像。这表明网络中的这个特定通道已经学会了在输入图像中检测狗和蛇。

图三。分别从层 1-瓶颈 1、层 2-瓶颈 3 和层 3-瓶颈 5 中的三个不同通道进行特征可视化。

要了解更多关于特性可视化及其在这个项目中的具体实现,请参见这篇优秀的文章。

比较特征可视化

既然我们已经讨论了潜在的想法,让我们看看如何在神经网络中可视化这种变化。回想一下,有两个网络需要考虑:

  • 在 ImageNet 上预先训练的基础网络
  • 狗网络是在狗数据集上微调的基础网络

在微调过程中,只允许训练体系结构中的四个组件(不包括全连接层):

  • 第 3 层,瓶颈 5
  • 第 4 层,瓶颈 0
  • 第 4 层,瓶颈 1
  • 第 4 层,瓶颈 2

因此,我们将只为这四个层中的通道创建特征可视化。目标是比较两个网络中匹配组件的特征可视化。例如,层 3-瓶颈 5 中的第一通道的特征可视化在基础网络和狗网络之间如何变化?直觉上,我们应该期待后一个网络的许多特征更像“狗”(例如,更像皮毛的纹理)。

这种分析的一个假设是,随着我们深入网络,特征可视化将变得越来越不同。这是基于这样的观察,即更深的层通常代表更复杂的特征(见图 3 )。另一种看待这一点的方式是,网络中的早期层代表更基本的特征,这些特征在计算机视觉任务中是通用的(因此在训练期间不太可能被改变)。

自动化图像比较

手动比较特征可视化是不方便的。目标层上有数千个通道。更不用说,这将在比较中引入人为偏见,因为一个人对哪些图像不同的看法是主观的。相反,我们必须定义两幅图像之间的相似性度量。

当我们通过神经网络输入图像时,图像在每一层中的隐藏状态都是丰富的潜在向量表示。如果我们使用图像的这种矢量表示,我们可以使用余弦相似度来判断两个矢量彼此有多相似。

对于每一对特征可视化,我们通过基本网络分别馈送它们,并在完全连接的层之前检索它们的隐藏矢量表示(嵌入)。然后,我们将两个可视化之间的相似性度量定义为它们各自嵌入的余弦相似性。

图四。余弦相似性度量的概述。层 4-瓶颈 2 之后的全局*均池产生 2048 维向量。

功能:ImageNet →狗

在我们进行比较之前,需要注意的是,一些通道未能优化其特征可视化,导致无特征的灰度图像。有趣的是,这种模式在基础网络中的任何特征可视化中都没有出现。不太清楚为什么这些通道未能优化。在任何情况下,由于那些有缺陷的可视化缺乏任何可比较的特征,它们被丢弃了(更多细节见附录)。

图 5 中,我们可以看到基础网络和狗网络之间的第 3 层瓶颈 5 中最不同和最相似的前 3 个通道。在大多数不同的通道中,在通道 667 和 675 中的狗网络的特征可视化中清楚地出现了毛皮状纹理。尽管 963 频道也有明显的变化,但那里的新功能在视觉上并不能解释为“像狗一样”。不足为奇的是,实际上在前 3 个最相似的通道中没有可检测到的变化,因为相同的模式在每个图像对中重复。

图五。分别列出第 3 层-瓶颈 5 中最不同和最相似的 3 个特征可视化。

移动到图 6 的下一层,前 3 个最不同的特征可视化的变化有点难以解读。狗网络中的通道 503 的可视化似乎包含散布在图像上的几个类似狗的特征,包括眼睛、鼻子和嘴。频道 1904 很有趣,因为可视化看起来几乎像植物,这可能是数据集的副产品,因为许多狗的图像是在户外拍摄的。

同样值得注意的是,该层的前 3 个最相似通道中的可视化对彼此之间的差异比前一层中的可视化对更多。有趣的是,它们都在图像上共享类似特定符号/字符的覆盖纹理(这可能有助于放大以获得更好的视图)。

图 5。分别列出第 4 层-瓶颈 0 中最不同和最相似的 3 个特征可视化。

图 7 的下一层中,前 3 个最不同的通道中的可视化开始代表更完整的狗的图片。例如,在频道 700 和 899 中,特征似乎分别类似于哈巴狗和伯恩山犬的头部。有趣的是,最相似的通道再次包含类似字符的纹理。

图 7。第 4 层-瓶颈 1 中最不同和最相似的 3 个特征可视化。

下面的图 8 描绘了最终层中前 3 个最不同和最相似的通道。前 3 个最不同的频道中的频道 707 和 442 再次在可视化中展示更完整的狗特征,例如头。

在这一层中,甚至前 3 个最相似频道中的频道 1485 和 31 也在其狗网络的可视化中展示了类似狗的特征。这些通道还包含前两层示例中讨论的特定纹理。另一方面,通道 952 不包含该纹理,并且其图案在其对于基础和狗网络的可视化中保持一致。这可能会突出我们的余弦相似性度量中的缺陷,因为它忽略了关于通道 1485 和 31 的新狗特征的图像中的明显变化。出于某种原因,相似性度量更关注它们的纹理,而不是它们的新内容。

图 8。分别列出第 4 层-瓶颈 2 中最不同和最相似的 3 个特征可视化。

表征层之间的差异

已经可视化了目标层内特征的变化,现在让我们评估层之间的变化的程度。图 9 以箱线图的形式展示了四个目标层内余弦相似性的分布。除了最后一层(第 4 层-瓶颈 2),随着我们深入网络,余弦相似性分布有明显的下降趋势。这表明,*均而言,对于更深的层,基本网络和狗网络的特征可视化之间存在更多差异(这与我们之前的假设一致)。

图九。每个目标层的基本网络和 dog 网络特征可视化之间的*均余弦相似性分布的箱线图。

有趣的是,最后一层偏离了这种模式,并且与前一层具有几乎相同的中值余弦相似性。这种偏差更有可能是使用要素可视化作为比较手段的误导效果,而不是最终图层变化较小的迹象。

为了理解这一点,让我们再看几个第 4 层瓶颈 2 的特征可视化(仅使用前 3 个极端可能不是一个好的表示)。下图 10 显示了该层中三个不同通道的特征可视化的变化。这一层的可视化似乎更加复杂,许多表现出来的特征相互纠缠在一起。在所有三个例子中,我们可以看到新的类似狗的特征出现在狗网络的可视化中。然而,由于其他可视化特征的丰富性,这些新的类似狗的特征不像前面图层中的可视化特征那样突出。

假设这种模式在最终层的可视化中是常见的,这可以解释为什么层 4-瓶颈 2 的*均余弦相似性不低于层 4-瓶颈 1 的*均余弦相似性。与直觉相反,最终层中特征可视化的更高复杂性和丰富性可能会“淹没”新狗特征引入的变化。

图 10。基础网络和 dog 网络的第 4 层瓶颈 2 的三个示例特征可视化。

结论

在这个项目中,我们可视化了神经网络的检测特征如何随着网络向新任务的微调而变化。我们将 ImageNet 预训练的 ResNet-50 模型微调到一个更小的狗品种图像数据集。正如所料,新的类似狗的特征出现在微调网络的可视化中,尤其是在更深的层中。根据我们的相似性度量,网络中的最后一层打破了这种模式,突出了使用特征可视化来评估网络中的变化的潜在缺陷或困难。

考虑到这一点,让我们讨论一下这个项目的其他一些细微差别:

  • 特征可视化提供了对网络的有限一瞥:特征可视化创建了一个图像,它最大化地激活了网络中的一个组件。然而,生成的图像只捕捉到每个组件学习检测的少量特征。这就是为什么更深层的特征可视化看起来如此混乱和纠结的原因(很难将所有潜在的特征都压缩到一张图像中!)
  • 可能会有一个更好的特征可视化配置:这个项目中的结果是使用一个单一的配置生成的,它为每个层产生了良好的结果,但是可能有不同的设置会产生更好的可视化效果。
  • 这个项目中的相似性度量是一个黑盒:余弦相似性本身并不是一个黑盒。然而,由于其输入是深层网络中的隐藏表示,我们对图像中的相似性度量究竟比较什么的理解有限。这解释了为什么我们的度量突出显示为最相似的几个通道包含相同的特定纹理。

附录

斯坦福汽车数据集

在这个项目中还执行了第二个微调任务。和以前一样,基本网络是在 ImageNet 上预先训练的 ResNet-50。第二个数据集是斯坦福汽车数据集 [4],其中包含 196 种不同车型的约 16,000 张汽车图像。使用标准的微调方法,在这个新数据集上实现了 70%的分类准确率。

然而,由于生成的要素可视化中的变化缺乏可解释性,该数据集不包括在讨论中。尽管这些变化是显而易见的,相似性分布的箱线图也遵循了狗网络中的模式,但新特征并不十分“像汽车”。这可能是由于更困难的微调任务(如在结果的准确度分数中明显的)或者可能是由于识别狗特征比识别汽车特征更好的人类偏见。

移除故障特征可视化

由于特征可视化是一个优化问题,并且每一层仅使用一种配置,因此一些通道未能优化,这导致了灰色图像。图 11 显示了每一层的灰度图像数量(第三层-瓶颈 5 没有)。

图 11。每层中错误可视化的数量

为了识别和去除这些灰度图像,必须定义一个评分函数。第一步是创建每个图像的灰度版本(这可以使用 Pillow python 库来完成)。然后,计算图像的原始 RGB 版本和灰度版本之间的*方误差。灰色特征可视化与其灰度版本非常相似,导致误差更小(图 12 )。事实上,绘制分类错误显示了错误的灰色特征可视化和正常特征可视化之间的大尖峰。剩下的就是移除落在该尖峰左侧的特征可视化(图 13 )。

图 12。灰度图像评分功能概述。在这个例子中,主要是灰色的有缺陷的可视化将具有比原始图像更低的*方误差。

图 13。在误差值的巨大尖峰之前,故障通道可以被识别为簇。

克矩阵距离

在试验特征可视化之间的相似性度量时,基于 Gram 矩阵定义了一个度量。Gram 矩阵是在神经风格转移[1]中引入的,是一种捕捉图像中纹理信息的技术。然后,克矩阵距离被定义为比较中第一和第二图像的克矩阵之间的*方误差。

这种想法背后的直觉是,可视化中的特征通常会在整个图像中重复出现(有一些变化)。比较特征可视化之间的纹理信息是有意义的,因为它总结了图像中的局部结构,而不考虑它们的位置。

然而,基于视觉检查,该度量不如余弦相似性表现得好。一个原因是网络中不同层之间的 Gram 矩阵距离变化很大,很难将它们组合成一个度量。

参考

  1. Gatys,l .,Ecker,a .,& Bethge,M. (2016 年)。《艺术风格的神经算法》。视觉杂志,16(12),326。doi: 10.1167/16.12.326
  2. 何刚,张,任,孙,“深度残差学习在图像识别中的应用”。2016 年在 CVPR
  3. 科斯拉(a .),贾亚德瓦普拉卡什(n .),姚(b)和(l .),“用于细粒度图像分类的新型数据集”。2011 年 IEEE 计算机视觉和模式识别会议(CVPR),第一届细粒度视觉分类研讨会。
  4. j .克劳斯,m .斯塔克,邓杰,飞飞,l .〈精细分类的三维对象表示〉。第四届 IEEE 表示和识别研讨会,ICCV 2013 (3dRR-13)。澳大利亚悉尼。2013 年 12 月 8 日。
  5. Olah,c .,Mordvintsevm A .,和 Schubert,L. 2017。“特征可视化”。蒸馏。https://distill.pub/2017/feature-visualization

可视化冠状病毒爆发

原文:https://towardsdatascience.com/visualizing-coronavirus-outbreak-da835608fb88?source=collection_archive---------36-----------------------

数据新闻

对这种疾病在全世界传播的深入观察

杰克·布拉德利Unsplash 上拍摄的照片

"如果不加以控制,它会像病毒一样传播."——丽斯·麦克布莱德

我已经很久没有在媒体上写东西了。我觉得目前的疫情给我带来了完美的机会,让我期待已久的复出。让我们开始吧。

概观

2020 年初,冠状病毒(新冠肺炎)爆发将成为全球各大报纸的头条。截至 2020 年 2 月 28 日,这种臭名昭著的病毒已经影响了 84124 人,并导致 2867 人死亡。病毒的中心是位于湖北 Mainland China 的武汉市。与 SARS 爆发相比,中国这次确实反应更快,以限制疾病向其他地区的传播。然而,尽管他们尽了最大努力,在许多其他国家还是出现了一些疑似和确诊病例。这篇博客文章将作为对病毒爆发的具体观察。

免责声明:所有数据都是截至 2020 年 2 月 28 日的最新数据。

数据源

使用的数据集可以在 Github 上找到。它由约翰·霍普金斯大学系统科学与工程中心(CSSE)出版。数据每天更新两次。

探索性数据分析(EDA)

数据源有三种类型的数据,已确认、死亡和已恢复,在三个单独的文件中可用。让我们来看看。

结构

在观察我们的数据结构时,我们看到它具有地理数据集的常见嫌疑(州、国家、纬度、经度)。每行的粒度仅在状态之前可用。在检查 State 列时,我们看到它缺少值。让我们对此进行调查。

我们看到,当删除 State 列中的空值时,唯一国家的数量有所不同。大多数州数据来自 Mainland China,其次是美国。让我们来看看汇总统计数据。

汇总统计数据

这里没有太多惊喜。我们的数据有 4332 行。一切似乎都很简单。让我们更深入地进行一些分析和可视化。

中国

我们知道冠状病毒爆发源于中国。因此,它应该是我们的首选。让我们看看中国的一些地区是如何受到影响的。

我们看到湖北地区显然是该病毒的高发区。如前所述,武汉市是湖北区的首府。难怪我们在湖北看到大量确诊病例。确切数字是 65914。这尤其令人着迷,因为全球确诊病例总数为 84,124 例。这意味着仅湖北区就占确诊病例总数的 78.35%!

让我们来看看中国湖北以外的情况。

广东的确诊病例数(1348 例)仅次于湖北。其次是河南省(1272)。

从死亡和康复图表中,我们可以看到河南区的死亡和康复人数最多。快速的谷歌搜索显示,与广东相比,河南实际上离湖北更*。或许,邻*可能是造成这些高数字的一个因素?对这些假设进行统计测试会很有趣。也许我们应该在以后的博客文章中重新讨论这个问题。

这张图是中国冠状病毒病例的时间序列图。我们可以看到,在 2 月 12 日至 2 月 13 日期间,确诊病例数量突然激增,随后斜率变*。也许关于诊断和治疗的信息在这个时候得到了改善?这一假设得到了以下事实的支持,即红色回收线的斜率在图表的后半部分变得更陡,表明回收的案件数量有所增加。🙂

让我们慢慢把注意力从中国转移到世界其他地方。

世界其他地方

韩国是中国以外确诊病例最多的国家。全国冠状病毒病例 2337 例。

值得注意的一个非常有趣的数字是,在韩国之后,意大利的确诊病例最多,为 888 例。几个小时前,我收到消息,一场大型的意大利足球联赛由于努力应对病毒而被推迟。意大利米兰的一名传染病教授表示,在最初几个病例被发现之前,病毒可能已经在欧洲国家存在了数周。看起来意大利可能还有很长的路要走。

让我们看看在中国以外有多少病例被证明是致命的。

伊朗(34 人)其次是意大利(21 人)在中国境外因该病毒而伤亡人数最多。据来自中东国家的报道,一名伊朗议员死于该病毒。随后,一些国家已经决定禁止航班往返伊朗。

尽管韩国是中国以外病例最多的国家,但该病毒在该国的死亡率相当低。

到目前为止,我们只研究了世界各地的死亡人数。让我们来看看世界各国抗击这种病毒的情况。

我们可以看到,一些国家似乎有 100%的病毒恢复率。乍一看,似乎是越南、比利时、印度等。对疾病爆发表现出了惊人的反应。然而,百分比在很大程度上取决于分母,在这种情况下,分母恰好是确诊病例的数量。让我们看看当我们过滤掉复苏百分比最高的国家时会发生什么。

所有治愈率为 100%的国家的确诊病例数都少于 20 例。相比之下,新加坡(93 人)和泰国(41 人)的病例都要高得多。新加坡的回收率为 68%,而泰国为 66%。这两个相邻的亚洲国家似乎在治疗这种病毒方面做得非常好。好消息!👍🏼

现在,让我们将我们在中国使用的时间序列图复制到世界其他地方。

我们可以看到,自 2 月 23 日以来,确诊病例数量急剧增加。最*有新闻报道提到世界范围内病例数量的快速增长。

最后,这是一个显示病毒在全球传播的动画地图。

最初,我们只在中国和周边地区看到斑点。在 2 月 20 日左右,欧洲的病例数量大幅上升。这和前面提到的这篇博文的观察结果是一致的。

结论

冠状病毒是当今媒体最热门的话题之一。记者称之为致命的。由于担心疫情爆发,全球市场已经看到7 万亿美元化为乌有。流行病学家对这种病毒的致命性没有把握

尽管这篇文章提供了很多真知灼见,但世界各地可能还有更多未被发现的病例。

“没有证据并不是不存在的证据”——卡尔·萨根

如果你在受病毒影响的地区或去中国旅行,确保遵循这些指示以保持安全。

我希望你们都喜欢这篇文章。所有的图表都是使用 Plotly 创建的。Plotly 是一个非常棒的可视化库,用于构建交互式的图形。他们有 Python、R 和 JavaScript 的图形库。我鼓励我所有的读者去尝试一下。

文章中使用的所有代码都可以在这里找到。

如果你喜欢这篇博文,请在 MediumLinkedIn 上关注我,并与你的朋友分享这篇博文。下次见。✋

参考资料:

【1】https://www . ArcGIS . com/apps/ops dashboard/index . html #/BDA 7594740 FD 40299423467 b48e 9 ECF 6

【2】https://www . ka ggle . com/imdevskp/新冠肺炎-分析-viz-预测-比较

用 Python 漂亮地可视化新冠肺炎数据(不到 5 分钟!!)

原文:https://towardsdatascience.com/visualizing-covid-19-data-beautifully-in-python-in-5-minutes-or-less-affc361b2c6a?source=collection_archive---------8-----------------------

让 Matplotlib 不那么痛苦!

让我们用 Python 创建一些漂亮的数据可视化!资料来源:Nik Piepenbreier。

Matplotlib 可能是 Python 事实上的数据可视化库,但它并不总是最漂亮的。在这篇文章中,我们将探索如何把一个单调的默认 Matplotlib 图变成一个漂亮的数据可视化。我们将研究新冠肺炎的数据,看看病毒是如何在不同国家传播的。

让我们载入数据

我们将使用来自这个美妙的 Github 库的数据,它每天自动更新数据。我们将根据 URL 把我们的数据加载到熊猫的数据框架中,这样它将每天为我们自动更新。

加载我们的数据并创建汇总变量。资料来源:Nik Piepenbreier

  • 在上述要点的第 1 节 中,我们正在加载我们的库。在本教程中,我们将使用 Pandas 和 Matplotlib。
  • 第 2 节 中,我们将数据读入数据帧df,然后只选择列表countries中的国家。选择数据使结果可视化更具可读性。
  • 在第 3 节 的 中,我们创建了一个汇总列,汇总了所有确诊病例、已康复病例和任何因新冠肺炎而死亡的个体的病例总数。

为数据可视化准备数据框架

现在我们已经将数据存储在一个数据帧中,让我们准备另外两个数据帧,将数据保存在交叉表中,这将使我们能够更容易地可视化数据。

为可视化准备数据。资料来源:Nik Piepenbreier

让我们更详细地探讨一下我们在这里做了什么:

第 4 节 中,我们旋转我们的数据框架df,创建国家的列,以案件数量作为数据字段。这个新的数据帧被称为covid。然后,我们将数据帧的索引设置为日期,并将国家名称分配给列标题。

第 5 节 中,我们复制了我们的数据帧covid,称之为percapita。我们使用存储所有国家人口的字典,将每个值除以人口,再乘以 100,000,得出每 100,000 人中的病例数。

如果你想学习如何解透视数据,看看这篇关于熊猫融化功能的教程

让我们来看看我们的数据从开始到现在是如何变化的:

我们如何重塑数据来讲述一个故事。资料来源:Nik Piepenbreier

创建我们的第一个可视化—案例随时间推移

让我们首先创建第一个可视化视图,展示不同国家/地区一段时间内的病例总数:

创建我们的第一个可视化。资料来源:Nik Piepenbreier

让我们更详细地探究一下我们对她做了什么:

第 6 节 中,我们创建了一个包含不同国家十六进制值的字典。将它存储在字典中可以让我们稍后在 for 循环中轻松调用它。我们还分配了 FiveThirtyEight 样式来添加一些通用格式,我们将在此基础上进行大量构建。

第 7 节 中,我们使用 Pandas 的 plot 函数创建了我们的第一个可视化。我们使用 colors 参数将颜色分配给不同的列。我们还使用set_major_formatter方法来格式化带有千位分隔符的值。

然后,在 第 8 节 中,我们创建一个 for 循环,为各个国家生成标签文本。这个 for 循环以列表的形式从字典中的关键字获取每个国家的名称,并遍历这个列表。它将包含国家名称的文本放置在最后一个 x 值的右侧(covid.index[-1] →数据帧中的最后一个日期),在当天的 y 值处(它将始终等于该列的最大值)。

最后,在 第 9 节 中,我们添加了一个关于图表的标题、副标题和源信息。我们再次使用变量来定位数据,因此当图形更新时,这些位置会动态更新!

这是我们第一张图表的最终结果:

我们的第一个可视化结果——各个国家的案例。资料来源:Nik Piepenbreier

创建我们的第二个可视化——每 100,000 人中的病例

为了创建我们的第二个可视化,我们将使用下面的代码:

创建我们的第二个可视化——每 10 万人中的病例。资料来源:Nik Piepenbreier

这一部分主要遵循我们为第一个图表所做的。这表明,一旦使用 Python 设置了图表,更新不同数据集的可视化效果是多么简单!

这是我们的可视化结果:

我们的第二个设想——每个国家每 10 万人中的病例。资料来源:Nik Piepenbreier

结论:用 Matplotlib 实现漂亮的 COVID 可视化

感谢阅读!资料来源:Nik Piepenbreier

在这篇文章中,我们学习了如何使用 Github 上的新冠肺炎数据集生成漂亮的数据可视化。我们可以利用 Python 的强大功能,根据今天的数据自动更新我们的图表。

非常感谢你花时间阅读这篇文章!

使用 Julia 可视化新冠肺炎数据

原文:https://towardsdatascience.com/visualizing-covid-19-data-using-julia-7731a524cf49?source=collection_archive---------28-----------------------

探索 Python 和 R 的强大替代品

克莱班克斯Unsplash 拍摄的照片

朱莉娅在科学计算领域相当有名。继 2018 年发布稳定的 1.0 版本后,逐渐成熟为一种功能强大的通用编程语言。Julia 是动态类型的,被设计得和 C 一样快(参见基准测试),并且使用了令人印象深刻的数学友好语法。我最*完成了 Coursera 上的一门入门课程,之后开始将 Julia 纳入我的日常工作流程。作为一个小项目,我决定利用 Julia 中的 DataFrames 来可视化新冠肺炎时间序列数据。在这个过程中,我意识到关于使用和排除 Julia 故障的信息相对较难找到,这可能会提高像我这样的新用户的准入门槛。因此,我决定把我分享的过程、代码和结果放在一起。

我通常使用 Jupyter 笔记本,它们很容易使用并能完成工作。我没有包括在您的系统上设置 Julia 的详细步骤,这是相对简单的。请记住:

  • 您需要有一个工作的 Jupyter 安装,强烈推荐使用 Anaconda
  • Julia 二进制文件可以在线获得,不要忘记验证 sha256 校验和
  • 你需要“IJulia”包来让 Julia 使用 Jupyter 笔记本,这些指令对我起作用了!我可以很容易地在初级操作系统(基于 Ubuntu)中建立一个工作的 Julia 环境。

让我们开始吧:加载基本包

与 Python 类似,Julia 也使用了许多可以加载到 Jupyter 笔记本中的包。不像 Python,大部分都是用 Julia 本身写的!“Pkg”是 Julia 中内置的软件包管理器,处理它们的安装、更新和删除。“Pkg”带有一个 REPL(读取-评估-打印-循环)。在茱莉亚·REPL 上按]进入“Pkg”REPL。要返回到 Julia REPL,请按退格键或^C.

在朱莉娅 REPL 中添加 StatsBase 包。这一个已经被添加,因此没有做任何改变。

可以如上所示添加包。或者,您可以直接在 Jupyter 笔记本中添加它们,例如通过执行:import PkgPkg.add("假设检验")。因为软件包会定期更新(错误修复、新特性等)。),这篇文章中链接的一些代码可能会在不同的时间点对您不起作用。不过不要担心,朱莉娅有一个非常聪明的解决方案。“Pkg”创建两个额外的文件——“project . toml”和“Manifest.toml”,这两个文件包含关于依赖项、版本、包名、UUIDs 等信息。这些文件可以很容易地共享,并让您重新创建我所拥有的确切的工作环境。

使用笔记本第一个单元格中的“InstantiateFromURL”包直接从我的 GitHub 库下载这些文件。它还激活所需的环境。

现在可以在下一个单元格中编译包,如下所示。包版本将完全一样,我在这个项目工作时使用。

在第一个单元中一次执行(加载和编译)所有包,这需要一段时间(2-3 分钟)

导入数据

在这个练习中,我使用了来自著名的 GitHub 库的新冠肺炎数据,该库由约翰霍普金斯大学系统科学与工程中心(CSSE)维护。数据为 CSV 格式,每天更新。它可以直接导入到文件中,如下所示:

从 GitHub 存储库导入 CSV 数据

第一眼

在继续之前,让我们看一下我们的数据。我想知道更多关于它的结构,大小和类型。

探索数据框架

  • size(data_df)返回数据帧中的行数和列数。由于每天都会添加新列,因此根据检索数据的日期,输出看起来会有所不同。有一列是国家名称,另一列是日期。
  • 使用 names(data_df)列出所有列名,请参见下面的输出示例。这在以后会很方便!

数据帧中所有列名的列表

  • 快速调查显示,我们有一个国家名称列和许多包含所有日期的列。在 Julia 中,缺失的条目用一个特殊的缺失对象来表示。

在数据框架内选择一个国家

我希望能够从数据框架中选择给定国家的时间序列数据。有些国家还列出了“省/州”,这对我来说不是很有用。但是,列为的“省/州”行缺少,包含该国家所有地区的总和。

我将编写一个函数,只选择“省/州”缺少的行,并丢弃其余的行。然后,我可以通过将“国家/地区”条目与我提供的关键字进行匹配,轻松找到该国家。在浏览数据时,我已经注意到提到的国家名称有澳大利亚、德国、印度等,所以我的输入关键字应该相同。

函数返回带有与国家名称匹配的关键字的数据行

处理日期

日期可以直接从列名中读取。为了绘制时间序列数据(x 轴上的日期),我们需要以正确的日期-时间格式显示它们。看看下面的代码片段:

为国家列表创建输入数据

到目前为止,我已经创建了用于绘制时间序列中 x 轴的数据。在 y 轴上,我们可以绘制该特定日期每天的确诊病例总数。然而,我想为我选择的一系列国家这样做,这将有助于比较它们之间的感染传播。回想一下,我之前创建了一个函数,它返回特定国家的一行数据。我们可以使用这个函数遍历用户指定的国家列表。

“find_country”函数从原始数据帧中返回行。然后,从第 5 列开始,也就是第一个日期 22/01/2020 开始,将它堆叠成垂直布局。请注意,Julia 中的索引从 1 开始。

“y”数据帧的最后 10 个条目,最新条目为 2020 年 7 月 24 日。

将所有内容整合在一起—是时候开始策划了!

我们现在有了适合各个国家的时间序列图的 y 轴数据(“y”数据帧)。Julia 允许使用宏' @df '直接从数据帧绘图。我们之前已经加载了“Plots”包,它使用“gr()”后端来生成图形。

用指定的绘图选项绘制 y(所有列)与 x,如图所示。剧情!(称为爆炸)将添加到相同的数字,在这种情况下,虚线标记 100 万个报告的病例。

当返回到单元格时,绘图输出内联显示。这里,我使用了“显示”来明确显示用红色虚线覆盖的原始图(使用 plot!)标志着一百万计数(至少可以说是一个令人担忧的数字)。添加了额外的打印选项以改善打印外观。关于绘图的综合指南可以在这里找到。

前面代码块的输出,红色虚线表示一百万标记

另一组国家的先前代码块的输出

计算每日报告的病例数

另一个值得关注的指标是每天报告的案例数量。我们已经有了一个包含给定日期报告病例总数的数据框架,每天的增加只是任何两个连续日期之间的差异。这种操作可以很容易地全天进行。请参见下面的代码片段:

计算并绘制每日报告病例的增加

在这种情况下,条形图通常能提供更多信息。对于报告病例总数开始饱和的国家,我们可以看到每日病例的增加开始下降。一旦没有新的病例报告,这一数字最好为零。意大利、德国和英国已经设法限制了增长,而印度目前正经历指数增长。

印度每日确诊病例数持续上升

美国每天确诊的病例数最初在下降,然后又开始增长

查找报告病例数最多的前五个国家

为了找到确诊病例数量最多的国家,我们可以根据最后(最*)日期列中的值对原始数据帧“data_df”进行排序。排序是使用“sort!”完成的功能(bang 版,就地排序)降序排列。

对原始数据框架“data_df”进行排序,以确定确诊病例数量最多的国家,并绘制一个水*条形图

截至 2020 年 7 月 24 日确诊病例数最多的前五个国家

随着时间的推移,可视化哪些国家占据了前五名的位置可能会特别有用。幸运的是,Julia 允许我们使用“@animate”宏轻松生成动画。我们只需要遍历这些日期,并为每一天生成一个排名前五的国家的图表(如上所示)。然后将这些图组合成动画,可以以任何所需的帧速率运行。之前使用的代码块需要放在动画循环中,如下所示:

通过循环浏览日期并绘制每个日期的前五个国家来生成动画。fps=2 '设置所需的帧速率,在本例中为每秒 2 帧(2 个日期)。

截至 2020 年 8 月 14 日,新冠肺炎确诊病例最多的前五个国家的动画。执行完代码块后,视频会自动开始在你的 Jupyter 笔记本上播放。

死亡、康复和当前感染的人数

CSSE GitHub 库还包含死亡和康复病例数的时间序列数据。我们可以使用前面所示的相同代码将这些 CSV 数据导入两个新的数据帧:“data_df_recovered”和“data_df_deaths”。

导入附加 CSV 数据

我们可以从这些新的数据框架中收集数据,再一次收集一些国家的数据。下面显示的代码创建了新的数据帧“y_r”和“y_d ”,它们分别包含恢复病例和死亡人数的数据。y '包含确诊病例数,与早前相同。

“find_country”函数从原始数据帧中返回行。然后,从第 5 列开始,即第一个日期 22/01/2020 开始,将其堆叠成垂直布局。请注意,Julia 中的索引从 1 开始。

成组的条形图是可视化一系列国家的多个数据集(确诊、恢复、感染、死亡数)的有用方法。回想一下,我们已经在上面创建了数据帧“y_r”和“y_d”。既然知道了确诊病例总数,我们也可以计算出目前感染人数=确诊病例数(痊愈病例数+死亡人数)。

为了制作柱状图,我们需要从所有单独的数据框架中收集数据。下面的代码将最后一个 DataFrame 行(最*的日期)转换成一个向量,然后作为列添加到二维数组“Y”中。该数组的大小为:行(国家名称列表)×列(=4,对应于确认、恢复、死亡和感染数据)。

请注意,“Y[:,1] = deaths”将一维数组“deaths”分配给“Y”的第一列。类似的赋值用于“已确认病例”和“已恢复病例”。

二维数组“Y”的每一行现在包含给定国家的 4 个数据点。绘图类型“groupedbar”允许我们直接读取这些数据,并使用下面的代码根据国家排列条形组。额外的绘图选项控制条形的外观。

使用 x 轴上的国家名称(names(y))和 Y 轴上的二维数组“Y”中的数据制作一个分组条形图

包含截至 2020 年 7 月 31 日数据的各个国家的分组条形图

德国似乎在管理疫情方面做得很好,类似的“已确认”和“已恢复”数字就证明了这一点。对于印度和巴西等国来说,复苏看起来很有希望,尽管仍有相当一部分工作要做。与痊愈人数相比,法国感染人数更多。

查找康复病例数和死亡人数最多的前五个国家

为了找到恢复案例数量最多的国家,我们可以根据最后(最*)日期列中的值对数据帧“data_df_recovered”进行排序。排序是使用“sort!”完成的函数(bang 版本,就地排序)按降序排列,类似于前面所做的。使用“数据 _ df _ 死亡”数据帧,死亡人数遵循相同的逻辑。

对数据框“数据 _ df _ 恢复”进行排序,以确定确诊病例数最高的国家,并绘制一个水*条形图

截至 2020 年 7 月 31 日,恢复案例数量最多的前 5 个国家

截至 2020 年 7 月 31 日死亡人数最多的前 5 个国家

结论:Julia——解决数据科学问题的通用工具

通过这篇文章,我试图展示一个初学者使用 Julia 解决数据科学中一些基本问题的经验。完整代码可以在这里找到。我意识到我可能错过了一些细节,这是意料之中的,因为这绝不是一个权威的指南。其他资源也存在于网络上,尽管这样的指南可能很难找到。我对 Julia 的世界还很陌生,很乐意收到一些反馈,甚至是改进代码的建议。我将继续探索高级的 Julia 库,并使用它们来创建使用大型复杂数据集的更有洞察力的可视化。请继续关注更多这样的指南。感谢你花时间阅读这篇文章!请随时在 LinkedIn 上与我联系。

参考资料:

  1. 链接完成茱莉亚代码要旨
  2. https://syl 1 . git book . io/Julia-language-a-concise-tutorial/language-core/getting-started
  3. https://julialang.org/
  4. 另一个使用 Python 的优秀数据可视化教程

[## 使用 Python 实现新冠肺炎数据可视化

什么是数据可视化?

towardsdatascience.com](/covid-19-data-visualization-using-python-3c8bcfaeff5f)

想象 2020 年 8 月的新冠肺炎

原文:https://towardsdatascience.com/visualizing-covid-19-in-august-2020-9e08cc1e489d?source=collection_archive---------47-----------------------

通过一个案例研究来展示新冠肺炎的发展

图片作者:特里斯特·约瑟夫

自 2019 年 12 月底在中国首次记录以来,新冠肺炎已传播到世界各地,并被世界卫生组织宣布为疫情。正因为如此,数十亿人被封锁,卫生服务部门疲于应付。现在,在 2020 年 8 月,学生是否应该亲自回到学校度过新学期,餐馆等企业是否可以恢复正常运营,以及各国是否应该加强之前的封锁措施,这些都有很多问题。

这些决策中的许多需要由数据保健专业人员来指导,而不应该在没有数据的真空中做出。数据分析过程有许多方面,数据可视化是一个非常重要的方面。数据可视化是获取信息并将其转换为可视化上下文(如图表)的过程。大多数人倾向于同意,看一个图表并理解潜在的信息比通读一个数字表要容易得多,特别是对于大型数据集。因此,为了了解新冠肺炎病例在各个国家的分布情况以及新冠肺炎是如何在这些国家传播的,我将进行一次数据可视化练习。

图片作者:特里斯特·约瑟夫

所有分析都将在 R 中使用 tidyverse 进行,数据可以从一个公开可用的数据库中检索(参考资料部分中的链接)。

library(tidyverse)
library(ggthemes) # contains the theme used for the graphs

第一步是将数据加载到我的环境中,并确保它的结构适合可视化分析。

covid_df <- read_csv('file_path'+'file_name')
glimpse(covid_df)

该数据集包含日期、国家、省份、经度、纬度、给定日期的病例数以及这些病例是确诊阳性病例、痊愈还是死亡等变量。对于这一分析,我感兴趣的是确诊阳性病例的日期、国家和数量。因此,我将选择这些列,并创建一个仅包含感兴趣的变量的新数据框。

但是,在检查来自glimpse(covid_df)的输出时,发现日期变量被解析为字符类型而不是日期类型,并且 case 类型也被解析为字符,而它应该是因子。因此,我将把变量转换成适当的数据类型,然后创建新的数据框。

covid_df$date <- parse_date(covid_df$date, format="%m/%d/%Y")
covid_df$type <- parse_factor(covid_df$type)confirmed_cases <- covid_df%>%
  filter(type=="confirmed")%>%
  select(c("date", "country", "cases"))

现在我有了感兴趣的数据,这将对了解新冠肺炎的全球增长很有价值。由于数据框包含许多国家/地区,并且多个国家/地区在同一天出现确诊阳性病例是合理的,因此需要按日期对数据进行分组,然后进行汇总,以找到每天的病例总数。此外,为了了解增长情况,还应该计算一段时间内案例的累计总数。

confirmed_cases_total <- confirmed_cases%>%
  group_by(date)%>%
  summarise(Total_cases= sum(cases))%>% #aggregates by day
  mutate(Cumulative_cases = cumsum(Total_cases)) #calc cumulativeggplot(confirmed_cases_total, aes(x=date, y=Cumulative_cases))+
  geom_line()+
  scale_y_log10()+
  scale_x_date(date_breaks = "months", date_labels = "%b-%Y")+
  ylab("Cumulative Cases")+
  xlab("Date")+
  ggtitle("Cumulative World Covid-19 Cases per day")+
  theme_tufte()

图片作者:特里斯特·约瑟夫

该图显示,全球新冠肺炎病例在 1 月至 2 月间迅速增加,在 3 月初放缓,然后在 3 月中旬后再次迅速增加。还可以看出,目前的新增病例率低于 3 月中旬至 4 月的比率,但世界范围内的病例仍在增加。

尽管在疫情爆发的早期,病例主要集中在中国,但美国很快成为关注的地区。因此,我接下来将绘制美国与世界其他地区的对比图,以收集关于 3 月份及以后案件上升的见解。

------------------ # Data 
UnitedStates_confirmed_cases <- confirmed_cases%>%
  filter(country=="US")%>%
  group_by(date)%>%
  summarise(Total_cases = sum(cases))%>%
  mutate(Cumulative_cases = cumsum(Total_cases))UnitedStates_confirmed_cases$Location <- as.factor(rep("USA", nrow(UnitedStates_confirmed_cases))) #creating memebership variableNotUnitedStates_confirmed_cases <- confirmed_cases%>%
  filter(country!="US")%>%
  group_by(date)%>%
  summarise(Total_cases = sum(cases))%>%
  mutate(Cumulative_cases = cumsum(Total_cases))NotUnitedStates_confirmed_cases$Location <- as.factor(rep("USA", nrow(NotUnitedStates_confirmed_cases)) #memebership variableusa_vs_world <- rbind(UnitedStates_confirmed_cases, NotUnitedStates_confirmed_cases) #combining the two df's------------------ # Graph
ggplot(usa_vs_world, aes(x=date, y=Cumulative_cases, color=Location))+
  geom_line()+
  scale_y_log10()+
  scale_x_date(date_breaks = "months", date_labels = "%b-%Y")+
  xlab("Date")+ 
  ylab("Cumulative Cases")+ 
  ggtitle("Cumulative Covid-19 Cases per day, USA vs The World")+
  theme_tufte()

图片作者:特里斯特·约瑟夫

这两条曲线具有相似的形状;它表明,美国国内确诊病例的数量在 3 月份期间迅速增加,并且这种迅速增加一直持续到 4 月份。尽管这确实为第一个图中出现的病例激增提供了洞察力,但也可以看出,世界其他地区在 3 月期间和之后仍出现了确诊病例数量的快速增加。

正因为如此,我将比较美国和中国,以确定这两个国家的疫情之间的异同。

------------------ # Data
UnitedStates_confirmed_cases$Country <- UnitedStates_confirmed_cases$LocationUnitedStates_confirmed_cases$Location <- NULLChina_confirmed_cases <- confirmed_cases%>%
  filter(country == "China")%>%
  group_by(date)%>%
  summarise(Total_cases= sum(cases))%>%
  mutate(Cumulative_cases = cumsum(Total_cases))China_confirmed_cases$Country <- as.factor(rep("China", nrow(confirmed_cases_China)))USAvsChina <- rbind(China_confirmed_cases, UnitedStates_confirmed_cases)------------------ # Graph
ggplot(USAvsChina, aes(x=date, y=Cumulative_cases, color=Country))+
  geom_line()+
  scale_y_log10()+
  scale_x_date(date_breaks = "months", date_labels = "%b-%Y")+
  xlab("Date")+ 
  ylab("Cumulative Cases")+
  ggtitle("Cumulative Covid-19 Cases per day, USA vs China")+
  theme_tufte()

图片作者:特里斯特·约瑟夫

图表显示,随着美国确诊病例的持续增长,中国相对趋于*稳。因此,中国的情况无法解释前面图表中看到的跳跃。

那么是哪些国家导致了新冠肺炎病例的持续增长呢?理想的做法是确定哪些国家在确诊阳性病例总数方面名列前茅。

Hardest_hit_Countries <- confirmed_cases%>%
  group_by(country)%>%
  summarise(Total_cases = sum(cases))%>%
  arrange(desc(Total_cases))%>%
  top_n(5)

Hardest_hit_Countries的输出显示了确认阳性病例总数排名前 5 位的国家的表格。从该表可以看出,美国是这方面最多的国家,共有 4,823,890 起案件。美国之后是巴西,为 2859073 例;印度,1964536 例;俄罗斯 864948 例;南非有 529,877 个病例。

为了了解这些国家在一段时间内对全球新冠肺炎病例增长的相对贡献,可以绘制一个图表,比较这些国家与世界其他国家的增长情况。如果这些国家是前面图表中出现的凸起的原因,那么与前面图表中的同一条线相比,代表世界其他地区的线将会*坦得多。

图片作者:特里斯特·约瑟夫

图表显示,受打击最严重的国家在 3 月期间和之后的病例上升中占了相当大的一部分,其中美国占了 3 月份病例的大部分。然而,在三月份,世界其他地方仍然存在着明显的颠簸。一个原因是,受打击最严重的过滤器决定了哪些国家目前新冠肺炎病例最多,而这些国家可能不是 3 月份的同一批国家。

为了确定在此期间哪些国家是受打击最严重的,我将更新受打击最严重的过滤器,并确定哪些国家现在名列前茅。

Hardest_hit_Countries_before_may <- confirmed_cases%>%
  filter(date <= "2020-04-01")%>%
  group_by(country)%>%
  summarise(Total_cases = sum(cases))%>%
  arrange(desc(Total_cases))%>%
  top_n(5)

这个数据框的输出现在显示,美国仍然是排名第一的国家,有 214,205 例。然而,美国现在以 110,574 例紧随其后的是意大利;西班牙 104118 例;中国 82361 例;德国有 77872 例。

这些数字还表明,在 4 月 1 日至 8 月 5 日期间,美国确诊阳性病例的数量增加了 2000%以上。疯狂。

那么,现在知道了美国确诊的阳性病例大幅增加,那么美国占全球病例的比例是多少呢?事实上,了解每个国家在确诊病例中所占的比例将是令人感兴趣的。

share_of_cases <- confirmed_cases%>%
  group_by(country)%>%
  summarise(Total_cases = sum(cases))%>%
  mutate(p_of_total_cases = (Total_cases/sum(Total_cases))*100)%>%
  arrange(desc(p_of_total_cases))%>%
  mutate(cumulative_p_of_total_cases = cumsum(p_of_total_cases))

share_of_cases的输出显示,3 个国家的病例目前约占全球确诊阳性新冠肺炎病例的 50%,其中美国的病例约占 26%;巴西的病例占~ 15%;印度的病例约占 10%。这尤其令人担忧,因为该数据集包含 188 个国家。因此,这意味着该数据集内不到 2%的国家占全世界病例的 50%。

结果还显示,14 个国家的病例目前占全球确诊阳性新冠肺炎病例的 75%。现在,这一指标仍然表明病例集中在少数几个国家,但这比占全球病例约 50%的 3 个国家的病例要好。

我要做的最后一件事是创建一个图表来显示美国境内确诊阳性病例的增长情况,同时标注关键事件,例如何时宣布疫情以及何时所有州都处于封锁措施之下。

------------------ # Data
usa_events <- tribble(
  ~date, ~event, 
  "2020-01-30", "Global Health\nEmergency", 
  "2020-03-11", "Pandemic\nDeclared",
)%>%
  mutate(date = as.Date(date))------------------ # Graph
ggplot(confirmed_cases_USA) +
  geom_line(mapping=aes(x=date, y=Cumulative_cases)) +
  geom_smooth(mapping=aes(x=date, y=Cumulative_cases), method="loess")+
  geom_vline(aes(xintercept = date), data=usa_events, linetype="dashed")+
  geom_text(aes(x=date, label=event), data=usa_events, y=3000000)+
  annotate("rect", xmin =as.Date("2020-03-19", "%Y-%m-%d"), xmax=as.Date("2020-04-24", "%Y-%m-%d"), ymin=0, ymax=6000000, alpha=0.25)+
  annotate("text", x=as.Date("2020-04-06", "%Y-%m-%d"), y=4000000, label="All States Lockdown")+
  theme_tufte()+
  scale_x_date(date_breaks="months", date_labels="%b-%Y")+
  xlab("Date")+
  ylab("Cumulative Cases")+
  ggtitle("United States Cumulative COVID-19 Cases")

图片作者:特里斯特·约瑟夫

该图显示,尽管此前采取了封锁措施,美国确诊的新冠肺炎阳性病例数量仍在以二倍的速度增长。由于一些州反对继续(或重新实施)封锁措施,这一点更令人担忧。

由于它涉及前面提到的关于学生、餐馆和类似企业以及其他国家的问题,决策者应继续监测其管辖范围内的案件,并根据其情况做出最佳决定。冠状病毒肯定没有消失,任何关于健康和安全的决策都需要高度的数据驱动。

参考文献:

数据仓库:github.com/RamiKrispin/coronavirus

代号:github.com/trisxcj1/visualizing-covid19

tidyverse.org/

其他有用的素材:

【tidyverse.org/learn/

r-bloggers.com/why-learn-the-tidyverse/

linkedin.com/learning/learning-the-r-tidyverse

dplyr.tidyverse.org/

linkedin.com/in/rick-scavetta/

新冠肺炎:隔离措施在加州奏效了。我们需要全国范围内更多的承诺。

原文:https://towardsdatascience.com/visualizing-covid-19-isolation-measures-are-working-we-need-more-ca1012ff269e?source=collection_archive---------42-----------------------

随着美国最*声称全球大多数冠状病毒病例的不良区分(根据官方统计),纽约时报提供了一个全国所有确诊新冠肺炎病例的数据集,在州和县一级进行跟踪,并每天更新。

虽然承认数据永远不会完美,但真实的案例数量可能要大得多,并且测试频率和有效性因地区而异,以下是我迄今为止的发现。

为了保持简短和可操作性,我将只限制两个要点,概述如下 (请注意,我不是流行病学家、医生或医疗保健专业人士):

  • 几个星期以来,安东尼·福奇博士等专家一直鼓励我们保持社交距离,与他人隔离,以使曲线变*,减缓新冠肺炎病毒的传播,让压力过大的医疗系统有机会迎头赶上。最*来自加利福尼亚的报道表达了谨慎的乐观,认为这些努力在减缓病毒传播方面是有效的。下面分享的我的数据分析,支持了这个观点。
  • 因为目前没有有效的治疗方法或疫苗,更不用说新冠肺炎病毒会在它存在的任何地方呈指数级传播。这个国家的不同地区只是位于指数曲线的前部或后部。与其坐等疫情在适当的时候爆发,让医疗系统不堪重负,病例数量较少的州和管辖区应该抓住机会,在局势更加可控的时候实施隔离:

继续分析…

由于早期采取了积极的隔离措施,加州似乎正在减缓新冠肺炎的传播。

下图显示了在撰写本文时美国十个州每 100,000 人的新冠肺炎病例数。

除了纽约和新泽西非常需要我们的帮助这一事实之外,这张图表中更微妙的观察和一线希望是,与其他州相比,加州的病例增长相对缓慢,尽管加州是早期震中的所在地。该州采取了果断的行动,在纽约事件发生前 5-7 天下令“避难所就位”,这似乎产生了巨大的影响,尽管显然不是唯一的影响因素。

鉴于新加坡和台湾等国家使用积极的检测和隔离措施成功控制了病毒的传播,有理由认为,及早采取积极的隔离措施有助于加州控制传播,并将有助于全国其他州。

虽然对许多人来说,积极的隔离措施显然是有效的,但一些国家仍然没有执行任何就地安置/留在家中的命令,或任何其他形式的强力隔离。

实施这些隔离措施可能是我们在世界上抗击病毒传播的最佳机会,因为美国目前是世界上确诊病例最多的国家。

案例数较少的州应实施隔离。新冠肺炎到处呈指数传播。

第二个要点:所有州似乎都遵循类似的指数增长模式,正如你将在下面看到的那样——即使是那些病例数量较少的州。

鉴于他们中的许多人似乎处于曲线的早期,当务之急是在他们的情况可能更加可控的时候,抓住机会采取行动和实施隔离措施。

下图显示了“前 10 名”之外的各州案件总数的增长情况。你会注意到所有的曲线都有相似的形状。为了便于查看,我将每个图表限制在不超过 10 个状态。

社交距离和隔离可能是我们目前在全球抗击新型冠状病毒的最佳工具,根据数据,当正确实施时,它们正在发挥作用。

我希望那些处于领导地位的人将迅速采取必要的行动,我们每个人都将认真对待这一问题,尽我们的努力,尽我们最大的能力留在家里。

当然,所有这些隔离并不是没有代价的。我们还需要社会解决方案、政府干预、新的创新和大量的同理心来相互帮助,度过这个在精神上、精神上和经济上极具挑战性和毁灭性的经历,特别是对我们人口和经济中最脆弱的部分。

怀着谨慎的乐观,我相信我们有能力应付这一局面,但我不想在这里探讨这些问题。在我的公寓里,我将和我的家人呆在一起,祝愿我们一切都好。

想进一步了解我分析背后的细节,或者想看背后的 Python 代码,可以 访问我的 Github 这里

请理解这是一项正在进行的工作,不要指望我清理任何东西😆

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

使用 React 可视化新冠肺炎随时间的变化

原文:https://towardsdatascience.com/visualizing-covid-19-over-time-using-react-92ccf9a3354e?source=collection_archive---------45-----------------------

如何创建同时显示地理和时态数据的工具。

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

可视化电晕超时

neerajcshah.github.io](https://neerajcshah.github.io/corona/)

当我在二月份第一次看到 Johns Hopkins 拼凑了一个新冠肺炎可视化工具时,我也想看看我能做些什么。我意识到,我不可能制作出比现有的在线地图好得多的实时地图,但我开始回答一个不同的问题:我们能看到日冕在地理和时间上是如何传播的吗?

追踪新冠肺炎的基于时间的地图的屏幕截图

从那以后,我制作了一个 React 可视化程序来监控电晕的传播,我想我会分享它,以防它能让其他人受益。它从约翰霍普金斯大学 CSSE 分校提取数据,并允许用户查看从 1 月 22 日起任何日期的病毒状态(这是 JHU 有数据的第一天)。您可以拖动地图下的滑块来查看案例如何随着时间的推移而改变世界。

可视化是基本的,但它帮助我更好地理解一些由研究人员表达的东西。

首先,它告诉我,美国现在是危机的中心,但以前,中国和意大利拥有这个头衔。

它还帮助我理解,在像中国这样的国家,测试或报告方面的差距肯定存在,那里的数据已经几个月没有变化了。

最后,如果我们在 2020 年 6 月 8 日检查新西兰的所有方框,我们可以看到“感染”圈与“恢复”圈几乎完美重叠。也是在这一天,新西兰宣布在其境内消灭了该病毒。

新西兰宣布零病例的那一天

用 python 开发这种交互式的东西可能会很有挑战性,也不那么完美。相反,React 是自然的选择,因为它被设计成通过简单、响应迅速的 UI 组件来呈现变化的数据。在本文的其余部分,我将介绍使用 React 开发这个项目的关键部分。

1-获取数据

任何可视化的一个挑剔的部分可能是处理输入数据,在这种情况下尤其如此,因为数据由另一方(Johns Hopkins)拥有和更新。这意味着当他们改变他们的组织风格时,我也必须适应。我选择依赖他们的数据库,因为这意味着我不必担心自己存储和维护实时数据。

他们目前每天在世界协调时 23:59 分左右上传一次时间序列数据到 Github。csv 文件。我希望我的应用程序在启动时提取数据,这样我们就可以始终显示世界的当前状态。

每当您从托管文件中提取内容时,获取原始内容是一种很好的做法。我们可以在 Github 上通过点击任何文件右上角的“Raw”按钮来实现。

始终提取“原始”内容,以便于后期处理

我使用了一个名为“ Axios ”的基于 promise 的 HTTP 客户端,用这个原始内容的 URL 执行“get”请求。这个异步操作的结果可以用“then”关键字来处理,它接受一个成功完成的承诺,并对其执行一个函数。

static pullAndParseUrl(url) {
    return axios.get(url).then(response => 
                               Papa.parse(response.data,
                                         { header: true }));
}

如上所示,“then”函数获取“axios.get”的结果,并用浏览器内的 csv 解析器“ Papa Parse ”解析内容。

Johns Hopkins 将数据存储在 csv 中,其中行映射到国家,列映射到日期。因为第一行包含列名,所以我们在调用“Papa.parse”时指定“header : true”。Papa.parse 生成一个与国家对应的字典列表。每个字典都允许我们按日期索引感染人口规模,这对于稍后的 slider 集成非常重要。这整个行动的结果是一个承诺,一旦它完成,我们将有我们想要的形式的数据!

2-传单地图

为了制作地图,我们将使用传单,这是我选择的一个 JavaScript 交互式映射库,因为它有很好的文档,并且不需要任何 API 键或令牌。还有一个 react 库叫做 react-leaflet ,它是带有 React 组件的 leaflet 库的抽象。

我们将从导入“Map”和“TileLayer”组件来显示一个简单的地图开始。

import { Map, TileLayer } from 'react-leaflet';

作为反应的快速复习,组件接受参数,这些参数被称为“道具”。每当组件的属性改变时,组件就更新它的显示。组件之间的嵌套允许数据流经应用程序的各个部分。

我们现在将创建一个新的传单类,它扩展了“React。组件”。注意,构造函数只接受一个参数——“props”——它包含所有传入的参数。作为参考,要访问传递给组件的特定参数,我们可以编写“this.props.parameterName”。

export default class Leaflet extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
     //TODO: Return map you wish to display.
  }
}

传单地图可以用很少的代码显示在屏幕上。我们只需用纬度/经度和缩放级别实例化地图组件。我们还应该添加 TileLayer,为开放街道地图团队增光添彩。

我们将用我们希望类返回的内容填充 render 方法。每当传递给类的参数发生变化时,就会调用 render 方法。

render() {
  const position = [35, -40];
  const zoom = 2;
  return (
    <Map center={position} zoom={zoom}>
      <TileLayer
        url={"[https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png](https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png)"}
        attribution={contributors}
      />
    </Map>
}

我们有地图!

3-表示数据

我们将使用 react-leaflet 中的圆形组件在地图上描绘人口。圆是一种有点粗糙的地理数据可视化方式,因为它们可能无法很好地反映地理事实。例如,我们知道美国的大多数病例都发生在沿海地区,但如果我们只能画一个圈来代表美国的新冠肺炎病例,我们会将它放在国家的中心。解决方案应该是拥有更细粒度的数据,并利用这些数据构建详细的热图,但不幸的是,我们受到数据稀疏性的限制。

import { Circle } from 'react-leaflet';

地图上圆圈的大小代表了感染、康复或死亡人口的数量。我们可以通过指定半径来控制圆组件的大小。因为增加半径会导致圆的面积以*方的方式增加,所以我们需要小心不要将人口直接映射到半径上。相反,我们通过取每个群体的*方根并乘以某个常数来计算半径。

我们将在传单组件中添加一个名为“MyCircles”的组件,它将处理圆圈的创建。它将接收数据(在第 1 节中构造)、选定的日期和所需的圆圈颜色——所有这些都传递给了传单。

// Within the Map tags in Leaflet.
<MyCircles data={this.props.data} 
           date={this.props.date} 
           color="red"/>

下面实现了一个简化的 MyCircles 类。

const MyCircles = (props) => {
  return (
    props.data.map((row, i) => {
      if (row["Lat"] != null && row["Long"] != null) {
        return (
          <Circle
            key={i}
            center={[row["Lat"], row["Long"]]}
            radius={1000 * Math.sqrt(row[props.date])}
            fillColor={props.color}
          />)
        }
      }
    )
  );
}

回想一下,props.data 由一个列表组成,其中的每一项都是一个字典,按日期表示一个国家的病例数。MyCircles 遍历 props.data 中的每个国家/地区,并读取该国家/地区在 props.date 的事例数。如果事例数不为零,它将返回一个在给定纬度/经度处具有计算半径的圆组件。

4 —滑块

React 的一个核心概念是将 UI 分割成几部分。正如我们为地图构建了一个名为“传单”的组件一样,我们也将为滑块构建一个组件。我们通过使用“material-ui”中内置的“Slider”组件来实现它。我在下面包含了一个对 slider 组件的简化调用:

<Slider
  defaultValue={0}
  onChange={this.handleChange}
  marks={marks}
  max={difference_in_days}
/>

如您所见,它有不同的参数,如“默认值”、“标记”和“最大值”。我们将第 0 天(2020 年 1 月 22 日)指定为默认值。“标记”是指滑块上带标签的“记号”,在这种情况下,我们只标记开头和结尾。“max”设置的“difference_in_days”变量指的是第 0 天和今天之间的天数(这是动态计算的,并保持可视化为最新)。最后,“onChange”被分配给一个名为“this.handleChange”的函数,如下所示。每当滑块移动时,React 都会调用它。

handleChange(event, newValue) {
    var result = new Date("01/22/2020");
    result.setDate(result.getDate() + newValue);
    this.props.handleDateChange(formatDate(result));
}

这个函数基于从滑块传入的值更新日期,并调用“this.props.handleDateChange”,我们将在下一节讨论它。

5 —管理状态

到目前为止,我们已经看了道具。Props 是不可变的,用于从高层组件向下传递数据。为了利用 React 的响应能力,我们还将查看状态。状态是可变的,不应由子组件直接访问。

状态帮助我们将组件之间的交互联系在一起。如前所述,我们将看看滑块的 onChange 方法如何修改地图。

下面,我在 React 项目中加入了顶级“App”组件的简化版本。如图所示,它在“state”中有一个名为“date”的条目。

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      date: "1/22/20",
    };
    this.handleDateChange = this.handleDateChange.bind(this);
  }
}

您还会注意到,构造函数提到了“handleDateChange”方法,在上一节中,我们将该方法传递给了 slider 组件。“bind”函数将方法的“this”关键字设置为总是引用“App”,即使我们将方法传递给不同的类。

“handleDateChange”方法的简短实现如下所示。

handleDateChange(selectedDate) {
    this.setState({ "date": selectedDate });
};

它调用名为“setState()”的 React 生命周期方法来设置新的日期。“setState”函数更新组件的状态,并告诉该组件及其所有子组件再次呈现它们自己。

我们将这个方法传递给 slider,这样它的“onChange”方法就可以改变父组件的状态。

<DateSlider
  handleDateChange={this.handleDateChange}
/>

现在,每当我们拖动滑块时,父“App”组件将更新其状态的日期。

由于我们将“this.state.date”作为道具传递给了 Leaflet 类,因此每当日期发生变化时,地图都会动态更新,从而满足我们在地理和时间上显示日冕分布的愿望。

<Leaflet
  date={this.state.date}
/>

这种结构有助于应用程序具有流动性,也用于帮助复选框修改地图。它允许您编写少量代码来促进引人注目的 UI 交互。

结论

通过将这些案例可视化,我已经能够观察到一些趋势,否则我会发现很难理解这些趋势。这个工具帮助我确认我正在阅读的报告,但它偶尔也会让我有新的惊喜,因为它可以一次显示大量的全球数据。我所介绍的框架可以用于任何项目,在这些项目中,您希望在不同的时间灵活地查看某些内容。我建议将它应用到您感兴趣的另一个数据集并共享结果!

如需进一步参考,可在此处找到代码

[1] ReactJs, React 顶级 API (2020)。Reactjs.org

可视化新冠肺炎传播与 Tableau 动画

原文:https://towardsdatascience.com/visualizing-covid-19-spread-with-tableau-animations-75890dda23bb?source=collection_archive---------41-----------------------

动画地图,赛车条形图,和 Python 合并,天啊!

绘制从美国首次爆发到 2020 年 7 月 1 日的新冠肺炎病例传播图。作者 GIF。

这个项目产生于一种兴趣,即想象新冠肺炎的热点是如何随着疫情的发展而变化的。自从看了这个视频之后,我就对视频中显示的“赛车条形图”这样的基于时间的动画产生了兴趣,还有动画地图。

由于 COVID 的爆发与地理高度相关,我将创建一些动画地图和赛车条形图,看看我们可以了解到什么。在此过程中,您将了解如何将数据集与 Python 相结合,以及如何使用 Tableau Public 创建基于时间的动画。如果你只是想跳到已完成的项目,在这里查看

🚨强制性公共卫生咨询🚨远离拥挤的海滩,去和后院的游泳池做朋友吧😉(当然,只要他们的测试结果是阴性的……而且他们没有邀请其他朋友……你知道吗,只要洗个放松的澡就可以了)

我将在这里使用两个数据集:

  1. 来自《纽约时报》的数据显示了美国各县的新冠肺炎病例。它每天都在更新,但我下载的数据只到 2020 年 7 月 1 日。 注: COVID 病例在此列为截至给定日期的累计总数,包括无症状病例、有症状病例和已痊愈病例。换句话说,病例数可能高估了在给定时间点实际患有 COVID 的人数,所以请记住这一点。
  2. 人口普查局的美国各县人口数据表。

数据清理和混合(也是每个数据科学家最喜欢的部分,❤️)

我不仅希望看到哪些县的病例最多,而且希望看到哪些县的感染率最高。虽然像佛罗里达、加利福尼亚和纽约这样的地方有大量的病例(主要是因为人口较多),但是它们就一定有最高的感染率吗?

NYT 数据集不包括县人口信息,所以我将使用 Python 和pd.merge()将两个数据集合并为一个。如果您对 Python 不感兴趣,也可以通过在 Excel 中使用 SQL JOIN 或 VLOOKUP 来完成。在此之前,我们首先需要清理数据,使其成为最适合合并的格式。

我不会用清理数据的所有细节来烦你——如果你想看到我的数据清理的全部,请查看 Github repo 这里 。然而,我确实遇到了一些意想不到的障碍。

路易斯安那州有教区而不是县,阿拉斯加州的县名与“斯卡圭市”、“诺姆人口普查区”和“德纳里自治市”完全不一致。这使得隔离这些地区的名称以便 Tableau 可以正确地识别它们来构建地图成为一项有趣 (阅读:两个痛苦的小时)的任务。

import numpy as np
import pandas as pdcovid = pd.read_csv('covid-us-counties.csv')
cpop = pd.read_excel('co-est2019-annres.xlsx',skiprows=2)df = pd.merge(covid,cpop,left_on=['county','state'],right_on=['County','State'],how='inner')
dfm = df[['date','County','State','cases','deaths','Population Estimate 2019']]dfm.to_excel('covid-us-county-population.xlsx')

注意,我已经执行了一个内部合并,这意味着两个数据集将只在 county 和州的值匹配的行上连接,所有不匹配的行将被丢弃。现在我们的数据看起来像这样,只有我们需要的行:

按县数据集合并新冠肺炎病例。图片作者。

Tableau 动画

Tableau 是最强大的数据可视化*台之一,他们的免费版本 Tableau Public 拥有我们完成这一分析所需的所有功能。Tableau 的团队和保罗·艾萨克斯在解释如何实际制作动画赛车条形图方面做得比我好得多,所以我会让他们告诉我如何做,并更多地关注我们可以从数据中提取哪些见解。

让我们从用动画地图可视化各县的新冠肺炎案例开始,如下图所示。

一段时间内各县的累计 COVID 病例(左),以及 2020 年 7 月 1 日的最终分布(右)。作者图片。

当我第一次创建地图时,颜色之间的对比度太小,地理上的小县如纽约县(基本上只是曼哈顿)和少数其他暗红色。为了使地图阅读起来更有趣,并显示更大的颜色梯度,我设置了最大值(在加利福尼亚和新英格兰的暗红色),这样 20%的县将被暗红色覆盖。(病例数的第 80 百分位恰好是 513 例。)

关于这张地图的一些观察立刻引起了我的注意:

  • 无论是由于缺乏足够的检测资源,缺乏报告病例,还是真正没有冠状病毒,相当多的县似乎没有冠状病毒病例。加利福尼亚州、内华达州和华盛顿州的这些县可能是灰色的,因为周围的县往往有大量病例,因此缺乏报告。
  • 另一方面,整个中西部的灰色县可能真正没有报告病例,因为周围的县都是浅红色阴影,表示病例很少。
  • 虽然加州、纽约州和德克萨斯州一直占据着新闻报道的中心,但很明显,其他几个州也受到了重创,尽管受到的关注相对较少:亚利桑那州、科罗拉多州、密歇根州、北卡罗来纳州以及新英格兰的大部分地区。

让我们更仔细地看看病例数最多的 10 个县。

按一段时间内累计病例和死亡人数排名的县(左),以及 2020 年 7 月 1 日的最终排名(右)。作者图片。

根据 Worldometer 对纽约市COVID 病例和死亡病例的分析,*均感染死亡率为 1.4% 。人们很容易看到 1.4%这样的数字,并认为它在任何地方都适用,这将使比较各县的病例和死亡人数变得完全没有意思。换句话说,很容易假设:

(病例数)*(1.4%) =(死亡数)

在上面的图表中,我们开始发现事实并非如此。例如,洛杉矶县在病例数量上排名第二,但在死亡人数上排名第三。另一方面,米德尔塞克斯郡在病例数量上排名第六,但在死亡人数上排名第四。

也许洛杉矶县比米德尔塞克斯县拥有更多的医院床位和更好的优质医疗服务,所以感染 COVID 的人很少到达危急阶段。另一种可能的解释是,洛杉矶县的年轻人比例高得多,他们死于 COVID 的风险较小,因此更愿意外出冒险,这使他们感染 COVID 的风险更大。老年人可能更不愿意去公共场合,但当他们感染了 COVID,他们更有可能死亡。

在下面的州一级,同样的趋势也很明显。加利福尼亚州在病例数上排名第二,但在死亡率上排名第七,而另一方面,马萨诸塞州在病例数上排名第七,但在死亡率上排名第三。

各州按一段时间内的累计病例和死亡人数排名(左),2020 年 7 月 1 日的最终排名(右)。作者图片。

各县受感染人口的百分比

尽管病例数在纽约和洛杉矶等地继续以惊人的速度攀升,但我在新闻中没有听到的一项统计数据是,这些县的人口中有多少百分比实际上受到了感染。我使用人口普查局的数据创建了下面的地图和条形图。

****

随着时间的推移,县人口感染的百分比(左)和 2020 年 7 月 1 日的最终分布(右)。作者图片。

暗红色县的聚集似乎从主要的大都市地区急剧转移到人口密度较低的农村地区。突然间,洛杉矶县看起来相当受控制,而亚利桑那州、密西西比州和中西部的一些县看起来受到了破坏。

用数字来说明:

  • **洛杉矶县只有 1.05%的人被感染**,而亚利桑那州的马里科帕县(凤凰城州府所在地)的感染率为 3.3%。
  • 纽约县(曼哈顿)感染率 13.52% 依然惊人!
  • 人口只有 7816 人的田纳西州特鲁斯代尔县,感染率高达 13.2% 。住在这里而不知道至少一个被感染的人是不可能的。

想象一下这些感染率超过 5%的县正在经历的灾难,然后结合这些地方获得高质量医疗保健的机会可能比洛杉矶或纽约少的事实,我们面临着一个相当严峻的局面。

****

按累计病例数和县人口感染百分比对各县进行排名(左),最终排名于 2020 年 7 月 1 日。作者图片。

免责声明:我不分享这些见解来贬低像洛杉矶和纽约这样有大量病例的城市。我只是想指出一些事实,揭示另一个没有受到关注的故事:获得优质医疗服务较少的农村地区的故事,他们遭受的痛苦可能超出我们大多数城市居民的想象。

有待改进的领域

#1:将固定的 x 轴改为动态轴

动态 x 轴示例。视频由 RankingTheWorld 制作(https://www.youtube.com/watch?v=8WVoJ6JNLO8)。

在经典的赛车条形图(如上所示)中,排名第一的条形占据了屏幕的整个宽度,每隔一个条形占据的宽度与排名第一的条形成比例。然而,目前所有的赛车条形图的 x 轴都是固定的,这使得分辨率太低,无法看到 4 月份之前的真实情况。

这里有一个关于如何修复这个的教程,它适用于非聚合的原始数据,但是因为我们的原始数据是预聚合的,所以他们对 WINDOW_MAX 的修复不起作用。(如果你能想出如何让它工作就加分!)**

#2:创建实时连接

我在 2020 年 7 月 1 日从 NYT 的 Github 页面下载了这个数据集,从那以后出现了相当多的案例和新趋势,这些都没有被这些动画捕捉到。目前,我使用的是 Tableau Public (Tableau 的免费提供),它不允许与数据集进行实时连接。如果我升级到完整版的 Tableau Desktop,我可以与 NYT 的 Github 页面建立实时连接,这样数据每天都会自动更新,可视化效果也会随之更新。

#3:速度

这个数据集有大约 280k 行,所以每次放大或缩小地图时,整个地图都需要重新绘制,这使得界面有时非常滞后。我不知道这是否可以用 Tableau 来修复,但我很想知道是否有人知道如何修复。

疾控中心Unsplash 上拍照。

希望你喜欢这个分析,即使它有点令人沮丧…要查看完整的可视化,请查看我的 Tableau 公共简介这里,我也期待看到你观察到的!

使用 Plot.ly For Python 可视化新冠肺炎漏洞

原文:https://towardsdatascience.com/visualizing-covid-19-vulnerability-with-plot-ly-for-python-bce308dd58?source=collection_archive---------17-----------------------

使用 Python 的 Plot.ly 模块创建 choropleth 的快速演练。

(图片由作者提供)

介绍

随着新冠肺炎病例在美国再次上升,一个有趣和令人兴奋的发展可能被忽略了,那就是每个州对这种性质的病毒的实际威胁程度。当我决定用 Python 的 Plot.ly 绘图库写一篇可视化地理数据的简介时,我很快意识到这是我想做的项目。因此,今天我们将通过 Plot.ly 创建 choropleth 地图并可视化 FIPS 数据,同时了解有关我国整体的有趣信息。与往常一样,数据和笔记本都可以通过以下链接获得:

数据

笔记本

数据读取和清理

幸运的是,对于今天的工作来说,数据已经准备好了——虽然我们也可以查询 API,但我决定使用 CSV 数据,所以让我们使用 Pandas 库中的 read_csv()函数来读取它:

import pandas as pd
import numpy as npimport plotly.express as pxdf = pd.read_csv("data/CDC_SVI.csv")

接下来,我们将使用 head()函数来查看我们的数据帧:

df.head(10)

(图片由作者提供)

那可是好多列啊!

所有这些特征都需要一千年才能完成。幸运的是,使用在获取数据的网站上找到的描述,我们可以删除不需要的列。我最初是通过删除列来实现这一点的,当列数超过 100 时,这很快就变得乏味了——所以我决定构建一个全新的数据框架。

df = pd.DataFrame({"FIPS": df["FIPS"], "POP": df["E_TOTPOP"], 
                  "HOUSEHOLDS": df["E_HH"], "POV": df["E_POV"], "UNEMP": df["E_UNEMP"],
                  "PCI": df["M_PCI"], "DIS": df["E_DISABL"], "UNINS": df["E_UNINSUR"]})

我使用的功能如下:

  • FIPS —给定辖区的联邦 ID。(我们需要这个来绘制 choropleth。)
  • POP——对给定县的总人口的估计。
  • 家庭——给定县的估计家庭数量。
  • POV —该县生活在贫困线以下的估计*民人数。
  • UNEMP——该县失业美国人的估计人数。
  • PCI——估计的人均收入。
  • DIS——辖区内残疾*民的估计人数。
  • unis——该县未投保的美国人的估计人数。

接下来,我得到了这些数据中所有潜在缺失值的总和。幸运的是,这些数据非常干净!实际上没有丢失值:

(图片由作者提供)

特征是氯过多

首先,我们需要可视化我们的美国县是一组 JSON 数据,它将告诉 Plot.ly 对应于正确的 FIPS 的地图区域。我们可以从 Plot.ly Github 获得这一点:

https://raw . githubusercontent . com/plot ly/datasets/master/geo JSON-counties-FIPS . JSON

我们可以获取这些数据,然后用 JSON 甚至 Pandas 读取,或者我们可以简单地使用 URLLib 用 Python 请求数据:

from urllib.request import urlopen
import json
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)

接下来,我将创建一个名为 current_feature 的新变量,它将代表我们要可视化的数据帧中的特征。这只是我为了使事情变得简单一点而加入的一个步骤,因为从这一点开始所要做的就是复制、粘贴和更改值来创建一个新的 choropleth。我们还需要这些数据的最小值和最大值,作为我们 choropleth 色标的参数。

current_feature = "POV"
curr_min = min(df[current_feature])
curr_max = max(df[current_feature])

现在,我们将把我们创建的所有数据插入 px.choropleth():

fig = px.choropleth(df, geojson=counties, locations='FIPS', color=current_feature,
                           color_continuous_scale="reds",
                           range_color=(curr_min, curr_max),
                           scope="usa",
                           labels={current_feature: current_feature}
                          )

接下来,我将使用 fig.update_layout()函数添加一个标题:

fig.update_layout(title_text = "US Poverty by county")

最后,展示新的 choropleth:

fig.show()

(图片由作者提供)

进一步考察,我们说美国在贫困问题上是相当*衡的。也就是说,有一些异常值,如德克萨斯州的哈里斯县。这是休斯顿所在的地方——就传播和住院率而言,这几个月来它实际上已经深陷泥潭。接下来,让我们用同样的方式想象我们的其他特征。

首先,让我们看看人口:

current_feature = "POP"
curr_min = min(df[current_feature])
curr_max = max(df[current_feature])fig = px.choropleth(df, geojson=counties, locations='FIPS', color=current_feature,
                           color_continuous_scale="blues",
                           range_color=(curr_min, curr_max),
                           scope="usa",
                           labels={current_feature: "Population"}
                          )
fig.update_layout(title_text = "US Population by county")
fig.show()

(图片由作者提供)

比较这两种可视化,似乎人口和贫困是相互关联的——至少在某些县是如此。回到德克萨斯州的休斯顿/哈里斯县,情况确实如此。我决定在 GIMP 中的另一张地图上叠加一个不透明版本的地图,我们看到大多数非白色的区域变成了紫色,是红色和蓝色的混合:

(图片由作者提供)

这可能是需要记住的事情,但让我们看看它与家庭的关联程度:

current_feature = "HOUSEHOLDS"
curr_min = min(df[current_feature])
curr_max = max(df[current_feature])
fig = px.choropleth(df, geojson=counties, locations='FIPS', color=current_feature,
                           color_continuous_scale="greens",
                           range_color=(curr_min, curr_max),
                           scope="usa",
                           labels={current_feature: "Population"}
                          )
fig.update_layout(title_text = "US Household Count By County")
fig.show()

(图片由作者提供)

定性地说,我们可以说,人口和共享住房肯定是新冠肺炎感染的一个风险因素。话虽如此,贫困和普遍差异也肯定是一个因素。利用这一点,我们可以构建一个新的探索基础。

特征工程

一个很好的方法是使用我们自己的特征来重新想象这些数据的真实表现。我想调查的第一个指标是共有家庭的人口。为了做到这一点,我认为将人口中的居民数量除以家庭数量是有意义的,它给出了一个大约有多少人一起生活在一个地点的数字。为了设计这个特性,我创建了一个快速 Lambda 函数:

POPPERH = lambda pop, hh: pop / hh

然后将我们传递的列的返回设置为 dataframe 上的一列。

df["POPPERH"] = POPPERH(df["POP"], df["HOUSEHOLDS"])

如果你想了解更多关于使用 Python 的 lambda 来做像这样又酷又简单的事情,我也有一篇文章详细介绍了它是如何工作的:

[## 带 Lambda 的科学 Python

Python Lambda 函数的正确用法:Python 科学编程的最佳语法。

towardsdatascience.com](/scientific-python-with-lambda-b207b1ddfcd1)

现在让我们以同样的方式来想象这个特征:

(图片由作者提供)

有趣的是,通过设计这一特征,我们发现,尽管美国某些地区的人口和贫困率很高,但这两个属性并不一定与生活在一起的大家庭相关。当然,这不能说是客观事实,而很可能是一个粗略的估计;但有趣的是,这可能是一个潜在的风险因素,就像我们今年早些时候在意大利看到的那样。

对于我的最后一个想法,我想通过结合所有这些特征来创建一个任意值,该值可以指示某个区域构成的风险有多高。当然,这个数字将是任意的,并且可以是基本上任何东西的计算结果,只要这些值在具有统计显著性的特征上呈现不同的结果。话虽如此,请允许我向您介绍我的新的任意风险测量系统:

RVRI

  • 呼吸的
  • 病毒
  • 风险
  • 索引

让我们为这个值建立一个公式:

然后,我们将像以前一样创建一个新的 lambda 函数,并将其应用于数据帧:

# (unemp + POV + UNINS / POPPERH) + POV 
RVRI = lambda df: (df["UNEMP"] + df["POV"] + df["UNINS"] / df["POPPERH"]) + df["POP"]df["RVRI"] = RVRI(df)

现在,我们将像之前一样可视化这些数据:

(图片由作者提供)

结论

使用 Plot.ly API,这些数据的可视化变得相对简单明了。Plot.ly 是一个很棒的工具,我以前讲过很多,最*在本文中更具体地讲过:

[## 用于数据分析的 10 个我最喜欢的 Python 库

一些你应该在 Python 中使用的优秀分析包的快速概要。

towardsdatascience.com](/10-of-my-favorite-python-libraries-for-data-analysis-597e09cca026)

我认为我们可以从这些视觉化图像和任意的 RVRI 值中得出一些有趣的见解。对我来说,有趣的是,在没有保险的美国人、贫困和其他被调查的特征方面,看到了最大的风险群体。更有趣的是,这些价值中有多少是相关的,因为更多的人口意味着更多的贫困,而更多的贫困意味着更多的患病风险。

明确地说,这一武断的特征还假设,在*民没有保险、贫困且居住密集的情况下,所讨论的病毒要危险得多。也就是说,对于(美好的)2020 年,这个计量单位当然是适用的。

可视化新西兰的犯罪和 Twitter 数据

原文:https://towardsdatascience.com/visualizing-crime-and-twitter-data-for-new-zealand-e79aa5b759ed?source=collection_archive---------63-----------------------

推特科学

用 R,Shiny,Python 和 QGIS3 开发的可视化 app。

推特和执法

新西兰警方的目标是提高公民参与度,同时提高警务效率。量化公民参与度的方法之一是观察他们的 twitter 习惯,以确定其与该地区犯罪的相关性。

这项工作背后的基本想法是通过分析他们的推文来可视化特定地点的犯罪和该地区人民的情绪。显然,对于像新西兰这样一个人口稀少的国家来说,选择分享地理位置的人太少了,这种分析不可信。

因此,我们使用了 5 年内发送到 https://twitter.com/nzpolice的推文总数以及新西兰各地区的犯罪数据。本文描述了开发可视化的方法。检查短视频,看看它看起来怎么样。

分析犯罪和推特数据

提取推文

我试图获得 Twitter 开发者的帐户,但它被拒绝,声称它不符合他们的条款和条件,这是愚蠢的。因为我既没有做任何商业目的的事情,也没有试图窃取私人数据。这只是一个小实验。所以我用了 TweetScraper ,它实际上工作得很好,尽管它不是没有错误。

我摘录了 2015 年到 2020 年初发给新西兰警方的推文。下面的命令是一个典型的例子。

scrapy crawl TweetScraper -a "query=@nzpolice near:Auckland since:2014-07-01 until:2020-03-31"

这个查询并没有真正的用处,因为在这段时间的 80,000 多条推文中,只有几百个用户允许从奥克兰进行地理定位访问。用它来分析毫无意义。

推文感悟

我在寻找深度学习来进行适当的情感分析,但并不热衷于在这个方向上做更多的研究。这是一个单独的话题,NLP 的深度学习是一个正在增长的领域,但还没有接*与视觉相关的应用。因此,我决定使用非常简单易用的Vader presentation

import re
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
from tqdm import tqdm_notebook
analyser = SentimentIntensityAnalyzer()sentiment = []for i,tweet in enumerate(tqdm_notebook(tweets)):
    string = tweet
    string = re.sub(r'https?:\S+', "", string) #Removes Hyperlink
    string = re.sub('@[^\s]+','',string) #Removes Usernames
    string = re.sub('#[^\s]+','',string) #Removes Hashtags

    score = analyser.polarity_scores(string)
    score.pop('compound')
    sentiment.append(max(score, key=score.get))

警方犯罪数据

警方网站提取受害数据。顺便说一句,他们已经用 Tableau 实现了可视化。

来自新西兰警方网站

数据准备

说到数据准备,没有什么能打败熊猫。因为这是一个已经被警方清理和管理过的结构化数据,所以任务相当简单。下面是代码片段。

代码快照

闪亮的应用仪表板

所以这个练习的真正乐趣就是去做。由于我对这些工具很熟悉,我选择了 R 和 Shiny 来开发可视化。闪亮的仪表板使得制作高质量的交互式可视化效果变得非常容易。

Shiny 将这个过程分解为用户界面和服务器。逻辑驻留在服务器中,而 UI 可以单独管理。很容易在侧面板上设置控制面板。

可视化由两部分组成。第一个是 choropleth。维基百科对 choropleth 的定义是:

choropleth 地图(来自希腊语 χῶρος“区域/地区”和πλῆθος“大众”)是一种主题地图,其中区域按照统计变量的比例进行阴影化或图案化,该统计变量代表每个区域内地理特征的汇总,例如人口密度或人均收入

如上所述,这基本上就是警方网站上显示的内容。

第二个是推特和犯罪的时间序列数据。R 中 Dygraph 的使用使其成为一个交互式的情节。以下是它的快照。

新西兰犯罪和推特活动的时间序列

注意,2019 年 3 月有一个峰值。这是新西兰历史上不幸的一天,克赖斯特彻奇发生了枪战。

新西兰警方的推特账号上还有其他一些推特活动高峰,对此进行调查会很有趣。总的来说,我看不出推特活动和犯罪活动之间有任何联系。虽然我在刑事案件中看到了某种循环。我想知道它是否比实地的实际事件更具行政性。

使用 QGIS3 创建矢量文件

最有趣的部分是在 QGIS 中,多边形被准备好放在地图上。很难确定一个载体形状文件,其中包含的区域与警方用于管理的区域相同。更重要的是有相同的名字。例如,警察数据集将奥克兰称为奥克兰市。

网上有许多矢量文件。例如链接

QGIS 使得根据需要合并不同区域和重命名要素变得非常容易。它肯定不如商业版的 ArcGIS,但进步很快。我已经在不同的项目中使用它两年了,我已经看到新版本有了很大的改进。

QGIS3 在运行

这是最终应用程序的样子。请注意,不同地区的犯罪数量差异很大。因此,颜色编码很困难。因此,使用对数标度。

此外,滑块会导致不必要的计算,因为滑块中的每个增量都会重新计算贴图。应该使用更好的输入部件。

最终可视化的快照

后续步骤

这只是一个简单的可视化,并没有提供任何尚未知晓或预期的见解。这些是我在扩展这项基础工作时可能会用到的一些想法。首先,我收集了 Twitter 数据。很多都是对一系列事件的反应。

了解人们在什么水*上参与这些活动并量化他们的情感投入将会很好。目前,情绪只是积极,消极和中性的。这将是有用的分配学位,这是一个极其困难的问题。

此外,通过给犯罪添加更多类别来使这种可视化更有用也是不错的。虽然不可能确定地理位置,但量化人们对这些到来的参与度会很好。举例来说,它可以让我们了解与金融犯罪相比,人们对毒品的担忧程度。

https://github.com/deepakkarunakaran/nzpolice找到代码

用 RoughViz.js 可视化数据

原文:https://towardsdatascience.com/visualizing-data-with-roughviz-js-77b8f96331e9?source=collection_archive---------57-----------------------

使用 RoughViz.js 让您的图表更有趣、更具互动性

在本教程中,我们将深入到 RoughViz.js 来可视化数据。有了它,你就能画出具有草图视觉效果的图形。对于本教程,我们将使用disease . shAPI来可视化各个国家的人口和新冠肺炎数据。我选择这个库的原因是对如何可视化数据有一个更开放的想法。随着每一次数据可视化,我们用不同的艺术风格讲述一个故事可以极大地改变人们对它的看法。对我来说,这也是一个实验,看看使用 RoughViz.js 这样的工具的数据可视化是否可以因为本库使用的视觉效果而使看起来枯燥的主题变得更有趣。****

RoughViz.js 示例图

设置我们的开发人员环境

对于本教程,我们将使用 React 创建一个项目。建立 react 项目最简单的方法是通过创建 React 应用。如果您还没有安装 create react 应用程序,请检查他们的文档以准备好工具开始使用。我们将使用以下命令创建并运行项目:

**npx create-react-app rough-vizcd rough-viznpm start**

文件夹的名字可以是你喜欢的任何名字,但这是我在本教程中选择的。执行npm **start**应该显示一个带有旋转 react 标志的运行页面。现在让我们安装 RoughViz.js,这样我们就可以在我们的项目中使用它了。因为我们使用 react,所以我们将安装 react 包装器。

**npm install react-roughviz --save**

我们现在可以开始在app.js中导入库了。从起始项目中移除所有代码,并添加导入。你的app.js应该是这样的:

**import React from 'react';
import { Bar, StackedBar, Scatter } from 'react-roughviz'
import './App.css';function App() {return (<div className="App">
      <header className="App-header">

      </header>
    </div>
  );
}export default App;**

创建我们的第一个条形图

我们现在可以开始 bij 建立我们的第一个图表。现在,我们将使用一个硬编码的数组来向您展示 RoughViz.js 的功能。不要担心,在我们设置完第一个图表后,我们将使用来自 API 的数据。对于第一张图表,我们将使用条形图。使用下面的代码,你应该能够看到一个有 4 个条的条形图。

**<Bar
    data={{
        labels: ['Appels',
            'Bananas',
            'Strawberries',
            'Blueberries'    
              values: [10, 5, 8, 3],
            }}
    color="pink"
    title="Top 4 sold fruits"
    stroke='coral'
    axisFontSize={"1.5rem"}
    tooltipFontSize={"2rem"}
    roughness={5}
    labelFontSize={'3rem'}
    strokeWidth={2}
    fillStyle="hachure"
    fillWeight={1}
    margin={{ top: 70, right: 50, bottom: 80, left: 150 }}
    padding={0.2}
    height={700}
    width={window.innerWidth - 100}
    font={1}
/>**

图 1:条形图销售的前 4 种水果

我添加了一些额外的可选属性,如fillWeightaxisFontSizeroughnesspadding。我添加了这些属性,以便您可以随意使用。更改这些值,并查看它对图形的影响。增加roughnessfillWeight特别有趣,因为它允许我们将图表从图 1 变成类似下面的图 2。

图 2:粗糙度和填充重量增加的相同条形图

用 API 数据填充图表

在这个例子中,我们将使用 Disease.sh API 来显示人口最多的 10 个国家。让我们首先设置 API 调用,以便用来获取我们想要的数据。首先导入useStateuseEffect,因为我们将使用它们来存储我们的数据。

**import React, { **useState, useEffect** } from 'react';**

接下来用useState初始化变量以存储数据。我们还需要为人口和姓名初始化一个单独的数组,因为我们需要两个数组,一个用于标签,另一个用于人口字段。

**const [data, setData] = useState([]);let population = [];let names = [];**

接下来,我们将创建一个fetchData函数,该函数将调用 API 来检索数据。检索之后,我们可以将这个响应存储在上面初始化的setData中。尝试控制台记录数据,看看是否能从 API 获得数据输出。如果一切就绪,我们可以开始过滤数据,只显示人口最多的前 10 个国家。我们将使用 ES6 中的过滤功能来只检索这些国家,并将它们从最高到最低排序。

**useEffect(() => {
    fetchData();
  }, [])const fetchData = () => {
    fetch(`[https://disease.sh/v2/countries`](https://disease.sh/v2/countries`))
      .then(response => response.json())
      .then(json => setData(json))
  }**

完成后,我们将把它存储在。将函数映射到我们上面初始化的人口变量中。最后,我们还将填充上面的 names 数组,以在图表的标签字段中显示每个国家的名称。

**let dataCut = data.filter(*a* => (*a*.population > 106932753) && data.sort((*a*, *b*) => *b*.population - *a*.population));population = dataCut.map((*a*) => *a*.population);
names = dataCut.map((*a*) => *a*.country);**

我们现在可以用新检索到的数据填充图表。图形的代码看起来应该是一样的,唯一不同的是数据属性。

**<Bar
    *data*={{
     labels: names,
     values: population
    }}
    color="pink"
    title="Top 4 sold fruits"
    stroke='coral'
    axisFontSize={"1.5rem"}
    tooltipFontSize={"2rem"}
    roughness={5}
    labelFontSize={'3rem'}
    strokeWidth={2}
    fillStyle="hachure"
    fillWeight={1}
    margin={{ top: 70, right: 50, bottom: 80, left: 150 }}
    padding={0.2}
    height={700}
    width={window.innerWidth - 100}
    font={1}
/>**

图 3:拥有 API 数据的前 10 个人口大国

如果操作正确,您的图表应该如图 3 所示。

显示前 10 个活动新冠肺炎案例的散点图

现在我们可以尝试另一个图表。散点图的代码大致相同。这里最重要的区别是,我们将数据存储在 x 和 y 属性中,而不是标签和值中。我们仍将使用人口数组,但添加了一个活动数组来显示每个国家有多少活动病例。接下来,我们还应该设置地图上显示的每个圆圈的radius。我把我的设置为 40,但你可以设置为任何你想要的。接下来,我们还添加了一个colors属性来添加颜色数组。这是用来确定什么颜色的一个圆的基础上的价值

**let population = [];
  let names = [];
 ** let active = [];** useEffect(() => {
    fetchData();
  }, [])
const fetchData = () => {
    fetch(`[https://disease.sh/v2/countries`](https://disease.sh/v2/countries`))
      .then(response => response.json())
      .then(json => setData(json))
  }let dataCut = data.filter(a => (a.population > 106932753) &&  data.sort((a, b) => b.population - a.population));population = dataCut.map((a) => a.population);**active = dataCut.map((a) => a.active);**<Scatter
    data={{
        x: population,
        y: **active**
    }}
    title='Population country versus active covid-19 cases'
    titleFontSize={'2rem'}
    roughness={2}
    bowing={true}
    radius={40}
    xLabel={'Population'}
    yLabel={'active covid-19 cases'}
    labelFontSize={'2rem'}
    fillWeight={8}
    axisRoughness={0}
    font={0}
    height={700}
    tooltipFontSize={'1.5rem'}
    colors={['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99',  '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928']}
    width={window.innerWidth}
    margin={{ top: 50, right: 50, bottom: 170, left: 300 }}
    curbZero={true}**

如果实现正确,您的图表应该如图 4 所示。

图 4:人口国家与活跃的新冠肺炎病例

太好了,你现在已经用真实的 API 数据做出了两个很棒的图表。RoughViz.js 有更多的图形,如折线图、堆积条形图和圆形图。在图 5 中是另一个例子,我用同样的新冠肺炎数据制作了散点图。

图 5:每个国家的死亡/康复/活跃病例

如果你想了解他们的图书馆,你可以查看他们的 GitHub 页面。他们有各种代码甚至 React、Vue 和 Python 的包装器的例子。我希望你喜欢这个教程,并学到一些新的东西。编码快乐!

本文使用的资源…

用 Python 可视化决策树(Scikit-learn,Graphviz,Matplotlib)

原文:https://towardsdatascience.com/visualizing-decision-trees-with-python-scikit-learn-graphviz-matplotlib-1c50b4aa68dc?source=collection_archive---------0-----------------------

了解如何使用 matplotlib 和 Graphviz 可视化决策树

图片来自我的理解分类决策树(Python)教程

由于各种原因,决策树是一种流行的监督学习方法。决策树的好处包括它们可以用于回归和分类,它们不需要特征缩放,并且它们相对容易解释,因为你可以可视化决策树。这不仅是理解您的模型的一种强有力的方式,而且也是传达您的模型如何工作的一种强有力的方式。因此,了解如何基于您的模型进行可视化会有所帮助。

本教程涵盖:

  • 如何使用 Scikit-Learn 拟合决策树模型
  • 如何使用 Matplotlib 可视化决策树
  • 如何使用 Graphviz 可视化决策树(Graphviz 是什么,如何在 Mac 和 Windows 上安装,如何使用它可视化决策树)
  • 如何可视化袋装树或随机森林中的单个决策树

和往常一样,本教程中使用的代码可以在我的 GitHub 上获得。就这样,让我们开始吧!

如何使用 Scikit-Learn 拟合决策树模型

为了可视化决策树,我们首先需要使用 scikit-learn 来拟合决策树模型。如果这一节不清楚,我鼓励你阅读我的理解分类决策树(Python)教程,因为我会详细介绍决策树如何工作以及如何使用它们。

导入库

我们将在本教程的这一部分使用以下导入语句。

import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.datasets import load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import pandas as pd
import numpy as np
from sklearn import tree

加载数据集

Iris 数据集是 scikit-learn 附带的数据集之一,不需要从外部网站下载任何文件。下面的代码加载 iris 数据集。

import pandas as pd
from sklearn.datasets import load_iris
data = load_iris()
df = pd.DataFrame(data.data, columns=data.feature_names)
df['target'] = data.target

原创熊猫 df(特色+目标)

将数据分为训练集和测试集

下面的代码执行训练测试分割,将 75%的数据放入训练集,25%的数据放入测试集。

X_train, X_test, Y_train, Y_test = train_test_split(df[data.feature_names], df['target'], random_state=0)

图像中的颜色表示数据帧 df 中的数据用于特定训练测试分割的哪个变量(X_train,X_test,Y_train,Y_test)。迈克尔·加拉尼克的图片。

sci kit-学习 4 步建模模式

# **Step 1:** Import the model you want to use
# This was already imported earlier in the notebook so commenting out
#from sklearn.tree import DecisionTreeClassifier**# Step 2:** Make an instance of the Model
clf = DecisionTreeClassifier(max_depth = 2, 
                             random_state = 0)**# Step 3:** Train the model on the data
clf.fit(X_train, Y_train)**# Step 4:** Predict labels of unseen (test) data
# Not doing this step in the tutorial
# clf.predict(X_test)

如何使用 Matplotlib 可视化决策树

自 scikit-learn 版本 21.0(大约 2019 年 5 月)起,现在可以使用 scikit-learn 的[**tree.plot_tree**](https://scikit-learn.org/stable/modules/generated/sklearn.tree.plot_tree.html#sklearn.tree.plot_tree)用 matplotlib 绘制决策树,而不依赖于dot库,后者是一个难以安装的依赖项,我们将在稍后的博客文章中介绍。

下面的代码使用 scikit-learn 绘制了一个决策树。

tree.plot_tree(clf);

这还不是最容易解释的树。

除了添加允许您保存图像的代码之外,下面的代码试图通过添加特性和类名(以及设置filled = True)来使决策树更容易理解。

fn=['sepal length (cm)','sepal width (cm)','petal length (cm)','petal width (cm)']
cn=['setosa', 'versicolor', 'virginica']fig, axes = plt.subplots(nrows = 1,ncols = 1,figsize = (4,4), dpi=300)tree.plot_tree(clf,
               feature_names = fn, 
               class_names=cn,
               filled = True);fig.savefig('imagename.png')

如何使用 Graphviz 可视化决策树

通过 Graphviz 生成的决策树。请注意,我使用文本编辑器编辑了文件,使文本颜色与叶/终端节点或决策节点相对应。

Graphviz是开源的图形可视化软件。图形可视化是一种将结构信息表示为抽象图形和网络的方式。在数据科学中,Graphviz的一个用途是可视化决策树。我应该注意的是,在介绍完 Matplotlib 之后,我之所以要回顾 Graphviz,是因为让它工作起来可能很困难。这个过程的第一部分包括创建一个点文件。点文件是决策树的 Graphviz 表示。问题是使用 Graphviz 将点文件转换成图像文件(png、jpg 等)可能很困难。有几种方法可以做到这一点,包括:通过 Anaconda 安装python-graphviz,通过 Homebrew (Mac)安装 Graphviz,从官方网站(Windows)安装 Graphviz 可执行文件,以及使用在线转换器将您的点文件内容转换成图像。

创建点文件通常不是问题。将点文件转换成 png 文件可能很困难。

将模型导出到点文件

代码下面的代码将在任何操作系统上工作,因为 python 生成了点文件并将其导出为名为tree.dot的文件。

tree.export_graphviz(clf,
                     out_file="tree.dot",
                     feature_names = fn, 
                     class_names=cn,
                     filled = True)

安装和使用 Graphviz

将点文件转换成图像文件(png、jpg 等)通常需要安装 Graphviz,这取决于您的操作系统和许多其他东西。本节的目标是帮助人们尝试并解决出现以下错误的常见问题。dot: command not found

dot: command not found

如何通过 Anaconda 在 Mac 上安装使用

为了能够通过这种方法在你的 Mac 上安装 Graphviz,你首先需要安装 Anaconda(如果你没有安装 Anaconda,你可以在这里学习如何安装它)。

打开一个终端。你可以点击屏幕右上角的聚光灯放大镜,输入终端,然后点击终端图标。

键入下面的命令来安装 Graphviz。

conda install python-graphviz

之后,你应该可以使用下面的dot命令将点文件转换成 png 文件。

dot -Tpng tree.dot -o tree.png

如何通过家酿在 Mac 上安装使用

如果你没有 Anaconda 或者只是想要另一种在 Mac 上安装 Graphviz 的方式,你可以使用自制软件。我以前写过一篇关于如何安装家酿软件并使用它将点文件转换成图像文件的文章这里(参见教程的家酿软件帮助可视化决策树部分)。

如何通过 Anaconda 在 Windows 上安装使用

这是我在 Windows 上更喜欢的方法。为了能够通过这种方法在您的 Windows 上安装 Graphviz,您首先需要安装 Anaconda(如果您没有安装 Anaconda,您可以在这里了解如何安装它)。

打开终端/命令提示符,输入下面的命令来安装 Graphviz。

conda install python-graphviz

之后,您应该能够使用下面的dot命令将点文件转换成 png 文件。

dot -Tpng tree.dot -o tree.png

通过 conda 安装 Graphviz。这应该可以解决“点”不被识别为内部或外部命令、可操作程序或批处理文件的问题。

如何通过 Graphviz 可执行文件在 Windows 上安装和使用

如果你没有 Anaconda 或者只是想要在你的 Windows 上安装 Graphviz 的另一种方式,你可以使用下面的链接下载并安装它

如果您不熟悉改变 PATH 变量,而想在命令行上使用 dot,我鼓励您使用其他方法。有许多 Stackoverflow 问题是基于这个特殊的问题

如何使用在线转换器来可视化你的决策树

如果其他方法都失败了,或者你只是不想安装任何东西,你可以使用在线转换器。

在下图中,我用 Sublime Text 打开了文件(尽管有许多不同的程序可以打开/读取点文件),并复制了文件的内容。

复制点文件的内容

在下图中,我将点文件中的内容粘贴到在线转换器的左侧。然后,您可以选择想要的格式,然后将图像保存在屏幕右侧。

将可视化保存到计算机

请记住,有其他在线转换器可以帮助完成同样的任务。

如何可视化袋装树或随机森林中的单个决策树

关于袋装树木的免费预览视频,来自机器学习与 Scikit-Learn 课程

决策树的一个弱点是它们往往没有最好的预测准确性。这部分是因为高方差,这意味着训练数据中的不同分裂可以导致非常不同的树。上面的视频涵盖了袋装树,这是一个集合模型。这意味着使用多个学习算法来获得比单独从任何组成学习算法获得的预测性能更好的预测性能。在这种情况下,许多树相互保护,避免各自的错误。有趣的是,上面视频中的缩略图可能是袋装树或随机森林的示意图(另一个集合模型)。袋装树和随机森林模型如何工作的区别是另一个博客的主题,但是值得注意的是,对于这两个模型,我们都生长了 N 棵树,其中 N 是用户指定的决策树的数量。因此,在你拟合一个模型之后,看看组成你的模型的各个决策树会很好。

使用 Scikit-Learn 拟合随机森林模型

为了可视化单个决策树,我们首先需要使用 scikit-learn 拟合一个袋装树或随机森林模型(下面的代码适合一个随机森林模型)。

# Load the Breast Cancer (Diagnostic) Dataset
data = load_breast_cancer()
df = pd.DataFrame(data.data, columns=data.feature_names)
df['target'] = data.target# Arrange Data into Features Matrix and Target Vector
X = df.loc[:, df.columns != 'target']
y = df.loc[:, 'target'].values# Split the data into training and testing sets
X_train, X_test, Y_train, Y_test = train_test_split(X, y, random_state=0)# Random Forests in `scikit-learn` (with N = 100)
rf = RandomForestClassifier(n_estimators=100,
                            random_state=0)
rf.fit(X_train, Y_train)

可视化您的评估人员

现在,您可以从拟合的模型中查看所有单独的树。在本节中,我将使用 matplotlib 可视化所有决策树。

rf.estimators_

在这个例子中,注意我们有 100 个评估者。

现在,您可以将单棵树可视化。下面的代码可视化了第一个决策树。

fn=data.feature_names
cn=data.target_names
fig, axes = plt.subplots(nrows = 1,ncols = 1,figsize = (4,4), dpi=800)
tree.plot_tree(rf.estimators_[0],
               feature_names = fn, 
               class_names=cn,
               filled = True);
fig.savefig('rf_individualtree.png')

请注意,随机森林和袋装树木中的单个树木正在长得更深

您可以尝试使用 matplotlib 子图来可视化尽可能多的树。下面的代码可视化了前 5 个决策树。我个人不喜欢这种方法,因为它更难阅读。

# This may not the best way to view each estimator as it is smallfn=data.feature_names
cn=data.target_names
fig, axes = plt.subplots(nrows = 1,ncols = 5,figsize = (10,2), dpi=3000)for index in range(0, 5):
    tree.plot_tree(rf.estimators_[index],
                   feature_names = fn, 
                   class_names=cn,
                   filled = True,
                   ax = axes[index]);

    axes[index].set_title('Estimator: ' + str(index), fontsize = 11)fig.savefig('rf_5trees.png')

为每个决策树(评估者)创建图像

请记住,如果出于某种原因,您需要所有评估者(决策树)的图像,您可以使用 my GitHub 上的代码来实现。如果你只是想看看随机森林模型的 100 个估值器中的每一个都适合本教程,而不需要运行代码,你可以看看下面的视频。

结束语

本教程讲述了如何使用 Graphviz 和 Matplotlib 可视化决策树。请注意,使用 Matplotlib 可视化决策树的方法是一种较新的方法,因此将来可能会有所改变或改进。Graphviz 目前更加灵活,因为你可以随时修改你的点文件,使它们在视觉上更具吸引力,就像我使用点语言所做的那样,甚至只是改变你的决策树的方向。我们没有谈到的一件事是如何使用 dtreeviz ,这是另一个可以可视化决策树的库。上面有一个很棒的帖子这里

图片来自 dtreeviz 库制作。

我的下一个机器学习教程介绍了如何加速 Scikit-Learn 模型训练。如果您对本教程有任何问题或想法,请在下面的评论中或通过 Twitter 联系我们。

使用 ClinicalTrials.gov 可视化疾病关系

原文:https://towardsdatascience.com/visualizing-disease-relationships-using-clinicaltrials-gov-8ab0c9322d63?source=collection_archive---------37-----------------------

我喜欢可视化数据。如果要做到这一点,我必须经历一个叫做“生物医学文本处理”的地狱循环,那感觉就更好了。这里的情况也是如此。

众所周知,疾病之间的遗传和症状相似性允许将已知药物重新用于新的适应症。但是,如果相似性也可以从用于计划和进行临床试验的专家知识中发现呢?逻辑很简单: 如果在相同的两种疾病上试验了大量不同的药物,就说明这些疾病之间有很强的生物学联系。 让我们看看是不是真的。

我决定利用 ClinicalTrials.gov 的研究数据来可视化不同类型癌症之间的关系。后者有许多关于公共和私人支持的临床研究的有用信息,每个介入研究记录都包含参与者收到的适应症和干预措施(例如,药物或设备)。

如果我只需要从 ClinicalTrials.gov 下载数据,并根据普通药物将疾病配对,这本来是一件容易的事情,但问题是同一生物医学概念在数据库中可以有许多不同的名称。例如,乳腺癌可以写成“乳房肿瘤”或“乳房恶性肿瘤”。不幸的是,毒品也是如此。

为了解决这个问题,我使用了一个名为科学空间的 NLP 模型来查找临床试验记录中的疾病和药物术语,并从 UMLS 字典中获得它们的通用名称。在建立了癌症类型对并计算了每对上测试的常见药物的数量后,我用 Gephi 可视化了网络。

这里,节点代表癌症的类型,节点的大小与针对该类型癌症测试的药物数量成比例。节点之间的边表示在该边所连接的两种癌症上测试的药物。边缘越厚,颜色越浅,对这两种疾病进行测试的药物数量就越多。

有些关系非常明显,如下图所示。

但是该图也揭示了具有不同定位的癌症之间的联系。下面的例子表明,同样的药物经常在前列腺癌和乳腺癌上进行试验(多西他赛,仅举一例)。

对疾病关系的深入了解可以帮助科学家发现新的治疗方案。这就是为什么使用 NLP 技术和不同类型的可视化来充分利用历史临床研究数据是有意义的。

如果你有任何问题或者想要一个 gephi 文件来检查整个图表,请告诉我。

可视化电子商务调查数据

原文:https://towardsdatascience.com/visualizing-e-commerce-survey-data-9771bfb3f694?source=collection_archive---------52-----------------------

使用 Python 和 Pandas 从 SurveyMonkey 数据进行数据辩论和可视化

卢克·切瑟在 Unsplash 上的照片

我和 Dimitri Mahayana 博士在概率统计课上有一个期末项目,是关于分析印度尼西亚的电子商务调查数据的。每个学生从一些回答者那里收集数据,做出大约 1600 个回答。这项调查由 50 多个问题组成。有些问题是关于网上购物的个人数据和个人行为。

在这篇文章中,我使用的是 2019 年的数据。我将向您展示数据争论和可视化如何让我们对数据有更多的了解。我们将查看个人数据、行为数据以及它们之间的组合,以获取更多信息。

数据集解释

该调查使用 SurveyMonkey 进行数据收集,这是一个流行的调查*台。然而,SurveyMonkey 的原始数据变得非常混乱,因为有许多未命名的列和 NaN 值。因此,清理和分析数据需要一些时间。如下图所示,问题在列名中,选项在第一行。幸运的是,我们可以使用 Pandas,它对于数据争论来说是非常通用的。

来自 SurveyMonkey 的原始数据(图片由作者提供)

重新组织数据

数据争论不是一件容易的事情,尤其是当你处理大量数据的时候。也就是说,清理数据是令人疲惫的,因为你必须做一个迭代的过程,直到你得到你需要的。所以,我把我的数据重新整理成一个问题列表,我可以单独访问。例如,我可以键入“Q32”来访问第 32 个问题。这是数据重新排列后的样子。(你可以在我的 Github 上看到我的代码)

预处理数据(图片由作者提供)

您可以看到问题和子问题是如何移动到多索引列中的,所有答案都在它下面的行中。此外,您可能已经注意到,仍然有很多 NaN 值,因为 SurveyMonkey 将答案选项视为数字。假设有 2 个选项,A 和 B,当回答者选择 A 时,SurveyMonkey 用 1 填充 A 列,用 NaN 填充 B 列。我们将在以后可视化数据时处理这个问题。

因为这个调查中有很多问题,我只选取其中的一部分进行分析。想看看性别,职业,月收入等一些个人信息。除此之外,我将分析他们的行为,如首选网上购物*台,购买偏好等。之后,我将结合一些特性来获得关于数据的更多见解。

个人资料

首先,我想形象化一下按性别划分的回答者人数。下面的饼状图显示了受访者的性别分布。女性人数比男性略高约 8%。请注意,当我们可视化数据时,我们计算每一列的值,并忽略所有 NaN 值。

受访者的性别(图片由作者提供)

接下来,我们将职业分布可视化,以了解受访者的背景。下面的饼图显示,超过三分之二的受访者是学生。第二高的数字是私人雇员,然后是家庭主妇和其他职业。

受访者的职业(图片由作者提供)

最后,我们来看看他们的月收入,以印度尼西亚卢比计算。根据这个问题,我们有四个收入类别,即每月 200 万以下、200 万至 500 万之间、500 万至 1000 万以及 1000 万以上。柱状图表明,* 1000 名受访者的月收入低于 200 万卢比(相当于 135 美元左右)。

受访者的月收入范围(图片由作者提供)

行为数据

现在,我们继续研究行为数据。第一个是受访者用于网上购物的*台分布。柱状图表明他们中的大多数人使用 marketplace 进行网上购物。印度尼西亚有几个市场,例如 Tokopedia、Shopee 和 Bukalapak。接下来,在线交付(如 Gojek 和 Grab)是第二高的数字,有超过 800 名受访者。Instagram 的比例也很高,大约 25%(1600 人中有 400 人)的受访者使用它进行在线购物。

受访者使用的网购*台(图片由作者提供)

正如我们所知,他们中的大多数人使用 marketplace 进行在线购物,我想更深入地了解在线商店或 marketplace 的分布。下面的柱状图代表了有多少人选择不同的在线商店作为他们的最爱。大多数人选择 Gojek、Shopee 和 Tokopedia 作为他们最喜欢的三大在线*台,而在印度尼西亚,没有多少人使用 Elevenia、Blanja 和 Matahari Mall。

最喜欢的购物*台(图片由作者提供)

根据我的经验,我用 Gojek 主要是为了食物,用 Tokopedia 是为了其他东西。所以,我认为看看人们在购买某些物品时的偏好可能会很有趣。下面的柱状图表明了在购买某些商品时,从电脑到电话信用卡,有多少人更喜欢某种在线方式。对于每个类别,人们可以通过市场、官方在线商店、在线交付和社交媒体购买商品。

基于商品的首选网上购物方式(图片由作者提供)

总的来说,市场似乎是购买物品时最受欢迎的方式。大多数人在购买化妆品和美容、时尚、爱好、电子产品和电话信用时都会使用市场。然而,大约 75%的人在购买食品和饮料时选择在线交付。此外,在购买电脑和手机时,官方网上商店是最受欢迎的方式。就购买食品杂货而言,网上交货和市场似乎是最受欢迎的网上购物方式。

结合个人数据和行为数据

我们不仅可以查看每个特征,还可以组合两个(或更多)特征来获得更多的数据信息。下面的堆积条形图显示了各*台的男女比例。在 Instagram、Line 和 Whatsapp 上,女性的比例明显更高。相比之下,其他*台的男女数量并没有明显差异。

基于性别的首选*台(图片由作者提供)

最后但同样重要的是,我试图根据月收入将三个最受欢迎的在线商店结合起来。堆积条形图显示,月收入低于 200 万卢比的人在所有*台中占主导地位,因为大约 60%的受访者属于这一类别。尽管如此,我们仍然可以观察到每个*台的收入分布大致相同。我们可以有把握地说,基于这一数据,月收入不会严重影响购物*台的偏好。

基于商品的首选网上购物方式(图片由作者提供)

结论

数据争论和可视化并不总是一件有趣的事情,但它可以给我们更多关于数据的见解。在清理和可视化之后,我们有了一些关于个人和行为数据的信息。除此之外,组合要素还可以增加对数据的了解。

你可以在这里找到我这个项目的代码。

关于作者

Alif Ilham Madani 是一名有抱负的数据科学和机器学习爱好者,他热衷于从他人那里获得洞察力。他在印尼最顶尖的大学之一 万隆技术学院 主修电子工程。

如果你有任何要讨论的话题,你可以通过 LinkedIn 和 Twitter @_alifim 联系 Alif。

用 Hopfield 网络可视化情景记忆

原文:https://towardsdatascience.com/visualizing-episodic-memory-with-hopfield-network-a6e8bde967cb?source=collection_archive---------62-----------------------

一个可以学习模式的网络,给定部分学习的模式,该网络可以恢复整个学习的模式。

2018 年,我写了一篇文章描述神经模型及其与人工神经网络的关系。我参考的《T2》一书中的一章解释说,当一组神经元一起工作并形成网络时,某些特性可能会出现。书中有很多理论,但更吸引我的是一个可以模拟人类记忆如何工作的网络,叫做 Hopfield 网络【Hopfield,J.J. 1982】。

Hopfield 网络的前身是受限玻尔兹曼机(RBM)和多层感知器(MLP)。这是一个基于能量的自动联想记忆、循环和生物启发网络

  • 它是一个基于能量的网络,因为它使用能量函数并最小化能量来训练权值。想象一个神经元被一种外部脉冲能量触发,这种能量在整个网络中传播,激发所有其他连接的神经元。
  • 它是一个自联想记忆网络,意思是训练好的网络可以在只给部分信息作为输入的情况下恢复全部记忆信息。例如,假设我们有一个由 10 个相互连接的神经元组成的网络。当我们用所谓的输入一个状态触发 8 个神经元时,网络会来回反应和计算,直到所有的神经元和神经元突触(神经元之间的连接)稳定。假设这个稳定状态叫做 S,但现在实际上网络被隐含地记忆了输入状态。之后,当我们触发一些神经元(与之前被触发的神经元相同,但不是全部,少于 8 个)时,网络将再次做出反应,直到所有神经元都稳定下来。而稳定的条件是先前的 8 个神经元都处于输入状态
  • 这是一个循环网络,意思是网络输出回到网络输入,网络形成一个有向图。在这种情况下,有向循环图。
  • 由于海马 CA3 区的结构形成了与 Hopfield 网络相似的结构和行为,这是一个受生物启发的网络。

行为研究表明,CA3 支持空间快速一次性学习、以空间为成分的任意联想学习、模式完成、空间短期记忆和通过连续项目之间形成的联想进行的序列学习。[ Cutsuridis,V. &温内克斯,T 。2006]

与其他使用反向传播来学习权重的神经网络不同,Hopfield 网络使用 Hebb 的学习或 Hebbian 学习 Hebb,D.O. 1949 ,这也是一种生物启发的学习。希伯莱学习背后的想法是,如果两端的神经元积极相关,两个神经元(突触)之间的连接将会更强。在 Hopfield 网络中,神经元只有两种状态,激活和非激活。有时人们用 1 来量化激活状态,用 0 来量化非激活状态。有时他们也用 1 来量化激活状态,用-1 来量化非激活状态。

2019 年底,我抽出时间试图用 Hopfield 网络模拟和可视化记忆回忆是如何工作的。我做的模拟和可视化是一个网络应用程序,所以它是可访问的,所有人都可以尝试。关于 Hopfield 网络有很多解释,这是多余的(或者不是?)如果我在这里也解释一下。相反,我将开放这个 web 应用程序的源代码,让人们探索并获得实现的想法。这里的链接是这里的

hopfield 网络可视化模拟 web app 截图

上图显示了用于可视化 Hopfield 网络的 web 应用程序的屏幕截图。有两个部分,TrainPredict。您可以在每个网格上绘制一些图案(最多 3 个),也可以选择提供的预定义图案。图案绘制完成后,可以点击Train 3 Patterns按钮。完成后,网络已经记住了上面提供的 3 种模式。您可以通过在Predict网格中绘制(不完整的)模式,来尝试形象化 Hopfield 网络如何回忆一个模式。下面是我们玩可视化时的 GIF。

Hopfield 网络如何工作的可视化

这篇文章和模拟希望启发一些仍然对 Hopfield 网络如何工作感到困惑的人。对于那些通过视觉更好地学习的人来说,这可能也是有用的。

除了 Hopfield Network,我还创建了一个 web 应用程序来模拟 Q-learning 是如何工作的。q 学习是强化学习算法的一种。你可以在这里查看。

可视化高斯消去法

原文:https://towardsdatascience.com/visualizing-gaussian-elimination-6cb6fdb59475?source=collection_archive---------50-----------------------

行列式与矩阵中向量所跨越的*行六面体的体积有关,让我们来看看是怎么回事。

最*,我被要求制作一个视频,演示如何将一个矩阵转换成减少行梯队形式(RREF)揭示行列式。我知道这听起来难以置信,但它确实发生了。这篇文章的目的不是描述行列式的所有性质,也不是解释高斯消去法是如何工作的,有大量的其他资源,而是展示矩阵的几何如何与行列式相关,以及将矩阵转换成 RREF 揭示了几何对象的体积。首先,让我们考虑如何从几何角度来看矩阵。在整个讨论中,我将使用矩阵:

查看该矩阵的一种方式是将它看作行向量的集合,如图 1 所示。

该矩阵与图 2 中的*行四边形相关,其中行列式的绝对值是其体积。我们最终会证实这一点,但现在请相信我。

我们取行列式ad--BC= 1。这很好,你们大多数人已经知道如何计算一个行列式了,但是对矩阵进行行归约是如何实现的呢?当我们缩小矩阵时,我们开始将值集中在矩阵的对角线上。这基本上相当于将矢量与笛卡尔轴对齐。为了看到这一点,让我们朝着矩阵的简化行形式的方向前进一步。让我们从 A_2 中取. 1 × A_1 几次,看看会发生什么。

我们可以看到,底部向量逐渐与规范的 x,y 轴对齐!如果我们做同样的事情,但是从 A _ 1 中减去 A_2,我们将对齐另一个向量。这意味着查看缩减的行梯队形式的另一种方式是作为原始矩阵的轴对齐版本。这一点可以从下面的视频中看出。

高斯消去法的可视化

现在,我们可以很容易地计算这个缩小的*行四边形的体积,因为高度和底部尺寸只是对角线的条目,它们都是 1,意味着体积是 1。

为了验证原始*行四边形的体积是 1,我们可以使用标准的体积=底×高计算方法。在开始走这条路之前,我们需要考虑我们的基础和高度。我们将我们的底||A_1||,我们可以使用三角公式 sin (θ) =对边/斜边和点积 a⋅b = | | a | | | b | |cos(θ)来找到我们的高度。在这种情况下,我们的对立面是||A_2||现在我们有了计算体积所需的一切。

实际上是 1!这里我们已经验证了所有矩阵的行列式和体积都是相同的。我们还可以看到减少一个矩阵是如何改变基础向量的几何形状,使其与轴对齐,从而更容易解释。如果你想在更高的维度上看到同样的过程,我为 3× 3 矩阵制作了另一个视频。

**

3×3 矩阵上高斯消去法的可视化

最初发表于【http://www.nbertagnolli.com】

用 Python 可视化地理空间数据

原文:https://towardsdatascience.com/visualizing-geospatial-data-in-python-e070374fe621?source=collection_archive---------0-----------------------

用于在自定义地图上可视化数据的开源工具和技术

在全球疫情中,许多人花了大量时间查看可视化数据的地图。重要数据。从事数据科学工作的人可能会发现使用地理空间数据的需求越来越多,尤其是在可视化方面。越来越需要了解有关地理区域的指标,分析供应链,制定考虑当地条件和规则的计划等。

本文展示了如何使用 Python 中两个流行的地理空间库:

  • geopandas :扩展 pandas 以允许对几何类型进行空间操作
  • geoplot :高级地理空间绘图库

第二个库特别有用,因为它建立在其他几个流行的地理空间库之上,简化了通常需要的编码。这些工具包括: cartopy ,它依次利用 CythonNumPyGEOSShapelypyshpPROJ六个,或许还有其他一些工具,比如 mapclassify ,这取决于您需要使用哪些功能。

注意:所有这些代码都可以在 Jupyter 的笔记本上找到,网址是github . com/DerwenAI/IBM _ DSC _ articles/blob/master/2020 _ 05/tutorial . ipynb

装置

安装应该很快。只需将以下三个命令行与 conda 一起使用:

注意:如果您在这些安装中遇到问题,还有其他方法可用。一些附加说明讨论了如何在 Linux 上构建这些依赖项

github . com/DerwenAI/IBM _ DSC _ articles/blob/master/2020 _ 05/install . MD

术语

使用地理空间数据的部分学习曲线是使用了大量的特殊术语。这里有一张你可能会遇到的术语的便签:

  • shapefile : 用于表示地图上项目的数据文件格式
  • 几何 : 用于表示点、多边形和其他几何形状或位置的向量(通常是数据帧中的一列),通常表示为 熟知文本【WKT】
  • 多边形:一个区域
  • 点:具体位置
  • 底图 : 地图的背景设置,如加州的县界
  • 投影 : 由于地球是一个三维球体,选择了一种如何将一个区域展*到 2D 地图的方法,使用一些 坐标参考系统 (CRS)
  • 色彩图 : 选择渲染数据的调色板,用 cmap 参数选择
  • 过度绘制:将几块不同的图堆叠在一起
  • choropleth : 用不同的色调给多边形上色,作为一种表现数据等级的方式
  • 内核密度估计 : 一种数据*滑技术(KDE ),创建阴影轮廓来表示数据级别
  • 图表 : 扭曲多边形的相对面积来表示数据等级
  • 分位数 : 将宁滨数据值分成指定数量的大小相等的组
  • voronoi 图 : 将一个区域划分为多边形,使得每个多边形恰好包含一个生成点,并且给定多边形中的每个点都比任何其他点更靠*其生成点;也称为狄利克雷镶嵌

好了,这些术语定义在这里供参考…让我们开始吧!

获取一些数据

我们需要获得一些数据用于这些例子。虽然 geoplot 包含大量样本数据集geojson 格式,但它有助于了解如何加载您自己的数据。

首先,让我们从美国人口普查局 TIGER 数据库中获取一个 shapefile 来可视化州边界,我们将把它放入一个“maps”子目录中:

当然,像这样的 shapefiles 有很多开放的数据源。以下是一些例子:

接下来,让我们获取一些要绘制的数据,在这种情况下,我们将把美国 2018 年的人口估计值放入“data”子目录中:

开始绘图

要在 Python 中导入所需的包:

如果你在一个 Jupyter 笔记本上工作,确保运行下面的“魔法”命令来正确渲染图形:

%matplotlib inline

然后加载 shapefile 并查看其部分内容:

注意“几何”栏,它指定了多边形的形状。

现在,我们将把美国人口普查数据作为一个熊猫数据框架加载,并查看其中的一部分:

接下来,我们将 shapefile 与人口数据合并,加入州名:

很好,现在数据已经准备好绘制形状了。我们将按名称指定加利福尼亚:

或者,我们可以通过从 geoplot 加载一个样本数据集来创建一个地理数据框(一个包含地理空间数据的数据框),在本例中是州边界的多边形:

然后画一张美国各州的地图:

让我们加载另一个样本数据集,在本例中是美国城市:

然后以点的形式标出美国大陆每个城市的位置:

合成这两个,我们将使用超画来显示美国大陆的城市和州。请注意,州多边形的“ax”变量如何提供一个轴,我们在该轴上绘制城市:

这看起来有点夸张,所以让我们调整投影以使用艾伯斯等面积圆锥投影:

好吧,这样更好!同样,由于地球是一个 3D 球体,投影是一种如何使用某个坐标参考系统 (CRS)将一个区域展*到 2D 地图中的方法。geoplot 库使我们可以方便地使用任意数量的投影— 艾伯斯等积投影是一个符合库文档的选择。你也可以玩一些你可能还记得的小学游戏,比如“墨卡托 gcrs”。墨卡托()或它的现代变体,如 gcrs . web 墨卡托()`投影。和他们一起玩吧,让我们知道你更喜欢哪一个,为什么!

表示数据

现在让我们比较几种不同的可视化地理空间数据的方法。首先,我们将根据城市的海拔高度更改城市标绘点的色调,并添加一个图例,以便人们解读不同色调的含义。参数列表开始变得很长,所以我们将在不同的行中指定参数:

我们也可以使用每个标绘点的刻度来表示另一个尺寸。在这种情况下,城市点的比例基于其高程:

使用 choropleth 我们使用不同的色调给多边形着色,以表示数据的维度:

一种被称为核密度估计 ( KDE )的数据*滑技术创建等高线来表示数据的维度。在这种情况下,我们将放大查看纽约市各区的交通碰撞:

让我们缩小范围,在全美国的主要人口中心尝试 KDE:

下一节将介绍如何处理与区域(多边形)相关的数据。我们将加载一个关于美国各州肥胖率的数据集:

使用连接将其转换为地理数据框架。请注意这是如何添加所需的“几何图形”列的:

现在我们可以使用这些数据来绘制一个图表,它可以增长或收缩多边形来表示一个维度的数据——在本例中,是每个州的肥胖率:

简化数据可视化的一个好方法是将数据宁滨成分位数。这些是大小相等的组,在这种情况下,10 个分位数代表海拔:

这里,我们将高程分为 10 个分位数,每个分位数大约有 375 个值。现在让我们给每个分位数分配一个不同的色调,加上一个图例来解释它们:

注意色彩图是如何被更改为“inferno_r”设置的。

接下来,让我们为可以忽略的典型警告添加一个过滤器:

下一个例子使用了一个 voronoi 图,根据数据的维度计算多边形面积。每个多边形以一个生成点为中心,这样多边形中的每个位置都比其他任何位置更靠*它的生成点。当您想要检查一列数据,以查看它是否有任何地理空间相关性时,这很有帮助。

在以下示例中,我们将绘制澳大利亚墨尔本小学的位置,并使用 voronoi 图显示它们的集中位置:

让我们构建一个美国城市海拔的 voronoi 图。这是一种数据*滑技术,因为高程是针对点的,但我们将跨区域“*滑”这些值:

可视化新冠肺炎数据

接下来,让我们从华盛顿大学 IHME 中心下载一些新冠肺炎的数据。根据需要更改解压缩目录的名称(下载日期):

然后加载数据集:

我们将过滤行,将此可视化限于 2020 年地球日(4 月 22 日):

现在将州名与之前的美国大陆数据集合并:

为“每百万死亡人数”添加一个计算列:

然后为了形象化这些数据,让我们画出每个州“每百万死亡人数”的曲线图,再画出每个城市的人口:

请注意,通过重复使用相同的“ax”变量,choropleth 是如何与点绘图过度绘制的。点绘图规定了一个“zorder”参数(哪一个“层”)和一个“alpha”参数(如何“半透明”),以使过度绘图更可读。第一个图中的“figsize”参数修改图的整体大小。

这幅图像显示了美国人口集中的地方风险更大:纽约市地区、路易斯安那州、伊利诺伊州、密歇根州、乔治亚州等。这也是 2020 年地球日当天美国关于新冠肺炎的新闻头条的焦点。

动画地图

接下来,让我们准备动画这个可视化。我们将定义一个函数来可视化给定日期的数据:

然后定义一个日期范围:

遍历这些日期,为每个日期创建一个可视化结果,并保存到一个文件中:

使用“imageio”以 2 帧/秒的速度将这些单独的图形拼接成动画 GIF:

这是最终动画的视频:

注意:还有一个 matplotlib.animation API,我们可以用它来代替 imageio。前者在最*的版本中有一些 bug,而后者有更多的通用用途。

同样,所有这些代码都可以在 Jupyter 笔记本上找到,网址是github . com/DerwenAI/IBM _ DSC _ articles/blob/master/2020 _ 05/tutorial . ipynb

如果你想尝试扩展这个可视化的例子,在 https://covidtracking.com/data有很多相关的数据集

合著: 威廉·罗伯茨

最初发表在 IBM 数据科学社区博客上,地址:https://ibm.biz/paco-geospatial

使用优步的 Kepler.gl 可视化地理空间数据

原文:https://towardsdatascience.com/visualizing-geospatial-data-with-ubers-kepler-gl-2a437ada573d?source=collection_archive---------34-----------------------

了解事件发生的方式、地点和时间。

最终产品是一张按人口普查区域划分的拼车出行地图

Kepler.gl 是优步对地理空间分析的回答。它于 2019 年开源,以最终用户为中心,创建了一个“拖放”系统,能够在瞬间分析数百万个点。幸运的是,对于我们这些喜欢在 Jupyter 笔记本上工作的人来说,他们已经使用 ipywidgets 创建了一个扩展,允许用户在我们的日常数据科学工作流中创建地图。继续阅读教程,轻松开始创建自己的地图!

如果你想在笔记本文件中跟随,继续前进,并在这里叉我的 github repo-found。你也可以在下面玩我们最终地图的现场版本:

[## 芝加哥的拼车旅行- kepler.gl

www.dancorley.com](https://dancorley.com/chicago.html)

套餐

首先,我们需要安装将要使用的软件包;GeoPandas、keplergl 和 sodapy。这些可以很容易地安装,然后导入到我们的笔记本电脑与每个人都喜欢的包管理系统,匹普!

安装/导入软件包

收集数据

我们今天要看的数据可以很容易地通过芝加哥市的数据门户网站获得,其中包括从圣诞树回收地点到当前政府雇员工资的各种数据。很多数据,但今天我们将只关注两个数据集——交通网络提供商——Trips人口普查区

该城市的数据门户有一个很棒的用户界面,可以方便地导出到用户选择的文件类型。csv,。xml 等。),但是在撰写本文时,我们的目标数据集已经超过 1.29 亿行。为了节省时间(和本地存储空间),谢天谢地,他们允许通过 Socrata 进行类似 SQL 的查询。我们之前安装的包(sodapy)将允许我们轻松地对这个数据集进行请求。同样值得注意的是,我们可以匿名访问这些数据,但您将受到限制,为了绕过,您可以获得一个可选的授权令牌-请参见此处的

让我们继续收集我们的旅行数据。以下要点将带领我们创建一个 Socrata 查询,返回由 2019 年 3 月的旅行次数组成的 geojson(按点分组)(纬度/经度坐标),并实例化地理数据框架。然后我们只用三行代码就可以创建我们的第一张开普勒地图……就这么简单!

函数来调用旅行数据,并创建我们的第一个地图

该地图是交互式的,允许用户轻松缩放、*移和滚动点来查看数据。还可以根据与每个点相关联的乘坐次数来定制点,以改变颜色或大小,从而更容易摄取。这可能是本文的结尾,但开普勒不仅仅是点。输入人口普查区域多边形:

调用芝加哥人口普查区域数据集的函数

将图层添加到我们创建的当前地图中,可以让我们看到每个人口普查区域的边界,以及我们之前点的位置。现在,因为这是两个不同的数据集,我们不能根据另一个来操纵每个数据集的属性。借助 GeoPandas 的几何操作,这一点很容易克服,它允许我们检查一个点是否包含在一个区域内,并返回乘坐的总次数:

有了这张地图,我们为我们的最终用户添加了更多的数据,我在最后几张图片中提到过。根据客流量级别创建区域的填充颜色和高度使得从我们的数据中收集见解变得更加简单。

这个看起来很棒,但是还没有完成。我们仍然需要添加等式的最后一部分;时间。下一个代码块运行了我们在这篇文章中完成的查询,并添加了一个 datetime 元素,创建了每天每个区域的乘车次数总和:

现在,我们如何分享它,以便其他人可以享受??当然 Kepler.gl 的 python 包也有一个简单的方法来做这件事!

保存文件以便于部署!

如果你已经走了这么远,感谢你加入我的地理空间之旅!我们已经通过查询芝加哥的开放数据来收集数据,在 Kepler.gl 中使用点和多边形创建地图,以及使用 GeoPandas 进行几何操作。

如果你对方法论有任何问题/意见,欢迎在评论栏或我的收件箱——hello@dancorley.com 里开始对话

用 kepler.gl 可视化地理空间电子商务销售数据

原文:https://towardsdatascience.com/visualizing-geospatial-e-commerce-sales-data-with-kepler-gl-ff127896804e?source=collection_archive---------43-----------------------

在几分钟内实现优雅的数据可视化

(最初发布于https://www . dattivo . com/visualizing-geospatial-e-commerce-sales-data-with-Kepler-GL/)

任务背景

作为内部研究和发现工作的一部分,我们希望评估可视化数据分析工具的可用性和功能,以检查我们的一个客户举办的活动的在线门票销售数据集。我们的数据集包括在线购买活动门票的客户的位置,以及提前多长时间购买活动门票。在这种情况下,像 kepler.gl 这样的数据可视化工具非常适合快速生成任何观察者都能轻松理解的数据视图。

Kepler.gl 是由优步开发的开源地理空间数据分析和可视化工具。Kepler.gl 可以直接集成到基于 React 的 web 应用程序或 Jupyter 笔记本中。在这个练习中,我们将在 https://kepler.gl/demo使用“演示应用程序”。

请注意,虽然这些可视化效果是由现实生活中的事件激发的,但实际的可视化效果只是为了演示 kepler.gl 而放在一起的。

地理编码电子商务订单

在对订单数据集执行任何地理空间分析之前,我们首先需要通过为每个订单分配一个纬度和经度来对附加到订单的地址进行地理编码。对于我们的数据集,一个包含客户订单和相关细节的 MySQL 数据库,我们将基于客户账单地址的邮政编码来完成这项工作。许多提供商提供不同价位和请求限制的地理编码 API,但在本练习中,我们将使用 Google 的地理编码 API。为了获得最佳结果(以及数据集的一般可读性),我们通过将字母转换为大写并过滤掉任何空格、连字符或其他非字母数字字符来“规范化”邮政编码。

将初始数据集导出到 CSV 文件后,下一步是检索地理编码数据。这是使用 Python 脚本完成的,但当然也可以使用任何允许您发出 HTTP 请求和/或写入 CSV 的语言来完成。首先,我们导入必要的库,并将地理编码数据加载到 Pandas DataFrame 对象中:

熊猫⁴是一个非常强大的 Python 开源库,具有许多数据操作和分析的特性。它可以快速有效地读写串行数据或 DataFrame 对象中的数据,处理 CSV、Excel 或文本文件,以及数据库导出。接下来,我们将开始构建邮政编码“目录”的过程,将邮政编码映射到其纬度和经度值。条目的示例可能是:[N6J3T9,43.3326543,-79.4324534]。我们将使用它来修饰我们当前的数据集,但也保留它以备将来使用,以便我们可以在将来将它应用于任何重复的邮政编码,而不必进行多余的 API 调用。为了向 Google 的地理编码 API 发出这些请求,我们使用 Python 的开源 Requests ⁵库,它提供了发出 HTTP 请求的简单函数,来创建一个会话对象来发出我们的多个请求。我们还使用了地理编码器 ⁶库,它带有简单的功能,可以向许多不同的提供商发出地理编码 API 请求,包括 Google、Bing、ArcGIS 等等。

这段代码将遍历数据集中每个唯一的邮政编码,并请求获取其大概的经度和纬度。我们将把响应保存到我们的目录文件中,并输出到控制台,这样我们仍然可以把它复制到一个文件中,以防脚本运行时出现问题。如果脚本由于任何原因中断,并且我们最终只得到部分地理编码数据,我们可以简单地重复该过程,过滤掉任何已经地理编码的值,并将结果文件合并在一起。

一旦我们有了地理编码数据,我们就可以用 Pandas 来修饰我们最初的客户数据导出。

准备好数据后,我们现在准备将其导入 kepler.gl。

在 kepler.gl 中可视化数据

将数据加载到 kepler.gl 很简单,https://kepler.gl/demo的演示应用程序提供了一种直观的方式来立即在地图上查看数据。页面首次加载时,会提示您上传数据。请注意,kepler.gl 演示在您的浏览器中运行,因此任何上传的数据都不会发送到他们的服务器,而是保留在您的本地计算机上。

基于数据集中的列,kepler.gl 将尝试自动决定如何呈现数据。如果您的数据集包含标记为“lat”和“lng”的列,kepler.gl 将自动识别它们,并使用这些字段将您的数据放置在地图上。

定义数据图层时,也可以手动指定用于纬度和经度的列。单击图层名称旁边的符号查看设置,然后单击“基本”旁边的省略号选择要用于点位置的列。

当前状态下的地图向我们显示了每张已购买机票的位置,但是 kepler.gl 提供了不同的图层类型,我们可以使用它们来聚合数据。在这个练习中,我们将使用一个 Hexbin 层,它将数据点聚合成一个指定半径(默认为 1 公里)的六边形。

基于指定的度量,将选定光谱上的颜色分配给每个六邻体。默认情况下,这基于点计数,但可以更改为数据集中的任何列。还可以配置使用的色标和光谱中的级数。

如果我们通过切换右上角的立方体图标从 2D 地图切换到 3D 地图,我们可以根据数据集中的另一个字段为我们的 hexbins 分配一个高度值。在这个例子中,我们用高度表示每个聚类的点数(在我们的例子中,它表示购买的门票数量),用颜色表示在活动日期前多少天购买的门票。还可以应用高程比例,以便更容易地识别数据集中的极值。

从视觉上看,我们可以看到,虽然有客户会提前购买全省的门票,但那些远离多伦多市中心的客户似乎更有可能在接*活动日期时购买(其中较暗的数据点表示门票是在活动当天购买的)。这是有意义的,因为天气等变量会影响客户的决策过程。

接下来,我们可以基于数据集的任何列对数据集应用过滤器。单击漏斗图标切换到过滤器选项卡,然后单击添加过滤器并选择一列。

对于数值或“时间”数据类型(例如,格式化为日期和时间,如 2019–12–25 12:00:00),您可以通过单击并拖动显示的范围来选择要过滤的列的最小值、最大值和范围值。按时间值过滤时,您还可以单击播放按钮来显示地图数据的延时动画(您需要单击并拖动屏幕底部的日期过滤间隔的边缘,这样才有用)。对于字符串或日期等其他数据类型,可以选择特定的值进行筛选。

如果我们想要比较多个数据集之间的数据(例如,多年的活动销售数据),我们可以简单地在 kepler.gl 中向我们的可视化添加另一个图层。此时,从默认的“点”标签的图层选项卡中重命名您的图层很有帮助,以便更容易地在菜单和图例中区分它们。

如果您愿意,可以在同一个地图视图上显示多个图层,但是如果我们像本例中一样尝试在相似的数据集之间进行直接比较,在各自的地图上查看每个数据集会更有意义。我们可以通过点击右上角的图标切换到双地图视图,并切换每个视图中可见的图层。请注意,滤镜是分别应用于每一层的。

结论

如前所述,数据集的初始地理编码数据检索和修饰可以通过多种方法完成,但我们选择使用提到的 Python 库,以评估它们在未来项目中的效用。这个练习没有深入到 Pandas 的功能中,但是我们鼓励您深入了解它,看看它是否适合您的需要,因为它提供了各种各样的功能。

Kepler.gl 允许非常快速地生成专业外观的数据可视化,并提供许多不同类型的数据可视化。除了这里演示的点和六边形以外,kepler.gl 的可用数据图层还包括用于聚合分析的热点图和聚类、用于可视化移动的弧和线,以及用于显示复杂路径或多边形(如出行路线)的 GeoJSON 图层。如果我们将来需要执行这些类型的分析,kepler.gl 将是一个显而易见的选择。生成的视图在第一次呈现时有一个明确的“哇”的因素,并且可以根据被调查的数据提供清晰的、可操作的见解

Kepler.gl 也是一个 React 库,可以集成到现有的前端项目中。对于未来的工作,我们可能会研究实现在嵌入管理界面的 kepler.gl 地图中查看最*销售数据子集的能力。

需要注意的一点是:数据点的颜色比例和高度/大小会根据当前正在检查的数据子集而动态变化。这意味着,当从一个视图到另一个视图比较数据时,您必须关注图例,以确保您得出的结论是准确的。例如,来自不同过滤数据集的两个点可能具有相同的颜色,但是为其分配特定颜色的值的范围在视图之间可能不同(例如,在一个视图中,值小于 16.2 的点可能显示为红色,而在另一个视图中,阈值为 12.0)。遗憾的是,在执行时间序列回放或使用双地图视图时,目前似乎没有标准化该比例的方法。

参考文献

[1] 开普勒. gl

[2] S. He,从美丽的地图到可行的见解:介绍开普勒. gl,优步的开源地理空间工具箱 (2018)

[3]kepler.gl/demo

[4] 熊猫— Python 数据分析库

[5] K. Reitz,请求:人类 HTTP 请求 2.23.0 文档

[6] D. Carriere, Geocoder:简单、一致— geocoder 1.38.1 文档

使用 leav 可视化新冠肺炎的全球地位

原文:https://towardsdatascience.com/visualizing-global-status-of-covid-19-using-folium-52797b5dcc19?source=collection_archive---------63-----------------------

这个博客是关于根据国家对抗冠状病毒的表现将国家分为不同的组,并最终可视化地理结果。

2019 年全球冠状病毒状况

冠状病毒已经影响了我们每一个人的生活。随着世界大部分地区陷入经济活动萎缩的困境,我们每个人都想知道我们在遏制疫情方面做得有多好,它何时会最终结束?

虽然预测疫情的终结是一个百万美元的问题,也是另一个博客的主题,但这篇文章是关于理解和可视化所有国家如何抑制其蔓延。在这篇博客中,我们的目的是根据确诊病例、死亡和患者康复数据将国家分类,然后在地图上显示出来。

方法

我们将使用 PPDAC 方法来解决这个问题。我们将从讨论我们的问题开始,然后计划解决它。一旦我们弄清楚了这一点,下一步就是收集必要的数据并对其进行分析。最后,我们将提出我们的结论并交流我们的结果。

解决数据科学问题的 PPDAC 方法

我们会一步一步地走完每一步。

问题

我们试图解决的问题是将不同的国家分为不同的类别,分别命名为“低风险”、“高风险”、“稳定”和“复苏”。在这一点上,我们只能模糊地定义这些群体。如果新冠肺炎病毒的传播正在增加,增长仍然是线性的,但存在指数增长的普遍风险,我们可以将任何国家标为“低风险”。使用类似的标准,“高风险”国家是 COVID 病例呈指数增长的国家。“稳定”阶段可以定义为病例减少和指数增长停止的情况。最后,恢复是指病例非常少,而且该国正在走向彻底根除疫情。由于新病例不能作为确定任何国家状况的唯一标准,我们需要有类似的报告死亡和成功康复的标准。

一旦我们对我们的标签有了一个模糊的理解,我们就需要制定一个标准,如何从一个包含新病例、死亡和康复的数据集转移到一个包含我们的标签的数据集。为此,我们必须后退一步,理解疫情图。

疫情图

我们现在已经看够了这个图表,它解释了使曲线变*的所有智慧,这样医疗保健系统就不会压力过大,最迫切需要医疗护理的人可以得到最多的医疗护理。但是我们可以比这挖得更深一点。正如我们从图表中看到的,病例数开始或多或少地呈线性增长,之后呈指数增长。指数增长达到峰值,之后开始下降。这是任何流行病的一般趋势,它达到最大值,趋势开始逆转。这一点被称为病毒的死亡,因为在这一点上,要么所有的人都被感染,人群中没有更多的人被感染,导致病毒死亡,要么在另一种情况下,采取措施,如社会距离,锁定,这拒绝了新的宿主病毒导致其死亡,或者我们可能有最终的救世主,一种疫苗基本上杀死它。

有了这样的理解,我们现在可以看看另一个有趣的特征,在特定点的导数或变化率。这定义了每天新病例的增加或减少。请看下图:

正如我们所见,导数展示了四种特定的行为。第一个,当变化率是正的和线性的,在这个点之后它变成指数正的。在达到最高点之后,梯度为零,它开始变成指数负值,并最终变成线性负值。衍生产品的所有这四种不同行为都可以与我们的标签联系起来,即低风险、高风险、稳定和恢复。这个想法可以用下图来表达:

哇,我们这里有很多信息,我们还有一段路要走。顺便说一下,如果你有兴趣了解我是如何制作这些图表的,请查看这里的。

现在,我们已经定义了衍生品如何帮助我们确定任何特定国家的地位或标签,故事中还有另一个陷阱。我们注意到,即使该国处于稳定阶段,回到低风险或高风险阶段,病例数量仍可能增加。为了迎合这一点,我们需要以某种方式检查情况是在变好还是在变坏。

我们可以通过将任何特定一天的导数与 14 天的*均导数(14AVd)进行比较来做到这一点。如果我们用特定一天的导数减去 14AVd,值为负,这意味着特定一天的导数高于 14 天的*均值,这意味着情况正在变得更糟。反之亦然,如果答案是肯定的,这意味着情况正在好转,疾病正在走向根除。

现在,我们可以将上述基本原理应用于确诊病例、死亡和康复的所有数据集。一旦完成,我们就可以应用 K-means 算法来寻找组的聚类。由于我们对可视化和简单理解 k-means 结果更感兴趣,所以我们需要将我们的维度从新增病例、死亡和恢复的三个维度降低到两个信号。

新病例信号对确定任何国家的情况都至关重要。我们称这个信号为“强度信号”。它决定了病毒在特定国家传播的快慢。然而,死亡和康复的其他数据集是疾病的两个结果。要么,任何人都可能死于这种疾病,要么康复。从今以后,死亡和康复可以结合起来产生一个冲击信号。我们可以从死亡中减去康复。如果结果是负数,这意味着死亡人数大于复苏人数,情况正在变得更糟,而在其他情况下,结果是积极的,这意味着复苏正在增加,情况正在好转。

看看下面的象限,它们有意义吗?

据此,我们更新了不同标签的定义,建立了从新病例、死亡和康复的数据集到特定国家的标签或标记的必要联系。

当我们进行编码时,我们将把这种方法称为“algo”。没有特别的理由称之为“算法”。只是我找不到更好的了,😄

最后,我们可以将“强度”和“影响”这两个信号输入 k-means 算法,以生成组的聚类,从而确定标签。

Huff,如果你正在跟随,拍拍你的背,为你欢呼。

计划

我们将使用由 HDX 编辑的数据集,并将上述基本原理应用于熊猫。数据集可以在这里找到。该数据集包含每个国家每日新增确诊病例、死亡和恢复的数量,并且几乎每天更新。

一旦我们完成编码,我们只需要更新数据集,每个国家的新标签将自动计算。

数据

现在是时候用代码弄脏我们的手了。我们将首先从 HDX 网站这里下载新确诊病例、死亡和康复的所有相关数据集,并将它们放在一个名为“数据集”的文件夹中。

现在需要一些预处理。很少有国家有一个以上的列与自己相关联,像澳大利亚有八个相关联的列,每个列代表一个州。我们需要将所有这些列相加,以获得整个国家的数据。

接下来,我们需要将每个数据集作为一个熊猫数据框,提取最后 14 列数据,计算导数,并使用它来计算所有国家的 14 天*均值。

完整的 python 实现以及代码解释可以在这里找到。至此,我们已经完成了数据预处理练习,可以继续前进了。

分析和结论

我们已经走得足够远,可以对我们的数据实现 k 均值。这个想法是在两个强度和冲击信号之间应用 k-means 聚类,看看我们是否能找到一些足够接*我们早先开发的基本原理的聚类。KNN 的 python 实现可以在这里找到。一旦我们运行这个 python 脚本,我们最终会得到如下所示的聚类图:

现在,我们需要根据我们之前开发的原理,查看哪个集群可以被标记为“低风险”、“高风险”、“稳定”和“恢复”。正如我们所看到的,大部分国家都被困在原点附*,只有少数国家在他们的探索中做得特别好或特别差。然而,正如我们所看到的,集群并没有像我们预期的那样形成。我们已经结束了左边的三个集群,标记出可以被称为低、中、高风险区域的区域,而例外的是没有国家处于复苏阶段,描绘了一幅令人沮丧且与事实相反的画面。

我们数据集的主要问题是离群值问题,这使得聚类过程变得困难。正如我们所看到的,在图表的右边有一个国家,做得非常好。但是它使我们无法进行聚类工作,因为它被当作自己的一个聚类。为了解决数据中的这些问题,我们可以尝试使用一个简单的 if-else 函数对我们之前的基本原理进行编码,并查看其结果。

对右边的国家很好奇。点击查看

我们之前开发的基本原理的一个简单 Python 实现可以在这里找到。生成了下图。

是啊,这还差不多。按照我们的基本原理准确地描绘我们的世界。然而,上面提到的右边的异常值在这里被忽略了,以强调数据集中的主要聚类。分配状态标签后,我们可以进入项目的最后一个也是最有趣的部分,地理数据可视化。

我们将使用 Geopandas 和 leav 来可视化我们的数据。安装 geopandas 有时会很棘手。如果您正在任何阶段挣扎,请看看如何创建 anaconda 的环境来管理依赖关系。

一旦我们的环境创建完成,Geopandas 和 Folium 启动并运行,我们就可以在这里实现代码来生成我们对抗冠状病毒的性能的全局可视化。

请使用这个链接查看你所在国家的状态。

我们终于看到了新冠肺炎的世界地位。结果更新至 2020 年 4 月 11 日。想要可视化当前状态吗?只需锥形这个储存库,更改文件夹数据集中的文件,并执行 jupyter notebook 这里的

在最后,一个直方图显示了每种状态下的国家数量,可以帮助我们进一步了解世界的状态。

正如我们可以想象的那样,世界上最大的一部分陷入了“低风险”,稳定和复苏的频率越来越低。对于许多国家正在复苏的世界来说,这仍然是一线希望。低风险和高风险的最高频率强调了仍然坚持自我隔离和社会距离的重要性。

数据可视化完成后,讨论我们的数据和算法的缺点是很重要的。所使用的强度信号并不是一个很强的方向指示器,这个国家正在前进。几个病例的随机出现可以极大地影响一个国家的地位。另一个主要争论点是缺少测试数据。怎么强调都不为过,任何国家的地位都可能是虚假的,因为它没有积极地测试其公民。事实上,病毒的传播速度可能比想象的要快得多。

最后,我想说,我绝不是流行病方面的专家,但是如果有人碰巧读到这篇文章,请随时向我提出你的建议。我们可以一起使这些数据更准确,更能代表地面的实际情况。同时,这里的是可视化 web 应用的链接,玩一玩,乐一乐。

特别感谢艾哈迈德·赛义德对这个项目的帮助。

可视化高维微生物组数据

原文:https://towardsdatascience.com/visualizing-high-dimensional-microbiome-data-eacf02526c3a?source=collection_archive---------22-----------------------

来源:wallpapercave.com/dna-background

第 2 部分—基因组数据科学系列

本文是将机器学习应用于生物信息学数据的系列教程的一部分:

第一部分—数据采集&预处理

第 2 部分—降维

为了跟进,你可以在这里下载我们的 Jupyter 笔记本,或者继续阅读并输入下面的代码。

介绍

无监督的机器学习方法可以让我们在没有给定明确标签的情况下理解和探索数据。一种无监督的机器学习方法属于聚类家族。获得相似数据点的组或簇的一般概念可以告知我们数据中的任何潜在结构模式,例如地理、功能相似性或社区,否则我们不会事先知道这些信息。

我们将把我们的降维技术应用于从 UCSD 的 Qiita *台获取的微生物组数据。如果您还没有这样做,请参阅本教程系列的第 1 部分了解如何获取和预处理您的数据,或者在这里下载我们的笔记本。在我们继续前进之前,我们需要这个。基本上,我们的微生物数据集的列代表细菌 DNA 序列的数量,我们的行代表单个细菌群落的样本。这种类型的数据表可以从 Illumina NGS 测序数据经过各种生物信息学数据清理和转换后创建。我们期望来自不同环境的样本具有不同的微生物特征,因为细菌群落受其环境的影响。我们为本文处理的数据是从多伦多、弗拉格斯塔夫和圣地亚哥采集的样本,它们应该各不相同。我们希望将这种隐藏在细菌组成中的差异可视化。

预计这三个不同地点的细菌群落是独特的,我们希望通过高维微生物组数据来可视化这一点。图片来源:Pexels,由用户修改。

为了将这种复杂、稀疏和高维的宏基因组数据可视化为我们的眼睛可以在二维计算机屏幕上解释的东西,我们将需要大幅减少我们的维度大小,或者换句话说,我们数据中的特征数量。我们的数据集有 25,000 列,这些列目前代表了每种生物体的一部分基因序列以及它们在我们的微生物组中的数量,相反,我们希望绘制“最重要的特征”的概念。本文探讨了应用于微生物组数据的 3 种不同的维度减少和可视化技术,并解释了这些可视化可以告诉我们关于我们的数据中固有的结构的信息。

所有可视化都是用 python 和 Matplotlib 和 Seaborn 绘图包制作的,pandas 用于构建数据框。

出于演示的目的,由于我们实际上有这个数据集的标签,我们可以通过为对应于不同地理位置的每个点分配不同的颜色来确认我们的数据集是否产生了良好的可视化效果。在现实中,如果你已经在采用无监督的机器学习方法,你通常不会有这种情况。

主成分分析

我们的第一种降维技术,也是最常用的一种,叫做主成分分析(PCA)。PCA 试图将特征空间减少到数据中发现的变化的表示。它通过获取所有数据点并旋转到清晰显示最大可变性的轴来实现这一点。这个轴被称为你的“第一主成分”。从数学上来说,这条线的位置穿过数据的质心,同时也最小化了每个点到这条线的*方距离。它也是数据变化最大的轴。重新排列数据后,我们将把所有数据点折叠到该维度上。一旦这一步完成,我们冲洗和重复,记住,每次我们找到一个新的主成分,新的线将总是垂直于前一个主成分。看这里(https://setosa.io/ev/principal-component-analysis/)对 PCA 的形象化解释。

为了进行 PCA,我们可以在我们之前构建的特性表上运行下面的代码。

来源:作者图片

如果给我们一些标签来检查我们的维数减少情况(提醒一下,在现实中这是不能保证的),我们可以用颜色重新绘制我们的 PCA:

当我们将数据从 1,894 个特征转换为 2 个特征时,我们可以看到数据被放入两个可辨别的维度。然而,一旦我们在数据的地理来源被揭示后查看数据的真正含义,我们会发现这种可视化技术并没有给我们一个地理数据的良好表示。不幸的是,当应用于微生物组数据产生的稀疏水*时,这种常见技术就分崩离析了。

*需要注意的是,应用 PCA 后,我们可以得到各种形状的图。为了解释你可以得到的不同形状,我们建议你看看这个帖子这里

t-SNE

另一种用于探索像我们的微生物组数据这样的高维数据的技术是使用一种被称为 t-分布式随机邻居嵌入 t-SNE 的东西。与 PCA 不同,它通过使用线性方法试图在我们的低维表示中保持不同的数据点相距很远,t-SNE 试图通过试图保持相似的数据点靠*来处理位于非线性低维流形上的数据。

t-SNE 通过最小化两个分布之间的差异来工作。第一个分布来自我们在原始高维输入空间中对象的成对相似性。第二个分布是我们在相应的低维嵌入中对象的成对相似性。本质上,我们试图最小化原始高维空间和相应的低维空间的这两种分布之间的差异。

要运行 t-SNE,让我们使用 scikit-learn 的实现,并在之前的功能表上运行它:

在我们继续之前,让我们提出几个要点。t-SNE 的一个参数是我们用来计算特征实例之间距离的度量。默认值是欧几里德距离,但是因为我们使用计数作为每行的条目,所以我们将使用一个称为 Jaccard 距离的度量。实质上,Jaccard 距离度量是两个集合中的计数数量除以任一集合中的数量,乘以 100,然后从 1 中减去所有这些。它从技术上衡量样本集之间的差异。

我们可以在 t-SNE 中调整的另一个重要的超参数是困惑。从本质上说,困惑让我们能够*衡我们在数据中对本地和全球关系的重视程度。我们选择坚持困惑=30 的默认设置,但是我们强烈推荐这次探索 t-SNE 和困惑这里

让我们绘制 t-SNE 嵌入的结果,显示一个没有标签的图(同样,就像你在真实的无监督场景中所期望的那样)和一个有已知标签的图:

当标签被揭示时,我们可以看到,这种嵌入是我们微生物组遗传数据中存在的潜在地理结构的体面代表,正如从相同地理区域获取的数据点在它们自己的象限中所证明的那样。接下来,我们将转向 UMAP,这是一种我们发现对这类数据最有效的技术。

我们将用于表示高维微生物组宏基因组数据的最后一种降维技术称为一致*似和投影(UMAP)。UMAP 改进了 t-SNE 的性能,不仅在明显更短的时间内更好地处理更大的数据集,而且保留了更多的原始数据全局结构。为了更深入地比较 t-SNE 和 UMAP,我们在这里推荐这个教程。

UMAP 的数学基础集中在首先构建一个加权图,其中边权重表示点之间连接的可能性。这是由从每个点向外扩展的半径和具有重叠半径的连接点决定的。随着每个点的半径增加,其连接的可能性降低。

类似于 t-SNE,我们也可以调整与 UMAP 相关的超参数,以*衡我们在低维嵌入中的局部和全局结构。我们的 n_neighbors 参数对应于用于构建原始图形的最*邻点的数量,低值强调局部结构,高值强调全局结构。

第二个主要参数是 min_dist 的参数。该参数表示我们在低维嵌入中想要的点之间的最小距离,低值给出更紧密包装的点组,而较大值给出更松散包装的点组。我们建议在这里使用交互式可视化来获得对 UMAP 超参数的直观感受。

现在让我们用 UMAP 创建新的低维嵌入:

…并且带有标签:

正如我们可以看到的,一旦我们应用颜色来显示我们的标签,似乎 UMAP 在将基础地理结构从我们原始的高维宏基因组数据集传递到上面的低维可视化方面做得更好,图中的每个“轮辐”或“花瓣”代表该地区的当地微生物群落,也称为那些微生物组。

结论

微生物组数据因其固有的高维度和稀疏性而呈现出独特的挑战。为了降低维数,我们应用了三种技术:主成分分析,t-SNE 和 UMAP。在对类似数据进行分组方面,如具有类似地理来源的微生物样本,UMAP 表现最好。

在上面的基础上,我们可以使用这些 2D 嵌入结合我们最喜欢的聚类算法来从数据中推断类别。我们可以尝试将维度减少到任意数量的维度,然后在此基础上应用聚类,而不是将维度减少到两个维度。使用聚类方法对微生物组数据进行分类是我们可能在下一篇文章中讨论的主题。

这一系列教程的两位合著者是尼古拉斯·帕克 & 蒙迪·雷默,他们都是旧金山大学数据科学硕士项目的毕业生。

如果您想联系我们,请联系我们:

蒙迪·雷默 领英
个人博客
推特

尼克·帕克 领英
个人博客

PCA,SNE 霸王龙和 UMAP。用户创建的图像。

通过数据收集和清理可视化休斯顿暴力犯罪趋势

原文:https://towardsdatascience.com/visualizing-houston-violent-crime-trends-via-data-collection-and-cleaning-64592a8bac25?source=collection_archive---------43-----------------------

黄昏时分的休斯顿市区。 Pixabay 供图。

暴力犯罪是表明社会疾病的症状之一。这在很大程度上是因为一个社会及其政府未能提供人类繁荣所必需的要素:食物、住所、教育、职业培训和获得身心保健。与此同时,犯下滔天罪行和轻微罪行的人都具备这些基本条件。在本文中,我将使用暴力犯罪统计的例子来说明 Python 中的基本数据科学方法。特别是,我将关注我的家乡德克萨斯州休斯顿的暴力犯罪数据。

本文的目标是展示

  1. 数据采集:网页抓取将文件下载到本地目录
  2. 数据清洗:仅提取并存储所需值
  3. 数据可视化:绘制数据揭示趋势

免责声明:我不会逐行检查执行上述三个步骤所需的代码。我希望代码块的截图能够帮助您理解:(1)如何对数据文件执行 web 抓取(2)读取 Excel 文件并将其转换为 Pandas dataframes (3)在 Pandas 中执行标准的数据清理操作(4)使用 matplotlib 库绘制 Pandas dataframes 中存储的数据。

一、利用网页抓取和浏览器自动化进行数据收集

首先,我们去休斯顿警察局犯罪统计网页

休斯顿警察局 2009 年至 2018 年每月犯罪统计网页。

每月犯罪统计数据有 Access 和 Excel 两种格式。我将使用 Excel 文件。当您单击 Excel 链接时,包含该月统计数据的 Excel 文件会下载到您的本地计算机上。下面是 2009 年 6 月数据的前几列的示例。

2009 年 6 月休斯顿犯罪数据

在继续讨论数据科学之前,让我们花一点时间来思考上述每一个事件所带来的痛苦,再花一点时间来思考无数未报告的此类事件。

请注意,有些行的日期不在 2009 年 6 月。这可能是由于以前的事故在以后的日期得到报告。我们必须在数据清理和处理步骤中处理这些情况。为了开始收集数据,我们注意到所有的 Excel 链接都有 URL,当被访问时会启动相关文件的下载。所以首先我们需要收集上面网页上所有的 Excel 链接网址。我们将使用请求bs4 (也称为 BeautifulSoup)库来完成这项工作。使用以下函数可以获得 Excel 链接。

功能,以刮除每月犯罪统计网页上的 Excel 文件的所有网址

该函数将两个 URL 作为输入:一个主页 URL 和一个基本 URL 。因为这两个 URL 是固定的,所以可以在名为 config.py 的配置文件中定义它们。以下是它们的定义:

网页抓取步骤的固定网址

有了链接,我们需要编写浏览器自动化代码来访问它们,并将它们下载到我们选择的目录中。这个特殊数据集的一个障碍是文件名和扩展名是两种不同的格式。此外,包括字符串NIBRS _ Public _ Data _ Group _ A&B在内的较长文件名的文件具有更复杂的结构,并且在使用 Pandas 库导入时会产生官样文章。由于这些文件仅包含数据集中 114 个月中的最后 6 个月,我们现在将忽略这些文件。为了适当地忽略它们,我们将它们保存在一个名为凌乱的子目录中。这里有一个从 URL 链接下载文件到本地目录的功能

从 HPD 罪案统计网页下载 Excel 文件的功能

其中 data_dir 是下载目录的路径,字典 m_dict 用于在 3 个字符的字母和 2 个字符的数字字符串之间进行转换,表示由

忽略乱七八糟的文件,其他都是格式 mm-yyyy.xlsx 。我想把它们改成格式 yyyy-mm.xlsx ,这样文件系统在按字母数字排序时会按时间顺序列出它们。下面的函数将完成这个任务

现在,非混乱文件按时间顺序列出,混乱文件存储在子目录中。

我们的数据收集步骤现在已经完成。为了组织代码,我将上面显示的所有函数放入一个名为 helper_funcs.py 的文件中,并导入了请求操作系统bs4 库。然后,我创建了另一个名为 data_collection.py 的文件来处理这个数据收集步骤。下面的屏幕截图提供了该文件的全部内容

网页抓取和文件重命名的完整代码(又名数据收集)

二。用熊猫清理数据

现在我们准备清理数据并提取信息的子集。我们希望使用 read_excel 函数将单个电子表格导入到 Pandas 数据框中。当我直接尝试这样做时,我遇到了以下文件重要子集的错误:

警告文件大小(3085901)不是 512 +扇区大小的倍数(512)
警告
OLE2 不一致:SSCS 大小为 0,但 SSAT 大小为非零

为了绕过这些错误,我在这里找到了下面的 hack ,它需要导入 xlrd 库。

一旦我们将电子表格转换成 Pandas 数据框架,我们需要删除所有无关信息的列。在这种情况下,我们只对发生日期、犯罪类型和犯罪次数感兴趣。我们还将只记录暴力犯罪,因此将删除与非暴力事件相关的行。被认为是暴力和非暴力的犯罪列举如下

我们稍后会把“严重人身攻击”改名为“人身攻击”。以下是数据集(2009 年前后)开头的许多文件共有的所有列名的列表

我们感兴趣的列子集是['日期','犯罪类型','犯罪数量']。为简单起见,我们将把“冒犯类型”列重命名为“冒犯”,将“冒犯数量”重命名为“#”。然而,在浏览数据时,我注意到并非所有最后一栏都标有“犯罪数量”。事实上,以下是本专栏所有备选名称的详尽列表:

为了处理这些不规则性,我们将查找上述项目的任何出现,并将它们重命名为' # '。这个问题正在处理,我们现在可以删除无关的列。以 2009 年 6 月的数据为例,下面是熊猫数据框架的打印结果,其中删除了一些列

以下函数将从 Excel 文件中创建一个 Pandas 数据框,并生成一个三列数据框作为输出,如上图所示

请注意 inplace=True 参数的用法。这在将数据帧传递给函数时是必要的,因为它告诉 Pandas 更新原始数据帧,而不是创建一个副本并保持原始数据帧不变。最后一行是行条目重命名,而不是删除列。

数据清理操作中剩下的两个步骤是:(1)删除无关的行,以及(2)合计给定月份中发生的所有违规行为。为了删除无关的行,我们使用下面的代码删除与非暴力犯罪相关的行和包含空条目的行

现在我们需要合计每个月的暴力犯罪。在此之前,有几件事需要做。

首先,对于一些数据文件,与进攻类型相关的字符串包含额外的空格,需要清理。下面的代码将完成这个任务。

第二,我想重新格式化事件日期的存储方式,因为我不想在演示如何将数据分成多列的同时使用 Pandas 的时间戳对象。下面的代码有两个函数:第一个函数将日期转换成数字格式,而第二个函数将数字信息拆分成年份和月份列。第二个函数也会删除缺少日期值的行。

我们的数据清理操作的最后一步涉及总结给定类型的所有违例,并将它们存储在输出数据帧中。下面的函数 append_monthly_sum 实现了这一点:

将所有这些放在一起,我们创建一个名为 data_collection.py 的文件来执行上述步骤。首先,我们导入库和函数,然后创建一个空的 Pandas 数据框架,并遍历目录中的所有数据文件

在循环内部,对于目录中的每个文件(对应于当月发生的犯罪统计数据),我们调用上面定义的函数

一旦所有月份都被添加到输出数据帧中,我们就可以使用 to_pickle 命令将数据帧导出到 pickle 文件中。我们现在已经成功清理了数据。

三。使用 matplotlib 进行数据可视化

清理完数据后,让我们绘制九年数据期内每月报告的暴力犯罪事件,以直观地捕捉时间序列动态。我们将使用 matplotlib 库绘制数据。当然,还有更好的开源绘图库。特别是,我发现库有更广泛的功能,更简单的语法和更漂亮的自然外观。但是,在写的时候,我用的是 matplotlib。

在进入这个数据可视化步骤的最终代码版本之前,让我们先来看一下每月攻击数据的图表。

从 2009 年 6 月到 2018 年 5 月德克萨斯州休斯顿每月报告的攻击次数

我们可以看到,每个月的数据都有很大的波动。使用移动*均线来消除这些波动会更容易确定数据的总体趋势。为了查看原始数据和*滑趋势,我绘制了月度数据和移动*均值。

下面是计算一个名为 data 的数组的移动*均值的函数,该数组带有大小为 w_sizen _ w 个窗口。

下面是针对给定犯罪类型绘制月度和移动*均数据的函数:

我们将所有内容放在一个名为 data_visualization.py 的文件中,该文件简单地循环所有暴力犯罪类型并应用该函数。

在名为 Photopea、的免费在线照片编辑器中稍加欺骗,插入一个图例,这里是每种暴力犯罪类型的最终情节。

****

数据可视化的全部目的是获得关于整个时间序列数据集的直觉。事实上,上面的图表有助于我们确定每种犯罪类型发生的总体趋势。以上情节讲述的故事是:

(1) 袭击事件在 2009 年 6 月后的 80 个月开始的快速增长期之前,下降了最初水*的三分之一。

谋杀案在整个九年期间大致保持不变。然而,前 60 个月有所下降,随后又有所上升。

在前 70 个月里,强奸案基本保持不变。之后,每月的事件数量急剧增加,到 2018 年 5 月,几乎是初始值的两倍。这一趋势令人担忧,需要调查其根源

在最初的两年里,的抢劫案几乎减少了一半。随后,它们反弹,并以略低于最初月值的价格稳定下来。

可视化不同的 ML 模型如何在特征空间中操作

原文:https://towardsdatascience.com/visualizing-how-different-ml-models-operate-in-the-feature-space-c6caa8a96375?source=collection_archive---------44-----------------------

直观地理解每个机器学习模型的本质

我记得当我学习机器学习模型时——KNN、逻辑回归、SVM、决策树等等——我只学习了理论。因为所有这些算法都涉及大量的数学,大多数人只学到了肤浅的理论。但是,往往对一个模型的理解还不够深入,理解不了算法的本质。

每个机器学习模型如何在特征空间中操作可以用三个机器学习问题来可视化——识别聚类、环带问题和棋盘问题。通过这些可视化,将实现对每个机器学习模型如何在特征空间中操作的更深入理解。

所有人物由作者创作。

识别集群

在这个问题中,每个机器学习模型必须将一个二维点分类到五个聚类中的一个,标记为 0 到 4。

决策树算法创建一个规则系统,将特征空间分成几个区域。该算法划分特征空间的一个直接引人注目的方式是,它创建了几个“不自然”的区域,因为决策树算法创建了水*和垂直线条的复杂系统,而不是线条清晰。这可以归因于算法用来划分空间的规则系统——例如,具有 0 < y < 5 和-6 < x < -1 的数据点。

随机森林算法类似于决策树分类器,但是区域的组织更加精确。而决策树算法将中左区域中的一段空白空间分类为类别 2(绿色),即使它确实属于任何区域。因为随机森林算法包含几个决策树的智慧,所以区域被更好地划分,但也更详细,以捕捉已经复杂的模型集合的更大复杂性。

支持向量机(SVM)算法的性质决定了比决策树和随机森林算法更*滑的线,在决策树和随机森林算法中,对角线实际上不是线,而是非常复杂和长的垂直和水*移动序列。因此,它实现了随机森林的目标,而没有增加方差(过拟合)。

K-最*邻算法类似于随机森林算法,但由于其算法本质上严重依赖于少量的唯一数据点,因此方差增加了。虽然在其他机器学习问题上,KNN 可能并不强大,但它在识别几何轮廓清晰的聚类方面似乎表现不错。

六种流行的机器学习算法的并排比较很能说明每种算法在特征空间上如何操作的本质。

环形问题

在环带问题中,分类器必须区分环带内的区域和环带外的区域,其中环带由两个圆定义。成功解决环形问题的模型可以处理非线性数据和同类的分离区域。

正如前面在聚类识别问题中所看到的,决策树试图仅使用由严格的水*线和垂直线界定的区域来重新创建环。它的许多异常,包括在右上角断开。这是决策树过度拟合能力和偶尔无法识别看似明显的模式的一个强有力的可视化表示。

随机森林算法可以通过利用大数定律的导数来避免这种缺陷,并通过增加集合中投票者的数量来提高准确性和理解性。很明显,随机森林算法认识到了环的连续性——然而,环周边的颗粒噪声表明该算法缺乏泛化能力。

KNN 算法能够形成环的形状,但是外部和内部参数中的噪声细节再次显示了对数据点的过度依赖和缺乏理解。SVM 同样理解环带的连续性,并且几乎完美地描绘了环带的内周。即使角点是线,但看数据,也不能怪算法画了线性边界。

逻辑回归和朴素贝叶斯在环带问题上都失败了,显示出太多的偏差和太少的方差。两种算法都将整个特征空间归为一类。

环空问题模型的横向比较;

棋盘问题

棋盘问题是一个高方差问题,其中二进制类在棋盘空间中交替出现。

决策树、随机森林和 KNN 算法都是非常高方差的算法,展示了基于给定数据构建棋盘的强大能力。但是,请注意,他们无法将棋盘图案推广到任何大小的棋盘——在棋盘的顶部和右侧,颜色一致的矩形向前扩展到无穷远。

应该注意到 SVM 在高方差问题上表现不佳。由于 SVM 只能分配有限数量的支持向量,它能做的最好的事情就是将棋盘空间分成四个区域。

与环形问题一样,逻辑回归和朴素贝叶斯在棋盘问题上失败,预测整个棋盘的一个类。与 SVM 一样,这些低方差算法在需要如此多复杂区域划分的任务中失败了。

这些算法中没有一个能够有效地划分棋盘并推广到比训练空间更大的空间。神经网络已经能够在这方面显示出希望;也就是说,在例如 20×20 的棋盘上进行训练,并且能够在例如 40×40 的棋盘上继续该模式。棋盘问题的一个解决方案是画对角线,这是一种神经网络能够识别的模式。

棋盘问题算法的并列比较;

感谢阅读!

希望这些来自三个完全不同的问题的可视化能够说明每个算法的本质,以及它如何划分特征空间以实现减少错误的目标。

创建这些问题和其他合成数据问题的代码和解释可以在这里找到。

识别星团代码圆环问题棋盘问题

使用 Python 中的桑基图可视化应用内用户旅程

原文:https://towardsdatascience.com/visualizing-in-app-user-journey-using-sankey-diagrams-in-python-8373a7bb2d22?source=collection_archive---------3-----------------------

应用程序开发人员和营销人员 DIY 指南

TL;DR: Sankey 图可以在二维空间显示多种类型的数据,这使它们成为可视化您的应用程序或网站用户旅程的一个很好的工具。本文将帮助您开始用 Python 构建自己的 Sankey 图表(在此 要点 中找到代码)。

盯着图表想知道你应该从中得到什么是令人沮丧的。就数据类型而言,可视化越恰当,受众就越容易理解数字背后的故事。并且可以推断的信息越丰富。

作为领先的游戏应用移动广告公司 Adikteev 的数据分析师,我一直在寻找一种方法来展示我们客户的应用内用户旅程,Sankey diagrams 是实现这一目标的绝佳数据可视化工具:

  • 像任何组织或层次结构图一样,Sankey 图可以表示一组节点之间的顺序关系。如果不是按时间顺序排列的不同步骤或阶段之间的关系,那么什么是用户旅程呢?
  • 桑基图的每个节点之间的链接宽度与流量成比例,查看者可以一眼看出完成特定旅程的用户比例。

Sankey 图可以在两个维度上显示不同的数据类型:节点的数量和链接的宽度。在用户旅程的情况下,节点的数量可以传递应用内事件的数量和时间顺序信息,链接的宽度可以显示从特定应用内事件转移到另一个应用内事件的用户比例。

更一般地说,桑基图可用于绘制网站流量、工厂能源流量……甚至拿破仑的俄罗斯战役地图:

查尔斯·密纳德绘制的拿破仑 1812 年灾难性的俄国战役地图。作为一个法国人,我不得不在文章中提到拿破仑。

当涉及到用户旅程分析时,这些图表可以让您一目了然地确定哪些是最频繁触发的事件,以什么顺序触发,或者从操作 A 到操作 b 有什么不同的路径。这些是营销人员、决策者或您的客户可能感兴趣的信息。

但是当构建具有三个或更多节点级别的 Sankey 图时,事情会变得混乱。您不希望花费数小时来绘制点并手动链接它们,如果您需要分析多个旅程或定期更新分析,就更是如此。在处理大型数据集时,Python 非常方便,两个 Python 库可以在这里帮助我们:

  • Pandas:用于数据分析的最著名和最常用的 Python 库之一。如果你不熟悉熊猫,但对 SQL 有一些概念,我推荐这篇伟大的文章
  • Plotly :一个 Python 图形库,允许创建交互式的、出版物质量的图形。

本文的其余部分是使用 Pandas DataFrames 和 Plotly 的 Sankey graphing object 在 Python 中进行自己的用户旅程分析的分步指南。

使用 Pandas 和 Plotly 在 Python 中绘制用户旅程的快速指南

还在吗?太好了!

我们将描绘一个非常简单的应用程序的用户旅程。为了清楚起见,这个应用程序只包含 4 种类型的事件:installsopenssignuppurchase

这是在安装后用户旅程的第四个应用内事件中截断时的样子:

如果您尝试将鼠标悬停在链接和节点上,您会看到您可以获得更多关于传入和传出流的详细信息,以及从一个事件到另一个事件的*均时间。

要完成本次研讨会,您需要:

  • Python 3.6 安装完毕;
  • Plotly python 包:我们将使用 plotly.graph_objects 来创建图表;
  • Pandas :我们将使用 Pandas 的 DataFrames 属性和一些常用的 Pandas 函数;
  • 或者,您可以安装 Seaborn 和 Plotly 的 chart_studio 包。 chart_studio 会让你发布你的图表,而 Seaborn 会让你生成酷酷的调色板来定制你的图表。

你需要一些数据。你会在这里找到一组原始数据来帮助你开始。这个数据帧的头部看起来像这样:

我们将在图表中加入以下信息:

  • 用户旅程的每个应用内事件:图表的节点将代表所有应用内事件,从安装到第 n 个事件。在这里,我们将进行到第 10 个事件。
  • 每个用户的事件漏斗:每次我们看到一个用户完成了一个应用内的事件,我们会把这个事件和他之前的事件联系起来。我们将只查看安装程序的数据,这样每个用户的第一个事件就是一个安装事件。随着我们观察到更多的用户完成同一系列的应用内事件,链接的宽度将会增加。
  • 两个事件之间的*均时间:我们还将计算每个用户的每个事件之间的时间,以便能够计算漏斗的每个步骤之间的*均时间。

本教程的第一步是准备和清理数据集:

  • 删除time_install列,在event_nametime_event列增加虚拟install事件;
  • 在新的rank_action列中计算每个事件在用户级别的排名;
  • 增加next_actiontime_to_next action列;
  • 在本教程中,我们将只保留每个用户第 10 个事件之前的行,但是如果您愿意,可以随意保留更多的事件!

您现在应该有一个新的数据帧,如下所示:

Plotly 的 Sankey 数据结构由两个 Python 字典组成:nodelinklink dict 将四个 Python 列表作为参数:

  • source:每个流的源节点列表。为了让每个事件流都有一个源,我们需要将每个事件的唯一索引和每个事件等级的唯一索引添加到这个列表中。
  • target:目标节点列表。我们将使用next_event列将每个源事件映射到它的目标事件。
  • value:包含每个流量的流量信息的列表。每次我们将一个源映射到一个目标时,我们都会进行计数,并将这个计数添加到value列表中。
  • label:悬停每个链接时显示的元数据列表。这里,我们想知道从一个源事件到一个目标事件的用户数量,以及他们这样做所花费的*均时间。

node字典采用以下两个参数:

  • label:包含节点名称的列表(在我们的例子中,是事件的名称);
  • color:包含节点颜色信息的可选列表。

查看 Plotly 的文档以了解关于每个参数的更多信息。

首先,我们将在用户旅程的每一步为每个事件创建一个唯一的source_index,记录每个事件的名称。Python 字典可以做到这一点,看起来会是这样的:

1: {
    'sources': ['install'], 
    'color': [(80, 190, 151)],
    'sources_index': [0]
  },
2: {
    'sources': ['signup', 'purchase', 'reopen'],
    'color': [(228, 101, 92), (191, 214, 222), (252, 200, 101)],
    'sources_index': [1, 2, 3]
  },
3: {
    'sources': ['reopen', 'purchase', 'signup'],
    'color': [(252, 200, 101), (191, 214, 222), (228, 101, 92)],
    'sources_index': [4, 5, 6]
  }
}

第一级键是每个事件的等级。排名#1 只包含install作为来源,因为我们只查看新安装者的数据。

我们存储一个唯一的source_index,而不是事件的名称,因为事件在旅程中可能会出现多次。我们还为每个事件赋予了一个独特的颜色,并将这个 dict 命名为 nodes_dict。

下面是实现这一点的脚本:

然后,我们需要计算漏斗的每一步(即每一个rank_event),每个用户从一个源到一个目标有多少次,并使用我们的time_to_next列记录花费了多长时间。

这里,Python 字典将再次完成这项工作——这次我们将把它命名为 links_dict 。第一级键将是我们的源索引,第二级键是每个流的目标索引。从排名 N+1 的源索引中检索排名 N 的目标索引:

{
  0: { # source index
    1: { # target index
      'unique_users': 14991,
      'avg_time_to_next': numpy.timedelta64(192..., 'ns')
    },
    2: {
      'unique_users': 3879,
      'avg_time_to_next': numpy.timedelta64(393..., 'ns')
    },
    ...
  },
  1: {
    4: {
      'unique_users': 3158,
      'avg_time_to_next': numpy.timedelta64(495..., 'ns')
    },
    5: {
      'unique_users': 4843,
      'avg_time_to_next': numpy.timedelta64(303..., 'ns')
    },
    ...
  },
  2: {
    5: {
      'unique_users': 1426,
      'avg_time_to_next': numpy.timedelta64(14524260000000000, 'ns')
    },
      ...
  },
  3: {...}

对于每个用户的事件序列,我们需要:

  • 1)读入 nodes_dict 序列中每个事件的唯一source_index
  • 2)同样,读取每个事件的下一个事件的source_index(从等级 N+1 的源索引中检索等级 N 的目标索引)并将其存储到一个target_index变量中。
  • 3)检查source_indextarget_index的组合是否已经是 links_dict 的一个键。如果没有,我们将创建它。如果是,我们将增加唯一用户的数量,并添加time_to_next信息。稍后,通过将time_to_next除以独立用户的数量,我们将得到从一个事件到另一个事件的*均时间。

该脚本如下所示:

在能够绘制我们的 Sankey 图之前,我们需要从我们的字典中创建targetssourcesvalueslabelscolors列表,这些列表将作为参数在绘图函数中传递。这可以通过迭代我们的 nodes_dictlinks_dict 轻松实现:

安全了。现在一切都准备好了,我们只需绘制图形。我们可以用linethickness参数给节点添加一些样式,并利用hovertemplate来重新表述悬停的元数据,以满足我们的需求。update_layout Plotly 功能允许我们调整图表的大小、标题文本、字体大小和背景颜色。

如果你想把它发布到网上,你需要创建一个 Plotly 账户并设置你的凭证。如果你想保持离线,你也可以在笔记本或 Chrome 上渲染你的图表。

如果你喜欢这个故事,请在 Medium 上关注我!感谢阅读。

使用 H2O 可视化大型数据集

原文:https://towardsdatascience.com/visualizing-large-datasets-with-h2o-ffe9af40371b?source=collection_archive---------26-----------------------

了解如何使用 H2O 聚合器函数有效地减少数据量。

梅尔·普尔在 Unsplash 上的照片

探索性数据分析是任何数据处理管道的基本部分之一。然而,当数据量很大时,这些可视化就变得模糊了。如果我们要绘制数百万个数据点,就不可能区分各个数据点。在这种情况下,可视化的输出看起来很舒服,但是对分析人员来说没有统计上的好处。研究人员设计了几种方法来驯服海量数据集,以便更好地进行分析。这篇短文将着眼于 H2O 图书馆如何聚集大规模数据集,然后可以轻松地可视化。

目标

H2O 是一个完全开源的、分布式内存机器学习*台,具有线性可扩展性。通过使用 Python 和 R 社区,H2O 支持大多数领先的和广泛使用的机器学习算法。我们将使用一个公开可用的 航空公司数据集 来证明我们的观点。这是一个包含超过 500 万条记录的庞大数据集,非常适合这种情况。

先决条件

在继续操作之前,请确保您的系统上安装了最新版本的 H2O。我们将使用 H2O 3.32——H2O 的最新版本恩斯特·策梅洛命名。关于安装库的详细说明可以在文档的 下载&安装 部分找到。

可视化大数据

现在让我们看看如何利用 H2O 来可视化一个大型数据集。

1️⃣.初始化 H2O 集群

H2O 有一个 R 和 Python 接口以及一个名为 Flow 的 web GUI。然而,在本文中,我们将使用 H2O 的 Python 接口。每个新会话都从初始化 python 客户端和 H2O 集群之间的连接开始。

一个集群是一组协同工作的 H2O 节点;当作业提交到集群时,集群中的所有节点都处理作业的一部分。

要检查是否一切就绪,请打开 Jupyter 笔记本,键入以下内容:

% matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')import h2o
h2o.init()

这是一个本地的 H2O 集群。在执行单元时,一些信息将以表格形式打印在屏幕上,显示节点数量、总内存、Python 版本等。

用户运行 H2O . init()(Python 中)| Image

2️⃣.第一次看数据👀

接下来,我们将导入航空公司数据集并进行快速浏览。

path = "https://s3.amazonaws.com/h2o-public-test-data/bigdata/laptop/airlines_all.05p.csv" airlines = h2o.import_file(path=path)
  • 让我们检查数据集的前十行。
airlines.head()

按作者排列的数据帧|图像的前十行

我们上面所说的叫做 H2O 框架。类似于Pandas’ dataframe 或者R’s data.frame。一个关键的区别是
数据通常不保存在内存中。相反,它位于一个(可能是远程的)H2O 集群上,因此 H2OFrame 仅仅代表该数据的一个句柄。

我们还可以使用如下所示的.describe()命令查看数据集的快速统计摘要

airlines.describe

按作者统计的数据帧|图像摘要

3️⃣.可视化数据

数据集大约有 500 万行和 31 列。现在让我们快速绘制一个Year列的直方图,看看数据中是否有某种模式。

%matplotlib inline
airlines["Year"].hist()

航班频率|作者图片

有趣的是,直方图显示我们没有某些年份的数据。这就是 EDA 带给分析的力量。它有助于快速查明数据集中的异常,如缺失值、异常值等。

接下来,让我们画出DepartureArrival time的对比图,看看两者之间是否有关系。这次我们将绘制一个散点图,这样我们就可以看到各个点。

# Convert H2O Frame into Pandas dataframe for plotting with matplotlibairlines_pd = airlines.as_data_frame(use_pandas = True)plt.scatter(airlines_pd.DepTime, airlines_pd.ArrTime)
plt.xlabel("Departure Time")
plt.ylabel("Arrival Time") 

Scatterplot of DepartureArrival time | Image by Author

如上所述,我们确实得到了一个散点图,但是很难辨别出各个点。大量的重叠点使得很难看出数据中的总体趋势。

H2O 3 号的聚合器救援方法

仅仅查看整个数据没有多大意义。相反,我们可以研究一部分数据,只要它反映了整个数据集的属性。这就是 H2O-3 的聚合器 方法的用武之地。H2O 聚合器方法是一种基于聚类的方法,用于将数值/分类数据集缩减为行数较少的数据集。

“聚合器方法的行为就像任何其他无监督模型一样。您可以忽略列,这些列将在距离计算时被删除。

聚合的输出是一个新的聚合框架,可以在 R 和 Python 中访问。

为什么不能用随机抽样来代替?

这种方法优于随机抽样,因为聚合器将保持数据的形状。随机抽样经常会导致异常值被意外删除。

使用 H2O-3 的聚合器减少数据量

现在让我们将数据的大小减少到 1000 个数据点。我们将首先创建一个包含大约 1000 条记录的聚合框架,然后使用这个聚合框架创建一个新的数据框架。

from h2o.estimators.aggregator import H2OAggregatorEstimator# Build an aggregated frame with around 1000 records
agg_frame = H2OAggregatorEstimator(target_num_exemplars = 1000)
agg_frame.train(training_frame=airlines)# Use the aggregated model to create a new dataframe using aggregated_frame
small_airlines_data = agg_frame.aggregated_frame

让我们来看看新数据帧的尺寸

small_airlines_data.dim[979, 32]

事实上,我们现在有大约 1000 个数据点,但是我们也有一个额外的列。如果您注意到,列数增加了一。让我们看看新数据帧的所有列。

small_airlines.head()

作者新创建的聚合数据帧|图像

如上所述,创建了一个新的计数列。聚合器将异常值保持为异常值,但是将密集的聚类聚集到样本中,并附带显示成员点的计数列。

可视化简化的数据帧

现在让我们想象一下新的数据帧。我们将创建与上面相同的散点图来比较两者。

small_airlines_pd = small_airlines.as_data_frame(use_pandas = True)
plt.scatter(small_airlines_pd.DepTime, small_airlines_pd.ArrTime)
plt.xlabel("DepTime")
plt.ylabel("ArrTime") 

Scatterplot of DepartureArrival time — Reduced dataframe| Image by Author

正如预期的那样,这一步花费的时间要少得多,而且输出的数据点清晰易辨。

正在关闭集群

完成实验后,记得使用下面的命令关闭集群。

h2o.cluster().shutdown()

结论

在本文中,我们研究了一种使用 H2O 聚合器方法将数值/分类数据集缩减为行数更少的数据集的方法。在如上所述的情况下,我们需要可视化大数据集,这种用途是显而易见的。如果你有兴趣深入挖掘,论文— 威尔金森,利兰。“可视化离群值。”(2016)——一定会引起你的兴趣。本文提出了一种新的检测多维异常值的算法,将帮助您理解聚合器方法的功能。

承认

感谢 H2O.ai 的高级客户数据科学家 Megan Kurka ,为本文编写代码。代码已经与 H2O 3 库的其他实现一起公开发布。

可视化线性、脊形和套索回归性能

原文:https://towardsdatascience.com/visualizing-linear-ridge-and-lasso-regression-performance-6dda7affa251?source=collection_archive---------24-----------------------

使用黄砖可视化分析模型性能

亨特·哈里特在 Unsplash 上的照片

机器学习是对通过经验自动改进的计算机算法的研究。根据问题和我们正在处理的数据集,有大量的机器学习算法。

机器学习模型性能是选择特定模型的最重要因素。为了选择机器学习模型,我们可以查看某些指标,这些指标可以帮助我们选择具有最高准确性和最小误差的最佳模型。除了所有这些因素,显示模型性能的最重要因素是不同类型的可视化。我们可以使用预测误差和残差图等可视化工具来选择性能最佳的模型。

Yellowbrick 是一个开源 python 库/包,它扩展了 Scikit-Learn API,使模型选择和超参数调整更加容易。在引擎盖下,它使用的是 Matplotlib。

在本文中,我们将探讨如何使用可视化技术(即使用 Yellowbrick 创建的残差图和预测误差)来可视化线性、岭和套索回归的模型性能。

安装 Yellowbrick

像任何其他库一样,我们将使用 pip 安装 yellowbrick。

pip install yellowbrick

导入所需的库

我们将使用 sklearn 库下定义的线性、岭和套索回归模型,除此之外,我们将导入 yellowbrick 进行可视化,并导入 pandas 来加载我们的数据集。

from sklearn.linear_model import LinearRegression, Lasso, Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from yellowbrick.regressor import PredictionError, ResidualsPlot
import pandas as pd

正在加载数据集

在本文中,我们将探索一个包含跨国公司销售数据的简单数据集,您可以使用任何包含回归相关数据的数据集。让我们加载数据集,看看有哪些属性。

df = pd.read_csv("Advertsisng.csv')
df.head()

数据集(来源:作者)

分割测试和训练数据

为了将数据集分为测试和训练,我们首先需要定义特征和目标变量。定义功能和目标后,我们将使用标准缩放器缩放数据,然后使用 sklearn 拆分数据。

X=df.iloc[:,0:3]
y=df.iloc[:,3]
#Scaling The data
scaler = StandardScaler()
scaler.fit(X)
X = scaler.transform(X)
#Splitting the data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=101)

创建模型可视化

现在我们将创建模型并使用该模型来创建可视化。我们将创建的可视化是:

a.预测误差

预测误差图显示了数据集的实际目标与模型生成的预测值的对比。这让我们可以看到模型中的方差有多大。

b.残差图

在回归模型的上下文中,残差是目标变量的观测值(y)和预测值(ŷ)之间的差,即预测的误差。残差图显示了垂直轴上的残差和水*轴上的因变量之间的差异。

1.线性回归

model1 = LinearRegression()
visualizer = PredictionError(model1)
visualizer.fit(X_train, y_train)  
visualizer.score(X_test, y_test)  
visualizer.poof()

预测误差(来源:作者)

visualizer = ResidualsPlot(model1)visualizer.fit(X_train, y_train)  
visualizer.score(X_test, y_test)  
visualizer.poof()

残差图(来源:作者)

2.套索回归

model2 = Lasso()
visualizer = PredictionError(model2)
visualizer.fit(X_train, y_train)  
visualizer.score(X_test, y_test)  
visualizer.poof()

套索预测(来源:作者)

model2 = Lasso()
visualizer = ResidualsPlot(model2)
visualizer.fit(X_train, y_train)  
visualizer.score(X_test, y_test)  
visualizer.poof()

套索残差(来源:作者)

3.里脊回归

model3 = Ridge()
visualizer = PredictionError(model3)
visualizer.fit(X_train, y_train)  
visualizer.score(X_test, y_test)  
visualizer.poof()

山脊预测(来源:作者)

model3 = Ridge()
visualizer = ResidualsPlot(model3)
visualizer.fit(X_train, y_train)  
visualizer.score(X_test, y_test)  
visualizer.poof()

岭残差(来源:作者)

这就是我们如何为不同的模型创建残差图和预测误差图。通过分析这些图,我们可以选择性能最佳的模型。

在我们数据集的上述图中,我们可以看到,根据我们创建的图,性能最好的模型是线性回归,因此对于这个给定的数据集,我们将使用线性回归进行预测,因为它的准确性高,误差小。

类似地,我们可以将 yellowbrick 用于不同的机器学习模型性能可视化。你可以尝试不同的数据集,找到最适合你的数据的模型,尝试一下,让我知道你对这个故事的反应。

在你走之前

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

使用大查询自由可视化实时大数据源

原文:https://towardsdatascience.com/visualizing-live-big-data-sources-freely-with-big-query-28c9b5ad985d?source=collection_archive---------32-----------------------

构建第一个仪表板的指南

从大数据查询构建您的第一个可视化的指南

来源( Unsplash )

对庞大的数据集进行数据分析需要几个小时

没有付费订阅,我无法找到实时数据源

可扩展性是数据分析中的一个问题。现在大数据时代,分析 Pb 级数据的技能弥足珍贵。但是,我们在大学期间学习的大多数工具是不够的。大多数时候,我们使用小规模数据集,这并不能测试我们扩展解决方案的技能。

想象 MySQL 和 Excel 作为给定的数据源。Excel 是很好的电子表格分析工具,但是它们最多允许 1,048,576 行和 16,384 列。MySQL 可以对超过这些容量的数据集运行查询,但连接、聚合和可视化大型数据集的速度很慢。

为什么我们不把它们*行地分割、聚合和具体化呢?

一个常见的解决方案是设计数据仓库ETL 管道(提取、转换和加载),它们将物化的更小的聚合数据集开发为具有大量处理单元的输入流。

这就是 Hadoop 等 MapReduce 工具试图完成的任务。它通过对数据集进行分片并使用多线程运行操作和聚合来加速这些作业。它适用于大数据,但很难从头开始构建一个健壮的管道。

我们需要开始的是一个工具来编码、重新编译、重新部署和重新运行工作,而不需要大量的努力来构建和维护;一个拥有众多工人的加工中心,具有故障保护功能,可扩展,损耗最小。

欢迎来到谷歌大查询

教程

我将向您展示如何在不到 10 分钟的时间内将 Google BigQuery 公共数据集导入仪表板。

我们将使用实时公共数据集(JHU·科维德数据集)进行实验,这将为您快速介绍如何将该数据集导入仪表板(谷歌数据工作室)。

请随意跟随本教程或直接访问仪表板,在这里您可以复制并亲自尝试。

附言:如果您想要一种简单的方式来开发和部署您的仪表板即服务。我也为 Dash & Plotly 提供一个教程。它们是构建在 Matplotlib 和 Flask 之上的 python 库,是构建 web 应用程序的有用框架。

什么是谷歌大查询

使用 Google BigQuery 访问公共数据集

Google Big Query 是一个完全托管的无服务器数据仓库,可以专注于分析,而不是管理基础架构。它允许您可伸缩地托管您的数据。

Google BigQuery 是由 Google 大表和 Google 云*台组成的企业数据仓库。每个技术层都是无服务器的,可扩展到所有数据大小。从 Excel 电子表格到数 Pb 的流数据,它都能很好地工作。

大查询非常适合大数据,因为它可以自动管理复制的分布式存储。它可以接收多个自定义存储,然后查询大型分析。

BigQuery 是一个分布式数据存储,用于为流式工作流建立数据仓库和数据集市。BigQuery 擅长防止每个数据产品的可配置访问权限层的泄漏。

方便的是,谷歌已经有了实时公共数据集,如 JHU 实时数据连接,供我们查询。

好处

自动扩展大型数据集的计算能力。

BigQuery 连接到 Google 云*台,该*台在一个池中拥有数千个 CPU 来处理请求和作业。

当您执行 BigQuery 时,它会立即赋予您部署每个单元来计算一小部分数据的能力。然后,BigQuery 将这些数据合并在一起并进行聚合。

换句话说,BigQuery 使用类似的 Map Reduce 算法,提供了巨大的集群,而不需要太多的麻烦和配置。全部免费。

托管大量公共实时数据集(犯罪、出租车、COVID 等)。

BigQuery 通过谷歌云公共数据集计划向公众开放。

谷歌已经付费托管这些数据集,并提供这些数据集的公共访问。您可以免费访问每月 1TB 的查询数据集,这些数据集为您的投资组合托管大中型项目。

定期更新实时数据(数据新鲜度)

这有助于您配置将实时数据直接更新到可视化中的频率。

这个想法是为了缩短用户交互和用户影响您的仪表板或分析之间的时间。因此,您可以优化计算能力以及仪表板带来的影响。

例如,如果您关注每天的出租车收入。让它成为每日新鲜感可能是有意义的。但是,如果你关注的是出租车的供给/需求流量。每小时更新一次是有道理的。

使用 BigQuery 公共数据集

首先打开谷歌数据工作室

在“报告”页面上,从模板部分开始。单击空白报告模板。谷歌大查询处理不同的数据集,你可以直接分析并立即加入。

点击 BigQuery

选择 BigQuery

单击公共数据集→我的第一个项目→选择数据集

获取公共数据集 JHU Covid 案例

打开公共数据集,我的第一个项目,搜索 jhu(约翰·霍普斯金大学 Covid 数据集)

确认您的数据字段和类型

获取字段和列

如果你看一看,你会发现有各自类型的字段。这些数据类型包括分类数据、数字数据和顺序数据,默认聚合是所有数字的总和。

调整实时数据馈送频率(数据新鲜度)

在顶部,您可以点击数据新鲜度,然后您可以调整新鲜度。Google 已经为您建立了数据连接,因此您可以直接配置其新鲜度。

操纵数据新鲜度

一旦你完成了。点击右上角的创建报告,进入 Data Studio 网站。这样,您就可以将仪表板连接到一个实时的大型公共数据集进行探索。

最后,您应该会得到以下结果,您可以进一步将其制作成仪表板。

从 BigQuery Covid (JHU)数据集构建数据仪表板

全部免费。

最后的想法

在本教程中,我们学习了 Google BigQuery 获取实时数据集的 3 个最大优势:

  1. 可扩展性:扩展大型数据集的计算能力
  2. 存储库:实时公共数据集(犯罪、Covid 等)的存储库
  3. 数据新鲜度:直接为您的可视化配置实时数据

有了它,您可以将实时数据导入 dashboard,拖放交互式可视化和令人惊叹的样式,并与您的同事和经理轻松分享。

一如既往,如有任何问题,请通过 LinkedIn联系我。如果时间允许,我很乐意回答你的问题。

索利·德奥·格洛丽亚

关于作者

文森特用 ML @ Google 对抗网络滥用。文森特使用高级数据分析、机器学习和软件工程来保护 Chrome 和 Gmail 用户。

除了在谷歌的工作,Vincent 还是《走向数据科学媒体》的特约撰稿人,为全球 50 万以上的观众提供有抱负的 ML 和数据从业者的指导。

在空闲时间,文森特在佐治亚理工学院攻读硕士学位,并为铁人三项/自行车旅行进行训练。

最后,请通过 LinkedIn Medium Youtube 频道 联系文森特

使用 Geopandas 在地图上可视化印度针对女性的犯罪

原文:https://towardsdatascience.com/visualizing-map-of-crime-against-women-in-india-using-geopandas-2d31af1a369b?source=collection_archive---------11-----------------------

本文向我们展示了一种使用 GeoPandas:一个 Python 库在印度地图(或者您可以选择任何国家)上绘制邦或地区统计数据(就像这里使用的一样,即印度针对女性的犯罪)的简单方法。

图片提供:雷纳萨莫拉,[Pinterest 邮报]。于 2020 年 2 月 18 日从https://in.pinterest.com/pin/626563366894685267/检索

简介:

大家好,这篇文章演示了如何在印度各邦的 choropleth 地图上绘制针对女性的犯罪数据。

根据谷歌字典的解释:“choropleth 地图是一种利用预先定义的区域内的阴影、颜色或符号放置的差异来表示这些区域内特定数量的*均值的地图。”

地质公园:

Geopandas 是一个不需要太多代码就可以创建 choropleth 地图的库!它可以将文件作为数据帧读取,这通常称为地理数据帧。地理数据框架很像熊猫数据框架,因此两者通常配合得很好。更多关于 https://geopandas.org/的地质公园

形状文件:

shapefile 是一种简单的非拓扑格式,用于存储地理要素的几何位置和属性信息。shapefile 中的地理要素可由点、线或面(区域)表示。

本文中用于绘制印度地图的带有邦边界的形状文件可以从链接下载,而带有地区边界的形状文件可以从链接下载。

使用 Pip 安装:

您可以使用 pip 安装 Geopandas 库,如下所示:

pip install geopandas
pip install descartes

descartes 是 geopandas 的依赖项,必须显式安装,所以别忘了也安装它。

实施:

我们在 5 个简单步骤中解释了 Python 的整个实现

假设我们有一个名为 state_wise_crimes.xlsx 的 excel 文件,其中包含印度所有的州名以及针对女性的犯罪总数,如下所示:

+-------------------+----------------------------+
|    state_name     | Total Crimes against Women |
+-------------------+----------------------------+
| Andhra Pradesh    |                    15931.0 |
| Arunachal Pradesh |                      384.0 |
| Assam             |                    23258.0 |
| Bihar             |                    13891.0 |
| Chhattisgarh      |                     5720.0 |
| .....             |                      ..... |
+-------------------+----------------------------+

我们按照以下步骤创建 chloropeth 图

第一步:将 excel 文件读入熊猫数据帧:

df = pd.read_excel('state_wise_crimes.xlsx')

步骤 2:读取地理数据框架中带有地区边界的印度地图 shape file:

fp = "Igismap/Indian_States.shp"
map_df = gpd.read_file(fp)

第三步:通过州名连接两个数据帧:

merged = map_df.set_index('st_nm').join(data_for_map.set_index('state_name'))
merged.head()

第四步:为 Matplotlib 创建图形和轴,并设置标题

fig, ax = plt.subplots(1, figsize=(10, 6))
ax.axis('off')
ax.set_title('State Wise Crime against women in India in 2015', fontdict={'fontsize': '25', 'fontweight' : '3'})

第六步:最后,绘制绿色地图

merged.plot(column='Total Crimes against Women', cmap='YlOrRd', linewidth=0.8, ax=ax, edgecolor='0.8', legend=True)

输出: 输出应该是这样的

您还可以使用下面的代码片段将输出保存为图像:

fig.savefig("State_wise.png", dpi=100)

类似地,我们可以使用形状文件一节中提到的形状文件来绘制地区的 chloropeth 地图。您可以从此链接下载包含针对女性的地区性犯罪的 excel 文件。

的输出如下所示:

我们也可以对任何一个邦做同样的事情,就像我对马哈拉施特拉邦所做的那样。
为此,我们可以通过添加一行来使用用于分区可视化的相同形状文件:

map_df = map_df[map_df['NAME_1']=='Maharashtra']

输出如下所示:

Github 链接:

你可以在这里得到完整的代码:

[## yasersakkaf/Visualize-Women-Harrasment-in-India-using-geo pandas

GeoPandas 图书馆的实现,用于可视化印度各邦和各地区的妇女遭遇。…

github.com](https://github.com/yasersakkaf/Visualize-Women-Harrasment-in-India-using-GeoPandas)

总结:

在本文中,我们看到了如何使用 GeoPandas 库来绘制印度的 chloropeth 地图,以描述 2015 年各邦和各地区针对女性的犯罪。

有了合适的数据集和形状文件,我们可以对其中的任何国家或州做同样的事情。

参考文献:

[## 让我们做一张地图吧!利用 Geopandas、pandas 和 Matplotlib 制作 Choropleth 地图

所以你想用 Python 做地图。我们开始吧!

towardsdatascience.com](/lets-make-a-map-using-geopandas-pandas-and-matplotlib-to-make-a-chloropleth-map-dddc31c1983d) [## 什么是 shapefile?

shapefile 是一种简单的非拓扑格式,用于存储的几何位置和属性信息…

desktop.arcgis.com](https://desktop.arcgis.com/en/arcmap/10.3/manage-data/shapefiles/what-is-a-shapefile.htm)

在 R 中使用 ggeffects 可视化边缘效果

原文:https://towardsdatascience.com/visualizing-marginal-effects-using-ggeffects-in-r-4e7fb0569040?source=collection_archive---------10-----------------------

数据集中关键变量边际效应的图解指南。

这是一个众所周知的困境:你知道你的变量 X1 影响你的变量 Y,你可以在回归分析中显示出来,但很难用图形显示出来。原因是还有一个变量影响着 Y,即 X2,只有在考虑了 X2 的影响后,X1 对 Y 的影响才显现出来。因此,你需要一种方法来显示 X1 如何影响 Y,同时考虑 X2 的影响。

这就是边际效应派上用场的地方。它们使您能够显示感兴趣的自变量的变化如何影响因变量,同时将所有其他自变量考虑在内。更具体地说,您可以使用 ggeffects 包来可视化关键变量的边际效应。

下面的教程将使用 base R 中可用的 sales 数据集。它包含教授的薪水数据和其他几个会直观地影响他们薪水的变量。

也许有人拿着他或她的薪水?亚历山大·密尔斯在 Unsplash 上拍摄的照片

您只需输入以下命令就可以加载它。

df=Salaries

我们想回答这个数据集中的关键问题:教授的性别会影响他们的薪水吗?

天真地,人们可以通过简单地运行下面的回归模型来尝试回答这个问题:

fit1=lm(salary~sex,df)
summary(fit1)

单看产量,似乎性别影响一个教授的工资。此外,当绘制性别对工资的影响时,这种影响似乎是显著的。

#install and load ggplot
install.packages("ggplot2")
library(ggplot2)#plot the relationship
ggplot(df,aes(y=salary, x=sex))+
  stat_summary(fun.y="mean", geom="bar",position="dodge")+
  stat_summary(fun.data = mean_se, geom = "errorbar", position="dodge",width=.8)+
  labs(
    x="Sex",
    y="Salary",
    title="The Effect of Sex on Salary"
  )

性别对工资的影响

然而,问题是:是性别导致了这种差异,还是性别与更直接的薪水预测因素相关?这个问题在回归中很容易回答。一种方法是增加更多的协变量来检验是性别还是其他原因导致了这种差异。

fit2=lm(salary~sex+yrs.since.phd+yrs.service+rank+discipline,df)
summary(fit2)

第二次回归的输出

正如你所看到的,性别的边际效应现在是微不足道的,这意味着在这个数据集中,性别不是工资的实际预测因素,而是与数据集中的其他变量之一相关,这些变量可以概括为资历和学术学科的指标。

所以我们知道性别不是工资的重要预测因素。但是如果我们要绘制性别和薪水之间的关系——如上图所示——看起来好像性别是一个实际的薪水预测因素。如果我们想在考虑所有其他协变量后,绘制性别对工资的实际影响——即绘制边际影响——会怎么样?这就是 ggeffects 发挥作用的地方。

因此,我们安装并加载 ggeffects,如果我们还没有这样做的话。

install.packages("ggeffects")
library(ggeffects)

然后,我们使用 ggeffects 包中的 ggpredict 函数,预测数据集中每个性别的边际效应。我们将输出保存为一个整洁的数据帧,命名为 dummy。

dummy=ggpredict(fit2, terms = "sex")

然后,我们使用 ggplot 来绘制这些边际效应。

ggplot(dummy, aes(x=x, y=predicted)) +
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high), alpha = .9,position = position_dodge())+
  labs(
    x="Sex",
    y="Salary",
    title="The Marginal Effect of Sex on Salary"
  )+scale_x_continuous(breaks=c(1,2) ,labels = c("Female", "Male"))

性别对工资的边际影响

在控制了所有其他预测因素后,我们现在可以绘制出性别对工资的实际边际影响。

觉得这个故事有趣?在 Medium 上关注我看我的其他故事!

使用热图可视化多元线性回归

原文:https://towardsdatascience.com/visualizing-multiple-linear-regression-with-heatmaps-3f69f1652fc4?source=collection_archive---------35-----------------------

图片来自 PixabayDavidRockDesign

介绍

不管你对数据科学和统计世界有多了解,在某个时候,你可能至少听说过回归。作为多元回归快速课程的前奏,您应该对简单线性回归有所了解。如果你不是,你可以从这里开始!否则,让我们开始多元线性回归。

我们在简单线性回归和多元线性回归之间的区别仅仅是帮助我们理解因变量的解释变量的数量。

多元线性回归是数据科学家非常流行的统计技术,也是数据科学家使用的许多更复杂方法的基础。

多元线性回归

在我关于简单线性回归的帖子中,我给出了使用一个数字变量——*方英尺来预测房价的例子。

这篇文章与我的另一篇关于多元线性回归的文章非常接*,区别在于解释因变量的变量的数据类型。那篇帖子用一个数字&一个分类变量解释了多元线性回归;也称为*行斜坡模型。

下面我们将介绍的内容将让我们深入了解一个多元线性回归模型,在该模型中,我们使用多个数字变量来解释我们的因变量,以及我们如何有效地利用热图进行可视化。尽情享受吧!

让我们建立一个回归模型

类似于我们在前面提到的文章中所构建的,我们将创建一个线性回归模型,其中我们添加了另一个数字变量。

我们正在处理的数据集是西雅图房价数据集。数据集的记录级别是按房屋和详细价格、*方英尺数、床位数、浴室数等。

在这篇文章中,我们将尝试通过数据集中其他数值变量的函数来解释价格。

说到这里,让我们开始吧。与其他帖子类似,我们使用sqft_living来预测price,只是这里我们将添加另一个变量:bathrooms

fit <- lm(price ~  sqft_living + bathrooms,    
          data = housing)
summary(fit)

回归模型中包含各种数字解释变量在语法上和数学上都很简单。

可视化限制

虽然从技术上讲,您可以将数字变量一个接一个地分层到同一个模型中,但这很快就会变得难以可视化和理解。

在我们的模型中,我们需要评估三个独立的维度。

接下来,我们将回顾不同的方法来可视化越来越复杂的模型。

打开热图

我们可视化的目的是理解给定变量之间的相互关系。对于两个数值变量,简单的散点图是非常直观的选择。目前,我们包括第三个变量,事情有点混乱。

我们将回顾的第一个选项是热图。这种覆盖散点图的可视化形式很好地传达了我们的模型输出如何随着解释变量组合的变化而变化。

首先,我们需要创建一个网格,将两个变量的所有独特组合结合起来。这将是关键,因为我们希望对我们的模型如何随解释变量变化有一个详尽的了解。

一旦我们做到了这一点,我们就可以给它们中的每一个分配预测,给我们一个清晰的指示,表明我们对数值变量的所有潜在组合的预测。

下面我将使用 table 函数来了解值的范围,以便创建序列,如您在下面的代码中所见。或者,您也可以将给定变量的所有唯一出现的情况传递给 expand.grid 函数,比如 so data.frame(table(housing$sqft_living))[1]

我们使用 expand.grid 创建一个包含各种变量组合的数据框架。

table(housing$bathrooms)
table(housing$sqft_living)all_combinations <- expand.grid(sqft_living = seq(370, 13540, by = 10), bathrooms = seq(0.75, 8, by = 0.25))

现在我们有了数据框架,让我们使用broomaugment函数生成预测。

combos_aug <- augment(fit, newdata = all_combinations)

让我们开始视觉化。

housing %>%
ggplot(aes(x = sqft_living, y = bathrooms))+
  geom_point(aes(color = price))

在这里,我们看到了解释变量之间的分散,颜色梯度分配给因变量价格。

让我们添加我们的瓷砖。我们看到与上面相同的代码,我们只是现在包含了带有模型预测的geom_tile函数,.fitted

housing %>%
ggplot(aes(x = sqft_living, y = bathrooms))+
  geom_point(aes(color = price))+
  geom_tile(data = combos_aug, 
            aes(fill = .fitted), alpha = 0.5)

如您所见,我们可以看到一个更明显的梯度在 x 轴上穿过sqft_living。也就是说,我们还可以看到 y 轴上bathrooms的一些梯度。同样,我们可以看到,在图表的右下方,点颜色渐变所显示的价格要暗得多/低得多。

结论

创建一个包含大量不同解释变量的模型非常容易。这是否会对给定的变量产生更深的理解是个问题。虽然这是一个简单的例子,但我希望它能对你理解一些更复杂的多元线性回归模型有所帮助。

在这篇文章中,我们讨论了以下内容:

  • 多元线性回归定义
  • 构建 mlr 模型
  • 可视化/解释限制
  • 将热图与散点图结合使用

如果这有帮助,请随时查看我在datasciencelessons.com的其他帖子。祝数据科学快乐!

三维可视化多元回归

原文:https://towardsdatascience.com/visualizing-multiple-regression-in-3d-a1e7aba7a007?source=collection_archive---------30-----------------------

如何更好地理解高维数据集?

图片由 Mediamodifier 来自 Pixabay

介绍

不管你是否接触过数据科学&统计学,至少,你很可能听说过回归。在本帖中,我们将讨论多元回归,作为前兆,你肯定希望对简单的线性回归有所了解。如果你不熟悉,你可以从这里开始!否则,让我们开始多元线性回归。我最*谈到了用热图可视化多元线性回归,如果你已经读过这篇文章,请随意跳到这篇文章的建模部分,在那里我们将构建我们的新模型,并介绍plotly包和三维可视化。如果你还没有读过,这是另一个可视化多元回归的有用方法。

多元线性回归

我们在简单线性回归和多元线性回归之间的区别仅仅是帮助我们理解因变量的解释变量的数量。

多元线性回归是数据科学家非常流行的统计技术,也是数据科学家使用的许多更复杂方法的基础。

在我关于简单线性回归的文章中,我给出了一个用一个数字变量——*方英尺来预测房价的例子。

这篇文章是我们探索线性回归不同实现的系列文章的一部分。在我们探索*行斜坡模型的帖子中,我们创建了一个模型,在这个模型中,我们使用*方英尺来预测价格,以及它是否是一个滨水房产。这里我们将做一些类似的事情,但是我们将使用多个数字输入来创建我们的模型。

让我们开始建模

类似于我们在前面提到的文章中所构建的,我们将创建一个线性回归模型,其中我们添加了一个新的数值变量。

我们正在处理的数据集是西雅图房价数据集。数据集的记录级别是按房屋和详细价格、*方英尺数、床位数、浴室数等。

在这篇文章中,我们将尝试通过数据集中其他数值变量的函数来解释价格。

说到这里,让我们开始吧。与我们之前构建的类似,我们使用sqft_living来预测price,只是这里我们将添加另一个变量:sqft_basement

fit <- lm(price ~  sqft_living + sqft_basement,    
          data = housing)
summary(fit)

回归模型中包含各种数字解释变量在语法上和数学上都很简单。

可视化限制

虽然从技术上讲,您可以将数字变量一个接一个地分层到同一个模型中,但这很快就会变得难以可视化和理解。

在我们的模型中,我们需要能够评估三个独立的维度。

正如我之前提到的,这里我们将使用plotly的 3d 绘图工具来加深理解。

让我们和plot_ly一起玩吧!

让我们首先可视化sqft_livingprice来熟悉语法。

plot_ly(data = housing, x = ~sqft_living, y = ~price, opacity = 0.5) %>%
  add_markers()

如你所见,语法与 ggplot 没有太大的不同。首先指定数据,然后跳入美学,而不必明确声明它们是美学。上图是一个简单的二维散点图。

让我们在三维空间中想象一下!

plot_ly(data = housing, z = ~price, x = ~sqft_living, y = ~bathrooms, opacity = 0.5) %>%
  add_markers()

类似于我们之前所做的,我们只是将price移动到 z 轴,现在包括了sqft_basement。这个绘图工具的有趣之处在于它不是静态的,你可以点击并拖动旋转你观察绘图的角度。显然这里你只是看到了一个截图,但是让它在你自己的机器上运行来体验一下plotly的全部灵活性。当您在 RStudio 中运行这个命令时,您的Viewer窗口将会填充这个可拖动/可移动的可视内容,这有助于解释更大维度的数据集。

添加*面

当从二维转移到三维时,事情就变了。如果你有线性代数的背景,这可能会引起共鸣。简单来说,如果你有一个单一的维度,那么你就有一个点。如果你有两个维度,你有一条线。如果你有三个维度…你就有一个*面

考虑到这一点,让我们用一个*面来形象化我们的多元线性回归模型。

首先,我们需要创建一个矩阵,其中包含所有可能的模型输入以及每种情况下的模型预测。

下面我为我们的xy创建一个向量。然后我们将它们传递给outer函数,在这里我们声明将它们传递给通过拟合我们的模型定义的线性回归函数的操作。

x <- seq(370, 15000, by = 10)
y <- seq(0, 15000, by = 10)plane <- outer(x, y, function(a, b){fit$coef[1] + 
    fit$coef[2]*a + fit$coef[3]*b})

现在我们有了我们的飞机,让我们把它添加到我们的视觉。

plot_ly(data = housing, z = ~price, x = ~sqft_living, y = ~sqft_basement, opacity = 0.5) %>%
  add_markers() %>%
  add_surface(x = ~x, y = ~y, z = ~plane, showscale = FALSE)

再说一次,你必须自己跳进去和plotly一起玩。

你做到了!您已经将一个*面添加到您的 3D 散点图中,该*面代表我们的回归公式与不同输入sqft_lot & sqft_basement之间的关系,但是我们仍然有一个问题…这如何帮助我们?

你曾经在你的 2D 散点图上加过回归线吗?如果是,意图是什么?

你可以在你的图中添加一条线来表示“最佳拟合”是什么样子,但是对于给定的x值,我们可以预测y,这也是很有用的。飞机给了我们这一切。对于xy的给定值,z是什么?

结论

我们在短时间内做了很多工作。多元线性回归模型会很快变得越来越复杂。我希望将此功能添加到您的工具集中,您将能够更好地理解您正在处理的数据和模型。给一个模型加载我们能接触到的每一个变量并不是非常困难,但是它确实提出了这样一个问题:它是否解决了我们的目标。它是否有助于我们在参与建模过程时开始获得的那种理解?

在短短的几分钟内,我们讲述了:

  • 多元线性回归定义
  • 构建 mlr 模型
  • 可视化/解释限制
  • 使用 3D 绘图和*面来解释我们的数据和模型

如果这有帮助,请随时查看我在 datasciencelessons.com 的其他帖子。祝数据科学快乐!

用李萨如曲线可视化音乐音程

原文:https://towardsdatascience.com/visualizing-musical-intervals-with-lissajous-curves-351248ee30ff?source=collection_archive---------47-----------------------

可视化确定完美/不完美的音乐音程

照片由马尔特·温根Unsplash 上拍摄

我喜欢音乐——弹吉他总能让我从日常生活中的压力中解脱出来。音乐最神奇的一面是,多个独立的音符是如何组合成一个和弦的——这个和弦比单个部分的总和还要大。但是是什么让某些和弦听起来和谐而其他的不和谐呢?最终,它归结为和弦中音符频率的比率。为了看到这一点,我们可以使用一个叫做李萨如曲线的函数。

李萨如曲线

以朱尔斯·安托万·李萨如命名的李萨如曲线由以下参数方程定义:

使用上述等式绘制的曲线对 ab 的值非常敏感,本质上是一种不协调的度量。比率 a/b 也在视觉上对应于李萨如曲线中的叶片数。此外,当这个比例不合理时,图将出现旋转。让我们看看如何使用它来可视化不同的和弦音程。

在 Python 中定义函数

对于这个分析,我们将用 Python 创建可视化,所以首先我们应该导入相关的包:

如果你使用 Jupyter 来生成你的动画,你需要添加行%matplotlib notebook来使用交互式后端。

现在,我们可以为我们的李萨如曲线定义函数——我们将使用简化形式的方程,其中系数 AB 都将设置为 1,我们将设置𝛿 = 0,因此在 x 项中没有偏移。

在我们的函数中,输入t将是我们传递给sincos的时间值数组,而ab将是我们之前讨论过的常数,它们代表了不协调的度量。

让我们对常规参数进行一些调整——我们将移除四个轴棘并更改绘图的字体属性:

我以前写过一篇文章在这里关于 Python 动画情节的基础,但是我们将快速浏览这里的所有步骤。首先,我们要创建一个空图,并创建一个对该图的变量引用,然后我们可以使用它在动画过程中更新数据。

现在,我们需要创建动画函数——该函数将索引i作为输入,并在每次调用时使用该信息更新绘图。在我们的例子中,我们将改变基于i的值绘制的时间间隔,这样不和谐和“不稳定”的图将随着时间范围的变化而发生视觉变化。在下面的代码中,我已经将 ab 的值都设置为等于 1。

在上面的例子中,在第一次迭代中,我们绘制从 0 到 8π的t值,随后的迭代从 8π到 16π,依此类推。我们实际上是在绘制一个时间尺度,并在更新动画时滑动整个时间尺度。

最后,我们可以用下面的代码调用动画:

frames —我们使用range(10)来传递来自[0,9]的值列表

interval —我们将每 100 毫秒移动一次时间刻度

repeat —我们将不断重复播放动画

为了美观,我们将去掉 x 和 y 刻度标记,并将 x 轴标签设置为代表我们选择的 ab 的值。

xlabel中的\n是一个转义换行符——通过添加这些字符,我们将在单独的行上打印出 ab 的值。因为我们有一个多行轴标签,所以我们可以添加以下行来确保整个标签可见:

现在,对于 a = b = 1 这个简单的例子,我们得到如下结果(记住这实际上是一个动画!).

writer —用于创建动画的后端(为此我们使用pillow)

fps —每秒帧数(因为我们每 100 毫秒调用一次 animate,所以我们应该将这个值设为 10 来匹配)

dpi —用于制作动画的图像分辨率(每英寸点数)

当我们的两个频率相同时,我们得到的是一条不随时间变化的线。请记住,“看起来更简单”的数字是 ab 的低整数比的结果,在这种情况下,它们都等于 1。此外,由于该比率是一个有理数,我们不希望该图随时间旋转。

音乐频率的第二个自然泛音是它的倍频,也称为八度。通过将 a 的值改为 2,我们得到如下动画:

由于 ab 的比值现在是 2,我们的李萨如曲线中有 2 个凸角,并且由于 a/b 是有理数,我们没有旋转。在古希腊,毕达哥拉斯就曾使用这样的“纯音程”来调整音符,以产生一个音阶。

毕达哥拉斯调音

毕达哥拉斯调音系统使用两个纯音程来确定整个音阶:八度音阶(2:1)和完美五度音阶(3:2)——你可以在本文这里找到更多信息。通过反复应用这两个比率,我们可以生成音阶中的所有音符。举个例子:

从基频、八度、五度开始:

(1/1), (3/2), (2/1)

相对于当前五度音程寻找新的完美五度音程:

(3/2) * (3/2) = (9/4)

因为这个值大于我们的八度音程(2/1),我们除以这个比率(2)使它回到我们的音程:

(3/2) * (3/2) *(1/2) = (9/8)

我们现在的规模是:

(1/1), (9/8), (3/2), (2/1)

其中(9/8)现在代表一个新音符——大调第二音符

我们一遍又一遍地继续这个过程,直到我们生成了音阶的所有音符——只看大调音阶的音符,我们得到:

根: (1/1)

大调第二: (9/8)

大调第三: (81/64)

完美 4 档 : (4/3)

完美 5 档 : (3/2)

大 6:(27/16)

大七: (243/128)

八度: (2/1)

我们可以通过使用支线剧情和绘制每个动画来可视化所有这些笔记!我们将制作如下的支线剧情:

add_subplot(xyz)x是行数,y是列数,z是感兴趣的支线剧情(从左上角开始,逐一遍历每行)

现在,我们的动画函数必须同时更新所有的支线剧情:

勾股调音中主要音阶音程的李萨如曲线

还是那句话,上面的情节都是动画的,所以我们可以看到没有一个是“不稳定”的。然而,正如我们之前看到的,曲线的复杂性代表了整个数字比率,我们看到大 3 度和大 7 度的复杂性很高。虽然后一个音程听起来不和谐(因为它们对应于两个连续的半音),但大三度应该不会。其实这其实是对使用毕达哥拉斯调音音阶的主要批评!大三度音是如此的不协调,以至于会导致大和弦听起来不和谐。

性情*等

通常用来解决这个问题的调音系统是十二音*等律,其中相邻音符之间的比率不再由纯音或整数比率来定义,而是相等的。为此,我们取 2 的十二次方根,因为每 12 个半音频率加倍(八度)。

使用这个系统的结果是,因为我们不再使用纯音音程,所以我们所有的音符都只是稍微走调,不像毕达哥拉斯系统,在毕达哥拉斯系统中,许多音程都是完美的,一些大整数的比率会导致不和谐。然而,相对音程可以提供比毕达哥拉斯的和弦听起来不那么不和谐的和弦。

现在,让我们像对毕达哥拉斯调音一样,用*等的音律来想象大调音阶。我们需要构建大调音阶的半音如下:

词根:原始频率

大调第二:第二半音

大调第三:第四半音

全四度:五度半音

全五度:七度半音

大调第六:第九半音

大调第七:第十一半音

八度:第十二个半音(或倍频)

下面是我们如何在动画函数中实现它的一个例子:

勾股调音中主要音阶音程的李萨如曲线

我们看到八度以外的所有音程现在都不稳定了!即使是*均律系统中的五度音程也不再是完美的五度——然而,我们注意到大三度现在比在毕达哥拉斯调音的情况下不那么不和谐了。这就是为什么对于像钢琴这样的乐器来说,在飞行中微调音符是不可能的(例如,在管乐器中),同等调和的音符是更可取的。

结束语

我希望这篇文章对展示我们如何使用动态 Python 可视化来判断音乐和弦中的“不和谐”有用。本文中的所有代码都可以在这个 Github 资源库中找到。

我感谢任何建议或反馈!你可以在 Twitter 上关注我,或者在 LinkedIn 上联系我,获取更多文章和更新。

可视化我的 LinkedIn 网络

原文:https://towardsdatascience.com/visualizing-my-linkedin-network-c4b232ab2ad0?source=collection_archive---------3-----------------------

一目了然地看到我的整个网络

来自金的便利,承蒙吉菲

这就是我在现实生活中参加社交活动时的感受。然而,使用 LinkedIn 建立我的人际网络是一种完全不同的体验——我甚至通过给*台上的人发短信获得了一份实习工作。所以我真的很看重这个*台,非常看重。

LinkedIn 的不足之处

但是 LinkedIn 在一个主要方面让我失望了,真的很难理解你的网络。我的意思是,LinkedIn 没有提供任何方便的统计数据或可视化工具来让你了解你的 LinkedIn 领域,这使得你很难最大限度地利用它。

在探索你自己的 LinkedIn 网络时,这几乎是最好的了。

我的网络->连接->使用过滤器搜索

用于搜索的所有过滤器

您可以使用一些过滤器,但仅此而已。你不能把你的整个网络看做一瞥或任何统计摘要,所以很难对你的数据进行理解。

我觉得可视化我的网络,将有助于我最终了解我的 LinkedIn 足迹——谁在其中,他们在哪里工作,是否多样化等等。在这成为他们*台上的一个功能之前,我希望你会受到启发,积极主动地想象你自己的网络,最终了解你网络中的 500 多个联系是由什么样的人组成的。

获取我的 LinkedIn 数据

如果我想可视化我的网络,第一步是获取我的网络数据。你可能认为这有一个 API,你是对的。但是 LinkedIn 的 API 使用起来并不那么简单——访问连接数据需要多个权限,这是有充分理由的。但是我所需要的可视化我的网络就是我的数据。LinkedIn 非常好,可以让下载你自己数据的过程变得相当简单——不需要 API,只需下载一个好的旧 csv 文件。

您可以在个人资料的“设置和隐私”部分找到它

有趣的部分到了——可视化!

所以现在数据可用了,我需要开始分析它——我的首选工具是可信赖的 Jupyter 笔记本

这是我下载的 Connections.csv 文件的前几行。

import pandas as pd
df = pd.read_csv('Connections.csv')
df.head()

它列出了我的网络中每个人的电子邮件、当前职位和公司,以及他们何时成为我的网络的一部分。但是打印 csv 的行显然不是可视化或理解我的网络的最佳方式。

为了让我的整个网络一目了然,我将使用 Plot.ly 的树形图。

import plotly.express as px
px.treemap(df, path=['My Network', 'Company', 'Position'], width=1200, height=1200)

用 Python 中的 Plot.ly 制作

让我们仔细看看…

我最*才发现树状图,我很高兴我发现了它们,因为它如此优雅地捕捉了 LinkedIn 网络数据。

该图将我的关系网分为一个等级结构——关系网、关系网中的公司以及在这些公司中的职位。每个区块的大小表明有多少人属于该组。因此,公司磁贴越大,它在我的网络中所占的比例就越大。公司内部的瓷砖也是如此。这让我探索我的网络构成变得如此容易和有趣。

但是我还没说完。通过切换代码中的几个参数,我可以探索以位置为中心的网络视图,而不是以前可视化的以公司为中心的视图。

px.treemap(df, path=['My Network', 'Position', 'Company'], width=1200, height=1200)

也是用 Python 中的 Plot.ly 制作的

我们可以再仔细看看。

解读数据

在玩了太长时间的可视化游戏后,我开始思考他们在说什么。

比较以公司和职位为中心的树形图给了我一个有趣的见解。在公司焦点中,我可以看到明显的主导公司,如摩根大通、HKUST 和高盛。但立场聚焦,显示了更民主的观点。目前有几个主要职位:软件工程师、分析师和助理——但大图显示了更多样化的存在(更多的小盒子和更少的笨重盒子)。这让我很惊讶,因为这违背了我最初的直觉“工作种类比公司少”。相反,小众角色比我预想的要多得多,它们压倒了公司的多样性(至少在我的网络中)。

就个人而言,这些树状图也让我意识到我的 LinkedIn 网络比我想象的更加多样化。看着我的推荐和我最*添加的人,我经常认为一些公司和肯定一些职业构成了我的网络的大部分。但这与事实相去甚远,因为我现在意识到,我的大部分人际网络是由公司和职业组成的,它们只包含一两个人。

本质上,这些发现是一个…

来自朋友,承蒙吉菲

自己尝试代码

你可以修改代码,并通过直接进入活页夹环境这里与可视化交互。

你也可以通过访问代码库,这里是

如果你有任何问题、批评或赞美,请随时在推特、 LinkedIn 或下面联系我😄

可视化参数化量子分类器。

原文:https://towardsdatascience.com/visualizing-parameterized-quantum-classifiers-e5dfb0c584ba?source=collection_archive---------62-----------------------

一个量子位数据的情况。

这篇文章的目的是解释在 1 个量子位的情况下量子态的参数化二进制分类器。这个简单的例子允许我们有一些很好的可视化,甚至一些分析表达式。

第一部分将陈述结果并显示数字,而技术证明将留给第二部分。所以如果你不喜欢方程,你可以在第一部分之后停止阅读。

我鼓励每个不熟悉球坐标的人看看这里的,因为这是这篇文章的核心。

这个帖子不是对量子计算的介绍,这里的是关于它的最清晰的视频。这里是更详细的文章。

所有的图形都是用库 QuTip 创建的。

可视化和结果

布洛赫球

量子态可以表示为一个复矢量|ψ> = 𝑎|0>+𝑏|1>,比如|𝑎| + |𝑏| = 1。它也被定义为一个全局相位,我们可以用𝜃 ∈ [0,π]和ϕ∈ [0,2π]写出|ψ> = cos(𝜃/2)|0>+e^(iϕ)sin(𝜃/2)|1>。这对夫妇(𝜃,ϕ)在 R^3 的单位球面上定义了一个点,这种量子位的表示被称为布洛赫球面。

这是一个用布洛赫球表示的量子态的例子。蓝色表示状态|0 >,红色表示状态|1 >,绿色表示状态 1/√2 (|0> + |1 >)。

量子态的二元分类器。

正如在一个经典的分类问题中,我们假设每个量子态都与{0,1}中的标签 y 相关联。我们观察到一组称为训练集的状态的标签,我们希望构建一个函数来预测一个新的量子状态的标签。我们希望构造一个参数化的酉算子 U(⍺) 比如

u(⍺)|ψ(x)>=√p(y = 0)|0>+p(y = 1)| 1>

通过测量量子态来估计概率。然后可以计算一个成本函数,并用经典优化器更新参数

我们不会在这篇文章中讨论这个问题,我们的目标是可视化参数化分类器在 Bloch 球上的效果。

分类器的基本属性

幸运的是,在一个量子位的情况下,幺正算符非常简单,可以用 3 个参数来完全表征。一般形式由下式给出。

这意味着我们只需要查看这个矩阵族就可以找到我们的候选分类器。此外,我们可以证明参数ϕ对最终概率没有影响。它把我们简化成最后的形式。

边框的属性

边界由一组点定义,P(y=0) = P(y=1) = 1/2。在一个量子位上的二进制分类器的情况下,这个边界是一个将布洛赫球体切割成两个相等半球的圆。一个半球包含分类为 0 的所有量子态,另一个半球包含分类为 1 的所有量子态。

形象化

现在让我们想象一下分类器的结果是什么样的。对于下面的每张图,我们用红色和蓝色标出了由量子模拟器计算出的分类区域。边界用黑色画,知道圆的方程式。

下面是 𝜃 = 0𝜃 = π的结果,两种情况下λ = 0。完全翻转 𝜃 不会改变*面图(x,y)中边界的位置,但是标签会反转。

我们现在来看看λ = 0 时的 𝜃 = π/2。边界已经从*面(x,y)旋转到*面(y,z)。

现在,更一般的数值有 𝜃 = π/6,并且λ = 0,λ = 3π/2。在保持 𝜃 不变的同时修改λ,就像围绕 z 轴旋转球体。

数学

现在让我们详细证明我们以前见过的一切。

证明ϕ不影响概率。

设|ψ> =⍺|0

u |ψ> = cos(𝜃/2)| 0>+e^(iϕ)sin(𝜃/2】| 1>+(-sin(𝜃/2)e(iλ)β)|0>+e(iϕ+iλ)cos(𝜃/2)β|1>=【cos(𝜃/2】+(-sin(Iλ/2)e(Iλ)β)]| 0>+【e(Iε)sin(Iλ/2)】

我们现在取与|1 >相关的振幅的模*方。

而我们有p(y = 1)= |e(iϕ)sin(𝜃/2)*⍺*+e(iϕ+iλ)cos(𝜃/2)β| =|e^(iϕ)| |sin(𝜃/2)+e^(iλ)cos(𝜃/2)β| =|sin(𝜃/2)+e^(iλ)cos(𝜃/2)β|

因此,分类概率独立于ϕ.

边界的等式。

让|ψ> = cos(𝜃/2)|0>+e^(iϕ)sin(𝜃/2)|1>,让我们考虑如下定义的酉 u(θ,λ)。

这就像前一段中设定的ϕ=0。

于是,我们知道被分类为 1 的概率是:

**p(y = 1)=|sin(θ/2)cos(𝜃/2)+e^(iλ+iϕ)cos(θ/2)sin(𝜃/2)|用他们的表达式替换 和β时。请不要把这个ϕ和上一段中的那个混淆了。

扩展完整的表达式给了我们

我们可以利用 cos +sin =1 的事实来简化最后两项,并且可以利用等式 sin(2)= 2cos(⍺)sin(⍺).)来简化第二项**

然后我们用 sin(⍺/2) = (1-cos(⍺))/2 和 cos(⍺/2) = (1+cos(⍺))/2)和我们有

边界例如 P(y=1) = 1/2。因此,它的集合是(𝜃,ϕ如 cos(λ+ϕ)sin(θ)sin(𝜃)-cos(θ)cos(𝜃)= 0。

边界方程:

cos(λ+ϕ)sin(θ)sin(𝜃)—cos(θ)cos(𝜃)= 0

然后我们将证明这个方程刻画了以原点为中心的单位球面上的一个圆。

球坐标中圆的方程

以原点为圆心的单位球面上的圆,完全可以用一个法向量来表征,如下图所示。设×ᵤ=(𝜃ᵤ,)这个向量的坐标。

设(𝜃,ϕ)为圆的一点。与 x 的正交性可以写成 :

sin(𝜃ᵤ)cos(ϕᵤ)sin(𝜃)cos(ϕ)+sin(𝜃ᵤ)sin(ϕᵤ)sin(𝜃)sin(ϕ)+cos(𝜃ᵤ)cos(𝜃)= 0

sin(𝜃ᵤ)sin(𝜃)(cos(ϕᵤ)cos(ϕ)+sin(ϕᵤ)sin(ϕ))+cos(𝜃ᵤ)cos(𝜃)= 0

通过使用三角加法公式,

sin(𝜃ᵤ)sin(𝜃)cos(ϕᵤ+ϕ)+cos(𝜃ᵤ)cos(𝜃)= 0

我们最后的圆方程式是:

sin(𝜃ᵤ)sin(𝜃)cos(ϕᵤ+ϕ)+cos(𝜃ᵤ)cos(𝜃)= 0

通过识别 cos(λ+ϕ)sin(θ)sin(𝜃的术语)—cos(θ)cos(𝜃)= 0(上一段),我们有ϕᵤ=λ,还有𝜃ᵤ=π-θ.**

因此,边界是一个圆,给定初始幺正参数,我们可以计算这个圆的方程。

这就是,一些量子分类器的可视化,以及即将出现的证据。Maria Schuld 等人在本文中对参数化量子分类器进行了全面解释。

欢迎分享您的反馈,您可以在 LinkedIn 上联系我,或者发布对文章的回应。

使用 HERE traffic api 可视化实时交通模式

原文:https://towardsdatascience.com/visualizing-real-time-traffic-patterns-using-here-traffic-api-5f61528d563?source=collection_archive---------14-----------------------

虽然谷歌地图显示的是实时交通状况,但却无法访问底层的交通数据。HERE technologies 提供各种基于位置的服务,包括提供交通流量和事故信息的 REST API。

这里有一个非常强大的免费增值账户,允许多达 25 万次免费交易。然而,虽然有一些不错的开发人员文档,但缺乏关于如何准确提取交通信息并进行分析的在线教程。在本文中,我将介绍使用 python 和 xml 解析从道路网络获取交通数据的基本过程。这是 2019 年 12 月随机周四下午 1:30 至 4:30 之间 DC 高速公路交通数据的 GIF 图:

下午 1:30-4:30 的 DC 交通 gif 图显示了这里的交通流量数据。资料来源:塞犍陀·维维克

%matplotlib inline
from matplotlib import pyplot as plt
import numpy as np
import matplotlib.cm as cmimport requests
#import dill
from bs4 import BeautifulSoup
#from datetime import datetime
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import XML, fromstring, tostringpage = requests.get('https://traffic.api.here.com/traffic/6.2/flow.xml?app_id=BLAH&app_code=BLAH2&bbox=39.039696,-77.222108;38.775208, -76.821107&responseattributes=sh,fc')
soup = BeautifulSoup(page.text, "lxml")
roads = soup.find_all('fi')

首先,您需要在这里注册,并生成应用 id 和应用代码凭证(上例中的 BLAH 和 BLAH 2)——这非常简单。接下来,你需要找出你想要查找交通流量的道路网络区域,你可以在谷歌地图中点击某个位置,然后右键单击“这里有什么?”这将给出稍后长坐标。这里,traffic API 需要对应于左上和右下的 2 个 lat long 对,以便给出矩形边界框内包含的道路上的交通流量信息。响应属性是将包含在 API 响应中的信息。在上面的示例中,“sh”表示 shapefile 属性,这很重要,因为它们给出了道路的几何图形,而“fc”表示函数类,对于以后仅过滤高速公路或街道等非常有用。最后一行代码给出了一个 XML 文档,其中每个孩子代表一个特定的路段,每个路段都有一个唯一的形状文件。

a1=[]
loc_list_hv=[]
lats=[]
longs=[]
sus=[]
ffs=[]
c=0
for road in roads:
    #for j in range(0,len(shps)):
    myxml = fromstring(str(road))
    fc=5
    for child in myxml:
        #print(child.tag, child.attrib)
        if('fc' in child.attrib):
            fc=int(child.attrib['fc'])
        if('cn' in child.attrib):
            cn=float(child.attrib['cn'])
        if('su' in child.attrib):
            su=float(child.attrib['su'])
        if('ff' in child.attrib):
            ff=float(child.attrib['ff']) if((fc<=2) and (cn>=0.7)):
        shps=road.find_all("shp")
        for j in range(0,len(shps)):
            latlong=shps[j].text.replace(',',' ').split()
            #loc_list=[]
            la=[]
            lo=[]
            su1=[]
            ff1=[]

            for i in range(0,int(len(latlong)/2)):
                loc_list_hv.append([float(latlong[2*i]),float(latlong[2*i+1]),float(su),float(ff)])
                la.append(float(latlong[2*i]))
                lo.append(float(latlong[2*i+1]))
                su1.append(float(su))
                ff1.append(float(ff))
            lats.append(la)
            longs.append(lo)
            sus.append(np.mean(su1))
            ffs.append(np.mean(ff1))

上面,我按照功能等级≤2(表示高速公路)过滤了所有道路,cn 表示置信度,0 表示低置信度,1 表示最高置信度。总的来说,这个 DC 高速公路系统有大约 5000 个路段。

fig=plt.figure()
plt.style.use('dark_background')
#plt.plot(np.linspace(0,10,10),np.linspace(0,10,10))
plt.grid(False)
for i in range(0,len(lats)):
    if(sus[i]/ffs[i]<0.25):
        plt.plot(longs[i],lats[i], c='brown',linewidth=0.5)
    elif(sus[i]/ffs[i]<0.5):
        plt.plot(longs[i],lats[i], c='red',linewidth=0.5)
    elif(sus[i]/ffs[i]<0.75):
        plt.plot(longs[i],lats[i], c='yellow',linewidth=0.5)
    else:
        plt.plot(longs[i],lats[i], c='green',linewidth=0.5)
    #print(i)
#plt.xlim(-77.055,-77.015)
#plt.ylim(38.885,38.91)
plt.axis('off')
plt.show()

最后,我绘制了道路上所有的交通速度,用棕色、红色、黄色、绿色表示最差到最少的交通,类似于谷歌地图。一个缺点是没有检索以前数据的选项,这都是实时的:/。

还有很多其他的服务。例如,TomTom 提供的路段数据与这里非常相似,只不过它是距离给定经度位置最*的单个路段的速度信息。但是要获得整个区域,需要熟悉缩放级别和*铺网格。对于缩放级别 0,世界显示在一个单幅图块上。在缩放级别 22,世界被分成 2^44 瓷砖。弄清楚像 DC 这样的特定位置如何对应于哪一个瓦片是一件非常头痛的事情。Waze 似乎也有一些选择来获得它的流量数据,但是你需要注册成为 Waze 的合作伙伴,这是一个完全不同的过程。

所以你去,你现在可以可视化实时交通和模式!还有很多更酷的事情可以做,例如将这与事件数据相结合,以预测交通如何基于事件而变化。或者与 fleet 或 Mapbox 等网络地图*台配合使用,让它看起来更漂亮。基于位置和交通的服务将继续存在。想想优步、Lyft、波导、亚马逊快递等。所有这些公司都需要实时位置和交通信息。在不久的将来,自动送货卡车车队可能会依靠这些信息做出明智的决定。前途无量!

关注我 如果你喜欢这篇文章——我经常写复杂系统、物理学、数据科学和社会的界面。

如果你还不是中会员,想支持我这样的作家,可以通过我的推荐链接随意报名:https://skanda-vivek.medium.com/membership

可视化正则化与 L1 和 L2 规范

原文:https://towardsdatascience.com/visualizing-regularization-and-the-l1-and-l2-norms-d962aa769932?source=collection_archive---------13-----------------------

为什么最小化规范会导致正则化?

作者图片

如果你上过机器学习的入门课,你肯定遇到过过度拟合的问题,并了解过正则化和规范的概念。我经常看到纯粹通过查看公式来讨论这个问题,所以我想我会尝试使用一些直观的例子来更好地了解为什么最小化范数会导致正则化,以及 L1 和 L2 之间的差异。

必备知识

  • 线性回归
  • 梯度下降
  • 对过拟合和正则化的一些理解

涵盖的主题

  • 为什么最小化范数会诱导正则化?
  • L1 标准和 L2 标准有什么区别?

正规化概述

使用线性回归的例子,我们的损失由均方误差(MSE)给出:

我们的目标是尽量减少这种损失:

为了防止过度拟合,我们想要添加一个偏向不太复杂的函数。也就是给定两个可以合理拟合我们数据的函数,我们更喜欢简单的一个。为此,我们添加了一个正则项,通常是 L1 范数或*方 L2 范数:

因此,例如,通过将*方 L2 范数添加到损失和最小化,我们获得岭回归:

其中λ是正则化系数,它决定了我们需要多少正则化。

为什么最小化范数会诱导正则化?

最小化范数有助于降低函数的“复杂性”。从数学上讲,我们可以看到 L1 和 L2 范数都是权重大小的度量:L1 范数的绝对值之和,L2 范数的*方值之和。所以更大的权重给出了更大的范数。这意味着,简单地说,最小化范数鼓励权重变小,这反过来给出了“更简单”的函数

让我们用一个例子来形象化这一点。让我们假设我们得到一些类似这样的数据:

作者图片

我们应该选择什么函数来拟合这些数据呢?有许多选择,这里有三个例子:

作者图片

这里我们有一个 2 次多项式拟合和两个不同的 8 次多项式,由以下等式给出:

前两个(是“更简单”的函数)最有可能更好地概括新数据,而第三个(更复杂的函数)显然过度拟合了训练数据。这种复杂性是如何体现在规范中的?

作者图片

我们可以看到,线[c]的均方误差为 0,但其范数相当高。相反,线[a]和[b]具有稍高的 MSE,但是它们的规范低得多:

  • 线[a]具有较低的范数,因为与[c]相比,它具有明显较少的参数
  • 线[b]具有较低的范数,因为尽管有相同数量的参数,它们都比[c]小得多

由此我们可以得出结论,通过将 L1 或 L2 范数添加到我们的最小化目标,我们可以鼓励具有较低权重的更简单的函数,这将具有正则化效果,并帮助我们的模型更好地推广新数据。

L1 标准和 L2 标准有什么区别?

我们已经看到,为了降低函数的复杂性,我们可以完全去掉一些权重(将它们设置为零),或者使所有权重尽可能小,这就是 L1 和 L2 之间的区别。

为了理解它们如何不同地操作,让我们看一看它们如何根据权重的值而变化。

作者图片

左边是给定重量 w 的 L1 和 L2 范数图,右边是相应的范数斜率图。正如我们所看到的,L1 和 L2 都随着 w 值的增加而增加。然而,当 L1 范数以恒定速率增加时,L2 范数以指数形式增加。

这很重要,因为正如我们所知,当进行梯度下降时,我们将基于损失函数的导数来更新我们的权重。因此,如果我们在损失函数中包含一个范数,范数的导数将决定权重如何更新

我们可以看到, L2 范数随着 w 变小,范数的斜率也变小,这意味着更新也将变得越来越小。当权重接* 0 时,更新会变得非常小,几乎可以忽略不计,所以权重不太可能变成 0。

另一方面,用 L1 范数斜率是常数。这意味着随着 w 变小,更新不会改变,所以我们会因为权重变小而得到相同的“奖励”。因此,L1 规范更有可能将一些权重降低到 0。

概括一下:

  • L1 范数将一些权重驱动到 0 ,导致权重稀疏。这对于内存效率或者当需要特征选择时是有益的(即我们只想选择某些权重)。
  • 相反, L2 规范减少所有权重,但不会一直减少到 0 。这不太节省内存,但如果我们想要/需要保留所有参数,这可能是有用的。

觉得这个故事有帮助?考虑 订阅 到媒体支持作家!

在 Python 的 Plotly 中可视化德国汽车供应商的收入

原文:https://towardsdatascience.com/visualizing-revenues-of-german-car-suppliers-in-pythons-plotly-9c90610af4f1?source=collection_archive---------55-----------------------

初升的太阳从升起

如今,数据无处不在,让每个人都能访问数据是必不可少的一步,不管他们的专业背景如何。

手动分析表格数据是极其讨厌的,肯定不会引起任何人的注意。

事情不一定要这样。

完全相同的数据可以以奇特的方式可视化,甚至非数据科学家也渴望一睹这些令人钦佩的情节。

如果每个人眼前都有一个有意义的图表,而不是枯燥的表格,那么用数据来销售一个故事就会变得容易得多。

与表格相比,拥有一个漂亮而干净的图表可以更快地浏览手头的数据,提供更好的交互机会,并且看起来非常漂亮。

让我们点燃蜡烛。

这篇文章使用了listen campion,)的一小段数据,这是一家提供特定市场列表的领先公司,对于可视化和分析目的来说是最佳的。非常感谢它的团队为我提供了这个列表,并允许发表对它的分析。

当以正确的方式可视化数据时,用数据说服人们会变得简单。我的正道是 Python 的 Plotly 库。与 matplotlib 相比,它的视觉效果一流,响应速度也很快,因此它是我在 Python 中实现可视化的首选库。

首先,我们必须对手头的数据有一个概念,所以让我们检查一下我们的代码片段提供了什么:

关于手头数据集的信息

令人兴奋的是,德国 20 大汽车供应商名单。二十个条目足够小,甚至对人类友好,但是,想想一个有几千个条目的列表,事情会变得很快变得很糟糕。这就是为什么 Python 和 Plotly 是分析和可视化数据的好方法。

该数据集包括公司地址、员工人数、2015 年至 2018 年的收入、首席执行官、联邦州、联系人等信息。

为了在世界地图上显示这些公司,有必要以经度-纬度格式提取它们的地理位置。幸运的是,我们有一个给定的地址,可以进一步用来获得地理坐标。因此,谷歌地理位置 API 来得非常方便。初次登录时,您还可以获得最初的 300 美元,这对于任何较小的项目来说都足够了。

那么,让我们得到这些地址的地理坐标(经度,纬度):

import googlemaps
gmaps = googlemaps.Client(MAPS_KEY)def get_coordinates(plz_string):

convert zip code into geo coordinates.Input:
plz_string: string with the zip code + country location, i.e. 75242 Germany, or 94086 USA

   try:
      lon = location[0][“geometry”][“location”][“lng”]
      lat = location[0][“geometry”][“location”][“lat”]
   except:
      lon = None
      lat = None
      print(“Something went wrong with: {}”.format(plz_string))
   return lat, londf[‘location’] = df[“PLZ”].apply(lambda x: str(x) + “, Germany”)
df[‘lat / lon’] = df[‘location’].apply(lambda x: get_coordinates(x))

这太神奇了,在几分钟内,我们已经将邮政编码转换成地理坐标,这使我们能够在地图上标出确切的位置。

现在我们有了这些简洁的坐标,让我们进入这篇文章的核心,用最好的方式使用 Plotly 的功能。

我为建议和改进而高兴,也为你指出的每一个代码垃圾而高兴。

Plotly 提供了各种可以使用的地图,如 chloropleth 地图、地图框或散点图。我将利用后者。

现在的问题是,你想把公司总部的位置形象化吗?因此,我将从我们的数据中列出的他们过去两次录音(2018-2017)的收入差异入手。我还根据联邦州、公司规模或他们运营的分支机构进行了可视化。查看我的 github,包括整个笔记本

然而,为了简单和美观,我将只带您进行收入发展之旅。请随意实现其他版本或提出更有创意的想法来可视化该数据集。

在我向你展示情节之前,请记住,这些是汽车供应商,没有谷歌或亚马逊。他们的收入可能会让你震惊。

scale = 56
revenue = go.Figure()for diff in list(df[colName]):
    ## create sub dataframe containing the 16 federal states in Germany
    df_sub = df[df[colName] == diff]
    ## plot the bubbles on the map
    revenue.add_trace(go.Scattergeo(
        locationmode = 'geojson-id',
        lon = df_sub['longitude'],
        lat = df_sub['latitude'],
        name = df_sub['Unternehmen'].values[0],
        hovertemplate = "<b>{} </b><br><br>".format(df_sub['Unternehmen'].values[0]) +
                        "Rev. Difference: {}<br>".format(diff) +
                        "# Employees: {}<br>".format(df_sub["Mitarbeiter"].values[0]) ,
        marker = dict(
            ## scale the bubble size properly, to at least have a size of 5
            size = diff/scale if (diff/scale) > 6 else 7,
            line_color='rgb(40,40,40)',
            line_width=0.4,
            color = df_sub['color'],
            sizemode = 'area'
        )))## get the layout right
revenue.update_layout(
        #title_text = 'Revenue Difference [in Mio. €] from 2017 to 2018 of selected automotive suppliers',
        showlegend = True,

    geo = go.layout.Geo(
        resolution = 50,
        scope = 'europe',
        showframe = False,
        showcoastlines = True,
        landcolor = "rgb(229, 229, 229)",
        countrycolor = "white" ,
        coastlinecolor = "white",
        projection_type = 'mercator',
        ## limit our projection to Germany only
        lonaxis_range= [ 5.0, 15.0 ],
        lataxis_range= [ 47.0, 55.0 ],
        ## center the projection at Germany's center coordinates
        center = {"lat": 50.757958, "lon": 10.266271},
        domain = dict(x = [ 0, 1 ], y = [ 0, 1 ])
    )
)
## enable and disable all the configurations we do not want to display
config = dict({'scrollZoom':True, 
               'displayModeBar':False,
               'showLink':False, 
               'displaylogo': False,
               'editable': False})## Save Plot on plotly account
py.plot(revenue, filename = 'revenue difference map', auto_open=True, showLink=False, config=config)
revenue.show()## Also possible to save it as HTML and host it on github
#pio.write_html(revenue, file=’biggest firms.html’, auto_open=True)

现在我们已经有了一张所有 20 家公司的整洁地图,可以根据它们各自的公司名称进行过滤,如果有一条显示每家公司在记录年份的收入增长的线形曲线,那就太棒了。

要做到这一点,我们必须对我们的数据框架做一点小小的调整,将其变成不同的形状,我们将每家公司的记录年份作为 x 轴,将 2015 年至 2018 年的收入作为 y 轴。

这是在下面完成的,我们循环遍历每一家公司,并强迫它进入正确的形状。如果你是虐待狂,那么这个解决方案可能适合你,然而,聪明的人会找到更有效的方法来达到同样的结果。

cols = ['Unternehmen', 'Umsatz 2015 (in Mio. €)', 'Umsatz 2016 (in Mio. €)', 'Umsatz 2017 (in Mio. €)', 'Umsatz 2018 (in Mio. €)']
revenue_plot = df.loc[:, cols]
## extract all the years, cast it to int and reverse the list to get [2015, 2016, 2017, 2018]
years = [ int(ele[0]) for ele in list(filter(None, [ re.findall('\d+', string) for string in df.columns ]))][::-1]revenue_cruve = go.Figure()
for i in range(len(revenue_plot)):
    plot_df = pd.DataFrame(
        {'Company': [revenue_plot.iloc[i, 0] for j in range(len(years))],
         'Year': years,
         'Revenue': list(revenue_plot.loc[i, ["Umsatz 2015 (in Mio. €)", 'Umsatz 2016 (in Mio. €)', 'Umsatz 2017 (in Mio. €)', 'Umsatz 2018 (in Mio. €)']]) },
        columns = ['Company', 'Year', 'Revenue'])
    revenue_cruve.add_trace(go.Scatter(
                    x=plot_df['Year'],
                    y=plot_df['Revenue'],
                    name=plot_df['Company'][0],
                    text =  '<b>{}</b> <br>'.format(plot_df['Company'][0]) +
                            'Revenue {}: {} <br>'.format(plot_df['Year'][0], plot_df['Revenue'][0]) +
                            'Revenue {}: {} <br>'.format(plot_df['Year'][1], plot_df['Revenue'][1]) +
                            'Revenue {}: {} <br>'.format(plot_df['Year'][2], plot_df['Revenue'][2]) +
                            'Revenue {}: {}'.format(plot_df['Year'][3], plot_df['Revenue'][3])
    ))revenue_cruve.update_traces(mode="markers+lines",
                            hovertemplate = None                           )

revenue_cruve.update_layout(
    width = 1100,
    height = 800,
    legend_title='<b> Company </b>',

    yaxis=dict(
        title_text="Revenue in Mio. €",
        titlefont=dict(size=22),
    ),
    xaxis = dict(
        tickmode = 'linear',
        tick0 = years[0],
        dtick = 1)
)
config = dict({'scrollZoom':True, 
               'displayModeBar':False,
               'showLink':False, 
               'displaylogo': False,
               'editable': False})py.plot(revenue_cruve, filename='revenue firms curve', auto_open=True, config=config)
revenue_cruve.show()

现在,我们甚至有了每家公司的收入线曲线图,之后我们还可以进行筛选。这使得一切更容易分析,我们不必手动仔细检查每一行。正如你可能看到的,20 家公司会很快变得混乱不堪。减少混乱的另一个好方法是添加一个带有 Plotly 的下拉按钮来选择感兴趣的公司。不幸的是,我还没有这样做,但这是一个很好的实践,以培养我们刚刚学到的东西。

可视化方法对于在公司范围内共享信息也非常方便,例如在时事通讯中。每个员工只需简单浏览一下就能获得关键信息。

就是这样,我希望你今天学到了一些新东西,这篇文章不会太无聊。无论如何,如果你有一些建议或发现错误,请让我知道。该代码可在我的 github 账户中获得。

感谢阅读!

想象 Soundcloud.com 的非法毒品卖家

原文:https://towardsdatascience.com/visualizing-sellers-of-illicit-narcotics-on-soundcloud-com-5b3bb9331b4b?source=collection_archive---------52-----------------------

使用 Tableau 了解网上毒贩

介绍

许多网上药品销售发生在暗网市场——隐藏在暗网上销售非法商品的*台。然而,在 Instagram 和 Snapchat 等地方,这些商品的销售开始从暗网过渡到表面网。

这些卖家在网络上宣传他们的 Instagram 和 Snapchat 个人资料。这种情况发生在流行的在线音乐流媒体网站 Soundcloud 的评论区。下面是一个评论的截图,可识别的信息被编辑,广告大麻,可卡因和迷幻药。

图片来自声音云

可视化这些广告可以提供对这个市场如何运作、谁是主要参与者以及他们卖什么的洞察。

管道

为了可视化这些数据,开发了一个 python 框架的变体,它可以抓取 Soundcloud 评论,并从广告销售麻醉品的评论中提取 Snapchat 和 Instagram 帐户。最初的框架包括两个组件:一个 web scraper 和一个 account extractor。关于这个框架的文章可以在这里看到。

为了收集 Soundcloud.com 的评论,开发了一种网络刮刀。这个抓取器抓取给定歌曲的 Soundcloud 评论,并将用户、评论文本、歌曲名称和歌曲 url 存储在一个 csv 文件中。对于这些可视化,Soundcloud 上排名前三的歌曲是刮出来的:Playboi Carti 的@MEH,Baby Jesus 的 Find My Way,Lil Mosey 的 Blueberry Faygo。一共刮了 17048 条评论。

因为该帐户提取器组件仅收集 Snapchat 和 Instagram 帐户名称,所以需要开发用于不同可视化的新组件,以便提取所需的数据。

词云

为了使用广告非法麻醉品销售的评论中的文本创建单词云,开发了一个新的组件来提取评论,将评论的文本转换为向量,并将它们导出到包含单个单词列表的 csv。还提供了停用词列表,以消除可视化中的无用词。使用的停用词是:

"我"、"我"、"我的"、"我自己"、"我们"、"我们的"、"我们的"、"我们自己"、"你"、"你的"、"你的"、"你自己"、"你们自己"、"他"、"他"、"他的"、"自己"、"她"、"她的"、"她自己"、"它"、"它"、"它"、"它本身"、"他们"、"他们"、"他们的"、"他们的"、"他们的"、"他们的"、"自己的"、"自己"、"什么"、"哪个"、"谁"、"这个"、"那个"、"这些"、"那些"、" am "、"是"、"是"、"是"、"是"、"有"、"有"、"有"、"有"、"有"、"有"、"做"、"做了"、"做了"、"一个"、"安"、"这个"、"但是"、"如果"、"或者"、"因为"、"作为"、"直到" "上"、"下"、"进"、"出"、"上"、"关"、"过"、"下"、"再"、"进一步"、"然后"、"一次"、"这里"、"那里"、"当"、"哪里"、"为什么"、"如何"、"所有"、"任何"、"两者"、"每一个"、"几个"、"更多"、"大多数"、"其他"、"一些"、"这样"、"没有"、"也没有"、"只有"、"自己的"、"相同的"、"所以"、"比"、"太"、"非常"、" s "、" t "、"能"、"将"、"刚刚"、"唐"、"应该"、"现在"

重复评论的数量

为了直观显示非法麻醉品销售广告的重复评论数量,开发了一个新组件来提取评论并将评论文本存储在 csv 文件中。

总评论中的药品广告评论数

为了直观显示广告销售非法麻醉品的评论的百分比,开发了一个新的组件来识别广告销售非法麻醉品的评论,并将这些评论标上“是”字,将其他评论标上“否”字。

词云

Soundcloud.com 评论广告非法毒品的词云

上述单词云通过从被识别为非法麻醉品销售广告的评论中计数出 1977 个单词来可视化前 50 个单词。最常见的广告药物是大麻、可待因、四氢大麻酚汽化筒(称为“手推车”)、蘑菇、Xanax 和未知的处方药(“药丸”)。许多评论还提到了科罗拉多州和加利福尼亚州,暗示毒品,很可能是大麻,来自这些地方,或者至少广告上是这样说的。看起来,这些卖家中的许多人会小心翼翼地将药物邮寄给顾客。

重复评论的数量

通过计数过滤的非法麻醉品广告的 Soundcloud.com 评论计数> 2

上图显示了多次发布的评论,评论文本完全相同。该图表仅包括出现 1 次以上的注释。在 57 条不同的评论中,只有 5 条被评论了 10 次以上,17 条被评论了两次以上。这有助于识别市场中的潜在关键参与者。

总评论中的药品广告评论数

与其他评论相比,宣传非法麻醉品的 Soundcloud.com 评论的数量

从 Soundcloud.com 收集到的 17,048 条评论中,有 222 条是销售毒品的广告。这占所有评论的 1.3%,这意味着 Soundcloud 上每 100 条评论中就有 1 条以上为药物销售做广告。虽然这个数字看起来很低,但考虑到 Soundcloud 上的评论应该与毒品销售无关,这实际上是非常惊人的。

讨论

从 Soundcloud.com 的评论中寻找非法毒品的卖家似乎是一个很有前途的研究领域。这些评论相当普遍,有 1.3%的评论是关于三首为毒品销售做广告的歌曲。此外,这些评论集中在一些海报上,为谨慎运输做广告,并且通常为大麻、可待因、四氢大麻酚蒸发筒、蘑菇、Xanax 和未知处方药的销售做广告。

我将继续这项研究,并在下面发表更多文章。另外,你可以在下面找到我关于这个框架开发的文章。

  1. 识别 Soundcloud.com 的非法毒品卖家

使用 geojson 热图可视化空间数据

原文:https://towardsdatascience.com/visualizing-spatial-data-with-geojson-heatmaps-1fbe2063ab86?source=collection_archive---------22-----------------------

热图是一种很好的可视化方式,但在地图上绘制它们可能是一个挑战。了解如何使用 geojsoncountour 创建自定义 geojson 数据来创建身临其境的地图。

华沙房地产价格[兹罗提/*方米]

您是否曾经处理过空间数据,并面临过必须在过度拥挤的散点图或局限于行政边界(如地区)的等值线图之间做出选择的挑战?

作为一名房地产行业的数据科学家,我经常处理空间数据,但是,我一直在努力寻找可视化空间数据的最佳方式,以便能够轻松地从大型数据集中掌握关键的空间要素。

Plotly 或 Folium 提供的基本功能受到限制,所以我决定研究一下如何在地图上创建自定义热图,我想在本文中与您分享。从 2020 年 5 月起,我将致力于华沙超过 1 万个房地产报价的数据集,你可以通过下面的链接从我的 GitHub 下载。

GitHub 上有完整的代码和数据来源:https://GitHub . com/Jan-Majewski/Project _ Portfolio/blob/master/03 _ Real _ Estate _ pricing _ in _ Warsaw/03 _ 02 _ Data _ viz ualization . ipynb

对于交互式可视化,我推荐使用 nbviewer 链接:https://nb viewer . jupyter . org/github/Jan-Majewski/Project _ Portfolio/blob/c 770 f 21 DC 410 b 1495 DBD F5 b 9 F4 f 443 ECD 4d 986 ba/03 _ Real _ Estate _ pricing _ in _ Warsaw/03 _ 02 _ Data _ viz ualization . ipynb

1.介绍

使用的数据可以从 GitHub 下载

df = pd.read_excel(r"[https://raw.githubusercontent.com/Jan-Majewski/Project_Portfolio/master/03_Real_Estate_pricing_in_Warsaw/Warsaw_RE_data.xlsx](https://raw.githubusercontent.com/Jan-Majewski/Project_Portfolio/master/03_Real_Estate_pricing_in_Warsaw/Warsaw_RE_data.xlsx)")

由于数据的特性比这个项目所需的要多得多,所以让我们只选择关键的 8 列。

key_columns=['Id', 'Area', 'Price', 'latitude', 'longitude',
      'City','district']df**=**df[key_columns]df.head(10)

首先,让我们探索使用基本 Plotly 要素可视化空间数据的最常见方法。

1.1 .基本散点图框

地图上的散点图可能是可视化空间数据的最常见和最简单的方式。你得到坐标,设置一个特征为颜色,这就是你的地图。乍一看,它甚至看起来非常有效,但是如果你正在处理一个更大的数据集,它会变得过于拥挤,你实际上看不到下面的地图。

1.2 网格散点图框

我们可以通过舍入坐标并计算每个图块的*均值来创建网格,从而简化散布。它看起来更容易阅读,但我们也失去了很多细节。

格网图基于通过裁剪纬度和经度、创建纬度 _ 模式和经度 _ 模式要素以及对数据进行分组以创建测向图而汇总的数据。

2.使用 geojson 定制热图

由于对之前的结果不满意,我决定寻找基于等高线图创建热图的方法。

对我来说,最好的解决方案是一个 4 步过程:

  • 在 matplotlib 中创建等高线图
  • 使用 geojsoncountour 库将其转换为 geojson
  • 从 geojson 提取值到 df_contour
  • 使用 plotly 创建 choropleth 地图

2.1 用 matplotlib 计算我们的图

价格密度等值线图

我们得到了一个非常好的等高线图,现在我们需要做的就是把它转换成 geojson,这样它就可以和 plotly 兼容了。

警告!为等值线图选择边界时,请确保每个图层至少有一个数据点。如果最大值和最小值太宽或者步长太小,并且其中一个图层为空,则可能会使整个 geojson 在 plotly 中根本不出现。

2.2 .将等高线图转换为 geojson

要将等高线图转换为 geojson,您需要 geojsoncontour 库。

pip install geojsoncontour

2.3.创建 viz 之前的最后一步是将 geojson 的价格提取到 DataFrame 中

由于 plotly 需要一个数据帧,其中的值用于 geojson 中空间对象的填充颜色,我们需要通过迭代 geojson 字典中的“features”键来提取它们。该键包含一个字典列表,热图的每一层都有一个字典。该值作为“title”键存储在子字典的“properties”键中。让我们还将“id”键添加到列表中的每个字典,以将空间对象与数据帧行相匹配。

2.4 最终创建热图

现在我们有了创建一个漂亮的热图所需要的一切。我们来策划吧!

房地产价格密度的最终热图

我建议参考页面顶部的 nbviewer 链接,以探索缩放和深入研究最有趣的情节区域的全部可能性。

3.摘要

我希望本教程能帮助你使你的空间可视化更有效,更容易一目了然地抓住关键的洞察力。

这种类型的可视化适用于各种数据,其中空间要素是关键驱动因素之一。总结一下,享受一个类似的基于谷歌通勤数据的 viz。如果您对分析感兴趣,本文顶部引用的笔记本也使用 Google API 处理提取和处理驾驶时间数据。

华沙早晨通勤时间

用 Matplotlib 和熊猫可视化 2019-20 英超联赛赛季

原文:https://towardsdatascience.com/visualizing-the-2019-20-english-premier-league-season-with-matplotlib-and-pandas-fd491a07cfda?source=collection_archive---------26-----------------------

2019-20 英超联赛积分榜背后的统计数据是什么?

照片由 KAKUDMIUnsplash 上拍摄

当我们急切地等待 6 月 17 日英超联赛赛季的重新开始时,我们可以从这个 Kaggle 数据集来看看这个赛季迄今为止的故事。作为一名利物浦球迷,我希望本赛季在英超联赛时代第一次以冠军结束(在一个历史性的、破纪录的赛季中)。

在过去的一年里,利物浦以 25 分的领先优势高居榜首,只需要 6 分就能确保夺冠,统治了英格兰足坛。让我们看看相对于他们的预计总分,他们的表现如何。首先,我们将导入可视化所需的包:

# Import packages
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patheffects as pe
import pandas as pd
import numpy as np

稍后,我们将使用matplotlib.patheffects包来进行文本注释(来标记单个数据点)。

导入团队数据

从 Kaggle 下载数据集后,我们将有两个数据文件:

  1. epl2020.csv —包含特定团队的数据,如进球、失球、成绩、积分等。
  2. players_1920.csv —包含特定球员的数据,包括个人进球、卡牌、助攻、扑救等。

我们的第一个可视化是查看表格中每个团队的实际积分值与他们的预期总积分(基于基于他们表现的预测)的比较。为此,我们将使用epl2020.csv中的团队级数据。

# Load team data
filename = './epl2020.csv'
data_epl = pd.read_csv(filename)

现在,让我们看看我们可以访问该文件中的哪些数据:

data_epl.columns>>> Index(['Unnamed: 0', 'h_a', 'xG', 'xGA', 'npxG', 'npxGA', 'deep', 'deep_allowed', 'scored', 'missed', 'xpts', 'result', 'date', 'wins', 'draws', 'loses', 'pts', 'npxGD', 'teamId', 'ppda_cal', 'allowed_ppda', 'matchtime', 'tot_points', 'round', 'tot_goal', 'tot_con', 'Referee.x', 'HS.x', 'HST.x', 'HF.x', 'HC.x', 'HY.x', 'HR.x', 'AS.x', 'AST.x', 'AF.x', 'AC.x', 'AY.x', 'AR.x', 'B365H.x', 'B365D.x', 'B365A.x', 'HtrgPerc', 'AtrgPerc', 'matchDay'], dtype='object')

那可是好多列啊!但是为了比较实际分数和预期分数,我们只需要其中的两列:xptspts

积分总计

由于我们加载的数据集包含每场比赛的结果,球队名称将在teamId列中重复多次,因此我们将所有唯一的球队名称收集到一个列表中:

# Get unique team names
teams = data_epl.teamId.unique()

现在,使用我们的独特团队列表,我们可以通过对数据帧中对应于特定团队的列求和来计算实际和预期的总积分。我们的做法如下:

# Get the actual and expected points for each team
actual_pts = {}
expected_pts = {}for team in teams:
  actual_pts[team] = data_epl[data_epl['teamId'] == team].pts.sum()
  expected_pts[team] = data_epl[data_epl['teamId'] == team].xpts.sum()

在上面的代码片段中,我们已经使用 Python 字典为预期和实际总点数创建了一个查找表,所以现在我们可以直接使用这些数据结构,以及我们的唯一团队名称列表(teams)来绘制我们的总点数。

我们要做的最后一件事是对数据进行数字排序——在这种情况下,我们要根据实际总点数和预期总点数之间的差异进行排序。这样做的目的是将我们的数据集分成超额完成(即比预期多的分数)和未完成的团队。为此,我们创建了一个名为pts_difference的新字典,并使用这些值对我们的团队列表进行排序。

pts_difference = {team: actual_pts[team] - expected_pts[team] for team in teams}
sorted_teams = sorted(pts_difference.keys(), key=pts_difference.get)

现在我们有了数据,我们可以创建我们的可视化。首先,我们将编辑一些总体绘图参数:

# Plot parameters
mpl.rcParams['font.family'] = 'Avenir'
mpl.rcParams['font.size'] = 16mpl.rcParams['axes.linewidth'] = 0
mpl.rcParams['axes.facecolor'] = '#ededed'mpl.rcParams['xtick.major.size'] = 0
mpl.rcParams['xtick.major.pad'] = 10
mpl.rcParams['ytick.major.size'] = 0
mpl.rcParams['ytick.major.pad'] = 10

现在我们可以开始拼凑我们的情节了。首先,我们想区分超水*团队和低水*团队。为此,我将使用一个名为PuOr的内置色图,并获得两种极端的颜色来对应超额完成(橙色)和未完成(紫色)。

# Create figure
fig = plt.figure(figsize=(8,6))
ax = fig.add_axes([0, 0, 1, 1])# Get colors
colors = plt.get_cmap('PuOr', 2)

现在,我们可以绘制我们的数据。为此,我将使用一个计数器变量yval来对应垂直方向上团队条目之间的间距。该变量将在循环的每次迭代中递增。在循环过程中,我们首先根据实际和预期总点数之间的差异检查使用哪种颜色。一旦我们做到这一点,我们将实际的总点数绘制成实心圆,将预期的总点数绘制成空心圆,然后用虚线将两者连接起来。

由于我们绘制数据的方式,很难使用内置的matplotlib图例函数。我们将使用插图自己创建一个。在这种情况下,我只是绘制一个填充和未填充的圆,并标记它们。我们通过用fig.add_axes([x, y, width, height])创建 axes 对象来指定图例的大小,其中(x, y)是左下角。

最后,我们可以更新记号和标签以对应每个团队:

# Add grid
ax.grid(color='white', linewidth=2)# Points labels
ax.set_xticks(np.arange(0, 110, 10))# Team labels
ax.set_yticks(np.arange(0, len(sorted_teams), 1))
ax.set_yticklabels(sorted_teams)# Set axis limits
ax.set_xlim(0, 100)# Set axis labels
ax.set_xlabel('Points')

纯粹基于对预期积分的预测,利物浦本赛季似乎明显超额完成了任务。事实上,如果利物浦和曼城都按照他们的预测比赛,利物浦实际上会在积分榜上排名第二!这是一个很好的例子,说明了在足球场上,不管有多少统计数据,结果最终是如何决定的。

评分和创意

对于这些可视化,我们将使用来自第二个数据文件的特定于玩家的数据:

# Load player data
filename_players = './players_1920.csv'
data_pl = pd.read_csv(filename_players)

正如我们对团队数据所做的那样,让我们看看数据框中所有可用的列:

data_pl.columns>>> Index(['Unnamed: 0', 'assists', 'bonus', 'bps', 'clean_sheets', 'creativity', 'element', 'fixture', 'goals_conceded', 'goals_scored', 'ict_index', 'influence', 'kickoff_time', 'minutes', 'opponent_team', 'own_goals', 'penalties_missed', 'penalties_saved', 'red_cards', 'round', 'saves', 'selected', 'team_a_score', 'team_h_score', 'threat', 'total_points', 'transfers_balance', 'transfers_in', 'transfers_out', 'value', 'was_home', 'yellow_cards', 'full', 'team'], dtype='object')

就像我们为团队所做的一样,让我们将独特的玩家名字收集到一个列表中。玩家的名字可以在标签为full的栏中找到。

players = data_pl.full.unique()

在这组图像中,我们感兴趣的是球员的得分和创造力,所以我们将统计他们的进球和助攻数。由于单纯的进球和助攻数据显然会对那些没有踢过那么多比赛的球员产生偏见,我们希望每 90 分钟对这些数据进行标准化。唯一的问题是,当一名球员只打了很少几场比赛时,这个*均值就会上升——因此,为了考虑这种影响,我们将确保我们名单中的每名合格球员都至少打了 10 场比赛(900 分钟)。

像我们的团队数据一样,我们正在用每 90 分钟的*均值填充两个字典,player_assistsplayer_goals,只有出场超过 900 分钟的球员才被计算在内。

现在,我们需要从高到低对球员进行排序——字典本质上不包含任何排序信息,因此我们可以创建一个正确排序的球员姓名列表。在这种情况下,我们希望收集前 20 名进球者和助攻者。

top_players_goals = sorted(player_goals.keys(), key=player_goals.get, reverse=True)[:20]top_players_assists = sorted(player_assists.keys(), key=player_assists.get, reverse=True)[:20]

在上面的代码片段中,我们使用通过调用player_goals.get获得的值对字典的键(球员名字)进行排序。我们必须使用reverse=True,因为我们希望统计数据从最高到最低排序。最后,我们只将列表中的前 20 个元素作为我们的前 20 名玩家。

在我们绘图之前,我想创建一个名为updated_names的字典,它包含格式为“First Initial”的更短形式的玩家名字。姓氏”,所以“Sadio Mané”变成了“S. Mané”。此外,数据集不处理重音字符,因此我必须手动更改名称来解决这个问题。

现在我们可以绘制数据了!

首先,我们可以收集每个团队的团队颜色作为分散点的颜色——我从这个网站获得了每个团队颜色的十六进制代码。

为了看到这些颜色,我们可以为每个团队绘制一个色板图。我们首先创建一个图形,遍历每个独特的团队,并创建一个填充的多边形。然后我们增加一个计数器变量y_val,它向上移动下一个颜色样本。我们还对团队名称进行了排序,以便它们按字母顺序出现:

axes.fill_between(x, y1, y2)x是要绘制的 x 值数组,y1是底部的 y 值,y2是顶部的 y 值。

现在,我们要删除 x 记号,将 y 记号改为按字母顺序排列的团队名称:

# Remove x-ticks
ax.set_xticks([])# Set y-ticks to team names
ax.set_yticks(np.arange(0.5, 20, 1))
ax.set_yticklabels(sorted(teams, reverse=True))

所以现在我们有了正确的球队颜色,我们可以回去绘制每 90 分钟的进球和助攻的图表。我们将首先使用以下代码片段绘制前 20 名进球得分者的数据:

我们找到前 20 名中每个球员的球队,并用各自的球队颜色画出一个点。然后,我们通过将 x 值偏移 0.01,将玩家的名字放在该点旁边。最后,为了提高可读性,函数text.set_path_effects()允许我们在每个名字周围放置一个粗的白色轮廓(前景色为w或白色,linewidth为 5)。

我们看到沙治·奥阿古路是一个多产的得分手,每 90 分钟得分超过一次,而他的曼城队友里亚德·马赫雷斯,虽然也是前 20 名得分手,但每 90 分钟的助攻数也明显高于其他人。

我们可以用下面的代码对 90 后前 20 名助教做同样的练习:

我们看到每 90 分钟的三名顶级助攻手都是曼城球员——里亚德·马赫雷斯、凯文·德·布鲁恩和戴维·席尔瓦。从前两个情节来看,曼城在球场上并不缺乏创造力。实际上,我们可以通过查看数据集中的creativity指标来对此进行量化。与前两个例子类似,我们可以从所有玩家数据中收集所有创造力的总和:

现在,我们可以使用下面的代码来绘制创造力值。我们使用ax.barh(y, length)来创建一个水*条形图——y的值是横条的垂直位置,length是特定横条的长度。

从助攻数据来看,曼城无疑拥有最高的创造力指数。这似乎表明(并且可以通过观看他们的比赛来证实)曼城的防守是薄弱环节,也是他们迄今为止总得分不足的原因。

守门员

让我们看看守门员的表现——我们将创建对应于扑救和不失球的字典,并按照每 90 分钟的扑救次数进行排序(同样,我们仅限于踢了 900 分钟或更长时间的球员)。我们采用前 22 个条目,因为通过检查,在这一点之后,我们开始在我们的列表中获得外场球员:

我们这次的绘图将在 x 轴上显示干净的纸张,在 y 轴上显示每 90 分钟节省的纸张。我们使用下面的代码片段,它与我们之前在目标和辅助图中使用的代码片段非常相似:

*衡良好的球队往往会把他们的 GKs 放在这个图的右下象限——他们的防守足够稳健,他们的守门员不必面对大量的射门,所以他们不必做出太多的扑救,可以保持不失球。毫不奇怪,积分榜前三名的球队都有自己的守门员——艾利森·贝克尔(利物浦)、埃德森·莫赖斯(曼城)和卡斯帕·舒梅切尔(莱斯特)。在另一个极端,乌戈·洛里斯(托特纳姆)被迫做出名单上任何门将中最多的 90 次扑救,这也意味着最少的不失球。这表明他没有从他的防守线上得到太多的帮助,而是被迫承受许多对手进攻的冲击。

结束语

我希望这篇文章是有帮助的,试图可视化数据,以了解更多关于正在进行的英超联赛赛季的故事,而不仅仅是联赛排名。这篇文章的所有分析都可以在这个 Github 仓库中找到。

感谢您的阅读!我感谢任何反馈,你可以在推特上找到我,并在 LinkedIn 上与我联系以获得更多更新和文章。

如何用 Choropleth 图显示疫情冠状病毒

原文:https://towardsdatascience.com/visualizing-the-coronavirus-pandemic-with-choropleth-maps-7f30fccaecf5?source=collection_archive---------7-----------------------

关于 Choropleth 地图的介绍和教程

图片来自皮克斯拜米洛丝拉娃·克里斯诺娃

介绍

我非常支持数据可视化,因为我相信这是以简单易懂的方式说明和解释复杂信息,尤其是数字数据的最有效方法。此外,当正确执行时,可视化数据可以减少或帮助减轻数据解释中的偏差。

我最喜欢的可视化类型之一是动画 choropleth 地图。鉴于疫情正在进行,我认为现在是展示动画 choropleth 地图威力的好时机。

在本文中,您将了解以下内容:

  1. 什么是 choropleth 地图
  2. 何时以及为什么使用它们最有效
  3. Python 代码来创建您自己的 choropleth 地图,如下所示:

Choropleth 地图

choropleth 地图是一种专题地图,其中区域或地区按照给定数据变量的比例进行着色。

当您想要按区域比较所需变量时,静态 choropleth 图最有用。例如,如果你想比较某一时刻美国各州的犯罪率,你可以用一个静态的 choropleth 来显示。

一个动画动态弦线图类似于一个静态弦线图,除了你可以随时间按区域比较一个变量。这增加了第三维度的信息,也是这些可视化变得如此有趣和强大的原因。

可视化冠状病毒疫情

我用来创建以下可视化效果的数据是 Kaggle 的新 Corona Virus 2019 数据集,可以在这里找到。该数据集由多个来源组成,包括世界卫生组织、中华人民共和国国家卫生委员会和美国疾病控制中心。

注意:如果这些来源中的任何一个未能提供准确和及时的数据,可视化可能会失真或不准确。

静态 Choropleth

以下是截至 2020 年 3 月 28 日各国冠状病毒确诊病例总数的静态分布图。你可以看到,病例数量最多的国家包括美国、中国、意大利以及其他几个欧洲国家。

冠状病毒确诊病例的静态霍乱弧菌

创建它的代码如下:

**# Import libraries**
import numpy as np 
import pandas as pd 
import plotly as py
import plotly.express as px
import plotly.graph_objs as go
from plotly.subplots import make_subplots
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)**# Read Data**
df = pd.read_csv("../input/novel-corona-virus-2019-dataset/covid_19_data.csv")**# Rename columns**
df = df.rename(columns={'Country/Region':'Country'})
df = df.rename(columns={'ObservationDate':'Date'})**# Manipulate Dataframe** df_countries = df.groupby(['Country', 'Date']).sum().reset_index().sort_values('Date', ascending=False)
df_countries = df_countries.drop_duplicates(subset = ['Country'])
df_countries = df_countries[df_countries['Confirmed']>0]**# Create the Choropleth**
fig = go.Figure(data=go.Choropleth(
    locations = df_countries['Country'],
    locationmode = 'country names',
    z = df_countries['Confirmed'],
    colorscale = 'Reds',
    marker_line_color = 'black',
    marker_line_width = 0.5,
))fig.update_layout(
    title_text = 'Confirmed Cases as of March 28, 2020',
    title_x = 0.5,
    geo=dict(
        showframe = False,
        showcoastlines = False,
        projection_type = 'equirectangular'
    )
)

请注意,您真正做的只是设置几个参数来引用数据集中的特定变量,如位置位置模式z 。代码的其余部分用于更改 choropleth 地图的外观。

动画 Choropleth 地图

你可以看到动画的 choropleth 地图比静态地图更有效,更吸引人。在这里,我们正在查看一段时间内各国确诊的冠状病毒病例总数。你可以看到,直到最*,中国的病例数一直是最多的。

创建它的代码如下:

**# Manipulating the original dataframe**
df_countrydate = df[df['Confirmed']>0]
df_countrydate = df_countrydate.groupby(['Date','Country']).sum().reset_index()
df_countrydate**# Creating the visualization**
fig = px.choropleth(df_countrydate, 
                    locations="Country", 
                    locationmode = "country names",
                    color="Confirmed", 
                    hover_name="Country", 
                    animation_frame="Date"
                   )fig.update_layout(
    title_text = 'Global Spread of Coronavirus',
    title_x = 0.5,
    geo=dict(
        showframe = False,
        showcoastlines = False,
    ))

fig.show()

感谢阅读!

如果你喜欢我的工作,想支持我…

  1. 支持我的最好方式就是在Medium这里关注我。
  2. Twitter 这里成为第一批关注我的人之一。我会在这里发布很多更新和有趣的东西!
  3. 此外,成为第一批订阅我的新 YouTube 频道 这里
  4. LinkedIn 上关注我这里
  5. 在我的邮箱列表 这里报名。
  6. 看看我的网站,terenceshin.com

相关文章

[## 使用 Plotly 实现冠状病毒数据可视化

新型冠状病毒 2019 数据集分析及代码

towardsdatascience.com](/coronavirus-data-visualizations-using-plotly-cfbdb8fcfc3d) [## 9 种有趣的新型冠状病毒统计和数据可视化

以下是你应该知道的关于冠状病毒的知识

towardsdatascience.com](/9-fascinating-novel-coronavirus-statistics-and-data-visualizations-710cfa039dfd)

资源

[## Choropleth 地图

如何用 Plotly 在 Python 中制作 choropleth 地图?

plotly.com](https://plotly.com/python/choropleth-maps/) [## 新型冠状病毒 2019 数据集

新冠肺炎受影响病例的日水*信息

www.kaggle.com](https://www.kaggle.com/sudalairajkumar/novel-corona-virus-2019-dataset)

在美国可视化新冠肺炎

原文:https://towardsdatascience.com/visualizing-the-coronavirus-spread-cef4ae0dd38?source=collection_archive---------25-----------------------

跟踪美国各县冠状病毒爆发的交互式 choropleth 地图和仪表板

陈家米兰达·朗

我们最新的地图追踪证实了美国各县每*方英里的新冠肺炎病例

随着冠状病毒(新冠肺炎)爆发现已成为疫情,出现了许多工具来跟踪该病毒的新确诊病例,从在线数字地图到详细的仪表板。这些工具有助于对抗这种疫情。他们帮助公共卫生官员协调应对工作,并让公民更好地了解病毒的影响范围,以便他们能够做好相应的准备。

尽管这些地图无疑是重要的,但许多地图缺乏必要的粒度,无法将新确诊的病毒病例置于“大范围”的背景中。在像加利福尼亚这样的大州,观察全州范围内的病例对国家卫生官员来说可能是有价值的,但对州官员、地方官员或普通公民来说就没那么有帮助了。此外,由于人口密度高,病例往往偏向较大的城市地区,而不利于农村和郊区。

我们的目标是创造几个互动的可视化场景,将疫情的方方面面融入其中。

  1. 累积地图-可视化每个县的案例总数
  2. 每*方英里地图-可视化每个县每*方英里的案例
  3. 人均-可视化每 100,000 人中的人均病例数

还应注意的是,由于选择性检测和无症状个体,数据无疑遗漏了许多病例。这些想象虽然不完整,但对我们理解和抗击疫情的集体努力仍然很重要。

约翰·霍普金斯大学的可视化技术过于具体,使得数据难以掌握

health map的可视化过于宽泛,使得数据难以解读

考虑到这些因素,我和我的团队试图在这些现有的地图上进行构建。我们的目标是创建一组视觉效果,为普通市民和当地卫生官员更好地呈现适当规模的疫情。我们认为,郡尺度的 choropleth 地图是准确显示美国各地新冠肺炎新增确诊病例的最佳方式。

早期发展

该团队目前由来自卡内基梅隆大学和纽约大学的三名成员组成。如果你认为你能帮忙,请联系我们!

Jason Zhu——项目和设计负责人
;陈家——开发负责人
;Miranda Luong——研究设计&

在最初的地图开发之前,我们注意到许多大学生开始编制他们自己的高等教育机构和被关闭事件的列表。通过最少的开发,我们很快就建立了一个由受疫情影响的机构事件组成的众包知识库。这项工作由社区众包,并成为产生更全面的地图兴趣的工具。例如,一个的 reddit 帖子在 NYU 的 subreddit 上吸引了超过 1000 个独立访客,并在 Reddit 和 Twitter 上转发。

截至 3 月 16 日,已经上线的大学初步名单。

初始累积地图可视化

使用 Mapbox GL JS公共数据集,我们开发了一个显示确诊病例的美国地图——类似于上面提到的 HealthMap 可视化。然后,我们将每个坐标标绘到相关的县上。我们认为这是一个适当的粒度——对各级政府和普通公民都有用。为了不忽略查看各州数据的重要性,我们还将美国各州的数据显示在左侧。

以公开可用的美国各县 GeoJSON 边界文件为例,我们使用 Node.js 为每个县添加属性,记录每个日期的确诊病例数。这些数据来源于 UW GitHub 知识库,其中概述了每个案例、确认日期和坐标。

我们数据可视化的初始版本

在一天多的时间里,我们能够创建一个 choropleth 地图,将每个确诊病例坐标与其相关的县进行映射。虽然还处于初级阶段,但这是我们所知的第一次在县一级成功绘制美国冠状病毒病例的努力。我们认为,由于难以找到必要的数据,以前没有这样做过。

该地图的一个缺点是,它可能会歪曲新冠肺炎是如何在美国蔓延和增长的。随着美国的测试能力刚刚开始提升,随着时间的推移,这是可视化数据的必然结果。

从右到左:我们的累积 choropleth 图的三次迭代。

每*方英里和人均地图可视化

随着初始地图的发布,我们开始着手解决累积氯图所呈现的一些问题。举例来说,累积地图可能会忽略新冠肺炎是如何影响农村地区的,因为它倾向于容易进行测试和人口众多的地方。

每*方英里地图

每 10 万人地图

虽然这项工作仍在进行中,但我们会邀请您在 coronashutdown.com 参观我们的可视化项目。

如果您想参与或有任何反馈,请联系我。

非常感谢 Lucy Zhu 和其他人的编辑和反馈

可视化新冠肺炎曲线

原文:https://towardsdatascience.com/visualizing-the-covid-19-curve-a5f99f4de43f?source=collection_archive---------41-----------------------

每个人都知道我们需要使曲线变*。我们进展如何?

图片: navy.mil

《纽约时报》发布了一组数据,让我们可以查看美国各州、各县的新冠肺炎和相关死亡病例的传播情况。

我们将利用这些数据来观察病毒传播迅速的两个地方:纽约和加利福尼亚。这些数据意义重大,不仅因为它们是最大的州,还因为这些数据可以让我们深入了解社会隔离和就地安置等“曲线拉*”程序有多有效。

但是,由于这只是对数据的快速回顾和可视化,我们将尽量不要得出太多的结论。事实上,我们可以从数据中得出的一个结论是,基于简单的分析就自满太容易了。另一个结论是,即使在加州,我们的情况也很糟糕。除此之外,我邀请你检查数据并得出你自己的结论。

用 Python 提取数据

如果您对提取数据的技术方面不感兴趣,请随意跳到下一节,我们将在这里查看线图。

首先,我们从纽约时报的 github 账号 中提取数据。一旦我们建立了这个过程,我们可以简单地重新运行相同的代码,每天重新提取数据,以获得最新的数据集。本页结果完成于 2020 年 3 月 29 日。毫无疑问,接下来的几天和几周,剧情会有所不同。

一个文件是县的,一个是州的,两者都包括累积的(不是新的,而是总数)病例和死亡。

import pandas as pdcounties_url = '[https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv'](https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv')
df = pd.read_csv(counties_url)
cal_counties_df = df[df['state'] == 'California']
ny_counties_df = df[df['state'] == 'New York']states_url = '[https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-states.csv'](https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-states.csv')
df = pd.read_csv(states_url)
ny_df = df[df['state'] == 'New York']
cal_df = df[df['state'] == 'California']

请注意,第一次感染发生在纽约(3 月 1 日)晚于加州(1 月 25 日),因此纽约的数据集不包括任何更早的日期。您可以通过运行以下命令来验证这一点:

cal_df['date'].min()
ny_df['date'].min()

为了使折线图正确排列,我们需要将那些具有零值的较早日期添加到纽约数据帧中。

ny_add_dates = pd.date_range(start=cal_df['date'].min(), end=ny_df['date'].min()).sort_values(ascending=True)[0:-1]ny_append_list = []for dt in ny_add_dates:
    ny_append_list.append([dt.strftime("%Y-%m-%d"), 'New York', 36, 0, 0])
new_ny = pd.DataFrame(
    ny_append_list,
    columns = ["date", "state", "fips", "cases", "deaths"])ny_extended_df = pd.concat([ny_df, new_ny]).sort_values(by='date')

现在,让我们设置 Python 方法,这将允许我们进行一些绘图:

import matplotlib.pyplot as plt# Plot a single line/location
def plot_loc(loc_df, name, col_name):
    fig, ax = plt.subplots()
    loc_df.plot(ax=ax, x='date', y=col_name, label=name, kind = 'line')
    plt.setp(ax.get_xticklabels(), rotation=30, horizontalalignment='right')
    plt.show()# Plot multiple lines/locations
def plot_locs(loc1, loc2, loc1_name, loc2_name, col_name):
    ax = loc1.plot(x='date', y=col_name, label=loc1_name, kind='line')
    loc2.plot(ax=ax, x='date', y=col_name, label=loc2_name, kind='line')
    plt.setp(ax.get_xticklabels(), rotation=30, horizontalalignment='right')
    plt.show()

看着这些数据

首先,我们将看看加利福尼亚州与纽约州的比赛:

plot_locs(cal_df, ny_extended_df, 'CA', 'NY', 'cases')

纽约(橙色线)和加州(蓝色线)的感染情况

如果你想对纽约和加州的感染情况做一个简单的比较,那就是了。如果你想知道纽约的情况有多糟糕,那就再考虑几件事情。首先,纽约比加州晚了一个多月才出现第一例感染。其次,加州的面积是纽约的两倍多。

换句话说,纽约的情况很糟糕。

但是我们加州人不应该如此自满。这可能不是因为我们在控制病毒方面比纽约做得更好(尽管也许我们的行动有所帮助),这可能只是因为纽约受到的打击要严重得多。加州早期的就地安置行动可能已经产生了影响(虽然我们不能仅仅通过查看这些数据来说),但加州的情况仍然非常糟糕。

让我们来看看纽约和加州各自的地块,而不是将加州的景色挤进纽约旁边的地块:

plot_loc(cal_df, 'CA', 'cases')
plot_loc(ny_extended_df, 'NY', 'cases')

纽约(左)和加州(右)的感染情况

注意 y 轴(每个图左侧的数字)。左侧图中纽约的最大值为 40,000。对于右边的加利福尼亚,最大值是 5000。换句话说,纽约的感染人数是加州的*十倍。这与我们看到的第一个联合地块非常一致。

但是曲线并没有完全不同。纽约和加州的感染率都呈指数级增长。换句话说,加州落后于纽约,但以这种速度,我们将很快赶上他们现在的水*。

现在,让我们问一个不同的问题:为什么纽约如此糟糕?从这些数据中很难回答这个问题,但是我们可以问纽约哪里这么糟糕?这个就好回答多了,应该很明显:纽约市。

我们可以用下面的代码提取纽约市的数据:

nyc_df = ny_counties_df[ny_counties_df['county']=='New York City'].sort_values(by='date')
nyc_add_dates = pd.date_range(start=cal_df['date'].min(), end=nyc_df['date'].min()).sort_values(ascending=True)[0:-1]nyc_append_list = []for dt in nyc_add_dates:
    nyc_append_list.append([dt.strftime("%Y-%m-%d"),'New York City', 'New York', 36, 0, 0])
new_nyc = pd.DataFrame(
    nyc_append_list,
    columns = ["date", "county", "state", "fips", "cases", "deaths"])nyc_extended_df = pd.concat([nyc_df, new_nyc]).sort_values(by='date')

请注意,纽约时报数据将所有纽约市列在一个名为“纽约市”的县下,而不是五个区中的每一个区下。

将纽约市与纽约州的其他城市相比较,我们会看到以下情况:

纽约市所有五个区(蓝线)和整个纽约州的感染情况

蓝线是纽约市,蓝线以上到橙线的所有区域都是州内城市以外的额外感染,包括附*和接壤的县。所以我们可以看到,不出所料,纽约市占了该州感染人数的很大一部分。考虑到纽约州的人口集中在纽约市,这是意料之中的。

但是,为了了解纽约市的情况有多糟糕,让我们将它与加州进行比较:

同样,我们不应该在加州过于自满,但要注意的是,仅纽约市的情况就相当糟糕。

最后,关于指数增长的一个注记。如果你已经学习了计算机科学的入门理论,不仅仅是编程,还有算法分析,一个很大的收获就是指数增长率是不好的。我们经常听到这个词棘手,也就是说,一个非常难以处理的问题,即使对于相对较小的指数曲线也是如此。

与纽约相比,加州的感染增长率可能相对较小,但仍呈指数增长,这仍然是一个非常糟糕的预兆。

可视化新冠肺炎对零售的影响

原文:https://towardsdatascience.com/visualizing-the-impact-of-covid-19-on-retail-sales-49ce73509b1f?source=collection_archive---------53-----------------------

零售业是受疫情影响最大的行业之一,而且可能永远不会恢复

来源:作者使用人口普查局月度零售报告的数据制作的图表

由于新冠肺炎造成的全球疫情现在已经延伸到 2020 年上半年之后,几个国家仍然每天报告数千例病例。最初的行动旨在遏制病毒的传播并使曲线变*以拯救生命,但也产生了严重限制经济活动的不幸影响,因为大多数人都呆在家里以遵守封锁措施。严重依赖人流量的部门被派往 UCI,数量空前的企业要么在有限的产能下工作,要么完全停止运营。尚不清楚一些行业是否会从冲击中恢复过来。

根据美国人口普查局(Census Bureau)的数据,零售业就是这样一个行业,在两个月内,调整后的零售额从 2 月份的 5273 亿美元增加到 4 月份的 4128 亿美元。这意味着总销售额下降了约 22%,也意味着许多企业关门,也许是永远关门。

数据

人口普查局定期发布全国零售数据,这些数据可以直接从官方网站下载。excel 文件包含自 1992 年以来所有月份的数据,每张工作表都以年份命名。从那里,我提取了调整后的数据(如果你对这个过程感兴趣,欢迎你访问Github 项目并查看转换和代码,对于情节复杂的情节使用 NBViewer )。

我选择了调整后的数据,因为显示的估计值是针对季节变化、假日和交易日差异进行调整的,这意味着图表中显示的影响将仅对应于新冠肺炎。使用调整后的数据的一个缺点是,未调整数据的一些细节会丢失,如下图所示。

来源:作者照片。数据来自人口普查局月度零售报告

来源:作者照片。数据来自人口普查局月度零售报告

调整后的切片中有更少的 NAICs,这意味着我们将使用组成每个代码的聚合。总的来说,调整后的数据有 30 个部门,这足以了解每个部门的总体情况。

疫情之前的现实

来源:作者使用人口普查局月度零售报告的数据制作的图表

在上图中,调整后的数据中确定的 30 个地区中的大多数都报告说 1 月份的销售额有所增长,只有一些例外。五个行业的利润率下降到 2%以下,只有燃油经销商似乎表现出“挣扎”的迹象,与 2019 年 12 月相比,下降了约 7.5%。

来源:作者使用人口普查局月度零售报告的数据制作的图表

2 月份几乎所有的零售行业都遇到了一些困难,行业整体下降了 0.44%,在 3 月份灾难降临之前,大多数行业的销售额都减少了相对较小的一部分。

封锁

来源:作者使用人口普查局月度零售报告的数据制作的图表

虽然一些地区在封锁措施下蓬勃发展,如杂货店、药店和非商店零售商;其他公司遭受了不成比例的冲击,比同行受到的伤害大得多。其中一个例子就是仅在三月份就损失了高达 50%的鞋店。

这种情况在 4 月份开始恶化,当时距离措施开始生效。4 月份只有两个行业出现增长,因为整个行业的销售额下降了创纪录的 14.71%。

来源:作者使用人口普查局月度零售报告的数据制作的图表

受封锁影响最大的是服装店、家具和家电商店、餐饮服务和饮酒场所、运动和爱好商店以及加油站。

仅凭直觉,这些结果并不令人惊讶,因为这些商店严重依赖流量来确保其大部分销售。它们还具有非必需品的性质,这意味着公众可以放弃这些支出,转而将资金用于购买危机情况下的必需品。

复苏的开始

随着 5 月初,一些州取消了限制,允许人们回到日常生活中。这些行动转化为大多数行业的销售增长,尤其是受疫情影响最大的行业。仅鞋店销售额就恢复了 200%以上,服装店恢复了 176.88%。

来源:作者使用人口普查局月度零售报告的数据制作的图表

然而,这些数字仍低于新冠肺炎封锁前的水*,如下图所示。

来源:作者使用人口普查局月度零售报告的数据制作的图表

结论

从冠状病毒的初始休克中恢复的小步骤正在进行中。令人高兴的是,在 2020 年 6 月月度报告的预览中看到了进一步改善的迹象,这标志着零售销售的总体增长约为 7.5%,正如华尔街日报所报道的那样。

然而,随着美国的病例数量日益增加,恢复封锁措施的可能性增加,5 月和 6 月取得的成果可能会付诸东流。

[1]人口普查局,零售业月度报告,(2020)

【2】h . Torry,美国随着商店重新开业,6 月份零售额增长 7.5%, (2020),华尔街日报

[3]世界计量仪,美国冠状病毒,(2020)。

视觉化虚无

原文:https://towardsdatascience.com/visualizing-the-nothing-ae6daccc9197?source=collection_archive---------17-----------------------

如何用 Python 可视化数据集的不完整性

很难知道如何处理数据中的空值。大多数时候,放下它们,继续做剩下的事情会更容易。

但它们最终会有意义,可以被研究。花些时间好好看看它们,通常可以更好地理解数据是如何收集的,甚至可以揭示其中的一些模式。

空值矩阵

在本文中,我们将探索如何可视化数据集中的所有空值,并看看我们可以从中获得什么样的见解。

我将在 Jupyer Lab 中运行代码,对于这个例子,我将使用 PandasNumpyMissingnoMatplotlib

数据集将是加州监狱概况调查,包含 1995 年至 2018 年每月县级数据。

import pandas as pdf = 'data/california_jail_county_monthly_1995_2018.csv'
df = pd.read_csv(f)

将数据集加载到 Pandas 之后,我们可以看看它处理空值的一种方便的方法。

我们可以利用。isnull 后跟一个. sum,并获取缺失值的个数。

df.isnull().sum()

空值按列计数

这已经很有用了,因为它让我们知道我们可以依赖哪些字段,但是有更好的方式来可视化它,让我们尝试使用 Missingno。

Missingno 是一个用于可视化数据集中不完整性的库,它工作在 Matplotlib 和 Seaborn 之上,使用起来毫不费力。

import missingno as msno

我们将从一个简单的条形图开始。我们将使用矩形和它们的大小,而不是比较大量的数字。

条形图

msno.bar(df)

空值的条形图表示

太好了!在一个方法中,仅仅传递数据帧,我们就已经有了丢失值的可视化表示。

此条形图代表每列中的记录数。这里我们有两个刻度,一个表示字段中值的确切数量(右),另一个表示占总行数的比例。

从条形图开始可以让我们快速判断是否需要花更多的时间来分析空值。

我们的数据并非如此,但如果您有一个没有任何空值或空值数量可接受的数据集,您现在可以停下来继续您的分析。

让我们尝试一种不同的可视化方法来显示缺失的值。

[数]矩阵

msno.matrix(df)

数据集的空值矩阵

矩阵告诉我们丢失值的确切位置,在我们的例子中,数据被排序,最新的记录在最上面。

通过查看矩阵并了解我们的数据是如何排列的,我们已经可以获得一些有价值的见解。在这里,我们可以看到收集的数据在某个时间点发生了变化,矩阵右侧的“*均囚犯获得心理健康床位”等字段被终止,其他字段被添加。

突出显示列组的矩阵

非常酷,矩阵的右边还有一个小的 viz,代表行的完整性——它们甚至标记了缺失值的最大和最小数量。

现在让我们来看看。热图,这将有助于我们理解关于不完整性的领域是如何相互关联的。

热图

msno.heatmap(df)

具有空值相关性的热图

好吧,事情变得复杂了——让我们简化一下。

此图按列表示空值之间的相关性。

A 列有一个值,B 也有一个值,这意味着强正相关或图表中的蓝色 1。

A 列有一个值,但 B 列有一个空值,这意味着强负相关,或者在图表中为红色-1。

突出显示的热图

我们之前注意到数据收集方式发生了一些变化,在这里我们可以再次看到这一点。新变量与自身正相关,但与旧字段负相关。

尽管我们可以通过查看矩阵来可视化这种关系,但热图使它们更加明显。为了实现这种模式,我们并不总是以一种方便的方式对行进行排序。

在这个数据集中,我们可以看到调查的字段几乎是分组的。

因此,如果回答了一个问题,我们很可能会得到该组中所有项目的答案。

突出显示各组的热图

好的,我想通过另一种方式,来形象化地展示场在空值问题上的关系。

系统树图

msno.dendrogram(df)

数据集的树状图

我们在热图中看到了一些群体行为,但主要是因为数据集的排列。

如果对进行排序,我们可以使用矩阵图表注意到字段之间的一些相关性,但是如果它们是随机放置的,这将更加困难。

同样的事情也发生在热图上。如果是随机放置的,我们将会有一段更具挑战性的时间来找出变量组之间的模式。

树状图使用分层聚类算法根据字段的相关性对其进行分类。**我们看到的与热图的关系。*

因此,这就像找出哪些字段在无效性问题上高度相关,然后测试这些变量组如何相互关联等等。

突出显示各组的树状图

同样,我们可以注意到不连续的字段,但我们可以更清楚地看到哪些变量可能更可靠。

该图说明了各组之间的联系,其中离零越远的联系表示无效性不太相似的变量的组合。

过滤器和 Matplotlib

Missingno 是快速可视化缺失值的优秀工具;我们对每个图表只使用了一行代码,得到了一个相当不错的结果。

该工具具有一些过滤功能,可以选择和排列我们想要绘制的变量。它允许我们自定义图表的某些方面,所有这些都在同一个语句中。

对于任何你不能直接用 Missingno 定制的东西,你都可以去 Matplotlib。

from IPython.core.display import display, HTML
import matplotlib.pyplot as plt
import numpy as np# define matrix for the 13 columns with most nulls
**m** = msno.matrix(df, figsize=(25, 14),
                **filter='bottom', n=13**, 
                color=(0.3, 0.3, 0.5))# get ticks names and positions
cols = [i.get_text() for i in **m.axes.get_xticklabels()**]
ticks = np.arange(0,len(cols))# plot new ticks
**plt.xticks**(ticks, labels=ticks+1, rotation=0, ha='center')# title n plot
**plt.title**('Null values matrix\n'.upper(), loc='left', fontsize=22)
plt.show()# empty string for the HTML and template for div
html_table = ''
template = '<div style="border-style:solid; display: inline-block; width: 325px; padding-left: 5px; border-width: thin" >{} - {}</div>'table_order = [1, 6, 10,
               2, 7, 11,
               3, 8, 12,
               4, 9, 13,
               5]# draw table
for i in table_order:
    html_table += template.format(i, cols[i-1])HTML(html_table)

空值最多的 13 列的空值矩阵

很好,我们了解了可视化和分析数据集完整性的基础知识。有趣的是,我们可以通过可视化数据缺失的值来了解这些数据。

感谢阅读我的文章。我希望你喜欢它。

在这里你可以找到更多关于 Python 和数据可视化的教程。

资源:
https://pandas . pydata . org/pandas-docs/stable/reference/API/pandas . is null . html
https://github.com/ResidentMario/missingno

想象新冠肺炎对全球经济的影响

原文:https://towardsdatascience.com/visualizing-the-pandemics-impact-on-the-global-economy-with-plotly-169f31963eb3?source=collection_archive---------60-----------------------

理解四种数据可视化中的疫情效应

凯尔·格伦在 Unsplash 上的照片

目录

  1. 简介
  2. 冠状病毒与股市
  3. 冠状病毒与失业率
  4. 冠状病毒和黄金
  5. 冠状病毒和消费者信心
  6. 奖金

数据和代码可以在这里找到:https://github.com/terenceshin/Covid_Impact_on_Economy

介绍

随着我们接** 400 万例冠状病毒病例、* 25 万例死亡和数月的隔离,我们都同意它极大地影响了我们的日常生活。但这不是唯一受影响的事情。

全球经济中断如此之多,以至于有些人想知道第二次大萧条是否正在向我们走来。虽然目前这只是一种猜测,但我们可以通过客观数字看到,疫情确实正在影响我们的经济。下面是一些统计数据和可视化数据,让你更好地理解目前的经济状况。

冠状病毒和股票市场

标准普尔 500 指数

S&p500 正在下跌。简单来说,标准普尔 500 指数基本上代表了美国 500 家最大的上市公司。今年早些时候,标准普尔 500 指数从最高点下跌了 30%以上——上次标准普尔 500 指数下跌这么多是在 2008 年的经济衰退期间。

你可能会问,“为什么疫情会导致股市下跌这么多?”从理论上讲,股票市场是我们经济运行状况的反映,并且受到许多因素的影响,比如利率。但实际上,股票市场反映了我们对经济在不久的将来会有多好的预期。由于这场疫情引发了很多对未来的不确定性,投资者一直在抛售股票套现,这反过来又降低了股市的价值。

当然,不确定性不是唯一的因素。还有许多其他指标,如失业率和消费者信心,表明经济放缓。这让我们有了下一个洞见…

冠状病毒和失业率

历史失业率

失业率正在上升。2008 年经济衰退后,失业率从 10%一路稳步下降到今年 2 月的 3.5%。然而,从 2 月到 3 月,失业率从 3.5%增加到 4.4%,增幅超过 25%。这可能只是个开始……高盛预测今年失业率可能达到 15%的峰值

举个例子,2008 年衰退期间的最高失业率是 10%。这既可怕又糟糕,因为失业率影响到每个人。更高的失业率意味着家庭的可支配收入将减少,这意味着公司的收入将下降,从而导致更多的裁员,这一循环还在继续。

冠状病毒和黄金

GLD 信托价格

黄金正在增值。当经济形势恶化时,黄金往往会升值,这种情况也不例外。对那些感兴趣的人来说,从技术上讲,黄金没有内在价值。你不能去杂货店用黄金买食品杂货。但黄金在古代文明中是一种货币,从那时起,它就被社会建构并被视为价值储存手段。因此,这可能是另一个迹象,表明我们的经济正在走下坡路。

冠状病毒与消费者信心

消费者信心下降。经合组织对消费者信心的定义如下:

「这个消费者信心指标提供了家庭消费和储蓄未来发展的指标,是根据对他们预期的财务状况、对整体经济状况的看法、失业情况和储蓄能力的回答而得出的。高于 100 的指标表明消费者对未来经济形势的信心增强,因此他们不太倾向于储蓄,而更倾向于在未来 12 个月内花钱购买大件商品。低于 100 的数值表明对经济未来发展的悲观态度,可能导致更多储蓄和更少消费的趋势。”

从上面的图片来看,消费者信心指数已经下降到 100 以下,我预计在接下来的几个月里会继续下降。这是什么意思?报告称,数值低于 100 表明对未来经济发展持悲观态度。这与我们在上面看到的其他指标是一致的。

如果消费者认为*期前景黯淡,并决定增加储蓄,这意味着经济中流通的货币会减少,这意味着企业赚钱会减少,裁员会增多。

奖金

  • 世界上 90%以上的人生活在有旅行限制的国家。这对航空业产生了重大影响,因为许多航空公司已经解雇了数千名员工。点击 这里 如果你想了解更多。
  • 从更积极的方面来看,世界各地的空气污染正在急剧下降。呆在室内意味着路上的汽车更少,经济放缓意味着产量减少。一月和二月,中国的 NO₂水*下降了 40%。点击 这里 如果你想了解更多。

感谢阅读!

如果你喜欢我的工作并想支持我,我会非常感谢你在我的社交媒体频道上关注我:

  1. 支持我的最好方式就是在媒体这里关注我
  2. 在推特上关注我这里
  3. 点击这里订阅我的新 YouTube 频道
  4. LinkedIn 这里关注我。
  5. 在我的邮箱列表 这里注册。
  6. 查看我的网站terenceshin.com

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

可视化冠状病毒爆发的进程

原文:https://towardsdatascience.com/visualizing-the-progression-of-the-coronavirus-outbreak-a586cf1dc879?source=collection_archive---------29-----------------------

章节

前几天我发表了一篇文章,分析了冠状病毒(新冠肺炎)在中国的社会影响。然而,总的来说,一些人仍然对这次疫情缺乏充分的了解。我认为从一个更客观的角度来想象这种情况会很有趣。

如何开始

首先,我从网络搜集开始,从中国国家卫生委员会提取数据,并使用表格从空间上可视化疫情进展。我还创建了一个 仪表板 ,我们可以在其中轻松地切换日期和省份,以便更仔细地查看。

冠状病毒进展仪表板由 Ashley

免责声明:

请注意,我收集的数据截止到 2 月 11 日。当你读到这篇文章的时候,这些数据可能已经跑偏了,不能反映这次疫情的现状。我将在本文的后面解释有一种简单的方法来跟上实时数据。我使用了一个 网页抓取工具 来提取数据,而不是编码,因为它可以将数据转换为可行的格式,而无需清理数据。

选择数据源:

如果你谷歌冠状病毒数据,我相信你会找到很多资源。像 Kaggle 这样的来源是其他人收集的二手数据,这些数据落后于像中国官方健康网站这样的主要来源的最新数据。如果你是一个对准确性和及时性有严格标准的数据分析师,你应该避免用二手数据下结论。那么你应该使用什么来源呢?原始数据是你选择的。此时,我选择了冠状病毒更新源,因为它被保存为 JSONs,使我们能够通过 API 管道将各个城市的数据传输到我们的系统。(阅读这个 JSON 文件的指南)

八分网页抓取 JSON

刮模板

另一种提取实时数据的方法是使用一个抓取模板,就像我在上一篇文章中做的那样。对于不会编码的人来说,这是一个现成的解决方案(观看此视频了解详情)。您可以设置任务计划程序来获取最新数据。这是我收集的数据,可以随意使用。

用 Tableau 实现数据可视化

在获得大量数据后,我们可以将其上传到 Tableau。我首先创建一个地图层,只需将省/州拖放到拖放字段中。之后,我添加时间序列并累加数值,以全面展示每个省的数据趋势。我把湖北省画出来,因为我可以特别注意它的数据趋势。该地图显示了自 1 月 22 日以来过去 20 天冠状病毒的历史传播情况。截至 2 月 11 日,仅湖北一地的确诊感染人数就达到了 33366 人。

阿什利冠状病毒爆发

我们可以看出,除了湖北,这次疫情对广东、浙江、湖南和河南的影响也很大。

不同省份报告的病例

请注意,湖北报告的病例明显多于所有其他病例的总和。我创建一个群,把他们分成两类:湖北和其他。为了更好地了解此次疫情的发展方向,我还添加了趋势线来分析当前形势。

湖北和其他地区都开始下滑到趋势线之下,这表明确诊病例呈下降趋势。然而,死亡人数并没有显示出积极的变化,因为数字仍然高于趋势线。

冠状病毒爆发湖北 vs .其他

冠状病毒爆发湖北 vs .其他

除了湖北以外,各省的复苏速度似乎是一些令人高兴的消息,因为随着时间的推移,趋势线变得更加强硬,更多的地方向上移动,表明复苏有所倾斜。恢复率将继续增长,因为人们现在正在迅速采取行动击败病毒。

回收率增长

最终想法:

我制作了动画,因为这是一个很好的方式来理解大画面,我们能够看到这次疫情的进展。一旦我们将数据可视化,分析就变得容易多了。数据分析中最大的挑战是数据收集。我通常会把大部分时间投资在无需动脑的劳动上。通常,我还需要手动修复数据格式。我发现网页抓取工具可以大大提高工作效率。但是,我不会建议过度滥用和刮擦任何网站。这将导致严重的法律后果。查看这篇文章了解更多信息:网络爬行合法吗?

我会努力提高可视化,并随时分享你的想法和电子邮件给我。

原载于 2020 年 2 月 14 日 https://www.octoparse.com**

用 Python 散景可视化股票市场

原文:https://towardsdatascience.com/visualizing-the-stock-market-with-python-bokeh-d40d9d1f288e?source=collection_archive---------5-----------------------

创建交互式股票价格仪表板的初学者指南。

克里斯·利维拉尼Unsplash 上拍摄

为什么可视化很重要

要建立你的交易*台,你还需要有一个可视化你的股市数据的方法。最简单的方法之一你可以选择 TradingView ,它有一个极好的分析金融市场数据的想法。

但是,您可能有特定的需求,比如在某种程度上比较两只股票的价格。大部分网络*台都支持不了这种情况。或者,如果你已经有一些自动化,你需要一个工具来可视化你的交易策略。

在这篇文章中,我将向你展示我如何开始在我的每日交易*台中建立我的可视化。在过去的几年里,我尝试了很多可视化框架,并且散景可以支持我的大多数用例。

也许你对 Python 中绘图的matplotlibseaborn比较熟悉。然而,金融数据,尤其是价格历史可视化在交互时更好。 散景可以用多个复杂的图表创建丰富的交互式仪表盘。

如果你对我如何尝试其他框架感兴趣,请查看附录。

什么是散景?

散景是一个可视化库,可以很容易地创建功能强大的交互式绘图。

散景图可以导出为静态图像,或者嵌入到网页中。该库有一个内置的应用服务器,可以作为交互式仪表板的后端。

另一方面,散景也是一个低级的库,因为它允许我们控制一个情节的所有方面,包括交互和样式。

但是,散景也是简单易用和强大的,因为在几行代码中,你可以有多种多样的互动情节。为了对散景图有所了解,让我们来看看 MSFT 股票的一个简单图:

MSFT 每日股票价格烛台

开始前,数据

从可视化开始,我们需要先谈谈数据。

在本文中,我们将使用从使用雅虎金融 API 的 Python 的免费股票数据中提取的 OHLCV 数据。先看看这个帖子,你应该能得到你想要的数据。或者你已经有了自己的 OHLC 股票数据。

数据格式如下:

这里我们将使用 MSFT 日报 OHLCV 数据作为例子,并建立一个与历史股票价格相关的仪表板。你可以把它应用到任何金融符号上。

你可以在这里下载我的示例数据

入门指南

根据您的设置,使用conda install bokehpip install bokeh安装散景很简单。

该库不仅提供了 Python 包,还提供了一个名为bokeh的 CLI,用于运行bokeh app server。你可以通过命令行bokeh serve — show xxx.py轻松运行散景。

基本概念

编译后,JavaScript 客户端库将在浏览器中呈现可视元素并处理散景图的 UI 交互。不需要控制 JavaScript 部分。

注意,使用bokeh.plotting界面创建的散景图带有一组默认的基本字形。字形有多种形式:字形、线字形、文字、其他。对于主要用途,散景图就足够了。

每个散景图由一组模型组成。构成散景“场景图”的最低级别对象。这些都存在于bokeh.models接口中。最终,所有的散景图都由模型集合组成,这给了你对图的绝对控制,它通常不会被直接使用。

散景服务器用于将散景图作为静态页面共享和发布,或者在浏览器中部署应用。

基于以上所掌握的知识,我们应该能够用市场数据画出一个图来。

使用股票历史价格数据源绘图

为了使绘图更加简单和清晰,我们使用了ColumnDataSourceColumnDataSource是散景的基本数据结构。大多数图、数据表等。将由一辆ColumnDataSource驱动。可以像字典一样定义ColumnDataSource,然后从pandas.dataframe导入。

使用基本的字形vbar来渲染基于ColumnDataSource的烛台。

基本代码如下所示:

运行bokeh serve — show xxx.py显示图形:

自定义日期标签

到目前为止,我们只处理了标准数据。这个情节有很多问题。有一点是 x 轴索引不正确。通常,我们可以显示索引号。然而,股票价格是按日期排序的时间序列数据,我们需要绘制一个时间范围并显示确切的日期。我们需要建立一个从索引到日期字符串的映射。

默认情况下,一个图中只有五个分笔成交点。为了显示每一天,我们必须设置刻度数。

更新了代码:

更改后,现在日期 x 轴清晰多了。

自定义货币

这里我们再次使用 Bokeh 的货币格式:($ 0.00 a),它将以百万为单位输出数值。对于其他预定义的格式和各种格式化程序,请参见格式化程序文档

自定义绘图工具悬停工具

你可能已经注意到,散景为每个图提供了一个工具栏。工具允许缩放*移选择数据并执行其他动作。

悬停工具是一种检查工具。它通常一直处于打开状态,但可以在与默认隐藏的工具栏相关联的检查器菜单中进行配置。默认情况下,悬停工具将生成一个工具提示,其中每行包含一个标签和相关值。

通过添加带有标签的工具提示更新了代码:日期时间、打开、关闭、体积。可以根据自己的选择添加更多。

下面是修改后的工具提示:

包裹

到目前为止,您已经学会了如何:

  • 基于 OHLCV 股票数据创建带有字形的图。
  • 用日期时间标签配置图。
  • 配置自定义布局和工具提示。

现在你应该可以开始建立你的仪表板,开始你的算法交易分析。如果你想知道更多关于这个话题的信息,请留下你的评论,让我知道。

代码和数据

下面附上我的代码,示例数据是这里是

附录:其他框架

以下是我对其他框架的评论:

  • Matplotlib 财务-> mpl_finance -> mplfinance
  • Viser

Matplotlib finance,已被弃用,已被移到一个名为mpl_finance的模块中。还有,mpl_finance是贬义,会有新版本 mplfinance (估计 2020 年年中替换)。

与我去年使用的相比,新的打印机相当不错。

价格和成交量图

相比于散景,很难做到交互。如果对于基本用例。这应该是一个快速的解决方案。由于它仍在开发中,我建议在 2020 年中期使用它。

我尝试过的另一个框架是 Viser 。如果你喜欢 JavaScript 技术栈。我做了一个 Viser 的投资组合图。然而,Viser 的社区支持非常差。您必须知道许多技巧,才能使它与其他 JavaScript 库一起工作。

可视化白宫新冠肺炎疫情

原文:https://towardsdatascience.com/visualizing-the-white-house-covid-outbreak-f5e35b01ae26?source=collection_archive---------44-----------------------

作者图片

新闻充斥着 COVID 在白宫行政部门的传播,所以让我们立即进入下图的代码和可视化。数据集在此。 此处代码。

方法论

使用《纽约时报》的文章追踪白宫冠状病毒爆发,我们可以创建一个快速的 excel 表格,列出特朗普总统宣布 COVID 检测呈阳性之前与他在一起的所有人。

作者图片

作者图片

最无聊的部分是,又多了一个数据集来匹配缩写名和全名。数据集在这里所以你可以跳过这个过程。

为了创建可视化效果,我使用 Python 将 events 数据集转换成网络可视化格式的数据集,并使用 Gephi 来可视化网络。

作者图片

关于网络可视化和 Python 的说明

在我们开始为 Gephi 准备这些数据之前,我只想简单谈谈网络可视化数据集和 Python 的准备工作。网上很多教程提到“网络可视化”这几个字就会带进 NetworkX 。然而,我发现 NetworkX 对于很少或没有接触过网络分析的初学者来说是不直观的,尤其是与 TidyText (R)之类的东西相比,它真的可以指导您完成网络分析+基于文档/文本的关系提取和分析。

因此,如果您打算深入研究——在编写任何代码之前,先读一点资料,并尝试一下网络可视化。对你能运行的统计数据和你能创建的网络感兴趣。一个很棒的资源是网络知识库,它有一个交互式图形 Vis 页面,可以立即将你吸引到你可以从一个网络中学到的奇妙的东西,而不仅仅是 Twitter 上谁关注谁的基础知识。

当您准备好之后,请认真考虑如何创建您一直在尝试的网络数据集格式。对于小型网络,您可以用不到 20 行的代码编写必要的脚本,使用您已经熟悉的库和函数来准备数据集。

准备数据

使用 pandas,导入数据集并使用 ast.literal_eval 将出席特朗普总统活动的人员列表的字符串表示转换为列表。

import pandas as pd
import os
from path import Path
import ast 
import itertools# set directory to where this file is located
folder_loc = os.path.dirname(os.path.realpath(__file__))
os.chdir(Path(folder_loc))events_df = pd.read_excel('events.xlsx')
ppl_df = pd.read_excel('ppl.xlsx')output_name = 'edges.csv'# convert str list to list -- please excuse the following these
# apply(lambda x)'s.. this quick script isn't industrial strength in
# efficiency
events_df['ppl'] = events_df['ppl'].apply(lambda x: ast.literal_eval(x))

我们的目标是创建两列: SourceTarget ,它们表示任何给定的两个人之间的联系,前提是他们都与 Donald Trump 参加了同一个活动。

因此,我们首先获得列表的所有可能组合,每个组合代表一个事件的参与者。然后,我们分解刚刚创建的元组列表,以创建目标列。

# new column of all combinations possible
# whats cool about itertools combos is that it doesn't do duplicates
# e.g. (DT, KM) (KM, DT)
events_df['combos'] = events_df['ppl'].apply(
    lambda x: list(itertools.combinations(x, 2)))# reshape dataframe with source target
events_df_exploded = events_df.explode('combos')# create source and target rows
def src_targ(combo):
    lst = list(combo)
    return pd.Series([lst[0], lst[1]])events_df_exploded[['src', 'tar']
                   ] = events_df_exploded['combos'].apply(src_targ)

接下来,我们用全名替换姓名缩写,清理我们的列,并为 Gephi 导出我们的 csv 文件。我还添加了代码来导出单个数据集,每天一个,以防对您自己的项目有所帮助。

# add in the real names of everyone
events_df_exploded = pd.merge(events_df_exploded, ppl_df, how='left',
                              left_on='src', right_on='abbrev')
events_df_exploded = pd.merge(events_df_exploded, ppl_df, how='left',
                              left_on='tar', right_on='abbrev')# clean up
events_df_exploded.rename(columns={'name_x': 'Source',
                                   'name_y': 'Target'},
                          inplace=True)events_df_exploded = events_df_exploded.drop([
    'ppl', 'combos', 'abbrev_x', 'abbrev_y', 'src', 'tar'],
    axis=1)# export file
events_df_exploded.to_csv(output_name)# export batches by day
df_grouped = events_df_exploded.groupby('date')# iterate and export
for group_name, df_group in df_grouped:
    print(group_name)
    out_name = output_name.replace(
        '.csv', '') + '_' + str(str(group_name).split(' ')[0]) + '.csv'
    df_group.to_csv(out_name)

基于 Gephi 的网络可视化

关于 Gephi 要知道的第一件事是,它对你导入的数据集的格式和列标题非常特别。虽然我已经很多年没有使用 Gephi 了,但我很高兴地看到今天网上有更多的文章和视频解释 Gephi 的怪癖。一定要在谷歌上搜索一下,看看 Gephi 的插件,寻找新的想法和未来的项目。

使用 Data Laboratory 屏幕将节点和边数据集导入 Gephi 后,使用概览屏幕左侧的外观选项卡中的参数,以及屏幕右侧和底部的过滤和布局。当您对可视化效果感到满意时,单击预览选项卡并导出您的图像。我用 photopea 把出口和标题放在一起。

就是这样!

还有两件事。如果你或你的学生有热情,但不知道如何或何时,找一个安静的地方,用一支不起眼的笔(转述自保罗·西蒙)。实际上,尝试一下 NodeXL 吧——每份学生许可证 39 美元,在 Twitter 抓取、网络可视化(虽然很慢)和数据集准备(如果你愿意,可以将其导入 Gephi)方面,它包含了一些非常强大的功能。对于非编码人员来说,这是一个轻松的好方法。

作者图片

对于跟随本教程的每个人来说,这里有一些你可能想不到在 Gephi 上看的地方,它们对于创建视觉效果非常关键,而不需要在论坛上寻找答案。整个项目花了我大约 2 个小时,最大的时间消耗(除了开始输入 excel 表格)是记住东西在 Gephi 中的位置。所以,确保你对你想要想象的东西有一个清晰的画面(一直到调色板),放上一些高保真的音乐来放松/学习,然后投入进去。

关于我:Basil Labs 的创始人,Basil Labs 是一家大数据消费者智能初创公司,帮助组织量化消费者的去向和价值。

热爱音乐,开放数据政策和数据科学。更多文章请关注我的媒体
如果你对数据伦理、开放数据和/或音乐充满热情,欢迎在 Twitter 上加我。

使用 Python 可视化三维数据-热点图、等值线和 3D 绘图

原文:https://towardsdatascience.com/visualizing-three-dimensional-data-heatmaps-contours-and-3d-plots-with-python-bd718d1b42b4?source=collection_archive---------3-----------------------

Python 科学绘图

使用 Python 绘制热点图、等值线图和 3D 图

USGSUnsplash 上拍摄的照片

当您测量属性对多个独立变量的依赖性时,您现在需要绘制三维数据。这种例子通常发生在空间测量中,其中存在与每个(x,y)点相关联的强度,类似于光栅显微镜测量或空间衍射图案。为了可视化这些数据,我们有几个选项可供选择——我们将探索创建热图、等高线图(未填充和填充)和 3D 图。

我将在这个例子中使用的数据集是来自原子力显微镜(AFM)的一张 2 m x 2 m 的显微照片。首先,我们导入包——我们这次添加的两个新包是make_axes_locatable,它将帮助我们管理我们的绘图的色条,以及我们的 3D 绘图所需的Axes3D:

# Import packages
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

我们现在将加载我们的 AFM 数据,再次使用numpy.loadtxt将我们的数据直接加载到 2D numpy数组中。

# Import AFM data
afm_data = np.loadtxt('./afm.txt')

然后,我们可以检查我们加载的数据中的几行:

# Print some of the AFM data
print(afm_data[0:5])>>> [[4.8379e-08 4.7485e-08 4.6752e-08 ... 6.0293e-08 5.7804e-08 5.4779e-08]
 [5.0034e-08 4.9139e-08 4.7975e-08 ... 5.7221e-08 5.4744e-08 5.1316e-08]
 [5.2966e-08 5.2099e-08 5.1076e-08 ... 5.4061e-08 5.0873e-08 4.7128e-08]
 [5.7146e-08 5.6070e-08 5.4871e-08 ... 5.1104e-08 4.6898e-08 4.1961e-08]
 [6.2167e-08 6.0804e-08 5.9588e-08 ... 4.7038e-08 4.2115e-08 3.7258e-08]]

我们有一个 256 x 256 的点数组,每个值对应于该位置的测量高度(以米为单位)。因为我们知道如果用纳米表示,我们的数据会更有意义,所以我们可以用这个常数来衡量我们所有的值:

# Convert data to nanometers (nm)
afm_data *= (10**9)

现在我们可以开始可视化我们的数据了。我们从设置一些全局参数开始(随意编辑这些参数,但这些是我使用的设置):

# Edit overall plot parameters# Font parameters
mpl.rcParams['font.family'] = 'Avenir'
mpl.rcParams['font.size'] = 18# Edit axes parameters
mpl.rcParams['axes.linewidth'] = 2# Tick properties
mpl.rcParams['xtick.major.size'] = 10
mpl.rcParams['xtick.major.width'] = 2
mpl.rcParams['xtick.direction'] = 'out'
mpl.rcParams['ytick.major.size'] = 10
mpl.rcParams['ytick.major.width'] = 2
mpl.rcParams['ytick.direction'] = 'out'

热图

对于热图可视化,我们将使用imshow函数将我们的数据显示为图像。首先,我们创建一个图形并添加一个主轴来显示我们的图像。此外,我们将删除刻度线,因为我们将添加一个比例尺。

# Create figure and add axis
fig = plt.figure(figsize=(4,4))
ax = fig.add_subplot(111)# Remove x and y ticks
ax.xaxis.set_tick_params(size=0)
ax.yaxis.set_tick_params(size=0)
ax.set_xticks([])
ax.set_yticks([])

现在我们用下面的命令显示我们的图像:

# Show AFM image
img = ax.imshow(afm_data, origin='lower', cmap='YlGnBu_r', extent=(0, 2, 0, 2), vmin=0, vmax=200)

origin —图像通常显示为其原点在左上角,因此通过使用origin='lower'我们强制原点在左下角

我们图像的色彩映射表。所有可用的matplotlib色彩映射表都可以在中找到,在任何色彩映射表名称中添加_r都会将其反转。

extent——imshow将使用像素绘制我们的图像,除非我们告诉它这些像素对应的范围。在这种情况下,我们知道我们的图像是 2 m x 2 m,所以我们让我们的extent=(x_min, x_max, y_min, y_max)等于(0, 2, 0, 2)

vmin —设置为颜色图最小值的值

vmax —设置为色彩映射表最大值的值

我们的 AFM 显微照片的图像绘图

现在,我们应该添加我们的比例尺,这样任何查看该图的人都会对大小比例有一个概念。我们将使用plt.fill_between创建一个填充的矩形,然后在顶部添加一个文本标签。

# Create scale bar
ax.fill_between(x=[1.4, 1.9], y1=[0.1, 0.1], y2=[0.2, 0.2], color='white')

x —我们的填充形状的 x 范围(因为我们的图像从[0,2]到指定的范围[1.4,1.9]是 0.5 米或 500 纳米)

y1 —我们填充形状的底部 y 值(对应于x的值)

y2 —我们填充形状的顶部 y 值(对应于x的值)

ax.text(x=1.65, y=0.25, s='500 nm', va='bottom', ha='center', color='white', size=20)

x —文本的 x 轴位置

y —文本的 y 轴位置

s —文本字符串

va —垂直对齐(bottom表示y对应文本底部)

ha —水*对齐(center表示x对应文本中心)

添加比例尺的 AFM 显微照片

最后,我们可以添加一个颜色条来显示图像中的颜色与高度值的对应关系。首先,我们为 colorbar 创建一个新的 axis 对象,这是通过使用make_axes_locatable().append_axes函数在原始轴的右侧追加一个新轴来实现的。我们将原始轴对象ax传递给函数:

# Create axis for colorbar
cbar_ax = make_axes_locatable(ax).append_axes(position='right', size='5%', pad=0.1)

position —添加下一个轴的位置,在本例中为原始图像的右侧

size —新轴沿position方向的尺寸,相对于原始轴(图像宽度的 5%)

pad —两轴之间的填充(在绝对坐标中)

现在,我们把这个新的轴对象变成一个颜色条:

# Create colorbar
cbar = fig.colorbar(mappable=img, cax=cbar_ax)

mappable —映射到颜色条的图像/绘图(我们在前面使用imshow时创建了img

cax —用于颜色条的轴

最后,我们调整色条的刻度线和标签:

# Edit colorbar ticks and labels
cbar.set_ticks([0, 50, 100, 150, 200])
cbar.set_ticklabels(['0', '50', '100', '150', '200 nm'])

带有比例尺和颜色条的 AFM 显微照片

等高线图

就像在大多数徒步旅行路线中发现的地形图一样,我们也可以用恒定强度的等高线来呈现三维数据。我们现在将使用等高线图绘制相同的 AFM 数据。

我们使用与之前相同的代码,更改了以下代码行(我添加了zorder=1以确保等值线图位于比例尺下方,因为首先绘制的是较低的 z 顺序数字):

# Show AFM contour plot
ax.contour(afm_data, extent=(0, 2, 0, 2), cmap='YlGnBu_r', vmin=0, vmax=200, zorder=1)

AFM 显微图像轮廓图,带比例尺和颜色条

如果我们使用contourf而不是contour,我们可以创建填充轮廓,而不仅仅是轮廓线:

# Show AFM filled contour plot
ax.contourf(afm_data, extent=(0, 2, 0, 2), cmap='YlGnBu_r', vmin=0, vmax=200)

AFM 显微照片填充的轮廓图,带有比例尺和颜色条

在这种情况下,来自imshow的许多更精细的细节在contourcontourf中没有被很好地捕捉到。如果您的数据相当*滑,没有很多较小的细节,等值线图像可能比热图更好看。最终,您希望以尽可能透明和直观的方式呈现数据,因此在这种情况下,带有颜色条的热图可能是最好的。

3D 绘图

到目前为止,我们已经将我们的图限制为二维,并使用色标让读者推断强度。如果我们想更好地理解这些强度值,我们实际上可以用 3D 来绘制数据。

我们首先用下面的代码创建一个 3D 轴,这里的关键是我们在生成轴对象时使用了projection=’3d':

# Create figure and add axis
fig = plt.figure(figsize=(8,6))
ax = plt.subplot(111, projection='3d')

空 3D 轴对象

灰色窗格和轴网格给我们的绘图增加了混乱,所以让我们删除它们。此外,我将再次为高度添加颜色条,因为透视视图的原因,z 轴将被压缩,所以我将删除它。

# Remove gray panes and axis grid
ax.xaxis.pane.fill = False
ax.xaxis.pane.set_edgecolor('white')
ax.yaxis.pane.fill = False
ax.yaxis.pane.set_edgecolor('white')
ax.zaxis.pane.fill = False
ax.zaxis.pane.set_edgecolor('white')
ax.grid(False)# Remove z-axis
ax.w_zaxis.line.set_lw(0.)
ax.set_zticks([])

没有背景窗格和 z 轴的空三维轴

对于表面图,我们需要 x 和 y 值的 2D 数组来对应强度值。我们通过用np.meshgrid创建一个 mesh-grid 来做到这一点——我们对这个函数的输入是一个要在网格中重复的 x 值和 y 值的数组,我们将使用np.linspace来生成这个数组。

# Create meshgrid
X, Y = np.meshgrid(np.linspace(0, 2, len(afm_data)), np.linspace(0, 2, len(afm_data)))

现在我们有了网格,我们可以绘制三维数据:

# Plot surface
plot = ax.plot_surface(X=X, Y=Y, Z=afm_data, cmap='YlGnBu_r', vmin=0, vmax=200)

X—x 值网格

Y—y 值的网格

Z-z 值的网格

AFM 显微照片的 3D 绘图

现在,我们可以调整绘图视图——我们为此控制三个参数:仰角、方位角(在 x-y *面中)和离轴的距离,它们分别大致对应于球坐标系值 φθ、r 。我将方位角设置为 225,因为我们希望 x 轴和 y 轴在(0,0)处相交。

# Adjust plot view
ax.view_init(elev=50, azim=225)
ax.dist=11

添加颜色栏:

# Add colorbar
cbar = fig.colorbar(plot, ax=ax, shrink=0.6)
cbar.set_ticks([0, 50, 100, 150, 200])
cbar.set_ticklabels(['0', '50', '100', '150', '200 nm'])

shrink —相对于其默认大小将颜色条缩小多少

最后,我们编辑一些美感——x 和 y 轴上的刻度线、轴限制和轴标签。

# Set tick marks
ax.xaxis.set_major_locator(mpl.ticker.MultipleLocator(0.5))
ax.yaxis.set_major_locator(mpl.ticker.MultipleLocator(0.5))# Set axis labels
ax.set_xlabel(r'$\mathregular{\mu}$m', labelpad=20)
ax.set_ylabel(r'$\mathregular{\mu}$m', labelpad=20)# Set z-limit
ax.set_zlim(50, 200)

带彩条的 AFM 显微图的 3D 绘图

这个图让读者除了用颜色表示强度值之外,还能看到高度的波动。然而,噪声更大的数据集可能会导致非常混乱的 3D 绘图。

结论

我希望本教程有助于解决绘制三维数据集的不同方法。在这个 Github 资源库中可以找到例子。感谢阅读!

可视化时间序列生存数据

原文:https://towardsdatascience.com/visualizing-time-series-survival-data-36029652a393?source=collection_archive---------26-----------------------

Geran de Klerk 在 Unsplash 上拍摄的照片

卡普兰-迈耶曲线

让我们想象一下,你有关于你的研究对象“存活”了多久的数据。生存可以是字面意义上的(如在临床试验中)或比喻意义上的(如果你正在研究客户保持,当人们停止阅读一篇文章,或当一台机器坏了)。为了可视化数据,我们想要绘制一条生存曲线,叫做卡普兰-迈耶曲线,如下图所示。

具有 95%置信区间的药物耐受性和使用的存活曲线(人工生成的数据,n ≈ 300)

左边的曲线(使用人工生成的数据创建)旨在显示开始服药几天后仍在服药的人的百分比。在这种情况下,他们会停下来,因为药物不再控制疾病,或者因为它引起了太多的副作用。

理想情况下,通过简单地考虑在开始服药后的给定天数内服药的人的百分比,很容易计算出这条曲线。

然而,一些人(本例中约 25%)仍在服药。他们可能只是服用了很长一段时间(在这种情况下接* 10 年)而没有问题,或者他们可能只是刚刚开始服用。这种观察被称为“右删截”,因为我们不能及时观察到它们(向右)。

对此最简单的解决方案是卡普兰-迈耶曲线,也称为乘积极限估计量。还有其他解决方案,但它们需要对数据做出假设,并为数据提供一个模型。另一方面,我们通常的第一步是只看数据,卡普兰-迈耶曲线允许我们在不做假设的情况下这样做。

在本文中,我们将讨论如何计算卡普兰-迈耶曲线,最重要的是,显示的置信区间。更重要的是,我们将探讨计算置信区间(有时称为“对数”和“对数-对数”/指数格林伍德置信区间)的两种方法之间的差异。

卡普兰·迈耶的估计

如果你还没猜到,这种生存曲线起源于医学和精算界,字面上的关注是某人是否真的会死亡。因此,我们将采用这样的术语:研究中给定的受试者(比如说一个人)可能仍然活着,在这种情况下,观察是经过审查的(我们没有观察到一个事件),或者他们可能已经在特定的时间点死亡(我们观察到了该事件)。

请注意,当我们说“时间”时,我们不是指字面上的日期,而是相对于参与者进入研究的时间。在人寿保险的例子中,那只是他们出生的时间。在上面的医学例子中,它是当某人开始服用药物时。

上世纪 50 年代的卡普兰-迈耶估计,用文字表述比用公式表述更容易。规则是:

  1. 一开始,100%的人都是活着的。
  2. 在每个时间点(以 i 为索引),计算存活的人的百分比,作为已知活了那么久的人的百分比。
  3. 为了创建曲线,假设在时间 i 幸存者的百分比是该时间和每个先前时间的生存机会百分比的乘积。

例如,假设我们有三个人的记录。一个活到了 92 岁,一个死于 90 岁,一个死于 95 岁。90 岁时,66.7%的人口存活下来。92 岁时,100%存活。在 95 岁时,100%的人(不是 50 岁)会死亡。这是因为 92 岁的人没有计入 95 岁的人口中。

注意,某人被审查的次数(在我们的例子中是 92 次)不会影响曲线。事实上,只有我们观察到某人死亡的次数才算数。

现在让我们用方程式来做。

  • i 索引某事发生的时间(即某人死亡)。
  • d 为在时间 i. 停止的人数
  • 设 n 是在时间 i. 时人口中(已知幸存)的人数

生存函数的卡普兰-迈耶估计量为

生存函数的 Kaplan-Meier 估计

换句话说,生存百分比与当前时间 t 之前所有时间的产品的乘积。

卡普兰-迈耶估计量是生存函数的最大似然估计量,这使得它成为快速可视化的自然选择。

一般来说,你可以发现这是大多数处理时间序列数据的统计软件包。对于 python 来说,[statsmodels](https://www.statsmodels.org/stable/generated/statsmodels.duration.survfunc.SurvfuncRight.html#statsmodels.duration.survfunc.SurvfuncRight)[lifelines](https://lifelines.readthedocs.io/en/latest/)是一些不错的选择。[survival](https://cran.r-project.org/web/packages/survival/index.html)作 R。

格林伍德置信区间

棘手的部分在于计算置信区间。首先,我们假设在时间 i. 有一个真实的“风险率”,换句话说,我们假设 d 遵循一个二项式分布,概率 h 和样本量 n、在时间 i. 各不相同,这意味着它有均值和方差 nhnh(1-h)

d 的均值和方差

下一个技巧是,由于 S 的估计量是一个乘积,所以处理 S 的对数会更容易,因为它是一个和。

现在我们需要转移话题,谈谈泰勒级数*似,它将使我们能够进行一系列的计算。

德尔塔法

Delta 方法是处理随机变量(如对数)转换的一种方便而严格的方法。假设我们有一个随机变量 X 和一个函数 f (你应该认为它是对数)。如果我们假设 X 只是一个正则数(不是随机的),那么我们可以写下关于一个点 c 的一阶泰勒展开式:

f 的一阶泰勒展开

delta 方法的本质洞见是,假设 X 是一个像样本均值或我们对 s 的估计一样的统计量,如果 c 是 X 的期望值,E[X],那么在大样本量的极限下,X 将接* c 并呈正态分布(由中心极限定理),逼*将非常好。这让我们可以计算 f 的期望值:

delta——期望值的方法*似值

更好的是,我们可以应用大一微积分的中值定理。假设我们已经测量了 X 的值,我们可以找到位于 c 和 X 之间的值 d,因此

泰勒展开的中值定理

同样,在大样本量的限制下,X 更接* c,因此 d 被挤压在它们之间,也更接* c。因此,在大样本量的限制下非正式地工作,我们可以将上面的*似等式视为等式。

现在假设我们知道 X 的方差取决于样本大小 n :

根据中心极限定理,x 关于其期望值是正态分布的

回到我们最初的泰勒展开,重新排列各项并乘以 n 的*方根:

f(X)的泰勒展开的重排

这意味着我们已经计算出 f(X)的方差是 x 乘以 fʹ(c *方的方差。

运用德尔塔法

请回忆一下,在我们离题进入德尔塔法之前,我们说过

让我们考虑使用 Delta 方法计算总和中每一项的方差。期望值是 1–h,所讨论的函数是导数为 1/x 的对数 log(x)(当然,我们只使用自然对数)。因此:

我们还可以计算每一项的方差。log(1-h)项没有方差(是常数),第二项减去 h 也不影响方差。

各项的方差

现在,一个简单的技术问题。通常,我们可以把方差加起来,来计算总和的方差。然而,从技术上讲,这两项并不独立,因为时间 I 的死亡会影响后面时间的分母 n。另一方面,感兴趣的项(d/n–h)具有均值 0,条件是知道所有以前的死亡,这使得这些项成为一个差(或者它们的和是一个鞅)。反过来,鞅中心极限定理告诉我们,方差实际上只是个体方差之和。

最后,我们得到了 S 的对数的方差

最后,我们可以再次应用德尔塔法

最后

我们可以反过来估计为:

这又让我们通过假设 S 的估计量是正态分布(如果样本量足够大,就会是这种情况)来计算格林伍德置信区间。

唷。

指数格林伍德置信区间

现在,使用上面的格林伍德置信区间会导致一个问题,即您的置信区间可能会落在 0-1 边界之外。如果有一个图表,在这个图表上,你的置信区间允许有时候存活率是负的,这将是非常尴尬的。

这里的解决方案是注意我们使用了 log,因为它强制 S 为正。如果我们计算变换后的对数 S 的置信区间,我们至少可以保证得到的置信区间将大于 0(但也可以大于 1)。我们为此付出的“代价”是拥有一个不对称的置信区间。但是,如果我们要这样做,我们不妨一路走下去。如果我们用

那么我们将得到保证位于 0–1 区间内的置信区间,因为 log(–log(X))只接受 0–1 范围内的参数;逆变换将确保我们在该范围内结束。

我不会给你数学;经过变换的 S 的最终方差为

计算变换后的 s 的置信区间,然后用 x ⟼指数(-exp(x))撤消变换,以获得 s 的非对称置信区间

我的目标是写(相对)易懂的数据科学概念的解释,而不回避有时涉及的复杂数学。如果你喜欢这个,你我还有类似风格的解释**困惑中心极限定理 ,或者 期望最大化 **

如果你不喜欢这个,多考虑一下 回归 ,奇异值分解,或者* 傅立叶变换 ***

笔记

[1]很明显,如果 fʹ(c)为 0,事情会变得非常糟糕,所以这是一个很好的时机来说明这是一个额外的假设。查阅维基百科的文章,获得完全严格的处理方法。

基于广播交通新闻的交通状况可视化

原文:https://towardsdatascience.com/visualizing-traffic-conditions-based-on-radio-traffic-news-67e63eee58b3?source=collection_archive---------30-----------------------

美声网刮

Unsplash 上的 Max Titov 拍摄的照片

背景

这个项目发生在 2019 年 10 月,当时我的老板要求我们的团队在网络运营中心(NOC)的大屏幕上可视化我们的网络质量。作为移动运营商,我们经常全天候监控我们的网络质量和状况。开发了许多重要网络 KPI 的仪表板,我的老板希望我们增强所获得的信息,让 NOC 员工“知道/猜测”正在发生的事情。

我们的网络流量可能会受到许多外部因素的影响,我们可以想到的一般信息之一是流量状况,我指的是道路上的实际流量。当出现拥堵、交通堵塞或其他特殊路况时,该特定蜂窝基站的 KPI 可能会爆仓。因此,我们希望在地图上可视化交通状况,让我们的工作人员知道哪个位置有情况。

使用 BeautifulSoup 进行网页抓取

Radio news provides a very good source of detail traffic conditions as they are very useful for the Taxi drivers to choose their route (especially before the birth of Google Map). Besides the radio broadcast, all this information is online. The one we are choosing is the official radio station of Hong Kong RTHK: http://programme.rthk.hk/channel/radio/trafficnews/index.php (Sorry, only Chinese version available). If you know Chinese, you may figure out that the news is well-formatted. If the news is about traffic congestion, the format is the name of the road, the direction, and the queue end position (龍尾:)

HTML 结构也非常好。我们可以看到所有单独的新闻都有一个无序列表

新闻网站的 HTML 结构

有了请求和 BeautifulSoup,我们很容易获得并解析网页。感谢标准格式,我们可以在一秒钟内看到所有的故事。

import requestsfrom bs4
import BeautifulSoup
r = requests.get("http://programme.rthk.hk/channel/radio/trafficnews/index.php")
if r.status_code == requests.codes.ok:
    r.encoding='utf-8'
    soup = BeautifulSoup(r.text, 'html.parser')
    stories = soup.find_all('li', class_='inner')

我们将每条新闻分为标题(新闻内容)和发布时间。我们用“%Y-%m-%d HKT %H:%M”来格式化发布时间。

titles = []
times = []
for s in stories:
    title, time = list(filter(None, re.split(r'**\t**|**\n'**, s.text)))
    titles.append(title)
    times.append(time)

The most difficult part is to extract the location. Here we search for the particular phrase (龍尾:), which means the queue end in Chinese. If this phrase does not include in the news, we search for our location database. We will discuss how we obtain this database later. And now we have this DataFrame with title, publish time and location.

交通新闻的数据框架

接下来,我们需要对新闻进行分类。经过长时间的观察,我们发现新闻的类型属于这几类:

交通新闻类别

服务暂停:部分公共交通服务停止,
受阻:部分道路因各种原因受阻:附*道路维修或特殊事件,
繁忙:道路繁忙但仍可行驶;
拥堵:道路严重拥堵;
事故:那条路上发生了交通事故;
正常:被封锁或拥堵的道路恢复通行;
Info: 只是一些大概的信息。

而且那些措辞曾经重复出现过很多次。因此,我们可以通过识别词语来明确地划分不同的类别。

# set category
df.loc[df.title.str.contains('關閉'), 'category'] = 'service paused'
df.loc[df.title.str.contains('暫停'), 'category'] = 'service paused'
df.loc[df.title.str.contains('間封'), 'category'] = 'blocked'
df.loc[df.title.str.contains('繁忙'), 'category'] = 'busy'
df.loc[df.title.str.contains('多車'), 'category'] = 'busy'
df.loc[df.title.str.contains('車多'), 'category'] = 'busy'
df.loc[df.title.str.contains('慢車'), 'category'] = 'busy'
df.loc[df.title.str.contains('龍尾'), 'category'] = 'busy'
df.loc[df.title.str.contains('塞車'), 'category'] = 'congestion'
df.loc[df.title.str.contains('擠塞'), 'category'] = 'congestion'
df.loc[df.title.str.contains('意外'), 'category'] = 'accident'
df.loc[df.title.str.contains('回復暢順'), 'category'] = 'normal'
df.loc[df.title.str.contains('回復正常'), 'category'] = 'normal'
df.loc[df.title.str.contains('恢復運作'), 'category'] = 'normal'
df.loc[df.title.str.contains('禁止'), 'category'] = 'blocked'
df.loc[df.title.str.contains('受阻'), 'category'] = 'blocked'
df.loc[df.title.str.contains('不能通車'), 'category'] = 'blocked'
df.loc[df.title.str.contains('封閉'), 'category'] = 'blocked'
df.loc[df.title.str.contains('封路'), 'category'] = 'blocked'
df.loc[df.title.str.contains('恢復'), 'category'] = 'normal'
df.loc[df.title.str.contains('回復'), 'category'] = 'normal'
df.loc[df.title.str.contains('重開'), 'category'] = 'normal'
df.loc[df.title.str.contains('間封措施取消'), 'category'] = 'normal'
df.loc[df.category.isnull(), 'category'] = 'info'

为了定位交通新闻场景,我们需要纬度和经度。幸运的是,我们找到了一个 API GeoPy。你可能会找到一个关于如何使用它的很好的书面教程,从 Geocode with Python,到数据科学。这将物理地址转换为地理位置(即纬度和经度)。乍一看,我们怀疑这个 python 库是否支持中文地址。但事实证明它有着相当不错的性能。我们使用的是基于 OpenStreetMap 数据构建的 nomist 地理编码服务。

locator = Nominatim(user_agent=’myGeocoder’, timeout=3)
try:
    location = locator.geocode(record)
except GeocoderTimedOut as e:
    print(“Error: geocode failed on input {} with message {}”.format(record, e))

过了一段时间,我们收集了一堆新闻,可以选择经常出现的道路手动查询其经纬度(相信我,交通拥堵每天都在同一条道路上重复重复!)

这是我们 NOC 中使用的仪表板。也请访问 Tableau 创建的演示站点

交通状况仪表板

使用 Tableau 的可视化

结论

感谢互联网上的丰富资源和那些已经建立了重要有用模块的巨人,我们可以在他们的基础上建立一个交通新闻可视化仪表板。

要了解这个项目的更多信息,请点击这里查看我的 Github 链接

使用 ggplot2 可视化 R 中多元数据的趋势

原文:https://towardsdatascience.com/visualizing-trends-of-multivariate-data-in-r-using-ggplot2-1b85409afcfb?source=collection_archive---------23-----------------------

字云生成

数据可视化是通过图形元素表示数据的艺术,是任何研究或数据分析项目的重要组成部分。可视化在探索性数据分析和展示研究结果中是必不可少的。良好的可视化有助于讲述您的数据故事,并传达您的分析的重要信息,因为它允许我们快速查看趋势和模式,找到异常值,并获得洞察力。

通常,要么不容易找到最能描述数据的可视化类型,要么不容易找到生成感兴趣的图的简单工具。例如,可视化具有多个因变量和自变量(以及它们之间的相互作用)的高维数据集中的趋势可能是乏味的。

在这篇文章中,我决定介绍一种我认为非常有效的 3D 数据可视化技术。如果你是第一次接触 R 或者你从未在 R 中使用过 ggplot2 库,这会很有帮助。ggplot2 有几个内置的函数和功能,带来了显示复杂数据所需的灵活性。

此外,在这个博客中,将会有一些例子来说明如何使用函数设置来创建发布就绪的图形,并以高分辨率保存它们。你也可以在我的 Github 页面的一个地方找到所有代码。

概要:

第一部分:数据解释和准备

第二部分:使用 facet_grid() 函数可视化 3D 数据

第三部分:用其他 ggplot2 内置函数可视化 3D 数据

第 4 部分:可视化多因变量数据

第一部分:数据解释和准备

这里,我将使用来自真实世界问题的内部数据集,我们希望根据图像采集时设置的三个关键参数来表征一组对象图像中的噪声。我们不会深入讨论这些参数的细节,为了简单起见,我们将其命名为 Var1、Var2、Var3。图像中的噪声由标准偏差计算得出,命名为 SD。

Var1: Categorical at four levels of 100, 50, 25, 10Var2: Categorical at three levels of k1, k2, k3Var3: Categorical at three levels of st0.6, st1.0, st2.0SD: Continuous in the range of (0, 500)

这些参数有 4x3x3 = 36 种组合。所有这些参数的组合存在于数据集中,这意味着对于每个对象,存在 36 幅图像。每个图像都是参数集的不同组合(见下表)。

# set csv_file name
# set working directory
# set output_path# import libraries
library(ggplot2)
library(stringr)
library(ggpubr)

读取数据并准备数据列。准备工作的一个例子是数据转换:这里 Var1 是一个四层分类变量。在读取数据后,我们必须首先将该列转换为具有四个级别的数字列,然后对其进行排序,以便它在我们的图中按顺序出现。

# Read data
data = read.csv(csv_file,header = TRUE)
#prepare data
data$Var1 <- as.numeric(data$Var1,levels =data$Var1)
data$Var1 <- ordered(data$Var1)
data$Parameter_Set <- factor(data$Parameter_Set)

几行数据。每个对象(由唯一 ID 确定)有 36 个参数集的 36 幅图像

出于可视化的目的,我们将取每个参数集中图像的噪声*均值:

mean_SD = c()
mean_intensity = c()
Var1 = c()
Var2 = c()
Var3 = c()
for (ParamSet in levels(data$Parameter_Set)){
 data_subset = data[which(data$Parameter_Set==ParamSet),]
 mean_SD = c(mean_SD, mean(data_subset$SD))
 mean_intensity = c(mean_intensity, mean(data_subset$intensity))
 Var1 = c(Var1,str_split(ParamSet, “_”)[[1]][1])
 Var2 = c(Var2,str_split(ParamSet, “_”)[[1]][2])
 Var3 = c(Var3,str_split(ParamSet, “_”)[[1]][3])
}
Mean_DF = data.frame(Parameter_Set = levels(data$Parameter_Set),Var1 = Var1, Var2 = Var2, Var3 = Var3 ,mean_SD = mean_SD, mean_intensity = mean_intensity)

来自 Mean_DF 的几个样本行。注意:该数据框有 36 行,用于 36 个参数集

####### Prepare the Mean_DF dataframe
data = Mean_DF
data$Var3 <- factor(data$Var3)
data$Var1 <- as.numeric(data$Var1,levels =data$Var1)
data$Var1 <- ordered(data$Var1)
data$Parameter_Set <- factor(data$Parameter_Set)

第 2 部分:使用 facet_grid()函数可视化 3D 数据

让我们看看剧情

最后,我们将跨 3 个参数可视化图像中*均噪声的 3D 数据!ggplot 2 库中的 facet_grid() 函数是关键函数,它允许我们跨越多个自变量的所有可能组合来绘制因变量。ggplot2 可灵活添加各种功能,通过“+”改变绘图格式。下面我们添加 facet_grid()geom_point()labs()ylim()

ggplot(data, aes(y = mean_SD, x = Var1))+ geom_point(size = 3)+facet_grid(Var3 ~ Var2, scales = "free_x",space = "free")+labs(title =" SD across all parameter sets",x = "Var1 ", y= "Mean SD")+ ylim(0, 500)

看起来在这个情节中发生了很多事情,所以让我们回顾一下:我们有一个有九个街区的情节。每个模块都是 Var2 和 Var3 特定级别的一个参数集。(九块:三级 Var2 和三级 Var3 的组合)。Var3 显示在行上,Var2 显示在列上。在每个块中,横轴是 Var1,纵轴是因变量 mean_SD,范围为 0–500(由 ylim()确定)。

在这里使用 facet_grid()函数的好处是,随着我们的数据变得越来越复杂,变量越来越多,在自变量的不同组合下解开数据并可视化因变量的趋势将变得非常直观。例如,在这里,通过比较右上方的块(k3,st0.6)和左下方的块(k1,st2.0),我们可以看到明显的差异。在(k1,st2.0)处,当 Var1 从 10 变到 100 时,mean_SD 是恒定的,但是在(k3,st0.6)处,当 Var1 变化时,mean_SD 显示出显著的变化。正如你所看到的,这张图可以显示自变量之间的相互作用以及它们各自对因变量的影响。

如果我们只想根据两个参数(Var1 和 Var3)绘图,facet_grid 的输入将更改如下:

…+facet_grid(Var3 ~ . , scales = “free_x”,space = “free”)+ …

在 facet_grid()中,如果将 space 和 scale 参数设置为“自由”而不是默认值“固定”,则很有帮助,这样变量的比例和面板的大小可以根据行和列中每个变量的比例自由变化。

如果你计划发表你的结果或在会议上发表,你必须注意你的绘图格式字体/字体大小/颜色,点和线的颜色/大小等。这里有一些关于如何使上面的情节看起来更好的帮助。我们简单地添加了 theme() 函数来处理 axis 和块元素的一些细节。

ggplot(data, aes(y = mean_SD, x = Var1))+
  geom_point(size = 4)+facet_grid(Var3 ~ Var2, scales = "free_x",space = "free")+labs(title =" SD across all parameter sets",x = "Var1 ", y= "Mean SD")+ ylim(0, 500)+
theme(axis.text=element_text(size=16,face= "bold"),  axis.text.x = element_text(colour = "blue3"),
axis.title.y=element_text(size=18,face="bold", colour = "black"),
axis.title.x=element_text(size=18,face="bold", colour = "blue3"),
strip.text = element_text(size=18, colour = "blue3",face="bold"))

如果您想以高分辨率保存 R 图,可以使用下面这段代码。

myplot <- ggplot2(data, aes(y = mean_SD, x = Var1))+ ...tiff(mytitle, units=”in”, width=8, height=5, res=300)
myplot
dev.off()

第 3 部分:使用其他 ggplot2 内置函数可视化 3D 数据

假设我们不想使用 facet_grid():

绘制高维数据的另一种方式是简单地为 Var2 和 Var3 的每个不同级别分配不同的颜色和线型。在下面的代码中,我们为不同级别的 Var2 分配不同的颜色,为不同级别的 Var3 分配不同的线型。

在这里,我们将创建三个具有 3 个不同 Var2 值的数据帧。我们将为每个数据帧生成一个图,并将使用 ggarrange() 将这些图合并成一个图。

在下面的图中,我们有意使用了背景颜色和网格线(panel.background 和 panel.grid 作为 theme() 函数中的选项)。

将上面的图与有九个块的图(通过 facet_grid())进行比较,我们可以看到它们各有利弊;一个将数据合并到一个图表中,而另一个展示了允许单独和分别检查数据的 3D 数据面板。我本人更喜欢参数集面板的版本。

下面是上图中的代码:

#separate data frames based on Var2
data_k1 = data[which(data$Var2 == “k1”),]
data_k2 = data[which(data$Var2 == “k2”),]
data_k3 = data[which(data$Var2 ==”k3"),]

第 4 部分:用多个因变量可视化数据

假设我们希望不仅通过图像中的噪声,而且通过图像的亮度值范围来可视化数据的趋势。所以我们现在有了第二个因变量,叫做强度。在第一部分中,与“mean_SD”类似,我们计算了所有参数集的强度*均值(“mean_intensity”)。

首先,让我们看一下“mean_SD”和 Var1 之间的简单图表,其中我们通过颜色渐变显示了“mean_intensity”值的范围(参见图例)

上图的代码:

ggplot(data, aes(x = Var1, y = mean_SD , group = interaction(Var3, Var2)))+ geom_point(size = 3, aes(color = mean_intensity))+ 
 geom_line(lwd = 1.5, aes(color = mean_intensity))+    scale_colour_gradient(low = “yellow”, high = “red3”)+
 labs( x = “Var1 “, y = “Mean_SD”)+
 theme(strip.text = element_text(size = 20,face=”bold”, colour = “red3”),axis.text=element_text(size=20, face=”bold”),
 axis.title=element_text(size=20,face=”bold”, colour = “red3”),
 legend.text = element_text(size = 10,face=”bold” ), 
 panel.grid = element_line(colour= “white”),
 panel.background = element_rect(fill = “gray64”),
 legend.background = element_rect(fill = “gray64”))

现在,我们可以使用这个想法再次生成一个用块来可视化高维数据的图,并演示三个自变量对两个因变量的影响!

ggplot(data, aes(y = mean_SD, x = Var1))+
 geom_point(size = 4,aes(color = mean_intensity))+facet_grid(Var3 ~ Var2, scales = “free_x”,space = “free”)+ scale_colour_gradient(low = “yellow”, high = “red3”)+
 labs(title =” SD across all parameter sets”,x = “Var1 “, y= “Mean SD”)+ ylim(0, 500)+
 theme(axis.text=element_text(size=16,face= “bold”), axis.text.x = element_text(colour = “blue3”),
 axis.title.y=element_text(size=18,face=”bold”, colour = “black”),
 axis.title.x=element_text(size=18,face=”bold”, colour = “blue3”),
 strip.text = element_text(size=18, colour = “blue3”,face=”bold”),
 panel.grid = element_line(colour= “grey”),
 panel.background = element_rect(fill = “gray64”))

清晰的可视化有助于从数据中获得洞察力。在高维数据中,理解模式和交互尤其困难。 R 及其库如 ggplot 2 为研究人员、数据爱好者和工程师处理数据和执行知识发现提供了一个有用的框架。

Rggplot2 有更多创建有洞察力的可视化的能力,所以我邀请你探索这些工具。我希望这个简短的教程有助于熟悉一个对数据分析有用的强大绘图工具。

纳斯塔兰·埃玛尼贾德

在 Twitter 上关注我:@ N _ Emaminejad和 LinkedIn:Nastaran _ Emaminejad

基于主成分分析和 t-SNE 的可视化单词嵌入

原文:https://towardsdatascience.com/visualizing-word-embedding-with-pca-and-t-sne-961a692509f5?source=collection_archive---------3-----------------------

实践教程

在 2D 或 3D 中创建单词嵌入的交互式可视化

弗朗西斯科·温加罗Unsplash 上拍摄的照片

当你听到‘茶’‘咖啡’这两个词,你会怎么想?大概你会说它们都是饮料,都含有一定量的咖啡因。关键是,我们可以很容易地识别出这两个词是相互关联的。然而,当我们向计算机提供单词‘茶’‘咖啡’时,它无法像我们一样识别这两个单词之间的关联。

Word 不是计算机会自然理解的东西。为了让计算机理解单词背后的含义,需要将单词编码成数字形式。这就是单词嵌入背后的技术有用的地方。

单词嵌入是自然语言处理中常用的一种技术,用于将单词转换成向量形式的数值。这些向量将占据一定维数的嵌入空间。

如果两个单词具有相似的上下文,如‘茶’‘咖啡’那样,那么这两个单词在嵌入空间中的距离将会彼此接*,而与具有不同上下文的其他单词的距离将会更远。

在这篇文章中,我将一步一步地向你展示如何可视化单词嵌入。由于本文的重点不是详细解释单词 embedding 背后的基本理论,您可以在本文和中阅读更多关于理论的内容。

为了可视化单词嵌入,我们将使用常见的降维技术,如 PCA 和 t-SNE。为了将单词映射到它们在嵌入空间中的向量表示,将实现预先训练的单词嵌入手套。

加载预先训练的单词嵌入模型

在可视化单词嵌入之前,通常我们需要首先训练模型。然而,训练单词嵌入在计算上是非常昂贵的。因此,通常使用预先训练的单词嵌入模型来代替。它包含嵌入空间中的记号及其相关向量表示。

除了 Google 开发的 word2vec 之外,GloVe 是一个由斯坦福研究人员开发的流行的预训练单词嵌入模型。本文实现了 GloVe 预训练单词嵌入,你可以在这里下载。同时,我们可以使用 Gensim 库来加载预先训练好的单词嵌入模型。您可以使用 pip 命令安装该库,如下所示。

pip install gensim

作为第一步,我们需要将 GloVe 文件格式转换为 word2vec 文件格式。使用 word2vec 文件格式,我们可以使用 Gensim 库将预先训练好的单词嵌入模型加载到内存中。由于每次调用该命令时,文件加载都会花费一些时间,因此如果我们使用一个单独的 Python 文件来实现这个目的,效果会更好。

创建输入单词并生成相似的单词

现在我们有了一个 Python 文件来加载预训练的模型,接下来我们可以在另一个 Python 文件中调用它,根据输入的单词生成最相似的单词。根据您的喜好,输入的单词可以是任何单词。

在我们键入输入的单词后,下一件事就是创建一个代码来读取它。然后,我们需要根据模型将生成的每个输入单词指定相似单词的数量。最后,我们将相似单词的结果存储在一个列表中。下面是实现这一目的的代码。

例如,假设我们想要找出与“学校”相关的 5 个最相似的单词。因此,‘学校’将是我们的输入单词。使用上面的代码,我们将得到单词、【学校】、、【小学】、、【学生】、、【学生】、作为结果。**

用主成分分析可视化单词嵌入

到目前为止,我们已经有了输入单词和基于它生成的相似单词。接下来,是时候让我们在嵌入空间中可视化它们了。

有了预训练的模型,每个单词现在可以用它的向量表示法映射到嵌入空间。然而,单词嵌入具有非常高的维数,这意味着不可能可视化单词如何占据嵌入空间。

通常实现诸如主成分分析(PCA)的方法来降低单词嵌入的维度。简而言之,PCA 是一种特征提取技术,它结合变量,然后丢弃最不重要的变量,同时仍然保留变量中有价值的部分。如果你想深入研究 PCA,我推荐这篇文章

使用 PCA,我们可以在 2D 或 3D 中可视化单词嵌入。因此,让我们使用我们在上面的代码块中调用的模型创建代码来可视化单词嵌入。在下面的代码中,只显示了 3D 可视化。为了使 2D 的认证后活动形象化,只需稍加改动。您可以在代码的注释部分找到需要更改的部分。

例如,假设我们想要可视化与、【球】、、【学校】、、【食物】、相关联的前 5 个最相似的单词。使用我们到目前为止创建的代码,下面是 2D 的可视化示例。**

基于主成分分析的 2D 词嵌入可视化

下面是同样一组单词的三维可视化。

基于主成分分析的三维单词嵌入可视化

从可视化中,现在我们可以看到这些单词所占空间的模式。与‘ball’相关联的单词被放置得彼此靠*,因为它们具有相似的上下文。同时,它们和与【学校】**【食物】相关的词之间的距离更远,因为它们有不同的上下文。

用 t-SNE 可视化单词嵌入

除了 PCA 之外,另一种常用的降维技术是 t 分布随机邻居嵌入或 t-SNE。主成分分析和 t-SNE 之间的区别是它们都实现了降低维数的基本技术。

PCA 是一种线性降维方法。高维空间中的数据被线性映射到低维空间,同时最大化数据的方差。同时,t-SNE 是一种非线性降维方法。利用 t-SNE,该算法计算高维空间和低维空间的相似度。接下来,使用优化方法,例如梯度下降方法,最小化两个空间中的相似性差异。

使用 t-SNE 可视化单词嵌入的代码与使用 PCA 的代码非常相似。在下面的代码中,只显示了 3D 可视化。为了使 2D 的 SNE 霸王龙形象化,只需要做一些小的改动。您可以在代码的注释部分找到需要更改的部分。

对于与 PCA 可视化中相同的例子,即与‘球’‘学校’‘食物’相关联的前 5 个最相似单词的可视化,下面是在 2D 的可视化结果。

基于 t-SNE 的 2D 单词嵌入可视化

下面是同样一组单词的三维可视化。

基于 t-SNE 的三维单词嵌入可视化

与主成分分析的方法相同,注意如何将具有相似上下文的单词放在彼此靠*的位置,而将具有不同上下文的单词放在较远的位置。

创建一个 Web 应用程序来可视化单词嵌入

到目前为止,我们已经成功地创建了一个 Python 脚本,使用 PCA 或 t-SNE 在 2D 或 3D 中可视化单词嵌入。接下来,我们可以创建一个 Python 脚本来构建一个 web 应用程序,以获得更好的用户体验。

web 应用程序使我们能够通过许多功能和交互性来可视化单词嵌入。例如,用户可以键入他们自己的输入单词,并且他们还可以选择与将被返回的每个输入单词相关联的前 n 个最相似的单词。

可以使用 Dash 或 Streamlit 创建 web 应用程序。在本文中,我将向您展示如何构建一个简单的交互式 web 应用程序,用 Streamlit 可视化单词嵌入。

首先,我们将使用我们之前创建的所有 Python 代码,并将它们放入一个 Python 脚本中。接下来,我们可以开始创建如下几个用户输入参数:

  • 降维技术,用户可以选择是应用 PCA 还是 t-SNE。因为只有两个选项,所以我们可以使用 Streamlit 的selectbox 属性。
  • 可视化的维度,其中用户有一个选项,他们是否希望在 2D 或 3D 中可视化单词嵌入。和以前一样,我们可以使用selectbox 属性。
  • 输入单词。这是一个用户输入参数,要求用户键入他们想要的输入单词,例如‘球’‘学校’‘食物’。因此,我们可以使用text_input 属性。
  • 前 n 个最相似的单词,其中用户需要指定将返回多少个与每个输入单词相关联的相似单词。由于我们可以选择任何数字,那么slider 属性将是最好的选择。

接下来,我们需要考虑在我们决定使用 SNE 霸王龙时会出现的参数。在 t-SNE 中,我们可以调整一些参数来获得最佳的可视化结果。这些参数是困惑度、学习率和优化迭代次数。在每种情况下,这些参数都没有单一的最佳值,因此最好的解决方案是让用户指定这些值。

由于我们使用的是 Scikit-learn,我们可以参考文档来找出这些参数的默认值。困惑的默认值是 30,但是我们可以在 5 到 50 之间调整这个值。学习率的默认值是 300,但是我们可以在 10 到 1000 之间调整这个值。最后,迭代次数的默认值是 1000,但是我们可以将这个值调整为 250。我们可以使用slider 属性来创建这些参数值。

现在我们已经涵盖了构建 web 应用程序的所有必要部分。最后,我们可以将所有的东西打包成一个完整的脚本,如下所示。

您现在可以使用 Conda 提示符运行 web 应用程序。在提示符下,转到 Python 脚本的目录,然后输入以下命令:

$ streamlit run your_script_name.py

接下来,会自动弹出一个浏览器窗口,您可以在这里本地访问您的 web 应用程序。下面是您可以使用 web 应用程序做些什么的快照。

就是这样!您已经创建了一个简单的 web 应用程序,它具有很多交互性,可以用 PCA 或 t-SNE 可视化单词嵌入。

如果你想看这个单词嵌入可视化的完整代码,可以在我的 GitHub 页面这里访问。

用交互式地图可视化世界幸福

原文:https://towardsdatascience.com/visualizing-world-happiness-with-an-interactive-map-e33ebbaa3936?source=collection_archive---------44-----------------------

哪些国家最幸福?这个问题极难回答。然而,《世界幸福报告》尽力报道这个话题,对 156 个国家的公民认为自己有多幸福进行了排名。分析《世界幸福报告》数据的一个有趣的方法是观察各国的幸福分数与地图上与它们相*的国家的幸福分数之间的关系。

在本教程结束时,您将拥有一张交互式地理地图,可以用来调查世界各地不同国家的幸福程度——或者,您可以交换数据并可视化一些您自己的有趣地理数据!

安装软件包

以下是完成本教程所需的先决条件,可能有,也可能没有:

  • 地质公园。GeoPandas 是一个软件包,它使得使用 Python 处理地理空间数据变得更加容易。你可以在这里找到安装说明
  • 形状文件。为了绘制世界地图或城市地图,我们需要一个 shapefile,用于存储地理信息。我们在这个例子中使用的 shapefile 可以在我的 Github 上获得,或者你可以在这里找到它
  • 散景。散景有助于快速轻松地制作交互式绘图、仪表盘和数据应用。
  • 世界幸福报告数据。我在 Kaggle 上找到了数据。
# basic modules 
import geopandas as gpd 
import pandas as pd 
import json 
import glob 
import os # visualizaztion modules 
from bokeh.resources import INLINE 
from bokeh.io import output_notebook, show, output_file 
from bokeh.plotting import figure 
from bokeh.models import GeoJSONDataSource, LinearColorMapper, ColorBar 
from bokeh.palettes import brewer,mpl # interactive visualization models 
from bokeh.io import curdoc, output_notebook 
from bokeh.models import Slider, HoverTool 
from bokeh.layouts import widgetbox, row, column

导入和清理数据

shapefile 包含了所有的坐标,这些坐标将有助于以后绘制世界地图。可以重命名这些列,以便它们对分析更有意义。

shapefile = 'ne_110m_admin_0_countries/ne_110m_admin_0_countries.shp'

# Read shapefile using Geopandas
gdf = gpd.read_file(shapefile)[['ADMIN', 'ADM0_A3', 'geometry']]

# Rename columns.
gdf.columns = ['country', 'country_code', 'geometry']

《世界幸福报告》提供的数据来自 2015 年至 2019 年间每年的一个文件。有些文件具有不同的形状和列名。我们必须确保所有感兴趣的列都有匹配的名称,以防止以后出现问题。

此外,在使用 pd.concat()函数将每个文件合并到一起之前,文件名中的年份必须附加到数据框中名为 year 的新列中。否则,我们将在每个国家的数据框架中有 5 行,完全不知道数据来自哪一年。

最后,发现在 shapefile 中,US 被标记为美利坚合众国。在世界幸福报告数据中,美国被标注为美国。为了在后面的操作中使两者相匹配,我们必须更新国家数据框,将美国替换为美利坚合众国。

datafiles_1 = ['2019.csv', '2018.csv']
datafiles_2 = ['2015.csv', '2016.csv']

df = pd.concat((pd.read_csv(f).assign(Year=os.path.basename(f[0:4])) for f in datafiles_1), sort=False)
df2 = pd.concat((pd.read_csv(f).assign(Year=os.path.basename(f[0:4])) for f in datafiles_2), sort=False)
df3 = pd.read_csv('2017.csv').assign(Year="2017")

df['Country'] = df['Country or region']
df2['Score'] = df2['Happiness Score']
df3['Score'] = df3['Happiness.Score']

countries = pd.concat([df[['Country', 'Score', 'Year']], df2[['Country', 'Score', 'Year']], df3[['Country', 'Score', 'Year']]], sort=False)

countries = countries.replace('United States', 'United States of America')

创建交互性功能

我们将需要两个功能,使我们的地理地图互动和动态。

  1. 获取快乐数据的函数。该函数将接受选择的年份作为参数;今年可以用滑块选择。快乐数据将以 JSON 的形式返回,无论是哪一年。
  2. 滑块更新时触发的函数。这个函数的工作是获取滑块保存的任何新值,并将其传递给从数字 1 开始的函数。无论滑块设置为什么,此功能都会使地图数据保持最新。
# 1\. Define function that returns json_data for the year selected by slider.
def json_data(selectedYear):
    yr = selectedYear
    df_yr = countries[countries['Year'] == yr]
    merged = gdf.merge(df_yr, left_on ='country', right_on ='Country', how ='left')
    merged['Score'] = merged.Score.fillna("N/A")
    merged_json = json.loads(merged.to_json())
    json_data = json.dumps(merged_json)
    return json_data

# 2\. Define the callback function.
# This is what will be called when the slider value changes.
def update_plot(attr, old, new):
    yr = slider.value
    new_data = json_data(str(yr))
    geosource.geojson = new_data
    p.title.text = 'Happiness Score by Country (%d)' %yr

渲染地图

现在终于可以在地图上看到所有这些数据了!

鉴于颜色可以在可视化中产生或破坏,我对散景的调色板做了一些研究,并选择了一个与我的数据有意义的调色板。在这种情况下,悬停工具提示很有帮助,因为有些人(像我一样)苦于地理知识,可能无法说出地图上一半国家的名称。

创建了 slider 对象,注意它的回调函数是上面创建的函数之一。国家之间的线条被设置为白色,以便更好地匹配配色方案。

# Input GeoJSON source that contains features for plotting.
# Select a default year to show on first display.
geosource = GeoJSONDataSource(geojson = json_data("2016"))

# Define a sequential multi-hue color palette.
# I chose the Plasma theme because 10 would map to yellow :)
palette = mpl['Plasma'][10]

# Instantiate LinearColorMapper that maps numbers to a sequence of colors.
color_mapper = LinearColorMapper(palette = palette, low = 0, high = 10)

# Add the hovering tooltips.
hover = HoverTool(tooltips = [ ('Country','@country'),('Score', '@Score')])

# Create the color bar. 
color_bar = ColorBar(color_mapper=color_mapper, label_standoff=8,width = 500, height = 20, border_line_color=None,location = (0,0), orientation = 'horizontal')

# Create the figure object.
p = figure(title = 'World Happiness by Country (2016)', plot_height = 600 , plot_width = 950, toolbar_location = None, tools = [hover])
# Remove the grid lines. 
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None
# Increase the title font size.
p.title.text_font_size = '12pt'

# Add the patch renderer to the figure. 
# Notice that this is where you provide the Score column from the json_data and the color mapper.
p.patches('xs','ys', source = geosource,fill_color = {'field' :'Score', 'transform' : color_mapper}, line_color = 'white', line_width = 0.5, fill_alpha = 1)

# Place the color bar below the map.
p.add_layout(color_bar, 'below')

# Make a slider object.
slider = Slider(title = 'Year',start = 2015, end = 2019, step = 1, value = 2016)
slider.on_change('value', update_plot)

# Make a column layout of widgetbox (slider) and plot, and add it to the current document
layout = column(p,widgetbox(slider))
curdoc().add_root(layout)

# Show the figure.
output_notebook(INLINE)
show(layout)

只需最后一步,你就可以看到你创建的美丽的地图。因为我们使用 on_change()函数,所以我们需要地图是交互式的,否则,当您移动滑块时,地图不会更新。要以交互模式查看此应用程序,您需要设置一个本地散景服务器。不要烦恼!您可以在一行中完成这项工作,并且您可以在命令行中完成这项工作,并且感觉自己已经是一名成熟的黑客了。

打开你的命令行,输入:bokeh serve-show your file name . ipynb

这是最终产品的样子:

嘣!你刚刚做了一个互动地图来分析世界幸福。我希望你喜欢。如果是这样,可以看看我的其他教程,比如我写的关于用单词云可视化 Kickstarter 数据的文章。也许这篇文章提醒了您,您需要复习数据框架知识..别担心,前往我的数据帧 101

原载于 2020 年 5 月 12 日https://data dreamer . io

使用 Jupyter 可视化全球冠状病毒传播

原文:https://towardsdatascience.com/visualizing-worldwide-coronavirus-spread-using-jupyter-dfbf2cd4618?source=collection_archive---------35-----------------------

创建你自己的新冠肺炎传播的可视化

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

有很多关于新冠肺炎和冠状病毒在世界各地传播的公共数据集。 Corona Data Scraper 从经过验证的来源提取新冠肺炎案例数据,找到相应的 GeoJSON 特征,并添加人口信息。Corona Data Scraper 提供了奇妙的可视化效果,比如经过速率调整的 2D 国家级地图和 Antonio Piccolboni 对*滑后的新冠肺炎趋势和预测的可视化效果

如果你想尝试对冠状病毒数据进行自己的分析,你也可以使用 Jupyter 和 Python 小部件创建一些自己的漂亮的全局可视化,我们将在本文中进行讨论。这里有一个完整的交互式可视化的截图。可以拖动滑块查看从 2020 年 1 月 22 日开始的不同日期的新冠肺炎案例。

导入依赖项和数据集

我们将使用的数据集是冠状病毒数据刮刀的时间序列数据。首先导入依赖项并读入数据集。如果尚未安装底图、Networkx 和 Shapely 包,您可能需要安装它们。

import numpy as np
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap as Basemap
from shapely.geometry import Point, MultiPoint
from ipywidgets import interact, widgets
from IPython.display import display

您可以下载 CSV 格式的数据集并在本地读取,也可以在https://coronadatascraper.com/timeseries.csv读取最新更新的数据集。

df = pd.read_csv(‘[https://coronadatascraper.com/timeseries.csv'](https://coronadatascraper.com/timeseries.csv'), parse_dates=[‘date’])

查看数据集和列信息。

我们的分析将只使用一些数据,特别是国家、纬度、经度和案例列。

# Get Country, Lat, Long, Cases, Date
case_df = df[[‘country’, ‘lat’, ‘long’, ‘cases’, ‘date’]]

Jupyter 笔记本截图

使用底图绘制地图

接下来,我们从包含边列表的 Pandas 数据帧创建一个 NetworkX 图。我们的目标是简单地在冠状病毒出现的位置标绘点。使用底图 Matplotlib 工具包,我们可以在地图背景上绘制点。

墨卡托投影。图片鸣谢:维基百科。来自维基共享资源的原始文件

为了使世界形象化,我们将使用墨卡托投影,一种圆柱形的保形投影。这种投影在高纬度地区产生很大的失真,并且不能完全覆盖极地区域。

创建底图墨卡托投影。参数 llcrnrlonllcrnrlat 代表右下角经度和纬度。参数 urcrnrlonurcrnrlat 代表右下角经度和纬度。右下角(西经 150 度,南经 50 度)到左上角(东经 160 度,北纬 75 度)似乎很适合我们的显示。

m = Basemap(llcrnrlon=-150., llcrnrlat=-50., urcrnrlon=160., urcrnrlat=75., rsphere=(6378137.00,6356752.3142), resolution=’l’, projection=’merc’, lat_0=0,lon_0=0., lat_ts=20.)

接下来,创建一个没有节点和边的空图。初始化 Matplotlib 图形以显示地图。

G=nx.Graph()plt.figure(figsize = (20,10))

用 Matplotlib 画空图 G。

nx.draw_networkx(G, node_size=200, node_color=’blue’)

绘制冠状病毒病例

在地图上用点标出冠状病毒病例的位置。

# Create a scatter plot of cases on a single date *d*.one_date_df = case_df[case_df[‘date’]== *d*]
map_points = pd.Series([Point(m(mapped_x, mapped_y)) for mapped_x, mapped_y in zip(one_date_df[‘long’], one_date_df[‘lat’])])

在地图上画出病例的散点图。

# Create a scatterplot on the mapdev = m.scatter( [geom.x for geom in map_points],  [geom.y for geom in map_points],  20, marker=’o’, lw=.25, facecolor=’#33ccff’, edgecolor=’w’, alpha=0.9,antialiased=True, zorder=3)

最后,画地图。

# Now draw the map
 m.drawcountries()
 m.drawstates()
 m.bluemarble()
 plt.title(‘Coronavirus’)

2020 年 1 月 22 日冠状病毒图谱

使地图互动

将单个地图制作代码组合到一个名为 create_map 的函数中,以在任意给定日期执行上述地图绘制。

def create_map(date_d):
    m = Basemap(
            llcrnrlon=-150.,
            llcrnrlat=-50.,
            urcrnrlon=160.,
            urcrnrlat=75.,\
            rsphere=(6378137.00,6356752.3142),\
            resolution='l',projection='merc',\
            lat_0=0,lon_0=0.,lat_ts=20.)G=nx.Graph()fig = plt.figure(figsize = (20,10))nx.draw_networkx(G,node_size=200,node_color='blue')# Draw scatter
one_date_df = case_df[case_df['date']== date_d]
map_points = pd.Series([Point(m(mapped_x, mapped_y)) for mapped_x, mapped_y in zip(one_date_df['long'], one_date_df['lat'])])# Scatterplot on the map
    dev = m.scatter(
                [geom.x for geom in map_points],
                [geom.y for geom in map_points],
                20, marker='o', lw=.25,
                facecolor='#33ccff', edgecolor='w',
                alpha=0.9,antialiased=True,
                zorder=3)# Draw the map
    m.drawcountries()
    m.drawstates()
    m.bluemarble()
    plt.title('Global Coronavirus Cases Starting From 1/22/2020')
    return (date_d, fig)

现在,为每个感兴趣的日期画一张地图。

all_dates = list(case_df['date'].unique()) all_maps = [ ]
for date_d in all_dates:
    all_maps.append(create_map(date_d))

定义一个功能 f 用于选择对应于其各自日期的地图。

def f(index):
    img = all_maps[index][1]
    display(img)

现在创建交互式滑块和地图。

interact(f, index=widgets.IntSlider(min=0,max=68,step=1,value=1,
 description=’Date Starting From 1/22/2020:’ ))

就是这样!这里有一张 gif 图,可以看到交互式滑块在整个时间序列中的样子。

通过 imgflip.com 创建的 Gif

参考文献

[1]https://coronadatascraper.com/

[2]https://towards data science . com/catching-the-flight-visualizing-social-network-with-network x-and-base map-ce 4a 0 D2 ea 6

[3] NetworkX 文档https://networkx.github.io/documentation/stable/index.html

[4]底图文档https://matplotlib.org/basemap/

使用 Python Plotly 地图可视化全球新冠肺炎数据

原文:https://towardsdatascience.com/visualizing-worldwide-covid-19-data-using-python-plotly-maps-c0fba09a1b37?source=collection_archive---------18-----------------------

埃德温·胡珀在 Unsplash 上的照片

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

2019 年 12 月 31 日,世界卫生组织(世卫组织)驻中国国家办事处首次报告了一种未知的肺炎类型疾病。这种未知的疾病后来在 2020 年 2 月 11 日被命名为新冠肺炎,因为它与导致 2003 年 SARS 爆发的冠状病毒有遗传关系。新冠肺炎很快在世界范围内广泛传播,直到世卫组织于 2020 年 1 月 30 日宣布该疫情为国际关注的突发公共卫生事件。

在这篇文章中,我将介绍使用 Python Plotly 库 绘制地图的两种方法,以显示新冠肺炎病例在世界各地的分布。

你需要什么

先决条件 Python 库

python Plotly—https://plotly.com/python/

蟒蛇熊猫—https://pandas.pydata.org/

安装指南可以在官方网页上找到。

数据集

新型冠状病毒数据集

第 1 部分:地图上的散点图

在本节中,我们将使用来自 plotly 库的 plotly.graph_objects 在世界地图上创建一个散点图,以显示新冠肺炎确诊病例在世界各地的分布。

步骤 1:探索新的冠状病毒数据集

探索新冠肺炎数据集的 Python 代码

代码解释

第 1–2 行:导入熊猫和 Plotly 库

第 3 行:世界范围内的新冠肺炎数据可以在 小说电晕病毒数据集 的一个 CSV 文件中找到。 我们可以使用熊猫 read_csv 方法来读取文件。

第 4 行:使用 Pandas head 方法显示前 5 行记录。

数据集记录的前五行

从上面的结果中,我们可以观察到数据集包括从 2020 年 1 月 22 日到 2020 年 4 月 13 日(截至本文撰写时)每个国家报告的新冠肺炎病例数。该数据集每天都会更新。不幸的是,数据集中缺少省/州的详细信息。我们可以看到在省/州列中有很多 NaN 值。

为了简化我们操作列和绘制地图的后续任务,建议简化一些列名(如国家/地区)。

Python 代码重命名列

代码解释

第 5 行:我们可以使用熊猫重命名的方法,将列名“国家/地区”改为“国家”,“省/州”改为“省”。

第 6 行:重命名列后,我们使用熊猫头方法再次查看记录。

重命名的列

步骤 2:在地图上创建散点图

我们现在可以继续使用 Python Plotly 库,使用Plotly . graph _ objects在地图上创建散点图。

用于在地图上创建散点图的 Python 代码

这些代码(第 8 - 39 行)一开始看起来让人望而生畏。不要担心,它们只是我们需要为地图设置的参数,关于这些参数的信息可以在 Plotly 参考页面中找到。这里我只讨论几个重要的参数。

代码解释

第 8 行:设置将出现在数据点上的文本元素。这意味着当我们将鼠标悬停在地图上的数据点上时,预定义的文本(例如,国家名称+20 年 4 月 4 日的病例数)将会弹出。

Line 10–11:lonlat 是我们为地图上每个数据点设置的经纬度参数。

第 14–23 行 : 标记是地图上数据点的表示。这里我们将符号(第 19 行)设置为正方形。这将在地图上将每个数据点呈现为一个正方形。我们可以将 reversescaleautocolorscale 保留为 True,以使标记的颜色根据报告的新冠肺炎病例数自动改变。

第 24–26 行 : cmincmax 是数据点色域的下限和上限。

第 31–37 行:这是我们为整个地图设置参数值的部分,比如地图标题(第 32 行),更重要的是范围(第 34 行)。如果我们打算在地图上显示世界范围的数据,我们需要将范围设置为“world ”, Plotly 将生成一个世界地图。如果我们的目的只是只显示美国的数据点,我们可以将范围设置为“美国”。我们可以选择以下范围选项之一:

  • 世界
  • 美国
  • 欧洲
  • 非洲
  • 北美洲
  • 南美洲

第 39 行 : fig.write_html 将生成一个显示散点图的 html 页面。

: 可以在 Jupyter 笔记本或 Jupyter Lab 上显示地图,而不是在单独的 HTML 页面上。为此,我们必须为我们的 Jupyter 笔记本/ Jupyter 实验室安装一个扩展(【https://plotly.com/python/getting-started/】)。

地图上的散布图

上面的散点图让我们大致了解了 2020 年 4 月 13 日世界各地报告的新冠肺炎病例。与深色标记相比,黄色标记反映的报告病例相对较少。从地图上,我们可以看到美国是报告病例最多的国家,其次是欧洲的一些国家,如意大利、英国、法国等。当我们将鼠标悬停在地图上的一个数据点上时,我们可以看到一个预定义的弹出文本,显示与该数据点相关的国家名称和已报告病例数。

弹出信息

第 2 部分:Choropleth 地图

我们也可以使用同一个数据集,通过 plotly.graph_objects 绘制 choropleth 图。但是,我们需要对数据进行预处理,然后才能创建 choropleth 图。

第一步:数据预处理

为了创建 choropleth 图,我们需要从我们的数据集中获得两条信息:

  1. 独特的国家列表
  2. 每个国家报告的新冠肺炎病例总数(2020 年 4 月 13 日)

不幸的是,我们无法从原始数据集中直接提取出这两条所需的信息。通过预览一些记录,再次仔细查看我们的数据集。

原始数据集中的两个问题

我们可以从我们的数据集中得到如下两个观察结果:

  1. 我们的记录中有重复的国家名称。这是因为给定数量的已报告新冠肺炎病例被分解到可能属于同一个国家的几个省/州。
  2. 2020 年 4 月 13 日报道的新冠肺炎案例的每一行都只是发生在一个国家的每个省或州的案例的小计。

当我们逐个国家地遍历记录时,可以断断续续地看到上面的两个观察结果。这意味着原始数据集中的记录不一致。有些记录需要对一个国家的州进行细分,而有些记录只包含整个国家的单行数据。

幸运的是,这里有一个简单的修复方法。我们可以使用熊猫图书馆来重组我们的数据。

用于重构数据的 Python 代码

代码解释

第 1–5 行:这是导入必要的 Plotly 和 Pandas 库,读取 CSV 文件以及重命名一些列的步骤。

第 7 行:我们可以使用 Pandas groupby 方法根据国家对我们的数据进行分组,并应用 sum 方法计算每个国家报告的病例总数。结果是一个总和列表,我们将它赋给一个名为 total_list 的变量。

每个国家报告病例总数系列

第 9–13 行:我们将清理国家列表并生成一个唯一的国家列表。

  • 首先,使用 tolist 方法将 Country 列转换为 list 对象,并将其赋给变量 country_list (第 9 行)。
  • 接下来,使用 set 方法将 country_list 转换成 Python set 对象。set 方法将自动从 country_list 中删除所有重复的国家名称。只有唯一的国家名称会存储在国家设置(第 10 行)中。
  • 接下来,再次将 country_set 转换为列表,并将其分配回 country_list (第 11 行)。
  • 使用排序方法按照字母顺序重新排列国家列表(第 12 行)。**这一步是必需的,因为之前使用的 set 方法会使国家/地区的顺序随机化。*

第 14 行:最后,我们使用前面步骤生成的 country_listtotal_list 作为新数据帧中仅有的两列,创建一个新数据帧。

重组原始数据后的新数据框架

我们已经成功地重组了我们的数据,并将其存储到一个新的数据帧中, new_dfnew_df 包含了我们生成 choropleth 地图所需的数据(唯一的国家列表和每个国家的总病例数),我们现在准备进入下一步。

步骤 2:生成 Choropleth 图

choropleth 地图是一种由彩色多边形组成的地图,用于表示数量的空间变化。我们将使用 go。Choropleth graph 对象创建一个 Choropleth 图,显示全球已报告新冠肺炎病例的分布。

创建 Choropleth 地图的 Python 代码

同样,这些代码一开始看起来令人望而生畏。然而,它们只不过是设置参数来构建 choropleth 图。我们可以参考官方网站上的参考页面来获得更多关于参数的信息。

代码解释

第 17–19 行:我们可以为我们的 choropleth 贴图定义一个色域。要定义一个色域,我们只需创建一个六色代码列表。(*颜色代码可在此处获得)。

第 22–33 行:这是我们可以设置位置列表、色域、地图上显示的文本信息、标记线颜色等参数的部分。

  • 因为我们绘制地图来显示世界各地的新冠肺炎病例,所以我们将位置模式设置为“国家名称”。这使我们能够将国家列从 new_df 设置为地点参数(第 23–24 行)。这是使 Plotly 能够将我们的新冠肺炎数据映射到 choropleth 地图上各自国家位置的重要一步。(请注意,这里没有坐标,lat & long,均为必填)。
  • 我们将来自 new_dfTotal_Cases 数据设置为参数 z (第 25 行)这是使 Plotly 能够根据应用于 choropleth 图的色域揭示报告病例频率的另一个关键步骤。
  • 我们还可以将“ Total_Cases ”设置为文本参数(第 26 行)。每当我们将鼠标悬停在地图上的某个国家/地区上方时,就会在弹出文本中显示病例总数。
  • 由于我们已经定义了自己的色域(第 17–19 行),我们可以将参数 autocolorscale 设置为 false(第 28 行)。
  • 我们还为颜色栏设置了一个标题(第 30 行)。

Line 33–37:这里,我们简单地为地图设置一个标题,并启用地图上显示的海岸线。

第 40 行:将地图输出到 HTML 页面。

等值区域图

最后,我们成功创建了一个 Choropleth 地图,显示了全球冠状病毒爆发的流行水*。当我们将鼠标放在一个国家地区的上方时,我们可以看到以弹出文本显示的报告病例数。

Choropleth 地图上的弹出文本

第 3 部分:在线发布 Plotly 地图

你有没有想过我们可以在线发布我们的地图?Plotly 为我们提供了一个免费与公众分享地图的选项。为此,我们只需遵循以下几个简单的步骤:

第一步:安装 chart_studio

打开您的终端(Mac)或命令提示符(Windows),点击

**pip install chart_studio
or
sudo pip install chart_studio**

第二步:注册一个 Chart Studio 的免费账户

访问图表工作室页面,注册一个免费账户。这个过程只需要不到 3 分钟。免费帐户允许我们与公众分享最多 100 张图表。

步骤 3:在 Python 代码中设置凭证

注册一个免费的 Chart Studio 帐户后,访问设置页面并寻找 API 键。复制 API 键并将其粘贴到我们之前的 Python 代码(散点图或 Choropleth 图)的顶部。

设置 Chart Studio 凭据的 Python 代码

第 1–2 行:这两行代码提供凭证信息,使我们的 Python 程序能够访问 Chart Studio 特性。

步骤 4:将地图共享给公众

为了将我们的地图分享给公众,我们所需要的只是在现有 Python 程序的最后一行(第 42 行)添加一行代码。

将地图共享给公众的 Python 代码

运行代码,Plotly 将返回一个 URL,将我们重定向到托管我们地图的网站。

您可以在此链接 1 查看我的共享散点图,在此链接 2 查看 Choropleth 地图。

结束语

Python Plotly 是一个易于使用的图表绘图库,使我们能够创建令人惊叹的图表并与公众分享。这绝对值得我们花时间学习 Plotly,并使用它来完成我们的数据可视化任务。如果你有兴趣了解更多关于 Plotly 库的知识,可以在这篇博客文章中找到有用的教程。

我希望这篇文章能对你有所帮助。

为了与我联系,你可以

  1. 跟着我上
  2. 通过 LinkedIn 联系我

开源代码库

本文中的所有源代码都可以在 GitHub 资源库中找到。

参考

  1. https://www . who . int/emergencies/diseases/novel-coronavirus-2019/events-as-these-as-than-happens
  2. https://plotly.com/python/
  3. https://Neptune . ai/blog/plotly-python-tutorial-for-machine-learning-specialists

维特尔应该被认为是一名伟大的 F1 车手吗?他在法拉利的时光是失败的吗?

原文:https://towardsdatascience.com/visuallyanalysingvettelscareer-9e8a881e2292?source=collection_archive---------20-----------------------

塞巴斯蒂安·维特尔职业生涯的数字和图表视觉分析。

维特尔代表法拉利参赛(照片由澳门图片社在 un spash上提供)

"头号车手回来了,法拉利回来了."

塞巴斯蒂安·维特尔刚刚赢得了 2015 年马来西亚大奖赛,这是他从红牛车队加入意大利赛车巨头法拉利以来的第二场比赛。

“谢谢,谢谢。法拉利万岁”

随着他的食指指向天空,可以听到世界各地的 F1 粉丝抱怨说,随着维特尔消失在远处,这项运动注定会有更多的旗杆游行,而不是在比赛期间受到困扰。

但那并没有发生。不管怎么说,维特尔和法拉利都不是。

2015 年至 2019 年的比赛冠军。自 2015 年以来,汉密尔顿赢得了 50%的 F1 比赛。

自 2015 年以来,梅赛德斯已经连续赢得了 5 个制造商冠军,刘易斯·汉密尔顿赢得了 50%的比赛(没错,*均而言,汉密尔顿在过去 5 年中每隔一场比赛就赢一场)。与此同时,维特尔(14%)和法拉利(17%)一直在与红牛车队争夺剩下的少得多的胜利。

快进到 2020 年,由于冠状病毒,赛季仍未开始,一级方程式围场的亮点是维特尔将在 2020 赛季结束时离开法拉利。没有一个可行的开放在一个顶级车队下赛季,维特尔的 F1 未来悬而未决。

在这篇文章中,我回顾了维特尔的职业生涯,直观地分析了他在 F1 大师赛中的表现,并评估了他在法拉利的时光是否应该被视为成功。

故事到此为止...

Rain 在 f1 中是一个伟大的*衡器,它将重要性的天*从赛车转移到了车手身上,并测试车手在测试条件下的适应能力。湿滑比赛是 F1 中典型的戏剧性场面,水花从轮胎胎面飞溅出来,汽车四处滑行(偶尔还会打滑)..)路滑的情况下。

在这种比赛中的出色表现往往会铭记在心。据说塞纳在潮湿的 T5 赛道上让 T4 变得活跃起来,比如 1993 年的欧洲大奖赛,他从发车位置滑落到第五位,然后在第一圈 4 次超车后重新获得第一名。简森·巴顿在 2011 年蒙特利尔的一场湿滑比赛中的胜利仍然让人不寒而栗,当他从第 20 名跑到最后一圈的时候(那一次对维特尔不利)。

正是在 2008 年非常潮湿的蒙扎,21 岁的维特尔成为 F1 历史上最年轻的杆位获得者。他和许多人在一起;舒马赫和塞纳的第一场胜利都来自于湿滑的比赛,他们在充满挑战的湿滑天气条件下超越了他们的赛车。鉴于他的年龄和国籍,媒体很快将他与舒马赫相提并论,一些人将他称为“小舒米”,尽管维特尔在他职业生涯的早期很快就将这些称为“荒谬”。

根据年龄赢得比赛:维特尔在 2008 年成为最年轻的 F1 比赛冠军和杆位获得者,这一纪录由马克斯·维斯塔潘在 2016 年打破。

然而,在很长一段时间内,这种比较可能不会像维特尔最初建议的那样荒谬。继维特尔在 2008 年红牛之队(红牛的姐妹队)取得突破性的赛季后,他在 2009 赛季开始时被提升到红牛车队退役的大卫·库特哈德留下的空缺席位上。

克里斯蒂安·霍纳掌舵,艾德里安·纽维领导赛车的设计,维特尔通过红牛的“RB5”在 2009 年发起了一场严峻的冠军挑战。红牛在 2009 赛季获得了 6 场胜利,布朗的简森·巴顿赢得了车手总冠军。个人而言,维特尔赢得了 4 场比赛,并以 11 分的优势获得亚军。

没过多久,维特尔就获得了他的第一个车手总冠军。2010 年,这位德国车手赢得了世界冠军,打破了最年轻车手的冠军记录。他随后连续赢得了 3 个世界冠军,打破或*了许多记录,包括一个赛季中从杆位获得最多的胜利(9),连续比赛最多的胜利(9)和一个赛季中最多的胜利(13,与迈克尔·舒马赫分享)。

维特尔的累积胜利轨迹在加入法拉利后发生了巨大变化

2009 & 2013 年间,维特尔&红牛创造了一个堪比舒马赫&法拉利,以及后来的汉密尔顿&奔驰的王朝。维特尔赢得比赛的速度让他名列前茅;在 120 场比赛中,他的轨迹远远领先于其他 F1 大师塞纳、普罗斯特和汉密尔顿。他甚至在 2013 赛季中期超过了舒马赫的胜率(在各自的职业生涯中参加了 113 场比赛)。

但是,突然之间,这条线停止了增长。坡度从陡坡变到缓坡。维特尔在 2014 赛季未能赢得一场比赛,之后他“梦想转会”到 F1 最负盛名、装饰最华丽的车队。

这种关系有了一个充满希望的开端。在一个由刘易斯·汉密尔顿和尼科·罗斯伯格主宰的赛季中,维特尔是唯一一个赢得比赛的非梅赛德斯车手,也是托托·沃尔夫车队之外唯一一个真正的挑战者。这为法拉利在冬歇期变得更具竞争力提供了基础,维特尔更加融入了马拉内罗的车队和文化。

不幸的是,这没有成功。法拉利在 2016 年没有赢得一场比赛,在车队积分榜上落后于红牛,加剧了维特尔和法拉利的痛苦。维特尔目前在法拉利 5 年的胜利数只比他在红牛最成功的一年多一次。

那么,为什么这一举动(以及维特尔的胜利曲线)会变得*淡,这对他在 F1 传奇中的地位意味着什么?

对比维特尔的红牛和法拉利职业生涯

在高水*上,维特尔在法拉利和红牛的表现非常相似。

当我们汇总数据来比较维特尔在法拉利和红牛的表现时,他们之间的差距很小。在最高水*上,在所有比赛中,维特尔在法拉利的*均排名仅比红牛高 0.1 位。取中间值提供了一个非常相似的故事;维特尔在法拉利和红牛车队的中间位置是第三名。

逐步降低一个级别来评估季节级别的结果说明了更多一点的变化,但再次描绘了类似的画面。事实上,维特尔在 2015 年、2017 年和 2018 年在法拉利的*均排名低于他在红牛赢得世界冠军的两个赛季(2010 年和 2012 年)。2017 年和 2018 年,维特尔的赛季末总积分也远高于 2010 年和 2012 年。

直到你更深入地挖掘个体结果,差异才开始显现。除了 2014 赛季,维特尔最常获得的名次是第一。这在法拉利只发生过一次,2018 年。他在法拉利每个赛季的其他成绩都集中在第二、第三和第四名。这些无疑仍然是令人印象深刻的结果,但缺乏第一名的成绩对维特尔在法拉利的最终成功产生了巨大的影响。

维特尔结果的形状:每个赛季的直方图显示在红牛有更多的第一名,在法拉利有更多的较低积分。

首先,在这项运动中,比赛胜利是衡量车手的标准,除了第一名就是失败。由塞纳雄辩地提出;成为第二就是成为第一个失败的人。更重要的是,F1 的统计数据受到每个赛季比赛数量的限制。足球或橄榄球赛季可能有 40-50 场比赛,加上国际比赛,而 F1 车手每个赛季最多有 20-22 场比赛来确保胜利。

其次,对他的冠军挑战更有影响的是国际汽联的积分分配系统对第一名的激励。一场胜利得 25 分,比第二名多 7 分。从第二名到第三名的差距是 3 分,第三名到第四名也是如此,此后差距缩小。如果积分以线性方式下降,多个第二和第三名对维特尔来说不会是这样的坏消息,但单个名次下降的收益递减的规模赋予了比赛胜利额外的重要性。因此,维特尔在法拉利的日子里没有赢得领奖台的集群严重抑制了他增加世界冠军的能力。

为了理解为什么维特尔无法将更多的领奖台成绩转化为比赛胜利,我们可以进一步细分到比赛水*。是维特尔对未能赢得比赛负有责任,还是法拉利套件在需要与梅赛德斯争夺霸权的时候根本没有竞争力?

法拉利总积分与最终赢家(在这种情况下,梅赛德斯在所有 5 年)。

根据制造商排名(一个车队中所有车手的积分总和),法拉利在 2015 年、2016 年和 2019 年都没有接*挑战最终的冠军(梅赛德斯在所有 5 年中都是冠军)。然而,在 2017 年和 2018 年,差距明显缩小,这表明法拉利作为一个团队,在性能方面更接*梅赛德斯。

在这两年中,维特尔在锦标赛中获得亚军,并获得了 5 场比赛的胜利。两个赛季的开局都很强劲,维特尔在前半个赛季的大部分时间里都领先于冠军。然而,在这两次比赛中,他都在赛季中期到后期的一系列低排名中让领先优势溜走了。

在维特尔的辩护中,一些低的成绩是由于工程问题。英国大奖赛后期爆胎,随后是马来西亚的涡轮问题和日本的火花塞故障,这些都导致维特尔失去了位置和积分。与此同时,车手的失误和挫折悄悄进入了他的比赛,这在他为红牛效力期间并不普遍。

最终位置的移动*均值:维特尔在 2017 年和 2018 年与法拉利的冠军挑战在赛季中期瓦解。

2017 年,维特尔的问题始于阿塞拜疆,他在安全车条件下分流汉密尔顿有罪,声称英国人在对他进行“刹车测试”。汉密尔顿赛车的遥测数据显示情况并非如此。在新加坡,维特尔在赛道上与莱科宁和维斯塔彭发生了冲突,导致法拉利有史以来第一次在比赛的第一圈就双双退赛。

2018 年本应是法拉利套件最终与梅赛德斯匹敌的赛季。法拉利和维特尔在半程阶段领先两个冠军,但车手和车队再次合谋丢掉领先优势。维特尔在德国大奖赛中领先,在他的家乡赛中接*胜利,这时他冲出路障并结束了比赛。在蒙扎,维特尔让与汉密尔顿发生冲突,并再次打滑,在第一圈跌至第 18 位。

汉密尔顿(蓝绿色)和维特尔(红色)每个赛季的累积积分。在 2017 年和 2018 年,维特尔的冠军挑战在赛季中期结束后瓦解。

虽然法拉利的可靠性和策略要求并不总是像在梅赛德斯那样得到很好的执行,但排位赛和比赛日的一系列非受迫性失误成为了维特尔比赛的模式。他真正伟大的表现变得越来越少(尽管没有完全消失,但 2018 年 Spa 是一场令人想起他在红牛时代的胜利)。

如果没有车队和车手的失误,很难说维特尔在 2017 和 2018 赛季会取得什么样的成绩。双方都必须为他们在一起时未能获得车手或车队世界冠军承担一些责任,但维特尔作为首席车手和四次世界冠军的责任是提供无失误的表现,并以身作则领导团队。在这方面,他在法拉利的时光不能被视为成功。

到了 2019 赛季,维特尔与法拉利的关系开始变得紧张。借口和道歉越来越少,两人都感到疲惫。除此之外,街区里还有一个新来的小伙子,他开始为自己扬名,并吸引了法拉利车迷的注意。

可能加速维特尔离开法拉利的一个因素是查尔斯·勒克莱尔的到来。当把维特尔在红牛和法拉利的职业生涯放在一起时,很明显德国人更喜欢某种团队动力。

维特尔在红牛车队(左)和法拉利车队(右)的积分

在两支车队中,维特尔作为车队的“第一号”或首席车手(正式或非正式地)享受了他的大部分成功。韦伯和莱科宁都是经验丰富的车手,都非常有能力赢得比赛,但当维特尔分别加入红牛和法拉利时,他们的职业生涯即将结束。虽然两人都很有竞争力,但在整个赛季中,他们都没有对维特尔构成太大的威胁;他们在 8 个赛季的比赛中都未能超过维特尔。

然而,当维特尔与一位渴望在 F1 留下自己印记的年轻天才车手搭档时,这一统计数据发生了变化。在红牛车队是丹尼尔·里卡多,在法拉利车队是查尔斯·勒克莱尔。像维特尔一样,里卡多从红牛之队晋升到红牛车队的席位,并以其幽默、灿烂的笑容、狡猾的超车和赢得比赛的能力迅速赢得了 F1 粉丝的心。

里卡多和莱克勒克与维特尔之间的相似之处非常有趣。2014 年,维特尔未能赢得一场比赛,里卡多赢得了 3 场比赛,领先队友 71 分。2019 年,维特尔赢得了一场比赛,而莱克勒克在法拉利的首个赛季赢得了 2 场胜利,得分超过了他的队友。随着 2020 赛季看起来将以一种与粉丝们习惯的非常不同的形式开始,至少维特尔将有机会反击莱克勒克,如果只是为了临时日历在比赛方面能够承受的任何事情。

这给维特尔留下了什么?

加入法拉利后,维特尔的最终目标是增加他的 4 个世界冠军。在 2020 年底没有实现这一目标就离开意味着他在法拉利的时间不能被视为成功。由于 2017 年和 2018 年的错误挑战,情况尤其如此,车手错误对他的最终总积分产生了相当大的影响。

虽然从世界冠军的关键指标来看,维特尔并不成功,但在法拉利,他绝不是一个失败者。他在法拉利历史冠军排行榜上名列第三,领先于法拉利世界冠军阿斯卡里和莱科宁。就*均排位赛而言,他在法拉利的排位赛也非常接*红牛。他只是缺乏他在红牛时代的临床和统治力,无法将一些登上领奖台的成绩转化为胜利和最终的冠军。

他在法拉利工作的影响也使维特尔在 F1 大师中的地位受到质疑。汉密尔顿、舒马赫、普罗斯特和方吉奥都以多名建造者获得了冠军。维特尔只是凭借发车区最快的赛车赢得冠军的说法将困扰着他。当然,在任何一年,可能只有一两辆车能够赢得冠军,但许多人会认为 2017 年和 2018 年的法拉利属于那种赛车。

从统计数据来看,维特尔的胜利和杆位也推动他走向伟大;他在所有获奖名单中排名第三,在所有杆位名单中排名第四。然而,不知何故,在讨论 F1 的“山羊”(有史以来最伟大的)时,提到他有点犹豫。他在红牛车队的日子里留下了深刻的记忆,那是一次又一次的胜利,其他车队都在他身后苦苦挣扎。更新的记忆,尽管看起来很残酷,是压力下的旋转和不合时宜的错误。

还有一种说法是,这是一个时机问题。如果维特尔先为法拉利比赛,然后去红牛,获得他的 4 个世界冠军,我相信他今天会被以一种非常不同的眼光看待。他的职业生涯将加速达到一个顶峰,而不是从顽皮早期的巅峰减速到他现在的位置。

比赛胜利:维特尔和汉密尔顿从 2015 年到现在的对比命运。

与此同时,汉密尔顿展示了相反的轨迹。他在迈凯轮的职业生涯无疑令人印象深刻,但更稳定的开局与维特尔在法拉利的表现并无不同。他目前在梅赛德斯的位置显示了维特尔在红牛的统治地位。随着他的梅赛德斯赛车在人们记忆中的胜利,汉密尔顿在大赛中的地位得到了巩固,因为他追逐了舒马赫有史以来的比赛胜利和冠军记录。

没人能夺走维特尔的冠军和胜利,但如果 2020 年是他在 F1 的最后一年,他在缩减赛季剩余比赛中的表现将在很大程度上决定维特尔在 F1 粉丝的记忆中的地位。

詹姆斯·史密斯是伦敦的分析顾问和体育数据可视化专家。更多详情请访问 sportschord.com**或在 twitter 上关注他@sports chord

本文的数据是使用 Ergast 开发人员 API 在 R 中准备的,并在 Tableau 中可视化。

立即可视化您的音乐流偏好🎧

原文:https://towardsdatascience.com/viz-your-music-with-spotify-api-and-plotly-eaa65f652191?source=collection_archive---------26-----------------------

通过连接到 Spotify APIs,您可以收集您的流媒体历史记录和播放列表歌曲的曲目功能。你会惊讶的!

穆罕默德·梅特里在 Unsplash 上的照片

作为一个公认的音乐爱好者,我几乎每天都听音乐,在学习、跑步或者只是为了放松的时候。我在中国时使用网易云播放流媒体音乐,而在美国开始硕士课程后,我改用 Spotify。网易和 Spotify 都提供年度总结服务,让用户回顾他们今年最喜欢的歌曲。除此之外,我渴望知道我喜欢的歌曲或艺术家的其他特点。因此,我从流媒体历史记录和我自己创建的播放列表中收集了曲目信息和功能,以构建我的音乐流媒体故事。

我将这篇文章分成两部分:第一部分向您介绍我如何连接到 Spotify APIs 并检索我需要的音乐数据。第二部分显示流历史和播放列表轨道的探索性分析。让我们开始拍子吧!

完整代码可在我的GitHub获取。

第一部分。获取您的流媒体历史和播放列表轨道信息。

I.1 下载流媒体历史记录

工作的第一步是决定我想要可视化的覆盖范围,以便我们从 Spotify 检索正确的数据。Spotify 允许用户在https://www.spotify.com/ca-en/account/privacy/请求他们的流媒体历史记录,通常需要 2-3 天才能获得数据,尽管说明显示 Spotify 需要大约 30 天来准备数据。
流历史将被下载到 JSON 文件中,我们可以先将 JSON 数据转换成数据帧。

现在,我们可以更好地查看流历史中的信息:我们得到了艺术家名称、结束时间、播放时间、曲目名称(这些都是不言自明的)

从 Spotify 帐户下载的流媒体历史数据的示例视图

I.2 从 Spotify APIs 检索您的流媒体历史记录的曲目功能

上述步骤仅提供了有限的流媒体历史信息,其他曲目信息不包括在内,例如,Echo Nest(Spotify 拥有)计算的流行度、模式、基调和其他特征

Spotify Web APIs 出现了,它允许用户搜索歌曲、艺术家和播放列表,设置元数据功能。

首先,在开发者仪表盘中注册你的应用。注册后可以看到你的 ClientID 和客户端秘密(如图 1 截图)接下来,转到网页右上角的‘编辑设置’,然后重定向 URIs=http://localhost:7777/callback。保存设置,我们完成了先决条件设置,然后可以检索数据。

图一。你自己的 Spotify 应用截图

然后我们使用 python 包 Spotipy 连接到 web APIs。函数从 spotipy.util 发送我们的客户端 ID客户端秘密给 Spotify,Spotify 会通过提示授权窗口返回令牌。跟随它,使用您的 Spotify 凭据登录,并粘贴提示控制台中重定向到的任何链接(这将是一个无效页面)。

那么你的令牌将被存储在变量令牌中。打印出来,回顾一下你得到了什么!

获取 track_id,Spotify 中某首曲目的唯一标识符。Spotify API 还提供了描述歌曲特征的多个维度的歌曲特征。让我们稍微了解一些特性吧!
声学:一个衡量音轨是否声学的指标(0 到 1)。1.0 表示音轨是声学的高置信度。
dance ability:dance ability(0 到 1)描述歌曲是否适合跳舞,它结合了包括拍子、节奏稳定性、拍子力度等元素。值=1 非常适合跳舞。
能量:能量(0 到 1)衡量歌曲的速度、音量和嘈杂程度。
乐器性:一个度量(0 到 1)表示一个音轨是否不包含人声。对于一个纯器乐宋立科一个没有任何声乐的古典钢琴杰作,指数将接* 1。
响度:一个音轨的指数,单位为分贝(dB)。该值通常介于-60 和 0 dB 之间。
模式:该特征表示音轨的音阶(大调或小调)。大调用 1 表示,小调用 0 表示。通常情况下,大音阶的音乐作品更明亮,而小音阶的音乐作品更模糊/暗淡。
价:这是一个有趣的衡量标准(0 到 1),描述了一条赛道的积极程度。一个曲目越快乐欢快,数值越高。

砰!现在,我们拥有了 Spotify 流媒体历史的所有功能!

I.3 检索我自己创建的播放列表和功能

除了可能会偶然播放大量歌曲的流媒体历史记录之外,播放列表中的歌曲也由我固定,我根据不同的心情或不同的目的对它们进行了分类。Spotify APIs 还允许用户检索播放列表记录,我们将检索我的播放列表中所有曲目的功能,就像我在上一节中所做的那样。(请看我在 Github 中的代码!)

砰!现在,我们既有完整的流媒体历史数据,也有我的播放列表。

播放列表曲目的结果数据帧

流式历史曲目的结果数据帧

第二部分。可视化我的流媒体习惯和音乐偏好

到目前为止,我们应该已经准备好了完整的数据表。在这一部分,我将展示探索性分析如何帮助我进一步了解我喜欢什么音乐。

我多久听一次音乐?

我经常告诉人们我离不开音乐,我每天都在听…但是我做到了吗?下面的热图日历剧情告诉我真相:不,我没有!(蓝色方块越深,那天我播放音乐的时间越长。2019 年的大片空白是因为我在转投 Spotify 之前是 Apple music 用户。)根据热图,我每周大约有一天不听音乐。

我最喜欢的歌手和歌曲

麦克·艾尔斯、 两度约翰·梅耶是我播放列表中的前三位艺术家。Twice 是韩国流行音乐中的顶级组合之一,约翰·梅耶是美国著名的歌手兼作曲家、吉他手和唱片制作人。等等,谁是麦克·艾尔斯?我甚至不知道麦克·艾尔斯是谁!经过审查,我知道 Mac 是一个美国 R & B 歌手兼词曲作者、制作人和多乐器演奏家。我在 chillnightVlog 列表中总共添加了 9 首 Mac Ayres 的歌曲,我喜欢它们,因为这些歌曲是冷冻的,并且是蒸汽波风格的。他值得被重视。

根据流媒体历史,我听了很多古典音乐,大多是巴赫,弗朗兹,德彪西。去年我演奏了 100 多首巴赫的不同作品。表示我大部分时间都是随机播放他的作品,而不是循环重复。相比之下,对于彼得·马什,我花了几乎同样多的时间,但只唱了他的大约 20 首歌。我重复最多的歌曲正是来自彼得·马奇。我已经放了他的圣诞树超过 400 分钟,比我放其他歌的时间都多。

根据我这一年来听过的顶级歌曲和顶级艺人,几乎一半都是古典音乐。直到看了数据,我才意识到我对古典音乐如此着迷。

我的播放列表的个性

让我们先来探索我的播放列表的个性吧!我有 8 个播放列表,在那里我收集了适合不同心情的音乐:客厅歌曲更温和稳定,更适合在我学习或工作时听,因为这些音乐让我*静和放松。相比之下,K-pop 的播放列表则包含了大多数轻快而丰富的韩国流行歌曲,有着吸引人的旋律和非常规的制作。

我检查了雷达图中的以下特征:声音、舞蹈性、能量、乐器性、响度、*衡。除了响度,所有其他功能都在 0-1 标度上,因此我首先将响度转换为 0-1 标度。我把每个播放列表都画成了雷达图,以显示和比较列出的功能。图表显示播放列表客厅歌曲古典音乐最具音乐性和器乐性,因为这两个播放列表中的大多数歌曲都是纯粹的器乐作品,而 K-pop公路旅行则非常响亮,充满活力。其余四个播放列表相当均衡。

接下来,我们来探究一下我的播放列表歌曲有多受欢迎。通过流行指数的箱线图,我可以看出我播放列表中的大多数歌曲都是 50-60 流行度的。榜单 K-pop 最受欢迎,古典最不受欢迎。这是很合理的,因为现在人们很少关注古典音乐,除非这首曲子非常有名。名单寒夜踮起脚尖💫在流行度分数方面具有稀疏分布。最高人气略高于 80,说明我好像不是“热门”歌曲的粉丝。

模式是轨道的两个基本特征。不同调的音乐有不同的风格,但微小的差异只有专业的音乐人才能识别。然而,大调和小调模式更容易识别:大调音阶通常更明亮或欢快,而小调听起来更忧郁和悲伤。看看这个 Youtube 视频与样本音频有更直接的联系。根据下图,我可以看出我更喜欢大调模式而不是小调模式。我喜欢让我开心,点亮我生活的歌!

让价指数代表我的心情。

Spotify 计算的价指数表明一首歌有多快乐或悲伤,这有助于我跟踪我的情绪。我用误差棒图来表示每天的*均价和价的方差。下图显示了我在 3 月上半月和 5 月的心情似乎并不好。嗯嗯,正好是我硕士项目两个季度的期末考试阶段,真的很忙,压力很大。那就很有道理了!

结论

通过可视化我的播放列表曲目和流媒体历史,我更彻底地了解了我喜欢的音乐,甚至对不看数据永远不会知道的事实感到惊讶。如果你也对你正在听的音乐感兴趣,试着建立你的探索。欢迎来到 Spotify 中的与我联系

参考文献

[1] Santos,J. D. 我的 Spotify 音乐无聊吗?涉及音乐、数据和机器学习的分析 (2017)

[2]Spotify for Developers:Reference,获取多首曲目的音频功能

这是我第一个与音乐有关的博客。接下来,我将进一步探索其他主题和工具(例如,在我无聊时倒出我可能喜欢的音乐的音乐推荐工具,或使人们能够听我的流媒体音乐的同步流媒体工具)。有兴趣的话,随时联系我 Linkedin

基于神经网络的语音分类

原文:https://towardsdatascience.com/voice-classification-with-neural-networks-ff90f94358ec?source=collection_archive---------8-----------------------

使用 python 对说话人和说话人性别进行神经网络分类

Si-Gal/Getty Images 在 searchmobilecomputing 拍摄的照片

想象一个正在开会的会议室。有几个人,他们都轮流发言。我们想记下他们所说的话。有一些工具可以将语音转换为文本(我们大多数人的手机上都有这个功能,但我们甚至不知道它),但我们可以训练一个模型来学习语音,并通过听他们的声音来准确预测谁在说话吗?我们能预测他们的性别吗?

我们将通过使用带有神经网络的机器学习来解决这些问题。

项目概述

第一步是学习如何处理音频数据和建立声音分类模型。我发现一个很棒的比赛叫做城市声音分类这里 。问题是对 10 种不同的城市声音进行分类,如儿童玩耍、街头音乐、汽车引擎声等。我做了很多研究来了解如何解决这个问题,以及很多人是如何解决这个问题的。我主要关注两种方法。第一种方法是使用 python 的 librosa 库从音频剪辑中提取数字特征,并使用这些特征来训练神经网络模型(NN),第二种方法是将音频剪辑转换为图片,并使用这些图像来训练卷积神经网络模型(CNN)。

我在神经网络(93%的测试数据)和 CNN (92%的测试数据)上得到了很好的结果。我通过加入预测的概率将这两个模型结合在一个投票分类器中,当同时使用神经网络和 CNN 时,获得了 95%的准确率。

现在我可以继续前进,用我学到的知识来解决说话者和说话者的性别分类问题。

我用神经网络模型对 115 个说话人进行分类,得到了 99.8%的准确率。因为神经网络模型的高精度(几乎完美),我不再做 CNN 了。

我使用神经网络模型来预测性别,并在对该模型之前听过的发言者的性别进行分类时获得了 99.8%的准确率。我从扬声器中获得了模型从未听过的新数据,并获得了 95%的准确率。

我还使用了 CNN 模型来预测性别,并获得了 97.7%的准确率(相比之下,NN 模型的准确率为 99.8%)。我对从未听过的扬声器有 95%的准确率。

现在让我们更深入地了解每个不同的项目。

城市声音挑战

前馈神经网络

我从比赛的网站上找到了数据的链接。他们在谷歌硬盘里这里。我只使用训练数据,因为我想测试标签数据,看看我的模型有多好。来自源的测试数据是未标记的,并且仅用于为竞赛提交的预测。

该数据包含来自 10 个不同类别的 5435 个标记声音。这些课程是警笛、街头音乐、钻孔、发动机空转、空调、汽车喇叭、狗叫、钻孔、枪击和手提钻。大多数班级是*衡的,但是有两个班级代表性很低。大多数代表 11%的数据,但一个只代表 5%,一个只代表 4%。我没有*衡这些类,因为我把用有些不*衡的类构建一个好的模型当作一个很好的挑战。

Librosa 是一个很棒的 python 库,可以用来处理音频文件,也是大多数人在音频分类问题中使用的库。我用 librosa 库提取特征。在做了一些研究后,我从 librosa 信息这里发现了一些特征。

我将训练数据附带的 csv 文件加载到一个数据帧中,该数据帧包含所有音频文件的名称及其对应的标签。我通过一个函数提取了这些特征,这个函数遍历数据帧的每一行,通过读取文件的路径来访问计算机中的文件。我使用了梅尔频率倒谱系数(MFCCs)、色谱图、梅尔标度谱图、光谱对比度和音调质心特征(tonnetz)。我得到了一个包含 193 个特征及其各自标签的数组。我将它们设置为我的 X 和 y,并将其分为训练、验证和测试数据。我检查了是否保持了与总数据相同的类比例,并对数据进行了缩放。我选择 3435 个音频作为我的训练数据,1000 个音频作为我的验证数据,1000 个音频作为我的测试数据。

我使用 relu 和 softmax 为 10 个输出建立了一个具有两个隐藏层的密集层的前馈神经网络。然后,我使用 adam 优化器和损失分类交叉熵来编译模型。我还搜索了神经元数量和各层脱落比例的最佳参数,并提出了一个不错的模型,该模型预测了我的测试中从未见过(或听过)的数据,准确率为 93%。

卷积神经网络

使用与上面相同的数据和步骤,我为音频文件生成了数据帧。现在我需要使用一个函数来为每个音频文件创建图像。和以前一样,我的函数遍历了 dataframe 的每一行,并使用 librosa 创建了一个图像,并将其保存到本地文件夹中。以下是关于如何从 librosa 创建图像的信息,以及您可以创建的不同类型的图像: Specshow from librosa

创建图像后,我再次分割我的数据介绍训练,验证和测试(我使用了与之前神经网络相同的比例)。我检查了我在类上有相同的*衡,并把 dataframe 文件名从。wav to。jpg,这样我就可以使用相同的数据帧来访问本地文件夹中的图像。

Keras 提供了一些关于如何从本地文件加载和预处理图像的精彩信息,特别是。我用的是 flow_from_dataframe。这里的文档是。这样,我将我的训练、验证和测试数据加载到生成器中,并准备好构建模型。

我用一个 Conv2D 和 MaxPooling2D 输入和五个隐藏层构建了一个卷积神经网络:三个 Conv2D 和它们各自的 MaxPooling2D,然后是 flatten 和两个密集层(都用 relu)。最后,我用 softmax 激活了 10 个类的密集输出层。我再次使用 adam 优化器和分类交叉熵来编译模型。我没有使用 gridsearch,因为它花费的时间太长(大约两个小时),所以我训练了 250 个纪元。我从未见过的测试数据有 92%的准确率。

投票分类器

我决定,既然我有两个做同样事情的模型,我不妨一起使用它们。我从我的神经网络和 CNN 得到了每一类的预测概率,把它们加在一起,得到了每一类的最大值。换句话说,如果我的神经网络 65%确定一个声音是一些孩子在玩,而我的 CNN 95%确定是街头音乐,那么街头音乐的概率会更高,因此我的预测是街头音乐。我这样做了,在从未见过的测试数据上,我的预测准确率达到了 95%(记得我对神经网络的准确率是 93%,对 CNN 的准确率是 92%)。我发现这是一种将不同的模型结合起来进行更好预测的惊人方法。

说话人分类器

现在我有了解决我最初的问题的工具,这个问题就是对说话者进行分类。第一个问题是获得好的音频数据。经过大量的研究,我发现了一个绝对惊人的数据库,里面有有声读物录音的音频剪辑。该数据集包含许多千兆字节的干净数据。flac”文件,非常适合 MAC 电脑。我使用了 train-clean-100.tar.gz[6.3G]的一个子集。这些数据按照演讲者的 id、书籍、章节和文件编号很好地组织在文件夹中。我也得了一个”。txt”文件中的信息,让你知道他们的性别,他们的录音长度,甚至他们的名字。我使用的子集有 13000 个语音剪辑,通常从 12 秒到 18 秒不等。

我尝试了前馈神经网络,因为它速度更快,给了我更好的城市声音挑战问题的准确性。我按照以前相同的步骤,只是现在处理更多的数据(大约 13k 而不是 5k)和更长的语音剪辑(*均大约 14 秒而不是 4 秒)。提取特性需要大约 3 个小时,但只需要做一次,我将该数组作为 numpy 数组保存在本地文件夹中,并在需要使用它或更改任何内容时加载它。

我使用了 115 个不同的演讲者,包括男性和女性,其中每个演讲者的最小语音剪辑数为 56,最大为 166(随机选择)。每个扬声器的剪辑数量的标准偏差约为 16。我认为他们是*衡的阶级。

我将数据放入一个神经网络模型中,该模型与我在城市声音挑战赛中的 gridsearched 模型具有相同的配置,并获得了高达 99.8%的准确率。我预测了 1312 个音频样本,并将它们分类到 115 个扬声器中,只有两个音频样本是错误的。这个模型只花了 20 秒来拟合,它几乎是完美的,所以我决定没有必要做 CNN 的模型。

说话者性别分类器

使用与说话者分类器相同的数据量,我通过将声音片段放入两个独立的文件夹中,按男性和女性对它们进行标记。我从每个文件夹中生成数据帧,然后将它们连接(放在一起的奇特术语)成一个数据帧。我打乱了数据,重新设置了索引,得到了一个全新的数据框架,包含了所有标注了性别数据的文件。

我使用了与城市声音挑战 NN 模型相同的分割和提取相同的特征。我使用了来自我的前馈神经网络的相同配置,同样,它只花了 20 秒来拟合模型。我的测试数据准确率达到了 99.8%。尽管我的模型从未看过(或听过)我的测试数据,但它已经用包含相同人说话的数据进行了训练,这就是为什么我的模型几乎是完美的。我教模型哪个说话者是男性和女性,当我预测新的语音剪辑时,它几乎是完美的,因为它已经知道这些人了。考虑到这一点,我收集了更多的数据。我从新人那里收集了 100 个新的声音片段,这些人是我的模型从未听过的。我用同样的方法清理了它,并对它进行了预测。我从 100 个从未听过的说话者那里获得了 97%的新测试数据。

我有一个很好的模型,但它不像说话人分类器的模型那样几乎完美,所以我决定做一个 CNN,看看我是否可以改善我的结果。

就像在城市声音分类器问题中一样,我从我的数据中创建了图像,并将其标记和放置到本地文件夹中。我创建了数据帧,并使用我的函数在不同的文件夹中创建图像,以便与 Keras 生成器一起使用。因为我处理的是语音,所以我降低了音频剪辑图像的频率,只包括 50 赫兹到 280 赫兹的频率。“一个典型的成年男性的浊音语音将具有 85 至 180 Hz 的基频,一个典型的成年女性的浊音语音将具有 165 至 255 Hz 的基频”(来自维基百科 ).) 。我再次使用与之前相同的 CNN 配置,并拟合模型(花了几个小时)。我的测试数据有 97.7%的准确率。请记住,我用简单的密集前馈神经网络获得了 99.8%的测试数据准确性,因此这有点令人失望。我又一次对 100 个从未听过的新说话者进行了预测,准确率达到了 95%。

我可以将这两个模型与投票分类器结合起来,获得更好的准确性,或者用更多的数据训练模型,使它们更准确,但我有时间限制来展示我的项目,我想实现这个模型,以便能够将其用于交互式演示,而 CNN 模型的过程需要太长时间。创建图像和拟合模型需要很长时间,所以我使用了准确率为 97%的神经网络,因为它既快又准确。

未来探索:

我想在我的 CNN 上搜索最佳参数,看看我是否能获得与我的密集分层神经网络相同或更好的准确性。这也可以通过上传数据和使用 Google Colab 来完成,因为他们提供免费的 GPU 使用,使神经网络运行得更快。如果你的笔记本电脑需要 4 个小时来适应一个神经网络,谷歌 Colab 可能在 15 分钟内完成。如果 Google Colab 听起来很有趣,我推荐阅读我的朋友兼同事布兰达·哈利关于 Google Colab 的 这篇 博文。

我还想用 librosa 从音频文件中提供的所有不同类型的图像来尝试 CNN 模型,看看哪种图像给出了更好的预测。

我想添加更多的训练数据,看看我是否可以在说话人的性别分类器中获得更好的结果。我不得不手工标记数据,这非常耗时。有了更多的数据,我大概可以有更精确的模型。

我还想拟合一个递归神经网络,看看它有多准确,因为它们擅长处理时间序列数据,语音剪辑基本上是时间序列。

密码

jupyter 笔记本中整个项目的代码可以在我的 github 上获得。

来源:

图片:

Si-Gal/Getty Images,searchmobilecomputing.techtarget.com

数据集:

http://www.openslr.org/12/

https://drive . Google . com/drive/folders/0 by 0 Bai 7 hobafuhvxd 1 jcn 3 MWT eu。

文章和有用的链接:

[1]大卫·卡斯帕,亚历山大·贝利,帕特里克·富勒, Librosa:一个 Python 音频库(2019)

[2] Rami S. Alkhawaldeh,DGR:使用一维常规神经网络的人类语音性别识别 (2019)

[3]科里·贝克尔,使用机器学习识别声音的性别 (2016)

[4] 乔纳森·巴拉班深度学习技巧和窍门 (2018)

[5] Youness Mansar音频分类:一种卷积神经网络方法 (2018)

[6] Faizan Shaik h,使用深度学习开始音频数据分析(附案例研究) (2017)

[7] Mike Smales利用深度学习进行声音分类,(2019)

[8] Aaqib Saeed城市声音分类,第 1 部分,(2016)

[9] Marc Palet Gual,使用运行在 FPGA 上的深度神经网络进行声音性别识别,【2016】

[10] Kamil Ciemniewski在 TensorFlow ,【2019】中使用扩展卷积和 CTC 从零开始进行语音识别

[11] Admond Lee如何用 Python 构建语音识别机器人 (2019)

[12] 阿德里安·易捷·许利用卷积神经网络和 Keras 进行城市声音分类:理论与实现,(2019)

[13]塞纳特·阿达帕,K .阿格尔自由声音音频标记 (2018)

【14】歌词特征提取

【15】Librosa 显示 Specshow

[16] Keras 图像预处理

[17] Keras 序贯模型方法

用 Python 进行语音分类

原文:https://towardsdatascience.com/voice-classification-with-python-4bec6856d06a?source=collection_archive---------16-----------------------

我们需要多少训练数据来识别说话者?

图片来自 Adobe Stock166291199 由 metamorworks

在我之前的帖子 用神经网络进行声音分类 中,我解释了如何让 python 只根据声音来识别不同的说话者。对于我的数据,我使用了 115 个不同的扬声器,每个扬声器有 13000 多个 15 秒左右的语音剪辑。也就是说,每个发言人大约需要 28 分钟。我的前馈神经网络给了我 99.8%的测试数据准确率。从逻辑上讲,下一步是弄清楚我们是否真的需要那么多数据来获得一个好的结果。

这个项目的想法来自于尝试用一个可以区分声音并记录谁说了什么的应用程序来转录会议。对于这种用法,115 人可能是多余的。会议通常不会有那么多人发言。我觉得 10 是个更现实的数字。然而,我想更广泛一些,以便捕捉在线会议动态,您可能与一组选定的人进行电话会议,然后与不同的人进行单独的电话会议。如果你想使用相同的转录应用程序,将所有这些声音都放在你的数据集中会很好。考虑到这些因素,我认为 30 人足够了。

就训练数据而言,30 分钟的语音剪辑太多了。例如,当你设置 Siri 学习你的声音时,iPhone 只要求你说五个短语。我的手机已经被其他人语音激活,因此少量数据不是最佳的,但五个短语听起来像是更现实的训练数据量。没有人愿意花 30 分钟来设置一个应用程序。

我开始减少 115 个扬声器的训练数据量,并验证我的神经网络每次运行的准确性。

30 分钟的训练数据是一个巨大的杀伤。当减少训练数据量时,在 2500 个语音剪辑(大约是 5 分钟的训练数据)时,我们仍然获得了 99%的测试数据准确率。之后准确度逐渐下降。正如我们在上面的图表中看到的,在大约 1000 个语音剪辑(大约 2 分钟的训练数据)的情况下,我们仍然获得了 94%的测试数据准确率。这很好。

然而,我真的不在乎有那么多人。因此,我从头开始重做了整个项目。这次我只收集了 30 个人的数据。结果很有收获。

我对每个神经网络运行了三次,并记录了*均准确度(相当于进行了三重交叉验证),以确保我的准确度分数是可以接受的。当只有 30 个说话者时,我对说话者的声音使用了 60 秒的训练数据,并在测试数据上获得了 100%的准确性。我每人测试了两个剪辑,因此测试了 60 个不同的剪辑。我运行神经网络的三次预测都是正确的。然后我把数据压缩到 30 秒,得到了 93%的准确率。只有 15 秒的训练数据,我得到了 85%的准确率。我发现非常有趣的是,当你改变训练数据或语音剪辑的秒数时,准确率会迅速变化;但是仍然取得了很好的效果。

总之,声音分类是非常有效和可靠的。我们通常在电影中看到的绝密堡垒最著名的密码输入是语音识别、指纹和视网膜扫描。我现在明白为什么语音认证这么可靠了。对于我的下一个项目,我可能会尝试用卷积神经网络建立一个视网膜扫描或虹膜识别分类器,看看这些方法有多准确。

密码

我在 Jupyter 笔记本上的项目代码可以在我的 github 上找到。

消息来源

尤尔根·阿里亚斯,用神经网络进行声音分类(2020)

使用 Chrome 网络语音 API 将语音转换为文本

原文:https://towardsdatascience.com/voice-to-text-with-chrome-web-speech-api-d98462cb0849?source=collection_archive---------31-----------------------

使用谷歌 Chrome 网络语音 API,写邮件的速度比其他人快 10 倍

来源:bensonruan.com

自 2013 年谷歌 Chrome 发布第 25 版以来,对网络语音 API 的支持为网络应用程序将语音转换为文本开辟了一个全新的机会世界。

通过下面的演示,你可以将谷歌 Chrome 用作语音识别应用程序,在不触摸键盘的情况下输入长文档、电子邮件和学校论文。

点击下面的链接亲自尝试一下:

[## 使用 Chrome Web Speech API 的语音转文本- Benson 技术

您可以在下面的链接中下载上面演示的完整代码:您可能会想“功能就像…

bensonruan.com](https://bensonruan.com/voice-to-text-with-chrome-web-speech-api/)

你可能会想“像语音转文本这样的功能实现起来相当复杂。”嗯,如果你从头开始训练语音识别模型,你就对了。但感谢谷歌,他们已经为你做了艰苦的工作,通过利用 Chrome 内置的网络语音 API,你可以将你的 Chrome 浏览器变成语音到文本的应用程序。让我们在下面探索更多的细节。

履行

#步骤 1:检查浏览器支持

来源:caniuse.com

正如你在上面看到的,Chrome 是支持语音到文本 API 的主要浏览器,使用谷歌的语音识别引擎。

你可以通过检查webkitSpeechRecognition对象是否存在来判断浏览器是否支持 Web Speech API。

if (**'webkitSpeechRecognition'** in window) {
  // speech recognition API supported
} else {
  // speech recognition API not supported
}

#步骤 2:创建语音识别对象

下一步是创建一个新的语音识别对象。

recognition = new **webkitSpeechRecognition**();

#步骤 3:注册事件处理程序

语音识别对象有许多属性、方法和事件处理程序。完整名单请参考https://w3c.github.io/speech-api/#speechreco-section

interface SpeechRecognition : EventTarget {
    // recognition parameters
    attribute SpeechGrammarList grammars;
    attribute DOMString lang;
    attribute boolean continuous;
    attribute boolean interimResults;
    attribute unsigned long maxAlternatives;

    // methods to drive the speech interaction
    void start();
    void stop();
    void abort();

    // event methods
    **attribute EventHandler onresult;**
    attribute EventHandler onerror;
    attribute EventHandler onstart;
    attribute EventHandler onend;
};

下面我将强调这个应用程序的重要部分。

recognition.continuous = true;recognition.interimResults = true;

recognition.continuous设置为真时,识别引擎将把你讲话的每一部分都视为一个中间结果。当recognition.interimResults设置为真时,应该返回中间结果。

**recognition.onresult** = function(event) {
  var interim_transcript = '';
  for (var i = event.resultIndex; i < event.results.length; ++i) {
    **if (event.results[i].isFinal) {
      final_transcript += event.results[i][0].transcript;**
    } else {
      **interim_transcript += event.results[i][0].transcript;**
    }
  }
  final_transcript = capitalize(final_transcript);
  final_span.innerHTML = linebreak(final_transcript);
  interim_span.innerHTML = linebreak(interim_transcript);
};

让我们在下面探索一下这个recognition.onresult事件,以便更好地理解会返回什么。

recognition.onresult事件处理程序返回一个包含以下字段的SpeechRecognitionEvent:

  • event.results[i]–包含识别结果对象的数组。每个数组元素对应于 i 识别台上的一个已识别单词。
  • event.resultIndex–当前识别结果指数。
  • event.results[i][j]–已识别单词的第 j 个备选项。第一个元素是最有可能识别的单词。
  • event.results[i].isFinal–显示该结果是最终结果还是临时结果的布尔值。
  • event.results[i][ j].transcript–单词的文本表示。
  • event.results[i][j].confidence–给定单词正确解码的概率(值从 0 到 1)。

#第四步:语言选择

Chrome 语音识别支持多种语言,如果您的用户说的不是英语,您可以通过指定语言参数recognition.lang来改善他们的结果

recognition.lang = select_dialect.value;

#第五步:开始识别

通过调用recognition.start(),它激活语音识别器。一旦它开始捕获音频,它就调用onstart事件处理程序,然后对于每一组新的结果,它调用onresult事件处理程序。

$("#start_button").click(function () {
  recognition.lang = select_dialect.value;
  **recognition.start();**
});

就是这样!剩下的代码只是为了增强用户体验。它向用户显示一些信息,并交换麦克风按钮上的 GIF 图像。

GitHub 知识库

您可以通过下面的链接下载上述演示的完整代码:

[## Benson Ruan/Chrome-Web-Speech-API

使用 Google Chrome Web Speech API 的语音转文本 https://Benson Ruan . com/voice-to-Text-with-Chrome-Web-Speech-API/Clone…

github.com](https://github.com/bensonruan/Chrome-Web-Speech-API)

结论

Sebastian Scholz (Nuki) 在 Unsplash 上拍摄的照片

Web 语音 API 对于语音控制、对话脚本、数据输入非常有用。但目前在各大浏览器中,只有 Chrome 在桌面和安卓手机上支持。很高兴看到将来其他现代浏览器也能支持这个伟大的特性。

感谢您的阅读。如果你喜欢这篇文章,请在脸书或推特上分享。如果你有任何问题,请在评论中告诉我。在 GitHubLinkedin 上关注我。

为数据工程发声,无名英雄

原文:https://towardsdatascience.com/voicing-for-data-engineering-the-unsung-hero-b91b6ef39dcd?source=collection_archive---------44-----------------------

我如何改变策略来帮助企业启动其数据基础设施和报告渠道

来源 : Intellij Scala 插件博客——大数据的数据工程和开发工具,2019 年 12 月,作者 Jeff Zhang

每当“数据科学”或“深度学习”出现在对话中,房间里立即充满了智慧的光环和人们的好奇心,他们想知道你是如何通过使用现代水晶球——一种预测模型——让企业赚了一百万美元。如果您是数据科学家,您不会让他们厌烦花费大量的时间来处理数据,以确保它是干净的、语义正确的,并且格式适合您使用的任何模型。你会跳到最后 20%的工作,开始解释让房间里的人敬畏(和困惑)的数学。

图片来自 Sanchez,Cruz :让我们听听他的百万美元预测模型

哦,等等,你有没有提到有一个数据工程团队会给你预处理过的数据,你可以相对容易地提取出来?(我的意思是,看看他们疯狂的计划 ETL 工作的队列…我说的对吗?)

不,关键是你已经为公司赚了几百万美元。

好吧,虽然我确信你最有可能是一个体面的数据科学家,因为你有一个由公司决策者选择的模型来继续实施,但我更确信你有一个强大的数据工程团队,能够在第一时间为你提供稳定的各种数据。哦,他们的工作也没有完成。现在,他们有一个全新的项目正在进行中,因为他们和软件工程师需要通过将您的模型与当前系统集成(或为其提供全新的服务)来使其为生产做好准备。

我在执行数据工程任务时没有意识到

之前我有一篇文章概述了如何充分利用数据分析证书计划。当我完成一个顶点项目时,我遇到的第一个大障碍是导入数据。我做了额外的学习,以了解如何将流行类型的*面文件读入 pandas Dataframe,甚至验证 ping 数据的应用程序接口(API)。花很多时间熟悉数据意味着用映射到正确值的不正确值的字典清理数据,根据可视化或报告格式塑造窄或宽的数据,并调整可视化,以便读者可以理解而不是猜测其中的含义。与我的一些更痴迷于开发预测模型的同学不同,我着迷于为获得用于质量分析的正确数据而投入的策略。

项目结束后,我受雇的两家公司都有同样的动机。他们希望改进他们的业务流程,以便能够利用高质量的数据,并获得有意义的分析结果。他们(以及任何企业)总是对减少管理/手动工作、领先竞争对手一步以及获取秘密以更快提高盈利能力感兴趣。然而,当我开始工作时,我真正的问题是,业务流程是否存在,如果存在,数字化转型的阻力有多大。

来源:业务流程建模工作流示意图. svg

也许“业务流程”这个术语对你和对我来说听起来一样模糊。如果我试图根据我的经验来定义它,我相信它是这样的:

数字化转换的业务流程将有一个定义和标准化的协议,详细说明数据如何产生(数据收集)、转换(数据管道或通常称为 ETL )和消费(数据分析&数据可视化)。

阻碍业务流程数字化的瓶颈通常是在数据收集或数据管道阶段。例如(根据真实故事修改),如果不同的团队都有报告成本的电子表格的小版本,对您来说,集中他们报告成本的地方是否更有意义,这样您只需要从一个地方收集数据?假设你是一个团队的明星,并且设法集中成本数据,你开始注意到一个团队以与另一个团队完全不同的格式报告成本。这严重影响了您的仪表板对成本报告的可视化。现在,您需要检查将数据发送到仪表板的数据管道,以使这种差异正常化。

大多数企业都有大数据的前身——混乱数据

图片来自《驯服和教育马的艺术》第 184 页(1884 年)

我被聘为分析师,但我患有严重的冒名顶替综合症,因为我认为我没有做足够多的“冷静分析”来推动商业决策(这也是我围绕“数据工程师”这一职位做更多研究的时候,罗伯特·张带着他的三部曲,/P2/大结局)。不要管推荐系统背后的尖端机器学习模型,有时甚至很难将没有意义的总体字段放在一起(嗯,请求者可能不知道这一点)或找到数据源。

幸运的是,在后一家公司,他们对转变业务流程的阻力要小得多,所以我不用再去处理成堆的*面文件了。尽管如此,新的挑战开始涌现。我能够通过托管在 AWS Lambda 上的 ETL 脚本来管理 MySQL 数据库中的集中式任务关键型运营数据,而不是*面文件。整个运营使用的许多系统没有集成,所以 MySQL 数据库是桥接数据的旁路。有了这个集中的数据库,我们就可以实现“数据驱动”的要求。对从这个 MySQL 数据库中提取数据的兴趣从一些分析师发展到管理者,他们的决策与数据库中的历史数据或主数据相关。

如果你是一个有经验的工程师,你现在会有很多问题冒出来。首先,这个数据库是 OLTP 还是 OLAP ?连接数量的增长是否会带来任何性能问题?为什么它不能作为 OLAP 并集成系统的后端 OLTP(他们每个人都有一个,对吗?)反而?我们如何保证数据的一致性?

都是非常合理的问题。这是我真正对《气流》作者马克西姆·博奇明(Maxime Beauchemin)写的 数据工程师的崛起 中的一段话产生共鸣的时候。

现代数据仓库是一个比过去更加公开的机构,欢迎数据科学家、分析师和软件工程师参与它的构建和操作。数据对于公司的活动来说太过集中,以至于没有限制哪些角色可以管理它的流动。虽然这允许扩展以匹配组织的数据需求,但它通常会导致基础架构更加混乱、变形和不完善。

您使用分配给您的或未被阻止的工作,不可控因素将影响您设计/管理数据生态系统的方式。这家公司大约两年前刚刚成立,我是在它扩张阶段的早期被聘用的。当时,发生了太多事情—公司合并、人员流动、新系统上线、数据集成等。虽然我很兴奋,在某种程度上,这意味着我们可以用新的氛围定义新的业务流程,但这也可能意味着一些现有的伟大业务流程可能会在被记录下来之前丢失,或者如果它不适合公司的路线图。

把所有的东西放在一起

退一步说,您会注意到大多数企业在利用大数据工具的力量之前,通常会经历数据管道的演变。大数据、机器学习和人工智能等流行语为分析赢得了大量公众关注。从尖端技术会议到一切如常的办公室,经常缺少的是应用适当的技术来优化业务的当前状态。

作者图片

最后,理解和重新设计业务的整个数据基础设施,对于许多利益相关者来说,将您置于一个极其宝贵的位置。决策者必须向你咨询一份需要从头开始创建的报告。软件工程师将不得不询问您在新部署时对其他数据服务的连锁反应。分析师必须与您一起就如何(多长时间)捕获数据进行头脑风暴,以便他们的分析能够支持业务需求。加分?如果有一天你改变了成为一名数据工程师的想法,你将会对数据和它们的用例了如指掌,以至于你可以相对容易地转换到上面描述的任何角色。

波动交易 101

原文:https://towardsdatascience.com/volatility-trading-101-6f934cce5be3?source=collection_archive---------24-----------------------

delta 对冲的直观指南

来自 Unsplash 的照片

某大客户欲购买100,000 份 AAPL 看涨期权,参数如下:

  • 成交价格: 350
  • 现货价格: 320
  • 隐含波动率: 30%
  • 无风险利率: 8%
  • 到期时间: 1 年

你决定咨询你的团队。

你的团队有研究表明,已实现的波动率将小于期权隐含的波动率,你的目的是从这种价差中获利。然而,他们对 AAPL 的发展方向持有不同的观点。你的任务是构建一个投资组合,以利用潜在的波动性传播,同时减轻方向性风险。

让我们来看看如何实现这一点…

布莱克-斯科尔斯方程

1973 年,费希尔·布莱克、迈伦·斯克尔斯和罗伯特·默顿在发表于的政治经济学杂志的论文 【期权定价和公司负债 中开发了臭名昭著的布莱克-斯科尔斯期权定价模型。如果你想理解整个推导过程,你可以看推导布莱克-斯科尔斯模型。这个等式有效地给定了一个执行价格、到期日、波动性和适当的无风险利率的期权定价。

看涨期权和看跌期权定价的布莱克-斯科尔斯方程

  • N : 累积正态分布函数
  • K :成交价格
  • T :截止时间
  • r :无风险利率
  • S :标的资产的现货价格
  • σ :波动性

本质上,这个等式是一个多变量函数,其中输入 K、T、r、S 和σ产生理论期权价格。因此,它可以对每个变量进行部分微分,以找出每个变量的变化对期权价格的影响,保持所有其他变量不变。

Delta 对冲

Delta 是部分区分基础资产价格的结果。以下是描述 delta 的函数的推导…

Black-Scholes 方程相对于基础资产的偏导数导致 delta

如果期权是看跌期权,那么 delta 是负数或零:[-1,0],如果期权是看涨期权,delta 是正数或零:[0,1]。虽然δ的函数是根据累积正态分布函数,但有一个简单的解释。

当基础资产的现货价格增加/减少 1 美元时,保持所有其他变量不变,期权的价值将增加/减少δ。值得注意的是,期权的结算与股票相同,这些由基础资产的增加/减少产生的利润/损失在头寸清算之前是未实现的

由于 delta 告诉我们期权的价值如何随着基础资产价值的变化而变化,我们可以采取抵消头寸来创建一个**风险中性delta 中性投资组合。为了构建这个投资组合,我们基于我们的头寸和 delta 的数量,相对于我们的期权头寸采取一个头寸。

让我们考虑一个例子:

  • 持仓:多头 10 万看涨期权,delta = .7

要构建 delta 中性投资组合,做空(100,000)*(.7) = 70,000 股相关资产。

案例 1:

基础资产增加 1 美元

期权头寸价值减少(100,000)(. 7)= 70,000 美元*

基础资产头寸价值减少(70,000)(-1)=-70,000 美元*

投资组合价值的净变化= 0 美元

案例二:

基础资产减少 1 美元

期权头寸减少(100,000)(. 7)=-70,000 美元*

股票头寸的价值增加(70,000)(1)= 70,000 美元*

投资组合价值的净变化= 0 美元

虽然投资组合保持 delta 中性,但标的资产的方向性变动不会改变投资组合的整体价值。这使我们能够利用我们的研究,即隐含波动率将大于实际波动率,而不用担心基础资产价格最终会在哪里。

在上面例子的上下文中,我们有了寻找期权 delta 所需的所有参数。我冒昧地用 Python 构建了看涨和看跌期权的类,以帮助定价和计算 delta…

使用示例中给定的参数创建了 EuropeanCall 类的实例后,我们得到了一个……

*.5469501144776616*

要构建风险中性的投资组合…

  • 持仓:做空 10 万 1 年期 350 AAPL 看涨期权,delta = .54695

构建 delta 中性投资组合,做多(100,000)*(.54695) = 54,695 股标的资产。

案例 1:

AAPL 价格 320 →321

期权头寸价值减少(100,000)(. 54695)=-54,695 美元*

股票头寸的价值增加了(54,695)(321–320)= 54,695 美元*

投资组合价值的净变化= 0 美元

案例二:

AAPL 价格 320 →319

期权头寸增加(100,000)(. 54695)= 54,695 美元*

股票头寸价值减少(54,695)(319–320)=-54,695 美元*

投资组合价值的净变化= 0 美元

我们有效地构建了一个投资组合,以利用潜在的高估的波动性,同时减轻方向风险。

重新对冲

这是风险中性投资组合的一个主要问题,也是为什么我在上面指定了 临时 。基础资产中的抵消头寸基于非线性函数的线性*似。这意味着随着基础资产的价格进一步偏离我们的初始对冲,当前 delta 和初始 delta 之间的误差会产生方向性风险。为了继续维持风险中性的投资组合,股票头寸必须通过购买或出售股票定期更新,以确保当前 delta 的正确股票数量保留在风险中性头寸的投资组合中。请记住,这一过程不是免费的,当购买/出售股票时,你将受到交易成本的影响,同时(可能)实现一个开放的损益。

想要更多信息?

我制作了一个视频来解释这个例子中的波动性交易:

一如既往,这个项目的所有代码都可以在我的 GitHub 上找到。

基于 Vox2Vox 的体积医学图像分割

原文:https://towardsdatascience.com/volumetric-medical-image-segmentation-with-vox2vox-f5350ed2094f?source=collection_archive---------37-----------------------

如何实现用于 CT/ MRI 分割的 3D 体积生成对抗网络

如果你熟悉生成对抗网络(GANs)及其流行变体,Pix2Pix 这个术语应该一点也不陌生。Pix2Pix 是一种执行图像到图像转换的条件 GAN (cGAN)。在医学领域,它们通常用于执行模态翻译,在某些情况下用于器官分割。

“我脑海中的体素”——唐·巴克斯

Pix2Pix,基础知识

与大多数 gan 类似,Pix2Pix 由单个发生器网络和单个鉴别器网络组成。生成器网络只不过是一个 U-Net,这是一种最初提出用于执行生物医学图像分割的深度卷积神经网络。U-Net 具有以下架构:

弗赖堡大学计算机科学系

U-Net 包含三个主要组件:编码器、瓶颈和解码器。Pix2Pix 的生成器 U-Net 的技术细节包括输入/输出通道的数量、内核大小、步长和填充可以在其原始论文中找到。简而言之,编码器提供了一种压缩路径,该路径卷积并减少了给定 2D 图像的维度。瓶颈块包含具有跳跃连接的卷积块,并且最终解码器提供扩展路径来升级编码表示。共享相同大小的编码器和解码器层沿着它们的通道连接。如果你有兴趣了解更多关于 U-Net 以及它如何执行图像分割的信息, Heet Sankesara 有一篇关于它的很棒的文章

Pix2Pix 的鉴别器只不过是一个标准的卷积网络,它“鉴别”给定图像是真实的(原始训练数据)还是伪造的(由 U-Net 生成器生成)。Pix2Pix 的训练目标是生成图像和真实图像之间的 L₂/ MSE 损失(对抗损失)和 L₁损失(重建损失)的简单最小最大公式。

Pix2Pix 最早的应用之一就是从图纸生成猫的图片(给各位酷猫和小猫)。然而,它还被扩展到医学成像领域,以执行磁共振(MR)、正电子发射断层扫描(PET)和计算机断层扫描(CT)图像之间的畴转移。

(左)Christopher Hesse 的 Pix2Pix demo(右)杨等的 MRI 跨通道翻译。

对 Pix2Pix 的主要批评之一是它不能在 3D 级别上执行图像到图像的转换。这对许多医学人工智能研究人员来说是一个巨大的障碍,因为医学图像通常是自然的体积。随着图形处理单元(GPU)和深度神经网络设计的进步,研究人员*年来取得了巨大的突破,使他们能够执行体积分割。V-网(U-网的简单 3D 扩展)和密集 V-网是执行 3D 单/多器官分割的常见架构。来自瑞典林雪*大学的 M. Cirillo、D. Abramian 和 A. Eklund 提出了 Pix2Pix 的一种变体,其中他们调用 Vox2Vox 网络以对抗的方式执行分割。这里是链接到论文。

因为在这篇博文发表时,目前还没有 Vox2Vox 的开源 PyTorch 实现,所以我决定尝试一下。全网实现可以在我的 github repo 找到。还链接到 PapersWithCode 以获得更多曝光和反馈。请随意叉,修改我的代码,甚至提交错误修复,只要你给我信用。

实现 Vox2Vox

对于这个项目,您将需要以下依赖关系:

  • Python 3.7
  • PyTorch>=0.4.0
  • 火炬视觉
  • Matplotlib
  • 笨笨,笨笨
  • 枕头
  • sci kit-图像
  • Pyvista
  • h5py

克隆存储库后,您可以通过运行以下命令来安装所有需要的库:

pip **install** -r **requirements**.**txt**

U-Net 生成器的实现可能有点棘手,主要是因为论文的作者没有指定卷积块是如何连接的。我花了好几个小时才得到正确的体积尺寸。

“具有体积卷积和跳跃连接瓶颈块的 3D U-Net 生成器”

然而,以下是体积 U 网生成器的三个主要构建模块。每个块包含一个卷积层、一个归一化层和一个激活层。三个模块:编码器模块、瓶颈模块和解码器模块实现如下:

瓶颈模块和解码器模块都使用级联。然而,瓶颈模块的连接与解码器模块略有不同。如该论文所述,典型瓶颈块的输入是其前一个块的输入和输出的串联。尽管输入和输出的连接是恒定的,但是瓶颈块的输出尺寸应该保持恒定(8x8x8x512)。另一方面,解码器块的输出被连接到它们各自的编码器块的输出。

“Vox2Vox 的模型架构”——m . ci rillo、D. Abramian 和 A. Eklund

有了模型架构描述,用我们之前创建的三个基本块来实现 U-Net 生成器就非常简单了:

鉴别器的实现非常简单,因为它包含与发生器相同的体积编码器模块。事实上,你可以用任何你想要的鉴别器架构来训练。只要确保你在训练中注意发电机和鉴别器之间的*衡。通过调整初始学习率和设置鉴别器的精度阈值,您可以通过试错法轻松*衡两个网络。3DGAN 的作者在他们最初的 3DGAN 论文中提供了许多关于容量 GAN 的*衡和稳定训练的有用建议。

Vox2Vox 实现的另一个重要部分是它的损失函数。与 Pix2Pix 类似,Vox2Vox 的损失可以分解为对抗性损失(MSE 损失)和重构损失(广义骰子损失)。在 PyTorch 中,标准类似于损失函数。因此, criterion_GAN 表示对抗损失,而 criterion_voxelwise 表示重建损失。发电机损耗的计算包含一个可调参数λ,它控制对抗损耗和重建损耗之间的比率。以下是发生器和鉴别器训练期间损失函数的实现:

广义骰子损失

在医学图像分割中,一种常用的损失函数是广义 dice 损失。索伦森 Dice 系数通常用于评估两个样本之间的相似性,其公式如下:

TP 代表真阳性,FP 代表假阳性,FN 代表假阴性。骰子系数通常在 0 到 1 之间,1 代表两个给定样本之间的完美匹配。广义骰子损失是骰子分数的简单修改,以提供深度学习训练期间最小化的损失函数。下面是我的 PyTorch 实现的广义骰子损失:

虽然我有可能一行一行地检查我的代码的其余部分,但是我将把它留给您来通读和理解我的实现。通读原文肯定是有帮助的。我对创建 Vox2Vox 的作者充满敬意,所以如果你决定自己实现 Vox2Vox,也请给予他们信任。如果你有任何问题,请在下面评论,告诉我你想在我的下一篇博文中看到什么!保持安全,保持好奇:)

AWS 云中的 VPC、子网和路由器

原文:https://towardsdatascience.com/vpc-subnet-and-router-in-aws-cloud-17c8f421af21?source=collection_archive---------39-----------------------

了解如何在 AWS cloud 中设置 VPC 和子网,以及路由器的作用。

指导——在每一步,我都给出了如何执行该步骤的指导,然而,在下面的描述中,我解释了我自己对整个过程的评估,这可能因人而异。(可以的话请指正)

作为一个旁注,如果下面的文章看起来太脱节,只需打开 AWS 控制台,开始动手实践,这将是小菜一碟。

VPC 是一种虚拟私有云,它允许我们创建一个网络逻辑单元,其中的硬件和资源由供应商或服务提供商管理。作为用户,我们负责网络的配置和逻辑设置。

一个 VPC 只能在一个区域内定义,每个 VPC 可以有多个子网。子网用于提供 VPC 内部的粒度。我为这个博客创建了三个子网。每个子网的 IP 地址范围都必须在 its IP 的范围内,并且每个子网的 IP 都不能与其他子网冲突。我们使用 CIDR 块来设置这些 IP 范围。

每个子网可以是公共子网,也可以是私有子网。公共子网可以直接访问互联网,而私有子网不能直接访问互联网。

一旦建立了 VPC,我们就需要创建一个互联网网关来允许 VPC 的流量进出互联网。拥有一个因特网网关并不能使每个子网对因特网公开,而是允许路由表做出决定。

路由表将来自网关的流量转移到 VPC 内部,并在子网之间进行分配。每个 VPC 都有一个连接到每个子网的默认路由表。另一方面,我们可以创建自己的路由表来定义 VPC 内部的流量。因此,我创建了一个单独的路由表,然后将它连接到 IP 为 0.0.0.0/0 的 internet 网关,然后将两个子网关联到这个自制的路由表。这样,我使我的两个子网(三个中的两个)具有公共访问权限,而第三个子网只连接到默认路由表(仍然是私有的)。

需要注意的一点是,每个 VPC 只能有一个互联网网关。当我试图连接另一个网关时,系统不允许我这样做。

正如 AWS 中的其他服务需要一个安全组来定义入站和出站流量一样,VPC 也需要这样做。因此,我提供了 HTTP 入站流量和完整的出站流量。这意味着来自互联网网关的任何 HTTP 请求都将被允许到达网络内部,SSH 也是允许的。但是,每种输出流量都将被允许流向互联网。

网络建立后,出于安全原因,监控任何更改都至关重要。因此,我们必须设置一个日志流来跟踪我们的 VPC 内部的每一个活动,并将其发送到所需的目的地。我们可以将其发送到 s3,然后使用数据进行分析,也可以将其发送到 cloud watch。我已经将我的流日志设置为使用适当的 IAM 角色发送到 CloudWatch。

  1. 创建了 VPC →去控制台搜索 VPC。然后点击启动 VPC 向导,并选择正确的模板。提供必要的详细信息,然后点击创建。

2。 创建三个具有不同可用性区域的子网。转到左侧面板上的子网,然后单击创建子网。为子网提供名称,并将其连接到相关 VPC。重复该步骤三次,创建三个子网,每个子网具有不同的可用性分区,如下图快照中突出显示的那样。

3。 创造了一个互联网网关,并将其连接到 VPC。单击左侧面板上的互联网网关,提供一个名称,然后单击创建。我把它命名为实验室互联网网关。创建后,选择网关并单击操作下拉菜单。将有一个选项将其附加到特定的 VPC。一旦附上,回到你的 VPC 菜单。

4。 创建了另一个互联网网关,并试图将其连接到同一个 VPC。再次遵循上述相同的步骤,可以看到我们只能将一个网关连接到一个 VPC。

5。 创建公共访问路由表后,三个子网中有 2 个是公共访问,剩下 1 个是私有访问。首先,创建一个路由表,然后附上有关 VPC。连接 VPC 并创建路由表后,单击路由器选项卡并编辑路由表。在路由表中,单击添加路由并输入 0.0.0.0/0,这是一个公共访问 IP。现在,将该 IP 与我们在上述步骤中创建的 VPC 网关连接起来。现在,要使我们的两个子网具有公共访问权限,请转到“subnet associated”选项卡,编辑子网关联,选择两个子网,然后单击“save”按钮。这样,我们就创建了一个连接到 VPC 网关的路由表,并且我们已经将两个子网连接到该路由表,可以通过连接的网关进行公共访问。

6。现在,我们已经将子网连接到 VPC,将路由表连接到网关,我正在连接安全组。安全小组将允许交通进出我们的 VPC。对于入站流量,我允许 HTTP 和 SSH,对于出站流量,我允许完全访问。这意味着只有 HTTP 和 SSH 元素可以进入 VPC,但是 VPC 内部的所有内容都可以不受任何限制地发送到外部。首先,单击左侧面板上的安全组,然后单击“创建安全组”,然后为安全组提供一个新名称,提供一个描述并附上相关的 VPC。然后提供入站和出站流量规则,如快照所示。完成后,单击创建安全组,它将被附加到 VPC。

7。现在我们已经建立了整个环境,跟踪我们网络内部的每一项活动非常重要。为此,我们必须创建一个 VPC 流量日志。首先,单击我们创建的 VPC,然后单击“流量日志”选项卡,然后单击蓝色的“创建流量日志”按钮,然后选择过滤器,通知流量日志监控特定类型的活动。例如,如果我们希望只监控网络中被拒绝的请求,或者只监控网络中被允许的请求,或者两者都监控。我选择了全部。现在创建一个目标日志组,该日志组将包含来自我们网络的所有日志信息,此外,用户还可以将日志发送到 s3 存储桶。为了访问日志组,我们还必须附加 IAM 策略,以允许流日志访问云观察日志组。最后,我们点击保存。

我们到此为止,我们的网络设置完毕。如果你有任何意见,请分享你的想法。谢谢大家!

如何为数据科学设置 VS 代码—手册

原文:https://towardsdatascience.com/vs-code-setup-for-data-science-5f8ba549802a?source=collection_archive---------6-----------------------

入门

开始使用 VSCode for Data Science 所需的一切

图片来源:Pixabay

在热情的、有时是暴力的推荐之后,我决定从 PyCharm 转向 VSCode。在设置我的环境时,我觉得我花了太多的时间来弄清楚我需要什么,并通过几个指南来学习如何安装每个小东西。在那段时间里,我希望有一本手册能给我一些简介,并准确地告诉我如何为数据科学设置 VSCode 环境。由于我找不到,我决定记录我的过程的每一个部分,并在此提供给你,这样你就可以在合理的时间内愉快地完成你的设置。

安装 VSCode

每个伟大的旅程都从安装开始,在这里做

Python

要使用 Python,您需要安装它的扩展。

关于扩展的补充说明——基本上,VSCode 中的所有东西都通过它们工作。要找到一个,请按左边栏上的第四个图标(下图中被包围)或 ctrl-shift-X。然后,您会看到一个扩展列表、一个搜索面板和对右边扩展的解释。安装你喜欢的,但要小心——扩展浏览可能是免费的,但也很容易上瘾。

VSCode 扩展预览。用绿色圈起来的是打开这个魔法的按钮,在它的右边有一个扩展列表和一个搜索面板。按一个分机将在右边打开关于它的解释。

解释器

为了让我们的 DS/ML/AI 包工作,我们需要设置解释器,如下所示

Ctrl+shift+p → Python: Select 解释器→ conda base。

在这个例子中,我选择了 conda base,但是你可以从列表中选择任何你喜欢的解释器。

请注意,由于路径设置的原因,这里可能会有问题。为了解决这些问题,我建议在这里查看一下中描述的步骤

开始一个新文件

我发现这并不简单,因此值得一提——当您在 VSCode 中打开一个文件时,在您保存它之前,它不会出现在您的目录中。保存时,为了使它成为您想要的文件类型,您需要在文件名中注明扩展名。

底线—要启动一个 Python 文件,请执行以下操作

文件->新建->写一些代码。

使文件成为. py 类型-

文件->另存为->带有。py 扩展->保存。

然后 Python 的颜色就会出现,你就可以运行这个文件了。

运行您的脚本

右键单击文件->在终端中运行 Python 文件。或者,单击脚本窗口左上角的绿色播放按钮。

饭桶

我假设您希望将您的环境连接到您的 git 帐户和存储库,如果您没有,那么这一节对您来说就不太相关了。

1.安装扩展: GitHub 拉请求和发布

2.签到。您可以通过下图中蓝色箭头所指的按钮来确认您的登录是否正确。

3.克隆存储库:ctrl-shift-p -> Git: Clone

4.进入存储库进行编辑:文件->打开目录。

这个链接中,有更深入的解释和一些更有用的东西,所以我建议你有空去看看。

在 VSCode 预览中 Git。绿色箭头标记的按钮打开 Git,蓝色箭头指向可以检查连接的按钮。

Jupyter 功能

VSCode 为数据科学家提供的最强大的功能之一是可以在一个地方同时使用 IDE 和 Jupyter 笔记本的功能。要获得 Jupyter 功能,请安装其扩展— VSCode Jupyter 笔记本预览,安装后您可能需要重新启动 VSCode。

要使用“单元格”功能,请在代码段上方的行中用# %%标记代码段,以将其转换为单元格(如下图所示)。请注意,它会将代码的其余部分标记为单元格,或者直到下一次出现该标记。一旦将这一行放在代码之前,运行单元、调试单元和运行上面代码的选项就会出现(如图所示)。按下“运行单元”后,Python Interactive 将在右侧打开,您可以从其中的脚本运行单元,也可以从它自己的控制台运行代码(图中用蓝色箭头指向)。

此处需要注意的有用特性

1.变量(图中用红色圈出)——显示当前存储在内核中的所有变量及其有用信息。

2.导出为 Jupyter Notebook(图中用蓝色圈出)-在我看来,这款工具非常有用,因为它将您在内核中运行的所有内容(无论是通过脚本还是从 python 交互式控制台)保存到一个笔记本中。这样你就可以回去找到你可能忘记添加到你的脚本/函数中的代码段,这样可以节省很多时间。

VSCode 的 Jupyter 功能预览。用红色圈起来的是变量按钮,下面是你按下时看到的。蓝色圆圈是通往 Jupyter 按钮的出口。

这应该足够让你开始了。如上所述,您可以添加扩展来增强您在 VSCode 中的编码体验(请在评论中告诉我哪些非常有用),并根据您的偏好对环境进行一些不同的设置和调整。然而,要开始使用 VSCode for data science,我发现这些步骤已经足够了。我希望这本手册对你有所帮助,如果你有任何反馈,请在评论中或私信中与我分享。干杯。

带有 VSCode devcontainers 的 Python AzureML SDK 工作流

原文:https://towardsdatascience.com/vscode-devcontainers-and-the-python-azureml-sdk-323dec18a675?source=collection_archive---------43-----------------------

微软和 Python 机器学习:现代爱情故事,第 1 部分,共 2 部分

微软在征服我们的心和融入开源生态系统方面正在大步前进。他们在 2000 年公开反对的生态系统。我承认我正在融入微软的世界,并且感觉很好。在这篇博客中,我描述了在云中启动 ML 模型(AzureML)和在 VSCode 中远程开发代码的开发工作流。

参见:第 2 部分:统一远程和本地 AzureML 环境

1 VSCode ML 开发容器

由于对 VSCode 的认识相当晚,在我通常的否认期之后,它让我大吃一惊。在 Q2 2019 上引入的远程开发功能( vscode-dev-blog )真的为我敲定了这笔交易。这有三种味道:

  1. 在 Linux 的 Windows 子系统(WSL)中部署 VSCode 服务器,并在 Windows 桌面上运行客户端
  2. 在 Docker 容器中部署 VSCode 服务器,并在 Windows 桌面上运行客户端
  3. 将 VSCode 服务器部署到 SSH 目标,并在本地运行客户机

这是一个非常丰富的功能,不会令人失望的可靠性。让我们仔细看看。

1.1 VSCode 和 WSL2

Linux 的 Windows 子系统(WSL)已经存在了很多年。WSL2 在同一架构上统一了运行基于 Linux 的 docker 容器和 WSL Linux(docker-WSL 2-back end)。重要的是,它从架构中移除了复杂的虚拟化,WSL Linux 几乎可以本地运行。VSCode 可以处理 windows 文件系统上的代码,并在 WSL 上运行其服务器;与 Python 解释器和 shells 无缝集成。

在这篇博客中,我们建议在 WSL2 后端的 docker 容器中运行 VSCode 服务器,GUI 在 Windows 桌面上运行。WSL2 是未来的发展方向,它有很多好处,比如 Windows Home 支持( docker-windows-home )、资源管理和 GPU 支持的潜力( WSL2-dev-blog )。我们讨论的内容也适用于历史悠久的 Docker 后端。

在 devcontainer 中运行的 VSCode 和 Python(图片由作者提供)

AzureML devcontainer 中的 1.2 VSCode

微软提供了维护良好的 Dockerfiles,其中包含用于语言和语言不可知场景的通用开发工具( vscode-dev-containers )。我们选择了 azure-machine-learning-Python-3 容器( azureml-dev-container ,因为它的 Conda Python 解释器安装了 azureml-sdk 包。图片来源于 Ubuntu。如果我们包括了”。/.devcontainer”文件夹,VSCode 将:

  1. 检测”的存在。/.devcontainer”及其内容
  2. 从“构建一个容器。/.devcontainer/Dockerfile `文件
  3. 安装“decontainer.json”中定义的 VSCode 服务器和可选扩展
  4. 按照“devcontainer.json”中的配置运行容器;定义 a.o .绑定装载和启动脚本

VSCode 容器集成的设置存储在。/.devcontainer/devcontainer.json ”,并允许集成任何 docker 文件而无需修改。

可定制

我们可以将我们喜欢的开发工具添加到这些 devcontainers 中,作为 Dockerfile 中的附加层。或者,我们可以通过调用自定义“Dockerfile”中的“FROM ”,在基本图像的基础上进行构建。例如,添加带有扩展的 Azure CLI 和带有“运行”命令的 terra form(my-branch)。带有您最喜欢的开发环境的映像可能是一个很好的伙伴。我们可以在一个地方管理我们的自定义图像,并从我们的每个项目中提供到它的符号链接。

1.2.2 设置 VSCode Python AzureML 项目

  1. 在 windows 上安装 docker 桌面
  2. 安装 git for windows(我建议在安装过程中将其添加到 powershell 中)
  3. 安装 VSCode 及其“远程容器”扩展
  4. 将目录更改为 windows 文件系统上合适的 dev 目录(这里是“dev”)
  5. git clonehttps://github . com/Microsoft/vs code-dev-containers/tree/master/containers/azure-machine-learning-python-3
  6. 在现有的 Python 项目中,符号链接。使用 New-Item-Item type Junction-Path " c:\ dev \ Path \ to \ your \ project \的 Powershell 中的 devcontainer。dev container \ "-Target " c:\ dev \ vs code-dev-containers \ containers \ azure-machine-learning-python-3 \。devcontainer "
  7. 在项目基本文件夹中,使用“code”启动 vscode。
  8. VSCode 检测到“.”。并要求在容器中重新打开->是
  9. VSCode 构建容器并安装其服务器,然后重新打开
  10. 确认你的环境在左下角,一个绿色方块写着“Dev Container:Azure Machine Learning”

1.3 VSCode devcontainer 摘要

我们可以使用完全可复制的 Linux 工具链进行开发,并且仍然可以在 windows 笔记本电脑上工作。对于 Linux 或 MacOS 用户来说,这可能没有说服力,但是如果您对这些工具感到舒适,您几乎可以在任何地方使用它们。如果你在为你提供基础设施和笔记本电脑的公司工作,这是很有价值的。另一个场景是在你的游戏桌面 windows 电脑上用 GPU 训练深度学习模型,因为已经宣布了对 WSL2 的 GPU 支持( WSL2-dev-blog )。

Azureml Python SDK 很棒

此部分的先决条件是有效的 Azure 订阅。如果你有信用卡,你可以很容易地获得一个免费的 azure 账户。

我们的 VSCode 运行在一个包含 Python 和 AzureML Python SDK 的 devcontainer 中。SDK 包含一个复杂的 API,跨越了 ML 模型的整个生命周期。从笔记本中的探索、培训和跟踪模型到工件管理和部署。这包括用于模型培训的计算资源调配和配置,以及用于模型评分的部署目标。我将引用的一些工具(Azure CLI)被添加到我自己的 fork 中( my-branch )。

下图显示了我们的目标工作流程。我们使用 devcontainer 中的 AzureML SDK 从 VSCode 启动了一个实验,SDK 在计算目标上执行我们的代码。计算目标也在 docker 容器中运行我们的代码。运行时环境的细节将在本博客的第 2/2 部分讨论。

带有 VSCode devcontainer 的 AzureML 工作流(图片由作者提供)

2.1 向 Azure 注册您的容器

  1. 在 VSCode 中打开一个终端:菜单终端->新终端
  2. 在 shell 上执行“az 登录”。前往 www.microsoft.com/devicelogin填写控制台输出中提供的密码
  3. 我们现在已经将我们的环境与 Azure 订阅链接起来
  4. 帐户信息存储在“~/”中。azure/azureProfile.json”。

2.2 给我们看看代码!

让我们看看 Python AzureML SDK 代码:

  1. 创建 AzureML 工作区
  2. 创建一个计算集群作为培训目标
  3. 在计算目标上运行 Python 脚本

2.2.1 创建 AzureML 工作空间

AzureML 工作区由一个存储帐户、一个 docker 图像注册表和一个在 portal.azure.com 上具有丰富 UI 的实际工作区组成。一个新的相关机器学习工作室正在公开测试中,看起来真的很好(https://ml.azure.com)。下面的代码创建工作区及其所需的服务,并将它们附加到一个新的资源组。

**from** **azureml.core** **import** Workspaceworkspace = Workspace.create(
    name="learnml", subscription_id="<UUID>", resource_group="ml", create_resource_group=**True**, location="<location>", sku="basic",)

创建计算集群

我们需要计算资源来训练我们的 ML 模型。我们可以使用 AzureML Python SDK 创建、编排计算集群。创建资源的工作空间由工作目录中的 config.json 文件定义( configure-workspace )。 AmlCompute 代表 Azure 机器学习计算,是集群的配置类。如果群集不存在,我们将创建一个从 0 到定义的最大虚拟机数量的扩展。这些虚拟机正在运行 docker。我们将供应配置传递给 ComputeTarget 类的 create 方法,该方法返回一个 ComputeTarget 对象。每当我们要进行计算时,就会用到这个对象。下面的代码可以包装成一个函数来获取 compute_target。

**from** **azureml.core** **import** Workspace**from** **azureml.core.compute** **import** AmlCompute, ComputeTarget**from** **azureml.core.compute_target** **import** ComputeTargetExceptionCLUSTER_NAME = "cpucluster"VM_SIZE = "Standard_D2_V2"MAX_NODES = 1workspace = Workspace.from_config()  *# local config.json with subscription info**# retrieve existing cluster or create a new one***try**: cpu_cluster = ComputeTarget(workspace=workspace, name=CLUSTER_NAME) print("Found existing cluster, use it.")**except** ComputeTargetException: compute_config = AmlCompute.provisioning_configuration( vm_size=VM_SIZE, max_nodes=MAX_NODES )cpu_cluster = ComputeTarget.create(workspace, CLUSTER_NAME, compute_config)

2.2.3 在计算目标上运行 Python 脚本

我们希望在我们的计算集群上运行一个 Python 脚本。在本系列的第 2/2 部分中,我们将详细讨论运行时环境的配置。这里我们展示了在 compute _ target(AML compute-docs)上运行 Pyton 脚本所需的最少代码。

**from** **azureml.core** **import** Experiment, RunConfiguration, ScriptRunConfig, Workspace**from** **tools** **import** get_compute_targetCLUSTER_NAME = "cpucluster"EXPERIMENT_FOLDER = "/workspaces/azureml/code"workspace = Workspace.from_config()*# get_compute_cluster wraps the code under section 2.2.2*cpu_cluster = get_compute_target(workspace, CLUSTER_NAME)*# Create a new runconfig object*run_amlcompute = RunConfiguration()*"""**Skipping Environment details, treated in Blog Part 2/2, code is still valid**"""**# Set the compute target for the run*run_amlcompute.target = cpu_cluster*# Create a script config*script_config = ScriptRunConfig( source_directory=EXPERIMENT_FOLDER, script="run_experiment.py", run_config=run_amlcompute,)*# Submit the experiment*experiment = Experiment(workspace=workspace, name="my-experiment")run = experiment.submit(config=script_config)

2.3 AzureML SDK 摘要

我们已经看到创建 Azure ML 工作空间是多么容易,旋转计算集群并在其上运行 Python 脚本。所有这些都作为 ML 工作室内的一个实验被跟踪。

3 四舍五入

微软全力投入机器学习和 Python,这一点显而易见。对于我们的工作流,我们已经添加了 Docker/WSL2。从开发人员的角度来看,所有部分可靠地协同工作以完成实际工作是很重要的。我对生态系统各个部分的质量印象深刻:Docker/WSL2、VSCode 和 AzureML 以及它们对工作流的集成。当然,这一过程中也有一些陷阱,总结如下。

3.1 Windows 10 上 Docker 和 WSL2 的陷阱:

  • Linux 和 Windows 文件系统之间的文件权限映射是奇数(wsl-chmod-dev-blog);绑定挂载在 root:root 下
  • Crontab 用户可能不得不接触 windows 任务调度程序( wsl-scheduling )
  • GPU 支持正在进行中,但尚未实现(2020 年)
  • Linux 图形用户界面应用在路线图上,但还没有实现(2021 年)

原载于https://codebeez . nl

VSCode Jupyter 笔记本即将迎来重大升级

原文:https://towardsdatascience.com/vscode-jupyter-notebooks-are-getting-an-upgrade-cc9aaaefc744?source=collection_archive---------3-----------------------

刷新的用户界面和显著的性能修复

VSCode Jupyter 笔记本。图片来源:我😄

介绍

我一直想用 Visual Studio Code (VSCode)作为我日常一切的驱动,包括 iPython 笔记本。不要误解我的意思:JupyterLab 用于数据科学目的很棒(Jupyter 笔记本也是如此),但用于常规代码脚本就不那么好了,更不用说 Jupyter 只(实际上)支持 Python、Julia 或其他一些编程语言。

当 vs code——或者确切地说是 VSCode Python 扩展团队——在 2019 年首次宣布笔记本支持时,我不得不尝试一下。最后,除了涵盖 Jupyter 笔记本的所有按键和功能外,它还完成了一些值得注意的壮举:

  • 强大的变量浏览器绘图浏览器
  • 将 VSCode 的智能感知自动完成功能集成到代码单元中

但是,我发现它在其他方面有点令人失望:

  • 启动非常慢,尤其是通过 WSL 或 SSH
  • 界面很笨拙感觉半生不熟
  • 与 JupyterLab 不同,笔记本会话在 VSCode 中关闭后是不可恢复的

尽管如此,引入 Jupyter 笔记本集成是 VSCode 在 Python 数据科学领域向前迈出的一大步。 随着该团队最*宣布对 VSCode Jupyter 笔记本电脑进行重大更新,似乎在不久的将来会有另一个巨大的进步!

有什么新鲜事?

让我们先拿一个 Jupyter 笔记本样本来看看这些新变化。我将使用我以前的一篇关于 的文章中的一个笔记本来预测英雄联盟与 py torch的比赛,因为它有大量的代码、一个熊猫数据帧和一些图形——一个真实世界场景的很好的例子。**

可以看一下笔记本 这里 。免费文章可在下面阅读👇。

** [## 学习 PyTorch 的同时预测英雄联盟比赛(第二部分)

学习在 PyTorch 中实现一个前馈网络,并使用 GPU 为一个合适的用例进行训练,稍微接触一下…

towardsdatascience.com](/predict-league-of-legends-matches-while-learning-pytorch-part-2-38b8e982c7ea)

改进的用户界面

对于我们 VSCode+Python 用户来说,这可能是最大的变化。与旧的笔记本编辑器相比,新的 VSCode Python Jupyter 笔记本拥有全新的外观!下面是旧的(左)和新的(右)用户界面的对比。

老款(左) vs 新款(右) Jupyter 笔记本接口。使用的主题:Dark+(默认)。

界面的许多元素已经比它的前身干净多了。markdown 单元格文本的可怕字体和间距现在已经消失了,取而代之的是一种更加标准的字体,在我看来,这种字体更加美观。您可以在顶部的单元格中看到:“定义训练循环的模型&”。

让我们放大其中一个单元格:

笔记本单元格比较[ 左(旧)右(新)

代码单元变得不那么杂乱,让你更好地专注于你正在编程/解决的问题。虽然他们已经用 markdown 单元格减少了过多的间距,但这些间距被添加回代码单元格之间,作为生活质量的改善。

这让我对谷歌实验室产生了模糊的感觉😳

在这个新的 UI 中,添加新的单元格是一件轻而易举的事情。你甚至可以选择想要添加哪种类型的单元格,这对不使用键盘快捷键的人很有用。

另一个显著的 UI 变化位于顶部,如下所示:

一条青色线将旧的(最上面的)新的(最下面的) UI 分开。

当我开始使用新的 VSCode Jupyter 笔记本电脑时,我感觉突然有了更多空间来存放我的笔记本电脑。事实证明,情况确实如此——现在,按钮与文件名标签集成在同一层,这不仅节省了空间,而且看起来非常时尚😏。唯一的问题是:我们失去了对心爱的变量浏览器的访问(尽管我确信随着开发的继续,这个问题会得到解决)。

不过,这个新的用户界面并不全是外观。首先,拖放笔记本单元格的功能成为现实(类似于 JupyterLab)。没有更多的剪切和粘贴代码和 markdown 单元格!

展示新 VSCode Jupyter 笔记本电脑的新拖放功能

你可能还会注意到一些降价单元格旁边的箭头。更新后的笔记本用户界面还支持在 markdown 标题下折叠单元格,这对于浏览较长的笔记本非常方便。

这是我展示的可折叠笔记本电池。此外,如果你不知道为什么隐藏状态和侧边栏,我在 VSCode 上使用 Zen 模式(Ctrl + K,Z)。

提高装载性能

我可以处理一个半生不熟的用户界面,但是我不能处理一个永远显示在我屏幕上的笔记本电脑——这是我还没有放弃 Jupyter 的主要原因之一。然而,随着即将到来的笔记本更新,这将最终成为历史!

老版本(左)新版本(右)加载同一笔记本的对比,实时。

在你从上面看到的 GIF 中的这个小实验中,我试着为两个版本加载同一个笔记本。我已经尽力保持所有变量不变(python 环境、CPU/内存使用等。)——是的,两次试验都是在电脑重启后进行的。没有对 gif 进行任何修改来放大性能提升。综上所述,新的 VSCode Jupyter 笔记本的速度将会有多快已经很明显了。

VSCode 扩展与笔记本的兼容性

旧的 VSCode Jupyter 笔记本界面在处理扩展兼容性方面存在各种问题。以下是最值得注意的:

  • 括号对着色 这样的扩展根本不能在笔记本上工作
  • VSCode 主题不在 WSL 上注册,也不通过 SSH 注册

此更新将修复这两个问题,如下所示:

括号对着色现在可以在 VSCode Jupyter 笔记本上使用。不过,以前没有!

这是在 WSL 下运行的 VSCode。在新笔记本上(右),主题被保留,但在旧笔记本上(左)没有。VSCode 主题:仙女座

这些变化是如何实现的?

新的 VSCode Jupyter 笔记本利用了新的原生笔记本 API 。为了澄清任何混淆,该 API 由 VSCode 团队开发,该团队独立于负责 Jupyter 笔记本集成的 Python 扩展开发人员。在 API 之前,UI 基本上是从头开始构建的,解释了旧的 VSCode Jupyter 笔记本所遭受的一些性能/扩展兼容性问题。**

先看看这些新功能

这些特性在内部版本的 VSCode 和 Python 扩展中都可用。简而言之,以下是启用这些实验功能的步骤:

  1. 在这里下载并安装 Visual Studio 代码内幕
  2. 在扩展管理器上安装 Python 扩展
  3. 为 Python 扩展启用知情者每日频道

就是这样!它将开始安装,并让您知道完成后重新加载您的 VSCode Insiders。现在,无论何时你想用新的 Jupyter 笔记本用户界面打开一个**.ipynb**文件,打开上下文菜单(右击文件)并选择“在预览笔记本编辑器中打开”

右键单击. ipynb (Jupyter 笔记本)文件时显示的上下文菜单。

您对 VSCode Jupyter 笔记本电脑的这些升级有多期待?下面让我知道!

Vue vs 反应 vs 角度

原文:https://towardsdatascience.com/vue-vs-react-vs-angular-114718eac3c5?source=collection_archive---------12-----------------------

哪个 JavaScript 框架适合你

🇨🇭·克劳迪奥·施瓦茨| @purzlbaum 在 Unsplash 上拍摄的照片

JavaScript 是一种高级编程语言,目前是 web 的语言。前端和后端开发都可以用这种语言进行。随着当前网站的发展以及对设计和简单性需求的增加,框架被开发出来。它们允许程序员更快地创建漂亮的网站,这就是为什么他们比直接用 JS 编写更受欢迎的原因。

选择一个 JavaScript 框架是相当具有挑战性和令人困惑的,尤其是在没有任何相关知识的情况下。实际上有相当多的框架,我们将只讨论最流行的三个,它们通常被认为是开发得最好的。在这篇文章中,我将讨论它们的不同点和相同点,以及在选择一个之前需要考虑的问题。我会尽量简明扼要,所以我们开始吧。

做决定

首先也是最重要的,不需要过多考虑初始框架的选择。学习其中的一个会让学习其他的更容易。此外,您不仅将学习特定于该框架的特性,还将学习适用于每个框架的一般概念以及一般的 web 开发(设计和开发组件、理解数据流、管理状态和模板等等)。记住这一点,让我们更详细地看看每一个框架。

某视频剪辑软件

(图片由 2Developer 提供)

特点:

  • 数据绑定
  • 简单
  • 模板

Vue 是最新的框架,拥有越来越多的用户。它是三者中最容易上手的,对于更专业的开发者来说足够强大。Vue 没有 Angular 那么多内置功能,但仍然比 React 多很多,这意味着你可以马上开始用 Vue 建立网站。这是初学者的普遍选择。Vue 还允许你利用你的原生 HTML 和 CSS 技能。更重要的是,它以其精心编写的文档而闻名,这是非常有用的。最*,除了 CLI 之外,Vue 还创建了 UI 组件。这甚至进一步简化了初学者的学习过程,并提供了大量的统计数据。

Vue 比 Angular 和 React 更新,这意味着它有一个不断增长的社区。但是,它不像其他两个那样成立。

反应

(图片由菲利普·桑托斯·科雷亚提供)

特点:

  • 基于组件的
  • 宣言的
  • JSX

React 提供简单实用的组件创建。此外,React 优雅的 API 敦促您利用组件。React 非常受欢迎,尤其是在创业社区。通过选择大量容易获得的开源插件和扩展,基本上可以开发任何类型的网站。组件模板是用 JSX 编写的,这可能和你习惯的有点不同。

拥有如此多的扩展选择是很好的,但是会很有挑战性,甚至令人困惑,特别是对于那些刚刚起步的创作者。

有角的

(图片由 Angular GitHub 提供)

特点:

  • 普遍的
  • 当地的
  • 复杂的

Angular 当然比 React 或 Vue 提供了更多。因此,构建完整的解决方案更加简单。棱角分明受企业欢迎。此外,它还提供了三者中最好的命令行界面(CLI)。虽然它的语法需要一些时间来适应,Angular 允许更好地使用 HTML 和 CSS。与其他框架相比,代码相当冗长和复杂,学习曲线也更陡峭。

找什么?

弄清楚你将使用框架做什么是很重要的。想想自己的现状和要求。如果你正在你所在的地区找工作,检查一下招聘启事上的要求,弄清楚哪一个更常用。

你打算为一家新公司还是一家大公司工作?与招聘人员交谈,对你选择的职业道路做一些研究。查看哪个框架拥有最大的本地开发人员社区,并参加任何会议或加入他们的在线小组和讨论。

如果你为你的团队的下一个项目选择一个框架,看看你的团队成员有什么技能。思考一下克服一个更陡峭的学习曲线是否有利于进一步发展,比如 Angular 中的那个。也许这只是一个小项目,你想选择一些简单和容易开始。

比较

易用性

React 和 Vue 在很大程度上专注于构建用户界面,而 Angular 专注于构建应用程序。因为这个角度对于初学者来说比较复杂和困难。React 和 Vue 最初比较简单,但是在开发更大的应用程序时会变得越来越复杂。

工具支持

这三个框架都提供了 CLIs,这使得创建新项目和支持持续开发变得更加容易。此外,它们都受到流行的 ide 的良好支持,比如 VS Code 和 Atom。

表演

性能当然会因情况而异,在大多数情况下,这三个框架都相当快。在它们之间进行选择时,性能通常不是主要考虑的因素。然而,值得注意的是,在特定的任务中,一个可能比另一个更好,这是在处理大型应用程序时要考虑的事情。

结论

试图决定哪一个框架是最好的可能是棘手和主观的。这三者都提供了相似的功能,掌握其中任何一个对任何开发人员来说都绝对是一种好处。更重要的是学习使用 JavaScript 和开发 web 应用程序的核心概念和理论。最好先从一个开始,然后再尝试使用其他的。您最喜欢的框架当然会有所不同,所以考虑每一个细节并不重要。

链接:

https://vuejs.org/

反应过来:【https://reactjs.org/】T2

棱角分明:【https://angular.io/】T4

posted @ 2024-10-16 08:59  绝不原创的飞龙  阅读(196)  评论(0)    收藏  举报