Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs

Last change on this file was 15973, checked in by gkronber, 6 years ago

#2522: merged trunk changes from r13402:15972 to branch resolving conflicts where necessary

File size: 8.8 KB
RevLine 
[14348]1#region License Information
2/* HeuristicLab
[15583]3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[14348]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
[15665]21
[14348]22using System;
[15626]23using System.Collections.Generic;
[14348]24using System.Linq;
[15973]25using System.Threading;
[14348]26using System.Threading.Tasks;
[15637]27using HeuristicLab.Common;
[14348]28using HeuristicLab.Data;
29using HeuristicLab.MainForm;
30
31namespace HeuristicLab.Problems.DataAnalysis.Views {
32  [View("Variable Impacts")]
33  [Content(typeof(IRegressionSolution))]
34  public partial class RegressionSolutionVariableImpactsView : DataAnalysisSolutionEvaluationView {
[15973]35    private CancellationTokenSource cancellationToken = new CancellationTokenSource();
[15673]36    private enum SortingCriteria {
37      ImpactValue,
38      Occurrence,
39      VariableName
40    }
[15973]41    private IProgress progress;
[15626]42    private Dictionary<string, double> rawVariableImpacts = new Dictionary<string, double>();
43
[14348]44    public new IRegressionSolution Content {
45      get { return (IRegressionSolution)base.Content; }
46      set {
47        base.Content = value;
48      }
49    }
50
51    public RegressionSolutionVariableImpactsView()
52      : base() {
53      InitializeComponent();
[15665]54
55      //Little workaround. If you fill the ComboBox-Items in the other partial class, the UI-Designer will moan.
[15673]56      this.sortByComboBox.Items.AddRange(Enum.GetValues(typeof(SortingCriteria)).Cast<object>().ToArray());
57      this.sortByComboBox.SelectedItem = SortingCriteria.ImpactValue;
[15665]58
[15973]59      //Set the default values
[14348]60      this.dataPartitionComboBox.SelectedIndex = 0;
61      this.replacementComboBox.SelectedIndex = 0;
[14826]62      this.factorVarReplComboBox.SelectedIndex = 0;
[14348]63    }
64
65    protected override void RegisterContentEvents() {
66      base.RegisterContentEvents();
67      Content.ModelChanged += new EventHandler(Content_ModelChanged);
68      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
69    }
70
71    protected override void DeregisterContentEvents() {
72      base.DeregisterContentEvents();
73      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
74      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
75    }
76
77    protected virtual void Content_ProblemDataChanged(object sender, EventArgs e) {
78      OnContentChanged();
79    }
80
81    protected virtual void Content_ModelChanged(object sender, EventArgs e) {
82      OnContentChanged();
83    }
84
85    protected override void OnContentChanged() {
86      base.OnContentChanged();
87      if (Content == null) {
88        variableImactsArrayView.Content = null;
89      } else {
[15973]90        UpdateVariableImpact();
[14348]91      }
92    }
93
[15973]94    private void RegressionSolutionVariableImpactsView_VisibleChanged(object sender, EventArgs e) {
95      if (!cancellationToken.IsCancellationRequested) {
96        cancellationToken.Cancel();
97      }
98    }
[15665]99
[15973]100
[15665]101    private void dataPartitionComboBox_SelectedIndexChanged(object sender, EventArgs e) {
[15973]102      UpdateVariableImpact();
[15665]103    }
104
105    private void replacementComboBox_SelectedIndexChanged(object sender, EventArgs e) {
[15973]106      UpdateVariableImpact();
[15665]107    }
108
109    private void sortByComboBox_SelectedIndexChanged(object sender, EventArgs e) {
110      //Update the default ordering (asc,desc), but remove the eventHandler beforehand (otherwise the data would be ordered twice)
111      ascendingCheckBox.CheckedChanged -= ascendingCheckBox_CheckedChanged;
[15673]112      switch ((SortingCriteria)sortByComboBox.SelectedItem) {
113        case SortingCriteria.ImpactValue:
[15665]114          ascendingCheckBox.Checked = false;
115          break;
[15673]116        case SortingCriteria.Occurrence:
[15665]117          ascendingCheckBox.Checked = true;
118          break;
[15673]119        case SortingCriteria.VariableName:
[15665]120          ascendingCheckBox.Checked = true;
121          break;
122        default:
[15673]123          throw new NotImplementedException("Ordering for selected SortingCriteria not implemented");
[15665]124      }
125      ascendingCheckBox.CheckedChanged += ascendingCheckBox_CheckedChanged;
126
127      UpdateDataOrdering();
128    }
129
130    private void ascendingCheckBox_CheckedChanged(object sender, EventArgs e) {
131      UpdateDataOrdering();
132    }
133
[15973]134
135    private async void UpdateVariableImpact() {
136      //Check if the selection is valid
[15673]137      if (Content == null) { return; }
138      if (replacementComboBox.SelectedIndex < 0) { return; }
139      if (dataPartitionComboBox.SelectedIndex < 0) { return; }
140      if (factorVarReplComboBox.SelectedIndex < 0) { return; }
141
[15973]142      //Prepare arguments
[15673]143      var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
144      var replMethod = (RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum)replacementComboBox.Items[replacementComboBox.SelectedIndex];
145      var factorReplMethod = (RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum)factorVarReplComboBox.Items[factorVarReplComboBox.SelectedIndex];
146      var dataPartition = (RegressionSolutionVariableImpactsCalculator.DataPartitionEnum)dataPartitionComboBox.SelectedItem;
147
[15973]148      variableImactsArrayView.Caption = Content.Name + " Variable Impacts";
149      progress = mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name);
150      progress.ProgressValue = 0;
[14348]151
[15973]152      cancellationToken = new CancellationTokenSource();
153      //Remember the original ordering of the variables
154      try {
155        var impacts = await Task.Run(() => RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content, dataPartition, replMethod, factorReplMethod,
156          (i, s) => {
157            progress.ProgressValue = i;
158            progress.Status = s;
159            return cancellationToken.Token.IsCancellationRequested;
160          }), cancellationToken.Token);
161
162        if (cancellationToken.Token.IsCancellationRequested) { return; }
163        var problemData = Content.ProblemData;
164        var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(Content.Model.VariablesUsedForPrediction));
165        var originalVariableOrdering = problemData.Dataset.VariableNames.Where(v => inputvariables.Contains(v)).Where(problemData.Dataset.VariableHasType<double>).ToList();
166
167        rawVariableImpacts.Clear();
168        originalVariableOrdering.ForEach(v => rawVariableImpacts.Add(v, impacts.First(vv => vv.Item1 == v).Item2));
169        UpdateDataOrdering();
170      } finally {
171        ((MainForm.WindowsForms.MainForm)MainFormManager.MainForm).RemoveOperationProgressFromView(this);
172      }
[14348]173    }
174
[15626]175    /// <summary>
176    /// Updates the <see cref="variableImactsArrayView"/> according to the selected ordering <see cref="ascendingCheckBox"/> of the selected Column <see cref="sortByComboBox"/>
177    /// The default is "Descending" by "VariableImpact" (as in previous versions)
178    /// </summary>
179    private void UpdateDataOrdering() {
[15665]180      //Check if valid sortingCriteria is selected and data exists
[15673]181      if (sortByComboBox.SelectedIndex == -1) { return; }
182      if (rawVariableImpacts == null) { return; }
183      if (!rawVariableImpacts.Any()) { return; }
[15665]184
[15673]185      var selectedItem = (SortingCriteria)sortByComboBox.SelectedItem;
[15626]186      bool ascending = ascendingCheckBox.Checked;
187
[15665]188      IEnumerable<KeyValuePair<string, double>> orderedEntries = null;
[15626]189
[15665]190      //Sort accordingly
191      switch (selectedItem) {
[15673]192        case SortingCriteria.ImpactValue:
193          orderedEntries = rawVariableImpacts.OrderBy(v => v.Value);
[15665]194          break;
[15673]195        case SortingCriteria.Occurrence:
196          orderedEntries = rawVariableImpacts;
[15665]197          break;
[15673]198        case SortingCriteria.VariableName:
199          orderedEntries = rawVariableImpacts.OrderBy(v => v.Key, new NaturalStringComparer());
[15665]200          break;
201        default:
[15673]202          throw new NotImplementedException("Ordering for selected SortingCriteria not implemented");
[15626]203      }
204
[15673]205      if (!ascending) { orderedEntries = orderedEntries.Reverse(); }
206
[15665]207      //Write the data back
208      var impactArray = new DoubleArray(orderedEntries.Select(i => i.Value).ToArray()) {
209        ElementNames = orderedEntries.Select(i => i.Key)
210      };
[15973]211
212      //Could be, if the View was closed
213      if (!variableImactsArrayView.IsDisposed) {
214        variableImactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly();
215      }
[15626]216    }
[14348]217  }
218}
Note: See TracBrowser for help on using the repository browser.