ElasticSearch之向量空间模型算法

来源:互联网 发布:网站源码免费分享 编辑:程序博客网 时间:2024/05/20 13:04

一 检索模型

1.1 bool模式

bool模式下,是最简单的检索模式,依据操作符AND 或者 OR 过滤document,结果只是包含指定的term的文档。他不会对document打分,只是为了减少后续要计算的document的数量,提升性能

 

1.2 TF/IDF

TF 是 term frequency的缩写,表示这个词条term在该文档出现的频率,往往能够表现文档的主体信息,即TF值越大,应该给于这个单词更大权值,具体计算词频因子的时候,基于不同的出发点,可以采纳不同的计算公式,最直接的方式就是直接利用词频数。假设某一个term出现过5次,那么这个term的TF值就是5,还有些变体计算公式:


第一个变体,为身取log是因为基于如下考虑:假设一个term出现了10次,也不该在计算权值时比出现1次的情况大10倍。加上1的目的是为进行平滑,比如TF就是1,那么计算对数,就是0,本来出现了一次的term,现在是不出现了。所以需要+1进行平滑。

第二个变体:a 是调节因子,0.4效果更好,TF表示实际的词频数,Max(TF)表示文档中所有单词出现次数最多的单词对应的词频数。

之所以这样做是因为:出于对长文档的限制,因为如果文档比较长,与短文档相比,则长文档中所有单词的TF值普遍比短文档高,但是这并不意味着长文档更合查询相关。

 

IDF是inverse document frequency的缩写,表示逆文档频率因子。我们知道同一个单词在不同的文档中TF值可能是不一样的。而逆文档频率因子IDF则不同,它代表着文档集合范围内的全局因子。给定一个文档集合,那么每一个单词的IDF值就唯一确定,跟具体文档无关


而我们一般是TF * IDF权值,如果计算出来的权值越大,那么打分可能会更高

 

1.3 向量空间模型(VSM)

VSM是Vector Space Model的缩写,把对文本内容的处理简化为对向量运算,并且以空间上的相似度表达语义的相似度。

 

每一个term或者n-gram片段都是一个维度。首先会在向量空间中构建N个维度的文档

举个例子:



ES会根据Flexible Plastic Frame在所有doc中的权值计算出一个query vector(1,1,1),然后N维空间我们放入查询向量,此时我们就可以计算各个doc的权值向量与查询向量之间的相似度


我们知道,cos值越大,表示相似度越高,我们可以看出,doc3的相关度是最高,其次是doc2,doc1最低

 

 

二 查询是如何为文档打分的

查询为每一个文档打分最主要的会使用一个公式来计算:


三 对相关度评分进行调节和优化的常见的3种方法

3.1 query的时候进行boost

POST /typeahead/guitar/_search

{

   "query":{

       "bool":{

           "should":{

               "match":{

                   "title":{

                       "query":"Plastic Sunglasses",

                        "boost":2

                   }

               }

            }

        }

    }

}

 

3.2 negative boost

我们有时候可能需要搜索包含Plastic,但是不包行Sunglasses的文档,但是这样有可能返回的文档数量太少,即召回率太少。那我们可以将包含Sunglassesde也返回,只是降低其分数而已

召回率低的做法:

POST /ecommerce/glasses/_search

{

   "query":{

       "bool": {

           "must":[

               {"match":{"record.desc":"Metal Alloy"}}

           ],

           "must_not": [

              {"match":{"record.desc":"Spring"}}

            ]

        }

    }

}

召回率较好的做法:

POST /ecommerce/glasses/_search

{

    "query":{

        "boosting":{

            "positive":{

                "match":{"record.desc":"Metal Alloy"}

            },

            "negative": {

                "match":{"record.desc":"Spark"}

            },

             "negative_boost": 0.2

         }

     }

}

 

3.3 constant_score

我们不需要进行相关度平分,所有的文档的分数都是1

POST /ecommerce/glasses/_search

{

   "query":{

      "constant_score": {

         "filter": {

           "term": {

              "record.desc": "Metal Alloy"

            }

          }

       }

    }

}

 

四 function_score自定义相关度分数算法

有时候我们想自己根据数据进行一些打分计算,比如商品的review数量,由review在一定程度上增强商品的打分记录。

这时候我们看就可以使用function_score来自定义打分。

POST /ecommerce/glasses/_search

{

   "query":{

       "function_score":{

           "query":{

               "multi_match": {

                  "query": "hadoop spark",

                  "fields": ["record.desc","record.content"]

               }

           },

           "field_value_factor":{

               "field":"record.review",

               "modifier":"log1p",

               "factor":0.5

           },

           "boost_mode": "sum",

           "max_boost": 2

        }

    }

}

 

POST /ecommerce/glasses/_search

{

   "query":{

       "function_score":{

           "query":{

              "match_all": {}

           },

           "boost":5,

           "functions":[

               {

                   "filter":{"match":{"record.color":"Red"}},

                   "weight":10

               },

               {

                   "filter":{"match":{"record.color":"Black"}},

                   "field_value_factor": {

                       "field":"record.review",

                        "modifier":"square",

                        "factor": 0.5

                    }

               }

           ],

           "boost_mode": "multiply",

           "max_boost":1000,

           "min_score":10

        }

    }

}

Function Score Query提供几种类型打分函数:

1 script_score

2 weight,相当于文档分数乘以这个权重

3 random_score: 随机打分

"random_score": {

   "seed" : number

}

默认使用_uid字段,进行hash

4 field_value_factor 允许你使用一文档字段去影响打分结果

 

function_score下的参数解释

# query 指定查询

# field_value_factor 允许你使用一文档字段去影响打分结果,如果指定了多个字段,只有第一个字段才会被计算。它的主要属性如下:

1 field: 指定哪个字段去影响评分

2 factor: 一个可选的配置,它会乘以字段值,默认是1

3 modifier: 指定字段值的函数,即这个字段值应用一个函数,有如下选项可供选择:假设该字段值是8

none: 不应用函数到字段值

log: 应用log函数到这个字段值,即log8

log1p: 应用log函数到这个字段值,即log(8+1),主要是为了防止有的值是1,这样计算出来就是0

log2p: 应用log函数到这个字段值,即log(8+2)     

ln: 使用自然对数函数,即ln8

ln1p: 自然对数函数加1,即ln(8+1)

ln2p:自然对数函数加2,即ln(8+2)

squre:平方

sqrt:开方

reciprocal: 即 1/field value,即这里1/8

4missing,如果没有这个字段,我们给它一个默认值

#boost_mode: 指定doc分数与指定字段的值如何计算

1 multiply:字段值乘以文档分数  

2replace : 字段值替换文档分数   

3 sum字段值加上文档分数 

4 avg:字段值和文档分数的平均值

5 min:min{字段值,文档分数}

6 max:max{字段值,文档分数}

# max_boost: 限制计算出来的分数不要超过max_boost指定的值

# min_score: 最小分数

# functions 可以分别定义计算规则