溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

elasticsearch7.x中的IDF該怎么調(diào)試

發(fā)布時間:2021-09-14 11:57:33 來源:億速云 閱讀:190 作者:柒染 欄目:大數(shù)據(jù)

本篇文章給大家分享的是有關(guān)elasticsearch7.x中的IDF該怎么調(diào)試,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

簡介

TF-IDF 是elasticsearch中的默認打分機制(與Lucene一樣),解釋:

一個詞條出現(xiàn)在某個文檔中的次數(shù)越多,它就越相關(guān)。但是詞條出現(xiàn)在不同文檔中的次數(shù)越多,它就越不相關(guān)。

TF 詞頻,詞條在文檔中出現(xiàn)的次數(shù)

比如現(xiàn)在有這樣兩個文檔,搜索Elasticsearch時,文檔2應(yīng)該具有更高的得分,文檔1的詞頻是1,文檔2的詞頻是2

1、We will discuss Elasticsearch at the nex Big Data group

2、Tuesday the Elasticsearch team will gather to answer questions about Elasticsearch

IDF 逆文檔頻率,詞條在索引下所有文檔中出現(xiàn)的次數(shù)

比如現(xiàn)在有這樣三個文檔,the在每一個文檔中都存在,假如我們搜索the score時,如果沒有IDF的話,最先返回的文檔可能是不準(zhǔn)確的,IDF均衡了常見詞的相關(guān)性影響

1、We ues Elasticsearch to power the search for our website

2、The developers like Elasticsearch so far

3、The scoring of documents is calculated by the scoring formula

如何調(diào)試

當(dāng)查詢結(jié)果與我們預(yù)期出現(xiàn)不符時,可以使用"explain": true來調(diào)試

GET /full_text_test123/_search
{
  "query": {
    "match": {
      "content": "北京市"
    }
  },
  "explain": true
}

在知道文檔ID的情況下,如果想查詢某文檔為什么沒有被查詢出來可以使用_explain API

GET /full_text_test123/_explain/1
{
  "query": {
    "match": {
      "content": "云南省"
    }
  }
}

在查詢時設(shè)置評分

使用boost字段來設(shè)置評分系數(shù) ,當(dāng)使用 bool 或 and/or/not 等組合查詢時,boost查詢才更有意義

dsl中指定評分

bool 查詢指定"北京市"優(yōu)先級為10,云南省為1

GET /full_text_test123/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "content": {
              "query" : "北京市",
              "boost" : 10
            }
          }
        },
        {
          "match": {
            "content": {
              "query" : "云南省",
              "boost" : 1
            }
          }
        }
      ]
    }
  }
}

查詢的結(jié)果,可以看到北京市的幾個鎮(zhèn)排列在前

"hits" : [
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "1",
	"_score" : 7.315132,
	"_source" : {
	  "title" : "回龍觀鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)回龍觀鎮(zhèn)",
	  "geolocation" : "40.0764332591,116.3429765651",
	  "clicknum" : 102,
	  "date" : "2019-01-01"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "3",
	"_score" : 7.315132,
	"_source" : {
	  "title" : "小湯山鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)小湯山鎮(zhèn)",
	  "geolocation" : "40.1809900000,116.3915700000",
	  "clicknum" : 202,
	  "date" : "2019-03-03"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "2",
	"_score" : 7.156682,
	"_source" : {
	  "title" : "沙河鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)沙河鎮(zhèn)",
	  "geolocation" : "40.1481760748,116.2889957428",
	  "clicknum" : 92,
	  "date" : "2019-02-02"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "6",
	"_score" : 1.4350727,
	"_source" : {
	  "title" : "勐侖鎮(zhèn)",
	  "content" : "中華人民共和國云南省西雙版納自治州勐臘縣孟侖鎮(zhèn)",
	  "geolocation" : "21.9481406582,100.4479980469",
	  "clicknum" : 330,
	  "date" : "2019-10-05"
	}
  }
]

如果我們使用的是multi_match查詢,該如何指定評分系數(shù)呢,可以使用^符合,如下content字段評分系數(shù)是3,title是4,所以以title匹配的結(jié)果優(yōu)先content次之

GET /full_text_test123/_search
{
  "query": {
    "multi_match": {
      "query": "北京市",
      "fields": ["content^3","title^4"]
    }
  }
}

上面兩種是比較簡單的評分方法,讓我們看一看elasticsearch為用戶提供的更高一級的方式

function_score 設(shè)置評分

function_score 還提供了其他五種修改評分的方法分別是:

  1. filter,設(shè)置內(nèi)容符合過濾條件的文檔為指定評分

  2. field_value_factor,使用文檔中的參數(shù)作為系數(shù)來影響評分,如消息的評論數(shù)量越多評分越高

  3. script_score,使用腳本來計算評分系數(shù),可以使用doc['fieldname']訪問文檔中某字段的值,比如使用Math.log(doc['attendees'].values.size()) * myweight,其中myweight是查詢時params字段中指定的參數(shù)

  4. random_score,隨機分配一個數(shù)值,在某些場景下希望每次返回的數(shù)據(jù)都不一樣可以使用這個函數(shù)

  5. 衰減功能(linear線性曲線、gauss高斯曲線、exp指數(shù)曲線)

filter

搜索出北京市昌平區(qū)關(guān)鍵字的文檔,通過functions設(shè)置評分,根據(jù)需求設(shè)置優(yōu)先級

這里的weight和上面示例中的boost的區(qū)別是,普通boost是按照標(biāo)準(zhǔn)化來增加分數(shù),而weight是乘以一個常數(shù)

GET full_text_test123/_search
{
  "query": {
    "function_score": {
      "query": {"match": {
        "content": "北京市昌平區(qū)"
      }},
      "functions": [
        {
          "weight": 2,
          "filter": {"match":{"content":"沙河鎮(zhèn)"}}
        },
        {
          "weight": 3,
          "filter": {"match":{"content":"回龍觀鎮(zhèn)"}}
        }
      ],
      "score_mode": "max",
      "boost_mode": "replace"
    }
  }
}

結(jié)果

"hits" : [
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "1",
	"_score" : 3.0,
	"_source" : {
	  "title" : "回龍觀鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)回龍觀鎮(zhèn)",
	  "geolocation" : "40.0764332591,116.3429765651",
	  "clicknum" : 102,
	  "date" : "2019-01-01"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "2",
	"_score" : 3.0,
	"_source" : {
	  "title" : "沙河鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)沙河鎮(zhèn)",
	  "geolocation" : "40.1481760748,116.2889957428",
	  "clicknum" : 92,
	  "date" : "2019-02-02"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "3",
	"_score" : 1.0,
	"_source" : {
	  "title" : "小湯山鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)小湯山鎮(zhèn)",
	  "geolocation" : "40.1809900000,116.3915700000",
	  "clicknum" : 202,
	  "date" : "2019-03-03"
	}
  }
]

score_mode,從每個單獨的函數(shù)而來的得分是如何合并的,分別有如下幾種設(shè)置

  1. multiply,默認值

  2. sum

  3. avg

  4. first

  5. max

  6. min

boost_mode,從函數(shù)得到的得分如何同原始得分合并,原始得分指的是示例中的content:"北京市昌平區(qū)"的查詢,分別有如下幾種設(shè)置

  1. sum,評分_score與函數(shù)值間的和

  2. max,評分_score與函數(shù)值間的較大值

  3. min,評分_score與函數(shù)值間的較小值

  4. replace,將函數(shù)得分替換為原始得分

field_value_factor

field_value_factor,使用文檔中的參數(shù)作為系數(shù)來影響評分

  1. field:指定是文檔中的哪個字段名稱參與計算

  2. factor:點擊次數(shù)要乘以的評分倍數(shù)

  3. modifier:評分的計算方式,默認為none,共分為以下幾種(log、log1p、log2p、ln、ln1p、ln2p、square、sqrt、reciprocal)

點擊率越高優(yōu)先級越高

GET full_text_test123/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "content": "北京市"
        }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "clicknum",
            "factor": 2.2,
            "modifier": "log1p"
          }
        }
      ],
      "score_mode": "max",
      "boost_mode": "replace"
    }
  }
}

結(jié)果

[
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "3",
	"_score" : 2.6487503,
	"_source" : {
	  "title" : "小湯山鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)小湯山鎮(zhèn)",
	  "geolocation" : "40.1809900000,116.3915700000",
	  "clicknum" : 202,
	  "date" : "2019-03-03"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "1",
	"_score" : 2.352954,
	"_source" : {
	  "title" : "回龍觀鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)回龍觀鎮(zhèn)",
	  "geolocation" : "40.0764332591,116.3429765651",
	  "clicknum" : 102,
	  "date" : "2019-01-01"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "2",
	"_score" : 2.308351,
	"_source" : {
	  "title" : "沙河鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)沙河鎮(zhèn)",
	  "geolocation" : "40.1481760748,116.2889957428",
	  "clicknum" : 92,
	  "date" : "2019-02-02"
	}
  }
]

script_score

使用腳本來計算評分系數(shù),可以使用doc['fieldname']訪問文檔中某字段的值,比如使用Math.log(doc['attendees'].values.size()) * myweight,其中myweight是查詢時params字段中指定的參數(shù)

source:腳本函數(shù)(在7.x版本和舊版有細微的差別,在source中指定腳本)

params:我們自定義的對象

GET full_text_test123/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "content": "北京市"
        }
      },
      "functions": [
        {
          "script_score": {
            "script": {
              "source": "doc['clicknum'].value * params.myweight",
              "params": {
                "myweight":3
              }
            }
          }
        }
      ],
      "score_mode": "max",
      "boost_mode": "replace"
    }
  }
}

結(jié)果

[
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "3",
	"_score" : 606.0,
	"_source" : {
	  "title" : "小湯山鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)小湯山鎮(zhèn)",
	  "geolocation" : "40.1809900000,116.3915700000",
	  "clicknum" : 202,
	  "date" : "2019-03-03"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "1",
	"_score" : 306.0,
	"_source" : {
	  "title" : "回龍觀鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)回龍觀鎮(zhèn)",
	  "geolocation" : "40.0764332591,116.3429765651",
	  "clicknum" : 102,
	  "date" : "2019-01-01"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "2",
	"_score" : 276.0,
	"_source" : {
	  "title" : "沙河鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)沙河鎮(zhèn)",
	  "geolocation" : "40.1481760748,116.2889957428",
	  "clicknum" : 92,
	  "date" : "2019-02-02"
	}
  }
]

random_score

隨機分配一個數(shù)值,在某些場景下希望每次返回的數(shù)據(jù)都不一樣可以使用這個函數(shù)

seed:隨機數(shù)的種子,如果兩次查詢seed相同,那么結(jié)果頁相同

官網(wǎng)對seed和field字段的解釋

Random

The random_score generates scores that are uniformly distributed from 0 up to but not including 1. By default, it uses the internal Lucene doc ids as a source of randomness, which is very efficient but unfortunately not reproducible since documents might be renumbered by merges.

In case you want scores to be reproducible, it is possible to provide a seed and field. The final score will then be computed based on this seed, the minimum value of field for the considered document and a salt that is computed based on the index name and shard id so that documents that have the same value but are stored in different indexes get different scores. Note that documents that are within the same shard and have the same value for field will however get the same score, so it is usually desirable to use a field that has unique values for all documents. A good default choice might be to use the _seq_no field, whose only drawback is that scores will change if the document is updated since update operations also update the value of the _seq_no field.

翻譯如下(使用軟件翻譯的湊合看吧) 

可以在不設(shè)置字段的情況下設(shè)置種子,但不建議這樣做,因為這需要在_id字段上加載fielddata,這會消耗大量內(nèi)存。

默認情況下,它使用內(nèi)部lucene doc id作為隨機性的來源,這是非常有效的,但不幸的是不可復(fù)制,因為文檔可能被合并重新編號。
如果您希望分數(shù)是可復(fù)制的,可以提供種子和字段。最后的得分將基于這個種子、所考慮文檔的字段最小值和基于索引名和shard id計算的salt,這樣具有相同值但存儲在不同索引中的文檔將得到不同的得分。

請注意,在同一個shard中并且字段值相同的文檔將得到相同的分數(shù),因此通常需要對所有文檔使用具有唯一值的字段一個好的默認選擇可能是使用_seq_no字段,其唯一的缺點是,如果文檔被更新,分數(shù)將改變,因為更新操作也會更新seq no字段的值

GET full_text_test123/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "content": "北京市"
        }
      },
      "functions": [
        {
          "random_score": {
            "seed": 314159265359, 
            "field": "_seq_no"
          }
        }
      ],
      "score_mode": "max",
      "boost_mode": "replace"
    }
  }
}

衰減功能

衰減函數(shù)根據(jù)文檔的數(shù)值字段值與用戶給定的原點之間的距離衰減函數(shù),為文檔打分,類似于范圍的查詢。

衰減功能提供三種曲線(linear線性曲線、gauss高斯曲線、exp指數(shù)曲線),這三種類型的衰減類型可以有4個配置參數(shù)

  1. origin,曲線的中心點或字段可能的最佳值,落在原點origin上的文檔評分_score為滿分,是用戶希望的最高峰值最高分,假如在計算 “小明” 距離 “圖書館” 位置距離的例子中表示 “小明” 當(dāng)前的位置,或在某日期到今天的例子中表示今天

  2. offset,以原點origin為中心點,為其設(shè)置一個非零的偏移量offset覆蓋一個范圍(origin+/-offset這個范圍),而不只是單個原點,在范圍內(nèi)內(nèi)的所有評分_score都是滿分,默認是0

  3. scale:衰減率,即一個文檔從原點origin下落時,評分_score改變的速度。

  4. decay:當(dāng)字段吧值衰減到scale指定的值時,衰減到decay

elasticsearch7.x中的IDF該怎么調(diào)試

圖中所有曲線的原點origin(即中心點)的值都是40 ,office是5 ,也就是在范圍40 - 5 <= value <= 40+5內(nèi)的所有值都會被當(dāng)作原點origin處理——所有這些點的評分都是滿分。

在此范圍之外,評分開始衰減,衰減率由scale值(此例中的值為5)和 衰減值 decay(此例中為默認值0.5 )共同決定。結(jié)果是所有三個曲線在origin +/- (offset + scale)處的評分都是0.5,即點30和50處。

linear 、 exp 和 gauss (線性、指數(shù)和高斯)函數(shù)三者之間的區(qū)別在于范圍( origin +/- (offset + scale) )之外的曲線形狀:

  1. linear 線性函數(shù)是條直線,一旦直線與橫軸 0 相交,所有其他值的評分都是 0.0 。

  2. exp 指數(shù)函數(shù)是先劇烈衰減然后變緩。

  3. gauss 高斯函數(shù)是鐘形的——它的衰減速率是先緩慢,然后變快,最后又放緩。

選擇曲線的依據(jù)完全由期望評分 _score 的衰減速率來決定,即距原點 origin 的值。

使用經(jīng)緯度"47.7226969027,128.6911010742"(黑龍江省伊春市)進行查詢

GET full_text_test123/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "content": "中華人民共和國"
        }
      },
      "functions": [
        {
          "gauss": {
            "geolocation": {
              "origin": "47.7226969027,128.6911010742",
              "offset": "1km", 
              "scale": "3000km",
              "decay": 0.25
            }
          }
        }
      ],
      "score_mode": "max",
      "boost_mode": "replace"
    }
  }
}

結(jié)果

[
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "5",
	"_score" : 0.07333869,
	"_source" : {
	  "title" : "翠烏鎮(zhèn)",
	  "content" : "中華人民共和國黑龍江省伊春市燕翠烏鎮(zhèn)",
	  "geolocation" : "47.7226969027,128.6911010742",
	  "clicknum" : 50,
	  "date" : "2019-06-05"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "3",
	"_score" : 0.06053602,
	"_source" : {
	  "title" : "小湯山鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)小湯山鎮(zhèn)",
	  "geolocation" : "40.1809900000,116.3915700000",
	  "clicknum" : 202,
	  "date" : "2019-03-03"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "1",
	"_score" : 0.060268145,
	"_source" : {
	  "title" : "回龍觀鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)回龍觀鎮(zhèn)",
	  "geolocation" : "40.0764332591,116.3429765651",
	  "clicknum" : 102,
	  "date" : "2019-01-01"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "2",
	"_score" : 0.05901804,
	"_source" : {
	  "title" : "沙河鎮(zhèn)",
	  "content" : "中華人民共和國北京市昌平區(qū)沙河鎮(zhèn)",
	  "geolocation" : "40.1481760748,116.2889957428",
	  "clicknum" : 92,
	  "date" : "2019-02-02"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "4",
	"_score" : 0.054671418,
	"_source" : {
	  "title" : "燕郊鎮(zhèn)",
	  "content" : "中華人民共和國河北省廊坊市三河市燕郊鎮(zhèn)",
	  "geolocation" : "39.9601300000,116.8147600000",
	  "clicknum" : 100,
	  "date" : "2019-04-05"
	}
  },
  {
	"_index" : "full_text_test123",
	"_type" : "_doc",
	"_id" : "6",
	"_score" : 0.0073663373,
	"_source" : {
	  "title" : "勐侖鎮(zhèn)",
	  "content" : "中華人民共和國云南省西雙版納自治州勐臘縣孟侖鎮(zhèn)",
	  "geolocation" : "21.9481406582,100.4479980469",
	  "clicknum" : 330,
	  "date" : "2019-10-05"
	}
  }
]

以上就是elasticsearch7.x中的IDF該怎么調(diào)試,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降摹OM隳芡ㄟ^這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI