Frage zu nls passt in R - warum ist das so eine seltsame Passform?

Nov 23 2020

Ich versuche, einige einfache Daten (Maisertrag pro Jahr) nicht linear anzupassen. Es ist einfach genug, es mit lm in R zu tun, aber einige der Daten würden besser passen, wenn eine Kurve erlaubt wäre, etwas in der Größenordnung von Jahr ^ 1,5 oder so.

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

Warum passen die nls so schlecht (sichtbar, wenn Sie es zeichnen)? Habe ich etwas falsch gemacht? Sie können sich vorstellen, dass eine leichte Kurve bei der Anpassung an die Daten zusammen mit einem Trend besser wäre. Es ist, als hätte nls den Trend entfernt oder so. Jede Hilfe wäre großartig.

Antworten

3 Duck Nov 23 2020 at 22:51

Zwei Optionen. Wie von @RuiBarradas erwähnt, ist das Problem die Spezifikation des Modells. Sie können Ihre Startwerte folgendermaßen einstellen 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)

Ausgabe:

Oder versuchen Sie einen anderen Ansatz wie 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)

Ausgabe:

2 RuiBarradas Nov 23 2020 at 22:41

Die Anpassung vergisst den konstanten Term, den y-Achsenabschnitt. Benötigt im Gegensatz zu anderen Modellierungsfunktionen nlseinen expliziten Abschnitt.
Unten passe ich lmzum Vergleich auch ein lineares Modell an .

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)

Wie Sie sehen können, liegen die Passungen sehr nahe beieinander. Aber sie sind nicht gleich, um es laufen zu sehen:

predict(yield_model) - predict(yield_model2)