Pré-processamento de dados é um conjunto de atividades que envolvem converter dados brutos em dados preparados, ou seja, em formatos úteis e eficientes. É um processo que compreende a preparação, organização e estruturação de dados.
Python
R
A segunda etapa no fluxo de trabalho do Jornalismo de Dados é a preparação dos dados antes da análise. Essa etapa, também conhecida como pré-processamento ou limpeza, é o momento em que os dados coletados são padronizados e formatados de modo que não tenha valores estranhos ou incorretos no conjunto de dados final.
Para isso, devo carregar os pacotes necessários e o arquivo gerado na etapa anterior:
library(tidyverse)library(lubridate)library(janitor)library(stopwords)library(tm) #removewordslibrary(tidytext)#unnest tokenslibrary(DT)library(kableExtra)df <-read_rds("dados/02_dados_raspagem_folha.rds") |>clean_names() |># padronizando as colunasglimpse() # Dando uma olhadinha nas colunas
Algumas colunas de texto aparecem com quebras de linha. Vou remover essas marcações e forma:
## removendo quebras de linhasdf$titulos <-gsub("\n|\\t| ", "", df$titulos)df$editoria <-gsub("\n|\\t| ", "", df$editoria)df$texto <-gsub("\n|\\t| ", "", df$texto)## Formatando as datasdf$datas <-gsub(".jan.", "/01/", df$datas)df$datas <-gsub(".fev.", "/02/", df$datas)df$datas <-gsub(".mar.", "/03/", df$datas)df$datas <-gsub(".abr.", "/04/", df$datas)df$datas <-gsub(".mai.", "/05/", df$datas)df$datas <-gsub(".jun.", "/06/", df$datas)df$datas <-gsub(".jul.", "/07/", df$datas)df$datas <-gsub(".ago.", "/08/", df$datas)df$datas <-gsub(".set.", "/09/", df$datas)df$datas <-gsub(".out.", "/10/", df$datas)df$datas <-gsub(".nov.", "/11/", df$datas)df$datas <-gsub(".dez.", "/12/", df$datas)df$datas <-dmy(df$datas)## Excluindo colunasmaterias <- dfmaterias$data_formatada <-NULLmaterias$pesquisa <-NULLmaterias$x2 <-NULLmaterias$horario <-NULLmaterias$texto <-NULLmaterias$edit <-substr(materias$editoria, 1, 16)## Criando colunas titulo_limpo e editoria_limpomaterias<- materias |>mutate(titulo_limpo =tolower(titulos)) |>mutate(editoria_limpo =tolower(editoria))## Removendo a pontuação das colunas titulo_limpo e editoria_limpomaterias$titulo_limpo <-gsub("[[:punct:]]", "", materias$titulo_limpo)materias$editoria_limpo <-gsub("[[:punct:]]", "", materias$editoria_limpo)## Removendo duplicatas e filtrando editoriasmaterias <- materias |>filter(materias$edit =="Folha de S.Paulo")|>distinct(editoria, titulo_limpo, .keep_all =TRUE)|>arrange(datas)write_rds(materias, "dados/03_materias_sem_duplicatas.rds")rm(df)materias$titulo_tidy <- materias$titulo_limpo #duplicando a coluna pra manipular depoismaterias$ano <-year(materias$datas)materias <- materias |>filter(editoria_limpo %in%c("folha de spaulo cotidiano", "folha de spaulo mundo","folha de spaulo ilustrada", "folha de spaulo ilustríssima","folha de spaulo ilustrissima", "folha de spaulo poder","folha de spaulo mercado", "folha de spaulo esporte","folha de spaulo educação","folha de spaulo equilíbrio e saúde","folha de spaulo equilíbrio e saúde","folha de spaulo equilíbrio e opinião"))
Serão análisados na próxima etapa 9900 itens.
Acrescentando mais palavras no conjunto de stopwords
Stopwords são palavras comuns que são frequentemente usadas em uma linguagem, mas que geralmente não contribuem muito para o significado do texto em que aparecem. Essas palavras incluem artigos, preposições, conjunções e outras palavras comuns, como “o”, “a”, “um”, “de”, “para”, “em”, “com”, “e”, entre outras. Em muitas tarefas de processamento de linguagem natural, como análise de sentimentos, classificação de texto e recuperação de informações, as stopwords são removidas do texto para reduzir o ruído e melhorar a precisão dos resultados.
Muitas palavras que não contribuem tanto para o contexto estão entre as mais frequentes porque ainda não foram retiradas as stopwords. O dataframe contando com as stopwords tem 109637 observações.
Removendo as stopwords, o dataframe resultante tem 71702 linhas
tidy_df$palavra <-removeWords(tidy_df$palavra, stopwords_final)tidy_df <-subset(tidy_df, palavra !="")head(tidy_df) #visualizando os resultados
# A tibble: 6 × 10
x1 datas editoria titulos url edit titulo_limpo editoria_limpo
<dbl> <date> <chr> <chr> <chr> <chr> <chr> <chr>
1 7517 2013-01-02 Folha de S.P… Veread… http… Folh… vereadores … folha de spau…
2 7517 2013-01-02 Folha de S.P… Veread… http… Folh… vereadores … folha de spau…
3 7517 2013-01-02 Folha de S.P… Veread… http… Folh… vereadores … folha de spau…
4 7517 2013-01-02 Folha de S.P… Veread… http… Folh… vereadores … folha de spau…
5 7517 2013-01-02 Folha de S.P… Veread… http… Folh… vereadores … folha de spau…
6 7517 2013-01-02 Folha de S.P… Veread… http… Folh… vereadores … folha de spau…
# ℹ 2 more variables: ano <dbl>, palavra <chr>
Dicionário de Palavras Raciais
Este trecho lê um arquivo CSV chamado “dicionario_termos.csv”, que contém um dicionário de termos relacionados a raça e cor. Esse dicionário será usado para identificar palavras específicas durante a análise.
A definição de termos raciais foi feita da seguinte forma:
Fiz alguns prompts no ChatGPT, como “liste 100 personalidades negras e justifique”, “me dê uma lista de termos relacionados a cor/raça negra”
Em seguida, fiz uma limpeza “manual”: conferi se as justificativas estavam coerentes e acrescentei palavras faltantes.
O código abaixo lida com a análise de texto e tem como objetivo agrupar palavras de um dicionário em categorias e, em seguida, verificar se essas palavras ou categorias estão presentes em títulos de algum conjunto de dados. Aqui está uma explicação passo a passo do que o código faz:
Agrupar as palavras por categoria:
O código começa criando um novo dataframe chamado df_nested.
Ele usa o operador pipe (%>%) que é comum em pacotes como o dplyr para encadear operações. O dicionario parece ser um dataframe ou tibble que contém uma coluna chamada “palavra”.
O nest(palavra) agrupa as palavras do dicionário em listas aninhadas no dataframe df_nested, de forma que cada lista interna corresponda a uma categoria de palavras.
Converter o dataframe em uma lista de listas:
O código cria uma variável chamada lista_palavras que extrai a coluna data do dataframe df_nested. Essa coluna agora contém listas de palavras agrupadas por categoria.
Converter cada lista interna em uma lista:
A variável listas_palavras é criada usando a função map para percorrer a variável lista_palavras e converter cada lista interna em uma lista separada.
Verificar a presença das palavras em títulos:
O código cria uma nova coluna chamada nova_coluna no dataframe titulos_palavras usando map_lgl. Ele percorre a coluna titulo_limpo do dataframe titulos_palavras e verifica se alguma das palavras ou categorias do dicionário está presente nos títulos. A função str_detect é usada para essa verificação, e o resultado é uma coluna de valores booleanos (TRUE ou FALSE) indicando se alguma palavra do dicionário está presente em cada título.
Extrair palavras identificadas:
O código cria uma nova coluna chamada strings_identificadas no dataframe titulos_palavras. Ele percorre a coluna titulo_limpo e usa str_extract_all para extrair todas as palavras ou categorias do dicionário que estão presentes em cada título. O resultado é uma lista de palavras ou categorias para cada título.
Remover palavras irrelevantes:
A variável palavra no dataframe titulos_palavras parece ser limpa, removendo palavras irrelevantes (stopwords) usando a função removeWords. As stopwords são frequentemente palavras comuns que podem não ser informativas para a análise de texto, como “a”, “de”, “para”, etc.
Filtrar títulos com correspondências:
Finalmente, o código cria um novo dataframe chamado titulos_palavras_true usando o operador pipe (|>) para filtrar apenas as linhas em que a coluna nova_coluna tem o valor TRUE. Isso significa que ele está selecionando apenas os títulos que contêm palavras ou categorias do dicionário.
Portanto, o resultado final, armazenado em titulos_palavras_true, contém os títulos que contêm palavras ou categorias do dicionário, após a limpeza e verificação realizadas no código.
# Agrupar as palavras por categoriadf_nested <- dicionario %>%nest(palavra)# Converter o dataframe em uma lista de listaslista_palavras <- df_nested %>%pull(data)# Converter cada lista interna em uma listalistas_palavras <- lista_palavras %>%map(as.list)tidy_df$nova_coluna <-map_lgl(tidy_df$titulo_limpo, function(x) any(str_detect(x, paste(unlist(listas_palavras), collapse ="|"))))tidy_df$strings_identificadas <-map(tidy_df$titulo_limpo, function(x) unlist(str_extract_all(x, paste(unlist(listas_palavras), collapse ="|"))))tidy_df$palavra <-removeWords(tidy_df$palavra, stopwords_final)tidy_df <-subset(tidy_df, palavra !="")tidy_df_true <- tidy_df |>filter(nova_coluna==TRUE)tidy_df_false <- tidy_df |>filter(nova_coluna==FALSE)write_rds(tidy_df_true, "dados/04_titulos_palavras.rds")write_csv2(tidy_df_true, "dados/04_titulos_palavras.csv")
titulos_bigramas
Semelhante ao arquivo anterior, esse será utilizado na análise de bigramas
Arquivos criados para o reconhecimento de entidades nomeadas e análise pós-tagging
Esta etapa, diferentemente das outras, foi feita com Python e Excel
Os dados gerados foram limpos novamente, no Excel.
dados_ner <-read.csv2("dados/05_materias_pos_tagging_wide2.csv") |>select("X","datas","editoria","titulos","url","edit","titulo_limpo","editoria_limpo","ano","palavra", "classe_gramatical") |>filter(editoria_limpo %in%c("folha de spaulo cotidiano", "folha de spaulo mundo","folha de spaulo ilustrada", "folha de spaulo ilustríssima","folha de spaulo ilustrissima", "folha de spaulo poder","folha de spaulo mercado", "folha de spaulo esporte","folha de spaulo educação","folha de spaulo opinião","folha de spaulo educação")) |>clean_names() |>mutate(valor_limpo =tolower(palavra)) |>subset(palavra !="")dados_classe <-read.csv2("dados/05_materias_pos_tagging_wide2.csv") |>select("X","datas","editoria","titulos","url","edit","titulo_limpo","editoria_limpo","ano","entidade", "tipo_entidade") |>filter(editoria_limpo %in%c("folha de spaulo cotidiano", "folha de spaulo mundo","folha de spaulo ilustrada", "folha de spaulo ilustríssima","folha de spaulo ilustrissima", "folha de spaulo poder","folha de spaulo mercado", "folha de spaulo esporte","folha de spaulo educação","folha de spaulo opinião","folha de spaulo educação")) |>clean_names() |>mutate(valor_limpo =tolower(entidade)) |>subset(entidade !="")## Backup#write_csv2(dados_ner, "dados/08_materias_pos_tagging_classe_gramatical.csv")write_csv2(dados_classe, "dados/08_materias_pos_tagging_entidades.csv")