如何从R中的线性模型中获得交叉验证的r-square?

Jer*_*lim 7 r linear-regression cross-validation

我在R中有一个线性模型

set.seed(1234)
x <- rnorm(100)
z <- rnorm(100)
y <- rnorm(100, x+z)
mydata <- data.frame(x,y,z)

fit <- lm(y ~ x + z, mydata)
Run Code Online (Sandbox Code Playgroud)

我想获得样本r-square的估计值.我正在考虑使用某种形式的k-fold交叉验证.

  • R中的代码采用线性模型拟合并返回交叉验证的r平方?
  • 或者是否有其他方法可以使用R获得交叉验证的r-square?

Jer*_*lim 4

因此,接下来是对@NPR 从 statsmethods 链接到的示例的轻微修改。本质上我修改了这个例子,使其成为一个函数。

library(bootstrap)

k_fold_rsq <- function(lmfit, ngroup=10) {
    # assumes library(bootstrap)
    # adapted from http://www.statmethods.net/stats/regression.html
    mydata <- lmfit$model
    outcome <- names(lmfit$model)[1]
    predictors <- names(lmfit$model)[-1]

    theta.fit <- function(x,y){lsfit(x,y)}
    theta.predict <- function(fit,x){cbind(1,x)%*%fit$coef} 
    X <- as.matrix(mydata[predictors])
    y <- as.matrix(mydata[outcome]) 

    results <- crossval(X,y,theta.fit,theta.predict,ngroup=ngroup)
    raw_rsq <- cor(y, lmfit$fitted.values)**2 # raw R2 
    cv_rsq <- cor(y,results$cv.fit)**2 # cross-validated R2

    c(raw_rsq=raw_rsq, cv_rsq=cv_rsq)
}
Run Code Online (Sandbox Code Playgroud)

所以使用之前的数据

# sample data
set.seed(1234)
x <- rnorm(100)
z <- rnorm(100)
y <- rnorm(100, x+z)
mydata <- data.frame(x,y,z)
Run Code Online (Sandbox Code Playgroud)

我们可以拟合线性模型并调用交叉验证函数:

# fit and call function
lmfit <- lm(y ~ x + z, mydata)
k_fold_rsq(lmfit, ngroup=30)
Run Code Online (Sandbox Code Playgroud)

并获得原始和交叉验证的 r 方:

  raw_rsq    cv_rsq 
0.7237907 0.7050297
Run Code Online (Sandbox Code Playgroud)

警告:虽然raw_rsq显然是正确的并且cv_rsq符合我的预期,但请注意,我还没有确切地检查该crosval函数的作用。因此,使用的风险由您自己承担,如果有人有任何反馈,我们将非常欢迎。它也仅设计用于具有截距和标准主效应符号的线性模型。