mgcv结果的visreg可视化(GAM)

机器算法验证 r 数据可视化 随机效应模型 广义加法模型 毫克CV
2022-03-24 07:29:36

我使用 mgcv 为 GAM 安装了随机效应,我注意到使用 visreg 的平滑可视化似乎与 mgcv 绘图的输出不匹配:

library(ggplot2)
library(visreg)
library(mgcv)

fit <- gam(log(Response) ~ s(Tag, by=Wundinfektionsstatus) + s(PatientenID, bs = "re") + s(PatientenID, Tag, bs = "re"), data=zeitreihen, method="REML")

intercept <- fit$coefficients[["(Intercept)"]]

plot(fit, trans = exp, shift = intercept, shade=T, residuals=T, select=1)
plot(fit, trans = exp, shift = intercept, shade=T, residuals=T, select=2)

visreg(fit, "Tag", "Wundinfektionsstatus", gg=T, type="conditional", overlay=T, partial=F, rug=F, ylab="Response", trans=exp)

第一顺 第二顺 visreg 输出

前两个图与数据非常匹配,特别是第二个图中的持续下降。请注意,在 visreg 图中,该曲线看起来几乎恒定,末端急剧上升,并且第一个最大值的高度不匹配。

知道这种脱节是如何产生的吗?

1个回答

之所以出现差异,是因为您在通过该方法时忽略了截距(以及该因子的非参考水平的系数;请参见第一个注释)mgcv:::plot.gam()visreg输出显示了每个变量的平滑效果,条件是模型的其他项。蓝线显示 的估计平滑效果Tag,包括模型截距。

请注意您的模型可能是错误的;您可能应该包括Wundinfektionsstatus,因为因子平滑以零为中心,因此您需要一个参数固定效果(在这种情况下)来提高调整每个级别的平均响应向上/向下。没有它,模型必须将其构建到平滑函数中。

您可以在mgcv中通过模型预测值网格Tag(在本例中为蓝线)为您的因子的每个级别重复的值,您可以在 mgcv 中实现相同的目标,并且您需要包含一个虚拟患者 ID,我们'将排除:

## Assuming data in df
pred_df <- with(df, expand.grid(Tag = seq(min(Tag), max(Tag), length = 100),
                                Wundinfektionsstatus = levels(Wundinfektionsstatus),
                                PatientenID = sample(PatientenID, 1)))

pred <- predict(fit, newdata = pred_df, type = 'link', se.fit = TRUE,
                exclude = c("s(PatientenID)", "s(PatientenID,Tag)"))
pred_df <- cbind(pred_df, as.data.frame(pred))

## create confidence interval and back transform
pred_df <- transform(pred_df,
                     fitted_response = exp(fit),
                     fitted_upper    = exp(fit + (2 * se.fit)),
                     fitted_lower    = exp(fit - (2 * se.fit)))

pred_df应该采用您认为合适的格式以使用ggplot2进行绘图:

library('ggplot2')

ggplot(pred_df, aes(x = Tag, y = fitted_response)) +
  geom_ribbon(aes(fill = Wundinfektionsstatus, ymin = fitted_lower,
                  ymax = fitted_upper)) +
  geom_line(aes(colour = Wundinfektionsstatus))

注意:当我从内存中编写此代码时,将上述代码作为伪代码进行线程化,并且未经测试,因为没有可重现的示例。