Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/VariableInteractionNetworkView.cs @ 12321

Last change on this file since 12321 was 12321, checked in by arapeanu, 9 years ago

#2288: Modified CreateTargetVariationExperimentDialog.cs to exclude unchecked inputs from the target variables

File size: 19.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.ComponentModel;
25using System.Drawing;
26using System.Linq;
27using System.Windows.Forms;
28using HeuristicLab.Common;
29using HeuristicLab.Data;
30using HeuristicLab.MainForm;
31using HeuristicLab.MainForm.WindowsForms;
32using HeuristicLab.Optimization;
33using HeuristicLab.Problems.DataAnalysis;
34using HeuristicLab.Problems.DataAnalysis.Symbolic;
35using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
36using System.Collections;
37
38namespace HeuristicLab.VariableInteractionNetworks.Views
39{
40    [View("Variable Interaction Network")]
41    [Content(typeof(RunCollection), IsDefaultView = false)]
42
43    public sealed partial class VariableInteractionNetworkView : AsynchronousContentView
44    {
45        private const string variableImpactResultName = "Variable impacts";
46        private const string TrainingBestSolutionParameterName = "Best training solution";
47
48        public new RunCollection Content
49        {
50            get { return (RunCollection)base.Content; }
51            set { base.Content = value; }
52        }
53
54        public VariableInteractionNetworkView()
55        {
56            InitializeComponent();
57        }
58
59        internal class NoFocusTrackBar : System.Windows.Forms.TrackBar
60        {
61            [System.Runtime.InteropServices.DllImport("user32.dll")]
62            public extern static int SendMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
63
64            private static int MakeParam(int loWord, int hiWord)
65            {
66                return (hiWord << 16) | (loWord & 0xffff);
67            }
68
69            protected override void OnGotFocus(EventArgs e)
70            {
71                base.OnGotFocus(e);
72                SendMessage(this.Handle, 0x0128, MakeParam(1, 0x1), 0);
73            }
74        }
75
76        #region events
77
78        //  #region Event Handlers (Content)
79        protected override void OnContentChanged()
80        {
81            base.OnContentChanged();
82            if (Content == null)
83            {
84                // TODO: Add code when content has been changed and is null
85            }
86            else
87            {
88                // TODO: Add code when content has been changed and is not null
89                viewHost2.Content = CalculateNodeImportance(CalculateAdjacencyMatrix());     
90                var adjMatrix = CalculateAdjacencyMatrix();
91                viewHost1.Content = adjMatrix;
92                viewHost3.Content = (DoubleMatrix)adjMatrix.Clone();
93                trackBar1.Minimum = (int)(1000 * GetMinNonNullElement(adjMatrix));
94                trackBar1.Maximum = (int)(1000 * (adjMatrix.Max()));
95            }
96        }
97        #endregion
98
99        protected override void SetEnabledStateOfControls()
100        {
101            base.SetEnabledStateOfControls();
102            // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
103        }
104
105        #region Event Handlers (child controls)
106        // TODO: Put event handlers of child controls here.
107        #endregion
108
109        private DoubleMatrix CalculateAdjacencyMatrix()
110        {
111            var runCollection = Content;
112            var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
113
114            var allVariableImpacts = runCollection.Select(run => (DoubleMatrix)run.Results[variableImpactResultName]);
115            var variableNames = (from variableImpact in allVariableImpacts
116                                 from variableName in variableImpact.RowNames
117                                 select variableName).Distinct().ToArray();
118            var adjMatrix = new DoubleMatrix(variableNames.Length, variableNames.Length);
119
120            adjMatrix.RowNames = groupRunCollection.Select(x => x.Key);
121            adjMatrix.ColumnNames = adjMatrix.RowNames;
122            for (int j = 0; j < groupRunCollection.Count; ++j)
123            {
124                var g = groupRunCollection[j];
125                var matrix = CalculateAdjacencyRows(g);
126                var variables = new List<Tuple<string, double>>();
127                var columnNames = matrix.ColumnNames.ToList();
128
129                for (int i = 0; i < matrix.Columns; ++i)
130                {
131                    variables.Add(new Tuple<string, double>(columnNames[i], matrix[0, i]));
132                }
133                variables.Add(new Tuple<string, double>(g.Key, 0));
134                variables.Sort((a, b) => a.Item1.CompareTo(b.Item1));
135                for (int i = 0; i < variables.Count; ++i)
136                {
137                    adjMatrix[j, i] = variables[i].Item2;
138
139                }
140            }
141            return adjMatrix;
142        }
143
144        private DoubleMatrix CalculateAdjacencyRows(IEnumerable<IRun> runs)
145        {
146            IEnumerable<DoubleMatrix> allVariableImpacts = (from run in runs
147                                                            select run.Results[variableImpactResultName]).Cast<DoubleMatrix>();
148            var variableNames = (from variableImpact in allVariableImpacts
149                                 from variableName in variableImpact.RowNames
150                                 select variableName).Distinct().ToArray();
151
152            List<string> variableNamesList = (from variableName in variableNames
153                                              where GetVariableImpacts(variableName, allVariableImpacts).Any(x => !x.IsAlmost(0.0))
154                                              select variableName)
155                                             .ToList();
156
157            var runNames = runs.Select(x => x.Name).ToArray();
158            var runsArray = runs.ToArray();
159            DoubleMatrix varImpactMatrix = CalculateVariableImpactMatrix(runsArray, runNames);
160            var targetMatrix = new DoubleMatrix(1, variableNames.Length);
161
162            for (int i = 0; i < varImpactMatrix.Rows; ++i)
163            {
164                targetMatrix[0, i] = varImpactMatrix[i, runNames.Length];
165            }
166
167            targetMatrix.RowNames = new[] { "Target" };
168            targetMatrix.ColumnNames = variableNames;
169
170            return targetMatrix;
171        }
172
173        private DoubleMatrix UpdateAdjacencyMatrixByThresholdAndTargetVariable(double threshold, string targetVariable, DoubleMatrix adjMatrix)
174        {
175            var originalMatrix = (DoubleMatrix)viewHost1.Content;
176            var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
177            string[] targets = adjMatrix.RowNames.ToArray();
178            var targetIndex = Array.IndexOf(targets, targetVariable);
179
180            for (int j = 0; j < groupRunCollection.Count; ++j)
181            {
182                double originalValue = originalMatrix[targetIndex, j];
183                adjMatrix[targetIndex, j] = (originalValue <= Math.Max(threshold, Double.Parse(genThreshold.Text))) ? 0 : originalValue;
184            }
185            return adjMatrix;
186        }
187
188        private DoubleMatrix UpdateAdjacencyMatrixByThreshold(double threshold, DoubleMatrix adjMatrix)
189        {
190            var originalMatrix = (DoubleMatrix)viewHost1.Content;
191            var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
192
193            for (int i = 0; i < adjMatrix.Rows; ++i)
194            {
195                for (int j = 0; j < adjMatrix.Columns; ++j)
196                {
197                    double originalValue = originalMatrix[i, j];
198                    adjMatrix[i, j] = originalValue <= threshold ? 0 : originalValue;
199                }
200            }
201            return adjMatrix;
202        }
203
204        private double GetMinNonNullElement(DoubleMatrix adjMatrix)
205        {
206            double min = adjMatrix.Max();
207            for (int i = 0; i < adjMatrix.Rows; i++)
208            {
209                for (int j = 0; j < adjMatrix.Columns; j++)
210                {                 
211                    min = (min > adjMatrix[i, j] && adjMatrix[i, j] != 0) ? adjMatrix[i, j] : min;
212                }
213            }
214            return min;
215        }
216
217        private double GetMaxFromRow(int rowIndex, DoubleMatrix adjMatrix)
218        {
219            double max = adjMatrix.Min();
220            for (int j = 0; j < adjMatrix.Columns; ++j)
221            {
222                max = (max < adjMatrix[rowIndex, j] && adjMatrix[rowIndex, j] != 0) ? adjMatrix[rowIndex, j] : max;
223            }
224            return max;
225        }
226
227        private DoubleMatrix CalculateNodeImportance(DoubleMatrix adjMatrix)
228        {
229            DoubleMatrix nodeImportance = new DoubleMatrix(adjMatrix.Rows, 1);
230            var variables = new List<Tuple<string, double>>();
231            var rowNames = adjMatrix.RowNames.ToList();
232            var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
233            double[] meanQuality = new double[groupRunCollection.Count];
234
235            for (int j = 0; j < groupRunCollection.Count; ++j)
236            {
237                var g = groupRunCollection[j];
238                meanQuality[j] = g.Average(x => ((IRegressionSolution)x.Results[TrainingBestSolutionParameterName]).TrainingRSquared);
239            }
240
241            for (int i = 0; i < adjMatrix.Columns; ++i)
242            {
243                for (int j = 0; j < adjMatrix.Rows; ++j)
244                {
245                    nodeImportance[i, 0] += adjMatrix[j, i] * meanQuality[j];
246                }
247                nodeImportance[i, 0] /= (adjMatrix.Rows - 1);
248                variables.Add(new Tuple<string, double>(rowNames[i], nodeImportance[i, 0]));
249            }
250
251            variables.Sort((b, a) => a.Item2.CompareTo(b.Item2));
252
253            for (int i = 0; i < nodeImportance.Rows; ++i)
254            {
255                nodeImportance[i, 0] = variables[i].Item2;
256                rowNames[i] = variables[i].Item1;
257            }
258
259            nodeImportance.RowNames = rowNames;
260            nodeImportance.ColumnNames = new[] { "Node Importance" };
261            return nodeImportance;
262        }
263
264        //adapted from RunCollectionVariableImpactView
265        private DoubleMatrix CalculateVariableImpactMatrix(IRun[] runs, string[] runNames)
266        {
267            IEnumerable<DoubleMatrix> allVariableImpacts = (from run in runs
268                                                            select run.Results[variableImpactResultName]).Cast<DoubleMatrix>();
269            IEnumerable<string> variableNames = (from variableImpact in allVariableImpacts
270                                                 from variableName in variableImpact.RowNames
271                                                 select variableName).Distinct();
272
273            // filter variableNames: only include names that have at least one non-zero value in a run
274            List<string> variableNamesList = (from variableName in variableNames
275                                              where GetVariableImpacts(variableName, allVariableImpacts).Any(x => !x.IsAlmost(0.0))
276                                              select variableName).ToList();
277
278            List<string> columnNames = new List<string>(runNames);
279            columnNames.Add("Mean");
280
281            int numberOfRuns = runs.Length;
282
283            DoubleMatrix matrix = new DoubleMatrix(variableNamesList.Count, numberOfRuns + 1);
284            matrix.SortableView = true;
285            matrix.ColumnNames = columnNames;
286
287            List<List<double>> variableImpactsOverRuns = (from variableName in variableNamesList
288                                                          select GetVariableImpacts(variableName, allVariableImpacts).ToList()).ToList();
289
290            for (int row = 0; row < variableImpactsOverRuns.Count; row++)
291            {
292                matrix[row, numberOfRuns] = Math.Round(variableImpactsOverRuns[row].Average(), 3);
293            }
294
295            // fill matrix with impacts from runs
296            for (int i = 0; i < runs.Length; i++)
297            {
298                IRun run = runs[i];
299                DoubleMatrix runVariableImpacts = (DoubleMatrix)run.Results[variableImpactResultName];
300                for (int j = 0; j < runVariableImpacts.Rows; j++)
301                {
302                    int rowIndex = variableNamesList.FindIndex(s => s == runVariableImpacts.RowNames.ElementAt(j));
303                    if (rowIndex > -1)
304                    {
305                        matrix[rowIndex, i] = Math.Round(runVariableImpacts[j, 0], 3);
306                    }
307                }
308            }
309            return matrix;
310        }
311
312        //taken from RunCollectionVariableImpactView
313        private IEnumerable<double> GetVariableImpacts(string variableName, IEnumerable<DoubleMatrix> allVariableImpacts)
314        {
315            foreach (DoubleMatrix runVariableImpacts in allVariableImpacts)
316            {
317                int row = 0;
318                foreach (string rowName in runVariableImpacts.RowNames)
319                {
320                    if (rowName == variableName)
321                        yield return runVariableImpacts[row, 0];
322                    row++;
323                }
324            }
325        }
326
327        private void trackBar1_ValueChanged(object sender, EventArgs e)
328        {
329            genThreshold.Text = (0.001 * trackBar1.Value).ToString();
330            textBox1.Text = (0.001 * trackBar1.Minimum).ToString();
331            textBox2.Text = (0.001 * trackBar1.Maximum).ToString();
332            viewHost3.Content = UpdateAdjacencyMatrixByThreshold(0.001 * trackBar1.Value, (DoubleMatrix)viewHost3.Content);
333        }
334
335        private void mouseDownEvent(TrackBar tb, MouseEventArgs e)
336        {
337                double percentage = (double)e.X / (double)(tb.Width - 6);
338                double clickPos = percentage * (tb.Maximum - tb.Minimum);
339                try
340                {
341                    tb.Value = (int)clickPos + tb.Minimum;
342                }
343                catch
344                {
345                    MessageBox.Show("Value outside range!");
346                    return;
347                }
348        }
349
350        private void trackBar1_MouseDown(object sender, MouseEventArgs e)
351        {
352            mouseDownEvent(trackBar1, e);
353        }
354
355        private void trackBar2_MouseDown(object sender, MouseEventArgs e)
356        {
357            if (targetVariablesCombo.SelectedIndex < 0)
358            {
359                return;
360            }
361            else
362            {
363                mouseDownEvent(trackBar2, e);
364            }
365        }
366
367        private void trackBar2_ValueChanged(object sender, EventArgs e)
368        {
369            targetThreshold.Text = (0.001 * trackBar2.Value).ToString();
370
371            if (targetVariablesCombo.SelectedIndex < 0)
372            {
373                MessageBox.Show("Please select target variable!");
374                return;
375            }
376            else
377            {
378                string selectedItem = (string)targetVariablesCombo.Items[targetVariablesCombo.SelectedIndex];
379                viewHost3.Content = UpdateAdjacencyMatrixByThresholdAndTargetVariable(0.001 * trackBar2.Value, selectedItem, (DoubleMatrix)viewHost3.Content);
380            }
381        }
382
383        private void genThresholdEvent()
384        {
385            this.errorProvider.SetError(genThreshold, "");
386
387            if (genThreshold.Text != "")
388            {
389                if (Double.Parse(genThreshold.Text) >= GetMinNonNullElement((DoubleMatrix)viewHost1.Content) && Double.Parse(genThreshold.Text) <= ((DoubleMatrix)viewHost1.Content).Max())
390                {
391                    genThreshold.Select(genThreshold.Text.Length, 0);
392                    trackBar1.Value = (int)(1000 * Double.Parse(genThreshold.Text));
393                    viewHost3.Content = UpdateAdjacencyMatrixByThreshold(Double.Parse(genThreshold.Text), (DoubleMatrix)viewHost3.Content);
394                }
395                else
396                {
397                    this.errorProvider.SetError(genThreshold, "Value out of range!");
398                }
399            }
400            else
401            {
402                MessageBox.Show("Please select a threshold!");
403                this.errorProvider.SetError(genThreshold, "");
404                return;
405            }
406        }
407
408        private void genThreshold_TextChanged(object sender, EventArgs e)
409        {
410            genThresholdEvent();
411        }
412
413        private void genThreshold_KeyDown(object sender, KeyEventArgs e)
414        {
415            if (e.KeyCode == Keys.Enter)
416                genThresholdEvent();       
417        }
418
419        private void targetThresholdEvent()
420        {
421            this.errorProvider2.SetError(targetThreshold, "");
422
423            if (targetVariablesCombo.SelectedIndex < 0)
424            {
425                return;
426            }
427            else
428            {
429                string selectedItem = (string)targetVariablesCombo.Items[targetVariablesCombo.SelectedIndex];
430                if (Double.Parse(targetThreshold.Text) >= Double.Parse(textBox3.Text) && Double.Parse(targetThreshold.Text) <= Double.Parse(textBox4.Text))
431                {
432                    trackBar2.Value = (int)(1000 * Double.Parse(targetThreshold.Text));
433                }
434                else
435                {
436                    this.errorProvider2.SetError(targetThreshold, "Value out of range!");
437                    return;
438                }
439            }
440        }
441
442        private void targetThreshold_TextChanged(object sender, EventArgs e)
443        {
444            targetThresholdEvent();
445        }
446
447        private void targetThreshold_KeyDown(object sender, KeyEventArgs e)
448        {
449            if (e.KeyCode == Keys.Enter)
450            {
451                targetThresholdEvent();
452            }
453        }
454
455        private void targetVariablesCombo_Dropdown(object sender, System.EventArgs e)
456        {
457            targetVariablesCombo.Items.Clear();
458            string[] targetVariables = ((DoubleMatrix)viewHost3.Content).RowNames.ToArray();
459            targetVariablesCombo.Items.AddRange(targetVariables);
460        }
461
462        private void targetVariablesCombo_SelectedIndexChanged(object sender, System.EventArgs e)
463        {
464            var targetIndex = targetVariablesCombo.SelectedIndex;
465            string selectedItem = (string)targetVariablesCombo.Items[targetIndex];
466            trackBar2.Minimum = 0;
467            trackBar2.Maximum = (int)(1000 * GetMaxFromRow(targetIndex, (DoubleMatrix)viewHost1.Content));
468            textBox3.Text = trackBar2.Minimum.ToString();
469            textBox4.Text = (0.001 * trackBar2.Maximum).ToString();
470            UpdateAdjacencyMatrixByThresholdAndTargetVariable(0.001 * trackBar2.Value, selectedItem, (DoubleMatrix)viewHost3.Content);
471        }
472    }
473}
Note: See TracBrowser for help on using the repository browser.