데이터 전처리 과정

개요

NLP에서 데이터 전처리 과정이란, 보편적으로 텍스트 전처리(Text preprocessing) 과정을 뜻한다. 본문 서에서는 크롤링 등으로 얻어낸 코퍼스 데이터를 사용하고자 하는 용도에 맞게 토큰화(tokenization) & 정제(cleaning) & 정규화(normalization)을 과정에 대하여 다룬다.

단어 토큰화(Word Tokenization)

본 프로젝트에서는 해당 자연어에 대한 토큰화 기준으로 단어로 결정하였다.

고려 사항

두점이나 특수 문자 단순 제외 X

구두점을 포함한 여러 특수 문자는 해당 단어의 뜻을 내포하고 있는 구분자로 충분히 사용될 수 있기 때문에 해당 문자에 대한 단순한 제거 처리를 수행해선 안된다.

줄임말과 단어 내에 띄어쓰기

영어권에서는 언어 ['] 문자를 사용하여 단어를 압축한다. 이러한 상황 외에도 한국어에는 여러 줄임말이 존재하며, 해당 단어에 대한 전처리 작업을 신중하게 진행해야 한다.

한국어는 단어의 순서가 중요하지 않음

한국어에서는 어순이 중요하지 않다. 이전 단어가 주어 졌을때, 다음 단어가 나타날 확률을 구해야 하는데 어순이 중요하지 않다는 것은 어떤 단어든 나타나도 된다는 의미이기 때문에 다음 단어를 예측하는 모델에서 한국어는 다른 언어들과 큰 차이를 보여준다.

교착어

한국어는 부사를 비롯한 관련 단어와 함께 붙여서 뜻을 이루게 되는 교착어이다. 이는 모델의 학습 과정에서 상당히 까다로운 부분으로 작용되며, 단어의 전처리를 수행할 경우, 각 단어의 의존 부사 등을 모두 떼어내 줄 필요가 있다.

한국어는 띄어쓰기가 제대로 지켜지지 않음

한국어는 언어의 특성상 띄어쓰기를 제대로 하지 않아도 의미가 전달되며, 띄어쓰기 규칙 또한 상대적으로 까다로운 언어로 취급되고 있다.

정제(Cleaning) & 정규화(Normalization)

한 문서, 문장 단위에서 토큰화를 수행한 하나의 묶음을 보편적으로 코퍼스라고 정의한다. 코퍼스에서 용도에 맞게 토큰을 분류하는 작업을 토큰화(tokenization)라고 하며, 토큰화 작업 전, 후에는 텍스트 데이터를 용도에 맞게 정제(cleaning) 및 정규화(normalization) 과정을 함께 수행해주어야 한다.

  • 정제(cleaning) : 갖고 있는 코퍼스로부터 노이즈 데이터를 제거한다.

  • 정규화(normalization) : 표현 방법이 다른 단어들을 통합시켜서 같은 단어로 만들어준다

규칙에 기반한 표기가 다른 단어들의 통합

예를 들어 미국을 뜻하는 USA와 US는 같은 의미를 가지므로 이 두 단어를 하나의 의미로 정규화할 과정이 필요하다.

대소문자 통합

한국어에는 이러한 개념이 존재하지 않지만, 함께 사용되는 영어에서 대소문자의 차이라 같은 단어를 다른 토큰으로 인식해버릴 수 있기 때문에 그에 대한 통합 과정이 필요하다.

불용어(Noise Data) 제거

연어가 아니면서 아무 의미도 갖지 않는 글자들(특수 문자 등)이나, 분석하고자 하는 목적에 맞지 않는 불필요한 모든 단어를 제거해야 한다.

등장 빈도가 적은 단어

텍스트 데이터에서 너무 적게 등장해서 자연어 처리에 도움이 되지 않는 단어들이 존재하며, 이러한 단어들은 모델에 악영향을 끼칠 수 있으므로 제거 해주어야한다.

길이가 너무 짧거나 긴 단어

단정적으로 말할 수는 없지만 보편적으로 너무 짧은 단어나 너무 긴 단어들은 해당 토픽에 기여를 할 확률이 상대적으로 적어진다. 그러므로 이러한 단어를 삭제하는 것만으로도 어느정도 자연어 처리에서 크게 의미가 없는 단어들을 제거하는 효과를 볼 수 있다.

간단한 토크나이저 구현 예제

정수 인코딩(Integer Encoding)

위의 규정을 반영하여 정제된 코퍼스가 도출되었다면, 이번에는 컴퓨터가 해당 단어들을 인식할 수 있도록 각 단어를 숫자로 인코딩하는 과정이 필요하다. 이 과정을 통해 각 단어들은 고유의 식별 값을 부여받게 되며, 해당 값을 통해 더 빠른 연산을 수행할 수 있다.

Code

from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from collections import Counter
vocab=Counter() # 파이썬의 Counter 모듈을 이용하면 단어의 모든 빈도를 쉽게 계산할 수 있습니다.  

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)
                vocab[word]=vocab[word]+1 #각 단어의 빈도를 Count 합니다.
    sentences.append(result) 
print(sentences)
print(vocab)

Output

다음과 같은 코드를 통해 2-gram으로 토큰화시킨 리스트를 생성하였다.

[['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), ('secret', 6), ('huge', 5), ('kept', 4), ('person', 3), ('word', 2), ('keeping', 2), ('good', 1), ('knew', 1), ('driving', 1), ('crazy', 1), ('went', 1), ('mountain', 1)]

Last updated