Performs nonlinear dimensionality reduction using the Self-Organizing
Nebulous Growths (SONG) algorithm. SONG builds a codebook of coding
vectors connected by a topology-preserving graph, then maps the graph
into a low-dimensional embedding space. Unlike t-SNE and UMAP, the
resulting model supports incremental updates with new data via
update.song_model.
Usage
song(
X,
d = 2L,
k = 3L,
epsilon = 0.9,
epochs = 50L,
alpha = 1,
a = 1.577,
b = 0.895,
spread_factor = 0.5,
neg_sample_rate = 5L,
max_age = 3L,
e_min = NULL,
max_prototypes = NULL,
lr_sigma = 5,
dispersion = TRUE,
seed = NULL,
verbose = TRUE,
feature_manifest = NULL
)Arguments
- X
Numeric matrix of input data (
n x D), or a data.frame with all numeric columns (will be coerced to matrix).- d
Integer. Output dimensionality (default: 2).
- k
Integer. Neighborhood size for the coding-vector graph. Corresponds to
dim + n_neighborsin the Python reference. Must be>= d + 1(default: 3, which matches Python'sn_neighbors = 1withdim = 2).- epsilon
Numeric. Edge decay rate, in
(0, 1)(default: 0.9). Lower values produce sparser, faster-pruning graphs.- epochs
Integer. Number of self-organisation iterations (default: 50, matching Python's
so_steps).- alpha
Numeric. Initial SO learning rate (default: 1.0).
- a
Numeric. Rational-quadratic kernel parameter (default: 1.577, from
find_spread_tightness(spread=1, min_dist=0.1)).- b
Numeric. Rational-quadratic kernel parameter (default: 0.895).
- spread_factor
Numeric. Controls growth threshold \(\theta = -\ln(D) \cdot \ln(\mathrm{sf})\); higher values produce more coding vectors. In
(0, 1)(default: 0.5).- neg_sample_rate
Integer. Number of negative samples per positive edge during repulsion (default: 5).
- max_age
Integer. Controls automatic edge pruning: edges weaker than
epsilon^(d + max_age)are removed (default: 3).- e_min
Numeric or
NULL. Minimum edge strength below which edges are pruned.NULL(default) auto-computes asepsilon^(d + max_age), matching the Python reference.- max_prototypes
Integer or
NULL. Maximum number of coding vectors.NULL(default) auto-computes asfloor(exp(log(n) / 1.5)), matching the Python reference.- lr_sigma
Numeric. Decay constant for the SO learning-rate schedule:
so_lr = alpha * exp(-lr_sigma * (epoch/epochs)^2). Default: 5.0 (matches Python).- dispersion
Logical. If
TRUE(default) and uwot is available, runs a short UMAP refinement step initialised from the SONG embedding. This matches the Python reference implementation'stransform()method and dramatically improves visual cluster separation.- seed
Integer or
NULL. Random seed for reproducibility.- verbose
Logical. Whether to print progress per epoch (default: TRUE).
- feature_manifest
Optional data frame with exactly these character columns, in order:
feature,compartment,statistic,unit,transform,normalization. Rows must follow the named input columns. Describe complete externally applied transform/normalization recipes, including parameters or a versioned reference identifier; use"identity"/"none"when applicable. The manifest records declarations; it does not apply transformations or establish that supplied measurements have the declared physical meaning.
Value
An S3 object of class "song_model" containing:
- Y
Embedding coordinates of coding vectors (
n_coding x d).- C
Coding vectors (
n_coding x D).- E
Directed adjacency matrix (
n_coding x n_coding).- E_s
Symmetric adjacency matrix.
- assignments
Integer vector of length
n: nearest CV index.- embedding
Embedding coordinates for all input points (
n x d).- parameters
List of all hyperparameters used.
- feature_contract
Versioned feature order, declared metadata and missing-value policy.
- n_epochs
Number of epochs actually run.
Details
Named training columns are bound in exact order and must also be named in prediction and updates. An explicit manifest must be supplied again, unchanged, to predict or update a model trained with one. Missing/nonfinite measurements are rejected; no feature is silently reordered or imputed. Unnamed training data retains positional compatibility and cannot verify feature semantics. Legacy models without a contract also retain positional behavior.
References
Senanayake, D. A., Wang, W., Naik, S. H., & Halgamuge, S. (2021). Self-Organizing Nebulous Growths for Robust and Incremental Data Visualization. IEEE Transactions on Neural Networks and Learning Systems, 32(10), 4588–4602. doi:10.1109/TNNLS.2020.3023941
Examples
model <- song(as.matrix(iris[, 1:4]), epochs = 5L, seed = 42)
#> Epoch 1/5 | CVs: 3 | QE: 1.5296 | so_lr: 1.0000 | lr: 1.0000
#> Epoch 2/5 | CVs: 5 | QE: 0.8414 | so_lr: 0.8187 | lr: 0.8000
#> Epoch 3/5 | CVs: 9 | QE: 0.5442 | so_lr: 0.4493 | lr: 0.6000
#> Epoch 4/5 | CVs: 16 | QE: 0.4508 | so_lr: 0.1653 | lr: 0.4000
#> Epoch 5/5 | CVs: 25 | QE: 0.3978 | so_lr: 0.0408 | lr: 0.2000
#> Running UMAP dispersion step...
plot(model, color_by = iris$Species)