#!/usr/bin/env python # coding: utf-8 # # #

# # **Chapter 3 | word2vec** # ## **1 데이터 전처리** # [**word2vec matplotlib**](https://www.kaggle.com/jeffd23/visualizing-word-vectors-with-t-sne) # In[ ]: # ! apt-get update # ! apt-get install g++ openjdk-8-jdk # ! pip3 install nltk konlpy matplotlib gensim # ! apt-get install fonts-nanum-eco # ! apt-get install fontconfig # ! fc-cache -fv # ! cp /usr/share/fonts/truetype/nanum/Nanum* /usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/fonts/ttf/ # ! rm -rf /content/.cache/matplotlib/* # script_text = "https://raw.githubusercontent.com/YongBeomKim/nltk_tutorial/master/data/movie_memories_of_murder_2003.txt" # font_file = "/usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/fonts/ttf/NanumGothicCoding.ttf" script_text = "../data/movie_memories_of_murder_2003.txt" font_file = "../data/D2Coding.ttf" # In[ ]: import matplotlib as mpl import matplotlib.pyplot as plt import matplotlib.font_manager as fm font_name = fm.FontProperties(fname=font_file, size=10).get_name() plt.rc('font', family=font_name) fm._rebuild() mpl.rcParams['axes.unicode_minus'] = False # In[ ]: get_ipython().run_line_magic('matplotlib', 'inline') from sklearn.manifold import TSNE import matplotlib.pyplot as plt def tsne_plot(model, figsize=(12,12)): "Creates and TSNE model and plots it" labels, tokens = [], [] for word in model.wv.vocab: tokens.append(model[word]) labels.append(word) tsne_model = TSNE(n_components=2) new_values = tsne_model.fit_transform(tokens) x, y = [], [] for value in new_values: x.append(value[0]) y.append(value[1]) plt.figure(figsize=figsize) for i in range(len(x)): plt.scatter(x[i],y[i]) plt.annotate(labels[i], xy = (x[i], y[i]), fontsize=15) # ha = 'right', # va = 'bottom') plt.grid(True) plt.show() # In[ ]: # 텍스트를 줄단위로 끊어서 불러온뒤 # Token 단위로, 한글명사들을 추출한다 def txtnoun(sentences , skip=False, tags=['Noun'], stem=True, set_tokens=False): r""" 살인의 추억 대본의 텍스트 전처리 작업을 진행합니다 :param sentences: 단일한 Text String 데이터를 입력합니다 :param skip: 분류된 Token 중 사용자가 원하는 형태로 변환된 내용을 출력 :param tags: konlpy 로 분류된 품사중 추출하고자 하는 품사를 정의합니다 :param stem: stemming 작업여부를 정의합니다. :param set_tokens: return 결과를 token list 객체로 출력할지를 정의합니다 :return: set_tokens 내용에 따라 List, String 타입으로 출력합니다 """ import re from konlpy.tag import Okt twitter = Okt() result = [] sentences = sentences.replace('\n', '\n|') sentences = sentences.split('|') for content in sentences: texts = content.replace('\n', '') # 해당줄의 줄바꿈 내용 제거 tokenizer = re.compile(r'[^ ㄱ-힣]+') # 한글과 띄어쓰기를 제외한 모든 글자를 선택 token_data = tokenizer.sub('', texts) # 한글과 띄어쓰기를 제외한 모든 부분을 제거 token_data = token_data.split(' ') sentence = [] for token in token_data: # skip 대상이 없을 떄 if skip == False: chk_tok = twitter.pos(token, stem=stem) chk_tok = [temp[0] for temp in chk_tok if temp[1] in tags] ckeck = "".join(chk_tok) if len(ckeck) > 1: sentence.append(ckeck) # skip 내용이 있을 때 else: if token.strip() in skip.keys(): result.append(skip[token.strip()]) else: chk_tok = twitter.pos(token, stem=stem) chk_tok = [temp[0] for temp in chk_tok if temp[1] in tags] ckeck = "".join(chk_tok) # 전처리가 끝난 결과가 skip에 해당여부 판단 if ckeck.strip() in skip.keys(): result.append(skip[ckeck.strip()]) elif len(ckeck) > 1: sentence.append(ckeck) # 단락별 작업이 끝난 뒤 '\n'를 덧붙여서 작업을 종료 temp = "".join(sentence) if len(temp) > 1: sentence = " ".join(sentence) sentence += "\n" result.append(sentence) if set_tokens == True: from nltk.tokenize import word_tokenize set_token = word_tokenize(" ".join(result)) return list(set(set_token)) else: return " ".join(result) # In[ ]: skips = {'두만':'박두만', '태윤':'서태윤', '용구':'조용구', '귀옥':'권귀옥', '희봉':'구희봉', '동철':'신동철', '광호':'백광호', '병순':'조병순', '해일':'박해일', '광호의':'백광호', '백광호의':'백광호'} # In[ ]: # import requests # sentences = requests.get(script_text).text # sentences[:300] with open(script_text, 'r') as f: sentences = f.read() sentences[:300] # In[ ]: sentences = txtnoun(sentences, skip=skips, tags=['Noun']) script_file = 'script.txt' with open(script_file, 'w', encoding='utf-8') as file: file.write(sentences) # In[ ]: get_ipython().run_cell_magic('time', '', 'from gensim.models import word2vec\ndata = word2vec.LineSentence(script_file)\nmodel = word2vec.Word2Vec(data, size=30, window=2, min_count=10, \n hs=1, workers=4, iter=100, sg=1)\nmodel_file = "script.model"\nmodel.save(model_file)\n') #

# ## **2 Word2Vec 모델의 활용** # 모델을 활용하여 유력한 범인을 찾아보자!! # In[ ]: # 저장된 학습모델파일 불러오기 from gensim.models import word2vec model_file = "script.model" model = word2vec.Word2Vec.load(model_file) len(model.wv.vocab.keys()) # In[ ]: model.wv.vocab.keys() #

# ## **3 Word2Vec 모델 내용 확인** # 모델을 활용하여 유력한 범인을 찾아보자!! # In[ ]: # 범인과 관련된 내용 중 사람이름이 안나옴... model.wv.most_similar('범인', topn=10) # In[ ]: # 현장과 가장 가깝게 등장한 인물이 1명 등장 model.wv.most_similar('현장', topn=10) # In[ ]: # 현장 과 백광호 와 밀접한 증거들 중에 방해가 되는 내용을 찾는다 model.wv.most_similar(['현장','이향숙'], topn=10) # In[ ]: # 현장 과 백광호 와 밀접한 증거들 중에 방해가 되는 내용을 찾는다 model.wv.most_similar(['현장', '백광호'], topn=10) # In[ ]: # 현장 과 백광호 와 밀접한 증거들 중에 '참깨밭' 이 계속 방해가 됨 # 참깨밭에 백광호가 밀접하게 연결되어 있어서 이를 제외한 분석이 필요 model.wv.most_similar(['현장','백광호'], negative=['참깨밭'], topn=15) # In[ ]: # 현장 과 백광호 와 밀접한 증거들 중에 '참깨밭' 이 계속 방해가 됨 # 참깨밭에 백광호와 이향숙을 제외한 분석이 필요 model.wv.most_similar(['현장','백광호'], negative=['참깨밭','이향숙'], topn=20) #

# ## **4 Visulaization** # gensim # In[ ]: vocab = list(model.wv.vocab) X = model[vocab] # In[ ]: from sklearn.manifold import TSNE tsne = TSNE(n_components = 2) X_tsne = tsne.fit_transform(X) # In[ ]: import pandas as pd df = pd.DataFrame(X_tsne, index=vocab, columns=['x','y']) df.head() # In[ ]: get_ipython().run_line_magic('matplotlib', 'inline') import matplotlib.pyplot as plt fig = plt.figure(figsize=(12,12)) ax = fig.add_subplot(1, 1, 1) ax.scatter(df['x'], df['y']) for word, pos in df.iterrows(): ax.annotate(word, pos, fontsize=15) plt.grid(True) # In[ ]: tsne_plot(model) #

# ## **5 결과의 해석 및 활용** # 1. 유사관계, 반대관계로 **출력된 모든 Token들이 가치가 있지는 않다** # 1. **min_count, Vector 갯수** 2가지 조건만 사용하여 모델을 생성한다 # 1. Word2Vec 도 **문서를 분석하는 도구**에 불과 (절대적 **가치를 창출하는 기법** 으로 오해 X) # 1. 해당 분야의 **잘 정리된 Document로 학습한 Word2Vec 모델** 에서 **유의미 한 token 들의 관계** 를 Template으로 잘 정리 # 1. 분석대상 문서를 **유사한 조건으로 word2vec 모델** 을 만들고, **앞에서 정리된 Template와** 비교하여 결과 # 다듬기 # 1. 시나리오의 분석 경우 # 1. 결과물 중 인물의 Token 만 활용하여 분석 # 1. 결과물 중 증거물의 Token 만 활용하여 분석 # 1. 결과물 중 장소의 Token 만 활용하여 분석 # In[ ]: # model 에 등장하는 인물들 charator = ["박두만", "서태윤", "조용구", "권귀옥", "구희봉", "신동철", "백광호", "조병순", "박해일", "박보희", "이향숙", "독고현순", "박명자", "안미선", "반장", "소현", "범인", "형사", '괴남자', '순경','피해자', '권기옥','용의자'] # In[ ]: # model 에 등장하는 장소명 들 area = ['현장', '사무실', '취조실', '변소', '참깨밭', '빗줄기', '어둠속', '언덕집'] # In[ ]: # model 에 등장하는 Item 들 items = ['브래지어', '팬티', '우산', '운동화', '스타킹', '목소리', '불빛', '음악', '후레쉬', '카메라', '라디오', '방송', '유전자', '가방', '코피', '휴지', '신문', '총구']