Wordcloud из таблицы данных в R - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть таблица данных, составленная из положительных и отрицательных ассоциаций слов.Я хотел бы создать два облака слов, одно для положительных слов и одно для отрицательных слов.

Пример таблицы sentiment_words:

          element_id    sentence_id   negative     positive
1115:          1        1115          limits       agree,available
1116:          1        1116          slow         strongly,agree
1117:          1        1117                       management
1118:          1        1118                                      
1119:          1        1119          concerns     strongly,agree,better,

Я использую library(wordcloud) и library(sentimentr)

Например, как мне извлечь слова из «положительного» столбца, чтобы создать облако слов?Я не уверен, как решить тот факт, что с каждой строкой связано несколько слов (например, «согласен, доступно» следует рассматривать как две записи)

Я предпринял разные попытки для wordcloud() функция, такая как wordcloud(words = sentiment_words$positive, freq = 3, min.freq = 1, max.words = 200, random.order = FALSE, rot.per=0.35, colors=brewer.pal(8, "Dark2")), но она возвращает только облако с термином в первой записи

Редактировать: я попробовал ответ tidyverse ниже, и я получаю следующий результат: words n <chr> <int> 1 " \"ability\"" 3 2 " \"ability\")" 1 3 " \"acceptable\")" 1 4 " \"accomplish\"" 1 5 " \"accomplished\")" 1 6 " \"accountability\"" 1 7 " \"accountability\")" 1 8 " \"accountable\"" 2 9 " \"accountable\")" 1

Я пробовал умножить варианты gsub() и apply, чтобы удалить лишние ) и c(, но пока не нашел ничего, что работает.В результате слова, которые должны быть подсчитаны вместе, считаются отдельно (например, «приемлемый» и «приемлемый)» - это два разных слова в слове «облако»)

Редактировать: чтобы заставить его работать правильно, я имелсначала очистить мой sentiment_words, как предложено ниже.

for (j in seq(sentiment_words)) {
  sentiment_words[[j]] <- gsub("character(0)", "", sentiment_words[[j]])
  sentiment_words[[j]] <- gsub('"', "", sentiment_words[[j]])
  sentiment_words[[j]] <- gsub("c\\(", "", sentiment_words[[j]])
  sentiment_words[[j]] <- gsub(" ", "", sentiment_words[[j]])
  sentiment_words[[j]] <- gsub("\\)", "", sentiment_words[[j]])  
}

, и мне также пришлось отфильтровать оставшиеся строки «символ (0» в функции count_words. Обратите внимание, что он фильтрует символ «(0 «а не« символ (0) », потому что я удалил закрывающую скобку выше

filter(!!var != "character(0") %>%

Реализация вышеупомянутого дала самое чистое слово-облако, основанное на полярности текста

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Я бы настоятельно рекомендовал не использовать принятый ответ, поскольку он игнорирует то, что sentimentr уже возвращает вычисленные значения для вас (через attributes(sentiment_words)$counts).Документация для extract_sentiment_terms показывает примеры , которые проясняют это (была возможность улучшить документацию о том, что возвращено и было добавлено в версии dev: https://github.com/trinker/sentimentr/blob/master/R/extract_sentiment_terms.R). Ниже я покажу, какчтобы извлечь счетчики для использования в облаке слов и некоторые возможные раскладки:

library(sentimentr)
library(wordcloud)
library(data.table)

set.seed(10)
x <- get_sentences(sample(hu_liu_cannon_reviews[[2]], 1000, TRUE))
sentiment_words <- extract_sentiment_terms(x)

sentiment_counts <- attributes(sentiment_words)$counts
sentiment_counts[polarity > 0,]

par(mfrow = c(1, 3), mar = c(0, 0, 0, 0))
## Positive Words
with(
    sentiment_counts[polarity > 0,],
    wordcloud(words = words, freq = n, min.freq = 1,
          max.words = 200, random.order = FALSE, rot.per = 0.35,
          colors = brewer.pal(8, "Dark2"), scale = c(4.5, .75)
    )
)
mtext("Positive Words", side = 3, padj = 5)

## Negative Words
with(
    sentiment_counts[polarity < 0,],
    wordcloud(words = words, freq = n, min.freq = 1,
          max.words = 200, random.order = FALSE, rot.per = 0.35,
          colors = brewer.pal(8, "Dark2"), scale = c(4.5, 1)
    )
)
mtext("Negative Words", side = 3, padj = 5)

sentiment_counts[, 
    color := ifelse(polarity > 0, 'red', 
        ifelse(polarity < 0, 'blue', 'gray70')
    )]

## Together
with(
    sentiment_counts[polarity != 0,],
    wordcloud(words = words, freq = n, min.freq = 1,
          max.words = 200, random.order = FALSE, rot.per = 0.35,
          colors = color, ordered.colors = TRUE, scale = c(5, .75)
    )
)
mtext("Positive (red) & Negative (blue) Words", side = 3, padj = 5)

enter image description here

0 голосов
/ 04 декабря 2018

Вот подход, основанный на tidyverse, который должен помочь вам начать.Я согласен с Mr_Z в том, что мне не совсем ясно, где проблема.

  1. Давайте определим функцию, которая генерирует data.frame с количеством слов, основанным на словах, разделенных запятымив определенном столбце var ваших исходных данных df.

    library(tidyverse)
    count_words <- function(df, var) {
        var <- enquo(var)
        df %>%
            separate_rows(!!var, sep = ",") %>%
            filter(!!var != "") %>%
            group_by(!!var) %>%
            summarise(n = n()) %>%
            rename(words = !!var)
    }
    
  2. Затем мы можем сгенерировать количество слов для столбцов positive и negative

    df.pos <- count_words(df, positive)
    df.neg <- count_words(df, negative)
    

    Давайте проверим data.frame s

    df.pos
    # A tibble: 5 x 2
      words          n
      <chr>      <int>
    1 agree          3
    2 available      1
    3 better         1
    4 management     1
    5 strongly       2
    
    df.neg
    # A tibble: 3 x 2
      words        n
      <chr>    <int>
    1 concerns     1
    2 limits       1
    3 slow         1
    
  3. Давайте построим облака слов

    library(wordcloud)
    wordcloud(words = df.pos$words, freq = df.pos$n, min.freq = 1,
              max.words = 200, random.order = FALSE, rot.per = 0.35,
              colors = brewer.pal(8, "Dark2"))
    

    enter image description here

    wordcloud(words = df.neg$words, freq = df.neg$n, min.freq = 1,
              max.words = 200, random.order = FALSE, rot.per = 0.35,
              colors = brewer.pal(8, "Dark2"))
    

    enter image description here

...