11

假设我有基于文本的训练数据和测试数据。更具体地说,我有两个数据集——训练和测试——它们都有一个包含文本的列,并且对手头的工作很感兴趣。

我使用 R 中的 tm 包来处理训练数据集中的文本列。在删除空格、标点符号和停用词之后,我对语料库进行词干处理,最后创建了一个 1 克的文档术语矩阵,其中包含每个文档中单词的频率/计数。然后,我采用了预先确定的截止值,例如 50,并且只保留那些计数大于 50 的术语。

在此之后,我使用 DTM 和因变量(存在于训练数据中)训练了一个 GLMNET 模型。到目前为止,一切都顺利而轻松。

但是,当我想根据测试数据或未来可能出现的任何新数据对模型进行评分/预测时,我该如何进行?

具体来说,我想找出的是如何在新数据上创建确切的 DTM?

如果新数据集没有任何与原始训练数据相似的单词,那么所有术语的计数都应该为零(这很好)。但我希望能够在任何新语料库上复制完全相同的 DTM(就结构而言)。

有什么想法/想法吗?

4

2 回答 2

16

tm有很多陷阱...查看更有效的text2vec矢量化小插图,它们完全回答了这个问题。

因为tm这里可能是为第二个语料库重建 DTM 矩阵的一种更简单的方法:

crude2.dtm <- DocumentTermMatrix(crude2, control = list
               (dictionary=Terms(crude1.dtm), wordLengths = c(3,10)) )
于 2013-12-27T14:35:08.333 回答
11

如果我理解正确,您已经制作了一个 dtm,并且您想从与第一个 dtm 具有相同列(即术语)的新文档中制作一个新的 dtm。如果是这种情况,那么应该通过第一个中的条款对第二个 dtm 进行子设置,可能是这样的:

首先设置一些可重现的数据...

这是你的训练数据...

library(tm)
# make corpus for text mining (data comes from package, for reproducibility) 
data("crude")
corpus1 <- Corpus(VectorSource(crude[1:10]))    
# process text (your methods may differ)
skipWords <- function(x) removeWords(x, stopwords("english"))
funcs <- list(tolower, removePunctuation, removeNumbers,
              stripWhitespace, skipWords)
crude1 <- tm_map(corpus1, FUN = tm_reduce, tmFuns = funcs)
crude1.dtm <- DocumentTermMatrix(crude1, control = list(wordLengths = c(3,10))) 

这是你的测试数据...

corpus2 <- Corpus(VectorSource(crude[15:20]))  
# process text (your methods may differ)
skipWords <- function(x) removeWords(x, stopwords("english"))
funcs <- list(tolower, removePunctuation, removeNumbers,
              stripWhitespace, skipWords)
crude2 <- tm_map(corpus2, FUN = tm_reduce, tmFuns = funcs)
crude2.dtm <- DocumentTermMatrix(crude2, control = list(wordLengths = c(3,10))) 

这是做你想做的事:

现在我们只保留训练数据中存在的测试数据中的术语......

# convert to matrices for subsetting
crude1.dtm.mat <- as.matrix(crude1.dtm) # training
crude2.dtm.mat <- as.matrix(crude2.dtm) # testing

# subset testing data by colnames (ie. terms) or training data
xx <- data.frame(crude2.dtm.mat[,intersect(colnames(crude2.dtm.mat),
                                           colnames(crude1.dtm.mat))])

最后将训练数据中不在测试数据中的术语的所有空列添加到测试数据中......

# make an empty data frame with the colnames of the training data
yy <- read.table(textConnection(""), col.names = colnames(crude1.dtm.mat),
                 colClasses = "integer")

# add incols of NAs for terms absent in the 
# testing data but present # in the training data
# following SchaunW's suggestion in the comments above
library(plyr)
zz <- rbind.fill(xx, yy)

测试文档的数据框也是如此zz,但与训练文档具有相同的结构(即相同的列,尽管其中许多包含 NA,如 SchaunW 所述)。

这符合你想要的吗?

于 2013-05-20T05:55:16.313 回答