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的多样性。

相关推荐
圣光SG10 小时前
Java操作题练习(七)
java·开发语言·算法
Cx330_FCQ11 小时前
Tmux使用
服务器·git·算法
拳里剑气12 小时前
C++算法:多源BFS
c++·算法·宽度优先·多源bfs
ysa05103013 小时前
【板子】短序列dp(换成维护更小常数维度的dp)
c++·笔记·算法·板子
shwill12313 小时前
PID 算法(三)--- 增量 PID ↔ 单神经元 PID 等价映射
linux·算法
wabs66614 小时前
关于图论【卡码网110.字符串迁移的思考】
数据结构·算法·图论
hanlin0315 小时前
刷题笔记:力扣第242、349题(哈希表)
笔记·算法·leetcode
浮沉98715 小时前
二分查找算法例题(二)
算法
only-qi16 小时前
大模型Agent面试攻略:落地工程痛点、评估体系与Agentic RAG核心精讲
人工智能·算法·面试·职场和发展·langchain·rag
Gauss松鼠会18 小时前
【GaussDB】GaussDB锁阻塞源头查询
java·开发语言·前端·数据库·算法·gaussdb·经验总结