2018년 11월 6일 화요일

TF-IDF에 대하여


TF-IDF란

TF-IDF(Term Frequency - Inverse Document Frequency)는 Term의 가중치를 구하는 가장 흔한 알고리즘이다. ( Scoring, 참고: TF-IDF (Wikipedia) )

검색에 있어 거의 바이블(?)격인 알고리즘이기에, 반드시 알아둬야하는 개념이라 할 수 있다.

TFIDF는, 문서의 핵심어를 추출하거나, 검색 엔진에서 검색 결과의 순위를 결정하거나, 문서들 사이의 비슷한 정도를 구하는 등의 용도로 사용할 수 있다.
물론 ElasticSearch 5.0.0 GA 버전 이후 기본 scoring알고리즘이 TF-IDF에서 BM25로 변경되었으나, TF-IDF는 반드시 알아둬야할 개념임에는 분명하다.
그리고 "Term"이라는 것은 조각, 토큰과 유사한 의미로, 문헌분석의 경우에서는 단어 정도로 생각하면 좋을것이다.

Formula




공식이라고 하니 좀 복잡해보일 수 있다. 하지만 사실 간단한 의미이다. 위 공식을 쉽게 설명하자면,

"해당 단어(Term)이 문서에 몇번 노출되는가? 그리고 전체 데이터 중 해당 단어는 얼마나 흔한가?"

라는 의미이다.

결국 문헌상 많이 나타나는 단어가 있다면 그 단어는 매우 중요하며, 반대로 너무도 많이 나타나는 단어는 희소가치가 떨어져서 중요하지 않다는 의미이다.



Formula - Common

공식의 큰 뜻(?)을 이해했다면 이제 공식이 어떻게 동작하는지 보자.

TF라 함은 "Term Frequency" 즉, Term의 빈도이다. 위에 언급한 "문서에 몇번 노출되는가?"의 의미이다.

IDF에서 DF는 "Document Frequency" 즉, Term이 포함된 문서의 빈도이다. 이를 "Inverse" 즉, 역수를 취하는 것이다.

2은 2배를 의미하지만, ½은 반(Half)을 의미한다. 역수를 취한다는 의미는 결국 정 반대로 가중치를 책정한다는 의미이다.


예를들어보면,
  1. I love dogs. 
  2. I hate dogs and knitting. 
  3. Knitting is my hobby and my passion. 

아래는 위 내용을 각 문헌을 키워드 대비 빈도로 보기 좋게 정리한 표이다.

Ilovedogshateandknittingismyhobbypassion
D-1111






D-21
1111



D-3



111211
※ 키워드별 빈도

D1문서에서의 "dogs"를 기준으로 계산해보자.

"dogs"는 D1에서 1회 나타났다. 따라서 TF1이 된다.

그에 반해 "dogs"는 전체 3개 문서 중 2개의 문서에서 나타났다. 따라서 DF는 2/3이다. 
IDF는 역수이므로 3/2이 된다.
즉, 결과는 1 x (3/2) ≒ 1.5가 된다.


같은 방식으로 나머지를 모두 계산해보면,
Ilovedogshateandknittingismyhobbypassion
D-11.531.5






D-21.5
1.531.51.5



D-3



1.51.53633
※ TF * (N/DF)

이런 방식으로 각 문서상 Term들의 중요도를 분석할 수 있게된다.


예외처리에 대해

D-1문서에서 hate의 가중치를 보려한다고 생각해보자.
계산식은 TF * (N/log(DF))이므로 대입해보면 0 * (1 / 0) 이기에, 결국 0으로 나누려하는 error가 발생한다.
따라서 일반적으로는 DF(혹은 아래 설명할 로그스케일 빈도에서의 TF)가 0이 나오는것을 방지하기 위해 (+1)을 해준다.
※ TF * ( N/ log(DF+1) )


Formula - IDF & Logarithm

자, 그럼 공식에서 사용된 log는 무어냐?
사실 log는 없어도 되는 놈이다. 특히 위와 같이 단순한 표본분석에서는 log는 필요치 않을 수도 있다.
하지만 데이터가 커지면? 좀더 다양한 데이터를 대상으로 한다면? 그때 상황이 달라진다.

다들 log 그래프를 기억(?)하고 있겠지만;; ㅎㅎ

log는 밑수가 1보다 큰 경우 점점 증가하지만 정해진 한계값을 넘어서지 않게 수렴되는 것을 볼 수 있다.



결국 log를 사용한 이유는 "리미터"을 주기 위해서이다.

전체 문헌상에 정말로 많이 노출되는 Term이나 혹은 거의 노출되지 않는 Term은 그 가중치가 엄청나게 높거나 낮은 수치를 가지게 될 텐데, 방대한 문서를 위와같이 계산하다보면 어떤 가중치는 천정부지 치솟게 되고 나중에는 관리는 커녕 계산조차 어려워질 것이다.

따라서 log로서 이러한 편차를 줄이는 것이다.


위 결과표를 IDF에 log를 적용해 계산해보면 다음과 같다.

Ilovedogshateandknittingismyhobbypassion
D-10.180.480.18






D-20.18
0.180.480.180.18



D-3



0.180.180.480.950.480.48
※ TF * log(N/(DF+1))

결국 특정 구간 값을 가지게 된다. 이것이 바로 cosine normalization(코사인 평준화)의 가장 간단한 예이다.
코사인평준화에 대한 내용은 "cosine similarity", 그러니까 "문헌 유사도" 중 "코사인유사도"에서 다시 언급되게 된다.
여기까지 이해했다면 TF-IDF는 사실 다 이해한 것이나 마찬가지다. ^^


Formula - TF

하지만, 한가지 문제가 더 남았다. IDF뿐만이 아니고 TF가 무턱대고 커지는 경우이다.

문서상에 매우 악의적(?)으로 반복되는 Term이 존재할 수가 있다. 이 경우 언급한 IDF의 문제처럼 TF역시 문제가 된다.

따라서 이를 해결하기 위해 일반적으로 다음의 3가지 방법이 쓰인다.


  • 불린(Boolean)빈도 
    • 단어의 노출빈도를 카운팅 하지 않고, 그저 존재유무만을 따진다. 
    • 즉, 문헌상 Term이 있으면 1, 없으면 0을 적용하여 하나만 있든 1,000개가 있든 같은 상황으로 간주하는 방식이다. 
    • 위 표의 경우, my가 hobby나 passion과 다르지않은 값을 가지게 된다. 
  • 로그 스케일(Log Scale) 빈도 
    • 로그 스케일은 위에 설명과 동일하다. 즉 매우 커지는 TF값에 IDF처럼 리미터를 주는 것이다. (zero값을 피하기 위해 역시 +1을 해 준다.) 
    • tf(t,d) = log (f(t,d) +1); 
  • 증가빈도 
    • 문서 길이에 따라 단어의 상대적 빈도 값을 조정해주는 방법으로 이 방법을 쓰면 0과 1사이에 값으로 제한할 수 있다. 
    • 문서 내 단어들의 단어 빈도 중 최대 빈도로 단어빈도를 나눠주는 방법이다. 

참고

증가빈도에서의 0.5는 평준화를 위한 임의값이라 보면 좋다. 사실 다음과 같은 공식에서의 대표적인 K값일 뿐이다.








댓글 없음:

댓글 쓰기