private static Tuple <TDecisionValue, double> HandleRegressionAndModelLeaf(
            IDataVector <TDecisionValue> vector,
            IDecisionTreeNode decisionTree,
            double probabilitiesProductSoFar)
        {
            var regressionLeaf = decisionTree as IDecisionTreeRegressionAndModelLeaf;
            var numericVector  = vector.NumericVector.ToList();

            numericVector.Insert(0, 1.0);
            var vectorWithIntercept = Vector <double> .Build.DenseOfArray(numericVector.ToArray());

            double predictedVal = 0.0;

            if (regressionLeaf.ModelWeights != null)
            {
                predictedVal =
                    vectorWithIntercept.DotProduct(Vector <double> .Build.DenseOfArray(regressionLeaf.ModelWeights.ToArray()));
            }
            else
            {
                predictedVal = regressionLeaf.DecisionMeanValue;
            }
            return(new Tuple <TDecisionValue, double>(
                       (TDecisionValue)Convert.ChangeType(predictedVal, typeof(TDecisionValue)),
                       probabilitiesProductSoFar));
        }
Beispiel #2
0
 private void DoExtractPatterns(IDecisionTreeNode node,
                                List <SelectorContext> contexts, InstanceModel model,
                                Action <EmergingPattern> patternFound,
                                Feature classFeature)
 {
     if (node.IsLeaf)
     {
         EmergingPattern newPattern = Create(contexts, model, classFeature);
         newPattern.Counts     = node.Data;
         newPattern.Supports   = CalculateSupports(node.Data, classFeature);
         newPattern.ClassValue = newPattern.Supports.ArgMax();
         if (patternFound != null)
         {
             patternFound(newPattern);
         }
     }
     else
     {
         for (int i = 0; i < node.Children.Length; i++)
         {
             SelectorContext context = new SelectorContext
             {
                 Index    = i,
                 Selector = node.ChildSelector,
             };
             contexts.Add(context);
             DoExtractPatterns(node.Children[i], contexts, model, patternFound,
                               classFeature);
             contexts.Remove(context);
         }
     }
 }
Beispiel #3
0
 /// <summary>
 /// Creates a new decision node.
 /// </summary>
 /// <param name="test">
 /// Function which will make the true or false decision.
 /// </param>
 /// <param name="trueNode">
 /// DT node to return when the decision is true.
 /// </param>
 /// <param name="falseNode">
 /// DT node to return when the decision is false.
 /// </param>
 public DecisionNode(
     Func <bool> test,
     IDecisionTreeNode trueNode, IDecisionTreeNode falseNode)
 {
     this.decisionFunc = test;
     this.trueNode     = trueNode;
     this.falseNode    = falseNode;
 }
Beispiel #4
0
        /// <summary>
        /// Make a decision.
        /// </summary>
        /// <returns>
        /// A DT node, which will depend wether the decision was true or false.
        /// </returns>
        public IDecisionTreeNode MakeDecision()
        {
            // Determine the branch to take depending on the decision function
            IDecisionTreeNode branch = decisionFunc() ? trueNode : falseNode;

            // Recursively return the branch returned by the selected branch
            return(branch.MakeDecision());
        }
 private double[] ClassifyInstance(IDecisionTreeNode node, Instance instance, double instanceMembership)
 {
     if (node.IsLeaf)
     {
         return(node.Data.MultiplyBy(instanceMembership));
     }
     double[] childrenSelection = node.ChildSelector.Select(instance);
     if (childrenSelection != null)
     {
         if (childrenSelection.Length != node.Children.Length)
         {
             throw new IndexOutOfRangeException("Child index is out of range");
         }
         double[] result = null;
         for (int i = 0; i < childrenSelection.Length; i++)
         {
             double selection = childrenSelection[i];
             if (selection > 0)
             {
                 IDecisionTreeNode child      = node.Children[i];
                 double[]          childValue = ClassifyInstance(child, instance, instanceMembership);
                 if (result != null)
                 {
                     result = result.AddTo(childValue);
                 }
                 else
                 {
                     result = childValue;
                 }
             }
         }
         return(result);
     }
     else
     {
         double[] result = null;
         double   totalNodeMembership = node.Data.Sum();
         for (int i = 0; i < node.Children.Length; i++)
         {
             IDecisionTreeNode child           = node.Children[i];
             double            childMembership = node.Children[i].Data.Sum();
             double[]          childValue      = ClassifyInstance(child, instance, childMembership / totalNodeMembership * instanceMembership);
             if (result != null)
             {
                 result = result.AddTo(childValue);
             }
             else
             {
                 result = childValue;
             }
         }
         return(result);
     }
 }
Beispiel #6
0
    public IDecisionTreeNode MakeDecision()
    {
        IDecisionTreeNode branch = GetBranch();

        if (branch != null)
        {
            branch = branch.MakeDecision();
        }

        return(branch);
    }
Beispiel #7
0
        public static IDecisionTreeNode Do(this IDecisionTreeNode self,
                                           IDecisionTreeNode node)
        {
            if (self is BaseDecision bd)
            {
                bd.TrueNode = node;
                return(self);
            }

            log.Error("You can use it only with BaseDecision");
            return(self);
        }
        public IPredictionModel BuildModel(IDataFrame dataFrame, string dependentFeatureName, IModelBuilderParams additionalParams)
        {
            if (!(additionalParams is IRandomForestModelBuilderParams))
            {
                throw new ArgumentException("Invalid parameters passed to Random Forest Model builder!");
            }

            var randomForestParams = additionalParams as IRandomForestModelBuilderParams;

            var trees     = new IDecisionTreeNode[randomForestParams.TreesCount];
            var oobErrors = new double[randomForestParams.TreesCount];

            var columnsCountToTake = featuresToUseCountCalculator(dataFrame.ColumnsCount - 1);
            var featureColumns     = dataFrame.ColumnNames.Except(new[] { dependentFeatureName }).ToList();
            var randomizer         = new Random();
            var locker             = new object();

            Parallel.For(
                0,
                randomForestParams.TreesCount,
                i =>
            {
                var localRandomizer         = new Random(i.GetHashCode());
                var randomlySelectedIndices =
                    Enumerable.Range(0, dataFrame.RowCount)
                    .Select(_ => localRandomizer.Next(0, dataFrame.RowCount))
                    .ToList();
                var outOfBagIndices =
                    Enumerable.Range(0, dataFrame.RowCount).Except(randomlySelectedIndices).ToList();
                var columnsToTake = new List <string>();
                columnsToTake     = featureColumns.Shuffle(localRandomizer).Take(columnsCountToTake).ToList();

                columnsToTake.Add(dependentFeatureName);

                var baggedTestData = dataFrame.Slice(randomlySelectedIndices, columnsToTake);
                var oobTestData    = dataFrame.Slice(outOfBagIndices, columnsToTake);
                var oobExpected    = oobTestData.GetColumnVector <TPredictionVal>(dependentFeatureName).Values;

                var decisionTree = decisionTreeModelBuilder.BuildModel(
                    baggedTestData,
                    dependentFeatureName,
                    decisionTreeModelBuilderParamsFactory());
                var prediction = decisionTreePredictor.Predict(oobTestData, decisionTree, dependentFeatureName);

                //TODO: AAA !!! Later on add support for calculating variable importance!!!
                var oobError = dataQualityMeasure.CalculateError(oobExpected, prediction);
                trees[i]     = decisionTree as IDecisionTreeNode;
                oobErrors[i] = oobError;
            });

            return(new RandomForestModel(trees, oobErrors));
        }
Beispiel #9
0
        public void TestDecisionTreeStructure()
        {
            IDecisionTreeNode first = new DecisionTreeLeafNode(2);
            var tree = new DecisionTree(first);

            AreEqual(2, tree.Classify(new[] { 1, 2, 3 }));
            var tests = new IDecisionTreeNode[]
            {
                new DecisionTreeLeafNode(0), new DecisionTreeLeafNode(0),
                new DecisionTreeLeafNode(1), new DecisionTreeLeafNode(2)
            };

            first = new DecisionTreeInternalNode(1, tests);
            tree  = new DecisionTree(first);
            int[][] x = { new[] { 0, 0 }, new[] { 0, 1 }, new[] { 0, 2 } };
            for (var i = 0; i < 3; i++)
            {
                AreEqual(x[i][1], tree.Classify(x[i]));
            }
        }
        private bool Prune(IDecisionTreeNode node)
        {
            if (node.IsLeaf)
            {
                return(true);
            }
            bool allPrunned = true;

            foreach (IDecisionTreeNode child in node.Children)
            {
                bool childPrunned = Prune(child);
                allPrunned = allPrunned && childPrunned;
            }
            if (allPrunned && PruneTester.CanPrune(node))
            {
                node.ChildSelector = null;
                node.Children      = null;
            }
            return(false);
        }
        public string ToString(int ident, InstanceModel model, int digits = -1)
        {
            // "-[2,3]\n -IntFeature<=4 [1,1]\n -IntFeature>4 [1,2]"
            StringBuilder builder = new StringBuilder();

            builder.Append(Data.ToStringEx(digits));
            if (!IsLeaf)
            {
                for (int i = 0; i < Children.Length; i++)
                {
                    IDecisionTreeNode child = Children[i];
                    builder.Append("\n");
                    builder.Append(' ', (ident + 1) * 3);
                    builder.Append("- ");
                    builder.Append(ChildSelector.ToString(model, i));
                    builder.Append(' ');
                    builder.Append(child.ToString(ident + 1, model));
                }
            }
            return(builder.ToString());
        }
Beispiel #12
0
    // Create the decision tree
    protected override void Start()
    {
        // Call base class Start()
        base.Start();

        // Create the leaf actions
        IDecisionTreeNode seek    = new ActionNode(SeekAction);
        IDecisionTreeNode nothing = new ActionNode(StandStillAction);
        IDecisionTreeNode patrol  = new ActionNode(PatrolAction);

        // Create the random decision behaviour node
        RandomDecisionBehaviour rdb = new RandomDecisionBehaviour(
            () => Random.value,
            () => Time.frameCount,
            randomDecisionDurationInFrames,
            0.55f);
        IDecisionTreeNode rndNode = new DecisionNode(
            rdb.RandomDecision, seek, nothing);

        // Create the root node
        root = new DecisionNode(PlayerInSight, rndNode, patrol);
    }
 public IDecisionTreeLink GetChildLinkForChild(IDecisionTreeNode child)
 {
     return(this.LinksByChildren[child]);
 }
 private int ComputeLeaves(IDecisionTreeNode decisionTree)
 {
     return(decisionTree.IsLeaf ? 1 : decisionTree.Children.Sum(childs => ComputeLeaves(childs)));
 }
Beispiel #15
0
        private void FillNode(ref Dictionary <IDecisionTreeNode, double> validityIndexByNode, InstanceModel model, ref Dictionary <IDecisionTreeNode, IEnumerable <Tuple <Instance, double> > > instancesByNode,
                              Feature classFeature, ref Dictionary <IDecisionTreeNode, int> levelByNode, List <SelectorContext> currentContext, ref int leafCount)
        {
            IDecisionTreeNode node           = null;
            double            bestIndexValue = Double.MinValue;

            foreach (var currentNode in validityIndexByNode.Keys)
            {
                if (bestIndexValue < validityIndexByNode[currentNode])
                {
                    bestIndexValue = validityIndexByNode[currentNode];
                    node           = currentNode;
                }
            }

            if (node != null)
            {
                int level     = levelByNode[node];
                var instances = instancesByNode[node];

                int whichBetterToFind = 1;
                if (OnSelectingWhichBetterSplit != null)
                {
                    whichBetterToFind = OnSelectingWhichBetterSplit(node, level);
                }
                WiningSplitSelector winingSplitSelector = new WiningSplitSelector(whichBetterToFind)
                {
                    CanAcceptChildSelector = this.CanAcceptChildSelector,
                };
                foreach (var feature in OnSelectingFeaturesToConsider(model.Features, level))
                {
                    if (feature != classFeature)
                    {
                        ISplitIterator splitIterator = SplitIteratorProvider.GetSplitIterator(model, feature, classFeature);
                        if (splitIterator == null)
                        {
                            throw new InvalidOperationException(string.Format("Undefined iterator for feature {0}",
                                                                              feature));
                        }
                        splitIterator.Initialize(feature, instances);
                        while (splitIterator.FindNext())
                        {
                            double currentGain = DistributionEvaluator.Evaluate(node.Data,
                                                                                splitIterator.CurrentDistribution);
                            if (currentGain > MinimalSplitGain || leafCount < ClusterCount)
                            {
                                if (OnSplitEvaluation != null)
                                {
                                    OnSplitEvaluation(node, splitIterator, currentContext);
                                }
                                winingSplitSelector.EvaluateThis(currentGain, splitIterator, level);
                            }
                        }
                    }
                }

                if (winingSplitSelector.IsWinner())
                {
                    IChildSelector maxSelector = winingSplitSelector.WinningSelector;
                    node.ChildSelector = maxSelector;
                    node.Children      = new IDecisionTreeNode[maxSelector.ChildrenCount];
                    var instancesPerChildNode =
                        childrenInstanceCreator.CreateChildrenInstances(instances, maxSelector, double.MinValue);

                    for (int i = 0; i < maxSelector.ChildrenCount; i++)
                    {
                        var childNode = new DecisionTreeNode {
                            Parent = node
                        };
                        node.Children[i] = childNode;
                        childNode.Data   = winingSplitSelector.WinningDistribution[i];
                        SelectorContext context = null;
                        if (OnSplitEvaluation != null)
                        {
                            context = new SelectorContext
                            {
                                Index    = i,
                                Selector = node.ChildSelector,
                            };
                            currentContext.Add(context);
                        }

                        double currentBestValidityIndex = double.MinValue;
                        foreach (var feature in OnSelectingFeaturesToConsider(model.Features, level))
                        {
                            if (feature != classFeature)
                            {
                                ISplitIterator splitIterator = SplitIteratorProvider.GetSplitIterator(model, feature, classFeature);
                                if (splitIterator == null)
                                {
                                    throw new InvalidOperationException(string.Format("Undefined iterator for feature {0}",
                                                                                      feature));
                                }
                                splitIterator.Initialize(feature, instancesPerChildNode[i]);
                                while (splitIterator.FindNext())
                                {
                                    double currentGain = DistributionEvaluator.Evaluate(node.Data,
                                                                                        splitIterator.CurrentDistribution);
                                    if (currentGain > currentBestValidityIndex)
                                    {
                                        if (OnSplitEvaluation != null)
                                        {
                                            OnSplitEvaluation(node, splitIterator, currentContext);
                                        }

                                        currentBestValidityIndex = currentGain;
                                    }
                                }
                            }
                        }

                        if (currentBestValidityIndex > validityIndexByNode[node] || leafCount < ClusterCount)
                        {
                            validityIndexByNode.Add(childNode, currentBestValidityIndex);
                            instancesByNode.Add(childNode, instancesPerChildNode[i]);
                            levelByNode.Add(childNode, level + 1);
                        }

                        if (OnSplitEvaluation != null)
                        {
                            currentContext.Remove(context);
                        }
                    }

                    validityIndexByNode.Remove(node);
                    instancesByNode.Remove(node);
                    levelByNode.Remove(node);
                    leafCount++;

                    if (leafCount < 4 * ClusterCount)
                    {
                        FillNode(ref validityIndexByNode, model, ref instancesByNode, classFeature, ref levelByNode, currentContext, ref leafCount);
                    }
                }
            }
        }
 public void Init(IDecisionTreeNode trueNode, IDecisionTreeNode falseNode)
 {
     TrueNode  = trueNode;
     FalseNode = falseNode;
 }
 private int ComputeSizeTree(IDecisionTreeNode decisionTree)
 {
     return(decisionTree.Children == null
                ? 0
                : decisionTree.Children.Select(ComputeSizeTree).Concat(new[] { 0 }).Max() + 1);
 }
 public void SetDecisionTree(IDecisionTreeNode decisionTree) =>
 this.decisionTree = CurrentDecision = decisionTree;
Beispiel #19
0
 public DecisionTree(IDecisionTreeNode root)
 {
     _root = root;
 }
        private static IDecisionTreeNode IterativeDichotomiser3(int[,] x, int[] y, List <int> attributes)
        {
            var distinctLabelCount = y.Distinct().Count();

            if (x.Length == 0)
            {
                return(new DecisionTreeLeafNode(0));
            }

            switch (distinctLabelCount)
            {
            case 1:
                return(new DecisionTreeLeafNode(y[0]));

            default:
            {
                if (attributes.Count == 0)
                {
                    return(new DecisionTreeLeafNode(MajorLabel(y, distinctLabelCount)));
                }

                var attributeTest = BestAttribute(x, y, attributes);
                if (attributeTest == -1)
                {
                    return(new DecisionTreeLeafNode(MajorLabel(y, distinctLabelCount)));
                }

                attributes.Remove(attributeTest);
                var attributeStateCount = 0;
                for (var i = 0; i < y.Length; i++)
                {
                    if (x[i, attributeTest] > attributeStateCount)
                    {
                        attributeStateCount = x[i, attributeTest];
                    }
                }

                ++attributeStateCount;
                attributeStateCount = Math.Max(_discreteClasses * 2, attributeStateCount);

                // Split data
                var subX = new int[attributeStateCount][, ];
                var subY = new int[attributeStateCount][];
                var attributeSubXCount = new int[attributeStateCount];
                for (var i = 0; i < y.Length; i++)
                {
                    ++attributeSubXCount[x[i, attributeTest]];
                }

                var attributeLength = x.Length / y.Length;
                for (var i = 0; i < attributeStateCount; i++)
                {
                    subX[i] = new int[attributeSubXCount[i], attributeLength];
                    subY[i] = new int[attributeSubXCount[i]];
                }

                var subXAttributeFormCount = new int[attributeStateCount];
                for (var i = 0; i < y.Length; i++)
                {
                    for (var j = 0; j < attributeLength; j++)
                    {
                        subX[x[i, attributeTest]][subXAttributeFormCount[x[i, attributeTest]], j] = x[i, j];
                    }

                    subY[x[i, attributeTest]][subXAttributeFormCount[x[i, attributeTest]]] = y[i];
                    ++subXAttributeFormCount[x[i, attributeTest]];
                }

                // Create tests
                var tests = new IDecisionTreeNode[attributeStateCount];
                for (var i = 0; i < attributeStateCount; i++)
                {
                    if (subX[i].Length == 0)
                    {
                        tests[i] = new DecisionTreeLeafNode(MajorLabel(y, distinctLabelCount));
                    }
                    else
                    {
                        tests[i] = IterativeDichotomiser3(subX[i], subY[i],
                                                          attributes.GetRange(0, attributes.Count));
                    }
                }

                IDecisionTreeNode root = new DecisionTreeInternalNode(attributeTest, tests);

                return(root);
            }
            }
        }
Beispiel #21
0
 public LoggingDecorator(IDecisionTreeNode decision, DebugInfo debugInfo)
 {
     this.decision  = decision;
     this.debugInfo = debugInfo;
 }
        private static Tuple <TDecisionValue, double> HandleLeaf(IDataVector <TDecisionValue> vector, IDecisionTreeNode decisionTree, double probabilitiesProductSoFar)
        {
            if (decisionTree is IDecisionTreeRegressionAndModelLeaf)
            {
                return(HandleRegressionAndModelLeaf(vector, decisionTree, probabilitiesProductSoFar));
            }
            var classificationLeaf = decisionTree as IDecisionTreeLeaf;

            return(new Tuple <TDecisionValue, double>((TDecisionValue)classificationLeaf.LeafValue, probabilitiesProductSoFar));
        }
        private Tuple <TDecisionValue, double> ProcessInstance(IDataVector <TDecisionValue> vector, IDecisionTreeNode decisionTree, double probabilitiesProductSoFar)
        {
            if (decisionTree is IDecisionTreeLeaf)
            {
                return(HandleLeaf(vector, decisionTree, probabilitiesProductSoFar));
            }
            var parentNode = decisionTree as IDecisionTreeParentNode;

            if (parentNode is IBinaryDecisionTreeParentNode)
            {
                return(this.ProcessBinarySplit(vector, parentNode as IBinaryDecisionTreeParentNode, probabilitiesProductSoFar));
            }
            return(this.ProcessMultiValueSplit(vector, parentNode, probabilitiesProductSoFar));
        }
 public object GetTestResultForChild(IDecisionTreeNode child)
 {
     return(this.TestResultsByChildren[child]);
 }