Py学习  »  Python

Python Seaborn (4) 线性关系的可视化

EasyCharts • 5 年前 • 1533 次点击  
声明
本文作者 未禾,首发于作者知乎,https://zhuanlan.zhihu.com/p/27593869,已获作者授权原创形式发布,欢迎点击【阅读原文】关注支持!


第四章 线性关系的可视化


这章介绍的针对回归类型的散点数据的可视化可能是未来机器学习最直接的助理,这章给我的感悟很多。

许多数据集包含多个定量变量,分析的目的通常是将这些变量相互关联起来。 我们以前讨论过可以通过显示两个变量的联合分布来实现的功能。 然而,使用统计模型来估计两个噪声观测组之间的简单关系可能是非常有帮助的。 本章讨论的功能将通过线性回归的通用框架进行。

在 Tukey 的精神中,Seaborn 的回归图主要是为了添加一个视觉指南,有助于在探索性数据分析期间强调数据集中的模式。 也就是说,Seaborn 本身并不是统计分析的一揽子计划。 要获得与回归模型拟合相关的量化措施,您应该使用 statsmodels。 然而,Seaborn 的目标是通过可视化快速,轻松地探索数据集,使之变得与通过统计表格来探索数据集一样重要(如果不是更重要的话)。

http://www.statsmodels.org/stable/index.html

%matplotlib inline

import numpy as np

import pandas as pd

import matplotlib as mpl

import matplotlib.pyplot as plt


import seaborn as sns

sns.set(color_codes=True)


np.random.seed(sum(map(ord, "regression")))


tips = sns.load_dataset("tips")


  

绘制线性回归模型的函数

使用 Seaborn 中的两个主要功能可视化通过回归确定的线性关系。这些函数 regplot() 和 lmplot() 是密切相关的,并且共享了大部分的核心功能。然而,了解他们不同的方式很重要,以便您可以快速为特定工作选择正确的工具。

在最简单的调用中,两个函数绘制了两个变量 x 和 y 的散点图,然后拟合回归模型 y〜x 并绘制了该回归线的结果回归线和 95%置信区间:

sns.regplot(x="total_bill", y="tip", data=tips);

sns.lmplot(x="total_bill", y="tip", data=tips);

很显然,所得到的的图的结果是相同的,除了图形形状略有些不同,这里会简短的解释。

目前,要知道的另一个主要区别是 regplot()以各种格式接受 x 和 y 变量,包括 numpy 数组、Pandas 的 Series 列或 DataFrame 对象的变量引用;不一样的是,lmplot()将数据集作为一个必需的参数,而 x 和 y 变量必须指定为字符串。这种数据格式称为 “长格式” 或“整洁”数据。除了这种输入灵活性,regplot()可以看做是拥有 lmplot()特征的子集,所以后面将使用后者进行演示。

备注:

这里官方的例子实际上并不好,比较容易的理解方式是:上面的结果可以在 regplot() 函数中通过只传入 x 和 y 绘出:sns.regplot(x=tips["total_bill"], y=tips["tip"]);而相应的 sns.lmplot(x=tips["total_bill"], y=tips["tip"]) 这种写法就会报错,因为数据集 data 是 lmplot() 的必传参数。

当其中一个变量取值为离散型的时候,可以拟合一个线性回归。然而,这种数据集生成的简单散点图通常不是最优的:

tips.head()

  total_bill    tip    sex    smoker  day    time  size  big_tip

0  16.99    1.01   Female    No  Sun    Dinner   2  FALSE

1  10.34    1.66   Male        No  Sun   Dinner   3  TRUE

2  21.01    3.50   Male        No  Sun    Dinner   3  TRUE

3  23.68    3.31   Male        No  Sun    Dinner   2  FALSE

4  24.59    3.61   Female    No  Sun    Dinner   4  FALSE


sns.lmplot(data=tips,x="size",y="tip")

一个常用的方法是为离散值添加一些随机噪声的 “抖动”(jitter),使得这些值的分布更加明晰。

值得注意的是,抖动仅适用于散点图数据,且不会影响拟合的回归线本身

sns.lmplot(x="size", y="tip", data=tips, x_jitter=.05);

另一种选择是在每个独立的数据分组中对观察结果进行折叠,以绘制中心趋势的估计以及置信区间:

sns.lmplot(x="size", y="tip", data=tips, x_estimator=np.mean);

  

不同类型的模型拟合

上面使用的简单线性回归模型非常简单,但是,它不适用于某些种类的数据集。 Anscombe's quartet数据集显示了一些简单线性回归提供了简单目视检查清楚显示差异的关系估计的例子。 例如,在第一种情况下,线性回归是一个很好的模型:

https://en.wikipedia.org/wiki/Anscombe%27s_quartet

anscombe = sns.load_dataset("anscombe")

sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'I'"),

           ci=None, scatter_kws={"s": 80});

第二个数据集中的线性关系是一样的,但是基本清楚地表明这不是一个好的模型:

sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'II'"),

           ci=None, scatter_kws={"s": 80});

在存在这些高阶关系的情况下,lmplot() 和 regplot() 可以拟合多项式回归模型来拟合数据集中的简单类型的非线性趋势:

sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'II'"),

           order=2, ci=None, scatter_kws={"s": 80});

除了正在研究的主要关系之外,“异常值” 观察还有一个不同的问题,它们由于某种原因而偏离了主要关系:

sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'III'"),

           ci=None, scatter_kws={"s": 80});

在有异常值的情况下,它可以使用不同的损失函数来减小相对较大的残差,拟合一个健壮的回归模型,传入 robust=True:

sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'III'"),

           robust=True, ci=None, scatter_kws={"s": 80});

当 y 变量是二进制时,简单的线性回归也 “工作” 了,但提供了不可信的预测结果:

tips["big_tip"] = (tips.tip / tips.total_bill) > .15

sns.lmplot(x="total_bill", y="big_tip", data=tips,

           y_jitter=.03);

在这种情况下,解决方案是拟合逻辑 (Logistic) 回归,使得回归线显示给定值 x 的 y=1 的估计概率:

sns.lmplot(x="total_bill", y="big_tip", data=tips,

           logistic=True, y_jitter=.03);

请注意,逻辑回归估计比简单回归计算密集程度(Robust 回归也是如此),并且由于使用引导程序计算回归线周围的置信区间,您可能希望将其关闭获得更快的迭代速度(使用参数 ci=None)。

一个完全不同的方法是使用一个 lowess smoother拟合非参数回归。 这种方法具有最少的假设,尽管它是计算密集型的,因此目前根本不计算置信区间:

https://en.wikipedia.org/wiki/Local_regression

sns.lmplot(x="total_bill", y="tip", data=tips,

           lowess=True);

residplot() 是一个有用的工具,用于检查简单的回归模型是否拟合数据集。它拟合并移除一个简单的线性回归,然后绘制每个观察值的残差值。 理想情况下,这些值应随机散布在 y = 0 附近:

sns.residplot(x="x", y="y", data=anscombe.query("dataset == 'I'"),

              scatter_kws={"s": 80});

如果残差中有结构,则表明简单的线性回归是不合适的:

sns.residplot(x="x", y="y", data=anscombe.query("dataset == 'II'"),

              scatter_kws={"s": 80});

  

调节其他变量

上面的图表显示了许多方法来探索一对变量之间的关系。然而,通常,一个更有趣的问题是 “这两个变量之间的关系如何作为第三个变量的函数而变化?” 这是 regplot()和 lmplot()之间的区别。 虽然 regplot()总是显示单个关系,lmplot()将 regplot()与 FacetGrid 结合在一起,提供了一个简单的界面,可以在 “faceted” 图上显示线性回归,从而允许您探索与多达三个其他类别变量的交互。

分类关系的最佳方式是绘制相同轴上的两个级别,并使用颜色来区分它们:

sns.lmplot(x="total_bill", y="tip", hue="smoker", data=tips);

除了颜色之外,还可以使用不同的散点图标记来使黑色和白色的图像更好地绘制。 您还可以完全控制所用的颜色:

sns.lmplot(x="total_bill", y="tip", hue="smoker", data=tips,

           markers=["o", "x"], palette="Set1");

要添加另一个变量,您可以绘制多个 “facet”,每个级别的变量出现在网格的行或列中:

sns.lmplot(x="total_bill", y="tip", hue="smoker", col="time", data=tips);

sns.lmplot(x="total_bill", y="tip", hue="smoker",

           col="time", row="sex", data=tips);

  

控制绘制的大小和形状

在我们注意到由 regplot()和 lmplot()创建的默认绘图看起来是一样的,但在轴上却具有不同大小和形状。 这是因为 func:regplot 是一个 “轴级” 功能绘制到特定的轴上。 这意味着您可以自己制作多面板图形,并精确控制回归图的位置。 如果没有提供轴,它只需使用 “当前活动的” 轴,这就是为什么默认绘图与大多数其他 matplotlib 函数具有相同的大小和形状的原因。要控制大小,您需要自己创建一个图形对象。

f, ax = plt.subplots(figsize=(5, 6))

sns.regplot(x="total_bill", y="tip", data=tips, ax=ax);

相反,lmplot() 图的大小和形状通过 FacetGrid 界面使用 size 和 aspect 参数进行控制,这些参数适用于每个图中的设置,而不是整体图形:

sns.lmplot(x="total_bill", y="tip", col="day", data=tips,

           col_wrap=2, size=3);

sns.lmplot(x="total_bill", y="tip", col="day", data=tips,

           aspect=.5);

  

在其他背景下绘制回归

另外一些 Seaborn 函数在更大,更复杂的绘制中使用 regplot()。 第一个是在上一章分布介绍的 jointplot() 函数。 除了前面讨论的绘图样式之外,jointplot() 可以使用 regplot() 通过传递 kind ="reg" 来显示关节轴上的线性回归拟合:

sns.jointplot(x="total_bill", y="tip", data=tips, kind="reg");

使用 kind="reg" 的 pairplot() 函数结合了 regplot() 和 PairGrid 来显示数据集中变量之间的线性关系。 注意这是不同于 lmplot() 的。 在下图中,两轴在第三个变量的两个级别上不显示相同的关系; 相反,PairGrid() 用于显示数据集中变量的不同配对之间的多个关系:

sns.pairplot(tips, x_vars=["total_bill", "size"], y_vars=["tip"],

             size=5, aspect=.8, kind="reg");

类似 lmplot(),但不同于 jointplot(),使用 hue 参数在 pairplot() 中内置了一个附加分类变量的条件:

sns.pairplot(tips, x_vars=["total_bill", "size"], y_vars=["tip"],

             hue="smoker", size=5, aspect=.8, kind="reg");


大家都在看

plotnine:python数据可视化版ggplot2

Python科研统计作图Plotnine+Seaborn+matplotlib替代R ggplot2系列(1)

Python科研统计作图Plotnine+Seaborn+matplotlib替代R ggplot2系列(2)



加入QQ群可领取: plotnine的数据可视化学习手册


如需联系EasyCharts团队

请加微信:EasyCharts


【书籍推荐】《Excel 数据之美--科学图表与商业图表的绘制》

【手册获取】国内首款-数据可视化参考手册:专业绘图必备

【必备插件】  EasyCharts -- Excel图表插件

【网易云课堂】  Excel 商业图表修炼秘笈之基础篇




今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/JPNGQIiU70
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/28461
 
1533 次点击