为什么 R 平方和 RMSE 的模型排名顺序不同?

机器算法验证 模型选择 r平方 模型评估 有效值
2022-03-29 09:58:08

我在比较R2和不同模型的RMSE。有趣的是,模型相对于R2和 RMSE 不同,我不明白为什么。

这是R中的一个例子:

library(caret) 

set.seed(0)
d<-SLC14_1(n=1000)

folds<-createMultiFolds(d$y,k=10,times=1)
tc<-trainControl(index=folds,returnResamp="all")
t1<-train(y~.,data=d,method="glmnet",trControl=tc) 
order(t1$results$RMSE)==order(-t1$results$Rsquared)

输出:

[1]  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE

因此,如果不同的顺序R2求和RMSE.

问题是,为什么。

SSres是残差平方和(yifi)2.

RMSE定义为SSres/n.

R2定义为1SSres/SStot在哪里SStot(yiy¯)2.

自从SSres=n(RMSE)2,我们可以写R2作为1n(RMSE)2/SStot. 自从nSStot对于所有模型都是恒定的并且相同,R2RMSE应该严格正相关。但是,它们不是,因为排名顺序实际上并不相同(请参见示例代码)。

我的论点有什么问题?

3个回答

results$RMSE在插入符号中,和的计算results$Rsquared并不像您所说的那么简单。它们实际上是RMSER2超过十个坚持集。

要确认这一点,请运行摘要:

> t1
glmnet 

1000 samples
  20 predictors

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 900, 900, 900, 900, 900, 900, ... 
Resampling results across tuning parameters:

  alpha  lambda      RMSE      Rsquared 
  0.10   0.01065054  17.93931  0.1655746
  0.10   0.10650539  17.93720  0.1656599
  0.10   1.06505391  17.89291  0.1678166
  0.55   0.01065054  17.93838  0.1657046
  0.55   0.10650539  17.91755  0.1668356
  0.55   1.06505391  17.84962  0.1731936
  1.00   0.01065054  17.93824  0.1657245
  1.00   0.10650539  17.90045  0.1678998
  1.00   1.06505391  17.92535  0.1710923

RMSE was used to select the optimal model using  the smallest value.
The final values used for the model were alpha = 0.55 and lambda = 1.065054.

对于最佳参数组合alpha = 0.55 and lambda = 1.065054,每个保留集的性能都可以在对象中看到t1$resample

> t1$resample
       RMSE   Rsquared Resample
1  18.42848 0.04479504   Fold05
2  21.17820 0.10500276   Fold08
3  18.27933 0.20858027   Fold04
4  17.31308 0.19080079   Fold07
5  16.60865 0.21812706   Fold10
6  20.07291 0.18737052   Fold02
7  16.48082 0.24041654   Fold03
8  17.18363 0.18379930   Fold06
9  17.29819 0.13669866   Fold09
10 15.65289 0.21634546   Fold01

(不用说,上面看到的 RMSE 和 Rsquared 是在不同的 CV 折叠上评估的,因此它们的排名顺序不同。)如果对这些列进行平均,您将得到:

> mean(t1$resample$RMSE)
[1] 17.84962
> mean(t1$resample$Rsquared)
[1] 0.1731936

...这与摘要第 6 行中看到的 RMSE 和 Rsquared 数字相同。


编辑:为什么平均折叠会破坏排名顺序?假设我们将数据拆分为F折叠,我们正在考虑C调音组合。对于每个组合c并保持折叠f, 之间的关系R2和 MSE 按折叠计算f是:

(1)Rsquared(c,f)=1MSE(c,f)Var(f),
在哪里Var(f)是折叠中观察到的响应的方差的简写f. 当然,对于给定的f, 如果我们平均c那么之间的单调关系R2并且 MSE 被保留,因为线性:
(2)1CcRsquared(c,f)=11CcMSE(c,f)Var(f).
但是,如果我们平均 (1)f我们不能断言类似的陈述,因为分母Var(f),随着折叠的展开而变化,阻碍了:
(3)1FfRsquared(c,f)=11Ff(MSE(c,f)Var(f)).
(3) 的 RHS 不能进一步简化以揭示平均值之间的单调关系R2所有折叠和所有折叠的平均 MSE。

由于 MSE 是 RMSE 的平方,所以折叠平均之间的关系R2而折叠平均 RMSE 则更不直接。实际上,对于任何给定的折叠,组合平均之间甚至没有 (2) 的类似物R2和组合平均 RMSE。

这是因为caret计算 R 平方的方式与您不同。请参阅此问题的答案:插入符号如何计算 R Squared

要在您的代码中看到它,

library(caret) 

set.seed(0)
d<-SLC14_1(n=1000)

folds<-createMultiFolds(d$y,k=10,times=1)
tc<-trainControl(index=folds,returnResamp="all",
             savePredictions = TRUE) # New option 
t1<-train(y~.,data=d,method="glmnet",trControl=tc) 
order(t1$results$RMSE)==order(-t1$results$Rsquared)

library(data.table)
preds <- data.table(t1$pred)
preds[, overall_mean := mean(obs), by = .(lambda, alpha, Resample)]

sum_sq <- preds[, .(SS_res = sum((obs - pred)^2),
                SS_tot = sum((obs - overall_mean)^2),
                n = .N,
                var = var(obs),
                Rsquared_corr = cor(obs, pred)^2),
            by = .(lambda, alpha, Resample)]
sum_sq <- sum_sq[, ':=' (RMSE_Julian = sqrt(SS_res / n),
                         Rsquared_Julian = 1 - (SS_res/SS_tot),
                         Rsquared_traditional = 1 - (SS_res/ ((n-1)*var) ))]
sum_sq <- merge(sum_sq, t1$resample, by = c("lambda", "alpha", "Resample"))
head(sum_sq)

注意savePredictions = TRUE调用traincontrol(). 在最终的数据集中,sum_sq您可以看到结果,Rsquared_Julianmatches Rsquared_traditional,但这些不匹配Rsquared_corr与插入符号的 R 平方匹配的结果,Rsquared

同样在您的问题中,您假设n并且SS_tot是恒定的,但这仅适用于折叠,而不适用于所有交叉验证。

@grand_chat 有正确的数学,我只是在一个比较示例中成长,以帮助说明问题的不同方面,希望有助于理解。

我们在这里使用分数项,类似于每加仑英里数。如果我们在设定的时间单位内平均 mpg,与超过设定的燃料或距离单位相比,我们会得到非常不同的结果。

如果我们以 50 英里/小时的速度行驶 10 分钟,达到 50 英里/加仑,然后以 60 英里/小时行驶 10 分钟,达到 30 英里/加仑,然后我们要计算旅途的平均燃油效率。

基于时间的平均值(一分钟代表一个时间单位)是(5010+3010)/20=40mpg

但我们旅行的距离是50/6+60/6=18.33miles假设十分钟是一小时的 1/6

我们使用的燃料是(50/6)/50+(60/6)/30=1/6+2/6=1/2gallon

这意味着我们的平均 mpg 实际上是18.33/(1/2)=36.66

因为总方差在每个折叠中都不同,所以您需要在平均中考虑这一点以保持单调关系。由于它存在于 R2 计算中但不存在于 RMSE 中,因此您可以通过不考虑每个折叠中的总方差来进行排名切换