Como obter uma amostra com um tamanho exato de amostra em Spark RDD?

porque é que a função rdd.sample() na Spark RDD devolve um número diferente de elementos, mesmo que o parâmetro da fracção seja o mesmo? Por exemplo, se meu código é como abaixo:

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

cada vez que corro a segunda linha do Código devolve um número diferente não igual a 1000. Na verdade, espero ver 1000 cada vez, embora os 1000 elementos possam ser diferentes. Alguém me pode dizer Como posso obter uma amostra com o tamanho da amostra exactamente igual a 1000? Muito obrigado.

Author: Metropolis, 2015-09-29

2 answers

Se queres uma amostra exacta, tenta fazer

a.takeSample(false, 1000)

Mas lembre-se que isto devolve um Array e não um RDD.

Quanto à razão pela qual o a.sample(false, 0.1) não devolve o mesmo tamanho da amostra: é porque a spark internamente usa algo chamado amostragem de Bernoulli para a recolha da amostra. O argumento fraction não representa a fração do tamanho real da RDD. Representa a probabilidade de cada elemento da população ser selecionado para a amostra, e como Wikipédia diz:

Uma vez que cada elemento da população é considerado separadamente para a amostra, o tamanho da amostra não é fixo, mas sim segue uma distribuição binomial.

E isso significa que o número não permanece fixo.

Se você definir o primeiro argumento para true, então ele vai usar algo chamado Poisson sampling , o que também resulta em um tamanho de amostra resultante não-determinístico.

Actualizar

Se se quiser manter o método sample, poderá provavelmente indicar uma probabilidade maior para o fraction param e depois ligar para take como em:

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

Isto deve, na maioria das vezes, mas não necessariamente sempre, resultar no tamanho da amostra de 1000. Isto pode funcionar se você tiver uma população grande o suficiente.

 15
Author: Bhashit Parikh, 2015-09-29 07:31:37
Outra maneira pode ser primeiro tomar um par e depois fazer RDD. Isto pode ser lento com grandes conjuntos de dados.
sc.makeRDD(a.takeSample(false, 1000, 1234))
 2
Author: Laeeq, 2016-11-01 11:19:32