在`r`的`插入符号'包中训练测试分裂

5xu*_*xum 5 r r-caret

我已经熟悉了它rcaret软件包,但是,从其他编程语言来看,它让我很困惑.

我现在想做的是一个相当简单的机器学习工作流程,它是:

  1. 采取训练集,在我的例子中是虹膜数据集
  2. 将其拆分为训练和测试集(80-20分割)
  3. 对于每一个k120,训练k近邻分类训练集
  4. 在测试装置上测试它

我知道如何做第一部分,因为iris已经加载了.然后,第二部分通过调用完成

a <- createDataPartition(iris$Species, list=FALSE)
training <- iris[a,]
test <- iris[-a,]
Run Code Online (Sandbox Code Playgroud)

现在,我也知道我可以通过调用训练模型

library(caret)
knnFit <- train()
knnFit <- train(Species~., data=training, method="knn")
Run Code Online (Sandbox Code Playgroud)

但是,这将导致r已对参数执行某些优化k.当然,我可以限制k该方法应该尝试的值,例如

knnFit <- train(Species~., data=training, method="knn", tuneGrid=data.frame(k=1:20))
Run Code Online (Sandbox Code Playgroud)

哪个工作得很好,但它仍然不是我想要它做的.这个代码现在将为每个代码执行k:

  1. 从中获取一个自助样本test.
  2. k使用给定的样本评估-nn方法的性能

我想要它做什么:

  1. 对于每个人k,在我之前建造的同一列车上训练模型
  2. 在我之前构建的相同测试集上评估性能**.

所以我需要类似的东西

knnFit <- train(Species~., training_data=training, test_data=test, method="knn", tuneGrid=data.frame(k=1:20))
Run Code Online (Sandbox Code Playgroud)

但这当然不起作用.

我知道我应该对trainControl参数做些什么,但我看到它可能的方法是:

"boot", "boot632", "cv", "repeatedcv", "LOOCV", "LGOCV", "none"
Run Code Online (Sandbox Code Playgroud)

这些似乎没有做我想做的事.

thi*_*e1e 8

如果我正确地理解了这个问题,可以使用LGOCV(Leave-group-out-CV =重复训练/测试分割)在插入符号中完成所有操作,并将训练百分比p = 0.8和训练/测试分割的重复设置为number = 1如果你真的想要每个模型只适合k在测试集上测试.设置number> 1将重复评估number不同列车/测试拆分的模型性能.

data(iris)
library(caret)
set.seed(123)
mod <- train(Species ~ ., data = iris, method = "knn", 
             tuneGrid = expand.grid(k=1:20),
             trControl = trainControl(method = "LGOCV", p = 0.8, number = 1,
                                      savePredictions = T))
Run Code Online (Sandbox Code Playgroud)

测试集上不同模型所做的所有预测都在mod$predif中savePredictions = T.注意rowIndex:这些是已经采样到测试集中的行.对于所有不同的值k,它们是相同的,因此每次使用相同的训练/测试集.

> head(mod$pred)
    pred    obs rowIndex k  Resample
1 setosa setosa        5 1 Resample1
2 setosa setosa        6 1 Resample1
3 setosa setosa       10 1 Resample1
4 setosa setosa       12 1 Resample1
5 setosa setosa       16 1 Resample1
6 setosa setosa       17 1 Resample1
> tail(mod$pred)
         pred       obs rowIndex  k  Resample
595 virginica virginica      130 20 Resample1
596 virginica virginica      131 20 Resample1
597 virginica virginica      135 20 Resample1
598 virginica virginica      137 20 Resample1
599 virginica virginica      145 20 Resample1
600 virginica virginica      148 20 Resample1 
Run Code Online (Sandbox Code Playgroud)

除非需要某种嵌套验证程序,否则无需在插入符之外手动构建训练/测试集.您还可以绘制不同的kby 值的验证曲线plot(mod).


phi*_*ver 6

请通读插入符号网站以了解一切如何运作。或者阅读 Max Kuhn 撰写的“应用预测建模”一书,了解有关插入符号如何工作的更多信息。

粗略地说,trainControl 包含一组不同的训练函数参数,例如交叉验证设置、要应用的指标 (ROC / RMSE)、采样、预处理等。

在训练中,您可以设置其他设置,例如网格搜索。我扩展了您的代码示例,使其有效。确保检查 createDataPartition 的工作方式,因为默认设置将数据分成两半。

library(caret)

a <- createDataPartition(iris$Species, p = 0.8, list=FALSE)
training <- iris[a,]
test <- iris[-a,]

knnFit <- train(Species ~ ., 
                data = training, 
                method="knn",  
                tuneGrid=data.frame(k=1:20))

knn_pred <- predict(knnFit, newdata = test)
Run Code Online (Sandbox Code Playgroud)

根据评论编辑:

一个火车对象不可能实现您想要的。Train 将使用 tunegrid 找到最佳 k 并在 finalModel 中使用该结果。此 finalModel 将用于进行预测。

如果您想对所有 k 有一个概览,您可能不想使用 caret 的 train 函数,而是为自己编写一个函数。也许像下面这样。请注意,knn3 是来自插入符号的 knn 模型。

k <- 20
knn_fit_list <- list()
knn_pred_list <- list()

for (i in 1:k) {
  knn_fit_list[[i]] <- knn3(Species ~ ., 
                            data = training, 
                            k = i)
  knn_pred_list[[i]] <- predict(knn_fit_list[[i]], newdata = test, type = "class")

}
Run Code Online (Sandbox Code Playgroud)

knn_fit_list 将包含指定数量 k 的所有拟合模型。knn_pred_list 将包含所有预测。