grpel 和 quanteda textstat_frequency

问题描述

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

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() 仅在文档​​(或 TRUE 向量的字符元素)中出现一次匹配时才计算 Commentstextstat_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

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

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

相关问答

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