You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于gstat的cv.krige获取各折交叉验证的R²、RMSE、MAE统计值

解决留一法交叉验证cv.krige的指标统计问题

问题根源

你遇到的分位值完全一致的问题,是因为代码仅使用了留一法中**最后一个样本(最后一折)**的数据计算指标,而非所有折的结果。留一法交叉验证中,每个样本单独作为测试集,cv.krige返回的结果每行对应一个折的真实值(observed)和预测值(var1.pred),必须基于全量行数据计算统计汇总。

解决方案代码

以下代码严格使用gstat、Metrics包及自定义RSQUARE函数,实现所有折的指标统计:

# 加载依赖包
library(gstat)
library(Metrics)

# 自定义R²计算函数
RSQUARE <- function(obs, pred) {
  cor(obs, pred)^2
}

# 示例:使用meuse数据集执行留一法交叉验证
data(meuse)
coordinates(meuse) <- ~x+y
cv_result <- cv.krige(zinc ~ 1, meuse, vgm(1, "Sph", 900, 1))

# 1. 计算每个折的单样本误差(MAE和RMSE,单样本下二者数值相同)
cv_result$mae_per_fold <- abs(cv_result$observed - cv_result$var1.pred)
cv_result$rmse_per_fold <- sqrt((cv_result$observed - cv_result$var1.pred)^2)

# 2. 计算整体交叉验证指标(全局R²、RMSE、MAE)
overall_metrics <- data.frame(
  Metric = c("R²", "RMSE", "MAE"),
  Value = c(
    RSQUARE(cv_result$observed, cv_result$var1.pred),
    rmse(cv_result$observed, cv_result$var1.pred),
    mae(cv_result$observed, cv_result$var1.pred)
  )
)

# 3. 对单折误差做统计汇总(分位数、极值)
fold_metrics_summary <- data.frame(
  Metric = rep(c("单折MAE", "单折RMSE"), each = 5),
  Statistic = rep(c("最小值", "25分位数", "中位数", "75分位数", "最大值"), 2),
  Value = c(
    quantile(cv_result$mae_per_fold, c(0, 0.25, 0.5, 0.75, 1)),
    quantile(cv_result$rmse_per_fold, c(0, 0.25, 0.5, 0.75, 1))
  )
)

# 输出结果
cat("=== 整体交叉验证指标 ===\n")
print(overall_metrics, row.names = FALSE)

cat("\n=== 单折误差统计汇总 ===\n")
print(fold_metrics_summary, row.names = FALSE)

关键说明

  • 留一法中单个样本的RMSE与MAE数值完全一致(单个误差的平方开根号等于绝对误差),因此二者的统计结果也会相同,属于正常现象。
  • 全局R²基于所有真实值与预测值的相关系数平方,反映模型整体拟合能力,无需按折拆分统计。
  • 避免错误:不要通过tail()或索引取单个行数据计算指标,必须使用cv_result的全量observed和var1.pred列。

内容的提问来源于stack exchange,提问作者Foeke Boersma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:46:09