Exemplo n.º 1
0
 public Vector getRangos() {
   Vector salida = new Vector();
   double[][] rangos = this.devuelveRangos();
   for (int i = 0; i < nVars; i++) {
     Vector rango = new Vector();
     if (this.getTiposIndex2(i).equals("real")) {
       // if (this.getTiposIndex(i).equals("real")) {
       rango.add(new Double(rangos[i][0]));
       rango.add(new Double(rangos[i][1]));
       /*}else if(this.getTiposIndex2(i).equals("integer")){
          rango.add(new Integer((int)rangos[i][0]));
          rango.add(new Integer((int)rangos[i][1]));
       */
     } else {
       if (i == nVars - 1) {
         for (int j = 0; j < Attributes.getOutputAttribute(0).getNumNominalValues(); j++) {
           rango.add(Attributes.getOutputAttribute(0).getNominalValue(j));
         }
       } else {
         for (int j = 0; j < Attributes.getAttribute(i).getNumNominalValues(); j++) {
           rango.add(Attributes.getAttribute(i).getNominalValue(j));
         }
       }
     }
     salida.add(rango);
   }
   return salida;
 }
Exemplo n.º 2
0
  /**
   * Function to read an itemset and appends it to the dataset.
   *
   * @return True if the itemset was readed succesfully.
   */
  private boolean getItemsetFull() {

    // fill itemset
    for (int j = 0; j < IS.getNumInstances(); j++) {

      double[] itemset = new double[Attributes.getNumAttributes()];
      int index;

      // Get values for all input attributes.
      for (int i = 0; i < Attributes.getInputNumAttributes(); i++) {

        // check type and if there is null

        if (IS.getInstance(j).getInputMissingValues(i)) itemset[i] = Itemset.getMissingValue();
        else {
          if (Attributes.getInputAttribute(i).getType() == 0) // nominal
          {
            for (int k = 0; k < Attributes.getInputAttribute(i).getNumNominalValues(); k++)
              if (Attributes.getInputAttribute(i)
                  .getNominalValue(k)
                  .equals(IS.getInstance(j).getInputNominalValues(i))) itemset[i] = (double) k;
          } else // real and integer
          {
            itemset[i] = IS.getInstance(j).getInputRealValues(i);
          }
        } // else
      } // for

      // Get values for output attribute.
      int i = Attributes.getInputNumAttributes();

      // check type and if there is null
      if (IS.getInstance(j).getOutputMissingValues(0)) itemset[i] = Itemset.getMissingValue();
      else {
        if (Attributes.getOutputAttribute(0).getType() == 0) // nominal
        {
          for (int k = 0; k < Attributes.getOutputAttribute(0).getNumNominalValues(); k++)
            if (Attributes.getOutputAttribute(0)
                .getNominalValue(k)
                .equals(IS.getInstance(j).getOutputNominalValues(0))) itemset[i] = (double) k;
        } else // real and integer
        {
          itemset[i] = IS.getInstance(j).getOutputRealValues(0);
        }
      } // else

      // Add itemset to dataset
      addItemset(new Itemset(1, itemset));
    } // for

    return true;
  }
Exemplo n.º 3
0
 /**
  * Devuelve el universo de discuros de las variables de entrada y salida
  *
  * @return double[][] El rango minimo y maximo de cada variable
  */
 public double[][] devuelveRangos() {
   double[][] rangos = new double[this.getnVars()][2];
   for (int i = 0; i < this.getnInputs(); i++) {
     if (Attributes.getInputAttribute(i).getNumNominalValues() > 0) {
       rangos[i][0] = 0;
       rangos[i][1] = Attributes.getInputAttribute(i).getNumNominalValues() - 1;
     } else {
       rangos[i][0] = Attributes.getInputAttribute(i).getMinAttribute();
       rangos[i][1] = Attributes.getInputAttribute(i).getMaxAttribute();
     }
   }
   rangos[this.getnVars() - 1][0] = Attributes.getOutputAttribute(0).getMinAttribute();
   rangos[this.getnVars() - 1][1] = Attributes.getOutputAttribute(0).getMaxAttribute();
   return rangos;
 }
Exemplo n.º 4
0
  /**
   * Generates output file for a clasification problem @ param Foutput Name of the output file @
   * param real Vector of outputs instances @ param obtained Vector of net outputs
   *
   * @return Nothing
   */
  public void generateResultsClasification(String Foutput, int[] real, int[] obtained) {

    // Output file, classification problems
    FileOutputStream out;
    PrintStream p;
    Attribute at = Attributes.getOutputAttribute(0);

    // Check whether the output value is nominal or integer
    boolean isNominal = (at.getType() == at.NOMINAL);
    try {
      out = new FileOutputStream(Foutput);
      p = new PrintStream(out);
      CopyHeaderTest(p);
      // System.out.println("Longitudes "+real.length+" "+obtained.length);
      for (int i = 0; i < real.length; i++) {
        // Write the label associated to the class number,
        // when the output is nominal
        if (isNominal)
          p.print(at.getNominalValue(real[i]) + " " + at.getNominalValue(obtained[i]) + "\n");
        else p.print(real[i] + " " + obtained[i] + "\n");
      }
      p.close();
    } catch (Exception e) {
      System.err.println("Error building file for results: " + Foutput);
    }
  }
Exemplo n.º 5
0
  private void normalizarTest() {

    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) {
      System.err.println(
          "This dataset haven´t outputs, so it not corresponding to a classification problem.");
      System.exit(-1);
    } else if (Attributes.getOutputNumAttributes() > 1) {
      System.err.println("This dataset have more of one output.");
      System.exit(-1);
    }

    if (Attributes.getOutputAttribute(0).getType() == Attribute.REAL) {
      System.err.println(
          "This dataset have an input attribute with floating values, so it not corresponding to a classification problem.");
      System.exit(-1);
    }

    datosTest = new double[test.getNumInstances()][Attributes.getInputNumAttributes()];
    clasesTest = new int[test.getNumInstances()];
    caja = new double[1];

    for (i = 0; i < test.getNumInstances(); i++) {
      temp = test.getInstance(i);
      nulls = temp.getInputMissingValues();
      datosTest[i] = test.getInstance(i).getAllInputValues();
      for (j = 0; j < nulls.length; j++) if (nulls[j]) datosTest[i][j] = 0.0;
      caja = test.getInstance(i).getAllOutputValues();
      clasesTest[i] = (int) caja[0];
      for (k = 0; k < datosTest[i].length; k++) {
        if (Attributes.getInputAttribute(k).getType() == Attribute.NOMINAL) {
          datosTest[i][k] /= Attributes.getInputAttribute(k).getNominalValuesList().size() - 1;
        } else {
          datosTest[i][k] -= Attributes.getInputAttribute(k).getMinAttribute();
          datosTest[i][k] /=
              Attributes.getInputAttribute(k).getMaxAttribute()
                  - Attributes.getInputAttribute(k).getMinAttribute();
        }
      }
    }
  }
Exemplo n.º 6
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();
        }
      }
    }
  }
Exemplo n.º 7
0
  /**
   * It does remove an attribute. To remove an attribute, the train and the test sets have to be
   * passed to mantain the coherence of the system. Otherwise, only the attribute of the train set
   * would be removed, leaving inconsistent the instances of the test set, because of having one
   * extra attribute inexistent anymore.
   *
   * @param tSet is the test set.
   * @param inputAtt is a boolean that is true when the attribute that is wanted to be removed is an
   *     input attribute.
   * @param whichAtt is a integer that indicate the position of the attriubte to be deleted.
   * @return a boolean indicating if the attribute has been deleted
   */
  public boolean removeAttribute(InstanceSet tSet, boolean inputAtt, int whichAtt) {
    Attribute attToDel = null;
    // Getting a reference to the attribute to del
    if (inputAtt) {
      if (storeAttributesAsNonStatic && attributes != null)
        attToDel = (Attribute) attributes.getInputAttribute(whichAtt);
      else attToDel = (Attribute) Attributes.getInputAttribute(whichAtt);
    } else {
      if (storeAttributesAsNonStatic && attributes != null)
        attToDel = (Attribute) attributes.getOutputAttribute(whichAtt);
      else attToDel = (Attribute) Attributes.getOutputAttribute(whichAtt);
    }

    if (storeAttributesAsNonStatic && attributes != null) {
      System.out.println("Removing the attribute");
      if (!attributes.removeAttribute(inputAtt, whichAtt)
          || !tSet.attributes.removeAttribute(inputAtt, whichAtt)) return false;
    } else {
      if (!Attributes.removeAttribute(inputAtt, whichAtt)) return false;
    }

    for (int i = 0; i < instanceSet.length; i++) {
      if (storeAttributesAsNonStatic && attributes != null) {
        instanceSet[i].removeAttribute(attributes, attToDel, inputAtt, whichAtt);
      } else {
        instanceSet[i].removeAttribute(attToDel, inputAtt, whichAtt);
      }
    }

    if (tSet != null)
      for (int i = 0; i < tSet.instanceSet.length; i++) {
        if (storeAttributesAsNonStatic && attributes != null)
          tSet.instanceSet[i].removeAttribute(attributes, attToDel, inputAtt, whichAtt);
        else tSet.instanceSet[i].removeAttribute(attToDel, inputAtt, whichAtt);
      }
    return true;
  } // end removeAttribute
Exemplo n.º 8
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());
  }
Exemplo n.º 9
0
  /**
   * This function builds the data matrix for reference data and normalizes inputs values
   *
   * @throws keel.Algorithms.Preprocess.Basic.CheckException Can not be normalized.
   */
  protected void normalizar() throws CheckException {

    int i, j, k;
    Instance temp;
    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.");
    }

    entradas = Attributes.getInputAttributes();
    salida = Attributes.getOutputAttribute(0);
    nEntradas = Attributes.getInputNumAttributes();
    tokens = new StringTokenizer(training.getHeader(), " \n\r");
    tokens.nextToken();
    relation = tokens.nextToken();

    datosTrain = new double[training.getNumInstances()][Attributes.getInputNumAttributes()];
    clasesTrain = new int[training.getNumInstances()];
    caja = new double[1];

    nulosTrain = new boolean[training.getNumInstances()][Attributes.getInputNumAttributes()];
    nominalTrain = new int[training.getNumInstances()][Attributes.getInputNumAttributes()];
    realTrain = new double[training.getNumInstances()][Attributes.getInputNumAttributes()];

    for (i = 0; i < training.getNumInstances(); i++) {
      temp = training.getInstance(i);
      nulls = temp.getInputMissingValues();
      datosTrain[i] = training.getInstance(i).getAllInputValues();
      for (j = 0; j < nulls.length; j++)
        if (nulls[j]) {
          datosTrain[i][j] = 0.0;
          nulosTrain[i][j] = true;
        }
      caja = training.getInstance(i).getAllOutputValues();
      clasesTrain[i] = (int) caja[0];
      for (k = 0; k < datosTrain[i].length; k++) {
        if (Attributes.getInputAttribute(k).getType() == Attribute.NOMINAL) {
          nominalTrain[i][k] = (int) datosTrain[i][k];
          datosTrain[i][k] /= Attributes.getInputAttribute(k).getNominalValuesList().size() - 1;
        } else {
          realTrain[i][k] = datosTrain[i][k];
          datosTrain[i][k] -= Attributes.getInputAttribute(k).getMinAttribute();
          datosTrain[i][k] /=
              Attributes.getInputAttribute(k).getMaxAttribute()
                  - Attributes.getInputAttribute(k).getMinAttribute();
          if (Double.isNaN(datosTrain[i][k])) {
            datosTrain[i][k] = realTrain[i][k];
          }
        }
      }
    }

    datosTest = new double[test.getNumInstances()][Attributes.getInputNumAttributes()];
    clasesTest = new int[test.getNumInstances()];
    caja = new double[1];

    for (i = 0; i < test.getNumInstances(); i++) {
      temp = test.getInstance(i);
      nulls = temp.getInputMissingValues();
      datosTest[i] = test.getInstance(i).getAllInputValues();
      for (j = 0; j < nulls.length; j++)
        if (nulls[j]) {
          datosTest[i][j] = 0.0;
        }
      caja = test.getInstance(i).getAllOutputValues();
      clasesTest[i] = (int) caja[0];
    }
  } // end-method
Exemplo n.º 10
0
 public String getOutputValue(int intValue) {
   return Attributes.getOutputAttribute(0).getNominalValue(intValue);
 }
Exemplo n.º 11
0
  /** Function to stores header of a data file. */
  private void readHeader() {
    String attributeName;
    Vector attributeValues;
    int i;

    name = Attributes.getRelationName();

    // Create vectors to hold information temporarily.
    attributes = new Vector();

    Attribute at;

    // store attribute inputs and of the header
    for (int j = 0; j < Attributes.getInputNumAttributes(); j++) {
      at = Attributes.getInputAttribute(j);
      attributeName = at.getName();

      // check if it is real
      if (at.getType() == 2) {
        float min = (float) at.getMinAttribute();
        float max = (float) at.getMinAttribute();
        attributes.addElement(new MyAttribute(attributeName, j));
        MyAttribute att = (MyAttribute) attributes.elementAt(j);
        att.setRange(min, max);
        att.activate();
      } else {
        if (at.getType() == 1) // check if it is integer
        {
          int min = (int) at.getMinAttribute();
          int max = (int) at.getMinAttribute();
          attributes.addElement(new MyAttribute(attributeName, j));
          MyAttribute att = (MyAttribute) attributes.elementAt(j);
          att.setRange(min, max);
          att.activate();
        } else // it is nominal
        {
          attributeValues = new Vector();
          for (int k = 0; k < at.getNumNominalValues(); k++) {
            attributeValues.addElement(at.getNominalValue(k));
          }
          attributes.addElement(new MyAttribute(attributeName, attributeValues, j));
          MyAttribute att = (MyAttribute) attributes.elementAt(j);
          att.activate();
        }
      }
    } // for

    // store outputs of the header
    at = Attributes.getOutputAttribute(0);
    attributeName = at.getName();

    int j = Attributes.getNumAttributes() - 1;

    // check if it is real
    if (at.getType() == 2) {
      float min = (float) at.getMinAttribute();
      float max = (float) at.getMinAttribute();
      attributes.addElement(new MyAttribute(attributeName, j));
      MyAttribute att = (MyAttribute) attributes.elementAt(j);
      att.setRange(min, max);
      att.activate();
    } else {
      if (at.getType() == 1) // check if it is integer
      {
        int min = (int) at.getMinAttribute();
        int max = (int) at.getMinAttribute();
        attributes.addElement(new MyAttribute(attributeName, j));
        MyAttribute att = (MyAttribute) attributes.elementAt(j);
        att.setRange(min, max);
        att.activate();
      } else // it is nominal
      {
        attributeValues = new Vector();
        for (int k = 0; k < at.getNumNominalValues(); k++) {
          attributeValues.addElement(at.getNominalValue(k));
        }
        attributes.addElement(new MyAttribute(attributeName, attributeValues, j));
        MyAttribute att = (MyAttribute) attributes.elementAt(j);
        att.activate();
      }
    }

    // set the index of the output class
    classIndex = Attributes.getNumAttributes() - 1;
  }
Exemplo n.º 12
0
  /**
   * It reads the whole input data-set and it stores each example and its associated output value in
   * local arrays to ease their use.
   *
   * @param datasetFile String name of the file containing the dataset
   * @param train boolean It must have the value "true" if we are reading the training data-set
   * @throws IOException If there ocurs any problem with the reading of the data-set
   */
  public void readClassificationSet(String datasetFile, boolean train) throws IOException {
    try {
      // Load in memory a dataset that contains a classification problem
      IS.readSet(datasetFile, train);
      nData = IS.getNumInstances();
      nInputs = Attributes.getInputNumAttributes();
      nVars = nInputs + Attributes.getOutputNumAttributes();

      // outputIntegerheck that there is only one output variable
      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");
        System.exit(1);
      }
      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;
        System.exit(1);
      }

      // Initialice and fill our own tables
      X = new double[nData][nInputs];
      Nominal = new String[nData][nVars];
      missing = new boolean[nData][nVars];
      outputInteger = new int[nData];
      outputReal = new double[nData];
      output = new String[nData];

      // Maximum and minimum of inputs
      emax = new double[nInputs];
      emin = new double[nInputs];
      for (int i = 0; i < nInputs; i++) {
        emax[i] = Attributes.getAttribute(i).getMaxAttribute();
        emin[i] = Attributes.getAttribute(i).getMinAttribute();
      }
      // All values are casted into double/integer
      nClasses = 0;
      for (int i = 0; i < nData; i++) {
        Instance inst = IS.getInstance(i);
        for (int j = 0; j < nInputs; j++) {
          X[i][j] = IS.getInputNumericValue(i, j); // inst.getInputRealValues(j);
          Nominal[i][j] = "" + IS.getInputNumericValue(i, j);
          missing[i][j] = inst.getInputMissingValues(j);
          if (missing[i][j]) {
            X[i][j] = emin[j] - 1;
          }
        }

        if (noOutputs) {
          outputInteger[i] = 0;
          output[i] = "";
        } else {
          outputInteger[i] = (int) IS.getOutputNumericValue(i, 0);
          output[i] = IS.getOutputNominalValue(i, 0);
          Nominal[i][nInputs] = output[i];
          missing[i][nInputs] = false;
        }
        if (outputInteger[i] > nClasses) {
          nClasses = outputInteger[i];
        }
      }
      nClasses++;
      System.out.println("Number of classes=" + nClasses);

    } catch (Exception e) {
      System.out.println("DBG: Exception in readSet");
      e.printStackTrace();
    }
    computeStatistics();
    this.computeInstancesPerClass();
    Attribute[] atts = Attributes.getAttributes();
    for (indexClass = 0;
        (indexClass < atts.length)
            && (!(Attributes.getOutputAttribute(0)
                .getName()
                .equalsIgnoreCase(atts[indexClass].getName())));
        indexClass++) {;
    }
  }