Changeset 6974
- Timestamp:
- 11/09/11 10:59:31 (13 years ago)
- Location:
- trunk/sources
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
r6913 r6974 143 143 <Compile Include="Interfaces\Regression\IRegressionEnsembleSolution.cs" /> 144 144 <Compile Include="Implementation\Regression\RegressionSolutionBase.cs" /> 145 <Compile Include="Interfaces\TimeSeriesPrognosis\IOnlineTimeSeriesCalculator.cs" /> 145 146 <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisModel.cs" /> 146 147 <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisProblem.cs" /> -
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
r6961 r6974 40 40 private const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)"; 41 41 private const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)"; 42 private const string TrainingDirectionalSymmetryResultName = " Directional symmetry (training)";43 private const string TestDirectionalSymmetryResultName = " Directional symmetry (test)";44 private const string TrainingWeightedDirectionalSymmetryResultName = " Weighted directional symmetry (training)";45 private const string TestWeightedDirectionalSymmetryResultName = " Weighted directional symmetry (test)";46 private const string TrainingTheilsUStatisticResultName = " Theil's U (training)";47 private const string TestTheilsUStatisticResultName = " Theil's U (test)";42 private const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)"; 43 private const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)"; 44 private const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)"; 45 private const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)"; 46 private const string TrainingTheilsUStatisticResultName = "Average Theil's U (training)"; 47 private const string TestTheilsUStatisticResultName = "Average Theil's U (test)"; 48 48 49 49 public new ITimeSeriesPrognosisModel Model { … … 146 146 Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleValue())); 147 147 Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleValue())); 148 Add(new Result(TrainingDirectionalSymmetryResultName, "The directional symmetry of the output of the model on the training partition", new DoubleValue()));149 Add(new Result(TestDirectionalSymmetryResultName, "The directional symmetry of the output of the model on the test partition", new DoubleValue()));150 Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The weighted directional symmetry of the outputof the model on the training partition", new DoubleValue()));151 Add(new Result(TestWeightedDirectionalSymmetryResultName, "The weighted directional symmetry of the outputof the model on the test partition", new DoubleValue()));152 Add(new Result(TrainingTheilsUStatisticResultName, "The Theil's U statistic of the outputof the model on the training partition", new DoubleValue()));153 Add(new Result(TestTheilsUStatisticResultName, "The Theil's U statistic of the outputof the model on the test partition", new DoubleValue()));148 Add(new Result(TrainingDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the training partition", new PercentValue())); 149 Add(new Result(TestDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the test partition", new PercentValue())); 150 Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the training partition", new DoubleValue())); 151 Add(new Result(TestWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the test partition", new DoubleValue())); 152 Add(new Result(TrainingTheilsUStatisticResultName, "The average Theil's U statistic of the forecasts of the model on the training partition", new DoubleValue())); 153 Add(new Result(TestTheilsUStatisticResultName, "The average Theil's U statistic of the forecasts of the model on the test partition", new DoubleValue())); 154 154 } 155 155 … … 191 191 TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNmse : double.NaN; 192 192 193 double trainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState); 193 var startTrainingValues = originalTrainingValues; 194 // each continuation is only one element long 195 var actualContinuationsTraining = from x in originalTrainingValues.Skip(1) 196 select Enumerable.Repeat(x, 1); 197 // each forecast is only one elemnt long 198 // disregards the first estimated value (we could include this again by extending the list of original values by one step to the left 199 // this is the easier way 200 var predictedContinuationsTraining = from x in estimatedTrainingValues.Skip(1) 201 select Enumerable.Repeat(x, 1); 202 203 var startTestValues = originalTestValues; 204 var actualContinuationsTest = from x in originalTestValues.Skip(1) 205 select Enumerable.Repeat(x, 1); 206 var predictedContinuationsTest = from x in estimatedTestValues.Skip(1) 207 select Enumerable.Repeat(x, 1); 208 209 double trainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(startTrainingValues, actualContinuationsTraining, predictedContinuationsTraining, out errorState); 194 210 TrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? trainingDirectionalSymmetry : double.NaN; 195 double testDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate( originalTestValues, estimatedTestValues, out errorState);211 double testDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(startTestValues, actualContinuationsTest, predictedContinuationsTest, out errorState); 196 212 TestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? testDirectionalSymmetry : double.NaN; 197 213 198 double trainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate( originalTrainingValues, estimatedTrainingValues, out errorState);214 double trainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(startTrainingValues, actualContinuationsTraining, predictedContinuationsTraining, out errorState); 199 215 TrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? trainingWeightedDirectionalSymmetry : double.NaN; 200 double testWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate( originalTestValues, estimatedTestValues, out errorState);216 double testWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(startTestValues, actualContinuationsTest, predictedContinuationsTest, out errorState); 201 217 TestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? testWeightedDirectionalSymmetry : double.NaN; 202 218 203 double trainingTheilsU = OnlineTheilsUStatisticCalculator.Calculate( originalTrainingValues, estimatedTrainingValues, out errorState);219 double trainingTheilsU = OnlineTheilsUStatisticCalculator.Calculate(startTrainingValues, actualContinuationsTraining, predictedContinuationsTraining, out errorState); 204 220 TrainingTheilsUStatistic = errorState == OnlineCalculatorError.None ? trainingTheilsU : double.NaN; 205 double testTheilsU = OnlineTheilsUStatisticCalculator.Calculate( originalTestValues, estimatedTestValues, out errorState);221 double testTheilsU = OnlineTheilsUStatisticCalculator.Calculate(startTestValues, actualContinuationsTest, predictedContinuationsTest, out errorState); 206 222 TestTheilsUStatistic = errorState == OnlineCalculatorError.None ? testTheilsU : double.NaN; 207 208 209 223 } 210 224 } -
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs
r6964 r6974 22 22 using System; 23 23 using System.Collections.Generic; 24 using HeuristicLab.Common; 24 25 25 26 26 27 namespace HeuristicLab.Problems.DataAnalysis { 27 public class OnlineDirectionalSymmetryCalculator : IOnlineCalculator { 28 private double prevEstimated; 29 private double prevOriginal; 28 public class OnlineDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator { 30 29 private int n; 31 30 private int nCorrect; … … 33 32 public double DirectionalSymmetry { 34 33 get { 35 if (n < =1) return 0.0;36 return (double)nCorrect / (n - 1) * 100.0;34 if (n < 1) return 0.0; 35 return (double)nCorrect / n; 37 36 } 38 37 } … … 51 50 } 52 51 53 public void Add(double original, double estimated) {54 if (double.IsNaN( estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {52 public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) { 53 if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) { 55 54 errorState = errorState | OnlineCalculatorError.InvalidValueAdded; 56 } else if (n == 0) {57 prevOriginal = original;58 prevEstimated = estimated;59 n++;60 55 } else { 61 if ((original - prevOriginal) * (estimated - prevEstimated) >= 0.0) { 62 nCorrect++; 56 var actualEnumerator = actualContinuation.GetEnumerator(); 57 var predictedEnumerator = predictedContinuation.GetEnumerator(); 58 double prevActual = startValue; 59 double prevPredicted = startValue; 60 while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) { 61 double actual = actualEnumerator.Current; 62 double predicted = predictedEnumerator.Current; 63 if (double.IsNaN(actual) || double.IsNaN(predicted)) { 64 errorState = errorState | OnlineCalculatorError.InvalidValueAdded; 65 } else { 66 // count a prediction correct if the trend (positive/negative/no change) is predicted correctly 67 if ((actual - prevActual) * (predicted - prevPredicted) > 0.0 || 68 (actual - prevActual).IsAlmost(predicted - prevPredicted) 69 ) { 70 nCorrect++; 71 } 72 n++; 73 } 63 74 } 64 n++; 65 errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1 66 prevOriginal = original; 67 prevEstimated = estimated; 75 // check if both enumerators are at the end to make sure both enumerations have the same length 76 if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) { 77 errorState = errorState | OnlineCalculatorError.InvalidValueAdded; 78 } else { 79 errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1 80 } 68 81 } 69 82 } … … 72 85 n = 0; 73 86 nCorrect = 0; 74 prevOriginal = double.NaN;75 prevEstimated = double.NaN;76 87 errorState = OnlineCalculatorError.InsufficientElementsAdded; 77 88 } 78 89 79 90 80 public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) { 81 IEnumerator<double> originalEnumerator = originalValues.GetEnumerator(); 82 IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator(); 91 public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) { 92 IEnumerator<double> startValueEnumerator = startValues.GetEnumerator(); 93 IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator(); 94 IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator(); 83 95 OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator(); 84 96 85 // add first element of time series as a reference point 86 originalEnumerator.MoveNext(); 87 estimatedEnumerator.MoveNext(); 88 dsCalculator.Add(originalEnumerator.Current, estimatedEnumerator.Current); 89 90 // always move forward both enumerators (do not use short-circuit evaluation!) 91 while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) { 92 double original = originalEnumerator.Current; 93 double estimated = estimatedEnumerator.Current; 94 dsCalculator.Add(original, estimated); 97 // always move forward all enumerators (do not use short-circuit evaluation!) 98 while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) { 99 dsCalculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current); 95 100 if (dsCalculator.ErrorState != OnlineCalculatorError.None) break; 96 101 } 97 102 98 // check if bothenumerators are at the end to make sure both enumerations have the same length103 // check if all enumerators are at the end to make sure both enumerations have the same length 99 104 if (dsCalculator.ErrorState == OnlineCalculatorError.None && 100 ( originalEnumerator.MoveNext() || estimatedEnumerator.MoveNext())) {101 throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");105 (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) { 106 throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match."); 102 107 } else { 103 108 errorState = dsCalculator.ErrorState; -
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs
r6964 r6974 22 22 using System; 23 23 using System.Collections.Generic; 24 using HeuristicLab.Common; 24 25 25 26 namespace HeuristicLab.Problems.DataAnalysis { 26 public class OnlineTheilsUStatisticCalculator : IOnline Calculator {27 public class OnlineTheilsUStatisticCalculator : IOnlineTimeSeriesCalculator { 27 28 private OnlineMeanAndVarianceCalculator squaredErrorMeanCalculator; 28 29 private OnlineMeanAndVarianceCalculator unbiasedEstimatorMeanCalculator; 29 private double prevOriginal;30 private int n;31 30 32 31 public double TheilsUStatistic { … … 52 51 } 53 52 54 public void Add(double original, double estimated) {55 if (double.IsNaN( estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {53 public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) { 54 if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) { 56 55 errorState = errorState | OnlineCalculatorError.InvalidValueAdded; 57 } else if (n == 0) {58 prevOriginal = original;59 n++;60 56 } else { 61 // error of predicted change 62 double errorEstimatedChange = (estimated - original); 63 squaredErrorMeanCalculator.Add(errorEstimatedChange * errorEstimatedChange); 57 var actualEnumerator = actualContinuation.GetEnumerator(); 58 var predictedEnumerator = predictedContinuation.GetEnumerator(); 59 while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & ErrorState != OnlineCalculatorError.InvalidValueAdded) { 60 double actual = actualEnumerator.Current; 61 double predicted = predictedEnumerator.Current; 62 if (double.IsNaN(actual) || double.IsNaN(predicted)) { 63 errorState = errorState | OnlineCalculatorError.InvalidValueAdded; 64 } else { 65 // error of predicted change 66 double errorPredictedChange = (predicted - startValue) - (actual - startValue); 67 squaredErrorMeanCalculator.Add(errorPredictedChange * errorPredictedChange); 64 68 65 double errorNoChange = (original - prevOriginal); 66 unbiasedEstimatorMeanCalculator.Add(errorNoChange * errorNoChange); 67 errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1 68 prevOriginal = original; 69 n++; 69 double errorNoChange = (actual - startValue); 70 unbiasedEstimatorMeanCalculator.Add(errorNoChange * errorNoChange); 71 } 72 } 73 // check if both enumerators are at the end to make sure both enumerations have the same length 74 if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) { 75 errorState = errorState | OnlineCalculatorError.InvalidValueAdded; 76 } else { 77 errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1 78 } 70 79 } 71 80 } 72 81 73 74 82 public void Reset() { 75 prevOriginal = double.NaN;76 n = 0;77 83 squaredErrorMeanCalculator.Reset(); 78 84 unbiasedEstimatorMeanCalculator.Reset(); … … 82 88 #endregion 83 89 84 public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) { 85 IEnumerator<double> originalValuesEnumerator = originalValues.GetEnumerator(); 86 IEnumerator<double> estimatedValuesEnumerator = estimatedValues.GetEnumerator(); 90 public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) { 91 IEnumerator<double> startValueEnumerator = startValues.GetEnumerator(); 92 IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator(); 93 IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator(); 87 94 OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator(); 88 95 89 // add first element of time series as a reference point 90 originalValuesEnumerator.MoveNext(); 91 estimatedValuesEnumerator.MoveNext(); 92 calculator.Add(originalValuesEnumerator.Current, estimatedValuesEnumerator.Current); 93 94 // always move forward both enumerators (do not use short-circuit evaluation!) 95 while (originalValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) { 96 double estimated = estimatedValuesEnumerator.Current; 97 double original = originalValuesEnumerator.Current; 98 calculator.Add(original, estimated); 96 // always move forward all enumerators (do not use short-circuit evaluation!) 97 while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) { 98 calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current); 99 99 if (calculator.ErrorState != OnlineCalculatorError.None) break; 100 100 } 101 101 102 // check if bothenumerators are at the end to make sure both enumerations have the same length102 // check if all enumerators are at the end to make sure both enumerations have the same length 103 103 if (calculator.ErrorState == OnlineCalculatorError.None && 104 ( estimatedValuesEnumerator.MoveNext() || originalValuesEnumerator.MoveNext())) {105 throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");104 (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) { 105 throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match."); 106 106 } else { 107 107 errorState = calculator.ErrorState; -
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs
r6964 r6974 22 22 using System; 23 23 using System.Collections.Generic; 24 using HeuristicLab.Common; 24 25 25 26 26 27 namespace HeuristicLab.Problems.DataAnalysis { 27 public class OnlineWeightedDirectionalSymmetryCalculator : IOnline Calculator {28 public class OnlineWeightedDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator { 28 29 private double prevEstimated; 29 30 private double prevOriginal; … … 52 53 } 53 54 54 public void Add(double original, double estimated) {55 if (double.IsNaN( estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {55 public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) { 56 if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) { 56 57 errorState = errorState | OnlineCalculatorError.InvalidValueAdded; 57 } else if (n == 0) {58 prevOriginal = original;59 prevEstimated = estimated;60 n++;61 58 } else { 62 double err = Math.Abs(original - estimated); 63 if ((original - prevOriginal) * (estimated - prevEstimated) >= 0.0) { 64 correctSum += err; 59 var actualEnumerator = actualContinuation.GetEnumerator(); 60 var predictedEnumerator = predictedContinuation.GetEnumerator(); 61 while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) { 62 double actual = actualEnumerator.Current; 63 double predicted = predictedEnumerator.Current; 64 if (double.IsNaN(actual) || double.IsNaN(predicted)) { 65 errorState = errorState | OnlineCalculatorError.InvalidValueAdded; 66 } else { 67 double err = Math.Abs(actual - predicted); 68 // count as correct only if the trend (positive/negative/no change) is predicted correctly 69 if ((actual - startValue) * (predicted - startValue) > 0.0 || 70 (actual - startValue).IsAlmost(predicted - startValue)) { 71 correctSum += err; 72 } else { 73 incorrectSum += err; 74 } 75 n++; 76 } 77 } 78 // check if both enumerators are at the end to make sure both enumerations have the same length 79 if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) { 80 errorState = errorState | OnlineCalculatorError.InvalidValueAdded; 65 81 } else { 66 incorrectSum += err;82 errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1 67 83 } 68 n++;69 errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 170 prevOriginal = original;71 prevEstimated = estimated;72 84 } 73 85 } … … 83 95 84 96 85 public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) { 86 IEnumerator<double> originalEnumerator = originalValues.GetEnumerator(); 87 IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator(); 88 OnlineWeightedDirectionalSymmetryCalculator dsCalculator = new OnlineWeightedDirectionalSymmetryCalculator(); 97 public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) { 98 IEnumerator<double> startValueEnumerator = startValues.GetEnumerator(); 99 IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator(); 100 IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator(); 101 OnlineWeightedDirectionalSymmetryCalculator calculator = new OnlineWeightedDirectionalSymmetryCalculator(); 89 102 90 // add first element of time series as a reference point 91 originalEnumerator.MoveNext(); 92 estimatedEnumerator.MoveNext(); 93 dsCalculator.Add(originalEnumerator.Current, estimatedEnumerator.Current); 94 95 // always move forward both enumerators (do not use short-circuit evaluation!) 96 while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) { 97 double original = originalEnumerator.Current; 98 double estimated = estimatedEnumerator.Current; 99 dsCalculator.Add(original, estimated); 100 if (dsCalculator.ErrorState != OnlineCalculatorError.None) break; 103 // always move forward all enumerators (do not use short-circuit evaluation!) 104 while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) { 105 calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current); 106 if (calculator.ErrorState != OnlineCalculatorError.None) break; 101 107 } 102 108 103 // check if bothenumerators are at the end to make sure both enumerations have the same length104 if ( dsCalculator.ErrorState == OnlineCalculatorError.None &&105 ( originalEnumerator.MoveNext() || estimatedEnumerator.MoveNext())) {106 throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");109 // check if all enumerators are at the end to make sure both enumerations have the same length 110 if (calculator.ErrorState == OnlineCalculatorError.None && 111 (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) { 112 throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match."); 107 113 } else { 108 errorState = dsCalculator.ErrorState;109 return dsCalculator.WeightedDirectionalSymmetry;114 errorState = calculator.ErrorState; 115 return calculator.WeightedDirectionalSymmetry; 110 116 } 111 117 } -
trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis-3.4/StatisticCalculatorsTest.cs
r6880 r6974 20 20 #endregion 21 21 22 using System; 22 23 using System.Collections.Generic; 23 24 using System.Linq; … … 140 141 } 141 142 } 143 144 [TestMethod] 145 public void CalculateDirectionalSymmetryTest() { 146 // delta: +0.01, +1, -0.01, -2, -0.01, -1, +0.01, +2 147 var original = new double[] 148 { 149 0, 150 0.01, 151 1.01, 152 1, 153 -1, 154 -1.01, 155 -2.01, 156 -2, 157 0 158 }; 159 // delta to original(t-1): +1, +0, -1, -0, -1, +0.01, +0.01, +2 160 var estimated = new double[] 161 { 162 -1, 163 1, 164 0.01, 165 0.01, 166 1, 167 -1, 168 -1.02, 169 -2.02, 170 0 171 }; 172 173 // one-step forecast 174 var startValues = original; 175 var actualContinuations = from x in original.Skip(1) 176 select Enumerable.Repeat(x, 1); 177 var predictedContinuations = from x in estimated.Skip(1) 178 select Enumerable.Repeat(x, 1); 179 double expected = 0.5; // half of the predicted deltas are correct 180 OnlineCalculatorError errorState; 181 double actual = OnlineDirectionalSymmetryCalculator.Calculate(startValues, actualContinuations, predictedContinuations, out errorState); 182 Assert.AreEqual(expected, actual, 1E-9); 183 } 184 [TestMethod] 185 public void CalculateWeightedDirectionalSymmetryTest() { 186 var original = new double[] { 0, 0.01, 1.01, 1, -1, -1.01, -2.01, -2, 0 }; // +0.01, +1, -0.01, -2, -0.01, -1, +0.01, +2 187 var estimated = new double[] { 1, 2, 2, 1, 1, 0, 0.01, 0.02, 2.02 }; // delta to original: +2, +1.99, -0.01, 0, +1, -1.02, +2.01, +4.02 188 // one-step forecast 189 var startValues = original; 190 var actualContinuations = from x in original.Skip(1) 191 select Enumerable.Repeat(x, 1); 192 var predictedContinuations = from x in estimated.Skip(1) 193 select Enumerable.Repeat(x, 1); 194 // absolute errors = 1.99, 0.99, 0, 2, 1.01, 2.02, 2.02, 2.02 195 // sum of absolute errors for correctly predicted deltas = 2.97 196 // sum of absolute errors for incorrectly predicted deltas = 3.03 197 double expected = 5.03 / 7.02; 198 OnlineCalculatorError errorState; 199 double actual = OnlineWeightedDirectionalSymmetryCalculator.Calculate(startValues, actualContinuations, predictedContinuations, out errorState); 200 Assert.AreEqual(expected, actual, 1E-9); 201 } 202 [TestMethod] 203 public void CalculateTheilsUTest() { 204 var original = new double[] { 0, 0.01, 1.01, 1, -1, -1.01, -2.01, -2, 0 }; 205 var estimated = new double[] { 1, 1.01, 0.01, 2, 0, -0.01, -1.01, -3, 1 }; 206 // one-step forecast 207 var startValues = original; 208 var actualContinuations = from x in original.Skip(1) 209 select Enumerable.Repeat(x, 1); 210 var predictedContinuations = from x in estimated.Skip(1) 211 select Enumerable.Repeat(x, 1); 212 // Sum of squared errors of model y(t+1) = y(t) = 10.0004 213 // Sum of squared errors of predicted values = 8 214 double expected = Math.Sqrt(8 / 10.0004); 215 OnlineCalculatorError errorState; 216 double actual = OnlineTheilsUStatisticCalculator.Calculate(startValues, actualContinuations, predictedContinuations, out errorState); 217 Assert.AreEqual(expected, actual, 1E-9); 218 } 219 [TestMethod] 220 public void CalculateAccuracyTest() { 221 var original = new double[] { 1, 1, 0, 0 }; 222 var estimated = new double[] { 1, 0, 1, 0 }; 223 double expected = 0.5; 224 OnlineCalculatorError errorState; 225 double actual = OnlineAccuracyCalculator.Calculate(original, estimated, out errorState); 226 Assert.AreEqual(expected, actual, 1E-9); 227 } 228 229 [TestMethod] 230 public void CalculateMeanAbsolutePercentageErrorTest() { 231 var original = new double[] { 1, 2, 3, 1, 5 }; 232 var estimated = new double[] { 2, 1, 3, 1, 0 }; 233 double expected = 0.5; 234 OnlineCalculatorError errorState; 235 double actual = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(original, estimated, out errorState); 236 Assert.AreEqual(expected, actual, 1E-9); 237 Assert.AreEqual(OnlineCalculatorError.None, errorState); 238 239 // if the original contains zero values the result is not defined 240 var original2 = new double[] { 1, 2, 0, 0, 0 }; 241 OnlineMeanAbsolutePercentageErrorCalculator.Calculate(original2, estimated, out errorState); 242 Assert.AreEqual(OnlineCalculatorError.InvalidValueAdded, errorState); 243 } 142 244 } 143 245 }
Note: See TracChangeset
for help on using the changeset viewer.