基于火山引擎云搜索服务的排序学习实战

排序学习(LTR: Learning to Rank)作为一种机器学习技术,其应用场景非常广泛。例如,在电商推荐领域,可以帮助电商平台对用户的购买历史、搜索记录、浏览行为等数据进行分析和建模;可以帮助搜索引擎对用户的搜索关键词进行分析建模;可以为广告主提供最精准和最有效的广告投放方案;在金融风控领域,排序学习可以帮助金融机构分析客户的信用评级和欺诈风险,提高风控能力和业务效率。

原理介绍

一般的搜索引擎服务,其搜索过程包含了两个阶段,即召回+排序。如火山引擎云搜索服务,通过用户输入的文本段作为关键词,使用 BM25 打分算法,遍历数据库并挑选出分数最高的文档排好序后再返回展示给用户。由于 BM25 算法模型考虑的因素主要是文本的词频、逆文档频率等。因此搜索结果的排序仅仅取决于它所检索的文本的相关性,这在大部分场景下都是够用的,但是有些应用场景用户则想要实现相关性更优的个性化推荐效果。

为了达到这个目的,需要在已有召回+排序的基础上,额外引入重排阶段。相比较于前两个阶段,第三阶段考虑的因素则偏向于用户行为,通过用户点击、收藏、购买等反馈特征,引入机器学习算法,针对特征与反馈自动学习并调整参数,预估用户对于返回结果的偏好,最终实现个性化搜推结合的效果。整个训练排序过程,也被称为排序学习(LTR: Learning to Rank)。

以火山引擎云搜索服务为例,为了实现完整的三阶段流程,存在内置和外挂两种方式:

  • 内置方式,是将重排阶段以插件的形式安装到火山引擎云搜索服务中,用户输入查询,得到搜推结果。整个流程对业务保持透明,业务只需与搜索引擎完成交互。相关实现为:elasticsearch-learning-to-rank 插件等。

  • 外挂方式,是指在业务侧,先通过火山引擎云搜索服务查询得到召回+排序前两阶段结果,然后将中间结果作为输入,再与 LTR 模型工具进行交互,最后返回搜推结果。整个流程需要业务侧自行处理中间结果,完成与搜索服务和 LTR 模型工具的交互,灵活性更高,对应的开源工具有:metarank 等。

本文的后续内容将利用火山引擎云搜索服务结合 Metarank 项目来演示如何实现用户的个性化搜推实践方案。


环境准备

1.登录火山引擎云搜索服务,创建实例集群,集群版本选择 7.10。

2.Python Client 关键依赖准备

pip install -U elasticsearch7==7.10.1 # ES数据库相关 pip install -U pandas #分析splash的csv

数据集准备

选择 Metarank 文档中推荐的 RankLens 数据集,其中原始的数据集在 dataset 路径下,将其解压后即可得到约 2500 条数据,每条数据包含电影海报、演员、评分等信息。

{ ... "description": "When a rare phenomenon gives police officer John Sullivan the chance to speak to his father, 30 years in the past, he takes the opportunity to prevent his dad's tragic death. After his actions inadvertently give rise to a series of brutal murders he and his father must find a way to fix the consequences of altering time.", "director": { "gender": 2, "id": 17812, "name": "Gregory Hoblit", "popularity": 1.62 }, "id": 3510, "overview": "When a rare phenomenon gives police officer John Sullivan the chance to speak to his father, 30 years in the past, he takes the opportunity to prevent his dad's tragic death. After his actions inadvertently give rise to a series of brutal murders he and his father must find a way to fix the consequences of altering time.", "poster": "https://image.tmdb.org/t/p/original/eu3Hrjj271dnBdNAF0HqfmwWASt.jpg", "releaseDate": "2000-04-28", "tags": [ "time travel", "father-son relationship", "alternate reality", "father son relationship", "supernatural" ], "title": "Frequency", "tmdbId": 10559, "tmdbPopularity": 10.95, "tmdbVoteAverage": 7.2, "tmdbVoteCount": 1254, "topActors": [ { "gender": 1, "id": 31167, "name": "Elizabeth Mitchell", "popularity": 8.646 }, ... ] }

搜推结合实践操作

连接

  • 火山引擎云搜索服务

登录火山引擎云搜索服务,选择刚刚创建好的实例,选择复制公网访问地址(由于Metarank运行在本地机器上,为了连接云搜索服务,需要打开公网访问,如果Metarank运行在用户VPC里则不需要):

# 连接火山引擎云搜索服务实例 cloudSearch = CloudSearch("https://{user}:{password}@{ES_URL}", verify_certs=False, ssl_show_warn=False)

  • Metarank 服务

本地启动 Metarank 服务,数据集参数(--data)指定转化后的数据集,包括数据的元信息及用户点击率信息;配置文件参数(--config)指定模型配置等,参数及文件下载可参考 https://docs.metarank.ai/introduction/quickstart

java -jar metarank-0.7.1.jar standalone --data events.jsonl.gz --config events-config.yml

写入

将 RankLens 数据集写入火山引擎云搜索服务

import json path = '${下载的数据集所在路径}' with open(path, 'r') as f: bulk_docs = [] n = 0 for line in f.readlines(): doc = json.loads(line.rstrip()) if 'title' in doc: n += 1 bulk_docs.append({"index": {"_id": doc['id']}}) bulk_docs.append(doc) ## 每次批量写入50条数据 if n % 50 == 0: resp = cloudSearch.bulk(bulk_docs, index='events2') bulk_docs = []

查询

1.文本查询 + Metarank 重排

@app.route('/search', methods=['GET']) def search(): return innerSearch() def innerSearch(): # 获取参数 query = request.args.get('query') method = request.args.get('retrieval') n = int(request.args.get('size')) rank = request.args.get('rank') start = time.time() # 文本查询 docs = retrieve(method, query, n) done1 = time.time() if len(docs['hits']['hits']) == 0: return render_template('search.html', help=False, query=query, method=method, rank=rank, size=n, took={"search": 1000*(done1-start), "rank": 0, "total": 1000*(done1-start)}) # Metarank重排 sorted = rerank(rank, query, docs['hits']['hits']) done2 = time.time() return render_template('search.html', help=False, query=query, docs=sorted, method=method, rank=rank, size=n, took={"search": 1000*(done1-start), "rank": 1000*(done2-done1), "total": 1000*(done2-start)})

2.点击反馈

将用户的偏好反馈写入 metarank

@app.route('/feedback', methods=['GET']) def feedback(): item = request.args.get('item') # 点击反馈 interaction = metarank.feedbackInteraction(item) return innerSearch()

结果展示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/128561.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Dockerfile创建镜像

基于现有镜像创建 1.首先启动一个镜像,在容器里做修改 docker create -it centos:7 /bin/bash #常用选项: -m 说明信息; -a 作者信息; -p 生成过程中停止容器的运行。 2.然后将修改后的容器提交为新的镜像,需要使用…

全场景流量验证系统 | 京东物流技术团队

本文介绍了一种基于线上流量实现对重构系统进行功能和性能验证的实践方案。针对线上流量如何拦截、如何录制、如何存储、如何回放以及如何发压均作了详细说明,为具有类似需求的读者提供了一种可供参考的思路。 1 业务背景 随着百川项目的启动,中台需要…

平板第三方电容笔怎么样?便宜的ipad触控笔推荐

苹果原装的电容笔与国产的平替电容笔最大的区别在于,平替电容笔只有一个斜面压力感应,而苹果电容笔既有斜面压力感应,又有重力压力感应。但是,如果你不经常使用它来进行绘画的话,你也不必买选择这款苹果电容笔&#xf…

ASP.NET Core教程:ASP.NET Core 程序部署到Windows系统

框架依赖 一、发布 框架依赖(FDD):即Framework-dependent deployments的缩写。这种发布方式依赖于Framework框架,即要部署的服务器上面必须按照ASP.NET Core 运行时环境(ASP.NET Core Runtime)。这种部署方式是微软默认推荐的。下…

MySQL基础-事务

目录 1.事务简介 2.事务的操作 2.1 实验需要用到的数据 2.2 完成转账操作 修改事务执行方式 手动开启事务的方式 3.事务的四大特性 4.并发事务问题 5.事务隔离级别 5.1 事务隔离级别分类 5.2 查看事务隔离级别 5.3 设置事务隔离级别 1.事务简介 事务是一组操作的集合…

【Linux】文件权限详解

🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁 🦄 个人主页——🎐开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 🎐✨🍁 🪁🍁 希望本文能够给您带来一定的…

vue-6

一、声明式导航-导航链接 1.需求 实现导航高亮效果 如果使用a标签进行跳转的话,需要给当前跳转的导航加样式,同时要移除上一个a标签的样式,太麻烦!!! 2.解决方案 vue-router 提供了一个全局组件 router…

我的创业之路:我为什么选择 Angular 作为前端的开发框架?

我是一名后端开发人员,在上班时我的主要精力集中在搜索和推荐系统的开发和设计工作上,我比较熟悉的语言包括java、golang和python。对于前端技术中typescript、dom、webpack等流行的框架和工具也懂一些。目前,已成为一名自由职业者&#xff0…

Allegro如何用Pad Designer 设计焊盘

跟其它PCB的设计软件不一样。Allegro制作封装,第一步要先制作焊盘。 本文以圆形钻孔0.5mm,外盘0.8mm的C05D08焊盘为例一步步讲解如何制作焊盘。 1、首先打开Pad Designer,选择File→New,新建一个焊盘。 然后跳出下面的对话框,在框内输入封装名称,选择好要保存的焊盘路径…

母婴店怎么在微信小程序卖东西

随着互联网的发展,微信小程序已经成为一种新型的电商模式,它无需下载安装,使用方便,不占用手机内存,让购物变得更加简单便捷。母婴店也可以通过微信小程序来销售产品,拓宽销售渠道,增加销售额。…

HDMI简介

VGA接口 VGA传输红绿蓝模拟信号和同步信号。因传输的模拟信号,易受干扰,因此,在高分辨率下字体容易虚,信号线长的话,图像有拖尾现象。目前一些显示器已经不带VGA接口,取而代之的是HDMI和DP接口。 如下图所示…

Vs - Qt - 下拉窗口示例

下列代码定义了一个窗口&#xff0c;窗口采用竖直布局&#xff1a;一个按钮及一个label。按下按钮时候&#xff0c;窗口扩张&#xff0c;显示label控件。再次按下按钮时&#xff0c;窗口收缩&#xff0c;隐藏label控件。 详细代码如下&#xff1a; #include <QApplication&g…