Changeset 16036 for branches/2904_CalculateImpacts/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionVariableImpactsView.cs
- Timestamp:
- 08/01/18 14:01:08 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2904_CalculateImpacts/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionVariableImpactsView.cs
r15753 r16036 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 //Little workaround. If you fill the ComboBox-Items in the other partial class, the UI-Designer will moan.63 this.sortByComboBox.Items.AddRange(Enum.GetValues(typeof(SortingCriteria)).Cast<object>().ToArray());64 this.sortByComboBox.SelectedItem = SortingCriteria.ImpactValue;65 66 54 //Set the default values 67 55 this.dataPartitionComboBox.SelectedIndex = 0; 68 this.replacementComboBox.SelectedIndex = 0;56 this.replacementComboBox.SelectedIndex = 3; 69 57 this.factorVarReplComboBox.SelectedIndex = 0; 70 } 71 #endregion 72 73 #region Events 58 this.sortByComboBox.SelectedItem = SortingCriteria.ImpactValue; 59 } 60 74 61 protected override void RegisterContentEvents() { 75 62 base.RegisterContentEvents(); … … 77 64 Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged); 78 65 } 79 80 66 protected override void DeregisterContentEvents() { 81 67 base.DeregisterContentEvents(); … … 87 73 OnContentChanged(); 88 74 } 89 90 75 protected virtual void Content_ModelChanged(object sender, EventArgs e) { 91 76 OnContentChanged(); 92 77 } 93 94 78 protected override void OnContentChanged() { 95 79 base.OnContentChanged(); … … 100 84 } 101 85 } 102 103 86 private void ClassificationSolutionVariableImpactsView_VisibleChanged(object sender, EventArgs e) { 104 if (thread == null) { return; } 105 106 if (thread.IsAlive) { thread.Abort(); } 107 thread = null; 108 } 109 87 cancellationToken.Cancel(); 88 } 110 89 111 90 private void dataPartitionComboBox_SelectedIndexChanged(object sender, EventArgs e) { 112 91 UpdateVariableImpact(); 113 92 } 114 115 93 private void replacementComboBox_SelectedIndexChanged(object sender, EventArgs e) { 116 94 UpdateVariableImpact(); 117 95 } 118 119 96 private void sortByComboBox_SelectedIndexChanged(object sender, EventArgs e) { 120 97 //Update the default ordering (asc,desc), but remove the eventHandler beforehand (otherwise the data would be ordered twice) 121 98 ascendingCheckBox.CheckedChanged -= ascendingCheckBox_CheckedChanged; 122 switch ((SortingCriteria)sortByComboBox.SelectedItem) { 123 case SortingCriteria.ImpactValue: 124 ascendingCheckBox.Checked = false; 125 break; 126 case SortingCriteria.Occurrence: 127 ascendingCheckBox.Checked = true; 128 break; 129 case SortingCriteria.VariableName: 130 ascendingCheckBox.Checked = true; 131 break; 132 default: 133 throw new NotImplementedException("Ordering for selected SortingCriteria not implemented"); 134 } 99 ascendingCheckBox.Checked = (SortingCriteria)sortByComboBox.SelectedItem != SortingCriteria.ImpactValue; 135 100 ascendingCheckBox.CheckedChanged += ascendingCheckBox_CheckedChanged; 136 101 137 UpdateDataOrdering(); 138 } 139 102 UpdateOrdering(); 103 } 140 104 private void ascendingCheckBox_CheckedChanged(object sender, EventArgs e) { 141 UpdateDataOrdering(); 142 } 143 144 #endregion 145 146 #region Helper Methods 147 private void UpdateVariableImpact() { 105 UpdateOrdering(); 106 } 107 108 private async void UpdateVariableImpact() { 148 109 //Check if the selection is valid 149 110 if (Content == null) { return; } … … 152 113 if (factorVarReplComboBox.SelectedIndex < 0) { return; } 153 114 115 IProgress progress; 116 154 117 //Prepare arguments 155 118 var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm; … … 159 122 160 123 variableImactsArrayView.Caption = Content.Name + " Variable Impacts"; 161 162 mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name); 163 164 Task.Factory.StartNew(() => { 165 thread = Thread.CurrentThread; 166 //Remember the original ordering of the variables 167 var impacts = ClassificationSolutionVariableImpactsCalculator.CalculateImpacts(Content, dataPartition, replMethod, factorReplMethod); 124 progress = mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name); 125 progress.ProgressValue = 0; 126 127 cancellationToken = new CancellationTokenSource(); 128 129 try { 168 130 var problemData = Content.ProblemData; 169 131 var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(Content.Model.VariablesUsedForPrediction)); 170 var originalVariableOrdering = problemData.Dataset.VariableNames.Where(v => inputvariables.Contains(v)).Where(problemData.Dataset.VariableHasType<double>).ToList(); 132 //Remember the original ordering of the variables 133 var originalVariableOrdering = problemData.Dataset.VariableNames 134 .Where(v => inputvariables.Contains(v)) 135 .Where(v => problemData.Dataset.VariableHasType<double>(v) || problemData.Dataset.VariableHasType<string>(v)) 136 .ToList(); 137 138 List<Tuple<string, double>> impacts = null; 139 140 await Task.Run(() => { impacts = CalculateVariableImpacts(originalVariableOrdering, (IClassificationModel)Content.Model.Clone(), problemData, Content.EstimatedClassValues, dataPartition, replMethod, factorReplMethod, cancellationToken.Token, progress); }); 141 if (impacts == null) { return; } 171 142 172 143 rawVariableImpacts.Clear(); 173 originalVariableOrdering.ForEach(v => rawVariableImpacts.Add(v, impacts.First(vv => vv.Item1 == v).Item2)); 174 }).ContinueWith((o) => { 175 UpdateDataOrdering(); 176 mainForm.RemoveOperationProgressFromView(this); 177 thread = null; 178 }, TaskScheduler.FromCurrentSynchronizationContext()); 144 originalVariableOrdering.ForEach(v => rawVariableImpacts.Add(new Tuple<string, double>(v, impacts.First(vv => vv.Item1 == v).Item2))); 145 UpdateOrdering(); 146 } 147 finally { 148 ((MainForm.WindowsForms.MainForm)MainFormManager.MainForm).RemoveOperationProgressFromView(this); 149 } 150 } 151 152 private List<Tuple<string, double>> CalculateVariableImpacts(List<string> originalVariableOrdering, 153 IClassificationModel model, 154 IClassificationProblemData problemData, 155 IEnumerable<double> estimatedValues, 156 ClassificationSolutionVariableImpactsCalculator.DataPartitionEnum dataPartition, 157 ClassificationSolutionVariableImpactsCalculator.ReplacementMethodEnum replMethod, 158 ClassificationSolutionVariableImpactsCalculator.FactorReplacementMethodEnum factorReplMethod, 159 CancellationToken token, 160 IProgress progress) { 161 List<Tuple<string, double>> impacts = new List<Tuple<string, double>>(); 162 int count = originalVariableOrdering.Count; 163 int i = 0; 164 var modifiableDataset = ((Dataset)(problemData.Dataset).Clone()).ToModifiable(); 165 IEnumerable<int> rows = ClassificationSolutionVariableImpactsCalculator.GetPartitionRows(dataPartition, problemData); 166 167 //Calculate original quality-values (via calculator, default is R²) 168 OnlineCalculatorError error; 169 IEnumerable<double> targetValuesPartition = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows); 170 IEnumerable<double> estimatedValuesPartition = rows.Select(v => estimatedValues.ElementAt(v)); 171 var originalCalculatorValue = ClassificationSolutionVariableImpactsCalculator.CalculateVariableImpact(targetValuesPartition, estimatedValuesPartition, out error); 172 if (error != OnlineCalculatorError.None) throw new InvalidOperationException("Error during calculation."); 173 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 = ClassificationSolutionVariableImpactsCalculator.CalculateImpact(variableName, model, modifiableDataset, rows, targetValuesPartition, originalCalculatorValue, replMethod, factorReplMethod); 180 impacts.Add(new Tuple<string, double>(variableName, impact)); 181 } 182 183 return impacts; 179 184 } 180 185 … … 183 188 /// The default is "Descending" by "VariableImpact" (as in previous versions) 184 189 /// </summary> 185 private void Update DataOrdering() {190 private void UpdateOrdering() { 186 191 //Check if valid sortingCriteria is selected and data exists 187 192 if (sortByComboBox.SelectedIndex == -1) { return; } … … 192 197 bool ascending = ascendingCheckBox.Checked; 193 198 194 IEnumerable< KeyValuePair<string, double>> orderedEntries = null;199 IEnumerable<Tuple<string, double>> orderedEntries = null; 195 200 196 201 //Sort accordingly 197 202 switch (selectedItem) { 198 203 case SortingCriteria.ImpactValue: 199 orderedEntries = rawVariableImpacts.OrderBy(v => v. Value);204 orderedEntries = rawVariableImpacts.OrderBy(v => v.Item2); 200 205 break; 201 206 case SortingCriteria.Occurrence: … … 203 208 break; 204 209 case SortingCriteria.VariableName: 205 orderedEntries = rawVariableImpacts.OrderBy(v => v. Key, new NaturalStringComparer());210 orderedEntries = rawVariableImpacts.OrderBy(v => v.Item1, new NaturalStringComparer()); 206 211 break; 207 212 default: … … 212 217 213 218 //Write the data back 214 var impactArray = new DoubleArray(orderedEntries.Select(i => i. Value).ToArray()) {215 ElementNames = orderedEntries.Select(i => i. Key)219 var impactArray = new DoubleArray(orderedEntries.Select(i => i.Item2).ToArray()) { 220 ElementNames = orderedEntries.Select(i => i.Item1) 216 221 }; 217 222 … … 221 226 } 222 227 } 223 #endregion224 228 } 225 229 }
Note: See TracChangeset
for help on using the changeset viewer.