Skip to content

densityPreservation

function densityPreservation(s, method?): MetricResult & {
radiusHigh: Float64Array;
radiusLow: Float64Array;
};

Defined in: metrics/structure.ts:51

Whether dense regions stayed dense and sparse ones sparse.

The one thing no other measure here sees. Trustworthiness checks ordering, stress checks magnitudes — a projection that inflates a tight cluster to the size of a diffuse one satisfies both while destroying the density contrast, which is the failure t-SNE and UMAP are known for.

  • Needs: high-dimensional data and projection. No labels.
  • Range: [-1, 1], higher is better. Above ~0.8 means density is broadly kept; near 0 means it carries no information.
  • Cost: O(N), or O(N log N) for "spearman", on top of an O(N² log N) pass given densityK. Unlike most read-outs here it is not constant-time: it walks every point and correlates the two radius arrays.

The correlation is taken over the logarithms of the two radii, following den-SNE; points whose radius is 0 in either space are dropped from it. The radiusHigh and radiusLow arrays expose the raw per-point radii, including any that were dropped, and plot against each other as a density-preservation scatterplot.

ParameterTypeDefault value
sStructureMomentsundefined
method"pearson" | "spearman""pearson"

MetricResult & { radiusHigh: Float64Array; radiusLow: Float64Array; }

Narayan, Berger & Cho, Nature Biotechnology 39 (2021) https://doi.org/10.1038/s41587-020-00801-7

import { analyze, densityPreservation } from "@saehrimnir/sickle";
// The pass must be told to collect local radii.
const a = analyze(data, projection, { densityK: 20 });
densityPreservation(a.structure).value; // 0.4271 — Pearson by default
densityPreservation(a.structure, "spearman").value; // 0.4229