[英]R: Maximum Likelihood Estimation of a exponential mixture using optim
I'm trying to get the parameters w, lambda_1, lambda_2
and p
from a mixture bi-exponential model, using a loglikelihood function and the optim
function in R. The model is the following我正在尝试从混合双指数 model 中获取参数
w, lambda_1, lambda_2
和p
,使用对数似然 function 和 R 中的optim
function。model 如下
Here is the code这是代码
biexpLL <- function(theta, y) {
# define parameters
w <- theta[1]
lambda_1 <- theta[2]
a <- theta[3]
lambda_2 <- theta[4]
# likelihood function with dexp
l <- w * dexp((y - a), rate = 1/lambda_1) + (1 - w) * dexp((y - a), rate = 1/lambda_2)
- sum(log(l))
}
# Generate some fake data
w <- 0.7
n <- 500
lambda_1 <- 2
lambda_2 <- 0.2
set.seed(45)
biexp_data <- (w * rexp(n, 1/lambda_1) + (1 - w) * rexp(n, 1/lambda_2))
# Optimization
optim(par = c(0.5,0.1,0.001,0.2),
fn=biexpLL,
y=biexp_data)
#$par
#[1] -94789220.4 16582.9 -333331.7 134744336.2
The parameters are very different from the used in the fake data?这些参数与假数据中使用的参数有很大不同? What I'm doing wrong?
我做错了什么?
The original code is prone to warnings and errors since the parameters may go to invalid values easily.原始代码容易出现警告和错误,因为参数可能 go 容易变为无效值。 For example, we need
w in [0, 1]
and lambda > 0
.例如,我们需要
w in [0, 1]
和lambda > 0
。 Also, if a
is larger than a data point, then the density becomes zero, hence infinite log likelihood.此外,如果
a
大于数据点,则密度变为零,因此对数似然无限。
The code below uses some tricks to handle these cases.下面的代码使用一些技巧来处理这些情况。
w
is converted to the range [0, 1]
by the logistic function w
通过逻辑 function 转换为范围[0, 1]
lambda
are converted to positive values by the exponential function. lambda
通过指数 function 转换为正值。 Also, the data generation process has been changed so that samples are generated from one of the exponential distributions with the given probability w
.此外,数据生成过程已更改,以便从具有给定概率
w
的指数分布之一生成样本。
Finally, increased the sample size since the result was not stable with n=500
.最后,增加样本量,因为
n=500
的结果不稳定。
biexpLL <- function(theta, y) {
# define parameters
w <- 1/(1+exp(-theta[1]))
lambda_1 <- exp(theta[2])
a <- theta[3]
lambda_2 <- exp(theta[4])
# likelihood function with dexp
l <- w * dexp((y - a), rate = 1/lambda_1) + (1 - w) * dexp((y - a), rate = 1/lambda_2)
- sum(log(l + 1e-9))
}
# Generate some fake data
w <- 0.7
n <- 5000
lambda_1 <- 2
lambda_2 <- 0.2
set.seed(45)
n1 <- round(n*w)
n2 <- n - n1
biexp_data <- c(rexp(n1, rate=1/lambda_1),
rexp(n2, rate=1/lambda_2))
# Optimization
o <- optim(par=c(0.5,0.1,0.001,0.2),
fn=biexpLL,
y=biexp_data)
1/(1+exp(-o$par[1]))
exp(o$par[2])
o$par[3]
exp(o$par[4])
On my environment I obtained the below.在我的环境中,我获得了以下内容。
The result seems reasonably close to the simulation parameters (note that two lambda values are swapped).结果似乎与模拟参数相当接近(请注意,交换了两个 lambda 值)。
> 1/(1+exp(-o$par[1]))
[1] 0.3458264
> exp(o$par[2])
[1] 0.1877655
> o$par[3]
[1] 3.738172e-05
> exp(o$par[4])
[1] 2.231844
Notice that for mixture models of this kind, people often use the EM algorithm for optimizing the likelihood instead of the direct optimization as this.请注意,对于这种混合模型,人们经常使用 EM 算法来优化似然性,而不是像这样直接优化。 You may want to have a look at it as well.
您可能也想看看它。
I have been able to get the parameters with the R package DEoptim:我已经能够使用 R package DEoptim 获取参数:
library(DEoptim)
biexpLL <- function(theta, y)
{
w <- theta[1]
lambda_1 <- theta[2]
lambda_2 <- theta[3]
l <- w * dexp(y, rate = 1 / lambda_1) + (1 - w) * dexp(y, rate = 1 / lambda_2)
log_Lik <- -sum(log(l))
if(is.infinite(log_Lik))
{
return(10 ^ 30)
}else
{
return(log_Lik)
}
}
w <- 0.7
n <- 500
lambda_1 <- 2
lambda_2 <- 0.2
set.seed(45)
indicator <- rbinom(n = 500, size = 1, prob = w)
biexp_data <- (indicator * rexp(n, 1 / lambda_1) + (1 - indicator) * rexp(n, 1 / lambda_2))
obj_DEoptim <- DEoptim(fn = biexpLL, lower = c(0, 0, 0), upper = c(1, 1000, 1000), control = list(itermax = 1000, parallelType = 1), y = biexp_data)
obj_DEoptim$optim$bestmem
par1 par2 par3
0.7079678 2.2906098 0.2026040
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.