【问题标题】:Keep only highest frequency term per unique label in DFM在 DFM 中仅保留每个唯一标签的最高频率项
【发布时间】:2020-09-14 13:55:39
【问题描述】:

我的问题涉及根据先验知识在 quanteda dfm 中修剪/选择术语,通常每个文档中只有一个术语对于确定正确的标签很重要。有多种工具用于修剪或选择,但似乎没有一个能满足我的需要,因为它们似乎没有考虑到生成的标签。如果我想重新发明轮子,请指导我采用正确的方法,否则这里有一个小数据集,其中解释了我想使用的机制以获取我的术语列表(然后我可以应用使用 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 函数可以执行此操作,或者是一种更简单的方法,其代码比我在描述的逻辑中设想的更简单

【问题讨论】:

    标签: r quanteda


    【解决方案1】:

    有趣的问题:您希望将文档频率最高的特征保留在组内。我会通过按组拆分 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-02
      • 2018-04-02
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      相关资源
      最近更新 更多