TF-IDF

애늙은이·2023년 9월 11일
0

NLP 여행기

목록 보기
13/13
post-thumbnail
post-custom-banner

지난 시간에 배운 BoW(Bag of Words), 그리고 BoW를 기반으로 하는 DTM(Document Term Matrix)의 경우, 단순 빈도수를 기반으로 하기 때문에 불용어와 같은 단어들이 있으면 유의미한 결과를 얻지 못할 수도 있다고 배웠습니다.
때문에 각 단어의 중요도를 가중치로 한 TF-IDF가 등장하게 되었습니다.

🤔 TF-IDF란?

TF-IDF는 문서 간의 유사도나 문서 전체 내에서 단어의 중요도를 구하는데 쓰입니다. TF-IDF는 TF값과 IDF값을 곱한 것으로 각각은 다음과 같습니다.

TF(Term Frequency)

특정 문서에서의 특정 단어의 등장 횟수를 의미합니다. 우리가 DTM에서 구했던 등장 빈도와 같습니다. 특정 문서 d에서 특정 단어 t의 TF는 다음과 같이 표현할 수 있습니다.

tf(d,t)tf(d, t)

IDF(Inverse Document Frequency)

IDF를 이해하기 위해선 우선 DF(Document Frequency)부터 이해할 필요가 있습니다. DF는 특정 단어가 등장한 문서의 빈도를 말합니다. IDF는 DF의 역수값으로, 적은 문서에 등장할수록 불용어가 아닌 유의미한 단어일 확률이 높아지기에 역수값을 구합니다. DF를 df(t)df(t), NN을 전체 문서 수라고 할 때, 문서IDF를 구하는 식은 다음과 같습니다.

idf(d,t)=log(N1+df(t))idf(d, t) = log(\frac N {1 + df(t)})

식을 보면 DF의 역수값에 해당하지만 IDF값이 너무 커지는 것을 막기 위해 로그를 사용하고, 분모로 온 df(t)df(t)가 0인 경우를 고려하여 1을 더한 형태가 되었습니다.

TF-IDF는 TF×IDFTF \times IDF로 TF-IDF값이 높으면 특정 문서에서의 빈도수는 높은데, 전체 문서에서 등장하는 경우는 적은 것이니 특정 문서에서 중요한 의미를 갖는 단어일 가능성이 높아집니다.

💻 TF-IDF의 구현

TF-IDF는 scikit-learn 라이브러리의 TfidVectorizer() 클래스를 통해 구현할 수 있습니다.

from sklearn.feature_extraction.text import TfidfVectorizer


docs = ["what is love", "all you need is love", "you can't forget love and pride", "the ones you love mean more than anything"]

vect = TfidfVectorizer()
vect.fit(docs) # 데이터를 학습시킵니다.

print(f"BoW: \n{vect.vocabulary_}")
print(f"TF-IDF: \n{vect.transform(docs).toarray()}") 

# 결과

# BoW: 
#{'what': 14, 'is': 5, 'love': 6, 'all': 0, 'you': 15, 'need': 9, 'can': 3, 'forget': 4, 'and': 1, 'pride': 11, 'the': 13, 'ones': 10, 'mean': 7, 'more': 8, 'than': 12, 'anything': 2}

# TF-IDF:
# [[0.         0.         0.         0.         0.         0.5728925
#  0.37919167 0.         0.         0.         0.         0.
#  0.         0.         0.72664149 0.        ]
# [0.55037169 0.         0.         0.         0.         0.43391936
#  0.28720678 0.         0.         0.55037169 0.         0.
#  0.         0.         0.         0.35129512]
# [0.         0.46226355 0.         0.46226355 0.46226355 0.
#  0.2412283  0.         0.         0.         0.         0.46226355
#  0.         0.         0.         0.29505684]
# [0.         0.         0.38691947 0.         0.         0.
#  0.20191063 0.38691947 0.38691947 0.         0.38691947 0.
#  0.38691947 0.38691947 0.         0.24696568]]

fit_transform()을 통해 학습과 TF-IDF 계산을 한 번에 진행할 수 있습니다.

print(vect.fit_transform(docs).toarray())

🔍 TF-IDF의 장단점

🟢 장점

이전의 DTM 방식보다 발전된 형태로, IDF를 통해서 문서 내에서 토픽이 되는 단어를 알 수 있습니다.

🔴 단점

DTM과 마찬가지로 단어 가방의 크기가 커지면 표현해야 할 벡터가 늘어나 공간적으로 비효율적입니다.

profile
글쓰는 개발자입니다.
post-custom-banner

0개의 댓글