public int CountNodes(Node node) { int result = 1; if (node.GetLeft() != null) result += CountNodes(node.GetLeft()); if (node.GetRight() != null) result += CountNodes(node.GetRight()); return result; }
public int CountLeafLastNodes(Node node) { int result = 0; if (node.GetLeft() != null) result += CountLeafLastNodes(node.GetLeft()); if (node.GetRight() != null) result += CountLeafLastNodes(node.GetRight()); if (node.GetLeft() == null && node.GetRight() == null) return node.leaf; return result; }
public void Algorithm(double[][] dataInput, Node node) { /* * Choose class for node if is the case. */ node.classType = sameClass(dataInput); if (node.classType != -1) { node.leaf = dataInput.Length; return; } node.classType = sameAtributtes(dataInput); if (node.classType != -1) { node.leaf = dataInput.Length; return; } /* * Choose best axis-parallel split node for dataInput. */ bestAxisParallel(dataInput, node); /* * Apply OC1 */ Node auxNode = (Node)node.Clone(); for (int i = 0; i < R; i++) { if (i > 0) auxNode.Random(); step1: double initialGain = gain(dataInput, node); // Gain for better node. for (int d = 0; d < dataInput[0].Length; d++) { pertube(d, auxNode, dataInput); if (gain(dataInput, auxNode) > initialGain) { node.SetNode(auxNode); break; } } // step 2 initialGain = gain(dataInput, node); for (int j = 0; j < J; j++) { Random rand = new Random(); int direction = rand.Next(dataInput[0].Length - 1); pertube(direction, auxNode, dataInput); if (gain(dataInput, auxNode) > initialGain) { node.SetNode(auxNode); goto step1; } } if (gain(dataInput, auxNode) > gain(dataInput, node)) node.SetNode(auxNode); } /* * Recursive Algorithm for each branch for node. */ Node left = new Node(new double[dataInput[0].Length], 0); Node right = new Node(new double[dataInput[0].Length], 0); node.SetLeft(left); node.SetRight(right); List<double[]>[] data = divideData(dataInput, node); Algorithm(data[0].ToArray(), node.GetLeft()); Algorithm(data[1].ToArray(), node.GetRight()); }
private void pertube(int m, Node node, double[][] dataInput) { if (!node.ActiveAtributtes[m]) return; Node auxNode = (Node)node.Clone(); double[] U = new double[dataInput.Length]; for (int i = 0; i < dataInput.Length; i++) U[i] = Math.Min((node.weights[m] * dataInput[i][m] - node.Evaluate(dataInput[i])) / dataInput[i][m], 0); Array.Sort(U); int bestA = 0; int dif = Int16.MaxValue; for (int i = 0; i < U.Length; i++) { int positive = 0; int negative = 0; for (int j = 0; j < U.Length; j++) { if (j <= i && U[j] <= 0) negative++; else if (j > i && U[j] > 0) positive++; } if (Math.Abs(positive - negative) < dif) { dif = Math.Abs(positive - negative); bestA = i; } } auxNode.weights[m] = U[bestA]; if (gain(dataInput, auxNode) > gain(dataInput, node)) { node.weights[m] = U.Max(); node.ResetPmove(); } else if (gain(dataInput, auxNode) == gain(dataInput, node)) { if(node.EvaluatePmove()) node.weights[m] = U.Max(); node.DecreasePmove(); } }
private void bestAxisParallel(double[][] dataInput, Node n) { bool[] dimensionUsed = new bool[dataInput[0].Length]; dimensionUsed[dataInput[0].Length - 1] = true; for (int k = 0; k < _k; k++) { int bestDimension = 0; double bestGain = gain(dataInput, n); for (int d = 0; d < dataInput[0].Length; d++) { if (!dimensionUsed[d]) { n.weights[d] = 1; for (int i = 0; i < dataInput.Length; i++) { double baias = n.baias; n.SetBaias(dataInput[i]); if (gain(dataInput, n) > bestGain) { bestDimension = d; bestGain = gain(dataInput, n); } else n.baias = baias; } n.weights[d] = 0; } } dimensionUsed[bestDimension] = true; n.weights[bestDimension] = 1; n.Activate(bestDimension); } }
private static double gain(double[][] input, Node node) { double gain = entropy(input); List<double[]>[] dataGroups = divideData(input, node); for (int i = 0; i < 2; i++) { if(dataGroups[i].Count > 0) gain -= (dataGroups[i].Count * entropy(dataGroups[i].ToArray())) / input.Length; } return gain; }
/* * data[0]: left * data[1]: right */ private static List<double[]>[] divideData(double[][] input, Node node) { List<double[]>[] data = new List<double[]>[2]; data[0] = new List<double[]>(); data[1] = new List<double[]>(); for (int i = 0; i < input.Length; i++) { if (node.Evaluate(input[i]) < 0) //Curioso caso. data[0].Add(input[i]); else data[1].Add(input[i]); } return data; }
private void setParent(Node parent) { _parent = parent; }
public void SetRight(Node right) { _right = right; _right.setParent(this); }
public void SetNode(Node input) { for (int i = 0; i < weights.Length; i++) { weights[i] = input.weights[i]; } baias = input.baias; }
public void SetLeft(Node left) { _left = left; _left.setParent(this); }
public DesicionTree(Node root) { _root = root; }
private void Prunning(int n, Node node) { if (node.GetLeft() != null) Prunning(n, node.GetLeft()); if (node.GetRight() != null) Prunning(n, node.GetRight()); if (node.GetRight() == null && node.GetLeft() == null) return; if (node.GetRight() == null && node.GetLeft().leaf < n) { node.leaf += node.GetLeft().leaf; node.classType = node.GetLeft().classType; node.RemoveLeft(); } else if (node.GetLeft() == null && node.GetRight().leaf < n) { node.leaf += node.GetRight().leaf; node.classType = node.GetRight().classType; node.RemoveRight(); } else if (node.GetRight().leaf < n && node.GetLeft().leaf >= n) { node.classType = node.GetRight().classType; node.leaf += node.GetRight().leaf; node.RemoveRight(); } else if (node.GetRight().leaf >= n && node.GetLeft().leaf < n) { node.classType = node.GetLeft().classType; node.leaf += node.GetLeft().leaf; node.RemoveLeft(); } else if (node.GetRight().leaf < n && node.GetLeft().leaf < n) { if (node.GetRight().leaf > node.GetLeft().leaf) node.classType = node.GetRight().classType; else node.classType = node.GetLeft().classType; node.leaf += node.GetLeft().leaf + node.GetRight().leaf; node.RemoveLeft(); node.RemoveRight(); } }