功率定律由`fitdistr()函数在`fitdistrplus`包中拟合

时间:2016-05-11 03:11:58

标签: r mle power-law fitdistrplus

我使用包rplcon()

中的poweRlaw函数生成一些随机变量

data <- rplcon(1000,10,2)

现在,我想知道哪些已知的发行版最适合数据。 Lognorm? EXP?伽玛?权力法?指数截止的幂律?

所以我在包fitdist()中使用函数fitdistrplus

fit.lnormdl <- fitdist(data,"lnorm")
fit.gammadl <- fitdist(data, "gamma", lower = c(0, 0))
fit.expdl <- fitdist(data,"exp")

由于幂律分布和指数截止的幂律不是CRAN Task View: Probability Distributions的基本概率函数,所以我根据{{{4}的例子4写出幂律的d,p,q函数。 1}}

?fitdist

最后,我使用下面的代码获取幂律的参数dplcon <- function (x, xmin, alpha, log = FALSE) { if (log) { pdf = log(alpha - 1) - log(xmin) - alpha * (log(x/xmin)) pdf[x < xmin] = -Inf } else { pdf = (alpha - 1)/xmin * (x/xmin)^(-alpha) pdf[x < xmin] = 0 } pdf } pplcon <- function (q, xmin, alpha, lower.tail = TRUE) { cdf = 1 - (q/xmin)^(-alpha + 1) if (!lower.tail) cdf = 1 - cdf cdf[q < round(xmin)] = 0 cdf } qplcon <- function(p,xmin,alpha) alpha*p^(1/(1-xmin)) xmin

alpha

但它引发了一个错误:

fitpl <- fitdist(data,"plcon",start = list(xmin=1,alpha=1))

我尝试在google和stackoverflow中搜索,并出现了很多类似的错误问题,但在阅读和尝试后,我的问题没有解决方案,我该怎么做才能正确完成参数? 谢谢所有帮我一个忙的人!

1 个答案:

答案 0 :(得分:4)

这是一个有趣的,我对这个发现并不完全满意,但我会告诉你我发现了什么,看看它是否有帮助。

在调用fitdist函数时,默认情况下,它希望使用同一个包中的mledist。这本身导致调用stats::optim,这是一般的优化函数。在其返回值中,它会给出收敛错误代码,有关详细信息,请参阅?optim。您看到的100不是optim返回的其中之一。因此,我拆开了mledistfitdist的代码,以找到错误代码的来源。不幸的是,它在多个案例中定义,并且是一般陷阱错误代码。如果你分解了所有的代码,fitdist试图在这里做的是以下内容,事先经过各种检查等。

fnobj <- function(par, fix.arg, obs, ddistnam) {
  -sum(do.call(ddistnam, c(list(obs), as.list(par), 
                           as.list(fix.arg), log = TRUE)))
}

vstart = list(xmin=5,alpha=5)
fnobj <- function(par, fix.arg obs, ddistnam) {
  -sum(do.call(ddistnam, c(list(obs), as.list(par), 
                           as.list(fix.arg), log = TRUE)))
}
ddistname=dplcon
fix.arg = NULL
meth = "Nelder-Mead"
lower = -Inf
upper = Inf
optim(par = vstart, fn = fnobj, 
      fix.arg = fix.arg, obs = data, ddistnam = ddistname, 
      hessian = TRUE, method = meth, lower = lower, 
      upper = upper)

如果我们运行此代码,我们会发现一个更有用的错误&#34;函数无法在初始参数下评估&#34;。如果我们看一下函数定义,这是有道理的。拥有xmin=0alpha=1会产生-Inf的对数似然。好吧,想想尝试不同的初始值,我尝试了一些随机选择,但都返回了一个新的错误,&#34;非有限的有限差分值1&#34;。

进一步搜索optim源这两个错误的来源,它们不属于R源本身,但是有一个.External2调用,所以我只能假设错误来自那里。非有限误差意味着其中一个函数评估给出了非数字结果。函数dplcon将在alpha <= 1xmin <= 0时执行此操作。 fitdist允许您指定传递给mledist或其他的其他参数(取决于您选择的方法,默认为mle),其中lower是用于控制参数下限的{1}}优化。所以我试着施加这些限制并再试一次:

fitpl <- fitdist(data,"plcon",start = list(xmin=1,alpha=2), lower = c(xmin = 0, alpha = 1))

令人讨厌的是,这仍然给出了错误代码100.跟踪此错误会产生错误&#34; L-BFGS-B需要有限的“fn&#39;&#34;”。当您指定边界时,优化方法已从默认的Nelder-Mead更改,并且在外部C代码调用的某处出现此错误,可能接近xminalpha的限制,其中的稳定性为接近无穷大时的数值计算很重要。

我决定进行分位数匹配而不是最大可能性来尝试找出更多

fitpl <- fitdist(data,"plcon",start = list(xmin=1,alpha=2),
    method= "qme",probs = c(1/3,2/3))
fitpl
## Fitting of the distribution ' plcon ' by matching quantiles 
## Parameters:
##          estimate
## xmin   0.02135157
## alpha 46.65914353

表明xmin的最佳值接近0,这是它的极限。我不满意的原因是我无法使用fitdist获得分布的最大似然拟合,但希望这种解释有所帮助,并且分位数匹配提供了另一种选择。

修改

在了解了一般关于幂律分布的更多内容之后,有意义的是,这并不像您期望的那样有效。参数功率参数具有似然函数,该函数函数可以在给定的xmin条件下最大化。然而,xmin不存在这样的表达式,因为似然函数在xmin中增加。通常,xmin的估计来自Kolmogorov - Smirnov统计量,请参阅this mathoverflow问题和poweRlaw包的d_jss_paper插图以获取更多信息和相关参考。

有功能可以估算poweRlaw包本身中幂律分布的参数。

m = conpl$new(data)
xminhat = estimate_xmin(m)$xmin
m$setXmin(xminhat)
alphahat = estimate_pars(m)$pars
c(xmin = xminhat, alpha = alphahat)