mojolearn.IVFIndex#
- class mojolearn.IVFIndex(n_lists, n_probes, n_neighbors=8, kmeans_n_iters=20, metric='sqeuclidean', random_state=0)[source]#
Bases:
NumericModeMixinApproximate nearest-neighbor index with inverted lists (IVF-Flat).
Follows cuVS’s
ivf_flat.fittrains a k-means coarse quantizer that splits the rows inton_listslists and stores the rows uncompressed, grouped by list.searchscans then_probeslists nearest each query and returns exact distances to the rows in those lists, so recall depends only onn_probes. Results are reproducible. On a GPU the fitted index stays on the device between searches; each search uploads only its queries.IVFFlatis another name for this class.- Parameters:
n_lists (int) – Number of inverted lists (k-means clusters). Must be at least 1.
n_probes (int) – Number of lists scanned per query. Required, with no default; a value greater than
n_listsraises an error rather than being clamped.n_neighbors (int, default 8) – Number of neighbors
searchreturns per query.kmeans_n_iters (int, default 20) – k-means iterations for the coarse quantizer.
metric ({‘sqeuclidean’, ‘euclidean’}, default ‘sqeuclidean’) – ‘sqeuclidean’ (cuVS
L2Expanded) returns squared Euclidean distances; ‘euclidean’ (cuVSL2SqrtExpanded) returns their square roots. ‘l2_expanded’ is accepted for ‘sqeuclidean’, and ‘l2_sqrt_expanded’ and ‘l2’ for ‘euclidean’. The metric is fixed when the index is built: on one index the ids are the same under both, but the k-means quantizer trains differently under each, so two indexes built with different metrics can return different neighbors whenn_probes < n_lists.random_state (int, default 0) – Seed for the k-means initialization.
numeric_mode (str or None, default None) – Numeric mode for this estimator; None uses the package default set with
mojolearn.set_numeric_mode.
- Variables:
centers_ (ndarray of shape (n_lists, n_features), float32) – Coarse quantizer centers.
center_norms_ (ndarray of shape (n_lists,), float32) – Squared norm of each center.
list_offsets_ (ndarray of shape (n_lists + 1,), int32) – Start of each list in
list_indices_andlist_data_.list_indices_ (ndarray of shape (
n_rows_,), int32) – Original row ids, grouped by list and ascending within each list.list_data_ (ndarray of shape (
n_rows_, n_features), float32) – The indexed rows, in the order oflist_indices_.n_features_in_ (int) – Number of features seen during
fit.n_rows_ (int) – Number of indexed rows, including rows added by
extend.n_lists_ (int) – The fitted value of
n_lists.metric_code_ (int) – The metric the index was built under: 0 for ‘sqeuclidean’, 1 for ‘euclidean’.
n_candidates_ (ndarray of shape (n_queries,), int32) – Set by
search: how many indexed rows each query scanned.extend_labels_ (ndarray of shape (n_new,), int32) – Set by
extend: the list each new row joined.
- Raises:
TypeError – If an integer parameter is not an int.
ValueError – If
n_listsis less than 1 ormetricis unknown.
Examples
>>> import numpy as np, mojolearn >>> X = np.random.default_rng(0).random((1000, 8), dtype=np.float32) >>> index = mojolearn.IVFIndex(n_lists=16, n_probes=4, n_neighbors=5).fit(X) >>> distances, indices = index.search(X[:10]) >>> indices.shape (10, 5)
- __init__(n_lists, n_probes, n_neighbors=8, kmeans_n_iters=20, metric='sqeuclidean', random_state=0)[source]#
Methods
extend(X)Add the rows of
Xto the built index.fit(X[, y])Build the index from
X.get_params([deep])load(path)Load an index written by
save.numeric_mode_used()The numeric mode this estimator runs in.
save(path)Write the built index to
pathas an.npzfile.search(queries[, filter])Find the nearest indexed rows of each query within the probed lists.
set_params(**params)Set constructor parameters.
vendor_used()The GPU backend this estimator runs on.
- fit(X, y=None)[source]#
Build the index from
X.Building needs a GPU install; on a CPU-only install, load a saved index instead.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Rows to index, converted to float32.
y (None) – Ignored.
- Returns:
self (IVFIndex) – The fitted index.
- search(queries, filter=None)[source]#
Find the nearest indexed rows of each query within the probed lists.
- Parameters:
queries (array-like of shape (n_queries, n_features)) – Query rows, converted to float32.
filter (array-like of bool, shape (
n_rows_,), optional) – One flag per indexed row, by original row id; a row flagged False is never scored, returned or counted inn_candidates_(cuVS’s sample filter, applied before any distance is computed).
- Returns:
distances (ndarray of shape (n_queries, n_neighbors), float32) – Distances under
metric, ascending.indices (ndarray of shape (n_queries, n_neighbors), int32) – Original row ids of the neighbors.
- Raises:
ValueError – If the index is not fitted or loaded, the queries have a different number of features,
metricno longer names the metric the index was built under, orfilterhas the wrong shape or dtype.
Notes
Unlike the compressed IVF indexes, a query whose probed lists hold (after filtering) fewer than
n_neighborsrows raises an error rather than being padded. Raisen_probesif this happens.
- extend(X)[source]#
Add the rows of
Xto the built index.Follows cuVS’s
ivf_flat::extendwithadaptive_centers=False: each new row joins the list of its nearest center (an exact tie goes to the lower list id), and the centers do not move. The new rows take the idsn_rows_, ``n_rows_+ 1, …`` in the order given; unlike cuVS, custom ids are not accepted. Extending by a set of rows in one call or in several calls, in the same order, gives the same index. Works on a CPU-only install, since it trains nothing.- Parameters:
X (array-like of shape (n_new, n_features)) – Rows to add, converted to float32.
- Returns:
self (IVFIndex) – The extended index.
extend_labels_holds the list each new row joined.- Raises:
ValueError – If the index is not fitted or loaded,
Xhas a different number of features, ormetricno longer names the metric the index was built under.
- save(path)[source]#
Write the built index to
pathas an.npzfile.The file holds the index arrays, the parameters and the numeric mode. Reload it with
load; a loaded index searches without rebuilding, including on a CPU-only install.- Parameters:
path (str or path-like) – Destination file.
- Returns:
path (str or path-like) – The path written.
- Raises:
RuntimeError – If the index has not been fitted.
- classmethod load(path)[source]#
Load an index written by
save.Every array’s dtype and shape is checked on load; the list layout is checked at the first search.
- Parameters:
path (str or path-like) – File written by
save.- Returns:
index (IVFIndex) – A fitted index, ready to
searchorextend.- Raises:
ValueError – If the file was saved by another class or its contents do not match the IVF-Flat layout.