stemCompletion无效

时间:2014-08-08 14:39:55

标签: tm

我使用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)

如何解决此错误?

4 个答案:

答案 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)

我在以下工作流程中取得了成功:

  1. 使用content_transformer对语料库的每个文档应用匿名函数
  2. 按空格将文档拆分为单词
  3. 在词典的帮助下调用stemCompletion字样,
  4. 并使用paste再次将单独的单词连接到文档中。
  5. 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时,数据将采用正确的格式。

removePunctuationremoveNumbers等其他功能照常使用tm_map,即没有content_transformer

参考:https://stackoverflow.com/a/24771621