rueki

텍스트 전처리 - 원-핫 인코딩(One-hot encoding) 본문

DL/NLP

텍스트 전처리 - 원-핫 인코딩(One-hot encoding)

륵기 2019. 7. 2. 10:04
728x90
반응형

본문은 https://wikidocs.net/22647 참고해서 작성한 글입니다.

 

원-핫 인코딩은 문자를 숫자로 바꾸는 기법 중 하나이며, 단어를 표현하는 가장 기본적인 방법이다.

원-핫 인코딩을 하기 앞서 단어집합을 만들어야하는데, 단어 집합은 서로 다른 단어들의 집합으로서, 중복값이

ㅇ없어야 한다.

 

단어집합의 크기를 벡터의 차원으로 하고, 표현하고 싶은 단어의 인덱스에 1의 값을 부여하고,

다른 인덱스에는 0을 부여하는 단어의 벡터 표현 방식이다.

1) 각 단어에 고유 인덱스 부여(정수 인코딩)

2) 표현하고자 하는 단어의 인덱스 위치에 1을 부여, 나머지 위치에는 0을 부여

 

한국어 문장에 원-핫 인코딩 진행을 해보자

from konlpy.tag import Okt
okt = Okt()
token = okt.morphs("나는 자연어 처리를 배운다")
print(token)
['나', '는', '자연어', '처리', '를', '배운다']

Okt 형태소 분석기를 통해 문장의 형태소 토큰화를 했다.

그 다음, 토큰에 대해 고유 인덱스를 부여하겠다.

word2index={}
for voca in token:
    if voca not in word2index.keys():
        word2index[voca] = len(word2index)

print(word2index)
{'나': 0, '는': 1, '자연어': 2, '처리': 3, '를': 4, '배운다': 5}
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)
[0, 0, 1, 0, 0, 0]

원-핫 인코딩 함수를 만들어서 진행한 결과, 자연어의 인덱스는 2이고,

해당 인덱스에대해 원-핫 벡터 값은 1이고 나머지는 0인것을 알 수가 있다.

 


케라스를 이용해서 원-핫 인코딩을 진행해보자.

케라스에서는 to_categorical()이라는 원-핫 인코딩에 유용한 도구를 지원한다.

 

from keras_preprocessing.text import Tokenizer
text = "나랑 점심 먹으러 갈래 점심 메뉴는 햄버거 갈래 갈래 햄버거 최고야"
t = Tokenizer()
t.fit_on_texts([text])# text를 []에 안 넣으면 한 글자 단위 인코딩이 된다.
print(t.word_index)
{'갈래': 1, '점심': 2, '햄버거': 3, '나랑': 4, '먹으러': 5, '메뉴는': 6, '최고야': 7}

단어 집합을 생성했고, 이제 인덱스로 변환이 가능하다. 단어 집합으로만 구성된 서브 텍스트를 가지고

정수 인코딩을 진행해보겠다.

text2 = "점심 먹으러 갈래 메뉴는 햄버거 최고야"
x = t.texts_to_sequences([text2])
print(x)
[[2, 5, 1, 6, 3, 7]]

정수 인코딩 된 결과를 입력으로 해서 원-핫 인코딩을 to_categorical()을 통해 진행해보겠다.

vocab_size = len(t.word_index)
from keras.utils import to_categorical
x = to_categorical(x, num_classes=vocab_size+1)
print(x)
[[[0. 0. 1. 0. 0. 0. 0. 0.]
  [0. 0. 0. 0. 0. 1. 0. 0.]
  [0. 1. 0. 0. 0. 0. 0. 0.]
  [0. 0. 0. 0. 0. 0. 1. 0.]
  [0. 0. 0. 1. 0. 0. 0. 0.]
  [0. 0. 0. 0. 0. 0. 0. 1.]]]

t.fit_on_texts()는 인덱스를 1부터 부여하지만, 배열의 인덱스는 0부터 부여하기에 크기를 +1 시켜주어야 한다.

원-핫 인코딩은 기본적으로 단어 간 유사성을 표한하지 못한다. 즉 연관 검색이 불가능 하다는 것이다.

이러한 단점을 없애기위해 단어의 의미를 다차원 공간에 벡터화 하는 기법이 있다.

1) 카운트 기반으로 단어의 의미 벡터화 - LSA, HAL

2) 예측 기반으로 단어의 의미 벡터화 - NNLM, RNNLM, Word2Vec, FastText

3) 두 가지 모두 사용 -> Glove

728x90
반응형
Comments