You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python环境下支持增量更新的最近邻搜索应用设计咨询

Python中支持增量更新的最近邻搜索方案

刚好之前做过类似的需求,来给你梳理下可行的方案——首先得明确:scikit-learn的NearestNeighbors模块本身不支持原生的增量更新,它的索引是一次性构建的,新数据进来后只能重新拟合整个模型,数据量大的时候这会慢到没法用,完全不符合你要的增量场景。下面给你推荐几种适配增量更新的实现思路:

1. 优先选择支持增量的近似最近邻(ANN)库

大部分业务场景下,近似最近邻的精度完全能满足需求,而且这类库几乎都原生支持增量更新,速度和效率远优于精确最近邻的增量方案。

a. FAISS(Facebook AI Similarity Search)

这是目前最流行的ANN库,速度快、精度可调,对增量更新的支持非常友好,不管是单条还是批量添加新数据都很顺畅。
示例代码:

import faiss
import numpy as np

# 初始化索引:这里用L2距离的精确索引,数据维度设为128(根据你的数据调整)
dimension = 128
index = faiss.IndexFlatL2(dimension)

# 导入初始数据
initial_data = np.random.rand(1000, dimension).astype('float32')
index.add(initial_data)

# 增量添加新数据
new_data = np.random.rand(200, dimension).astype('float32')
index.add(new_data)

# 查询top5最近邻
query = np.random.rand(1, dimension).astype('float32')
distances, indices = index.search(query, k=5)
print("最近邻索引:", indices)
print("对应距离:", distances)

如果追求更快的查询速度,可以换成近似索引(比如IVFFlat),只需要提前训练一次索引,后续增量添加数据不需要重复训练。

b. Annoy(Approximate Nearest Neighbors Oh Yeah)

Spotify开发的轻量级ANN库,用法简单,同样支持动态添加数据,适合资源有限的场景。
示例代码:

from annoy import AnnoyIndex
import numpy as np

dimension = 128
# 初始化索引,指定距离度量(可选angular/euclidean等)
index = AnnoyIndex(dimension, 'euclidean')

# 添加初始数据
for i in range(1000):
    vector = np.random.rand(dimension)
    index.add_item(i, vector)

# 构建索引(n_trees越大精度越高,速度略慢)
index.build(10)

# 增量添加新数据
for i in range(1000, 1200):
    vector = np.random.rand(dimension)
    index.add_item(i, vector)
# 增量添加后可以重新build一次优化性能,不重新build也能正常查询
index.build(10, n_jobs=-1)

# 查询top5最近邻
query = np.random.rand(dimension)
indices = index.get_nns_by_vector(query, 5)
print("最近邻索引:", indices)

2. 若必须用精确最近邻的增量更新

如果业务要求必须是精确最近邻,有两种思路:

  • 手动维护数据矩阵:数据量极小的时候(比如几千条以内),可以每次新数据进来就追加到矩阵里,查询时用sklearn.metrics.pairwise_distances计算所有距离再取topn,但数据量一增长查询速度会暴跌,不推荐用于生产环境。
  • 用pynndescent:这个库主要做近似最近邻,但也支持精确模式下的增量更新,不过效率不如FAISS的精确索引。

关于scikit-learn的临时替代方案

如果你的数据量很小,只是临时测试,可以勉强用sklearn的NearestNeighbors,每次新数据进来就重新拟合:

from sklearn.neighbors import NearestNeighbors
import numpy as np

# 初始拟合模型
X = np.random.rand(1000, 128)
nn_model = NearestNeighbors(n_neighbors=5, metric='euclidean')
nn_model.fit(X)

# 增量更新:重新拼接数据再拟合(数据量大时极慢)
new_X = np.random.rand(200, 128)
X = np.vstack([X, new_X])
nn_model.fit(X)

# 查询
query = np.random.rand(1, 128)
distances, indices = nn_model.kneighbors(query)

但这种方法完全没有增量更新的优势,数据量上去后肯定会卡,所以只适合小数据量的测试场景。

内容的提问来源于stack exchange,提问作者beginner_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:26:38