Notícias manchetes análise de texto

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br


[Esteartigofoipublicadopelaprimeiravezem[Thisarticlewasfirstpublishedon Programação R – DataScience +, e gentilmente contribuiu para R-blogueiros]. (Você pode relatar um problema sobre o conteúdo desta página aqui)


Deseja compartilhar seu conteúdo com R-blogueiros? clique aqui se você tiver um blog ou aqui se não tiver.

Você está interessado em postar comentários? Publique no DataScience + através do seu editor RStudio.

Categoria

  • Modelagem Avançada

Tag

  • Gestão de dados
  • Programação R
  • Mineração de texto

No presente tutorial, mostro uma análise de texto introdutória de um conjunto de dados de manchetes de notícias da ABC. Examinarei as palavras mais comuns presentes e apresentarei uma análise de sentimentos nessas manchetes, aproveitando os seguintes léxicos de sentimentos:

  • NRC
  • Bing
  • AFINN
  • O léxico de sentimentos do NRC de Saif Mohammad e Peter Turney categoriza as palavras em categorias de positivo, negativo, raiva, antecipação, nojo, medo de alegria, tristeza, surpresa e confiança.

    O léxico de sentimento do Bing de Bing Liu e outros categoriza as palavras em categoria de sentimento positivo ou negativo.

    O léxico de sentimentos AFINN do Finn Arup Nielsen atribui palavras com uma pontuação de -5 a 5, com pontuações negativas indicando sentimentos negativos e pontuações positivas indicando sentimentos positivos.

    Para obter mais informações sobre esses léxicos de sentimentos, consulte as referências listadas na parte inferior.

    Pacotes

    Vou aproveitar os seguintes pacotes R.

    suppressPackageStartupMessages(library(stringr))
    suppressPackageStartupMessages(library(dplyr))
    suppressPackageStartupMessages(library(tidytext))
    suppressPackageStartupMessages(library(tidyr))
    suppressPackageStartupMessages(library(textdata))
    suppressPackageStartupMessages(library(widyr))
    suppressPackageStartupMessages(library(ggplot2))
    

    As versões dos pacotes estão listadas aqui.

    packages <- c("stringr", "dplyr", "tidytext", "tidyr", "textdata", "widyr", "ggplot2")
    version <- lapply(packages, packageVersion)
    version_c <- do.call(c, version)
    data.frame(packages=packages, version = as.character(version_c))
    ##   packages version
    ## 1  stringr   1.4.0
    ## 2    dplyr   0.8.4
    ## 3 tidytext   0.2.2
    ## 4    tidyr   1.0.2
    ## 5 textdata   0.3.0
    ## 6    widyr   0.1.2
    ## 7  ggplot2   3.2.1
    

    Executando no Windows-10 a seguinte versão no idioma R.

    R.version
    ##                _                           
    ## platform       x86_64-w64-mingw32          
    ## arch           x86_64                      
    ## os             mingw32                     
    ## system         x86_64, mingw32             
    ## status                                     
    ## major          3                           
    ## minor          5.3                         
    ## year           2019                        
    ## month          03                          
    ## day            11                          
    ## svn rev        76217                       
    ## language       R                           
    ## version.string R version 3.5.3 (2019-03-11)
    ## nickname       Great Truth
    

    Nota

    Antes de executar esse código, baixe o léxico dos sentimentos lexicons executando a seguinte operação:

    get_sentiments("nrc")
    get_sentiments("bing")
    get_sentiments("afinn")
    

    e aceitando todas as prescrições, conforme solicitado pelo menu interativo exibido.

    Obtendo dados

    Em seguida, baixo nosso conjunto de dados de notícias que contém milhões de títulos de:

    “Https://www.kaggle.com/therohk/million-headlines/downloads/million-headlines.zip/7”

    Sua descompressão produz o arquivo abcnews-date-text.csv. Carrego-o no conjunto de dados news_data e dou uma olhada.

    news_data <- read.csv("abcnews-date-text.csv", header = TRUE, stringsAsFactors = FALSE)
    dim(news_data)
    ## [1] 1103663       2
    
    head(news_data)
    ##   publish_date                                      headline_text
    ## 1     20030219 aba decides against community broadcasting licence
    ## 2     20030219     act fire witnesses must be aware of defamation
    ## 3     20030219     a g calls for infrastructure protection summit
    ## 4     20030219           air nz staff in aust strike for pay rise
    ## 5     20030219      air nz strike to affect australian travellers
    ## 6     20030219                  ambitious olsson wins triple jump
    
    tail(news_data)
    ##         publish_date                                               headline_text
    ## 1103658     20171231             stunning images from the sydney to hobart yacht
    ## 1103659     20171231 the ashes smiths warners near miss liven up boxing day test
    ## 1103660     20171231                     timelapse: brisbanes new year fireworks
    ## 1103661     20171231                    what 2017 meant to the kids of australia
    ## 1103662     20171231            what the papodopoulos meeting may mean for ausus
    ## 1103663     20171231   who is george papadopoulos the former trump campaign aide
    

    Análise de Token

    É hora de extrair os tokens do nosso conjunto de dados. Selecione a coluna denominada como headline_text e desinvestir os tokens de palavras determina o seguinte.

    news_df % select(headline_text)
    news_tokens % unnest_tokens(word, headline_text)
    head(news_tokens, 10)
    ##             word
    ## 1            aba
    ## 1.1      decides
    ## 1.2      against
    ## 1.3    community
    ## 1.4 broadcasting
    ## 1.5      licence
    ## 2            act
    ## 2.1         fire
    ## 2.2    witnesses
    ## 2.3         must
    
    tail(news_tokens, 10)
    ##                   word
    ## 1103662.7        ausus
    ## 1103663            who
    ## 1103663.1           is
    ## 1103663.2       george
    ## 1103663.3 papadopoulos
    ## 1103663.4          the
    ## 1103663.5       former
    ## 1103663.6        trump
    ## 1103663.7     campaign
    ## 1103663.8         aide
    

    É interessante gerar e inspecionar uma tabela relatando quantas vezes cada token aparece dentro dos títulos e sua proporção em relação ao total.

    news_tokens_count % count(word, sort = TRUE) %>% mutate(proportion = n / sum(n))
    

    As 10 melhores palavras que aparecem mais.

    head(news_tokens_count, 10)
    ## # A tibble: 10 x 3
    ##    word        n proportion
    ##             
    ##  1 to     214201    0.0303 
    ##  2 in     135981    0.0192 
    ##  3 for    130239    0.0184 
    ##  4 of      80759    0.0114 
    ##  5 on      73037    0.0103 
    ##  6 over    50306    0.00711
    ##  7 the     49810    0.00704
    ##  8 police  35984    0.00509
    ##  9 at      31723    0.00449
    ## 10 with    29676    0.00420
    

    E os que aparecem com menos frequência:

    tail(news_tokens_count, 10)
    ## # A tibble: 10 x 3
    ##    word           n  proportion
    ##                 
    ##  1 zweli          1 0.000000141
    ##  2 zwitkowsky     1 0.000000141
    ##  3 zydelig        1 0.000000141
    ##  4 zygar          1 0.000000141
    ##  5 zygiefs        1 0.000000141
    ##  6 zylvester      1 0.000000141
    ##  7 zynga          1 0.000000141
    ##  8 zyngier        1 0.000000141
    ##  9 zz             1 0.000000141
    ## 10 zzz            1 0.000000141
    

    Existe um problema em fazer dessa maneira. A questão é que existem palavras que não têm papel relevante para facilitar a análise de sentimentos, as chamadas pare de palavras. Abaixo, as palavras de parada no nosso conjunto de dados são mostradas.

    data(stop_words)
    head(stop_words, 10)
    ## # A tibble: 10 x 2
    ##    word        lexicon
    ##             
    ##  1 a           SMART  
    ##  2 a's         SMART  
    ##  3 able        SMART  
    ##  4 about       SMART  
    ##  5 above       SMART  
    ##  6 according   SMART  
    ##  7 accordingly SMART  
    ##  8 across      SMART  
    ##  9 actually    SMART  
    ## 10 after       SMART
    

    Para remover palavras de parada conforme necessário, aproveitamos o anti_join Operação.

    news_tokens_no_sp % anti_join(stop_words)
    head(news_tokens_no_sp, 10)
    ##            word
    ## 1           aba
    ## 2       decides
    ## 3     community
    ## 4  broadcasting
    ## 5       licence
    ## 6           act
    ## 7          fire
    ## 8     witnesses
    ## 9         aware
    ## 10   defamation
    

    Depois, contando os tokens de notícias novamente depois de remover as palavras finais.

    news_tokens_count % count(word, sort = TRUE) %>% mutate(proportion = n / sum(n))
    head(news_tokens_count, 10)
    ## # A tibble: 10 x 3
    ##    word          n proportion
    ##               
    ##  1 police    35984    0.00673
    ##  2 govt      16923    0.00317
    ##  3 court     16380    0.00306
    ##  4 council   16343    0.00306
    ##  5 interview 15025    0.00281
    ##  6 fire      13910    0.00260
    ##  7 nsw       12912    0.00242
    ##  8 australia 12353    0.00231
    ##  9 plan      12307    0.00230
    ## 10 water     11874    0.00222
    
    tail(news_tokens_count)
    ## # A tibble: 6 x 3
    ##   word          n  proportion
    ##               
    ## 1 zygiefs       1 0.000000187
    ## 2 zylvester     1 0.000000187
    ## 3 zynga         1 0.000000187
    ## 4 zyngier       1 0.000000187
    ## 5 zz            1 0.000000187
    ## 6 zzz           1 0.000000187
    

    Depois, filtro os tokens com mais de 8.000 contagens.

    news_token_over8000 % filter(n > 8000) %>% mutate(word = reorder(word, n))
    nrow(news_token_over8000)
    ## [1] 32
    
    head(news_token_over8000, 10) 
    ## # A tibble: 10 x 3
    ##    word          n proportion
    ##               
    ##  1 police    35984    0.00673
    ##  2 govt      16923    0.00317
    ##  3 court     16380    0.00306
    ##  4 council   16343    0.00306
    ##  5 interview 15025    0.00281
    ##  6 fire      13910    0.00260
    ##  7 nsw       12912    0.00242
    ##  8 australia 12353    0.00231
    ##  9 plan      12307    0.00230
    ## 10 water     11874    0.00222
    
    tail(news_token_over8000, 10) 
    ## # A tibble: 10 x 3
    ##    word         n proportion
    ##              
    ##  1 day       8818    0.00165
    ##  2 hospital  8815    0.00165
    ##  3 car       8690    0.00163
    ##  4 coast     8411    0.00157
    ##  5 calls     8401    0.00157
    ##  6 win       8315    0.00156
    ##  7 woman     8213    0.00154
    ##  8 killed    8129    0.00152
    ##  9 accused   8094    0.00151
    ## 10 world     8087    0.00151
    

    É interessante mostrar a proporção em milhares por meio de um gráfico de histograma.

    news_token_over8000 %>%  
      ggplot(aes(word, proportion*1000, fill=ceiling(proportion*1000))) +
      geom_col() + xlab(NULL) + coord_flip() + theme(legend.position = "none")
    

    Análise de notícias

    Neste parágrafo, concentro-me em cada título para avaliar seu sentimento específico, conforme determinado por cada léxico. Portanto, o resultado deve determinar se cada título específico tem sentimentos positivos ou negativos.

    head(news_df, 10)
    ##                                         headline_text
    ## 1  aba decides against community broadcasting licence
    ## 2      act fire witnesses must be aware of defamation
    ## 3      a g calls for infrastructure protection summit
    ## 4            air nz staff in aust strike for pay rise
    ## 5       air nz strike to affect australian travellers
    ## 6                   ambitious olsson wins triple jump
    ## 7          antic delighted with record breaking barca
    ## 8   aussie qualifier stosur wastes four memphis match
    ## 9        aust addresses un security council over iraq
    ## 10         australia is locked into war timetable opp
    

    Analisarei apenas as primeiras 1000 manchetes apenas por razões de tempo computacional. A lista de tokens é a seguinte.

    news_df_subset <- news_df[1:1000,,drop=FALSE]
    tkn_l % unnest_tokens(word, headline_text)})
    

    Removendo as palavras de parada da lista de tokens.

    single_news_tokens <- lapply(tkn_l, function(x) {anti_join(x, stop_words)})
    
    str(single_news_tokens, list.len = 5)
    ## List of 1000
    ##  $ 1   :'data.frame':    5 obs. of  1 variable:
    ##   ..$ word: chr [1:5] "aba" "decides" "community" "broadcasting" ...
    ##  $ 2   :'data.frame':    5 obs. of  1 variable:
    ##   ..$ word: chr [1:5] "act" "fire" "witnesses" "aware" ...
    ##  $ 3   :'data.frame':    4 obs. of  1 variable:
    ##   ..$ word: chr [1:4] "calls" "infrastructure" "protection" "summit"
    ##  $ 4   :'data.frame':    7 obs. of  1 variable:
    ##   ..$ word: chr [1:7] "air" "nz" "staff" "aust" ...
    ##  $ 5   :'data.frame':    6 obs. of  1 variable:
    ##   ..$ word: chr [1:6] "air" "nz" "strike" "affect" ...
    ##   [list output truncated]
    

    Como podemos ver, a cada título está associada uma lista de tokens. O sentimento de um título é calculado com base na soma da pontuação positiva / negativa de cada token de.

    single_news_tokens[[1]]
    ##           word
    ## 1          aba
    ## 2      decides
    ## 3    community
    ## 4 broadcasting
    ## 5      licence
    

    Bing lexicon

    Neste parágrafo, o cálculo do sentimento associado à lista de tokens é mostrado para Bing léxico. Primeiro defino uma função denominada como compute_sentiment () cujo objetivo é gerar a pontuação de positividade de um título específico.

    compute_sentiment <- function(d) {
      if (nrow(d) == 0) {
        return(NA)
      }
      neg_score % filter(sentiment=="negative") %>% nrow()
      pos_score % filter(sentiment=="positive") %>% nrow()
      pos_score - neg_score
    } 
    

    A junção interna em bing O léxico de cada lista de tokens de título único é fornecido como entrada para o compute_sentiment () para determinar a pontuação de sentimentos de cada título específico.

    sentiments_bing <- get_sentiments("bing")
    str(sentiments_bing)
    ## Classes 'tbl_df', 'tbl' and 'data.frame':    6786 obs. of  2 variables:
    ##  $ word     : chr  "2-faces" "abnormal" "abolish" "abominable" ...
    ##  $ sentiment: chr  "negative" "negative" "negative" "negative" ...
    
    single_news_sentiment_bing % inner_join(sentiments_bing) %>% compute_sentiment()})
    

    O resultado é um vetor de números inteiros, cada valor de elemento na i-ésima posição é o sentimento associado à i-ésima notícia

    cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
    str(single_news_sentiment_bing)
    ##  Named int [1:1000] NA -1 1 -1 -1 2 0 NA NA NA ...
    ##  - attr(*, "names")= chr [1:1000] "1" "2" "3" "4" ...
    

    Aqui está o resumo, observe que:

    • a mediana é negativa
    • NA aparece
    summary(single_news_sentiment_bing)
    ##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
    ##  -3.000  -1.000  -1.000  -0.475   1.000   2.000     520
    

    Coletando o resultado em um quadro de dados da seguinte maneira.

    single_news_sentiment_bing_df <- data.frame(headline_text=news_df_subset$headline_text, score = single_news_sentiment_bing)
    head(single_news_sentiment_bing_df, 10)
    ##                                         headline_text score
    ## 1  aba decides against community broadcasting licence    NA
    ## 2      act fire witnesses must be aware of defamation    -1
    ## 3      a g calls for infrastructure protection summit     1
    ## 4            air nz staff in aust strike for pay rise    -1
    ## 5       air nz strike to affect australian travellers    -1
    ## 6                   ambitious olsson wins triple jump     2
    ## 7          antic delighted with record breaking barca     0
    ## 8   aussie qualifier stosur wastes four memphis match    NA
    ## 9        aust addresses un security council over iraq    NA
    ## 10         australia is locked into war timetable opp    NA
    

    Léxico do NRC

    Neste parágrafo, o cálculo do sentimento associado à lista de tokens é mostrado para NRC léxico. Com relação à análise anterior baseada em bing léxico, é necessário um pouco mais de pré-processamento, conforme explicado a seguir. Primeiro temos o NRC léxico de sentimentos e veja quais são os sentimentos presentes.

    sentiments_nrc <- get_sentiments("nrc")
    (unique_sentiments_nrc <- unique(sentiments_nrc$sentiment))
    ##  [1] "trust"        "fear"         "negative"     "sadness"      "anger"        "surprise"    
    ##  [7] "positive"     "disgust"      "joy"          "anticipation"
    

    Para ter como resultado um resultado positivo / negativo de sentimento, defino um mapeamento de sentimentos anteriores a um resultado positivo / negativo de sequência da seguinte forma.

    compute_pos_neg_sentiments_nrc <- function(the_sentiments_nrc) {
      s <- unique(the_sentiments_nrc$sentiment)
      df_sentiments <- data.frame(sentiment = s, 
                                  mapped_sentiment = c("positive", "negative", "negative", "negative",
                                                        "negative", "positive", "positive", "negative", 
                                                        "positive", "positive"))
      ss % inner_join(df_sentiments)
      the_sentiments_nrc$sentiment <- ss$mapped_sentiment
      the_sentiments_nrc
    }
    
    nrc_sentiments_pos_neg_scale <- compute_pos_neg_sentiments_nrc(sentiments_nrc)
    

    A função acima é usada para produzir os resultados de sentimentos de texto de título único. Esse resultado é dado como entrada para o compute_sentiment () função.

    single_news_sentiment_nrc % inner_join(nrc_sentiments_pos_neg_scale) %>% compute_sentiment()})
    
    str(single_news_sentiment_nrc)
    ##  Named int [1:1000] 1 -4 1 2 -2 2 4 NA 5 -2 ...
    ##  - attr(*, "names")= chr [1:1000] "1" "2" "3" "4" ...
    

    Aqui está o resumo, observe que:

    • a mediana é igual a zero
    • NA aparece
    summary(single_news_sentiment_nrc)
    ##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
    ## -9.0000 -2.0000  0.0000 -0.3742  2.0000  9.0000     257
    
    single_news_sentiment_nrc_df <- data.frame(headline_text=news_df_subset$headline_text, score = single_news_sentiment_nrc)
    head(single_news_sentiment_nrc_df, 10)
    ##                                         headline_text score
    ## 1  aba decides against community broadcasting licence     1
    ## 2      act fire witnesses must be aware of defamation    -4
    ## 3      a g calls for infrastructure protection summit     1
    ## 4            air nz staff in aust strike for pay rise     2
    ## 5       air nz strike to affect australian travellers    -2
    ## 6                   ambitious olsson wins triple jump     2
    ## 7          antic delighted with record breaking barca     4
    ## 8   aussie qualifier stosur wastes four memphis match    NA
    ## 9        aust addresses un security council over iraq     5
    ## 10         australia is locked into war timetable opp    -2
    

    Dicionário AFINN

    Neste parágrafo, o cálculo do sentimento associado à lista de tokens é mostrado para AFINN léxico.

    sentiments_afinn <- get_sentiments("afinn")
    colnames(sentiments_afinn) <- c("word", "sentiment")
    str(sentiments_afinn)
    ## Classes 'spec_tbl_df', 'tbl_df', 'tbl' and 'data.frame': 2477 obs. of  2 variables:
    ##  $ word     : chr  "abandon" "abandoned" "abandons" "abducted" ...
    ##  $ sentiment: num  -2 -2 -2 -2 -2 -2 -3 -3 -3 -3 ...
    ##  - attr(*, "spec")=
    ##   .. cols(
    ##   ..   word = col_character(),
    ##   ..   value = col_double()
    ##   .. )
    

    Como podemos ver, o afinn O léxico fornece uma pontuação para cada token. Só precisamos resumir cada pontuação de tokens de título para obter a pontuação de sentimento do título em análise.

    single_news_sentiment_afinn_df % inner_join(sentiments_afinn)})
    single_news_sentiment_afinn  0, sum(x$sentiment), NA)
      })
    
    str(single_news_sentiment_afinn)
    ##  Named num [1:1000] NA -2 NA -2 -1 6 3 NA NA -2 ...
    ##  - attr(*, "names")= chr [1:1000] "1" "2" "3" "4" ...
    

    Aqui está o resumo, observe que:

    • a mediana é negativa
    • NA aparece
    summary(single_news_sentiment_afinn)
    ##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
    ##  -9.000  -3.000  -2.000  -1.148   1.000   7.000     508
    
    single_news_sentiment_afinn_df <- data.frame(headline_text=news_df_subset$headline_text, score = single_news_sentiment_afinn)
    head(single_news_sentiment_afinn_df, 10)
    ##                                         headline_text score
    ## 1  aba decides against community broadcasting licence    NA
    ## 2      act fire witnesses must be aware of defamation    -2
    ## 3      a g calls for infrastructure protection summit    NA
    ## 4            air nz staff in aust strike for pay rise    -2
    ## 5       air nz strike to affect australian travellers    -1
    ## 6                   ambitious olsson wins triple jump     6
    ## 7          antic delighted with record breaking barca     3
    ## 8   aussie qualifier stosur wastes four memphis match    NA
    ## 9        aust addresses un security council over iraq    NA
    ## 10         australia is locked into war timetable opp    -2
    

    Comparando resultados

    Tendo obtido para cada notícia três resultados potenciais como avaliação de sentimentos, gostaríamos de comparar sua congruência.
    Como congruência, entendemos o fato de que todos os três léxicos expressam o mesmo resultado positivo ou negativo; em outras palavras, a mesma pontuação assina indipendentemente de sua magnitude. Se houver valores de NA, a congruência será calculada até que pelo menos dois valores não NA estejam disponíveis, caso contrário, será igual a NA.

    Além disso, calculamos o sentimento final de notícias com base na soma de cada pontuação de sentimento do léxico.

    compute_congruence <- function(x,y,z) {
      v = 2) {
        return (NA)
      }
      # removing NA and zero value
      v <- na.omit(v)
      v_sum <- sum(v)
      abs(v_sum) == length(v)
    }
    
    compute_final_sentiment <- function(x,y,z) {
      if (is.na(x) && is.na(y) && is.na(z)) {
        return (NA)
      }
    
      s  0, "positive", ifelse(s < 0, "negative", "neutral"))
    }
    
    news_sentiments_results <- data.frame(headline_text = news_df_subset$headline_text, 
                                          bing_score = single_news_sentiment_bing, 
                                          nrc_score = single_news_sentiment_nrc, 
                                          afinn_score = single_news_sentiment_afinn,
                                          stringsAsFactors = FALSE)
    
    news_sentiments_results % rowwise() %>% 
      mutate(final_sentiment = compute_final_sentiment(bing_score, nrc_score, afinn_score),
             congruence = compute_congruence(bing_score, nrc_score, afinn_score))
    
    head(news_sentiments_results, 40)
    ## Source: local data frame [40 x 6]
    ## Groups: 
    ## 
    ## # A tibble: 40 x 6
    ##    headline_text                           bing_score nrc_score afinn_score final_sentiment congruence
    ##                                                                         
    ##  1 aba decides against community broadcas~         NA         1          NA positive        NA        
    ##  2 act fire witnesses must be aware of de~         -1        -4          -2 negative        TRUE      
    ##  3 a g calls for infrastructure protectio~          1         1          NA positive        TRUE      
    ##  4 air nz staff in aust strike for pay ri~         -1         2          -2 negative        FALSE     
    ##  5 air nz strike to affect australian tra~         -1        -2          -1 negative        TRUE      
    ##  6 ambitious olsson wins triple jump                2         2           6 positive        TRUE      
    ##  7 antic delighted with record breaking b~          0         4           3 positive        FALSE     
    ##  8 aussie qualifier stosur wastes four me~         NA        NA          NA             NA        
    ##  9 aust addresses un security council ove~         NA         5          NA positive        NA        
    ## 10 australia is locked into war timetable~         NA        -2          -2 negative        TRUE      
    ## # ... with 30 more rows
    

    Seria útil substituir a pontuação numérica pela mesma escala {negativa, neutra, positiva}.

    replace_score_with_sentiment  0] <- "positive"
      v_score[v_score < 0] <- "negative"
      v_score[v_score == 0] <- "neutral"
      v_score
    } 
    
    news_sentiments_results$bing_score <- replace_score_with_sentiment(news_sentiments_results$bing_score)
    news_sentiments_results$nrc_score <- replace_score_with_sentiment(news_sentiments_results$nrc_score)
    news_sentiments_results$afinn_score <- replace_score_with_sentiment(news_sentiments_results$afinn_score)
    
    news_sentiments_results[,2:5] <- lapply(news_sentiments_results[,2:5], as.factor)
    
    head(news_sentiments_results, 40)
    ## Source: local data frame [40 x 6]
    ## Groups: 
    ## 
    ## # A tibble: 40 x 6
    ##    headline_text                           bing_score nrc_score afinn_score final_sentiment congruence
    ##                                                                         
    ##  1 aba decides against community broadcas~        positive          positive        NA        
    ##  2 act fire witnesses must be aware of de~ negative   negative  negative    negative        TRUE      
    ##  3 a g calls for infrastructure protectio~ positive   positive          positive        TRUE      
    ##  4 air nz staff in aust strike for pay ri~ negative   positive  negative    negative        FALSE     
    ##  5 air nz strike to affect australian tra~ negative   negative  negative    negative        TRUE      
    ##  6 ambitious olsson wins triple jump       positive   positive  positive    positive        TRUE      
    ##  7 antic delighted with record breaking b~ neutral    positive  positive    positive        FALSE     
    ##  8 aussie qualifier stosur wastes four me~                                  NA        
    ##  9 aust addresses un security council ove~        positive          positive        NA        
    ## 10 australia is locked into war timetable~        negative  negative    negative        TRUE      
    ## # ... with 30 more rows
    

    Tabularizações de cada sentimento resultante do léxico e sentimentos finais são aqui mostradas.

    table(news_sentiments_results$bing_score, news_sentiments_results$final_sentiment, dnn = c("bing", "final"))
    ##           final
    ## bing       negative neutral positive
    ##   negative      278      15       14
    ##   neutral        16       6       11
    ##   positive        6       7      127
    
    table(news_sentiments_results$nrc_score, news_sentiments_results$final_sentiment, dnn = c("nrc", "final"))
    ##           final
    ## nrc        negative neutral positive
    ##   negative      353      10        4
    ##   neutral        18      13        6
    ##   positive       25      16      298
    
    table(news_sentiments_results$afinn_score, news_sentiments_results$final_sentiment, dnn = c("afinn", "final"))
    ##           final
    ## afinn      negative neutral positive
    ##   negative      326      10       12
    ##   neutral         3       1        6
    ##   positive        4       9      121
    

    A tabularização da congruência e dos sentimentos finais é mostrada aqui.

    table(news_sentiments_results$congruence, news_sentiments_results$final_sentiment, dnn = c("congruence", "final"))
    ##           final
    ## congruence negative neutral positive
    ##      FALSE       67      33       45
    ##      TRUE       292       0      132
    

    Conclusões

    Analisamos as manchetes das notícias para determinar seus sentimentos e aproveitar três léxicos de sentimentos. Mostramos alguns conceitos básicos da metodologia para esse fim. Também tivemos a chance de comparar os resultados obtidos nos três léxicos e estabelecer uma avaliação final do sentimento. Se você estiver interessado em entender muito mais sobre análise de texto, consulte a ref. [4].

    Referências

    [1] Léxico de sentimentos do NRC
    [2] Dicionário de sentimentos BING
    [3] Dicionário de sentimentos AFINN
    [4] Mineração de texto com R

    Post relacionado

    • Algoritmo Genético no Aprendizado de Máquina usando Python
    • Pacote poderoso para aprendizado de máquina, ajuste de hiperparâmetro (pesquisa em grade e aleatória), aplicativo brilhante
    • Analisando HTML e Aplicando Aprendizado de Máquina Não Supervisionado. Parte 3: Análise de Componentes Principais (PCA) usando Python
    • Analisando HTML e Aplicando Aprendizado de Máquina Não Supervisionado. Parte 2: Clustering Aplicado Usando Python
    • Analisando HTML e Aplicando Aprendizado de Máquina Não Supervisionado. Parte 1: Processamento de HTML usando Python

    var vglnk = {key: '949efb41171ac6ec1bf7f206d57e90b8'};

    (função (d, t) {
    var s = d.createElement
    s.src = '//cdn.viglink.com/api/vglnk.js';
    var r = d.getElementsByTagName
    } (documento, 'script'));

    Para Deixe um comentário para o autor, siga o link e comente no blog: Programação R - DataScience +.

    R-bloggers.com oferece atualizações diárias por email sobre notícias e tutoriais do R sobre o aprendizado do R e muitos outros tópicos. Clique aqui se você deseja publicar ou encontrar um emprego em ciência da dados / R.


    Deseja compartilhar seu conteúdo com R-blogueiros? clique aqui se você tiver um blog ou aqui se não tiver.



    cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
    Leia Também  Identidades financeiras para os não-bancários do mundo adicionariam US $ 250 bilhões ao PIB global, de acordo com um novo estudo