NLP - 텍스트 데이터 전처리

Michael Kim·2022년 6월 21일
0

0. Intro

이전까지 Vision 관련 데이터 및 모델만 다뤄왔다. NLP에 대해서도 궁금한 점이 많이 있었지만, 공부해볼 기회가 따로 없었기에 미루고만 있었다. 그리고 얼마 전에 관심 있는 회사에서 NLP관련 과제 테스트를 요청했고, 드디어 NLP 공부할 기회가 생겼다!

먼저 항상 궁금했던 것은 '어떻게 자연어를 컴퓨터가 이해할 수 있을까'였다. 영상 관련 데이터는 여러 컬러 정보를 수치화하여 데이터를 표현할 수 있다고 하지만, NLP에서 어떻게 자연어 데이터를 수치화할 수 있는걸까?

1. Tokenizer

토큰화란 주어진 말뭉치(corpus)를 의미있는 단위로 나누는 작업을 뜻한다. 그리고 나눠진 것을 토큰(token)이라고 한다.

토큰화의 주목적은 불용어를 없애거나 품사 태깅을 하는 등 단위 별로 처리가 가능하게끔 하고, NLP 모델이 문맥을 이해할 수 있도록 돕는 것이다.

토큰화에는 크게 두 가지가 있다. 단어 토큰화(Word Tokenization)와 문장 토큰화(Sentence Tokenization)이다.

  • ex) word tokenization: 'i was car' -> 'i', 'was', 'car'
  • ex) sentence tokenization: 'it was just accident! forgive me...' -> 'it was just accident!', 'forgive me...'

토큰화에서 가장 큰 어려운 점은 토큰을 나누는 기준을 정의하는 것이다. 영어의 경우 주로 띄어쓰기 단위로 토큰화가 이루어지고, " ' "아포스트로피의 경우, 특정 기준으로 추가하는 경우도 있다.

from nltk.tokenize import TreebankWordTokenizer
tk = TreebankWordTokenizer()

text = "I don't wanna go home now. Dr.Kim needs you, Son. Michael's dog is missing... and the dog's food price is just 5$. A-ha! (2022/06/21)"

tk.tokenize(text)
>>> ['I', 'do', "n't", 'wan', 'na', 'go', 'home', 'now.', 'Dr.Kim', 'needs', 'you', ',', 'Son.', 'Michael', "'s", 'dog', 'is', 'missing', '...', 'and', 'the', 'dog', "'s", 'food', 'price', 'is', 'just', '5', '$', '.', 'A-ha', '!', '(', '2022/06/21', ')']

위 테스트 예제와 같이 토큰화 기준을 정의할 때, 특수 문자와 이름, 신조어 등을 어떻게 고려해야만 한다.

한국어 토큰화는 어떨까? 한국어는 교착어로, 조사, 어미 등이 붙어서 말이 만들어지며, 주로 형태소(morpheme) 단위로 토큰화가 이루어진다. 또한 띄어쓰기가 잘 지켜지지 않아, 영어 토큰화 기준 정하기가 더 어렵다.

(형태소: 의미를 지닌 가장 작은 언어 단위.)

한국어 토큰화 라이브러리는 주로 konlpy(코엔엘파이)를 사용하며, 내부엔 여러 서브 모듈(Kkma, Hannanum, Komoran, Mecab, Twitter)이 존재한다. 서브 모듈 모두 형태소 토큰화 및 품사 태깅 기능이 존재하지만, 각각 성능 및 형태소 분석 방법이 다르다.

(KoNLPy: https://konlpy-ko.readthedocs.io/ko/v0.4.3/api/konlpy.tag/#module-konlpy.tag._kkma)

2. Cleaning & Normalization

  • Cleaning(정제): 데이터에서 노이즈 데이터(분석하고자 하는 목적에 맞지 않는 불필요한 데이터)를 제거하는 역할을 한다. 토큰화 작업에 방해되는 부분들을 제거하거나, 토큰화 이후에도 남아있는 노이즈를 제거하는 방식으로 이루어진다. 정제 방법은 다음과 같다.
    • 무의미하다고 생각되는 등장 빈도가 적은 단어를 제거한다
    • 길이가 짧은 단어를 제거하는 방법으로 영어에서는 'at', 'i', 'to', 'on' 같은 의미없는 데이터를 제거하는 데에 효과적이지만, 한국어의 경우 의미있는 한 글자 데이터도 많기 때문에 아주 비효율적이다.
    • 불용어(Stopword) 제거 - 불용어란 의미 분석을 하는 데에 기여하는 바가 크게 없는 단어를 뜻한다. 영어 모듈 nltk에는 'i', 'me', 'ourselves', 등이 불용어로 설정되어 있다. 이 페이지에서 참고할 만한 한국어 불용어를 확인할 수 있다.
  • Normalization(정규화): 표현 방법이 다른 단어를 통합시켜 같은 단어로 만든다. 대소문자를 통합하거나 동의어를 하나로 규합하기도 한다. 또는 접사를 제거하는 방식으로 표제어 추출, 어간 추출 방법을 사용하기도 한다.
    * Lemmatization(표제어 추출): 표제어란 기본 사전형 단어를 의미한다. 정확한 표제어 추출을 위해서는 품사 태깅이 필요하다. ('has'를 동사로 인식하는 경우 'have'로 표제어 추출 가능하지만, 명사로 인식되는 경우, 복수형 접사 '-s'를 떼어낸 'ha'로 추출된다)
    	* ex) 'am'->'be', 'wateched'->'watch'
    * Stemming(어간 추출): 표제어 추출의 경우 품사가 유지되지만, 어간 추출은 형태와 품사까지 정규화시키기도 한다. 한국어의 경우, 용언(동사, 형용사)에서 어미(ending)을 떼어내는 방식으로 어간(stem)을 추출합니다. 
    	* ex) 'formalize'->'formal'
    어간: 용언(동사, 형용사)을 활용할 때, 원칙적으로 모양이 변하지 않는 부분. (때로는 변한다)
    어미: 용언의 어간 뒤에 붙는 방식으로 활용하면서 모양이 변하는 부분이며, 문법적 기능을 수행한다.

3. Encoding

자연어 전처리에서 인코딩(Encoding)이란, 컴퓨터가 이해할 수 있도록 텍스트를 숫자로 바꾸는 기법을 뜻한다.

  • 정수 인코딩(Integer Encoding): 문서의 단어 개수를 세어보고, 가장 많은 순서대로 번호를 매겨 단어 집합(dictionary)를 만드는 인코딩 방식

  • 원-핫 인코딩(One-Hot Encoding): 단어 집합 크기 만큼의 0이 채워진 리스트(벡터)에서 표현하고 싶은 단어에 해당하는 인덱스 자리의 값만 1로 표현하는 방식

  • Encoding 방식의 단점

    • 단어의 개수가 늘어날 수록, 단어 집합을 저장할 메모리 공간이 더 많이 필요하게 된다.
    • 단어의 유사도를 표현할 수 없다.

4. Embedding

위의 Encoding 방식의 단점을 보완한 것이 Word Embedding 방식이다. 이 또한 벡터로 표현하는 방법이지만, 실수의 값을 갖는 저차원 벡터면서, 수동이 아닌 훈련 데이터 학습을 통해 벡터화 가능하다는 점에서 다르다. 주로 글의 문맥을 학습하여 단어의 의미를 실수 벡터로 표현하게 된다.

Embedding 방법으로는 'Word2Vec', 'Glove', 'FastText', 'LSA'가 있다.

5. Padding

어떤 문장을 Word Embedding을 통해 벡터로 만든다고 할 때, 벡터의 크기는 문장의 길이에 따라 다를 것이다. 그렇게 벡터의 크기가 다르게 되면 병렬 연산을 사용할 수 없게 된다. 여기에서 문장마다 벡터의 크기를 맞추기 위해 벡터를 가감하는 방식을 Padding이라고 한다. 보통은 0 벡터를 넣는 Zero-Padding 방식을 사용한다. 문단이나 전체 글에서 평균 문장 길이를 구하고 그 길이 이상의 단어를 제거하는 방식 또한 사용하기도 한다.


Ref.

1) 딥러닝을 이용한 자연어 처리 입문: https://wikidocs.net/book/2155
2) 자연어처리(NLP)가 한국어에서 특히 어려운 4가지 이유: https://media.fastcampus.co.kr/knowledge/data-science/nlp-korean-4reasons/
3) 유튜브 '허민석'-딥러닝 자연어처리: https://www.youtube.com/playlist?list=PLVNY1HnUlO26qqZznHVWAqjS1fWw0zqnT
4) 한국어 임베딩: https://ratsgo.github.io/embedding/

profile
정리하고 복습하고 일기도 쓰고

0개의 댓글