본문 바로가기

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

토큰화(Tokenization)

토큰화 : 코퍼스(corpus)에서 토큰(token)이라 불리는 단위로 나누는 작업 

 1 단어 토큰화

단어 토큰화 : 토큰의 기준을 단어(word)로 하는 경우 (단어 단위 외에도 단어구, 의미를 갖는 문자열)

2 토큰화 중 생기는 선택의 순간

from nltk.tokenize import word_tokenize
from nltk.tokenize import WordPunctTokenizer
from tensorflow.keras.preprocessing.text import text_to_word_sequence

word_tokenize

import nltk
nltk.download('punkt')

print('단어 토큰화1 :',word_tokenize("Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop."))

word_tokenize - Don't를 Do와 n't로 분리하였으며, 반면 Jone's는 Jone과 's로 분리

wordPunctTokenizer

print('단어 토큰화2 :',WordPunctTokenizer().tokenize("Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop."))

wordPunctTokenizer - 구두점을 별도로 분류하는 특징을 갖고 있기때문에,
  Don't를 Don과 '와 t로 분리하였으며,
   Jone's를 Jone과 '와 s로 분리

 케라스의 토큰화 도구 - text_to_word_sequence

print('단어 토큰화3 :',text_to_word_sequence("Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop."))

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

3. 토큰화에서 고려해야할 사항

1) 구두점이나 특수 문자를 단순 제외해서는 안 된다
 구두점조차도 하나의 토큰으로 분류되기때문이다.

1.   문장의 경계를 알 수 있는 마침표(.)
2.   단어로서 사용되는 특수문자
3.   숫자 사이의 컴마(,)

2) 줄임말과 단어 내에 띄어쓰기가 있는 경우.
토큰화 작업에서 종종 영어권 언어의 아포스트로피(')는 단어가 줄임말로 쓰일 때 생기는 형태로도 쓰인다.
 사용 용도에 따라서, 하나의 단어 사이에 띄어쓰기가 있는 경우에도 하나의 토큰으로 봐야하는 경우도 있을 수 있음

3) 표준 토큰화 예제


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

from nltk.tokenize import TreebankWordTokenizer

tokenizer = TreebankWordTokenizer()

text = "Starting a home-based restaurant may be an ideal. it doesn't have a food chain or restaurant of their own."
print('트리뱅크 워드토크나이저 :', tokenizer.tokenize(text))

4 문장 토큰화

문장 분류(sentence segmentation) - 코퍼스 내에서 문장 단위로 구분하는 작업 [문장 토큰화 필요]

NLTK에서는 영어 문장의 토큰화를 수행하는 sent_tokenize를 지원

from nltk.tokenize import sent_tokenize

text = "His barber kept his word. But keeping such a huge secret to himself was driving him crazy. Finally, the barber went up a mountain and almost to the edge of a cliff. He dug a hole in the midst of some reeds. He looked about, to make sure no one was near."
print('문장 토큰화1 :',sent_tokenize(text))

 문장 중간에 마침표가 다수 등장하는 경우

text = "I am actively looking for Ph.D. students. and you are a Ph.D student."
print('문장 토큰화2 :',sent_tokenize(text))

NLTK는 단순히 마침표를 구분자로 하여 문장을 구분하지 않는다

 한국어에 대한 문장 토큰화 도구 - KSS(Korean Sentence Splitter)

pip install kss

import kss

text = '딥 러닝 자연어 처리가 재미있기는 합니다. 그런데 문제는 영어보다 한국어로 할 때 너무 어렵습니다. 이제 해보면 알걸요?'
print('한국어 문장 토큰화 :',kss.split_sentences(text))

5 한국어에서의 토큰화의 어려움.

영어는 단어 단위로 띄어쓰기가 이루어지기 때문에 합성어나 줄임말에 대한 예외처리만 한다면, 띄어쓰기(whitespace)를 기준으로 하는 띄어쓰기 토큰화를 수행해도 단어 토큰화가 잘 작동합니다. 
하지만 한국어는 교착어(조사, 어미 등을 붙여서 말을 만드는 언어)라 어절 토큰화와 단어 토큰화는 같지 않아 어절 단위(띄워쓰기) 토큰화는 지양된다.

1) 교착어의 특성

1.   조사
(은, 는, 이, 가, 에게...) 

2.   형태소
뜻을 가진 가장 작은 말의 단위

*   자립 형태소 : 접사, 어미, 조사와 상관없이 자립하여 사용할 수 있는 형태소. 그 자체로 단어가 된다. 체언(명사, 대명사, 수사), 수식언(관형사, 부사), 감탄사 등이 있다
*   의존 형태소 : 다른 형태소와 결합하여 사용되는 형태소. 접사, 어미, 조사, 어간을 말한다.

한국어에서 영어에서의 단어 토큰화와 유사한 형태를 얻으려면 어절 토큰화가 아니라 형태소 토큰화를 수행해야한다.

2) 한국어는 띄어쓰기가 영어보다 잘 지켜지지 않는다.

한국어는 영어권 언어와 비교하여 띄어쓰기가 어렵고 잘 지켜지지 않는 경향이 있습니다. 

1.    한국어의 경우 띄어쓰기가 지켜지지 않아도 글을 쉽게 이해할 수 있는 언어

2.   근대(1933년, 한글맞춤법통일안) : 한국어에 띄어쓰기가 보편화됨

3.   한국어(모아쓰기 방식)와 영어(풀어쓰기 방식)라는 언어적 특성의 차이

 결론적으로 한국어는 수많은 코퍼스에서 띄어쓰기가 무시되는 경우가 많아 자연어 처리가 어려워졌다

6 품사태깅

품사에 따라서 단어의 의미가 달라지기도 합니다
그에 따라 단어 토큰화 과정에서 각 단어가 어떤 품사로 쓰였는지를 구분해놓기도 하는데, 이 작업을 품사 태깅(part-of-speech tagging)이라고 합니다.

7 NLTK와 KoNLPy를 이용한 영어, 한국어 토큰화 실습

NLTK에서는 Penn Treebank POS Tags라는 기준을 사용하여 품사를 태깅합니다.

nltk.download('averaged_perceptron_tagger')

from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag

text = "I am actively looking for Ph.D. students. and you are a Ph.D. student."
tokenized_sentence = word_tokenize(text)

print('단어 토큰화 :',tokenized_sentence)
print('품사 태깅 :',pos_tag(tokenized_sentence))

 Penn Treebank POG Tags
*   PRP : 인칭 대명사
*   VBP : 동사
*   RB : 부사
*   VBG : 현재부사
*   IN :전치사
*   NNP :고유명사
*   NNS :복수형 명사
*   CC :접속사
*   DT :관사

한국어 자연어 처리 - KoNLPy

KoNLPY 형태소 분석기 : Okt(Open Korea Text), 메캅(Mecab), 코모란(Komoran), 한나눔(Hannanum), 꼬꼬마(Kkma)

pip install konlpy

from konlpy.tag import Okt
from konlpy.tag import Kkma

okt = Okt()
kkma = Kkma()

print('OKT 형태소 분석 :',okt.morphs('열심히 코딩한 당신, 연휴에는 여행을 가봐요'))
print('OKT 품사 태깅 :',okt.pos("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))
print('OKT 명사 추출 :',okt.nouns("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))

print('꼬꼬마 형태소 분석:',kkma.morphs("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))
print('꼬꼬마 품사 태깅:',kkma.pos('열심히 코딩한 당신, 연휴에는 여행을 가봐요'))
print('꼬꼬마 명사 추출:',kkma.nouns('열심히 코딩한 당신, 연휴에는 여행을 가봐요'))

1.   morphs : 형태소 추출
2.   pos : 품사 태깅(Part-of-speech tagging)
3.    nouns : 명사 추출

형태소 추출과 품사 태깅 메소드의 결과를 보면 조사를 기본적으로 분리하고 있음