Подгонка полиномиальной модели к данным в R - PullRequest
80 голосов
/ 29 сентября 2010

Я прочитал ответы на этот вопрос , и они весьма полезны, но мне особенно нужна помощь в R.

У меня есть пример данных, установленных в R следующим образом:

x <- c(32,64,96,118,126,144,152.5,158)  
y <- c(99.5,104.8,108.5,100,86,64,35.3,15)

Я хочу подогнать модель под эти данные, чтобы y = f(x). Я хочу, чтобы это была полиномиальная модель 3-го порядка.

Как я могу сделать это в R?

Кроме того, может ли R помочь мне найти наиболее подходящую модель?

Ответы [ 4 ]

89 голосов
/ 29 сентября 2010

Чтобы получить полином третьего порядка по x (x ^ 3), вы можете сделать:

lm(y ~ x + I(x^2) + I(x^3))

или

lm(y ~ poly(x, 3, raw=TRUE))

Вы можете установить полином 10-го порядка и получитьидеально подходит, но вы должны?

РЕДАКТИРОВАТЬ: poly (x, 3), вероятно, лучший выбор (см. @hadley ниже).

40 голосов
/ 29 сентября 2010

Какая модель является «наиболее подходящей моделью», зависит от того, что вы подразумеваете под «лучшей».У R есть инструменты, чтобы помочь, но вам нужно дать определение «наилучшим», чтобы выбрать между ними.Рассмотрим следующий пример данных и кода:

x <- 1:10
y <- x + c(-0.5,0.5)

plot(x,y, xlim=c(0,11), ylim=c(-1,12))

fit1 <- lm( y~offset(x) -1 )
fit2 <- lm( y~x )
fit3 <- lm( y~poly(x,3) )
fit4 <- lm( y~poly(x,9) )
library(splines)
fit5 <- lm( y~ns(x, 3) )
fit6 <- lm( y~ns(x, 9) )

fit7 <- lm( y ~ x + cos(x*pi) )

xx <- seq(0,11, length.out=250)
lines(xx, predict(fit1, data.frame(x=xx)), col='blue')
lines(xx, predict(fit2, data.frame(x=xx)), col='green')
lines(xx, predict(fit3, data.frame(x=xx)), col='red')
lines(xx, predict(fit4, data.frame(x=xx)), col='purple')
lines(xx, predict(fit5, data.frame(x=xx)), col='orange')
lines(xx, predict(fit6, data.frame(x=xx)), col='grey')
lines(xx, predict(fit7, data.frame(x=xx)), col='black')

Какая из этих моделей лучше?аргументы могут быть приведены для любого из них (но я бы не хотел использовать фиолетовый для интерполяции).

14 голосов
/ 29 сентября 2010

Относительно вопроса «Может ли R помочь мне найти наилучшую подходящую модель?», Вероятно, есть функция для этого, при условии, что вы можете указать набор моделей для тестирования, но это будет хорошим первым подходом для набораполиномы n-1 градусов:

polyfit <- function(i) x <- AIC(lm(y~poly(x,i)))
as.integer(optimize(polyfit,interval = c(1,length(x)-1))$minimum)

Примечания

  • Обоснованность этого подхода будет зависеть от ваших целей, предположений optimize() и AIC() иесли AIC является критерием, который вы хотите использовать,

  • polyfit() может не иметь единственного минимума.проверьте это следующим образом:

    for (i in 2:length(x)-1) print(polyfit(i))
    
  • Я использовал функцию as.integer(), потому что мне не понятно, как я буду интерпретировать нецелый многочлен.

  • для проверки произвольного набора математических уравнений рассмотрим программу 'Eureqa' , рассмотренную Эндрю Гельманом здесь

Обновление

Также см. Функцию stepAIC (в пакете MASS) для автоматизации выбора модели.

5 голосов
/ 14 сентября 2012

Самый простой способ найти лучшее соответствие в R - это кодировать модель следующим образом:

lm.1 <- lm(y ~ x + I(x^2) + I(x^3) + I(x^4) + ...)

После использования понижающей регрессии AIC

lm.s <- step(lm.1)
...