API reference

This page shows the signature and docstring of each public name in starfold, grouped by the job it does.

Note

starfold.search runs the search alone. It needs config=, random_state= and a resolved engine ("cpu" or "cuml", not "auto").

Run a recovery

recover runs the whole procedure and returns one Result. Config declares its budgets and Space the ranges of the settings it searches. Every Config argument is a keyword with a default; Configuration fields lists each one.

starfold.recover(X, *, X_err=None, measurement_sampler=None, config=None, random_state=0, engine='auto', n_jobs=1)[source]

Recover recurrent density populations from a feature matrix.

Parameters:
Xarray-like of shape (n_samples, n_features)

Feature matrix. Rows with non-finite values are rejected and counted.

X_errarray-like of shape (n_samples, n_features), optional

Per-value standard deviations, from which each world draws X + X_err * N(0, 1).

measurement_samplercallable, optional

Alternative measurement model sampler(rows, indices, rng).

configConfig, optional

Declared budgets and rules; defaults to Config().

random_stateint, default 0

Base seed of every stochastic stage.

engine{“auto”, “cpu”, “cuml”}, default “auto”

Backend; auto prefers cuML when it imports with a device.

n_jobsint, default 1

Worker processes inside a trial and over worlds. On the CPU with at most 20000 rows per resample, null realisations also run n_jobs at a time. Forced to 1 on cuML.

Returns:
Result

The emitted partition, world evidence, consensus check, null calibration, flags and provenance.

Raises:
ValueError

For an invalid matrix, uncertainties, job count, or engine value.

ImportError

Raised before any stage runs if engine="cuml" or config.check_backends is set and cuML cannot be used.

class starfold.Config[source]

Declared budgets and rules of one recover run.

null_families is empty by default, so recover skips the matched null: it costs 102 fits per realisation over up to 19 realisations, about six times the rest of a run. Run null_test() once on the result you report, or name the families here to run it inside recover.

Attributes:
spaceSpace, default Space()

Search bounds.

scaling{“standard”, “robust”}, default “standard”

Feature scaling, fitted inside each resample and world.

n_trialsint, default 48

Largest number of search trials, the default and the design included.

n_exploreint, default 16

Sobol design trials after the default trial, a power of two.

n_resamplesint, default 3

Resamples of the common plan on which every trial is scored, at least 2.

resample_fractionfloat, default 0.8

Fraction of rows in each resample, strictly between 0 and 1.

patienceint, default 16

Window, in trials, of the patience stopping rule.

min_improvementfloat, default 0.01

Smallest gain of the best score over patience trials that keeps the search running.

prunebool, default True

Whether convergence trials may be median-pruned.

n_complete_prunedint, default 3

Largest number of promising pruned trials completed after the search.

n_rescoreint, default 3

Top complete trials re-scored on the fresh plan, together with the default.

n_null_rescoreint, default 3

Structureless copies on which each candidate is re-scored. Zero also drops the copy scored during the search.

gap_family{“gaussian_copula”, “independent_marginals”} or None, default “gaussian_copula”

Generator of the structureless copies behind the gap, or None to score the data alone.

n_worldsint, default 32

Possible worlds, between 2 and 32767.

world_fractionfloat, default 0.8

Fraction of rows each world draws without replacement.

null_familiestuple of str, default ()

Generator families of the matched null; empty skips it.

null_procedure{“exploration”, “full_search”}, default “exploration”

Search procedure replayed on each null realisation.

n_null_maxint, default 19

Largest number of null realisations per family.

null_exceedancesint, default 3

Exceedances at which the sequential null rule stops a family.

alphafloat, default 0.05

Declared level of the matched null.

consensus_budget_bytesint, default 512 * 2**20

Largest size, in bytes, of the dense co-association matrix of the consensus check.

consensus_check_rowsint, default 4096

Subset size of the consensus check when all rows exceed the budget.

check_backendsbool, default False

Whether to compare the CPU and cuML fits of the deployed configuration.

Raises:
ValueError

If a range is empty or reaches zero on a log axis, n_explore is not a power of two, n_null_max cannot reach alpha, or a budget or option is outside its allowed values.

class starfold.Space(n_neighbors=(5, 100), min_dist=(0.0, 0.5), n_components=(2, 10), min_cluster_size=None, min_samples_fraction=(0.05, 1.0), selection_method=('eom', 'leaf'))[source]

Search space bounds, with trial 0 the library default clipped into them.

Attributes:
n_neighborstuple of int

Log-uniform bounds. The upper bound may not exceed 100 (the width of the cached neighbour graph) and is capped at m - 1 per fit.

min_disttuple of float

Uniform bounds.

n_componentstuple of int

Uniform integer bounds.

min_cluster_sizetuple of int or None

Log-uniform bounds, [5, min(max(50, n // 20), 1023)] when None.

min_samples_fractiontuple of float

Log-uniform bounds of min_samples / min_cluster_size.

selection_methodtuple of str

Categorical choices among eom and leaf.

Run one stage

search runs the search alone. null_test runs the calibration test for a finished search. generate_null draws one structureless copy of a table.

starfold.search.search(x, *, config, random_state, engine, n_jobs=1, exploration_only=False)[source]

Run the joint search and select by the fresh gap over the null.

Every trial is scored on one resample plan with common random numbers (Glasserman and Yao 1992, doi:10.1287/mnsc.38.6.884). Trial 0 is default_in_space() and trials 1 to n_explore are the Sobol design, followed by multivariate TPE (Bergstra et al. 2011, NeurIPS 24; Akiba et al. 2019, arXiv:1907.10902), all enqueued into one study for the surrogate to be built from complete evaluations. Convergence trials report the leading-pair score after two fits and may be median-pruned (median stopping rule, Golovin et al. 2017, doi:10.1145/3097983.3098043), while design trials report it too but are never pruned, giving the pruner a median from the first convergence trial onwards. The search stops when the best score improves by less than min_improvement over patience trials, or at n_trials. Pruned trials whose leading-pair score exceeds the best complete gap are then completed, given that the data score bounds the gap from above (the null score is non-negative). The top n_rescore trials plus the default are re-scored on a fresh plan and fresh null matrices, and the largest fresh gap is selected. The fresh scores reduce the winner’s curse of the search scores but do not remove it: the selected gap is still the largest of up to n_rescore + 1 fresh gaps, the default’s included, so it remains biased upwards relative to the default’s.

Parameters:
xndarray of shape (n, d)

Validated feature matrix.

configConfig

Search controls.

random_stateint

Seed of both plans, the null matrices, the Sobol scrambling and the sampler.

engine{“cpu”, “cuml”}

Resolved backend.

n_jobsint, default 1

Worker processes inside a trial.

exploration_onlybool, default False

Run trials 0 to n_explore only, without pruning, completion or fresh re-scoring. selected is then their best, the reported scores are search scores and candidates is empty. The exploration null procedure uses this mode.

Returns:
SearchResult

Selected configuration, trial table, candidates and counters.

Raises:
ValueError

If engine is not "cpu" or "cuml", x is not two-dimensional, n_trials < n_explore + 1, or resolve_space() rejects the space.

ImportError

If engine="cuml" and the cuML libraries cannot be imported.

starfold.null_test(X, search_result, *, config=None, families=('gaussian_copula',), random_state=0, engine='auto', n_jobs=1)[source]

Run the matched null for a completed search, separately from recover.

Parameters:
Xarray-like of shape (n_samples, n_features)

The finite matrix the search used.

search_resultSearchResult

The search whose observed statistic is calibrated.

configConfig, optional

Configuration of the search, Config() when None. It must match the search for the replay to be matched.

familiestuple of str, default (“gaussian_copula”,)

Generator families, replacing config.null_families.

random_stateint, default 0

Seed of the replayed search and of the null realisations. It must match the search.

engine{“auto”, “cpu”, “cuml”}, default “auto”

Backend of the replayed search. It must match the search.

n_jobsint, default 1

As in recover. Above 20000 rows per resample it must also match the search, because the approximate neighbour graph depends on it.

Returns:
NullEvidence

Matched null outcome per generator family.

Raises:
ValueError

If X is invalid or has a non-finite row, a family is unknown, a configuration value is invalid, n_jobs < 1, or engine is not a supported value.

ImportError

If engine="cuml" and cuML cannot be used.

starfold.generate_null(x, family, seed)[source]

Draw one null matrix from a declared family.

Parameters:
xndarray of shape (n_samples, n_features)

Finite observed feature matrix.

family{“gaussian_copula”, “independent_marginals”}

Generator family.

seedint

Seed of the generator draw.

Returns:
ndarray of shape (n_samples, n_features)

Null matrix whose every column holds exactly the observed values of the corresponding input column, reordered.

Raises:
ValueError

If family is unknown or x is not a finite 2-D matrix.

Compare backends

compare_backends fits one setting on the CPU and on cuML and reports how well the two partitions agree. default_params returns the library defaults.

starfold.compare_backends(x, params, *, scaling='standard', n_seeds=3, random_state=0)[source]

Fit the same configuration on both backends and report partition agreement.

Backends are compared by the agreement of their partitions, never by exact labels, because their layouts differ in floating-point order.

Parameters:
xndarray of shape (n, d)

Feature matrix; validated with validate_matrix.

paramsParams

Configuration fitted on the full row set.

scaling{“standard”, “robust”}, default “standard”

Scaler family.

n_seedsint, default 3

Seeds derive_seed(random_state, 7, s) for s < n_seeds.

random_stateint, default 0

Base seed.

Returns:
BackendAgreement

Per-seed agreement and group counts.

Raises:
ImportError

If cuML is not usable in this process.

ValueError

If n_seeds < 1 or x fails validation.

starfold.default_params()[source]

Return the library defaults of umap-learn and hdbscan.

Returns:
Params

Params(15, 0.1, 2, 5, 5, "eom"), used as trial 0 of every search after clipping into the declared space.

Save and load

save writes a result to a directory with checksums. load checks them and rebuilds the result. The files are listed in Saved result files.

starfold.save(result, path)[source]

Persist a result as a checksummed directory.

Parameters:
resultResult

Result to persist.

pathstr or Path

Target directory, created if absent. Existing files are overwritten.

Returns:
Path

The directory written.

starfold.load(path)[source]

Load a persisted result, verifying checksums and re-deriving flags.

Parameters:
pathstr or Path

Directory written by save().

Returns:
Result

The rebuilt result.

Raises:
ValueError

If the manifest is unreadable or incomplete, a checksum does not match, the format is unknown, the support identity fails, or the stored flags differ from the re-derived ones.

Result classes

Result holds everything recover returns. The other classes hold its parts. Each field is explained in Result fields.

class starfold.Result(labels, strengths, default_labels, kept_rows, params, deployed_params, default_params, search, worlds, consensus, null, backends, flags, provenance)[source]

Complete outcome of starfold.recover().

Attributes:
labelsndarray of int32, shape (n_kept,)

Emitted partition, one full-data fit of deployed_params, with -1 for noise.

strengthsndarray of float32, shape (n_kept,)

HDBSCAN within-fit strengths of that fit, not posteriors.

default_labelsndarray of int32, shape (n_kept,)

One full-data fit of the library defaults, the external comparator.

kept_rowsndarray of intp, shape (n_kept,)

Row indices of the input matrix that were finite and used.

paramsParams

Configuration selected by the search, validated on resample rows.

deployed_paramsParams

Configuration that produced labels: params with the minimum cluster mass rescaled from the resample row count to the full row count, equal to params when the two counts agree.

default_paramsParams

The library defaults, fitted at full size as the external comparator.

searchSearchResult

Trial table, candidates, fresh scores and the beats-default statement.

worldsWorldEvidence

Recurrence support, unresolved mass, group recurrence, count and property stability intervals.

consensusConsensusCheck

Bounded label-invariant co-association check on the reference.

nullNullEvidence

Matched null calibration.

backendsBackendAgreement or None

Backend agreement when compare_backends ran.

flagstuple of str

Machine-readable flags from FLAG_VOCABULARY.

provenancedict

Engines, versions, configuration, seeds, budgets, fit counts, wall time per stage, peak memory and the input fingerprint.

property n_groups

Number of groups in the emitted partition.

property support

Per-row recurrence support over reference groups, shape (n_kept, G).

property unresolved_mass

Mean unresolved mass over sampled rows.

class starfold.SearchResult(selected, trials, candidates, score_selected, score_default, gap_selected, gap_default, paired_differences, beats_default_under_objective, selected_is_default, exploration_max, stop_reason, n_completed, n_pruned, n_completed_after_prune, n_fits, seconds, plan)[source]

Outcome of search(). Every score is the objective, never agreement with truth.

In a full search, gap_selected and gap_default are the fresh scores minus the mean score of the same configuration on the fresh null matrices, the gap statistic that selects the configuration (Tibshirani, Walther and Hastie 2001, doi:10.1111/1467-9868.00293). Both equal the fresh scores when no null matrix was scored. In exploration-only mode nothing is re-scored: both gaps, like score_selected and score_default, are search scores on the common plan.

Attributes:
selectedParams

Selected configuration.

trialstuple of TrialRecord

Every trial, in trial-number order.

candidatestuple of Candidate

Re-scored candidates, largest gap first; empty in exploration-only mode.

score_selectedfloat

Fresh score of the selected configuration, or its search score in exploration-only mode.

score_defaultfloat

Fresh score of the default, or its search score in exploration-only mode.

gap_selectedfloat

Fresh gap of the selected configuration, or its search score in exploration-only mode.

gap_defaultfloat

Fresh gap of the default, or its search score in exploration-only mode.

paired_differencestuple of float

Fresh pair scores of the selected configuration minus those of the default; empty in exploration-only mode.

beats_default_under_objectivebool

Whether gap_selected exceeds gap_default.

selected_is_defaultbool

Whether the selected configuration is trial 0.

exploration_maxfloat

Largest complete search score among the default and design trials, 0.0 when none completed.

stop_reason{“patience”, “budget”, “exploration_only”}

Why the search stopped.

n_completedint

Complete trials, completed pruned trials included.

n_prunedint

Trials that remain pruned.

n_completed_after_pruneint

Pruned trials completed after the search.

n_fitsint

UMAP and HDBSCAN fits the search ran.

secondsfloat

Wall time of the search.

planResamplePlan

Common resample plan of the search scores.

class starfold.WorldEvidence(world_labels, n_sampled, support, unresolved, own_support, unresolved_mass, group_recurrence, group_recurrence_band, count_values, count_interval, count_reference, property_median, property_band, property_propagated, world_agreement, world_seeds, world_errors, n_fits, seconds)[source]

Recurrence evidence of a reference partition over possible worlds.

Attributes:
world_labelsndarray of shape (W, n), dtype int16

Per world, -2 for a row the world did not sample, -1 for world noise, else the world cluster id.

n_sampledndarray of shape (n,), dtype uint16

Number of worlds that sampled each row (the evidence coverage).

supportndarray of shape (n, G), dtype float32

Purity-weighted recurrence of each row landing with the members of each reference group, averaged over the worlds that sampled the row. NaN for rows no world sampled.

unresolvedndarray of shape (n,), dtype float32

Mean mass a row placed on world noise or on reference-noise company, with support.sum(1) + unresolved == 1 on every sampled row.

own_supportndarray of shape (n,), dtype float32

support[i, labels[i]] for reference-assigned rows, NaN for reference noise.

unresolved_massfloat

Mean of unresolved over sampled rows.

group_recurrencendarray of shape (G,), dtype float32

Mean over worlds of the best Jaccard match of each reference group (Hennig 2007, doi:10.1016/j.csda.2006.11.025). NaN when no world sampled a member.

group_recurrence_bandndarray of shape (G, 2), dtype float32

5th and 95th percentiles of the per-world Jaccard match, a stability interval.

count_valuesndarray of shape (W,), dtype int16

Number of clusters found in each world.

count_intervaltuple of int

Integer hull of the 5th and 95th percentiles of count_values, a stability interval and never a confidence interval.

count_referenceint

Number of groups in the reference partition.

property_medianndarray of shape (G, d), dtype float64

Median over worlds of the per-feature median of the world cluster matched to each group, in original units. NaN when never matched.

property_bandndarray of shape (G, d, 2), dtype float64

5th and 95th percentiles over worlds of the same per-world medians.

property_propagatedbool

Whether the world features carried measurement draws.

world_agreementndarray of shape (W,), dtype float32

Adjusted Rand index, floored at 0, times joint coverage between each world and the reference on the world’s rows.

world_seedstuple of int

UMAP seed of each world.

world_errorstuple of str

Exception text of each world whose fit raised, empty otherwise.

n_fitsint

Number of world fits attempted.

secondsfloat

Wall time of the stage.

class starfold.NullEvidence(families, statistic_name, observed, values, n_realisations, exceedances, p_values, p_intervals, p_value, alpha, structure_supported, stopped_early, skipped_reason, n_fits, seconds)[source]

Outcome of a matched null test over one or more generator families.

Attributes:
familiestuple of str

Generator families in the order they were run.

statistic_namestr

Name of the statistic the caller supplied: exploration_design_max or full_search_max.

observedfloat

Observed statistic on the data.

valuestuple of tuple of float

Null statistics per family, in generation order.

n_realisationstuple of int

Realisations generated per family (the sequential rule may stop early).

exceedancestuple of int

Count of null statistics at or above observed per family.

p_valuestuple of float

Add-one Monte Carlo p-value per family.

p_intervalstuple of tuple of float

Nominal 95 percent Clopper-Pearson interval on the exceedance proportion per family, describing Monte Carlo precision only.

p_valuefloat

Composite p-value, the maximum over families (least favourable).

alphafloat

Declared level.

structure_supportedbool

p_value <= alpha. Never a probability that groups are real.

stopped_earlytuple of bool

Whether the sequential rule stopped a family before n_null_max.

skipped_reasonstr or None

null_not_run when no family was declared, observed_statistic_zero when the observed statistic is zero, else None.

n_fitsint

Fits spent on the realisations in values.

secondsfloat

Wall time of the stage.

class starfold.BackendAgreement(agreement, mean_agreement, ari, coverage, assigned_cpu, assigned_cuml, normalised, mean_normalised, n_groups_cpu, n_groups_cuml)[source]

Partition agreement between the CPU and cuML backends.

Attributes:
agreementtuple of float

Per seed, adjusted Rand index times joint coverage between the two fits.

mean_agreementfloat

Mean of agreement.

ari, coveragetuple of float

The two factors of agreement per seed. A low product can mean that the backends disagree or only that few rows are assigned by both.

assigned_cpu, assigned_cumltuple of float

Fraction of rows each backend assigned, per seed.

normalisedtuple of float

ari * coverage / min(assigned_cpu, assigned_cuml) per seed: agreement relative to the most the assigned fractions allow, so a configuration that leaves most rows as noise is not read as backend disagreement. Equal to 1 when neither backend assigns a row and 0 when only one does.

mean_normalisedfloat

Mean of normalised, read by the backend_disagreement flag.

n_groups_cpu, n_groups_cumltuple of int

Per-seed group counts on each backend.

class starfold.Params(n_neighbors, min_dist, n_components, min_cluster_size, min_samples, selection_method)[source]

One complete UMAP and HDBSCAN configuration.

Attributes:
n_neighborsint

UMAP neighbourhood size, at least 2.

min_distfloat

UMAP minimum embedding distance in [0, 1].

n_componentsint

Embedding dimension, at least 1.

min_cluster_sizeint

HDBSCAN minimum cluster size in rows, at least 2.

min_samplesint

HDBSCAN core-distance neighbour count in [1, min_cluster_size].

selection_method{“eom”, “leaf”}

HDBSCAN cluster selection rule.

Raises:
ValueError

If a field lies outside the range stated above.

to_dict()[source]

Return the fields as a JSON-ready mapping.

Returns:
dict[str, object]

Field names to values.

classmethod from_dict(d)[source]

Rebuild a configuration from a mapping such as a JSON record.

Parameters:
dmapping

Field names to values, with integral floats accepted for int fields.

Returns:
Params

Validated configuration.

Raises:
ValueError

If a field is missing, non-numeric, non-integral, or out of range.