我在75%的数据集上拟合了一个线性回归模型,其中包括约11000个观测值和143个变量:
gl.fit <- lm(y[1:ceiling(length(y)*(3/4))] ~ ., data= x[1:ceiling(length(y)*(3/4)),]) #3/4 for training
字符串
我得到了0.43的R^2。然后我试着用剩下的数据预测我的测试数据:
ytest=y[(ceiling(length(y)*(3/4))+1):length(y)]
x.test <- cbind(1,x[(ceiling(length(y)*(3/4))+1):length(y),]) #The rest for test
yhat <- as.matrix(x.test)%*%gl.fit$coefficients #Calculate the predicted values
型
现在我想计算测试数据的R^2值,有什么简单的方法吗?
谢谢你
5条答案
按热度按时间yzuktlbb1#
这里有几个问题。首先,这不是使用
lm(...)
的好方法。lm(...)
旨在用于数据框,公式表达式引用df中的列。因此,假设您的数据位于两个向量x
和y
中,字符串
现在
fit
有了基于训练集的模型。使用lm(...)
这种方式可以让你,例如,生成预测而无需所有的矩阵乘法。第二个问题是R平方的定义。conventional definition是:
1 - SS.残差/SS.总
对于训练集,* 和仅训练集 *,
SS.total = SS.回归+ SS.残差
所以
SS.回归= SS.total- SS.残差,
并且因此
R.sq = SS.回归/SS.总
所以R.sq是模型解释的数据集中的变异性分数,并且总是在0和1之间。
你可以在下面看到。
型
但这对测试集不起作用(例如,当你从模型中进行预测时)。
型
在这个人为的例子中,没有太大的差异,但很可能有一个R-sq值小于0(当以这种方式定义时)。
例如,如果模型对测试集的预测效果非常差,那么残差实际上可能大于测试集的总变异,这相当于说使用测试集的均值比使用从训练集导出的模型更好地建模测试集。
我注意到你使用了前四分之三的数据作为训练集,而不是随机抽取样本(如本例),如果
y
对x
的依赖是非线性的,并且x
是有序的,那么你可以用测试集得到负的R-sq。关于OP下面的评论,使用测试集评估模型的一种方法是比较模型内和模型外的均方误差(MSE)。
型
如果我们假设训练集和测试集都是正态分布,具有相同的方差,并且均值遵循相同的模型公式,那么比率应该具有F分布,自由度为(n.train-2)和(n.test-2)。如果基于F检验,MSE显著不同,那么模型不能很好地拟合测试数据。
你有没有画出你的test.y和pred.y与x的关系图??单凭这一点就能告诉你很多。
ctzwtxfj2#
在测试数据上计算R平方有点棘手,因为你必须记住你的基线是什么。你的基线投影是你的训练数据的平均值。
因此,扩展上面@jlhoward提供的示例:
字符串
更新:
miscTools::rSquared()
函数假设R平方是在相同的数据集上计算的,模型是在该数据集上训练的,因为它计算型
第184行的幕后:https://github.com/cran/miscTools/blob/master/R/utils.R
cgh8pdjw3#
如果你想要一个函数,
miscTools
包有一个rSquared
函数。字符串
bbuxkriu4#
当您在样本(外)上使用R2测量时,您会丢失R2解释的某些方面:
如果你想使用R,我推荐
modelr::rsquare
函数。注意,它使用的是测试样本的SSR总数,而不是训练样本(有些人似乎提倡)。这里我举一个例子,我们的训练数据只有3个点,因此我们有一个很高的风险,我们有一个坏的模型,因此一个差的样本外性能,事实上,你可以看到R2是负的!
字符串
计算列车数据:
型
根据测试数据计算:
型
6qftjkof5#
字符串