for循环错误“尝试在R中选择少于一个元素”

时间:2016-02-27 03:59:24

标签: r for-loop vector svm

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

  

indeces.gen_error中的错误[[i]]< - paste(classification_error):
  尝试选择少于一个元素

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这是正确的,所以我不知道为什么它说我选择的不到一个元素。 任何帮助,将不胜感激。感谢

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

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
}

1 个答案:

答案 0 :(得分:2)

#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的元素。这没有意义。没有一半的位置。有第二或第三。尝试看看返回的内容。

在你的循环中,你要求R代表indeces.gen_error[[0.00001]]。因此,您要求的是1/100000位置。这没有意义。评估者将强制子集为整数。它转到0。我们得到一个错误。