我正在拟合贝叶斯模型来使用Brms
包预测考试成绩。我想知道如何使用LOO
包计算基于"留一交叉验证"(LOO)的"平均绝对误差",但我找不到任何与如何自己实现它相关的信息。
如果有人告诉我如何计算基于LOO的MAE,我将非常感激。
下面是一个可复制的示例代码:
set.seed(123) # for reproducibility
n <- 100 # number of observations
predictor_1 <- rnorm(n)
predictor_2 <- rnorm(n)
test_score <- 5 + 2*predictor_1 + 3*predictor_2 + rnorm(n)
data <- data.frame(test_score, predictor_1, predictor_2)
head(data)
fit <- brm(test_score ~ predictor_1 + predictor_2, data = data)
predicted_test_score <- predict(fit)
# calculate mean absolute error
mae <- mean(abs(predicted_test_score - data$test_score))
mae
功能brms::kfold_predict()
可用于此,并且在帮助文件中有一个易于适应的示例,参见?brms::kfold_predict()
。
执行LOOCV和保存fits(对象大小随着nobs快速增长!)
fit_LOO <- kfold(fit, save_fits = TRUE, chains = 1, folds = "loo")
从100个观测值中的每一个的后验预测分布中获得样本(默认为1000)。这将产生一个1000x100的矩阵。
predict_LOO <- kfold_predict(fit_LOO, method = "predict")
> dim(predict_LOO$yrep)
[1] 1000 100
定义并计算您期望的损失(基于后验均值):
MAE <- function(y, yrep) {
yrep_mean <- colMeans(yrep)
mean(abs(yrep_mean - y))
}
> MAE(y = predict_LOO$y, yrep = predict_LOO$yrep)
[1] 0.7846185
为了使用loo
包计算基于LOO
的MAE
,您需要使用brms
包中的brm
函数拟合贝叶斯模型,然后使用loo
函数执行left - out交叉验证。此外,您还需要从brmsfit
对象中提取点向对数似然矩阵,并使用loo::loo_compare
函数计算期望的对数点向预测密度(ELPD)差异。最后,你必须计算LOO平均绝对误差。
if (!requireNamespace("brms", quietly = TRUE)) {
install.packages("brms")
}
library(brms)
if (!requireNamespace("loo", quietly = TRUE)) {
install.packages("loo")
}
library(loo)
fit <- brm(test_score ~ predictor_1 + predictor_2, data = data, save_all_pars = TRUE)
loo_fit <- loo(fit, save_psis = TRUE)
log_lik <- log_lik(fit)
elpd_diff <- loo::loo_compare(loo_fit, loo_fit)
loo_mae <- mean(abs(exp(elpd_diff$diff)))
print(loo_mae)