R中cv.glmnet输出误差与手动计算值不匹配问题求助
问题:glmnet中cv.glmnet手动计算MSE与模型输出不匹配
在使用glmnet包的cv.glmnet函数进行多响应高斯回归(family="mgaussian")时,手动通过fit.preval计算的均方误差(MSE)远小于模型报告的结果。复现代码如下:
library(glmnet) x <- data.frame(runif(100),runif(100),runif(100),runif(100),runif(100)) y <- data.frame(runif(100),runif(100),runif(100)) cvfit <- cv.glmnet(x = as.matrix(x), y = as.matrix(y), keep = T, family = "mgaussian") # 手动计算MSE mean(unlist((cvfit$fit.preval[,,cvfit$index["min",]] - y)^2)) ## [1] 0.08803571 # 模型输出结果 cvfit ## Call: cv.glmnet(x = as.matrix(x), y = as.matrix(y), keep = T, family = "mgaussian") ## ## Measure: Mean-Squared Error ## ## Lambda Index Measure SE Nonzero ## min 0.06003 1 0.2641 0.01158 1 ## 1se 0.06003 1 0.2641 0.01158 1
原因分析
差异的核心是多响应场景下MSE的计算逻辑不一致:
cv.glmnet针对mgaussian族的计算规则:先对单个样本的所有响应变量的预测误差平方求和,再对所有样本取均值(即每个样本的总平方误差的平均值)。- 你的手动计算规则:将所有样本的所有响应变量的平方误差拉平后取平均(即所有响应变量的MSE的平均值),结果恰好是模型输出值的1/3(0.088×3≈0.264,与模型报告的
Measure值完全匹配)。
另外确认:fit.preval确实存储了交叉验证中每个样本在其所属验证折叠中的预测值,这部分你的理解是正确的。
修正后的手动计算代码
要得到与模型一致的结果,需遵循相同的计算逻辑:先计算每个样本的所有响应误差平方之和,再取样本均值:
# 转换y为矩阵(避免data.frame的隐式转换问题) y_mat <- as.matrix(y) # 计算每个样本的所有响应的平方误差之和 row_sse <- rowSums((cvfit$fit.preval[,,cvfit$index["min",]] - y_mat)^2) # 取样本均值 mean(row_sse) ## [1] 0.2641071 # 与模型输出的Measure值一致
内容的提问来源于stack exchange,提问作者Tristan Kos
相关产品推荐
相关产品推荐

