Beispiel #1
0
  /**
   * Process a dataset file for a clustering problem.
   *
   * @param nfexamples Name of the dataset file
   * @param train The dataset file is for training or for test
   * @throws java.io.IOException if there is any semantical, lexical or sintactical error in the
   *     input file.
   */
  public void processClusterDataset(String nfexamples, boolean train) throws IOException {

    try {

      // Load in memory a dataset that contains a classification problem
      IS.readSet(nfexamples, train);

      nData = IS.getNumInstances();
      nInputs = Attributes.getInputNumAttributes();
      nVariables = nInputs + Attributes.getOutputNumAttributes();

      if (Attributes.getOutputNumAttributes() != 0) {
        System.out.println("This algorithm can not process datasets with outputs");
        System.out.println("All outputs will be removed");
      }

      // Initialize and fill our own tables
      X = new double[nData][nInputs];
      missing = new boolean[nData][nInputs];

      // Maximum and minimum of inputs
      iMaximum = new double[nInputs];
      iMinimum = new double[nInputs];

      // Maximum and minimum for output data
      oMaximum = 0;
      oMinimum = 0;

      // All values are casted into double/integer
      nClasses = 0;
      for (int i = 0; i < X.length; i++) {
        Instance inst = IS.getInstance(i);
        for (int j = 0; j < nInputs; j++) {
          X[i][j] = IS.getInputNumericValue(i, j);
          missing[i][j] = inst.getInputMissingValues(j);
          if (X[i][j] > iMaximum[j] || i == 0) {
            iMaximum[j] = X[i][j];
          }
          if (X[i][j] < iMinimum[j] || i == 0) {
            iMinimum[j] = X[i][j];
          }
        }
      }

    } catch (Exception e) {
      System.out.println("DBG: Exception in readSet");
      e.printStackTrace();
    }
  }
Beispiel #2
0
  /**
   * Returns the fraction of correct instances of the instance's set for the rule 'regla'
   *
   * @param i Number of the rule
   * @return Fraction of correct instances of the instance's set for the rule 'regla'
   */
  private double getAccuracy(int i) {

    Instance instancia;
    double Accuracy;
    num_cubiertas = 0;
    num_correctas = 0;
    for (int k = 0; k < instancias.getNumInstances(); k++) {
      instancia = instancias.getInstance(k);
      cubierta = regla.reglaCubreInstancia(instancia);
      if (cubierta) {
        num_cubiertas++;
        clase = instancia.getOutputNominalValuesInt(0);
        if (clase == i) num_correctas++;
      }
    }
    Accuracy = (double) num_correctas / (double) num_cubiertas;
    if (num_cubiertas == 0) Accuracy = 0;
    return Accuracy;
  }
Beispiel #3
0
  /**
   * Removes from the instance's set those instances that matches with the rule
   *
   * @param i Numebr of the rule
   */
  private void removeInstancesCovered(int i) {

    for (int k = 0; k < instancias.getNumInstances(); k++) {

      instancia = instancias.getInstance(k);
      /*System.out.print(k+" ");
         instancia.print();
      System.out.println();*/
      cubierta = regla.reglaCubreInstancia(instancia);
      if (cubierta) {
        //  System.out.println("CUBIERTA");
        clase = instancia.getOutputNominalValuesInt(0);
        // if(clase==i){
        instancias.removeInstance(k);
        instancia.print();
        System.out.println();
        k = k - 1;
        // }
      }
    }
  }
Beispiel #4
0
  public LVQ(String ficheroScript) {
    super(ficheroScript);
    try {
      referencia = new InstanceSet();
      referencia.readSet(ficheroReferencia, false);

      /*Normalize the data*/
      normalizarReferencia();
    } catch (Exception e) {
      System.err.println(e);
      System.exit(1);
    }
  }
Beispiel #5
0
  private void normalizarReferencia() throws CheckException {

    int i, j, cont = 0, k;
    Instance temp;
    boolean hecho;
    double caja[];
    StringTokenizer tokens;
    boolean nulls[];

    /*Check if dataset corresponding with a classification problem*/

    if (Attributes.getOutputNumAttributes() < 1) {
      throw new CheckException(
          "This dataset haven´t outputs, so it not corresponding to a classification problem.");
    } else if (Attributes.getOutputNumAttributes() > 1) {
      throw new CheckException("This dataset have more of one output.");
    }

    if (Attributes.getOutputAttribute(0).getType() == Attribute.REAL) {
      throw new CheckException(
          "This dataset have an input attribute with floating values, so it not corresponding to a classification problem.");
    }

    datosReferencia = new double[referencia.getNumInstances()][Attributes.getInputNumAttributes()];
    clasesReferencia = new int[referencia.getNumInstances()];
    caja = new double[1];

    /*Get the number of instances that have a null value*/
    for (i = 0; i < referencia.getNumInstances(); i++) {
      temp = referencia.getInstance(i);
      nulls = temp.getInputMissingValues();
      datosReferencia[i] = referencia.getInstance(i).getAllInputValues();
      for (j = 0; j < nulls.length; j++) if (nulls[j]) datosReferencia[i][j] = 0.0;
      caja = referencia.getInstance(i).getAllOutputValues();
      clasesReferencia[i] = (int) caja[0];
      for (k = 0; k < datosReferencia[i].length; k++) {
        if (Attributes.getInputAttribute(k).getType() == Attribute.NOMINAL) {
          datosReferencia[i][k] /=
              Attributes.getInputAttribute(k).getNominalValuesList().size() - 1;
        } else {
          datosReferencia[i][k] -= Attributes.getInputAttribute(k).getMinAttribute();
          datosReferencia[i][k] /=
              Attributes.getInputAttribute(k).getMaxAttribute()
                  - Attributes.getInputAttribute(k).getMinAttribute();
        }
      }
    }
  }
Beispiel #6
0
  // Write data matrix X to disk, in KEEL format
  private void write_results(String output) {
    // File OutputFile = new File(output_train_name.substring(1, output_train_name.length()-1));
    try {
      FileWriter file_write = new FileWriter(output);

      file_write.write(IS.getHeader());

      // now, print the normalized data
      file_write.write("@data\n");
      for (int i = 0; i < ndatos; i++) {
        file_write.write(X[i][0]);
        for (int j = 1; j < nvariables; j++) {
          file_write.write("," + X[i][j]);
        }
        file_write.write("\n");
      }
      file_write.close();
    } catch (IOException e) {
      System.out.println("IO exception = " + e);
      System.exit(-1);
    }
  }
Beispiel #7
0
  public void ejecutar() {

    int i, j, l, m;
    double alfai;
    int nClases;

    int claseObt;

    boolean marcas[];
    boolean notFound;

    int init;
    int clasSel[];

    int baraje[];

    int pos, tmp;
    String instanciasIN[];
    String instanciasOUT[];

    long tiempo = System.currentTimeMillis();

    /* Getting the number of differents classes */

    nClases = 0;

    for (i = 0; i < clasesTrain.length; i++) if (clasesTrain[i] > nClases) nClases = clasesTrain[i];

    nClases++;

    /* Shuffle the train set */

    baraje = new int[datosTrain.length];

    Randomize.setSeed(semilla);

    for (i = 0; i < datosTrain.length; i++) baraje[i] = i;

    for (i = 0; i < datosTrain.length; i++) {

      pos = Randomize.Randint(i, datosTrain.length - 1);

      tmp = baraje[i];

      baraje[i] = baraje[pos];

      baraje[pos] = tmp;
    }

    /*
     * Inicialization of the flagged instaces vector for a posterior
     * elimination
     */

    marcas = new boolean[datosTrain.length];

    for (i = 0; i < datosTrain.length; i++) marcas[i] = false;

    if (datosTrain.length > 0) {

      // marcas[baraje[0]] = true; //the first instance is included always

      nSel = n_p;
      if (nSel < nClases) nSel = nClases;

    } else {

      System.err.println("Input dataset is empty");

      nSel = 0;
    }
    clasSel = new int[nClases];
    System.out.print("Selecting initial neurons... ");
    // at least, there must be 1 neuron of each class at the beginning
    init = nClases;
    for (i = 0; i < nClases && i < datosTrain.length; i++) {
      pos = Randomize.Randint(0, datosTrain.length - 1);
      tmp = 0;
      while ((clasesTrain[pos] != i || marcas[pos]) && tmp < datosTrain.length) {
        pos = (pos + 1) % datosTrain.length;
        tmp++;
      }
      if (tmp < datosTrain.length) marcas[pos] = true;
      else init--;
      // clasSel[i] = i;
    }
    for (i = init; i < Math.min(nSel, datosTrain.length); i++) {
      tmp = 0;
      pos = Randomize.Randint(0, datosTrain.length - 1);
      while (marcas[pos]) {
        pos = (pos + 1) % datosTrain.length;
        tmp++;
      }
      // if(i<nClases){
      // notFound = true;
      // do{
      // for(j=i-1;j>=0 && notFound;j--){
      // if(clasSel[j] == clasesTrain[pos])
      // notFound = false;
      // }
      // if(!notFound)
      // pos = Randomize.Randint (0, datosTrain.length-1);
      // }while(!notFound);
      // }
      // clasSel[i] = clasesTrain[pos];
      marcas[pos] = true;
      init++;
    }
    nSel = init;
    System.out.println("Initial neurons selected: " + nSel);

    /* Building of the S set from the flags */

    conjS = new double[nSel][datosTrain[0].length];

    clasesS = new int[nSel];

    for (m = 0, l = 0; m < datosTrain.length; m++) {

      if (marcas[m]) { // the instance must be copied to the solution

        for (j = 0; j < datosTrain[0].length; j++) {

          conjS[l][j] = datosTrain[m][j];
        }

        clasesS[l] = clasesTrain[m];

        l++;
      }
    }

    alfai = alpha;
    boolean change = true;
    /* Body of the LVQ algorithm. */

    // Train the network
    for (int it = 0; it < T && change; it++) {
      change = false;
      alpha = alfai;
      for (i = 1; i < datosTrain.length; i++) {
        // search for the nearest neuron to training instance
        pos = NN(nSel, conjS, datosTrain[baraje[i]]);
        // nearest neuron labels correctly the class of training
        // instance?

        if (clasesS[pos] != clasesTrain[baraje[i]]) { // NO - repel
          // the neuron
          for (j = 0; j < conjS[pos].length; j++) {
            conjS[pos][j] = conjS[pos][j] - alpha * (datosTrain[baraje[i]][j] - conjS[pos][j]);
          }
          change = true;
        } else { // YES - migrate the neuron towards the input vector
          for (j = 0; j < conjS[pos].length; j++) {
            conjS[pos][j] = conjS[pos][j] + alpha * (datosTrain[baraje[i]][j] - conjS[pos][j]);
          }
        }
        alpha = nu * alpha;
      }
      // Shuffle again the training partition
      baraje = new int[datosTrain.length];

      for (i = 0; i < datosTrain.length; i++) baraje[i] = i;

      for (i = 0; i < datosTrain.length; i++) {

        pos = Randomize.Randint(i, datosTrain.length - 1);

        tmp = baraje[i];

        baraje[i] = baraje[pos];

        baraje[pos] = tmp;
      }
    }
    System.out.println(
        "LVQ " + relation + " " + (double) (System.currentTimeMillis() - tiempo) / 1000.0 + "s");
    // Classify the train data set
    instanciasIN = new String[datosReferencia.length];
    instanciasOUT = new String[datosReferencia.length];
    for (i = 0; i < datosReferencia.length; i++) {
      /* Classify the instance selected in this iteration */
      Attribute a = Attributes.getOutputAttribute(0);

      int tipo = a.getType();
      claseObt = KNN.evaluacionKNN2(1, conjS, clasesS, datosReferencia[i], nClases);
      if (tipo != Attribute.NOMINAL) {
        instanciasIN[i] = new String(String.valueOf(clasesReferencia[i]));
        instanciasOUT[i] = new String(String.valueOf(claseObt));
      } else {
        instanciasIN[i] = new String(a.getNominalValue(clasesReferencia[i]));
        instanciasOUT[i] = new String(a.getNominalValue(claseObt));
      }
    }

    escribeSalida(
        ficheroSalida[0], instanciasIN, instanciasOUT, entradas, salida, nEntradas, relation);

    // Classify the test data set
    normalizarTest();
    instanciasIN = new String[datosTest.length];
    instanciasOUT = new String[datosTest.length];
    for (i = 0; i < datosTest.length; i++) {
      /* Classify the instance selected in this iteration */
      Attribute a = Attributes.getOutputAttribute(0);

      int tipo = a.getType();

      claseObt = KNN.evaluacionKNN2(1, conjS, clasesS, datosTest[i], nClases);
      if (tipo != Attribute.NOMINAL) {
        instanciasIN[i] = new String(String.valueOf(clasesTest[i]));
        instanciasOUT[i] = new String(String.valueOf(claseObt));
      } else {
        instanciasIN[i] = new String(a.getNominalValue(clasesTest[i]));
        instanciasOUT[i] = new String(a.getNominalValue(claseObt));
      }
    }

    escribeSalida(
        ficheroSalida[1], instanciasIN, instanciasOUT, entradas, salida, nEntradas, relation);

    // Print the network to a file
    printNetworkToFile(ficheroSalida[2], referencia.getHeader());
  }
Beispiel #8
0
  /**
   * Constructor with all the attributes to initialize
   *
   * @param ficheroTrain Train file
   * @param ficheroTest Test file
   * @param fSalidaTr Out-put train file
   * @param fSalidaTst Out-put test file
   * @param fsalida Out-put file
   * @param semilla seed
   */
  public Prism(
      String ficheroTrain,
      String ficheroTest,
      String fSalidaTr,
      String fSalidaTst,
      String fsalida,
      long semilla) {

    ficheroSalida = fsalida;
    ficheroSalidaTr = fSalidaTr;
    ficheroSalidaTst = fSalidaTst;
    seed = semilla;

    datosTrain = new ConjDatos(); // datosEval = new ConjDatos();
    datosTest = new ConjDatos();

    train = new Dataset();
    test = new Dataset();
    s = new Selector(0, 0, 0.);
    conjunto_reglas = new ConjReglas();

    try {
      Randomize.setSeed(seed);
      System.out.println("la semilla es " + seed);
      train.leeConjunto(ficheroTrain, true);
      test.leeConjunto(ficheroTest, false); //
      if (train.hayAtributosContinuos() /*|| train.hayAtributosDiscretos()*/) {
        System.err.println("\nPrism may not work properly with real or integer attributes.\n");
        // System.exit(-1);
        hayContinuos = true;
      }
      if (!hayContinuos) {
        train.calculaMasComunes(); // eval.calculaMasComunes();
        test.calculaMasComunes();
        datosTrain =
            creaConjunto(
                train); // Leemos los datos de entrenamiento (todos seguidos como un
                        // String)//datosEval = creaConjunto(eval);
        datosTest = creaConjunto(test);

        valores = train.getX2(); // obtengo los valores nominales
        clases = train.getC2();
        clasitas = train.getC();
        /*System.out.println(train.getndatos());
        System.out.println(train.getnentradas());
        for(int i=0;i<train.getndatos();i++){
        	for(int j=0;j<train.getnentradas();j++)
        		System.out.print(valores[i][j]);
        	System.out.print(clases[i]);System.out.println(clasitas[i]);}*/
        // COMENZAMOS EL ALGORITMO PRISM
        // FOR EACH CLASS C
        clases = train.dameClases();
        int unavez = 0, candidato;
        for (int i = 0; i < train.getnclases(); i++) {
          System.out.println("CLASE :" + clases[i] + "\n");
          // initialize E to the instance set
          /*Cuando haya que inicializar de nuevo el conjunto de instancias no es necesario insertar aquellas que se eliminaron, sino que nos va a bastar con inicializar otra vez el conjunto mediante el fichero de entrenamiento. Por eso hay un metodo para insertar una instancia*/
          train.leeConjunto(ficheroTrain, false);
          nombre_atributos = train.dameNombres();
          instancias = train.getInstanceSet();

          // While E contains instances in class C
          while (train.hayInstanciasDeClaseC(i)) {
            // Create a rule R with an empty left-hand side that predicts class C
            regla = new Complejo(train.getnclases());
            regla.setClase(i);
            regla.adjuntaNombreAtributos(nombre_atributos);
            // esto lo hacemos solo aqui pq luego vamos quitando selectores del almacen
            almacen = hazSelectores(train);
            almacen.adjuntaNombreAtributos(nombre_atributos);
            do {
              // FOR EACH ATTRIBUTE A NOT MENTIONED IN R, AND EACH VALUE V
              accuracy_ant = -1.;
              p = 0;
              int seleccionados[] = new int[almacen.size()];
              for (int jj = 0; jj < almacen.size(); jj++) seleccionados[jj] = 0;
              System.out.println();
              for (int j = 0; j < almacen.size(); j++) {
                // tenemos que quitar el selector anterior
                if (j > 0) regla.removeSelector(s);
                s = almacen.getSelector(j);
                // if(i==0)
                s.print();
                // CONSIDER ADDING THE CONDITION A=V TO THE LHS OF R
                regla.addSelector(s);
                accuracy = getAccuracy(i);
                // if(i==0)	{
                System.out.println("correctas " + num_correctas + " cubiertas " + num_cubiertas);
                System.out.println("Acurracy " + accuracy);
                // }

                if ((accuracy > accuracy_ant)
                    || ((accuracy == accuracy_ant) && (num_correctas > p))) {

                  // if((accuracy==accuracy_ant) &&(num_correctas>p)){
                  // System.out.println("atn "+accuracy_ant);
                  // System.out.println("ahora "+accuracy);
                  accuracy_ant = accuracy;
                  seleccionado = j;
                  p = num_correctas;

                  // si se encuentra un superior hay que quitar
                  // todo lo q se hay ido almacenando en esta iteracion
                  for (int jj = 0; jj < almacen.size(); jj++) seleccionados[jj] = 0;
                  // }
                } else {
                  if ((accuracy == accuracy_ant) && (num_correctas == p)) {
                    seleccionados[seleccionado] = 1;
                    seleccionados[j] = 1;
                  }
                }
              }
              // seleccionamos uno de los seleccionados en el caso de empate
              int contador = 0;
              for (int jj = 0; jj < almacen.size(); jj++) {
                if (seleccionados[jj] == 1) {
                  contador++;
                  System.out.println("OPCION " + jj);
                }
              }
              if (contador > 0) {
                candidato = Randomize.RandintClosed(1, contador);
                contador = 0;
                for (int jj = 0; jj < almacen.size(); jj++) {
                  if (seleccionados[jj] == 1) {
                    contador++;
                    if (contador == candidato) seleccionado = jj;
                  }
                }
              }
              System.out.println("ELEGIDO " + seleccionado);

              // antes hay que quitar el q metimos
              regla.removeSelector(s);
              s = almacen.getSelector(seleccionado);
              s.print();
              // ADD A=V TO R
              regla.addSelector(s);
              /*AHORA HAY QUE QUITAR DEL ALMACEN SE SELECTORES AQUELLOS QUE
              HACEN REFERENCIA AL ATRIBUTO SELECCIONADO*/
              // obtener el atributo del selector ganador
              atributo = s.getAtributo();
              // se borran todos los q tengan ese atributo
              // System.out.println("ALMACEN");almacen.print();
              almacen.removeSelectorAtributo(atributo);

              reglaPerfecta = perfectRule(regla, train);
            } while (!reglaPerfecta && (regla.size() < train.getnentradas()));

            System.out.println("\n");
            System.out.println("\nREGLA............................................");
            regla.print();
            System.out.println("\n");
            /*necesitamos evaluar la regla para obtener la salida del metodo
            para compararla con la salida esperada*/
            evaluarComplejo(regla, datosTrain);
            // INCLUIMOS ESTA REGLA YA PARA EL CONJUNTO FINAL DE REGLAS
            conjunto_reglas.addRegla(regla);
            // REMOVE THE INSTANCES COVERED BY R FROM E

            // Instance instancia;
            /*for(int k=0;k<instancias.getNumInstances();k++){
            instancia=instancias.getInstance(k);
            System.out.print(k+" ");
              	instancia.print();
            System.out.println();
              	}*/
            removeInstancesCovered(i);
            for (int k = 0; k < instancias.getNumInstances(); k++) {
              instancia = instancias.getInstance(k);
              clase = instancia.getOutputNominalValuesInt(0);
              if (clase == i) {
                System.out.print(k + " ");
                instancia.print();
                System.out.println();
              }
            }
            // instancias.print();
            System.out.println("\n");
          } // del while
        } // del for de las clases

        // EVALUAMOS LA CALIDAD DE LAS REGLAS
        int[] clasesEval;
        clasesEval = train.getC();
        muestPorClaseEval = new int[train.getnclases()];
        for (int j = 0; j < train.getnclases(); j++) {
          muestPorClaseEval[j] = 0;
          for (int i = 0; i < datosTrain.size(); i++) {
            if (
            /*valorClases[j]*/ j == clasesEval[i]) {
              muestPorClaseEval[j]++;
            }
          }
        }
        conjunto_reglas.eliminaRepetidos(1);
        evReg =
            new EvaluaCalidadReglas(
                conjunto_reglas,
                datosTrain,
                datosTest,
                muestPorClaseEval,
                muestPorClaseEval,
                clases);
        // GENERAMOS LA SALIDA
        generaSalida();
        System.out.println("la semilla es " + seed);
      } // del if
    } catch (IOException e) {
      System.err.println("There was a problem while trying to read the dataset files:");
      System.err.println("-> " + e);
      // System.exit(0);
    }
  }
Beispiel #9
0
 /**
  * Returns the header of the data set with the attributes' information
  *
  * @return The header of the data set
  */
 public String getHeader() {
   return IS.getHeader();
 }
Beispiel #10
0
  /**
   * Process a dataset file for a classification problem.
   *
   * @param nfejemplos Name of the dataset file
   * @param train The dataset file is for training or for test
   * @throws java.io.IOException if there is any semantical, lexical or sintactical error in the
   *     input file.
   */
  public void processClassifierDataset(String nfejemplos, boolean train) throws IOException {

    try {

      // Load in memory a dataset that contains a classification problem
      IS.readSet(nfejemplos, train);

      nData = IS.getNumInstances();
      nInputs = Attributes.getInputNumAttributes();
      nVariables = nInputs + Attributes.getOutputNumAttributes();

      // Check that there is only one output variable and
      // it is nominal

      if (Attributes.getOutputNumAttributes() > 1) {
        System.out.println("This algorithm can not process MIMO datasets");
        System.out.println("All outputs but the first one will be removed");
      }

      boolean noOutputs = false;
      if (Attributes.getOutputNumAttributes() < 1) {
        System.out.println("This algorithm can not process datasets without outputs");
        System.out.println("Zero-valued output generated");
        noOutputs = true;
      }

      // Initialize and fill our own tables
      X = new double[nData][nInputs];
      missing = new boolean[nData][nInputs];
      C = new int[nData];

      // Maximum and minimum of inputs
      iMaximum = new double[nInputs];
      iMinimum = new double[nInputs];

      // Maximum and minimum for output data
      oMaximum = 0;
      oMinimum = 0;

      // All values are casted into double/integer
      nClasses = 0;
      for (int i = 0; i < X.length; i++) {
        Instance inst = IS.getInstance(i);
        for (int j = 0; j < nInputs; j++) {
          X[i][j] = IS.getInputNumericValue(i, j);
          missing[i][j] = inst.getInputMissingValues(j);
          if (X[i][j] > iMaximum[j] || i == 0) {
            iMaximum[j] = X[i][j];
          }
          if (X[i][j] < iMinimum[j] || i == 0) {
            iMinimum[j] = X[i][j];
          }
        }

        if (noOutputs) {
          C[i] = 0;
        } else {
          C[i] = (int) IS.getOutputNumericValue(i, 0);
        }
        if (C[i] > nClasses) {
          nClasses = C[i];
        }
      }
      nClasses++;
      System.out.println("Number of classes=" + nClasses);

    } catch (Exception e) {
      System.out.println("DBG: Exception in readSet");
      e.printStackTrace();
    }
  }
Beispiel #11
0
  /** Process the training and test files provided in the parameters file to the constructor. */
  public void process() {
    // declarations
    double[] outputs;
    double[] outputs2;
    Instance neighbor;
    double dist, mean;
    int actual;
    Randomize rnd = new Randomize();
    Instance ex;
    gCenter kmeans = null;
    int iterations = 0;
    double E;
    double prevE;
    int totalMissing = 0;
    boolean allMissing = true;

    rnd.setSeed(semilla);
    // PROCESS
    try {

      // Load in memory a dataset that contains a classification problem
      IS.readSet(input_train_name, true);
      int in = 0;
      int out = 0;

      ndatos = IS.getNumInstances();
      nvariables = Attributes.getNumAttributes();
      nentradas = Attributes.getInputNumAttributes();
      nsalidas = Attributes.getOutputNumAttributes();

      X = new String[ndatos][nvariables]; // matrix with transformed data
      kmeans = new gCenter(K, ndatos, nvariables);

      timesSeen = new FreqList[nvariables];
      mostCommon = new String[nvariables];

      // first, we choose k 'means' randomly from all
      // instances
      totalMissing = 0;
      for (int i = 0; i < ndatos; i++) {
        Instance inst = IS.getInstance(i);
        if (inst.existsAnyMissingValue()) totalMissing++;
      }
      if (totalMissing == ndatos) allMissing = true;
      else allMissing = false;
      for (int numMeans = 0; numMeans < K; numMeans++) {
        do {
          actual = (int) (ndatos * rnd.Rand());
          ex = IS.getInstance(actual);
        } while (ex.existsAnyMissingValue() && !allMissing);

        kmeans.copyCenter(ex, numMeans);
      }

      // now, iterate adjusting clusters' centers and
      // instances to them
      prevE = 0;
      iterations = 0;
      do {
        for (int i = 0; i < ndatos; i++) {
          Instance inst = IS.getInstance(i);

          kmeans.setClusterOf(inst, i);
        }
        // set new centers
        kmeans.recalculateCenters(IS);
        // compute RMSE
        E = 0;
        for (int i = 0; i < ndatos; i++) {
          Instance inst = IS.getInstance(i);

          E += kmeans.distance(inst, kmeans.getClusterOf(i));
        }
        iterations++;
        // System.out.println(iterations+"\t"+E);
        if (Math.abs(prevE - E) == 0) iterations = maxIter;
        else prevE = E;
      } while (E > minError && iterations < maxIter);
      for (int i = 0; i < ndatos; i++) {
        Instance inst = IS.getInstance(i);

        in = 0;
        out = 0;

        for (int j = 0; j < nvariables; j++) {
          Attribute a = Attributes.getAttribute(j);

          direccion = a.getDirectionAttribute();
          tipo = a.getType();

          if (direccion == Attribute.INPUT) {
            if (tipo != Attribute.NOMINAL && !inst.getInputMissingValues(in)) {
              X[i][j] = new String(String.valueOf(inst.getInputRealValues(in)));
            } else {
              if (!inst.getInputMissingValues(in)) X[i][j] = inst.getInputNominalValues(in);
              else {
                actual = kmeans.getClusterOf(i);
                X[i][j] = new String(kmeans.valueAt(actual, j));
              }
            }
            in++;
          } else {
            if (direccion == Attribute.OUTPUT) {
              if (tipo != Attribute.NOMINAL && !inst.getOutputMissingValues(out)) {
                X[i][j] = new String(String.valueOf(inst.getOutputRealValues(out)));
              } else {
                if (!inst.getOutputMissingValues(out)) X[i][j] = inst.getOutputNominalValues(out);
                else {
                  actual = kmeans.getClusterOf(i);
                  X[i][j] = new String(kmeans.valueAt(actual, j));
                }
              }
              out++;
            }
          }
        }
      }
    } catch (Exception e) {
      System.out.println("Dataset exception = " + e);
      e.printStackTrace();
      System.exit(-1);
    }
    write_results(output_train_name);
    /** ************************************************************************************ */
    // does a test file associated exist?
    if (input_train_name.compareTo(input_test_name) != 0) {
      try {

        // Load in memory a dataset that contains a classification problem
        IStest.readSet(input_test_name, false);
        int in = 0;
        int out = 0;

        ndatos = IStest.getNumInstances();
        nvariables = Attributes.getNumAttributes();
        nentradas = Attributes.getInputNumAttributes();
        nsalidas = Attributes.getOutputNumAttributes();

        for (int i = 0; i < ndatos; i++) {
          Instance inst = IStest.getInstance(i);

          in = 0;
          out = 0;

          for (int j = 0; j < nvariables; j++) {
            Attribute a = Attributes.getAttribute(j);

            direccion = a.getDirectionAttribute();
            tipo = a.getType();

            if (direccion == Attribute.INPUT) {
              if (tipo != Attribute.NOMINAL && !inst.getInputMissingValues(in)) {
                X[i][j] = new String(String.valueOf(inst.getInputRealValues(in)));
              } else {
                if (!inst.getInputMissingValues(in)) X[i][j] = inst.getInputNominalValues(in);
                else {
                  actual = kmeans.getClusterOf(i);
                  X[i][j] = new String(kmeans.valueAt(actual, j));
                }
              }
              in++;
            } else {
              if (direccion == Attribute.OUTPUT) {
                if (tipo != Attribute.NOMINAL && !inst.getOutputMissingValues(out)) {
                  X[i][j] = new String(String.valueOf(inst.getOutputRealValues(out)));
                } else {
                  if (!inst.getOutputMissingValues(out)) X[i][j] = inst.getOutputNominalValues(out);
                  else {
                    actual = kmeans.getClusterOf(i);
                    X[i][j] = new String(kmeans.valueAt(actual, j));
                  }
                }
                out++;
              }
            }
          }
        }
      } catch (Exception e) {
        System.out.println("Dataset exception = " + e);
        e.printStackTrace();
        System.exit(-1);
      }
      write_results(output_test_name);
    }
  }