parameteroptimizationoperator.java

来自「一个很好的LIBSVM的JAVA源码。对于要研究和改进SVM算法的学者。可以参考」· Java 代码 · 共 207 行

JAVA
207
字号
/*
 *  YALE - Yet Another Learning Environment
 *  Copyright (C) 2001-2004
 *      Simon Fischer, Ralf Klinkenberg, Ingo Mierswa, 
 *          Katharina Morik, Oliver Ritthoff
 *      Artificial Intelligence Unit
 *      Computer Science Department
 *      University of Dortmund
 *      44221 Dortmund,  Germany
 *  email: yale-team@lists.sourceforge.net
 *  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;

import edu.udo.cs.yale.operator.parameter.*;
import edu.udo.cs.yale.operator.performance.PerformanceCriterion;
import edu.udo.cs.yale.operator.performance.PerformanceVector;
import edu.udo.cs.yale.tools.LogService;
import edu.udo.cs.yale.tools.ParameterService;

import java.util.*;
import java.io.*;
import java.awt.Component;
import javax.swing.JLabel;

/** This operator finds the optimal values for a set of parameters. The parameter
 *  <var>parameters</var> is a list of key value pairs where the keys are of the form
 *  <code>OperatorName.parameter_name</code> and the value is a comma separated list of
 *  values.
 *  <br/>
 *  The operator returns an optimal {@link ParameterSet} which can as well be written to a file and 
 *  read in another experiment using an {@link edu.udo.cs.yale.operator.io.ParameterSetLoader} and the
 *  {@link PerformanceVector} of the best run.
 *  <br/>
 *  The file format of the parameter set file is straightforward and can easily be
 *  generated by foreign applications. Each line is of the form
 *  <center><code>OperatorName.parameter_name = value</code></center>
 *  <br/>
 *  Please refer to 
 *  section {@yale.ref sec:parameter_optimization|Advanced experiments/Parameter and performance analysis} 
 *  for an example application. 
 *
 *  @yale.xmlclass ParameterOptimization
 *  @author Simon
 *  @version $Id: ParameterOptimizationOperator.java,v 2.15 2004/08/27 11:57:34 ingomierswa Exp $
 */
public class ParameterOptimizationOperator extends OperatorChain {

    private static final Class[] OUTPUT_CLASSES = { ParameterSet.class, PerformanceVector.class };

    private ParameterSet best;
    private int numberOfCombinations = 0;

	public ParameterOptimizationOperator() {
		addValue(new Value("performance", "best performance") {
				public double getValue() {
					if (best != null)
						return best.getPerformance().getMainCriterion().getValue();
					else
						return Double.NaN;
				}
				});
	}

    public IOObject[] apply() throws OperatorException {

	IOContainer input = getInput();

	List parameterList = getParameterList("parameters");
	Operator[] operators  = new Operator[parameterList.size()];
	String[]   parameters = new String[parameterList.size()];
	String[][] values     = new String[parameterList.size()][];
	int[] currentIndex    = new int[parameterList.size()];
	Iterator i = parameterList.iterator();
	int index = 0;
	numberOfCombinations = 1;
	while (i.hasNext()) {
	    Object[] keyValue  = (Object[])i.next();
	    String[] parameter = ((String)keyValue[0]).split("\\.");
	    if (parameter.length != 2) 
		throw new UserError(this, 907, keyValue[0]);
	    Operator operator = getExperiment().getOperator(parameter[0]);
	    if (operator == null) 
		throw new UserError(this, 109, parameter[0]);
	    operators[index]  = operator;
	    parameters[index] = parameter[1];
	    ParameterType targetType = operators[index].getParameters().getParameterType(parameters[index]);
	    if (targetType == null) {
		throw new UserError(this, 906, parameter[0]+"."+parameter[1]);
	    }
	    if (!(targetType instanceof ParameterTypeSingle)) {
		throw new UserError(this, 908, parameter[0]+"."+parameter[1]);
	    }
	    values[index] = ((String)keyValue[1]).split(",");
	    numberOfCombinations *= values[index].length;
	    index++;
	}

	best = null;
	while (true) {
	    LogService.logMessage("Using parameter set", LogService.TASK);
	    // set all parameter values
	    for (int j = 0; j < operators.length; j++) {
		operators[j].getParameters().setParameter(parameters[j], values[j][currentIndex[j]]);
		LogService.logMessage(operators[j]+"."+parameters[j]+
				      " = " + values[j][currentIndex[j]], LogService.TASK);
	    }
	    
	    setInput(input.copy());
	    PerformanceVector performance = getPerformance();
	    if ((best == null) || (performance.compareTo(best.getPerformance()) > 0)) {
		String[] bestValues     = new String[parameters.length];
		for (int j = 0; j < parameters.length; j++) {
		    bestValues[j]     = values[j][currentIndex[j]];
		}
		best = new ParameterSet(operators, parameters, bestValues, performance);
	    }

	    // next parameter values
	    int k = 0;
	    boolean ok = true;
	    while (!(++currentIndex[k] < values[k].length)) {
		currentIndex[k] = 0;
		k++;
		if (k >= currentIndex.length) {
		    ok = false;
		    break;
		}
	    }
	    if (!ok) break;

	    inApplyLoop();
	}
	
	String parameterFile = getParameterAsString("parameter_file");
	if (parameterFile != null) {
	    try {
		LogService.logMessage("Writing parameter file: '"+parameterFile+"'", LogService.TASK);
		best.write(new PrintWriter(new FileWriter(getExperiment().resolveFileName(parameterFile))));
	    } catch (IOException e) {
		LogService.logMessage("Cannot write parameter file: '"+parameterFile+"'", LogService.ERROR);
	    }
	}

	return new IOObject[] { best, best.getPerformance() };
    }

    /** Applies the inner operator and employs the PerformanceEvaluator for calculating a list
     *  of performance criteria which is returned. */
    private PerformanceVector getPerformance() throws OperatorException {
	IOObject[] evalout = super.apply();
	IOContainer evalCont = new IOContainer(evalout);
	return (PerformanceVector)evalCont.getInput(PerformanceVector.class);
    }

    public Class[] getInputClasses() {
	return new Class[0];
    }

    public Class[] getOutputClasses() {
	return OUTPUT_CLASSES;
    }

    public Class[] checkIO(Class[] input) throws IllegalInputException {
	for (int i = 0; i < getNumberOfOperators(); i++) {
	    Operator o = getOperator(i);
	    input = o.checkIO(input);
	}
	return OUTPUT_CLASSES;
    }


    /** Returns the highest possible value for the maximum number of innner operators. */
    public int getMaxNumberOfInnerOperators() { return Integer.MAX_VALUE; }
    /** Returns 1 for the minimum number of innner operators. */
    public int getMinNumberOfInnerOperators() { return 1; }

    public int getNumberOfSteps() {
	return numberOfCombinations * (getNumberOfChildrensSteps() + 1);
    }

    public List getParameterTypes() {
	List types = super.getParameterTypes();
	ParameterType type = new ParameterTypeList("parameters", "A list of parameters to optimize", 
						   new ParameterTypeString("value", "The values of the parameter (comma-separated"));
	type.setExpert(false);
	types.add(type);
	types.add(new ParameterTypeFile("parameter_file", "A file that the optimal parameter set will be written to.", true));
	return types;
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?