J'ai un ensemble de données avec environ 130000 enregistrements. Les enregistrements divisés en deux classes de variables cibles, 0 et 1. 1 ne contiennent que 0,09% de la proportion totale.
J'exécute mon analyse dans R-3.5.1 sur Windows 10. J'ai utilisé l'algorithme SMOTE pour travailler avec cela ensemble de données déséquilibré.
J'ai utilisé le code suivant pour gérer l'ensemble de données déséquilibré
library(DMwR) data_code$target=as.factor(data_code$target) #Converted to factor as # SMOTE works with factor data type smoted_data <- SMOTE(target~., data_code, perc.over=100)
Mais après avoir exécuté le code, je vois que le nombre de 0 est 212 & 1 est également 212, ce qui représente une réduction significative de la taille de mon échantillon.Pouvez-vous me suggérer comment gérer cet ensemble de données déséquilibré avec SMOTE sans changer la taille de mes données
3 Réponses :
Il faut jouer un peu avec les deux paramètres disponibles à partir de la fonction: perc.over
et perc.under
.
Selon le doc de SMOTE
: p >
Les paramètres perc.over et perc.under contrôlent la quantité de suréchantillonnage de la classe minoritaire et sous-échantillonnage de la majorité classes, respectivement.
So:
perc.over sera généralement un nombre supérieur à 100. Avec ce type de valeurs, pour chaque cas de l'ensemble de données d'origine appartenant au classe minoritaire, perc. sur / 100 nouveaux exemples de cette classe seront créé
Je ne peux pas voir vos données mais, si votre classe minoritaire a 100 cas et perc.over = 100
, l'algorithme générera 100/100 = 1 nouveaux cas à partir de cela classe.
Le paramètre perc.under contrôle la proportion d'observations du classe majoritaire qui sera choisie au hasard pour la finale "équilibrée" base de données. Cette proportion est calculée par rapport au nombre de cas de classe minoritaire nouvellement générés.
Ainsi, par exemple, une valeur de perc.under = 100
sélectionnera dans la classe majoritaire sur les données d'origine la même quantité d'observations qui a été générée pour la classe minoritaire.
Dans notre exemple, un seul nouveau cas a été généré, il en ajoutera un autre, résultant en un nouvel ensemble de données avec 2 observations.
Je suggère d'utiliser des valeurs supérieures à 100 pour perc.over
, et une valeur encore plus élevée pour perc.under
(les valeurs par défaut sont 100 et 200).
Gardez à l'esprit que vous ajoutez de nouvelles observations qui ne sont pas réels dans votre classe minoritaire, j'essaierais de les garder sous contrôle.
Exemple numérique:
set.seed(123) data <- data.frame(var1 = sample(50), var2 = sample(50), out = as.factor(rbinom(50, 1, prob=0.1))) table(data$out) # 0 1 # 43 7 # 50 rows total (original data) smote_data <- DMwR::SMOTE(out ~ var1, data, perc.over = 200, perc.under = 400) table(smote_data$out) # 0 1 # 56 21 # 77 rows total (smote data)
p >
très belle explication. Merci beaucoup
Une alternative au package DMwR
est le package smotefamily
qui ne réduit pas la taille de l'échantillon.
Au lieu de cela, il crée des data (= données synthétisées) de la classe minoritaire et l'ajoute aux données d'origine. Ainsi, la sortie de l'argument $ data
est prête pour l'entraînement. Pour régler la quantité de données synthétisées, vous pouvez modifier le paramètre dup_size
. Cependant, la valeur par défaut dup_size = 0
optimise déjà la sortie pour obtenir des classes équilibrées, vous n'avez donc pas besoin de la régler.
Ceci est largement expliqué dans ce article de blog de Richard Richard.
Exemple de code (avec des fonctionnalités dans les deux premières colonnes):
smote1 <- smotefamily::SMOTE(features, target, K = 4, dup_size = 0) formula1 <- "class ~ ." %>% as.formula model.smote <- caret::train(formula1, method = "rpart", smote1$data) predictions.smote <- predict(model.smote, smote1$data[,1:2]) %>% print cv2 <- confusionMatrix(smote1$data$class %>% as.factor, predictions.smote)
Je trouve la smotefamily :: SMOTE
plus pratique car vous n'avez pas à régler les deux paramètres perc_over
et perc_under
jusqu'à ce que vous obteniez une taille d'échantillon acceptable et que DMwR :: SMOTE
génère souvent des valeurs NA.
Je sais que je suis un peu trop tard pour répondre à votre question, mais j'espère que cette réponse aidera les autres! Le package que vous utilisez est DMwR
qui utilise une combinaison de SMOTE et sous- échantillonnage de la classe majoritaire .
Je vous suggère d'utiliser smotefamily :: SMOTE
car il échantillonne uniquement la classe minoritaire, afin de ne pas perdre vos observations de classe majoritaire.
Veuillez donner un exemple de code reproduisant votre problème, afin que les gens puissent essayer de proposer une solution. Voir stackoverflow.com/help/mcve
Salut @denis, j'ai déjà donné le code que j'utilise dans mon message. Que voulez-vous d'autre?
Ce que les gens veulent, comme décrit en détail dans le lien que j'ai donné, ce sont des exemples de données. Si je copie-collez votre code, je n'obtiendrai rien car je ne connais pas
data_code
. Si je propose une solution, je ne peux pas la tester. Je devrais créer moi-même un exemple, mais c'est censé faire partie de votre travail ici. Créez un faux ensemble dedata_code
qui reproduit le problème et postez-le dans votre question (évitez les liens externes).Désolé, je ne peux pas partager avec vous le data_code car il contient des données client.
Encore une fois, je ne vous demande / nous ne vous demandons pas de partager l'ensemble de données: créez un faux ensemble de données qui reproduit votre problème.