在DFM中,每个唯一标签仅保留最高频率项

问题描述

我的问题涉及到基于现有知识(通常每个文档中只有1个术语对确定正确的标签才有意义)来修剪/选择dfm中的术语。有多种用于修剪或选择的工具,但是似乎没有一种工具可以满足我的需要,因为它们似乎没有考虑到生成标签。如果我想重新发明轮子,请引导我采取正确的方法,否则,这是一个小数据集,其中包含我要使用的术语列表的解释,以便获取我的用语清单(然后我可以应用使用dfm_select到起始dfm)

启动dfm如下所示(为简单起见,使用data.frame)。 t1 ... t6是出现项的名称,每个频率为1或0

# A tibble: 4,859 x 5
   industry             SIC   time      employees    earnings
   <chr>                <chr> <yearmon>     <dbl>       <dbl>
 1 Mining and quarrying 2     Sep 2009     487132 16448188825
 2 Mining and quarrying 2     Dec 2009     487745 17510873008
 3 Mining and quarrying 2     Mar 2010     490847 17149708859
 4 Mining and quarrying 2     Jun 2010     496710 17603372833
 5 Mining and quarrying 2     Sep 2010     505244 19129235237
 6 Mining and quarrying 2     Dec 2010     504067 19696688896
 7 Mining and quarrying 2     Mar 2011     511433 19567627283
 8 Mining and quarrying 2     Jun 2011     517104 20444707224
 9 Mining and quarrying 2     Sep 2011     518719 21593220480
10 Mining and quarrying 2     Dec 2011     518240 24878861928
# ... with 4,849 more rows

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

my_dfm <- data.frame(t1=c(0,1,0),t2=c(0,t3=c(1,t4=c(0,t5=c(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

我要申请修整dfm的规则是,对于每个唯一标签{a,b},仅选择足够的唯一术语以确保每个文档{1..6}至少具有1个匹配术语,并优先考虑这些术语每组文档中出现次数最多的术语。因此,在此示例中,对于标签 a b ,总计看起来像这样

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

在这一点上,我需要确定哪些术语满足规则。标签a的t3满足所有三个文档,标签b的t4和t5组合满足三个文档。

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

重叠的“保持”向量看起来像这样:

# a_keep
c(0,0)
# 0 0 1 0 0
#
# b_keep
c(0,1)
# 0 0 0 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,1,0),t2 = c(0,t3 = c(1,t4 = c(0,t5 = c(1,1)
))
dfmat$labels <- c("a","a","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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...