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

如何在同一张图中绘制多个GAM模型的参数化连续变量?

解决方案:在同一张图中绘制GAM模型的参数化连续变量

一、同一参数化变量(如两个模型中的z)同图绘制

方法1:使用mgcViz提取绘图数据后合并

mgcViz的pterm()函数可以提取参数化项的绘图数据,我们可以将两个模型的数据合并后用ggplot统一绘制:

library(mgcViz)
library(ggplot2)
library(dplyr)

# 将模型转换为gamViz对象
gv1 <- getViz(g1)
gv2 <- getViz(g2)

# 提取z变量的偏效应数据,并标记模型来源
df_g1 <- pterm(gv1, "z")$data %>% mutate(model = "g1")
df_g2 <- pterm(gv2, "z")$data %>% mutate(model = "g2")

# 合并数据并绘制对比图
bind_rows(df_g1, df_g2) %>%
  ggplot(aes(x = x, y = y, color = model)) +
  geom_line(linewidth = 1) +
  # 添加95%置信区间(2倍标准误)
  geom_ribbon(aes(ymin = y - 2*se, ymax = y + 2*se, fill = model), 
              alpha = 0.2, color = NA) +
  labs(x = "z", y = "Partial Effect", color = "Model", fill = "Model") +
  theme_minimal()

方法2:手动提取偏效应(无需mgcViz)

如果不用mgcViz,可以通过predict.gam()的type="terms"参数直接提取参数化项的偏效应,再整理数据绘图:

library(mgcv)
library(ggplot2)
library(dplyr)

# 生成覆盖两个模型z变量范围的序列
z_range <- range(c(g1$model$z, g2$model$z))
z_seq <- seq(z_range[1], z_range[2], length.out = 100)

# 提取g1中z的偏效应及标准误
pred_g1 <- predict(g1, 
                   newdata = data.frame(z = z_seq, y = mean(g1$model$y)),  # 控制其他变量为均值
                   type = "terms", 
                   se.fit = TRUE)
df_g1 <- data.frame(
  z = z_seq,
  effect = pred_g1$fit[, "z"],
  se = pred_g1$se.fit[, "z"],
  model = "g1"
)

# 提取g2中z的偏效应及标准误
pred_g2 <- predict(g2, 
                   newdata = data.frame(z = z_seq, y1 = mean(g2$model$y1)),
                   type = "terms", 
                   se.fit = TRUE)
df_g2 <- data.frame(
  z = z_seq,
  effect = pred_g2$fit[, "z"],
  se = pred_g2$se.fit[, "z"],
  model = "g2"
)

# 合并绘图
bind_rows(df_g1, df_g2) %>%
  ggplot(aes(x = z, y = effect, color = model)) +
  geom_line(linewidth = 1) +
  geom_ribbon(aes(ymin = effect - 2*se, ymax = effect + 2*se, fill = model),
              alpha = 0.2, color = NA) +
  labs(x = "z", y = "Partial Effect", color = "Model", fill = "Model") +
  theme_minimal()

二、不同参数化变量(如z和z1)同图绘制

可以实现,但需要注意变量的尺度和含义是否适合直接对比。如果变量单位或取值范围差异大,建议先标准化变量,或用分面展示:

方案1:标准化变量后同图对比

将z和z1转换为z-score(标准化),让偏效应的尺度具有可比性:

library(mgcv)
library(ggplot2)
library(dplyr)

# 处理g3的z变量
z_mean <- mean(g3$model$z)
z_sd <- sd(g3$model$z)
z_seq_std <- seq(min((g3$model$z - z_mean)/z_sd), max((g3$model$z - z_mean)/z_sd), length.out = 100)
z_seq_original <- z_seq_std * z_sd + z_mean  # 保留原始值用于预测

pred_g3 <- predict(g3, 
                   newdata = data.frame(z = z_seq_original, y = mean(g3$model$y)),
                   type = "terms", 
                   se.fit = TRUE)
df_g3 <- data.frame(
  variable = "z",
  x_std = z_seq_std,
  effect = pred_g3$fit[, "z"],
  se = pred_g3$se.fit[, "z"]
)

# 处理g4的z1变量
z1_mean <- mean(g4$model$z1)
z1_sd <- sd(g4$model$z1)
z1_seq_std <- seq(min((g4$model$z1 - z1_mean)/z1_sd), max((g4$model$z1 - z1_mean)/z1_sd), length.out = 100)
z1_seq_original <- z1_seq_std * z1_sd + z1_mean

pred_g4 <- predict(g4, 
                   newdata = data.frame(z1 = z1_seq_original, y1 = mean(g4$model$y1)),
                   type = "terms", 
                   se.fit = TRUE)
df_g4 <- data.frame(
  variable = "z1",
  x_std = z1_seq_std,
  effect = pred_g4$fit[, "z1"],
  se = pred_g4$se.fit[, "z1"]
)

# 合并绘图
bind_rows(df_g3, df_g4) %>%
  ggplot(aes(x = x_std, y = effect, color = variable)) +
  geom_line(linewidth = 1) +
  geom_ribbon(aes(ymin = effect - 2*se, ymax = effect + 2*se, fill = variable),
              alpha = 0.2, color = NA) +
  labs(x = "Standardized Variable (z-score)", y = "Partial Effect", 
       color = "Variable", fill = "Variable") +
  theme_minimal()

方案2:分面展示(避免尺度混淆)

如果不想标准化,用分面可以清晰展示各自的偏效应,同时保留原始变量尺度:

# 基于上面的df_g3和df_g4,调整数据格式
df_g3 <- df_g3 %>% mutate(x_original = z_seq_original)
df_g4 <- df_g4 %>% mutate(x_original = z1_seq_original)

bind_rows(df_g3, df_g4) %>%
  ggplot(aes(x = x_original, y = effect)) +
  geom_line(color = "#2c3e50", linewidth = 1) +
  geom_ribbon(aes(ymin = effect - 2*se, ymax = effect + 2*se),
              alpha = 0.2, fill = "#2c3e50") +
  facet_wrap(~variable, scales = "free_x") +  # 每个变量用独立的x轴
  labs(x = "Variable Value", y = "Partial Effect") +
  theme_minimal()

内容的提问来源于stack exchange,提问作者mto23

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:33:16