Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/RunCollectionVariableImpactView.cs @ 5750

Last change on this file since 5750 was 5750, checked in by gkronber, 13 years ago

#1418 Implemented variable view that allows to add and remove variable strings (ported from external evaluation views). Implemented formatter and grammar for external evaluation plugin. Fixed bug in symbolic expression view. Fixed bug in run collection variable impact view. Removed unused plugin HeuristicLab.Problems.ExternalEvaluation.GP.Views. Renamed files.

File size: 10.3 KB
RevLine 
[3969]1#region License Information
2/* HeuristicLab
[5445]3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[3969]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
[4385]22using System;
[3969]23using System.Collections.Generic;
24using System.Linq;
25using System.Windows.Forms;
[4068]26using HeuristicLab.Common;
27using HeuristicLab.Data;
[3969]28using HeuristicLab.MainForm;
29using HeuristicLab.MainForm.WindowsForms;
[4037]30using HeuristicLab.Optimization;
[3969]31
[5693]32namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
[3969]33  [Content(typeof(RunCollection), false)]
34  [View("RunCollection Variable Impact View")]
[4944]35  public sealed partial class RunCollectionVariableImpactView : AsynchronousContentView {
[5750]36    private const string variableImpactResultName = "Variable impacts";
[3969]37    public RunCollectionVariableImpactView() {
38      InitializeComponent();
39    }
40
41    public new RunCollection Content {
42      get { return (RunCollection)base.Content; }
43      set { base.Content = value; }
44    }
45
[4944]46    #region events
[3969]47    protected override void RegisterContentEvents() {
48      base.RegisterContentEvents();
[4944]49      Content.UpdateOfRunsInProgressChanged += new EventHandler(Content_UpdateOfRunsInProgressChanged);
50      Content.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
51      Content.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
52      Content.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
53      RegisterRunEvents(Content);
[3969]54    }
55    protected override void DeregisterContentEvents() {
56      base.RegisterContentEvents();
[4944]57      Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
58      Content.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
59      Content.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
60      Content.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
61      DeregisterRunEvents(Content);
[3969]62    }
[4944]63    private void RegisterRunEvents(IEnumerable<IRun> runs) {
64      foreach (IRun run in runs)
65        run.Changed += new EventHandler(Run_Changed);
[3969]66    }
[4944]67    private void DeregisterRunEvents(IEnumerable<IRun> runs) {
68      foreach (IRun run in runs)
69        run.Changed -= new EventHandler(Run_Changed);
70    }
[3969]71    private void Content_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
[4944]72      RegisterRunEvents(e.Items);
73      UpdateData();
[3969]74    }
75    private void Content_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
[4944]76      DeregisterRunEvents(e.Items);
77      UpdateData();
[3969]78    }
79    private void Content_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
[4944]80      DeregisterRunEvents(e.OldItems);
81      RegisterRunEvents(e.Items);
82      UpdateData();
83    }
84    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
85      if (!Content.UpdateOfRunsInProgress) UpdateData();
86    }
87    private void Run_Changed(object sender, EventArgs e) {
88      if (!Content.UpdateOfRunsInProgress) UpdateData();
89    }
90    #endregion
91
92    protected override void OnContentChanged() {
93      base.OnContentChanged();
[3969]94      this.UpdateData();
95    }
96
97    private void UpdateData() {
98      matrixView.Content = CalculateVariableImpactMatrix();
99    }
100
101    private DoubleMatrix CalculateVariableImpactMatrix() {
102      DoubleMatrix matrix = null;
103      if (Content != null) {
[4385]104        List<IRun> runsWithVariables = Content.Where(r => r.Visible && r.Results.ContainsKey(variableImpactResultName)).ToList();
[4124]105        IEnumerable<DoubleMatrix> allVariableImpacts = (from run in runsWithVariables
106                                                        select run.Results[variableImpactResultName]).Cast<DoubleMatrix>();
107        IEnumerable<string> variableNames = (from variableImpact in allVariableImpacts
108                                             from variableName in variableImpact.RowNames
109                                             select variableName)
110                                            .Distinct();
111        // filter variableNames: only include names that have at least one non-zero value in a run
112        List<string> variableNamesList = (from variableName in variableNames
113                                          where GetVariableImpacts(variableName, allVariableImpacts).Any(x => !x.IsAlmost(0.0))
114                                          select variableName)
115                                         .ToList();
116
[4143]117        List<string> statictics = new List<string> { "Median Rank", "Mean", "StdDev", "pValue" };
[3969]118        List<string> columnNames = runsWithVariables.Select(r => r.Name).ToList();
[3975]119        columnNames.AddRange(statictics);
[3969]120        int runs = runsWithVariables.Count();
121
[4124]122        matrix = new DoubleMatrix(variableNamesList.Count, runs + statictics.Count);
[3969]123        matrix.SortableView = true;
[4124]124        matrix.RowNames = variableNamesList;
[3969]125        matrix.ColumnNames = columnNames;
126
[4068]127        for (int i = 0; i < runsWithVariables.Count; i++) {
[4010]128          IRun run = runsWithVariables[i];
[3969]129          DoubleMatrix runVariableImpacts = (DoubleMatrix)run.Results[variableImpactResultName];
[4010]130          for (int j = 0; j < runVariableImpacts.Rows; j++) {
[4124]131            int rowIndex = variableNamesList.FindIndex(s => s == runVariableImpacts.RowNames.ElementAt(j));
132            if (rowIndex > -1) {
133              matrix[rowIndex, i] = runVariableImpacts[j, 0];
134            }
[3969]135          }
136        }
137
[4124]138        List<List<double>> variableImpactsOverRuns = (from variableName in variableNamesList
139                                                      select GetVariableImpacts(variableName, allVariableImpacts).ToList())
140                                                     .ToList();
141        List<List<double>> variableRanks = (from variableName in variableNamesList
142                                            select GetVariableImpactRanks(variableName, allVariableImpacts).ToList())
143                                        .ToList();
144        if (variableImpactsOverRuns.Count() > 0) {
[4143]145          // the variable with the worst median impact value is chosen as the reference variable
146          // this is problematic if all variables are relevant, however works often in practice
147          List<double> referenceImpacts = (from impacts in variableImpactsOverRuns
148                                           let avg = impacts.Median()
149                                           orderby avg
150                                           select impacts)
151                                           .First();
[4124]152          // for all variables
153          for (int row = 0; row < variableImpactsOverRuns.Count; row++) {
[4143]154            // median rank
[4124]155            matrix[row, runs] = variableRanks[row].Median();
[4143]156            // also show mean and std.dev. of relative variable impacts to indicate the relative difference in impacts of variables
157            matrix[row, runs + 1] = variableImpactsOverRuns[row].Average();
158            matrix[row, runs + 2] = variableImpactsOverRuns[row].StandardDeviation();
[4124]159
160            double leftTail = 0; double rightTail = 0; double bothTails = 0;
[4143]161            // calc differences of impacts for current variable and reference variable
162            double[] z = new double[referenceImpacts.Count];
163            for (int i = 0; i < z.Length; i++) {
164              z[i] = variableImpactsOverRuns[row][i] - referenceImpacts[i];
165            }
166            // wilcoxon signed rank test is used because the impact values of two variables in a single run are not independent
167            alglib.wsr.wilcoxonsignedranktest(z, z.Length, 0, ref bothTails, ref leftTail, ref rightTail);
168            matrix[row, runs + 3] = bothTails;
[4124]169          }
[3969]170        }
171      }
172      return matrix;
173    }
[4124]174
175    private IEnumerable<double> GetVariableImpactRanks(string variableName, IEnumerable<DoubleMatrix> allVariableImpacts) {
176      foreach (DoubleMatrix runVariableImpacts in allVariableImpacts) {
177        // certainly not yet very efficient because ranks are computed multiple times for the same run
178        string[] variableNames = runVariableImpacts.RowNames.ToArray();
179        double[] values = (from row in Enumerable.Range(0, runVariableImpacts.Rows)
180                           select runVariableImpacts[row, 0] * -1)
181                          .ToArray();
182        Array.Sort(values, variableNames);
183        // calculate ranks
184        double[] ranks = new double[values.Length];
185        // check for tied ranks
186        int i = 0;
187        while (i < values.Length) {
188          ranks[i] = i + 1;
189          int j = i + 1;
190          while (j < values.Length && values[i].IsAlmost(values[j])) {
191            ranks[j] = ranks[i];
192            j++;
193          }
194          i = j;
195        }
196        int rankIndex = 0;
197        foreach (string rowVariableName in variableNames) {
198          if (rowVariableName == variableName)
199            yield return ranks[rankIndex];
200          rankIndex++;
201        }
202      }
203    }
204
205    private IEnumerable<double> GetVariableImpacts(string variableName, IEnumerable<DoubleMatrix> allVariableImpacts) {
206      foreach (DoubleMatrix runVariableImpacts in allVariableImpacts) {
207        int row = 0;
208        foreach (string rowName in runVariableImpacts.RowNames) {
209          if (rowName == variableName)
210            yield return runVariableImpacts[row, 0];
211          row++;
212        }
213      }
214    }
[3969]215  }
216}
Note: See TracBrowser for help on using the repository browser.