如何在R中将每个单词出现表示为单独的tcm向量?

时间:2018-10-23 17:00:33

标签: r sparse-matrix quanteda tidytext text2vec

我正在寻找一种效率的方法来为语料库中的(每个)目标单词创建一个词共现矩阵,以便该单词的每次出现都将构成其自己的向量(行)在tcm中,其中的列是上下文词(即,基于令牌的共现模型)。这与矢量语义中使用的更常见的方法形成对比,在矢量语义中,每个术语(类型)在对称tcm中获得一行和一列,并且值在类型的令牌的(共)出现时聚合。

很明显,这可以使用base R功能从头开始,或者通过过滤由执行该操作的现有程序包之一生成的tcm进行破解,但是我要处理的语料库数据相当大(数百万个字)-并且已经有不错的R语料库/ NLP软件包,可以高效地执行此类任务并将结果存储在内存友好的稀疏矩阵中,例如text2vec(函数tcm),quanteda({{ 1}})和整洁文本(fcm)。因此,尝试重新发明轮子似乎没有任何意义(就迭代器,哈希和诸如此类而言)。但是我无法找到一种直接的方法来创建基于令牌的tcm。因此这个问题。

最小示例:

cast_dtm

针对目标单词“ short”,尝试获取基于令牌的模型:

  library(text2vec)
  library(Matrix)
  library(magrittr)

  # default approach to tcm with text2vec:
  corpus = strsplit(c("here is a short document", "here is a different short document"), " ")
  it = itoken(corpus) 
  tcm = create_vocabulary(it)  %>% vocab_vectorizer() %>% create_tcm(it, . , skip_grams_window = 2, weights = rep(1,2))

  # results in this:
  print(as.matrix(forceSymmetric(tcm, "U")))

            different here short document is a
  different         0    0     1        1  1 1
  here              0    0     0        0  2 2
  short             1    0     0        2  1 2
  document          1    0     2        0  0 1
  is                1    2     1        0  0 2
  a                 1    2     2        1  2 0

像上一个示例一样,有什么更好/更快的方法来替代基于令牌的tcm? (可能使用已经进行过基于类型的tcms的R软件包之一)

1 个答案:

答案 0 :(得分:1)

quanteda 的fcm是一种非常有效的方法,可以在文档级别或用户定义的上下文中创建特征同现矩阵。这导致稀疏,对称的逐特征矩阵。但这听起来好像您希望每个独特功能都成为自己的行,并在其周围加上目标词。

从示例中可以看出,您需要一个+/- 2个单词的上下文窗口,因此我已经为目标单词“ short”完成了此操作。

首先,我们使用上下文关键字获得上下文:

library("quanteda")
txt <- c("here is a short document", "here is a different short document")

(shortkwic <- kwic(txt, "short", window = 2))
#                                          
# [text1, 4]        is a | short | document
# [text2, 5] a different | short | document

然后根据上下文创建一个语料库,并将关键字作为唯一的文档名称:

shortcorp <- corpus(shortkwic, split_context = FALSE, extract_keyword = TRUE)
docnames(shortcorp) <- make.unique(docvars(shortcorp, "keyword"))
texts(shortcorp)
#                 short                      short.1 
# "is a short document" "a different short document" 

然后创建一个dfm,选择所有单词,但删除目标:

dfm(shortcorp) %>%
  dfm_select(dfm(txt)) %>%
  dfm_remove("short")
# Document-feature matrix of: 2 documents, 5 features (40% sparse).
# 2 x 5 sparse Matrix of class "dfm"
#          features
# docs      here is a document different
#   short      0  1 1        1         0
#   short.1    0  0 1        1         1