È corretto valutare i singoli conducenti con il valore AUC?
Ho una discussione con il mio supervisore sull'uso dell'AUC per determinare, fondamentalmente, l'importanza di tre diversi driver costituiti da più variabili ciascuno. Afferma che posso esaminare il valore AUC per il modello complessivo e quindi provare a eseguire un modello simile utilizzando solo un driver alla volta, ottenere il valore AUC per ciascun driver e valutare l'importanza di ciascun driver.
Inherent driver: 2 variables
Static driver: 2 variables
Dynamic driver: 7 variables
Quindi il mio output AUC da un modello ElasticNet binario sarebbe il seguente:
Overall AUC score (all drivers included): 0.89
Quindi eseguo lo stesso modello ElasticNet ma solo con le mie due variabili selezionate nella inherent driver
e nella variabile dipendente. E così via con i driver successivi ecc. ecc. I valori AUC sono i seguenti:
Inherent driver: 0.58
Static driver: 0.67
Dynamic driver: 0.88
- Il risultato quindi mi dice che
dynamic driver
sono relativamente più importanti o semplicemente migliori nel distinguere 0 da 1? - È anche un metodo statisticamente valido? Se no come posso valutarlo?
MODIFICARE:
V1 dependent V2 V3 V4 V5 V6 V7 V8 V9 V10 V11
1 -1.3 0 494. 34.1 2.23 43.0 4.58 46.7 283. 0.442 34.5 0
2 -4.2 0 231. 16.9 1.01 69.4 0 66.4 277. 0.959 11.1 0
3 -11.7 0 646. 132. 20.5 88.0 0.063 34.0 291. 5.63 21 0
4 -9.3 0 44.0 16.4 0.397 39.1 2.37 77.6 279. 7.24 31.8 0
5 -14.2 0 88.2 128. 40.6 83.4 1.09 47.2 284. 8.23 2.92 0
6 19.4 0 382. 49.4 1.15 54.4 0.914 53.6 279. 3.03 16.8 1
df <- df %>% select(V1, dependent, V2, V3, V4, V5, V6, V7, V8, V9, V11, V12)
training.samples <- df$dependent %>% createDataPartition(p = 0.8, list = FALSE)
train <- df[training.samples, ]
test <- df[-training.samples, ]
x.train <- data.frame(train[, names(train) != "dependent"])
x.train <- data.matrix(x.train)
y.train <- train$dependent
x.test <- data.frame(test[, names(test) != "dependent"])
x.test <- data.matrix(x.test)
y.test <- test$dependent
list.of.fits.overall.model <- list()
for (i in 0:10){
fit.name <- paste0("alpha", i/10)
list.of.fits.overall.model[[fit.name]] <- cv.glmnet(x.train, y.train, type.measure = c("auc"), alpha = i/10, family = "binomial", nfolds = 10, foldid = foldid, parallel = TRUE)
}
predicted <- predict(list.of.fits.overall.model[[fit.name]], s = list.of.fits.overall.model[[fit.name]]$lambda.1se, newx = x.test, type = "response")
#PLOT AUC
pred <- prediction(predicted, y.test)
perf <- performance(pred, "tpr", "fpr")
plot(perf)
abline(a = 0, b = 1, lty = 2, col = "red")
auc_ROCR <- performance(pred, measure = "auc")
auc_ROCR <- [email protected][[1]]
auc_ROCR
Ora ripeto l'intera procedura di modellazione della rete elastica (ricerca del compromesso cresta/lazo ottimale e valore di penalità ottimale) con solo due variabili. Fondamentalmente, modifico quanto segue:
df.inherent <- df %>% select(V1, dependent, V2)
training.samples <- df.inherent$dependent %>% createDataPartition(p = 0.8, list = FALSE)
train <- df.inherent[training.samples, ]
test <- df.inherent[-training.samples, ]
x.train <- data.frame(train[, names(train) != "dependent"])
x.train <- data.matrix(x.train)
y.train <- train$dependent
x.test <- data.frame(test[, names(test) != "dependent"])
x.test <- data.matrix(x.test)
y.test <- test$dependent
list.of.fits.inherent <- list()
for (i in 0:10){
fit.name <- paste0("alpha", i/10)
list.of.fits.inherent[[fit.name]] <- cv.glmnet(x.train, y.train, type.measure = c("auc"), alpha = i/10, family = "binomial", nfolds = 10, foldid = foldid, parallel = TRUE)
}
predicted <- predict(list.of.fits.inherent[[fit.name]], s = list.of.fits.inherent[[fit.name]]$lambda.1se, newx = x.test, type = "response")
Quindi, alla fine, l'ultima cosa che @EDM ha messo in discussione nei commenti.
Risposte
Dato che la penalizzazione è importante per la tua modellazione, sei potenzialmente su una buona strada ma devi incorporare informazioni sul potenziale errore nella tua metrica di qualità dell'AUC. Non è possibile confrontare un AUC di 0,58 con uno di 0,67 a meno che non si sappia quanto variabili potrebbero essere tali stime.
A simple way to handle this would be to repeat the process with multiple (say several hundred) test/train splits instead of a single one as you currently perform. Single test/train splits can be unreliable with data sets having anything below several thousand cases. (As you would probably need fewer than 200 cases in the minority class to fit an unpenalized model with 11 predictors reliably, I assume that you don't have several thousand cases and thus should be doing more resampling in any event.) Then you use the variability among the (several hundred) test-set AUC values to gauge whether or not any differences among the predictor subsets are statistically reliable.
Potresti stare meglio con un approccio simile basato sul bootstrap invece delle molteplici divisioni di test/train. Per prima cosa utilizzi tutti i dati per adattare un modello completo. In questo modo ottieni un modello completo che, a differenza del tuo approccio, utilizza tutti i dati disponibili per costruire e non dipende dai capricci di una particolare divisione test/treno.
Quindi ripeti l'intero processo di modellazione (inclusa la scelta alpha
e lambda
tramite la convalida incrociata interna) su alcune centinaia di campioni bootstrap del set di dati e utilizzi l'intero set di dati come set di test in ogni caso. In base al principio bootstrap che è analogo alla creazione di modelli su più campioni dell'intera popolazione di interesse e quindi al loro test sulla popolazione. Si ottiene così una stima ragionevole della qualità del processo di modellazione: ottimismo (overfitting) nei valori dei coefficienti e distorsione e variabilità nelle stime della misura della qualità.
In termini di modellazione, anche se scegli di utilizzare l'AUC come misura finale, dovresti utilizzare la devianza anziché l'AUC come criterio per la scelta della convalida incrociata di alpha
e lambda
. L'AUC (o C-index) non è molto sensibile per distinguere i modelli. Inoltre, pensa attentamente se lambda.1se
è una buona scelta in questo caso. Ciò aiuta a ottenere un modello parsimonioso, ma con così pochi predittori con cui iniziare (solo 2 nel tuo secondo esempio) potresti stare molto meglio con il lambda.min
valore che minimizza l'errore di convalida incrociata (di nuovo, è meglio farlo con la devianza anche se il tuo finale la valutazione deve essere fatta con l'UAC).