Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/Evaluators/SymbolicTimeSeriesPrognosisScaledNormalizedFractionalDistanceEvaluator.cs @ 5275

Last change on this file since 5275 was 5275, checked in by gkronber, 13 years ago

Merged changes from trunk to data analysis exploration branch and added fractional distance metric evaluator. #1142

File size: 10.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Linq;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28using HeuristicLab.Problems.DataAnalysis.SupportVectorMachine;
29using HeuristicLab.Problems.DataAnalysis;
30using HeuristicLab.Problems.DataAnalysis.Evaluators;
31using HeuristicLab.Parameters;
32using HeuristicLab.Optimization;
33using HeuristicLab.Operators;
34using HeuristicLab.Problems.DataAnalysis.Regression.Symbolic;
35using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
36using System.Collections.Generic;
37using HeuristicLab.Problems.DataAnalysis.Regression;
38using HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis.Symbolic.Interfaces;
39using HeuristicLab.Problems.DataAnalysis.MultiVariate.Evaluators;
40
41namespace HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis.Symbolic.Evaluators {
42  [Item("SymbolicTimeSeriesPrognosisScaledNormalizedFractionalDistanceEvaluator", "")]
43  [StorableClass]
44  public class SymbolicTimeSeriesPrognosisScaledNormalizedFractionalDistanceEvaluator : SymbolicTimeSeriesPrognosisEvaluator {
45    public ValueParameter<DoubleValue> DimensionParameter {
46      get { return (ValueParameter<DoubleValue>)Parameters["Dimension"]; }
47    }
48    public DoubleValue Dimension {
49      get { return DimensionParameter.Value; }
50      set { DimensionParameter.Value = value; }
51    }
52    [StorableConstructor]
53    protected SymbolicTimeSeriesPrognosisScaledNormalizedFractionalDistanceEvaluator(bool deserializing) : base(deserializing) { }
54    protected SymbolicTimeSeriesPrognosisScaledNormalizedFractionalDistanceEvaluator(SymbolicTimeSeriesPrognosisScaledNormalizedFractionalDistanceEvaluator original, Cloner cloner)
55      : base(original, cloner) {
56    }
57    public SymbolicTimeSeriesPrognosisScaledNormalizedFractionalDistanceEvaluator()
58      : base() {
59        Parameters.Add(new ValueParameter<DoubleValue>("Dimension", "The dimension parameter for the fractional distance metric (Sum(x_i-y_i)^(1/d))^d). d=0.5 is equivalent to Euclidian distance.", new DoubleValue(0.5)));
60    }
61    public override IDeepCloneable Clone(Cloner cloner) {
62      return new SymbolicTimeSeriesPrognosisScaledNormalizedFractionalDistanceEvaluator(this, cloner);
63    }
64    public override double Evaluate(SymbolicExpressionTree tree, MultiVariateDataAnalysisProblemData problemData, ISymbolicTimeSeriesExpressionInterpreter interpreter, IEnumerable<int> rows, int predictionHorizon, DoubleArray lowerEstimationLimit, DoubleArray upperEstimationLimit) {
65      return Calculate(tree, problemData, interpreter, rows, predictionHorizon, Dimension.Value, lowerEstimationLimit, upperEstimationLimit);
66    }
67
68    public static double Calculate(SymbolicExpressionTree tree, MultiVariateDataAnalysisProblemData problemData, ISymbolicTimeSeriesExpressionInterpreter interpreter, IEnumerable<int> rows, int predictionHorizon, double fractionalDimension, DoubleArray lowerEstimationLimit, DoubleArray upperEstimationLimit) {
69      double[] alpha, beta;
70      double quality;
71
72      Dataset dataset = problemData.Dataset;
73      // calculate scaling parameters based on one-step-predictions
74      IEnumerable<string> selectedTargetVariables = (from item in problemData.TargetVariables
75                                                     where problemData.TargetVariables.ItemChecked(item)
76                                                     select item.Value).ToArray();
77      int dimension = selectedTargetVariables.Count();
78
79      IEnumerable<int> selectedTargetVariableIndexes = (from targetVariable in selectedTargetVariables
80                                                        select dataset.GetVariableIndex(targetVariable)).ToArray();
81      IEnumerable<IEnumerable<double>> oneStepPredictions =
82        interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, selectedTargetVariables, rows, 1).Cast<IEnumerable<double>>();
83      IEnumerable<IEnumerable<double>> originalValues = from row in rows
84                                                        select (from targetVariableIndex in selectedTargetVariableIndexes
85                                                                select dataset[row, targetVariableIndex]);
86      alpha = new double[dimension];
87      beta = new double[dimension];
88
89      CalculateScalingParameters(originalValues, oneStepPredictions, ref beta, ref alpha);
90
91      // calculate the quality for the full horizon
92      quality = CalculateWithScaling(tree, problemData, interpreter,
93        rows, predictionHorizon, fractionalDimension,
94        lowerEstimationLimit, upperEstimationLimit,
95        beta, alpha);
96      return quality;
97    }
98
99    public static double CalculateWithScaling(SymbolicExpressionTree tree, MultiVariateDataAnalysisProblemData problemData,
100      ISymbolicTimeSeriesExpressionInterpreter interpreter,
101      IEnumerable<int> rows, int predictionHorizon, double fractionalDimension,
102      DoubleArray lowerEstimationLimit, DoubleArray upperEstimationLimit,
103      double[] beta, double[] alpha) {
104      Dataset dataset = problemData.Dataset;
105      IEnumerable<string> selectedTargetVariables = (from targetVariable in problemData.TargetVariables
106                                                     where problemData.TargetVariables.ItemChecked(targetVariable)
107                                                     select targetVariable.Value).ToArray();
108      IEnumerable<int> selectedTargetVariableIndexes = (from targetVariable in selectedTargetVariables
109                                                        select dataset.GetVariableIndex(targetVariable)).ToArray();
110
111      IEnumerable<double[]> estimatedValues =
112        interpreter.GetScaledSymbolicExpressionTreeValues(tree, dataset, selectedTargetVariables,
113        rows, predictionHorizon, beta, alpha);
114
115      IEnumerable<IEnumerable<double>> originalValues = from row in rows
116                                                        from step in Enumerable.Range(0, predictionHorizon)
117                                                        select (from targetVariableIndex in selectedTargetVariableIndexes
118                                                                select dataset[row + step, targetVariableIndex]);
119
120      var evaluator = new OnlineMeanFractionalDistanceEvaluator(fractionalDimension);
121
122      var estimatedValuesEnumerator = estimatedValues.GetEnumerator();
123      var originalValuesEnumerator = originalValues.GetEnumerator();
124      while (originalValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) {
125        IEnumerable<double> original = originalValuesEnumerator.Current;
126        double[] estimated = estimatedValuesEnumerator.Current;
127        for (int i = 0; i < estimated.Length; i++) {
128          if (double.IsNaN(estimated[i])) estimated[i] = upperEstimationLimit[i];
129          else estimated[i] = Math.Min(upperEstimationLimit[i], Math.Max(lowerEstimationLimit[i], estimated[i]));
130        }
131        evaluator.Add(original, estimated);
132      }
133
134      double quality = evaluator.Value;
135      return quality;
136    }
137
138    public static void CalculateScalingParameters(IEnumerable<IEnumerable<double>> originalValues, IEnumerable<IEnumerable<double>> estimatedValues, ref double[] beta, ref double[] alpha) {
139      List<OnlineLinearScalingCalculator> linearScalingCalculators = new List<OnlineLinearScalingCalculator>();
140      // initialize lists
141      int dimension = originalValues.First().Count();
142      for (int i = 0; i < dimension; i++) {
143        linearScalingCalculators.Add(new OnlineLinearScalingCalculator());
144      }
145
146      var estimatedEnumerator = estimatedValues.GetEnumerator();
147      var originalEnumerator = originalValues.GetEnumerator();
148      // foreach row vector in both series
149      while (estimatedEnumerator.MoveNext() & originalEnumerator.MoveNext()) {
150        IEnumerable<double> original = originalEnumerator.Current;
151        IEnumerable<double> estimated = estimatedEnumerator.Current;
152        var originalComponentValuesEnumerator = original.GetEnumerator();
153        var estimatedComponentValuesEnumerator = estimated.GetEnumerator();
154
155        int component = 0;
156        // for each component in both row vectors
157        while (originalComponentValuesEnumerator.MoveNext() & estimatedComponentValuesEnumerator.MoveNext() && component < dimension) {
158          if (IsValidValue(originalComponentValuesEnumerator.Current) && IsValidValue(estimatedComponentValuesEnumerator.Current)) {
159            linearScalingCalculators[component].Add(originalComponentValuesEnumerator.Current, estimatedComponentValuesEnumerator.Current);
160          }
161          component++;
162        }
163        // check if both row vectors are finished
164        if (originalComponentValuesEnumerator.MoveNext() | estimatedComponentValuesEnumerator.MoveNext() || component < dimension) {
165          throw new ArgumentException("Number of elements in original and estimated row vectors does not match.");
166        }
167      }
168
169      // check if both series are finished
170      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())
171        throw new InvalidOperationException("Number of elements in estimated and original series doesn't match.");
172
173      // get alpha and beta for each component
174      for (int component = 0; component < dimension; component++) {
175        alpha[component] = linearScalingCalculators[component].Alpha;
176        beta[component] = linearScalingCalculators[component].Beta;
177      }
178    }
179
180    private static bool IsValidValue(double d) {
181      return !double.IsInfinity(d) && !double.IsNaN(d) && d > -1.0E07 && d < 1.0E07;  // don't consider very large or very small values for scaling
182    }
183  }
184}
Note: See TracBrowser for help on using the repository browser.