Вопрос о соответствии nls в R — почему это такое странное соответствие?

#r #non-linear-regression #nls

#r #нелинейная регрессия #nls

Вопрос:

Я пытаюсь выполнить нелинейную подгонку к некоторым простым данным (урожайность кукурузы по годам). Достаточно просто сделать это с lm в R, но некоторые данные соответствовали бы лучше, если бы была разрешена кривая, что-то порядка года ^ 1,5 или около того.

 x <- c(1979L, 1980L, 1981L, 1982L, 1983L, 1984L, 1985L, 1986L, 1987L, 
1988L, 1989L, 1990L, 1991L, 1992L, 1993L, 1994L, 1995L, 1996L, 
1997L, 1998L, 1999L, 2000L, 2001L, 2002L, 2003L, 2004L, 2005L, 
2006L, 2007L, 2008L, 2009L, 2010L, 2011L, 2012L, 2013L, 2015L, 
2016L, 2017L, 2018L, 2019L)

y <- c(47.3, 25.4, 39, 56.4, 41.4, 56.1, 60.3, 58, 64, 35, 56, 54, 
37, 80, 59, 88, 55, 87, 90, 99, 93, 90.4, 80.7, 35, 80.2, 104.9, 
59.9, 43.5, 97.9, 106, 132, 121.7, 120.1, 63.9, 142.5, 129.9, 
114.8, 122.1, 164.3, 133.9)

yield_model <- nls(y ~ x^a,start=list(a = 1))

plot(x,y)
lines(x,predict(yield_model),lty=2,col="red",lwd=3)

> yield_model2
Nonlinear regression model
 model: y ~ x^a
 data: parent.frame()
 a 
0.5778 
residual sum-of-squares: 46984

Number of iterations to convergence: 8 
Achieved convergence tolerance: 7.566e-09
 

Почему nls так плохо подходит (видно, если вы его нанесете)? Я сделал что-то не так? Вы можете себе представить, что небольшая кривая в соответствии с данными была бы лучше, наряду с тенденцией. Похоже, что nls удалил тренд или что-то в этом роде. Любая помощь была бы отличной.

Ответ №1:

Два варианта. Как упоминалось @RuiBarradas, проблема заключается в спецификации модели. Вы можете установить свои начальные значения, используя lm() примерно следующее:

 #Define initial values
mod <- lm(y~x)
#nls model
yield_model <- nls(y ~ a x^b,
                   start=list(a = mod$coefficients[1],b=mod$coefficients[2]))
#Plot
plot(x,y)
lines(x,predict(yield_model),lty=2,col="red",lwd=3)
 

Вывод:

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

Или попробуйте другой подход, например loess :

 library(ggplot2)
#Data
df <- data.frame(x=x,y=y)
#Plot
ggplot(df,aes(x=x,y=y)) 
  geom_point() 
  stat_smooth(se=F)
 

Вывод:

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

Ответ №2:

Подгонка — это забывание постоянного члена, y-перехвата. В отличие от других функций моделирования, nls требуется явный перехват.
Ниже я также использую линейную модель lm для сравнения.

 df1 <- data.frame(x, y)

yield_model <- nls(y ~ k   x^a, data = df1, start=list(k = 0, a = 1))
yield_model2 <- lm(y ~ x, df1)
summary(yield_model)
summary(yield_model2)

plot(x, y)
lines(x, predict(yield_model), lty = "dashed", col = "red", lwd = 3)
lines(x, predict(yield_model2), lty = "dotted", col = "blue", lwd = 3)
 

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

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

 predict(yield_model) - predict(yield_model2)