001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.experiment.evaluation.classification.analysers.roc; 031 032import gov.sandia.cognition.statistics.method.ReceiverOperatingCharacteristic; 033import gov.sandia.cognition.statistics.method.ReceiverOperatingCharacteristic.DataPoint; 034import gov.sandia.cognition.statistics.method.ReceiverOperatingCharacteristic.Statistic; 035 036import java.util.Map; 037import java.util.Map.Entry; 038 039import net.sf.jasperreports.engine.JasperPrint; 040 041import org.openimaj.experiment.evaluation.AnalysisResult; 042 043/** 044 * An {@link AnalysisResult} representing a set of ROC curves and associated 045 * statistics. 046 * 047 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 048 * 049 * @param <CLASS> 050 * Type of classes 051 */ 052public class ROCResult<CLASS> implements AnalysisResult { 053 Map<CLASS, ReceiverOperatingCharacteristic> rocData; 054 055 /** 056 * Default constructor 057 * 058 * @param rocData 059 */ 060 ROCResult(Map<CLASS, ReceiverOperatingCharacteristic> rocData) { 061 this.rocData = rocData; 062 } 063 064 /** 065 * @return the {@link ReceiverOperatingCharacteristic} for each CLASS 066 */ 067 public Map<CLASS, ReceiverOperatingCharacteristic> getROCData() { 068 return rocData; 069 } 070 071 @Override 072 public String toString() { 073 return getSummaryReport(); 074 } 075 076 @Override 077 public JasperPrint getSummaryReport(String title, String info) { 078 // FIXME: 079 throw new UnsupportedOperationException(); 080 } 081 082 @Override 083 public JasperPrint getDetailReport(String title, String info) { 084 // FIXME: 085 throw new UnsupportedOperationException(); 086 } 087 088 @Override 089 public String getSummaryReport() { 090 final StringBuilder sb = new StringBuilder(); 091 092 for (final Entry<CLASS, ReceiverOperatingCharacteristic> entry : rocData.entrySet()) { 093 final Statistic stats = entry.getValue().computeStatistics(); 094 095 sb.append( 096 String.format("%10s\tAUC: %2.3f\tEER:%2.3f\n", entry.getKey(), 097 stats.getAreaUnderCurve(), stats.getOptimalThreshold().getFalsePositiveRate()) 098 ); 099 } 100 101 return sb.toString(); 102 } 103 104 @Override 105 public String getDetailReport() { 106 final StringBuilder sb = new StringBuilder(); 107 108 for (final Entry<CLASS, ReceiverOperatingCharacteristic> entry : rocData.entrySet()) { 109 final Statistic stats = entry.getValue().computeStatistics(); 110 111 sb.append("Class: " + entry.getKey() + "\n"); 112 113 sb.append(String.format("AUC: %2.3f\n", stats.getAreaUnderCurve())); 114 sb.append(String.format("EER: %2.3f\n", stats.getOptimalThreshold().getFalsePositiveRate())); 115 // sb.append(String.format(" D': %2.3f\n", stats.getDPrime())); 116 117 sb.append("\n"); 118 sb.append("FPR\tTPR\n"); 119 for (final DataPoint dp : entry.getValue().getSortedROCData()) { 120 sb.append(String.format("%2.3f\t%2.3f\n", dp.getFalsePositiveRate(), dp.getTruePositiveRate())); 121 } 122 sb.append("\n"); 123 } 124 125 return sb.toString(); 126 } 127}