【问题标题】:for loop error "attempt to select less than one element" in RR中的for循环错误“尝试选择少于一个元素”
【发布时间】:2016-06-10 11:33:06
【问题描述】:

我已经为我的向量创建了正确数量的索引,并且我正在尝试从 for 循环中输入第 i 个元素作为索引来保存分类错误值。但我得到了错误:

indeces.gen_error[[i]] 中的错误 尝试选择少于一个元素

uspscl.txt

uspsdata.txt

我的代码:

library(e1071)
library(caret)

set.seed(733)
uspscldf = read.table('uspscl.txt', header=F, sep=',')
uspsdatadf = read.table('uspsdata.txt', header=F, sep='\t')

trainIndex <- createDataPartition(uspscldf$V1,list=FALSE, p = .80,times=1)
dataTrain <- uspsdatadf[ trainIndex,]
dataTest  <- uspsdatadf[-trainIndex,]

classTrain <- uspscldf[ trainIndex,]
classTest  <- uspscldf[-trainIndex,]

indeces = seq(0.00001, 1, by=0.001)

indeces.gen_error = NULL
indeces.softmargin = NULL
for (i in seq(0.00001, 1, by=0.001)){
    # For svm(): soft margin is "cost" 
    # Gaussian kernel bandwidth (sigma) = is implicitly defined by "gamma"
    # kernal=radial is non-linear while kernal=linear is linear
    svm.model <- svm(classTrain ~ ., data = dataTrain, cost = i,type="C-classification",kernal = "linear")

    svm.pred <- predict(svm.model, dataTrain)

    # confusion matrix
    tab <- table(pred = svm.pred, true = classTrain)

    classification_error <- 1- sum(svm.pred == classTrain)/length(svm.pred)

    indeces.gen_error[[i]] <- paste(classification_error)
    indeces.softmargin[[i]]<-i
}

我在第一次迭代中打印了第一个 i,它给出了 1e-5,这是正确的,所以我不知道为什么它说我选择的元素少于一个。 任何帮助,将不胜感激。谢谢

回答::: 在我自己解决答案之前,我没有看到皮埃尔对此的回答,但他的解释更好,所以我接受他的回答。我现在的新代码是:

indeces = seq(0.00001, 1, by=0.001)

indeces.gen_error = NULL
indeces.softmargin = NULL
count=0
for (i in indeces){
  count=count+1
    # For svm(): soft margin is "cost" 
    # Gaussian kernel bandwidth (sigma) = is implicitly defined by "gamma"
    # kernal=radial is non-linear while kernal=linear is linear
    svm.model <- svm(classTrain ~ ., data = dataTrain, cost = i,type="C-classification",kernal = "linear")

    svm.pred <- predict(svm.model, dataTrain)

    # confusion matrix
    tab <- table(pred = svm.pred, true = classTrain)

    classification_error <- 1- sum(svm.pred == classTrain)/length(svm.pred)

    indeces.gen_error[[count]] <- paste(classification_error)
    indeces.softmargin[[count]]<-i
}

【问题讨论】:

  • 你能解释一下 0.00001 的索引对数组意味着什么吗?索引应该是整数;如果不是,它们会以某种方式被强制(在这种情况下,这似乎会给您带来问题)。
  • 在 Stack Overflow 上,任何调试问题(“为什么这段代码不起作用?”)都必须包含一个可重现的示例。在这种情况下,我们没有 uspscl.txt 或 uspsdata.txt,因此我们无法复制您的错误。您可以发布数据样本或使用内置数据集来使您的问题可重现。要阅读有关 R 中可重现示例的更多信息,请参阅stackoverflow.com/questions/5963269
  • 您正在使用 0.00001 之类的值进行子集化。我确定这不是故意的。要查看重现的错误,请尝试x &lt;- NULL; x[[0.001]] &lt;- "a"
  • @josliber 我添加了文本文件。
  • @PierreLafortune hm 我看到你复制了代码,但我还是不明白。

标签: r for-loop vector svm


【解决方案1】:
#Example
x <- NULL
for( i in seq(0.01, 1, .01)) {
  a <- 10 * i
  x[[i]] <- paste("b", a)
}
# Error in x[[i]] <- paste("b", a) : 
#   attempt to select less than one element

#The right way
x <- NULL
myseq <- seq(0.01, 1, 0.01)
for( i in 1:length(myseq)) {
  a <- 10 * myseq[i]
  x[i] <- paste("b", a)
}

为什么第一种方法会失败for( i in seq(0.01, 1, .01)) 将使用序列作为“i”。每当循环失败时,第一种排除故障的方法是逐个尝试每个循环。因此,每个循环都会获取序列的一个值,并将其输入到有i 的任何地方。第一个循环看起来像:

for (i in seq(0.00001, 1, by=0.001)){

    svm.model <- svm(classTrain ~ ., data = dataTrain, cost = 0.00001,type="C-classification",kernal = "linear")

    svm.pred <- predict(svm.model, dataTrain)

    # confusion matrix
    tab <- table(pred = svm.pred, true = classTrain)

    classification_error <- 1- sum(svm.pred == classTrain)/length(svm.pred)

    indeces.gen_error[[0.00001]] <- paste(classification_error)
    indeces.softmargin[[0.00001]]<- 0.00001
}

你看到问题了吗?使用indeces.gen_error[[0.00001]],请注意这里发生的事情。你不是故意的。您的意思是让indeces.gen_error[[1]] 成为第一个条目。

您正在使用小数进行子集化。如果我们有:

x <- 1:10

您认为x[2.5] 会发生什么?我们要求 R 获取位置 2.5 处的元素。那没有意义。没有半位置。有第2个或第3个。试试看返回什么。

在您的循环中,您向 R 询问 indeces.gen_error[[0.00001]]。因此,您请求的是第 1/100,000 个位置。那没有意义。评估器将强制子集为整数。它转到0。我们得到一个错误。

【讨论】:

  • 感谢您的解释 :) 如果您在上面看到,我更改了我的代码。告诉它进入 R 中的第一个位置的最佳方法是什么?我的解决方案是使用计数,但我认为有一个更优雅的解决方案,我没有想到。
  • 使用答案中的示例并将想法应用到您的循环中for (i in 1:length(indeces)) 是开始
  • 在你的模型中使用cost = indeces[i]。最后使用indeces.gen_error[i]
  • 啊,我明白了。谢谢! :)
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 2015-07-13
  • 2016-01-24
  • 2020-07-28
  • 2020-06-19
  • 1970-01-01
  • 2017-10-03
  • 1970-01-01
相关资源
最近更新 更多