[HackMD Tutorials](https://hackmd.io/c/tutorials) # Workshop Análise Textual em R para dados turísticos ## Objetivos - Fornecer os primeiros passos para que vocês consigam caminhar sozinhos :wink: --- ## KDD (Knowledge Discovery in Databases) KDD é o processo não trivial de identificação de padrões em dados que sejam válidos, novos, potencialmente úteis e compreensíveis [Fayyad, 1996]. --- Por exemplo: **Sintetizar informação:** - a partir de logs de servidores web, identificar qual é o caminho mais frequente de navegação dos usuários no site. - a partir de notícias publicadas em veículos web, sumarizar os principais eventos do dia. **Prescrever ações:** - a partir do histórico de candidaturas em vagas de um candidato, recomendar novas vagas para o mesmo. - a partir de conteúdo previamente moderado, construir uma aplicação capaz de moderar conteúdo automaticamente. --- **Processo de KDD** 1. Qual é a pergunta? 2. Aquisição e pré-processamento dos dados. 3. Análise Exploratória. 4. Modelagem: construçãoo do modelo descritivo ou preditivo. 5. Avaliaçãoo do modelo. 6. Entrega: relatórios estáticos, dinâmicos, sistemas ou funcionalidade de sistemas. --- ***Machine Learning*** ![](https://i.imgur.com/uXJ568F.jpg) --- **Não supervisionada** ![](https://i.imgur.com/7XjQR4z.jpg) --- O processo de KDD (pode/deve) ser suportado por ferramentas computacionais, tais como: • R • SPSS • RapidMiner • Weka • Tableau • Python, Julia, Octave, Matlab. --- ## O Projeto R ![](https://i.imgur.com/kQphyQW.png) - R é um software gratuito, fácil de usar e possui uma comunidade grande desenvolvendo pacotes novos todo dia. - É possivel utilizar o R nativo, mas uma IDE poderosa e muito útil é o R studio (integra várias funcionalidade que deixam as coisas mais fáceis e simples). - Uma alternativa é utilizar o [R studio Cloud](https://rstudio.cloud/), porém a versão gratuita tem certas limitações em tempo de processamento e capacidade de armazenamento. --- ![](https://i.imgur.com/NOpA8EY.png) **1. (editor)**: onde escrevemos o código, **2. (console)**: onde tudo no R acontece, **3. (ambiente)**: objetos e funções carregadas no ambiente do R, **4. (outros)**: arquivos, gráficos, pacotes, ajuda, .. --- - **Importante:** texto após um (#) serve para escrever comentários --- **Operações básicas** ``` 2+3 # Soma 5-6 # Substração 3*4 # Multiplicação 30/6 # Divisão 2^4 # Potenciação ``` **Perguntas lógicas** ```` 1 == 1 # 1 é igual a 1? 1 != 2 # 1 é diferente de 2? 2 <= 3 # 2 é menor ou igual a 3? 3 < 3 # 3 é menor do que 3? 4 > 5 # 4 é maior do que 5? 7 >= 8 # 7 é maior ou igual a 8? ```` **Atribuição** (pode ser feita com = ou <-) ```` y <- 5 # Atribuição y # Mostra o valor atribuido x <- c(5, 7, 8, 1, 3, 8, 9) # c() cria um vetor de dados (com elementos separados por ",") x # Mostra os valores atribuidos z <- 1:10 # cria uma sequência do 1 ao 10 w <- c("João", "Paty", "Igor") # c() cria um vetor de dados ```` --- Uma lista com várias funções disponíveis no R podem ser encontradas nos *Cheatsheets* do [R](https://cran.r-project.org/doc/contrib/Baggott-refcard-v2.pdf) e [Rstudio**](https://www.rstudio.com/resources/cheatsheets/). **Não precisa** imprimir todos os *Cheatsheets*, mas ter por perto **unicamente aqueles** que lhe ajudarão nas suas tarefas diárias. --- R tem uma comunidade bastante ativa e novos ***pacotes*** (módulos com várias funções implementadas para trabalhar em assuntos específicos) são disponibilizados todo dia. Daqui em diante focaremos em alguns pacotes úteis para raspagem de dados e mineração de texto. --- ![](https://i.imgur.com/xk9auZj.jpg) ![](https://i.imgur.com/MZgzAPx.png) --- ## Web Scraping Extensão Google Chrome - [Selector Gadget](https://chrome.google.com/webstore/detail/selectorgadget/mhjhnkcfbdhnjickkkdbjoemdmbfginb) --- ## Análise de dados Estudos têm mostrado que o TripAdvisor está se tornando muito importante no processo de tomada de decisão de um viajante. No entanto, entender a nuance da classificação de um atrativo em relação a cada um dos milhares de comentários de avaliação pode ser um desafio. Em um esforço para entender melhor a qualidade da experiência obtida pelo turista ao visitar um atrativo, técnicas de mineração de texto podem ser aplicadas. #### Carregando pacotes ```` if(!require(pacman)) install.packages("pacman") pacman::p_load(devtools, rvest, httr, XML, dplyr, textreuse, rslp, tm, proxy, factoextra, text2vec, ngram, ggplot2, stringr, stringi, cluster, dendextend, wordcloud, wordcloud2, rmarkdown, knitr, gridExtra, kableExtra, textreuse, syuzhet, RColorBrewer, tidyverse, reshape2, lexiconPT, textdata, tidyr, scales, broom, purrr, widyr, igraph, ggraph, SnowballC, RWekajars) library(sentimentBR) library(tidytext) ```` #### Limpando o ambiente R ````` rm(list = ls()) ````` #### Importando os dados ```` data<- read.csv2("./01_Dados/00_ComentariosSuperagui.csv", encoding = 'UTF-8') ```` --- A análise de conteúdo só é possível através da transformação do texto bruto em estruturas de dados convenientes para análise. Esta etapa é fundamental e deve ser feita com cuidado para evitar erros. Temos basicamente três estruturas num texto: **Tokens**: O texto pode ser armazenado em n-grams ou cadeias de caracteres (strings), por exemplo a frase “projeto de lei,” em n-gram de tamanho 1, ou seja unigram, se torna “projeto” “de” “lei.” **Corpus**: Estruturas que armazenam tanto o conteúdo de documentos como seus metadados. Também pode ser descrito como uma coleção de documentos. **Matriz de documentos e termos** (DFM ou DTM): é uma matriz esparsa com uma linha para cada documento e uma coluna para cada termo. Em geral, as células de uma DTM são preenchidas pela frequência de palavras. A análise do conteúdo do texto como dado exige versatilidade na transformação entre estruturas. Os pacotes que veremos permitem essa versatilidade, especialmente os pacotes *tidytext* e *quanteda*. Uma comparação entre os pacotes pode ser encontrada [aqui](https://quanteda.io/articles/pkgdown/comparison.html). --- #### Token O token é uma unidade de texto significativa, podendo ser uma única palavra, um conjunto de palavras, uma frase ou um parágrafo. Para obte-lo se deve realizar o processo de tokenização, em que se divide o texto em tokens, como veremos a seguir. Considere o vetor ``text <- c("Minha terra tem palmeiras", "Onde canta o Sabiá", "As aves, que aqui, gorjeiam", "Não gorjeiam como lá")`` Para transformar o vetor de strings em formato *tidytext*, precisamos criar um *data.frame*, através da função *tibble*. Abaixo, estamos declarando o nome das colunas e o valor contido nelas, por exemplo *text* é a coluna que contém cada observação do vetor *text* que criamos anteriormente. ![](https://i.imgur.com/fb06J7v.jpg) Um objeto `tibble` é uma classe moderna de `data.frames` dentro do R, disponível nos pacotes `dplyr` e `tibble`, que possui um método de impressão conveniente, não converte strings em fatores e não usa nomes de linhas. Tibbles são ótimos para uso com funções, pacotes e ferramentas `tidy`. Contudo, nosso objeto `tibble` ainda não está coerente com a definição de *tidytext* que apresentamos. Temos que converter nosso objeto em outro que atenda a condição *one-token-per-document-per-row*. Logo, cada token *unigram* (cada palavra) deve ser um valor indicado por verso. A função `unnest_tokens` presente no pacote *tidytext* realiza este processo de tokenização. Abaixo, a coluna “word” irá conter uma palavra por linha através da coluna *text* que contém nosso texto. ```` text_token <- text_df %>% unnest_tokens(word, text) ```` ![](https://i.imgur.com/3YptSih.jpg) --- #### Atributos Os atributos são as palavras que aparecem nos documentos. As palavras do texto precisam ser normalizadas: - caixa baixa, - remover acentuação, - remover stopwords, - aplicar algoritmos de steamming. --- ![](https://i.imgur.com/Wrs5yNH.jpg) --- ![](https://i.imgur.com/fJFfi7U.jpg) --- **Radicalizador para o português:** • Regra de reducao de plurais (**Regras N**) • Regra de reducao de femininos (**Regras G**) • Regras de reducao de aumentativos e diminutivos (**Regras T**) • Regras de reducao de grau (**Regras S**) • Outras regras (**Regras O**) • Regras para formas verbais (**Regras V**) - A sequência para as **formas verbais** reduz-se à aplicação da regra para redução ao infinito. - Para os nomes (**substantivos, adjetivos e advérbios**) aplica-se a seguinte sequência: N → G → T → S → O --- ````` data %>% group_by(coments) %>% count(coments) #Carrega Stopwords stopwords_iso<-sort(stopwords::stopwords("pt", source = "stopwords-iso")) file <- url("https://jodavid.github.io/Slide-Introdu-o-a-Web-Scrapping-com-rvest/stopwords_pt_BR.txt") stopwords_ptBR <- read.table(file) stopwords_ptBR <- unlist(stopwords_ptBR, use.names = FALSE) #limpeza data$coments<- tolower(data$coments) data$coments<- removePunctuation(data$coments) data$coments<- removeNumbers(data$coments) data$coments<- removeWords(data$coments, stopwords_iso) data$coments<- stripWhitespace(data$coments) data <- data %>% filter(is.na(coments) == FALSE) review_words <- data %>% distinct(coments, .keep_all = TRUE) %>% unnest_tokens(word, coments, drop = FALSE) %>% distinct(id, word, .keep_all = TRUE) %>% anti_join(get_stopwords("pt"), source = "stopwords-iso", by = "word") %>% filter(str_detect(word, "[^\\d]")) %>% group_by(word) %>% mutate(word_total = n()) %>% ungroup() ````` --- ````` word_counts <- review_words %>% count(word, sort = TRUE) word_counts %>% head(50) %>% mutate(word = reorder(word, n)) %>% ggplot(aes(word, n)) + geom_col(fill = "lightblue") + scale_y_continuous(labels = comma_format()) + coord_flip() + labs(title = "Palavras mais comuns", subtitle = "171 comentários; stopwords removidas", y = "# of uses") word_counts %>% head(25) %>% mutate(word = wordStem(word)) %>% mutate(word = reorder(word, n)) %>% ggplot(aes(word, n)) + geom_col(fill = "lightblue") + scale_y_continuous(labels = comma_format()) + coord_flip() + labs(title = "Palavras mais comuns", subtitle = "171 comentários; stopwords removidas and stemmed", y = "# of uses") ````` --- ![](https://i.imgur.com/69OqS6u.jpg) ![](https://i.imgur.com/6KIgdWd.jpg) --- • Já conhecemos os atributos. • E os valores? - **Booleana** - se a palavra aparece ou não no documento (1 ou 0) - **Por frequência do termo** - a frequência com que a palavra aparece no documento (normalizada ou não) - **Ponderação tf-idf** - o peso é proporcional ao número de ocorrências do termo no documento e inversamente proporcional ao número de documentos onde o termo aparece. --- ### N-Grams #### Bigramas Muitas vezes, queremos entender a relação entre as palavras em uma revisão. - Quais sequências de palavras são comuns no texto? - Dada uma sequência de palavras, qual palavra é mais provável de seguir? - Quais palavras têm a relação mais forte entre si? Portanto, muitas análises de texto interessantes são baseadas nas relações. - Quando examinamos pares de duas palavras consecutivas, chama-se “bigramas”. Então, quais são os bigramas mais comuns nas avaliações do TripAdvisor do Superagui? ```` review_bigrams <- data %>% unnest_tokens(bigram, coments, token = "ngrams", n = 2) bigrams_separated <- review_bigrams %>% separate(bigram, c("word1", "word2"), sep = " ") bigram_counts <- bigrams_separated %>% count(word1, word2, sort = TRUE) bigrams_united <- bigrams_separated %>% unite(bigram, word1, word2, sep = " ") bigrams_united %>% count(bigram, sort = TRUE) head(bigrams_united) ```` ![](https://i.imgur.com/4fo0fQO.jpg) Podemos também visualizar os bigramas em redes de palavras: ``` review_subject <- data %>% unnest_tokens(word, coments) %>% anti_join(get_stopwords("pt"), source = "stopwords-iso", by = "word") review_subject <- review_subject %>% anti_join(get_stopwords("pt"), source = "stopwords-iso", by = "word") title_word_pairs <- review_subject %>% pairwise_count(word, id, sort = TRUE, upper = FALSE) set.seed(1234) title_word_pairs %>% filter(n >= 10) %>% graph_from_data_frame() %>% ggraph(layout = "fr") + geom_edge_link(aes(edge_alpha = n, edge_width = n), edge_colour = "cyan4") + geom_node_point(size = 5) + geom_node_text(aes(label = name), repel = TRUE, point.padding = unit(0.2, "lines")) + ggtitle('Rede de Palavras das revisões do TripAdvisor') theme_void() ```` ![](https://i.imgur.com/WVELrXo.png) --- #### Trigramas ```` review_trigrams <- data %>% unnest_tokens(trigram, coments, token = "ngrams", n = 3) trigrams_separated <- review_trigrams %>% separate(trigram, c("word1", "word2", "word3"), sep = " ") trigrams_filtered <- trigrams_separated %>% filter(!word1 %in% stopwords_iso) %>% filter(!word2 %in% stopwords_iso) %>% filter(!word3 %in% stopwords_iso) trigram_counts <- trigrams_filtered %>% count(word1, word2, word3, sort = TRUE) trigrams_united <- trigrams_filtered %>% unite(trigram, word1, word2, word3, sep = " ") trigrams_united %>% count(trigram, sort = TRUE) ````` ![](https://i.imgur.com/u4RXSJg.jpg) --- ### Análise de sentimentos ## Links úteis ### Livros #### - [Texto como Dado para Ciências Sociais - Davi Moreira](https://bookdown.org/davi_moreira/txt4cs/) #### - [Text Mining with R - Julia Silge e David Robinson](https://www.tidytextmining.com/index.html) #### - [Supervised Machine Learning for Text Analysis in R - Emil Hvitfeldt e Julia Silge](https://smltar.com/) #### - [Text Mining in Practice with R - Ted Kwartler](https://www.wiley.com/en-us/Text+Mining+in+Practice+with+R-p-9781119282082) ### Cursos #### - [R Básico](https://livro.curso-r.com/3-r-base.html) #### - [Mineraçao de texto - Professor Walmes M. Zeviani](http://leg.ufpr.br/~walmes/ensino/mintex/index.html) #### - [Mineraçao de texto - Professor Carlos Trucíos](https://ctruciosm.github.io/) - [Introdução à mineração de texto](https://ctruciosm.github.io/teaching.html?panelset=short-courses) - - [Aula 1](https://ctruciosm.github.io/IMTR/IMTR#1) - - [Aula 2](https://ctruciosm.github.io/IMTR/IMTR2#1) - - [Aula 3](https://ctruciosm.github.io/IMTR/IMTR3#1) - - [Aula 4](https://ctruciosm.github.io/IMTR/IMTR4#1) #### - [Mineraçao de texto - Dr. Fabrício Barth](http://fbarth.net.br/materiais/cursoBigData/textMining.html) #### - [An introduction to text mining](https://port.sas.ac.uk/mod/book/view.php?id=554) - [Dr Matthew Phillpott](https://port.sas.ac.uk/course/view.php?id=53&section=1) #### - [Curso R - EcoR - USP](http://ecor.ib.usp.br/doku.php?id=start) ### Blogs #### - [Julia Silge - Supervised Machine Learning for Text Analysis in R ](https://www.r-bloggers.com/2020/07/supervised-machine-learning-for-text-analysis-in-r/) #### - [Susan Li - Web Scraping TripAdvisor, Text Mining and Sentiment Analysis for Hotel Reviews](https://towardsdatascience.com/scraping-tripadvisor-text-mining-and-sentiment-analysis-for-hotel-reviews-cc4e20aef333) #### - [Paixão por dados - Sillas Gonzaga](http://sillasgonzaga.com/post/) - [Mineração de textos em notícias de G1](https://ctruciosm.github.io/teaching.html?panelset=short-courses) - [Análise de sentimento usando o lexiconPT](http://sillasgonzaga.com/post/o-sensacionalista-e-text-mining/) #### - [Jodavid Ferreira ](https://jodavid.github.io/posts/) - [Introdução a Web Scraping com R](https://jodavid.github.io/posts/web-scraping-introduction-with-r/) - [Scraping de texto com análise de sentimentos em R](https://jodavid.github.io/posts/2021-06-06-scraping-de-texto-com-an%C3%A1lise-de-sentimento-em-r/) #### - [Marcus Nunes](https://marcusnunes.me/posts/) - [Análise de Sentimentos em R](https://marcusnunes.me/posts/analise-de-sentimentos-com-r-bojack-horseman-vs-brooklyn-99/) #### - [Giuliano Lemes](https://rpubs.com/giuice) - [Analise de Sentimentos - parte 1](https://rpubs.com/giuice/analisesentimentos1) - [Analise de Sentimentos - parte 2](https://rpubs.com/giuice/sentimentos2) #### - [Brian Zive](https://rpubs.com/brianzive) - [Text Mining and N-Grams](https://rpubs.com/brianzive/textmining) ### Extra #### - [Tutorial Quanteda](https://tutorials.quanteda.io/introduction/) #### - [Text Mining](https://medium.com/towards-data-science/search?q=text+mining) #### - [Web Scraping](https://medium.com/towards-data-science/search?q=web+scraping+r) #### - [Deep Learning with R](https://tensorflow.rstudio.com/) #### - [Springboard - text mining](https://www.springboard.com/blog/?s=text+mining) #### - [Datacamp - webscraping](https://www.datacamp.com/tutorial/r-web-scraping-rvest) #### - [rvest](https://rvest.tidyverse.org/index.html) #### - [user_agents](https://techblog.willshouse.com/2012/01/03/most-common-user-agents/) #### - [Programaçao para Humanidades](https://p4husp.github.io/material/textmining/) #### - [Curso R](https://curso-r.github.io/202210-visualizacao/) #### - [Oficinas USP](https://github.com/ngiachetta/OficinaCIS-USP) #### - [R tutorials](https://www.tutorialkart.com/r-tutorial/r-vector-length/) ### Cheatsheets - [R Studio](https://www.rstudio.com/resources/cheatsheets/) - [Emoji](https://github.com/ikatyang/emoji-cheat-sheet) [ToC] É importante escolher o valor certo para n ao usar n-gramas para a pergunta que queremos responder. O uso de unigramas é mais rápido e eficiente, mas não capturamos informações sobre a ordem das palavras. Usar um valor mais alto para n mantém mais informações, mas o espaço vetorial de tokens aumenta drasticamente, correspondendo a uma redução na contagem de tokens. Um ponto de partida sensato na maioria dos casos é três. No entanto, se você não tiver um vocabulário amplo em seu conjunto de dados, considere começar com dois em vez de três e experimentar a partir daí. A Figura 2.2 demonstra como a frequência do token começa a diminuir dramaticamente para trigramas e n-gramas de ordem superior. ![](https://i.imgur.com/TVhvIlE.png) [figura2.2](https://smltar.com/tokenization.html#types-of-tokens) Não estamos limitados a usar apenas um grau de n-gramas. Podemos, por exemplo, combinar unigramas e bigramas em uma análise ou modelo. Obter vários graus de n-gramas é um pouco diferente, dependendo do pacote que você está usando; usando tokenize_ngrams() você pode especificar n e n_min.
{"metaMigratedAt":"2023-06-17T12:04:58.664Z","metaMigratedFrom":"Content","title":"Workshop Análise Textual em R para dados turísticos","breaks":true,"contributors":"[{\"id\":\"fec1dd06-38d4-4ed3-b254-3b207291c375\",\"add\":22572,\"del\":3940}]"}
Expand menu