segunda-feira, 20 de novembro de 2023

Gerenciando ambientes virtuais com Conda

O Conda – que vem com o Anaconda ou Miniconda – facilita o gerenciamento de ambientes virtuais para os diferentes projetos em Python.

Uma vez disponível (para conferir se está ok: conda --version), podemos construir, ativar, alternar ou deletar os ambientes com os seguintes comandos:


1. Criar novo ambiente virtual:

conda create --name meu_ambiente python=3.8

conda create --name meu_ambiente


2. Ativar o ambiente virtual:

conda activate meu_ambiente


3. Instalar pacotes:

conda install numpy

ou

pip install numpy


4. Listar ambientes:

conda env list


5. Desativar ambiente:

conda deactivate


6. Remover um ambiente:

conda env remove --name meu_ambiente


Outras dicas:


7. Criação de um arquivo yml com as dependências do ambiente: 

conda env export > environment.yml (recomendo excluir a linha iniciada por “prefix”, que se refere ao caminho local do seu sistema de arquivos)

ou

pip freeze > requirements.txt (padrão do pip)


Obs. : para recriar ambiente a partir de environment.yml:

conda env create -f environment.yml


8. Mantenha o Conda atualizado: 

conda update conda


quinta-feira, 9 de novembro de 2023

Em breve, nós promotores de justiça compartilharemos nossos próprios GPTs

Quando ingressei no Ministério Público, era comum recebermos dos Centros de Apoio (CAOs) alguns CDs (de 650 MB) com modelos de peças e jurisprudência. 

Com a expansão da Internet e a implantação do portal institucional, a forma de compartilhar conhecimento no âmbito do MPSP mudou completamente. Nossa capacidade atual de fazer o reuso de teses e reaproveitar as peças elaboradas pelos colegas está diretamente relacionada à organização do site e à eficácia do mecanismo buscador. 

Há um “game changing” acontecendo nessa área. 

No evento “DevDay” do último dia 6, a primeira conferência direcionada a desenvolvedores promovida pela OpenAI, foram anunciadas inovações ao ChatGPT que permitirão, mesmo aos não desenvolvedores, criar versões customizadas do bot, denominadas GPTs (Generative Pre-trained Transformers), para tarefas específicas. 

O ChatGPT poderá, agora, se conectar a bases de dados, aprender com dados pessoais e acessar a internet. Não será preciso escrever código para que criemos soluções próprias destinadas a minutar denúncias, alegações finais e outras manifestações... e com o nosso estilo. Esses bots poderão ser publicados numa plataforma – a “GPT Store” – e compartilhados. 

É urgente, portanto, que conheçamos a política de privacidade dessas soluções e que a alta gestão do MPSP se atente ao tema.

Pensando no MPSP como um todo, precisaremos, também, ter em nossos quadros engenheiros de dados (para coletar, preparar e organizar as informações corporativas para treinamento de IAs) e engenheiros de softwares (para implementar as soluções em produção). 

Para saber mais: https://openai.com/blog/introducing-gpts

quarta-feira, 26 de julho de 2023

Operações com datas e horas usando Python

Com Python, fazemos operações com datas e horas usando as bibliotecas datetime e relativedelta.

A biblioteca datetime possui as seguintes classes principais: date, time, datetime e timedelta

A classe date representa uma data, a classe time representa um horário e a classe datetime representa uma combinação de data e horário. A classe timedelta é usada para realizar operações matemáticas com datas e tempos. Representa, portanto, um intervalo de tempo (com dias, horas, minutos e segundos).

Uma estratégia bastante usada nos programas é converter, previamente, as strings representativas de datas em objetos datetime para em seguida realizar as operações desejadas. Vamos fazer isso, calculando há quantos dias estou vivo.


Primeiro obtemos a data de hoje:

>>> from datetime import datetime, timedelta

>>> hoje = datetime.now()

>>> print(hoje)

2023-07-26 07:01:20.328655


Depois, convertemos a string em objeto datetime:

>>> nascimento = '24/03/1966'

>>> data_nasc = datetime.strptime(nascimento, "%d/%m/%Y")

>>> print(type(data_nasc))

<class 'datetime.datetime'>


Agora, é só calcular…

>>> dias_vividos = hoje - data_nasc

>>> print(dias_vividos)

20943 days, 7:01:20.328655

>>> print(dias_vividos.days)

20943


A classe relativedelta é mais poderosa que a timedelta, pois permite lidar com unidades de tempo maiores, como meses e anos, além dos componentes habituais de tempo, como dias, horas e minutos. Deve ser importada de from dateutil.relativedelta.

Com ela podemos, por exemplo, adicionar ou subtrair uma semana, um mês ou um ano de uma determinada data, considerando as diferenças de dias contidos nos meses e com anos bissextos.


Usando a classe relativedelta, poderíamos obter o seguinte resultado para o tempo vivido.

>>> from dateutil.relativedelta import relativedelta

>>> relativedelta(data_nasc, hoje)

relativedelta(years=-57, months=-4, days=-2, hours=-7, minutes=-1, seconds=-21, microseconds=+671345)


Poderíamos calcular o termo final de um prazo penal (contando o dia do início e excluindo o dia do fim) de 1 ano e 6 meses a partir de hoje da seguinte forma:

>>> termo_final = hoje + relativedelta(years=1, months=6) + relativedelta(days= -1)

>>> print(termo_final)

2025-01-25 07:01:20.328655


Ou, com uma saída mais amigável:

>>> print(termo_final.strftime("%d/%m/%Y"))

25/01/2025


domingo, 9 de julho de 2023

Roteiro para a criação de contêiner Docker para uma aplicação com Python

Quero rodar uma aplicação escrita em Python com suas dependências em um contêiner Docker, construído do zero.

Para isso, preciso:

1 - Definir um diretório de trabalho na máquina local.

2 - Construir a imagem Docker, a partir das instruções do arquivo "Dockerfile" (sem extensão) e das dependências listadas no arquivo "requirements.txt".

3 - Construir a imagem. Nesta fase, são instaladas as dependências encontradas em "requirements.txt".

4 - Executar o contêiner, mapeando a pasta local com a pasta do contêiner onde roda a aplicação.

Só isso!

domingo, 11 de junho de 2023

Machine Learning: escolha dos hiperparâmetros e ensamble

Introdução

Nesta semana, implementamos uma solução de machine learning para o conhecido problema "Titanic - Machine Learning From Disaster", disponibilizado em forma de competição permanente no Kaggle, conhecido portal com conteúdo voltado para a Ciência de Dados. 

Seguimos os seguintes passos: 1) importação das bibliotecas necessárias; 2) leitura do dataset (disponibilizado no Kaggle); 3) pré-processamento dos dados; 4) criação de "features"; 5) seleção de "features"; 6) visualização; 7) agrupamento por sobreviventes (o que permitiu observar quais "features" eram mais relevantes para o resultado); 8) criação da tabela pivô (em relação à "feature" "Pclass"); 9) padronização das variáveis; 10 ) utilização dos modelos (Logistic Regression, Naive Bayes para Classificação, KNN para Classificação, SVM para Classificação, Decision Tree e Random Forest) e avaliação de seus respectivos desempenhos, obtidos por validação cruzada (método sklearn.model_selection.cross_val_score).

Dois aspectos do trabalho mereceram maior atenção: a escolha dos hiperparâmetros (tuning) e o e ensamble (conjugação) dos modelos.

Escolha dos hiperparâmetros

A otimização dos hiperparâmetros (tuning) foi feita com o método gp_minize da biblioteca scikit-optimize (skop). O método implementa a otimização bayesiana, usando processos gaussianos , para encontrar os hiperparâmetros ótimos, sendo computacionalmente mais eficiente do que a classe GridSearchCV, do Sklearn, que faz a busca exaustiva.

A biblioteca pode ser instalada com:

!pip install scikit-optimize

A função que nos retorna a métrica e a lista da parâmetros ótimos é a seguinte:

def treinar_modelo_dtc (parametros_dtc):

  model_dtc = DecisionTreeClassifier(criterion = parametros_dtc[0], 

                                     max_depth = parametros_dtc[1],

                                     min_samples_split = parametros_dtc[2], 

                                     min_samples_leaf = parametros_dtc[3],

                                     random_state = 0)  

  score = cross_val_score(model_dtc, X_train_sc, y_train, cv = 10)  

  mean_score = np.mean(score)

  print(np.mean(score))

  return -mean_score

parametros_dtc= [['gini', 'entropy', 'log_loss'], 

                  (2, 6), 

                  (2, 5), 

                  (1, 3),

                  ]

otimos_dtc = gp_minimize(treinar_modelo_dtc, parametros_dtc, random_state = 0, verbose = 1, n_calls = 30, n_random_starts = 10)

print(otimos_dtc.fun, otimos_dtc.x)

# -0.8181772784019975 ['entropy', 3, 3, 2]


Ensamble dos modelos

Para o ensamble dos modelos, após a obtenção dos hiperparâmetros ótimos, usamos a classe VotingClassifier.

A implementação foi feita da seguinte forma:

from sklearn.ensemble import VotingClassifier

model_voting = VotingClassifier(estimators = [('RF', model_rf),

                                              ('SVC', model_svc),

                                              ('DTC', model_dtc)], 

                                weights=[1, 2, 1],

                                voting='hard' )

model_voting.fit(X_train_sc, y_train)

score = cross_val_score(model_voting, X_train_sc, y_train, cv = 10)

print(np.mean(score))

# sem weights: 0.8339200998751561

# com weights: 0.8350062421972535


Resultado

O modelo combinado obteve o score de 0.77751 no Kaggle, conferindo-nos a posição nº 4499 no ranking,  às 11h54min de 9 jun. 2023.



Referências

ANIFOWOSE, Fatai. Ensemble Machine Learning Explained in Simple Terms. Disponível em: <https://jpt.spe.org/twa/ensemble-machine-learning-explained-simple-terms>. Acesso em 10 jun. 2023.

CODERSCOLUMN. Scikit-Optimize: Simple Guide to Hyperparameters Tunning / Optimization. Disponível em: <https://coderzcolumn.com/tutorials/machine-learning/scikit-optimize-guide-to-hyperparameters-optimization>. Acesso em 10 jun. 2023.

KUMAR, Satyam. Use Voting Classifier to improve the performance of your ML model [Towardsdatascience]. Disponível em: <https://towardsdatascience.com/use-voting-classifier-to-improve-the-performance-of-your-ml-model-805345f9de0e>. Acesso em: 10 jun. 2023.

SCIKIT-LEARN. Ensemble Methods. Disponível em: <https://scikit-learn.org/stable/modules/ensemble.html>. Acesso em 10 jun. 2023.

SCIKIT-OPTIMIZE. Disponível em <https://scikit-optimize.github.io/stable/modules/generated/skopt.gp_minimize.html#>. Acesso em 10 jun. 2023.

VALENTE, Domingos Sárvio Magalhães. ELT579 - Aula 8 VotingModel. Disponível em: <https://youtu.be/Fo5QLR8fyZw> . Acesso em 10 jun. 2023.

domingo, 23 de abril de 2023

ChatPDF analisa processos judiciais com resultados surpreendentes

Quem acompanha o assunto "Inteligência Artificial" concorda que os modelos de linguagem natural vêm evoluindo paulatinamente há anos e que a grande disruptura produzida pelo ChatGPT é tornar a ferramenta acessível a todos e de modo bastante amigável, na forma de chat.


A IA “caiu no colo” de usuários de computadores, comuns ou avançados, e todos estão encontrando utilidades práticas para ela. Eu, particularmente, uso o ChatGPT para estudar programação, otimizar e auditar códigos e para melhorar minha compreensão sobre temas ligados à tecnologia.


Uma das aplicações possíveis - e que há até pouco tempo parecia longe de se concretizar - é a análise de autos de processos judiciais, para a identificação das controvérsias ou teses e para localização ágil de referências e documentos.


Testei a plataforma ChatPDF para essa finalidade (há ferramentas similares na Internet). Trata-se, aparentemente (a documentação é escassa) de uma interface web que extrai o texto do PDF e o submete com "prompts" específicos à API do ChatGPT, emulando a conversa sobre o PDF apresentado.


O resultado foi bastante assertivo, tanto em autos de processo criminal, como em caso de processo de falência, como se pode conferir no vídeo abaixo. 


Não é defeso pensar que, com técnicas de “transfer learning” (largamente adotadas no campo do reconhecimento de imagens) tenhamos, em breve, IAs treinadas em bases de dados especificas de processos judiciais e que, destarte, serão muito mais precisas na execução dessa tarefa. 




sexta-feira, 21 de abril de 2023

Pesquisa processos no 2º Grau do TJSP por investigado ou advogado

Introdução
A Promotoria de Justiça de Piracicaba monitora a entrada de processos em 2º grau relacionados a seus investigados, realizando consultas periódicas ao eSAJ, de forma automática. Para isso, criamos um web crawler (ou "robozinho") para realizar a pesquisa não autenticada ao eSAJ.

A aplicação faz buscas por nome da parte ou número de OAB e retorna informações sobre processos criminais encontrados.

A linguagem de programação escolhida foi o Python, utilizando-se as bibliotecas Requests (requisições web), BeautifulSoup (para parsear o HTML), datetime (para a manipulação de datas e horários) e os (para a manipulação de arquivos).

Estratégias usadas no programa
O programa realiza a busca em uma URL específica e utiliza o método POST para enviar os dados necessários. Ele analisa a resposta utilizando a biblioteca BeautifulSoup e, a partir disso, retorna os resultados em um formato legível. Os arquivos de configuração armazenam as informações de investigados e números de OAB. O arquivo de resultados gravado é comparado com o atual, por meio de hash, para verificar se houve alteração nas informações anteriormente obtidas.

Como obter o programa
O código fonte do programa está publicado no GitHub, com licença MIT (cf. em <https://github.com/jespimentel/crawler_sg>). Os iniciados em Python não terão qualquer dificuldade para clonar o programa e rodar na própria máquina. As bibliotecas necessárias estão relacionadas no arquivo "requirements.txt". Para os colegas de MP, podemos fornecer o executável, mediante solicitação.

Como usar o programa
Para utilizar o programa, é necessário criar dois arquivos de texto dentro da pasta "config_pesquisa": "investigados.txt" e "oab.txt". No arquivo "investigados.txt", deve-se incluir o nome das partes que se deseja buscar informações, uma em cada linha. Já no arquivo "oab.txt", deve-se incluir o número de OAB, um em cada linha. Assentos e pontos devem ser desprezados.

Após a criação dos arquivos, basta executar o programa e esperar o resultado ser gerado na pasta "_resultados".

Limitações
Não há garantia de funcionamento, nem de resultados. Qualquer alteração no site do TJSP "quebra" a lógica do programa, que procura o resultado contido em tags específicas da página html de resultados. 

Conclusões
O programa é uma ferramenta útil para a coleta automatizada das informações sobre processos judiciais, limitada a consulta ao 2º Grau do Tribunal de Justiça do Estado de São Paulo, através do portal eSAJ e para um usuário não autenticado.




Palestra para o Grupo de Estudos de Marília/SP


 

domingo, 26 de março de 2023

Análise Espectral e Transformada de Fourier