O que é

Protótipo simples de uma pesquisa usando ferramentas de jurimetria para que possamos realizar análises de dados sobre processos e decisões judiciais. Basicamente, a ideia é coletar dados de processos e transformá-los em formatos que propiciem análises, inclusive estatísticas, que possam ser úteis para nós.

Primeiro passo: definir o objeto

É fundamental termos claro o escopo e objetivo da pesquisa. Com isso, devemos fazer uma análise de viabilidade a fim de verificar se o dado é possível de ser extraído e analisado.

Se o volume for muito pequeno, corremos o risco de ser pouco relevante ou representativo. Se o volume for excessivo, teremos dificuldades para baixar, armazenar e processar.

Devemos também entender muito bem o problema para estabelecer as melhores estratégias de extração. Apesar disso, nada impede de fazermos diversos testes e análises mais exploratórias a fim de entender o quão “redondo” está nossa metodologia.

É importante definir:

Ciclo da ciência de dados

Exemplo: Aplicação do HC coletivo 165.704

Para demonstrar como funciona, vamos tomar como exemplo uma pesquisa simples sobre a aplicação do HC coletivo 165.704 (sobre mães e pais custodiados) para verificar como o TJ-SP vem aplicando a decisão.

Vamos ter em mente o ciclo descrito acima e tentar aplicar para essa situação concreta.

Aspecto Definição
Tribunal: TJ-SP
Espaço de tempo: Considerando que o HC é recente, de 2018, o foco será a partir dele.
Instância Apenas 2º grau
Classe processual Habeas corpus apenas
Termo de pesquisa Quero todas as decisões que mencionem o HC 165.704

Tendo isso em mente, vou até a busca de jurisprudência de segundo grau do TJ-SP fazer testes de termos de pesquisa que me interesssem. É super importante também olhar as orientações do Tribunal sobre o mecanismos de pesquisa:

Operador E : permite consultar os documentos que contenham todas as palavras informadas. Exemplo: furto E assalto E carro.

Quando nenhum operador é indicado, o E é utilizado por padrão.

Operador OU: consulta os documentos que contenham todas as palavras informadas ou apenas uma delas. Exemplo: bicicleta OU carro OU motocicleta.

Operador NÃO: a consulta é feita excluindo determinada palavra da busca. Por exemplo, se eu digitar NÃO assassinato, o sistema busca textos que não contenham a palavra assassinato.

Operador ?: permite consulta de palavras no documento que contenham um caractere qualquer, substituindo uma letra. Exemplo: ca?a para casa, cada, cara. Lembre-se que o operador ? não pode ser utilizado no início dos termos de pesquisa. Qualquer outra combinação é válida.

Operador " ": pesquisa por frases exatas. Por exemplo, a pesquisa “área de preservação permanente” somente trará ocorrências que contenham essa frase exatamente como ela foi digitada. Para resultados precisos, a frase pesquisada deve conter no máximo cinco palavras.

Além dos operadores apresentados, você também pode utilizar o parêntese para pesquisas mais complexas. Por exemplo, ao pesquisar “plano de saúde” E angioplastia OU ecocardiograma, não está explícito qual operação será desenvolvida primeiro, contudo, se você utilizar a seguinte ordem “plano de saúde” E (angioplastia OU ecocardiograma), entre parênteses, o resultado da pesquisa exibirá todas as ocorrências que contenham a frase “plano de saúde” e a palavra “angioplastia”, juntamente com todas as ocorrências que contenham a frase “plano de saúde” e a palavra “ecocardiograma”.

Tendo tudo isso em mente, o raciocínio que foi:

  1. Preciso que as expressões “HC” e “165.704” estejam presentes: pesquisando por HC 165704 aparecem apenas 24 decisões, muito pouco.

  2. Vou tentar então apenas o número: “165704”. Aparecem apenas 27 decisões.

  3. O problema pode ser que ao se referir a ela, algumas mencionem o “.” e outras não. Eu poderia então usar o operador OU (165704 OU 165.704): já sobe para 148, bem melhor.

  4. Eu também poderia acrescentar a expressão que remeta a habeas corpus. Por exemplo, “HC” ou usar “habeas corpus” por extenso. Ou, ainda, usando os operadores de busca, tentar algo como "hc OU "habeas corpus". Fazendo o teste com(165704 OU 165.704) E (hc OU "habeas corpus") tenho 143 decisões.

Nesse caso, vou optar por fazer a pesquisa com a expressão 165704 OU 165.704, do item 3, que pareceu mais adequada.

Bom lembrar que a pesquisa do TJ-SP é bastante poderosa e permite vários outros parâmetros. Em casos em que eu tenha muita decisões mas potencialmente poucas úteis, vale a pena explorar aqueles filtros. O importante é sempre anotar os parâmetros usados para poder passar eles para o mecanismo de raspagem.

Raspando os dados: pacote tjsp do R

Estamos usando o software R para realizar as raspagens e análises. Recomenda-se vivamente que para prosseguir você tenha o R e o RStudio instalado e que faça os passos a seguir usando um novo projeto. Também é recomendável instalar o pacote tidyverse. A seguir referências de como fazer isso:

Feitas essas etapas, podemos continuar.

Foram desenvolvidos alguns pacotes de raspagem de dados de interesse da jurimetria,dentre eles vários feitos pelo prof. José de Jesus.

Como definimos nesse exemplo o interesse em pesquisar o TJ-SP, vamos usar o pacote que ele desenvolveu para essa finalidade, chamado “tjsp”.

library(magrittr) # pacote para facilitar a escrita das funções

# caso eu não tenha instalado preciso rodar:
# install.packages("remotes")
# remotes::install_github("jjesusfilho/tjsp")

# após instalar:
library(tjsp) # carrega o pacote propriamente dito

O primeiro passo, então, é requisitar ao pacote que baixe os dados que queremos. Vamos então salvar a expressão de busca em uma variável de texto e chamar a função que realiza a pesquisa propriamente dita.

Usaremos a função tjsp_baixar_cjsg() (sabendo que “cjsg” significa “consulta julgados de segundo grau”), preenchendo o parâmetro: livrecom nosso termo de pesquisa e diretorio com a pasta que vamos usar.

O pacote tem uma série de outros parâmetros que podem ser usados na pesquisa como classe, assunto, orgao_julgador, data de início, data de fim, etc. Recomendo a leitura da documentação usando o comando ?tjsp_baixar_cjsg()

# Expressão de busca que definimos no item 3

exp <- '165704 OU 165.704'

# Escolher uma pasta para receber os resultados

pasta <- "data-raw/pesquisa_jurisprudencia_exemplo"

# Vou criar essa pasta no meu computador para salvar os resultados:
usethis::use_directory(pasta)
# Realizar a pesquisa:
baixar_cjsg(livre = exp, 
                  diretorio = pasta)

A depender do tamanho da pesquisa, ela pode levar alguns minutos (ou mesmo algumas horas).

Com isso, eu já tenho condições preliminares de colocar em uma mesma tabela todas as informações básicas da pesquisa. Vou poder saber quantidade, assunto de cada uma delas, qual foi a data de julgamento, relator(a), ementa, etc.

A função para essa leitura preliminar é ler_cjsg() na qual eu vou colocar como parâmetro a pasta que utilizei para salvar a busca.

Posso criar uma tabela com isso e até mesmo exportar para excel ou outros formatos:

# ler a tabela
tabela <- ler_cjsg(diretorio = pasta)

# olhar os resultados
tabela
## # A tibble: 148 x 10
##    classe assunto relator comarca orgao_julgador data_julgamento data_publicacao
##    <chr>  <chr>   <chr>   <chr>   <chr>          <date>          <date>         
##  1 Embar~ Homicí~ Luiz A~ Diadema 3ª Câmara de ~ 2021-06-21      2021-06-21     
##  2 Habea~ Tráfic~ Albert~ Presid~ 7ª Câmara de ~ 2021-06-21      2021-06-21     
##  3 Habea~ Tráfic~ Robert~ São Be~ 4ª Câmara de ~ 2021-06-15      2021-06-15     
##  4 Habea~ Roubo   Eduard~ Guarul~ 6ª Câmara de ~ 2021-06-09      2021-06-09     
##  5 Habea~ Homicí~ Euvald~ Mogi d~ 4ª Câmara de ~ 2021-06-09      2021-06-09     
##  6 Habea~ Tráfic~ Cesar ~ Guarar~ 3ª Câmara de ~ 2021-06-08      2021-06-08     
##  7 Habea~ Quadri~ Amable~ Sumaré  12ª Câmara de~ 2021-06-07      2021-06-07     
##  8 Habea~ Homicí~ Laerte~ Limeira 14ª Câmara de~ 2021-06-06      2021-06-06     
##  9 Habea~ Tráfic~ Edison~ Ubatuba 4ª Câmara de ~ 2021-06-02      2021-06-02     
## 10 Habea~ Roubo ~ Fátima~ Cajuru  9ª Câmara de ~ 2021-05-28      2021-05-28     
## # ... with 138 more rows, and 3 more variables: processo <chr>, ementa <chr>,
## #   cdacordao <chr>

Podem acontecer alguns erros de leitura, mas em geral não vai ser um problema.

Exemplo de exportação para o formato excel:

writexl::write_xlsx(tabela, path = "data-raw/tabela_basica_jurisprudencia.xlsx")

E ela poderá ser lida normalmente:

Essa primeira tabela é útil para algmas análises exploratórias simples:

# Quantas decisões temos?

nrow(tabela)
## [1] 148
# Quais as comarcas com mais decisões?

tabela %>% 
  dplyr::group_by(comarca) %>% # agrupar por comarcas
  dplyr::count(sort = TRUE) %>% # contar ocorrências
  head() %>% # ver os primeiros resultados
  knitr::kable() # gerar tabela
comarca n
São Paulo 24
Ribeirão Preto 9
Limeira 6
Campinas 5
Bauru 4
Comarca nâo informada 4

Além dessas análises simples, essa tabela inicial é importante para permitir que sejam baixados os andamentos, as partes, resultado do julgamento e o texto do acórdão em si.

Baixando o restante dos dados

Embora o que se possa obter até aqui já seja provavelmente suficiente para uma análise preliminar de viabilidade do tema, normalmente vamos querer extrair mais informações do Tribunal.

No caso do TJ-SP, para as etapas a seguir é fundamental que possua um login no sistema e-saj e que utilize aqui uma função de autenticação. Não sei informar se é preciso possuir login de advogado(a) ou se qualquer um basta. Em todo caso, recomendo se habilitar no sistema: https://esaj.tjsp.jus.br/sajcas/login?service=https%3A%2F%2Fesaj.tjsp.jus.br%2Fesaj%2Fj_spring_cas_security_check#

Feito o cadastro, para poder acessar os dados o pacote possui uma função que realiza para nós a autenticação:

# asssim, ela irá abrir uma janela pedindo login e senha
tjsp::autenticar()

# posso também colocar diretamente esses dados nos parâmetros da função
# contudo, MUITO cuidado se isso for se tornar público uma vez que o login é o próprio CPF e a senha tampouco queremos que seja usada por terceiros:

tjsp::autenticar(login = <seu login>, password = <sua senha>)

Feita a autenticação, podemos prosseguir baixando mais dados:

Baixar detalhes:

Para isso vamos usar a função tjsp_baixar_cposg() colocando como parâmetros a coluna da tabela onde estão os números do processo e a pasta onde queremos que tudo seja salvo.

# crio uma nova pasta dentro da pasta anterior
# definir o nome:
pasta_detalhes <- paste0(pasta, "/detalhes")

# criar a pasta:
usethis::use_directory(pasta_detalhes)
# baixar os detalhes em si
tjsp_baixar_cposg(processos = tabela$processo, diretorio = pasta_detalhes)

Baixar os acórdãos:

O pacote também permite baixar o inteiro teor dos acórdãos (em .pdf) para depois poder analisar o texto com o R. Isso pode levar alguns minutos ou mesmo horas caso o volume seja grande.

A função é tjsp_baixar_acordaos_cposg()e vamos usar os mesmos parâmetros da anterior

# dou um nome para uma nova pasta, para que tudo fique organizado
pasta_acordaos <- paste0(pasta, "/acordaos")

# criar a pasata:
usethis::use_directory(pasta_acordaos)
# rodar a função que baixa
tjsp::tjsp_baixar_acordaos_cposg(
  processos = tabela$processo,
  diretorio = pasta_acordaos)

Ler os arquivos baixados

Agora que baixamos os dados podemos usar outas funções do pacote para extrair mais informações de nosso interesse. Lembrando que a etapa de baixar não precisa ser repetida no futuro, uma vez que os arquivos estarão salvos no seu disco.

Apenas iremos repetir a etapa de baixar do Tribunal caso queiramos dados mais atualizados ou novas decisões não abrangidas pela busca inicial. Nesse caso, pode ser uma boa usar na nova busca os parâmetros que permitem definir as datas de início e fim, para abranger apenas as decisões que já não foram baixadas.

Ler as partes e andamentos

Pra isso vamos criar duas variáveis que vão receber o resultado das funções que buscam, respectivamente, as partes e os andamentos. O parâmetro usado nas duas é o mesmo: o diretorio, que será a a pasta que criamos e salvamos como pasta_detalhes.

# ler as partes
partes <- tjsp_ler_partes(diretorio = pasta_detalhes)

# ver o resultado
partes
## # A tibble: 485 x 4
##    processo     tipo_parte   parte             representante                    
##    <chr>        <chr>        <chr>             <chr>                            
##  1 00033666420~ Agravante:   Jhonatas brito d~ "Advogado:&nbspRoberto Neiva Fer~
##  2 00033666420~ Agravado:    Ministério Públi~  <NA>                            
##  3 00034757720~ Agravante:   MARCOS ADRIANO B~ "Advogado:&nbspRonaldo Vaz da Si~
##  4 00034757720~ Agravado:    Ministério Públi~  <NA>                            
##  5 00123465120~ Paciente:    Renato de Mendon~ "Advogado:&nbspMarlon Heghys Gio~
##  6 00123465120~ Impetrante:  Marlon Heghys Gi~  <NA>                            
##  7 00134836820~ Paciente:    Rodrigo Fernando~ "Advogado:&nbspDomingos Gerage \~
##  8 00134836820~ Impetrante:  Domingos Gerage    <NA>                            
##  9 00134836820~ Impetrante:  Danilo Aurelio O~  <NA>                            
## 10 00305499520~ Impette/Pac~ Fernando Luis de~  <NA>                            
## # ... with 475 more rows
# ler os andamentos
andamentos <- tjsp::ler_movimentacao_cposg(diretorio = pasta_detalhes)

# ver o resultado
andamentos
## # A tibble: 4,357 x 3
##    processo         data       movimentacao                                     
##    <chr>            <date>     <chr>                                            
##  1 000336664202182~ 2021-06-05 "Expedido Certidão\n\t        \t\t\n\t        \t~
##  2 000336664202182~ 2021-05-27 "Publicado em\n\t        \t\n\t\t\t\n\t\t\t\n\t\~
##  3 000336664202182~ 2021-05-27 "Expedido Certidão\n\t        \t\t\n\t        \t~
##  4 000336664202182~ 2021-05-26 "Ciência de acórdão - Prazo - 15 dias\n\t       ~
##  5 000336664202182~ 2021-05-26 "Expedido Certidão\n\t        \t\t\n\t        \t~
##  6 000336664202182~ 2021-05-22 "Mensagem Eletrônica (e-mail) Juntada"           
##  7 000336664202182~ 2021-05-22 "Mensagem Eletrônica (e-mail) Juntada"           
##  8 000336664202182~ 2021-05-21 "Expedido Ofício\n\t        \t\t\n\t        \t\n~
##  9 000336664202182~ 2021-05-21 "Acórdão registrado\n\t        \t\n\t\t\t\n\t\t\~
## 10 000336664202182~ 2021-05-20 "Processo encaminhado para o Processamento de Gr~
## # ... with 4,347 more rows

Ler dispositivo da decisão

Embora tenhamos baixado o inteiro teor dos acórdãos, é razoavelmente complexo manusear esses arquivos. Temos uma vantagem no TJ-SP que é o fato de a tira de julgamento, isto é, o resultado do que foi decidido pelo Tribunal fica num campo explicitamente separado.

Isso permite saber o resultado dos julgamentos sem necessariamente ter que ler os arquivos .pdf.

# ler o dispositivo das decisões
dispositivo <- tjsp_ler_dispositivo(diretorio = pasta_detalhes)

# ver o resultado
dispositivo
## # A tibble: 134 x 3
##    processo         data       dispositivo                                      
##    <chr>            <date>     <chr>                                            
##  1 000336664202182~ 2021-05-20 Conheceram em parte do recurso e, na parte conhe~
##  2 000347577202082~ 2021-03-30 Negaram provimento ao recurso. V. U.             
##  3 001234651202182~ 2021-04-29 Denegaram a ordem. V. U.                         
##  4 001348368202182~ 2021-05-19 Não conheceram da impetração. V.U.               
##  5 003054995202082~ 2021-06-06 Denegaram a ordem. V. U.                         
##  6 003094487202082~ 2020-11-17 por votação unânime, denegaram a presente ordem ~
##  7 003737924202082~ 2021-02-11 Negaram provimento ao recurso. V. U.             
##  8 004193185202082~ 2021-06-09 Denegaram a ordem. V. U.                         
##  9 006646655199582~ NA         <NA>                                             
## 10 150109425201982~ 2020-11-12 Negaram provimento ao recurso. V. U.             
## # ... with 124 more rows

Alguns exemplos de análises

Temos então baixados os dados de todas as decisões que atenderam ao nosso termo de pesquisa definido acima.

Agora, podemos fazer análises mais aprofundadas. Sugere-se começar com perguntas mais amplas e, depois, ir aprofundando nos cruzamentos. Também, com apoio de metodologias de pesquisa e de estatísticas é possível aplicar técnicas mais robustas de análise, inclusive machine learning, análise de linguagem natural e outras ferramentas. O céu é o limite!

Naturalmente, antes de obter dados confiáveis, é preciso conhecer bem os dados e verificar inconsistências, realizar filtragens e adaptações.

Alguns exemplos de perguntas que podem ser interessantes:

  1. Quantas decisões concedem o HC e quantas negam?
  2. Quais as câmaras que mais negam? E quais mais deferem?
  3. Distribuição das ações ao longo do tempo. Há algum padrão? Há alguma sazonalidade? Há algum pico?
  4. Quanto tempo essas decisões tramitam?
  5. Há liminar? Em quais? A liminar tende a ser confirmada?
  6. A audiência pública ocorrida em 14/06 mudou as decisões que vieram depois?
  7. É possível agrupar comarcas em razão do peril das decisões proferidas?
  8. etc

Claro que nem sempre todas as perguntas poderão ser respondidas com os dados que possuímos. Como nosso objetivo aqui é meramente exemplificar, vamos apenas demonstrar um gráfico simples mostrando como foram julgadas as causas.

library(ggplot2) # carrega biblioteca que desenha gráficos

dispositivo %>% 
  dplyr::filter(!is.na(dispositivo)) %>% # tirar os vazios
  dplyr::mutate( 
    # avaliar qual foi o resultado da decisão
    resultado = tjsp_classificar_writ(dispositivo)
  ) %>%
  # conta os resultados
  dplyr::count(resultado) %>% 
  # cria um gráfico
  ggplot(aes(x = forcats::fct_reorder(resultado, n, .desc = T), y = n)) +
  geom_col() +
  theme_classic() +
  labs(x = "Decisão", y = "Quantidade", 
       title = "Aplicação do TJ-SP do HC Coletivo 165.704",
       subtitle = "Decisões proferidas em habeas corpus")

tabela %>% 
  dplyr::left_join(dispositivo) %>% 
  dplyr::filter(classe == "Habeas Corpus Criminal", !is.na(dispositivo)) %>% 
   dplyr::mutate( 
    # avaliar qual foi o resultado da decisão
    resultado = tjsp_classificar_writ(dispositivo),
    orgao_julgador = stringr::str_remove(orgao_julgador, " Câmara de Direito"),
  ) %>% 
  dplyr::group_by(orgao_julgador) %>% 
  dplyr::count(resultado) %>%
  ggplot(aes(x = forcats::fct_reorder(orgao_julgador, n, .desc = T), 
             y = n, 
             fill = resultado)) +
  geom_col() +
  theme_classic() +
  scale_fill_brewer(palette = "Dark2") +
  labs(x = "Câmara", y = "Quant. decisões",
       title = "Decisões do TJ-SP sobre aplicação do HC Coletivo",
       subtitle = "Distribuição por Câmara de Direito Criminal") +
  theme(axis.text.x = element_text(angle = 90))