Идентификация и группировка синонимов в R

Я пытаюсь определить и агрегировать синонимы для данного набора данных. См. примеры данных ниже.

library(tm)
library(SnowballC)

dataset <- c("dad glad accept large admit large accept dad big large big accept big accept dad dad Happy dad accept glad papa dad Happy dad glad dad dad papa admit Happy big accept accept big accept dad Happy admit Happy Happy glad Happy dad accept accept large daddy large accept large large large big daddy accept admit dad admit daddy dad admit dad admit Happy accept accept Happy daddy accept admit")

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

Результат:

accept    dad  happy  admit  large    big  daddy   glad   papa 
    15     14      9      8      8      6      4      4      2 

Я хотел бы найти синонимы для каждого из приведенных выше слов, используя пакет wordnet, который я скачал и установил. Например, чтобы получить синоним «принять», я могу сделать:

library(wordnet)
setDict("C:/Program Files (x86)/WordNet/2.1/dict")

filter <- getTermFilter("ExactMatchFilter", "accept", TRUE)
terms <- getIndexTerms("VERB", 1, filter)
getSynonyms(terms[[1]])

Результат:

 [1] "accept"    "admit"     "assume"    "bear"      "consent"   "go for"    "have"      "live with"
 [9] "swallow"   "take"      "take on"   "take over"

Теперь я хотел бы объединить эти два набора результатов, чтобы группировать синонимы следующим образом. Отметьте наиболее распространенные слова (ранг 1) для данной группы и сгруппируйте по этим словам позже, как это:

id  word    word_count  syn_group   rank
1   accept  15          1           1
5   admit   8           1           2
2   dad     14          2           1
8   daddy   4           2           2
9   papa    2           2           3
3   happy   9           3           1
7   glad    4           3           2
4   large   8           4           1
6   big     6           4           2

тогда это можно было бы агрегировать следующим образом

id  word    word_count
1   accept  15+8
2   dad     14+4+2
3   happy   9+4
4   large   8+6

и окончательный результат будет тогда

id  word    word_count
1   accept  23
2   dad     20
3   large   14
4   happy   13

Я столкнулся с несколькими проблемами, включая получение GetIndexTerms для циклического перебора слов, независимо от того, являются ли они существительными, глаголами и т. д. Надеюсь, все это имеет смысл? Любая помощь приветствуется. Спасибо.


person GraveDigger    schedule 22.02.2017    source источник
comment
К вашему сведению: перейдите на сайт Wordnet.princeton.edu и загрузите версию WordNet для вашей операционной системы. После того, как вы его установите, вы можете получить код GraveDigger после библиотеки (wordnet).   -  person lawyeR    schedule 30.05.2017


Ответы (1)


Мы можем сделать следующее, используя dplyr

library(dplyr)
df %>% 
  group_by(syn_group) %>%
  mutate(sum_word_count = sum(word_count)) %>% 
  filter(rank == 1)

Данные:

df <- read.table(text = "id  word    word_count  syn_group   rank
1   accept  15          1           1
5   admit   8           1           2
2   dad     14          2           1
8   daddy   4           2           2
9   papa    2           2           3
3   happy   9           3           1
7   glad    4           3           2
4   large   8           4           1
6   big     6           4           2", header = T)

Пожалуйста, в следующий раз опубликуйте вывод dput.

Изменить. Ниже приведен код, который поможет вам начать перебор слов и частей речи и сохранение синонимов. Остается определить, является ли текущий термин синонимом предыдущего, и в этом случае у вас уже есть синонимы, и вы можете назначить уникальную сингруппу. Далее вам нужно сохранить некоторые результаты. Наконец, вам нужно вычислить ранг, который состоит всего лишь из seq_along синонимов и grep для определения позиции в ранге. Комментарии являются намеками на то, где вы можете включить код для этих советов.

d <- data.frame(Term = row.names(m), word_count = m[,1])
all_pos <- c("ADJECTIVE", "ADVERB", "NOUN","VERB")
syns <- vector("list", length(all_pos))
for(w in seq(nrow(d))){
  # if sysns of (d$Term[w]) has been calculated skip over current w 
  emf <- getTermFilter("ExactMatchFilter", d$Term[w], TRUE)  
  for(i in seq_along(syns)){
    terms <- getIndexTerms(all_pos[i], 1, emf)
    if(is.null(terms)){
      syns[i] <- NA
    } else{
      syns[[i]] <-  getSynonyms(terms[[1]])
    }
  }
  # store the results of syns for current w 
}
person shayaa    schedule 22.02.2017
comment
Спасибо за ваш ответ. Проблема в том, что у меня нет этой таблицы (см. ваш комментарий), вот что я пытаюсь придумать. Все, что у меня есть, это вектор символов с кучей слов и доступом к wordnet. Любое другое предложение? Еще раз спасибо! - person GraveDigger; 23.02.2017
comment
@GraveDigger, отредактировано, чтобы включить достаточно информации, чтобы помочь вам решить эту проблему. - person shayaa; 23.02.2017
comment
Спасибо!! Я новичок в R, поэтому не понимаю всего, что вы сделали, мне нужно будет потратить некоторое время на выяснение того, что вы сделали и почему. - person GraveDigger; 01.03.2017