Python—数据可视化
(以Wine Quality Data Set数据为例)
1.单变量分析
单变量分析基本上是数据分析或可视化的最简单形式,因为只关心分析一个数据属性或变量并将其可视化
使所有数值数据及其分布可视化的最快、最有效的方法之一是利用 pandas 画直方图
对于连续型数据,直方图或核密度图能够很好地帮助理解该属性数据的分布
可视化一个离散分类型数据属性稍有不同,条形图是(bar plot)最有效的方法之一。
2.多变量分析
多元分析才是真正有意思并且有复杂性的领域。这里我们分析多个数据维度或属性(2 个或更多)。多变量分析不仅包括检查分布,还包括这些属性之间的潜在关系、模式和相关性。你也可以根据需要解决的问题,利用推断统计(inferential statistics)和假设检验,检查不同属性、群体等的统计显著性(significance)。
检查不同数据属性之间的潜在关系或相关性的最佳方法之一是利用配对相关性矩阵并将其可视化为热力图。
热力图中的梯度根据相关性的强度而变化,你可以很容易发现彼此之间具有强相关性的潜在属性。另一种可视化的方法是在感兴趣的属性之间使用配对散点图。
根据上图,可以看到散点图也是观察数据属性的 2 维潜在关系或模式的有效方式。另一种将多元数据可视化为多个属性的方法是使用平行坐标图。
1 | # Correlation Matrix Heatmapf, ax = plt.subplots(figsize=(10, 6))corr = wines.corr()hm = sns.heatmap(round(corr,2), annot=True, ax=ax, cmap="coolwarm",fmt='.2f', linewidths=.05)f.subplots_adjust(top=0.93) |
基本上,在如上所述的可视化中,点被表征为连接的线段。每条垂直线代表一个数据属性。所有属性中的一组完整的连接线段表征一个数据点。因此,趋于同一类的点将会更加接近。仅仅通过观察就可以清楚看到,与白葡萄酒相比,红葡萄酒的密度略高。与红葡萄酒相比,白葡萄酒的残糖和二氧化硫总量也较高,红葡萄酒的固定酸度高于白葡萄酒。查一下我们之前得到的统计表中的统计数据,看看能否验证这个假设!
因此,让我们看看可视化两个连续型数值属性的方法。散点图和联合分布图(joint plot)是检查模式、关系以及属性分布的特别好的方法。
1 | # Scatter Plotplt.scatter(wines['sulphates'], wines['alcohol'], alpha=0.4, edgecolors='w') |
使用散点图和联合分布图可视化 2 维连续型数值数据
散点图在上图左侧,联合分布图在右侧。就像我们提到的那样,你可以查看联合分布图中的相关性、关系以及分布。
如何可视化两个连续型数值属性?一种方法是为分类维度画单独的图(子图)或分面(facet)。
1 | # Using subplots or facets along with Bar Plotsfig = plt.figure(figsize = (10, 4))title = fig.suptitle("Wine Type - Quality", fontsize=14)fig.subplots_adjust(top=0.85, wspace=0.3)# red wine - wine qualityax1 = fig.add_subplot(1,2, 1)ax1.set_title("Red Wine")ax1.set_xlabel("Quality")ax1.set_ylabel("Frequency") rw_q = red_wine['quality'].value_counts()rw_q = (list(rw_q.index), list(rw_q.values))ax1.set_ylim([0, 2500])ax1.tick_params(axis='both', which='major', labelsize=8.5)bar1 = ax1.bar(rw_q[0], rw_q[1], color='red', edgecolor='black', linewidth=1) |
使用条形图和子图可视化 2 维离散型分类数据
虽然这是一种可视化分类数据的好方法,但正如所见,利用 matplotlib 需要编写大量的代码。另一个好方法是在单个图中为不同的属性画堆积条形图或多个条形图。可以很容易地利用 seaborn 做到。
1 | # Multi-bar Plotcp = sns.countplot(x="quality", hue="wine_type", data=wines, |
在一个条形图中可视化 2 维离散型分类数据
这看起来更清晰,你也可以有效地从单个图中比较不同的类别。
让我们看看可视化 2 维混合属性(大多数兼有数值和分类)。一种方法是使用分图\子图与直方图或核密度图。
1 | # facets with histogramsfig = plt.figure(figsize = (10,4))title = fig.suptitle("Sulphates Content in Wine", fontsize=14)fig.subplots_adjust(top=0.85, wspace=0.3) |
利用分面和直方图\核密度图可视化 2 维混合属性
虽然这很好,但是我们再一次编写了大量代码,我们可以通过利用 seaborn 避免这些,在单个图表中画出这些图。
1 | # Using multiple Histograms fig = plt.figure(figsize = (6, 4))title = fig.suptitle("Sulphates Content in Wine", fontsize=14)fig.subplots_adjust(top=0.85, wspace=0.3)ax = fig.add_subplot(1,1, 1)ax.set_xlabel("Sulphates")ax.set_ylabel("Frequency") |
利用多维直方图可视化 2 维混合属性
可以看到上面生成的图形清晰简洁,我们可以轻松地比较各种分布。除此之外,箱线图(box plot)是根据分类属性中的不同数值有效描述数值数据组的另一种方法。箱线图是了解数据中四分位数值以及潜在异常值的好方法。
1 | # Box Plotsf, (ax) = plt.subplots(1, 1, figsize=(12, 4))f.suptitle('Wine Quality - Alcohol Content', fontsize=14) |
2 维混合属性的有效可视化方法——箱线图
另一个类似的可视化是小提琴图,这是使用核密度图显示分组数值数据的另一种有效方法(描绘了数据在不同值下的概率密度)。
1 | # Violin Plotsf, (ax) = plt.subplots(1, 1, figsize=(12, 4))f.suptitle('Wine Quality - Sulphates Content', fontsize=14) |
2 维混合属性的有效可视化方法——小提琴图
你可以清楚看到上面的不同酒品质类别的葡萄酒硫酸盐的密度图。
将 2 维数据可视化非常简单直接,但是随着维数(属性)数量的增加,数据开始变得复杂。原因是因为我们受到显示媒介和环境的双重约束。
对于 3 维数据,可以通过在图表中采用 z 轴或利用子图和分面来引入深度的虚拟坐标。
但是,对于 3 维以上的数据来说,更难以直观地表征。高于 3 维的最好方法是使用图分面、颜色、形状、大小、深度等等。你还可以使用时间作为维度,为随时间变化的属性制作一段动画(这里时间是数据中的维度)。看看 Hans Roslin 的精彩演讲就会获得相同的想法!
可视化 3 维数据(3-D)
这里研究有 3 个属性或维度的数据,我们可以通过考虑配对散点图并引入颜色或色调将分类维度中的值分离出来。
1 | # Scatter Plot with Hue for visualizing data in 3-D |
用散点图和色调(颜色)可视化 3 维数据
上图可以查看相关性和模式,也可以比较葡萄酒组。就像我们可以清楚地看到白葡萄酒的总二氧化硫和残糖比红葡萄酒高。
让我们来看看可视化 3 个连续型数值属性的策略。一种方法是将 2 个维度表征为常规长度(x 轴)和宽度(y 轴)并且将第 3 维表征为深度(z 轴)的概念。
1 | # Visualizing 3-D numeric data with Scatter Plots# length, breadth and depthfig = plt.figure(figsize=(8, 6))ax = fig.add_subplot(111, projection='3d') |
通过引入深度的概念来可视化 3 维数值数据
我们还可以利用常规的 2 维坐标轴,并将尺寸大小的概念作为第 3 维(本质上是气泡图),其中点的尺寸大小表征第 3 维的数量。
1 | # Visualizing 3-D numeric data with a bubble chart# length, breadth and sizeplt.scatter(wines['fixed acidity'], wines['alcohol'], s=wines['residual sugar']*25, alpha=0.4, edgecolors='w') |
通过引入尺寸大小的概念来可视化 3 维数值数据
因此,你可以看到上面的图表不是一个传统的散点图,而是点(气泡)大小基于不同残糖量的的气泡图。当然,并不总像这种情况可以发现数据明确的模式,我们看到其它两个维度的大小也不同。
为了可视化 3 个离散型分类属性,我们可以使用常规的条形图,可以利用色调的概念以及分面或子图表征额外的第 3 个维度。seaborn 框架帮助我们最大程度地减少代码,并高效地绘图。
1 | # Visualizing 3-D categorical data using bar plots |
通过引入色调和分面的概念可视化 3 维分类数据
上面的图表清楚地显示了与每个维度相关的频率,可以看到,通过图表能够容易有效地理解相关内容。
考虑到可视化 3 维混合属性,我们可以使用色调的概念来将其中一个分类属性可视化,同时使用传统的如散点图来可视化数值属性的 2 个维度。
1 | # Visualizing 3-D mix data using scatter plots |
通过利用散点图和色调的概念可视化 3 维混合属
因此,色调作为类别或群体的良好区分,虽然如上图观察没有相关性或相关性非常弱,但从这些图中我们仍可以理解,与白葡萄酒相比,红葡萄酒的硫酸盐含量较高。你也可以使用核密度图代替散点图来理解 3 维数据。
1 | # Visualizing 3-D mix data using kernel density plots# leveraging the concepts of hue for categorical dimensionax = sns.kdeplot(white_wine['sulphates'], white_wine['alcohol'], cmap="YlOrBr", shade=True, shade_lowest=False)ax = sns.kdeplot(red_wine['sulphates'], red_wine['alcohol'], cmap="Reds", shade=True, shade_lowest=False) |
通过利用核密度图和色调的概念可视化 3 维混合属性
与预期一致且相当明显,红葡萄酒样品比白葡萄酒具有更高的硫酸盐含量。你还可以根据色调强度查看密度浓度。
如果我们正在处理有多个分类属性的 3 维数据,我们可以利用色调和其中一个常规轴进行可视化,并使用如箱线图或小提琴图来可视化不同的数据组。
1 | # Visualizing 3-D mix data using violin plots |
通过利用分图小提琴图和色调的概念来可视化 3 维混合属性
在上图中,我们可以看到,在右边的 3 维可视化图中,我们用 x 轴表示葡萄酒质量,wine_type 用色调表征。我们可以清楚地看到一些有趣的见解,例如与白葡萄酒相比红葡萄酒的挥发性酸度更高。
你也可以考虑使用箱线图来代表具有多个分类变量的混合属性。
1 | # Visualizing 3-D mix data using box plots# leveraging the concepts of hue and axes for > 1 categorical dimensions |
通过利用箱线图和色调的概念可视化 3 维混合属性
我们可以看到,对于质量和 quality_label 属性,葡萄酒酒精含量都会随着质量的提高而增加。另外红葡萄酒与相同品质类别的白葡萄酒相比具有更高的酒精含量(中位数)。然而,如果检查质量等级,我们可以看到,对于较低等级的葡萄酒(3 和 4),白葡萄酒酒精含量(中位数)大于红葡萄酒样品。否则,红葡萄酒与白葡萄酒相比似乎酒精含量(中位数)略高。
可视化 4 维数据(4-D)
基于上述讨论,我们利用图表的各个组件可视化多个维度。一种可视化 4 维数据的方法是在传统图如散点图中利用深度和色调表征特定的数据维度。
1 | # Visualizing 4-D mix data using scatter plots |
通过利用散点图以及色调和深度的概念可视化 4 维数据
wine_type 属性由上图中的色调表征得相当明显。此外,由于图的复杂性,解释这些可视化开始变得困难,但我们仍然可以看出,例如红葡萄酒的固定酸度更高,白葡萄酒的残糖更高。当然,如果酒精和固定酸度之间有某种联系,我们可能会看到一个逐渐增加或减少的数据点趋势。
另一个策略是使用二维图,但利用色调和数据点大小作为数据维度。通常情况下,这将类似于气泡图等我们先前可视化的图表。
1 | # Visualizing 4-D mix data using bubble plots |
通过利用气泡图以及色调和大小的概念可视化 4 维数据
我们用色调代表 wine_type 和数据点大小代表残糖。我们确实看到了与前面图表中观察到的相似模式,白葡萄酒气泡尺寸更大表征了白葡萄酒的残糖值更高。
如果我们有多于两个分类属性表征,可在常规的散点图描述数值数据的基础上利用色调和分面来描述这些属性。我们来看几个实例。
1 | # Visualizing 4-D mix data using scatter plots |
通过利用散点图以及色调和分面的概念可视化 4 维数据
这种可视化的有效性使得我们可以轻松识别多种模式。白葡萄酒的挥发酸度较低,同时高品质葡萄酒具有较低的酸度。也基于白葡萄酒样本,高品质的葡萄酒有更高的酒精含量和低品质的葡萄酒有最低的酒精含量!
让我们借助一个类似实例,并建立一个 4 维数据的可视化。
1 | # Visualizing 4-D mix data using scatter plots |
通过利用散点图以及色调和分面的概念可视化 4 维数据
我们清楚地看到,高品质的葡萄酒有较低的二氧化硫含量,这是非常相关的,与葡萄酒成分的相关领域知识一致。我们也看到红葡萄酒的二氧化硫总量低于白葡萄酒。在几个数据点中,红葡萄酒的挥发性酸度水平较高。
可视化 5 维数据(5-D)
我们照旧遵从上文提出的策略,要想可视化 5 维数据,我们要利用各种绘图组件。我们使用深度、色调、大小来表征其中的三个维度。其它两维仍为常规轴。因为我们还会用到大小这个概念,并借此画出一个三维气泡图。
1 | # Visualizing 5-D mix data using bubble charts |
利用气泡图和色调、深度、大小的概念来可视化 5 维数据
气泡图灵感来源与上文所述一致。但是,我们还可以看到以二氧化硫总量为指标的点数,发现白葡萄酒的二氧化硫含量高于红葡萄酒。
除了深度之外,我们还可以使用分面和色调来表征这五个数据维度中的多个分类属性。其中表征大小的属性可以是数值表征甚至是类别(但是我们可能要用它的数值表征来表征数据点大小)。由于缺乏类别属性,此处我们不作展示,但是你可以在自己的数据集上试试。
1 | # Visualizing 5-D mix data using bubble charts |
借助色调、分面、大小的概念和气泡图来可视化 5 维数据
通常还有一个前文介绍的 5 维数据可视化的备选方法。当看到我们先前绘制的图时,很多人可能会对多出来的维度深度困惑。该图重复利用了分面的特性,所以仍可以在 2 维面板上绘制出来且易于说明和绘制。
我们已经领略到多位数据可视化的复杂性!如果还有人想问,为何不增加维度?让我们继续简单探索下!
可视化 6 维数据(6-D)
目前我们画得很开心(我希望是如此!)我们继续在可视化中添加一个数据维度。我们将利用深度、色调、大小和形状及两个常规轴来描述所有 6 个数据维度。
我们将利用散点图和色调、深度、形状、大小的概念来可视化 6 维数据。
1 | # Visualizing 6-D mix data using scatter charts |
这可是在一张图上画出 6 维数据!我们用形状表征葡萄酒的质量标注,优质(用方块标记),一般(用 x 标记),差(用圆标记):用色调表示红酒的类型,由深度和数据点大小确定的酸度表征总二氧化硫含量。
这个解释起来可能有点费劲,但是在试图理解多维数据的隐藏信息时,最好结合一些绘图组件将其可视化。
- 结合形状和 y 轴的表现,我们知道高中档的葡萄酒的酒精含量比低质葡萄酒更高。
- 结合色调和大小的表现,我们知道白葡萄酒的总二氧化硫含量比红葡萄酒更高。
- 结合深度和色调的表现,我们知道白葡萄酒的酸度比红葡萄酒更低。
- 结合色调和 x 轴的表现,我们知道红葡萄酒的残糖比白葡萄酒更低。
- 结合色调和形状的表现,似乎白葡萄酒的高品质产量高于红葡萄酒。(可能是由于白葡萄酒的样本量较大)
我们也可以用分面属性来代替深度构建 6 维数据可视化效果。
1 | # Visualizing 6-D mix data using scatter charts |
借助色调、深度、面、大小的概念和散点图来可视化 6 维数据
因此,在这种情况下,我们利用分面和色调来表征三个分类属性,并使用两个常规轴和大小来表征 6 维数据可视化的三个数值属性。
四、结论
数据可视化与科学一样重要。如果你看到这,我很欣慰你能坚持看完这篇长文。我们的目的不是为了记住所有数据,也不是给出一套固定的数据可视化规则。本文的主要目的是理解并学习高效的数据可视化策略,尤其是当数据维度增大时。希望你以后可以用本文知识可视化你自己的数据集。