赞
踩
我们知道在搜索中,item的召回主要还是基于关键词召回,但是用户表达与商家对item的描述存在差异导致一些长尾query可能召回很少或者召不回item,虽然现在有语义模型可以减少这种问题出现,但当数据稀疏,训练样本较少的情况下,基于语义向量召回效果也并不好。
那么大模型是不是可以提高召回的效果?答案是可以的,大模型的一个优势就是有多领域知识,可以更好的理解信息。接下来介绍用大模型做基础工作提升召回效果
基于关键词的召回,我们首先要清楚什么是倒排索引,如下图所示:
上述整个流程表示了倒排索引是如何建立的以及ES如何基于倒排索引进行检索。
由于用户与商家存在表达差异以及数据噪声等问题,导致基于倒排索引进行召回存在一些问题,假设我们有如下倒排索引数据:
索引词 | 文档 |
---|---|
挂面 | 福临门挂面500g*2袋 |
面 | 福临门挂面500g*2袋,佰草集白泥面膜组合 |
白 | 佰草集白泥面膜组合 |
… | … |
当用户搜索query=‘白面’,通过切词,可以切分为:"白|面"两个term,从上面倒排索引表可以看出,同时命中“白"和"面“文本是:“佰草集白泥面膜组合”,反而和query相关的文本:“福临门挂面500g*2袋”没能够同时命中这两个term。主要原因是用户表达与商家描述存在差异,同时数据噪声加大了索引建立的复杂性通过语义向量进行召回减少了这种问题,但是需要大量的数据训练模型,才有较好的效果,当数据量不足的时候,效果并不佳。
大模型的优势是基于庞大的多类型数据进行学习的,所以有很强的通用知识能力。我们可以基于大模型来优化倒排索引,提升召回的效果。通过大模型对文本生成标准的实体词,比如 {洗面奶,手机,苹果,牛奶,口红,馒头,香蕉,面, 面膜,蛋糕等},基于大模型的理解能力,将文本映射到标准的实体词中,同时对用户输入的query也映射到实体词,这样就可以将query与item的标准实体词建立关联。首先,我们构造好我们的promp,让chatgpt生成我们想要的结果,我们prompt模板可以这么写:
给定如下实体词和文本内容,给出每条文本内容对应的实体词
输出格式:{文本内容:实体词}
实体词:{洗面奶,手机,苹果,牛奶,口红,馒头,香蕉,面, 面膜,蛋糕}
文本内容: {白面, 平安质优 福临门挂面500g*2袋,佰草集白泥面膜组}
然后我们调用chatgpt进行预测,如下所示:
得到的结果如下:
{白面: 面, 平安质优 福临门挂面500g*2袋: 面, 佰草集白泥面膜组合: 面膜}
从测试来看,预测的还是比较准确的。这样,我们可以基于大模型建立标准化的实体索引,索引建立如下:
索引词 | 标准化实体索引 | 文档 |
---|---|---|
挂面 | 面 | 福临门挂面500g*2袋 |
面 | 面 | 福临门挂面500g*2袋,佰草集白泥面膜组合 |
白 | 面膜 | 佰草集白泥面膜组合 |
… | … | … |
用chatgpt对query和item生成标准实体词,通过实体词建立索引关系,这种方式可以减少用户表达与item信息描述的差异导致召不回或者召不准的问题,索引建立流程图如下所示:
在搜索中,影响语义排序算法主要有三个核心部分,我们基于双塔模型的结构来讲解,如下所示:
第一部分 (人的特征):在搜索里面,核心是用户搜索的query,还有用户历史行为以及画像等特征
第二部分 (货的特征):这里主要包括货(item)的标题,标签等特征
第三部分 (人与货的关系):主要基于用户行为比如:曝光,点击,转化等反馈数据中建立关系,这也是我们的模型训练样本主要来源。若用户点击了一个item,则这个用户与item的样本label我们就认为是正样本y=1,否则y=0。但是在现实场景中,数据稀疏,数据噪声等问题,导致模型对人与货的匹配学习存在较大的挑战,有可能会犯我们人看来很“低级“的错误,比如用户搜索一个“橙",模型反而将“梨子"相关的item给出的排序分比有“橙子"的item分还高。
所以,顺着我们上述部分讲述的大模型在搜索召回层的应用,在排序层我们其实也可以利用大模型的通用知识理解能力,融入大模型的通用知识实体排序,如下图所示:
我们可以基于大模型对query与item生成的标准实体进行简单的匹配打分再融合到最终的排序的模型里,融合部分可以简单的进行加权求和得到最终的排序分也可以将大模型对query和item生成的标准实体作为基础排序模型特征输入等。
在这里也尝试了下用大模型生成向量,基于余弦值做相似度分计算,如下是调用chatgpt计算向量相似分代码:
def embedding(content): response = openai.Embedding.create( model="text-embedding-ada-002", input=content ) embs = response.data[0].embedding return embs if __name__=='__main__': query = '白面' content_1 ='福临门挂面500g*2袋' content_2 = '草集白泥面膜组合' q_emb = np.array(embedding(query)) c1_emb = np.array(embedding(content_1)) c2_emb = np.array(embedding(content_2)) # cos simi qc1_cos = q_emb.dot(c1_emb) / (np.linalg.norm(q_emb) * np.linalg.norm(c1_emb)) qc2_cos = q_emb.dot(c2_emb) / (np.linalg.norm(q_emb) * np.linalg.norm(c2_emb)) print('query:%s\nitem:%s\n相似度为:%s' % (query, content_1, qc1_cos)) print('query:%s\nitem:%s\n相似度为:%s' % (query, content_2, qc2_cos))
输出结果为:
从结果来看,query=‘白面’与item='草集白泥面膜组合’相似分更高
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。