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

带(x-location)/scale>0约束的MLE优化:L-BFGS-B报错求解

Fixing "L-BFGS-B needs finite values of 'fn'" Error in Pearson III MLE with Constraints

Let's break down why you're hitting this error and fix it step by step.

The Root Cause

Your initial parameter c(100, 1000, 10) violates the critical constraint (x - location)/scale > 0:

  • Your generated x values come from a Pearson III distribution with location=6 and positive scale=7, so all x are slightly larger than 6.
  • With location=1000 and positive scale=10, x - location is negative for every data point. This makes ssgn*(x-location) negative, and dgamma() returns NaN when given negative inputs.
  • Taking log(NaN) gives NaN, so your negative log-likelihood (tmp) becomes NaN, which your code converts to +Inf. L-BFGS-B can't handle non-finite function values, hence the error.

Step-by-Step Fixes

1. Guard Against Invalid Parameters in the Log-Likelihood Function

Modify your LL3 function to check constraints before computing the density. If parameters violate the constraint, return a large finite value (instead of Inf) to guide the optimizer away from bad regions:

LL3 <- function(theta, x, display) {
  shape <- as.numeric(theta[1])
  location <- as.numeric(theta[2])
  scale <- as.numeric(theta[3])
  
  # Check shape is positive (required for gamma distribution)
  if (shape <= 1e-6) {
    return(1e10)
  }
  
  # Enforce (x - location)/scale > 0 for all x
  if (scale > 0) {
    # All x must be > location → location < min(x)
    if (location >= min(x)) {
      return(1e10)
    }
  } else if (scale < 0) {
    # All x must be < location → location > max(x)
    if (location <= max(x)) {
      return(1e10)
    }
  } else {
    # Scale can't be zero
    return(1e10)
  }
  
  # Compute negative log-likelihood only if parameters are valid
  dens_vals <- dpearson3(x, shape, location, scale, log = FALSE)
  tmp <- -sum(log(dens_vals))
  
  # Fallback for any unexpected NaNs
  tmp <- ifelse(is.na(tmp), 1e10, tmp)
  
  if(display == 1){print(c(tmp, theta))}
  return(tmp)
}

Note: I removed the redundant sum(tmp) since tmp is already a sum of log densities.

2. Tighten Parameter Bounds for L-BFGS-B

Since your data was generated with a positive scale, we can restrict the optimizer to only consider positive scales and valid locations. This reduces the chance of it wandering into invalid regions:

x_min <- min(x)
x_max <- max(x)

# Set bounds: shape > 0, location < min(x), scale > 0
lower <- c(1e-6, -Inf, 1e-6)
upper <- c(Inf, x_min - 1e-6, Inf)

3. Use a Reasonable Initial Parameter

Your original starting point was way outside the valid region. Pick initial values that satisfy the constraint:

# Start with values close to the true parameters (or at least valid)
param <- c(5, 5, 5)

4. Run the Optimizer

Now your optim call should work without errors:

control.list <- list(maxit = 100000, factr=1e-12, fnscale = 1)
fit <- optim(par = param, fn = LL3, hessian = TRUE, method = "L-BFGS-B", 
             lower = lower, upper = upper, control = control.list, x = x, display = 1)

# Check the results
fit$par

You should get estimates close to the true values shape=5, location=6, scale=7.

Why This Works

  • The pre-checks in LL3 prevent the optimizer from ever computing non-finite values.
  • Tighter bounds guide L-BFGS-B to focus only on valid parameter space.
  • A valid initial start ensures the optimizer begins in a region where the log-likelihood is finite.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:52:36