Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicDataAnalysisSolutionResponseFunctionView.cs @ 7028

Last change on this file since 7028 was 7028, checked in by gkronber, 12 years ago

#1621: fixed bugs in response function view and added scatter plot of original data as a reference.

File size: 10.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Drawing;
25using System.Linq;
26using System.Windows.Forms;
27using HeuristicLab.Common;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.MainForm;
30using HeuristicLab.MainForm.WindowsForms;
31
32namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views {
33  [View("Response Function View")]
34  [Content(typeof(ISymbolicRegressionSolution), false)]
35  public partial class SymbolicDataAnalysisSolutionResponseFunctionView : AsynchronousContentView {
36    private Dictionary<string, List<ISymbolicExpressionTreeNode>> variableNodes;
37    private ISymbolicExpressionTree clonedTree;
38    private Dictionary<string, double> medianValues;
39    public SymbolicDataAnalysisSolutionResponseFunctionView() {
40      InitializeComponent();
41      this.variableNodes = new Dictionary<string, List<ISymbolicExpressionTreeNode>>();
42      medianValues = new Dictionary<string, double>();
43      this.Caption = "Response Function View";
44    }
45
46    public new ISymbolicRegressionSolution Content {
47      get { return (ISymbolicRegressionSolution)base.Content; }
48      set { base.Content = value; }
49    }
50
51    protected override void RegisterContentEvents() {
52      base.RegisterContentEvents();
53      Content.ModelChanged += new EventHandler(Content_ModelChanged);
54      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
55    }
56    protected override void DeregisterContentEvents() {
57      base.DeregisterContentEvents();
58      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
59      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
60    }
61
62    private void Content_ModelChanged(object sender, EventArgs e) {
63      OnModelChanged();
64    }
65    private void Content_ProblemDataChanged(object sender, EventArgs e) {
66      OnProblemDataChanged();
67    }
68
69    protected virtual void OnModelChanged() {
70      this.UpdateView();
71    }
72
73    protected virtual void OnProblemDataChanged() {
74      this.UpdateView();
75    }
76
77    protected override void OnContentChanged() {
78      base.OnContentChanged();
79      this.UpdateView();
80    }
81
82    private void UpdateView() {
83      if (Content != null && Content.Model != null && Content.ProblemData != null) {
84        var referencedVariables =
85       (from varNode in Content.Model.SymbolicExpressionTree.IterateNodesPrefix().OfType<VariableTreeNode>()
86        select varNode.VariableName)
87         .Distinct()
88         .OrderBy(x => x)
89         .ToList();
90
91        medianValues.Clear();
92        foreach (var variableName in referencedVariables) {
93          medianValues.Add(variableName, Content.ProblemData.Dataset.GetDoubleValues(variableName).Median());
94        }
95
96        comboBox.Items.Clear();
97        comboBox.Items.AddRange(referencedVariables.ToArray());
98        comboBox.SelectedIndex = 0;
99      }
100    }
101
102    private void CreateSliders(IEnumerable<string> variableNames) {
103      flowLayoutPanel.Controls.Clear();
104
105      foreach (var variableName in variableNames) {
106        var variableTrackbar = new VariableTrackbar(variableName,
107                                                    Content.ProblemData.Dataset.GetDoubleValues(variableName));
108        variableTrackbar.Size = new Size(variableTrackbar.Size.Width, flowLayoutPanel.Size.Height - 23);
109        variableTrackbar.ValueChanged += TrackBarValueChanged;
110        flowLayoutPanel.Controls.Add(variableTrackbar);
111      }
112    }
113
114    private void TrackBarValueChanged(object sender, EventArgs e) {
115      var trackBar = (VariableTrackbar)sender;
116      string variableName = trackBar.VariableName;
117      ChangeVariableValue(variableName, trackBar.Value);
118    }
119
120    private void ChangeVariableValue(string variableName, double value) {
121      foreach (var constNode in variableNodes[variableName].Cast<ConstantTreeNode>())
122        constNode.Value = value;
123
124      UpdateResponseSeries();
125    }
126
127    private void UpdateScatterPlot() {
128      string freeVariable = (string)comboBox.SelectedItem;
129      IEnumerable<string> fixedVariables = comboBox.Items.OfType<string>()
130        .Except(new string[] { freeVariable });
131     
132      // scatter plots for subset of samples that have values near the median values for all variables
133      Func<int, bool> NearMedianValue = (r) => {
134        foreach (var fixedVar in fixedVariables) {
135          double med = medianValues[fixedVar];
136          if (!(Content.ProblemData.Dataset.GetDoubleValue(fixedVar, r) < med + 0.1 * Math.Abs(med) &&
137            Content.ProblemData.Dataset.GetDoubleValue(fixedVar, r) > med - 0.1 * Math.Abs(med)))
138            return false;
139        }
140        return true;
141      };
142
143      var mainTrainingIndizes = (from row in Content.ProblemData.TrainingIndizes
144                                 where NearMedianValue(row)
145                                 select row)
146        .ToArray();
147      var mainTestIndizes = (from row in Content.ProblemData.TestIndizes
148                             where NearMedianValue(row)
149                             select row)
150        .ToArray();
151
152      var freeVariableValues = Content.ProblemData.Dataset.GetDoubleValues(freeVariable, mainTrainingIndizes).ToArray();
153      var trainingValues = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable,
154                                                                     mainTrainingIndizes).ToArray();
155      Array.Sort(freeVariableValues, trainingValues);
156      responseChart.Series["Training Data"].Points.DataBindXY(freeVariableValues, trainingValues);
157
158      freeVariableValues = Content.ProblemData.Dataset.GetDoubleValues(freeVariable, mainTestIndizes).ToArray();
159      var testValues = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable,
160                                                                     mainTestIndizes).ToArray();
161      Array.Sort(freeVariableValues, testValues);
162      responseChart.Series["Test Data"].Points.DataBindXY(freeVariableValues, testValues);
163
164      // draw scatter plots of remaining values
165      freeVariableValues = Content.ProblemData.Dataset.GetDoubleValues(freeVariable, Content.ProblemData.TrainingIndizes).ToArray();
166      trainingValues = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable,
167                                                                     Content.ProblemData.TrainingIndizes).ToArray();
168      Array.Sort(freeVariableValues, trainingValues);
169      responseChart.Series["Training Data (edge)"].Points.DataBindXY(freeVariableValues, trainingValues);
170
171      freeVariableValues = Content.ProblemData.Dataset.GetDoubleValues(freeVariable, Content.ProblemData.TestIndizes).ToArray();
172      testValues = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable,
173                                                                     Content.ProblemData.TestIndizes).ToArray();
174      Array.Sort(freeVariableValues, testValues);
175      responseChart.Series["Test Data (edge)"].Points.DataBindXY(freeVariableValues, testValues);
176
177
178
179      responseChart.ChartAreas[0].AxisX.Maximum = Math.Ceiling(freeVariableValues.Max());
180      responseChart.ChartAreas[0].AxisX.Minimum = Math.Floor(freeVariableValues.Min());
181      responseChart.ChartAreas[0].AxisY.Maximum = Math.Ceiling(Math.Max(testValues.Max(), trainingValues.Max()));
182      responseChart.ChartAreas[0].AxisY.Minimum = Math.Floor(Math.Min(testValues.Min(), trainingValues.Min()));
183    }
184
185    private void UpdateResponseSeries() {
186      string freeVariable = (string)comboBox.SelectedItem;
187
188      var freeVariableValues = Content.ProblemData.Dataset.GetDoubleValues(freeVariable, Content.ProblemData.TrainingIndizes).ToArray();
189      var responseValues = Content.Model.Interpreter.GetSymbolicExpressionTreeValues(clonedTree,
190                                                                              Content.ProblemData.Dataset,
191                                                                              Content.ProblemData.TrainingIndizes)
192                                                                              .ToArray();
193      Array.Sort(freeVariableValues, responseValues);
194      responseChart.Series["Model Response"].Points.DataBindXY(freeVariableValues, responseValues);
195    }
196
197    private void ComboBoxSelectedIndexChanged(object sender, EventArgs e) {
198      string freeVariable = (string)comboBox.SelectedItem;
199      IEnumerable<string> fixedVariables = comboBox.Items.OfType<string>()
200        .Except(new string[] { freeVariable });
201
202      variableNodes.Clear();
203      clonedTree = (ISymbolicExpressionTree)Content.Model.SymbolicExpressionTree.Clone();
204
205      foreach (var varNode in clonedTree.IterateNodesPrefix().OfType<VariableTreeNode>()) {
206        if (fixedVariables.Contains(varNode.VariableName)) {
207          if (!variableNodes.ContainsKey(varNode.VariableName))
208            variableNodes.Add(varNode.VariableName, new List<ISymbolicExpressionTreeNode>());
209
210          int childIndex = varNode.Parent.IndexOfSubtree(varNode);
211          var replacementNode = MakeConstantTreeNode(medianValues[varNode.VariableName]);
212          var parent = varNode.Parent;
213          parent.RemoveSubtree(childIndex);
214          parent.InsertSubtree(childIndex, MakeProduct(replacementNode, varNode.Weight));
215          variableNodes[varNode.VariableName].Add(replacementNode);
216        }
217      }
218
219      CreateSliders(fixedVariables);
220      UpdateScatterPlot();
221      UpdateResponseSeries();
222    }
223
224    private ISymbolicExpressionTreeNode MakeProduct(ConstantTreeNode c, double weight) {
225      var mul = new Multiplication();
226      var prod = mul.CreateTreeNode();
227      prod.AddSubtree(MakeConstantTreeNode(weight));
228      prod.AddSubtree(c);
229      return prod;
230    }
231
232    private ConstantTreeNode MakeConstantTreeNode(double value) {
233      Constant constant = new Constant();
234      constant.MinValue = value - 1;
235      constant.MaxValue = value + 1;
236      ConstantTreeNode constantTreeNode = (ConstantTreeNode)constant.CreateTreeNode();
237      constantTreeNode.Value = value;
238      return constantTreeNode;
239    }
240  }
241}
Note: See TracBrowser for help on using the repository browser.