适合三角分布

时间:2016-10-11 16:13:31

标签: r distribution fitdistrplus

我有以下数据

dat<-c(16.254884, 14.077510, 12.851675, 19.152597, 11.511230, 
   16.122911, 16.099962,  9.670949, 12.523661, 15.257432, 13.603848,
   14.118873, 12.632340, 15.413753,  5.426383, 11.369880, 12.895920, 
   13.635134, 15.118388,13.154107, 8.913164, 17.302810, 14.968054, 
   16.200151, 16.068944, 18.571952, 15.247535, 15.018281)

我正在使用此代码来查找模式:

Mode_fc <- function(x) {
     ux <- unique(x)
     ux[which.max(tabulate(match(x, ux)))]
 }

使用MyParam,我可以获得最小值,最大值和模式

MyParam <- c(min= min(dat), max= max(dat), mode= Mode_fc(dat))

当我在下面的代码中输入这些值时,fitdist按预期工作

fitdist(dat, "triang", start = list(min=5.4, max=19.2, mode=16.3))

但是,当我尝试阅读MyParam时,我会遇到各种各样的错误

fitdist(dat, "triang", 
 start = list(min=MyParam[[1]], max=MyParam[[2]], mode=MyParam[[3]]))

我知道问题出在optim(),但我无法弄清楚如何解决这个问题。任何建议表示赞赏!

2 个答案:

答案 0 :(得分:1)

你的问题(诚然相当微妙)是三角分布下数据的可能性为零(因此对数似然是负无穷大),如果任何数据在外面,或在边界上,分发。插图:

library(fitdistrplus)
library(mc2d)  ## needed for dtriang

尝试拟合(如上例所示):

L1 <- list(min=5.4, max=19.2, mode=16.3)
fitdist(dat, "triang", start = L1)  ## works
L2 <- list(min=MyParam[[1]], max=MyParam[[2]], mode=MyParam[[3]])
fitdist(dat, "triang",  start = L2)  ## fails

让我们稍微分解一下,看看每组参数的实际对数似然性是什么:

do.call(dtriang,c(list(x=dat,log=TRUE),L1))
##  [1] -1.935669 -2.159550 -2.311845 -6.045302 -2.510156 -1.947902 -1.950044
##  [8] -2.868448 -2.356862 -2.032059 -2.215681 -2.154794 -2.341722 -2.016325
## [15] -7.955320 -2.533557 -2.305925 -2.211875 -2.046264 -2.272062 -3.063767
## [22] -2.355858 -2.061854 -1.940724 -1.952947 -3.461371 -2.033063 -2.056619

所有有限值。

(test2 <- do.call(dtriang,c(list(x=dat,log=TRUE),L2)))
##  [1] -1.926160 -2.150652 -2.303450      -Inf -2.502540 -1.938423 -1.940570
##  [8] -2.862702 -2.348631 -2.022796 -2.206960 -2.145882 -2.333434 -2.007021
## [15]      -Inf -2.526044 -2.297509 -2.203141 -2.037041 -2.263528 -3.059363
## [22] -2.375012 -2.052673 -1.931228 -1.943481 -3.533698 -2.023803 -2.047423

两个无限值,对应于最小值和最大值。

which(!is.finite(test2))  ## 4 15
which.min(test2)  ## 4
which.max(test2)  ## 5

我们可以通过调整最小值并从观察值中调整最大值来轻松解决这个问题:

eps <- 0.100
L3 <- list(min=MyParam[[1]]-eps, max=MyParam[[2]]+eps, mode=MyParam[[3]])
fitdist(dat, "triang",  start = L3)

这很好用。

答案 1 :(得分:-1)

您必须使用一个[]而不是[[]]来对MyParam的最小值和最大值进行子集化。

window.onload = function(){}