2017-02-20 7 views
2

Спасибо, что нашли время, чтобы прочитать мое сообщение. Новичок здесь и здесь - это мой первый скрипт R с некоторыми примерами данных.Частота слов неточная после окончания текста

library(tm) 
library(hunspell) 
library(stringr) 

docs <- VCorpus(VectorSource('He is a nice player, She could be a better player. Playing basketball is fun. Well played! We could have played better. Wish we had better players!')) 

input <- strsplit(as.character(docs), " ") 
input <- unlist(input) 
input <- hunspell_stem(input) 
input <- word(input,-1) 

input <- VCorpus(VectorSource(input)) 
docs <- input 

docs <- tm_map(docs, content_transformer(tolower)) 
docs <- tm_map(docs, removeWords, stopwords("english")) 
docs <- tm_map(docs, removePunctuation) 
docs <- tm_map(docs, stripWhitespace) 

dtm <- TermDocumentMatrix(docs) 
m <- as.matrix(dtm) 
sort(rowSums(m),decreasing=TRUE) 

Это возвращает следующие результаты:

character0 48 лучше 3 играть 3 баскетбол 1 Описание 1
весело 1 головка 1 час 1 язык 1 мета- 1 мин 1 хороший 1 происхождения 1 хорошо 1 хотят 1 год 1

Ожидаемые результаты:

лучше 3 игра 3 баскетбола 1 забава 1 язык 1 хорошей 1 хорошо 1 желания 1

Не знаю, где эти слова приходят из (character0, описания, мета, языка и т.д.), и если есть способ Избавься от них?

В основном то, что я пытаюсь сделать, это применить на корпусе (таблице данных SQL-сервера источника данных) с помощью hunspell и отобразить их в облаке слов позже. Любая помощь будет оценена по достоинству. GD

+1

Если вы просматриваете свой код по строкам, вы видите, что 'input <- word (input, -1)' ломает вещи. 'hunspell_stem' возвращает структуру списка, где каждый элемент соответствует одному слову; однако он может вернуть более одного стебля для одного слова. Вы можете пропустить свою среднюю часть и сделать 'dtm <- TermDocumentMatrix (docs, control = list (stemming = function (x) sapply (hunspell_stem (x), tail, 1)))'. – lukeA

+0

Спасибо за помощь. Это хорошо работает для приведенного выше примера, но если я введу что-то еще, я получаю сообщение об ошибке ниже: 'library (tm) library (hunspell) docs <- VCorpus (VectorSource (« Спасибо lukeA за вашу помощь! »)) dtm <- TermDocumentMatrix (docs, control = list (stemming = function (x) sapply (hunspell_stem (x), tail, 1))) m <- as.matrix (dtm) sort (rowSums (m) , убывающее = TRUE) ' ' Ошибка в таблице (txt): все аргументы должны иметь одинаковую длину. Это потому, что ни одно из слов не имеет стеблей в строке? – GraveDigger

+0

Это потому, что нет стебля, возвращенного для lukea. Таким образом, вам нужно не только проверять наличие нескольких стеблей, но также и без каких-либо проблем, если вы настаиваете на hunspell. – lukeA

ответ

0

Вот почему пример ваш комментарий не удается:

library(tm) 
library(hunspell) 
hunspell_stem(strsplit('Thanks lukeA for your help!', "\\W")[[1]]) 
# [[1]] 
# [1] "thank" 
# 
# [[2]] 
# character(0) 
# 
# [[3]] 
# [1] "for" 
# 
# [[4]] 
# [1] "your" 
# 
# [[5]] 
# [1] "help" 

А вот один способ заставить его работать:

docs <- VCorpus(VectorSource('Thanks lukeA for your help!')) 
myStem <- function(x) { 
    res <- hunspell_stem(x) 
    idx <- which(lengths(res)==0) 
    if (length(idx)>0) 
    res[idx] <- x[idx] 
    sapply(res, tail, 1) 
} 
dtm <- TermDocumentMatrix(docs, control = list(stemming = myStem)) 
m <- as.matrix(dtm) 
sort(rowSums(m),decreasing=TRUE) 
    # for help! lukea thank your 
    # 1  1  1  1  1 

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

+0

Еще раз спасибо. Я действительно не понимаю, почему смена тестовой строки выше с помощью «теста» не удалась. Hunspell возвращает «t» в качестве стебля, поэтому я ожидаю, что «t» будет возвращено. Если бы у меня была «проверка» как строка, она бы работала нормально, так как вернувшийся стержень был «тестом». Любые идеи? Большое спасибо. – GraveDigger

+0

Функция возвращает последний стержень обоих стеблей «тест» и «т» («хвост»). Вы можете вернуть первый, используя 'head'. Тем не менее, «t» фильтруется фильтром длины слова по умолчанию.Вот почему он терпит неудачу. Вы можете сделать 'TermDocumentMatrix (docs, control = list (stemming = myStem, wordLengths = c (-Inf, Inf)))' отключить фильтрацию по длине слова. См. '? TermFreq'. – lukeA