토큰화

ro_ot ㅣ 2020. 3. 1. 00:53

※ 자연어란 우리가 일상 생활에서 사용하는 언어를 말한다.

자연어 처리란 이러한 자연어에 의미를 분석하여 컴퓨터가 처리 할 수 있도록 하는 일을 말한다.

 

* 텍스트 전처리

텍스트 전처리는 용도에 맞게 텍스트를 사전에 처리하는 작업입니다.

 

데이터가 필요에 맞게 전처리 되지 않은 상태라면, 데이터를 용도에 맞게 토큰화(tokenization) & 정제(cleaning) & 정규화(normalization)하는 일을 해야 합니다.

 

주어진 말뭉치(corpus)에서 토큰(token)이라 불리는 단위로 나누는 작업을 토큰화라고 부릅니다.

1. 단어 토큰화

토큰의 기준을 단어(word)로 하는 경우, 단어 토큰화라고 합니다.

예를들어, 아래의 입력으로부터 구두점(punctuation)과 같은 문자는 제외시키는 간단한 단어 토큰화 작업을 할때

* 구두점이란, 온점(.), 컴마(,), 물음표(?), 세미콜론(;), 느낌표(!)등과 같은 기호를 말함.

→ 입력: Time is an illusion. Lunchtime double so!

이러한 입력으로부터 구두점을 제외시킨 토큰화 작업의 결과는 다음과 같다.

 출력 : "Time", "is", "an", "illustion", "Lunchtime", "double", "so"

위 예제는 구두점을 지운 뒤에 띄어쓰기(whitespace)를 기준으로 잘라냈다.

 

하지만 영어에서는 단어 토큰이 구분되지만, 한국어는 띄어쓰기만으로는 단어 토큰을 구분하기 어렵다.

또한 구두점이나 특수문자를 전부 제거하면 토큰이 의미를 잃어버리는 경우가 발생하기도 한다.

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

토큰화를 하다보면, 예상하지 못한 경우가 있어서 토큰화의 기준을 생각해봐야 하는 경우가 발생한다.

어떤 용도로 사용할 것인지에 따라, 그 용도에 영향이 없는 기준으로 정하면 된다.

 

예를 들면,

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

위와 같은 문장이 있을 때 아포스트로피(')가 들어간 상황에서 Don't와 Jone's의 토큰화를 볼 수 있다.

  • Don't
  • Don t
  • Dont
  • Do n't

  • Jone's

  • Jone s
  • Jone
  • Jones
더보기

원하는 결과가 나오도록 토큰화 도구를 직접 설계할 수도 있겠지만, 기존에 공개된 도구들을 사용하였을 때의 결과가 사용자의 목적과 일치한다면 해당 도구를 사용할 수도 있을 것입니다. 

NLTK는 영어 코퍼스를 토큰화하기 위한 도구들을 제공한다.

그중 word_tokenize와 WordPunctTokenizer를 사용해서 NLTK에서는 아포스트로피를 어떻게 처리하는지 확인해본다.

 

from nltk.tokenize import word_tokenize  
print(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."))  
['Do', "n'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를 살펴보자

from nltk.tokenize import WordPunctTokenizer  
print(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."))
['Don', "'", 't', 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name', ',', 'Mr', '.', 'Jone',
"'", 's', 'Orphanage', 'is', 'as', 'cheery', 'as', 'cheery','goes', 'for', 'a', 'pastry', 'shop', '.']

WordPunctTokenizer는 구두점을 별도로 분류하는 특징을 갖고 있기때문에, 앞서 확인했던 word_tokenize와는 달리 Don't를 Don과 '와 t로 분리하였으며, 이와 마찬가지로 Jone's를 Jone과 '와 s로 분리한 것을 확인할 수 있다.

 

케라스 또한 토큰화 도구로서 text_to_word_sequence를 지원한다.

from tensorflow.keras.preprocessing.text import text_to_word_sequence
print(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."))
["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와 같은 경우 아포스트로피를 보존한다.

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

토큰화 작업에서는 구두점을 제외하고 공백 기준으로 잘라내는 작업뿐만이 아니라 보다 섬세한 알고리즘이 필요하다.

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

단순히 구두점이나 특수문자를 제외하는것은 안된다. 때론 구두점조차 하나의 토큰으로 분류하기도 한다.

가장 기본적으로는 온점(.)과 같은 경우는 문장의 경계를 알 수 있는데 도움이 되므로 온점(.)을 제외하지 않을 수 있다.

또 다른 예를 들어 Ph.D나 AT&T 같이 단어 자체에 구두점을 갖고 있는 경우도 있다.

또 달러($)나 슬래시(/)로 예를 들어보면, $45.55와 같은 가격을 의미 하기도 하고, 01/02/06은 날짜를 의미하기도 한다.보통 이런 경우 45.55를 하나로 취급해야하지, 45와 55로 따로 분류하고 싶지는 않을 것이다.

 

숫자 사이에 컴마(,)가 들어가는 경우도 있는데 보통 수치를 표현할 때는 123,456,789와 같이 세 자리 단위로 컴마가 들어간다.

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

토큰화 작업에서 종종 영어권 언어의 아포스트로피(')는 압축된 단어를 다시 펼치는 역할을 하기도 한다.

what're는 what are 나 we're는 we are 같은 줄임말을 예로 들수 있다. 위의 예에서 re를 접어(clitic)이라고 한다.

즉, 단어가 줄임말로 쓰일 때 생기는 형태를 말한다.

더보기

가령 I am을 줄인 I'm이 있을 때, m을 접어라고 합니다.

또는 New York이라는 단어나 rock 'n' roll이라는 하나의 단어지만 중간에 띄어쓰기가 존재하는 단어들도 하나의 토큰으로 봐야 하는 경우도 있다. 이에 토큰화 작업은 저러한 단어를 하나로 인식할 수 있는 능력도 가져야한다.

2-3) 표준 토큰화 예제

표준으로 쓰이고 있는 토큰화 방법 중 하나인 Penn Treebank Tokenization의 규칙에 대해서 소개하고, 토큰화의 결과를 보자면,

 

규칙 1. 하이푼으로 구성된 단어는 하나로 유지한다.

규칙 2. doesn't와 같이 아포스트로피로 '접어'가 함께하는 단어는 분리해준다.

 

해당 표준에 아래의 문장을 input으로 넣어본다면,

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

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))
['Starting', 'a', 'home-based', 'restaurant', 'may', 'be', 'an', 'ideal.', 'it', 'does', "n't", 'have',
'a', 'food', 'chain', 'or', 'restaurant', 'of', 'their', 'own', '.'] 

결과를 보면, 각각 규칙에 따라 home-based는 하나의 토큰으로 취급하고 있으며, dosen't의 경우 does와 n't는 분리 되었음을 볼 수 있다.

4. 문장 토큰화(Sentence Tokenization)

이번에는 토큰의 단위가 문장(sentence)일 때, 토큰화 수행 방법을 알아본다.

이 작업은 갖고있는 코퍼스 내에서 문장 단위로 구분하는 작업으로 문장 분류(sentence segmentation)라고도 부른다.

 

corpus로 부터 문장 단위로 분류할 수 있는 방법을 직관적으로 생각해보자면, ?나 온점(.)이나 !기준으로 문장을 잘라낼 수 있다고도 할 수 있지만, !나 ?는 문장의 구분을 위한 꽤 명확한 구분자(boundary)역할을 하지만 온점은 문장의 끝이 아니더라도 등장할 수 있다.

 

EX1) IP 192.168.56.31 서버에 들어가서 로그 파일 저장해서 ukairia777@gmail.com로 결과 좀 보내줘. 그러고 나서 점심 먹으러 가자.*

 

EX2) Since I'm actively looking for Ph.D. students, I get the same question a dozen times every year.

 

위의 예제를 보면 단순히 온점(.)으로 문장을 구분짓는다고 가정하면, 문장의 끝이 나오기 전에 이미 온점이 여러번 등장하여 예상한 결과가 나오지 않게 된다.

 

그렇기 때문에 사용하는 corpus가 어떤 국적의 언어인지, 또는 해당 코퍼스 내에서 특수문자들이 어떻게 사용되고 있는지에 따라서 직접 규칙들을 정의 해 볼 수 있다.

 

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 mae sure no one was near."
print(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 mae sure no one was near.']

위 코드는 text에 저장된 여러 개의 문장들로부터 문장을 구분하는 코드이다.

from nltk.tokenize import sent_tokenize
text="I am actively looking for Ph.D. students. and you are a Ph.D student."
print(sent_tokenize(text))
['I am actively looking for Ph.D. students.', 'and you are a Ph.D student.']

NLTK는 단순히 온점을 구분자로 하여 문장을 구분하지 않았기 때문에, Ph.D.를 문장 내의 단어로 인식하여 성공적으로 인식하는 것을 볼 수 있다.

 

다음은 한국어에 대한 문장 토큰화 도구이다.(Korean Sentence Splitter/KSS)

# kss 문장 토큰화 도구 install 하기
pip install kss
import kss
text='딥 러닝 자연어 처리가 재미있기는 합니다. 그런데 문제는 영어보다 한국어로 할 때 너무 어려워요. 농담아니에요. 이제 해보면 알걸요?'
print(kss.split_sentences(text))
['딥 러닝 자연어 처리가 재미있기는 합니다.', '그런데 문제는 영어보다 한국어로 할 때 너무 어려워요.',
'농담아니에요.', '이제 해보면 알걸요?']

출력이 정상적으로 분리된 것을 알 수 있다.

5. 이진 분류기(Binary Classifier)

문장 토큰화에서의 예외 사항을 발생시키는 온점의 처리를 위해서 입력에 따라 두 개의 클래스로 분류하는 이진 분류기

(binary classifier)를 사용하기도 합니다.

 

여기서 말하는 두 개의 클래스는

1. 온점(.)이 단어의 일부분일 경우. 즉, 온점이 약어(abbreivation)로 쓰이는 경우
2. 온점(.)이 정말로 문장의 구분자(boundary)일 경우

 

온점(.)이 어떤 클래스에 속하는지 결정을 위해서는 어떤 온점이 주로 약어(abbreviation)으로 쓰이는 지 알아야한다.

그렇기 때문에, 이진 분류기 구현에서 약어 사전(abbreviations dictionary)은 유용하게 쓰인다.

더보기

영어권 언어의 경우에 있어 약어 사전의 예

https://public.oed.com/how-to-use-the-oed/abbreviations/

이러한 문장 토큰화를 수행하는 오픈 소스로는 NLTK, OpenNLP, 스탠포드 CoreNLP, splitta, LingPipe 등이 있다.

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

영어는 New York과 같은 합성아나 he's와 같이 줄임말에 대한 예외처리만 한다면, 띄어쓰기(whitespace)를 기준으로 하는 띄어쓰기 토큰화를 수행해도 단어 톤큰화가 잘 작동 된다.

 

하지만 한국어는 띄어쓰기만으로는 토큰화를 하기에 부족하다.

한국어의 경우에는 띄어쓰기 단위가 되는 단위'어절'이라고 한다.

어절 토큰화와 단어 토큰화가 같지 않기 때문이다.

그 근본적인 이유는 한국어가 영어와는 다른 형태를 가지는 언어인 교착어라는 점에서 기인한다.

* 교착어: 조사, 어미등을 붙여서 말을 만드는 언어를 말한다.

6-1) 한국어는 교착어이다

그 (he/him)라는 주어나 목적어가 들어간 문장이 있다고 한다면, 그라는 단어 하나에도 '그가', '그에게', '그를', '그와', '그는'과 같이 다양한 조사가 '그'라는 글자 뒤에 띄어쓰기 없이 바로 붙게된다.

또한 같은 단어임에도 서로 다른 조사가 붙어서 다른 단어로 인식이 되면 자연어 처리가 힘들고 번거로워 지는 경우도 많다.

* 대부분의 한국어 NLP에서 조사는 분리해줄 필요가 있다.

 

좀 더 자세히 설명해보자면, 한국어 토큰화에서는 형태소(morpheme)란 개념을 반드시 이해해야 한다.

형태소(morphemem)란 뜻을 가진 가장 작은 말의 단위를 말한다.

 

형태소에는 두 가지 형태소가 있는데 자립 형태소와 의존 형태소이다.

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

예를 들어 다음과 같은 문장이 있다고 하면,

  • 문장: 에디가 딥러닝책을 읽었다.

이를 형태소 단위로 분해하면 다음과 같다.

 

자립 형태소 : 에디, 딥러닝책
의존 형태소 : -가, -을, 읽-, -었, -다

 

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

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

사용하는 한국어 코퍼스는 띄어쓰기가 틀렸거나 지켜지지 않는 경우가 많다.

그 이유는 한국어의 띄어쓰기가 지켜지지 않아도 글을 쉽게 이해할 수 있는 언어라는 점이다.

 

EX1) 제가이렇게띄어쓰기를전혀하지않고글을썼다고하더라도글을이해할수있습니다.

 

EX2) Tobeornottobethatisthequestion

 

반면, 영어의 경우에는 띄어쓰기를 하지 않으면 손쉽게 알아보기 어려운 문장들이 생긴다.

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

* 한국어는 수많은 코퍼스에서 띄어쓰기가 무시되는 경우가 많아 자연어 처리가 어려워졌다는 것이다.

7. 품사 태깅(Part-of-speech tagging)

단어는 표기는 같지만, 품사에 따라서 단어의 의미가 달라지기도 한다. 예를 들어 영어 단어 'fly'는 동사로는 '날다'라는 의미를 갖지만, 명사로는 '파리'라는 의미를 갖고있다. 한국어로 예를 들면 '못'이라는 단어는 명사로서는 망치를 사용해 목재 따위를 고정하는 물건을 의미하지만 부사로서의 '못'은 '먹는다', '달린다'와 같은 동작 동사를 할 수 없다는 의미로 쓰인다. 

 

즉, 단어의 의미를 제대로 파악하기 위해서는 해당 단어가 어떤 품사로 쓰였는지 보는 것이 주요 지표가 될 수 있다.

단어 토큰화 과정에서 각 단어가 어떤 품사로 쓰였는지를 구분해 놓기도 하는데, 이 작업을 품사 태깅이라고 한다.

더보기

품사란, 낱말을 문법적인 기능이나 형태, 뜻에 따라 몇 갈래로 나눈 것을 말한다.

 

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

NLTK에서는 영어 코퍼스에 품사 태깅 기능을 지원한다. 품사를 어떻게 명명하고, 태깅하는지의 기준은 여러가지가 있는데, NLTK에서는 Penn Treebank POS Tags라는 기준을 사용한다.

 

다음은 NLTK를 사용해서 영어 코퍼스에 품사 태깅을 해본다.

from nltk.tokenize import word_tokenize
text="I am actively looking for Ph.D. students. and you are a Ph.D. student."
print(word_tokenize(text))
['I', 'am', 'actively', 'looking', 'for', 'Ph.D.', 'students', '.', 'and', 'you', 'are', 'a', 'Ph.D.', 'student', '.']
from nltk.tag import pos_tag
x=word_tokenize(text)
pos_tag(x)
[('I', 'PRP'), ('am', 'VBP'), ('actively', 'RB'), ('looking', 'VBG'), ('for', 'IN'), ('Ph.D.', 'NNP'), ('students', 'NNS'),
('.', '.'), ('and', 'CC'), ('you', 'PRP'), ('are', 'VBP'), ('a', 'DT'), ('Ph.D.', 'NNP'), ('student', 'NN'), ('.', '.')]

Penn Treebank POG Tags에서 PRP는 인칭 대명사, VBP는 동사, RB는 부사, VBG는 현재부사, IN은 전치사, NNP는 고유 명사, NNS는 복수형 명사, CC는 접속사, DT는 관사를 의미한다.

 

한국어 자연어 처리를 위해서는 KoNLPy라는 파이썬 패키지를 사용한다.

코엔엘파이를 통해서 사용할 수 있는 형태소 분석기로 Okt(Open Korea Text), 메캅(Mecab), 코모란(Komoran), 한나눔(Hannanum), 꼬꼬마(Kkma)가 있다.

 

한국어 NLP에서 형태소 분석기를 사용한다는 것은 단어 토큰화가 아니라 정확히는 형태소(morpheme)단위로 형태소  토큰화(morpheme tokenization)를 수행하게 됨을 뜻한다.

 

Okt와 꼬꼬마를 이용한 토큰화를 수행해보도록 한다.

from konlpy.tag import Okt  
okt=Okt()  
print(okt.morphs("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))
['열심히', '코딩', '한', '당신', ',', '연휴', '에는', '여행', '을', '가봐요']  
print(okt.pos("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))  
[('열심히','Adverb'), ('코딩', 'Noun'), ('한', 'Josa'), ('당신', 'Noun'), (',', 'Punctuation'), ('연휴', 'Noun'), ('에는', 'Josa'), ('여행', 'Noun'), ('을', 'Josa'), ('가봐요', 'Verb')]  
print(okt.nouns("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))  
['코딩', '당신', '연휴', '여행']  

위의 예제는 Okt 형태소 분석기로 토큰화를 시도해본 예제이다.

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

위 예제에서 사용된 각 메소드는 이런 기능을 갖고 있다.

위 예제에서 형태소 추출과 품사 태깅 메소드의 결과를 보면, 조사를 기본적으로 분리하고 있음을 확인할 수 있다.

 

이번엔 꼬꼬마 형태소 분석기를 사용하여 토큰화를 진행해본다.

from konlpy.tag import Kkma  
kkma=Kkma()  
print(kkma.morphs("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))

 

['열심히', '코딩', '하', 'ㄴ', '당신', ',', '연휴', '에', '는', '여행', '을', '가보', '아요']  
print(kkma.pos("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))  
[('열심히','MAG'), ('코딩', 'NNG'), ('하', 'XSV'), ('ㄴ', 'ETD'), ('당신', 'NP'), (',', 'SP'), 
('연휴', 'NNG'), ('에', 'JKM'), ('는', 'JX'), ('여행', 'NNG'), ('을', 'JKO'), ('가보', 'VV'), ('아요', 'EFN')]  
print(kkma.nouns("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))  
['코딩', '당신', '연휴', '여행']  

앞에서 본Okt 형태소 분석기와 결과가 다른 것을 볼 수 있다. 각 형태소 분석기는 성능과 결과가 다르게 나오기 때문에, 형태소 분석기의 선택은 사용하고자 하는 필요 용도에 어떤 형태소 분석기가 가장 적절한지를 판단하고 사용하면 된다. 예를 들어서 속도를 중시한다면 메캅을 사용할 수 있다.

 

* 정리:

1. 주어진 코퍼스(corpus)에서 토큰(token)이라 불리는 단위로 나누는 작업을 토큰화(tokenization)라고 부른다.

2. 토큰화는 기준을 단어(word)나 문장(sentence)으로 한다.

3. 아포스트로피, 온점 등 구두점이 들어간 상황에선 그에 맞는 토큰화가 필요하다.

4. NLTK에서 영어 토큰화를 하기 위한 도구는 word_tokenize와 WordPunctTokenizer이다.

5. 줄임말과 단어 내에 띄어쓰기가 존재하는 단어가 있다.

6. 토큰화 방법 중 하나인 Penn Treebank Tokenization의 규칙

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

7. 문장 토큰화에서  ?나 온점(.)이나 ! 기준 등으로 문장을 잘라내면 되지만, 간혹 온점은 구분자 역할이 명확하지 않을 때가 있다.

8. NLTK에서는 영어 문장의 토큰화를 하기 위한 도구로 sent_tokenize를 지원한다.

9. 한국어의 문장 토큰화는 kss를 사용한다.

10. 온점의 처리를 위해 입력에 따라 두 개의 클래스로 분류해주는 것을 이진 분류기(binary classifier)이라 한다.

    클래스 1. 온점(.)이 단어의 일부분일 경우. 즉, 온점이 약어(abbreivation)로 쓰이는 경우
    클래스 2. 온점(.)이 정말로 문장의 구분자(boundary)일 경우를 의미할 것입니다.

11. 단어 토큰화 과정에서 각 단어가 어떤 품사로 쓰였는지를 구분해놓기도 하는데, 이 작업을 품사 태깅이라 한다.

12. NLTK에서는 영어 코퍼스 품사태깅 기준을 Penn Treebank POS Tags라는 것을 사용한다.

13. Penn Treebank POG Tags에서 PRP는 인칭 대명사, VBP는 동사, RB는 부사, VBG는 현재부사, IN은 전치사, NNP는 고유 명사, NNS는 복수형 명사, CC는 접속사, DT는 관사를 의미

14. KoNLPy로 한국어 자연어 처리를 할 수 있다.

15. 한국어 NLP에서 형태소 분석기를 사용한다는 것은 형태소(morpheme) 단위로 형태소 토큰화(morpheme tokenization)를 수행하게 됨을 뜻한다.

16. 한국어 NLP에서는 조사를 기본적으로 분리하고 있다.