已有向量怎么做相似检索?用 NearestNeighbors 返回余弦距离与文档 ID

用现成向量建立小规模精确余弦检索,把矩阵行号映射到稳定文档 ID,并核对维度、零向量、距离方向与无答案情况。

已经有一组文档向量时,可以先用 NearestNeighbors 做小规模精确检索,不必为运行检查搭建数据库。它返回的是矩阵行号和距离;把行号映射回自己保存的文档 ID,才是读者能使用的检索结果。本文只处理现成向量,不生成文本 embedding,也不把人工向量的相似度冒充真实语义效果。

以下代码在 Windows、Python 3.11、scikit-learn 1.7.2、NumPy 2.4.6 的本地环境运行核对。数据是教学用人工构造样例,不是业务测评;示例数字只用于检查代码路径。

已有向量怎么做相似检索?用 NearestNeighbors 返回余弦距离与文档 ID

先准备环境

在自己可写的目录打开终端。首次运行先创建虚拟环境;Windows 用下面的命令,macOS/Linux 把激活命令换成 source .venv/bin/activate。安装只需要在该环境里进行一次。

python -m venv .venv
.venv\Scripts\activate
python -m pip install scikit-learn==1.7.2 numpy==2.4.6

先核对向量与 ID 的契约

库向量应是“文档数 × 维度”的二维数组,查询也要是“查询数 × 同一维度”。库向量和查询向量必须处于可比较的同一向量空间,并遵守所用编码模型规定的文档/查询输入配置;长度相同不意味着向量可比较。文档 ID 和向量行必须同序,且 ID 不重复。

NearestNeighbors 官方文档说明 fit、kneighbors 和返回数组。下面明确使用 brute 与 cosine,适合检查小规模数据的精确结果,不宣称建立了近似索引或长期持久化数据库。

执行一次检索并返回文档 ID

保存代码为 search_vectors.py,运行 python search_vectors.py。用三个维度的手工向量做几何演示,便于直接核算结果。

import numpy as np
from sklearn.neighbors import NearestNeighbors

ids = np.array(['doc-A', 'doc-B', 'doc-C', 'doc-D'])
vectors = np.array([[1, 0, 0], [0.8, 0.6, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float64)
query = np.array([[1, 0, 0]], dtype=np.float64)
assert len(ids) == len(vectors) and len(set(ids)) == len(ids)
assert query.shape[1] == vectors.shape[1]
assert np.isfinite(vectors).all() and np.isfinite(query).all()
assert np.all(np.linalg.norm(vectors, axis=1) > 0)
assert np.all(np.linalg.norm(query, axis=1) > 0)
index = NearestNeighbors(metric='cosine', algorithm='brute')
index.fit(vectors)
distances, positions = index.kneighbors(query, n_neighbors=2)
for row in range(len(query)):
    print('query:', row)
    for distance, pos in zip(distances[row], positions[row]):
        print(ids[pos], 'distance:', round(float(distance), 6),
              'cosine similarity:', round(1-float(distance), 6))
assert ids[positions[0, 0]] == 'doc-A'
assert np.allclose(distances[0], [0, 0.2])

怎样验证距离方向没有写反

本地运行第一名为 doc-A,余弦距离 0.0,相似度 1.0;第二名为 doc-B,距离 0.2,相似度 0.8。距离越小越接近,不能把距离直接按从大到小排序。对于此处的余弦距离,相似度写为 1 减距离;余弦相似度还可能为负,不是始终处于 0 到 1 的概率。

脚本同时核对行数、维度、有限值和非零范数。零向量没有可用方向,遇到零向量应先定位生成失败或空文本,保留错误记录,而不是替换成一个随机向量继续检索。

接入实际文档时保存什么

为每行保存稳定文档 ID、对应正文或来源路径、向量模型版本和生成时间。查询处理必须与库向量采用同样约定。替换模型或维度后,需要重新生成和验证全库向量,不能把新旧结果混在一个矩阵里。

一次可先用三类查询核验:明确应命中的文档、措辞不同但意思相近的文档、库内没有答案的查询。检查返回 ID 对应的正文,不能只看分数。kneighbors 即便面对无关查询,也会返回最近的几个点,所以还需用自己任务的正反样本设定接受规则;本文没有提供可跨数据集通用的阈值。

边界与常见疑问

n_neighbors 不可大于已拟合样本数;批量查询的每一行应分别映射结果。距离相同的记录可能出现不同的并列顺序,不要把并列名次当成质量差异。如果查询本来就是库内文档,要依据 ID 排除自身,再取需要的推荐数;本题的外部查询没有这种处理需求。

brute 会直接比较查询与库向量,数据量增加时应实际测量内存和延迟。若任务需要大规模近似检索、磁盘保存、过滤或增量更新,应另选并验证对应索引或数据库。本文的完成结果是一份正确映射文档 ID 的小规模精确检索结果。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30839.html

赞 (0)
AI小管家的头像AI小管家
OCR 前怎么矫正倾斜照片?用 OpenCV 四点透视变换检查结果
上一篇 1天前
AI 视频识别前怎么抽帧?用 OpenCV 保存时间位置并检查遗漏
下一篇 1天前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部