在推荐系统的重排阶段,我们常面临结果同质化问题——精排结果相似物料扎堆,导致用户体验单调。行列式点过程(Determinantal Point Processes, DPP)通过数学建模相关性与多样性的平衡,成为解决该问题的经典方案。


一、DPP的核心思想

DPP将推荐列表视为一个点过程,其核心是计算子集出现的概率。给定候选集 ( Z )(精排输出的Top-N物料),DPP定义子集 ( Y \subseteq Z ) 出现的概率为:
P(Y)∝det⁡(LY) P(Y) \propto \det(L_Y) P(Y)det(LY)
其中 ( L ) 是核矩阵(Kernel Matrix),( L_Y ) 是 ( L ) 的 ( Y ) 对应的子矩阵。行列式 (\det(L_Y)) 的几何意义是向量集合构成的超平行多面体体积:

  • 体积越大 → 向量差异性越大 → 推荐多样性越强
  • 对角线元素 LiiL_{ii}Lii 表示物料 iii 的质量(如CTR得分)
  • 非对角线元素 LijL_{ij}Lij 表示物料 iiijjj 的相似度

关键公式(核矩阵构造):
L=Diag(r)⋅S⋅Diag(r) L = \text{Diag}(\mathbf{r}) \cdot S \cdot \text{Diag}(\mathbf{r}) L=Diag(r)SDiag(r)

  • r\mathbf{r}r:物料质量分向量(如精排得分)
  • SSS:物料相似度矩阵,Sij=cos(embi,embj)S_{ij} = \text{cos}(\text{emb}_i, \text{emb}_j) Sij=cos(embi,embj)

二、核矩阵 ( L ) 的工程实现
1. 基础构造法
# 输入:精排结果物料集合 Z,包含每个物料的embedding和得分
def build_kernel_matrix(Z):
    r = [item.score for item in Z]  # 质量分向量
    S = cosine_similarity([item.embedding for item in Z])  # 相似度矩阵
    L = np.diag(r) @ S @ np.diag(r)  # Diag(r) * S * Diag(r)
    return L

缺陷:( S ) 的余弦相似度可能为负,导致 ( L ) 非正定。

2. 改进方案(文档式6-29)

高斯核保证正定性
Sij=exp⁡(−dist(i,j)22σ2) S_{ij} = \exp\left(-\frac{\text{dist}(i,j)^2}{2\sigma^2}\right) Sij=exp(2σ2dist(i,j)2)

3. 个性化加权(华为pDPP)

Lij=ri⋅rj⋅Sij⋅ϕu L_{ij} = r_i \cdot r_j \cdot S_{ij} \cdot \color{red}{\phi_u} Lij=rirjSijϕu
ϕu\phi_uϕu 为用户个性化权重


三、贪婪求解:Fast Greedy MAP

直接枚举所有子集计算 (\det(L_Y)) 是指数级复杂度。Fast Greedy MAP算法(复杂度 (O(N^2 K)))是工业界首选:

def fast_greedy_map(L, K):
    Y = []          # 已选集合
    for _ in range(K):
        max_gain = -np.inf
        best_item = None
        for j in range(len(L)):
            if j in Y: continue
            gain = compute_marginal_gain(L, Y, j)  # 计算边际增益
            if gain > max_gain:
                max_gain = gain
                best_item = j
        Y.append(best_item)
        update_cached_vectors(L, Y)  # 更新中间变量(避免重复计算)
    return Y

关键优化:利用Cholesky分解的增量更新(见文档公式6-47, 6-48):
cj=1Ljj−∥vj∥2(LY,j−VTvj)dj=Ljj−∥vj∥2 \begin{align*} \mathbf{c}_j &= \frac{1}{\sqrt{L_{jj} - \|\mathbf{v}_j\|^2}} \left( L_{Y,j} - V^T \mathbf{v}_j \right) \\ d_j &= \sqrt{L_{jj} - \|\mathbf{v}_j\|^2} \end{align*} cjdj=Ljjvj2 1(LY,jVTvj)=Ljjvj2

其中 ( V ) 是Cholesky分解的三角矩阵,(\mathbf{v}_j) 是中间向量。

DPP 算法流程
在这里插入图片描述


四、实际应用技巧
  1. 特征工程
    • 质量分 ( rir_iri ):精排CTR得分 × 时长增益系数
    • Embedding:双塔模型输出的物料向量
  2. 负样本策略
    • 曝光未点击物料作为Hard Negative
    • 随机采样物料作为Easy Negative(比例100:1)
  3. 在线服务
    • Faiss加速相似矩阵计算
    • 核矩阵 ( L ) 的增量更新(新物料动态插入)

五、效果对比(Hulu案例)
算法 多样性↑ 点击率↑ 时长↑
精排基线 0.82 0.125 45s
DPP重排 0.93 0.127 51s

多样性指标:物料类别熵(Entropy),值越大越多样


六、总结

DPP的数学美感工程实用性使其成为重排阶段的核心算法:

  • 优势:严格建模相关性与多样性的trade-off
  • 挑战:核矩阵构造的合理性、大规模计算的优化
  • 趋势:与强化学习(如RNN重排)、多任务学习的结合
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐