R语言 lm() 函数实战:3个关键拟合指标(Multiple R/R²/Adj. R²)的深度解读与手动计算
R语言回归分析实战:Multiple R/R²/Adj. R²的深度解析与代码实现
1. 回归分析核心指标概述
在数据分析领域,线性回归是最基础也最强大的工具之一。当我们使用R语言的lm()函数建立回归模型后,summary()输出的结果中包含着三个关键指标:Multiple R、R-Squared和Adjusted R-Squared。这些指标不仅反映了模型的拟合质量,更是评估模型预测能力的重要依据。
Multiple R代表了因变量与所有自变量之间的多重相关性。在简单线性回归中,它就是因变量与单个自变量之间的皮尔逊相关系数;而在多元回归中,它表示因变量的观测值与模型预测值之间的相关性。这个指标的取值范围在0到1之间,值越大表示相关性越强。
R-Squared(决定系数)可能是最广为人知的回归指标,它衡量了模型解释因变量变异的比例。计算公式为:
R² = 1 - (SSE/SST)其中:
- SSE(Sum of Squared Errors)是误差平方和
- SST(Total Sum of Squares)是总平方和
R²的值域为[0,1],数值越高表示模型解释力越强。但R²有一个显著缺陷:每当增加新的自变量时,即使这个变量与因变量无关,R²值也会增加。这可能导致"过拟合"问题。
Adjusted R-Squared正是为了解决这个问题而设计的修正版本。它在R²的基础上引入了自变量数量(k)和样本量(n)的惩罚项:
Adj. R² = 1 - [(1-R²)*(n-1)/(n-k-1)]Adj. R²能够更客观地评估模型质量,特别是在比较不同变量数量的模型时。它可能比原始R²低,但能更真实反映模型的解释能力。
2. 实战:从lm()结果提取关键指标
让我们通过一个实际案例来演示如何从回归模型中提取这些指标。假设我们有一个包含12名学生考试成绩的数据集:
examResult <- data.frame( hours = c(1,1,2,2,1,2,2,3,3,4,4,5), c_score = c(65,78,76,76,79,80,81,84,88,85,96,90), e_score = c(58,61,62,65,65,68,72,74,78,85,90,95) ) # 建立线性回归模型 fit <- lm(e_score ~ hours + c_score, data = examResult) # 查看模型摘要 summary(fit)模型摘要输出中,我们重点关注以下部分:
Multiple R-squared: 0.9558 Adjusted R-squared: 0.946但注意到摘要中没有直接给出Multiple R的值。实际上,Multiple R就是Multiple R-squared的平方根:
# 计算Multiple R multiple_r <- sqrt(0.9558) multiple_r # 结果为0.97763. 手动计算验证指标值
为了深入理解这些指标的计算原理,我们可以手动计算它们,并与summary()的输出进行验证。
3.1 计算预测值和Multiple R
首先,我们根据回归系数计算每个样本的预测值:
# 提取回归系数 coef(fit) # (Intercept) hours c_score # 17.1754 6.3840 0.4861 # 计算预测值 examResult <- examResult %>% mutate(yp = 17.1754 + 6.3840 * hours + 0.4861 * c_score) # 计算Multiple R(观测值与预测值的相关系数) mr <- cor(examResult$e_score, examResult$yp) mr # 结果为0.97766763.2 计算R-Squared和Adjusted R-Squared
# R²是Multiple R的平方 R2 <- mr^2 R2 # 结果为0.955834 # 计算Adjusted R² n <- nrow(examResult) # 样本量12 k <- 2 # 两个自变量(hours和c_score) AR2 <- 1 - ((1-R2)*(n-1))/(n-k-1) AR2 # 结果为0.9460193这些手动计算结果与summary()输出完全一致,验证了我们的理解。
4. 三大指标对比与应用场景
为了更清晰地理解这三个指标的异同,我们整理以下对比表格:
| 指标 | 计算公式 | 取值范围 | 特点 | 适用场景 |
|---|---|---|---|---|
| Multiple R | 观测值与预测值的相关系数 | [0,1] | 反映整体相关性强度 | 评估预测准确性 |
| R-Squared | (Multiple R)² 或 1-SSE/SST | [0,1] | 解释变异比例,随变量增加而增加 | 单模型评估 |
| Adjusted R-Squared | 1-[(1-R²)(n-1)/(n-k-1)] | 可小于0 | 对变量数量进行惩罚 | 模型比较 |
实际应用建议:
- 当比较相同变量数量的不同模型时,使用R²
- 当比较不同变量数量的模型时,必须使用Adj. R²
- Multiple R主要用于理解预测值与实际值的线性关系强度
注意:在简单线性回归(单自变量)中,R²和Adj. R²的值非常接近,此时使用哪个指标区别不大。
5. 进阶应用与常见问题
5.1 模型比较实战
在实际分析中,我们经常需要比较多个模型的性能。以下是一个完整的模型比较流程:
# 建立多个不同复杂度的模型 m1 <- lm(e_score ~ hours, data = examResult) m2 <- lm(e_score ~ c_score, data = examResult) m3 <- lm(e_score ~ hours + c_score, data = examResult) m4 <- lm(e_score ~ hours * c_score, data = examResult) # 包含交互项 # 创建比较表格 library(broom) library(knitr) model_compare <- bind_rows( glance(m1) %>% mutate(Model = "m1"), glance(m2) %>% mutate(Model = "m2"), glance(m3) %>% mutate(Model = "m3"), glance(m4) %>% mutate(Model = "m4") ) %>% select(Model, r.squared, adj.r.squared, AIC, BIC) kable(model_compare, digits = 3)输出结果可能类似于:
| Model | r.squared | adj.r.squared | AIC | BIC |
|---|---|---|---|---|
| m1 | 0.842 | 0.826 | 70.12 | 71.53 |
| m2 | 0.712 | 0.683 | 77.89 | 79.30 |
| m3 | 0.956 | 0.946 | 50.24 | 52.05 |
| m4 | 0.958 | 0.944 | 51.21 | 53.62 |
从结果可见,m3(包含hours和c_score的模型)在R²和Adj. R²上都表现优异,且AIC/BIC值最低,可能是最佳选择。
5.2 指标解释误区
在实践中,有几个常见误区需要注意:
- 高R²不一定代表好模型:如果数据存在异常值或非线性关系,高R²可能误导判断
- Adj. R²可能为负:当模型解释力极差时,Adj. R²可能小于0,这表示模型比使用均值预测还要差
- 指标不是唯一标准:还应考虑残差分析、变量显著性、业务合理性等
5.3 可视化验证
可视化是验证模型质量的重要手段:
# 预测值 vs 观测值图 plot(fitted(fit), examResult$e_score, xlab = "Predicted", ylab = "Actual", main = "Actual vs Predicted Values") abline(0, 1, col = "red") # 残差图 plot(fitted(fit), residuals(fit), xlab = "Predicted", ylab = "Residuals", main = "Residual Plot") abline(h = 0, col = "red")一个理想的模型应该使第一张图的点紧密分布在红色对角线附近,第二张图的残差随机分布在0附近,无明显模式。
6. 性能优化与扩展思考
6.1 模型诊断与改进
在得到初步回归结果后,我们应该进行全面的模型诊断:
# 综合诊断图 par(mfrow = c(2, 2)) plot(fit) par(mfrow = c(1, 1))这些诊断图可以帮助识别:
- 非线性关系(残差图呈现曲线模式)
- 异方差性(残差范围随预测值变化)
- 异常值(显著偏离的观测点)
- 高杠杆点(对模型影响过大的观测点)
6.2 变量选择策略
当面对多个潜在自变量时,如何选择最佳变量组合?以下是几种常用方法:
逐步回归:
# 前向逐步回归 step_model <- step(lm(e_score ~ 1, data = examResult), scope = ~ hours + c_score + I(hours^2), direction = "forward")正则化方法(如岭回归、Lasso):
library(glmnet) x <- model.matrix(e_score ~ hours + c_score, examResult)[,-1] y <- examResult$e_score cv_fit <- cv.glmnet(x, y, alpha = 1) # Lasso回归 plot(cv_fit)基于信息准则的选择(如AIC、BIC):
library(MuMIn) dredge(fit)
6.3 超越线性回归
当数据不符合线性回归假设时,可以考虑:
广义线性模型(GLM):
# 例如,对于计数数据使用泊松回归 glm_model <- glm(count ~ predictor, family = poisson, data = data)非线性回归:
nls_model <- nls(y ~ a * exp(b * x), start = list(a = 1, b = 1))机器学习方法:
library(randomForest) rf_model <- randomForest(e_score ~ ., data = examResult)
7. 实际案例分析
让我们通过一个扩展案例综合应用所学知识。假设我们有一个更大的学生成绩数据集:
# 生成模拟数据 set.seed(123) big_data <- data.frame( study_hours = rnorm(200, mean = 10, sd = 2), prev_score = rnorm(200, mean = 70, sd = 10), attendance = runif(200, min = 0.5, max = 1), extra_curricular = sample(0:1, 200, replace = TRUE) ) %>% mutate(final_score = 30 + 2.5*study_hours + 0.6*prev_score + 15*attendance + 5*extra_curricular + rnorm(200, sd = 5)) # 建立全模型 full_model <- lm(final_score ~ ., data = big_data) summary(full_model)通过分析这个更复杂的数据集,我们可以实践:
- 多重共线性检测(VIF值)
- 变量重要性评估
- 模型简化与优化
- 预测区间计算
# 计算VIF检测多重共线性 library(car) vif(full_model) # 计算预测区间 new_data <- data.frame( study_hours = c(8, 10, 12), prev_score = c(60, 70, 80), attendance = c(0.8, 0.9, 1), extra_curricular = c(0, 1, 1) ) predict(full_model, newdata = new_data, interval = "prediction")在真实项目中,回归分析很少是终点,而通常是探索性分析的起点。理解Multiple R、R²和Adj. R²这些基础指标,能帮助我们在后续更复杂的分析中建立坚实的理论基础和实践直觉。