如何限制删失伽马分布的百分位数曲线不超出0-100边界
问题:删失伽马分布拟合的百分位数曲线超出100边界
我正尝试为删失伽马分布拟合百分位数曲线,删失处理过程正常,但生成的百分位数曲线出现超出100的情况(见下图)。
使用的代码如下:
y <- c(35.00, 100.00, 100.00, 5.00, 40.00, 40.00, 80.00, 50.00, 40.00, 60.00, 45.00, 100.00, 40.00, 15.00, 45.00, 40.00, 72.50, 50.00, 100.00, 35.00, 100.00, 50.00, 60.00, 30.00, 50.00, 56.25, 70.00, 50.00, 75.00, 100.00, 83.00, 100.00, 81.25, 40.00, 50.00, 40.00, 36.00, 40.00, 56.25, 25.00, 100.00, 50.00, 67.00, 100.00, 70.00, 45.00, 50.00, 100.00, 50.00, 50.00, 50.00, 30.00, 50.00, 62.50, 30.00, 55.00, 40.00, 40.00, 25.00, 45.00, 20.00, 40.00, 100.00, 40.00, 50.00, 75.00, 100.00, 50.00, 40.00, 70.00, 35.00, 100.00, 100.00, 80.00, 50.00) x <- c(44, 58, 57, 67, 52, 41, 49, 41, 33, 42, 47, 61, 68, 57, 58, 42, 53, 57, 57, 49, 58, 42, 55, 34, 55, 52, 61, 66, 57, 53, 50, 48, 69, 66, 60, 65, 56, 47, 52, 36, 62, 63, 50, 61, 56, 46, 35, 65, 48, 65, 58, 65, 64, 58, 53, 63, 58, 54, 64, 40, 65, 50, 61, 57, 61, 48, 64, 56, 62, 56, 50, 66, 65, 64, 64) ysurv <- Surv(y1, y1!=100, type="right") gen.cens(GA, type = "right") g0Cens <- gamlss(ysurv ~ x, sigma.fo = ~x, nu.fo = ~ x, family = GArc) centiles(g0Cens, x)
由于实际取值仅在0-100之间,请问如何避免百分位数曲线超出100的边界?
解决方案
1. 使用截断伽马分布限制取值范围
伽马分布原生取值范围是(0, +∞),即使做右删失,模型仍可能外推到100以上。改用截断在[0,100]的伽马分布,从模型层面限制分布边界:
# 生成右截断伽马分布族,截断上限设为100 gen.trun(family = GA, type = "right", trunc = 100) # 拟合截断伽马模型(若为删失数据,需确保删失标记与截断逻辑一致) g0Trunc <- gamlss(y ~ x, sigma.fo = ~x, nu.fo = ~x, family = GAtr) centiles(g0Trunc, x)
2. 变量变换后拟合再反变换
将因变量缩放至[0,1]后做logit变换,转换到无边界尺度拟合模型,最后反变换回0-100范围:
# 缩放并做logit变换 y_scaled <- y / 100 y_logit <- qlogis(y_scaled) # 处理删失:原y=100对应logit变换后为+∞,标记为右删失 ysurv_logit <- Surv(y_logit, y != 100, type = "right") # 拟合模型 g0Logit <- gamlss(ysurv_logit ~ x, sigma.fo = ~x, nu.fo = ~x, family = NO) # 生成百分位数并反变换回原尺度 cent_logit <- centiles(g0Logit, x) cent_original <- plogis(cent_logit) * 100 # 绘制修正后的曲线 plot(x, y, ylim = c(0,100)) matlines(sort(x), t(cent_original)[,order(x)], col = 2:6, lty = 1)
这种方法强制结果落在0-100之间,但需验证变换后的模型假设合理性。
3. 事后截断超出边界的数值
若不想修改模型,可直接对生成的百分位数做边界截断:
# 生成原模型的百分位数 cent <- centiles(g0Cens, x) # 截断超出0-100的数值 cent[cent > 100] <- 100 cent[cent < 0] <- 0 # 绘制修正后的曲线 plot(x, y, ylim = c(0,100)) matlines(sort(x), t(cent)[,order(x)], col = 2:6, lty = 1)
此方法操作简单,但属于事后修正,未从模型层面解决外推问题,仅适用于快速调整或可视化场景。
内容的提问来源于stack exchange,提问作者Mathemagician777
相关产品推荐
相关产品推荐

