我从一本书中读了一段关于二元决策树的代码。它在原始数据中只有一个分类特征,即字段(3),并被转换为一个k(单热编码)。如何处理决策树中的多个分类特征?
def PrepareData(sc: SparkContext): (RDD[LabeledPoint], RDD[LabeledPoint], RDD[LabeledPoint], Map[String, Int]) = {
val rawDataWithHeader = sc.textFile("data/train.tsv")
val rawData = rawDataWithHeader.mapPartitionsWithIndex { (idx, iter) => if (idx == 0) iter.drop(1) else iter }
val lines = rawData.map(_.split("\t"))
val categoriesMap = lines.map(fields => fields(3)).distinct.collect.zipWithIndex.toMap
val labelpointRDD = lines.map { fields =>
val trFields = fields.map(_.replaceAll("\"", ""))
val categoryFeaturesArray = Array.ofDim[Double](categoriesMap.size)
val categoryIdx = categoriesMap(fields(3))
categoryFeaturesArray(categoryIdx) = 1
val numericalFeatures = trFields.slice(4, fields.size - 1).map(d => if (d == "?") 0.0 else d.toDouble)
val label = trFields(fields.size - 1).toInt
LabeledPoint(label, Vectors.dense(categoryFeaturesArray ++ numericalFeatures))
}
val Array(trainData, validationData, testData) = labelpointRDD.randomSplit(Array(8, 1, 1))
return (trainData, validationData, testData, categoriesMap)
}
不知如何,如果有原始数据几个类别特征修改代码,让我们说现场(3),现场(5),现场(7)全部类别特征。
我修改的第一行:
def PrepareData(sc: SparkContext): (RDD[LabeledPoint], RDD[LabeledPoint], RDD[LabeledPoint], Map[String, Int], Map[String, Int], Map[String, Int], Map[String, Int]) =......
然后,我转换另一两个字段成1-的k值编码,因为它是像完成:
val categoriesMap5 = lines.map(fields => fields(5)).distinct.collect.zipWithIndex.toMap
val categoriesMap7 = lines.map(fields => fields(7)).distinct.collect.zipWithIndex.toMap
val categoryFeaturesArray5 = Array.ofDim[Double](categoriesMap5.size)
val categoryFeaturesArray7 = Array.ofDim[Double](categoriesMap7.size)
val categoryIdx3 = categoriesMap5(fields(5))
val categoryIdx5 = categoriesMap7(fields(7))
categoryFeaturesArray5(categoryIdx5) = 1
categoryFeaturesArray7(categoryIdx7) = 1
最后,我修改LabeledPoint和返回像:
LabeledPoint(label, Vectors.dense(categoryFeaturesArray ++ categoryFeaturesArray5 ++ categoryFeaturesArray7 ++ numericalFeatures))
return (trainData, validationData, testData, categoriesMap, categoriesMap5, categoriesMap7)
它是正确的吗?
============================================== ====
我遇到的第二个问题是:从书下面的代码,在trainModel,它采用
DecisionTree.trainRegressor(trainingData, categoricalFeaturesInfo, impurity, maxDepth, maxBins)
下面是代码:
def trainModel(trainData: RDD[LabeledPoint], impurity: String, maxDepth: Int, maxBins: Int): (DecisionTreeModel, Double) = {
val startTime = new DateTime()
val model = DecisionTree.trainClassifier(trainData, 2, Map[Int, Int](), impurity, maxDepth, maxBins)
val endTime = new DateTime()
val duration = new Duration(startTime, endTime)
(model, duration.getMillis())
}
的问题是:如果它具有前面提到的三个分类特征,我该如何将categoricalFeaturesInfo传递到此方法中?
我只想按照书中的步骤通过使用决策树自行建立预测系统。更具体地讲,我选择的是数据集有几个分类的功能,如: 性别:男,女
教育:HS-毕业,学士,硕士,博士,......
国家:美国,加拿大,英国,澳大利亚,......
但我不知道如何将它们合并成一个单一的categoryFeatures ++ numericalFeatures
投入Vector.dense()
,和一个单一的categoricalFeaturesInfo
投入DecisionTree.trainRegressor()
哼哼......我只是想按照书中的步骤,通过使用决策树自己建立预测系统。 更具体地说,我选择的数据集有几个明确的特征,如: 性别:男性,女性; 学历:HS-grad,Bachelors,Master,PH.D,......; 国家:美国,加拿大,英国,澳大利亚......; ...等等。 但我不知道如何将它们合并成一个单独的“categoryFeatures ++ numericalFeatures”放入“Vector.dense()”,并将一个单独的“categoricalFeaturesInfo”放入“DecisionTree.trainRegressor()” –
If您使用ML Pipelines,您将获得所需的所有工具,包括编码器,分度器和组装器。 – zero323
@ C.Y.Wu我赞同zero323,但是如果我问这本书的标题是什么?我想看看它。 – eliasah