티스토리 뷰

자연어처리

[1] 토큰화(Tokenizer)

up_one 2025. 3. 21. 16:56

NLP(Natural Language Processing)은 인간의 언어를 이해하고 해석하기 위한 목적으로 발전해 왔습니다. 다만 분석 모델의 학습 데이터셋은 수치형으로만 입력이 가능하기 때문에 텍스트 데이터 자체로는 학습이 불가능합니다. 따라서 원본 텍스트 문서를 전처리해 유의미한 정보를 추출하고 그 정보를 손실 없이 수치형으로 변환하는 과정이 중요합니다.

NLP Process

 

이번 글에서는 NLP Process의 가장 기초이자 텍스트 문서를 일정 기준에 따라 분리하는 '토큰화 (Tokenizer)'에 대해 알아보겠습니다.  '토큰화 (Tokenizer)'은 텍스트를 문법적으로 더 이상 나눌 수 없는 요소까지 만드는 작업이라고 합니다.

원본 데이터 토큰화 된 상태
"I am David, I am a student" ["I", "am", "David", "I", "am", "a", "student"]

 

다만 토큰화는 위 예시처럼 공백을 기준으로 잘라내는 작업이라고 간단하게 처리할 수는 없습니다. 객관적인 기준을 가지고 구두점, 공백을 기준으로 잘라내는 섬세한 알고리즘이 필요합니다. 

 

가장 통용되는 토큰화 방법은 NLTK 모듈에서 제공하는 Tokenize 패키지입니다. 패키지 내 Tokenize 방법은 다양하며 상황에 따라 적절하게 사용하는 방법이 중요합니다.

 

1. Sentence Tokenize

데이터를 문장 별로 구분하기 위해서는 Sentence Tokenize을 사용합니다. Sentence Tokenize을 사용하면 텍스트를 문장 단위로 자를 수 있습니다.

from nltk.tokenize import sent_tokenize

print('토큰화된 결과 : ', sent_tokenize("I like you. you're my son")
#['I like you.', "you're my son"]

 

문장이 마침표(.)을 기준으로 분리된 것과 출력 형태가 리스트에 담겨 반환되는 것을 알 수 있습니다.

 

2. Word Tokenize

Token의 기준을 단어로 하는 경우를 word tokenize라고 합니다. 영어의 토큰화의 경우 띄어쓰기를 기준으로 하는 것이 대체적이지만 한국어는 띄어쓰기만으로 토큰화를 하는 것은 어려움이 있습니다.

from nltk.tokenize import word_tokenize, sent_tokenize

text = "I like you. you're my son"
sentence = sent_tokenize(text)
for texts in sentence:
  print(word_tokenize(texts))
 
#['I', 'like', 'you', '.']
#['you', "'re", 'my', 'son']

print(word_tokenize(text))
#['I', 'like', 'you', '.', 'you', "'re", 'my', 'son']

 

text 문장을 문장 토큰화를 처리 후, 워드 토큰화를 한 결과와 바로 워드 토큰화를 처리한 결과가 다르게 나타나는 것을 알 수 있습니다. 다만, nltk의 word tokenize은 '(구두점)이 Token으로 분리가 제대로 안 되는 것을 확인할 수 있습니다.

 

3. WordPunctTokenizer

WordPunctTokenizer은 '(구두점)을 Token으로 분리시킬 때 사용합니다.

sentence = "Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop."
words = WordPunctTokenizer().tokenize(sentence)
print(words)

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

 

4. TreebankWordTokenizer

TreebankWordTokenizer은 표준화된 토큰화 모델이라고 여겨지며, 공백과 구두점을 사용하여 단어를 Token으로 만들어 줍니다. 결과로 구두점을 버리지 않으므로 그것에 대해 확장해서 활용할 수 있습니다.

from nltk.tokenize import TreebankWordTokenizer

tokenize = TreebankWordTokenizer()
text = "Starting a home-based restaurant may be an ideal. it doesn't have a food chain or restaurant of their own."
print(tokenize.tokenize(text))
# ['Starting', 'a', 'home-based', 'restaurant', 'may', 'be', 'an', 'ideal.', 'it', 'does', "n't", 'have', 'a', 'food', 'chain', 'or', 'restaurant', 'of', 'their', 'own', '.']

 

예시의 결과에서 'ideal.'으로 구두점이 버려지지 않음을 확인할 수 있습니다.

 

5. Python을 이용한 토큰화

Python의 내장 함수인 split을 이용하여 텍스트 데이터를 토큰화할 수 있습니다. 다만, nltk의 패키지와 다르게 구두점과 마침표에 대한 처리는 미숙한 것을 알 수 있습니다.

text = "I like you. you're my son"
print(text.split())

#['I', 'like', 'you.', "you're", 'my', 'son']

 

[한국어에서의 토큰화 처리의 어려움]

띄어쓰기 단위로 단어를 토큰화 할 수 있는 영어와 달리 한글은 그것이 힘들다고 언급하였습니다. 그 이유는 한글에는 '형태소'라는 개념이 들어있기 때문입니다. 형태소는 뜻을 가진 가장 작은 말의 단위를 의미합니다.

에디가 딥러닝 책을 읽었다 자립형태소(명사, 대명사, 수사) 의존형태소(관형사, 부사)
에디, 딥러닝 책 -가, -을, 읽-, -었, -다

 

from nltk.tokenize import word_tokenize

text = "에디가 딥러닝 책을 읽었다."
print(word_tokenize(text))

#['에디가', '딥러닝', '책을', '읽었다']

 

nltk의 word tokenize 함수를 이용하여 한글을 토큰화하면 의존형태소가 분리가 되지 않음을 알 수 있습니다. 즉, 한글의 토큰화는 영어처럼 띄어쓰기 기준의 토큰화가 정확하지 않아 활용에 어려움이 존재합니다.

 

형태소 토큰화를 위한 라이브러리는 'konlpy'을 활용할 수 있습니다. 

  1. Okt
  2. Komoran
  3. Hannanum
  4. Kkma
from konlpy.tag import Okt

text ="에디가 딥러닝 책을 읽었다"
okt = Okt()
print(okt.morphs(text))
#['에디', '가', '딥', '러닝', '책', '을', '읽었다']

 

Okt 함수는 트위터에서 사용된 형태소 분석기로 신조어 및 이모티콘 분석에 장점을 가지고 있습니다. 띄어쓰기 단위 분석을 수행하고 가벼운 형태소 분석 및 품사 태깅에 적합하여 SNS 댓글 및 챗봇 분석에 용이합니다. 다만 위의 예에서 의존 형태소는 토큰화가 부정확한 것을 알 수 있습니다.

 

from konply.tag import Komoran

text = "에디가 딥러닝 책을 읽었다."
kmn = Komoran()
print(kmn.morphs(text))

#['에디', '가', '딥러닝', '책', '을', '읽', '었', '다']

 

Komoran 함수의 형태소 분석은 꽤 정확한 것을 확인할 수 있습니다. Komorna 함수는 사전 분석을 기반으로 작동되며 긴 문장에서도 안정적인 결과를 산출합니다. 따라서 뉴스기사와 같은 공식문서를 분석하는 데에 용이합니다

 

from konply.tag import Hannanum

text = "에디가 딥러닝 책을 읽었다"
hann = Hannanum()
print(hann.morphs(text))
# ['에디', '가', '딥러닝', '책', '을', '읽', '었다']

 

Hannanum 함수는 문장 구조를 분석하고 의미 분석이 가능한 기능을 가지고 있습니다. 따라서 빠른 속도와 정확도를 자랑하며, 자동 보정 기능을 가지고 있습니다.

 

from konply.tag import Kkma

text = "에디가 딥러닝 책을 읽었다"
kkma = Kkma()
print(kkma.morphs(text))
# ['에디가', '딥', '러닝', '책', '을', '읽', '었', '다']

 

Kkma 함수는 어미, 구문, 명사 추출에서 비교적 높은 정확도를 산출하고 구어체와 문어체를 잘 분석하는 장점을 가지고 있습니다.

'자연어처리' 카테고리의 다른 글

[4] TF - IDF을 이용한 특징 추출  (0) 2025.03.29
[3] 정수 인코딩  (0) 2025.03.28
[2] 정제와 추출  (0) 2025.03.24
TAG more
글 보관함
최근에 올라온 글