小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型(谁知道原文出处告诉我一下谢谢)

今天我开始切入了 Linear models with quantitative data 这一Tutorial, 让seaborn拼图增加了一块大大的领土.

初识lmplot

在之前讲解distribution分布一节中, 主要围绕的是单(双)样本间各自样本的形态, 或者是两个样本间的形态差异. 还未涉及到分析多个样本间的依赖关系. 后者需要借助于更复杂的工具来实现, 比如用线性函数来表达这一关系的线性回归模型, seaborn专门为此制定了强大的lmplot可以解决大多数本原线性模型.

这一节将会对定量数据, 线性模型做一个详尽的讲解.首先是 lmplot (plot for linear model).

lmplot 最简单的 y~x 模型

Visualizing Multiple regression with lmplot()

lmplot, 首先要明确的是:它的输入数据必须是一个Pandas的’DataFrame Like’ 对象, 然后从这个DataFrame中挑选一些参数进入绘图充当不同的身份.观察下面几行代码, 你就能一目了然了:

# 有的时候, 受测试环境制约, 我有可能会把数据从本地导入; 数据集文件同样是来自于seaborn-data tips = pd.read_csv('c:/tips.csv', index_col=False) # tips = sns.load_dataset('tips') # 网络环境正常的话也可以这样直接导入  # 直接作图, 使用我喜欢的xkcd style with plt.xkcd():     sns.color_palette('husl', 8)     sns.set_context('paper')     sns.lmplot(x='total_bill', y='tip', data=tips, ci=65, color='indianred')

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

参数解释,

在上面的lmplot()中, x, y, data(前三个不可省略)分别表示回归的自变量, 回归变量和数据源;

ci用于描述置信区域(confidential interval)的大小, 往往是65, 97这样的标准差的整数倍取值; color是颜色控制.

有的人可能会看到"线点分离"的效果, 是的, 我在一开始也是抱着这样的想法 — 希望用更突出的颜色来强调回归直线的位置, 而不是将它与scatter群混在一起.

控制散点图和直线的参数分别是 scatter_kws, line_kws先观察下面的代码:

sns.lmplot("total_bill", "tip", tips,            scatter_kws={"marker": ".", "color": "slategray"},            line_kws={"linewidth": 1, "color": "indianred"});  #{scatter, line}_kws : dictionaries, optional #Additional keyword arguments passed to scatter() and plot() for drawing the components of the plot.

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

解释: 实际上 scatter_kwsline_kws 两个参数是来自于 regplot, 因为lmplot是继承于regplot 因此顺利得到这对参数.

第二阶: y~x[d1, d2, …dn] 自变量取离散值的回归

Plotting with discrete predictor variables

x, y均是连续型取值应该是简单情形, 联想到最小二乘, 联想到一个凸优化问题, …, 下面来起讨论x, y二者之一取离散值(descrete int).因为若x, y均是离散水平就是涉及到的离散型卡方检验(Chi-Square Test)/列联表(cross table)之类的范畴了, 非本节讨论范围.

还是利用小费数据集, 这次把total_bill 账单金额替换为size 权当是用餐人数好了.

sns.lmplot(‘size’, ‘tip’, tips)

可以看到, 在代码的结构组成, 与上面的形式看不出任何差异. 不过输出的形式却有很大不同, 而且其难点在于对数据的解读. 这种图形结合到现实的话稍有难度. 现实意义: 人越多小费越多(当然前面的总账单金额和小费的正向关系也是直觉的产物), 但不同人数的权重是否有考虑;是否直线被极端group产生了杠杆导致有偏严重? 这类信息还是很难在图中读取出来.

plt.figure() # 为了进一步查看各size水平下tip的分布, 可能还需要展示更多 sns.lmplot('size', 'tip', tips, x_estimator= np.mean) # 如果说回归直线基本是在各组mean值上下微小浮动, 说明直线并没有受到部分size水平的影响. # 关于 x_estimator 我想不难理解 - > 对拥有相同x水平的y值进行映射

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

我想对于 y-x 模型中 x连续与x离散的差异性还有很多没有提到的. 这里只是学生的粗浅直觉.

jitter

jitter是个很有意思的参数, 特别是处理靶数据的overlapping过于严重的情况时, 通过增加一定程度的噪声(noise)实现数据的区隔化, 这样原始数据是若干 点簇 变成一系列密集邻近的点群. 另外, 有的人会经常将 rugjitter 结合使用. 这依人吧.

对于横轴取离散水平的时候, 用x_jitter可以让数据点发生水平的扰动.但扰动的幅度不宜过大, 比如看官可以尝试一下超过0.5会发生什么.

sns.lmplot(‘size’, ‘tip’, tips, x_jitter=.15)

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

注. jitter 与 estimator参数是冲突的. 不应共同使用.

连续数据离散化

将一个连续型数据映射为有限个(1=2量级的缩小水平)的方法有很多, 对于一维-一维的常用思路是通过一个breaks列表中的各个cut points实现对原始数据的有限切分, 即让原始数据落在目标区间群中唯一的区间中.然后用区间位置作为新的变量. 因为多数情况下是数值型, 所以组标识是离散整数表示, 这样起到离散化,同时保留了Order的知识.

说了这么多, 其实就是想讲lmplot中的这个参数 x_bins

bins = [10, 20, 30, 40]  fig = plt.figure(figsize=(16, 10)) sns.lmplot('total_bill', 'tip', tips, x_bins = bins) plt.xlabel('bins-list')

若 x_bins 换成一个整数? 请你自己试试吧

Facet plot

我明白的另一个事实就是, 现实模型是远比 y~x要复杂的.不过学习还是一点一点深入的过程.

数据的Facet Plot要借助于第三变量, 起到切片/切面的效果.

分组形式1: hue参数

hue是个很重要的参数, 不只出现在lmplot.还是用之前的参数, 以及在本节第一行正式代码的结尾参加这个参数, 记住:要指定一个categorical variable!

hue通过指定一个分组变量, 将原来的y~x关系划分成若干个分组:

y1~x1 | y2~x2 | …

然后再用不同的color将数据统一展示到一张图中.

with plt.xkcd():     sns.lmplot('total_bill', 'tip', data=tips, hue='day')     plt.xlabel('hue = day')

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

类似的, 你还可以绘制tips数据集中以其它分组变量的图形, 如smoker.

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

通过比较不同分组的斜率, 还是能得到一些有意思的结论, 比如相同账单金额的水平, 不抽烟的顾客可能给付更高的小费.

hue相关辅助参数
  • marker, 用于数据点的外观标识
  • hue_order 控制hue组类别的排序

对于很多情况下的categorical-label类的值, seaborn多能提供一些xxx_order的参数来控制展示的顺序(从左-右, 上-下 诸如此类)hue_order但是用来 控制hue组类别的排序的. 比如tips中day参数拥有超过2个水平时, 排序问题就应该注意了. (在我看来, 水平为2的情况 不須指定排序)

# hue_order g = sns.lmplot("total_bill", "tip", tips, hue="day", palette="Set2", hue_order=["Thur", "Fri", "Sat", "Sun"]) g.set_axis_labels("Total bill (US Dollars)", "Tip"); g.set(xticks=[10, 30, 50], ylim=(0, 10), yticks=[0, 2.5, 5, 7.5, 10]);

为什么要指定顺序呢? 这是因为分组的属性是一周时间内的日期 == 一个明显的order/interval变量, 所以人工指定新的顺序, 不然系统只能用字典排列了.

这里还引用了另一种Handler 句柄化的操作方式.

即sns生成的绘图对象, 然后调用对象的set类函数, 实现对g的局部配置. (上面的set_axis_labels, set(xticks, ylim, yticks))

plt.xkcd() sns.lmplot("total_bill", "tip", tips, hue="smoker", markers=["x", "o"]);

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

分组形式2: col 参数

如果要将不同水平单独画出来了就可用这个参数, col表示column.

sns.lmplot(‘total_bill’, ‘tip’, data=tips, col=’smoker’)

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

col与hue共用会产生怎样的效果?

当写完hue col的展示之后, 我不禁产生这样的疑问.于是我也分为两种情况, 第一种比较容易想到, 就是hue = col的取值.

sns.lmplot('total_bill', 'tip', data=tips, col='smoker', hue='smoker')

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

那如果col指定day, 而hue指定smoker呢?我还是希望自己去试试吧!

lmplot不仅仅能画直线

在研究生期间, 我接触过非线性模型又再次分为本原线性和本原非线性模型, 即通过对x,y进行transform从而得到一个线性模型. 如果是这样的模型也是在广义线性模型的范畴内的.

我也是初识seaborn, 通过文档介绍也发现它也是支持一些简单的非线性模型的.

实际上一个lmplot在一开始的图中能看出就是由简单的scatter图和一条简单的线组成(ci置信区域不妨就当作直线的衍生产物). 因此. 能不能只显示一种?

Non-linear

Polynomial Trends

非线性关系里比较简单的方式是过渡至多项式关系, 一般用2-3次的关系来查看是否比一次线性更好的拟合数据.

sns.set_style('dark') sns.set_context('talk') sns.lmplot('size', 'total_bill', tips, order=2) plt.title('# poly order = 2') plt.figure() sns.lmplot('size', 'total_bill', tips, order=3) plt.title('# poly order = 3')

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

lowess

LOESS and LOWESS (locally weighted scatterplot smoothing)

对于Lowess不熟悉的人, 可能要事先作一些homework了. 简单的理解是对简单最小二乘作了复杂化.通过分类, 聚集, 计算变换, 加权等方式改变了最小二乘的原始最优问题, 也许看结果会像是指数平滑的结果, 但其机理还要比k-neighbors平滑稍稍麻烦一些.

如果有兴趣, 可以学习一下 wiki, 或者曾记得stanford前老师Ng老师课中有提到.

sns.set_style('dark') sns.lmplot('total_bill', 'tip', tips, lowess=True, line_kws={'color': '.2'}) plt.title('figure with  lowerss=True')   plt.figure() sns.set_style('white') sns.lmplot('total_bill', 'tip', tips, lowess=False, line_kws={'color': '.4'}) plt.title('figure with  lowerss=False')

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

Logistic 回归

L回归是描述y[0,1] ~ x(连续)的问题注: (y多水平的情况就先… 不考虑了)

首先, 由于原数据tips中没有符合logistics建模条件y变量, 我们先人工计算一个, 计算规则是小费占比是否大于10%.

# make a target Y as logistic predit variable  tips['big_tip'] = (tips['tip'] / tips['total_bill'] ) > .1 print tips.head() sns.lmplot('total_bill' , 'big_tip',y_jitter=.15, data=tips)

依照着之前设置xjitter的方式, 这里设置了yjitter.

# logistic model sns.set_style('whitegrid') sns.lmplot("total_bill", "big_tip", tips, y_jitter=.05, logistic=True);

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

lmplot 其它参数

  • fit_reg 这也是来自于 regplot 的参数 取值为bool型.

sns.lmplot("total_bill", "tip", tips, hue="time", palette="Set1", fit_reg=False);

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

  • n_boost robust

为了减少Outliers对模型整体的影响(outliers的占比应该是很少的, 而不是和其它大众群体一样权重). 如有兴趣搜索bootstrap.

sns.lmplot('total_bill', 'tip', data=tips, robust=True, n_boot=500)

  • others

    • xlabel ylabel 指定标签.
    • x_partial y_partial 关于水平 垂直的偏量分解我接触不多. 不过在我理解一个主要应用是用来作实验效应, 比如x y如果单纯作图时发现有显著线性相关. 可以如果x y均与 c 有交互效应, 将c作为partial进行分解之后就能看到其实x y 的相关性多是取决于c的. 把c的效应抹去, x y 就未必显著了. 有兴趣尝试这段代码
import seaborn as sns iris = sns.load_dataset("iris") sns.regplot("sepal_length", "sepal_width", data=iris,             x_partial=iris[["petal_length", "petal_width"]])
 - truncate

其它相关的函数

regplot

之前曾经提过lmplot是regplot(regression plot)的上级函数, 很多参数是继承自regplot的.

用下面一个简单例子来演示.

f, (ax1, ax2) = plt.subplots(1, 2, sharey=True) sns.regplot('total_bill', 'tip', data=tips, ax=ax1) sns.boxplot(tips['tip'], tips['size'], color='Blues_r', ax=ax2).set_ylabel("") f.tight_layout()

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

不同类型的图形,如何组合, 挑选哪样的图形类型, 这其中这也是数据作图的哲学. 我想还得要有大量的经验积累.

residplot

残差图是用来检视一个回归模型优劣的一个快速, 直观的工具.一个回归模型的本质就是为了"提纯", 因为回归模型其前提是我们假定

Y = F(X) + err,

所以回归曲线如果已经描述出Y = F(x)

那么剩下的err 的分布就应是如同white noise一样的分布(随机正态分布, 方差为给定值)

当然这一系列的一厢情愿只是美好的理论层幻想.

为了演示residplot, 需要自建一些测试数据.

说明, multivariate_normal 这是生成多元正态分布的numpy-random 不常用函数(因为生活中更多的还是一维啦). 其中第一位置是指定多元各元的期望均值; 第位置是一个n*n 的协方差矩阵, 然后最后一个位置是sclar型的, 描述多元样本的容量.

# sample data x , y =np.random.multivariate_normal([1, 5], [(2,-.8), (-.8, 2)], 80).T  ax = sns.regplot(x, y , color='slategray') ax.set(xlabel='xxx', ylabel= 'yyy')

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型 能看到x y 之间有较显著的线性关系. 再用残差图来识别此模型.

sns.residplot(x, y , color=’indianred’)

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

基本没问题, 残差线分布 y = 0 边缘, 几乎重合.

当然了, 残差图的内部也是要考虑x y 之间的关系类型的, 用线性残差图不能很解释二次关系.

y = x + 1.5 * x ** 2 + np.random.randn(len(x))  sns.residplot(x, y, color='indianred') plt.figure() sns.residplot(x, y , color='slategray', lowess=True)

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

再来看jointplot

在上一节中我曾经提过用jointplot画x, y 两个连续值的分布, 以及用hex(正六边形)的集中色块来突显出x*y 笛卡尔空间中密集的hot area.这一节再次出现jointplot, 也是为了说明这个函数的强大之处.

首先可以先想象一下这段代码的显示结果.

sns.jointplot("total_bill", "tip", tips);

还记得kind参数吗? 如果不指定的话 kind默认是point, 一个点表示一个观测. 上一次用的形式为kind=’hex’ , 现在我们来查看另一个有意思的参数.

为了强调这一部分, 我还找了几种有意思的RGB颜色, 不过我的FF水平比较差, 请见谅.

# 实际上Jointplots 可以画出reg直线来. 多提一句,jointplot调用了JointGrid Layout, 未来若有机会我还打算深入学习关于 SpecLayout等几种 Subplot的高级扩展方式.  sns.jointplot('total_bill', 'tip', data=tips,kind='reg', color='#ddddff')

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

这是reg回归模块, 同样的 jointplot还支持resid残差模块.

# 类似的, 能把Reg 换成Resid sns.jointplot('total_bill', 'tip', data=tips, kind='resid', color='#774400')

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

插入, 冷知识 – 德比郡足球俱乐部. 成立于1884年. 2002年开始凋零, 目前在哪徘徊还不清楚.

interactplot()

这个函数我之前没见过, 现在暂时没有完全掌握. 这里不提.

corrplot()

查看数据集中两两相关的程度, 在R中是用correlation matrix plot来实现的.seaborn中使用corrplot.

  • 有缺失值数据
  • fill/drop 缺失
titanic = sns.load_dataset('titanic')#.dropna() sns.corrplot(titanic)
titanic = sns.load_dataset('titanic').dropna() sns.corrplot(titanic)

比较结果的差异.

基本上corrplot的图形组成分为几部分: 相关系数矩阵被cmap映射后的色块矩阵.主对角线是默认的变量名称. 如果想要隐藏一部分, 要进行相关的参数调整.

demo

# cmap 控制颜色映射帽子  cbar 设置是否显示右边小条 f, ax = plt.subplots(figsize=(10, 10)) cmap = sns.blend_palette(["#00008B", "#6A5ACD", "#F0F8FF",                           "#FFE6F8", "#C71585", "#8B0000"], as_cmap=True) d = np.random.standard_t(20, (100, 30)) sns.corrplot(d, annot=False, diag_names=False, cmap=cmap) ax.grid(False);

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

了解更多的corrplot可以参见参数说明 corrplot

corrplot在刚一开始对输入变量的colinearity(共线性)的识别还是很有帮助的,

例如下图:

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

coefplot

在回归模型中, 回归系数是模型结果, 模型评估的重要参考. 对于每个进入到回归模型的 x_i.coefplot 会使用如同R中回归模型中的模型表达式来指定预测变量和自变量, 然后输出各自的系数(以及每个系数估计的置信区间).

sns.coefplot('tip ~ scale(total_bill) + size + time + sex + smoker', tips)

小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

附加参数

coefplot的默认参数列表:

seaborn.coefplot(formula, data, groupby=None, intercept=False, ci=95, palette='husl')

  • intercept=对于截距项并不是在公式中指定, 默认值False,即回归曲线经过原点, 若要增加常数效应,要用intercept=True来指派.

  • palette=

    色板的设置. 默认Husl, 可用其它Set代替.

    sns.coefplot("score ~ center(solutions) * attention", attention, intercept=True, palette="Set1");

    小数据分析师学 Python 之 Seaborn(二):定量数据的线性模型

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值