aprendizadodemaquina.Featurizador.java Source code

Java tutorial

Introduction

Here is the source code for aprendizadodemaquina.Featurizador.java

Source

/*
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 *   Copyright (C) 2012-2013 LaLiC
 */

package aprendizadodemaquina;

import anotadorderelacoes.model.Relacao;
import anotadorderelacoes.model.Sentenca;
import anotadorderelacoes.model.Termo;
import aprendizadodemaquina.features.morfologicas.*;
import aprendizadodemaquina.features.sintaticas.*;
import aprendizadodemaquina.features.superficiais.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;

/**
 * Classe que realiza a featurizao das instncias de relaoes para uso no
 * treinamento e predio dos classificadores. Engloba as classes Feature dentro
 * da lista features.
 */
public class Featurizador implements Serializable {

    private List<Feature> features; // quais features sero utilizadas na featurizao
    private List<String> tiposRelacoes; // as classes de relaoes possiveis
    private boolean usarFeatureIdentificacao;
    private boolean usarFeaturesSuperficiais;
    private boolean usarFeaturesMorfologicas;
    private boolean usarFeaturesSintaticas;

    public Featurizador() {
        inicializacao();
    }

    public Featurizador(boolean featureId, boolean featuresSuperficiais, boolean featuresMorfologicas,
            boolean featuresSintaticas) {
        this.usarFeatureIdentificacao = featureId;
        this.usarFeaturesSuperficiais = featuresSuperficiais;
        this.usarFeaturesMorfologicas = featuresMorfologicas;
        this.usarFeaturesSintaticas = featuresSintaticas;
        inicializacao();
    }

    private void inicializacao() {
        features = new ArrayList<Feature>();

        // "Feature" de identificao da sentena
        if (usarFeatureIdentificacao)
            features.add(new FeatureIdentificacao());

        // Superficiais
        if (usarFeaturesSuperficiais) {
            features.add(new FeatureDistanciaTermos());
            features.add(new FeatureTamanhoTermos());
            features.add(new FeatureOrdemTermos());
            features.add(new FeatureVirgulasEntreTermos());
            features.add(new FeaturePalavrasCapitalizadasEntre());
            features.add(new FeaturePadroesTextuais()); // aparentemente funcionando OK//
            features.add(new FeatureTokensTermosCapitalizados());
            features.add(new FeatureParentesesRedorTermos());
            features.add(new FeatureAspasRedorTermos());//
            features.add(new FeatureVirgulasRedorTermos());
            features.add(new FeatureTermosContemNumeros());//
            features.add(new FeatureTermosComecamComDe());
            features.add(new FeatureNumeroTermosEntreTermos());
            features.add(new FeatureTamanhoCaracteresTermos());
            features.add(new FeatureTermosCapitalizados());
        }

        // Morfolgicas
        if (usarFeaturesMorfologicas) {
            features.add(new FeaturePOSTermos()); // aparentemente funcionando OK
            //        features.add( new FeaturePOSTermos2() );
            features.add(new FeaturePOSRedor()); // aparentemente funcionando OK 
            //        features.add( new FeaturePOSRedor2() );
            features.add(new FeatureVerboSerEntre());
            features.add(new FeaturePreposicaoEntre());
            features.add(new FeatureArtigoAntesTermo());
        }

        // Sintticas
        if (usarFeaturesSintaticas) {
            features.add(new FeatureClasseSintaticaTermos());
            features.add(new FeatureClasseSintaticaTokensRedor());
        }

        // Semnticas
        //if ( usarFeaturesSemanticas ) {
        //features.add( new FeatureNomePais() );
        //features.add( new FeatureNomePais2() );
        //features.add( new FeatureNomeEstado() );
        //features.add( new FeatureSiglaEstado() );
        //features.add( new FeatureNomeCidade() );
        //}

        tiposRelacoes = new ArrayList<String>();
        tiposRelacoes.add("is-a");
        tiposRelacoes.add("property-of");
        tiposRelacoes.add("part-of");
        tiposRelacoes.add("made-of");
        tiposRelacoes.add("effect-of");
        tiposRelacoes.add("used-for");
        tiposRelacoes.add("location-of");
        tiposRelacoes.add("none");
    }

    /**
     * Converte uma instncia de relao semntica em uma lista de objetos
     * Double, utilizada nos classificadores libSVM e SVMLight
     * 
     * @param s Sentena que contem a instncia de relao
     * @param r A instncia de relao em si (null se no for treinamento)
     * @param t1 Primeiro termo da relao
     * @param t2 Segundo termo da relao
     * @param tipo Pode ser "predicao", "treinamento" ou "negativa"
     * 
     * @return Lista de objetos Double que representa a instncia de relao
     *         semntica passada como parametro.
     */
    public List<Double> paraSvm(Sentenca s, Relacao r, Termo t1, Termo t2, String tipo) {

        List<Double> valores = new ArrayList<Double>();

        // Nas instncias SVMLight a classe alvo  o primeiro atributo
        if (tipo.equals("predicao"))
            valores.add(0.0);
        else if (tipo.equals("treinamento"))
            valores.add((double) tiposRelacoes.indexOf(r.getRelacao()) + 1.0);
        else if (tipo.equals("negativa"))
            valores.add((double) tiposRelacoes.indexOf("none") + 1.0);

        for (Feature f : features) {

            List<Object> gerados = f.gerar(s, t1, t2);

            if (f.tipo().equals("NUMERICO"))
                for (Object o : gerados)
                    valores.add(Double.parseDouble(o.toString()));
            else if (f.tipo().equals("NOMINAL")) {
                // Quando  um atributo nominal, recomenda-se que sejam criadas
                // N features binrias, uma para cada valor possvel

                // Se j  uma feature binaria, mantemos os valores
                if (f.valoresPossivis().length == 2) {
                    for (Object o : gerados)
                        if ((o.toString()).equals("1"))
                            valores.add(1.0);
                        else if ((o.toString()).equals("0"))
                            valores.add(0.0);
                }
                // Se no , fazemos a separao da feature em N features binrias
                else {
                    for (Object o : gerados)
                        for (String valorPossivel : f.valoresPossivis())
                            if ((o.toString()).equals(valorPossivel))
                                valores.add(1.0);
                            else
                                valores.add(0.0);
                }
            }

        }

        return valores;

    }

    /**
     * Converte uma instncia de relao semantica em um objeto Instance que e
     * utilizado pelo Weka.
     * <p>
     * O parmetro tipo pode ser "predicao", "treinamento" ou "negativa",
     * dependendo do tipo de instncia que est sendo gerada. Se for do tipo
     * "treinamento", o parmetro r deve ser diferente de null. 
     * 
     * @param s Sentena que contem a instncia de relao
     * @param r A instncia de relao em si (null se no for treinamento)
     * @param t1 Primeiro termo da relao
     * @param t2 Segundo termo da relao
     * @param tipo Pode ser "predicao", "treinamento" ou "negativa"
     * 
     * @return Objeto Instance que representa a instncia de relao semantica
     *         passada como parametro.
     */
    public Instance paraInstancia(Sentenca s, Relacao r, Termo t1, Termo t2, String tipo) {

        List<Double> valores = new ArrayList<Double>();

        for (Feature f : features) {

            List<Object> gerados = f.gerar(s, t1, t2);

            if (f.tipo().equals("NUMERICO"))
                for (Object o : gerados)
                    valores.add(Double.parseDouble(o.toString()));
            else if (f.tipo().equals("NOMINAL")) {
                FastVector valoresPossiveis = new FastVector();
                for (String valor : f.valoresPossivis())
                    valoresPossiveis.addElement(valor);
                for (Object o : gerados)
                    valores.add((double) valoresPossiveis.indexOf(o.toString()));
            }

        }

        double[] valoresDouble = new double[numeroAtributos()];
        for (int i = 0; i < valores.size(); ++i)
            valoresDouble[i] = valores.get(i);

        // Apenas o ltimo atributo muda de acordo com o tipo de instncia

        // Se for do tipo "predicao", o ltimo atributo  um missingValue
        if (tipo.equals("predicao"))
            valoresDouble[valores.size()] = Instance.missingValue();
        // Se for do tipo "treinamento", a relao  fornecida
        else if (tipo.equals("treinamento"))
            valoresDouble[valores.size()] = tiposRelacoes.indexOf(r.getRelacao());
        // Se for "negativa", a relao  negativa
        else if (tipo.equals("negativa"))
            valoresDouble[valores.size()] = tiposRelacoes.indexOf("none");

        // 
        Instance instance = new Instance(1.0, valoresDouble);

        //System.out.println("DEBUG: Instncia " + tipo + " = " + instance);

        return instance;

    }

    /**
     * Gera o objeto Instances - cabealho dos dados a serem utilizados pelo
     * classificador, guarda os atributos das instncias e seus tipos
     * 
     * @return Objeto Instances que  armazenado na classe Classificador
     */
    public Instances geraInstances() {

        FastVector atributos = new FastVector();

        for (Feature f : features)
            if (f.tipo().equals("NUMERICO")) {
                if (f.quantosValores() == 1)
                    atributos.addElement(new Attribute(f.nome()));
                else
                    for (int i = 0; i < f.quantosValores(); ++i)
                        atributos.addElement(new Attribute(f.nome() + (i + 1)));
            } else if (f.tipo().equals("NOMINAL")) {
                FastVector valoresPossiveis = new FastVector();
                for (String valor : f.valoresPossivis())
                    valoresPossiveis.addElement(valor);
                if (f.quantosValores() == 1)
                    atributos.addElement(new Attribute(f.nome(), valoresPossiveis));
                else
                    for (int i = 0; i < f.quantosValores(); ++i)
                        atributos.addElement(new Attribute(f.nome() + (i + 1), valoresPossiveis));
            }

        // Qual relao 
        FastVector valoresPossiveis = new FastVector();
        for (String s : tiposRelacoes)
            valoresPossiveis.addElement(s);
        atributos.addElement(new Attribute("relacao", valoresPossiveis));

        return (new Instances("dados_de_treinamento", atributos, 0));

    }

    /**
     * Retorna o numero de atributos gerados pelo featurizador
     * 
     * @return Nmero de atributos gerados
     */
    public int numeroAtributos() {
        int numero = 0;
        for (Feature f : features)
            numero += f.quantosValores();
        numero++; // Qual relao 
        return numero;
    }

}