Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   *   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/>.
  */
 
 /*
  *    FLDA.java
  *    Copyright (C) 2004, 2014 University of Waikato, Hamilton, New Zealand
  *
  */
 package weka.classifiers.functions;
 
 
 
 
Builds Fisher's Linear Discriminant function. The threshold is selected so that the separator is half-way between centroids. The class must be binary and all other attributes must be numeric. Missing values are not permitted. Constant attributes are removed using RemoveUseless. No standardization or normalization of attributes is performed.

Valid options are:

 -R
  The ridge parameter.
  (default is 1e-6)
 -output-debug-info
  If set, classifier is run in debug mode and
  may output additional info to the console
 -do-not-check-capabilities
  If set, classifier capabilities are not checked before classifier is built
  (use with caution).

Version:
$Revision: 10382 $
 
 public class FLDA extends AbstractClassifier {
  
  
for serialization
 
   static final long serialVersionUID = -9212385698193681291L;

  
Holds header of training date
 
   protected Instances m_Data;
  
  
The weight vector as a 1-dimensional matrix
 
   protected Matrix m_Weights;

  
The threshold
 
   protected double m_Threshold;

  
Ridge parameter
 
   protected double m_Ridge = 1e-6;

  
Rmeove useless filter
 
   protected RemoveUseless m_RemoveUseless;

  
Global info for this classifier.
 
   public String globalInfo() {
     return "Builds Fisher\'s Linear Discriminant function. The threshold is selected "
       + "so that the separator is half-way between centroids. The class must be "
       + "binary and all other attributes must be numeric. Missing values are not "
       + "permitted. Constant attributes are removed using RemoveUseless. No "
       + "standardization or normalization of attributes is performed.";
   }

  
Returns default capabilities of the classifier.

Returns:
the capabilities of this classifier
    Capabilities result = super.getCapabilities();
    result.disableAll();
    // attributes
    // class
    // instances
    result.setMinimumNumberInstances(0);
    
    return result;
  }

  
Computes the mean vector for each class.
  protected Matrix[] getClassMeans(Instances dataint[] counts) {
    
    double[][] centroids = new double[2][data.numAttributes() - 1];
    for (int i = 0; i < data.numInstances(); i++) {
      Instance inst = data.instance(i);
      int index = 0;
      for (int j = 0; j < data.numAttributes(); j++) {
        if (j != data.classIndex()) {
          centroids[(int)inst.classValue()][index++] += inst.value(j);
        } 
      }
      counts[(int)inst.classValue()] ++;
    }
    Matrix[] centroidMatrices = new Matrix[2];
    for (int i = 0; i < 2; i++) {
      centroidMatrices[i] = new Matrix(centroids[i], 1);
      centroidMatrices[i].timesEquals(1.0 / (double)counts[i]);
    }
    if () {
      ..println("Count for class 0: " + counts[0]);
      ..println("Centroid 0:" + centroidMatrices[0]); 
      ..println("Count for class 11: " + counts[1]);
      ..println("Centroid 1:" + centroidMatrices[1]); 
    }
    return centroidMatrices;
  } 
  
  
Computes centered subsets as matrix.
  protected Matrix[] getCenteredData(Instances dataint[] countsMatrix[] centroids) {
    Matrix[] centeredData = new Matrix[2];
    for (int i = 0; i < 2; i++) {
      centeredData[i] = new Matrix(counts[i], data.numAttributes() - 1);
    }
    int[] indexC = new int[2];
    for (int i = 0; i < data.numInstances(); i++) {
      Instance inst = data.instance(i);
      int classIndex = (int)inst.classValue();
      int index = 0;
      for (int j = 0; j < data.numAttributes(); j++) {
        if (j != data.classIndex()) {
          centeredData[classIndex].set(indexC[classIndex], index
                                       inst.value(j) - centroids[classIndex].get(0, index)); 
          index++;
        }
      }
      indexC[classIndex]++;
    }
    if () {
      ..println("Centered data for class 0:\n" + centeredData[0]); 
      ..println("Centered data for class 1:\n" + centeredData[1]); 
    }
    return centeredData;
  }

  
Builds the classifier.
  public void buildClassifier(Instances inststhrows Exception {
    // can classifier handle the data?
    // Remove constant attributes
     = new RemoveUseless();
    insts = Filter.useFilter(insts);
    insts.deleteWithMissingClass();
    // Establish class frequencies and centroids
    int[] classCounts = new int[2];
    Matrix[] centroids = getClassMeans(instsclassCounts);
    // Compute difference of centroids
    Matrix diff = centroids[0].minus(centroids[1]);
    // Center data for each class
    Matrix[] data = getCenteredData(instsclassCountscentroids);
    // Computer scatter matrix and add ridge
    Matrix scatter = data[0].transpose().times(data[0]).plus(data[1].transpose().times(data[1]));
    scatter.plusEquals(Matrix.identity(insts.numAttributes() - 1, insts.numAttributes() - 1).timesEquals());
    if () {
      ..println("Scatter:\n" + scatter);
    }
    // Establish and normalize weight vector
     = scatter.inverse().times(diff.transpose());
    // Computer threshold
     = 0.5 * .transpose().times(centroids[0].transpose().plus(centroids[1].transpose())).get(0,0);
    // Store header only
     = new Instances(insts, 0);
  }   
    
  
Output class "probabilities". These need to be calibrated.
  public double[] distributionForInstance(Instance instthrows Exception {
    
    // Filter instance
    .input(inst);
    inst = .output();
    
    // Convert instance to matrix
    Matrix instM = new Matrix(1, inst.numAttributes() - 1);
    int index = 0;
    for (int i = 0; i < inst.numAttributes(); i++) {
      if (i != .classIndex()) {
        instM.set(0, index++, inst.value(i));
      }
    }
    // Pipe output through sigmoid
    double[] dist = new double[2];
    dist[1] = 1/(1 + Math.exp(instM.times().get(0, 0) - ));
    dist[0] = 1 - dist[1];
    return dist;
  }
    
  public String toString() {
    if ( == null) {
      return "No model has been built yet.";
    }
    StringBuffer result = new StringBuffer();
    result.append("Fisher's Linear Discriminant Analysis\n\n");
    result.append("Threshold: " +  + "\n\n");
    result.append("Weights:\n\n");
    int index = 0;
    for (int i = 0; i < .numAttributes(); i++) {
      if (i != .classIndex()) {
        result.append(.attribute(i).name() + ": \t");
        double weight = .get(index++, 0);
        if (weight >= 0) {
          result.append(" ");
        }
        result.append(weight + "\n");
      }
    }
    return result.toString();
  }  

  
Returns the tip text for this property

Returns:
tip text for this property suitable for displaying in the explorer/experimenter gui
  public String ridgeTipText() {
    return "The value of the ridge parameter.";
  }

  
Get the value of Ridge.

Returns:
Value of Ridge.
  public double getRidge() {
    return ;
  }

  
Set the value of Ridge.

Parameters:
newRidge Value to assign to Ridge.
  public void setRidge(double newRidge) {
     = newRidge;
  }

  
Returns an enumeration describing the available options.

Returns:
an enumeration of all the available options.
  public Enumeration<OptionlistOptions() {
    Vector<OptionnewVector = new Vector<Option>(7);
    newVector.addElement(new Option(
	      "\tThe ridge parameter.\n"+
	      "\t(default is 1e-6)",
	      "R", 0, "-R"));
    newVector.addAll(Collections.list(super.listOptions()));
    
    return newVector.elements();
  }

  
Parses a given list of options.

Valid options are:

 -R
  The ridge parameter.
  (default is 1e-6)
 -output-debug-info
  If set, classifier is run in debug mode and
  may output additional info to the console
 -do-not-check-capabilities
  If set, classifier capabilities are not checked before classifier is built
  (use with caution).

Parameters:
options the list of options as an array of strings
Throws:
java.lang.Exception if an option is not supported
  public void setOptions(String[] optionsthrows Exception {
    
    String ridgeString = Utils.getOption('R'options);
    if (ridgeString.length() != 0) {
      setRidge(Double.parseDouble(ridgeString));
    } else {
      setRidge(1e-6);
    }
    
    super.setOptions(options);
    
    Utils.checkForRemainingOptions(options);
  }

  
Gets the current settings of IBk.

Returns:
an array of strings suitable for passing to setOptions()
  public String [] getOptions() {
    Vector<Stringoptions = new Vector<String>();
    options.add("-R"); options.add("" + getRidge());
    
    Collections.addAll(optionssuper.getOptions());
    
    return options.toArray(new String[0]);
  }

  
Returns the revision string.

Returns:
the revision
    public String getRevision() {
    return RevisionUtils.extract("$Revision: 10382 $");
  }
  
  
Generates an FLDA classifier.

Parameters:
argv the options
  public static void main(String [] argv){  
    runClassifier(new FLDA(), argv);
  }
New to GrepCode? Check out our FAQ X