评分文档

全文评分函数

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

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

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

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

TFIDF(默认)

基本的TF-IDF 评分,并具有一些额外的功能。

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

  2. 查询词语的总 TF-IDF 乘以通过 SCORE_FIELDFT.CREATE 上给出的推定文档得分。

  3. 根据搜索词语之间的“slop”或累积距离,对每个结果分配一个惩罚。精确匹配将不会受到惩罚,但搜索词语距离较远的匹配将显著降低其分数。对于每个连续词语的二元组,确定它们之间的最小距离。惩罚是距离平方和的平方根;例如,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 评分器的变体,请参阅维基百科文章以了解更多信息

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

FT.SEARCH myIndex "foo" SCORER BM25

DISMAX

一个简单的评分器,它将匹配词语的频率加起来。在联合子句的情况下,它将给出这些匹配的最大值。没有应用其他惩罚或因素。

它不是Solr 的 DISMAX 算法的逐一实现,但它在广义上遵循该算法。

FT.SEARCH myIndex "foo" SCORER DISMAX

DOCSCORE

一个评分函数,它只返回文档的推定得分,而不对其应用任何计算。由于文档得分可以更新,因此如果您想使用外部得分而不做任何其他操作,这将非常有用。

FT.SEARCH myIndex "foo" SCORER DOCSCORE

HAMMING

通过文档有效负载与查询有效负载之间的反向汉明距离进行评分。由于最邻近的邻居是最重要的,因此使用反向汉明距离(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 ↑