第20讲:从一元到多元线性回归

数据挖掘与R语言

2026年11月10日

本讲导览

One More Variable, Three Numbers — 项目五·基础版

  • 一、前课测验与情境导入 —— 一元的三个数先读熟
  • 二、加一个变量 —— 二元系数怎么读、方程怎么写
  • 三、换一个变量 —— 变量换了,结论就变了
  • 四、综合实战 —— 自己挑第二个变量,比出更好的模型
  • 五、课堂总结 —— 学习成果确认与 Exit Ticket

重要

第19讲我们用一个自变量拟合了一条直线。今天把它升级成两个自变量:写法只多一个 +,但系数的读法要多带半句话,而判断模型好坏,全程只用三个数——R²、系数的 p 值、F 检验的 p 值。

本讲有两页练习和一页综合实战要当场动手:每人从 mtcars 里自己挑一个变量放进模型,用那三个数比出结论。全程只用 R 内置数据,不装包、不下载。

本讲学习目标

学完这一讲,你能够:

  • 把一元回归写成二元回归:lm(y ~ x1 + x2, data = ...)
  • 在 summary() 输出里一次读出三个数:R²、每个系数的 p 值、最后一行 F 检验
  • 用答题模板解释二元系数,不漏"在另一个变量不变时"这半句话
  • 由 Estimate 列写出回归方程,并代入 newdata 算出预测值
  • 换一个自变量重跑一遍,用三个数判断"换得好不好"
  • 说清 mpg 越大越省油:系数为负是每加仑行驶里程减少,不是"油耗下降"

一、前课测验与情境导入

第19讲:一元线性回归 → 今天:再加一个自变量

1.1 选择题(每题 1 分钟)

1. lm(销量 ~ 广告费, data = ad_data) 中,~ 左边的 销量 是:

A. 自变量  B. 因变量(要预测的 y)  C. 残差  D. 样本量

2. 第19讲那份广告数据的输出里 Multiple R-squared: 约等于 0.851,意思是:

  • A. 差不多 85% 的点正好落在回归线上
  • B. 销量的波动里约 85% 能由广告费解释
  • C. 预测值有 85% 的概率正确
  • D. 广告费与销量相关的概率是 85%

1.2 填空题(每题 1 分钟)

3. lm() 估计回归系数时,要让 ______ 最小,这种方法叫 ______。

4. 读 summary(m):系数的估计值看 ______ 列;判断某个变量是否显著,看它这一行的 ______ 值。

提示

今天再加一个数:输出最后一行 F 检验。三个数凑齐,一份回归结果就能读下来了。

1.3 本讲唯一的数据:32 辆汽车

mtcars 是 R 内置数据,取自 1974 年美国《Motor Trend》对 32 款车型的测试。本讲只用其中四个变量:

变量 含义 单位
mpg 每加仑汽油能跑多远(数值越大越省油) 英里/加仑
wt 车重 千磅
hp 总马力 马力
disp 发动机排量 立方英寸
▶️ 查看代码
mtcars %>%                             # R 内置的 32 辆车数据
  select(mpg, wt, hp, disp) %>%        # 只看本讲要用的四列
  head(4)                              # 先展示前 4 行
                mpg   wt  hp disp
Mazda RX4      21.0 2.62 110  160
Mazda RX4 Wag  21.0 2.88 110  160
Datsun 710     22.8 2.32  93  108
Hornet 4 Drive 21.4 3.21 110  258

警告

mpg 是每加仑能跑多少英里,不是"耗了多少油"。所以车越重,mpg 的数值变小、里程变短,含义才是"更费油"。

说成"车重每增 1 千磅,油耗下降"——方向和单位都反了。应该是"每加仑行驶里程平均减少多少英里"。

1.4 先看散点图:车越重,每加仑跑得越短

▶️ 查看代码
ggplot(mtcars, aes(x = wt, y = mpg)) +      # 数据 + 映射
  geom_point(size = 3, alpha = 0.85,        # 图层:散点
             color = c_navy) +              #       深蓝圆点
  geom_smooth(method = "lm", se = FALSE,    # 图层:直线拟合,不要置信带
              color = c_orange,             #       橙色
              linetype = "dashed") +        #       虚线
  labs(title = "车重与每加仑行驶里程",        # 标题:主语是"里程"
       x = "车重 wt(千磅)",
       y = "每加仑里程 mpg(英里/加仑)")     # 轴名带单位
图 1

本讲的问题:每加仑能跑多远由什么决定?只看车重够不够?要再加一个,该加谁?

1.5 一元模型 m0:第19讲知识点回顾

▶️ 查看代码
m0 <- lm(mpg ~ wt, data = mtcars)    # 一元:只看车重
summary(m0)                          # 三个数全在这里

Call:
lm(formula = mpg ~ wt, data = mtcars)

Residuals:
   Min     1Q Median     3Q    Max 
-4.543 -2.365 -0.125  1.410  6.873 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   37.285      1.878   19.86  < 2e-16 ***
wt            -5.344      0.559   -9.56  1.3e-10 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 3.05 on 30 degrees of freedom
Multiple R-squared:  0.753, Adjusted R-squared:  0.745 
F-statistic: 91.4 on 1 and 30 DF,  p-value: 1.29e-10
  • 斜率 -5.34:车重每增 1 千磅,每加仑行驶里程平均减少 5.34 英里(更费油)
  • R² = 0.753:车重解释了里程波动的 75.3%
  • F 检验 p < 0.001:这个模型整体显著或有效

重要

R² = 0.753 → 解释了 75.3%,还有 24.7% 没解释(期末要这样写)。这三个数记牢,等会儿和二元模型对账。

1.6 车重解释不掉的那部分,还跟着马力走

残差 = 真实值 − 预测值,是模型没解释掉的部分。如果规律抓干净了,残差应该和谁都不相关。

图 2
▶️ 查看代码
e0 <- resid(m0)                             # m0 的残差
cor(e0, mtcars$hp)                          # 残差与马力的相关系数
[1] -0.412

-0.41(p = 0.019):残差还和马力有关 → 一元模型没把话说完 → 请第二个变量进场。

提示

不用记公式,记住一句:残差里还有信息,就还差一个变量。

二、加一个变量:系数怎么读、方程怎么写

mpg ~ wt + hp:写法只多一个 +,读法多带半句话

2.1 写法只多一个 +

▶️ 查看代码
m1 <- lm(mpg ~ wt + hp, data = mtcars)   # 加一个变量:+ hp
summary(m1)                              # 三个数照样看

Call:
lm(formula = mpg ~ wt + hp, data = mtcars)

Residuals:
   Min     1Q Median     3Q    Max 
-3.941 -1.600 -0.182  1.050  5.854 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 37.22727    1.59879   23.28  < 2e-16 ***
wt          -3.87783    0.63273   -6.13  1.1e-06 ***
hp          -0.03177    0.00903   -3.52   0.0015 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.59 on 29 degrees of freedom
Multiple R-squared:  0.827, Adjusted R-squared:  0.815 
F-statistic: 69.2 on 2 and 29 DF,  p-value: 9.11e-12
  • + 读作"和":把 hp 和 wt 一起放进模型,不是数学加法
  • 输出和第19讲长得一样,只是系数表多了一行 hp
  • 三个数照样看:R²、每行系数的 p 值、最后一行 F 检验

2.2 读懂一份 summary(),只盯三个数

看哪里 本例 回答什么 期末怎么答
倒数第二行 Multiple R-squared = 0.827 y 的变异解释了百分之几 写出"解释了 82.7%,还有 17.3% 没解释"
系数表每行 Pr(>|t|):wt < 0.001、hp = 0.0015 这个变量自己有没有用 p < 0.05 就算有用
最后一行 F-statistic 的 p < 0.001 整组变量一起有没有用 写"模型整体显著"

提示

R² 加任何变量都只涨不跌,所以比模型时顺带看一眼 Adjusted R-squared(它给多用的变量扣分)。除此之外,今天不比别的。

2.3 二元系数怎么解释:每个都要带半句话

系数 估计值 完整读法
wt -3.88 在马力相同的前提下,车重每增 1 千磅,每加仑行驶里程平均减少 3.88 英里(更费油)
hp -0.0318 在车重相同的前提下,马力每增 1,里程平均减少 0.0318 英里;增 100 马力约减少 3.18 英里

答题模板(照着填就行):

在【另一个变量】保持不变时,【x】每增加 1 个【单位】,【y】平均变化【系数】个【单位】。

警告

✗ 错:车重每增 1 千磅,油耗降 3.88。(少了前提,还把 mpg 的方向说反了) ✓ 对:马力不变时,车重每增 1 千磅,每加仑行驶里程平均减少 3.88 英里。

2.4 从回归结果写出回归方程

第一步:抄 Estimate 列的三个数(多显示几位,方便对照)

▶️ 查看代码
round(coef(m1), 4)                         # 截距、wt、hp 三个估计值
(Intercept)          wt          hp 
    37.2273     -3.8778     -0.0318 

第二步:按顺序写成方程 —— 截距 + 两个斜率,负号别丢

\[\widehat{mpg} = 37.23 - 3.88 \times wt - 0.0318 \times hp\]

重要

左边写 \(\widehat{mpg}\)(预测值),不是真实的 mpg;三个数字从 Estimate 那一列原样搬过来。期末"写出回归公式"就是这一步。

2.5 用方程算一次预测

代入一辆车:wt = 3(千磅)、hp = 150(马力)

\[37.23 - 3.88 \times 3 - 0.0318 \times 150 \approx 20.82\]

▶️ 查看代码
predict(m1,                                     # 用 m1 做预测
        newdata = data.frame(wt = 3, hp = 150))  # 两个 x 都要给
   1 
20.8 

重要

按方程手算约 20.82,predict() 给 20.83 英里/加仑——零头是系数只取两位小数造成的,以 R 的完整精度为准。含义:车重 3 千磅、马力 150 的车,每加仑行驶里程预测约 20.83 英里。期末"写出预测值并解释含义"就是这句。

注记

两个 x,newdata 就要给两列,列名必须和 lm() 里完全一致。

2.6 一元 vs 二元:三个数对账

m0:mpg ~ wt m1:mpg ~ wt + hp 变了什么
R² 0.753 0.827 没解释的从 24.7% 降到 17.3%
wt 系数 -5.34 -3.88 缩水 27%
hp 的 p 值 —— 0.0015 新变量自己有用
F 检验 p < 0.001 < 0.001 整体一直有用

提示

一元和二元的差别就在这张表:多一行系数、R² 涨了、老系数被"修正"。老系数为什么缩水?重的车往往马力也大(r = 0.66),hp 分走了一部分原本记在 wt 名下的功劳——系数跟着它所在的模型走,不是算错了。

2.7 【练习】再加一个变量试试:换成 drat

照抄 2.1 的代码(模仿),把 hp 换成 drat(后轴传动比,mtcars 里现成的第三列),跑 summary()(练习):

▶️ 查看代码
lm(mpg ~ wt + drat, data = mtcars) %>%   # 换成 drat 再跑一次
  summary()                              # 只看三个数

只回答两个问题:drat 这一行的 p 值过 0.05 了吗?Adjusted R-squared 比一元的 0.745 高了还是低了?

三、换一个变量:结论会跟着变

把 hp 换成 disp:同样是二元模型,结果不一样

3.1 换个变量,写法不变

▶️ 查看代码
m2 <- lm(mpg ~ wt + disp, data = mtcars)  # 把 hp 换成 disp
summary(m2)                               # 三个数照样看

Call:
lm(formula = mpg ~ wt + disp, data = mtcars)

Residuals:
   Min     1Q Median     3Q    Max 
-3.409 -2.324 -0.768  1.772  6.348 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 34.96055    2.16454   16.15  4.9e-16 ***
wt          -3.35083    1.16413   -2.88   0.0074 ** 
disp        -0.01772    0.00919   -1.93   0.0636 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.92 on 29 degrees of freedom
Multiple R-squared:  0.781, Adjusted R-squared:  0.766 
F-statistic: 51.7 on 2 and 29 DF,  p-value: 2.74e-10
  • 系数表还是三行,只是 hp 换成了 disp
  • disp 的 p = 0.0636,按 0.05 的口径没站住(差一点点过线,别说成"完全没关系")
  • R² = 0.781,比 m1 的 0.827 低

3.2 三个模型摆一起:变量不同,结论就不同

模型 第二个变量 它的 p 值 R² Adjusted R²
m0 —— —— 0.753 0.745
m1 hp 0.0015 0.827 0.815
m2 disp 0.0636 0.781 0.766

重要

别只挑"和 y 相关最强"的那个:disp 与 mpg 的相关是 -0.85,绝对值比 hp 的 -0.78 还大,换进来反而更差。相关强弱只是入场推荐,能不能带来新信息才是关键。

3.3 为什么 disp 不行:它和 wt 太像了

▶️ 查看代码
cor(mtcars$wt, mtcars$disp)                  # 两个自变量的相关
[1] 0.888
▶️ 查看代码
ggplot(mtcars, aes(x = wt, y = disp)) +      # 车重 vs 排量
  geom_point(size = 3, alpha = 0.85,        # 图层:散点
             color = c_navy) +
  geom_smooth(method = "lm", se = FALSE,    # 图层:直线
              color = c_orange,
              linetype = "dashed") +
  labs(title = "两个自变量在说同一件事",
       x = "车重 wt(千磅)", y = "排量 disp(立方英寸)")
图 3

r = 0.888 —— 两个自变量几乎在说同一件事,谁也分不清功劳该记给谁,于是 disp 自己就不显著了。

提示

一句话记住:换变量要看它能不能带来车重给不了的新信息,不是看它跟 y 相关多高。更细的判断留到后面的课程。

3.4 【练习】自选一个变量,比出三个数

从 mtcars 里自己挑一个还没用过的变量(qsec 1/4 英里加速时间,秒;cyl 气缸数;am 自动挡;gear 挡位数;vs 发动机形状;carb 化油器数),照 3.1 的写法跑一遍(实战):

▶️ 查看代码
lm(mpg ~ wt + qsec, data = mtcars) %>%   # 把 qsec 换成你选的变量
  summary()

在纸上填三格,然后和邻座对一下选的变量是否相同:我选的变量/它的 p 值/调整 R² 比一元的 0.745 高还是低。最后每人说一句"这个变量加得好不好"。

3.5 最后看一眼:模型剩下的东西

▶️ 查看代码
plot(m1, which = 1, id.n = 0)               # 拟合值 vs 残差图

残差 = 真实值 − 预测值。健康的样子:点随机撒在 0 线上下,红线大致是平的。

m1 的红线有点 U 形:说明直线的"形状"还没抓到位。换变量治不了它,下一讲用对数变换处理。

注记

今天的诊断就这一张图 + 前面那三个数,够了。

四、综合实战:自己挑第二个变量,比出更好的模型

四步走一遍,正好是期末案例题的四个采分点

4.1 动手实战(约 8 分钟)

用你在 3.4 挑的那个变量,把四步做完(实战,不是看老师做):

  1. 写方程 —— round(coef(模型), 4),抄三个数,负号别丢
  2. 读系数 —— 两个斜率各念一遍,都带上"在另一个变量不变时"
  3. 比三个数 —— 与 m1 比 R²、调整 R²、新变量的 p 值,说一句谁的模型更好
  4. 算预测 —— 代一辆你编的车,newdata 两列列名和公式里逐字一致

4.2 参考做法:wt + qsec 全程走一遍

4.3 课堂展示

抽 2 位同学上台,各 2 分钟,只讲自己模型的第 1 步和第 3 步:方程 + 三个数。

台下同学按 4.1 的验收标准点评两件事:那半句话带了吗?单位说的是里程还是"油耗"?

提示

被挑到"白加"变量的同学,请这位补一句:调整 R² 掉到哪里去了,为什么这算模型变差。

五、课堂总结、学习成果确认与 Exit Ticket

三个数、一句话模板、一套四步

5.1 本讲小结

  1. 一元 → 二元:多一个 +,多一行系数;R² 从 0.753 涨到 0.827、老系数被修正
  2. 系数解释:每个都要带"在另一个变量不变时",mpg 读作每加仑行驶里程减少,照模板答
  3. 写方程:抄 Estimate 三个数 → \(\widehat{y} = b_0 + b_1 x_1 + b_2 x_2\) → 代入算预测(20.83 英里/加仑)
  4. 比模型只看三个数:R²、系数的 p 值、F 检验的 p 值;换变量要看有没有带来新信息

5.2 学习成果自查

对照一下,今天这几件事你都做到了吗?

  • ✓ 能独立把 lm(y ~ x1) 改成 lm(y ~ x1 + x2) 并跑通 summary()
  • ✓ 能在输出里一次指出三个数:R²、每行系数的 p 值、最后一行 F 检验
  • ✓ 能用模板解释二元系数,不漏"在另一个变量不变时",并把 mpg 说成里程而不是"油耗"
  • ✓ 能由 Estimate 写出回归方程,负号不丢,左边带"帽子"
  • ✓ 能给 newdata 补齐两列、列名逐字一致,算出预测值并解释含义
  • ✓ 能从 mtcars 自选变量,用调整 R² 判断"加得值不值"

5.3 Exit Ticket —— 写给自己的三个问题

请花 1 分钟,在纸条或在线问卷上简要回答:

  1. 用一句话解释 m1 里 wt 的系数(-3.88),不许丢那半句话,也不许说"油耗下降"。
  2. 读一份回归输出,三个数分别在哪三处?
  3. 换一个自变量时,你要问自己的那个问题是什么?

下讲预告

项目五:虚拟变量、对数变换与随机抽样

  • 文字类别(如 A/B/C 评级、自动挡/手动挡)怎么进回归方程
  • 对数变换:把今天这张 U 形残差图拉直
  • 随机抽样与训练/测试集:模型评估如何"防作弊"

提示

课前准备:把你今天的模型代码留在 .qmd 里,下节课接着改。今天这三个数——R²、系数的 p 值、F 检验——下节课照样用。

谢谢!

第20讲:从一元到多元线性回归 —— 项目五

会读系数,会写方程,会拿三个数比模型。

朱 奇 | 锦城大学 · 财会学院