tensor_predictors/tensorPredictors/R/SIR.R

37 lines
1023 B
R

#' Sliced Inverse Regression
#'
#' @export
SIR <- function(X, y, d, nr.slices = 10L, slice.method = c("cut", "ecdf")) {
if (!(is.factor(y) || is.integer(y))) {
slice.method <- match.arg(slice.method)
if (slice.method == "ecdf") {
y <- cut(ecdf(y)(y), nr.slices)
} else {
y <- cut(y, nr.slices)
# ensure there are no empty slices
if (any(table(y) == 0)) {
y <- as.factor(as.integer(y))
}
}
}
# Center `X`
Z <- scale(X, scale = FALSE)
# Split `Z` into slices determined by `y`
slices <- Map(function(i) Z[i, , drop = FALSE], split(seq_along(y), y))
# Sizes and Means for each slice
slice.sizes <- mapply(nrow, slices)
slice.means <- Map(colMeans, slices)
# Inbetween slice covariances
sCov <- Reduce(`+`, Map(function(mean_s, n_s) {
n_s * tcrossprod(mean_s)
}, slice.means, slice.sizes)) / nrow(X)
# Compute EDR directions
La.svd(sCov, d, 0L)$u
}