作者:来自 Elastic Alexander Marquardt, Honza Král 及 Taylor Roy
了解如何使用利润率和流行度加权来优化电商搜索。本博客解释了受治理控制平面如何在 Elasticsearch 中处理经济优化。
如果你是 Elasticsearch 新手,欢迎参加我们的 Elasticsearch 入门网络研讨会。你也可以立即开始免费云试用,或在你的机器上尝试 Elastic。
本系列第 1 到第 6 部分描述了一个受治理的控制平面,它可以对意图进行分类、强制执行约束、解决冲突、进行个性化排序,并路由到合适的检索策略。本篇文章引入了一个不同的目标:确保零售商的商业优先级能够影响这些相关商品的最终排序位置,并且这种优化以每次查询为粒度通过策略进行治理,而不是作为静态的全局设置应用。
在大多数电商部署中,经济信号(例如利润率和商品热度)要么在搜索排序中被忽略,要么作为静态的全局权重应用。固定的利润率提升可能会在所有查询中都提升高利润商品,这在 “巧克力” 这种用户愿意被引导的场景中有效,但在 “婴儿配方奶粉 ” 这种用户更关注可信和热门品牌的场景中就会适得其反。
受治理的控制平面使得可以将经济优化作为一种每次查询的决策来处理,通过策略数据表达,并与其他治理机制一样在同一个管理 UI 中进行管理。商品运营人员可以说 “对于巧克力查询,优先利润率”,以及“对于婴儿配方奶粉查询,优先流行度”,而不需要写代码、不需要部署变更,并且具备完整的可审计性。
关于 Elasticsearch 中利润率与流行度加权的数学基础(包括对数缩放公式和参数调优说明),请参见在 Elasticsearch 中通过 function score query 结合利润与流行度提升电商搜索的相关内容。
两个业务信号:利润率与流行度
在我们的商品目录中,每个商品文档都包含两个数值字段:
- margin:商品的利润率百分比(在我们的数据集中为 0 到 200)。
- popularity:相对销量指标(在我们的数据集中为 0 到 10,000),例如每周平均销量。
这两个字段代表了两种完全不同的业务目标。利润率优化推动每笔交易的利润最大化;流行度优化则提升转化概率,因为被大量用户购买的商品,更可能也是当前用户愿意购买的商品。
基线:使用业务信号进行全局 boosting
在引入按查询策略覆盖之前,系统对利润率和流行度都会应用默认 boosting。这些是在 Elasticsearch 的 function_score query 中使用 field_value_factor 并结合对数缩放实现的,具体可参考通过 Elasticsearch 中的 function score query 按利润和受欢迎程度提升电商搜索效果。
该设计具有三个值得注意的特性:
- 校准范围(Calibrated range)。每个信号的 factor 都经过校准,使其在取值上限时最多贡献约 +1.0 的 boost multiplier。与基础权重 1 结合后,最终 multiplier 范围为 1.0(利润率和流行度都为 0 的商品)到约 3.0(利润率与流行度都达到最大值的商品)。也就是说,一个业务信号强的商品,其得分大约是同类但没有这些信号的商品的 3 倍,而不依赖 BM25 分数的绝对大小。
- 对数缩放(Logarithmic scaling)。ln1p 修饰符在小值区间增长较快(奖励增量提升),在高值区间趋于平缓(防止单个商品主导得分)。这也使系统对数据分布变化具有鲁棒性:如果数据集中最大 popularity 发生变化,boost 曲线会“拉伸”而不是失效。
- 乘法而非加法(Multiplicative, not additive)。业务信号的 boost 是与 BM25 以乘法方式(boost_mode: "multiply")结合,而不是加到 BM25 上。由于 BM25 在不同查询之间波动很大,加法会导致影响不稳定;乘法缩放可以保证无论 BM25 绝对值如何变化,都能带来一致的百分比提升。
通过策略实现按查询的 boosting 覆盖
默认权重(margin 和 popularity 均为 1.0)适用于所有查询。但受治理的控制平面允许通过按查询方式覆盖这些权重,并使用第 3 部分和第 4 部分中描述的同一策略引擎来实现。
每个策略文档包含两个可选字段:margin_boost_weight 和 popularity_boost_weight。当某个策略匹配到查询并包含权重覆盖时,这些值会被传递到 function_score 的构建过程中,从而替换默认值。
为什么按查询控制很重要
考虑两个查询,以及为什么它们需要不同的经济优化策略。
利润率 boosting:巧克力
当用户搜索 “chocolate” 时,这是一种浏览型意图。用户会对多种巧克力相关商品都感到满意。零售商的自有品牌巧克力松露(60% 利润率)可能与知名品牌巧克力棒(15% 利润率)同样具有吸引力。如果用户并不在意具体品牌,而是购买了被利润率提升排序靠前的商品,那么激进的利润率 boosting 就能带来收益。
未使用利润率 boosting 的巧克力结果
为了隔离按查询利润率 boosting 的影响,我们在该查询中完全关闭利润率 boosting(margin boost weight:0)。在没有任何利润率信号的情况下,排序由文本相关性决定。在我们的数据集中,第一个结果的利润率为 10,第二个结果的利润率为 84(最大值为 200),如下所示:
为 “chocolate” 查询设置利润率 boosting
商品运营人员如果决定“chocolate”查询应优先考虑利润率,可以在管理 UI 中进行配置,将该变更在代表性查询上进行测试,并发布到生产环境。该变更会在下一次查询时立即生效,无需工程工单、无需部署、无需代码修改。
下面这个 “chocolate” 策略将 margin_boost_weight 设置为 3.0,从而确保巧克力搜索会强力提升高利润商品的排序优先级。
启用利润率 boosting 后的巧克力结果
在启用上述利润率 boosting 策略后,利润率较高的巧克力商品(利润率分别为 197 和 184)被提升到结果顶部,如下所示(请记住,我们数据集中的最大利润率为 200):
流行度 boosting:婴儿配方奶粉
当用户搜索 “baby formula” 时,用户并不是在做尝试性购买。他们希望购买的是其他父母也信任的产品。在这种高风险购买场景下,如果将高利润的自有品牌奶粉排在已有大量父母购买的知名品牌之上,会显得不合理,并可能削弱信任。此时,流行度是更合适的信号,因为它代表社会认同(social proof)。
未使用流行度 boosting 的婴儿配方奶粉结果
为了隔离按查询流行度 boosting 的影响,我们在该查询中完全关闭流行度 boosting(popularity_boost_weight:0)。在没有任何流行度信号的情况下,排序由文本相关性决定。在这个例子中,排名第一的结果流行度为 50(在最高 10,000 的范围内)。
为 “baby formula” 查询设置流行度 boosting
一个 “baby formula” 策略设置 popularity_boost_weight:5.0,并将 margin_boost_weight:0;配方奶粉搜索会优先考虑流行度,完全忽略利润率。
启用流行度 boosting 后的婴儿配方奶粉结果
如果启用上述规则,那么最受欢迎的婴儿配方奶粉(Lactogen 2,流行度为 9979)将被提升到结果顶部,如下所示。
禁用业务信号:清仓(Clearance)
并不是每个查询都适合经济类 boosting。搜索 “clearance” 的用户是在寻找折扣商品;利润率和流行度这两个信号都与这种意图无关。高利润商品恰恰违背了用户需求,而高流行度商品也不一定是清仓商品。
“clearance” 策略设置 margin_boost_weight:0 和 popularity_boost_weight:0,从而完全禁用这两个业务信号。结果仅基于纯文本相关性排序,不受任何经济因素影响。这完成了整个设计空间:策略可以独立强化任一信号、重新平衡它们,或者完全关闭它们。
覆盖值如何在控制平面中流动
当 percolator 返回匹配策略后,控制平面会检查优先级最高的匹配策略中是否存在 margin_boost_weight 和 popularity_boost_weight 字段。如果存在,这些值会替换 RewriteState 中的默认值。如果没有任何匹配策略包含权重覆盖,则使用默认值(两者均为 1.0)。
随后,这些权重会在最终 Elasticsearch 查询构建时进入 function_score 结构。function_score 的结构本身不会改变,只是 margin 和 popularity 两个函数的 weight 值发生变化。
权重覆盖与所有其他策略机制一样参与治理模型,并遵循优先级排序:一个圣诞促销策略(margin_boost_weight:0.5)如果优先级高于一个商品类目策略(margin_boost_weight:3.0),就会覆盖后者。第 3 部分中的级联变换模型同样适用:经济优化参数只是策略执行计划中的一个字段。
与其他策略的交互
按查询的权重覆盖可以与本系列前文中描述的约束执行、冲突解决以及个性化机制自然组合。
以一个在圣诞促销期间搜索“cheap chocolate”的用户为例,该用户具有购买历史,并属于 vegan 用户群组(cohort)。控制平面会通过完整的治理栈来处理该查询:
- “cheap” 策略提取价格约束,并将 “cheap” 从查询中移除。
- “chocolate” 策略设置 margin_boost_weight:3.0,并将结果限制在巧克力类目。
- “圣诞活动”策略(更高优先级)覆盖类目约束,引入节日类目并调整价格上限。
- “vegan cohort” 策略对经过 vegan 认证的商品应用软性 boosting。
- 利润率与流行度 boosting 按照治理后的权重应用(来自 “chocolate” 策略的 margin 为 3.0×,popularity 为默认 1.0×)。
- 用户的购买历史 boosting 作为最外层 scoring 层应用。
每一层都是乘法叠加的。经济优化权重由与类目约束、活动覆盖以及 cohort 特定 boosting 相同的策略框架所治理。商品运营人员可以在同一个管理 UI 中调整所有这些参数,而无需任何代码变更。
这个例子也说明了经济优化在 scoring 栈中的位置。各层以明确顺序嵌套:基础查询(关键词或语义匹配),然后是治理约束(第 3 和第 4 部分中的硬过滤与软 boosting),然后是业务信号 boosting(带治理权重的 margin 与 popularity),最后是购买历史个性化(第 6 部分)。每一层都包裹前一层,并以乘法方式叠加效果。治理控制 “展示什么”。经济优化影响“在商家视角下什么排在最前”。个性化则从用户视角进一步调整排序。
调优指南
基础 function_score 中的 factor 值是根据 demo 数据集中字段范围校准的。在生产环境中,如果 margin 或 popularity 的数值范围差异较大,则需要重新校准这些 factor,以确保每个信号都能贡献一致的最大 boost。
对数缩放提供了对异常值和分布变化的内建鲁棒性,但当底层数据发生显著变化时,这些 factor 仍然值得重新评估。关于校准方法,请参见 通过 Elasticsearch 中的 function score query 按利润和受欢迎程度提升电商搜索效果。
从经济优化到 agentic AI
受治理的控制平面现在已经能够处理意图分类、约束执行、冲突解决、个性化以及经济优化,所有这些都通过策略数据表达,通过业务可编辑的管理 UI 进行管理,并通过确定性的转换框架进行组合。
本系列的最后一篇文章将探讨:当这个系统的输入不再是人类用户输入的搜索字符串,而是由 AI agent 提取的 intent string 时会发生什么,以及为什么当上游决策者是概率模型时,受治理控制平面的确定性特性变得更加关键。
将受治理的电商搜索付诸实践
本篇文章中描述的按查询经济优化(策略治理的 margin 和 popularity 权重,与治理约束、个性化和活动覆盖组合)是由 Elastic Services Engineering 设计并构建,作为可复用电商搜索加速方案的一部分。欢迎联系 Elastic Professional Services。
参与讨论
如果你对搜索治理、检索策略或电商搜索架构有问题,欢迎加入更广泛的 Elastic 社区讨论。
这些内容对你有多大帮助?
原文:https://www.elastic.co/search-labs/blog/ecommerce-search-optimization-query-governed