Carregando as bibliotecas a serem usados nesse exemplo:

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(bnlearn)
library(reshape)
## 
## Attaching package: 'reshape'
## The following object is masked from 'package:dplyr':
## 
##     rename

Preparação dos Dados

Carregando os dados:

matricula = read.csv('alunosUFCGAnon.csv')

A seguir selecionamos somente os registros referentes ao curso de computação nos períodos relativos 1, 2 e 3. A ideia é construir uma rede bayesiana para atender os alunos que estão se matriculando no terceiro período, observando dessa forma os dados de matrícula dos alunos que já cursaram o terceiro período.

matricula_cc = filter(matricula,Cod_Curso==14102100,Periodo_Relativo==1|Periodo_Relativo==2|Periodo_Relativo==3)

Agora selecionamos as colunas de interesse, nesse caso Matricula, Cod_Disciplina (pois é mais compacta que o nome da disciplina) e a Situação (e.g. Aprovado e Reprovado).

matricula_cc = select(matricula_cc,Matricula,Cod_Disciplina,Situacao)

Com esse exemplo queremos responder os seguintes tipos de perguntas (assumindo somente alunos que cursaram o terceiro período):

Para isso precisamos considerar cada disciplina como uma variável binária, onde os valores indicam se uma disciplina foi ou não cursada por um aluno. Para isso, os dados devem ser transformados de tal forma que cada coluna seja uma disciplina e cada linha represente as disciplinas que foram cursadas por um aluno.

input_data = cast(matricula_cc,Matricula~Cod_Disciplina)
## Using Situacao as value column.  Use the value argument to cast to override this choice
## Aggregation requires fun.aggregate: length used as default

Valores maiores que 1 representam o fato que o aluno cursou essa disciplina mais de uma vez. Sendo assim, vamos transformar esses valores para 1 já que por agora estamos somente interessados se o aluno realizou ou não a matrícula em uma dada disciplina.

input_data=input_data[,-1] #retirando a coluna matricula
input_data[input_data!='0' & input_data!='1'] = 1

Aprendizagem da Rede

Agora estamos prontos para aprender a estrutura da rede. Para isso podemos usar a função hc (hill-climbing) do pacote bnlearn. Mas antes disso precisamos transformar as variáveis em fatores.

col_names = colnames(input_data) 
input_data[,col_names] = lapply(input_data[,col_names],factor) #transformando as variáveis em fatores
bnet_grafo = hc(input_data)
plot(bnet_grafo) #A função plot default é muito limitada. Precisamos explorar outras funções mais sofisticadas com mais opções de layout para a rede.

Para recuperar os “pais” de um dado nó, usamos a função parents. Os “pais” de Probabilidade e Estatística, por exemplo, são Fundamentos da Física Moderna, Cálculo I e Teoria da Computação. Isso indica que a matrícula em Probabilidade e Estatística pode ser vista como efeito das matrículas em Fundamentos da Física Moderna, Cálculo I e Teoria da Computação (as causas).

parents(bnet_grafo,"1114107")
## [1] "1108090" "1109103"

Uma vez definida a estrutura, precisamos agora aprender as tabelas de probabilidade condicionais (tpc) para cada varíavel (disciplina).

tpc = bn.fit(bnet_grafo,data=input_data)

Consultando a Rede

Agora finalmente estamos prontos para realizar consultas. Abaixo alguns exemplos de consultas probabilísticas que podem ser submetidas à rede.

cpquery(tpc,event=(`1109103`=="1"),evidence=TRUE)
## [1] 0.9265

Nesse caso, mais de 92% de todos os alunos que cursaram o terceiro período se matricularam em Cálculo I.

cpquery(tpc,event=(`1305218`=="1"),evidence=TRUE)
## [1] 0.2939

Note que embora Metodologia Científica seja uma disciplina do segundo período, poucos alunos a cursaram pois o atual Prof. da disciplina sugere um pré-requisito informal que se encontra em um período posterior no plano de curso.

cpquery(tpc,event=(`1114107`=="1"),evidence=((`1108090`==1) & (`1109049`==1)))
## [1] 0.8852772