Changeset 16422 for trunk/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionVariableImpactsView.cs
- Timestamp:
- 12/20/18 13:29:51 (5 years ago)
- Location:
- trunk/HeuristicLab.Problems.DataAnalysis.Views
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/HeuristicLab.Problems.DataAnalysis.Views
-
trunk/HeuristicLab.Problems.DataAnalysis.Views/3.4
-
Property
svn:mergeinfo
set to
(toggle deleted branches)
/branches/2904_CalculateImpacts/HeuristicLab.Problems.DataAnalysis.Views/3.4 merged eligible /stable/HeuristicLab.Problems.DataAnalysis.Views/3.4 merged eligible /branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4 13329-15286 /branches/Benchmarking/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4 6917-7005 /branches/ClassificationModelComparison/HeuristicLab.Problems.DataAnalysis.Views/3.4 9116-13099 /branches/CloningRefactoring/HeuristicLab.Problems.DataAnalysis.Views/3.4 4656-4721 /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Views/3.4 5471-5599 /branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis.Views/3.4 5815-6180 /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Views/3.4 4458-4459,4462,4464 /branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Views/3.4 10085-11101 /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4 8036-8538 /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4 6284-6795 /branches/GP.Symbols (TimeLag, Diff, Integral)/HeuristicLab.Problems.DataAnalysis.Views/3.4 5060 /branches/HeuristicLab.DatasetRefactor/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4 11570-12508 /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.DataAnalysis.Views/3.4 11130-12721 /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4 13780-14091 /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4 7098-8789 /branches/NET40/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4 5138-5162 /branches/ParallelEngine/HeuristicLab.Problems.DataAnalysis.Views/3.4 5175-5192 /branches/ProblemInstancesRegressionAndClassification/HeuristicLab.Problems.DataAnalysis.Views/3.4 7568-7810 /branches/QAPAlgorithms/HeuristicLab.Problems.DataAnalysis.Views/3.4 6350-6627 /branches/Restructure trunk solution/HeuristicLab.Problems.DataAnalysis.Views/3.4 6828 /branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Views/3.4 15318-15370 /branches/SuccessProgressAnalysis/HeuristicLab.Problems.DataAnalysis.Views/3.4 5370-5682 /branches/Trunk/HeuristicLab.Problems.DataAnalysis.Views/3.4 6829-6865 /branches/VNS/HeuristicLab.Problems.DataAnalysis.Views/3.4 5594-5752 /branches/histogram/HeuristicLab.Problems.DataAnalysis.Views/3.4 5959-6341 /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4 14232-14825
-
Property
svn:mergeinfo
set to
(toggle deleted branches)
-
trunk/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionVariableImpactsView.cs
r16232 r16422 33 33 [Content(typeof(IClassificationSolution))] 34 34 public partial class ClassificationSolutionVariableImpactsView : DataAnalysisSolutionEvaluationView { 35 #region Nested Types36 35 private enum SortingCriteria { 37 36 ImpactValue, … … 39 38 VariableName 40 39 } 41 #endregion 42 43 #region Fields 44 private Dictionary<string, double> rawVariableImpacts = new Dictionary<string, double>(); 45 private Thread thread; 46 #endregion 47 48 #region Getter/Setter 40 private CancellationTokenSource cancellationToken = new CancellationTokenSource(); 41 private List<Tuple<string, double>> rawVariableImpacts = new List<Tuple<string, double>>(); 42 49 43 public new IClassificationSolution Content { 50 44 get { return (IClassificationSolution)base.Content; } … … 53 47 } 54 48 } 55 #endregion 56 57 #region Ctor 49 58 50 public ClassificationSolutionVariableImpactsView() 59 51 : base() { 60 52 InitializeComponent(); 61 53 62 this.sortByComboBox.Items.AddRange(Enum.GetValues(typeof(SortingCriteria)).Cast<object>().ToArray());63 this.sortByComboBox.SelectedItem = SortingCriteria.ImpactValue;64 65 54 //Set the default values 66 55 this.dataPartitionComboBox.SelectedIndex = 0; 67 this.replacementComboBox.SelectedIndex = 0;56 this.replacementComboBox.SelectedIndex = 3; 68 57 this.factorVarReplComboBox.SelectedIndex = 0; 69 } 70 #endregion 71 72 #region Events 58 this.sortByComboBox.SelectedItem = SortingCriteria.ImpactValue; 59 } 60 73 61 protected override void RegisterContentEvents() { 74 62 base.RegisterContentEvents(); … … 76 64 Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged); 77 65 } 78 79 66 protected override void DeregisterContentEvents() { 80 67 base.DeregisterContentEvents(); … … 86 73 OnContentChanged(); 87 74 } 88 89 75 protected virtual void Content_ModelChanged(object sender, EventArgs e) { 90 76 OnContentChanged(); 91 77 } 92 93 78 protected override void OnContentChanged() { 94 79 base.OnContentChanged(); 80 rawVariableImpacts.Clear(); 81 95 82 if (Content == null) { 96 variableIm actsArrayView.Content = null;83 variableImpactsArrayView.Content = null; 97 84 } else { 98 85 UpdateVariableImpact(); 99 86 } 100 87 } 101 102 88 private void ClassificationSolutionVariableImpactsView_VisibleChanged(object sender, EventArgs e) { 103 if (thread == null) { return; } 104 105 if (thread.IsAlive) { thread.Abort(); } 106 thread = null; 107 } 108 89 cancellationToken.Cancel(); 90 } 109 91 110 92 private void dataPartitionComboBox_SelectedIndexChanged(object sender, EventArgs e) { 93 rawVariableImpacts.Clear(); 111 94 UpdateVariableImpact(); 112 95 } 113 114 96 private void replacementComboBox_SelectedIndexChanged(object sender, EventArgs e) { 97 rawVariableImpacts.Clear(); 115 98 UpdateVariableImpact(); 116 99 } 117 118 100 private void sortByComboBox_SelectedIndexChanged(object sender, EventArgs e) { 119 101 //Update the default ordering (asc,desc), but remove the eventHandler beforehand (otherwise the data would be ordered twice) 120 102 ascendingCheckBox.CheckedChanged -= ascendingCheckBox_CheckedChanged; 121 switch ((SortingCriteria)sortByComboBox.SelectedItem) { 122 case SortingCriteria.ImpactValue: 123 ascendingCheckBox.Checked = false; 124 break; 125 case SortingCriteria.Occurrence: 126 ascendingCheckBox.Checked = true; 127 break; 128 case SortingCriteria.VariableName: 129 ascendingCheckBox.Checked = true; 130 break; 131 default: 132 throw new NotImplementedException("Ordering for selected SortingCriteria not implemented"); 133 } 103 ascendingCheckBox.Checked = (SortingCriteria)sortByComboBox.SelectedItem != SortingCriteria.ImpactValue; 134 104 ascendingCheckBox.CheckedChanged += ascendingCheckBox_CheckedChanged; 135 105 136 UpdateDataOrdering(); 137 } 138 106 UpdateOrdering(); 107 } 139 108 private void ascendingCheckBox_CheckedChanged(object sender, EventArgs e) { 140 UpdateDataOrdering(); 141 } 142 143 #endregion 144 145 #region Helper Methods 146 private void UpdateVariableImpact() { 109 UpdateOrdering(); 110 } 111 112 private async void UpdateVariableImpact() { 113 IProgress progress; 114 147 115 //Check if the selection is valid 148 116 if (Content == null) { return; } … … 157 125 var dataPartition = (ClassificationSolutionVariableImpactsCalculator.DataPartitionEnum)dataPartitionComboBox.SelectedItem; 158 126 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); 127 variableImpactsArrayView.Caption = Content.Name + " Variable Impacts"; 128 progress = mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name); 129 progress.ProgressValue = 0; 130 131 cancellationToken = new CancellationTokenSource(); 132 133 try { 167 134 var problemData = Content.ProblemData; 168 135 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()); 136 //Remember the original ordering of the variables 137 var originalVariableOrdering = problemData.Dataset.VariableNames 138 .Where(v => inputvariables.Contains(v)) 139 .Where(v => problemData.Dataset.VariableHasType<double>(v) || problemData.Dataset.VariableHasType<string>(v)) 140 .ToList(); 141 142 List<Tuple<string, double>> impacts = null; 143 await Task.Run(() => { impacts = CalculateVariableImpacts(originalVariableOrdering, Content.Model, problemData, Content.EstimatedClassValues, dataPartition, replMethod, factorReplMethod, cancellationToken.Token, progress); }); 144 if (impacts == null) { return; } 145 146 rawVariableImpacts.AddRange(impacts); 147 UpdateOrdering(); 148 } 149 finally { 150 ((MainForm.WindowsForms.MainForm)MainFormManager.MainForm).RemoveOperationProgressFromView(this); 151 } 152 } 153 private List<Tuple<string, double>> CalculateVariableImpacts(List<string> originalVariableOrdering, 154 IClassificationModel model, 155 IClassificationProblemData problemData, 156 IEnumerable<double> estimatedClassValues, 157 ClassificationSolutionVariableImpactsCalculator.DataPartitionEnum dataPartition, 158 ClassificationSolutionVariableImpactsCalculator.ReplacementMethodEnum replMethod, 159 ClassificationSolutionVariableImpactsCalculator.FactorReplacementMethodEnum factorReplMethod, 160 CancellationToken token, 161 IProgress progress) { 162 List<Tuple<string, double>> impacts = new List<Tuple<string, double>>(); 163 int count = originalVariableOrdering.Count; 164 int i = 0; 165 var modifiableDataset = ((Dataset)(problemData.Dataset).Clone()).ToModifiable(); 166 IEnumerable<int> rows = ClassificationSolutionVariableImpactsCalculator.GetPartitionRows(dataPartition, problemData); 167 168 //Calculate original quality-values (via calculator, default is R²) 169 IEnumerable<double> targetValuesPartition = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows); 170 IEnumerable<double> estimatedClassValuesPartition = Content.GetEstimatedClassValues(rows); 171 172 var originalCalculatorValue = ClassificationSolutionVariableImpactsCalculator.CalculateQuality(targetValuesPartition, estimatedClassValuesPartition); 173 var clonedModel = (IClassificationModel)model.Clone(); 174 foreach (var variableName in originalVariableOrdering) { 175 if (cancellationToken.Token.IsCancellationRequested) { return null; } 176 progress.ProgressValue = (double)++i / count; 177 progress.Status = string.Format("Calculating impact for variable {0} ({1} of {2})", variableName, i, count); 178 179 double impact = 0; 180 //If the variable isn't used for prediction, it has zero impact. 181 if (model.VariablesUsedForPrediction.Contains(variableName)) { 182 impact = ClassificationSolutionVariableImpactsCalculator.CalculateImpact(variableName, clonedModel, problemData, modifiableDataset, rows, replMethod, factorReplMethod, targetValuesPartition, originalCalculatorValue); 183 } 184 impacts.Add(new Tuple<string, double>(variableName, impact)); 185 } 186 187 return impacts; 178 188 } 179 189 180 190 /// <summary> 181 /// Updates the <see cref="variableIm actsArrayView"/> according to the selected ordering <see cref="ascendingCheckBox"/> of the selected Column <see cref="sortByComboBox"/>191 /// Updates the <see cref="variableImpactsArrayView"/> according to the selected ordering <see cref="ascendingCheckBox"/> of the selected Column <see cref="sortByComboBox"/> 182 192 /// The default is "Descending" by "VariableImpact" (as in previous versions) 183 193 /// </summary> 184 private void Update DataOrdering() {194 private void UpdateOrdering() { 185 195 //Check if valid sortingCriteria is selected and data exists 186 196 if (sortByComboBox.SelectedIndex == -1) { return; } … … 191 201 bool ascending = ascendingCheckBox.Checked; 192 202 193 IEnumerable< KeyValuePair<string, double>> orderedEntries = null;203 IEnumerable<Tuple<string, double>> orderedEntries = null; 194 204 195 205 //Sort accordingly 196 206 switch (selectedItem) { 197 207 case SortingCriteria.ImpactValue: 198 orderedEntries = rawVariableImpacts.OrderBy(v => v. Value);208 orderedEntries = rawVariableImpacts.OrderBy(v => v.Item2); 199 209 break; 200 210 case SortingCriteria.Occurrence: … … 202 212 break; 203 213 case SortingCriteria.VariableName: 204 orderedEntries = rawVariableImpacts.OrderBy(v => v. Key, new NaturalStringComparer());214 orderedEntries = rawVariableImpacts.OrderBy(v => v.Item1, new NaturalStringComparer()); 205 215 break; 206 216 default: … … 211 221 212 222 //Write the data back 213 var impactArray = new DoubleArray(orderedEntries.Select(i => i. Value).ToArray()) {214 ElementNames = orderedEntries.Select(i => i. Key)223 var impactArray = new DoubleArray(orderedEntries.Select(i => i.Item2).ToArray()) { 224 ElementNames = orderedEntries.Select(i => i.Item1) 215 225 }; 216 226 217 227 //Could be, if the View was closed 218 if (!variableImactsArrayView.IsDisposed) { 219 variableImactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly(); 220 } 221 } 222 #endregion 228 if (!variableImpactsArrayView.IsDisposed) { 229 variableImpactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly(); 230 } 231 } 223 232 } 224 233 }
Note: See TracChangeset
for help on using the changeset viewer.