之前一直做的都是J2EE,最近开始接触数据挖掘,特做笔记记录一下。第一次写东西,写的不好,望大家谅解。先上一些基础概念,大致了解下决策树这个东西:
•3、属性是连续值。此时确定一个值作为分裂点split_point,按照>split_point和<=split_point生成两个分支。
决策树算法很多,先说下ID3和C4.5算法。
计算熵的公式为:
信息增益的公式如下:
缺点:
1:ID3算法在选择根节点和内部节点中的分支属性时,采用信息增益作为评价标准。信息增益的缺点是倾向于选择取值较多的属性,在有些情况下这类属性可能不会提供太多有价值的信息。 例如ID字段等。
2:ID3算法只能对描述属性为离散型属性的数据集构造决策树
1:可以处理连续数值型属性,对于离散值,C4.5和ID3的处理方法相同,对于某个属性的值连续时,假设这这个节点上的数据集合样本为total,C4.5算法进行如下处理:
- 将样本数据该属性A上的具体数值按照升序排列,得到属性序列值:{A1,A2,A3,...,Atotal}
- 在上一步生成的序列值中生成total-1个分割点。第i个分割点的取值为Ai和Ai+1的均值,每个分割点都将属性序列划分为两个子集。
- 计算每个分割点的信息增益(Information Gain),得到total-1个信息增益。
- 对分裂点的信息增益进行修正:减去log2(N-1)/|D|,其中N为可能的分裂点个数,D为数据集合大小。
- 选择修正后的信息增益值最大的分类点作为该属性的最佳分类点
- 计算最佳分裂点的信息增益率(Gain Ratio)作为该属性的Gain Ratio
- 选择Gain Ratio最大的属性作为分类属性。
2:用信息增益率(Information Gain Ratio)来选择属性 ,克服了用信息增益来选择属性时偏向选择值多的属性的不足。信息增益率定义为:
其中Gain(S,A)和ID3算法中的信息增益计算相同,而SplitInfo(S,A)代表了按照属性A分裂样本集合S的广度和均匀性。
其中Si表示根据属性A分割S而成的样本子集。
3:后剪枝策略
Decision Tree很容易产生Overfitting,剪枝能够避免树高度无限制增长,避免过度拟合数据。剪枝算法那是相当复杂
4:缺失值处理
对于某些采样数据,可能会缺少属性值。在这种情况下,处理缺少属性值的通常做法是赋予该属性的常见值,或者属性均值。另外一种比较好的方法是为该属性的每个可能值赋予一个概率,即将该属性以概率形式赋值。例如给定Boolean属性B,已知采样数据有12个B=0和88个B=1实例,那么在赋值过程中,B属性的缺失值被赋为B(0)=0.12、B(1)=0.88;所以属性B的缺失值以12%概率被分到False的分支,以88%概率被分到True的分支。这种处理的目的是计算信息增益,使得这种属性值缺失的样本也能处理。
1:算法低效,在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效,尤其是在大量特征属性的数据集中。
2:内存受限,适合于能够驻留于内存的数据集,当训练集大得无法在内存容纳时程序无法运行。
下面用Java代码来实现这两个算法:
抽象类定义一个构建决策树的整体过程,子类只负责具体算法的实现。
@Override public Object build(Data data) { //获取数据集的分类分割集合 Map<Object, List<Instance>> splits = data.getSplits(); //如果只有一个样本,将该样本所属分类作为新样本的分类 if (splits.size() == 1) { return splits.keySet().iterator().next(); } String[] attributes = data.getAttributes(); // 如果没有供决策的属性,则将样本集中具有最多样本的分类作为新样本的分类,即投票选举出最多个数分类 if (attributes.length == 0) { return obtainMaxCategory(splits); } // 选取最优最佳属性信息,交由子类去实现各个算法 BestAttribute bestAttribute = chooseBestAttribute(data); // 决策树根结点,分支属性为选取的分割属性 int bestAttrIndex = bestAttribute.getIndex(); if (bestAttrIndex == -1) { return obtainMaxCategory(splits); } TreeNode treeNode = new TreeNode(attributes[bestAttrIndex]); // 已用过的测试属性不应再次被选为分割属性 String[] subAttributes = new String[attributes.length - 1]; for (int i = 0, j = 0; i < attributes.length; i++) { if (i != bestAttrIndex) { subAttributes[j++] = attributes[i]; } } // 根据分支属性生成分支分裂信息 Map<Object, Map<Object, List<Instance>>> subSplits = bestAttribute.getSplits(); for (Entry<Object, Map<Object, List<Instance>>> entry : subSplits.entrySet()) { Object attrValue = entry.getKey(); Data subData = new Data(subAttributes, entry.getValue()); Object child = build(subData); treeNode.setChild(attrValue, child); } return treeNode; }
public abstract BestAttribute chooseBestAttribute(Data data);
ID3算法的具体实现
@Override public BestAttribute chooseBestAttribute(Data data) { Map<Object, List<Instance>> splits = data.getSplits(); String[] attributes = data.getAttributes(); int optIndex = -1; // 最优属性下标 double minValue = Double.MAX_VALUE; // 最小信息量或说是期望 Map<Object, Map<Object, List<Instance>>> optSplits = null; // 最优分支方案 // 对每一个属性,计算将其作为测试属性的情况下在各分支确定新样本的分类需要的信息量之和,选取最小为最优 for (int attrIndex = 0; attrIndex < attributes.length; attrIndex++) { int allCount = 0; // 统计样本总数的计数器 //按当前属性构建分裂信息:属性值->(分类->样本列表) Map<Object, Map<Object, List<Instance>>> curSplits = new HashMap<Object, Map<Object, List<Instance>>>(); for (Entry<Object, List<Instance>> entry : splits.entrySet()) { Object category = entry.getKey(); List<Instance> instances = entry.getValue(); for (Instance instance : instances) { Object attrValue = instance.getAttribute(attributes[attrIndex]); Map<Object, List<Instance>> split = curSplits.get(attrValue); if (split == null) { split = new HashMap<Object, List<Instance>>(); curSplits.put(attrValue, split); } List<Instance> splitInstances = split.get(category); if (splitInstances == null) { splitInstances = new LinkedList<Instance>(); split.put(category, splitInstances); } splitInstances.add(instance); } allCount += instances.size(); } // 计算将当前属性作为测试属性的情况下在各分支确定新样本的分类需要的信息量之和 double curValue = 0.0; // 计数器:累加各分支 for (Map<Object, List<Instance>> curSplit : curSplits.values()) { double perSplitCount = 0; for (List<Instance> list : curSplit.values()) perSplitCount += list.size(); // 累计当前分支样本数 double perSplitValue = 0.0; // 计数器:当前分支 for (List<Instance> list : curSplit.values()) { double p = list.size() / perSplitCount; perSplitValue -= p * (Math.log(p) / Math.log(2)); } curValue += (perSplitCount / allCount) * perSplitValue; } // 选取最小为最优 if (minValue > curValue) { optIndex = attrIndex; minValue = curValue; optSplits = curSplits; } } return new BestAttribute(optIndex, minValue, optSplits); }
C4.5算法具体实现
@Override public BestAttribute chooseBestAttribute(Data data) { Map<Object, List<Instance>> splits = data.getSplits(); String[] attributes = data.getAttributes(); int optIndex = -1; // 最优属性下标 double maxGainRatio = 0.0; // 最大增益率 Map<Object, Map<Object, List<Instance>>> optSplits = null; // 最优分支方案 // 对每一个属性,计算将其作为测试属性的情况下在各分支确定新样本的分类需要的信息量之和,选取最优 for (int attrIndex = 0; attrIndex < attributes.length; attrIndex++) { int allCount = 0; // 统计样本总数的计数器 // 按当前属性构建Map:属性值->(分类->样本列表) Map<Object, Map<Object, List<Instance>>> curSplits = new HashMap<Object, Map<Object, List<Instance>>>(); for (Entry<Object, List<Instance>> entry : splits.entrySet()) { Object category = entry.getKey(); List<Instance> instances = entry.getValue(); for (Instance instance : instances) { Object attrValue = instance.getAttribute(attributes[attrIndex]); Map<Object, List<Instance>> split = curSplits.get(attrValue); if (split == null) { split = new HashMap<Object, List<Instance>>(); curSplits.put(attrValue, split); } List<Instance> splitInstances = split.get(category); if (splitInstances == null) { splitInstances = new LinkedList<Instance>(); split.put(category, splitInstances); } splitInstances.add(instance); } allCount += instances.size(); } // 计算将当前属性作为测试属性的情况下在各分支确定新样本的分类需要的信息量之和 double curValue = 0.0; // 计数器:累加各分支 double splitInfo = 0.0; //分裂信息 for (Map<Object, List<Instance>> curSplit : curSplits.values()) { double perSplitCount = 0; for (List<Instance> list : curSplit.values()) perSplitCount += list.size(); // 累计当前分支样本数 double perSplitValue = 0.0; // 计数器:当前分支 for (List<Instance> list : curSplit.values()) { double p = list.size() / perSplitCount; perSplitValue -= p * (Math.log(p) / Math.log(2)); } double dj = (perSplitCount / allCount); curValue += dj * perSplitValue; splitInfo -= dj * (Math.log(dj) / Math.log(2)); } double gainRatio = curValue / splitInfo; if (maxGainRatio <= gainRatio) { optIndex = attrIndex; maxGainRatio = gainRatio; optSplits = curSplits; } } return new BestAttribute(optIndex, maxGainRatio, optSplits); }
相关推荐
高效决策树算法是数据挖掘和机器学习领域中的一个重要工具,尤其在分类问题中表现出色。这一系列笔记将深入探讨如何构建高效、准确的决策树模型。决策树是一种以树状结构进行决策的模型,其中每个内部节点代表一个...
在数据挖掘领域,决策树算法是一种常用的分类方法,它通过一系列规则对数据进行分类或回归。C4.5决策树是决策树算法的一种改进形式,由Ross Quinlan开发,它继承了ID3决策树处理离散型属性的能力,并且还能够处理...
在数据挖掘中,常用的分类方法有KNN、决策树、朴素贝叶斯分类等。 KNN算法是指K-Nearest Neighbors算法,该算法通过计算测试样本与训练样本之间的距离来预测测试样本的类别。 决策树算法是指使用决策树来分类数据...
5. 数据挖掘技术:常见的数据挖掘技术包括决策树、贝叶斯网络、支持向量机、聚类算法如K-means和DBSCAN,以及关联规则算法如Apriori。这些技术各有优缺点,适用于不同的数据特性和问题场景。 6. 数据挖掘的应用领域...
分类算法如决策树(C4.5, ID3)、随机森林和神经网络,它们能根据已有数据构建模型,预测未知数据的类别。聚类算法如K-means、层次聚类和DBSCAN,则是无监督学习方法,用于发现数据的自然分组。关联规则学习,如...
决策树是一种常用的数据挖掘方法,尤其在机器学习领域中占据着重要的地位。它通过一系列基于数据属性的判断规则,将数据集分割成不同的类别或数值预测。Spark 是一个开源的大数据处理框架,它提供了MLlib库,其中...
在浙江大学的数据挖掘课程中,可能会涵盖这些基本概念,同时深入到更具体的算法和技术,如SVM(支持向量机)、决策树、神经网络、Apriori算法、K-means聚类等。此外,还可能涉及数据库管理系统、统计学基础、机器...
分类和预测任务中,支持向量机(SVM)、决策树、贝叶斯网络和神经网络是常用的模型。SVM通过构造最大分类间隔的超平面实现分类,对于非线性问题,它引入了核函数进行映射。贝叶斯网络则利用概率和条件概率来表示变量间...
### Python版数据挖掘实验4报告:用决策树预测获胜球队 #### 实验名称与目的 本次实验名为“用决策树预测获胜球队”。其主要目的是利用机器学习中的决策树算法来预测篮球比赛中哪支球队可能获胜。这不仅是一次理论...
《机器学习与数据挖掘学习笔记》是一份综合性的学习资料,涵盖了这两个领域的重要概念、算法和技术。这份笔记的目的是为了帮助读者深入理解机器学习和数据挖掘的基础知识,并提供实际操作的指导。 首先,我们来探讨...
决策树算法是一种直观且易于理解的分类和回归方法。它通过学习一系列的决策规则,将特征空间划分为多个子空间,并且这些子空间对应于不同的类别标签。决策树的核心是选择最优的属性进行分割,这通常依据信息增益或...
数据挖掘十大算法详解,数据挖掘学习笔记--决策树C4.5 、数据挖掘十大算法--K-均值聚类算法 、机器学习与数据挖掘-支持向量机(SVM)、拉格朗日对偶、支持向量机(SVM)(三)-- 最优间隔分类器 (optimal margin ...
3. 学习和实践各种数据挖掘算法,如决策树、随机森林、支持向量机和神经网络等。 4. 了解如何在大数据环境中实现模型的训练和验证。 5. 提升问题解决能力,通过比赛代码学习如何解决实际问题并优化模型性能。 这个...
决策树是一种广泛应用于机器学习和数据挖掘中的分类和回归模型,它的主要特点是通过构建树状结构来模拟一系列的决定过程。在本章的学习笔记中,我们聚焦于决策树的生成流程、属性划分的选择以及剪枝处理,同时也涉及...
数据仓库笔记的知识点涵盖了数据仓库和数据挖掘的基本概念、数据挖掘的主要任务与方法、学习算法以及搭建数据仓库的相关知识。下面将详细阐述这些知识点。 首先,数据仓库是为了企业决策支持而设计的系统,它主要...
"数据挖掘笔记"这部分内容可能是学习者对所学知识的整理,包括关键概念的总结、公式解析、算法实现步骤等,对于初学者来说,这是一份极具价值的参考资料,能帮助他们更好地理解和记忆复杂的知识点。 "习题"则提供了...
数据挖掘中的分类技术 数据挖掘是一种常用的数据分析技术,旨在从大量数据中提取有价值的信息。数据挖掘技术可以分为多种类型,包括分类、预测、聚类、关联规则等。其中,分类是数据挖掘中的一种重要技术,旨在对...
《数据挖掘》读书笔记主要涵盖了数据可视化、建模方法、数据挖掘技术和预测分析的应用。作者Philipp K. Janer凭借其在物理学和软件工程领域的深厚背景,为读者提供了丰富的数据分析和数学建模知识。 在全书中,作者...
分类算法如决策树、随机森林和支持向量机,用于将数据分成不同的类别。聚类方法如K-means和层次聚类则用于无监督学习,帮助发现数据的自然分组。关联规则学习如Apriori算法常用于市场篮子分析,找出商品之间的购买...
在本项目中,我们主要探讨的是如何在JupyterLab环境下使用Python进行数据挖掘,并通过决策树模型对数据进行分析。JupyterLab是一个交互式的开发环境,适合数据分析、机器学习等任务,而决策树是一种常见的监督学习...