在R中查找多个术语的findAssocs

时间:2013-05-30 12:21:40

标签: r text-mining term-document-matrix

在R中,我使用[tm package][1]从文档语料库中构建术语 - 文档矩阵。

我的目标是从术语文档矩阵中的所有双字母组合中提取单词关联,并为每个前三个或一些返回。因此,我正在寻找一个包含矩阵中所有ro​​w.names的变量,以便函数findAssocs()可以完成他的工作。

到目前为止,这是我的代码:

library(tm)
library(RWeka)
txtData <- read.csv("file.csv", header = T, sep = ",")
txtCorpus <- Corpus(VectorSource(txtData$text))

...further preprocessing

#Tokenizer for n-grams and passed on to the term-document matrix constructor
BigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
txtTdmBi <- TermDocumentMatrix(txtCorpus, control = list(tokenize = BigramTokenizer))

#term argument holds two words since the BigramTokenizer extracted all pairs from txtCorpus
findAssocs(txtTdmBi, "cat shop", 0.5)
cat cabi  cat scratch  ...
    0.96         0.91

我尝试使用txtTdmBi中的所有row.names定义变量,并将其提供给findAssocs()函数。但是,结果如下:

allRows <- c(row.names(txtTdmBi))
findAssocs(txtTdmBi, allRows, 0.5)
Error in which(x[term, ] > corlimit) : subscript out of bounds
In addition: Warning message:
In term == Terms(x) :
  longer object length is not a multiple of shorter object length

由于已经解释了在多个术语 - 文档矩阵上花费的术语的提取关联here,我想可以在单个术语 - 文档矩阵中找到多个术语的关联。除了怎么样?

我希望有人能告诉我如何解决这个问题。提前感谢您的支持。

1 个答案:

答案 0 :(得分:6)

如果我理解正确,lapply解决方案可能是回答您问题的方法。这与您链接的答案相同,但这是一个可能更接近您的用例的自包含示例:

加载库和可重现的数据(请在此处将这些内容包含在此处)

library(tm)
library(RWeka)
data(crude)

你的bigram tokenizer ......

#Tokenizer for n-grams and passed on to the term-document matrix constructor
BigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
txtTdmBi <- TermDocumentMatrix(crude, control = list(tokenize = BigramTokenizer))

通过检查随机样本检查它是否有效......

inspect(txtTdmBi[1000:1005, 10:15])
A term-document matrix (6 terms, 6 documents)

Non-/sparse entries: 1/35
Sparsity           : 97%
Maximal term length: 18 
Weighting          : term frequency (tf)

                    Docs
Terms                248 273 349 352 353 368
  for their            0   0   0   0   0   0
  for west             0   0   0   0   0   0
  forced it            0   0   0   0   0   0
  forced to            0   0   0   0   0   0
  forces trying        1   0   0   0   0   0
  foreign investment   0   0   0   0   0   0

以下是您问题的答案:

现在使用lapply函数计算术语 - 文档矩阵中术语向量中每个项目的关联词。最简单地使用txtTdmBi$dimnames$Terms访问术语向量。例如,txtTdmBi$dimnames$Terms[[1005]]是&#34;外国投资&#34;。

我在这里使用了llply套餐中的plyr,因此我们可以设置一个进度条(对于大型工作感到满意),但它与基本{基本相同} { {1}}功能。

lapply

输出是一个列表,其中列表中的每个项目都是命名数字的向量,其中名称是术语,数字是相关值。例如,要查看与&#34;外国投资相关的条款&#34;,我们可以像这样访问列表:

library(plyr)
dat <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocs(txtTdmBi, i, 0.5), .progress = "text" )

以下是与该术语相关的术语(我刚刚粘贴在前几名中)

dat[[1005]]

这就是你想要做的吗?

顺便提一下,如果您的术语 - 文档矩阵非常大,您可能需要尝试此版本的168 million 1986 was 1987 early 300 mln 31 pct 1.00 1.00 1.00 1.00 1.00 a bit a crossroads a leading a political a population 1.00 1.00 1.00 1.00 1.00 a reduced a series a slightly about zero activity continues 1.00 1.00 1.00 1.00 1.00 advisers are agricultural sector agriculture the all such also reviews 1.00 1.00 1.00 1.00 1.00 and advisers and attract and imports and liberalised and steel 1.00 1.00 1.00 1.00 1.00 and trade and virtual announced since appears to are equally 1.00 1.00 1.00 1.00 1.00 are recommending areas for areas of as it as steps 1.00 1.00 1.00 1.00 1.00 asia with asian member assesses indonesia attract new balance of 1.00 1.00 1.00 1.00 1.00

findAssocs

这可以这样使用:

# u is a term document matrix
# term is your term
# corlimit is a value -1 to 1

findAssocsBig <- function(u, term, corlimit){
  suppressWarnings(x.cor <-  gamlr::corr(t(u[ !u$dimnames$Terms == term, ]),        
                                         as.matrix(t(u[  u$dimnames$Terms == term, ]))  ))  
  x <- sort(round(x.cor[(x.cor[, term] > corlimit), ], 2), decreasing = TRUE)
  return(x)
}

这样做的好处是它使用了一种将TDM转换为矩阵dat1 <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocsBig(txtTdmBi, i, 0.5), .progress = "text" ) 的不同方法。这种不同的方法更有效地使用内存,因此可以防止出现此类消息:tm:findAssocs

快速基准测试显示两个Error: cannot allocate vector of size 1.9 Gb函数的速度大致相同,因此主要区别在于内存的使用:

findAssocs