我使用tm包进行修复数据的文本分析,将数据读入数据框,转换为Corpus对象,应用各种方法使用lower,stipWhitespace,removestopwords等清理数据。
取回用于stemCompletion的Corpus对象。
使用tm_map函数执行的stemDocument,我的对象词被阻止了
得到了预期的结果。
当我使用tm_map函数运行stemCompletion操作时,它无法正常工作 并得到以下错误
UseMethod中出错(“words”):'words'没有适用的方法 应用于“character”类的对象
执行trackback()以显示并获得以下步骤
> traceback()
9: FUN(X[[1L]], ...)
8: lapply(dictionary, words)
7: unlist(lapply(dictionary, words))
6: unique(unlist(lapply(dictionary, words)))
5: FUN(X[[1L]], ...)
4: lapply(X, FUN, ...)
3: mclapply(content(x), FUN, ...)
2: tm_map.VCorpus(c, stemCompletion, dictionary = c_orig)
1: tm_map(c, stemCompletion, dictionary = c_orig)
如何解决此错误?
答案 0 :(得分:6)
使用tm v0.6时收到了同样的错误。我怀疑这是因为stemCompletion
不在此版本的tm包的默认转换中:
> getTransformations
function ()
c("removeNumbers", "removePunctuation", "removeWords", "stemDocument",
"stripWhitespace")
<environment: namespace:tm>
现在,tolower
函数存在同样的问题,但可以使用content_transformer
函数使其运行。我为stemCompletion
尝试了类似的方法,但没有成功。
注意,即使stemCompletion
不是默认转换,但在手动输入词干时它仍然有效:
> stemCompletion("compani",dictCorpus)
compani
"companies"
为了能够继续我的工作,我通过单个空格手动分隔语料库中的每个文档,通过stemCompletion
提供它们,并将它们与以下(笨重且不优雅!)函数连接在一起:
stemCompletion_mod <- function(x,dict=dictCorpus) {
PlainTextDocument(stripWhitespace(paste(stemCompletion(unlist(strsplit(as.character(x)," ")),dictionary=dict, type="shortest"),sep="", collapse=" ")))
}
其中dictCorpus
只是清理过的语料库的副本,但在它被阻止之前。额外的stripWhitespace
特定于我的语料库,但对于一般语料库来说可能是良性的。您可能需要根据需要从“最短”更改type
选项。
举一个完整的例子,让我们使用tm包中的crude
数据设置一个虚拟语料库:
> data("crude")
> docs = Corpus(VectorSource(crude))
> docs <- tm_map(docs, content_transformer(tolower))
> docs <- tm_map(docs, removeNumbers)
> docs <- tm_map(docs, removeWords, stopwords("english"))
> docs <- tm_map(docs, removePunctuation)
> docs <- tm_map(docs, stripWhitespace)
> docs <- tm_map(docs, PlainTextDocument)
> dictCorpus <- docs
> docs <- tm_map(docs, stemDocument)
> # Define modified stemCompletion function
> stemCompletion_mod <- function(x,dict=dictCorpus) {
PlainTextDocument(stripWhitespace(paste(stemCompletion(unlist(strsplit(as.character(x)," ")),dictionary=dict, type="shortest"),sep="", collapse=" ")))
}
> # Original doc in crude data
> crude[[1]]
<<PlainTextDocument (metadata: 15)>>
Diamond Shamrock Corp said that
effective today it had cut its contract prices for crude oil by
1.50 dlrs a barrel.
The reduction brings its posted price for West Texas
Intermediate to 16.00 dlrs a barrel, the copany said.
"The price reduction today was made in the light of falling
oil product prices and a weak crude oil market," a company
spokeswoman said.
Diamond is the latest in a line of U.S. oil companies that
have cut its contract, or posted, prices over the last two days
citing weak oil markets.
Reuter
> # Stemmed example in crude data
> docs[[1]]
<<PlainTextDocument (metadata: 7)>>
diamond shamrock corp said effect today cut contract price crude oil dlrs barrel
reduct bring post price west texa intermedi dlrs barrel copani said price reduct today
made light fall oil product price weak crude oil market compani spokeswoman said diamond
latest line us oil compani cut contract post price last two day cite weak oil market reuter
> # Stem comlpeted example in crude data
> stemCompletion_mod(docs[[1]],dictCorpus)
<<PlainTextDocument (metadata: 7)>>
diamond shamrock corp said effect today cut contract price crude oil dlrs barrel
reduction brings posted price west texas intermediate dlrs barrel NA said price reduction today
made light fall oil product price weak crude oil market companies spokeswoman said diamond
latest line us oil companies cut contract posted price last two day cited weak oil market reuter
注意:这个例子很奇怪,因为拼写错误的单词“copany”被映射: - &gt; “copani” - &gt; “NA”,在这个过程中。不知道如何纠正这个......
要在整个语料库中运行stemCompletion_mod
,我只使用sapply
(或parSapply
雪包)。
也许比我更有经验的人可以提出一个更简单的修改,让stemCompletion
在tm包的v0.6中工作。
答案 1 :(得分:5)
我在以下工作流程中取得了成功:
content_transformer
对语料库的每个文档应用匿名函数stemCompletion
字样,paste
再次将单独的单词连接到文档中。POC演示代码:
tm_map(c, content_transformer(function(x, d)
paste(stemCompletion(strsplit(stemDocument(x), ' ')[[1]], d), collapse = ' ')), d)
PS:由于c
base::c
作为变量名来存储语料库不是一个好主意
答案 2 :(得分:5)
谢谢,cdxsza。你的方法适合我。
所有将要使用
stemCompletion
的人员的说明:该函数使用字典中的单词完成一个空字符串,这是意外的。请参阅下面的示例,其中第一个&#34;星期一&#34;是在字符串开头的空白处产生的。
stemCompletion(unlist(strsplit(" mond tues ", " ")), dict=c("monday", "tuesday"))
[1] "monday" "monday" "tuesday"
可以通过删除
""
之前的空字符stemCompletion
轻松修复,如下所示。
stemCompletion2 <- function(x, dictionary) {
x <- unlist(strsplit(as.character(x), " "))
x <- x[x != ""]
x <- stemCompletion(x, dictionary=dictionary)
x <- paste(x, sep="", collapse=" ")
PlainTextDocument(stripWhitespace(x))
}
myCorpus <- lapply(myCorpus, stemCompletion2, dictionary=myCorpusCopy)
myCorpus <- Corpus(VectorSource(myCorpus))
请参阅幻灯片第12页的详细示例 http://www.rdatamining.com/docs/RDataMining-slides-text-mining.pdf
此致
赵延昌RdataMining.com
答案 3 :(得分:3)
问题在于使用tolower
(例如myCorpus <- tm_map(myCorpus, tolower)
)会将文本转换为简单字符值,tm
版本0.6不接受与tm_map
一起使用。< / p>
如果你改为做这样的原始tolower
myCorpus <- tm_map(myCorpus, content_transformer(tolower))
然后,当您需要stemCompletion
时,数据将采用正确的格式。
removePunctuation
和removeNumbers
等其他功能照常使用tm_map
,即没有content_transformer
。