Moja szczegółowa odpowiedź znajduje się poniżej, ale ogólna (tj. Prawdziwa) odpowiedź na tego rodzaju pytanie brzmi: 1) eksperymentuj, przekręć się, spójrz na dane, nie możesz uszkodzić komputera bez względu na to, co robisz, więc. . . eksperyment; lub 2) RTFM .
Oto R
kod, który mniej więcej odzwierciedla problem zidentyfikowany w tym pytaniu:
# 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))
Pierwszy lm
zwraca oczekiwaną odpowiedź:
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
Drugi lm
zwraca coś dziwnego:
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
Ponieważ lm
jest tak samo w dwóch wywołaniach, muszą to być lm
różne argumenty . Spójrzmy więc na argumenty. Oczywiście y
jest tak samo. To inne części. Spójrzmy na kilka pierwszych obserwacji zmiennych po prawej stronie w pierwszym wywołaniu lm
. Powrót head(cbind(x,x^2))
wygląda następująco:
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
To jest zgodne z oczekiwaniami. Pierwsza kolumna to x
druga kolumna x^2
. Co powiesz na drugie połączenie z lm
tym z poli? Powrót head(poly(x,2))
wygląda następująco:
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, to naprawdę coś innego. Pierwsza kolumna nie jest x
, a druga kolumna nie x^2
. Cokolwiek więc poly(x,2)
zrobi, nie powróci x
i x^2
. Jeśli chcemy wiedzieć, co poly
robi, możemy zacząć od przeczytania pliku pomocy. Tak mówimy help(poly)
. Opis mówi:
Zwraca lub ocenia ortogonalne wielomiany stopnia 1 do stopnia względem określonego zestawu punktów x. Wszystkie są prostopadłe do stałego wielomianu stopnia 0. Ewentualnie oceń surowe wielomiany.
Teraz albo wiesz, co to są „wielomiany ortogonalne”, albo nie. Jeśli nie, skorzystaj z Wikipedii lub Binga (oczywiście nie Google, ponieważ Google jest zły - nie tak zły jak Apple, oczywiście, ale nadal zły). Lub możesz zdecydować, że nie obchodzi Cię, jakie są wielomiany ortogonalne. Możesz zauważyć wyrażenie „surowe wielomiany” i możesz zauważyć nieco dalej w pliku pomocy poly
z opcją, raw
która domyślnie jest równa FALSE
. Te dwa względy mogą zainspirować Cię do wypróbowania, head(poly(x, 2, raw=TRUE))
które zwroty:
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
Podekscytowany tym odkryciem (teraz wygląda na to, prawda?), Możesz spróbować. summary(lm(y ~ poly(x, 2, raw=TRUE)))
Zwraca:
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
Powyższa odpowiedź ma co najmniej dwa poziomy. Najpierw odpowiedziałem na twoje pytanie. Po drugie i, co ważniejsze, zilustrowałem, w jaki sposób powinieneś sam odpowiadać na takie pytania. Każda osoba, która „umie programować”, przechodziła przez sekwencję taką jak ta ponad sześćdziesiąt milionów razy. Nawet ludzie tak przygnębiająco słabi w programowaniu jak ja cały czas przechodzę przez tę sekwencję. To normalne, że kod nie działa. Nieporozumienie, jakie funkcje pełnią, jest normalne. Sposobem poradzenia sobie z tym jest przekręcenie, eksperymentowanie, przeglądanie danych i RTFM. Wyjdź z trybu „bezmyślnego przestrzegania przepisu” i przejdź do trybu „detektywistycznego”.