/* * RapidMiner * * Copyright (C) 2001-2008 by Rapid-I and the contributors * * Complete list of developers available at our web site: * * http://rapid-i.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.operator.performance; import java.awt.Component; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.swing.Icon; import com.rapidminer.gui.tools.SwingTools; import com.rapidminer.gui.viewer.PerformanceVectorViewer; import com.rapidminer.operator.IOContainer; import com.rapidminer.tools.LogService; import com.rapidminer.tools.Tools; import com.rapidminer.tools.math.Averagable; import com.rapidminer.tools.math.AverageVector; /** * Handles several performance criteria. It is possible to obtain more than one * criterion and therefore they are added to a criteria list. * * @author Ingo Mierswa, Simon Fischer * @version $Id: PerformanceVector.java,v 2.29 2006/03/21 15:35:51 ingomierswa * Exp $ */ public class PerformanceVector extends AverageVector { private static final long serialVersionUID = 3123587140049371098L; public static final String MAIN_CRITERION_FIRST = "first"; private static final String RESULT_ICON_NAME = "percent.png"; private static Icon resultIcon = null; static { resultIcon = SwingTools.createIcon("16/" + RESULT_ICON_NAME); } /** * The default performance comparator compares the main criterion of two * performance vectors. In case that the minimum description length (mdl) * criterion is also calculated and have a weight > 0 the weighted sums * of the main and the mdl criterion are compared. */ public static class DefaultComparator implements PerformanceComparator { private static final long serialVersionUID = 8632060851821885142L; public DefaultComparator() {} public int compare(PerformanceVector av1, PerformanceVector av2) { return av1.getMainCriterion().compareTo(av2.getMainCriterion()); } } /** This value map will only be intialized before writing this vector to a file. This * allows a quick human readable format in the resulting file. */ private Map<String, Double> currentValues = null; /** Used to compare two average vectors. */ private PerformanceComparator comparator = new DefaultComparator(); /** Name of the main criterion. */ private String mainCriterion = null; public void setComparator(PerformanceComparator comparator) { this.comparator = comparator; } public void addCriterion(PerformanceCriterion crit) { PerformanceCriterion pc = getCriterion(crit.getName()); if (pc != null) { removeAveragable(pc); LogService.getGlobal().log("Performance criterion '" + crit.getName() + "' was already part of performance vector. Overwritten...", LogService.WARNING); } addAveragable(crit); } public PerformanceCriterion getCriterion(int index) { return (PerformanceCriterion) getAveragable(index); } public PerformanceCriterion getCriterion(String name) { return (PerformanceCriterion) getAveragable(name); } public String[] getCriteriaNames() { String[] criteriaNames = new String[getSize()]; for (int i = 0; i < criteriaNames.length; i++) { criteriaNames[i] = getCriterion(i).getName(); } return criteriaNames; } /** * Sets the name of the main average (must be added by * {@link #addAveragable(Averagable)}) */ public void setMainCriterionName(String mcName) { if ((!mcName.equals(MAIN_CRITERION_FIRST)) && (getAveragable(mcName) == null)) { LogService.getGlobal().log("Main criterion not found: '" + mcName + "'.", LogService.ERROR); } this.mainCriterion = mcName; } /** * Returns the main {@link PerformanceCriterion}. If the main criterion is * not specified by {@link #setMainCriterionName(String)}, the first * criterion is returned. */ public PerformanceCriterion getMainCriterion() { if (mainCriterion == null) { return (PerformanceCriterion) getAveragable(0); } else { PerformanceCriterion pc = (PerformanceCriterion) getAveragable(mainCriterion); if (pc == null) return (PerformanceCriterion) getAveragable(0); return pc; } } /** Returns a negative value iff o is better than this performance vector */ public int compareTo(Object o) { double result = comparator.compare(this, (PerformanceVector) o); if (result < 0.0) return -1; else if (result > 0.0) return +1; else return 0; } public Object clone() throws CloneNotSupportedException { PerformanceVector av = new PerformanceVector(); for (int i = 0; i < size(); i++) { Averagable avg = getAveragable(i); av.addAveragable((Averagable) (avg).clone()); } return av; } public Component getVisualizationComponent(IOContainer container) { return new PerformanceVectorViewer(this, container); } public Icon getResultIcon() { return resultIcon; } public String toString() { StringBuffer result = new StringBuffer(Tools.getLineSeparator() + "PerformanceVector ["); for (int i = 0; i < size(); i++) { Averagable avg = getAveragable(i); if ((mainCriterion != null) && (avg.getName().equals(mainCriterion))) { result.append(Tools.getLineSeparator() + "*****"); } else { result.append(Tools.getLineSeparator() + "-----"); } result.append(avg); } result.append(Tools.getLineSeparator() + "]"); return result.toString(); } public String getExtension() { return "per"; } public String getFileDescription() { return "performance vector file"; } public void save(File file) throws IOException { FileOutputStream out = null; try { out = new FileOutputStream(file); super.write(out); } catch (IOException e) { throw e; } finally { if (out != null) out.close(); } } /** Init the value map which ensures an easy human readable format. */ public void initWriting() { this.currentValues = new HashMap<String, Double>(); for (int i = 0; i < size(); i++) { Averagable averagable = getAveragable(i); this.currentValues.put(averagable.getName(), averagable.getAverage()); } } }