繁体   English   中英

R中的nls():评估模型时产生的缺失值或无穷大

[英]nls() in R: Missing value or an infinity produced when evaluating the model

我正在尝试使用nls(),但问题中的错误已经完成。

以下是与原始数据集类似的示例数据集:

rh1 = rnorm(301, 0.75, 0.1)
rh1[rh1 > 1] = 1
ta1 = rnorm(301, 302, 3)
y1 = rnorm(301, 0.2, 0.05)

df_test = data.frame(rh1 = rh1,
                 rh2 = c(NA, rh1[-c(1)]),
                 ta1 = ta1,
                 ta2 = c(NA, ta1[-c(1)]),
                 y1 = y1,
                 y2 = c(NA, y1[-c(1)]))
df_test = df_test[-c(1), ] # this function cannot estimate for the first value

其中rh是空气的相对湿度,ta是K中的空气温度,y是物体的水分含量。 1意味着今天的价值; 2表示昨天的价值。

我试图通过下面的模型使用y2,rh1&2和ta1&2来估计y:

nls(y1 ~
  coef1 ^ 2 * y2 +
  coef1 * (1 - coef1) * 
  (coef2 + coef3 * log(-8.3 * ta2 * log(rh2) / 18)) +
  (1 - coef1) * 
  (coef2 + coef3 * log(-8.3 * ta1 * log(rh1) / 18)),
data = df_test,
algorithm = "port",
start = list(coef1 = 0.7,
             coef2 = 0.15,
             coef3 = 0),
upper = c(exp(-0.00005), Inf, Inf),
lower = c(exp(-0.5), Inf, Inf))

Coef1,2和3是要估计的参数。

通过手动计算第一行数据确定初始值。

但是这个脚本在标题中出现了错误。

评估模型时产生的缺失值或无穷大

我也尝试使用minpack.lm :: nlsLM()函数根据以下链接:

nls麻烦:评估模型时产生的缺失值或无穷大

library(minpack.lm)
nlsLM(y1 ~
    coef1 ^ 2 * y2 +
    coef1 * (1 - coef1) * 
    (coef2 + coef3 * log(-8.3 * ta2 * log(rh2) / 18)) +
    (1 - coef1) * 
    (coef2 + coef3 * log(-8.3 * ta1 * log(rh1) / 18)),
  data = df_test,
  start = list(coef1 = 0.7,
               coef2 = 0.15,
               coef3 = 0),
  upper = c(exp(-0.00005), Inf, Inf),
  lower = c(exp(-0.5), Inf, Inf))

但仍然有同样的错误。

这里有几个问题。

首先:你的滞后值并没有真正滞后。 看看df_test ,你会发现12是相同的。
这将为您提供滞后值:

set.seed(1)

rh1 <- rnorm(301, 0.75, 0.1)
rh1[rh1 > 1] <- 1
ta1 <- rnorm(301, 302, 3)
y1 <- rnorm(301, 0.2, 0.05)

df_test <- data.frame(
  rh1 = rh1,
  rh2 = c(NA, head(rh1, -1)),
  ta1 = ta1,
  ta2 = c(NA, head(ta1, -1)),
   y1 = y1,
   y2 = c(NA, head(y1, -1))
)
df_test <- df_test[complete.cases(df_test), ]

下一个:

评估模型时产生的缺失值或无穷大

意思就是这样,我的眼睛立即修复你表情中的log 我们都知道取一个负数的对数是未定义的,因为0的对数,虽然它通常返回为无穷大。

我们来看看那些表达式

ex1 <- with(df_test, log(-8.2 * ta2 * log(rh2) / 18))
ex2 <- with(df_test, log(-8.3 * ta1 * log(rh1) / 18))

如果你看ex1ex2你会发现它们都包含-Inf 现在有你的罪魁祸首。 但是我们如何解决这个问题呢? 让我们看看数据中的哪些行会产生这种情况。

df_test[which(is.infinite(ex1 + ex2)),]
#        rh1     rh2      ta1      ta2      y1      y2
# 274 1.0000 0.66481 304.5453 300.5972 0.20930 0.17474
# 275 0.7656 1.00000 304.9603 304.5453 0.20882 0.20930

有趣的是,它们彼此相邻,它们都包含1 什么是log(1) 如果你将它乘以某个东西并记录产品,会发生什么?

让我们确保rh1rh2始终小于1

set.seed(1)

rh1 <- rnorm(301, 0.75, 0.1)
rh1[rh1 > 0.99] <- 0.99
ta1 <- rnorm(301, 302, 3)
y1 <- rnorm(301, 0.2, 0.05)

df_test <- data.frame(
  rh1 = rh1,
  rh2 = c(NA, head(rh1, -1)),
  ta1 = ta1,
  ta2 = c(NA, head(ta1, -1)),
   y1 = y1,
   y2 = c(NA, head(y1, -1))
)
df_test <- df_test[complete.cases(df_test), ]

但我们还没有完成。 如果您现在运行nls()调用,您将收到错误

收敛失败:初始标准违反限制

如果查看为系数约束指定的值,则原因很明显。 coef2coef3约束设置为无穷大! 这没有意义。 “初始par违反约束”通常意味着起始值不在约束范围内,这绝对是这里的情况。 如果我们将它们改为负无穷大,一切正常。

nls(y1 ~
  coef1 ^ 2 * y2 +
  coef1 * (1 - coef1) * 
  (coef2 + coef3 * log(-8.3 * ta2 * log(rh2) / 18)) +
  (1 - coef1) * 
  (coef2 + coef3 * log(-8.3 * ta1 * log(rh1) / 18)),
  data = df_test,
  algorithm = "port",
  start = list(coef1 = 0.7,
               coef2 = 0.15,
               coef3 = 0),
  upper = c(exp(-0.00005), Inf, Inf),
  lower = c(exp(-0.5), -Inf, -Inf)
)
# Nonlinear regression model
#    model: y1 ~ coef1^2 * y2 + coef1 * (1 - coef1) * (coef2 + coef3 * log(…
#    data: df_test
#   coef1   coef2   coef3 
#  0.6065  0.2569 -0.0170 
#  residual sum-of-squares: 1.058

# Algorithm "port", convergence message: 
#   both X-convergence and relative convergence (5)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM