Changeset 16499


Ignore:
Timestamp:
01/04/19 15:04:26 (3 months ago)
Author:
bburlacu
Message:

#2977: Implement Pearson R2 & Tree Similarity Evaluator.

Location:
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj

    r15198 r16499  
    121121    <Compile Include="MultiObjective\PearsonRSquaredNestedTreeSizeEvaluator.cs" />
    122122    <Compile Include="MultiObjective\PearsonRSquaredNumberOfVariablesEvaluator.cs" />
     123    <Compile Include="MultiObjective\PearsonRSquaredAverageSimilarityEvaluator.cs" />
    123124    <Compile Include="MultiObjective\PearsonRSquaredTreeComplexityEvaluator.cs" />
    124125    <Compile Include="MultiObjective\SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs" />
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredAverageSimilarityEvaluator.cs

    r16303 r16499  
    2222using System;
    2323using System.Collections.Generic;
     24using System.Diagnostics;
     25using System.Linq;
    2426using HeuristicLab.Common;
    2527using HeuristicLab.Core;
    2628using HeuristicLab.Data;
    2729using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     30using HeuristicLab.Parameters;
    2831using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2932
    3033namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
    31   [Item("Pearson R² & Tree Complexity Evaluator", "Calculates the Pearson R² and the tree complexity of a symbolic regression solution.")]
     34  [Item("Pearson R² & Average Similarity Evaluator", "Calculates the Pearson R² and the average similarity of a symbolic regression solution candidate.")]
    3235  [StorableClass]
    33   public class PearsonRSquaredTreeComplexityEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
     36  public class PearsonRSquaredAverageSimilarityEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
     37    private const string StrictSimilarityParameterName = "StrictSimilarity";
     38
     39    private readonly object locker = new object();
     40
     41    public IFixedValueParameter<BoolValue> StrictSimilarityParameter {
     42      get { return (IFixedValueParameter<BoolValue>)Parameters[StrictSimilarityParameterName]; }
     43    }
     44
     45    public bool StrictSimilarity {
     46      get { return StrictSimilarityParameter.Value.Value; }
     47    }
     48
    3449    [StorableConstructor]
    35     protected PearsonRSquaredTreeComplexityEvaluator(bool deserializing) : base(deserializing) { }
    36     protected PearsonRSquaredTreeComplexityEvaluator(PearsonRSquaredTreeComplexityEvaluator original, Cloner cloner)
     50    protected PearsonRSquaredAverageSimilarityEvaluator(bool deserializing) : base(deserializing) { }
     51    protected PearsonRSquaredAverageSimilarityEvaluator(PearsonRSquaredAverageSimilarityEvaluator original, Cloner cloner)
    3752      : base(original, cloner) {
    3853    }
    3954    public override IDeepCloneable Clone(Cloner cloner) {
    40       return new PearsonRSquaredTreeComplexityEvaluator(this, cloner);
     55      return new PearsonRSquaredAverageSimilarityEvaluator(this, cloner);
    4156    }
    4257
    43     public PearsonRSquaredTreeComplexityEvaluator() : base() { }
     58    public PearsonRSquaredAverageSimilarityEvaluator() : base() {
     59      Parameters.Add(new FixedValueParameter<BoolValue>(StrictSimilarityParameterName, "Use strict similarity calculation.", new BoolValue(false)));
     60    }
    4461
    4562    public override IEnumerable<bool> Maximization { get { return new bool[2] { true, false }; } } // maximize R² and minimize model complexity
     
    6178    }
    6279
    63     public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
     80    public double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
    6481      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
    6582      if (decimalPlaces >= 0)
    6683        r2 = Math.Round(r2, decimalPlaces);
    67       return new double[2] { r2, SymbolicDataAnalysisModelComplexityCalculator.CalculateComplexity(solution) };
     84
     85      var variables = ExecutionContext.Scope.Variables;
     86      if (!variables.ContainsKey("AverageSimilarity")) {
     87        lock (locker) {
     88          CalculateAverageSimilarities(ExecutionContext.Scope.Parent.SubScopes.Where(x => x.Variables.ContainsKey("SymbolicExpressionTree")).ToArray(), StrictSimilarity);
     89
     90        }
     91      }
     92
     93      double avgSim = ((DoubleValue)variables["AverageSimilarity"].Value).Value;
     94      return new double[2] { r2, avgSim };
    6895    }
    6996
     
    82109      return quality;
    83110    }
     111
     112    private readonly Stopwatch sw = new Stopwatch();
     113    public void CalculateAverageSimilarities(IScope[] treeScopes, bool strict) {
     114      var trees = treeScopes.Select(x => (ISymbolicExpressionTree)x.Variables["SymbolicExpressionTree"].Value).ToArray();
     115      var similarityMatrix = SymbolicExpressionTreeHash.ComputeSimilarityMatrix(trees, simplify: false, strict: strict);
     116
     117      for (int i = 0; i < treeScopes.Length; ++i) {
     118        var scope = treeScopes[i];
     119        var avgSimilarity = 0d;
     120        for (int j = 0; j < trees.Length; ++j) {
     121          if (i == j) continue;
     122          avgSimilarity += similarityMatrix[i, j];
     123        }
     124        avgSimilarity /= trees.Length - 1;
     125
     126        if (scope.Variables.ContainsKey("AverageSimilarity")) {
     127          ((DoubleValue)scope.Variables["AverageSimilarity"].Value).Value = avgSimilarity;
     128        } else {
     129          scope.Variables.Add(new Core.Variable("AverageSimilarity", new DoubleValue(avgSimilarity)));
     130        }
     131      }
     132    }
    84133  }
    85134}
Note: See TracChangeset for help on using the changeset viewer.