A formação de clusters ou agrupamentos são importantes métodos de data mining para aprendizado não supervisionado, que podem proporcionar amplo conhecimento “oculto” acerca dos dados em análise. Entre suas diversas possíveis aplicações, a análise de process mining (mineração de dados para processos) vem se tornando latente e cada vez mais importante para as industrias, visto os avanços científicos-tecnológicos como a Indústria 4.0.
No presente trabalho realizei agrupamento dos dados de pluviometria operação de um sistema de contenção de efluentes industriais. Este último é um processo industrial em uma refinaria de petróleo, e é muito importante no âmbito ambiental, pois o extravasamento das bacias de contenção podem ocasionar impacto ambiental negativo ao ambiente.
Este trabalho é um resultado parcial do meu mestrado, intitulado como “Mineração de dados para predição de falhas em sistemas de coleta de efluentes”, desenvolvido no Programa de Pós-Graduação em Engenharia Industrial - PEI/UFBA.
Para aplicação da técnica de agrupamento foi necessário embasamento no estado da arte a partir do artigo de Yu et al. (2013), onde foi analisado o sistema de drenagem d cidade de Tóquio, Japão. No artigo foi desenvolvido uma métrica de Índice de Similaridade, que é calculada a partir das informações contidas nos agrupamentos.
Neste “tutorial” apenas mostrarei como é possível realizar a tarefa de agrupamento de dados no R e escolher o melhor algoritmo e melhor número de grupos (clusters) a partir de resultados numéricos (análise numérica). Para tal utilizarei o pacote clValid.
Os agrupamentos foram gerados baseados no cálculo de dissimilaridade da Distância Euclideana entre objetos, e com emprego de diferentes algoritmos, hierárquico com método de Ward, K-means e PAM (Partitioning Around Medoids) com o objetivo de escolher o melhor método de agrupamento. O número de grupos foi determinado através de análise numérica da qualidade e estabilidade dos agrupamentos.
A qualidade interna dos agrupamentos foi verificada através de três medidas: Índice Dunn, Conectividade e Silhueta. Para a análise da estabilidade dos agrupamentos empregou-se as técnicas de proporção média de observações não classificadas no mesmo cluster (average porportion of nonoverlap - APN), distância média entre objetos em um mesmo cluster (average distance - AD), distância média entre os centroides quando as observações estão no mesmo cluster (average distance between means - ADM) e figura de mérito (figure of merit - FOM).
Uma informação adicional, com o pacote NbClust também seria possível realizar quase totalmente este “exercício”.
Para o presente problema os dados são basicamente diferenciados em função da ocorrência e característica das chuvas (pluviometria) e operação das bacias de contenção.
Baseado nos atributos escolhidos e avaliados no estudo desenvolvido por Yu et al., (2013), no fenômeno chuva-vazão e nos dados e informações disponíveis, quatro atributos para agrupamento do comportamento relacionado com a ocorrência e frequência condicional (se-então) de chuvas foram escolhidos, sendo: Volume acumulado de chuva do dia anterior (Vci-1 [mm/dia]); Volume acumulado de chuva de um dia (Vci [mm/dia]); Volume acumulado se ocorrido dois dias consecutivos chuva (Vci + Vci-1) [mm]; e Volume acumulado se ocorridos três dias consecutivos de chuva (Vci + Vci-1 + Vci-2) [mm].
Caso não satisfeita a condição inicial dos volumes de chuva condicional, foi considerado o volume zero como resposta.
Quanto ao comportamento dos extravasamentos nas bacias, quatro atributos foram considerados para o conjunto, sendo que estes parâmetros representam o sistema como um todo, pois a ocorrência de extravasamento não acontece em todas as bacias e também existe variabilidade na quantidade de bacias com extravasamento. Os atributos para o fenômeno extravasamento são análogos ao de sistema de drenagem urbana, sendo: Volume total de extravasamento por dia [m³/dia]; Número de bacias transbordando por evento; Tempo médio de transbordamento por dia [min/dia]; e Tempo médio diário de operação das bombas [min/dia].
O atributo relacionado à operação das bombas foi considerado em função da relevância e modelo de operação mecanizada das bacias, bem como o manejo dos efluentes na planta industrial. O volume total de extravasamento foi obtido pela soma do volume de extravasamento de cada bacia em cada dia.
Como para os dois conjuntos de dados a abordagem é a mesma, no presente tutorial constará apenas a análise para os dados de pluviometria para reduzir a redundância.
O código para desenvolvimento da metodologia no R será apresentado neste momento apenas para os dados de pluviometria. Entretanto para qualquer outra réplica é possível utilizar a mesma metodologia e pacotes empregados.
Carregando pacotes de dataset.
if (!require("pacman")) install.packages("pacman")
pacman::p_load(ggplot2, clValid, lemon, dplyr, tidyr, tibble, reshape2)
# Dataset Chuva
chuva_analise2011_jan_set <- read.csv("D:/PEI/Mestrado/Time series/R/DADOS/MH/chuva_analise2011_jan_set.txt",
sep = ";", stringsAsFactors = FALSE)
head(chuva_analise2011_jan_set, 5)
## Data Quan_chu Chuva Ind_chu
## 1 2011-01-01 11:59:30 0 Não 0
## 2 2011-01-02 11:59:30 0 Não 0
## 3 2011-01-03 11:59:30 0 Não 0
## 4 2011-01-04 11:59:30 0 Não 0
## 5 2011-01-05 11:59:30 0 Não 0
Para pré-processament, desenvolvimento de atributos e organização do banco de dados é necessário a manipulação dos dados, como no chunk abaixo.
Dia.Anterior <- chuva_analise2011_jan_set %>%
dplyr::select(Data, Quan_chu) %>%
dplyr::mutate(Ocorr01Ant = ifelse(Quan_chu > 0 & dplyr::lag(Quan_chu) > 0, 1, 0),
Vol02Dias = ifelse(Quan_chu > 0 & Ocorr01Ant > 0, Quan_chu + dplyr::lag(Quan_chu), 0),
Ocorr02Ant = ifelse(Ocorr01Ant > 0 & dplyr::lag(Quan_chu, 2L) > 0, 1, 0),
Vol03Dias = ifelse(Ocorr01Ant > 0 & Ocorr02Ant > 0,
Quan_chu + dplyr::lag(Quan_chu, 1L) + dplyr::lag(Quan_chu, 2L), 0),
Anterior = ifelse(dplyr::lag(Quan_chu) > 0,
dplyr::lag(Quan_chu), 0)) %>%
tidyr::fill(Anterior, .direction = 'up')
Chuva2 <- Chuva <- Dia.Anterior %>%
dplyr::rename("Vol01Dia" = Quan_chu) %>%
dplyr::select(-Data, -Ocorr01Ant, -Ocorr02Ant)
head(Chuva2, 5)
## Vol01Dia Vol02Dias Vol03Dias Anterior
## 1 0 0 0 0
## 2 0 0 0 0
## 3 0 0 0 0
## 4 0 0 0 0
## 5 0 0 0 0
Chuva.Cluster2 <- Chuva2 %>%
na.omit() %>%
base::scale()
head(Chuva.Cluster2, 5)
## Vol01Dia Vol02Dias Vol03Dias Anterior
## 1 -0.4588538 -0.4691842 -0.443378 -0.4588538
## 2 -0.4588538 -0.4691842 -0.443378 -0.4588538
## 3 -0.4588538 -0.4691842 -0.443378 -0.4588538
## 4 -0.4588538 -0.4691842 -0.443378 -0.4588538
## 5 -0.4588538 -0.4691842 -0.443378 -0.4588538
Para a estimativa do número de clusters, será testado a quantidade de 2 à 10 grupos.
No primeiro momento será realizado a validação interna. No segundo momento a verificação de estabilidade.
cmin <- 2
cmax <- 10
algoritmos <- c("hierarchical","kmeans","pam")
intern <- clValid::clValid(Chuva.Cluster2, cmin:cmax,
clMethods = algoritmos, validation = "internal")
summary(intern)
##
## Clustering Methods:
## hierarchical kmeans pam
##
## Cluster sizes:
## 2 3 4 5 6 7 8 9 10
##
## Validation Measures:
## 2 3 4 5 6 7 8 9 10
##
## hierarchical Connectivity 8.7698 8.9948 11.8238 14.7528 17.0028 18.5028 32.3841 34.3841 35.4492
## Dunn 0.4388 0.4388 0.4439 0.5463 0.5463 0.5463 0.1486 0.1486 0.1620
## Silhouette 0.8298 0.8168 0.7760 0.7426 0.7391 0.7366 0.6946 0.6930 0.6858
## kmeans Connectivity 17.2448 27.2980 36.8667 42.1012 68.5159 68.8492 45.4246 48.8579 61.5349
## Dunn 0.0830 0.0724 0.0254 0.0400 0.0201 0.0250 0.0618 0.0769 0.0314
## Silhouette 0.7617 0.7065 0.6466 0.6007 0.5137 0.5145 0.6175 0.6246 0.5663
## pam Connectivity 18.8984 48.5659 56.2361 69.8500 70.5698 80.6885 82.5210 79.9857 79.5194
## Dunn 0.0208 0.0074 0.0077 0.0097 0.0096 0.0097 0.0109 0.0109 0.0133
## Silhouette 0.6369 0.4721 0.4854 0.4926 0.5047 0.5258 0.5262 0.5526 0.5525
##
## Optimal Scores:
##
## Score Method Clusters
## Connectivity 8.7698 hierarchical 2
## Dunn 0.5463 hierarchical 5
## Silhouette 0.8298 hierarchical 2
Observe que se desejado realizar uma análise fria, a função summary retorna na parte inferior o algoritmo e o número ótimo de grupos para as diferentes métricas analisadas. É notório que o algoritmo hierárquico apresenta as melhores formações de grupos. O número de grupos escolhidos pode ser o de 02.
O pacote clValid também proporciona análise visual através de gráficos. Contudo são utilizados gráficos do pacote residente no R.
op <- par(no.readonly = TRUE)
par(mfrow = c(2, 2), mar = c(4, 4, 3, 1))
plot(intern, legend = FALSE)
plot(nClusters(intern), measures(intern, "Dunn")[, , 1], type = "n",
axes = F, xlab = "", ylab = "")
legend("center", clusterMethods(intern), col = 1:3, lty = 1:3,
pch = paste(1:3)) ; par(op)
Contudo, com uma breve manipulação de dados a partir do objeto gerado através do clValid é possível realizar o gráfico utilizando o pacote ggplot2.
Os gráficos construídos contarão com tema modificado (opt0L).
opt0L <- theme_bw() +
theme(axis.title = element_text(face = "bold", color = "black", size = 26),
axis.text.x = element_text(face = "bold", color = "black",
size = 18, angle = 90),
axis.text.y = element_text(face = "bold", color = "black", size = 22),
legend.text = element_text(size = 18, face = "bold"),
legend.title = element_text(size = 30, face = "bold"),
strip.text.x = element_text(size = 18, face = "bold"),
strip.text.y = element_text(size = 14, face = "bold"))
df_intern_chuva <- as.data.frame(intern@measures)
df_intern_chuva_hier <- df_intern_chuva %>%
dplyr::select(1:length(cmin:cmax)) %>% t %>%
as.data.frame() %>%
tibble::remove_rownames() %>%
dplyr::mutate(Clusters = 2:10) %>%
dplyr::rename("Conectividade" = Connectivity,
"Silhueta" = Silhouette) %>%
reshape2::melt(id.vars = "Clusters")
head(df_intern_chuva_hier)
## Clusters variable value
## 1 2 Conectividade 8.769841
## 2 3 Conectividade 8.994841
## 3 4 Conectividade 11.823810
## 4 5 Conectividade 14.752778
## 5 6 Conectividade 17.002778
## 6 7 Conectividade 18.502778
clus_chu_val_int_hier <- ggplot2::ggplot(df_intern_chuva_hier) +
lemon::geom_pointline(aes(x = Clusters, y = value,
col = variable, shape = variable),
size = 3, show.legend = F) +
facet_wrap(~variable, scales = "free") +
xlab("Número de Clusters - Agrupamento Hierárquico") + ylab("Valor") +
opt0L + theme(axis.text.x = element_text(angle = 0))
clus_chu_val_int_hier
df_intern_chuva_kmeans <- df_intern_chuva %>%
dplyr::select((length(cmin:cmax) + 1):(length(cmin:cmax)*2)) %>% t %>%
as.data.frame() %>%
tibble::remove_rownames() %>%
dplyr::mutate(Clusters = 2:10) %>%
dplyr::rename("Conectividade" = Connectivity,
"Silhueta" = Silhouette) %>%
reshape2::melt(id.vars = "Clusters")
clus_chu_val_int_kmeans <- ggplot2::ggplot(df_intern_chuva_kmeans) +
lemon::geom_pointline(aes(x = Clusters, y = value,
col = variable, shape = variable),
size = 3, show.legend = F) +
facet_wrap(~variable, scales = "free") +
xlab("Número de Clusters - Kmeans") + ylab("Valor") +
opt0L + theme(axis.text.x = element_text(angle = 0))
clus_chu_val_int_kmeans
df_intern_chuva_pam <- df_intern_chuva %>%
dplyr::select((2*(length(cmin:cmax)) + 1):(length(cmin:cmax)*3)) %>% t %>%
as.data.frame() %>%
tibble::remove_rownames() %>%
dplyr::mutate(Clusters = 2:10) %>%
dplyr::rename("Conectividade" = Connectivity,
"Silhueta" = Silhouette) %>%
reshape2::melt(id.vars = "Clusters")
clus_chu_val_int_pam <- ggplot2::ggplot(df_intern_chuva_pam) +
lemon::geom_pointline(aes(x = Clusters, y = value,
col = variable, shape = variable),
size = 3, show.legend = F) +
facet_wrap(~variable, scales = "free") +
xlab("Número de Clusters - PAM") + ylab("Valor") +
opt0L + theme(axis.text.x = element_text(angle = 0))
clus_chu_val_int_pam
clus_chu_val_int <- cowplot::plot_grid(clus_chu_val_int_hier,
clus_chu_val_int_kmeans,
clus_chu_val_int_pam,
ncol = 1, align = 'hv')
clus_chu_val_int
Apesar da boa qualidade de imagem, é necessário colocar os gráficos em uma escala onde seja possível empregar a análise visual.
df_intern <- df_intern_chuva_hier %>%
dplyr::mutate(variable_h = variable,
variable_h1 = paste(variable,"Ward", sep = "-"),
value_h = value) %>%
dplyr::select(-value) %>%
dplyr::mutate(variable_p1 = paste(df_intern_chuva_pam$variable,"PAM", sep = "-"),
value_p = df_intern_chuva_pam$value,
variable_k1 = paste(df_intern_chuva_kmeans$variable,"kmeans", sep = "-"),
value_k = df_intern_chuva_kmeans$value)
df_teste <- data.frame(Clusters = df_intern$Clusters, variable = df_intern$variable,
Algoritmo = df_intern$variable_h1, Valor = df_intern$value_h)
df_teste <- rbind(df_teste,
data.frame(Clusters = df_intern$Clusters, variable = df_intern$variable,
Algoritmo = df_intern$variable_k1, Valor = df_intern$value_k),
data.frame(Clusters = df_intern$Clusters, variable = df_intern$variable,
Algoritmo = df_intern$variable_p1, Valor = df_intern$value_p))
df_teste <- df_teste %>%
dplyr::mutate(metodo = c(rep("Ward", 27),
rep("k-means", 27),
rep("PAM", 27)))
head(df_teste)
## Clusters variable Algoritmo Valor metodo
## 1 2 Conectividade Conectividade-Ward 8.769841 Ward
## 2 3 Conectividade Conectividade-Ward 8.994841 Ward
## 3 4 Conectividade Conectividade-Ward 11.823810 Ward
## 4 5 Conectividade Conectividade-Ward 14.752778 Ward
## 5 6 Conectividade Conectividade-Ward 17.002778 Ward
## 6 7 Conectividade Conectividade-Ward 18.502778 Ward
plot_valid_chuv <- ggplot2::ggplot(df_teste) +
lemon::geom_pointline(aes(x = Clusters, y = Valor,
col = variable, shape = variable),
show.legend = F) +
facet_grid(variable~metodo, scales = "free") +
opt0L + theme(axis.text.x = element_text(angle = 0))
plot_valid_chuv
Fica nítido também que pacotes como o cowplot não devem ser empregados para confecção de facets simples. O próprio ggplot2 já proporciona uma boa função (facet_grid) e com excelente estética.
Quanto a estabilidade, perceba que é necessário a modificação apenas no argumento validation da função clValid.
estabilidade <- clValid::clValid(Chuva.Cluster2, cmin:cmax,
clMethods = algoritmos,
validation = "stability")
summary(estabilidade)
##
## Clustering Methods:
## hierarchical kmeans pam
##
## Cluster sizes:
## 2 3 4 5 6 7 8 9 10
##
## Validation Measures:
## 2 3 4 5 6 7 8 9 10
##
## hierarchical APN 0.0089 0.0087 0.0068 0.0055 0.0331 0.0725 0.0353 0.0536 0.0479
## AD 1.6015 1.5085 1.4652 1.4324 1.4069 1.3838 1.1712 1.1566 1.1156
## ADM 0.1369 0.0805 0.0810 0.0753 0.1690 0.3054 0.1801 0.2105 0.1814
## FOM 0.8746 0.8276 0.8061 0.8018 0.7534 0.6753 0.6398 0.6280 0.6175
## kmeans APN 0.0318 0.0947 0.0736 0.1465 0.1518 0.1677 0.2011 0.1665 0.1288
## AD 1.4083 1.3650 1.1587 1.1571 1.1149 1.0921 1.0967 1.0475 0.9517
## ADM 0.1730 0.4157 0.2284 0.4416 0.5763 0.5836 0.4570 0.3921 0.3423
## FOM 0.7912 0.7983 0.7047 0.7224 0.7034 0.6980 0.6813 0.6452 0.6124
## pam APN 0.0556 0.1052 0.2089 0.2432 0.2110 0.2207 0.2111 0.2254 0.2542
## AD 1.3403 1.1435 1.1333 1.0860 1.0059 0.9358 0.8878 0.8446 0.8120
## ADM 0.1701 0.2186 0.4716 0.5240 0.4690 0.4358 0.4465 0.4344 0.4238
## FOM 0.8340 0.7594 0.7745 0.7696 0.7451 0.6911 0.6771 0.6425 0.6323
##
## Optimal Scores:
##
## Score Method Clusters
## APN 0.0055 hierarchical 5
## AD 0.8120 pam 10
## ADM 0.0753 hierarchical 5
## FOM 0.6124 kmeans 10
O resultado e análise são muito próximos do realizado para validação interna. Perceba que a função summary proporciona, novamente, um resultado objetivo.
Como visto anteriormente é possível transformar a tabela de informações finais em gráficos. Para isto é necessário a manipulação de dados do objeto criado a partir da função clValid.
df_estabilidade_chuva <- as.data.frame(estabilidade@measures)
df_estabilidade_chuva_hier <- df_estabilidade_chuva %>%
dplyr::select(1:length(cmin:cmax)) %>% t %>%
as.data.frame() %>%
tibble::remove_rownames() %>%
dplyr::mutate(Clusters = 2:10) %>%
reshape2::melt(id.vars = "Clusters")
clus_chu_val_estab_hier <- ggplot2::ggplot(df_estabilidade_chuva_hier) +
lemon::geom_pointline(aes(x = Clusters, y = value,
col = variable, shape = variable),
size = 3, show.legend = F) +
facet_wrap(~variable, scales = "free") +
xlab("Número de Clusters - Agrupamento Hierárquico") + ylab("Valor") +
opt0L + theme(axis.text.x = element_text(angle = 0),
axis.title.x = element_text(size = 16,
face = "bold"))
clus_chu_val_estab_hier
df_estabilidade_chuva_kmeans <- df_estabilidade_chuva %>%
dplyr::select((length(cmin:cmax) + 1):(length(cmin:cmax)*2)) %>% t %>%
as.data.frame() %>%
tibble::remove_rownames() %>%
dplyr::mutate(Clusters = 2:10) %>%
reshape2::melt(id.vars = "Clusters")
clus_chu_val_estab_kmeans <- ggplot2::ggplot(df_estabilidade_chuva_kmeans) +
lemon::geom_pointline(aes(x = Clusters, y = value,
col = variable, shape = variable),
size = 3, show.legend = F) +
facet_wrap(~variable, scales = "free") +
xlab("Número de Clusters - Kmeans") + ylab("Valor") +
opt0L + theme(axis.text.x = element_text(angle = 0),
axis.title.x = element_text(size = 16,
face = "bold"))
clus_chu_val_estab_kmeans
df_estabilidade_chuva_pam <- df_estabilidade_chuva %>%
dplyr::select((2*(length(cmin:cmax)) + 1):(length(cmin:cmax)*3)) %>% t %>%
as.data.frame() %>%
tibble::remove_rownames() %>%
dplyr::mutate(Clusters = 2:10) %>%
reshape2::melt(id.vars = "Clusters")
clus_chu_val_estab_pam <- ggplot2::ggplot(df_estabilidade_chuva_pam) +
lemon::geom_pointline(aes(x = Clusters, y = value,
col = variable, shape = variable),
size = 3, show.legend = F) +
facet_wrap(~variable, scales = "free") +
xlab("Número de Clusters - PAM") + ylab("Valor") +
opt0L + theme(axis.text.x = element_text(angle = 0),
axis.title.x = element_text(size = 16,
face = "bold"))
clus_chu_val_estab_pam
clus_chu_val_estab <- cowplot::plot_grid(clus_chu_val_estab_hier,
clus_chu_val_estab_kmeans,
clus_chu_val_estab_pam,
NULL,
ncol = 2, align = 'hv')
clus_chu_val_estab
Percebe-se novamente que o cowplot não é elementar para produção de gráficos com essa simplicidade e que é necessário realizar novo gráfico objetivado em ajustar a escala e proporcionar a visualização adequada para análise.
Vale a pena ressaltar que n manipulações distintas poderiam ser feitas para a confecção deste plot.
df_est <- df_estabilidade_chuva_hier %>%
dplyr::mutate(variable_h = variable,
variable_h1 = paste(variable,"Ward", sep = "-"),
value_h = value) %>%
dplyr::select(-value) %>%
dplyr::mutate(variable_p1 = paste(df_estabilidade_chuva_pam$variable,"PAM", sep = "-"),
value_p = df_estabilidade_chuva_pam$value,
variable_k1 = paste(df_estabilidade_chuva_kmeans$variable,"kmeans", sep = "-"),
value_k = df_estabilidade_chuva_kmeans$value)
df_teste <- data.frame(Clusters = df_est$Clusters, variable = df_est$variable,
Algoritmo = df_est$variable_h1, Valor = df_est$value_h)
df_teste <- rbind(df_teste,
data.frame(Clusters = df_est$Clusters, variable = df_est$variable,
Algoritmo = df_est$variable_k1, Valor = df_est$value_k),
data.frame(Clusters = df_est$Clusters, variable = df_est$variable,
Algoritmo = df_est$variable_p1, Valor = df_est$value_p))
df_teste <- df_teste %>%
dplyr::mutate(metodo = c(rep("Ward", nrow(df_estabilidade_chuva_hier)),
rep("k-means", nrow(df_estabilidade_chuva_kmeans)),
rep("PAM", nrow(df_estabilidade_chuva_pam))))
plot_estb_chuv <- ggplot2::ggplot(df_teste) +
lemon::geom_pointline(aes(x = Clusters, y = Valor,
col = variable, shape = variable),
size = 2, linesize = 20, show.legend = F) +
facet_grid(variable~metodo, scales = "free") +
scale_y_continuous(breaks = scales::pretty_breaks(n = 3)) +
opt0L + theme(axis.text.x = element_text(angle = 0))
plot_estb_chuv
Na análise de agrupamento para os dados de chuva os resultados da análise de validação interna indicam que o agrupamento hierárquico com método de Ward foi o melhor nos três critérios. Para a métrica de conectividade e silhueta, dois clusters foram indicados, já para o índice Dunn, cinco clusters foram indicados.
Em relação à estabilidade dos agrupamentos, as estatísticas apresentadas não há uniformidade do número de clusters e melhor algoritmo, porém dos quatro resultados, o método hierárquico apresenta melhor resultado para proporção média de observações não classificadas no mesmo cluster (APN) e distância média entre os centroides quando as observações estão no mesmo cluster (ADM), embora o número de clusters seja de cinco.
Como conteúdo extra, disponibilizo também a criação do dendrograma considerando o método escolhido a partir das análises de validação interna e estabilidade.
Chuva.Dend2 <- Chuva.Cluster2 %>%
stats::dist(method = "euclidean") %>%
stats::hclust(method = "ward.D")
dend_ch <- factoextra::fviz_dend(Chuva.Dend2, k = 2, cex = 0,
k_colors = c("black", "black"),
main = "Dendrograma - Chuva",
ylab = "Distâncias", sub = "",
xlab = "Objetos",
lwd = 1) +
# geom_hline(yintercept = 80, linetype = 2, size = 1) +
scale_x_continuous(expand = c(0, 0)) +
scale_y_continuous(expand = c(0, 0)) +
opt0L +
theme(axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
plot.title = element_text(hjust = 0.5, size = 30, face = "bold"),
panel.border = element_blank(),
panel.background = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank())
dend_ch
dend_ch2 <- factoextra::fviz_dend(Chuva.Dend2, k = 2, cex = 0,
k_colors = c("darkblue", "darkgreen"),
main = "Dendrograma - Chuva",
ylab = "Distâncias", sub = "",
xlab = "Objetos",
lwd = 1) +
geom_hline(yintercept = 80, linetype = 2, size = 1) +
scale_x_continuous(expand = c(0, 0)) +
scale_y_continuous(expand = c(0, 0)) +
opt0L +
theme(axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
plot.title = element_text(hjust = 0.5, size = 30, face = "bold"),
panel.border = element_blank(),
panel.background = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank())
dend_ch2
Autor:
Brenner Silva.
Contato