Olá! Me chamo João Miranda e serei o seu instrutor ao longo deste curso.
Audiodescrição: João é um homem de pele clara, com cabelo curto e barba também curta. Veste uma camisa preta, sem estampas. Ao fundo, há uma parede iluminada em tons de verde e azul.
Já consideraram a possibilidade de utilizar modelos de NLP ("Processamento de Linguagem Natural") para identificar entidades como pessoas, organizações e outros elementos em textos de maneira automatizada?
Neste curso, construiremos uma aplicação prática que será capaz de identificar entidades nomeadas em textos jurídicos. Ao longo do projeto, realizaremos diversas etapas de tratamento de dados textuais, rotularemos as informações no formato IOB ("Inside-Outside-Beginning") e treinaremos um modelo de NLP com a capacidade de reconhecer palavras e expressões específicas em documentos.
Utilizaremos modelos tradicionais da biblioteca SpaCy. Portanto, não aprenderemos a realizar esse tipo de tarefa com modelos LLN ("Large Language Models"). Ao final do curso, teremos essa aplicação que está sendo mostrada na tela.
Endereço acessado pelo instrutor:
localhost:8501
Nessa aplicação, haverá um título "Reconhecimento de Entidades Nomeadas". Abaixo, podemos escolher a opção de um texto ("Texto") que podemos inserir manualmente ou um arquivo do computador ("Arquivo").
Neste arquivo, é possível clicar no botão "Browse Files" à direita para selecionar o arquivo desejado. Ao realizar um duplo clique no arquivo desejado, a aplicação será capaz de reconhecer automaticamente todas as entidades presentes no texto. Durante o desenvolvimento do projeto, as entidades selecionadas poderão ser filtradas, permitindo decidir quais serão destacadas dentro do conteúdo textual.
Essa aplicação é bastante completa e muito útil para agilizar procedimentos jurídicos, pois acelera o processo de análise desses documentos. Esse mesmo processo pode ser aplicado em diversas áreas, não apenas em documentos jurídicos.
Para acompanhar o conteúdo, é necessário que você tenha conhecimento na linguagem de programação Python e também conceitos de Machine Learning.
Vamos começar?
Uma empresa de advocacia está buscando soluções tecnológicas para otimizar o processamento de documentos jurídicos e melhorar a gestão dos processos em andamento.
Atualmente, o escritório lida com uma grande quantidade de contratos, petições, jurisprudências e outros documentos legais, mas não existe uma forma eficiente de extrair essas informações críticas de forma automática, como, por exemplo:
Nosso papel neste projeto consiste em desenvolver um modelo de NLP especializado na tarefa de reconhecimento de entidades nomeadas, também conhecida como NER ("Named Entity Recognition").
Esse modelo será capaz de identificar e classificar automaticamente informações relevantes em textos jurídicos, como partes envolvidas, datas e dispositivos legais.
Com isso, as pessoas advogadas e das equipes terão acesso mais rápido a dados cruciais, o que contribuirá para otimizar o tempo dedicado à análise, reduzir o risco de erros humanos e melhorar a gestão dos processos de forma mais eficiente e assertiva.
Para construir um modelo que identifique as entidades nomeadas específicas para o nosso problema, utilizaremos o Google Colab. O primeiro passo será carregar os textos jurídicos, que utilizaremos em nosso modelo. Para isso, no menu lateral esquerdo, selecionaremos a opção "Arquivos" (ícone de arquivo) e clicaremos em "Fazer Upload para o armazenamento da sessão" na parte superior esquerda.
Em seguida, selecionaremos o arquivo texts.zip
, que estará disponível na atividade "Preparando Ambiente".
É importante fazer o download do arquivo
texts.zip
antes de continuar, para garantir que ele esteja disponível para o projeto.
Após selecionar o arquivo, clicamos duas vezes nele, e o Colab fará o upload para a aba de arquivos.
Podemos então ler este arquivo, que é um arquivo compactado contendo vários arquivos .txt
. Para isso, usaremos a biblioteca zipfile
. Na primeira célula, escreveremos:
import zipfile
Pressionaremos "Ctrl + Enter" para executar a célula. Durante esse tempo, o arquivo será carregado à esquerda no Colab:
texts.zip
Acessamos o caminho do arquivo clicando nos três pontos ao lado do nome do arquivo e selecionando a opção "Copiar Caminho". Na próxima célula, utilizaremos a biblioteca zipfile
para fazer a leitura desse arquivo compactado.
Digitamos with zipfile
e utilizamos a função .ZipFile()
, passando o caminho do arquivo entre aspas simples: with zipfile.ZipFile('/content/texts.zip')
. Em seguida, adicionamos uma vírgula e colocamos como segundo parâmetro a letra 'r'
indicando que realizaremos a leitura desse arquivo ("read").
Fora dos parênteses, adicionamos um apelido para o arquivo com as zip:
. Na linha seguinte da mesma célula, após realizar a leitura, listamos os arquivos presentes dentro do arquivo compactado utilizando print(zip.namelist())
.
with zipfile.ZipFile('/content/texts.zip', 'r') as zip:
print(zip.namelist())
Ao executar "Ctrl + Enter", obteremos uma lista com os nomes de todos os arquivos.
['ADI2TJDFT.txt', 'adi3767.txt', 'Ag10000170733596001.txt', 'Ag10105170208398001.txt', 'AgAIRR11889820145030011.txt', 'AgCr10582160008758001.txt', 'AgRgSTJ1.txt', 'AgRgSTJ2.txt', 'AgRgTSE1.txt', 'AgRgTSE3.txt', 'AIAgRAgI6193ARAGUARIMG.txt', 'airr801422012.txt', 'AIRR3999520145020086.txt', 'AIRR15708820115050222.txt', 'AP00000794920137060006.txt', 'AP00001415620157010201.txt', 'AP00001441420167030203.txt', 'AP771420167080008PA.txt', 'CP32320177080008PA.txt', 'DespSEPLAGDF.txt', 'ED1STM.txt', 'ED1TJAC.txt', 'EDAgRgTSE2.txt', 'EDEDARR208420135040232.txt', 'EDRR1TST.txt', 'EEDRR9715120105020002.txt', 'ERR731004520105130003.txt', 'HC110260SP.txt', 'HC151914AgRES.txt', 'HC340624SP.txt', 'HC418951PR.txt', 'HC70000845920187000000.txt', 'lei11340.txt', 'Lei11788.txt', 'LoaDF2018.txt', 'Pet128TSE5.txt', 'Port77DF.txt', 'Rcl3495STJ.txt', 'REE5908TSE4.txt', 'REsp1583083RS.txt', 'RR474820145230056.txt', 'RR942006420095040028.txt', 'RR2574407120025020372.txt', 'TCU4687.txt', 'TSTRR16037920105200001.txt', 'AC1TCU.txt', 'AC1TJAC.txt', 'AC1TJMG.txt', 'AC2.txt', 'ACORDAOTCU25052016.txt']
Para exibir cada nome de arquivo em uma linha separada, facilitando a leitura, modificamos o código dentro do print()
pasa *zip.namelist(), sep = '\n'
. O asterisco descompactará a lista e extrairá cada um dos elementos, colocando cada nome de arquivo em uma linha diferente com sep = '\n'
:
with zipfile.ZipFile('/content/texts.zip', 'r') as zip:
print(*zip.namelist(), sep = '\n')
Executamos com "Ctrl + Enter".
ADI2TJDFT.txt
adi3767.txt
Ag10000170733596001.txt
Ag10105170208398001.txt
AgAIRR11889820145030011.txt
AgCr10582160008758001.txt
AgRgSTJ1.txt
AgRgSTJ2.txt
AgRgTSE1.txt
AgRgTSE3.txt
AIAgRAgI6193ARAGUARIMG.txt
airr801422012.txt
AIRR3999520145020086.txt
AIRR15708820115050222.txt
AP00000794920137060006.txt
AP00001415620157010201.txt
AP00001441420167030203.txt
AP771420167080008PA.txt
CP32320177080008PA.txt
DespSEPLAGDF.txt
ED1STM.txt
ED1TJAC.txt
EDAgRgTSE2.txt
EDEDARR208420135040232.txt
EDRR1TST.txt
EEDRR9715120105020002.txt
ERR731004520105130003.txt
HC110260SP.txt
HC151914AgRES.txt
HC340624SP.txt
HC418951PR.txt
HC70000845920187000000.txt
lei11340.txt
Lei11788.txt
LoaDF2018.txt
Pet128TSE5.txt
Port77DF.txt
Rcl3495STJ.txt
REE5908TSE4.txt
REsp1583083RS.txt
RR474820145230056.txt
RR942006420095040028.txt
RR2574407120025020372.txt
TCU4687.txt
TSTRR16037920105200001.txt
AC1TCU.txt
AC1TJAC.txt
AC1TJMG.txt
AC2.txt
ACORDAOTCU25052016.txt
Para ler um arquivo de texto, como o ADI2TJDFT.txt
, na próxima célula, utilizaremos o mesmo código da célula anterior para descompactar o arquivo zip
. Em vez de utilizar o print()
, podemos usar o with zip.open()
passando o nome do arquivo que desejamos abrir entre aspas simples, 'ADI2TJDFT.txt'
. Fora dos parênteses, apelidamos o arquivo de as arquivo
.
Na linha seguinte, realizamos a leitura do arquivo e o decodificamos para o formato UTF-8. Isso é necessário porque o arquivo está em língua portuguesa e, portanto, pode conter acentos e outros elementos da língua que precisam ser interpretados corretamente para que a leitura seja feita. Para isso, digitamos texto = arquivo.read().decode('utf-8')
.
with zipfile.ZipFile('/content/texts.zip', 'r') as zip:
with zip.open('ADI2TJDFT.txt') as arquivo:
texto = arquivo.read().decode('utf-8')
Com isso, armazenaremos na variável texto
toda a informação daquele arquivo. Ao executar essa célula, não aparecerá nada no output, mas a informação estará salva na variável texto
.
Na próxima célula, podemos exibir o conteúdo do arquivo com:
print(texto)
Pressionando "Ctrl + Enter", conseguiremos realizar a leitura de um dos arquivos dentro do arquivo compactado.
O retorno abaixo foi parcialmente transcrito:
print(texto)
Órgão : Conselho Especial
Classe : ADI Ação Direta de Inconstitucionalidade
N. Processo : 2010002019357-4
Requerente(s) : PROCURADORA-GERAL DE JUSTIÇA DO DISTRITO FEDERAL E TERRITÓRIOS
Requerido(s) : PRESIDENTE DA CÂMARA LEGISLATIVA DO DISTRITO FEDERAL E OUTRO(S)
Relator : Desembargador LÉCIO RESENDE
EMENTA
AÇÃO DIRETA DE INCONSTITUCIONALIDADE. LEIS DISTRITAIS N.º 747/1994 E 2018/1998. LEI COMPLEMENTAR DISTRITAL N.º 380/2001. INCONSTITUCIONALIDADE FORMAL. LEI ORGÂNICA DO DISTRITO FEDERAL. OCUPAÇÃO DE ÁREA PÚBLICA. COMPETÊNCIA PRIVATIVA DO GOVERNADOR DO DISTRITO FEDERAL. AÇÃO JULGADA PROCEDENTE EM RAZÃO DO VÍCIO FORMAL. Tanto o Decreto n.º 10.829/87, quanto a Portaria n.º 314/92, do Instituto Brasileiro do Patrimônio Cultural IBPC, hoje Instituto do Patrimônio Histórico e Artístico Nacional IPHAN, conferem ao Governador do Distrito Federal competência privativa para iniciar o processo legislativo, quando se tratar o tema de uso e ocupação do solo em todo o território do Distrito Federal.
ACÓRDÃO
Acordam os Desembargadores do Conselho Especial do Tribunal de Justiça do Distrito Federal e dos Territórios LÉCIO RESENDE Relator, JOÃO MAIORISI Vogal, ROMÃO C. OLIVEIRA Vogal, DÁCIO VIEIRA Vogal, SÉRGIO BITTENCOURT Vogal, LECIR MANOEL DA LUZ Vogal, CARMELITA BRASIL Vogal, WALDIR LEÔNCIO LOPES JÚNIOR Vogal, J.J. COSTA CARVALHO Vogal, HUMBERTO ADJUTO ULHÔA Vogal, NÍDIA CORRÊA LIMA Vogal, ANA MARIA DUARTE AMARANTE BRITO Vogal, CRUZ MACEDO - Vogal, ROBERBAL CASEMIRO BELINATI Vogal, SILVÂNIO BARBOSA DOS SANTOS Vogal, OTÁVIO AUGUSTO Vogal, sob a presidência do Desembargador OTÁVIO AUGUSTO, em proferir a seguinte decisão: JULGOU-SE PROCEDENTE A AÇÃO, POR MAIORIA, de acordo com a ata do julgamento e notas taquigráficas.
Brasília (DF), 17 de maio de 2011
Des. LÉCIO RESENDE
Relator
…
Se quisermos identificar as entidades dentro desse texto, como o número do processo, precisaríamos fazer a leitura e identificação manualmente, o que não seria tão eficiente.
No próximo vídeo, aprenderemos como identificar essas entidades automaticamente dentro do nosso texto!
Demos o primeiro passo no projeto ao realizar a leitura de um documento jurídico armazenado em um arquivo compactado no formato zip. A partir desse documento, conseguimos reconhecer as entidades nomeadas presentes no texto jurídico, identificando as informações mais relevantes.
Ao ler o texto, fomos capazes de identificar as jurisprudências, as partes envolvidas, entre outros aspectos. Nosso objetivo é automatizar essa tarefa, de modo que não seja mais necessário realizar a leitura manual, utilizando um modelo que fará o entendimento e o reconhecimento dessas entidades de forma automática.
Para automatizar esse processo, utilizaremos a biblioteca SpaCy, que oferece modelos para o reconhecimento de entidades nomeadas em textos. O primeiro passo consiste em instalar essa biblioteca no Google Colab. Para isso, acessaremos a documentação do SpaCy na seção de instalação ("Install spaCy"), onde encontraremos o código necessário para instalar tanto a biblioteca quanto o modelo correspondente.
Na documentação, podemos selecionar as configurações específicas para o nosso projeto, como o sistema operacional ("Operating system"), que no caso do Google Colab é Linux. Assim, selecionaremos a opção Linux, deixaremos a plataforma de instalação "pip" e o hardware como "CPU".
Além disso, optaremos pelo pipeline treinado em português, já que nosso modelo precisa ser ajustado para a língua portuguesa. Podemos escolher entre um modelo de eficiência, que é mais rápido, mas menos preciso, ou um modelo de acurácia, que é mais preciso, mas mais lento. Optaremos pelo modelo de eficiência ("efficiency").
A documentação mostrará as informações para instalar tanto a biblioteca SpaCy quanto o modelo pt_core_news_sm
, que é o modelo em português. Copiaremos as duas últimas linhas de código:
pip install -U spacy
python -m spacy download pt_core_news_sm
No Colab, começamos escrevendo !pip install -U spacy
. A exclamação serve para acessarmos o prompt do Google Colab para realizar a instalação dentro da máquina:
!pip install -U spacy
Executamos com "Ctrl + Enter".
Enquanto a instalação ocorre, copiamos o código necessário para instalar o modelo e, em seguida, colamos na próxima célula com a exclamação:
!python -m spacy download pt_core_news_sm
Executamos com "Ctrl + Enter". Assim, será feito o download do modelo da lingua portuguesa da biblioteca SpaCy.
Retorno parcialmente transcrito:
Restart to reload dependencies
Após a instalação, será necessário reiniciar o ambiente para carregar as dependências. Para isso, comentamos o código de instalação da biblioteca e do modelo:
# !pip install -U spacy
# !python -m spacy download pt_core_news_sm
Logo após, selecionamos a opção de reiniciar a sessão e executar tudo no Colab, na parte superior, em "Ambiente de execução > Reiniciar sessão e executar tudo". Com isso, o ambiebte será reiniciado e todas as células serão executadas.
Será exibida uma janela intitulada "Reiniciar e executar tudo" com a pergunta "Você quer mesmo reiniciar o ambiente de execução? O estado dele e todas as variáveis locais será perido.". Clicamos no botão "Sim" na parte inferior direita.
Após a reinicialização, importamos a biblioteca SpaCy e o modelo na célula seguinte com:
import spacy
import pt_core_news_sm
Na mesma célula, carregamos o modelo armazenando-o em uma variável chamada modelo_ner
que receberá pt_core_news_sm.load()
:
import spacy
import pt_core_news_sm
modelo_ner = pt_core_news_sm.load()
O
ner
refere-se a Named Entity Recognition ("Reconhecimento de Entidades Nomeadas").
Executamos a célula e não há nenhum retorno relacionado a esse comando.
Podemos testar o modelo no documento jurídico que lemos. Para isso, criamos uma variável doc
para armazenar o texto
processado pelo modelo_ner()
.
doc = modelo_ner(texto)
Utilizamos um loop for
para percorrer as entidades no documento. Na linha seguinte, digitamos for entidade in doc.ents:
, pulamos mais uma linha e escrevemos print(f'{entidade.text} -> {entidade.label_}')
.
O entidade.text
indica o texto da entidade, e após o ->
, indicamos o tipo de entidade com entidade.label_
. Com essa nomenclatura, extraímos a label
dentro das entidades identificadas pelo modelo.
doc = modelo_ner(texto)
for entidade in doc.ents:
print(f'{entidade.text} -> {entidade.label_}')
Executando essa célula, o modelo reconhece as entidades no texto, como Órgão
sendo identificados com a label LOC
e o Conselho Especial Classe
sendo identificado com a label ORG
. O DISTRITO FEDERAL E TERRITÓRIOS Requerido
também é identificado como um LOC
.
O retorno abaixo foi parcialmente transcrito:
Órgão -> LOC
Conselho Especial
Classe -> ORG
DISTRITO FEDERAL E TERRITÓRIOS
Requerido(s -> LOC
DA CÂMARA -> ORG
DISTRITO FEDERAL E OUTRO(S)
Relator -> LOC
LEIS DISTRITAIS -> MISC
COMPLEMENTAR DISTRITAL -> MISC
FORMAL -> ORG
LEI ORGÂNICA -> MISC
DISTRITO FEDERAL -> LOC
ÁREA PÚBLICA -> LOC
DO GOVERNADOR -> MISC
DISTRITO FEDERAL -> LOC
VÍCIO FORMAL -> ORG
Decreto n.º 10.829/87 -> MISC
Portaria n.º 314/92 -> ORG
…
Em cada uma das linhas, temos uma palavra do texto e, à direita, o tipo de entidade reconhecido. Embora ainda não saibamos o tipo exato de cada uma dessas entidades, já conseguimos extrair informações importantes dentro do nosso texto.
Para visualizar e filtrar melhor essas informações, podemos construir uma tabela com o Pandas. Importamos a biblioteca com o seguinte comando:
import pandas as pd
Executamos com "Ctrl + Enter".
Na próxima célula, criaremos um dataframe com as entidades e suas respectivas labels. Primeiro, definimos uma lista vazia com entidades = []
, na qual armazenaremos cada uma das palavras (as entidades) reconhecidas. Para cada uma dessas palavras, também associamos sua label correspondente, armazenando essas informações em uma lista com labels = []
.
Dessa forma, organizamos as entidades e suas labels lado a lado em uma tabela do Pandas.
Logo após, usamos o código for entidade in doc.ents:
, mas, em vez de printarmos as informações, utilizamos entidades.append(entidade.text)
para adicionar os textos das entidades na lista entidades. Na linha seguinte, digitamos labels.append(entidade.label_)
para adicionar as labels correspondentes a cada entidade na lista labels.
entidades = []
labels = []
for entidade in doc.ents:
entidades.append(entidade.text)
labels.append(entidade.label_)
Ao executarmos a célula, criamos uma lista de entidades e de labels.
Para criar o dataframe, na próxima célula, digitamos pd.DataFrame({})
e passamos o título (nome da coluna) que será 'Entidade'
, associando à lista de entidades: 'Entidade': entidades
. Aplicamos a mesma lógica para a label, criando a coluna 'Label'
e associando à lista de labels: 'Label': labels
.
pd.DataFrame({'Entidade': entidades, 'Label': labels})
Executando essa célula, obtemos uma tabela com as entidades e suas labels:
- | Entidade | Label |
---|---|---|
0 | Órgão | LOC |
1 | Conselho Especial\nClasse | ORG |
2 | DISTRITO FEDERAL E TERRITÓRIOS\nRequerido(s) | LOC |
3 | DA CÂMARA | ORG |
4 | DISTRITO FEDERAL E OUTRO(S)\nRelator | LOC |
... | ... | ... |
851 | PROCEDENTE | LOC |
852 | Leis Distritais | MISC |
853 | Lei Complementar | MISC |
854 | omnes | ORG |
855 | D E C I S | MISC |
Assim, teremos as entidades e suas respectivas labels organizadas em um dataframe.
É possível filtrar, por exemplo, apenas as labels LOC
. Dessa forma, conseguimos extrair informações relevantes do texto utilizando o modelo do SpaCy.
No entanto, ainda não temos clareza sobre o significado de cada label, e seria interessante visualizar essas labels destacadas no texto. Esse processo ajudará a verificar se todas as informações foram corretamente identificadas e também a compreender como o modelo as reconheceu. Abordaremos essa etapa no próximo vídeo!
O curso NLP: buscando entidades em documentos possui 150 minutos de vídeos, em um total de 53 atividades. Gostou? Conheça nossos outros cursos de Machine Learning em Data Science, ou leia nossos artigos de Data Science.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.