Inteligência artificial na educação

Inteligência artificial na educação
gas
gas

Compartilhe

Como detectar se um aluno terá dificuldades no andamento de seu curso e interferir para ajudá-lo? Como conectar alunos de níveis semelhantes para que aprendam junto?

Desde que a Caelum decidiu enfrentar o desafio de criar uma plataforma online nos perguntamos como poder ajudar o aluno de maneiras diferentes. Desde então participamos de diversos cursos online nas mais variadas plataformas como os disponibilizados por Stanford através do Coursera.

Após estudar o curso de Machine Learning do instrutor Andrew Ng, um dos responsáveis pelo resultado de auto-detecção de faces e gatos do Google, participamos do Intelligent Tutor Systems 2012 na Grécia, onde discutimos abordagens de AI para a educação com equipes especializadas na área, em especial com desenvolvedores das plataformas de Carnegie Mellow e MIT.

Diversas das perguntas citadas anteriormente podem ser resolvidas com algoritmos de AI e muitas delas são utilizadas faz muito tempo.

Tomando como exemplo a deteção de aluno que está ficando atrasado no curso, temos os dados de quanto tempo cada aluno gasta para fazer um exercício:

Paulo: exercício 1, 12 minutos. exercício 2, 150 minutos. exercício 3, 3 minutos. exercicio 4, 15 minutos. Ana: exercício 1, 4 minutos. exercício 2, 170 minutos. exercício 3, 32 minutos. exercicio 4, 25 minutos. Maria: exercício 1, 1 minuto. exercício 2, 10 minutos. exercício 3, 3 minutos. exercicio 4, 25 minutos. Carlos: exercício 1, 12 minutos. exercício 2, 20 minutos. exercício 3, 31 minutos. exercicio 4, 15 minutos.

E sabemos que o Paulo e a Ana demoraram mais do que o tempo desejado para obter aproveitamento máximo do conteúdo apresentado. Isto é, classificamos eles como sendo alunos que atrasaram mais de 3 meses e portanto não aproveitaram tanto o curso.

Podemos representar esses dados através de uma matriz onde cada linha é um aluno, as 4 primeiras colunas o tempo gasto. Em Ruby, teríamos algo como:

 alunos = \[\] alunos << ```12, 150, 3, 15
 alunos << ```4, 170, 32, 25
 alunos << ```1, 10, 3, 25
 alunos << ```12, 20, 31, 15

Podemos também definir zero como sendo a classificação de quem atrasou e gostaríamos de motivá-lo, e um como quem não atrasou. Como temos que os dois primeiros não atrasaram e os dois últimos atrasaram, podemos dar um label para cada um deles:

 labels = ```1, 1, 0, 0

Note que cada aluno fez muito mais de 4 exercícios para acabar o curso, mas só estou analisando os 4 primeiros exercícios. Com essas informações e um novo aluno (Guilherme), como poderíamos dizer se o Guilherme terá dificuldades ou não? Existem diversos algoritmos e técnicas que podem ser utilizados. Nesse simples exemplo veremos a aplicação de Support Vector Machines através da libsvm em Ruby (o código original é em C e portanto para dezenas de diferentes linguagens):

 require 'libsvm' problem = Libsvm::Problem.new problem.set\_examples(labels, alunos.map {|ary| Libsvm::Node.features(ary) }) 

Configuramos os parâmetros do algoritmo, que no nosso caso não estudaremos mas em uma aplicação real é importante encontrar parâmetros que otimizem seu aprendizado:

 parameter = Libsvm::SvmParameter.new parameter.cache\_size = 4 parameter.eps = 0.001 parameter.c = 1 

Por fim, pedimos para o algoritmo ser treinado e criar um modelo de como os estudantes funcionam:

 model = Libsvm::Model.train(problem, parameter) 

E agora dado o Guilherme:

 guilherme = ``` 6, 140, 25, 10 

O algoritmo é capaz de prever:

 prediction = model.predict(Libsvm::Node.features(guilherme)) puts prediction 

E o resultado é 1, isto é, o Guilherme vai atrasar no curso e é importante avisá-lo para que não perca o ritmo. Claro, tudo isso aconteceu com uma base de dados muito pequena e irreal. Note que o segundo exercício é visualmente um indicador se o aluno vai ou não atrasar: acima de 100, todos atrasaram! O código Octave abaixo gera um gráfico que fica mais fácil visualizar:

 X = ```12,150,3,15,1;4,170,32,25,1;1,10,3,25,0;12,20,31,15,0
; y = ```1 1 0 0
'; primeiro = X(:,1); segundo = X(:,2); terceiro = X(:,3);

plot3(primeiro, segundo, terceiro, '^'); 

O gráfico a seguir mostra essas três primeiras dimensões do exercício:

Já o gráfico a seguir tenta "reduzir" os 4 exercícios em 3 (usando PCA), para que possamos "visualizar" todos os 4 exercícios em 3 dimensões, para tentar detectar um padrão:

Pode ser que o algoritmo tenha pego essa regra, que até mesmo um ser humano detecta rapidamente. O que aconteceria com dados reais?

 2.81670     7.40000     0.63330     0
 0.55000    21.65000     4.76670     0
 1.25000    53.36670    43.05000     1
 1.20000    36.10000    12.00000     0
 0.83330   180.00000    22.41670     1
 1.06670   180.00000   180.00000     0
 1.33330    95.26670    42.83330     0
 2.06670   180.00000    23.13330     0
 5.51670   180.00000    10.78330     1

180.00000 180.00000 12.65000 1

Esses são alguns dados reais de 3 exercícios de um curso. Note como não existe uma regra visual tão fácil que indique se o aluno terá ou não dificuldade para continuar o curso em um andamento bom para seu aprendizado:

O aluno [1.06670 180 180] demorou muito nos dois exercícios mas pode ser que ele fez uma viagem no fim de semana e por isso não respondeu naquela hora, mas mesmo assim conseguiu terminar o curso a tempo.

Treinando o SVM com C=0.08 o algoritmo é capaz de detectar um padrão muito mais complexo. Mas mesmo assim o algoritmo é capaz de prever com exatidão 86% dos casos.

C utilizado ACERTOS NO TREINO PREVISOES COM ACERTO 0.08 93.18% 85.71%

Por fim, ao fazer o fine tuning do algoritmo, encontramos funções capazes de detectar com muita exatidão se o aluno terá dificuldade em completar o curso a tempo.

C utilizado ACERTOS NO TREINO PREVISOES COM ACERTO 0.001 70.45454545454545 61.904761904761905 0.04 88.63636363636364 71.42857142857143 0.08 93.18181818181819 85.71428571428571 0.2 100.0 100.0

Essa implementação básica de SVM em Ruby é capaz de ir além prevendo o quão difícil será um exercício para um aluno, mas na prática utilizamos Octave, uma alternativa que balanceia melhor a simplifidade do código e o desempenho de algoritmos matemáticos como esse.

Veja outros artigos sobre Inovação & Gestão