tEs de fundamental importancia probar y comparar modelos de aprendizaje automático comparando sus predicciones en un conjunto de pruebas, incluso después de su implementación. Para hacer esto, es necesario pensar en una medida o puntaje que toma una predicción y un punto de prueba y asigna un valor que mide el éxito de la predicción con respecto al punto de prueba. Sin embargo, se debe pensar detenidamente qué medida de puntuación es apropiada. En particular, al elegir un método para evaluar una predicción debemos adherirnos a la idea de reglas de puntuación adecuadas. Aquí solo doy una definición vaga de esta idea, pero básicamente, ¡queremos una puntuación que se minimice en lo que queremos medir!
Como una regla general: se puede usar MSE para evaluar predicciones medias, MAE para evaluar predicciones medianas, la puntuación cuantil para evaluar predicciones cuantiles más generales y la puntuación de energía o MMD para evaluar predicciones distributivas.
Considere una variable que desea predecir, digamos una variable aleatoria Ya partir de un vector de covariables x. En el siguiente ejemplo, Y serán ingresos y x Habrá ciertas características, como edad y educación. Aprendimos un predictor F en algunos datos de entrenamiento y ahora predecimos Y como F(x). Generalmente, cuando queremos predecir una variable Y lo mejor posible predecimos la expectativa de y dado xes decir F(x) debe aproximarse E(Y | x=x). Pero de manera más general, F(x) podría ser un estimador de la mediana, otros cuantiles o incluso la distribución condicional completa P(Y | x=x).
Ahora para un nuevo punto de prueba yqueremos calificar tu predicción, es decir, quieres una función S(y,f(x))eso es minimizado (a la espera) cuando F(x) es lo mejor que puedes hacer. Por ejemplo, si queremos predecir E(Y | x=x)esta puntuación se da como MSE: S(y,f(x))= (yf(x))².
Aquí estudiamos el principio de puntuación del predictor. F en el conjunto de pruebas de (y_i,x_i), i=1,…,prueba con más detalle. En todos los ejemplos compararemos el método de estimación ideal con otro que es claramente incorrecto o ingenuo y mostraremos que nuestras puntuaciones hacen lo que se supone que deben hacer.
El ejemplo
Para ilustrar las cosas, simularé un conjunto de datos simple que debería imitar los datos de ingresos. Usaremos este ejemplo simple a lo largo de este artículo para ilustrar los conceptos.
library(dplyr)#Create some variables:
# Simulate data for 100 individuals
n <- 5000
# Generate age between 20 and 60
age <- round(runif(n, min = 20, max = 60))
# Define education levels
education_levels <- c("High School", "Bachelor's", "Master's")
# Simulate education level probabilities
education_probs <- c(0.4, 0.4, 0.2)
# Sample education level based on probabilities
education <- sample(education_levels, n, replace = TRUE, prob = education_probs)
# Simulate experience correlated with age with some random error
experience <- age - 20 + round(rnorm(n, mean = 0, sd = 3))
# Define a non-linear function for wage
wage <- exp((age * 0.1) + (case_when(education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2)) + (experience * 0.05) + rnorm(n, mean = 0, sd = 0.5))
hist(wage)
Aunque esta simulación puede estar demasiado simplificada, refleja ciertas características bien conocidas de dichos datos: la edad avanzada, la educación avanzada y la mayor experiencia están todos vinculados con salarios más altos. El uso del operador “exp” da como resultado una distribución salarial muy sesgada, lo cual es una observación constante en este tipo de conjuntos de datos.
Fundamentalmente, esta asimetría también está presente cuando fijamos la edad, la educación y la experiencia en ciertos valores. Imaginemos que miramos a una persona específica, Dave, que tiene 30 años, una Licenciatura en Economía y 10 años de experiencia y veamos su distribución real de ingresos de acuerdo con nuestro proceso de generación de datos:
ageDave<-30
educationDave<-"Bachelor's"
experienceDave <- 10wageDave <- exp((ageDave * 0.1) + (case_when(educationDave == "High School" ~ 1,
educationDave == "Bachelor's" ~ 1.5,
TRUE ~ 2)) + (experienceDave * 0.05) + rnorm(n, mean = 0, sd = 0.5))
hist(wageDave, main="Wage Distribution for Dave", xlab="Wage")
Por tanto, la distribución de los posibles salarios de Dave, dada la información que tenemos sobre él, sigue siendo muy sesgada.
También generamos un conjunto de prueba de varias personas:
## Generate test set
ntest<-1000# Generate age between 20 and 60
agetest <- round(runif(ntest, min = 20, max = 60))
# Sample education level based on probabilities
educationtest <- sample(education_levels, ntest, replace = TRUE, prob = education_probs)
# Simulate experience correlated with age with some random error
experiencetest <- agetest - 20 + round(rnorm(ntest, mean = 0, sd = 3))
## Generate ytest that we try to predict:
wagetest <- exp((agetest * 0.1) + (case_when(educationtest == "High School" ~ 1,
educationtest == "Bachelor's" ~ 1.5,
TRUE ~ 2)) + (experiencetest * 0.05) + rnorm(ntest, mean = 0, sd = 0.5))
Ahora comencemos de manera simple y primero observemos las puntuaciones de predicción de la media y la mediana.
Las puntuaciones para la predicción media y mediana.
En la ciencia de datos y el aprendizaje automático, el interés a menudo se centra en un solo número que significa el “centro” o “medio” de la distribución que pretendemos predecir, es decir, la media o mediana (condicional). Para ello tenemos el error cuadrático medio (MSE):
y el error absoluto medio (MAE):
Una conclusión importante es que el MSE es la métrica adecuada para predecir la media condicional, mientras que el MAE es la medida a utilizar para la mediana condicional. La media y la mediana no son lo mismo para distribuciones asimétricas como la que estudiamos aquí.
Ilustremos esto en el ejemplo anterior con estimadores muy simples (a los que no tendríamos acceso en la vida real), solo a modo de ilustración:
conditionalmeanest <-
function(age, education, experience, N = 1000) {
mean(exp((age * 0.1) + (
case_when(
education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2
)
) + (experience * 0.05) + rnorm(N, mean = 0, sd = 0.5)
))
}conditionalmedianest <-
function(age, education, experience, N = 1000) {
median(exp((age * 0.1) + (
case_when(
education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2
)
) + (experience * 0.05) + rnorm(N, mean = 0, sd = 0.5)
))
}
Es decir, estimamos la media y la mediana simplemente simulando a partir del modelo para valores fijos de edad, educación y experiencia (esto sería una simulación de la distribución condicional correcta) y luego simplemente tomamos la media/mediana de eso. Probemos esto en Dave:
hist(wageDave, main="Wage Distribution for Dave", xlab="Wage")
abline(v=conditionalmeanest(ageDave, educationDave, experienceDave), col="darkred", cex=1.2)
abline(v=conditionalmedianest(ageDave, educationDave, experienceDave), col="darkblue", cex=1.2)
Es evidente que la media y la mediana son diferentes, como cabría esperar de tal distribución. De hecho, como es típico en las distribuciones del ingreso, la media es más alta (más influenciada por valores altos) que la mediana.
Ahora usemos estos estimadores en el conjunto de prueba:
Xtest<-data.frame(age=agetest, education=educationtest, experience=experiencetest)meanest<-sapply(1:nrow(Xtest), function(j) conditionalmeanest(Xtest$age(j), Xtest$education(j), Xtest$experience(j)) )
median<-sapply(1:nrow(Xtest), function(j) conditionalmedianest(Xtest$age(j), Xtest$education(j), Xtest$experience(j)) )
Esto proporciona una amplia gama de valores medios/medianos condicionales. Ahora calculamos MSE y MAE:
(MSE1<-mean((meanest-wagetest)^2))
(MSE2<-mean((median-wagetest)^2))MSE1 < MSE2
### Method 1 (the true mean estimator) is better than method 2!
# but the MAE is actually worse of method 1!
(MAE1<-mean(abs(meanest-wagetest)) )
(MAE2<-mean( abs(median-wagetest)))
MAE1 < MAE2
### Method 2 (the true median estimator) is better than method 1!
Esto muestra lo que se sabe teóricamente: MSE se minimiza para la expectativa (condicional) E(Y | x=x)mientras que MAE se minimiza en la mediana condicional. En general, no tiene sentido utilizar el MAE cuando intentas evaluar tu predicción media. En gran parte de la investigación aplicada y la ciencia de datos, la gente usa el MAE o ambos para evaluar las predicciones medias (lo sé porque lo hice yo mismo). Si bien esto puede estar justificado en ciertas aplicaciones, puede tener consecuencias graves para distribuciones que no son simétricas, como vimos en este ejemplo: Al observar el MAE, el método 1 parece peor que el método 2, aunque el primero estima la media correctamente. . De hecho, en este ejemplo tan sesgado, El método 1 debe tener un MAE más bajo que el método 2..
Para calificar la predicción de la media condicional, utilice el error cuadrático medio (MSE) y no el error medio absoluto (MAE). El MAE se minimiza para la mediana condicional.
Puntuaciones para predicción de cuantiles e intervalos
Supongamos que queremos obtener una estimación. F(x) del cuantil q_x tal que
En este caso, podemos considerar la puntuación cuantil:
por lo cual
Para descomprimir esta fórmula, podemos considerar dos casos:
(1) y es más pequeña que F(x):
es decir, incurrimos en una penalización que aumenta cuanto más nos alejamos y es desde F(x).
(2) y Es mas grande que F(x):
es decir, una penalización que aumenta cuanto más se aleja y es desde F(x).
Observe que el peso es tal que para un alto alfateniendo el cuantil estimado F(x) menor que y recibe más penalización. Esto es por diseño y garantiza que el cuantil correcto sea de hecho el minimizador del valor esperado de S(y,f(x)) sobre y. Esta puntuación es de hecho la pérdida cuantil (hasta un factor 2), consulte, por ejemplo, este bonito artículo. Se implementa en el puntuación_cuantil función del paquete útiles de puntuación en R. Finalmente, tenga en cuenta que para alfa=0,5:
simplemente el MAE! Esto tiene sentido, ya que el cuantil 0,5 es la mediana.
Con el poder de predecir cuantiles, también podemos construir intervalos de predicción. Considerar (l_xtu_x)dónde l_x ≤ tu_x son cuantiles tales que
De hecho, esto se cumple si l_x es el alfa/2 cuantil, y tu_x es el 1-alfa/2 cuantil. Por lo tanto, ahora estimamos y calificamos estos dos cuantiles. Considerar F(x)=(f_1(x), f_2(x))por lo que f_1(x) ser una estimación de l_x y f_2(x) una estimación de tu_x. Proporcionamos dos estimadores, uno “ideal” que simula nuevamente el proceso real para luego estimar los cuantiles requeridos y uno “ingenuo”, que tiene la cobertura correcta pero es demasiado grande:
library(scoringutils)## Define conditional quantile estimation
conditionalquantileest <-
function(probs, age, education, experience, N = 1000) {
quantile(exp((age * 0.1) + (
case_when(
education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2
)
) + (experience * 0.05) + rnorm(N, mean = 0, sd = 0.5)
)
, probs =
probs)
}
## Define a very naive estimator that will still have the required coverage
lowernaive <- 0
uppernaive <- max(wage)
# Define the quantile of interest
alpha <- 0.05
lower <-
sapply(1:nrow(Xtest), function(j)
conditionalquantileest(alpha / 2, Xtest$age(j), Xtest$education(j), Xtest$experience(j)))
upper <-
sapply(1:nrow(Xtest), function(j)
conditionalquantileest(1 - alpha / 2, Xtest$age(j), Xtest$education(j), Xtest$experience(j)))
## Calculate the scores for both estimators
# 1. Score the alpha/2 quantile estimate
qs_lower <- mean(quantile_score(wagetest,
predictions = lower,
quantiles = alpha / 2))
# 2. Score the alpha/2 quantile estimate
qs_upper <- mean(quantile_score(wagetest,
predictions = upper,
quantiles = 1 - alpha / 2))
# 1. Score the alpha/2 quantile estimate
qs_lowernaive <- mean(quantile_score(wagetest,
predictions = rep(lowernaive, ntest),
quantiles = alpha / 2))
# 2. Score the alpha/2 quantile estimate
qs_uppernaive <- mean(quantile_score(wagetest,
predictions = rep(uppernaive, ntest),
quantiles = 1 - alpha / 2))
# Construct the interval score by taking the average
(interval_score <- (qs_lower + qs_upper) / 2)
# Score of the ideal estimator: 187.8337
# Construct the interval score by taking the average
(interval_scorenaive <- (qs_lowernaive + qs_uppernaive) / 2)
# Score of the naive estimator: 1451.464
Nuevamente podemos ver claramente que, en promedio, ¡el estimador correcto tiene una puntuación mucho más baja que el ingenuo!
Por lo tanto, con la puntuación cuantil, tenemos una forma confiable de calificar las predicciones cuantiles individuales. Sin embargo, la forma de promediar la puntuación de los cuantiles superior e inferior para el intervalo de predicción podría parecer ad hoc. Por suerte resulta que esto lleva al llamado puntuación de intervalo:
Así, mediante algo de magia algebraica, podemos puntuar un intervalo de predicción promediando las puntuaciones de los alfa/2 y el 1-alfa/2 cuantiles como lo hicimos nosotros. Curiosamente, la puntuación de intervalo resultante recompensa los intervalos de predicción estrechos e induce una penalización, cuyo tamaño depende de alfa, si la observación pierde el intervalo. En lugar de utilizar el promedio de puntuaciones cuantiles, también podemos calcular directamente esta puntuación con el paquete puntuaciónutils.
alpha <- 0.05
mean(interval_score(
wagetest,
lower=lower,
upper=upper,
interval_range=(1-alpha)*100,
weigh = T,
separate_results = FALSE
))
#Score of the ideal estimator: 187.8337
Este es exactamente el mismo número que obtuvimos arriba al promediar las puntuaciones de los dos intervalos.
La puntuación cuantil implementada en R en el paquete scoringutils se puede utilizar para puntuar predicciones cuantiles. Si se quiere puntuar un intervalo de predicción directamente, se puede utilizar la función intervalo_score.
Puntuaciones para la predicción distributiva
Cada vez más campos tienen que lidiar con predicción distribucional. Por suerte, incluso hay puntuaciones para este problema. En particular, aquí me centro en lo que se llama puntuación de energía:
para F(x) siendo una estimación de la distribución P(Y | x=x). El segundo término toma la expectativa de la distancia euclidiana entre dos muestras independientes de F(x). Esto es similar a un término de normalización, que establece el valor si se compara la misma distribución. El primer término luego compara el punto muestral. y a un empate x de F(x). En expectativa (más Y trazada desde P(Y | x=x)) Esto se minimizará si F(x)=P(Y | x=x).
Así, en lugar de limitarnos a predecir la media o los cuantiles, ahora intentamos predecir la distribución completa del salario en cada punto de prueba. Básicamente, intentamos predecir y evaluar la distribución condicional que trazamos anteriormente para Dave. Esto es un poco más complicado; ¿Cómo representamos exactamente una distribución aprendida? En la práctica, esto se resuelve asumiendo que podemos obtener una muestra de la distribución prevista. Así comparamos una muestra de norte, obtenido a partir de la distribución prevista, a un único punto de prueba. Esto se puede hacer en R usando es_sample desde el puntuaciónReglas paquete:
library(scoringRules)## Ideal "estimate": Simply sample from the true conditional distribution
## P(Y | x=x) for each sample point x
distributionestimate <-
function(age, education, experience, N = 100) {
exp((age * 0.1) + (
case_when(
education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2
)
) + (experience * 0.05) + rnorm(N, mean = 0, sd = 0.5))
}
## Naive Estimate: Only sample from the error distribution, without including the
## information of each person.
distributionestimatenaive <-
function(age, education, experience, N = 100) {
exp(rnorm(N, mean = 0, sd = 0.5))
}
scoretrue <- mean(sapply(1:nrow(Xtest), function(j) {
wageest <-
distributionestimate(Xtest$age(j), Xtest$education(j), Xtest$experience(j))
return(scoringRules::es_sample(y = wagetest(j), dat = matrix(wageest, nrow=1)))
}))
scorenaive <- mean(sapply(1:nrow(Xtest), function(j) {
wageest <-
distributionestimatenaive(Xtest$age(j), Xtest$education(j), Xtest$experience(j))
return(scoringRules::es_sample(y = wagetest(j), dat = matrix(wageest, nrow=1)))
}))
## scoretrue: 761.026
## scorenaive: 2624.713
En el código anterior, comparamos nuevamente la estimación “perfecta” (es decir, muestreo de la distribución verdadera P(Y | x=x)) a uno muy ingenuo, es decir, uno que no considera ninguna información sobre salario, educación o experiencia. Nuevamente, la puntuación identifica de manera confiable el mejor de los dos métodos.
La puntuación de energía, implementada en el paquete R scoringRules, se puede utilizar para puntuar la predicción distributiva, si hay disponible una muestra de la distribución predicha.
Conclusión
Hemos analizado diferentes formas de puntuar las predicciones. Es importante pensar en la medida correcta para probar las predicciones, ya que una medida incorrecta podría hacernos elegir y mantener el modelo incorrecto para nuestra tarea de predicción.
Cabe señalar que, especialmente para la predicción distributiva, esta puntuación es una tarea difícil y es posible que la puntuación no tenga mucho poder en la práctica. Es decir, incluso un método que conduzca a una gran mejora podría tener sólo una puntuación ligeramente menor. Sin embargo, esto no es un problema per se, siempre y cuando la puntuación sea capaz de identificar de forma fiable el mejor de los dos métodos.
Referencias
(1) Tilmann Gneiting y Adrian E Raftery (2007) Reglas de puntuación, predicción y estimación estrictamente adecuadas, Revista de la Asociación Estadounidense de Estadística, 102:477, 359–378, DOI: 10.1198/016214506000001437
Apéndice: Todo el código en un solo lugar
library(dplyr)#Create some variables:
# Simulate data for 100 individuals
n <- 5000
# Generate age between 20 and 60
age <- round(runif(n, min = 20, max = 60))
# Define education levels
education_levels <- c("High School", "Bachelor's", "Master's")
# Simulate education level probabilities
education_probs <- c(0.4, 0.4, 0.2)
# Sample education level based on probabilities
education <- sample(education_levels, n, replace = TRUE, prob = education_probs)
# Simulate experience correlated with age with some random error
experience <- age - 20 + round(rnorm(n, mean = 0, sd = 3))
# Define a non-linear function for wage
wage <- exp((age * 0.1) + (case_when(education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2)) + (experience * 0.05) + rnorm(n, mean = 0, sd = 0.5))
hist(wage)
ageDave<-30
educationDave<-"Bachelor's"
experienceDave <- 10
wageDave <- exp((ageDave * 0.1) + (case_when(educationDave == "High School" ~ 1,
educationDave == "Bachelor's" ~ 1.5,
TRUE ~ 2)) + (experienceDave * 0.05) + rnorm(n, mean = 0, sd = 0.5))
hist(wageDave, main="Wage Distribution for Dave", xlab="Wage")
## Generate test set
ntest<-1000
# Generate age between 20 and 60
agetest <- round(runif(ntest, min = 20, max = 60))
# Sample education level based on probabilities
educationtest <- sample(education_levels, ntest, replace = TRUE, prob = education_probs)
# Simulate experience correlated with age with some random error
experiencetest <- agetest - 20 + round(rnorm(ntest, mean = 0, sd = 3))
## Generate ytest that we try to predict:
wagetest <- exp((agetest * 0.1) + (case_when(educationtest == "High School" ~ 1,
educationtest == "Bachelor's" ~ 1.5,
TRUE ~ 2)) + (experiencetest * 0.05) + rnorm(ntest, mean = 0, sd = 0.5))
conditionalmeanest <-
function(age, education, experience, N = 1000) {
mean(exp((age * 0.1) + (
case_when(
education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2
)
) + (experience * 0.05) + rnorm(N, mean = 0, sd = 0.5)
))
}
conditionalmedianest <-
function(age, education, experience, N = 1000) {
median(exp((age * 0.1) + (
case_when(
education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2
)
) + (experience * 0.05) + rnorm(N, mean = 0, sd = 0.5)
))
}
hist(wageDave, main="Wage Distribution for Dave", xlab="Wage")
abline(v=conditionalmeanest(ageDave, educationDave, experienceDave), col="darkred", cex=1.2)
abline(v=conditionalmedianest(ageDave, educationDave, experienceDave), col="darkblue", cex=1.2)
Xtest<-data.frame(age=agetest, education=educationtest, experience=experiencetest)
meanest<-sapply(1:nrow(Xtest), function(j) conditionalmeanest(Xtest$age(j), Xtest$education(j), Xtest$experience(j)) )
median<-sapply(1:nrow(Xtest), function(j) conditionalmedianest(Xtest$age(j), Xtest$education(j), Xtest$experience(j)) )
(MSE1<-mean((meanest-wagetest)^2))
(MSE2<-mean((median-wagetest)^2))
MSE1 < MSE2
### Method 1 (the true mean estimator) is better than method 2!
# but the MAE is actually worse of method 1!
(MAE1<-mean(abs(meanest-wagetest)) )
(MAE2<-mean( abs(median-wagetest)))
MAE1 < MAE2
### Method 2 (the true median estimator) is better than method 1!
library(scoringutils)
## Define conditional quantile estimation
conditionalquantileest <-
function(probs, age, education, experience, N = 1000) {
quantile(exp((age * 0.1) + (
case_when(
education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2
)
) + (experience * 0.05) + rnorm(N, mean = 0, sd = 0.5)
)
, probs =
probs)
}
## Define a very naive estimator that will still have the required coverage
lowernaive <- 0
uppernaive <- max(wage)
# Define the quantile of interest
alpha <- 0.05
lower <-
sapply(1:nrow(Xtest), function(j)
conditionalquantileest(alpha / 2, Xtest$age(j), Xtest$education(j), Xtest$experience(j)))
upper <-
sapply(1:nrow(Xtest), function(j)
conditionalquantileest(1 - alpha / 2, Xtest$age(j), Xtest$education(j), Xtest$experience(j)))
## Calculate the scores for both estimators
# 1. Score the alpha/2 quantile estimate
qs_lower <- mean(quantile_score(wagetest,
predictions = lower,
quantiles = alpha / 2))
# 2. Score the alpha/2 quantile estimate
qs_upper <- mean(quantile_score(wagetest,
predictions = upper,
quantiles = 1 - alpha / 2))
# 1. Score the alpha/2 quantile estimate
qs_lowernaive <- mean(quantile_score(wagetest,
predictions = rep(lowernaive, ntest),
quantiles = alpha / 2))
# 2. Score the alpha/2 quantile estimate
qs_uppernaive <- mean(quantile_score(wagetest,
predictions = rep(uppernaive, ntest),
quantiles = 1 - alpha / 2))
# Construct the interval score by taking the average
(interval_score <- (qs_lower + qs_upper) / 2)
# Score of the ideal estimator: 187.8337
# Construct the interval score by taking the average
(interval_scorenaive <- (qs_lowernaive + qs_uppernaive) / 2)
# Score of the naive estimator: 1451.464
library(scoringRules)
## Ideal "estimate": Simply sample from the true conditional distribution
## P(Y | x=x) for each sample point x
distributionestimate <-
function(age, education, experience, N = 100) {
exp((age * 0.1) + (
case_when(
education == "High School" ~ 1,
education == "Bachelor's" ~ 1.5,
TRUE ~ 2
)
) + (experience * 0.05) + rnorm(N, mean = 0, sd = 0.5))
}
## Naive Estimate: Only sample from the error distribution, without including the
## information of each person.
distributionestimatenaive <-
function(age, education, experience, N = 100) {
exp(rnorm(N, mean = 0, sd = 0.5))
}
scoretrue <- mean(sapply(1:nrow(Xtest), function(j) {
wageest <-
distributionestimate(Xtest$age(j), Xtest$education(j), Xtest$experience(j))
return(scoringRules::es_sample(y = wagetest(j), dat = matrix(wageest, nrow=1)))
}))
scorenaive <- mean(sapply(1:nrow(Xtest), function(j) {
wageest <-
distributionestimatenaive(Xtest$age(j), Xtest$education(j), Xtest$experience(j))
return(scoringRules::es_sample(y = wagetest(j), dat = matrix(wageest, nrow=1)))
}))
## scoretrue: 761.026
## scorenaive: 2624.713