[PyConKR2017] 노가다 없는 텍스트 분석을 위한 한국어 NLP

Similar documents
PowerPoint 프레젠테이션


<C5D8BDBAC6AEBEF0BEEEC7D02D3336C1FD2E687770>

제5장 형태소분석

C:/Users/Kuk/Documents/Laboratory/TR/ tr(a)/TR ¾ç½Ä.dvi

fl 2

1

단순 베이즈 분류기

1

Part Part

£01¦4Àå-2

PART

½ºÅ丮ÅÚ¸µ3_³»Áö

272*406OSAKAÃÖÁ¾-¼öÁ¤b64ٽÚ

자연언어처리

BY-FDP-4-70.hwp

View Licenses and Services (customer)

8장 문자열

지도상 유의점 m 학생들이 어려워하는 낱말이 있으므로 자세히 설명해주도록 한다. m 버튼을 무리하게 조작하면 고장이 날 위험이 있으므로 수업 시작 부분에서 주의를 준다. m 활동지를 보고 어려워하는 학생에게는 영상자료를 접속하도록 안내한다. 평가 평가 유형 자기 평가

Microsoft PowerPoint - chap04-연산자.pptx

프로그래밍개론및실습 2015 년 2 학기프로그래밍개론및실습과목으로본내용은강의교재인생능출판사, 두근두근 C 언어수업, 천인국지음을발췌수정하였음

윙윙_포트폴리오_3


아이콘의 정의 본 사용자 설명서에서는 다음 아이콘을 사용합니다. 참고 참고는 발생할 수 있는 상황에 대처하는 방법을 알려 주거나 다른 기능과 함께 작동하는 방법에 대한 요령을 제공합니다. 상표 Brother 로고는 Brother Industries, Ltd.의 등록 상

강창훈

<32332D322D303120B9E6BFB5BCAE20C0CCB5BFC1D6312D32302E687770>

hwp

Web Scraper in 30 Minutes 강철

PHP & ASP

국내외 장애인 텔레비전 방송 현황 연구

Let G = (V, E) be a connected, undirected graph with a real-valued weight function w defined on E. Let A be a set of E, possibly empty, that is includ

<30352DC0CCC7F6C8F B1B3292DBFACB1B8BCD2B1B3C1A42E687770>

<B3EDB9AEC0DBBCBAB9FD2E687770>

1809_2018-BESPINGLOBAL_Design Guidelines_out

Big Data Analysis Using RHINO

C++ Programming

게시판 스팸 실시간 차단 시스템

2015 개정교육과정에따른정보과평가기준개발연구 연구책임자 공동연구자 연구협력관

C 언어 프로그래밊 과제 풀이

도약종합 강의목표 -토익 700점이상의점수를목표로합니다. -토익점수 500점정도의학생들이 6주동안의수업으로 점향상시킵니다. 강의대상다음과같은분들에게가장적합합니다. -현재토익점수 500점에서 600점대이신분들에게가장좋습니다. -정기토익을 2-3번본적이있으신분

2015 경제ㆍ재정수첩

Java ...

untitled

750 1,500 35

중간고사

2002년 2학기 자료구조


NLTK 6: 텍스트 분류 학습 (` `%%%`#`&12_`__~~~ౡ氀猀攀)

DIY 챗봇 - LangCon

Microsoft PowerPoint - MonthlyInsighT-2018_9월%20v1[1]

Microsoft PowerPoint - Java7.pptx

기술통계

RNN & NLP Application

오빠두엑셀 E-Book [VBA 1-7] VBA Method 란무엇인가 >> VBA 개체 Method ( 함수 ) Copyright 2018 by 오빠두 0

Microsoft PowerPoint - chap05-제어문.pptx

4. #include <stdio.h> #include <stdlib.h> int main() { functiona(); } void functiona() { printf("hihi\n"); } warning: conflicting types for functiona

슬라이드 1

SIGPLwinterschool2012

?

PowerPoint 프레젠테이션

Microsoft PowerPoint - gnu-w06-python_[실습]_day13-turtle-shape

Secure Programming Lecture1 : Introduction

강의계획서 과목 : JUN s TOEIC 700+( 도약 ) 2017년 3차강사 : 황준선 교재 : ETS 토익기본서 (RC&LC)+ 수업부교재 (JUN s TOEIC 700+) + 품사별추가문제 +Mini Test 수업목표 : LC & RC 필수기본전략수립및 GRAM

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

KMC.xlsm

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

¼øâÁö¿ª°úÇÐÀÚ¿ø

R을 이용한 텍스트 감정분석

확률 및 분포

untitled

PathEye 공식 블로그 다운로드 받으세요!! 지속적으로 업그래이드 됩니다. 여러분의 의견을 주시면 개발에 반영하겠 습니다.

<BFB9BCFAB0E6BFB5C1F6BFF8BCBEC5CD5F BFB9BCFAB0E6BFB520C4C1BCB3C6C FB3BBC1F628C3D6C1BEBBF6BAAFC8AF292E706466>

step 1-1

lkh

Microsoft PowerPoint - 3장-MS SQL Server.ppt [호환 모드]

Windows Server 2012

*캐릭부속물

국어 순화의 역사와 전망

Microsoft Word - ijungbo1_13_02

수식모드수식의표현법 수학식표현 조남운 조남운 수학식표현

Print

Xcrypt 내장형 X211SCI 수신기 KBS World 채널 설정법

슬라이드 1

KCC2011 우수발표논문 휴먼오피니언자동분류시스템구현을위한비결정오피니언형용사구문에대한연구 1) Study on Domain-dependent Keywords Co-occurring with the Adjectives of Non-deterministic Opinion

PowerPoint Template

W7_Business_ 제품설계

untitled

17장 클래스와 메소드

10(833-) SAA13-24.hwp

Microsoft PowerPoint - WiseNLU(ETRI, 임수종) 배포본

Polly_with_Serverless_HOL_hyouk

chap 5: Trees

Page 2 of 5 아니다 means to not be, and is therefore the opposite of 이다. While English simply turns words like to be or to exist negative by adding not,

OCW_C언어 기초

WINDOW FUNCTION 의이해와활용방법 엑셈컨설팅본부 / DB 컨설팅팀정동기 개요 Window Function 이란행과행간의관계를쉽게정의할수있도록만든함수이다. 윈도우함수를활용하면복잡한 SQL 들을하나의 SQL 문장으로변경할수있으며반복적으로 ACCESS 하는비효율역

Microsoft PowerPoint Python-Function.pptx

¹Ì¼ú-°¢·ÐÁß¿ä³»¿ëb74öÁ¤2š

비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

Journal of Educational Innovation Research 2019, Vol. 29, No. 1, pp DOI: : * Research Subject

Lab 3. 실습문제 (Single linked list)_해답.hwp

Transcription:

노가다없는텍스트분석을위한한국어 NLP 파이콘코리아 2017 김현중 (soy.lovit@gmail.com) 1

노가다없는텍스트분석을위한한국어 NLP Hyunjoong Kim soy.lovit@gmail.com 2

KoNLPy 는 Python 에서사용할수있는한국어자연어처리패키지 from konlpy.tag import Kkma kkma = Kkma() print(kkma.nouns(u' 질문이나건의사항은깃헙이슈트래커에남겨주세요.')) [ 질문, 건의, 건의사항, 사항, 깃헙, 이슈, 트래커 ] print(kkma.pos(u' 오류보고는실행환경, 에러메세지와함께설명을최대한상세히!^^')) [( 오류, NNG), ( 보고, NNG), ( 는, JX), ( 실행, NNG), ( 환경, NNG), (,, SP), ( 에러, NNG), ( 메세지, NNG), ( 와, JKM), ( 함께, MAG), ( 설명, NNG), ( 을, JKO), ( 최대한, NNG), ( 상세히, MAG), (!, SF), (^^, EMO)] * http://konlpy.org/ko/latest/ 3

미등록단어문제 새롭게만들어진단어들은인식이잘되지않습니다 from konlpy.tag import Kkma, Twitter kkma = Kkma() twitter = Twitter() kkma.pos( 파이콘에서엔엘피이야기를합니다 ) 파이 /NNG, 콘 /NNG, 에서 /JKM, 엔엘피 /NNG, 이야기 /NNG, 를 /JKO, 하 /VV, ㅂ시다 /EF twitter.pos( 파이콘에서엔엘피이야기를합니다 ) 파 /Noun, 이콘 /Noun, 에서 /Josa, 엔 /Josa, 엘피 /Noun, 이야기 /Noun, 를 /Josa, 합 /Verb, 시 /PreEomi, 다 /Eomi 4

미등록단어문제 새롭게만들어진단어들은인식이잘되지않습니다 from konlpy.tag import Kkma, Twitter kkma = Kkma() twitter = Twitter() kkma.pos( 너무너무너무는아이오아이의노래에요 ) 너무 /MAG, 너무너무 /MAG, 는 /JX, 아이오 /NNG, 아이 /NNG, 의 /JKG, 노래 /NNG, 에 /JKM, 요 /JX twitter.pos( 너무너무너무는아이오아이의노래에요 ) 너무 /Noun, 너무 /Noun, 너무 /Noun, 는 /Josa, 아이오 /Noun, 아이 /Noun, 의 /Josa, 노래 /Noun, 에요 /Josa 5

미등록단어문제 이를해결하기위하여사용자사전을추가하여사용합니다 주로이작업은품사판별을한뒤, 빈도수가높은단어들중에서잘못처리된단어를고르는방식입니다 이반복적 / 노동집약적인과정을최대한자동화하는게목표입니다 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) 를아래처럼정의해봅니다 cohesion(c 1:n ) = n 1 n 1 i=1 P(c 1:i+1 c 1:i, ) P c 1:2 c 1 = #c 1:2 #c 1 cohesion( 아이오아이 ) = { p( 아 아이 ) * p( 아이 아이오 ) * p( 아이오 아이오아 ) * p( 아이오아 아이오아이 ) 학습은오로직 string count } 1/(5-1) 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] 아이, 아이오, 아이오아, 아이오아이, 아이오아이는, 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 print('{:6}, f={}, p={:.2}'. format(w, f, p)) 19

Cohesion (Character n-gram) 단어의점수 (cohesion) 를아래처럼구현해봅니다 def cohesion(w): return pow(count[w]/count[w[0]], 1/(len(w)-1)) 아이, 아이오, f=4910, s=0.15 f=307, s=0.10 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=270, s=0.20 f=270, s=0.30 아이오아이가, f=18, s=0.22 #c 1:4 #c 1 = #c 1:2 #c 1 #c 1:3 #c 1:2 #c 1:4 #c 1:3 단어로선택 20

Cohesion (Character n-gram) 단어의점수 (cohesion) 를아래처럼구현해봅니다 def cohesion(w): return pow(count[w]/count[w[0]], 1/(len(w)-1)) 아이, 아이오, f=4910, s=0.15 f=307, s=0.10 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=270, s=0.20 f=270, s=0.30 아이오아이가, f=18, s=0.22 #c 1:4 #c 1 = #c 1:2 #c 1 #c 1:3 #c 1:2 #c 1:4 #c 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 L 드라마 frequency ( 드라마 를 ) 를 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( 드라마 ') get_r(' 시작했 ') get_r(' 드라 ') [('', 1268), [(' 다 ', 567), [(' 마 ', 1268), (' 를 ', 164), (' 고 ', 73), (' 마를 ', 164), (' 다 ', 152), (' 다고 ', 61), (' 마다 ', 152), (' 의 ', 140), (' 습니다 ', 42), (' 마의 ', 140), (' 로 ', 138), (' 는데 ', 26), (' 마로 ', 138), (' 에서 ', 98), (' 으며 ', 16), (' 마에서 ', 98), (' 와 ', 62), (' 지만 ', 15), (' 기 ', 65), (' 는 ', 55), (' 던 ', 12), (' 마와 ', 62), (' 에 ', 55), (' 어요 ', 10), (' 마는 ', 55), (' 가 ', 48), (' 다는 ', 7), (' 마에 ', 55), (' 이다 ', 24), (' 으나 ', 5), (' 마가 ', 48), (' 인 ', 14), (' 죠 ', 4), (' 이브 ', 28), ] ] ] 40

Noun Extraction L R graph: [ 명사 + 조사 ], [ 동사 + 어미 ], [ 틀린단어 + 틀린단어 ] get_r(' 드라마 ') get_r(' 시작했 ') get_r(' 드라 ') [('', 1268), [(' 다 ', 567), [(' 마 ', 1268), (' 를 ', 164), (' 고 ', 73), (' 마를 ', 164), (' 다 ', 152), (' 다고 ', 61), (' 마다 ', 152), (' 의 ', 140), (' 습니다 ', 42), (' 마의 ', 140), (' 로 ', 138), (' 는데 ', 26), (' 마로 ', 138), (' 에서 ', 98), (' 으며 ', 16), (' 마에서 ', 98), (' 와 ', 62), (' 지만 ', 15), (' 기 ', 65), (' 는 ', 55), (' 던 ', 12), (' 마와 ', 62), (' 에 ', 55), (' 어요 ', 10), (' 마는 ', 55), (' 가 ', 48), (' 다는 ', 7), (' 마에 ', 55), (' 이다 ', 24), (' 으나 ', 5), (' 마가 ', 48), (' 인 ', 14), (' 죠 ', 4), (' 이브 ', 28), ] ] ] 41

Noun Extraction L R graph: [ 명사 + 조사 ], [ 동사 + 어미 ], [ 틀린단어 + 틀린단어 ] get_r(' 드라마 ') get_r(' 시작했 ') get_r(' 드라 ') [('', 1268), [(' 다 ', 567), [(' 마 ', 1268), (' 를 ', 164), (' 고 ', 73), (' 마를 ', 164), (' 다 ', 152), (' 다고 ', 61), (' 마다 ', 152), (' 의 ', 140), (' 습니다 ', 42), (' 마의 ', 140), (' 로 ', 138), (' 는데 ', 26), (' 마로 ', 138), (' 에서 ', 98), (' 으며 ', 16), (' 마에서 ', 98), (' 와 ', 62), (' 지만 ', 15), (' 기 ', 65), (' 는 ', 55), (' 던 ', 12), (' 마와 ', 62), (' 에 ', 55), (' 어요 ', 10), (' 마는 ', 55), (' 가 ', 48), (' 다는 ', 7), (' 마에 ', 55), (' 이다 ', 24), (' 으나 ', 5), (' 마가 ', 48), (' 인 ', 14), (' 죠 ', 4), (' 이브 ', 28), ] ] ] 42

Noun Extraction R 의분포를이용하여 L 의명사점수를계산할수있습니다 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 S L l = f l, r S R(r) r L R f(l, r) 드라마 를 (164) 다 (152) 의 (140) 로 (138) 에서 (98) 와 (62) 43

Noun Extraction R 의분포를이용하여 L 의명사점수를계산할수있습니다 ( 명사점수, 알려진 R 비율 ) = noun_score( Word ) noun_score(' 드라마 ) (0.574, 0.921) noun_score( 시작했 ) (-0.976, 0.999) noun_score( 드라 ) (-0.661, 0.579) 틀린단어뒤에는조사 / 어미들이아닌글자들이등장 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) 품사빈도수보정빈도수점수 명사 980 980 0.810 ^ 명사 136,598 (0.162) ^명사 20 103.5 = 20 * (0.838/0.162) = (980 103.5) / (980 + 103.5) 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[ 설입 ] NounScore(frequency=67, score=0.926, known_r_ratio=0.529) nouns[ 드라마 ] NounScore(frequency=4976, score=0.522, known_r_ratio=0.601) 47

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