我有一个带标签的数据集,其中包括350万条推文,我想使用Spark中的决策树对该数据集进行分类。我要做的第一件事是使用以下代码获取每个推文的tf-idf向量:
val tokenizer = new Tokenizer().setInputCol("text").setOutputCol("words")
val wordsData = tokenizer.transform(data)
val hashingTF = new HashingTF()
.setInputCol("words").setOutputCol("rawFeatures").setNumFeatures(10000)
val featurizedData = hashingTF.transform(wordsData)
val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")
val idfModel = idf.fit(featurizedData)
var tfidfData = idfModel.transform(featurizedData)
然后我使用以下代码在该数据上运行决策树:
var labeledData = tfidfData.rdd.map(x => LabeledPoint(x.getAs("label"),
org.apache.spark.mllib.linalg.Vectors.fromML(x.getAs("features"))))
// Split the data into training and test sets (30% held out for testing)
val splits = labeledData.randomSplit(Array(0.7, 0.3))
val (trainingData, testData) = (splits(0), splits(1))
// Train a DecisionTree model.
val numClasses = 2
val categoricalFeaturesInfo = Map[Int, Int]()
val impurity = "gini"
val maxDepth = 5
val maxBins = 1000
val model = DecisionTree.trainClassifier(trainingData, numClasses, categoricalFeaturesInfo,
impurity, maxDepth, maxBins)
问题是数据太大,无法容纳到内存中,因此请火花将其写入磁盘(超过100G),因此花在培训上的时间太长(超过了决策的简单单核sk-learn实现)树木)。
这里的问题是,有没有更好的方法来获取tf-idf向量或训练决策树?我在做错什么吗?
好吧,我想我自己弄清楚了。我分享答案,以帮助火花新手将来遇到此问题。我代码上的tfidfData是一个ml稀疏向量,为了与mllib一起使用,我将其转换为以下代码:
org.apache.spark.mllib.linalg.Vectors.fromML(x.getAs("features"))
此结果不是稀疏向量,所以我将其更改为:
org.apache.spark.mllib.linalg.SparseVector.fromML(row.getAs("features"))
然后,先前代码的结果时间(大约1600s)减少到100s,甚至f1预测值也增加了。