class: center, middle, inverse, title-slide # Introdução à mineração de texto com R: Parte II ### Prof. Carlos Trucíos
ctruciosm.github.io
carlos.trucios@facc.ufrj.br
### Faculdade de Administração e Ciências Contábeis, Universidade Federal do Rio de Janeiro ### Última atualização: 2021-11-14 --- layout: true <a class="footer-link" href="http://ctruciosm.github.io">ctruciosm.github.io — Carlos Trucíos (FACC/UFRJ)</a> ---
## Introdução à mineração de texto: pacotes necessários. Para esta seção serão necessários os pacotes: - `dplyr`, - `wordcloud`, - `wordcloud2`, - `tidytext`, - `lexiconPT`, - `tm`, - `rtweet`, - `stringr` -- .pull-left[ ```r # Instalando pacotes install.packages("wordcloud") install.packages("wordcloud2") install.packages("tidytext") install.packages("lexiconPT") install.packages("tm") install.packages("stringr") ``` .blue[Não precisamos instalar o pacote `dplyr` pois já foi instalado quando instalamos o pacote `tidyverse`.] ] -- .pull-right[ ```r # Carregando pacotes library(dplyr) # Manipulação de dados library(wordcloud) # Nuvem de palavras library(wordcloud2) # Nuvem de palavras library(tidytext) # Mineração de texto library(lexiconPT) # Dicionários library(tm) # Mineração de texto library(rtweet) # Dados to Twitter library(stringr) # Manipulação de textp ``` ] --- ## Introdução à mineração de texto .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ .center[ Existem vários formatos para se trabalhar com texto. Na medida do possível, utilizaremos o formato `tidy text` que nos permite interagir facilmente com várias funções disponíveis no pacote `tidyverse`. **O formato `tidy text` é uma tabela na qual cada _token_ é uma linha.** ] ] -- .pull-left[ ![pensativo](img/pensativo_tgTUNVNfyq4uyXYMAE.gif) ] .pull-right[ **Token:** unidade do texto que estamos interessados em analisar. Geralmente são palavras, mas podem também ser n-gramas ou frases. **Tokenization:** refere-se ao processo de dividir o texto em _tokens_. > Na versão mais simples, o formato `tidy text` é uma tabela onde cada palavra do texto é uma linha! ] --- ### Introdução à mineração de texto ```r # Baixando tweets twitter <- search_tweets("CPI", n = 200, lang = "pt", include_rts = FALSE) # Selecionamos a variável text e tokenizamos twitter_token <- twitter %>% dplyr::select(text) %>% unnest_tokens(word, text) glimpse(twitter_token) ``` ``` ## Rows: 4,588 ## Columns: 1 ## $ word <chr> "lucianohangbr", "a", "havan", "ganhou", "propaganda", "grátis", … ``` -- > A função `unnest_tokens()` além de transformar o texto no formato `tidytext` também remove as puntuações e passa tudo para minúsculas 😄. --- ### Introdução à mineração de texto #### Hands-On: Utilizando os dados e contidos no objeto `twitter`, repita o processo de dividir o texto em tokens, mas dessa vez utilize: 1. unnest_tokens(word, text, token = "words") 2. unnest_tokens(word, text, token = "ngrams", n = 2) 3. unnest_tokens(word, text, token = "ngrams", n = 4) 4. unnest_tokens(word, text, token = "sentences") Dica: Modifique levemente o código abaixo: ```r twitter_token <- twitter %>% dplyr::select(text) %>% unnest_tokens(word, text) glimpse(twitter_token) ```
04
:
00
--- ### Introdução à mineração de texto Contando _tokens_ com a função `count()`. ```r twitter_token <- twitter %>% dplyr::select(text) %>% unnest_tokens(word, text) twitter_token %>% count(word, sort = TRUE) ``` ``` ## # A tibble: 1,439 × 2 ## word n ## <chr> <int> ## 1 cpi 245 ## 2 do 187 ## 3 a 178 ## 4 o 108 ## 5 de 107 ## 6 não 95 ## 7 da 93 ## 8 https 88 ## 9 t.co 88 ## 10 e 73 ## # … with 1,429 more rows ``` -- .red[Repare que `word` é o nome da variavel contida em `twitter_token` que contem os _tokens_. Repare também que a função `count()` automaticamente criou uma variável chamada `n` com a frequência absoluta de cada _token_.] --- ### Introdução à mineração de texto Dados vindos do twitter precisam de uma limpeza especial (possuim links, nomes de usuários, etc.). Não entraremos em detalhes sobre como funcionam as funções abaixo, mas utilizaremos o seguinte código para fazer essa limpeza. ```r clean_tweets <- function(x) { x %>% str_remove_all(" ?(f|ht)(tp)(s?)(://)(.*)[.|/](.*)") %>% # Remove URLs str_remove_all("@[[:alnum:]_]{4,}") %>% # Remove nomes de usuário str_remove_all("#[[:alnum:]_]+") %>% # Remove hashtags str_replace_all("&", "e") %>% # Troca "&" por "e" str_remove_all("^RT:? ") %>% # Remove "RT: " no começo do tweet str_replace_all("\\\n", " ") %>% # Replace any newline characters with a space # Removes whitespace from start and end of string str_trim("both") } ``` --- ### Introdução à mineração de texto .panelset[ .panel[.panel-name[Tweets] ```r twitter <- search_tweets("CPI", n = 200, lang = "pt", include_rts = FALSE) ``` ] .panel[.panel-name[Limpeza] ```r twitter$text <- clean_tweets(twitter$text) # ou twitter <- twitter %>% mutate(text = clean_tweets(text)) ``` ] .panel[.panel-name[Tokens] ```r twitter_token <- twitter %>% dplyr::select(text) %>% unnest_tokens(word, text) ``` ] .panel[.panel-name[Contamos] ```r twitter_count <- twitter_token %>% count(word, sort = TRUE) twitter_count ``` ``` ## # A tibble: 1,237 × 2 ## word n ## <chr> <int> ## 1 cpi 237 ## 2 do 187 ## 3 a 178 ## 4 o 108 ## 5 de 107 ## 6 não 95 ## 7 da 93 ## 8 e 73 ## 9 que 67 ## 10 na 57 ## # … with 1,227 more rows ``` ] ] --- ### Introdução à mineração de texto .blue[Quando analisamos texto, algumas palavras tais como `a`, `o`, `de`, `para`, etc. não trazem informação relevante mas possuem uma frequência alta. Essa palavras são conhecidas como _stop words_ e precisar ser retiradas antes de qualquer análise.] -- Infelizmene, o pacote `tidytext` apenas contém _stop words_ em Inglês 😢, mas o pacote `tm` contém _stop words_ em várias linguas! 💖. -- ```r stop_words_pt <- stopwords("portuguese") %>% # Stop Words do pacote tm union(c("é", "pra", "pro", "vc", "vcs")) %>% # Nossas proprias Stop Words as_tibble() %>% # Formato tibble unnest_tokens(word, value) # Tokens ``` -- > **_Stop Words_ devem ser retiradas antes de fazermos a contagem de palavras.** -- .pull-left[ Para ficarmos unicamente com as palavras que estão em _twitter_token_ não estão em _stop_words_pt_, utilizamos a função `anti_join()` do pacote `dplyr`. ] .pull-right[ <div class="figure"> <img src="imagens/anti_join.png" alt="Fonte: https://qiita.com/matsuou1/items/b1bd9778610e3a586e71" width="100%" /> <p class="caption">Fonte: https://qiita.com/matsuou1/items/b1bd9778610e3a586e71</p> </div> ] --- ### Introdução à mineração de texto .panelset[ .panel[.panel-name[Tweets] ```r twitter <- search_tweets("CPI", n = 200, lang = "pt", include_rts = FALSE) ``` ] .panel[.panel-name[Limpeza] ```r twitter <- twitter %>% mutate(text = clean_tweets(text)) ``` ] .panel[.panel-name[Tokens] ```r twitter_token <- twitter %>% dplyr::select(text) %>% unnest_tokens(word, text) ``` ] .panel[.panel-name[Stop Words] ```r # Primeiro definimos as Stop Word stop_words_pt <- stopwords("portuguese") %>% union(c("é", "pra", "pro", "vc", "vcs")) %>% as_tibble() %>% unnest_tokens(word, value) # Aplicamos anti_join twitter_token <- twitter %>% dplyr::select(text) %>% unnest_tokens(word, text) %>% anti_join(stop_words_pt, by = "word") ``` ] .panel[.panel-name[Contamos] ```r twitter_count <- twitter_token %>% count(word, sort = TRUE) twitter_count ``` ``` ## # A tibble: 1,130 × 2 ## word n ## <chr> <int> ## 1 cpi 237 ## 2 circo 50 ## 3 grande 41 ## 4 norte 37 ## 5 rio 37 ## 6 bandidos 36 ## 7 investigando 35 ## 8 investigou 35 ## 9 covid 30 ## 10 senador 17 ## # … with 1,120 more rows ``` ] ] --- ### Introdução à mineração de texto Uma vez que temos as palavras contadas (e _stop words_ removidas), podemos, por exemplo, fazer uma nuvem de palavras. -- ```r wordcloud(words = twitter_count$word, freq = twitter_count$n, min.freq = 3, colors = brewer.pal(8,"Dark2")) ``` <img src="IMTR2_files/figure-html/unnamed-chunk-19-1.png" width="100%" /> --- ### Introdução à mineração de texto Outra forma de fazer nuvem de pontos é coma função `wordcloud2` do pacote `wordcloud2` -- ```r wordcloud2(data = twitter_count) ```
--- ## Introdução à mineração de texto ### Hands-On: 1. Escolha uma conta do Twitter da sua preferência. 2. Baixe os últimos 100 tweets postados nessa _timeline_. 3. Limpe os dados (limpeza especial para o Twitter). 4. Transforme os textos em _tokens_. 5. Remova _Stop Words_. 6. Conte as palavras. 7. Faça uma nuvem de pontos (seja com `wordcloud` ou `wordcloud2`).
05
:
00
--- # Data-Tips: .pull-left[ <img src="https://octodex.github.com/images/minertocat.png" width="70%" /> ] .pull-right[ O livro [Text Mining with R](https://www.tidytextmining.com) contém bastante informação para fazermos mineração de texto. Nas próximas reuniões veremos os pontos mais importantes. O livro [Supervised Machine Learning for Text Analysis in R](https://smltar.com) presenta vários tópicos de modelagem de dados com dados textuais. O livro [Textual Data Science with R](https://www.routledge.com/Textual-Data-Science-with-R/Becue-Bertaut/p/book/9781032093659) discute vários conceitos teóricos e pode ser um ótimo complemento. ]