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是object的水分含量。 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是待估计的参数。
第一行数据的初始值是通过人工计算确定的。
但是这个脚本在标题中出现了错误。
Missing value or an infinity produced when evaluating the model
我也根据下面的 link 尝试使用 minpack.lm::nlsLM() 函数:
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
,您会发现 1
和 2
是相同的。
这将为您提供滞后值:
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), ]
下一个:
Missing value or an infinity produced when evaluating the model
就是那个意思,我的眼睛立刻就盯着你表情中的 log
。我们都知道取负数的对数是不确定的,0的对数也是未定义的,虽然它经常返回为无穷大。
让我们看看那些表达式
ex1 <- with(df_test, log(-8.2 * ta2 * log(rh2) / 18))
ex2 <- with(df_test, log(-8.3 * ta1 * log(rh1) / 18))
如果您查看 ex1
和 ex2
,您会发现两者都包含一个 -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)
是什么?如果将它乘以某项并取乘积的对数会怎样?
让我们确保 rh1
和 rh2
始终小于 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()
调用你会得到错误
Convergence failure: initial par violates constraints
如果您查看为系数约束指定的值,原因就很明显了。 coef2
和 coef3
的下限约束设置为无穷大!那没有意义。 "initial par violates constraints" 通常意味着起始值不在约束范围内,这里确实是这种情况。如果我们将它们更改为负无穷大,一切正常。
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)
我正在尝试使用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是object的水分含量。 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是待估计的参数。
第一行数据的初始值是通过人工计算确定的。
但是这个脚本在标题中出现了错误。
Missing value or an infinity produced when evaluating the model
我也根据下面的 link 尝试使用 minpack.lm::nlsLM() 函数:
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
,您会发现 1
和 2
是相同的。
这将为您提供滞后值:
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), ]
下一个:
Missing value or an infinity produced when evaluating the model
就是那个意思,我的眼睛立刻就盯着你表情中的 log
。我们都知道取负数的对数是不确定的,0的对数也是未定义的,虽然它经常返回为无穷大。
让我们看看那些表达式
ex1 <- with(df_test, log(-8.2 * ta2 * log(rh2) / 18))
ex2 <- with(df_test, log(-8.3 * ta1 * log(rh1) / 18))
如果您查看 ex1
和 ex2
,您会发现两者都包含一个 -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)
是什么?如果将它乘以某项并取乘积的对数会怎样?
让我们确保 rh1
和 rh2
始终小于 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()
调用你会得到错误
Convergence failure: initial par violates constraints
如果您查看为系数约束指定的值,原因就很明显了。 coef2
和 coef3
的下限约束设置为无穷大!那没有意义。 "initial par violates constraints" 通常意味着起始值不在约束范围内,这里确实是这种情况。如果我们将它们更改为负无穷大,一切正常。
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)