【问题标题】:Toy R function for solving ordinary least squares by singular value decomposition通过奇异值分解求解普通最小二乘的 Toy R 函数
【发布时间】:2017-03-08 02:22:55
【问题描述】:

我正在尝试使用矩阵的奇异值分解来编写用于多元回归分析 (y = Xb + e) 的函数。 yX 必须是输入和回归系数向量 b,残差向量 e 和方差占 R2 作为输出。下面是我到目前为止所拥有的,我完全被困住了。重量的labels 部分也给了我一个错误。这是什么labels 部分?谁能给我一些提示以帮助我继续进行?

Test <- function(X, y) {
  x <- t(A) %*% A
  duv <- svd(x)
  x.inv <- duv$v %*% diag(1/duv$d) %*% t(duv$u)
  x.pseudo.inv <- x.inv %*% t(A)
  w <- x.pseudo.inv %*% labels
  return(b, e, R2)
  }

【问题讨论】:

  • 案例很重要 - xX 是不同的。你的函数的第一行使用A,但A没有输入。它从何而来?我也不确定labels 是什么——这不是你写的代码吗?它应该做什么?
  • 大部分是我在这个网站上找到的代码。他们使用labels。是的,抱歉,A 是一个测试矩阵。但是我的问题已经在下面回答了,还是谢谢!

标签: r matrix regression linear-regression svd


【解决方案1】:

你不在路上了......奇异值分解应用于模型矩阵X,而不是普通矩阵X'X。以下是正确的程序:

所以在写R函数的时候,我们应该这样做

svdOLS <- function (X, y) {
  SVD <- svd(X)
  V <- SVD$v
  U <- SVD$u
  D <- SVD$d
  ## regression coefficients `b`
  ## use `crossprod` for `U'y`
  ## use recycling rule for row rescaling of `U'y` by `D` inverse
  ## use `as.numeric` to return vector instead of matrix
  b <- as.numeric(V %*% (crossprod(U, y) / D))
  ## residuals
  r <- as.numeric(y - X %*% b)
  ## R-squared
  RSS <- crossprod(r)[1]
  TSS <- crossprod(y - mean(y))[1]
  R2 <- 1 - RSS / TSS
  ## multiple return via a list
  list(coefficients = b, residuals = r, R2 = R2)
  }

我们来测试一下

## toy data
set.seed(0)
x1 <- rnorm(50); x2 <- rnorm(50); x3 <- rnorm(50); y <- rnorm(50)
X <- model.matrix(~ x1 + x2 + x3)

## fitting linear regression: y ~ x1 + x2 + x3
svdfit <- svdOLS(X, y)

#$coefficients
#[1]  0.14203754 -0.05699557 -0.01256007  0.09776255
#
#$residuals
# [1]  1.327108410 -1.400843739 -0.071885339  2.285661880  0.882041795
# [6] -0.535230752 -0.927750996  0.262674650 -0.133878558 -0.559783412
#[11]  0.264204296 -0.581468657  2.436913000  1.517601798  0.774515419
#[16]  0.447774149 -0.578988327  0.664690723 -0.511052627 -1.233302697
#[21]  1.740216739 -1.065592673 -0.332307898 -0.634125164 -0.975142054
#[26]  0.344995480 -1.748393187 -0.414763742 -0.680473508 -1.547232557
#[31] -0.383685601 -0.541602452 -0.827267878  0.894525453  0.359062906
#[36] -0.078656943  0.203938750 -0.813745178 -0.171993018  1.041370294
#[41] -0.114742717  0.034045040  1.888673004 -0.797999080  0.859074345
#[46]  1.664278354 -1.189408794  0.003618466 -0.527764821 -0.517902581
#
#$R2
#[1] 0.008276773

另一方面,我们可以使用.lm.fit 来检查正确性:

qrfit <- .lm.fit(X, y)

在系数和残差上完全一样:

all.equal(svdfit$coefficients, qrfit$coefficients)
# [1] TRUE

all.equal(svdfit$residuals, qrfit$residuals)
# [1] TRUE

【讨论】:

  • 好的,我知道你要处理这个了。谢谢!但是我怎样才能从中得到 b、e 和 R^2 呢?
  • 非常感谢!你拯救了我的白天/黑夜。如果你愿意的话,你能看看我和我的同学有类似的问题吗? stackoverflow.com/questions/40250691/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 2019-10-05
  • 2013-10-11
  • 2015-04-13
相关资源
最近更新 更多