在 Elasticsearch 中,默认情况下,文档是按照相关性得分倒序排列的,其对应的相关性得分字段用 _score 来表示,它是浮点数类型,_score 评分越高,相关性越高。评分模型的选择可以通过 similarity
参数在映射中指定。
相似度算法种类
es 提供了很多种现成的相似度算法,具体如下:
- BM25
- DFR
- DFI
- IB
- LM Dirichlet
- LM Jelinek Mercer
- Scripted(自定义脚本计算相似度)
BM25(默认)
Elasticsearch 在 5.4 版本之后,针对文本类型的字段,默认采用的是 BM25 评分模型,而不是基于 tf-idf 的向量空间模型,它其实也是基于 tf-idf 模型进行优化出来的模型,主要增加了可以控制词频结果在词频饱和度中的上升速度的参数 k1 和 字段平均文档长度相关的控制字段长度归一值的参数 b;BM25 适合短文本的字段。
可设置的参数具体如下:
k1
:控制非线性词频的归一标准化,默认为1.2
。b
:基于 tf 值针对文档长度进行归一标准化的控制参数,默认为0.75
。discount_overlaps
:确定在计算归一标准化时,是否忽略重叠的 token(位置增量为 0 的 token)。默认情况下为true
,这意味着重叠 token 在计算归一标准化时,不计算在内。
开发者可以指定设置相关的参数来定制自己的 BM25 实现,具体如下:
{
"settings": {
"index": {
"similarity": {
"my_bm25_similarity": {
"type": "BM25",
"k1": 1.0
"b": 0.8,
"discount_overlaps": false
}
}
},
...
...
},
...
}
BM25 对应的 type 名称为 BM25
。
DFR
DFR(Divergence From Randomness)是一种基于同名概率模型的相似度模型,又叫随机性偏差模型,它是信息检索的最早模型之一。
DFR 模型由通过实例化框架的三个组成部分组成:
- 选择基本随机性模型(Selecting A Basic Randomness Model);
- 第一次的正常化(First Normalization);
- 规范化词的频率(Term Frequency Normalization)。
关于 DFR 算法的详细文档可以参考英文 wiki:https://en.wikipedia.org/wiki/Divergence-from-randomness_model
DFR 可配置的参数选项如下:
basic_model
:指定基础随机模型,可选项值有g
、if
、in
和ine
。after_effect
:可选项的值有b
和l
。normalization
:指定规范化,可选项的值有no
、h1
、h2
、h3
和z
。
除了第一个选项外,其余所有选项都需要标准化值。
DFR 对应的 type 名称为 DFR
。
可配置的示例如下:
PUT {index}
{
"settings": {
"index": {
"similarity": {
"my_dfr_similarity": {
"type": "DFR",
"basic_model": "g",
"after_effect": "l",
"normalization": "h2",
"normalization.h2.c": "3.0"
}
}
}
}
}
DFI
DFI(Divergence From Independence)是也和 BM25、DFR 一样都属于概率模型,是一种基于差异的独立性模型的实现。
它的可配置项如下:
independence_measure
:可选的值有standardized
、saturated
和chisquared
。
使用这种相似度算法时,强烈建议不要删除停用词以取得良好的相关性。此外,需要注意的是,频率低于预期频率的字词的得分将等于 0。
DFI 对应的 type 名称为 DFI
。
IB
IB(Information Based model)是一种基于信息的模型,该算法基于以下概念:任何符号分发序列中的信息内容主要取决于其基本元素的重复使用。对于文本而言,这一挑战将对应于比较不同作者的写作风格。
它的可配置项如下:
distribution
:可选项的值,ll
和spl
。lambda
:可选项的值,df
和ttf
。normalization
:等同于 DFR 算法的配置项值,可选项的值有no
、h1
、h2
、h3
和z
。
IB 对应的 type 名称为 IB
。
LM Dirichlet
LM Dirichlet 这种相似度可选项如下:
mu
:默认是 2000。
这种计分公式为出现次数少于语言模型预测的次数的词汇分配了负分数,这对 Lucene 是非法的,因此此类词汇的分数为 0。
LM Dirichlet 对应的 type 名称为 LMDirichlet
。
LM Jelinek Mercer
LM Jelinek Mercer 算法尝试捕获文本中的重要模式,同时保留噪声。
这种相似性具有以下选项:
lambda
:最佳值取决于文档合集和查询 query。针对标题字段的查询最优值在 0.1 左右,对长字段的查询最佳值在 0.7 左右。默认为0.1
。当值接近为 0 时,匹配更多查询词的文档将比匹配较少词的文档排名更高。
LM Jelinek Mercer 对应的 type 名称为 LMJelinekMercer
。
Scripted
有一种相似度计算,开发者可以使用脚本来指定应如何计算分数。
例如,以下示例显示了如何重新实现 TF-IDF:
PUT {index}
{
"settings": {
"number_of_shards": 1,
"similarity": {
"scripted_tfidf": {
"type": "scripted",
"script": {
"source": "double tf = Math.sqrt(doc.freq); double idf = Math.log((field.docCount+1.0)/(term.docFreq+1.0)) + 1.0; double norm = 1/Math.sqrt(doc.length); return query.boost * tf * idf * norm;"
}
}
}
},
"mappings": {
"properties": {
"field": {
"type": "text",
"similarity": "scripted_tfidf"
}
}
}
}
尽管自定义脚本相似度提供了很大的灵活性,但它们必须满足下列规则:
- 返回的分数必须为正。
- 当其它变量保持不变时,当
doc.freq
增加时,分数不能减少。 - 当其它变量保持不变时,当
doc.length
增加时,分数不能增加。
Scripted 对应的 type 名称为 scripted
。