source: branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicExpressionTreeBacktransformator.cs @ 10980

Last change on this file since 10980 was 10980, checked in by pfleck, 8 years ago
  • Inverse iterate when backtransforming model
  • Insert CopyColumnTransformation in front of Transformations-List
File size: 4.3 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.Collections.Generic;
23using System.Linq;
24using HeuristicLab.Common;
25using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
26using HeuristicLab.Problems.DataAnalysis.Transformations;
27
28namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
29  public class SymbolicExpressionTreeBacktransformator : IModelBacktransformator {
30    private readonly ITransformationMapper<ISymbolicExpressionTreeNode> transformationMapper;
31
32    public SymbolicExpressionTreeBacktransformator(ITransformationMapper<ISymbolicExpressionTreeNode> transformationMapper) {
33      this.transformationMapper = transformationMapper;
34    }
35
36    public void Backtransform(IDataAnalysisModel model, IEnumerable<ITransformation> transformations, string targetVariable) {
37      var symbolicModel = (ISymbolicDataAnalysisModel)model;
38
39      foreach (var transformation in transformations.Reverse()) {
40        ApplyBacktransformation(transformation, symbolicModel.SymbolicExpressionTree, targetVariable);
41      }
42    }
43
44    private void ApplyBacktransformation(ITransformation transformation, ISymbolicExpressionTree symbolicExpressionTree, string targetVariable) {
45      if (transformation.Column != targetVariable) {
46        var variableNodes = symbolicExpressionTree.IterateNodesBreadth()
47          .OfType<VariableTreeNode>()
48          .Where(n => n.VariableName == transformation.Column);
49        ApplyRegularBacktransformation(transformation, variableNodes);
50      } else if (!(transformation is CopyColumnTransformation)) {
51        ApplyInverseBacktransformation(transformation, symbolicExpressionTree);
52      }
53    }
54
55    private void ApplyRegularBacktransformation(ITransformation transformation, IEnumerable<VariableTreeNode> variableNodes) {
56      foreach (var variableNode in variableNodes) {
57        // generate new subtrees because same subtree cannot be added more than once
58        var transformationTree = transformationMapper.GenerateModel(transformation);
59        SwapVariableWithTree(variableNode, transformationTree);
60      }
61    }
62
63    private void ApplyInverseBacktransformation(ITransformation transformation, ISymbolicExpressionTree symbolicExpressionTree) {
64      var startSymbol = symbolicExpressionTree.Root.GetSubtree(0);
65      var modelTree = startSymbol.GetSubtree(0);
66      startSymbol.RemoveSubtree(0);
67
68      var transformationTree = transformationMapper.GenerateInverseModel(transformation);
69      var variableNode = transformationTree.IterateNodesBreadth()
70        .OfType<VariableTreeNode>()
71        .Single(n => n.VariableName == transformation.Column);
72
73      SwapVariableWithTree(variableNode, modelTree);
74
75      startSymbol.AddSubtree(transformationTree);
76    }
77
78    private void SwapVariableWithTree(VariableTreeNode variableNode, ISymbolicExpressionTreeNode treeNode) {
79      var parent = variableNode.Parent;
80      int index = parent.IndexOfSubtree(variableNode);
81      parent.RemoveSubtree(index);
82
83      if (!variableNode.Weight.IsAlmost(1.0))
84        treeNode = CreateNodeFromWeight(treeNode, variableNode);
85
86      parent.InsertSubtree(index, treeNode);
87    }
88
89    private ISymbolicExpressionTreeNode CreateNodeFromWeight(ISymbolicExpressionTreeNode transformationTree, VariableTreeNode variableNode) {
90      var multiplicationNode = new SymbolicExpressionTreeNode(new Multiplication());
91      multiplicationNode.AddSubtree(new ConstantTreeNode(new Constant()) { Value = variableNode.Weight });
92      multiplicationNode.AddSubtree(transformationTree);
93      return multiplicationNode;
94    }
95  }
96}
Note: See TracBrowser for help on using the repository browser.