Wie Sie bereits erwähnt haben, ist die AUC eine Rangstatistik (dh eine Skaleninvariante) und der Protokollverlust eine Kalibrierungsstatistik. Man kann trivial ein Modell konstruieren, das dieselbe AUC hat, aber den Protokollverlust gegenüber einem anderen Modell nicht minimiert, indem man die vorhergesagten Werte skaliert. Erwägen:
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
Wir können also nicht sagen, dass ein Modell, das die AUC maximiert, einen minimierten Protokollverlust bedeutet. Ob ein Modell zur Minimierung des Protokollverlusts einer maximierten AUC entspricht, hängt stark vom Kontext ab. Klassentrennbarkeit, Modellbias usw. In der Praxis könnte man eine schwache Beziehung in Betracht ziehen, aber im Allgemeinen handelt es sich einfach um unterschiedliche Ziele. Betrachten Sie das folgende Beispiel, das die Klassentrennbarkeit erhöht (Effektgröße unseres Prädiktors):
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()
}