Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicDataAnalysisRegressionSolutionPruningOptimizer.cs @ 10396

Last change on this file since 10396 was 10396, checked in by bburlacu, 10 years ago

#1837: Introduced the SlidingWindowBestSolutionsCollectionView which shows how well each individual sliding window solution performs on the other portions of the training data.

File size: 4.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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.Linq;
23using HeuristicLab.Core;
24using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
25using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
26
27namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
28  [Item("SymbolicDataAnalysisSolutionPruningOptimizer", "An operator which automatically removes nodes that have a negative impact from the tree model, optimizing the remaining constants.")]
29  [StorableClass]
30  public class SymbolicDataAnalysisRegressionSolutionPruningOptimizer : SymbolicDataAnalysisSolutionPruningOptimizer {
31    public override ISymbolicDataAnalysisSolution PruneAndOptimizeSolution(ISymbolicDataAnalysisSolution solution) {
32      var regressionSolution = (ISymbolicRegressionSolution)solution;
33      return PruneAndOptimizeRegressionSolution(regressionSolution);
34    }
35    /// <summary>
36    /// This method will walk all the levels of the symbolic regression solution model root starting from the deepest level and:
37    /// - it calculates the impact value of every originalNode on that level
38    /// - it prunes (replaces with a constant) the originalNode with the lowest negative impact value (0 or positive impacts are left unchanged)
39    /// - when no more nodes can be pruned, it moves on the upper level in the tree
40    /// - if the pruned and optimized solution is worse than the original solution (it can happen sometimes), then the original solution is returned
41    /// </summary>
42    /// <param name="solution"></param>
43    /// <returns></returns>
44    private ISymbolicRegressionSolution PruneAndOptimizeRegressionSolution(ISymbolicRegressionSolution solution) {
45      var calculator = new SymbolicRegressionSolutionImpactValuesCalculator();
46      var model = (ISymbolicRegressionModel)solution.Model;
47      var problemData = solution.ProblemData;
48      var rows = problemData.TrainingIndices.ToList();
49      // get tree levels and iterate each level from the bottom up
50      var root = model.SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0);
51      var levels = root.IterateNodesBreadth().GroupBy(root.GetBranchLevel).OrderByDescending(g => g.Key);
52
53      OptimizeConstants(solution);
54
55      foreach (var level in levels) {
56        var nodes = level.ToArray();
57        double minImpact;
58        do {
59          minImpact = 0.0;
60          int minImpactIndex = -1;
61          for (int i = 0; i < nodes.Length; ++i) {
62            // parent will be null if the node has already been replaced with a constant node in the tree (therefore it can be skipped)
63            if (nodes[i] is ConstantTreeNode || nodes[i].Parent == null) continue;
64            var impact = calculator.CalculateImpactValue(model, nodes[i], problemData, rows);
65            if (!(impact < minImpact)) continue;
66            minImpact = impact;
67            minImpactIndex = i;
68          }
69          if (minImpact >= 0) continue;
70          var node = nodes[minImpactIndex];
71          var replacementValue = calculator.CalculateReplacementValue(model, node, problemData, rows);
72          var constantNode = MakeConstantTreeNode(replacementValue);
73          ReplaceWithConstantNode(node, constantNode);
74          nodes[minImpactIndex] = constantNode;
75          OptimizeConstants(solution);
76        } while (minImpact < 0);
77      }
78
79      var newSolution = (ISymbolicRegressionSolution)model.CreateRegressionSolution(problemData);
80      return newSolution.TrainingRSquared > solution.TrainingRSquared ? newSolution : solution;
81    }
82
83    private static void OptimizeConstants(ISymbolicRegressionSolution solution) {
84      const int MAX_ITERATIONS = 50;
85      var model = solution.Model;
86      var interpreter = model.Interpreter;
87      var tree = model.SymbolicExpressionTree;
88      var problemData = solution.ProblemData;
89      var rows = problemData.TrainingIndices;
90
91      SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData, rows, true, MAX_ITERATIONS);
92    }
93  }
94}
Note: See TracBrowser for help on using the repository browser.