使用 tm 包,我有一个包含 10,900 个文档的语料库 (docs)。
docs = Corpus(VectorSource(abstracts$abstract))
我还有一个术语列表 (termslist) 及其所有同义词和不同的拼写。我用它来将每个同义词或拼写转换为一个术语。
Term, Synonyms
term1, synonym1
term1, synonym2
term1, synonym3
term2, synonym1
... etc
我现在的做法是遍历所有文档,另一个嵌套器循环遍历所有术语以查找和替换。
for (s in 1:length(docs)){
for (i in 1:nrow(termslist)){
docs[[s]]$content<-gsub(termslist[i,2], termslist[i,1], docs[[s]])
}
print(s)
}
目前,对于一个文档(termslist 中大约有 1000 行),这需要一秒钟,这意味着 10,900 秒,大约 6 小时!
一般在 tm 包或 R 中是否有更优化的方法来执行此操作?
更新:
mathematical.coffee 的回答实际上很有帮助。我不得不重新创建一个表,其中包含唯一术语作为行,第二列是用“|”分隔的同义词,然后循环遍历它们。现在所需的时间比以前少得多。
**创建新表的[乱七八糟]代码:
newtermslist<-list()
authname<-unique(termslist[,1])
newtermslist<- cbind(newtermslist,authname)
syns<-list()
for (i in seq(authname)){
syns<- rbind(syns,
paste0('(',
paste(termslist[which(termslist[,1]==authname[i]),2],collapse='|')
, ')')
)
}
newtermslist<-cbind(newtermslist,syns)
newtermslist<-cbind(unlist(newtermslist[,1]),unlist(newtermslist[,2]))
最佳答案
我认为当您希望执行多次替换时,这可能是唯一的方法(即按顺序将替换的输出保存为下一次替换的输入)。
但是,您可能会尝试获得一些速度(您必须进行一些基准测试才能进行比较):
- 使用
fixed=T
(因为你的同义词不是正则表达式而是文字拼写),useBytes=T
(**请参阅?gsub
- 如果您使用多字节语言环境,这可能是个好主意,也可能不是)。或者 - 压缩你的条款列表——如果
blue
有同义词cerulean
,cobalt
和sky
, 那么你的正则表达式可能是(cerulean|cobalt|sky)
替换blue
, 所以blue
的所有同义词在一次迭代中被替换,而不是在 3 个单独的迭代中。为此,您需要预处理您的术语列表 - 例如newtermslist <- ddply(terms, .(term), summarize, regex=paste0('(', paste(synonym, collapse='|'), ')'))
然后对此进行当前循环。你将有fixed=F
(默认,即使用正则表达式)。 - 另见
?tm_map
和?content_transformer
.我不确定这些是否会加快速度,但您可以试试。
(重新基准测试 - 尝试 library(rbenchmark); benchmark(expression1, expression2, ...)
,或者好的 ol' system.time
用于计时,Rprof
用于分析)
关于r - 寻找一种优化的方式来替换长文档中的列表模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31621620/