为何R中拟合数据的MSE不等于偏差、方差与误差项方差之和?
MSE分解的错误分析与修正
你的代码里的MSE分解有三个核心错误:
1. 误解了MSE分解的前提:它是期望意义下的(多次重复实验的平均)
MSE分解公式是针对「多次生成不同数据集、拟合模型后,预测误差平方的期望」的拆分,而你只做了单次模拟,直接用一次拟合的结果计算,自然得不到正确的对应关系——单次模拟的结果受随机性影响,各部分的和不会严格等于单次的MSE。
2. 偏差项的计算完全错误
MSE分解中的偏差平方项是「每个样本点的期望预测值与真实函数值差的平方的平均」,公式为:mean( (E[ŷ_i] - f(x_i))^2 )。在你的设定中,真实函数是f(x)=x,而简单线性回归的系数估计是无偏的,即E[β̂₀]=0、E[β̂₁]=1,所以E[ŷ_i] = E[β̂₀ + β̂₁x_i] = x_i = f(x_i),因此偏差平方项的期望为0。你写的mean((x-mean(fitted))^2)完全不符合偏差的定义,这只是计算了真实值x和拟合值均值的差的平方平均,和偏差无关。
3. 方差项的计算不符合分解要求
分解中的方差项是「每个样本点预测值的方差的平均」,即mean( Var(ŷ_i) ),而你用的var(fitted)是单次拟合结果的样本方差,这不是分解中需要的「每个ŷ_i的方差的平均」。
正确的实现方式(多次模拟验证分解)
要验证MSE分解,需要重复多次模拟,每次生成数据集、拟合模型,记录每个部分的数值,最后取平均验证:
set.seed(123) # 固定随机种子,保证结果可复现 n <- 100 Sigma <- 2 x <- rnorm(n, 0, 3) # 固定x,只让噪声变化(更贴合分解的假设:x是固定的) sim_times <- 1000 # 重复模拟1000次 # 存储每次模拟的结果 mse_list <- numeric(sim_times) fitted_matrix <- matrix(nrow = n, ncol = sim_times) for (i in 1:sim_times) { # 生成响应变量 y <- x + rnorm(n, 0, sqrt(Sigma)) # 拟合模型 model <- lm(y ~ x) fitted <- predict(model, data.frame(x)) # 计算单次模拟的MSE mse_list[i] <- mean( (fitted - y)^2 ) # 存储拟合值 fitted_matrix[,i] <- fitted } # 计算各部分的期望(平均) avg_mse <- mean(mse_list) # 偏差平方:用多次模拟的拟合值均值近似期望预测值 E_fitted <- rowMeans(fitted_matrix) avg_bias_sq <- mean( (E_fitted - x)^2 ) # 方差:每个x_i对应拟合值的方差的平均 var_hat <- apply(fitted_matrix, 1, var) avg_var <- mean(var_hat) # 噪声方差 avg_noise_var <- Sigma # 验证分解 cat("平均MSE:", avg_mse, "\n") cat("偏差平方+方差+噪声方差:", avg_bias_sq + avg_var + avg_noise_var, "\n")
运行这段代码后,你会看到平均MSE和三个部分的和几乎相等,符合MSE分解公式。
内容的提问来源于stack exchange,提问作者Vassilis Chasiotis
相关产品推荐
相关产品推荐

