2016-12-02 12 views
0

От ответа Опубликовано: Хранить идентификатор документа с R корпуса по @MrFlickДержите ТОЧНЫЕ слова из R корпуса

Я пытаюсь немного изменить то, что является отличным примером.

Вопрос: Как модифицировать content_transformer функция держать только точные слова? Вы можете видеть в результатах проверки, что замечательный считается как чудо, а отношение считается обоснованным. Я не очень хорошо понимаю gregexpr и regmatches.

Создать фрейм данных:

dd <- data.frame(
    id = 10:13, 
    text = c("No wonderful, then, that ever", 
      "So that in many cases such a ", 
      "But there were still other and", 
      "Not even at the rationale") 
    , stringsAsFactors = F 
) 

Теперь для того, чтобы читать специальные атрибуты из data.frame, мы будем использовать функцию readTabular, чтобы сделать наш собственный читатель пользовательских data.frame

library(tm) 
myReader <- readTabular(mapping = list(content = "text", id = "id")) 

укажите столбец для содержимого и идентификатор в файле data.frame. Теперь мы читаем его с помощью DataframeSource, но используем наш пользовательский ридер.

tm <- VCorpus(DataframeSource(dd), readerControl = list(reader = myReader)) 

Теперь, если мы хотим сохранить только определенный набор слов, мы можем создать нашу собственную функцию content_transformer. Один из способов сделать это -

keepOnlyWords <- content_transformer(function(x, words) { 
     regmatches(x, 
      gregexpr(paste0("\\b(", paste(words, collapse = "|"), "\\b)"), x) 
     , invert = T) <- " " 
     x 
    }) 

Это заменит все, что находится в списке слов, пробелом. Обратите внимание, что после этого вы, вероятно, захотите запустить stripWhitespace. Таким образом, наши преобразования будут выглядеть

keep <- c("wonder", "then", "that", "the") 

tm <- tm_map(tm, content_transformer(tolower)) 
tm <- tm_map(tm, keepOnlyWords, keep) 
tm <- tm_map(tm, stripWhitespace) 

Проверьте Dtm матрицу:

> inspect(dtm) 
<<DocumentTermMatrix (documents: 4, terms: 4)>> 
Non-/sparse entries: 7/9 
Sparsity   : 56% 
Maximal term length: 6 
Weighting   : term frequency (tf) 

    Terms 
Docs ratio that the wonder 
    10  0 1 1  1 
    11  0 1 0  0 
    12  0 0 1  0 
    13  1 0 1  0 

ответ

1

Switching грамматик к tidytext, текущее преобразование будет

library(tidyverse) 
library(tidytext) 
library(stringr) 

dd %>% unnest_tokens(word, text) %>% 
    mutate(word = str_replace_all(word, setNames(keep, paste0('.*', keep, '.*')))) %>% 
    inner_join(data_frame(word = keep)) 

## id word 
## 1 10 wonder 
## 2 10 the 
## 3 10 that 
## 4 11 that 
## 5 12 the 
## 6 12 the 
## 7 13 the 

Сохраняя точные совпадения легче, как вы можете (которые используют ==) вместо регулярного выражения:

dd %>% unnest_tokens(word, text) %>% 
    inner_join(data_frame(word = keep)) 

## id word 
## 1 10 then 
## 2 10 that 
## 3 11 that 
## 4 13 the 

принять его обратно в документ долгосрочной матрицы,

library(tm) 

dd %>% mutate(id = factor(id)) %>% # to keep empty rows of DTM 
    unnest_tokens(word, text) %>% 
    inner_join(data_frame(word = keep)) %>% 
    mutate(i = 1) %>% 
    cast_dtm(id, word, i) %>% 
    inspect() 

## <<DocumentTermMatrix (documents: 4, terms: 3)>> 
## Non-/sparse entries: 4/8 
## Sparsity   : 67% 
## Maximal term length: 4 
## Weighting   : term frequency (tf) 
## 
##  Terms 
## Docs then that the 
## 10 1 1 0 
## 11 0 1 0 
## 12 0 0 0 
## 13 0 0 1 

В настоящее время ваша функция согласования words с границей, прежде чем или после. Для того, чтобы изменить его, прежде чем и после того, изменения параметра collapse включать границы:

tm <- VCorpus(DataframeSource(dd), readerControl = list(reader = myReader)) 

keepOnlyWords<-content_transformer(function(x,words) { 
     regmatches(x, 
      gregexpr(paste0("(\\b", paste(words, collapse = "\\b|\\b"), "\\b)"), x) 
     , invert = T) <- " " 
     x 
    }) 

tm <- tm_map(tm, content_transformer(tolower)) 
tm <- tm_map(tm, keepOnlyWords, keep) 
tm <- tm_map(tm, stripWhitespace) 

inspect(DocumentTermMatrix(tm)) 

## <<DocumentTermMatrix (documents: 4, terms: 3)>> 
## Non-/sparse entries: 4/8 
## Sparsity   : 67% 
## Maximal term length: 4 
## Weighting   : term frequency (tf) 
## 
##  Terms 
## Docs that the then 
## 10 1 0 1 
## 11 1 0 0 
## 12 0 0 0 
## 13 0 1 0 
+0

Спасибо за подробный ответ. прекрасно работает! @alistaire – BEMR

0

я получил тот же результат, как @alistaire с тм, со следующей модифицированной линии в keepOnlyWords трансформатора контента, определенного первым @BEMR:

gregexpr(paste0("\\b(", paste(words, collapse = "|"), ")\\b"), x) 

Был ошибочный «)» в gregexpr, впервые заданном @BEMR, т.е.должно быть «) \\ Ь» не «\\ б)»

Я думаю, что выше gregexpr эквивалентно тому, что указано @alistaire:

gregexpr(paste0("(\\b", paste(words, collapse = "\\b|\\b"), "\\b)"), x)