Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMultiSoftConstraintEvaluator.cs @ 17623

Last change on this file since 17623 was 17623, checked in by chaider, 4 years ago

#3076 Added multi objective analyzer and evaluators

File size: 10.0 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25using System.Collections.Generic;
26using System.Linq;
27using HEAL.Attic;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Data;
31using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
32using HeuristicLab.Parameters;
33
34namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.MultiObjective {
35  [Item("Multi Soft Constraints Evaluator",
36    "Calculates the Person R² and the constraints violations of a symbolic regression solution.")]
37  [StorableType("8E9D76B7-ED9C-43E7-9898-01FBD3633880")]
38  public class
39    SymbolicRegressionMultiObjectiveMultiSoftConstraintEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
40    private const string MinIntervalWidthParameterName      = "MinIntervalWidth";
41    private const string MaxIntervalSplitDepthParameterName = "MaxIntervalSplitDepth";
42
43    public IFixedValueParameter<DoubleValue> MinIntervalWidthParameter =>
44      (IFixedValueParameter<DoubleValue>) Parameters[MinIntervalWidthParameterName];
45
46    public IFixedValueParameter<IntValue> MaxIntervalSplitDepthParameter =>
47      (IFixedValueParameter<IntValue>) Parameters[MaxIntervalSplitDepthParameterName];
48
49    public double MinIntervalWidth => MinIntervalWidthParameter.Value.Value;
50
51    public int MaxIntervalSplitDepth => MaxIntervalSplitDepthParameter.Value.Value;
52
53    #region Constructors
54
55    public SymbolicRegressionMultiObjectiveMultiSoftConstraintEvaluator() {
56      Parameters.Add(new FixedValueParameter<DoubleValue>(MinIntervalWidthParameterName, new DoubleValue(1.0)));
57      Parameters.Add(new FixedValueParameter<IntValue>(MaxIntervalSplitDepthParameterName, new IntValue(5)));
58    }
59
60    [StorableConstructor]
61    protected SymbolicRegressionMultiObjectiveMultiSoftConstraintEvaluator(StorableConstructorFlag _) : base(_) { }
62
63    protected SymbolicRegressionMultiObjectiveMultiSoftConstraintEvaluator(
64      SymbolicRegressionMultiObjectiveMultiSoftConstraintEvaluator original, Cloner cloner) : base(original, cloner) { }
65
66    #endregion
67
68    public override IDeepCloneable Clone(Cloner cloner) {
69      return new SymbolicRegressionMultiObjectiveMultiSoftConstraintEvaluator(this, cloner);
70    }
71
72
73    public override IOperation InstrumentedApply() {
74      var rows             = GenerateRowsToEvaluate();
75      var solution         = SymbolicExpressionTreeParameter.ActualValue;
76      var problemData      = ProblemDataParameter.ActualValue;
77      var interpreter      = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
78      var estimationLimits = EstimationLimitsParameter.ActualValue;
79      //var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
80      var applyLinearScaling = false;
81
82      if (UseConstantOptimization)
83        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows,
84                                                                          applyLinearScaling,
85                                                                          ConstantOptimizationIterations,
86                                                                          ConstantOptimizationUpdateVariableWeights,
87                                                                          estimationLimits.Lower,
88                                                                          estimationLimits.Upper);
89
90      var qualities = Calculate(interpreter, solution, estimationLimits.Lower, estimationLimits.Upper, problemData,
91                                rows, applyLinearScaling, DecimalPlaces, MinIntervalWidth, MaxIntervalSplitDepth);
92      QualitiesParameter.ActualValue = new DoubleArray(qualities);
93      return base.InstrumentedApply();
94    }
95
96    public override double[] Evaluate(IExecutionContext context, ISymbolicExpressionTree tree,
97                                      IRegressionProblemData problemData,
98                                      IEnumerable<int> rows) {
99      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
100      EstimationLimitsParameter.ExecutionContext                    = context;
101      ApplyLinearScalingParameter.ExecutionContext                  = context;
102
103      var quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
104                              EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
105                              problemData, rows,
106                              ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces, MinIntervalWidth,
107                              MaxIntervalSplitDepth);
108
109      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
110      EstimationLimitsParameter.ExecutionContext                    = null;
111      ApplyLinearScalingParameter.ExecutionContext                  = null;
112
113      return quality;
114    }
115
116
117    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
118                                     ISymbolicExpressionTree solution, double lowerEstimationLimit,
119                                     double upperEstimationLimit,
120                                     IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling,
121                                     int decimalPlaces, double minIntervalSplitWidth, int maxIntervalSplitDetph) {
122      OnlineCalculatorError errorState;
123      var estimatedValues =
124        interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
125      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
126
127      double nmse;
128
129      var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
130      nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
131      if (errorState != OnlineCalculatorError.None) nmse = double.NaN;
132
133      if (nmse > 1)
134        nmse = 1;
135
136      var constraints    = problemData.IntervalConstraints.Constraints.Where(c => c.Enabled);
137      var variableRanges = problemData.VariableRanges.GetReadonlyDictionary();
138
139      var objectives          = new List<double> {nmse};
140      var intervalInterpreter = new IntervalInterpreter();
141      /*{MinIntervalSplitWidth = minIntervalSplitWidth, MaxIntervalSplitDepth = maxIntervalSplitDetph};*/
142
143      var constraintObjectives = new List<double>();
144      foreach (var c in constraints) {
145        var penalty = ConstraintExceeded(c, intervalInterpreter, variableRanges,
146                                         solution /*, problemData.IntervalSplitting*/);
147        var maxP = 0.1;
148
149        if (double.IsNaN(penalty) || double.IsInfinity(penalty) || penalty > maxP)
150          penalty = maxP;
151
152        constraintObjectives.Add(penalty);
153      }
154
155      objectives.AddRange(constraintObjectives);
156
157      return objectives.ToArray();
158    }
159
160    public static double ConstraintExceeded(IntervalConstraint constraint, IntervalInterpreter intervalInterpreter,
161                                            IReadOnlyDictionary<string, Interval> variableRanges,
162                                            ISymbolicExpressionTree solution /*, bool splitting*/) {
163      if (constraint.Variable != null && !variableRanges.ContainsKey(constraint.Variable))
164        throw new ArgumentException(
165                                    $"The given variable {constraint.Variable} in the constraint does not exists in the model.",
166                                    nameof(IntervalConstraintsParser));
167      Interval resultInterval;
168      if (!constraint.IsDerivative) {
169        resultInterval =
170          intervalInterpreter.GetSymbolicExpressionTreeInterval(solution, variableRanges /*, splitting:splitting*/);
171      }
172      else {
173        var tree = solution;
174        for (var i = 0; i < constraint.NumberOfDerivations; ++i)
175          tree = DerivativeCalculator.Derive(tree, constraint.Variable);
176
177        resultInterval =
178          intervalInterpreter.GetSymbolicExpressionTreeInterval(tree, variableRanges /*, splitting: splitting*/);
179      }
180
181      //Calculate soft-constraints for intervals
182      if (constraint.Interval.Contains(resultInterval)) return 0;
183      var pLower = 0.0;
184      var pUpper = 0.0;
185      if (constraint.Interval.Contains(resultInterval.LowerBound))
186        pLower = 0;
187      else
188        pLower = constraint.Interval.LowerBound - resultInterval.LowerBound;
189
190      if (constraint.Interval.Contains(resultInterval.UpperBound))
191        pUpper = 0;
192      else
193        pUpper = resultInterval.UpperBound - constraint.Interval.UpperBound;
194      var penalty = Math.Abs(pLower) + Math.Abs(pUpper);
195
196      return penalty;
197    }
198
199    public static double Normalize(double val, double min = 0, double max = 10e6) {
200      return (val - min) / (max - min);
201    }
202
203    /*
204     * First objective is to maximize the Pearson R² value
205     * All following objectives have to be minimized ==> Constraints
206     */
207    public override IEnumerable<bool> Maximization {
208      get {
209        var objectives = new List<bool> {false}; //First NMSE ==> min
210        objectives.AddRange(Enumerable.Repeat(false, 3)); //Constraints ==> min
211
212        return objectives;
213      }
214    }
215  }
216}
Note: See TracBrowser for help on using the repository browser.