在 DFM 中仅保留每个唯一标签的最高频率术语

Keep only highest frequency term per unique label in DFM

我的问题涉及基于先验知识的 quanteda dfm 中的 trimming/selecting 个术语,每个文档中通常只有 1 个术语对确定正确的标签很重要。有多种用于修剪或选择的工具,但 none 似乎可以满足我的需要,因为它们似乎没有考虑生成的标签。如果我想重新发明轮子,请指导我采用正确的方法,否则这里有一个小数据集,其中包含我想使用的机制的解释,以便获得我的术语列表(然后我可以应用使用 dfm_select)

到起始 dfm

启动 dfm 看起来像这样(data.frame 为简单起见)。 t1...t6 是出现项的名称,每个频率为 1 或 0

my_dfm <- data.frame(t1=c(0,0,0,1,0,0), t2=c(0,1,1,0,0,0), t3=c(1,1,1,0,0,0), t4=c(0,0,1,1,1,0),t5=c(1,0,0,0,1,1))
my_dfm

#    t1 t2 t3 t4 t5
#  1  0  0  1  0  1
#  2  0  1  1  0  0
#  3  0  1  1  1  0
#  4  1  0  0  1  0
#  5  0  0  0  1  1
#  6  0  0  0  0  1

标签不会分组,但为了清楚起见,在本示例中将标签分组在一起

my_labels <- data.frame(my_labels=c('a','a','a','b','b','b'))
my_labels
#   my_labels
# 1         a
# 2         a
# 3         a
# 4         b
# 5         b
# 6         b

我要申请修剪我的dfm的规则是,对于每个唯一标签{a,b},只选择足够的唯一术语以确保每个文档{1..6}至少有1个匹配术语,对每组文档中出现次数最多的术语进行优先排序。所以在这个例子中,对于标签 ab,总数看起来像这样

# a freq totals
c(0,2,3,1,1)
# 0 2 3 1 1
#
# b freq totals
c(1,0,0,2,2)
# 1 0 0 2 2

此时我需要确定哪些条款满足规则。对于标签a,t3满足所有三个文档,对于标签b,t4和t5合起来满足对应的3个文档

# a_keep
c(0,0,1,0,0)
# 0 0 1 0 0
#
# b_keep
c(0,0,0,1,1)
# 0 0 0 1 1

重叠的“保持”向量如下所示:

# keep
c(0,0,1,1,1)
# 0 0 1 1 1

所以我现在可以将其应用到我的 dfm 并且只保留 t3、t4、t5

我可以通过几个循环看到执行此操作的方法,但尚未尝试过。逻辑:对于每个标签,计算术语频率。然后从最高总术语开始检查每个文档是否都被考虑在内,如果没有,则添加下一个最高频率术语等等,直到所有文档都被考虑在内。然后保留组合的术语集)。不过,我想要的是发现实际上已经有一个 dfm 函数可以做到这一点,或者是一种比我在描述的逻辑中设想的代码更简单的方法

有趣的问题:您想将文档频率最高的特征保留在组内。我会通过按组拆分 dfm,然后使用具有排名文档频率过滤的非常通用的 dfm_trim() 函数来做到这一点。

要将您的 dfm 设置为 dfm,并添加文档变量:

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

# set up dfm
dfmat <- as.dfm(data.frame(
  t1 = c(0, 0, 0, 1, 0, 0),
  t2 = c(0, 1, 1, 0, 0, 0),
  t3 = c(1, 1, 1, 0, 0, 0),
  t4 = c(0, 0, 1, 1, 1, 0),
  t5 = c(1, 0, 0, 0, 1, 1)
))
dfmat$labels <- c("a", "a", "a", "b", "b", "b")

现在将 dfm 拆分到各组中,并选择排名最高的那些。 (要更改此设置,请更改 min_docfreq 值。)

# chooses the top document frequency by group
tokeep <- lapply(unique(dfmat$labels), function(x) {
  dfm_subset(dfmat, labels == x) %>%
    dfm_trim(min_docfreq = 1, docfreq_type = "rank")
})

结果按组显示,使用 rbind() 很容易重新组合。

tokeep
## [[1]]
## Document-feature matrix of: 3 documents, 1 feature (0.0% sparse) and 1 docvar.
##     features
## docs t3
##    1  1
##    2  1
##    3  1
## 
## [[2]]
## Document-feature matrix of: 3 documents, 2 features (33.3% sparse) and 1 docvar.
##     features
## docs t4 t5
##    4  1  0
##    5  1  1
##    6  0  1

# make back into a single dfm
do.call(rbind, tokeep)
## Document-feature matrix of: 6 documents, 3 features (61.1% sparse).
##     features
## docs t3 t4 t5
##    1  1  0  0
##    2  1  0  0
##    3  1  0  0
##    4  0  1  0
##    5  0  1  1
##    6  0  0  1