728x90
반응형
In [277]:
import os
corpus = list()
for filename in os.listdir('./News'):
if filename.startswith('정치'):
with open('./News/'+filename,encoding='utf-8') as f:
corpus.append(f.read())
In [278]:
corpus[0]
Out[278]:
In [279]:
from string import punctuation
corpus2 = list()
for i in range(len(corpus)):
corpus[i] = corpus[i].translate(str.maketrans('', '', punctuation))
corpus[i] = corpus[i].replace('flash 오류를 우회하기 위한 함수 추가\nfunction flashremoveCallback', '')
corpus2.append((corpus[i]))
In [280]:
len(corpus2)
Out[280]:
In [285]:
## 진짜 Noun으로만 DTM 만드는거
DTM = defaultdict(lambda: defaultdict(int))
dictNoun = list()
for i in range(len(corpus2)):
for t in Kkma().pos(corpus2[i]):
if len(t[0]) >1 and t[1].startswith('N'):
DTM[i][t[0]] += 1
In [313]:
# DTM
In [287]:
termList = list(list([] for _ in range(len(corpus2))))
In [288]:
for i in range(len(corpus2)):
for j,d in DTM[i].items():
termList[i].append(j)
In [294]:
len(termList), type(termList)
Out[294]:
In [295]:
from collections import defaultdict
documents = defaultdict(lambda: defaultdict(int)) # DTM
vocabulary = list()
# i : 문서제목 / d : i번째 문서 내 단어목록
for i, d in enumerate(termList):
for term in d:
documents[i][term.lower()] += 1
vocabulary.append(term.lower())
vocabulary = list(set(vocabulary))
In [297]:
# D : docu, a,b
# alpha, beta 만들기
a = 0.1
b = 0.1
K = 3 # 전체 토픽 수
M = len(documents) # 전체 문서의 수
V = len(vocabulary) # 전체 단어의 수
# N은 특정 문서마다 항상 다르다.
# 특정 토픽에 몇 개의 단어가 있는지 -> 분모
# 특정 토픽 : sum(단어)
topicTermCount = defaultdict(int)
# 특정 문서의 단어에 상관없이 토픽 할당 횟수
docTopicDistribution = defaultdict(lambda: defaultdict(int))
# [document][0번째토픽: 몇 개의 단어, 1번째 토픽:몇 개의 단어]
# 문서에 상관없이 특정 단어의 토픽 할당 횟수
topicTermDistribution = defaultdict(lambda: defaultdict(int))
# [topic][vocab 0 : 몇 번, ... , n]
# Z_ml = m번째 문서 1번째 단어의 Topic
# M개의 문서만큼 -> N개의 단어 -> Topic
termTopicAssignmentMatrix = defaultdict(lambda:defaultdict(int))
# Z[documents][term] = topic
# n(i,(j,r)) = i번째 토픽의 횟수, j번째 문서의 r번째 단어
In [299]:
from random import randrange,seed
seed(0)
for i,t in enumerate(termList):
for j, term in enumerate(t):
token = term.lower()
topic = randrange(K)
topicTermCount[topic] += 1
docTopicDistribution[i][topic] += 1
topicTermDistribution[topic][term] += 1
termTopicAssignmentMatrix[i][j] = topic
In [300]:
from random import random
def collapsedGibbsSampling(i,term):
sampling = list()
# k번째 토픽에 대한 확률
for k in range(K):
sampling.append(likelighoodAlpha(i,k) * likelighoodBeta(k,term))
# 0~1의 실수값을 가짐
threshold = sum(sampling) * random()
for topicNo, topicProbability in enumerate(sampling):
threshold -= topicProbability
if threshold <= 0.0:
return topicNo
# print(sampling)
# return termTopicAssignmentMatrix[i][term]
In [301]:
def likelighoodAlpha(i,k):
return docTopicDistribution[i][k] + a
In [302]:
def likelighoodBeta(k,term):
return (topicTermDistribution[k][term] +b) / (topicTermCount[k] + b * V)
In [304]:
iterationNumber = 1000
for _ in range(iterationNumber):
# m을 고정, l을 고정해야함 -> topicTermAssingnmentMatrix
# m,l => i, j
for i,t in enumerate(termList):
for j,term in enumerate(t):
topic = termTopicAssignmentMatrix[i][j]
topicTermCount[topic] -= 1
docTopicDistribution[i][topic] -= 1
topicTermDistribution[topic][term] -= 1
topic = collapsedGibbsSampling(i,term)
topicTermCount[topic] += 1
docTopicDistribution[i][topic] += 1
topicTermDistribution[topic][term] += 1
termTopicAssignmentMatrix[i][j] = topic
In [306]:
topicTermCount
Out[306]:
In [314]:
# topicTermDistribution
# 결과가 기니 직접 쳐서 확인해보자
In [308]:
docTopicDistribution
Out[308]:
In [315]:
# termTopicAssignmentMatrix
# 결과가 기니 직접 쳐서 확인해보자
728x90
반응형