Relatório de Análise Multivariada
Análise de Agrupamentos
Introdução
Análise de Cluster é uma técnica multivariada cuja finalidade é agregar objetos com base nas características que eles possuem. O resultado são grupos que exibem máxima homogeneidade de objetos dentro de grupos e, ao mesmo tempo, máxima heterogeneidade entre os grupos. A maioria dos métodos de análise de cluster requer uma medida de similaridade entre os elementos a serem agrupados, normalmente expressa como uma função distância ou métrica.
Análise Exploratória
knitr::kable(apply(wine[,-1], 2, summary))| V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 | V11 | V12 | V13 | V14 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Min. | 11.03000 | 0.740000 | 1.360000 | 10.60000 | 70.00000 | 0.980000 | 0.34000 | 0.1300000 | 0.410000 | 1.28000 | 0.4800000 | 1.270000 | 278.0000 |
| 1st Qu. | 12.36250 | 1.602500 | 2.210000 | 17.20000 | 88.00000 | 1.742500 | 1.20500 | 0.2700000 | 1.250000 | 3.22000 | 0.7825000 | 1.937500 | 500.5000 |
| Median | 13.05000 | 1.865000 | 2.360000 | 19.50000 | 98.00000 | 2.355000 | 2.13500 | 0.3400000 | 1.555000 | 4.69000 | 0.9650000 | 2.780000 | 673.5000 |
| Mean | 13.00062 | 2.336348 | 2.366517 | 19.49494 | 99.74157 | 2.295112 | 2.02927 | 0.3618539 | 1.590899 | 5.05809 | 0.9574494 | 2.611685 | 746.8933 |
| 3rd Qu. | 13.67750 | 3.082500 | 2.557500 | 21.50000 | 107.00000 | 2.800000 | 2.87500 | 0.4375000 | 1.950000 | 6.20000 | 1.1200000 | 3.170000 | 985.0000 |
| Max. | 14.83000 | 5.800000 | 3.230000 | 30.00000 | 162.00000 | 3.880000 | 5.08000 | 0.6600000 | 3.580000 | 13.00000 | 1.7100000 | 4.000000 | 1680.0000 |
BoxPlot Comparativo
Dados Originais
#BoxPlot
plot_ly(y = wine$V2, name = "var 2", type = "box") %>%
add_trace(y = wine$V3, name = "var 3")%>%
add_trace(y = wine$V4, name = "var 4")%>%
add_trace(y = wine$V5, name = "var 5")%>%
add_trace(y = wine$V6, name = "var 6")%>%
add_trace(y = wine$V7, name = "var 7")%>%
add_trace(y = wine$V8, name = "var 8")%>%
add_trace(y = wine$V9, name = "var 9")%>%
add_trace(y = wine$V10, name = "var 10")%>%
add_trace(y = wine$V11, name = "var 11")%>%
add_trace(y = wine$V12, name = "var 12")%>%
add_trace(y = wine$V13, name = "var 13")%>%
add_trace(y = wine$V14, name = "var 14")Dados Padronizados
WP <- scale(wine[,-1]) %>% data.frame()
plot_ly(y = WP$V2, name = "var 2", type = "box") %>%
add_trace(y = WP$V3, name = "var 3")%>%
add_trace(y = WP$V4, name = "var 4")%>%
add_trace(y = WP$V5, name = "var 5")%>%
add_trace(y = WP$V6, name = "var 6")%>%
add_trace(y = WP$V7, name = "var 7")%>%
add_trace(y = WP$V8, name = "var 8")%>%
add_trace(y = WP$V9, name = "var 9")%>%
add_trace(y = WP$V10, name = "var 10")%>%
add_trace(y = WP$V11, name = "var 11")%>%
add_trace(y = WP$V12, name = "var 12")%>%
add_trace(y = WP$V13, name = "var 13")%>%
add_trace(y = WP$V14, name = "var 14")Matriz de Distâncias
Distancia Euclidiana - Dados originais
A distância euclidiana entre dois elementos \(X = (X_1, X_2,..., X_p)\) e \(Y=(Y_1, Y_2,..., X_p)\) é definida por:
\[ d_{XY} = \sqrt{(x_1 - y_1)^2 + (x_2-y_2)^2 + ... +(x_p-y_p)^2)}\]
d = dist(wine, method = "euclidean") # matriz de distancias
m = as.matrix(d)
fviz_dist(d,
gradient = list(low = "#00AFBB", mid = "white", high = "#FC4E07"))Distancia Euclidiana - Dados padronizados
A distância euclidiana entre dois elementos \(X = (X_1, X_2,..., X_p)\) e \(Y=(Y_1, Y_2,..., X_p)\) é definida por:
\[ d_{XY} = \sqrt{(x_1 - y_1)^2 + (x_2-y_2)^2 + ... +(x_p-y_p)^2}\]
D = dist(WP) # matriz de distancias
m = as.matrix(D)
fviz_dist(D,
gradient = list(low = "#00AFBB", mid = "white", high = "#FC4E07"))Distancia Euclidiana ao Quadrado - Dados padronizados
A distância euclidiana ao quadrado entre dois elementos \(X = (X_1, X_2,..., X_p)\) e \(Y=(Y_1, Y_2,..., X_p)\) é definida por:
\[ d_{XY} = (x_1 - y_1)^2 + (x_2-y_2)^2 + ... +(x_p-y_p)^2\]
D = dist(WP)^2 # matriz de distancias
m = as.matrix(D)
fviz_dist(D,
gradient = list(low = "#00AFBB", mid = "white", high = "#FC4E07"))Distancia de Manhattan - Dados padronizados
A distância de manhattan entre dois elementos \(X = (X_1, X_2,..., X_p)\) e \(Y=(Y_1, Y_2,..., X_p)\) é definida por:
\[ d_{XY} = |x_1 - y_1| + |x_2-y_2| + ... +|x_p-y_p|\]
d_manhattan = dist(WP, method = "manhattan")
fviz_dist(d_manhattan,
gradient = list(low = "#00AFBB", mid = "white", high = "#FC4E07"))Distancia Minkowski - Dados padronizados
A distância de é a generalização da distância euclidiana entre dois elementos \(X = (X_1, X_2,..., X_p)\) e \(Y=(Y_1, Y_2,..., X_p)\) e é definida por:
\[ d_{XY} = (|x_1 - y_1|^r + |x_2-y_2|^r + ... +|x_p-y_p|^r)^\frac{1}{r}\]
d_minkwski = dist(WP, method = "minkowski")
fviz_dist(d_minkwski,
gradient = list(low = "#00AFBB", mid = "white", high = "#FC4E07"))Índice de Validação: Silhueta
Definida para cada objeto em análise \[s(i) = \frac{b(i)-a(i)}{max(a(i),b(i))}\]
onde
\(a(i)\) é distância média do i-ésimo objeto em relação a todos os objetos do mesmo grupo ;
\(b(i)\) é a distância média do i-ésimo objeto em relação a todos os objetos do grupo vizinho mais próximo a ele.
A silhueta média (\(SM\)) é a medida de qualidade efetivamente utilizada para avaliar a estrutura de agrupamento.
knitr::kable(cbind("SM" = c("0.71 - 1.00","0.51 - 0.70","0.26 - 0.50","< 0.25"),
"Interpretação" = c("Grupos produzidos pelo algoritmo possuem uma estrutura muito robusta
","Grupos possuem uma estrutura razoável
","Os grupos encontrados possuem uma estrutura fraca e pode ser artificial
","Nenhuma estrutura foi descoberta
")))| SM | Interpretação |
|---|---|
| 0.71 - 1.00 | Grupos produzidos pelo algoritmo possuem uma estrutura muito robusta |
| 0.51 - 0.70 | Grupos possuem uma estrutura razoável |
| 0.26 - 0.50 | Os grupos encontrados possuem uma estrutura fraca e pode ser artificial |
| < 0.25 | Nenhuma estrutura foi descoberta |
Algoritmos de Agrupamento
Por critério de comparação, consideramos a distância euclidiana ao quadrado em ambos os algoritmos apresentados.
Método Hierárquico Aglomerativo
Os métodos hierárquicos da análise de cluster tem como principal característica um algoritmo capaz de fornecer mais de um tipo de partição dos dados. Ele gera vários agrupamentos possíveis, onde um cluster pode ser mesclado a outro em determinado passo do algoritmo.
Esses métodos não exigem que já se tenha um número inicial de clusters e são considerados inflexíveis uma vez que não se pode trocar um elemento de grupo. Eles podem ser classificados em dois tipos: Aglomerativos e Divisivos.
Métodos Aglomerativos: nesse caso, todos os elementos começam separados e vão sendo agrupados em etapas, um a um, até que tenhamos um único cluster com todos os elementos. O número ideal de clusters é escolhido dentre todas as opções.
Métodos Divisivos: no método divisivo todos os elementos começam juntos em um único cluster, e vão sendo separados um a um, até que cada elemento seja seu próprio cluster. Assim como no método aglomerativo, escolhemos o número ótimo de clusters dentre todas as possíveis combinações.
As variáveis podem ser quantitativas, qualitativas ou uma distribuição de ambas. O critério de agregação é a diminuição da homogeneidade para o cluster que está sendo mesclado. A homogeneidade de um cluster é a soma da razão de correlação (para variáveis qualitativas) e da correlação quadrática (para variáveis quantitativas) entre as variáveis e o centro do cluster (centroide) que é o primeiro componente principal de PCA mix.
PCA mix é definido para uma distribuição de variáveis qualitativas e quantitativas e inclui análises de componentes principais comuns (PCA) e análise de correspondência múltipla (MCA) como casos especiais. Os valores em falta são substituídos por médias para variáveis quantitativas e por zeros na matriz de indicadores para a variável qualitativa.
Vamos separar o dataset em duas partes, qualitativa como “a” e quantitativa como “x” Vamos também ignorar o ID do cliente para efietos de clusterização, poiis queremos nesse momento entender o dataset e como ele se comporta. Avaliando para \(k = 2,3,...,M\), onde M é a raiz quadrada do número de objetos na base de dados. Este limite superior é utilizado na literatura para delimitar a análise.
k <- 2:floor(sqrt(nrow(wine)))
D <- dist(WP)^2
CL_H = hclust(D, method = "ward.D")Dendograma
Usa-se o dendograma para visualizar o processo de clusterização passo a passo, assim como analisar os níveis de distância dos clusters formados. Um bom ponto de decisão da clusterização final é onde os valores de distância mudam consideravelmente. Para a decisão do agrupamento final também devem ser avaliados se os clusters formados fazem sentido para o problema.
Avaliando o dendograma, há uma estrutura indicando 3 grupos neste conjunto de dados.
fviz_dend(CL_H, k = 3,# Cut in four groups
cex = 0.5, # label size
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
color_labels_by_k = TRUE, # color labels by groups
rect = TRUE # Add rectangle around groups
)Silhueta
Avaliando o resultado da silhueta média, também indicou 3 grupos como o melhor resultado.
# Silhueta
best_H <- sapply(k, function(k) mean(silhouette(cutree(CL_H, k = k), D)[,3]))
ggplot() + geom_line(aes(k, best_H), color = grey(0.5), size = 1.5) + geom_point(aes(k, best_H), color = grey(0.5), size = 2) + theme_minimal() +
geom_label_repel(aes(k, best_H, label = paste('k =',k),
color = k==k[which.max(best_H)]),
force = 0, nudge_y = -0.05,
size = 4,
arrow = arrow(length = unit(0.03, "npc"), type = "closed", ends = "first")) +
scale_y_continuous(limits = c(0,max(best_H)+0.05)) + labs(x = NULL, y = "Silhueta Média") + guides(color = FALSE) +
theme(panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
axis.title.y = element_text(size = 12)) +
scale_x_discrete(NULL)A silhueta para cada objeto apresentou alguns valores abaixo de zero, esta situação pode ser contornada realizando um ajuste de realocação. Função função disponível nos APÊNDICE I.
Silhueta
clust_H <- cutree(CL_H, k = 3)
sil <- silhouette(clust_H, D)
bar_sil(sil)Silhueta Ajustada
ajust_clust <- ajuste_sil(sil, D)
bar_sil(ajust_clust)Análise dos grupos
Visualmente considerando as duas dimensões com maior variância explicada, tempos:
Silhueta
dim_cluster(WP, clust_H, "Set1")Silhueta Ajustada
clust_H_ajuste <- ajust_clust[,1]
dim_cluster(WP, clust_H_ajuste, "Set1")Método Não-Hierárquico - K-means
Os métodos não-hierárquicos da análise de cluster são caracterizados pela necessidade de definir uma partição inicial e pela flexibilidade, uma vez que os elementos podem ser trocados de grupo durante a execução do algoritmo.
O procedimento geral adotado para os métodos não hierárquicos é: - Escolher uma partição inicial (baseada em conhecimentos anteriores do problema); - Realizar o deslocamento do objeto de seu grupo para outros grupos; - Verificar o valor do critério utilizado, decidindo pela clusterização que apresentar melhoria. Esse processo é repetido até que não se obtenha mais nenhuma melhoria com os deslocamentos.
Os métodos das k-médias e o Fuzzy c-Médias são alguns exemplos conhecidos desses métodos, que tem como vantagem a possibilidade de mover um elemento de um cluster para o outro, o que não é possível no método hierárquico.
Usualmente, os métodos não hierárquicos são mais eficientes na análise de bancos de dados com maior número de observações.
Silhueta
Avaliando o resultado da silhueta média, também indicou 3 grupos como o melhor resultado.
# Silhueta
best_K <- sapply(k, function(k) mean(silhouette(kmeans(WP, k, nstart = 30, iter.max = 30)$cluster, D)[,3]))
ggplot() + geom_line(aes(k, best_K), color = grey(0.5), size = 1.5) + geom_point(aes(k, best_K), color = grey(0.5), size = 2) + theme_minimal() +
geom_label_repel(aes(k, best_K, label = paste('k =',k),
color = k==k[which.max(best_K)]),
force = 0, nudge_y = -0.05,
size = 4,
arrow = arrow(length = unit(0.03, "npc"), type = "closed", ends = "first")) +
scale_y_continuous(limits = c(0,max(best_K)+0.05)) + labs(x = NULL, y = "Silhueta Média") + guides(color = FALSE) +
theme(panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
axis.title.y = element_text(size = 12)) +
scale_x_discrete(NULL)Silhueta para cada objeto
Silhueta
clust_K <- kmeans(WP, 3, nstart = 30, iter.max = 30)$cluster
sil <- silhouette(clust_K, D)
bar_sil(sil)Silhueta Ajustada
ajust_clust <- ajuste_sil(sil, D)
bar_sil(ajust_clust)Análise dos grupos
Visualmente considerando as duas dimensões com maior variância explicada, tempos:
Silhueta
dim_cluster(WP, clust_K, "Set1")Silhueta Ajustada
clust_K_ajuste <- ajust_clust[,1]
dim_cluster(WP, clust_H_ajuste, "Set1")APÊNDICE I
ajuste_sil <- function(sil, D, best = F, max.null = 100){
neg <- which(sil[,3]<0)
i = 0
while(length(neg) != 0 & i < max.null){
p <- sample(neg,1)
aux <- sil
aux[p,1] <- aux[p,2]
aux <- silhouette(aux[,1], D)
if (!best | (best & mean(aux[, 3]) > mean(sil[, 3]))) {
sil <- aux
# cat(mean(sil[, 3]), "; \n ")
i = 0
} else i = i + 1
neg <- which(sil[,3]<0)
}
return(sil)
}