All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aliasi.classify.ScoredClassifierEvaluator Maven / Gradle / Ivy

Go to download

This is the original Lingpipe: http://alias-i.com/lingpipe/web/download.html There were not made any changes to the source code.

There is a newer version: 4.1.2-JL1.0
Show newest version
/*
 * LingPipe v. 4.1.0
 * Copyright (C) 2003-2011 Alias-i
 *
 * This program is licensed under the Alias-i Royalty Free License
 * Version 1 WITHOUT ANY WARRANTY, without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the Alias-i
 * Royalty Free License Version 1 for more details.
 *
 * You should have received a copy of the Alias-i Royalty Free License
 * Version 1 along with this program; if not, visit
 * http://alias-i.com/lingpipe/licenses/lingpipe-license-1.txt or contact
 * Alias-i, Inc. at 181 North 11th Street, Suite 401, Brooklyn, NY 11211,
 * +1 (718) 290-9170.
 */
package com.aliasi.classify;

import com.aliasi.util.Scored;

import java.util.ArrayList;
import java.util.List;

/**
 * A {@code ScoredClassifierEvaluator} provides an evaluation harness for
 * score-based classifiers.  It extends the ranked classifier evaluator with
 * score-specific evaluation metrics.
 *
 * 

Thread Safety

* * This class must be read-write synchronized externally for use * in multiple threads. * * @author Bob Carpenter * @version 3.9.1 * @since LingPipe3.9.1 * @param The type of objects being classified by the evaluated classifier. */ public class ScoredClassifierEvaluator extends RankedClassifierEvaluator { private final List[] mScoreOutcomeLists; boolean mDefectiveScoring = false; /** * Construct a scored classifier evaluator with the specified * classifier, categories and flag indicating whether or not to * store inputs. * * @param classifier Classifier to evaluate. * @param categories Complete list of categories. * @param storeInputs Set to {@code true} to store input objects. */ public ScoredClassifierEvaluator(ScoredClassifier classifier, String[] categories, boolean storeInputs) { super(classifier,categories,storeInputs); @SuppressWarnings({"unchecked","rawtypes"}) List[] scoreOutcomeLists = new ArrayList[numCategories()]; mScoreOutcomeLists = scoreOutcomeLists; for (int i = 0; i < mScoreOutcomeLists.length; ++i) mScoreOutcomeLists[i] = new ArrayList(); } /** * Set the classifier being evaluated to the specified value. This * method is useful to evaluate multiple classifiers with the same * evaluator, for instance for use in cross-validation. * * @param classifier New classifier for this evaluation. * @throws IllegalArgumentException If called from an evaluator with * a runtime type other than {@code ScoredClassifierEvaluator}. */ public void setClassifier(ScoredClassifier classifier) { setClassifier(classifier,ScoredClassifierEvaluator.class); } /** * Return the classifier being evaluated. * * @return The classifier for this evaluator. */ @Override public ScoredClassifier classifier() { @SuppressWarnings("unchecked") ScoredClassifier result = (ScoredClassifier) super.classifier(); return result; } @Override public void handle(Classified classified) { // CUT AND PASTE FROM SUPERCLASS, and INTO SUBCLASS E input = classified.getObject(); Classification refClassification = classified.getClassification(); String refCategory = refClassification.bestCategory(); validateCategory(refCategory); ScoredClassification classification = classifier().classify(input); addClassification(refCategory,classification,input); addRanking(refCategory,classification); // new stuff addScoring(refCategory,classification); } /** * Returns a scored precision-recall evaluation of the * classification of the specified reference category versus all * other categories using the classification scores. * * @param refCategory Reference category. * @return The scored one-versus-all precision-recall evaluatuion. * @throws IllegalArgumentException If the specified category * is unknown. */ public ScoredPrecisionRecallEvaluation scoredOneVersusAll(String refCategory) { validateCategory(refCategory); return scoredOneVersusAll(mScoreOutcomeLists, categoryToIndex(refCategory)); } /** * Returns the average score of the specified response category * for test cases with the specified reference category. If there * are no cases matching the reference category, the result is * Double.NaN. * *

Better classifiers return high values when the reference * and response categories are the same and lower values * when they are different. Depending on the classifier, the * scores may or may not be meaningful as an average. * * @param refCategory Reference category. * @param responseCategory Response category. * @return Average score of response category in test cases for * specified reference category. * @throws IllegalArgumentException If the either category is unknown. */ public double averageScore(String refCategory, String responseCategory) { validateCategory(refCategory); validateCategory(responseCategory); double sum = 0.0; int count = 0; for (int i = 0; i < mReferenceCategories.size(); ++i) { if (mReferenceCategories.get(i).equals(refCategory)) { ScoredClassification c = (ScoredClassification) mClassifications.get(i); for (int rank = 0; rank < c.size(); ++rank) { if (c.category(rank).equals(responseCategory)) { sum += c.score(rank); ++count; break; } } } } return sum / (double) count; } /** * Returns the average over all test cases of the score of the * response that matches the reference category. Better * classifiers return higher values for this average. * *

Whether average scores make sense across training instances * depends on the classifier. * * @return The average score of the reference category in the * response. */ public double averageScoreReference() { double sum = 0.0; for (int i = 0; i < mReferenceCategories.size(); ++i) { String refCategory = mReferenceCategories.get(i).toString(); ScoredClassification c = (ScoredClassification) mClassifications.get(i); for (int rank = 0; rank < c.size(); ++rank) { if (c.category(rank).equals(refCategory)) { sum += c.score(rank); break; } } } return sum / (double) mReferenceCategories.size(); } ScoredPrecisionRecallEvaluation scoredOneVersusAll(List[] outcomeLists, int categoryIndex) { ScoredPrecisionRecallEvaluation eval = new ScoredPrecisionRecallEvaluation(); for (ScoreOutcome outcome : outcomeLists[categoryIndex]) eval.addCase(outcome.mOutcome,outcome.mScore); return eval; } void addScoring(String refCategory, ScoredClassification scoring) { // will this rank < scoring.size() mess up eval? if (scoring.size() < numCategories()) mDefectiveScoring = true; for (int rank = 0; rank < numCategories() && rank < scoring.size(); ++rank) { double score = scoring.score(rank); String category = scoring.category(rank); int categoryIndex = categoryToIndex(category); boolean match = category.equals(refCategory); ScoreOutcome outcome = new ScoreOutcome(score,match,rank==0); mScoreOutcomeLists[categoryIndex].add(outcome); } } @Override void baseToString(StringBuilder sb) { super.baseToString(sb); sb.append("Average Score Reference=" + averageScoreReference() + "\n"); } @Override void oneVsAllToString(StringBuilder sb, String category, int i) { super.oneVsAllToString(sb,category,i); sb.append("Scored One Versus All\n"); sb.append(scoredOneVersusAll(category) + "\n"); sb.append("Average Score Histogram=\n"); appendCategoryLine(sb); for (int j = 0; j < numCategories(); ++j) { if (j > 0) sb.append(','); sb.append(averageScore(category,categories()[j])); } sb.append("\n"); } static class ScoreOutcome implements Scored { private final double mScore; private final boolean mOutcome; private final boolean mFirstBest; public ScoreOutcome(double score, boolean outcome, boolean firstBest) { mOutcome = outcome; mScore = score; mFirstBest = firstBest; } public double score() { return mScore; } @Override public String toString() { return "(" + mScore + ": " + mOutcome + "firstBest=" + mFirstBest + ")"; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy