我创建这篇文章是为了围绕我对用于复制统计模型结果的种子数的选择的想法展开讨论。以下是关于我如何提出这个想法以及如何应用它的一些背景知识。
我有一个数据集,称为数据,它有 506 个观察值、13 个预测变量和 1 个连续响应变量。我通过随机抽样 380 个索引而不进行替换,将数据拆分为训练和测试集,将与数据数据帧中的 380 个索引相等的行中的观察结果存储到称为 train 的数据帧中,并将剩余的 126 个观察结果存储到称为 test 的数据帧中.
创建训练集和测试集后,我使用glm函数构建了一个线性模型,使用predict函数预测了测试集的结果,并计算了测试集的预测值与其实际值之间的 MSE。在本例中,我获得了 16.65786 的 MSE。我把代码留在这里过夜,因为该回家了。
用于此的 R 代码是:
library(MASS)
data <- Boston
index <- sample(x = 1:nrow(data), size = round(nrow(data)*0.75), replace = FALSE)
train <- data[index, ]
test <- data[-index, ]
lm1.fit <- glm(medv ~ ., data = train)
pr.lm1 <- predict(lm1.fit, test)
(MSE.lm1 <- sum((pr.lm1 - test$medv)^2) / nrow(test))
第二天,我意识到我应该设置一个种子,以便用于创建训练集和测试集的随机索引(行)样本在每次运行代码时都是相同的。所以我选择了种子 1 并重新运行了上面的代码。这次我收到了 28.72933 的 MSE,与我前一天晚上获得的 MSE 相差很大。这引发了一个问题,如果我选择的种子是导致异常情况的种子,或者我获得的非种子结果是异常情况怎么办。也许这两个结果都是异常情况!所以我做了一些调查。
我使用 for 循环 10,000 次,每次获取一个新的随机索引样本,创建一个新的训练和测试集,建立一个线性模型,预测测试集的结果,并计算 MSE。我将 10,000 个 MSE 中的每一个都存储在一个数据框中,并计算了 MSE 的平均值和中值。我还查看了看起来大致正常的 MSE 分布。我再次重新运行了forloop,以确保MSE的平均值和中位数没有太大变化,它们没有。
前 10,000 个 MSE 的平均值为 24.13,中位数为 23.51。
第二个 10,000 个 MSE 的平均值为 24.01,中位数为 23.48。
用于此的 R 代码是:
error <- data.frame(err = rep(0, 10000))
for(i in 1:10000)
{
index <- sample(x = 1:nrow(data), size = round(nrow(data)*0.75),
replace = FALSE)
train <- data[index, ]
test <- data[-index, ]
#Linear Model 1 - No Data Cleaning
lm1.fit <- glm(medv ~ ., data = train)
summary(lm1.fit)
pr.lm1 <- predict(lm1.fit, test)
error[i, 1] <- sum((pr.lm1 - test$medv)^2) / nrow(test)
}
summary(error[, 1])
我做的最后一件事是循环通过相同的模型构建过程,直到我找到一个种子,导致 MSE 介于 20,000 个 MSE 的平均值和中位数之间。
用于此的 R 代码是:
for(i in 1:10000)
{
set.seed(i)
index <- sample(x = 1:nrow(data), size = round(nrow(data)*0.75),
replace = FALSE)
train <- data[index, ]
test <- data[-index, ]
#Linear Model 1 - No Data Cleaning
lm1.fit <- glm(medv ~ ., data = train)
summary(lm1.fit)
pr.lm1 <- predict(lm1.fit, test)
error <- sum((pr.lm1 - test$medv)^2) / nrow(test)
if(error > 23 & error < 24){print(i)}
}
我选择使用 47 的种子,导致 MSE 为 23.63085。我相信这种获得种子的方法更准确地描述了模型准确预测的能力,而不是仅仅随机挑选种子或找到能提供最佳结果的种子(我认为这是“作弊”)。
我对你们所有统计学家的问题是,这似乎是一种合理的意识形态/方法吗?有没有更合适的方法?以这种方式采摘种子有缺点吗?
提前感谢大家的意见!
[Scortchi] 谢谢 - 我试图简洁并将两点混为一谈:(1)特别是 OP 的重新发明 Monte-Carlo 交叉验证;& (2) 样本外 MSE 估计对所用种子的敏感性表明他们应该使用某种形式的重新采样验证,而不是训练/测试拆分。– 斯科奇
[Brandon] @Scortchi 所以你说的是我应该简单地使用以下代码:
library(MASS)
data <- Boston
lm1.fit <- glm(medv ~ ., data = data)
library(boot)
set.seed(1)
cvResult <- cv.glm(data = data, glmfit = lm1.fit, K = 10)
cvResult$delta
这导致 cv 预测误差为 23.38074,非常接近使用我上面的 long 方法获得的预测误差。我对么?