protected SymbolicDataAnalysisModel(SymbolicDataAnalysisModel original, Cloner cloner) : base(original, cloner) { this.symbolicExpressionTree = cloner.Clone(original.symbolicExpressionTree); this.interpreter = cloner.Clone(original.interpreter); this.lowerEstimationLimit = original.lowerEstimationLimit; this.upperEstimationLimit = original.upperEstimationLimit; }
protected override Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>> CalculateImpactAndReplacementValues(ISymbolicExpressionTree tree) { var interpreter = Content.Model.Interpreter; var rows = Content.ProblemData.TrainingIndices; var dataset = Content.ProblemData.Dataset; var targetVariable = Content.ProblemData.TargetVariable; var targetValues = dataset.GetDoubleValues(targetVariable, rows); var originalOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows).ToArray(); var impactAndReplacementValues = new Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>>(); List<ISymbolicExpressionTreeNode> nodes = tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPostfix().ToList(); OnlineCalculatorError errorState; double originalR = OnlinePearsonsRCalculator.Calculate(targetValues, originalOutput, out errorState); if (errorState != OnlineCalculatorError.None) originalR = 0.0; foreach (ISymbolicExpressionTreeNode node in nodes) { var parent = node.Parent; constantNode.Value = CalculateReplacementValue(node, tree); ISymbolicExpressionTreeNode replacementNode = constantNode; SwitchNode(parent, node, replacementNode); var newOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows); double newR = OnlinePearsonsRCalculator.Calculate(targetValues, newOutput, out errorState); if (errorState != OnlineCalculatorError.None) newR = 0.0; // impact = 0 if no change // impact < 0 if new solution is better // impact > 0 if new solution is worse double impact = (originalR * originalR) - (newR * newR); impactAndReplacementValues[node] = new Tuple<double, double>(impact, constantNode.Value); SwitchNode(parent, replacementNode, node); } return impactAndReplacementValues; }
public static Instruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, IEnumerable<Func<Instruction, Instruction>> postInstructionCompiledHooks) { Dictionary<string, ushort> entryPoint = new Dictionary<string, ushort>(); List<Instruction> code = new List<Instruction>(); // compile main body branches foreach (var branch in tree.Root.GetSubtree(0).Subtrees) { code.AddRange(Compile(branch, opCodeMapper, postInstructionCompiledHooks)); } // compile function branches var functionBranches = from node in tree.IterateNodesPrefix() where node.Symbol is Defun select node; foreach (DefunTreeNode branch in functionBranches) { if (code.Count > ushort.MaxValue) throw new ArgumentException("Code for the tree is too long (> ushort.MaxValue)."); entryPoint[branch.FunctionName] = (ushort)code.Count; code.AddRange(Compile(branch.GetSubtree(0), opCodeMapper, postInstructionCompiledHooks)); } // address of all functions is fixed now // iterate through code again and fill in the jump locations for (int i = 0; i < code.Count; i++) { Instruction instr = code[i]; if (instr.dynamicNode.Symbol is InvokeFunction) { var invokeNode = (InvokeFunctionTreeNode)instr.dynamicNode; instr.data = entryPoint[invokeNode.Symbol.FunctionName]; } } return code.ToArray(); }
public Interpreter(ISymbolicExpressionTree tree, BoolMatrix world, int maxTimeSteps) { this.Expression = tree; this.MaxTimeSteps = maxTimeSteps; // create a clone of the world because the ant will remove the food items it can find. World = (BoolMatrix)world.Clone(); CountFoodItems(); }
protected override void Manipulate(IRandom random, ISymbolicExpressionTree tree) { tree.Root.ForEachNodePostfix(node => { if (node.HasLocalParameters) { node.ShakeLocalParameters(random, ShakingFactor); } }); }
public SymbolicDiscriminantFunctionClassificationModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDiscriminantFunctionThresholdCalculator thresholdCalculator, double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue) : base(tree, interpreter, lowerEstimationLimit, upperEstimationLimit) { this.thresholds = new double[0]; this.classValues = new double[0]; this.ThresholdCalculator = thresholdCalculator; }
protected override ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataAnalysisProblemData problemData, DoubleLimit estimationLimits) { var model = ModelCreatorParameter.ActualValue.CreateSymbolicClassificationModel(tree, interpreter, estimationLimits.Lower, estimationLimits.Upper); var classificationProblemData = (IClassificationProblemData)problemData; var rows = classificationProblemData.TrainingIndices; model.RecalculateModelParameters(classificationProblemData, rows); return model; }
public Solution(ISymbolicExpressionTree tree, int length, int width, double quality) : base("Solution", "A lawn mower solution.") { this.Tree = tree; this.Length = length; this.Width = width; this.Quality = quality; }
public Solution(ISymbolicExpressionTree tree, string path, int nrOfRounds, EnemyCollection enemies) : base() { this.Tree = tree; this.Path = path; this.NrOfRounds = nrOfRounds; this.Enemies = enemies; }
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; }
public static void RemoveRandomBranch(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, int maxTreeLength, int maxTreeDepth) { var allowedSymbols = new List<ISymbol>(); ISymbolicExpressionTreeNode parent; int childIndex; int maxLength; int maxDepth; // repeat until a fitting parent and child are found (MAX_TRIES times) int tries = 0; var nodes = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).ToList(); do { parent = nodes.SampleRandom(random); childIndex = random.Next(parent.SubtreeCount); var child = parent.GetSubtree(childIndex); maxLength = maxTreeLength - symbolicExpressionTree.Length + child.GetLength(); maxDepth = maxTreeDepth - symbolicExpressionTree.Root.GetBranchLevel(child); allowedSymbols.Clear(); foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex)) { // check basic properties that the new symbol must have if ((symbol.Name != child.Symbol.Name || symbol.MinimumArity > 0) && symbol.InitialFrequency > 0 && parent.Grammar.GetMinimumExpressionDepth(symbol) <= maxDepth && parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength) { allowedSymbols.Add(symbol); } } tries++; } while (tries < MAX_TRIES && allowedSymbols.Count == 0); if (tries >= MAX_TRIES) return; ReplaceWithMinimalTree(random, symbolicExpressionTree.Root, parent, childIndex); }
public static bool DeleteSubroutine( IRandom random, ISymbolicExpressionTree symbolicExpressionTree, int maxFunctionDefinitions, int maxFunctionArguments) { var functionDefiningBranches = symbolicExpressionTree.IterateNodesPrefix().OfType<DefunTreeNode>().ToList(); if (!functionDefiningBranches.Any()) // no ADF to delete => abort return false; var selectedDefunBranch = functionDefiningBranches.SampleRandom(random); // remove the selected defun int defunSubtreeIndex = symbolicExpressionTree.Root.IndexOfSubtree(selectedDefunBranch); symbolicExpressionTree.Root.RemoveSubtree(defunSubtreeIndex); // remove references to deleted function foreach (var subtree in symbolicExpressionTree.Root.Subtrees.OfType<SymbolicExpressionTreeTopLevelNode>()) { var matchingInvokeSymbol = (from symb in subtree.Grammar.Symbols.OfType<InvokeFunction>() where symb.FunctionName == selectedDefunBranch.FunctionName select symb).SingleOrDefault(); if (matchingInvokeSymbol != null) { subtree.Grammar.RemoveSymbol(matchingInvokeSymbol); } } DeletionByRandomRegeneration(random, symbolicExpressionTree, selectedDefunBranch); return true; }
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 double CalculateSimilarity(ISymbolicExpressionTree t1, ISymbolicExpressionTree t2) { if (t1 == t2) return 1; var map = ComputeBottomUpMapping(t1.Root, t2.Root); return 2.0 * map.Count / (t1.Length + t2.Length); }
public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, IProblemData problemData, IEnumerable<int> rows) { IEnumerable<double> signals = GetSignals(interpreter, solution, problemData.Dataset, rows); IEnumerable<double> returns = problemData.Dataset.GetDoubleValues(problemData.PriceChangeVariable, rows); OnlineCalculatorError errorState; double sharpRatio = OnlineSharpeRatioCalculator.Calculate(returns, signals, problemData.TransactionCosts, out errorState); if (errorState != OnlineCalculatorError.None) return 0.0; else return sharpRatio; }
public string Format(ISymbolicExpressionTree symbolicExpressionTree) { // skip root and start symbols StringBuilder strBuilder = new StringBuilder(); GenerateHeader(strBuilder, symbolicExpressionTree); FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0), strBuilder); GenerateFooter(strBuilder); return strBuilder.ToString(); }
public string Format(ISymbolicExpressionTree symbolicExpressionTree) { int nodeCounter = 1; StringBuilder strBuilder = new StringBuilder(); strBuilder.AppendLine("graph {"); strBuilder.AppendLine(FormatRecursively(symbolicExpressionTree.Root, 0, ref nodeCounter)); strBuilder.AppendLine("}"); return strBuilder.ToString(); }
/// <summary> /// It is necessary to create new models of an unknown type with new trees in the simplifier. /// For this purpose the cloner is used by registering the new tree as already cloned object and invoking the clone mechanism. /// This results in a new model of the same type as the old one with an exchanged tree. /// </summary> /// <param name="tree">The new tree that should be included in the new object</param> /// <returns></returns> protected ISymbolicClassificationModel CreateModel(ISymbolicExpressionTree tree) { var cloner = new Cloner(); cloner.RegisterClonedObject(Content.Model.SymbolicExpressionTree, tree); var model = (ISymbolicClassificationModel)Content.Model.Clone(cloner); model.RecalculateModelParameters(Content.ProblemData, Content.ProblemData.TrainingIndices); return model; }
public ISymbolicExpressionTree Simplify(ISymbolicExpressionTree originalTree) { var clone = (ISymbolicExpressionTreeNode)originalTree.Root.Clone(); // macro expand (initially no argument trees) var macroExpandedTree = MacroExpand(clone, clone.GetSubtree(0), new List<ISymbolicExpressionTreeNode>()); ISymbolicExpressionTreeNode rootNode = (new ProgramRootSymbol()).CreateTreeNode(); rootNode.AddSubtree(GetSimplifiedTree(macroExpandedTree)); return new SymbolicExpressionTree(rootNode); }
public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) { var mse = SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling); if (decimalPlaces >= 0) mse = Math.Round(mse, decimalPlaces); return new double[2] { mse, solution.Length }; }
public sealed override IOperation InstrumentedApply() { if (Parents.Length != 2) throw new ArgumentException("Number of parents must be exactly two for symbolic expression tree crossover operators."); ISymbolicExpressionTree result = Crossover(RandomParameter.ActualValue, Parents[0], Parents[1]); Child = result; return base.InstrumentedApply(); }
public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable<int> rows) { IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows); IEnumerable<double> originalValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows); IEnumerable<double> boundedEstimationValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit); OnlineCalculatorError errorState; double mse = OnlineMeanSquaredErrorCalculator.Calculate(originalValues, boundedEstimationValues, out errorState); if (errorState != OnlineCalculatorError.None) mse = double.NaN; return new double[2] { mse, solution.Length }; }
protected override Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>> CalculateImpactAndReplacementValues(ISymbolicExpressionTree tree) { var impactAndReplacementValues = new Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>>(); foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix()) { double impactValue, replacementValue, newQualityForImpactsCalculation; calculator.CalculateImpactAndReplacementValues(Content.Model, node, Content.ProblemData, Content.ProblemData.TrainingIndices, out impactValue, out replacementValue, out newQualityForImpactsCalculation); impactAndReplacementValues.Add(node, new Tuple<double, double>(impactValue, replacementValue)); } return impactAndReplacementValues; }
public static bool[,] EvaluateLawnMowerProgram(int length, int width, ISymbolicExpressionTree tree) { bool[,] lawn = new bool[length, width]; var mowerState = new MowerState(); mowerState.Heading = Heading.South; mowerState.Energy = length * width * 2; lawn[mowerState.Position.Item1, mowerState.Position.Item2] = true; EvaluateLawnMowerProgram(tree.Root, mowerState, lawn, tree.Root.Subtrees.Skip(1).ToArray()); return lawn; }
protected SymbolicDataAnalysisModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, double lowerEstimationLimit, double upperEstimationLimit) : base() { this.name = ItemName; this.description = ItemDescription; this.symbolicExpressionTree = tree; this.interpreter = interpreter; this.lowerEstimationLimit = lowerEstimationLimit; this.upperEstimationLimit = upperEstimationLimit; }
public static void Shake(IRandom random, ISymbolicExpressionTree tree, double shakingFactor) { List<ISymbolicExpressionTreeNode> parametricNodes = new List<ISymbolicExpressionTreeNode>(); tree.Root.ForEachNodePostfix(n => { if (n.HasLocalParameters) parametricNodes.Add(n); }); if (parametricNodes.Count > 0) { var selectedPoint = parametricNodes.SampleRandom(random); selectedPoint.ShakeLocalParameters(random, shakingFactor); } }
public CFGSolution(ISymbolicExpressionTree tree, ICFGProblemData problemData) : base() { name = ItemName; description = ItemDescription; Add(new Result(ModelLengthResultName, "Length of the symbolic regression model.", new IntValue(tree.Length))); Add(new Result(ModelDepthResultName, "Depth of the symbolic regression model.", new IntValue(tree.Depth))); Add(new Result(ModelResultName, "The CFG model.", tree)); }
private void ApplyBacktransformation(ITransformation transformation, ISymbolicExpressionTree symbolicExpressionTree, string targetVariable) { if (transformation.Column != targetVariable) { var variableNodes = symbolicExpressionTree.IterateNodesBreadth() .OfType<VariableTreeNode>() .Where(n => n.VariableName == transformation.Column); ApplyRegularBacktransformation(transformation, variableNodes); } else if (!(transformation is CopyColumnTransformation)) { ApplyInverseBacktransformation(transformation, symbolicExpressionTree); } }
public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows) { SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context; EstimationLimitsParameter.ExecutionContext = context; double mlr = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows); SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null; EstimationLimitsParameter.ExecutionContext = null; return mlr; }
public static void ChangeNodeType(IRandom random, ISymbolicExpressionTree symbolicExpressionTree) { List<ISymbol> allowedSymbols = new List<ISymbol>(); ISymbolicExpressionTreeNode parent; int childIndex; ISymbolicExpressionTreeNode child; // repeat until a fitting parent and child are found (MAX_TRIES times) int tries = 0; do { #pragma warning disable 612, 618 parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random); #pragma warning restore 612, 618 childIndex = random.Next(parent.SubtreeCount); child = parent.GetSubtree(childIndex); int existingSubtreeCount = child.SubtreeCount; allowedSymbols.Clear(); foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex)) { // check basic properties that the new symbol must have if (symbol.Name != child.Symbol.Name && symbol.InitialFrequency > 0 && existingSubtreeCount <= parent.Grammar.GetMinimumSubtreeCount(symbol) && existingSubtreeCount >= parent.Grammar.GetMaximumSubtreeCount(symbol)) { // check that all existing subtrees are also allowed for the new symbol bool allExistingSubtreesAllowed = true; for (int existingSubtreeIndex = 0; existingSubtreeIndex < existingSubtreeCount && allExistingSubtreesAllowed; existingSubtreeIndex++) { var existingSubtree = child.GetSubtree(existingSubtreeIndex); allExistingSubtreesAllowed &= parent.Grammar.IsAllowedChildSymbol(symbol, existingSubtree.Symbol, existingSubtreeIndex); } if (allExistingSubtreesAllowed) { allowedSymbols.Add(symbol); } } } tries++; } while (tries < MAX_TRIES && allowedSymbols.Count == 0); if (tries < MAX_TRIES) { var weights = allowedSymbols.Select(s => s.InitialFrequency).ToList(); #pragma warning disable 612, 618 var newSymbol = allowedSymbols.SelectRandom(weights, random); #pragma warning restore 612, 618 // replace the old node with the new node var newNode = newSymbol.CreateTreeNode(); if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random); foreach (var subtree in child.Subtrees) newNode.AddSubtree(subtree); parent.RemoveSubtree(childIndex); parent.InsertSubtree(childIndex, newNode); } }
protected override void Manipulate(IRandom random, ISymbolicExpressionTree symbolicExpressionTree) { ChangeNodeType(random, symbolicExpressionTree); }
public static double CalculateComplexity(ISymbolicExpressionTree tree) { return(CalculateComplexity(tree.Root)); }
public string Format(ISymbolicExpressionTree symbolicExpressionTree) { return(FormatRecursively(symbolicExpressionTree.Root)); }
protected override Dictionary <ISymbolicExpressionTreeNode, double> CalculateImpactValues(ISymbolicExpressionTree tree) { var values = CalculateImpactAndReplacementValues(tree); return(values.ToDictionary(x => x.Key, x => x.Value.Item1)); }
public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable <int> rows, bool applyLinearScaling, int decimalPlaces) { double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling); if (decimalPlaces >= 0) { r2 = Math.Round(r2, decimalPlaces); } return(new double[2] { r2, solution.Length }); }
public SymbolicExpressionTreeChart(ISymbolicExpressionTree tree) : this() { this.Tree = tree; }
public SymbolicDiscriminantFunctionClassificationModel(string targetVariable, ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDiscriminantFunctionThresholdCalculator thresholdCalculator, double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue) : base(targetVariable, tree, interpreter, lowerEstimationLimit, upperEstimationLimit) { this.thresholds = new double[0]; this.classValues = new double[0]; this.ThresholdCalculator = thresholdCalculator; }
// Does not produce the same result for the same seed when using parallel engine (see below)! public override double Evaluate(ISymbolicExpressionTree tree, IRandom random) { var meanFunction = new MeanConst(); var problemData = ProblemData; var ds = problemData.Dataset; var targetVariable = problemData.TargetVariable; var allowedInputVariables = problemData.AllowedInputVariables.ToArray(); var nVars = allowedInputVariables.Length; var trainingRows = problemData.TrainingIndices.ToArray(); // use the same covariance function for each restart var covarianceFunction = TreeToCovarianceFunction(tree); // allocate hyperparameters var hyperParameters = new double[meanFunction.GetNumberOfParameters(nVars) + covarianceFunction.GetNumberOfParameters(nVars) + 1]; // mean + cov + noise double[] bestHyperParameters = new double[hyperParameters.Length]; var bestObjValue = new double[1] { double.MinValue }; // data that is necessary for the objective function var data = Tuple.Create(ds, targetVariable, allowedInputVariables, trainingRows, (IMeanFunction)meanFunction, covarianceFunction, bestObjValue); for (int t = 0; t < Restarts; t++) { var prevBest = bestObjValue[0]; var prevBestHyperParameters = new double[hyperParameters.Length]; Array.Copy(bestHyperParameters, prevBestHyperParameters, bestHyperParameters.Length); // initialize hyperparameters hyperParameters[0] = ds.GetDoubleValues(targetVariable).Average(); // mean const // Evaluate might be called concurrently therefore access to random has to be synchronized. // However, results of multiple runs with the same seed will be different when using the parallel engine. lock (syncRoot) { for (int i = 0; i < covarianceFunction.GetNumberOfParameters(nVars); i++) { hyperParameters[1 + i] = random.NextDouble() * 2.0 - 1.0; } } hyperParameters[hyperParameters.Length - 1] = 1.0; // s² = exp(2), TODO: other inits better? // use alglib.bfgs for hyper-parameter optimization ... double epsg = 0; double epsf = 0.00001; double epsx = 0; double stpmax = 1; int maxits = ConstantOptIterations; alglib.mincgstate state; alglib.mincgreport rep; alglib.mincgcreate(hyperParameters, out state); alglib.mincgsetcond(state, epsg, epsf, epsx, maxits); alglib.mincgsetstpmax(state, stpmax); alglib.mincgoptimize(state, ObjectiveFunction, null, data); alglib.mincgresults(state, out bestHyperParameters, out rep); if (rep.terminationtype < 0) { // error -> restore previous best quality bestObjValue[0] = prevBest; Array.Copy(prevBestHyperParameters, bestHyperParameters, prevBestHyperParameters.Length); } } UpdateBestSoFar(bestObjValue[0], bestHyperParameters, meanFunction, covarianceFunction); return(bestObjValue[0]); }
private ICovarianceFunction TreeToCovarianceFunction(ISymbolicExpressionTree tree) { return(TreeToCovarianceFunction(tree.Root.GetSubtree(0).GetSubtree(0))); // skip programroot and startsymbol }
/// <summary> /// Takes two parent individuals P0 and P1. /// Randomly choose a node i from the first parent, then get a node j from the second parent that matches the semantic similarity criteria. /// </summary> public static ISymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, T problemData, List <int> rows, int maxDepth, int maxLength, DoubleRange range) { var crossoverPoints0 = new List <CutPoint>(); parent0.Root.ForEachNodePostfix((n) => { if (n.Parent != null && n.Parent != parent0.Root) { crossoverPoints0.Add(new CutPoint(n.Parent, n)); } }); var crossoverPoint0 = crossoverPoints0.SampleRandom(random); int level = parent0.Root.GetBranchLevel(crossoverPoint0.Child); int length = parent0.Root.GetLength() - crossoverPoint0.Child.GetLength(); var allowedBranches = new List <ISymbolicExpressionTreeNode>(); parent1.Root.ForEachNodePostfix((n) => { if (n.Parent != null && n.Parent != parent1.Root) { if (n.GetDepth() + level <= maxDepth && n.GetLength() + length <= maxLength && crossoverPoint0.IsMatchingPointType(n)) { allowedBranches.Add(n); } } }); if (allowedBranches.Count == 0) { return(parent0); } var dataset = problemData.Dataset; // create symbols in order to improvize an ad-hoc tree so that the child can be evaluated var rootSymbol = new ProgramRootSymbol(); var startSymbol = new StartSymbol(); var tree0 = CreateTreeFromNode(random, crossoverPoint0.Child, rootSymbol, startSymbol); List <double> estimatedValues0 = interpreter.GetSymbolicExpressionTreeValues(tree0, dataset, rows).ToList(); crossoverPoint0.Child.Parent = crossoverPoint0.Parent; // restore parent ISymbolicExpressionTreeNode selectedBranch = null; // pick the first node that fulfills the semantic similarity conditions foreach (var node in allowedBranches) { var parent = node.Parent; var tree1 = CreateTreeFromNode(random, node, startSymbol, rootSymbol); // this will affect node.Parent List <double> estimatedValues1 = interpreter.GetSymbolicExpressionTreeValues(tree1, dataset, rows).ToList(); node.Parent = parent; // restore parent OnlineCalculatorError errorState; double ssd = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedValues0, estimatedValues1, out errorState); if (range.Start <= ssd && ssd <= range.End) { selectedBranch = node; break; } } // perform the actual swap if (selectedBranch != null) { Swap(crossoverPoint0, selectedBranch); } return(parent0); }
public override ISymbolicExpressionTree Crossover(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1) { ISymbolicDataAnalysisExpressionTreeInterpreter interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue; List <int> rows = GenerateRowsToEvaluate().ToList(); T problemData = ProblemDataParameter.ActualValue; return(Cross(random, parent0, parent1, interpreter, problemData, rows, MaximumSymbolicExpressionTreeDepth.Value, MaximumSymbolicExpressionTreeLength.Value, SemanticSimilarityRange)); }
public override ISymbolicExpressionTree Crossover(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1) { return(Cross(random, parent0, parent1, InternalCrossoverPointProbability.Value, MaximumSymbolicExpressionTreeLength.Value, MaximumSymbolicExpressionTreeDepth.Value)); }
public SymbolicTimeSeriesPrognosisModel(ISymbolicExpressionTree tree, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, double lowerLimit = double.MinValue, double upperLimit = double.MaxValue) : base(tree, interpreter, lowerLimit, upperLimit) { }
private static IEnumerable <bool> Interpret(ISymbolicExpressionTree tree, IEnumerable <int> bs) { // skip programRoot and startSymbol return(InterpretRec(tree.Root.GetSubtree(0).GetSubtree(0), bs)); }
public string Format(ISymbolicExpressionTree symbolicExpressionTree) { return(Format(symbolicExpressionTree, NumberFormatInfo.InvariantInfo)); }
protected override void UpdateModel(ISymbolicExpressionTree tree) { var model = CreateModel(tree); Content.Model = (ISymbolicDiscriminantFunctionClassificationModel)model; }
protected override Dictionary <ISymbolicExpressionTreeNode, Tuple <double, double> > CalculateImpactAndReplacementValues(ISymbolicExpressionTree tree) { var impactAndReplacementValues = new Dictionary <ISymbolicExpressionTreeNode, Tuple <double, double> >(); foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix()) { double impactValue, replacementValue, newQualityForImpactsCalculation; calculator.CalculateImpactAndReplacementValues(Content.Model, node, Content.ProblemData, Content.ProblemData.TrainingIndices, out impactValue, out replacementValue, out newQualityForImpactsCalculation); impactAndReplacementValues.Add(node, new Tuple <double, double>(impactValue, replacementValue)); } return(impactAndReplacementValues); }
protected override void Manipulate(IRandom random, ISymbolicExpressionTree symbolicExpressionTree) { ReplaceRandomBranch(random, symbolicExpressionTree, MaximumSymbolicExpressionTreeLength.Value, MaximumSymbolicExpressionTreeDepth.Value); }
protected override Dictionary <ISymbolicExpressionTreeNode, double> CalculateReplacementValues(ISymbolicExpressionTree tree) { return(tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToDictionary( n => n, n => calculator.CalculateReplacementValue(Content.Model, n, Content.ProblemData, Content.ProblemData.TrainingIndices) )); }
protected abstract void Manipulate(IRandom random, ISymbolicExpressionTree symbolicExpressionTree);
public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable <int> rows, bool applyLinearScaling) { IEnumerable <double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows); IEnumerable <double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows); OnlineCalculatorError errorState; double r; if (applyLinearScaling) { var rCalculator = new OnlinePearsonsRCalculator(); CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, rCalculator, problemData.Dataset.Rows); errorState = rCalculator.ErrorState; r = rCalculator.R; } else { IEnumerable <double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit); r = OnlinePearsonsRCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState); } if (errorState != OnlineCalculatorError.None) { r = double.NaN; } return(new double[2] { r *r, solution.Length }); }
protected virtual Dictionary <ISymbolicExpressionTreeNode, Tuple <double, double> > CalculateImpactAndReplacementValues(ISymbolicExpressionTree tree) { var impactAndReplacementValues = new Dictionary <ISymbolicExpressionTreeNode, Tuple <double, double> >(); foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix()) { if (progress.ProgressState == ProgressState.StopRequested) { continue; } double impactValue, replacementValue, newQualityForImpactsCalculation; impactCalculator.CalculateImpactAndReplacementValues(Content.Model, node, Content.ProblemData, Content.ProblemData.TrainingIndices, out impactValue, out replacementValue, out newQualityForImpactsCalculation); double newProgressValue = progress.ProgressValue + 1.0 / (tree.Length - 2); progress.ProgressValue = Math.Min(newProgressValue, 1); impactAndReplacementValues.Add(node, new Tuple <double, double>(impactValue, replacementValue)); } return(impactAndReplacementValues); }
public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable <int> rows) { IEnumerable <double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows); IEnumerable <double> originalValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows); IEnumerable <double> boundedEstimationValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit); OnlineCalculatorError errorState; double mse = OnlineMeanSquaredErrorCalculator.Calculate(originalValues, boundedEstimationValues, out errorState); if (errorState != OnlineCalculatorError.None) { mse = double.NaN; } return(new double[2] { mse, solution.Length }); }
protected abstract T CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality);
private bool HasAtLeastOneAdf(ISymbolicExpressionTree tree) { return(tree.Root.Subtrees.Count() > 1); }
public override IOperation Apply() { var results = ResultCollection; #region create results if (!results.ContainsKey(TrainingBestSolutionParameter.Name)) { results.Add(new Result(TrainingBestSolutionParameter.Name, TrainingBestSolutionParameter.Description, typeof(T))); } if (!results.ContainsKey(TrainingBestSolutionQualityParameter.Name)) { results.Add(new Result(TrainingBestSolutionQualityParameter.Name, TrainingBestSolutionQualityParameter.Description, typeof(DoubleValue))); } if (!results.ContainsKey(TrainingBestSolutionGenerationParameter.Name) && IterationsParameter.ActualValue != null) { results.Add(new Result(TrainingBestSolutionGenerationParameter.Name, TrainingBestSolutionGenerationParameter.Description, typeof(IntValue))); } if (StoreHistory && !results.ContainsKey(TrainingBestSolutionsHistoryParameter.Name)) { results.Add(new Result(TrainingBestSolutionsHistoryParameter.Name, TrainingBestSolutionsHistoryParameter.Description, typeof(ItemList <T>))); TrainingBestSolutionsHistoryParameter.ActualValue = new ItemList <T>(); results[TrainingBestSolutionsHistoryParameter.Name].Value = TrainingBestSolutionsHistoryParameter.ActualValue; } #endregion #region find best tree double bestQuality = Maximization.Value ? double.NegativeInfinity : double.PositiveInfinity; ISymbolicExpressionTree bestTree = null; ISymbolicExpressionTree[] tree = SymbolicExpressionTree.ToArray(); double[] quality = Quality.Select(x => x.Value).ToArray(); for (int i = 0; i < tree.Length; i++) { if (IsBetter(quality[i], bestQuality, Maximization.Value)) { bestQuality = quality[i]; bestTree = tree[i]; } } #endregion if (bestTree != null && (UpdateAlways || TrainingBestSolutionQuality == null || IsBetter(bestQuality, TrainingBestSolutionQuality.Value, Maximization.Value))) { TrainingBestSolution = CreateSolution(bestTree, bestQuality); TrainingBestSolutionQuality = new DoubleValue(bestQuality); if (IterationsParameter.ActualValue != null) { TrainingBestSolutionGenerationParameter.ActualValue = new IntValue(IterationsParameter.ActualValue.Value); } results[TrainingBestSolutionParameter.Name].Value = TrainingBestSolution; results[TrainingBestSolutionQualityParameter.Name].Value = TrainingBestSolutionQuality; if (TrainingBestSolutionGenerationParameter.ActualValue != null) { results[TrainingBestSolutionGenerationParameter.Name].Value = TrainingBestSolutionGenerationParameter.ActualValue; } if (StoreHistory) { TrainingBestSolutionsHistoryParameter.ActualValue.Add(TrainingBestSolution); } } return(base.Apply()); }
public static void ChangeNodeType(IRandom random, ISymbolicExpressionTree symbolicExpressionTree) { List <ISymbol> allowedSymbols = new List <ISymbol>(); ISymbolicExpressionTreeNode parent; int childIndex; ISymbolicExpressionTreeNode child; // repeat until a fitting parent and child are found (MAX_TRIES times) int tries = 0; do { #pragma warning disable 612, 618 parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random); #pragma warning restore 612, 618 childIndex = random.Next(parent.SubtreeCount); child = parent.GetSubtree(childIndex); int existingSubtreeCount = child.SubtreeCount; allowedSymbols.Clear(); foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex)) { // check basic properties that the new symbol must have if (symbol.Name != child.Symbol.Name && symbol.InitialFrequency > 0 && existingSubtreeCount <= parent.Grammar.GetMinimumSubtreeCount(symbol) && existingSubtreeCount >= parent.Grammar.GetMaximumSubtreeCount(symbol)) { // check that all existing subtrees are also allowed for the new symbol bool allExistingSubtreesAllowed = true; for (int existingSubtreeIndex = 0; existingSubtreeIndex < existingSubtreeCount && allExistingSubtreesAllowed; existingSubtreeIndex++) { var existingSubtree = child.GetSubtree(existingSubtreeIndex); allExistingSubtreesAllowed &= parent.Grammar.IsAllowedChildSymbol(symbol, existingSubtree.Symbol, existingSubtreeIndex); } if (allExistingSubtreesAllowed) { allowedSymbols.Add(symbol); } } } tries++; } while (tries < MAX_TRIES && allowedSymbols.Count == 0); if (tries < MAX_TRIES) { var weights = allowedSymbols.Select(s => s.InitialFrequency).ToList(); #pragma warning disable 612, 618 var newSymbol = allowedSymbols.SelectRandom(weights, random); #pragma warning restore 612, 618 // replace the old node with the new node var newNode = newSymbol.CreateTreeNode(); if (newNode.HasLocalParameters) { newNode.ResetLocalParameters(random); } foreach (var subtree in child.Subtrees) { newNode.AddSubtree(subtree); } parent.RemoveSubtree(childIndex); parent.InsertSubtree(childIndex, newNode); } }
public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable <int> rows) { IEnumerable <double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows); IEnumerable <double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows); IEnumerable <double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit); var relResiduals = boundedEstimatedValues.Zip(targetValues, (e, t) => Math.Abs(t - e) / (Math.Abs(t) + 1.0)); OnlineCalculatorError errorState; OnlineCalculatorError varErrorState; double mre; double variance; OnlineMeanAndVarianceCalculator.Calculate(relResiduals, out mre, out variance, out errorState, out varErrorState); if (errorState != OnlineCalculatorError.None) { return(double.NaN); } return(mre); }
private static void SelectCrossoverPoint(IRandom random, ISymbolicExpressionTree parent0, double internalNodeProbability, int maxBranchLength, int maxBranchDepth, out CutPoint crossoverPoint) { if (internalNodeProbability < 0.0 || internalNodeProbability > 1.0) { throw new ArgumentException("internalNodeProbability"); } List <CutPoint> internalCrossoverPoints = new List <CutPoint>(); List <CutPoint> leafCrossoverPoints = new List <CutPoint>(); parent0.Root.ForEachNodePostfix((n) => { if (n.SubtreeCount > 0 && n != parent0.Root) { //avoid linq to reduce memory pressure for (int i = 0; i < n.SubtreeCount; i++) { var child = n.GetSubtree(i); if (child.GetLength() <= maxBranchLength && child.GetDepth() <= maxBranchDepth) { if (child.SubtreeCount > 0) { internalCrossoverPoints.Add(new CutPoint(n, child)); } else { leafCrossoverPoints.Add(new CutPoint(n, child)); } } } // add one additional extension point if the number of sub trees for the symbol is not full if (n.SubtreeCount < n.Grammar.GetMaximumSubtreeCount(n.Symbol)) { // empty extension point internalCrossoverPoints.Add(new CutPoint(n, n.SubtreeCount)); } } } ); if (random.NextDouble() < internalNodeProbability) { // select from internal node if possible if (internalCrossoverPoints.Count > 0) { // select internal crossover point or leaf crossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)]; } else { // otherwise select external node crossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)]; } } else if (leafCrossoverPoints.Count > 0) { // select from leaf crossover point if possible crossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)]; } else { // otherwise select internal crossover point crossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)]; } }
public Model(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter) : base(tree, interpreter, -10, 10) { }