/*********************************************************************** This file is part of KEEL-software, the Data Mining tool for regression, classification, clustering, pattern mining and so on. Copyright (C) 2004-2010 F. Herrera (herrera@decsai.ugr.es) L. S�nchez (luciano@uniovi.es) J. Alcal�-Fdez (jalcala@decsai.ugr.es) S. Garc�a (sglopez@ujaen.es) A. Fern�ndez (alberto.fernandez@ujaen.es) J. Luengo (julianlm@decsai.ugr.es) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ **********************************************************************/ /** * <p> * @author Written by Manuel Moreno (Universidad de C�rdoba) 01/07/2008 * @version 0.1 * @since JDK 1.5 *</p> */ package keel.Algorithms.Decision_Trees.CART.tree; /** * * Class that implements a tree used by the CART algorithm * */ public class TreeNode { /** * Link to this node's parent. * Null when this node is the root of the tree */ private TreeNode parent; /** Left son */ private TreeNode leftSon; /** Right son */ private TreeNode rightSon; /** Index of patterns from data set included in this node */ private int[] patterns; /** Input variable index */ private int variable = -1; /** Split value */ private double value = -1; /** Output class associated with this node. Index to data set output class */ private int outputClass = -1; /** Output value associated with this node. Only used in regression problems */ private double outputValue = -1; /** Impurities associated to this node. This improve the algorithm performance*/ private double impurities; ///////////////////////////////////////////////////////////////////// // ------------------------------------------------------ Constructor ///////////////////////////////////////////////////////////////////// /** * Default Constructor */ public TreeNode(TreeNode parent) { super(); this.parent = parent; } /** * Constructor * @param patterns Index of patterns in this node */ public TreeNode(TreeNode parent, int[] patterns) { this.parent = parent; this.patterns = patterns; } ///////////////////////////////////////////////////////////////////// // ---------------------------------------------- Getters and Setters ///////////////////////////////////////////////////////////////////// /** * It gets the parent of the current node * * @return parent parent of current node */ public TreeNode getParent() { return parent; } /** * It sets the parent of the current node * * @param parent to set */ public void setParent(TreeNode parent) { this.parent = parent; } //////////////////////////////////////////////////////////////// /** * It gets the left son of the current node * * @return left son of current node. null if it is terminal */ public TreeNode getLeftSon() { return leftSon; } /** * @param leftSon son to set */ public void setLeftSon(TreeNode leftSon) { this.leftSon = leftSon; } //////////////////////////////////////////////////////////////// /** * @return right son of current node. null if it is terminal */ public TreeNode getRightSon() { return rightSon; } /** * @param rightSon to set */ public void setRightSon(TreeNode rightSon) { this.rightSon = rightSon; } //////////////////////////////////////////////////////////////// /** * @return the patterns */ public int[] getPatterns() { return patterns; } /** * @param patterns the patterns to set */ public void setPatterns(int[] patterns) { this.patterns = patterns; } //////////////////////////////////////////////////////////////// /** * @return the variable */ public int getVariable() { return variable; } /** * @param variable the variable to set */ public void setVariable(int variable) { this.variable = variable; } //////////////////////////////////////////////////////////////// /** * @return the value */ public double getValue() { return value; } /** * @param value the value to set */ public void setValue(double value) { this.value = value; } //////////////////////////////////////////////////////////////// /** * @return the outputClass */ public int getOutputClass() { return outputClass; } /** * @param outputClass the outputClass to set */ public void setOutputClass(int outputClass) { this.outputClass = outputClass; } /** * @return the outputValue */ public double getOutputValue() { return outputValue; } /** * @param outputValue the outputValue to set */ public void setOutputValue(double outputValue) { this.outputValue = outputValue; } //////////////////////////////////////////////////////////////// /** * @return the impurities */ public double getImpurities() { return impurities; } /** * @param impurities the impurities to set */ public void setImpurities(double impurities) { this.impurities = impurities; } ///////////////////////////////////////////////////////////////////// // --------------------------------------------------- Public methods ///////////////////////////////////////////////////////////////////// /** * @return depth of current node */ public int depth() { int leftDepth, rightDepth; if (leftSon != null) leftDepth = leftSon.depth(); else leftDepth = 0; if (rightSon != null) rightDepth = rightSon.depth(); else rightDepth = 0; return 1 + Math.max(leftDepth, rightDepth); } /** * @return true if node is leaf; false otherwise */ public boolean isTerminal() { if (leftSon == null && rightSon == null) return true; else return false; } /** * @param pattern pattern to evaluate * @param regression flag to determine whether it is a regression or classification problem */ public double evaluate(double [] pattern, boolean regression) { if (this.isTerminal()) { // if terminal return output class if (regression) return outputValue; else return outputClass; } else {// else, call proper son's evaluation if (pattern[variable] <= value) return leftSon.evaluate(pattern, regression); else return rightSon.evaluate(pattern, regression); } } /** * {@inheritDoc} */ public String toString() { String result = new String(); if (this.isTerminal()) if (outputClass != -1) result = "Class: "+outputClass+"\n"; else result = "Mean: "+outputValue+"\n"; else { result = "If "+ variable+" <= "+value+";\n "; //Class: "+outputClass+"\n"; if (leftSon != null) result += "Then "+leftSon.toString(); if (rightSon != null) result += "Else\n"+ rightSon.toString(); } return result; } }