r - MLE 在 R 中使用 nlminb - 理解/调试某些错误
问题描述
这是我在这里的第一个问题,所以我会尽量写得好。如果我犯了一个愚蠢的错误,请霸道。
简而言之,我正在尝试进行最大似然估计,我需要估计 5 个参数。我想解决的问题的一般形式如下:三个copula的加权平均值,每个copula都有一个要估计的参数,其中权重是非负的并且总和为1,也需要估计。
R 中有一些包用于对单个 copula 或具有固定权重的 copula 的加权平均值进行 MLE。但是,据我所知,没有任何软件包可以直接解决我上面概述的问题。因此,我正在尝试自己编写问题代码。有一种特殊类型的错误我无法追踪其来源。下面我试图给出一个最小的可重现示例,其中只需要估计一个参数。
library(copula)
set.seed(150)
x <- rCopula(100, claytonCopula(250))
# Copula density
clayton_density <- function(x, theta){
dCopula(x, claytonCopula(theta))
}
# Negative log-likelihood function
nll.clayton <- function(theta){
theta_trans <- -1 + exp(theta) # admissible theta values for Clayton copula
nll <- -sum(log(clayton_density(x, theta_trans)))
return(nll)
}
# Initial guess for optimization
guess <- function(x){
init <- rep(NA, 1)
tau.n <- cor(x[,1], x[,2], method = "kendall")
# Guess using method of moments
itau <- iTau(claytonCopula(), tau = tau.n)
# In case itau is negative, we need a conditional statement
# Use log because it is (almost) inverse of theta transformation above
if (itau <= 0) {
init[1] <- log(0.1) # Ensures positive initial guess
}
else {
init[1] <- log(itau)
}
}
estimate <- nlminb(guess(x), nll.clayton)
(parameter <- -1 + exp(estimate$par)) # Retrieve estimated parameter
fitCopula(claytonCopula(), x) # Compare with fitCopula function
这在模拟具有较小 copula 参数值的数据时效果很好,并且每次都给出与 fitCopula() 几乎完全相同的答案。
对于较大的 copula 参数值,例如 250,当我使用 nlminb() 运行该行时会显示以下错误:"Error in .local(u, copula, log, ...) : parameter is NA Called from: .local(u, copula, log, ...) 总结时出错:'eval' 中未实现的类型 (29)"
当我运行 fitCopula() 时,优化已完成,但会弹出此消息:“警告消息:在 dlogcdtheta(copula, u) 中:dlogcdtheta() 在第 1 列中为此显式 copula 返回了 NaN;回退到数字这些列的导数"
我已经能够使用 debug() 发现在 nlminb 的优化过程中的某个地方,感兴趣的参数被分配了值 NaN,然后在调用 dCopula() 时会产生此错误。但是,我不知道它发生在哪个迭代中,以及当它发生时 nlminb() 正在做什么。我怀疑也许在某些迭代中,目标函数在 Inf/-Inf 处进行评估,但我不知道 nlminb() 接下来会做什么。此外,fitCopula() 似乎也发生了类似的事情,但优化仍然进行到最后,只有上述警告。
在理解正在发生的事情、我如何自己调试它和/或我如何处理这个问题方面,我真的很感激任何帮助。从问题中可以看出,我没有很强的编码背景。非常感谢任何花时间考虑这个问题的人。
更新:
当我运行dCopula(x, claytonCopula(-1+exp(guess(x))))
或等效clayton_density(x, -1+exp(guess(x)))
时,很明显密度在几个数据点处评估为 0。不幸的是,通过使用创建伪x <- pobs(x)
观察并不能解决问题,这可以通过重复看到dCopula(x, claytonCopula(-1+exp(guess(x))))
。结果是,当应用对数函数时,我们得到了几个 -Inf 评估,这当然意味着整个负对数似然函数评估为 Inf,如运行所示nll.clayton(guess(x))
。因此,除了上述查询之外,欢迎和赞赏在进行数字 MLE 时处理 log(0) 的任何提示。
第二次更新 如下编辑 nll.clayton 中的第二行似乎可以正常工作:
nll <- -sum(log(clayton_density(x, theta_trans) + 1e-8))
但是,我不知道这是否是规避问题的“好”方法,因为它不会引入潜在的大错误(尽管如果这样做会让我感到惊讶)。
解决方案
推荐阅读
- ruby-on-rails - 覆盖 has_many getter
- c++ - 创建文件夹结构
- r - 如何检查向量是否是斐波那契数列
- javascript - 如何在我的日历中写下所选日期的文本?
- c++ - 数组大小超过函数大小 (C++)
- javascript - 有没有办法压缩以下正则表达式替换?(javascript)
- java - 使用 Graphics2D#drawString 后如何正确存储坐标?
- python - 如果文件已经存在并且只从 json 追加新条目,如何查看文件?
- c++ - 在 switch case 中读取 .txt 文件
- flutter - 如何解决问题:使用 Bloc 时“已关闭的 Dismissible 小部件仍然是树的一部分”