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

时间:2016-03-01 08:53:48

标签: r r-caret

我熟悉r的{​​{1}}软件包,但是,来自其他编程语言,它让我感到困惑。

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

  1. 采取训练集,在我的例子中是虹膜数据集
  2. 将其拆分为训练和测试集(80-20分割)
  3. 对于从caretk的每1次,培训培训集上的20最近邻居分类器
  4. 在测试集上测试
  5. 我理解如何执行第一部分,因为k已经加载。然后,第二部分通过调用

    完成
    iris

    现在,我也知道我可以通过调用

    训练模型
    a <- createDataPartition(iris$Species, list=FALSE)
    training <- iris[a,]
    test <- iris[-a,]
    

    但是,这会导致library(caret) knnFit <- train() knnFit <- train(Species~., data=training, method="knn") 已对参数r执行某些优化。当然,我可以限制该方法应该尝试的k值,例如

    k

    效果很好,但它仍然不能完全符合我的要求。现在,对于每个knnFit <- train(Species~., data=training, method="knn", tuneGrid=data.frame(k=1:20))

    ,此代码将执行此操作
    1. k
    2. 获取引导样本
    3. 使用给定样本
    4. 评估test - nn方法的性能

      我想要它做什么:

      1. 对于每个k,在我之前构建的同一列车上训练模型
      2. 在我之前构建的同一测试集上评估性能**。
      3. 所以我需要像

        这样的东西
        k

        但这当然不起作用。

        我知道我应该对knnFit <- train(Species~., training_data=training, test_data=test, method="knn", tuneGrid=data.frame(k=1:20)) 参数做一些事情,但我看到它可能的方法是:

        trainControl

        并且这些似乎都没有做我想要的。

2 个答案:

答案 0 :(得分:8)

如果我正确理解了这个问题,可以使用LGOCV(Leave-group-out-CV =重复训练/测试分割)并设置训练百分比p = 0.8和训练的重复,在插入符号内完成/ test如果你真的只想在testset上测试每个number = 1一个模型,则将其拆分为k。设置number&gt; 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))

测试集上不同模型所做的所有预测都在mod$pred 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 

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

答案 1 :(得分:3)

请仔细阅读caret website ,了解一切如何运作。或者阅读本书&#34; Applied Predictive Modeling&#34;由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)

根据评论编辑:

一个火车对象无法实现您的目标。 Train将使用tunegrid找到最佳k并在finalModel中使用该结果。此finalModel将用于进行预测。

如果你想概述所有k,你可能不想使用插入符号的列车功能,但为自己编写一个功能。也许就像下面这样。请注意,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")

}

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