nls () в R: при оценке модели отсутствует значение или бесконечность - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь использовать 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 означает вчерашнее значение.

Я пытаюсь оценить y, используя y2, rh1 & 2 и ta1 & 2, по следующей модели:

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))

, но все равно получена та же ошибка.

1 Ответ

0 голосов
/ 22 ноября 2018

Здесь есть несколько проблем.

Прежде всего: ваши отстающие значения на самом деле не отстают.Посмотрите на 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), ]

Далее:

Отсутствует значение или бесконечность, возникающая при оценке модели

Означает, что это просто, и мои глаза сразу же фиксируют log s в вашем выражении.Мы все знаем, что взятие лога отрицательного числа не определено, как и лог 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() вызов сейчас, вы получите ошибку

Ошибка сходимости: первоначальное равенство нарушает ограничения

И причина очевидна, если вы посмотрите назначения, которые вы указываете для ограничений ваших коэффициентов.coef2 и coef3 имеют нижние ограничения, установленные на бесконечность!Это не имеет смысла.«Начальный номинал нарушает ограничения» обычно означает, что начальные значения не находятся в пределах ограничений, что, безусловно, имеет место в данном случае.Если мы изменим их на отрицательную бесконечность, все будет хорошо.

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)
...