grassp.tl.competitive_diffusion#
- competitive_diffusion(data, gt_col=None, fix_markers=False, renormalize_class_mass=True, min_probability=None, plot_optimization=True, inplace=True, obsp_key='connectivities', key_added='competitive_diffusion', iterative=False, max_iter=1000, rtol=0.0001, verbose=False, method='propagation', alpha=0.8, seed_obsm_key=None, seed_categories_uns_key=None, unknown_label='unknown')[source]#
Propagate categorical annotations along the k-NN graph.
For each observation the function inspects its neighbourhood in
adata.obsp[obsp_key](generated byscanpy.pp.neighbors()) and calculates the a weighted probability for each label category.- Parameters:
- data
AnnData anndata.AnnDatawith a populated neighbour graph (distances or connectivities).- gt_col
str|None(default:None) Observation column containing the source annotations to be propagated.
- fix_markers
bool(default:False) If
Truemarker probabilities do not get overwritten by the propagated labels. Effectively required wheniterative=True: without it nothing anchors the recursion and the class probabilities collapse (seeiterative). Ignored, with a warning, when seeding fromseed_obsm_key(a soft seed has no one-hot marker rows to clamp).- renormalize_class_mass
bool(default:True) If
True(default) each compartment’s propagated mass is rescaled back to the mass it had in the seed, undoing the redistribution diffusion causes. This is not inverse-frequency weighting: a large compartment is not penalised for its size, it is returned to the share it started with. Named for what it does –tl.class_balanceis an unrelated function that subsamples classes to equal size, and the two used to share a name.- min_probability
float|None(default:None) Confidence cutoff: if the probability of the most probable label is below this threshold, the label is set to
np.nan.None(the default) applies no cutoff, i.e. it is equivalent to0.0, so every protein keeps its most probable label and the full probability matrix in.obsmcarries the confidence. Automatic, F1-optimal selection of the cutoff is not currently implemented.- plot_optimization
bool(default:True) Unused; accepted for backwards compatibility and ignored. It belonged to the automatic threshold selection described above.
- obsp_key default:
'connectivities' Name of the neighbour connectivity graph to use (default
"connectivities"). Ifobsp_key="distances"is passed, a Gaussian RBF affinityW = exp(-d² / (2σ²))is built on the kNN distance graph (with σ the median nonzero distance) and used as the spreading/propagation operator. The resulting matrix is cached atadata.obsp["W_spreading"]for inspection. This typically gives a narrower effective kernel than UMAP’s fuzzy-unionconnectivities, which is useful when you want boundary-localized uncertainty withmethod="spreading".- key_added
str(default:'competitive_diffusion') Name of the new column that will hold the propagated annotation (default
"competitive_diffusion").- iterative
bool(default:False) If
Trueperform multi-step label propagation (in the style ofsklearn.semi_supervised.LabelPropagation). At every step the label distribution is propagated alongTand row-normalized; iffix_markers=Truethe labeled rows are then reset to their initial one-hot encoding. Iteration stops when the relative L1 change falls belowrtolor whenmax_iteris reached. IfFalse(default) only a single propagation step is performed. Ignored whenmethod="spreading"(spreading is always iterative, and its soft clamp plays the role offix_markers).Pair this with
fix_markers=True. Without the clamp the iteration has a degenerate fixed point — every class column converges to the graph’s stationary distribution and the probabilities collapse — and a warning is emitted.- max_iter
int(default:1000) Maximum number of propagation iterations when
iterative=Trueormethod="spreading"(default 1000). A warning is emitted if it is reached beforertolis satisfied.- rtol
float(default:0.0001) Relative convergence tolerance (default
1e-4). The L1 change between consecutive iterations is compared againstrtoltimes a reference magnitude, so the same number means the same thing on maps of any size and with any number of compartments – unlike an absolute L1 sum, which tightens as either grows.- verbose
bool(default:False) If
Trueprint progress to the console.- method
Literal['propagation','spreading'] (default:'propagation') Either
"propagation"(default, Zhu & Ghahramani, 2002) or"spreading"(Zhou et al., 2003). Spreading uses the symmetric normalized operatorS = D^{-1/2} W D^{-1/2}and a soft clamp controlled byalpha, which makes it more robust to noisy seeds.- alpha
float(default:0.8) Soft-clamping parameter for label spreading, in
[0, 1). The update rule isF(t+1) = alpha * S @ F(t) + (1 - alpha) * Y_0: smallalphakeeps predictions close to the initial seeds,alphaclose to 1 lets labeled rows drift. Ignored whenmethod="propagation". Default0.8. The update rule is the same onesklearn.semi_supervised.LabelSpreadinguses, but note that its default isalpha=0.2: grassp therefore weights the neighbourhood four times as heavily out of the box.- seed_obsm_key
str|None(default:None) If given, seed the propagation with a soft per-observation label distribution stored in
data.obsm[seed_obsm_key](shape(n_obs, n_categories)) instead of a one-hot encoding ofgt_col. Use this to propagate enrichment uncertainty produced byenrichment_to_cluster_distribution()/soft_cluster_annotation().gt_colbecomes optional when this is set, andfix_markersis disabled (its one-hot marker test does not apply to soft seeds).- seed_categories_uns_key
str|None(default:None) Name of the
data.unsentry holding the ordered list of category names matching the columns of the soft seed matrix. Optional when the seed is aDataFrame, whose own column names are used instead; required when it is a bare ndarray, as written by grassp before labelledobsmmatrices were introduced.- unknown_label
str|None(default:'unknown') Name of the background/unknown category in the soft seed. Observations whose most probable label is this category are reported as unassigned (
NaN) indata.obs[key_added]while the full probability matrix (including the unknown column) is kept inobsm. Set toNoneto keep the unknown label as a regular category. Only used with soft seeds.- inplace bool
- data
- Returns:
Modified anndata object with the following new entries: - .obsm[f”{key_added}_probabilities”] containing the propagated probabilities - .obs[f”{key_added}”] containing the propagated labels (most probable label) - .uns[f”{key_added}_colors”] to make sure plotting uses the same colors as the ground truth labels - .obs[f”{key_added}_probability”] containing the probability of the most probable label