#region License Information
/* HeuristicLab
* Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System.Linq;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Operators;
using HeuristicLab.Optimization;
using HeuristicLab.Parameters;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
using HeuristicLab.Problems.DataAnalysis.Regression.Symbolic;
using HeuristicLab.Problems.DataAnalysis.Symbolic;
using System.Collections.Generic;
using HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols;
using HeuristicLab.Problems.DataAnalysis;
using System;
using HeuristicLab.Problems.DataAnalysis.Evaluators;
using HeuristicLab.Problems.DataAnalysis.Regression;
using HeuristicLab.Analysis;
using HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis.Symbolic.Evaluators;
using HeuristicLab.Problems.DataAnalysis.MultiVariate.Regression.Symbolic;
using HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis.Symbolic.Interfaces;
namespace HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis.Symbolic.Analyzers {
///
/// An operator that analyzes the validation best scaled symbolic time series prognosis solution.
///
[Item("ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer", "An operator that analyzes the validation best scaled symbolic time series prognosis solution.")]
[StorableClass]
public sealed class ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer : SingleSuccessorOperator, IAnalyzer {
private const string RandomParameterName = "Random";
private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
private const string EvaluatorParameterName = "Evaluator";
private const string MaximizationParameterName = "Maximization";
private const string ProblemDataParameterName = "ProblemData";
private const string ValidationSamplesStartParameterName = "SamplesStart";
private const string ValidationSamplesEndParameterName = "SamplesEnd";
private const string QualityParameterName = "Quality";
private const string ScaledQualityParameterName = "ScaledQuality";
private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
private const string ValidationPredictionHorizonParameterName = "ValidationPredictionHorizon";
private const string ModelPredictionHorizonParameterName = "ModelPredictionHorizon";
private const string ConditionVariableParameterName = "ConditionVariableName";
private const string ResultsParameterName = "Results";
private const string VariableFrequenciesParameterName = "VariableFrequencies";
private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
private const string BestSolutionParameterName = "Best solution (validation)";
private const string BestSolutionQualityParameterName = "Best solution quality (validation)";
private const string CurrentBestValidationQualityParameterName = "Current best validation quality";
private const string BestSolutionQualityValuesParameterName = "Validation Quality";
private const string BestKnownQualityParameterName = "BestKnownQuality";
private const string GenerationsParameterName = "Generations";
private const string BestSolutionMeanSquaredErrorTrainingParameterName = "Best validation solution mean squared error (training)";
private const string BestSolutionMeanSquaredErrorTestParameterName = "Best validation solution mean squared error (test)";
private const string BestSolutionRSquaredTrainingParameterName = "Best validation solution Rē (training)";
private const string BestSolutionRSquaredTestParameterName = "Best validation solution Rē (test)";
private const string BestSolutionDirectionalSymmetryTrainingParameterName = "Best validation solution directional symmetry (training)";
private const string BestSolutionDirectionalSymmetryTestParameterName = "Best validation solution directional symmetry (test)";
private const string BestSolutionTheilsUTrainingParameterName = "Best validation solution Theil's U (training)";
private const string BestSolutionTheilsUTestParameterName = "Best validation solution Theil's U (test)";
private const string BestSolutionTheilsUTrendTrainingParameterName = "Best validation solution Theil's U with trend (training)";
private const string BestSolutionTheilsUTrendTestParameterName = "Best validation solution Theil's U with trend (test)";
#region parameter properties
public ILookupParameter RandomParameter {
get { return (ILookupParameter)Parameters[RandomParameterName]; }
}
public ScopeTreeLookupParameter SymbolicExpressionTreeParameter {
get { return (ScopeTreeLookupParameter)Parameters[SymbolicExpressionTreeParameterName]; }
}
public OptionalValueParameter ConditionVariableNameParameter {
get { return (OptionalValueParameter)Parameters[ConditionVariableParameterName]; }
}
public IValueLookupParameter SymbolicExpressionTreeInterpreterParameter {
get { return (IValueLookupParameter)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
}
public IValueLookupParameter ProblemDataParameter {
get { return (IValueLookupParameter)Parameters[ProblemDataParameterName]; }
}
public ILookupParameter EvaluatorParameter {
get { return (ILookupParameter)Parameters[EvaluatorParameterName]; }
}
public IValueLookupParameter ValidationSamplesStartParameter {
get { return (IValueLookupParameter)Parameters[ValidationSamplesStartParameterName]; }
}
public IValueLookupParameter ValidationSamplesEndParameter {
get { return (IValueLookupParameter)Parameters[ValidationSamplesEndParameterName]; }
}
public IValueLookupParameter UpperEstimationLimitParameter {
get { return (IValueLookupParameter)Parameters[UpperEstimationLimitParameterName]; }
}
public IValueLookupParameter LowerEstimationLimitParameter {
get { return (IValueLookupParameter)Parameters[LowerEstimationLimitParameterName]; }
}
public IValueLookupParameter ValidationPredictionHorizonParameter {
get { return (IValueLookupParameter)Parameters[ValidationPredictionHorizonParameterName]; }
}
public IValueLookupParameter ModelPredictionHorizonParameter {
get { return (IValueLookupParameter)Parameters[ModelPredictionHorizonParameterName]; }
}
public ILookupParameter BestSolutionParameter {
get { return (ILookupParameter)Parameters[BestSolutionParameterName]; }
}
public ILookupParameter GenerationsParameter {
get { return (ILookupParameter)Parameters[GenerationsParameterName]; }
}
public ILookupParameter BestSolutionQualityParameter {
get { return (ILookupParameter)Parameters[BestSolutionQualityParameterName]; }
}
public ILookupParameter ResultsParameter {
get { return (ILookupParameter)Parameters[ResultsParameterName]; }
}
public ILookupParameter BestKnownQualityParameter {
get { return (ILookupParameter)Parameters[BestKnownQualityParameterName]; }
}
public ILookupParameter VariableFrequenciesParameter {
get { return (ILookupParameter)Parameters[VariableFrequenciesParameterName]; }
}
public IValueParameter RelativeNumberOfEvaluatedSamplesParameter {
get { return (IValueParameter)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; }
}
public ILookupParameter MaximizationParameter {
get { return (ILookupParameter)Parameters[MaximizationParameterName]; }
}
public ILookupParameter BestSolutionMeanSquaredErrorTrainingParameter {
get { return (ILookupParameter)Parameters[BestSolutionMeanSquaredErrorTrainingParameterName]; }
}
public ILookupParameter BestSolutionMeanSquaredErrorTestParameter {
get { return (ILookupParameter)Parameters[BestSolutionMeanSquaredErrorTestParameterName]; }
}
public ILookupParameter BestSolutionRSquaredTrainingParameter {
get { return (ILookupParameter)Parameters[BestSolutionRSquaredTrainingParameterName]; }
}
public ILookupParameter BestSolutionRSquaredTestParameter {
get { return (ILookupParameter)Parameters[BestSolutionRSquaredTestParameterName]; }
}
public ILookupParameter BestSolutionDirectionalSymmetryTrainingParameter {
get { return (ILookupParameter)Parameters[BestSolutionDirectionalSymmetryTrainingParameterName]; }
}
public ILookupParameter BestSolutionDirectionalSymmetryTestParameter {
get { return (ILookupParameter)Parameters[BestSolutionDirectionalSymmetryTestParameterName]; }
}
public ILookupParameter BestSolutionTheilsUTrainingParameter {
get { return (ILookupParameter)Parameters[BestSolutionTheilsUTrainingParameterName]; }
}
public ILookupParameter BestSolutionTheilsUTestParameter {
get { return (ILookupParameter)Parameters[BestSolutionTheilsUTestParameterName]; }
}
public ILookupParameter BestSolutionTheilsUTrendTrainingParameter {
get { return (ILookupParameter)Parameters[BestSolutionTheilsUTrendTrainingParameterName]; }
}
public ILookupParameter BestSolutionTheilsUTrendTestParameter {
get { return (ILookupParameter)Parameters[BestSolutionTheilsUTrendTestParameterName]; }
}
#endregion
#region properties
public IRandom Random {
get { return RandomParameter.ActualValue; }
}
public ItemArray SymbolicExpressionTree {
get { return SymbolicExpressionTreeParameter.ActualValue; }
}
public ISymbolicTimeSeriesExpressionInterpreter SymbolicExpressionTreeInterpreter {
get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; }
}
public MultiVariateDataAnalysisProblemData ProblemData {
get { return ProblemDataParameter.ActualValue; }
}
public IntValue ValidiationSamplesStart {
get { return ValidationSamplesStartParameter.ActualValue; }
}
public IntValue ValidationSamplesEnd {
get { return ValidationSamplesEndParameter.ActualValue; }
}
public DoubleArray UpperEstimationLimit {
get { return UpperEstimationLimitParameter.ActualValue; }
}
public DoubleArray LowerEstimationLimit {
get { return LowerEstimationLimitParameter.ActualValue; }
}
public IntValue ValidationPredictionHorizon {
get { return ValidationPredictionHorizonParameter.ActualValue; }
}
public IntValue ModelPredictionHorizon {
get { return ModelPredictionHorizonParameter.ActualValue; }
}
public StringValue ConditionVariableName {
get { return ConditionVariableNameParameter.Value; }
}
public ResultCollection Results {
get { return ResultsParameter.ActualValue; }
}
public DataTable VariableFrequencies {
get { return VariableFrequenciesParameter.ActualValue; }
}
public IntValue Generations {
get { return GenerationsParameter.ActualValue; }
}
public PercentValue RelativeNumberOfEvaluatedSamples {
get { return RelativeNumberOfEvaluatedSamplesParameter.Value; }
}
public BoolValue Maximization {
get { return MaximizationParameter.ActualValue; }
}
public DoubleArray BestSolutionMeanSquaredErrorTraining {
get { return BestSolutionMeanSquaredErrorTrainingParameter.ActualValue; }
set { BestSolutionMeanSquaredErrorTrainingParameter.ActualValue = value; }
}
public DoubleArray BestSolutionMeanSquaredErrorTest {
get { return BestSolutionMeanSquaredErrorTestParameter.ActualValue; }
set { BestSolutionMeanSquaredErrorTestParameter.ActualValue = value; }
}
public DoubleArray BestSolutionRSquaredTraining {
get { return BestSolutionRSquaredTrainingParameter.ActualValue; }
set { BestSolutionRSquaredTrainingParameter.ActualValue = value; }
}
public DoubleArray BestSolutionRSquaredTest {
get { return BestSolutionRSquaredTestParameter.ActualValue; }
set { BestSolutionRSquaredTestParameter.ActualValue = value; }
}
public DoubleArray BestSolutionDirectionalSymmetryTraining {
get { return BestSolutionDirectionalSymmetryTrainingParameter.ActualValue; }
set { BestSolutionDirectionalSymmetryTrainingParameter.ActualValue = value; }
}
public DoubleArray BestSolutionDirectionalSymmetryTest {
get { return BestSolutionDirectionalSymmetryTestParameter.ActualValue; }
set { BestSolutionDirectionalSymmetryTestParameter.ActualValue = value; }
}
public DoubleArray BestSolutionTheilsUTraining {
get { return BestSolutionTheilsUTrainingParameter.ActualValue; }
set { BestSolutionTheilsUTrainingParameter.ActualValue = value; }
}
public DoubleArray BestSolutionTheilsUTest {
get { return BestSolutionTheilsUTestParameter.ActualValue; }
set { BestSolutionTheilsUTestParameter.ActualValue = value; }
}
public DoubleArray BestSolutionTheilsUTrendTraining {
get { return BestSolutionTheilsUTrendTrainingParameter.ActualValue; }
set { BestSolutionTheilsUTrendTrainingParameter.ActualValue = value; }
}
public DoubleArray BestSolutionTheilsUTrendTest {
get { return BestSolutionTheilsUTrendTestParameter.ActualValue; }
set { BestSolutionTheilsUTrendTestParameter.ActualValue = value; }
}
#endregion
[StorableConstructor]
protected ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer(bool deserializing) : base(deserializing) { }
protected ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer(ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer original, Cloner cloner)
: base(original, cloner) {
}
public ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer()
: base() {
Parameters.Add(new LookupParameter(RandomParameterName, "A random number generator."));
Parameters.Add(new ScopeTreeLookupParameter(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
Parameters.Add(new OptionalValueParameter(ConditionVariableParameterName, "The name of the condition variable indicating if a row should be considered for evaluation or not."));
Parameters.Add(new ValueLookupParameter(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used for the analysis of symbolic expression trees."));
Parameters.Add(new ValueLookupParameter(ProblemDataParameterName, "The problem data for which the symbolic expression tree is a solution."));
Parameters.Add(new ValueLookupParameter(ValidationSamplesStartParameterName, "The first index of the validation partition of the data set."));
Parameters.Add(new ValueLookupParameter(ValidationSamplesEndParameterName, "The last index of the validation partition of the data set."));
Parameters.Add(new ValueLookupParameter(ValidationPredictionHorizonParameterName, "The number of time steps for which to create a forecast for the validation procedure."));
Parameters.Add(new ValueLookupParameter(ModelPredictionHorizonParameterName, "Prediction horizont stored in the validation best model."));
Parameters.Add(new LookupParameter(EvaluatorParameterName, ""));
Parameters.Add(new ValueLookupParameter(UpperEstimationLimitParameterName, "The upper estimation limit that was set for the evaluation of the symbolic expression trees."));
Parameters.Add(new ValueLookupParameter(LowerEstimationLimitParameterName, "The lower estimation limit that was set for the evaluation of the symbolic expression trees."));
Parameters.Add(new LookupParameter(BestSolutionParameterName, "The best symbolic time series prognosis solution."));
Parameters.Add(new LookupParameter(GenerationsParameterName, "The number of generations calculated so far."));
Parameters.Add(new LookupParameter(BestSolutionQualityParameterName, "The quality of the best symbolic regression solution."));
Parameters.Add(new LookupParameter(ResultsParameterName, "The result collection where the best symbolic regression solution should be stored."));
Parameters.Add(new LookupParameter(BestKnownQualityParameterName, "The best known (validation) quality achieved on the data set."));
Parameters.Add(new LookupParameter(VariableFrequenciesParameterName, "The variable frequencies table to use for the calculation of variable impacts"));
Parameters.Add(new ValueParameter(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index.", new PercentValue(1)));
Parameters.Add(new LookupParameter(MaximizationParameterName));
Parameters.Add(new LookupParameter(BestSolutionMeanSquaredErrorTrainingParameterName));
Parameters.Add(new LookupParameter(BestSolutionMeanSquaredErrorTestParameterName));
Parameters.Add(new LookupParameter(BestSolutionRSquaredTrainingParameterName));
Parameters.Add(new LookupParameter(BestSolutionRSquaredTestParameterName));
Parameters.Add(new LookupParameter(BestSolutionDirectionalSymmetryTrainingParameterName));
Parameters.Add(new LookupParameter(BestSolutionDirectionalSymmetryTestParameterName));
Parameters.Add(new LookupParameter(BestSolutionTheilsUTrainingParameterName));
Parameters.Add(new LookupParameter(BestSolutionTheilsUTestParameterName));
Parameters.Add(new LookupParameter(BestSolutionTheilsUTrendTrainingParameterName));
Parameters.Add(new LookupParameter(BestSolutionTheilsUTrendTestParameterName));
}
public override IDeepCloneable Clone(Cloner cloner) {
return new ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer(this, cloner);
}
[StorableHook(Persistence.Default.CompositeSerializers.Storable.HookType.AfterDeserialization)]
private void AfterDeserialization() {
}
public override IOperation Apply() {
var trees = SymbolicExpressionTree;
ISingleObjectiveSymbolicTimeSeriesPrognosisEvaluator evaluator = EvaluatorParameter.ActualValue;
int trainingStart = ProblemData.TrainingSamplesStart.Value;
int trainingEnd = ProblemData.TrainingSamplesEnd.Value;
int testStart = ProblemData.TestSamplesStart.Value;
int testEnd = ProblemData.TestSamplesEnd.Value;
#region validation best model
int validationStart = ValidiationSamplesStart.Value;
int validationEnd = ValidationSamplesEnd.Value;
int rowCount = (int)Math.Ceiling((validationEnd - validationStart) * RelativeNumberOfEvaluatedSamples.Value);
IEnumerable rows = RandomEnumerable.SampleRandomNumbers(Random.Next(), validationStart, validationEnd, rowCount);
double bestValidationQuality = Maximization.Value ? double.MinValue : double.MaxValue;
SymbolicExpressionTree bestTree = null;
string conditionalVariableName = ConditionVariableName == null ? null : ConditionVariableName.Value;
if (conditionalVariableName != null) {
rows = from row in rows
where !ProblemData.Dataset[conditionalVariableName, row].IsAlmost(0.0)
select row;
}
foreach (var tree in trees) {
double validationQuality;
validationQuality = evaluator.Evaluate(tree, ProblemData,
SymbolicExpressionTreeInterpreter, rows, ValidationPredictionHorizon.Value, LowerEstimationLimit, UpperEstimationLimit);
if ((Maximization.Value && validationQuality > bestValidationQuality) ||
(!Maximization.Value && validationQuality < bestValidationQuality)) {
bestValidationQuality = validationQuality;
bestTree = tree;
}
}
if (BestSolutionQualityParameter.ActualValue == null ||
(Maximization.Value && BestSolutionQualityParameter.ActualValue.Value < bestValidationQuality) ||
(!Maximization.Value && BestSolutionQualityParameter.ActualValue.Value > bestValidationQuality)) {
var scaledTree = GetScaledTree(bestTree);
var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicTimeSeriesExpressionInterpreter)SymbolicExpressionTreeInterpreter.Clone(), scaledTree);
model.Name = "Time series prognosis model";
model.Description = "Best solution on validation partition found over the whole run.";
var solution = new SymbolicTimeSeriesPrognosisSolution((MultiVariateDataAnalysisProblemData)ProblemData.Clone(), model, ModelPredictionHorizon.Value, conditionalVariableName, LowerEstimationLimit.ToArray(), UpperEstimationLimit.ToArray());
solution.Name = BestSolutionParameterName;
solution.Description = "Best solution on validation partition found over the whole run.";
BestSolutionParameter.ActualValue = solution;
BestSolutionQualityParameter.ActualValue = new DoubleValue(bestValidationQuality);
#region calculate accuracy
List targetVariables = ProblemData.TargetVariables.CheckedItems.Select(x => x.Value.Value).ToList();
// create a list of time series evaluators for each target variable
Dictionary> trainingEvaluators =
new Dictionary>();
Dictionary> testEvaluators =
new Dictionary>();
foreach (string targetVariable in targetVariables) {
trainingEvaluators.Add(targetVariable, new List());
trainingEvaluators[targetVariable].Add(new OnlineMeanSquaredErrorEvaluator());
trainingEvaluators[targetVariable].Add(new OnlinePearsonsRSquaredEvaluator());
trainingEvaluators[targetVariable].Add(new OnlineDirectionalSymmetryEvaluator());
trainingEvaluators[targetVariable].Add(new OnlineTheilsUStatisticEvaluator());
trainingEvaluators[targetVariable].Add(new OnlineTheilsUStatisticEvaluator(10));
testEvaluators.Add(targetVariable, new List());
testEvaluators[targetVariable].Add(new OnlineMeanSquaredErrorEvaluator());
testEvaluators[targetVariable].Add(new OnlinePearsonsRSquaredEvaluator());
testEvaluators[targetVariable].Add(new OnlineDirectionalSymmetryEvaluator());
testEvaluators[targetVariable].Add(new OnlineTheilsUStatisticEvaluator());
testEvaluators[targetVariable].Add(new OnlineTheilsUStatisticEvaluator(10));
}
Evaluate(solution, solution.ProblemData.Dataset, targetVariables, conditionalVariableName, trainingStart, trainingEnd, trainingEvaluators);
Evaluate(solution, solution.ProblemData.Dataset, targetVariables, conditionalVariableName, testStart, testEnd, testEvaluators);
#endregion
BestSolutionMeanSquaredErrorTraining = new DoubleArray((from variable in targetVariables
let eval = trainingEvaluators[variable].OfType().Single()
select TryGetValue(eval))
.ToArray());
BestSolutionMeanSquaredErrorTest = new DoubleArray((from variable in targetVariables
select TryGetValue(testEvaluators[variable].OfType().Single()))
.ToArray());
BestSolutionRSquaredTraining = new DoubleArray((from variable in targetVariables
select TryGetValue(trainingEvaluators[variable].OfType().Single()))
.ToArray());
BestSolutionRSquaredTest = new DoubleArray((from variable in targetVariables
select TryGetValue(testEvaluators[variable].OfType().Single()))
.ToArray());
BestSolutionDirectionalSymmetryTraining = new DoubleArray((from variable in targetVariables
select TryGetValue(trainingEvaluators[variable].OfType().Single()))
.ToArray());
BestSolutionDirectionalSymmetryTest = new DoubleArray((from variable in targetVariables
select TryGetValue(testEvaluators[variable].OfType().Single()))
.ToArray());
BestSolutionTheilsUTraining = new DoubleArray((from variable in targetVariables
select TryGetValue(trainingEvaluators[variable].OfType().First()))
.ToArray());
BestSolutionTheilsUTest = new DoubleArray((from variable in targetVariables
select TryGetValue(testEvaluators[variable].OfType().First()))
.ToArray());
BestSolutionTheilsUTrendTraining = new DoubleArray((from variable in targetVariables
select TryGetValue(trainingEvaluators[variable].OfType().Skip(1).First()))
.ToArray());
BestSolutionTheilsUTrendTest = new DoubleArray((from variable in targetVariables
select TryGetValue(testEvaluators[variable].OfType().Skip(1).First()))
.ToArray());
if (!Results.ContainsKey(BestSolutionParameterName)) {
for (int i = 0; i < targetVariables.Count; i++) {
Results.Add(new Result(BestSolutionMeanSquaredErrorTrainingParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionMeanSquaredErrorTraining[i])));
Results.Add(new Result(BestSolutionMeanSquaredErrorTestParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionMeanSquaredErrorTest[i])));
Results.Add(new Result(BestSolutionRSquaredTrainingParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionRSquaredTraining[i])));
Results.Add(new Result(BestSolutionRSquaredTestParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionRSquaredTest[i])));
Results.Add(new Result(BestSolutionDirectionalSymmetryTrainingParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionDirectionalSymmetryTraining[i])));
Results.Add(new Result(BestSolutionDirectionalSymmetryTestParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionDirectionalSymmetryTest[i])));
Results.Add(new Result(BestSolutionTheilsUTrainingParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionTheilsUTraining[i])));
Results.Add(new Result(BestSolutionTheilsUTestParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionTheilsUTest[i])));
Results.Add(new Result(BestSolutionTheilsUTrendTrainingParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionTheilsUTrendTraining[i])));
Results.Add(new Result(BestSolutionTheilsUTrendTestParameterName + " (" + targetVariables[i] + ")",
new DoubleValue(BestSolutionTheilsUTrendTest[i])));
}
} else {
for (int i = 0; i < targetVariables.Count; i++) {
Results[BestSolutionMeanSquaredErrorTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionMeanSquaredErrorTraining[i]);
Results[BestSolutionMeanSquaredErrorTestParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionMeanSquaredErrorTest[i]);
Results[BestSolutionRSquaredTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionRSquaredTraining[i]);
Results[BestSolutionRSquaredTestParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionRSquaredTest[i]);
Results[BestSolutionDirectionalSymmetryTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionDirectionalSymmetryTraining[i]);
Results[BestSolutionDirectionalSymmetryTestParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionDirectionalSymmetryTest[i]);
Results[BestSolutionTheilsUTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionTheilsUTraining[i]);
Results[BestSolutionTheilsUTestParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionTheilsUTest[i]);
Results[BestSolutionTheilsUTrendTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionTheilsUTrendTraining[i]);
Results[BestSolutionTheilsUTrendTestParameterName + " (" + targetVariables[i] + ")"].Value =
new DoubleValue(BestSolutionTheilsUTrendTest[i]);
}
}
}
if (!Results.ContainsKey(BestSolutionQualityValuesParameterName)) {
Results.Add(new Result(BestSolutionParameterName, BestSolutionParameter.ActualValue));
Results.Add(new Result(BestSolutionQualityValuesParameterName, new DataTable(BestSolutionQualityValuesParameterName, BestSolutionQualityValuesParameterName)));
Results.Add(new Result(BestSolutionQualityParameterName, new DoubleValue()));
Results.Add(new Result(CurrentBestValidationQualityParameterName, new DoubleValue()));
}
Results[BestSolutionParameterName].Value = BestSolutionParameter.ActualValue;
Results[BestSolutionQualityParameterName].Value = new DoubleValue(BestSolutionQualityParameter.ActualValue.Value);
Results[CurrentBestValidationQualityParameterName].Value = new DoubleValue(bestValidationQuality);
DataTable validationValues = (DataTable)Results[BestSolutionQualityValuesParameterName].Value;
AddValue(validationValues, BestSolutionQualityParameter.ActualValue.Value, BestSolutionQualityParameterName, BestSolutionQualityParameterName);
AddValue(validationValues, bestValidationQuality, CurrentBestValidationQualityParameterName, CurrentBestValidationQualityParameterName);
#endregion
return base.Apply();
}
private double TryGetValue(IOnlineEvaluator eval) {
try {
return eval.Value;
}
catch {
return double.NaN;
}
}
private SymbolicExpressionTree GetScaledTree(SymbolicExpressionTree tree) {
double[] alpha, beta;
int trainingStart = ProblemData.TrainingSamplesStart.Value;
int trainingEnd = ProblemData.TrainingSamplesEnd.Value;
IEnumerable trainingRows = Enumerable.Range(trainingStart, trainingEnd - trainingStart);
string conditionalVariableName = ConditionVariableName == null ? null : ConditionVariableName.Value;
if (conditionalVariableName != null) {
trainingRows = from row in trainingRows
where !ProblemData.Dataset[conditionalVariableName, row].IsAlmost(0.0)
select row;
}
// calculate scaling parameters based on one-step-predictions
IEnumerable selectedTargetVariables = from item in ProblemData.TargetVariables
where ProblemData.TargetVariables.ItemChecked(item)
select item.Value;
int dimension = selectedTargetVariables.Count();
IEnumerable> oneStepPredictions =
SymbolicExpressionTreeInterpreter.GetSymbolicExpressionTreeValues(tree, ProblemData.Dataset, selectedTargetVariables, trainingRows, 1)
.Cast>();
IEnumerable> originalValues = from row in trainingRows
select (from targetVariable in selectedTargetVariables
select ProblemData.Dataset[targetVariable, row]);
alpha = new double[dimension];
beta = new double[dimension];
SymbolicTimeSeriesPrognosisScaledNormalizedMseEvaluator.CalculateScalingParameters(originalValues, oneStepPredictions, ref beta, ref alpha);
// scale tree for solution
return SymbolicVectorRegressionSolutionLinearScaler.Scale(tree, beta, alpha);
}
private void Evaluate(SymbolicTimeSeriesPrognosisSolution solution, Dataset dataset, IEnumerable targetVariables, string conditionalEvaluationVariable, int start, int end, Dictionary> evaluators) {
for (int row = start; row < end; row++) {
if (string.IsNullOrEmpty(conditionalEvaluationVariable) || dataset[conditionalEvaluationVariable, row] != 0) {
// prepare evaluators for each target variable for a new prediction window
foreach (var entry in evaluators) {
double referenceOriginalValue = dataset[entry.Key, row - 1];
foreach (IOnlineTimeSeriesPrognosisEvaluator evaluator in entry.Value.OfType()) {
evaluator.StartNewPredictionWindow(referenceOriginalValue);
}
}
if (string.IsNullOrEmpty(conditionalEvaluationVariable) ||
dataset[conditionalEvaluationVariable, row] > 0) {
int timestep = 0;
foreach (double[] x in solution.GetPrognosis(row)) {
int targetIndex = 0;
if (row + timestep < dataset.Rows) {
foreach (var targetVariable in targetVariables) {
double originalValue = dataset[targetVariable, row + timestep];
double estimatedValue = x[targetIndex];
if (IsValidValue(originalValue) && IsValidValue(estimatedValue)) {
foreach (IOnlineEvaluator evaluator in evaluators[targetVariable]) {
evaluator.Add(originalValue, estimatedValue);
}
}
targetIndex++;
}
}
timestep++;
}
}
}
}
}
private bool IsValidValue(double d) {
return !(double.IsNaN(d) || double.IsInfinity(d));
}
private static void AddValue(DataTable table, double data, string name, string description) {
DataRow row;
table.Rows.TryGetValue(name, out row);
if (row == null) {
row = new DataRow(name, description);
row.Values.Add(data);
table.Rows.Add(row);
} else {
row.Values.Add(data);
}
}
}
}