Seaborn 回归分析绘图
2021-11-14 本文已影响0人
山药鱼儿
在正式开始任务前,我们先来导入工具包,并执行魔法指令:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
今天使用的数据集是关于顾客小费的记录,可以直接使用 Pandas 读取该内置数据集:
tips = pd.read_csv("tips.csv")
tips.head()
读取结果:
假设,我们现在需要研究顾客的消费总额 taotal_bill
与小费 tip
的关系。这是,可以借助 sns.regplot
函数,不仅可以绘制出两个特征构成的散点图,还会绘制出一条线性拟合的直线:
sns.regplot(x='total_bill', y='tip', data=tips)
其中,data
为特征所在的 DataFrame ,x
y
分别为特征使用的列名。
接下来,假设我们研究每单顾客的人数与小费的关系。
sns.regplot(x='size', y='tip', data=tips)
分析结果:
由于每单的顾客人数是离散值,所有的点在竖直方向上都是堆叠在一起的,非常不利于拟合。
这时,我们可以给 sns.regplot
传入抖动参数:x_jitter
或者 y_jitter
。此处我们希望在 X 轴方向让数据左右抖动一下,这样就不会堆叠在一起了,以优化拟合模型:
sns.regplot(x='size', y='tip', data=tips, x_jitter=0.1)
分析结果:
Anscombe 奇特数据
为了说明绘图的重要性呢?我们来学习一下统计学家 F.J. Anscombe 曾经做过的统计学实验。
1973年,Anscombe 构造出了四组奇特的数据。告诉人们,在分析数据之前,描绘数据所对应的图像有多么的重要。
这四组数据中:
-
x 值的平均数都是
9.0
,y 值的平均数都是7.5
; -
x 值的方差都是
10.0
,y 值的方差都是3.75
; - 它们的相关度都是
0.816
,线性回归线都是y=3+0.5x
。
单从这些统计数字上看来,四组数据所反映出的实际情况非常相近,而事实上,这四组数据却大相径庭。
dataset = pd.MultiIndex.from_product([['I','II', 'III', 'IV'], ['x','y']])
df = pd.DataFrame(np.zeros((11,8)),columns=dataset)
df.iloc[0] = [10.0,8.04,10.0,9.14,10.0,7.46,8.0,6.58]
df.iloc[1] = [8.0,6.95,8.0,8.14,8.0,6.77,8.0,5.76]
df.iloc[2] = [13.0,7.58,13.0,8.74,13.0,12.74,8.0,7.71]
df.iloc[3] = [9.0,8.81,9.0,8.77,9.0,7.11,8.0,8.84]
df.iloc[4] = [11.0,8.33,11.0,9.26,11.0,7.81,8.0,8.47]
df.iloc[5] = [14.0,9.96,14.0,8.10,14.0,8.84,8.0,7.04]
df.iloc[6] = [6.0,7.24,6.0,6.13,6.0,6.08,8.0,5.25]
df.iloc[7] = [4.0,4.26,4.0,3.10,4.0,5.39,19.0,12.50]
df.iloc[8] = [12.0,10.84,12.0,9.13,12.0,8.15,8.0,5.56]
df.iloc[9] = [7.0,4.82,7.0,7.26,7.0,6.42,8.0,7.91]
df.iloc[10] = [5.0,5.68,5.0,4.74,5.0,5.73,8.0,6.89]
df
数据内容如下:
下面,我们将这四组数据分别绘制出来:
plt.figure(figsize=(8,8))
plt.subplot(221)
sns.regplot(x="x", y="y", data=df['I'], scatter_kws={"s": 40, "color":'orange'})
plt.subplot(222)
sns.regplot(x='x', y='y', data=df['II'], scatter_kws={'s':40, 'color':'orange'})
plt.subplot(223)
sns.regplot(x='x', y='y', data=df['III'], scatter_kws={'s':40, 'color':'orange'})
plt.subplot(224)
sns.regplot(x='x', y='y', data=df['IV'], scatter_kws={'s':40, 'color':'orange'})
绘制结果:
是不是实际上 4 组数据相差太远了!比如第二组数据,使用线性回归函数拟合显然是不合理的。
sns.lmplot(x='x', y='y', data=df['II'], scatter_kws={'s':100, 'color':'orange'}, order=2)
更好的拟合结果: