📄 quadraticparameteroptimizationoperator.java
字号:
/*
* 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;
import Jama.*;
import java.lang.Double;
import java.lang.Math.*;
/** This operator finds the optimal values for a set of parameters using a quadratic
* interaction model. 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>
*
* @yale.xmlclass QuadraticParameterOptimization
* @author Stefan Rueping, Helge Homburg
* @version $Id: QuadraticParameterOptimizationOperator.java,v 2.9 2004/08/27 11:57:34 ingomierswa Exp $
*/
public class QuadraticParameterOptimizationOperator extends OperatorChain {
private static final Class[] OUTPUT_CLASSES = { ParameterSet.class, PerformanceVector.class };
private static final String[] EXCEED_BEHAVIORS = { "ignore", "clip", "fail" };
private static final int IGNORE = 0;
private static final int CLIP = 1;
private static final int FAIL = 2;
private ParameterSet best;
private int numberOfCombinations = 0;
private double param2coded(String value, double base) {
double res = Double.parseDouble(value);
return Math.log(res)/Math.log(base);
};
/** Inverse of param2coded. */
private String coded2param(double value, double base) {
return Double.toString(Math.exp(Math.log(base)*value));
};
public IOObject[] apply() throws OperatorException {
IOContainer input = getInput();
List parameterList = getParameterList("parameters");
Operator[] operators = new Operator[parameterList.size()];
String[] parameters = new String[parameterList.size()];
double[] logBase = new double[parameterList.size()];
String[][] values = new String[parameterList.size()][];
Iterator iter = parameterList.iterator();
int index = 0;
numberOfCombinations = 1;
while (iter.hasNext()) {
Object[] keyValue = (Object[])iter.next();
String[] parameter = ((String)keyValue[0]).split("\\.");
if ((parameter.length < 2) || (parameter.length > 3))
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 ParameterTypeNumber)) {
throw new UserError(this, 909, parameter[0]+"."+parameter[1]);
}
if (parameter.length == 2) {
logBase[index] = 2.0;
} else {
try {
logBase[index] = Double.parseDouble(parameter[2]);
} catch (NumberFormatException e) {
throw new UserError(this, 907, keyValue[0]);
}
}
values[index] = ((String)keyValue[1]).split(",");
numberOfCombinations *= values[index].length;
index++;
}
int ifExceedsRegion = getParameterAsInt("if_exceeds_region");
int ifExceedsRange = getParameterAsInt("if_exceeds_range");
int[] currentIndex = new int[parameterList.size()];
// sort parameter values
String[] valuesToSort;
String s;
double val1;
double val2;
int ind1;
int ind2;
for(index=0;index<parameterList.size();index++){
valuesToSort = values[index];
// straight-insertion-sort of valuesToSort
for(ind1=0;ind1<valuesToSort.length;ind1++){
val1 = Double.parseDouble(valuesToSort[ind1]);
for(ind2=ind1+1;ind2<valuesToSort.length;ind2++){
val2 = Double.parseDouble(valuesToSort[ind2]);
if(val1 > val2){
s = valuesToSort[ind1];
valuesToSort[ind1] = valuesToSort[ind2];
valuesToSort[ind2] = s;
val1 = val2;
};
};
};
};
best = null;
int[] bestIndex = new int[parameterList.size()];
ParameterSet[] allParameters = new ParameterSet[numberOfCombinations];
int paramIndex=0;
// Test all parameter combinations
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();
String[] currentValues = new String[parameters.length];
for (int j = 0; j < parameters.length; j++) {
currentValues[j] = values[j][currentIndex[j]];
};
allParameters[paramIndex] = new ParameterSet(operators, parameters, currentValues, performance);
if ((best == null) || (performance.compareTo(best.getPerformance()) > 0)) {
best = allParameters[paramIndex];
// bestIndex = currentIndex; geht das?
for(int j = 0;j<parameterList.size();j++){
bestIndex[j] = currentIndex[j];
};
};
// 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;
paramIndex++;
};
// start quadratic optimization
int nrParameters=0;
for(int i=0;i<parameterList.size();i++){
if((values[i]).length > 2){
LogService.logMessage("Param "+i+", bestI = "+bestIndex[i], LogService.MINIMUM);
nrParameters++;
if(bestIndex[i] == 0){
bestIndex[i]++;
};
if(bestIndex[i] == (values[i]).length -1){
bestIndex[i]--;
};
}
else{
LogService.logMessage("Parameter "+parameters[i]+" has <3 values, skipped.", LogService.WARNING);
};
};
if(nrParameters>3){
LogService.logMessage("Optimization not recommended for >3 values. Check results carefully!", LogService.WARNING);
};
if(nrParameters>0){
// Designmatrix A f?r den 3^nrParameters-Plan aufstellen,
// A*x=y l?sen lassen
// x = neue Parameter
// check, ob neuen Parameter in zul?ssigem Bereich
// - Okay, wenn in Kubus von 3^k-Plan
// - Warnung wenn in gegebenem Parameter-Bereich
// - Fehler sonst
int threetok=1;
for(int i=0;i<nrParameters;i++){ threetok *= 3; };
LogService.logMessage("Optimising "+nrParameters+" parameters", LogService.MINIMUM);
Matrix Designmatrix = new Matrix(threetok,nrParameters+nrParameters*(nrParameters+1)/2+1);
Matrix y = new Matrix(threetok,1);
paramIndex = 0;
for(int i=parameterList.size()-1;i>=0;i--){
if((values[i]).length > 2){
currentIndex[i] = bestIndex[i]-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -