MMR最大边际相关性

MMR(最大边际相关性,Maximal Marginal Relevance)的核心公式如下:

MMR = λ ⋅ Sim₁(Di, Q) - (1 - λ) ⋅ max Sim₂(Di, Dj)

这个公式的含义是:在构建 Few-Shot 提示词时,系统会从你的示例库(examples)中,贪心地挑选出下一个最能平衡"相关性"和"多样性"的示例加入最终列表。

公式中各项参数的具体含义如下:

Di:当前正在被评估的候选示例(比如你示例库里的 {"question": "高", "answer": "低"})。

Q:用户的实际输入(比如你代码中的 input="个子")。

Dj:已经被选中放入最终提示词里的示例集合。

Sim₁(Di, Q):相关性得分。衡量候选示例 Di 和用户输入 Q 的语义相似度。在你的代码中,Embedding 模型会计算"高"和"个子"的向量距离,距离越近得分越高。

max Sim₂(Di, Dj):多样性惩罚项。衡量候选示例 Di 与已选示例 Dj 的最大相似度。如果 Di 和已经选中的示例长得很像,这一项的值就会很大,导致 MMR 总分被扣减,从而避免选出重复或过于相似的示例。

λ (Lambda):平衡因子(取值范围 0 到 1)。它决定了算法更偏向哪一边:

λ 接近 1:极度看重相关性,选出的示例会和用户输入最贴近(退化为纯相关性排序)。

λ 接近 0:极度看重多样性,选出的示例会尽量互不相同,哪怕和用户输入关系不大。

简单来说,MMR 的打分逻辑就是:

最终得分 = 相关性奖励 - 重复性惩罚

算法筛选大致过程:

假设你的示例库 examples 里有4个例子:开心, 高, 精力充沛, 粗

现在用户输入了 "走",算法开始工作:

如果我们设置需要两个示例即k=1,则进行1轮筛选,k=2则是2轮筛选。

csharp 复制代码
example_selector = MaxMarginalRelevanceExampleSelector.from_examples(
    examples,
    embeddings,
    FAISS,
    k=1  #这里的 k 决定了挑选的轮数
)

我们假设 λ = 0.5(即相关性和多样性各占一半权重)。

第一轮挑选:只看相关性

此时最终的结果集 S 还是空的,没有任何元素被选中,所以公式里的 Dj ∈ S(已选集合)为空。 因为没有

Dj,公式后半部分的"多样性惩罚项" (1 - λ) ⋅ max Sim₂(Di, Dj) 也就无从计算,直接视为 0。

所以,第一次计算时,MMR 公式实际上退化成了: MMR = λ ⋅ Sim₁(Di, Q)

这意味着,算法会直接从候选池里,挑出那个和用户输入 Q 最相关、得分最高的 Di,作为第一个被选中的元素。

此时已选集合 S 是空的,没有 Dj,所以不需要计算多样性惩罚。公式退化为:MMR = 0.5 × 相关性。

算法会把"走"和四个备选示例的 question 进行语义相似度对比:

开心 vs 走:语义不相关,假设相似度 0.1 → 得分 0.05

高 vs 走:语义不相关,假设相似度 0.05 → 得分 0.025

精力充沛 vs 走:语义不相关,假设相似度 0.1 → 得分 0.05

粗 vs 走:语义不相关,假设相似度 0.05 → 得分 0.025

结果:虽然都很不相关,但"开心"和"精力充沛"勉强排在前两名。假设"开心"以微弱优势胜出。

动作:{开心, 伤心} 被选中,放入已选集合 S。

此时 S = {开心}。

第二轮挑选:相关性与多样性并重

现在 S 里已经有了 {开心},它变成了 Dj。算法在评估剩下的三个备胎(高、精力充沛、粗)时,不仅要算它们和"走"的相关性,还要算它们和已入选的"开心"的相似度(作为惩罚项)。

公式:MMR = 0.5 × 相关性 - 0.5 × max(与"开心"的相似度)

候选者:高

与"走"的相关性:极低 (0.05)

与 Dj"开心"的相似度:极低 (0.1)

最终得分:0.5×0.05 - 0.5×0.1 = -0.025

候选者:精力充沛

与"走"的相关性:极低 (0.1)

与 Dj"开心"的相似度:极高 (0.9) (因为"精力充沛"和"开心"都是形容积极情绪的词)

最终得分:0.5×0.1 - 0.5×0.9 = -0.4 (被严重扣分!)

候选者:粗

与"走"的相关性:极低 (0.05)

与 Dj"开心"的相似度:极低 (0.1)

最终得分:0.5×0.05 - 0.5×0.1 = -0.025

结果:虽然大家的得分都是负的(因为跟"走"都不相关),但"高"和"粗"因为没有被惩罚,分数远高于"精力充沛"。假设"高"胜出。

动作:{高, 低} 被选中,放入已选集合 S。

此时 S = {开心, 高}。

问题:

为什么跟Dj相似就要惩罚?

跟 Dj 相似就要惩罚,核心原因是为了消除信息冗余,提升结果的多样性。

保证Di和Q的相似性,降低 S集合中Dj的相似性,保证 Dj的多样性。

相关推荐
JieE21214 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack201 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树1 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术2 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦2 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050732 天前
(一)小红的数组操作
算法·编程语言
怕浪猫2 天前
Electron 系列文章封面图
算法·架构·前端框架