You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从ggplot2的geom_smooth模型中提取标准差?(二次拟合场景)

解决二次拟合时geom_smooth提取标准差不一致的问题

问题根源

你之前用的ymin=after_stat(y-se*sqrt(length(y))逻辑不成立,因为:

  • geom_smooth中的se是模型预测值的标准误(Standard Error),反映拟合线本身的不确定性(和模型参数方差相关);
  • 你需要的**观测数据的标准差(Standard Deviation)**是原始数据围绕拟合线的离散程度,对应模型的残差标准差(σ);
  • 仅在简单线性回归(y~x)的特殊场景下,se*sqrt(n)才近似等于残差标准差,但二次拟合(y ~ x + I(x^2))属于非线性模型,两者的转换关系完全不适用,因此会出现结果不一致的情况。

正确解决方案

步骤1:拟合模型并提取残差标准差

先通过lm()拟合二次模型,用sigma()提取残差标准差——这就是你要的观测数据围绕拟合线的离散程度:

library(ggplot2)

# 示例数据(替换成你的数据)
set.seed(123)
x <- seq(0, 10, length.out = 100)
y <- 2 + 3*x - 0.2*x^2 + rnorm(100, 0, 2)
df <- data.frame(x, y)

# 拟合二次模型
model <- lm(y ~ x + I(x^2), data = df)
# 提取残差标准差
resid_sd <- sigma(model)

方式一:手动计算区间后绘图(更灵活)

生成拟合值和对应的标准差区间,用geom_line和geom_ribbon绘制:

# 生成预测用的x序列
new_x <- seq(min(df$x), max(df$x), length.out = 100)
pred_df <- data.frame(x = new_x)
# 计算拟合值
pred_df$fit <- predict(model, newdata = pred_df)
# 计算±1倍残差标准差的区间
pred_df$ymin <- pred_df$fit - resid_sd
pred_df$ymax <- pred_df$fit + resid_sd

# 绘图
ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.5) +
  geom_line(data = pred_df, aes(y = fit), color = "blue", linewidth = 1) +
  geom_ribbon(data = pred_df, aes(ymin = ymin, ymax = ymax), alpha = 0.2, fill = "blue")

方式二:直接在geom_smooth中使用残差标准差

如果想保留geom_smooth的语法,可以关闭默认的se,手动指定基于残差标准差的区间:

ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.5) +
  geom_smooth(method = "lm", formula = y ~ x + I(x^2), 
              aes(ymin = after_stat(fit) - resid_sd, 
                  ymax = after_stat(fit) + resid_sd),
              se = FALSE, color = "blue", fill = "blue", alpha = 0.2)

关键说明

  • 残差标准差sigma(model)是全局的,代表整个数据集围绕拟合线的平均离散程度;
  • 如果你的数据存在异方差(不同x对应的离散程度不同),可以考虑用predict(model, interval = "prediction")生成预测区间,它会结合预测值的标准误和残差标准差,更准确反映单个观测的不确定性。

内容的提问来源于stack exchange,提问作者Sibylle Stöckli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:48:19