Пример #1
0
  /**
   * Classifies the given instance using the linear regression function.
   *
   * @param instance the test instance
   * @return the classification
   * @throws Exception if classification can't be done successfully
   */
  public double classifyInstance(Instance instance) throws Exception {
    // Filter instance
    m_Missing.input(instance);
    m_Missing.batchFinished();
    instance = m_Missing.output();

    if (!m_onlyNumeric && m_NominalToBinary != null) {
      m_NominalToBinary.input(instance);
      m_NominalToBinary.batchFinished();
      instance = m_NominalToBinary.output();
    }

    if (m_Filter != null) {
      m_Filter.input(instance);
      m_Filter.batchFinished();
      instance = m_Filter.output();
    }

    double result = m_optimizer.SVMOutput(instance);
    return result * m_x1 + m_x0;
  }
Пример #2
0
  /**
   * Computes the distribution for a given instance
   *
   * @param instance the instance for which distribution is computed
   * @return the distribution
   * @throws Exception if the distribution can't be computed successfully
   */
  @Override
  public double[] distributionForInstance(Instance instance) throws Exception {

    m_ReplaceMissingValues.input(instance);
    instance = m_ReplaceMissingValues.output();
    m_AttFilter.input(instance);
    instance = m_AttFilter.output();
    m_NominalToBinary.input(instance);
    instance = m_NominalToBinary.output();

    // Extract the predictor columns into an array
    double[] instDat = new double[m_NumPredictors + 1];
    int j = 1;
    instDat[0] = 1;
    for (int k = 0; k <= m_NumPredictors; k++) {
      if (k != m_ClassIndex) {
        instDat[j++] = instance.value(k);
      }
    }

    double[] distribution = evaluateProbability(instDat);
    return distribution;
  }
Пример #3
0
  /**
   * Method for building the classifier.
   *
   * @param instances the set of training instances
   * @throws Exception if the classifier can't be built successfully
   */
  public void buildClassifier(Instances instances) throws Exception {
    // can classifier handle the data?
    getCapabilities().testWithFail(instances);

    // remove instances with missing class
    instances = new Instances(instances);
    instances.deleteWithMissingClass();

    // Removes all the instances with weight equal to 0.
    // MUST be done since condition (8) of Keerthi's paper
    // is made with the assertion Ci > 0 (See equation (3a).
    Instances data = new Instances(instances, 0);
    for (int i = 0; i < instances.numInstances(); i++) {
      if (instances.instance(i).weight() > 0) {
        data.add(instances.instance(i));
      }
    }

    if (data.numInstances() == 0) {
      throw new Exception(
          "No training instances left after removing "
              + "instance with either a weight null or a missing class!");
    }
    instances = data;

    m_onlyNumeric = true;
    for (int i = 0; i < instances.numAttributes(); i++) {
      if (i != instances.classIndex()) {
        if (!instances.attribute(i).isNumeric()) {
          m_onlyNumeric = false;
          break;
        }
      }
    }
    m_Missing = new ReplaceMissingValues();
    m_Missing.setInputFormat(instances);
    instances = Filter.useFilter(instances, m_Missing);

    if (getCapabilities().handles(Capability.NUMERIC_ATTRIBUTES)) {
      if (!m_onlyNumeric) {
        m_NominalToBinary = new NominalToBinary();
        m_NominalToBinary.setInputFormat(instances);
        instances = Filter.useFilter(instances, m_NominalToBinary);
      } else {
        m_NominalToBinary = null;
      }
    } else {
      m_NominalToBinary = null;
    }

    // retrieve two different class values used to determine filter transformation
    double y0 = instances.instance(0).classValue();
    int index = 1;
    while (index < instances.numInstances() && instances.instance(index).classValue() == y0) {
      index++;
    }
    if (index == instances.numInstances()) {
      // degenerate case, all class values are equal
      // we don't want to deal with this, too much hassle
      throw new Exception(
          "All class values are the same. At least two class values should be different");
    }
    double y1 = instances.instance(index).classValue();

    // apply filters
    if (m_filterType == FILTER_STANDARDIZE) {
      m_Filter = new Standardize();
      ((Standardize) m_Filter).setIgnoreClass(true);
      m_Filter.setInputFormat(instances);
      instances = Filter.useFilter(instances, m_Filter);
    } else if (m_filterType == FILTER_NORMALIZE) {
      m_Filter = new Normalize();
      ((Normalize) m_Filter).setIgnoreClass(true);
      m_Filter.setInputFormat(instances);
      instances = Filter.useFilter(instances, m_Filter);
    } else {
      m_Filter = null;
    }
    if (m_Filter != null) {
      double z0 = instances.instance(0).classValue();
      double z1 = instances.instance(index).classValue();
      m_x1 =
          (y0 - y1) / (z0 - z1); // no division by zero, since y0 != y1 guaranteed => z0 != z1 ???
      m_x0 = (y0 - m_x1 * z0); // = y1 - m_x1 * z1
    } else {
      m_x1 = 1.0;
      m_x0 = 0.0;
    }

    m_optimizer.setSMOReg(this);
    m_optimizer.buildClassifier(instances);
  }
Пример #4
0
  /**
   * Builds the classifier
   *
   * @param train the training data to be used for generating the boosted classifier.
   * @throws Exception if the classifier could not be built successfully
   */
  @Override
  public void buildClassifier(Instances train) throws Exception {
    // can classifier handle the data?
    getCapabilities().testWithFail(train);

    // remove instances with missing class
    train = new Instances(train);
    train.deleteWithMissingClass();

    // Replace missing values
    m_ReplaceMissingValues = new ReplaceMissingValues();
    m_ReplaceMissingValues.setInputFormat(train);
    train = Filter.useFilter(train, m_ReplaceMissingValues);

    // Remove useless attributes
    m_AttFilter = new RemoveUseless();
    m_AttFilter.setInputFormat(train);
    train = Filter.useFilter(train, m_AttFilter);

    // Transform attributes
    m_NominalToBinary = new NominalToBinary();
    m_NominalToBinary.setInputFormat(train);
    train = Filter.useFilter(train, m_NominalToBinary);

    // Save the structure for printing the model
    m_structure = new Instances(train, 0);

    // Extract data
    m_ClassIndex = train.classIndex();
    m_NumClasses = train.numClasses();

    int nK = m_NumClasses - 1; // Only K-1 class labels needed
    int nR = m_NumPredictors = train.numAttributes() - 1;
    int nC = train.numInstances();

    m_Data = new double[nC][nR + 1]; // Data values
    int[] Y = new int[nC]; // Class labels
    double[] xMean = new double[nR + 1]; // Attribute means
    double[] xSD = new double[nR + 1]; // Attribute stddev's
    double[] sY = new double[nK + 1]; // Number of classes
    double[] weights = new double[nC]; // Weights of instances
    double totWeights = 0; // Total weights of the instances
    m_Par = new double[nR + 1][nK]; // Optimized parameter values

    if (m_Debug) {
      System.out.println("Extracting data...");
    }

    for (int i = 0; i < nC; i++) {
      // initialize X[][]
      Instance current = train.instance(i);
      Y[i] = (int) current.classValue(); // Class value starts from 0
      weights[i] = current.weight(); // Dealing with weights
      totWeights += weights[i];

      m_Data[i][0] = 1;
      int j = 1;
      for (int k = 0; k <= nR; k++) {
        if (k != m_ClassIndex) {
          double x = current.value(k);
          m_Data[i][j] = x;
          xMean[j] += weights[i] * x;
          xSD[j] += weights[i] * x * x;
          j++;
        }
      }

      // Class count
      sY[Y[i]]++;
    }

    if ((totWeights <= 1) && (nC > 1)) {
      throw new Exception("Sum of weights of instances less than 1, please reweight!");
    }

    xMean[0] = 0;
    xSD[0] = 1;
    for (int j = 1; j <= nR; j++) {
      xMean[j] = xMean[j] / totWeights;
      if (totWeights > 1) {
        xSD[j] = Math.sqrt(Math.abs(xSD[j] - totWeights * xMean[j] * xMean[j]) / (totWeights - 1));
      } else {
        xSD[j] = 0;
      }
    }

    if (m_Debug) {
      // Output stats about input data
      System.out.println("Descriptives...");
      for (int m = 0; m <= nK; m++) {
        System.out.println(sY[m] + " cases have class " + m);
      }
      System.out.println("\n Variable     Avg       SD    ");
      for (int j = 1; j <= nR; j++) {
        System.out.println(
            Utils.doubleToString(j, 8, 4)
                + Utils.doubleToString(xMean[j], 10, 4)
                + Utils.doubleToString(xSD[j], 10, 4));
      }
    }

    // Normalise input data
    for (int i = 0; i < nC; i++) {
      for (int j = 0; j <= nR; j++) {
        if (xSD[j] != 0) {
          m_Data[i][j] = (m_Data[i][j] - xMean[j]) / xSD[j];
        }
      }
    }

    if (m_Debug) {
      System.out.println("\nIteration History...");
    }

    double x[] = new double[(nR + 1) * nK];
    double[][] b = new double[2][x.length]; // Boundary constraints, N/A here

    // Initialize
    for (int p = 0; p < nK; p++) {
      int offset = p * (nR + 1);
      x[offset] = Math.log(sY[p] + 1.0) - Math.log(sY[nK] + 1.0); // Null model
      b[0][offset] = Double.NaN;
      b[1][offset] = Double.NaN;
      for (int q = 1; q <= nR; q++) {
        x[offset + q] = 0.0;
        b[0][offset + q] = Double.NaN;
        b[1][offset + q] = Double.NaN;
      }
    }

    OptObject oO = new OptObject();
    oO.setWeights(weights);
    oO.setClassLabels(Y);

    Optimization opt = null;
    if (m_useConjugateGradientDescent) {
      opt = new OptEngCG(oO);
    } else {
      opt = new OptEng(oO);
    }
    opt.setDebug(m_Debug);

    if (m_MaxIts == -1) { // Search until convergence
      x = opt.findArgmin(x, b);
      while (x == null) {
        x = opt.getVarbValues();
        if (m_Debug) {
          System.out.println("First set of iterations finished, not enough!");
        }
        x = opt.findArgmin(x, b);
      }
      if (m_Debug) {
        System.out.println(" -------------<Converged>--------------");
      }
    } else {
      opt.setMaxIteration(m_MaxIts);
      x = opt.findArgmin(x, b);
      if (x == null) {
        x = opt.getVarbValues();
      }
    }

    m_LL = -opt.getMinFunction(); // Log-likelihood

    // Don't need data matrix anymore
    m_Data = null;

    // Convert coefficients back to non-normalized attribute units
    for (int i = 0; i < nK; i++) {
      m_Par[0][i] = x[i * (nR + 1)];
      for (int j = 1; j <= nR; j++) {
        m_Par[j][i] = x[i * (nR + 1) + j];
        if (xSD[j] != 0) {
          m_Par[j][i] /= xSD[j];
          m_Par[0][i] -= m_Par[j][i] * xMean[j];
        }
      }
    }
  }