| sfpca | R Documentation |
Performs Sparse and Functional PCA on a data matrix, allowing for both sparsity and smoothness
in the estimated principal components. Penalty parameters left NULL are selected
automatically (see Details). The spatial smoothness penalty is constructed based on
provided spatial coordinates.
sfpca(
X,
K,
spat_cds,
lambda_u = NULL,
lambda_v = NULL,
alpha_u = NULL,
alpha_v = NULL,
Omega_u = NULL,
penalty_u = "l1",
penalty_v = "l1",
nlambda = 10,
lambda_min_ratio = 0.01,
knn = min(6, ncol(X) - 1),
max_iter = 100,
tol = 1e-06,
verbose = FALSE,
uthresh = NULL,
vthresh = NULL
)
X |
A numeric data matrix of dimensions n (observations/time points) by p (variables/space). |
K |
The number of principal components to estimate. |
spat_cds |
A matrix of spatial coordinates for each column of X (variables). Each row
corresponds to a spatial dimension (e.g., x, y, z), and each column corresponds to a variable.
Note the orientation: this is |
lambda_u |
Sparsity penalty parameter for u. If NULL, selected per component by BIC along a regularization path (see Details). |
lambda_v |
Sparsity penalty parameter for v. If NULL, selected per component by BIC along a regularization path (see Details). |
alpha_u |
Smoothness penalty parameter for u. If NULL, defaults to
|
alpha_v |
Smoothness penalty parameter for v. If NULL, defaults to
|
Omega_u |
A positive semi-definite matrix for smoothness penalty on u. If NULL, defaults to
second differences penalty (sparse matrix). Unlike |
penalty_u |
The penalty function for u. Either "l1" (lasso, the default) or "scad". |
penalty_v |
The penalty function for v. Either "l1" (lasso, the default) or "scad". |
nlambda |
Number of values on the regularization path used for BIC selection
of |
lambda_min_ratio |
Smallest path value as a fraction of the closed-form
|
knn |
Number of nearest neighbours for constructing |
max_iter |
Maximum number of iterations for the alternating optimization.
Default |
tol |
Tolerance for convergence of the rank-1 objective. Default |
verbose |
Logical; if TRUE, prints progress messages. |
uthresh |
Deprecated and ignored; |
vthresh |
Deprecated and ignored; |
Each rank-1 problem is solved by alternating solves of the penalized
quadratic subproblems (via C++ coordinate descent) followed by rescaling
onto the smoothness-metric ball, in the constraint form of Allen & Weylandt
(2019). For the convex "l1" penalty with subproblems solved to tolerance
(the internal exact_inner = TRUE path, used by the monotonicity test) the
objective is monotonically non-decreasing; the default inexact path
tightens the inner tolerance to a floor before it may declare convergence,
reproducing the same terminal iterates but without an every-iteration
monotonicity guarantee (it may also stop at max_iter).
When lambda_u or lambda_v is NULL it is selected per component by a
BIC-style criterion along a regularization path. For the convex "l1"
penalty lambda_max = max(abs(b)) is, in closed form, the smallest value
whose subproblem solution is exactly zero (at x = 0 the S x term
vanishes, so the KKT condition |b_j| <= lambda does not depend on S);
where b is the matrix-vector product with the other factor fixed at the
SVD initializer. For the non-convex "scad" penalty the same value anchors
the path but is not a global-optimality threshold. nlambda values are
laid log-spaced down to lambda_min_ratio * lambda_max, coordinate descent
is warm-started along the path, and the value minimizing
log(RSS / (n p)) + df * log(n p) / (n p) is chosen, with df the support
size of the solution and RSS the one-sided rank-1 residual sum of squares
with the opposite factor held fixed (a selection heuristic, not the BIC of
the fully alternated rank-1 model). The all-zero solution (at lambda_max)
is a legitimate candidate: if no rank-1 structure justifies its degrees of
freedom, the component is returned as exactly zero with d = 0.
When alpha_u or alpha_v is NULL it defaults to
1 / lambda_max(Omega), so the roughest direction of the smoothness
penalty is weighted exactly as strongly as the identity term. This makes
the default invariant to the scaling of Omega and bounds the condition
number of every subproblem system I + alpha * Omega by 2.
An object of class c("sfpca", "bi_projector") from the
multivarious framework. Use multivarious::scores() for the sample
scores (U D), multivarious::components() for the sparse loadings
V, multivarious::sdev() for d_k, and
multivarious::reconstruct() for the rank-K approximation. ov (like
components()) holds the sparse right factors V; ou holds the
left factors U. The selected penalty parameters are stored as
lambda_u, lambda_v, alpha_u, and alpha_v. For backward
compatibility the pre-0.1 list fields $d (singular values) and $u
(left factors) remain readable but emit a deprecation warning; use
sdev() and scores()/$ou instead.
Important: unlike genpca(), the columns of U (ou) and V
(ov) are Euclidean unit-norm but are not mutually orthogonal
across components – sfpca() extracts each rank-1 term from a
constraint-form subproblem rather than a joint SVD, so U'U != I and
V'V != I in general. Consequently multivarious::sdev() here is
not the singular values of X; it is the per-component captured
covariance d_k = u_k' X_k v_k, where X_k is the matrix after
the preceding components have been deflated out (so the identity holds
against X itself only for k = 1). This non-orthogonality is also why
reconstruct() for "sfpca" objects uses the stored U, d, V
factors directly (U D V') rather than SVD-based identities such as the
Moore-Penrose pseudoinverse of the loadings, which would not reproduce
the fitted model for non-orthogonal V (see reconstruct.sfpca()).
Allen, G. I., & Weylandt, M. (2019). Sparse and functional principal components analysis. In 2019 IEEE Data Science Workshop (DSW) (pp. 11-16). \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1109/DSW.2019.8755778")}. Also available as arXiv:1309.2895, first posted in 2013 and revised through 2019; the preprint and the DSW paper are the same work, which is why both years appear in the literature.
genpca() for the shared multivarious verbs;
multivarious::bi_projector.
library(Matrix)
set.seed(123)
# Smooth temporal factor, sparse spatial factor
n <- 100 # Number of time points
p <- 50 # Number of spatial locations
u <- sin(seq(0, 2 * pi, length.out = n))
v <- c(rnorm(10), rep(0, p - 10))
X <- 8 * tcrossprod(u / sqrt(sum(u^2)), v / sqrt(sum(v^2))) +
matrix(rnorm(n * p, sd = 0.2), n, p)
spat_cds <- matrix(runif(p * 3), nrow = 3, ncol = p) # 3D coordinates
result <- sfpca(X, K = 1, spat_cds = spat_cds)
multivarious::sdev(result) # captured covariance (BIC-tuned)
sum(multivarious::components(result) != 0) # sparse spatial loading
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.