第12讲:对数回归与分类自变量
2026年05月08日
lm(y ~ x1 + x2)、vif()、AIC()
当散点图不是一条直线
复习:线性回归的前提是 \(y\) 和 \(x\) 之间存在线性关系。
注记
散点图是诊断工具。 如果散点图呈现弯曲趋势,不要强行套线性回归——考虑对数变换。
适合取对数的变量(正数且跨越多个数量级):
提示
快速判断三步法:
满足以上任意一点,就可以考虑取对数。
| 模型 | 方程 | 系数解读 | 典型场景 |
|---|---|---|---|
| level-log | \(y = \beta_0 + \beta_1 \ln(x) + \varepsilon\) | \(x\) 增加 1%,\(y\) 变化 \(\beta_1 / 100\) 个单位 | 广告费→销量 |
| log-level | \(\ln(y) = \beta_0 + \beta_1 x + \varepsilon\) | \(x\) 增加 1,\(y\) 变化约 \(\beta_1 \times 100\%\) | 经验→工资 |
| log-log | \(\ln(y) = \beta_0 + \beta_1 \ln(x) + \varepsilon\) | \(x\) 增加 1%,\(y\) 变化 \(\beta_1\%\)(弹性) | 价格→需求量 |
\(x\) 每增加1%,\(y\) 变化多少?
现实规律: 广告的边际效益是递减的——第一个 100 万效果显著,第二个 100 万效果没那么好。这是对数增长,不是线性增长。
Call:
lm(formula = 销量 ~ log(广告费), data = ad_log)
Residuals:
Min 1Q Median 3Q Max
-15.517 -4.578 0.646 4.533 18.558
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 8.09 4.59 1.76 0.082 .
log(广告费) 25.61 1.02 25.10 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 7.13 on 78 degrees of freedom
Multiple R-squared: 0.89, Adjusted R-squared: 0.888
F-statistic: 630 on 1 and 78 DF, p-value: <2e-16
根据输出,回归方程为:
\[\widehat{\text{销量}} = \hat{\beta}_0 + 24.8 \times \ln(\text{广告费})\]
当 \(x\) 增加 1%(即 \(\ln(x)\) 增加约 \(0.01\))时:
如何解读斜率 \(\hat{\beta}_1 = 24.8\)?
当 \(x\) 增加 1%(即 \(\ln(x)\) 增加约 \(0.01\))时:
\[\Delta\hat{y} \approx \hat{\beta}_1 \times 0.01 = 24.8 \times 0.01 = 0.248 \text{ 万件}\]
提示
level-log 系数的解读口诀:
\(x\) 每增加 1%,\(y\) 增加约 \(\hat{\beta}_1 \div 100\) 个单位
具体说: 广告费每增加 1%,销量预期增加约 0.248 万件。
等价地:广告费每翻一番(+100%),销量增加约 \(24.8 \times \ln(2) \approx 17.2\) 万件。
| (1) | (2) | |
|---|---|---|
| + p < 0.1, * p < 0.05, ** p < 0.01, *** p < 0.001 | ||
| (Intercept) | 87.136*** | 8.087+ |
| (2.558) | (4.585) | |
| 广告费 | 0.329*** | |
| (0.022) | ||
| log(广告费) | 25.605*** | |
| (1.020) | ||
| Num.Obs. | 80 | 80 |
| R2 | 0.748 | 0.890 |
| R2 Adj. | 0.744 | 0.888 |
| AIC | 611.5 | 545.2 |
| BIC | 618.7 | 552.4 |
| Log.Lik. | -302.774 | -269.607 |
| F | 230.947 | 629.924 |
| RMSE | 10.65 | 7.04 |
\(x\) 增加 1,\(y\) 变化百分之几?
现实规律: 工资随经验的增长往往是指数型的——从 0 到 5 年涨幅小,从 20 到 25 年涨幅相对大。对 \(y\) 取对数后,关系趋于线性。
Call:
lm(formula = log(工资) ~ 经验年数, data = exp_data)
Residuals:
Min 1Q Median 3Q Max
-0.7216 -0.1556 0.0086 0.1906 0.5006
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 7.47821 0.05190 144.1 <2e-16 ***
经验年数 0.06038 0.00273 22.1 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.246 on 98 degrees of freedom
Multiple R-squared: 0.833, Adjusted R-squared: 0.832
F-statistic: 490 on 1 and 98 DF, p-value: <2e-16
回归方程为:
\[\ln(\widehat{\text{工资}}) = \hat{\beta}_0 + 0.060 \times \text{经验年数}\]
如何解读斜率 \(\hat{\beta}_1 = 0.060\)?
当 \(x\) 增加 1 时,\(\ln(y)\) 增加 \(0.060\),因此 \(y\) 的百分比变化为:
\[\% \Delta y \approx \hat{\beta}_1 \times 100\% = 6.0\%\]
提示
log-level 系数的解读口诀:
\(x\) 每增加 1 个单位,\(y\) 增加约 \(\hat{\beta}_1 \times 100\%\)
具体说: 工作经验每增加 1 年,工资预期增加约 6.0%。
这正是经济学中「Mincer 工资方程」的标准形式。
注记
大系数时用精确公式: \((e^{\hat{\beta}_1} - 1) \times 100\%\)。
本例:\((e^{0.06}-1) \times 100\% = 6.18\%\),与近似值 6.0% 差别不大。 系数较大(如 \(\hat{\beta}_1 > 0.2\))时,精确公式更准确。
重要
注意: log-level 模型预测的是 \(\ln(y)\),不是 \(y\) 本身。需要做反变换才能得到原始尺度的预测值。
ln(工资) 的预测值: 8.08
工资的预测值(元/月): 3236
弹性系数:\(x\) 变化 1%,\(y\) 变化几个百分点?
经济学核心概念: 价格弹性——价格上涨 1%,需求量下降几个百分点?log-log 模型的斜率直接就是弹性系数。
Call:
lm(formula = log(需求量) ~ log(价格), data = price_data)
Residuals:
Min 1Q Median 3Q Max
-0.564 -0.121 0.012 0.114 0.438
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 7.9100 0.1114 71.0 <2e-16 ***
log(价格) -1.2857 0.0289 -44.5 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.188 on 78 degrees of freedom
Multiple R-squared: 0.962, Adjusted R-squared: 0.962
F-statistic: 1.98e+03 on 1 and 78 DF, p-value: <2e-16
回归方程为:
\[\ln(\widehat{\text{需求量}}) = \hat{\beta}_0 - 1.30 \times \ln(\text{价格})\]
如何解读斜率 \(\hat{\beta}_1 = -1.30\)?
\[\hat{\beta}_1 = \frac{\Delta\ln y}{\Delta\ln x} \approx \frac{\% \Delta y}{\% \Delta x} = \text{弹性系数}\]
提示
log-log 系数的解读口诀(最简洁):
\(x\) 每增加 1%,\(y\) 变化 \(\hat{\beta}_1\%\)
具体说: 价格每上涨 1%,需求量预期下降 1.30%。
\(|\hat{\beta}_1| > 1\) → 富有弹性(需求对价格敏感);\(|\hat{\beta}_1| < 1\) → 缺乏弹性。
用 0/1 虚拟变量表示类别
线性回归要求自变量是数值型。 但很多重要变量是类别型的:
解决方案:虚拟变量(Dummy Variable)
对于有 2 个类别 的变量,创建 1 个虚拟变量:
\[D = \begin{cases} 1 & \text{类别 A(处理组)} \\ 0 & \text{类别 B(参照组,reference group)} \end{cases}\]
重要
参照组(Reference Group): 虚拟变量系数衡量「与参照组相比的差异」。选哪个类别作参照组不影响预测值和 \(R^2\),但影响系数的数值和解读方向。通常选「基准」或「对照」类别。
set.seed(5)
n <- 100
promo_data <- data.frame(
广告费 = runif(n, 10, 80),
促销 = sample(c("无促销", "有促销"), n, replace = TRUE)
) |>
mutate(
促销虚拟 = if_else(促销 == "有促销", 1, 0),
销量 = 5 + 1.2 * 广告费 + 15 * 促销虚拟 + rnorm(n, sd = 6)
)
# 直接传入字符型变量,R 会自动创建虚拟变量
# "无促销" 按字母顺序排在"有促销"之前,自动成为参照组
model_promo <- lm(销量 ~ 广告费 + 促销, data = promo_data)
summary(model_promo)
Call:
lm(formula = 销量 ~ 广告费 + 促销, data = promo_data)
Residuals:
Min 1Q Median 3Q Max
-15.183 -3.859 0.073 4.707 14.968
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.7422 1.6166 3.55 0.00059 ***
广告费 1.1966 0.0299 39.96 < 2e-16 ***
促销有促销 13.8947 1.2726 10.92 < 2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 6.32 on 97 degrees of freedom
Multiple R-squared: 0.947, Adjusted R-squared: 0.946
F-statistic: 864 on 2 and 97 DF, p-value: <2e-16
根据输出,回归方程为:
\[\widehat{\text{销量}} = \hat{\beta}_0 + 1.21 \times \text{广告费} + 14.9 \times D_{\text{有促销}}\]
注记
两条平行线的直觉: 虚拟变量模型假设两组斜率相同,只有截距不同。橙色线(有促销)整体比蓝色线(无促销)高约 15 个单位——这就是虚拟变量系数的几何意义。
(Intercept) 促销有促销
1 1 1
2 1 1
3 1 1
4 1 0
5 1 1
6 1 0
提示
实用建议: 养成显式用 factor(levels = ...) 指定顺序的习惯,尤其是类别名称不按预期顺序排列时(如「高/中/低」会被自动排成「低/高/中」)。
参照组与多个虚拟变量
重要
为什么是 \(k-1\) 个,而不是 \(k\) 个?
若创建 \(k\) 个虚拟变量,它们之和恒等于 1,与截距项完全共线(完全多重共线性),OLS 无解。必须去掉一个类别作参照组,被「藏进截距」。
例子:营销渠道(3 个类别)
| 渠道 | \(D_{\text{社交媒体}}\) | \(D_{\text{搜索引擎}}\) | 预测值 |
|---|---|---|---|
| 线下门店(参照组) | 0 | 0 | \(\hat{\beta}_0\) |
| 社交媒体 | 1 | 0 | \(\hat{\beta}_0 + \hat{\beta}_1\) |
| 搜索引擎 | 0 | 1 | \(\hat{\beta}_0 + \hat{\beta}_2\) |
mtcars 数据: 气缸数(cyl)有 4 缸、6 缸、8 缸三种。气缸数对油耗的净影响有多大?
Call:
lm(formula = mpg ~ cyl_f, data = mtcars_cyl)
Residuals:
Min 1Q Median 3Q Max
-5.264 -1.836 0.029 1.389 7.236
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 26.664 0.972 27.44 < 2e-16 ***
cyl_f6缸 -6.921 1.558 -4.44 0.00012 ***
cyl_f8缸 -11.564 1.299 -8.90 8.6e-10 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 3.22 on 29 degrees of freedom
Multiple R-squared: 0.732, Adjusted R-squared: 0.714
F-statistic: 39.7 on 2 and 29 DF, p-value: 4.98e-09
根据输出:
\[\widehat{\text{mpg}} = 26.66 - 6.92 \times D_{\text{6缸}} - 11.56 \times D_{\text{8缸}}\]
| 系数 | 数值 | 含义 |
|---|---|---|
| 截距 \(= 26.66\) | — | 4 缸车的平均油耗(英里/加仑) |
| \(\hat{\beta}_{\text{6缸}} = -6.92\) | \(p < 0.001\) | 6 缸车比 4 缸平均低 6.92 英里/加仑 |
| \(\hat{\beta}_{\text{8缸}} = -11.56\) | \(p < 0.001\) | 8 缸车比 4 缸平均低 11.56 英里/加仑 |
更完整的分析: 控制车重后,气缸数的净效应有多大?
Call:
lm(formula = mpg ~ cyl_f + wt, data = mtcars_cyl)
Residuals:
Min 1Q Median 3Q Max
-4.589 -1.236 -0.516 1.384 5.792
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 33.991 1.888 18.01 < 2e-16 ***
cyl_f6缸 -4.256 1.386 -3.07 0.00472 **
cyl_f8缸 -6.071 1.652 -3.67 0.00100 ***
wt -3.206 0.754 -4.25 0.00021 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 2.56 on 28 degrees of freedom
Multiple R-squared: 0.837, Adjusted R-squared: 0.82
F-statistic: 48.1 on 3 and 28 DF, p-value: 3.59e-11
提示
对比两个模型:
model_cyl:气缸数对油耗的「总效应」(未控制车重)model_cyl_wt:控制车重后,气缸数对油耗的「净效应」观察气缸数系数的变化幅度,可判断车重是否是气缸数与油耗关系中的混淆变量——这正是第 11 讲学到的偏回归系数逻辑。
Call:
lm(formula = log(price) ~ cut + log(carat), data = diamonds_m)
Residuals:
Min 1Q Median 3Q Max
-1.5225 -0.1648 -0.0059 0.1609 1.3811
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 8.39201 0.00174 4835.55 < 2e-16 ***
cut.L 0.22433 0.00440 50.97 < 2e-16 ***
cut.Q -0.06643 0.00389 -17.05 < 2e-16 ***
cut.C 0.05289 0.00340 15.55 < 2e-16 ***
cut^4 0.01863 0.00273 6.81 9.6e-12 ***
log(carat) 1.69577 0.00191 887.68 < 2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.254 on 53934 degrees of freedom
Multiple R-squared: 0.937, Adjusted R-squared: 0.937
F-statistic: 1.61e+05 on 5 and 53934 DF, p-value: <2e-16
注记
有趣的发现: 控制克拉数后,Ideal(最高切工)相比 Fair 的价格溢价约为 12%。但 Premium 与 Very Good 之间差异很小——消费者愿意为「顶级切工」额外支付的溢价,远小于为「克拉数」支付的溢价。
学习路线图
重要
以下内容是本课程的基础,期末考试必考,实际工作必用:
识别何时需要对数变换:散点图弯曲 → 考虑取对数;变量严重右偏 → 考虑取对数
三种对数模型的系数解读(用一句话表达):
exp() 还原虚拟变量的含义:系数 = 该类别相对参照组的均值差(已控制其他变量)
\(k\) 类别用 \(k-1\) 个虚拟变量:去掉一个作参照组;多一个会导致完全共线性,OLS 无法估计
R 操作:lm(log(y) ~ log(x));factor(x, levels = ...) 指定参照组;relevel() 修改参照组
注记
以下内容理解含义即可,不需要记公式、不需要手算:
对数的近似关系:\(\Delta\ln(x) \approx \Delta x / x\),这是「\(x\) 增加 1% 等价于 \(\ln(x)\) 增加 0.01」的数学来源
log-level 反变换的精确公式:\(\%\Delta y = (e^{\hat{\beta}_1} - 1) \times 100\%\);系数较小时用 \(\hat{\beta}_1 \times 100\%\) 近似即可
虚拟变量回归与单因素 ANOVA 的等价性:纯虚拟变量回归(无其他控制变量)在数学上等价于单因素 ANOVA,\(F\) 统计量相同
交互项:虚拟变量与连续变量相乘(lm(y ~ x * D)),允许两组有不同的斜率——这是下讲内容
警告
以下是初学者最容易犯的错误,请对照检查:
| 错误 | 正确理解 |
|---|---|
| 把 level-log 系数解读为「\(x\) 增加 1,\(y\) 增加 \(\hat{\beta}_1\)」 | log-level 的自变量是 \(\ln(x)\);\(x\) 增加 1% 对应 \(\ln(x)\) 增加 \(\approx 0.01\) |
| 忘记对 log-level 预测值做反变换 | 预测 \(\ln(y)\) 后必须用 exp() 还原,才能得到 \(y\) 的预测值 |
| 将有序类别(如 1/2/3 代表低/中/高)直接当数值型使用 | 数值编码暗含「间距相等」假设,应先用 factor() 转换再建模 |
| 创建了 \(k\) 个虚拟变量(含参照组)导致模型报错 | 只能创建 \(k-1\) 个;R 自动处理,手动创建时记得去掉一列 |
| 认为参照组的选择影响模型拟合效果 | 参照组只影响系数的解读方式,不影响 \(R^2\)、AIC 和任何预测值 |
对数变换:解决 \(y\) 与 \(x\) 非线性关系的利器;变换后模型仍然是「对系数的线性模型」;只需在 lm() 里用 log() 包裹变量
level-log:lm(y ~ log(x));\(x\) 增加 1%,\(y\) 增加 \(\hat{\beta}_1/100\) 个单位;适用于收益递减场景
log-level:lm(log(y) ~ x);\(x\) 增加 1 单位,\(y\) 增加约 \(\hat{\beta}_1 \times 100\%\);预测后用 exp() 还原
log-log:lm(log(y) ~ log(x));\(\hat{\beta}_1\) 直接是弹性系数;\(x\) 增加 1%,\(y\) 增加 \(\hat{\beta}_1\%\)
两类虚拟变量:1 个虚拟变量,系数 = 两组均值差(控制其他变量后);R 对字符型/因子型自动处理
三类及以上:\(k\) 个类别用 \(k-1\) 个虚拟变量,参照组藏进截距;factor(levels = ...) 显式指定参照组
使用 diamonds 数据集,分别建立三个模型预测 price:线性模型(price ~ carat)、level-log 模型(price ~ log(carat))、log-level 模型(log(price) ~ carat、log-log 模型(log(price) ~ log(carat))。用 Adjusted \(R^2\) 和 AIC 比较,判断哪个最优,并用一句话解读最优模型的 carat 系数
使用 mtcars 数据集,将变速箱类型 am(0 = 自动挡,1 = 手动挡)作为虚拟变量,建立 mpg ~ wt + factor(am) 的回归模型。解释 am 系数的含义,判断手动挡是否显著影响油耗(在控制车重的前提下)
以 mtcars 中气缸数 cyl 为分类变量,分别以 4 缸和 8 缸作参照组建立两个纯虚拟变量模型。验证:两个模型的 \(R^2\)、AIC 和拟合值(fitted())完全相同,但系数数值和解读不同
使用 gapminder 包中的 gapminder 数据集(install.packages("gapminder")),建立 log-log 模型:log(lifeExp) ~ log(gdpPercap) + continent。解释 log(gdpPercap) 的弹性系数,以及各洲虚拟变量系数的含义;思考:为什么要同时加入 continent?
综合挑战:在练习 1 的 diamonds 最优模型基础上,加入切工等级 cut(factor(),以 "Fair" 为参照组)。对比加入 cut 前后 Adjusted \(R^2\) 和系数的变化;画出系数图(参考本讲切工案例),解释各等级切工的价格溢价。
提示
今天的虚拟变量模型探讨的是自变量为分类变量的情形;而下一讲的逻辑回归则将处理因变量为分类变量的情况。这种转换赋予了模型极大的灵活性,是解决现实中‘判断决策’与‘概率预测’问题的核心工具。
第12讲:对数回归与分类自变量
「所有模型都是错的,但有些是有用的。」
—— 乔治·博克斯(George Box)
数据挖掘与R语言 | 第12讲:对数回归与分类自变量