#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; using System.Collections.Generic; using System.Linq; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Operators; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.DataAnalysis.Regression; using HeuristicLab.Problems.DataAnalysis.Symbolic; namespace HeuristicLab.Problems.DataAnalysis.MultiVariate.Regression.Symbolic.Evaluators { [StorableClass] public abstract class SymbolicVectorRegressionEvaluator : SingleSuccessorOperator, IMultiVariateDataAnalysisEvaluator { private const string RandomParameterName = "Random"; private const string MultiVariateDataAnalysisProblemDataParameterName = "MultiVariateDataAnalysisProblemData"; private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree"; private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter"; private const string SamplesStartParameterName = "SamplesStart"; private const string SamplesEndParameterName = "SamplesEnd"; private const string LowerEstimationLimitParameterName = "LowerEstimationLimit"; private const string UpperEstimationLimitParameterName = "UpperEstimationLimit"; private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples"; #region parameter properties public ILookupParameter RandomParameter { get { return (ILookupParameter)Parameters[RandomParameterName]; } } public ILookupParameter MultiVariateDataAnalysisProblemDataParameter { get { return (ILookupParameter)Parameters[MultiVariateDataAnalysisProblemDataParameterName]; } } public IValueLookupParameter SamplesStartParameter { get { return (IValueLookupParameter)Parameters[SamplesStartParameterName]; } } public IValueLookupParameter SamplesEndParameter { get { return (IValueLookupParameter)Parameters[SamplesEndParameterName]; } } public IValueLookupParameter LowerEstimationLimitParameter { get { return (IValueLookupParameter)Parameters[LowerEstimationLimitParameterName]; } } public IValueLookupParameter UpperEstimationLimitParameter { get { return (IValueLookupParameter)Parameters[UpperEstimationLimitParameterName]; } } public ILookupParameter SymbolicExpressionTreeParameter { get { return (ILookupParameter)Parameters[SymbolicExpressionTreeParameterName]; } } public ILookupParameter SymbolicExpressionTreeInterpreterParameter { get { return (ILookupParameter)Parameters[SymbolicExpressionTreeInterpreterParameterName]; } } public IValueParameter RelativeNumberOfEvaluatedSamplesParameter { get { return (IValueParameter)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; } } #endregion #region properties public IRandom Random { get { return RandomParameter.ActualValue; } } public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter { get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; } } public SymbolicExpressionTree SymbolicExpressionTree { get { return SymbolicExpressionTreeParameter.ActualValue; } } public MultiVariateDataAnalysisProblemData MultiVariateDataAnalysisProblemData { get { return MultiVariateDataAnalysisProblemDataParameter.ActualValue; } } public IntValue SamplesStart { get { return SamplesStartParameter.ActualValue; } } public IntValue SamplesEnd { get { return SamplesEndParameter.ActualValue; } } public DoubleArray LowerEstimationLimit { get { return LowerEstimationLimitParameter.ActualValue; } } public DoubleArray UpperEstimationLimit { get { return UpperEstimationLimitParameter.ActualValue; } } public PercentValue RelativeNumberOfEvaluatedSamples { get { return RelativeNumberOfEvaluatedSamplesParameter.Value; } } #endregion public SymbolicVectorRegressionEvaluator() : base() { Parameters.Add(new LookupParameter(RandomParameterName, "A random number generator.")); Parameters.Add(new LookupParameter(MultiVariateDataAnalysisProblemDataParameterName, "The multi-variate data analysis problem data to use for training.")); Parameters.Add(new LookupParameter(SymbolicExpressionTreeInterpreterParameterName, "The tree interpreter that should be used to evaluate the symbolic expression tree.")); Parameters.Add(new ValueLookupParameter(SamplesStartParameterName, "The first index of the data set partition to use for training.")); Parameters.Add(new ValueLookupParameter(SamplesEndParameterName, "The last index of the data set partition to use for training.")); Parameters.Add(new ValueLookupParameter(UpperEstimationLimitParameterName, "The upper limit for the estimated values for each component.")); Parameters.Add(new ValueLookupParameter(LowerEstimationLimitParameterName, "The lower limit for the estimated values for each component.")); Parameters.Add(new LookupParameter(SymbolicExpressionTreeParameterName, "The symbolic vector regression solution encoded as a symbolic expression tree.")); 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))); } public override IOperation Apply() { var interpreter = SymbolicExpressionTreeInterpreter; var tree = SymbolicExpressionTree; var problemData = MultiVariateDataAnalysisProblemData; IEnumerable selectedTargetVariables = problemData.TargetVariables.CheckedItems .Select(x => x.Value.Value); // check if there is a vector component for each target variable if (selectedTargetVariables.Count() != tree.Root.SubTrees[0].SubTrees.Count) throw new ArgumentException("The dimension of the output-vector of the tree doesn't match the number of selected target variables."); int start = SamplesStart.Value; int end = SamplesEnd.Value; IEnumerable rows = GenerateRowsToEvaluate((uint)Random.Next(), RelativeNumberOfEvaluatedSamples.Value, start, end); Evaluate(tree, interpreter, problemData, selectedTargetVariables, rows, LowerEstimationLimit, UpperEstimationLimit); return base.Apply(); } public abstract void Evaluate(SymbolicExpressionTree tree, ISymbolicExpressionTreeInterpreter interpreter, MultiVariateDataAnalysisProblemData problemData, IEnumerable targetVariables, IEnumerable rows, DoubleArray lowerEstimationBound, DoubleArray upperEstimationBound); private static IEnumerable GenerateRowsToEvaluate(uint seed, double relativeAmount, int start, int end) { if (end < start) throw new ArgumentException("Start value is larger than end value."); int count = (int)((end - start) * relativeAmount); if (count == 0) count = 1; return RandomEnumerable.SampleRandomNumbers(seed, start, end, count); } } }