
Run consensus NMF on single cell or meta cell data
consensus_nmf_sc.RdRuns n_runs HALS NMF restarts, pools their components, drops unstable ones
by local density, k-means clusters the survivors into k groups and refits
the partner factor against the per-cluster median. This is cNMF: the answer
is the structure the restarts agree on, and the mean silhouette of those
clusters (stability) says how much they agreed.
Usage
consensus_nmf_sc(
object,
k,
cell_ids = NULL,
gene_ids = NULL,
preprocessing = "none",
use_second_layer = TRUE,
nmf_hals_params = params_nmf_hals(),
nmf_consensus_params = params_nmf_consensus(),
n_runs = 30L,
seed = 42L,
.verbose = TRUE
)Arguments
- object
SingleCellsorMetaCellsclass.- k
Integer. Number of latent factors. Must be at least 2.
- cell_ids
Optional character. Cell ids (or meta cell ids) to restrict the NMF to. If
NULL, usesget_cells_to_keep()forSingleCellsand all meta cells forMetaCells.- gene_ids
Optional character. Gene ids to restrict the NMF to. If
NULL, usesget_hvg()on the object.- preprocessing
String. One of
c("none", "sd", "sqrt_sd").- use_second_layer
Boolean. If
TRUE, runs NMF on the normalised counts (recommended); ifFALSE, on the raw counts.- nmf_hals_params
List, see
params_nmf_hals(). Thenmf_initfield is ignored, restarts always use random initialisation.- nmf_consensus_params
List, see
params_nmf_consensus().- n_runs
Integer. Number of random restarts. Must be at least 2.
- seed
Integer. Base random seed. Restart
iusesseed + i, and the k-means step is seeded from it too.- .verbose
Boolean or integer. Verbosity.
Details
Use nmf_k_sweep_sc() first if you do not already know k.
Memory is the thing to watch. The restarts are dense and all live at once:
roughly n_cells * k * n_runs plus n_runs * k * n_genes floats on top of
the counts. At 200k cells, k = 20 and n_runs = 50 that is a few hundred
megabytes before anything else, which is exactly the regime where running on
MetaCells instead is the honest answer.
The density filter is the part that bites. If it leaves fewer than k
components the fit errors rather than returning something degenerate. With
few restarts the filter is jumpy, so either raise n_runs or set
density_threshold = 2 in params_nmf_consensus() to switch it off.
Examples
# ten restarts pooled, density filter off on data this small
sc <- demo_single_cells()
res <- consensus_nmf_sc(
sc,
k = 3L,
n_runs = 10L,
nmf_consensus_params = params_nmf_consensus(density_threshold = 2),
.verbose = FALSE
)
res
#> ConsensusNmfResult (consensus HALS NMF)
#> Source class: SingleCells
#> No genes: 30
#> No cells: 500
#> No components: 3
#> No runs: 10
#> Stability: 0.9944
#> Relative error: 0.2518
#> Dropped: 0 / 30 components
#> Preprocessing: none
unlink(sc@dir_data, recursive = TRUE, force = TRUE)