你有没有过这样的经历:在搜索框输入一个词,结果却完全不是自己想要的。比如搜“苹果”,可能想查iPhone新机,结果满屏都是水果种植技术。这时候,如果你身边有位懂行的服务员,他听了“苹果”两个字,会先问一句:“您是想要手机,还是想买水果?”然后麻利地给你端来一桌候选——iPhone、Mac、水果礼盒。这个“懂你的服务员”,就是今天的主角:查询扩展。 查询扩展是搜索系统里的一项核心技术:当用户输入简短的查询词时,系统自动从同义词表、历史反馈、词向量空间中找来一批相关词,和原始查询拼在一起,再去检索。这样一来,原本搜不到的隐藏文档就能被捞出来,召回率显著提升。它就像服务员手里那本“黑话词典”——你说“辣的”,他听懂你想吃川菜,还顺手推荐了水煮鱼和麻婆豆腐。别小看这个动作,搜索引擎、电商搜索、企业知识库都在靠它“更懂你”。
掌握查询扩展,你就能直接提升搜索系统的召回率与用户体验。无论做搜索引擎、电商检索还是 RAG 知识库,这都是召回环节的必备技能,也是搜索算法工程师面试的高频考点。
目录
可视化演示
展示同义词扩展、伪相关反馈PRF和词嵌入语义扩展三种查询扩展方法,帮助理解搜索引擎如何通过扩展查询提升召回率。
本节配有交互动效(进入视口后自动加载,约 3KB)。
'+captions.synonym+'
概念原理:点菜服务的第一步
想象你走进一家餐厅,只说了句“随便来点好吃的”。服务员如果只端上一道菜,你大概率会失望——因为“好吃的”这个词太模糊了,它可能指口味、食材、做法,或者是招牌菜。聪明的服务员会怎么做?他会在你原话的基础上,补充几个可能的方向:招牌菜、当季特色、大众点评高分菜,然后一起端上来让你选。这个过程,就是查询扩展的缩影:保留你的原始意图,再帮你多找几条候选路径。
在信息检索里,查询扩展(Query Expansion)做的正是这件事。用户输入的查询词往往只有两三个字,比如“苹果”,但文档库里可能有一万种“苹果”的写法:iPhone、MacBook、红富士、Apple Inc.……仅仅用“苹果”两个字去匹配,大量相关文档会被漏掉。查询扩展的思路是:在原始查询的基础上,通过同义词表、检索反馈或词向量模型,自动生成一批相关词,让检索系统有更多“钩子”去文档库里捞鱼。
一次标准的查询扩展流程分为三步:先接收原始查询,再调用扩展策略生成扩展词集合,最后用扩展后的查询去执行检索并融合打分。常见扩展策略有三种——同义词扩展、伪相关反馈、词嵌入扩展,接下来的章节会逐一展开。
回到餐厅的场景:原始查询是客人那句“随便吃点”,扩展函数是服务员脑子里的菜谱知识,并集运算则是把客人原话和候选菜名放在同一张菜单上。查询扩展的价值正在于此——它不改变你的需求,只是帮你多留几扇门。
- 原始查询集合用户输入的全部词构成初始查询集合,它是所有扩展动作的起点。
- 扩展函数从同义词表、反馈文档或词向量空间中派生相关词。
- 合并去重把原始词与扩展词合并去重,得到规模更大、召回能力更强的查询集合。
同义词扩展:服务员的“黑话词典”
店里来了位客人说:“我要吃辣的。”经验丰富的服务员立刻在脑海里翻出一本词典:“辣的”= 川味 = 重口味 = 香辣 = 麻辣。他写上菜单的不仅是“辣”这个字,还有一整套“辣的家族”。这本词典,在检索系统里就是同义词表。
同义词扩展是最经典、最容易落地的扩展方式。它的做法很简单:离线维护一张同义词表,记录词语之间的同义或近义关系;在线查询时,把用户查询中的每个词拿去查表,命中就把同义词也加入查询。比如搜“连衣裙”,同义词表里有“长裙”、“雪纺裙”,检索时这几个词一起去匹配文档,召回覆盖面立刻扩大。
同义词表从哪里来?主要有三种构建途径。其一是人工编纂,标注人员把搜索词和商品词、规范词对齐,质量高但成本大;其二是从用户点击日志中挖掘——用户搜“苹果”后大量点击了"iPhone"标题的页面,这两个词就会被关联起来;其三是借助词嵌入聚类,把语义相近的词自动归组,再辅以人工审核。然而同义词扩展也有明显的局限:词典的覆盖永远追不上新词热词的出现速度,而且一旦同义词选用不当,就会把查询带偏,反而拉低效果。
服务员的“黑话词典”需要定期更新——新菜式、新流行语要随时补录;检索系统的同义词表同样需要多路信号持续迭代。词典越厚,服务员越懂客,搜索系统也就越懂用户。
- 查表取词在既有的同义词表中,找到与查询词 w 语义相同或相近的条目。
- 生成候选集把表中所有条目取出,构成 w 的同义词扩展集合。
- 全查询合并对查询中的每个词分别查表扩展,再与原始查询合并,得到最终扩展查询。
伪相关反馈:看反应再加菜
服务员上了一桌菜,客人拿起水煮鱼连吃三筷,又夹了两块辣子鸡。服务员看在眼里,转身对后厨说:“再上两份偏辣、重油的菜!”他没有问客人“您觉得刚才的菜如何”,而是从客人的“反应”里自动读出了口味偏好。这就是伪相关反馈的直觉。
伪相关反馈(Pseudo-Relevance Feedback,简称 PRF)的核心假设是:先用原始查询做一轮检索,排名靠前的文档大概率与用户需求相关。于是系统把这前 N 篇文档当作“相关反馈”(故称“伪”),从这些文档中提取高频关键词,补充进原始查询,再做第二轮检索。整个过程不需要用户有任何额外操作,完全自动完成。
具体流程分四步:第一轮用原始查询检索,取回 Top-N 文档;假设这些文档相关;从这些文档中挑出区分度高的词(通常是 TF-IDF 加权后得分高的词);把挑选出的词追加到原始查询中,执行第二轮检索。经典算法是 Rocchio 相关反馈公式,它把原查询向量与反馈文档的质心向量做加权融合,让新查询“靠近”相关文档、远离不相关文档。
服务员从客人的“筷子动向”里学到的东西,本质上也是一种反馈信号,虽然客人从没开口,但行为已经说明了一切。伪相关反馈能在无语义资源(如同义词表)的情况下自动发现相关词,是很多搜索引擎召回增强的秘密武器。
- 第一轮检索用原始查询检索,取得分最高的前 N 篇文档作为伪相关文档集合。
- 文档向量平均对反馈文档的词频向量(或词向量)取算术平均,得到“反馈方向”。
- 加权融合原查询向量与反馈方向按权重 α、β 相加,得到下一轮查询向量。
词嵌入扩展:食材性格图谱
一位顶级厨师脑子里装着一张“食材性格图谱”:豆腐和豆干性格相近——都是豆制品,口感软嫩、味道清淡;牛肉和牛腩性格相容——都适合慢炖。客人点了“豆腐汤”,厨师会推荐豆干、千张这类“性格相近”的食材。这张图谱,对应着检索系统里的词嵌入(Word Embedding)。
词嵌入技术(如 Word2Vec、GloVe)把每个词映射成一个几百维的稠密向量。训练之后,语义相近的词在向量空间中距离很近,比如“苹果”向量和“iPhone“向量、和”水果”向量都处于邻近区域。词嵌入扩展的做法是:计算查询词向量与候选词向量的余弦相似度,选出相似度最高的 Top-N 个词,作为扩展词加入查询。
与同义词表相比,词嵌入扩展的最大优势是“无监督发现”——不需要人工维护词典,模型自动从语料中学习语义关联,甚至能发现“苹果”与“华为”这种竞争品关系、以及“京东”与“物流”这种场景关联。它的局限性在于:相似不等于同义,高相似度的词可能语义相关但并不适合作为查询词,所以工业界通常会设定相似度阈值,并加一轮人工规则过滤来控制噪声。
厨师的“食材性格图谱”来自长年累月的烹饪经验;词嵌入模型的“性格图谱”则来自海量文本语料的统计规律。图谱在手,厨师能举一反三,检索系统也能触类旁通。
- 词向量映射词 w 和词 v 分别转换为 d 维稠密向量,语义通过向量的位置表达。
- 点积计算两向量对应维度相乘再累加,数值越大表示方向重叠越多。
- 归一化相似度除以两个向量的长度之积,使相似度落在 [-1, 1] 区间,便于统一设阈值。
改写区别:复述菜单 vs 加菜
有时服务员会跟客人确认:“您说的是要一份辣子鸡,对吗?”这是复述——把客人模糊的话翻译成一道明确的菜。而另一种情况是,客人说“来点辣的”,服务员端上来水煮鱼、辣子鸡、麻婆豆腐三样,这是加菜。把这两件事分清,你就理解了查询改写与查询扩展的本质区别。
查询改写(Query Rewriting)是把原始查询“翻译”成另一个查询:把长句压缩成关键词、把口语换成书面语、把有歧义的词消歧。比如用户输入“北京天气怎么样”,改写系统可能输出“北京 天气”,它用新查询替换掉了原查询。查询扩展(Query Expansion)则不同:它保留原始查询的全部词语,只是额外叠加一批相关词。一个替换,一个叠加,这是两者最本质的差异。
从目标看,改写追求“更精准地表达用户意图”,扩展追求“更广泛地覆盖相关内容”。从形式看,改写的输出通常仍是单个查询串,可以继续作为扩展的输入,两者天然是流水线上下游的关系——现阶段的搜索系统往往先用改写归一化查询,再做扩展增强召回。写公式来对照,就更清楚了:
服务员先确认菜名(改写),再端上一桌候选(扩展),客人体验自然更好。搜索系统也遵循同样的分工:改写负责“听懂你”,扩展负责“多给你选择”。
- 改写映射规则或模型把 Q 映射为另一个查询串,输出是“替换式”的。
- 扩展叠加在原查询基础上附加扩展词,输出是“叠加式”的。
- 协同使用改写先做语义归一,扩展再扩充候选,两者配合使用效果最佳。
召回评估:上菜率怎么算
客人说“来点辣的”,这家餐厅菜单上真正符合“辣”的菜有 10 道。服务员忙了一晚上,结果只端出来了 3 道,这时候我们可以说:这桌菜的上菜率是 30%。“上菜率”换成搜索术语,就是召回率(Recall)。
召回率衡量的是:系统返回的文档中,真正相关的文档占“全部相关文档”的比例。计算时以“用户需求”为基准,问一个问题——所有应该被检索到的文档中,系统真正捞出了多少?与召回率相伴的是精确率(Precision),它问的是另一个问题——系统返回的文档中,有多少是真正相关的?这两者像跷跷板的两端:扩展词加得越多,召回的文档越多,但无关文档混入的概率也变大,精确率随之下降。
为了平衡二者,业界常用 F1 分数,它是精确率和召回率的调和平均,能综合反映检索质量。在工程实践中,上线查询扩展前后一定要做 A/B 实验:对比扩展前后的召回率、精确率、点击率、下单率等指标,确认扩展带来的收益大于噪声带来的损失,才能全量放量。
上菜率高的餐厅不一定好吃——还有口味(精确率)的考量;召回率高的搜索系统也不一定好用——还有排在第一页的答案准不准。好的检索系统,像好的服务员一样,在“什么都端上来”和“精准拿捏”之间找到平衡点。
- 相关文档集合与用户查询意图真正相关的全部文档,是评估的“标准答案”。
- 检索结果集合系统实际返回的文档集合,通常取 Top-K 或得分大于阈值者。
- 交集与比率同时属于 R 和 A 的文档数占 R 的比例,数值越高说明漏检越少。
实践应用:把“懂你”做成标准流程
服务员“懂你”的本事再大,如果只在单家店里灵光一现,也成不了连锁品牌。要把这门手艺沉淀成标准化流程,需要一套从离线到在线的完整体系。查询扩展在工业界的落地,正是这样一套工程化打法。
在搜索引擎中,查询扩展被广泛用于同义匹配:用户搜“没油了”,系统能理解他想要“加油站”;搜“宝宝腹泻”,能关联“婴幼儿 拉肚子”。这些同义关系来自搜索日志挖掘与同义词表的联动。在电商搜索中,查询扩展是提升长尾商品曝光的利器:用户搜“连衣裙”,通过同义词与词嵌入双路扩展,把“雪纺裙”“长裙”“one-piece“一并召回,让那些从来不会被”连衣裙”三个字匹配到的商品也有机会出现在用户面前。
部署与优化的要点有三条:其一,离线构建资源——定期更新同义词表、训练词向量、沉淀点击日志;其二,在线轻量执行——扩展逻辑必须低延迟,通常用倒排索引加内存词典完成,不能每次查询都去跑一趟大模型;其三,效果持续监控——用 A/B 实验对比扩展前后的核心指标,既看召回率提升,也盯住精确率与转化率是否劣化。记住,扩展是手段,让用户找到想要的东西才是目的。
从一家小店到连锁餐厅,靠的是把“懂客”沉淀成流程;从单次查询到海量流量,查询扩展靠的也是把“懂用户”沉淀成资源和策略。搜索与搜索背后的人,永远值得被更好地理解。
- 基线召回率不扩展、只用原始查询检索时的召回率,作为对照基准。
- 扩展后召回率应用查询扩展后再次检索的召回率。
- 增益差值两者相减,得到扩展带来的绝对提升幅度。
AI 应用场景
电商搜索长尾词召回
阶段:召回与查询理解
解决的问题:用户搜“连衣裙”,大量描述为“雪纺裙”“长裙”的商品由于字面不匹配而无法曝光,传统字面匹配召回率低,商家好货卖不出去,用户也找不到心仪的款。
具体案例:某电商平台在搜索“连衣裙”时,调用同义词扩展(雪纺裙、长裙、one-piece)叠加词嵌入扩展(碎花裙、半身裙),扩展后召回文档数提升,长尾商品曝光量明显上升,搜索页人均浏览商品数提升,平台成交转化率同步改善。
搜索引擎口语化同义匹配
阶段:查询理解 / 查询预处理
解决的问题:用户习惯用口语甚至方言查询(“没油了”“车坏了”),而网页文档用的是书面语(“加油站”“车辆故障”),字面匹配形同虚设。
具体案例:某地图搜索 App 从用户点击日志中挖掘出“没油了→加油站”“胎爆了→补胎 维修”等关联对,构建同义词表并用于查询扩展。用户输入口语词时,系统自动追加书面语扩展词,附近加油站、维修店的召回率显著提升,导航到店率与用户满意度双涨。
企业知识库伪相关反馈增强
阶段:召回与重排
解决的问题:企业内部文档用词规范(“差旅费用报销”),员工搜索时却习惯说“出差发票怎么贴”,字面差异导致关键制度文件搜不到,人力咨询成本居高不下。
具体案例:某公司知识库接入伪相关反馈模块:先对“出差发票”做首轮检索,取回 Top-5 文档,自动提取其中高频词“报销”“差旅”“审批”回注查询,再执行第二轮检索。员工用日常口语提问,也能命中最新的制度文件,知识库搜索满意度大幅提高。
Python 演示
# -*- coding: utf-8 -*-"""极简查询扩展演示: 同义词扩展 + 伪相关反馈 提升召回."""from collections import Counter # 模拟的文档库, 词语已用空格切分DOCS = { 0: "苹果 公司 发布 了 新款 iPhone 手机", 1: "苹果 是 一种 营养 丰富 的 水果", 2: "苹果 手机 在 国内 市场 销量 领先", 3: "水果 富含 维生素 适合 日常 食用", 4: "华为 手机 与 苹果 手机 竞争 激烈", 5: "水果 种植 需要 充足 的 光照 和 水分", 6: "今年 苹果 减产 果农 收入 下降", 7: "苹果 电脑 Mac 系统 深受 设计 者 喜爱", 8: "香蕉 和 苹果 都是 常见 水果", 9: "手机 行业 报告 显示 苹果 位居 榜首",} # 人工标注: 搜索"苹果"时真正相关的文档 (想买苹果电子产品的人)RELEVANT = {0, 2, 4, 7, 9} # 极简同义词表SYNONYMS = { "苹果": ["手机", "水果", "iPhone", "Mac"], "手机": ["iPhone", "智能手机"], "水果": ["香蕉", "维生素"],} def tokenize(text): """按空格切分得到词列表.""" return text.split() def score(query_terms, doc_terms): """计算查询词在文档中的词频总分.""" cnt = Counter(doc_terms) return sum(cnt[t] for t in query_terms) def search(query_terms, top_k=None): """返回按得分降序的 (doc_id, score) 列表.""" ranked = [] for doc_id, text in DOCS.items(): ranked.append((doc_id, score(query_terms, tokenize(text)))) ranked.sort(key=lambda x: x[1], reverse=True) if top_k is not None: ranked = ranked[:top_k] return ranked def expand_by_synonyms(query_terms): """同义词扩展: 查询词查表并扩充.""" expanded = set(query_terms) for term in query_terms: if term in SYNONYMS: expanded.update(SYNONYMS[term]) return list(expanded) def pseudo_feedback(query_terms, top_k=3, extra=2): """伪相关反馈: 取前top_k篇文档, 提取高频词加入查询.""" feedback_docs = search(query_terms, top_k=top_k) counter = Counter() for doc_id, _ in feedback_docs: counter.update(tokenize(DOCS[doc_id])) for term in query_terms: counter.pop(term, None) return query_terms[:] + [w for w, _ in counter.most_common(extra)] def recall_at_k(doc_ids, k=5): """计算前k篇结果中的召回率.""" hits = [d for d in doc_ids[:k] if d in RELEVANT] recall = len(hits) / len(RELEVANT) return hits, recall def main(): q = ["苹果"] print("原始查询:", q) base = search(q) base_ids = [d for d, _ in base] hits, rec = recall_at_k(base_ids) print("返回top5:", base_ids[:5], "命中相关:", hits[:5]) print("recall@5 = %.2f" % rec) expanded = expand_by_synonyms(q) print("\n同义词扩展后:", expanded) res2 = search(expanded) res2_ids = [d for d, _ in res2] hits, rec = recall_at_k(res2_ids) print("返回top5:", res2_ids[:5], "命中相关:", hits[:5]) print("recall@5 = %.2f" % rec) feedback = pseudo_feedback(expanded) print("\n伪相关反馈再加词:", feedback) res3 = search(feedback) res3_ids = [d for d, _ in res3] hits, rec = recall_at_k(res3_ids) print("返回top5:", res3_ids[:5], "命中相关:", hits[:5]) print("recall@5 = %.2f" % rec) print("\n结论: 查询扩展让top5命中的相关文档数由3个增加到4个") if __name__ == "__main__": main()
DOCS预置的模拟文档库,词语已用空格隔开,省去中文分词依赖,让代码专注演示扩展逻辑。RELEVANT人工标注的“标准答案”,即搜索“苹果”时真正相关的文档集合,用于计算召回率。SYNONYMS = {"苹果": ["手机", "水果", "iPhone", "Mac"]}极简同义词表,模拟服务员口中的“黑话词典”。def score(query_terms, doc_terms)用查询词在文档中的词频之和作为打分依据,模拟检索打分过程。def search(query_terms, top_k=None)遍历文档库计算得分并排序,返回 Top-K 文档,相当于餐厅端出最匹配的几道菜。def expand_by_synonyms(query_terms)核心扩展逻辑:查询词逐词查表,命中就把同义词并入查询集合。def pseudo_feedback(query_terms, top_k=3, extra=2)伪相关反馈:先把首轮 Top-3 文档的词频汇总,剔除查询已有词,选频率最高的 2 个词回注。recall_at_k(doc_ids, k=5)计算前 5 篇结果中相关文档的占比,即“上菜率”。base_ids[:5]只截取前 5 篇结果做评估,贴近工程中“只看第一页”的真实体验。
常见误区
误区初学者常把查询扩展和查询改写混为一谈,觉得两者都是“把用户输入换成更好的说法”。搜索系统里常常一起出现,更让人分不清谁是谁。
正解查询改写的本质是“替换”——把原查询翻译成新查询(如“北京市今天的天气”→“北京 天气”);查询扩展的本质是“叠加”——原查询词一个不动,在旁边追加相关词(如“苹果”→“苹果 手机 水果”)。如果把餐厅场景套进来:改写是服务员复述确认菜单,扩展是服务员多端几道候选菜。两者是流水线上相邻的两个环节,但动作完全不同。
为何常见:因为在真实搜索系统中,改写和扩展往往串联使用,并且都发生在“查询预处理”这个阶段,表面看起来都在“改查询”,于是被混为一谈。
误区“多加点词,反正召回率会上升,词多多益善。” 不少人在调参时把扩展词数量拉到二三十个,觉得这样覆盖率最高。
正解扩展词并非越多越好。每加一个词,就会引入一份噪声:不相关的扩展词会把文档库中无关的内容也捞出来,召回率虽然上升,精确率却显著下降——用户看到一堆不相关结果,体验反而更差。正确做法是像服务员加菜一样:先看客人反应(A/B 实验),控制扩展词数量与质量,监测精确率、点击率、转化率等下游指标,找到召回与精确的最佳平衡点。
为何常见:因为召回率的计算公式只看“有没有捞到相关文档”,不看“捞出来的文档里有多少是垃圾”。只盯着单指标优化,自然会产生“词越多越好”的错觉。
误区名字里带“反馈”二字,初学者以为伪相关反馈是“用户看完搜索结果点击了哪些,系统再据此扩展”,需要真实用户的交互行为才能工作。
正解伪相关反馈的最大特点就是“伪”——它假设第一轮检索返回的前 N 篇文档与查询相关,完全不需要用户做任何标注或点击,全程自动执行。真正的“相关反馈”(如用户手动标记相关文档)是另一套更古老且成本更高的交互式方法。伪相关反馈的代价是:这个假设并不总是成立,首轮结果不佳时,扩展词会被带偏,所以实践中要加质量过滤。
为何常见:“反馈”在机器学习语境中常指“来自标注者的反馈”,而伪相关反馈的反馈来源是检索系统自己的排名结果,这个反直觉的设定让初学者容易误解。
误区看到词嵌入扩展输出一批与查询词相近的词,便认为它只是在自动找同义词,和同义词表扩展没什么区别,只是换了种自动化生成方式。
正解同义词表收录的是“可以互换”的词(苹果↔iPhone),而词嵌入找的是“语义相关”的词(苹果↔华为、苹果↔乔布斯、苹果↔富士康)。相关不等于同义,甚至可能是类比、上下位或场景关系。词嵌入扩展的覆盖范围远大于同义词表,但噪声也更大,因此通常需要设相似度阈值,并与同义词表互补使用。
为何常见:因为两种扩展方式的输出形式很相似——都是“在原查询旁边多出几个词”,而初学者还没建立起“同义 ≠ 相关”的概念边界,自然会把两者看成同一件事。
面试题
Q1. 查询扩展的核心目标是什么?
- A.压缩索引体积
- B.提升搜索召回率← 正确答案
- C.加速查询解析
- D.美化界面样式
答案:B。查询扩展通过添加相关词扩大查询覆盖面,让更多相关文档有机会被检索到,核心收益就是召回率提升。压缩索引、加速解析、美化界面都不是扩展的目标,它们分属存储、性能与前端领域。
Q2. 同义词扩展依赖的主要资源是什么?
- A.同义词表← 正确答案
- B.用户头像
- C.文档字体
- D.网络延迟
答案:A。同义词扩展的核心就是一张同义词表,查询时查表把同义词并入查询。用户头像、文档字体、网络延迟都与语义扩展无关,属于明显的干扰项。
Q3. 伪相关反馈中“伪”的含义是什么?
- A.伪造用户点击数据
- B.假设首轮结果相关← 正确答案
- C.扩展词是虚假的
- D.指扩展词具有伪造性
答案:B。“伪”体现在它并不确认首轮结果真的相关,而是直接假设前 N 篇文档相关并加以利用。这既不是伪造数据,也不是扩展词虚假,而是“未经证实的相关假设”。
Q4. 词嵌入扩展挑选扩展词的依据是什么?
- A.词语出现频率
- B.向量余弦相似度← 正确答案
- C.拼音完全相同
- D.字面包含关系
答案:B。词嵌入把词映射为向量,两个词的语义相近程度用向量余弦相似度衡量,选出相似度 Top-N 的词作为扩展词。词频反映的是重要性而非语义相近,拼音和字面关系都与语义无关。
Q5. 查询改写与查询扩展的本质区别是什么?
- A.改写生成新查询,扩展叠加词← 正确答案
- B.改写用于离线,扩展用于在线
- C.改写提升召回,扩展提升精度
- D.改写一定更好,扩展没有用
答案:A。改写是替换式的——输出一个新查询替换原查询;扩展是叠加式的——原查询保留,额外附加相关词。两者没有离线在线之分,也不是一个提召回一个提精度的分工,更不存在谁一定更好的说法。
Q6. 召回率的计算公式是什么?
- A.检索的文档数除以全部文档数
- B.检索到的相关数除以全部相关数← 正确答案
- C.正确推荐数除以推荐总数
- D.相关文档数除以检索文档数
答案:B。召回率 = 检索到的相关文档数 ÷ 全部相关文档数,它衡量的是“该捞的都捞出来了吗”。选项 A 是覆盖率、选项 C 是精确率、选项 D 是另一种口头的“命中率”,都不对。
Q7. 伪相关反馈在第二轮检索前做了哪件事?
- A.直接删除原始查询词
- B.提取反馈文档关键词加入← 正确答案
- C.跳过第一轮检索打分
- D.仅保留得分最高的文档
答案:B。伪相关反馈的两轮流程是:先检索取前 N 篇,再从这些文档中提取高频词回注查询,最后执行第二轮检索。删除原查询会丢失意图,跳过打分会失去排名依据,仅保留一篇文档则信息量不足。
Q8. 查询扩展的常用实现方式有哪些?
- A.同义词表规则扩展← 正确答案
- B.伪相关反馈扩展← 正确答案
- C.词嵌入相似词扩展← 正确答案
- D.中文分词标注词性
答案:ABC。三种主流扩展方式是同义词表、伪相关反馈和词嵌入相似词。中文分词标注是查询预处理的基础步骤,它负责把句子切成词,本身并不产生扩展词,属于干扰项。
Q9. 同义词表可以通过哪些途径构建?
- A.人工编纂同义词表← 正确答案
- B.用户点击日志挖掘← 正确答案
- C.词嵌入自动聚类← 正确答案
- D.随机抽取无关词组
答案:ABC。人工编纂质量高但成本大,点击日志挖掘能捕捉真实搜索场景下的同义关联,词嵌入聚类可自动发现语义相近的词对再辅以人工审核。随机抽取无关词组无法构建有语义价值的同义词表。
Q10. 关于伪相关反馈,下列说法正确的有哪些?
- A.无需用户手动标注← 正确答案
- B.假设前N篇结果相关← 正确答案
- C.可动态补充查询词← 正确答案
- D.扩展词必须出自词典
答案:ABC。伪相关反馈自动假设首轮 Top-N 结果相关并从中提炼词,全程无需用户参与,能动态补充超出原查询的词语。它的扩展词来自检索文档,而非预先准备的词典,因此 D 错误。