Esempio n. 1
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 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);
            }
            }
        }