Я проверял некоторые данные и заметил, что когда я использую 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 не подходит для этого?
Во-первых, ваше регулярное выражение будет захватывать только «время», в то время как ваш код quanteda преобразует все в нижний регистр, поэтому он включает «время» и «время» (и так далее). Это вполне может быть причиной дополнительных подсчетов. Вы можете попробовать tolower = FALSE и посмотреть, что получится.
Возможны две причины.
Grepl() учитывает только TRUE, если совпадение происходит один раз в документе (или символьном элементе вектора Comments). textstat_frequency() подсчитывает токен каждый раз, когда он появляется. Это одна из вероятных причин, по которой последний насчитывает больше экземпляров, чем первый.
У вас есть вхождения «время» в верхнем регистре в вашем текстовом поле, которые не соответствуют тому, как вы используете 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() определенно подходит для этого.
Интересные подходы. Причина, по которой я спрашиваю, заключается в том, что я создал блестящее приложение, которое будет отображать textstat_frequency, а затем, используя plotly, вы можете щелкнуть термин, и этот щелчок сработает DT:::DataTable, и используя щелчок в качестве входных данных для поиска, чтобы вы могли получить kwic подобное представление все комментарии с этим поисковым запросом. Возможно, сейчас нет отличного способа сделать это, учитывая ограничения функции поиска с данными сюжетных событий.
Есть несколько причин, по которым это может произойти. Без данных очень сложно сказать. Есть ли небольшое его подмножество, на которое вы можете нацелиться и поделиться здесь, где есть разница?