// This function will recursively traverse the tree, matching // the Row with the current node Question, until we reach a Leaf. public DecisionNode Predict(Row row, DecisionNode node = null) { // If we don't have a root, we can't do anything if (root == null) { return(null); } if (node == null) { node = root; } // We return if this node is a Leaf if (node.IsLeaf) { return(node); } // If this row matches this Question, we enter the true branch if (node.question.Match(row)) { return(Predict(row, node.trueBranch)); } // Otherwise we use the false branch return(Predict(row, node.falseBranch)); }
private void predictionBtn_Click(object sender, EventArgs e) { if (features != null && features.All(item => item != null)) { DecisionNode node = tree.Predict(features); resultLabel.Text = PredictionToString(node); } }
private static string TreeToString(DecisionNode node, string spacing = "") { if (node.IsLeaf) { return($"{spacing}Resultado: {node}\n"); } string str = $"{spacing}{node.question}\n"; str += $"{spacing}--> Sí:\n"; str += TreeToString(node.trueBranch, spacing + " "); str += $"{spacing}--> No:\n"; str += TreeToString(node.falseBranch, spacing + " "); return(str); }
static TreeNode RenderTree(DecisionNode node) { if (node.IsLeaf) { return(new TreeNode($"Resultado: {node}")); } TreeNode treeNode = new TreeNode(node.question.ToString()); TreeNode trueBranch = treeNode.Nodes.Add("Verdadero"); _ = trueBranch.Nodes.Add(RenderTree(node.trueBranch)); TreeNode falseBrach = treeNode.Nodes.Add("Falso"); _ = falseBrach.Nodes.Add(RenderTree(node.falseBranch)); return(treeNode); }
// This function will recursively create the tree private static DecisionNode BuildTree(Dataset dataset) { // We find the best gain and question (double gain, Question question) = FindBestSplit(dataset); // Once we reach a gain of 0, this is the end of the route if (gain == 0) { return(new DecisionNode(dataset)); } // If there's more gain, we need to partition using the best question (Dataset trueRows, Dataset falseRows) = PartitionDataset(dataset, question); // Then we recursively generate the true and false branch and return that DecisionNode trueBranch = BuildTree(trueRows); DecisionNode falseBranch = BuildTree(falseRows); return(new DecisionNode(question, trueBranch, falseBranch)); }
private static string PredictionToString(DecisionNode node) { Dictionary <string, int> predictions = node.predictions; double total = predictions.Aggregate(0.0, (acc, x) => acc + x.Value); string str = "Predicción en base al árbol de decisión:\n"; int index = 1; foreach (KeyValuePair <string, int> elem in predictions) { int percent = (int)Math.Round(elem.Value / total * 100, 0); string key = elem.Key.FirstCharToUpper(); if (predictions.Count == 1) { str += $"{key} (Nivel de certeza: {percent}%)\n"; } else { str += $"Respuesta {index}: {key} (Nivel de certeza: {percent}%)\n"; } ++index; } return(str); }
// This function is used to generate the tree (aka training). // It will recursively work out each Node and save it with a // private method called BuildTree (defined below). public void Fit(Dataset dataset) { this.dataset = dataset; root = BuildTree(dataset); }
public DecisionNode(Question question, DecisionNode trueBranch, DecisionNode falseBranch) { this.question = question; this.trueBranch = trueBranch; this.falseBranch = falseBranch; }