按文档提取 tf-idf topfeatures 的正确方法是什么?
What's the correct way to extract tf-idf topfeatures by document?
假设我们有一个来自 10K 相当小文档的语料库的 tf-idf 加权 dfm。
quanteda
提取顶级特征(即文档的最大 tf-idf 值)的方法是什么?
我确实希望整个语料库成为计算 tf-idf 时的参考。类似于
topfeatures(some_dfm_tf_idf, n =3, decreasing = TRUE, groups ="id")
returns 一个适当的列表。然而,这时基本上已经整理好的东西需要相当长的时间。鉴于 quanteda 在我迄今为止所做的一切中都表现得如此出色,我怀疑我在这里可能做错了什么。
也许这与关于 github (https://github.com/quanteda/quanteda/issues/1646) 的讨论和 @Astelix 显示的示例解决方法有关。
topfeatures()
正是要走的路。我不确定你为什么要说它 "takes quite some time",或者你的 "id" docvar 是什么,但以下是获取 dfm 中得分最高的功能列表的正确且最有效的方法(不考虑权重)。
结果是一个命名列表,其中名称是文档名,每个元素是一个命名数值向量,其中元素名称是特征标签。
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
topfeatures()
有点慢,因为它对每个特征进行排序,然后 return 是最高值。获取每个文档中最有价值的特征的更有效方法是使用 max.col
。这是方法和比较(将 return 放在与 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
除了 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)])
假设我们有一个来自 10K 相当小文档的语料库的 tf-idf 加权 dfm。
quanteda
提取顶级特征(即文档的最大 tf-idf 值)的方法是什么?
我确实希望整个语料库成为计算 tf-idf 时的参考。类似于
topfeatures(some_dfm_tf_idf, n =3, decreasing = TRUE, groups ="id")
returns 一个适当的列表。然而,这时基本上已经整理好的东西需要相当长的时间。鉴于 quanteda 在我迄今为止所做的一切中都表现得如此出色,我怀疑我在这里可能做错了什么。
也许这与关于 github (https://github.com/quanteda/quanteda/issues/1646) 的讨论和 @Astelix 显示的示例解决方法有关。
topfeatures()
正是要走的路。我不确定你为什么要说它 "takes quite some time",或者你的 "id" docvar 是什么,但以下是获取 dfm 中得分最高的功能列表的正确且最有效的方法(不考虑权重)。
结果是一个命名列表,其中名称是文档名,每个元素是一个命名数值向量,其中元素名称是特征标签。
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
topfeatures()
有点慢,因为它对每个特征进行排序,然后 return 是最高值。获取每个文档中最有价值的特征的更有效方法是使用 max.col
。这是方法和比较(将 return 放在与 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
除了 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)])