文档评分

全文评分函数

在搜索时,文档会根据其与查询的相关性进行评分。评分是一个介于0.0和1.0之间的浮点数,其中1.0是最高分。评分作为搜索结果的一部分返回,并可用于对结果进行排序。

Redis Stack 提供了一些非常基础的评分函数来评估文档的相关性。它们都基于文档分数和词频。这与使用可排序字段的能力无关。评分函数通过在搜索查询中添加SCORER {scorer_name}参数来指定。

如果您更喜欢自定义评分函数,可以使用扩展API添加更多函数。

以下是Redis Stack中预捆绑的评分函数列表及其工作原理的简要说明。每个函数都通过注册名称提及,该名称可以作为FT.SEARCH中的SCORER参数传递。

TFIDF(默认)

基本的 TF-IDF 评分 带有一些额外功能:

  1. 对于每个结果中的每个术语,计算该术语对该文档的TF-IDF分数。频率根据预先确定的字段权重进行加权,并且每个术语的频率通过每个文档中的最高术语频率进行归一化。

  2. 查询词的总TF-IDF乘以通过FT.CREATESCORE_FIELD上给出的预设文档分数。

  3. 根据搜索词之间的“间隔”或累积距离,为每个结果分配一个惩罚。完全匹配将不会受到惩罚,但搜索词相距较远的匹配将显著降低其分数。对于每个连续词的双字母组合,确定它们之间的最小距离。惩罚是距离平方和的平方根;例如,1/sqrt(d(t2-t1)^2 + d(t3-t2)^2 + ...)

给定文档D中的N个术语,T1...Tn,可以使用以下Python函数描述结果分数:

def get_score(terms, doc):
    # the sum of tf-idf
    score = 0

    # the distance penalty for all terms
    dist_penalty = 0

    for i, term in enumerate(terms):
        # tf normalized by maximum frequency
        tf = doc.freq(term) / doc.max_freq

        # idf is global for the index, and not calculated each time in real life
        idf = log2(1 + total_docs / docs_with_term(term))

        score += tf*idf

        # sum up the distance penalty
        if i > 0:
            dist_penalty += min_distance(term, terms[i-1])**2

    # multiply the score by the document score
    score *= doc.score

    # divide the score by the root of the cumulative distance
    if len(terms) > 1:
        score /= sqrt(dist_penalty)

    return score

TFIDF.DOCNORM

与默认的TFIDF评分器相同,但有一个重要的区别:

词频通过文档的长度进行归一化,表示为总词数。长度是加权的,因此如果一个文档包含两个词,一个在权重为1的字段中,另一个在权重为5的字段中,总频率是6,而不是2。

FT.SEARCH myIndex "foo" SCORER TFIDF.DOCNORM

BM25

基本TFIDF评分器的一个变体,详情请参阅此维基百科文章

每个文档的相关性分数乘以推定文档分数,并根据slop应用惩罚,如TFIDF中所示。

FT.SEARCH myIndex "foo" SCORER BM25

DISMAX

一个简单的评分器,它汇总了匹配项的频率。在联合子句的情况下,它将给出这些匹配项的最大值。不应用其他惩罚或因素。

它不是Solr的DISMAX算法的一对一实现,但在大体上遵循了它。

FT.SEARCH myIndex "foo" SCORER DISMAX

文档评分

一个评分函数,它只是返回文档的假定分数,而不对其应用任何计算。由于文档分数可以更新,如果您想使用外部分数而不进行进一步操作,这可能很有用。

FT.SEARCH myIndex "foo" SCORER DOCSCORE

汉明

通过文档的有效载荷和查询有效载荷之间的逆汉明距离进行评分。由于对最近邻感兴趣,因此使用逆汉明距离(1/(1+d)),以便距离为0时给出完美的分数1,并且是最高排名。

这仅在以下情况下有效:

  1. 文档包含有效载荷。
  2. 查询具有有效负载。
  3. 两者的长度完全相同。

负载是二进制安全的,并且负载长度为64位的倍数时,结果会稍微快一些。

示例:

> HSET key:1 foo hello payload aaaabbbb
(integer) 2

> HSET key:2 foo bar payload aaaacccc 
(integer) 2

> FT.CREATE idx ON HASH PREFIX 1 key: PAYLOAD_FIELD payload SCHEMA foo TEXT
"OK"

> FT.SEARCH idx "*" PAYLOAD "aaaabbbc" SCORER HAMMING WITHSCORES
1) "2"
2) "key:1"
3) "0.5"
4) 1) "foo"
   2) "hello"
5) "key:2"
6) "0.25"
7) 1) "foo"
   2) "bar"
RATE THIS PAGE
Back to top ↑