source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs @ 15665

Last change on this file since 15665 was 15665, checked in by fholzing, 4 years ago

#2871: Implemented review-issues

File size: 8.3 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
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Threading.Tasks;
26using HeuristicLab.Common;
27using HeuristicLab.Data;
28using HeuristicLab.MainForm;
29
30namespace HeuristicLab.Problems.DataAnalysis.Views {
31  [View("Variable Impacts")]
32  [Content(typeof(IRegressionSolution))]
33  public partial class RegressionSolutionVariableImpactsView : DataAnalysisSolutionEvaluationView {
34    private Dictionary<string, double> rawVariableImpacts = new Dictionary<string, double>();
35
36    public new IRegressionSolution Content {
37      get { return (IRegressionSolution)base.Content; }
38      set {
39        base.Content = value;
40      }
41    }
42
43    public RegressionSolutionVariableImpactsView()
44      : base() {
45      InitializeComponent();
46
47      //Little workaround. If you fill the ComboBox-Items in the other partial class, the UI-Designer will moan.
48      this.sortByComboBox.Items.AddRange(Enum.GetValues(typeof(RegressionSolutionVariableImpactsCalculator.SortingCriteria)).Cast<object>().ToArray());
49      this.sortByComboBox.SelectedItem = RegressionSolutionVariableImpactsCalculator.SortingCriteria.ImpactValue;
50
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
87    private void dataPartitionComboBox_SelectedIndexChanged(object sender, EventArgs e) {
88      UpdateVariableImpacts();
89    }
90
91    private void replacementComboBox_SelectedIndexChanged(object sender, EventArgs e) {
92      UpdateVariableImpacts();
93    }
94
95    private void sortByComboBox_SelectedIndexChanged(object sender, EventArgs e) {
96      //Update the default ordering (asc,desc), but remove the eventHandler beforehand (otherwise the data would be ordered twice)
97      ascendingCheckBox.CheckedChanged -= ascendingCheckBox_CheckedChanged;
98      switch ((RegressionSolutionVariableImpactsCalculator.SortingCriteria)sortByComboBox.SelectedItem) {
99        case RegressionSolutionVariableImpactsCalculator.SortingCriteria.ImpactValue:
100          ascendingCheckBox.Checked = false;
101          break;
102        case RegressionSolutionVariableImpactsCalculator.SortingCriteria.Occurrence:
103          ascendingCheckBox.Checked = true;
104          break;
105        case RegressionSolutionVariableImpactsCalculator.SortingCriteria.VariableName:
106          ascendingCheckBox.Checked = true;
107          break;
108        default:
109          throw new Exception("Cannot interpret SortingCriteria");
110      }
111      ascendingCheckBox.CheckedChanged += ascendingCheckBox_CheckedChanged;
112
113      UpdateDataOrdering();
114    }
115
116    private void ascendingCheckBox_CheckedChanged(object sender, EventArgs e) {
117      UpdateDataOrdering();
118    }
119    #endregion
120
121    #region Helper Methods         
122    private void UpdateVariableImpacts() {
123      if (Content == null || replacementComboBox.SelectedIndex < 0
124        || factorVarReplComboBox.SelectedIndex < 0
125        || dataPartitionComboBox.SelectedIndex < 0) return;
126      var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
127      variableImactsArrayView.Caption = Content.Name + " Variable Impacts";
128      var replMethod =
129         (RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum)
130           replacementComboBox.Items[replacementComboBox.SelectedIndex];
131      var factorReplMethod =
132        (RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum)
133          factorVarReplComboBox.Items[factorVarReplComboBox.SelectedIndex];
134      var dataPartition =
135        (RegressionSolutionVariableImpactsCalculator.DataPartitionEnum)dataPartitionComboBox.SelectedItem;
136
137      Task.Factory.StartNew(() => {
138        try {
139          mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name);
140
141          //Remember the original ordering of the variables
142          var impacts = RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content, dataPartition, replMethod, factorReplMethod);
143          var problemData = Content.ProblemData;
144          var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(Content.Model.VariablesUsedForPrediction));
145          var originalVariableOrdering = problemData.Dataset.VariableNames.Where(v => inputvariables.Contains(v)).Where(problemData.Dataset.VariableHasType<double>).ToList();
146          rawVariableImpacts.Clear();
147          originalVariableOrdering.ForEach(v => rawVariableImpacts.Add(v, impacts.First(vv => vv.Item1 == v).Item2));
148        } finally {
149          mainForm.RemoveOperationProgressFromView(this);
150          UpdateDataOrdering();
151        }
152      });
153    }
154
155    /// <summary>
156    /// Updates the <see cref="variableImactsArrayView"/> according to the selected ordering <see cref="ascendingCheckBox"/> of the selected Column <see cref="sortByComboBox"/>
157    /// The default is "Descending" by "VariableImpact" (as in previous versions)
158    /// </summary>
159    private void UpdateDataOrdering() {
160      //Check if valid sortingCriteria is selected and data exists
161      if (sortByComboBox.SelectedIndex == -1 || rawVariableImpacts == null || !rawVariableImpacts.Any()) { return; }
162
163      var selectedItem = (RegressionSolutionVariableImpactsCalculator.SortingCriteria)sortByComboBox.SelectedItem;
164      bool ascending = ascendingCheckBox.Checked;
165
166      IEnumerable<KeyValuePair<string, double>> orderedEntries = null;
167
168      //Sort accordingly
169      switch (selectedItem) {
170        case RegressionSolutionVariableImpactsCalculator.SortingCriteria.ImpactValue:
171          orderedEntries = ascending ? rawVariableImpacts.OrderBy(v => v.Value) : rawVariableImpacts.OrderByDescending(v => v.Value);
172          break;
173        case RegressionSolutionVariableImpactsCalculator.SortingCriteria.Occurrence:
174          orderedEntries = ascending ? rawVariableImpacts : rawVariableImpacts.Reverse();
175          break;
176        case RegressionSolutionVariableImpactsCalculator.SortingCriteria.VariableName:
177          orderedEntries = ascending ? rawVariableImpacts.OrderBy(v => v.Key, new NaturalStringComparer()) : rawVariableImpacts.OrderByDescending(v => v.Key, new NaturalStringComparer());
178          break;
179        default:
180          throw new Exception("Cannot interpret SortingCriteria");
181      }
182
183      //Write the data back
184      var impactArray = new DoubleArray(orderedEntries.Select(i => i.Value).ToArray()) {
185        ElementNames = orderedEntries.Select(i => i.Key)
186      };
187      variableImactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly();
188    }
189    #endregion
190  }
191}
Note: See TracBrowser for help on using the repository browser.