R:从lapply对象中提取循环元素

时间:2018-11-10 19:38:12

标签: r for-loop machine-learning lapply

简而言之:有没有一种方法可以遍历下面allModelsResults所述的lapply对象的每个元素?

平均,例如allModelsResults$'1'给我对象的第一个元素。下一个allModelsResults$'2'将是第二个元素。我想创建一个for循环,以提取每个元素,运行一些命令并存储结果。

下面的详细说明...

我有以下代码,在其中跨多个模型规范使用“ knn”运行简单的ML模型。模型规格存储在allModelList中,所有结果存储在allModelsResults中。

所有模型列表中的单个模型如下:

y ~ x1 + x2 + x3

y ~ x1 + x5 + x4

等等...简而言之,一系列模型规格组合

allModelsResults <- lapply(allModelsList, function(x) train(x,       data=All_categories_merged_done,method = "knn"))

我现在想一一提取每个元素(每个模型的结果)以进行分析。例如,我可以手动服用:

allModelsResults$'1'从第一个模型获得结果,或者allModelsResults$'5'从第5个模型获得结果,依此类推。

理想情况下,每次选择一个元素在其上运行一系列命令时,我都会在for循环中遍历这些对象。

任何有关如何从allModelsResults对象中提取元素的帮助都会有帮助!我大约有50个模型规格,因此我需要创建一个循环或类似的东西来自动一个接一个地提取。

特别是为了与社区共享,对于每个元素,我想针对每个模型逐一进行。

作为一个示例,我在这里提取模型1(这显然不起作用):

aggregate_results <- NULL

for(z in 1:length(categories)){
element_number_ID <- (element_number[z])

element_number_ID应该等于'1'才能提取正确的模型

    model_1_result <- allModelsResults$'1'

    ResultsTestPred <- predict(model_1_result, testing_data)
    results_to_store <- confusionMatrix(ResultsTestPred, testing_data $outcome)

aggregate_results  <- rbind(aggregate_results, results_to_store)

}

results_to_store的一个元素输出如下:

混淆矩阵和统计

      Reference

预测0 1          0 14 2          1 4 19

           Accuracy : 0.8462          
             95% CI : (0.6947, 0.9414)
No Information Rate : 0.5385          
P-Value [Acc > NIR] : 0.00005274      

              Kappa : 0.688           

麦克纳马尔的检验P值:0.6831

        Sensitivity : 0.7778          
        Specificity : 0.9048          
     Pos Pred Value : 0.8750          
     Neg Pred Value : 0.8261          
         Prevalence : 0.4615          
     Detection Rate : 0.3590          

检测患病率:0.4103
      平衡精度:0.8413

   'Positive' Class : 0       

我要为每个元素/模型保存Accuracy值的位置。这样,我就可以比较每个模型规格的准确性。

任何见识将不胜感激!

1 个答案:

答案 0 :(得分:1)

您似乎想要获得每个模型的预测和混淆矩阵。没有可复制的示例,并带有一些混乱的术语,我正在做很多猜测,但是我想我知道您想要什么(或者足够接近)。我将向您展示如何使用lapplyMap,然后我们也可以使用for循环来实现它。

首先,对测试数据进行预测。所有这些方法完全相同:

# lapply way
predictions = lapply(allModelsList, predict, newdata = testingdata)

# for loop way
predictions = list()
for (i in 1:length(allModelsList)) {
  predictions[[i]] = predict(allModelsList[[i]], newdata = testingdata)
}

# manual way - just so you understand exactly what's going on
predictions = list(
  predict(allModelsList[[1]], newdata = testingdata),
  predict(allModelsList[[2]], newdata = testingdata),
  predict(allModelsList[[3]], newdata = testingdata),
  ...
)

现在,predictionslist,因此我们使用[[访问每个元素。如果我们要定义某个变量predictions[[1]](喜欢在循环中使用),则第一个是k,第predictions[[k]]个是k。我们还可以添加描述性名称,并使用名称代替索引。

类似地,我们可以计算所有混淆矩阵:

# lapply way
conf_matrices = lapply(predictions, confusionMatrix, reference = testingdata$outcome)

# for loop way
conf_matrices = list()
for (p in 1:length(predictions)) {
  conf_matrices[[p]] = confusionMatrix(p, reference = testingdata$outcome)
}

# manual way (for illustration)
conf_matrices = list(
  confusionMatrix(predictions[[1]], reference = testingdata$outcome),
  confusionMatrix(predictions[[2]], reference = testingdata$outcome),
  ...
) 

同样,我们有一个list。第一个混淆矩阵是conf_matrices[[1]],都与上面相同。

希望这有助于我们了解如何使用lapplyfor循环来创建列表。


现在,在问题的最下方,您似乎暗示了混淆矩阵的Accuracy部分。我在帮助页面?confusionMatrix的底部运行了示例,并查看了结果。在结果上运行str(conf_mat)告诉我它是list,并且列表中的"overall"元素是命名向量,包括"Accuracy"。因此,对于单个混淆矩阵cm,我们可以使用cm[["overall"]]["Accuracy"]提取准确性。我们将[[部分用作list,将常规矢量部分用作[。 (我们也可以使用cm$overall["Accuracy"]$的工作原理是提供确切的名称,没有引号,没有变量。很多问题似乎与尝试将$与引号或变量。您只是不能这样做。请参阅fortunes::fortune(312)

因此,我们可以从混淆矩阵列表中提取精度:

# I use *s*apply here so the result will be *s*implified into a vector
acc = sapply(conf_matrices, function(cm) cm[["overall"]]["Accuracy"])

acc = numeric(length(conf_matrices))
for (i in 1:length(conf_matrices)) {
  acc[i] = conf_matrices[[i]][["overall"]]["Accuracy"]
}

或者,如果您从一开始就知道只需要准确性,我们可以直接到达那里而无需保存中间步骤:

# apply
acc = sapply(allModelsList, function(x) {
    pred = predict(x, newdata = testingdata)
    cm = confusionMatrix(pred, reference = testingdata$outcome
    return(cm[["overall"]]["Accuracy"]
  }
)

#for循环    acc =数字(length(allModelsList))    对于(i in 1:length(allModelsList)){      pred =预测(allModelsList [[i]],newdata = testingdata)      cm = confusionMatrix(pred,reference = testingdata $ outcome      acc [i] =(cm [[“ overall”]] [“ Accuracy”]    }


注意:如上所述,在没有可重复的示例的情况下,我猜测很多,并且这些都没有经过测试,因为我没有任何可测试的输入。我假设我在您的问题中看到的关于各个步骤的信息是正确的,就像我们希望对allModelResults的每个元素进行预测一样。 (如果是这样,fittedModels似乎比allModelResults更好。)我不知道您所说的“模型规范”是什么意思,我也不知道其中的含义是什么。 allModelList,但希望这为您提供了使用列表的足够示例,可以解决所有问题。 (例如,可能还有不匹配的括号或缺少括号。)

lapply循环相比,

sapplyfor方便您键入,但实际上并没有什么不同。他们设置了一个对象来保存结果,然后将其填满。如果要同时创建多个结果,则可能只需要一个for循环。而且,随着内部步骤数的增加,无论如何,调试for循环会更加容易。使用您喜欢的东西和对您有意义的东西。