import os
from konlpy.tag import Okt
import nltk
nltk.download()
from nltk import word_tokenize, pos_tag, ne_chunk
sentence = 'Mike is working at IT Centre'
# 토큰화, 품사태깅 pos_tag 후 -> ne_chunk 개체명인식
sentence = pos_tag(word_tokenize(sentence))
print(sentence)
# 개체명 인식
sentence = ne_chunk(sentence)
print(sentence)
저는 아나콘다 환경에서 파이썬을 사용하고 있으므로 이미 루트 가상환경에 NLTK가 설치가 되어있었습니다. KoNLPy와 다르게 별도의 설정등을 해줄 필요가 없습니다.아나콘다 내에서 가상환경을 따로 만들어 설치를 해줄시엔 해당 가상환경 activate 후에
> conda install nltk]
> conda update nltk
위 명령어를 입력하여 설치해주면 됩니다.
하지만 예제를 수행하면 여러 에러 메세지들을 볼 수 있습니다. 예를들어 nltk.download('words'), nltk.download('maxent_ne_chunker')를 하라는 등의 메세지가 뜨면 오류메세지에 뜬 명령어 그대로 입력해서 별도의 모듈들을 설치해주면 됩니다.
○ 예제 시행해보기
from nltk import word_tokenize, pos_tag, ne_chunk
sentence = 'Mike is working at IT Centre'
# 토큰화, 품사태깅 pos_tag 후 -> ne_chunk 개체명인식
sentence = pos_tag(word_tokenize(sentence))
print(sentence)
# 개체명 인식
sentence = ne_chunk(sentence)
print(sentence)
nltk.Text()는 자연어 데이터의 탐색을 편리하게 해주는 다양한 기능들을 제공합니다.
import nltk
from nltk.corpus import gutenberg
from nltk import regexp_tokenize
f = gutenberg.fileids()
doc_en = gutenberg.open('austen-emma.txt').read()
pattern = r'''(?x) ([A-Z]\.)+ | \w+(-\w+)* | \$?\d+(\.\d+)?%? | \.\.\. | [][.,;"'?():-_`]'''
tokens_en = regexp_tokenize(doc_en, pattern)
en = nltk.Text(toekns_en)
테스트를 하기 위해NLTK에서 제공하는 제인오스틴의 소설 Emma데이터를 다운받습니다. 이후문서를 토큰으로 나누는 작업을 해주었는데 한국어를 토크나이즈하거나 품사태깅, 개체명 태깅 등을 할 때는 KoNLPy를 이용하는 것이 훨씬 낫다고 봅니다.
예를 들어 NLTK에서 '나는 바보다'라는 문장에서 '바보다'라는 토큰의 개체명을 'Organization'으로 인식하는 등의 문제가 있습니다. 그래서 한국어 처리를 할 때에는 nltk를 데이터를 탐색하는 용도로 많이 사용하는 듯 합니다.
2. 그래프 그리기
en.plot(50)
en문서의 50개의 토큰만 플롯으로 그려보았습니다.
en.dispersion_plot(['Emma','Frank','Jane'])
3. 문서 탐색
print(len(en.tokens)) # 토큰의 개수 확인
print(len(set(en.tokens))) # Unique 토큰의 개수 확인
en.vocab() # Frequency Distribution 확인
print(en.count('Emma')) # 'Emma'의 개수
en.concordance('Emma', lines=5) # 'Emma'가 들어있는 5개의 문장만 출력
en.similar('Emma')
en.similar('Frank') # 비슷한 단어 찾기
> 결과
> 191061
> 7927
> FreqDist({',': 12018, '.': 8853, 'to': 5127, 'the': 4844, 'and': 4653, 'of': 4278, '"': 4187, 'I': 3177, 'a': 3000, 'was': 2385, ...})
> 865
> Displaying 5 of 865 matches:
Emma by Jane Austen 1816 ] VOLUME I CHAPT
Emma Woodhouse , handsome , clever , and
both daughters , but particularly of Emma . Between them it was more the int
friend very mutually attached , and Emma doing just what she liked ; highly e
r own . The real evils , indeed , of Emma situation were the power of havi
> she it he i harriet you her jane him that me and all they them there herself was hartfield be
mr mrs emma harriet you it her she he him hartfield them jane that isabella all herself look i me
그래프를 그리는 것 외에도 토큰의 개수나 frequency distribution등을 확인하여데이터의 구조를 살펴보는데 좋은 기능들도 많이 제공하고 있습니다.
4. Chunking nltk.RegexParser()
Chunking얕은 구문 분석, 음성 및 단구 (명사구와 같은)를 식별하는 것
tokens = "The little yellow dog barked at the Persian cat".split()
tags_en = nltk.pos_tag(tokens)
parser_en = nltk.RegexpParser("NP: {<DT>?<JJ>?<NN.*>*}")
chunks_en = parser_en.parse(tags_en)
chunks_en.draw()
NLTK에서는 영어 코퍼스에 품사 태깅 기능을 지원하고 있습니다. 품사를 어떻게 명명하고, 태깅하는지의 기준은 여러가지가 있는데, NLTK에서는 Penn Treebank POS Tags라는 기준을 사용합니다. 실제로 NLTK를 사용해서 영어 코퍼스에 품사 태깅을 해보도록 하겠습니다.
nltk 에러나면 CMD에서 pip install nltk
>>> from nltk.tokenize import word_tokenize
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
from nltk.tokenize import word_tokenize
ModuleNotFoundError: No module named '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)가 있습니다.
한국어 자연어 처리를 위해서는 KoNLPy("코엔엘파이"라고 읽습니다)라는 파이썬 패키지를 사용할 수 있습니다. 코엔엘파이를 통해서 사용할 수 있는 형태소 분석기로 Okt(Open Korea Text), 메캅(Mecab), 코모란(Komoran), 한나눔(Hannanum), 꼬꼬마(Kkma)가 있습니다.
한국어 NLP에서 형태소 분석기를 사용한다는 것은 단어 토큰화가 아니라 정확히는 형태소(morpheme) 단위로 형태소 토큰화(morpheme tokenization)를 수행하게 됨을 뜻합니다. 여기선 이 중에서 Okt와 꼬꼬마를 통해서 토큰화를 수행해보도록 하겠습니다. (Okt는 기존에는 Twitter라는 이름을 갖고있었으나 0.5.0 버전부터 이름이 변경되어 인터넷에는 아직 Twitter로 많이 알려져있으므로 학습 시 참고바랍니다.)
위 예제에서 사용된 각 메소드는 이런 기능을 갖고 있습니다. 앞서 언급한 코엔엘파이의 형태소 분석기들은 공통적으로 이 메소드들을 제공하고 있습니다. 위 예제에서 형태소 추출과 품사 태깅 메소드의 결과를 보면, 조사를 기본적으로 분리하고 있음을 확인할 수 있습니다. 그렇기 때문에 한국어 NLP에서 전처리에 형태소 분석기를 사용하는 것은 꽤 유용합니다.
앞서 사용한 Okt 형태소 분석기와 결과가 다른 것을 볼 수 있습니다. 각 형태소 분석기는 성능과 결과가 다르게 나오기 때문에, 형태소 분석기의 선택은 사용하고자 하는 필요 용도에 어떤 형태소 분석기가 가장 적절한지를 판단하고 사용하면 됩니다. 예를 들어서 속도를 중시한다면 메캅을 사용할 수 있습니다.
fromtwythonimportTwythonimportsettingsass# Create a file named settings.py, and put oauth KEY values insidetwitter=Twython(s.APP_KEY,s.APP_SECRET,s.OAUTH_TOKEN,s.OAUTH_TOKEN_SECRET)tweets=twitter.search(q='삼성',count=100)data=[(t['user']['screen_name'],t['text'],t['created_at'])fortintweets['statuses']]
fromnltk.corpusimportgutenberg# Docs from project gutenberg.orgfiles_en=gutenberg.fileids()# Get file idsdoc_en=gutenberg.open('austen-emma.txt').read()
Korean
fromkonlpy.corpusimportkobill# Docs from pokr.kr/billfiles_ko=kobill.fileids()# Get file idsdoc_ko=kobill.open('1809890.txt').read()
2. Tokenize
문서를 토큰으로 나누는 방법은 다양하다. 여기서는 영어에는 nltk.regexp_tokenize, 한국어에는 konlpy.tag.Twitter.morph를 사용해보자.
print(len(en.tokens))# returns number of tokens (document length)print(len(set(en.tokens)))# returns number of unique tokensen.vocab()# returns frequency distribution
print(len(ko.tokens))# returns number of tokens (document length)print(len(set(ko.tokens)))# returns number of unique tokensko.vocab()# returns frequency distribution
en.plot(50)# Plot sorted frequency of top 50 tokens
Korean
ko.plot(50)# Plot sorted frequency of top 50 tokens
Tip: To save a plot programmably, and not through the GUI, overwrite pylab.show with pylab.savefig before drawing the plot (reference):
from matplotlib import pylab
pylab.show = lambda: pylab.savefig('some_filename.png')
Troubleshooting: For those who see rectangles instead of letters in the saved plot file, include the following configurations before drawing the plot:
from matplotlib import font_manager, rc
font_fname = 'c:/windows/fonts/gulim.ttc' # A font of your choice
font_name = font_manager.FontProperties(fname=font_fname).get_name()
rc('font', family=font_name)
Some example fonts:
Mac OS: /Library/Fonts/AppleGothic.ttf
Count
English
en.count('Emma')# Counts occurrences
865
Korean
ko.count('초등학교')# Counts occurrences
6
Dispersion plot
English
en.dispersion_plot(['Emma','Frank','Jane'])
Korean
ko.dispersion_plot(['육아휴직','초등학교','공무원'])
Concordance
English
en.concordance('Emma',lines=5)
Displaying 5 of 865 matches:
Emma by Jane Austen 1816 ] VOLUME I CHAPT
Emma Woodhouse , handsome , clever , and
both daughters , but particularly of Emma . Between them it was more the int
friend very mutually attached , and Emma doing just what she liked ; highly e
r own . The real evils , indeed , of Emma ' s situation were the power of havi
Displaying 6 of 6 matches:
․ 김정훈 김학송 의원 ( 10 인 ) 제안 이유 및 주요 내용 초등학교 저학년 의 경우 에도 부모 의 따뜻한 사랑 과 보살핌 이 필요 한
을 할 수 있는 자녀 의 나이 는 만 6 세 이하 로 되어 있어 초등학교 저학년 인 자녀 를 돌보기 위해서 는 해당 부모님 은 일자리 를
다 . 제 63 조제 2 항제 4 호 중 “ 만 6 세 이하 의 초등학교 취학 전 자녀 를 ” 을 “ 만 8 세 이하 ( 취학 중인 경우
전 자녀 를 ” 을 “ 만 8 세 이하 ( 취학 중인 경우 에는 초등학교 2 학년 이하 를 말한 다 ) 의 자녀 를 ” 로 한 다 . 부
. ∼ 3 . ( 현행 과 같 음 ) 4 . 만 6 세 이하 의 초등학교 취 4 . 만 8 세 이하 ( 취학 중인 경우 학 전 자녀 를 양
세 이하 ( 취학 중인 경우 학 전 자녀 를 양육 하기 위하 에는 초등학교 2 학년 이하 를 여 필요하거 나 여자 공무원 이 말한 다 ) 의
Find similar words
English
en.similar('Emma')en.similar('Frank')
she it he i harriet you her jane him that me and all they them there herself was hartfield be
mr mrs emma harriet you it her she he him hartfield them jane that isabella all herself look i me
Korean
ko.similar('자녀')ko.similar('육아휴직')
논의
None
Collocations
English
en.collocations()
Frank Churchill; Miss Woodhouse; Miss Bates; Jane Fairfax; Miss
Fairfax; every thing; young man; every body; great deal; dare say;
John Knightley; Maple Grove; Miss Smith; Miss Taylor; Robert Martin;
Colonel Campbell; Box Hill; said Emma; Harriet Smith; William Larkins
Korean
en.collocations()
초등학교 저학년; 육아휴직 대상
For more information on nltk.Text(), see the source code or API.
Tagging and chunking
Until now, we used delimited text, namely tokens, to explore our sample document. Now let's classify words into given classes, namely part-of-speech tags, and chunk text into larger pieces.
1. POS tagging
There are numerous ways of tagging a text. Among them, the most frequently used, and developed way of tagging is arguably POS tagging.
Since one document is too long to observe a parsed structure, lets use one short sentence for each language.
English
tokens="The little yellow dog barked at the Persian cat".split()tags_en=nltk.pos_tag(tokens)