我正在尝试在Scala/Spark中进行替换采样,定义每个类的概率。
这就是我在R.中的做法
# Vector to sample from
x <- c("User1","User2","User3","User4","User5")
# Occurenciens from which to obtain sampling probabilities
y <- c(2,4,4,3,2)
# Calculate sampling probabilities
p <- y / sum(y)
# Draw sample with replacement of size 10
s <- sample(x, 10, replace = TRUE, prom = p)
# Which yields (for example):
[1] "User5" "User1" "User1" "User5" "User2" "User4" "User4" "User2" "User1" "User3"
我如何在Scala/Spark中做到这一点?
我对它进行了更多的研究,正如我之前所说,我认为分层采样的东西不适用,所以这里有另一个想法。
对于采样权重p(i)
(非负,加起来为1),每个基准x(i)
的样本数量具有二项式分布,如果没有权重太大,则可以通过泊松分布来近似。泊松参数将为p(i)*n
,其中n
是要绘制的样本总数。
对数据进行迭代,生成数据的m
个副本(可能为零),其中m
是参数为p(i)*n
的泊松分布。将所有副本展平成一个列表。达,仅此而已。
结果的长度是随机的,期望值为n
。如果它太短,我想你可以产生更多,或者如果它太长,可以扔掉一些。大概如果你很小心的话,当你以这种方式整理清单时,你必须考虑到重量。
要生成泊松值,可以使用apache-commons-math3中的PoissonDistribution.sample
(就像Spark MLlib本身所做的那样),或者,如果你很勇敢,你可以自己实现它。
祝你好运,玩得开心。如果你还有其他问题,我可以试着回答。
查看标题为"分层采样"的MLLib基本统计信息页面。我认为sampleByKey
或sampleByKeyExact
在这里可能是合适的。