using HEAL.Attic; using HeuristicLab.Algorithms.OESRALPS.Evaluators; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Problems.DataAnalysis; using HeuristicLab.Problems.DataAnalysis.Symbolic; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HeuristicLab.Algorithms.OESRALPS.Analyzers { [Item("SlidingWindowAnalyzer", "An analyzer which implements a sliding window.")] [StorableType("136DA41B-0AC1-49A8-B419-DCE93BDB7114")] public abstract class SlidingWindowAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer, ISlidingWindowAnalyzer, IIterationBasedOperator where T : class, ISymbolicDataAnalysisSingleObjectiveEvaluator where U : class, IDataAnalysisProblemData { private const string ProblemDataParameterName = "ProblemData"; private const string EvaluatorParameterName = "Evaluator"; private const string SlidingWindowSizeParameterName = "SlidingWindowSize"; private const string SlidingWindowStepWidthParameterName = "SlidingWindowStepWidth"; private const string StartSlidingWindowParameterName = "StartSlidingWindow"; private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition"; private const string TrainingPartitionParameterName = "TrainingPartition"; private const string TestPartitionParameterName = "TestPartition"; private const string ValidationPartitionParameterName = "ValidationPartition"; private const string IterationsParameterName = "Generations"; private const string MaximumIterationsParameterName = "MaximumIterations"; private const string MinimumIterationsUntilNextMoveParameterName = "MinimumIterationsUntilNextMove"; private const string LastSlidingWindowMoveIterationParameterName = "LastSlidingWindowMoveIteration"; private const string PredefinedTestsetParameterName = "PredefinedTestset"; private const string TerminateSlidingWindowParameterName = "TerminateSlidingWindow"; protected const double TrainingToValidationRatio = 2.0 / 3.0; #region parameter properties public ILookupParameter ProblemDataParameter { get { return (ILookupParameter)Parameters[ProblemDataParameterName]; } } public IFixedValueParameter SlidingWindowSizeParameter { get { return (IFixedValueParameter)Parameters[SlidingWindowSizeParameterName]; } } public IFixedValueParameter SlidingWindowStepWidthParameter { get { return (IFixedValueParameter)Parameters[SlidingWindowStepWidthParameterName]; } } public IFixedValueParameter StartSlidingWindowParameter { get { return (IFixedValueParameter)Parameters[StartSlidingWindowParameterName]; } } public ILookupParameter FitnessCalculationPartitionParameter { get { return (ILookupParameter)Parameters[FitnessCalculationPartitionParameterName]; } } public IValueLookupParameter TrainingPartitionParameter { get { return (IValueLookupParameter)Parameters[TrainingPartitionParameterName]; } } public IValueLookupParameter ValidationPartitionParameter { get { return (IValueLookupParameter)Parameters[ValidationPartitionParameterName]; } } public IValueLookupParameter TestPartitionParameter { get { return (IValueLookupParameter)Parameters[TestPartitionParameterName]; } } public ILookupParameter EvaluatorParameter { get { return (ILookupParameter)Parameters[EvaluatorParameterName]; } } public IValueParameter MinimumIterationsUntilNextMoveParameter { get { return (IValueParameter)Parameters[MinimumIterationsUntilNextMoveParameterName]; } } public ILookupParameter IterationsParameter { get { return (ILookupParameter)Parameters[IterationsParameterName]; } } public IValueLookupParameter MaximumIterationsParameter { get { return (IValueLookupParameter)Parameters[MaximumIterationsParameterName]; } } public IValueLookupParameter LastSlidingWindowMoveIterationParameter { get { return (IValueLookupParameter)Parameters[LastSlidingWindowMoveIterationParameterName]; } } public IFixedValueParameter PredefinedTestsetParameter { get { return (IFixedValueParameter)Parameters[PredefinedTestsetParameterName]; } } public ILookupParameter TerminateSlidingWindowParameter { get { return (ILookupParameter)Parameters[TerminateSlidingWindowParameterName]; } } #endregion #region properties public U ProblemData { get { return ProblemDataParameter.ActualValue; } } public IntValue SlidingWindowSize { get { return SlidingWindowSizeParameter.Value; } } public IntValue SlidingWindowStepWidth { get { return SlidingWindowStepWidthParameter.Value; } } public IntValue StartSlidingWindow { get { return StartSlidingWindowParameter.Value; } } public IntRange FitnessCalculationPartition { get { return FitnessCalculationPartitionParameter.ActualValue; } } public IntValue Iterations { get { return IterationsParameter.ActualValue; } } public IntValue MaximumIterations { get { return MaximumIterationsParameter.Value; } } public BoolValue PredefinedTestset { get { return PredefinedTestsetParameter.Value; } } public IntRange TrainingPartition { get { return TrainingPartitionParameter.ActualValue; } } public IntRange TestPartition { get { return TestPartitionParameter.ActualValue; } } #endregion [StorableConstructor] protected SlidingWindowAnalyzer(StorableConstructorFlag _) : base(_) { } protected SlidingWindowAnalyzer(SlidingWindowAnalyzer original, Cloner cloner) : base(original, cloner) { } public SlidingWindowAnalyzer() : base() { Parameters.Add(new LookupParameter(ProblemDataParameterName, "The problem data.")); Parameters.Add(new LookupParameter(EvaluatorParameterName, "")); Parameters.Add(new FixedValueParameter(SlidingWindowSizeParameterName, "The sliding window size.", new IntValue(400))); Parameters.Add(new FixedValueParameter(SlidingWindowStepWidthParameterName, "The number of steps by which the sliding window is moved.", new IntValue(10))); Parameters.Add(new FixedValueParameter(StartSlidingWindowParameterName, "The starting position of the sliding window.", new IntValue(0))); Parameters.Add(new LookupParameter(FitnessCalculationPartitionParameterName, "The current sliding window position or range.")); Parameters.Add(new ValueLookupParameter(TrainingPartitionParameterName, "The current training sliding window position or range.")); Parameters.Add(new ValueLookupParameter(ValidationPartitionParameterName, "The current validation sliding window position or range.")); Parameters.Add(new ValueLookupParameter(TestPartitionParameterName, "The current test sliding window position or range.")); Parameters.Add(new LookupParameter(IterationsParameterName, "The number of performed iterations.")); Parameters.Add(new ValueLookupParameter(MaximumIterationsParameterName, "The maximum number of performed iterations.") { Hidden = true }); Parameters.Add(new ValueParameter(MinimumIterationsUntilNextMoveParameterName, "The minimum number of iterations that have to pass before the next sliding window move.", new IntValue(1))); Parameters.Add(new ValueLookupParameter(LastSlidingWindowMoveIterationParameterName, "Iteration the sliding window has been moved the last time.") { Hidden = true }); Parameters.Add(new FixedValueParameter(PredefinedTestsetParameterName, "Indicates if a predefined split between training and test data is available.", new BoolValue(true))); Parameters.Add(new LookupParameter(TerminateSlidingWindowParameterName, "Indicates if sliding window reached end of training data.")); } public event EventHandler MoveWindow; public IOperation OnMoveWindow() { if (TrainingPartition == null) { TerminateSlidingWindowParameter.ActualValue.Value = false; InitializeSlidingWindow(StartSlidingWindow.Value, SlidingWindowSize.Value); return base.Apply(); } if (ValidationPartitionParameter.ActualValue.End + SlidingWindowStepWidth.Value > ProblemData.TestPartition.Start) { TerminateSlidingWindowParameter.ActualValue.Value = true; return base.Apply(); } if(!IsMinimumIterationIntervalPassed()) return base.Apply(); TrainingPartition.Start += SlidingWindowStepWidth.Value; TrainingPartition.End += SlidingWindowStepWidth.Value; if (!PredefinedTestsetParameter.Value.Value) { TestPartitionParameter.ActualValue.Start += SlidingWindowStepWidth.Value; TestPartitionParameter.ActualValue.End += SlidingWindowStepWidth.Value; } ValidationPartitionParameter.ActualValue.Start += SlidingWindowStepWidth.Value; ValidationPartitionParameter.ActualValue.End += SlidingWindowStepWidth.Value; FitnessCalculationPartitionParameter.ActualValue.Start = TrainingPartition.Start; FitnessCalculationPartitionParameter.ActualValue.End = TrainingPartition.End; LastSlidingWindowMoveIterationParameter.ActualValue.Value = IterationsParameter.ActualValue.Value; VisualizeSlidingWindow(); // Reevaluate all individuals with new sliding window UniformSubScopesProcessor subScopesProcessor = new UniformSubScopesProcessor(); subScopesProcessor.Operator = EvaluatorParameter.ActualValue; subScopesProcessor.Depth.Value = 2; var operation = ExecutionContext.CreateChildOperation(subScopesProcessor); var successor = base.Apply(); MoveWindow?.Invoke(this, EventArgs.Empty); return new OperationCollection() { operation, successor }; } protected void InitializeSlidingWindow(int startSlidingWindow, int slidingWindowSize) { if (startSlidingWindow + slidingWindowSize > ProblemData.Dataset.Rows) return; LastSlidingWindowMoveIterationParameter.ActualValue = new IntValue(IterationsParameter.ActualValue.Value); // Training partition is 66 percent of window size TrainingPartitionParameter.ActualValue = new IntRange( startSlidingWindow, startSlidingWindow + (int)(slidingWindowSize * TrainingToValidationRatio) ); if (PredefinedTestsetParameter.Value.Value) { // Validation partition is 33.3 percent of window size ValidationPartitionParameter.ActualValue.Start = TrainingPartitionParameter.ActualValue.End; ValidationPartitionParameter.ActualValue.End = TrainingPartitionParameter.ActualValue.Start + slidingWindowSize; } else { // Test partition is 16.6 percent of window size TestPartitionParameter.ActualValue = new IntRange( TrainingPartitionParameter.ActualValue.End, TrainingPartitionParameter.ActualValue.End + (int)((slidingWindowSize - TrainingPartitionParameter.ActualValue.End) * 0.5) ); // Validation partition is 16.6 percent of window size ValidationPartitionParameter.ActualValue.Start = TestPartitionParameter.ActualValue.End; ValidationPartitionParameter.ActualValue.End = TrainingPartitionParameter.ActualValue.Start + slidingWindowSize; } FitnessCalculationPartitionParameter.ActualValue.Start = TrainingPartitionParameter.ActualValue.Start; FitnessCalculationPartitionParameter.ActualValue.End = TrainingPartitionParameter.ActualValue.End; VisualizeSlidingWindow(); return; } protected void VisualizeSlidingWindow() { var results = ResultCollection; if (!results.ContainsKey(TrainingPartitionParameterName)) results.Add(new Result(TrainingPartitionParameterName, TrainingPartitionParameter.ActualValue)); else results[TrainingPartitionParameterName].Value = TrainingPartitionParameter.ActualValue; if (!results.ContainsKey(TestPartitionParameterName)) results.Add(new Result(TestPartitionParameterName, TestPartitionParameter.ActualValue)); else results[TestPartitionParameterName].Value = TestPartitionParameter.ActualValue; if (!results.ContainsKey(ValidationPartitionParameterName)) results.Add(new Result(ValidationPartitionParameterName, ValidationPartitionParameter.ActualValue)); else results[ValidationPartitionParameterName].Value = ValidationPartitionParameter.ActualValue; } protected bool IsMinimumIterationIntervalPassed() { return IterationsParameter.ActualValue.Value - LastSlidingWindowMoveIterationParameter.ActualValue.Value >= MinimumIterationsUntilNextMoveParameter.Value.Value; } } }