# ! 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"
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
%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()
# 텍스트를 줄단위로 끊어서 불러온뒤
# 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)
skips = {'두만':'박두만', '태윤':'서태윤', '용구':'조용구', '귀옥':'권귀옥',
'희봉':'구희봉', '동철':'신동철', '광호':'백광호', '병순':'조병순',
'해일':'박해일', '광호의':'백광호', '백광호의':'백광호'}
# import requests
# sentences = requests.get(script_text).text
# sentences[:300]
with open(script_text, 'r') as f:
sentences = f.read()
sentences[:300]
sentences = txtnoun(sentences, skip=skips, tags=['Noun'])
script_file = 'script.txt'
with open(script_file, 'w', encoding='utf-8') as file:
file.write(sentences)
%%time
from gensim.models import word2vec
data = word2vec.LineSentence(script_file)
model = word2vec.Word2Vec(data, size=30, window=2, min_count=10,
hs=1, workers=4, iter=100, sg=1)
model_file = "script.model"
model.save(model_file)
# 저장된 학습모델파일 불러오기
from gensim.models import word2vec
model_file = "script.model"
model = word2vec.Word2Vec.load(model_file)
len(model.wv.vocab.keys())
model.wv.vocab.keys()
# 범인과 관련된 내용 중 사람이름이 안나옴...
model.wv.most_similar('범인', topn=10)
# 현장과 가장 가깝게 등장한 인물이 1명 등장
model.wv.most_similar('현장', topn=10)
# 현장 과 백광호 와 밀접한 증거들 중에 방해가 되는 내용을 찾는다
model.wv.most_similar(['현장','이향숙'], topn=10)
# 현장 과 백광호 와 밀접한 증거들 중에 방해가 되는 내용을 찾는다
model.wv.most_similar(['현장', '백광호'], topn=10)
# 현장 과 백광호 와 밀접한 증거들 중에 '참깨밭' 이 계속 방해가 됨
# 참깨밭에 백광호가 밀접하게 연결되어 있어서 이를 제외한 분석이 필요
model.wv.most_similar(['현장','백광호'], negative=['참깨밭'], topn=15)
# 현장 과 백광호 와 밀접한 증거들 중에 '참깨밭' 이 계속 방해가 됨
# 참깨밭에 백광호와 이향숙을 제외한 분석이 필요
model.wv.most_similar(['현장','백광호'], negative=['참깨밭','이향숙'], topn=20)
vocab = list(model.wv.vocab)
X = model[vocab]
from sklearn.manifold import TSNE
tsne = TSNE(n_components = 2)
X_tsne = tsne.fit_transform(X)
import pandas as pd
df = pd.DataFrame(X_tsne, index=vocab, columns=['x','y'])
df.head()
%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)
tsne_plot(model)
다듬기
# model 에 등장하는 인물들
charator = ["박두만", "서태윤", "조용구", "권귀옥", "구희봉", "신동철", "백광호",
"조병순", "박해일", "박보희", "이향숙", "독고현순", "박명자", "안미선",
"반장", "소현", "범인", "형사", '괴남자', '순경','피해자', '권기옥','용의자']
# model 에 등장하는 장소명 들
area = ['현장', '사무실', '취조실', '변소', '참깨밭', '빗줄기', '어둠속', '언덕집']
# model 에 등장하는 Item 들
items = ['브래지어', '팬티', '우산', '운동화', '스타킹', '목소리', '불빛', '음악', '후레쉬',
'카메라', '라디오', '방송', '유전자', '가방', '코피', '휴지', '신문', '총구']