使用fitdistrplus拟合泊松二项分布时遇参数匹配错误求助
解决fitdist拟合泊松二项分布时的参数报错问题
报错核心原因
你遇到的问题本质有两点:
fitdist默认仅支持拟合标量参数的分布,而dpoibin的pp是向量型参数,工具内部的参数检查机制无法识别这种类型的参数传递。- 直接拟合与样本量数量相同的向量参数(比如你的示例中10个观测对应10个
pp元素),统计上属于过拟合,没有实际意义。
临时验证方案(不推荐实际使用)
如果只是想绕过参数检查验证函数调用逻辑,可以自定义包装函数,把向量参数拆成多个标量参数传入:
library(fitdistrplus) library(poibin) set.seed(123) # 生成示例数据 dd <- rpoibin(10, pp=seq(0.1, 0.5, length.out=10)) # 自定义包装函数,将pp拆分为单个标量参数 dpoibin_wrap <- function(x, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) { pp_vec <- c(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) dpoibin(x, pp_vec) } # 设置10个标量参数的初始值 start_vals <- as.list(runif(10)) names(start_vals) <- paste0("p", 1:10) # 执行拟合(注意:此方法会导致过拟合,仅作演示) ret <- fitdist(dd, distr=dpoibin_wrap, start=start_vals)
合理的拟合方案(推荐)
实际应用中,我们通常假设所有伯努利试验的成功概率pp来自某个共同的分布(比如Beta分布),然后拟合该分布的参数,避免过拟合。以下是基于Beta分布假设的拟合示例:
library(poibin) set.seed(123) dd <- rpoibin(10, pp=seq(0.1, 0.5, length.out=10)) # 定义边际对数似然函数(蒙特卡洛近似) log_lik_beta <- function(params, data, n_trials=10) { shape1 <- params[1] shape2 <- params[2] # 参数约束:Beta分布的形状参数必须大于0 if (shape1 <= 0 || shape2 <= 0) return(-Inf) total_ll <- 0 # 对每个观测值计算边际对数似然 for (x in data) { # 生成1000组符合Beta分布的pp向量 pp_mat <- rbeta(n_trials * 1000, shape1, shape2) dim(pp_mat) <- c(1000, n_trials) # 计算每组pp对应的泊松二项分布密度 dens <- apply(pp_mat, 1, function(pp) dpoibin(x, pp)) # 取平均作为边际密度的估计,累加对数似然 total_ll <- total_ll + log(mean(dens)) } return(total_ll) } # 使用optim拟合Beta分布的形状参数 init_params <- c(shape1=1, shape2=1) fit_result <- optim(init_params, log_lik_beta, data=dd, n_trials=10, control=list(fnscale=-1)) # fnscale=-1表示最大化对数似然 # 查看拟合结果 fit_result
补充说明
如果你的pp有已知的结构(比如线性变化p_i = a + b*i),也可以基于该结构定义包装函数,拟合结构中的标量参数(比如a和b),这种方式同样能避免过拟合。
内容的提问来源于stack exchange,提问作者Tad Dallas
相关产品推荐
相关产品推荐

