R: найти ngram, используя dfm, когда в одном документе несколько предложений
У меня большой набор данных (>1 миллиона строк), и каждая строка представляет собой текст из нескольких предложений. Например, следующий пример из 2 строк:
mydat <- data.frame(text=c('I like apple. Me too','One two. Thank you'),stringsAsFactors = F)
То, что я пытался сделать, это извлечь термины биграммы в каждой строке ("." Сможет разделять термины ngram). Если я просто использую функцию dfm:
mydfm = dfm(mydat$text,toLower = T,removePunct = F,ngrams=2)
dtm = as.DocumentTermMatrix(mydfm)
txt_data = as.data.frame(as.matrix(dtm))
Вот условия, которые я получил:
"i_like" "like_apple" "apple_." "._me" "me_too" "one_two" "two_." "._thank" "thank_you"
Это то, что я ожидаю, в основном "." пропускается и используется для разделения терминов:
"i_like" "like_apple" "me_too" "one_two" "thank_you"
Поверьте, написание медленных циклов также может решить эту проблему, но, учитывая, что это огромный набор данных, я бы предпочел эффективные способы, аналогичные dfm() в quanteda, для решения этой проблемы. Мы ценим любые предложения!
2 ответа
Если ваша цель просто извлечь эти биграммы, то вы можете использовать tokens
дважды. Один раз токенизировать до предложений, затем снова составить нграммы для каждого предложения.
library("quanteda")
mydat$text %>%
tokens(mydat$text, what = "sentence") %>%
as.character() %>%
tokens(ngrams = 2, remove_punct = TRUE) %>%
as.character()
#[1] "I_like" "like_apple" "Me_too" "One_two" "Thank_you"
Вставьте tokens_tolower()
после первого tokens()
позвоните, если хотите, или используйте char_tolower()
в конце.
Ответ @Jota работает, но есть способ более точно контролировать токенизацию, вызывая ее только один раз:
(toks <- tokenize(toLower(mydat$text), removePunct = 2, ngrams = 2))
## tokenizedText object from 2 documents.
## Component 1 :
## [1] "i_like" "like_apple" "apple_me" "me_too"
##
## Component 2 :
## [1] "one_two" "two_thank" "thank_you"
dfm(toks)
## Document-feature matrix of: 2 documents, 7 features.
## 2 x 7 sparse Matrix of class "dfmSparse"
## features
## docs i_like like_apple apple_me me_too one_two two_thank thank_you
## text1 1 1 1 1 0 0 0
## text2 0 0 0 0 1 1 1
Добавлено:
Затем удалить любой Ngram с .
Вы можете использовать пунктуацию: следующее, по умолчанию valuetype = "glob"
:
removeFeatures(toks2, "*.*")
## tokenizedText object from 2 documents.
## Component 1 :
## [1] "i_like" "like_apple" "me_too"
##
## Component 2 :
## [1] "one_two" "thank_you"