2015-11-27 3 views
2

У меня есть большой фреймворк, в котором я идентифицирую шаблоны в строках, а затем извлекаю их. Я привел небольшое подмножество, чтобы проиллюстрировать мою задачу. Я создаю свои шаблоны, создавая TermDocumentMatrix с несколькими словами. Я использую эти шаблоны с stri_extract и str_replace из пакетов stringi и stringr для поиска в кадре данных punct_prob.R Как сохранить знаки препинания с помощью TermDocumentMatrix()

Моя проблема в том, что мне нужно держать пунктуацию в такте в «punct_prob $ description», чтобы поддерживать буквальные значения внутри каждой строки. Например, я не могу иметь 2,35 мм, становясь 235 мм. Тем не менее, процедура TermDocumentMatrix, которую я использую, удаляет пунктуацию (или, по крайней мере, периоды), и поэтому мои функции поиска шаблона не могут их сопоставить.

Вкратце ... как я могу хранить знаки препинания при создании TDM? Я попытался включить removePunctuation = FALSE в аргумент управления TermDocumentMatrix, но без успеха.

library(tm) 
punct_prob = data.frame(description = tolower(c("CONTRA ANGLE HEAD 2:1 FOR 2.35mm BUR", 
            "TITANIUM LINE MINI P.B F.O. TRIP SPRAY", 
            "TITANIUM LINE POWER P. B F.O. TRIP SPR", 
            "MEDESY SPECIAL ITEM"))) 

punct_prob$description = as.character(punct_prob$description) 

# a control for the number of words in phrases 
max_ngram = max(sapply(strsplit(punct_prob$description, " "), length)) 

#set up ngrams and tdm 
BigramTokenizer <- function(x) {RWeka::NGramTokenizer(x, RWeka::Weka_control(min = max_ngram, max = max_ngram))} 
punct_prob_corpus = Corpus(VectorSource(punct_prob$description)) 
punct_prob_tdm <- TermDocumentMatrix(punct_prob_corpus, control = list(tokenize = BigramTokenizer, removePunctuation=FALSE)) 
inspect(punct_prob_tdm) 

проверять результаты - без пунктуации ....

        Docs 
Terms        1 2 3 4 
    angle head 2 1 for 2 35mm bur 1 0 0 0 
    contra angle head 2 1 for 2 35mm 1 0 0 0 
    line mini p b f o trip spray  0 1 0 0 
    line power p b f o trip spr  0 0 1 0 
    titanium line mini p b f o trip 0 1 0 0 
    titanium line power p b f o trip 0 0 1 0 

Спасибо за любую помощь заранее :)

ответ

3

Проблема не столько termdocumentmatrix, но базируется Ngram токенизатор на RWEKA. Rweka удаляет пунктуации при выполнении токенизации.

Если вы используете токенизатор nlp, он сохраняет знаки препинания. См. Код ниже.

P.S. Я удалил одно место в вашей третьей текстовой строке, так что P. B. является P.B. как он находится на линии 2.

library(tm) 
punct_prob = data.frame(description = tolower(c("CONTRA ANGLE HEAD 2:1 FOR 2.35mm BUR", 
               "TITANIUM LINE MINI P.B F.O. TRIP SPRAY", 
               "TITANIUM LINE POWER P.B F.O. TRIP SPR", 
               "MEDESY SPECIAL ITEM"))) 
punct_prob$description = as.character(punct_prob$description) 

max_ngram = max(sapply(strsplit(punct_prob$description, " "), length)) 

punct_prob_corpus = Corpus(VectorSource(punct_prob$description)) 




NLPBigramTokenizer <- function(x) { 
    unlist(lapply(ngrams(words(x), max_ngram), paste, collapse = " "), use.names = FALSE) 
} 


punct_prob_tdm <- TermDocumentMatrix(punct_prob_corpus, control = list(tokenize = NLPBigramTokenizer)) 
inspect(punct_prob_tdm) 

<<TermDocumentMatrix (terms: 3, documents: 4)>> 
Non-/sparse entries: 3/9 
Sparsity   : 75% 
Maximal term length: 38 
Weighting   : term frequency (tf) 

             Docs 
Terms         1 2 3 4 
    contra angle head 2:1 for 2.35mm bur 1 0 0 0 
    titanium line mini p.b f.o. trip spray 0 1 0 0 
    titanium line power p.b f.o. trip spr 0 0 1 0 
+0

Спасибо @piver - отлично работает! – CallumH

1

quanteda пакет достаточно умен, чтобы tokenise без обработки внутри слова символы пунктуации как «знаки препинания». Это делает очень легко строить вашу матрицу:

txt <- c("CONTRA ANGLE HEAD 2:1 FOR 2.35mm BUR", 
     "TITANIUM LINE MINI P.B F.O. TRIP SPRAY", 
     "TITANIUM LINE POWER P.B F.O. TRIP SPR", 
     "MEDESY SPECIAL ITEM") 

require(quanteda) 
myDfm <- dfm(txt, ngrams = 6:8, concatenator = " ") 
t(myDfm) 
#          docs 
# features        text1 text2 text3 text4 
# contra angle head for 2.35mm bur   1  0  0  0 
# titanium line mini p.b f.o trip   0  1  0  0 
# line mini p.b f.o trip spray    0  1  0  0 
# titanium line mini p.b f.o trip spray  0  1  0  0 
# titanium line power p.b f.o trip   0  0  1  0 
# line power p.b f.o trip spr    0  0  1  0 
# titanium line power p.b f.o trip spr  0  0  1  0 

Если вы хотите сохранить «знаки препинания», он будет tokenised как отдельный знак, когда заканчивается срок:

myDfm2 <- dfm(txt, ngrams = 8, concatenator = " ", removePunct = FALSE) 
t(myDfm2) 
#           docs 
# features         text1 text2 text3 text4 
# titanium line mini p.b f.o . trip spray  0  1  0  0 
# titanium line power p.b f.o . trip spr  0  0  1  0 

Отметим здесь, что ngrams аргумент полностью гибкий и может принимать вектор размеров ngram, как в первом примере, где ngrams = 6:8 указывает, что он должен образовывать 6-, 7- и 8-граммы.

+0

Спасибо @Ken. Я собираюсь поиграть с этим в ближайшее время. Мне нравится идея переменной длины ngram, которая является одной из причин, по которой я обратился к маркеру RWeka в первую очередь. – CallumH

 Смежные вопросы

  • Нет связанных вопросов^_^