R中多个术语的findAssocs

Posted

技术标签:

【中文标题】R中多个术语的findAssocs【英文标题】:findAssocs for multiple terms in R 【发布时间】:2013-05-26 00:28:40 【问题描述】:

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

我的目标是从术语文档矩阵中的 all 二元组中提取单词关联,并为每个前三个或一些返回。因此,我正在寻找一个包含矩阵中所有 row.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】:

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

加载库和可重现数据(请在此处将这些包含在您以后的问题中)

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

您的二元标记器...

#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]]就是“外资”。

这里我使用了plyr 包中的llply,所以我们可以有一个进度条(为大型工作提供便利),但它与基本lapply 函数基本相同。

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 cros-s-roads             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)

可以这样使用:

dat1 <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocsBig(txtTdmBi, i, 0.5), .progress = "text" )

这样做的好处是它使用不同的方法将 TDM 转换为矩阵tm:findAssocs。这种不同的方法更有效地使用内存,因此可以防止出现这种消息:Error: cannot allocate vector of size 1.9 Gb

快速基准测试表明findAssocs 两个函数的速度大致相同,因此主要区别在于内存的使用:

library(microbenchmark)
microbenchmark(
dat1 <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocsBig(txtTdmBi, i, 0.5)),
dat <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocs(txtTdmBi, i, 0.5)),
times = 10)

Unit: seconds
                                                                                     expr      min       lq   median
 dat1 <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocsBig(txtTdmBi,      i, 0.5)) 10.82369 11.03968 11.25492
     dat <- llply(txtTdmBi$dimnames$Terms, function(i) findAssocs(txtTdmBi,      i, 0.5)) 10.70980 10.85640 11.14156
       uq      max neval
 11.39326 11.89754    10
 11.18877 11.97978    10

【讨论】:

谢谢本!我设法在我的术语文档矩阵中找到了所有二元组的关联。但是,在变量dat 中,我将txtTdmBi$dimnames$Terms 替换为txtTdmBi,因为我一直收到错误消息:0%Error in UseMethod("findAssocs", x): no applicable method for 'findAssocs' applied to an object of class "character" 除了这个话题;您示例中的函数findAssocsBig 是一个很好的内存保存解决方案。一个人怎么能申请多个任期。还有lapply 方法? 感谢您发现这个错误,我已相应地更正了我的答案,并添加了您如何使用其他功能。

以上是关于R中多个术语的findAssocs的主要内容,如果未能解决你的问题,请参考以下文章

Solr突出显示多个术语

java术语(PO/POJO/VO/BO/DAO/DTO)

Java的常见术语(PO/POJO/VO/BO/DAO/DTO)

具有多个分类术语的 Drupal 8 实体查询

检测包含多个字符串的列表中的唯一术语

r 在甲基化年龄分析的背景下,展示拦截术语如何从抽样方法中调整估计偏差