출처 : 텐서플로와 머신러닝으로 시작하는 자연어 처리, https://wikidocs.net/31767
단어 표현은 모든 자연어 처리 문제의 기본 바탕이 되는 개념이다. 기존에 컴퓨터는 텍스트를 유니코드 혹은 아스키 코드 방식으로 인식했다. 이 방법을 사용하면 텍스트를 이진화 된 값으로 인식한다. 이 경우 언어적인 특성이 전혀 없이 컴퓨터가 문자를 인식하기 위해 만들어진 값이므로 자연어 처리를 위해 만드는 모델에 적용하기에 부적합하다.
어떤 방식으로 텍스트를 표현해야 자연어 처리 모델에 적용할 수 있을까?
단어의 표현 방법은 크게 두 가지가 있다.
1. 국소 표현 (Local Representation)방법
2.분산 표현(Distributed Representation)방법
여기서는 국소표현방법으로 one-hot-encoding만 다루도록 하겠다.
단어를 표현하는 가장 기본적인 방법은 원-핫 인코딩(one-hot encoding) 방식이다. 각 단어의 인덱스를 정한 후 각 단어의 벡터를 그 단어에 해당하는 인덱스의 값을 1로 표현하는 방식이다.
예시
(포도,딸기,수박,레몬,망고) 라는 단어를 알려야 한다고 했을 때 원-핫 인코딩 방식으로 표현하면 각 단어를 표현하는 벡터의 크기는 5가 된다.각 단어는 이 중에서 하나만 1이 된다.
포도는 [1,0,0,0,0], 딸기는 [0,1,0,0,0],수박은 [0,0,1,0,0], 레몬은 [0,0,0,1,0], 망고는 [0,0,0,0,1]으로 표현한다.
코드
토큰화된 단어들에 대해서 고유의 인덱스를 부여한다.
token = ['포도', '딸기', '수박', '레몬', '망고']
word2index={}
for voca in token:
if voca not in word2index.keys():
word2index[voca]=len(word2index)
print(word2index)
결과
{'포도': 0, '딸기': 1, '수박': 2, '레몬': 3, '망고': 4}
토큰을 입력하면 해당 토큰에 대한 원-핫 벡터를 만들어내는 함수를 만든다.
def one_hot_encoding(word, word2index):
one_hot_vector = [0]*(len(word2index))
index=word2index[word]
one_hot_vector[index]=1
return one_hot_vector
one_hot_encoding("포도",word2index)
결과
[1, 0, 0, 0, 0]
이 밖에도 케라스의 to_categorical()을 이용해 원-핫 인코딩을 할 수 있다. (참고 https://wikidocs.net/22647)
장점
단점
이 문제를 해결하기 위해 벡터의 크기가 작으면서도 벡터의 단어의 의미를 표현할 수 있는 방법들이 제안되었다. 이러한 방법들은 분포가설(Distributed hypothesis)을 기반으로 한다.
분포가설이란 "같은 문맥의 단어, 즉 비슷한 위치에 나오는 단어는 비슷한 의미를 가진다."라는 개념이다.
분포가설을 기반으로 하는 벡터의 크기가 작으면서도 단어의 의미를 표현할 수 있는 방법은 크게 두 가지 방법으로 나뉜다.
카원트 기반 방법은 기본적으로 동시 출현 행렬(Co-occurence Matrix)을 만들고 그 행렬들을 변형하는 방식을 사용한다.
여기서는 동시 출현 행렬까지만 다루도록 하겠다.
동시출현(공기, Co-occurrence) : 단어들이 동시에 등장하는 횟수
동시 출현 횟수를 하나의 행렬로 나타낸 뒤 그 행렬을 수치화해서 단어 벡터로 만드는 방법
동시 출현 행렬 (Co-occurrence Matrix)
아래의 예시문장으로 동시 출현 행렬을 만들어보자.
나의 취미는 영화 보기 입니다.
내 취미는 넷플릭스 보기이다.
나의 취미는 유튜브 보기 입니다.
나의 | 내 | 취미는 | 영화 | 넷플릭스 | 유튜브 | 보기 | 입니다. | 이다. | |
---|---|---|---|---|---|---|---|---|---|
나의 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 |
내 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
취미는 | 2 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 |
영화 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
넷플릭스 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
유튜브 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
보기 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 2 | 1 |
입니다. | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
이다. | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
이렇게 만들어진 동시 출현 행렬을 토대로 특이값 분해를 하거나 단어 벡터를 만든다.
장점
예측 기반 방법은 신경망 구조 혹은 어떠한 모델을 사용해 특정 문맥에서 어떤 단어가 나올지를 예측하면서 단어를 벡터로 만드는 방식이다.
참고 : <한국어 임베딩> 이기창
벡터 공간Vector으로 + 끼워넣는다embed = Embedding
단어난 문장 각각을 벡터로 변환하는 일련의 과정 전체를 가리키는 용어이다.
임베딩이 중요한 이유는 전이학습 transfer learning 때문이다. 대규모 말뭉치 corpus를 미리 학습 pretrain한 임베딩을 모델의 입력값으로 사용하고, 모델이 task를 잘 수행할 수 있도록 업데이트 fine-tuning하는 방식을 썼을때 성능이 좋다.
Word2vec는 워드 임베딩 방법중 하나이다. 임베딩은 단어를 밀집 표현(희소 표현과 반대되는 표현)으로 변환하여 벡터화 한다. Word2vec은 CBOW(Continuous Bag of Words) 와 Skip-Gram 두가지 모델로 나뉜다.
원-핫 벡터는 단어 간 유사도를 계산할 수 없지만 Word2vec을 사용하면 단어 간 유사도를 반영할 수 있도록 단어의 의미를 벡터화 할 수 있다.
희소 표현(Sparse Representation)
벡터 또는 행렬(matrix)의 값이 대부분이 0으로 표현되는 방법. (각 단어간 유사성을 표현할 수 없음.)
ex. 원-핫 벡터 = 희소 벡터(sparse vector)
분산 표현(Distributed Representation)
단어의 '의미'를 다차원 공간에 벡터화하는 방법
분산 표현을 이용하여 단어의 유사도를 벡터화하는 작업은 워드 임베딩(embedding) 작업에 속함.
분포 가설을 이용하여 단어들의 셋을 학습하고, 벡터에 단어의 의미를 여러 차원에 분산하여 표현
저차원에 단어의 의미를 여러 차원에다가 분산하여 표현
단어 간 유사도를 계산 가능
CBOW
: 어떤 단어를 문맥 안의 주변 단어들을 통해 예측하는 방법
<고양이가 생선을 먹는다.> 라는 문장에서 주변 단어를 통해 <생선>이라는 하나의 단어를 예측하는 모델이다.
학습 방법
Skip-Gram
: 어떤 단어를 가지고 특정 문맥 안의 주변 단어들을 예측하는 방법
<고양이가 생선 을 먹는다.>
<생선>이라는 단어를 가지고 주변에 올 단어를 예측하는 모델이다.
학습 방법