[前回] Elasticsearchで見る検索エンジンの仕組み(4): サンプルデータでクエリ編
はじめに
前回は、Elasticsearch付属のサンプルデータでクエリを実行しました。
今回は、検索結果におけるランキングを理解します。
スコアリング(ランク付け)とは
- ユーザーにとって重要と思われる文書を上位に表示するようにソート
- 独自のランク付けルールを適用し
重要度
と呼んでいる - 使用される手法
- 文書中の検索単語出現頻度
- 検索単語が、各文書内でどのくらいの頻度で出現しているかを表す割合
- TF-IDF
- TF(term frequency)は、ある文書における単語の出現頻度
- IDF(inverse document frequency)は、単語の文書間でのレア度(希少価値)を表す
- どの文書にもある単語はレア度(重要度)が低い
- BM25(Okapi BM25)
- tf-idfを改良した手法で、クエリとの関連性に応じて、文書を順位付け
- Elasticsearchで使用
- tf-idfを改良した手法で、クエリとの関連性に応じて、文書を順位付け
- ページランク
-
重要度の高いページからリンクされているページは重要である
という原理に基づいたランク付け
-
- HTMLタグの解析
-
<title>
タグや<H1>
タグを重視するランキング - ※ 引用元: https://ja.wikipedia.org/wiki/%E5%85%A8%E6%96%87%E6%A4%9C%E7%B4%A2
-
- 文書中の検索単語出現頻度
スコアリングを検証
KibanaのDev Toolsで、score-testインデックスへドキュメント登録
POST /score-test/_bulk
{"index": {"_id": 1}}
{"message": "Apache Lucene Solr Blog"}
{"index": {"_id": 2}}
{"message": "Elasticsearch Tech"}
{"index": {"_id": 3}}
{"message": "Apache Lucene Tech Elasticsearch Tech Blog"}
{"index": {"_id": 4}}
{"message": "Lucene Tech Elasticsearch Tech Solr Tech"}
{"index": {"_id": 5}}
{"message": "Lucene Elasticsearch Blog"}
登録されたドキュメントを確認
- クエリ
GET /score-test/_search
- 結果
- 5件ヒット
スコアを確認
-
Elasticsearch Tech
で、インデックスscore-testを検索
GET /score-test/_search
{
"query": {
"match": {
"message": "Elasticsearch Tech"
}
}
}
- 検索結果
- 検索条件と類似した4件がヒット
- ドキュメント
_id: 2
のElasticsearch Tech
が、最もスコアが高く、検索条件に類似(完全一致) - その他ドキュメントのランク付けの根拠は?
... ...
"hits": {
"total": {
"value": 4,
"relation": "eq"
},
"max_score": 1.0521364,
"hits": [
{
"_index": "score-test",
"_id": "2",
"_score": 1.0521364,
"_source": {
"message": "Elasticsearch Tech"
}
},
{
"_index": "score-test",
"_id": "4",
"_score": 1.0205201,
"_source": {
"message": "Lucene Tech Elasticsearch Tech Solr Tech"
}
},
{
"_index": "score-test",
"_id": "3",
"_score": 0.9061662,
"_source": {
"message": "Apache Lucene Tech Elasticsearch Tech Blog"
}
},
{
"_index": "score-test",
"_id": "5",
"_score": 0.32575765,
"_source": {
"message": "Lucene Elasticsearch Blog"
}
}
]
... ...
スコア計算ロジックを確認
-
explain=true
パラメータを付けて検索
GET /score-test/_search?explain=true
{
"query": {
"match": {
"message": "Elasticsearch Tech"
}
}
}
- スコア計算の過程が詳細に表示される
- boost、idf、tfなどの値でスコアが計算されている
... ...
"_explanation": {
"value": 1.0521364,
"description": "sum of:",
"details": [
{
"value": 0.36614084,
"description": "weight(message:elasticsearch in 1) [PerFieldSimilarity], result of:",
"details": [
{
"value": 0.36614084,
"description": "score(freq=1.0), computed as boost * idf * tf from:",
"details": [
{
"value": 2.2,
"description": "boost",
"details": []
},
{
"value": 0.2876821,
"description": "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
"details": [
{
"value": 4,
"description": "n, number of documents containing term",
"details": []
},
{
"value": 5,
"description": "N, total number of documents with field",
"details": []
}
]
},
{
"value": 0.57851243,
"description": "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
"details": [
{
"value": 1,
"description": "freq, occurrences of term within document",
"details": []
},
{
"value": 1.2,
"description": "k1, term saturation parameter",
"details": []
},
{
"value": 0.75,
"description": "b, length normalization parameter",
"details": []
},
{
"value": 2,
"description": "dl, length of field",
"details": []
},
{
"value": 4.2,
"description": "avgdl, average length of field",
"details": []
}
]
}
]
}
]
},
... ...
おわりに
全文検索のスコアリングを理解しました。
次回も続きます。お楽しみに。