본문 바로가기

딥러닝/[딥 러닝을 이용한 자연어 처리 입문]딥러닝

정수 인코딩(Integer Encoding)

컴퓨터는 텍스트보다는 숫자를 더 잘 처리 할 수 있음

각 단어를 고유한 정수에 맵핑(mapping)시키는 전처리 작업 진행

랜덤으로 부여하기도 하지만, 보통은 단어 등장 빈도수를 기준으로 정렬한 뒤에 부여합니다.

 

1. 정수 인코딩(Integer Encoding)

단어를 빈도수 순으로 정렬한 단어 집합(vocabulary)을 만들고, 빈도수가 높은 순서대로 차례로 낮은 숫자부터 정수를 부여

 

1) dictionary 사용하기

문장 토큰화 수행

이제 정제 작업과 정규화 작업을 병행하며, 단어 토큰화를 수행합니다. 

단어들을 소문자화하여 단어의 개수를 통일시키고, 불용어와 단어 길이가 2이하인 경우에 대해서 단어를 일부 제외시켜주었습니다. 

 vocab에는 각 단어에 대한 빈도수가 기록되어있음

파이썬의 딕셔너리 구조로 단어를 키(key)로, 단어에 대한 빈도수가 값(value)으로 저장되어져 있습니다

빈도수가 높은 순으로 정렬

높은 빈도수를 가진 단어일수록 낮은 정수를 부여합니다. 정수는 1부터 부여합니다.

빈도수가 적은 단어를 제외시키는 작업을 수행했습니다.

이처럼 단어 집합에 존재하지 않는 단어들이 생기는 상황을 Out-Of-Vocabulary(단어 집합에 없는 단어) 문제라고 합니다. 약자로 'OOV 문제'라고도 합니다.

word_to_index에 'OOV'란 단어를 새롭게 추가하고, 단어 집합에 없는 단어들은 'OOV'의 인덱스로 인코딩하겠습니다.

이제 word_to_index를 사용하여 sentences의 모든 단어들을 맵핑되는 정수로 인코딩하겠습니다

2)counter 사용하기

현재 sentences는 단어 토큰화가 된 결과가 저장되어져 있습니다.

단어 집합(vocabulary)을 만들기 위해서 sentences에서 문장의 경계인 [, ]를 제거하고 단어들을 하나의 리스트로 만들겠습니다.

이를 파이썬의 Counter()의 입력으로 사용하면 중복을 제거하고 단어의 빈도수를 기록합니다.

단어를 키(key)로, 단어에 대한 빈도수가 값(value)으로 저장되어져 있습니다.

vocab에 단어를 입력하면 빈도수를 리턴합니다.

most_common()는 상위 빈도수를 가진 주어진 수의 단어만을 리턴합니다.

이를 사용하여 등장 빈도수가 높은 단어들을 원하는 개수만큼만 얻을 수 있습니다. 

 

이제 높은 빈도수를 가진 단어일수록 낮은 정수 인덱스를 부여합니다.

 

3) NLTK의 FreqDist 사용하기

NLTK에서는 빈도수 계산 도구인 FreqDist()를 지원합니다.

단어를 키(key)로, 단어에 대한 빈도수가 값(value)으로 저장되어져 있습니다.

vocab에 단어를 입력하면 빈도수를 리턴합니다.

 most_common()는 상위 빈도수를 가진 주어진 수의 단어만을 리턴합니다.

이를 사용하여 등장 빈도수가 높은 단어들을 원하는 개수만큼만 얻을 수 있습니다

enumerate()를 사용하여 좀 더 짧은 코드로 인덱스를 부여하겠습니다.

4)enumerate 이해하기

enumerate()는 순서가 있는 자료형(list, set, tuple, dictionary, string)을 입력으로 받아 인덱스를 순차적으로 함께 리턴한다

2. 케라스(Keras)의 텍스트 전처리

 정수 인코딩을 위해서 케라스의 전처리 도구인 토크나이저를 사용

fit_on_texts는 입력한 텍스트로부터 단어 빈도수가 높은 순으로 낮은 정수 인덱스를 부여

word_index를 사용하면 각 단어의 빈도수가 높은 순서대로 인덱스가 부여된 것을 확인할 수 있습니다.

각 단어가 카운트를 수행하였을 때 몇 개였는지를 보고자 한다면 word_counts를 사용합니다.

texts_to_sequences()는 입력으로 들어온 코퍼스에 대해서 각 단어를 이미 정해진 인덱스로 변환합니다.

 

케라스 토크나이저에서는 tokenizer = Tokenizer(num_words=숫자)와 같은 방법으로 빈도수가 높은 상위 몇 개의 단어만 사용하겠다고 지정할 수 있습니다.

num_words에서 +1을 더해서 값을 넣어주는 이유는 num_words는 숫자를 0부터 카운트합니다.

실질적으로 숫자 0에 지정된 단어가 존재하지 않는데도 케라스 토크나이저가 숫자 0까지 단어 집합의 크기로 산정하는 이유는 자연어 처리에서 패딩(padding)이라는 작업 때문입니다.

word_index와 word_counts에서도 지정된 num_words만큼의 단어만 남기고 싶다면 아래의 코드도 방법입니다.

 

케라스 토크나이저는 기본적으로 단어 집합에 없는 단어인 OOV에 대해서는 단어를 정수로 바꾸는 과정에서 아예 단어를 제거한다

단어 집합에 없는 단어들은 OOV로 간주하여 보존하고 싶다면 Tokenizer의 인자 oov_token을 사용합니다.

 

만약 oov_token을 사용하기로 했다면 케라스 토크나이저는 기본적으로 'OOV'의 인덱스를 1로 합니다.

이제 코퍼스에 대해서 정수 인코딩을 진행합니다.

빈도수 상위 5개의 단어는 2 ~ 6까지의 인덱스를 가졌으며, 그 외 단어 집합에 없는 단어들은 전부 'OOV'의 인덱스인 1로 인코딩되었습니다.