Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 16591 was 16591, checked in by chaider, 5 years ago

#2971 Fixed checking if a given interval is in another interval

File size: 7.7 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      return base.InstrumentedApply();
54    }
55
56    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
57      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
58      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
59      OnlineCalculatorError errorState;
60
61      IntervalConstraintsParser parser = new IntervalConstraintsParser();
62      var constraints = parser.Parse(((RegressionProblemData) problemData).IntervalConstraintsParameter.Value.Value);
63      var intervalInterpreter = new IntervalInterpreter();
64      var variableRanges = ((RegressionProblemData) problemData).VariableRangesParameter.Value.VariableIntervals;
65
66
67      foreach (var constraint in constraints) {
68        if (constraint.Variable != null && !variableRanges.ContainsKey(constraint.Variable))
69          throw new ArgumentException($"The given variable {constraint.Variable} in the constraint does not exists in the model.", nameof(IntervalConstraintsParser));
70        if (!constraint.IsDerivation) {
71          var res = intervalInterpreter.GetSymbolicExressionTreeInterval(solution, variableRanges);
72          if (!IntervalInBoundaries(constraint.Interval, res, constraint.InclusiveLowerBound,
73            constraint.InclusiveUpperBound)) {
74            return 0;
75          }
76        } else {
77          var tree = solution;
78          for (var i = 0; i < constraint.NumberOfDerivation; ++i) {
79            tree = DerivativeCalculator.Derive(tree, constraint.Variable);
80          }
81          var res = intervalInterpreter.GetSymbolicExressionTreeInterval(tree, variableRanges);
82          if (!IntervalInBoundaries(constraint.Interval, res, constraint.InclusiveLowerBound,
83            constraint.InclusiveUpperBound)) {
84            return 0;
85          }
86        }
87      }
88
89
90      double r;
91      if (applyLinearScaling) {
92        var rCalculator = new OnlinePearsonsRCalculator();
93        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, rCalculator, problemData.Dataset.Rows);
94        errorState = rCalculator.ErrorState;
95        r = rCalculator.R;
96      } else {
97        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
98        r = OnlinePearsonsRCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
99      }
100      if (errorState != OnlineCalculatorError.None) return double.NaN;
101      return r*r;
102    }
103
104    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows) {
105      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
106      EstimationLimitsParameter.ExecutionContext = context;
107      ApplyLinearScalingParameter.ExecutionContext = context;
108
109      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
110
111      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
112      EstimationLimitsParameter.ExecutionContext = null;
113      ApplyLinearScalingParameter.ExecutionContext = null;
114
115      return r2;
116    }
117
118    private static bool IntervalInBoundaries(Interval i1, Interval i2, bool inclusiveLower, bool inclusiveUpper) {
119      if (double.IsNegativeInfinity(i1.LowerBound) && double.IsPositiveInfinity(i1.UpperBound))
120        return true;
121      //Left-unbounded and right-bounded:
122      if (double.IsNegativeInfinity(i1.LowerBound)) {
123        if (inclusiveUpper)
124          return i2.LowerBound <= i1.UpperBound && i2.UpperBound <= i1.UpperBound;
125        return i2.LowerBound < i1.UpperBound && i2.UpperBound < i1.UpperBound;
126      }
127
128      //Left-bounded and right-unbounded:
129      if (double.IsPositiveInfinity(i1.UpperBound)) {
130        if (inclusiveLower)
131          return i2.LowerBound >= i1.LowerBound && i2.UpperBound >= i1.LowerBound;
132        return i2.LowerBound > i1.LowerBound && i2.UpperBound > i1.LowerBound;
133      }
134
135      //Proper and bounded:
136      //Closed:
137      if (inclusiveLower && inclusiveUpper) {
138        return i1.LowerBound <= i2.LowerBound && i2.UpperBound <= i1.UpperBound;
139      }
140      //Open:
141      if (!inclusiveLower && !inclusiveUpper) {
142        return i1.LowerBound < i2.LowerBound && i2.UpperBound < i1.UpperBound;
143      }
144      //Left-closed, right-open:
145      if (inclusiveLower) {
146        return i1.LowerBound <= i2.LowerBound && i2.UpperBound < i1.UpperBound;
147      }
148      //Left-open, right-closed:
149      return i1.LowerBound < i2.LowerBound && i2.UpperBound <= i1.UpperBound;
150    }
151  }
152}
Note: See TracBrowser for help on using the repository browser.