[PYTHON] Échantillonnage dans des données déséquilibrées

Motivation

Ma motivation est de former efficacement des classificateurs en utilisant des données déséquilibrées de 1: 10 000 ou plus. Je pense que ceux qui font une analyse de CV sur le Web peuvent être troublés ici. Je suis l'un d'eux w

Ce que j'ai écrit dans ce blog

Vue d'ensemble des méthodes d'échantillonnage pour les données déséquilibrées

Les références

Résumé approprié du document ci-dessus

Veuillez consulter l'article pour plus de détails car il est vraiment correctement résumé. ..

Comment gérer les données déséquilibrées

- algorithm-level approaches Introduire un coefficient pour ajuster le déséquilibre dans le modèle (ajuster la fonction de coût) - data-level approaches Une méthode pour réduire les données majoritaires et augmenter les données minoritaires. L'ordre est sous-échantillonnage, suréchantillonnage. Cette fois, je décrirai principalement les approches au niveau des données.

Type d'échantillonnage

En gros, il existe des méthodes de sous-échantillonnage, de sur-échantillonnage et hybrides. - under-sampling ・ Réduire les données majoritaires ・ Sous-échantillonnage aléatoire et autres méthodes ・ Un sous-échantillonnage aléatoire peut supprimer des données utiles ⇒ Si la méthode basée sur les clusters est utilisée, chaque classe aura un groupe de données distinct. N'effacez jamais que certaines données utiles

- over-sampling ・ Augmenter les données sur les minorités ・ Suréchantillonnage aléatoire et autres méthodes ・ Le suréchantillonnage aléatoire a tendance à provoquer un surapprentissage ⇒Résolution en augmentant les données environnantes (données avec du bruit ajouté) au lieu de dupliquer les données existantes

- Hybrid Methods Faites à la fois un sous-échantillonnage et un sur-échantillonnage

Type d'erreur

En regardant la formule, cela ressemble à ce qui suit. erro.png

Algorithme d'échantillonnage

- under-sampling · Laisser / supprimer les données / clusters les plus éloignés / les plus récents des données / clusters minoritaires (Dans le cas d'un amas, il est jugé par la distance du centre de gravité, etc.) ・ Regroupez toutes les données avec des k-moyennes et déterminez le nombre de réductions d'échantillons négatifs en fonction du rapport des échantillons positifs et négatifs pour chaque groupe. ← Cette fois, j'utilise cette méthode - over-sampling ・ La méthode appelée SMOTE semble être la norme de facto Échantillonné avec du bruit ajouté à l'un des cinq voisins de l'échantillon minoritaire basé sur k-NN

Code de référence

under-sampling Tout d'abord, sur le sous-échantillonnage

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]]

    #Regroupement avec kmeans2
    whitened = whiten(imp_info) #Normalisation (correspond à la distribution de chaque axe)
    centroid, label = kmeans2(whitened, k=3) # kmeans2
    C1 = []; C2 = []; C3 = []; #Pour le stockage en cluster
    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])
    
    #Converti car le format numpy est plus facile à gérer
    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);
    
    #Nombre de données minoritaires pour chaque classe
    C1_Nmajo = sum(1*(C1_cv==0)); C2_Nmajo = sum(1*(C2_cv==0)); C3_Nmajo = sum(1*(C3_cv==0)) 
    
    #Nombre de données majoritaires pour chaque classe
    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

    #Il est possible que 0 apparaisse dans le dénominateur, alors ajoutez 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)
    
    #Supprimer les données pour que la majorité et la minorité soient les mêmes dans chaque groupe
    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 Ensuite, à propos du suréchantillonnage

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,:]
        
        #Implémentation de 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: #Si vous n'avez pas atteint le nombre de voisins attendu, ajoutez-le à la liste sans poser de questions
                        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   

Impressions de l'expérience

Je me demande si les approches au niveau des algorithmes sont plus robustes aux données sales que les approches au niveau des données. Peut-être que le code est faux. .. .. Veuillez indiquer s'il y a des lacunes m (_ _) m

Résumé

Étant donné que le traitement par lots est la cible des approches au niveau des données et qu'il existe une forte possibilité que le nombre de calculs augmente, j'ai estimé qu'il serait plus pratique de faire des ajustements avec des approches au niveau de l'algorithme. Avec les approches au niveau de l'algorithme, vous n'avez qu'à augmenter le coût et le gradient de l'ajustement de poids dans l'échantillon de données minoritaires, il n'y a donc pratiquement aucun effet sur le temps de calcul. .. Si vous avez d'autres bons moyens de traiter les données déséquilibrées, veuillez commenter.

Recommended Posts

Échantillonnage dans des données déséquilibrées
Gérer les données ambiantes en Python
Manipuler des données en Python-essayez avec Pandas_plyr
Afficher les données UTM-30LX en Python
Écrire des données au format HDF
Prédiction de probabilité de données déséquilibrées
Prétraitement dans l'apprentissage automatique 3 Données de valeur manquante / aberrante / de déséquilibre
Obtenez des données LeapMotion en Python.
Exporter les données DB au format json
Lire les données des tampons de protocole avec Python3
Obtenir des données de Quandl en Python
Gérez les données au format NetCDF avec Python
Comment gérer les données déséquilibrées
Visualisation des données avec Python - dessinons une carte de chaleur fraîche
Stocker les données RSS dans Zabbix (expéditeur Zabbix)
Essayez de mettre des données dans MongoDB
Concours de prédiction de données en 3 étapes (titanesque)
Hashing de données en R et Python
Apprentissage automatique dans Delemas (acquisition de données)
Vérifiez le résumé des données dans CASTable
Prétraitement dans l'apprentissage automatique 2 Acquisition de données
Prétraitement dans l'apprentissage automatique 4 Conversion de données
Python: prétraitement en machine learning: gestion des données manquantes / aberrantes / déséquilibrées
Afficher l'image après l'augmentation des données avec PyTorch
Entrée / sortie de données en Python (CSV, JSON)
Livre Ali en python: Sec.2-4, structure de données
Essayez de travailler avec des données binaires en Python
Sklearn de données déséquilibrées avec apprentissage automatique k-NN
Windows → Linux Conseils pour importer des données
Obtenez les données de l'API Google Fit en Python
Génération de données factices en forme de vent dans le processus de Markov
Python: prétraitement en machine learning: acquisition de données
Obtenez des données Youtube en Python à l'aide de l'API Youtube Data
J'ai essayé de sauvegarder les données récupérées au format CSV!
Stocker les données RSS dans Zabbix (vérification externe)
Représentez facilement des données graphiques dans le shell et Python
Séparation de la conception et des données dans matplotlib
Conversion des données de temps en notation 25 heures
Les données RDS via la plate-forme pas à pas sont envoyées aux Pandas
Python: prétraitement dans l'apprentissage automatique: conversion de données
Gacha écrit en python-Implémentation dans la structure de données de base-
Écraser les données dans RDS avec AWS Glue
Prétraitement dans l'apprentissage automatique 1 Processus d'analyse des données
SELECT des données à l'aide de la bibliothèque cliente avec BigQuery
Gérez les structures de données 3D avec les pandas
Livres sur la science des données à lire en 2020