Bessere Möglichkeit, Stichproben ohne Ersatz aus der Liste in Haskell zu nehmen

8

Ich muss eine Stichprobe ohne Ersatz nehmen (jedes Element kommt nur einmal in der Stichprobe vor), aus einer längeren Liste. Ich benutze den Code unten, aber jetzt würde ich gerne wissen:

  1. Gibt es eine Bibliotheksfunktion, die das tut?
  2. Wie kann ich diesen Code verbessern? (Ich bin ein Haskell-Anfänger, also wäre das auch nützlich, wenn es eine Bibliotheksfunktion gibt).

Der Zweck der Probenahme besteht darin, Erkenntnisse aus der Analyse der Stichprobe für die Bevölkerung zu verallgemeinern.

%Vor%     
ajerneck 08.12.2012, 16:56
quelle

2 Antworten

6

Hier ist eine schnelle Umsetzung von dem, was Daniel Fischer in seinem Kommentar vorgeschlagen hat, indem er meinen bevorzugten PRNG (mwc-random) verwendet:

%Vor%

Dies ist so ziemlich eine (knappe) funktionale Neuschreibung von Rs interner C-Version von sample() , wie es ohne Ersatz heißt.

sample ist nur ein Wrapper für eine rekursive Worker-Funktion, die die Population inkrementell mischt, bis die gewünschte Stichprobengröße erreicht ist. Dabei werden nur die vielen gemischten Elemente zurückgegeben. Durch das Schreiben der Funktion wird sichergestellt, dass GHC sie inline einbinden kann.

Es ist einfach zu bedienen:

%Vor%

Eine Produktionsversion möchte vielleicht etwas wie einen veränderbaren Vektor anstelle von Data.Sequence verwenden, um die Zeit für GC zu verkürzen.

    
jtobin 08.12.2012, 21:39
quelle
2

Ich denke, ein üblicher Weg, dies zu tun, besteht darin, einen Puffer fester Größe mit den ersten N Elementen initialisiert zu halten und für jedes i-te Element i & gt; = N dies zu tun:

  1. Wählen Sie eine Zufallszahl, j, zwischen 0 und i.
  2. Wenn j & lt; N dann ersetzen Sie das j-te Element im Puffer durch den aktuellen.

Sie können die Richtigkeit durch Induktion beweisen:

Dies erzeugt eindeutig eine Stichprobe (ich nehme an, die Reihenfolge ist irrelevant), wenn Sie nur N Elemente haben. Nun nehme an, dass es bis zum i-ten Element stimmt. Dies bedeutet, dass die Wahrscheinlichkeit, dass irgendein Element im Puffer ist, N / (i + 1) ist (ich fange an, bei 0 zu zählen).

Nach der Auswahl der Zufallszahl ist die Wahrscheinlichkeit, dass das i + 1-te Element im Puffer ist, N / (i + 2) (j ist zwischen 0 und i + 1, und N davon enden im Puffer) ). Was ist mit den anderen?

%Vor%

Hier ist ein Code, der es im Sample-Size-Bereich unter Verwendung des (langsamen) Standard-System.Randoms macht.

%Vor%     
Itai Zukerman 10.12.2012 05:27
quelle

Tags und Links