在 Python 中可视化和分析蛋白质
数据科学
生物蛋白组学
人类生物学极其复杂。即使我们的理解越来越多,我们的答案只会发现越来越多的问题。人类基因组计划的完成给了许多科学家信心,我们可以通过基因组学解决生物学中的紧迫问题。然而,随着我们对生物学理解的加深,我们已经认识到其他因素会影响生物体基因组的利用。因此,新的研究领域诞生了,以解决这些相互联系和灵活的领域,包括转录组学(mRNA 的研究)和蛋白质组学(蛋白质的研究)。
作者 GIF
正如我在之前的博客中提到的,Biopython 软件包非常强大,可以简单地可视化和分析 DNA 和 RNA 序列。它还具有蛋白质分析能力!所以让我们开始吧。
蛋白质数据库是探索和下载蛋白质序列的一站式商店。PDB 为此开发了自己的文件格式——恰当地命名为. pdb。但随着更大、更复杂的蛋白质被分析,另一种格式被开发出来——CIF 和 mmCIF。CIF(晶体学信息文件)被开发用来存档研究晶体中原子排列的小分子晶体学实验。用 mmCIF 将 CIF 扩展到更大的分子(大分子,因此 mm ),并取代了 PDB 格式。[ 1
用 PDB 格式可视化
虽然 mmCIF 现在是标准,但仍有对 PDB 文件的传统支持。
让我们看看植物血凝素-L ,一种在某些豆类中发现的凝集素,如菜豆。
导入必要的包:
from Bio.PDB import *
import nglview as nv
import ipywidgets
现在我们将创建 Biopython 的 PDBParser 的一个实例,并使用 nglview 库来创建我们的交互式可视化。我们可以平移、缩放和旋转分子,甚至悬停以获取特定的原子信息。
pdb_parser = PDBParser()
structure = pdb_parser.get_structure("PHA-L", "Data/1FAT.pdb")
view = nv.show_biopython(structure)
作者图片
用 CIF 格式可视化
我们处理 CIF 文件的过程将非常相似,只是使用 MMCIF 解析器来代替!在这里,我们正在想象一个更大的蛋白质 6EBK ,或者脂质纳米盘中的电压激活 kv 1.2–2.1 桨嵌合体通道(一口…)
cif_parser = MMCIFParser()
structure = cif_parser.get_structure("6EBK", "fa/6ebk.cif")
view = nv.show_biopython(structure)
作者图片
访问蛋白质信息
页眉
获取蛋白质信息的最直接方式是通过标题,这是一个元数据字典,有 PDB 和 CIF 两种文件格式。
mmcif_dict = MMCIFDict.MMCIFDict("fa/1fat.cif")
len(mmcif_dict) # 689
这产生了一个关于蛋白质信息的大字典,包括对蛋白质排序的引用、结构信息、原子与原子的位置和角度以及化学成分。如你所见,这本词典有 689 个词条。
剩余序列
你想要分析的最重要的信息之一是蛋白质或多肽的残基——想想氨基酸——序列。因为蛋白质可以由几个多肽组成,我们使用一个框架来了解我们正在检查的组织水平。从整体结构,到单个原子。
我们文件中的结构对象遵循父子关系中的 SMCRA 体系结构:
- 一个 S 结构由模型组成
- 一个 M 模型由链条组成
- 链由残基(氨基酸)组成
- 一个Re 由ATom 组成
有许多方法可以解析结构元数据以返回蛋白质的残基序列。以下是三种方式:
# .get_residues() method in a loop
for model in structure:
for residue in model.get_residues():
print(residue)# .get_residues() method as generator object
residues = structure.get_residues() # returns a generator object
[item for item in residues]# .unfold_entities - keyword for each level of the SMCRA structure
Selection.unfold_entities(structure, "R") # R is for residues
构建多肽
得到上面的残基序列会返回整个蛋白质结构的序列,但是蛋白质通常由几个较小的多肽组成,我们可能想要单独分析它们。Biopython 通过可以产生这些单独多肽的多肽构建体来实现这一点。
polypeptide_builder = CaPPBuilder()
counter = 1for polypeptide in polypeptide_builder.build_peptides(structure):
seq = polypeptide.get_sequence()
print(f"Sequence: {counter}, Length: {len(seq)}")
print(seq)
counter += 1# Sequence: 1, Length: 36
# SNDIYFNFQRFNETNLILQRDASVSSSGQLRLTNLN
# Sequence: 2, Length: 196
# NGEPRVGSLGRAFYSAPIQIWDNTTGTVASFATSFT...ASKLS
# Sequence: 3, Length: 233
# SNDIYFNFQRFNETNLILQRDASVSSSGQLRLTNLN...ASKLS
# Sequence: 4, Length: 36
# SNDIYFNFQRFNETNLILQRDASVSSSGQLRLTNLN
# Sequence: 5, Length: 196
# NGEPRVGSLGRAFYSAPIQIWDNTTGTVASFATSFT...ASKLS
# Sequence: 6, Length: 35
# SNDIYFNFQRFNETNLILQRDASVSSSGQLRLTNL
# Sequence: 7, Length: 196
# NGEPRVGSLGRAFYSAPIQIWDNTTGTVASFATSFT...ASKLS
分析残基序列
所以现在我们有了这 7 条链的残基序列,但是我们也有了很多分析这些序列的方法。
from Bio.SeqUtils.ProtParam import ProteinAnalysis
唯一需要注意的是。上面的 get_sequences()返回一个 Biopython Seq()对象——查看我之前的博客以深入了解 Seq()对象及其功能——而 ProteinAnalysis 需要一个字符串。
analyzed_seq = ProteinAnalysis(str(seq))
我们现在准备运行以下方法来建立对我们序列的理解!
分子量
我们可以计算多肽的分子量。
analyzed_seq.molecular_weight()
# 4176.51669
肉汁
蛋白质肉汁返回您输入的蛋白质序列的肉汁(亲水性的大平均值)值。通过将每个残基的亲水性值相加并除以序列长度来计算肉汁值(Kyte 和 Doolittle1982).2
值越高,疏水性越强。值越低,亲水性越强。我们后面会讨论如何通过残基疏水性生成残基。
**analyzed_seq.gravy()
# -0.5611**
氨基酸计数
我们可以很容易地计算出每种氨基酸的数量。
**analyzed_seq.count_amino_acids()
# {'A': 1,
'C': 0,
'D': 2,
'E': 1,
'F': 3,
'G': 1,
'H': 0,
'I': 2,
'K': 0,
'L': 5,
'M': 0,
'N': 6,
'P': 0,
'Q': 3,
'R': 3,
'S': 5,
'T': 2,
'V': 1,
'W': 0,
'Y': 1}**
氨基酸百分比
以及序列中每个氨基酸的百分比!
**analyzed_seq.get_amino_acids_percent()
# {'A': 0.027777777777777776,
'C': 0.0,
'D': 0.05555555555555555,
'E': 0.027777777777777776,
'F': 0.08333333333333333,
'G': 0.027777777777777776,
'H': 0.0,
'I': 0.05555555555555555,
'K': 0.0,
'L': 0.1388888888888889,
'M': 0.0,
'N': 0.16666666666666666,
'P': 0.0,
'Q': 0.08333333333333333,
'R': 0.08333333333333333,
'S': 0.1388888888888889,
'T': 0.05555555555555555,
'V': 0.027777777777777776,
'W': 0.0,
'Y': 0.027777777777777776}**
二级结构
一个非常有用的方法。secondary _ structure _ fraction()-返回三种经典二级结构中的氨基酸比例。这些是β折叠、α螺旋和转角(残基改变方向的地方)。
图片由托马斯·沙菲在维基媒体的 CC BY-SA 4.0 许可下提供。
**analyzed_seq.secondary_structure_fraction() # helix, turn, sheet
# (0.3333333333333333, 0.3333333333333333, 0.19444444444444445)**
蛋白质秤
蛋白质尺度是一种使用滑动窗口测量肽序列长度上残基的某些属性的方法。标度由基于不同物理和化学性质的每种氨基酸的值组成,例如疏水性、二级结构趋势和表面可及性。与一些链级测量(如整体分子行为)相反,尺度允许对序列的较小部分将如何表现有更细粒度的理解。
**from Bio.SeqUtils.ProtParam import ProtParamData**
一些常见的秤包括:
- kd → Kyte & Doolittle 疏水性指数[ 原文
- 弹性→标准化平均弹性参数(B 值)[ 原文
- hw → Hopp & Wood 亲水性指数[ 原文
- em → Emini 表面分数概率(表面可达性)[ 原著
可在这里找到一些常见秤的文档。
让我们以疏水性指数(kd)为例。这是一个等级,每个残基都有一个代表其疏水性水平的相关值。
**kd = {"A": 1.8, "R": -4.5, "N": -3.5, "D": -3.5, "C": 2.5,
"Q": -3.5, "E": -3.5, "G": -0.4, "H": -3.2, "I": 4.5,
"L": 3.8, "K": -3.9, "M": 1.9, "F": 2.8, "P": -1.6,
"S": -0.8, "T": -0.7, "W": -0.9, "Y": -1.3, "V": 4.2}**
正值是疏水的。异亮氨酸(I)和缬氨酸(V)最疏水,精氨酸®和赖氨酸(K)最亲水。疏水性残基通常位于多肽的内部,而亲水性残基位于外部,因此这一尺度也给出了该多肽可能如何折叠的意义。
蛋白质规模分析需要设置一个窗口大小,在此范围内计算平均值。您还可以使用“edge”关键字来指定相邻残基的重要性,基本上是将它们的重要性加权到窗口的平均值。
**analysed_seq.protein_scale(window=7, param_dict=ProtParamData.kd)# [-0.7571428571428572,
-0.2428571428571429,
-0.24285714285714288,
-0.38571428571428573,
-0.6285714285714287,
-0.942857142857143,
-1.842857142857143,
-1.442857142857143,
-2.3428571428571425,
-1.3000000000000003,
-0.01428571428571433,
0.1285714285714285,
0.1285714285714285,
-0.014285714285714235,
-0.4142857142857143,
0.3428571428571428,
-0.31428571428571417,
-0.35714285714285715,
-1.014285714285714,
-0.6285714285714284,
-0.10000000000000002,
0.3428571428571429,
-0.4142857142857142,
0.24285714285714285,
-1.0,
-0.34285714285714286,
-0.32857142857142857,
-0.7142857142857143,
-0.1142857142857144,
-0.11428571428571435]**
把它绑在一起
让我们把所有的方法放在一起,创建一个脚本,它可以遍历我们结构中的每个链,并运行一些常规分析。我们将创建一个空容器,然后用每个序列的关键信息的字典填充它。在这个嵌套结构中,我们可以像对 Python 中的任何容器一样进行切片,以选择单个条目。
**# Create empty list for chains
all_seqs = []
counter = 1# For each polypeptide in the structure, run protein analysis methods and store in dictfor pp in ppb.build_peptides(structure):
seq_info = {} # create an empty dict
seq = pp.get_sequence() # get the sequence like above
analyzed_seq = ProteinAnalysis(str(seq)) # needs to be a str # Specify dict keys and values
seq_info['Sequence Number'] = counter # set sequence id
seq_info['Sequence'] = seq # store BioPython Seq() object
seq_info['Sequence Length'] = len(seq) # length of seq
seq_info['Molecular Weight'] = analyzed_seq.molecular_weight()
seq_info['GRAVY'] = analyzed_seq.gravy() # hydrophobicity
seq_info['AA Count'] = analyzed_seq.count_amino_acids()
seq_info['AA Percent'] = analyzed_seq.get_amino_acids_percent() # tuple of (helix, turn, sheet)
seq_info['Secondary Structure'] = \
analyzed_seq.secondary_structure_fraction()
# Update all_seqs list and increase counter
all_seqs.append(seq_info)
counter += 1**
选择第一个序列将返回包含我们的分析和值的字典!
**all_seqs[0] # select the first sequence# {'Sequence Number': 1,
'Sequence': Seq('SNDIYFNFQRFNETNLILQRDASVSSSGQLRLTNLN'),
'Sequence Length': 36,
'Molecular Weight': 4176.52,
'GRAVY': -0.5611,
'Amino Acid Count': {'A': 1,
'C': 0,
'D': 2,
'E': 1,
'F': 3,
'G': 1,
'H': 0,
'I': 2,
'K': 0,
'L': 5,
'M': 0,
'N': 6,
'P': 0,
'Q': 3,
'R': 3,
'S': 5,
'T': 2,
'V': 1,
'W': 0,
'Y': 1},
'Amino Acid Percent': {'A': 0.027777777777777776,
'C': 0.0,
'D': 0.05555555555555555,
'E': 0.027777777777777776,
'F': 0.08333333333333333,
'G': 0.027777777777777776,
'H': 0.0,
'I': 0.05555555555555555,
'K': 0.0,
'L': 0.1388888888888889,
'M': 0.0,
'N': 0.16666666666666666,
'P': 0.0,
'Q': 0.08333333333333333,
'R': 0.08333333333333333,
'S': 0.1388888888888889,
'T': 0.05555555555555555,
'V': 0.027777777777777776,
'W': 0.0,
'Y': 0.027777777777777776},
'Secondary Structure': (0.3333333333333333,
0.3333333333333333,
0.19444444444444445)}**
我们也可以很容易地选择特定的值。
**all_seqs[0]['Sequence']# Seq('SNDIYFNFQRFNETNLILQRDASVSSSGQLRLTNLN')all_seqs[0]['Molecular Weight']# 4176.52**
结论
Biopython 不仅使处理 DNA 序列变得容易,它还可以用于蛋白质组学来可视化和分析蛋白质。它为常规蛋白质分析提供了强大而灵活的方法,可用于根据您的特定需求开发定制管道。我知道,随着我继续深入研究 Biopython 所提供的功能,我将会继续留下深刻的印象,因此您可以期待将来有更多的文章介绍它的功能。
和往常一样,本文中描述的所有代码和依赖项都可以在这个 repo 中找到,随着我对 Biopython 的探索,我将继续更新这个 repo。我希望本指南向您展示用 Biopython 开始自己的生物信息学项目是多么简单,我期待看到您能创造出什么!
连接
我一直在寻找连接和探索其他项目!你可以在 GitHub 或 LinkedIn 上关注我,并在媒体上查看我的其他故事。我也有一个推特!
来源
[1] R. K. Green,PDB 结构和 PDBx/mmCIF 格式的初学者指南。
[2] J. Kyte 和 R.F. Doolittle,一种显示蛋白质亲水特性的简单方法 (1983),J. Mol .生物。157 (1): 105–32.
可视化和预处理图像数据集
使用 Tensorbay 和 SkImage 对大型数据集进行可视化和预处理
来源:作者
当创建计算机视觉项目或模型时,我们通常使用大型数据集。不仅图像数据集的大小比文本数据集大,而且使用了更多的图像,因此我们的模型不会过拟合,并且具有高性能。
我们在哪里可以找到新的、新鲜的数据集?鉴于它们的大小,下载可能吗?我们都曾在 MNIST、FashionMNIST、CIFAR-10 等数据集上工作过。,但是这些都是旧的,用过很多次了。一旦我们访问了新的数据集,我们如何在不下载到本地的情况下轻松使用它们?
答案是使用来自 Graviti 的 TensorBay。TensorBay 是一个数据集管理平台,可自动化和简化整个流程,包括数据托管、版本控制和数据可视化。为了便于集成,Graviti 为 TensorBay 开发了一个基于 Python 的 SDK 来执行这些服务。
对于本地数据集的可视化,我们可以使用 Pharos ,它是 TensorBay SDK 的一个插件。Pharos 发布了一个 Flask 应用程序,允许我们可视化数据并检查其注释。这些可视化有助于识别我们的数据是如何组织的,以及数据中是否存在异常。
对于图像处理,使用了一个 Python 库 Skimage。Skimage 包含不同的算法,可以用来编辑图像。
在本文中,我们将使用 TensorBay、Pharos 和 Skimage 探索图像数据可视化。让我们开始吧…
为访问密钥创建 Graviti 帐户
在可视化数据之前,您需要有一个访问键来访问数据和分叉数据集。除了可视化,这个键还可以让您访问其他功能,如版本控制、数据集创建等。
上面给出的链接可以用来在 Graviti 上创建一个帐户。注册后,您可以从开发人员工具部分生成并使用您的访问密钥。
分叉数据集
下一步是派生数据集。 Graviti 提供了 1000 多个数据集,可以很容易地进行相应的分叉和使用。您可以在此选择任何数据集。对于本文,我们使用的是 17 类别花数据集。
来源:作者
使用 Pharos 可视化数据集
要可视化一个数据集,请登陆它在 TensorBay 的主页,使用 Pharos 启动 Flask 应用程序。
来源:作者
创建 Jupyter 笔记本
最后一步是创建一个 Jupyter 笔记本,用于加载分叉数据集。但是首先,我们需要使用下面给出的命令安装所需的 TensorBay 及其插件 Pharos Python 库。
在下面显示的代码中,数据集在我们的本地机器上被读取,图像从 URL 中获取并保存在一个列表中,该列表将用于预处理。请记住,您需要提供自己的访问键,并派生出您想要使用的数据。
from tensorbay import GAS
from tensorbay.dataset import Segment
from tensorbay.dataset import Data, Dataset
import requests
from PIL import ImageACCESS_KEY = “Your Access Key”
gas = GAS(ACCESS_KEY)dataset_client = gas.get_dataset(“Flower17–1”)img_list=[]segments = dataset_client.list_segment_names()segment = Segment(“default”, dataset_client)for data in segment:
fp = data.open()
img_list.append(Image.open(requests.get(fp.url,
stream=True).raw))
img_list
来源:作者
在上面的图片中,你可以看到我们如何从 URL 加载不同的图片。现在我们将对将要处理的图像进行可视化,然后对这些图像进行预处理,这些图像存储在一个列表中。
plt.figure(figsize=(11,11))for i in range(1,10):plt.subplot(3,3,i)plt.tight_layout()plt.imshow(img_list[i-1])plt.title(‘Flower’)plt.xlabel(img_list[i-1].shape[1], fontsize=10)plt.ylabel(img_list[i-1].shape[0], fontsize=10)
来源:作者
#converting image to numpy arrayimport numpy as npimage1 = np.array(img_list[0])image1
来源:作者
image1.shape
来源:作者
image1.size
来源:作者
#Converting Grayscale
from skimage.color import rgb2gray
grayscale = rgb2gray(img_list[0])#Edge Detection
from skimage import filters
ed_sobel = filters.sobel(grayscale)
imshow(ed_sobel, cmap=’gray’);
边缘(来源:作者)
from skimage.exposure import histogram
hist, hist_centers = histogram(grayscale)#Plotting the Image and the Histogram of gray valuesfig, axes = plt.subplots(1, 2, figsize=(8, 3))axes[0].imshow(grayscale, cmap=plt.cm.gray)axes[0].axis(‘off’)axes[1].plot(hist_centers, hist, lw=2)axes[1].set_title(‘histogram of gray values’)
来源:作者
在 Graviti 使用不同的数据集尝试这个过程,并使用 Pharos 创建可视化。请在回复部分留下你的评论,让我知道结果如何。
使用 Streamlit 可视化音频管道
检查浏览器中增强功能的效果
当处理图像数据时,从业者经常使用增强。扩充是人为随机改变数据以增加多样性的技术。将这种变换应用于训练数据使得模型更加健壮。对于图像数据,常用的方法是旋转、调整大小或模糊。转换的效果很容易看到和理解。甚至可以快速掌握多个增强,如下例所示:
示例性增强。一个 TensorFlow 教程后作者创建的图片。
这种增强并不局限于图像(尽管它们在那里很受欢迎)。对于音频数据,有类似的方法来修改训练数据。不利的一面是,人们不能同时观察增强的效果,而必须手动聆听个别的转换。但是,您可以将音频数据可视化,而不是按顺序聆听所有样本。通过视觉化改变,你将检查转移到图像世界。现在,看一眼比同时听十个样本能告诉你更多。当您为新任务构建原型并希望快速检查数据集的变化时,这很有帮助。
这篇文章并没有展示如何在使用 TensorFlow 的时候增加音频数据。我在最近的帖子中对此进行了弥补。
要创建一个简单的应用程序来完成您正在寻找的功能,谢天谢地,您不必再深入 GUI 编程了。相反,你可以利用像 streamlit 这样的工具来可视化数据脚本。将这个与 audiomentations 包结合起来,你可以在两三个下午内构建一个可视化工具。
让我们看看这样的应用程序是什么样子的:
示例性应用的概述。图片由作者提供。你可以在这里复制代码,在这里现场试用。
在左侧边栏,您构建了您的增强管道。选择一些转换;可能包括添加噪声(AddGaussianNoise)和掩蔽频率(FrequencyMask)。然后,上传一个音频文件或选择一个提供的样本。点击“应用”后,您可以在中心检查效果。
最左边的列包含文件的谱图表示。这种可视化显示了给定时间步长下频率的功率。中间一栏包括波形,最右边一栏显示音频播放器。
侧栏是通过调用以下代码创建的:
我们首先为所有可能的扩展创建复选框,并通过在下面放置一个水平栏来直观地划分这一部分。下一部分添加文件选择功能,最后一个按钮启动可视化过程。
主布局通过以下方法创建:
我们首先绘制未更改的音频文件,然后应用管道的单独转换。增强 A 的输出是增强 b 的输入。为了区分各个变化,我们添加一个小标题,就这样。
更多的代码在后台工作,但是没有太多令人兴奋的事情发生。如果你无论如何都想深入了解它,那么就在这里浏览这些行。要查看运行中的完整应用程序,您有两种选择:
首先,你可以在你的浏览器这里现场试用。
其次,你可以克隆库,安装需要的包,然后在命令行运行streamlit run visualize _ transformation . py。然后,Streamlit 在本地的*http://localhost:8501/*上呈现并提供您的 python 脚本。
最近,这个帖子得到了一个兄弟,它展示了如何将增强应用于(TensorFlow)音频数据集。你可以在这里找到说明。
可视化丹佛的公共汽车轨迹
实践教程
使用 Python 和 Unfolded 可视化 RTD 的实时总线数据馈送
区域交通区,通常被称为 RTD,是丹佛运营公共交通服务的区域机构。RTD 有一个开放的数据平台,发布:
- 时刻表数据,包括完整的时刻表和路线配置
- RTD 公交服务的实时数据,包括作为 GTFS 实时反馈的到达/离开预测和车辆位置信息
使用展开的最终可视化(Abdullah Kurkcu 图像)
我们将使用实时数据馈送来首先存储一些数据,然后使用新发布的 explode studio 来可视化公共汽车运动。利用优步的开普勒定律可以达到同样的结果。
在寻找如何下载 GTFS 实时数据的例子时,我看到了这篇精美的文章和代码,展示了如何下载这样的地理空间数据。
https://medium.com/swlh/visualizing-istanbul-bus-traffic-with-python-and-keplergl-a84895788825
我按照奥赞·卡拉的方法下载了丹佛地区的 GTFS 数据,并对代码做了一些修改,还增加了一些额外的后处理步骤来计算总线速度。
我试图下载数据时遇到的问题是,GTFS 提要中有一些空闲的总线,这改变了提要的格式。例如,如果车辆空闲,则 tripID/stopID 等标签不存在。
让我们看看计划车辆的常规饲料:
如果公共汽车还没有时间表,那么 JSON 就是这样的:
如您所见,没有时间表的公共汽车没有 stopId、tripId、routeId 等。这就是为什么我们必须在尝试读取它们之前检查这些标签是否存在。让我们在整个数据下载过程中导入我们需要的库。
下面的虚拟函数将检查可能存在的标签,并使用数据或 NA 填充它们。
下面的函数将下载我们需要的数据。为了能够从 RTD 的 GTFS 实时数据馈送下载数据,您将需要 HTTP 基本身份验证凭据。
我们需要每分钟调用这个函数,因为公共汽车每分钟都会发送位置更新。
好了,我们现在有了我们需要的一切。您可以想运行这个函数多长时间就运行多长时间,但是我认为一个小时的数据足以构建一个很好的可视化。我让它运行了一天,并存储了数据。以下函数将 busdata 保存为 geoJSON 文件。它以 Kepler.gl 或 Unfolded 可以动画的方式格式化。
另外,如果你想计算公共汽车的速度,我写了下面这段混乱的代码。我想计算给定路线的平均公交车速度。这就是为什么该函数会计算每次 ping 之间的速度,并取该路线所有这些值的平均值。
不要忘记将其保存为新的 geoJSON 文件。
我们需要的一切都准备好了。你可以去 kepler.gl 或者 unfolded.ai 来可视化这个 geoJSON。我将使用展开,因为我有一个老朋友在那家非常成功的公司工作。
登录 studio.unfolded.ai ,点击右上方“新地图”。这将把你带到要求你上传数据的屏幕。
只需找到您保存的 geojson 文件,并将其放在此屏幕上。展开将自动识别格式,并为您创建一个动画时间线。我们唯一需要改变的是颜色。我想根据公交车的平均速度给这些轨迹上色。
好吧,我撒谎了,这不是我唯一要改变的。我也会增加步道的长度。更长的步道看起来更酷:)谢谢展开!(图片由阿卜杜拉·库尔库提供)
仅此而已!这是最终产品的视频。你可能会看到一些飞行器。我认为原因是他们打开/关闭追踪器或者失去了与服务器的连接。
(阿卜杜拉·库尔库的视频)
用 Python 可视化气候变化数据
使用 xarray 和 cartopy Python 库创建气候变化图表
2020 年全球气温异常(图片由作者提供)-数据由美国宇航局/GISS 提供
不可否认的事实是,气候变化是当今时代人类面临的最大挑战。全球平均气温持续上升,IPCC 指出的上升幅度应限制在比工业化前水平高 1.5 摄氏度,才有希望减轻气候变化的有害影响。这个目标是在巴黎协定中设定的,该协定于 2015 年被世界上几乎所有国家采纳。然而不幸的是,几乎没有采取什么行动来解决这个问题,不断发表的令人担忧的科学研究突出了这一点。
新冠肺炎疫情导致了人类活动的大多数方面的下降,以及随之而来的化石燃料燃烧和二氧化碳排放的减少。尽管如此, 2020 年是历史上最热的年份之一,全球各地都有极端天气事件的记录。此外,根据发表在《冰冻圈杂志》上的研究,全球冰盖正在以创纪录的速度融化,这符合 IPCC 的最坏情况。其他科学家声称,气候变化和生物多样性的丧失对人类的生存构成了前所未有的威胁,其程度甚至连专家都难以理解。
根据皮尤研究中心进行的调查,全球大约 70%的人认为气候变化是他们国家的主要威胁。与 2013 年相比,这一比例显著增加,但仍然很低,因为每个人都必须了解这一问题的严重性。让公众了解气候变化的一个方法是创建相关数据的信息性和美观的可视化。在这篇文章中,我将教你如何使用 Python 制作温度变化的地图和动画。
GIS temp 数据集
我们的可视化基于美国宇航局 GISTEMP v4 数据集,该数据集结合了 NOAA GHCN v4(气象站)和 ERSST v5(海洋区域),从而产生了我们星球整个表面气候可变性的全面记录。该数据集包括 1880 年以来的温度,每月一次,由美国国家航空航天局用于监测全球和区域气候变化。没有提供绝对温度,而是给出了与基准期(1951-1980 年)相比的异常。该数据集以 netCDF 格式在GIS temp 网站免费提供。如果你想了解关于数据集的更多细节,以及美国宇航局分析数据集以生成气候变化图表的方式,你可以查看相关论文。
Xarray 和 Cartopy 图书馆
NetCDF 是一种支持面向数组的科学数据的文件格式,通常用于气候学和气象学等领域。有各种各样的 Python 库支持它,但是我们将使用 xarray,因为它是最强大的。Xarray 受流行的 pandas 库的启发,将其大部分功能扩展到多维数组。该库构建在 NumPy 之上,易于集成到 Python 机器学习工作流中。最后,它还具有强大的科学数据集可视化绘图功能。Cartopy 是一个用于地理空间数据可视化的 Python 库,使科学家能够创建出版物质量的地图。它与 xarray 集成得很好,所以我们要用它来生成我们的地图。
可视化 GISTEMP 数据
下面的代码可以在使用 Python 3 的 Jupyter 笔记本上执行,如果您愿意,甚至可以使用 Google Colab。首先,我们将通过使用open_dataset()
xarray 函数导入必要的库并加载 GISTEMP 数据集。
(图片由作者提供)
打印 xarray 数据集输出一些关于其属性和变量的基本信息。正如我们所看到的,数据集是一个 2 ×2 的温度异常网格,每月一次。我们现在要绘制 2020 年全球气温异常图。
2020 年全球气温异常(图片由作者提供)
首先,我们将 xarray 数据集重新采样为一年一次的频率,因为这样更便于操作。之后,我们创建一个卡通地图,并添加世界上每个国家的边界。然后,我们使用imshow()
方法绘制 xarray 数据。我们还启用了双三次插值,因此图形看起来更具视觉吸引力。我们现在要把我们的重点转移到欧洲国家,通过绘制该地区的地图。
2020 年欧洲气温异常(图片由作者提供)
我们更改了制图地理轴的范围,以仅绘制我们偏好的区域,而不是整个地图。在这种情况下,我们绘制了欧洲大陆,但您可以选择任何您喜欢的地区,这取决于您希望与哪些受众共享图表。我们现在要制作同一地区过去几十年温度变化的动画。
我们现在使用FuncAnimation()
Matplotlib 函数来生成 1950-2020 年期间的动画,而不是生成静态图表。使用了一个名为animate()
的附加方法,指定动画的每一帧将如何生成。这个函数作为一个参数传递给FuncAnimation()
,同时传递的还有我们想要制作动画的时间段。之后,我们使用 FFmpeg 将动画保存为 MP4 视频。在所有主流操作系统上安装 FFmpeg 的下载链接和说明可从这里获得。
结论
为气候变化创建信息丰富且吸引人的图表是一个相对简单的过程,我希望这篇教程能帮助你完成这个任务。由 NASA 等知名组织免费提供的科学数据集,以及众多开源工具,使得每个人都可以进行气候数据分析。我鼓励你们使用 GISTEMP 或其他类似的数据集,并告知你们地区的公民有关气候变化的信息。我们都可以为应对这一巨大挑战做出贡献,而利用数据是实现这一目标的一个很好的方式。如果你想克隆这个项目的 Github 库,可以在这里找到。欢迎在评论中分享你的想法,或者在 LinkedIn 上关注我,我经常在那里发布关于数据科学、气候变化和其他主题的内容。你也可以访问我的个人网站或者查看我的新书,名为用 PyCaret 简化机器学习。
参考
[1]斯莱特,托马斯等,“地球的冰不平衡。”冰冻圈 15.1(2021):233–246。
[2]布拉德肖,科里·贾等人,“低估避免可怕未来的挑战。”保护科学前沿 1 (2021): 9。
[3]汉森,詹姆斯,等,“全球地表温度变化。”地球物理学评论 48.4 (2010)。
用 Python 的 Matplotlib 可视化集群
如何提高聚类分析的可视化
集群肯定不是什么新鲜事物。MacQueen 在 1967 年开发了 k-means 算法,从那以后,人们开发了许多其他实现和算法来执行对数据进行分组的任务。
散点图—作者提供的图片
本文将探讨如何用散点图来改进我们的集群的可视化。
散点图
让我们从加载和准备数据开始。我将使用口袋妖怪统计数据的数据集。
import pandas as pddf = pd.read_csv('data/Pokemon.csv')# prepare data
types = df['Type 1'].isin(['Grass', 'Fire', 'Water'])
drop_cols = ['Type 1', 'Type 2', 'Generation', 'Legendary', '#']
df = df[types].drop(columns = drop_cols)
df.head()
数据框-作者提供的图片
由于这篇文章与其说是关于集群,不如说是关于可视化,我将在下面的例子中使用一个简单的 k-means。
我们将计算三个集群,获得它们的质心,并设置一些颜色。
from sklearn.cluster import KMeans
import numpy as np# k means
kmeans = KMeans(n_clusters=3, random_state=0)
df['cluster'] = kmeans.fit_predict(df[['Attack', 'Defense']])# get centroids
centroids = kmeans.cluster_centers_
cen_x = [i[0] for i in centroids]
cen_y = [i[1] for i in centroids]
## add to df
df['cen_x'] = df.cluster.map({0:cen_x[0], 1:cen_x[1], 2:cen_x[2]})
df['cen_y'] = df.cluster.map({0:cen_y[0], 1:cen_y[1], 2:cen_y[2]})# define and map colors
colors = ['#DF2020', '#81DF20', '#2095DF']
df['c'] = df.cluster.map({0:colors[0], 1:colors[1], 2:colors[2]})
然后,我们可以将用于创建聚类的字段传递给 Matplotlib 的散点图,并使用我们创建的“c”列根据聚类在图表中绘制点。
import matplotlib.pyplot as pltplt.scatter(df.Attack, df.Defense, c=df.c, alpha = 0.6, s=10)
散点图—作者提供的图片
酷毙了。这是聚类数据集的基本可视化,即使没有太多信息,我们也可以开始了解我们的聚类以及它们是如何划分的。
多维度
我们经常使用多个变量对数据进行聚类,而散点图只能显示两个变量。可视化三个以上变量有几种选择,但都有应该考虑的缺点。
我们可以使用标记的大小,并使其成为一个气泡图,但这不是一个最佳的解决方案。我们无法将第三个变量与其他变量进行比较,因为它们的编码不同。
例如,我们可以通过查看我们之前制作的图表来判断某个记录的攻击或防御是否较高。但是如果我们把速度作为大小加入,我们就无法和其他两个变量进行比较。
plt.scatter(df.Attack, df.Defense, c=df.c, s=df.Speed, alpha = 0.6)
气泡图—作者图片
3D 图也可以对第三个变量进行编码,但它也可能会令人困惑,有时甚至会产生误导——这是因为取决于我们如何看待图表,它可能会给我们错误的印象。
3D 散点图—图片由作者提供
不过,3D 散点图还是很有帮助的,尤其是在它们不是静态的情况下。
根据您的环境,很容易添加一些与 Matplotlib 的交互性。
一些 ide 默认会有这个;其他环境将需要扩展和一个神奇的命令,如 Jupyter Lab 上的“Matplotlib Widget”或 Jupyter notebooks 上的“Matplotlib Notebook”。
通过改变我们看图表的角度,我们可以更仔细地检查它,避免误解数据。
from mpl_toolkits.mplot3d import Axes3D
%matplotlib widgetcolors = ['#DF2020', '#81DF20', '#2095DF']kmeans = KMeans(n_clusters=3, random_state=0)df['cluster'] = kmeans.fit_predict(df[['Attack', 'Defense', 'HP']])
df['c'] = df.cluster.map({0:colors[0], 1:colors[1], 2:colors[2]})fig = plt.figure(figsize=(26,6))ax = fig.add_subplot(131, projection='3d')
ax.scatter(df.Attack, df.Defense, df.HP, c=df.c, s=15)ax.set_xlabel('Attack')
ax.set_ylabel('Defense')
ax.set_zlabel('HP')plt.show()
3D 散点图—图片由作者提供
总的来说,它们仍然是一个非常有限的解决方案。
我认为最好的方法是使用多个散点图,要么以矩阵格式,要么通过变量之间的变化。你也可以考虑使用一些数据简化方法,如主成分分析法,将你的变量合并成更少的因素。
释文
现在,让我们开始改善我们的视觉化。
如果数据可视化是讲故事,那么注释就相当于我们故事中的叙述者。他们应该帮助观众理解和关注什么是重要的,而不是占用太多的情节空间。
我们将添加基础知识、标题、标签和图例。
### BUILD A TWO DIMENSIONS CLUSTER AGAIN ###
# k means
kmeans = KMeans(n_clusters=3, random_state=0)
df['cluster'] = kmeans.fit_predict(df[['Attack', 'Defense']])# get centroids
centroids = kmeans.cluster_centers_
cen_x = [i[0] for i in centroids]
cen_y = [i[1] for i in centroids]
## add to df
df['cen_x'] = df.cluster.map({0:cen_x[0], 1:cen_x[1], 2:cen_x[2]})
df['cen_y'] = df.cluster.map({0:cen_y[0], 1:cen_y[1], 2:cen_y[2]})# define and map colors
colors = ['#DF2020', '#81DF20', '#2095DF']
df['c'] = df.cluster.map({0:colors[0], 1:colors[1], 2:colors[2]})#####PLOT#####
from matplotlib.lines import Line2Dfig, ax = plt.subplots(1, figsize=(8,8))
# plot data
plt.scatter(df.Attack, df.Defense, c=df.c, alpha = 0.6, s=10)# create a list of legend elemntes
## markers / records
legend_elements = [Line2D([0], [0], marker='o', color='w', label='Cluster {}'.format(i+1),
markerfacecolor=mcolor, markersize=5) for i, mcolor in enumerate(colors)]# plot legend
plt.legend(handles=legend_elements, loc='upper right')# title and labels
plt.title('Pokemon Stats\n', loc='left', fontsize=22)
plt.xlabel('Attack')
plt.ylabel('Defense')
散点图—作者提供的图片
酷,现在我们可以清楚地了解这个图表是关于什么的了。
我们也可以给观众一些参考点。显示质心并画出平均值或百分位数的参考线有助于解释我们的聚类。
from matplotlib.lines import Line2Dfig, ax = plt.subplots(1, figsize=(8,8))
# plot data
plt.scatter(df.Attack, df.Defense, c=df.c, alpha = 0.6, s=10)
# plot centroids
plt.scatter(cen_x, cen_y, marker='^', c=colors, s=70)# plot Attack mean
plt.plot([df.Attack.mean()]*2, [0,200], color='black', lw=0.5, linestyle='--')
plt.xlim(0,200)# plot Defense mean
plt.plot([0,200], [df.Defense.mean()]*2, color='black', lw=0.5, linestyle='--')
plt.ylim(0,200)# create a list of legend elemntes
## average line
legend_elements = [Line2D([0], [0], color='black', lw=0.5, linestyle='--', label='Average')]
## markers / records
cluster_leg = [Line2D([0], [0], marker='o', color='w', label='Cluster {}'.format(i+1),
markerfacecolor=mcolor, markersize=5) for i, mcolor in enumerate(colors)]
## centroids
cent_leg = [Line2D([0], [0], marker='^', color='w', label='Centroid - C{}'.format(i+1),
markerfacecolor=mcolor, markersize=10) for i, mcolor in enumerate(colors)]
# add all elements to the same list
legend_elements.extend(cluster_leg)
legend_elements.extend(cent_leg)
# plot legend
plt.legend(handles=legend_elements, loc='upper right', ncol=2)# title and labels
plt.title('Pokemon Stats\n', loc='left', fontsize=22)
plt.xlabel('Attack')
plt.ylabel('Defense')
散点图—作者提供的图片
现在很容易分辨出集群是如何划分的。
红色组的攻击和防御值最高,而蓝色组最低,绿色组通常更接近平均值。
线
说明我们的集群工作与其结果一样重要。在 k-means 中,由于我们正在处理距离,将点连接到它们各自的质心可以帮助我们可视化算法实际在做什么。
fig, ax = plt.subplots(1, figsize=(8,8))
# plot data
plt.scatter(df.Attack, df.Defense, c=df.c, alpha = 0.6, s=10)
# plot centroids
plt.scatter(cen_x, cen_y, marker='^', c=colors, s=70)
# plot lines
for idx, val in df.iterrows():
x = [val.Attack, val.cen_x,]
y = [val.Defense, val.cen_y]
plt.plot(x, y, c=val.c, alpha=0.2)# legend
legend_elements = [Line2D([0], [0], marker='o', color='w', label='Cluster {}'.format(i+1),
markerfacecolor=mcolor, markersize=5) for i, mcolor in enumerate(colors)]
legend_elements.extend([Line2D([0], [0], marker='^', color='w', label='Centroid - C{}'.format(i+1),
markerfacecolor=mcolor, markersize=10) for i, mcolor in enumerate(colors)])legend_elements.extend(cent_leg)
plt.legend(handles=legend_elements, loc='upper right', ncol=2)# x and y limits
plt.xlim(0,200)
plt.ylim(0,200)# title and labels
plt.title('Pokemon Stats\n', loc='left', fontsize=22)
plt.xlabel('Attack')
plt.ylabel('Defense')
连通散点图—图片由作者提供
现在,聚类和质心之间的关系已经完全清楚了,也更容易解释算法是如何工作的。
我们还可以看到每个分类中的值是如何分布的。
例如,红色值看起来比蓝色值离其质心更远。如果组的方差对我们的分析很重要,这样的图表可能是有效的。
我们还应该注意到,绿色和蓝色之间的区别在之前的可视化中并不明显。
散点图—作者提供的图片
即使它们具有不同的颜色,并且连接到不同的位置,那些用黑色圈出的记录在它们之间仍然比它们自己的分类中的大多数值更相似。
这种可视化使人更难察觉到这一点,并可能给人以不同分类的值完全不同的印象。
凸包
另一个帮助我们可视化星团大小或分布的方法是在它周围画一个形状或一个阴影。手动这样做将花费很长时间,而且肯定不值得。
幸运的是,有一些方法可以实现自动化。
凸包是我们的数据点之间形成包围所有点的多边形的最小连接集,并且有系统地找到凸包的方法——也就是说,我们可以使用 Sklearn 来获得我们数据集的轮廓。
from scipy.spatial import ConvexHull
import numpy as npfig, ax = plt.subplots(1, figsize=(8,8))
# plot data
plt.scatter(df.Attack, df.Defense, c=df.c, alpha = 0.6, s=10)
# plot centers
plt.scatter(cen_x, cen_y, marker='^', c=colors, s=70)# draw enclosure
for i in df.cluster.unique():
points = df[df.cluster == i][['Attack', 'Defense']].values
# get convex hull
hull = ConvexHull(points)
# get x and y coordinates
# repeat last point to close the polygon
x_hull = np.append(points[hull.vertices,0],
points[hull.vertices,0][0])
y_hull = np.append(points[hull.vertices,1],
points[hull.vertices,1][0])
# plot shape
plt.fill(x_hull, y_hull, alpha=0.3, c=colors[i])
plt.xlim(0,200)
plt.ylim(0,200)
突出显示的散点图-图片由作者提供
太好了。我们甚至可以插入多边形的线条,使数据周围的形状更加平滑。
from scipy import interpolatefig, ax = plt.subplots(1, figsize=(8,8))
plt.scatter(df.Attack, df.Defense, c=df.c, alpha = 0.6, s=10)
plt.scatter(cen_x, cen_y, marker='^', c=colors, s=70)
for i in df.cluster.unique():
# get the convex hull
points = df[df.cluster == i][['Attack', 'Defense']].values
hull = ConvexHull(points)
x_hull = np.append(points[hull.vertices,0],
points[hull.vertices,0][0])
y_hull = np.append(points[hull.vertices,1],
points[hull.vertices,1][0])
# interpolate
dist = np.sqrt((x_hull[:-1] - x_hull[1:])**2 + (y_hull[:-1] - y_hull[1:])**2)
dist_along = np.concatenate(([0], dist.cumsum()))
spline, u = interpolate.splprep([x_hull, y_hull],
u=dist_along, s=0, per=1)
interp_d = np.linspace(dist_along[0], dist_along[-1], 50)
interp_x, interp_y = interpolate.splev(interp_d, spline)
# plot shape
plt.fill(interp_x, interp_y, '--', c=colors[i], alpha=0.2)
plt.xlim(0,200)
plt.ylim(0,200)
*插值方法基于来自此线程的回复。
- *正如 Dragan Vidovic 在评论中指出的,我已经将参数 per=1 添加到了
splprep
函数中。
突出显示的散点图-图片由作者提供
我们不应该把这些轮廓看得太重,因为它们不是实际的测量值。但是它们仍然很好地突出了星团,所以没有观众会错过它们。
总的来说,没有简单的方法来可视化集群。每个案例都是独特的,在决定向公众展示什么之前,我们应该做大量的实验。
提到我使用的例子是干净的也很重要。我使用一个简单的数据集和两个变量进行聚类。真实情况下,不会一直是这个样子。通常,画出质心的连线会使我们的图表污染太严重,几乎无法阅读。
最好从简单的事情开始:想象变量的每一个组合,找出更有意义的或者你可以自然展示你的洞察力的变量。然后你可以尝试其他的可视化和技术来突出你的发现。
我希望你学到了一些东西,喜欢我的文章。谢谢!
更多教程 | 酷炫玩意儿 | 推特
使用 pycohort 软件包可视化群组保持率
罗伯特·卡茨基在 Unsplash 上的照片
关于如何在 PyPi 上创建 Python 包的教程
订阅业务的主要收入来源是定期支付。可能会有额外的一次性服务,但选择额外收费的用户数量有限,这个数字将更难预测。这就是为什么订阅业务的财务健康状况最好用留存率来衡量。如果用户对产品或服务满意,他们可能会一直呆到他们的需求改变。这就是为什么应用程序中有什么样的保留功能以及如何呈现给用户非常重要,特别是那些正在进入取消漏斗以结束重复支付周期的用户。
为了以更详细的格式快速可视化保留率,企业利用基于时间的群组分析。群组由在特定时间范围内注册的用户组成,该时间范围可能具有从每周到每季度的粒度。对于每个群组,在每个时间段计算保留客户的百分比,直到最近一次。
如何阅读基于时间的队列分析图表?
以下是基于时间的群组分析图表示例。用户根据他们的订阅开始月份被分组。每一行代表一群用户。对于每个群体,第一栏中有一个初始保留率。这是在订阅开始日期后一个月仍未离开的用户的百分比。每行的比率代表订阅旅程中给定月份的保留率。这些比率是基于某个月之后剩余的用户数量除以开始时给定群组中的所有用户数量来计算的。让我们以 2020 年 1 月注册的用户群体为例。订阅开始两个月后,75%的订阅者仍然在那里。也就是说,前两个月的流失率是 25%。由于数据拉动将于 2021 年 4 月结束,这一群体还有 16 个月的时间。16 个月后,仍有 44%的用户订阅。(由于这是一个人工数据集,数字可能会高于真实案例的预期。)
基于时间的队列分析
这个观点能概括关于保留的一切吗?
不要!该图表总结了每个群组在订阅过程中特定时期的保留率。但重要的是要记住,这些只是利率。在没有看到分子和分母的情况下,我们不应该对一家公司的未来是否处于危险之中妄下结论。可能会有新的服务增加门户网站的流量,从而增加订阅数量并增加收入,因此这是非常可取的,但费率可能会显示不同的趋势。尽管数量有所增加,但用户流失的速度可能会更快。这就是为什么这种可视化只能呈现业务的局部视图,如果单独使用可能会产生误导!
如何为我的公司创建类似的图表?
为了回答这个问题,我构建了一个名为 pycohort 的 python 包。要使用这个包,数据需要有特定的格式。否则,无法使用这些功能。首先,由用户创建的每个订阅需要有一个惟一的标识符,这个标识符需要被称为id
。然后需要在creation_date
字段中输入每个订阅的开始日期。metric_month
为订阅活动的每个月添加一列。这就是为什么每活跃一个月,就会有一个新的数据点。订阅最后激活的日期需要在last_active_month
字段中。这不一定等于取消月。如果订阅仍然有效,那么last_active_month
将等于最近的月份。所需的最后一列是active_duration
,它是在creation_date
和last_active_month
之间花费的时间。
数据帧的格式需要加载到 pycohort 函数中
在这样的数据格式中,可能会有重复。例如,对于在 2020 年 3 月创建并在 2020 年 5 月取消的订阅,将有三行:第一行的metric_month
等于 2020 年 3 月,第二行的metric_month
等于 2020 年 4 月,第三行的metric_month
等于 2020 年 5 月。
在确保数据格式正确后,有 5 个函数可用来了解保留情况。前三个是计算平均值,中位数和标准差。这三个主要用于active_duration
字段。下一个函数叫做cohort_preprocess
。在这个函数中,上面解释的数据帧格式被转换成一个矩阵,在这个矩阵中计算每个周期中不同群组的保持率。最后一个函数cohort_viz
将cohort_preprocess
的输出作为输入,并打印群组分析可视化。
# to download the package:
!pip install pycohort# importing necessary functions from the package
from pycohort import calculate_stdev
from pycohort import calculate_mean
from pycohort import calculate_median
from pycohort import calculate_stdev
from pycohort import calculate_stdev# calculating mean
calculate_mean(df.active_duration)
>>> 13.315# calculating median
calculate_median(df.active_duration)
>>> 12# calculating standard deviation
calculate_stddev(df.active_duration)
>>> 7.256# printing the visualization
cohort_viz(cohort_preprocess(df))
群组预处理函数的输出
如何将所有功能捆绑在一个 python 包中?
在发布这段代码之前,我创建了一个名为 pycohort 的工作目录。在那个文件夹下,有一个 readme.md,setup.py,license.txt,还有一个叫 pycohort 的文件夹。在 setup.py 下,作者需要输入与包相关的具体信息,如下所示。请注意这个包的名字不能被其他开发者使用。同样,如果你想上传一个新的版本,你需要迭代这个版本。正如你所看到的,我花了几个版本来调整代码,添加注释和提高包的效率。
# content of setup.py for pycohort
from setuptools import setupsetup(name='pycohort',
version='2.6',
description='pycohort package',
url='[https://github.com/demirkeseny'](https://github.com/demirkeseny'),
author='Yalim Demirkesen',
[author_email='yalimdemirkesen@gmail.com](mailto:author_email='yalimdemirkesen@gmail.com)',
license='MIT',
packages=['pycohort'],
zip_safe=False)
在工作目录的 pycohort 文件夹下有两个文件。init。py,它通知用户如何导入包,还有 pycohort.py,上面提到的所有函数都存储在这里。
# content of __init__.py for pycohort
from .pycohort import calculate_mean
from .pycohort import calculate_stdev
from .pycohort import calculate_median
from .pycohort import cohort_preprocess
from .pycohort import cohort_viz
最终的文件布局如下所示:
这些文件需要上传到哪里以及如何上传?
下一步是上传我们的文件,以便其他人可以安装它们。我们将上传我们的包的站点叫做 PyPi 。当你通常使用pip install
下载任何 python 包时,你从 PyPi 中拉出文件夹。最佳实践是首先尝试将您的包上传到 test PyPi 中,这是 PyPi 的一个测试库。如果顺利的话,我们可以把所有东西上传到 PyPi。为了上传我们的文件,我们需要在 test PyPi 和 PyPi 上创建一个帐户。
一旦每个文件都准备好了,帐户也创建好了,我们需要使用cd
命令导航到 pycohort 所在的工作目录。然后我们需要运行python setup.py sdist
。这个命令将向我们的存储库添加两个额外的文件,这样我们的包就可以上传到 PyPi,也可以从 PyPi 下载。接下来,我们需要下载twine
包,将我们的文件推送到 PyPi 存储库。然后我们可以上传我们的包来测试 PyPi,并尝试从测试存储库中下载它。如果上传到测试 PyPi 时没有问题,我们可以转移到常规的 PyPi。您可以在下面找到所有必要的代码:
# navigate to pycohort working directory:
cd pycohort# download the necessary files to upload your package:
python setup.py sdist# install twine package:
pip install twine# upload package to test PyPi:
twine upload --repository-url https://test.pypi.org/legacy/ dist/*# install from test PyPi:
pip install --index-url https://test.pypi.org/simple/ pycohort# upload package to PyPi:
twine upload dist/*# install from test PyPi:
pip install pycohort
结论
如果您想要直观显示不同群组的保留趋势,这种基于时间的群组分析是一个完美的选择。一旦你的数据是上面解释的格式,那么使用 pycohort 包就更容易了。
在对这张图表做出任何决定之前,请记住,这种可视化是基于没有反映分子或分母突然变化的比率。
请点击这里找到 Github repo ,点击这里找到 PyPi 链接,获得关于软件包和功能的更详细的视图。
特别感谢 Gunsu 阿尔丁达格所有的灵感!
用 Python 可视化新冠肺炎疫苗数据(5 个简单步骤)
让您的 MatPlotlib 图形脱颖而出
让你的 Matplotlib 可视化更加漂亮!资料来源:Nik Piepenbreier
Matplotlib 是 Python 中最常用的数据可视化库之一。然而,它的默认设置会导致单调乏味的图形。本快速教程将指导您使用一些技巧和窍门来设计更漂亮的 Matplotlib 图。
你会做什么!
我们将从我们的数据世界中获取一些新冠肺炎疫苗数据,并用它将我们最初的、枯燥的 Matplotlib 可视化变成更漂亮的东西。
你的开始和结束。资料来源:Nik Piepenbreier
我们开始吧!
我们将从加载所需的库开始。不要被长长的导入列表吓倒——在整个教程中,我将逐一介绍每个导入的细节:
如果你在 Jupyter 笔记本上跟随,确保包含%matplotlib inline
Jupyter magic,让你的图表在线显示。
加载我们的数据帧
我们将使用 Pandas 的.read_csv()
方法加载我们的数据帧。好的一面是,随着数据的更新,您的绘图将通过简单的重新运行进行更新。
让我们看看我们在这里做了什么:
在步骤 1 中,我们加载数据,让 Pandas 知道只加载列的子集(date
、location
、total_vaccinations_per_hundred
),并将date
作为日期时间值读取。
- 我们还创建了一个包含不同国家的列表。如果您希望您的可视化显示其他国家,只需确保它们与数据框中的可用内容相匹配。
提示:您可以通过使用 print(df[‘location’]找到 location 中使用的国家名称。唯一())
然后,我们过滤数据框架,只包括这些国家,这样我们的可视化就不会被太多的国家弄乱。
汇总数据
在步骤 2 中,我们使用一个简单的数据透视表汇总数据。如果你想了解熊猫的数据透视表,点击这里查看我的 YouTube 视频。
- 最后,我们填充缺失的值。不幸的是,数据中分散着一些缺失值。我们使用
method='ffill'
参数向前填充任何丢失的值以获得最佳估计。
创造我们的视觉化
让我们开始创建我们的可视化!这有点复杂,但我会一步一步地教你:
在步骤 3 中,我们设置了一些辅助变量。我们想突出我们的main_country
,在这个例子中是美国。如果您想突出显示另一个国家,只需用另一个国家(您已经在步骤 1 中过滤到数据框中)替换掉该字符串。
然后,我们使用两种字典理解将所有国家指定为灰色,透明度为 0.75,除了main_country
,它被指定为深青色,没有透明度。要了解更多关于字典理解和它们是如何工作的,请查看这个教程。
在步骤 4 中,我们做了很多,所以让我们来分解一下!
- 我们举例说明一个图形和一个大小为 12x8 的轴
- 然后,我们循环遍历 countries 变量中的每个国家,分别绘制每条线。我们使用指数(我们的日期)作为 x 值,使用接种疫苗的人口比例作为 y 值。我们从步骤 3 中创建的字典中提取颜色和透明度。
- 然后,我们将文本添加到我们的绘图中,以直接在线上显示国家的标签。我们使用
timedelta
函数将索引的最后一个值增加 2 天,以在行尾和文本开始处之间创建一点缓冲。 - 我们可以使用
.max()
值来表示每个国家的值,因为这个比例只会越来越大。 - 最后,我们传入国家的名称作为要使用的字符串,并使用字典传入颜色和透明度,就像我们传入行本身一样。
第 5 步也有点复杂,所以我把它分成了几个子步骤。
- 对我来说,A 部分是最复杂的。我们使用
DateFormatter
将日期格式化为 YYYY-MM-DD 格式。然后我们使用.set_major_locator()
告诉 Matplotlib 使用什么作为刻度标记,传入WeekdayLocator
作为参数,表示我们希望使用第一个工作日作为刻度。然后,我们将标签旋转 45 度,并将 y 轴限制在 0 到 100 之间。 - 在B 部分中,我们移除了顶部和右侧的脊线,并降低了左侧和底部脊线的对比度。我们还添加了一个微妙的网格。
- 在C 部分中,我们添加了描述性轴标签和标题。
- 最后,我们在d 部分展示剧情
运行此代码会返回以下视觉效果:
我们最后的视觉化。图片作者:Nik Piepenbreier
结论
在这篇文章中,我们学习了如何使用新冠肺炎数据集生成漂亮的数据可视化。我们可以利用 Python 的强大功能,根据今天的数据自动更新我们的图表。
如果你想了解更多关于 Matplotlib 的内容,可以查看我在 YouTube 上不断增加的播放列表:
如果你想订阅我的频道,请点击下面的按钮!
点击此处订阅(图片由 stickpng.com 提供)
想象洛杉矶的犯罪
影响犯罪的因素有哪些?一天中的什么时候?星期几?
洛杉矶是全球特大城市之一。这个大都市每年都吸引成千上万像我一样的学生。2021 年 8 月,我将搬到洛杉矶,在南加州大学(USC)学习数据科学。自从我做出决定后,朋友、家人和其他洛杉矶人一再提醒我,这个地区可能不是最安全的。因此,我决定在 2021 年期间对洛杉矶的犯罪本质进行一次知情的调查,以确保我在这座城市的这段时间里做出明智的、由数据驱动的决定。
让我印象深刻的一件事是,LAPD 提供的犯罪数据在埃里克·加希提市长的网站上随时可供公众使用。即使在当今开放的数据世界中,这也是相对罕见的。无论如何,让我们深入这个庞大的数据集,收集一些重要的见解。
在探索和清理数据以进行适当的分析后,我想看看这个城市中最常见的犯罪类型。
2021 年,截至 6 月,洛杉矶市记录了超过 79,000 起犯罪案件。“偷车”占所有犯罪的 11%以上,高居榜首。“自行车失窃”占所有犯罪的 1%。作为一名学生,我很可能每天骑自行车去大学,因此看到如此高的自行车被盗数量令人震惊。
好了,我们现在知道了什么类型的犯罪比其他类型的犯罪发生得更频繁,但是这些犯罪是什么时候发生的呢?他们是遵循特定的时间模式,还是一周中的某一天比其他时间承担更多的案件?
上面的树形图给了我们一些相当有用的见解:周末很麻烦!周五累积了全年最多的犯罪案件,随着新一周的开始,案件数量减少了近 1500 起。周五的高峰很可能是由于周末的到来,更多的人外出社交和聚会,导致深夜外出,这是犯罪发生的最大可能。就洛杉矶的犯罪而言,周二和周三是最平静的。
一天中的时间在犯罪中也起着重要的作用。我在下面绘制了一张图表,其中我们以 24H 格式显示了一天中的时间与犯罪数量的关系。
凌晨 5 点左右,当城市的大部分人都在睡觉时,犯罪率就下降了。这是非常期待的。我还预计在傍晚 6 点左右会出现一个高峰,这时人们下班回家或者出去享受夜晚。令我惊讶的是,中午的时候几乎达到了峰值。看看在这几个小时里会发生什么类型的犯罪会很有趣。我预测这些犯罪属于“软性”类型,包括毒品违法、盗窃和财产犯罪。
正如我所预测的,左上方的表格清楚地告诉我们,财产犯罪和入室盗窃是最常见的犯罪类型,在中午我们会看到每天的高峰。
尽管这些犯罪是频繁和令人不安的,但由于犯罪的性质,这仍然是一个相对安全的外出时间。然而,如果与一天中晚些时候(大约晚上 7 点)的类似高峰相比,情况就不同了。
随着太阳落山,攻击性犯罪的数量显著上升。致命袭击上升到令人震惊的 294 起,而对伴侣的袭击也在增加。“软”犯罪也有所上升,被盗车辆数量几乎是中午的两倍。
虽然这提供了关于一天中什么时间更安全的有价值的见解,但我仍然不完全满意。这里还需要考虑其他因素,比如犯罪率高的地区。更重要的是,我想知道犯罪在南加州大学大学公园校区的分布情况,在接下来的两年里,我将在这里度过大部分时间。首先,我绘制了周边地区的犯罪分布图。该数据集通过地理坐标提供犯罪现场位置,这使得在 Tableau 中绘图变得简单。
标记的不透明度描绘了彼此靠近的单个犯罪地点,因此形成了该区域中犯罪数据点的聚类。哪里的标记暗,哪里就有频繁的犯罪麻烦。校园东侧的 Figueroa 街有多个集群,表明那里的犯罪率较高。我是一个狂热的跑步者,我们获得的时间和地点信息帮助我计算出合适的跑步时间和潜在的安全跑步路线!让我们继续探索。南加州大学地区的犯罪类型呢?
“车辆被盗”仍然是最常见的犯罪类型,该地区似乎有很多破坏和盗窃行为。《致命武器袭击》进入了前 7 名,不过我想看看它在“高峰”犯罪时段,即正午和黄昏的表现。
当“一天中的某个小时”过滤器应用于上表时,“致命武器袭击”在中午和晚上 7 点没有进入前 7 名。这让人放心,那么什么时候十恶不赦的犯罪最常见呢?
袭击犯罪在下午 4 点左右上升,在晚上 8 点和 11 点再次上升。在《安全》杂志的一篇报道中,攻击性犯罪在美国最有可能发生在晚上,我的情节也证实了这一点。同样,这个情节令人放心,并且帮助本文的读者在计划他们的一天时做出数据驱动的决定,如果他们碰巧住在洛杉矶地区的话。
继续前进,随着洛杉矶成为不同文化和种族的大熔炉,我想看看某些人群是否比其他人更容易成为犯罪的受害者。
上述种族和受害者血统类别由 LAPD 在数据集中定义,并按原样转载。西班牙裔/拉丁裔/墨西哥裔人在这个城市的犯罪率最高,其次是白人和黑人。其他亚洲人排名第四。看了看洛杉矶的人口多样性数据,这些数字提供了一个可能的原因。49%的洛杉矶人口被归类为“西班牙裔/拉丁裔/墨西哥裔”。利用概率,人们可以确定人口分布是这两个种族在城市犯罪受害者排行榜上名列前茅的原因。(免责声明:由于缺乏可量化的数据,我在本文中没有考虑种族偏见等影响犯罪的因素。)
该市受害者的平均年龄为 29.82 岁,这表明相对年轻的人容易犯罪。为什么不看看按性别划分的犯罪数量呢?
该数据集按男性/女性/未知进行性别分类,因此不可能进行其他性别鉴定。尽管洛杉矶县的男女比例较高,但我们仍然看到更多的男性成为犯罪的受害者。根据 M E Lewyn 在《圣地亚哥司法杂志》上发表的一篇文章,男性更有可能成为暴力犯罪的受害者。在我们的例子中,我们已经通过上面的饼状图证明了这一点。
尽管南加州大学附近地区因“不安全”而闻名,尽管有数据支持这一说法,但对 LAPD 提供的数据集的进一步分析和研究得出的结论是,在一天中的特定时间,发生的犯罪比其他时间更严重。此外,随着周末的临近,与平日相比,更有可能发生犯罪。我们还知道南加州大学周围的哪些街道相对来说比其他街道更安全,以及哪些街道可以在“高峰”犯罪时段避开。虽然我周围的人对这个地方的担忧在一定程度上是合理的,但任何读过这篇文章的人都可以获得一些重要的见解,这些见解将使他们能够在日常生活中做出数据驱动的决策。只要负责任地去做,洛杉矶有很多值得享受和体验的东西。我期待着今年秋天和以后去体验加州的美丽!
免责声明:
- 上述文章中表达的所有观点都基于 LAPD 提供的数据集。
- 在发布时,Medium 不支持 Tableau 可视化的嵌入,因此我在标题中提供了原始可视化的 URL,读者可以应用更多的过滤器来查看他们喜欢的数据。
骚乱后宵禁期间 DC 实时交通可视化
流动性是城市的生命线。让我们用这里的交通流量/事故 API 来想象一下今天发生不幸的混乱之后,宵禁期间的 DC。
DC 的交通流量和事故。在 Kepler.gl |塞犍陀·维韦克创建的图表
不幸的是,今天的骚乱导致了混乱和生命损失。许多数据提供商免费提供实时详细信息,这对于应急人员和市民应对我们今天看到的突发事件非常有用。让我们深入研究一下使用这样一个 API 量化实时事件和流量数据的潜力。
谷歌地图在计算走哪条路线可以最大限度地减少旅行时间方面非常有用。然而,对于数据爱好者来说,它并不提供这些交通信息。TomTom,Waze,这里都是实时交通信息的提供者。就个人而言,我觉得这里最容易使用,它的免费 API 对于获取详细的交通信息非常有用,比如速度和事故。在之前的博客中,我讲述了如何使用 HERE traffic flow API 提取单个路段的交通速度:
在这里,我将说明如何提取交通事故数据,并将这里的速度/事故与谷歌地图的图像进行比较。
%matplotlib inline
import numpy as np
import requests
from bs4 import BeautifulSoup
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import XML, fromstring, tostringpage = requests.get('[https://traffic.api.here.com/traffic/6.2/incidents.xml?app_id=BLAH&app_code=BLAH2&bbox=38.92,-77.06;38.88,-77.00&responseattributes=sh,fc'](https://traffic.api.here.com/traffic/6.2/incidents.xml?app_id=EuBWKTOquw60Mdj8U9Tu&app_code=aEJDOiovLnfYhC6jcT_pkA&bbox=38.92,-77.06;38.88,-77.00&responseattributes=sh,fc'))
soup = BeautifulSoup(page.text, "lxml")incidents = soup.find_all('traffic_item')
您可以在这里注册以获得一个应用程序 id 以及证书的应用程序代码(以上示例中的 BLAH、BLAH2)。接下来,您需要一个边界框来获取流量/事件。为此,在谷歌地图上,你会看到纬度-经度对。您需要左上角和右下角的按钮来获取边界框的坐标。响应属性 fc 和 sh 非常重要,稍后可用于过滤高速公路、街道等。,但我不会在这篇文章中使用这些信息。最后一行给出了当时所有独特的事件。
myxml = fromstring(str(incidents[0]))
for child in myxml:
print(child.tag)traffic_item_id
original_traffic_item_id
traffic_item_status_short_desc
traffic_item_type_desc
start_time
end_time
entry_time
criticality
verified
abbreviation
rds-tmc_locations
location
traffic_item_detail
traffic_item_description
traffic_item_description
traffic_item_description
查看第一个事件,有 16 个标签包含有用的事件信息,如事件开始和结束的时间、描述和位置。目前,我只对事件发生的地点感兴趣。事实证明,这并不像交通速度那样简单。但是稍微调查了一下,我发现它隐藏在位置标签中。
myxml = fromstring(str(incidents[0]))
for child in myxml:
if (child.tag==’location’):
for chelds in child:
print(chelds.tag,chelds.attrib)intersection
geoloc
political_boundary
navtech
length
最后,我发现了隐藏在地理标签中的事件的来龙去脉:
incidents[0].location.geoloc<geoloc><origin><latitude>38.88507</latitude><longitude>-77.01081</longitude></origin><to><latitude>38.88602</latitude><longitude>-77.01051</longitude></to><geometry><shapes><shp fc="5" fw="SD" le="0.042374034341961575" lid="1186813844F">38.88507,-77.01081 38.88544,-77.01069</shp><shp fc="5" fw="SD" le="0.06625476521319096" lid="1254739814F">38.88544,-77.01069 38.88602,-77.01051</shp></shapes></geometry></geoloc>
您还可以查看存在哪些类型的事件。在 2021 年 6 月 1 日晚上 9 点左右,DC 总共发生了 173 起事故。所有这些都被描述为道路封闭或有计划的活动。以下是前 10 个。注意:这里的时间显然不是美国东部时间。可能是格林威治时间,虽然我现在还不确定。
for inc in incidents:
print(inc.start_time.text, inc.end_time.text,inc.traffic_item_type_desc.text)12/15/2020 15:46:16 02/15/2023 17:00:00 ROAD_CLOSURE
01/06/2021 21:46:56 01/07/2021 21:45:44 ROAD_CLOSURE
01/06/2021 22:52:32 01/07/2021 22:52:07 ROAD_CLOSURE
12/15/2020 15:46:16 02/15/2023 17:00:00 ROAD_CLOSURE
01/06/2021 21:46:56 01/07/2021 21:45:44 ROAD_CLOSURE
12/15/2020 15:46:16 02/15/2023 17:00:00 ROAD_CLOSURE
01/06/2021 23:04:11 01/07/2021 23:01:47 ROAD_CLOSURE
12/15/2020 15:46:16 02/15/2023 17:00:00 ROAD_CLOSURE
12/15/2020 15:46:16 02/15/2023 17:00:00 ROAD_CLOSURE
01/06/2021 23:04:11 01/07/2021 23:01:47 ROAD_CLOSURE
最后,这里是 here 交通速度/事件与谷歌地图承诺的视觉对比:
左边是谷歌地图,右边是华盛顿 DC |塞犍陀·维韦克的数据
有一些有趣的区别。这里有更多的事件和更多的速度数据在一些较小的路段。否则,在没有谷歌地图数据的情况下,很难直观地识别速度有多相似/不同。还有,我不确定谷歌地图是如何通过颜色来识别自己的速度的。谷歌地图有 4 种颜色,从慢到快(暗红色、红色、黄色、绿色)。我在这里制作了一个类似的彩色地图,其中道路颜色根据相对于速度限制的速度进行分段:0-0.25,0.25-0.5,0.5-0.75,0.75-1(0 对应于平均速度为 0 英里/小时,1 代表速度限制)。
这里有一个获取实时信息的绝佳资源,你无法从谷歌地图上获得。此外,这里似乎有更详细的小路段交通信息,他们声称是世界第一的定位平台,相当大胆的说法。唯一的缺点是他们没有可用的历史交通数据——但希望这是未来的选择。
正如我们今天所看到的,有时一群人会以以前不可想象的方式集体行动,并造成巨大的伤害。当这种情况发生时,我们需要对不断演变的地貌有一个准确的了解。今天的事件表明,DC 政府对抗议的规模和国会大厦被渗透的突然性毫无准备。
与其他实时数据源集成的实时交通数据,包括社交媒体消息,如推文;作为社会的脉搏。这些数据提供了强大的、可操作的信息,执法部门、应急响应人员甚至市民等城市利益相关者可以利用这些信息来正确评估情况的严重性,并在时间至关重要的情况下做出关键决策。
如果你喜欢这篇文章,请关注我——我经常在复杂系统、物理学、数据科学和社会的界面上写作
用 Pybaobabdt 可视化决策树
实践教程
一个用于决策树可视化和模型解释的开源包
数据可视化是决策的语言。好的图表有效地传达信息。伟大的图表使决策成为可能,提供信息,并改善决策: 但丁·维塔利亚诺
决策树可以以多种方式可视化。以缩进节点为例,其中每个内部节点和叶节点都被描述为文本,而父子关系是通过相对于父节点缩进子节点来显示的。
缩进图|作者图片
然后是**节点-链路图。**这是可视化决策树最常用的方法之一,决策树中的节点通过字形表示,父节点和子节点通过链接连接。
节点链接图|作者图片
冰柱图图是同样的另一个选项。除了显示关系,这些图还有助于描述节点大小。他们的名字来源于这样一个事实,即最终的可视化看起来像冰柱。
由 https://www . cs . middlebury . edu/~ can drews/showcase/infovis _ techniques _ s16/icicle _ plots/icicle plots . html| CC-经许可
虽然这些技术很有帮助,但是它们不能很好地扩展,尤其是当数据量增加时。在这种情况下,不仅可视化数据变得困难,而且解释和理解树也是一个挑战。 BaobabView 是一个为解决这类问题而创建的库,在本文中,我们将通过例子详细介绍它的 python 实现 pybaobabdt 。
绘制决策树的几个软件包
我们通过讨论可视化决策树的多种方式开始了这篇文章。查看各种帮助绘制决策树的库也是值得的。
资料组
这里我们将使用帕尔默企鹅数据集作为公共数据集。这是一个众所周知的数据集,通常是 iris 数据集的替代物,目标是根据给定的特征预测企鹅种类。
数据集|图像的前五行(按作者)
1\. Visualization using [sklearn.tree](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.tree)
。绘图树
这是默认的方式,也是最常用的方法。它是 scikit-learn 的默认选项。
Visualization using [sklearn.tree](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.tree)
。plot_tree |作者图片
在这个例子中,树的max_depth
被限制为 3。
Visualization using [sklearn.tree](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.tree)
。plot_tree |作者图片
2.Visualization using
达特里维兹
dtreeviz 库提供了更好的外观和直观的可视化,同时提供了更好的可解释性选项。图书馆的灵感来源于r2d 3的教育动画;* 机器学习视觉入门 。*
链接到文章 : 用 dtreeviz 库可视化决策树的更好方法
Visualization using
dtreeviz |作者图片
Visualization using
作者图片
3.张量流决策森林
TensorFlow 决策森林是为训练、服务、推理和解释这些决策森林模型而创建的库。它为基于树的模型和神经网络提供了统一的 API。TensorFlow 决策森林具有内置的交互式绘图方法来绘制和帮助理解树结构。
链接到文章 : 回顾 TensorFlow 决策森林库
Visualization using
张量流决策森林(TF-DF) |图片由作者提供
张量流决策森林(TF-DF) |图片由作者提供
镇上的新成员
一篇名为 猴面包树视图:决策树的交互式构建和分析 的论文展示了一种可视化决策树的独特技术。这种技术不仅可扩展,而且使专家能够将他们的领域知识注入到决策树的构造中。该方法被称为 BaobabView 和依赖于可视化、交互和算法支持这三个关键方面。
BaobabView 的三个关键方面:可视化、交互和算法支持|作者图片
以下是这篇论文的摘录,具体强调了这一点:
我们认为我们的工具提供了一个可视化分析方法的双重例子。我们展示了如何使用交互和可视化来增强机器学习方法;我们还展示了人工构建和分析是如何得到算法和自动化支持的。
名字里有什么?
你想知道这个奇怪的名字吗?这个词源于 非洲猴面包树 或 非洲猴面包树 ,因为它与树的结构惊人地相似。
荷兰阿纳姆的费迪南·勒乌斯, CC BY-SA 2.0 ,通过维基共享
pybaobabdt 包是 BaobabView 的 python 实现。现在让我们从这个库的安装开始,稍微深入一点这个库的细节。
装置
该软件包可以按如下方式安装:
pip install pybaobabdt
但是,需要满足一些要求:
- Python 版本≥ 3.6
- PyGraphviz
- 还应该安装像 sklearn、numpy、pygraphviz、matplotlib、scipy、pandas 这样的流行 python 包。
我在安装pygraphviz
的时候经历了几次打嗝。如果您面临同样的问题,请参考随附的代码笔记本。
Pybaobabdt 在行动
我们将继续我们的企鹅数据集,并建立一个决策树,根据给定的特征预测企鹅物种。
from sklearn.tree import DecisionTreeClassifier
y = list(df['Species'])
features = list(df.columns)
target = df['Species']
features.remove('Species')
X = df.loc[:, features]clf = DecisionTreeClassifier().fit(X,y)
上面的代码初始化并训练一个分类树。一旦完成,下一个任务就是使用pybaobabdt
包来可视化树,这只需要一行代码就可以完成。
ax = pybaobabdt.drawTree(clf, size=10, dpi=300, features=features, ratio=0.8,colormap='Set1')
使用 Pybaobabdt 软件包可视化决策树分类器|图片由作者提供
这就对了。你有一个决策树分类器,每一类物种用不同的颜色表示。在随机森林的情况下,也可以可视化单个的树。然后,这些树可以保存为更高分辨率的图像,以便进行深入检查。
自定义
pybaobabdt 库也提供了许多定制。我将在这里展示其中的一些:
彩色地图
pybaobabdt 支持所有 matplotlib 颜色映射。我们已经看到了Set1
色图的样子,但是你可以从许多不同的选项中选择。以下是它们在使用时出现的次数:
使用 Pybaoabdt 和不同的颜色图进行决策树可视化|图片由作者提供
但是您并不局限于可用的色彩映射表。你甚至可以自己定义一个。假设我们只想突出显示数据集中的一个特定类,而将所有其他类置于背景中。我们可以这样做:
from matplotlib.colors import ListedColormapcolors = ["green", "gray", "gray"]
colorMap = ListedColormap(colors)ax = pybaobabdt.drawTree(clf, size=10, features=features, ratio=0.8,colormap=colorMap)
仅突出显示决策树中的特定类别|作者图片
比例
比率选项用于设置树的比率,默认值为 1。下面是这两个比率的比较,以及它们在屏幕上的显示方式。
ax = pybaobabdt.drawTree(clf, size=10, dpi=300, features=features, ratio=0.5,colormap='viridis')
不同的比例如何影响体型|作者图片
最大深度=3
参数maxdepth
控制树的深度。较低的数字限制了树的分裂,也显示了顶部分裂。如果上述树的max_depth
设置为 3,我们将得到一个发育不良的树:
ax = pybaobabdt.drawTree(clf, size=10, maxdepth = 3,features=features, ratio=1,colormap='plasma')
调整树的最大深度以控制树的大小|图片由作者提供
保存图像
输出图形可以保存如下:
ax.get_figure().savefig('claasifier_tree.png', format='png', dpi=300, transparent=True)
结论
pybaobabdt 包为可视化提供了一个新的视角。它包括了在它的对应物中没有见过的特征。主要思想是通过有意义的可视化来帮助用户理解和解释树。本文使用了一个简单的例子来演示这个库。然而,将它用于更广泛和更复杂的数据集,以了解它在实际意义上的优势,这将是一个很好的练习。我将把它留给读者做练习。
参考资料和进一步阅读:
可视化降维
使用 UMAP 进行降维
来源:作者
在处理大型数据集时,降维是最重要的方面之一,因为它有助于将数据转换到较低的维度,以便我们可以识别一些重要的特征及其属性。它通常用于避免在分析大型数据集时出现的维数灾难。
当我们进行数值分析或创建机器学习模型时,处理高维数据可能会很困难。使用高维数据集会导致高方差,并且模型不会被一般化。如果我们降低维度,我们可以使机器学习模型更加一般化,并避免过度拟合。
UMAP 是一个开源的 Python 库,有助于可视化降维。
在本文中,我们将探索 UMAP 提供的一些功能。
让我们开始吧…
安装所需的库
我们将从使用 pip 安装 UMAP 库开始。下面给出的命令可以做到这一点。
!pip install umap-learn
导入所需的库
在这一步中,我们将导入加载数据集和可视化降维所需的库。
import umap
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline
正在加载数据集
在本文中,我们将使用从 Github 获取的著名的 Palmer Penguins 数据集。
penguins = pd.read_csv("https://github.com/allisonhorst/palmerpenguins/raw/5b5891f01b52ae26ad8cb9755ec93672f49328a8/data/penguins_size.csv")
penguins.head()
加载数据集后,我们将从删除空值开始,并使用 UMAP 创建一个 reducer 对象。该缩减器将用于维度缩减,并进一步用于可视化。
penguins = penguins.dropna()
penguins.species_short.value_counts()
reducer = umap.UMAP()
penguin_data = penguins[
[
"culmen_length_mm",
"culmen_depth_mm",
"flipper_length_mm",
"body_mass_g",
]
].values
scaled_penguin_data = StandardScaler().fit_transform(penguin_data)
embedding = reducer.fit_transform(scaled_penguin_data)
绘制降维图
在这一步,我们将绘制降维图。
plt.scatter(embedding[:, 0], embedding[:, 1], c=[sns.color_palette()[x] for x in penguins.species_short.map({"Adelie":0, "Chinstrap":1, "Gentoo":2})])
plt.gca().set_aspect('equal', 'datalim')
plt.title('UMAP projection of the Penguin dataset', fontsize=24)
降维(来源:作者)
在这里,您可以清楚地看到企鹅数据集的维数减少。
继续尝试不同的数据集,执行降维,并使用 UMAP 绘制。如果您发现任何困难,请在回复部分告诉我。
本文是与 Piyush Ingale 合作完成的。
在你走之前
感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 。可以查看我的Github简介针对不同的数据科学项目和包教程。还有,随意探索 我的简介 ,阅读我写过的与数据科学相关的不同文章。
使用 t-SNE 和 PCA 可视化特征向量/嵌入
丹尼斯·库默在 Unsplash 上拍摄的照片
在学习机器学习或深度学习的基础知识的同时训练一个模型是一个非常受引导的过程。数据集已被很好地理解,并被充分格式化以供您使用。然而,当你步入现实世界,试图解决行业或现实生活中的挑战时,数据集通常是混乱的,如果一开始不存在的话。理解为什么你的模型不简单。没有具体的步骤引导你找到答案。然而,某些工具允许您调查并获得关于模型输出的更深入的见解。可视化是一个非常强大的工具,可以提供非常宝贵的信息。在这篇文章中,我将讨论两种非常强大的技术,可以帮助你在低维空间中可视化高维数据,以找到趋势和模式,即主成分分析和 t-SNE。我们将采用一个基于 CNN 的示例,并在测试数据集中注入噪声来进行可视化研究。
介绍
在深入研究如何使用这两种技术之前,我将简要介绍一下它们。
主成分分析[1]
PCA 是一种探索性工具,通常用于将大型复杂数据集简化为更小、更容易理解的数据集。它通过进行正交线性变换来实现这一点,该变换将数据转换到一个新的坐标系中,该坐标系以主成分的形式根据其方差内容进行排列,即您的高维相关数据被投影到一个具有线性独立基的较小空间中。第一个分量的方差最大,最后一个分量的方差最小。在原始空间中相关的特征在这个新的子空间中用线性独立或正交的基向量来表示。[注意:给定向量空间 V 的基集 B 包含的向量允许 V 中的每个向量唯一地表示为这些向量的线性组合[2]。PCA 的数学超出了本文的范围。]您可以将这些组件用于许多事情,但在本文中,我将使用这些组件来可视化特征向量或嵌入中的模式,我们通常从 2D/3D 空间中的神经网络的倒数第二层获得这些模式。
t-分布随机邻居嵌入(t-SNE) [2]
t-SNE 是一种强大的可视化技术,可以帮助发现低维空间中的数据模式。这是一种非线性降维技术。然而,与 PCA 不同,它涉及迭代优化,这需要时间来收敛,并且有一些参数可以调整。这涉及到两个主要步骤。首先,t-SNE 在高维对象对上构建概率分布,使得相似的对象被分配较高的概率,而不相似的对象被分配较低的概率。相似性是基于某个距离(例如欧几里德距离)来计算的。接下来,t-SNE 在低维空间中定义了类似的概率分布,并最小化了两个分布之间关于空间中点的位置的 Kullback-Leibler 散度(KL 散度)。KL 散度是一个统计工具,它允许你测量两个分布之间的相似性。当你用一个分布来近似另一个分布时,它会给你丢失的信息。因此,如果 KL 散度被最小化,我们会发现一个分布,它是相似和不相似物体的高维分布的一个很好的低维近似。这也意味着结果不会是唯一的,每次运行都会得到不同的结果。因此,在做出结论之前,多次运行 t-SNE 算法是一个好主意。
接下来,我将讨论我们将在本文中使用的分类数据集和体系结构。
使用 CNN 的 MNIST 分类
我想使用真实世界的数据集,因为我最近在工作中的一个项目中使用了这种技术,但由于 IP 原因,我不能使用该数据集。所以我们将使用著名的 MNIST 数据集[4]。(尽管它现在已经成为一个玩具数据集,但它已经足够多样化,可以展示这种方法。)
它总共由 70,000 幅手写数字图像组成。这些样本分为 60,000 个训练样本和 10,000 个测试样本。这些是 28x28 灰度图像。一些带有相应标签的随机样本如下所示。
来源:作者
我将使用一个小的 CNN 架构来执行分类并在 PyTorch 中构建它。该架构如下所示:
来源:作者
它由一个带有 16 个滤波器的 conv2d 层和两个完全连接的线性层组成。网络为每个图像输出 10 个值。我已经应用了最大池来减少特征尺寸。网络参数摘要如下所示。
来源:作者
我们看到,即使这个微小的网络也有 175k 个参数。这里需要注意的是,与全连接层相比,CNN 层的网络参数非常少。这些线性图层还会对网络的输入大小产生限制,因为它是针对 28x28 输入计算的,并且会针对其他输入大小更改其尺寸。这就是为什么我们不能将具有全连接层的预训练 CNN 模型用于与训练期间使用的维度大小不同的输入。除了最后一层,我在每一层之后都应用了 relu 激活。因为 PyTorch 中的交叉熵损失需要原始逻辑。它在内部应用 softmax。因此,在使用该特定功能时,请记住这一点。
对于训练,我使用具有默认设置的 Adam 优化器,并且模型被训练 20 个时期,并且基于最低验证损失保留最佳模型。通过查看 train 和 val 指标,我观察到了随着训练的进行过度拟合的趋势。我觉得给你看看可能是个好主意。
来源:作者
在整个训练过程中,我们看到训练损失呈下降趋势,训练准确率呈上升趋势。这意味着我们的模型复杂度对于我们的训练数据集来说是足够的。对于验证损失,我们看到直到第七个时期(步骤 14k)损失减少,然后损失开始增加。验证准确度经历了增加,然后也在接近结束时开始降低。想了解更多关于偏差-方差权衡、过拟合和欠拟合的内容,可以阅读本文:https://towardsdatascience . com/bias-variance-trade-off-7b 4987 DD 9795?sk = 38729126412 b 0 DC 94 ca 5 D2 a 9494067 b 7
现在我们将转移到今天文章的核心,特征向量或嵌入的可视化。
特征向量的可视化
我不会解释训练代码。所以让我们从视觉化开始。我们将需要导入一些库。我在我的脚本中使用了 PyTorch Lightning ,但是代码将适用于任何 PyTorch 模型。
我们加载训练好的模型,将其发送到 GPU,并将其置于评估模式。将你的模型放入 eval 是非常重要的,因为它将设置 BatchNorm、Dropout 等层。在推理过程中恰当地表现。
接下来,我们加载我们的 MNIST 数据集,并在数据集中注入一些噪声样本。
注入的噪声看起来像这样。
来源:作者
所以我们知道,模型必须要抛出一些类,但是对于这些样本来说,这是无用的。这是使用 DL 模型的问题之一,如果您遇到非分布数据,那么很难预测模型会预测什么。对看不见的数据进行归纳总是一个挑战。我已经定义了模型,它返回嵌入张量和最终预测张量。这使得无需改变 PyTorch 中的前钩就可以容易地接近。
但是,如果您发现自己想要访问预训练模型的中间层的输出,您可以使用下面的代码来注册前向挂钩。
MNIST 数据集的预测代码如下。我们只需在数据集上循环,向前遍历网络,提取嵌入,并将其存储在嵌入张量中。
为了进行健全性检查,我绘制了几个样本输入测试点的输出预测。
来源:作者
该模型似乎按预期工作,预测标签显示在每个子情节的顶部。最后,我们可以做 t-SNE 和主成分分析投影,看看一些漂亮的视觉效果。我用 scikit-learn 来学习这些算法。
经过训练的模型嵌入的结果图如下所示。正如我们所料,我们看到了 11 个漂亮的星团。该模型预测所有的噪声样本为八个。我们看到这些噪声图像中最右边的紫色集群。这是一种异常,这种异常或异常值应该在您的真实数据集调查中进一步调查。您可以使用 x,y 位置来获取嵌入的索引,并将它们映射到图像索引。那会告诉你那些样品有什么问题。
来源:作者
我还计算了 3D t-SNE 投影,只是为了说明做这件事同样容易。
我们在 3D 投影中也观察到了同样的现象。
来源:作者
对于 PCA,代码非常相似,但是我们使用 PCA 类而不是 TSNE。我做了类似 t-SNE 的二维和三维投影。但是,对于 PCA,您需要记住一个额外的参数。这就是被解释的方差比率。这将告诉您主成分捕获的数据的差异量。这些值越高,主成分就越能更好地显示低维空间中数据的变化。但是较低的值表明只有 2 或 3 个组件不太擅长显示模式。
对于前两个主成分,仅捕获嵌入中 25%的变化。我们确实看到了一些模式,但是这些集群并不像 t-SNE 嵌入那样清晰。主成分分析图中的异常值并不明显。不过,3D 图显示的聚类更好一些。这是因为 3 个分量捕获了更多的方差。因此,PCA 可视化的有效性将取决于您的数据。
来源:作者
来源:作者
在我结束之前,我想再给你们看一个图,让 t-SNE 视觉化的力量更加清晰。作为一个实验,我用一个随机权重的模型计算了嵌入量,并绘制了 t-SNE 投影。为了正确地向您展示聚类,我根据我们可用的实际标签对这些重量进行了颜色编码。我们看到 t-SNE 从一个未训练的模型中提取的嵌入中给了我们 11 个聚类。
来源:作者
但是你必须小心,SNE 霸王龙会产生一些毫无意义的集群。我还要重申我在导言中所说的,这些预测并不是唯一的。因此,投射几次,并验证你在所有情况下都得到了相似的结果。
结论
我们研究了 t-SNE 和 PCA 来可视化从神经网络获得的嵌入/特征向量。这些图可以向您显示数据中的异常值或异常,可以进一步调查以了解这种行为发生的确切原因。这些方法的计算时间随着样本的增加而增加,所以要认识到这一点。感谢您的阅读,我希望您喜欢阅读这篇文章。代码可从这里获得:https://github . com/msminhas 93/embeddings-visualization/blob/main/readme . MD
参考
[1]https://en.wikipedia.org/wiki/Principal_component_analysis
[2]https://en . Wikipedia . org/wiki/Basis _(线性代数)
[3]https://jakevdp . github . io/python datascience handbook/05.09-principal-component-analysis . html
http://yann.lecun.com/exdb/mnist/
可视化足球比赛数据
使用 Python、JSON、Matplotlib 和 Streamlit
由法布里西奥·特鲁希略拍摄于像素
- 在 Streamlit 上查看申请:https://share . Streamlit . io/andriigoz/football _ game _ stats/main . py
- GitHub 库:https://github.com/AndriiGoz/football_game_stats
浏览数据
我总是对显示足球运动员在球场上表现的热图感到兴奋。让我们尝试构建我们的应用程序,在其中我们可以选择一个玩家和他的动作,并将其可视化。用于分析的数据在 StatsBomb 开放数据存储库中的处找到。StatsBomb 是一家收集和存储足球比赛数据的英国公司。对于我的应用程序,我取了 15 个 JSON 文件,代表 2020 年欧锦赛淘汰赛阶段的 15 场比赛,比赛发生在 2021 年 6 月 26 日至 2021 年 7 月 11 日之间。
让我们打开并发现意大利和英格兰之间的决赛。
# Read JSON file
with open('3795506.json', 'r', errors="ignore") as f:
game = json.load(f)
df = pd.json_normalize(game, sep='_')
4796 行× 122 列
让我们先来看看数据框架。共 4796 行,122 列,有时间戳、玩家名、*类型名位置、*等列。它告诉我们整个游戏的故事,从开始到结束:发生了什么,谁做的,什么样的行动,在哪里等。有一个大约 120 分钟长的游戏和一个 4796 行的数据帧,我们得到每 1.5 秒捕获的动作列表。
那场比赛玩家做了几个动作?那是什么样的行动?使用 pd.value_counts 我们可以看到 player_name 和 type_name 列的唯一值的计数,并了解那里发生了什么。
玩家名称和类型名称的动作数量
马尔科·维拉蒂以他的 382 次行动成为游戏中最活跃的玩家。最常见的动作是传球、接球和持球。对于我的应用程序,我决定采取四个最频繁的动作加上 Shot 动作。app 的思路是做一些下拉菜单,我们可以在里面选择一场比赛、一名球员、其中一个动作,然后在球场上画出这个具体动作的可视化。
创建音高
在之友的追踪库中的这里找到了 Pitch Plot 函数。他们用长度、宽度、单位和线条颜色参数创建了一个很好的函数,返回给我们一个现成的足球场作为次要情节。所以我们只是拿着它,并不太坚持这一部分。
*from FCPython import createPitch
# Create pitch plot
pitch_width = 120
pitch_height = 80
fig, ax = createPitch(pitch_width, pitch_height, 'yards', 'gray')*
通过绘图功能
我们通过选择包含某些类型名称和玩家名称的行来启动通道绘图功能。 type_name 在这里等于“Pass”, player_name 将由用户从下拉菜单中选择分配(这将在 Streamlit 应用程序部分完成)。接下来,我们得到位置和 pass_end_location 系列并将它们转换成两个列表:(x1,y1)坐标,这里给出了一个 pass;和(x2,y2)坐标,其中接收到传球。使用py plot . fibble(x1,y1,u,v)* 方法,我们现在可以绘制代表通道的箭头。此外,我们为主队分配蓝色,为客场队分配红色。*
马尔科·维拉蒂通行证地图(意大利)。作者图片
这样,我们就有了一个函数,它返回游戏中所选玩家的所有传球的可视化效果。进位图和 Shot 图功能具有相同的结构,因此不必在本文中描述。
接球图
对于球收据绘图功能,我们选择type _ name = =‘球收据’*的行。这里我们只得到一个(x,y)坐标列表,并用 *plt 将它们可视化为点。圆(x,y)法。压力绘图功能具有相同的逻辑。
哈里·马奎尔(英国)的球收据地图。作者图片
简化应用程序
Streamlit 是每个数据科学家都应该知道的强大工具。它非常简单,同时,它让您有可能通过 web 应用程序可视化和共享您的数据见解。首先,我们创建了一个侧边栏,它有四个下拉菜单和一些只有几行代码的文本:
*# Drop-down menu 'Select Football Game'
st.sidebar.markdown('## Select Football Game')
menu_game = st.sidebar.selectbox('Select Game', games_list, index=14)
# Drop-down menus 'Select Team, Player and Activity'
st.sidebar.markdown('## Select Player and Activity')
menu_team = st.sidebar.selectbox('Select Team', (team_1, team_2))
if menu_team == team_1:
menu_player = st.sidebar.selectbox('Select Player', player_names_1)
else:
menu_player = st.sidebar.selectbox('Select Player', player_names_2)
menu_activity = st.sidebar.selectbox('Select Activity', activities)
st.sidebar.markdown('Select a player and activity. Statistics plot will appear on the pitch.')*
这里我们让用户通过从相应的‘选择玩家’和‘选择活动’下拉菜单中选择来指定玩家名称和类型名称*。这些参数将定义必须显示哪个特定的玩家和活动。然后 activity 的 plot 会被 st.pyplot 函数调用。使用 st.head 、 st.write 和 st.markdown 方法,我们用一些文本填充我们的主区域。*
Streamlit 上的应用程序
要创建 Streamlit 应用程序,您需要为您的 Python 安装 Streamlit 库。为了分享它,你必须在 streamlit.io 注册,制作一个新的应用程序,并将其连接到 GitHub 存储库中的项目文件夹。将自动创建一个随时可用的 web 应用程序。
参考
*[1] StatsBomb 公开数据:【https://github.com/statsbomb/open-data *
[2]创建 Pitch 资源库:https://github . com/Friends-of-Tracking-Data-FoTD/SoccermaticsForPython/blob/master/fc python . py
[3] Irfan Alghani Khalid ,如何使用 Python 分析足球赛事数据:https://towards Data science . com/How-to-Analyze-Football-Event-Data-Using-Python-2f 4070d 551 ff
[4]2020 年欧锦赛淘汰赛阶段:https://en.wikipedia.org/wiki/UEFA_Euro_2020_knockout_phase
在 Kepler.gl 中可视化地理空间交通数据
使用 Kepler.gl 和 HERE traffic data,对数十万个交通数据点进行快速、优雅的地理空间可视化
使用 Kepler.gl |塞犍陀·维维克可视化波士顿交通
Kepler.gl 是优步的开源地理空间工具箱。通常,可视化大规模地理空间数据集可能相当具有挑战性。有很多 Python 包包括 leav、GeoPandas 和 Plotly 都做得很好;但是找到合适的情节背景可能是一个挑战。在本地机器上绘制数千或数十万个数据点在计算上也具有挑战性。
这就是 Kepler.gl 有巨大优势的地方。Kepler.gl 是一个基于浏览器的框架,可以轻松加载 CSV、JSON 或 GeoJSON 数据,并以最少的格式生成优雅的可视化效果。在这个例子中,我在几秒钟内可视化了从 HERE Traffic API 获得的成千上万的流量数据点。
我们开始吧!
获取交通数据:
我已经从HERE Technologies traffic flow API获得了交通数据。我写过几篇文章,重点介绍如何提取交通流量数据:
保存文件
Kepler.gl 喜欢将文件保存为 CSV 格式,有不同的列。如果您想要一个即时的地理空间图,您需要将这两列标记为“纬度”和“经度”,用于空间位置,第三列用于颜色偏好(在交通信息的情况下是速度)。
在 Kepler.gl 中可视化
既然我们已经以正确的格式保存了数据,我们就可以拖放了——就这么简单!
在 Kepler.gl 中加载文件
你会自动得到一个可以保存的漂亮图像。
从 Kepler.gl 导出图像
然而,当你仔细观察时——色阶是根据分位数显示的——这取决于数据以及数据的比例和速度。例如,如果大部分交通是快速移动的(通常是在深夜或清晨),颜色味觉将偏向这些更高的速度。然而,这不是我们想要的。我们希望颜色能清楚地表明绝对速度:就像谷歌地图中的交通一样。在这种情况下,我们根据量化值而不是分位数来选择颜色,如下所示。
选择是基于 Kepler.gl 中的量化值还是分位数来着色
还有一些选项可以改变符号的外观和颜色。这样做,我们可以生成一些非常优雅的可视化效果——如本文的标题图片所示!
在 Kepler.gl 中修改颜色和符号
结论
Kepler.gl 非常适合以最小的努力相对快速地生成优雅的可视化效果。相比之下,使用 OSMnx 和其他 Python 库在我的本地机器上绘制成千上万个点需要更长的时间。
然而,在 Kepler.gl 以最少的输入在可视化方面做得很好的地方,人们也遇到了最小可定制性的问题。例如,基本上只有 3 种背景——黑暗、明亮和卫星。可能存在需要其他类型背景的情况。
但是 Kepler.gl 在地理空间可视化方面做得很好。
关注我 如果你喜欢这篇文章——我经常写复杂系统、物理学、数据科学和社会的界面。
如果你还不是中会员,想支持我这样的作家,可以通过我的推荐链接随意报名:https://skanda-vivek.medium.com/membership
用 Python 中的 t-SNE 可视化图形嵌入
实践教程
如何定性评估 Neo4j 图嵌入
图片由 Martin Grandjean 提供,根据知识共享 署名-分享相似 4.0 国际许可授权。未对原始图像进行任何更改。
介绍
在我的上一篇文章中,我们讨论了图嵌入的目的和本质。主要思想是,为了在图上进行机器学习,我们需要将图转换成一系列向量(嵌入),然后我们可以使用这些向量来训练我们的机器学习(ML)模型。
问题是图嵌入可能很难调优。与创建嵌入和它们所用于的模型的其他方法类似,我们需要考虑很多超参数,并且针对特定的应用对它们进行优化需要时间。关于调整嵌入的主题,我将留到以后的文章中讨论。
这篇文章是关于开发关于嵌入的超参数的直觉。更具体地说,我将向您展示如何在 Neo4j 中注入由图形数据科学 (GDS)库创建的图形嵌入,然后用 Streamlit 仪表板可视化它们。Tomaz Bratanic 开发了功能来可视化 NEuler Neo4j 工具中的嵌入,但是我将演示如何以一种纯粹的 pythonic 方式来实现这一点。
你可以在 GitHub repo 中找到本教程的所有代码。
入门指南
我们需要做的第一件事是使用免费的 Neo4j 沙箱实例创建一个用于嵌入创建的图。在本次演示中,我们将使用一个预先构建在沙盒中的图表,即《权力的游戏》图表,它是许多图表示例的来源。(这张图贯穿了前 5 本书,我要警告你,《权力的游戏》剧透就要来了!)
当您到达主沙盒页面时,您将希望选择带有预构建数据的图表数据科学类型,并启动项目:
选择带有预建数据的图形数据科学图像。(图片由作者提供。)
您将看到实例被创建。然后,您需要使用右边的下拉菜单获取连接详细信息:
实例的连接详细信息。(图片由作者提供。)
酷毙了。请务必获取 Bolt URL 和密码,因为这些将用于建立我们的连接。如果您单击 Open: Open with Browser,然后单击左上角的数据库图标,您应该会看到一个预先填充的 2642 个节点的图表,这些节点代表人员、地点等。以及各种类型的 16,474 个关系。
《权力的游戏》图表的节点和关系。(图片由作者提供。)
在这一点上,你会想进入回购(你克隆了它,对不对?)并且我们将用这些信息调整 Dockerfile 文件。我喜欢使用 Docker,这样结果是可重复的。因此,根据上面的图像,您将编辑 Dockerfile 文件的最后一行,以读取
(在本文发布时,这个沙盒实例将被关闭。)
太棒了。现在我们可以构建用于建立连接的 Streamlit 容器。我非常喜欢 Streamlit,因为它允许您以最少的编码开销快速创建非常复杂的仪表板。我们现在将通过命令行使用标准命令来构建容器:
docker build -t neo_stream .
然后我们会用
docker run -p 8501:8501 -v $PWD/src:/examples neo_stream
(请注意,如果您在 Windows 上,您将需要调整这些命令。)
在仪表板中可视化嵌入
现在,我们已经启动并运行了 Streamlit 容器,并将其连接到 Neo4j 沙盒实例。现在容器正在运行,它将为您提供您应该使用浏览器导航到的 URL。它看起来会像 http://172.17.0.2:8501。当您这样做时,您应该会看到类似这样的内容:
Streamlit 仪表板的屏幕截图。(图片由作者提供。)
很好。现在让我们看看这里有什么。我们可以做的第一件事是点击“获取图表列表”这将做两件事。首先,如果您得到一些文本,您知道您已经正确地连接到沙箱。其次,如果有任何由 GDS 创建的内存图形(参见 API 文档和本帖了解这些),那么它们将在此列出。既然我们才刚刚开始,应该不会有。
但是我们现在要创建一个,因为他们是整个 GDS 的支柱。给图形命名并点击“创建内存图形”(没有空格!).这将创建一个单边无向图,查看《权力的游戏》中的哪些人与其他人互动,或(person1:Person)-[:INTERACTS]-(person2:Person)
。当我们这样做时,我们将得到一个有 2166 个节点和 7814 个关系的图。注意,无向图将使关系的数量加倍,因为它考虑了从人员 1 到人员 2 和人员 2 到人员 1 的两个方向。剧透:如果你沿着图的自然方向走,你的嵌入看起来会不同:(person1:Person)-[:INTERACTS]->(person2:Person)
。
好了,现在是开始工作并创建一些嵌入的时候了。在撰写本文时,我已经实现了 GDS 内置的两个更简单的嵌入,即 FastRP 和 node2vec 。如果你阅读了 API 文档,你可以并且应该使用很多超参数,因为正如我们所知,缺省值往往不会给出最好的结果。我只包含了每种方法的一个子集,但将来会添加更多。对于 FastRP,我有以下内容:
仪表板中包含的 FastRP 超参数。(图片由作者提供。)
您还可以单击 node2vec 的下拉菜单,查看其中有哪些可调参数。我强烈建议您查阅每种嵌入方法的 API 文档,以获得更多关于每种方法的含义的信息,因为详细描述每种方法超出了本文的范围(尽管在以后关于嵌入调优的文章中,我们将深入讨论这一点!).
因此您可以创建 FastRP 和 node2vec 嵌入。现在我们想把它们形象化。但是为了什么目标呢?我们来看看,在这一点上,我们是否无法预测哪些角色是活着的,哪些是死了的。这是一个非常基本的节点分类问题,也是一个很好的起点,因为这是一个监督学习问题。对于这个数据,我将每个人节点标记为 1(如果他们活着), 0(如果他们死了)。
我们将使用[scikit-learn](https://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html)
中可用的t-分布式随机邻居嵌入 (t-SNE)来执行维度缩减,以便在 2 维空间中可视化。(您可以使用任何降维方法,如 PCA。我对 SNE 霸王龙的选择是任意的。)
我将选取一些随机值并生成一些 node2vec 嵌入,如下所示:
my node2vec 嵌入的演示超参数。(图片由作者提供。)
接下来,我将使用 t-SNE 选项卡来可视化这些嵌入。当我这么做的时候,我得到了这个:
基于以上 node2vec 嵌入的 2D t-SNE 向量。(图片由作者提供。)
哦不!这太可怕了!红色的数据点是死去的人,蓝色的是活着的人。我们希望我们的红色和蓝色点会比这更好地聚集!我把它作为一个练习留给读者,让他们来修补这些值,看看他们是否能做得更好。(相信我,你可以!)
后续步骤
这里需要考虑一些事情。首先,这是一个非常小的图表。所以真正的优化通常会很难。第二,如果我们真的想优化它们,我们需要做的不仅仅是在 2D 看一张更高维度的嵌入的漂亮图片。我们可以使用这样的工具来获得对我们的图最重要的超参数的直觉,然后在 ML 模型中使用这些参数进行网格搜索,以优化我们的相关指标。因此,我鼓励您修改这些超参数,看看会发生什么。
在未来的帖子中,我计划使用更大的图,我们希望可以得到更好的嵌入结果,并在 ML 模型中测试它们。
可视化高维数据
使用 Hypertools——Python 工具箱
来源:https://hypertools.readthedocs.io/en/latest/
数据可视化有助于识别不同数据列之间的隐藏模式、关联和趋势。我们制作不同类型的图表、绘图、图形等。为了理解数据是什么以及不同的列是如何相互关联的。
很容易可视化具有较低维度的数据,但是当涉及具有较高维度的数据时,很难分析或可视化它们,因为在可视化中不可能显示大量维度。
但是,如果我告诉你,有一个 python 工具箱,它不仅创建了视觉上吸引人的可视化效果,而且在单个函数调用中简化了维数约减。
Hypertools 是一个开源的 python 工具箱,它通过自身降维来创建高维数据集的可视化。它主要构建在 matplotlib、sklearn 和 seaborn 之上。在本文中,我们将探索一些可以使用 hypertools 创建的可视化。
让我们开始吧…
安装所需的库
我们将从使用 pip 安装 hypertools 开始。下面给出的命令可以做到这一点。
pip install hypertools
导入所需的库
在这一步中,我们将导入用于创建可视化的所需库。
import hypertools as hyp
创建可视化
现在我们将开始创建不同的可视化效果,看看 hypertools 是如何工作的。
- 基本剧情
# data loading
basic = hyp.load('weights_sample')
# Creating plot
basic.plot(fmt='.')
来源:作者
2.集群剧情
clust = hyp.load('mushrooms')
# Creating plot
clust.plot(n_clusters=10)
来源:作者
3.文集情节
此图用于文本数据集。
text = ['i am from India', 'India is in asia', 'Asia is the largest continent',
'There are 7 continents', 'Continents means earth surfaces ', 'Surfaces covers land area',
'land area is largest in asia']# creating plot
hyp.plot(text, '*', corpus=text)
来源:作者
4。UMAP
from sklearn import datasets data = datasets.load_digits(n_class=6)
df = digits.data
hue = data.target.astype('str')hyp.plot(df, '.', reduce='UMAP', hue=hue, ndims=2)
来源:作者
5.动画剧情
ani = hyp.load('weights_avg')# plot
ani.plot(animate=True, chemtrails=True)
来源:作者
继续尝试不同的数据集,并创建美丽的可视化来解释数据。如果您发现任何困难,请在回复部分告诉我。
本文是与 Piyush Ingale 合作完成的。
参考:https://hypertools.readthedocs.io/en/latest/
在你走之前
感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 。可以查看我的Github简介针对不同的数据科学项目和包教程。还有,随意探索 我的简介 ,阅读我写过的与数据科学相关的不同文章。
可视化滤波器如何在卷积神经网络(CNN)中工作
使用 Excel 了解边缘检测的工作原理
约翰·巴克利在 Unsplash 上拍摄的照片
在深度学习中,卷积神经网络 (CNN)是一种特殊类型的神经网络,旨在通过多层阵列处理数据。CNN 非常适合像图像识别这样的应用,特别是经常用于人脸识别软件。
在 CNN 中,卷积层是创造奇迹的基本构件。在典型的图像识别应用中,卷积层由几个滤波器组成,用于检测图像的各种特征*。理解这项工作如何最好地用类比来说明。*
假设你看到有人从远处朝你走来。从远处看,你的眼睛会试图检测图形的边缘,你会试图将该图形与其他物体区分开来,如建筑物或汽车等。当这个人向你走近时,你试着关注这个人的形状,试着推断这个人是男是女,瘦还是胖,等等。随着这个人越来越近,你的注意力转移到这个人的其他特征上,比如他的面部特征,他是否戴眼镜,等等。总的来说,你的关注点从宽泛的特性转移到了具体的特性。
同样,在 CNN 中,有几层包含各种过滤器(通常称为内核)的层,负责检测您试图检测的目标的特定特征。早期层试图集中于广泛的特征,而后面的层试图检测非常具体的特征。
在 CNN 中,每个卷积层中各种滤波器的值是通过对特定训练集进行训练而获得的。在训练结束时,您将拥有一组唯一的过滤器值,用于检测数据集中的特定要素。使用这组滤镜值,您可以将它们应用到新图像上,以便预测图像中包含的内容。
向 CNN 初学者教授的挑战之一是解释过滤器是如何工作的。学生们常常难以想象(并非有意双关)过滤器的用法。正是带着这个目标,我开始写这篇文章。我希望在这篇文章结束时,你会对 CNN 中的过滤器如何工作有一个更好的理解。
获取我们的数据
深度学习的一个经典例子是 MNIST 数据集。我将在我们的例子中使用它。
何 MNIST 数据库(修改后的国家标准与技术研究所数据库)是一个手写数字的大型数据库,通常用于训练各种图像处理系统。
来源:https://en . Wikipedia . org/wiki/MNIST _ 数据库#/media/File:mnistexamples . png
使用 TensorFlow,您可以按如下方式加载 MNIST 数据:
from tensorflow.keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
我现在要做的是使用该数据集中的特定项目,提取其数据,然后将其保存到 CSV 文件中。下面的代码片段可以做到这一点。
item = 66 # index of the digit to load
data = X_train[item] # data is a 2D array# get the rows and columns of the data
rows = data.shape[0]
columns = data.shape[1]# used to store all the numbers of the digits
lines = ''# convert all the cells into lines of values separated by commas
for r in range(rows):
print(data[r])
lines += ','.join([f'{i}' for i in data[r]]) + "\n"# write the lines to a csv file
with open('mnist.csv','w') as file:
file.write(lines)
如果您打开保存的 mnist.csv 文件,您将看到以下内容:
更好的可视化方法是使用 Excel 打开它:
您现在可以非常清晰地看到,这个数据集表示数字“2”。
将滤镜应用于图像
为了直观显示筛选器的工作方式,让我们使用 Excel 并创建一个新的工作表。
我已经把最终的电子表格放在https://bit.ly/2QVLnSS供下载。
首先,用以下值创建一个 28x28 的网格(我们稍后将使用 MNIST 数字的数据;现在我要给你看一些更容易理解的东西):
假设 28x28 网格中的每个值代表一种颜色(255 代表白色,0 代表黑色)。
接下来,创建另一个 28x28 网格,其值是通过将第一个网格中的每个值除以 255 获得的:
接下来,我们创建一个代表过滤器(内核)的 3x3 网格:
过滤器代表我们在图像中寻找的模式类型,其中 1 代表白色,-1 代表黑色。在上面的过滤器中,我在图像中寻找一个垂直边缘,颜色从白色变为黑色,就像这样:
将过滤器应用于网格只是将过滤器中的每个值与网格中的相应值相乘:
过滤器中的每个值都与网格中的相应值相乘,然后求和
应用于图像的滤镜的值;然后,结果的小数部分被截断
生成的网格就是我们试图寻找的特征图。看数值,我们不容易知道特征图的意义。因此,让我们添加一些颜色编码到我们的原始图像和特征地图,以便我们可以清楚地看到我们在寻找什么。
对于这个图像网格,我们希望通过选择整个网格,然后选择格式|条件格式… 来应用颜色:
在管理规则窗口中,点击对话框左下角的+按钮:
如下设置颜色,然后点击确定两次:
网格现在看起来像这样:
我们的图像只是一个中间有一个黑色矩形的白色图像
从图像中可以看到,图像中有两条边,一条从白到黑,另一条从黑到白:
现在让我们也对我们的特征图进行颜色编码(应用了过滤器的图像):
您现在应该看到以下内容:
基于我们的过滤器,白色的列是我们正在寻找的(记住我们正在寻找颜色从白色变为黑色的边缘)。如果我们现在更改过滤器,寻找从黑色变为白色的垂直边缘,那么输出将如下所示:
水平边缘怎么样?嗯,如果您更改过滤器以寻找水平边缘,您将一无所获(这并不奇怪):
现在,您可以看到过滤器如何处理 MNIST 数据集了。将您在上一节中提取的数据(数字“2”)粘贴到工作表中:
标准化和颜色编码的图像现在看起来如下:
如果您想检测水平边缘,请使用以下过滤器:
现在,图像中的所有水平边缘都高亮显示:
使用另一个例子(对于数字“6”):
您可以像这样检测所有垂直边缘:
您也可以检测水平边缘:
每个卷积层中各种滤波器的组合使得 CNN 中的预测成为可能。
自己试试吧
了解过滤器工作原理的最佳方式是亲自尝试。在https://bit.ly/2QVLnSS下载电子表格,使用不同的过滤值,例如:
此外,在 MNIST 数据集中尝试不同的数字。当你这样做的时候,试着使用一些除了数字以外的其他图像!
可视化全球贸易如何塑造气候危机
全球贸易和气候危机有什么关系?很复杂,但是一张图胜过千言万语。
如果决策者想要履行《巴黎协定》中的义务,他们的时间很紧。幸运的是,有很多关于从金融角度理解气候危机的研究可以帮助他们。作为一名数据科学家,我认为查看一些数据并看看是否能找出一些模式会很有趣。
图一。从我以前的博客帖子的中间需求。图片作者。
在我之前的博文中,我使用数据科学工具挖掘全球经济。我使用 Pymrio 和其他几个库以及 Gephi 来可视化基于 Eora26 数据集的全球经济。我发现有一个紧密相连的核心经济体相互进行贸易。世界上大约一半的国家属于这一核心,而其余的国家起着次要的作用。我还发现,在整个 90 年代,美国是全球经济的动力,但中国正在快速赶上。在图 1 中,您可以看到 2014 年几个核心经济体之间的贸易情况。
在这篇博文中,我将尝试使用 PRIMAP-hist 数据集[3]将国际贸易与全球排放数据联系起来,该数据集包括《京都议定书》中包含的所有温室气体,但不包括土地使用变化和林业。该数据包含在 Eora26 中。我将首先解释投入产出理论背后的经济建模思想,以及如何将其与排放数据相结合。之后,我们将深入研究数据。
投入产出表速成班
在投入产出理论中,通过考虑资本流入、流出和在经济中的流动来模拟经济。这种观点认为,最终用户推动经济发展,因为他们提供了对产品的最终需求,而最终需求又产生了供应产品的中间需求。考虑下面的例子。你花 1 美元从木匠那里买了一把钉子。然后你是钉子的最终用户,所以你的购买构成了最终需求。这个木匠没有做钉子,他是从一个批发商那里买的,这个批发商是从一个工厂买的。工厂需要钢材、机器和一堆其他材料来制造钉子。钢铁制造商需要天然气、电力和计算机,并从其他供应商那里购买。这样,所有部门都联系起来,产生中间需求,以满足最终需求。经济中的资本数量不是恒定的,所以为了平衡经济,你还需要关于经济增加值的信息。投入产出表反映了资本如何流入和流出经济,以及经济各部门之间的流动。所有这些信息都被收集到巨大的表格中,例如 Eora26。
不过,首先让我们试着了解一下中间需求和最终需求的规模。
最终和中间需求
在下面的柱状图(图 2)中,我以基本价格(税前)绘制了 2015 年全球最终和中间需求的规模。
图二。2015 年最终和中间需求总量。图片作者。
我们可以看到,平均而言,对全球经济而言,价值 1 美元的最终需求(比如一把钉子)会产生大约 1 美元的中间需求。如果你假设最终需求和经济总产出(中间+最终)之间呈线性关系,你就可以计算出满足最终需求的部门间的资本流动。如果你对这个模型的细节感兴趣,我推荐你阅读这个介绍[4]或者看一看包含我的代码的笔记本。但是我们来看一个例子。
可视化供应链
在下面的图 3 中,我展示了满足建筑部门 1 美元最终需求所需的计算中间需求的可视化(你从那里买了钉子,记得吗?).用于建立模型的数据来自 2015 年。我用 NetworkX 搭建了网络,写了一些代码在 Gephi 中可视化。
图 3。“建筑”部门 1 美元最终需求产生的中间需求。图片作者。
经济中的每个部门都用一个点(节点)来表示,每个部门都用一个箭头(有向边)与所有其他部门相连,箭头通过其大小和黑色来指示资本流动的方向和流动的大小。你会看到也有箭头会自己绕成圈。这表明一个部门内的资本流动。我使用了一个弹簧算法来放置这些点,它们之间的距离对应于中间需求(Force Atlas 2 算法)。节点的颜色对应于建筑部门 1 美元最终需求对总产出的贡献。您可以通过将进入每个节点的所有箭头相加来找到该值(入度)。
我们看到,对“建筑”部门的最终需求平均而言会导致“石油、化工……”、“金属产品”和“金融中介”产生大量产出。相反,在“旅馆和餐馆”以及“电力、煤气和水”部门,该部门似乎没有产生大量产出。但你可以看到供应链中的其他部门在“电、气和水”部门产生产出。尤其是“石油、化工……”和“金属制品”部门。这种类型的可视化使得可视化资本流动和识别供应链中的潜在热点变得非常容易。但你会问,这与气候危机有什么关系?坚持住,因为我们快到了!
排放核算
我们已经学会了一种将最终需求归因于不同部门产出的方法。如果我们知道每个部门的排放量,那么我们可以认为,与该部门产品的最终需求相关的足迹应该与该部门的产出和排放量成比例。这样我们就可以计算出经济的总产出和与经济相关的总排放量。对于给定的最终需求,我们可以计算总足迹,并将其理解为不同部门的贡献。这当然只是一个模型——但是一个直观且可解释的模型。所以让我们开始研究排放数据。
排放与产出的关系 我想知道全球范围内不同行业的产出与排放之间关系的本质。在下面的图 4 中,我展示了一个散点图,其中每个部门的排放量与该部门的总产出一起绘制。
图 4。总排放量散点图,不包括 PRIMAP-hist 数据集中的 LULUCF 和 Eora26 数据集中的输出。
正如你所看到的,每个部门的排放量和其产出之间似乎有一个几乎线性的关系。不过有一个例外。“电力、燃气和水”部门产出一般,但排放量巨大。因此,在包括“电、气和水”的所有供应链中(都是供应链),该部门对碳足迹的贡献远远大于对总产出的贡献(平均而言)。让我们暂时回到我们的例子。
在图 3 中,您将看到每个节点都有不同的大小。大小表示该部门对总足迹的贡献。你可以看到,虽然“电、气、水”并没有真正贡献间接产出(进入其中的箭头很小,节点离“建设”节点很远),但它对间接足迹的贡献很大。
像这样的可视化使得识别全球供应链中的排放热点变得容易。例如,即使建筑部门减少了对"电、气和水"的需求,也不会使总足迹发生很大变化,因为所有其他部门也需要"电、气和水",其中一些部门甚至比"建筑"部门更需要。因此,一个更好的解决方案是改造“天然气、水和电力”部门,以减少单位产出的排放量。
做预测
该模型的强大之处在于,我们还可以预测需求的“微小”变化对整个供应链的影响(微小,因为该模型假设线性,还记得吗?).例如,如果我们将“天然气、水和电力”部门的排放效率提高 10%,我们可以减少多少建筑部门的全球足迹?像这样的信息可能对决策者很重要,但对消费者也很重要,因为是他们的最终需求推动了中间需求。例如,一种类似于本文中概述的方法最近被用来计算丹麦 500 种最受欢迎的食品杂货的足迹。这使得消费者能够就他们的消费习惯如何影响他们的个人足迹做出明智的决定。在丹麦,许多食品杂货都是进口的。因此,与最终需求相关的大量排放发生在国外。我有兴趣了解这在全球范围内的真实程度。接下来让我们来看看。
可视化排放的输出/输入
我解决这个问题的方法是,首先计算所有地区对当地足迹的贡献大小。然后,我将全球总排放量与这些地方排放量的总和进行了比较。我在下面的图 5 中绘制了 1993 年至 2015 年的图表。
图 5。区域总排放量和满足区域需求的排放量。图片作者。
您可以看到,全球排放量在此期间有所增加,总排放量的 85–90%可归因于本地需求的本地贡献。但是,10-15%是进口/出口排放,这仍然是一个很大的贡献,尽管不一定是一件坏事。为了了解一段时间内的发展情况,我在图 6 中绘制了每个地区的足迹与该地区领土排放量的比率。
图 6。Eora26 数据集中各区域的碳足迹与地域排放的比率。
一些较小的国家有非常高和非常低的比率,所以我不得不限制颜色范围从-0.5 到 0.5。你可以看到随着时间的推移,地图变得更加丰富多彩。这一趋势表明排放量的进出口增加。我们还可以从蓝色和红色看出,西方的最终需求似乎倾向于导致向国外排放。对亚洲和非洲部分地区来说,国外的最终需求往往会导致当地的排放。但是该图没有告诉我们在哪些区域之间发生了导出/导入。所以我做了另一个图表…
绘制排放流图
我想了解哪些国家推动了与国际贸易相关的排放。为了做到这一点,我可以绘制每个地区的供应链,并像我们对每个部门一样寻找模式。相反,我计算了 A 地区的最终需求在多大程度上可以归因于所有其他地区的排放。然后,我在区域 A 和所有其他区域之间画了一个箭头,每个箭头的大小和红色反映了该国排放的方向和幅度,这是区域 A 最终需求的结果。我对所有区域都画了一个箭头,并再次使用 Gephi 和 Force Atlas 2 spring 算法显示了图表。您可以在下面的图 7 中看到结果。
图 7。不同国家最终需求导致的当地排放可视化。仅显示高于特定阈值的箭头。图片作者。
记住,箭头指向发射的方向,大小和红色表示发射的大小。我为何时绘制箭头设置了一个阈值,以使可视化效果更漂亮。点(节点)的大小反映了总输入或输出排放量的大小。如果一个区域是排放的净输出者,那么节点的色调是蓝色,如果该区域是排放的净输入者,那么节点的色调是红色。颜色的饱和度和节点的大小表示向/从该区域排放的总输入/输出的量级。例如,美国是最大的排放出口国,因此美国节点是最大的蓝色节点,具有最清晰的蓝色。相反,中国是最大的排放进口国,所以它的红色最明显。中国节点的大小大于美国节点,这表明中国的净排放量进口大于美国的净排放量出口。
我们看到,西方和一些亚洲国家的最终需求推动了中国的排放。有趣的是,中国的最终需求似乎推动了俄罗斯的排放,而俄罗斯的最终需求似乎推动了白俄罗斯的排放。香港的最终需求似乎也推动了中国的排放。但是一张图胜过千言万语,所以我鼓励你自己去探索可视化,看看你是否能发现一些有趣的模式。让我知道你有什么意见。
所有这些排放的进口和出口并不一定是坏事。如果中国和印尼的单位产出排放效率高于它们出口产品的国家,那么这实际上是一件好事。不幸的是,他们不是。因此,虽然一些西方国家的本土排放正在减少,但这是以更大的海外足迹为代价的。决策者应该记住这一点。
我是博客新手。所以,如果你有任何意见或建议,请告诉我。你可以在这里找到 代号 。也可以在LinkedIn上找我。
[1] Lenzen M,Kane moto K;Moran D 和 Geschke A (2012 年)绘制世界经济结构图。环境科学&技术46(15)PP 8374–8381。 DOI: 10.1021/es300171x
[2] Lenzen,m .,Moran,d .,Kanemoto,k .,Geschke,A. (2013) 建立 Eora:高国家和部门分辨率的全球多区域投入产出数据库。经济系统研究,25:1,20–49,DOI:10.1080/09535314 . 2013 . 769938
[3] Gütschow,j .,Jeffery,M. L .,Gieseke,r .,Gebel,r .,Stevens,d .,Krapp,m .,& Rocha,M. (2016 年)。PRIMAP-hist 国家历史排放量时间序列。 地球系统科学数据, 8 (2),571–603。https://doi.org/10.5194/essd-8-571-2016
[4]莱昂蒂夫,W. (1970 年)。环境影响和经济结构:投入产出方法,《经济学和统计学评论》,第 52 卷,第 3 期(1970 年 8 月),第 262-271 页,麻省理工学院出版社。经济与统计评论, 52 (3),262–271。