source: branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/LinearScaling.cs @ 18191

Last change on this file since 18191 was 18191, checked in by mkommend, 4 months ago

#3136: Extracted linear scaling functionality in a dedicated helper class.

File size: 3.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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;
23using System.Linq;
24using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
25
26namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
27  public static class LinearScaling {
28
29    public static ISymbolicExpressionTree AddLinearScalingTerms(ISymbolicExpressionTree tree, double offset = 0.0, double scale = 1.0) {
30      var startNode = tree.Root.Subtrees.First();
31      var template = startNode.Subtrees.First();
32
33      var addNode = new Addition().CreateTreeNode();
34      var mulNode = new Multiplication().CreateTreeNode();
35      var offsetNode = new NumberTreeNode(offset);
36      var scaleNode = new NumberTreeNode(scale);
37
38      addNode.AddSubtree(offsetNode);
39      addNode.AddSubtree(mulNode);
40      mulNode.AddSubtree(scaleNode);
41
42      startNode.RemoveSubtree(0);
43      startNode.AddSubtree(addNode);
44      mulNode.AddSubtree(template);
45      return tree;
46    }
47
48    public static void RemoveLinearScalingTerms(ISymbolicExpressionTree tree) {
49      var startNode = tree.Root.GetSubtree(0);
50      ExtractScalingTerms(tree, out NumberTreeNode offsetNode, out NumberTreeNode scaleNode);
51
52      var evaluationNode = scaleNode.Parent.GetSubtree(1); //move up to multiplication and take second child
53      startNode.RemoveSubtree(0);
54      startNode.AddSubtree(evaluationNode);
55    }
56
57    public static void ExtractScalingTerms(ISymbolicExpressionTree tree,
58      out NumberTreeNode offset, out NumberTreeNode scale) {
59      var startNode = tree.Root.Subtrees.First();
60
61      //check for scaling terms
62      var addNode = startNode.GetSubtree(0);
63      var offsetNode = addNode.GetSubtree(0);
64      var mulNode = addNode.GetSubtree(1);
65      var scaleNode = mulNode.GetSubtree(0);
66
67
68      var error = false;
69      if (addNode.Symbol is not Addition) error = true;
70      if (mulNode.Symbol is not Multiplication) error = true;
71      if (offsetNode is not NumberTreeNode) error = true;
72      if (scaleNode is not NumberTreeNode) error = true;
73      if (error) throw new ArgumentException("Scaling terms cannot be found.");
74
75      offset = (NumberTreeNode)offsetNode;
76      scale = (NumberTreeNode)scaleNode;
77    }
78
79    public static void AdjustLinearScalingParams(IRegressionProblemData problemData, ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter) {
80      ExtractScalingTerms(tree, out NumberTreeNode offsetNode, out NumberTreeNode scaleNode);
81
82      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, problemData.TrainingIndices);
83      var targetValues = problemData.TargetVariableTrainingValues;
84
85      OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out double a, out double b, out OnlineCalculatorError error);
86      if (error == OnlineCalculatorError.None) {
87        offsetNode.Value = a;
88        scaleNode.Value = b;
89      }
90    }
91  }
92}
Note: See TracBrowser for help on using the repository browser.