#scala #machine-learning #apache-spark
#scala #машинное обучение #apache-spark
Вопрос:
Я пытаюсь разделить свой набор данных на обучающие и тестовые наборы данных. Сначала я считываю файл в память, как показано здесь:
val ratings = sc.textFile(movieLensdataHome "/ratings.csv").map { line=>
val fields = line.split(",")
Rating(fields(0).toInt,fields(1).toInt,fields(2).toDouble)
}
Затем я выбираю 80% из них для своего обучающего набора:
val train = ratings.sample(false,.8,1)
Есть ли простой способ получить набор тестов распределенным способом,
Я пытаюсь это сделать, но безуспешно:
val test = ratings.filter(!_.equals(train.map(_)))
Комментарии:
1. Ключевым недоразумением в вопросе является использование функции ‘map’ в вашем фильтре. ‘map’ — это преобразование одного значения в другое значение, указанное данной функцией. Возможно, вы думаете о поиске значения в hashmap, но это неправильное понимание определения функции map.
Ответ №1:
val test = ratings.subtract(train)
Ответ №2:
Взгляните сюда. http://markmail.org/message/qi6srcyka6lcxe7o
Вот код
def split[T : ClassManifest](data: RDD[T], p: Double, seed: Long =
System.currentTimeMillis): (RDD[T], RDD[T]) = {
val rand = new java.util.Random(seed)
val partitionSeeds = data.partitions.map(partition => rand.nextLong)
val temp = data.mapPartitionsWithIndex((index, iter) => {
val partitionRand = new java.util.Random(partitionSeeds(index))
iter.map(x => (x, partitionRand.nextDouble))
})
(temp.filter(_._2 <= p).map(_._1), temp.filter(_._2 > p).map(_._1))
}
Ответ №3:
Вместо использования метода исключения (например, filter или subtract), я бы разделил набор «вручную» для более эффективного выполнения:
val probabilisticSegment:(RDD[Double,Rating],Double=>Boolean) => RDD[Rating] =
(rdd,prob) => rdd.filter{case (k,v) => prob(k)}.map {case (k,v) => v}
val ranRating = rating.map( x=> (Random.nextDouble(), x)).cache
val train = probabilisticSegment(ranRating, _ < 0.8)
val test = probabilisticSegment(ranRating, _ >= 0.8)
cache
сохраняет промежуточный RDD, чтобы с этого момента можно было выполнять следующие две операции без необходимости выполнения полной линейки.
(*) Обратите внимание на использование val
для определения функции вместо def
. val
они удобны для сериализатора
Комментарии:
1. У меня возникли проблемы с выполнением probabilisticSegment.
{case (k,v) => v
Где}
заканчивается? все еще учусь печатать на scala duck.2. должно быть:
{case (k,v) => v}
. Отредактировал код, чтобы отразить это.