Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionVariableImpactsView.cs @ 16403

Last change on this file since 16403 was 16232, checked in by mkommend, 6 years ago

#2884: Removed unnecesary comment in ClassificationSolutionVariableImpactView.

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