Precision annoy.AnnoyIndex with examples#

An example showing the AnnoyIndex class.

from __future__ import print_function

import random; random.seed(0)
import time

# from annoy import AnnoyIndex
# from scikitplot.annoy import AnnoyIndex
from scikitplot.annoy import Index as AnnoyIndex

try:
    from tqdm.auto import tqdm, trange
except ImportError:
    # Fallback: dummy versions that ignore all args/kwargs
    tqdm = lambda iterable, *args, **kwargs: iterable
    trange = lambda n, *args, **kwargs: range(n)

n, f = 1_000_000, 100 # 100~2.5GB

n, f = 1_000, 100  # 100~0.25GB 256~0.6GB


idx = AnnoyIndex(
    f=f,
    metric='angular',
)
idx.set_seed(0)
for i in trange(n):
    if(i % (n//10) == 0): print(f"{i} / {n} = {1.0 * i / n}")
    # v = []
    # for z in range(f):
    #     v.append(random.gauss(0, 1))
    v = [random.gauss(0, 1) for _ in range(f)]
    idx.add_item(i, v)

idx.build(2 * f)
idx.save('test.annoy')
idx.info()
/work/galleries/examples/annoy/plot_precision_script.py:37: UserWarning:

seed=0 resets to Annoy's default seed


  0%|          | 0/1000 [00:00<?, ?it/s]0 / 1000 = 0.0
100 / 1000 = 0.1
200 / 1000 = 0.2
300 / 1000 = 0.3
400 / 1000 = 0.4
500 / 1000 = 0.5
600 / 1000 = 0.6
700 / 1000 = 0.7
800 / 1000 = 0.8

 88%|████████▊ | 877/1000 [00:00<00:00, 8541.28it/s]900 / 1000 = 0.9

100%|██████████| 1000/1000 [00:00<00:00, 7380.78it/s]

{'f': 100, 'metric': 'angular', 'n_neighbors': 5, 'on_disk_path': 'test.annoy', 'prefault': False, 'seed': None, 'verbose': None, 'schema_version': 0, 'n_items': 1000, 'n_trees': 200, 'memory_usage_byte': 5722240, 'memory_usage_mib': 5.4571533203125}
def plot(idx, y=None, **kwargs):
    import numpy as np
    import matplotlib.pyplot as plt
    import scikitplot.cexternals._annoy._plotting as utils

    single = np.zeros(idx.get_n_items(), dtype=int)
    if y is None:
        double = np.random.uniform(0, 1, idx.get_n_items()).round()

    # single vs double
    fig, ax = plt.subplots(ncols=2, figsize=(12, 5))
    alpha = kwargs.pop("alpha", 0.8)
    y2 = utils.plot_annoy_index(
        idx,
        dims = list(range(idx.f)),
        plot_kwargs={"draw_legend": False},
        ax=ax[0],
    )[0]
    utils.plot_annoy_knn_edges(
        idx,
        y2,
        k=1,
        line_kwargs={"alpha": alpha},
        ax=ax[1],
    )

# idx.unbuild()
# idx.build(10)
plot(idx)
plot precision script
def precision(q):
  limits = [10, 100, 1_000]
  k = 10
  prec_n = 10
  prec_sum = {}
  time_sum = {}

  for i in trange(prec_n):
    j = random.randrange(0, n)
    closest = set(q.get_nns_by_item(j, k, n))
    for limit in limits:
        t0 = time.time()
        toplist = q.get_nns_by_item(j, k, limit)
        T = time.time() - t0

        found = len(closest.intersection(toplist))
        hitrate = 1.0 * found / k
        prec_sum[limit] = prec_sum.get(limit, 0.0) + hitrate
        time_sum[limit] = time_sum.get(limit, 0.0) + T

        print('limit: %-9d precision: %6.2f%% avg time: %.6fs'
              % (limit, 100.0 * prec_sum[limit] / (i + 1), time_sum[limit] / (i + 1)))
q = AnnoyIndex(f, 'angular')
q.set_seed(0)
q.load('test.annoy')
precision(q)
/work/galleries/examples/annoy/plot_precision_script.py:110: UserWarning:

seed=0 resets to Annoy's default seed


  0%|          | 0/10 [00:00<?, ?it/s]limit: 10        precision:  20.00% avg time: 0.000070s
limit: 100       precision:  40.00% avg time: 0.000075s
limit: 1000      precision: 100.00% avg time: 0.000239s
limit: 10        precision:  35.00% avg time: 0.000068s
limit: 100       precision:  45.00% avg time: 0.000073s
limit: 1000      precision: 100.00% avg time: 0.000260s
limit: 10        precision:  36.67% avg time: 0.000063s
limit: 100       precision:  53.33% avg time: 0.000073s
limit: 1000      precision: 100.00% avg time: 0.000237s
limit: 10        precision:  37.50% avg time: 0.000062s
limit: 100       precision:  52.50% avg time: 0.000073s
limit: 1000      precision: 100.00% avg time: 0.000227s
limit: 10        precision:  38.00% avg time: 0.000062s
limit: 100       precision:  54.00% avg time: 0.000072s
limit: 1000      precision: 100.00% avg time: 0.000221s
limit: 10        precision:  40.00% avg time: 0.000066s
limit: 100       precision:  53.33% avg time: 0.000073s
limit: 1000      precision: 100.00% avg time: 0.000217s
limit: 10        precision:  38.57% avg time: 0.000066s
limit: 100       precision:  54.29% avg time: 0.000078s
limit: 1000      precision: 100.00% avg time: 0.000215s
limit: 10        precision:  38.75% avg time: 0.000065s
limit: 100       precision:  52.50% avg time: 0.000077s
limit: 1000      precision: 100.00% avg time: 0.000213s
limit: 10        precision:  38.89% avg time: 0.000064s
limit: 100       precision:  54.44% avg time: 0.000076s
limit: 1000      precision: 100.00% avg time: 0.000211s
limit: 10        precision:  39.00% avg time: 0.000064s
limit: 100       precision:  55.00% avg time: 0.000076s
limit: 1000      precision: 100.00% avg time: 0.000208s

100%|██████████| 10/10 [00:00<00:00, 1436.21it/s]

Tags: model-workflow: vector-db plot-type: bar level: beginner purpose: showcase

Total running time of the script: (0 minutes 11.810 seconds)

Related examples

Simple annoy.AnnoyIndex with examples

Simple annoy.AnnoyIndex with examples

annoy.Index to NPY or CSV with examples

annoy.Index to NPY or CSV with examples

Mmap annoy.AnnoyIndex with examples

Mmap annoy.AnnoyIndex with examples

annoy.Annoy legacy c-api with examples

annoy.Annoy legacy c-api with examples

Gallery generated by Sphinx-Gallery