我有一个包含大约 1 000 000 条文本的数据集,我用语言模型计算了它们的句子嵌入,并将它们存储在一个 numpy 数组中。
我希望将一个新的看不见的文本与所有 1 000 000 个预先计算的嵌入进行比较,并执行余弦相似度来检索语料库中语义最相似的文档。
执行这种 1-vs-all 比较最有效的是什么?
我会感谢任何指示和反馈!
我有一个包含大约 1 000 000 条文本的数据集,我用语言模型计算了它们的句子嵌入,并将它们存储在一个 numpy 数组中。
我希望将一个新的看不见的文本与所有 1 000 000 个预先计算的嵌入进行比较,并执行余弦相似度来检索语料库中语义最相似的文档。
执行这种 1-vs-all 比较最有效的是什么?
我会感谢任何指示和反馈!
有专门从事该任务的库,例如Facebook AI Research 的FAISS:
Faiss 是一个用于高效相似性搜索和密集向量聚类的库。它包含在任意大小的向量集中搜索的算法,直到那些可能不适合 RAM 的向量。它还包含用于评估和参数调整的支持代码。Faiss 是用 C++ 编写的,带有 Python/numpy 的完整包装器。一些最有用的算法是在 GPU 上实现的。它由 Facebook AI Research 开发。
对于余弦相似度,您可以使用 FAISS 类IndexFlatIP
首先对向量进行归一化,如 FAISS 文档中所述。
如果你想了解更多关于 FAISS 背后的技术,你可以看看他们的研究论文,如果你想了解更多关于相似度搜索的基本知识,你可以看看Flickr 的这篇博文。
FAISS 的一些替代品是Annoy、NMSLib和Yahoo 的 NGT。您可以在此处和此处找到这些库和其他库的一些比较。
@lsbister,
您可以创建一个 pandas 数据框并使用 dask 函数/lambda 函数同时并行化一个与所有的计算。
如果您使用 dask,您可以创建分区并将响应映射回来。如果您使用 pandas,您可以使用 apply 函数并在一定程度上并行计算。
我建议也给 gensim 一个机会。与其他自行编写的“余弦相似度检索 top_n”函数相比,它的速度非常快。
将嵌入保存在 .txt 或 .csv 文件中,然后使用命令“load_word2vecformat”加载它。加载模型后,您可以使用函数 'similar_by_word' 或 'similar_by_vector' 来检索 n 个最接近的向量。
from gensim.models import KeyedVectors
model = KeyedVectors.load_word2vec_format(datapath('model_file'), binary=False)
top_10 = model.similar_by_word('cat')
当您保存文件以将嵌入的数量(在您的情况下为 1M)和向量维度包含为第一行时,请注意。它只是 gensim 标准格式,文件应该是这样的:
1000000, 300
'.', -0.0001, -0.0001, ...
',', -0.0001, -0.0001, ...
'a', -0.0001, -0.0001, ...