数据挖掘与R语言

第10讲:简单线性回归

2026年04月29日

上讲回顾

  • 描述统计:均值受极端值影响,中位数更稳健;标准差衡量离散程度;回归本质是解释方差\(\text{SS}_\text{Total} = \text{SS}_\text{Reg} + \text{SS}_\text{Res}\)
  • 正态分布:由 \(\mu\)\(\sigma\) 完全决定;68-95-99.7 法则;残差正态假设是 OLS 最优性的基础
  • 相关性:Pearson 衡量线性关系,\(r \in [-1, 1]\)cor.test() 检验相关系数是否显著
  • 统计推断\(t\) 检验看单个系数;\(F\) 检验看模型整体;置信区间比点估计更诚实
  • wtmpg 的相关系数 \(r = -0.87\)这就是今天回归分析的起点

本讲内容

  • Part 1:"回归"这个词从哪里来? ——高尔顿与历史故事
  • Part 2:回归方程 ——从散点图到直线
  • Part 3:最小二乘法(OLS) ——直观理解
  • Part 4:读懂 summary(lm()) ——R 语言输出逐行解析
  • Part 5:财务案例实战 ——广告费预测销量
  • Part 6:预测与区间 ——predict() 函数的使用
  • Part 7:你必须掌握什么? ——学习路线图

为什么学回归?

从已知到未知

初中就学过的简单方程

\[ y = a - bx\] 在中学时,\(a\)\(b\) 是已知数,我们的任务是:任意给定一个\(x\),求出\(y\)的值。

但现在,我们的已知条件和未知条件变了,相应的,任务也变了!

注记

  • 当我们知道一个规律的时候,可以根据这个规律来预测未知的数据点
  • 但是,这个规律是如何获得的呢?

Part 1:"回归"这个词从哪里来?

一个维多利亚时代的发现

弗朗西斯·高尔顿(Francis Galton)

Francis Galton(1822—1911)

  • 英国统计学家、博学家,达尔文的表弟
  • 对人类遗传学痴迷,尤其着迷于"高个子的父母亲,子女会有多高?"
  • 收集了205个家庭中928名成年子女 的父母子女身高数据

他的发现让他惊讶:

父母亲极高 → 子女通常会比父母亲矮一些
父母亲极矮 → 子女通常会比父母亲高一些

子女的身高总是倾向于向平均值靠拢。

注记

高尔顿的原文(1886):

"Regression towards Mediocrity in Hereditary Stature"

《遗传身高向均值的回归》

发表于 Journal of the Anthropological Institute

这是"回归"(Regression)这个词的第一次出现。

高尔顿的数据:父子身高

"回归均值"的直觉

高尔顿把这个现象叫做:

"Regression to the Mean"
向均值回归

为什么会这样?

极端结果 = 真实遗传因素 + 运气(随机误差)

下一代再抽一次,运气不再那么极端,结果就"回归"到了均值附近。

提示

生活中的"回归均值":

  • 考试考了满分的学生,下次往往考得差一点(不一定变笨了)
  • 赛季表现最差的运动员,明年通常会好转
  • 极端天气之后往往回归正常

这是统计规律,不是命运。

注记

后来,"回归"这个词被数学家卡尔·皮尔逊(Karl Pearson)推广,用来指代所有"用一个变量预测另一个变量"的统计方法。今天我们说的"回归分析",用法早已超越了高尔顿的原意——但名字保留下来了。

Part 2:回归方程

从散点图到一条直线

核心思想:用直线描述关系

看到散点图,我们想画一条直线来概括趋势

这条直线的方程就是简单线性回归方程

\[\hat{y} = \hat{\beta}_0 + \hat{\beta}_1 x\]

回归方程的每个符号

\[y = \underbrace{\beta_0}_{\text{截距}} + \underbrace{\beta_1}_{\text{斜率}} x + \underbrace{\varepsilon}_{\text{误差项}}\]

符号 名称 含义 财务案例
\(y\) 因变量 我们想预测的量 销量
\(x\) 自变量 我们用来预测的量 广告费
\(\beta_0\) 截距 \(x=0\) 时,\(y\) 的理论值 不投广告时的基础销量
\(\beta_1\) 斜率 \(x\) 每增加 1 个单位,\(y\) 增加多少 每多投 1 万广告,销量增加多少
\(\varepsilon\) 误差项 模型无法解释的随机波动 季节、促销、偶然因素……

注记

\(\beta_0\)\(\beta_1\) 是未知的总体真实值,我们用数据估计它们,估计值写作 \(\hat{\beta}_0\)\(\hat{\beta}_1\)(读作"β hat")。

斜率的直觉

\(\hat{\beta}_1 > 0\)(正斜率)

广告费多 → 销量多

\(\hat{\beta}_1 < 0\)(负斜率)

车越重 → 油耗越高(每加仑的行驶里程越短)

Part 3:最小二乘法(OLS)

怎么找到"最好"的那条直线?

问题:哪条线最好?

答案:让所有点到直线的距离之和最小的那条线!

最小二乘法:核心思想

残差(Residual):实际值与预测值的差

\[e_i = y_i - \hat{y}_i = y_i - (\hat{\beta}_0 + \hat{\beta}_1 x_i)\]

目标: 找到 \(\hat{\beta}_0\)\(\hat{\beta}_1\),使残差平方和(RSS)最小:

\[\text{minimize} \quad \text{RSS} = \sum_{i=1}^{n} e_i^2 = \sum_{i=1}^{n}(y_i - \hat{\beta}_0 - \hat{\beta}_1 x_i)^2\]

提示

为什么要"平方"?

  • 正残差(点在线上方)和负残差(点在线下方)会相互抵消
  • 平方消除了符号,同时让大误差受到更重的"惩罚"
  • 平方后数学上容易求最优解(求导令导数为零)

注记

OLS 不需要手算。 你只需要理解它的目标:让误差最小。R 语言一行代码 lm() 就能完成所有计算。

OLS 的解(了解即可)

通过微积分(对 RSS 求偏导,令导数为零),可以解出:

\[\hat{\beta}_1 = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sum_{i=1}^{n}(x_i - \bar{x})^2} = r_{xy} \cdot \frac{s_y}{s_x}\]

\[\hat{\beta}_0 = \bar{y} - \hat{\beta}_1 \bar{x}\]

从公式看出几件事:

  • 回归线一定经过点 \((\bar{x},\, \bar{y})\)(均值点)
  • 斜率 \(\hat{\beta}_1\) 与相关系数 \(r\) 成正比
  • \(r = 0\) 时,\(\hat{\beta}_1 = 0\)(斜率为零,无法预测)

重要

考试不要求手推公式。
但要知道:

① OLS 是"让误差平方和最小"
② R 语言用 lm() 自动完成计算

Part 4:读懂 summary(lm())

R 输出的每一行都有含义

建立第一个回归模型

用上讲已经探索过的 mtcars 数据:

▶️ 查看代码
# 建立简单线性回归:用车重(wt)预测油耗(mpg)
model <- lm(mpg ~ wt, data = mtcars)

# 查看完整输出
summary(model)

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

逐行解读:Coefficients 表格

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.29e-10 ***
列名 含义 本例解读
Estimate 系数估计值 \(\hat{\beta}\) 截距=37.3,斜率=-5.34
Std. Error 估计的不确定性(标准误) 斜率的标准误=0.56
t value \(t\) 统计量 = Estimate ÷ Std.Error \(-5.344/0.559 = -9.56\)
Pr(>|t|) 双尾 \(p\) \(p < 0.001\),极其显著
*** 显著性星号 *** = \(p < 0.01\)

提示

业务语言解读斜率:
wt 的 Estimate = −5.344,意思是:车重每增加 1000 磅,每加仑油预期行驶里程下降 5.344 英里

p-value = 1.29e-10,意思是:如果车重和油耗真的无关,观察到这么强的负相关的概率不到十亿分之一。

逐行解读:显著性星号

\(p\) 值范围 标记 含义 记忆方法
\(p < 0.01\) *** 极其显著 三颗星,最强
\(0.01 \leq p < 0.05\) ** 非常显著 两颗星
\(0.05 \leq p < 0.10\) . 边缘显著 注意,不算显著!
\(p \geq 0.10\) (空白) 不显著 无法拒绝原假设

重要

统计显著 ≠ 实际重要

\(p\) 值只告诉你"这个系数是否可靠或可信",不告诉你系数有多大、在业务上是否重要。

样本量极大时,即使非常小的效应也会显著(\(p < 0.05\))。

逐行解读:R² 和 F 检验

Multiple R-squared:  0.7528
Adjusted R-squared:  0.7446
F-statistic: 91.38 on 1 and 30 DF,  p-value: 1.294e-10

\(R^2\)(决定系数)= 0.753

车重(wt)解释了油耗(mpg75.3% 的变异。
剩余 24.7% 由其他因素(发动机、气动……)决定。

\[R^2 = 1 - \frac{\text{SS}_\text{Residual}}{\text{SS}_\text{Total}} \in [0, 1]\]

\(F\) 检验:p = 1.29e-10

整个模型(不只是某个系数)是否有预测价值?
\(p < 0.05\) → 模型整体显著,回归有意义。

注记

简单回归中: \(F\) 检验的 \(p\) 值 = 斜率 \(t\) 检验的 \(p\) 值(因为只有一个自变量)。
多元回归中: \(F\) 检验和各系数 \(t\) 检验的 \(p\) 值可以不同。

用一张图记住所有输出

Part 5:财务案例实战

广告费能预测销量吗?

数据:12 个月的广告投入与销量

▶️ 查看代码
# 创建数据:某公司12个月的广告费(万元)与产品销量(万件)
ad_data <- data.frame(
  月份  = 1:12,
  广告费 = c(12, 15, 18, 20, 22, 25, 28, 30, 32, 35, 38, 40),
  销量   = c(25, 28, 32, 35, 38, 42, 46, 50, 53, 57, 61, 65)
)

ad_data
   月份 广告费 销量
1     1     12   25
2     2     15   28
3     3     18   32
4     4     20   35
5     5     22   38
6     6     25   42
7     7     28   46
8     8     30   50
9     9     32   53
10   10     35   57
11   11     38   61
12   12     40   65

第一步:先画图,再建模

▶️ 查看代码
ggplot(ad_data, aes(x = 广告费, y = 销量)) +
  geom_point(size = 4, color = "#1a3a5c") +
  geom_smooth(method = "lm", se = TRUE,
              color = "#e05c2a", fill = "#e05c2a", alpha = 0.15,
              linewidth = 1.3) +
  labs(
    title    = "广告费与销量的关系",
    subtitle = "目测:线性趋势非常明显",
    x = "广告费(万元)", y = "销量(万件)"
  )

提示

原则:永远先画散点图,再建模型。 如果散点图呈现非线性(如 U 形、指数型),直接套线性回归就会出错。

第二步:建立回归模型

▶️ 查看代码
# 建立回归:用广告费预测销量
ad_model <- lm(销量 ~ 广告费, data = ad_data)
summary(ad_model)

Call:
lm(formula = 销量 ~ 广告费, data = ad_data)

Residuals:
   Min     1Q Median     3Q    Max 
-0.860 -0.339 -0.146  0.281  1.237 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   6.4399     0.5673    11.3  4.9e-07 ***
广告费        1.4436     0.0205    70.4  8.2e-15 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.619 on 10 degrees of freedom
Multiple R-squared:  0.998, Adjusted R-squared:  0.998 
F-statistic: 4.95e+03 on 1 and 10 DF,  p-value: 8.18e-15

第三步:解读结果

回归方程:

\[\widehat{\text{销量}} = 6.44 + 1.44 \times \text{广告费}\]

截距 \(\hat{\beta}_0 = 6.44\)

广告费为 0 时,预期销量约 6.44 万件。

→ 这是品牌自然流量、回头客带来的基础销量。

斜率 \(\hat{\beta}_1 = 1.44\)

广告费每增加 1 万元,销量预期增加 1.44 万件

→ 广告投入的边际效益是 1.44。

\(p < 0.001\)***

→ 广告费对销量的影响极其显著。

\(R^2 = 0.998\)

→ 广告费解释了销量 99.8% 的变异。

→ 模型拟合非常好(但要注意:数据只有 12 个月,样本量小)。

注记

\(R^2\) 极高有时要警惕:样本量太小或变量之间有内在依赖(如时间序列)都会人为抬高 \(R^2\)

用系数回答业务问题

重要

财务决策者真正关心的问题:

"我多花 10 万元广告费,值吗?"

用回归方程回答:

\[\Delta\widehat{\text{销量}} = 1.44 \times \Delta\text{广告费} = 1.44 \times 10 = 14.4 \text{ 万件}\]

进一步:如果每件商品利润 = 2 元,则

\[\text{增量利润} = 14.4 \times 2 = 28.8 \text{ 万元}\]

\[\text{广告 ROI} = \frac{28.8}{10} = 2.88\]

每投入 1 万元广告,带来 2.88 万元利润回报——这就是回归分析的业务价值。

Part 6:预测与区间

用模型预测新数据

predict() 函数的基本用法

▶️ 查看代码
# 预测:广告费 = 50 万元时的销量
new_data <- tibble(广告费 = 50)

# 点预测(单一数值)
predict(ad_model, newdata = new_data)
   1 
78.6 

也可以手动计算验证:

▶️ 查看代码
# 手动计算
6.44 + 1.44 * 50
[1] 78.4

注记

点预测给出一个数值,但这个数值一定有不确定性。更诚实的做法是给出区间估计

两种预测区间

▶️ 查看代码
# 置信区间:预测"平均销量"的范围(模型均值的不确定性)
predict(ad_model, newdata = new_data,
        interval = "confidence", level = 0.95)
   fit  lwr  upr
1 78.6 77.5 79.8
▶️ 查看代码
# 预测区间:预测"单次实际销量"的范围(包含个体随机误差)
predict(ad_model, newdata = new_data,
        interval = "prediction", level = 0.95)
   fit  lwr  upr
1 78.6 76.8 80.4
置信区间 预测区间
回答的问题 均值销量的范围? 某月实际销量的范围?
宽度 较窄 较宽(包含 \(\varepsilon\)
用于 评估模型精度 实际业务预测

可视化两种区间

▶️ 查看代码
# 生成预测数据
pred_range <- data.frame(广告费 = seq(5, 55, length.out = 100))
conf_int   <- predict(ad_model, newdata = pred_range, interval = "confidence")
pred_int   <- predict(ad_model, newdata = pred_range, interval = "prediction")

plot_df <- bind_cols(pred_range,
                     as.data.frame(conf_int) |> rename(fit=fit, conf_lwr=lwr, conf_upr=upr),
                     as.data.frame(pred_int)  |> select(pred_lwr=lwr, pred_upr=upr))

ggplot(plot_df, aes(x = 广告费)) +
  geom_ribbon(aes(ymin = pred_lwr, ymax = pred_upr),
              fill = "#4472C4", alpha = 0.15) +
  geom_ribbon(aes(ymin = conf_lwr, ymax = conf_upr),
              fill = "#e05c2a", alpha = 0.3) +
  geom_line(aes(y = fit), color = "#e05c2a", linewidth = 1.3) +
  geom_point(data = ad_data, aes(x = 广告费, y = 销量),
             size = 3, color = "#1a3a5c") +
  annotate("text", x = 8, y = 90,
           label = "蓝色宽带:预测区间(单次实际值)", color = "#4472C4",
           hjust = 0, size = 3.5) +
  annotate("text", x = 8, y = 85,
           label = "橙色窄带:置信区间(均值范围)", color = "#e05c2a",
           hjust = 0, size = 3.5) +
  labs(
    title    = "回归预测的两种区间",
    subtitle = "预测区间 ⊃ 置信区间:前者更宽,因为包含了个体随机误差",
    x = "广告费(万元)", y = "销量(万件)"
  )

外推预测的风险

重要

不要在数据范围之外随意外推!

我们的数据只覆盖广告费 12—40 万元的范围。预测广告费 = 200 万元时的销量,完全是在猜测——市场可能早就饱和了。

Part 7:你必须掌握什么?

学习路线图

必须掌握(核心概念)

重要

以下内容是本课程的基础,期末考试必考,实际工作必用:

  1. 回归方程的含义\(\hat{y} = \hat{\beta}_0 + \hat{\beta}_1 x\),能用中文解释截距和斜率的业务含义

  2. OLS 的目标:知道"最小化残差平方和"是什么意思(不需要会手推公式)

  3. 读懂 summary(lm()) 的输出

    • Estimate:系数是多少?方向(正/负)对不对?
    • Pr(>|t|)\(p\) 值是多少?星号代表什么?
    • Multiple R-squared:模型解释了多少变异?
  4. R 语言操作lm(y ~ x, data = )summary()predict()

  5. 散点图先行原则:建模前必须先画图,判断线性关系是否成立

理解即可

注记

以下内容理解含义即可,不需要记公式、不需要手算:

  • OLS 的数学推导:斜率和截距的求解公式(\(\hat{\beta}_1 = r_{xy} \cdot {s_y\over s_x}\))——知道 R 在帮你算就好

  • \(t\) 统计量的计算:知道 \(t = {\hat{\beta}_1 \over \text{SE}(\hat{\beta}_1)}\),知道它用来检验"系数是否为零"

  • \(F\) 统计量:知道它检验"整体模型是否有价值",会看 \(p\) 值就够

  • 置信区间的数学公式\(\hat{\beta}_j \pm t_{0.025} \times \text{SE}(\hat{\beta}_j)\)——R 的 confint() 直接给你

常见错误清单

警告

以下是初学者最容易犯的错误,请对照检查:

错误 正确理解
"\(p\) 值越小,说明系数越大" \(p\) 值只说明显著性,系数大小看 Estimate
"\(R^2 = 0.99\) 说明模型完美" \(R^2\) 高可能是过拟合,要结合样本量和业务判断
"相关就是因果" 回归不能证明因果,只能量化关联
"模型显著,可以随意外推" 数据范围之外的预测不可靠,需要领域知识支撑
"截距没有意义,忽略它" 截距是回归方程的一部分,忽略会导致预测错误

知识结构回顾

本讲小结

  • 回归的历史:高尔顿 1886 年发现"向均值回归","regression"由此得名;今天的回归分析用途已大大扩展

  • 回归方程\(\hat{y} = \hat{\beta}_0 + \hat{\beta}_1 x\);截距是 \(x=0\)\(y\) 的基准值;斜率是 \(x\) 每变化一个单位,\(y\) 预期变化多少

  • OLS:通过最小化残差平方和找到最优直线;不用手算,lm() 自动完成

  • 读懂输出Estimate(系数大小)→ Pr(>|t|)(显著性)→ R-squared(解释力)→ F-statistic(整体有效性)

  • 预测predict() 做点预测;置信区间估计均值,预测区间估计单次实际值;不要在数据范围外随意外推

课后练习

基础练习(必做)

  1. 使用 mtcars 数据集,建立用马力(hp)预测油耗(mpg的回归模型。写出回归方程,解释斜率的实际含义,判断 \(p\) 值和 \(R^2\)

  2. 对上述模型,用 predict() 预测当 hp = 150 时的 mpg,并给出 95% 预测区间

  3. 在第 1 题的散点图中,用 geom_smooth(method = "lm") 画出回归线,叠加 95% 置信区间阴影.

进阶挑战(选做)

  1. 使用 diamonds 数据集,建立用克拉数(carat)预测价格(price的回归模型。注意:先画散点图——关系是线性的吗?如果不是,尝试对 price 取对数后再建模,比较两个模型的 \(R^2\)

  2. 思考题:高尔顿的"向均值回归"是一种统计规律,不是命运。你能想到生活或工作中被误解为因果的"回归均值"案例吗?(提示:体育运动员的"二年级诅咒")

下讲预告

第11讲:多元线性回归

  • 为什么需要多元回归? 一个 \(x\) 往往不够,引入多个自变量控制混淆因素
  • 模型方程\(y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \cdots + \beta_k x_k + \varepsilon\)
  • 偏回归系数:控制其他变量后,某个 \(x\)\(y\) 的"净效应"
  • 多重共线性:自变量之间高度相关时会发生什么?VIF 检验
  • 模型选择:Adjusted \(R^2\)、AIC——怎么知道加哪个变量?
  • R 实战lm(y ~ x1 + x2 + x3) 语法,vif() 函数,逐步回归

提示

今天的简单回归是基础。多元回归只是在右边多加几个 \(x\),核心逻辑完全一致。把今天的内容搞透,下讲就会非常轻松。

谢谢!

第10讲:简单线性回归


「回归分析让我们能够用数据说话,而不是靠感觉拍脑袋。」

—— 弗朗西斯·高尔顿(Francis Galton),1886