Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/26/16 00:02:05 (8 years ago)
Author:
abeham
Message:

#2457: worked on recommendation algorithms (x-validation)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Views/PerformanceModelingView.cs

    r13791 r13794  
    2020#endregion
    2121
     22using HeuristicLab.Analysis;
    2223using HeuristicLab.Common.Resources;
    2324using HeuristicLab.Core;
     
    134135      var trainingSet = Content.ProblemInstances.Where(x => !Content.IsCurrentInstance(x)).ToArray();
    135136
     137      var absErr = 0.0;
     138      var confMatrix = new int[6, 6];
     139      var tau = 0.0;
    136140      // leave one out crossvalidation
    137141      foreach (var pi in trainingSet) {
    138142        var model = recommender.TrainModel(trainingSet.Where(x => x != pi).ToArray(), Content, features);
    139         var ranking = model.GetRanking(pi).ToList();
    140         var realPerformance = Content.GetAlgorithmPerformance(pi);
    141         // absolute error predicting ert
    142         // confusion matrix predicting class
    143         // Kendall's tau
     143        var predicted = model.GetRanking(pi).ToDictionary(x => x.Key, x => x.Value);
     144        var observed = Content.GetAlgorithmPerformance(pi);
     145        absErr += AbsoluteError(observed, predicted);
     146        var confMat = ConfusionMatrix(observed, predicted);
     147        for (var i = 0; i < confMat.GetLength(0); i++)
     148          for (var j = 0; j < confMat.GetLength(1); j++)
     149            confMatrix[i, j] += confMat[i, j];
     150        tau += KendallsTau(observed, predicted);
    144151        // average NCDG ... relevance determined by clustering (unsuccessful algorithms being penalized with negative relevance)
    145152        // mean reciprocal rank
    146153        // optional: expected reciprocal rank
    147154      }
    148     }
    149 
    150     private static double AbsoluteError(Dictionary<IAlgorithm, double> performance, List<Tuple<IAlgorithm, double>> ranking) {
     155      absErr /= trainingSet.Length;
     156      tau /= trainingSet.Length;
     157
     158      confusionMatrixView.Content = new IntMatrix(confMatrix);
     159      absoluteErrorView.Content = new DoubleValue(absErr);
     160      kendallsTauView.Content = new DoubleValue(tau);
     161    }
     162
     163    private static double AbsoluteError(Dictionary<IAlgorithm, double> performance, Dictionary<IAlgorithm, double> ranking) {
    151164      var error = 0.0;
    152165      foreach (var tuple in ranking) {
    153166        double actual;
    154         if (!performance.TryGetValue(tuple.Item1, out actual)) continue;
    155         error += Math.Abs(actual - tuple.Item2);
     167        if (!performance.TryGetValue(tuple.Key, out actual)) continue;
     168        if (double.IsNaN(actual)) actual = int.MaxValue;
     169        error += Math.Abs(actual - tuple.Value);
    156170      }
    157171      return error;
    158172    }
    159173
    160     private static int[,] ConfusionMatrix(Dictionary<IAlgorithm, double> performance, List<Tuple<IAlgorithm, double>> ranking) {
    161       var confMatrix = new int[5,5];
     174    private static int[,] ConfusionMatrix(Dictionary<IAlgorithm, double> performance, Dictionary<IAlgorithm, double> ranking) {
     175      var confMatrix = new int[6,6];
     176      var clusteredPerformance = ClusteringHelper<IAlgorithm>.Cluster(5, performance, a => double.IsNaN(a.Value)).GetByInstance().ToDictionary(x => x.Key, x => x.Value.Item2);
     177      var clusteredRanks = ClusteringHelper<IAlgorithm>.Cluster(5, ranking, x => double.IsNaN(x.Value) || x.Value >= int.MaxValue).GetByInstance().ToDictionary(x => x.Key, x => x.Value.Item2);
     178      foreach (var cr in clusteredRanks) {
     179        int realRank;
     180        if (!clusteredPerformance.TryGetValue(cr.Key, out realRank)) continue;
     181        confMatrix[realRank, cr.Value]++;
     182      }
    162183      return confMatrix;
     184    }
     185
     186    private static double KendallsTau(Dictionary<IAlgorithm, double> performance, Dictionary<IAlgorithm, double> ranking) {
     187      var commonKeys = performance.Keys.Intersect(ranking.Keys).ToList();
     188      var n = commonKeys.Count;
     189      if (n == 0) return 0.0;
     190
     191      var actualRanks = commonKeys.Select((x, i) => new { Alg = x, Index = i, Perf = performance[x] })
     192                                  .OrderBy(x => x.Perf).Select((x, i) => new { Index = x.Index, Rank = i })
     193                                  .OrderBy(x => x.Index).Select(x => x.Rank).ToList();
     194      var predictedRanks = commonKeys.Select((x, i) => new { Alg = x, Index = i, Perf = ranking[x] })
     195                                     .OrderBy(x => x.Perf).Select((x, i) => new { Index = x.Index, Rank = i })
     196                                     .OrderBy(x => x.Index).Select(x => x.Rank).ToList();
     197     
     198      var paired = actualRanks.Zip(predictedRanks, (a, p) => new { Actual = a, Predicted = p }).ToList();
     199      var concordant = 0;
     200      var discordant = 0;
     201      for (var i = 0; i < paired.Count - 1; i++)
     202        for (var j = 0; j < paired.Count; j++) {
     203          if (paired[i].Actual > paired[j].Actual && paired[i].Predicted > paired[j].Predicted
     204            || paired[i].Actual < paired[j].Actual && paired[i].Predicted < paired[j].Predicted)
     205            concordant++;
     206          else discordant++;
     207        }
     208      return (2.0 * (concordant - discordant)) / (n * (n - 1));
    163209    }
    164210    #endregion
Note: See TracChangeset for help on using the changeset viewer.