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; }
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())); }
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); } }