在 R 中使用 nls 进行非线性回归的交叉验证
Cross-validation for non-linear regression using nls in R
问题:
我有一个数据集inputAll.data
。我想使用 80% 的数据作为模型构建输入并在剩余 20% 的数据上验证模型。
我手动将数据集拆分为两个较小的数据集 input80.data
和 input20.data
,分别包含 80% 和 20% 的数据。
我的数据集中的数据格式:
Name xvalues yvalues
Prog1 0.654219 59.70282
Prog2 0.149516 49.59548
Prog3 0.50577 50.53859
Prog4 0.77783 59.95499
Prog5 0.237923 49.61133
Prog6 0.756063 50.63021
Prog7 0.015625 53.77959
我正在使用 80% 的数据构建非线性回归模型 nls
。
df = data.frame(input80.data)
yval = df$yvalues
xval = df$xvalues
model1 = nls(formula = yval ~ exp(xval + beta * xval), start = list(beta = 0))
sm1 = summary(model1)
fit1 = fitted.values(model1)
我正在使用剩余的 20% 数据来获得预测值。我在另一个名为 input20Actual.data
的文件中保存了包含实际 y
值的此数据的副本,但 input20.data
仅包含 x
值。
dfNew = data.frame(input20.data)
xpred = dfNew$xvalues
dfVerify = data.frame(input20Actual.data)
yverify = dfVerify$yvalues
xverify = dfVerify$xvalues
obtainedPred = predict(model1, data.frame(xvalues = c(xpred) ))
然后我使用名为 RMSE
的自定义函数来计算预测值与实际值之间的误差。
RMSE <- function(fitted, actual){
sqrt(mean((fitted - actual)^2))
}
误差计算是通过获取每个预测值并将其与我存储在 input20Actual.data
中的实际值进行比较来完成的。我将输出存储在一个文件中。
sink("ErrorsOut.txt")
cat("\n\nRMSE:\n")
for (i in 1:13) {
#There are 13 values to be predicted in input20.data
corr = obtainedPred[[i]]
act = yverify[[i]]
err = RMSE(act, corr)
cat(err)
cat(" ")
}
cat("\n")
sink()
问题是我手动拆分了输入集。我想自动化这个,对不同的分割(每次不同的数据)做同样的事情,并获得计算误差的平均值。
我试过的:
我在 Whosebug 上阅读了有关 R 中的交叉验证的内容。我的理解是它迭代地获取部分数据用于模型创建,其余数据用于测试。如果我可以在 nls
中使用交叉验证功能,我就不必将我的输入数据分成两个文件。
我在 SO 上搜索了很多解决方案。许多关于交叉验证的答案都是针对 lm
。但我特别需要 nls
的交叉验证。我还阅读了 caret
包,但我尝试安装它,但大多数时候我最终遇到包安装错误,如下所示:
Warning: dependency ‘plyr’ is not available
package ‘plyr’ is not available (for R version 3.0.2)
所以我希望有一种直接的方法可以在不安装更多包的情况下执行交叉验证(在 rkward 中)。 R 中是否有函数或 API 可用于迭代创建模型并测试它们?
请注意,我是 R 的新手。抱歉,如果这是一个明显的问题。
使用内置数据框 BOD
尝试下面 fo
中显示的简单模型。首先使用 sample
获取样本行的索引,然后使用 运行 获取这些行的模型。 predict.nls
然后使用样本外数据和样本内模型来获得预测值。由此可以计算残差平方和 (RSS) 和其他结果。每次 运行 sample
都会生成一组可能不同的索引(前提是 set.seed
不是 re运行)。这可以打包在一个函数中并 运行 重复。没有使用包。
set.seed(123) # for reproducibility
n <- nrow(BOD)
frac <- 0.8
ix <- sample(n, frac * n) # indexes of in sample rows
fo <- demand ~ a + Time * b
fm <- nls(fo, BOD, start = c(a = 0, b = 0), subset = ix) # in sample model
BOD.out <- BOD[-ix, ] # out of sample data
pred <- predict(fm, new = BOD.out)
act <- BOD.out$demand
RSS <- sum( (pred - act)^2 )
RSS
问题:
我有一个数据集inputAll.data
。我想使用 80% 的数据作为模型构建输入并在剩余 20% 的数据上验证模型。
我手动将数据集拆分为两个较小的数据集 input80.data
和 input20.data
,分别包含 80% 和 20% 的数据。
我的数据集中的数据格式:
Name xvalues yvalues
Prog1 0.654219 59.70282
Prog2 0.149516 49.59548
Prog3 0.50577 50.53859
Prog4 0.77783 59.95499
Prog5 0.237923 49.61133
Prog6 0.756063 50.63021
Prog7 0.015625 53.77959
我正在使用 80% 的数据构建非线性回归模型 nls
。
df = data.frame(input80.data)
yval = df$yvalues
xval = df$xvalues
model1 = nls(formula = yval ~ exp(xval + beta * xval), start = list(beta = 0))
sm1 = summary(model1)
fit1 = fitted.values(model1)
我正在使用剩余的 20% 数据来获得预测值。我在另一个名为 input20Actual.data
的文件中保存了包含实际 y
值的此数据的副本,但 input20.data
仅包含 x
值。
dfNew = data.frame(input20.data)
xpred = dfNew$xvalues
dfVerify = data.frame(input20Actual.data)
yverify = dfVerify$yvalues
xverify = dfVerify$xvalues
obtainedPred = predict(model1, data.frame(xvalues = c(xpred) ))
然后我使用名为 RMSE
的自定义函数来计算预测值与实际值之间的误差。
RMSE <- function(fitted, actual){
sqrt(mean((fitted - actual)^2))
}
误差计算是通过获取每个预测值并将其与我存储在 input20Actual.data
中的实际值进行比较来完成的。我将输出存储在一个文件中。
sink("ErrorsOut.txt")
cat("\n\nRMSE:\n")
for (i in 1:13) {
#There are 13 values to be predicted in input20.data
corr = obtainedPred[[i]]
act = yverify[[i]]
err = RMSE(act, corr)
cat(err)
cat(" ")
}
cat("\n")
sink()
问题是我手动拆分了输入集。我想自动化这个,对不同的分割(每次不同的数据)做同样的事情,并获得计算误差的平均值。
我试过的:
我在 Whosebug 上阅读了有关 R 中的交叉验证的内容。我的理解是它迭代地获取部分数据用于模型创建,其余数据用于测试。如果我可以在 nls
中使用交叉验证功能,我就不必将我的输入数据分成两个文件。
我在 SO 上搜索了很多解决方案。许多关于交叉验证的答案都是针对 lm
。但我特别需要 nls
的交叉验证。我还阅读了 caret
包,但我尝试安装它,但大多数时候我最终遇到包安装错误,如下所示:
Warning: dependency ‘plyr’ is not available
package ‘plyr’ is not available (for R version 3.0.2)
所以我希望有一种直接的方法可以在不安装更多包的情况下执行交叉验证(在 rkward 中)。 R 中是否有函数或 API 可用于迭代创建模型并测试它们?
请注意,我是 R 的新手。抱歉,如果这是一个明显的问题。
使用内置数据框 BOD
尝试下面 fo
中显示的简单模型。首先使用 sample
获取样本行的索引,然后使用 运行 获取这些行的模型。 predict.nls
然后使用样本外数据和样本内模型来获得预测值。由此可以计算残差平方和 (RSS) 和其他结果。每次 运行 sample
都会生成一组可能不同的索引(前提是 set.seed
不是 re运行)。这可以打包在一个函数中并 运行 重复。没有使用包。
set.seed(123) # for reproducibility
n <- nrow(BOD)
frac <- 0.8
ix <- sample(n, frac * n) # indexes of in sample rows
fo <- demand ~ a + Time * b
fm <- nls(fo, BOD, start = c(a = 0, b = 0), subset = ix) # in sample model
BOD.out <- BOD[-ix, ] # out of sample data
pred <- predict(fm, new = BOD.out)
act <- BOD.out$demand
RSS <- sum( (pred - act)^2 )
RSS