#region License Information /* HeuristicLab * Copyright (C) 2002-2013 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.Analysis; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Problems.DataAnalysis.Symbolic.SlidingWindow { [StorableClass] [Item("Sliding Window Qualities Analyzer", "Analyzer that computes the qualities of the best solution on past, current, and future regions of the sliding window training data.")] public sealed class SlidingWindowQualitiesAnalyzer : SymbolicDataAnalysisAnalyzer { private const string SlidingWindowQualitiesResultName = "Sliding Window Qualities"; private const string ProblemDataParameterName = "ProblemData"; private const string EvaluatorParameterName = "Evaluator"; private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition"; private const string ValidationPartitionParameterName = "ValidationPartition"; private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter"; public IValueLookupParameter ProblemDataParameter { get { return (IValueLookupParameter)Parameters[ProblemDataParameterName]; } } public ILookupParameter FitnessCalculationPartitionParameter { get { return (ILookupParameter)Parameters[FitnessCalculationPartitionParameterName]; } } public ILookupParameter ValidationPartitionParameter { get { return (ILookupParameter)Parameters[ValidationPartitionParameterName]; } } public ILookupParameter EvaluatorParameter { get { return (ILookupParameter)Parameters[EvaluatorParameterName]; } } public ILookupParameter SymbolicExpressionTreeInterpreter { get { return (ILookupParameter)Parameters[SymbolicExpressionTreeInterpreterParameterName]; } } public override IDeepCloneable Clone(Cloner cloner) { return new SlidingWindowQualitiesAnalyzer(this, cloner); } private SlidingWindowQualitiesAnalyzer(SlidingWindowQualitiesAnalyzer original, Cloner cloner) : base(original, cloner) { } [StorableConstructor] private SlidingWindowQualitiesAnalyzer(bool deserializing) : base(deserializing) { } public SlidingWindowQualitiesAnalyzer() { Parameters.Add(new ValueLookupParameter(ProblemDataParameterName, "The problem data on which the symbolic data analysis solution should be evaluated.")); Parameters.Add(new LookupParameter(EvaluatorParameterName, "")); Parameters.Add(new LookupParameter(FitnessCalculationPartitionParameterName, "")); Parameters.Add(new LookupParameter(SymbolicExpressionTreeInterpreterParameterName, "")); ProblemDataParameter.Hidden = true; } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { } public override IOperation Apply() { if (FitnessCalculationPartitionParameter.ActualValue == null) // do nothing because the sliding window hasn't been initialized yet return base.Apply(); var results = ResultCollectionParameter.ActualValue; if (!results.ContainsKey("Best training solution")) return base.Apply(); var problemData = (IRegressionProblemData)ProblemDataParameter.ActualValue; var evaluator = (SymbolicDataAnalysisSingleObjectiveEvaluator)EvaluatorParameter.ActualValue; var context = new Core.ExecutionContext(ExecutionContext, evaluator, new Scope()); var fitnessCalculationPartition = FitnessCalculationPartitionParameter.ActualValue; var bestSolution = (ISymbolicDataAnalysisSolution)results["Best training solution"].Value; var bestModel = bestSolution.Model; var bestTree = bestModel.SymbolicExpressionTree; // add result if (!results.ContainsKey(SlidingWindowQualitiesResultName)) { results.Add(new Result(SlidingWindowQualitiesResultName, new DataTable(SlidingWindowQualitiesResultName))); } var swQualitiesTable = (DataTable)results[SlidingWindowQualitiesResultName].Value; // compute before quality var beforeQuality = 0.0; if (!swQualitiesTable.Rows.ContainsKey("Before Quality")) swQualitiesTable.Rows.Add(new DataRow("Before Quality") { VisualProperties = { StartIndexZero = true } }); if (fitnessCalculationPartition.Start > problemData.TrainingPartition.Start) { var beforeRange = new IntRange(problemData.TrainingPartition.Start, fitnessCalculationPartition.Start); beforeQuality = evaluator.Evaluate(context, bestTree, problemData, Enumerable.Range(beforeRange.Start, beforeRange.Size)); } swQualitiesTable.Rows["Before Quality"].Values.Add(beforeQuality); // compute current quality var currentQuality = ((DoubleValue)results["CurrentBestQuality"].Value).Value; if (!swQualitiesTable.Rows.ContainsKey("Current Quality")) swQualitiesTable.Rows.Add(new DataRow("Current Quality") { VisualProperties = { StartIndexZero = true } }); swQualitiesTable.Rows["Current Quality"].Values.Add(currentQuality); // compute after quality if (fitnessCalculationPartition.End < problemData.TrainingPartition.End) { var afterRange = new IntRange(fitnessCalculationPartition.End, problemData.TrainingPartition.End); var afterQuality = evaluator.Evaluate(context, bestTree, problemData, Enumerable.Range(afterRange.Start, afterRange.Size)); if (!swQualitiesTable.Rows.ContainsKey("After Quality")) swQualitiesTable.Rows.Add(new DataRow("After Quality") { VisualProperties = { StartIndexZero = true } }); swQualitiesTable.Rows["After Quality"].Values.Add(afterQuality); } // compute test quality if (!swQualitiesTable.Rows.ContainsKey("Test Quality")) swQualitiesTable.Rows.Add(new DataRow("Test Quality") { VisualProperties = { StartIndexZero = true } }); var regressionSolution = (IRegressionSolution)bestSolution; swQualitiesTable.Rows["Test Quality"].Values.Add(regressionSolution.TestRSquared); return base.Apply(); } public override bool EnabledByDefault { get { return false; } } } }