public DecisionNode(int col, object value, DecisionNode tb, DecisionNode fb)
        {
            Col   = col;
            Value = value;

            Tb = tb;
            Fb = fb;
        }
        public Dictionary <string, float> MdClassify(object[] observation, DecisionNode tree)
        {
            if (tree.Results != null)
            {
                return(tree.Results.ToDictionary(r => r.Key, r => (float)r.Value));
            }
            var v = observation[tree.Col];

            if (v == null)
            {
                var tr     = MdClassify(observation, tree.Tb);
                var fr     = MdClassify(observation, tree.Fb);
                var tcount = tr.Values.Count;
                var fcount = fr.Values.Count;
                var tw     = tcount / (float)(tcount + fcount);
                var fw     = fcount / (float)(tcount + fcount);
                var result = tr.ToDictionary(trKvp => trKvp.Key, trKvp => trKvp.Value * tw);
                foreach (var frKvp in fr)
                {
                    if (!result.ContainsKey(frKvp.Key))
                    {
                        result.Add(frKvp.Key, 0);
                    }
                    result[frKvp.Key] += frKvp.Value * fw;
                }
                return(result);
            }
            else
            {
                DecisionNode branch;
                if (v is int || v is float)
                {
                    var val = v is int?Convert.ToInt32(v) : Convert.ToSingle(v);

                    var treeVal = tree.Value is int?Convert.ToInt32(tree.Value) : Convert.ToSingle(tree.Value);

                    branch = val >= treeVal ? tree.Tb : tree.Fb;
                }
                else
                {
                    branch = v.ToString() == tree.Value.ToString() ? tree.Tb : tree.Fb;
                }
                return(MdClassify(observation, branch));
            }
        }
        public void PrintTree(DecisionNode tree, string indent = "")
        {
            //是叶节点吗?
            if (tree.Results != null)
            {
                Console.WriteLine(JsonConvert.SerializeObject(tree.Results));
            }
            else
            {
                //打印判断条件
                Console.WriteLine($"{tree.Col}:{tree.Value}? ");

                //打印分支
                Console.Write($"{indent}T->");
                PrintTree(tree.Tb, indent + "  ");
                Console.Write($"{indent}F->");
                PrintTree(tree.Fb, indent + "  ");
            }
        }
        public Dictionary <string, int> Classify(object[] observation, DecisionNode tree)
        {
            if (tree.Results != null)
            {
                return(tree.Results);
            }
            var          v = observation[tree.Col];
            DecisionNode branch;

            if (v is int || v is float)
            {
                var val = v is int?Convert.ToInt32(v) : Convert.ToSingle(v);

                var treeVal = tree.Value is int?Convert.ToInt32(tree.Value) : Convert.ToSingle(tree.Value);

                branch = val >= treeVal ? tree.Tb : tree.Fb;
            }
            else
            {
                branch = v.ToString() == tree.Value.ToString() ? tree.Tb : tree.Fb;
            }
            return(Classify(observation, branch));
        }
        public void Prune(DecisionNode tree, float mingain)
        {
            //如果分支不是叶节点,则进行剪枝操作
            if (tree.Tb.Results == null)
            {
                Prune(tree.Tb, mingain);
            }
            if (tree.Fb.Results == null)
            {
                Prune(tree.Fb, mingain);
            }

            //如果两个子分支都是叶节点,则判断是否需要合并
            if (tree.Tb.Results != null && tree.Fb.Results != null)
            {
                //构造合并后的数据集
                IEnumerable <object[]> tb = new List <object[]>();
                IEnumerable <object[]> fb = new List <object[]>();
                tb = tree.Tb.Results.Aggregate(tb, (current, tbKvPair)
                                               => current.Union(ArrayList.Repeat(new object[] { tbKvPair.Key }, (int)tbKvPair.Value).Cast <object[]>()));
                fb = tree.Fb.Results.Aggregate(fb, (current, tbKvPair)
                                               => current.Union(ArrayList.Repeat(new object[] { tbKvPair.Key }, (int)tbKvPair.Value).Cast <object[]>()));

                //检查熵增加情况
                var mergeNode = tb.Union(fb).ToList();
                var delta     = Entropy(mergeNode) - (Entropy(tb.ToList()) + Entropy(fb.ToList()) / 2);
                Debug.WriteLine(delta);
                if (delta < mingain)
                {
                    //合并分支
                    tree.Tb      = null;
                    tree.Fb      = null;
                    tree.Results = UniqueCounts(mergeNode);
                }
            }
        }