Um futebol de emoções: wordclouds em python mostram o que disseram os torcedores dos times do campeonato brasileiro de 2021

Capa - Um futebol de emoções


A cada rodada, uma nova emoção: angústia, alívio, decepção, euforia, felicidade, tristeza. O que dizem os torcedores de cada um dos 20 times do campeonato brasileiro de 2021 no Twitter? Será que dá para saber o que sentem com o desenrolar do jogo? Neste projeto de estudo eu tento responder a essas perguntas utilizando a api to twitter com python para extrair, tratar e gerar wordclouds que serão o resultado inicial dessa jornada que já começou incrível cheia de aprendizados. Vambora entender do que se trata, na real, o post de hoje?

Transmissões no Twitter

Nunca fui um usuário ativo no twitter, mas sempre soube do potencial dele como rede social geradora de dados para análises de texto e análise de sentimentos. Ao entrar no twitter do Flamengo para ver o que eu poderia tentar explorar, percebi que o time fazia verdadeiras transmissões durante seus jogos. Minuto a minuto, um tweet com evento do jogo. Leigo, pensei: "Nossa, que incrível isso!". Gols, faltas, substituições... perfeito para se trabalhar, no mínimo, funções de texto para identificação desses eventos. E em cada tweet, centenas e até milhares de compartilhamentos, respostas e likes. Ou seja, as emoções e as reações da torcida - do Flamengo ou a adversária! - a cada minuto, nesta quantidade. Um prato cheio para qualquer interessado em dados, python e análise de sentimentos. Só faltava percorrer os outros 19 times e saber se eles faziam o mesmo. Para minha surpresa, não é que fazem? Claro que não na mesma escala que o Flamengo, afinal nem todo time tem a mesma estrutura, mas todos fazem! Isso era semana passada, antes da estreia do campeonato. A ideia foi esquentando, fui pesquisando as possibilidades e acabei decidindo cair dentro. 

Um Futebol de Emoções

Análise de texto e análise de sentimentos sempre estiveram no meu radar de possibilidades para estudo. Em 2016 eu tentei utilizar o R para botar em prática essa ideia, mas sem muito sucesso. Primeiro porque o que eu tinha acesso na época era uma receita de bolo que me deixava um pouco engessado e segundo porque o próprio fluxo de trabalho não era muito convidativo. Imagina não saber como fazer um loop no R, ter que rodar o código para todos os times, salvar a imagem, fazer upload ... e por aí vai.

A ideia, desde aquela época, sempre foi tentar explorar os tweets e mostrar através dessas análises e de visualizações interessantes como os torcedores de expressavam em tão pouco espaço de escrita. Em apenas 280 caracteres (o limite original de 140 foi dobrado em 2017) o twitter te força a filtrar e condensar ao máximo o que você vai dizer e só pode sair dali um espremido de pura emoção durante a transmissão de um jogo. 

Devido ao fluxo trabalhoso que eu comentei, pensava em fazer só do Flamengo para um ou outro jogo que eu julgassse emocionante o bastante. Hoje, com as ferramentas disponíveis e a vontade não só de aprender, realizar as ideias e compartilhar a experiência com vocês é possível fazer de todos os times nas 38 rodadas. Não é necessário nem se limitar às rodadas, é tanto dado que no caso dos times que transmitem os jogos minuto a minuto a análise das emoções e sentimentos pode se dar nessa frequência aí. Vou fazer toda rodada? É compromisso? Não posso garantir, mas é uma vontade! Utilizo python no google colab e a API para fazer as extrações, e pouco é necessário alterar para executar a cada rodada (a ideia é automatizar o máximo possível). As imagens são geradas automaticamente diretamente no google drive.

Este primeiro passo de construir as wordclouds no python foi o grande motivador para iniciar o projeto. Ter conseguido chegar ao objetivo já me realizou e já dá margem a muitos assuntos para compartilhar com vocês, e embora este post seja vivo (volte de vez em quando para ver as novidades), eu imagino uma série com a seguinte estrutura:

Introdução (este post que você está lendo)
A Estrutura de um Tweet
Transmissões de Futebol no Twitter
A Twitter API V2
Fluxo de Extração e Tratamento dos Tweets
Os Emojis
WordClouds em Python
Análise de Sentimentos
Visualizando as emoções no Tableau
Modelos

Para quem não curte esperar este passo a passo e quiser entender e melhorar este projeto, ele ficará disponível no Git Hub. Cai dentro, é de graça! 

Twitter API V2

O tempo para decidir se eu começaria ou não este projeto na semana passada era curto, devido a uma característica muito importante de como o Twitter disponibiliza as informações através da sua API: somente as publicações dos últimos 7 dias ficam disponíveis para acesso e extração no modo gratuito. Então se eu decidisse fazer, teria que pegar nisso no tempo disponível - final de semana - para já guardar o histórico da primeira rodada.

Entraremos no detalhe no respectivo post, mas fui lá, me inscrevi para ter acesso à API, e aí é aquela jornada de busca pela informação para entender como a coisa toda funciona. E não é fácil, não. Tem muito material disponível, mas a maioria em inglês e é necessário distinguir sobre qual versão da API a comunidade está falando, de qual pacote e até mesmo em que época o post que você está lendo foi escrito, porque tudo muda e às vezes um método que funcionava não serve mais. É preciso ter capacidade de discernir e ficar tentando até conseguir para não ficar no meio do caminho. Foi assim para mim que sei pouco - até sobre a estrutura de um tweet eu tive que ler. Aliás, dá uma espiada na figura abaixo:

Anatomia de um tweet - Flamengo Twitter API V2


Isso, se você não sabe, é um tweet, e com a API você pode acessar cada dado público deste tweet. Você não só extrai o texto em si, mas você tem acesso às mídias, ao número de retweets (compartilhamentos), favoritos (curtidas) e claro, nosso objetivo maior, às respostas a este e qualquer outro tweet, pois é aí que reside a emoção dos torcedores, reagindo ao que foi publicado por uma determinada conta. Se o usuário deixa habilitada sua informação geográfica é possível inclusive acessá-la! O balãozinho embaixo da imagem indica que apenas para este tweet foram 952 respostas (ou comentários), e assim como acontece na interface, onde você precisa clicar para acessar as respostas, na API você precisa acessar o ID da conversa (conversation_id) para baixá-las. Ao clicar neste tweet você vai ver as respostas da seguinte forma:

Exemplos de respostas de tweets
Exemplos de respostas ao tweet do gol do Flamengo no primeiro jogo do campeonato brasileiro.  


Ou seja, primeiro você pega os tweets publicados pelo time, depois com o respectivo id da conversa você pega os tweets dos torcedores que responderam. Isso feito para os 20 times. O twiter limita o acesso às respostas também: somente as 100 primeiras, da mais recente para a mais antiga. Este detalhe é importante, pois se o dado for extraído muito depois do jogo (até no máximo 7 dias, como já falado), no caso de um time muito grande os tweets mais recentes podem na verdade ser frios e não capturar o "calor da emoção". A limitação para o número de respostas pode ser contornado com métodos de paginação e é uma melhoria que pretendo fazer. No momento, esse limite não é um problema pois se encaixa bem no propósito do projeto e permite processar os dados com as máquinas do google colab sem problemas, além de não ocupar muito espaço no google drive. Além disso, não é todo tweet que ultrapassa 100 respostas, então estou captando na maioria das vezes o conteúdo total de respostas disponível.

O ambiente limitado da API do twitter força a adoção de uma estratégia fundamental para manter tudo dentro dos limites. Partindo do pressuposto que os jogos começam na hora e duram por até duas horas, contando o intervalo e tempo adicionais, montei uma tabela com a agenda da rodada e adicionei duas horas a mais em relação a hora inicial do jogo. Nessa primeira rodada, por inspeção visual, não houve perda de tweets, pelo contrário, vieram alguns a mais. Também não vejo problema nisso, pois não há rigor acadêmico nesse estudo. 

Para conseguir filtrar o período do jogo, mais uma dica: é necessário converter a data e hora que é fornecida no tweet para o fuso horário do Brasil. Todas essas informações de agenda ficam num arquivo separado no drive que é importado no início da execução e cujas variáveis vão alimentando os loops subsequentes.

Extração dos Tweets

Falando em loops, são eles os responsáveis pelo trabalho duro na hora de extrair os tweets. Perceba o encadeamento das informações: numa determinada rodada, para cada time, pesquisar os tweets publicados e dentro de cada tweet, acessar cada uma das respostas. Construir essa mecânica não é fácil, pois como em praticamente toda API, você está lidando com uma estrutura nova e possivelmente não documentada, o que torna o trabalho uma espécie de teste e erro até que se conheça a estrutura e se consiga acessar as variáveis de loop e os dados dentro de cada estrutura do JSON (listas, dicionários, e quaisquer combinações aninhadas entre essas duas estruturas). Felizmente, a API do Twitter V2 conta com uma boa documentação, mas também é preciso aprender como entendê-la. É um "open bar" de aprendizado, só de abrir esse link você já vai ver quanta coisa é oferecida.

Para completar, loops só fazem o que você manda. Claro, é programação. Se você não prever exceções, eles podem falhar. Na vontade de trazer o máximo de informações possível, pode ser que nem todo dado esteja disponível para todos os tweets de todos os times. Isso acontece porque às vezes, por algum motivo que ainda desconheço, uma das partes do JSON retornado não é preenchido. Por exemplo, se você deseja identificar a localização geográfica do tweet, poderá apontar para a estrutura do JSON que fornece esta informação, mas se o usuário desabilitou o compartilhamento de sua localização ou se houve algum problema interno no twitter e ele não conseguiu processar o dado, este pedaço de informação dentro do JSON estará vazia e se não houver previsão deste erro dentro do loop for que controla a extração das informações o programa dará erro. Felizmente as exceções puderam ser controladas e com as mais de 22 mil respostas que puderam ser coletadas passamos para a parte de tratamento dos tweets.

Tratamento dos Tweets

Análise de textos e sentimentos tendo tweets como objeto de estudo existem há muito tempo. Portanto, já existe um caminho pavimentado, conhecido e facilmente acessível com algumas boas práticas. Quando pensamos em emoções e sentimentos, podemos retirar de um tweet tudo que não vai adicionar informação relevante na análise das emoções, como links para páginas externas (http/https), menções (marcações de outros usuários) , assim como as famosas stopwords. No código abaixo, como essas extrações se dão no programa:
# CONVERTE TODAS AS LETRAS PARA MINÚSCULO

df_replies0['tweet_text'] = df_replies0['tweet_text'].apply(lambda x: x.lower())

# EXTRAINDO HASHTAGS

df_replies0['hashtag'] = df_replies0['tweet_text'].apply(lambda x: re.findall(r"#(\w+)", x))

# EXTRAINDO MENÇÕES

df_replies0['mentions'] = df_replies0['tweet_text'].apply(lambda x: re.findall(r"@(\w+)", x))

# EXTRAINDO EMOJIS

df_replies0['emojis']  = df_replies0['tweet_text'].apply(lambda x: emojis.get(x))

Stopwords são palavras que podem ser excluídas do texto (neste caso, do tweet) sem perda relevante de significado. Não há consenso sobre uma lista oficial e muitas são as fontes para obtenção de uma. Você pode utilizar as que vêm no pacote NTLK ou fazer uma personalizada. Foi o meu caso, peguei as que vinham no pacote e adicionei as minhas. Para cada projeto você pode utilizar uma lista diferente, pois o contexto poderá ser diferente. Penso que deveria retirar os nomes de jogadores, técnicos e dos próprios times das Wordclouds, mas ainda não resolvi esse dilema. Palavrões? Tem que deixar com certeza 😂, são emoção pura!!Será que retirando esses termos com alta frequência não poderiam aparecer coisas surpreendentes em cada um dos Wordclouds 💭? O desafio é pegar o elenco de cada time e gerar a listagem - o que atrasaria o post - mas fica como mais uma melhoria. O que não pode deixar de fazer é excluí-las, pois como análise de texto é um processo que utiliza de forma muito intensa a criação de grandes tabelas (com uma coluna para cada termo de um twet, por exemplo, dependendo da análise), quanto menos termos desnecessários, melhor. Nesta primeira versão eu tiro o nome dos jogadores e técnicos pois eles tendiam a ocupar um grande espaço, e sem uma visualização que dá contexto acho que fica um pouco sem sentido.

Tem polêmica com as hashtags e com os emoticons também. Eu os apago do texto do tweet, mas os extraio para outras variáveis porque principalmente os emojis resumem a emoção em apenas um caractere, o que pode ser extremamente útil na análise, mas como não está em formato texto, fica em separado aguardando mais desenvolvimentos.

Para os wordclouds gerados até agora, vou tratar os tweets apenas com essas retiradas que mencionei, mas é claro que existem outros outros trataementos, mais precisos e complexos. Vamos com um passo de cada vez: quando as análises exigirem, aplicaremos a normalização, contagem vetorial, lematização, aplicação de frequências diferentes, etc.

Wordclouds

Todo esse trabalho tem que chegar em algum resultado, não é mesmo? Uma forma de visualizar frequências de palavras no corpo de um texto (neste caso, a coleção de tweets coletados durante a transmissão do jogo) é com os chamados Wordclouds ou, em português, nuvem de palavras. Neste tipo de visualização, um determinado número de palavras é arrumado dentro de um retângulo e o tamanho de cada palavra é relativo à frequência (quantidade de ocorrências) com a qual as palavras tratadas aparecem no texto. Não se deve aplicar muito rigor a este tipo de visualização. É uma ferramenta exploratória, e sinceramente acho que as críticas não são muito justas. Wordclouds são uma ferramenta visual popular capaz de trazer as palavras que mais se destacaram no texto e fazer uma conexão rápida com a audiência geral à qual se destina. Para um tema como os tweets relativos ao futebol numa rede social na qual os usuários se expressam em 140 caracteres, as nuvens de palavras cumprem o papel de comunicar o resultado atingido . Claro que existe o problema do tamanho das palavras grandes, do excesso de palavras e cores, mas aí é parcimônia e aplicabilidade de cada estudo. Você pode acessar a galeria clicando na imagem abaixo. Até o próximo post!

Galeria de Word Clouds dos Times do Brasileirão 2021


Postagens mais visitadas deste blog

Anatomia de um Tweet e as transmissões de partidas de futebol pelo Twitter: o supra sumo da emoção

Storytelling com Dados - Box Plots