-
TF-IDF (Term Frequency-Inverse Document Frequency)란
TF-IDF는 TF와 idf의 곱입니다.
2015년 한 조사에 따르면 전자도서관들이 텍스트 기반 추천시스템을 구축할 때 가장 많이쓰는 것이 이 tf-idf라고 하며, 그 비율은 83%에 이른다고 합니다.
검색엔진에서 관련성 순위를 매길때 자주 이용되며, 문서 요약 등에서도 자주 쓰인다고 합니다. 관련성 순위를 계산할 때 쓸수있는 가장 단순한 방법은 각 문서마다 이용자가 입력한 단어들의 tf-idf 값을 계산한 뒤 큰 순서대로 우선순위로 표시하는 것입니다.
TF (Term Frenquency)
1개의 문서 안에서 특정 단어의 등장 빈도를 의미
문장을 단어로 나누고 전체 단어수가 얼마나 사용됐는지를 파악해 문서의 종류를 분류하는 지표로 사용
- 1글자의 경우 생략하는 경우가 많음
영어로 된 문서들 중에서 유저가 입력한 검색어 "an apple"과 가장 관련성이 높은 순서대로 순위를 매긴다고 가정합니다. 우선 가장먼저 "an"과 "apple"을 포함하지 않는 문서를 제외하고 각 문서에서 "an"과 "apple"이 각각 몇번씩 등장하는지 빈도를 계산합니다. 이 빈도값이 TF(Term Frequency)가 됩니다. 이 때 길이가 긴 문서일수록 단어가 많고 "an"과 "apple" 또한 더 자주 등장할 것이라 예상할 수 있으므로 빈도를 정규화할 필요가 생깁니다. 단어 가중치(term weighting)는 “한 문서에서 단어의 가중치는 단어 빈도수에 비례한다.” 라고 요약할 수 있습니다.
DF (Dcument Frequency)
특정 단어가 나타나는 문서의 갯수를 의미
특정 단어가 각 문서들에 몇 번 등장하는지는 신경쓰지 않고 특정 단어가 문서에 등장했는지 안했는지만 관심을 가짐
- 100개의 문서중 2개의 문서만 '반도체' 라는 단어가 등장하면, 그 문서안의 '반도체'가 100번, 200번 등장했는지는 관심없고 오로지 'DF(반도체') == 2를 의미함
IDF (Inverse Document Frequency)
특정 단어 모든 문서에 등장하는 흔한 단어라면 이를 방지하기 위해 역수를 취한 값
영어의 언어 특성상 "an apple"에서 "an"과 "apple"의 빈도를 계산하면 "an"이 압도적으로 많을 것으로 예상할 수 있으며 단순히 TF를 기준으로 순위를 계산한다면 "an"이 가장 많은 문서가 상위에 랭크될 가능성이 높습니다. 그러나 "an"은 문서를 구분하는데에 있어서 무의미한 키워드이며 사용자가 원하는 것은 "apple"과 관련된 문서일 것입니다. 이때 IDF(Inverse Document Frequency)를 도입하는데 이 값은 코퍼스(문서 집합) 전체에서 특정 단어가 자주 언급될수록 작아지고 적게 언급될수록 커집니다. “an apple”의 경우에서 보면 “an”은 코퍼스의 거의 모든 문서들에 한 번 씩은 포함될 것이므로 “an”의 IDF값은 작아지고 반대로 “apple”은 코퍼스 내의 몇몇 문서들에서만 언급될 것이므로 이 값이 커지게 됩니다. IDF는 "단어의 특이성은 단어가 등장하는 문서의 수에 대한 반비례 함수로 정량화될 수 있다." 라고 요약할 수 있습니다.
사용 예제
import numpy as np import pandas as pd from sklearn.feature_extraction.text import CountVectorizer documents = [ "`중국판 우버` 수난시대 전기차 자회사 파산 신청", "'중국판 우버' 디디추싱, 전기차 자회사 파산 신청", "'코스피 매력없네' 외국인 비중 30% 금융 위기후 최저", "[증시 풍향계] 상승세 지속할까…FOMC 의사록 주목", "코스피, 2600선 갈까 FOMC 회의록에 쏠리는 눈 [주간전망]", "[뉴욕증시-주간전망] 소매판매· FOMC 의사록 주시" ] # 단어 출연 빈도를 벡터화하여 표현 vectorizer = CountVectorizer() # Document Term Matrix dtm = vectorizer.fit_transform(documents) # Term Freqeuncy tf = pd.DataFrame(dtm.toarray(), columns=vectorizer.get_feature_names_out()) print(tf) # Document Frequency df = tf.astype(bool).sum(axis=0) print(df) # 문서 개수 D = len(tf) # Inverse Document Frequency idf = np.log((D + 1) / (df + 1)) + 1 print(idf) # TF-IDF tfidf = tf * idf tfidf = tfidf / np.linalg.norm(tfidf, axis=1, keepdims=True) print(tfidf)
레퍼런스