Made NearPy.query actually do something with the provided value of n
This is a bit of a hack: NearPy requires that filters be installed at
instantiation time, so we create and install one of our own and then
reconfigure it on the fly with the right value of n
from __future__ import absolute_import
import nearpy
+from nearpy.filters import NearestFilter
import sklearn.preprocessing
from ann_benchmarks.algorithms.base import BaseANN
@@ -8,6 +9,7 @@ class NearPy(BaseANN):
self._n_bits = n_bits
self._hash_counts = hash_counts
self._metric = metric
+ self._filter = NearestFilter(10)
self.name = 'NearPy(n_bits=%d, hash_counts=%d)' % (n_bits, hash_counts)
def fit(self, X):
@@ -19,9 +21,15 @@ class NearPy(BaseANN):
if self._metric == 'euclidean':
dist = nearpy.distances.EuclideanDistance()
- self._nearpy_engine = nearpy.Engine(X.shape[1], lshashes=hashes, distance=dist)
+ self._nearpy_engine = nearpy.Engine(
+ X.shape[1],
+ lshashes=hashes,
+ distance=dist)
else: # Default (angular) = Cosine distance
- self._nearpy_engine = nearpy.Engine(X.shape[1], lshashes=hashes)
+ self._nearpy_engine = nearpy.Engine(
+ X.shape[1],
+ lshashes=hashes,
+ vector_filters=[self._filter])
if self._metric == 'angular':
X = sklearn.preprocessing.normalize(X, axis=1, norm='l2')
@@ -29,6 +37,9 @@ class NearPy(BaseANN):
self._nearpy_engine.store_vector(x, i)
def query(self, v, n):
+ # XXX: This feels like an unpleasant hack, but it's not clear how to do
+ # better without making changes to NearPy
+ self._filter.N = n
if self._metric == 'angular':
v = sklearn.preprocessing.normalize([v], axis=1, norm='l2')[0]
return [y for x, y, z in self._nearpy_engine.neighbours(v)]
