我的小流量“转正”心得 --- 下载下方深度语义重排的实践

2023-10-19 19:20

本文主要是介绍我的小流量“转正”心得 --- 下载下方深度语义重排的实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、背景

二、通过数据分析找到的问题

三、迭代流程

迭代一:

迭代二:

迭代三:

迭代成功的原因:

知识扩展

四、hnswlib调优过程

五、附录

5.1 hnsw 超参选择


一、背景

  1. 在分发中下载带来的收入占比排列仅次于搜索。
  2. 下载资源的分发占比在一半以上。
  3. 下载资源是重要的收入来源之一。
  4. 下载相关推荐现有的策略大部分无法满足用户的需求。

二、通过数据分析找到的问题

  1. 下载资源中一半以上的资源都是曝光搜索词的。
  2. 在所有的下载资源中,有曝光搜索词的资源占比面积小。
  3. 博客和下载的曝光搜索词得分存在不准确性。
  4. 下载资源推荐结果存在无序的情况。

三、迭代流程

迭代一:

迭代方式:下载相关推荐下通过用户点击和下单行为进行重排

迭代失败原因:

  1. 用户在下载相关推荐下产生的点击过少,二级排序是针对于用户点击行为进行的加权处理。经统计,有曝光无点击的占比较高,导致二级排序的影响面很少,最终实验效果不明显。
  2. 为了避免整体收入波动大,实验上线后将策略安排在了2、3槽位,从不同实验相同槽位来看,新策略的收入和用户行为不如老策略,新策略落败。

总结:

  1. 下载相关推荐下无法做到像博客相关推荐一样的策略,下载推荐的点击量过少,而新策略是基于用户点击进行的排序。
  2. 在从槽位上对比发现,老策略召回的结果比较优,下一步打算从老策略调优入手。

迭代二:

迭代方式:下载相关推荐老策略通过ADA语义相似度计算距离,能将相似度最高的进行计算

迭代失败的原因:

  1. 词库中有曝光搜索词的资源只有百万资源,占比33%,覆盖面积较小,再加上实验只是小流量,导致在实验组中看到的召回率非常低。
  2. 老策略内部做排序是会把相同的曝光搜索词计算得分,但会出现结果全是新策略的资源,会把相关的资源挤到后面,导致结果不相关。

总结:

  1. 在现有的资源中做扩覆盖处理不是最优的选择,首先成本较大,并且覆盖面积较小,从实验数据中看出,召回率和收入微乎其微。
  2. 从扩覆盖中得知,扩覆盖是相当于把推荐结果进行了扩充并重排,何必不把原来的推荐结果重排,这是下一个实验的导火索。

迭代三:

迭代方式:下载相关推荐曝光搜索词通过ADA语义进行相似度计算,并根据相似度进行重排

全量上线原因:

  1. 这次挑选实验组时,挑选了一个在空跑期间收入较弱的一组,如果收入落败的组在新策略上线后能跟对照组拉平,则胜出。
  2. 从实验期开始,实验组的收入只有1天落败,在其他的同一天时间不同实验来看,实验组的收入大范围胜出。
  3. 扩量后,实验组的整体收入也高于对照组,并且点击率也有所上涨。

迭代成功的原因:

  1. 经统计下载资源中,推荐结果列表无排序的结果占比较大,下载资源中曝光搜索词得分一半以上较低,说明在现有的推荐结果中,部分推荐结果都是无排序结果。
  2. 首条结果是用户的首要选择,所以排序结果会对收入产生影响,通过语义排序,会提高用户体验。
  3. 吸取了前两个实验失败的原因,总结出对推荐结果进行重排才是重要原因。

知识扩展

语义计算:我们使用的是OpenAI第二代嵌入模型 text-embedding-ada-002将 SA资源的标题进行向量化,借助 hnswlib 完成向量索引库构建,通过余弦距离衡量两段文本之间的相关性。

GPT3采用Transformer的解码器:

text-embedding-ada-002在文本搜索、代码搜索和句子相似性任务上优于所有旧的嵌入模型,并在文本分类上获得相当好的性能,文本检索领域的评测结果: 

GOOD CASE:

 

四、hnswlib调优过程

1. hnsw超参调整,增加连接数量,召回从75.16%提升至80.21% ;详见附录5.1 hnsw超参选择
2. 前五十万样本建索引库召回率在96%,后四十多万建立索引库召回率只有 53%,分析发现24.7w 不同的 title向量存在重复,去除后召回率在96.7%;定位到原因:使用多线程批量访问OpenAI 向量化接口,hnswlib 对文本向量化存储时出现较多异常数据;
3. 重建向量索引库后,跟第一版相比top1 差异率:47.19%,自评 GSB=45:48:7;标注团队GSB=30:68:2;线上小流量实验落败,分析原因可能:query embedding 和 title embedding 分布存在差异,用于召回效果可能不太理想,尝试用于title to title的相似度重排,故尝试在下载下方相关推荐重排实验;
4. 对下载相关推荐中曝光搜索词召回结果使用文本向量相似度重排,胜出;

五、附录

5.1 hnsw 超参选择

  1. 选择 l2 距离还是 cosine 距离对召回率影响不大,但是cosine距离会更好一点;
  2. 扩大 候选list 大小ef 和 连接数M召回率会有提升,对应的创建索引库的时间和检索时间会增加; 

ef - the size of the dynamic list for the nearest neighbors (used during the search).

M - the number of bi-directional links created for every new element during construction.

第一版向量召回优化,recall 对比

recall

l2

cosine

耗时

ef = 100

75.16%

75.35%

37.4s

ef = 500

80.163%

80.21124%

11min36s

ef = 600

80.166%

80.21157%

28min09s

# m = 64

# ef = 500: 10min25s 0.8021080499165129

# ef = 600: 30min27s 0.8021146410053608

# m = 100

# ef = 200: 11min36s 0.8021124439757448

# ef = 600: 28min09s 0.8021157395201687

文章作者:李震 & 卫亮亮 & 李长皓 & 王品

这篇关于我的小流量“转正”心得 --- 下载下方深度语义重排的实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/241843

相关文章

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

Spring Boot 整合 SSE的高级实践(Server-Sent Events)

《SpringBoot整合SSE的高级实践(Server-SentEvents)》SSE(Server-SentEvents)是一种基于HTTP协议的单向通信机制,允许服务器向浏览器持续发送实... 目录1、简述2、Spring Boot 中的SSE实现2.1 添加依赖2.2 实现后端接口2.3 配置超时时

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

Python 中的 with open文件操作的最佳实践

《Python中的withopen文件操作的最佳实践》在Python中,withopen()提供了一个简洁而安全的方式来处理文件操作,它不仅能确保文件在操作完成后自动关闭,还能处理文件操作中的异... 目录什么是 with open()?为什么使用 with open()?使用 with open() 进行

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.