最初に、コードのどこが間違っているかを指摘します。
する必要はありdunif
ませんrunif
。以下を定義できます。
LL <- function (a, b) -sum(dunif(x, a, b, log.p = TRUE))
dunif
以下のコードでは、密度がちょうどいい1 / (b - a)
ので、直接書いたので、使用しませんでした。
- 目的関数内でサンプルを生成しています。
U[a,b]
これは、密度が自由であるため、問題ありませんx
。しかし、他の分布では、反復ごとに目的関数が変化します。
method = "L-BFGS-B"
ボックス制約では、通常の ではなくが必要です"BFGS"
。また、適切な制約を使用していません。
では、さらに深く...
からの長n
さサンプル ベクトルの場合、尤度はであり、負の対数尤度はです。明らかに、MLE はとです。x
U[a, b]
(b - a) ^ (-n)
n * log(b - a)
a = min(x)
b = max(x)
数値最適化はまったく不要であり、実際には制約なしでは不可能です。勾配ベクトルを見てください。
( n / (a - b), n / (b - a) )
偏導関数 wrt a
/b
は常に負 / 正であり、0 にはなりません。
ボックス制約を課すと、数値的アプローチが実現可能になり-Inf < a <= min(x)
ますmax(x) <= b < Inf
。反復が境界で終了することは確かです。
以下の私のコードでは、 と の両方optim
を使用していmle
ます。mle
ヘッセ行列を反転すると、特異であるため、注意してください。
-(b - a) ^ 2 (b - a) ^ 2
(b - a) ^ 2 -(b - a) ^ 2
コード:
## 100 samples
set.seed(20161208); x <- runif(100, 1, 3)
# range(x)
# [1] 1.026776 2.984544
## using `optim`
nll <- function (par) log(par[2] - par[1]) ## objective function
gr_nll <- function (par) c(-1, 1) / diff(par) ## gradient function
optim(par = c(0,4), fn = nll, gr = gr_nll, method = "L-BFGS-B",
lower = c(-Inf, max(x)), upper = c(min(x), Inf), hessian = TRUE)
#$par
#[1] 1.026776 2.984544 ## <- reaches boundary!
#
# ...
#
#$hessian ## <- indeed singular!!
# [,1] [,2]
#[1,] -0.2609022 0.2609022
#[2,] 0.2609022 -0.2609022
## using `stats4::mle`
library(stats4)
nll. <- function (a, b) log(b - a)
mle(minuslogl = nll., start = list(a = 0, b = 4), method = "L-BFGS-B",
lower = c(-Inf, max(x)), upper = c(min(x), Inf))
#Error in solve.default(oout$hessian) :
# Lapack routine dgesv: system is exactly singular: U[2,2] = 0