📄 performancecriterion.java
字号:
/* * YALE - Yet Another Learning Environment * Copyright (C) 2002, 2003 * Simon Fischer, Ralf Klinkenberg, Ingo Mierswa, * Katharina Morik, Oliver Ritthoff * Artificial Intelligence Unit * Computer Science Department * University of Dortmund * 44221 Dortmund, Germany * email: yale@ls8.cs.uni-dortmund.de * web: http://yale.cs.uni-dortmund.de/ * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */package edu.udo.cs.yale.operator.performance;import edu.udo.cs.yale.example.ExampleSet;import edu.udo.cs.yale.example.Example;import edu.udo.cs.yale.tools.LogService;import edu.udo.cs.yale.operator.ResultObjectAdapter;import java.util.*;import java.text.*;/** Each <tt>PerformanceCriterion</tt> contains a method to compute this * criterion on a given set of examples, each which has to have a real and a * predicted label. * <br> * PerformanceCriteria must implement the <tt>compareTo</tt> method in a way that * allows <tt>Collections</tt> to sort the criteria in ascending order and * determine the best as the maximum. * * @author Ingo * @version $Id: PerformanceCriterion.java,v 2.9 2003/05/14 13:33:20 fischer Exp $ */public abstract class PerformanceCriterion extends ResultObjectAdapter implements Cloneable, Comparable { /** Used for formatting values in the {@link #toString()} method. */ private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance(); /** Used for formatting values in the {@link #formatValue(double)} method. */ private static final NumberFormat PERCENT_FORMAT = NumberFormat.getPercentInstance(); static { PERCENT_FORMAT.setMaximumFractionDigits(2); NUMBER_FORMAT.setMaximumFractionDigits(3); } /** The averages are summed up each time buildAverage is called. */ private double meanSum = Double.NaN; /** The squared averages are summed up each time buildAverage is called. */ private double meanSquaredSum = Double.NaN; /** Counts the number of times, build average was executed. */ private int averageCount = 0; /** Returns the name of this performance criterion. */ public abstract String getName(); /** Returns the fitness depending on the value. */ public abstract double getFitness(); /** Returns the value of the performance criterion. */ public abstract double getValue(); /** Returns the variance of the performance criterion. */ public abstract double getVariance(); /** Returns the maximum fitness. The default implementation resturns POSITIVE_INFINITY, subclasses may override * this to allow feature operators to end the optimization if the maximum was reached. */ public double getMaxFitness() { return Double.POSITIVE_INFINITY; } /** This method builds the average of two performance criteria of the same type. * First this method checks if the classes of <code>this</code> and * <code>performance</code> are the same and if the * {@link PerformanceCriterion#getName()} methods return the same String. Otherwise * a RuntimeException is thrown. * <br> * The values of <code>performance.</code>{@link PerformanceCriterion#getValue()} is added to * {@link PerformanceCriterion#meanSum}, its square is added to * {@link PerformanceCriterion#meanSquaredSum} and * {@link PerformanceCriterion#averageCount} is increased by one. These * values are used in the {@link PerformanceCriterion#getMakroAverage()} and * {@link PerformanceCriterion#getMakroVariance()} methods. * <br> * Subclasses should implement this method to build the weighted average of * <code>this</code> measured performance and <code>performance</code>. The * must be weighted by the number of examples used for calculating the * criteria. Sublclasses <code>must</code> call <code>super.buildAverage</code> * before they do anything that changes the return value of * <code>performance.</code>{@link PerformanceCriterion#getValue()}! */ public void buildAverage(PerformanceCriterion performance) { if (!performance.getClass().equals(this.getClass())) throw new RuntimeException("Cannot build average of different criterion types ("+ this.getClass().getName()+"/"+performance.getClass().getName()+")."); if (!performance.getName().equals(this.getName())) throw new RuntimeException("Cannot build average of different criterion types ("+ this.getName()+"/"+performance.getName()+")."); if (averageCount == 0) { // count yourself double value = this.getValue(); meanSum = value; meanSquaredSum = value*value; averageCount = 1; } double value = performance.getValue(); meanSum += value; meanSquaredSum += value*value; averageCount++; } /** Returns the standard deviation of the performance criterion. */ public double getStandardDeviation() { double variance = getVariance(); if (Double.isNaN(variance)) return Double.NaN; else return Math.sqrt(variance); } /** Returns the average value of all performance criteria average by using the * {@link PerformanceCriterion#buildAverage(PerformanceCriterion)} method. */ public double getMakroAverage() { return meanSum / averageCount; } /** Returns the variance of all performance criteria average by using the * {@link PerformanceCriterion#buildAverage(PerformanceCriterion)} method. */ public double getMakroVariance() { double mean = getMakroAverage(); return meanSquaredSum / averageCount - mean * mean; } /** Returns the standard deviation of all performance criteria average by using the * {@link PerformanceCriterion#buildAverage(PerformanceCriterion)} method. */ public double getMakroStandardDeviation() { return Math.sqrt(getMakroVariance()); } /** Returns a (deep) clone of this performance criterion. */ public Object clone() { try { Class clazz = this.getClass(); PerformanceCriterion clone = (PerformanceCriterion)clazz.newInstance(); clone.clonePerformanceCriterion(this); return clone; } catch (Exception e) { LogService.logException("In PerformanceCriterion.clone():", e); return null; } } /** Must be implemented by subclasses such that it copies * all values of <code>other</code> to <code>this</code>. * When this method is called, it is guaranteed, that <code>other</code> is a subclass * of the class of the object it is called on. * The default implementation does nothing. */ void clonePerformanceCriterion(PerformanceCriterion other) { this.meanSum = other.meanSum; this.meanSquaredSum = other.meanSquaredSum; this.averageCount = other.averageCount; } /** * The semantics of this method follow the specification in the interface * <tt>java.lang.Comparable</tt> in the following way: Two objects of this * class are equal if their <b>getFitness()</b> values are equal. The return * value is 0 in this case. If the specified object is not an object of this * class, a ClassCastException is thrown. If the given object has fitness bigger than this * object, the return value is -1. If the given object has fitness smaller than * this object, 1 is returned. No attributes other than error are used to * compare two objects of this class! * * @param o Object of this class to compare this object to. * @return -1, 0 or 1 if the specified object is greater than, equal to, or * less than this object. */ public int compareTo(Object o) { if (!this.getClass().equals(o.getClass())) throw new RuntimeException("Mismatched criterion class:"+this.getClass()+", "+o.getClass()); PerformanceCriterion pc = (PerformanceCriterion)o; if (!pc.getName().equals(this.getName())) throw new RuntimeException("Mismatched criterion type:"+this.getName()+", "+pc.getName()); if (this.getFitness() < pc.getFitness()) { return -1; } else if (this.getFitness() > pc.getFitness()) { return 1; } else { return 0; } } /** Indicates wether or not percentage format should be used in the * {@link #toString} method. The default implementation returns false. */ public boolean formatPercent() { return false; } /** Formats the value for the {@link #toString()} method. */ private String formatValue(double value) { if (formatPercent()) { return PERCENT_FORMAT.format(value); } else { return NUMBER_FORMAT.format(value); } } /** Formats the standard deviation for the {@link #toString()} method. */ private String formatDeviation(double dev) { if (formatPercent()) { return NUMBER_FORMAT.format(dev*100.0); } else { return NUMBER_FORMAT.format(dev); } } public String toString() { String str = getName()+": "+formatValue(getValue()); double sd = getStandardDeviation(); if (!Double.isNaN(sd)) str += " +/- "+formatDeviation(sd); if (averageCount > 0) { str += " (makro avg: "+formatValue(getMakroAverage()); sd = getMakroStandardDeviation(); if (!Double.isNaN(sd)) str += " +/- "+formatDeviation(sd); str += ")"; } return str; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -