Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs @ 8010

Last change on this file since 8010 was 8010, checked in by mkommend, 12 years ago

#1081: Corrected time series solution results and implemented new models.

File size: 22.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Data;
27using HeuristicLab.Optimization;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Problems.DataAnalysis {
31  [StorableClass]
32  public abstract class TimeSeriesPrognosisSolutionBase : DataAnalysisSolution, ITimeSeriesPrognosisSolution {
33    private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
34    private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
35    private const string TrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
36    private const string TestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
37    private const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
38    private const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
39    private const string TrainingRelativeErrorResultName = "Average relative error (training)";
40    private const string TestRelativeErrorResultName = "Average relative error (test)";
41    private const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
42    private const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
43    private const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
44    private const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)";
45    private const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
46    private const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
47    private const string TrainingTheilsUStatisticLastResultName = "Average Theil's U (last) (training)";
48    private const string TestTheilsUStatisticLastResultName = "Average Theil's U (last) (test)";
49    private const string TrainingTheilsUStatisticMeanResultName = "Average Theil's U (mean) (training)";
50    private const string TestTheilsUStatisticMeanResultName = "Average Theil's U (mean) (test)";
51    private const string TrainingTheilsUStatisticMaResultName = "Average Theil's U (moving average) (training)";
52    private const string TestTheilsUStatisticMaResultName = "Average Theil's U (moving average) (test)";
53
54    public new ITimeSeriesPrognosisModel Model {
55      get { return (ITimeSeriesPrognosisModel)base.Model; }
56      protected set { base.Model = value; }
57    }
58
59    public new ITimeSeriesPrognosisProblemData ProblemData {
60      get { return (ITimeSeriesPrognosisProblemData)base.ProblemData; }
61      set { base.ProblemData = value; }
62    }
63
64    [Storable]
65    private int horizon;
66    public int Horizon {
67      get { return horizon; }
68      set {
69        if (horizon != value) {
70          horizon = value;
71          RecalculateResults();
72        }
73      }
74    }
75
76    public abstract IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizon);
77
78    #region Results
79    public double TrainingMeanSquaredError {
80      get { return ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value; }
81      private set { ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value = value; }
82    }
83    public double TestMeanSquaredError {
84      get { return ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value; }
85      private set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
86    }
87    public double TrainingMeanAbsoluteError {
88      get { return ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value; }
89      private set { ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value = value; }
90    }
91    public double TestMeanAbsoluteError {
92      get { return ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value; }
93      private set { ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value = value; }
94    }
95    public double TrainingRSquared {
96      get { return ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value; }
97      private set { ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value = value; }
98    }
99    public double TestRSquared {
100      get { return ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value; }
101      private set { ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value = value; }
102    }
103    public double TrainingRelativeError {
104      get { return ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value; }
105      private set { ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value = value; }
106    }
107    public double TestRelativeError {
108      get { return ((DoubleValue)this[TestRelativeErrorResultName].Value).Value; }
109      private set { ((DoubleValue)this[TestRelativeErrorResultName].Value).Value = value; }
110    }
111    public double TrainingNormalizedMeanSquaredError {
112      get { return ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value; }
113      private set { ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value = value; }
114    }
115    public double TestNormalizedMeanSquaredError {
116      get { return ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value; }
117      private set { ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value = value; }
118    }
119    public double TrainingDirectionalSymmetry {
120      get { return ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value; }
121      private set { ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value = value; }
122    }
123    public double TestDirectionalSymmetry {
124      get { return ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value; }
125      private set { ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value = value; }
126    }
127    public double TrainingWeightedDirectionalSymmetry {
128      get { return ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value; }
129      private set { ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value = value; }
130    }
131    public double TestWeightedDirectionalSymmetry {
132      get { return ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value; }
133      private set { ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value = value; }
134    }
135    public double TrainingTheilsUStatisticLast {
136      get { return ((DoubleValue)this[TrainingTheilsUStatisticLastResultName].Value).Value; }
137      private set { ((DoubleValue)this[TrainingTheilsUStatisticLastResultName].Value).Value = value; }
138    }
139    public double TestTheilsUStatisticLast {
140      get { return ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value; }
141      private set { ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value = value; }
142    }
143    public double TrainingTheilsUStatisticMean {
144      get { return ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value; }
145      private set { ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value = value; }
146    }
147    public double TestTheilsUStatisticMean {
148      get { return ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value; }
149      private set { ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value = value; }
150    }
151    public double TrainingTheilsUStatisticMovingAverage {
152      get { return ((DoubleValue)this[TrainingTheilsUStatisticMaResultName].Value).Value; }
153      private set { ((DoubleValue)this[TrainingTheilsUStatisticMaResultName].Value).Value = value; }
154    }
155    public double TestTheilsUStatisticMovingAverage {
156      get { return ((DoubleValue)this[TestTheilsUStatisticMaResultName].Value).Value; }
157      private set { ((DoubleValue)this[TestTheilsUStatisticMaResultName].Value).Value = value; }
158    }
159    #endregion
160
161    [StorableConstructor]
162    protected TimeSeriesPrognosisSolutionBase(bool deserializing) : base(deserializing) { }
163    protected TimeSeriesPrognosisSolutionBase(TimeSeriesPrognosisSolutionBase original, Cloner cloner)
164      : base(original, cloner) {
165      this.horizon = original.horizon;
166    }
167    protected TimeSeriesPrognosisSolutionBase(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
168      : base(model, problemData) {
169      Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleValue()));
170      Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleValue()));
171      Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
172      Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
173      Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
174      Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
175      Add(new Result(TrainingRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the training partition", new DoubleValue()));
176      Add(new Result(TestRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the test partition", new DoubleValue()));
177      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleValue()));
178      Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleValue()));
179      Add(new Result(TrainingDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the training partition", new DoubleValue()));
180      Add(new Result(TestDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the test partition", new DoubleValue()));
181      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the training partition", new DoubleValue()));
182      Add(new Result(TestWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the test partition", new DoubleValue()));
183      Add(new Result(TrainingTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the training partition", new DoubleValue()));
184      Add(new Result(TestTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the test partition", new DoubleValue()));
185      Add(new Result(TrainingTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the training partition", new DoubleValue()));
186      Add(new Result(TestTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition", new DoubleValue()));
187      Add(new Result(TrainingTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the training partition", new DoubleValue()));
188      Add(new Result(TestTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the test partition", new DoubleValue()));
189      horizon = 1;
190    }
191
192
193    protected void CalculateResults() {
194      OnlineCalculatorError errorState;
195      //mean model
196      double trainingMean = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes).Average();
197      var meanModel = new TimeSeriesPrognosisConstantModel(trainingMean);
198
199      //AR1 model
200      double alpha, beta;
201      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes.Select(r => r - 1).Where(r => r > 0)).ToList();
202      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
203      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(alpha, beta, ProblemData.TargetVariable);
204
205      //MA model
206      int movingAverageWindowSize = 10 + horizon;
207      var MovingAverageModel = new TimeSeriesPrognosisMovingAverageModel(movingAverageWindowSize, ProblemData.TargetVariable);
208
209      #region Calculate training quality measures
210      var trainingHorizions = ProblemData.TrainingIndizes.Select(r => Math.Min(horizon, ProblemData.TrainingPartition.End - r)).ToList();
211      IEnumerable<IEnumerable<double>> trainingTargetValues = ProblemData.TrainingIndizes.Zip(trainingHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
212      IEnumerable<IEnumerable<double>> trainingEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndizes, trainingHorizions).ToList();
213
214      TrainingMeanSquaredError = OnlineMeanSquaredErrorCalculator.Calculate(trainingTargetValues.SelectMany(x => x), trainingEstimatedValues.SelectMany(x => x), out errorState);
215      TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? TrainingMeanSquaredError : double.PositiveInfinity;
216      TrainingMeanAbsoluteError = OnlineMeanAbsoluteErrorCalculator.Calculate(trainingTargetValues.SelectMany(x => x), trainingEstimatedValues.SelectMany(x => x), out errorState);
217      TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? TrainingMeanAbsoluteError : double.PositiveInfinity;
218      TrainingRelativeError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(trainingTargetValues.SelectMany(x => x), trainingEstimatedValues.SelectMany(x => x), out errorState);
219      TrainingRelativeError = errorState == OnlineCalculatorError.None ? TrainingRelativeError : double.PositiveInfinity;
220      TrainingRSquared = OnlinePearsonsRSquaredCalculator.Calculate(trainingTargetValues.SelectMany(x => x), trainingEstimatedValues.SelectMany(x => x), out errorState);
221      TrainingRSquared = errorState == OnlineCalculatorError.None ? TrainingRSquared : 0.0;
222      TrainingNormalizedMeanSquaredError = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(trainingTargetValues.SelectMany(x => x), trainingEstimatedValues.SelectMany(x => x), out errorState);
223      TrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? TrainingNormalizedMeanSquaredError : double.PositiveInfinity;
224
225      IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndizes, trainingHorizions);
226      IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndizes, trainingHorizions);
227      IEnumerable<IEnumerable<double>> trainingMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndizes, trainingHorizions);
228
229      TrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
230      TrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingDirectionalSymmetry : 0.0;
231      TrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
232      TrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingWeightedDirectionalSymmetry : 0.0;
233      TrainingTheilsUStatisticLast = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
234      TrainingTheilsUStatisticLast = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticLast : double.PositiveInfinity; ;
235      TrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
236      TrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMean : double.PositiveInfinity; ;
237      TrainingTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMovingAverageModelPredictions, trainingEstimatedValues, out errorState);
238      TrainingTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMovingAverage : double.PositiveInfinity; ; ;
239      #endregion
240
241      #region  Calculate test quality measures
242      var testHorizions = ProblemData.TestIndizes.Select(r => Math.Min(horizon, ProblemData.TestPartition.End - r)).ToList();
243      IEnumerable<IEnumerable<double>> testTargetValues = ProblemData.TestIndizes.Zip(testHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
244      IEnumerable<IEnumerable<double>> testEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndizes, testHorizions).ToList();
245
246      TestMeanSquaredError = OnlineMeanSquaredErrorCalculator.Calculate(testTargetValues.SelectMany(x => x), testEstimatedValues.SelectMany(x => x), out errorState);
247      TestMeanSquaredError = errorState == OnlineCalculatorError.None ? TestMeanSquaredError : double.PositiveInfinity;
248      TestMeanAbsoluteError = OnlineMeanAbsoluteErrorCalculator.Calculate(testTargetValues.SelectMany(x => x), testEstimatedValues.SelectMany(x => x), out errorState);
249      TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? TestMeanAbsoluteError : double.PositiveInfinity;
250      TestRelativeError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(testTargetValues.SelectMany(x => x), testEstimatedValues.SelectMany(x => x), out errorState);
251      TestRelativeError = errorState == OnlineCalculatorError.None ? TestRelativeError : double.PositiveInfinity;
252      TestRSquared = OnlinePearsonsRSquaredCalculator.Calculate(testTargetValues.SelectMany(x => x), testEstimatedValues.SelectMany(x => x), out errorState);
253      TestRSquared = errorState == OnlineCalculatorError.None ? TestRSquared : 0.0;
254      TestNormalizedMeanSquaredError = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(testTargetValues.SelectMany(x => x), testEstimatedValues.SelectMany(x => x), out errorState);
255      TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? TestNormalizedMeanSquaredError : double.PositiveInfinity;
256
257      IEnumerable<double> testStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndizes.Select(r => r - 1).Where(r => r > 0)).ToList();
258      IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndizes, testHorizions);
259      IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndizes, testHorizions);
260      IEnumerable<IEnumerable<double>> testMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndizes, testHorizions);
261
262      TestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
263      TestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestDirectionalSymmetry : 0.0;
264      TestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
265      TestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestWeightedDirectionalSymmetry : 0.0;
266      TestTheilsUStatisticLast = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
267      TestTheilsUStatisticLast = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticLast : double.PositiveInfinity; ;
268      TestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
269      TestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMean : double.PositiveInfinity; ;
270      TestTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMovingAverageModelPredictions, testEstimatedValues, out errorState);
271      TestTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMovingAverage : double.PositiveInfinity; ; ;
272      #endregion     
273    }
274  }
275}
Note: See TracBrowser for help on using the repository browser.