SecAct Algorithm: Ridge Regression with Permutation Testing
Zaoqu Liu
2026-01-23
Source:vignettes/algorithm.Rmd
algorithm.RmdOverview
SecAct (Secreted protein Activity inference) is a computational framework for inferring the signaling activity of over 1,000 secreted proteins from gene expression profiles. This vignette provides a detailed explanation of the mathematical algorithm underlying SecAct.
Mathematical Framework
Problem Formulation
Given: - Y: Gene expression matrix (genes × samples) - X: Signature matrix (genes × secreted proteins)
We aim to infer the activity matrix β (secreted proteins × samples) that best explains the observed gene expression changes.
Ridge Regression Model
SecAct employs ridge regression to solve this inverse problem:
Where: - : Estimated activity coefficients - : Regularization parameter (default: 5×10⁵) - : Identity matrix
The ridge penalty provides: 1. Numerical stability when is ill-conditioned 2. Regularization to prevent overfitting 3. Unique solution even when features > samples
Implementation via Cholesky Decomposition
For computational efficiency, SecAct uses Cholesky decomposition:
A = X'X + λI (symmetric positive definite)
R = chol(A) (A = R'R)
β = R⁻¹ (R')⁻¹ X' Y
This approach is: - Numerically stable: Exploits the SPD structure - Computationally efficient: O(n³/3) vs O(n³) for general inverse - Memory efficient: Only stores upper triangular R
Statistical Significance
Permutation Testing
SecAct assesses statistical significance through permutation testing:
- Null hypothesis: No association between gene expression and secreted protein activity
-
Procedure:
- Randomly permute sample labels in Y
- Recompute β for each permutation
- Build null distribution of coefficients

Permutation testing procedure
Signature Matrix Construction
SecAct Signature Database
The SecAct signature matrix contains: - 1,170 secreted proteins - 7,919 downstream target genes - Curated from published literature and databases
library(SecAct)
# Load signature matrix
sig_path <- system.file("extdata/SecAct.tsv.gz", package = "SecAct")
sig_mat <- read.table(gzfile(sig_path), sep = "\t", header = TRUE, row.names = 1, nrows = 100)
cat("Signature matrix dimensions:\n")
#> Signature matrix dimensions:
cat(" Genes:", nrow(sig_mat), "(showing first 100)\n")
#> Genes: 100 (showing first 100)
cat(" Secreted proteins:", ncol(sig_mat), "\n")
#> Secreted proteins: 1170Signature Grouping
To reduce multicollinearity, SecAct groups highly correlated signatures:
# Demonstrate signature grouping concept
set.seed(123)
# Simulate correlation matrix for 20 signatures
n_sig <- 20
cor_mat <- matrix(runif(n_sig^2, 0.2, 0.9), n_sig, n_sig)
cor_mat <- (cor_mat + t(cor_mat)) / 2
diag(cor_mat) <- 1
rownames(cor_mat) <- colnames(cor_mat) <- paste0("SP", 1:n_sig)
# Hierarchical clustering
hc <- hclust(as.dist(1 - cor_mat), method = "complete")
plot(hc, main = "Signature Grouping by Correlation", xlab = "", sub = "")
abline(h = 0.1, col = "red", lty = 2)
text(15, 0.15, "Correlation threshold = 0.9", col = "red")
Hierarchical clustering of signature correlation
Algorithm Comparison: R vs GSL
SecAct provides two implementations:
| Feature | SecAct.inference.r |
SecAct.inference.gsl |
|---|---|---|
| Language | Pure R | C with GSL |
| Speed | Moderate | Fast |
| Platform | All | Unix/macOS |
| Precision | 64-bit | 64-bit |
# Compare R and GSL implementations
data_path <- system.file("extdata/GSE100093.IFNG.expr.gz", package = "SecAct")
Y <- read.table(gzfile(data_path), sep = "\t", header = TRUE, row.names = 1)
# Run both implementations
set.seed(42)
result_r <- SecAct.inference.r(Y[, 1:3], lambda = 5e5, nrand = 100)
set.seed(42)
result_gsl <- SecAct.inference.gsl(Y[, 1:3], lambda = 5e5, nrand = 100)
# Compare results
cor_beta <- cor(as.vector(result_r$beta), as.vector(result_gsl$beta))
cor_zscore <- cor(as.vector(result_r$zscore), as.vector(result_gsl$zscore))
cat("Implementation Consistency:\n")
#> Implementation Consistency:
cat(" Beta correlation:", round(cor_beta, 4), "\n")
#> Beta correlation: 0.9854
cat(" Z-score correlation:", round(cor_zscore, 4), "\n")
#> Z-score correlation: 0.9733Practical Considerations
Lambda Selection
The regularization parameter λ controls the bias-variance tradeoff:
# Demonstrate lambda effect
lambdas <- c(1e3, 1e4, 1e5, 5e5, 1e6, 1e7)
Y_small <- Y[, 1:2]
results <- lapply(lambdas, function(l) {
SecAct.inference.r(Y_small, lambda = l, nrand = 50)
})
# Plot coefficient ranges
coef_ranges <- sapply(results, function(r) range(r$beta))
par(mar = c(4, 4, 2, 1))
plot(log10(lambdas), coef_ranges[2,], type = "b", pch = 19, col = "blue",
ylim = range(coef_ranges), xlab = "log10(lambda)", ylab = "Coefficient range",
main = "Lambda Effect on Coefficients")
lines(log10(lambdas), coef_ranges[1,], type = "b", pch = 19, col = "red")
legend("topright", c("Max", "Min"), col = c("blue", "red"), pch = 19)
abline(v = log10(5e5), lty = 2, col = "gray")
text(log10(5e5), mean(coef_ranges), "Default", pos = 4)
Effect of lambda on coefficient estimates
Summary
SecAct combines:
- Ridge regression for robust activity inference
- Permutation testing for statistical significance
- Efficient implementation in C/GSL for speed
- Comprehensive signature database covering 1,170+ secreted proteins
For questions or issues, please contact:
- Author: Zaoqu Liu (liuzaoqu@163.com)
- GitHub: https://github.com/Zaoqu-Liu/SecAct
References
- Hoerl, A.E. and Kennard, R.W. (1970). Ridge Regression: Biased Estimation for Nonorthogonal Problems. Technometrics.
- Good, P. (2005). Permutation, Parametric and Bootstrap Tests of Hypotheses. Springer.
Session Info
sessionInfo()
#> R version 4.4.0 (2024-04-24)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS 15.6.1
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
#>
#> locale:
#> [1] C
#>
#> time zone: Asia/Shanghai
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] SecAct_1.0.1
#>
#> loaded via a namespace (and not attached):
#> [1] digest_0.6.39 desc_1.4.3 R6_2.6.1 fastmap_1.2.0
#> [5] xfun_0.56 cachem_1.1.0 knitr_1.51 htmltools_0.5.9
#> [9] rmarkdown_2.30 lifecycle_1.0.5 cli_3.6.5 sass_0.4.10
#> [13] pkgdown_2.1.3 textshaping_1.0.4 jquerylib_0.1.4 systemfonts_1.3.1
#> [17] compiler_4.4.0 tools_4.4.0 ragg_1.5.0 bslib_0.9.0
#> [21] evaluate_1.0.5 yaml_2.3.12 otel_0.2.0 jsonlite_2.0.0
#> [25] rlang_1.1.7 fs_1.6.6 htmlwidgets_1.6.4