本文已参加「新人创作礼」活动,一起开启掘金创作之路。
这次带来的是 RStudio 的统计模型 - 多种回归模型。
各个知识点后面都有对应的小练习哦,大家可以利用刚刚学到的知识来试着写写看!
简单线性回归模型
线性回归模型(linear regression model)是一类非常常用的统计模型, 它通过拟合因变量和自变量之间的线性方程来建立模型. 因变量(dependent variable)必须是一个连续的响应变量(scalar response), 并依赖于一个或多个自变量(independent variables / explanatory variables).
- 线性回归模型的分类
- 一元线性回归方程
- 一元线性回归方程的计算
- 使用
stats包中的lm函数 - 拟合值 & 预测新值
- 一元线性回归方程结果的解读
线性回归模型的分类
- simple linear regression, multiple linear regression
- multivariate linear regression(multiple correlated dependent variables are predicted, rather than a single scalar variable)
一元线性回归方程
如果(我们认为)两个变量(Y, X)之间满足线性关系, 即 Y=β0+β1⋅XY=β0+β1⋅X, 那么就可以根据(Y, X)的观测值算出这个线性方程.
当我们得到了这个线性方程之后, 就可以根据新的X值来计算Y值.
比如现在有两组观测值:
可以列方程算出 β0=−3, β1=3β0=−3, β1=3
现在有三组观测值:
怎么办? 找不到一条直线能穿过这三个点
最小二乘法:
b1 = cov(dat$y, dat$x)/var(dat$x)
b0 = mean(dat$y) - b1 * mean(dat$x)
用stats包中的lm函数拟合线性模型
# lm(formula, data, subset, weights, na.action,
# method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE,
# singular.ok = TRUE, contrasts = NULL, offset, ...)
lm(y ~ x, data=dat)
mod = lm(y ~ x, data=dat)
mod
summary(mod)
str(mod)
mod$coefficients
拟合值 & 预测新值
# 拟合值
mod$coefficients[1] + mod$coefficients[2] * dat$x
mod$fitted.values
# 预测新值
mod$coefficients[1] + mod$coefficients[2] * 5
predict(mod, data.frame(x=5))
# 添加回归直线
plot(y ~ x, data=dat)
abline(mod$coefficients[1], mod$coefficients[2], col=2, lty=2)
plot(y ~ x, data=dat)
abline(mod, col=2, lty=2)
如何解读回归结果
-
方程是否有意义
-
系数是否显著
-
拟合效果: 拟合优度/决定系数(coefficient of determination):
R2=1−SSresidualSStotal, where SSresidual=∑(y−y^)2, SStotal=∑(y−y¯)2R2=1−SSresidualSStotal, where SSresidual=∑(y−y^)2, SStotal=∑(y−y¯)2
Residuals:
Min 1Q Median 3Q Max
-29.069 -9.525 -2.272 9.215 43.201
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -17.5791 6.7584 -2.601 0.0123 *
speed 3.9324 0.4155 9.464 1.49e-12 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 15.38 on 48 degrees of freedom
Multiple R-squared: 0.6511, Adjusted R-squared: 0.6438
F-statistic: 89.57 on 1 and 48 DF, p-value: 1.49e-12
练习
# Q1
# 手工计算线性拟合方程, 数据: x=c(2,4,3), y=c(3,9,4)
# Q2
# 不使用lm函数, 编程计算 Y: dist 与 X: speed 之间的线性拟合方程, 数据来自 cars
习题
# Q1
# 使用lm函数, 计算 Y: dist 与 X: speed 之间的线性拟合方程并画图, 数据来自 cars
# Q2
# 上题的数据中包含50个样本, 其中误差(拟合值与真实值之差)最大的是哪个样本?
各种模型的拟合
- 普通的线性模型
- 不含常数项/截距项/intercept
- 非线性模型
# 普通的线性模型
# 拟合数据集 mtcars 中 mpg(作为Y)与wt(作为X)之间的关系
# mpg = b0 + b1*wt
plot(mpg ~ wt, data=mtcars)
mod1 = lm(mpg ~ wt, data=mtcars)
summary(mod1)
# 不含常数项/截距项/intercept
# mpg = b1*wt
mod2 = lm(mpg ~ wt - 1, data=mtcars)
summary(mod2)
# 其实现在我们也能处理一些非线性模型了, 只要这些模型可以转换成线性的形式
# 非线性模型举例1
# mpg: miles per gallon, 按照物理知识, 汽车跑每单位路程所需的汽油应该与车重成正比
# 考虑用 1/mpg 作为Y
plot(1/mpg ~ wt, data=mtcars)
mod3 = lm(1/mpg ~ wt, data=mtcars)
summary(mod3)
# 如果车重非常接近于0, 那么每单位路程所需的汽油也应该接近于0
mod4 = lm(1/mpg ~ wt - 1, data=mtcars)
summary(mod4)
# 非线性模型举例2
# 模拟一个按平方根增长的数据 y = b0 + sqrt(b1*x)
set.seed(1234)
x2 = runif(30, 0, 10)
y2 = 2 + sqrt(9*x2) + rnorm(30, 0, 0.5)
plot(x2, y2)
mod5 = lm(y2 ~ sqrt(x2))
f2 = function(x) mod5$coefficients[1] + sqrt(mod5$coefficients[2]^2 * x)
curve(f2, 0, 10, add=T, col=2, lty=2)
# 非线性模型举例3
# 流行病爆发初期的感染人数通常是指数增长的
# y = b0 * exp( b1*x )
# 模拟一个按照指数增长的数据 y = b0 * exp(b1*x)
set.seed(9527)
x3 = 1:10
y3 = round(2.5*exp(0.8*x3 + rnorm(10,0,0.3)))
plot(x3, y3)
lm(y3 ~ exp(x3) )
lm(log(y3) ~ x3)
# 非线性模型举例4
# 按照物理知识, 刹车距离应该跟速度的平方成正比
plot(dist ~ speed^2, data=cars)
mod6 = lm(dist ~ speed^2, data=cars) # wrong formula, 因为x^n在回归模型的formula中有另外的意思
summary(mod6)
mod7 = lm(dist ~ I(speed^2), data=cars) # right
summary(mod7)
# 另一种方法: 直接创建出所需变量
cars$sp2 = cars$speed^2
mod8 = lm(dist ~ sp2, data=cars)
summary(mod8)
练习
# Q1
# 在 "非线性模型举例3" 和 "非线性模型举例4" 的原始图像上添加拟合出的曲线
# Q2
# 想办法修改 mod7, 提高它的拟合优度
习题
# Q1
# 使用 lm 函数, 计算 Y: price 与 X: carat 之间的线性拟合方程, 数据来自之前的 dia_a.
# 注意: 数据集里面有缺失值
# Q2
# 想办法修改Q1中的模型, 提高它的拟合优度
# Q3
# 上题的数据中包含很多样本, 其中误差(拟合值与真实值之差)最大的是哪个样本?