딥 러닝을 이용한 자연어처리 입문1. 텍스트 전처리(5)

정선용·2021년 8월 16일
0

token화-> 정제(불용어..)/정규화(형태소분석)에대한 방법론까지 알아봤는데,
이를 위해 텍스트 전처리에서 자주 사용되는 도구들을 알아볼것

1. 정규표현식 Regular Expression

1.1 정규표현식 문법

특수문자description
.한 개의 임의의 문자
?문자가 0개 또는 1개
*문자가 0개 이상
+문자가 1개 이상
^뒤의 문자로 문자열이 시작
$앞의 문자로 문자열이 끝
{숫자}숫자만큼 반복
{숫자1,숫자2}숫자1 이상 숫자2 이하만큼 반복
{숫자,}숫자 이상만큼 반복
[]대괄호 안의 문자들 중 한 개의 문자와 매치
[^문자]해당 문자를 제외한 문자를 매치
|또는 기호

2. 정수 인코딩 Integer Encoding

2.1 dictionary

# 정제와 단어 토큰화
vocab = {} # 파이썬의 dictionary 자료형
sentences = []
stop_words = set(stopwords.words('english'))

for i in text:
    sentence = word_tokenize(i) # 단어 토큰화를 수행합니다.
    result = []

    for word in sentence: 
        word = word.lower() # 모든 단어를 소문자화하여 단어의 개수를 줄입니다.
        if word not in stop_words: # 단어 토큰화 된 결과에 대해서 불용어를 제거합니다.
            if len(word) > 2: # 단어 길이가 2이하인 경우에 대하여 추가로 단어를 제거합니다.
                result.append(word)
                if word not in vocab:
                    vocab[word] = 0 
                vocab[word] += 1
    sentences.append(result) 
print(sentences)
print(vocab)
------------------------------------------------------------------------
[['barber', 'person'], ['barber', 'good', 'person'], ['barber', 'huge', 'person'], ['knew', 'secret'], ['secret', 'kept', 'huge', 'secret'], ['huge', 'secret'], ['barber', 'kept', 'word'], ['barber', 'kept', 'word'], ['barber', 'kept', 'secret'], ['keeping', 'keeping', 'huge', 'secret', 'driving', 'barber', 'crazy'], ['barber', 'went', 'huge', 'mountain']]

{'barber': 8, 'person': 3, 'good': 1, 'huge': 5, 'knew': 1, 'secret': 6, 'kept': 4, 'word': 2, 'keeping': 2, 'driving': 1, 'crazy': 1, 'went': 1, 'mountain': 1}

=> vocab에서 빈도수가 높은 순서대로 정렬 후, 높은 빈도수를 가진 단어에 낮은 정수 인덱스 부여.

{'barber': 1, 'secret': 2, 'huge': 3, 'kept': 4, 'person': 5, 'word': 6, 'keeping': 7}

자연어 처리 과정에서, 텍스트 데이터에 있는 단어를 모두 사용하기 보다는 빈도수가 가장 높은 n개의 단어만 사용하고자 하는 경우가 多
=>example) 상위 5개까지만 index부여, 나머지는 모두 index 6(OOV)

encoded = []
for s in sentences:
    temp = []
    for w in s:
        try:
            temp.append(word_to_index[w])
        except KeyError:
            temp.append(word_to_index['OOV'])
    encoded.append(temp)
print(encoded)
-----------------------------------------------
[[1, 5], [1, 6, 5], [1, 3, 5], [6, 2], [2, 4, 3, 2], [3, 2], [1, 4, 6], [1, 4, 6], [1, 4, 2], [6, 6, 3, 2, 6, 1, 6], [1, 6, 3, 6]]

=> 첫 sentences에서 정수인코딩된 value로 매핑 / 상위 5개 빈도가 아닌 단어는 6으로 매핑.

2.2 counter

위의 방법은 일일이 손으로 코딩을 해준거고, python collection의 counter를 이용해보자.

from collections import Counter
words = sum(sentences, [])
# 위 작업은 words = np.hstack(sentences)로도 수행 가능.
vocab = Counter(words) # 파이썬의 Counter 모듈을 이용하면 단어의 모든 빈도를 쉽게 계산할 수 있습니다.
print(vocab)
---------------------------------------------------------------------------
Counter({'barber': 8, 'secret': 6, 'huge': 5, 'kept': 4, 'person': 3, 'word': 2, 'keeping': 2, 'good': 1, 'knew': 1, 'driving': 1, 'crazy': 1, 'went': 1, 'mountain': 1})

=> 이후 목적에 따라 정렬 후 높은빈도수대로 잘라 인덱스 부여

2.3 NLTK의 FreqDist

NLTK에서 제공하는 빈도수 계산 도구를 이용

from nltk import FreqDist
import numpy as np
# np.hstack으로 문장 구분을 제거하여 입력으로 사용 . ex) ['barber', 'person', 'barber', 'good' ... 중략 ...
vocab = FreqDist(np.hstack(sentences))
vocab_size = 5
vocab = vocab.most_common(vocab_size) # 등장 빈도수가 높은 상위 5개의 단어만 저장

word_to_index = {word[0] : index + 1 for index, word in enumerate(vocab)}
print(word_to_index)
------------------------------------------------------------
{'barber': 1, 'secret': 2, 'huge': 3, 'kept': 4, 'person': 5}

편리하다.

  • keras에서도 텍스트 전처리 도구를 제공한다.
from tensorflow.keras.preprocessing.text import Tokenizer
tokenizer = Tokenizer()
tokenizer.fit_on_texts(sentences) # fit_on_texts()안에 코퍼스를 입력으로 하면 빈도수를 기준으로 단어 집합을 생성한다.
print(tokenizer.word_index)
---------------------------------------
{'barber': 1, 'secret': 2, 'huge': 3, 'kept': 4, 'person': 5, 'word': 6, 'keeping': 7, 'good': 8, 'knew': 9, 'driving': 10, 'crazy': 11, 'went': 12, 'mountain': 13}

print(tokenizer.word_counts)
-----------------------------------------
OrderedDict([('barber', 8), ('person', 3), ('good', 1), ('huge', 5), ('knew', 1), ('secret', 6), ('kept', 4), ('word', 2), ('keeping', 2), ('driving', 1), ('crazy', 1), ('went', 1), ('mountain', 1)])

필요시 찾아서 사용하자

3. 패딩 Padding

  • 패딩 : 각 문장의 서로 길이가 서로 다른경우가 많은데, machine에서는 길이가 전부 동일한 문서들에 대해서 하나의 행렬로 보고, 한꺼번에 묶어서 처리할 수 있어 병렬 연산을 위해서 여러 문장의 길이를 임의로 동일하게 맞춰주는 작업

4. 원핫 인코딩 One-hot Encoding

  • 원 핫 인코딩 : 단어 집합의 크기를 벡터의 차원으로 하고, 표현하고 싶은 단어의 인덱스에 1의 값을 부여하고, 다른 인덱스에는 0을 부여하는 단어의 벡터 표현 방식, 이 때 벡터= One-Hot vector

  • 과정
    (1) 각 단어에 고유한 인덱스를 부여(정수 인코딩)
    (2) 표현하고 싶은 단어의 인덱스의 위치에 1을 부여하고, 다른 단어의 인덱스의 위치에는 0을 부여.

5. 데이터 분리 Splitting

6. 한국어 전처리 패키지

6.1. PyKoSpacing
6.2. Py-Hanspell
6.3. SOYNLP를 이용한 단어 토큰화 / 반복되는 문자 정제
6.4. Customized KoNLPy

필요시 정리

profile
정선용

0개의 댓글