Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2870_AutoDiff-nuget/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs @ 16123

Last change on this file since 16123 was 15637, checked in by fholzing, 7 years ago

#2871: Included the points from the review (added third sorting-possibility, renamed the existing ones, added default-behavior)

File size: 8.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 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
21using System;
22using System.Collections.Generic;
23using System.Linq;
24using System.Threading.Tasks;
25using HeuristicLab.Common;
26using HeuristicLab.Data;
27using HeuristicLab.MainForm;
28using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
29
30namespace HeuristicLab.Problems.DataAnalysis.Views {
31  [View("Variable Impacts")]
32  [Content(typeof(IRegressionSolution))]
33  public partial class RegressionSolutionVariableImpactsView : DataAnalysisSolutionEvaluationView {
34
35    private const int ORDER_BY_IMPACT = 0;
36    private const int ORDER_BY_OCCURRENCE = 1;
37    private const int ORDER_BY_NAME = 2;
38
39    private Dictionary<string, double> rawVariableImpacts = new Dictionary<string, double>();
40
41    public new IRegressionSolution Content {
42      get { return (IRegressionSolution)base.Content; }
43      set {
44        base.Content = value;
45      }
46    }
47
48    public RegressionSolutionVariableImpactsView()
49      : base() {
50      InitializeComponent();
51      this.dataPartitionComboBox.SelectedIndex = 0;
52      this.replacementComboBox.SelectedIndex = 0;
53      this.factorVarReplComboBox.SelectedIndex = 0;
54    }
55
56    #region events
57    protected override void RegisterContentEvents() {
58      base.RegisterContentEvents();
59      Content.ModelChanged += new EventHandler(Content_ModelChanged);
60      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
61    }
62
63    protected override void DeregisterContentEvents() {
64      base.DeregisterContentEvents();
65      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
66      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
67    }
68
69    protected virtual void Content_ProblemDataChanged(object sender, EventArgs e) {
70      OnContentChanged();
71    }
72
73    protected virtual void Content_ModelChanged(object sender, EventArgs e) {
74      OnContentChanged();
75    }
76
77    protected override void OnContentChanged() {
78      base.OnContentChanged();
79      if (Content == null) {
80        variableImactsArrayView.Content = null;
81      } else {
82        UpdateVariableImpacts();
83      }
84    }
85
86    private void UpdateVariableImpacts() {
87      if (Content == null || replacementComboBox.SelectedIndex < 0
88        || factorVarReplComboBox.SelectedIndex < 0
89        || dataPartitionComboBox.SelectedIndex < 0) return;
90      var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
91      variableImactsArrayView.Caption = Content.Name + " Variable Impacts";
92      var replMethod =
93         (RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum)
94           replacementComboBox.Items[replacementComboBox.SelectedIndex];
95      var factorReplMethod =
96        (RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum)
97          factorVarReplComboBox.Items[factorVarReplComboBox.SelectedIndex];
98      var dataPartition =
99        (RegressionSolutionVariableImpactsCalculator.DataPartitionEnum)dataPartitionComboBox.SelectedItem;
100
101      Task.Factory.StartNew(() => {
102        try {
103          mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name);
104
105          var impacts = RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content, dataPartition, replMethod, factorReplMethod);
106          var impactArray = new DoubleArray(impacts.Select(i => i.Item2).ToArray());
107          impactArray.ElementNames = impacts.Select(i => i.Item1);
108          variableImactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly();
109
110          //Remember the original ordering of the variables
111          var problemData = Content.ProblemData;
112          var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(Content.Model.VariablesUsedForPrediction));
113          var originalVariableOrdering = problemData.Dataset.VariableNames.Where(v => inputvariables.Contains(v)).Where(problemData.Dataset.VariableHasType<double>).ToList();
114          rawVariableImpacts.Clear();
115          originalVariableOrdering.ForEach(v => rawVariableImpacts.Add(v, impacts.First(vv => vv.Item1 == v).Item2));
116
117        } finally {
118          mainForm.RemoveOperationProgressFromView(this);
119        }
120      });
121    }
122
123    private void dataPartitionComboBox_SelectedIndexChanged(object sender, EventArgs e) {
124      ResetOrdering();
125      UpdateVariableImpacts();
126    }
127
128    private void replacementComboBox_SelectedIndexChanged(object sender, EventArgs e) {
129      ResetOrdering();
130      UpdateVariableImpacts();
131    }
132
133    private void sortByComboBox_SelectedIndexChanged(object sender, EventArgs e) {
134      //Update the default ordering (asc,desc), but remove the eventHandler beforehand (otherwise the data would be ordered twice)
135      ascendingCheckBox.CheckedChanged -= ascendingCheckBox_CheckedChanged;
136      switch (sortByComboBox.SelectedIndex) {
137        case ORDER_BY_IMPACT: {
138            ascendingCheckBox.Checked = false;
139            break;
140          }
141        case ORDER_BY_OCCURRENCE: {
142            ascendingCheckBox.Checked = true;
143            break;
144          }
145        case ORDER_BY_NAME: {
146            ascendingCheckBox.Checked = true;
147            break;
148          }
149      }
150      ascendingCheckBox.CheckedChanged += ascendingCheckBox_CheckedChanged;
151
152      UpdateDataOrdering();
153    }
154
155    private void ascendingCheckBox_CheckedChanged(object sender, EventArgs e) {
156      UpdateDataOrdering();
157    }
158    #endregion
159
160    #region Helper Methods
161    /// <summary>
162    /// Updates the <see cref="variableImactsArrayView"/> according to the selected ordering <see cref="ascendingCheckBox"/> of the selected Column <see cref="sortByComboBox"/>
163    /// The default is "Descending" by "VariableImpact" (as in previous versions)
164    /// </summary>
165    private void UpdateDataOrdering() {
166      int orderIdx = sortByComboBox.SelectedIndex;
167      bool ascending = ascendingCheckBox.Checked;
168
169      //Check if valid ordering is selected AND at if any VariableImpact exists
170      if (orderIdx > -1 && rawVariableImpacts != null && rawVariableImpacts.Any()) {
171        IEnumerable<KeyValuePair<string, double>> orderedEntries = null;
172
173        //Sort accordingly
174        switch (orderIdx) {
175          case ORDER_BY_IMPACT: {
176              orderedEntries = ascending ? rawVariableImpacts.OrderBy(v => v.Value) : rawVariableImpacts.OrderByDescending(v => v.Value);
177              break;
178            }
179          case ORDER_BY_OCCURRENCE: {
180              orderedEntries = ascending ? rawVariableImpacts : rawVariableImpacts.Reverse();
181              break;
182            }
183          case ORDER_BY_NAME: {
184              orderedEntries = ascending ? rawVariableImpacts.OrderBy(v => v.Key, new NaturalStringComparer()) : rawVariableImpacts.OrderByDescending(v => v.Key, new NaturalStringComparer());
185              break;
186            }
187        }
188
189        //Write the data back
190        var impactArray = new DoubleArray(orderedEntries.Select(i => i.Value).ToArray()) {
191          ElementNames = orderedEntries.Select(i => i.Key)
192        };
193        variableImactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly();
194      }
195    }
196
197    /// <summary>
198    /// Resets the ordering to the default behaviour (descending by variableImpact), meaning <see cref="ascendingCheckBox"/> and <see cref="sortByComboBox"/> will be updated
199    /// Note: this will NOT update the UI
200    /// </summary>
201    private void ResetOrdering() {
202      //The events shouldn't fire everytime we reset the data
203      ascendingCheckBox.CheckedChanged -= ascendingCheckBox_CheckedChanged;
204      sortByComboBox.SelectedIndexChanged -= sortByComboBox_SelectedIndexChanged;
205
206      ascendingCheckBox.Checked = false;
207      sortByComboBox.SelectedIndex = ORDER_BY_IMPACT;
208
209      ascendingCheckBox.CheckedChanged += ascendingCheckBox_CheckedChanged;
210      sortByComboBox.SelectedIndexChanged += sortByComboBox_SelectedIndexChanged;
211    }
212    #endregion
213  }
214}
Note: See TracBrowser for help on using the repository browser.