这里有几个问题。首先,这不是使用lm(...)
的好方法。 lm(...)
旨在与数据框一起使用,公式表达式引用df中的列。因此,假设你的数据在两个向量x
和y
,
set.seed(1) # for reproducible example
x <- 1:11000
y <- 3+0.1*x + rnorm(11000,sd=1000)
df <- data.frame(x,y)
# training set
train <- sample(1:nrow(df),0.75*nrow(df)) # random sample of 75% of data
fit <- lm(y~x,data=df[train,])
现在fit
具有基于训练集模型。使用lm(...)
这种方式可以让您例如生成预测,而不用全部矩阵乘法。
第二个问题是R平方的定义。所述conventional definition是:
1 - SS.residuals/SS.total
对于训练集,和训练ONLY设置,
SS.total = SS。回归+ SS.residual
so
SS.regression = SS.total - SS.residual,
因此
R.sq = SS.regression/SS.total
所以R. sq是由模型解释的数据集中变化的分数,并且始终在0和1之间。
您可以看到th在下面。
SS.total <- with(df[train,],sum((y-mean(y))^2))
SS.residual <- sum(residuals(fit)^2)
SS.regression <- sum((fitted(fit)-mean(df[train,]$y))^2)
SS.total - (SS.regression+SS.residual)
# [1] 1.907349e-06
SS.regression/SS.total # fraction of variation explained by the model
# [1] 0.08965502
1-SS.residual/SS.total # same thing, for model frame ONLY!!!
# [1] 0.08965502
summary(fit)$r.squared # both are = R.squared
# [1] 0.08965502
但这确实与测试集不工作(例如,当你从一个模型的预测)。
test <- -train
test.pred <- predict(fit,newdata=df[test,])
test.y <- df[test,]$y
SS.total <- sum((test.y - mean(test.y))^2)
SS.residual <- sum((test.y - test.pred)^2)
SS.regression <- sum((test.pred - mean(test.y))^2)
SS.total - (SS.regression+SS.residual)
# [1] 8958890
# NOT the fraction of variability explained by the model
test.rsq <- 1 - SS.residual/SS.total
test.rsq
# [1] 0.0924713
# fraction of variability explained by the model
SS.regression/SS.total
# [1] 0.08956405
在这个人为的例子中没有太大的区别,但是很可能有一个R-sq。值小于0(当以这种方式定义时)。
例如,如果模型对于测试集来说是一个非常差的预测变量,那么残差实际上可能大于测试集中的总变化量。这相当于说,使用平均值来比使用从训练集派生的模型更好地模拟测试集。
我注意到,你使用你的数据的前四个季度作为训练集,而不是随机抽样(如本例中)。如果y
对x
的依赖是非线性的,并且x
是有序的,那么您可以得到具有测试集的负R-sq。
关于下面的OP评论,一种用测试集评估模型的方法是通过比较模型内模型和模型外均方误差(MSE)。
mse.train <- summary(fit)$sigma^2
mse.test <- sum((test.pred - test.y)^2)/(nrow(df)-length(train)-2)
如果我们假设训练和测试组都通常与相同的方差分布并且具有遵循相同的模型公式的装置,则该比率应该有一个F-分布(n.train-2 )和(n.test-2)自由度。如果MSE基于F测试显着不同,那么该模型确实适合测试数据,而不是而不是。
你有没有绘制你的test.y和pred.y和x?只有这一点会告诉你很多。
请参阅[此类似的问题(http://stats.stackexchange.com/questions/863 CrossValidated上的14/higher-r-squared-on-test-data-than-training-data)。 – nrussell 2014-09-05 17:41:13
@nrussell谢谢;我在提到的问题中使用了公式,并得到了一个负数(-0.59)作为我的R^2值。我对我的lm模型有疑问,我应该添加一个拦截(我认为R会自动执行)?那为什么我会得到负面的R^2呢? – 2014-09-05 18:06:37
您是否在问题下面的评论中使用公式或注释中的公式?因为问题中的公式不正确 - 请参阅@Panos对该问题的评论。 – nrussell 2014-09-05 18:41:21