如何在Spark RDD中获取具有精确样本大小的样本?

时间:2015-09-29 06:55:03

标签: apache-spark sample rdd

为什么Spark RDD上的rdd.sample()函数返回不同数量的元素,即使fraction参数相同?例如,如果我的代码如下所示:

val a = sc.parallelize(1 to 10000, 3)
a.sample(false, 0.1).count

每次运行代码的第二行时,它返回一个不等于1000的不同数字。实际上我希望每次都能看到1000,尽管1000个元素可能不同。谁能告诉我如何获得样本大小恰好等于1000的样本?非常感谢你。

2 个答案:

答案 0 :(得分:22)

如果您需要精确样本,请尝试

a.takeSample(false, 1000)

但请注意,这会返回一个数组,而不是RDD

至于为什么a.sample(false, 0.1)没有返回相同的样本大小:因为spark内部使用了一个名为Bernoulli sampling的东西来获取样本。 fraction参数不代表RDD实际大小的分数。它表示人口中每个元素被选为样本的概率,并且维基百科说:

  

因为样本的每个元素都是单独考虑的,所以样本大小不是固定的,而是遵循二项分布。

这实质上意味着这个数字不会保持不变。

如果您将第一个参数设置为true,那么它将使用名为Poisson sampling的内容,这也会导致非确定性的结果样本大小。

<强>更新

如果您希望坚持使用sample方法,则可以为fraction参数指定更大的概率,然后按以下方式调用take

a.sample(false, 0.2).take(1000)

大部分时间,但不一定总是,这应该导致样本量为1000.如果你有足够多的人口,这可能会有效。

答案 1 :(得分:4)

另一种方法可以是先取样然后再制作RDD。对于大型数据集,这可能会很慢。

sc.makeRDD(a.takeSample(false, 1000, 1234))