Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1081: Derived time series classes from regression classes to avoid code duplication.

File size: 15.0 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 : RegressionSolutionBase, ITimeSeriesPrognosisSolution {
33    private const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
34    private const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)";
35    private const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
36    private const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
37    private const string TrainingTheilsUStatisticLastResultName = "Average Theil's U (last) (training)";
38    private const string TestTheilsUStatisticLastResultName = "Average Theil's U (last) (test)";
39    private const string TrainingTheilsUStatisticMeanResultName = "Average Theil's U (mean) (training)";
40    private const string TestTheilsUStatisticMeanResultName = "Average Theil's U (mean) (test)";
41    private const string TrainingTheilsUStatisticMaResultName = "Average Theil's U (moving average) (training)";
42    private const string TestTheilsUStatisticMaResultName = "Average Theil's U (moving average) (test)";
43
44    public new ITimeSeriesPrognosisModel Model {
45      get { return (ITimeSeriesPrognosisModel)base.Model; }
46      protected set { base.Model = value; }
47    }
48
49    public new ITimeSeriesPrognosisProblemData ProblemData {
50      get { return (ITimeSeriesPrognosisProblemData)base.ProblemData; }
51      set { base.ProblemData = value; }
52    }
53
54    [Storable]
55    private int horizon;
56    public int Horizon {
57      get { return horizon; }
58      set {
59        if (horizon != value) {
60          horizon = value;
61          RecalculateResults();
62        }
63      }
64    }
65
66    public abstract IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizon);
67
68    #region Results
69    public double TrainingDirectionalSymmetry {
70      get { return ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value; }
71      private set { ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value = value; }
72    }
73    public double TestDirectionalSymmetry {
74      get { return ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value; }
75      private set { ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value = value; }
76    }
77    public double TrainingWeightedDirectionalSymmetry {
78      get { return ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value; }
79      private set { ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value = value; }
80    }
81    public double TestWeightedDirectionalSymmetry {
82      get { return ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value; }
83      private set { ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value = value; }
84    }
85    public double TrainingTheilsUStatisticLast {
86      get { return ((DoubleValue)this[TrainingTheilsUStatisticLastResultName].Value).Value; }
87      private set { ((DoubleValue)this[TrainingTheilsUStatisticLastResultName].Value).Value = value; }
88    }
89    public double TestTheilsUStatisticLast {
90      get { return ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value; }
91      private set { ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value = value; }
92    }
93    public double TrainingTheilsUStatisticMean {
94      get { return ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value; }
95      private set { ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value = value; }
96    }
97    public double TestTheilsUStatisticMean {
98      get { return ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value; }
99      private set { ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value = value; }
100    }
101    public double TrainingTheilsUStatisticMovingAverage {
102      get { return ((DoubleValue)this[TrainingTheilsUStatisticMaResultName].Value).Value; }
103      private set { ((DoubleValue)this[TrainingTheilsUStatisticMaResultName].Value).Value = value; }
104    }
105    public double TestTheilsUStatisticMovingAverage {
106      get { return ((DoubleValue)this[TestTheilsUStatisticMaResultName].Value).Value; }
107      private set { ((DoubleValue)this[TestTheilsUStatisticMaResultName].Value).Value = value; }
108    }
109    #endregion
110
111    public override IEnumerable<double> EstimatedValues {
112      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
113    }
114    public override IEnumerable<double> EstimatedTrainingValues {
115      get { return GetEstimatedValues(ProblemData.TrainingIndices); }
116    }
117    public override IEnumerable<double> EstimatedTestValues {
118      get { return GetEstimatedValues(ProblemData.TestIndices); }
119    }
120    public override IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
121      return Model.GetEstimatedValues(ProblemData.Dataset, rows);
122    }
123
124    [StorableConstructor]
125    protected TimeSeriesPrognosisSolutionBase(bool deserializing) : base(deserializing) { }
126    protected TimeSeriesPrognosisSolutionBase(TimeSeriesPrognosisSolutionBase original, Cloner cloner)
127      : base(original, cloner) {
128      this.horizon = original.horizon;
129    }
130    protected TimeSeriesPrognosisSolutionBase(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
131      : base(model, problemData) {
132      Add(new Result(TrainingDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the training partition", new DoubleValue()));
133      Add(new Result(TestDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the test partition", new DoubleValue()));
134      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the training partition", new DoubleValue()));
135      Add(new Result(TestWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the test partition", new DoubleValue()));
136      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()));
137      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()));
138      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()));
139      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()));
140      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()));
141      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()));
142      horizon = 1;
143    }
144
145    protected override void RecalculateResults() {
146      base.RecalculateResults();
147      CalculateTimeSeriesResults();
148    }
149
150    private void CalculateTimeSeriesResults() {
151      OnlineCalculatorError errorState;
152      //mean model
153      double trainingMean = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average();
154      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
155
156      //AR1 model
157      double alpha, beta;
158      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
159      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
160      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(alpha, beta, ProblemData.TargetVariable);
161
162      //MA model
163      int movingAverageWindowSize = 10 + horizon;
164      var MovingAverageModel = new TimeSeriesPrognosisMovingAverageModel(movingAverageWindowSize, ProblemData.TargetVariable);
165
166      #region Calculate training quality measures
167      var trainingHorizions = ProblemData.TrainingIndices.Select(r => Math.Min(horizon, ProblemData.TrainingPartition.End - r)).ToList();
168      IEnumerable<IEnumerable<double>> trainingTargetValues = ProblemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
169      IEnumerable<IEnumerable<double>> trainingEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
170      IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions);
171      IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions);
172      IEnumerable<IEnumerable<double>> trainingMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions);
173
174      TrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
175      TrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingDirectionalSymmetry : 0.0;
176      TrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
177      TrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingWeightedDirectionalSymmetry : 0.0;
178      TrainingTheilsUStatisticLast = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
179      TrainingTheilsUStatisticLast = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticLast : double.PositiveInfinity; ;
180      TrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
181      TrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMean : double.PositiveInfinity; ;
182      TrainingTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMovingAverageModelPredictions, trainingEstimatedValues, out errorState);
183      TrainingTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMovingAverage : double.PositiveInfinity; ; ;
184      #endregion
185
186      #region  Calculate test quality measures
187      var testHorizions = ProblemData.TestIndices.Select(r => Math.Min(horizon, ProblemData.TestPartition.End - r)).ToList();
188      IEnumerable<IEnumerable<double>> testTargetValues = ProblemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
189      IEnumerable<IEnumerable<double>> testEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
190      IEnumerable<double> testStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
191      IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions);
192      IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions);
193      IEnumerable<IEnumerable<double>> testMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions);
194
195      TestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
196      TestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestDirectionalSymmetry : 0.0;
197      TestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
198      TestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestWeightedDirectionalSymmetry : 0.0;
199      TestTheilsUStatisticLast = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
200      TestTheilsUStatisticLast = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticLast : double.PositiveInfinity; ;
201      TestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
202      TestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMean : double.PositiveInfinity; ;
203      TestTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMovingAverageModelPredictions, testEstimatedValues, out errorState);
204      TestTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMovingAverage : double.PositiveInfinity; ; ;
205      #endregion
206    }
207  }
208}
Note: See TracBrowser for help on using the repository browser.