小智是一家自助火锅店的老板,最头疼的事不是食材不够,而是怎么从几百道菜品里,给客人配出“一桌好菜”。如果全上客人最爱吃的和牛卷,第一口惊艳,第三口就腻了;如果为了花样新奇,每样都来一点,又可能端上一桌谁都不爱吃的“黑暗料理”。推荐系统在冷启动阶段面临的正是这个难题——新用户几乎没有历史记录,系统不知道他喜欢什么,却又必须立刻端出第一桌“菜”。这时,光靠“好不好吃”的单维度排序是不够的,还得考虑“这一桌菜够不够多样”。行列式点过程(Determinantal Point Process,DPP)就是一把神奇的“数学秤”:把每道菜想象成一根指向不同方向的筷子,行列式称量的,就是这些筷子在桌上“摊开”的面积——筷子张得越开,说明这桌菜花样越多。DPP 在推荐重排序领域正是用这把秤,帮你从候选清单里挑出“既高品质、又彼此不撞味”的那一桌。

岗位关联

对于 AI 从业者而言,DPP 是解决推荐多样性、避免“信息茧房”的实用重排序工具,理解它能让你的推荐系统在点击率之外,真正赢得用户的长期信任与惊喜感。

目录
  1. 可视化演示
  2. 多样性问题起源
  3. 核矩阵构造
  4. 行列式几何意义
  5. DPP概率模型
  6. 贪心推理算法
  7. MapReduce加速
  8. 效果评估对比
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示DPP核矩阵质量-多样性分解(L=q·S·q)、贪心采样最大化行列式选择多样化子集、DPP与MMR多样性方法性能对比,交互切换核心环节。

本节配有交互动效(进入视口后自动加载,约 3KB)。

DPP核矩阵与质量-多样性分解 核矩阵L由质量分q和相似度S构成,L_ij=q_i×S_ij×q_j 对角线为质量平方,非对角线反映物品间相似度,高相似降低多样性 L_ij = q_i · S_ij · q_j 质量-多样性分解使DPP自然平衡相关性与多样性

多样性问题起源

新客人第一次走进小智的火锅店,没有会员档案、没有口味偏好。小智不能问太多问题,怕打扰;也不能只凭直觉乱上菜,怕砸招牌。这种“什么都不知道却必须马上端出一桌菜”的处境,正是推荐系统的冷启动。在冷启动阶段,用户行为数据稀疏得像一张白纸,系统唯一能确定的是“候选人尽皆知的热门品”,但把所有热门品堆在一起,客人味觉很快麻木——这不只是体验差,还会让用户误以为这家店只有一种味道。

推荐系统平时最朴素的思路,是按预估点击率从高到低排一条长队,取前 N 个。这个思路就像“哪道菜点单最多就上哪道”,在信息充足时有效,但在冷启动时它会把最热门的几样菜全都端上来,造成“审美疲劳”——数学上叫多样性不足。为了缓解这个问题,传统方法会引入一种叫 MMR(最大边际相关性) 的贪心策略:每选一道新菜,都要扣除它与已选菜谱中“最相似那道菜”的相似度。MMR 的公式可以写成:

小智试过 MMR 后觉得,它像一位只记得“上一个菜别重复”的领位员,却忘了看整桌的“大局”。真正的好菜单,应当让每道菜之间都“相得益彰”,而不是两两之间只躲开最相似的那一个。这份执念,把他引向了行列式点过程。

MMR:arg⁡max⁡i∈R[λ qi−(1−λ)max⁡j∈SSij]\mathrm{MMR:}\quad \mathop{\arg\max}_{i \in R} \left[ \lambda\, q_i - (1-\lambda) \max_{j \in S} S_{ij} \right]
MMR 公式的含义是:每道候选菜最终得分 = 单品质分 − 与已选菜单里最像那道菜的相似度。它像一位“矫枉过正”的领位员,只盯着当前菜单里最像的一道去惩罚,并没有全局查看整桌菜的整体搭配。
  1. 质量项 $\lambda q_i$$q_i$ 是菜品 $i$ 自身的吸引力得分,$\lambda$ 控制“质量”的重要程度。它提醒我们,推荐不能为了多样而忘记好吃。
    λ qi\lambda\, q_i
  2. 相似惩罚 $(1-\lambda) \max_{j \in S} S_{ij}$先找出与候选菜 $i$ 在已选集合 $S$ 中最相似的那道菜,用相似度 $S_{ij}$ 作为惩罚值。它只盯着“最像的那道”,是 MMR 的典型特征。
    (1−λ)max⁡j∈SSij(1-\lambda) \max_{j \in S} S_{ij}
  3. 相减融合用质量减去最大相似度,得到最终边际得分。这道算术题只做了“单点对比”,忽视了整桌菜之间的全局搭配。
    λ qi−(1−λ)max⁡j∈SSij\lambda\, q_i - (1-\lambda) \max_{j \in S} S_{ij}
  4. $\arg\max$ 选取从候选集合 $R$ 中挑出边际得分最高的那道菜加入菜单。MMR 每步都看似合理,最终却未必是全局最丰富的一桌。
    arg⁡max⁡i∈R[⋯ ]\mathop{\arg\max}_{i \in R} \left[ \cdots \right]

核矩阵构造

怎样把“整桌菜的搭配”装进一个数学对象里?小智想了个办法:给每道菜两个标签。第一个标签是“品质分”,记作 $q_i$,代表这道菜本身的诱人程度——和牛卷分数高,创意冰粉分数低一些。第二个标签是“撞味程度”,任意两道菜 $i$ 和 $j$ 之间都有一个相似度 $S_{ij}$,蘑菇和香菇的 $S$ 接近 1,蘑菇和三文鱼刺身的 $S$ 几乎为 0。把这两个标签组合起来,就得到核矩阵 $L$ 的每个元素:

核矩阵就像一个“菜品关系登记簿”,每一格都记录两道菜之间的化学反应。小智看着这本登记簿,心想:如果有办法能同时翻看所有格子的信息,而不是像 MMR 那样只看一列,也许就能称出整桌菜的“花样面积”了。

Lij=qi×qj×SijL_{ij} = q_i \times q_j \times S_{ij}
核矩阵是 DPP 的心脏:它把“每道菜有多好”(质量)和“两道菜有多像”(多样性)乘在一起,存进一个方方正正的表里。表里第 $i$ 行第 $j$ 列,就是菜品 $i$ 和菜品 $j$ 共同对“多样性”的贡献。
  1. $q_i$(第一道菜的质量分)菜品 $i$ 的吸引力得分,来自 CTR 预估模型或人工打分。质量越高,越容易被选进最终菜单。
    qiq_i
  2. $q_j$(第二道菜的质量分)菜品 $j$ 的吸引力得分。两项质量相乘,意味着“两强相遇”才会给这对组合更高的基础分。
    qjq_j
  3. $S_{ij}$(两菜相似度)取值范围通常是 $[0,1]$,越接近 1 越相似。它是多样性的“刹车片”:越相似,乘积中的这一项就越小。
    SijS_{ij}
  4. 三项连乘质量与相似度共同作用。当 $i=j$ 时 $S_{ii}=1$,对角线上只剩 $q_i^2$,代表单品自身的“底气”;当 $i \neq j$ 时,相似度开始压低核值。
    Lij=qi×qj×SijL_{ij} = q_i \times q_j \times S_{ij}

行列式几何意义

行列式对初学者来说像个神秘的“黑盒计算”,但它的几何意义非常直观:如果把两道菜分别想象成从原点出发的两根筷子,行列式就是这两根筷子围成的平行四边形面积。以两道菜 $i,j$ 为例,它们的核矩阵是 $2\times 2$:

推广到三道菜、四道菜,行列式的意义也随之升级:它称量的是这些向量在空间里张成的“平行体体积”。小智现在明白了——他想要的“这桌菜够不够丰富”,原来可以用一个体积数字来衡量。体积越大,菜与菜之间越“各占一方”,整桌越丰盛。行列式,就是那把称体积的秤。

det⁡(L{i,j})=qi2×qj2×(1−Sij2)\det(L_{\{i,j\}}) = q_i^2 \times q_j^2 \times \left(1 - S_{ij}^2\right)
这个公式透露了两个信息:第一,行列式正比于两道菜质量的平方之积,质量越高“底气”越足;第二,它乘以 $(1 - S_{ij}^2)$,相似度越接近 1,这个因子越小,行列式越小。两根筷子方向完全一致($S_{ij}=1$)时面积为 0——两道一模一样的菜,等于没有增加任何花样。
  1. $q_i^2 q_j^2$(质量底气)两道菜各自质量的乘积再平方,代表这组组合的“硬实力”。这项越大,行列式越有起飞的基础。
    qi2×qj2q_i^2 \times q_j^2
  2. $1 - S_{ij}^2$(多样性因子)用 1 减去相似度平方。相似度越高,这个因子越小;完全不相似时它接近 1,让行列式“全额保留”。
    1−Sij21 - S_{ij}^2
  3. 整体乘积质量底气乘以多样性因子。它说明行列式同时奖励“好吃”和“不撞味”,两者缺一不可。
    qi2×qj2×(1−Sij2)q_i^2 \times q_j^2 \times (1 - S_{ij}^2)
  4. 极端情形当 $S_{ij}=1$ 时因子为 0,行列式为 0,说明两菜完全重复;当 $S_{ij}=0$ 时行列式最大,说明完全不相关的新花样贡献最大。
    Sij=1⇒det⁡=0S_{ij}=1 \Rightarrow \det=0

DPP概率模型

有了“体积秤”,小智还想回答一个问题:面对几百道候选菜,哪些“一桌组合”更值得端给客人?DPP 的做法是给每个子集分配一个概率,这个概率正比于该子集行列式的大小:

DPP 本质上是一个“会挑组合的概率转盘”。小智发现,它对单个物品的吸引力有天然的偏好——质量越高越容易被转中;但它也惩罚“扎堆”——一旦某几道菜相似度高,它们同时出现在同一桌的概率就断崖式下跌。这种“互相排斥”的性格,正是推荐列表需要的“克制感”。

P(Y)=det⁡(LY)det⁡(L+I)P(Y) = \frac{\det(L_Y)}{\det(L + I)}
分子 $\det(L_Y)$ 度量候选组合 $Y$ 的“质量 × 多样性”;分母 $\det(L+I)$ 是归一化常数,保证所有可能子集的概率加起来等于 1。这个公式就像把每桌菜的“花样面积”画成不同大小的扇形,面积越大,被转盘指针选中的机会越大。
  1. 分子 $\det(L_Y)$$L_Y$ 是从核矩阵 $L$ 中抽取 $Y$ 中物品对应的行与列组成的小矩阵。它的行列式代表这组物品的整体质量与多样性的乘积,是概率的“得分”。
    det⁡(LY)\det(L_Y)
  2. 分母 $\det(L + I)$用单位矩阵 $I$ 调整后的核矩阵行列式。数学上有恒等式 $\det(L+I) = \sum_{Y'} \det(L_{Y'})$,它穷举了所有子集的行列式之和,作为归一化常数,确保概率总和为 1。
    det⁡(L+I)\det(L + I)
  3. 比值即概率得分除以总得分,得到 $0$ 到 $1$ 之间的概率。这个比例自动完成“质量与多样性”的权衡——重复的组合因行列式小而概率低。
    P(Y)=det⁡(LY)det⁡(L+I)P(Y) = \frac{\det(L_Y)}{\det(L + I)}

贪心推理算法

有了概率模型,理论上可以枚举所有子集找最大概率的组合,但候选菜有几百道,组合数是指数级的,算到天荒地老也出不了菜单。小智想到后厨的实战智慧:与其一次配齐一桌,不如一道一道地加菜。每次加入能让“花样面积”增量最大的那道菜,这就是 DPP 贪心推理。它的目标函数是已选集合行列式的对数,边际增益为:

小智在后厨验证这个算法:第一道先选品质最高的和牛卷,第二道开始,系统自动避开同类肉卷,挑了一盘时蔬;第三道又选了一碟海味。整个过程就像经验丰富的配菜师傅——每加一道菜都先掂量“会不会和已有的重复”,再用数学精确算出增量。最终端上桌的,是一份让客人惊喜连连的“花样拼盘”。

Δi=log⁡det⁡(LY∪{i})−log⁡det⁡(LY)=log⁡(Lii−c⊤c)\Delta_i = \log \det(L_{Y \cup \{i\}}) - \log \det(L_Y) = \log\left( L_{ii} - \mathbf{c}^\top \mathbf{c} \right)
这个公式把“加入菜 $i$ 后花样面积增加了多少”变成了一个简单的对数差。右边 $L_{ii}$ 是菜 $i$ 自身的质量底气,$\mathbf{c}^\top\mathbf{c}$ 则是它跟已选菜单“重叠”的部分——重叠越大,净增益越小。贪心算法每步挑 $\Delta_i$ 最大的菜加入,虽然不保证全局最优,却有很强的理论保证(目标函数是子模函数),实践中效果极好。
  1. $\log \det(L_{Y \cup \{i\}})$(加入后的花样面积)先算把 $i$ 加进去后新集合的行列式对数。取对数可以让连乘变为连加,数值上更稳定,也便于比较增量。
    log⁡det⁡(LY∪{i})\log \det(L_{Y \cup \{i\}})
  2. 减去 $\log \det(L_Y)$(原来的花样面积)两者相减就是边加入边增加的“面积增量”。如果增量很小甚至为负,说明 $i$ 与已选菜太像,不值得加入。
    log⁡det⁡(LY∪{i})−log⁡det⁡(LY)\log \det(L_{Y \cup \{i\}}) - \log \det(L_Y)
  3. $L_{ii}$(菜 $i$ 自身底气)质量分的平方,代表“单独吃它有多好”。它是增量的上限——再差的搭配也不至于让这道的自身价值消失。
    LiiL_{ii}
  4. $\mathbf{c}^\top \mathbf{c}$(与已选菜单的重叠量)向量 $\mathbf{c}$ 由解方程 $V\mathbf{c} = L_{iY}$ 得到,$V$ 是已选集合的 Cholesky 因子。这个二次型量化了 $i$ 与已选集合的冗余度,是增量公式的“惩罚项”。
    c⊤c\mathbf{c}^\top \mathbf{c}
  5. 相减取对数自身底气减去冗余惩罚,再取对数得到净增益。这个计算每次只需 $\mathrm{O}(k^2)$ 时间($k$ 为已选数量),比重新计算整个行列式快得多。
    log⁡(Lii−c⊤c)\log\left( L_{ii} - \mathbf{c}^\top \mathbf{c} \right)

MapReduce加速

实际推荐场景中,候选集可能有数万道“菜”,即使单步贪心很快,全量扫描仍然昂贵。小智的后厨来了几百个帮厨,他决定把出菜流程改成“分头行动、汇总定夺”——这正是 MapReduce 的思路。具体分为三步:先把候选菜品按类别(荤、素、海鲜、甜品等)分到不同的小组,这就是 Map(映射)分块;每个小组在自己的块内独立跑一遍 DPP 贪心,各自选出本组最优秀的几道菜,这就是 局部贪心;最后把各组候选合并到一个较小的集合上,再跑一次全局贪心完成精排,这就是 Reduce(归约)合并。

分块背后的数学依据是:当块间相似度很低时,整个集合的行列式可以近似分解为各块行列式的乘积:

小智的后厨从此井井有条:帮厨们各管一摊,先把每个类别里的“尖子生”挑出来,再由主厨在精英小圈子里定最终菜单。这个流程不仅快,而且保留了 DPP 的灵魂——组内不重复、组间不干扰。MapReduce 让 DPP 从实验室真正走向了“千人千面”的线上服务。

det⁡(LY)≈∏b=1Bdet⁡(LYb)\det(L_Y) \approx \prod_{b=1}^{B} \det(L_{Y_b})
这个近似式把“全桌花样面积”拆成了“每组花样面积”的乘积。只要各组之间“井水不犯河水”(相似度低),乘法近似就成立。它让 DPP 从单机计算扩展到分布式集群,保证了毫秒级的重排序响应。
  1. $B$ 个分块把候选集划分成 $B$ 个互不重叠的块,每块对应一个 Map 任务。块数越多,并行度越高。
    b=1,2,…,Bb = 1, 2, \ldots, B
  2. $\det(L_{Y_b})$(块内行列式)每块独立计算自己子集的行列式。块内仍然用完整 DPP 逻辑,保证局部质量与多样性。
    det⁡(LYb)\det(L_{Y_b})
  3. 连乘近似理论上全集合行列式包含大量块间交叉项,但当块间相似度极低时,交叉项趋近于 0,乘积近似成立。
    ∏b=1Bdet⁡(LYb)\prod_{b=1}^{B} \det(L_{Y_b})
  4. $\approx$(近似条件)近似只在块间相似度低时可靠。因此实际工程中分块常按类别或聚类结果进行,让“撞味”尽量留在块内。
    det⁡(LY)≈∏b=1Bdet⁡(LYb)\det(L_Y) \approx \prod_{b=1}^{B} \det(L_{Y_b})

效果评估对比

DPP 到底比 MMR 和纯质量排序好多少?小智决定用数据说话。他邀请一批“冷启动”新客人做盲测,每桌菜分别由纯质量排序、MMR、DPP 三种方法配出。衡量一桌菜“花样多不多”,业界常用的指标是 ILD(Intra-List Distance,列表内不相似度):

实验结果显示:纯质量排序的 ILD 最低,几乎全是高分热门款;MMR 的 ILD 有所提升,但因为它只惩罚“最像的那道”,偶尔还是会出现三道菌菇类菜品扎堆;DPP 的 ILD 最高,同时因为核矩阵里的质量项 $q$ 在把关,整体点击率并不输于前两者。小智的客人满意度明显上升,回头客也多了——这正是 DPP 在线上系统里的价值:用数学的“花样面积”,换来了用户长期的新鲜感与忠诚度。

ILD(S)=2k(k−1)∑1≤i<j≤k(1−Sij)\mathrm{ILD}(S) = \frac{2}{k(k-1)} \sum_{1 \le i < j \le k} \left(1 - S_{ij}\right)
ILD 计算的是推荐列表中所有“菜对”的平均不相似度。$1 - S_{ij}$ 越大说明两道菜越不搭边,所有菜对求平均后,ILD 越高代表整桌花样越丰富。它是衡量多样性的“直尺”。
  1. $\frac{2}{k(k-1)}$(菜对数量的倒数)$k$ 是列表长度,$\frac{k(k-1)}{2}$ 是全部无序菜对的数量,乘 2 后取倒数用于求平均。
    2k(k−1)\frac{2}{k(k-1)}
  2. $1 - S_{ij}$(两菜不相似度)相似度 $S_{ij}$ 的补数。完全相同的菜为 0,完全不同的菜为 1,是从相似度到多样性的自然翻转。
    1−Sij1 - S_{ij}
  3. 求和并取平均对所有 $i<j$ 的菜对求和,再乘以倒数归一化,得到平均不相似度。ILD 越高,说明列表内部越“百花齐放”。
    2k(k−1)∑1≤i<j≤k(1−Sij)\frac{2}{k(k-1)} \sum_{1 \le i < j \le k} \left(1 - S_{ij}\right)

AI 应用场景

电商推荐重排序:搭配“购物车”

阶段:召回与精排之后的重排序阶段

解决的问题:精排按点击率排序容易让用户看到清一色的“爆款同款”,尤其在用户历史行为稀疏时缺少个性。传统做法直接截断前 $k$ 个,多样性差,用户容易疲劳并放弃浏览。

具体案例:某电商平台对“夏季上新”频道做冷启动推荐,用户没有历史购买记录。系统用 DPP 对精排结果做最终重排:核矩阵的质量分来自 CTR 预估,相似度矩阵由商品标题和类目向量计算得出。重排后的 10 个商品里,连衣裙、防晒衣、凉鞋、草帽各占其位,ILD 提升约 40%,人均浏览深度提升 27%。

内容信息流去重:打破“信息茧房”

阶段:信息流内容排序阶段

解决的问题:短视频信息流如果只按用户兴趣排序,容易陷入“越刷越相似”的怪圈,导致用户流失。DPP 可以将“内容多样”纳入排序目标,在保证相关性的同时主动引入不同话题。

具体案例:某资讯 App 在面对新注册用户时,使用 DPP 从精排候选的 200 条新闻中选出 20 条,覆盖体育、科技、财经、生活等 8 个一级类目。相比 MMR 方案,新用户 7 日留存提升 5 个百分点,曝光类目覆盖率从 45% 提升到 78%。

搜索排序小结:搜索结果多样化

阶段:搜索结果重排阶段

解决的问题:搜索“苹果”时,全部返回 iPhone 手机而忽略苹果公司新闻、苹果水果食谱,是典型的多义查询歧义问题。DPP 通过核矩阵在结果页内压制相似文档,让多个语义侧面都有露脸机会。

具体案例:某搜索团队在搜索结果页接入 DPP 重排序,核矩阵质量分由相关性模型给出,相似度由文档向量余弦计算。重排后,第一屏结果覆盖 4 个以上语义侧面,用户平均搜索轮次减少 33%,点选深度提升 20%。

Python 演示

python86 行
import numpy as npimport math  def make_kernel(q, S):    """构造DPP核矩阵:L_ij = q_i * q_j * S_ij"""    return np.outer(q, q) * S  def greedy_dpp(L, k):    """DPP贪心重排序:每次选择使行列式增量最大的物品"""    n = L.shape[0]    selected = []    rest = list(range(n))    V = np.zeros((k, k))    for step in range(k):        best = -1        best_gain = -1e18        best_c = np.zeros(0)        for i in rest:            if not selected:                gain = math.log(L[i, i] + 1e-9)            else:                c = np.linalg.solve(V[:step, :step], L[i, selected])                gain = math.log(L[i, i] - c @ c + 1e-9)            if gain > best_gain:                best_gain = gain                best = i                best_c = c if selected else np.zeros(0)        if not selected:            V[0, 0] = math.sqrt(L[best, best])        else:            remain = math.sqrt(max(L[best, best] - best_c @ best_c, 1e-9))            V[:step, step] = best_c            V[step, step] = remain        selected.append(best)        rest.remove(best)    return selected  def greedy_mmr(q, S, k, lam=0.5):    """MMR基线:最大边际相关性重排"""    selected = []    rest = list(range(len(q)))    for _ in range(k):        best = -1        best_score = -1e18        for i in rest:            max_sim = max([S[i, j] for j in selected], default=0.0)            score = lam * q[i] - (1 - lam) * max_sim            if score > best_score:                best_score = score                best = i        selected.append(best)        rest.remove(best)    return selected  def ild(items, S):    k = len(items)    pairs = k * (k - 1) / 2    return sum(1 - S[i, j] for idx, i in enumerate(items) for j in items[idx + 1:]) / pairs  def main():    rng = np.random.RandomState(42)    n = 8    q = rng.uniform(0.5, 1.0, n)    feat = rng.randn(n, 4)    S = np.exp(-0.5 * ((feat[:, None, :] - feat[None, :, :]) ** 2).sum(-1))    L = make_kernel(q, S)     dpp_order = greedy_dpp(L, 4)    mmr_order = greedy_mmr(q, S, 4)    top_q = list(np.argsort(-q)[:4])     print("DPP重排:", dpp_order)    print("MMR重排:", mmr_order)    print("纯质量Top:", top_q)    print("DPP ILD=%.3f" % ild(dpp_order, S))    print("MMR ILD=%.3f" % ild(mmr_order, S))    print("Top ILD=%.3f" % ild(top_q, S))  if __name__ == "__main__":    main()
目的:在一个 8 样本的小数据集上同时实现 DPP 贪心重排序、MMR 基线和纯质量排序,并对比三种方法的 ILD 多样性指标,直观验证 DPP 在多样性与质量权衡上的优势。
  1. return np.outer(q, q) * S用质量向量的外积逐元素乘相似度矩阵,一次性构造核矩阵 $L$,对应正文中的 $L_{ij}=q_i q_j S_{ij}$。
  2. c = np.linalg.solve(V[:step, :step], L[i, selected])解三角方程 $V\mathbf{c}=L_{iY}$,用 Cholesky 因子快速得到候选物品与已选集合的重叠系数。
  3. gain = math.log(L[i, i] - c @ c + 1e-9)利用 Schur 补公式计算边际增益,$c@c$ 是冗余惩罚,加极小值防止对 0 取对数。
  4. V[:step, step] = best_c选中物品后更新 Cholesky 因子,把新列的系数写入矩阵,使后续增量计算保持 $\mathrm{O}(k^2)$。
  5. score = lam * q[i] - (1 - lam) * max_simMMR 的边际得分:质量减最相似项的相似度,作为传统方法的对照组。
  6. print("DPP ILD=%.3f" % ild(dpp_order, S))输出 ILD 指标,数值越高代表重排列表越多样,是判断 DPP 是否生效的关键证据。

常见误区

误区“DPP 选出来的东西很杂很全,但会不会推荐一堆用户根本不喜欢的东西?它是不是只在乎多样、不在乎质量?”

正解DPP 的核矩阵是质量与相似度的乘积,$L_{ij}=q_i q_j S_{ij}$,质量项 $q$ 直接参与行列式计算。质量高的物品天然有更大的对角元,更容易进入高概率子集。好比小智摆“花样拼盘”时,每一道入选菜都得先过“品质分”这一关,只新奇却难吃的菜永远上不了桌。实验也证明 DPP 在提升 ILD 的同时不会显著牺牲点击率。

为何常见:因为大家看到 DPP 的招牌效果是“去重”和“花样”,再加上数学形式晦涩,容易误以为它是纯多样性工具,忽略了核矩阵中的质量通道。

误区“行列式的值就是集合好坏分数,我直接选 det(L_Y) 最大的子集不就行了?”

正解行列式本身会随集合大小增长,不能跨不同大小的集合直接比较。而且 DPP 的最终选择是“带概率的采样”,并非单纯取最大行列式。真正可靠的做法是在固定大小的候选列表上比较 logdet 增量,或通过概率公式 $P(Y) \propto \det(L_Y)$ 做采样。就像比较两桌菜时,一桌有 20 道菜的行列式通常大于一桌有 3 道菜,但不代表 20 道菜的搭配更好。

为何常见:人们习惯把“分数”理解为越大越好,忽略了行列式是一个随维度膨胀的体积度量,而不是绝对值意义上的质量分。

误区“MMR 不也是边选边扣除相似度吗?DPP 不就是它的另一种写法吗?”

正解两者差异明显。MMR 每步只减去“与已选集合中最相似一项”的相似度,是局部近邻惩罚;DPP 通过行列式考察新物品与整个已选集合构成的几何体积增量,等价于考虑它和所有已选物品的整体交互。此外 DPP 有严格的概率模型与子模性理论保证,还可用 Cholesky 增量实现高效推理,这些 MMR 都不具备。

为何常见:两者都出现在“重排序去重”场景,形式上都有“质量减相似度”的影子,初学者容易把它们归为同一类启发式方法,而忽略了概率建模上的本质区别。

误区“DPP 的核矩阵是不是要专家手工调一堆参数?这样落地成本太高了吧。”

正解核矩阵的两个零件都有现成来源:质量分 $q$ 直接复用 CTR 预估或相关性模型的输出;相似度 $S$ 可由物品 embedding 的余弦相似度、类目标签等自动计算。工程上甚至可以在精排模型后加一层轻量 DPP,完全复用已有特征,无需额外标注。小智的后厨也不需要重新发明菜谱,只需要把现成的“口味档案”填进登记簿即可。

为何常见:很多人首次接触核矩阵时被数学符号吓住,以为每个 $L_{ij}$ 都要手工指定,实际上 $L$ 是质量与相似度两套成熟信号的“自动组合”。

误区“行列式是 $O(n^3)$,候选集几万个,DPP 只适合做离线论文实验吧?”

正解DPP 的贪心单步增量可以通过 Cholesky 因子维护做到 $O(k^2)$($k$ 为已选数量),加上 MapReduce 分块并行、先局部后全局,线上候选几万条也能在毫秒级完成重排。很多大厂在推荐精排后接入 DPP 做实时重排,正是因为它有这套成熟的加速体系。小智的后厨用“分头试菜、汇总定夺”的方式,让配菜速度反而比一个人全流程琢磨更快。

为何常见:人们把“行列式”和“矩阵求逆”的复杂度直接画等号,忽略了贪心推理中可以利用增量更新避免每次重新计算整个行列式。

面试题

Q1. 在 DPP 中,核矩阵 $L$ 的元素 $L_{ij}$ 通常如何构造?

单选题 · easy

  • A.$q_i \times q_j \times S_{ij}$← 正确答案
  • B.$q_i + q_j + S_{ij}$
  • C.$q_i \times S_{ij} / q_j$
  • D.$S_{ij} - q_i \times q_j$

答案:A。$L_{ij}$ 由物品 $i$ 的质量分、物品 $j$ 的质量分和两物相似度三项相乘构成,让“质量”与“多样性”共同生效。选项 B 是加法无法让相似度起到“乘法抑制”作用;选项 C 和 D 在数学上都不符合 DPP 核矩阵定义。

Q2. 两个物品构成的子集行列式 $\det(L_{\{i,j\}})$ 的几何意义是什么?

单选题 · easy

  • A.两个物品的维度大小
  • B.两根向量张成的平行四边面积← 正确答案
  • C.两个向量的长度之和
  • D.核矩阵对角线元素之和

答案:B。行列式对应向量张成平行体的体积(二维时是面积),向量夹角越大、体积越大,代表两个物品越多样。选项 A 没有几何对应,选项 C 是向量模长和,选项 D 是矩阵的迹,均与行列式无关。

Q3. DPP 概率公式 $P(Y)=\det(L_Y)/\det(L+I)$ 中,分母 $\det(L+I)$ 的作用是什么?

单选题 · mid

  • A.归一化所有子集概率总和为 1← 正确答案
  • B.放大质量分数的作用
  • C.抵消相似度的高频噪声
  • D.将核矩阵转化为协方差矩阵

答案:A。数学恒等式 $\det(L+I)=\sum_{Y'}\det(L_{Y'})$ 表明分母是全体子集行列式之和,用于归一化。它不是放大质量、也不是去噪或协方差转换,只是让 $P(Y)$ 成为合法概率。

Q4. DPP 贪心推理每一步的核心动作是什么?

单选题 · mid

  • A.加入使 logdet 边际增益最大的物品← 正确答案
  • B.加入预估点击率最高的物品
  • C.删除与已选集合最相似的物品
  • D.按均匀分布随机采样一个物品

答案:A。贪心算法维护已选集合的 Cholesky 因子,对每个候选计算 $\Delta_i=\log\det(L_{Y\cup\{i\}})-\log\det(L_Y)$,选增量最大者。选项 B 是纯质量排序,选项 C 是反方向操作,选项 D 是随机策略,都不符合贪心目标。

Q5. 相比 MMR,DPP 的优势包括哪些?

多选题 · mid

  • A.有概率模型做理论支撑← 正确答案
  • B.能系统权衡质量与多样性← 正确答案
  • C.可用 Cholesky 增量加速推理← 正确答案
  • D.完全不需要质量得分

答案:ABC。DPP 是概率模型,核矩阵同时包含质量与相似度,且增量推理维护 Cholesky 因子非常高效。选项 D 错误:DPP 必须依赖质量分 $q$ 构造核矩阵,没有质量分就无法工作。

Q6. 在 DPP 贪心算法的 Cholesky 增量公式 $\log(L_{ii}-\mathbf{c}^\top\mathbf{c})$ 中,$\mathbf{c}^\top\mathbf{c}$ 表示什么?

单选题 · hard

  • A.候选物品与已选集合的冗余度量← 正确答案
  • B.候选物品的独立质量分
  • C.全局的总相似度
  • D.归一化常数

答案:A。$\mathbf{c}$ 是解 $V\mathbf{c}=L_{iY}$ 得到的系数,$\mathbf{c}^\top\mathbf{c}$ 量化候选物品被已选集合“解释”掉的部分,即冗余度。它越大,净增益越小。选项 B 对应 $L_{ii}$,选项 C、D 与增量公式无关。

Q7. 基于 MapReduce 的 DPP 加速方案包括哪些步骤?

多选题 · hard

  • A.把候选集按类目或聚类分块← 正确答案
  • B.每个块内独立运行局部 DPP 贪心← 正确答案
  • C.将各块输出合并后做全局精排← 正确答案
  • D.用随机采样替代所有行列式计算

答案:ABC。加速思路是“分块-局部-合并”:先分块,再块内贪心,最后合并精排。块间相似度低时近似公式 $\det(L_Y)\approx\prod_b\det(L_{Y_b})$ 成立。选项 D 是不同思路,MapReduce 方案并没有放弃行列式计算。

Q8. 列表多样性指标 ILD 的 $2/(k(k-1))$ 系数是什么含义?

单选题 · mid

  • A.所有无序物品对数量的倒数← 正确答案
  • B.覆盖率倒数
  • C.列表长度的一半
  • D.推荐轮次倒数

答案:A。长度为 $k$ 的列表共有 $k(k-1)/2$ 个无序物品对,乘 2 取倒数后对全部“不相似度”求和求平均。它衡量的是平均不相似程度,与覆盖率、长度、轮次无关。

Q9. 冷启动阶段引入 DPP 的主要价值是什么?

单选题 · easy

  • A.用多样性弥补用户信息稀疏← 正确答案
  • B.直接预测用户的评分
  • C.自动扩充训练数据
  • D.替代召回阶段的所有逻辑

答案:A。冷启动时用户行为少,系统分不清偏好,主动提供多样内容可以覆盖多种可能兴趣、减少流失。DPP 不负责评分预测、数据扩充或召回,它专注于重排序阶段的多样性优化。

Q10. 关于 DPP 的行列式性质,下列说法正确的有哪些?

多选题 · hard

  • A.物品越相似,子集行列式越趋近于 0← 正确答案
  • B.质量分越高的物品,越容易被选入子集← 正确答案
  • C.DPP 的概率只取决于相似度矩阵
  • D.核矩阵 $L$ 需要保持对称半正定← 正确答案

答案:ABD。相似度高使行列式趋于 0,质量高使对角元大从而增加行列式,核矩阵由 $q_i q_j S_{ij}$ 构成天然对称半正定。选项 C 错误:DPP 概率同时依赖质量分 $q$ 和相似度矩阵 $S$,二者缺一不可。