我正在使用 cv.glmnet()
进行交叉验证,默认情况下是 10折
library(Matrix)library(tm)library(glmnet)library(e1071)library(SparseM)library(ggplot2)trainingData <- read.csv("train.csv", stringsAsFactors=FALSE,sep=",", header = FALSE)testingData <- read.csv("test.csv",sep=",", stringsAsFactors=FALSE, header = FALSE)x = model.matrix(as.factor(V42)~.-1, data = trainingData)crossVal <- cv.glmnet(x=x, y=trainingData$V42, family="multinomial", alpha=1)plot(crossVal)
我遇到了以下错误信息
Error in lognet(x, is.sparse, ix, jx, y, weights, offset, alpha, nobs, : one multinomial or binomial class has 1 or 0 observations; not allowed
但如下面所示,我似乎没有观察值的计数为 0
或 1
的情况。
>table(trainingData$V42) back buffer_overflow ftp_write guess_passwd imap ipsweep land loadmodule multihop 956 30 8 53 11 3599 18 9 7 neptune nmap normal perl phf pod portsweep rootkit satan 41214 1493 67343 3 4 201 2931 10 3633 smurf spy teardrop warezclient warezmaster 2646 2 892 890 20
有什么建议吗?
回答:
cv.glmnet
默认情况下进行N折交叉验证,N=10。这意味着它将数据分成10个子集,然后在其中的9个子集上训练模型,并在剩下的1个子集上进行测试。它会重复这个过程,依次排除每个子集。
你的数据足够稀疏,以至于有时训练子集会遇到这里遇到的问题(以及在你之前的问题中)。最好的解决方案是通过合并较少见的类别来减少响应中的类别数量(例如,你真的需要为 spy
或 perl
获得预测概率吗)。
另外,如果你在进行glmnet交叉验证并构建模型矩阵,你可以使用我编写的glmnetUtils包来简化这个过程。