Как сделать модель экспоненциальной регрессии?

У меня есть небольшая база данных (текстовый файл).

Я хочу получить экспоненциальную регрессию в R.

Команды, которые я использую:

regression <- read.delim("C:/Users/david/OneDrive/Desktop/regression.txt")
View(regression)
source('~/.active-rstudio-document', echo=TRUE)
m <- nls(DelSqRho ~ (1-exp(-a*(d-b)**2)), data=regression, start=list(a=1, b=1))
y_est<-predict(m,regression$d)
plot(x,y)
lines(x,y_est)
summary(m)

Но при запуске получаю ошибку:

Error in nls(DelSqRho ~ (1 - exp(-a * (d - b)^2)), data = regression,  : 
  step factor 0.000488281 reduced below 'minFactor' of 0.000976562

и я не знаю, как это решить, как получить экспоненциальную регрессию, пожалуйста, подскажите?


person Another.Chemist    schedule 01.02.2021    source источник
comment
... В этом случае вы можете получить представление о начальных параметрах, подобрав start_m = lm(log(1/(1-DelSqRho)) ~ poly(d, 2, raw=TRUE), regression) (это переставленное уравнение вашей модели) и получив a = coef(start_m)[3] и b = sqrt(coef(start_m)[1]/coef(start_m)[3])   -  person user20650    schedule 02.02.2021
comment
@user20650 user20650 Спасибо за ваши ответы, но я не понял их должным образом, я попробовал start_m = lm(log(1/(1-DelSqRho)) ~ poly(d, 2, raw=TRUE), regression);;;;;; y_est<-predict(start_m,regression$DelSqRho) и получил Error in eval(predvars, data, env) : numeric 'envir' arg not of length one   -  person Another.Chemist    schedule 02.02.2021


Ответы (1)


nls очень чувствителен к значениям начальных параметров, поэтому вам нужно выбрать значения, которые дают разумное соответствие данным (minpack.lm::nlsLM может быть немного более щадящим).

Вы можете построить кривую при ваших начальных значениях a=1 и b=1 и увидеть, что она не очень хорошо справляется с захватом кривой.

regression <- read.delim("regression.txt")
with(regression, plot(d, DelSqRho, ylim=c(-3, 1)))
xs <- seq(min(regression$d), max(regression$d), length=100)
a <- 1; b <- 1; ys <- 1 - exp(-a* (xs - b)**2)
lines(xs, ys)

введите здесь описание изображения

Один из способов получить начальные значения — изменить целевую функцию. y = 1 - exp(-a*(x-b)**2) можно заменить на log(1/(1-y)) = ab^2 - 2abx + ax^2 (здесь y должно быть меньше единицы). Затем можно использовать линейную регрессию, чтобы получить оценку a и b.

start_m <- lm(log(1/(1-DelSqRho)) ~ poly(d, 2, raw=TRUE), regression)
unname(a <- coef(start_m)[3]) # as `a` is aligned with the quadratic term
# [1] -0.2345953 
unname(b <- sqrt(coef(start_m)[1]/coef(start_m)[3]))
# [1] 2.933345 

(Иногда невозможно переставить данные таким образом, и вы можете попытаться получить приблизительное представление о параметрах, построив кривые при различных начальных параметрах. nls2 также может выполнять поиск методом грубой силы или поиск по сетке по начальным параметрам.)

Теперь мы можем попытаться оценить модель nls при следующих параметрах:

m <- nls(DelSqRho ~ 1-exp(-a*(d-b)**2), data=regression, start=list(a=a, b=b))
coef(m)
#          a          b 
# -0.2379078  2.8868374 

И постройте результаты:

# note that `newdata` must be a named list or data frame 
# in which to look for variables with which to predict.
y_est <- predict(m, newdata=data.frame(d=xs))
with(regression, plot(d, DelSqRho))
lines(xs, y_est, col="red", lwd=2)

введите здесь описание изображения

Подгонка не идеальна и, возможно, наводит на мысль, что требуется более гибкая модель.

person user20650    schedule 02.02.2021
comment
Спасибо, все перепробовал, но последний блок команд не работает, подскажите мне Error in data.frame(d = xs) : object 'xs' not found - person Another.Chemist; 02.02.2021
comment
Другой.Химик ; xs определяется в первом кодовом блоке - person user20650; 02.02.2021