Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs @ 12509

Last change on this file since 12509 was 12461, checked in by bburlacu, 9 years ago

#2398: Skip root and start symbols when calculating impacts and replacement values in the pruning operators.

File size: 4.9 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2015 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.Collections.Generic;
25using System.Linq;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
32  [StorableClass]
33  [Item("SymbolicRegressionPruningOperator", "An operator which prunes symbolic regression trees.")]
34  public class SymbolicRegressionPruningOperator : SymbolicDataAnalysisExpressionPruningOperator {
35    protected SymbolicRegressionPruningOperator(SymbolicRegressionPruningOperator original, Cloner cloner)
36      : base(original, cloner) {
37    }
38    public override IDeepCloneable Clone(Cloner cloner) {
39      return new SymbolicRegressionPruningOperator(this, cloner);
40    }
41
42    [StorableConstructor]
43    protected SymbolicRegressionPruningOperator(bool deserializing) : base(deserializing) { }
44
45    public SymbolicRegressionPruningOperator(ISymbolicDataAnalysisSolutionImpactValuesCalculator impactValuesCalculator)
46      : base(impactValuesCalculator) {
47    }
48
49    protected override ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataAnalysisProblemData problemData, DoubleLimit estimationLimits) {
50      return new SymbolicRegressionModel(tree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
51    }
52
53    protected override double Evaluate(IDataAnalysisModel model) {
54      var regressionModel = (IRegressionModel)model;
55      var regressionProblemData = (IRegressionProblemData)ProblemDataParameter.ActualValue;
56      var rows = Enumerable.Range(FitnessCalculationPartitionParameter.ActualValue.Start, FitnessCalculationPartitionParameter.ActualValue.Size);
57      return Evaluate(regressionModel, regressionProblemData, rows);
58    }
59
60    private static double Evaluate(IRegressionModel model, IRegressionProblemData problemData,
61      IEnumerable<int> rows) {
62      var estimatedValues = model.GetEstimatedValues(problemData.Dataset, rows); // also bounds the values
63      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
64      OnlineCalculatorError errorState;
65      var quality = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, estimatedValues, out errorState);
66      if (errorState != OnlineCalculatorError.None) return double.NaN;
67      return quality;
68    }
69
70    public static ISymbolicExpressionTree Prune(ISymbolicExpressionTree tree, SymbolicRegressionSolutionImpactValuesCalculator impactValuesCalculator, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IRegressionProblemData problemData, DoubleLimit estimationLimits, IEnumerable<int> rows, double nodeImpactThreshold = 0.0, bool pruneOnlyZeroImpactNodes = false) {
71      var clonedTree = (ISymbolicExpressionTree)tree.Clone();
72      var model = new SymbolicRegressionModel(clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
73      var nodes = clonedTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList(); // skip the nodes corresponding to the ProgramRootSymbol and the StartSymbol
74      double quality = Evaluate(model, problemData, rows);
75
76      for (int i = 0; i < nodes.Count; ++i) {
77        var node = nodes[i];
78        if (node is ConstantTreeNode) continue;
79
80        double impactValue, replacementValue;
81        impactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, quality);
82
83        if (pruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0)) continue;
84        if (!pruneOnlyZeroImpactNodes && impactValue > nodeImpactThreshold) continue;
85
86        var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode();
87        constantNode.Value = replacementValue;
88
89        ReplaceWithConstant(node, constantNode);
90        i += node.GetLength() - 1; // skip subtrees under the node that was folded
91
92        quality -= impactValue;
93      }
94      return model.SymbolicExpressionTree;
95    }
96  }
97}
Note: See TracBrowser for help on using the repository browser.