Skip to content

Commit 58a909a

Browse files
committed
ridge: goodbye gcv, hello loocv
1 parent 72b9ff8 commit 58a909a

File tree

3 files changed

+16
-23
lines changed

3 files changed

+16
-23
lines changed

R/ridge.r

+15-15
Original file line numberDiff line numberDiff line change
@@ -56,29 +56,29 @@ ridge.matrix <- function (obj, y, lambda, ...) {
5656
p <- ncol(X)
5757
my <- mean(y)
5858
yy <- y - my
59-
Xs <- svd(X)
60-
d <- Xs$d
61-
k <- length(lambda)
62-
dx <- length(d)
63-
div <- d^2 + rep(n*lambda, rep(dx, k))
64-
rhs <- crossprod(Xs$u, yy)
65-
a <- drop(d * rhs)/div
66-
dim(a) <- c(dx, k)
67-
coef <- Xs$v %*% a
59+
xsvd <- svd(X)
60+
u <- xsvd$u
61+
d <- xsvd$d
62+
v <- xsvd$v
63+
div <- outer(d^2, n*lambda, '+')
64+
mid <- d^2 / div
65+
sii <- vapply(1:n, function(i) crossprod(u[i,], u[i,] * mid), numeric(length(lambda)))
66+
if (length(lambda) > 1) sii <- t(sii)
67+
coef <- v %*% sweep(1/div, 1, drop(d * crossprod(u, yy)), '*')
6868
dimnames(coef) <- list(colnames(obj), format(lambda))
6969

70-
df <- colSums(matrix(d^2/div, dx))
70+
df <- colSums(d^2/div)
7171
Y <- X %*% coef
72-
RSS <- colSums((yy - Y)^2)
73-
GCV <- RSS/(1-df/n)^2
72+
rss <- colSums((yy - Y)^2)
73+
loocv <- colMeans(((yy - Y) / (1-sii))^2)
7474

7575
beta <- matrix(0, nrow = nrow(coef) + 1, ncol = length(lambda))
7676
beta[-1,] <- coef/attr(X, 'scale')
7777
beta[1, ] <- my - crossprod(attr(X, 'center'), beta[-1,])
7878
if (is.null(colnames(obj))) colnames(obj) <- paste0('V', 1:p)
7979
dimnames(beta) <- list(c("(Intercept)", colnames(obj)), lambda)
8080

81-
res <- list(beta = drop(beta), lambda = lambda, GCV = GCV, df=df, RSS=RSS, n=n, SVD=Xs, center=attr(X, 'center'), scale=attr(X, 'scale'), ymean=my)
81+
res <- list(beta = drop(beta), lambda = lambda, loocv = loocv, df=df, rss=rss, n=n, svd=xsvd, center=attr(X, 'center'), scale=attr(X, 'scale'), ymean=my)
8282
class(res) <- "ridge"
8383
res
8484
}
@@ -165,11 +165,11 @@ summary.ridge <- function(object, lambda, which, ...) {
165165
ind <- which
166166
}
167167
l <- object$lambda[ind]
168-
W <- tcrossprod(sweep(object$SVD$v, 2, object$SVD$d^2/object$n + l, '/'), object$SVD$v)
168+
W <- tcrossprod(sweep(object$svd$v, 2, object$svd$d^2/object$n + l, '/'), object$svd$v)
169169
b <- coef(object, which=ind)
170170
bb <- coef(object, standardize=TRUE, which=ind)
171171
rdf <- object$n-object$df[ind]-1
172-
s2 <- object$RSS[ind]/rdf
172+
s2 <- object$rss[ind]/rdf
173173
V <- s2/object$n*W
174174
S <- diag(1/object$scale)
175175
x <- object$center

inst/tinytest/ridge.r

+1
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ expect_equivalent(p0, p1)
3535

3636
# plot.ridge works
3737
expect_silent(plot(ridge(y~X)))
38+

man/datasets.Rd

-8
This file was deleted.

0 commit comments

Comments
 (0)