使用Terra生成Logit GAM物种预测栅格遇问题:报错与非二进制预测值
问题1:GAM预测值为何不是0/1二进制值
默认情况下,mgcv::predict.gam返回的是logit链接尺度的线性预测值(范围为负无穷到正无穷),这是二项式模型的标准默认输出,并非直接的分类结果。
要得到预期的结果,分两步操作:
- 获得物种存在的概率(0~1区间):指定
type="response"参数pred_prob <- predict(mod_gam, type = "response") - 转换为0/1二进制分类:用阈值(通常取0.5)切割概率值
pred_binary <- ifelse(pred_prob >= 0.5, 1, 0)
问题2:
terra::predict()报"invalid name(s)"错误的解决 这个错误是因为terra::predict与mgcv::gam的默认参数交互不兼容,调整调用方式即可解决:
方案1:直接生成概率预测栅格
无需额外指定fun="predict",直接传递type="response"参数给模型的predict方法:
pred_raster_prob <- terra::predict(r, mod_gam, type = "response", na.rm = TRUE)
方案2:生成二进制分类栅格
如果需要直接输出0/1的分类结果,自定义预测函数传入fun参数:
gam_predict_fun <- function(model, data) { prob <- predict(model, newdata = data, type = "response") ifelse(prob >= 0.5, 1, 0) } pred_raster_binary <- terra::predict(r, mod_gam, fun = gam_predict_fun, na.rm = TRUE)
完整修正代码
library(terra) library(mgcv) library(sf) # 加载数据 v <- vect(system.file("ex/lux.shp", package="terra")) |> st_as_sf() r <- rast(system.file("ex/elev.tif", package="terra")) # 生成采样点并提取栅格值 set.seed(50) pnts <- st_sample(v, size = 50, type = "random") |> st_as_sf() pnts_r <- terra::extract(r, pnts, method = "simple") # 添加响应变量 pnts_r$occ <- as.factor(sample(0:1, 50, replace = TRUE)) # 拟合GAM模型 mod_gam <- mgcv::gam(formula = occ ~ elevation, data = pnts_r, family = binomial(link = "logit"), method = "REML") # 训练数据的预测 pred_prob <- predict(mod_gam, type = "response") pred_binary <- ifelse(pred_prob >= 0.5, 1, 0) # 栅格预测:概率结果 pred_raster_prob <- terra::predict(r, mod_gam, type = "response", na.rm = TRUE) # 栅格预测:二进制分类结果 gam_predict_fun <- function(model, data) { prob <- predict(model, newdata = data, type = "response") ifelse(prob >= 0.5, 1, 0) } pred_raster_binary <- terra::predict(r, mod_gam, fun = gam_predict_fun, na.rm = TRUE)
内容的提问来源于stack exchange,提问作者seak23
相关产品推荐
相关产品推荐

