source: branches/2971_named_intervals/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator.cs @ 16589

Last change on this file since 16589 was 16589, checked in by chaider, 5 months ago

#2971

  • Added new Evaluator to evaulate Pearson RSquared with repsect to given constraints
  • changes in SymbolicRegressionSolution
File size: 6.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
31  [Item("Pearson R² Constraint Evaluator", "Calculates the square of the pearson correlation coefficient (also known as coefficient of determination) of a symbolic regression solution.")]
32  [StorableClass]
33  public class SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
34    [StorableConstructor]
35    protected SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator(bool deserializing) : base(deserializing) { }
36    protected SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator(SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator original, Cloner cloner)
37      : base(original, cloner) {
38    }
39    public override IDeepCloneable Clone(Cloner cloner) {
40      return new SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator(this, cloner);
41    }
42
43    public SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator() : base() { }
44
45    public override bool Maximization { get { return true; } }
46
47    public override IOperation InstrumentedApply() {
48      var solution = SymbolicExpressionTreeParameter.ActualValue;
49      IEnumerable<int> rows = GenerateRowsToEvaluate();
50
51      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
52      QualityParameter.ActualValue = new DoubleValue(quality);
53
54      return base.InstrumentedApply();
55    }
56
57    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
58      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
59      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
60      OnlineCalculatorError errorState;
61
62      IntervalConstraintsParser parser = new IntervalConstraintsParser();
63      var constraints = parser.Parse(((RegressionProblemData) problemData).IntervalConstraintsParameter.Value.Value);
64      var intervalInterpreter = new IntervalInterpreter();
65      var variableRanges = ((RegressionProblemData) problemData).VariableRangesParameter.Value.VariableIntervals;
66
67
68      foreach (var constraint in constraints) {
69        if (!variableRanges.ContainsKey(constraint.Variable))
70          throw new ArgumentException($"The given variable {constraint.Variable} in the constraint does not exists in the model.", nameof(IntervalConstraintsParser));
71        if (!constraint.IsDerivation) {
72          var res = intervalInterpreter.GetSymbolicExressionTreeInterval(solution, variableRanges);
73          if (!IntervalInBoundaries(constraint.Interval, res, constraint.InclusiveLowerBound,
74            constraint.InclusiveUpperBound)) {
75            return 0;
76          }
77        } else {
78          var tree = solution;
79          for (var i = 0; i < constraint.NumberOfDerivation; ++i) {
80            tree = DerivativeCalculator.Derive(tree, constraint.Variable);
81          }
82          var res = intervalInterpreter.GetSymbolicExressionTreeInterval(tree, variableRanges);
83          if (!IntervalInBoundaries(constraint.Interval, res, constraint.InclusiveLowerBound,
84            constraint.InclusiveUpperBound)) {
85            return 0;
86          }
87        }
88      }
89
90
91      double r;
92      if (applyLinearScaling) {
93        var rCalculator = new OnlinePearsonsRCalculator();
94        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, rCalculator, problemData.Dataset.Rows);
95        errorState = rCalculator.ErrorState;
96        r = rCalculator.R;
97      } else {
98        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
99        r = OnlinePearsonsRCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
100      }
101      if (errorState != OnlineCalculatorError.None) return double.NaN;
102      return r*r;
103    }
104
105    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows) {
106      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
107      EstimationLimitsParameter.ExecutionContext = context;
108      ApplyLinearScalingParameter.ExecutionContext = context;
109
110      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
111
112      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
113      EstimationLimitsParameter.ExecutionContext = null;
114      ApplyLinearScalingParameter.ExecutionContext = null;
115
116      return r2;
117    }
118
119    private static bool IntervalInBoundaries(Interval i1, Interval i2, bool inclusiveLower, bool inclusiveUpper) {
120      if (inclusiveLower) {
121        if (i2.LowerBound < i1.LowerBound)
122          return false;
123      } else {
124        if (i2.LowerBound <= i1.LowerBound)
125          return false;
126      }
127
128      if (inclusiveUpper) {
129        if (i2.UpperBound > i1.UpperBound)
130          return false;
131      } else {
132        if (i2.UpperBound >= i1.UpperBound)
133          return false;
134      }
135
136      return true;
137    }
138  }
139}
Note: See TracBrowser for help on using the repository browser.