Полиномиальная регрессия: почему вам нужно определить полиномиальные термины вне lm (), чтобы избежать особенностей?
Если вы попытаетесь запустить полиномиальную регрессию, где x^2
определяется в функции lm()
, полиномиальный член будет отброшен из-за особенностей. Однако, если мы определяем полиномиальный член вне lm()
, модель подходит правильно.
Похоже, что это должно работать одинаково в обоих направлениях. Почему нам нужно определить полиномиальный член вне функции lm()
?
x <- round(rnorm(100, mean = 0, sd = 10))
y <- round(x*2.5 + rnorm(100))
# Trying to define x^2 in the model, x^2 is dropped
model_wrong <- lm(y ~ x + x^2)
# Define x^2 as its own object
x2 <- x^2
model_right <- lm(y ~ x + x2)
1 ответ:
lm
не знает, где начинается и заканчивается термин в Формуле, если вы не скажете ему, обычно обертывая его в функцию. Для произвольных вычислений вы можете обернуть их вI(...)
, который говорит функции использовать его как есть:set.seed(47) x <- round(rnorm(100, mean = 0, sd = 10)) y <- round(x*2.5 + rnorm(100)) lm(y ~ x + I(x^2)) #> #> Call: #> lm(formula = y ~ x + I(x^2)) #> #> Coefficients: #> (Intercept) x I(x^2) #> 2.563e-01 2.488e+00 -3.660e-06
Действительно, Вы можете обернуть
В качестве альтернативы, вы можете использовать функциюx^2
в почти любой вызов функции, который вернет вычисленный вектор, который может быть использован в матрице модели. В некоторых случаяхcbind
может быть очень удобно, хотяc
,identity
, или даже{...}
будет работать.I
является специально построенным, хотя.poly
, чтобы сделать оба члена для вас, что очень полезно для полиномов более высокой степени. По умолчанию он генерирует ортогональные полиномы, которые заставят коэффициенты выглядеть иначе:lm(y ~ poly(x, 2)) #> #> Call: #> lm(formula = y ~ poly(x, 2)) #> #> Coefficients: #> (Intercept) poly(x, 2)1 poly(x, 2)2 #> 1.500000 243.485357 -0.004319
Даже если они будут оценивать одно и то же:
new <- data.frame(x = seq(-1, 1, .5)) predict(lm(y ~ x + I(x^2)), new) #> 1 2 3 4 5 #> -2.2317175 -0.9876930 0.2563297 1.5003505 2.7443695 predict(lm(y ~ poly(x, 2)), new) #> 1 2 3 4 5 #> -2.2317175 -0.9876930 0.2563297 1.5003505 2.7443695
Если вы действительно хотите, чтобы ваши коэффициенты были одинаковыми, добавьте
raw = TRUE
:lm(y ~ poly(x, 2, raw = TRUE)) #> #> Call: #> lm(formula = y ~ poly(x, 2, raw = TRUE)) #> #> Coefficients: #> (Intercept) poly(x, 2, raw = TRUE)1 poly(x, 2, raw = TRUE)2 #> 2.563e-01 2.488e+00 -3.660e-06