Mi respuesta detallada está a continuación, pero la respuesta general (es decir, real) a este tipo de pregunta es: 1) experimentar, atornillar, mirar los datos, no puedes romper la computadora sin importar lo que hagas, entonces. . . experimentar; o 2) RTFM .
Aquí hay un R
código que replica el problema identificado en esta pregunta, más o menos:
# This program written in response to a Cross Validated question
# http://stats.stackexchange.com/questions/95939/
#
# It is an exploration of why the result from lm(y_x+I(x^2))
# looks so different from the result from lm(y~poly(x,2))
library(ggplot2)
epsilon <- 0.25*rnorm(100)
x <- seq(from=1, to=5, length.out=100)
y <- 4 - 0.6*x + 0.1*x^2 + epsilon
# Minimum is at x=3, the expected y value there is
4 - 0.6*3 + 0.1*3^2
ggplot(data=NULL,aes(x, y)) + geom_point() +
geom_smooth(method = "lm", formula = y ~ poly(x, 2))
summary(lm(y~x+I(x^2))) # Looks right
summary(lm(y ~ poly(x, 2))) # Looks like garbage
# What happened?
# What do x and x^2 look like:
head(cbind(x,x^2))
#What does poly(x,2) look like:
head(poly(x,2))
El primero lm
devuelve la respuesta esperada:
Call:
lm(formula = y ~ x + I(x^2))
Residuals:
Min 1Q Median 3Q Max
-0.53815 -0.13465 -0.01262 0.15369 0.61645
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 3.92734 0.15376 25.542 < 2e-16 ***
x -0.53929 0.11221 -4.806 5.62e-06 ***
I(x^2) 0.09029 0.01843 4.900 3.84e-06 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.2241 on 97 degrees of freedom
Multiple R-squared: 0.1985, Adjusted R-squared: 0.182
F-statistic: 12.01 on 2 and 97 DF, p-value: 2.181e-05
El segundo lm
devuelve algo extraño:
Call:
lm(formula = y ~ poly(x, 2))
Residuals:
Min 1Q Median 3Q Max
-0.53815 -0.13465 -0.01262 0.15369 0.61645
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 3.24489 0.02241 144.765 < 2e-16 ***
poly(x, 2)1 0.02853 0.22415 0.127 0.899
poly(x, 2)2 1.09835 0.22415 4.900 3.84e-06 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.2241 on 97 degrees of freedom
Multiple R-squared: 0.1985, Adjusted R-squared: 0.182
F-statistic: 12.01 on 2 and 97 DF, p-value: 2.181e-05
Dado que lm
es lo mismo en las dos llamadas, tiene que ser los argumentos de los lm
cuales son diferentes. Entonces, veamos los argumentos. Obviamente, y
es lo mismo. Son las otras partes. Veamos las primeras observaciones sobre las variables del lado derecho en la primera llamada de lm
. El regreso de head(cbind(x,x^2))
parece:
x
[1,] 1.000000 1.000000
[2,] 1.040404 1.082441
[3,] 1.080808 1.168146
[4,] 1.121212 1.257117
[5,] 1.161616 1.349352
[6,] 1.202020 1.444853
Esto es como se esperaba. La primera columna es x
y la segunda columna es x^2
. ¿Qué tal la segunda llamada de lm
, la que tiene poli? El regreso de head(poly(x,2))
parece:
1 2
[1,] -0.1714816 0.2169976
[2,] -0.1680173 0.2038462
[3,] -0.1645531 0.1909632
[4,] -0.1610888 0.1783486
[5,] -0.1576245 0.1660025
[6,] -0.1541602 0.1539247
OK, eso es muy diferente. La primera columna no es x
, y la segunda columna no lo es x^2
. Entonces, poly(x,2)
haga lo que haga, no regresa x
y x^2
. Si queremos saber qué poly
hace, podríamos comenzar leyendo su archivo de ayuda. Eso decimos nosotros help(poly)
. La descripción dice:
Devuelve o evalúa polinomios ortogonales de grado 1 a grado sobre el conjunto especificado de puntos x. Todos estos son ortogonales al polinomio constante de grado 0. Alternativamente, evalúe los polinomios en bruto.
Ahora, o sabes qué son los "polinomios ortogonales" o no. Si no lo hace, use Wikipedia o Bing (no Google, por supuesto, porque Google es malvado, no tan malo como Apple, naturalmente, pero sigue siendo malo). O bien, puede decidir que no le importa qué son los polinomios ortogonales. Puede notar la frase "polinomios en bruto" y puede notar un poco más abajo en el archivo de ayuda que poly
tiene una opción raw
que, por defecto, es igual a FALSE
. Esas dos consideraciones pueden inspirarlo a probar head(poly(x, 2, raw=TRUE))
qué retornos:
1 2
[1,] 1.000000 1.000000
[2,] 1.040404 1.082441
[3,] 1.080808 1.168146
[4,] 1.121212 1.257117
[5,] 1.161616 1.349352
[6,] 1.202020 1.444853
Emocionado por este descubrimiento (parece correcto, ahora, ¿sí?), Puede continuar. summary(lm(y ~ poly(x, 2, raw=TRUE)))
Esto devuelve:
Call:
lm(formula = y ~ poly(x, 2, raw = TRUE))
Residuals:
Min 1Q Median 3Q Max
-0.53815 -0.13465 -0.01262 0.15369 0.61645
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 3.92734 0.15376 25.542 < 2e-16 ***
poly(x, 2, raw = TRUE)1 -0.53929 0.11221 -4.806 5.62e-06 ***
poly(x, 2, raw = TRUE)2 0.09029 0.01843 4.900 3.84e-06 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.2241 on 97 degrees of freedom
Multiple R-squared: 0.1985, Adjusted R-squared: 0.182
F-statistic: 12.01 on 2 and 97 DF, p-value: 2.181e-05
Hay al menos dos niveles para la respuesta anterior. Primero, respondí tu pregunta. Segundo, y mucho más importante, ilustré cómo se supone que debes responder preguntas como esta tú mismo. Cada persona que "sabe programar" ha pasado por una secuencia como la que se menciona más de sesenta millones de veces. Incluso las personas tan deprimentemente malas en la programación como yo pasan por esta secuencia todo el tiempo. Es normal que el código no funcione. Es normal entender mal las funciones que hacen. La forma de lidiar con esto es atornillar, experimentar, mirar los datos y RTFM. Sal del modo de "seguir una receta sin pensar" y entra en el modo "detective".