Skip to content

Top level

Module-level helpers and the exception type. The estimators are documented under Estimators.

evoc_rs

EVoC clustering for high-dimensional embeddings, in Rust.

EVoC clusters embedding vectors (CLIP, sentence transformers, single-cell latent spaces) by embedding the kNN graph first and running density-based clustering on that embedding, rather than on the original space. The result is a hierarchy of clusterings ranked by persistence, not one labelling.

>>> import numpy as np, evoc_rs
>>> rng = np.random.default_rng(0)
>>> X = np.vstack([rng.normal(c * 20, 1, (300, 32)) for c in range(4)])
>>> model = evoc_rs.EVoC(n_neighbours=15).fit(X.astype(np.float32))
>>> model.labels_            # the most persistent layer
>>> model.cluster_layers_    # every layer, finest first
>>> model.persistence_scores_

Already know how many clusters you want? Pass approx_n_clusters and the finest layer is binary-searched for it, returning a single layer.

This is a port of TutteInstitute's evoc. Where behaviour diverges, the Python original is the source of truth.

EvocError

Bases: Exception

NotFittedError

Bases: ValueError, AttributeError

Raised when a fitted attribute is read before fit.

Inherits from both ValueError and AttributeError to match sklearn.exceptions.NotFittedError, so code catching either still works.

gpu_available builtin

gpu_available() -> bool

Whether the GPU kNN backends can be used here.

Returns

True only when this build has the gpu feature and wgpu resolves an adapter. Safe to call on any machine.

Note

Acquiring a client panics rather than erroring when no adapter is found, so the probe catches it. That is sound here because the release profile is pinned to panic = "unwind", which pyo3 requires anyway. The panic hook is silenced for the duration, otherwise merely asking the question prints a backtrace to stderr.

num_threads builtin

num_threads() -> int

Threads the Rust core will use for the next call.

Returns

The override thread count if one is set, otherwise rayon's global count.

set_num_threads builtin

set_num_threads(n: int) -> None

Cap the threads the Rust core uses.

Params
  • n - Thread count, or 0 to drop the override and go back to rayon's default of one thread per core.

Parameter introspection

get_params and set_params are reimplemented rather than inherited from scikit-learn, so clone, GridSearchCV and Pipeline all work by duck-typing without scikit-learn being an install requirement.

_base

Shared estimator behaviour.

get_params and set_params introspect the subclass __init__, which is all sklearn.base.BaseEstimator does. Doing it here keeps scikit-learn out of the install requirements while clone, GridSearchCV and Pipeline still work by duck-typing.

BaseEstimator

Parameter introspection shared by every estimator here.

Subclasses store their constructor arguments verbatim on self under the same names. That is the whole contract; nothing else is inspected.

get_params

get_params(deep: bool = True) -> dict[str, Any]

Constructor arguments as a dict.

Parameters:

Name Type Description Default
deep bool

Accepted for scikit-learn compatibility. These estimators hold no nested estimators, so it changes nothing.

True

Returns:

Type Description
dict[str, Any]

Mapping from parameter name to its current value.

set_params

set_params(**params: Any) -> BaseEstimator

Set constructor arguments in place.

Parameters:

Name Type Description Default
**params Any

Parameter names and their new values.

{}

Returns:

Type Description
BaseEstimator

The estimator, so calls chain.

Raises:

Type Description
ValueError

If a name is not a constructor parameter.

Version strings

__version__ is this wheel. __core_version__ is the evoc-rs crate it vendored. The two version independently, so the second is the one that tells you what the numerics are.

import evoc_rs

evoc_rs.__version__, evoc_rs.__core_version__