본문 바로가기
Computer Science

Elastic Search 톺아보기 #2

by Bloofer 2023. 3. 14.

 

Precision vs Recall

Precision과 Recall은 정적분석에서도 사용되지만 데이터 분석에서도 자주 나타나는 중요한 개념이다. 이 둘은 머신러닝 모델의 성능을 평가하거나, 검색 엔진의 검색 결과를 평가하는 등 다양한 분야에서 사용된다.

 

Precision은 모델이 예측한 결과 중 실제로 정답인 것의 비율이다. 즉, 모델이 Positive로 예측한 것 중에서 실제로 Positive인 것의 비율을 나타낸다.

Precision = TP / (TP + FP)

 

여기서 TP(True Positive)는 모델이 Positive로 예측하고 실제로 Positive인 것의 수를, FP(False Positive)는 모델이 Positive로 예측했지만 실제로 Negative인 것의 수를 나타낸다.

 

 

Recall은 실제 정답 중 모델이 정답을 맞춘 비율이다. 즉, 실제로 Positive인 것 중에서 모델이 Positive로 예측한 것의 비율을 나타낸다.

Recall = TP / (TP + FN)

 

여기서 FN(False Negative)은 모델이 Negative로 예측했지만 실제로 Positive인 것의 수를 나타낸다.

 

Precision과 Recall은 서로 반비례적인 관계를 가진다. Precision은 높으면 높을수록 모델이 Positive로 예측한 것 중에서 실제로 Positive인 비율이 높다는 것을 의미한다. 반면 Recall은 높으면 높을수록 모델이 실제 Positive 중에서 Positive로 예측한 비율이 높다는 것을 의미한다. Elasticsearch에서는 이러한 Trade-off를 개발자가 미세조정할 수 있도록 지원한다.

 

 


TF-IDF

Term Frequency(TF)는 특정 단어가 문서 내에서 얼마나 자주 등장하는지를 나타내는 값이다. 즉, 단어가 문서에서 출현하는 빈도수를 나타낸다. 단어의 빈도수가 높을수록 해당 단어가 문서에서 중요하다는 것을 의미한다.

 

Inverse Document Frequency(IDF)는 특정 단어가 얼마나 유용한지를 나타내는 값이다. IDF 값은 전체 문서 수를 해당 단어가 포함된 문서의 수로 나눈 뒤, 로그 값을 취한 값이다. IDF 값이 높을수록 해당 단어가 문서를 구분하는데 중요한 역할을 한다는 것을 의미한다.

 

여기서 눈치챘을 지 모르겠지만, TF 스코어와 IDF 스코어는 서로 상반되는 개념이다. TF는 단어의 빈도수에 가중치를 주지만 IDF는 단어의 희소성에 가중치를 준다. 이러한 TF-IDF 값은 단어의 TF 값과 IDF 값의 곱으로 계산된다. 즉, 특정 단어가 자주 등장하지만 모든 문서에서 등장한다면 IDF 값이 낮아져서 TF-IDF 값이 낮아진다. 반면, 특정 단어가 드물게 등장하지만 특정 문서에서만 등장한다면 IDF 값이 높아져서 TF-IDF 값이 높아진다.

 

TF-IDF 값은 문서 간의 단어들의 중요도를 비교할 때 사용된다. 예를 들어, 검색 엔진에서 검색어와 문서 간의 유사도를 계산할 때, 각 단어의 TF-IDF 값을 계산하여 문서 간의 유사도를 측정한다.

 

 


 

앞서 Precision과 Recall, 그리고 TF-IDF의 개념에 대해 장황하게 소개한 것은 검색엔진에서의 스코어에 이러한 개념들이 접목되기 때문이다.

 

(Elastic에서의) 스코어란 무엇인가?

 

어쨌거나 하고 싶은 것은 이러한 검색 쿼리에 대해서 TF-IDF 스코어를 적용하여 가장 연관된 높은 점수의 문서부터 가장 연관이 적은 낮은 점수의 문서 순으로 보여주고 싶은 것이다.

 

그렇다면, Elastic Query에서 문서의 스코어는 어떻게 적용될까?

 

 


Elasticsearch로 Precision과 Recall 미세조정하기

예제에서 준비된 데이터셋은 허핑턴포스트의 2010년부터 2018년도 사이의 Kaggle 데이터 형태의 뉴스 데이터셋이다. 각 데이터는 뉴스의 헤드라인, 날짜, 작성자 등의 정보를 포함한다.

 

이제, 이 데이터셋에서 우리가 원하는 문서를 Elasticsearch로 검색하는 시나리오를 상상해보자.

 

GET news_headlines/_search
{
  "query": {
    "match": {
      "headline": {
        "query": "Khloe Kardashian Kendall Jenner"
      }
    }
  }
}

 

“Khloe Kardashian Kendall Jenner”이라는 키워드를 포함한 헤드라인을 검색하는 쿼리가 있다.

 

 

 

By default, 엘라스틱 Match Query는 각각의 단어들에 대해 OR 연산을 적용하기 때문에 하나의 키워드라도 포함한 문서들, 즉 926개의 문서를 검색 결과로 반환한다.

 

 

Precision 올리기

GET news_headlines/_search
{
  "query": {
    "match": {
      "headline": {
        "query": "Khloe Kardashian Kendall Jenner",
        "operator": "and"
      }
    }
  }
}

 

여기에 쿼리 연산자를 AND로 지정함으로써 검색결과가 우리가 정말 원하는 문서들을 최대한 포함한, 즉 Precision이 높은 결과로 튜닝해볼 수 있다.

 

 

 

그 결과, 정확히 “Khloe Kardashian Kendall Jenner” 키워드를 포함한 문서는 단 하나뿐이기 때문에 검색결과는 1개만 반환된다.

 

아마, 검색 조건이 너무 Strict한 것이었을 수도 있다. 여기서 좀 더 튜닝해서 Precision과 Recall 사이의 밸런스를 조절해보자.

 

 

minimum_should_match

GET news_headlines/_search
{
  "query": {
    "match": {
      "headline": {
        "query": "Khloe Kardashian Kendall Jenner",
        "minimum_should_match": 3
      }
    }
  }
}

 

minimum_should_match는 말그대로 쿼리의 키워드중 최소 매치수를 지정하는 옵션이다.

minimum_should_match를 쿼리 길이 n에 가깝게 맞출수록 Precision은 올라가지만 Recall이 떨어질 것이고 minimum_should_match를 1에 가깝게 맞출수록 Recall은 올라가지만 Precision이 떨어질 것이다.

 

 

minimum_should_match를 3으로 준 검색 결과는 꽤 연관있지만 좀 더 많은 검색결과인 6개의 문서를 볼 수 있다.

 

 

  • 이 Precision과 Recall의 Trade-off를 잘 맞추어 미세조정하는 것은 데이터 분석 후 개발자가 해야 할 일이다.