[자연어 처리] 정보 검색 / TF-IDF

2024. 4. 16. 22:31AI/자연어 처리

1) TF-IDF란

Term Frequency - Inverse Document Frequency 의 약자로 하나의 문서에서 키워드를 추출하는 방법이다. 키워드를 추출하면 문서의 전체 내용을 단어들로 요약할 수 있다.

2) 왜 필요해?

자연어를 처리하기 위해선 컴퓨터가 이해할 수 있도록 숫자로의 변환과정이 필요하다. 비교적 유연한 문장의 구조를 그대로 변환하는 것보단, 문장에 포함된 단어들을 기준으로 하는 것이 훨씬 유리할 것이다. 문장에는 불용어(the, a, in, on 등) 같은 필요하지 않는 내용들도 모두 포함하고 있기 때문이다. 따라서, 키워드를 추출해야 그 문장을 잘 설명할 수 있는 숫자로 변환할 수 있다.

3) 어떻게 키워드를 추출해?

TF : 해당 문서의 특정 단어의 빈도
DF : 그 단어를 포함하는 문서의 빈도
IDF : DF의 역수

 

IDF는 DF를 역수로 만들어 문서에 흔히 존재하는 단어일수록 가중치를 줄이기 위함이다.

 

" 오늘 날씨는 해가 뜬다. "  
" 내일 날씨는 비가 온다. "

 

두 가지 문장을 예시로 설명해보자. 각 문장에서 단어만 추출하면 아래와 같다.

 

[ '오늘', '날씨', '해' ]  
[ '내일', '날씨', '비' ]

 

첫 문장에서 '오늘'의 TF는 1, IDF 는 DF의 역수인 2 가 될 것이다. '오늘'의 TF-IDF는 2 라는 값을 얻을 수 있다.

'날씨'의 TF는 1 이다. 두 개의 문장 모두 '날씨'를 포함하기 때문에, DF는 2/2 이다. 즉, IDF는 1이 된다. '날씨'의 TF-IDF는 1 이 된다.

 

#  '단어':TF-IDF
[ '오늘':2, '날씨':1, '해':2 ]
[ '내일':2, '날씨':1, '비':2 ]

 

이처럼, TF-IDF 방식으로 각 단어 중요성을 계산하여 키워드를 분류해낼 수 있다.

 

4) 실습 예제

from sklearn.feature_extraction.text import TfidfVectorizer

sentence = ("오늘 날씨는 해가 뜬다.",
             "내일 날씨는 비가 온다.")
             
vector = TfidfVectorizer(max_features=100)
tfidf_vector= vector.fit_transform(sentence)

 

TfidfVectorizer 라이브러리를 활용하여 각 문장을 벡터화 한다. 여기서 벡터화란 문장을 수치화 시키는 과정을 말한다. 하나의 문장을 벡터화 하면 각 단어의 TF-IDF값이 저장된다. 

 

print(vector.vocabulary_)
-
{'오늘': 4, '날씨는': 0, '해가': 6, '뜬다': 2, '내일': 1, '비가': 3, '온다': 5}

 

각 단어는 숫자로 mapping 된다. 

 

  print(tfidf_vector)
  -
  (0, 2)	0.534046329052269
  (0, 6)	0.534046329052269
  (0, 0)	0.37997836159100784
  (0, 4)	0.534046329052269
  (1, 5)	0.534046329052269
  (1, 3)	0.534046329052269
  (1, 1)	0.534046329052269
  (1, 0)	0.37997836159100784

 

(문서 번호, 단어 번호) TF-IDF 값이 출력된다. 이를 이용하여 두 문장의 유사도를 계산할 수 있다.

 

print(cosine_similarity(tfidf_vector[0], tfidf_vector[0]))
print(cosine_similarity(tfidf_vector[0], tfidf_vector[1]))
-
[[1.]]
[[0.14438356]]

 

cosine 유사도를 기반으로 계산한다. 유사도에 대해선 다음 포스팅에서 정리하고 지금은 의미만 확인해보자.

첫 번째 경우는 같은 문장을 비교했을 때이며 1이라는 결과가 나왔다. 두 번째 경우는 '날씨는' 이라는 단어가 일치하여 유사도가 0.144 가 나온 것을 확인할 수 있다. 즉, 두 문장은 14% 의 유사도를 가지고 있다!