问题描述
我的问题涉及到基于现有知识(通常每个文档中只有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