Projeto 7 – Termômetro de emoções no Whatsapp

Uma Crônica Condomínial: O Síndico, o WhatsApp e a Ciência de Dados

Histórias…

A vida em condomínios é como uma novela, com seus dramas, intrigas e reviravoltas. A minha, no entanto, ganhou um toque bem particular com as últimas eleições para síndico. A disputa acirrada dividiu os moradores em dois grupos, cada um defendendo seu candidato com unhas e dentes. As discussões, que antes se limitavam aos encontros presenciais, ganharam um novo palco: o grupo de WhatsApp do condomínio.

Com a eleição, as conversas se intensificaram. A cada nova decisão do síndico eleito, uma enxurrada de mensagens tomava conta do grupo. E foi nesse frenesi comunicativo que uma ideia me ocorreu: por que não tentar quantificar essa explosão de opiniões? Afinal, a ciência dos dados está em alta, e eu, um apreciador de histórias, não poderia deixar de aplicar um pouco de raciocínio analítico à minha própria vida.

Assim, comecei a desenvolver um pequeno código para rastrear as interações de grupo do condomínio. A cada mensagem enviada, um ponto é adicionado à sua pontuação. Com o passar das semanas, um ranking informal foi tomando forma. Para minha surpresa, os resultados revelaram um perfil bem definido para cada grupo: os mais engajados eram aqueles que, durante a campanha, mais se manifestaram contra o síndico eleito.

O código se tornou uma espécie de termômetro social, capaz de medir a temperatura das relações no condomínio. Mas, além de números e gráficos, essa experiência me proporcionou uma visão mais profunda sobre a dinâmica dos grupos e a importância da comunicação, mesmo que virtual.

Afinal, o WhatsApp, que inicialmente serviu como arena para debates acalorados, acabou se transformando em um espaço de observação e reflexão. E eu, que comecei como um simples observador, me vi imerso em uma verdadeira jornada de descoberta sobre os meus vizinhos e sobre mim mesmo.

Vamos ao código

O primeiro passo é conseguir os dados. Eles foram obtidos a partir do grupo do condomínio.

Consegui um arquivo em formato de texto, um .txt!!!

Com o arquivo em mãos, vamos ver como ele está organizado.

De cara você consegue perceber o seguinte padrão:

[<data> <hora>] <autor>: <mensgem>

Então matutei… e cheguei nesse formato

#Chamar as bibliotecas
import pandas as pd
import re

Em ciências de dados é assim, você acorda, toma um gole d’água e importa o ‘pandas’

A segunda linha é para as expressões regulares, forma mais eficiente que encontrei.

Criei a a função abaixo para tratar o arquivo e criar um dataframe (estrutura do pandas)

def processa_arquivo_texto(file_path):

  with open(file_path, 'r') as f:
    lines = f.readlines()

  data = [] # cria uma lista vazia
  for line in lines:
    # Usa expressão regular para extrair data, hora, autor e mensagem
    pattern = r"\[(.*?)\] (.*?): (.*)" #Esse foi o ponto chave

    match = re.match(pattern, line)
    if match:
      datetime_str = match.group(1)
      autor = match.group(2)
      mensagem = match.group(3)
      # Separa data e hora
      data_hora = datetime_str.split() #divide a estrutura entre os colchetes (data e hora)
      data_str = data_hora[0] # define o primeiro elemento (começa com zero) como data
      hora = data_hora[1] #define o segundo elemento como hora
      data.append([data_str, hora, autor, mensagem]) # insere os elementos criados na lista vazia

  # Cria o DataFrame pandas
  df = pd.DataFrame(data, columns=['data', 'hora', 'autor', 'mensagem'])
  return df

Agora vamos definir o caminho do arquivo

# Caminho do arquivo
file_path = 'arquivo.txt'

Chamamos a função criada e voilà, temos nosso dataframe

 Processa o arquivo e cria o DataFrame
df = process_text_file(file_path)

Analisando as variáveis…

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 17564 entries, 0 to 17563
Data columns (total 4 columns):
 #   Column    Non-Null Count  Dtype 
---  ------    --------------  ----- 
 0   data      17564 non-null  object
 1   hora      17564 non-null  object
 2   autor     17564 non-null  object
 3   mensagem  17564 non-null  object
dtypes: object(4)
memory usage: 549.0+ KB

…percebi que a ‘data’ e a ‘hora’ não estão em formatos adequados. Isso pode trazer problemas quando quisermos realizar um filtro temporal. Assim, vou trabalhar somente o campo data, pois só ele já basta para o que eu estou querendo.

#transformar o campo data em datetime

df['data'] = pd.to_datetime(df['data'], format='%d/%m/%Y', errors='coerce') 

Verifico novamente e voilà, tudo nos conformes!

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 17564 entries, 0 to 17563
Data columns (total 4 columns):
 #   Column    Non-Null Count  Dtype         
---  ------    --------------  -----         
 0   data      17563 non-null  datetime64[ns]
 1   hora      17564 non-null  object        
 2   autor     17564 non-null  object        
 3   mensagem  17564 non-null  object        
dtypes: datetime64[ns](1), object(3)
memory usage: 549.0+ KB

Agora podemos ir para a parte do filtro de datas. A linha de código abaixo vai abrir uma caixa para inserção da data, sendo que ela deve ser colocada no formato dd/mm/YYYY, tipo, por exemplo: 14/09/2024!

data_inicial = input('Inserir data no formato dd/mm/YYYY:')

Coloco o filtro de data inicial para limitar o dataframe e digo para ele contar as interações do autor, a partir daquela data.

As interações se resumem na quantidade de mensagens que o autor enviou. Futuramente poderei fazer um código para “Análise de sentimentos”!

mensagens_por_autor = df['autor'][df.data>=data_inicial].value_counts()

Defino, tal qual foi feito com a data inicial, o tamanho do ranking

hanking = input('Insira a quantidade de posições:  ')

E printo tudo.

hanking = input('Insira a quantidade de posições:  ')
print('==================================')
print(' ')
print('Serão mostrados os '+ hanking+ ' primeiros a partir de '+ data_inicial)
print(' ')
print('==================================')

# Criar um DataFrame com a contagem de mensagens por autor e a posição
ranking_df = pd.DataFrame({'Autor': mensagens_por_autor.index, 'Mensagens': mensagens_por_autor.values}, index=range(1, len(mensagens_por_autor) + 1))

# Mostrar o ranking com a posição
print(ranking_df.head(int(hanking)))

Vai ficar assim. Como não sou bobo, pseudo-anonimizo os dados para preservar as identidades dos vizinhos e para não receber mensagens de whatsapp acaloradas rsrsrsrsrsrsrs

Situação para o dia 01/08/2024, alguns dias antes da eleição.

Inserir data no formato dd/mm/YYYY:  01/08/2024
Insira a quantidade de posições:  10
==================================
 
Serão mostrados os 10 primeiros a partir de 01/08/2024
 
==================================
                             Autor  Mensagens
1                      ~ Condomino A     1359
2                      ~ Condomino B     1087
3                      ~ Condomino C      754
4                      ~ Condomino D      696
5                      ~ Condomino E      633
6                      ~ Condomino F      571
7                      ~ Condomino G      508
8                      ~ Condomino H      487
9                      ~ Condomino I      458
10                     ~ Condomino J      452

Situação a partir de 01/09/2024, alguns dias após da eleição.

Inserir data no formato dd/mm/YYYY:  01/09/2024
Insira a quantidade de posições:  10
==================================
 
Serão mostrados os 10 primeiros a partir de 01/09/2024
 
==================================
                             Autor  Mensagens
1                      ~ Condomino B     561
2                      ~ Condomino I     373
3                      ~ Condomino E     284
4                      ~ Condomino H     223
5                      ~ Condomino D     220
6                      ~ Condomino J     190
7                      ~ Condomino F     182
8                      ~ Condomino A     166
9                      ~ Condomino K     159
10                     ~ Condomino L     146

Percebe-se que o condomino/condomina B interagiu bastante, antes e depois da eleição. Será se ele/ela gostou do resultado?

E você, leitor, já se perguntou como a tecnologia pode influenciar as nossas relações sociais? Compartilhe suas experiências nos comentários!

#condomínio #síndico #whatsapp #dados #históriasdodiaadia

Grande abraço!!!