Posted:      Updated:

AI 스터디를 하며 ‘파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습’ 교재를 정리한 글입니다.

TF-IDF (Term Frequency-Inverse Document Frequency)

문서 내 단어의 중요도 평가에 사용되는 통계적인 가중치
텍스트 문서에서 특정 단어의 중요도를 계산하는 방법

BoW (Bag-of-Words)

문서나 문장을 단어의 집합으로 표현하는 방법
모든 단어가 동일한 가중치를 가지며, 단어의 빈도를 고려하여 표현

🔗 BoW 만들기

단어 빈도(Term Frequency, TF)

문서 내에서 특정 단어의 빈도수를 나타내는 값
3개의 문서에서 ‘movie’라는 단어가 4번 등장하면 TF 값은 4

\[TF(t,d) = count(t,d)\]

TF 값이 높을 수록 중요한 역할 혹은 전문 용어, 관용어 일 수 있음
단순히 빈도만 계산하므로 문장이 길면 TF 값도 높아질 수 있음

문서 빈도(Document Frequency, DF)

한 단어가 몇 개의 문서에서 등장하는지 계산
3개의 문서에서 ‘movie’라는 단어가 4번 등장하면 DF 값은 3

\[DF(t, D) = \text{count}(t \in d : d \in D)\]

DF 값이 높으면 특정 단어가 많은 문서에서 등장하므로 일반적으로 널리 사용되고 중요도가 낮을 수 있음
DF 값이 낮음녀 적은 수의 문서에만 등장하므로 특정 문맥에서 사용되거나 중요도가 높을 수 있음

역문서 빈도(Inverse Document Frequency, IDF)

전체 문서 수를 문서 빈도로 나눈 다음 로그를 취한 값
문서 내의 특정 단어의 중요도를 나타냄
단어의 문서 빈도 수가 적을 수록 IDF 값은 커짐

\[IDF(t, D) = \log\left(\frac{\text{count}(D)}{1 + DF(t, D)}\right)\]

특정 단어가 한 번도 등장하지 않아 문서 빈도(DF)가 0이 되어 분모가 0이 되는 걸 방지하기 위해 1을 더한 값 사용
IDF 값이 너무 커지는 걸 방지하기 위해 로그 사용

TF-IDF

단어 빈도와 역문서 빈도를 곱한 값

\[TF\text{-}IDF(t, d, D) = TF(t, d) \times IDF(t, D)\]

특정 문서 내에 단어가 자주 등장하고, 전체 문서 내에 해당 단어가 적게 등장하면 TF-IDF 값이 커짐
-> 단어 빈도(TF)가 크고, 역문서 빈도(IDF)가 큰 경우

사이킷런(Scikit-learn)의 TfidfVectorizer

tfidf_vectorizer = sklearn.feature_extraction.text.TfidfVectorizer(
    input="content",  # 입력될 데이터의 형태, content: 문자열 혹은 바이트 데이터, file: 파일 객체, filename: 파일 경로
    encoding="utf-8", # 바이트, 파일 입력 시 텍스트 인코딩 값
    lowercase=True, # 입력 받은 데이터 소문자로 변환 여부
    stop_words=None, # 분석에 사용하지 않을 단어
    ngram_range=(1, 1), 
    max_df=1.0, # 문서 빈도가 해당 값을 넘으면 stop word로 처리
    min_df=1, # 문서 빈도가 일정 횟수 미만이면 stop word로 처리
    vocabulary=None, # 미리 구축한 단어 사전 사용, 입력하지 않으면 자동으로 구축
    smooth_idf=True, # IDF 계산 시 분모(DF)에 1 더함
)

TF-ID 계산

벡터값을 활용해 문서 내 핵심(TF-IDF 값이 높은) 단어를 추출할 수 있음
벡터는 해당 문서 내 중요도만 의미하고 단어의 의미를 가지지 않음
빈도 기반 벡터화이므로 문장의 순서, 문맥을 고려하지 않음
문장 생성, 순서가 중요한 작업에는 부적합

from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
    "That movie is famous movie",
    "I like that actor",
    "I don’t like that actor"
]
tfidf_vectorizer = TfidfVectorizer() # TfidfVectorizer 객체 불러오기
tfidf_vectorizer.fit(corpus) # 코퍼스 학습
tfidf_matrix = tfidf_vectorizer.transform(corpus) # 변환 수행
# tfidf_matrix = tfidf_vectorizer.fit_transform(corpus) # 학습과 변환 동시에 수행
print(tfidf_matrix.toarray()) # 넘파이 배열로 변환 (문서 수)x(단어 수)
print(tfidf_vectorizer.vocabulary_) # 사용된 단어 사전 key: 고유 단어, value: index 값

출력

[[0.         0.         0.39687454 0.39687454 0.         0.79374908
  0.2344005 ]
 [0.61980538 0.         0.         0.         0.61980538 0.
  0.48133417]
 [0.4804584  0.63174505 0.         0.         0.4804584  0.
  0.37311881]]
{'that': 6, 'movie': 5, 'is': 3, 'famous': 2, 'like': 4, 'actor': 0, 'don': 1}

Categories:

댓글남기기