public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows, IntRange evaluationPartition, int horizon, bool applyLinearScaling) {
      var horizions = rows.Select(r => Math.Min(horizon, evaluationPartition.End - r));
      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows.Zip(horizions, Enumerable.Range).SelectMany(r => r));
      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows, horizions).SelectMany(x => x);
      OnlineCalculatorError errorState;

      double mse;
      if (applyLinearScaling && horizon == 1) { //perform normal evaluation and afterwards scale the solution and calculate the fitness value        
        var mseCalculator = new OnlineMeanSquaredErrorCalculator();
        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, mseCalculator, problemData.Dataset.Rows * horizon);
        errorState = mseCalculator.ErrorState;
        mse = mseCalculator.MeanSquaredError;
      } else if (applyLinearScaling) { //first create model to perform linear scaling and afterwards calculate fitness for the scaled model
        var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)solution.Clone(), interpreter, lowerEstimationLimit, upperEstimationLimit);
        model.Scale(problemData);
        var scaledSolution = model.SymbolicExpressionTree;
        estimatedValues = interpreter.GetSymbolicExpressionTreeValues(scaledSolution, problemData.Dataset, rows, horizions).SelectMany(x => x);
        var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
        mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
      } else {
        var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
        mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
      }

      if (errorState != OnlineCalculatorError.None) return Double.NaN;
      else return mse;
    }
    public static ISymbolicExpressionTree Prune(ISymbolicExpressionTree tree, SymbolicRegressionSolutionImpactValuesCalculator impactValuesCalculator, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IRegressionProblemData problemData, DoubleLimit estimationLimits, IEnumerable<int> rows, double nodeImpactThreshold = 0.0, bool pruneOnlyZeroImpactNodes = false) {
      var clonedTree = (ISymbolicExpressionTree)tree.Clone();
      var model = new SymbolicRegressionModel(problemData.TargetVariable, clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
      var nodes = clonedTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList(); // skip the nodes corresponding to the ProgramRootSymbol and the StartSymbol

      double qualityForImpactsCalculation = double.NaN; // pass a NaN value initially so the impact calculator will calculate the quality

      for (int i = 0; i < nodes.Count; ++i) {
        var node = nodes[i];
        if (node is ConstantTreeNode) continue;

        double impactValue, replacementValue;
        double newQualityForImpactsCalculation;
        impactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, out newQualityForImpactsCalculation, qualityForImpactsCalculation);

        if (pruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0)) continue;
        if (!pruneOnlyZeroImpactNodes && impactValue > nodeImpactThreshold) continue;

        var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode();
        constantNode.Value = replacementValue;

        ReplaceWithConstant(node, constantNode);
        i += node.GetLength() - 1; // skip subtrees under the node that was folded

        qualityForImpactsCalculation = newQualityForImpactsCalculation;
      }
      return model.SymbolicExpressionTree;
    }
Beispiel #3
0
        protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality)
        {
            var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);

            if (ApplyLinearScalingParameter.ActualValue.Value)
            {
                model.Scale(ProblemDataParameter.ActualValue);
            }
            return(new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone()));
        }
        public static bool CreateNewArgument(
            IRandom random,
            ISymbolicExpressionTree symbolicExpressionTree,
            int maxTreeLength, int maxTreeDepth,
            int maxFunctionDefinitions, int maxFunctionArguments)
        {
            // work on a copy in case we find out later that the tree would be too big
            // in this case it's easiest to simply return the original tree.
            ISymbolicExpressionTree clonedTree = (ISymbolicExpressionTree)symbolicExpressionTree.Clone();

            var functionDefiningBranches = clonedTree.IterateNodesPrefix().OfType <DefunTreeNode>().ToList();

            if (!functionDefiningBranches.Any())
            {
                // no function defining branch found => abort
                return(false);
            }

            // select a random function defining branch
            var selectedDefunBranch = functionDefiningBranches.SampleRandom(random);

            var definedArguments = (from symbol in selectedDefunBranch.Grammar.Symbols.OfType <Argument>()
                                    select symbol.ArgumentIndex).Distinct();

            if (definedArguments.Count() >= maxFunctionArguments)
            {
                // max number of arguments reached => abort
                return(false);
            }

            var allowedArgumentIndexes       = Enumerable.Range(0, maxFunctionArguments);
            var newArgumentIndex             = allowedArgumentIndexes.Except(definedArguments).First();
            ArgumentTreeNode newArgumentNode = MakeArgumentNode(newArgumentIndex);

            // this operation potentially creates very big trees so the access to the length property might throw overflow exception
            try {
                if (CreateNewArgumentForDefun(random, clonedTree, selectedDefunBranch, newArgumentNode) && clonedTree.Length <= maxTreeLength && clonedTree.Depth <= maxTreeDepth)
                {
                    // size constraints are fulfilled
                    // replace root of original tree with root of manipulated tree
                    symbolicExpressionTree.Root = clonedTree.Root;
                    return(true);
                }
                else
                {
                    // keep originalTree
                    return(false);
                }
            }
            catch (OverflowException) {
                // keep original tree
                return(false);
            }
        }
    public static bool CreateNewArgument(
      IRandom random,
      ISymbolicExpressionTree symbolicExpressionTree,
      int maxTreeLength, int maxTreeDepth,
      int maxFunctionDefinitions, int maxFunctionArguments) {
      // work on a copy in case we find out later that the tree would be too big
      // in this case it's easiest to simply return the original tree.
      ISymbolicExpressionTree clonedTree = (ISymbolicExpressionTree)symbolicExpressionTree.Clone();

      var functionDefiningBranches = clonedTree.IterateNodesPrefix().OfType<DefunTreeNode>().ToList();
      if (!functionDefiningBranches.Any())
        // no function defining branch found => abort
        return false;

      // select a random function defining branch
      var selectedDefunBranch = functionDefiningBranches.SampleRandom(random);

      var definedArguments = (from symbol in selectedDefunBranch.Grammar.Symbols.OfType<Argument>()
                              select symbol.ArgumentIndex).Distinct();
      if (definedArguments.Count() >= maxFunctionArguments)
        // max number of arguments reached => abort
        return false;

      var allowedArgumentIndexes = Enumerable.Range(0, maxFunctionArguments);
      var newArgumentIndex = allowedArgumentIndexes.Except(definedArguments).First();
      ArgumentTreeNode newArgumentNode = MakeArgumentNode(newArgumentIndex);

      // this operation potentially creates very big trees so the access to the length property might throw overflow exception
      try {
        if (CreateNewArgumentForDefun(random, clonedTree, selectedDefunBranch, newArgumentNode) && clonedTree.Length <= maxTreeLength && clonedTree.Depth <= maxTreeDepth) {

          // size constraints are fulfilled 
          // replace root of original tree with root of manipulated tree
          symbolicExpressionTree.Root = clonedTree.Root;
          return true;
        } else {
          // keep originalTree
          return false;
        }
      }
      catch (OverflowException) {
        // keep original tree
        return false;
      }
    }
        public static ISymbolicExpressionTree Prune(ISymbolicExpressionTree tree, ISymbolicClassificationModelCreator modelCreator,
                                                    SymbolicClassificationSolutionImpactValuesCalculator impactValuesCalculator, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
                                                    IClassificationProblemData problemData, DoubleLimit estimationLimits, IEnumerable <int> rows,
                                                    double nodeImpactThreshold = 0.0, bool pruneOnlyZeroImpactNodes = false)
        {
            var clonedTree = (ISymbolicExpressionTree)tree.Clone();
            var model      = modelCreator.CreateSymbolicClassificationModel(clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);

            var    nodes = clonedTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
            double qualityForImpactsCalculation = double.NaN;

            for (int i = 0; i < nodes.Count; ++i)
            {
                var node = nodes[i];
                if (node is ConstantTreeNode)
                {
                    continue;
                }

                double impactValue, replacementValue, newQualityForImpactsCalculation;
                impactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, out newQualityForImpactsCalculation, qualityForImpactsCalculation);

                if (pruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0))
                {
                    continue;
                }
                if (!pruneOnlyZeroImpactNodes && impactValue > nodeImpactThreshold)
                {
                    continue;
                }

                var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode();
                constantNode.Value = replacementValue;

                ReplaceWithConstant(node, constantNode);
                i += node.GetLength() - 1; // skip subtrees under the node that was folded

                qualityForImpactsCalculation = newQualityForImpactsCalculation;
            }
            return(model.SymbolicExpressionTree);
        }
        protected override ISymbolicTimeSeriesPrognosisSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality)
        {
            var model = new SymbolicTimeSeriesPrognosisModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);

            if (ApplyLinearScalingParameter.ActualValue.Value)
            {
                model.Scale(ProblemDataParameter.ActualValue);
            }
            return(new SymbolicTimeSeriesPrognosisSolution(model, (ITimeSeriesPrognosisProblemData)ProblemDataParameter.ActualValue.Clone()));
        }
Beispiel #8
0
        protected override ISymbolicClassificationSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality)
        {
            var model = ModelCreatorParameter.ActualValue.CreateSymbolicClassificationModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);

            if (ApplyLinearScalingParameter.ActualValue.Value)
            {
                model.Scale(ProblemDataParameter.ActualValue);
            }

            model.RecalculateModelParameters(ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TrainingIndices);
            return(model.CreateClassificationSolution((IClassificationProblemData)ProblemDataParameter.ActualValue.Clone()));
        }
        protected override ISolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality)
        {
            var model = new Model((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue);

            return(new SymbolicSolution(model, (IProblemData)ProblemDataParameter.ActualValue.Clone()));
        }
        public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable <int> rows, IntRange evaluationPartition, int horizon, bool applyLinearScaling)
        {
            var horizions = rows.Select(r => Math.Min(horizon, evaluationPartition.End - r));
            IEnumerable <double>  targetValues    = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows.Zip(horizions, Enumerable.Range).SelectMany(r => r));
            IEnumerable <double>  estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows, horizions).SelectMany(x => x);
            OnlineCalculatorError errorState;

            double mse;

            if (applyLinearScaling && horizon == 1) //perform normal evaluation and afterwards scale the solution and calculate the fitness value
            {
                var mseCalculator = new OnlineMeanSquaredErrorCalculator();
                CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, mseCalculator, problemData.Dataset.Rows * horizon);
                errorState = mseCalculator.ErrorState;
                mse        = mseCalculator.MeanSquaredError;
            }
            else if (applyLinearScaling) //first create model to perform linear scaling and afterwards calculate fitness for the scaled model
            {
                var model = new SymbolicTimeSeriesPrognosisModel(problemData.TargetVariable, (ISymbolicExpressionTree)solution.Clone(), interpreter, lowerEstimationLimit, upperEstimationLimit);
                model.Scale(problemData);
                var scaledSolution = model.SymbolicExpressionTree;
                estimatedValues = interpreter.GetSymbolicExpressionTreeValues(scaledSolution, problemData.Dataset, rows, horizions).SelectMany(x => x);
                var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
                mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
            }
            else
            {
                var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
                mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
            }

            if (errorState != OnlineCalculatorError.None)
            {
                return(Double.NaN);
            }
            else
            {
                return(mse);
            }
        }