오늘은 딥러닝을 이용한 자연어 처리 입문-1권에서 '2-1. 토큰화'와 '2-2. 정제와 정규화'에 해당되는 부분을 요약해보았습니다.
제가 텍스트 분석을 처음했을 때는 형태소 분석기의 종류가 다양하다는 것도 몰랐고, 형태소 분석기의 종류에 따라 분석 결과가 매우 다르게 나올 수 있다는 점도 몰랐습니다.
이 글을 읽고 텍스트 분석을 하신다면 분석 자료에 다양한 형태소 분석기를 테스트 해보시고, 분석 결과를 비교해보시면 좋을 것 같습니다!
2. 텍스트 전처리(Text preprocessing)
텍스트 전처리는 풀고자 하는 문제의 용도에 맞게 텍스트를 사전에 처리하는 작업
2-1. 토큰화(Tokenization)
토큰화는 주어진 자료를 토큰이라는 단위로 나누는 작업을 말하며, 토큰의 단위는 상황에 따라 다르게 정의할 수 있지만 보통 의미있는 단위로 정의함
- 단어 토큰화(Word Tokenization)
- 토큰의 기준이 단어인 경우, '단어 토큰화'라고 함
- NLTK의 word_tokenize, WordPunctTokenizer, Keras의 text_to_word_sequence 등을 활용하여 단어를 기준으로 토큰화할 수 있음(아래의 예시에서 어떤 것으로 토큰화하는지에 따라 I'm 부분이 다르게 토큰화된다는 것을 알 수 있음)
from nltk.tokenize import word_tokenize
from nltk.tokenize import WordPunctTokenizer
from tensorflow.keras.preprocessing.text import text_to_word_sequence
print('단어 토큰화1 :', word_tokenize("I'm not a student"))
print('단어 토큰화2 :', WordPunctTokenizer().tokenize("I'm not a student"))
print('단어 토큰화3 :', text_to_word_sequence("I'm not a student"))
단어 토큰화1 : ['I', "'m", 'not', 'a', 'student']
단어 토큰화2 : ['I', "'", 'm', 'not', 'a', 'student']
단어 토큰화3 : ["i'm", 'not', 'a', 'student']
- 단어 토큰화시 주의할 점
- 구두점(.,) 등의 특수문자를 무조건 제외하는 것은 옳지 않음. 예를 들어, 마침표의 경우 문장의 경계를 파악하는데 도움이 될 수 있음
- 줄임말과 단어 내에 띄어쓰기가 있는지 확인할 필요가 있음. 예를 들어, I'm과 I am은 동일한 의미이므로 같은 단어로 취급되어야 하며, New York은 띄어쓰기를 기준으로 토큰화되지 않아야 함
- 문장 토큰화(Sentence Tokenization)
- 토큰의 단위가 문장일 경우, '문장 토큰화'라고 함
- 영어의 경우 NLTK의 sent_tokenize를 이용해서 문장 토큰화를 할 수 있으며, 아래의 예시를 통해 마침표(.)를 기준으로만 토큰화되지 않는다는 것을 알 수 있음
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.']
- 한국어의 경우 박상길님이 개발한 KSS(Korean Sentence Splitter)을 활용하여 문장 토큰화를 할 수 있음
!pip install kss
import kss
text = "나는 딥러닝 관련 블로그를 운영 중에 있습니다. 블로그 주소는 https://study-with-yhk.tistory.com/ 입니다."
print('문 장 토 큰 화 :',kss.split_sentences(text))
문 장 토 큰 화 : ['나는 딥러닝 관련 블로그를 운영 중에 있습니다.', '블로그 주소는 https://study-with-yhk.tistory.com/ 입니다.']
- 한국어에서의 토큰화의 어려움
- 영어의 경우 New York과 같은 합성어나 I'm과 같은 줄임말만 예외처리한다면, 띄어쓰기를 기준으로 토큰화를 수행해도 큰 문제가 없지만 한국어의 경우 조사 및 어미 등을 붙여서 말을 만드는 교착어이기 떄문에 띄어쓰기를 기준으로 토큰화하는 데 어려움이 존재함
- 한국어의 경우 영어보다 띄어쓰기가 어렵고 잘 지켜지지 않는 경향이 있어 토큰화에 어려움이 있음
- 품사 태킹(Part-of-speech tagging)
- 단어는 표기는 같지만 품사에 따라서 단어의 의미가 달라지는 경우가 있으며, 예를 들어 '못'은 명사로서 망치를 사용해서 목재 따위를 고정하는 물건을 의미하기도 하며, 부사로서 '못'은 어떤 동작을 할 수 없다는 의미로 사용되기도 함. 따라서, 단어의 의미를 제대로 파악하기 위해서는 해당 단어가 어떤 품사로 사용되었는지 파악할 필요가 있음
- 영어의 경우 NLTK의 pos_tag를 활용하여 품사 태깅을 할 수 있음
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))
단 어 토 큰 화 : ['I', 'am', 'actively', 'looking', 'for', 'Ph.D.', 'students', '.', 'and', 'you', 'are', 'a', 'Ph.D', 'student', '.']
품 사 태 깅 : [('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'), ('.', '.')]
- 한국어의 경우 KoNLPy 패키지에 내장되어 있는 형태소 분석기인 Okt(Open Korean Text), 메캅(Mecab), 코모란(Komoran), 한나눔(Hannanum), 꼬꼬마(Kkms) 등을 활용하여 형태소 분석 및 품사 태깅이 가능함
- 아래의 예시에서 볼 수 있듯이 어떤 형태소 분석기를 쓰는지에 따라 형태소 분석과 품사 태깅이 다르게 되므로 분석하는 자료의 특성을 고려하여 형태소 분석기를 선택하여 사용해야 함!
!pip install konlpy
import konlpy
from konlpy.tag import Okt
from konlpy.tag import Mecab
from konlpy.tag import Kkma
okt = Okt()
mecab = Mecab()
kkma = Kkma()
print('okt 형태소 분석:', okt.morphs("밥도둑이 따로 없는 굴비조림"))
print('Mecab 형태소 분석:', mecab.morphs("밥도둑이 따로 없는 굴비조림"))
print('꼬꼬마 형태소 분석:', kkma.morphs("밥도둑이 따로 없는 굴비조림"))
print('okt 품사 태킹:', okt.pos("밥도둑이 따로 없는 굴비조림"))
print('Mecab 품사 태킹:', mecab.pos("밥도둑이 따로 없는 굴비조림"))
print('꼬꼬마 품사 태킹:', kkma.pos("밥도둑이 따로 없는 굴비조림"))
print('okt 명사 추출:', okt.nouns("밥도둑이 따로 없는 굴비조림"))
print('Mecab 명사 추출:', mecab.nouns("밥도둑이 따로 없는 굴비조림"))
print('꼬꼬마 명사 추출:', kkma.nouns("밥도둑이 따로 없는 굴비조림"))
okt 형태소 분석: ['밥', '도둑', '이', '따로', '없는', '굴비', '조림']
Mecab 형태소 분석: ['밥도둑', '이', '따로', '없', '는', '굴비', '조림']
꼬꼬마 형태소 분석: ['밥도둑', '이', '따로', '없', '는', '굴비', '조림']
okt 품사 태킹: [('밥', 'Noun'), ('도둑', 'Noun'), ('이', 'Josa'), ('따로', 'Adverb'), ('없는', 'Adjective'), ('굴비', 'Noun'), ('조림', 'Noun')]
Mecab 품사 태킹: [('밥도둑', 'NNG'), ('이', 'JKS'), ('따로', 'MAG'), ('없', 'VA'), ('는', 'ETM'), ('굴비', 'NNG'), ('조림', 'NNG')]
꼬꼬마 품사 태킹: [('밥도둑', 'NNG'), ('이', 'JKS'), ('따로', 'MAG'), ('없', 'VA'), ('는', 'ETD'), ('굴비', 'NNG'), ('조림', 'NNG')]
okt 명사 추출: ['밥', '도둑', '굴비', '조림']
Mecab 명사 추출: ['밥도둑', '굴비', '조림']
꼬꼬마 명사 추출: ['밥도둑', '굴비', '굴비조림', '조림']
2-2. 정제(cleaning)과 정규화(Normalization)
- 분석 자료에서 노이즈 데이터를 제거하는 과정을 '정제'라고 하며, 같은 의미이지만 디르게 표현된 단어를 통합하는 과정을 '정규화'라고 함
- 영어의 경우 대문자와 소문자를 통합하는 과정을 통해 정규화를 수행할 수 있음. 하지만 미국을 뜻하는 US와 우리를 뜻하는 us와 같이 대문자와 소문자가 구분되어야 할 필요가 있는 경우도 있을 수 있음. 가능하다면 이와 같은 경우를 고려하여 정규화를 하는 것이 옳지만 분석해야 하는 데이터의 양이 많다면 쉽지 않을 수 있음
- 분석에 의미없는 단어나 등장 빈도가 적은 단어는 제거하는 과정을 통해 분석 자료를 정제할 수 있음. 이외에도 영어의 경우 길이가 짧은 단어를 제거하는 것도 고려해 볼 수 있음. 예를 들어, 영어의 경우 한 글자인 단어를 제거하면 의미가 없는 관사인 'a'가 삭제되며, 두 글자 단어를 제거하면 it, at, to, on, in, by와 같은 불용어 단어가 삭제됨
- 아래의 예시는 정규식을 이용하여 문장에서 두 글자 이하의 단어를 삭제한 것임
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))
was wondering anyone out there could enlighten this car.
출처: 유원준/안상준, 딥러닝을 이용한 자연어 처리 입문-1권, p50-p63.
'자연어 처리' 카테고리의 다른 글
[딥러닝을 이용한 자연어 처리 입문] 벡터의 유사도 (0) | 2023.04.06 |
---|---|
[딥러닝을 이용한 자연어 처리 입문] 카운트 기반의 언어 모델 (0) | 2023.03.20 |
[딥러닝을 이용한 자연어 처리 입문] 언어모델 (0) | 2023.03.04 |
[딥러닝을 이용한 자연어 처리 입문] 패딩과 원-핫인코딩 (0) | 2023.02.27 |
[딥러닝을 이용한 자연어 처리 입문] 정규 표현식 (0) | 2023.02.25 |