source: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs @ 13100

Last change on this file since 13100 was 13100, checked in by gkronber, 6 years ago

#1998: merged changes from the branch to trunk (btw. this branch was difficult to merge back to trunk because of it's specific structure)

File size: 30.6 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.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Optimization;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Problems.DataAnalysis {
32  [StorableClass]
33  [Item("Prognosis Results", "Represents a collection of time series prognosis results.")]
34  public class TimeSeriesPrognosisResults : ResultCollection {
35    #region result names
36    protected const string PrognosisTrainingMeanSquaredErrorResultName = "Mean squared error (training)";
37    protected const string PrognosisTestMeanSquaredErrorResultName = "Mean squared error (test)";
38    protected const string PrognosisTrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
39    protected const string PrognosisTestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
40    protected const string PrognosisTrainingSquaredCorrelationResultName = "Pearson's R² (training)";
41    protected const string PrognosisTestSquaredCorrelationResultName = "Pearson's R² (test)";
42    protected const string PrognosisTrainingRelativeErrorResultName = "Average relative error (training)";
43    protected const string PrognosisTestRelativeErrorResultName = "Average relative error (test)";
44    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
45    protected const string PrognosisTestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
46    protected const string PrognosisTrainingMeanErrorResultName = "Mean error (training)";
47    protected const string PrognosisTestMeanErrorResultName = "Mean error (test)";
48
49    protected const string PrognosisTrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
50    protected const string PrognosisTestDirectionalSymmetryResultName = "Average directional symmetry (test)";
51    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
52    protected const string PrognosisTestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
53    protected const string PrognosisTrainingTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (training)";
54    protected const string PrognosisTestTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (test)";
55    protected const string PrognosisTrainingTheilsUStatisticMeanResultName = "Theil's U2 (mean) (training)";
56    protected const string PrognosisTestTheilsUStatisticMeanResultName = "Theil's U2 (mean) (test)";
57    #endregion
58
59    #region result descriptions
60    protected const string PrognosisTrainingMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the training partition";
61    protected const string PrognosisTestMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the test partition";
62    protected const string PrognosisTrainingMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the training partition";
63    protected const string PrognosisTestMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the test partition";
64    protected const string PrognosisTrainingSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition";
65    protected const string PrognosisTestSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition";
66    protected const string PrognosisTrainingRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the training partition";
67    protected const string PrognosisTestRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the test partition";
68    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the training partition";
69    protected const string PrognosisTestNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the test partition";
70    protected const string PrognosisTrainingMeanErrorResultDescription = "Mean of errors of the model on the training partition";
71    protected const string PrognosisTestMeanErrorResultDescription = "Mean of errors of the model on the test partition";
72
73    protected const string PrognosisTrainingDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the training partition";
74    protected const string PrognosisTestDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the test partition";
75    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the training partition";
76    protected const string PrognosisTestWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the test partition";
77    protected const string PrognosisTrainingTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the training partition";
78    protected const string PrognosisTestTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the test partition";
79    protected const string PrognosisTrainingTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean model) of the forecasts of the model on the training partition";
80    protected const string PrognosisTestTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition";
81    #endregion
82
83    #region result properties
84    //prognosis results for different horizons
85    public double PrognosisTrainingMeanSquaredError {
86      get {
87        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) return double.NaN;
88        return ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value;
89      }
90      private set {
91        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingMeanSquaredErrorResultName, PrognosisTrainingMeanSquaredErrorResultDescription, new DoubleValue()));
92        ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value = value;
93      }
94    }
95
96    public double PrognosisTestMeanSquaredError {
97      get {
98        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) return double.NaN;
99        return ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value;
100      }
101      private set {
102        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) Add(new Result(PrognosisTestMeanSquaredErrorResultName, PrognosisTestMeanSquaredErrorResultDescription, new DoubleValue()));
103        ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value = value;
104      }
105    }
106
107    public double PrognosisTrainingMeanAbsoluteError {
108      get {
109        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) return double.NaN;
110        return ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value;
111      }
112      private set {
113        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTrainingMeanAbsoluteErrorResultName, PrognosisTrainingMeanAbsoluteErrorResultDescription, new DoubleValue()));
114        ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value = value;
115      }
116    }
117
118    public double PrognosisTestMeanAbsoluteError {
119      get {
120        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) return double.NaN;
121        return ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value;
122      }
123      private set {
124        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTestMeanAbsoluteErrorResultName, PrognosisTestMeanAbsoluteErrorResultDescription, new DoubleValue()));
125        ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value = value;
126      }
127    }
128
129    public double PrognosisTrainingRSquared {
130      get {
131        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) return double.NaN;
132        return ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value;
133      }
134      private set {
135        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) Add(new Result(PrognosisTrainingSquaredCorrelationResultName, PrognosisTrainingSquaredCorrelationResultDescription, new DoubleValue()));
136        ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value = value;
137      }
138    }
139
140    public double PrognosisTestRSquared {
141      get {
142        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) return double.NaN;
143        return ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value;
144      }
145      private set {
146        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) Add(new Result(PrognosisTestSquaredCorrelationResultName, PrognosisTestSquaredCorrelationResultDescription, new DoubleValue()));
147        ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value = value;
148      }
149    }
150
151    public double PrognosisTrainingRelativeError {
152      get {
153        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) return double.NaN;
154        return ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value;
155      }
156      private set {
157        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) Add(new Result(PrognosisTrainingRelativeErrorResultName, PrognosisTrainingRelativeErrorResultDescription, new DoubleValue()));
158        ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value = value;
159      }
160    }
161
162    public double PrognosisTestRelativeError {
163      get {
164        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) return double.NaN;
165        return ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value;
166      }
167      private set {
168        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) Add(new Result(PrognosisTestRelativeErrorResultName, PrognosisTestRelativeErrorResultDescription, new DoubleValue()));
169        ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value = value;
170      }
171    }
172
173    public double PrognosisTrainingNormalizedMeanSquaredError {
174      get {
175        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) return double.NaN;
176        return ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value;
177      }
178      private set {
179        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingNormalizedMeanSquaredErrorResultName, PrognosisTrainingNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
180        ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value = value;
181      }
182    }
183
184    public double PrognosisTestNormalizedMeanSquaredError {
185      get {
186        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) return double.NaN;
187        return ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value;
188      }
189      private set {
190        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTestNormalizedMeanSquaredErrorResultName, PrognosisTestNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
191        ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value = value;
192      }
193    }
194
195    public double PrognosisTrainingMeanError {
196      get {
197        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) return double.NaN;
198        return ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value;
199      }
200      private set {
201        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) Add(new Result(PrognosisTrainingMeanErrorResultName, PrognosisTrainingMeanErrorResultDescription, new DoubleValue()));
202        ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value = value;
203      }
204    }
205
206    public double PrognosisTestMeanError {
207      get {
208        if (!ContainsKey(PrognosisTestMeanErrorResultName)) return double.NaN;
209        return ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value;
210      }
211      private set {
212        if (!ContainsKey(PrognosisTestMeanErrorResultName)) Add(new Result(PrognosisTestMeanErrorResultName, PrognosisTestMeanErrorResultDescription, new DoubleValue()));
213        ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value = value;
214      }
215    }
216
217
218    public double PrognosisTrainingDirectionalSymmetry {
219      get {
220        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) return double.NaN;
221        return ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value;
222      }
223      private set {
224        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingDirectionalSymmetryResultName, PrognosisTrainingDirectionalSymmetryResultDescription, new DoubleValue()));
225        ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value = value;
226      }
227    }
228    public double PrognosisTestDirectionalSymmetry {
229      get {
230        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) return double.NaN;
231        return ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value;
232      }
233      private set {
234        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) Add(new Result(PrognosisTestDirectionalSymmetryResultName, PrognosisTestDirectionalSymmetryResultDescription, new DoubleValue()));
235        ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value = value;
236      }
237    }
238    public double PrognosisTrainingWeightedDirectionalSymmetry {
239      get {
240        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) return double.NaN;
241        return ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value;
242      }
243      private set {
244        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingWeightedDirectionalSymmetryResultName, PrognosisTrainingWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
245        ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value = value;
246      }
247    }
248    public double PrognosisTestWeightedDirectionalSymmetry {
249      get {
250        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) return double.NaN;
251        return ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value;
252      }
253      private set {
254        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTestWeightedDirectionalSymmetryResultName, PrognosisTestWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
255        ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value = value;
256      }
257    }
258    public double PrognosisTrainingTheilsUStatisticAR1 {
259      get {
260        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) return double.NaN;
261        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value;
262      }
263      private set {
264        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticAR1ResultName, PrognosisTrainingTheilsUStatisticAR1ResultDescription, new DoubleValue()));
265        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value = value;
266      }
267    }
268    public double PrognosisTestTheilsUStatisticAR1 {
269      get {
270        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) return double.NaN;
271        return ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value;
272      }
273      private set {
274        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTestTheilsUStatisticAR1ResultName, PrognosisTestTheilsUStatisticAR1ResultDescription, new DoubleValue()));
275        ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value = value;
276      }
277    }
278    public double PrognosisTrainingTheilsUStatisticMean {
279      get {
280        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) return double.NaN;
281        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value;
282      }
283      private set {
284        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticMeanResultName, PrognosisTrainingTheilsUStatisticMeanResultDescription, new DoubleValue()));
285        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value = value;
286      }
287    }
288    public double PrognosisTestTheilsUStatisticMean {
289      get {
290        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) return double.NaN;
291        return ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value;
292      }
293      private set {
294        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTestTheilsUStatisticMeanResultName, PrognosisTestTheilsUStatisticMeanResultDescription, new DoubleValue()));
295        ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value = value;
296      }
297    }
298    #endregion
299
300    [Storable]
301    private int trainingHorizon;
302    public int TrainingHorizon {
303      get { return trainingHorizon; }
304      set {
305        if (trainingHorizon != value) {
306          trainingHorizon = value;
307          OnTrainingHorizonChanged();
308        }
309      }
310    }
311
312    [Storable]
313    private int testHorizon;
314    public int TestHorizon {
315      get { return testHorizon; }
316      set {
317        if (testHorizon != value) {
318          testHorizon = value;
319          OnTestHorizonChanged();
320        }
321      }
322    }
323
324    private ITimeSeriesPrognosisSolution solution;
325    [Storable]
326    public ITimeSeriesPrognosisSolution Solution {
327      get { return solution; }
328      private set { solution = value; } //necessary for persistence
329    }
330
331    [StorableConstructor]
332    public TimeSeriesPrognosisResults(bool deserializing) : base(deserializing) { }
333    protected TimeSeriesPrognosisResults(TimeSeriesPrognosisResults original, Cloner cloner)
334      : base(original, cloner) {
335      this.trainingHorizon = original.trainingHorizon;
336      this.testHorizon = original.testHorizon;
337      this.solution = cloner.Clone(original.solution);
338    }
339    public override IDeepCloneable Clone(Cloner cloner) {
340      return new TimeSeriesPrognosisResults(this, cloner);
341    }
342
343    public TimeSeriesPrognosisResults(int trainingHorizon, int testHorizon, ITimeSeriesPrognosisSolution solution)
344      : base() {
345      this.trainingHorizon = trainingHorizon;
346      this.testHorizon = testHorizon;
347      this.solution = solution;
348      CalculateTrainingPrognosisResults();
349      CalculateTestPrognosisResults();
350    }
351
352    #region events
353    public event EventHandler TrainingHorizonChanged;
354    protected virtual void OnTrainingHorizonChanged() {
355      CalculateTrainingPrognosisResults();
356      var handler = TrainingHorizonChanged;
357      if (handler != null) handler(this, EventArgs.Empty);
358    }
359
360    public event EventHandler TestHorizonChanged;
361    protected virtual void OnTestHorizonChanged() {
362      CalculateTestPrognosisResults();
363      var handler = TestHorizonChanged;
364      if (handler != null) handler(this, EventArgs.Empty);
365    }
366    #endregion
367
368    private void CalculateTrainingPrognosisResults() {
369      OnlineCalculatorError errorState;
370      var problemData = Solution.ProblemData;
371      if (!problemData.TrainingIndices.Any()) return;
372      var model = Solution.Model;
373      //mean model
374      double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
375      var meanModel = new ConstantModel(trainingMean);
376
377      //AR1 model
378      double alpha, beta;
379      IEnumerable<double> trainingStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
380      OnlineLinearScalingParameterCalculator.Calculate(problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
381      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(problemData.TargetVariable, new double[] { beta }, alpha);
382
383      var trainingHorizions = problemData.TrainingIndices.Select(r => Math.Min(trainingHorizon, problemData.TrainingPartition.End - r)).ToList();
384      IEnumerable<IEnumerable<double>> trainingTargetValues = problemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
385      IEnumerable<IEnumerable<double>> trainingEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
386      IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
387      IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
388
389      IEnumerable<double> originalTrainingValues = trainingTargetValues.SelectMany(x => x).ToList();
390      IEnumerable<double> estimatedTrainingValues = trainingEstimatedValues.SelectMany(x => x).ToList();
391
392      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
393      PrognosisTrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
394      double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
395      PrognosisTrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
396      double trainingR = OnlinePearsonsRCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
397      PrognosisTrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR*trainingR : double.NaN;
398      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
399      PrognosisTrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
400      double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
401      PrognosisTrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
402      double trainingME = OnlineMeanErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
403      PrognosisTrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
404
405      PrognosisTrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
406      PrognosisTrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingDirectionalSymmetry : 0.0;
407      PrognosisTrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
408      PrognosisTrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingWeightedDirectionalSymmetry : 0.0;
409      PrognosisTrainingTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
410      PrognosisTrainingTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticAR1 : double.PositiveInfinity;
411      PrognosisTrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
412      PrognosisTrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticMean : double.PositiveInfinity;
413    }
414
415    private void CalculateTestPrognosisResults() {
416      OnlineCalculatorError errorState;
417      var problemData = Solution.ProblemData;
418      if (!problemData.TestIndices.Any()) return;
419      var model = Solution.Model;
420      var testHorizions = problemData.TestIndices.Select(r => Math.Min(testHorizon, problemData.TestPartition.End - r)).ToList();
421      IEnumerable<IEnumerable<double>> testTargetValues = problemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
422      IEnumerable<IEnumerable<double>> testEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
423      IEnumerable<double> testStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
424
425      IEnumerable<double> originalTestValues = testTargetValues.SelectMany(x => x).ToList();
426      IEnumerable<double> estimatedTestValues = testEstimatedValues.SelectMany(x => x).ToList();
427
428      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
429      PrognosisTestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
430      double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
431      PrognosisTestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
432      double testR = OnlinePearsonsRCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
433      PrognosisTestRSquared = errorState == OnlineCalculatorError.None ? testR*testR : double.NaN;
434      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
435      PrognosisTestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
436      double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
437      PrognosisTestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
438      double testME = OnlineMeanErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
439      PrognosisTestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
440
441      PrognosisTestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
442      PrognosisTestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestDirectionalSymmetry : 0.0;
443      PrognosisTestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
444      PrognosisTestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestWeightedDirectionalSymmetry : 0.0;
445
446
447      if (problemData.TrainingIndices.Any()) {
448        //mean model
449        double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
450        var meanModel = new ConstantModel(trainingMean);
451
452        //AR1 model
453        double alpha, beta;
454        IEnumerable<double> trainingStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
455        OnlineLinearScalingParameterCalculator.Calculate(problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
456        var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(problemData.TargetVariable, new double[] { beta }, alpha);
457
458        IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
459        IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
460
461        PrognosisTestTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
462        PrognosisTestTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticAR1 : double.PositiveInfinity;
463        PrognosisTestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
464        PrognosisTestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticMean : double.PositiveInfinity;
465      }
466    }
467  }
468}
Note: See TracBrowser for help on using the repository browser.