/*
* File: EvaluatorToCategorizerAdapter.java
* Authors: Justin Basilico
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright December 20, 2007, Sandia Corporation.
* Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
* license for use of this work by or on behalf of the U.S. Government. Export
* of this program may require a license from the United States Government.
* See CopyrightHistory.txt for complete details.
*
*/
package gov.sandia.cognition.learning.function.categorization;
import gov.sandia.cognition.evaluator.Evaluator;
import gov.sandia.cognition.learning.algorithm.AbstractBatchLearnerContainer;
import gov.sandia.cognition.learning.algorithm.BatchLearner;
import gov.sandia.cognition.learning.algorithm.SupervisedBatchLearner;
import gov.sandia.cognition.learning.data.InputOutputPair;
import gov.sandia.cognition.util.AbstractCloneableSerializable;
import gov.sandia.cognition.util.ObjectUtil;
import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;
/**
* The {@code EvaluatorToCategorizerAdapter} class implements an adapter from a
* general {@code Evaluator} to be a {@code Categorizer}. This is done by just
* having a reference to the evaluator plus a field to store the list of
* possible output categories.
*
* @param <InputType> The type of the input to categorize.
* @param <CategoryType> The type of the output categories.
* @author Justin Basilico
* @since 2.0
*/
public class EvaluatorToCategorizerAdapter<InputType, CategoryType>
extends AbstractCategorizer<InputType, CategoryType>
{
/** The evaluator that is being wrapped into a categorizer. */
private Evaluator<? super InputType, ? extends CategoryType> evaluator;
/**
* Creates a new {@code EvaluatorToCategorizerAdapter}.
*/
public EvaluatorToCategorizerAdapter()
{
this(null, new TreeSet<CategoryType>());
}
/**
* Creates a new {@code EvaluatorToCategorizerAdapter}.
*
* @param evaluator The evaluator to turn into a categorizer.
* @param categories The list of possible output categories.
*/
public EvaluatorToCategorizerAdapter(
final Evaluator<? super InputType, ? extends CategoryType> evaluator,
final Set<CategoryType> categories)
{
super(categories);
this.setEvaluator(evaluator);
}
public CategoryType evaluate(
final InputType input)
{
return this.evaluator.evaluate(input);
}
/**
* Gets the evaluator that is to be adapted to be a categorizer.
*
* @return The evaluator to adapt.
*/
public Evaluator<? super InputType, ? extends CategoryType> getEvaluator()
{
return evaluator;
}
/**
* Sets the evaluator that is to be adapted to be a categorizer.
*
* @param evaluator The evaluator to adapt.
*/
public void setEvaluator(
final Evaluator<? super InputType, ? extends CategoryType> evaluator)
{
this.evaluator = evaluator;
}
@Override
public void setCategories(
final Set<CategoryType> categories)
{
super.setCategories(categories);
}
/**
* The {@code EvaluatorToCategorizerAdapter.Learner} class implements a
* simple supervised learner for a {@code EvaluatorToCategorizerAdapter}.
*
* @param <InputType> The type of the input values.
* @param <CategoryType> The type of the output categories.
*/
public static class Learner<InputType, CategoryType>
extends AbstractBatchLearnerContainer<BatchLearner<? super Collection<? extends InputOutputPair<? extends InputType, CategoryType>>, ? extends Evaluator<? super InputType, ? extends CategoryType>>>
implements SupervisedBatchLearner<InputType,CategoryType,EvaluatorToCategorizerAdapter<InputType, CategoryType>>
{
/**
* Creates a new {@code EvaluatorToCategorizerAdapter}.
*/
public Learner()
{
this(null);
}
/**
* Creates a new {@code EvaluatorToCategorizerAdapter}.
*
* @param learner The learner to adapt the output of to be a
* categorizer.
*/
public Learner(
final BatchLearner<? super Collection<? extends InputOutputPair<? extends InputType, CategoryType>>, ? extends Evaluator<? super InputType, ? extends CategoryType>> learner)
{
super();
this.setLearner(learner);
}
@Override
@SuppressWarnings("unchecked")
public Learner<InputType,CategoryType> clone()
{
return (Learner<InputType,CategoryType>) super.clone();
}
@SuppressWarnings("unchecked")
public EvaluatorToCategorizerAdapter<InputType, CategoryType> learn(
Collection<? extends InputOutputPair<? extends InputType, CategoryType>> data)
{
final Evaluator<? super InputType, ? extends CategoryType> learned =
(Evaluator<? super InputType, ? extends CategoryType>) this.getLearner().learn(data);
// Go through the input data to determine the possible output
// categories.
final TreeSet<CategoryType> categories =
new TreeSet<CategoryType>();
for (InputOutputPair<? extends InputType, ? extends CategoryType>
example : data)
{
categories.add(example.getOutput());
}
return new EvaluatorToCategorizerAdapter<InputType, CategoryType>(
learned, categories);
}
/**
* Gets the learner whose output is to be adapted to be a categorizer.
*
* @return The learner to adapt the output of.
*/
public BatchLearner<? super Collection<? extends InputOutputPair<? extends InputType, CategoryType>>, ? extends Evaluator<? super InputType, ? extends CategoryType>> getLearner()
{
return this.learner;
}
/**
* Sets the learner whose output is to be adapted to be a categorizer.
*
* @param learner The leaner to adapt the output of.
*/
public void setLearner(
final BatchLearner<? super Collection<? extends InputOutputPair<? extends InputType, CategoryType>>, ? extends Evaluator<? super InputType, ? extends CategoryType>> learner)
{
this.learner = learner;
}
}
}