前面在13.1做过一些ggplot的简单拟合曲线和置信区间,今天我们就对ggplot2绘制回归曲线的方法作个汇总学习。在众多的包中,相对而言,ggplot2是R里面非常专业的作图包,其同时涵括了多种类型的回归模型在内,这使回归曲线的实现更加轻松。这次还是以最常见的双变量关系分析(一元回归)为例,展示回归曲线通过ggplot2的绘制方法。
ggplot2内置了回归统计函数,我们也比较熟悉一些,在13.1我们用的是geom_smooth,其实还有一个就是stat_smooth()。两个函数的使用方法大致一致,可基于给定的双变量关系拟合指定的回归,默认方法包含局部加权回归(loess)、一般线性模型(lm)、广义线性模型(glm)、广义加性模型(gam)以及一些非线性回归(nls,如指数回归)等,并同时将双变量关系的回归线绘制在二维图中表示出来。此外,结合一些拓展包也可以实现更多非线性回归的作图。接下来我们通过几个例子详细的了解不同模式回归曲线通过ggplot2函数的绘制方法。
=======局部加权回归(loess)的平滑拟合========
平滑回归方法中,局部加权回归(LOESS)是最常用的平滑器。在函数stat_smooth()或geom_smooth()中通过method = 'loess'指定局部加权回归的平滑拟合,并通过span参数控制曲线平滑度。
测试数据我们用的是MASS包的内置数据集Boston,记录了波士顿郊区的房屋价值与当地社会环境、人口组成等信息。
library(ggplot2)
library(patchwork)
#MASS 包的示例数据集,波士顿郊区的房屋价值。
library(MASS)
data(Boston)
p <- ggplot(data = Boston, aes(x = medv, y = lstat)) +
geom_point() +
theme_bw()
p
##拟合局部加权回归(loess),并展示 95% 置信区间
#stat_smooth() 参数 span 可控制曲线平滑度,值越大拟合曲线越平滑
#注意平滑参数值应当谨慎设置,它强烈影响曲线意义的解读
p1 <- p + stat_smooth(method = 'loess', span = 0.5, se = TRUE, level = 0.95)
p1
#类似地,geom_smooth() 参数中,span 控制曲线平滑度
p2 <- p + geom_smooth(method = 'loess', span = 0.75, se = TRUE)
p2
p1|p2
从图中来看,两个函数的作用差不多。而就平滑曲线本身,展现了居住地房屋价格越高,当地低收入人口比例越低。可能与低收入人群难以负担得起较高居住地的成本,而更多选择廉价的房屋租赁或长期居住有关。
======一般加性模型的平滑拟合=======
实现非参数平滑回归的另一方法是使用加性模型。在函数stat_smooth()或geom_smooth()中通过method = 'gam'指定加性模型的平滑拟合,并通过在formula参数中选择平滑器参数实现。默认情况下,该函数假定响应变量服从正态分布,并执行一般加性模型的形式。
##gam 默认情况下执行一般加性模型的平滑回归,并展示 95% 置信区间
#通过 formula = y~s(x) 指定函数关系,s() 中的参数 k 可调整平滑度
#注意平滑参数值应当谨慎设置,它强烈影响曲线意义的解读
p3<-p + stat_smooth(method = 'gam', formula = y~s(x, k = 10), se = TRUE, level = 0.95)
p4<-p + geom_smooth(method = 'gam', formula = y~s(x, k = 5), se = TRUE)
p3|p4
和loess曲线一样,从平滑曲线本身来看,展现了居住地房屋价格越高,当地低收入人口比例越低。
=====一般线性模型(lm)之简单线性回归=====
前面我们在13.1其实用的也是lm,也就是一般线性回归,这也是最常使用的简单线性回归。函数stat_smooth()或geom_smooth()中,通过method = 'lm'指定线性回归拟合变量关系,默认绘制Y=β1X+β0形式的简单线性回归形式。
##一般线性模型(lm),并展示 95% 置信区间
#stat_smooth() 拟合简单线性回归
p5 <- p1 + stat_smooth(method = 'lm', se = TRUE, level = 0.95, color = 'red')
p5
#geom_smooth() 拟合简单线性回归
p6 <- p2 + geom_smooth(method = 'lm', se = TRUE, color = 'red')
p6
我们把loess的曲线和lm放在一起做个对比,来看下2者拟合的区别。
p5|p6
#蓝线,非参数loess平滑拟合;红线,普通线性回归拟合。
=====一般线性模型(lm)之带多次项的线性回归====
#geom_smooth() 默认 formula=y~x 对应一次关系,可更改 formula = y~poly(x, n) 拟合 n 次关系
p7<-p1 + stat_smooth(method = 'lm', formula = y~poly(x, 2), se = TRUE, level = 0.95, color = 'green3')
#同样地,geom_smooth() 默认 formula=y~x 对应一次关系,可更改 formula = y~poly(x, n) 拟合 n 次关系
p8<-p2 + geom_smooth(method = 'lm', formula = y~poly(x, 2), se = TRUE, color = 'green3')
p7|p8
====非线性参数回归示例之指数回归=====
再展示一例常见的参数非线性回归方法,指数回归在ggplot2中的绘制。
以波士顿郊区的房屋价值数据集为例,通过局部加权回归(LOESS)的平滑曲线观察居住地房屋价格和人均城镇犯罪率的关系时,发现二者似乎存在指数关联。随人均城镇犯罪率的升高,房屋价格开始呈现剧烈的下降,随后达到平缓。因此,考虑在图中拟合指数回归曲线。
p <- ggplot(data = Boston, aes(x = crim, y = medv)) +
geom_point() +
theme_bw() +
stat_smooth(method = 'loess', span = 0.5, se = TRUE, level = 0.95)
p
通过在stat_smooth()或geom_smooth()中指定method = 'nls'即可拟合参数非线性回归,formula中设置非线性回归式,method.args中设定一些必要的补充信息。
p9<-p + stat_smooth(method = 'nls', formula = y ~ a*x^b, method.args = list(start = list(a = 2, b = 1.5)), se = FALSE, color = 'red')
p10<-p + geom_smooth(method = 'nls', formula = y ~ a*x^b, method.args = list(start = list(a = 2, b = 1.5)), se = FALSE, color = 'red')
p9|p10
蓝线,非参数loess平滑拟合;红线,指数回归拟合曲线。这个指数回归大致描述出了随人均城镇犯罪率的升高,房屋价格首先呈现剧烈的下降,并在随后达到平缓的趋势。
====泊松加性模型======
下面,我们测试2个泊松分布的例子。先来测试gam,也就是广义加性模型之泊松分布。
测试数据记录了河流中某鱼类个体数量与水体环境的关系,非正态分布的一个例子。
dat <- read.delim('fish_data.txt', sep = "\t", row.names = 1)
p <- ggplot(data = dat, aes(x = acre, y = fish)) +
geom_point() +
theme_bw()
p
前面我们测试过,在函数stat_smooth()或geom_smooth()中通过method = 'gam'指定加性模型的平滑拟合。由于函数默认响应变量服从正态分布并执行一般加性模型的形式,因此在这里需要额外在参数method.args中指定响应变量的泊松分布,以执行泊松加性模型。此外,还需在formula参数中设定平滑器参数。
p1 <- p + stat_smooth(method = 'gam', formula = y~s(x, k = 5), method.args = list(family = 'poisson'), se = TRUE, level = 0.95)
p2 <- p + geom_smooth(method = 'gam', formula = y~s(x, k = 3), method.args = list(family = 'poisson'), se = TRUE)
p1|p2
从2张图的对比可以看出,平滑参数对于曲线的拟合还是至关重要的。
从上面的拟合曲线来看,非参数的泊松加性模型显示了鱼类物种数量随水域流域面积的增加而提升,这种提升效应似乎可以通过线性关系来描述。因此,接下来不妨使用参数化的广义线性模型描述这个趋势,即泊松回归,通过method = 'glm'指定使用广义线性回归拟合变量关系,并需额外在参数method.args中指定响应变量的泊松分布。
p3<-p1 + stat_smooth(method = 'glm', method.args = list(family = 'poisson'), se = TRUE, level = 0.95, color = 'red')
p4<-p2 + geom_smooth(method = 'glm', method.args = list(family = 'poisson'), se = TRUE, color = 'red')
p3|p4
但是具体采用什么拟合方式,主要看自己的数据分布,以及自己想说明的问题。