자연어 처리

Ho Jin Lee·2021년 9월 14일
0

자연어

목록 보기
1/3

기본


Corpus: 말뭉치, 언어 연구를 염두에 두고 구축 된 말,글,텍스트의 모음

Word Tokenization: 단어 토큰화, Word(단어, 단어구, 의미를 갖는 문자열)기준으로 토큰화 하는 것.

Ex: Hi, my name is Richard!
=> "Hi","my","name","is","Richard"

하지만 쉼표, 구두점을 제거하면 문제가 생김.
이 처럼 영어는 띄어쓰기로만 토큰화 할 수 있지만, 한국어의 경우 쉽지 않음.

토큰화 문제


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 를 어떻게 해야할까
Don't
Don t
Dont
Do n't
?

Jone's의 경우는?
Jone's
Jone s
Jone
Jones
?

NLTK(Natural Languagae Tool Kit)에서는
word_tokenize 와 WordPuncTonkenizer를 지원.

word_tokenize는 Don't를 Do와 n't로 분리하고,
wordPuncTonkenizer는 Don과 ', t로 분리하고, Jone과 ', s로 구두점을 별도로 분류한다.

Keras의 text_to_word_sequence에서는 don't, jone's로 모두 소문자로 만든 뒤 구두점은 제거되지만 어포스트로피는 보존 된다.

어떻게 토큰화?


구두점, 특수문자를 단순제외 X
줄임말과 단어내에 띄어쓰기가 있는경우 고려해야함.

표준 토큰화 예제

Penn Treebank Tokenization

규칙 1. 하이픈으로 구성도니 단어는 하나로 유지
규칙 2. doesn't와 같이 어퍼스트로피로 단축된 단어는 분리한다.

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', '.'] 

문장토큰화


토큰의 단위가 문장일 때

코퍼스가 정제되어 있지 않다면 문장 단위 구분이 필요->
! ?로는 확실히 구분가능 하지만, .같은 경우 이메일, 웹사이트 같이 확실 치 않음.

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='IP 192.168.56.31 서버에 들어가서 로그 파일 저장해서 ukairia777@gmail.com로 결과 좀 보내줘. 그러고나서 점심 먹으러 가자.'
print(kss.split_sentences(text))
#['IP 192.168.56.31 서버에 들어가서 로그 파일 저장해서 ukairia777@gmail.com로 결과 좀 보내줘.', '그러고나서 점심 먹으러 가자.']

이진 분류기(Binary Classifier)

  1. 마침표(.)가 단어의 일부분일 경우. 즉, 마침표가 약어(abbreivation)로 쓰이는 경우
  2. 마침표(.)가 정말로 문장의 구분자(boundary)일 경우를 의미할 것입니다.

이러한 문장 토큰화를 수행하는 오픈 소스로는 NLTK, OpenNLP, 스탠포드 CoreNLP, splitta, LingPipe 등이 있습니다. 문장 토큰화 규칙을 짤 때, 발생할 수 있는 여러가지 예외사항을 다룬 참고 자료로 아래 링크를 보면 좋습니다.
https://www.grammarly.com/blog/engineering/how-to-split-sentences/

한국어 처리의 어려움

1) 한국어는 교착어이다.

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

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

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

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

품사 태깅

못 같은 단어의 경우 Can't 또는 nail의 의미를 가질 수 있음
영어의 fly도 날다 또는 파리의 뜻을 가질 수 있기 때문에 명사로 쓰였는지, 동사로 쓰였는지 같은 품사를 태깅 해둠.

NLTK KoNLPy

NLTK는 영어 품사태깅
Penn Treebank POS Tags 사용

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)

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(Twitter)
1) morphs : 형태소 추출
2) pos : 품사 태깅(Part-of-speech tagging)
3) 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("열심히 코딩한 당신, 연휴에는 여행을 가봐요"))  
#['코딩', '당신', '연휴', '여행']  
profile
배 터져 죽을 때까지

0개의 댓글