R 中的 Optim() 函数
Optim() function in R
我正在尝试使用 R 的 optim() 函数优化具有边界的函数的参数。这是函数:Function, because mathjax does not work
下面的代码片段是我对其 Log-Likelihood 函数的实现,即 here
likelihood_levy <- function(params, x){
mu <- params[1]
sigma <- params[2]
n <- length(x)
ans <- ((1.5 * n) * log(sigma)) +
sum(log(1 / (x - mu))) -
(n * log(sqrt(2*pi) * sigma)) -
(0.5 * sigma * sum(1 / (x - mu)))
}
return(ans)
}
optim(c(-10, 2), likelihood_levy, x = sample1, method="L-BFGS-B",
lower = c(min(sample1) - 0.001, 0))
如何将参数范围添加到函数定义中?例如第一个参数必须小于x,第二个不能小于0。
注意:如果我使用 optim() 函数的“L-BFGS-B”方法,我会收到一条错误消息“L-BFGS-B 需要 'fn' 的有限值”
这个问题的任何解决方案都会很棒!
谢谢!
问题是函数 likelihood_levy
返回的值大于 .Machine$double.xmax
或在函数内发生被零除。这一行可能是罪魁祸首:
sum(log(1 / (x - mu)))
如果 x
等于或非常接近 mu
,就会出现问题。您可以添加一些防御代码来检查这一点。然而:
the first parameter must be lower than x
我认为 optim
没有办法做到这一点
存在多个问题:
- 在 return 语句之前有一个无关的右大括号。
- 即使 lower 确保 x - mu 为正,我们在计算数值梯度时仍然会遇到问题,因此请使用无导数方法(我们在下面这样做)或提供梯度函数来优化。
- optim 计算最小值,但我们想要最大似然,而不是最小似然。告诉 optim 最大化(我们在下面做)或使用负对数似然而不是对数似然。
- 起始值应该是可行的,即它应该可以计算对数似然并产生一个有限值,同时满足 mu < min(x) 的约束。
- 我们需要处理 mu < min(x) 不成立的情况。
- sample1 丢失,所以我们无法重现问题中的问题。
解决所有这些问题
likelihood_levy <- function(params, x){
mu <- params[1]
sigma <- params[2]
n <- length(x)
ans <- if (mu >= min(x)) -Inf
else ((1.5 * n) * log(sigma)) +
sum(log(1 / (x - mu))) -
(n * log(sqrt(2*pi) * sigma)) -
(0.5 * sigma * sum(1 / (x - mu)))
return(ans)
}
set.seed(123)
sample1 <- rnorm(25)
st <- c(min(sample1) - 0.001, 1)
res <- optim(st, likelihood_levy, x = sample1, control = list(fnscale = -1))
str(res)
给予
List of 5
$ par : num [1:2] -2.25 1.61
$ value : num -46.6
$ counts : Named int [1:2] 45 NA
..- attr(*, "names")= chr [1:2] "function" "gradient"
$ convergence: int 0
$ message : NULL
我正在尝试使用 R 的 optim() 函数优化具有边界的函数的参数。这是函数:Function, because mathjax does not work 下面的代码片段是我对其 Log-Likelihood 函数的实现,即 here
likelihood_levy <- function(params, x){
mu <- params[1]
sigma <- params[2]
n <- length(x)
ans <- ((1.5 * n) * log(sigma)) +
sum(log(1 / (x - mu))) -
(n * log(sqrt(2*pi) * sigma)) -
(0.5 * sigma * sum(1 / (x - mu)))
}
return(ans)
}
optim(c(-10, 2), likelihood_levy, x = sample1, method="L-BFGS-B",
lower = c(min(sample1) - 0.001, 0))
如何将参数范围添加到函数定义中?例如第一个参数必须小于x,第二个不能小于0。
注意:如果我使用 optim() 函数的“L-BFGS-B”方法,我会收到一条错误消息“L-BFGS-B 需要 'fn' 的有限值” 这个问题的任何解决方案都会很棒!
谢谢!
问题是函数 likelihood_levy
返回的值大于 .Machine$double.xmax
或在函数内发生被零除。这一行可能是罪魁祸首:
sum(log(1 / (x - mu)))
如果 x
等于或非常接近 mu
,就会出现问题。您可以添加一些防御代码来检查这一点。然而:
the first parameter must be lower than x
我认为 optim
存在多个问题:
- 在 return 语句之前有一个无关的右大括号。
- 即使 lower 确保 x - mu 为正,我们在计算数值梯度时仍然会遇到问题,因此请使用无导数方法(我们在下面这样做)或提供梯度函数来优化。
- optim 计算最小值,但我们想要最大似然,而不是最小似然。告诉 optim 最大化(我们在下面做)或使用负对数似然而不是对数似然。
- 起始值应该是可行的,即它应该可以计算对数似然并产生一个有限值,同时满足 mu < min(x) 的约束。
- 我们需要处理 mu < min(x) 不成立的情况。
- sample1 丢失,所以我们无法重现问题中的问题。
解决所有这些问题
likelihood_levy <- function(params, x){
mu <- params[1]
sigma <- params[2]
n <- length(x)
ans <- if (mu >= min(x)) -Inf
else ((1.5 * n) * log(sigma)) +
sum(log(1 / (x - mu))) -
(n * log(sqrt(2*pi) * sigma)) -
(0.5 * sigma * sum(1 / (x - mu)))
return(ans)
}
set.seed(123)
sample1 <- rnorm(25)
st <- c(min(sample1) - 0.001, 1)
res <- optim(st, likelihood_levy, x = sample1, control = list(fnscale = -1))
str(res)
给予
List of 5
$ par : num [1:2] -2.25 1.61
$ value : num -46.6
$ counts : Named int [1:2] 45 NA
..- attr(*, "names")= chr [1:2] "function" "gradient"
$ convergence: int 0
$ message : NULL