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

여지윤·2023년 5월 10일
0

출처
https://wikidocs.net/21698


토큰화(Tokenization)

데이터가 전처리되지 않은 상태라면, 해당 데이터를 사용하고자 하는 용도에 맞게 토큰화, 정제, 정규화를 해야 한다.
토큰의 단위는 상황에 따라 다르지만, 보통 의미있는 단위로 토큰을 정의한다.

정제(Cleaning)

갖고 있는 코퍼스로부터 노이즈 데이터를 제거한다.

정규화(Normalization)

표현 방법이 다른 단어들을 통합시켜서 같은 단어로 만들어준다.


토큰화

단어 토큰화

NLTK는 영어 코퍼스를 토큰화하기 위한 도구들을 제공한다. 그 중 word_tokenize와 WordPunctTokenizer는 아포스트로피(')를 처리하는 방법에 차이가 있다.

from nltk.tokenize import word_tokenize
from nltk.tokenize import WordPunctTokenizer
from tensorflow.keras.preprocessing.text import text_to_word_sequence
word_tokenize("sentence")
WordPunctTokenizer().tokenize("sentence")
text_to_word_sequence("sentence") #keras

위 코드들은 모두 토큰화된 단어들을 list 형태로 return한다.

케라스의 text_to_word_sequence는 기본적으로 모든 알파벳을 소문자로 바꾸면서 마침표나 컴마, 느낌표 등의 구두점을 제거한다. 하지만 don't나 jone's와 같은 경우 아포스트로피는 보존하는 것을 볼 수 있다.


토큰화 주의점

  • 구두점이나 특수 문자를 단순 제외해서는 안 된다.

    Ph.D나 $45.55 등 단어 자체에 구두점을 가지고 있거나 가격 등을 의미하기도 한다.

  • 줄임말과 단어 내에 띄어쓰기가 있는 경우

    New York 같은 단어의 경우, 한 단어이나 중간에 띄어쓰기가 있다. 이 경우 하나의 단어로 인식 할 수 있어야 한다.

  • 표준 토큰화 예제
    Penn Treebank Tokenization

    규칙 1. 하이푼으로 구성된 단어는 하나로 유지한다.
    규칙 2. doesn't와 같이 아포스트로피로 '접어'가 함께하는 단어는 does와 n't로 분리해준다.


한국어 토큰화

품사 태깅

단어의 의미를 파악하기 위해선 해당 단어가 어떤 품사로 쓰였는지 보는 것이 주요 지표가 된다. 각 단어가 어떤 품사로 쓰였는지 구분하는 작업을 품사 태깅(part-of-speech tagging)이라고 한다.


정제와 정규화

대, 소문자 통합(영어)

영어권 언어에서 대문자는 문장의 맨 앞 등 특정 상황에서만 쓰이기 때문에 소문자 변환작업이 주로 일어난다. 하지만 예외가 많이 존재하기 때문에 주의해야 한다.

  • 미국을 뜻하는 US와 우리를 뜻하는 us는 구분되어야 한다.
  • 회사 이름 (General Motors)나 사람 이름 등은 대문자로 유지되어야 한다.
  • 문장의 맨 앞에 나오는 단어의 대문자만 소문자로 바꾸는 등의 대안이 존재
  • 하지만 소문자만 사용하는 사용자 등의 경우에는 예외 사항을 크게 고려하지 않고 모든 코퍼스를 소문자로 바꾸는 것이 더 실용적인 해결책이 되기도 한다.

불필요한 단어의 제거

noise data의 제거
정제 작업에서의 noise data는 아무 의미도 갖지 않는 글자(특수 문자 등), 목적에 맞지 않는 불필요 단어들을 의미.
불용어 제거, 등장 빈도가 적은 단어 제거, 길이가 짧은 단어들을 제거하는 방법 등

  • 등장 빈도가 적은 단어
    100,000개의 파일에서 어떤 단어가 5번밖에 등장하지 않는다면 해당 단어는 직관적으로 분류에 거의 도움이 되지 않는 단어임을 알 수 있다.
  • 길이가 짧은 단어
    영어권 언어에서는 길이가 짧은 단어를 삭제하는 것만으로도 자연어 처리에서 효과를 볼 수 있다. 한국어 단어는 길이가 대체로 짧지만 영어권 언어는 길기 때문이다.
    길이가 '2'인 단어들을 제거하면 it, at, to, on, by 등과 같은 대부분 불용어에 해당하는 다너들이 제거된다. 하지만 길이가 3인 경우 'car'등의 명사도 제거되기 때문에 사용하고자 하는 data에서 해당 방법을 사용해도 될지 고민해봐야 한다.

code

import re #정규 표현식 라이브러리

text = "I was wondering if anyone out there could enlighten me on this car."

shortword = re.compile(r'\W*\b\w{1,2}\b') #정규식 객체 리턴
print(shortword.sub('', text))

output

was wondering anyone out there could enlighten this car.

어간 추출(Stemming)과 표제어 추출(Lemmatization)

정규화 기법 중 코퍼스에 있는 단어의 개수를 줄이는 기법
주로 단어의 빈도수를 기반으로 문제를 풀고자 하는 BoW 표현을 사용하는 자연어 처리 문제에서 주로 사용된다.

Lemmatization

단어의 형태학적 파싱 진행
형태소란 '의미를 가진 가장 작은 단위'

  1. 어간(stem)
    단어의 의미를 담고 있는 단어의 핵심 부분
  2. 접사(affix)
    단어에 추가적인 의미를 두는 부분

형태학적 파싱은 위 두 구성 요소를 분리하는 것.
NLTK에서는 표제어 추출을 위한 도구인 WordNetLemmatizer를 지원.

code

import nltk
from nltk.stem import WordNetLemmatizer

nltk.download('wordnet') #Resource wordnet not found.에러 발생 시 해당 커맨드로 wordnet 다운로드

lemmatizer = WordNetLemmatizer() #nltk의 표제어 추출 도구

words = ['policy', 'doing', 'organization', 'have', 'going', 'love', 'lives', 'fly', 'dies', 'watched', 'has', 'starting']

print('표제어 추출 전 :',words)
print('표제어 추출 후 :', [lemmatizer.lemmatize(word) for word in words])

result

표제어 추출 전 : ['policy', 'doing', 'organization', 'have', 'going', 'love', 'lives', 'fly', 'dies', 'watched', 'has', 'starting']
표제어 추출 후 : ['policy', 'doing', 'organization', 'have', 'going', 'love', 'life', 'fly', 'dy', 'watched', 'ha', 'starting']

표제어 추출과 어간 추출은 다른 양상을 보인다. 표제어 추출은 단어의 형태를 보존하는데, 위와 같이 적절하지 못한 단어를 추출하는 경우에는 본래 단어의 품사를 입력시켜주어야 한다.


Stemming

어간을 추출하는 작업. 정해진 규칙만 보고 단어의 어미를 자르는 어림짐작의 작업으로도 볼 수 있다. 섬세한 작업이 아니라 결과 단어는 사전에 존재하지 않는 단어일 수도 있다.

porter algorithm을 이용한 code

from nltk.stem import PorterStemmer

stemmer = PorterStemmer() #어간 추출 알고리즘 중 하나인 포터 알고리즘

sentence = "This was not the map we found in Billy Bones's chest, but an accurate copy, complete in all things--names and heights and soundings--with the single exception of the red crosses and the written notes."

tokenized_sentence = word_tokenize(sentence)

print('어간 추출 전 :', tokenized_sentence)
print('어간 추출 후 : ', [stemmer.stem(word) for word in tokenized_sentence])

output

어간 추출 전 : ['This', 'was', 'not', 'the', 'map', 'we', 'found', 'in', 'Billy', 'Bones', "'s", 'chest', ',', 'but', 'an', 'accurate', 'copy', ',', 'complete', 'in', 'all', 'things', '--', 'names', 'and', 'heights', 'and', 'soundings', '--', 'with', 'the', 'single', 'exception', 'of', 'the', 'red', 'crosses', 'and', 'the', 'written', 'notes', '.']
어간 추출 후 :  ['thi', 'wa', 'not', 'the', 'map', 'we', 'found', 'in', 'billi', 'bone', "'s", 'chest', ',', 'but', 'an', 'accur', 'copi', ',', 'complet', 'in', 'all', 'thing', '--', 'name', 'and', 'height', 'and', 'sound', '--', 'with', 'the', 'singl', 'except', 'of', 'the', 'red', 'cross', 'and', 'the', 'written', 'note', '.']

포터 알고리즘의 추출은 아래와 같은 규칙들을 가진다.

  • ALIZE → AL
  • ANCE → 제거
  • ICAL → IC
    위의 규칙에 따르면
  • formalize → formal
  • allowance → allow
  • electricical → electric

단어에서 어미가 좌측과 같은 형태면 우측과 같은 형태로 변화시킨다는 의미.

그 외에도 다양한 stemmer가 존재하는데, 결과가 전혀 다르므로 어떤 stemmer가 해당 코퍼스에 적합한지의 판단이 선행되어야 함


  • 나중에 porter stemmer algorithm논문도 한 번 보고 구현해봐야겠음
  • 친구가 hugging face tockenizer는 신이라고 함 나중에 공부해봐야겠음..
profile
개발새발

0개의 댓글