Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/25/16 12:56:17 (8 years ago)
Author:
abeham
Message:

#2457: working on recommendation algorithms

Location:
branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/HeuristicLab.OptimizationExpertSystem.Common-3.3.csproj

    r13787 r13791  
    161161    <Compile Include="Recommenders\KNearestNeighborModel.cs" />
    162162    <Compile Include="Recommenders\OverallBestRecommender.cs" />
    163     <Compile Include="Recommenders\DistanceWeightedRecommender.cs" />
    164163    <Compile Include="Interfaces\IAlgorithmInstanceRecommender.cs" />
    165164    <Compile Include="Recommenders\KNearestNeighborRecommender.cs" />
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Interfaces/IAlgorithmInstanceRecommender.cs

    r13787 r13791  
    2121
    2222using HeuristicLab.Core;
     23using HeuristicLab.Optimization;
    2324
    2425namespace HeuristicLab.OptimizationExpertSystem.Common {
    2526  public interface IAlgorithmInstanceRecommender : IParameterizedItem {
    26     IRecommendationModel TrainModel(KnowledgeCenter kc, string[] characteristics);
     27    IRecommendationModel TrainModel(IRun[] problemInstances, KnowledgeCenter kc, string[] characteristics);
    2728  }
    2829}
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Interfaces/IRecommendationModel.cs

    r13787 r13791  
    2727namespace HeuristicLab.OptimizationExpertSystem.Common {
    2828  public interface IRecommendationModel : IContent {
    29     IEnumerable<Tuple<IAlgorithm, double>> GetRanking(KnowledgeCenter kc);
     29    IEnumerable<Tuple<IAlgorithm, double>> GetRanking(IRun problemInstance);
    3030  }
    3131}
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/KnowledgeCenter.cs

    r13787 r13791  
    212212      #endregion
    213213      #region PCA
     214      double[,] v = null;
    214215      var ds = new double[instances.Count, characteristics.Length];
    215       foreach (var instance in instances) {
    216         var arr = instance.Value;
    217         for (var feature = 0; feature < arr.Length; feature++)
    218           ds[key2Idx.GetByFirst(instance.Key), feature] = arr[feature];
    219       }
    220 
    221       int info;
    222       double[] s2;
    223       double[,] v;
    224       alglib.pcabuildbasis(ds, ds.GetLength(0), ds.GetLength(1), out info, out s2, out v);
     216      if (characteristics.Length > 1) {
     217        foreach (var instance in instances) {
     218          var arr = instance.Value;
     219          for (var feature = 0; feature < arr.Length; feature++)
     220            ds[key2Idx.GetByFirst(instance.Key), feature] = arr[feature];
     221        }
     222
     223        int info;
     224        double[] s2;
     225        alglib.pcabuildbasis(ds, ds.GetLength(0), ds.GetLength(1), out info, out s2, out v);
     226      }
    225227      #endregion
    226228      #region SOM
     
    231233          features[feature, key2Idx.GetByFirst(instance.Key)] = arr[feature];
    232234      }
    233       var somCoords = SOM.Map(features, new MersenneTwister(42), somSize: 20, learningRadius: 20, iterations: 200, jittering: true);
     235      var somCoords = SOM.Map(features, new MersenneTwister(42), somSize: 10, learningRadius: 20, iterations: 200, jittering: true);
    234236      #endregion
    235237
     
    237239      try {
    238240        foreach (var instance in ProblemInstances) {
    239           double x = 0, y = 0;
    240           for (var feature = 0; feature < ds.GetLength(1); feature++) {
    241             x += ds[key2Idx.GetByFirst(instance), feature] * v[feature, 0];
    242             y += ds[key2Idx.GetByFirst(instance), feature] * v[feature, 1];
    243           }
    244 
    245241          IItem item;
    246           if (instance.Results.TryGetValue("Projection.PCA.X", out item)) {
    247             ((DoubleValue)item).Value = x;
    248           } else instance.Results.Add("Projection.PCA.X", new DoubleValue(x));
    249           if (instance.Results.TryGetValue("Projection.PCA.Y", out item)) {
    250             ((DoubleValue)item).Value = y;
    251           } else instance.Results.Add("Projection.PCA.Y", new DoubleValue(y));
     242          if (v != null) {
     243            double x = 0, y = 0;
     244            for (var feature = 0; feature < ds.GetLength(1); feature++) {
     245              x += ds[key2Idx.GetByFirst(instance), feature] * v[feature, 0];
     246              y += ds[key2Idx.GetByFirst(instance), feature] * v[feature, 1];
     247            }
     248
     249            if (instance.Results.TryGetValue("Projection.PCA.X", out item)) {
     250              ((DoubleValue)item).Value = x;
     251            } else instance.Results.Add("Projection.PCA.X", new DoubleValue(x));
     252            if (instance.Results.TryGetValue("Projection.PCA.Y", out item)) {
     253              ((DoubleValue)item).Value = y;
     254            } else instance.Results.Add("Projection.PCA.Y", new DoubleValue(y));
     255          } else {
     256            instance.Results.Remove("Projection.PCA.X");
     257            instance.Results.Remove("Projection.PCA.Y");
     258          }
    252259
    253260          if (instance.Results.TryGetValue("Projection.MDS.X", out item)) {
     
    266273        }
    267274      } finally { ProblemInstances.UpdateOfRunsInProgress = false; }
    268     }
    269 
    270     public Dictionary<IRun, double[]> GetProblemCharacteristics(string[] characteristics) {
    271       var instances = new Dictionary<IRun, double[]>();
    272       var values = new List<double>[characteristics.Length];
    273       foreach (var run in ProblemInstances) {
    274         var f = 0;
    275         instances[run] = new double[characteristics.Length];
    276         foreach (var c in characteristics) {
    277           if (values[f] == null) values[f] = new List<double>(ProblemInstances.Count);
    278           IItem item;
    279           if (run.Results.TryGetValue(c, out item)) {
    280             var val = (double)((dynamic)item).Value;
    281             if (!double.IsNaN(val)) values[f].Add(val);
    282             instances[run][f] = val;
    283           } else instances[run][f] = double.NaN;
    284           f++;
    285         }
    286       }
    287       var median = values.Select(x => x.Count == 0 ? 0.0 : x.Median()).ToList();
    288 
    289       var allValues = instances.Values.Select(x => x.Select((f, i) => new {Idx = i, Val = double.IsNaN(f) ? median[i] : f}).ToList())
    290         .SelectMany(x => x)
    291         .GroupBy(x => x.Idx, x => x.Val)
    292         .OrderBy(x => x.Key).ToList();
    293       var avg = allValues.Select(x => x.Average()).ToList();
    294       var stdev = allValues.Select(x => x.StandardDeviation()).ToList();
    295 
    296       // normalize characteristic values by transforming them to their z-score
    297       foreach (var key in instances.Keys.ToList()) {
    298         var arr = instances[key];
    299         for (var i = 0; i < arr.Length; i++) {
    300           if (double.IsNaN(arr[i])) arr[i] = median[i];
    301           if (stdev[i] > 0) arr[i] = (arr[i] - avg[i]) / stdev[i];
    302         }
    303       }
    304       return instances;
    305275    }
    306276
     
    579549    }
    580550
     551    public static double[][] GetFeatures(IRun[] problemInstances, string[] characteristics, double[] medianValues = null) {
     552      var instances = new double[problemInstances.Length][];
     553      for (var p = 0; p < problemInstances.Length; p++) {
     554        instances[p] = new double[characteristics.Length];
     555        for (var f = 0; f < characteristics.Length; f++) {
     556          IItem item;
     557          if (problemInstances[p].Results.TryGetValue(characteristics[f], out item)) {
     558            double val = 0;
     559            var dItem = item as DoubleValue;
     560            if (dItem != null) {
     561              val = dItem.Value;
     562            } else {
     563              var iItem = item as IntValue;
     564              if (iItem != null) val = iItem.Value;
     565              else val = double.NaN;
     566            }
     567            if (double.IsNaN(val) && medianValues != null)
     568              instances[p][f] = medianValues[f];
     569            else instances[p][f] = val;
     570          } else instances[p][f] = medianValues != null ? medianValues[f] : double.NaN;
     571        }
     572      }
     573      return instances;
     574    }
     575
     576    public static double[] GetMedianValues(IRun[] problemInstances, string[] characteristics) {
     577      var values = new List<double>[characteristics.Length];
     578      foreach (var problemInstance in problemInstances) {
     579        for (var f = 0; f < characteristics.Length; f++) {
     580          if (values[f] == null) values[f] = new List<double>(problemInstances.Length);
     581          IItem item;
     582          if (problemInstance.Results.TryGetValue(characteristics[f], out item)) {
     583            var dItem = item as DoubleValue;
     584            if (dItem != null) values[f].Add(dItem.Value);
     585            else {
     586              var iItem = item as IntValue;
     587              if (iItem != null) values[f].Add(iItem.Value);
     588            }
     589          }
     590        }
     591      }
     592      return values.Select(x => x.Count == 0 ? 0.0 : x.Median()).ToArray();
     593    }
     594
     595    public Dictionary<IRun, double[]> GetProblemCharacteristics(string[] characteristics) {
     596      var map = ProblemInstances.Select((v, i) => new { Index = i, ProblemInstance = v }).ToDictionary(x => x.Index, x => x.ProblemInstance);
     597      var instances = GetFeatures(ProblemInstances.ToArray(), characteristics);
     598      var median = GetMedianValues(ProblemInstances.ToArray(), characteristics);
     599
     600      var allValues = instances.Select(x => x.Select((f, i) => new { Idx = i, Val = double.IsNaN(f) ? median[i] : f }).ToList())
     601        .SelectMany(x => x)
     602        .GroupBy(x => x.Idx, x => x.Val)
     603        .OrderBy(x => x.Key).ToList();
     604      var avg = allValues.Select(x => x.Average()).ToList();
     605      var stdev = allValues.Select(x => x.StandardDeviation()).ToList();
     606
     607      // normalize characteristic values by transforming them to their z-score
     608      foreach (var features in instances) {
     609        for (var i = 0; i < features.Length; i++) {
     610          if (double.IsNaN(features[i])) features[i] = median[i];
     611          if (stdev[i] > 0) features[i] = (features[i] - avg[i]) / stdev[i];
     612        }
     613      }
     614      return instances.Select((v, i) => new { ProblemInstance = map[i], Features = v }).ToDictionary(x => x.ProblemInstance, x => x.Features);
     615    }
     616
    581617    public Dictionary<IAlgorithm, double> GetAlgorithmPerformance(IRun problemInstance) {
    582618      if (!problemInstance.Parameters.ContainsKey("BestKnownQuality")) return new Dictionary<IAlgorithm, double>();
     
    586622                          .ToDictionary(x => x.Key, x => ExpectedRuntimeHelper.CalculateErt(x.ToList(), "QualityPerEvaluations", target, Maximization).ExpectedRuntime);
    587623    }
     624
     625    public Dictionary<IAlgorithm, List<IRun>> GetAlgorithmRuns(IRun problemInstance) {
     626      return knowledgeBase.Where(x => ((StringValue)x.Parameters["Problem Name"]).Value == ((StringValue)problemInstance.Parameters["Problem Name"]).Value)
     627                          .GroupBy(x => algorithmId2AlgorithmInstanceMapping.GetByFirst(algorithmId2RunMapping.GetBySecond(x).Single()))
     628                          .ToDictionary(x => x.Key, x => x.ToList());
     629    }
    588630
    589631    public Dictionary<IAlgorithm, List<IRun>> GetKnowledgeBaseByAlgorithm() {
     
    708750    }
    709751
    710     private double GetTarget(double bestKnownQuality, bool maximization) {
     752    public double GetTarget(double bestKnownQuality, bool maximization) {
    711753      return bestKnownQuality * (maximization ? (1 - MinimumTarget.Value) : (1 + MinimumTarget.Value));
    712754    }
     
    817859
    818860    public IEnumerable<Tuple<IAlgorithm, double>> GetAlgorithmInstanceRanking() {
    819       return RecommendationModel.GetRanking(this);
     861      return RecommendationModel.GetRanking(ProblemInstances.Single(IsCurrentInstance));
    820862    }
    821863  }
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Recommenders/FixedRankModel.cs

    r13787 r13791  
    2626namespace HeuristicLab.OptimizationExpertSystem.Common {
    2727  public class FixedRankModel : IRecommendationModel {
    28     private List<Tuple<IAlgorithm, double>> ranking;
     28    private readonly List<Tuple<IAlgorithm, double>> ranking;
    2929
    3030    public FixedRankModel(IEnumerable<Tuple<IAlgorithm, double>> ranking) {
     
    3333    }
    3434 
    35     public IEnumerable<Tuple<IAlgorithm, double>> GetRanking(KnowledgeCenter kc) {
    36       if (kc.Problem.ProblemId == -1) return new Tuple<IAlgorithm, double>[0];
     35    public IEnumerable<Tuple<IAlgorithm, double>> GetRanking(IRun problemInstance) {
    3736      return ranking;
    3837    }
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Recommenders/KNearestNeighborModel.cs

    r13787 r13791  
    2020#endregion
    2121
    22 using HeuristicLab.Common;
     22using HeuristicLab.Collections;
    2323using HeuristicLab.Optimization;
    2424using System;
     
    3030    private readonly int K;
    3131    private readonly string[] characteristics;
     32    private readonly Dictionary<IRun, Dictionary<IAlgorithm, double>> performance;
     33    private readonly BidirectionalDictionary<int, IRun> problemInstanceMap;
     34    private readonly double[] medianValues;
    3235
    33     public KNearestNeighborModel(int k, string[] characteristics) {
     36    public KNearestNeighborModel(int k, Dictionary<IRun, Dictionary<IAlgorithm, double>> perfData, string[] characteristics) {
    3437      this.K = k;
     38      this.performance = perfData;
    3539      this.characteristics = characteristics;
     40      problemInstanceMap = new BidirectionalDictionary<int, IRun>();
     41      var i = 0;
     42      foreach (var pi in perfData.Keys) {
     43        problemInstanceMap.Add(i++, pi);
     44      }
     45      this.medianValues = KnowledgeCenter.GetMedianValues(perfData.Keys.OrderBy(problemInstanceMap.GetBySecond).ToArray(), characteristics);
    3646    }
    3747
    38     public IEnumerable<Tuple<IAlgorithm, double>> GetRanking(KnowledgeCenter kc) {
    39       var distances = kc.GetProblemDistances(characteristics);
     48    public IEnumerable<Tuple<IAlgorithm, double>> GetRanking(IRun problemInstance) {
     49      var features = KnowledgeCenter.GetFeatures(performance.Keys.OrderBy(problemInstanceMap.GetBySecond).ToArray(), characteristics, medianValues);
     50      var feature = KnowledgeCenter.GetFeatures(new [] { problemInstance }, characteristics, medianValues)[0];
     51      var nearestK = features.Select((f, i) => new { ProblemInstanceIndex = i, Feature = f })
     52                             .OrderBy(x => x.Feature.Select((f, i) => (f - feature[i]) * (f - feature[i])).Sum())
     53                             .Take(K);
     54     
    4055      var performances = new Dictionary<IAlgorithm, List<double>>();
    41       for (var k = 0; k < K; k++) {
    42         if (distances.Count == 0) break;
    43         var min = distances.MinItems(x => x.Value).First();
    44         // lookup algorithm performances in min
    45         var perfs = kc.GetAlgorithmPerformance(min.Key);
    46         if (perfs.Count == 0) {
    47           k--;
    48           continue;
    49         }
     56      foreach (var next in nearestK) {
     57        var perfs = performance[problemInstanceMap.GetByFirst(next.ProblemInstanceIndex)];
     58        if (perfs.Count == 0) continue;
     59       
    5060        foreach (var p in perfs) {
    5161          var ert = p.Value;
     
    5666          } else erts.Add(ert);
    5767        }
    58         distances.Remove(min.Key);
    5968      }
    6069
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Recommenders/KNearestNeighborRecommender.cs

    r13787 r13791  
    2323using HeuristicLab.Core;
    2424using HeuristicLab.Data;
     25using HeuristicLab.Optimization;
    2526using HeuristicLab.Parameters;
    2627using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     28using System.Linq;
    2729
    2830namespace HeuristicLab.OptimizationExpertSystem.Common {
     
    3739    [StorableConstructor]
    3840    private KNearestNeighborRecommender(bool deserializing) : base(deserializing) { }
    39     private KNearestNeighborRecommender(KNearestNeighborRecommender original, Cloner cloner)
    40       : base(original, cloner) { }
     41    private KNearestNeighborRecommender(KNearestNeighborRecommender original, Cloner cloner) : base(original, cloner) { }
    4142    public KNearestNeighborRecommender() {
    42       Parameters.Add(new FixedValueParameter<IntValue>("K", "The number of nearest neighbors to consider.", new IntValue(5)));
     43      Parameters.Add(new FixedValueParameter<IntValue>("K", "The number of nearest neighbors to consider.", new IntValue(3)));
    4344    }
    4445
     
    4748    }
    4849
    49     public IRecommendationModel TrainModel(KnowledgeCenter kc, string[] characteristics) {
    50       return new KNearestNeighborModel(KParameter.Value.Value, characteristics);
     50    public IRecommendationModel TrainModel(IRun[] problemInstances, KnowledgeCenter kc, string[] characteristics) {
     51      var perfData = problemInstances.Select(pi => new { ProblemInstance = pi, Performance = kc.GetAlgorithmPerformance(pi) })
     52                                     .ToDictionary(x => x.ProblemInstance, x => x.Performance);
     53      return new KNearestNeighborModel(KParameter.Value.Value, perfData, characteristics);
    5154    }
    5255  }
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Recommenders/OverallBestRecommender.cs

    r13787 r13791  
    2525using HeuristicLab.Data;
    2626using HeuristicLab.Optimization;
    27 using HeuristicLab.Parameters;
    2827using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2928using System;
     
    3938      get { return (IFixedValueParameter<DoubleValue>)Parameters["NeighborhoodFactor"]; }
    4039    }
    41 
    42     public double NeighborhoodFactor {
    43       get { return NeighborhoodFactorParameter.Value.Value; }
    44       set { NeighborhoodFactorParameter.Value.Value = value; }
    45     }
    4640   
    4741    [StorableConstructor]
    4842    private OverallBestRecommender(bool deserializing) : base(deserializing) { }
    49     private OverallBestRecommender(OverallBestRecommender original, Cloner cloner)
    50       : base(original, cloner) { }
    51     public OverallBestRecommender() {
    52       Parameters.Add(new FixedValueParameter<DoubleValue>("NeighborhoodFactor", "Penalize neighbors that are far away.", new DoubleValue(5)));
    53     }
     43    private OverallBestRecommender(OverallBestRecommender original, Cloner cloner) : base(original, cloner) { }
     44    public OverallBestRecommender() { }
    5445
    5546    public override IDeepCloneable Clone(Cloner cloner) {
     
    5748    }
    5849
    59     public IRecommendationModel TrainModel(KnowledgeCenter kc, string[] characteristics) {
     50    public IRecommendationModel TrainModel(IRun[] problemInstances, KnowledgeCenter kc, string[] characteristics) {
    6051      var instances = new List<Tuple<IAlgorithm, double>>();
    6152      foreach (var relevantRuns in kc.GetKnowledgeBaseByAlgorithm()) {
    6253        var algorithm = relevantRuns.Key;
    6354        var pis = relevantRuns.Value.Select(x => ((StringValue)x.Parameters["Problem Name"]).Value).Distinct()
    64                               .Select(x => Tuple.Create(x, kc.ProblemInstances.SingleOrDefault(y => ((StringValue)y.Parameters["Problem Name"]).Value == x)))
     55                              .Select(x => Tuple.Create(x, problemInstances.SingleOrDefault(y => ((StringValue)y.Parameters["Problem Name"]).Value == x)))
    6556                              .Where(x => x.Item2 != null)
    6657                              .Select(x => Tuple.Create(x.Item1, ((DoubleValue)x.Item2.Parameters["BestKnownQuality"]).Value))
     
    7061        foreach (var problemRuns in relevantRuns.Value.GroupBy(x => ((StringValue)x.Parameters["Problem Name"]).Value)) {
    7162          var bkq = pis[problemRuns.Key];
    72           var ert = ExpectedRuntimeHelper.CalculateErt(problemRuns.ToList(), "QualityPerEvaluations", (kc.Maximization ? (1 - kc.MinimumTarget.Value) : (1 + kc.MinimumTarget.Value)) * bkq, kc.Maximization).ExpectedRuntime;
     63          var ert = ExpectedRuntimeHelper.CalculateErt(problemRuns.ToList(), "QualityPerEvaluations", kc.GetTarget(bkq, kc.Maximization), kc.Maximization).ExpectedRuntime;
    7364          if (double.IsNaN(ert)) ert = int.MaxValue;
    7465          avgERT += ert;
Note: See TracChangeset for help on using the changeset viewer.