
Run non-negative matrix factorisation on a BulkCoExp
nmf_bulk.RdFits a single HALS-NMF V ~ W H to the bulk expression matrix with a fixed
number of components k. V is samples x features (matches the layout of
raw_data / processed_data on BulkCoExp()). The result is
rearranged so that:
gene_loadings(features x k) captures per-module gene contributions.sample_activity(samples x k) captures per-module sample activity.
Module membership is derived by keeping the upper tail of each component's
gene loadings, see params_module_membership(). A gene can belong
to several modules, and a gene in no tail belongs to none.
Usage
nmf_bulk(
object,
k,
preprocessing = c("none", "sd", "sqrt_sd"),
nmf_hals_params = params_nmf_hals(),
membership_params = params_module_membership(),
seed = 42L,
.verbose = TRUE
)Arguments
- object
The class, see
BulkCoExp(). Ideally, you should runpreprocess_bulk_coexp()before applying this function. The NMF requires non-negative input, so the pre-processing should either skip scaling or use a strictly non-negative representation.- k
Integer. Number of latent factors (modules).
- preprocessing
String. One of
c("none", "sd", "sqrt_sd"). Applied inside the Rust kernel to the input matrix before the HALS updates.- nmf_hals_params
List. Output of
params_nmf_hals():max_iter - Integer. Maximum number of HALS iterations.
tol - Float. Convergence tolerance.
eps - Float. Numerical floor.
check_every - Integer. Convergence check interval.
nmf_init - String. One of
c("nndsvd", "svd", "random").
- membership_params
List. Controls how the gene loadings are turned into module membership, see
params_module_membership(). Membership is not exclusive: a gene loading strongly on several components appears in several modules, and a gene in no tail appears in none.- seed
Integer. Random seed for the NMF initialisation. Defaults to
42L.- .verbose
Boolean or integer
0L/1L/2L. Controls verbosity.
Value
The class with final_results populated (see description) and the
fit parameters stored under params$nmf_fit, plus
params$detection_method = "nmf-based".
Examples
# a single four-factor HALS-NMF fit
syn <- generate_gene_module_data(n_samples = 24L, n_genes = 60L)
# NMF needs a non-negative matrix
mat <- syn$data - min(syn$data)
obj <- BulkCoExp(mat, syn$meta_data)
obj <- preprocess_bulk_coexp(
obj, hvg = NULL, scaling = FALSE, .verbose = FALSE
)
obj <- nmf_bulk(obj, k = 4L, .verbose = FALSE)
head(get_nmf_modules(obj))
#> gene module_id loading sign z
#> <char> <char> <num> <char> <num>
#> 1: feature_44 comp_01 3.675330 pos 38.28581
#> 2: feature_40 comp_01 3.643421 pos 37.94433
#> 3: feature_42 comp_01 3.633641 pos 37.83967
#> 4: feature_31 comp_01 3.630990 pos 37.81130
#> 5: feature_34 comp_01 3.602253 pos 37.50377
#> 6: feature_45 comp_01 3.590235 pos 37.37517