算法小白的第一次尝试---ID3实现决策树

基于决策树算法对良/恶性乳腺癌肿瘤预测 基于决策树算法对良/恶性乳腺癌肿瘤预测——数据结构课程设计,欢迎各位阅读,共同学习! 阅读详情
package DecesionTree
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.ml.feature.StringIndexer
import java.math._
import scala.collection.mutable.ArrayBuffer
import org.apache.spark.storage.StorageLevel
import org.apache.spark.sql.DataFrame
/**
 * 基于ID3算法生成决策树---统计学习方法
 */
object ID3Tree {
  def main(args: Array[String]): Unit = {    
    val conf=new SparkConf().setMaster("local").setAppName("ML")
    val sc=new SparkContext(conf)
    val sqlcontext=new SQLContext(sc)
    //train数据
    val sampleData=Array(Array("1","青年","否","否","一般","否"),Array("2","青年","否","否","好","否"),Array("3","青年","是","否","好","是"),
                   Array("4","青年","是","是","一般","是"),Array("5","青年","否","否","一般","否"),Array("6","中年","否","否","一般","否"),
                   Array("7","中年","否","否","好","否"),Array("8","中年","是","是","好","是"),Array("9","中年","否","是","非常好","是"),
                   Array("10","中年","否","是","非常好","是"),Array("11","老年","否","是","非常好","是"),Array("12","老年","否","是","好","是"),
                   Array("13","老年","是","否","好","是"),Array("14","老年","是","否","非常好","是"),Array("15","老年","否","否","一般","否"))
   import sqlcontext.implicits._
   var DF=sc.parallelize(sampleData).map { x => 
      val age=x(1)
      val work=x(2)
      val house=x(3)
      val credit=x(4)
      val label=x(5)
      (age,work,house,credit,label)  
    }.toDF("age","isWork","isHouse","credit","label")
    
    //决策树节点,内部节点(String),其中String表示当前内部节点
    val internalNode=ArrayBuffer[String]()
    //决策树节点,叶子节点(str1,str2),其中str1表示判定条件,str2表示叶子节点标记
    val leafNode=ArrayBuffer[(String,String)]()
    //每个内部节点所对应的子节点数
    val countArr=ArrayBuffer[Int]()
    var flag=true
    while(flag){
      val totalRecord=DF.rdd.count().toInt
      val labels=DF.select("label").rdd.map(Row=>Row.getString(Row.fieldIndex("label"))).map { x => (x,1)}.reduceByKey(_+_).collect()
      val featurePoint=Getfeature(DF,totalRecord,labels)(0)._1
      //df表示上一个特征点对应的所有label
      val df=DF.select(featurePoint).distinct().rdd.map { Row => Row.getString(Row.fieldIndex(featurePoint))}.collect()
      var count=0
      //arr表示该内部节点中非叶子节点的子节点
      var arr=""
      for(lb<-df){
        //根据最优特征,划分数据集
        val str=s"$featurePoint =" + s"'$lb'" 
        val newDF=DF.where(str).select("label").distinct().rdd.map { Row => Row.getString(Row.fieldIndex("label"))}.collect()
        val D1=newDF.length
        if(D1==1){
          leafNode.append((lb,newDF(0)))
          count +=1
        }else{
          arr=lb
        }
      }
      internalNode.append(featurePoint)
      //判断决策树是否训练完成,若当前内部节点所对应的叶子节点的个数为2,则表示训练结束
      if(count==2) flag=false else{
        val str2=s"$featurePoint =" + s"'$arr'"
        var sk=DF.where(str2).toDF().rdd.map { Row => 
          val ID="0"
          val age=Row.getString(Row.fieldIndex("age"))
          val isWork=Row.getString(Row.fieldIndex("isWork"))
          val isHouse=Row.getString(Row.fieldIndex("isHouse"))
          val credit=Row.getString(Row.fieldIndex("credit"))
          val label=Row.getString(Row.fieldIndex("label"))
          Array(ID,age,isWork,isHouse,credit,label)
        }.collect()
        //此处应该刷新一下DF
        DF=sc.parallelize(sk).map { x => 
          val age=x(1)
          val work=x(2)
          val house=x(3)
          val credit=x(4)
          val label=x(5)
          (age,work,house,credit,label)  
        }.toDF("age","isWork","isHouse","credit","label")    
      }
      countArr.append(count)
    }
    println("所有的内部节点")
    internalNode.foreach { x => println(x) }
    println("所有的叶子节点")
    leafNode.foreach(println(_))
    println("每个内部节点对应的叶子节点个数")
    countArr.foreach { x => println(x) }
  }
   
  /**
   * 根据ID3算法,求取最优特征
   */
  def Getfeature(DF:DataFrame,totalRecord:Int,labels:Array[(String,Int)]):ArrayBuffer[(String, Double)]={   
      val features=DF.columns
      //计算数据集D的熵
      var Hd=0.0
      for(lab<-labels){
        val labelcount=lab._2.toDouble
        val pi=labelcount/totalRecord
        Hd+= -1.0*((pi)*Math.log(pi)/Math.log(2))
      }
     //计算特征A对数据集的经验条件熵
     val Hda=ArrayBuffer[Double]()
       for(feature<-features){
          var Hdik=0.0
          if(!"label".equals(feature)){
            //DI表示特征A对应的信息
            val DI=DF.groupBy(feature).count()
            //lab表示特征A所有可能得取值
            val Lab=ArrayBuffer[String]()
            val Di=ArrayBuffer[Int]()
            DI.collect().map { Row =>  
              Lab +=Row.getString(Row.fieldIndex(feature))
              Di +=Row.getLong(Row.fieldIndex("count")).toInt
            }    
            //获取Dik信息
            val Dik=ArrayBuffer[(Int,Int)]()
            for(lab<-Lab){
              var i=0
              val str=s"$feature = " + s"'$lab'"
              val newDF=DF.where(str).groupBy("label").count().persist(StorageLevel.MEMORY_ONLY_SER)
              val df=newDF.rdd.map { Row => Row.getLong(Row.fieldIndex("count")).toInt}.collect()
              if(newDF.count().toInt ==2)  Dik.append((df(0),df(1))) else Dik.append((df(0),0))
            }
            //计算每个label的条件熵
            for(i<-Di){
              val newDik=Dik.take(1)
              Dik.remove(0,1)
              for(j<-newDik){
                if(j._2 ==0){
                  val pi=j._1.toDouble/i
                  Hdik += i.toDouble/totalRecord*(-1.0)*(pi)*Math.log(pi)/Math.log(2)
                }else{
                  val pi1=j._1.toDouble/i
                  val pi2=j._2.toDouble/i
                   Hdik += i.toDouble/totalRecord*(-1.0)*(pi1)*Math.log(pi1)/Math.log(2) + i.toDouble/totalRecord*(-1.0)*(pi2)*Math.log(pi2)/Math.log(2) 
                }
              }
            }
            Hda.append(Hdik)
          }
      }
     //Gda表示信息增益,选取信息增益最大值作为最优特征。
     val Gda=ArrayBuffer[(String,Double)]()
     for(i<-0 until Hda.length){
       val hda=Hda(i)
       Gda.append((features(i),(Hd-hda)))
     }
     Gda.sortBy(x=>x._2).reverse.take(1)
  }
}
-----------------------------
Result:
所有的内部节点
isHouse
isWork
所有的叶子节点
(是,是)
(否,否)
(是,是)
每个内部节点对应的叶子节点个数
1
2
----------------------------
Decision Tree:
if("是".equals(isHouse))
	"是"
else if("是".equals(isWork))
	"是"
else "否"	
机器学习之决策树模型篇 ---- 某流行手游胜负预测 决策树模型在MOBA类手游胜负预测任务中表现优异,准确率达72.57%。该模型通过计算熵或基尼系数选择最优分裂特征,模拟人类决策过程,特别适合处理游戏数据中的非线性关系和离散特征。实验表明max_depth=3时效果最佳,过深易导致过拟合。优化建议包括采用向量化计算、信息增益率和动态参数调整。决策树的高解释性和高效推理能力使其成为电竞预测的理想选择,未来可升级为随机森林或XGBoost进一步提升性能。该模型不仅能提供可靠预测,还能揭示经济差等关键制胜因素。 阅读详情

相关推荐

决策树算法实现(以ID3为例)

决策树之训练过程在于建树,树结构的建立过程是递归的,关键步骤是选择属性进行划分数据集,选择划分的策略引出了各种版本决策树,ID3、C4.5和CART,其中前两种基于信息论,CART采用GINI系数对属性进行划分。编写决策树之前首先需要明确决策树的结构特点: 1、叶子节点是样本(用这类样本计算标签值,回归树用这个单元中的样本计算输出值,然后联合多个单元中的输出值和权重计算总的回归值) 2、非叶节...

david_hnu的博客 1517

基于ID3算法的决策树分类模型

用于理解决策树模型,并以此进行复现依据ID3算法,进行复现。在复现中,尽可能所有运算只通过numpy实现,减少for循环的调用,做到减少运算量,加快运算结果。

aouiylfjh的博客 1756

[机器学习]决策树选西瓜

文章目录一、决策树1、画法2、决策树的剪枝3、挑西瓜决策树3.1利用信息增益选择最优划分属性二、sk-learn库对西瓜数据集,分别进行ID3、C4.5和CART的算法代码实现1.ID3算法2、C4.5算法3、CART算法三、参考 一、决策树 在机器学习中,决策树是一个预测模型,他代表的是对象属性与对象值之间的一种映射关系。Entropy = 系统的凌乱程度,使用算法ID3, C4.5和C5.0生成树算法使用熵。这一度量是基于信息学理论中熵的概念。 1、画法 机器学习中,决策树是一个预测模型;他代表的是对

weixin_47593895的博客 3683

【Python】ID3算法的实现

ID3算法的实现ID3实现首先定义一个ID3DTree类来封装算法数据导入函数执行决策树函数决策树主方法构建决策树:创建决策树主程序计算出现次数最多的类别标签计算最优特征计算信息熵划分数据集训练决策树 ID3实现 首先定义一个ID3DTree类来封装算法 # coding:utf-8 #Python3.7.2 from numpy import * import math import copy...

qq_45587822的博客 6376

机器学习-周志华-课后习题答案-决策树

本文为博主原创,由于没有可以参考的答案,所以内容中若有错误的地方烦请指正,不甚感激。 注:本文中的代码均使用python,常用工具包包括 pandas,scikit-learn,numpy, scipy,matplotlib等。 4.1 试证明对于不含冲突数据(即特征向量完全相同但标记不同)的训练集,必存在与训练集一致(即训练误差为0)的决策树 答:假设不存在与训练集一致的决策

Will Lin的博客 4万+

决策树之CART算法

在之前介绍过决策树的ID3算法实现,今天主要来介绍决策树的另一种实现,即CART算法。   Contents      1. CART算法的认识    2. CART算法的原理    3. CART算法的实现     1. CART算法的认识      Classification And Regression Tree,即分类回归树算法,简称CART算法,它是决策树的一种实

ACdreamer 8万+

python实现ID3决策树分类算法

所有的分类与回归算法中心思想大致是一样的,那就是根据现有带标签的数据集训练一个分类器模型,然后对待未知的样本,根据训练好的分类模型来判定它属于哪个类。分类与回归的区别在我看来就是标签连续与否的区别,若标签连续,则是回归,若标签离散,则是分类。 数据集中的每个样本的特征都是相同维度的,生活中我们常遇到的是根据某个样本少量的特征就可以确定这个样本属于哪个类,比如可以根据一个人的长相、身高、文凭、收入...

aoanng的博客 3万+

Python实现ID3决策树算法实战

ID3(Iterative Dichotomiser 3)是机器学习中一个经典的决策树算法,由Ross Quinlan在1986年提出。其核心思想是通过递归方式构建一棵树结构的分类器,以此来实现样本数据的分类任务。信息熵是衡量数据中包含信息量多少的一种度量。在一个信息集合中,熵越低,信息的不确定性就越小。熵的数学表达式通常被定义为:其中 (H(S)) 表示集合 (S) 的熵,(p(x_i)) 表示 (x_i) 出现的概率。在一个决策树中,熵用来衡量一个节点中所有实例的纯度。

weixin_30951515的博客 821

机器学习之决策树(ID3算法)

决策树(Decision Tree)是一种常见的机器学习算法,用于分类和回归任务。它通过对数据集进行反复的二分划分,构建一棵树状结构,每个非叶节点代表一个特征属性上的决策,每个叶节点代表一个类别标签或回归值。

weixin_74105361的博客 2746

ID3算法在MATLAB中的实现与应用

ID3算法是机器学习中一种经典的决策树学习算法,主要用途是分类问题。它采用信息增益作为选择特征的标准,通过递归构建决策树的方式,将数据集划分为更小的子集,直到所有子集中的数据都属于同一类别或者没有任何特征可供划分为止。在这个过程中,ID3算法的核心思想是尝试每一个特征,并计算这个特征能够提供的信息增益,以决定哪个特征在当前分割数据时最有用。ID3算法的优点在于它结构简单,易于理解和实现。然而它也存在一些不足之处,比如对缺失数据敏感,无法处理连续特征,容易产生过拟合等。

weixin_30533301的博客 697

深入理解与应用:决策树模型案例分析

决策树是一种流行的机器学习模型,它通过一系列的分支决策规则来预测目标变量的值。它在分类和回归任务中都有广泛的应用,并且以直观和易于解释著称。在本章中,我们将简要介绍决策树的基本概念,并讨论其在实际问题中的应用实例,为读者提供对决策树模型全面的初步认识。信息熵的概念最早来源于热力学,它衡量了一个系统的无序度。在信息论中,熵被用来量化信息的不确定性。信息熵越高,表示系统中的信息不确定性越大。在决策树模型中,熵是衡量数据集纯度的重要指标,它可以帮助我们识别在分割数据时最有信息量的特征。

weixin_31776191的博客 1182

AI遮天传 ML-决策树(二)

决策树学习第二章

suic009的博客 2870

ID3算法scala语言实现

完整的ID3决策树算法,采用了scala语言来实现,代码完整。

决策树(ID3算法)

决策树学习笔记1、决策树的概念    顾名思义,决策树是用来:根据已知的若干条件,来对事件作出判断。从根节点到叶子节点,是将不同特征不断划分的过程,最后将类别分出。    在理论学习前,先了解下面一个例子:    如下图所示,根据“不浮出水面是否可以生存”和“是否有脚蹼”两种特征来判断该海洋动物是否鱼类。图中有5个样本,样本中有两种是鱼类,三种不是鱼类。    可建立的特征向量如下:_data_s...

知难行更难 3万+

java实现基于ID3算法的决策树分类器

用java实现基于ID3算法的决策树分类器的eclipse完整工程代码,测试结果正确。

Matlab实战:用卡尔曼滤波搞定无人机GPS轨迹优化(附完整代码)

本文详细介绍了如何使用Matlab实现卡尔曼滤波(KF)算法优化无人机GPS轨迹,提供完整代码和工程实践指南。通过线性卡尔曼滤波技术,有效降低定位噪声,提升轨迹平滑度,适用于无人机导航和控制系统开发。

weixin_29061425的博客 253

决策树之理解ID3算法和C4.5算法

决策树学习笔记(一) 前言 决策树本身没有太多高深的数学方法,它依托于信息论的一些知识以及在数据结构中所学的树形结构。书中阐述的相当清楚明白,可是当我看完这些章节时,却始终无法得知决策树构建的思路,即决策树方法本身的诞生历程是什么?发明算法的作者是如何一步步构建,联想,解决数据分类问题的呢?因此,本文重点还是尝试去理解作者是如何一步步构建决策树,希望能够通过对关键问题进行抽象建模从而找到决...

Demon-初来驾到 3万+

地瓜派RDK X5部署YOLOv11n避坑指南:从Softmax瓶颈到BPU加速的实战解析

本文详细解析了在地瓜派RDK X5开发板上部署YOLOv11n模型时,从性能暴跌到成功优化的全过程。核心在于通过配置`node_info`将模型中的Softmax算子强制在BPU上以int16精度运行,解决了因算子被分配到CPU导致的严重性能瓶颈。实战部署后,模型推理延迟从126ms降至10.8ms,FPS从7.9提升至92.3,实现了显著的性能优化。

beta5的博客 865

rapidminer decision tree(决策树)手册

决策树是类似于节点集合的树,旨在创建有关与类的值隶属关系或数字目标值估计值的决策。每个节点表示一个特定属性的拆分规则。对于分类,此规则将属于不同类的值分开,对于回归,它将它们分开,以便以最佳方式减少所选参数条件的误差。...

m0_56134806的博客 2666

【深度避坑】Word 提示“内存或磁盘空间不足,保存失败”的真正原因与终极解决方案

这是 Word 2003 时代的老功能⚠现代 Office 使用全新的保存 API(与 OneDrive 深度集成)老插件无法兼容现代保存机制会拦截 Word 的写入流程导致保存动作失败,Word 误以为磁盘坏了,于是报错不是磁盘坏了,是 Word 被插件绊倒了。Word 无法保存 = 加载项冲突(尤其是书法 / 稿纸向导)。永久禁用即可彻底恢复。如果在写毕业论文、要交文档,强烈建议马上检查一下你的加载项,避免后期出现大规模崩溃丢稿。

m0_59029415的博客 3077

别再只设接触压力了!用ANSYS Workbench模拟O型圈密封泄漏的完整流程

本文详细介绍了在ANSYS Workbench中模拟O型圈密封泄漏的完整流程,重点解析了流体渗透压力载荷的设置与应用。通过双物理场耦合模型和精确的参数配置,帮助工程师准确评估密封性能,避免传统方法仅考虑接触压力的局限性。文章还提供了常见问题的解决方案和工程实践建议,提升密封设计的可靠性。

weixin_30372371的博客 403

机器学习方法:15分钟带你吃透决策树模型

【本文的阅读时间约15分钟,希望大家耐心观看】这是机器学习方法系列科普文章,由浙中大公卫徐老师撰写,往期推文可以看集合。在众多机器学习模型中,决策树是最为简单直观的一种算法。它就像我们平常做决定时的过程,逐步排除可能的选项,最终得出结论。今天这篇文章中,我们将结合图例讲解讲解决策树的结构、数学原理、具体构建和优化过程,让大家在理解时不至于太抽象,同时我们也会提供构建决策树预测模型的数据和代码,感...

郑老师统计 2936

Windows 必看!OpenClaw 一键安装教程|告别报错,一次成功不踩坑

OpenClaw 完整安装与配置的全流程教程

m0_70389289的博客 1085
上一篇: Spark性能优化--基础篇
下一篇: spark-submit 报错:No suitable driver 最终解决方案(测试通过)
小糖宝
博客等级 码龄9年 47粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值