Die geschichtete Probenahme ist eine Technik zur Aufrechterhaltung einer guten Bevölkerungsverteilung und Probenahme. In Python ist es in StratifiedShuffleSplit und train_test_split von Scikit-learn implementiert. Dies wird häufig bei der Kreuzvalidierung eines maschinellen Lernmodells berücksichtigt. Anstatt es nur als Werkzeug zu verwenden, implementierte ich einen Beispielcode zum Lernen in Python und verglich ihn mit Zufallsstichproben, um mein Verständnis zu vertiefen. Als Ergebnis wurde bestätigt, dass die Genauigkeit der Probenahme im Vergleich zur Zufallsstichprobe umso besser ist, je kleiner die Anzahl der Proben aus der Probenahmequelle ist. (Obwohl es ein natürliches Ergebnis ist, habe ich mein Verständnis vertieft, indem ich es mit meinen eigenen Händen reproduziert habe.)
Einfach ausgedrückt ist dies eine nützliche Technik für die Probenahme aus einer Population mit einer voreingenommenen Probenstruktur. Teilen Sie die Bevölkerung in kleine Gruppen, die "Schichten" genannt werden. Zu diesem Zeitpunkt sollte die Dispersion für jede Schicht so klein wie möglich sein und die Dispersion zwischen den Schichten sollte so groß wie möglich sein. Mit anderen Worten, Stichproben mit denselben Attributen werden zusammengefasst.
Angenommen, Sie haben 100 Karten mit einer beliebigen Zahl von 0 bis 9. Mische das.
0 | 1 | 9 | ・ ・ ・ | 5 | 3 | 7 | 1 |
---|---|---|---|---|---|---|---|
Gruppieren Sie dies nach derselben Nummer. Es ist eine Zahl, damit Sie sie sortieren können.
0 | 0 | 0 | ・ ・ ・ | 5 | 5 | 5 | 5 | ・ ・ ・ | 9 | 9 | 9 | 9 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Nach der Gruppierung nach derselben Nummer wie folgt eine Stichprobe aus jeder Gruppe im gleichen Verhältnis. Wenn beispielsweise die Abtastrate 10% beträgt, besteht eine 10% ige Wahrscheinlichkeit einer Zufallsstichprobe aus jeder Gruppe mit den Nummern 0-9. Wenn es jeweils 10 Zahlen von 0 bis 9 gibt, werden diese wie folgt zufällig ausgewählt.
0 | 0 | 0 | ・ ・ ・ | 0 | → Wählen Sie zufällig eine aus |
---|---|---|---|---|---|
1 | 1 | 1 | ・ ・ ・ | 1 | → Wählen Sie zufällig eine aus |
2 | 2 | 2 | ・ ・ ・ | 2 | → Wählen Sie zufällig eine aus |
・ ・ ・ | |||||
9 | 9 | 9 | ・ ・ ・ | 9 | → Wählen Sie zufällig eine aus |
Diese geschichtete Stichprobe ist für voreingenommene Stichprobenkonfigurationen wirksam.
Nehmen wir als leicht verständliches Beispiel an, dass von 20 Karten 2 "0" und die restlichen 18 "1" sind.
0 | 0 | 1 | 1 | ・ ・ ・ | 1 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|---|
Angenommen, Sie wählen zufällig 10 Blätter aus dem Ganzen aus. Die Extraktionsrate beträgt 50%. Da es zufällig ist, kann es vorkommen, dass 10 von 18 "1" ausgewählt werden und "0" nicht extrahiert wird. In diesem Fall enthält die Probe nach der Extraktion keine "0", sodass die Verteilung nicht aufrechterhalten werden kann.
0 | 0 | 1 | 1 | ・ ・ ・ | 1 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|---|
↓ ↓ ↓ ↓ Extrahieren Sie 10 von 20
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|---|
→ ** Da es keine "0" gibt, unterscheidet es sich deutlich von der Verteilung der Bevölkerung! ** ** **
Daher wird eine geschichtete Probenahme durchgeführt.
Für eine geschichtete Probenahme wie folgt extrahieren.
0 | 0 | 1 | 1 | ・ ・ ・ | 1 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|---|
↓ ↓ ↓ ↓ Extrahieren Sie 10 von 20
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|---|
→ ** Das Zusammensetzungsverhältnis von "0" und "1" entspricht der Grundgesamtheit = die Verteilung ist gleich! ** ** **
Die so extrahierten Proben behalten eine bessere Populationsverteilung bei, als wenn sie zufällig aus dem Ganzen ausgewählt würden.
Nachdem wir uns einen Überblick verschafft haben, werden wir eine geschichtete Stichprobe implementieren. Die Verarbeitungslogik ist wie folgt.
Unten ist der Code, der basierend auf der obigen Logik abgetastet wurde.
import numpy as np
import random
def extract_stratified_sampling_result(ratio, base_samples):
u"""
Eine geschichtete Probenahme wird aus einer endlichen Population durchgeführt, indem das Extraktionsverhältnis angegeben wird.
:param ratio:Extraktionsverhältnis 0 zu 1.0
:param base_sample:Extraktionsquellengruppe
:return:
"""
#Nehmen Sie zunächst eine aus jeder Zahlengruppe heraus.
#Danach wird es zufällig aus jeder numerischen Gruppe ausgewählt, um das Zusammensetzungsverhältnis näher an die Population zu bringen.
#X-Extraktionsrate nach dem Extrahieren einer aus jeder Zahlengruppe(i)Und. Ich bin die Gruppennummer.
#N für die Nummer jeder Nummerngruppe(i)Und.
#Die zu extrahierende Zahl ist das Verhältnis x N.(i)Ist.
#Ich habe bereits einen herausgenommen, also bleibt es( N(i) - 1 )Extraktionsrate X aus den Stücken(i)Nach dem Zufallsprinzip herausnehmen.
#In Kombination mit dem bereits herausgenommenen Verhältnis ergibt sich daher das Verhältnis x N.(i)Werde ein Individuum.
# X(i) x (N(i) - 1) + 1 = ratio x N(i)
# X(i) = (ratio x N(i) - 1 )/(N(i) - 1)Ist.
block_count = np.bincount(base_samples)
x = (ratio * block_count - 1) / (block_count - 1)
#Berechnen Sie den Schwellenwert für Zufallszahlen bei der Stichprobe.
#Schwelle= 1.0 -Extraktionsrate jeder Gruppe
#Extrahieren, wenn die Zufallszahl den Schwellenwert überschreitet.
#Die Extraktionsrate einer Gruppe beträgt 0.Wenn 3, dann 1.0 - 0.3 = 0.7, Zufallszahl ist 0.Wenn es 7 oder mehr ist, wird es extrahiert.
#Ein Array x, das die Extraktionsrate für jede Zahlengruppe enthält,
#Ordnen Sie so viele wie die Nummer jeder Nummer.
threshold = np.repeat(1.0 - x, block_count)
#Indexliste jedes Elements, wenn der ursprüngliche Satz sortiert ist
#Das Extrahieren aus Proben in dieser Reihenfolge führt zur Sortierung.
sorted_pos = np.argsort(base_samples)
#Startposition jeder Nummerngruppe
block_start = np.concatenate(([0], np.cumsum(block_count)[:-1]))
#Wenn die generierte Zufallszahl den Schwellenwert überschreitet, wird sie extrahiert.
threshold[block_start] = 0 #Das erste Element jeder Zahlengruppe wird immer extrahiert
extracted = []
for i in range(len(base_samples)):
each_rand = random.random()
if each_rand > threshold[i]:
pos = sorted_pos[i]
extracted.append(base_samples[pos])
extracted = np.array(extracted, dtype=np.int64)
return extracted
Es wird angenommen, dass das Argument base_samples eine Liste von Ganzzahlen enthält. Werfen wir einen Blick auf jeden Code. Lassen Sie uns zunächst die Zusammensetzung der Gruppe von base_samples verstehen, aus der sie extrahiert wird. Hier kommt np.bincount () ins Spiel. Es aggregiert die Nummer jeder Nummer, aus der die Liste besteht.
block_count = np.bincount(base_samples)
Wenn base_samples beispielsweise 9 0s und 91 1s enthält, gibt block_count das folgende Ergebnis zurück:
[ 9 91]
Mit anderen Worten block_coount [0] = Anzahl der Zahlen 0, block_count [1] = Anzahl der Zahlen 1, Deshalb. Diese block_count entspricht der Nummer N (i) jeder Schicht in der vorherigen Logik. Als nächstes finden Sie die Extraktionsrate X (i) für jede Schicht. Die Extraktionsrate r entspricht dem Argumentverhältnis, daher lautet der Code wie folgt.
x = (ratio * block_count - 1) / (block_count - 1)
Da block_count ein Numpy-Array ist, ist das Berechnungsergebnis auch ein Numpy-Array. Das heißt, der Inhalt von x sieht folgendermaßen aus:
x [0] = Extraktionsrate der Schicht mit der Nummer 0 x [1] = Extraktionsrate der Schicht mit der Nummer 1
Nachdem x berechnet wurde, besteht der nächste Schritt darin, den zufälligen Schwellenwert zu finden. Wenn die Zufallszahl größer oder gleich diesem Wert ist, wird die Stichprobe entnommen. Deshalb,
Zufälliger Schwellenwert für jede Schicht= 1.0 - X(i)
Es wird sein. Wenn beispielsweise die Extraktionsrate für die Zahl 0 0,10 beträgt, ist der Schwellenwert
1.0 - 0.10 = 0.90
Es wird sein.
Mit anderen Worten, die Stichprobe wird nur genommen, wenn die erzeugte Zufallszahl (0 bis 1,0) 0,90 oder mehr beträgt.
Die zufälligen Schwellenwerte jeder Schicht, die auf diese Weise erhalten werden, werden wiederholt so oft angeordnet, wie die Anzahl der Proben in jeder Schicht.
#Ein Array x, das die Extraktionsrate für jede Zahlengruppe enthält,
#Ordnen Sie so viele wie die Nummer jeder Nummer.
threshold = np.repeat(1.0 - x, block_count)
x[0] = 0.20 , block_count[0] = 2 Unter der Annahme von x [1] = 0,10, block_count [1] = 18 ist der Listenschwellenwert für Zufallszahlenschwellen:
threshold = [ 0.80, 0.80, 0.90, 0.90, 0.90, ... 0.90]
Rufen Sie als Nächstes die Indexliste ab, nachdem Sie base_samples sortiert haben.
#Indexliste jedes Elements, wenn der ursprüngliche Satz sortiert ist
#Das Extrahieren aus Proben in dieser Reihenfolge führt zur Sortierung.
sorted_pos = np.argsort(base_samples)
Sie können eine Kombination aus Schwellenwert, sortierten_Positionen und Basisstichproben für geschichtete Stichproben verwenden. Zum Beispiel
--threshold [0]: Zufälliger Schwellenwert der ersten Anzahl von Layer 0 --sort_pos [0]: Position (= Index), an der die erste Nummer der Schicht 0 in base_samples gespeichert ist
Wenn daher die erste erzeugte Zufallszahl den Schwellenwert [0] oder höher ist, wird das erste Element der Schicht 0 extrahiert. Durch Verschieben der Scanposition von Schwelle und sortierten_Pos kann eine geschichtete Abtastung durchgeführt werden.
Danach werden wir für die Logik verarbeiten, dass immer eine aus jeder Schicht herausgenommen wird.
#Startposition jeder Nummerngruppe
block_start = np.concatenate(([0], np.cumsum(block_count)[:-1]))
#Wenn die generierte Zufallszahl den Schwellenwert überschreitet, wird sie extrahiert.
threshold[block_start] = 0 #Das erste Element jeder Zahlengruppe wird immer extrahiert
block_start enthält die Position des ersten Elements jeder Ebene. Wenn es beispielsweise 10 0s und 90 1s gibt, dann:
block_start = [0,10]
Die Ebene mit der Nummer 0 beginnt am block_start [0] th Die Ebene mit der Nummer 1 bedeutet, dass sie von der block_start [1] -ten Ebene ausgeht.
Verwenden Sie diesen block_start, um den Zufallszahlenschwellenwert des ersten Elements jeder Ebene auf 0 zu setzen. Ein Zufallszahlenschwellenwert von 0 bedeutet, dass er immer extrahiert wird.
Und da die Zufallszahlenschwelle nach dem Beginn jeder Schicht (1-X (i)) ist, wird sie gemäß der berechneten Extraktionsrate zufällig extrahiert.
Der Eintrag wird wahrscheinlich lang sein, daher werde ich hier abschließen.
Der folgende Eintrag enthält einen Beispielcode, der die Leistung einer einfachen Zufallsstichprobe mit einer geschichteten Stichprobe vergleicht.
Recommended Posts