深度学习 - 52.推荐场景的多样性与 MMR [Maximal Marginal Relevance] 简介与 Python 实现

news2024/9/23 5:21:57

目录

一.引言

二.多样性

三.MMR 流程

1.标准 MMR

2.窗口 MMR

四.基于向量内积相似度的 MMR Python 实现

1.模拟用户 rank 结果

2.向量内积计算 MRi

2.1 获取向量计算 max sim

2.2 argmax 获取最优 MRi item

3.MMR 测试

4.MMR 完整代码

五.总结 


一.引言

MMR - Maximal Marginal Relevance 最大边界相关算法是一种多样性计算方法,最早起源于 NLP,后被应用于推荐算法的重排用于提高推荐的多样性。

二.多样性

推荐系统常常分为召回、粗排、精排与重排、随着步骤的深入,物料的数量也越来越小,精排给 n 个候选 item 打分后,可以获得每个物品的融合分数,有纯 CTR 场景,此时分数为 CTR、也有多目标场景、例如同时预测 Item 的点赞率、收藏率、点击率等等,此时将多个指标加权作为当前 item 的融合分数,这里我们统称为 reward_i 代表当前 item 的回报值。

传统推荐阶段在精排后按照 reward_i 降序排列取 TopK 即可实现推荐,为了提高用户推荐的多样性,我们引入了 item 的相似度度量记录为 sim(i,j),其中相似度的计算可以是简单的类目匹配,也可以是 Context 文本向量的相似度度量。

多样性重排要求从 n 个精排 item 中选出 TopK,要求这 K 个商品既有高精排分数,也拥有一定的多样性。

三.MMR 流程

1.标准 MMR

Maximal Marginal Relevance 最大边界相关算法:

上图为 MMR 在论文中的公式表达,上面多样性中我们提到 MMR 最终的目的是既要又要,所以式子中的 λ 很明显是作为调节因子,控制用户既要想要的区分度,下面解释下推荐系统下的 MMR 计算:

• 构建集合 S 与 R 

精排后获得 N 个候选商品,其中 reward 排名第一个 item 构成数组 S = [Top],剩下的 N-1 个商品构成数组 R。S 中的物品代表已选、R 中的物品代表备选,假设要从 N 中选 Top K,则 MMR 的任务是从 R 中挑选 K-1 个商品送进 S。

• 计算 R 中商品的 MRi

初始化 S 和 R 后,需要计算 R 中每个物品的 MRi,MRi 是综合了商品的打分与其与 S 中商品的多样性得到的分数,θ 为调和参数,θ 越大越偏向 reward 高的商品,反之越偏向多样性强的物品,此时曝光少、长尾的物品更容易获得下发机会。

max_{j\in S} sim(i,j)

i 代表当前 R 中的某个候选集,j 是所有当前 S 中的商品,需要计算 i、j 的相似度,并取出 max 的值,这一步主要是为了让当前 i 尽量不与 S 中的某个商品很相似,从而导致多样性差或者出现重复内容。

• MMR 添加商品至 S

遍历 R 中的商品并计算 sim(i,j),argmax 找到 MRi 最大的候选 item 从 R 中 pop 并 append 添加至 S 中。重复上述步骤 K-1 次,此时 len(S) = K、len(R) = N - K ,迭代结束,S 作为 MMR 重排后的结果参与后续推荐逻辑。

Tips:

- 关于 S 的初始化

为什么 S 初始化要放入 reward 最高的商品,这是因为当 S 为 0 时,max sim 这一项为 0 ,所以 RMi 的计算只考虑 θ * reward,自然会放入 reward 最高的商品,当 S 有元素时,max sim 这一项非 0 ,从而可能出现 reward 低但多样性好的商品逆袭。

- sim(i,j) 计算

sim(i,j) 可以是简单的物品属性匹配,例如一级类目、二级类目、三级类目的匹配,也可以通过预训练 embedding 的方式,获取不同商品的 embedding,通过计算向量内积、向量 Cos 等方式计算候选集之间的相似度。这里推荐使用基于图片或者 NLP 语义理解的 embedding 方式,而不推荐类似双塔的结构,这是因为双塔训练对于长尾与低曝光物品训练不到位,可能影响效果。

- 关于 max、θ

max 是寻找当前候选与所有 item 中相似度的最大值,这里也可以尝试 mean 代表与整体的相似度差异。 θ 的话就根据自己的场景调试即可,不同的值不同的偏好,可以从 0.5 试起来。

2.窗口 MMR

当 K 设置的很大时,随着添加的物品增多,max sim(i,j) 总是约等于1,这将导致 MMR 算法退化成基于 reward 排序。 解决方案也很简单,把 max 的计算方式修改,把与 J ∈ S 改成 J ∈ SBS 即 S 的一个子集,实际场景下为 S 中最近选中的 M 个物品。这个也很好理解,第 1 个物品和第 30 个物品可以相似,这对多样性并不会造成多大影响,只要保证局部的 W 内的多样性同样可以做好用户的多样性。

 

Tips:

- 关于计算复杂度

传统 MMR 计算需要遍历 R 中的物品,同时 R 中每个物品还需要遍历 S 中的物品,计算复杂度较高。引入滑动窗口可以有效缩减  max sim(i,j) 的计算量,可以通过提前缓存 item 之间的 sim 值或者引入动态 Cache 提高 MRi 的计算速度。除此之外,通过 batch 矩阵计算也可以优于 for 循环的 sim 计算。

- 关于 W 窗口大小

这个参数的设置有多个考虑因素,一方面要考虑用户一次刷新要曝光的物品条数,W 应该与该数量成正比,除此之外也可以考虑实际端上曝光可显示范围数,例如手机上一屏只能显示 6 件商品,那么也可以适当缩小 W 范围。

 

四.基于向量内积相似度的 MMR Python 实现

1.模拟用户 rank 结果

if __name__ == '__main__':
    
    total = 10000
    n = 100
    k = 10
    theta = 0.5

    # 1.模拟用户排序分数,假设此时为精排,候选集 n=100
    R = list(zip(np.random.randint(0, total, size=n), np.random.random(n)))

    # 2.Embedding 相似度依据
    id_embedding = dict(zip(list(range(0, total)), np.random.random(size=(total, 8))))

这里假设商品库大小为 10000,精排结果为 100,重排后选择 K=10 个商品,R 代表用户排序的商品 id 与 reward 得分:

(2929, 0.8633555492090925)
(1662, 0.18390267494361623)
(8939, 0.9977265350155343)
(2402, 0.3223362034792787)
(9430, 0.19965218206425672)

id_embedding 为模拟的 10000 个商品的预训练 embedding,实际场景下可以通过 NLP 例如 bert 生成相关的文案 Embedding,通过 CNN 生成相关的图像信息 Embedding 再将二者结合:

9995: array([0.77517001, 0.6545193 , 0.07678476, 0.82733098, 0.86182284, 0.04631414, 0.00104291, 0.91166001]), 
9996: array([0.68162543, 0.3751251 , 0.10805542, 0.63555129, 0.51926022, 0.2010376 , 0.59947074, 0.7950087 ]), 
9997: array([0.95780135, 0.00484409, 0.05476651, 0.65649113, 0.71699212, 0.88593591, 0.49342144, 0.29664633]), 
9998: array([0.88086731, 0.70929634, 0.58964263, 0.70942298, 0.16545527, 0.6283401 , 0.02261712, 0.46174134]), 
9999: array([0.88725936, 0.33872398, 0.10774754, 0.95433321, 0.71457625, 0.92265572, 0.63147676, 0.48301763])}

2.向量内积计算 MRi

2.1 获取向量计算 max sim

        sort_list = []
        for item in _R:
            # 候选 Id 与预期收益
            item_id = item[0]
            item_reward = item[1]

            # 获取向量用于相似度计算
            item_emd = np.expand_dims(_id_embedding[item_id], axis=0)

            # 是否使用滑动窗口
            if is_slid:
                s_emd = np.transpose([_id_embedding[s[0]] for s in _S[len(_S) - window_size: len(_S)]])
            else:
                s_emd = np.transpose([_id_embedding[s[0]] for s in _S])

            # 计算 Max Sim ij
            max_sim = np.max(np.dot(item_emd, s_emd))

            # 计算 MRi
            MRi = theta * item_reward - (1 - theta) * max_sim
            sort_list.append((item_id, item_reward, MRi))

获取 Ri 的向量,与 S 中的多个候选商品 Item 进行 Batch Dot 计算,最后套公式计算 MRi。

2.2 argmax 获取最优 MRi item

        # 获取大的 RMi 商品
        sort_list.sort(key=lambda x: x[2], reverse=False)
        max_MRi = sort_list.pop()
        cur_max = (max_MRi[0], max_MRi[1])

        # Max RMi 从 R 移到 S 中
        max_MRi_id = _R.index(cur_max)
        _R.pop(max_MRi_id)
        _S.append(cur_max)

根据 MRi 排序,将 MRi 最大的 item 从 R 中 pop 并 append 至 S 中,完成一次循环。将上述逻辑执行 K-1 次,完成 K 个候选商品的选择。这里通过 is_slid 和 w 参数控制是否使用滑动窗口,工业场景下推荐使用滑动窗口并根据业务场景曝光条数选择合适的 w。

3.MMR 测试

    # 3.MMR
    S = mmr(R, id_embedding, k)
    for candidate in S:
        print("Id: %s Reward: %s" % (candidate[0], candidate[1]))
S Size: 2 R Size: 98 Id: 2023 Reward: 0.9803380341271558 RMi: 0.18914732654032512
S Size: 3 R Size: 97 Id: 7055 Reward: 0.9234506566901367 RMi: 0.09500372556637421
S Size: 4 R Size: 96 Id: 1307 Reward: 0.7965671493211518 RMi: 0.03062159309825946
S Size: 5 R Size: 95 Id: 4457 Reward: 0.9834577224706769 RMi: 0.09144580217525927
S Size: 6 R Size: 94 Id: 5394 Reward: 0.7642957463819996 RMi: -0.25072450194085166
S Size: 7 R Size: 93 Id: 2844 Reward: 0.7683949135991219 RMi: -0.17790320675225413
S Size: 8 R Size: 92 Id: 1430 Reward: 0.6749584037283536 RMi: -0.25759969410263295
S Size: 9 R Size: 91 Id: 8762 Reward: 0.7054624111048696 RMi: -0.26594825156168417
S Size: 10 R Size: 90 Id: 1109 Reward: 0.8096079183764663 RMi: -0.23384115011894474

我们在每一轮迭代中打印了 S、R 的信息,并打印了每轮从 R 中优胜的 item 对应的 Reward 与 RMi,可以看到最终 S 中的候选集已不完全按照 reward 排序,一些 reward 相对较低但多样性好的商品也会排在前面:

Id: 3816 Reward: 0.9994031803099526
Id: 2023 Reward: 0.9803380341271558
Id: 7055 Reward: 0.9234506566901367
Id: 1307 Reward: 0.7965671493211518
Id: 4457 Reward: 0.9834577224706769
Id: 5394 Reward: 0.7642957463819996
Id: 2844 Reward: 0.7683949135991219
Id: 1430 Reward: 0.6749584037283536
Id: 8762 Reward: 0.7054624111048696
Id: 1109 Reward: 0.8096079183764663

4.MMR 完整代码

import numpy as np


def mmr(_R, _id_embedding, _k=10, is_slid=True, window_size=5):
    # 按照 reward 排序 False 增序、True 降序
    _R.sort(key=lambda x: x[1], reverse=False)

    # 初始化集合 S
    top = _R.pop()
    _S = [top]
    _RMi = []

    # 构建后 K 个元素
    for i in range(_k - 1):
        sort_list = []
        for item in _R:
            # 候选 Id 与预期收益
            item_id = item[0]
            item_reward = item[1]

            # 获取向量用于相似度计算
            item_emd = np.expand_dims(_id_embedding[item_id], axis=0)

            # 是否使用滑动窗口
            if is_slid:
                s_emd = np.transpose([_id_embedding[s[0]] for s in _S[len(_S) - window_size: len(_S)]])
            else:
                s_emd = np.transpose([_id_embedding[s[0]] for s in _S])

            # 计算 Max Sim ij
            max_sim = np.max(np.dot(item_emd, s_emd))

            # 计算 MRi
            MRi = theta * item_reward - (1 - theta) * max_sim
            sort_list.append((item_id, item_reward, MRi))

        # 获取大的 RMi 商品
        sort_list.sort(key=lambda x: x[2], reverse=False)
        max_MRi = sort_list.pop()
        cur_max = (max_MRi[0], max_MRi[1])

        # Max RMi 从 R 移到 S 中
        max_MRi_id = _R.index(cur_max)
        _R.pop(max_MRi_id)
        _S.append(cur_max)
        print(
            "S Size: %s R Size: %s Id: %s Reward: %s RMi: %s" % (len(_S), len(_R), max_MRi[0], max_MRi[1], max_MRi[2]))
    return _S


if __name__ == '__main__':
    total = 10000
    n = 100
    k = 10
    theta = 0.5

    # 1.模拟用户排序分数,假设此时为精排,候选集 n=100
    R = list(zip(np.random.randint(0, total, size=n), np.random.random(n)))

    # 2.Embedding 相似度依据
    id_embedding = dict(zip(list(range(0, total)), np.random.random(size=(total, 8))))

    # 3.MMR
    S = mmr(R, id_embedding, k)
    for candidate in S:
        print("Id: %s Reward: %s" % (candidate[0], candidate[1]))

一些最大元素的构造也可以使用堆代替 List,提高计算效率,元素 Embedding 可以通过预训练得到或者换成简单的规则匹配。

五.总结

MMR 发表于 1998 年,是早期多样性文章的代表作之一,算法简单有效值得大家在推荐场景使用。

参考:

MMR 多样性算法(Maximal Marginal Relevance)

The use of MMR, diversity-based reranking for reordering documents and producing summaries

更多推荐算法相关深度学习:深度学习导读专栏 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记一次k8s节点上出现node.kubernetes.io/disk-pressure污点的问题

目录 问题描述 原因分析: 解决方案: 其他问题 问题描述 k8s部署时pod一直属于Pending状态,也就是说pod未调度到k8s节点上 原因分析: 通过以下命令查看下pod kubectl get pod 以上命令可以看到各个pod的状态&#xff0c…

【商城后台管理系统】项目初始化(UmiJS)

目录 一、运行时配置 1.1 配置方式 1.2 常用配置项 1.3 关于运行时配置说明 二、使用Umi UI 2.1 Umi UI的特性 2.2 项目中安装Umi UI 2.3 使用Umi UI 三、Umi JS总结 3.1 路由状态管理 3.2 配置代理 3.3 封装requset 一、运行时配置 运行时配置和配置的区别是他跑…

Geohash算法原理及实现

最近需要实现一个功能,查找车辆附近的加油站,如果车和加油站距离在200米以内,则查找成功。 加油站数量肯定不小,能否缩小查找范围,否则以遍历形式,效率肯定高不了。 Geohash算法就是将经纬度编码&#xf…

又名管道和无名管道

一、进程间通信(IPC,InterProcess Communication) 概念:就是进程和进程之间交换信息。 常用通信方式 无名管道(pipe) 有名管道 (fifo) 信号(signal) 共…

数字化时代,低代码+进销存管理系统让你省时省力

进销存系统是一种用于管理企业物资流动和库存的软件系统,可以帮助企业优化物资管理过程,提高效率,减少成本,从而提升企业的盈利能力。本文将详细介绍进销存系统的定义、功能、好处以及如何选择适合自己企业的进销存系统&#xff0…

【嵌入式烧录/刷写文件】-2.6-剪切/保留Intel Hex文件中指定地址范围内的数据

案例背景: 有如下一段HEX文件,保留地址范围0x9140-0x91BF内的数据,删除地址范围0x9140-0x91BF外的数据。 :2091000058595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576775F :2091200078797A7B7C7D7E7F808182838485868788898A…

「ACL 2023」发榜!火山语音推出业内首个借助视频信息的端到端语音翻译模型

日前 ACL 2023的论文录用结果公布,火山语音团队多篇论文成功入选,内容涵盖音频合成、歌声合成以及语音翻译等多个前沿技术领域的创新突破。ACL(Annual Meeting of the Association for Computational Linguistics)每年由国际计算语…

Nginx服务器及其配置与应用

目录 一、Nginx的特点 1.高并发 2.低消耗 3.低消耗 4.高可用 5.高扩展 6.Nginx与Apache的差异 7.Nginx与Apache的区别 二、Linux中的I/O 1.I/O介绍 2.同步/异步 3.阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态 三、编译安装Nginx服务 1.关闭防火墙&#…

SOLIDWORKS安装使用说明网络版

安装准备 系统要求:参考https://www.solidworks.com/sw/support/SystemRequirements.htmlSolidWorks 2017 是最蕞后一个支持win server 2008 R2 sp1的软件。 SolidWorks 2018支持win server 2012及以上的系统,但不支持win server 2019 SolidWorks 2019…

HNU-计算机系统-CSAPP作业答案

计算机系统CSAPP课后作业答案 计科210X wolf 202108010XXX 第2章 2.61 解: (!~x) || (!x) || (!~(x|0x00ffffff)) || (!(x&0x000000ff)) 或者: (!~x) || (!x) || (!~(x>>24)) || (!(x<<24)) 2.71 A. 实现的是逻辑位移,扩展后前面全是0,不符合符号扩…

Linux常见命令学习

目录 1.ls2.pwd3.cd (change directory)4.touch&&cat&&echo5.mkdir&&rm6.cp&&mv7.man8.less&&vim 1.ls 列出当前目录中包含的文件和目录~ 类似于在windows上双击某个目录&#xff0c;把他打开&#xff0c;看看目录里有啥~ ls -> l…

企业内容管理丨如何解决企业客户签收回执慢,缩短回款周期?

方案应用领域及行业 本方案适用于快消品行业的供应链管理和财务管理 方案应用背景 由于动产物权的政策变化&#xff0c;物权转移从交付时才开始发生效力。也就是说&#xff0c;新政之前&#xff0c;企业发出商品&#xff0c;开出销售发票&#xff0c;即可申请货物回款&#…

C# webapi接口传输byte[]数据,报错:415 Unsupported Media Type

最近需要做上传文件操作。 由于历史原因&#xff0c;以前的接口使用了这样的入参&#xff1a; 代码如下&#xff1a; /// <summary> /// 上传文件 /// </summary> [HttpPost] public Result<UploadImageResult> UploadFile(byte[] bytes, string extName, s…

html框架-----标签(上)

目录 前言&#xff1a; 标签简介 1. HTML的基本结构 (1)html标签 (2)head标签 &#xff08;3&#xff09;body标签 2. 标题标签 3. 段落标签 4. 文本格式化标签 前言&#xff1a; 现在学前端工程师的都很难找工作&#xff0c;懂的都懂了&#xff0c;因为学前端一般去做那…

console.log是异步还是同步?为什么console.log有时候不准

console.log是异步还是同步 在前端开发中&#xff0c;控制台console.log通常是同步的。这意味着&#xff0c;当代码执行到console.log语句时&#xff0c;它会立即写入到控制台中&#xff0c;并且JavaScript代码执行会在console.log完成后继续进行。 但是&#xff0c;在某些情况…

# croc用法实践(设备间文件或文件夹传输)

croc用法实践&#xff08;设备间文件或文件夹传输&#xff09; 文章目录 croc用法实践&#xff08;设备间文件或文件夹传输&#xff09;1 安装2 使用示例2.1 发送文件2.2 发送文件夹2.3 发送文本字符串2.4 发送时指定code&#xff0c;接收时自动【Y】&#xff0c;并保存到指定目…

《MySQL(一):基础篇-MySQL概述》

文章目录 1. MySQL概述1.1 数据库相关概念1.2 MySQL数据库1.2.1 版本1.2.2 下载1.2.3 安装1.2.4 启动停止1.2.5 客户端连接1.2.6 数据模型1. MySQL概述 1.1 数据库相关概念 先来了解三个概念:数据库、数据库管理系统、SQL。 而目前主流的关系型数据库管理系统的市场占有率…

ic验证的主要工作流程和验证工具是什么?

验证其实是一个“证伪”的过程&#xff0c;从流程到工具&#xff0c;验证工程师的终极目的都只有一个&#xff1a; 发现所有BUG&#xff0c;或者证明没有BUG&#xff0c;以保证芯片功能性能的正确性和可靠性。 验证环节对于一颗芯片的重要性也是不言而喻的&#xff1a; 从项…

VMware16安装Linux CentOS7完整教程(附下载地址)

一、准备工作 1.安装VMware Workstation Pro 16 &#xff08;1&#xff09;百度网盘下载地址 链接:https://pan.baidu.com/s/1jv0kQ26TLMt9MzofImRzgA?pwds0m1 提取码&#xff1a;s0m1 &#xff08;2&#xff09;VMware官网 https://www.vmware.com/cn &#xff08;2&#x…

广通优云徐育毅:筑基数字化,打造中国IT运维新范式

2023年2月&#xff0c;中共中央、国务院印发《数字中国建设整体布局规划》&#xff0c;数字技术与经济、政治、文化、社会等各领域融合愈发紧密&#xff0c;一册百花齐放、生机勃勃的数字化图卷正徐徐展开。 随着数字中国战略深入推进&#xff0c;IT运维作为核心领域受到关注。…