public void Process()
        {
            Attribute[] attributes =
                StaticStorage.DataSet.Columns.Cast<DataColumn>().Where(m => !m.ColumnName.Equals(StaticStorage.TargetColum))
                    .Select(
                        m =>
                            new Attribute(m.ColumnName,
                                StaticStorage.DataSet.AsEnumerable()
                                    .Select(i => i[m.ColumnName].ToString().Format())
                                    .ToArray()
                                    .Distinct()
                                    .ToArray())).ToArray();

            DecisionTreeId3 id3 = new DecisionTreeId3();
            TreeNode root = id3.MountTree(StaticStorage.DataSet, StaticStorage.TargetColum, attributes);

            PrintNode(root, "");
        }
        private TreeNode InternalMountTree(DataTable samples, string targetAttribute,
            IReadOnlyCollection<Attribute> attributes)
        {
            if (AllSamplesPositives(samples, targetAttribute))
                return new TreeNode(new Attribute(true));

            if (AllSamplesNegatives(samples, targetAttribute))
                return new TreeNode(new Attribute(false));

            if (attributes.Count == 0)
                return new TreeNode(new Attribute(GetMostCommonValue(samples, targetAttribute)));

            _total = samples.Rows.Count;
            _targetAttribute = targetAttribute;
            _totalPositives = CountTotalPositives(samples);

            _mEntropySet = CalcEntropy(_totalPositives, _total - _totalPositives);

            Attribute bestAttribute = GetBestAttribute(samples, attributes);

            TreeNode root = new TreeNode(bestAttribute);

            DataTable aSample = samples.Clone();

            foreach (string value in bestAttribute.Values)
            {
                // Select all the elements with this Attribute value
                aSample.Rows.Clear();

                DataRow[] rows = samples.Select(bestAttribute.AttributeName + " = " + "'" + value + "'");

                foreach (DataRow row in rows)
                    aSample.Rows.Add(row.ItemArray);

                // Select all the elements with this Attribute value

                // Create a new list of attributes less the current Attribute that is the best Attribute
                ArrayList aAttributes = new ArrayList(attributes.Count - 1);
                foreach (
                    Attribute attribute in
                        attributes.Where(attribute => attribute.AttributeName != bestAttribute.AttributeName))
                    aAttributes.Add(attribute);

                // Create a new list of attributes less the current Attribute that is the best Attribute

                if (aSample.Rows.Count == 0)
                    return new TreeNode(new Attribute(GetMostCommonValue(aSample, targetAttribute)));

                DecisionTreeId3 dc3 = new DecisionTreeId3();
                TreeNode childNode = dc3.MountTree(aSample, targetAttribute,
                    (Attribute[])aAttributes.ToArray(typeof(Attribute)));
                root.AddTreeNode(childNode, value);
            }

            return root;
        }