Создать матрицу сроков документа с N-граммами в R - PullRequest
0 голосов
/ 08 ноября 2018

Я использую пакет "tm" для создания DocumentTermMatrix в R. Он хорошо работает для одного грамма, но я пытаюсь создать DocumenttermMatrix из N-грамм (сейчас N = 3), используя пакет tm и функцию tokenize_ngrams из " токенизаторы ". Но я не могу его создать.

Я искал возможное решение, но мне не очень помогли. По соображениям конфиденциальности я не могу поделиться данными. Вот что я попробовал,

library(tm)  
library(tokenizers)

данные - это фрейм данных, содержащий около 4,5 тыс. Строк и 2 столбца, а именно «doc_id» и «текст»

data_corpus = Corpus(DataframeSource(data))

Пользовательская функция для токенизации n-грамм:

ngram_tokenizer = function(x){
  temp = tokenize_ngrams(x, n_min = 1, n = 3, stopwords = FALSE, ngram_delim = "_")
  return(temp)
}

контрольный список для создания DTM:
1 грамм

control_list_unigram = list(tokenize = "words",
                          removePunctuation = FALSE,
                          removeNumbers = FALSE, 
                          stopwords = stopwords("english"), 
                          tolower = T, 
                          stemming = T, 
                          weighting = function(x)
                            weightTf(x)
)

для токенизации N-грамм

control_list_ngram = list(tokenize = ngram_tokenizer,
                    removePunctuation = FALSE,
                    removeNumbers = FALSE, 
                    stopwords = stopwords("english"), 
                    tolower = T, 
                    stemming = T, 
                    weighting = function(x)
                      weightTf(x)
                    )


dtm_unigram = DocumentTermMatrix(data_corpus, control_list_unigram)
dtm_ngram = DocumentTermMatrix(data_cropus, control_list_ngram)

dim(dtm_unigram)
dim(dtm_ngram)

Размеры обоих ДТМ были одинаковыми.
Пожалуйста, поправьте меня!

1 Ответ

0 голосов
/ 09 ноября 2018

К сожалению, у tm есть некоторые причуды, которые раздражают и не всегда понятны.Во-первых, токенизация не работает на Corpera, созданной Corpus.Для этого вам нужно использовать VCorpus.

Так что измените строку data_corpus = Corpus(DataframeSource(data)) на data_corpus = VCorpus(DataframeSource(data)).

Это одна проблема, которая решается.Теперь корпус будет работать для токенизации, но теперь у вас возникнет проблема с tokenize_ngrams.Вы получите следующую ошибку:

Input must be a character vector of any length or a list of character
  vectors, each of which has a length of 1. 

при запуске этой строки: dtm_ngram = DocumentTermMatrix(data_cropus, control_list_ngram)

Чтобы решить эту проблему и не зависеть от пакета токенизатора, вы можете использовать следующеефункция для токенизации данных.

NLP_tokenizer <- function(x) {
  unlist(lapply(ngrams(words(x), 1:3), paste, collapse = "_"), use.names = FALSE)
}

Используется функция ngrams из пакета NLP, который загружается при загрузке пакета tm.1: 3 говорит ему создавать нграммы от 1 до 3 слов.Так что ваш control_list_ngram должен выглядеть так:

control_list_ngram = list(tokenize = NLP_tokenizer,
                          removePunctuation = FALSE,
                          removeNumbers = FALSE, 
                          stopwords = stopwords("english"), 
                          tolower = T, 
                          stemming = T, 
                          weighting = function(x)
                            weightTf(x)
                          )

Лично я бы использовал пакет quanteda для всей этой работы.Но сейчас это должно помочь вам.

...