为什么质量:lm.ridge系数与手动计算的不同?

为什么质量:lm.ridge系数与手动计算的不同?,r,regression,mass,R,Regression,Mass,手动执行岭回归时,如定义 solve(t(X) %*% X + lbd*I) %*%t(X) %*% y 我得到的结果与通过MASS::lm.ridge计算得到的结果不同。为什么?对于普通线性回归,手动方法(计算伪逆)效果良好 以下是我的最小可复制示例: library(tidyverse) ridgeRegression = function(X, y, lbd) { Rinv = solve(t(X) %*% X + lbd*diag(ncol(X))) t(Rinv %*% t

手动执行岭回归时,如定义

solve(t(X) %*% X + lbd*I) %*%t(X) %*% y
我得到的结果与通过
MASS::lm.ridge
计算得到的结果不同。为什么?对于普通线性回归,手动方法(计算伪逆)效果良好

以下是我的最小可复制示例:

library(tidyverse)

ridgeRegression = function(X, y, lbd) {
  Rinv = solve(t(X) %*% X + lbd*diag(ncol(X)))
  t(Rinv %*% t(X) %*% y)
}

# generate some data:
set.seed(0)
tb1 = tibble(
  x0 = 1,
  x1 = seq(-1, 1, by=.01),
  x2 = x1 + rnorm(length(x1), 0, .1),
  y  = x1 + x2 + rnorm(length(x1), 0, .5)
)
X = as.matrix(tb1 %>% select(x0, x1, x2))

# sanity check: force ordinary linear regression
# and compare it with the built-in linear regression:
ridgeRegression(X, tb1$y, 0) - coef(summary(lm(y ~ x1 + x2, data=tb1)))[, 1]
# looks the same: -2.94903e-17 1.487699e-14 -2.176037e-14

# compare manual ridge regression to MASS ridge regression:
ridgeRegression(X, tb1$y, 10) - coef(MASS::lm.ridge(y ~ x0 + x1 + x2 - 1, data=tb1, lambda = 10))
# noticeably different: -0.0001407148 0.003689412 -0.08905392

MASS::lm.ridge在建模前对数据进行缩放-这说明了系数的差异

您可以通过在R控制台中键入MASS::lm.ridge来检查函数代码来确认这一点

下面是lm.ridge函数,其缩放部分已注释掉:

X = as.matrix(tb1 %>% select(x0, x1, x2))
n <- nrow(X); p <- ncol(X)
#Xscale <- drop(rep(1/n, n) %*% X^2)^0.5
#X <- X/rep(Xscale, rep(n, p))
Xs <- svd(X)
rhs <- t(Xs$u) %*% tb1$y
d <- Xs$d
lscoef <-  Xs$v %*% (rhs/d)
lsfit <- X %*% lscoef
resid <- tb1$y - lsfit
s2 <- sum(resid^2)/(n - p)
HKB <- (p-2)*s2/sum(lscoef^2)
LW <- (p-2)*s2*n/sum(lsfit^2)
k <- 1
dx <- length(d)
div <- d^2 + rep(10, rep(dx,k))
a <- drop(d*rhs)/div
dim(a) <- c(dx, k)
coef <- Xs$v %*% a
coef
#             x0        x1        x2
#[1,] 0.01384984 0.8667353 0.9452382

X=as.matrix(tb1%>%select(x0,x1,x2))

nMASS::lm.ridge在建模前对数据进行缩放-这解释了系数的差异

您可以通过在R控制台中键入MASS::lm.ridge来检查函数代码来确认这一点

下面是lm.ridge函数,其缩放部分已注释掉:

X = as.matrix(tb1 %>% select(x0, x1, x2))
n <- nrow(X); p <- ncol(X)
#Xscale <- drop(rep(1/n, n) %*% X^2)^0.5
#X <- X/rep(Xscale, rep(n, p))
Xs <- svd(X)
rhs <- t(Xs$u) %*% tb1$y
d <- Xs$d
lscoef <-  Xs$v %*% (rhs/d)
lsfit <- X %*% lscoef
resid <- tb1$y - lsfit
s2 <- sum(resid^2)/(n - p)
HKB <- (p-2)*s2/sum(lscoef^2)
LW <- (p-2)*s2*n/sum(lsfit^2)
k <- 1
dx <- length(d)
div <- d^2 + rep(10, rep(dx,k))
a <- drop(d*rhs)/div
dim(a) <- c(dx, k)
coef <- Xs$v %*% a
coef
#             x0        x1        x2
#[1,] 0.01384984 0.8667353 0.9452382

X=as.matrix(tb1%>%select(x0,x1,x2))

n谢谢,我已经接受了你的回答。然而,我仍然感到困惑:我认为
coef()
,当应用于
lm.ridge()
的结果时,会缩小系数。很明显,它没有做到这一点。它将它们缩放到其他一些值。那么系数值多少呢?我想我也有点困惑。虽然coef()方法没有对系数进行缩放。岭回归对原始数据的规模很敏感(否则它会根据变量的规模任意惩罚变量)——尽管你的自变量有0,但这意味着它们有不同的方差。谢谢,我接受了你的答案。然而,我仍然感到困惑:我认为
coef()
,当应用于
lm.ridge()
的结果时,会缩小系数。很明显,它没有做到这一点。它将它们缩放到其他一些值。那么系数值多少呢?我想我也有点困惑。虽然coef()方法没有对系数进行缩放。岭回归对原始数据的规模很敏感(否则它会根据变量的规模任意惩罚变量)——尽管自变量的0表示它们有不同的方差。