nls fit in R에 대한 질문-이것이 왜 그렇게 이상하게 맞습니까?
Nov 23 2020
몇 가지 간단한 데이터 (연도 별 옥수수 생산량)에 비선형 피팅을 수행하려고합니다. R의 lm으로 할 수있을만큼 간단하지만, 허용되는 곡선이 있다면 일부 데이터가 더 잘 맞을 것입니다.
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가 트렌드를 제거하는 것과 같습니다. 어떤 도움이라도 좋을 것입니다.
답변
3 Duck Nov 23 2020 at 22:51
두 가지 옵션. @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 RuiBarradas Nov 23 2020 at 22:41
적합은 상수 항인 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)