Conheça o “Edu”: Algoritmo de recomendação de textos para uma aprendizagem mais eficiente

Bruna Alves Maia
Somos Tera
Published in
9 min readApr 1, 2021

--

Apresentamos parte do projeto do curso de Data Science da Tera. Este é o primeiro artigo do grupo de soluções para educação, composto pelos estudantes: Allan Bravos, Bruna Maia, Camila Neves, Guilherme Lino e Victor Stefanelli e do desenvolvedor convidado, Luiz Henrique Araújo.

Resumidamente, “Edu — “your educational recommender and guru” — é uma solução amigável que recomenda artigos para os usuários com base em seu perfil.

Ou em “termos técnicos”: Edu é uma solução desenvolvida utilizando o framework Flutter, que possibilita o desenvolvimento de aplicações híbridas (um mesmo código fonte pode ser desenvolvido para várias plataformas). A solução consome uma API desenvolvida em python utilizando Flask, que está hospedada no Heroku e, que tem acesso ao banco de dados completo, e faz as operações básicas. A recomendação disponibilizada no app é essencialmente a mesma que a original desenvolvida no Jupyter Notebook e baseada em um modelo de Collaborative Filtering. Para a interface, utilizamos como base um layout disponibilizado gratuitamente no Figma.

MOTIVAÇÃO & OBJETIVO

A internet é um grande aliado da educação moderna, ela propicia que seus usuários encontrem informações de forma rápida e sucinta, sobre praticamente qualquer tema, em segundos. As enciclopédias ficaram para trás, hoje todo o conteúdo está a alguns cliques de distância. Segundo uma pesquisa recente da Internet Live Stats, o Google processa mais de 3.5 bilhões de buscas por dia, no mundo todo e 84% dos usuários de internet pesquisam no google pelo menos 3x ao dia. Isso acontece porque estamos procurando respostas e novos conhecimentos o tempo todo e o termo “life long learning”, que significa aprender durante a vida, descreve bem o novo modus operandi da pessoa com internet.

Parece fácil desenvolver novas habilidades com uma ferramenta poderosa, mas na prática não é bem assim, já que apenas 36.4% das pessoas consideram as práticas de estudo online produtivas.

Como otimizar o tempo destinado para o aprendizado online? E como ser mais assertivo no que ler para aprender um novo assunto, quando se há tanta opção?

Pensando em solucionar esse dilema, nosso grupo desenvolveu um modelo de recomendação baseado em Collaborative Filtering, a mesma técnica aplicada no Spotify e Netflix. Combinando perfis de aprendizado e artigos taggeados e avaliados pelos próprios usuários.

CONSTRUINDO A SOLUÇÃO

O modelo de Filtro Colaborativo parte da seguinte ideia: usuários que interagem com o produto de uma mesma forma tendem a ter as mesmas preferências. Por exemplo, se os usuários A e B compraram um mesmo produto, quando A comprar um novo produto, essa será uma boa recomendação para o usuário B.

Nosso modelo de recomendação para as trilhas de aprendizagem segue o mesmo princípio. Os usuários são associados a perfis, que representam o seu grupo de preferência. Para cada tema da trilha, o usuário recebe uma recomendação de artigo e devolve o seu feedback ao final da leitura. A princípio, com a base de dados não populada, os usuários recebem recomendações aleatórias. Mas conforme as interações vão acontecendo, o sistema passa a recomendar artigos que foram bem avaliados pelo grupo, aumentando a chance de recomendação de artigos mais “interessantes”, que recebam melhores feedbacks.

Nosso modelo tem potencial para entregar diversos cursos otimizados, sobre qualquer tema (tecnologia, idiomas, música, educação básica). Para testar nossa hipótese, tivemos que definir um MVP. Assim, criamos perfis de aprendizado e trilhas para o curso hipotético de “Data Science”, usando muito das referências introduzidas pelo próprio curso da Tera.

  1. Pesquisamos as features relevantes na hora de decidir um artigo para ler: tempo de leitura, tema, tópico, se tem imagens ou não, idioma, etc…
  2. Tabulamos (manualmente) artigos associados às temáticas a serem abordadas na trilha de Data Science. Coletamos, para cada artigo, as informações referentes às features definidas, criando um padrão de classificação e gerando a primeira versão da nossa base de dados de artigos (nesse momento, ainda em um arquivo .xlsx).
  3. A partir da arquitetura conceitual da solução, construímos as tabelas importantes para nosso sistema: desde a que armazenaria as respostas da pesquisa inicial de perfil do usuário até a que iria armazenar os feedbacks (as notas) deles para os artigos.
  4. Em um arquivo do Jupyter Notebook, desenvolvemos a primeira versão do algoritmo de recomendação em si e as conexões necessárias com o banco de dados.
  5. No Streamlit, a versão inicial do Jupyter Notebook foi adaptada à lógica de funcionamento do Streamlit. Nesse ambiente, seria possível testar a solução para além das nossas máquinas locais, com uma interface amigável para o usuário final.

Veja a seguir mais detalhes da nossa solução:

CRIANDO AS FEATURES NECESSÁRIAS

Parte importante de um projeto de Data Science e Machine Learning é a criação das tabelas e features necessárias, que serão consumidas pelo modelo e aplicação. Falamos desse passo com mais detalhes no nosso artigo anterior sobre esse projeto.

O importante é ressaltar que cada coluna é uma feature e as informações das tabelas devem seguir a mesma lógica, já que estão todas conectadas. Faz parte do trabalho do Data Scientist e/ou do Q&A garantir que tudo esteja funcionando de maneira correta, com as labels indicadas na estrutura do dataset, pois é aqui no banco que o projeto começa.

A base elaborada para a nossa aplicação é composta por 10 tabelas, destinadas à alocação dos dados de identificação dos usuários, aos tipos de perfis, feedbacks e os artigos que serão recomendados. A base foi criada no PostgreSQL e se conecta diretamente ao nosso Jupyter Notebook.

ALGORITMO DE RECOMENDAÇÃO

O modelo de recomendação utilizado neste MVP foi uma versão bastante simples do Collaborative Filtering. A base de dados de artigos a serem recomendados foi carregada manualmente e organizada por tópicos. Os usuários na base são distribuídos em perfis, e o modelo de recomendação vai tentar indicar o artigo com melhor score para um dado perfil e tópico. Por exemplo, pessoas programadoras podem dar um score (nota média de NPS) igual a 7 para o Artigo A, e score 8 para o Artigo B, dentro do tópico de “Introdução a Ciência de Dados”. Considerando que esses sejam os maiores scores de artigos dentro do perfil e tópico, uma nova pessoa programadora ao passar por esse ponto na trilha, receberia a indicação do Artigo B. Já pessoas estatísticas poderiam dar score 8,5 para o Artigo A e 8 para o B. Essas pessoas receberiam a indicação do artigo A.

É importante destacar o problema do Cold Start. Na implementação do MVP, a solução dada foi entregar recomendações aleatórias de artigos para os perfis e tópicos, até que todos os artigos daquele bloco tenham recebido pelo menos um feeback. A partir daí, o modelo passa a recomendar sempre o artigo com maior score dentro do seu contexto (perfil e tópico).

As recomendações podem mudar conforme novos feedbacks chegam e diminuem o score do artigo melhor posicionado. Ou no caso de novos artigos serem adicionados ao banco de dados, ainda sem feedbacks.

TESTE E ITERAÇÃO DO MODELO

O modelo de recomendação foi testado manualmente e através de debug. Desta forma, foi possível observar a recomendação de artigos aleatórios para um dados perfil até que todos os artigos dentro de um tópico tivessem recebido feedback. Após isso, o modelo passou a recomendar o artigo com maior score, que é ajustado sempre que entra um novo feedback.

DEPLOY: GitHub + PostgreSQL + Streamlit + App

O código original, nosso querido e amado Jupyter Notebook, pode ser acessado aqui. Conforme já mencionado, todas as tabelas necessárias ao funcionamento da solução estão em um banco de dados na nuvem.

Entretanto, ainda era necessário superar o problema do Cold Start. Precisávamos atingir um threshold, uma massa crítica de recomendações reais que permitissem que a solução passasse a, de fato, recomendar artigos. Entre em cena então o Streamlit (e sua recém lançada nova plataforma de compartilhamento, o Streamlit Sharing).

A partir do nosso Jupyter Notebook original, um dos desafios enfrentados foi adaptar o código para funcionar no Streamlit. Em uma primeira aproximação, o custo de migração se mostrou bem baixo, uma vez que com apenas duas linhas de código o Streamlit já pode começar a ser usado em uma máquina com Python 3.6 a 3.8 instalado. A documentação e os diversos tópicos de dúvidas disponíveis sobre os mais variados temas foram muito úteis para começar a construir as primeiras peças da interface na plataforma.

O verdadeiro desafio, entretanto, foi conciliar a lógica de funcionamento do Streamlit com o que gostaria de gerar enquanto experiência do usuário durante o uso da aplicação, mesmo em uma versão beta.

A arquitetura do Streamlit foi pensada de modo a responder a toda e qualquer modificação do código-fonte da aplicação ou interação com widgets do aplicativo. Isso implica em um fluxo de dados bastante peculiar: sempre que algo deve ser atualizado na tela, o Streamlit executa novamente todo script de cima para baixo. Por exemplo, ao arrastar a barra de um slicer, inserir texto em uma caixa de entrada ou clicar em um botão, todo seu código é “reexecutado” desde o início.

Embora essa arquitetura permita funcionalidades incríveis ao Streamlit, a mesma acabou criando um desafio adicional para nós, uma vez que o fluxo da nossa aplicação dependia primordialmente de sucessivas interações entre o algoritmo (recomendação) e o usuário (nota). A cada interação (submissão de nota, por exemplo), o Streamlit executava o código do início e o efeito prático para o usuário era “retornar à estaca zero”.

Graças a comunidade já bem desenvolvida de usuários do Streamlit, solucionamos esse problema com a inclusão de SessionStates, uma feature ainda não totalmente implementada na plataforma, mas que já recebeu diversas contribuições da comunidade e já funciona perfeitamente (e em breve fará parte da plataforma de maneira nativa).

Finalmente (e depois de algumas horas de sono a menos), a solução intermediária para coleta de feedbacks estava pronta para ser compartilhada com o mundo (você pode conferir ela aqui).

Paralelamente aos esforços de criar uma versão no Streamlit, contamos com uma (super) ajuda do Luiz Henrique (@luizaraujodev) para dar vida ao Edu no formato de um app 100% funcional. Em breve na loja de aplicativos mais perto de você! #bum

LIÇÕES APRENDIDAS

  • Nunca, em hipótese alguma, subestime a importância do banco de dados (e a qualidade deles) em um projeto de Data Science;
  • Uma boa pesquisa e UX são grandes aliados do Data Scientist e tornarão suas decisões mais fáceis e embasadas;
  • O código não vai fazer mágica e será necessário muito trabalho manual;
  • Soluções que precisam de interações com usuários reais para engrenar podem ser especialmente desafiadoras;
  • Trabalhar com URLs públicas e por vezes não verificadas impactou no que queríamos entregar;
  • Menos é mais: definir um bom MVP é doído, mas necessário;

obrigada! :)

Este texto faz parte do programa do curso de Data Science da Tera. Este é o primeiro artigo do grupo de soluções para educação, composto pelos estudantes: Allan Bravos, Bruna Maia, Camila Neves, Guilherme Lino e Victor Stefanelli e do desenvolvedor convidado, Luiz Henrique Araújo.

--

--

Bruna Alves Maia
Somos Tera

Lead of Global UX Research in Gympass / Co-founder Experiência Observe / Feminist and researcher / Consumption Anthropology / Embroidery and video lover