Narrow the search space¶
This guide shows how to set the ranges of the six setting axes that Optuna searches, and explains why the library defaults are always trial 0.
Prerequisites¶
A prepared table (Prepare your table for recover).
A reason to narrow a range. Examples: you know that groups smaller than 30 rows are not of interest, or a setting produced hundreds of tiny groups.
The fields of Space¶
starfold.Space holds inclusive bounds. The defaults are the values you get with Space().
Field |
Default bounds |
Scale |
What narrowing does |
|---|---|---|---|
|
(5, 100) |
log |
A higher floor removes fine local detail. The upper bound may not exceed 100 and is capped at the resample size minus 1. |
|
(0.0, 0.5) |
linear |
A higher floor packs similar rows less tightly in the embedding. |
|
(2, 10) |
linear, integer |
Fewer dimensions give a simpler map. |
|
|
log |
A higher floor forbids small groups. A lower ceiling forbids large ones. |
|
(0.05, 1.0) |
log |
The ratio |
|
(“eom”, “leaf”) |
categorical |
|
The 1,023 cap on min_cluster_size is the cuML limit on min_samples. It keeps the CPU and GPU searches the same. Here n is the number of kept rows.
Steps¶
Build the space. Change only the fields you have a reason to change.
import starfold space = starfold.Space(min_cluster_size=(30, 200), selection_method=("eom",))
Put the space in a
Configand run.config = starfold.Config(space=space) result = starfold.recover(X, config=config, random_state=0)
Read what trial 0 became. The search moves the library default into your bounds.
trial0 = next(t for t in result.search.trials if t.number == 0) print(trial0.params)
With the bounds above, trial 0 takes
min_cluster_size=30(the nearest bound to the default 5). It keeps the default fractionmin_samples / min_cluster_sizeof 1, somin_samplesbecomes 30 as well.Keep the same
config, including the space, for every call that has to match the run. Run the calibration test replays the search, and a different space gives a different replay.
Expected result¶
result.params and result.deployed_params lie inside your bounds, except that deployed_params rescales min_cluster_size and min_samples from the resample size to the full row count. For the recorded Digits run the two tables differ in exactly this way (min_cluster_size 11 and min_samples 9 in params, 14 and 11 in deployed_params).
A bound that makes a range empty, or that reaches zero on a log axis, raises ValueError when you build the Config. An n_neighbors bound above 100 raises the same error.
Why the defaults are trial 0¶
Trial 0 of every search is the library default (n_neighbors=15, min_dist=0.1, n_components=2, min_cluster_size=5, min_samples=5, selection_method="eom"), clipped into your space. The search therefore always scores the answer you would get without Starfold. At the end the search re-scores the best three trials and trial 0 on new resamples (a fresh re-score). If trial 0 wins, result.flags contains selected_is_default. If the winner and trial 0 differ by less than the noise, it contains default_within_noise. Both flags are listed in Flags.
In the recorded Digits run, trial 0 had a fresh gap of 0.565 and the chosen trial 33 had 0.661.
Variations¶
To forbid small groups, raise the floor of
min_cluster_sizeand keep the ceiling of the data rule. For 2,000 kept rows the rule gives 100, soSpace(min_cluster_size=(30, 100))does it.To search wider than the defaults, you cannot raise
n_neighborspast 100, because the search caches one neighbour graph of that width.