2016-07-30 118 views
3

我想估計3p威布爾分佈的尺度,形狀和閾值參數。r中三參數威布爾分佈的極大似然估計

我到目前爲止已經做的是以下幾點:

指的這個帖子,Fitting a 3 parameter Weibull distribution in R

我用過的功能

EPS = sqrt(.Machine$double.eps) # "epsilon" for very small numbers 

llik.weibull <- function(shape, scale, thres, x) 
{ 
    sum(dweibull(x - thres, shape, scale, log=T)) 
} 

thetahat.weibull <- function(x) 
{ 
    if(any(x <= 0)) stop("x values must be positive") 

    toptim <- function(theta) -llik.weibull(theta[1], theta[2], theta[3], x) 

    mu = mean(log(x)) 
    sigma2 = var(log(x)) 
    shape.guess = 1.2/sqrt(sigma2) 
    scale.guess = exp(mu + (0.572/shape.guess)) 
    thres.guess = 1 

    res = nlminb(c(shape.guess, scale.guess, thres.guess), toptim, lower=EPS) 

    c(shape=res$par[1], scale=res$par[2], thres=res$par[3]) 
} 

「預估計」我威布爾參數,以便我可以將它們用作MASS包的「fitdistr」函數中參數「start」的初始值。

您可能會問爲什麼我想估計兩次參數......原因是我需要估計值的方差 - 協方差矩陣,這也是由fitdistr函數估計的。

例:

set.seed(1) 

    thres <- 450 
    dat <- rweibull(1000, 2.78, 750) + thres 

pre_mle <- thetahat.weibull(dat) 

    my_wb <- function(x, shape, scale, thres) { 
     dweibull(x - thres, shape, scale) 
    } 

    ml <- fitdistr(dat, densfun = my_wb, start = list(shape = round(pre_mle[1], digits = 0), scale = round(pre_mle[2], digits = 0), 
    thres = round(pre_mle[3], digits = 0))) 

    ml 

    > ml 
     shape  scale  thres 
     2.942548 779.997177 419.996196 ( 0.152129) (32.194294) (28.729323) 

    > ml$vcov 
       shape  scale  thres 
    shape 0.02314322 4.335239 -3.836873 
    scale 4.33523868 1036.472551 -889.497580 
    thres -3.83687258 -889.497580 825.374029 

這工作得很好,其中形狀參數大於1的情況下不幸的是我的做法應該處理的情況下,形狀參數可以是小於1

的原因爲何這對於小於1的形狀參數是不可能的這裏描述:http://www.weibull.com/hotwire/issue148/hottopics148.htm

在情況1中,所有三個參數都是未知的,以下是說:

「定義ti的最小失效時間爲tmin。那麼當γ→tmin時,ln(tmin-γ)→-∞。如果β小於1,則(β-1)ln(tmin-γ)變爲+∞。對於給定的β,η和γ解,我們總是可以找到另一組解(例如,使γ更接近tmin),這將給出更大的似然值。因此,對於β,η和γ沒有MLE的解決方案。「

這使得有很大的意義。正是由於這個原因,我想這樣做,他們形容此頁面上的方式。

」在Weibull ++是一種基於梯度的算法,用於尋找β,η和γ的MLE解。 γ的範圍的上限任意設定爲tmin的0.99。根據數據集,本地最優或0.99tmin作爲γ的MLE解決方案返回。「

我想爲gamma設置一個可行的時間間隔(在我的代碼中稱爲'thres'),以便解決方案是之間(0,0.99 * t最小)。

有沒有人有一個想法如何解決這個問題呢?

在功能fitdistr似乎沒有機會做一個限制MLE,制約一個參數。

另一種方法是通過評分向量的外積來估計漸近方差,得分可以從上面使用的函數thetahat.weibul(x)中獲取矢量。但是手動計算外部產品(沒有函數)似乎非常耗時,並且不能解決約束ML估計的問題。

最好的問候, 添

回答

3

這不是太難建立約束MLE。我打算在bbmle::mle2這樣做;您也可以在stats4::mle中執行此操作,但bbmle還有一些其他功能。

更大的問題是它理論上難以定義估計值在允許空間邊界上時的採樣方差;瓦爾德方差估計背後的理論崩潰了。你仍然可以通過可能性分析來計算置信區間......或者你可以引導。這樣做時,我遇到了各種各樣的問題,優化......我真的沒有想過羯羊有特殊原因

格式化三個參數mle2使用(韋伯函數採用x作爲第一個參數,需要log作爲參數):

dweib3 <- function(x, shape, scale, thres, log=TRUE) { 
    dweibull(x - thres, shape, scale, log=log) 
} 

啓動功能(略有重新格式化):

weib3_start <- function(x) { 
    mu <- mean(log(x)) 
    sigma2 <- var(log(x)) 
    logshape <- log(1.2/sqrt(sigma2)) 
    logscale <- mu + (0.572/logshape) 
    logthres <- log(0.5*min(x)) 
    list(logshape = logshape, logsc = logscale, logthres = logthres) 
} 

生成數據:

set.seed(1) 
dat <- data.frame(x=rweibull(1000, 2.78, 750) + 450) 

擬合模型:爲了方便和穩定性,我將擬合參數放在對數刻度上,但您也可以使用邊界爲零。

tmin <- log(0.99*min(dat$x)) 
library(bbmle) 
m1 <- mle2(x~dweib3(exp(logshape),exp(logsc),exp(logthres)), 
      data=dat, 
      upper=c(logshape=Inf,logsc=Inf, 
        logthres=tmin), 
      start=weib3_start(dat$x), 
      method="L-BFGS-B") 

vcov(m1),通常應該提供一個方差 - 協方差估計(除非估計的邊界,這是不是這裏的情況上)給出NaN值......不知道爲什麼沒有更多的挖掘。

library(emdbook) 
tmpf <- function(x,y) [email protected](logshape=x, 
             logsc=coef(m1)["logsc"], 
             logthres=y) 
tmpf(1.1,6) 
s1 <- curve3d(tmpf, 
       xlim=c(1,1.2),ylim=c(5.9,tmin),sys3d="image") 
with(s1,contour(x,y,z,add=TRUE)) 

enter image description here

h <- lme4:::hessian(function(x) do.call([email protected],as.list(x)),coef(m1)) 
vv <- solve(h) 
diag(vv) ## [1] 0.002672240 0.001703674 0.004674833 
(se <- sqrt(diag(vv))) ## standard errors 
## [1] 0.05169371 0.04127558 0.06837275 
cov2cor(vv) 
##   [,1]  [,2]  [,3] 
## [1,] 1.0000000 0.8852090 -0.8778424 
## [2,] 0.8852090 1.0000000 -0.9616941 
## [3,] -0.8778424 -0.9616941 1.0000000 

這是日誌縮放變量的方差 - 協方差矩陣。如果要轉換爲原始尺度上的方差 - 協方差矩陣,則需要按(x_i)*(x_j)進行縮放(即通過變換exp(x)的導數)。

outer(exp(coef(m1)),exp(coef(m1))) * vv 
##    logshape  logsc logthres 
## logshape 0.02312803 4.332993 -3.834145 
## logsc  4.33299307 1035.966372 -888.980794 
## logthres -3.83414498 -888.980794 824.831463 

我不知道爲什麼這不符合numDeriv工作 - 將非常小心方差上述估計。 (也許太靠近邊界的外推理查森工作?)

library(numDeriv) 
hessian() 
grad(function(x) do.call([email protected],as.list(x)),coef(m1)) ## looks OK 
vcov(m1) 

的輪廓看起來OK ......(我們必須提供std.err因爲黑森州不可逆)

pp <- profile(m1,std.err=c(0.01,0.01,0.01)) 
par(las=1,bty="l",mfcol=c(1,3)) 
plot(pp,show.points=TRUE) 

enter image description here

confint(pp) 
##    2.5 % 97.5 % 
## logshape 0.9899645 1.193571 
## logsc 6.5933070 6.755399 
## logthres 5.8508827 6.134346 

另外,我們在原有規模可以做到這一點...一種可能性是使用對數標度適合,然後從原始標度上的這些參數開始重新進行。

wstart <- as.list(exp(unlist(weib3_start(dat$x)))) 
names(wstart) <- gsub("log","",names(wstart)) 
m2 <- mle2(x~dweib3(shape,sc,thres), 
      data=dat, 
      lower=c(shape=0.001,sc=0.001,thres=0.001), 
      upper=c(shape=Inf,sc=Inf, 
        thres=exp(tmin)), 
      start=wstart, 
      method="L-BFGS-B") 
vcov(m2) 
##    shape   sc  thres 
## shape 0.02312399 4.332057 -3.833264 
## sc  4.33205658 1035.743511 -888.770787 
## thres -3.83326390 -888.770787 824.633714 
all.equal(unname(coef(m2)),unname(exp(coef(m1))),tol=1e-4) 

與上述值大致相同。

如果我們更加小心地限定參數,我們可以適應一個小的形狀,但是現在我們最終在閾值的邊界上,這將導致方差計算的很多問題。

set.seed(1) 
dat <- data.frame(x = rweibull(1000, .53, 365) + 100) 
tmin <- log(0.99 * min(dat$x)) 
m1 <- mle2(x ~ dweib3(exp(logshape), exp(logsc), exp(logthres)), 
    lower=c(logshape=-10,logscale=0,logthres=0), 
    upper = c(logshape = 20, logsc = 20, logthres = tmin), 
    data = dat, 
    start = weib3_start(dat$x), method = "L-BFGS-B") 

截尾數據,你需要pweibull更換dweibull;有關提示,請參閱Errors running Maximum Likelihood Estimation on a three parameter Weibull cdf

+0

感謝您的幫助。我已經瞭解如何在3p weibull情況下使用約束MLE解決閾值參數的最大化問題。獲取參數的置信區間也非常有幫助。不幸的是我需要估計的方差 - 協方差矩陣,因爲我也想爲3p weibull構建'Fisher Matrix Confidence Bounds'[http://reliawiki.org/index.php/The_Weibull_Distribution#Fisher_Matrix_Confidence_Bounds] 。 mle2是否有機會處理刪失的數據? – Tim91

+0

你真的幫了我很多。我試着計算正常範圍內的方差 - 協方差矩陣(這是我正在尋找的)來計算可靠性和時間的Fisher-Matrix-Confidence-Bounds,這在上面的鏈接中有描述。 我期待的是,計算的var-cov-matrix(從log-scale var-cov-matrix轉換而來)應該接近var-cov-matrix在我的問題上,因爲對於這個特定的參數選擇, 「fitdistr」軟件包起作用了。不幸的是,它不是。 一個突出的任務是對被審查的數據做同樣的事情。 – Tim91

+0

我想說的是,ml優化方法** bbmle :: mle2 **對於低於1的形狀參數不起作用,即使設置了short的約束。 'set.seed(1) DAT < - data.frame(X = rweibull(1000,0.53,365)+ 100) TMIN < - 日誌(0.99 *分鐘(DAT $ X)) M1 < (logshape),exp(logsc),exp(logthres)), data = dat, webr3_start(dat $ x), method =「L-BFGS-B」)' 優化錯誤(par = ... L-BFGS-B需要有限的'fn' – Tim91

1

另一個可能的解決方案是做貝葉斯推斷。在形狀和比例參數上使用比例先驗,並且在位置參數上使用統一的先驗,您可以按照以下方式輕鬆運行Metropolis-Hastings。根據log(形狀),log(比例)和log(y_min - location)的方式重新參數化可能是有意義的,因爲某些參數的後驗變得強烈傾斜,特別是對於位置參數。請注意,下面的輸出顯示了回變參數的後驗。

library(MCMCpack) 
logposterior <- function(par,y) { 
    gamma <- min(y) - exp(par[3]) 
    sum(dweibull(y-gamma,exp(par[1]),exp(par[2]),log=TRUE)) + par[3] 
} 
y <- rweibull(100,shape=.8,scale=10) + 1 
chain0 <- MCMCmetrop1R(logposterior, rep(0,3), y=y, V=.01*diag(3)) 
chain <- MCMCmetrop1R(logposterior, rep(0,3), y=y, V=var(chain0)) 
plot(exp(chain)) 
summary(exp(chain)) 

這將產生以下輸出

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
The Metropolis acceptance rate was 0.43717 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 

Iterations = 501:20500 
Thinning interval = 1 
Number of chains = 1 
Sample size per chain = 20000 

1. Empirical mean and standard deviation for each variable, 
    plus standard error of the mean: 

     Mean  SD Naive SE Time-series SE 
[1,] 0.81530 0.06767 0.0004785  0.001668 
[2,] 10.59015 1.39636 0.0098738  0.034495 
[3,] 0.04236 0.05642 0.0003990  0.001174 

2. Quantiles for each variable: 

      2.5%  25%  50%  75% 97.5% 
var1 0.6886083 0.768054 0.81236 0.8608 0.9498 
var2 8.0756210 9.637392 10.50210 11.4631 13.5353 
var3 0.0003397 0.007525 0.02221 0.0548 0.1939 

enter image description here