召回库转换成向量存入hnswlib,然后查询的也转换成向量进行查询即可转换成向量的方式有很多种方式
https://blog.csdn.net/CHIERYU/article/details/81989920
语义索引模型的目标是: 给定输入文本,模型可以从海量候选召回库中快速、准确地召回一批语义相关文本。
简要介绍 In-batch negatives 策略和 HardestNeg 策略思路
In-batch negatives 核心思路
In-batch negatives 策略的训练数据为语义相似的 Pair 对,如下所示为 Batch size = 4 的训练数据样例:
我手机丢了,我想换个手机 我想买个新手机,求推荐
求秋色之空漫画全集 求秋色之空全集漫画
学日语软件手机上的 手机学日语的软件
侠盗飞车罪恶都市怎样改车 侠盗飞车罪恶都市怎么改车
In-batch negatives 策略核心是在 1 个 Batch 内同时基于 N 个负例进行梯度更新,将Batch 内除自身之外其它所有 Source Text 的相似文本 Target Text 作为负例,例如: 上例中 我手机丢了,我想换个手机 有 1 个正例(1.我想买个新手机,求推荐),3 个负例(1.求秋色之空全集漫画,2.手机学日语的软件,3.侠盗飞车罪恶都市怎么改车)。
HardestNeg 核心思路
HardestNeg 策略核心是在 1 个 Batch 内的所有负样本中先挖掘出最难区分的负样本,基于最难负样本进行梯度更新。例如: 上例中 Source Text: 我手机丢了,我想换个手机 有 3 个负例(1.求秋色之空全集漫画,2.手机学日语的软件,3.侠盗飞车罪恶都市怎么改车),其中最难区分的负例是 手机学日语的软件,模型训练过程中不断挖掘出类似这样的最难负样本,然后基于最难负样本进行梯度更新。
和前几种算法不同,HNSW(Hierarchcal Navigable Small World graphs)是基于图存储的数据结构。
参数设置中,ef表示最近邻动态列表的大小(需要大于查找的topk),M表示每个结点的“友点”数,是平衡时间/准确率的超参数。可以根据服务器资源和查找的召回率等,做相应调整。本文介绍了几种常用的k近邻查找算法,kdtree是KNN的一种基本实现算法;考虑到并发、延时等要素,annoy、hnsw是可以在实际业务中落地的算法,其中bert/sentence-bert+hnsw的组合会有不错的召回效果。
- hnswlib支持的距离
在 hnswlib分别支持L2距离,向量内积以及cosine相似度。在构建索引的过程中对应的具体参数为:
l2,ip,cosine
构建索引的时候,通过传递参数确认检索最近邻需要使用的距离:
p = hnswlib.Index(space = ‘l2’, dim = dim)
1
2 构建参数
在索引初始化阶段的代码如下:
index.init_index(max_elements=num_elements, ef_construction=200, M=16)
1
M: 表示在构建期间,每个元素创建的双向链表的数量。M合理的范围是2-100。M值较高的时候在高召回率数据集上效果好,M值较低在低召回率数据集上效果好。M值决定了算法内存消耗,大概是 M × ( 8 10 ) B y t e s M \times (8~10);BytesM×(8 10)Bytes
ef_construction:控制了索引时间和索引准确度,和ef参数具有相同的意义。ef_constraction越大,构建时间越长,但是索引质量更好。在某种程度上提高ef_construction并不能提高index的质量。
检查ef_construction的选取是否正确的一种方法是在ef=ef_construction的时候测量M最近邻搜索的召回率,如果召回率低于0.9,ef_construction可以继续改进。
num_elements: 在index最大的元素个数。
3 检索参数
在近邻检索阶段的代码如下:
index.set_ef(int(k * 1.2))
labels, distances = index.knn_query(data, k=k)
1
2
ef: 动态检索链表的大小。当ef设置的越大,越准确同时检索速度越慢,ef不能设置的比检索最近邻的个数K小。ef的值可以设置为k到集合大小之间的任意值。
k: 结果中返回的最近邻的结果的个数k。knn_query函数返回两个numpy数据。分别包括k个最近邻结果的标签和与这k个标签的距离。