从向量匹配到排序优化——推荐系统中的离散数学小小应用

2025 年 1 月 17 日 星期五
10

从向量匹配到排序优化——推荐系统中的离散数学小小应用

在推荐系统的实现中,如何将用户输入的查询和大量候选产品进行匹配与排序,是一个至关重要的课题。特别是当我们结合向量匹配、评分和销量等多维度特征时,排序的复杂性和业务需求会进一步提高。本文将从一个实际案例出发,探讨如何通过离散数学的思想优化排序逻辑,最终实现性能和业务目标的双赢。

背景与问题

推荐系统的核心在于找到最适合用户需求的候选产品。常见的流程包括以下几个步骤:

  • 向量匹配:通过向量数据库计算候选产品与用户查询的相似度,得到一个 score。
  • 多维度筛选:结合结构化数据库(如 Elasticsearch,简称 ES),对候选产品进行进一步筛选和排序。
  • 综合排序:在筛选后的产品中,综合 score 和其他特征(如销量)进行排序。

问题在于,向量匹配的 score 是由外部系统计算的,不能直接传入 ES,同时有希望结合其他的字段做进一步排序。我们希望根据 score 对产品进行分桶排序,并在每个分桶内按销量降序排列。

解决思路

为了解决上述问题,我们引入离散数学的分桶思想:

  • 将 score 分成若干离散范围,例如每 0.05 为一个桶。
  • 对所有产品按照 score 分桶,从大到小排序。
  • 在每个桶内,再按照销量从高到低排序。

通过这种方式,我们既保留了向量匹配的相似度信息,又结合了产品销量,实现了更符合业务需求的排序逻辑。

代码实现

以下是核心排序代码:

public static List<Item> sortItems(List<Item> items, Map<String, Float> idScoreMap) {
    if (items == null || idScoreMap == null) {
        return new ArrayList<>(); // 处理空输入
    }

    return items.stream()
            .sorted(Comparator
                    .comparing((Item item) -> {
                        // 获取分数值;如果不存在则使用默认值 0f
                        float score = idScoreMap.getOrDefault(item.id, 0f);
                        // 将分数映射到 0.05 的倍数范围内
                        return (float) (Math.floor(score / 0.05f) * 0.05f);
                    }, Comparator.reverseOrder()) // 按分桶值降序排列
                    .thenComparingInt(item -> -item.soldNum) // 在每个分桶内按销量降序排列
            )
            .collect(Collectors.toList()); // 返回排序后的列表
}

关键技术解析

  • 离散化处理 我们通过以下公式将分数划分为离散范围:

    float rangeKey = (float) (Math.floor(score / 0.05f) * 0.05f);
      

    该公式的作用是将任意分数映射到最近的 0.05 倍数范围。例如: • 0.333 → 0.30 • 0.367 → 0.35

  • 双重排序
    • 外层:按照分桶范围从大到小排序,保证高分桶的产品优先展示。
    • 内层:对每个分桶内的产品按销量降序排序,突出热销产品。
  • 流式操作 利用 Java Stream API 和链式 Comparator,代码逻辑清晰,避免了复杂的手动分组和排序操作。

性能分析

  • 时间复杂度:排序的时间复杂度为 O(n \log n),这里 n 是产品数量。由于产品总量较小(如 100 以下),性能表现良好。
  • 空间复杂度:仅使用了流操作,无需额外存储中间结果,空间开销较低。

应用场景与优势

  • 推荐系统中的多维排序 本方法特别适用于需要结合向量匹配与其他业务特征(如销量、评分等)进行综合排序的场景。
  • 灵活扩展性 离散范围的粒度(如 0.05 或 0.1)可以根据业务需求动态调整,以平衡相似度的区分度和排序的多样性。
  • 性能与可维护性 流式操作让代码更加简洁,同时保持了较高的运行效率。

使用社群帳號登入

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...