[Implementierung zum Lernen] Implementieren Sie Stratified Sampling in Python (1)

Eintragsübersicht

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.)

Geschichtete Stichprobe

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.

Extraktion aus vorgespannter Probenzusammensetzung

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

(1) Bei zufälliger Auswahl aus dem Ganzen

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.

(2) Bei geschichteten Stichproben

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.

Implementieren Sie geschichtete Stichproben

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

[Implementierung zum Lernen] Implementieren Sie Stratified Sampling in Python (1)
Implementieren Sie das Stacking-Lernen in Python [Kaggle]
RNN-Implementierung in Python
ValueObject-Implementierung in Python
Implementieren Sie XENO mit Python
Implementieren Sie sum in Python
Implementieren Sie Traceroute in Python 3
SVM-Implementierung in Python
Erstes tiefes Lernen in C # - Einführung in Python implementieren-
Erstellen Sie mit Python eine interaktive Umgebung für maschinelles Lernen
Lernablauf für Python-Anfänger
Python-Lernplan für KI-Lernen
Implementieren Sie Naive Bayes in Python 3.3
Implementieren Sie alte Chiffren in Python
Techniken zum Sortieren in Python
Implementieren Sie Redis Mutex in Python
Implementieren Sie die Erweiterung in Python
Implementieren Sie schnelles RPC in Python
Checkios Empfehlung zum Erlernen von Python
Implementieren Sie den Dijkstra-Algorithmus in Python
Implementieren Sie den Slack Chat Bot in Python
Implementierung der schnellen Sortierung in Python
Über "für _ in range ():" von Python
So implementieren Sie Python EXE für Windows mit Docker-Container
Implementieren Sie die Funktion power.prop.test von R in Python
Suchen Sie mit Python nach externen Befehlen
Sortieralgorithmus und Implementierung in Python
Implementierung der HMM-Parameterschätzung in Python
Implementierung einer gemischten Normalverteilung in Python
Web-Lehrmaterialien zum Erlernen von Python
Implementieren Sie das Singleton-Muster in Python
Implementierung eines Lebensspiels in Python
<Für Anfänger> Python-Bibliothek <Für maschinelles Lernen>
Python: Vorverarbeitung beim maschinellen Lernen: Übersicht
Implementierte Perceptron-Lernregeln in Python
Implementieren Sie die REST-API schnell in Python
Implementierung der ursprünglichen Sortierung in Python
Führen Sie unittest in Python aus (für Anfänger)
Lernverlauf für die Teilnahme an der Team-App-Entwicklung mit Python ~ Django Tutorial 5 ~
Lernverlauf für die Teilnahme an der Entwicklung von Team-Apps in Python ~ Indexseite ~
Lernverlauf für die Teilnahme an der Entwicklung von Team-Apps mit Python ~ Django Tutorial 4 ~
Wie wäre es mit Anaconda zum Erstellen einer maschinellen Lernumgebung mit Python?
Lernverlauf für die Teilnahme an der Team-App-Entwicklung mit Python ~ Django Tutorial 6 ~
Ich habe versucht, PLSA in Python zu implementieren
Implementieren Sie __eq__ usw. generisch in der Python-Klasse
Ich habe versucht, Permutation in Python zu implementieren
Verstärken Sie Bilder für maschinelles Lernen mit Python
Anmerkung von nfc.ContactlessFrontend () von nfcpy von Python
Inject wird für DDD in Python empfohlen
Warteschlangen- und Python-Implementierungsmodul "deque"
Implementieren Sie den FIR-Filter in Python und C.
Tipps zum Umgang mit Binärdateien in Python
[Python] Techniken, die häufig beim maschinellen Lernen verwendet werden
Implementieren Sie gemeinsam statistische Hypothesentests in Python
Warum Python für maschinelles Lernen ausgewählt wird
Ich habe versucht, PLSA in Python 2 zu implementieren
Zusammenfassung verschiedener for-Anweisungen in Python