通过文档提取tf-idf顶级功能的正确方法是什么?

时间:2019-12-03 00:27:32

标签: r quanteda

假设我们有一个10k相当小的文档集的tf-idf加权dfm。

提取quanteda的主要特征(即,按文档提取最大tf-idf值)的方法是什么? 我确实希望整个语料库在计算tf-idf时作为参考。类似于

topfeatures(some_dfm_tf_idf, n =3, decreasing = TRUE, groups ="id")

返回适当的列表。但是,到目前为止,已经基本解决了一些问题需要花费一些时间。鉴于到目前为止,Quanteda在所有工作中的表现都非常出色,我怀疑自己在这里可能做错了什么。

也许这与github(https://github.com/quanteda/quanteda/issues/1646)上的讨论以及@Astelix显示的示例解决方法有些相关。

3 个答案:

答案 0 :(得分:1)

topfeatures()就是正确的选择。我不确定您为什么要说明它“需要花费一些时间”或您的“ id” docvar是什么,但是以下是获取dfm中得分最高的功能的正确且最有效的方法(不管权重如何。

结果是一个命名列表,其中名称是docname,每个元素是一个命名数字矢量,其中元素名称是功能标签。

library("quanteda")
## Package version: 1.5.2

some_dfm_tf_idf <- dfm(data_corpus_irishbudget2010)[1:5, ] %>%
  dfm_tfidf()

topfeatures(some_dfm_tf_idf, n = 1, groups = docnames(some_dfm_tf_idf))
## $`Lenihan, Brian (FF)`
## details 
## 5.57116 
## 
## $`Bruton, Richard (FG)`
## confront 
##  5.59176 
## 
## $`Burton, Joan (LAB)`
## lenihan 
## 4.19382 
## 
## $`Morgan, Arthur (SF)`
##    sinn 
## 5.59176 
## 
## $`Cowen, Brian (FF)`
## dividend 
##  4.19382

答案 1 :(得分:1)

topfeatures()有点慢,因为它会对每个功能进行排序,然后返回最高值。仅获取每个文档中最有价值的功能的更有效方法是使用max.col。这是方法和比较(将返回值放入与topfeatures()答案相同格式的列表中。)

library("quanteda")
## Package version: 1.5.2

data(data_corpus_sotu, package = "quanteda.corpora")
dfmat <- dfm(data_corpus_sotu) %>%
  dfm_tfidf()

# alternative using max.col
get_top_feature <- function(x) {
  topfeature_index <- max.col(x, "first")
  result <- mapply(function(a, b) {
    l <- as.numeric(x[a, b])
    names(l) <- featnames(x)[b]
    l
  },
  seq_len(ndoc(x)), topfeature_index,
  SIMPLIFY = FALSE
  )
  names(result) <- docnames(x)
  result
}

microbenchmark::microbenchmark(
  topfeatures = topfeatures(dfmat, n = 1, groups = docnames(dfmat)),
  maxcol = get_top_feature(dfmat),
  times = 20, unit = "relative"
)
## Unit: relative
##         expr      min       lq     mean   median       uq      max neval
##  topfeatures 2.085184 2.113136 2.069444 2.104166 2.032536 1.987218    20
##       maxcol 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000    20

答案 2 :(得分:0)

除了 Ken 的 get_top_feature() 之外,您可能不仅对“顶级”术语感兴趣,还可能对 tfidf-dtm 中具有第二高权重的术语感兴趣。我花了一些时间才弄明白,所以我认为它总体上可能会有所帮助。

get_scnd_feature <- function(x) {
topfeature_index <- max.col(x, 'first')
scndfeature_index <- max.col(replace(x, cbind(seq_len(nrow(x)), topfeature_index), -Inf), 'first')
  result <- mapply(function(a, b) {
    l <- as.numeric(x[a, b])
    names(l) <- featnames(x)[b]
    l
  },
  seq_len(ndoc(x)), scndfeature_index,
  SIMPLIFY = FALSE
  )
  names(result) <- docnames(x)
  result
}
scndterm_tfidf <- get_scnd_feature(dtmtfidf)

您可以通过比较权重来检查结果:

maxn <- function(n) function(x) order(x, decreasing = TRUE)[n]
scndtermcount <- apply(dtmtfidf, 1, function(x)x[maxn(2)(x)])