한글 데이터 머신러닝 및 word2vec을 이용한 유사도 분석

 
 
 
 

A. 설치
1.  한글 처리 분야의 prototyping에 python이 가장 적합합니다.

2. python용 버전관리 소프트웨어 pip를 설치합니다.
sudo easy_install pip

3. gensim을 설치합니다. (Gensim은 Python 기반의 Text mining library이며, 토픽 모델링, word2vec도 지원합니다.)
sudo pip install -U gensim

4. NLTK를 설치합니다. (자연어 처리를 위해 광범위하게 쓰이는 Python library입니다.)
sudo pip install nltk

5. KoNLPy를 설치합니다. (한글처리를 위한 library입니다.)
sudo pip install konlpy

6. twython를 설치합니다. (twitter api를 쉽게 사용하기위해 필요합니다.)
sudo pip install twython


B. NLTK와 konlpy, twython으로 텍스트 다루기
1. 읽기
$ python
from konlpy.corpus import kobill    # Docs from pokr.kr/bill
files_ko = kobill.fileids()         # Get file ids
doc_ko = kobill.open('news.txt').read() 
# news.txt는 http://boilerpipe-web.appspot.com/ 를 통해 포탈뉴스 데이터를 수집
# news.txt 는  konlpy의 corpus 아래에 있는 kobill directory에 미리 저장되어있어야 함
# /Library/Python/2.7/site-packages/konlpy/data/corpus/kobill

2.Tokenize (의미단어를 검출합니다.)
from konlpy.tag import Twitter; t = Twitter()
tokens_ko = t.morphs(doc_ko)

3. Token Wapper 클래스를  만듭니다.(token에 대한 처리를 위해 필요합니다.)
import nltk
ko = nltk.Text(tokens_ko, name='뉴스')   # 이름

4. 토근 정보 및 단일 토큰 정보를 확인합니다.
print(len(ko.tokens))       # returns number of tokens (document length)
print(len(set(ko.tokens)))  # returns number of unique tokens
ko.vocab()                  # returns frequency distribution

5. 챠트로 확인합니다.
ko.plot(50) #상위 50개의 unique token에 대해서 plot한 결과를 아래와 같이 보여줍니다.


왼쪽부터 잦은 빈도로 출현한 단어들입니다. ...과 같은 의미없는 특수문자들을 제외하면 요즘 유행하는 메르스가 역시 가장 높은 빈도수(약 30건) 정도를 보여주고 있습니다. 적절한 토큰나이저로 특수문자들을 걸러준다면 의미있는 결과를 얻어내기 용이합니다.


6. 특정 단어에 대해서 빈도수를 확인합니다.
print(ko.count(str('메르스'))) 

결과)
18
위처럼 하면 메르스에 대한 숫자를 줍니다. 만약에 제대로 글자를 인식 못한다면, 파일의 앞에 아래처럼 디폴트 인코딩을 세팅해 줍니다.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

7. 분산 차트 보기 (dispersion plot)
ko.dispersion_plot(['메르스','학교','병원'])


8. 색인하기 (본문속에서 해당 검색어가 포함된 문장을 찾아주는 작업입니다.)
ko.concordance(unicode('메르스'))

결과) 문장들이 출력됩니다.

9.유의어 찾기
ko.similar(unicode('메르스'))

결과)

의미 있는 유의어 출력을 확인할 수 있습니다.

10. 의미단위로 나누기 (Tagging and chunking)
10.1 형태소 분석기(POS tagging)
from konlpy.tag import Twitter; t = Twitter()
tags_ko = t.pos(unicode('작고 노란 강아지가 고양이에게 짖었다'))
print(tags_ko)

결과)
[(u'\uc791\uace0', u'Noun'), (u'\ub178\ub780', u'Adjective'), (u'\uac15\uc544\uc9c0', u'Noun'), (u'\uac00', u'Josa'), (u'\uace0\uc591\uc774', u'Noun'), (u'\uc5d0\uac8c', u'Josa'), (u'\uc9d6\uc5c8', u'Noun'), (u'\ub2e4', u'Josa')]

명사,형용사, 조사등을 나누어 보여줍니다. 

10.2 명사구 단위로 그룹화하기 (Noun Phrase Chunking)
parser_ko = nltk.RegexpParser("NP: {<Adjective>*<Noun>*}")
chunks_ko = parser_ko.parse(tags_ko)
chunks_ko.draw()

결과)

 위처럼 NP(Noun Phrase)단위로  문장구조를 보여줍니다. 


C. Topic Modeling 과 Word Embedding(Word2Vec)
1. 요점
Python gensim library로 아래 두가지 작업을 많이 합니다. 간단한 실행과정 입니다.

- Topic Modeling 
: 어떤 문서에서 자주 나타는 단어를 통해, 주제를 찾아주는 확률적인 모델을 디자인합니다.
유명한 것으로 LDA, LSI, HDP가 있습니다.

- Word Embedding
문장속의 단어간의 관계를 비지도 학습 방식으로 분석하여 만들어지는 수십~ 수백차원의 벡터로서 특징(Feature)화 되는 단어들을 만들어 냅니다. 단어가 가지고있는 벡터간의 연산을 통해 다른 단어와의 관계를 만들어내게 됩니다.

2. 한글처리
word2vec에서 한글처리를 해주려면 아래 몇가지 요소를 고려해야 합니다.

2.1. UTF8 디폴트 처리 
아래처럼 파일의 최상단에 선언합니다.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

2.2. konlpy 라이브러리 설정
- 한글 파일들의 위치는 konlpy의 corpus 아래에 있는 kobill directory에 읽을 파일들이 미리 저장되어 있어야 합니다. 
/Library/Python/2.7/site-packages/konlpy/data/corpus/kobill

- 토크나이저를 설정합니다. nltk방식처럼 nltk + twitter api를 사용해서 토근화합니다. 
#load from kobill 
from konlpy.corpus import kobill
docs_ko = [kobill.open(i).read() for i in kobill.fileids()]
#Tokenize
from konlpy.tag import Twitter; t = Twitter()
pos = lambda d: ['/'.join(p) for p in t.pos(d)]
texts_ko = [pos(doc) for doc in docs_ko]

3. 사용례
3.1. Topic Modeling (LSI, LDA, HDP 알고리즘)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
from konlpy.corpus import kobill
docs_ko = [kobill.open(i).read() for i in kobill.fileids()]
from konlpy.tag import Twitter; t=Twitter()
pos = lambda d: ['/'.join(p) for p in t.pos(d, stem=True, norm=True)]
texts_ko = [pos(doc) for doc in docs_ko]

#encode tokens to integers
from gensim import corpora
dictionary_ko = corpora.Dictionary(texts_ko)
dictionary_ko.save('ko.dict')  # save dictionary to file for future use

#calulate TF-IDF
from gensim import models
tf_ko = [dictionary_ko.doc2bow(text) for text in texts_ko]
tfidf_model_ko = models.TfidfModel(tf_ko)
tfidf_ko = tfidf_model_ko[tf_ko]
corpora.MmCorpus.serialize('ko.mm', tfidf_ko) # save corpus to file for future use
#train topic model

#LSI
ntopics, nwords = 3, 5
lsi_ko = models.lsimodel.LsiModel(tfidf_ko, id2word=dictionary_ko, num_topics=ntopics)
print(lsi_ko.print_topics(num_topics=ntopics, num_words=nwords))

#LDA
import numpy as np; np.random.seed(42)  # optional
lda_ko = models.ldamodel.LdaModel(tfidf_ko, id2word=dictionary_ko, num_topics=ntopics)
print(lda_ko.print_topics(num_topics=ntopics, num_words=nwords))

#HDP
import numpy as np; np.random.seed(42)  # optional
hdp_ko = models.hdpmodel.HdpModel(tfidf_ko, id2word=dictionary_ko)
print(hdp_ko.print_topics(topics=ntopics, topn=nwords))

#Scoring document
bow = tfidf_model_ko[dictionary_ko.doc2bow(texts_ko[0])]
sorted(lsi_ko[bow], key=lambda x: x[1], reverse=True)
sorted(lda_ko[bow], key=lambda x: x[1], reverse=True)
sorted(hdp_ko[bow], key=lambda x: x[1], reverse=True)
bow = tfidf_model_ko[dictionary_ko.doc2bow(texts_ko[1])]
sorted(lsi_ko[bow], key=lambda x: x[1], reverse=True)
sorted(lda_ko[bow], key=lambda x: x[1], reverse=True)
sorted(hdp_ko[bow], key=lambda x: x[1], reverse=True)

result) 아래 결과를 통해 육야휴직, 임신에 대한 글들이 대부분이라는 것을 알수 있습니다.


==LSI==
[u'0.527*"육아휴직/Noun" + 0.261*"만/Noun" + 0.231*"%xd7/Foreign" + 0.217*"대체/Noun" + 0.204*"고용/Noun"', u'0.455*"파견/Noun" + 0.417*"부대/Noun" + 0.266*"UAE/Alpha" + 0.246*"○/Foreign" + 0.195*"국군/Noun"', u'-0.313*"결혼/Noun" + -0.276*"손해/Noun" + -0.255*"예고/Noun" + -0.210*"ㆍ/Foreign" + -0.204*"입법/Noun”']

===LDA===
[u'0.002*육아휴직/Noun + 0.001*만/Noun + 0.001*…/Foreign + 0.001*%xd7/Foreign + 0.001*고용/Noun', u'0.001*결혼/Noun + 0.001*손해/Noun + 0.001*학위/Noun + 0.001*간호/Noun + 0.001*원사/Noun', u'0.002*육아휴직/Noun + 0.001*만/Noun + 0.001*부대/Noun + 0.001*대체/Noun + 0.001*파견/Noun’]

==HDP==
[u'topic 0: 0.004*임신/Noun + 0.003*놓다/Verb + 0.003*육아휴직/Noun + 0.003*부/Noun + 0.003*하루/Noun', u'topic 1: 0.004*공/Noun + 0.003*시험/Noun + 0.003*생략/Noun + 0.003*러버/Noun + 0.003*학년/Noun', u'topic 2: 0.004*질타/Noun + 0.003*724/Number + 0.003*열/Noun + 0.003*15/Number + 0.003*WHO/Alpha']

 3.2. Word2Vec을 이용한 Word Embedding
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

#load
from konlpy.corpus import kobill
docs_ko = [kobill.open(i).read() for i in kobill.fileids()]

#Tokenize
from konlpy.tag import Twitter; t = Twitter()
pos = lambda d: ['/'.join(p) for p in t.pos(d)]
texts_ko = [pos(doc) for doc in docs_ko]

#train
from gensim.models import word2vec
wv_model_ko = word2vec.Word2Vec(texts_ko)
wv_model_ko.init_sims(replace=True)
wv_model_ko.save('ko_word2vec_e.model')

#test
print(wv_model_ko.most_similar(pos('메르스')))

Result)
메르스라는 단어에 대해 유사검색을 실행했고, 첫번째 유사도로 찾은 단어는 \ubcd1\uc6d0 로서, "병원"입니다.
(출력된 결과를 유니코드 변환 사이트에서 돌려보면 금방 확인이 가능합니다.(http://allog.tistory.com/41)  ) 

[(u'병원/Noun', 0.9664202928543091), (u"'/Punctuation", 0.9501774311065674), (u'…/Foreign', 0.945787250995636), (u'"/Punctuation', 0.8908506631851196), (u'%xb7/Foreign', 0.8733454942703247), (u'[/Punctuation', 0.8687864542007446), (u']/Punctuation', 0.8462499976158142), (u'연합뉴스/Noun', 0.8382998704910278), (u'공개/Noun', 0.8208351731300354), (u'있어/Adjective', 0.8137425184249878)] [(u'취학/Noun', 0.9841623306274414), (u'중인/Noun', 0.9737297296524048), (u'號/Foreign', 0.9697698950767517), (u'학년/Noun', 0.9695179462432861), (u'第/Foreign', 0.9606421589851379), (u'조정함/Verb', 0.9572989344596863), (u'상향/Noun', 0.9528375864028931), (u'지방/Noun', 0.949833869934082), (u'여자/Noun', 0.9465466737747192), (u'44/Number', 0.9451450109481812)]

한글 데이터 분석에서 gensim 조합은 매우 좋은 선택입니다. 사용법이 매우 쉬우며 이미 잘 정리된 library들이 있습니다.


NLTK + KoNLPy + Word2Vec이면 많은 문제를 직관적으로 해결할수 있습니다.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

 

원문 : http://blog.naver.com/PostView.nhn?blogId=2feelus&logNo=220384206922&redirect=Dlog&widgetTypeCall=true

 

[출처] https://www.nextobe.com/single-post/2017/06/28/%ED%95%9C%EA%B8%80-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-%EB%B0%8F-word2vec%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9C%A0%EC%82%AC%EB%8F%84-%EB%B6%84%EC%84%9D

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
공지 오라클 기본 샘플 데이터베이스 졸리운_곰 2014.01.02 86979
공지 [SQL컨셉] 서적 "SQL컨셉"의 샘플 데이타 베이스 SAMPLE DATABASE of ORACLE 가을의 곰을... 2013.02.10 79241
공지 [G_SQL] Sample Database 가을의 곰을... 2012.05.20 95978
61 [몽고디비 mongodb] MongoDB Bulk Insert – MongoDB insertMany file 졸리운_곰 2020.10.09 773
60 [mongodb 몽고디비] How to insert multiple document into a MongoDB collection using Java? 졸리운_곰 2020.10.09 1168
59 Mongodb Bulk operation 졸리운_곰 2020.10.09 957
58 MongoDB Bulk Write(대랑 쓰기) & Retryable Write(쓰기 재시도) file 졸리운_곰 2020.10.09 1349
57 How to work with MongoDB in .NET file 졸리운_곰 2020.09.30 1380
56 MongoDB : 기본 구조 file 졸리운_곰 2020.09.30 1131
55 [mongodb] SQL to Aggregation Mapping Chart 몽고디비 SQL 쿼리 매핑 졸리운_곰 2020.09.23 1509
54 초간단 Mongo DB Quick Start Guide file 졸리운_곰 2020.09.20 920
53 MongoDB(몽고디비) 특징 정리 file 졸리운_곰 2019.12.25 1274
52 MongoDB의 한계(?) 졸리운_곰 2019.01.22 1184
51 MongoDB의 기본 CRUD 문법. 졸리운_곰 2018.12.30 1532
50 MongoDB를 쓰면서 알게 된 것들 file 졸리운_곰 2018.12.30 1594
49 [MongoDB] MongoDB의 제약사항들. (MongoDB limits thresholds) 졸리운_곰 2018.12.30 1509
48 몽고DB 컬렉션 관리 졸리운_곰 2018.12.30 1255
47 MongoDB 명령어 (database, collection, document, query, cursor, index) file 졸리운_곰 2018.12.30 1274
46 Neo4j 소개 file 졸리운_곰 2018.07.05 1331
45 [DB] neo4j를 정리하자. file 졸리운_곰 2018.07.05 1229
44 Neo4J - 그래프 데이터베이스 file 졸리운_곰 2018.07.05 1476
43 MongoDB CRUD 동작의 이해 졸리운_곰 2018.06.26 1264
42 NoSQL 데이타 모델링 #1 file 졸리운_곰 2018.04.15 1640
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED