Щоб проілюструвати проблему чисельної стабільності, згадану @cbeleites, ось приклад Саймона Вуда про те, як "зламати" lm()
. Спочатку ми згенеруємо кілька простих даних і помістимо просту квадратичну криву.
set.seed(1); n <- 100
xx <- sort(runif(n))
y <- .2*(xx-.5)+(xx-.5)^2 + rnorm(n)*.1
x <- xx+100
b <- lm(y ~ x+I(x^2))
plot(x,y)
lines(x, predict(b), col='red')
Але якщо ми додамо 900 до X, то результат повинен бути майже однаковим, за винятком зсуву вправо, ні? На жаль ні...
X <- x + 900
B <- lm(y ~ X+I(X^2))
plot(X,y)
lines(X, predict(B), col='blue')
Змінити, щоб додати до коментаря @Scortchi - якщо ми подивимось на об’єкт, повернутий lm (), ми побачимо, що квадратичний додаток не був оцінений і відображається як NA.
> B
Call:
lm(formula = y ~ X + I(X^2))
Coefficients:
(Intercept) X I(X^2)
-139.3927 0.1394 NA
І справді, як запропонував @Scortchi, якщо ми подивимось на матрицю моделі та спробуємо вирішити безпосередньо, вона "ламається".
> X <- model.matrix(b) ## get same model matrix used above
> beta.hat <- solve(t(X)%*%X,t(X)%*%y) ## direct solution of ‘normal equations’
Error in solve.default(t(X) %*% X, t(X) %*% y) :
system is computationally singular: reciprocal condition number = 3.9864e-19
Однак lm()
не дає мені жодного попередження або повідомлення про помилку, окрім NA
s у I(X^2)
рядку summary(B)
в R-3.1.1. Інші алгоритми, звичайно, можна "поламати" по-різному на різних прикладах.