Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/19/16 12:40:40 (8 years ago)
Author:
abeham
Message:

#2457: worked on recommendation algorithms

Location:
branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3
Files:
4 added
2 edited

Legend:

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

    r13757 r13774  
    7878      <Private>False</Private>
    7979    </Reference>
     80    <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     81      <SpecificVersion>False</SpecificVersion>
     82      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
     83      <Private>False</Private>
     84    </Reference>
    8085    <Reference Include="HeuristicLab.Clients.OKB-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    8186      <SpecificVersion>False</SpecificVersion>
     
    120125    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
    121126      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
     127      <Private>False</Private>
     128    </Reference>
     129    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     130      <SpecificVersion>False</SpecificVersion>
     131      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
    122132      <Private>False</Private>
    123133    </Reference>
     
    148158  </ItemGroup>
    149159  <ItemGroup>
     160    <Compile Include="OverallBestRecommender.cs" />
     161    <Compile Include="DistanceWeightedRecommender.cs" />
     162    <Compile Include="IAlgorithmInstanceRecommender.cs" />
     163    <Compile Include="KNearestNeighborRecommender.cs" />
    150164    <Compile Include="KnowledgeCenter.cs" />
    151165    <Compile Include="Plugin.cs" />
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/KnowledgeCenter.cs

    r13759 r13774  
    3030using HeuristicLab.Optimization;
    3131using HeuristicLab.Persistence.Default.Xml;
     32using HeuristicLab.Problems.DataAnalysis;
    3233using HeuristicLab.Random;
    3334using System;
     
    5051    public string Filename { get; set; }
    5152
    52     public static new Image StaticItemImage {
     53    public static Image StaticItemImage {
    5354      get { return VSImageLibrary.Library; }
    5455    }
     
    8485    }
    8586
    86     private readonly ItemList<IAlgorithm> suggestedInstances;
    87     private readonly ReadOnlyItemList<IAlgorithm> readOnlySuggestedInstances;
    88     public ReadOnlyItemList<IAlgorithm> SuggestedInstances {
    89       get { return readOnlySuggestedInstances; }
     87    private readonly ItemList<IAlgorithm> algorithmInstances;
     88    private readonly ReadOnlyItemList<IAlgorithm> readonlyAlgorithmInstances;
     89    public ReadOnlyItemList<IAlgorithm> AlgorithmInstances {
     90      get { return readonlyAlgorithmInstances; }
    9091    }
    9192
     
    101102    }
    102103
    103     private readonly EnumValue<ProblemInstanceProximityType> problemInstanceProximity;
    104     public EnumValue<ProblemInstanceProximityType> ProblemInstanceProximity {
    105       get { return problemInstanceProximity; }
    106     }
    107 
    108     private readonly DoubleValue problemInstanceNeighborhoodFactor;
    109     public DoubleValue ProblemInstanceNeighborhoodFactor {
    110       get { return problemInstanceNeighborhoodFactor; }
     104    private IAlgorithmInstanceRecommender algorithmInstanceRecommender;
     105    public IAlgorithmInstanceRecommender AlgorithmInstanceRecommender {
     106      get { return algorithmInstanceRecommender; }
     107      set { algorithmInstanceRecommender = value; }
    111108    }
    112109
     
    125122    private BidirectionalDictionary<long, IRun> problemId2ProblemInstanceMapping;
    126123   
    127     private bool Maximization {
     124    public bool Maximization {
    128125      get { return Problem != null && Problem.ProblemId >= 0 && ((IValueParameter<BoolValue>)Problem.MaximizationParameter).Value.Value; }
    129126    }
     
    135132      seededRuns = new RunCollection();
    136133      knowledgeBase = new RunCollection();
    137       suggestedInstances = new ItemList<IAlgorithm>();
    138       readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
     134      algorithmInstances = new ItemList<IAlgorithm>();
     135      readonlyAlgorithmInstances = algorithmInstances.AsReadOnly();
    139136      problemInstances = new RunCollection();
    140137      problemCharacteristics = new CheckedItemList<StringValue>();
    141       problemInstanceProximity = new EnumValue<ProblemInstanceProximityType>(ProblemInstanceProximityType.FeatureSpace);
    142       problemInstanceNeighborhoodFactor = new DoubleValue(5);
    143138      readonlyProblemCharacteristics = problemCharacteristics.AsReadOnly();
     139      algorithmInstanceRecommender = new OverallBestRecommender(this);
    144140      problem = new SingleObjectiveOKBProblem();
    145141      algorithmId2RunMapping = new BidirectionalLookup<long, IRun>();
     
    176172      problemCharacteristics.CollectionReset += CharacteristicChanged;
    177173      problemCharacteristics.CheckedItemsChanged += CharacteristicChanged;
    178       problemInstanceProximity.ValueChanged += ProblemInstanceProximityChanged;
    179       problemInstanceNeighborhoodFactor.ValueChanged += ProblemInstanceProximityChanged;
    180174    }
    181175
     
    205199      UpdateInstanceProjection();
    206200    }
    207 
    208     private void ProblemInstanceProximityChanged(object sender, EventArgs e) {
    209       UpdateSuggestions();
    210     }
    211 
     201   
    212202    public bool IsCurrentInstance(IRun run) {
    213203      if (!problemId2ProblemInstanceMapping.ContainsSecond(run)) return false;
     
    339329
    340330    public Task<ResultCollection> StartAlgorithmAsync(int index, CancellationToken cancellation) {
    341       var selectedInstance = suggestedInstances[index];
     331      var selectedInstance = algorithmInstances[index];
    342332      var algorithmClone = (IAlgorithm)selectedInstance.Clone();
    343333      var problemClone = Problem.CloneProblem() as ISingleObjectiveHeuristicOptimizationProblem;
     
    627617    }
    628618
    629     private void UpdateSuggestions() {
    630       if (Problem == null) return;
    631       var piDistances = GetProblemDistances();
    632       var maxDist = piDistances.Max(x => x.Value);
    633       var instances = new SortedList<double, IAlgorithm>();
     619    public void UpdateSuggestions() {
     620      // TODO: Maintain a separate list of suggested instances
     621      // TODO: expose expected expected run time
     622      algorithmInstances.Replace(AlgorithmInstanceRecommender.GetRanking());
     623    }
     624
     625    public Dictionary<IAlgorithm, double> GetAlgorithmPerformance(IRun problemInstance) {
     626      if (!problemInstance.Parameters.ContainsKey("BestKnownQuality")) return new Dictionary<IAlgorithm, double>();
     627      var target = GetTarget(((DoubleValue)problemInstance.Parameters["BestKnownQuality"]).Value);
     628      return knowledgeBase.Where(x => ((StringValue)x.Parameters["Problem Name"]).Value == ((StringValue)problemInstance.Parameters["Problem Name"]).Value)
     629                          .GroupBy(x => algorithmId2AlgorithmInstanceMapping.GetByFirst(algorithmId2RunMapping.GetBySecond(x).Single()))
     630                          .ToDictionary(x => x.Key, x => ExpectedRuntimeHelper.CalculateErt(x.ToList(), "QualityPerEvaluations", target, Maximization).ExpectedRuntime);
     631    }
     632
     633    public Dictionary<IAlgorithm, List<IRun>> GetKnowledgeBaseByAlgorithm() {
     634      return KnowledgeBase.GroupBy(x => algorithmId2AlgorithmInstanceMapping.GetByFirst(algorithmId2RunMapping.GetBySecond(x).Single()))
     635                          .ToDictionary(x => x.Key, x => x.ToList());
     636    }
     637
     638    public IEnumerable<IRegressionProblem> GetDataAnalysisProblem(double target) {
     639      if (Problem == null) yield break;
     640      var characteristics = GetProblemCharacteristics();
     641      // TODO: knowledgebase only stores problem name as a string
     642      // this doesn't work if there are two equally named problem instances
     643      var problemMap = ProblemInstances.Select(x => new { Key = ((StringValue)x.Parameters["Problem Name"]).Value, Value = x })
     644                                       .ToDictionary(x => x.Key, x => x.Value);
    634645      foreach (var relevantRuns in knowledgeBase.GroupBy(x => algorithmId2RunMapping.GetBySecond(x).Single())) {
    635         var algorithm = algorithmId2AlgorithmInstanceMapping.GetByFirst(relevantRuns.Key);
    636         Func<double, double> distFunc = (d) => Math.Exp(ProblemInstanceNeighborhoodFactor.Value * (-d / maxDist));
    637         var pis = relevantRuns.Select(x => ((StringValue)x.Parameters["Problem Name"]).Value).Distinct()
    638                               .Select(x => Tuple.Create(x, ProblemInstances.SingleOrDefault(y => ((StringValue)y.Parameters["Problem Name"]).Value == x)))
    639                               .Where(x => x.Item2 != null)
    640                               .Select(x => Tuple.Create(x.Item1, distFunc(piDistances[x.Item2]), ((DoubleValue)x.Item2.Parameters["BestKnownQuality"]).Value))
    641                               .ToDictionary(x => x.Item1, x => Tuple.Create(x.Item2, x.Item3));
    642         var sumPis = pis.Sum(x => x.Value.Item1);
    643         var avgERT = 0.0;
    644         foreach (var problemRuns in relevantRuns.GroupBy(x => ((StringValue)x.Parameters["Problem Name"]).Value)) {
    645           Tuple<double, double> info;
    646           if (!pis.TryGetValue(problemRuns.Key, out info)) continue;
    647           var convGraph = new List<List<Tuple<double, double>>>();
    648           foreach (var run in problemRuns) {
    649             var current = new List<Tuple<double, double>>();
    650             var performanceGraph = ((IndexedDataTable<double>)run.Results["QualityPerEvaluations"]);
    651             current.AddRange(performanceGraph.Rows.First().Values.TakeWhile(v => v.Item1 < MaximumEvaluations.Value));
    652             if (current.Count > 0) {
    653               current.Add(Tuple.Create((double)MaximumEvaluations.Value, current.Last().Item2));
    654               convGraph.Add(current);
    655             }
    656           }
    657           var ert = ExpectedRuntimeHelper.CalculateErt(convGraph, (Maximization ? (1 - MinimumTarget.Value) : (1 + MinimumTarget.Value)) * info.Item2, Maximization).ExpectedRuntime;
    658           if (double.IsNaN(ert)) {
    659             ert = ExpectedRuntimeHelper.CalculateErt(problemRuns.ToList(), "QualityPerEvaluations", (Maximization ? (1 - MinimumTarget.Value) : (1 + MinimumTarget.Value)) * info.Item2, Maximization).ExpectedRuntime;
    660             if (double.IsNaN(ert)) ert = int.MaxValue;
    661           }
    662           avgERT += info.Item1 * ert;
    663         }
    664         avgERT /= sumPis;
    665         if (instances.ContainsKey(avgERT)) {
    666           avgERT += new System.Random().NextDouble();
    667         }
    668         instances.Add(avgERT, algorithm);
    669       }
    670 
    671       var instanceLadder = instances.Select(x => (IAlgorithm)x.Value.Clone()).ToList();
    672       suggestedInstances.Replace(instanceLadder);
    673     }
    674 
    675     private Dictionary<IRun, double> GetProblemDistances() {
     646        var problemRuns = relevantRuns.GroupBy(x => ((StringValue)x.Parameters["Problem Name"]).Value).ToList();
     647        var ds = new ModifiableDataset();
     648        ds.AddVariable("Problem Name", new List<string>());
     649        foreach (var pc in ProblemCharacteristics.CheckedItems)
     650          ds.AddVariable(pc.Value.Value, new List<double>());
     651        ds.AddVariable("ERT", new List<double>());
     652        var max = Maximization;
     653        foreach (var pr in problemRuns) {
     654          var prob = problemMap[pr.Key];
     655          var features = characteristics[prob];
     656          var bkq = ((DoubleValue)prob.Parameters["BestKnownQuality"]).Value;
     657          var ert = ExpectedRuntimeHelper.CalculateErt(pr.ToList(), "QualityPerEvaluations", GetTarget(bkq), max).ExpectedRuntime;
     658          if (double.IsNaN(ert)) ert = int.MaxValue;
     659          ds.AddRow(new object[] { pr.Key }.Concat(features.Cast<object>()).Concat(new object[] { ert }));
     660        }
     661        var datAnalysisData = new RegressionProblemData(ds, ProblemCharacteristics.CheckedItems.Select(x => x.Value.Value), "ERT");
     662        var result = new RegressionProblem() {
     663          Name = algorithmId2AlgorithmInstanceMapping.GetByFirst(relevantRuns.Key).Name
     664        };
     665        result.ProblemDataParameter.Value = datAnalysisData;
     666        yield return result;
     667      }
     668    }
     669
     670    private double GetTarget(double bestKnownQuality) {
     671      return bestKnownQuality * (Maximization ? (1 - MinimumTarget.Value) : (1 + MinimumTarget.Value));
     672    }
     673
     674    public Dictionary<IRun, double> GetProblemDistances(ProblemInstanceProximityType proximityType) {
    676675      var result = new Dictionary<IRun, double>();
    677676      var currentInstance = problemId2ProblemInstanceMapping.GetByFirst(Problem.ProblemId);
    678       switch (ProblemInstanceProximity.Value) {
     677      switch (proximityType) {
    679678        case ProblemInstanceProximityType.MDS:
    680679        case ProblemInstanceProximityType.PCA:
    681680        case ProblemInstanceProximityType.SOM:
    682681          double xa, ya;
    683           GetProjectionCoordinates(currentInstance, out xa, out ya);
     682          GetProjectionCoordinates(currentInstance, proximityType, out xa, out ya);
    684683          foreach (var b in ProblemInstances) {
     684            if (b == currentInstance) continue;
    685685            double xb, yb;
    686             GetProjectionCoordinates(b, out xb, out yb);
     686            GetProjectionCoordinates(b, proximityType, out xb, out yb);
    687687            var d = Math.Sqrt((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb));
    688688            result[b] = d;
     
    693693          var cF = features[currentInstance];
    694694          foreach (var b in ProblemInstances) {
     695            if (b == currentInstance) continue;
    695696            var sum = features[b].Select((t, f) => (cF[f] - t) * (cF[f] - t)).Sum();
    696697            result[b] = Math.Sqrt(sum);
    697698          }
    698699          break;
    699         default: throw new InvalidOperationException(string.Format("Unkonwn proximity type {0}", ProblemInstanceProximity.Value));
     700        default: throw new InvalidOperationException(string.Format("Unkonwn proximity type {0}", proximityType));
    700701      }
    701702      return result;
    702703    }
    703704
    704     private void GetProjectionCoordinates(IRun problemInstance, out double x, out double y) {
    705       x = ((DoubleValue)problemInstance.Results["Projection." + ProblemInstanceProximity.Value + ".X"]).Value;
    706       y = ((DoubleValue)problemInstance.Results["Projection." + ProblemInstanceProximity.Value + ".Y"]).Value;
    707       if (ProblemInstanceProximity.Value == ProblemInstanceProximityType.SOM) {
     705    private void GetProjectionCoordinates(IRun problemInstance, ProblemInstanceProximityType proximityType, out double x, out double y) {
     706      x = ((DoubleValue)problemInstance.Results["Projection." + proximityType + ".X"]).Value;
     707      y = ((DoubleValue)problemInstance.Results["Projection." + proximityType + ".Y"]).Value;
     708      if (proximityType == ProblemInstanceProximityType.SOM) {
    708709        x = Math.Floor(x);
    709710        y = Math.Floor(y);
Note: See TracChangeset for help on using the changeset viewer.