我正在尝试将我的数据集拆分为训练和测试数据集。我首先将文件读入内存,如下所示:
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(_)))
答案 0 :(得分:3)
val test = ratings.subtract(train)
答案 1 :(得分:1)
看看这里。 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))
}
答案 2 :(得分:0)
我没有使用排除方法(如过滤或减法),而是“手动”对集合进行分区,以便更有效地执行:
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
是串行器友好的