支持向量机适用于训练集,但不适用于 R 中的测试集(使用 e1071)

Posted

技术标签:

【中文标题】支持向量机适用于训练集,但不适用于 R 中的测试集(使用 e1071)【英文标题】:Support Vector Machine works on Training-set but not on Test-set in R (using e1071) 【发布时间】:2014-04-04 15:35:36 【问题描述】:

我正在为我的文档分类任务使用支持向量机!它对训练集中的所有文章进行了分类,但未能对我的测试集中的文章进行分类! trainDTM 是我的训练集的文档术语矩阵。 testDTM 是用于测试集的。 这是我的(不太漂亮)代码:

# create data.frame with labelled sentences

labeled <- as.data.frame(read.xlsx("C:\\Users\\LABELED.xlsx", 1, header=T))

# create training set and test set
traindata <- as.data.frame(labeled[1:700,c("ARTICLE","CLASS")])
testdata <- as.data.frame(labeled[701:1000, c("ARTICLE","CLASS")])

# Vector, Source Transformation
trainvector <- as.vector(traindata$"ARTICLE")
testvector <- as.vector(testdata$"ARTICLE")
trainsource <- VectorSource(trainvector)
testsource <- VectorSource(testvector)

# CREATE CORPUS FOR DATA
traincorpus <- Corpus(trainsource)
testcorpus <- Corpus(testsource)

# my own stopwords
sw <- c("i", "me", "my")

## CLEAN TEXT

# FUNCTION FOR CLEANING
cleanCorpus <- function(corpus)
  corpus.tmp <- tm_map(corpus, removePunctuation)
  corpus.tmp <- tm_map(corpus.tmp,stripWhitespace)
  corpus.tmp <- tm_map(corpus.tmp,tolower)
  corpus.tmp <- tm_map(corpus.tmp, removeWords, sw)
  corpus.tmp <- tm_map(corpus.tmp, removeNumbers)
  corpus.tmp <- tm_map(corpus.tmp, stemDocument, language="en")
  return(corpus.tmp)

# CLEAN CORP WITH ABOVE FUNCTION
traincorpus.cln <- cleanCorpus(traincorpus)
testcorpus.cln <- cleanCorpus(testcorpus)

## CREATE N-GRAM DOCUMENT TERM MATRIX 
# CREATE N-GRAM TOKENIZER

BigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 1, max = 1))

# CREATE DTM
trainmatrix.cln.bi <- DocumentTermMatrix(traincorpus.cln, control = list(tokenize = BigramTokenizer))
testmatrix.cln.bi <- DocumentTermMatrix(testcorpus.cln, control = list(tokenize = BigramTokenizer))

# REMOVE SPARSE TERMS
trainDTM <- removeSparseTerms(trainmatrix.cln.bi, 0.98)
testDTM <- removeSparseTerms(testmatrix.cln.bi, 0.98)

# train the model
SVM <- svm(as.matrix(trainDTM), as.factor(traindata$CLASS))

# get classifications for training-set
results.train <- predict(SVM, as.matrix(trainDTM)) # works fine!

# get classifications for test-set
results <- predict(SVM,as.matrix(testDTM))

Error in scale.default(newdata[, object$scaled, drop = FALSE], center = object$x.scale$"scaled:center",  : 
  length of 'center' must equal the number of columns of 'x'

我不明白这个错误。什么是“中心”?

谢谢!!

【问题讨论】:

为什么你认为这是过拟合的问题?即使模型过度拟合,我也应该能够对新数据进行分类.. 【参考方案1】:

训练和测试数据必须在同一个特征空间;以这种方式构建两个单独的 DTM 是行不通的。

使用 RTextTools 的解决方案:

DocTermMatrix <- create_matrix(labeled, language="english", removeNumbers=TRUE, stemWords=TRUE, ...)
container <- create_container(DocTermMatrix, labels, trainSize=1:700, testSize=701:1000, virgin=FALSE)
models <- train_models(container, "SVM")
results <- classify_models(container, models)

或者,要回答您的问题(使用 e1071),您可以在投影 (DocumentTermMatrix) 中指定词汇表(“特征”):

DocTermMatrixTrain <- DocumentTermMatrix(Corpus(VectorSource(trainDoc)));
Features <- DocTermMatrixTrain$dimnames$Terms;

DocTermMatrixTest <- DocumentTermMatrix(Corpus(VectorSource(testDoc)),control=list(dictionary=Features));

【讨论】:

我添加了完整的代码,所以你可以看到我是如何构建 TDM 的 @brobertie:感谢您的方法有效!我不太喜欢使用 RTextTools,因为我无法控制(或者我认为我无法控制)诸如停用词删除、否定处理、n-gram 等预处理步骤。顺便提一句。如果我使用朴素贝叶斯分类器,将文章分成两个单独的 TDM 似乎可行。但我无法以某种方式使用 SVM 使其工作。 @brobertie:你知道如何使用 e1071 构建 SVM 吗?

以上是关于支持向量机适用于训练集,但不适用于 R 中的测试集(使用 e1071)的主要内容,如果未能解决你的问题,请参考以下文章

R语言e1071包中的支持向量机:螺旋线型线性不可分数据集RBF核函数支持向量机SVM(验证模型在测试集上的表现可视化模型预测的结果添加超平面区域与原始数据标签进行对比分析)

第八篇:支持向量机 (SVM)

R语言e1071包中的支持向量机:仿真数据(螺旋线性不可分数据集)简单线性核的支持向量机SVM(模型在测试集上的表现可视化模型预测的结果添加超平面区域与原始数据标签进行对比分析)如何改进核函数

支持向量机

数据集必须包含 R 中 SVM 中的所有因素

机器学习 - 支持向量机