Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/Symbolic/InteractiveSymbolicRegressionSolutionSimplifierView.cs @ 4034

Last change on this file since 4034 was 4034, checked in by mkommend, 14 years ago

implemented first version of partially evaluation of samples (ticket #1082)

File size: 11.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Collections.Generic;
24using System.ComponentModel;
25using System.Data;
26using System.Drawing;
27using System.Linq;
28using System.Text;
29using System.Windows.Forms;
30using HeuristicLab.Common;
31using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
32using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
33using HeuristicLab.MainForm;
34using HeuristicLab.MainForm.WindowsForms;
35using HeuristicLab.Problems.DataAnalysis.Regression.Symbolic;
36using HeuristicLab.Problems.DataAnalysis.Symbolic;
37using HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols;
38using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
39
40namespace HeuristicLab.Problems.DataAnalysis.Views.Symbolic {
41  public partial class InteractiveSymbolicRegressionSolutionSimplifierView : AsynchronousContentView {
42    private SymbolicExpressionTree simplifiedExpressionTree;
43    private Dictionary<SymbolicExpressionTreeNode, ConstantTreeNode> replacementNodes;
44    private Dictionary<SymbolicExpressionTreeNode, double> nodeImpacts;
45
46    public InteractiveSymbolicRegressionSolutionSimplifierView() {
47      InitializeComponent();
48      this.replacementNodes = new Dictionary<SymbolicExpressionTreeNode, ConstantTreeNode>();
49      this.nodeImpacts = new Dictionary<SymbolicExpressionTreeNode, double>();
50      this.simplifiedExpressionTree = null;
51      this.Caption = "Interactive Solution Simplifier";
52    }
53
54    public new SymbolicRegressionSolution Content {
55      get { return (SymbolicRegressionSolution)base.Content; }
56      set { base.Content = value; }
57    }
58
59    protected override void RegisterContentEvents() {
60      base.RegisterContentEvents();
61      Content.ModelChanged += new EventHandler(Content_ModelChanged);
62      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
63    }
64    protected override void DeregisterContentEvents() {
65      base.DeregisterContentEvents();
66      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
67      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
68    }
69
70    private void Content_ModelChanged(object sender, EventArgs e) {
71      this.CalculateReplacementNodesAndNodeImpacts();
72    }
73    private void Content_ProblemDataChanged(object sender, EventArgs e) {
74      this.CalculateReplacementNodesAndNodeImpacts();
75    }
76
77    protected override void OnContentChanged() {
78      base.OnContentChanged();
79      this.CalculateReplacementNodesAndNodeImpacts();
80      this.viewHost.Content = this.Content;
81    }
82
83    private void CalculateReplacementNodesAndNodeImpacts() {
84      this.replacementNodes.Clear();
85      this.nodeImpacts.Clear();
86      if (Content != null && Content.Model != null && Content.ProblemData != null) {
87        SymbolicSimplifier simplifier = new SymbolicSimplifier();
88        simplifiedExpressionTree = simplifier.Simplify(Content.Model.SymbolicExpressionTree);
89        SymbolicExpressionTreeNode root = new ProgramRootSymbol().CreateTreeNode();
90        SymbolicExpressionTreeNode start = new StartSymbol().CreateTreeNode();
91        root.AddSubTree(start);
92        start.AddSubTree(simplifiedExpressionTree.Root);
93        int samplesStart = Content.ProblemData.TrainingSamplesStart.Value;
94        int samplesEnd = Content.ProblemData.TrainingSamplesEnd.Value;
95        double originalTrainingMeanSquaredError = SymbolicRegressionMeanSquaredErrorEvaluator.Calculate(
96            Content.Model.Interpreter, new SymbolicExpressionTree(root), Content.LowerEstimationLimit, Content.UpperEstimationLimit,
97            Content.ProblemData.Dataset, Content.ProblemData.TargetVariable.Value,
98            Enumerable.Range(samplesStart, samplesEnd - samplesStart));
99
100        this.CalculateReplacementNodes();
101
102        this.CalculateNodeImpacts(new SymbolicExpressionTree(root), start, originalTrainingMeanSquaredError);
103        this.treeChart.Tree = simplifiedExpressionTree;
104        this.PaintNodeImpacts();
105      }
106    }
107
108    private void CalculateReplacementNodes() {
109      ISymbolicExpressionTreeInterpreter interpreter = Content.Model.Interpreter;
110      IEnumerable<int> trainingSamples = Enumerable.Range(Content.ProblemData.TrainingSamplesStart.Value, Content.ProblemData.TrainingSamplesEnd.Value - Content.ProblemData.TrainingSamplesStart.Value);
111      SymbolicExpressionTreeNode root = new ProgramRootSymbol().CreateTreeNode();
112      SymbolicExpressionTreeNode start = new StartSymbol().CreateTreeNode();
113      root.AddSubTree(start);
114      SymbolicExpressionTree tree = new SymbolicExpressionTree(root);
115      foreach (SymbolicExpressionTreeNode node in this.simplifiedExpressionTree.IterateNodesPrefix()) {
116        while (start.SubTrees.Count > 0) start.RemoveSubTree(0);
117        start.AddSubTree(node);
118        double constantTreeNodeValue = interpreter.GetSymbolicExpressionTreeValues(tree, Content.ProblemData.Dataset, trainingSamples).Median();
119        ConstantTreeNode constantTreeNode = MakeConstantTreeNode(constantTreeNodeValue);
120        replacementNodes[node] = constantTreeNode;
121      }
122    }
123
124    private void CalculateNodeImpacts(SymbolicExpressionTree tree, SymbolicExpressionTreeNode currentTreeNode, double originalTrainingMeanSquaredError) {
125      foreach (SymbolicExpressionTreeNode childNode in currentTreeNode.SubTrees.ToList()) {
126        SwitchNode(currentTreeNode, childNode, replacementNodes[childNode]);
127        int samplesStart = Content.ProblemData.TrainingSamplesStart.Value;
128        int samplesEnd = Content.ProblemData.TrainingSamplesEnd.Value;
129        double newTrainingMeanSquaredError = SymbolicRegressionMeanSquaredErrorEvaluator.Calculate(
130          Content.Model.Interpreter, tree,
131          Content.LowerEstimationLimit, Content.UpperEstimationLimit,
132          Content.ProblemData.Dataset, Content.ProblemData.TargetVariable.Value,
133          Enumerable.Range(samplesStart, samplesEnd - samplesStart));
134        nodeImpacts[childNode] = newTrainingMeanSquaredError / originalTrainingMeanSquaredError;
135        SwitchNode(currentTreeNode, replacementNodes[childNode], childNode);
136        CalculateNodeImpacts(tree, childNode, originalTrainingMeanSquaredError);
137      }
138    }
139
140    private void SwitchNode(SymbolicExpressionTreeNode root, SymbolicExpressionTreeNode oldBranch, SymbolicExpressionTreeNode newBranch) {
141      for (int i = 0; i < root.SubTrees.Count; i++) {
142        if (root.SubTrees[i] == oldBranch) {
143          root.RemoveSubTree(i);
144          root.InsertSubTree(i, newBranch);
145          return;
146        }
147      }
148    }
149
150    private ConstantTreeNode MakeConstantTreeNode(double value) {
151      Constant constant = new Constant();
152      constant.MinValue = value - 1;
153      constant.MaxValue = value + 1;
154      ConstantTreeNode constantTreeNode = (ConstantTreeNode)constant.CreateTreeNode();
155      constantTreeNode.Value = value;
156      return constantTreeNode;
157    }
158
159    private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
160      VisualSymbolicExpressionTreeNode visualTreeNode = (VisualSymbolicExpressionTreeNode)sender;
161      foreach (SymbolicExpressionTreeNode treeNode in simplifiedExpressionTree.IterateNodesPostfix()) {
162        for (int i = 0; i < treeNode.SubTrees.Count; i++) {
163          SymbolicExpressionTreeNode subTree = treeNode.SubTrees[i];
164          if (subTree == visualTreeNode.SymbolicExpressionTreeNode) {
165            treeNode.RemoveSubTree(i);
166            if (replacementNodes.ContainsKey(subTree))
167              treeNode.InsertSubTree(i, replacementNodes[subTree]);
168            else if (subTree is ConstantTreeNode && replacementNodes.ContainsValue((ConstantTreeNode)subTree))
169              treeNode.InsertSubTree(i, replacementNodes.Where(v => v.Value == subTree).Single().Key);
170            else if (!(subTree is ConstantTreeNode))
171              throw new InvalidOperationException("Could not find replacement value.");
172          }
173        }
174      }
175      this.treeChart.Tree = simplifiedExpressionTree;
176
177      SymbolicExpressionTreeNode root = new ProgramRootSymbol().CreateTreeNode();
178      SymbolicExpressionTreeNode start = new StartSymbol().CreateTreeNode();
179      root.AddSubTree(start);
180      SymbolicExpressionTree tree = new SymbolicExpressionTree(root);
181      start.AddSubTree(simplifiedExpressionTree.Root);
182
183      this.Content.ModelChanged -= new EventHandler(Content_ModelChanged);
184      this.Content.Model = new SymbolicRegressionModel(Content.Model.Interpreter, tree);
185      this.Content.ModelChanged += new EventHandler(Content_ModelChanged);
186
187      this.PaintNodeImpacts();
188    }
189
190    private void PaintNodeImpacts() {
191      var impacts = nodeImpacts.Values;
192      double max = impacts.Max();
193      double min = impacts.Min();
194      foreach (SymbolicExpressionTreeNode treeNode in simplifiedExpressionTree.IterateNodesPostfix()) {
195        if (!(treeNode is ConstantTreeNode)) {
196          double impact = this.nodeImpacts[treeNode];
197          double replacementValue = this.replacementNodes[treeNode].Value;
198          VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
199
200          if (impact < 1.0) {
201            visualTree.FillColor = Color.FromArgb((int)((1.0 - impact) * 255), Color.Red);
202          } else {
203            visualTree.FillColor = Color.FromArgb((int)((impact - 1.0) / max * 255), Color.Green);
204          }
205          visualTree.ToolTip += Environment.NewLine + "Node impact: " + impact;
206          visualTree.ToolTip += Environment.NewLine + "Replacement value: " + replacementValue;
207        }
208      }
209      this.PaintCollapsedNodes();
210      this.treeChart.Repaint();
211    }
212
213    private void PaintCollapsedNodes() {
214      foreach (SymbolicExpressionTreeNode treeNode in simplifiedExpressionTree.IterateNodesPostfix()) {
215        if (treeNode is ConstantTreeNode && replacementNodes.ContainsValue((ConstantTreeNode)treeNode))
216          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DarkOrange;
217        else
218          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.Black;
219      }
220    }
221
222    private void btnSimplify_Click(object sender, EventArgs e) {
223      this.CalculateReplacementNodesAndNodeImpacts();
224    }
225  }
226}
Note: See TracBrowser for help on using the repository browser.