web-dev-qa-db-fra.com

Comment obtenir un échantillon avec une taille d'échantillon exacte en Spark RDD?

Pourquoi la fonction rdd.sample() on Spark RDD renvoie un nombre différent d'éléments même si le paramètre fraction est le même? Par exemple, si mon code est comme ci-dessous:

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

Chaque fois que j'exécute la deuxième ligne du code, il renvoie un nombre différent différent de 1000. En fait, je m'attends à voir 1000 à chaque fois, bien que les 1000 éléments puissent être différents. Quelqu'un peut-il me dire comment obtenir un échantillon dont la taille est exactement égale à 1000? Merci beaucoup.

15
Carter

Si vous voulez un échantillon exact, essayez de faire

a.takeSample(false, 1000)

Mais notez que cela renvoie un tableau et non un RDD.

Quant à savoir pourquoi la a.sample(false, 0.1) ne renvoie pas la même taille d'échantillon: c'est parce que spark utilise en interne quelque chose appelé échantillonnage de Bernoulli pour prendre l'échantillon. L'argument fraction ne représente pas la fraction de la taille réelle du RDD. Il représente la probabilité que chaque élément de la population soit sélectionné pour l'échantillon, et comme le dit wikipedia:

Étant donné que chaque élément de la population est considéré séparément pour l'échantillon, la taille de l'échantillon n'est pas fixe mais suit plutôt une distribution binomiale.

Et cela signifie essentiellement que le nombre ne reste pas fixe.

Si vous définissez le premier argument sur true, il utilisera quelque chose appelé échantillonnage de Poisson , ce qui entraîne également une taille d'échantillon résultante non déterministe.

Mise à jour

Si vous voulez vous en tenir à la méthode sample, vous pouvez probablement spécifier une probabilité plus grande pour le paramètre fraction puis appeler take comme dans:

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

Cela devrait, la plupart du temps, mais pas nécessairement toujours, donner un échantillon de 1 000 personnes. Cela pourrait fonctionner si vous avez une population suffisamment importante.

27
Bhashit Parikh

Une autre façon peut être de prendre d'abord Sample puis de faire RDD. Cela peut être lent avec de grands ensembles de données.

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