Come accennato, l'AUC è una statistica di rango (cioè invariante di scala) e la perdita di log è una statistica di calibrazione. Uno può banalmente costruire un modello che ha lo stesso AUC ma non riesce a minimizzare la perdita di log rispetto ad altri modelli ridimensionando i valori previsti. Prendere in considerazione:
auc <- function(prediction, actual) {
mann_whit <- wilcox.test(prediction~actual)$statistic
1 - mann_whit / (sum(actual)*as.double(sum(!actual)))
}
log_loss <- function (prediction, actual) {
-1/length(prediction) * sum(actual * log(prediction) + (1-actual) * log(1-prediction))
}
sampled_data <- function(effect_size, positive_prior = .03, n_obs = 5e3) {
y <- rbinom(n_obs, size = 1, prob = positive_prior)
data.frame( y = y,
x1 =rnorm(n_obs, mean = ifelse(y==1, effect_size, 0)))
}
train_data <- sampled_data(4)
m1 <- glm(y~x1, data = train_data, family = 'binomial')
m2 <- m1
m2$coefficients[2] <- 2 * m2$coefficients[2]
m1_predictions <- predict(m1, newdata = train_data, type= 'response')
m2_predictions <- predict(m2, newdata = train_data, type= 'response')
auc(m1_predictions, train_data$y)
#0.9925867
auc(m2_predictions, train_data$y)
#0.9925867
log_loss(m1_predictions, train_data$y)
#0.01985058
log_loss(m2_predictions, train_data$y)
#0.2355433
Quindi, non possiamo dire che un modello che massimizza l'AUC significhi una perdita di log ridotta al minimo. Se un modello che minimizza la perdita di log corrisponde all'AUC massimizzata dipenderà fortemente dal contesto; separabilità della classe, distorsione del modello, ecc. In pratica, si potrebbe considerare una relazione debole, ma in generale si tratta semplicemente di obiettivi diversi. Considera l'esempio seguente che aumenta la separabilità della classe (dimensione dell'effetto del nostro predittore):
for (effect_size in 1:7) {
results <- dplyr::bind_rows(lapply(1:100, function(trial) {
train_data <- sampled_data(effect_size)
m <- glm(y~x1, data = train_data, family = 'binomial')
predictions <- predict(m, type = 'response')
list(auc = auc(predictions, train_data$y),
log_loss = log_loss(predictions, train_data$y),
effect_size = effect_size)
}))
plot(results$auc, results$log_loss, main = paste("Effect size =", effect_size))
readline()
}