You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用mgcViz绘制平滑估计值及其差值的方法咨询

mgcViz绘制平滑估计值及其差值的方法咨询

你好呀!我完全get到你的需求了——你想用mgcViz实现类似mgcvvis.gam那样的模型整体拟合估计值可视化,同时也想绘制不同组之间的估计值差值,而不只是平滑项的效应和效应差值,对吧?

先明确下核心区别:mgcvvis.gam输出的是模型对响应变量的整体预测值(比如当fac="A1"时,给定x1、x2的y的估计值),而mgcViz默认的plot(sm(o, 1))只展示单个平滑项的效应(也就是不含模型截距和其他公共项的部分)。下面就来一步步实现你要的效果:

首先先还原你的示例环境:

library(mgcv)
library(mgcViz)
set.seed(235)
dat <- gamSim(1,n=1500,dist="normal",scale=20)
dat$fac <- as.factor( sample(c("A1", "A2", "A3"), nrow(dat), replace = TRUE) )
dat$logi <- as.logical( sample(c(TRUE, FALSE), nrow(dat), replace = TRUE) )
bs <- "cr"; k <- 12
b <- gam(y ~ s(x2, x1, by = fac), data=dat)
o <- getViz(b, nsim = 0)

你提到的三个参考可视化效果:

  • mgcvvis.gam绘制的整体估计值曲面:
    mgcv的vis.gam估计值曲面
  • mgcVizplot(sm(o,1))绘制的平滑项效应:
    mgcViz的平滑项效应图
  • mgcVizplotDiff绘制的平滑项效应差值:
    mgcViz的平滑项效应差值图

一、用mgcViz绘制模型整体估计值(对应vis.gam的效果)

这里有两种简单的实现方式:

方法1:给平滑项效应加上模型截距

你的模型结构中,fac="A1"时的整体预测值 = 模型截距 + 对应平滑项的效应。我们可以直接提取平滑项对象,加上截距后再绘图:

# 获取模型截距
model_intercept <- coef(b)[1]

# 提取fac=A1对应的平滑项效应,加上截距得到整体估计值
sm_a1 <- sm(o, 1)
sm_a1_estimate <- sm_a1
sm_a1_estimate$fit <- sm_a1_estimate$fit + model_intercept  # 加上截距转换为整体估计

# 用mgcViz的风格绘图
plot(sm_a1_estimate) + 
  l_fitRaster() + 
  l_fitContour(color = "white") +
  labs(title = "mgcViz绘制的整体估计值(fac=A1)")

这个结果就和vis.gam(b, cond=list(fac="A1"),plot.type="contour")完全一致啦!

方法2:生成预测网格后绘图

如果你的模型更复杂(比如包含其他协变量),这种方法更通用:先生成指定条件的预测数据,再用ggplot2/mgcViz的可视化语法绘图:

# 生成预测网格:固定fac为"A1",x1、x2取连续序列
pred_grid <- expand.grid(
  x1 = seq(min(dat$x1), max(dat$x1), length.out = 100),
  x2 = seq(min(dat$x2), max(dat$x2), length.out = 100),
  fac = "A1"
)
# 预测整体估计值
pred_grid$y_hat <- predict(b, newdata = pred_grid)

# 用mgcViz兼容的ggplot2风格绘图
library(ggplot2)
ggplot(pred_grid, aes(x = x1, y = x2, z = y_hat)) +
  geom_raster(aes(fill = y_hat)) +
  geom_contour(color = "white", linewidth = 0.5) +
  scale_fill_viridis_c(option = "viridis") +
  labs(title = "mgcViz风格的整体估计值(fac=A1)", fill = "y估计值") +
  theme_bw()

二、用mgcViz绘制整体估计值的差值

这里要注意:同一协变量条件下,不同fac组的整体估计值差值 = 对应平滑项的效应差值,因为模型中的公共项(比如截距、其他非组特异性项)会相互抵消。

所以你之前用plotDiff的代码,其实已经等价于估计值的差值了!我们只需要调整标注,明确这一点:

# 绘制fac=A2与fac=A1的估计值差值
pl <- plotDiff(s1 = sm(o, 1), s2 = sm(o, 2))
pl + 
  l_fitRaster() + 
  l_fitContour(color = "white") +
  labs(title = "整体估计值差值(fac=A2 - fac=A1)")

如果你的模型包含其他组特异性项,只需要把对应项的效应也加入差值计算即可,逻辑是一样的:先提取各组的所有相关项效应,求和得到整体估计,再计算差值后绘图。


备注:内容来源于stack exchange,提问作者David

火山引擎 最新活动