Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.cs @ 8863

Last change on this file since 8863 was 8863, checked in by sforsten, 11 years ago

#1776:

  • merged r8810:8862 from trunk into branch
  • fixed exception in ClassificationEnsembleSolutionAccuracyToCoveredSamples, if no estimated values are in a partition, so nothing can be shown
File size: 10.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Linq;
26using HeuristicLab.PluginInfrastructure;
27
28namespace HeuristicLab.Problems.DataAnalysis.Views {
29  [NonDiscoverableType]
30  public class FeatureCorrelationCalculator : Object {
31
32    private BackgroundWorker bw;
33    private BackgroundWorkerInfo bwInfo;
34
35    private IDataAnalysisProblemData problemData;
36    public IDataAnalysisProblemData ProblemData {
37      set {
38        if (bw != null) {
39          bw.CancelAsync();
40        }
41        problemData = value;
42      }
43    }
44
45    public FeatureCorrelationCalculator()
46      : base() { }
47
48    public FeatureCorrelationCalculator(IDataAnalysisProblemData problemData)
49      : base() {
50      this.problemData = problemData;
51    }
52
53    public void CalculateElements(IDependencyCalculator calc, string partition) {
54      CalculateElements(problemData.Dataset, calc, partition);
55    }
56
57    // returns true if any calculation takes place
58    public bool CalculateTimeframeElements(IDependencyCalculator calc, string partition, string variable, int frames, double[,] correlation = null) {
59      if (correlation == null || correlation.GetLength(1) <= frames) {
60        CalculateElements(problemData.Dataset, calc, partition, variable, frames, correlation);
61        return true;
62      } else {
63        return false;
64      }
65    }
66
67    public void TryCancelCalculation() {
68      if (bw != null && bw.IsBusy) {
69        bwInfo = null;
70        bw.CancelAsync();
71      }
72    }
73
74    private double[,] GetElementsOfCorrelation(double[,] corr, int frames) {
75      double[,] elements = new double[corr.GetLength(0), frames + 1];
76      for (int i = 0; i < corr.GetLength(0); i++) {
77        for (int j = 0; j <= frames; j++) {
78          elements[i, j] = corr[i, j];
79        }
80      }
81      return elements;
82    }
83
84    private void CalculateElements(Dataset dataset, IDependencyCalculator calc, string partition, string variable = null, int frames = 0, double[,] alreadyCalculated = null) {
85      bwInfo = new BackgroundWorkerInfo { Dataset = dataset, Calculator = calc, Partition = partition, Variable = variable, Frames = frames, AlreadyCalculated = alreadyCalculated };
86      if (bw == null) {
87        bw = new BackgroundWorker();
88        bw.WorkerReportsProgress = true;
89        bw.WorkerSupportsCancellation = true;
90        bw.DoWork += new DoWorkEventHandler(BwDoWork);
91        bw.ProgressChanged += new ProgressChangedEventHandler(BwProgressChanged);
92        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BwRunWorkerCompleted);
93      }
94      if (bw.IsBusy) {
95        bw.CancelAsync();
96      } else {
97        bw.RunWorkerAsync(bwInfo);
98      }
99    }
100
101    #region backgroundworker
102    private void BwDoWork(object sender, DoWorkEventArgs e) {
103      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
104      if (bwInfo.Variable == null) {
105        BwCalculateCorrelation(sender, e);
106      } else {
107        BwCalculateTimeframeCorrelation(sender, e);
108      }
109    }
110
111    private void BwCalculateCorrelation(object sender, DoWorkEventArgs e) {
112      BackgroundWorker worker = sender as BackgroundWorker;
113
114      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
115      Dataset dataset = bwInfo.Dataset;
116      string partition = bwInfo.Partition;
117      IDependencyCalculator calc = bwInfo.Calculator;
118
119      IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();
120      OnlineCalculatorError error = OnlineCalculatorError.None;
121      int length = doubleVariableNames.Count;
122      double[,] elements = new double[length, length];
123      double calculations = (Math.Pow(length, 2) + length) / 2;
124
125      worker.ReportProgress(0);
126
127      for (int i = 0; i < length; i++) {
128        for (int j = 0; j < i + 1; j++) {
129          if (worker.CancellationPending) {
130            worker.ReportProgress(100);
131            e.Cancel = true;
132            return;
133          }
134          IEnumerable<double> var1 = GetRelevantValues(problemData, partition, doubleVariableNames[i]);
135          IEnumerable<double> var2 = GetRelevantValues(problemData, partition, doubleVariableNames[j]);
136
137          elements[i, j] = calc.Calculate(var1, var2, out error);
138
139          if (!error.Equals(OnlineCalculatorError.None)) {
140            elements[i, j] = double.NaN;
141          }
142          elements[j, i] = elements[i, j];
143          worker.ReportProgress((int)Math.Round((((Math.Pow(i, 2) + i) / 2 + j + 1.0) / calculations) * 100));
144        }
145      }
146      e.Result = elements;
147      worker.ReportProgress(100);
148    }
149
150    private void BwCalculateTimeframeCorrelation(object sender, DoWorkEventArgs e) {
151      BackgroundWorker worker = sender as BackgroundWorker;
152
153      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
154      Dataset dataset = bwInfo.Dataset;
155      string partition = bwInfo.Partition;
156      IDependencyCalculator calc = bwInfo.Calculator;
157      string variable = bwInfo.Variable;
158      int frames = bwInfo.Frames;
159      double[,] alreadyCalculated = bwInfo.AlreadyCalculated;
160
161      IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();
162      OnlineCalculatorError error = OnlineCalculatorError.None;
163      int length = doubleVariableNames.Count;
164      double[,] elements = new double[length, frames + 1];
165      double calculations = (frames + 1) * length;
166
167      worker.ReportProgress(0);
168
169      int start = 0;
170      if (alreadyCalculated != null) {
171        for (int i = 0; i < alreadyCalculated.GetLength(0); i++) {
172          Array.Copy(alreadyCalculated, i * alreadyCalculated.GetLength(1), elements, i * elements.GetLength(1), alreadyCalculated.GetLength(1));
173        }
174        start = alreadyCalculated.GetLength(1);
175      }
176
177      for (int i = 0; i < length; i++) {
178        for (int j = start; j <= frames; j++) {
179          if (worker.CancellationPending) {
180            worker.ReportProgress(100);
181            e.Cancel = true;
182            return;
183          }
184
185          IEnumerable<double> var1 = GetRelevantValues(problemData, partition, variable);
186          IEnumerable<double> var2 = GetRelevantValues(problemData, partition, doubleVariableNames[i]);
187
188          var valuesInFrame = var1.Take(j);
189          var help = var1.Skip(j).ToList();
190          help.AddRange(valuesInFrame);
191          var1 = help;
192
193          elements[i, j] = calc.Calculate(var1, var2, out error);
194
195          if (!error.Equals(OnlineCalculatorError.None)) {
196            elements[i, j] = double.NaN;
197          }
198          worker.ReportProgress((int)((100.0 / calculations) * (i * (frames + 1) + j + 1)));
199        }
200      }
201      e.Result = elements;
202      worker.ReportProgress(100);
203    }
204
205    private IEnumerable<double> GetRelevantValues(IDataAnalysisProblemData problemData, string partition, string variable) {
206      IEnumerable<double> var = problemData.Dataset.GetDoubleValues(variable);
207      if (partition.Equals(FeatureCorrelationPartitions.TRAININGSAMPLES)) {
208        var = var.Skip(problemData.TrainingPartition.Start).Take(problemData.TrainingPartition.End - problemData.TrainingPartition.Start);
209      } else if (partition.Equals(FeatureCorrelationPartitions.TESTSAMPLES)) {
210        var = var.Skip(problemData.TestPartition.Start).Take(problemData.TestPartition.End - problemData.TestPartition.Start);
211      }
212      return var;
213    }
214
215    private void BwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
216      BackgroundWorker worker = sender as BackgroundWorker;
217      if (!e.Cancelled && !worker.CancellationPending) {
218        if (!(e.Error == null)) {
219          ErrorHandling.ShowErrorDialog(e.Error);
220        } else {
221          OnCorrelationCalculationFinished((double[,])e.Result, bwInfo.Calculator, bwInfo.Partition, bwInfo.Variable);
222        }
223      } else if (bwInfo != null) {
224        bw.RunWorkerAsync(bwInfo);
225      }
226    }
227    #endregion
228
229    #region events
230    public class CorrelationCalculationFinishedArgs : EventArgs {
231      public double[,] Correlation { get; private set; }
232      public IDependencyCalculator Calculcator { get; private set; }
233      public string Partition { get; private set; }
234      public string Variable { get; private set; }
235
236      public CorrelationCalculationFinishedArgs(double[,] correlation, IDependencyCalculator calculator, string partition, string variable = null) {
237        this.Correlation = correlation;
238        this.Calculcator = calculator;
239        this.Partition = partition;
240        this.Variable = variable;
241      }
242    }
243
244    public delegate void CorrelationCalculationFinishedHandler(object sender, CorrelationCalculationFinishedArgs e);
245    public event CorrelationCalculationFinishedHandler CorrelationCalculationFinished;
246    protected virtual void OnCorrelationCalculationFinished(double[,] correlation, IDependencyCalculator calculator, string partition, string variable = null) {
247      var handler = CorrelationCalculationFinished;
248      if (handler != null)
249        handler(this, new CorrelationCalculationFinishedArgs(correlation, calculator, partition, variable));
250    }
251
252    public delegate void ProgressCalculationHandler(object sender, ProgressChangedEventArgs e);
253    public event ProgressCalculationHandler ProgressCalculation;
254    protected void BwProgressChanged(object sender, ProgressChangedEventArgs e) {
255      BackgroundWorker worker = sender as BackgroundWorker;
256      if (ProgressCalculation != null) {
257        ProgressCalculation(sender, e);
258      }
259    }
260    #endregion
261
262    private class BackgroundWorkerInfo {
263      public Dataset Dataset { get; set; }
264      public IDependencyCalculator Calculator { get; set; }
265      public string Partition { get; set; }
266      public string Variable { get; set; }
267      public int Frames { get; set; }
268      public double[,] AlreadyCalculated { get; set; }
269    }
270  }
271}
Note: See TracBrowser for help on using the repository browser.