Acreditamos na importância do alinhamento entre prática e teoria dentro do processo de aprendizado de Data Science e Machine Learning. Nesse sentido, a frente de projetos busca se tornar um espaço para que os alunos possam explorar e expandir seus limites.
A cada semestre, nos reunimos e formamos times de desenvolvimento que buscam atacar tarefas ambiciosas em diversas aplicações e, os resultados dos projetos são expostos nesta página. O escopo dos projetos é livre, variando desde competiçoes de Ciência de Dados até ideias de pesquisa em colaboração com laboratórios e outras instituições, tudo em prol da promoção de hard e soft skills.
Além dos projetos oficialmente em desenvolvimento pelo Data, temos outras iniciativas em andamento em nossa organização oficial do GitHub.
Esta página é um compilado dos últimos projetos desenvolvidos ou ainda em desenvolvimento por nossos membros.
Seja bem-vindo(a) :)
Com o objetivo de capacitar estudantes em Ciência de Dados e disseminar o conhecimento na área, oferecemos um curso gratuito sobre o assunto no Instituto de Ciências Matemáticas e de Computação (ICMC) da USP, em São Carlos. A oportunidade é voltada para alunos de graduação e pós-graduação de qualquer instituição de ensino, e também para membros da comunidade são-carlense e da indústria.
Abordamos a derivação dos principais algoritmos de Aprendizado de
Máquina, como Regressão Linear, Naive Bayes, SVM e métodos de Arvores.
Juntando teoria com prática, ensinamos também bibliotecas populares no
ecossistema Python, como Numpy, Pandas e Scikit-Learn, incentivando os
alunos através de competições no estilo do Kaggle. As aulas ocorrem
todo primeiro semestre e incluem um certificado da USP para aqueles
que acompanharem as aulas e entregarem as atividades.
No contexto da análise e modelagem em machine learning nos últimos anos vem sendo integradas diversas técnicas e ideias que nos tempos nos que foram projetadas não foram possíveis implementar ou aplicar. Atualmente o desenvolvimento tecnológico e digital nesta era da informação caracterizada por a disponibilidade de grandes bases de dados levou ao mundo científico e a indústria a uma grande revolução cuja principal característica tem sido a de apagar as fronteiras entre as diversas áreas do conhecimento para fundir elas uma que satisfaça as necessidades atuais da sociedade.
Técnicas de diagnóstico têm sido propostas para detectar observações que podem exercer alguma influência nas estimativas dos parâmetros no contexto da modelagem estatística. Essas técnicas podem ser divididas em duas: (i) exclusão de casos para avaliar a influência global e (ii) incorporação de diversos tipos de perturbações para avaliar a influência local. A primeira é a técnica de deleção de caso \cite{cookD}, na qual o efeito ou influência de uma dada observação (ou um grupo de observações) é medido por uma comparação de estimativas de parâmetros antes e depois de sua deleção. Isso é feito analisando um ou mais modelos ajustados após a exclusão e, em seguida, avaliando o resultado por algumas métricas, como a distância de probabilidade ou a distância de Cook. O segundo método é a abordagem da influência local \cite{cook}, que avalia as mudanças nos resultados da análise como consequência de uma pequena perturbação do sujeito, não seu apagamento total. Existe também medidas de exclusão de casos e o diagnóstico de influência local para o modelo de regressão com base na função Q, tais resultados são apresentados e desemvolvidos nos trabalhos de Zhu et al.(2001) e Zhu and Lee (2001).
A exclusão de caso é uma maneira comum de avaliar o efeito de uma observação na estimativa procedimento. Esta é uma análise de influência global, uma vez que o efeito de uma observação é avaliado eliminando-o do conjunto de dados. Alternativamente, a influência local é baseada em uma diferenciação geométrica em vez de uma exclusão de observação. Neste caso, um diferencial comparação de estimativas é usada antes e depois de perturbar os dados e / ou modelo. Existem vários esquemas para avaliar a influência local. A seguir, descrevemos este método de influência.
O modelo MSOU (Mean Shift ourliers) foi introducido no trabalho de Xie and Wei (2007).
Em geral, o MSOU é definido como:
\begin{eqnarray}
Y_i&=& \mathbf{x}^{\top}_{i} \beta + \xi_i, \ \ \ \ i=1,\ldots,n,\quad j\neq i\\
Y_i&=& \mathbf{x}^{\top}_{i} \beta+\phi + \xi_i, \ \ \ \ i=1,\ldots,n,\quad j= i\\
\xi_i &\stackrel{iid}{\sim}& SSMN(0, \sigma^2, \lambda, H), \ i=1,\ldots,n,
\label{msoumodel}
\end{eqnarray} Onde $\phi$ é um paramêtro indicador, onde se ele for diferente de zero então a \(j\)-écima observação sera candidata a outlier (Cook et al. (1982)}). \(Y_i\) é variavél resposta observada continua para o individuo \(i\) and \(\xi_i\) é o erro aleatorio. associado com o individuo \(i\), assumindo conhecido \(p \times 1\) o vetor de covariaveis \(\textbf{x}_i\), que define nosso preditor lienar \(\mu_i = \textbf{x}^{\top}_i\beta\), onde \(\beta\) é um \(p\)-dimensional vector de coeficientes de regressão desconhecidos.
O modelos CDM foi desemvolvido no trabalho de Xie and Wei (2007) e pode ser especificado da seguinte forma
$$Y_i= \mathbf{x}^{\top}_{i} \beta + \xi_i, \ \ \ \xi_i \stackrel{iid}{\sim} SSMN(0, \sigma^2, \lambda, H), \ i=1,\ldots,n,$$ onde $$V_i =\left\{ \begin{array}{cc} c_i, &\, \mathrm{if}\,\,\, \rho_i=1\,\, (\mathrm{i.e.}\,\, Y_i\leq c_i), \\ Y_i, &\, \mathrm{if}\,\,\, \rho_i=0\,\, (\mathrm{i.e.}\,\, Y_i > c_i), \end{array} \right., \quad i=1,\ldots,n, \quad j\neq i,$$ aqui a observação \(j\) é deletada. Considere \(\widehat{\theta}_{[j]}=(\widehat{\beta}_{[j]}^{\top},\widehat{\sigma}_{[j]}^2,\widehat{\lambda}_{[j]},\widehat{\tau}_{[j]}^{\top})^{\top}\) como a estimativa de máxima verossimilhança de \(\theta\) da função \(Q_{[j]}(\theta|\widehat{\theta}); j=1,\ldots,n\), via algoritmo EM. Onde \([j]\) Significa a quantidade original com o \(j\)-écimo caso deletado.
A estatística para o teste LRT esta definida no trabalho de Neyman and Pearson (1928) é dada por
$$MS_{LR}=2[\ell(\widehat{\theta})-\ell(\widetilde{\theta})]$$ onde a função de log-verossimilhança \(\ell(\theta)\), \(\widehat{\theta}\) e \(\widetilde{\theta}\) são os MLE's (Maximum Likelihood Estimators) baixo os modelos restrito (Under \(H_0\)) e não restrito (Under \(H_1\)), respectivamente.
A estatística para este teste é definida por Terrell (2002), e tem a seguintee forma, $$MS_{G}=S^{\top}(\widetilde{\theta})(\widehat{\theta}-\widetilde{\theta}),$$ onde \(S(\theta)\) é a função score.
Cada uma dessas estatísticas possui uma distribuição assintótica \(\chi^2\) (chi-quadrado), sob \(H_0\). Assim, rejeitamos \(H_0\) com um nível de significância \(\alpha\), se os valores das estatísticas são menores que \(\chi^2_{1-\alpha,1}\), sob \(H_0\).
Note que podemos formular um Teste Outlier considerando $$H_0:\phi=0\quad\text{vs}\quad H_1:\phi\neq 0.$$ onde, se \(H_0\) é rejeitado, a \(j\)-ésima observação pode ser selecionada como um possivél Outlier. Para avaliar esta hipotese podemos usas testes assimtoticos tais como RVS (likelihood ratio test), wald, score e gradiente.
Para o Teste Assintótico, selecionamos essas duas estatísticas (LRT e GT) pela facilidade de computação que oferecem. Além disso, fechamos as expressões para os estimadores de máxima verossimilhança do algoritmo EM nos modelos restrito e irrestrito para a maioria dos parâmetros de interesse. Assim, o cálculo da estatística da região de verossimilhança não é complicado quando comparado com as estatísticas de Wald e Score que dependem da matriz de informação de Fisher disponível no trabalho de Guzman et al. (2020).
A técnica Support Vector Machine (SVM) - é amplamente conhecida e consiste num algoritmo de aprendizado de máquina supervisionado frequentemente citado e usado em problemas de classificação. Os SVMs usam hiperplanos no espaço multidimensional para separar uma classe de observações de outra. Naturalmente, o SVM é usado na solução de problemas de classificação de várias classes.
No entanto, o SVM também está cada vez mais sendo usado em um problema de classe, em que todos os dados pertencem a uma única classe. Nesse caso, o algoritmo é treinado para aprender o que é “normal”, para que quando um novo dado for mostrado o algoritmo possa identificar se ele deve pertencer ou não ao grupo. Caso contrário, os novos dados são rotulados como fora do comum ou com anomalia.
Como esse projeto pode beneficiar pessoas? Por meio do Sentinela, é possível detectar usuários que estão agindo de maneira tóxica de forma constante e de bots utilizados para ofensas. Ou seja, contas que atacam perfis pessoais e profissionais de maneira constante podem ter sua atividade verificada e, consequentemente, a proporção de comentários tóxicos em seus tweets analisados. Por meio dessa checagem, é possível punir os usuários de forma mais direcionada e reduzir a frequência de comentários violentos em páginas que são constantemente atacadas.
Exemplos de empresas que foram atacadas na internet:
Como isso é algo inovador? A existência de bases de dados de comentários em português rotuladas em "tóxico" e "não tóxico" é algo bem limitado e, dessa forma, não há uma grande variedade de projetos na língua. Portanto, uma plataforma de identificação é algo relativamente bem novo e, junto com os scrapers feitos para redes sociais, compõem um projeto único.
A tarefa de análise de toxicidade é bem conhecida dentro do contexto de Processamento de Linguagem Natural. Originalmente, as abordagens do estado da arte de classificação de texto se baseavam na extração de bag-of-words (vetores com zeros e uns para representar a presença ou ausência de cada palavra em um documento) que eram utilizados como inputs para métodos, como Regressão Logística, Support Vector Machines (SVM) e Árvores de Decisão. Dessa forma, optamos por iniciar o desenvolvimento do projeto nos inspirando nesses pipelines já conhecidos, afim de obter baselines rápidos que pudessem melhor embasar futuras decisões de projeto.
Tais pipelines, contudo, encontram limitações na capacidade de representação por se basearem em bag-of-words que representam o documento por completo e também sofrem com a alta dimensionalidade e com as representações demasiadamente esparsas. Essas limitações motivam a utilização de word embeddings (vetores de representação de palavras), que são capazes de representar cada palavra do vocabulário individualmente utilizando menores dimensionalidades. Métodos como Word2Vec e GloVe se utilizam da ideia de que palavras vizinhas devem estar próximas no espaço de representação.
A partir da utilização de word embeddings, podemos aplicar métodos de Recurrent Neural Networks (RNNs) (como LSTMs e GRUs) ou Transformers (como BERT), que se utilizam desses vetores de representação como inputs de cada palavra. Em nossos experimentos, utilizamos *word embeddings* em conjunto com LSTMs e GRUs para atacar a tarefa de classificação de textos, obtendo resultados compatíveis com os obtidos no conjunto de dados utilizado. Apesar de se saírem melhor, tais métodos necessitam de uma maior quantidade de dados para atingirem um melhor padrão de generalização além de exigirem mais recursos computacionais. Esses fatores mostram-se desafios, dado tamanho relativamente reduzido de nosso conjunto de dados e a disponibilidade de hardware do Google Colab, plataforma utilizada para o treinamento de todos os modelos.
De onde vieram nossos datasets? Utilizamos tweets anotados de acordo com diferentes tipos de toxicidade encontrados em Toxic Language Dataset for Brazilian Portuguese (ToLD-BR). Como nossa tarefa é classificar se o tweet é tóxico ou não, tratamos para que se constasse algum tipo de toxicidade no comentário, ele seria classificado como tóxico, não tóxico caso contrário.
Além disso, utilizamos dados do Twitter que foram extraídos diretamente da API oficial da plataforma. Para coletar os tweets para a classificação, utilizamos o tweepy. Tweepy é uma biblioteca escrita em python para acessar a API do Twitter. O código desenvolvido recebe como parâmetro um usuário do twitter e, a partir disso, coleta as respostas de publicações deste usuário de acordo com um certo limitante superior para a quantidade a ser coletada.
Para este preprocessamento, fizemos a remoção de caracteres especiais e acentos, lemmetização e remoção de stopwords. Para remoção de caracteres especiais e acentos, utilizamos expressões regulares. Além disso, realizamos um processo de lemmetização, que se baseia na extração do radical das palavras. Depois removemos as stopwords, que são palavras que não acrescentam muita informação ao texto.
| Modelo | f1 | Acurácia | Precisão |
|---|---|---|---|
| SVM com kernel sigmoid | 0.658 | 0.698 | 0.691 |
| SVM com kernel linear | 0.687 | 0.715 | 0.718 |
| SVM com kernel RBF | 0.665 | 0.714 | 0.762 |
| SVM com kernel polinomial grau 2 | 0.608 | 0.691 | 0.747 |
| Naive Bayes | 0.673 | 0.705 | 0.689 |
| XGBoost | 0.677 | 0.719 | 0.76 |
| Modelo | Acurácia - Treino | Acurácia - Teste |
|---|---|---|
| LSTM | 0.6705 | 0.7266 |
| GRU | 0.6557 | 0.6550 |
A união de todas as parte dos projeto se deu através da ferramenta Streamlit de criação de páginas web integradas com os modelos treinados. A partir dessa interface, é possível fornecer os inputs necessários para que a aquisição dos dados de texto do Twitter por meio da API oficial da plataforma. Em seguida, aplicamos o pipeline já mencionado para a realização do pré-processamento dos dados passados para os modelos.
Recentemente o GitHub, uma plataforma de hospedagem de código-fonte para software, criou uma nova badge em homenagem aos desenvolvedores que contribuíram para versões específicas de projetos e bibliotecas que foram utilizados pelo Laboratório Jet Propulsion Laboratory da NASA para enviar o helicóptero robótico Ingenuity à atmosfera de Marte. Aproximadamente 12 mil desenvolvedores a receberam.
Uma dúvida que paira é exatamente qual metodologia foi utilizada por eles para selecionar os desenvolvedores, uma vez que existe uma grande hierarquia de dependências entre os próprios projetos. Um único projeto, a depender do seu tamanho, pode ter várias dependências, as quais se segmentam em diversas outras dependências. Espera-se, portanto, que o número de contribuidores atinjam um grande patamar, especialmente se for considerado todos os níveis de contribuidores (diretos ou indiretos).
O modelo atual de bibliotecas e códigos abertos baseia-se fortemente na gratuidade e suporte contínuo do autor ou da comunidade. Ao terceirizarem funcionalidades, que pareceriam funções básicas, para outras bibliotecas, os desenvolvedores podem se dedicar a projetos maiores sem a necessidade de "reinventar a roda". Dessa forma, diversas bibliotecas tornam-se dependências populares de diversos outros projetos. O quadrinho XKCD a seguir sintetiza essa relação:
Tal qual em uma pilha de blocos, a retirada de um pedaço crítico de um software resultaria na perda de sua estabilidade. Sob essa ótica, a relação hierárquica entre os repositórios foi escolhida como tema para esse projeto.
Outra referência para o projeto foi uma palestra da 13ª Conferência Brasileira da Comunidade Python, promovida por Bernardo Fontes, entitulada de Grafos e uma Análise Matemática do Jazz nos anos 60. Nessa palestra foi apresentada uma análise matemática sobre o gênero musical Jazz através de uma modelagem matemática usando grafos sobre duas redes: uma que relaciona os músicos entre si, e uma outra que relaciona os músicos com os discos. É interessante notar como o estudo parte de algumas perguntas e hipóteses básicas e, a partir desses questionamentos, seleciona as melhores métricas, associadas às redes adequadas, para respondê-las. Essa palestra serviu como uma breve introdução a alguns conceitos de grafos aplicados à redes complexas, à ferramenta NetworkX - a qual também será usada para esse projeto - e, não menos importante, ao Jazz.
Munido dessas referências, o projeto buscou aplicar os conceitos de modelagem por grafos para exploração e visualização de repositórios do Github. Conceitos de análise de redes complexas foram utilizados como ferramentas para responder algumas perguntas básicas sobre como se estabelece a hierarquia de repositórios popularmente usados em aplicações de Machine Learning e Data Science.
A metodologia do trabalho foi formulada com base no pipeline clássico utilizado em Ciência de Dados. Resumidamente:
Os grafos são estruturas compostas por vértices e arestas. Os vértices(ou nós) são abstrações matemáticas de um objeto, e as arestas são responsáveis por conectar esses vértices e estabelecer uma relação entre esses pares. De outra forma, podemos considerar os nós como os dados e as arestas como propriedades/relações entre esses dados. A modelagem por grafos é mais indicada para resolução de problemas em que a relação entre os dados é tão importante quanto os dados em si. Sendo, por esse motivo, a melhor maneira de modelar o problema abordado.
Existem diversos tipos de grafos. Para esse projeto vamos focar nos grafos direcionados, também denominados de Dígrafos. Nesse tipo de grafo as arestas têm um sentido associado (graficamente indicado por um seta entre os nós). A origem da aresta também é denominada de nó pai e o destino de nó filho.
Para o propósito inicial desse projeto os nós serão repositórios abertos do Github, enquanto as arestas indicam se um repositório depende de outro repositório. Ou seja, a aresta parte das dependências em direção aos dependentes. Uma frase que melhor representaria essa aresta seria: "é dependência de". Segue um exemplo de como seria essa relação:
Como mostra a figura é possível notar que os repositórios PyCQA/flake8, PyCQA/flake8-bugbear, adamchainz/flake8-comprehensions, xuhdev/flake8-executable são dependências do pytorch/pytorch. Analogamente, também é possível dizer que o pytorch é dependente dos demais repositórios.
O primeiro passo foi obter os dados correspondentes ao objeto de análise. Inicialmente foi feita uma procura por datasets já disponibilizados pela comunidade que atendesse ao projeto. Neste caso, não foram encontrados datasets que atendessem especificamente o objetivo do projeto, mas essa mesma busca abriu caminhos para que a obtenção dos dados fosse possível.
O próprio GitHub fornece uma ferramenta, denominada Grafo de Dependência, capaz de rastrear as dependências e dependentes de um repositório. Essa funcionalidade está disponível para todo repositório que defina suas dependências através gerenciadores de pacote e formato de arquivos manifesto suportados.
O Grafo de dependências contém:
O Github disponibiliza em sua GraphQL API uma prévia que dá suporte à leitura do seu Grafo de Dependência para um repositório. Vale notar, que a referida API não fornece os dados dos dependentes, dessa forma, a obtenção dos dependentes só pode ser feita via web scraping da página do github. Dessa forma, com essa API, em uma única consulta é possível obter todas dependências diretas de um repositório. Além disso, é possível obter também outros dados desse repositório como: descrição, número de estrelas, número de forks, lista das linguagens utilizadas e muitos outros dados. Para a proposta inicial do projeto estamos interessados apenas em obter as dependências.
Por fim, para atender esse objetivo foi implementado um script para obtenção das dependências de um repositório. Para esse fim foi utilizado o algoritmo de Busca em Profundidade. Como já foi discutido anteriormente, a hierarquia de dependências pode ser muito complexa, dessa forma, a busca por profundidade foi implementada usando como parâmetro adicional a profundidade máxima(depth) para a busca. Compondo o que é conhecido como Depth Limited Search(DLS).
Para \(depth = 1\) corresponde a pegar apenas as profundidade diretas e para \(depth = 0\) equivale a recuperar todas as dependências diretas e indiretas, até o último nível.
A depender do tamanho da rede(ou grafo), a visualização de redes complexas torna-se uma tarefa computacional muito custosa. No entanto, a visualização dos dados pode auxiliar na análise exploratória dos dados, além de ser uma forma lúdica de rastrear o próprio progresso do projeto.
A ferramenta de visualização escolhida foi o módulo Force Layout da biblioteca D3.js. Esse módulo implementa uma simulação física de força entre as partículas, as quais, para esse projeto, seriam os nós dos repositórios. A obtenção dos dados foi implementada de forma a gerar um arquivo .json adequado para a simulação, bastando adicionar os conjuntos de nós e arestas, bem como, as forças entre eles.
Foi realizada uma simulação usando uma rede, construída através do script DLS implementado, partindo-se do repositório do pytorch/pytorch com \(depth = 2\). Essa simples rede já possui 726 nós e 1371 arestas. A visualização ajudou o projeto a obter uma melhor noção do quanto essas redes podem aumentar rapidamente, guiando melhorias ao script de busca como adicionar um limite para a busca em profundidade e outros filtros. Por fim, ficou bem claro que, apesar de muito interessante, a simulação possui suas limitações.
Existem em redes complexas um conjunto de elementos característicos. Alguns componentes formam um conjunto de elementos pouco conectados, enquanto outros formam conjuntos altamente conectados. Esses conjuntos tornam as redes complexas uma estrutura heterogênea na qual espera-se que, de alguma forma, alguns nós sejam mais importantes que outros. Algumas medidas, denominadas de medidas de centralidade, foram projetadas para tentar quantificar essa influência.
Muitas vezes essa influência pode ser notada através da propagação de informação, como em redes sociais, ou de algum outra característica da rede como, por exemplo, a propagação de doenças. A caráter de exemplo, em redes sociais um conjunto seleto de pessoa, como celebridades, políticos e outras figuras públicas, com uma grande quantidade de seguidores, são capazes de propagar informações mais facilmente que outras pessoas. Podendo até mesmo influenciar o mercado especulativo com algumas postagens.
O presente projeto fará uso dessas métricas para exploração das redes obtidas, como para responder quais repositórios são os mais influentes da rede.
A ferramenta utilizada foi o NetworkX. Trata-se de um pacote na linguagem python para criação, manipulação e estudo de redes complexas. Essa ferramenta além implementar as estruturas de dados adequadas para redes complexas, possui um grande arsenal de algoritmos voltados a essas estruturas. Incluindo as medidas de centralidade que serão usadas.
Seguem algumas perguntas que puderam ser respondidas com os dados coletados:
Essas perguntas estão respondidas nesse jupyter notebook.
Durante o projeto nos deparamos com algums desafios em diferentes esferas do pipeline. Uma das preocupações durante o projeto foi desenvolver a obtenção e o armazenamento dos dados da maneira mais robusta possível. Como o github é uma rede imensa foi preciso discutir as melhores maneiras para se coletar uma amostra dos dados. Dessa forma, ficou decidido que inicialmente, para poder atender em parte a visualização e a exploração, decidiu-se por coletar as dependências dos principais repositórios do tópico machine learning e Data Science, bem como, alguns dos seus dependentes, filtrados por número de estrelas. Os repositórios escolhidos foram:
Outro desafio encontrado foi procurar a melhor maneira de persistir os dados, de tal modo que o pudesse ser facilmente armazenado, bem como, escalonado sem comprometer os dados que já foram coletados. Dessa forma, escolheu-se, inicialmente, o banco de dados Sqlite. Nesse quesito, o projeto pôde se beneficiar diretamente da comunidade open-source, uma vez que a solução mais rápida encontrada foi adicionar o script para adquirir as dependências a um repositório já existente, denominado de github-to-sqlite. Vale notar que esse repositório detinha como funcionalidade apenas a busca por dependentes.
Alguns pontos do projeto ainda estão em aberto, havendo ainda algumas ideias futuras:
Para o desenvolvimento deste projeto foi pensada numa forma de interação em que o usuário possa descobrir como um autor de outra época escreveria frases comumente utilizadas hoje em dia. Para realizar essa simulação, o usuário pode entrar com frases digitadas e a partir da identificação delas, será reproduzida uma nova frase como se fosse dita pelo próprio autor com suas variações linguísticas.
Neste projeto em questão o autor escolhido foi o Machado de Assis. Essa escolha é justificada, principalmente, pelo fato de ele ser um dos maiores escritores da literatura brasileira e porque ele possui uma vasta coleção de livros escritos. Além disso, como todas as suas obras são de domínio público, a obtenção de seus textos para propósitos de extração de dados é muito facilitada. Isso permite a aquisição de uma grande variedade de dados que podem ser coletados para análise e tratamento.
Dessa forma, esperamos que ao ser concluído, o nosso modelo seja capaz de gerar boas estimativas de frases escritas na típica linguagem Machadiana.
Com este projeto inicial temos a intenção de aprofundar os conhecimentos na área da Ciência de Dados com o treinamento de modelos, usando ferramentas como Keras, TensorFlow, e aplicando as metodologias aprendidas como seq2seq, que facilita trabalhar com a conversão em si da linguagem. E para o nosso caso, permite converter um estilo de texto corriqueiro para a linguagem rebuscada característica de Machado de Assis.
A partir do que já se sabia da literatura, tipicamente, para modelar dinâmicas que envolvem sequências temporais, são utilizados modelos de seq2seq. Como o nosso problema consiste essencialmente na tradução de frases que se encontram em um estilo literário para outro e frases são sequências temporais nas quais uma palavra deve, necessariamente, anteceder ou suceder outra em uma sequência, achamos que essa arquitetura de redes neurais será utilizada. Basicamente, ela consiste em duas redes neurais recorrentes. Uma que é utilizada para codificar uma frase em um vocabulário como um vetor numérico e outra que é usada para decodificar esse vetor como uma frase que se encontra em outro espaço de vocabulário. Tal arquitetura pode ser visualizada através da imagem a seguir.
Nela, a RNN utilizada na codificação é representada pela cor azul e a que é utlizada para decodificação é representada pela cor vermelha. Nessa imagem, também está sendo demonstrado o mecanismo de atenção que é um módulo frequentemente utilizado em arquiteturas seq2seq para adicionar pesos diferentes para as diferentes entradas. Dessa forma, esse mecanismo permite formas diferentes de as entradas impactarem as saídas como (inserir conceitos aqui) para conversão de estilo de texto, foi desenvolvido um modelo de testes inicial com base em um outro modelo testado encontrado no TensorFlow.
A base de dados foi construída através de um conjunto de vários livros escritos pelo Machado de Assis que foi encontrado no Kaggle. Como targets, utilizamos as frases presentes nos textos originais. Já para os inputs que precisavam ser paralelizados com os targets para o treinamento de modelos seq2seq, foi utilizado back translation. Primeiro, as frases foram todas traduzidas para inglês e, após isso, foram traduzidas de volta para português. Dessa forma, foram obtidos inputs com um estilo “neutro”.