source: branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintEvaluator.cs @ 17878

Last change on this file since 17878 was 17878, checked in by chaider, 17 months ago

#3076 Removed unused code

File size: 12.0 KB
Line 
1using System;
2using System.CodeDom;
3using System.Collections.Generic;
4using System.Linq;
5using System.Text;
6using System.Threading.Tasks;
7using HEAL.Attic;
8using HeuristicLab.Common;
9using HeuristicLab.Core;
10using HeuristicLab.Data;
11using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
12using HeuristicLab.Parameters;
13using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
14
15namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
16  [Item("Constraints Evaluator", "Calculates NMSE of a symbolic regression solution with respect to constraints.")]
17  [StorableType("27473973-DD8D-4375-997D-942E2280AE8E")]
18  public class SymbolicRegressionSingleObjectiveConstraintEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
19    #region Parameter/Properties
20
21    private const string UseConstantOptimizationParameterName = "Use Constant Optimization";
22
23    private const string ConstantOptimizationIterationsParameterName = "Constant Optimization Iterations";
24
25    private const string UseSoftConstraintsParameterName = "Use Soft Constraints Evaluation";
26
27    private const string BoundsEstimatorParameterName = "Bounds estimator";
28
29    private const string MaximumPenaltyFactorParamterName = "Maximum Penalty Factor";
30
31
32    public IFixedValueParameter<BoolValue> UseConstantOptimizationParameter =>
33      (IFixedValueParameter<BoolValue>)Parameters[UseConstantOptimizationParameterName];
34
35    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter =>
36      (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName];
37
38    public IFixedValueParameter<BoolValue> UseSoftConstraintsParameter =>
39      (IFixedValueParameter<BoolValue>)Parameters[UseSoftConstraintsParameterName];
40
41    public IValueParameter<IBoundsEstimator> BoundsEstimatorParameter =>
42      (IValueParameter<IBoundsEstimator>)Parameters[BoundsEstimatorParameterName];
43    public IFixedValueParameter<DoubleValue> MaximumPenaltyFactorParamter =>
44      (IFixedValueParameter<DoubleValue>)Parameters[MaximumPenaltyFactorParamterName];
45
46    public bool UseConstantOptimization {
47      get => UseConstantOptimizationParameter.Value.Value;
48      set => UseConstantOptimizationParameter.Value.Value = value;
49    }
50
51    public int ConstantOptimizationIterations {
52      get => ConstantOptimizationIterationsParameter.Value.Value;
53      set => ConstantOptimizationIterationsParameter.Value.Value = value;
54    }
55
56    public bool UseSoftConstraints {
57      get => UseSoftConstraintsParameter.Value.Value;
58      set => UseSoftConstraintsParameter.Value.Value = value;
59    }
60
61    public double PenaltyMultiplier {
62      get => 1.0;//PenaltyMultiplierParameter.Value.Value;
63      //set => PenaltyMultiplierParameter.Value.Value = value;
64    }
65
66    public IBoundsEstimator BoundsEstimator {
67      get => BoundsEstimatorParameter.Value;
68      set => BoundsEstimatorParameter.Value = value;
69    }
70
71    public double MaximumPenaltyFactor {
72      get => MaximumPenaltyFactorParamter.Value.Value;
73      set => MaximumPenaltyFactorParamter.Value.Value = value;
74    }
75
76
77    //Use false for maximization, because we try to minimize the NMSE
78    public override bool Maximization => false;
79
80    #endregion
81
82    #region Constructors/Cloning
83
84    [StorableConstructor]
85    protected SymbolicRegressionSingleObjectiveConstraintEvaluator(StorableConstructorFlag _) : base(_) { }
86
87    protected SymbolicRegressionSingleObjectiveConstraintEvaluator(
88      SymbolicRegressionSingleObjectiveConstraintEvaluator original, Cloner cloner) : base(original, cloner) { }
89
90    public SymbolicRegressionSingleObjectiveConstraintEvaluator() {
91      Parameters.Add(new FixedValueParameter<BoolValue>(UseConstantOptimizationParameterName,
92        "Define whether constant optimization is active or not.", new BoolValue(false)));
93      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName,
94        "Define how many constant optimization steps should be performed.", new IntValue(10)));
95      Parameters.Add(new FixedValueParameter<BoolValue>(UseSoftConstraintsParameterName,
96        "Define whether the constraints are penalized by soft or hard constraints.", new BoolValue(false)));
97      Parameters.Add(new ValueParameter<IBoundsEstimator>(BoundsEstimatorParameterName,
98        "Select the Boundsestimator.", new IABoundsEstimator()));
99      Parameters.Add(new FixedValueParameter<DoubleValue>(MaximumPenaltyFactorParamterName,
100        "Specify how hard constraints violations should be punished", new DoubleValue(1.5)));
101    }
102
103    [StorableHook(HookType.AfterDeserialization)]
104    private void AfterDeserialization() {
105      if (!Parameters.ContainsKey(UseConstantOptimizationParameterName)) {
106        Parameters.Add(new FixedValueParameter<BoolValue>(UseConstantOptimizationParameterName,
107          "Define whether constant optimization is active or not.", new BoolValue(false)));
108      }
109
110      if (!Parameters.ContainsKey(ConstantOptimizationIterationsParameterName)) {
111        Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName,
112          "Define how many constant optimization steps should be performed.", new IntValue(10)));
113      }
114
115      if (!Parameters.ContainsKey(UseSoftConstraintsParameterName)) {
116        Parameters.Add(new FixedValueParameter<BoolValue>(UseSoftConstraintsParameterName,
117          "Define whether the constraints are penalized by soft or hard constraints.", new BoolValue(false)));
118      }
119
120      if (!Parameters.ContainsKey(BoundsEstimatorParameterName))
121        Parameters.Add(new ValueParameter<IBoundsEstimator>(BoundsEstimatorParameterName,
122          "Select the Boundsestimator.", new IABoundsEstimator()));
123
124      if (!Parameters.ContainsKey(MaximumPenaltyFactorParamterName)) {
125        Parameters.Add(new FixedValueParameter<DoubleValue>(MaximumPenaltyFactorParamterName,
126          "Specify how hard constraints violations should be punished", new DoubleValue(1.5)));
127      }
128    }
129
130    public override IDeepCloneable Clone(Cloner cloner) {
131      return new SymbolicRegressionSingleObjectiveConstraintEvaluator(this, cloner);
132    }
133
134    #endregion
135
136    public override IOperation InstrumentedApply() {
137      var rows = GenerateRowsToEvaluate();
138      var solution = SymbolicExpressionTreeParameter.ActualValue;
139      var problemData = ProblemDataParameter.ActualValue;
140      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
141      var estimationLimits = EstimationLimitsParameter.ActualValue;
142      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
143
144      if (UseConstantOptimization) {
145        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows,
146          false, ConstantOptimizationIterations, true,
147          estimationLimits.Lower, estimationLimits.Upper);
148      } else {
149        if (applyLinearScaling) {
150          //Check for interval arithmetic grammar
151          //remove scaling nodes for linear scaling evaluation
152          var rootNode = new ProgramRootSymbol().CreateTreeNode();
153          var startNode = new StartSymbol().CreateTreeNode();
154          SymbolicExpressionTree newTree = null;
155          foreach (var node in solution.IterateNodesPrefix())
156            if (node.Symbol.Name == "Scaling") {
157              for (var i = 0; i < node.SubtreeCount; ++i) startNode.AddSubtree(node.GetSubtree(i));
158              rootNode.AddSubtree(startNode);
159              newTree = new SymbolicExpressionTree(rootNode);
160              break;
161            }
162
163          //calculate alpha and beta for scaling
164          var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(newTree, problemData.Dataset, rows);
165          var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
166          OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out var alpha, out var beta,
167            out var errorState);
168          //Set alpha and beta to the scaling nodes from ia grammar
169          foreach (var node in solution.IterateNodesPrefix())
170            if (node.Symbol.Name == "Offset") {
171              node.RemoveSubtree(1);
172              var alphaNode = new ConstantTreeNode(new Constant()) { Value = alpha };
173              node.AddSubtree(alphaNode);
174            } else if (node.Symbol.Name == "Scaling") {
175              node.RemoveSubtree(1);
176              var betaNode = new ConstantTreeNode(new Constant()) { Value = beta };
177              node.AddSubtree(betaNode);
178            }
179        }
180      }
181
182      var quality = Calculate(interpreter, solution, estimationLimits.Lower, estimationLimits.Upper, problemData, rows,
183        PenaltyMultiplier, BoundsEstimator, UseSoftConstraints, MaximumPenaltyFactor);
184      QualityParameter.ActualValue = new DoubleValue(quality);
185
186      return base.InstrumentedApply();
187    }
188
189    public static double Calculate(
190      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
191      ISymbolicExpressionTree solution, double lowerEstimationLimit,
192      double upperEstimationLimit,
193      IRegressionProblemData problemData, IEnumerable<int> rows,
194      double penaltyMultiplier, IBoundsEstimator estimator,
195      bool useSoftConstraints, double maximumPenaltyFactor) {
196
197      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
198      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
199      var constraints = problemData.IntervalConstraints.EnabledConstraints;
200      var intervalCollection = problemData.VariableRanges;
201
202      var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
203      var nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues,
204        out var errorState);
205
206      if (errorState != OnlineCalculatorError.None) {
207        return 1.0;
208      }
209
210      var constraintResults = IntervalUtil.IntervalConstraintsViolation(constraints, estimator, intervalCollection, solution);
211
212      if (constraintResults.Any(x => double.IsNaN(x) || double.IsInfinity(x))) {
213        return 1.0;
214      }
215
216
217      if (useSoftConstraints) {
218        if (maximumPenaltyFactor < 0.0)
219          throw new ArgumentException("The parameter 'Maximum Penalty Factor' has to be greater or equal 0.0!");
220
221        var zip = constraints.Zip(constraintResults, (c, e) => new { Constraint = c, Error = e });
222        double sum = 0.0;
223
224        foreach (var x in zip) {
225          if (x.Constraint.Weight <= 0)
226            throw new ArgumentException("Constraint weights <= 0 are not allowed!");
227
228          double e = x.Error / x.Constraint.Weight;
229
230          e = double.IsNaN(e) ? 0.0 : e;
231          e = e > 1.0 ? 1.0 : e;
232
233          sum += Math.Sqrt(e) * maximumPenaltyFactor;
234        }
235
236        double avgError = sum / zip.Count();
237        nmse = nmse * avgError + nmse;
238        nmse = Math.Min(1.0, nmse);
239      } else if (constraintResults.Any(x => x != 0.0)) {
240        nmse = 1.0;
241      }
242
243      return nmse;
244    }
245
246    public override double Evaluate(
247      IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData,
248      IEnumerable<int> rows) {
249      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
250      EstimationLimitsParameter.ExecutionContext = context;
251      ApplyLinearScalingParameter.ExecutionContext = context;
252
253      var nmse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
254        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
255        problemData, rows, PenaltyMultiplier, BoundsEstimator, UseSoftConstraints, MaximumPenaltyFactor);
256
257      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
258      EstimationLimitsParameter.ExecutionContext = null;
259      ApplyLinearScalingParameter.ExecutionContext = null;
260
261      return nmse;
262    }
263  }
264}
Note: See TracBrowser for help on using the repository browser.