Comme vous le mentionnez, l'ASC est une statistique de rang (c'est-à-dire invariant d'échelle) et la perte de log est une statistique d'étalonnage. On peut construire trivialement un modèle qui a la même AUC mais ne parvient pas à minimiser la perte de journal par rapport à un autre modèle en mettant à l'échelle les valeurs prédites. Considérer:
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
Donc, nous ne pouvons pas dire qu'un modèle maximisant l'AUC signifie une perte de journal minimisée. La question de savoir si un modèle minimisant la perte de log correspond à l'ASC maximisée dépendra fortement du contexte; séparabilité des classes, biais de modèle, etc. En pratique, on peut considérer une relation faible, mais en général ce sont simplement des objectifs différents. Prenons l'exemple suivant qui augmente la séparabilité des classes (taille d'effet de notre prédicteur):
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()
}