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
Veuillez consulter l'article pour plus de détails car il est vraiment correctement résumé. ..
- 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.
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
En regardant la formule, cela ressemble à ce qui suit.
- 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
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
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
É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