2015-08-18 3 views
2

У меня есть набор данных, который находится в виде отдельных вложенных карт, а его тип Scala является:Как преобразовать карту, чтобы Спарк РДД

Map[String, (LabelType,Map[Int, Double])] 

Первый String ключ представляет собой уникальный идентификатор для каждого образца , а значение представляет собой кортеж, который содержит метку (которая равна -1 или 1), и вложенную карту, которая является разреженным представлением ненулевых элементов, которые связаны с образцом.

Я хотел бы загрузить эти данные в Spark (используя MUtil), а также обучить и протестировать некоторые алгоритмы машинного обучения.

Легко написать эти данные в файл с разреженным кодированием LibSVM, а затем загрузить его в Spark:

writeMapToLibSVMFile(data_map,"libsvm_data.txt") // Implemeneted some where else 
val conf = new SparkConf().setAppName("DecisionTree").setMaster("local[4]") 
val sc = new SparkContext(conf) 

// Load and parse the data file. 
val data = MLUtils.loadLibSVMFile(sc, "libsvm_data.txt") 
// Split the data into training and test sets 
val splits = data.randomSplit(Array(0.7, 0.3)) 
val (trainingData, testData) = (splits(0), splits(1)) 

// Train a DecisionTree model. 

Я знаю, что это должно быть так же легко, непосредственно загрузить переменную data из data_map, но я не знаю как.

Любая помощь приветствуется!

ответ

6

Я думаю, вы хотите что-то вроде этого

import org.apache.spark.rdd.RDD 
import org.apache.spark.mllib.linalg.Vectors 
import org.apache.spark.mllib.regression.LabeledPoint 

// If you know this upfront, otherwise it can be computed 
// using flatMap 
// trainMap.values.flatMap(_._2.keys).max + 1 
val nFeatures: Int = ??? 

val trainMap = Map(
    "x001" -> (-1, Map(0 -> 1.0, 3 -> 5.0)), 
    "x002" -> (1, Map(2 -> 5.0, 3 -> 6.0))) 

val trainRdd: RDD[(String, LabeledPoint)] = sc 
    // Convert Map to Seq so it can passed to parallelize 
    .parallelize(trainMap.toSeq) 
    .map{case (id, (labelInt, values)) => { 

     // Convert nested map to Seq so it can be passed to Vector 
     val features = Vectors.sparse(nFeatures, values.toSeq) 

     // Convert label to Double so it can be used for LabeledPoint 
     val label = labelInt.toDouble 

     (id, LabeledPoint(label, features)) 
}} 
2

Это можно сделать двумя способами

  1. sc.textFile("libsvm_data.txt").map(s => createObject())
  2. Преобразовать карты в коллекции объектов и использовать sc.parallelize()

Первый preferrable.

+0

Пожалуйста, обратите внимание, что «libsvm_data.txt» должен быть записан в файл первым, который я хочу избежать. – Alt

+0

Это правда, его следует избегать. – evgenii

Смежные вопросы