Thank you, Jörn. I committed a new revision.
William On Wed, Jan 12, 2011 at 8:24 AM, Jörn Kottmann <[email protected]> wrote: > Hi William, > > reviewed your changes, looks nice. > > I do not understand the javadoc comment for the fields > target and selected. Can you improve them ? > > Jörn > > On 1/5/11 5:44 PM, [email protected] wrote: > >> Author: colen >> Date: Wed Jan 5 16:44:58 2011 >> New Revision: 1055519 >> >> URL: http://svn.apache.org/viewvc?rev=1055519&view=rev >> Log: >> OPENNLP-59 New strategy to compute Precision, Recall and FM >> >> Modified: >> >> incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/util/eval/FMeasure.java >> >> incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/util/eval/FMeasureTest.java >> >> Modified: >> incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/util/eval/FMeasure.java >> URL: >> http://svn.apache.org/viewvc/incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/util/eval/FMeasure.java?rev=1055519&r1=1055518&r2=1055519&view=diff >> >> ============================================================================== >> --- >> incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/util/eval/FMeasure.java >> (original) >> +++ >> incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/util/eval/FMeasure.java >> Wed Jan 5 16:44:58 2011 >> @@ -29,15 +29,13 @@ package opennlp.tools.util.eval; >> */ >> public final class FMeasure { >> >> - /** >> - * The mean of all calculated precision scores. >> - */ >> - private Mean precisionScore = new Mean(); >> - >> - /** >> - * The mean of all calculated recall scores. >> - */ >> - private Mean recallScore = new Mean(); >> + /** |selected| = tp + fp */ >> + private long selected; >> + >> + /** |target| = tp + fp */ >> + private long target; >> + >> + private long truePositive; >> >> /** >> * Retrieves the arithmetic mean of the precision scores >> @@ -46,7 +44,7 @@ public final class FMeasure { >> * @return the arithmetic mean of all precision scores >> */ >> public double getPrecisionScore() { >> - return precisionScore.mean(); >> + return selected> 0 ? (double)truePositive / (double)selected : 0; >> } >> >> /** >> @@ -56,7 +54,7 @@ public final class FMeasure { >> * @return the arithmetic mean of all recall scores >> */ >> public double getRecallScore() { >> - return recallScore.mean(); >> + return target> 0 ? (double)truePositive / (double)target : 0; >> } >> >> /** >> @@ -79,19 +77,16 @@ public final class FMeasure { >> } >> >> public void updateScores(Object references[], Object predictions[]) { >> - >> - double precision = FMeasure.precision(references, predictions); >> - if (!Double.isNaN(precision)) >> - precisionScore.add(precision, references.length); >> - >> - double recall = FMeasure.recall(references, predictions); >> - if (!Double.isNaN(recall)) >> - recallScore.add(FMeasure.recall(references, predictions), >> references.length); >> + >> + truePositive += countTruePositives(references, predictions); >> + selected += predictions.length; >> + target += references.length; >> } >> >> public void mergeInto(FMeasure measure) { >> - precisionScore.add(measure.getPrecisionScore(), >> measure.precisionScore.count()); >> - recallScore.add(measure.getRecallScore(), >> measure.recallScore.count()); >> + this.selected += measure.selected; >> + this.target += measure.target; >> + this.truePositive += measure.truePositive; >> } >> >> /** >> >> Modified: >> incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/util/eval/FMeasureTest.java >> URL: >> http://svn.apache.org/viewvc/incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/util/eval/FMeasureTest.java?rev=1055519&r1=1055518&r2=1055519&view=diff >> >> ============================================================================== >> --- >> incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/util/eval/FMeasureTest.java >> (original) >> +++ >> incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/util/eval/FMeasureTest.java >> Wed Jan 5 16:44:58 2011 >> @@ -53,6 +53,27 @@ public class FMeasureTest { >> new Span(212, 220), >> new Span(220, 230) >> }; >> + >> + private Span goldToMerge[] = { >> + new Span(8, 9), >> + new Span(9, 10), >> + new Span(11, 11), >> + new Span(13, 14), >> + new Span(14, 15), >> + new Span(15, 16), >> + new Span(18, 19), >> + }; >> + >> + private Span predictedToMerge[] = { >> + new Span(8, 9), >> + new Span(14, 15), >> + new Span(15, 16), >> + new Span(100, 120), >> + new Span(210, 220), >> + new Span(220, 230) >> + }; >> + >> + >> >> /** >> * Test for the {...@link EvaluatorUtil#countTruePositives(Span[], >> Span[])} method. >> @@ -88,4 +109,49 @@ public class FMeasureTest { >> assertEquals(Double.NaN, FMeasure.recall(new Object[]{}, gold), >> DELTA); >> assertEquals(2d / gold.length, FMeasure.recall(gold, predicted), >> DELTA); >> } >> + >> + @Test >> + public void testEmpty() { >> + FMeasure fm = new FMeasure(); >> + assertEquals(-1, fm.getFMeasure(), DELTA); >> + assertEquals(0, fm.getRecallScore(), DELTA); >> + assertEquals(0, fm.getPrecisionScore(), DELTA); >> + } >> + >> + @Test >> + public void testPerfect() { >> + FMeasure fm = new FMeasure(); >> + fm.updateScores(gold, gold); >> + assertEquals(1, fm.getFMeasure(), DELTA); >> + assertEquals(1, fm.getRecallScore(), DELTA); >> + assertEquals(1, fm.getPrecisionScore(), DELTA); >> + } >> + >> + @Test >> + public void testMerge() { >> + FMeasure fm = new FMeasure(); >> + fm.updateScores(gold, predicted); >> + fm.updateScores(goldToMerge, predictedToMerge); >> + >> + FMeasure fmMerge = new FMeasure(); >> + fmMerge.updateScores(gold, predicted); >> + FMeasure toMerge = new FMeasure(); >> + toMerge.updateScores(goldToMerge, predictedToMerge); >> + fmMerge.mergeInto(toMerge); >> + >> + double selected1 = predicted.length; >> + double target1 = gold.length; >> + double tp1 = FMeasure.countTruePositives(gold, predicted); >> + >> + double selected2 = predictedToMerge.length; >> + double target2 = goldToMerge.length; >> + double tp2 = FMeasure.countTruePositives(goldToMerge, >> predictedToMerge); >> + >> + >> + assertEquals((tp1 + tp2) / (target1 + target2), >> fm.getRecallScore(), DELTA); >> + assertEquals((tp1 + tp2) / (selected1 + selected2), >> fm.getPrecisionScore(), DELTA); >> + >> + assertEquals(fm.getRecallScore(), fmMerge.getRecallScore(), >> DELTA); >> + assertEquals(fm.getPrecisionScore(), >> fmMerge.getPrecisionScore(), DELTA); >> + } >> } >> \ No newline at end of file >> >> >> >
