Deep Learning/Natural Language Processing

[NLP] Tokenization

언킴 2022. 1. 18. 18:39
반응형

Tokenization. 토큰화라고 불리는 이것은 단어를 작은 단위로 쪼개주는 역할을 한다. 영어를 토큰화 할 때에는 nltk를 사용하고, 한국어를 토큰화 할 때에는 konlpy를 사용한다.

from nltk.tokenize import word_tokenize
from nltk.tokenize import WordPunctTokenizer
from torchtext.data import get_tokenizer

sentence = "Don't be fooled by the dark sounding name, \
Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop."

print('word_tokenize', word_tokenize(sentence))

# word_tokenize ['Do', "n't", 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name', ',',\
# 'Mr.', 'Jone', "'s", 'Orphanage','is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop', '.']


print('WordPunctTokenizer', WordPunctTokenizer().tokenize(sentence))

# WordPunctTokenizer ['Don', "'", 't', 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name',\
# ',', 'Mr', '.', 'Jone', "'", 's', 'Orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop', '.']

tokenizer = get_tokenizer('basic_english')
print('torchtext', tokenizer(sentence))

# torchtext ['don', "'", 't', 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name', ',', 'mr', '.',\
# 'jone', "'", 's', 'orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop', '.']

각 토큰화 모델마다 조금씩 토큰화 결과가 다른 것을 확인할 수 있다. 

 

from nltk.tokenize import TreebankWordTokenizer

tokenizer = TreebankWordTokenizer()

text = "Starting a home-based restaurant may be an ideal. \
it doesn't bave a food chain or restaurant of their own."

print('트리뱅크 워드 토크나이저 : ', tokenizer.tokenize(text))

# 트리뱅크 워드 토크나이저 :  ['Starting', 'a', 'home-based', 'restaurant', 'may', 'be', 'an', \
# 'ideal.', 'it', 'does', "n't", 'bave', 'a', 'food', 'chain', 'or', 'restaurant', 'of', 'their', 'own', '.']

트리뱅크 토크나이저의 경우 home-based는 한 단어로 보고 있지만, doesn't는 does + n't로 분할하였다.

 

Sentence Tokenization

간단하게 생각하면 문장의 끝에는 (.)이나 (?), (!) 등으로 끝날 것으로 생각하여 해당 값을 기준으로 문장을 구분하게 되면 큰일이 난다. 백슬래시나 마침표의 경우에는 문장의 중간중간에 들어갈수도 있기 때문에 문장을 구분할 때에 조심 해야한다. 

 

sentence1 = "IP 192.168.56.32 서버에 들어가서 로그 파일 저장해서 \
aaa@gamil.com로 결과 좀 보내줘. 그 후 점심 먹으러 가자."

sentence2 = "Since I'm actively looking for Ph.D. students, \
I get the same question a dozen times every year."

from nltk.tokenize import sent_tokenize


text = "His barber kept his word. But keeping such a huge secret to himself\
was driving him craze. Finally, \ the barber went up a cliff. He dug a hole in the \
midst of sme reeds. He looked about, to make sure no one was nears."

print('문장 토큰화1 : ', sent_tokenize(text))
print('-' * 123)

# 문장 토큰화1 :  ['His barber kept his word.', 'But keeping such a huge secret to \
# himself was driving him craze.', 'Finally, the barber went up a cliff.',\
# 'He dug a hole in the midst of sme reeds.', 'He looked about, to make sure no one was nears.']
-----------------------------------------------------------------------------------------------

print(sent_tokenize(sentence1))
print(sent_tokenize(sentence2))

# ['IP 192.168.56.32 서버에 들어가서 로그 파일 저장해서 aaa@gamil.com로 결과 좀 보내줘.', '그 후 점심 먹으러 가자.']
# ["Since I'm actively looking for Ph.D. students, I get the same question a dozen times every year."]

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

문장 토큰화2 : ['I am actively looking for Ph.D. students.', 'and you are a Ph.D student.']

sentence tokenization은 마침표나 느낌표 등을 기준으로 문장을 구분하고 있지 않기 때문에 결과가 제대로 나오는 것을 확인할 수 있다. 한국어의 문장 토큰화를 하기 위해서는 KSS(Korean Sentence Splitter)를 사용한다.

 

#!pip install kss

import kss


text = '딥 러닝 자연어 처리가 재미있기는... 합니다. \
그런데 문제는 영어보다 한국어로 할 때 너무 어렵습니다. 이제 해보면 알걸요?'

print('한국어 문장 토큰화 :', kss.split_sentences(text) )

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

 

한국어 토큰화를 진행할 때에는 konlpy를 사용한다고 했는데, konlpy는 kkma, okt 등의 다양한 토큰화 모델을 제시해주고 있다. 각각의 토크나이저마다 성능이 다르고 어떤 것이 좋다고 할 수 없기 때문에 필요에 맞게 본인이 필요로하는 토크나이저를 사용하면 될 것 같다. 

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

okt = Okt()
kkma = Kkma()


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


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

# OKT 품사 태깅 :  [('열심히', 'Adverb'), ('코딩', 'Noun'), ('한', 'Josa'), ('당신', 'Noun'), \
# (',', 'Punctuation'), ('연휴', 'Noun'), ('에는', 'Josa'), ('여행', 'Noun'), ('을', 'Josa'), \
# ('가봐요', 'Verb'), ('.', 'Punctuation')]

# OKT 명사 추출 :  ['코딩', '당신', '연휴', '여행']


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

# KKMA 형태소 분석 :  ['열심히', '코딩', '하', 'ㄴ', '당신', ',', '연휴', '에', '는', '여행', '을', '가보', '아요', '.']
# KKMA 품사 태깅 :  [('열심히', 'MAG'), ('코딩', 'NNG'), ('하', 'XSV'), ('ㄴ', 'ETD'), \
# ('당신', 'NP'), (',', 'SP'), ('연휴', 'NNG'), ('에', 'JKM'), ('는', 'JX'), ('여행', 'NNG'),\
# ('을', 'JKO'), ('가보', 'VV'), ('아요', 'EFN'), ('.', 'SF')]
# KKMA 명사 추출 :  ['코딩', '당신', '연휴', '여행']

출처 : 딥러닝을 이용한 자연어 처리 입문

'Deep Learning > Natural Language Processing' 카테고리의 다른 글

Sequence-to-Sequence (Seq2Seq)  (0) 2022.05.12
[NLP] Stemming and Lemmatization  (0) 2022.01.18
[NLP] Transformer  (0) 2021.10.21
[NLP] Lexical Analysis  (0) 2021.07.20
[NLP] INTRODUCTION  (2) 2021.06.26