001/**
002 *  DeepNetts is pure Java Deep Learning Library with support for Backpropagation
003 *  based learning and image recognition.
004 *
005 *  Copyright (C) 2017  Zoran Sevarac <sevarac@gmail.com>
006 *
007 * This file is part of DeepNetts.
008 *
009 * DeepNetts is free software: you can redistribute it and/or modify it under
010 * the terms of the GNU General Public License as published by the Free Software
011 * Foundation, either version 3 of the License, or (at your option) any later
012 * version.
013 *
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
016 * Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License along with
019 * this program. If not, see <https://www.gnu.org/licenses/>.package
020 * deepnetts.core;
021 */
022
023package javax.visrec.ml.eval;
024
025import java.util.HashMap;
026
027/**
028 * Wrapper for constants and values for classifier and regressor evaluation metrics.
029 * 
030 * @author Zoran Sevarac
031 */
032public class EvaluationMetrics {
033
034    /**
035    * Mean value of sum of squared errors.
036    * Errors are squared in order to better explain variability, and take into account positive and negative errors.
037    * Regression metrics
038    */
039    public final static String MEAN_ABSOLUTE_ERROR      = "MeanAbsoluteError";
040    public final static String MEAN_SQUARED_ERROR       = "MeanSquaredError";
041    public final static String ROOT_MEAN_SQUARED_ERROR  = "RootMeanSquaredError";
042    public final static String RESIDUAL_SQUARE_SUM      = "ResidualSquareSum"; // RSS
043
044    /**
045     * Estimation of standard deviation of prediction errors for some given data set.
046     * Smaller is better.
047     */
048    public final static String RESIDUAL_STANDARD_ERROR = "ResidualStandardError";
049
050    /**
051     * Percent of variation explained by the regression model.
052     * 1 is good , 0 is bad, bigger is better.
053     */
054    public final static String R_SQUARED = "RSquared";
055
056    /**
057     * Is there a relationship between inputs and predictions(outputs) at all.
058     * If there is a relationship, this value is greater then 1. 
059     * When there is now relationship, this value is around 1.
060     */
061    public final static String F_STAT = "FStatistics";
062
063    // TODO: p value, t statistics
064
065    // Classification Metrics
066    public final static String ACCURACY         = "Accuracy";
067    public final static String PRECISION        = "Precision";
068    public final static String RECALL           = "Recall";
069    public final static String F1SCORE          = "F1Score";
070
071    //
072    private final HashMap<String, Float> values = new HashMap();
073    
074    private final static HashMap<String, String> description = new HashMap();
075    static {
076        description.put(ACCURACY, "How often is classifier correct in total");
077        description.put(PRECISION, "How often is classifier correct when it gives positive prediction");
078        description.put(RECALL, "When it is actually positive class, how often does it give positive prediction");
079        description.put(F1SCORE, "Average of precision and recall");
080    }
081    
082
083    public float get(String key) {
084        return values.get(key);
085    }
086
087    public void set(String key, float value) {
088        values.put(key, value);
089    }
090
091    @Override
092    public String toString() {
093        StringBuilder sb = new StringBuilder();
094        values.entrySet().stream().forEach((e) ->  { sb.append(e.getKey()).append(": ")
095                                                     .append(e.getValue());
096                                                     if (description.get(e.getKey())!=null)   
097                                                        sb.append(" (")
098                                                          .append(description.get(e.getKey())) 
099                                                          .append(")");
100                                                     sb.append(System.lineSeparator());
101                                                    });
102        // todo: also append decsripton
103        return sb.toString();
104    }
105
106}