library(ROSE)
## Loaded ROSE 0.0-4
library(caTools)
library(rpart)
library(caret)
## Loading required package: ggplot2
## Loading required package: lattice
#1. Un esempio con dati simulati Tratto dal package
ROSE
Si tratta di dati simulati che possono essere usati per illustrare l’effetto delle varie procedure di sovracampionamento della calsse rara, sottocampionamento della classe prevalente e generazione di dati sintetici.
I dati sono relativi a due classi rappresenatbili la prima come una sfera e la seconda come una semisfera svuotata che è collocata attorno alla prima.
Diamoci un’occhiata.
data(hacide)
table(hacide.train$cls)
##
## 0 1
## 980 20
plot(hacide.train$x1,hacide.train$x2,col=hacide.train$cls, pch=20)
Come primo passo proviamo a utilizzare un albero per prevedere la classe usando le due variabili continue. I dati sono giĂ suddivisi in training set e test set.
Utilizziamo alcune funzioni di ROSE per valutare la qualitĂ del classificatore.
Prima vediamo come funziona il calssificatore con dati sbilanciati.
treeimb <- rpart(cls ~ ., data = hacide.train)
pred.treeimb <- predict(treeimb, newdata = hacide.test)
accuracy.meas(hacide.test$cls, pred.treeimb[,2])
##
## Call:
## accuracy.meas(response = hacide.test$cls, predicted = pred.treeimb[,
## 2])
##
## Examples are labelled as positive when predicted is greater than 0.5
##
## precision: 1.000
## recall: 0.200
## F: 0.167
roc.curve(hacide.test$cls, pred.treeimb[,2], plotit = FALSE)
## Area under the curve (AUC): 0.600
Proviamo ora a vedere cos?samplea accade se bilanciamo il campione sovracampionando la classe rara o sottocampionando la prevalente
data.bal.ov <- ovun.sample(cls ~ ., data = hacide.train, method = "over",
p = 0.5, seed = 1)$data
table(data.bal.ov$cls)
##
## 0 1
## 980 941
###undersampling (selezione casuale)
data.bal.un <- ovun.sample(cls ~ ., data = hacide.train, method = "under",
p = 0.5, seed = 1)$data
table(data.bal.un$cls)
##
## 0 1
## 19 20
plot(data.bal.un$x1,data.bal.un$x2,col=data.bal.un$cls, pch=20)
#entrambe le cose
data.bal.ou <- ovun.sample(cls ~ ., data = hacide.train, method = "both",
N = 1000, p = 0.5, seed = 1)$data
table(data.bal.ou$cls)
##
## 0 1
## 520 480
data.rose <- ROSE(cls ~ ., data = hacide.train, seed = 1)$data
table(data.rose$cls)
##
## 0 1
## 520 480
plot(data.rose$x1,data.rose$x2,col=data.rose$cls, pch=20)
tree.rose <- rpart(cls ~ ., data = data.rose)
tree.ov <- rpart(cls ~ ., data = data.bal.ov)
tree.un <- rpart(cls ~ ., data = data.bal.un)
tree.ou <- rpart(cls ~ ., data = data.bal.ou)
pred.tree.rose <- predict(tree.rose, newdata = hacide.test)
pred.tree.ov <- predict(tree.ov, newdata = hacide.test)
pred.tree.un <- predict(tree.un, newdata = hacide.test)
pred.tree.ou <- predict(tree.un, newdata = hacide.test)
roc.curve(hacide.test$cls, pred.tree.rose[,2])
## Area under the curve (AUC): 0.993
roc.curve(hacide.test$cls, pred.tree.ov[,2], add.roc = TRUE, col = 2, lty = 2)
## Area under the curve (AUC): 0.798
roc.curve(hacide.test$cls, pred.tree.un[,2], add.roc = TRUE, col = 3, lty = 3)
## Area under the curve (AUC): 0.833
roc.curve(hacide.test$cls, pred.tree.ou[,2], add.roc = TRUE, col = 4, lty = 4)
## Area under the curve (AUC): 0.833
In R esistono vari pacchetti (ad esempio nella vecchia versione del pacchetto DMwR o nel pacchetto smotefamily)
library(smotefamily)
data.smote<-SMOTE(X=hacide.train[,-1],target=hacide.train[,1])
data.sm<-data.smote$data
plot(data.sm$x1,data.sm$x2,col=(as.numeric(data.sm$class)+1), pch=20)
tree.smote <- rpart(class ~ ., data = data.sm)
pred.tree.smote <- predict(tree.smote, newdata = hacide.test)
roc.curve(hacide.test$cls, pred.tree.smote[,2])
## Area under the curve (AUC): 0.970