Seaborn中文教程(二):分类数据可视化

在统计关系可视化教程中,我们学会了使用多种不同的方式来展示一个数据集中多个变量之间的关系。在一系列的例子中,我们聚焦于那些关系主要存在于两个数值型变量之间的情况。然而当其中一个变量是分类(离散)变量时,我们不妨使用更加有针对性的可视化方法。

seaborn中,有多种不同的方式来展示包含了分类数据的变量关系。正如relplot()scatterplot()/lineplot()之间的关系一样,我们可以使用catplot()函数来描述分类数据,也可以使用更多坐标轴级别的绘图函数来完成这些任务。catplot()提供了对这些axes-level的函数的整合,将他们放在了一个更高级别的统一的接口之中。

我们将分类可视化图形分为三类,并且之后我们会详细探讨他们:

  1. 分类散点图
  • stripplot(): 或catplot(kind="strip")
  • swarmplot(): 或catplot(kind="swarm")
  1. 分类分布图
  • boxplot(): 或catplot(kind="box")
  • violinplot(): 或catplot(kind="violin")
  • boxenplot(): 或catplot(kind="boxen")
  1. 分类统计估计图
  • pointplot(): 或catplot(kind="point")
  • barplot(): 或catplot(kind="bar")
  • countplot(): 或catplot(kind="count")

这些分类从不同的粒度来展示数据。想要知道哪个更合适,就需要我们认真思考我们到底要回答什么问题。catplot()提供的统一的API可以帮助我们轻松地在不同方法间切换并从不同的视角理解数据。

在这篇教程中,我们会主要使用图形级别的整合接口:catplot()。我们已经知道了这个函数是上边那一系列绘图方法的更高级别的整合接口,因此当我们详细讨论到了某种图形时,我们也会深涉及到这些稍底层的方法,这样我们就不会错过那些仅在某些方法中存在的API。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="ticks", color_codes=True)

一、分类散点图

catplot()默认的处理方式就是散点图。在绘制分类散点图时,我们会遇到一个挑战,当在同一个类别中出现大量取值相同或接近的观测数据时,他们会挤到一起。seaborn中有两种分类散点图,分别以不同的方式处理了这个问题。catplot()使用的默认方式是stripplot(),它给这些散点增加了一些随机的偏移量:

tips = sns.load_dataset("tips")
sns.catplot(x="day", y="total_bill", data=tips);

jitter参数控制着偏移量的大小,或者我们可以直接禁止他们偏移:

sns.catplot(x="day", y="total_bill", jitter=False, data=tips);

第二种解决方式使用算法避免了散点之间的重合。它提供了更好的方式来呈现观测点的分布,但是它仅适用于较小的数据集。这种图被叫做蜂群图,在seaborn中我们用swarmplot()或者catplot(kind="swarm")来绘制它:

sns.catplot(x="day", y="total_bill", kind="swarm", data=tips);

与关系图(relplot())类似,我们也可以使用hue参数来增加一个新的维度(但是分类图不支持sizestyle)。不同的分类图对于hue参数的处理不太一样,对于散点图而言,它仅仅控制散点的颜色就足够了:

sns.catplot(x="day", y="total_bill", hue="sex", kind="swarm", data=tips);

与连续数值型数据不同,如何在坐标轴上对分类变量进行排序并不总是那么显而易见。一般情况下,seaborn分类图函数会尝试推断数据集中分类的顺序。如果你的数据是pandasCategorical类型,那么默认的分类顺序可以在pandas中设置;如果数据看起来是数值型的(比如1,2,3…),那他们也会被排序。但是即使我们使用数字作为不同分类的标签,它们仍然是被当做分类型数据按顺序绘制在分类变量对应的坐标轴上的:

# 注意,2和4之间的距离与1和2之间的距离是一样的,它们是不同的分类,只会排序,但是并不会改变它们在坐标轴上的距离
sns.catplot(x="size", y="total_bill", kind="swarm", data=tips.query("size != 3"));

我们还可以通过order参数指定分类的顺序,当我们需要绘制多个分类变量图时这一点会很重要:

sns.catplot(x="smoker", y="tip", order=["No", "Yes"], data=tips);

我们前边涉及到过“分类坐标轴”,在这些例子中,我们的分类水平都与水平坐标轴绑定。但是有些时候我们把分类变量放在垂直坐标轴上会更有帮助(尤其是当分类名称较长或者分类较多时)。我们只需要交换x和y分配的变量即可:

sns.catplot(x="total_bill", y="day", hue="time", kind="swarm", data=tips);

二、分类分布图

当数据集的大小越来越大,分类散点图在表现不同分类的观测值的分布信息时就越发显得捉襟见肘。此时,我们有一些方法,能以清晰明了的对比方式来总结不同分类下的观测值分布信息。

箱线图

第一种就是我们的老朋友:箱线图。它能在图中展现出数据的上下四分位数、中文数以及一些极值。箱体上下方的须线会分别向上和向下延伸1.5倍IQR(上下四分位数之间的距离),落在这个区域之外的点会单独显示为离群点(异常值)。

sns.catplot(x="day", y="total_bill", kind="box", data=tips);

我们可以增加一个hue参数,这样就可以进一步增加一个维度来观察数据分布:

sns.catplot(x="day", y="total_bill", hue="smoker", kind="box", data=tips);

这种操作叫做“dodging”,它会默认保持打开,因为它假设hue参数对应的变量与坐标轴上的分类变量是相互嵌套的。假如事实并非如此,我们可以关闭“dodging”:

tips["weekend"] = tips["day"].isin(["Sat", "Sun"])
sns.catplot(x="day", y="total_bill", hue="weekend", kind="box", dodge=False, data=tips);

boxenplot()是一个与boxplot()相关的函数,它绘制的是与箱线图相似但是能展示更多关于数据分布形状的信息,它对大数据更加友好:

diamonds = sns.load_dataset("diamonds")
sns.catplot(x="color", y="price", kind="boxen", data=diamonds.sort_values("color"));

小提琴图

另一种方法是violinplot(),它将箱线图与核密度估计过程结合了起来:

sns.catplot(x="total_bill", y="day", hue="time", kind="violin", data=tips);

这种方法通过和密度估计提供了关于数据分布的更多信息。另外,箱线图中的分位数和须线也都在小提琴图中有所体现。但是由于小提琴图引入了KDE(核密度估计),所以相对于简单明了的箱线图,我们可能需要调整更多的参数。

sns.catplot(x="total_bill", y="day", hue="time",
            kind="violin", bw=.15, cut=0, data=tips);

当一个额外的分类变量仅有2个水平时,我们也可以将它赋给hue参数,并且设置split=True,这样我们可以更加充分地利用空间来表达更多信息:

sns.catplot(x="day", y="total_bill", hue="sex",
            kind="violin", split=True, data=tips);

在小提琴图中,我们有许多选项可以调整小提琴内部的内容,比如我们可以展示每个观测点的位置而非统计量:

sns.catplot(x="day", y="total_bill", hue="sex",
            kind="violin", inner="stick", split=True,
            palette="pastel", data=tips);

我们还可以将swarmplot()stripplot()与箱线图或者小提琴图结合起来,这样我们就可以同时看到每个观测值的分布以及关于分布形态的统计量情况(分位数、极值等):

g = sns.catplot(x="day", y="total_bill", kind="violin", inner=None, data=tips)
sns.swarmplot(x="day", y="total_bill", color="k", size=3, data=tips, ax=g.ax);

三、分类统计估计图

在某些应用场景中,相对于展示每个分类的数据分布,我们可能更想展示每个分类中数据的集中趋势估计(统计量,比如均值、中位数、方差等)。seaborn有两种方式来展示此类信息。需要知道的是,这些函数基本的API与前边提到的那些绘图函数是一致的。

条形图

一种常见的图形是条形图。在seaborn中,barplot()函数在整个数据集上运行,并且应用一个函数来获得那些统计量(默认为均值)。当每个分类中有多个观测值时,它还可以通过自助采样法计算出一个置信区间,并且通过误差棒的方式绘制出来。

titanic = sns.load_dataset("titanic")
sns.catplot(x="sex", y="survived", hue="class", kind="bar", data=titanic);

一个特例是我们想要展示每个分类下观测值(样本)的数量而非统计量。这就像是“属于分类变量而非连续变量的直方图”。在seaborn中,我们可以使用countplot()轻易地达成目的:

sns.catplot(x="deck", kind="count", palette="ch:.25", data=titanic);

barplot()countplot()在调用的时候支持所有我们在上边讨论过的选项(参数),同时一些额外支持的参数在它们各自的详细文档中可以找到:

sns.catplot(y="deck", hue="class", kind="count",
            palette="pastel", edgecolor=".6",
            data=titanic);

点图

我们也可以使用pointplot()来表现同样的信息。点图也使用高度来编码统计量,但是区别在于它不会画出一个完整的长条,而是用一个点以及置信区间来替代;另外,它还会将属于同一个hue分类的点连起来。这样,我们就可以很容易看到hue变量是如何影响坐标轴上的分类变量的(交互作用),因为不同线条的斜率简直是一目了然:

sns.catplot(x="sex", y="survived", hue="class", kind="point", data=titanic);

我们前边提到,分类绘图函数是没有style这一参数的(在relplot()中有)。但是我们同样可以修改线条和点的样式,使得我们的图片更有可读性,甚至可以在黑白色调下表现分类信息(考虑到色盲读者时,黑白色调会很有帮助):

sns.catplot(x="class", y="survived", hue="sex",
            palette={"male": "g", "female": "m"},
            markers=["^", "o"], linestyles=["-", "--"],
            kind="point", data=titanic);

四、绘制“宽表”数据

虽然我们推荐使用使用长数据或者整齐的数据(类似一维数组),但是宽表类的数据在seaborn中也是得到了支持的。宽表类数据是指二维的数据,比如pandasDataFrame或者numpy的二维数组。这些对象可以直接传递给data参数。

iris = sns.load_dataset("iris")
sns.catplot(data=iris, orient="h", kind="box")
<seaborn.axisgrid.FacetGrid at 0x1a209cb860>

另外,那些坐标轴级别的绘图函数(而非图形级别、整合后的API)可以接受类似向量的数据输入(比如pandasSeriesnumpy的一维数组):

sns.violinplot(x=iris.species, y=iris.sepal_length);

想要控制上边我们讨论的图形的大小和形状,我们需要使用更底层的matplotlib设置项:

f, ax = plt.subplots(figsize=(7, 3))
sns.countplot(y="deck", data=titanic, color="c");

这就是当我们想要让一个分类图在一个复杂图片中与其他子图和平共处时需要采用的方法。

五、使用子图展示多重关系

relplot()一样,calplot()也是基于FacetGrid构建,这意味着我们可以轻易地通过更多子图来表现高维的关系:

sns.catplot(x="day", y="total_bill", hue="smoker",
            col="time", aspect=.6,
            kind="swarm", data=tips);

当我们想要定制更多细节时,我们就需要使用FacetGrid对象支持的方法了:

g = sns.catplot(x="fare", y="survived", row="class",
                kind="box", orient="h", height=1.5, aspect=4,
                data=titanic.query("fare > 0"))
g.set(xscale="log");

关于libsvm分类结果的可视化分类曲线的可视化-加权SVM相关论文.rar 关于libsvvm分类结果的可视化分类曲线的可视化  by faruto 论坛里曾有多位朋友询问过,有关libsvvm分类结果的可视化分类曲线的可视化(可能大家感觉这个放在自己的paper里面会比较拉风,个人感觉可视化这些东西真的很虚幻,看着拉风,实则无用)。整体过程我心中明了,但实在是对可视化这种东西的鄙视,所以一直未将关于libsvm分类结果的可视化分类曲线的可视化的结果实现,并以插件函数的形式放在自己的faruto -libsvm工具箱里面。 本质其实就是用contour来实现。 今天下午把科学社会主义理论 翘掉了【我还记得代课老师说让大家查看一下科学社会主义理论和空想社会主义的区别。囧!】。在宿舍搞了一下。 原本想法是要搞就搞高级一点的,想把对于任意维的测试数据的任意两维(或任意三维)进行可视化,并给出分类超曲面,但最终未果,无法实现。【具体原因我就不说了,深入想过这个的应该会明的。】 【搞的我从下午一直搞到 晚上六点,晚饭都没吃,就直接去上的 《概率论的数学基础》课。囧!】你别看代码就几行。但里面的想法挺巧妙的。。 所以,我在这里要说的是,下面的函数插件 svmplot.m 只对两分类,且属性数据是两维的,给出的分类结果的可视化分类曲线的可视化才是有意义和准确的。对于不是两分类或属性数据不是两维的,我这个也可以给出个图,但那个的没有实际意义!切记!!切记!! {近期还想弄的就是专门对于 un-balanced data的处理的函数插件。!} 测试图: 1.jpg 代码:要的直接拿去【拿去在paper里面拉风吧!】。放在libsvm -faruto版本里面就能直接用。function svmplot % svmplot by faruto % 2009.12.03 % Email:patrick.lee@foxmail.com QQ:516667408 if nargin == 3     demension1 = 1;     demension2 = 2; end %% minX = min); maxX = max); minY = min); maxY = max); gridX = ./ 100; gridY = ./ 100; minX = minX - 10 * gridX; maxX = maxX 10 * gridX; minY = minY - 10 * gridY; maxY = maxY 10 * gridY; [bigX, bigY] = meshgrid; %% model.Parameters = 3; ntest=size * size; test_dataset=[reshape, reshape]; test_label = zeros, 1); [Z, acc] = svmpredict; bigZ = reshape, size); %% clf; hold on; grid on; ispos = ); pos = find; neg = find; h1 = plot, dataset, 'r '); h2 = plot, dataset, 'g*'); h3 = plot,model.SVs,'o' ); legend; [C,h] = contour; clabel; xlabel; ylabel; title; 复制代码代码的有一个小trick是参照了svmtoy的思路。 原本我也有思路,但这个更简便。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量化祛魅师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值