grpel 和 quanteda 之间的不同频率计数 textstat_frequency

Differing frequency count between grpel and quanteda textstat_frequency

我正在验证一些数据,我注意到当我使用 grepl 搜索使用 sum(grepl('time',x = df$Comments)) 的术语时(其中 df 是一个简单的 data.frame,其中每一行包含不同的推文)并且我尝试使用

将其与 quanteda 包中的 textstat_frequency 进行比较
df %>% corpus(text_field='Comments') %>% dfm(tolower = T,
                                             remove = stop_words,
                                             remove_punct = T,
                                             remove_symbols = T,
                                             remove_numbers = T) %>% textstat_frequency()

我得到两个不同的结果

使用 grepl,我得到 2718,使用 quanteda,我得到:

 feature frequency rank docfreq group
  time      2879    1    2113   all

textstat_frequency 不是解决这个问题的方法吗?

可能有两个原因。

  1. grepl() 仅当在文档(或 Comments 向量的字符元素)中出现一次匹配时才计算 TRUEtextstat_frequency() 每次出现时都会对令牌进行计数。这可能是后者比前者计数更多的原因之一。

  2. 您的文本字段中出现大写的“时间”,这与您使用 grepl() 的方式不匹配,而默认情况下,dfm()tolower = TRUE 作为默认值。所以 textstat_frequency() 会计算大写字母的出现次数,而您使用 grepl() 则不会。但是,您可以使用 grepl(..., ignore.case = TRUE).

    更改此设置

示例:

txt <- c("This time is new.", "Time, time, time.", "Time is on our side.")

sum(grepl("time", txt))
## [1] 2
sum(grepl("time", txt, ignore.case = TRUE))
## [1] 3

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

dfm(txt) %>%
  textstat_frequency(n = 1)
##   feature frequency rank docfreq group
## 1    time         5    1       3   all

如果你想通过正则表达式类型的解决方案来匹配计数行为,你可以这样工作:

stringi::stri_extract_all_fixed(txt, "time", case_insensitive = TRUE) %>%
  unlist() %>%
  length()
## [1] 5

但这仍然有不考虑单词边界的缺点,因此仍然会将“sometime”算作“time”。另一方面,标记化和使用 textstat_frequency() 将考虑单词边界,因为它已对文本进行标记化,包括连接到标点符号的单词,如 time,"time".

所以 textstat_frequency() 绝对是解决这个问题的方法。