def save_classis(self, cn):
     if self.lclassis is None:
         self.set_classisname(cn)
         self.lclassis = InfinityArray(self.classisname, self.classisname)
         #self.lclassis.open()
     self.lclassis.new()
     if not self.lclassis.ready() or self.lclassis.size == 0:
         for nome, classe in self.classis.iteritems():
             self.lclassis.append((nome, classe))
     self.lclassis.end()
 def load_classis(self, cn):
     self.set_classisname(cn)
     self.lclassis = InfinityArray(self.classisname, self.classisname)
     self.lclassis.open()
     if (self.lclassis.ready()):
         self.classis = {}
         for i in xrange(self.lclassis.size):
             k, v = self.lclassis.getx(i)
             self.classis[k] = v
         self.lclassis.end()
     else:
         self.lclassis.end()
         self.lclassis = None
 def load_listapares(self):
     print "Carrega lista pares..."
     self.pares = InfinityArray(self.paresname, 'x' + self.paresname)
     self.pares.open()
     if (not self.pares.ready()):
         for index, row in self.data[['id', 'qid1', 'qid2',
                                      'is_duplicate']].iterrows():
             par = Par(int(row['qid1']) - 1, int(row['qid2']) - 1)
             par.setLabel(row['is_duplicate'])
             par.process(self.colecao, self.get_fetures())
             self.pares.append(par)
             if (index % 1000 == 0):
                 print "\rProcessados {} pares: ({},{})={}".format(
                     index, par.getLabel(), par.getWeight(),
                     par.getVetSim())
Example #4
0
 def __init__(self,
              ltxt=None,
              name='colecao',
              tks=None,
              stopw=True,
              ngram=False):
     self.tokenizer = tks if tks else Tokenizer(sw=stopw)
     self.voc = {}  # Lista invertida: vocabulario => lista
     self.totaltok = 0  # Total de tokens do dataset
     self.documentos = InfinityArray(name + '.bin',
                                     name + '.idx')  # lista de bagtok
     self.documentos.open()
     self.ngram = ngram
     if (ltxt is None or self.documentos.ready()):
         for i in xrange(self.documentos.size):
             bag = self.documentos.getx(i)
             for t in bag.listToken():
                 st = self.voc.get(t)
                 if not st:
                     st = StaTok()
                     self.voc[t] = st
                 st.addIdDoc(i, bag.getWeight(t))
                 self.totaltok += 1
     else:
         i = 0
         cls = Cleaner()
         for txt in ltxt:
             txt = cls.onlytext(str(txt))
             bag = self.tokenizer.tokenize_ngram(txt) if (
                 self.ngram) else self.tokenizer.tokenize(txt)
             i += 1
             for t in bag.listToken():
                 st = self.voc.get(t)
                 if not st:
                     st = StaTok()
                     self.voc[t] = st
                 st.addIdDoc(i, bag.getWeight(t))
                 self.totaltok += 1
             self.documentos.append(bag)
         self.documentos.end()
class Experimento():
    ### CONSTANTES
    ddir = 'datasets'
    dname = 'train.csv'
    dcname = 'classis'
    drname = 'res.csv'
    dlcolname = ['colecao', 'colecao_gram', 'colecao_sw', 'colecao_gram_sw']
    dlparesname = ['pares', 'pares_gram', 'pares_sw', 'pares_gram_sw']
    dfeatures = {'Jaccard':Jaccard(),'BagSim':BagSim(),'Coseno':Coseno(),\
                 'TFIDF':TFIDF(),'SoftTFIDF':softTFIDF(),'STFIDFSound':softTFIDF(func=Soundex()),\
                 'STFIDFLeven':softTFIDF(func=Levenstein()),'STFIDFMonge':softTFIDF(func=MongeElkan()),\
                 'STFIDFSmith':softTFIDF(func=SmithWaterman()),'FullSim':FullSimilarity(),\
                 'FullSimSound':FullSimilarity(func=Soundex()),'FullSimLeven':FullSimilarity(func=Levenstein()),\
                 'FullSimMonge':FullSimilarity(func=MongeElkan()),'FullSimSmith':FullSimilarity(func=SmithWaterman())}
    dclassis = {'MultinomialNB':MultinomialNB(),'GaussianNB':GaussianNB(),\
               'SGDClassifier':SGDClassifier(loss='log', penalty='l2',alpha=1e-3, n_iter=10, learning_rate='optimal'),\
               'MLPClassifier':MLPClassifier(activation='relu',solver='lbfgs'),\
               'DecisionTreeClassifier':DecisionTreeClassifier(criterion='entropy',max_depth=20),\
               'RandomForestClassifier':RandomForestClassifier(criterion='entropy',max_depth=20, n_estimators=15),\
               'GradientBoostingClassifier':GradientBoostingClassifier(n_estimators=15, learning_rate=1.0, max_depth=20)}
    dmetricas = {'log_loss':log_loss,'f1_score':f1_score,'accuracy_score':accuracy_score,\
                 'classification_report':classification_report,'precision_recall_curve':precision_recall_curve,\
                 'average_precision_score':average_precision_score,'precision_score':precision_score,\
                 'recall_score':recall_score,'confusion_matrix':confusion_matrix}

    def __init__(self):
        # Parametros do experimento
        self.name = None  # nome do dataset
        self.ds = None  # caminho completo do dataset
        self.data = None  # dados do dataset
        self.listadocs = None  # Lista de documentos obtidos do dataset
        self.n = None  # número de rodadas
        self.features = None  # features do dataset (funcoes de similaridade)
        self.classis = None  # classificadores (tree, naive, svm, ...)
        self.classisname = None  # nome do arquivo que aramazena os classificadores
        self.lclassis = None  # array persistente que armazena os classificadores
        self.ntreino = None  # tamanho do treino
        self.metricas = None  # metricas aplicadas ao resultado (f1, precision, recall, log_loss, ...)
        self.comite = None  # parâmetros do comitê
        self.stopword = None  # indica se stop words serao removidos dos dados
        self.ngram = None  # indica se sera usado ngram
        self.colname = None  # nome do arquivo da colecao de documentos
        self.colecao = None  # Colecao de documentos com suas respectivas listas invertidas
        self.paresname = None  # nome do arquivo da lista de pares
        self.pares = None  # lista de pares de documentos
        self.vetsim = None  # Lista de features (similaridade) dos pares
        self.X_train = None  # Conjunto de Treino
        self.X_test = None  #  Conjunto de Teste
        self.y_train = None  # Conjunto dos rótulos do treino
        self.y_test = None  # Conjunto dos rótulos do teste
        self.tamcom = None  # Tamanho do comite
        self.comite = None  # Comite de classificadores
        self.resultados = None  # Resultados dos testes
        self.resultados_report = None  # Report dos resultados dos testes
        self.resultados_curve = None  # Resultados dos testes de precision recall curve
        self.resultados_confusion = None  # Resultados dos testes de Matriz de Confusao
        self.resname = None  # Nome do arquivo de resultados
        self.seed = None  # Semente de aleatoreidade

    # Seta o nome do dataset
    def set_name(self, nome):
        self.name = nome

    # Obtem o caminho completo do dataset
    def set_dataset(self):
        self.ds = os.sep.join([
            os.path.dirname(os.path.realpath(__file__)), self.ddir, self.name
        ])

    # Carrga os dados do dataset
    def load_dataset(self):
        print "Carrega dataset..."
        if (self.ds is None): self.set_dataset()
        self.data = pd.read_csv(self.ds)
        self.data = self.data.fillna("null")

    # Obtem lista de documentos do dataset
    def load_listadocs(self):
        print "Carrega lista de pares de documentos..."
        if (self.data is None): self.load_dataset()
        ldoc1 = self.data[['qid1', 'question1']].rename(columns={
            'qid1': 'qid',
            'question1': 'question'
        })
        ldoc2 = self.data[['qid2', 'question2']].rename(columns={
            'qid2': 'qid',
            'question2': 'question'
        })
        self.listadocs = ldoc1.append(ldoc2).sort_values(
            'qid').drop_duplicates()

    # Seta se removera stop words
    def set_stopword(self, sw):
        self.stopword = sw

    # Seta se os documentos serao divididos em ngram
    def set_ngram(self, ng):
        self.ngram = ng

    # Seta nome do arquivo de documentos
    def set_colname(self, cn):
        self.colname = cn

    # Gera a colecao de documentos com suas respectivas listas invertidas
    def load_colecao(self):
        if (self.listadocs is None): self.load_listadocs()
        print "Carrega colecao..."
        self.colecao = Colecao(list(self.listadocs['question']),
                               self.colname,
                               stopw=self.stopword,
                               ngram=self.ngram)

    # Seta nome do arquivo de documentos
    def set_paresname(self, pn):
        self.paresname = pn

    # Define as features
    def set_features(self, feat=dfeatures):
        self.features = feat

    # Obtem lista de nomes defeatures ordenada
    def get_fetures_name(self):
        if (self.features is None):
            return None
        else:
            return sorted(self.features.keys())

    # Obtem lista de features ordenada
    def get_fetures(self):
        if (self.features is None):
            return None
        else:
            return [self.features[k] for k in sorted(self.features.keys())]

    # Obtem lista de pares e tambem processa suas respectivas similaridades
    def load_listapares(self):
        print "Carrega lista pares..."
        self.pares = InfinityArray(self.paresname, 'x' + self.paresname)
        self.pares.open()
        if (not self.pares.ready()):
            for index, row in self.data[['id', 'qid1', 'qid2',
                                         'is_duplicate']].iterrows():
                par = Par(int(row['qid1']) - 1, int(row['qid2']) - 1)
                par.setLabel(row['is_duplicate'])
                par.process(self.colecao, self.get_fetures())
                self.pares.append(par)
                if (index % 1000 == 0):
                    print "\rProcessados {} pares: ({},{})={}".format(
                        index, par.getLabel(), par.getWeight(),
                        par.getVetSim())

    # Obtem o vetsim: lista de vetores de similaridade dos pares
    def load_vetsim(self):
        print "Carrega vetsim.."
        if (self.pares is None): self.load_listapares()
        self.pares.end()
        self.pares.start()
        self.vetsim = pd.DataFrame(data=np.array([self.pares.getx(i).getVetSim() for i in xrange(self.pares.size)], \
                       dtype = float), columns=list(self.get_fetures_name()))
        self.pares.end()

    # Define a semente da raiz para os processos aleatorios
    def set_seed(self, s):
        self.seed = s
        random.seed(s)

    # Carrega as classes do arquivo
    def load_classis(self, cn):
        self.set_classisname(cn)
        self.lclassis = InfinityArray(self.classisname, self.classisname)
        self.lclassis.open()
        if (self.lclassis.ready()):
            self.classis = {}
            for i in xrange(self.lclassis.size):
                k, v = self.lclassis.getx(i)
                self.classis[k] = v
            self.lclassis.end()
        else:
            self.lclassis.end()
            self.lclassis = None

    # Salva os classificadores
    def save_classis(self, cn):
        if self.lclassis is None:
            self.set_classisname(cn)
            self.lclassis = InfinityArray(self.classisname, self.classisname)
            #self.lclassis.open()
        self.lclassis.new()
        if not self.lclassis.ready() or self.lclassis.size == 0:
            for nome, classe in self.classis.iteritems():
                self.lclassis.append((nome, classe))
        self.lclassis.end()

    # Define o nome do arquivo que armazena os classificador
    def set_classisname(self, cn=dcname):
        self.classisname = cn

    # Define os classificadores
    def set_classis(self, cls=dclassis):
        if (self.classis is None):
            self.classis = cls

    # Obtem lista de nomes defeatures ordenada
    def get_classis_name(self):
        if (self.classis is None):
            return None
        else:
            return sorted(self.classis.keys())

    # Obtem lista de features ordenada
    def get_classis(self):
        if (self.classis is None):
            return None
        else:
            return [self.classis[k] for k in sorted(self.classis.keys())]

    # Define as metricas
    def set_metricas(self, m=dmetricas):
        self.metricas = m

    # Obtem lista de nomes das metricas ordenada
    def get_matricas_name(self):
        if (self.metricas is None):
            return None
        else:
            return sorted(self.metricas.keys())

    # Obtem lista de metricas ordenada
    def get_metricas(self):
        if (self.metricas is None):
            return None
        else:
            return [self.metricas[k] for k in sorted(self.metricas.keys())]

    # Define o tamanho do treino em %
    def set_ntreino(self, nt):
        self.ntreino = nt

    # Obtem o conjunto de dados de treino e teste
    def split_dados(self):
        print "Divide dataset entre treino e teste..."
        self.X_train,self.X_test,self.y_train,self.y_test = \
        train_test_split(self.vetsim,self.data.is_duplicate,train_size=self.ntreino,\
                         stratify=self.data.is_duplicate, random_state = self.seed)
        # Normaliza as features
        self.X_train.data = preprocessing.normalize(self.X_train, norm='l2')
        self.X_test.data = preprocessing.normalize(self.X_test, norm='l2')

    # Define o tamanho do comite
    def set_tamcom(self, tc):
        self.tamcom = tc

    # Cria o comite
    def set_comite(self, m, n):
        self.comite = Comite(m, n)

    # Seleciona os membros do comite: os classificadores com melhor acuracia
    def sel_membros(self):
        print "Seleciona membros para formar o comite..."
        membros = {}
        for nome, classe in sorted(self.classis.iteritems()):
            y_pred = classe.predict(self.X_train)
            score = self.metricas['accuracy_score'](self.y_train, y_pred)
            membros[nome] = score
        nm = sorted(membros, key=membros.get, reverse=True)[:self.tamcom]
        cm = [self.classis[n] for n in nm]
        self.set_comite(cm, n)

    # Realiza o treino dos classificadores
    def treinamento(self):
        print "Treinamento dos classificadores..."
        if (self.lclassis is None):
            for nome, classe in self.classis.iteritems():
                classe = classe.fit(self.X_train, self.y_train)
        self.sel_membros()
        # Treina o comite
        self.treina_comite()

    # Realiza o treino do comite conforme descrito no relatorio
    def treina_comite(self):
        print "Treinamento do comite.."
        self.comite.fit(self.X_train, self.y_train)

    # Realiza o teste dos classificadores e gera os resultados
    def avaliacao(self):
        print "Gera os resultados.."
        self.resultados = {}  # <classificador> => <dados metricas>
        self.resultados_confusion = {
        }  # <classificador> => <matriz de confulsao>
        self.resultados_curve = {
        }  # <classificador> => <curva de precisao revocação>
        self.resultados_report = {}  # <classificador> => <report>
        for nome, classe in sorted(self.classis.iteritems()):
            y_pred = classe.predict(self.X_test)
            y_proba = classe.predict_proba(self.X_test)
            dados = {}
            self.resultados[nome] = dados
            for nmet, met in sorted(self.metricas.iteritems()):
                if nmet in ('log_loss'):
                    dados[nmet] = met(self.y_test, y_proba)
                elif nmet in ('precision_recall_curve'):
                    self.resultados_curve[nome] = met(self.y_test, y_proba[:,
                                                                           1])
                elif nmet in ('confusion_matrix'):
                    self.resultados_confusion[nome] = met(self.y_test, y_pred)
                elif nmet in ('classification_report'):
                    self.resultados_report[nome] = met(self.y_test, y_pred)
                else:
                    dados[nmet] = met(self.y_test, y_pred)
        # Realiza o teste e prepara resultados do comite
        y_pred = self.comite.predict_ajust(self.X_test)
        y_proba = self.comite.predict_proba_original(self.X_test)
        dados = {}
        nome = 'COMITE'
        self.resultados[nome] = dados
        for nmet, met in sorted(self.metricas.iteritems()):
            if nmet in ('log_loss'):
                dados[nmet] = met(self.y_test, y_proba)
            elif nmet in ('precision_recall_curve'):
                self.resultados_curve[nome] = met(self.y_test, y_proba[:, 1])
            elif nmet in ('confusion_matrix'):
                self.resultados_confusion[nome] = met(self.y_test, y_pred)
            elif nmet in ('classification_report'):
                self.resultados_report[nome] = met(self.y_test, y_pred)
            else:
                dados[nmet] = met(self.y_test, y_pred)

    # Define o nome do arquivo de resultados
    def set_resname(self, rn=drname):
        self.resname = 'res_' + rn

    # Mostra e salva os resultados da avaliacao dos classificadores
    def mostra_resultados(self):
        if (self.resultados is None): self.avaliacao()
        cols = self.get_matricas_name()
        lvalues = [
            self.resultados.get(i) for i in sorted(self.resultados.keys())
        ]
        rdf = pd.DataFrame(data=lvalues,
                           index=sorted(self.get_classis_name() + ['COMITE']),
                           columns=cols)
        rdf.to_csv(self.resname, encoding='utf-8')
        print rdf

    # Mostra o resultado e gera a curva precisao-revocacao
    def mostra_resultados_curva(self):
        from itertools import cycle
        colors = cycle([
            'navy', 'turquoise', 'darkorange', 'cornflowerblue', 'teal',
            'blueviolet', 'chocolate', 'gold'
        ])

        if (self.resultados is None): self.avaliacao()
        cols = ['Precision', 'Recall', 'Threshold']
        lvalues = [
            self.resultados_curve.get(i)
            for i in sorted(self.resultados_curve.keys())
        ]
        lines = []
        labels = []
        plt.figure(figsize=(8, 10))
        classes = sorted(self.get_classis_name() + ['COMITE'])
        for l, color, c in zip(lvalues, colors, classes):
            (p, r, t) = l
            lin, = plt.plot(r, p, color=color, lw=2)
            lines.append(lin)
            labels.append(c)
        fig = plt.gcf()
        fig.subplots_adjust(bottom=0.35)
        plt.ylim([0.0, 1.05])
        plt.xlim([0.0, 1.0])
        plt.xlabel('Recall')
        plt.ylabel('Precision')
        plt.title('Precision-Recall Curve')
        plt.legend(lines, labels, loc=(0, 0), prop=dict(size=10))
        plt.savefig('curve_' + self.resname +
                    '.png')  # save the figure to file

        rdf = pd.DataFrame(data=lvalues,
                           index=sorted(self.get_classis_name() + ['COMITE']),
                           columns=cols)
        rdf.to_csv('curve_' + self.resname,
                   index=False,
                   encoding='utf-8',
                   tupleize_cols=True)
        print rdf

    # Mostra o resultado e gera a tabela de matriz de confulsao
    def mostra_resultados_confusion(self):
        if (self.resultados is None): self.avaliacao()
        v = [np.concatenate(a) for a in self.resultados_confusion.values()]
        rdf = pd.DataFrame(data=v,
                           index=sorted(self.get_classis_name() + ['COMITE']))
        rdf.to_csv('confusion_' + self.resname, encoding='utf-8')
        print rdf

    # Mostra o resultado e gera o report das metricas
    def mostra_resultados_report(self):
        if (self.resultados is None): self.avaliacao()
        cols = ['Classification Report']
        lvalues = [
            self.resultados_report.get(i)
            for i in sorted(self.resultados_report.keys())
        ]
        rdf = pd.DataFrame(data=lvalues,
                           index=sorted(self.get_classis_name() + ['COMITE']),
                           columns=cols)
        rdf.to_csv('report_' + self.resname, encoding='utf-8')
        print rdf

    # Executa uma rodada completa de experimento
    def rodada(self, s, nome, sw, ng, cn, pn, feat, cls, met, nt, tc, rn, fcn):
        self.set_seed(s)
        random.seed(s)
        self.set_name(nome)
        self.set_stopword(sw)
        self.set_ngram(ng)
        self.set_colname(cn)
        self.set_paresname(pn)
        self.load_colecao()
        self.set_features(feat)
        self.load_vetsim()
        self.load_classis(fcn)
        self.set_classis(cls)
        self.set_metricas(met)
        self.set_ntreino(nt)
        self.split_dados()
        self.set_tamcom(tc)
        self.treinamento()
        self.save_classis(fcn)
        self.avaliacao()
        self.set_resname(rn)
        self.mostra_resultados()
        self.mostra_resultados_curva()
        self.mostra_resultados_confusion()
        self.mostra_resultados_report()
Example #6
0
print "Processando Colecao de Documentos de TREINO..."
#colecao = Colecao(ltxt,'coltreino')
colecao = Colecao(ltxt,'coltreino')
print 'Tamanho Colecao Documentos Treino={}'.format(colecao.getTotalDoc())
print 'Tamanho Vocabulario={}'.format(colecao.size())
print 'Total Tokens={}\n'.format(colecao.getTotalTok())

print "Processando PARES DE TREINO.."
funcs = [Jaccard(), softTFIDF(func=Soundex()) , softTFIDF(), FullSimilarity(), BagSim()]
cols = ['Jaccard', 'softSoundex','softTFIDF', 'fullSim', 'bagSim']
pares = dados_treino[['id','qid1','qid2','is_duplicate']]
target = dados_treino.is_duplicate

print "Gerando Lista de Vetores de Similaridade de TREINO..."
lpares = InfinityArray('pares_treino.bin','pares_treino.idx')
lpares.open()
if(not lpares.ready()):
   for index, row in pares.iterrows():
      par = Par(int(row['qid1'])-1, int(row['qid2'])-1)
      par.setLabel(row['is_duplicate'])
      par.process(colecao,funcs)
      lpares.append(par)   
      if(index%1000==0):
         print "\rProcessados {} pares: ({},{})={}".format(index,par.getLabel(),par.getWeight(),par.getVetSim())
      
print 'Quantidade Pares de Treino: {}\n'.format(lpares.size)   
lpares.end()
del pares
del dados_treino
del ltxt[:]
Example #7
0
class Colecao():
    '''
    Classe que implementa uma lista invertida e uma lista de bag of tokens.
    Uma lista invertida é um indice de texto, onde cada palavra aponta para
    o documento (registro) em que ela pertence, conforme esquematizado abaixo:
    Dataset:
       1. aa bb ccc
       2. bb ddd mm
       3. mm ccc aa
       4. bb ddd bb
    Lista invertida:
       aa  => [1, 3]
       bb  => [1, 2, 4]
       ccc => [1]
       ddd => [2, 4]
       mm  => [2, 3]
    [aa, bb, ccc, ddd, mm] é o vocabulário. 
    Os documentos de ids 1,2,3 e 4 são armazenados como bag of tokens.
   '''
    def __init__(self,
                 ltxt=None,
                 name='colecao',
                 tks=None,
                 stopw=True,
                 ngram=False):
        self.tokenizer = tks if tks else Tokenizer(sw=stopw)
        self.voc = {}  # Lista invertida: vocabulario => lista
        self.totaltok = 0  # Total de tokens do dataset
        self.documentos = InfinityArray(name + '.bin',
                                        name + '.idx')  # lista de bagtok
        self.documentos.open()
        self.ngram = ngram
        if (ltxt is None or self.documentos.ready()):
            for i in xrange(self.documentos.size):
                bag = self.documentos.getx(i)
                for t in bag.listToken():
                    st = self.voc.get(t)
                    if not st:
                        st = StaTok()
                        self.voc[t] = st
                    st.addIdDoc(i, bag.getWeight(t))
                    self.totaltok += 1
        else:
            i = 0
            cls = Cleaner()
            for txt in ltxt:
                txt = cls.onlytext(str(txt))
                bag = self.tokenizer.tokenize_ngram(txt) if (
                    self.ngram) else self.tokenizer.tokenize(txt)
                i += 1
                for t in bag.listToken():
                    st = self.voc.get(t)
                    if not st:
                        st = StaTok()
                        self.voc[t] = st
                    st.addIdDoc(i, bag.getWeight(t))
                    self.totaltok += 1
                self.documentos.append(bag)
            self.documentos.end()

    def setDoc(self, i, txt):
        txt = str(txt)
        bag = self.tokenizer.tokenize_ngram(txt) if (
            self.ngram) else self.tokenizer.tokenize(txt)
        for t in bag.listToken():
            st = self.voc.get(t)
            if not st:
                st = StaTok()
                self.voc[t] = st
            st.addIdDoc(i, bag.getWeight(t))
            self.totaltok += 1
        self.documentos.append(bag)

    def getDocumentFrequency(self, t):
        st = self.voc.get(t)
        if not st:
            return 0.0
        else:
            return st.getFreq()

    def BagFrequency(self, b):
        bf = {}
        for t in b.listToken():
            bf[t] = self.getDocumentFrequency(t)
        return bf

    def getDocumentFrequencyTot(self, t):
        st = self.voc.get(t)
        if not st:
            return 0.0
        else:
            return st.getTotalFreq()

    def BagFrequencyTot(self, b):
        bf = {}
        for t in b.listToken():
            bf[t] = self.getDocumentFrequencyTot(t)
        return bf

    def getDocumentStatistic(self, t):
        return self.voc.get(t)

    def getFrequencyDoc(self, t, d):
        st = self.voc.get(t)
        if not st:
            return 0.0
        else:
            return st.getFreqDoc(d)

    def BagFrequencyDoc(self, b, d):
        bf = {}
        for t in b.listToken():
            bf[t] = self.getFrequencyDoc(t, d)
        return bf

    def getListDoc(self, t):
        st = self.voc.get(t)
        if not st:
            return 0.0
        else:
            return st.listIdDocs()

    def size(self):
        if self.voc:
            return len(self.voc)
        else:
            return 0

    def getTotalTok(self):
        return self.totaltok

    def getTotalDoc(self):
        if self.documentos:
            return (self.documentos.size)
        else:
            return 0.0

    def getDocumentos(self):
        return self.documentos

    def getDoc(self, iddoc):
        if (iddoc < 0 and iddoc >= self.getTotalDoc()):
            return None
        else:
            if (not self.documentos.ready()):
                self.documentos.start()
            return self.documentos.getx(iddoc)

    # Calcula o peso dos bags como TF e IDF conforme os tokens do dataset
    # aparecem na colecao. TF e IDF sao usados no calculo de similaridade
    def calcTFIDF(self, iddoc):
        norm = 0.0
        bag = self.getDoc(iddoc)
        if (not bag):
            print "Erro!!!"
            return None
        if (bag.prep): return bag

        collectionSize = self.getTotalDoc()
        for t in bag.listToken():
            if (collectionSize > 0):
                df = self.getDocumentFrequency(t)
                if (df == 0):
                    df = 1.0
                w = math.log(bag.getWeight(t) + 1) * math.log(
                    collectionSize / df)
                bag.setWeight(t, w)
                norm += w * w
            else:
                bag.setWeight(t, 1.0)
                norm += 1.0
        # Normaliza
        norm = math.sqrt(norm)
        for t in bag.listToken():
            bag.setWeight(t, bag.getWeight(t) / norm)
        bag.prep = True
        return bag