본문 바로가기

Natural_Language

[NLP] 03. 자연어 처리 개요 - 단어표현/단어임베딩/단어벡터

반응형

아래 내용은 텐서플로우와 머신러닝으로 시작하는 자연어처리

책을 바탕으로 작성 된 내용입니다.

 

단어 표현

- 어떤 방식으로 텍스트를 표현해야 자연어 처리 모델에 적용할 수 있을까에 대한 답을 찾는 것

- 단어표현 : 텍스트를 모델에 적용할 수 있게 언어적인 특성을 반영해서 단어를 수치화하는 방법을 찾는것

- 단어를 수치화할 때는 주로 벡터로 표현한다.

- 따라서 단어 표현 = 단어 임베딩 = 단어 벡터

 

원-핫 인코딩

- 단어를 하나의 벡터로 표현하는 방법인데, 각 값은 0혹은 1만 갖는다.

- 알 수 있는 벡터 값 가운데 하나만 1을 가지고, 나머지는 모두 0을 가지는 방식

- 여기서 1이 되는 것은 각 단어가 어떤 단어인지 알려주는 인덱스다.

- 즉, 원-핫 인코딩 방식은 각 단어의 인덱스를 정한 후 각 단어의 벡터를 그 단어에 해당하는 인덱스의 값을 1로 표현

 

- 단점 : 단어의 벡터의 크기가 너무 커지는 경우 공간을 많이 사용한다

         : 큰 공간에 비해 실제 사용하는 값은 1이 되는 값 하나뿐이므로 비효율적이다.

         : 단순히 단어가 뭔지만 알려주고, 벡터값 자체에는 단어의 의미나 특성이 전혀 표현 되지 않는다.

 

>> 위와 같은 단점을 해결하기 위해, 벡터의 크기가 작으면서도 벡터가 단어의 의미를 표현 할 수 있는 방법들이 제안되는데 이러한 방법들은 분포 가설을 기반으로 한다.

 

분포가설이란 "같은 문맥의 단어, 즉 비슷한 위치에 나오는 단어는 비슷한 의미를 가진다" 라는 개념이다.

 

>> 즉, 어떤 글에서 비슷한 위치에 나오는 단어는 단어 간의 유사도가 높다고 판단하는 방법인데,

     크게 카운트 기반 방법과 예측방법으로 나뉜다.

 

 

 

카운트 기반 방법

- 어떤 글의 문맥 안에 단어가 동시에 등장하는 횟수를 세는 방법

- 여기서 동시에 등장하는 횟수를 동시 출현 혹은 공기라고 부른다 : 영어로는 Co-occurrence

- 카운트 기반 방법에서는 기본적으로 동시 등장 횟수를 하나의 행렬로 나타낸 뒤 그 행렬을 수치화해서 단어 벡터로 만드는 방법을 사용하는 방식인데, 다음과 같은 방법이 있다.

 

특이값 분해( SVD ) / 잠재의미분석( LSA ) / HAL / Hellinger PCA

 

- 위의 방법은 모두 동시 출현 행렬(Co-occurrence Matrix)을 만들고 그 행렬들을 변형하는 방식이다.

- 동시 출현 행렬을 토대로 특이값 분해 방법을 사용해 단어 벡터를 만들면 된다.

- 이러한 카운트 기반 방법의 장점은 빠르다는 점

- 데이터가 많을 경우 잘 표현되고 효울적이다.

 

 

예측 기반 방법

- 예측 기반 방법이란 신경망 구조 혹은 어떠한 모델을 사용해 특정 문맥에서 어떤 단어가 나올지를 예측하면서 단어를 벡터로 만드는 방식이다.

 

Word2vec / NNLM( Nueral Network Language Model) / RNNLM ( Recurrent Neural Network Language ) 

 

- 여러 예측 기반 방법 중에서 단어 표현 방법으로 가장 많이 사용되는 Word2vec에 대해 알아본다

 

<Word2vec >

- 참고 논문 : Efficient Estimation of Word Representations in Vector Space(https://arxiv.org/pdf/1301.3781.pdf)

- Word2vec은 CBOW와 Skip-Gram이라는 두가지 모델로 나뉜다.

- 두 모델은 각각 서로 반대되는 개념으로 생각하면 된다.

 

CBOW : 어떤 단어를 문맥 안의 주변 단어들을 통해 예측하는 방법

- 주변 단어를 통해 하나의 단어를 예측하는 모델이다.

  ex ) 창욱은 냉장고에서 ____를 꺼내서 먹었다.

 

- 다음 문장의 빈칸을 채우는 모델이라고 생각하면 된다.

 

 

Skip-Gram : 어떤 단어를 가지고 특정 문맥안의 주변 단어를 예측하는 방법

- 하나의 단어를 가지고 주변에 올 단어를 예측하는 모델이다.

  ex ) __ ____ 음식을 ___ ____.

 

 

CODE >

from gensim.models import Word2Vec
embedding_model = Word2Vec( data,
                            size = 100,
                            window = 3, 
                            min_count=20, 
                            iter=100, 
                            sg=1)

- gensim 패키지의 Word2Vec 함수 사용

- 함수의 파라미터 값:

  1) size : 몇차원의 벡터로 변경할건지

  2) window : 주변 단어를 몇개까지 볼 것인지 

  3) min_count : 출현 빈도 최소 수

  4) iter : 몇번 반복해서 학습 할 건지

  5) sg : 방법론 2개중 무엇을 선택 할 건지 >> 0: CBOW, 1: Skip-Gram 

- 사용 가능한 함수:

  1) similarity : 두 단어의 유사도 계산 (인수로 2가지 단어를 준다)

  2) most_similar : 가장 유사한 단어를 출력 ( positive인수와 negetive인수를 사용하여 단어간 관계도 찾을 수 있다)

 

 

>> 두 모델은 위와 같이 단어들을 예측하면서 단어 벡터를 계속해서 학습한다. 모델의 전체적인 구조는 아래와 같다.

 

CBOW vs Skip-Gram

 

< 모델의 학습 방법 : CBOW >

1. 각 주변 단어들을 원 - 핫 벡터로 만들어 입력 값으로 사용한다 (입력층 벡터)

2. 가중치 행렬을 각 원-핫 벡터에 곱해서 N-차원 벡터를 만든다 (N-차원 은닉층)

3. 만들어진 N-차원 벡터를 모두 더한 후 개수로 나눠 평균 N-차원 벡터를 만든다(출력층 벡터)

4. N-차원 벡터에 다시 가중치 행렬을 곱해서 원-핫 벡터와 같은 차원의 벡터로 만든다

5. 만들어진 벡터를 실제 예측하려고 하는 단어의 원-핫 벡터와 비교해서 학습한다.

 

< 모델의 학습 방법 : Skip-Gram >

1. 하나의 단어를 원-핫 벡터로 만들어서 입력값으로 사용한다 (입력층 벡터)

2. 가중치 행렬을 원-핫 벡터에 곱해서 N-차원 벡터를 만든다 (N-차원 은닉층)'

3. N-차원 벡터에 다시 가중치 행렬을 곱해서 원-핫 벡터와 같은 차원의 벡터로 만든다 (출력층 벡터)

4. 만들어진 벡터를 실제 예측하려는 주변 단어들 각각의 원-핫 벡터와 비교해서 학습한다.

 

 

 

"

두 모델의 학습 과정이 비슷해 보이지만 확실한 차이점이 있다.

CBOW에서는 입력 값으로 여러단어를 사용하고, 학습을 위해 하나의 단어와 비교한다. 

 Skip-Gram에서는 입력값이 하나의 단어를 사용하고, 학습을 위해 주변 여러 단어와 비교한다.

"

 

 

< 학습 과정을 끝난 후>

- 각 가중치 행렬의 각 행을 단어 벡터로 사용한다.

- 두 모델의 장점은 기존의 카운트 기반 방법보다 단어 간의 유사도를 잘 측정한다.

- 또한 단어들의 복잡한 특징까지도 잘 잡아낸다.

- 이렇게 만들어진 단어 벡터는 서로에게 유의미한 관계를 측정할 수 있다.

( '엄마'와 '아빠'라는 단어의 벡터사이의 거리와 '여자'와 '남자'라는 단어의 벡터 사이의 거리가 같게 나온다)

- 보통은 Skip-Gram이 성능이 좋다.

반응형