同义词
ES 6.3.0 同义词配置后 查询结果异常
回复Elasticsearch • akingseu 发起了问题 • 1 人关注 • 0 个回复 • 1520 次浏览 • 2021-04-07 14:34
加入同义词全文检索查询以后,性能明显下降,请问怎么回事呢?
Elasticsearch • liubin 回复了问题 • 6 人关注 • 3 个回复 • 2639 次浏览 • 2019-01-22 11:44
es配置同义词时,只对分词后最小粒度的词有效,对于组合词,加在ik的扩展词表里起不了作用怎么办?
Elasticsearch • rochy 回复了问题 • 3 人关注 • 1 个回复 • 4400 次浏览 • 2018-11-22 21:34
ES查询时有时候走同义词,有时候不走
Elasticsearch • rochy 回复了问题 • 3 人关注 • 2 个回复 • 3489 次浏览 • 2018-11-12 16:04
关于同义词检索方案的一点实践经验
Elasticsearch • Jinyang Zhou 发表了文章 • 0 个评论 • 8147 次浏览 • 2018-06-15 13:36
最近一直在搞同义词搜索的问题,踩了一些坑,总结了一些经验,尤其是刚刚接触搜索和 ES,所以如果有不对的,或者不完备的地方也希望大家能提出改进意见。。。
下面是自己留下的文档记录:
需求
同义词检索也是搜索引擎必备的功能之一,例如,我们希望用户在搜索广东话的同时,也能找出和粤语有关的信息;用户在搜索苹果手机的同时,包含iPhone的内容也能被检索并呈现。
在现实生活中,相同语义的表述词汇往往有很多,而用户在检索的时候很难在一条 query 中将它们全部体现,所以识别和提供同义词检索显然可以获得更高的召回率。
需求剖析
在思考解决方案之前,我们不妨再来看看刚才提到的两个例子:
- 苹果手机与iPhone
- 广东话与粤语
我们先来看第一个,苹果手机和iPhone。
显然,这两个词是等价的,因为苹果公司发布的所有手机产品都叫 iPhone,而 iPhone 这个名字也没有被其他公司使用过。
于是,当用户搜索“苹果手机购买”的时候,我们也就有理由将它拆分成“苹果手机购买”和“iPhone购买”,分别进行检索,再将结果合并返回。
语言学中对这样的词组,称为是同义词中的相对同义词,或是等义词,等义同义词。它们表达意思完全一致,在绝大多数语境中都可以相互替换,同时对上下文也不会产生影响。
这样的词组还有很多,例如:猫熊和熊猫,柚子和文旦等等,这些等义词大抵来说有这样几种来源:
- 音节减缩形成:机枪和机关枪,坦克和坦克车,电扇和电风扇
- 音译和音译形成:出租车和的士 ,维生素和维他命
- 地域叫法不同,或新旧叫法:单车,自行车和脚踏车,西红柿和番茄,马铃薯,洋芋和土豆,黄瓜和胡瓜
- 昵称代称:周杰伦和周董
- 描述角度不同,学名方言差异:电脑和计算机,曲别针和回形针
这些词组多以名词呈现,数量比较少,词组规模也较小,同时变化也很小。
接下来我们再来看第二组词:广东话和粤语。
广东话和粤语这两个词代表的意思是相同的吗?它们也是可以相互替换的吗?
答案显然是否定的。
广东话从语义本身来说是一个比较粗糙的概念,它不仅指广东省内的粤语,还涵盖了潮汕话,客家话,雷州话等其他方言。而粤语却是一个非常严肃的概念,对语音语调都有非常详细的规定,不仅通用于广东省大部分地区,还包括广西、香港、澳门等地,甚至东南亚和北美。它们联系在于,大部分广东地区的人说的是粤语。
如此说来,给广东话和粤语这样非常相似却又并不完全一致的词直接划上等号是有失偏颇的。当然,其实仔细考虑也不难发现,和广东话有相似之处却又不完全相同的词还有很多,例如:客家话、广州话、广府话等等。
语言学中把这样的词汇,称作是相对同义词,或是近义词。它们在意义上有一些相似之处,只能在特定的语境中进行替换。
它们的差别可能包括:
- 语义上:毁坏和损坏(前者更严重),介绍和说明(前者可以对人施加作用)
- 色彩上:团结和勾结
对于这类相似却又不完全相同的近义词,在搜索的时候提供关联搜索是一个不错的方案。例如用户搜索“毁坏公物如何处罚”的时候,查询结果可以由90%的“损坏公物如何处罚”和10%的“毁坏公物如何处罚”查询结果合并后返回,从而获得更多的召回。
这些近义词以动词为主,不仅数量多,词组的规模也大,例如靠近的近义词可以是:靠拢,逼近,接近,迫近等等。
解决思路
在可替换的等义词问题中,我们可以直接使用 Elasticsearch 原生的 synonyms 功能来完成。虽说原生 synonyms 功能不支持热更新,而且需要将词典事先放进制定目录,不过好在这类等义词数量并不多,变化也并不大,尚且属于一劳永逸的任务。
对于不可直接替换的近义词问题,如果直接套用原生的 Synonyms 虽然可能会带来更多召回,但是查准率却骤降。
对于这类问题,我们期待的场景是,一旦发现用户 query 中的某个词有近义词,我们就将它拆分替换,成为多个 query 进行联合搜索。就像前面的例子:用户搜索“损坏公物如何处罚”的时候,查询结果可以由90%的“损坏公物如何处罚”和10%的“毁坏公物如何处罚”查询结果合并后返回。如此说来,使用 Elasticsearch 提供的 boosting_query 就成为了一个自然而然的想法。
不过稍加思考也不难发现,boosting_query 中 weight 的获得并不容易,也就是前面例子中的90%和10%这组数字应该怎么设定,这也是近义词联合搜索中的重点。
先回到我们刚才的例子:当用户搜索“损坏公物如何处罚”的时候,我们本能地觉得用90%的损坏和10%的毁坏合并在一起是“合理的”,这样的本能其实是来自于:我们主观地认为在检索“搞坏公物”这个事实的时候,90%的用户会使用毁坏来描述,10%的用户会使用损坏来描述。
简而言之,这组数字可以理解为用户群体描述同一个问题时,对词组选择的组成比例。再换个说法,也就是在当前这条 query 中,原词和近义词之间的可替换程度。
再举一例,在“广东话入门”这条 query 中,从“表达学习语言”的语义上来看,广东话和粤语差别并不大,这条 query 自然可以拆分成“广东话入门”和“粤语入门”,进行联合搜索,而且它们的 weight 甚至可以设置为 1:1 来获得更多合理的召回。
反过来,在“粤语歌曲推荐”这条 query 中,广东话的 weight 就需要慎重考虑,一方面是因为本身就没有“广东话歌曲”这种说法,另一方面也因为在广泛的语料中,歌曲和广东话这两个词极少同时被提及。所以几遍是“粤语歌曲推荐”的拆分成分中有“广东话歌曲推荐”,weight 也需要被设置地非常低(倘若真的没有“粤语歌曲”相关的内容,推荐“广东话”的内容作为替补)。
说到这里,其实已经很明白了,语言模型是可以在这里被使用的,而语言模型的困惑度也与前面提到的 weight 一脉相承。
所以大致计算流程可以是:获得用户的query之后进行分词,在词组中寻找所有可能的同义词替换,将所有替换后的 query 分别放进语言模型中获得困惑度(或其他 metrics),依据它们来作为 boosting query 中的 weight。
graph TD;
广东话入门-->'广东话','入门';
'广东话','入门'-->_'广东话','入门'_;
'广东话','入门'-->_'粤语','入门'_;
_'广东话','入门'_-->语言模型;
_'粤语','入门'_-->语言模型;
语言模型-->PPL:0.65;
语言模型-->PPL:0.35;
对于这里语言模型的选择,可以使用传统的ngram,也可以使用双向的LSTM这样一些成熟的方案从语料中训练,也可以使用一些现成的方案:http://ai.baidu.com/tech/nlp/dnnlm_cn
如何动态刷新同义词词典?
Elasticsearch • spxu2016 回复了问题 • 4 人关注 • 2 个回复 • 6360 次浏览 • 2017-08-18 11:15
elasticsearch-analysis-dynamic-synonym 远程请求报错
Elasticsearch • hailin0 回复了问题 • 1 人关注 • 2 个回复 • 6762 次浏览 • 2017-03-19 14:30
同义词的重复问题
Elasticsearch • medcl 回复了问题 • 2 人关注 • 1 个回复 • 4470 次浏览 • 2016-10-21 23:15
ES 6.3.0 同义词配置后 查询结果异常
回复Elasticsearch • akingseu 发起了问题 • 1 人关注 • 0 个回复 • 1520 次浏览 • 2021-04-07 14:34
加入同义词全文检索查询以后,性能明显下降,请问怎么回事呢?
回复Elasticsearch • liubin 回复了问题 • 6 人关注 • 3 个回复 • 2639 次浏览 • 2019-01-22 11:44
es配置同义词时,只对分词后最小粒度的词有效,对于组合词,加在ik的扩展词表里起不了作用怎么办?
回复Elasticsearch • rochy 回复了问题 • 3 人关注 • 1 个回复 • 4400 次浏览 • 2018-11-22 21:34
elasticsearch-analysis-dynamic-synonym 远程请求报错
回复Elasticsearch • hailin0 回复了问题 • 1 人关注 • 2 个回复 • 6762 次浏览 • 2017-03-19 14:30
关于同义词检索方案的一点实践经验
Elasticsearch • Jinyang Zhou 发表了文章 • 0 个评论 • 8147 次浏览 • 2018-06-15 13:36
最近一直在搞同义词搜索的问题,踩了一些坑,总结了一些经验,尤其是刚刚接触搜索和 ES,所以如果有不对的,或者不完备的地方也希望大家能提出改进意见。。。
下面是自己留下的文档记录:
需求
同义词检索也是搜索引擎必备的功能之一,例如,我们希望用户在搜索广东话的同时,也能找出和粤语有关的信息;用户在搜索苹果手机的同时,包含iPhone的内容也能被检索并呈现。
在现实生活中,相同语义的表述词汇往往有很多,而用户在检索的时候很难在一条 query 中将它们全部体现,所以识别和提供同义词检索显然可以获得更高的召回率。
需求剖析
在思考解决方案之前,我们不妨再来看看刚才提到的两个例子:
- 苹果手机与iPhone
- 广东话与粤语
我们先来看第一个,苹果手机和iPhone。
显然,这两个词是等价的,因为苹果公司发布的所有手机产品都叫 iPhone,而 iPhone 这个名字也没有被其他公司使用过。
于是,当用户搜索“苹果手机购买”的时候,我们也就有理由将它拆分成“苹果手机购买”和“iPhone购买”,分别进行检索,再将结果合并返回。
语言学中对这样的词组,称为是同义词中的相对同义词,或是等义词,等义同义词。它们表达意思完全一致,在绝大多数语境中都可以相互替换,同时对上下文也不会产生影响。
这样的词组还有很多,例如:猫熊和熊猫,柚子和文旦等等,这些等义词大抵来说有这样几种来源:
- 音节减缩形成:机枪和机关枪,坦克和坦克车,电扇和电风扇
- 音译和音译形成:出租车和的士 ,维生素和维他命
- 地域叫法不同,或新旧叫法:单车,自行车和脚踏车,西红柿和番茄,马铃薯,洋芋和土豆,黄瓜和胡瓜
- 昵称代称:周杰伦和周董
- 描述角度不同,学名方言差异:电脑和计算机,曲别针和回形针
这些词组多以名词呈现,数量比较少,词组规模也较小,同时变化也很小。
接下来我们再来看第二组词:广东话和粤语。
广东话和粤语这两个词代表的意思是相同的吗?它们也是可以相互替换的吗?
答案显然是否定的。
广东话从语义本身来说是一个比较粗糙的概念,它不仅指广东省内的粤语,还涵盖了潮汕话,客家话,雷州话等其他方言。而粤语却是一个非常严肃的概念,对语音语调都有非常详细的规定,不仅通用于广东省大部分地区,还包括广西、香港、澳门等地,甚至东南亚和北美。它们联系在于,大部分广东地区的人说的是粤语。
如此说来,给广东话和粤语这样非常相似却又并不完全一致的词直接划上等号是有失偏颇的。当然,其实仔细考虑也不难发现,和广东话有相似之处却又不完全相同的词还有很多,例如:客家话、广州话、广府话等等。
语言学中把这样的词汇,称作是相对同义词,或是近义词。它们在意义上有一些相似之处,只能在特定的语境中进行替换。
它们的差别可能包括:
- 语义上:毁坏和损坏(前者更严重),介绍和说明(前者可以对人施加作用)
- 色彩上:团结和勾结
对于这类相似却又不完全相同的近义词,在搜索的时候提供关联搜索是一个不错的方案。例如用户搜索“毁坏公物如何处罚”的时候,查询结果可以由90%的“损坏公物如何处罚”和10%的“毁坏公物如何处罚”查询结果合并后返回,从而获得更多的召回。
这些近义词以动词为主,不仅数量多,词组的规模也大,例如靠近的近义词可以是:靠拢,逼近,接近,迫近等等。
解决思路
在可替换的等义词问题中,我们可以直接使用 Elasticsearch 原生的 synonyms 功能来完成。虽说原生 synonyms 功能不支持热更新,而且需要将词典事先放进制定目录,不过好在这类等义词数量并不多,变化也并不大,尚且属于一劳永逸的任务。
对于不可直接替换的近义词问题,如果直接套用原生的 Synonyms 虽然可能会带来更多召回,但是查准率却骤降。
对于这类问题,我们期待的场景是,一旦发现用户 query 中的某个词有近义词,我们就将它拆分替换,成为多个 query 进行联合搜索。就像前面的例子:用户搜索“损坏公物如何处罚”的时候,查询结果可以由90%的“损坏公物如何处罚”和10%的“毁坏公物如何处罚”查询结果合并后返回。如此说来,使用 Elasticsearch 提供的 boosting_query 就成为了一个自然而然的想法。
不过稍加思考也不难发现,boosting_query 中 weight 的获得并不容易,也就是前面例子中的90%和10%这组数字应该怎么设定,这也是近义词联合搜索中的重点。
先回到我们刚才的例子:当用户搜索“损坏公物如何处罚”的时候,我们本能地觉得用90%的损坏和10%的毁坏合并在一起是“合理的”,这样的本能其实是来自于:我们主观地认为在检索“搞坏公物”这个事实的时候,90%的用户会使用毁坏来描述,10%的用户会使用损坏来描述。
简而言之,这组数字可以理解为用户群体描述同一个问题时,对词组选择的组成比例。再换个说法,也就是在当前这条 query 中,原词和近义词之间的可替换程度。
再举一例,在“广东话入门”这条 query 中,从“表达学习语言”的语义上来看,广东话和粤语差别并不大,这条 query 自然可以拆分成“广东话入门”和“粤语入门”,进行联合搜索,而且它们的 weight 甚至可以设置为 1:1 来获得更多合理的召回。
反过来,在“粤语歌曲推荐”这条 query 中,广东话的 weight 就需要慎重考虑,一方面是因为本身就没有“广东话歌曲”这种说法,另一方面也因为在广泛的语料中,歌曲和广东话这两个词极少同时被提及。所以几遍是“粤语歌曲推荐”的拆分成分中有“广东话歌曲推荐”,weight 也需要被设置地非常低(倘若真的没有“粤语歌曲”相关的内容,推荐“广东话”的内容作为替补)。
说到这里,其实已经很明白了,语言模型是可以在这里被使用的,而语言模型的困惑度也与前面提到的 weight 一脉相承。
所以大致计算流程可以是:获得用户的query之后进行分词,在词组中寻找所有可能的同义词替换,将所有替换后的 query 分别放进语言模型中获得困惑度(或其他 metrics),依据它们来作为 boosting query 中的 weight。
graph TD;
广东话入门-->'广东话','入门';
'广东话','入门'-->_'广东话','入门'_;
'广东话','入门'-->_'粤语','入门'_;
_'广东话','入门'_-->语言模型;
_'粤语','入门'_-->语言模型;
语言模型-->PPL:0.65;
语言模型-->PPL:0.35;
对于这里语言模型的选择,可以使用传统的ngram,也可以使用双向的LSTM这样一些成熟的方案从语料中训练,也可以使用一些现成的方案:http://ai.baidu.com/tech/nlp/dnnlm_cn