Текстовый майнинг с помощью tm-пакета - слово stemming

Я делаю текстовый майнинг в R с tm-package. Все работает очень гладко. Тем не менее, одна проблема возникает после stemming ( http://en.wikipedia.org/wiki/Stemming). Очевидно, что есть некоторые слова, которые имеют одинаковую основу, но важно, чтобы они не были "объединены" (так как эти слова означают разные вещи).

Для примера см. 4 текста ниже. Здесь вы не можете использовать "лектор" или "лекция" ("ассоциация" и "ассоциировать") взаимозаменяемо. Однако это то, что делается на шаге 4.

Есть ли какое-нибудь элегантное решение, как реализовать это для некоторых случаев / слов вручную (например, что "лектор" и "лекция" хранятся как две разные вещи)?

texts <- c("i am member of the XYZ association",
"apply for our open associate position", 
"xyz memorial lecture takes place on wednesday", 
"vote for the most popular lecturer")

# Step 1: Create corpus
corpus <- Corpus(DataframeSource(data.frame(texts)))

# Step 2: Keep a copy of corpus to use later as a dictionary for stem completion
corpus.copy <- corpus

# Step 3: Stem words in the corpus
corpus.temp <- tm_map(corpus, stemDocument, language = "english")  

inspect(corpus.temp)

# Step 4: Complete the stems to their original form
corpus.final <- tm_map(corpus.temp, stemCompletion, dictionary = corpus.copy)  

inspect(corpus.final)

2 ответа

Решение

Я не на 100% то, что вы после, и не совсем понимаю, как tm_map работает. Если я понимаю, то работает следующее. Насколько я понимаю, вы хотите предоставить список слов, которые не должны быть основаны. Я использую пакет qdap главным образом потому, что я ленивый, и у него есть функция mgsub Мне нравится.

Обратите внимание, что я разочаровался в использовании mgsub а также tm_map как он продолжал выбрасывать ошибку, поэтому я просто использовал lapply вместо.

texts <- c("i am member of the XYZ association",
    "apply for our open associate position", 
    "xyz memorial lecture takes place on wednesday", 
    "vote for the most popular lecturer")

library(tm)
# Step 1: Create corpus
corpus.copy <- corpus <- Corpus(DataframeSource(data.frame(texts)))

library(qdap)
# Step 2: list to retain and indentifier keys
retain <- c("lecturer", "lecture")
replace <- paste(seq_len(length(retain)), "SPECIAL_WORD", sep="_")

# Step 3: sub the words you want to retain with identifier keys
corpus[seq_len(length(corpus))] <- lapply(corpus, mgsub, pattern=retain, replacement=replace)

# Step 4: Stem it
corpus.temp <- tm_map(corpus, stemDocument, language = "english")  

# Step 5: reverse -> sub the identifier keys with the words you want to retain
corpus.temp[seq_len(length(corpus.temp))] <- lapply(corpus.temp, mgsub, pattern=replace, replacement=retain)

inspect(corpus)       #inspect the pieces for the folks playing along at home
inspect(corpus.copy)
inspect(corpus.temp)

# Step 6: complete the stem
corpus.final <- tm_map(corpus.temp, stemCompletion, dictionary = corpus.copy)  
inspect(corpus.final)

В основном это работает:

  1. Подстановка уникального ключа идентификатора для поставляемых слов "НЕТ СТАВКИ" (mgsub)
  2. тогда вы остановитесь (используя stemDocument)
  3. затем вы переворачиваете его и добавляете ключи идентификатора со словами "NO STEM" (mgsub)
  4. последний завершить ствол (stemCompletion)

Вот вывод:

## >     inspect(corpus.final)
## A corpus with 4 text documents
## 
## The metadata consists of 2 tag-value pairs and a data frame
## Available tags are:
##   create_date creator 
## Available variables in the data frame are:
##   MetaID 
## 
## $`1`
## i am member of the XYZ associate
## 
## $`2`
##  for our open associate position
## 
## $`3`
## xyz memorial lecture takes place on wednesday
## 
## $`4`
## vote for the most popular lecturer

Вы также можете использовать следующий пакет для изучения слов: https://cran.r-project.org/web/packages/SnowballC/SnowballC.pdf.

Вам просто нужно использовать функцию wordStem, передавая вектор слов, которые должны быть основаны, а также язык, с которым вы имеете дело. Чтобы узнать, какую именно языковую строку вам нужно использовать, вы можете обратиться к методу getStemLanguages, который вернет все возможные варианты для него.

С уважением

Другие вопросы по тегам