Free cookie consent management tool by TermsFeed Policy Generator

source: branches/StatisticalTesting/HeuristicLab.Analysis.Statistics/3.3/StatisticalTestingView.cs @ 9911

Last change on this file since 9911 was 9911, checked in by ascheibe, 11 years ago

#2031

  • renamed statistical run collection views
  • implemented RunCollection events in statistical testing view
  • incorporate content name into view caption
File size: 13.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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.Windows.Forms;
26using HeuristicLab.Core.Views;
27using HeuristicLab.Data;
28using HeuristicLab.MainForm;
29using HeuristicLab.Optimization;
30using HeuristicLab.Optimization.Views;
31
32namespace HeuristicLab.Analysis.Statistics {
33  [View("Statistical Testing")]
34  [Content(typeof(RunCollection), false)]
35  public sealed partial class StatisticalTestingView : ItemView {
36    private double[][] data;
37
38    public StatisticalTestingView() {
39      InitializeComponent();
40    }
41
42    public new RunCollection Content {
43      get { return (RunCollection)base.Content; }
44      set { base.Content = value; }
45    }
46
47    public override bool ReadOnly {
48      get { return true; }
49      set { /*not needed because results are always readonly */}
50    }
51
52    protected override void OnContentChanged() {
53      base.OnContentChanged();
54
55      if (Content != null) {
56        UpdateResultComboBox();
57        UpdateGroupsComboBox();
58        FillCompComboBox();
59        RebuildDataTable();
60      }
61      UpdateCaption();
62    }
63
64    private void UpdateCaption() {
65      Caption = Content != null ? Content.OptimizerName + " Statistical Testing" : ViewAttribute.GetViewName(GetType());
66    }
67
68    #region events
69    protected override void RegisterContentEvents() {
70      base.RegisterContentEvents();
71      Content.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
72      Content.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
73      Content.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
74      Content.UpdateOfRunsInProgressChanged += Content_UpdateOfRunsInProgressChanged;
75    }
76
77    protected override void DeregisterContentEvents() {
78      base.DeregisterContentEvents();
79      Content.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
80      Content.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
81      Content.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
82      Content.UpdateOfRunsInProgressChanged -= Content_UpdateOfRunsInProgressChanged;
83    }
84
85    private void Content_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
86      RebuildDataTable();
87    }
88
89    private void Content_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
90      RebuildDataTable();
91    }
92
93    private void Content_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
94      RebuildDataTable();
95    }
96
97    void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
98      if (!Content.UpdateOfRunsInProgress) {
99        RebuildDataTable();
100      }
101    }
102    #endregion
103
104    private void UpdateGroupsComboBox() {
105      groupComboBox.Items.Clear();
106
107      var parameters = (from run in Content
108                        where run.Visible
109                        from param in run.Parameters
110                        select param.Key).Distinct().ToArray();
111
112      foreach (var p in parameters) {
113        var variations = (from run in Content
114                          where run.Visible && run.Parameters.ContainsKey(p) &&
115                          (run.Parameters[p] is IntValue || run.Parameters[p] is DoubleValue ||
116                          run.Parameters[p] is StringValue || run.Parameters[p] is BoolValue)
117                          select ((dynamic)run.Parameters[p]).Value).Distinct();
118
119        if (variations.Count() > 1) {
120          groupComboBox.Items.Add(p);
121        }
122      }
123
124      if (groupComboBox.Items.Count > 0) {
125        //try to select something different than "Seed" or "Algorithm Name" as this makes no sense
126        //and takes a long time to group
127        List<int> possibleIndizes = new List<int>();
128        for (int i = 0; i < groupComboBox.Items.Count; i++) {
129          if (groupComboBox.Items[i].ToString() != "Seed"
130            && groupComboBox.Items[i].ToString() != "Algorithm Name") {
131            possibleIndizes.Add(i);
132          }
133        }
134
135        if (possibleIndizes.Count > 0) {
136          groupComboBox.SelectedItem = groupComboBox.Items[possibleIndizes.First()];
137        } else {
138          groupComboBox.SelectedItem = groupComboBox.Items[0];
139        }
140      }
141    }
142
143    private string[] GetColumnNames(IEnumerable<IRun> runs) {
144      string parameterName = (string)groupComboBox.SelectedItem;
145      var r = runs.Where(x => x.Parameters.ContainsKey(parameterName));
146      return r.Select(x => ((dynamic)x.Parameters[parameterName]).Value).Distinct().Select(x => (string)x.ToString()).ToArray();
147    }
148
149    private void UpdateResultComboBox() {
150      resultComboBox.Items.Clear();
151      var results = (from run in Content
152                     where run.Visible
153                     from result in run.Results
154                     where result.Value is IntValue || result.Value is DoubleValue
155                     select result.Key).Distinct().ToArray();
156
157      resultComboBox.Items.AddRange(results);
158      if (resultComboBox.Items.Count > 0) resultComboBox.SelectedItem = resultComboBox.Items[0];
159    }
160
161    private void FillCompComboBox() {
162      string parameterName = (string)groupComboBox.SelectedItem;
163      if (parameterName != null) {
164        string resultName = (string)resultComboBox.SelectedItem;
165        if (resultName != null) {
166          var runs = Content.Where(x => x.Results.ContainsKey(resultName) && x.Visible);
167          var columnNames = GetColumnNames(runs).ToList();
168          groupCompComboBox.Items.Clear();
169          columnNames.ForEach(x => groupCompComboBox.Items.Add(x));
170          if (groupCompComboBox.Items.Count > 0) groupCompComboBox.SelectedItem = groupCompComboBox.Items[0];
171        }
172      }
173    }
174
175    private void RebuildDataTable() {
176      string parameterName = (string)groupComboBox.SelectedItem;
177      if (parameterName != null) {
178        string resultName = (string)resultComboBox.SelectedItem;
179
180        var runs = Content.Where(x => x.Results.ContainsKey(resultName) && x.Visible);
181        var columnNames = GetColumnNames(runs);
182        var groups = GetGroups(columnNames, runs);
183        data = new double[columnNames.Count()][];
184
185        DoubleMatrix dt = new DoubleMatrix(groups.Select(x => x.Count()).Max(), columnNames.Count());
186        dt.ColumnNames = columnNames;
187
188        int i = 0;
189        int j = 0;
190        foreach (string columnName in columnNames) {
191          j = 0;
192          data[i] = new double[groups[i].Count()];
193          foreach (IRun run in groups[i]) {
194            dt[j, i] = (double)((dynamic)run.Results[resultName]).Value;
195            data[i][j] = dt[j, i];
196            j++;
197          }
198          i++;
199        }
200
201        stringConvertibleMatrixView.Content = dt;
202      }
203    }
204
205    private List<IEnumerable<IRun>> GetGroups(string[] columnNames, IEnumerable<IRun> runs) {
206      List<IEnumerable<IRun>> runCols = new List<IEnumerable<IRun>>();
207      string parameterName = (string)groupComboBox.SelectedItem;
208
209      foreach (string cn in columnNames) {
210        var tmpRuns = runs.Where(x => ((string)((dynamic)x.Parameters[parameterName]).Value.ToString()) == cn);
211        runCols.Add(tmpRuns);
212      }
213
214      return runCols;
215    }
216
217    private void ResetUI() {
218      normalityLabel.Image = null;
219      groupCompLabel.Image = null;
220      pairwiseLabel.Image = null;
221      pValTextBox.Text = string.Empty;
222      equalDistsTextBox.Text = string.Empty;
223    }
224
225    private void testButton_Click(object sender, EventArgs e) {
226      double pval = KruskalWallis.Test(data);
227      pValTextBox.Text = pval.ToString();
228      if (pval < 0.05) {
229        groupCompLabel.Image = HeuristicLab.Analysis.Statistics.Resources.Default;
230      } else {
231        groupCompLabel.Image = HeuristicLab.Common.Resources.VSImageLibrary.Warning;
232      }
233    }
234
235    private void normalDistButton_Click(object sender, EventArgs e) {
236      double val;
237      List<double> res = new List<double>();
238
239      for (int i = 0; i < data.Length; i++) {
240        alglib.jarqueberatest(data[i], data[i].Length, out val);
241        res.Add(val);
242      }
243
244      for (int i = 0; i < res.Count(); i++) {
245        if (res[i] < 0.1) {
246          normalityLabel.Image = HeuristicLab.Common.Resources.VSImageLibrary.Warning;
247        } else {
248          normalityLabel.Image = HeuristicLab.Analysis.Statistics.Resources.Default;
249        }
250      }
251    }
252
253    private void resultComboBox_SelectedValueChanged(object sender, EventArgs e) {
254      RebuildDataTable();
255      ResetUI();
256    }
257
258    private void groupComboBox_SelectedValueChanged(object sender, EventArgs e) {
259      FillCompComboBox();
260      RebuildDataTable();
261      ResetUI();
262    }
263
264    private void normalityDetails_Click(object sender, EventArgs e) {
265      DoubleMatrix pValsMatrix = new DoubleMatrix(1, stringConvertibleMatrixView.Content.Columns);
266      pValsMatrix.ColumnNames = stringConvertibleMatrixView.Content.ColumnNames;
267      pValsMatrix.RowNames = new string[] { "p-Value" };
268
269      double val;
270      for (int i = 0; i < data.Length; i++) {
271        alglib.jarqueberatest(data[i], data[i].Length, out val);
272        pValsMatrix[0, i] = val;
273      }
274
275      MainFormManager.MainForm.ShowContent(pValsMatrix);
276    }
277
278    private void pairwiseTestButton_Click(object sender, EventArgs e) {
279      string curItem = (string)groupCompComboBox.SelectedItem;
280      int colIndex = 0;
281
282      foreach (string col in stringConvertibleMatrixView.Content.ColumnNames) {
283        if (col == curItem) {
284          break;
285        }
286        colIndex++;
287      }
288
289      DoubleMatrix pValsMatrix = new DoubleMatrix(5, stringConvertibleMatrixView.Content.Columns);
290      pValsMatrix.ColumnNames = stringConvertibleMatrixView.Content.ColumnNames;
291      pValsMatrix.RowNames = new string[] { "p-Value of Mann-Whitney U", "p-Value of T-Test", "Necessary Sample Size for T-Test", "Cohen's d", "Hedges' g" };
292
293      double mwuBothtails;
294      double mwuLefttail;
295      double mwuRighttail;
296      double ttestLefttail;
297      for (int i = 0; i < data.Length; i++) {
298        alglib.mannwhitneyutest(data[colIndex], data[colIndex].Length, data[i], data[i].Length, out mwuBothtails, out mwuLefttail, out mwuRighttail);
299        ttestLefttail = TTest.Test(data[colIndex], data[i]);
300        pValsMatrix[0, i] = mwuBothtails;
301        pValsMatrix[1, i] = ttestLefttail;
302        pValsMatrix[2, i] = TTest.GetOptimalSampleSize(data[colIndex], data[i]);
303        pValsMatrix[3, i] = SampleSizeDetermination.CalculateCohensD(data[colIndex], data[i]);
304        pValsMatrix[4, i] = SampleSizeDetermination.CalculateHedgesG(data[colIndex], data[i]);
305      }
306
307      MainFormManager.MainForm.ShowContent(pValsMatrix);
308    }
309
310    private void infoLabel_DoubleClick(object sender, EventArgs e) {
311      using (InfoBox dialog = new InfoBox("Description of Statistical Tests", typeof(StatisticalTestingView).Namespace + ".InfoResources.StatisticalTestsInfo.rtf")) {
312        dialog.ShowDialog(this);
313      }
314    }
315
316    private void openBoxPlotToolStripMenuItem_Click(object sender, EventArgs e) {
317      RunCollectionBoxPlotView boxplotView = new RunCollectionBoxPlotView();
318      boxplotView.Content = Content;
319      // TODO: enable as soon as we move to HeuristicLab.Optimization.Views
320      // boxplotView.xAxisComboBox.SelectedItem = xAxisComboBox.SelectedItem;
321      // boxplotView.yAxisComboBox.SelectedItem = yAxisComboBox.SelectedItem;
322      boxplotView.Show();
323    }
324
325    private void pairwiseCheckDataButton_Click(object sender, EventArgs e) {
326      string curItem = (string)groupCompComboBox.SelectedItem;
327      int colIndex = 0;
328
329      foreach (string col in stringConvertibleMatrixView.Content.ColumnNames) {
330        if (col == curItem) {
331          break;
332        }
333        colIndex++;
334      }
335
336      double mwuBothtails;
337      double mwuLefttail;
338      double mwuRighttail;
339      int cnt = 0;
340
341      for (int i = 0; i < data.Length; i++) {
342        if (i != colIndex) {
343          alglib.mannwhitneyutest(data[colIndex], data[colIndex].Length, data[i], data[i].Length, out mwuBothtails, out mwuLefttail, out mwuRighttail);
344          if (mwuBothtails > 0.05) {
345            cnt++;
346          }
347        }
348      }
349
350      double ratio = ((double)cnt) / (data.Length - 1) * 100.0;
351      equalDistsTextBox.Text = ratio.ToString() + " %";
352
353      if (cnt == 0) {
354        pairwiseLabel.Image = HeuristicLab.Analysis.Statistics.Resources.Default;
355      } else {
356        pairwiseLabel.Image = HeuristicLab.Common.Resources.VSImageLibrary.Warning;
357      }
358    }
359  }
360}
Note: See TracBrowser for help on using the repository browser.