In [1]:
from gensim.utils import simple_preprocess
from gensim import corpora, models, similarities
from os import listdir
In [2]:
"""
os textos de cada classes estão divididos em
subdiretórios dentro de path
"""
class MyCorpus(object):
def __init__(self,path):
self.path = path
self.klasses = self.file_ids_klass()
self.dictionary = corpora.Dictionary(self.get_text(fname) for fname in self.klasses.keys())
def __iter__(self):
for fname in self.klasses.keys():
yield self.dictionary.doc2bow(self.get_text(fname))
def text_bow(self,fname):
return self.dictionary.doc2bow(self.get_text(fname))
def file_ids_klass(self):
ids = {}
for klass in listdir(self.path):
for fname in listdir(self.path+'/'+klass):
ids[klass+'/'+fname] = klass
return ids
def get_text(self,fname):
with open(self.path+'/'+fname) as finput:
text = ''.join(finput.readlines())
return self.pre_process(text)
"""
por hora, um preprocessamento simples...
podemos trocar por um mais elaborado depois
"""
def pre_process(self,text):
return simple_preprocess(text)
In [3]:
mc = MyCorpus('/home/kadnoise/Downloads/review_polarity/txt_sentoken/')
In [ ]:
In [ ]:
# gera o modelo tf-idf
tfidf = models.TfidfModel(mc)
In [ ]:
# cria um grafo dirigido (Digrafo)
import networkx as nx
G = nx.DiGraph()
# cada texto é um nó do grafo
# a classe do texto é um atributo do nó do grafo
for k,v in mc.klasses.items():
G.add_node(k,klass=v)
In [ ]:
# adiciona as arestas no grafo
# nomes dos arquivos...
# variável auxiliar...
names = mc.klasses.keys()
# gera o modelo de similaridades
# para encontaros k-vizinhos de cada nó
# num_best é o número de k-vizinhos + 1 (pois o nó é vizinho dele mesmo)
# num_best=11 gera um grafo com 10 vizinhos pra cada nó
index = similarities.Similarity('tmp',tfidf[mc],num_features=len(mc.dictionary.keys()),num_best=11)
for k in names:
for nn in index[tfidf[mc.text_bow(k)]]:
if not k==names[nn[0]]:
G.add_edge(k,names[nn[0]],weight=nn[1])
In [ ]:
# calcula a distribuição do grau de cada nó
from collections import Counter
# como o out_degree é sempre 10 (por construção)
# basta usar o in_degree
degree = G.in_degree().values()
cdegree = Counter(degree)
In [ ]:
# skewness and kurtosis mede o quanto não uniforme é a distribuição
from scipy.stats import skew, kurtosis
print skew(degree), kurtosis(degree)
In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt
In [ ]:
plt.plot(cdegree.keys(),cdegree.values(),'bo-')
In [ ]:
good_bad_edges = {}
for k in names:
good_bad_edges[k] = {}
good_bad_edges[k]['good'] = 0
good_bad_edges[k]['bad'] = 0
good_bad_edges[k]['all'] = 0
for edge in G.in_edges(k):
if G.node[edge[0]]['klass'] == G.node[edge[1]]['klass']:
good_bad_edges[k]['good']+=1
else:
good_bad_edges[k]['bad']+=1
good_bad_edges[k]['all']+=1
In [ ]:
baddegree = [d['bad'] for d in good_bad_edges.values()]
CBad = Counter(baddegree)
In [ ]:
plt.plot(cdegree.keys(),cdegree.values(),'bo-')
plt.plot(CBad.keys(),CBad.values(),'ro-')
In [ ]:
print skew(baddegree), kurtosis(baddegree)
In [ ]:
from scipy.stats import spearmanr,pearsonr
import numpy as np
corr = np.array([[d['bad'], d['all']] for d in good_bad_edges.values()])
print spearmanr(corr[:,0],corr[:,1]), pearsonr(corr[:,0],corr[:,1])
In [ ]:
import numpy as np
color = ['r' if node[1]['klass'] == 'positive' else 'b' for node in G.nodes(data=True)]
pos = nx.spring_layout(G)
ec = nx.draw_networkx_edges(G, pos, alpha=0.01)
nc = nx.draw_networkx_nodes(G, pos, node_color=color, node_size=2**np.sqrt(np.array(degree)),alpha=0.3)
In [ ]: