2.X/1. Getting Started

1-08-3. What Is Relevance?

drscg 2017. 9. 30. 18:10

We’ve mentioned that, by default, results are returned in descending order of relevance. But what is relevance? How is it calculated?

기본적으로 결과는 relevance를 기준으로, 내림차순으로 반환된다고 언급한 바 있다. 그런데, relevance가 무엇이고, 어떻게 계산되는가?

The relevance score of each document is represented by a positive floating-point number called the _score. The higher the _score, the more relevant the document.

각 document의 relevance score는 _score 라고 하는, 양(+)의 부동 소수점 정수로 표현된다. _score 가 높을수록, 더 관련 있는 document이다.

A query clause generates a _score for each document. How that score is calculated depends on the type of query clause. Different query clauses are used for different purposes: a fuzzy query might determine the _score by calculating how similar the spelling of the found word is to the original search term; a terms query would incorporate the percentage of terms that were found. However, what we usually mean by relevance is the algorithm that we use to calculate how similar the contents of a full-text field are to a full-text query string.

query 절은 각 document에 대해, _score 를 만들어낸다. score를 계산하는 방법은, query절의 유형에 달려 있다. 각각의 다른 query절은 각기 다른 용도로 사용된다. fuzzy query는 찾아낸 단어의 철자가, 원래의 검색어에 얼마나 유사한 가를 계산해, _score 를 결정하고, terms query는 찾아낸 단어의 비율을 포함한다. 그러나, 일반적으로, relevance 는 full-text field의 내용이 full-text query string에 얼마나 유사한가를 계산하는 알고리즘을 의미한다.

The standard similarity algorithm used in Elasticsearch is known as term frequency/inverse document frequency, or TF/IDF, which takes the following factors into account:

Elasticsearch에 사용되는 표준 유사성 알고리즘(similarity algorithm) 은 Terms Frequency(TF), Inverse Document Frequency(IDF)이다. 이는 아래 요소를 고려한다.

Term frequency

How often does the term appear in the field? The more often, the more relevant. A field containing five mentions of the same term is more likely to be relevant than a field containing just one mention.

field에 나타나는 단어의 횟수. 많이 나타날수록 관련성이 높다. 특정 field에 동일한 단어가 5회 언급되었다면, 단 1회 언급된 field보다 관련성이 더 높을 것이다.

Inverse document frequency

How often does each term appear in the index? The more often, the less relevant. Terms that appear in many documents have a lower weight than more-uncommon terms.

각 단어가 index에 나타난 횟수. 많이 나타날수록 관련성이 낮다. 많은 document에 나타난 단어는, 더 드물게 나타나는 단어보다 낮은 비중(weight) 을 가진다.

Field-length norm

How long is the field? The longer it is, the less likely it is that words in the field will be relevant. A term appearing in a short title field carries more weight than the same term appearing in a long content field.

field의 길이. 길수록, field에 있는 단어는 관련성이 낮을 것이다. 짧은 title field에 나타난 어떤 단어는, 긴 content field에 나타난 동일한 단어보다 높은 비중을 가진다.

Individual queries may combine the TF/IDF score with other factors such as the term proximity in phrase queries, or term similarity in fuzzy queries.

개별 query는 phrase query의 단어 근접성(proximity)이나 fuzzy query의 단어 유사성(similarity) 같은 다른 요소들과 함께, TF/IDF score를 조합한다.

Relevance is not just about full-text search, though. It can equally be applied to yes/no clauses, where the more clauses that match, the higher the _score.

relevance는 full-text 검색에서만 사용되는 것이 아니다. yes/no 절에도 똑같이 적용될 수 있다. 일치하는 절이 더 많을수록, 더 높은 _score 를 가진다.

When multiple query clauses are combined using a compound query like the bool query, the _scorefrom each of these query clauses is combined to calculate the overall _score for the document.

다중 query 절이 bool query 같은 복합 query를 사용하여 조합될 경우, 각 query 절에서 나온 _score 는 document 전체 _score 를 계산하기 위해, 조합된다.

Tip

We have a whole chapter dedicated to relevance calculations and how to bend them to your will: Controlling Relevance.

relevance 계산과 relevance를 조정하는 방법은 Controlling Relevance를 참고하자.

Understanding the Scoreedit

When debugging a complex query, it can be difficult to understand exactly how a _score has been calculated. Elasticsearch has the option of producing an explanation with every search result, by setting the explain parameter to true.

복잡한 query를 debug하는 경우, _score 가 계산되는 방법을 정확히 이해하기는 어려울 수 있다. Elasticsearch는 모든 검색 결과에 설명(explanation) 을 추가할 수 있는 옵션을 가지고 있다. explain 매개변수를 true 로 설정하면 된다.

GET /_search?explain 
{
   "query"   : { "match" : { "tweet" : "honeymoon" }}
}

explain 매개변수는 모든 검색 결과에, _score 가 계산되는 방법에 대한 설명을 추가한다.

Note

Adding explain produces a lot of output for every hit, which can look overwhelming, but it is worth taking the time to understand what it all means. Don’t worry if it doesn’t all make sense now; you can refer to this section when you need it. We’ll work through the output for one hit bit by bit.

explain 을 추가하면, 모든 hit에 굉장히 많은 출력이 나온다. 하지만, 그것이 무엇을 의미하는지 이해하기 위해, 시간을 투자할 가치가 있다. 바로 이해하지 못 할 수도 있지만, 걱정할 필요가 없다. 필요할 때 참조할 수 있다. 하나의 hit 에 하나씩 출력을 만들어 낸다.

First, we have the metadata that is returned on normal search requests:

먼저, 일반적인 검색 request로 반환된 metadata를 볼 수 있다.

{
    "_index" :      "us",
    "_type" :       "tweet",
    "_id" :         "12",
    "_score" :      0.076713204,
    "_source" :     { ... trimmed ... },

It adds information about the shard and the node that the document came from, which is useful to know because term and document frequencies are calculated per shard, rather than per index:

여기에 document가 존재하는 node와 shard에 대한 정보가 추가된다. 이는 단어와 document 빈도를 index별이 아닌, shard별로 계산하기 때문에, 알고 있는 것이 유용하다.

    "_shard" :      1,
    "_node" :       "mzIVYCsqSWCG_M_ZffSs9Q",

Then it provides the _explanation. Each entry contains a description that tells you what type of calculation is being performed, a value that gives you the result of the calculation, and the detailsof any subcalculations that were required:

그리고, _explanation 을 제공한다. 각 항목은 수행된 계산의 유형을 알려주는 description, 계산의 결과를 알려주는 value, 그리고 요구되는 하위 계산을 알려주는 details 를 포함하고 있다.

"_explanation": { 
   "description": "weight(tweet:honeymoon in 0)
                  [PerFieldSimilarity], result of:",
   "value":       0.076713204,
   "details": [
      {
         "description": "fieldWeight in 0, product of:",
         "value":       0.076713204,
         "details": [
            {  
               "description": "tf(freq=1.0), with freq of:",
               "value":       1,
               "details": [
                  {
                     "description": "termFreq=1.0",
                     "value":       1
                  }
               ]
            },
            { 
               "description": "idf(docFreq=1, maxDocs=1)",
               "value":       0.30685282
            },
            { 
               "description": "fieldNorm(doc=0)",
               "value":        0.25,
            }
         ]
      }
   ]
}

honeymoon 을 위한 score 계산의 요약

Term frequency

Inverse document frequency

Field-length norm

Warning

Producing the explain output is expensive. It is a debugging tool only. Don’t leave it turned on in production.

explain 을 출력하면 비용이 많이 발생한다. 단지 debug를 위한 tool이다. 제품에 사용되도록, 남겨두지 않길 바란다.

The first part is the summary of the calculation. It tells us that it has calculated the weight—the TF/IDF—of the term honeymoon in the field tweet, for document 0. (This is an internal document ID and, for our purposes, can be ignored.)

첫 번째 부분은 계산의 요약이다. document 0 (이것은 임의로 만든 내부의 document id 로써, 무시해도 좋다)의 tweet field에서 단어 honeymoon 의 비중(TF/IDF)을 계산한 것을 나타낸다.

It then provides details of how the weight was calculated:

그 다음에, 비중이 계산되는 방법을 자세히 알려준다.

Term frequency

How many times did the term honeymoon appear in the tweet field in this document?

이 document의 tweet field에서 honeymoon 이라는 단어가 나타나는 횟수.

Inverse document frequency

How many times did the term honeymoon appear in the tweet field of all documents in the index?

index에 있는 모든 document의 tweet field에서 honeymoon 이라는 단어가 나타난 횟수.

Field-length norm

How long is the tweet field in this document? The longer the field, the smaller this number.

이 document의 tweet field의 길이, field가 길수록 이 숫자는 더 작다.

Explanations for more-complicated queries can appear to be very complex, but really they just contain more of the same calculations that appear in the preceding example. This information can be invaluable for debugging why search results appear in the order that they do.

더 복잡한 query에 대한 explanation은 매우 복잡해 보일 수 있으나, 위의 예제에서 보이는 것과 동일한 계산을 더 많이 포함하고 있을 뿐이다. 이 정보는 검색의 결과가 저런 순서로 나타나는 이유를 debug할 경우 유용하다.

Tip

The output from explain can be difficult to read in JSON, but it is easier when it is formatted as YAML. Just add format=yaml to the query string.

explain 의 출력은 JSON으로 읽기가 어려울 수 있다. YAML 형식으로는 읽기가 더 쉽다.format=yaml 을 query string에 추가하기만 하면 된다.

Understanding Why a Document Matchededit

While the explain option adds an explanation for every result, you can use the explain API to understand why one particular document matched or, more important, why it didn’t match.

explain 옵션이 모든 결과에 explanation을 추가하면, explain API는 특정 document가 일치하는 이유, 더 중요한, 일치하지 않는 이유를 이해하는데 이용할 수 있다.

The path for the request is /index/type/id/_explain, as in the following:

다음처럼, request의 path는 /index/path/id/_explain 이다.

GET /us/tweet/12/_explain
{
   "query" : {
      "bool" : {
         "filter" : { "term" :  { "user_id" : 2           }},
         "must" :  { "match" : { "tweet" :   "honeymoon" }}
      }
   }
}

Along with the full explanation that we saw previously, we also now have a description element, which tells us this:

위에서 보았던, 전체 explanation을 따라가 보면, description 을 볼 수 있다.

"failure to match filter: cache(user_id:[2 TO 2])"

In other words, our user_id filter clause is preventing the document from matching.

즉, user_id filter 절 때문에, document가 일치하지 않았다.


'2.X > 1. Getting Started' 카테고리의 다른 글

1-08-1. Sorting  (0) 2017.09.30
1-08-2. String Sorting and Multifields  (0) 2017.09.30
1-08-4. Doc Values Intro  (0) 2017.09.30
1-09. Distributed Search Execution  (0) 2017.09.30
1-09-1. Query Phase  (0) 2017.09.30