1. TF-IDF(단어 빈도-역 문서 빈도, Term Frequency-Inverse Document Frequency)
: TF와 IDF를 곱한 값 의미
: 단어의 빈도와 역 문서 빈도(문서의 빈도에 특정 식을 취함)를 사용하여 DTM 내의 각 단어들마다 중요한 정도를 가중치로 주는 방법
ㄴ 문서의 유사도를 구하는 작업
ㄴ 검색 시스템에서 검색 결과의 중요도를 정하는 작업
ㄴ 문서 내에서 특정 단어의 중요도를 구하는 작업
문서: d
단어: t
문서의 총 개수: n
(1) tf(d,t): 특정 문서 d에서의 특정 단어 t의 등장 횟수
ㄴ DTM의 예제에서 각 단어들이 가진 값
(2) df(t): 특정 단어 t가 등장한 문서의 수
(3) idf(d,t): df(t)에 반비례하는 수
idf(d,t) = log(n / 1+df(t))
*log를 사용하지 않았을 때, IDF를 DF의 역수로 사용한다면 총 문서의 수 n이 커질 수록, IDF의 값은 기하급수적으로 커지게 됨 (희귀 단어들에 엄청난 가중치 부여)
2. 파이썬으로 TF-IDF 직접 구현하기
import pandas as pd # 데이터프레임 사용을 위해
from math import log # IDF 계산을 위해
docs = [
'먹고 싶은 사과',
'먹고 싶은 바나나',
'길고 노란 바나나 바나나',
'저는 과일이 좋아요'
]
vocab = list(set(w for doc in docs for w in doc.split()))
vocab.sort()
# 총 문서의 수
N = len(docs)
def tf(t, d):
return d.count(t)
def idf(t):
df = 0
for doc in docs:
df += t in doc
return log(N/(df+1))
def tfidf(t, d):
return tf(t,d)* idf(t)
# TF 구하기: DTM을 데이터프레임에 저장하여 출력
result = []
# 각 문서에 대해서 아래 연산을 반복
for i in range(N):
result.append([])
d = docs[i]
for j in range(len(vocab)):
t = vocab[j]
result[-1].append(tf(t, d))
tf_ = pd.DataFrame(result, columns = vocab)
# 각 단어에 대한 IDF 구하기
result = []
for j in range(len(vocab)):
t = vocab[j]
result.append(idf(t))
idf_ = pd.DataFrame(result, index=vocab, columns=["IDF"])
# TF-IDF 행렬 출력
result = []
for i in range(N):
result.append([])
d = docs[i]
for j in range(len(vocab)):
t = vocab[j]
result[-1].append(tfidf(t,d))
tfidf_ = pd.DataFrame(result, columns = vocab)
3. 사이킷런을 이용한 DTM과 TF-IDF 실습
from sklearn.feature_extraction.text import CountVectorizer
corpus = [
'you know I want your love',
'I like you',
'what should I do ',
]
vector = CountVectorizer()
# 코퍼스로부터 각 단어의 빈도수를 기록
print(vector.fit_transform(corpus).toarray())
# DTM: 각 단어와 맵핑된 인덱스 출력
print(vector.vocabulary_)
[[0 1 0 1 0 1 0 1 1]
[0 0 1 0 0 0 0 1 0]
[1 0 0 0 1 0 1 0 0]]
{'you': 7, 'know': 1, 'want': 5, 'your': 8, 'love': 3, 'like': 2, 'what': 6, 'should': 4, 'do': 0}
# TF-IDF 계산
from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
'you know I want your love',
'I like you',
'what should I do ',
]
tfidfv = TfidfVectorizer().fit(corpus)
print(tfidfv.transform(corpus).toarray())
print(tfidfv.vocabulary_)
[[0. 0.46735098 0. 0.46735098 0. 0.46735098 0. 0.35543247 0.46735098]
[0. 0. 0.79596054 0. 0. 0. 0. 0.60534851 0. ]
[0.57735027 0. 0. 0. 0.57735027 0. 0.57735027 0. 0. ]]
{'you': 7, 'know': 1, 'want': 5, 'your': 8, 'love': 3, 'like': 2, 'what': 6, 'should': 4, 'do': 0}