[PYTHON] Abtastung in unausgeglichenen Daten

Motivation

Meine Motivation ist es, Klassifikatoren mit unausgeglichenen Daten von 1: 10.000 oder mehr effektiv zu trainieren. Ich denke, dass diejenigen, die eine webbasierte Lebenslaufanalyse durchführen, hier Probleme haben könnten. Ich bin einer von ihnen w

Was ich in diesem Blog geschrieben habe

Übersicht über Stichprobenverfahren für unausgeglichene Daten

Verweise

Angemessene Zusammenfassung des obigen Papiers

Bitte lesen Sie das Papier für Details, da es wirklich richtig zusammengefasst ist. ..

Umgang mit unausgeglichenen Daten

- algorithm-level approaches Führen Sie einen Koeffizienten ein, um das Ungleichgewicht im Modell anzupassen (passen Sie die Kostenfunktion an). - data-level approaches Eine Methode zum Reduzieren von Mehrheitsdaten und Erhöhen von Minderheitsdaten. Die Reihenfolge ist Unterabtastung, Überabtastung. Dieses Mal werde ich hauptsächlich Ansätze auf Datenebene beschreiben.

Stichprobenart

Grob unterteilt gibt es Unter-, Über- und Hybridmethoden. - under-sampling ・ Reduzieren Sie die Mehrheitsdaten ・ Zufällige Unterabtastung und andere Methoden ・ Durch zufällige Unterabtastung können nützliche Daten gelöscht werden ⇒ Wenn die clusterbasierte Methode verwendet wird, hat jede Klasse eine eigene Datengruppe. Löschen Sie niemals nur einige nützliche Daten

- over-sampling ・ Erhöhen Sie die Minderheitsdaten ・ Zufällige Stichproben und andere Methoden ・ Zufälliges Oversampling führt zu Überlernen ⇒ Wird durch Erhöhen der Peripheriedaten (Daten mit hinzugefügtem Rauschen) gelöst, anstatt vorhandene Daten zu duplizieren

- Hybrid Methods Führen Sie sowohl Unter- als auch Überproben durch

Fehlertyp

Wenn man sich die Formel ansieht, sieht es wie folgt aus. erro.png

Abtastalgorithmus

- under-sampling · Verlassen / Löschen der am weitesten entfernten / neuesten Daten / Cluster von Minderheitendaten / Clustern (Im Fall eines Clusters wird dies anhand des Abstands des Schwerpunkts usw. beurteilt.) ・ Cluster alle Daten mit k-Mitteln und bestimmen die Anzahl der negativen Stichprobenreduktionen basierend auf dem Verhältnis von positiven und negativen Stichproben für jeden Cluster. ← Dieses Mal verwende ich diese Methode - over-sampling ・ Die Methode SMOTE scheint de facto der Standard zu sein Abtastung mit Rauschen, das einem der fünf Nachbarn der Minderheitsstichprobe basierend auf k-NN hinzugefügt wurde

Referenzcode

under-sampling Zunächst zur Unterabtastung

python


def undersampling(imp_info, cv, m):
    # minority data
    minodata = imp_info[np.where(cv==1)[0]]
    
    # majority data
    majodata = imp_info[np.where(cv==0)[0]]

    #Clustering mit kmeans2
    whitened = whiten(imp_info) #Normalisierung (entspricht der Verteilung jeder Achse)
    centroid, label = kmeans2(whitened, k=3) # kmeans2
    C1 = []; C2 = []; C3 = []; #Für die Clusterspeicherung
    C1_cv = []; C2_cv = []; C3_cv = [] 
    for i in xrange(len(imp_info)):
        if label[i] == 0:
            C1 += [whitened[i]]
            C1_cv.append(cv[i])
        elif label[i] == 1:
            C2 += [whitened[i]]
            C2_cv.append(cv[i])
        elif label[i] == 2:
            C3 += [whitened[i]]
            C3_cv.append(cv[i])
    
    #Konvertiert, weil das Numpy-Format einfacher zu handhaben ist
    C1 = np.array(C1); C2 = np.array(C2); C3 = np.array(C3) 
    C1_cv = np.array(C1_cv); C2_cv = np.array(C2_cv); C3_cv = np.array(C3_cv);
    
    #Anzahl der Minderheitsdaten für jede Klasse
    C1_Nmajo = sum(1*(C1_cv==0)); C2_Nmajo = sum(1*(C2_cv==0)); C3_Nmajo = sum(1*(C3_cv==0)) 
    
    #Anzahl der Mehrheitsdaten für jede Klasse
    C1_Nmino = sum(1*(C1_cv==1)); C2_Nmino = sum(1*(C2_cv==1)); C3_Nmino = sum(1*(C3_cv==1))
    t_Nmino = C1_Nmino + C2_Nmino + C3_Nmino

    #Es besteht die Möglichkeit, dass 0 im Nenner erscheint, also addieren Sie 1
    C1_MAperMI = float(C1_Nmajo)/(C1_Nmino+1); C2_MAperMI = float(C2_Nmajo)/(C2_Nmino+1); C3_MAperMI = float(C3_Nmajo)/(C3_Nmino+1);
    
    t_MAperMI = C1_MAperMI + C2_MAperMI + C3_MAperMI
    
    under_C1_Nmajo = int(m*t_Nmino*C1_MAperMI/t_MAperMI)
    under_C2_Nmajo = int(m*t_Nmino*C2_MAperMI/t_MAperMI)
    under_C3_Nmajo = int(m*t_Nmino*C3_MAperMI/t_MAperMI)
    t_under_Nmajo = under_C1_Nmajo + under_C2_Nmajo + under_C3_Nmajo

#    draw(majodata, label)
    
    #Löschen Sie die Daten so, dass die Mehrheit und die Minderheit in jeder Gruppe gleich sind
    C1 = C1[np.where(C1_cv==0),:][0]
    random.shuffle(C1)
    C1 = np.array(C1)
    C1 = C1[:under_C1_Nmajo,:]
    C2 = C2[np.where(C2_cv==0),:][0]
    random.shuffle(C2)
    C2 = np.array(C2)
    C2 = C2[:under_C2_Nmajo,:]
    C3 = C3[np.where(C3_cv==0),:][0]
    random.shuffle(C3)
    C3 = np.array(C3)
    C3 = C3[:under_C3_Nmajo,:]
    
    cv_0 = np.zeros(t_under_Nmajo); cv_1 = np.ones(len(minodata))
    cv_d = np.hstack((cv_0, cv_1))
    
    info = np.vstack((C1, C2, C3, minodata))
    
    return cv_d, info

over-sampling Als nächstes über Überabtastung

python


class SMOTE(object):
    def __init__(self, N):
        self.N = N
        self.T = 0
    
    def oversampling(self, smp, cv):
        mino_idx = np.where(cv==1)[0]
        mino_smp = smp[mino_idx,:]
        
        #Implementierung von kNN
        mino_nn = []
        
        for idx in mino_idx:
            near_dist = np.array([])
            near_idx = np.zeros(nnk)
            for i in xrange(len(smp)):
                if idx != i:
                    dist = self.dist(smp[idx,:], smp[i,:])
                    
                    if len(near_dist)<nnk: #Wenn Sie die erwartete Anzahl von Nachbarn nicht erreicht haben, fügen Sie sie der Liste hinzu, ohne Fragen zu stellen
                        tmp = near_dist.tolist()
                        tmp.append(dist)
                        near_dist = np.array(tmp)
                    elif sum(near_dist[near_dist > dist])>0:
                        near_dist[near_dist==near_dist.max()] = dist
                        near_idx[near_dist==near_dist.max()] = i
            mino_nn.append(near_idx)
        return self.create_synth( smp, mino_smp, np.array(mino_nn, dtype=np.int) )

    def dist(self, smp_1, smp_2):
        return np.sqrt( np.sum((smp_1 - smp_2)**2) )
                    
    def create_synth(self, smp, mino_smp, mino_nn):
        self.T = len(mino_smp)
        if self.N < 100:
            self.T = int(self.N*0.01*len(mino_smp))
            self.N = 100
        self.N = int(self.N*0.01)
        
        rs = np.floor( np.random.uniform(size=self.T)*len(mino_smp) )
        
        synth = []
        for n in xrange(self.N):
            for i in rs:
                nn = int(np.random.uniform(size=1)[0]*nnk)
                dif = smp[mino_nn[i,nn],:] - mino_smp[i,:]
                gap = np.random.uniform(size=len(mino_smp[0]))
                tmp = mino_smp[i,:] + np.floor(gap*dif)
                tmp[tmp<0]=0
                synth.append(tmp)
        return synth   

Eindrücke des Experiments

Ich frage mich, ob Ansätze auf Algorithmenebene gegenüber schmutzigen Daten robuster sind als Ansätze auf Datenebene. Vielleicht ist der Code falsch. .. .. Bitte unterrichten Sie, wenn es Mängel m (_ _) m gibt

Zusammenfassung

Da die Stapelverarbeitung das Ziel von Ansätzen auf Datenebene ist und die Wahrscheinlichkeit groß ist, dass die Anzahl der Berechnungen zunimmt, hielt ich es für praktischer, Anpassungen mit Ansätzen auf Algorithmenebene vorzunehmen. Bei Ansätzen auf Algorithmenebene müssen Sie nur die Kosten und den Gradienten der Gewichtsanpassung in der Minderheitendatenstichprobe erhöhen, sodass die Berechnungszeit fast nicht beeinflusst wird. .. Wenn Sie andere gute Möglichkeiten haben, mit unausgeglichenen Daten umzugehen, kommentieren Sie dies bitte.

Recommended Posts

Abtastung in unausgeglichenen Daten
Behandeln Sie Umgebungsdaten in Python
Bearbeiten von Daten in Python-try mit Pandas_plyr
Zeigen Sie UTM-30LX-Daten in Python an
Schreiben Sie Daten im HDF-Format
Wahrscheinlichkeitsvorhersage von unausgeglichenen Daten
Vorverarbeitung beim maschinellen Lernen 3 Fehlende Wert- / Ausreißer- / Ungleichgewichtsdaten
Holen Sie sich LeapMotion-Daten in Python.
Exportieren Sie DB-Daten im JSON-Format
Lesen Sie die Protokollpufferdaten mit Python3
Behandeln Sie Daten im NetCDF-Format mit Python
Umgang mit unausgeglichenen Daten
Datenvisualisierung in Python-Draw Cool Heatmaps
RSS-Daten in Zabbix speichern (Zabbix-Absender)
Versuchen Sie, Daten in MongoDB abzulegen
Datenvorhersagewettbewerb in 3 Schritten (titanisch)
Hashing von Daten in R und Python
Maschinelles Lernen in Delemas (Datenerfassung)
Überprüfen Sie die Datenzusammenfassung in CASTable
Vorverarbeitung beim maschinellen Lernen 2 Datenerfassung
Vorverarbeitung beim maschinellen Lernen 4 Datenkonvertierung
Python: Vorverarbeitung beim maschinellen Lernen: Umgang mit fehlenden / Ausreißern / unausgeglichenen Daten
Zeigen Sie das Bild nach der Datenerweiterung mit PyTorch an
Dateneingabe / -ausgabe in Python (CSV, JSON)
Ali Buch in Python: Abschnitt 2-4, Datenstruktur
Versuchen Sie, mit Binärdaten in Python zu arbeiten
Unausgeglichenes Datenlernen mit maschinellem Lernen k-NN
Windows → Linux Tipps zum Einbringen von Daten
Holen Sie sich Google Fit API-Daten in Python
Windähnliche Dummy-Datengenerierung im Markov-Prozess
Python: Vorverarbeitung beim maschinellen Lernen: Datenerfassung
Holen Sie sich Youtube-Daten in Python mithilfe der Youtube-Daten-API
Ich habe versucht, die verkratzten Daten in CSV zu speichern!
RSS-Daten in Zabbix speichern (externe Prüfung)
Zeichnen Sie Daten einfach in Shell und Python
Trennung von Design und Daten in matplotlib
Konvertierung von Zeitdaten in 25-Uhr-Notation
RDS-Daten über die Schrittplattform werden an Pandas gesendet
Python: Vorverarbeitung beim maschinellen Lernen: Datenkonvertierung
Gacha geschrieben in Python-Implementierung in grundlegende Datenstruktur-
Daten in RDS mit AWS Glue überschreiben
Vorverarbeitung beim maschinellen Lernen 1 Datenanalyseprozess
SELECT-Daten mithilfe der Client-Bibliothek mit BigQuery
Behandeln Sie 3D-Datenstrukturen mit Pandas
Bücher über Datenwissenschaft, die 2020 gelesen werden sollen