侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

Spark Decision Tree

2022-07-09 星期六 / 0 评论 / 0 点赞 / 48 阅读 / 7267 字

决策树归纳是从有类标号的训练元组中学习决策树。决策树是一种类似于流程图的树结构,其中,每个内部节点表示在一个属性上的测试,每个分支代表该测试的一个输出,而每个树叶节点存放一个类标号,最顶层节点是跟节点

    决策树归纳是从有类标号的训练元组中学习决策树。决策树是一种类似于流程图的树结构,其中,每个内部节点表示在一个属性上的测试,每个分支代表该测试的一个输出,而每个树叶节点存放一个类标号,最顶层节点是跟节点。


一:算法逻辑

D:数据

Attribute_list:元组属性列表

Attribute_selection_method:选择可以按类最好地区分给定元组的属性

  • 树从单个节点N开始,N代表D中的训练元组

  • 如果D中的元组都为同一类,则节点N变为树叶,并用该类标记他。

  • 否则继续调用attribute_selection_method确定如果分裂。目的是使得每个分支上的输出分区都尽可能“纯”。

  • 对分裂准则的每个输出,由节点N生长一个分支,D中的元组据此进行划分。假设A是分裂属性,根据训练数据,由三种可能的情况:

    (1) A是离散的:在这种情况下,节点N的测试输出直接对应与A的已知值。对A的每个已知值创建一个分支。

    (2)A是连续的:有两个可能的输出,分别对应与条件A<=split,A>split

    (3) A是离散的且必须产生二叉树:子集作为分裂条件

  • 对于D的每个结果分区上的元组,算法使用同样的递归形成决策树。

  • 终止条件

    (1)分区D的所有元组都属于同一个类

    (2)没有剩余属性可以用来进一步划分元组,使用多数表决。

  • 返回决策树

二: 属性选择度量

    属性选择度量是一种选择分裂准则,一般我们使用两种方式,信息增益(熵),以及基尼系数。基尼指数一般考虑属性的二元划分。两者的目的都是使得每个分支上的输出分区都尽可能“纯”。


三:使用Spark MLlib

  Spark MLlib提供了决策树算法,使我们能够从基本的算法中脱离出来。

 加载数据:

    // line -> user,featureCategoricalOne,fTwo,featureCategoricalThree,label    val rawData = sc.textFile(rawdataPath)                    .map(line =>{                      val values = line.split("/t")                      val featureVector = Vectors.dense(values.slice(1,values.length-1).map(_ .toDouble))                      val label = values(values.length-1).toDouble                      LabeledPoint(label, featureVector)                    })

第一步是加载数据,假设你已经有要处理的数据存放在hdfs中。

label:结果,也就是最后的分类

featureVector:特征向量

    //train data for training set, test data for valuating the model    val Array(trainData, testData) = rawData.randomSplit(Array(0.8, 0.2))    trainData.cache()    testData.cache()

第二部是划分数据,一部分数据用来训练构造决策树,另一部分用来做测试(其实还应该有第三部分,可以防止构造的决策树过分耦合overfitting)

    //tell DecisionTree the number of values of categorical feature    val featureMap = Map(0 -> 2,2 ->2)        val model = org.apache.spark.mllib.tree.DecisionTree.trainClassifier(trainData, 2, featureMap, "gini", 10, 100)

第三部分就是训练决策树。

最后是评估模型。

  def getMetrics(model: DecisionTreeModel, data: RDD[LabeledPoint]): MulticlassMetrics = {    val predictionsAndLabels = data.map(example => (model.predict(example.features), example.label)    )    new MulticlassMetrics(predictionsAndLabels)  }        val metrics = getMetrics(model, testData)          //our label is binary    println("precision:0:::::::::::::::"+metrics.precision(0))    println("recall pre:0::::::::::"+metrics.recall(0))    println("precision:1:::::::::::::::"+metrics.precision(1))    println("recall pre:1:::::::::::::::"+metrics.recall(1))    //confusion matrix    println("confusionMatrix:::::::::::::::"+metrics.confusionMatrix)

如何评估呢?有以下一些指标:精确度,召回率等。理解如下:

    假设原始样本中有两类,其中:

1:总共有 P个类别为1的样本,假设类别1为正例。 

2:总共有N个类别为0 的样本,假设类别0为负例。 

    经过分类后:

3:有 TP个类别为1 的样本被系统正确判定为类别1,FN 个类别为1 的样本被系统误判定为类别 0,

显然有P=TP+FN; 

4:有 FP 个类别为0 的样本被系统误判断定为类别1,TN 个类别为0 的样本被系统正确判为类别 0,

显然有N=FP+TN; 

那么:

精确度(Precision):

P = TP/(TP+FP) ;  反映了被分类器判定的正例中真正的正例样本的比重( 

 准确率(Accuracy)

A = (TP + TN)/(P+N) = (TP + TN)/(TP + FN + FP + TN);    

反映了分类器统对整个样本的判定能力——能将正的判定为正,负的判定为负 

 召回率(Recall),也称为 True Positive Rate:

R = TP/(TP+FN) = 1 - FN/T;  反映了被正确判定的正例占总的正例的比重 


另外,完成的项目存放在项目地址  


 

广告 广告

评论区