/*
* RapidMiner
*
* Copyright (C) 2001-2014 by RapidMiner and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapidminer.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.learner.functions.kernel;
import java.util.List;
import com.rapidminer.example.Attribute;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.operator.OperatorDescription;
import com.rapidminer.operator.OperatorException;
import com.rapidminer.operator.UserError;
import com.rapidminer.operator.annotation.ResourceConsumptionEstimator;
import com.rapidminer.operator.learner.functions.kernel.jmysvm.examples.SVMExamples;
import com.rapidminer.operator.learner.functions.kernel.jmysvm.kernel.Kernel;
import com.rapidminer.operator.learner.functions.kernel.jmysvm.svm.SVMInterface;
import com.rapidminer.operator.learner.functions.kernel.jmysvm.svm.SVMpattern;
import com.rapidminer.operator.learner.functions.kernel.jmysvm.svm.SVMregression;
import com.rapidminer.operator.performance.EstimatedPerformance;
import com.rapidminer.operator.performance.PerformanceVector;
import com.rapidminer.parameter.ParameterType;
import com.rapidminer.parameter.ParameterTypeBoolean;
import com.rapidminer.parameter.ParameterTypeDouble;
import com.rapidminer.tools.OperatorResourceConsumptionHandler;
import com.rapidminer.tools.RandomGenerator;
/**
* This learner uses the Java implementation of the support vector machine
* <em>mySVM</em> by Stefan Rüping. This learning method can be used for
* both regression and classification and provides a fast algorithm and good
* results for many learning tasks.
*
* @rapidminer.reference Rueping/2000a
* @rapidminer.reference Vapnik/98a
* @rapidminer.index SVM
*
* @author Ingo Mierswa
*/
public class JMySVMLearner extends AbstractMySVMLearner {
/** The parameter name for "Indicates if this learner should also return a performance estimation." */
public static final String PARAMETER_ESTIMATE_PERFORMANCE = "estimate_performance";
/** The parameter name for "A factor for the SVM complexity constant for positive examples" */
public static final String PARAMETER_L_POS = "L_pos";
/** The parameter name for "A factor for the SVM complexity constant for negative examples" */
public static final String PARAMETER_L_NEG = "L_neg";
/** The parameter name for "Insensitivity constant. No loss if prediction lies this close to true value" */
public static final String PARAMETER_EPSILON = "epsilon";
/** The parameter name for "Epsilon for positive deviation only" */
public static final String PARAMETER_EPSILON_PLUS = "epsilon_plus";
/** The parameter name for "Epsilon for negative deviation only" */
public static final String PARAMETER_EPSILON_MINUS = "epsilon_minus";
/** The parameter name for "Adapts Cpos and Cneg to the relative size of the classes" */
public static final String PARAMETER_BALANCE_COST = "balance_cost";
/** The parameter name for "Use quadratic loss for positive deviation" */
public static final String PARAMETER_QUADRATIC_LOSS_POS = "quadratic_loss_pos";
/** The parameter name for "Use quadratic loss for negative deviation" */
public static final String PARAMETER_QUADRATIC_LOSS_NEG = "quadratic_loss_neg";
public JMySVMLearner(OperatorDescription description) {
super(description);
}
/** Indicates if the SVM is used for classification learning. */
private boolean pattern = true;
@Override
public boolean shouldEstimatePerformance() {
return getParameterAsBoolean(PARAMETER_ESTIMATE_PERFORMANCE);
}
@Override
public boolean canEstimatePerformance() {
return true;
}
/**
* Returns the estimated performances of this SVM. Does only work for
* classification tasks.
*/
@Override
public PerformanceVector getEstimatedPerformance() throws OperatorException {
if (!pattern)
throw new UserError(this, 912, this, "Cannot calculate leave one out estimation of error for regression tasks!");
double[] estVector = ((SVMpattern) getSVM()).getXiAlphaEstimation(getKernel());
PerformanceVector pv = new PerformanceVector();
pv.addCriterion(new EstimatedPerformance("xialpha_error", estVector[0], 1, true));
pv.addCriterion(new EstimatedPerformance("xialpha_precision", estVector[1], 1, false));
pv.addCriterion(new EstimatedPerformance("xialpha_recall", estVector[2], 1, false));
pv.setMainCriterionName("xialpha_error");
return pv;
}
@Override
public AbstractMySVMModel createSVMModel(ExampleSet exampleSet, SVMExamples sVMExamples, Kernel kernel, int kernelType) {
return new JMySVMModel(exampleSet, sVMExamples, kernel, kernelType);
}
@Override
public SVMInterface createSVM(Attribute label, Kernel kernel, SVMExamples sVMExamples, com.rapidminer.example.ExampleSet rapidMinerExamples) throws OperatorException {
if (label.isNominal()) {
this.pattern = true;
return new SVMpattern(this, kernel, sVMExamples, rapidMinerExamples, RandomGenerator.getGlobalRandomGenerator());
} else {
this.pattern = false;
return new SVMregression(this, kernel, sVMExamples, rapidMinerExamples, RandomGenerator.getGlobalRandomGenerator());
}
}
@Override
public List<ParameterType> getParameterTypes() {
List<ParameterType> types = super.getParameterTypes();
types.add(new ParameterTypeDouble(PARAMETER_L_POS, "A factor for the SVM complexity constant for positive examples", 0, Double.POSITIVE_INFINITY, 1.0d));
types.add(new ParameterTypeDouble(PARAMETER_L_NEG, "A factor for the SVM complexity constant for negative examples", 0, Double.POSITIVE_INFINITY, 1.0d));
types.add(new ParameterTypeDouble(PARAMETER_EPSILON, "Insensitivity constant. No loss if prediction lies this close to true value", 0.0d, Double.POSITIVE_INFINITY, 0.0d));
types.add(new ParameterTypeDouble(PARAMETER_EPSILON_PLUS, "Epsilon for positive deviation only", 0.0d, Double.POSITIVE_INFINITY, 0.0d));
types.add(new ParameterTypeDouble(PARAMETER_EPSILON_MINUS, "Epsilon for negative deviation only", 0.0d, Double.POSITIVE_INFINITY, 0.0d));
types.add(new ParameterTypeBoolean(PARAMETER_BALANCE_COST, "Adapts Cpos and Cneg to the relative size of the classes", false));
types.add(new ParameterTypeBoolean(PARAMETER_QUADRATIC_LOSS_POS, "Use quadratic loss for positive deviation", false));
types.add(new ParameterTypeBoolean(PARAMETER_QUADRATIC_LOSS_NEG, "Use quadratic loss for negative deviation", false));
// deprecated parameters
ParameterType type = new ParameterTypeBoolean(PARAMETER_ESTIMATE_PERFORMANCE, "Indicates if this learner should also return a performance estimation.", false);
type.setDeprecated();
types.add(type);
return types;
}
@Override
public ResourceConsumptionEstimator getResourceConsumptionEstimator() {
return OperatorResourceConsumptionHandler.getResourceConsumptionEstimator(getExampleSetInputPort(), JMySVMLearner.class, null);
}
}