/*
* Debellor
*
* Copyright (C) 2008-2009 by Marcin Wojnarski
*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package org.debellor.base.evaluator;
import org.debellor.base.evaluator.score.Accuracy;
import org.debellor.base.evaluator.score.RMSE;
import org.debellor.base.evaluator.score.Score;
import org.debellor.core.Cell;
import org.debellor.core.exception.parameters.IllegalParameterValueException;
import org.debellor.core.exception.parameters.ParameterUndefinedException;
/**
* <p>Base class for cells that implement evaluation of other cells -- decision systems.
* To run evaluation you must insert the evaluated cell with either {@link #EvaluatorCell(Cell)}
* or {@link #setInner(Cell)}, set the data source with {@link #setSource(Cell)}
* and call {@link #learn} which performs actual evaluation.
* Afterwards you may read the result with either {@link #result} or {@link #report}.
* If you want to use the same instance of <code>EvaluatorCell</code> to run another evaluation
* you must call {@link #erase} first.
* Note that usually the evaluated cell must be <i>erasable</i>
* (it must correctly override {@link Cell#onErase}).</p>
*
* <p>Parameters:</p>
* <ul>
* <li><i>score</i>: score type, name of the {@link Score} class to be used to measure
* quality of the evaluated decision system.
* Currently either "Accuracy" (for classification problems) or
* "RMSE" (root mean squared error, for regression problems).
* Default: "Accuracy". Score instance of a different type can be set manually
* with {@link #setScore(Score)}.
* Note that manual setting of Score instance takes effect only
* on the nearest invocation of <code>learn</code>, as opposed to specifying the score type
* through a parameter, which is effective on all consecutive calls to <code>learn</code>
* until the parameter is explicitly changed.
* </ul>
*
* @see TrainAndTest
* @see CrossValidation
*
* @author Marcin Wojnarski
*
*/
public class EvaluatorCell extends Cell {
protected Score score;
protected Score scoreFromUser;
protected Cell learner;
public EvaluatorCell() {}
public EvaluatorCell(Cell cell) {
setInner(cell);
}
/** Sets the cell - a decision system - that would undergo evaluation. */
public void setInner(Cell cell) {
learner = cell;
}
/**
* <p>Sets {@link Score} instance that will be used for calculation of a quality measure
* of the evaluated decision system.
* This method is an alternative for specifying the score type through
* the cell parameter "score", which is a preferred way of doing this.
* If both this method has been called and the parameter has been set,
* the score instance passed to this method is used.
* </p>
* <p>Supplied score instance will be used only in the nearest call to <code>learn</code>.
* The score will <i>not</i> be reset at the beginning of evaluation,
* so the user may supply a previously-used score, in order to accumulate
* results of different evaluations.
* </p>
*/
public void setScore(Score sc) {
scoreFromUser = sc;
}
protected void initScore() throws IllegalParameterValueException {
if(scoreFromUser != null) {
score = scoreFromUser;
scoreFromUser = null;
}
else {
String param;
try {
param = parameters.get("score");
}
catch (ParameterUndefinedException e) {
param = "Accuracy";
}
if(param.equals("Accuracy"))
score = new Accuracy();
else if(param.equals("RMSE"))
score = new RMSE();
else
throw new IllegalParameterValueException("score", param);
}
}
protected void releaseData() {
learner = null;
}
public Double[] result() {
Double[] r = new Double[1];
r[0] = score.result();
return r;
}
public String report() {
return score.report();
}
@Override
protected void onErase() throws Exception {
score = null;
}
}