Построение матрицы терминов-документов с конкретными токенами (и всеми остальными)

Я пытаюсь создать матрицу терминов-документов, в которой перечислены все униграммы в корпусе, но также извлекается определенный список биграмм. Так, например, в предложении «используйте свой сигнал поворота» будут перечислены «использовать», «ваш» и «указатель поворота».

В документации предоставленный образец токенизатора:

strsplit_space_tokenizer <- function(x) unlist(strsplit(as.character(x), "[[:space:]]+"))

Любые идеи о том, как написать токенизатор, который находит заданный вектор биграмм и возвращает остальные в виде униграмм?

Спасибо!


r tm
person atgreenwood    schedule 15.07.2014    source источник


Ответы (2)


Вот возможная стратегия. По сути, вы можете пропустить текст, найти свои биграммы и заменить их чем-то, что не будет разбиваться на пробелы (здесь я использую «{0}», где фактическое число — это индекс биграммы в списке). Затем я разделяю строку, затем прохожу и заменяю значения "{0}" значением биграммы. Например, вот функция, которая построит токенизатор со списком биграмм

getBigramTokenizer <- function(bigrams=character(0)) {
    force(bigrams)
    return(function(x) {
        x <- Reduce(function(a,b) 
            gsub(bigrams[b],paste0("{",b,"}"),a, fixed=T), 
            seq_along(bigrams), x)
        x <- unlist(strsplit(as.character(x), "[[:space:]]+"))
        m<-regexec("\\{(\\d+)\\}", x)
        i<-which(sapply(m, '[', 1) != -1)
        mi<-sapply(regmatches(x,m)[i], '[', 2)
        x[i]<-bigrams[as.numeric(mi)]
        x
     })
}

Теперь мы можем использовать его с

bigrams <- c("turn signal", "back seat", "buckle up")
tk <- getBigramTokenizer(bigrams)

tk("use your turn signal")
# [1] "use"         "your"        "turn signal"

tk("please buckle up in the back seat")
# [1] "please"    "buckle up" "in"        "the"       "back seat"
person MrFlick    schedule 16.07.2014
comment
Фантастический! Я не думал об идентификации биграмм перед разделением строки. Спасибо за идею! - person atgreenwood; 16.07.2014

Если я правильно понимаю, то и здесь может помочь qdap версии 2.1.1:

library(tm)
library(qdap)

## the bigrams
bigrams <- c("turn signal", "back seat", "buckle up")

## fake data (MWE)
dat <- data.frame(docs=paste0("doc", 1:5), 
    state=c("use your turn signal",
        "please buckle up in the back seat",
        "buckle up for safety",
        "Sit in the back seat",
        "here it is"
    )
)

## make data into a Corpus
myCorp <- as.Corpus(dat$state, dat$docs)

myDF <- as.data.frame(myCorp)
f <- sub_holder(bigrams, myDF$text)
tdm <- as.tdm(f$output, myDF$docs)
rownames(tdm) <- f$unhold(rownames(tdm))
inspect(tdm)

##              Docs
## Terms         doc1 doc2 doc3 doc4 doc5
##   for            0    0    1    0    0
##   here           0    0    0    0    1
##   in             0    1    0    1    0
##   is             0    0    0    0    1
##   it             0    0    0    0    1
##   please         0    1    0    0    0
##   turn signal    1    0    0    0    0
##   back seat      0    1    0    1    0
##   buckle up      0    1    1    0    0
##   safety         0    0    1    0    0
##   sit            0    0    0    1    0
##   the            0    1    0    1    0
##   use            1    0    0    0    0
##   your           1    0    0    0    0
person Tyler Rinker    schedule 07.08.2014