You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决MLE调用中出现的'Error in optim: non-finite finite-difference value [1]'错误

解决SuppDists中dPearson配合mle的数值优化错误

问题重现

运行以下最小可复现代码:

library(SuppDists)
library(stats4)

mle(function(x) -log(dPearson(x, N=21, rho=0.999)), 0.5)

触发错误:

Error in optim(start, f, method = method, hessian = TRUE, ...) :
non-finite finite-difference value [1]

将rho改为0.99时无错误,但尝试指定method = "L-BFGS-B", lower = 0.00001, upper = 0.99999时,出现新错误:

L-BFGS-B needs finite values of 'fn'

实际使用场景代码:

library(SuppDists)
library(stats4)

test_rMZ_2rDZ <- function(rMZ, nMZ, rDZ, nDZ) {
  # Run MLE
  H1_MZ_MLE = mle(function(x) -log(dPearson(x, N=nMZ, rho=rMZ)), 0.5)
  H1_DZ_MLE = mle(function(x) -log(dPearson(x, N=nDZ, rho=rDZ)), 0.5)
  
  H0_MLE = mle(function(x) -(log(dPearson(x, N=nMZ, rho=rMZ)) + log(dPearson(x/2, N=nDZ, rho=rDZ))), 0.5)
  
  # Extract log-likelihoods
  H0_logLik = logLik(H0_MLE)
  H1_logLik = logLik(H1_MZ_MLE) + logLik(H1_DZ_MLE)
  
  # Run likelihood ratio test 
  test_stat = 2 * (H1_logLik - H0_logLik)
  pchisq(test_stat, df = 1, lower.tail = FALSE)
}

test_rMZ_2rDZ(rMZ = 0.999, nMZ = 21, rDZ = 0.98, nDZ = 52)

错误原因

当rho接近1时,dPearson计算出的概率密度值可能趋近于0,导致log(dPearson)返回-Inf,取负号后变成Inf(非有限值),优化算法无法处理。即使添加参数上下限,优化过程中仍可能采样到使目标函数非有限的x值,触发L-BFGS-B的报错。

解决方案

1. 目标函数添加数值稳定性处理

在计算-log(dPearson)前,先检查dPearson的结果,若过小则替换为极小正数,避免log(0)的情况。

2. 选择更合理的初始值

当rho接近1时,Pearson相关系数的MLE应接近rho,将初始值设为rho附近而非固定0.5,减少优化过程中遇到极端值的概率。

3. 严格限制参数范围并使用鲁棒优化方法

指定L-BFGS-B方法,同时设置参数上下限为远离0和1的极小/极大值(如1e-6和1-1e-6),避免参数接近边界导致的数值奇异。

修改后的实际场景代码

library(SuppDists)
library(stats4)

test_rMZ_2rDZ <- function(rMZ, nMZ, rDZ, nDZ) {
  # 定义带数值稳定处理的负对数似然函数
  neg_log_lik <- function(x, N, rho) {
    dp <- dPearson(x, N = N, rho = rho)
    # 避免log(0),将极小值替换为1e-16
    dp <- ifelse(dp < 1e-16, 1e-16, dp)
    -log(dp)
  }
  
  # 定义H0的负对数似然函数
  neg_log_lik_H0 <- function(x, nMZ, rMZ, nDZ, rDZ) {
    dp_mz <- dPearson(x, N = nMZ, rho = rMZ)
    dp_dz <- dPearson(x/2, N = nDZ, rho = rDZ)
    dp_mz <- ifelse(dp_mz < 1e-16, 1e-16, dp_mz)
    dp_dz <- ifelse(dp_dz < 1e-16, 1e-16, dp_dz)
    -(log(dp_mz) + log(dp_dz))
  }
  
  # Run MLE,使用更合理的初始值和鲁棒优化方法
  H1_MZ_MLE <- mle(neg_log_lik, start = list(x = rMZ), 
                   method = "L-BFGS-B", lower = 1e-6, upper = 1 - 1e-6,
                   N = nMZ, rho = rMZ)
  H1_DZ_MLE <- mle(neg_log_lik, start = list(x = rDZ), 
                   method = "L-BFGS-B", lower = 1e-6, upper = 1 - 1e-6,
                   N = nDZ, rho = rDZ)
  
  H0_MLE <- mle(neg_log_lik_H0, start = list(x = (rMZ + rDZ)/2), 
                method = "L-BFGS-B", lower = 1e-6, upper = 2*(1 - 1e-6),
                nMZ = nMZ, rMZ = rMZ, nDZ = nDZ, rDZ = rDZ)
  
  # Extract log-likelihoods
  H0_logLik <- logLik(H0_MLE)
  H1_logLik <- logLik(H1_MZ_MLE) + logLik(H1_DZ_MLE)
  
  # Run likelihood ratio test 
  test_stat <- 2 * (H1_logLik - H0_logLik)
  pchisq(test_stat, df = 1, lower.tail = FALSE)
}

# 测试修改后的函数
test_rMZ_2rDZ(rMZ = 0.999, nMZ = 21, rDZ = 0.98, nDZ = 52)

说明

  • 数值稳定处理通过ifelse将极小的dPearson值替换为1e-16,确保log(dp)返回有限值。
  • 初始值设置为rho(或rho的均值),让优化起点更接近真实MLE,减少迭代过程中遇到极端值的概率。
  • H0的参数上限设为2*(1-1e-6),因为x/2需要小于1,所以x最大接近2。

内容的提问来源于stack exchange,提问作者Mohan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 14:39:54