你走进一家小馆子,对老板说:“来个那个……甜甜的、红红的东西。”老板一愣,你补了一句:“就是那个水果。”老板恍然大悟:“哦!苹果!”——这顿饭能顺利点成,靠的是老板的“翻译能力”。用户搜索时,也常常只能说出“那个甜甜红红的”,而文档库里躺着的,却是写着"iPhone"“雪花梨”“乔布斯”的资料。查询扩展要做的,就是给搜索引擎配一位“善解人意的服务员”:当用户表达不够精确时,主动补上同义词、关联词,甚至先试搜一轮再从结果里反推用户的真实意图。这篇教程会带你从点菜的视角,把查询扩展的三种主流策略、质量陷阱和评估方法一次看清。

岗位关联

对 AI 从业者而言,理解查询扩展是构建高质量搜索系统的必备功:它直接决定检索召回率与用户体验,也是通往查询理解、对话式搜索等进阶能力的基石。

目录
  1. 可视化演示
  2. 扩展概览
  3. 词典扩展
  4. 统计关联扩展
  5. 伪相关反馈
  6. 扩展词评估
  7. 查询漂移抑制
  8. 改写协同
  9. 效果评估
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示同义词扩展、关联词扩展和伪相关反馈三种查询扩展策略的原理与流程,支持步进切换对比。

本节配有交互动效(进入视口后自动加载,约 3KB)。

同义词扩展:基于词典的词项扩展 原始查询词通过WordNet等词典查找同义词 同义词如car→auto/veh/moto recall↑ = |相关文档∩扩展后检索| / |相关文档| 词典扩展简单但覆盖面有限

扩展概览

客人说出“那个甜甜的、红红的东西”,服务员需要翻译成菜单上的“苹果”。搜索引擎面对的也是一样:用户脑中想的是“苹果”,输入框里敲下的却可能是“水果”“红富士”甚至“iPhone“。这种”用户表达出来的词“与”文档真实使用的词”之间的错位,就是搜索领域常说的词汇鸿沟。它不是某一个人的表达问题,而是人类语言的天然属性——同一个概念,可以有成千上万种说法。

查询扩展正是为了跨越这道鸿沟而生的技术:系统在原始查询词的基础上,自动补充一批同义词、关联词,再用扩充后的词集合去检索。这个过程通常分三步走:第一步,从词典、统计资源或反馈文档中生成候选词;第二步,对候选词打分,评估它们与查询主题的相关性;第三步,过滤低质量候选词,把幸存者与原始查询合并,交给检索引擎。短查询(如“苹果”)和长尾需求(如“苹果笔记本维修”)尤其依赖这项技术,因为词越少,可供匹配的信号就越弱。

从数学上看,词汇鸿沟可以被量化成查询词表与文档词表的重叠率。给定查询 Q 和文档 D,重叠率定义为:

回到点菜的比喻:重叠率低,就像客人说的“甜红果子”和菜单上的“苹果”一个字都对不上。服务员要做的不只是听懂,还要主动补上“这桌客人可能指的是那几道菜”——这正是查询扩展的使命。

overlap(Q,D)=∣VQ∩VD∣∣VD∣\text{overlap}(Q,D)=\frac{|V_Q \cap V_D|}{|V_D|}
overlap 衡量查询词表和文档词表的重合程度;值越低,说明鸿沟越深,越需要查询扩展来搭桥。
  1. 查询词集合$V_Q$ 表示把用户查询按空格或分词拆出来的词集合
    VQ={q1,q2,…,qm}\displaystyle V_Q=\{q_1,q_2,\ldots,q_m\}
  2. 文档词集合$V_D$ 表示把一篇文档拆出来的去重词集合
    VD={d1,d2,…,dn}\displaystyle V_D=\{d_1,d_2,\ldots,d_n\}
  3. 交集取共有词$V_Q \cap V_D$ 是同时出现在查询和文档中的词
    VQ∩VD={w∣w∈VQ 且 w∈VD}\displaystyle V_Q \cap V_D=\{w \mid w \in V_Q \text{ 且 } w \in V_D\}
  4. 归一化到文档分母取 $|V_D|$,将重叠程度折算成 0 到 1 之间的比例,值越小鸿沟越大

词典扩展

服务员手中有一本“菜品对照表”,客人说“甜红果子”,他翻一下表格,发现对应“苹果”。词典扩展的思路如出一辙:预先构建一部同义词词典或关联词词典,查询进来后,直接查表取出同义词加入查询。这是最古老也最直观的扩展方式,在知识组织良好的领域里非常可靠。

同义词词典的构建并非全手工。半自动构建流程通常是:由语言专家准备一批种子词对(如“苹果—iPhone”),再用规则或统计方法从语料中挖掘候选词对,最后人工审核入库。这种方法的优点是词对质量高、可解释性强;缺点也同样明显——领域适配局限。新出现的网络热词、专业术语、品牌名,词典往往来不及收录;而一部覆盖全领域的通用词典,又很难照顾到“法律术语”或“游戏黑话”这样的垂直表达。

扩展之后,检索打分需要考虑扩展词的权重。常见的做法是给扩展后的查询词集合中的每个词分配一个权重,再对文档进行加权求和打分:

对照表能解决常见的“黑话”,但新菜上市时,表格来不及更新。客人要是说一句刚流行起来的“东北话”,服务员就傻眼了——这就是词典扩展的天花板,也是我们要引入统计方法的原因。

score⁡(D)=∑t∈Q′wt⋅tf⁡(t,D)\operatorname{score}(D)=\sum_{t \in Q'} w_t \cdot \operatorname{tf}(t,D)
文档得分等于扩展后查询词集合中每个词的权重与其在文档中出现次数的乘积之和;权重越大的词,对得分的影响越强。
  1. 扩展查询集合$Q'$ 是原始查询词与词典扩展词的并集
    Q′=Q∪{s∣s∈Syn(q), q∈Q}\displaystyle Q' = Q \cup \{s \mid s \in \text{Syn}(q),\, q \in Q\}
  2. 每词权重$w_t$ 表示词 $t$ 的重要程度,原始词通常权重大于扩展词
    wt={1.0,t∈Q0.5,t∈Syn(q)\displaystyle w_t = \begin{cases} 1.0, & t \in Q \\ 0.5, & t \in \text{Syn}(q) \end{cases}
  3. 词频统计$\operatorname{tf}(t,D)$ 是词 $t$ 在文档 $D$ 中出现的次数,出现越多贡献越大
    tf⁡(t,D)=∑k[t=dk]\displaystyle \operatorname{tf}(t,D) = \sum_{k} [t = d_k]
  4. 加权累加对所有词求和,得到文档与扩展查询的匹配得分,据此排序

统计关联扩展

聪明的服务员不只靠手册,还会记“邻桌都怎么点”:十个客人点“苹果”,七个都加了一份“水果拼盘”。统计关联扩展正是基于这种直觉,从大量语料中发现词与词之间的共现规律。共现统计的基本假设是:如果两个词频繁出现在同一篇文档、同一个窗口或同一句话里,它们大概率语义相关。比如“苹果”和“iPhone“会共同出现在科技新闻里,和”水果”会共同出现在生鲜电商页面里。

有了共现记录,接下来要回答“相关到什程度”。一个常用的量化指标是 Dice 系数,它把两个词共同出现的次数,折算成 0 到 1 之间的关联强度:

除了共现统计,词向量近邻是另一种统计关联路线:先用 Word2Vec 等模型把词映射成向量,再在向量空间里找余弦距离最近的词作为扩展词。它的好处是能捕捉“语法上不同、语义上相近”的词,比如“苹果”的近邻里可能出现“乔布斯”。“邻桌记录”越丰富,服务员就越懂客人的搭配习惯。但统计关联也有噪音:两个词共现可能只是巧合,而非真有语义联系。

Dice⁡(w,q)=2×c(w,q)c(w)+c(q)\operatorname{Dice}(w,q)=\frac{2 \times c(w,q)}{c(w)+c(q)}
Dice 系数衡量词 w 与查询词 q 的共现强度;值越接近 1,说明两者越经常并肩出现,越适合作为扩展词。
  1. 共现次数$c(w,q)$ 表示词 w 和词 q 在语料中一起出现的次数
    c(w,q)=∑d∈D[w∈d∧q∈d]\displaystyle c(w,q)=\sum_{d \in \mathcal{D}} [w \in d \land q \in d]
  2. 单现频次$c(w)$ 与 $c(q)$ 分别是词 w、词 q 各自在语料中出现的总次数
    c(w)=∑d∈D[w∈d]\displaystyle c(w)=\sum_{d \in \mathcal{D}} [w \in d]
  3. 两倍共现分子取 $2 \times c(w,q)$,使系数值域落在 0 到 1
    0≤Dice⁡(w,q)≤1\displaystyle 0 \le \operatorname{Dice}(w,q) \le 1
  4. 归一化分母$c(w)+c(q)$ 是两个独立频次之和,频次悬殊的词对会被自然压低

伪相关反馈

服务员遇到拿不准的客人,会先端上两道“最可能的菜”;客人动筷子最多的一道,服务员就把它的配料记下来,追加进订单。伪相关反馈(Pseudo-Relevance Feedback,简称 PRF)用的正是这套“先试再学”的思路:先用原始查询检索一轮,把排名靠前的 Top-K 篇文档当作“客人动过筷子的菜”,假设它们与查询相关,然后从这些文档中抽取高频且有区分度的词,作为扩展词加回查询。

为什么叫“伪”相关?因为系统并没有人工标注,只是“假装”排名靠前的文档一定相关。这个 Top-K 文档假设在多数场景下成立,但也会出错——如果前几篇文档本身就跑偏了,反馈就会把错误放大。所以 PRF 在挑选扩展词时,不能简单地取最高频,而要给词计算权重。经典的 Robertson 权重(又称 RSJ 权重)公式如下:

服务员记下的是“客人真正吃光的配料”,而不是端上桌的所有菜。PRF 也一样:只把在伪相关文档中明显超常出现的词纳入扩展词,从而让加料更精准。

w(1)(t)=log⁡(r+0.5)(N−n−R+r+0.5)(n−r+0.5)(R−r+0.5)w^{(1)}(t)=\log \frac{(r+0.5)(N-n-R+r+0.5)}{(n-r+0.5)(R-r+0.5)}
这个权重回答的问题是:词 t 出现在“伪相关文档”中的比例,是否显著高于它在全集中的普遍比例;差异越大,词越有资格当扩展词。
  1. 相关文档数$R$ 是伪相关文档总数,即 Top-K 的大小
    R=∣Rtop∣\displaystyle R = |\mathcal{R}_{top}|
  2. 相关中含词数$r$ 是伪相关文档中出现词 $t$ 的文档数
    r=∣{d∈Rtop:t∈d}∣\displaystyle r = |\{d \in \mathcal{R}_{top} : t \in d\}|
  3. 全集参数$N$ 是语料文档总数,$n$ 是含词 $t$ 的文档总数
    N=∣D∣,n=∣{d∈D:t∈d}∣\displaystyle N = |\mathcal{D}|, \quad n = |\{d \in \mathcal{D} : t \in d\}|
  4. 平滑防零分子分母都加 $0.5$,避免出现 $\log 0$ 导致权重无穷大
    r+0.5,  n−r+0.5,  R−r+0.5,  N−n−R+r+0.5\displaystyle r+0.5,\; n-r+0.5,\; R-r+0.5,\; N-n-R+r+0.5
  5. 取对数得权重$\log$ 把比值映射到实数轴,正数表示词在相关文档中更常见,适合扩展

扩展词评估

加料之前,服务员会先尝一口:这味料是让菜更香,还是串了味?扩展词评估解决的就是“这味料该不该加”的问题。评估维度主要有三个:词项区分度、查询焦点保持、权重过滤。

词项区分度说的是:一个词如果满大街都是(比如“的”“内容”“我们”),它就没有资格当扩展词,因为它无法把相关文档和不相关文档区分开。信息检索中常用 IDF(逆文档频率)来度量词的区分能力:

查询焦点保持则回答“这个扩展词离用户本意有多远”:扩展词应与原始查询在向量空间或共现关系上保持足够近,否则会带偏检索方向。最后一步是权重过滤:把上面算出的 IDF、关联强度或 Robertson 权重乘起来得到综合得分,得分低于阈值的候选词直接丢弃。服务员的原则是“宁缺毋滥”——不是所有候选料都值得下锅。

IDF⁡(t)=log⁡Ndf⁡(t)\operatorname{IDF}(t)=\log \frac{N}{\operatorname{df}(t)}
IDF 衡量词 t 的稀有程度:含词 t 的文档越少,IDF 越高,词的区分能力越强;常见词的 IDF 趋近于 0。
  1. 文档总数$N$ 是语料库中的文档总数
    N=∣D∣\displaystyle N = |\mathcal{D}|
  2. 文档频率$\operatorname{df}(t)$ 是包含词 $t$ 的文档数,注意与词频区分
    df⁡(t)=∣{d∈D:t∈d}∣\displaystyle \operatorname{df}(t) = |\{d \in \mathcal{D} : t \in d\}|
  3. 取对数压缩$\log$ 让 IDF 的增长趋缓,避免稀有词权重爆炸
    log⁡Ndf⁡(t)\displaystyle \log \frac{N}{\operatorname{df}(t)}
  4. 高低判断$\operatorname{df}(t)$ 接近 $N$ 时 IDF 接近 0,说明该词区分度低,应被过滤

查询漂移抑制

如果服务员把客人的“苹果”一路加料成“水果沙拉配苹果醋再撒点苹果木熏肉”,端上来恐怕没人认识这道菜了。查询漂移指的就是:扩展词过多或权重失控,导致检索焦点从原始查询一路滑向另一个主题。漂移成因主要有两个:一是扩展词数量失控,引入了太多与查询弱相关的词;二是扩展词权度过高,盖过了原始查询词。

过度扩展危害非常直接:召回率确实涨了,但排在前面的文档大量跑题,精确率断崖式下跌。用户搜“苹果”想买水果,结果前十条全是“苹果手机壳”和“苹果醋酿造工艺”。抑制策略通常从三方面入手:限制扩展词数量(比如最多加 5 个)、压低扩展词权重(设 0.2 到 0.5)、对扩展词与原始查询做相似度约束。我们可以用一个“漂移风险比”来监控加料是否过量:

服务员每加一味料,都要回头比对“这还是不是客人最初点的那道菜”。当风险比过高时,就得果断撤掉一部分加料,让查询焦点重新回到原始意图上。

Risk⁡drift=∑t∈E∖Q0wt∑t∈Q′wt\operatorname{Risk}_{\text{drift}}=\frac{\sum_{t \in E \setminus Q_0} w_t}{\sum_{t \in Q'} w_t}
漂移风险比 = 新增扩展词的权重之和 ÷ 扩展后全部词的权重之和;比值越大,检索焦点就越容易被带偏。
  1. 新增扩展词集$E \setminus Q_0$ 表示只属于扩展词、不属于原始查询词的集合
    E∖Q0={t∈E:t∉Q0}\displaystyle E \setminus Q_0 = \{t \in E : t \notin Q_0\}
  2. 新增词权重和分子是把这些新增词的权重加起来,衡量“加了多少料”
    ∑t∈E∖Q0wt\displaystyle \sum_{t \in E \setminus Q_0} w_t
  3. 全部词权重和分母是扩展后查询词集合 $Q'$ 里所有词的权重总和
    ∑t∈Q′wt\displaystyle \sum_{t \in Q'} w_t
  4. 比值含义比值越接近 1,说明查询里几乎全是扩展词的贡献,漂移风险越高;应控制在 0.3 以下

改写协同

有时服务员会先跟客人确认:“您说的'甜红果子',是不是指苹果?”等客人点头,再决定后续加什么料。查询改写与查询扩展的关系正是如此:改写调整查询的“表达方式”,比如“苹果手机”改写为“iPhone“;扩展增加查询的”词项数量“,比如”苹果“扩展出”水果、乔布斯、平板”。

两者分工不同,但可以协同处理。典型的协同流程是:先用改写模块把口语化、错别字、中英混杂的表达规整成标准形式;再做扩展,从词典或反馈中补充关联词;最后合并为正式查询去检索。更进一步,交互式查询允许用户参与其中——把候选扩展词展示给用户打勾确认,就像服务员推荐配菜时问一句“要不要加这个?”既保证覆盖率,又避免跑偏。

协同设计中给扩展词打分,常用 KL 散度衡量“这个词在相关文档中的分布,与全集分布有多大差异”:

先确认需求,再加料,保证每一勺料都对路——这就是改写与扩展协同的精髓:前者保证“问对问题”,后者保证“找全答案”。

score⁡(w)=P(w∣R)log⁡P(w∣R)P(w∣C)\operatorname{score}(w)=P(w\mid R)\log\frac{P(w\mid R)}{P(w\mid C)}
候选扩展词 w 得分 = 它在相关文档集合中的概率 × 它与全集分布的 KL 差异;词在相关文档中越突出、越偏离全集,越值得被选中。
  1. 相关集概率$P(w \mid R)$ 是词 $w$ 在相关文档集合(如改写后查询命中的文档)中的概率
    P(w∣R)=tf⁡(w,R)∣R∣\displaystyle P(w \mid R)=\frac{\operatorname{tf}(w,\mathcal{R})}{|\mathcal{R}|}
  2. 全集概率$P(w \mid C)$ 是词 $w$ 在全体文档中的概率,作为“背景噪音”基线
    P(w∣C)=df⁡(w)N\displaystyle P(w \mid C)=\frac{\operatorname{df}(w)}{N}
  3. 对数比值$\log \frac{P(w \mid R)}{P(w \mid C)}$ 表示词在相关集中“超常”的程度
    log⁡P(w∣R)P(w∣C)\displaystyle \log \frac{P(w \mid R)}{P(w \mid C)}
  4. 加权综合乘上 $P(w \mid R)$,让那些本身太稀少的词不会因为比值大而虚高
    P(w∣R)log⁡P(w∣R)P(w∣C)\displaystyle P(w\mid R)\log\frac{P(w\mid R)}{P(w\mid C)}

效果评估

菜改进了,到底好不好吃?要数回头客。搜索引擎也一样,不能只凭感觉说“扩展有效”,要靠指标说话。召回率提升是最直接的收益:扩展前搜“苹果”只找到 10 篇相关文档,扩展后找到 50 篇,说明系统把更多藏在"iPhone"“水果”背后的文档打捞了上来。

排序质量的核心指标之一是 MAP(Mean Average Precision,平均准确率均值),它综合衡量“相关文档是否排得靠前”:

离线与在线测试要双管齐下:离线阶段用带标注的数据集计算 MAP、召回率;上线后用点击率、无结果率、用户停留时长来验证真实体验。就像服务员不能只盯着自己觉得好吃的菜,要看看客人是不是真的常来——指标对齐了,每一次扩展才真正有据可依。

MAP⁡=1∣Q∣∑q=1∣Q∣1Rq∑k=1nPq@k⋅rel⁡(q,k)\operatorname{MAP}=\frac{1}{|Q|}\sum_{q=1}^{|Q|}\frac{1}{R_q}\sum_{k=1}^{n}P_q@k \cdot \operatorname{rel}(q,k)
MAP 先对每个查询算“相关文档出现位置处的准确率平均值”,再对所有查询取平均;值越高,说明相关文档整体排得越靠前。
  1. 查询集合大小$|Q|$ 是评估用查询的总数
    ∣Q∣=∑q=1M1\displaystyle |Q| = \sum_{q=1}^{M} 1
  2. 单查询平均$\frac{1}{R_q}$ 是除以该查询的相关文档总数,避免相关文档多的查询占便宜
    1Rq∑k=1nPq@k⋅rel⁡(q,k)\displaystyle \frac{1}{R_q} \sum_{k=1}^{n} P_q@k \cdot \operatorname{rel}(q,k)
  3. 位置准确率$P_q@k$ 是前 $k$ 个结果中相关文档所占比例
    Pq@k=前 k 个结果中的相关文档数k\displaystyle P_q@k=\frac{\text{前 } k \text{ 个结果中的相关文档数}}{k}
  4. 相关指示$\operatorname{rel}(q,k)$ 取 1 或 0,表示第 $k$ 个结果对查询 $q$ 是否相关
    rel⁡(q,k)∈{0,1}\displaystyle \operatorname{rel}(q,k) \in \{0,1\}
  5. 外层平均最外层 $\frac{1}{|Q|}\sum_{q=1}^{|Q|}$ 把所有查询的值平均,得到全局排序质量

AI 应用场景

电商搜索的“同义词翻译官”

阶段:查询理解与召回阶段

解决的问题:电商平台上,用户搜“苹果”可能想买手机、水果、还是平板?传统检索只做字面匹配,把大量相关商品挡在了门外。查询扩展把“苹果”扩展为"iPhone““红富士””MacBook"等词,再分别召回合集,商品覆盖率显著提升。

具体案例:某电商搜索系统接入词典扩展 + 统计关联扩展后,搜索“苹果”的召回量提升了 62%,“苹果 手机”等复合查询的点击率上升 18%。扩展词还根据类目动态调整:在生鲜类目下“苹果”优先扩展水果词,在数码类目下优先扩展品牌词。

法律文献检索的“术语桥”

阶段:召回与重排阶段

解决的问题:法律文书中“原告”“起诉人”“上诉人”指代同一角色,普通用户搜“起诉人”却匹配不到大量含“原告”的文书。查询扩展用领域同义词词典 + 伪相关反馈,从已判案例中抽取术语关联,把查询桥接到真正的法律词汇。

具体案例:某法律检索平台针对“借款纠纷”相关查询,先用词典扩展补齐术语,再对 Top-20 结果做 PRF,抽取出“民间借贷”“利息约定”等高频法律概念加入查询,最终让相关判例的召回率从 34% 提升到 79%。

企业知识库客服的“智能接线员”

阶段:Query 理解与文档召回

解决的问题:员工在客服系统里问“怎么报销差旅费”,知识库文档标题却写的是“费用报销-差旅篇”。查询改写先规整出“报销、差旅”,查询扩展再补上“发票、住宿、交通”,让答案文档顺利浮出水面。

具体案例:某企业内部知识库部署“改写 + 扩展”流水线后,首次搜索即命中目标文档的比例从 41% 提高到 83%,无结果率下降了 55%,大量重复工单被直接化解。

Python 演示

python59 行
import mathimport refrom collections import Counter  class PRFRetriever:    """基于伪相关反馈的简易检索演示器"""     def __init__(self, docs):        self.docs = docs        self.word_lists = [self._tokenize(d) for d in docs]        self.total_docs = len(docs)        self.df_map = {}        for words in self.word_lists:            for w in set(words):                self.df_map[w] = self.df_map.get(w, 0) + 1     def _tokenize(self, text):        return re.findall(r"[\w\u4e00-\u9fa5]+", text.lower())     def score(self, query_words):        scores = []        for words in self.word_lists:            s = 0            for w in query_words:                if w in words:                    df = self.df_map.get(w, 1)                    s += math.log(self.total_docs / df)            scores.append(s)        return scores     def expand(self, query, top_k=2, expand_n=3):        q_words = self._tokenize(query)        scores = self.score(q_words)        top_idx = sorted(range(len(scores)),                         key=lambda i: scores[i],                         reverse=True)[:top_k]        term_counter = Counter()        for idx in top_idx:            term_counter.update(self.word_lists[idx])        for w in q_words:            term_counter.pop(w, None)        new_terms = [w for w, _ in term_counter.most_common(expand_n)]        return q_words + new_terms  if __name__ == "__main__":    docs = [        "苹果iPhone搭载iOS系统 提供流畅体验",        "苹果是常见水果 含有丰富的维生素",        "公司发布新款平板 支持手写笔和键盘",        "水果市场今天出售新鲜苹果和梨",        "乔布斯创立苹果公司 开创智能手机时代",    ]    retriever = PRFRetriever(docs)    print("初始查询:", "苹果")    print("文档数量:", retriever.total_docs)    expanded = retriever.expand("苹果")    print("扩展查询:", expanded)
目的:演示伪相关反馈的完整流程——先用原始查询对 5 篇文档打分排序,取 Top-2 文档假设为“伪相关”,从中抽取最高频的新词扩展查询。
  1. self.word_lists = [self._tokenize(d) for d in docs]提前把所有文档分词并保存,后续打分直接复用
  2. self.df_map[w] = self.df_map.get(w, 0) + 1统计每个词出现在多少篇文档中,这是 IDF 计算的基础
  3. s += math.log(self.total_docs / df)用简单 TF-IDF 思路给查询与文档的匹配打分,稀有词贡献更高
  4. top_idx = sorted(range(len(scores)), key=lambda i: scores[i], reverse=True)[:top_k]把文档按得分降序排列,取前 top_k 篇作为伪相关文档
  5. term_counter.update(self.word_lists[idx])统计伪相关文档里的词频,扩展词从这里诞生
  6. term_counter.pop(w, None)剔除原始查询词,防止扩展词与查询词重复
  7. new_terms = [w for w, _ in term_counter.most_common(expand_n)]取词频最高的前 expand_n 个词作为扩展词

常见误区

误区“查询扩展嘛,就是把同义词、关联词全塞进去,词加得越多,召回越全,效果肯定越好。”

正解加料不加节制,结果就是查询漂移。用户搜“苹果”想要水果,系统却把“乔布斯”“平板”加重了,返回结果全是数码产品。扩展词数量应设上限,权重也要压低,原始查询词的权重必须占主导。像服务员加料,每加一味都要确认“这道菜还认得出原样吗”。

为何常见:人天然觉得“多”意味着“全”,却忽略了多出来的词可能把检索焦点带偏。

误区“词典是专家手工维护的,质量高,覆盖广,有它在手,所有查询都能扩展到位。”

正解词典是静态的,语言是动态的。新品牌、网络热词、领域黑话永远跑在词典前面;而且跨领域时,同一词在不同语境下有完全不同的关联(“苹果”在生鲜和数码领域各说各话)。词典扩展必须与统计关联、伪相关反馈配合,才能跟上语言的变化。

为何常见:词典看起来最“确定性”、最可靠,容易被它的静态表象迷惑。

误区“排名靠前的文档肯定都相关,直接把它们的高频词当扩展词就行,不用挑。”

正解Top-K 只是在“没有标注”情况下的合理假设,不等于事实。前几篇文档可能恰好是噪音,或偏向某一侧面。必须用 Robertson 权重或 IDF 过滤,只保留“在相关文档中明显超常出现”的词,否则会把噪音放大进第二轮检索。

为何常见:“伪相关”四个字容易让人只看到“相关”,忘了它其实是伪装的。

误区“改写和扩展都是把查询变一变,谁先谁后都一样,效果差不多。”

正解改写是换一种表达方式解决“词对不上”,比如“苹果手机”→“iPhone“;扩展是增加词项解决”信息不足“,比如”苹果“+“水果”+”乔布斯”。两者需要协同:先改写澄清意图,再扩展扩充覆盖面。跳过改写直接扩展,等于服务员没听懂就开始加料,容易南辕北辙。

为何常见:两者在效果上都表现为“查询变了”,实际操作结果不同,容易混淆。

面试题

Q1. 查询扩展的核心目标是什么?

单选题 · easy

  • A.缩短用户查询的文本长度
  • B.弥补查询与文档的词汇鸿沟← 正确答案
  • C.降低索引构建的时间开销
  • D.减少检索结果的返回数量

答案:B。查询扩展通过补充同义词和关联词,让用户查询能匹配到更多表达不同但语义相关的文档,核心是解决词汇鸿沟。缩短文本、降低索引开销、减少返回数量都与查询扩展初衷无关。如同服务员翻译“甜红果子”是为了听懂,而不是省字。

Q2. 以下哪种策略依赖预先构建的词典?

单选题 · easy

  • A.伪相关反馈
  • B.词向量近邻扩展
  • C.同义词词典扩展← 正确答案
  • D.共现统计扩展

答案:C。同义词词典扩展直接在词典中查同义词,伪相关反馈、词向量近邻、共现统计都从语料中动态发现关联,不需要预构建词典。服务员对照“菜品对照表”加料是词典派,靠“邻桌记录”加料是统计派。

Q3. MAP 指标主要衡量检索系统的什么能力?

单选题 · easy

  • A.相关文档是否排得靠前← 正确答案
  • B.索引文件占用的空间大小
  • C.查询请求的响应延迟
  • D.同义词词典的覆盖范围

答案:A。MAP 对每个查询计算相关文档位置处的准确率平均值,再对所有查询平均,衡量的是整体排序质量——相关文档越靠前,MAP 越高。它与管理后端性能、词典覆盖面无关,是评估检索效果的核心指标。

Q4. Dice 系数为 0.5,说明两个词的关联强度处于什么水平?

单选题 · mid

  • A.完全无关,接近零关联
  • B.中等程度关联,可作候选扩展词← 正确答案
  • C.完全同义,可直接替换
  • D.数值无意义,无法解释

答案:B。Dice 系数值域 0 到 1,0.5 表示共现次数在各自频次中占比较高,属于中等偏强关联,适合作为候选扩展词。完全无关应接近 0,完全同义应接近 1(但同义词不等于共现词),Dice 是统计关联度量而非语义等价度量。

Q5. 伪相关反馈中“伪”字的含义是什么?

单选题 · mid

  • A.文档内容是伪造编造的
  • B.未经人工标注,假设 Top-K 结果相关← 正确答案
  • C.扩展词来自虚构的词典
  • D.反馈信号来自用户点击记录

答案:B。伪相关反馈把“排名靠前的文档”直接当作相关文档使用,整个过程没有人工标注,因此叫“伪”。它不是伪造文档或虚构词典,也不依赖用户点击,而是依赖初始检索结果这一自动信号,如同服务员假设“动筷子最多的菜”就是客人喜欢的。

Q6. IDF 越高,说明一个词越具备什么特性?

单选题 · mid

  • A.在单篇文档中出现次数越多
  • B.越能区分相关与不相关文档← 正确答案
  • C.在查询中出现频率越高
  • D.与查询词的共现次数越多

答案:B。IDF = log(N/df(t)),含词 t 的文档越少,IDF 越高,说明该词很稀有、判别力强,能把相关文档从海量文档中筛出来。它衡量的是词项区分度,与单篇词频、查询频率、共现次数无关。稀有配料才能让一道菜有辨识度。

Q7. 查询改写与查询扩展最核心的区别是什么?

单选题 · mid

  • A.改写增加词项数量,扩展更换表达方式
  • B.改写更换表达方式,扩展增加词项数量← 正确答案
  • C.两者完全相同,只是叫法不同
  • D.改写用于离线评估,扩展用于在线查询

答案:B。查询改写把“苹果手机”规整成“iPhone“,改变的是表达形式;查询扩展在”苹果“之外加上”水果”“乔布斯”,增加的是词项集合。两者分工不同但可协同:先改写澄清意图,再扩展扩大召回。选项 A 恰好说反了两者的分工。

Q8. 下列哪些是查询漂移的有效抑制策略?

多选题 · mid

  • A.限制扩展词的数量上限← 正确答案
  • B.降低扩展词的权重← 正确答案
  • C.过滤与原始查询相似度过低的词← 正确答案
  • D.无条件增加词典中的同义词

答案:ABC。抑制漂移的三板斧是限量(限制扩展词数)、降权(压低扩展词权重)、约束(过滤离题词)。无条件增加同义词恰恰会放大漂移风险,让查询焦点越发发散。如同服务员加料要有克制,一味堆料会让菜面目全非。

Q9. 查询重叠率公式中,分母取文档词表大小的意义是什么?

单选题 · easy

  • A.让结果量纲统一,便于跨文档比较← 正确答案
  • B.让分子永远大于分母
  • C.让结果只与查询词数有关
  • D.让结果反映文档的总字数

答案:A。分母用 \(|V_D|\) 将重叠程度归一化到 0 到 1,这样不同长度的文档之间可以公平比较。分子不可能大于分母,结果与查询词数无直接关系,也与文档总字数无关。归一化能让“鸿沟深浅”有统一的度量尺。

Q10. 相比词典扩展,基于统计的关联扩展有哪些天然优势?

多选题 · extreme

  • A.无需人工维护同义词词典← 正确答案
  • B.能自动捕捉领域特定的关联词← 正确答案
  • C.完全杜绝查询漂移现象
  • D.对新兴词汇和时效词更敏感← 正确答案

答案:ABD。统计扩展从语料中自动挖掘共现词或词向量近邻,省去人工词典维护,且能捕捉“苹果—iPhone”这类领域特有的动态关联,对新词反应快。但它并不杜绝查询漂移,反而因为词更杂更需要过滤。词典派胜在稳定,统计派胜在灵活,两者常配合使用。