A fim de analisar qual o melhor número de vizinhos para uma Filtragem Colaborativa, analisou-se qual é o menor erro para diferentes números de vizinhos considerando o mesmo algoritmo.
library(dplyr)
library(corrplot)
library(GGally)
library(ggplot2)
library(reshape2)
library(caret)
library(mlbench)
library(hydroGOF)
Os dados são tratados como anteriormente, veja em http://rpubs.com/liviaCavalcanti/337528.
dados_alunos <- read.csv("../alunosUFCGAnon.csv")
dados_aluno_cc <- dados_alunos %>% filter(Cod_Curso == 14102100 & Cod_Evasao == 0 & Tipo == "Obrigatória")
dados_aluno_cc <- dados_aluno_cc %>% mutate(Matricula = factor(Matricula)) %>% arrange(Matricula) %>%
select(Matricula, Cod_Disciplina, Nome_Disciplina, Periodo, Creditos, Media_Disciplina, Situacao, Periodo_Ingresso, Periodo_Relativo)
dados_aluno_cc <- dados_aluno_cc %>% group_by(Matricula) %>% mutate(Media = round(mean(Media_Disciplina), digits = 2)) %>% filter(!is.na(Media))
# storing data as factors insures that the modeling functions will treat such data correctly.
# Factors in R are stored as a vector of integer values with a corresponding set of character values to use when the factor is displayed
# Calulo do CRA
alunos_cra <- dados_aluno_cc %>% mutate(Cra.Crontibute = Media*Creditos) %>% summarise(cra = sum(Cra.Crontibute)/sum(Creditos))
alunos_max_media <- dados_aluno_cc %>% group_by(Matricula, Media_Disciplina) %>% filter(Media_Disciplina == max(Media_Disciplina)) %>% ungroup() %>%
select(Nome_Disciplina, Matricula, Media_Disciplina) %>% mutate(Nome_Disciplina = as.factor(gsub(" ", ".", Nome_Disciplina))) %>%
dcast(Matricula ~ Nome_Disciplina, mean) %>% merge(alunos_cra)
## Using Media_Disciplina as value column: use value.var to override.
alunos_max_media <- bind_cols(alunos_max_media,distinct(dados_aluno_cc %>% select(Matricula, Periodo_Ingresso))%>% select(Periodo_Ingresso)) %>% select(-Matricula1)
## Adding missing grouping variables: `Matricula`
alunos_graduados <- alunos_max_media[complete.cases(alunos_max_media), ]
##Organizando os data frames principais
# separando alunos por periodo
primeiro_periodo <- alunos_max_media %>% select(Matricula, cra, CALCULO.DIFERENCIAL.E.INTEGRAL.I, ÁLGEBRA.VETORIAL.E.GEOMETRIA.ANALÍTICA, PROGRAMAÇÃO.I,
LABORATÓRIO.DE.PROGRAMAÇÃO.I, INTRODUÇÃO.A.COMPUTAÇÃO, LEITURA.E.PRODUCAO.DE.TEXTOS, Periodo_Ingresso) %>%
na.omit(primeiro_periodo) %>% arrange(Matricula) %>%
rename(matricula = Matricula, cra = cra,calculo1 = CALCULO.DIFERENCIAL.E.INTEGRAL.I, vetorial = ÁLGEBRA.VETORIAL.E.GEOMETRIA.ANALÍTICA, p1 = PROGRAMAÇÃO.I,
lp1 = LABORATÓRIO.DE.PROGRAMAÇÃO.I, ic = INTRODUÇÃO.A.COMPUTAÇÃO, lpt = LEITURA.E.PRODUCAO.DE.TEXTOS)
head(primeiro_periodo)
## matricula cra calculo1 vetorial p1 lp1 ic lpt Periodo_Ingresso
## 1 B10079 6.37 5.75 5.00 5.0 5.75 7.10 9.5 2007.1
## 2 B10087 1.05 0.00 0.00 0.0 0.00 1.95 7.6 2008.2
## 3 B10088 2.10 0.00 0.15 0.7 0.00 5.20 7.7 2009.2
## 4 B10092 7.10 6.90 4.25 5.0 7.00 7.50 8.5 2009.1
## 5 B10172 4.68 2.70 5.35 6.9 7.10 7.30 8.2 2011.2
## 6 B10192 6.55 5.85 5.00 8.4 8.40 7.80 8.8 2006.1
segundo_periodo <- alunos_max_media %>%
select(Matricula,cra, CALCULO.DIFERENCIAL.E.INTEGRAL.II, FUNDAMENTOS.DE.FÍSICA.CLÁSSICA, TEORIA.DOS.GRAFOS, PROGRAMAÇÃO.II,
LABORATÓRIO.DE.PROGRAMAÇÃO.II, MATEMÁTICA.DISCRETA) %>% na.omit() %>%
arrange(Matricula) %>%
rename(matricula = Matricula, cra = cra,calculo2 = CALCULO.DIFERENCIAL.E.INTEGRAL.II, classica = FUNDAMENTOS.DE.FÍSICA.CLÁSSICA,
grafos = TEORIA.DOS.GRAFOS, p2 = PROGRAMAÇÃO.II, lp2 = LABORATÓRIO.DE.PROGRAMAÇÃO.II, discreta = MATEMÁTICA.DISCRETA)
head(segundo_periodo)
## matricula cra calculo2 classica grafos p2 lp2 discreta
## 1 B10079 6.37 4.200000 5.7 7.8 8.90 8.3 4.050000
## 2 B10092 7.10 5.400000 5.0 5.1 6.70 8.2 5.000000
## 3 B10172 4.68 2.033333 5.5 5.5 4.15 3.0 4.666667
## 4 B10192 6.55 5.400000 6.4 5.0 6.00 8.2 5.000000
## 5 B10199 5.86 5.100000 7.8 5.0 6.30 8.7 5.100000
## 6 B1024 5.91 5.000000 5.3 7.6 8.30 8.7 7.000000
terceiro_periodo <- alunos_max_media %>%
select(Matricula,cra, ESTRUTURA.DE.DADOS.E.ALGORITMOS, LAB.DE.ESTRUTURA.DE.DADOS.E.ALGORITMOS, FUNDAMENTOS.DE.FÍSICA.MODERNA,
ALGEBRA.LINEAR.I,PROBABILIDADE.E.ESTATISTICA, TEORIA.DA.COMPUTAÇÃO, GERÊNCIA.DA.INFORMAÇÃO) %>%
na.omit() %>%
arrange(Matricula) %>%
rename(matricula = Matricula, eda = ESTRUTURA.DE.DADOS.E.ALGORITMOS, leda = LAB.DE.ESTRUTURA.DE.DADOS.E.ALGORITMOS, moderna = FUNDAMENTOS.DE.FÍSICA.MODERNA,
linear = ALGEBRA.LINEAR.I, prob = PROBABILIDADE.E.ESTATISTICA, tc = TEORIA.DA.COMPUTAÇÃO, gi = GERÊNCIA.DA.INFORMAÇÃO)
head(terceiro_periodo)
## matricula cra eda leda moderna linear prob tc gi
## 1 B10092 7.10 6.60 7.9 8.3 6.1 6.0 7.2 7.7
## 2 B10284 7.14 7.00 7.2 8.3 6.1 5.5 6.9 7.0
## 3 B10304 6.17 5.15 7.0 8.5 6.2 1.2 6.9 8.6
## 4 B10443 7.15 7.00 7.7 8.7 7.2 6.8 7.3 7.9
## 5 B10504 7.12 6.70 8.2 8.3 5.0 6.7 7.0 7.1
## 6 B10644 6.07 5.10 5.2 5.0 5.1 5.0 5.3 4.7
quarto_periodo <- alunos_max_media %>% select(Matricula, cra, PARADIGMAS.DE.LING..DE.PROGRAMAÇÃO, METODOS.ESTATISTICOS, ORG.E.ARQUITETURA.DE.COMPUTADORES.I,
LAB.DE.ORG.E.ARQUITETURA.DE.COMPUTADORES, LÓGICA.MATEMÁTICA, ENGENHARIA.DE.SOFTWARE.I, SISTEMAS.DE.INFORMAÇÃO.I) %>%
na.omit() %>%
arrange(Matricula)%>%
rename(matricula = Matricula, plp = PARADIGMAS.DE.LING..DE.PROGRAMAÇÃO, metodos = METODOS.ESTATISTICOS, oac = ORG.E.ARQUITETURA.DE.COMPUTADORES.I,
loac = LAB.DE.ORG.E.ARQUITETURA.DE.COMPUTADORES, logica = LÓGICA.MATEMÁTICA, es = ENGENHARIA.DE.SOFTWARE.I, si1 = SISTEMAS.DE.INFORMAÇÃO.I)
head(quarto_periodo)
## matricula cra plp metodos oac loac logica es si1
## 1 B10092 7.10 7.0 5.0 7.6 7.1 7.0 6.6 9.3
## 2 B10192 6.55 7.3 5.1 5.8 7.3 6.6 6.3 9.6
## 3 B10199 5.86 5.6 6.5 5.2 8.6 6.2 7.0 5.7
## 4 B10447 8.66 8.1 8.7 8.3 9.2 10.0 9.2 9.6
## 5 B10504 7.12 9.3 6.0 7.2 9.6 8.3 8.1 9.7
## 6 B10644 6.07 5.5 6.4 7.3 8.7 7.0 8.3 8.4
# Unindo os periodos
primeiro_segundo_periodos <- merge(primeiro_periodo, segundo_periodo)
head(primeiro_segundo_periodos)
## matricula cra calculo1 vetorial p1 lp1 ic lpt Periodo_Ingresso
## 1 B10079 6.37 5.750000 5.00 5.0 5.75 7.1 9.5 2007.1
## 2 B10092 7.10 6.900000 4.25 5.0 7.00 7.5 8.5 2009.1
## 3 B10172 4.68 2.700000 5.35 6.9 7.10 7.3 8.2 2011.2
## 4 B10192 6.55 5.850000 5.00 8.4 8.40 7.8 8.8 2006.1
## 5 B10199 5.86 3.666667 6.20 6.1 5.60 7.8 7.0 2005.2
## 6 B1024 5.91 0.000000 5.45 7.5 8.40 7.7 7.0 2010.1
## calculo2 classica grafos p2 lp2 discreta
## 1 4.200000 5.7 7.8 8.90 8.3 4.050000
## 2 5.400000 5.0 5.1 6.70 8.2 5.000000
## 3 2.033333 5.5 5.5 4.15 3.0 4.666667
## 4 5.400000 6.4 5.0 6.00 8.2 5.000000
## 5 5.100000 7.8 5.0 6.30 8.7 5.100000
## 6 5.000000 5.3 7.6 8.30 8.7 7.000000
# Primeiro, segundo e terceiro periodo
primeiro_a_terceiro_periodo <- merge(primeiro_segundo_periodos, terceiro_periodo)
periodos_dados <- merge(primeiro_a_terceiro_periodo, quarto_periodo) %>% select(matricula, everything())
head(periodos_dados)
## matricula cra calculo1 vetorial p1 lp1 ic lpt Periodo_Ingresso
## 1 B10092 7.10 6.90 4.25 5.0 7.0 7.5 8.5 2009.1
## 2 B10504 7.12 4.65 6.30 5.3 7.9 7.6 7.2 2009.1
## 3 B10644 6.07 3.70 5.80 7.0 7.2 8.3 7.2 2010.2
## 4 B10973 6.73 5.60 5.60 7.0 7.7 8.4 6.7 2010.1
## 5 B11044 8.47 8.70 8.60 9.0 8.6 9.1 10.0 2008.1
## 6 B11365 8.35 6.20 8.20 7.9 7.9 9.2 9.3 2010.2
## calculo2 classica grafos p2 lp2 discreta eda leda moderna linear prob
## 1 5.400000 5.000000 5.1 6.7 8.2 5.0 6.6 7.9 8.3 6.1 6.0
## 2 5.000000 5.750000 6.3 7.7 5.0 6.3 6.7 8.2 8.3 5.0 6.7
## 3 4.033333 3.266667 7.9 7.6 7.0 6.5 5.1 5.2 5.0 5.1 5.0
## 4 5.900000 7.400000 5.9 7.4 7.0 6.8 7.0 5.0 7.7 6.7 5.2
## 5 8.400000 7.900000 8.2 8.8 9.4 8.3 8.4 9.4 9.4 9.3 7.2
## 6 6.900000 6.900000 9.2 9.1 9.3 7.6 7.1 8.6 8.2 8.3 7.0
## tc gi plp metodos oac loac logica es si1
## 1 7.2 7.7 7.0 5.0 7.6 7.1 7.0 6.60 9.3
## 2 7.0 7.1 9.3 6.0 7.2 9.6 8.3 8.10 9.7
## 3 5.3 4.7 5.5 6.4 7.3 8.7 7.0 8.30 8.4
## 4 7.6 7.7 7.0 8.6 6.6 5.0 5.8 4.75 8.4
## 5 7.8 7.8 6.8 9.0 8.2 8.8 10.0 8.50 8.4
## 6 7.9 7.7 9.4 8.1 8.2 10.0 8.4 9.10 9.4
COL_QUARTO_PER <- colnames(quarto_periodo %>% select(-cra, -matricula))
COL_QUARTO_PER
## [1] "plp" "metodos" "oac" "loac" "logica" "es" "si1"
## /// FUNCOES E CONSTANTES \\\##
#K= 10
NEIGH = 0.7
get_sim <- function(df) {
row.names(df) <- df$matricula
df <- df %>% subset(select=-c(matricula))
inv_df <- as.data.frame(t(df))
res <- cor(inv_df[sapply(inv_df, is.numeric)], use="p", method='pearson')
return(res);
}
# retorna um vector de Named num, cujo nome é a matrícula e o valor a similaridade
get_neigh <- function(df, index, corr, K) {
matr <- (df[index, 1])
# todos os vizinhos, porém temos que "invalidar" ele mesmo
corr[as.double(matr), as.double(matr)] = 0
all_neigh <- corr[matr, ]
k_neigh <- sort(all_neigh, decreasing = T)[1:K]
return(k_neigh);
}
# calcula score ignorando vizinhos com NAs
get_score <- function(df, k_neigh, item) {
notas <- subset(df, matricula %in% names(k_neigh))
# removendo vizinhos que não possuem notas
notas <- na.omit(notas)
# se todas as notas dos vizinhos forem NAs ou nenhum vizinho com
# nota tenha similaridade > NEIGH consideramos que esse aluno
# não tem vizinhos
if(nrow(notas) == 0) {
return(NA)
}
# atualizando similaridade
notas$sim <- 0
for(i in 1:length(notas$matricula)) {
notas$sim[i] <- k_neigh[as.character(notas$matricula[i])]
}
# se todas as notas dos vizinhos forem NAs ou nenhum vizinho com
# nota tenha similaridade > NEIGH consideramos que esse aluno
# não tem vizinhos
eh_valido <- notas[notas$sim > NEIGH,]
if(nrow(eh_valido) == 0) {
return(NA)
}
res <- sum(notas[, item] * notas$sim) / sum(notas$sim)
return(res)
}
rmse_cross <- as.data.frame(matrix(ncol = 7, nrow = 50))
media_rmse4 <- as.data.frame(matrix(ncol = 0, nrow = 50))
# separando em teste e treino
temp <- createDataPartition(periodos_dados$Periodo_Ingresso, p = 0.95, list = F)
A mudança em relação ao código anterior é que o número de vizinhos ‘K’ não é mais uma constante, e sim um valor que muda a cada iteração (‘K’ = ‘k’), sendo guardados os valores obtidos para cada ‘k’.
## 1 2 3 4 5 6 7 8
## 1 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501
## 2 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877
## 3 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946
## 4 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520
## 5 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302
## 6 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501
## 9 10 11 12 13 14 15 16
## 1 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501
## 2 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877
## 3 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946
## 4 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520
## 5 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302
## 6 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501
## 17 18 19 20 21 22 23 24
## 1 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501
## 2 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877
## 3 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946
## 4 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520
## 5 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302
## 6 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501
## 25 26 27 28 29 30 31 32
## 1 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501
## 2 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877
## 3 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946
## 4 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520
## 5 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302
## 6 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501
## 33 34 35 36 37 38 39 40
## 1 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501
## 2 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877
## 3 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946
## 4 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520
## 5 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302
## 6 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501
## 41 42 43 44 45 46 47 48
## 1 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501 2.385501
## 2 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877 2.396877
## 3 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946 2.344946
## 4 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520 2.333520
## 5 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302 2.376302
## 6 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501 2.382501
## 49 50 media_geral
## 1 2.385501 2.385501 2.385501
## 2 2.396877 2.396877 2.396877
## 3 2.344946 2.344946 2.344946
## 4 2.333520 2.333520 2.333520
## 5 2.376302 2.376302 2.376302
## 6 2.382501 2.382501 2.382501
## media_geral
## 1 2.33352
Por fim, foi feita a média de todas as observações por linha, ou seja, número de vizinhos e chegou-se ao valor ideal de 5 vizinhos.