Esm*_*me_ 16 statistics r function
我有一个带有观察和建模数据的数据框,我想计算R2值.我希望有一个我可以为此调用的函数,但找不到它.我知道我可以写自己的并应用它,但我错过了一些明显的东西吗?我想要类似的东西
obs <- 1:5
mod <- c(0.8,2.4,2,3,4.8)
df <- data.frame(obs, mod)
R2 <- rsq(df)
# 0.85
Run Code Online (Sandbox Code Playgroud)
李哲源*_*李哲源 36
你需要一些统计知识才能看到这一点.两个向量之间的R平方只是它们相关性的平方.所以你可以定义你的功能:
rsq <- function (x, y) cor(x, y) ^ 2
Run Code Online (Sandbox Code Playgroud)
Sandipan的答案将返回完全相同的结果(参见下面的证据),但是它看起来更具可读性(由于明显$r.squared).
基本上,我们拟合的线性回归y过x,并计算回归平方和的比率,以总平方和.
引理1:回归y ~ x相当于y - mean(y) ~ x - mean(x)
引理2:beta = cov(x,y)/ var(x)
引理3:R.square = cor(x,y)^ 2
两个任意向量之间的R平方x和y(相同长度)只是它们线性关系的良好度量.三思!对于任何恒定的移位,R之间的平方x + a和y + b相同.因此,它对"预测的良好性"是一种微弱甚至无用的衡量标准.请改用MSE或RMSE:ab
我同意42的评论:
通过与回归函数相关联的汇总函数报告R平方.但只有当这种估计在统计上是合理的时候.
R平方可以是"适合度"的衡量标准(但不是最佳).但没有理由认为它可以衡量样本外预测的优点.如果将数据拆分为训练和测试零件并在训练零件上拟合回归模型,则可以在训练零件上获得有效的R平方值,但是您无法合理地计算测试零件上的R平方.有些人这样做了,但我不同意.
这是一个非常极端的例子:
preds <- 1:4/4
actual <- 1:4
Run Code Online (Sandbox Code Playgroud)
这两个向量之间的R平方为1.当然,一个只是另一个的线性重新缩放,因此它们具有完美的线性关系.但是,你真的认为这preds是一个很好的预测actual吗?
你可能误解了这个程序.由于两个矢量x和y,我们首先拟合回归线y ~ x然后计算平方和总平方的回归之和.看起来你跳过这个回归步骤直接进入平方计算的总和.这是错误的,因为平方和的分区不成立,你无法以一致的方式计算R平方.
如您所示,这只是计算R平方的一种方法:
preds <- c(1, 2, 3)
actual <- c(2, 2, 4)
rss <- sum((preds - actual) ^ 2) ## residual sum of squares
tss <- sum((actual - mean(actual)) ^ 2) ## total sum of squares
rsq <- 1 - rss/tss
#[1] 0.25
Run Code Online (Sandbox Code Playgroud)
但还有另一个:
regss <- sum((preds - mean(preds)) ^ 2) ## regression sum of squares
regss / tss
#[1] 0.75
Run Code Online (Sandbox Code Playgroud)
此外,您的公式可以给出负值(正如" 警告"部分中所述,正确的值应为1 ).
preds <- 1:4 / 4
actual <- 1:4
rss <- sum((preds - actual) ^ 2) ## residual sum of squares
tss <- sum((actual - mean(actual)) ^ 2) ## total sum of squares
rsq <- 1 - rss/tss
#[1] -2.375
Run Code Online (Sandbox Code Playgroud)
当我在2年前发布我的初步答案时,我从未预料到这个答案最终会如此长.但是,鉴于这个主题的高度观点,我觉得有必要添加更多的统计细节和讨论.我不想误导人们,因为他们可以很容易地计算出R平方,他们可以在任何地方使用R平方.
San*_*Dey 12
为什么不这样:
rsq <- function(x, y) summary(lm(y~x))$r.squared
rsq(obs, mod)
#[1] 0.8560185
Run Code Online (Sandbox Code Playgroud)
这不是显而易见的事情,但是该caret软件包具有postResample()根据文档计算"性能估计的向量" 的函数."业绩估计"是
并且必须从这样的矢量访问
library(caret)
vect1 <- c(1, 2, 3)
vect2 <- c(3, 2, 2)
res <- caret::postResample(vect1, vect2)
rsq <- res[2]
Run Code Online (Sandbox Code Playgroud)
然而,这是使用另一个答案中提到的r平方的相关平方近似.为什么他们不仅仅使用传统的1-SSE/SST超出了我的范围.
实现正态确定系数方程的方法是:
preds <- c(1, 2, 3)
actual <- c(2, 2, 4)
rss <- sum((preds - actual) ^ 2)
tss <- sum((actual - mean(actual)) ^ 2)
rsq <- 1 - rss/tss
Run Code Online (Sandbox Code Playgroud)
手动编码当然不是太糟糕,但为什么在主要用于统计的语言中没有它的功能呢?我想我仍然错过了某个地方R ^ 2的实现.
小智 5
您还可以将摘要用于线性模型:
summary(lm(obs ~ mod, data=df))$r.squared
Run Code Online (Sandbox Code Playgroud)
这是基于 [ https://en.wikipedia.org/wiki/Coefficient_of_determination]的最简单的解决方案
# 1. 'Actual' and 'Predicted' data
df <- data.frame(
y_actual = c(1:5),
y_predicted = c(0.8, 2.4, 2, 3, 4.8))
# 2. R2 Score components
# 2.1. Average of actual data
avr_y_actual <- mean(df$y_actual)
# 2.2. Total sum of squares
ss_total <- sum((df$y_actual - avr_y_actual)^2)
# 2.3. Regression sum of squares
ss_regression <- sum((df$y_predicted - avr_y_actual)^2)
# 2.4. Residual sum of squares
ss_residuals <- sum((df$y_actual - df$y_predicted)^2)
# 3. R2 Score
r2 <- 1 - ss_residuals / ss_total
Run Code Online (Sandbox Code Playgroud)
不知道为什么这没有直接在 R 中实现,但这个答案本质上与 Andrii 和 Wordsforthewise 相同,如果有人像我一样经常使用它,我只是为了方便起见将其变成一个函数。
r2_general <-function(preds,actual){
return(1- sum((preds - actual) ^ 2)/sum((actual - mean(actual))^2))
}
Run Code Online (Sandbox Code Playgroud)