Construir uma regressão linear simples que explique o GPA (Grade Point Average), e realizar uma Análise de “Cluster”.
1. Importando dados do Excel:
library(readxl)
CASchools <- read_excel("C:/Users/User/Documents/Computacional/CASchools.xlsx")
View(CASchools)
str(CASchools)
## tibble [420 × 15] (S3: tbl_df/tbl/data.frame)
## $ ...1 : num [1:420] 1 2 3 4 5 6 7 8 9 10 ...
## $ district : num [1:420] 75119 61499 61549 61457 61523 ...
## $ school : chr [1:420] "Sunol Glen Unified" "Manzanita Elementary" "Thermalito Union Elementary" "Golden Feather Union Elementary" ...
## $ county : chr [1:420] "Alameda" "Butte" "Butte" "Butte" ...
## $ grades : chr [1:420] "KK-08" "KK-08" "KK-08" "KK-08" ...
## $ students : num [1:420] 195 240 1550 243 1335 ...
## $ teachers : num [1:420] 10.9 11.1 82.9 14 71.5 ...
## $ calworks : num [1:420] 0.51 15.42 55.03 36.48 33.11 ...
## $ lunch : num [1:420] 2.04 47.92 76.32 77.05 78.43 ...
## $ computer : num [1:420] 67 101 169 85 171 25 28 66 35 0 ...
## $ expenditure: num [1:420] 6385 5099 5502 7102 5236 ...
## $ income : num [1:420] 22.69 9.82 8.98 8.98 9.08 ...
## $ english : num [1:420] 0 4.58 30 0 13.86 ...
## $ read : num [1:420] 692 660 636 652 642 ...
## $ math : num [1:420] 690 662 651 644 640 ...
Dicionário de dados:
district: Código do distrito;
school: Nome da escola;
county: Município;
grades: Intervalo de notas do distrito;
students: Total de inscrições(matrícula);
teachers: Número de professores;
calworks: Porcentagem de qualificação para CalWorks
(assistência de renda);
lunch: Porcentagem de qualificação para almoço a preço
reduzido;
computer:Número de computadores;
expenditure: Despesa por aluno;
income: Renda média do distrito (em US$ 1.000);
english: Porcentagem de alunos de inglês;
read: Pontuação média de leitura;
math: Nota média de matemática.
attach(CASchools)
plot(math,read, main = "Diagrama de Dispersão", xlab = "Nota em Matemática",
ylab = "Nota em Leitura", col="gold4")
modelo1<- lm(data=CASchools, formula=math~read)
abline(modelo1, col="brown2")
Para melhorar a visualização, observaremos a distância dos pontos à reta do modelo.
Observando o gráfico de dispersão, é notável a presença de dados extremos à reta. Apesar do grande número de dados, é possível notar que há uma correlação significativa positiva entre a variável math e a variável read.
Math:
summary(math)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 605.4 639.4 652.5 653.3 665.9 709.5
var(math)
## [1] 351.7201
sd(math)
## [1] 18.7542
Read:
summary(read)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 604.5 640.4 655.8 655.0 668.7 704.0
var(read)
## [1] 404.3309
sd(read)
## [1] 20.10798
modelo1$coefficients
## (Intercept) read
## 89.5657974 0.8607668
Teremos a equação: \[ y = 89.5657 + 0.8607 * x \]
Na equação, variável resposta ou dependente (y) será o valor de math. O intercepto, ou seja, o valor que a variável resposta irá assumir quando a variável independente for igual a zero, é \(89.5657\), o coeficiente de regressão da variável x é igual a \(0.8607\), e x é o valor assumido por read, a variável preditora ou independente.
summary(modelo1)
##
## Call:
## lm(formula = math ~ read, data = CASchools)
##
## Residuals:
## Min 1Q Median 3Q Max
## -26.4897 -4.2335 0.5528 4.2775 23.1307
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 89.56580 11.50984 7.782 5.67e-14 ***
## read 0.86077 0.01756 49.005 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.23 on 418 degrees of freedom
## Multiple R-squared: 0.8517, Adjusted R-squared: 0.8514
## F-statistic: 2402 on 1 and 418 DF, p-value: < 2.2e-16
A significância da correlação é confirmada pelo \(p-valor<0.05\).
O valor de R²(R-squared) afirma que o modelo calculado explica 85.17% dos resultados.
confint(modelo1)
## 2.5 % 97.5 %
## (Intercept) 66.9414144 112.1901804
## read 0.8262404 0.8952931
O intervalo de confiança estreito, também mostra uma correlação significativa entre as variáveis math e read. Por fim, verificando o coeficiente de correlação exato:
cor.test(math,read)
##
## Pearson's product-moment correlation
##
## data: math and read
## t = 49.005, df = 418, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.9073417 0.9359362
## sample estimates:
## cor
## 0.9229015
O resultado da correlação próximo de 1, que é o maior nível positivo, comprova uma correlação forte positiva, em que os valores de math e read aumentam no mesmo sentido.
plot(modelo1, which=c(1:4), pch = 20)
Observando o gráfico dos dados do modelo relacionados aos valores estimados (primeira imagem), apesar da dispersão pelo grande número de dados, é possível notar que grande parte dos pontos estão próximos à linha central para y=0.
No segundo gráfico, o dos quantis teóricos, é possível notar uma distribuição normal, com alguns dados dispersos nas duas extremidades.
Ao analisar o terceiro podemos visualizar, assim como foi visto no primeiro gráfico, a dispersão dos dados com pouca concentração próxima à linha.
Com o quarto gráfico é possível identificar a presença de outliers, que são os dados mais dispersos. Como os valores de y não passaram de 1, vemos que esses dados não estão muito distantes da linha de distribuição.
attach(CASchools)
## The following objects are masked from CASchools (pos = 3):
##
## ...1, calworks, computer, county, district, english, expenditure,
## grades, income, lunch, math, read, school, students, teachers
plot(math,read, main = "Diagrama de Dispersão", xlab = "Nota Média em matemática",
ylab = "Nota Média em Leitura", col="gold4")
modelo1<- lm(data=CASchools, formula=math~read)
abline(modelo1, col="brown2")
pontos.1 <- seq(from = min(CASchools$read), to = max(CASchools$read),length.out = 800)
lm.inter <- predict(object = modelo1, newdata = data.frame(read = pontos.1),
interval = "confidence", level = 0.95)
lines(x = pontos.1, y = lm.inter[,2],type = "l", lwd = 2.5, col = "blue4", lty = 4)
lines(x = pontos.1, y = lm.inter[,3],type = "l", lwd = 2.5, col = "black", lty = 4)
É possível ver em azul a linha prevista do limite inferior, em preto a do limite superior, e na cor marrom está o modelo linear.
library("ggplot2")
## Warning: package 'ggplot2' was built under R version 4.3.2
library("tidyverse")
## Warning: package 'dplyr' was built under R version 4.3.2
library("dplyr")
CASchools %>%
ggplot(mapping = aes(x=math, y=english)) + geom_point() +
xlab("Nota Média em Matemática") + ylab("Porcentagem de Alunos de Inglês") +
geom_smooth(method = "lm") + ggtitle("Dispersão entre Math e English")
Diferente da análise de math e read, é possível notar que grande parte dos dados extremos estão muito distantes da linha.
Sumário dos dados, variância, e o desvio padrão de English:
English:
summary(english)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.000 1.941 8.778 15.768 22.970 85.540
var(english)
## [1] 334.3751
sd(english)
## [1] 18.28593
modelo2<- lm(data=CASchools, formula=math~english)
modelo2$coefficients
## (Intercept) english
## 662.5393150 -0.5832449
Teremos a equação:
\[
y = 662.5393 + (-0.5832) * english
\]
Na equação, variável resposta ou dependente (y) será o valor de math. O intercepto, ou seja, o valor que a variável resposta irá assumir quando a variável independente for igual a zero, é \(662.5393\), o coeficiente de regressão da variável x é igual a \(-0.5832\), e x é o valor assumido por english, a variável preditora ou independente.
confint(modelo2)
## 2.5 % 97.5 %
## (Intercept) 660.5822359 664.4963941
## english -0.6643536 -0.5021363
Com o resultado, é possível notar um intervalo mais amplo do que o observado entre math e read, mostrando um nível de correlação mais baixo entre math e english.
summary(modelo2)
##
## Call:
## lm(formula = math ~ english, data = CASchools)
##
## Residuals:
## Min 1Q Median 3Q Max
## -49.902 -11.289 -0.635 10.148 49.717
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 662.53931 0.99564 665.44 <2e-16 ***
## english -0.58324 0.04126 -14.13 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 15.44 on 418 degrees of freedom
## Multiple R-squared: 0.3234, Adjusted R-squared: 0.3218
## F-statistic: 199.8 on 1 and 418 DF, p-value: < 2.2e-16
Existe significância na correlação entre math e english, confirmada pelo p-valor<0.05.
O valor de R²(R-squared) afirma que o modelo calculado explica 32.34% das variações. Sendo uma porcentagem baixa, as previsões realizadas a partir desse modelo não são confiáveis.
cor.test(math,english)
##
## Pearson's product-moment correlation
##
## data: math and english
## t = -14.135, df = 418, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## -0.6300821 -0.5002148
## sample estimates:
## cor
## -0.5686818
A correlação entre math e english possui sentido negativo (-0.5686818) e significância moderada, indicando que as variáveis crescem em sentidos opostos com presença de outliers.
res.math.eng<- residuals(modelo2)
ggplot(data.frame(res.math.eng = res.math.eng), aes(x = res.math.eng)) +
geom_histogram(color = "gold4", fill = "brown2") +
ggtitle("Histograma dos Resíduos") + xlab("Resíduos de Math e English") + ylab(" ")
É possível observar que o histograma indica dispersão, com outliers nas duas extremidades do gráfico, e a maior parte dos dados está entre -30 e 30, apresentando uma concentração similar entre os dados situados à direita e à esquerda de zero.
qqnorm(res.math.eng, main = "Gráfico QQ dos Resíduos de Math e English",
xlab = "Quantis Teóricos", ylab = "Quantis dos Resíduos")
qqline(res.math.eng)
Explorando os dados de lunch:
Lunch:
summary(lunch)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.00 23.28 41.75 44.71 66.86 100.00
var(lunch)
## [1] 735.6778
sd(lunch)
## [1] 27.12338
library("ggplot2")
library("tidyverse")
library("dplyr")
CASchools %>%
ggplot(mapping = aes(x=math, y=lunch)) + geom_point() +
xlab("Nota Média em Matemática") + ylab("Qualificação Para Lanche a Preço Reduzido") +
geom_smooth(method = "lm") + ggtitle("Dispersão entre Math e Lunch")
Observando os pontos é possível verificar que na medida que a nota em matemática aumenta, menor é a porcentagem de qualificação para almoço a preço reduzido. Existem dados dispersos, mas a correlação é clara e significativa, apresentando sentido negativo.
modelo3<- lm(data=CASchools, formula=math~lunch)
modelo3$coefficients
## (Intercept) lunch
## 678.7828269 -0.5690655
Teremos a equação:
\[
y = 678.7828269 + (-0.5690655) * lunch
\]
Na equação, a variável resposta ou dependente (y) será o valor de math. O intercepto, ou seja, o valor que a variável resposta irá assumir quando a variável independente for igual a zero, é \(678.7828269\), o coeficiente de regressão da variável x é igual a \(-0.5690655\), e lunch será o valor assumido pela própria variável, que é a preditora do modelo.
confint(modelo3)
## 2.5 % 97.5 %
## (Intercept) 676.808965 680.756689
## lunch -0.606826 -0.531305
O resultado apresenta um intervalo de confiança estreito, apoiando a existência de um alto nível de correlação entre as variáveis em estudo.
summary(modelo3)
##
## Call:
## lm(formula = math ~ lunch, data = CASchools)
##
## Residuals:
## Min 1Q Median 3Q Max
## -33.083 -6.743 -0.223 6.435 31.573
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 678.78283 1.00417 675.96 <2e-16 ***
## lunch -0.56907 0.01921 -29.62 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 10.67 on 418 degrees of freedom
## Multiple R-squared: 0.6774, Adjusted R-squared: 0.6766
## F-statistic: 877.5 on 1 and 418 DF, p-value: < 2.2e-16
Existe significância na correlação entre math e lunch, confirmada pelo p-valor<0.05.
O valor de R²(R-squared) mostra que o modelo explica \(67.74\)% das variações.
cor.test(math,lunch)
##
## Pearson's product-moment correlation
##
## data: math and lunch
## t = -29.623, df = 418, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## -0.8516336 -0.7895025
## sample estimates:
## cor
## -0.8230145
Confirmando o que foi visto nas análises acima, a correlação entre math e lunch é fortemente significativa, com sentido negativo (\(-0.8230145\)). O valor de “cor” próximo a \(-1\), que é o mais próximo para correlações perfeitas, confirma essas informações.
par(mfrow= c(2,2))
plot(modelo3, which=c(1:4), pch = 20)
No primeiro e terceiro gráfico notamos a concentração dos pontos em torno da linha central, mostrando dados dispersos, assim como foi visto no gráfico de dispersão entre math e lunch.
No segundo gráfico é possível notar uma distribuição normal dos resíduos através dos quantis teóricos, com mais dados dispersos na extremidade direita.
No último gráfico é possível identificar a presença dos outliers, já vistos anteriormente, que possuem baixo nível de significância na distribuição.
plot(math~lunch , main = "Gráfico de Math e Lunch", xlab = "Nota Média em matemática",
ylab = "Qualificação Para Almoço a Preço Reduzido(%)", col="lightblue4")
abline(modelo3, col="brown")
pontos.3<- seq(from = min(CASchools$lunch), to = max(CASchools$lunch),length.out = 800)
lm.inter.3<- predict(object = modelo3, newdata = data.frame(lunch = pontos.3),
interval = "confidence", level = 0.95)
lines(x = pontos.3, y = lm.inter.3[,2], type = "l", lwd = 2.5, col = "blue4", lty = 4)
lines(x = pontos.3, y = lm.inter.3[,3], type = "l", lwd = 2.5, col = "black", lty = 4)
É possível visualizar em azul a linha prevista do limite inferior, em preto a do limite superior, e na cor marrom está o modelo linear.
Com o intuito de analisar a relação entre a nota média em matemática e a despesa por aluno (math e expenditure), será aplicada uma técnica para identificar padrões em conjuntos de dados, agrupando dados semelhantes em clusters. Desta forma, será realizada a Análise de Cluster.
math.exp<- data.frame(subset(CASchools, select=c(math, expenditure)))
Foi feita a separação dos dados de math e expenditure em um data frame.
ggplot() + geom_point(aes(x = math, y = expenditure), data = CASchools, alpha = 0.7) +
ggtitle('Gráfico de Math e Expenditure') + xlab("Nota Média em Matemática") +
ylab("Despesa por Aluno")
Observando o gráfico, notamos os dados muito dispersos, sem agrupamentos bem definidos. Dessa forma, não é possível definir um número inicial de clusters.
Como há um grande número de dados, irei utilizar o dendograma para visualizar melhor os grupos formados.
library(ggdendro)
dendrogram <- hclust(dist(math.exp, method = 'euclidean'), method = 'ward.D')
ggdendrogram(dendrogram, rotate = FALSE, labels = FALSE, theme_dendro = TRUE) +
labs(title = "Dendrograma de Math e Expenditure")
Observando o dendograma, vemos a formação de alguns grupos com maior altura, e é possível definir possíveis valores para k de acordo com o número de grupos. Utilizarei k=3, k=4 e k=5.
agrup <- hclust(dist(math.exp, method = 'euclidean'), method = 'ward.D')
classes <- cutree(agrup, k = 3)
math.exp$cluster <- classes
ggplot() + geom_point(aes(x = math, y = expenditure, color = cluster), data = math.exp,
size = 2) +
ggtitle("Agrupamento Hierárquico: Clusters com k = 3") +
scale_colour_gradientn(colours=rainbow(5)) +
xlab("Nota Média em Matemática") + ylab("Despesa por Aluno")
Os clusters separados por cores ainda estão muito dispersos, com grande concentração de dados nos grupos 3 (roxo) e 2 (verde). O grupo 1(vermelho) ganha destaque pela quantidade superior de pontos com nota em matemática acima de \(690\), sendo o grupo mais alto em y, com despesa por aluno acima de \(6000\), na maioria dos casos.
agrup <- hclust(dist(math.exp, method = 'euclidean'), method = 'ward.D')
classes <- cutree(agrup, k = 4)
math.exp$cluster <- classes
ggplot() + geom_point(aes(x = math, y = expenditure, color = cluster), data = math.exp,
size = 2) +
ggtitle("Agrupamento Hierárquico: Clusters com k = 4") +
scale_colour_gradientn(colours=rainbow(5)) +
xlab("Nota Média em Matemática") + ylab("Despesa por Aluno")
A visualização dos grupos melhorou, mostrando mais diferenças entre eles. O cluster 1 (vermelho), continua possuindo a maior quantidade de notas em matemática acima de \(690\). É perceptível a grande quantidade de pontos no cluster 4 (rosa), com poucos indicando nota em matemática acima \(675\), e tendo a menor despesa por aluno em relação aos outros grupos. Os grupos em azul e verde possuem muita similaridade em relação a nota em matemática, e possuem despesa por aluno entre 5 e 6 mil.
agrup <- hclust(dist(math.exp, method = 'euclidean'), method = 'ward.D')
classes <- cutree(agrup, k = 5)
math.exp$cluster <- classes
ggplot() + geom_point(aes(x = math, y = expenditure, color = cluster), data = math.exp,
size = 2) +
ggtitle("Agrupamento Hierárquico: Clusters com k = 5") +
scale_colour_gradientn(colours=rainbow(5)) +
xlab("Nota Média em Matemática") + ylab("Despesa por Aluno")
Neste gráfico a visualização dos grupos ficou mais detalhada. O cluster 4 (azul), que apresenta a menor despesa por aluno, com a maior parte dos dados entre \(4000\) e \(4500\), possui quase todos os pontos com nota em matemática abaixo de \(675\).
O cluster 5 (rosa) apresenta poucas notas acima de \(675\) e apenas uma acima de \(690\), com a despesa por aluno se destacando a partir de \(4500\) até em torno de \(5000\).
O cluster 2 (amarelo), com despesa entre \(5000\) e \(5500\), apresenta as notas em matemática semelhantes ao grupo situado abaixo dele (cluster 5).
O cluster 3 (verde) possui menor quantidade de pontos em relação aos grupos abaixo dele, com despesa predominante entre \(5500\) e \(6000\), e mostra uma nota em matemática acima de \(705\).
Por fim, o cluster 1 (vermelho), grupo com maior variabilidade em y, apresentando despesas concentradas entre \(6000\) até abaixo de \(8000\). É o grupo que possui mais notas acima de \(690\), e uma nota acima de \(705\), como o cluster 3.
cotovelo <- vector()
for(i in 1:15){cotovelo[i] <- sum(kmeans(math.exp, i)$withinss)}
ggplot() + geom_point(aes(x = 1:15, y = cotovelo), color = 'lightblue4', size = 2) +
geom_line(aes(x = 1:15, y = cotovelo), color = 'red4') +
ggtitle("Método do Cotovelo") +
xlab("Número de Centróides") +
ylab("Within Clusters Summed Squares")
Observando o gráfico, a partir do ponto 4 o declínio não está mais tão acentuado, e no ponto 6 já está quase em linha reta. Sendo assim, utilizarei k=6 e k=8.
agrup <- hclust(dist(math.exp, method = 'euclidean'), method = 'ward.D')
classes <- cutree(agrup, k = 6)
math.exp$cluster <- classes
ggplot() + geom_point(aes(x = math, y = expenditure, color = cluster), data = math.exp,
size = 2) +
ggtitle("Agrupamento K-Means: Clusters com k = 6") +
scale_colour_gradientn(colours=rainbow(6)) +
xlab("Nota Média em Matemática") + ylab("Despesa por Aluno")
Analisando os grupos em ordem crescente de y, é possível ver a semelhança em relação aos resultados anteriores, para k=5. O destaque do gráfico de k=6 é no grupo situado no topo de y, o cluster 4(ciano). Nesse grupo, os dados não aparecem nos primeiros valores de x, sendo o único grupo que não possui notas abaixo \(x=630\), e tem apenas uma nota em matemática abaixo de \(645\).
agrup <- hclust(dist(math.exp, method = 'euclidean'), method = 'ward.D')
classes <- cutree(agrup, k = 8)
math.exp$cluster <- classes
ggplot() + geom_point(aes(x = math, y = expenditure, color = cluster), data = math.exp,
size = 2) +
ggtitle("Agrupamento K-Means: Clusters com k = 8") +
scale_colour_gradientn(colours=rainbow(6)) +
xlab("Nota Média em Matemática") + ylab("Despesa por Aluno")
No gráfico de k=6 alguns grupos já estavam com poucos dados em relação aos outros, então parece ser necessário encerrar o aumento da divisão dos clusters.
Com a visualização do agrupamento com k=8, é possível ver que os grupos centrais, que possuíam maior concentração de dados, apenas se subdividiram, não mudando significativamente a análise anterior.
Através das análises realizadas, é possível afirmar que o desempenho em matemática e leitura é similar, ou seja, as escolas que apresentaram média alta em matemática, também possuem média alta em leitura.
Também foi possível observar que há uma correlação moderada negativa entre math e english. Então, quanto maior for a média em matemática, menor será a porcentagem de alunos de inglês. O que pode indicar que alunos de outros países que não dominam o inglês, por exemplo, tem maior dificuldade para obter um bom desempenho em matemática e em leitura.
Analisando as variáveis math e lunch, que representam a nota em matemática e a porcentagem de qualificação para almoço a preço reduzido, foi visto que há uma correlação negativa forte. Isto quer dizer que, as escolas com menor resultado em lunch, possuem média alta em matemática. Tal resultado pode ser explicado pelo fato das escolas com maiores notas geralmente estarem localizadas em áreas consideradas privilegiadas, em que os habitantes da região possuem melhor situação socioeconômica. Então, as chances dos alunos se inscreverem em programas assistenciais, como o lanche a preço reduzido, é menor. Além disso, em muitos casos, as escolas situadas nessas regiões oferecem mais recursos educacionais, o que incentiva o aprendizado dos alunos, contribuindo para que eles tenham um melhor desempenho.
Por fim, fazendo a Análise de Cluster para os dados de math e expenditure, através da visualização dos grupos formados, foi possível fazer algumas interpretações.
Nos clusters com menor despesa por aluno, a nota em matemática atingia os valores mais baixos, e mostrava a maior parte dos pontos situados em torno da média geral de math. Enquanto o cluster situado no maior nível de expenditure, mostrou grande parte das notas acima da média geral, com destaque nas notas mais alevadas.
Apesar da visível baixa correlação das variáveis, através da análise dos clusters foi possível ver que as escolas com maior despesa por aluno têm menos chance de obter notas baixas em matemática, e que as escolas com menor despesa por aluno dificilmente terão uma média alta em matemática.