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

R中Nelder-Mead优化(fminbnd)报错问题求助

优化二元选择Softmax似然函数时的missing value where TRUE/FALSE needed错误解决

报错详情

运行neldermead包的fminbnd优化自定义似然函数时,触发以下错误:

Error in if (fr < fhigh) { : missing value where TRUE/FALSE needed

开启verbose模式后,报错前的关键输出:

Step #1 : order 
================================================================= 
Iteration #1 (total = 1) 
Function Eval #2 
Xopt: [0.04] 
Fopt: 1.100429e+02 
DeltaFv: Inf 
Center: [2.85944413880818] 
Size: 5.638888e+00 
Vertex #1/2 : fv=1.100429e+02, x=4.000000e-02
 
Vertex #2/2 : fv=Inf, x=5.678888e+00
 
Reflect 
xbar=[0.04] 
boxlinesearch 
> xhigh=[5.67888827761635], fhigh=Inf 
> xbar=[0.04] 
> xr = [-7.29055476090126] 
Function Evaluation #3 at [-7.29055476090126  ] 

自定义优化函数

目标函数基于二元选择试验计算似然值,用于拟合Softmax决策策略:

softmaxEV <- function(startphi){
  pL <- c()
  for (row in 1:nrow(oneDat)){
    VA= oneDat[row, "EVA"]
    VB= oneDat[row, "EVB"]
    
    if (oneDat[row, "response"] == 0){
      p= exp(startphi*VA)/(exp(startphi*VA)+exp(startphi*VB))
      pL <-append(pL,p)
    }
    else {
      p= 1- (exp(startphi*VA)/(exp(startphi*VA)+exp(startphi*VB)))
      pL <-append(pL,p)
    }
  }
  gEV <- -2*sum(log(pL))
  return(gEV)
}

优化调用代码

函数嵌入参与者遍历循环中,设置参数范围为0到10:

optRes <- fminbnd(softmaxEV, startphi,0,10, verbose= TRUE)

已尝试的无效方案

  • 移除边界改用fminsearch
  • 调整边界范围
  • 切换到pracma包的fminbnd
  • 转至Python使用minimize函数
  • 手动测试多个startphi值(未触发报错)

问题根源

  1. 数值溢出/下溢:当优化算法生成的startphi值过大(如5.67)或超出边界(如-7.29)时,exp(startphi*VA)或exp(startphi*VB)可能溢出到Inf或下溢到0,导致:
    • Inf/Inf得到NaN,使得p为NaN
    • log(0)得到-Inf,累加后导致gEV为Inf或NaN
  2. 参数越界:优化算法可能跳出设定的[0,10]范围,进入无意义的参数区间,触发无效计算。
  3. 循环效率问题:逐行循环拼接向量容易引入隐性错误,且数值稳定性差。

解决方法

1. 稳定Softmax计算(避免数值溢出)

使用log-sum-exp技巧重新实现似然计算,避免直接计算大指数:

softmaxEV_stable <- function(startphi){
  # 向量化计算,替代循环
  VA <- oneDat$EVA
  VB <- oneDat$EVB
  response <- oneDat$response
  
  # 计算稳定的log(softmax)
  max_val <- pmax(startphi*VA, startphi*VB)
  log_denom <- max_val + log(exp(startphi*VA - max_val) + exp(startphi*VB - max_val))
  log_pA <- startphi*VA - log_denom
  
  # 根据response计算log似然
  log_pL <- ifelse(response == 0, log_pA, log(1 - exp(log_pA)))
  
  # 处理极端情况(如log_pA为-Inf时,1-exp(log_pA)=1,log(1)=0)
  log_pL <- ifelse(is.infinite(log_pA) & response == 1, 0, log_pL)
  
  gEV <- -2*sum(log_pL, na.rm = TRUE)
  return(gEV)
}

2. 限制参数范围

在函数开头添加参数检查,对超出[0,10]的参数返回极大惩罚值,避免无效计算:

softmaxEV_stable <- function(startphi){
  # 参数越界惩罚
  if (startphi < 0 || startphi > 10) {
    return(1e10)
  }
  
  # 后续稳定计算代码...
}

3. 优化算法选择

使用支持边界约束的优化函数,如stats::optim(method="L-BFGS-B"),确保参数不会越界:

optRes <- optim(par = startphi, fn = softmaxEV_stable, 
                method = "L-BFGS-B", lower = 0, upper = 10)

验证

替换函数后重新运行优化,即可避免Inf/NaN导致的条件判断错误,同时提升计算效率和稳定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:07:07