/* * Created by: Miguel Angel Medina P�rez (miguel.medina.perez@gmail.com) * Created: * Comments by: Miguel Angel Medina P�rez (miguel.medina.perez@gmail.com) */ using System.Collections.Generic; namespace PatternRecognition.ROC { /// <summary> /// Builds ROC curve of type True Positive Rate versus False Positive Rate ROC Builder. /// </summary> /// <remarks> /// <para> /// This implementation is based on the algorithm proposed in [1]. /// </para> /// <para> /// References: /// </para> /// <para> /// <list type="number"> /// <item> /// T. Fawcett, "An introduction to ROC analysis," Pattern Recognition Letters, vol. 27, pp. 861-874, 2006. /// </item> /// </list> /// </para> /// </remarks> public class TPRvsFPR : IROCBuilder { /// <summary> /// Build a ROC curve from the specified matching scores and score comparer. /// </summary> /// <param name="positiveMatching"> /// A collection containing the matching scores of objects in the same class. /// </param> /// <param name="negativeMatching"> /// A collection containing the matching scores of objects in different class. /// </param> /// <param name="scoreComparer"> /// A comparer for matching scores. /// </param> /// <returns> /// The points that compose the ROC curve. /// </returns> public List<ROCPoint> BuildROC(ICollection<double> positiveMatching, ICollection<double> negativeMatching, IComparer<double> scoreComparer) { var matchingResults = new List<MatchingResult>(); foreach (double d in positiveMatching) matchingResults.Add(new MatchingResult(MatchingType.Positive, d)); foreach (double d in negativeMatching) matchingResults.Add(new MatchingResult(MatchingType.Negative, d)); matchingResults.Sort(new MatchingResultComparer() { ValuesComparer = scoreComparer }); return BuildROC(matchingResults, negativeMatching.Count, positiveMatching.Count); } private List<ROCPoint> BuildROC(IList<MatchingResult> sortedResults, int negativeCount, int positiveCount) { int fp = 0; int tp = 0; var curve = new List<ROCPoint>(); double latter = double.MinValue; for (int i = 0; i < sortedResults.Count; i++) { MatchingResult mr = sortedResults[i]; if (mr.ComparissonValue != latter) { ROCPoint rocPoint = new ROCPoint(100.0 * fp / negativeCount, 100.0 * tp / positiveCount, mr.ComparissonValue); if (curve.Count > 1) { if (curve[curve.Count - 2].x == rocPoint.x) curve[curve.Count - 1] = rocPoint; else if (curve[curve.Count - 2].y == rocPoint.y) curve[curve.Count - 1] = rocPoint; else curve.Add(rocPoint); } else curve.Add(rocPoint); latter = mr.ComparissonValue; } if (mr.Type == MatchingType.Positive) tp++; else fp++; } curve.Add(new ROCPoint(100, curve[curve.Count - 1].y, curve[curve.Count - 1].matchingValue)); curve.Add(new ROCPoint(100, 100, curve[curve.Count - 1].matchingValue)); return curve; } } }
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)