由于不同行业的搜索需求可能有所不同,并且会不时发生变化,因此默认排名行为可能无法满足所有业务需求。为解决此问题,您可以使用自定义排名来修改排名行为。
本页介绍了如何在搜索请求中使用自定义排名公式,以及如何调整该公式。此功能适用于结构化数据、非结构化数据和网站数据。
概览
借助自定义排名,您可以提供一个数学表达式,该表达式依赖于一组模型计算的信号(例如语义相关性得分和关键字相似度得分)以及基于文档的信号(例如距离或文档年龄等自定义字段)。
借助自定义排名,您可以实现以下目标:
- 提高可见性:了解哪些信号会影响搜索结果的最终排名。
- 调整现有信号:调整各种信号的权重,例如语义相似度、关键字匹配或文档新鲜度。
- 纳入业务逻辑:将您自己的自定义信号从文档数据直接添加到排名公式中。
- 系统性优化:使用开源 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 用作信号。
在自定义排名中,您需要考虑影响文档相关性的不同信号。然后,您可以使用有效语法创建一个包含这些信号的数学表达式。在此表达式中,您将对信号进行归一化处理,并为其派生出的得分添加权重。计算最终的自定义得分并对文档进行排名。
在此示例中,此过程可解释如下:
每家酒店都会获得一个语义相似度得分和一个关键字相似度得分。此外,距机场的距离也是从文档中得出的一个重要信号。
倒数排名转换函数或
rr()用于将所有得分转换为同一比例。系统会为从每种信号中得出的分数分配权重,然后将所有单个分数相加,得出每个酒店的自定义排名分数。
下表列出了每家酒店的不同信号:
| 酒店 | 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 |
一种非常注重关键字匹配的分数。此信号使用 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 作为自定义信号。
信号名称是字母字符和下划线 (_) 的组合。以下是不能用作信号名称的预留名称列表:log、exp、rr、is_nan 和 fill_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。这对于处理可能缺少某些信号的文档至关重要。
排名公式示例
基本线性组合:
semantic_similarity_score * 0.7 + keyword_similarity_score * 0.3使用倒数排序和 NaN 处理的复杂公式:
rr(fill_nan(semantic_similarity_score, 0), 40) * 0.5 + topicality_rank * 0.5使用倒数排序、指数函数和 NaN 处理的复杂公式:
rr(fill_nan(semantic_similarity_score, 0), 40) * 0.2 + exp(keyword_similarity_score) * 0.3 + is_nan(keyword_similarity_score) * 0.1
响应中的信号
当搜索响应中返回某个文档时,搜索结果会列出有助于从数据存储区检索该文档的标准和自定义信号。rankSignals 字段列出了这些信号。
用于关键字相似度的文本字段
在结构化数据存储区中,如需在搜索响应中获取 keywordSimilarityScore 信号,您必须更新架构以执行以下操作:
- 将对关键字匹配至关重要的文本字段映射到键属性
title和description - 将文本字段的注解更新为
Searchable
在搜索中使用排名公式自定义排名
如需自定义搜索结果中文档的排名,请手动起草公式并将其添加到 search API 调用中。
制定排名表达式。
获取搜索结果。
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" }'替换以下内容:
PROJECT_ID:您的 Google Cloud 项目的 ID。APP_ID:您要查询的 Vertex AI Search 应用的 ID。QUERY:要搜索的查询文本。RANKING_EXPRESSION:您可以使用有效的排名公式语法,通过可用信号编写的自定义排名公式。- 如需查看有效示例,请参阅排名公式示例。
- 如需调整排名公式以获得最佳结果,请参阅使用 Python 库调整排名公式。
使用 Python 库调整排名公式
对于更高级的用例,为公式找到最佳权重可能是一项艰巨的任务。为了克服这一问题,您可以使用 Vertex AI Search 的排名调优 Python 库(一种开源工具),为您的使用情形找到合适的公式。
一般工作流程如下:
- 准备一个包含查询和相应标准标签的数据集。这些黄金标签可以是唯一标识字段(例如文档 ID),可帮助您关联搜索响应中的
SearchResult对象。 - 对于一组代表性查询,请调用
searchAPI 以获取所有返回文档的可用排名信号。您可以在SearchResult.rankSignals字段中找到此信息。将这些数据与黄金标签一起存储。 使用 Python 库根据此数据集训练排名模型。如需了解详情,请参阅 Clearbox Python 库。
将训练结果中的公式转换为排名表达式,然后您可以在 API 调用中使用该表达式。