Esempio n. 1
0
def get_erros_para_a_arvore(raiz, validacao, erros=dict(), novas_classes_majoritarias=dict()):
    """
    Recupera conjuntos de @erros e @novas_classes_majoritarias para os nós removidos.

    Usa a @raiz da árvore e o conjunto de @validacao para poda e @testes para testes.
    O conjunto de erros depois será utilizado para a remoção de fato dos nós.
    """

    subconjunto_validacao = validacao

    for filho in raiz.children:
        # Se for um nó de decisão
        if(is_no_de_decisao(filho)):
            # Extrai as regras que fazem chegar nele
            no = filho
            while(no.attribute != None):
                # Filtra o conjunto de validação
                subconjunto_validacao = subconjunto_validacao[(subconjunto_validacao[no.parent.name] == no.attribute)]

                no = no.parent

            # Recupera a classe majoritária do conjunto de validação
            classe_majoritaria_validacao = get_classe_majoritaria(
                conjunto=validacao
            )
            # Recupera-se o erro do conjunto
            resultado = poda(
                no=filho,
                validacao=subconjunto_validacao,
                classe_majoritaria=classe_majoritaria_validacao
            )
            erros[filho]=resultado[0]
            novas_classes_majoritarias[filho]=resultado[1]
            break
        
        # Se não é um nó de decisão desce na árvore
        else:
            get_erros_para_a_arvore(
                raiz=filho,
                validacao=validacao,
                erros=erros,
                novas_classes_majoritarias=novas_classes_majoritarias
            )
Esempio n. 2
0
def treina(arquivo_entrada, arvore_gerada):
    """
    Treina o conjunto de dados presente @arquivo_entrada.
    Salva o modelo na @arvore_gerada
    """
    conjunto = trata_conjunto(arquivo_entrada=arquivo_entrada,
                              char_a_remover='?',
                              numero_de_grupos=3)

    raiz = get_raiz_do_conjunto(conjunto=conjunto)
    classe_majoritaria = get_classe_majoritaria(conjunto=conjunto)
    monta_arvore(conjunto_completo=conjunto,
                 conjunto_atual=conjunto,
                 conjunto_teste=conjunto,
                 raiz=raiz,
                 nome_da_raiz=raiz.name,
                 classe_majoritaria=classe_majoritaria,
                 arquivo_saida_testes='',
                 arquivo_saida_treinamento='',
                 deve_testar_enquanto_monta=False)

    write_arvore_no_arquivo(arvore=raiz, arquivo=arvore_gerada)

    return raiz
Esempio n. 3
0
def poda(no, validacao, classe_majoritaria):
    """
    Efetua a remoção do @no e o teste com os conjuntos de @validacao.

    Usa a @classe_majoritaria do subconjunto de validação para definir a classe do novo nó folha
    Caso o conjunto esteja vazio usa a classe majoritária do nó pai.
    """

    # Se o conjunto estiver vaiz retorna-se o erro total da árvore para esse nó
    major = classe_majoritaria
    if(len(validacao) <= 0):
        return [get_erro(conjunto=validacao, arvore=get_raiz_da_arvore(no)), major]

    # Senão retorna o erro com o novo nó folha
    antiga_major = no.classe_major
    major = get_classe_majoritaria(validacao)
    no.classe_major = major
    
    # Realoca os filhos para um nó temporário
    no_temp = Node(name='')
    for filho in no.children:
        filho.parent = no_temp

    # Calcula o erro
    raiz = get_raiz_da_arvore(no)
    erro_pos_poda_validacao = get_erro(conjunto=validacao, arvore=raiz)
    
    # Realoca os filhos para o nó
    # O nó somente será removido de fato mais para frente
    for filho in no_temp.children:
        filho.parent = no
    
    no.classe_major = antiga_major

    # Retorna-se o erro pós-poda e a nova classe majoritária desse nó
    return [erro_pos_poda_validacao, major]
Esempio n. 4
0
def main(argv):
    # pylint: disable=W0612
    """
    Função de execução
    """

    inputfile = ''
    pastaarvore = ''
    pastaconjunto = ''
    filetreinamento = ''
    fileteste = ''

    try:
        opts, args = getopt.getopt(
            argv, 'hi:t:d:n:e:',
            ['ifile=', 'tpath=', 'dpath=', 'nfile=', 'efile='])

    except getopt.GetoptError:
        print(
            'usingGeraGrafico.py -i <inputfile> -t <treespath> -d <datasetspath> -n <trainfile> -e <testfile>'
        )
        sys.exit(2)

    for opt, arg in opts:
        if (opt == '-h'):
            print(
                'usingGeraGrafico.py -i <inputfile> -t <treespath> -d <datasetspath> -n <trainfile> -e <testfile>\n'
            )
            print(
                'Os parâmetros <inputfile>, <trainfile> e <testfile> DEVEM ser arquivos CSV. Os parâmetros <treespath> e <datasetspath> DEVEM terminar com /\n'
            )
            print('Exemplo: \n')
            print(
                'usingGeraGrafico.py -i \'./files/grafico/datasets/adult.csv\' -t \'./files/grafico/trees/\' -d \'./files/grafico/datasets/\' -n \'./files/grafico/output/treinamento_saida.csv\' -e \'./files/grafico/output/teste_saida.csv\''
            )
            sys.exit()

        elif (opt in ('-i', '--ifile')):
            inputfile = arg

        elif (opt in ('-t', '--tpath')):
            pastaarvore = arg

        elif (opt in ('-d', '--dpath')):
            pastaconjunto = arg

        elif (opt in ('-n', '--nfile')):
            filetreinamento = arg

        elif (opt in ('-e', '--efile')):
            fileteste = arg

    # Quebra o conjunto de TREINAMENTO, VALIDAÇÃO e TESTES
    # Escreve os três conjuntos em arquivos
    print('Início da divisão do conjunto: {0}'.format(datetime.now()))

    treinamento, validacao, teste = quebrar_conjunto(arquivo_entrada=inputfile)

    write_conjunto_no_arquivo(conjunto=treinamento,
                              arquivo=pastaconjunto + 'treinamento.csv')

    write_conjunto_no_arquivo(conjunto=validacao,
                              arquivo=pastaconjunto + 'validacao.csv')

    write_conjunto_no_arquivo(conjunto=teste,
                              arquivo=pastaconjunto + 'teste.csv')

    print('Fim da divisão do conjunto: {0}'.format(datetime.now()))

    # Gera a árvore de treinamento
    # Vai gerando CSV com desempenho dos conjuntos de treinamento e testes diante do modelo
    # Salva a árvore em um JSON
    print('Início da montagem da árvore: {0}'.format(datetime.now()))

    raiz = get_raiz_do_conjunto(conjunto=treinamento)
    major_class = get_classe_majoritaria(conjunto=treinamento)

    monta_arvore(conjunto_completo=treinamento,
                 conjunto_atual=treinamento,
                 conjunto_teste=teste,
                 raiz=raiz,
                 nome_da_raiz=raiz.name,
                 classe_majoritaria=major_class,
                 arquivo_saida_treinamento=filetreinamento,
                 arquivo_saida_testes=fileteste,
                 deve_testar_enquanto_monta=True)

    raiz = get_raiz_da_arvore(raiz)
    write_arvore_no_arquivo(arvore=raiz,
                            arquivo=pastaarvore + 'arvore_gerada.json')

    print('Fim da montagem da árvore: {0}'.format(datetime.now()))
Esempio n. 5
0
def main(argv):
    # pylint: disable=W0612
    """
    Função de execução
    """
    inputfile = ''
    outputfile = ''

    try:
        opts, args = getopt.getopt(argv, 'hi:o:', ['ifile=', 'ofile='])

    except getopt.GetoptError:
        print('usingImprimeRegras.py -i <inputfile> -o <outputfile>')
        sys.exit(2)

    for opt, arg in opts:
        if (opt == '-h'):
            print('usingImprimeRegras.py -i <inputfile> -o <outputfile>')
            print(
                'O parâmetro <inputfile> DEVE ser um arquivo CSV. O parâmetro <outputfile> DEVE ser um arquivo TXT.\n'
            )
            print('Exemplo: \n')
            print(
                'usingImprimeRegras.py -i \'./imprime-regras/conjuntos/adult.csv\' -o \'./imprime-regras/saidas/regras.txt\''
            )
            sys.exit()

        elif (opt in ('-i', '--ifile')):
            inputfile = arg

        elif (opt in ('-o', '--ofile')):
            outputfile = arg

    # Quebra o conjunto em TREINAMENTO, VALIDAÇÃO e TESTES
    print('Início da divisão do conjunto: {0}'.format(datetime.now()))

    treinamento, validacao, teste = quebrar_conjunto(arquivo_entrada=inputfile)

    print('Fim da divisão do conjunto: {0}'.format(datetime.now()))

    # Monta a árvore
    print('Início da montagem da árvore: {0}'.format(datetime.now()))

    raiz = get_raiz_do_conjunto(conjunto=treinamento)
    major_class = get_classe_majoritaria(conjunto=treinamento)

    monta_arvore(conjunto_completo=treinamento,
                 conjunto_atual=treinamento,
                 conjunto_teste=teste,
                 raiz=raiz,
                 nome_da_raiz=raiz.name,
                 classe_majoritaria=major_class,
                 arquivo_saida_treinamento='',
                 arquivo_saida_testes='',
                 deve_testar_enquanto_monta=False)

    print('Fim da montagem da árvore: {0}'.format(datetime.now()))

    # Imprime as regras
    print('Início da impressão das regras: {0}'.format(datetime.now()))

    raiz = get_raiz_da_arvore(no=raiz)

    dicionario = dict()
    get_dicionario_de_regras(raiz, dicionario, validacao)

    s = processa_impressao(dicionario)
    write_regras(outputfile, s)

    print('Fim da impressão das regras: {0}'.format(datetime.now()))
Esempio n. 6
0
def main(argv):
    # pylint: disable=W0612
    """
    Função de execução
    """

    inputfile = ''
    pastaarvore = ''
    pastaconjunto = ''
    filevalidacao = ''
    fileteste = ''
    outputfile = ''

    try:
        opts, args = getopt.getopt(argv, 'hi:t:d:v:e:o:', ['ifile=', 'tpath=', 'dpath=', 'vfile=', 'efile=', 'ofile='])

    except getopt.GetoptError:
        print('usingPoda.py -i <inputfile> -t <treespath> -d <datasetspath> -v <validationfile> -e <testfile> -o <rulesfile>')
        sys.exit(2)

    for opt, arg in opts:
        if(opt == '-h'):
            print('usingPoda.py -i <inputfile> -t <treespath> -d <datasetspath> -v <validationfile> -e <testfile> -o <rulesfile>\n')
            print('Os parâmetros <inputfile>, <validationfile> e <testfile> DEVEM ser arquivos CSV, já o parâmetro <rulesfile> DEVE ser um TXT. Os parâmetros <treespath> e <datasetspath> DEVEM terminar com /\n')
            print('Exemplo: \n')
            print('usingPoda.py -i \'./poda/conjuntos/adult.csv\' -t \'./poda/arvores/\' -d \'./poda/conjuntos/\' -v \'./poda/saidas/validacao_saida.csv\' -e \'./poda/saidas/teste_saida.csv\' -o \'./poda/saidas/regras_pos_poda.txt\'')
            sys.exit()
        
        elif(opt in ('-i', '--ifile')):
            inputfile = arg
        
        elif(opt in ('-t', '--tpath')):
            pastaarvore = arg

        elif(opt in ('-d', '--dpath')):
            pastaconjunto = arg

        elif(opt in ('-v', '--vfile')):
            filevalidacao = arg
        
        elif(opt in ('-e', '--efile')):
            fileteste = arg

        elif(opt in ('-o', '--ofile')):
            outputfile = arg
        
    
    # Quebra o conjunto em TREINAMENTO, VALIDAÇÃO e TESTES
    # Salva em arquivos na pasta designada
    print('Início da divisão do conjunto: {0}'.format(datetime.now()))

    treinamento, validacao, teste = quebrar_conjunto(
        arquivo_entrada=inputfile
    )

    write_conjunto_no_arquivo(
        conjunto=treinamento,
        arquivo=pastaconjunto+'treinamento.csv'
    )

    write_conjunto_no_arquivo(
        conjunto=validacao,
        arquivo=pastaconjunto+'validacao.csv'
    )

    write_conjunto_no_arquivo(
        conjunto=teste,
        arquivo=pastaconjunto+'teste.csv'
    )

    print('Fim da divisão do conjunto: {0}'.format(datetime.now()))


    # Monta a árvore
    print('Início da montagem da árvore: {0}'.format(datetime.now()))

    raiz = get_raiz_do_conjunto(
        conjunto=treinamento
    )
    major_class = get_classe_majoritaria(
        conjunto=treinamento
    )
    
    monta_arvore(
        conjunto_completo=treinamento,
        conjunto_atual=treinamento,
        conjunto_teste=teste,
        raiz=raiz,
        nome_da_raiz=raiz.name,
        classe_majoritaria=major_class,
        arquivo_saida_treinamento='',
        arquivo_saida_testes='',
        deve_testar_enquanto_monta=False
    )

    raiz = get_raiz_da_arvore(no=raiz)
    write_arvore_no_arquivo(
        arvore=raiz,
        arquivo=pastaarvore+'arvore_prepoda.json'
    )

    print('Fim da montagem da árvore: {0}'.format(datetime.now()))


    # Podando
    print('Início da poda: {0}'.format(datetime.now()))

    raiz = efetua_poda(
        raiz=raiz,
        validacao=validacao,
        testes=teste,
        deve_escrever_arquivo=True,
        saida_validacao=filevalidacao,
        saida_teste=fileteste
    )

    write_arvore_no_arquivo(
        arvore=raiz,
        arquivo=pastaarvore+'arvore_pospoda.json'
    )

    print('Fim da poda: {0}'.format(datetime.now()))


    print('Início da formulação das regras: {0}'.format(datetime.now()))

    raiz = get_raiz_da_arvore(no=raiz)
    
    dicionario = dict()
    get_dicionario_de_regras(raiz, dicionario, validacao)

    s = processa_impressao(dicionario)
    write_regras(outputfile, s)

    print('Fim da formulação das regras: {0}'.format(datetime.now()))
Esempio n. 7
0
def cross_validation(arquivo_entrada,
                     numero_de_folds=10,
                     deve_gerar_arquivos=True,
                     pasta_conjuntos='',
                     pasta_arvores=''):
    """
    Executa o @numero_de_folds-Fold Cross-Validation para o conjunto presente no @arquivo_entrada

    Usa o parâmetro @deve_gerar_arquivos para decidir se teremos output, gerando os conjuntos na @pasta_conjuntos e as árvores na @pasta_arvores
    """

    erro_medio = 0

    # Faz a leitura do arquivo de entrada
    # Remove os missing values
    # Discretiza
    conjunto = trata_conjunto(arquivo_entrada=arquivo_entrada,
                              char_a_remover='?',
                              numero_de_grupos=3)

    # Mistura os dados
    conjunto = shuffle(conjunto)

    # Cria N partições e calcula o tamanho do fold
    lista_de_conjuntos = [numero_de_folds]
    tamanho_do_fold = len(conjunto) / numero_de_folds

    # Quebra o conjunto completo em N partições
    i = 0
    while (i < numero_de_folds):
        inicio = int((i * tamanho_do_fold))
        fim = int(((tamanho_do_fold * (i + 1)) - 1))

        lista_de_conjuntos.insert(i, conjunto.iloc[inicio:fim])

        i = i + 1

    # Executa N vezes, usando N-1 partições para treinamento e 1 partição para testes
    # Cada execução uma partição distinta será usada para testes
    x = 0
    erro = 0
    while (x < numero_de_folds):
        conjunto_treinamento = conjunto[0:0]
        conjunto_teste = conjunto[0:0]
        y = 0

        while (y < numero_de_folds):
            if (x == y):
                conjunto_teste = conjunto_teste.append(lista_de_conjuntos[x],
                                                       ignore_index=True)
            else:
                conjunto_treinamento = conjunto_treinamento.append(
                    lista_de_conjuntos[x], ignore_index=True)

            y = y + 1

        # Seleciona a raiz da árvore
        raiz = get_raiz_do_conjunto(conjunto=conjunto)
        # Recupera a classe majoritária
        major_class = get_classe_majoritaria(conjunto=conjunto_treinamento)

        print('Montando a {0}a árvore'.format(x + 1))

        # Monta a árvore
        monta_arvore(conjunto_completo=conjunto_treinamento,
                     conjunto_atual=conjunto_treinamento,
                     conjunto_teste=conjunto_teste,
                     raiz=raiz,
                     nome_da_raiz=raiz.name,
                     classe_majoritaria=major_class,
                     arquivo_saida_treinamento='',
                     arquivo_saida_testes='',
                     deve_testar_enquanto_monta=False)

        # Recupera o erro dessa interação
        erro_deste_teste = get_erro(conjunto=conjunto_teste, arvore=raiz)
        erro = erro + erro_deste_teste

        print('Erro na {0}a interação: {1}'.format(x + 1, erro_deste_teste))

        x = x + 1

        if (deve_gerar_arquivos):
            # Escreve a árvore gerada nessa interação
            write_arvore_no_arquivo(arvore=raiz,
                                    arquivo=pasta_arvores +
                                    'modelo_{0}.json'.format(x))

            # Escreve o conjunto de teste gerado nessa interação
            write_conjunto_no_arquivo(conjunto=conjunto_teste,
                                      arquivo=pasta_conjuntos +
                                      'teste_{0}.csv'.format(x))

            # Escreve o conjunto de treinamento gerado nessa interação
            write_conjunto_no_arquivo(conjunto=conjunto_treinamento,
                                      arquivo=pasta_conjuntos +
                                      'treinamento_{0}.csv'.format(x))

    # Calcula o erro médio e o erro verdadeiro
    erro_medio = erro / numero_de_folds
    print('Erro médio: {0}'.format(erro_medio))

    se = math.sqrt((erro_medio * (1 - erro_medio)) / len(conjunto))
    erro_verd_min = erro_medio - 1.96 * se
    erro_verd_max = erro_medio + 1.96 * se

    print(
        'Com intervalo de confiança de 95% temos que o erro verdadeiro estará entre {0} por cento e {1} por cento'
        .format((erro_verd_min * 100), (erro_verd_max * 100)))

    return erro_medio