Câu trả lời chi tiết của tôi ở bên dưới, nhưng câu trả lời chung (nghĩa là thực) cho loại câu hỏi này là: 1) thử nghiệm, xoay quanh, nhìn vào dữ liệu, bạn không thể phá vỡ máy tính cho dù bạn có làm gì, vì vậy. . . thí nghiệm; hoặc 2) RTFM .
Đây là một số R
mã sao chép vấn đề được xác định trong câu hỏi này, ít nhiều:
# 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))
Câu đầu tiên lm
trả về câu trả lời mong đợi:
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
Thứ hai lm
trả về một cái gì đó kỳ lạ:
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
Vì lm
là giống nhau trong hai cuộc gọi, nên nó phải là đối số lm
khác nhau. Vì vậy, hãy nhìn vào các đối số. Rõ ràng, y
là như nhau. Đó là những phần khác. Chúng ta hãy xem xét một vài quan sát đầu tiên về các biến bên phải trong lệnh gọi đầu tiên của lm
. Sự trở lại của head(cbind(x,x^2))
hình như:
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
Đây là như mong đợi. Cột đầu tiên là x
và cột thứ hai là x^2
. Làm thế nào về cuộc gọi thứ hai của lm
, một cuộc gọi với poly? Sự trở lại của head(poly(x,2))
hình như:
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, điều đó thực sự khác biệt. Cột thứ nhất thì không x
, và cột thứ hai thì không x^2
. Vì vậy, bất cứ điều gì poly(x,2)
, nó không trở lại x
và x^2
. Nếu chúng ta muốn biết những gì poly
, chúng ta có thể bắt đầu bằng cách đọc tệp trợ giúp của nó. Vì vậy, chúng tôi nói help(poly)
. Mô tả cho biết:
Trả về hoặc đánh giá các đa thức trực giao bậc 1 đến độ so với tập hợp các điểm x đã chỉ định. Đây là tất cả các trực giao với đa thức không đổi độ 0. Hoặc, đánh giá đa thức thô.
Bây giờ, hoặc bạn biết "đa thức trực giao" là gì hoặc bạn không biết. Nếu bạn không, thì hãy sử dụng Wikipedia hoặc Bing (tất nhiên không phải Google, vì Google xấu xa --- không tệ như Apple, một cách tự nhiên, nhưng vẫn tệ). Hoặc, bạn có thể quyết định rằng bạn không quan tâm đa thức trực giao là gì. Bạn có thể nhận thấy cụm từ "đa thức thô" và bạn có thể nhận thấy một chút nữa trong tệp trợ giúp poly
có một tùy chọn raw
, theo mặc định, bằng FALSE
. Hai cân nhắc này có thể truyền cảm hứng cho bạn để thử head(poly(x, 2, raw=TRUE))
trả về:
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
Vui mừng vì khám phá này (có vẻ đúng, bây giờ, có?), Bạn có thể tiếp tục dùng thử summary(lm(y ~ poly(x, 2, raw=TRUE)))
Kết quả này:
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
Có ít nhất hai cấp độ cho câu trả lời trên. Đầu tiên, tôi trả lời câu hỏi của bạn. Thứ hai, và quan trọng hơn nhiều, tôi đã minh họa cách bạn phải tự mình trả lời những câu hỏi như thế này. Mỗi một người "biết cách lập trình" đã trải qua một chuỗi như trên sáu mươi triệu lần. Ngay cả những người chán nản lập trình như tôi lúc nào cũng trải qua trình tự này. Đó là bình thường cho mã không hoạt động. Đó là bình thường để hiểu sai những gì chức năng làm. Cách để đối phó với nó là xoay quanh, thử nghiệm, xem dữ liệu và RTFM. Thoát khỏi chế độ "vô thức theo một công thức" và vào chế độ "thám tử".