Recent Posts
Recent Comments
Archives
반응형
250x250
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Today
Yesterday

Total
05-02 06:06
관리 메뉴

Hey Tech

[NLP] TF-IDF 개념 및 계산 방법(+Python 코드) 본문

AI & 빅데이터/자연어처리(NLP)

[NLP] TF-IDF 개념 및 계산 방법(+Python 코드)

Tony Park 2022. 3. 25. 00:35
728x90
반응형

본 포스팅에서는 TF-IDF 개념 및 계산 방법에 대해 알아봅니다.


📚 목차

1. TF-IDF 개념
2. TF-IDF 계산방법
     2.1. TF(Term Frequency)
     2.2. DF(Document Frequency)
     2.3. IDF(Inverse Document Frequency)

1. TF-IDF 개념

TF-IDF(Term Frequency-Inverse Document Frequency)는 Document Term Matrix(DTM) 내 단어마다 중요도를 고려하여 가중치를 주는 통계적인 단어 표현방법입니다. DTM에 대한 자세한 설명은 이곳을 참고해 주세요.

그림 1. 단어 표현방법 분류

TF-IDF는 단어의 중요도를 고려하기 때문에, 일반적으로 단순히 문서 내 단어의 출현빈도만 고려하는 DTM보다 문서에서 유의미한 정보를 얻어내는 데 더욱 효과적입니다. 예를 들어, TF-IDF는 문서 간 유사도 검사, 중요 문서 위주의 검색 결과 제공 시스템, 문서 빅데이터 내 핵심어 추출 등에 활용되고 있습니다.

2. TF-IDF 계산방법

TF-IDF 가중치 계산 방법은 다음과 같습니다. DTM 생성 후, TF-IDF 이름처럼 단어 출현빈도(Term Frequency, TF)와 역 문서 빈도(Inverse Document Frequency, IDF)를 곱하여 단어마다 TF-IDF 가중치를 부여합니다. 아래 수식과 같이 말이죠.

$$ \text{TF-IDF} = \text{TF} * \text{IDF} $$

이제 TF와 IDF 각각에 대해 자세히 알아봅니다.

2.1. TF(Term Frequency)

TF(Term Frequency)는 특정 문서 \(d\)에서 특정 단어 \(t\)의 출현빈도입니다. TF 계산방법은 카운트 기반의 단어표현 방법인 DTMBag of Words(BoW)에서 문서마다 단어별 출현 횟수를 계산하는 방법과 동일합니다. DTM의 경우를 예시로 알아보죠. 아래와 같이 \(4\)개의 문서가 있다고 하겠습니다.

문서구분 내용
문서1 배가 부르다
문서2 배의 가격이 비싸다
문서3 진짜 사과가 진짜 좋다
문서4 아침엔 사과가 좋다

문서 내 띄어쓰기를 기준으로 토큰화(tokenization)한다고 가정하겠습니다. 토큰화는 문장을 여러 단위의 덩어리로 쪼개는 작업이라 생각하시면 됩니다. 문서별 TF는 아래 표와 같이 나타낼 수 있습니다. 문서3에서 '진짜'라는 단어를 예시로 살펴보면, TF 값은 \(2\)라고 할 수 있겠죠.

  가격이 배가 배의 비싸다 부르다 사과가 아침엔 진짜 좋다
문서1 0 1 0 0 1 0 0 0 0
문서2 1 0 1 1 0 0 0 0 0
문서3 0 0 0 0 0 1 0 2 1
문서4 0 0 0 0 0 1 1 0 1

2.2. DF(Document Frequency)

IDF(Inverse Document Frequency)는 DF(Document Frequency) 값의 역수입니다. IDF를 알아보기에 앞서 DF을 먼저 알아봅니다. DF는 전체 문서 \(D\)에서 특정 단어 \(t\)가 등장한 문서 개수입니다. 수식은 아래와 같습니다.

$$ df(t) = \vert \{d \in D: t \in d\} \vert $$

DF의 경우 오직 단어가 몇 개의 문서에 출현했는지만 관심이 있습니다. 예를 들어, A, B, C, D라는 \(4\)개의 문서가 있고, 단어 \(t\)가 \(A\)와 \(B\) 문서에서 등장했다고 가정하겠습니다. DF의 경우, 단어 \(t\)가 문서 \(A\)에서 \(100\)번 등장하고, \(B\)라는 문서에서 \(1,000\)번 등장했더라도 전체 문서에서 단어가 등장한 문서 개수는 \(2\)입니다. 즉, 위의 수식에 따라 \(df(t)\)를 계산하면 다음과 같습니다.

$$ df(t) = 2 $$

2.3. IDF(Inverse Document Frequency)

2.3.1. 개념

TF-IDF는 전체 문서에서 빈출되는 단어의 중요도는 낮다고 판단하고, 특정 문서에서만 빈출되는 단어는 중요도가 높다고 판단합니다. 즉, TF-IDF 값은 단어의 중요도와 비례하는데, TF-IDF 값이 클수록 해당 단어의 중요도가 높은 것이죠. 예를 들어, '합니다, '에서', '가'와 같이 서술어나 조사와 같은 불용어는 대부분의 문서에서 빈출하기 때문에 TF-IDF 값은 낮아집니다.

2.3.2. 수식

IDF(Inverse Document Frequency)는 DF 값의 역수라고 했습니다. 수식부터 살펴보겠습니다.

$$ idf(d, t)= \ln{}(\frac{D}{1+df(t)}) $$

IDF가 DF의 역수라고 했는데 수식을 보시면 몇 가지 의문이 드실 겁니다. 자연로그(\(ln\))를 사용하는 이유와 분모에 \(1\)을 더해준 이유가 무엇일까요? 각각 알아봅니다.

 

(1) 자연로그 사용이유

로그(\(log\))를 사용하는 이유는 문서 개수\(D\)가 늘어날수록 IDF 값 \((\frac{D}{\vert d \in D: t \in d \vert})\)이 기하급수적으로 증가하는 것을 방지하기 위함입니다. 이를 방지하기 위해 로그를 사용합니다. 더욱 구체적으로 설명해 드리자면, 문서 개수가 많아짐에 따라 문서 내 빈출 단어와 희귀 단어에 부여되는 가중치 차이를 줄이기 위해 로그를 사용합니다. 일반적으로 불용어(stop word)와 같은 빈출 단어는 희귀 단어와 출현 빈도가 적게는 수백 배 차이납니다. 즉, 로그를 사용하지 않으면 단어 간 가중치가 지나치게 차이나는 문제가 발생합니다. IDF 계산 시 \(log\)의 밑은 하이퍼 파라미터(Hyper Parameter)로써 사용자가 임의로 선정하는 값입니다. 일반적으로 프로그래밍을 통해 IDF 값을 계산할 때 대부분 로그의 밑을 자연상수 \(e(=2.718281...)\)를 사용합니다.

 

(2) 로그 내 분모에 \(1\)을 더하는 이유

로그 내 분모에 \(1\)을 더해주는 이유는 특정 단어 \(t\)가 전체 문서에서 출현하지 않는 경우, 분모가 \(0\)이 되는 상황을 방지하기 위함입니다.

2.3.3. 계산

파이썬을 활용하여 TF-IDF를 직접 계산해 보겠습니다. 필요한 패키지를 import합니다(패키지 설치 시 pipenv 가상환경 사용 권장).

try:
    import pandas as pd
    import numpy as np
    from sklearn.feature_extraction.text import CountVectorizer
except:
	!pip install -U -q pandas numpy sklearn

앞서 사용한 4가지 문서를 예시로 사용하겠습니다.

documents = [
   "배가 부르다",
   "배의 가격이 비싸다",
   "진짜 사과가 진짜 좋다",
   "아침엔 사과가 좋다"
]

단어 출현 빈도를 벡터화하여 표현하는 함수입니다.

vectorizer = CountVectorizer()

DTM과 TF를 계산합니다.

# Document Term Matrix
dtm = vectorizer.fit_transform(documents)

# Term Freqeuncy
tf = pd.DataFrame(dtm.toarray(), columns = vectorizer.get_feature_names())

TF를 출력해 보면 아래의 그림 2와 같습니다. 

그림 2. TF 계산결과

DF를 계산하고 결과를 출력하면 아래의 그림 3과 같습니다. '시과가'와 '좋다'라는 단어만 2개의 문서에서 등장한 것을 알 수 있습니다.

# Document Frequency 
df = tf.astype(bool).sum(axis = 0)

그림 3. DF 계산 결과

이제 IDF를 계산해 봅니다.

# 문서 개수
D = len(tf)

# Inverse Document Frequency
idf = np.log((D) / (df+1))

마지막으로 TF-IDF를 계산해 봅니다.

# TF-IDF
tfidf = tf * idf                      
tfidf = tfidf / np.linalg.norm(tfidf, axis = 1, keepdims = True)

📚 참고할 만한 포스팅

1. [NLP] Bag of Words(BoW) 개념 및 실습
2. [NLP] 문서 단어 행렬(DTM) 개념 이해
3. [NLP] TF-IDF 개념 및 계산 방법
4. [NLP] Word Embedding의 이해: (1) 희소표현 및 밀집표현
5. [NLP] 언어모델(Language Model)의 개념 및 특징
6. [NLP] N-gram 언어 모델의 개념, 종류, 한계점
7. [NLP] 언어모델의 평가지표 'Perplexity' 개념 및 계산방법
8. [NLP] Word2Vec: (1) 개념
9. [NLP] Word2Vec: (2) CBOW 개념 및 원리
10. [NLP] Word2Vec: (3) Skip-gram
11. [NLP] Word2Vec: (4) Negative Sampling
12. [NLP] 문서 유사도 분석: (1) 코사인 유사도(Cosine Similarity)
13. [NLP] 문서 유사도 분석: (2) 유클리디안 거리(Euclidean Distance)
14. [NLP] 문서 유사도 분석: (3) 자카드 유사도(Jaccard Similarity)
Last Updated @2022-06-13
- 수식 표기 및 계산 오류 수정

오늘은 TF-IDF 개념과 계산방법에 대해 알아봤습니다.
포스팅 내용에 오류가 있거나 보완할 점이 있다면 아래에 👇👇👇 댓글 남겨주시면 감사드리겠습니다 :)
그럼 오늘도 즐겁고 건강한 하루 보내시길 바랍니다.
고맙습니다😊

728x90
반응형
Comments