如何基于Algolia的getRankingInfo计算搜索结果匹配置信度
基于Algolia rankingInfo计算匹配置信度的可行方案
首先明确核心前提:Algolia原生返回的字段里没有直接提供0-100%区间的“匹配置信度”指标,返回值里的userScore是综合了自定义业务排序、文本匹配、地理权重等多维度规则的排序总分,不能直接用来代表搜索词和结果的匹配程度——你给出的示例数据里第三条结果userScore高达7801、远高于其他结果,但它的proximityDistance(匹配词邻近度)反而更差,就是因为这条命中了你配置的高优先级业务排序规则(比如内容热度、商品销量、发布时间这类非文本匹配规则),计算匹配度的时候要完全忽略这个字段。
具体计算步骤
1. 筛选和匹配质量强相关的字段
计算置信度时只保留和搜索词匹配质量直接相关的rankingInfo字段,排除所有业务排序、地理距离类的干扰项:
- 负向指标(值越高匹配质量越差):
nbTypos(匹配的拼写错误数)、proximityDistance(查询词在结果文本中匹配位置的间隔距离)、firstMatchedWord(首个匹配词在结果文本中的位置) - 正向指标(值越高匹配质量越好):
nbExactWords(和查询词精确匹配的词数量) - 兜底过滤指标:如果
filters值大于0且nbExactWords为0,说明结果完全是靠配置的过滤规则召回、没有命中任何搜索词,直接判定为最低置信度
2. 计算单条结果的基础匹配分
参考Algolia原生文本排序的优先级给各指标分配权重,单条结果基础分满分100,计算逻辑可以直接复用下面的规则:
/** * 计算单条结果的基础匹配分 * @param {object} rankingInfo - 接口返回的rankingInfo对象 * @param {number} totalQueryWords - 本次搜索的查询词总数量,对应rankingInfo里的words字段 * @returns {number} 0-100的基础匹配分 */ function calcBaseMatchScore(rankingInfo, totalQueryWords) { let score = 0; // 精确匹配词占比,权重40:精确匹配词数/总查询词数 * 40 const exactWordRatio = rankingInfo.nbExactWords / totalQueryWords; score += exactWordRatio * 40; // 拼写错误权重25:0错拼拿满,1个错拼得10分,2个及以上错拼得0分 if (rankingInfo.nbTypos === 0) { score += 25; } else if (rankingInfo.nbTypos === 1) { score += 10; } // 词邻近度权重25:邻近度距离≤总查询词数拿满,每超出3个单位扣5分,扣完为止 const proximityGap = rankingInfo.proximityDistance - totalQueryWords; if (proximityGap <= 0) { score += 25; } else { const deductScore = Math.floor(proximityGap / 3) * 5; score += Math.max(0, 25 - deductScore); } // 首词位置权重10:首个匹配词在文本前10个位置拿满,每往后20个位置扣2分,扣完为止 if (rankingInfo.firstMatchedWord <= 10) { score += 10; } else { const deductScore = Math.floor((rankingInfo.firstMatchedWord - 10) / 20) * 2; score += Math.max(0, 10 - deductScore); } // 兜底规则:纯filter召回的结果直接给0分 if (rankingInfo.filters > 0 && rankingInfo.nbExactWords === 0) { score = 0; } return Math.round(score); }
3. 同查询内做置信度归一化
注意:匹配置信度是同一次查询下的相对值,不能跨查询用固定绝对值当阈值,不同查询的词长度、结果分布差异极大,固定阈值会出现判定不准的问题。
归一化操作逻辑:
- 查询时不要设置过低的返回条数上限,先拉取当前查询下最多1000条结果(可以根据自己业务的最大可接受结果量调整)
- 对拉取到的所有结果逐条计算基础匹配分
- 取本次查询结果里的最高基础分作为满分基准
- 单条结果最终置信度 = (单条基础匹配分 / 本次查询最高基础分) * 100,结果取0-100的整数
- 最后用你预设的置信度阈值(比如90%)过滤即可,整个判定逻辑完全不依赖结果的返回排序位置。
针对你给出的示例数据的计算验证
你提供的示例查询总词数为5,所有结果nbTypos=0、firstMatchedWord=0、filters=0,代入计算:
- 前2条结果
proximityDistance=6:精确匹配占比100%得40分,0错拼得25分,邻近度仅比总词数多1、拿满25分,首词位置拿满10分,基础分100 - 后3条结果
proximityDistance=8:邻近度比总词数多3,扣5分得20分,其余项满分,基础分95
本次查询最高基础分为100,因此前2条结果置信度为100%,后3条为95%。如果设置90%的阈值,这5条结果都符合展示要求;如果设置98%的阈值,就只返回前2条。
补充说明:如果你的业务对匹配精度要求更高,可以调整各指标的权重占比,比如给精确匹配词占比分配更高权重、给错拼设置更严格的扣分规则,权重调整后重新做归一化即可。
内容的提问来源于stack exchange,提问作者Theuno de Bruin
相关产品推荐
相关产品推荐

