我想在R中拟合三个参数对数正态分布(参见here以供参考)。
我的MWE如下:
set.seed(12345)
library(FAdist)
X <- rlnorm3(n=100, shape = 2, scale = 1.5, thres = 1)
# m: Location Parameter
# s: Scale Parameter
# t: Threshold Parameter
LL3 <- function(X, m, s, t)(1/((X-t)*s*(2*pi)^0.5))*exp(((-(log(X-t)-m)^2)/(2*s^2)))
library(MASS)
fitdistr(x=X, densfun=LL3, start=list(m=2, s=1.5, t=1))
但是此代码会抛出以下错误消息:
Error in stats::optim(x = c(30.9012208754183, 223.738029433835,
46.4287558537441, : non-finite finite-difference value [3] In addition: Warning message: In log(X - t) : NaNs produced
是否有任何R包适合三个参数分布,例如三个参数Log-normal
,Gamma
,Weibull
和Log-logistic distributions
?
答案 0 :(得分:2)
错误消息表明在估计目标函数的梯度时存在问题。这可能会发生几种原因,但最可能的原因之一是在分布拟合/优化过程中其中一个参数变为负值或导致负值(可能是您的阈值参数变得大于对数正态变量,在这种情况下,分布在那些点应该是0 ......不幸的是,fitdistr
不知道这一点。
解决此类问题的最佳方法是尝试不同的起始参数,或者在这些情况下找到一种方法使分布为fitdistr
。
编辑:此外,代码还有其他错误,请尝试,如Jealie建议的那样:
LL3 <- function(X, m, s, t)ifelse(t>=X,0,(1/((X-t)*s*(2*pi)^0.5))*exp(((-(log(X-t)-m)^2)/(2*s^2))))
和rlnorm3
而不是rllog3
答案 1 :(得分:2)
事实上,似乎dlnorm3
(内置于FAdist
包中)已经x<=thres
时返回零概率,因此将dlnorm3
直接插入{ {1}}似乎工作正常:
fitdistr
结果:
set.seed(12345)
library(FAdist)
library(MASS)
X <- rlnorm3(n=100, shape = 2, scale = 1.5, thres = 1)
fitdistr(X,dlnorm3,start=list(shape = 2, scale = 1.5, thres = 1))
如果我们使用 shape scale thres
2.31116615 1.94366899 1.02798643
(0.18585476) (0.23426764) (0.01480906)
函数生成值(我们得到更多极端值),则会失败:
rllog3
使用Y <- rllog3(n=100, shape = 2, scale = 1.5, thres = 1)
fitdistr(Y,dlnorm3,start=list(shape = 2, scale = 1.5, thres = 1),
method="Nelder-Mead")
## Error in stats::optim(x = c(10.1733112422871,
## 310.508398424974, 1.08946140904075, :
## non-finite finite-difference value [3]
,如果我们切换到Nelder-Mead,我们可以推迟问题直到计算出Hessian。
如果我们使用debug(optim)
代替我们至少可以得到系数(警告Hessian不能被反转......)
bbmle::mle2