Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs

Last change on this file was 18180, checked in by dpiringe, 3 years ago

#3138

  • merged trunk into branch
File size: 5.7 KB
RevLine 
[11025]1#region License Information
2
3/* HeuristicLab
[17180]4 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[11025]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
[12189]24using System.Collections.Generic;
[11025]25using System.Linq;
[10469]26using HeuristicLab.Common;
27using HeuristicLab.Core;
[12189]28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
[12720]29using HeuristicLab.Parameters;
[16565]30using HEAL.Attic;
[10469]31
32namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
[16565]33  [StorableType("75843B4E-C69C-423A-87BD-A64619D380BB")]
[10469]34  [Item("SymbolicRegressionPruningOperator", "An operator which prunes symbolic regression trees.")]
35  public class SymbolicRegressionPruningOperator : SymbolicDataAnalysisExpressionPruningOperator {
[12720]36    private const string EvaluatorParameterName = "Evaluator";
37
38    #region parameter properties
39    public ILookupParameter<ISymbolicRegressionSingleObjectiveEvaluator> EvaluatorParameter {
40      get { return (ILookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>)Parameters[EvaluatorParameterName]; }
41    }
42    #endregion
43
[10469]44    protected SymbolicRegressionPruningOperator(SymbolicRegressionPruningOperator original, Cloner cloner)
45      : base(original, cloner) {
46    }
47    public override IDeepCloneable Clone(Cloner cloner) {
48      return new SymbolicRegressionPruningOperator(this, cloner);
49    }
50
51    [StorableConstructor]
[16565]52    protected SymbolicRegressionPruningOperator(StorableConstructorFlag _) : base(_) { }
[10469]53
[12189]54    public SymbolicRegressionPruningOperator(ISymbolicDataAnalysisSolutionImpactValuesCalculator impactValuesCalculator)
55      : base(impactValuesCalculator) {
[12720]56      Parameters.Add(new LookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>(EvaluatorParameterName));
[10469]57    }
58
[12744]59    [StorableHook(HookType.AfterDeserialization)]
60    private void AfterDeserialization() {
61      // BackwardsCompatibility3.3
62      #region Backwards compatible code, remove with 3.4
63      base.ImpactValuesCalculator = new SymbolicRegressionSolutionImpactValuesCalculator();
64      if (!Parameters.ContainsKey(EvaluatorParameterName)) {
65        Parameters.Add(new LookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>(EvaluatorParameterName));
66      }
67      #endregion
68    }
69
[12189]70    protected override ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataAnalysisProblemData problemData, DoubleLimit estimationLimits) {
[13941]71      var regressionProblemData = (IRegressionProblemData)problemData;
72      return new SymbolicRegressionModel(regressionProblemData.TargetVariable, tree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
[10469]73    }
74
75    protected override double Evaluate(IDataAnalysisModel model) {
[12720]76      var regressionModel = (ISymbolicRegressionModel)model;
[12358]77      var regressionProblemData = (IRegressionProblemData)ProblemDataParameter.ActualValue;
[12720]78      var evaluator = EvaluatorParameter.ActualValue;
79      var fitnessEvaluationPartition = FitnessCalculationPartitionParameter.ActualValue;
80      var rows = Enumerable.Range(fitnessEvaluationPartition.Start, fitnessEvaluationPartition.Size);
81      return evaluator.Evaluate(this.ExecutionContext, regressionModel.SymbolicExpressionTree, regressionProblemData, rows);
[12189]82    }
83
84    public static ISymbolicExpressionTree Prune(ISymbolicExpressionTree tree, SymbolicRegressionSolutionImpactValuesCalculator impactValuesCalculator, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IRegressionProblemData problemData, DoubleLimit estimationLimits, IEnumerable<int> rows, double nodeImpactThreshold = 0.0, bool pruneOnlyZeroImpactNodes = false) {
85      var clonedTree = (ISymbolicExpressionTree)tree.Clone();
[13941]86      var model = new SymbolicRegressionModel(problemData.TargetVariable, clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
[12461]87      var nodes = clonedTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList(); // skip the nodes corresponding to the ProgramRootSymbol and the StartSymbol
[12189]88
[12720]89      double qualityForImpactsCalculation = double.NaN; // pass a NaN value initially so the impact calculator will calculate the quality
90
[12189]91      for (int i = 0; i < nodes.Count; ++i) {
92        var node = nodes[i];
[18180]93        if (node is INumericTreeNode) continue; // skip constants and numbers
[12189]94
[18180]95        impactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows,
96          out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation, qualityForImpactsCalculation);
[12189]97
[12358]98        if (pruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0)) continue;
99        if (!pruneOnlyZeroImpactNodes && impactValue > nodeImpactThreshold) continue;
[12189]100
[18180]101        var numNode = (NumberTreeNode)node.Grammar.GetSymbol("Number").CreateTreeNode();
102        numNode.Value = replacementValue;
[12189]103
[18180]104        ReplaceWithNumber(node, numNode);
[12189]105        i += node.GetLength() - 1; // skip subtrees under the node that was folded
106
[12720]107        qualityForImpactsCalculation = newQualityForImpactsCalculation;
[12189]108      }
109      return model.SymbolicExpressionTree;
110    }
[10469]111  }
112}
Note: See TracBrowser for help on using the repository browser.