Up to this point, ScaleRank kept a table of the ranks of all points as seen from each point (N × N), which limited it to about 10,000 points. So I dropped the rank table and built a version that optimises the same objective function using only structures of size O(N log N).
- Ranks 1–100 are found with exact k-nearest neighbours.
- Larger ranks are estimated from random subsamples at several levels. The a-th nearest point in a subsample of size n corresponds to a rank of roughly a·N/(n+1) in the full data. This gives each point a "distance → rank" table.
- Negatives are chosen from candidates redrawn uniformly at each epoch: the candidates are ranked with the table, and those whose rank exceeds K are used.
Compared with the original version on 8 datasets × 3 seeds, the differences were within about ±0.01 on every metric (Table 5). Evaluation was also changed to estimate from only 2,000 rows for datasets of more than 10,000 points. Each metric is a mean of per-row values, so this estimate is unbiased.
- Globally (distance correlation), ScaleRank is clearly higher than t-SNE and UMAP.
- Locally (RNX@10), on the other hand, it weakens as N grows. On MNIST at γ=1, it was 0.27 at 10,000 points but 0.10 at 70,000 points: about a quarter of t-SNE (0.39) and about the same as UMAP.
In Figure 21, ScaleRank γ=1 (neg_scale 0.5) keeps the digits apart, but each class breaks into small clumps, with many scattered points around them. γ=0 keeps the overall arrangement but lets the classes overlap.
Why local weakens as N grows
If the number of negatives Q stays fixed while N grows, the Q negatives stand in for an ever larger set of "all other points", and the repulsion becomes relatively weaker. This is a known property in contrastive learning (Damrich et al. 2023), and the behaviour approaches that of UMAP, which draws few negatives.
So I added a setting that multiplies the negative terms by a weight w = ((N−1−K)/Q)a (neg_scale = a). With a = 0.5, local roughly doubles (MNIST 0.10 → 0.20, Fashion-MNIST 0.12 → 0.20), but it still falls short of t-SNE. On small datasets the density correlation drops (0.66 → 0.48 on digits), so it is not the default.
On 10,000 MNIST points I also tried other settings. Raising γ lifts local to at most 0.36 (γ=2); 100 negatives give 0.35, and neg_scale 0.5 gives 0.36, against 0.28 for the default γ=1 and 0.45 for t-SNE. Four times as many groups per point, or 2,000 epochs instead of 800, change almost nothing (0.29).