private static INode GetNodeFromData(string[] nodeData)
        {
            switch (nodeData[1])
            {
            case "Begin":
                var startingNode = new StartingNode(int.Parse(nodeData[0]));
                startingNode.AddFollowingNode(int.Parse(nodeData[2]));
                return(startingNode);

            case "End":
                return(new EndingNode(int.Parse(nodeData[0])));

            case "Decis":
                var decisionNode = new DecisionNode(int.Parse(nodeData[0]));
                decisionNode.AddLeftNode(int.Parse(nodeData[3]), nodeData[5]);
                decisionNode.AddRightNode(int.Parse(nodeData[2]), nodeData[4]);
                return(decisionNode);

            case "Proc":
                var processNode = new ProcessNode(int.Parse(nodeData[0]));
                processNode.AddFollowingNode(int.Parse(nodeData[2]));
                return(processNode);

            default:
                return(null);
            }
        }
        public Node DecisionNodeToNodeClass(DecisionNode root)
        {
            Node result = new Node();

            DecisionNodeToNodeClass(root, result);
            return(result);
        }
        private static INode GetNodeFromGSAData(string[] nodeData)
        {
            var nodeType = nodeData[1].ToLower();

            if (nodeType == "begin")
            {
                var startingNode = new StartingNode(int.Parse(nodeData[0]));
                startingNode.AddFollowingNode(int.Parse(nodeData[2]));
                return(startingNode);
            }
            else if (nodeType == "end")
            {
                return(new EndingNode(int.Parse(nodeData[0])));
            }
            else if (new Regex(@"y[0-9]+").IsMatch(nodeType))
            {
                var processNode = new ProcessNode(int.Parse(nodeData[0]));
                processNode.AddFollowingNode(int.Parse(nodeData[2]));
                return(processNode);
            }
            else if (new Regex(@"x[0-9]+").IsMatch(nodeType))
            {
                var decisionNode = new DecisionNode(int.Parse(nodeData[0]));
                decisionNode.AddLeftNode(int.Parse(nodeData[3]));
                decisionNode.AddRightNode(int.Parse(nodeData[2]));
                return(decisionNode);
            }
            else
            {
                return(null);
            }
        }
Exemple #4
0
 private void clearCache(DecisionNode current)
 {
     foreach (var node in tree.Traverse(DecisionTreeTraversal.BreadthFirst, current))
     {
         subsets[node].Clear();
     }
 }
Exemple #5
0
 private void trackDecisions(DecisionNode current, double[][] input)
 {
     for (int i = 0; i < input.Length; i++)
     {
         trackDecisions(current, input[i], i);
     }
 }
Exemple #6
0
        /// <summary>
        ///   Creates a new <see cref="DecisionRule"/> from a <see cref="DecisionTree"/>'s
        ///   <see cref="DecisionNode"/>. This node must be a leaf, cannot be the root, and
        ///   should have one output value.
        /// </summary>
        ///
        /// <param name="node">A <see cref="DecisionNode"/> from a <see cref="DecisionTree"/>.</param>
        ///
        /// <returns>A <see cref="DecisionRule"/> representing the given <paramref name="node"/>.</returns>
        ///
        public static DecisionRule FromNode(DecisionNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (!node.IsLeaf || node.IsRoot || !node.Value.HasValue)
            {
                throw new InvalidOperationException(
                          "Only leaf nodes that have a parent can be converted to rules.");
            }

            DecisionNode current = node;
            DecisionTree owner   = current.Owner;
            double       output  = current.Output.Value;

            var antecedents = new List <Antecedent>();

            while (current.Parent != null)
            {
                int            index      = current.Parent.Branches.AttributeIndex;
                ComparisonKind comparison = current.Comparison;
                double         value      = current.Value.Value;

                antecedents.Insert(0, new Antecedent(index, comparison, value));

                current = current.Parent;
            }

            return(new DecisionRule(node.Owner.Attributes, output, antecedents));
        }
Exemple #7
0
 private void createCache(DecisionNode current)
 {
     foreach (var node in tree.Traverse(DecisionTreeTraversal.BreadthFirst, current))
     {
         subsets[node] = new List <int>();
     }
 }
Exemple #8
0
    /// <summary>
    /// Returns the next hidingspot from the current DecisionTree for the AI to check, based on the probability of the HidingSpots
    /// </summary>
    /// <returns> The next hidingspot to check from the current DecisionTree</returns>
    public DecisionNode GetNextHidingSpot()
    {
        DecisionNode place = Tree.RootNode.GetNodeOfHighestProbability();
        DecisionNode spot  = place.GetRandomHidingSpot();

        return(spot);
    }
Exemple #9
0
        public virtual void dumpDot(TextWriter printWriter)
        {
            printWriter.Write("digraph \"CART Tree\" {\n");
            printWriter.Write("rankdir = LR\n");

            foreach (Node n in cart)
            {
                printWriter.WriteLine("\tnode" + Math.Abs(n.GetHashCode()) + " [ label=\""
                                      + n + "\", color=" + dumpDotNodeColor(n)
                                      + ", shape=" + dumpDotNodeShape(n) + " ]\n");
                if (n is DecisionNode)
                {
                    DecisionNode dn = (DecisionNode)n;
                    if (dn.qtrue < cart.Length && cart[dn.qtrue] != null)
                    {
                        printWriter.Write("\tnode" + Math.Abs(n.GetHashCode()) + " -> node"
                                          + Math.Abs(cart[dn.qtrue].GetHashCode())
                                          + " [ label=" + "TRUE" + " ]\n");
                    }
                    if (dn.qfalse < cart.Length && cart[dn.qfalse] != null)
                    {
                        printWriter.Write("\tnode" + Math.Abs(n.GetHashCode()) + " -> node"
                                          + Math.Abs(cart[dn.qfalse].GetHashCode())
                                          + " [ label=" + "FALSE" + " ]\n");
                    }
                }
            }

            printWriter.Write("}\n");
            printWriter.Close();
        }
        public static string GenerateAForgivingXpath(DecisionNode dn, int phasesLimit = 1000)
        {
            // return "//*[" + DecisionTreeToXpath(dn, new HashSet<Feature>(), 1) + "]";
            List <double> precisionLevels = FindInterestingPrecisionLevels(dn);


            string fullCondition    = "";
            string lastCondition    = "";
            string conditionClosing = "";

            foreach (double pl in precisionLevels)
            {
                string currCondition   = "";
                string beforeCondition = "";
                if (!lastCondition.Equals(""))
                {
                    beforeCondition = " | /*[not(." + lastCondition + ")]";
                }
                string condInside = DecisionTreeToXpath(dn, new HashSet <Feature>(), pl);
                currCondition    = "//*" + (condInside.Equals("") ? "" : ("[" + condInside + "]"));
                fullCondition    = fullCondition + beforeCondition + currCondition;
                conditionClosing = conditionClosing + "";
                //set lastCondition to curr for the next iteration
                lastCondition = currCondition;
            }

            return(fullCondition);//+conditionClosing+"]";
        }
Exemple #11
0
        private void trackDecisions(DecisionNode root, double[] input, int index)
        {
            DecisionNode current = root;

            while (current != null)
            {
                subsets[current].Add(index);

                if (current.IsLeaf)
                {
                    actual[index] = current.Output.HasValue ? current.Output.Value : -1;
                    return;
                }

                int attribute = current.Branches.AttributeIndex;

                DecisionNode nextNode = null;

                foreach (DecisionNode branch in current.Branches)
                {
                    if (branch.Compute(input[attribute]))
                    {
                        nextNode = branch; break;
                    }
                }

                current = nextNode;
            }

            // Normal execution should not reach here.
            throw new InvalidOperationException("The tree is degenerated.");
        }
        public static List <double> FindInterestingPrecisionLevels(DecisionNode dn, int roughlimit = 7)
        {
            if (dn == null)
            {
                return(new List <double>());
            }
            List <double>    left  = FindInterestingPrecisionLevels(dn.SetNotSelected);
            List <double>    right = FindInterestingPrecisionLevels(dn.SetSelected);
            HashSet <double> res   = new HashSet <double>(left);

            res.UnionWith(right);
            res.Add(dn.precision);
            List <double> resSorted = new List <double>(res);

            //Descending
            resSorted.Sort((a, b) => - 1 * a.CompareTo(b));
            if (resSorted.Count() > roughlimit)
            {
                int           skipLevel = resSorted.Count() / roughlimit;
                List <double> resFinal  = new List <double>();
                for (int i = 0; i < resSorted.Count(); i++)
                {
                    if (i % skipLevel == 0)
                    {
                        if (resSorted.ElementAt(i) > 0)
                        {
                            resFinal.Add(resSorted.ElementAt(i));
                        }
                    }
                }
                return(resFinal);
            }

            return(resSorted);
        }
Exemple #13
0
    /// <summary>
    /// Returns a DecisionNode randomly based on the HidingSpot's probability.
    /// A HidingSpot with a higher probability has a higher chans of being choosen.
    /// </summary>
    /// <returns> Returns the randomly selected DecisionNode. Returns null if the node do not have any children </returns>
    public DecisionNode GetRandomHidingSpot()
    {
        if (Children == null)
        {
            Spot.DisableUI();
            Parent.Children.Remove(this);
            Debug.LogWarning("this should not happen");
            return(null);
        }

        int totalsum = 0;

        foreach (DecisionNode node in Children)
        {
            totalsum += node.Spot.Probability;
        }

        int index = UnityEngine.Random.Range(0, totalsum) + 1;
        int sum   = 0;
        int i     = -1;

        while (sum < index)
        {
            sum += Children[i + 1].Spot.Probability;
            i++;
        }

        DecisionNode returnNode = Children[Mathf.Max(0, i)];

        return(returnNode);
    }
Exemple #14
0
    /// <summary>
    /// Returns the DecisionNode that contains the HidingSpot that has the highest probability.
    /// If there is mulitple HidingSpots with the same probability ït will return one of the randomly.
    /// </summary>
    /// <returns> The DecisionNode that contains the HidingSpot with the highest probability, or one of the DecisionNode if there are more that one.</returns>
    public DecisionNode GetNodeOfHighestProbability()
    {
        DecisionNode        currentBest  = null;
        List <DecisionNode> sameNodes    = new List <DecisionNode>();
        DecisionNode        nodeToRemove = null;

        foreach (DecisionNode node in Children)
        {
            if (node.Children == null || node.Children.Count == 0)
            {
                continue;
            }

            if (currentBest == null || currentBest.Spot.Probability < node.Spot.Probability)
            {
                currentBest = node;
                sameNodes.Clear();
                sameNodes.Add(currentBest);
            }
            else if (currentBest.Spot.Probability == node.Spot.Probability)
            {
                sameNodes.Add(node);
            }
        }

        return(sameNodes[Random.Range(0, sameNodes.Count)]);
    }
        private void  DecisionNodeToNodeClass(DecisionNode decisionNode, Node currentNode)
        {
            if (!decisionNode.IsRoot)
            {
                string   comparation = decisionNode.ToString();
                string[] aux         = comparation.Split(' ');
                currentNode.parent.value = int.Parse(aux[0]) + 1;
                int column = int.Parse(aux[0]) + 1;
                if (column == 1)
                {
                    string comparator = Math.Floor(double.Parse(aux[2])) == 0 ? "30" : "60";
                    currentNode.message = Patient.getNamesColums(column) + " " + aux[1] + " " + comparator;
                }
                else if (column == 2)
                {
                    string comparator = aux[1].Contains(">") ? "M" : "F";
                    currentNode.message = Patient.getNamesColums(column) + " " + comparator;
                }
                else if (column == 8)
                {
                    currentNode.message = "Value " + aux[1] + " " + Math.Floor(double.Parse(aux[2]));
                }
                else if (column == 6)
                {
                    string comparator = "120 mg/dl";
                    currentNode.message = Patient.getNamesColums(column) + " " + aux[1] + " " + comparator;
                }
                else
                {
                    currentNode.message = Patient.getNamesColums(column) + " " + aux[1] + " " + Math.Floor(double.Parse(aux[2]));
                }
            }
            else
            {
                currentNode.height = 1;
            }
            currentNode.answer = decisionNode.Output;
            currentNode.nodes  = new Node[decisionNode.Branches.Count];
            int distX = 2 * Visualization.SIZE + 10 * currentNode.nodes.Length;

            currentNode.distX = distX;
            int i = 0;

            foreach (DecisionNode childNode in decisionNode.Branches)
            {
                Node newNode = new Node();
                currentNode.nodes[i] = newNode;
                newNode.parent       = currentNode;
                newNode.height       = newNode.parent.height + 1;
                newNode.posY         = newNode.parent.posY + Visualization.DIST_Y;
                DecisionNodeToNodeClass(childNode, newNode);
                i++;
            }
            if (decisionNode.IsLeaf)
            {
                currentNode.value  = null;
                currentNode.answer = currentNode.answer == null ? -1 : currentNode.answer;
            }
        }
    public override void Execute()
    {
        State = (condition.IsTrue()) ? eState.ConditionTrue : eState.ConditionFalse;

        DecisionNode node = (State == eState.ConditionTrue) ? trueNode : falseNode;

        node?.Execute();
    }
        internal bool IsBetterThanParent(DecisionNode parent)
        {
            var betterBranch = Left.MeasureValue + Right.MeasureValue;

            return(parent is SplitDecisionNode node
                   &&
                   betterBranch - node.SplitInformation.MeasureValue > 0.1);
        }
 private static void Serialize(string prefix, DecisionNode splitter, string suffix, CodeWriter writer)
 {
     writer.AppendLine("{0}N({1},", prefix, SerializePartitioner(splitter.Partitioner));
     using (writer.Indent()) {
         Serialize("", splitter.Left, ",", writer);
         Serialize("", splitter.Right, ")" + suffix, writer);
     }
 }
Exemple #19
0
    /// <summary>
    /// Used to set up the defender type tree
    /// </summary>
    void SetupDefender()
    {
        DecisionNode isHealthLow       = new DecisionNode(Decisions.Shared_IsHealthLow, this);
        ActionNode   findPickup        = new ActionNode(Actions.Shared_SearchForHealthpack, this);
        DecisionNode enemyInRadiusNode = new DecisionNode(Decisions.Shared_IsEnemyInAttackRadius, this);

        isHealthLow.AddSuccessNode(findPickup);
        isHealthLow.AddFailureNode(enemyInRadiusNode);

        DecisionNode enemyHasFlag = new DecisionNode(Decisions.Defender_DoesEnemyHaveTeamFlag, this);
        ActionNode   attackTarget = new ActionNode(Actions.Shared_AttackEnemyTarget, this);

        enemyInRadiusNode.AddFailureNode(enemyHasFlag);
        enemyInRadiusNode.AddSuccessNode(attackTarget);

        ActionNode   attackEnemyWithFlag = new ActionNode(Actions.Defender_AttackEnemyWithTeamFlag, this);
        DecisionNode teamFlagOutsideBase = new DecisionNode(Decisions.Defender_IsTeamFlagOutsideBase, this);

        enemyHasFlag.AddSuccessNode(attackEnemyWithFlag);
        enemyHasFlag.AddFailureNode(teamFlagOutsideBase);

        DecisionNode hasTeamFlagInside  = new DecisionNode(Decisions.Defender_HasFriendlyFlag, this);
        DecisionNode hasTeamFlagOutside = new DecisionNode(Decisions.Defender_HasFriendlyFlag, this);

        teamFlagOutsideBase.AddFailureNode(hasTeamFlagInside);
        teamFlagOutsideBase.AddSuccessNode(hasTeamFlagOutside);

        DecisionNode hasSpottedEnemy = new DecisionNode(Decisions.Shared_HasSeenEnemy, this);
        ActionNode   dropTeamFlag    = new ActionNode(Actions.Defender_DropTeamFlag, this);

        hasTeamFlagInside.AddFailureNode(hasSpottedEnemy);
        hasTeamFlagInside.AddSuccessNode(dropTeamFlag);

        ActionNode goToTeamBase = new ActionNode(Actions.Defender_ReturnToBase, this);
        ActionNode attackEnemy  = new ActionNode(Actions.Shared_AttackEnemyTarget, this);

        hasSpottedEnemy.AddFailureNode(goToTeamBase);
        hasSpottedEnemy.AddSuccessNode(attackEnemy);

        DecisionNode teamMateHasFriendlyFlag = new DecisionNode(Decisions.Shared_TeamHasFriendlyFlag, this);

        hasTeamFlagOutside.AddFailureNode(teamMateHasFriendlyFlag);
        hasTeamFlagOutside.AddSuccessNode(goToTeamBase);

        ActionNode   collectFriendlyFlag            = new ActionNode(Actions.Defender_CollectFriendlyFlag, this);
        DecisionNode hasSpottedEnemyNearFlagCarrier = new DecisionNode(Decisions.Shared_HasSeenEnemy, this);

        teamMateHasFriendlyFlag.AddSuccessNode(hasSpottedEnemyNearFlagCarrier);
        teamMateHasFriendlyFlag.AddFailureNode(collectFriendlyFlag);

        ActionNode followTeamFlagCarrier = new ActionNode(Actions.Defender_FollowTeamMateWithFlag, this);

        hasSpottedEnemyNearFlagCarrier.AddSuccessNode(attackEnemy);
        hasSpottedEnemyNearFlagCarrier.AddFailureNode(followTeamFlagCarrier);

        decTree = new DecisionTree(isHealthLow);
    }
Exemple #20
0
        private bool compute(DecisionNode node)
        {
            int[] indices = subsets[node].ToArray();
            int[] subset  = outputs.Submatrix(indices);

            int          size       = indices.Length;
            int          mostCommon = Statistics.Tools.Mode(subset);
            DecisionNode maxChild   = getMaxChild(node);

            double replace = Double.PositiveInfinity;

            if (maxChild != null)
            {
                replace = computeErrorReplacingSubtrees(node, maxChild);
                replace = upperBound(replace, size);
            }


            double baseline = computeErrorSubtree(indices);
            double prune    = computeErrorWithoutSubtree(node, mostCommon);


            baseline = upperBound(baseline, size);
            prune    = upperBound(prune, size);


            bool changed = false;

            if (Math.Abs(prune - baseline) < limit ||
                Math.Abs(replace - baseline) < limit)
            {
                if (replace < prune)
                {
                    // We should replace the subtree with its maximum child
                    node.Branches = maxChild.Branches;
                    node.Output   = maxChild.Output;
                    foreach (var child in node.Branches)
                    {
                        child.Parent = node;
                    }
                }
                else
                {
                    // We should prune the subtree
                    node.Branches = null;
                    node.Output   = mostCommon;
                }

                changed = true;
                clearCache(node);
                trackDecisions(node, inputs);
            }

            return(changed);
        }
        private static double[] ComputeEstimates(IDataRow row, DecisionNode node)
        {
            var rowValue = row[node.Attribute];

            switch (node.Condition)
            {
            case PredicateCondition.Equal:
                if (!row[node.Attribute].Equals(node.ThreshHold))
                {
                    return(null);
                }
                break;

            case PredicateCondition.LessThanOrEqual:
                if ((rowValue == null) || (Convert.ToDouble(rowValue) > Convert.ToDouble(node.ThreshHold)))
                {
                    return(null);
                }
                break;

            case PredicateCondition.GreaterThan:
                if ((rowValue == null) || (Convert.ToDouble(rowValue) <= Convert.ToDouble(node.ThreshHold)))
                {
                    return(null);
                }
                break;

            default:
                return(null);
            }


            if (node.Children != null && node.Children.Any())
            {
                foreach (var child in node.Children)
                {
                    var estimates = ComputeEstimates(row, child);
                    if (estimates != null)
                    {
                        return(estimates);
                    }
                }
            }
            else
            {
                var estimates = new double[node.Statistics.Frequencies.Length];
                for (int index = 0; index < estimates.Length; index++)
                {
                    estimates[index] = node.Statistics.Frequencies[index] / (double)node.Statistics.DatasetLength;
                }
                return(estimates);
            }

            return(null);
        }
        private static bool GetClass(IDataRow row, DecisionNode node, out string className)
        {
            className = node.Class;
            bool isValid = false;

            var rowValue = row[node.Attribute];

            switch (node.Condition)
            {
            case PredicateCondition.Equal:
                if (row[node.Attribute].Equals(node.ThreshHold))
                {
                    isValid = true;
                }
                break;

            case PredicateCondition.LessThanOrEqual:
                if (rowValue == null)
                {
                    return(false);
                }
                if (Convert.ToDouble(rowValue) <= Convert.ToDouble(node.ThreshHold))
                {
                    isValid = true;
                }
                break;

            case PredicateCondition.GreaterThan:
                if (rowValue == null)
                {
                    return(false);
                }
                if (Convert.ToDouble(rowValue) > Convert.ToDouble(node.ThreshHold))
                {
                    isValid = true;
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (isValid && node.Children != null)
            {
                foreach (var child in node.Children)
                {
                    if (GetClass(row, child, out className))
                    {
                        break;
                    }
                }
            }

            return(isValid);
        }
 public static void LoadLeaves(DecisionNode node, List <DecisionNode> leaves)
 {
     if (node.IsLeaf)
     {
         leaves.Add(node);
         return;
     }
     foreach (var child in node.Children)
     {
         LoadLeaves(child, leaves);
     }
 }
Exemple #24
0
        internal SplitDecisionNode(DecisionTree owner, DecisionNode parent,
                                   SplitInformation splitInformation,
                                   ComparisonKind comparisonKind, double splitValue, int attributeIndex)
            : base(owner)
        {
            Parent = parent;

            Value            = splitValue;
            Comparison       = comparisonKind;
            SplitInformation = splitInformation;
            AttributeIndex   = attributeIndex;
        }
Exemple #25
0
        public string Compute(double[] input, DecisionTree tree)
        {
            DecisionNode Root = tree.Root;
            string       attributeName;
            string       attributeValue;
            string       rule = "";

            if (Root == null)
            {
                throw new InvalidOperationException();
            }

            DecisionNode current = Root;

            // Start reasoning
            while (current != null)
            {
                // Check if this is a leaf
                if (current.IsLeaf)
                {
                    // This is a leaf node. The decision proccess thus should stop here.
                    return(rule.Trim());
                }

                // This node is not a leaf. Continue the decisioning proccess following the childs
                // Get the next attribute to guide reasoning
                int attribute = current.Branches.AttributeIndex;

                // Check which child is responsible for dealing which the particular value of the attribute
                DecisionNode nextNode = null;

                foreach (DecisionNode branch in current.Branches)
                {
                    if (branch.Compute(input[attribute]))
                    {
                        // This is the child node responsible for dealing which this particular attribute value. Choose it
                        // to continue reasoning.

                        nextNode       = branch;
                        attributeName  = nextNode.Owner.Attributes[nextNode.Parent.Branches.AttributeIndex].Name;
                        attributeValue = this.trainningDataTabDianosis.CodificationData.Translate(attributeName,
                                                                                                  Convert.ToInt32(nextNode.Value));
                        rule += attributeName + "=" + attributeValue + " ";
                        break;
                    }
                }
                current = nextNode;
            }

            // Normal execution should not reach here.
            throw new InvalidOperationException("The tree is degenerated.");
        }
        public static HashSet <List <DecisionNode> > DecisionTreeToPathList(DecisionNode dn, double recallThreshold)
        {
            HashSet <List <DecisionNode> > res = new HashSet <List <DecisionNode> >();

            if (dn.SetSelected != null)
            {
                double covered   = dn.SetSelected.InitialNodeSet.Intersect(DomPool.TargetNodes).Count();
                double all       = DomPool.TargetNodes.Count();
                double threshold = 2 / ((double)DomPool.trainingDocsNames.Count());

                if (DomPool.trainingDocsNames.Count() == 1)
                {
                    threshold = 1;
                }

                if ((covered / all) < threshold)
                {
                    return(new HashSet <List <DecisionNode> >()
                    {
                        new List <DecisionNode>()
                        {
                            dn
                        }
                    });
                }
            }

            if (dn.SetSelected != null)
            {
                HashSet <List <DecisionNode> > rightLists = DecisionTreeToPathList(dn.SetSelected, recallThreshold);
                foreach (List <DecisionNode> l in rightLists)
                {
                    List <DecisionNode> toadd = new List <DecisionNode>()
                    {
                        dn
                    };
                    toadd.AddRange(l);
                    res.Add(toadd);
                }
            }

            if (dn.SetNotSelected != null)
            {
                HashSet <List <DecisionNode> > leftLists = DecisionTreeToPathList(dn.SetNotSelected, recallThreshold);
                foreach (List <DecisionNode> l in leftLists)
                {
                    res.Add(l);
                }
            }

            return(res);
        }
Exemple #27
0
    /// <summary>
    /// Get the DecisionNode that contains the hidingSpot, if the HidingSpot don't exist in the tree it will reutnr null.
    /// </summary>
    /// <param name="hidingSpot"> The HidingSpot that is containd in the returning DecisionNode</param>
    /// <returns> The DecisionNode that contains hidingSpot if one exists, otherwise returns null </returns>
    public DecisionNode GetDecisionNode(HidingSpot hidingSpot)
    {
        foreach (DecisionNode node in PlaceCreator.Instance.Tree.RootNode.Children)
        {
            DecisionNode Cnode = node.GetChild(hidingSpot);
            if (Cnode != null)
            {
                return(Cnode);
            }
        }

        return(null);
    }
        public static void GeneratePseudoCode(DecisionNode node, StringBuilder sb, bool first, int level = 0)
        {
            if (node == null)
            {
                return;
            }
            if (node.Attribute != null)
            {
                var    firstParam     = first ? "if " : "else if ";
                var    attributeParam = node.Attribute;
                string operatorParam;
                var    sentence = "{0} {1} {2}" + " \"{3}\" then ";
                switch (node.Condition)
                {
                case PredicateCondition.Equal:
                    operatorParam = "=";
                    break;

                case PredicateCondition.LessThanOrEqual:
                    operatorParam = "<=";
                    break;

                case PredicateCondition.GreaterThan:
                    operatorParam = ">";
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                AppendNewLine(sb, string.Format(sentence, firstParam, attributeParam, operatorParam, node.ThreshHold),
                              level);
                level++;
            }
            if (node.Class != null && (node.Children == null || !node.Children.Any()))
            {
                var ret = "class = " + node.Class;
                AppendNewLine(sb, ret, level);
            }
            else
            {
                if (node.Children != null)
                {
                    var children = node.Children.ToList();

                    for (int index = 0; index < children.Count; index++)
                    {
                        GeneratePseudoCode(children[index], sb, index == 0, level);
                    }
                }
            }
        }
Exemple #29
0
        private TreeModel buildModel(Man man)
        {
            var growNode          = new ActionNode <Man>("GrowAgeAndHealth");
            var goToWork          = new DecisionNode <Man>("DecideIFCanWork");
            var startDying        = new DecisionNode <Man>("DecideIFDye");
            var workHard          = new ActionNode <Man>("Work");
            var deadNode          = new ActionNode <Man>("Dead");
            var isSportish        = new DecisionNode <Man>("IfSportishContext");
            var fromManToSportish = new TransformationNode <Man, Sport>("FromManToSport");
            var practiceSport     = new ActionNode <Sport>("DoSport");
            var sportToMan        = new TransformationNode <Sport, Man>("SportToMan");

            growNode.AddChild(goToWork);
            growNode.SetAction(m => { m.Age++; m.Health++; });

            goToWork.SetCondition(m => m.Age > 18);
            goToWork.SetYesChild(workHard);
            goToWork.SetNoChild(growNode);

            workHard.AddChild(isSportish);
            workHard.SetAction(m => { m.Health--; m.Age++; });

            isSportish.SetNoChild(startDying);
            isSportish.SetYesChild(fromManToSportish);
            isSportish.SetCondition(m => m.Age < 60);

            fromManToSportish.AddChild(practiceSport);
            fromManToSportish.SetTranslator(m => new Sport(m.Age));


            practiceSport.SetAction(s => s.Do());
            practiceSport.AddChild(sportToMan);

            sportToMan.SetTranslator(sport =>
            {
                man.Health += sport.GainedHealth;
                return(man);
            });
            sportToMan.AddChild(startDying);

            startDying.SetCondition(m => m.Health < 5);
            startDying.SetNoChild(workHard);
            startDying.SetYesChild(deadNode);

            var model = new TreeModel(100);

            model.SetStartNode(growNode);
            model.SetEndNode(deadNode);
            Console.WriteLine("Done");
            return(model);
        }
Exemple #30
0
        // Regress tree
        private TreeNode convert(DecisionNode node)
        {
            string attributeName;
            string attributeValue;

            TreeNode treeNode;

            // Add root
            if (node.IsRoot)
            {
                treeNode = new TreeNode(node.ToString());
            }
            else
            {
                attributeName  = node.Owner.Attributes[node.Parent.Branches.AttributeIndex].Name;
                attributeValue = this.codification.Translate(attributeName, Convert.ToInt32(node.Value));

                // Create new treeNode to TreeView
                treeNode = new TreeNode(attributeName + "=" + attributeValue);
            }

            // If node is leaf
            if (node.IsLeaf)
            {
                // If node has value add classifier value
                if (node.Output.HasValue)
                {
                    attributeName  = TableMetaData.ClassAttribute;
                    attributeValue = this.codification.Translate(attributeName, Convert.ToInt32(node.Output));

                    treeNode.Nodes.Add(new TreeNode(attributeValue));
                }
                // Add ""
                else
                {
                    treeNode.Nodes.Add(new TreeNode(node.Output.ToString()));
                }
            }
            // Regress all child nodes
            else
            {
                foreach (var child in node.Branches)
                {
                    treeNode.Nodes.Add(convert(child));
                }
            }

            return(treeNode);
        }
Exemple #31
0
        public static void GeneratePseudoCode(DecisionNode node, StringBuilder sb, bool first, int level = 0)
        {
            if (node == null)
            {
                return;
            }
            if (node.Attribute != null)
            {
                var firstParam = first ? "if " : "else if ";
                var attributeParam = node.Attribute;
                string operatorParam;
                var sentence = "{0} {1} {2}" + " \"{3}\" then ";
                switch (node.Condition)
                {
                    case PredicateCondition.Equal:
                        operatorParam = "=";
                        break;
                    case PredicateCondition.LessThanOrEqual:
                        operatorParam = "<=";
                        break;
                    case PredicateCondition.GreaterThan:
                        operatorParam = ">";
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
                AppendNewLine(sb, string.Format(sentence, firstParam, attributeParam, operatorParam, node.ThreshHold),
                    level);
                level++;
            }
            if (node.Class != null && (node.Children == null || !node.Children.Any()))
            {
                var ret = "class = " + node.Class;
                AppendNewLine(sb, ret, level);
            }
            else
            {
                if (node.Children != null)
                {
                    var children = node.Children.ToList();

                    for (int index = 0; index < children.Count; index++)
                    {
                        GeneratePseudoCode(children[index], sb, index == 0, level);
                    }
                }
            }
        }
        private double computeErrorWithoutSubtree(DecisionNode tree, int mostCommon)
        {
            var branches = tree.Branches;
            var output = tree.Output;

            tree.Branches = null;
            tree.Output = mostCommon;

            double error = computeError();

            tree.Branches = branches;
            tree.Output = output;

            return error;
        }
Exemple #33
0
        private void split(DecisionNode root, double[][] input, int[] output)
        {

            // 2. If all examples are for the same class, return the single-node
            //    tree with the output label corresponding to this common class.
            double entropy = Statistics.Tools.Entropy(output, outputClasses);

            if (entropy == 0)
            {
                if (output.Length > 0)
                    root.Output = output[0];
                return;
            }

            // 3. If number of predicting attributes is empty, then return the single-node
            //    tree with the output label corresponding to the most common value of
            //    the target attributes in the examples.
            int predictors = attributes.Count(x => x == false);

            if (predictors <= attributes.Length - maxHeight)
            {
                root.Output = Statistics.Tools.Mode(output);
                return;
            }


            // 4. Otherwise, try to select the attribute which
            //    best explains the data sample subset.

            double[] scores = new double[predictors];
            double[] entropies = new double[predictors];
            double[] thresholds = new double[predictors];
            int[][][] partitions = new int[predictors][][];

            // Retrieve candidate attribute indices
            int[] candidates = new int[predictors];
            for (int i = 0, k = 0; i < attributes.Length; i++)
                if (!attributes[i]) candidates[k++] = i;


            // For each attribute in the data set
#if SERIAL
            for (int i = 0; i < scores.Length; i++)
#else
            Parallel.For(0, scores.Length, i =>
#endif
            {
                scores[i] = computeGainRatio(input, output, candidates[i],
                    entropy, out partitions[i], out thresholds[i]);
            }
#if !SERIAL
);
#endif

            // Select the attribute with maximum gain ratio
            int maxGainIndex; scores.Max(out maxGainIndex);
            var maxGainPartition = partitions[maxGainIndex];
            var maxGainEntropy = entropies[maxGainIndex];
            var maxGainAttribute = candidates[maxGainIndex];
            var maxGainRange = inputRanges[maxGainAttribute];
            var maxGainThreshold = thresholds[maxGainIndex];

            // Mark this attribute as already used
            attributes[maxGainAttribute] = true;

            double[][] inputSubset;
            int[] outputSubset;

            // Now, create next nodes and pass those partitions as their responsibilities. 
            if (tree.Attributes[maxGainAttribute].Nature == DecisionVariableKind.Discrete)
            {
                // This is a discrete nature attribute. We will branch at each
                // possible value for the discrete variable and call recursion.
                DecisionNode[] children = new DecisionNode[maxGainPartition.Length];

                // Create a branch for each possible value
                for (int i = 0; i < children.Length; i++)
                {
                    children[i] = new DecisionNode(tree)
                    {
                        Parent = root,
                        Value = i + maxGainRange.Min,
                        Comparison = ComparisonKind.Equal,
                    };

                    inputSubset = input.Submatrix(maxGainPartition[i]);
                    outputSubset = output.Submatrix(maxGainPartition[i]);
                    split(children[i], inputSubset, outputSubset); // recursion
                }

                root.Branches.AttributeIndex = maxGainAttribute;
                root.Branches.AddRange(children);
            }

            else if (maxGainPartition.Length > 1)
            {
                // This is a continuous nature attribute, and we achieved two partitions
                // using the partitioning scheme. We will branch on two possible settings:
                // either the value is higher than a currently detected optimal threshold 
                // or it is lesser.

                DecisionNode[] children = 
                {
                    new DecisionNode(tree) 
                    {
                        Parent = root, Value = maxGainThreshold,
                        Comparison = ComparisonKind.LessThanOrEqual 
                    },

                    new DecisionNode(tree)
                    {
                        Parent = root, Value = maxGainThreshold,
                        Comparison = ComparisonKind.GreaterThan
                    }
                };

                // Create a branch for lower values
                inputSubset = input.Submatrix(maxGainPartition[0]);
                outputSubset = output.Submatrix(maxGainPartition[0]);
                split(children[0], inputSubset, outputSubset);

                // Create a branch for higher values
                inputSubset = input.Submatrix(maxGainPartition[1]);
                outputSubset = output.Submatrix(maxGainPartition[1]);
                split(children[1], inputSubset, outputSubset);

                root.Branches.AttributeIndex = maxGainAttribute;
                root.Branches.AddRange(children);
            }
            else
            {
                // This is a continuous nature attribute, but all variables are equal
                // to a constant. If there is only a constant value as the predictor 
                // and there are multiple output labels associated with this constant
                // value, there isn't much we can do. This node will be a leaf.

                // We will set the class label for this node as the
                // majority of the currently selected output classes.

                outputSubset = output.Submatrix(maxGainPartition[0]);
                root.Output = Statistics.Tools.Mode(outputSubset);
            }

            attributes[maxGainAttribute] = false;
        }
        private double computeErrorReplacingSubtrees(DecisionNode tree, DecisionNode child)
        {
            var branches = tree.Branches;
            var output = tree.Output;

            tree.Branches = child.Branches;
            tree.Output = child.Output;

            double error = computeError();

            tree.Branches = branches;
            tree.Output = output;

            return error;
        }
 private void clearCache(DecisionNode current)
 {
     foreach (var node in tree.Traverse(DecisionTreeTraversal.BreadthFirst, current))
         subsets[node].Clear();
 }
        private DecisionNode getMaxChild(DecisionNode tree)
        {
            DecisionNode max = null;
            int maxCount = 0;

            foreach (var child in tree.Branches)
            {
                var list = subsets[child];
                if (list.Count > maxCount)
                {
                    max = child;
                    maxCount = list.Count;
                }
            }

            return max;
        }
        private void trackDecisions(DecisionNode root, double[] input, int index)
        {
            DecisionNode current = root;

            while (current != null)
            {
                info[current].subset.Add(index);

                if (current.IsLeaf)
                {
                    actual[index] = current.Output.HasValue ? current.Output.Value : -1;
                    return;
                }

                int attribute = current.Branches.AttributeIndex;

                DecisionNode nextNode = null;

                foreach (DecisionNode branch in current.Branches)
                {
                    if (branch.Compute(input[attribute]))
                    {
                        nextNode = branch; break;
                    }
                }

                current = nextNode;
            }

            // Normal execution should not reach here.
            throw new InvalidOperationException("The tree is degenerated.");
        }
Exemple #38
0
        private static bool GetClass(IDataRow row, DecisionNode node, out string className)
        {
            className = node.Class;
            bool isValid = false;

            var rowValue = row[node.Attribute];
            switch (node.Condition)
            {
                case PredicateCondition.Equal:
                    if (row[node.Attribute].Equals(node.ThreshHold))
                    {
                        isValid = true;
                    }
                    break;
                case PredicateCondition.LessThanOrEqual:
                    if (rowValue == null)
                    {
                        return false;
                    }
                    if (Convert.ToDouble(rowValue) <= Convert.ToDouble(node.ThreshHold))
                    {
                        isValid = true;
                    }
                    break;
                case PredicateCondition.GreaterThan:
                    if (rowValue == null)
                    {
                        return false;
                    }
                    if (Convert.ToDouble(rowValue) > Convert.ToDouble(node.ThreshHold))
                    {
                        isValid = true;
                    }
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            if (isValid && node.Children != null)
            {
                foreach (var child in node.Children)
                {
                    if (GetClass(row, child, out className))
                    {
                        break;
                    }
                }
            }

            return isValid;
        }
Exemple #39
0
        private void split(DecisionNode root, int[][] input, int[] output)
        {

            // 2. If all examples are for the same class, return the single-node
            //    tree with the output label corresponding to this common class.
            double entropy = Statistics.Tools.Entropy(output, outputClasses);

            if (entropy == 0)
            {
                if (output.Length > 0)
                    root.Output = output[0];
                return;
            }

            // 3. If number of predicting attributes is empty, then return the single-node
            //    tree with the output label corresponding to the most common value of
            //    the target attributes in the examples.
            int predictors = attributes.Count(x => x == false);

            if (predictors == 0)
            {
                root.Output = Statistics.Tools.Mode(output);
                return;
            }


            // 4. Otherwise, try to select the attribute which
            //    best explains the data sample subset.

            double[] scores = new double[predictors];
            double[] entropies = new double[predictors];
            int[][][] partitions = new int[predictors][][];

            // Retrieve candidate attribute indices
            int[] candidates = new int[predictors];
            for (int i = 0, k = 0; i < attributes.Length; i++)
                if (!attributes[i]) candidates[k++] = i;


            // For each attribute in the data set
            Parallel.For(0, scores.Length, i =>
            {
                scores[i] = computeGainRatio(input, output, candidates[i],
                    entropy, out partitions[i]);
            });

            // Select the attribute with maximum gain ratio
            int maxGainIndex; scores.Max(out maxGainIndex);
            var maxGainPartition = partitions[maxGainIndex];
            var maxGainEntropy = entropies[maxGainIndex];
            var maxGainAttribute = candidates[maxGainIndex];
            var maxGainRange = inputRanges[maxGainAttribute];

            attributes[maxGainAttribute] = true;

            // Now, create next nodes and pass those partitions as their responsabilities.
            DecisionNode[] children = new DecisionNode[maxGainPartition.Length];

            for (int i = 0; i < children.Length; i++)
            {
                children[i] = new DecisionNode(tree);
                children[i].Parent = root;
                children[i].Comparison = ComparisonKind.Equal;
                children[i].Value = i + maxGainRange.Min;


                int[][] inputSubset = input.Submatrix(maxGainPartition[i]);
                int[] outputSubset = output.Submatrix(maxGainPartition[i]);

                split(children[i], inputSubset, outputSubset); // recursion
            }

            attributes[maxGainAttribute] = false;

            root.Branches = new DecisionBranchNodeCollection(maxGainAttribute, children);
        }
        private DecisionNode getMaxChild(DecisionNode tree)
        {
            DecisionNode max = null;
            int maxCount = 0;

            foreach (var child in tree.Branches)
            {
                if (child.Branches != null)
                {
                    foreach (var node in child.Branches)
                    {
                        var list = subsets[node];
                        if (list.Count > maxCount)
                        {
                            max = node;
                            maxCount = list.Count;
                        }
                    }
                }
            }

            return max;
        }
        private bool compute(DecisionNode node)
        {
            int[] indices = subsets[node].ToArray();
            int[] subset = outputs.Submatrix(indices);

            int size = indices.Length;
            int mostCommon = Statistics.Tools.Mode(subset);
            DecisionNode maxChild = getMaxChild(node);

            double replace = Double.PositiveInfinity;
            if (maxChild != null)
            {
                replace = computeErrorReplacingSubtrees(node, maxChild);
                replace = upperBound(replace, size);
            }


            double baseline = computeErrorSubtree(indices);
            double prune = computeErrorWithoutSubtree(node, mostCommon);


            baseline = upperBound(baseline, size);
            prune = upperBound(prune, size);


            bool changed = false;

            if (Math.Abs(prune - baseline) < limit ||
                Math.Abs(replace - baseline) < limit)
            {
                if (replace < prune)
                {
                    // We should replace the subtree with its maximum child
                    node.Branches = maxChild.Branches;
                    node.Output = maxChild.Output;
                    foreach (var child in node.Branches)
                        child.Parent = node;
                }
                else
                {
                    // We should prune the subtree
                    node.Branches = null;
                    node.Output = mostCommon;
                }

                changed = true;
                clearCache(node);
                trackDecisions(node, inputs);
            }

            return changed;
        }
Exemple #42
0
        private void split(DecisionNode root, int[][] input, int[] output)
        {

            // 2. If all examples are for the same class, return the single-node
            //    tree with the output label corresponding to this common class.
            double entropy = Statistics.Tools.Entropy(output, outputClasses);

            if (entropy == 0)
            {
                if (output.Length > 0)
                    root.Output = output[0];
                return;
            }

            // 3. If number of predicting attributes is empty, then return the single-node
            //    tree with the output label corresponding to the most common value of
            //    the target attributes in the examples.
            int predictors = attributes.Count(x => x == false);

            if (predictors <= attributes.Length - maxHeight)
            {
                root.Output = Statistics.Tools.Mode(output);
                return;
            }


            // 4. Otherwise, try to select the attribute which
            //    best explains the data sample subset.

            double[] scores = new double[predictors];
            double[] entropies = new double[predictors];
            int[][][] partitions = new int[predictors][][];

            // Retrieve candidate attribute indices
            int[] candidates = new int[predictors];
            for (int i = 0, k = 0; i < attributes.Length; i++)
                if (!attributes[i]) candidates[k++] = i;


            // For each attribute in the data set
#if SERIAL
            for (int i = 0; i < scores.Length; i++)
#else
            Parallel.For(0, scores.Length, i =>
#endif
            {
                scores[i] = computeGainRatio(input, output, candidates[i],
                    entropy, out partitions[i]);
            }
#if !SERIAL
);
#endif

            // Select the attribute with maximum gain ratio
            int maxGainIndex; scores.Max(out maxGainIndex);
            var maxGainPartition = partitions[maxGainIndex];
            var maxGainEntropy = entropies[maxGainIndex];
            var maxGainAttribute = candidates[maxGainIndex];
            var maxGainRange = inputRanges[maxGainAttribute];

            attributes[maxGainAttribute] = true;

            // Now, create next nodes and pass those partitions as their responsibilities.
            DecisionNode[] children = new DecisionNode[maxGainPartition.Length];

            for (int i = 0; i < children.Length; i++)
            {
                children[i] = new DecisionNode(tree);
                children[i].Parent = root;
                children[i].Comparison = ComparisonKind.Equal;
                children[i].Value = i + maxGainRange.Min;


                int[][] inputSubset = input.Submatrix(maxGainPartition[i]);
                int[] outputSubset = output.Submatrix(maxGainPartition[i]);

                split(children[i], inputSubset, outputSubset); // recursion

                if (children[i].IsLeaf)
                {
                    // If the resulting node is a leaf, and it has not
                    // been assigned a value because there were no available
                    // output samples in this category, we will be assigning
                    // the most common label for the current node to it.
                    if (!Rejection && !children[i].Output.HasValue)
                        children[i].Output = Statistics.Tools.Mode(output);
                }
            }


            attributes[maxGainAttribute] = false;

            root.Branches.AttributeIndex = maxGainAttribute;
            root.Branches.AddRange(children);
        }
Exemple #43
0
 public static void LoadLeaves(DecisionNode node, List<DecisionNode> leaves)
 {
     if (node.IsLeaf)
     {
         leaves.Add(node);
         return;
     }
     foreach (var child in node.Children)
     {
         LoadLeaves(child, leaves);
     }
 }
        /// <summary>
        ///   Attempts to prune a node's subtrees.
        /// </summary>
        /// 
        /// <returns>Whether the current node was changed or not.</returns>
        /// 
        private bool compute(DecisionNode node)
        {
            int[] indices = subsets[node].ToArray();
            int[] outputSubset = outputs.Get(indices);

            if (indices.Length == 0)
            {
                // The rule employed by this node doesn't cover
                // any input points. This node could be removed.

                node.Branches = null;
                node.Output = null;

                return true;
            }

            int size = indices.Length;

            double baselineError = computeError();
            baselineError = upperBound(baselineError, size);

            int mostCommon = outputSubset.Mode();
            double pruneError = computeErrorWithoutSubtree(node, mostCommon);
            pruneError = upperBound(pruneError, size);

            DecisionNode maxChild = getMaxChild(node);
            double replaceError = computeErrorReplacingSubtrees(node, maxChild);
            replaceError = upperBound(replaceError, size);

            bool changed = false;
            if (Math.Abs(pruneError - baselineError) < limit ||
                Math.Abs(replaceError - baselineError) < limit)
            {
                if (replaceError < pruneError)
                {
                    // We should replace the subtree with its maximum child
                    node.Branches = maxChild.Branches;
                    node.Output = maxChild.Output;
                    foreach (var child in node.Branches)
                        child.Parent = node;
                }
                else
                {
                    // We should prune the subtree
                    node.Branches = null;
                    node.Output = mostCommon;
                }

                changed = true;

                foreach (var child in node)
                    subsets[child].Clear();

                double[][] inputSubset = inputs.Get(indices);
                for (int i = 0; i < inputSubset.Length; i++)
                    trackDecisions(node, inputSubset[i], i);
            }

            return changed;
        }
Exemple #45
0
 private void Prune(DecisionNode node)
 {
     if (node.Children != null)
     {
         var children = node.Children.ToList();
         for (int index = children.Count - 1; index >= 0; index--)
         {
             var child = children[index];
             if (child.Statistics.DatasetLength < Options.MinItemsOnNode ||
                 (child.Depth > Options.MaxTreeDepth && Options.MaxTreeDepth > 0))
             {
                 children.Remove(child);
             }
             else
             {
                 Prune(child);
             }
         }
         node.Children = children.ToArray();
     }
 }
        private double computeError(DecisionNode node)
        {
            List<int> indices = info[node].subset;

            int error = 0;
            foreach (int i in indices)
                if (outputs[i] != actual[i]) error++;
            return error / (double)indices.Count;
        }
 private void createCache(DecisionNode current)
 {
     foreach (var node in tree.Traverse(DecisionTreeTraversal.BreadthFirst, current))
         subsets[node] = new List<int>();
 }
        private double computeGain(DecisionNode node)
        {
            if (node.IsLeaf) return Double.NegativeInfinity;

            // Compute the sum of misclassifications at the children
            double sum = 0;
            foreach (var child in node.Branches)
                sum += info[child].error;

            // Get the misclassifications at the current node
            double current = info[node].error;

            // Compute the expected gain at the current node:
            return sum - current;
        }
 public DecisionTree(Minion owner, DecisionNode root)
 {
     _root = root;
     _owner = owner;
 }
 private void trackDecisions(DecisionNode current, double[][] input)
 {
     for (int i = 0; i < input.Length; i++)
         trackDecisions(current, input[i], i);
 }
Exemple #51
0
        private static double[] ComputeEstimates(IDataRow row, DecisionNode node)
        {
            var rowValue = row[node.Attribute];
            switch (node.Condition)
            {
                case PredicateCondition.Equal:
                    if (!row[node.Attribute].Equals(node.ThreshHold))
                    {
                        return null;
                    }
                    break;
                case PredicateCondition.LessThanOrEqual:
                    if ((rowValue == null) || (Convert.ToDouble(rowValue) > Convert.ToDouble(node.ThreshHold)))
                    {
                        return null;
                    }
                    break;
                case PredicateCondition.GreaterThan:
                    if ((rowValue == null) || (Convert.ToDouble(rowValue) <= Convert.ToDouble(node.ThreshHold)))
                    {
                        return null;
                    }
                    break;
                default:
                    return null;
            }

            if (node.Children != null && node.Children.Any())
            {
                foreach (var child in node.Children)
                {
                    var estimates = ComputeEstimates(row, child);
                    if (estimates != null)
                    {
                        return estimates;
                    }
                }
            }
            else
            {
                var estimates = new double[node.Statistics.Frequencies.Length];
                for (int index = 0; index < estimates.Length; index++)
                {
                    estimates[index] = node.Statistics.Frequencies[index]/(double) node.Statistics.DatasetLength;
                }
                return estimates;
            }

            return null;
        }