while (1): study();

Ch2. 자연어와 단어의 분산 표현 본문

독서

Ch2. 자연어와 단어의 분산 표현

전국민실업화 2021. 7. 25. 21:20
728x90

 지금까지 자연어 처리에 대해서 공부를 하면서 많은 임베딩 기법들을 접해보았습니다. 최신의 성능좋은 기술에 눈을 돌리다보니 아무래도 그 배경에 대해서는 상대적으로 소홀했던 것 같습니다. 컴퓨터에게 인간의 언어를 이해시키는 방법론은 3가지가 있습니다.


1. 시소러스 방법론

2. 통계 기반 방법론

3. 추론 기반 방법론


이 장에선 위의 반성과 더불어 통계적으로 단어를 분산 표현으로 바꾸는 방법에 대해서 알아봅니다.

 

1. 시소러스

 시소러스의 사전적 정의는 다음과 같습니다.

즉 시소러스 기반 방법론이란, 인간이 구축한 유의어 사전을 기반으로 단어들 간의 연관성을 컴퓨터가 파악하게 하는 것입니다. 대표적인 시소러스로는 프린스턴 대학교에서 1983년부터 구축하기 시작한 WordNet이 있습니다. WordNet은 다음 링크에서 확인해볼 수 있습니다.

링크: http://wordnetweb.princeton.edu/perl/webwn

 

WordNet Search - 3.1

 

wordnetweb.princeton.edu

 

위의 링크에서는 WordNet 데이터에 직접 쿼리를 날려 액세스할 수 있는데, 저는 car라는 단어를 검색해보겠습니다.

Wordnet example

위와 같이 car라는 단어는 5가지 뜻이 있으며, 각각의 뜻에 따라 동의어도 달라집니다. 또한 S:를 누르면 상하위 관계어도 확인할 수 있습니다.

Car.n.1 Hyponym

 car의 첫번째 의미의 상위어는 이렇게나 많이 있는 것을 확인할 수 있습니다.

 직관적으로 생각해볼때, 만약 시소러스를 구축하는 사람이 실수만 하지 않는다면 시소러스 기반 방법론은 인간이 직접 컴퓨터에게 지식을 전수해줄 수 있다는 면에서 괜찮은 듯 보입니다. 그러나 단점은 너무나도 명확합니다. 바로 '변화에 대응하기 힘들다'는 점입니다. 시간이 지나면서 언어는 진화와 쇠퇴를 거칩니다. 시소러스를 구축하는 사람은 언어가 시대의 변화에 의해서 맞게 되는 풍파를 함께 견뎌내겠다는 각오를 다지지 않으면 안되는 것이죠.

 이외에도 다음과 같은 단점이 있겠습니다. 


1. 인력과 시간(비용)이 많이 든다.

2. 단어의 미묘한 차이를 표현하기 어렵다.

3. 각 언어마다 시소러스를 따로 구축해야 한다.

4. 막대한 크기의 저장소가 필요하다.

...


 

2. 통계 기반 방법

 앞서 살펴본 '시소러스 기반 방법론'의 단점들을 극복하기 위해서 '통계 기반 방법론'을 제안합니다. 이것은 raw corpus로부터 단어의 의미를 파악하는데 필요한 정보를 자동화된 절차로 파악하는 것입니다.

 결과론적으로 우리는 컴퓨터에게 단어를 단어로서 이해하는 것을 바라는 것이 아닙니다. 각 단어의 미묘한 관계를 잘 파악하길 원하는 것입니다. 따라서 단어를 불연속적인 특성(Discrete feature)으로서 파악하면 관계에 대한 의미가 희석됩니다. 따라서 우리는 단어라는 것을 연속적인 실수 공간에 던져볼 필요가 있습니다.

 예를 들어 빨강, 주황, 초록이라는 단어가 있을 때 우리는 무의식적으로 초록보다는 주황이 빨강과 의미적으로 가까운 단어라는 것을 알고 있습니다. 그리고 빨강과 주황 사이에 RGB의 R값이 그 중간 정도인 새로운 색이 주어진다고 해도, 유사한 색이라는 것을 바로 판단할 수 있습니다. 즉, 색을 표현하는 단어 또한 사실상 그 의미는 연속적인 것입니다.

 따라서 단어의 의미를 연속적으로 파악할 수 있도록 어떤 벡터로 변환시켜야 합니다. 이 벡터를 단어의 분산 표현(Distributional Representation)이라고 합니다.

 

 그럼 어떤 식으로 우리는 단어를 실수공간에 사상(Embedding)할 수 있을까요? NLP에 있어 중요한 기반 중 하나는 분포 가설(Distributional Hypothesis)입니다. 즉 단어는 그 자체로 의미를 갖는 것이 아니라 주변의 단어에 의해 형성된다는 것입니다. 즉 어떤 단어를 기점으로 앞 뒤에 무슨 단어가 나오는지 파악해보면 실수 공간으로 사상하는 작업이 용이해질겁니다. 이러한 생각을 바탕으로 동시발생 행렬(Co-occurrence Matrix)를 만들어볼 수 있습니다.

 동시발생 행렬은 특정 단어의 앞뒤를 윈도우 사이즈만큼 확인하고, 동시에 등장한 횟수를 세어 해당 단어의 특성으로 삼습니다. 예를 들어 You say Goodbye and I say Hello라는 문장에 대해서 아래와 같은 동시발생 행렬로 표현할 수 있습니다.

 이제 실제로 각 단어간 유사도를 구하여 얼마나 직관과 맞아떨어지는지 확인해보겠습니다. 단어 간 유사도를 구할 때는 대체로 자카드 거리나 코사인 유사도를 사용합니다만, 여기서는 단어가 벡터로 표현되었으므로 코사인 유사도를 사용합니다.

$$Cosine similarity(x, y) = {xy \over ||x||||y||}$$

 두 벡터의 내적은 두 벡터의 방향이 같을 때 최대값, 반대일 때 최소값이 됩니다. 여기서 벡터의 크기로 스케일링을 하기 때문에 결과적으로 남는 것은 방향 뿐입니다. 따라서 두 벡터가 얼마나 비슷한 방향을 가리키고 있는지만 확인할 수 있습니다. 예시로 위의 동시발생 행렬에서 You와 I의 코사인 유사도는 약 0.7 정도가 나옵니다. 코사인 유사도의 최대값이 1이므로, 상당히 높은 유사도임을 알 수 있습니다.

  모든 단어에 대해서 같은 방식으로 코사인 유사도를 구해 오름차순으로 정렬한 결과는 다음과 같습니다. (상위 5개)

조금 더 전체적인 경향을 볼 수 있게 산점도를 찍어보겠습니다.

Scatter plot - SVD

hello와 goodbye가 상대적으로 가까이 있고, i와 you가 매우 가깝다는 점에서 직관과는 얼추 들어맞습니다. 호기심이 발동해서 다른 기법으로 차원을 축소해도 비슷한 결과가 나오는지 확인해보았습니다. 원래는 PCA를 사용하려고 했으나, 너무 느린 탓에 ICA(독립성분 분석)을 사용하기로 하였습니다.

Scatter plot - ICA

 i와 you가 상대적으로 가까운 건 동일하지만, hello와 goodbye는 멀어진 것을 볼 수 있습니다. 확실히 현재의 결과는 불안정한듯 합니다. 다만 애초에 훈련 데이터를 한 문장밖에 주지 않았으니 부정확한 결과가 나오는 것은 당연지사입니다. 이후에 조금 더 큰 데이터로 비교해보겠습니다.

 이것 외에도 문제점이 있습니다. 바로 많이 나온 단어에 대해서 더 높은 점수를 부여한다는 것입니다. 예를 들어 the와 cat과 dog라는 단어가 있다고 했을 때, cat과 dog는 의미적으로 높은 연관성을 보여야 타당합니다. 그러나 실제 코퍼스에서 the는 매우 빈번하게 발생하고, 따라서 the와 cat이 더 높은 연관성을 보일 확률이 높다는 것입니다. 

 이러한 연유로 상호정보량(Mutual Information)을 이용하여 단점을 개선해보겠습니다. 실제 상호정보량은 확률분포에 대해 계산하지만, 우리는 단어 간 유사도를 구하고 싶기 때문에 점별 상호정보량(PMI; Pointwise Mutual Information)을 사용합니다. 이는 다음과 같이 계산됩니다.

$$PMI(x, y) = log_{2}{P(x, y) \over P(x)P(y)}$$

P(x)는 x 단어가 뽑힐 확률, P(y)는 y단어가 뽑힐 확률이라고 볼 수 있습니다. 우리는 가상의 진리적 분포에서 해당 단어가 발생할 확률을 구하고 싶지만, 그럴 수 없기 때문에 코퍼스 내에서 단어의 발생 빈도로 이것을 근사합니다.

$$PMI(x, y) = log_{2}{P(x, y) \over P(x)P(y)} = log_2{N * CNT(x, y) \over CNT(x)CNT(y)}$$

만약 두 단어가 한번도 뽑히지 않았다면 로그값이 음의 무한대로 발산하므로, 여기서는 양의 상호정보량(PPMI; Positive PMI)를 사용합니다. ${P(x, y) \over P(x)P(y)}$가 0이 되는 경우는 두 단어가 독립이라는 가정 하에 단어가 함께 발생한 적이 없는 경우이므로, 최소값을 0으로 클리핑해도 직관적으로 타당합니다. 

$$PPMI(x, y) = max(0, PMI(x, y))$$

따라서 이전의 동시발생 행렬은 다음과 같이 표현됩니다.

PPMI matrix

 아직 문제점은 남았습니다. 바로 희소행렬(Sparse Matrix)라는 점입니다. 딥러닝을 사용하는 경우 피처의 개수에 큰 영향을 받지는 않지만, 메모리 낭비 및 과도한 연산이 발생할 수 있습니다. 또한 각 원소의 중요도가 낮기 때문에 견고하지 못한 표현일 수도 있죠. (경험적으로는 메모리 낭비 측면에서 가장 치명적인 듯 합니다..) 따라서 이 행렬의 차원을 조금 감소시킬 필요가 있습니다. 주성분분석(PCA), 특잇값분해(SVD), 오토인코딩 등을 사용할 수 있겠지만 여기선 SVD를 사용합니다.

 특잇값 분해(SVD; Singular Vector Decomposition)은 특정 행렬을 세 행렬의 곱으로 분해하는 것을 말합니다. 고윳값 분해가 역행렬이 존재하지 않는 행렬에 대해서만 행할 수 있는 것과 달리, 특잇값 분해는 모든 행렬에 대해서 가능합니다!

$$X = USV^{T}$$

이 때 왼쪽 특잇값 행렬인 U는 N차원의 정방행렬로, 모든 열벡터가 단위벡터이고 서로 직교합니다. 오른쪽 특잇값 행렬인 V는 M차원의 정방행렬이고, 마찬가지로 모든 열벡터가 단위벡터이고 서로 직교합니다. 중요한 것은 S 행렬은 대각행렬으로, 각 원소는 특잇값을 기준으로 오름차순 정렬되어 있습니다.

 U 행렬을 단어 공간으로 취급했을 때(단어장 크기만큼 차원을 유지하므로), S의 특잇값을 일종의 중요도 개념으로 생각할 수 있습니다. 따라서 중요도가 높은 특성들만 남기고 잘라내어 차원을 축소할 수 있습니다. 예를 들어 처음의 특잇값 분해 형태가 (N, N) * (M, N) * (M, M)이라고 해봅시다. 이 때 D개 만큼의 중요하지 않은 성분을 잘라냅니다. 그렇게 되면

형태는 (N, M - D) * (M - D, M - D) * (M - D, M)이 될 겁니다. 

 이러한 방식으로 위의 PPMI 행렬에 SVD를 수행해보겠습니다.

SVD

차원이 7이었던 PPMI 행렬이 2차원으로 줄어들었습니다. 다만 SVD의 시간복잡도는 $O(N^{3})$이라고 하므로, 실제로는 작은 특잇값을 고려하지 않는 Truncated SVD를 이용합니다.

 지금까지의 방법론이 얼마나 잘 작동하는지 펜 트리뱅크(이하 PTB) 벤치마크 데이터셋을 이용하여 정성적으로 평가해보도록 하겠습니다.

most similar - SVD

PTB를 이용하여 생성한 PPMI 행렬을 Truncated SVD를 이용하여 100차원으로 축소했습니다. 이후 5개 단어에 대해서 가장 비슷한 상위 5개 단어를 뽑게 했습니다. you의 경우 문법적으로 같은 대명사끼리 많이 묶였네요. year은 month, week등 날짜, 기간을 의미하는 단어들과 가장 비슷하다고 하네요.

 car같은 경우는 조금 의아한게, spy랑 jounalist가 섞여있습니다. spy는 스파이들이 멋진 차를 타는 모습을 상상하며, 그럴 수 있다고 생각했습니다만.. journalist는 왜 나왔는지 궁금해서 journalist car로 구글링해보았습니다.

아, 저널리스트들이 차를 타는 게 아니라, 차를 주제로 하는 저널리스트들 때문이었습니다.

 toyota의 경우는 제가 잘 몰라서 또 따로 구글링을 해보았습니다만, mcdonnell은 toyota의 회장이고, salomon은 에디션 이름이며, montgomery는 도요타 정비점이 있는 곳이네요. 어쨌든 코퍼스를 기준으로 꽤 관련있는 단어들이 도출되었다고 볼 수 있겠습니다. 100만 문장 수준이라 썩 만족스럽지는 않지만요.

 

Dimension Reduction with ICA

 마지막으로 아까 한 문장에 대해 ICA와 SVD가 사뭇 다른 산점도를 반환했던 것에 이어, 더 큰 데이터로 결과를 비교해보겠습니다.

most similar - ICA

 이번엔 확실히 거의 같은 결과를 반환하는 것을 볼 수 있습니다. 즉, 차원 축소 기법에 따른 결과는 대동소이하며, 데이터의 양이 많을수록 더 좋은 품질의 분산 표현을 만들 수 있다고 정리해볼 수 있습니다.

728x90

'독서' 카테고리의 다른 글

Ch4. Word2Vec 속도 개선  (0) 2021.07.27
Ch3. Word2Vec  (0) 2021.07.26
Ch1. 신경망 복습  (0) 2021.07.24
Ch7. 합성곱 신경망  (0) 2021.07.22
Ch6. 학습 관련 기술들  (0) 2021.07.21
Comments