Seaborn从零开始学习教程(三)

本次将主要介绍数据集的分布可视化的使用。

数据集分布可视化

当处理一个数据集的时候,我们经常会想要先看看特征变量是如何分布的。这会让我们对数据特征有个很好的初始认识,同时也会影响后续数据分析以及特征工程的方法。本篇将会介绍如何使用 seaborn 的一些工具来检测单变量和双变量分布情况。

首先还是先导入需要的模块和数据集。

%matplotlib inline
import numpy as np
import pandas as pd
from scipy import stats, integrate
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(color_codes=True)
np.random.seed(sum(map(ord, "distributions")))

注意:这里的数据集是随机产生的分布数据,由 numpy 生成,数据类型是ndarray。当然,pandas 的 Series 数据类型也是可以使用的,比如我们经常需要从 DataFrame 表中提取某一特征(某一列)来查看分布情况。

绘制单变量分布

在 seaborn 中,快速观察单变量分布的最方便的方法就是使用 distplot() 函数。默认会使用直方图 (histogram) 来绘制,并提供一个适配的核密度估计(KDE)。

x = np.random.normal(size=100)
sns.distplot(x);

直方图(histograms)

直方图是比较常见的,并且在 matplotlib 中已经存在了 hist 函数。直方图在横坐标的数据值范围内均等分的形成一定数量的数据段(bins),并在每个数据段内用矩形条(bars)显示y轴观察数量的方式,完成了对的数据分布的可视化展示。

为了说明这个,我们可以移除 kde plot,然后添加 rug plot(在每个观察点上的垂直小标签)。当然,你也可以使用 rug plot 自带的 rugplot() 函数,但是也同样可以在 distplot 中实现:

sns.distplot(x, kde=False, rug=True);

当绘制直方图时,你最需要确定的参数是矩形条的数目以及如何放置它们。distplot()使用了一个简单的规则推测出默认情况下最合适的数量,但是或多或少的对 bins 数量进行一些尝试也许能找出数据的其它特征:

sns.distplot(x, bins=20, kde=False, rug=True);

核密度估计(Kernel density estimation)

核密度估计可能不被大家所熟悉,但它对于绘制分布的形状是一个非常有用的工具。就像直方图那样,KDE plots 会在一个轴上通过高度沿着其它轴将观察的密度编码。

sns.distplot(x, hist=False, rug=True);

绘制 KDE 比绘制直方图需要更多的计算。它的计算过程是这样的,每个观察点首先都被以这个点为中心的正态分布曲线所替代。

x = np.random.normal(0, 1, size=30)
bandwidth = 1.06 * x.std() * x.size ** (-1 / 5.)
support = np.linspace(-4, 4, 200)
kernels = []
for x_i in x:
    kernel = stats.norm(x_i, bandwidth).pdf(support)
    kernels.append(kernel)
    plt.plot(support, kernel, color="r")
sns.rugplot(x, color=".2", linewidth=3);

然后,这些替代的曲线进行加和,并计算出在每个点的密度值。最终生成的曲线被归一化,以使得曲线下面包围的面积是 1。

density = np.sum(kernels, axis=0)
density /= integrate.trapz(density, support)
plt.plot(support, density);

我们可以看到,如果我们使用 kdeplot() 函数,我们可以得到相同的曲线。这个函数实际上也被 distplot() 所使用,但是如果你就只想要密度估计,那么 kdeplot() 会提供一个直接的接口更简单的操作其它选项。

sns.kdeplot(x, shade=True);

KDE 的带宽参数(bw)控制着密度估计曲线的宽窄形状,有点类似直方图中的 bins 参数的作用。它对应着我们上面绘制的 KDE 的宽度。默认情况下,函数会按照一个通用的参考规则来估算出一个合适的值,但是尝试更大或者更小也可能会有帮助:

sns.kdeplot(x)
sns.kdeplot(x, bw=.2, label="bw: 0.2")
sns.kdeplot(x, bw=2, label="bw: 2")
plt.legend();

如上所述,高斯KDE过程的意味着估计延续了数据集中最大和最小的值。 可以通过 cut 参数来控制绘制曲线的极值值的距离; 然而,这只影响曲线的绘制方式,而不是曲线如何拟合:

sns.kdeplot(x, shade=True, cut=0)
sns.rugplot(x);

拟合参数分布

你也可以使用distplot()将参数分布拟合到数据集,并可视化地评估其与观察数据的对应程度:

x = np.random.gamma(6, size=200)
sns.distplot(x, kde=False, fit=stats.gamma);

绘制双变量分布

对于双变量分布的可视化也是非常有用的。在 seaborn 中最简单的方法就是使用 joinplot() 函数,它能够创建一个多面板图形来展示两个变量之间的联合关系,以及每个轴上单变量的分布情况。

mean, cov = [0, 1], [(1, .5), (.5, 1)]
data = np.random.multivariate_normal(mean, cov, 200)
df = pd.DataFrame(data, columns=["x", "y"])

Scatterplots

双变量分布最熟悉的可视化方法无疑是散点图了,在散点图中每个观察结果以x轴和y轴值所对应的点展示。你可以用 matplotlib 的plt.scatter 函数来绘制一个散点图,它也是jointplot() 函数显示的默认方式。

sns.jointplot(x="x", y="y", data=df)

Hexbin plots

直方图 histogram 的双变量类似图被称为 “hexbin” 图,因为它展示了落在六角形箱内的观测量。这种绘图对于相对大的数据集效果最好。它可以通过 matplotlib 的 plt.hexbin 函数使用,也可以作为 jointplot 的一种类型参数使用。它使用白色背景的时候视觉效果最好。

x, y = np.random.multivariate_normal(mean, cov, 1000).T
with sns.axes_style("white"):
    sns.jointplot(x=x, y=y, kind="hex", color="k");

Kernel density estimation

还使用上面描述的核密度估计过程来可视化双变量分布。在 seaborn 中,这种绘图以等高线图展示,并且可以作为 jointplot() 的一种类型参数使用。

sns.jointplot(x="x", y="y", data=df, kind="kde");

你也可以用 kdeplot 函数来绘制一个二维的核密度图形。这可以将这种绘图绘制到一个特定的(可能已经存在的)matplotlib 轴上,而 jointplot() 函数只能管理自己:

f, ax = plt.subplots(figsize=(6, 6))
sns.kdeplot(df.x, df.y, ax=ax)
sns.rugplot(df.x, color="g", ax=ax)
sns.rugplot(df.y, vertical=True, ax=ax);

如果你希望让双变量密度看起来更连续,您可以简单地增加 n_levels 参数增加轮廓级数:

f, ax = plt.subplots(figsize=(6, 6))
cmap = sns.cubehelix_palette(as_cmap=True, dark=0, light=1, reverse=True)
sns.kdeplot(df.x, df.y, cmap=cmap, n_levels=60, shade=True);

jointplot() 函数使用 JointGrid 来管理图形。为了获得更多的灵活性,您可能需要直接使用JointGrid 绘制图形。jointplot() 在绘制后返回 JointGrid 对象,你可以用它来添加更多层或调整可视化的其他方面:

g = sns.jointplot(x="x", y="y", data=df, kind="kde", color="m")
g.plot_joint(plt.scatter, c="w", s=30, linewidth=1, marker="+")
g.ax_joint.collections[0].set_alpha(0)
g.set_axis_labels("$X$", "$Y$");

可视化数据集成对关系

为了绘制数据集中多个成对的双变量,你可以使用 pairplot() 函数。这创建了一个轴矩阵,并展示了在一个 DataFrame 中每对列的关系。默认情况下,它也绘制每个变量在对角轴上的单变量。

iris = sns.load_dataset("iris")
sns.pairplot(iris);

就像 joinplot() 和 JoinGrid 之间的关系,pairplot() 函数建立在 PairGrid 对象之上,直接使用可以更灵活。

g = sns.PairGrid(iris)
g.map_diag(sns.kdeplot)
g.map_offdiag(sns.kdeplot, cmap="Blues_d", n_levels=6);
/Users/mwaskom/anaconda/lib/python2.7/site-packages/matplotlib/axes/_axes.py:545: UserWarning: No labelled objects found. Use label='...' kwarg on individual plots.
  warnings.warn("No labelled objects found. "

http://seaborn.pydata.org/tutorial/distributions.html

原文发布于微信公众号 - Python数据科学(Python_Spiderman)

原文发表时间:2018-05-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏人工智能LeadAI

零基础入门深度学习 | 第三章:神经网络和反向传播算法

无论即将到来的是大数据时代还是人工智能时代,亦或是传统行业使用人工智能在云上处理大数据的时代,作为一个有理想有追求的程序员,不懂深度学习这个超热的技术,会不会感...

49212
来自专栏AI研习社

一文带你读懂图像处理工作原理

这里,如果小矩阵的点积与大矩阵的所有3x3大小的部分完成。 点积表示每个元素乘以其各自的元素,例如。 131 *( - 1),162 * 0,232 * 1等。

1513
来自专栏IT大咖说

阿猫还是阿狗?AI视觉识别中目标检测的关键技术

内容来源:2018 年 04 月 21 日,AI教育求职平台景略集智创始人王文凯在“百度深度学习公开课·北京站:AI工程师的快速进阶之路”进行《目标检测面面观》...

941
来自专栏SeanCheney的专栏

《Scikit-Learn与TensorFlow机器学习实用指南》 第13章 卷积神经网络

(第一部分 机器学习基础) 第01章 机器学习概览 第02章 一个完整的机器学习项目(上) 第02章 一个完整的机器学习项目(下) 第03章 分类 第...

881
来自专栏Coding迪斯尼

使用视觉化方法揭露卷积网络是如何从图片中抽取规律信息的

我们在前几节介绍过卷积网络的运算原理,以及通过代码实践,体验到了卷积网络对图片信息抽取的有效性。现在一个问题在于,我们知道卷积网络的运算过程,但不知道为什么卷积...

1033
来自专栏信数据得永生

《Scikit-Learn与TensorFlow机器学习实用指南》第13章 卷积神经网络

55511
来自专栏AI科技评论

干货 | 攻击AI模型之FGSM算法

本文将为您揭开白盒攻击中鼎鼎大名的FGSM(Fast Gradient Sign Method)算法的神秘面纱!

6562
来自专栏云时之间

深度学习与TensorFlow:FCN论文翻译

这篇论文跟上一篇的VGG论文一样,在深度学习领域同样的经典,在2015年的CVPR,该论文拿到了best paper候选的论文,在之后的PASCAL VOC20...

3442
来自专栏机器学习算法与Python学习

支持向量机(SVM)--(4)

回忆:在上一篇文章中我们谈到为了使支持向量机能够处理非线性问题,进而引进核函数,将输入空间的输入数据集通过一个满足Mercer核条件的核函数映射到更高...

3256
来自专栏机器人网

图解机器学习(清晰的路线图)

每当提到机器学习,大家总是被其中的各种各样的算法和方法搞晕,觉得无从下手。确实,机器学习的各种套路确实不少,但是如果掌握了正确的路径和方法,其实还是有迹可循的,...

5239

扫码关注云+社区

领取腾讯云代金券