ML & DL/NLP

텍스트 벡터화 기법의 종류

본 게시물은 2021.04.11. 에 작성되었으며, 블로그를 이전하며 현재 날짜로 등록되었습니다.

본 게시물은 모두의연구소 AIFFEL 컨텐츠를 참고하여 정리한 내용입니다.

우리는 컴퓨터가 이해하기 쉽도록 텍스트를 BOW(Bag of Words)등의 방법으로 표현해 수치화한다.
그렇다면 수치화한 것은 어떻게 활용할 수 있을까?

이전에 자연어처리와 토크나이저에 대해 공부하면서, 희소표현이 아닌 분산표현을 이용하면 좋은 점이 단어들 간의 의미적 유사도를 계산할 수 있다는 점이라고 배웠다.

단어 혹은 문장 간 의미적 유사도 계산 방법 중 하나인 코사인 유사도에 대해서 공부해보겠다!

우리는 단어를 수치화하면서 벡터화한다.

  • 벡터 : 벡터란 방향과 크기를 나타내는 원소이다.

 

코사인 유사도

코사인 유사도 : 두 벡터 간의 코사인 각도를 이용하여 구할 수 있는 두 벡터의 유사도

image

사진에서 벡터들의 방향을 보자!

  • 방향이 정반대일 경우에는 코사인 유사도 : -1
  • 90도의 각을 이루는 경우의 코사인 유사도 : 0
  • 방향이 완전히 일치할 때의 코사인 유사도 : 1 (최대)

따라서, 두 벡터를 비교했을 때 각 방향이 얼마나 유사한가를 의미한다.

다음은 두 벡터 A, B에 대한 코사인 유사도 식이다.

image

from numpy import dot
from numpy.linalg import norm
import numpy as np
def cos_sim(A, B):
       return dot(A, B)/(norm(A)*norm(B))

코사인 유사도 계산식을 이용해서 함수를 만들어, 문서에 대해 코사인 유사도를 계산해보자!

doc1=np.array([0,1,1,1])
doc2=np.array([1,0,1,1])
doc3=np.array([2,0,2,2])
print(cos_sim(doc1, doc2)) #문서1과 문서2의 코사인 유사도
print(cos_sim(doc1, doc3)) #문서1과 문서3의 코사인 유사도
print(cos_sim(doc2, doc3)) #문서2과 문서3의 코사인 유사도
0.67  # 문서1 & 문서2
0.67  # 문서1 & 문서3
1.00  # 문서2 & 문서3

위에서 코사인 유사도의 최대값은 1이라고 공부했다.
계산 결과를 보면 문서2와 문서 3의 코사인 유사도가 1로 나온 것을 볼 수 있는데, 이때 우리는 벡터가 무엇이었는지를 다시 상기할 수 있다.

문서 3은 문서 2에서 단어의 빈도수를 1씩 증가시켰다.
고로 방향은 같고 크기를 증가시킨 것이다.
이처럼 코사인 유사도는 크기가 아닌 방향을 기준으로 계산하기 때문에, 문서의 길이가 다른 상황이더라도 비교적 공정한 비교를 할 수 있도록 돕는다.

이러한 특성은 유클리디안 유사도(Euclidean distance)와 비교할 수 있다.

image

유클리디안 유사도 공식은 점 p와 q의 좌표들 간의 거리를 이용해서 두 점의 거리를 계산한다.
거리 기반으로 계산하기 때문에, 벡터의 방향이 아닌 비슷한 값(빈도)을 갖고 있는 문서들의 유사도가 더 높게 나올 것이다.

그럼 이제 벡터화의 종류에 대해 살펴보겠다.
오늘 정리할 벡터화 기법은 모두 통계와 머신러닝을 활용한 방법이다!

 

Bag of Words(BOW)

BOW는 자연어 처리에서 쓰이는 벡터화 기법 중 가장 간단한 기법이다.
그대로 직역하면 알 수 있듯이 문서 내의 모든 단어의 등장 횟수를 이용한다.

doc = ['인공지능 공부는 흥미롭다']

# 위 문서를 BoW로 표현하면 ?!

bow = {'공부는':1, '인공지능':1,  '흥미롭다':1}

이처럼 문서 내 단어 순서와 관계없이 {단어:등장 횟수}로 이루어진다.
때문에 어순에 따른 의미를 반영할 수 없다는 한계를 갖는다.

 

Document-Term Matrix(DTM)

DTM은 문서-단어 행렬 이라는 뜻으로, 등장한 단어의 빈도수를 하나의 행렬로 통합시키는 기법이다.
행에는 문서를, 열에는 단어를 배치하고 이 것이 역으로 구성되면 TDM이라고 부르기도 한다.
DTM은 단어의 빈도수를 이용한다는 점에서 BoW를 기반으로 되어있다.

DTM의 한계

문서가 많아지면, 단어(열)가 많아질 것이다.
이렇게 행렬이 커질 수록 0의 값을 갖는 원소가 많이 생겨 너무 sparse 해질 것이다.
이는 차원의 저주라는 문제를 발생시키기도 한다.
빈도수를 이용하게 되면 불용어(the, a, i, you, have, must, can...)처럼 중요하지 않은 단어에 대한 처리가 되지 않는다.

 

Term Frequency-Inverse Document Frequency(TF-IDF)

단어의 빈도 뿐만 아니라, 그 단어의 중요도를 반영한 기법을 알아보자.
TF-IDF는 모든 문서에서 자주 등장하는 단어는 중요도가 낮게, 특정 문서에서 자주 등장하는 단어는 중요도가 높게 판단한다.
수식을 먼저 살펴보자!

image

TF-IDF는 TF와 IDF를 곱한 행렬이다.
여기서 TF는 단어 빈도, 즉 DTM이다.
IDF는 각 단어(x)가 전체 문서(N) 중 몇 개의 문서에 등장했는지를 나타낸다.

doc1 = ['hi']
doc2 = ['hi hi my name is mike']
doc3 = ['bye see you again']

doc_list = [doc1, doc2, doc3]
N = len(doc_list)  # 3

df_hi = 2

'hi'에 대한 df를 구하면, 문서 1, 문서 2에 등장하기 때문에 2이다.
문서1에서는 1번, 문서 2에서는 2번 등장하지만 그 점은 고려하지 않는 것을 알 수 있다.

TF-IDF는 전체 문서에서의 단어 등장 빈도를 이용해 단어의 중요도를 반영했지만, 근본적인 단어의 의미는 표현하지 못한다는 한계가 있다.

 

Latent Semantic Analysis(LSA)

근본적인 단어의 의미까지 표현하기 위해 우리는 LSA, 잠재 의미 분석을 이용할 수 있다.
LSA는 행렬을 특잇값 분해해서 차원을 축소해 단어들의 관계를 찾아낸다.

특잇값 분해(Singular Value Decomposition)

image

특잇값 분해란 mxn크기의 사각행렬을 특이 벡터의 행렬과 특잇값의 대각행렬로 분해하는 것을 말한다.
LSA는 특잇값 분해를 통해 얻은 최대 특잇값에 대응되는 특이 벡터들로 행렬을 근사해 Truncated SVD를 수행한다.

DTM 혹은 TF-IDF 행렬에 이 과정을 수행하고, 이를 통해 얻은 행렬 3개는 각각 단어들의 관계를 나타낸다.
$U$ : 문서들과 관련된 의미들을 표현
$V^T$ : 단어들과 관련된 의미들을 표현
$S$ : 각 의미의 중요도를 표현

또한 Truncated SVD를 수행하고 얻는 $V_k^T$ 행렬의 k열은 전체 코퍼스(말뭉치)로부터 얻어낸 k개의 주요 주제라고 간주할 수 있다.

 

Latent Dirichlet Allocation(LDA)

LSA와 비슷한 토픽 모델링의 대표적인 알고리즘, LDA에 대해 배워보자.
LDA는 토픽을 단어들의 확률 분포에 기반해 찾아 낸다.
토픽의 개수(k)를 지정하면 전체 문서에 등장하는 단어들의 분포를 확인하고, 가장 많이 등장하는 k개의 토픽 분포를 추정하는 메커니즘으로 동작한다.
쉽게 테스트할 수 있는 링크에서 확인해보는 것이 가장 이해가 빠르다!

'가장 가까운 병원'이라고 검색한다고 가정하고, 병원이라는 단어가 들어가지만 검색어와 관련 없는 문장, 병원이라는 단어는 없지만 답변으로 나올 듯한 문장으로 시험해봤는데 00 정형외과라는 문장이 검색어와 같은 토픽의 분포가 높다고 추정했다.


오늘 정리한 각 기법들은 모두 sklearn패키지에서 쉽게 계산하고 생성할 수 있는 방법들이었다.
계속해서 한계점을 보완할 수 있는 기법이 나오는 것이 신기하고, LDA 같은 경우는 추천 분야에서도 많이 사용될 것 같다.

Reference

https://dailyheumsi.tistory.com/153
https://wikidocs.net/24557

반응형

'ML & DL > NLP' 카테고리의 다른 글

내적과 코사인 유사도  (1) 2023.01.30
Word Embedding Association Test (WEAT) - 편향성 측정  (0) 2021.11.08
자연어 처리와 토크나이저  (0) 2021.07.02