自定义搜索结果排名

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

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

概览

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

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

  • 提高可见性:了解哪些信号有助于确定搜索结果的最终 排名。
  • 调整现有信号:调整各种信号的权重,例如 语义相似度、关键字匹配或文档新鲜度。
  • 融入业务逻辑:将您自己的 文档数据中的自定义信号直接添加到排名公式中。
  • 系统地进行优化:使用开源 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 与“允许携带宠物入住”和“泳池”的语义匹配度良好。但“室内” 而非“屋顶”、“现代”和“时尚”而非“豪华”以及 “市中心”而非“机场”使其相关性低于 A。
3 酒店 D 与“允许携带宠物入住”“大型泳池”的语义匹配度高, 但“室内”而非“屋顶”以及“乡村”而非“豪华” 使其语义相关性略低于 A 和 B。
4 酒店 C “允许携带宠物入住”的匹配度高,但“没有泳池”和“精品”显著 降低了其与此特定查询的相关性。

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

自定义排名

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

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

其中,distance_from_airport 是目录中的可检索字段, c.distance_from_airport 充当信号。

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

在此示例中,此过程可以解释如下:

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

  2. 密集倒数排名转换函数或 drr() 用于将所有得分转换为相同的比例。

  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,此表达式是经过精心设计的表达式,它将多个信号组合在一起,为每个搜索结果计算新的得分。

标准信号

Agent Search 提供各种信号,您可以使用这些信号来制定自定义排名。以下是可用的标准信号:

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

自定义信号

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

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

地理距离 - 派生信号

派生信号(例如地理距离)是根据标准信号和自定义信号计算得出的。地理距离是一个函数,用于计算源位置和目标位置之间的距离。geo_distance() 函数表示为 geo_distance(source_location, destination_location)。它由以下实参组成:

  • 源位置或 source_location:用于计算距离的出发地,可以是以下类型之一:

    • 查询位置:使用 自然语言理解模型从查询中解析出的位置。例如,在查询 Hotels along the M6中,自然语言理解模型会将 Hotels提取为搜索参数的内容部分,并将M6提取为位置部分。where 部分是查询位置,可以表示为点、多段线、圆或多边形。

      {
       "query": "Hotels along M6",
       "ranking_expression": "geo_distance(query_loc, c.hotel_location)",
       "ranking_expression_backend": "RANK_BY_FORMULA"
      }
      
    • 请求位置坐标:在 搜索请求中明确提供的位置,例如用户的纬度和经度。例如,您可以将查询提供为 Hotels,并使用纬度和经度提供位置。

      {
        "query": "Hotels",
        "user_info": {
          "precise_location": {
            "point": {
              "lat": 52.23034637633789,
              "lon": 20.98339855121653,
            }
          }
        },
        "ranking_expression": "geo_distance(request_loc, c.hotel_location)",
        "ranking_expression_backend": "RANK_BY_FORMULA"
      }
      
    • 请求位置地址:在 搜索请求中明确提供的地址。例如,您可以将查询提供为 Hotels,并提供地址以供参考。

      {
        "query": "Hotels",
        "user_info": {
          "precise_location": {
            "address": "1800 Amphibious Blvd. Mountain View, CA 94045"
          }
        },
        "ranking_expression": "geo_distance(request_loc, c.hotel_location)",
        "ranking_expression_backend": "RANK_BY_FORMULA"
      }
      
  • 目标位置或 destination_location:用于计算距离的目标位置,这是一个自定义可检索字段,例如 c.office_locationc.home_location

函数中这些实参的顺序必须保持不变。也就是说,源位置必须始终是 geo_distance() 函数中的第一个实参,后跟目标位置。 该函数使用源位置和目标位置的纬度和经度计算距离(以米为单位)。

排名公式语法

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

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

  • 信号 (signal)标准信号部分中列出的信号的名称。

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

  • 数学函数

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

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

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

  • 密集倒数排名转换函数 (drr)

    此函数表示为 drr(expression, k, eps)。它首先按 expression 的值降序对文档进行排序,并为文档分配排名。当表达式值相差在 eps 内时,这些值被视为相等。然后,该函数使用表达式 1 / (rank_i + k) 计算最终值。在此表达式中,rank_i 是文档在排序列表中的位置(从 0 开始),k 是您提供的正浮点数。

    drr() 函数通常用于将所有得分转换为相同的比例,并消除对额外归一化的需求。

    Google 建议您使用此函数,而不是之前的倒数排名转换函数 (rr),因为在信号并列为最高结果的情况下,此函数可以提供更好的结果。例如,如果搜索的是旧金山的酒店,则市内有很多酒店,因此许多酒店共享相同的地理距离信号。

    详细了解 eps 参数:

    • eps 参数在确定两个信号是否相等时增加了灵活性。等效信号最常见于以下类型的信号:boosting_factorgeo_distance、分类自定义和整数自定义。

    • 该函数用于确定一个文档的表达式值是否 等于另一个文档的表达式值。如果 eps=0,则这些值 必须完全相同才被视为相等;如果 eps>0,则在 eps 指定的范围内的值被视为相等。

    • 更具体地说,如果 x1x2 是信号值,则当两者之间的绝对差小于 或等于 eps 时,即 abs(x1-x2) <= eps,它们被视为相同的值。默认情况下,eps=0,这意味着如果 x1 == x2,则这些值被视为相同。eps=0 的默认值适用于整数,但在某些情况下可能不适用于浮点数,因为浮点运算的性质不精确,例如,1/5 可能计算为 0.200000000000010.19999999999

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

    rr() 函数通常用于将所有得分转换为相同的比例,并消除对额外归一化的需求。

    虽然支持此函数,但 Google 建议使用较新的密集倒数排名转换函数 (drr)。

  • 非数字 (NaN) 处理函数:

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

排名公式示例

以下是一些排名公式示例,您可以在搜索请求的 rankingExpression 字段中使用这些公式:

  • 基本线性组合:

    semantic_similarity_score * 0.7 + keyword_similarity_score * 0.3
    
  • 使用密集倒数排名和 NaN 处理的复杂公式:

    drr(fill_nan(semantic_similarity_score, 0), 40) * 0.5 + drr(topicality_rank * -1, 40) * 0.5
    
  • 使用密集倒数排名、指数函数和 NaN 处理的复杂公式:

    drr(fill_nan(semantic_similarity_score, 0), 40) * 0.2 + exp(keyword_similarity_score) * 0.3 + is_nan(keyword_similarity_score) * 0.1
    
  • 使用带有 geo_distance() 函数的密集倒数排名的复杂公式,说明了如何将 eps 参数与 geo_distance() 函数搭配使用:

    drr(keyword_similarity_score, 16) * 0.8 + drr(geo_distance(query_loc, c.office_location) * -1, 16, 0.00001) * 0.2
    

    在此公式中,乘法因子为负值,因此距离越大,表达式值越小(负值越大),因此倒数排名会为更大的距离分配更低的排名得分。

响应中的信号

当文档在搜索响应中返回时,搜索结果会列出 有助于从 数据存储区检索文档的标准自定义信号rankSignals 字段会列出这些信号。

用于关键字相似度的文本字段

在结构化数据存储区中,如需在 您的搜索响应中获取 keywordSimilarityScore 信号,您必须 更新架构以执行以下操作:

  • 将关键字匹配所需的基本文本字段映射到键属性 titledescription
  • 将文本字段的注解更新为 Searchable

如需自定义搜索结果中文档的排名,请手动 编写公式并将其添加到您的 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 库调整排名公式

对于更高级的用例,为公式找到最佳权重可能具有挑战性。为了克服这个问题,您可以使用 Agent Search 的排名调整 Python 库(这是一个开源工具),并为您的用例找到合适的公式。

一般工作流程如下:

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

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