Функция Stemming для text2vec

я использую text2vec в R и испытываю трудности с написанием функции stemming, которая работает с функцией itoken в пакете text2vec. Документация text2vec предлагает эту функцию stemming:

stem_tokenizer1 =function(x) {
  word_tokenizer(x) %>% lapply(SnowballC::wordStem(language='en'))
 }

однако эта функция не работает. Это код, который я запустил (заимствованный из предыдущих ответов stackoverflow):

library(text2vec)
library(data.table)
library(SnowballC)
data("movie_review")
train_rows = 1:1000
prepr = tolower
stem_tokenizer1 =function(x) {
  word_tokenizer(x) %>% lapply(SnowballC::wordStem(language='en'))
 }
tok = stem_tokenizer1
it <- itoken(movie_review$review[train_rows], prepr, tok, ids = movie_review$id[train_rows])

это ошибка, которую он производит:

ошибка в {: аргумент "words" отсутствует, без по умолчанию

Я считаю, что проблема в том, что wordStem нуждается в символьном векторе, но word_tokenizer создает список символьных векторов.

mr<-movie_review$review[1]
stem_mr1<-stem_tokenizer1(mr)

ошибка в SnowballC:: wordStem (language = " en") : аргумент "words" отсутствует, без значения по умолчанию

чтобы исправить эту проблему, я написал эту функцию stemming:

stem_tokenizer2 = function(x)  {
  list(unlist(word_tokenizer(x)) %>% SnowballC::wordStem(language='en') )
}

однако эта функция не работает с функцией create_vocabulary.

data("movie_review")
train_rows = 1:1000
prepr = tolower
stem_tokenizer2 = function(x)  {
  list(unlist(word_tokenizer(x)) %>% SnowballC::wordStem(language='en') )
}
tok = stem_tokenizer2
it <- itoken(movie_review$review[train_rows], prepr, tok, ids = movie_review$id[train_rows])
v <- create_vocabulary(it) %>% prune_vocabulary(term_count_min = 5)

нет ошибка, но когда вы смотрите на количество документов, количество документов отличается от 1000 в данных, и поэтому вы не можете создать матрицу терминов документа или запустить LDA.

v$document_count

[1] 10

этот код:

dtm_train <- create_dtm(it, vectorizer)
dtm_train

произведите эту ошибку:

10 x 3809 разреженная Матрица класса " dgCMatrix" Ошибка в validObject (x) : недопустимый объект класса "dgCMatrix": length (Dimnames[1]) отличается от Dim[1], который 10

мои вопросы: что-то не так с функцией, которую я написал, и почему функция, которую я написал, вызывает эту ошибку с create_vocabulary? Я подозреваю, что это проблема с форматом вывода моей функции, но он выглядит идентично выходному формату функции word_tokenizer, и это отлично работает с itoken и create_vocabulary:

mr<-movie_review$review[1]
word_mr<-word_tokenizer(mr)
stem_mr<-stem_tokenizer2(mr)
str(word_mr)
str(stem_mr)

1 ответов


Спасибо за использование text2vec и сообщить о проблеме. В документах есть ошибка (можете ли вы указать мне, где я помещаю этот пример, чтобы я мог это исправить?). Stem tokenizer должен выглядеть так:

stem_tokenizer1 =function(x) {
  word_tokenizer(x) %>% lapply( function(x) SnowballC::wordStem(x, language="en"))
 }

логика следующая:

  1. это займет векторный характер и разметить его. Вывод список символьные векторы (каждый элемент списка = символьный вектор является документом).
  2. затем мы применяем stemming к каждому элементу списка (wordStem может быть применен на вектор символов)

итак, была моя синтаксическая ошибка для lapply в примере вы следовали. Mb будет более ясно, если мы перепишем его без %>% оператор в простом R, поэтому он будет выглядеть так:

stem_tokenizer1 =function(x) {
  tokens = word_tokenizer(x)
  lapply(tokens, SnowballC::wordStem, language="en")
}

Я также объясню, почему вы получаете 10 документов вместо 1000. По умолчанию text2vec::itoken разделить данные на 10 кусков (это можно настроить в itoken функция) и обрабатывать его кусок за куском. Поэтому, когда вы применяете unlist на каждом куске вы на самом деле рекурсивно распакуйте 100 документов и создайте 1 символьный вектор.