同义词的扩展或收缩edit

同义词格式 中,我们看到了可以通过 简单扩展(simple expansion) 、 简单收缩(simple contraction) 、或 类型扩展(generic expansion) 来指明同义词规则。 本章节我们将在这三者间做个权衡比较。

本节仅处理单词同义词。多词同义词又增添了一层复杂性,在 多词同义词和短语查询 中,我们将会讨论。

简单扩展 (Simple Expansion)edit

通过 简单扩展 ,我们可以把同义词列表中的任意一个词扩展成同义词列表 所有 的词:

"jump,hop,leap"

扩展可以应用在索引阶段或查询阶段。两者都有优点 (⬆)︎ 和缺点 (⬇)︎。到底要在哪个阶段使用,则取决于性能与灵活性:

索引 查询

索引的大小

⬇︎ 更大, 因为所有的同义词都会被索引。

⬆︎ 正常大小。

关联

⬇︎ 所有同义词都有相同的逆向文档频率(IDF),这意味着更常用的词和不常用的词都拥有着相同的权重。

⬆︎ 每个同义词的IDF都和原来一样。

性能

⬆︎ 查询只需要找到查询字符串中指定单个词项。

⬇︎ 对一个词项的查询重写来查找所有的同义词,从而降低性能。

灵活性

⬇︎ 同义词规则不能改变现有的文件。对于有影响的新规则,现有的文件都要重建(注:重新索引一次文档)。

⬆︎ 同义词规则可以更新不需要索引文件。

简单收缩 (Simple Contraction)edit

简单收缩 ,把左边的一组同义词映射到右边的一个词:

"leap,hop => jump"

它必须同时应用于索引和查询阶段,以确保查询词项映射到索引中存在的同一个值。

相对于简单扩展方法,这种方法也有一些优点和一些缺点:

索引的大小
⬆︎ 索引大小是正常的,因为只有单一词项(term)被索引。
关联
⬇︎ 所有词项的 IDF 是一样的,所以你无法区分一个词是比较常用的还是不常用的。
性能
⬆︎ 查询只需要找到有这么一个词项(term)的索引.
灵活性

⬆︎ 新同义词可以添加到规则的左侧并在查询阶段使用。例如,我们想添加 bound 到先前指定的同义词规则中。那么下面的规则将作用于包含 bound 的查询或包含 bound 的文档索引:

"leap,hop,bound => jump"

似乎对旧有的文档不起作用是么?其实我们可以把上面这个同义词规则改写下,以便对旧有文档同样起作用:

"leap,hop,bound => jump,bound"

重建索引时,就可以恢复到之前的规则(即: leap,hop,bound => jump )来获得查询单个词项的性能优势(注:因为上面那个规则相比这个而言,查询阶段就只要查询一个词了)。

类型扩展 (Genre Expansion) edit

类型扩展是完全不同于简单收缩 或扩张, 并不是平等看待所有的同义词,而是扩大了词的意义,使被拓展的词更为通用。以这些规则为例:

"cat    => cat,pet",
"kitten => kitten,cat,pet",
"dog    => dog,pet"
"puppy  => puppy,dog,pet"

通过在索引阶段使用类型扩展:

  • 一个关于 kitten 的查询会发现关于 kittens 的文档。
  • 查询一个 cat 会找到关于 kittenscats 的文档。
  • 一个 pet 的查询将发现有关的 kittenscatspuppiesdogs 或者 pets 的文档。

或者, 在查询阶段使用类型扩展, kitten 的查询结果就会被拓展成涉及到 kittens、cats、dogs。

有个两全其美的办法: 通过在索引阶段应用类型扩展同义词规则,以确保类型(genres)在索引中存在。然后,在查询阶段, 可以选择不采用同义词(这样kitten查询只返回与kittens有关的文件),或 采用同义词(kitten的查询操作就会返回包括kittenscatspetsdogspuppies的相关结果)。

前面的示例规则,kittenIDF是正确的,而catpetIDF将会被 Elasticsearch 人为的降低。然而, 这是有利的,比如, 执行kitten 或 cat 或 pet(即:只要其中一个匹配) 查询时使用类型扩展, kitten 相关的文档应该排在最上方,其次是cat, 而pet将被排在最底部。