Search
Duplicate

5-1 단어 임베딩의 중요성

우리가 사용하는 자연어인 텍스트를 프로그램이 이해하고 머신러닝 알고리즘에 사용하기 위해서는 이를 수치화하는 과정이 필요합니다. 주로 머신러닝 알고리즘은 텍스트를 단어 단위로 구분하여 학습과 분석에 활용합니다. 컴퓨터가 효율적으로 연산을 수행할 수 있는 행렬의 형태로 데이터를 구성하기 위해, NLP 분야에서는 단어를 벡터로 표현하는 방식을 주로 사용합니다.
단어를 벡터의 형태로 표현하기 위해 전통적으로는 원-핫 인코딩을 통한 벡터화 방식을 사용하였습니다.

전통적인 방식 : 원-핫 벡터 표현 (One-Hot Encoding)

원-핫 벡터 표현방식은 단어마다 대응하는 벡터를 하나씩 만드는 방식입니다. 일종의 어휘 사전을 만들면서 각 단어에 대응하는 의미를 하나씩 만드는 것과 비슷합니다.
다음 문장을 원-핫 벡터 표현 방식으로 나타내보겠습니다.
Let’s study with Deep Daiv
오른쪽 표에서 볼 수 있는 것 처럼, 문장에 등장하는 단어의 종류만큼 0으로 채워진 벡터가 생성되고, 각 단어마다 고유하게 부여되는 1의 위치에 의해 단어를 구분할 수 있습니다.
만약 ‘Daiv’ 라는 단어의 벡터만 확인한다면 오른쪽의 벡터처럼, 하나의 차원만 1이고 나머지는 0을 갖는 벡터의 형태로 표현될 것입니다.
원-핫 벡터 방식으로 표현한다면 단어의 의미를 담고있는 가중치 행렬에서 행렬곱만으로도 해당 단어의 의미를 쉽게 가져올 수 있다는 장점이 있습니다. 그러나, 단어마다 벡터의 길이가 하나씩 증가하기 때문에, 여러 문서에 등장하는 단어들을 모두 원-핫 인코딩으로 벡터화하면 의미 없는 값이 너무 많은 희소 표현이 되어버린다는 단점이 있습니다.
원-핫 인코딩 방식에서는 각 단어마다 자리가(혹은 번호가) 정해져있으니, 이를 이용해 문장이나 문서에 어떤 단어들이 얼마나 들어가는지에 대한 빈도 정보를 활용할 수도 있습니다.
이번에는 Let’s study with Deep Daiv machine learning study 라는 문장과 다른 문장에서 추가로 인코딩한 단어들이 포함된 원-핫 벡터 리스트가 있다고 합시다. 위 문장은 아래와 같은 벡터로 표현할 수도 있습니다. 이를 문서 빈도(Term-Frequency / TF) 라고 표현합니다. 각 단어가 문장에서 0회, 1회, 또는 2회 등장하였고 이 정보를 활용하여 문장을 벡터로 표현할 수 있습니다. 각 단어가 등장한 횟수를 세어(count) 벡터로 표현하기 때문에, TF 기반의 표현 방식을 카운트 기반 표현이라고 말합니다.
TF 방식을 통해 문장을 벡터로 표현한다면 서로 다른 문장이 똑같은 단어를 얼마나 많이 포함하는지에 대한 정보를 통하여, 앞서 확인한 원-핫 인코딩 방식에서는 찾을 수 없었던 서로 다른 문장 간의 ‘유사성'을 표현할 수 있게됩니다.

단어 임베딩

앞서 살펴본 카운트 기반의 TF 방식에서는 문장이나 단어의 중요한 의미나 내용이 여러 차원에 분산되어서 표현됩니다. TF 방식에서 한 문장에 여러 차원에 분산되어 표현된 것 처럼, 단어 역시 단순히 한 차원에 매핑되는 것이 아니라, 그 의미가 여러 차원에 분산되어 표현될 수 있습니다. 이러한 방식으로 단어나 문장을 표현하는 것을 분산적 표현(distributional representation)이라고 칭하며, 단어를 더 적은 차원에 분산하여 의미를 표현해내는 것을 단어 임베딩(word embedding)이라고 합니다.
각 단어를 하나의 차원에 매핑하여 벡터로 표현하는 것이 아니라 여러 차원에 의미나 속성을 분산하여 담고 표현한다면, 똑같은 개수의 단어를 훨씬 낮은 차원으로 표현이 가능합니다. 원-핫 인코딩 방식에서 100개의 차원으로 100개의 단어의 의미를 표현할 수 있었다면, 분산적 표현 방식에서는 100개의 차원으로 10,000개~100,000개의 단어의 의미를 표현해낼 수 있습니다.
오른쪽 이미지처럼, 임베딩된 단어는 앞서 본 Daiv 단어의 원-핫 벡터와 다르게, 모든 차원에 걸쳐 단어의 의미를 표현하고 있습니다. 이처럼 모든 차원에 0이 아닌 실수값을 갖는 표현 방식을 밀집 표현(dense representation) 이라고 합니다.

단어 임베딩을 배우는 이유

적은 차원 내에서 단어를 밀집 표현으로 나타낸다면 전통적인 원-핫 인코딩 등의 방식과 비교해 몇가지 장점을 가집니다.

1. 계산이 효율적이다.

연산을 수행해야 하는 벡터와 행렬의 차원을 줄여서, 연산량을 크게 감소시켜 계산을 효율적이고 빠르게 수행할 수 있습니다. 단순히 생각해봐도, 100x100 크기를 갖는 행렬 2개를 내적하는 연산과 10x10 크기의 두 행렬의 내적 연산의 연산량은 1,000배나 차이납니다.

2. 통계적 장점을 공유하기 원활하다.

일반적인 문장이나 문서에서는 사전에 있는 대부분의 단어를 사용하지 않을 것이기 때문에, 문서빈도(TF)를 통해 여러 문장 또는 문서의 단어 통계를 분석할 때, 문장에 대한 TF 벡터는 희소행렬(유의미한 값보다 0인 값이 더 많은 행렬)일 가능성이 매우 높습니다. 이러한 경우에는 계산량도 많이 잡아먹고 메모리도 낭비하게 되어 매우 비효율적이게 됩니다.
단어 임베딩을 통해 차원을 축소한 경우, 특이값 분해 등의 수학적 기법을 통해 통계 정보를 분석하고 활용하는 것이 더욱 효율적이게 된다.

3. 최적화가 가능하다.

원-핫 인코딩 방식처럼 너무 많은 차원을 가진 데이터를 사용하면 차원의 저주 등의 문제로 머신러닝의 최적화에서 문제가 발생할 수 있습니다. 단어 임베딩을 통해 차원을 축소하여, 저차원의 데이터를 입력으로 넣어야 원활한 학습 및 task처리가 가능합니다.
차원의 저주 차원의 저주는 학습 데이터의 수보다 차원의 수가 더 많아지면서 성능이 저하되는 현상을 말합니다. 데이터의 양에 비해 차원이 쓸데없이 많아지게 되면 그만큼 데이터 표현에서 빈 공간이 많아지면서 계산 성능도 떨어지고, 데이터에 대한 설명도 부족해지게 됩니다. 일반적으로 차원의 저주를 특이값 분해(SVD)나 주성분 분석(PCA) 등의 차원 축소 기법을 통해 해결하지만, 차원의 개수가 일반적으로 수백만개가 넘어가는 NLP 분야에서는 이러한 해결 방식이 잘 적용되지 않습니다.
단어를 임베딩했을 때, 각 단어 벡터는 유사한 의미를 갖는 단어끼리 같은 공간 내에 유사한 위치에 놓이게 됩니다. 또, 단어끼리의 관계는 단어간의 방향과 거리에 의해 나타내질 수 있습니다. 아래 그림은 2차원으로 축소하여 간략하게 단어 임베딩을 설명하기 위한 그림입니다.
위 그림에서 볼 수 있듯이, 동물에 대한 단어는 동물끼리, 나라에 대한 단어는 나라끼리, 가족 명칭에 대한 단어는 가족 명칭끼리 모여있는 것을 확인할 수 있습니다. 유사한 카테고리의 단어들은 비슷한 의미를 갖는다고 판단하여, 근처에 배치되게 됩니다.
또, 단어간의 관계는 두 단어 사이의 방향과 거리에 의해 나타내어집니다. 가운데 아래에 보이는 he-himself 단어간의 관계는 she-herself와 동일하므로, 두 단어쌍 사이의 선의 방향과 크기가 비슷한 것을 볼 수 있습니다. 이는 오른쪽의 형용사의 원급/비교급/최상급이나 왼쪽의 man-king, woman-queen에서도 확인할 수 있습니다.
아래 링크의 홈페이지는 한국어로 구현한 단어 임베딩에 대한 방식입니다. 직접 해볼 수 있으니, 재미로 한 번 단어간의 덧셈과 뺄셈을 시도해보길 바랍니다!
다음 글에서는 단어 임베딩에 대해 직접 코드를 작성하고 구현하여 시도해볼 것입니다.