自定义搜索结果排名

由于不同行业的搜索需求可能有所不同,并且会不时发生变化,因此默认排名行为可能无法满足所有业务需求。为解决此问题,您可以使用自定义排名来修改排名行为。

本页介绍了如何在搜索请求中使用自定义排名公式,以及如何调整该公式。此功能适用于结构化数据、非结构化数据和网站数据。

概览

借助自定义排名,您可以提供一个数学表达式,该表达式依赖于一组模型计算的信号(例如语义相关性得分和关键字相似度得分)以及基于文档的信号(例如距离或文档年龄等自定义字段)。

借助自定义排名,您可以实现以下目标:

  • 提高可见性:了解哪些信号会影响搜索结果的最终排名。
  • 调整现有信号:调整各种信号(例如语义相似度、关键字匹配或文档新鲜度)的权重。
  • 纳入业务逻辑:将您自己的自定义信号从文档数据直接添加到排名公式中。
  • 系统性优化:使用开源 Python 库以编程方式发现最佳排名公式。

需要自定义排名的原因 - 示例

假设在酒店预订网站上查询了以下字符串:

luxury hotel with a large rooftop pool in Vancouver, pet-friendly and close to airport.

假设检索到以下条目:

  • 酒店 A:“温哥华首屈一指的豪华酒店,可俯瞰机场。设有令人惊艳的屋顶泳池不允许携带宠物。
  • 酒店 B:“温哥华市中心时尚现代酒店。允许携带宠物,客房宽敞。设有大型室内泳池和健身中心。”
  • 酒店 C:“一家迷人的宠物友好型精品酒店,靠近水族馆(距离市中心 10 分钟步行路程)。设有漂亮的庭院花园。没有游泳池。
  • 酒店 D:“一家标志性的乡村风格度假村。以精致的餐饮和无可挑剔的服务而闻名。设有室内泳池和水疗中心。 可应要求提供允许携宠物入住的选项。”

目录中的所有酒店都包含一个以公里 (km) 为单位的 distance_from_airport 字段。

基于嵌入的排名

搜索系统会将查询转换为单个嵌入。然后,它会将此查询嵌入与目录中所有酒店的嵌入进行比较。嵌入在数值上与查询的嵌入最接近的酒店排名更高。

以下是纯粹基于嵌入的相关性搜索的可能排名:

排名 酒店 此排名的可能原因
1 酒店 A 与“豪华”“机场”“屋顶泳池”的语义匹配度非常高。“禁止携带宠物”不是理想的匹配项,但其他强匹配项占主导地位。
2 酒店 B “允许携带宠物”和“泳池”的语义匹配度较高。但“室内”而非“屋顶”、“现代”和“时尚”而非“豪华”,以及“市中心”而非“机场”使得 B 的相关性不如 A。
3 酒店 D 在语义上与“允许携带宠物”“大型泳池”高度匹配,但“室内”而非“屋顶”以及“乡村风格”而非“豪华”使得其语义相关性略低于 A 和 D。
4 酒店 C 虽然该房源非常适合携带宠物入住,但“无泳池”和“精品”这两个条件会显著降低其与此特定查询的相关性。

此排名无法提供相关度最高的搜索结果。即使酒店 A 的政策是“不允许携带宠物入住”,许多用户可能并不喜欢,但它仍排名第一。 酒店 D 符合多项条件,但排名较低,因为其“乡村”状态不一定与“豪华”相符,并且“室内”游泳池的排名低于“大型”和“室外”的完全匹配项。

自定义排名

假设您已为此示例场景配置了以下排名表达式。如需了解此表达式的组成部分,请参阅实现自定义排名简介

rankingExpression = rr(semantic_similarity_score, 32) * 0.4 + rr(keyword_similarity_score, 32) * 0.3 + rr(c.distance_from_airport * -1, 32) * 0.8

其中,distance_from_airport 是目录中的可检索字段,而 c.distance_from_airport 用作信号。

在自定义排名中,您需要考虑影响文档相关性的不同信号。然后,您可以使用有效语法创建一个包含这些信号的数学表达式。在此表达式中,您将对信号进行归一化处理,并为其派生出的得分添加权重。计算最终的自定义得分并对文档进行排名。

在此示例中,此过程可说明如下:

  1. 每家酒店都会获得一个语义相似度得分和一个关键字相似度得分。此外,与机场的距离也是从文档中提取的重要信号。

  2. 倒数排名转换函数或 rr() 用于将所有得分转换为同一比例。

  3. 系统会为从每种信号中得出的分数分配权重,然后将所有单个分数相加,得出每个酒店的自定义排名分数。

下表列出了每家酒店的不同信号:

酒店 semantic_similarity_score keyword_similarity_score c.distance_from_airport 自定义排名得分 自定义排名 基于嵌入的排名
酒店 A 9.0 6.2(“机场”“豪华”“屋顶泳池”) 5.0 0.04879 2 1
酒店 B 7.5 5.6(“允许携带宠物”“市中心”“室内游泳池”“时尚”) 12.5 0.04691 3 2
酒店 C 5.0 3.4(“允许携带宠物”“市中心”) 18 0.04525 4 4
酒店 D 8.0 4.5(“室内游泳池”“允许携带宠物”“乡村风格”) 1 0.04890 1 3

比较这两种排名方法,自定义排名会给出更周全的排名,可能比纯粹基于嵌入的排名更能满足用户的需求。

实现自定义排名简介

如需在搜索结果中获得自定义排名,您必须通过提供以下字段来调用 search 方法:

  • 排名表达式后端 (rankingExpressionBackend):此字段用于指明要使用以下哪种排名机制。

    • RANK_BY_EMBEDDING:如果未指定此字段,则这是默认值。选择此选项会根据预定义的排名表达式(基于嵌入或相关性)对结果进行排名。
    • RANK_BY_FORMULA:此值会替换默认排名,并允许您在 rankingExpression 字段中提供自定义公式。
  • 排名表达式 (rankingExpression):此字段包含一个数学公式,用于确定检索到的文档的排名。

    • 对于 RANK_BY_EMBEDDING,这是基于相关性得分 (double * relevanceScore) 或基于嵌入 (double * dotProduct(embedding_field_path))。

    • 对于 RANK_BY_FORMULA,这是一个精心设计的表达式,它会结合多种信号来计算每个搜索结果的新得分。

标准信号

Vertex AI Search 提供各种信号,可用于制定自定义排名。以下是可用的标准信号:

信号名称 说明
default_rank 由标准 VAIS 排名算法确定的文档的默认排名
semantic_similarity_score 根据查询和内容嵌入计算出的分数,用于确定搜索查询与文档内容的相似程度。这是使用 Google 的专有算法计算得出的。
relevance_score 由深度相关性模型生成的得分,用于处理复杂的查询-文档互动。模型会在内容背景下确定查询的含义和意图。这是使用 Google 的专有算法计算的。
keyword_similarity_score 一种非常注重关键字匹配的分数。此信号使用最佳匹配 25 (BM25) 排名函数。
document_age 相应文档的年龄(以小时为单位)。支持浮点值。例如,值 0.5 表示 30 分钟,而值 50 表示 2 天 2 小时。
pctr_rank 一种用于表示预测转化率的等级,根据用户事件数据计算得出。此信号使用预测点击率 (pCTR) 从用户的角度衡量搜索结果的相关性。
topicality_rank 一种用于表示使用 Google 专有算法计算出的关键字相似度调整的等级。
boosting_factor 您已应用于文档的所有自定义加权的组合。

除了这些字段之外,您还可以使用文档中标记为可检索的任何自定义字段。为此,请在其字段名称中添加 c. 前缀。例如,如果您有一个名为 date_approved 的自定义字段,则可以使用 c.date_approved 作为自定义信号。

信号名称是字母字符和下划线 (_) 的组合。以下是不能用作信号名称的预留名称列表:logexprris_nanfill_nan

排名公式语法

自定义排名公式是一个数学表达式,包含以下组成部分:

  • 数字 (double):为信号或表达式添加权重的正或负浮点值。

  • 信号 (signal)可用信号部分中列出的信号的名称。

  • 算术运算符+(加法)和 *(乘法)。

  • 数学函数

    • log(expression):自然对数
    • exp(expression):自然指数

    这些表达式中的每一个都只接受一个实参,该实参是根据信号编写的表达式。

    有效函数的示例:exp(c.document_age)log(keywordSimilarityScore * 0.2 + 1.0)

  • 倒数排名转换函数 (rr):此函数表示为 rr(expression, k)。它首先按 expression 的值以降序对文档进行排序,然后为文档分配排名。然后,它使用表达式 1 / (rank_i + k) 计算最终值;其中,rank_i 是文档在排序列表中的位置(从 0 开始),k 是您提供的正浮点数。

    rr() 函数会将所有得分转换为同一比例,从而无需进行额外的归一化处理。

  • 非数字 (NaN) 处理函数

    • is_nan(expression):当表达式的计算结果为 NaN 时(例如,当某个文档缺少信号时),系统会返回 1。否则,返回 0
    • fill_nan(arg_expression, fill_with_expression):如果 arg_expression 的评估结果为 NaN,则返回 fill_with_expression。否则,返回 arg_expression。这对于处理可能缺少某些信号的文档至关重要。

排名公式示例

  1. 基本线性组合:

    semantic_similarity_score * 0.7 + keyword_similarity_score * 0.3
    
  2. 使用倒数排序和 NaN 处理的复杂公式:

    rr(fill_nan(semantic_similarity_score, 0), 40) * 0.5 + topicality_rank * 0.5
    
  3. 使用倒数排序、指数函数和 NaN 处理的复杂公式:

    rr(fill_nan(semantic_similarity_score, 0), 40) * 0.2 + exp(keyword_similarity_score) * 0.3 + is_nan(keyword_similarity_score) * 0.1
    

如需自定义搜索结果中文档的排名,请手动起草公式并将其添加到 search API 调用中。

  1. 制定排名表达式。

  2. 获取搜索结果。

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    "https://discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/global/collections/default_collection/engines/APP_ID/servingConfigs/default_search:search" \
    -d '{
    "servingConfig": "projects/PROJECT_ID/locations/global/collections/default_collection/engines/APP_ID/servingConfigs/default_search",
    "query": "QUERY",
    "rankingExpression": "RANKING_EXPRESSION",
    "rankingExpressionBackend": "RANK_BY_FORMULA"
    }'
    

    替换以下内容:

使用 Python 库调整排名公式

对于更高级的用例,为公式找到最佳权重可能是一项艰巨的任务。为了克服这一问题,您可以使用 Vertex AI Search 的排名调优 Python 库(一种开源工具),为您的使用情形找到合适的公式。

一般工作流程如下:

  1. 准备一个包含查询和相应标准标签的数据集。这些黄金标签可以是唯一标识字段(例如文档 ID),可帮助您关联搜索响应中的 SearchResult 对象。
  2. 对于一组代表性查询,请调用 search API 以获取所有返回文档的可用排名信号。您可以在 SearchResult.rankSignals 字段中找到此信息。将这些数据与黄金标签一起存储。
  3. 使用 Python 库根据此数据集训练排名模型。如需了解详情,请参阅 Clearbox Python 库

  4. 将训练结果中的公式转换为排名表达式,然后您可以在 API 调用中使用该表达式。