SlideShare a Scribd company logo
1 of 52
Download to read offline
노가다 없는 텍스트 분석을 위한
한국어 NLP
파이콘 코리아 2017
김현중 (soy.lovit@gmail.com)
1
노가다 없는 텍스트 분석을 위한
한국어 NLP
Hyunjoong Kim
soy.lovit@gmail.com
2
• KoNLPy는 Python에서 사용할 수 있는 한국어 자연어처리 패키지
* http://konlpy.org/ko/latest/
from konlpy.tag import Kkma
kkma = Kkma()
print(kkma.nouns(u'질문이나 건의사항은 깃헙 이슈 트래커에 남겨주세요.'))
3
[질문, 건의, 건의사항, 사항, 깃헙, 이슈, 트래커]
print(kkma.pos(u'오류보고는 실행환경, 에러메세지와함께 설명을 최대한상세히!^^'))
[(오류, NNG), (보고, NNG), (는, JX), (실행, NNG), (환경, NNG), (,, SP),
(에러, NNG), (메세지, NNG), (와, JKM), (함께, MAG), (설명, NNG), (을, JKO),
(최대한, NNG), (상세히, MAG), (!, SF), (^^, EMO)]
미등록단어 문제
• 새롭게 만들어진 단어들은 인식이 잘 되지 않습니다
from konlpy.tag import Kkma, Twitter
kkma = Kkma()
twitter = Twitter()
kkma.pos(‘파이콘에서 엔엘피이야기를 합니다‘)
4
파이/NNG, 콘/NNG, 에서/JKM, 엔엘피/NNG, 이야기/NNG, 를/JKO, 하/VV, ㅂ시다/EF
twitter.pos(‘파이콘에서 엔엘피이야기를 합니다‘)
파/Noun, 이콘/Noun, 에서/Josa, 엔/Josa, 엘피/Noun, 이야기/Noun, 를/Josa, 합/Verb, 시/PreEomi, 다/Eomi
미등록단어 문제
• 새롭게 만들어진 단어들은 인식이 잘 되지 않습니다
from konlpy.tag import Kkma, Twitter
kkma = Kkma()
twitter = Twitter()
kkma.pos(‘너무너무너무는 아이오아이의 노래에요‘)
5
너무/MAG, 너무너무/MAG, 는/JX, 아이오/NNG, 아이/NNG, 의/JKG, 노래/NNG, 에/JKM, 요/JX
twitter.pos(‘너무너무너무는 아이오아이의 노래에요‘)
너무/Noun, 너무/Noun, 너무/Noun, 는/Josa, 아이오/Noun, 아이/Noun, 의/Josa, 노래/Noun, 에요/Josa
미등록단어 문제
• 이를 해결하기 위하여 사용자 사전을 추가하여 사용합니다
• 주로 이 작업은 품사 판별을 한 뒤, 빈도수가 높은 단어들 중에서 잘못 처리된
단어를 고르는 방식입니다
• 이 반복적/노동집약적인 과정을 최대한 자동화 하는게 목표입니다
6
우리가 다룰 이야기
• 사용자 사전을 사람이 만들지 말고, 데이터 기반으로 추출할 것입니다
• 여러 단어 추출 기법들 중 cohesion에 대하여 살펴봅니다.
• 단어 중에서도 명사는 따로 추출할 것입니다
• 명사는 새로운 단어가 가장 많이 생성되고 사용도 가장 많이 되는 품사입니다
7
Part 1: 단어 추출 + 토크나이징
Part 2: 명사 추출
부록 : KoNLPy + 사용자사전
8
단어 추출 + 토크나이징
https://github.com/lovit/soynlp
9
단어 추출
• 우리도 뉴스나 글을 읽으면서 새로운 단어들을 쉽게 학습합니다
• 단어는 (특히 명사는) 경계에 특징이 있습니다.
우리는 이를 이용하여 통계 기반으로 단어를 추출합니다
• 단, 1음절 단어는 제외합니다.
단어 길이가 1이면 봐도 무슨 말인지 해석하기 힘듧니다 (= 모호합니다)
10
Cohesion (Character n-gram)
• 한국어의 의미를 지니는 단어 (명사/동사/형용사/부사)는 어절 왼쪽에 있습니다
짜장면/명사 + 을/조사
먹/동사 + 었어/어미
11
Cohesion (Character n-gram)
• 맥락이 충분히 주어지지 않으면 다음에 등장할 글자의 확률이 작습니다
• 한글자 (‘아‘)는 매우 모호한 문맥입니다
아이
> 아니 17.15 %
> 아이 14.86 %
> 아시 8.06 %
> 아닌 4.74 %
> 아파 4.43 %
> 아직 3.85 %
…
한글자는 특별한 문맥을
가지기가 어렵습니다
12
Cohesion (Character n-gram)
• 맥락이 충분히 주어지지 않으면 다음에 등장할 글자의 확률이 작습니다
아이오
> 아이폰 16.60 %
> 아이들 13.37 %
> 아이디 9.66 %
> 아이돌 6.77 %
> 아이뉴 6.77 %
> 아이오 6.53 %
…
13
어떤 경우는 두 글자라 하더라도
다양한 맥락에서 등장하기도 합니다
Cohesion (Character n-gram)
• Subword 다음에 등장할 글자가 쉽게 예상된다면 (확률이 높다면) 아직 단어가
끝나지 않았다는 의미입니다
아이오아
> 아이오아 87.95 %
> 아이오닉 7.49 %
> 아이오와 3.26 %
> 아이오빈 0.65 %
> 아이오페 0.33 %
> 아이오케 0.33 %
문맥이 명확해 질수록
이전 단어  다음 글자 확률이
높아집니다
14
Cohesion (Character n-gram)
• Subword 다음에 등장할 글자가 쉽게 예상된다면 (확률이 높다면) 아직 단어가
끝나지 않았다는 의미입니다
아이오아이
> 아이오아이 100.00 %
15
문맥이 확실하면 다음글자의
등장 확률이 높습니다
Cohesion (Character n-gram)
• 단어의 경계를 넘으면 다음 글자에 대한 확률이 다시 작아집니다
아이오아이는
> 아이오아이의 31.97 %
> 아이오아이는 27.21 %
> 아이오아이와 13.61 %
> 아이오아이가 12.24 %
> 아이오아이에 9.52 %
> 아이오아이까 1.36 %
…
16
단어 경계 뒤에는 다양한
조사/어미 들이 등장합니다
Cohesion (Character n-gram)
• 단어의 점수(cohesion)를 아래처럼 정의해 봅니다
𝑐𝑜ℎ𝑒𝑠𝑖𝑜𝑛(𝑐1:𝑛 ) =
𝑛−1
𝑖=1
𝑛−1
𝑃(𝑐1:𝑖+1|𝑐1:𝑖, )
𝑃 𝑐1:2 𝑐1 =
#𝑐1:2
#𝑐1
cohesion(‘아이오아이’) = { p(아  아이) *
p(아이  아이오) *
p(아이오  아이오아) *
p(아이오아  아이오아이)
} 1/(5-1)
학습은 오로직
string count
17
Cohesion (Character n-gram)
• 어절의 왼쪽부터 subword의 빈도수를 세어봅니다.
docs = [‘파이콘에서 발표를 합니다‘,
… ]
from collections import defaultdict
count= defaultdict(lambda: 0)
for doc in docs:
for word in doc.split():
n = len(word)
for e in range(1, n+1):
count[word[:e]] += 1
18
Cohesion (Character n-gram)
• Subword의 빈도수와 P(AB|A)를 계산해 봅니다
word = '아이오아이는‘
n = len(word)
for e in range(2, n+1):
w = word[:e]
f = count[w]
p = f/count[:e-1]
print('{:6}, f={}, p={:.2}'.
format(w, f, p))
아이, f=4910, p=0.15
아이오, f=307, p=0.06
아이오아, f=270, p=0.88
아이오아이, f=270, p=1.00
아이오아이는, f=40, p=0.15
19
Cohesion (Character n-gram)
• 단어의 점수(cohesion)를 아래처럼 구현해 봅니다
def cohesion(w):
return pow(count[w]/count[w[0]],
1/(len(w)-1))
word = '아이오아이가‘
n = len(word)
for e in range(2, n+1):
w = word[:e]
f = count[w]
s = cohesion(w)
print('{:6}, f={}, s={:.2}'.
format(w, f, s))
아이, f=4910, s=0.15
아이오, f=307, s=0.10
아이오아, f=270, s=0.20
아이오아이, f=270, s=0.30
아이오아이가, f=18, s=0.22
단어로 선택
#𝑐1:4
#𝑐1
=
#𝑐1:2
#𝑐1
∗
#𝑐1:3
#𝑐1:2
∗
#𝑐1:4
#𝑐1:3
20
Cohesion (Character n-gram)
• 단어의 점수(cohesion)를 아래처럼 구현해 봅니다
def cohesion(w):
return pow(count[w]/count[w[0]],
1/(len(w)-1))
word = '아이오아이가‘
n = len(word)
for e in range(2, n+1):
w = word[:e]
f = count[w]
s = cohesion(w)
print('{:6}, f={}, s={:.2}'.
format(w, f, s))
아이, f=4910, s=0.15
아이오, f=307, s=0.10
아이오아, f=270, s=0.20
아이오아이, f=270, s=0.30
아이오아이가, f=18, s=0.22
단어로 선택
#𝑐1:4
#𝑐1
=
#𝑐1:2
#𝒄 𝟏
∗
#𝑐1:3
#𝑐1:2
∗
#𝒄 𝟏:𝟒
#𝑐1:3
21
Tokenizer
• 단어를 잘 인식할 수 있다면 토크나이징도 쉽게 할 수 있습니다
• 토크나이징은 여러 개의 단어로 이뤄진 문장/어절에서 단어를 구분하는 것
• 띄어쓰기 오류 정도에 따라 다른 토크나이징 전략을 사용할 수 있습니다
22
L-Tokenizer
• 띄어쓰기가 잘 되어 있다면, 어절의 왼쪽에서부터
단어의 점수가 가장 큰 subword를 기준으로 어절을 나눕니다
def ltokenize(w):
n = len(w)
if n <= 2: return (w, '')
tokens = []
for e in range(2, n+1):
tokens.append(w[:e], w[e:], cohesion(w[:e]))
tokens = sorted(tokens, key=lambda x:-x[2])
return tokens[0][:2]
sent = ‘뉴스의 기사를 이용했던 예시입니다'
for word in sent.split():
print( ltokenize(word) )
('뉴스', '의')
('기사', '를')
('이용', '했던')
('예시', '입니다')
23
Max Score Tokenizer
• 띄어쓰기가 잘 되어있지 않다면 아는 단어부터 잘라내면 됩니다
cohesions = {'파스': 0.3, '파스타': 0.7, '좋아요': 0.2, '좋아':0.5}
score = lambda x: cohesions.get(x, 0)
tokenize('파스타가좋아요')
[('파스', 0, 2, 0.3),
('파스타', 0, 3, 0.7),
('스타', 1, 3, 0),
('스타가', 1, 4, 0),
('타가', 2, 4, 0),
('타가좋', 2, 5, 0),
('가좋', 3, 5, 0),
('가좋아', 3, 6, 0),
('좋아', 4, 6, 0.5),
('좋아요', 4, 7, 0.2),
('아요', 5, 7, 0)]
[('파스타', 0, 3, 0.7),
('좋아', 4, 6, 0.5),
('파스', 0, 2, 0.3),
('좋아요', 4, 7, 0.2),
('스타', 1, 3, 0),
('스타가', 1, 4, 0),
('타가', 2, 4, 0),
('타가좋', 2, 5, 0),
('가좋', 3, 5, 0),
('가좋아', 3, 6, 0),
('아요', 5, 7, 0)]
[('파스타', 0, 3, 0.7),
('좋아', 4, 6, 0.5),
('파스', 0, 2, 0.3),
('좋아요', 4, 7, 0.2),
('스타', 1, 3, 0),
('스타가', 1, 4, 0),
('타가', 2, 4, 0),
('타가좋', 2, 5, 0),
('가좋', 3, 5, 0),
('가좋아', 3, 6, 0),
('아요', 5, 7, 0)]
Subword 별 score 계산
(subword, begin, end, score)
Score 기준으로 정렬 최고점수의 단어 선택,
위치가 겹치는 단어 제거 24
Max Score Tokenizer
• 띄어쓰기가 잘 되어있지 않다면 아는 단어부터 잘라내면 됩니다
cohesions = {'파스': 0.3, '파스타': 0.7, '좋아요': 0.2, '좋아':0.5}
score = lambda x: cohesions.get(x, 0)
[('파스타', 0, 3, 0.7),
('좋아', 4, 6, 0.5),
('파스', 0, 2, 0.3),
('좋아요', 4, 7, 0.2),
('스타', 1, 3, 0),
('스타가', 1, 4, 0),
('타가', 2, 4, 0),
('타가좋', 2, 5, 0),
('가좋', 3, 5, 0),
('가좋아', 3, 6, 0),
('아요', 5, 7, 0)]
[('파스타', 0, 3, 0.7),
('좋아', 4, 6, 0.5),
('파스', 0, 2, 0.3),
('좋아요', 4, 7, 0.2),
('스타', 1, 3, 0),
('스타가', 1, 4, 0),
('타가', 2, 4, 0),
('타가좋', 2, 5, 0),
('가좋', 3, 5, 0),
('가좋아', 3, 6, 0),
('아요', 5, 7, 0)]
[파스타, 가, 좋아, 요]
[파스타]가좋아요 [파스타]가[좋아]요
25
Max Score Tokenizer
• 확실히 아는 단어라면 scores에 최고 점수를 줄 수 있습니다
cohesions = {'파스': 0.3, '파스타': 0.7, '좋아요': 0.2, '좋아':0.5, ‘아이오아이’:1.0}
score = lambda x:cohesions.get(x, 0)
26
soynlp
• Cohesion, Branching Entropy 를 포함한, 단어 추출에 관련된 함수들을
github에 구현해 두었습니다.
from soynlp import DoublespaceLineCorpus
from soynlp.word import WordExtractor
corpus = DoublespaceLineCorpus(fname, iter_sent=True)
word_extractor = WordExtractor(corpus, min_count=10)
words = word_extractor.extract()
27
soynlp
• extract()는 단어 경계와 관련된 점수들이 계산되어 있는 dict를
return 합니다
words = word_extractor.extract()
words[‘드라마']
Scores(cohesion_forward=0.6093651029086764,
cohesion_backward=0.5282705437953743,
left_branching_entropy=3.6583115265560924,
right_branching_entropy=3.675624807575614,
left_accessor_variety=128,
right_accessor_variety=136,
leftside_frequency=2375,
rightside_frequency=1284)
28
soynlp
• Tokenizer 역시 구현되어 있습니다
from soynlp.tokenizer import LTokenizer
scores = {w:s.cohesion_forward for w, s in words.items()}
tokenizer = LTokenizer(scores=scores)
tokenizer.tokenize(‘뉴스의 기사를 이용했던 예시입니다')
[‘뉴스‘, ‘의 ‘, ‘기사‘, ‘를 ‘, ‘이용‘, ‘했던‘, ‘예시‘, ‘입니다‘]
29
soynlp
• 사전이 없이도 데이터 기반으로 토크나이저를 학습하면 잘 작동합니다
• 현재 분석 중인 데이터에 해당 알고리즘을 적용한 예시입니다
from soynlp.tokenizer import MaxScoreTokenizer
scores = {w:s.cohesion_forward for w, s in words.items()}
tokenizer = MaxScoreTokenizer(scores=scores)
tokenizer.tokenize(‘맛있는짜파게티파스타일식초밥소바김볶다먹고싶어라일단김밥천국으로고고')
['맛있', '는', '짜파게티', '파스타', '일식', '초밥', '소바', '김볶', '다', '먹고', '싶어', '라',
'일단', '김밥천국', '으로', '고고']
30
명사 추출
https://github.com/lovit/soynlp
31
명사
• 지금까지 분석할 데이터를 기반으로, 그 데이터에서 사용되는
단어를 추출하는 방법을 이야기했습니다
• 이번에는 {‘파스타’, ‘좋아’} 와 같은 단어에서 ‘파스타‘라는 명사만 선택하는
방법을 알아봅니다
32
A는 명사일까?
어제 A라는 가게에 가봤어
A에서 보자
A로 와줘
명사 우측에 등장하는 글자 분포를 이용하여
A가 명사임을 유추할 수 있다
33
L – R graph
• 어절은 L + [R] 구조로 나눌 수 있습니다
• 발표 + 를
• 하 + 면서
• 데이터에서 모든 어절들을 두 개의 subwords로 나눈 뒤 연결하면
L – R graph를 만들 수 있습니다
34
L – R graph
드라마
파이콘
발표
시작했
먹
달리
…
파이
를
지마
의
로
에서
…
콘에서
었어
고서
frequency (드라마 – 를)
L R
35
L – R graph
드라마
파이콘
발표
시작했
먹
달리
…
파이
를
지마
의
로
에서
…
콘에서
었어
고서
명사들의 오른쪽에는
조사들이 주로 연결되어 있습니다
36
L – R graph
드라마
파이콘
발표
시작했
먹
달리
…
파이
를
지마
의
로
에서
…
콘에서
었어
고서
동사/형용사들의 오른쪽에는
어미들이 주로 연결되어 있습니다
37
L – R graph
드라마
파이콘
발표
시작했
먹
달리
…
파이
를
지마
의
로
에서
…
콘에서
었어
고서
L이 제대로 된 단어가 아니면
오른쪽에도 조사/어미가 아닌 R이 연결됩니다
38
Noun Extraction
• L – R graph를 만들면 명사가 눈에 보입니다
lrgraph = defaultdict(lambda: defaultdict(lambda: 0))
for doc in docs:
for w in doc.split():
n = len(w)
for e in range(1, n+1):
lrgraph[ w[ :e] ][ w[e: ] ] += 1
def get_r(L):
return sorted( lrgraph[L].items(), key=lambda x:-x[1])
get_r(‘드라마’)
[('', 1268),
('를', 164),
('다', 152),
('의', 140),
('로', 138),
('에서', 98),
('와', 62),
('는', 55),
('에', 55),
('가', 48),
('이다', 24),
('인', 14),
… ]
39
Noun Extraction
• L – R graph: [명사 + 조사], [동사 + 어미], [틀린 단어 + 틀린 단어]
get_r(‘드라마')
[('', 1268),
('를', 164),
('다', 152),
('의', 140),
('로', 138),
('에서', 98),
('와', 62),
('는', 55),
('에', 55),
('가', 48),
('이다', 24),
('인', 14),
… ]
get_r('드라')
[('마', 1268),
('마를', 164),
('마다', 152),
('마의', 140),
('마로', 138),
('마에서', 98),
('기', 65),
('마와', 62),
('마는', 55),
('마에', 55),
('마가', 48),
('이브', 28),
… ]
get_r('시작했')
[('다', 567),
('고', 73),
('다고', 61),
('습니다', 42),
('는데', 26),
('으며', 16),
('지만', 15),
('던', 12),
('어요', 10),
('다는', 7),
('으나', 5),
('죠', 4),
… ] 40
Noun Extraction
• L – R graph: [명사 + 조사], [동사 + 어미], [틀린 단어 + 틀린 단어]
get_r('드라마')
[('', 1268),
('를', 164),
('다', 152),
('의', 140),
('로', 138),
('에서', 98),
('와', 62),
('는', 55),
('에', 55),
('가', 48),
('이다', 24),
('인', 14),
… ]
get_r('드라')
[('마', 1268),
('마를', 164),
('마다', 152),
('마의', 140),
('마로', 138),
('마에서', 98),
('기', 65),
('마와', 62),
('마는', 55),
('마에', 55),
('마가', 48),
('이브', 28),
… ]
get_r('시작했')
[('다', 567),
('고', 73),
('다고', 61),
('습니다', 42),
('는데', 26),
('으며', 16),
('지만', 15),
('던', 12),
('어요', 10),
('다는', 7),
('으나', 5),
('죠', 4),
… ] 41
Noun Extraction
• L – R graph: [명사 + 조사], [동사 + 어미], [틀린 단어 + 틀린 단어]
get_r('드라마')
[('', 1268),
('를', 164),
('다', 152),
('의', 140),
('로', 138),
('에서', 98),
('와', 62),
('는', 55),
('에', 55),
('가', 48),
('이다', 24),
('인', 14),
… ]
get_r('드라')
[('마', 1268),
('마를', 164),
('마다', 152),
('마의', 140),
('마로', 138),
('마에서', 98),
('기', 65),
('마와', 62),
('마는', 55),
('마에', 55),
('마가', 48),
('이브', 28),
… ]
get_r('시작했')
[('다', 567),
('고', 73),
('다고', 61),
('습니다', 42),
('는데', 26),
('으며', 16),
('지만', 15),
('던', 12),
('어요', 10),
('다는', 7),
('으나', 5),
('죠', 4),
… ] 42
Noun Extraction
• R 의 분포를 이용하여 L의 명사 점수를 계산할 수 있습니다
드라마
를 (164)
다 (152)
의 (140)
로 (138)
에서 (98)
와 (62)
…
r_scores = {'은': 0.5, ‘었다': -0.9, … }
def noun_score(L):
(norm, score, _total) = (0, 0, 0)
for R, frequency in get_r(L):
_total += frequency
if not R in r_scores:
continue
norm += frequency
score += frequency * r_scores[R]
score = score / norm if norm else 0
prop = norm / _total if _total else 0
return score, prop
𝑆 𝐿 𝑙 =
𝑓 𝑙, 𝑟 ∗ 𝑆 𝑅(𝑟)
𝑟∈𝐿 𝑅
𝑓(𝑙, 𝑟)
43
Noun Extraction
• R 의 분포를 이용하여 L의 명사 점수를 계산할 수 있습니다
noun_score('드라마‘)
(0.574, 0.921)
noun_score(‘시작했‘)
(-0.976, 0.999)
noun_score(‘드라‘)
(-0.661, 0.579)
틀린 단어 뒤에는 조사/어미 들이 아닌
글자들이 등장
(명사 점수, 알려진 R 비율) = noun_score(‘Word‘)
44
Noun Extraction
• R 점수는 세종 말뭉치를 이용하여 계산합니다
• 세종 말뭉치의 품사가 태깅된 정보로부터 L – R 구조의 테이블을 만듭니다
...
예술가의 예술가/NNG+의/JKG 113
예술가는 예술가/NNG+는/JX 45
예술가가 예술가/NNG+가/JKS 43
예술가들의예술가/NNG+들/XSN+의/JKG 30
...
단어 / R - 는 - 의 - 고 - 었다 -었던
예술가 45 113 2 0 0
먹 33 0 27 0 27
… … … … … …
단어 품사
명사
동사
…
45
Noun Extraction
• 명사의 빈도를 고려하여 – R 앞에 명사가 등장할 점수를 계산합니다
단어 / R - 는 - 의 - 고 - 었다 -구나
예술가 45 113 2 0 0
나이 54 87 27 0 27
들 0 0 0 255 0
춥 0 0 0 0 87
… … … … … …
품사
명사
명사
동사
형용사
…
품사 빈도수 (비율)
명사 704,197 (0.838)
^명사 136,598 (0.162)
품사 빈도수 보정빈도수 점수
명사 980 980 0.810
= (980 – 103.5)
/ (980 + 103.5)
^명사 20 103.5 =
20 * (0.838/0.162)
46
soynlp
• 후처리과정이 추가된 명사 추출기를 구현하였습니다
from soynlp.noun import LRNounExtractor
noun_extractor = LRNounExtractor(min_count=50)
nouns = noun_extractor.train_extract(corpus, minimum_noun_score=0.5)
nouns[‘설입‘]
47
NounScore(frequency=67, score=0.926, known_r_ratio=0.529)
nouns[‘드라마‘]
NounScore(frequency=4976, score=0.522, known_r_ratio=0.601)
KoNLPy + 사용자사전
https://github.com/lovit/customized_konlpy
48
사용자 사전 + 템플릿매칭을 이용한 토크나이징/품사판별
• 명사/단어에 대해서 사용자 사전을 만든다면, 내가 임의의 템플릿을
만들어서 템플릿 매칭으로 아는 단어들을 처리할 수도 있습니다
custom_dictionary = {'Noun': [‘파이콘', '엔엘피', '아이오아이', '너무너무너무']}
templates = [('Noun', 'Noun'),
('Noun', 'Josa'),
('Noun', 'Noun', ‘Josa')]
49
사용자 사전 + 템플릿매칭을 이용한 토크나이징/품사판별
custom_dictionary = {'Noun': ['파이콘', '엔엘피', '아이오아이', '너무너무너무']}
templates = [('Noun', 'Noun'),
('Noun', 'Josa'),
('Noun', 'Noun', ‘Josa')]
[파이콘][에서] [엔엘피][이야기][를] 합시다
(Noun, Josa)
(Noun, Noun, Josa) Unknown  KoNLPy에 넘기자
* 빨간색은 사용자에 의하여 추가된 사전에서 매칭
* 파란색은 KoNLPy의 트위터 분석기에 포함되어 있는 사전에서 매칭
50
사용자 사전 + 템플릿매칭을 이용한 토크나이징/품사판별
• customized_KoNLPy에 사전/템플릿 추가를 쉽게 할 수 있도록 KoNLPy를
래핑해두었습니다
from ckonlpy.tag import Twitter
tagger = Twitter()
tagger.add_dictionary(['파이콘', '엔엘피', '아이오아이', '너무너무너무'], 'Noun')
tagger.pos('파이콘에서 엔엘피이야기를 합시다')
tagger.pos('너무너무너무는 아이오아이의 노래에요')
[('파이콘', 'Noun'), ('에서', ‘Josa'), ('엔엘피', 'Noun'), ('이야기', 'Noun'), ('를', 'Josa'), ('합', 'Verb'), ('시', 'PreEomi'), ('다', 'Eomi')]
[('너무너무너무', 'Noun'), ('는', 'Josa'), ('아이오아이', 'Noun'), ('의', 'Josa'), ('노래', 'Noun'), ('에요', 'Josa')]
51
정리
• 데이터기반으로 스스로 단어/명사를 추출하고, 이를 그대로 이용하거나
KoNLPy와 결합하여 텍스트를 처리하는 방법에 대하여 이야기하였습니다
• 아직도 좀 더 좋은 단어/명사 추출기와 토크나이저를 연구하고 있습니다
• 조금 더 편한 데이터분석을, 분석 준비가 아닌 분석에 더 많이 집중하는데
도움이 되었으면 좋겠습니다
52

More Related Content

What's hot

책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017Taehoon Kim
 
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [리뷰의 재발견 팀] : 이커머스 리뷰 유용성 파악 및 필터링
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [리뷰의 재발견 팀] : 이커머스 리뷰 유용성 파악 및 필터링제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [리뷰의 재발견 팀] : 이커머스 리뷰 유용성 파악 및 필터링
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [리뷰의 재발견 팀] : 이커머스 리뷰 유용성 파악 및 필터링BOAZ Bigdata
 
Focal loss의 응용(Detection & Classification)
Focal loss의 응용(Detection & Classification)Focal loss의 응용(Detection & Classification)
Focal loss의 응용(Detection & Classification)홍배 김
 
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016Taehoon Kim
 
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEPKTH, 케이티하이텔
 
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016Taehoon Kim
 
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [Hands-on 팀] : 수어 번역을 통한 위험 상황 속 의사소통 시스템 구축
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [Hands-on 팀] : 수어 번역을 통한 위험 상황 속 의사소통 시스템 구축제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [Hands-on 팀] : 수어 번역을 통한 위험 상황 속 의사소통 시스템 구축
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [Hands-on 팀] : 수어 번역을 통한 위험 상황 속 의사소통 시스템 구축BOAZ Bigdata
 
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [코끼리책방 팀] : 사용자 스크랩 내용 기반 도서 추천
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [코끼리책방 팀] : 사용자 스크랩 내용 기반 도서 추천 제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [코끼리책방 팀] : 사용자 스크랩 내용 기반 도서 추천
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [코끼리책방 팀] : 사용자 스크랩 내용 기반 도서 추천 BOAZ Bigdata
 
Nlp toolkits and_preprocessing_techniques
Nlp toolkits and_preprocessing_techniquesNlp toolkits and_preprocessing_techniques
Nlp toolkits and_preprocessing_techniquesankit_ppt
 
인공지능추천시스템 airs개발기_모델링과시스템
인공지능추천시스템 airs개발기_모델링과시스템인공지능추천시스템 airs개발기_모델링과시스템
인공지능추천시스템 airs개발기_모델링과시스템NAVER D2
 
[PYCON Korea 2018] Python Application Server for Recommender System
[PYCON Korea 2018] Python Application Server for Recommender System [PYCON Korea 2018] Python Application Server for Recommender System
[PYCON Korea 2018] Python Application Server for Recommender System Kwangseob Kim
 
파이썬 로깅, 끝까지 파보면서 내가 배운 것
파이썬 로깅, 끝까지 파보면서 내가 배운 것파이썬 로깅, 끝까지 파보면서 내가 배운 것
파이썬 로깅, 끝까지 파보면서 내가 배운 것Hyun-Tae Hwang
 
[컴퓨터비전과 인공지능] 10. 신경망 학습하기 파트 1 - 1. 활성화 함수
[컴퓨터비전과 인공지능] 10. 신경망 학습하기 파트 1 - 1. 활성화 함수[컴퓨터비전과 인공지능] 10. 신경망 학습하기 파트 1 - 1. 활성화 함수
[컴퓨터비전과 인공지능] 10. 신경망 학습하기 파트 1 - 1. 활성화 함수jdo
 
딥러닝 기반 자연어 언어모델 BERT
딥러닝 기반 자연어 언어모델 BERT딥러닝 기반 자연어 언어모델 BERT
딥러닝 기반 자연어 언어모델 BERTSeonghyun Kim
 
2015 py con word2vec이 추천시스템을 만났을때
2015 py con word2vec이 추천시스템을 만났을때 2015 py con word2vec이 추천시스템을 만났을때
2015 py con word2vec이 추천시스템을 만났을때 choi kyumin
 
Urdu Alphabet PPT 1 - Copy (1).pdf
Urdu Alphabet PPT 1 - Copy (1).pdfUrdu Alphabet PPT 1 - Copy (1).pdf
Urdu Alphabet PPT 1 - Copy (1).pdfSanam Arain
 
MUJINプログラミングチャレンジ2016 解説
MUJINプログラミングチャレンジ2016 解説MUJINプログラミングチャレンジ2016 解説
MUJINプログラミングチャレンジ2016 解説AtCoder Inc.
 
20130116_pfiseminar_gwas_postgwas
20130116_pfiseminar_gwas_postgwas20130116_pfiseminar_gwas_postgwas
20130116_pfiseminar_gwas_postgwasPreferred Networks
 
제 17회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [ztyle] : 손그림 의류 검색 서비스
제 17회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [ztyle] : 손그림 의류 검색 서비스제 17회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [ztyle] : 손그림 의류 검색 서비스
제 17회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [ztyle] : 손그림 의류 검색 서비스BOAZ Bigdata
 

What's hot (20)

책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
 
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [리뷰의 재발견 팀] : 이커머스 리뷰 유용성 파악 및 필터링
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [리뷰의 재발견 팀] : 이커머스 리뷰 유용성 파악 및 필터링제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [리뷰의 재발견 팀] : 이커머스 리뷰 유용성 파악 및 필터링
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [리뷰의 재발견 팀] : 이커머스 리뷰 유용성 파악 및 필터링
 
Focal loss의 응용(Detection & Classification)
Focal loss의 응용(Detection & Classification)Focal loss의 응용(Detection & Classification)
Focal loss의 응용(Detection & Classification)
 
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
 
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
[H3 2012] 오픈 소스로 구현하는 실시간 데이터 처리를 위한 CEP
 
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
 
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [Hands-on 팀] : 수어 번역을 통한 위험 상황 속 의사소통 시스템 구축
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [Hands-on 팀] : 수어 번역을 통한 위험 상황 속 의사소통 시스템 구축제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [Hands-on 팀] : 수어 번역을 통한 위험 상황 속 의사소통 시스템 구축
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [Hands-on 팀] : 수어 번역을 통한 위험 상황 속 의사소통 시스템 구축
 
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [코끼리책방 팀] : 사용자 스크랩 내용 기반 도서 추천
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [코끼리책방 팀] : 사용자 스크랩 내용 기반 도서 추천 제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [코끼리책방 팀] : 사용자 스크랩 내용 기반 도서 추천
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [코끼리책방 팀] : 사용자 스크랩 내용 기반 도서 추천
 
Nlp toolkits and_preprocessing_techniques
Nlp toolkits and_preprocessing_techniquesNlp toolkits and_preprocessing_techniques
Nlp toolkits and_preprocessing_techniques
 
인공지능추천시스템 airs개발기_모델링과시스템
인공지능추천시스템 airs개발기_모델링과시스템인공지능추천시스템 airs개발기_모델링과시스템
인공지능추천시스템 airs개발기_모델링과시스템
 
NLTK
NLTKNLTK
NLTK
 
[PYCON Korea 2018] Python Application Server for Recommender System
[PYCON Korea 2018] Python Application Server for Recommender System [PYCON Korea 2018] Python Application Server for Recommender System
[PYCON Korea 2018] Python Application Server for Recommender System
 
파이썬 로깅, 끝까지 파보면서 내가 배운 것
파이썬 로깅, 끝까지 파보면서 내가 배운 것파이썬 로깅, 끝까지 파보면서 내가 배운 것
파이썬 로깅, 끝까지 파보면서 내가 배운 것
 
[컴퓨터비전과 인공지능] 10. 신경망 학습하기 파트 1 - 1. 활성화 함수
[컴퓨터비전과 인공지능] 10. 신경망 학습하기 파트 1 - 1. 활성화 함수[컴퓨터비전과 인공지능] 10. 신경망 학습하기 파트 1 - 1. 활성화 함수
[컴퓨터비전과 인공지능] 10. 신경망 학습하기 파트 1 - 1. 활성화 함수
 
딥러닝 기반 자연어 언어모델 BERT
딥러닝 기반 자연어 언어모델 BERT딥러닝 기반 자연어 언어모델 BERT
딥러닝 기반 자연어 언어모델 BERT
 
2015 py con word2vec이 추천시스템을 만났을때
2015 py con word2vec이 추천시스템을 만났을때 2015 py con word2vec이 추천시스템을 만났을때
2015 py con word2vec이 추천시스템을 만났을때
 
Urdu Alphabet PPT 1 - Copy (1).pdf
Urdu Alphabet PPT 1 - Copy (1).pdfUrdu Alphabet PPT 1 - Copy (1).pdf
Urdu Alphabet PPT 1 - Copy (1).pdf
 
MUJINプログラミングチャレンジ2016 解説
MUJINプログラミングチャレンジ2016 解説MUJINプログラミングチャレンジ2016 解説
MUJINプログラミングチャレンジ2016 解説
 
20130116_pfiseminar_gwas_postgwas
20130116_pfiseminar_gwas_postgwas20130116_pfiseminar_gwas_postgwas
20130116_pfiseminar_gwas_postgwas
 
제 17회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [ztyle] : 손그림 의류 검색 서비스
제 17회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [ztyle] : 손그림 의류 검색 서비스제 17회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [ztyle] : 손그림 의류 검색 서비스
제 17회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [ztyle] : 손그림 의류 검색 서비스
 

Similar to Pycon2017 koreannlp

230404_korean_text_preprocessing.pdf
230404_korean_text_preprocessing.pdf230404_korean_text_preprocessing.pdf
230404_korean_text_preprocessing.pdfminalang
 
Dark Circle - Translation : The cool way to contribute to F/OSS #2(우분투와 번역 이야...
Dark Circle - Translation : The cool way to contribute to F/OSS #2(우분투와 번역 이야...Dark Circle - Translation : The cool way to contribute to F/OSS #2(우분투와 번역 이야...
Dark Circle - Translation : The cool way to contribute to F/OSS #2(우분투와 번역 이야...Ubuntu Korea Community
 
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)WON JOON YOO
 
R 기초 : R Basics
R 기초 : R BasicsR 기초 : R Basics
R 기초 : R BasicsYoonwhan Lee
 
머신러닝의 자연어 처리기술(I)
머신러닝의 자연어 처리기술(I)머신러닝의 자연어 처리기술(I)
머신러닝의 자연어 처리기술(I)홍배 김
 
Python3 brief summary
Python3 brief summaryPython3 brief summary
Python3 brief summaryHoChul Shin
 
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)WON JOON YOO
 
iOS 개발자를 위한 영어로 이름 짓기
iOS 개발자를 위한 영어로 이름 짓기iOS 개발자를 위한 영어로 이름 짓기
iOS 개발자를 위한 영어로 이름 짓기hyunho Lee
 
Open domain dialogue Chatbot(잡담봇 삽질기)
Open domain dialogue Chatbot(잡담봇 삽질기)Open domain dialogue Chatbot(잡담봇 삽질기)
Open domain dialogue Chatbot(잡담봇 삽질기)NAVER Engineering
 
Python if loop-function
Python if loop-functionPython if loop-function
Python if loop-function건희 김
 
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이NAVER D2
 
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?ssuseraf7587
 
세미나
세미나세미나
세미나Dongyi Kim
 
2018 Ajou Programming Contest solutions
2018 Ajou Programming Contest solutions2018 Ajou Programming Contest solutions
2018 Ajou Programming Contest solutions현정 김
 
유한 상태 기반의 한국어 형태소 분석기_이상호
유한 상태 기반의 한국어 형태소 분석기_이상호유한 상태 기반의 한국어 형태소 분석기_이상호
유한 상태 기반의 한국어 형태소 분석기_이상호Lee Ji Eun
 
Ds4 artist week_03
Ds4 artist week_03Ds4 artist week_03
Ds4 artist week_03SeungBum Kim
 
통계자료분석을 ㅇ
통계자료분석을 ㅇ통계자료분석을 ㅇ
통계자료분석을 ㅇYoonwhan Lee
 

Similar to Pycon2017 koreannlp (20)

230404_korean_text_preprocessing.pdf
230404_korean_text_preprocessing.pdf230404_korean_text_preprocessing.pdf
230404_korean_text_preprocessing.pdf
 
Dark Circle - Translation : The cool way to contribute to F/OSS #2(우분투와 번역 이야...
Dark Circle - Translation : The cool way to contribute to F/OSS #2(우분투와 번역 이야...Dark Circle - Translation : The cool way to contribute to F/OSS #2(우분투와 번역 이야...
Dark Circle - Translation : The cool way to contribute to F/OSS #2(우분투와 번역 이야...
 
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
 
R 기초 : R Basics
R 기초 : R BasicsR 기초 : R Basics
R 기초 : R Basics
 
머신러닝의 자연어 처리기술(I)
머신러닝의 자연어 처리기술(I)머신러닝의 자연어 처리기술(I)
머신러닝의 자연어 처리기술(I)
 
Python3 brief summary
Python3 brief summaryPython3 brief summary
Python3 brief summary
 
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
 
iOS 개발자를 위한 영어로 이름 짓기
iOS 개발자를 위한 영어로 이름 짓기iOS 개발자를 위한 영어로 이름 짓기
iOS 개발자를 위한 영어로 이름 짓기
 
Topic models
Topic modelsTopic models
Topic models
 
파이썬을 활용한 자연어분석 기초
파이썬을 활용한 자연어분석 기초파이썬을 활용한 자연어분석 기초
파이썬을 활용한 자연어분석 기초
 
Open domain dialogue Chatbot(잡담봇 삽질기)
Open domain dialogue Chatbot(잡담봇 삽질기)Open domain dialogue Chatbot(잡담봇 삽질기)
Open domain dialogue Chatbot(잡담봇 삽질기)
 
Python if loop-function
Python if loop-functionPython if loop-function
Python if loop-function
 
파이썬을 활용한 자연어 분석 - 2차
파이썬을 활용한 자연어 분석 - 2차파이썬을 활용한 자연어 분석 - 2차
파이썬을 활용한 자연어 분석 - 2차
 
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
 
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
 
세미나
세미나세미나
세미나
 
2018 Ajou Programming Contest solutions
2018 Ajou Programming Contest solutions2018 Ajou Programming Contest solutions
2018 Ajou Programming Contest solutions
 
유한 상태 기반의 한국어 형태소 분석기_이상호
유한 상태 기반의 한국어 형태소 분석기_이상호유한 상태 기반의 한국어 형태소 분석기_이상호
유한 상태 기반의 한국어 형태소 분석기_이상호
 
Ds4 artist week_03
Ds4 artist week_03Ds4 artist week_03
Ds4 artist week_03
 
통계자료분석을 ㅇ
통계자료분석을 ㅇ통계자료분석을 ㅇ
통계자료분석을 ㅇ
 

Pycon2017 koreannlp

  • 1. 노가다 없는 텍스트 분석을 위한 한국어 NLP 파이콘 코리아 2017 김현중 (soy.lovit@gmail.com) 1
  • 2. 노가다 없는 텍스트 분석을 위한 한국어 NLP Hyunjoong Kim soy.lovit@gmail.com 2
  • 3. • KoNLPy는 Python에서 사용할 수 있는 한국어 자연어처리 패키지 * http://konlpy.org/ko/latest/ from konlpy.tag import Kkma kkma = Kkma() print(kkma.nouns(u'질문이나 건의사항은 깃헙 이슈 트래커에 남겨주세요.')) 3 [질문, 건의, 건의사항, 사항, 깃헙, 이슈, 트래커] print(kkma.pos(u'오류보고는 실행환경, 에러메세지와함께 설명을 최대한상세히!^^')) [(오류, NNG), (보고, NNG), (는, JX), (실행, NNG), (환경, NNG), (,, SP), (에러, NNG), (메세지, NNG), (와, JKM), (함께, MAG), (설명, NNG), (을, JKO), (최대한, NNG), (상세히, MAG), (!, SF), (^^, EMO)]
  • 4. 미등록단어 문제 • 새롭게 만들어진 단어들은 인식이 잘 되지 않습니다 from konlpy.tag import Kkma, Twitter kkma = Kkma() twitter = Twitter() kkma.pos(‘파이콘에서 엔엘피이야기를 합니다‘) 4 파이/NNG, 콘/NNG, 에서/JKM, 엔엘피/NNG, 이야기/NNG, 를/JKO, 하/VV, ㅂ시다/EF twitter.pos(‘파이콘에서 엔엘피이야기를 합니다‘) 파/Noun, 이콘/Noun, 에서/Josa, 엔/Josa, 엘피/Noun, 이야기/Noun, 를/Josa, 합/Verb, 시/PreEomi, 다/Eomi
  • 5. 미등록단어 문제 • 새롭게 만들어진 단어들은 인식이 잘 되지 않습니다 from konlpy.tag import Kkma, Twitter kkma = Kkma() twitter = Twitter() kkma.pos(‘너무너무너무는 아이오아이의 노래에요‘) 5 너무/MAG, 너무너무/MAG, 는/JX, 아이오/NNG, 아이/NNG, 의/JKG, 노래/NNG, 에/JKM, 요/JX twitter.pos(‘너무너무너무는 아이오아이의 노래에요‘) 너무/Noun, 너무/Noun, 너무/Noun, 는/Josa, 아이오/Noun, 아이/Noun, 의/Josa, 노래/Noun, 에요/Josa
  • 6. 미등록단어 문제 • 이를 해결하기 위하여 사용자 사전을 추가하여 사용합니다 • 주로 이 작업은 품사 판별을 한 뒤, 빈도수가 높은 단어들 중에서 잘못 처리된 단어를 고르는 방식입니다 • 이 반복적/노동집약적인 과정을 최대한 자동화 하는게 목표입니다 6
  • 7. 우리가 다룰 이야기 • 사용자 사전을 사람이 만들지 말고, 데이터 기반으로 추출할 것입니다 • 여러 단어 추출 기법들 중 cohesion에 대하여 살펴봅니다. • 단어 중에서도 명사는 따로 추출할 것입니다 • 명사는 새로운 단어가 가장 많이 생성되고 사용도 가장 많이 되는 품사입니다 7
  • 8. Part 1: 단어 추출 + 토크나이징 Part 2: 명사 추출 부록 : KoNLPy + 사용자사전 8
  • 9. 단어 추출 + 토크나이징 https://github.com/lovit/soynlp 9
  • 10. 단어 추출 • 우리도 뉴스나 글을 읽으면서 새로운 단어들을 쉽게 학습합니다 • 단어는 (특히 명사는) 경계에 특징이 있습니다. 우리는 이를 이용하여 통계 기반으로 단어를 추출합니다 • 단, 1음절 단어는 제외합니다. 단어 길이가 1이면 봐도 무슨 말인지 해석하기 힘듧니다 (= 모호합니다) 10
  • 11. Cohesion (Character n-gram) • 한국어의 의미를 지니는 단어 (명사/동사/형용사/부사)는 어절 왼쪽에 있습니다 짜장면/명사 + 을/조사 먹/동사 + 었어/어미 11
  • 12. Cohesion (Character n-gram) • 맥락이 충분히 주어지지 않으면 다음에 등장할 글자의 확률이 작습니다 • 한글자 (‘아‘)는 매우 모호한 문맥입니다 아이 > 아니 17.15 % > 아이 14.86 % > 아시 8.06 % > 아닌 4.74 % > 아파 4.43 % > 아직 3.85 % … 한글자는 특별한 문맥을 가지기가 어렵습니다 12
  • 13. Cohesion (Character n-gram) • 맥락이 충분히 주어지지 않으면 다음에 등장할 글자의 확률이 작습니다 아이오 > 아이폰 16.60 % > 아이들 13.37 % > 아이디 9.66 % > 아이돌 6.77 % > 아이뉴 6.77 % > 아이오 6.53 % … 13 어떤 경우는 두 글자라 하더라도 다양한 맥락에서 등장하기도 합니다
  • 14. Cohesion (Character n-gram) • Subword 다음에 등장할 글자가 쉽게 예상된다면 (확률이 높다면) 아직 단어가 끝나지 않았다는 의미입니다 아이오아 > 아이오아 87.95 % > 아이오닉 7.49 % > 아이오와 3.26 % > 아이오빈 0.65 % > 아이오페 0.33 % > 아이오케 0.33 % 문맥이 명확해 질수록 이전 단어  다음 글자 확률이 높아집니다 14
  • 15. Cohesion (Character n-gram) • Subword 다음에 등장할 글자가 쉽게 예상된다면 (확률이 높다면) 아직 단어가 끝나지 않았다는 의미입니다 아이오아이 > 아이오아이 100.00 % 15 문맥이 확실하면 다음글자의 등장 확률이 높습니다
  • 16. Cohesion (Character n-gram) • 단어의 경계를 넘으면 다음 글자에 대한 확률이 다시 작아집니다 아이오아이는 > 아이오아이의 31.97 % > 아이오아이는 27.21 % > 아이오아이와 13.61 % > 아이오아이가 12.24 % > 아이오아이에 9.52 % > 아이오아이까 1.36 % … 16 단어 경계 뒤에는 다양한 조사/어미 들이 등장합니다
  • 17. Cohesion (Character n-gram) • 단어의 점수(cohesion)를 아래처럼 정의해 봅니다 𝑐𝑜ℎ𝑒𝑠𝑖𝑜𝑛(𝑐1:𝑛 ) = 𝑛−1 𝑖=1 𝑛−1 𝑃(𝑐1:𝑖+1|𝑐1:𝑖, ) 𝑃 𝑐1:2 𝑐1 = #𝑐1:2 #𝑐1 cohesion(‘아이오아이’) = { p(아  아이) * p(아이  아이오) * p(아이오  아이오아) * p(아이오아  아이오아이) } 1/(5-1) 학습은 오로직 string count 17
  • 18. Cohesion (Character n-gram) • 어절의 왼쪽부터 subword의 빈도수를 세어봅니다. docs = [‘파이콘에서 발표를 합니다‘, … ] from collections import defaultdict count= defaultdict(lambda: 0) for doc in docs: for word in doc.split(): n = len(word) for e in range(1, n+1): count[word[:e]] += 1 18
  • 19. Cohesion (Character n-gram) • Subword의 빈도수와 P(AB|A)를 계산해 봅니다 word = '아이오아이는‘ n = len(word) for e in range(2, n+1): w = word[:e] f = count[w] p = f/count[:e-1] print('{:6}, f={}, p={:.2}'. format(w, f, p)) 아이, f=4910, p=0.15 아이오, f=307, p=0.06 아이오아, f=270, p=0.88 아이오아이, f=270, p=1.00 아이오아이는, f=40, p=0.15 19
  • 20. Cohesion (Character n-gram) • 단어의 점수(cohesion)를 아래처럼 구현해 봅니다 def cohesion(w): return pow(count[w]/count[w[0]], 1/(len(w)-1)) word = '아이오아이가‘ n = len(word) for e in range(2, n+1): w = word[:e] f = count[w] s = cohesion(w) print('{:6}, f={}, s={:.2}'. format(w, f, s)) 아이, f=4910, s=0.15 아이오, f=307, s=0.10 아이오아, f=270, s=0.20 아이오아이, f=270, s=0.30 아이오아이가, f=18, s=0.22 단어로 선택 #𝑐1:4 #𝑐1 = #𝑐1:2 #𝑐1 ∗ #𝑐1:3 #𝑐1:2 ∗ #𝑐1:4 #𝑐1:3 20
  • 21. Cohesion (Character n-gram) • 단어의 점수(cohesion)를 아래처럼 구현해 봅니다 def cohesion(w): return pow(count[w]/count[w[0]], 1/(len(w)-1)) word = '아이오아이가‘ n = len(word) for e in range(2, n+1): w = word[:e] f = count[w] s = cohesion(w) print('{:6}, f={}, s={:.2}'. format(w, f, s)) 아이, f=4910, s=0.15 아이오, f=307, s=0.10 아이오아, f=270, s=0.20 아이오아이, f=270, s=0.30 아이오아이가, f=18, s=0.22 단어로 선택 #𝑐1:4 #𝑐1 = #𝑐1:2 #𝒄 𝟏 ∗ #𝑐1:3 #𝑐1:2 ∗ #𝒄 𝟏:𝟒 #𝑐1:3 21
  • 22. Tokenizer • 단어를 잘 인식할 수 있다면 토크나이징도 쉽게 할 수 있습니다 • 토크나이징은 여러 개의 단어로 이뤄진 문장/어절에서 단어를 구분하는 것 • 띄어쓰기 오류 정도에 따라 다른 토크나이징 전략을 사용할 수 있습니다 22
  • 23. L-Tokenizer • 띄어쓰기가 잘 되어 있다면, 어절의 왼쪽에서부터 단어의 점수가 가장 큰 subword를 기준으로 어절을 나눕니다 def ltokenize(w): n = len(w) if n <= 2: return (w, '') tokens = [] for e in range(2, n+1): tokens.append(w[:e], w[e:], cohesion(w[:e])) tokens = sorted(tokens, key=lambda x:-x[2]) return tokens[0][:2] sent = ‘뉴스의 기사를 이용했던 예시입니다' for word in sent.split(): print( ltokenize(word) ) ('뉴스', '의') ('기사', '를') ('이용', '했던') ('예시', '입니다') 23
  • 24. Max Score Tokenizer • 띄어쓰기가 잘 되어있지 않다면 아는 단어부터 잘라내면 됩니다 cohesions = {'파스': 0.3, '파스타': 0.7, '좋아요': 0.2, '좋아':0.5} score = lambda x: cohesions.get(x, 0) tokenize('파스타가좋아요') [('파스', 0, 2, 0.3), ('파스타', 0, 3, 0.7), ('스타', 1, 3, 0), ('스타가', 1, 4, 0), ('타가', 2, 4, 0), ('타가좋', 2, 5, 0), ('가좋', 3, 5, 0), ('가좋아', 3, 6, 0), ('좋아', 4, 6, 0.5), ('좋아요', 4, 7, 0.2), ('아요', 5, 7, 0)] [('파스타', 0, 3, 0.7), ('좋아', 4, 6, 0.5), ('파스', 0, 2, 0.3), ('좋아요', 4, 7, 0.2), ('스타', 1, 3, 0), ('스타가', 1, 4, 0), ('타가', 2, 4, 0), ('타가좋', 2, 5, 0), ('가좋', 3, 5, 0), ('가좋아', 3, 6, 0), ('아요', 5, 7, 0)] [('파스타', 0, 3, 0.7), ('좋아', 4, 6, 0.5), ('파스', 0, 2, 0.3), ('좋아요', 4, 7, 0.2), ('스타', 1, 3, 0), ('스타가', 1, 4, 0), ('타가', 2, 4, 0), ('타가좋', 2, 5, 0), ('가좋', 3, 5, 0), ('가좋아', 3, 6, 0), ('아요', 5, 7, 0)] Subword 별 score 계산 (subword, begin, end, score) Score 기준으로 정렬 최고점수의 단어 선택, 위치가 겹치는 단어 제거 24
  • 25. Max Score Tokenizer • 띄어쓰기가 잘 되어있지 않다면 아는 단어부터 잘라내면 됩니다 cohesions = {'파스': 0.3, '파스타': 0.7, '좋아요': 0.2, '좋아':0.5} score = lambda x: cohesions.get(x, 0) [('파스타', 0, 3, 0.7), ('좋아', 4, 6, 0.5), ('파스', 0, 2, 0.3), ('좋아요', 4, 7, 0.2), ('스타', 1, 3, 0), ('스타가', 1, 4, 0), ('타가', 2, 4, 0), ('타가좋', 2, 5, 0), ('가좋', 3, 5, 0), ('가좋아', 3, 6, 0), ('아요', 5, 7, 0)] [('파스타', 0, 3, 0.7), ('좋아', 4, 6, 0.5), ('파스', 0, 2, 0.3), ('좋아요', 4, 7, 0.2), ('스타', 1, 3, 0), ('스타가', 1, 4, 0), ('타가', 2, 4, 0), ('타가좋', 2, 5, 0), ('가좋', 3, 5, 0), ('가좋아', 3, 6, 0), ('아요', 5, 7, 0)] [파스타, 가, 좋아, 요] [파스타]가좋아요 [파스타]가[좋아]요 25
  • 26. Max Score Tokenizer • 확실히 아는 단어라면 scores에 최고 점수를 줄 수 있습니다 cohesions = {'파스': 0.3, '파스타': 0.7, '좋아요': 0.2, '좋아':0.5, ‘아이오아이’:1.0} score = lambda x:cohesions.get(x, 0) 26
  • 27. soynlp • Cohesion, Branching Entropy 를 포함한, 단어 추출에 관련된 함수들을 github에 구현해 두었습니다. from soynlp import DoublespaceLineCorpus from soynlp.word import WordExtractor corpus = DoublespaceLineCorpus(fname, iter_sent=True) word_extractor = WordExtractor(corpus, min_count=10) words = word_extractor.extract() 27
  • 28. soynlp • extract()는 단어 경계와 관련된 점수들이 계산되어 있는 dict를 return 합니다 words = word_extractor.extract() words[‘드라마'] Scores(cohesion_forward=0.6093651029086764, cohesion_backward=0.5282705437953743, left_branching_entropy=3.6583115265560924, right_branching_entropy=3.675624807575614, left_accessor_variety=128, right_accessor_variety=136, leftside_frequency=2375, rightside_frequency=1284) 28
  • 29. soynlp • Tokenizer 역시 구현되어 있습니다 from soynlp.tokenizer import LTokenizer scores = {w:s.cohesion_forward for w, s in words.items()} tokenizer = LTokenizer(scores=scores) tokenizer.tokenize(‘뉴스의 기사를 이용했던 예시입니다') [‘뉴스‘, ‘의 ‘, ‘기사‘, ‘를 ‘, ‘이용‘, ‘했던‘, ‘예시‘, ‘입니다‘] 29
  • 30. soynlp • 사전이 없이도 데이터 기반으로 토크나이저를 학습하면 잘 작동합니다 • 현재 분석 중인 데이터에 해당 알고리즘을 적용한 예시입니다 from soynlp.tokenizer import MaxScoreTokenizer scores = {w:s.cohesion_forward for w, s in words.items()} tokenizer = MaxScoreTokenizer(scores=scores) tokenizer.tokenize(‘맛있는짜파게티파스타일식초밥소바김볶다먹고싶어라일단김밥천국으로고고') ['맛있', '는', '짜파게티', '파스타', '일식', '초밥', '소바', '김볶', '다', '먹고', '싶어', '라', '일단', '김밥천국', '으로', '고고'] 30
  • 32. 명사 • 지금까지 분석할 데이터를 기반으로, 그 데이터에서 사용되는 단어를 추출하는 방법을 이야기했습니다 • 이번에는 {‘파스타’, ‘좋아’} 와 같은 단어에서 ‘파스타‘라는 명사만 선택하는 방법을 알아봅니다 32
  • 33. A는 명사일까? 어제 A라는 가게에 가봤어 A에서 보자 A로 와줘 명사 우측에 등장하는 글자 분포를 이용하여 A가 명사임을 유추할 수 있다 33
  • 34. L – R graph • 어절은 L + [R] 구조로 나눌 수 있습니다 • 발표 + 를 • 하 + 면서 • 데이터에서 모든 어절들을 두 개의 subwords로 나눈 뒤 연결하면 L – R graph를 만들 수 있습니다 34
  • 35. L – R graph 드라마 파이콘 발표 시작했 먹 달리 … 파이 를 지마 의 로 에서 … 콘에서 었어 고서 frequency (드라마 – 를) L R 35
  • 36. L – R graph 드라마 파이콘 발표 시작했 먹 달리 … 파이 를 지마 의 로 에서 … 콘에서 었어 고서 명사들의 오른쪽에는 조사들이 주로 연결되어 있습니다 36
  • 37. L – R graph 드라마 파이콘 발표 시작했 먹 달리 … 파이 를 지마 의 로 에서 … 콘에서 었어 고서 동사/형용사들의 오른쪽에는 어미들이 주로 연결되어 있습니다 37
  • 38. L – R graph 드라마 파이콘 발표 시작했 먹 달리 … 파이 를 지마 의 로 에서 … 콘에서 었어 고서 L이 제대로 된 단어가 아니면 오른쪽에도 조사/어미가 아닌 R이 연결됩니다 38
  • 39. Noun Extraction • L – R graph를 만들면 명사가 눈에 보입니다 lrgraph = defaultdict(lambda: defaultdict(lambda: 0)) for doc in docs: for w in doc.split(): n = len(w) for e in range(1, n+1): lrgraph[ w[ :e] ][ w[e: ] ] += 1 def get_r(L): return sorted( lrgraph[L].items(), key=lambda x:-x[1]) get_r(‘드라마’) [('', 1268), ('를', 164), ('다', 152), ('의', 140), ('로', 138), ('에서', 98), ('와', 62), ('는', 55), ('에', 55), ('가', 48), ('이다', 24), ('인', 14), … ] 39
  • 40. Noun Extraction • L – R graph: [명사 + 조사], [동사 + 어미], [틀린 단어 + 틀린 단어] get_r(‘드라마') [('', 1268), ('를', 164), ('다', 152), ('의', 140), ('로', 138), ('에서', 98), ('와', 62), ('는', 55), ('에', 55), ('가', 48), ('이다', 24), ('인', 14), … ] get_r('드라') [('마', 1268), ('마를', 164), ('마다', 152), ('마의', 140), ('마로', 138), ('마에서', 98), ('기', 65), ('마와', 62), ('마는', 55), ('마에', 55), ('마가', 48), ('이브', 28), … ] get_r('시작했') [('다', 567), ('고', 73), ('다고', 61), ('습니다', 42), ('는데', 26), ('으며', 16), ('지만', 15), ('던', 12), ('어요', 10), ('다는', 7), ('으나', 5), ('죠', 4), … ] 40
  • 41. Noun Extraction • L – R graph: [명사 + 조사], [동사 + 어미], [틀린 단어 + 틀린 단어] get_r('드라마') [('', 1268), ('를', 164), ('다', 152), ('의', 140), ('로', 138), ('에서', 98), ('와', 62), ('는', 55), ('에', 55), ('가', 48), ('이다', 24), ('인', 14), … ] get_r('드라') [('마', 1268), ('마를', 164), ('마다', 152), ('마의', 140), ('마로', 138), ('마에서', 98), ('기', 65), ('마와', 62), ('마는', 55), ('마에', 55), ('마가', 48), ('이브', 28), … ] get_r('시작했') [('다', 567), ('고', 73), ('다고', 61), ('습니다', 42), ('는데', 26), ('으며', 16), ('지만', 15), ('던', 12), ('어요', 10), ('다는', 7), ('으나', 5), ('죠', 4), … ] 41
  • 42. Noun Extraction • L – R graph: [명사 + 조사], [동사 + 어미], [틀린 단어 + 틀린 단어] get_r('드라마') [('', 1268), ('를', 164), ('다', 152), ('의', 140), ('로', 138), ('에서', 98), ('와', 62), ('는', 55), ('에', 55), ('가', 48), ('이다', 24), ('인', 14), … ] get_r('드라') [('마', 1268), ('마를', 164), ('마다', 152), ('마의', 140), ('마로', 138), ('마에서', 98), ('기', 65), ('마와', 62), ('마는', 55), ('마에', 55), ('마가', 48), ('이브', 28), … ] get_r('시작했') [('다', 567), ('고', 73), ('다고', 61), ('습니다', 42), ('는데', 26), ('으며', 16), ('지만', 15), ('던', 12), ('어요', 10), ('다는', 7), ('으나', 5), ('죠', 4), … ] 42
  • 43. Noun Extraction • R 의 분포를 이용하여 L의 명사 점수를 계산할 수 있습니다 드라마 를 (164) 다 (152) 의 (140) 로 (138) 에서 (98) 와 (62) … r_scores = {'은': 0.5, ‘었다': -0.9, … } def noun_score(L): (norm, score, _total) = (0, 0, 0) for R, frequency in get_r(L): _total += frequency if not R in r_scores: continue norm += frequency score += frequency * r_scores[R] score = score / norm if norm else 0 prop = norm / _total if _total else 0 return score, prop 𝑆 𝐿 𝑙 = 𝑓 𝑙, 𝑟 ∗ 𝑆 𝑅(𝑟) 𝑟∈𝐿 𝑅 𝑓(𝑙, 𝑟) 43
  • 44. Noun Extraction • R 의 분포를 이용하여 L의 명사 점수를 계산할 수 있습니다 noun_score('드라마‘) (0.574, 0.921) noun_score(‘시작했‘) (-0.976, 0.999) noun_score(‘드라‘) (-0.661, 0.579) 틀린 단어 뒤에는 조사/어미 들이 아닌 글자들이 등장 (명사 점수, 알려진 R 비율) = noun_score(‘Word‘) 44
  • 45. Noun Extraction • R 점수는 세종 말뭉치를 이용하여 계산합니다 • 세종 말뭉치의 품사가 태깅된 정보로부터 L – R 구조의 테이블을 만듭니다 ... 예술가의 예술가/NNG+의/JKG 113 예술가는 예술가/NNG+는/JX 45 예술가가 예술가/NNG+가/JKS 43 예술가들의예술가/NNG+들/XSN+의/JKG 30 ... 단어 / R - 는 - 의 - 고 - 었다 -었던 예술가 45 113 2 0 0 먹 33 0 27 0 27 … … … … … … 단어 품사 명사 동사 … 45
  • 46. Noun Extraction • 명사의 빈도를 고려하여 – R 앞에 명사가 등장할 점수를 계산합니다 단어 / R - 는 - 의 - 고 - 었다 -구나 예술가 45 113 2 0 0 나이 54 87 27 0 27 들 0 0 0 255 0 춥 0 0 0 0 87 … … … … … … 품사 명사 명사 동사 형용사 … 품사 빈도수 (비율) 명사 704,197 (0.838) ^명사 136,598 (0.162) 품사 빈도수 보정빈도수 점수 명사 980 980 0.810 = (980 – 103.5) / (980 + 103.5) ^명사 20 103.5 = 20 * (0.838/0.162) 46
  • 47. soynlp • 후처리과정이 추가된 명사 추출기를 구현하였습니다 from soynlp.noun import LRNounExtractor noun_extractor = LRNounExtractor(min_count=50) nouns = noun_extractor.train_extract(corpus, minimum_noun_score=0.5) nouns[‘설입‘] 47 NounScore(frequency=67, score=0.926, known_r_ratio=0.529) nouns[‘드라마‘] NounScore(frequency=4976, score=0.522, known_r_ratio=0.601)
  • 49. 사용자 사전 + 템플릿매칭을 이용한 토크나이징/품사판별 • 명사/단어에 대해서 사용자 사전을 만든다면, 내가 임의의 템플릿을 만들어서 템플릿 매칭으로 아는 단어들을 처리할 수도 있습니다 custom_dictionary = {'Noun': [‘파이콘', '엔엘피', '아이오아이', '너무너무너무']} templates = [('Noun', 'Noun'), ('Noun', 'Josa'), ('Noun', 'Noun', ‘Josa')] 49
  • 50. 사용자 사전 + 템플릿매칭을 이용한 토크나이징/품사판별 custom_dictionary = {'Noun': ['파이콘', '엔엘피', '아이오아이', '너무너무너무']} templates = [('Noun', 'Noun'), ('Noun', 'Josa'), ('Noun', 'Noun', ‘Josa')] [파이콘][에서] [엔엘피][이야기][를] 합시다 (Noun, Josa) (Noun, Noun, Josa) Unknown  KoNLPy에 넘기자 * 빨간색은 사용자에 의하여 추가된 사전에서 매칭 * 파란색은 KoNLPy의 트위터 분석기에 포함되어 있는 사전에서 매칭 50
  • 51. 사용자 사전 + 템플릿매칭을 이용한 토크나이징/품사판별 • customized_KoNLPy에 사전/템플릿 추가를 쉽게 할 수 있도록 KoNLPy를 래핑해두었습니다 from ckonlpy.tag import Twitter tagger = Twitter() tagger.add_dictionary(['파이콘', '엔엘피', '아이오아이', '너무너무너무'], 'Noun') tagger.pos('파이콘에서 엔엘피이야기를 합시다') tagger.pos('너무너무너무는 아이오아이의 노래에요') [('파이콘', 'Noun'), ('에서', ‘Josa'), ('엔엘피', 'Noun'), ('이야기', 'Noun'), ('를', 'Josa'), ('합', 'Verb'), ('시', 'PreEomi'), ('다', 'Eomi')] [('너무너무너무', 'Noun'), ('는', 'Josa'), ('아이오아이', 'Noun'), ('의', 'Josa'), ('노래', 'Noun'), ('에요', 'Josa')] 51
  • 52. 정리 • 데이터기반으로 스스로 단어/명사를 추출하고, 이를 그대로 이용하거나 KoNLPy와 결합하여 텍스트를 처리하는 방법에 대하여 이야기하였습니다 • 아직도 좀 더 좋은 단어/명사 추출기와 토크나이저를 연구하고 있습니다 • 조금 더 편한 데이터분석을, 분석 준비가 아닌 분석에 더 많이 집중하는데 도움이 되었으면 좋겠습니다 52