`
fighting_2013
  • 浏览: 15591 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

数据挖掘笔记-分类-决策树-2

阅读更多

接着上面说下决策树的一些其他算法:SLIQ、SPRINT、CART。这些算法则是根据Gini指标来计算的。

SLIQ

SLIQ(Supervised Learning In Quest)利用三中数据结构来构造树,分别是属性表、类表和类直方图。

SLIQ算法在建树阶段,对连续属性采取预先排序技术与广度优先相结合的策略生成树,对离散属性采取快速求子集算法确定划分条件。

具体步骤如下:

step1:建立类表和各个属性表,并且进行预先排序,即对每个连续属性的属性表进行独立的排序,以避免在每个节点上都要给连续属性值重新排序;

step2:如果每个叶子节点中的样本都能归为一类,则算法停止;否则转step3;

step3:利用属性表计算gini值,选择最小gini值的属性和分割点作为最佳划分;

step4:根据step3得到的最佳划分节点,判断为真的样本划分为左孩子节点,否则划分为右孩子节点.这样就构成了广度优先的生成树策略;

step5:更新类表中的第二项,使之指向样本划分后所在的叶子节点;

step6:跳转到step2

 
SLIQ优异性能:
可伸缩性良好:缩短学习时间、处理常驻磁盘的数据集能力、处理结果的准确性
 
SPRINT
SPRINT(Scalable Parallelizable Induction of Classification Tree)算法是一种可扩展的、可并行的归纳决策树,它完全不受内存限制,运行速度快,且允许多个处理器协同创建一个决策树模型.
SPRINT算法是对SLIQ算法的改进,其目的有两个:一是为了能够更好的并行建立决策树,二是为了使得决策树适合更大的数据集.
SPRINT算法定义了两种数据结构,分别是属性表与直方图.属性表由一组三元组<属性值、类别属性、样本号>组成,它随节点的扩张而划分,并归附于相应的子节点.
与SLIQ算法不同,SPRINT算法采取传统的深度优先生成树策略,具体步骤如下:
step1:生成根节点,并为所有属性建立属性表,同时预先排序连续属性的属性表;
step2:如果节点中的样本都能归为一类,则算法停止;否则转step3;
step3:利用属性表寻找拥有最小gini值的划分作为最佳划分方案.算法依次扫描该节点上的每张属性表;
step4:根据划分方案,生成该节点的两个子节点;
step5:划分该节点上的各属性表;
step6:跳转到step2
 
SPRINT算法的优点是在寻找每个结点的最优分裂标准时变得更简单。其缺点是对非分裂属性的属性列表进行分裂变得很困难。解决的办法是对分裂属性进行分裂时用哈希表记录下每个记录属于哪个孩子结点,若内存能够容纳下整个哈希表,其他属性列表的分裂只需参照该哈希表即可。由于哈希表的大小与训练集的大小成正比,当训练集很大时,哈希表可能无法在内存容纳,此时分裂只能分批执行,这使得SPRINT算法的可伸缩性仍然不是很好。
 
CART

分类回归树算法:CART(Classification And Regression Tree)算法采用一种二分递归分割的技术,将当前的样本集分为两个子样本集,使得生成的的每个非叶子节点都有两个分支。因此,CART算法生成的决策树是结构简洁的二叉树。

分类树两个基本思想:第一个是将训练样本进行递归地划分自变量空间进行建树的想法,第二个想法是用验证数据进行剪枝。

 

这里只对SPRINT算法用Java进行了简单实现

@Override
public Object build(Data data) {
	//对数据集预先判断,特征属性为空时候选取最多数量的类型,数据集全部为统一类型时候直接返回类型
	Object preHandleResult = preHandle(data);
	if (null != preHandleResult) return preHandleResult;
	//创建属性表
	Map<String, List<Attribute>> attributeTableMap = 
			new HashMap<String, List<Attribute>>();
	for (Instance instance : data.getInstances()) {
		String category = String.valueOf(instance.getCategory());
		Map<String, Object> attrs = instance.getAttributes();
		for (Map.Entry<String, Object> entry : attrs.entrySet()) {
			String attrName = entry.getKey();
			List<Attribute> attributeTable = attributeTableMap.get(attrName);
			if (null == attributeTable) {
				attributeTable = new ArrayList<Attribute>();
				attributeTableMap.put(attrName, attributeTable);
			}
			attributeTable.add(new Attribute(instance.getId(), 
					attrName, String.valueOf(entry.getValue()), category));
		}
	}
	//计算属性表的基尼指数
	Set<String> attributes = data.getAttributeSet();
	String splitAttribute = null;
	String minSplitPoint = null;
	double minSplitPointGini = 1.0;
	for (Map.Entry<String, List<Attribute>> entry : attributeTableMap.entrySet()) {
		String attribute = entry.getKey();
		if (!attributes.contains(attribute)) {
			continue;
		}
		List<Attribute> attributeTable = entry.getValue();
		Object[] result = calculateMinGini(attributeTable);
		double splitPointGini = Double.parseDouble(String.valueOf(result[1]));
		if (minSplitPointGini > splitPointGini) {
			minSplitPointGini = splitPointGini;
			minSplitPoint = String.valueOf(result[0]);
			splitAttribute = attribute;
		}
	}
	System.out.println("splitAttribute: " + splitAttribute);
	TreeNode treeNode = new TreeNode(splitAttribute);
		
	//根据分割属性和分割点分割数据集
	attributes.remove(splitAttribute);
	Set<String> attributeValues = new HashSet<String>();
	List<List<Instance>> splitInstancess = new ArrayList<List<Instance>>();
	List<Instance> splitInstances1 = new ArrayList<Instance>();
	List<Instance> splitInstances2 = new ArrayList<Instance>();
	splitInstancess.add(splitInstances1);
	splitInstancess.add(splitInstances2);
	for (Instance instance : data.getInstances()) {
		Object value = instance.getAttribute(splitAttribute);
		attributeValues.add(String.valueOf(value));
		if (value.equals(minSplitPoint)) {
			splitInstances1.add(instance);
		} else {
			splitInstances2.add(instance);
		}
	}
	attributeValues.remove(minSplitPoint);
	StringBuilder sb = new StringBuilder();
	for (String attributeValue : attributeValues) {
		sb.append(attributeValue).append(",");
	}
	if (sb.length() > 0) sb.deleteCharAt(sb.length() - 1);
	String[] names = new String[]{minSplitPoint, sb.toString()};
	for (int i = 0; i < 2; i++) {
		List<Instance> splitInstances = splitInstancess.get(i);
		if (splitInstances.size() == 0) continue;
		Data subData = new Data(attributes.toArray(new String[0]),
				splitInstances);
		treeNode.setChild(names[i], build(subData));
	}
	return treeNode;
}

/** 计算基尼指数*/
public Object[] calculateMinGini(List<Attribute> attributeTable) {
	double totalNum = 0.0;
	Map<String, Map<String, Integer>> attrValueSplits = 
			new HashMap<String, Map<String, Integer>>();
	Set<String> splitPoints = new HashSet<String>();
	Iterator<Attribute> iterator = attributeTable.iterator();
	while (iterator.hasNext()) {
		Attribute attribute = iterator.next();
		String attributeValue = attribute.getValue();
		splitPoints.add(attributeValue);
		Map<String, Integer> attrValueSplit = attrValueSplits.get(attributeValue);
		if (null == attrValueSplit) {
			attrValueSplit = new HashMap<String, Integer>();
			attrValueSplits.put(attributeValue, attrValueSplit);
		}
		String category = attribute.getCategory();
		Integer categoryNum = attrValueSplit.get(category);
		attrValueSplit.put(category, null == categoryNum ? 1 : categoryNum + 1);
		totalNum++;
	}
	String minSplitPoint = null;
	double minSplitPointGini = 1.0;
	for (String splitPoint : splitPoints) {
		double splitPointGini = 0.0;
		double splitAboveNum = 0.0;
		double splitBelowNum = 0.0;
		Map<String, Integer> attrBelowSplit = new HashMap<String, Integer>();
		for (Map.Entry<String, Map<String, Integer>> entry : attrValueSplits.entrySet()){
			String attrValue = entry.getKey();
			Map<String, Integer> attrValueSplit = entry.getValue();
			if (splitPoint.equals(attrValue)) {
				for (Integer v : attrValueSplit.values()) {
					splitAboveNum += v;
				}
				double aboveGini = 1.0;
				for (Integer v : attrValueSplit.values()) {
					aboveGini -= Math.pow((v / splitAboveNum), 2);
				}
				splitPointGini += (splitAboveNum / totalNum) * aboveGini;
			} else {
				for (Map.Entry<String, Integer> e : attrValueSplit.entrySet()) {
					String k = e.getKey();
					Integer v = e.getValue();
					Integer count = attrBelowSplit.get(k);
					attrBelowSplit.put(k, null == count ? v : v + count);
					splitBelowNum += e.getValue();
				}
			}
		}
		double belowGini = 1.0;
		for (Integer v : attrBelowSplit.values()) {
			belowGini -= Math.pow((v / splitBelowNum), 2);
		}
		splitPointGini += (splitBelowNum / totalNum) * belowGini;
		if (minSplitPointGini > splitPointGini) {
			minSplitPointGini = splitPointGini;
			minSplitPoint = splitPoint;
		}
	}
	return new Object[]{minSplitPoint, minSplitPointGini};
}
分享到:
评论

相关推荐

    efficient-decision-tree-notes高效决策树算法系列笔记

    高效决策树算法是数据挖掘和机器学习领域中的一个重要工具,尤其在分类问题中表现出色。这一系列笔记将深入探讨如何构建高效、准确的决策树模型。决策树是一种以树状结构进行决策的模型,其中每个内部节点代表一个...

    基于C4.5决策树的大学生笔记本电脑购买行为的数据挖掘.pdf

    在数据挖掘领域,决策树算法是一种常用的分类方法,它通过一系列规则对数据进行分类或回归。C4.5决策树是决策树算法的一种改进形式,由Ross Quinlan开发,它继承了ID3决策树处理离散型属性的能力,并且还能够处理...

    山东大学数据挖掘期末复习笔记.pdf

    在数据挖掘中,常用的分类方法有KNN、决策树、朴素贝叶斯分类等。 KNN算法是指K-Nearest Neighbors算法,该算法通过计算测试样本与训练样本之间的距离来预测测试样本的类别。 决策树算法是指使用决策树来分类数据...

    《数据挖掘概念与技术》-思维导图学习笔记,第一章。

    5. 数据挖掘技术:常见的数据挖掘技术包括决策树、贝叶斯网络、支持向量机、聚类算法如K-means和DBSCAN,以及关联规则算法如Apriori。这些技术各有优缺点,适用于不同的数据特性和问题场景。 6. 数据挖掘的应用领域...

    《数据挖掘技术》课程学习笔记

    分类算法如决策树(C4.5, ID3)、随机森林和神经网络,它们能根据已有数据构建模型,预测未知数据的类别。聚类算法如K-means、层次聚类和DBSCAN,则是无监督学习方法,用于发现数据的自然分组。关联规则学习,如...

    决策树随堂笔记.pdf

    决策树是一种常用的数据挖掘方法,尤其在机器学习领域中占据着重要的地位。它通过一系列基于数据属性的判断规则,将数据集分割成不同的类别或数值预测。Spark 是一个开源的大数据处理框架,它提供了MLlib库,其中...

    [浙大-数据挖掘].1-10\4.rar [浙大-数据挖掘].1-10\4.rar

    在浙江大学的数据挖掘课程中,可能会涵盖这些基本概念,同时深入到更具体的算法和技术,如SVM(支持向量机)、决策树、神经网络、Apriori算法、K-means聚类等。此外,还可能涉及数据库管理系统、统计学基础、机器...

    Python版数据挖掘实验4报告:用决策树预测获胜球队.pdf

    ### Python版数据挖掘实验4报告:用决策树预测获胜球队 #### 实验名称与目的 本次实验名为“用决策树预测获胜球队”。其主要目的是利用机器学习中的决策树算法来预测篮球比赛中哪支球队可能获胜。这不仅是一次理论...

    数据挖掘笔记思维导图1

    分类和预测任务中,支持向量机(SVM)、决策树、贝叶斯网络和神经网络是常用的模型。SVM通过构造最大分类间隔的超平面实现分类,对于非线性问题,它引入了核函数进行映射。贝叶斯网络则利用概率和条件概率来表示变量间...

    机器学习与数据挖掘学习笔记.zip

    2. **决策树与随机森林**: 决策树通过一系列问题划分数据,随机森林则是由多个决策树构成的集成学习模型,能有效减少过拟合。 3. **K-Means**: K-Means是一种常见的聚类算法,通过迭代寻找最佳的聚类中心。 4. **PCA...

    数据挖掘十大算法详解.zip

    数据挖掘十大算法详解,数据挖掘学习笔记--决策树C4.5 、数据挖掘十大算法--K-均值聚类算法 、机器学习与数据挖掘-支持向量机(SVM)、拉格朗日对偶、支持向量机(SVM)(三)-- 最优间隔分类器 (optimal margin ...

    数据挖掘完整项目/课堂记录笔记/比赛代码

    3. 学习和实践各种数据挖掘算法,如决策树、随机森林、支持向量机和神经网络等。 4. 了解如何在大数据环境中实现模型的训练和验证。 5. 提升问题解决能力,通过比赛代码学习如何解决实际问题并优化模型性能。 这个...

    机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理)1

    决策树算法是一种直观且易于理解的分类和回归方法。它通过学习一系列的决策规则,将特征空间划分为多个子空间,并且这些子空间对应于不同的类别标签。决策树的核心是选择最优的属性进行分割,这通常依据信息增益或...

    数据仓库笔记

    数据仓库笔记的知识点涵盖了数据仓库和数据挖掘的基本概念、数据挖掘的主要任务与方法、学习算法以及搭建数据仓库的相关知识。下面将详细阐述这些知识点。 首先,数据仓库是为了企业决策支持而设计的系统,它主要...

    数据挖掘资料(吐血汇总).rar

    "数据挖掘笔记"这部分内容可能是学习者对所学知识的整理,包括关键概念的总结、公式解析、算法实现步骤等,对于初学者来说,这是一份极具价值的参考资料,能帮助他们更好地理解和记忆复杂的知识点。 "习题"则提供了...

    06数据挖掘21

    数据挖掘中的分类技术 数据挖掘是一种常用的数据分析技术,旨在从大量数据中提取有价值的信息。数据挖掘技术可以分为多种类型,包括分类、预测、聚类、关联规则等。其中,分类是数据挖掘中的一种重要技术,旨在对...

    《数据挖掘》读书笔记.pdf

    《数据挖掘》读书笔记主要涵盖了数据可视化、建模方法、数据挖掘技术和预测分析的应用。作者Philipp K. Janer凭借其在物理学和软件工程领域的深厚背景,为读者提供了丰富的数据分析和数学建模知识。 在全书中,作者...

    斯坦福大学CS345A 数据挖掘 课程所有课件(pdf+ppt)

    分类算法如决策树、随机森林和支持向量机,用于将数据分成不同的类别。聚类方法如K-means和层次聚类则用于无监督学习,帮助发现数据的自然分组。关联规则学习如Apriori算法常用于市场篮子分析,找出商品之间的购买...

    基于 jupyterlab的决策树模型,decision_tree.zip

    在本项目中,我们主要探讨的是如何在JupyterLab环境下使用Python进行数据挖掘,并通过决策树模型对数据进行分析。JupyterLab是一个交互式的开发环境,适合数据分析、机器学习等任务,而决策树是一种常见的监督学习...

    ch04 决策树_学习笔记1

    决策树是一种广泛应用于机器学习和数据挖掘中的分类和回归模型,它的主要特点是通过构建树状结构来模拟一系列的决定过程。在本章的学习笔记中,我们聚焦于决策树的生成流程、属性划分的选择以及剪枝处理,同时也涉及...

Global site tag (gtag.js) - Google Analytics