当前位置:文档之家› 决策树程序实验

决策树程序实验

决策树程序实验众所周知,数据库技术从20世纪80年代开始,已经得到广泛的普及和应用。

随着数据库容量的膨胀,特别是数据仓库以及web等新型数据源的日益普及,人们面临的主要问题不再是缺乏足够的信息可以使用,而是面对浩瀚的数据海洋如何有效地利用这些数据。

从数据中生成分类器的一个特别有效的方法是生成一个决策树(Decision Tree)。

决策树表示方法是应用最广泛的逻辑方法之一,它从一组无次序、无规则的事例中推理出决策树表示形式的分类规则。

决策树分类方法采用自顶向下的递归方式,在决策树的内部结点进行属性值的比较并根据不同的属性值判断从该结点向下的分支,在决策树的叶结点得到结论。

所以从决策树的根到叶结点的一条路径就对应着一条合取规则,整棵决策树就对应着一组析取表达式规则。

决策树是应用非常广泛的分类方法,目前有多种决策树方法,如ID3、CN2、SLIQ、SPRINT等。

一、问题描述相关信息决策树是一个类似于流程图的树结构,其中每个内部结点表示在一个属性上的测试,每个分支代表一个测试输入,而每个树叶结点代表类或类分布。

数的最顶层结点是根结点。

一棵典型的决策树如图1所示。

它表示概念buys_computer,它预测顾客是否可能购买计算机。

内部结点用矩形表示,而树叶结点用椭圆表示。

为了对未知的样本分类,样本的属性值在决策树上测试。

决策树从根到叶结点的一条路径就对应着一条合取规则,因此决策树容易转化成分类规则。

图1ID3算法:■决策树中每一个非叶结点对应着一个非类别属性,树枝代表这个属性的值。

一个叶结点代表从树根到叶结点之间的路径对应的记录所属的类别属性值。

■每一个非叶结点都将与属性中具有最大信息量的非类别属性相关联。

■采用信息增益来选择能够最好地将样本分类的属性。

信息增益基于信息论中熵的概念。

ID3总是选择具有最高信息增益(或最大熵压缩)的属性作为当前结点的测试属性。

该属性使得对结果划分中的样本分类所需的信息量最小,并反映划分的最小随机性或“不纯性”。

问题重述1、目标概念为“寿险促销”2、计算每个属性的信息增益3、确定根节点的测试属性模型求解构造决策树的方法是采用自上而下的递归构造,其思路是:■以代表训练样本的单个结点开始建树(步骤1)。

■如果样本都在同一类,则该结点成为树叶,并用该类标记(步骤2和3)。

■否则,算法使用称为信息增益的机遇熵的度量为启发信息,选择能最好地将样本分类的属性(步骤6)。

该属性成为该结点的“测试”或“判定”属性(步骤7)。

值得注意的是,在这类算法中,所有的属性都是分类的,即取离散值的。

连续值的属性必须离散化。

■对测试属性的每个已知的值,创建一个分支,并据此划分样本(步骤8~10)。

■算法使用同样的过程,递归地形成每个划分上的样本决策树。

一旦一个属性出现在一个结点上,就不必考虑该结点的任何后代(步骤13)。

■递归划分步骤,当下列条件之一成立时停止:(a)给定结点的所有样本属于同一类(步骤2和3)。

(b)没有剩余属性可以用来进一步划分样本(步骤4)。

在此情况下,采用多数表决(步骤5)。

这涉及将给定的结点转换成树叶,并用samples中的多数所在类别标记它。

换一种方式,可以存放结点样本的类分布。

没有样本。

在这种情况下,以samples中的多数(c)分支test_attribute=ai类创建一个树叶(步骤12)。

算法Decision_Tree(samples,attribute_list)输入由离散值属性描述的训练样本集samples;候选属性集合attribute_list。

输出一棵决策树。

(1)创建节点N;(2)If samples 都在同一类C中then(3)返回N作为叶节点,以类C标记;(4) If attribute_list为空then(5)返回N作为叶节点,以samples 中最普遍的类标记;quals("")) { StringTokenizer tokenizer = new StringTokenizer(str);while ()) {());}}return candAttr;}/*** 读取训练元组* @return 训练元组集合* @throws IOException*/public ArrayList<ArrayList<String>> readData() throws IOException { ArrayList<ArrayList<String>> datas = new ArrayList<ArrayList<String>>();BufferedReader reader = new BufferedReader(new InputStreamReader);String str = "";while (!(str = ()).equals("")) {StringTokenizer tokenizer = new StringTokenizer(str);ArrayList<String> s = new ArrayList<String>();while ()) {());}(s);}return datas;}/*** 递归打印树结构* @param root 当前待输出信息的结点*/public void printTree(TreeNode root){"name:" + ());ArrayList<String> rules = ();"node rules: {");for (int i = 0; i < (); i++) {+ " ");}"}");"");ArrayList<TreeNode> children = ();int size =();if (size == 0) {"-->leaf node!<--");} else {"size of children:" + ());for (int i = 0; i < (); i++) {"child " + (i + 1) + " of node " + () + ": ");printTree(i));}}}/*** 主函数,程序入口* @param args*/public static void main(String[] args) {TestDecisionTree tdt = new TestDecisionTree();ArrayList<String> candAttr = null;ArrayList<ArrayList<String>> datas = null;try {"请输入候选属性");candAttr = ();"请输入训练数据");datas = ();} catch (IOException e) {();}DecisionTree tree = new DecisionTree();TreeNode root = (datas, candAttr);(root);}}package DecisionTree;import * 选择最佳分裂属性*/public class Gain {private ArrayList<ArrayList<String>> D = null; et(attrIndex);if (!(r)) {(r);}}return values;}/*** 获取指定数据集中指定属性列索引的域值及其计数* @param d 指定的数据集* @param attrIndex 指定的属性列索引* @return 类别及其计数的map*/public Map<String, Integer> valueCounts(ArrayList<ArrayList<String>> datas, int attrIndex){Map<String, Integer> valueCount = new HashMap<String, Integer>();String c = "";ArrayList<String> tuple = null;for (int i = 0; i < (); i++) {tuple = (i);c = (attrIndex);if (c)) {(c, (c) + 1);} else {(c, 1);}}return valueCount;}/*** 求对datas中元组分类所需的期望信息,即datas的熵* @param datas 训练元组* @return datas的熵值*/public double infoD(ArrayList<ArrayList<String>> datas){double info = ;int total = ();Map<String, Integer> classes = valueCounts(datas, ());Iterator iter = ().iterator();Integer[] counts = new Integer[()];for(int i = 0; (); i++){entry = ();Integer val = (Integer) ();counts[i] = val;}for (int i = 0; i < ; i++) {double base = (counts[i], total, 3);info += (-1) * base * (base);}return info;}/*** 获取指定属性列上指定值域的所有元组* @param attrIndex 指定属性列索引* @param value 指定属性列的值域* @return 指定属性列上指定值域的所有元组*/public ArrayList<ArrayList<String>> datasOfValue(int attrIndex, String value){ArrayList<ArrayList<String>> Di = new ArrayList<ArrayList<String>>();ArrayList<String> t = null;for (int i = 0; i < (); i++) {t = (i);if(attrIndex).equals(value)){(t);}}return Di;}/*** 基于按指定属性划分对D的元组分类所需要的期望信息* @param attrIndex 指定属性的索引* @return 按指定属性划分的期望信息值*/public double infoAttr(int attrIndex){double info = ;ArrayList<String> values = getValues(D, attrIndex);for (int i = 0; i < (); i++) {ArrayList<ArrayList<String>> dv = datasOfValue(attrIndex, (i));info += (), (), 3), infoD(dv));}return info;}/*** 获取最佳分裂属性的索引* @return 最佳分裂属性的索引*/public int bestGainAttrIndex(){int index = -1;double gain = ;double tempGain = ;for (int i = 0; i < (); i++) {tempGain = infoD(D) - infoAttr(i);if (tempGain > gain) {gain = tempGain;index = i;}}return index;}}package DecisionTree;import .*;/*** 决策树构造类*/public class DecisionTree {private Integer attrSelMode; terator();for(int i = 0; (); i++){entry = ();String key = (String)();Integer val = (Integer) ();if(val > max){max = val;maxC = key;}}return maxC;}/*** 构造决策树* @param datas 训练元组集合* @param attrList 候选属性集合* @return 决策树根结点*/public TreeNode buildTree(ArrayList<ArrayList<String>> datas, ArrayList<String> attrList){emove(bestAttrIndex);}if () == 0) {TreeNode leafNode = new TreeNode();(maxC);(di);(attrList);().add(leafNode);} else {TreeNode newNode = buildTree(di, attrList);().add(newNode);}}return node;}}package DecisionTree;importpublic class DecimalCalculate {/*** 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精* 确的浮点数运算,包括加减乘除和四舍五入。

相关主题