Frage zu nls passt in R - warum ist das so eine seltsame Passform?
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
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:

Die Anpassung vergisst den konstanten Term, den y-Achsenabschnitt. Benötigt im Gegensatz zu anderen Modellierungsfunktionen nls
einen expliziten Abschnitt.
Unten passe ich lm
zum 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)