자연어 처리 모델은 다음과 같은 문제를 해결할 수 있어야 한다.
- 모호성 : 단어와 구가 사용되는 맥락에 따라 여러 의미를 갖게 되어 모호한 경우가 많다.
- 가변성 : 사투리, 강세, 신조어, 작문 스타일로 인해 매우 가변적이다.
- 구조 : 문장이나 구의 의미를 이해할 때 구문을 파악하여 의미를 해석해야 한다.
위와 같은 문제를 이해하고 구분할 수 있는 모델을 만들려면 우선 말뭉치(Corpus)를 일정한 단위인 토큰(Token)으로 나눠야 한다. 토큰은 개별 단어나 문장 부호와 같이 텍스트를 의미하며 말뭉치보다 더 작은 단위이다. 토큰으로 나누는 과정을 토큰화(Tokenization)이라 한다. 그리고 텍스트 문자열을 토큰으로 나누는 알고리즘이나 소프트웨어를 토크나이저(Tokenizer)라고 한다.
토큰을 어떻게 나누었느냐에 따라 성능이나 처리 결과가 크게 달라지기도 한다. 토크나이저를 구축하는 방법은 다음과 같다.
- 공백 분할
- 정규표현식 : 특정 패턴을 식별해 텍스트를 분할
- 어휘 사전 : 사전에 정의된 단어 집합을 토큰으로 사용
- 머신러닝 활용 : 데이터세트를 기반으로 토큰화하는 방법을 학습한 머신러닝을 적용
어휘 사전(Vocab)의 경우 직접 어휘 사전을 구축하기 때문에 없는 단어나 토큰이 존재할 수 있다. 이러한 토큰을 OOV(Out of Vocab)이라 한다.
단어 및 글자 토큰화
단어 토큰화(Word Tokenization)
띄어쓰기, 문장부호, 대소문자 등의 특정 구분자를 활용해 토큰화가 수행된다.
단어 토큰화
review = " 현실과 구분 불가능한 cg. 시각적 즐거음은 최고! 더불어 ost는 더더욱 최고!!"
tokenized = review.split()
print(tokenized)
['현실과', '구분', '불가능한', 'cg.', '시각적', '즐거음은', '최고!', '더불어', 'ost는', '더더욱', '최고!!']
'cg.'와 'cg'가 비슷한 의믜가 있는 것을 알지만 단어 토큰화를 통해 만들어진 사전에서는 다른 토큰이 된다. 'cg'가 단어 사전 내에 있더라도, 'cg.', 'cg는', 'cg도' 등은 OOV가 된다. 단어 토큰화는 한국어 접사, 문장 부포, 오타 혹은 띄어쓰기 오류 등에 취약하다.
글자 토큰화(Character Tokenization)
글자 토큰화
review = "현실과 구분 불가능한 cg. 시각적 즐거음은 최고! 더불어 ost는 더더욱 최고!!"
tokenized = list(review)
print(tokenized)
['현', '실', '과', ' ', '구', '분', ' ', '불', '가', '능', '한', ' ', 'c', 'g', '.', ' ', '시', '각', '적', ' ', '즐', '거', '음', '은', ' ', '최', '고', '!', ' ', '더', '불', '어', ' ', 'o', 's', 't', '는', ' ', '더', '더', '욱', ' ', '최', '고', '!', '!']
한글은 자음과 모음의 조합으로 이루어져 있기 때문에 자소 단위 토큰화를 수행한다. 이를 위해 jamo 라이브러리를 활용해보자.
자모 변환 함수
retval = jamo.h2j(
hangul_string
)
- 입력된 한글 문자열을 유니코드 U+1100 ~ U+11FE 사이의 조합형 한글 자모로 변환하는 함수이다.
- 완성형으로 입력된 한글을 조합형 한글로 반환한다.
한글 호환성 자모 변환 함수
retval = jamo.h2jch(
jamo
)
조합형 한글 문자열을 자소 단위로 나눠 반환하는 함수이다.
자소 단위 토큰화
from jamo import h2j, j2hcj
# 완성형 : 조합된 글자 자체에 값을 부여해 인코딩하는 방식
# 조합형 : 글자를 자모 단위로 나눠 인코딩한 뒤 이를 조합해 한글을 표현
# h2j : 완성형으로 입력된 한글을 조합형 한글로 변환
# j2hcj : 조합형 한글 문자열을 자소 단위로 나눠 반환하는 함수
review = "현실과 구분 불가능한 cg. 시각적 즐거음은 최고! 더불어 ost는 더더욱 최고!!"
decomposed = j2hcj(h2j(review))
tokenized = list(decomposed)
print(tokenized)
['ㅎ', 'ㅕ', 'ㄴ', 'ㅅ', 'ㅣ', 'ㄹ', 'ㄱ', 'ㅘ', ' ', 'ㄱ', 'ㅜ', 'ㅂ', 'ㅜ', 'ㄴ', ' ', 'ㅂ', 'ㅜ', 'ㄹ', 'ㄱ', 'ㅏ', 'ㄴ', 'ㅡ', 'ㅇ', 'ㅎ', 'ㅏ', 'ㄴ', ' ', 'c', 'g', '.', ' ', 'ㅅ', 'ㅣ', 'ㄱ', 'ㅏ', 'ㄱ', 'ㅈ', 'ㅓ', 'ㄱ', ' ', 'ㅈ', 'ㅡ', 'ㄹ', 'ㄱ', 'ㅓ', 'ㅇ', 'ㅡ', 'ㅁ', 'ㅇ', 'ㅡ', 'ㄴ', ' ', 'ㅊ', 'ㅚ', 'ㄱ', 'ㅗ', '!', ' ', 'ㄷ', 'ㅓ', 'ㅂ', 'ㅜ', 'ㄹ', 'ㅇ', 'ㅓ', ' ', 'o', 's', 't', 'ㄴ', 'ㅡ', 'ㄴ', ' ', 'ㄷ', 'ㅓ', 'ㄷ', 'ㅓ', 'ㅇ', 'ㅜ', 'ㄱ', ' ', 'ㅊ', 'ㅚ', 'ㄱ', 'ㅗ', '!', '!']
개별 토큰은 아무런 의미가 없어므르 모델이 각 토큰의 의미를 조합해 결과를 도출해야 한다. 또한 모델 입력 시퀀스가 질어져서 연산량이 증가한다는 단점이 있다.
형태소 토큰화
텍스트를 형태소 단위로 나누는 토큰화 방법으로 언어의 문법과 구조를 고려해 단어를 분리하고 이를 의미 있는 단위로 분류하는 작업이다. 한국어는 어근에 다양한 접사와 조사가 조합되어 하나의 낱말을 이루므로 각 형태소를 적절히 구분해 처리해야 한다.
'그', '나'와 같이 스스로 의미를 가지고 있는 형태소를 자립 형태소(Free Morpheme)이라 하고, '-는', '-에게'와 같이 스스로 의미를 갖지 못하고 다른 형태소와 조합되어 사용되는 의존 형태소(Bound Morpheme)로 구분된다.
형태소 어휘 사전
형태소 어휘 사전에는 각 형태소가 어떤 품사(Part Of Speech, POS)에 속하는지와 해당 품사의 뜻 등의 정보도 함께 제공된다. 텍스트 데이터를 형태소 분석하여 각 형태소에 해당하는 품사를 태깅하는 작업을 품사 태깅(POS Tagging)이라고 한다.
KoNLPy
한국어 자연어 처리를 위해 개발된 라이브러리로 명사 추출, 형태소 분석, 품사 태깅 등의 기능을 제공한다. KoNLPy는 Okt(Open Korean Text), 꼬꼬마(Kkma), 코모란(Komoran), 한나눔(Hannanum), 메캅(Mecab) 등의 다양한 형태소 분석기를 지원한다.
Okt 토큰화
from konlpy.tag import Okt
okt = Okt()
sentence = "무엇이든 상상할 수 있는 사람은 무엇이든 만들어 낼 수 있다."
nouns = okt.nouns(sentence)
phrases = okt.phrases(sentence)
morphs = okt.morphs(sentence)
pos = okt.pos(sentence)
print("명사 추출 :", nouns)
print("구 추출 :", phrases)
print("형태소 추출 :", morphs)
print("품사 태깅 :", pos)
명사 추출 : ['무엇', '상상', '수', '사람', '무엇', '낼', '수']
구 추출 : ['무엇', '상상', '상상할 수', '상상할 수 있는 사람', '사람']
형태소 추출 : ['무엇', '이든', '상상', '할', '수', '있는', '사람', '은', '무엇', '이든', '만들어', '낼', '수', '있다', '.']
품사 태깅 : [('무엇', 'Noun'), ('이든', 'Josa'), ('상상', 'Noun'), ('할', 'Verb'), ('수', 'Noun'), ('있는', 'Adjective'), ('사람', 'Noun'), ('은', 'Josa'), ('무엇', 'Noun'), ('이든', 'Josa'), ('만들어', 'Verb'), ('낼', 'Noun'), ('수', 'Noun'), ('있다', 'Adjective'), ('.', 'Punctuation')]
꼬꼬마 토큰화
from konlpy.tag import Kkma
kkma = Kkma()
sentence = "무엇이든 상상할 수 있는 사람은 무엇이든 만들어 낼 수 있다."
nouns = kkma.nouns(sentence)
sentences = kkma.sentences(sentence)
morphs = kkma.morphs(sentence)
pos = kkma.pos(sentence)
print("명사 추출 :", nouns)
print("문장 추출 :", sentences)
print("형태소 추출 :", morphs)
print("품사 태깅 :", pos)
명사 추출 : ['무엇', '상상', '수', '사람', '무엇']
문장 추출 : ['무엇이든 상상할 수 있는 사람은 무엇이든 만들어 낼 수 있다.']
형태소 추출 : ['무엇', '이', '든', '상상', '하', 'ㄹ', '수', '있', '는', '사람', '은', '무엇', '이', '든', '만들', '어', '내', 'ㄹ', '수', '있', '다', '.']
품사 태깅 : [('무엇', 'NNG'), ('이', 'VCP'), ('든', 'ECE'), ('상상', 'NNG'), ('하', 'XSV'), ('ㄹ', 'ETD'), ('수', 'NNB'), ('있', 'VV'), ('는', 'ETD'), ('사람', 'NNG'), ('은', 'JX'), ('무엇', 'NP'), ('이', 'VCP'), ('든', 'ECE'), ('만들', 'VV'), ('어', 'ECD'), ('내', 'VXV'), ('ㄹ', 'ETD'), ('수', 'NNB'), ('있', 'VV'), ('다', 'EFN'), ('.', 'SF')]
NLTK(Natural Language Toolkit)
토큰화, 형태소 분석, 구문 분석, 개체명 인식, 감성 분석 등과 같은 기능을 제공한다. 주로 영어 자연어 처리를 위해 개발됐지만, 네덜란드어, 프랑스어, 독일어 등과 같은 다양한 언어의 자연어 처리를 위한 데이터와 모델을 제공한다.
패키지 및 모델 다운로드
import nltk
nltk.download('punkt')
nltk.download('averaged_perceptron_tagger')
Punkt 모델은 통계 기반 모델이며, Averaged Perceptron Tagger는 퍼셉트론 기반으로 품사 태깅을 수행한다.
영문 토큰화
from nltk import tokenize
sentence = "Those who can imagine anything, can create the impossible."
word_tokens = tokenize.word_tokenize(sentence)
sent_tokens = tokenize.sent_tokenize(sentence)
print(word_tokens)
print(sent_tokens)
['Those', 'who', 'can', 'imagine', 'anything', ',', 'can', 'create', 'the', 'impossible', '.']
['Those who can imagine anything, can create the impossible.']
- punkt 모델을 기반으로 토큰화 하며 word_tokenize는 공백을 기준으로 단어를 분리하고, 구두점 등을 처리해 각각의 토큰을 추출해 리스트로 반환한다.
- sent_tokenize는 마침표, 느낌표, 물음표 등의 구두점을 기준으로 문장을 분리해 리스트로 반환한다.
영문 품사 태깅
from nltk import tag, tokenize
sentence = "Those who can imagine anything, can create the impossible."
word_tokens = tokenize.word_tokenize(sentence)
pos_tags = tag.pos_tag(word_tokens)
print(pos_tags)
[('Those', 'DT'), ('who', 'WP'), ('can', 'MD'), ('imagine', 'VB'), ('anything', 'NN'), (',', ','), ('can', 'MD'), ('create', 'VB'), ('the', 'DT'), ('impossible', 'JJ'), ('.', '.')]
spaCy
사이썬 기반으로 개발된 오픈 소스 라이브러리로 NLTK와 주요한 차이점은 빠른 속도와 높은 정확도를 ㅁ고표로 하는 머신러닝 기반의 자연어 처리 라이브러리이다.
spaCy 품사 태깅
import spacy
nlp = spacy.load("en_core_web_sm")
sentence = "Those who can imagine anything, can create the impossible."
doc = nlp(sentence)
for token in doc:
print(f"[{token.pos_:5} - {token.tag_:3}] : {token.text}")
[PRON - DT ] : Those
[PRON - WP ] : who
[AUX - MD ] : can
[VERB - VB ] : imagine
[PRON - NN ] : anything
[PUNCT - , ] : ,
[AUX - MD ] : can
[VERB - VB ] : create
[DET - DT ] : the
[ADJ - JJ ] : impossible
[PUNCT - . ] : .
token 객체에는 기본 품사 속성(pos_), 세분화 품사 속성(tag_), 원본 텍스트 데이터(text), 토큰 사이의 공백을 포함하는 텍스트 데이터(text_with_ws), 벡터(vector), 벡터 노름(vector_norm) 등의 속성이 포함돼 있다.
doc[0].vector
array([-0.8486347 , 1.2700524 , -1.1639701 , 1.1595925 , 1.4136884 ,
-0.19614898, 0.9234905 , 0.4656181 , -1.0459173 , 0.11757521,
0.8527639 , 0.04633076, -1.1558002 , 0.9284301 , -0.7888708 ,
-1.5080042 , -1.313452 , 0.84806657, -1.1665629 , 0.3201223 ,
-0.9707377 , 0.62648225, 0.6703317 , -1.1460655 , -0.7319551 ,
0.2837017 , 1.144692 , 2.067832 , -0.13750742, 0.13024698,
-0.7051562 , -1.896528 , 0.17930242, -1.046402 , -0.07028227,
0.22457415, 1.1773777 , 0.92348135, 1.360117 , 1.6645081 ,
0.34043953, 0.7469084 , -1.9169496 , -0.00400883, -0.78598726,
1.3460159 , -0.53799343, 1.4254917 , -0.5480755 , -0.7898176 ,
-0.72548103, -0.17522047, 1.0688438 , -0.68190444, 1.0573025 ,
-0.11982081, 0.58483195, 0.8068689 , -1.2866131 , 1.3019196 ,
0.823109 , -0.7804225 , -0.3887528 , -0.48427325, 1.0155696 ,
-0.16501564, -0.20351282, -1.594498 , -0.38102418, -0.08264378,
-1.3360388 , 0.43359813, 1.5765481 , -0.7661784 , 0.0101665 ,
-1.369622 , 0.9651014 , 0.60561234, 0.13627677, -0.05248693,
-0.7497197 , -1.6170738 , 0.9136694 , -1.1382043 , 0.23294806,
1.7038027 , 1.1977704 , 1.0437009 , 1.3076078 , -0.7804035 ,
-0.8293568 , -1.050417 , 0.04823226, -0.5849173 , 0.9292893 ,
1.0312169 ], dtype=float32)
'책 > 파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습' 카테고리의 다른 글
06 임베딩 (1) N-gram, TF-IDF, Word2Vec, fastText (0) | 2024.01.10 |
---|---|
05 토큰화 (2) 하위 단어 토큰화 (0) | 2024.01.08 |
04 파이토치 심화 (4) 데이터 증강 및 변환 (0) | 2024.01.05 |
04 파이토치 심화 (3) 정칙화 (0) | 2024.01.05 |
04 파이토치 심화 (2) 가중치 초기화 (0) | 2024.01.04 |