View Javadoc

1   /*
2    * Copyright (C) 2004 Christian Siefkes <christian@siefkes.net>.
3    * Development of this software is supported by the German Research Society,
4    * Berlin-Brandenburg Graduate School in Distributed Information Systems
5    * (DFG grant no. GRK 316).
6    *
7    * This library is free software; you can redistribute it and/or
8    * modify it under the terms of the GNU Lesser General Public
9    * License as published by the Free Software Foundation; either
10   * version 2.1 of the License, or (at your option) any later version.
11   *
12   * This library is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this library; if not, visit
19   * http://www.gnu.org/licenses/lgpl.html or write to the Free Software
20   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21   */
22  package de.fu_berlin.ties.eval;
23  
24  import org.apache.commons.math.stat.StatisticalSummary;
25  import org.apache.commons.math.stat.SummaryStatistics;
26  
27  import de.fu_berlin.ties.io.FieldMap;
28  
29  /***
30   * {@link de.fu_berlin.ties.eval.FMetrics} extension that additionally
31   * calculates a {@link org.apache.commons.math.stat.StatisticalSummary} of the
32   * intermediate precision, recall, and F1 metrics resulting from different
33   * {@link #update(long, long, long) update} operations. Values added by
34   * {@link de.fu_berlin.ties.eval.FMetrics#incFalseNeg() inc...} operations
35   * are <em>not</em> considered for summaries.
36   *
37   * <p>Especially the
38   * {@link org.apache.commons.math.stat.StatisticalSummary#getStandardDeviation()
39   * standard deviations} might be interested -- thus they are
40   * {@linkplain #storeFields() serialized} in addition to the values stored by
41   * the superclass. The summaries cannot be restored during
42   * {@link #SummaryFMetrics(FieldMap) deserialization} because not all required
43   * information is serialized.
44   *
45   * @author Christian Siefkes
46   * @version $Revision: 1.3 $, $Date: 2004/02/20 17:49:18 $, $Author: siefkes $
47   */
48  public class SummaryFMetrics extends FMetrics implements FMetricsSummary {
49  
50      /***
51       * Prefix of serialization keys for standard deviations.
52       */
53      public static final String PREFIX_STD_DEVIATION = "Std. Deviation ";
54  
55      /***
56       * Summary statistics for the precision.
57       */
58      private final SummaryStatistics precisionSummary =
59          SummaryStatistics.newInstance();
60  
61      /***
62       * Summary statistics for the recall.
63       */
64      private final SummaryStatistics recallSummary =
65          SummaryStatistics.newInstance();
66  
67      /***
68       * Summary statistics for the F1 measure.
69       */
70      private final SummaryStatistics f1Summary = SummaryStatistics.newInstance();
71  
72      /***
73       * Creates a new empty instance.
74       */
75      public SummaryFMetrics() {
76          super();
77      }
78  
79      /***
80       * Creates a new instance from a field map, fulfilling the
81       * {@link de.fu_berlin.ties.io.Storable} contract. <strong>Any summary
82       * information stored in the initial instance will be lost, thus summaries
83       * calculated after restoring will be inaccurate.</strong>
84       *
85       * @param fieldMap map containing the serialized fields
86       * @throws IllegalArgumentException if at least one of the parameters is
87       * negative or missing
88       */
89      public SummaryFMetrics(final FieldMap fieldMap)
90              throws IllegalArgumentException {
91          super(fieldMap);
92      }
93  
94      /***
95       * Stores all relevant fields of this object in a field map for
96       * serialization. An equivalent object can be created by calling
97       * {@link de.fu_berlin.ties.io.FieldMap#createObject(Class)} on the created
98       * field map. The calculated values precision, recall, and F-measure and
99       * their standard deviations are also stored (they are ignored when
100      * {@linkplain #SummaryFMetrics(FieldMap) deserializing} a stored instance).
101      *
102      * @return the created field map
103      */
104     public FieldMap storeFields() {
105         // delegate to super + add standard deviations
106         final FieldMap result = super.storeFields();
107         result.put(PREFIX_STD_DEVIATION + KEY_PRECISION,
108             new Double(precisionSummary.getStandardDeviation()));
109         result.put(PREFIX_STD_DEVIATION + KEY_RECALL,
110             new Double(recallSummary.getStandardDeviation()));
111         result.put(PREFIX_STD_DEVIATION + KEY_F1_MEASURE,
112             new Double(f1Summary.getStandardDeviation()));
113         return result;
114     }
115 
116     /***
117      * Updates the statistics, increasing the stored values as specified and
118      * updating the statistical summaries.
119      *
120      * @param addTruePos the number of new true positives to add
121      * @param addFalseNeg the number of new false negatives to add
122      * @param addFalsePos the number of new false positives to add
123      * @throws IllegalArgumentException if at least one of the parameters is
124      * negative
125      */
126     public final void update(final long addTruePos, final long addFalseNeg,
127             final long addFalsePos) throws IllegalArgumentException {
128         // delegate to super + update summaries
129         super.update(addTruePos, addFalseNeg, addFalsePos);
130         final FMetrics newMetrics =
131             new FMetrics(addTruePos, addFalseNeg, addFalsePos);
132         precisionSummary.addValue(newMetrics.getPrecision());
133         recallSummary.addValue(newMetrics.getRecall());
134         f1Summary.addValue(newMetrics.getF1Measure());
135     }
136 
137     /***
138      * Returns a summary view on the F1 values. This is not a snapshot but
139      * will change whenever the underlying values are changed.
140      *
141      * @return a summary view on the F1 value
142      */
143     public StatisticalSummary viewF1Summary() {
144         return f1Summary;
145     }
146 
147     /***
148      * Returns a summary view on the precision values. This is not a snapshot
149      * but will change whenever the underlying values are changed.
150      *
151      * @return a summary view on the precision value
152      */
153     public StatisticalSummary viewPrecisionSummary() {
154         return precisionSummary;
155     }
156 
157     /***
158      * Returns a summary view on the recall values. This is not a snapshot but
159      * will change whenever the underlying values are changed.
160      *
161      * @return a summary view on the recall value
162      */
163     public StatisticalSummary viewRecallSummary() {
164         return recallSummary;
165     }
166 
167 }