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

如何限制删失伽马分布的百分位数曲线不超出0-100边界

问题:删失伽马分布拟合的百分位数曲线超出100边界

我正尝试为删失伽马分布拟合百分位数曲线,删失处理过程正常,但生成的百分位数曲线出现超出100的情况(见下图)。
Centile curves for gamma distribution censored at 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 03:35:04