Análise de Correpondência
VIVA - 2017

Caio VAOS

2025.1


Introdução

Análise de Correspondência é uma técnica para analisar dados categóricos disponíveis nas bases de dados.

Ela é empregada na análise exploratória de dados para simplificar estruturas complexas por meio da redução de dimensões, além de fornecer insights visuais sobre padrões nos dados.

A análise de correspondência pode ser de dois tipos:

  • Análise de correspondência simples (AC): Utiliza os dados agregados em uma tabela de contingência para identificar associações e padrões.

  • Análise de correspondência múltipla (ACM): Aplica-se a bases de dados com três ou mais variáveis categóricas.

Nesta análise, estudaremos algumas variáveis do VIVA Inquérito1 do ano de 2017, utilizando a Análise de Correspondência Simples (AC).


Preparando Bases

Aqui, trataremos de duas vertentes:

Análise e tratamento de valores ausentes (missings), garantindo que eles não causem viés na análise. De modo geral, é recomendável que as variáveis tenham, no máximo, 30% de valores ausentes.

Padronização da nomenclatura das categorias, tornando-as mais facilmente identificáveis durante a análise.

Missings

summary(df)
##    NUM_TURNO2         ESTRATO           peso            fet       
##  Min.   :   1.00   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:  16.25   1st Qu.:1.000   1st Qu.:1.000   1st Qu.:3.000  
##  Median :  33.00   Median :1.000   Median :1.893   Median :3.000  
##  Mean   : 159.34   Mean   :1.326   Mean   :2.627   Mean   :3.052  
##  3rd Qu.:  49.75   3rd Qu.:2.000   3rd Qu.:3.404   3rd Qu.:4.000  
##  Max.   :3376.00   Max.   :3.000   Max.   :9.486   Max.   :5.000  
##                                                    NA's   :16     
##    TP_TRANSP          SEXO         CORPO_4cat    HORA_OCOR_4cat    EVENTO_T    
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.00   Min.   :1.000  
##  1st Qu.:3.000   1st Qu.:1.000   1st Qu.:2.000   1st Qu.:1.00   1st Qu.:1.000  
##  Median :3.000   Median :1.000   Median :3.000   Median :2.00   Median :2.000  
##  Mean   :2.976   Mean   :1.283   Mean   :2.839   Mean   :2.37   Mean   :2.202  
##  3rd Qu.:3.000   3rd Qu.:2.000   3rd Qu.:4.000   3rd Qu.:3.00   3rd Qu.:2.000  
##  Max.   :6.000   Max.   :2.000   Max.   :4.000   Max.   :9.00   Max.   :9.000  
##  NA's   :77                      NA's   :494                                   
##     CELULAR     
##  Min.   :1.000  
##  1st Qu.:2.000  
##  Median :2.000  
##  Mean   :3.609  
##  3rd Qu.:2.000  
##  Max.   :9.000  
## 

Aqui, analisamos a quantidade de valores ausentes (NAs) em cada variável. No entanto, também precisamos considerar observações que, embora não sejam NA, devem ser ignoradas conforme as diretrizes da Ficha VIVA. Assim, recodificados os NAs como 9 e verificamos a frequência das categorias.

df <- mutate(df, across(c(TP_TRANSP, CORPO_4cat, fet), ~replace_na(.x, 9)))
freq(df$fet)
freq(df$TP_TRANSP)
freq(df$CORPO_4cat)
freq(df$CELULAR)
freq(df$EVENTO_T)
freq(df$HORA_OCOR_4cat)
## Frequencies  
## df$fet  
## Type: Numeric  
## 
##                Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ----------- ------- --------- -------------- --------- --------------
##           1     588      4.98           4.98      4.98           4.98
##           2    1765     14.96          19.94     14.96          19.94
##           3    6457     54.71          74.65     54.71          74.65
##           4    2404     20.37          95.02     20.37          95.02
##           5     572      4.85          99.86      4.85          99.86
##           9      16      0.14         100.00      0.14         100.00
##        <NA>       0                               0.00         100.00
##       Total   11802    100.00         100.00    100.00         100.00
## Frequencies  
## df$TP_TRANSP  
## Type: Numeric  
## 
##                Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ----------- ------- --------- -------------- --------- --------------
##           1    1002      8.49           8.49      8.49           8.49
##           2     966      8.19          16.68      8.19          16.68
##           3    7813     66.20          82.88     66.20          82.88
##           4    1398     11.85          94.72     11.85          94.72
##           5     349      2.96          97.68      2.96          97.68
##           6     197      1.67          99.35      1.67          99.35
##           9      77      0.65         100.00      0.65         100.00
##        <NA>       0                               0.00         100.00
##       Total   11802    100.00         100.00    100.00         100.00
## Frequencies  
## df$CORPO_4cat  
## Type: Numeric  
## 
##                Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ----------- ------- --------- -------------- --------- --------------
##           1    1685     14.28          14.28     14.28          14.28
##           2    2691     22.80          37.08     22.80          37.08
##           3    2690     22.79          59.87     22.79          59.87
##           4    4242     35.94          95.81     35.94          95.81
##           9     494      4.19         100.00      4.19         100.00
##        <NA>       0                               0.00         100.00
##       Total   11802    100.00         100.00    100.00         100.00
## Frequencies  
## df$CELULAR  
## Type: Numeric  
## 
##                Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ----------- ------- --------- -------------- --------- --------------
##           1     315      2.67           2.67      2.67           2.67
##           2    8729     73.96          76.63     73.96          76.63
##           9    2758     23.37         100.00     23.37         100.00
##        <NA>       0                               0.00         100.00
##       Total   11802    100.00         100.00    100.00         100.00
## Frequencies  
## df$EVENTO_T  
## Type: Numeric  
## 
##                Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ----------- ------- --------- -------------- --------- --------------
##           1    3232     27.39          27.39     27.39          27.39
##           2    7767     65.81          93.20     65.81          93.20
##           9     803      6.80         100.00      6.80         100.00
##        <NA>       0                               0.00         100.00
##       Total   11802    100.00         100.00    100.00         100.00
## Frequencies  
## df$HORA_OCOR_4cat  
## Type: Numeric  
## 
##                Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ----------- ------- --------- -------------- --------- --------------
##           1    3007     25.48          25.48     25.48          25.48
##           2    3917     33.19          58.67     33.19          58.67
##           3    3633     30.78          89.45     30.78          89.45
##           4     995      8.43          97.88      8.43          97.88
##           9     250      2.12         100.00      2.12         100.00
##        <NA>       0                               0.00         100.00
##       Total   11802    100.00         100.00    100.00         100.00

Nomenclatura

Para melhorar a interpretação gráfica, é feita a renomeação das categorias.

A mudança de números para texto facilita a compreensão, e o número que antecede cada label serve para identificar a variável à qual a categoria pertence.

Variável Categoria Nome
Tipo de Transporte Pedestre 1Ped
Automóvel 1Auto
Motocicleta 1Moto
Bicicleta 1Bike
Veículo Pesado 1VPes
Outro 1Outr
Ignorado 1Ign
Faixa etária 0 a 9 anos 0a9
10 a 19 anos 10a19
20 a 39 anos 20a39
40 a 59 anos 40a59
60 anos ou mais 60+
Sexo Masculino Masc
Feminino Fem
Parte do Corpo Atingida Cabeça 2Cab
Tronco 2Tro
Membro Superior 2MSup
Membro Inferior 2MInf
Horário da Ocorrência Manhã 3Man
Tarde 3Tar
Noite 3Noi
Madrugada 3Mad
Evento a caminho do trabalho Sim 4Trab
Uso de celular Sim 5Cel
df_ac <- df %>%
  mutate(TP_TRANSP_str = as.factor(case_when(TP_TRANSP == 1 ~ '1Ped',
                                   TP_TRANSP == 2 ~ '1Auto',
                                   TP_TRANSP == 3 ~ '1Moto',
                                   TP_TRANSP == 4 ~ '1Bike',
                                   TP_TRANSP == 5 ~'1VPes',
                                   TP_TRANSP == 6 ~'1Outr',
                                   TP_TRANSP == 9 ~'1Ign')),
         fet_str = as.factor(case_when(fet == 1 ~ '0a9', 
                             fet == 2 ~ '10a19',
                             fet == 3 ~ '20a39', 
                             fet == 4 ~ '40a59', 
                             fet == 5 ~ '60+')),
         sexo_str = as.factor(case_when(SEXO == 1 ~ 'Masc',
                              SEXO == 2 ~ 'Fem')),
         CORPO_str = as.factor(case_when(CORPO_4cat == 1 ~ '2Cab',
                               CORPO_4cat == 2 ~ '2Tro',
                               CORPO_4cat == 3 ~ '2MSup',
                               CORPO_4cat == 4 ~ '2MInf')),
         HORA_OCOR_str = as.factor(case_when(HORA_OCOR_4cat == 1 ~ '3Man',
                                   HORA_OCOR_4cat == 2 ~ '3Tar',
                                   HORA_OCOR_4cat == 3 ~ '3Noi',
                                   HORA_OCOR_4cat == 4 ~ '3Mad')),
         EVENTO_T_str= as.factor(case_when(EVENTO_T == 1 ~ '4Trab')),
         CELULAR_str = as.factor(case_when(CELULAR == 1 ~ '5Cel'))) |> 
  select(NUM_TURNO2,ESTRATO,peso,fet_str,TP_TRANSP_str,sexo_str,CORPO_str,HORA_OCOR_str,
         EVENTO_T_str,CELULAR_str)
summary(df_ac)
##    NUM_TURNO2         ESTRATO           peso        fet_str     TP_TRANSP_str
##  Min.   :   1.00   Min.   :1.000   Min.   :1.000   0a9  : 588   1Auto: 966   
##  1st Qu.:  16.25   1st Qu.:1.000   1st Qu.:1.000   10a19:1765   1Bike:1398   
##  Median :  33.00   Median :1.000   Median :1.893   20a39:6457   1Ign :  77   
##  Mean   : 159.34   Mean   :1.326   Mean   :2.627   40a59:2404   1Moto:7813   
##  3rd Qu.:  49.75   3rd Qu.:2.000   3rd Qu.:3.404   60+  : 572   1Outr: 197   
##  Max.   :3376.00   Max.   :3.000   Max.   :9.486   NA's :  16   1Ped :1002   
##                                                                 1VPes: 349   
##  sexo_str    CORPO_str    HORA_OCOR_str EVENTO_T_str CELULAR_str 
##  Fem :3338   2Cab :1685   3Mad: 995     4Trab:3232   5Cel:  315  
##  Masc:8464   2MInf:4242   3Man:3007     NA's :8570   NA's:11487  
##              2MSup:2690   3Noi:3633                              
##              2Tro :2691   3Tar:3917                              
##              NA's : 494   NA's: 250                              
##                                                                  
## 

Pela frequência de NAs 9 nas variáveis EVENTO_T e CELULAR, elas tendem a ser consideradas categorias suplementares (serão exibidas no gráfico, pois ajudarão na interpretação), mas não serão utilizadas para a AC.


Tabela de Contigência

Agora será construída a tabela de contingência, etapa inicial para a Análise de Correspondência (AC).

No entanto, como se trata de uma base com pesos amostrais, é necessária a declaração do desenho amostral antes. Caso contrário, estaríamos avaliando apenas a própria amostra.

Adequação do plano amostral

o options é utilizado para ajustar como o R lida com Unidades Primárias de Amostragem (PSUs) solitárias em análises de amostras complexas. Com essa configuração, o R faz um pequeno ajuste nos pesos, evitando erros ao calcular variâncias quando um estrato contém apenas uma PSU.

Em seguida, criamos um objeto de design amostral chamado. Esse objeto é fundamental para realizar análises estatísticas ponderadas. A variável NUM_TURNO2 identifica as PSUs, ESTRATO define os estratos da amostra, e peso fornece os pesos amostrais que ajustam as estimativas. A opção nest = TRUE indica que os estratos estão aninhados dentro das PSUs, e o dataframe df_ac contém os dados utilizados.

Como isso poderemos fazer a AC correto para a população analisada.

options(survey.lonely.psu = 'adjust')
dsn <- svydesign(ids = ~NUM_TURNO2,
                 strata = ~ESTRATO,
                 weights = ~peso,
                 nest = TRUE,
                 data = df_ac)

Criando tabela

Enfim, criamos a tabela de contingência, seguindo os devidos pesos amostrais.

# Tabelas
tabela1 <- as.data.frame(svytable(~TP_TRANSP_str + fet_str, dsn)) |> 
  rename(Acidente = TP_TRANSP_str, Demografico = fet_str)

tabela2 <- as.data.frame(svytable(~TP_TRANSP_str + sexo_str, dsn)) |> 
  rename(Acidente = TP_TRANSP_str, Demografico = sexo_str)

tabela3 <- as.data.frame(svytable(~CORPO_str + fet_str, dsn)) |> 
  rename(Acidente = CORPO_str, Demografico = fet_str)

tabela4 <- as.data.frame(svytable(~CORPO_str + sexo_str, dsn)) |> 
  rename(Acidente = CORPO_str, Demografico = sexo_str)

tabela5 <- as.data.frame(svytable(~HORA_OCOR_str + fet_str, dsn)) |> 
  rename(Acidente = HORA_OCOR_str, Demografico = fet_str)

tabela6 <- as.data.frame(svytable(~HORA_OCOR_str + sexo_str, dsn)) |> 
  rename(Acidente = HORA_OCOR_str, Demografico = sexo_str)

tabela7 <- as.data.frame(svytable(~EVENTO_T_str + fet_str, dsn)) |> 
  rename(Acidente = EVENTO_T_str, Demografico = fet_str)

tabela8 <- as.data.frame(svytable(~EVENTO_T_str + sexo_str, dsn)) |> 
  rename(Acidente = EVENTO_T_str, Demografico = sexo_str)

tabela9 <- as.data.frame(svytable(~CELULAR_str + fet_str, dsn)) |> 
  rename(Acidente = CELULAR_str, Demografico = fet_str)

tabela10 <- as.data.frame(svytable(~CELULAR_str + sexo_str, dsn)) |> 
  rename(Acidente = CELULAR_str, Demografico = sexo_str)

# Juntando
df_tabela <- rbind(tabela1,tabela2,tabela3,tabela4,tabela5,tabela6,tabela7,tabela8,tabela9,tabela10) |> 
  mutate(Freq = round(Freq, 0))

# Contingência
tabela_contingencia <- xtabs(Freq ~Acidente + Demografico,
                             data = df_tabela)
tabela_contingencia
##         Demografico
## Acidente   0a9 10a19 20a39 40a59   60+   Fem  Masc
##    1Auto   131   297  1359   654   257  1054  1649
##    1Bike   746  1013  1095   754   240   899  2952
##    1Ign     18    21    74    38     6    32   127
##    1Moto   175  2534 12493  3511   472  4382 14819
##    1Outr    39   153   175    81    34   134   352
##    1Ped    405   502  1036   782   430  1359  1801
##    1VPes    16   131   615   432   239   920   525
##    2Cab    459   711  2093   892   399  1360  3221
##    2MInf   511  1651  6598  2061   454  3405  7875
##    2MSup   262  1107  3785  1450   331  1626  5317
##    2Tro    210  1021  3759  1587   438  1972  5044
##    3Mad     40   396  1773   428    50   671  2023
##    3Man    304   858  4339  1848   577  2392  5537
##    3Noi    449  1526  5178  1879   334  2400  6984
##    3Tar    704  1781  5217  1983   680  3140  7234
##    4Trab    13   581  5842  2215   330  1947  7039
##    5Cel     39   149   510   156    34   254   639

Feita a tabela de contigênia pode seguir para a AC


Análise de Correspondêcia Simples

Para calcular a AC, usamos a função CA do pacote FactoMineR. Esse pacote possui diversas outras funções para análise multivariada.

É feito um teste de qui-quadrado como métrica de distância para verificar se existe associação entre as variáveis categóricas, servindo para válidação da análise.

O número de dimensões é determinado pelo menor número de linhas ou colunas menos 1. Na nossa base, encontraremos um máximo de 6 dimensões. Em geral, tentamos encontrar uma situação em que possamos obter um bom percentual de explicação nas duas primeiras dimensões, para assim analisar em um Biplot.

Sobre os estatiticas das variaveis temos:

Termos-chave Definição Interpretação Uso
Dimensão Os eixos principais (dimensões) apresentados no Biplot. Representa um eixo no espaço reduzido, onde os dados são projetados. A primeira dimensão captura a maior variância. Usado para reduzir os dados em um espaço de menor dimensão, representando a estrutura dos dados.
Cos² (cosine squared) O cosseno quadrado do ângulo entre uma linha/coluna e uma dimensão. É uma medida de qualidade de representação de uma linha ou coluna em relação a uma dimensão. Quanto à variação de uma linha/coluna é explicada por esse eixo. Mais próximo de 1 significa bom ajuste, mais próximo de 0 significa ajuste ruim. Avalia a qualidade da representação de linhas/colunas em cada eixo (dimensão).
Inércia da linha ou coluna Mede quanto da variância total é explicada ou representada por essa linha ou coluna em relação aos eixos/dimensões extraídos pela análise. Ela reflete quanto da variabilidade total é representada ou explicada por essa linha ou coluna. Avaliação da qualidade dos resultados. Se a inércia de muitas linhas ou colunas for muito baixa, isso pode indicar que os dados não estão bem representados pelas dimensões.
Contribuição (ctr) A proporção da inércia total explicada por uma linha/coluna específica ao longo de uma dada dimensão. Quanto uma linha ou coluna específica contribui para a variância (inércia) de cada dimensão. Usado para identificar as linhas/colunas mais influentes para cada eixo (dimensão).

Resultado 1

Aqui temos a análaise com todas as variaveis. que nos orientará no polimento da tabela.

Biplot

ca_resultado_1 <- CA(tabela_contingencia, graph = TRUE)

1VPes pode ser consderado um outlier.

Estatísticas

summary(ca_resultado_1, nbelements = Inf)
## 
## Call:
## CA(X = tabela_contingencia, graph = TRUE) 
## 
## The chi square of independence between the two variables is equal to 10659.53 (p-value =  0 ).
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3   Dim.4   Dim.5   Dim.6
## Variance               0.035   0.014   0.003   0.001   0.000   0.000
## % of var.             65.747  27.123   4.972   1.598   0.558   0.001
## Cumulative % of var.  65.747  92.871  97.843  99.441  99.999 100.000
## 
## Rows
##         Iner*1000    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr
## 1Auto |     1.579 |  0.120  1.102  0.242 |  0.211  8.289  0.751 |  0.008  0.072
## 1Bike |    14.102 |  0.516 29.261  0.720 | -0.317 26.726  0.271 |  0.050  3.593
## 1Ign  |     0.125 |  0.144  0.093  0.259 | -0.171  0.320  0.367 |  0.155  1.440
## 1Moto |     7.143 | -0.187 19.217  0.933 | -0.043  2.477  0.050 | -0.024  4.081
## 1Outr |     0.763 |  0.271  1.015  0.461 | -0.161  0.864  0.162 | -0.156  4.431
## 1Ped  |     7.965 |  0.473 20.148  0.878 |  0.172  6.474  0.116 |  0.035  1.488
## 1VPes |     7.236 |  0.259  2.754  0.132 |  0.654 42.572  0.842 | -0.102  5.691
## 2Cab  |     2.549 |  0.227  6.708  0.913 | -0.016  0.081  0.005 |  0.038  2.490
## 2MInf |     0.583 | -0.013  0.057  0.034 | -0.002  0.003  0.001 | -0.055 12.891
## 2MSup |     0.433 | -0.030  0.181  0.145 | -0.053  1.328  0.439 |  0.013  0.414
## 2Tro  |     0.334 | -0.011  0.024  0.025 |  0.044  0.929  0.398 |  0.008  0.160
## 3Mad  |     1.015 | -0.168  2.163  0.739 | -0.057  0.597  0.084 | -0.078  6.111
## 3Man  |     0.946 |  0.007  0.012  0.004 |  0.098  5.256  0.795 |  0.049  7.053
## 3Noi  |     0.496 | -0.011  0.034  0.024 | -0.065  2.781  0.802 | -0.017  1.039
## 3Tar  |     1.545 |  0.117  4.060  0.912 | -0.010  0.077  0.007 | -0.032  4.081
## 4Trab |     5.887 | -0.227 13.168  0.776 |  0.043  1.133  0.028 |  0.113 43.301
## 5Cel  |     0.060 | -0.012  0.004  0.022 | -0.039  0.092  0.221 | -0.070  1.664
##         cos2  
## 1Auto  0.001 |
## 1Bike  0.007 |
## 1Ign   0.303 |
## 1Moto  0.015 |
## 1Outr  0.152 |
## 1Ped   0.005 |
## 1VPes  0.021 |
## 2Cab   0.026 |
## 2MInf  0.580 |
## 2MSup  0.025 |
## 2Tro   0.013 |
## 3Mad   0.158 |
## 3Man   0.195 |
## 3Noi   0.055 |
## 3Tar   0.069 |
## 4Trab  0.193 |
## 5Cel   0.731 |
## 
## Columns
##         Iner*1000    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr
## 0a9   |    19.491 |  0.871 48.913  0.871 | -0.312 15.176  0.111 |  0.076  4.954
## 10a19 |     5.555 |  0.183  6.888  0.430 | -0.168 14.046  0.362 | -0.112 34.370
## 20a39 |     7.743 | -0.165 21.712  0.973 |  0.003  0.018  0.000 | -0.014  1.982
## 40a59 |     1.753 |  0.021  0.130  0.026 |  0.089  5.722  0.467 |  0.082 26.258
## 60+   |     7.767 |  0.412 12.877  0.575 |  0.337 20.788  0.383 |  0.068  4.569
## Fem   |     7.584 |  0.131  6.888  0.315 |  0.182 32.089  0.606 | -0.062 20.256
## Masc  |     2.868 | -0.050  2.593  0.314 | -0.069 12.162  0.607 |  0.023  7.612
##         cos2  
## 0a9    0.007 |
## 10a19  0.162 |
## 20a39  0.007 |
## 40a59  0.393 |
## 60+    0.015 |
## Fem    0.070 |
## Masc   0.070 |

A associação entre as variáveis é forte, de 10659.53 o que prova que a análise é válida.

Nos Autovalores temos como fica a explicação para cada dimensão, com a soma das duas primeiras dando 92.81.

Na Inércia da linha temos que 5Cel é muito baixa, indicando uma baixa contribuição.

1Ign e 1Ped com baixo crt e cos2.

Resultado 2

Aqui é feita uma reanálise com uma redução no número de variáveis, buscando aumentar a explicação das dimensões.

Tiro a variável 1VPes por ser outlier.

E1Ign e 1Outr por ter baixas estatísticas, elas não caracterizam importãncia para a interpretação.

Também defino a variavel 5Cel como suplementar, será apenas uma aparição gráfica, sem influenciar no calculo da AC.

Biplot

ca_resultado_2 <- CA(tabela_contingencia[-c(3,5,7),], row.sup = 14, graph = TRUE)

Estatísticas

summary(ca_resultado_2, nbelements = Inf)
## 
## Call:
## CA(X = tabela_contingencia[-c(3, 5, 7), ], row.sup = 14, graph = TRUE) 
## 
## The chi square of independence between the two variables is equal to 9015.371 (p-value =  0 ).
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3   Dim.4   Dim.5   Dim.6
## Variance               0.035   0.008   0.002   0.001   0.000   0.000
## % of var.             75.163  18.061   4.867   1.358   0.550   0.000
## Cumulative % of var.  75.163  93.224  98.092  99.449 100.000 100.000
## 
## Rows
##         Iner*1000    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr
## 1Auto |     1.786 |  0.108  0.932  0.180 |  0.227 17.142  0.797 | -0.032  1.275
## 1Bike |    14.482 |  0.544 33.573  0.801 | -0.258 31.480  0.181 |  0.079 11.071
## 1Moto |     6.909 | -0.179 18.195  0.910 | -0.053  6.578  0.079 | -0.016  2.350
## 1Ped  |     8.529 |  0.464 20.057  0.813 |  0.223 19.201  0.187 | -0.010  0.132
## 2Cab  |     2.725 |  0.233  7.335  0.930 |  0.020  0.218  0.007 |  0.023  1.111
## 2MInf |     0.624 | -0.009  0.028  0.015 | -0.003  0.014  0.002 | -0.063 20.567
## 2MSup |     0.376 | -0.022  0.097  0.089 | -0.045  1.753  0.387 |  0.025  1.937
## 2Tro  |     0.403 | -0.010  0.021  0.018 |  0.050  2.177  0.448 |  0.006  0.118
## 3Mad  |     0.991 | -0.159  2.018  0.704 | -0.073  1.740  0.146 | -0.071  6.244
## 3Man  |     1.112 |  0.005  0.006  0.002 |  0.114 12.564  0.938 |  0.028  2.916
## 3Noi  |     0.429 | -0.002  0.001  0.001 | -0.062  4.416  0.855 | -0.008  0.282
## 3Tar  |     1.738 |  0.122  4.542  0.903 |  0.003  0.009  0.000 | -0.037  6.502
## 4Trab |     5.871 | -0.223 13.194  0.777 |  0.050  2.708  0.038 |  0.105 45.496
##         cos2  
## 1Auto  0.016 |
## 1Bike  0.017 |
## 1Moto  0.008 |
## 1Ped   0.000 |
## 2Cab   0.009 |
## 2MInf  0.738 |
## 2MSup  0.115 |
## 2Tro   0.007 |
## 3Mad   0.141 |
## 3Man   0.059 |
## 3Noi   0.015 |
## 3Tar   0.084 |
## 4Trab  0.173 |
## 
## Columns
##         Iner*1000    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr
## 0a9   |    19.645 |  0.912 54.165  0.953 | -0.173  8.061  0.034 |  0.056  3.176
## 10a19 |     5.058 |  0.194  7.732  0.528 | -0.156 20.785  0.341 | -0.077 18.899
## 20a39 |     7.543 | -0.162 21.264  0.974 | -0.004  0.044  0.000 | -0.018  4.109
## 40a59 |     1.447 |  0.011  0.035  0.008 |  0.080  7.804  0.448 |  0.080 29.507
## 60+   |     6.333 |  0.381 10.716  0.585 |  0.308 29.091  0.381 |  0.042  2.026
## Fem   |     4.340 |  0.106  4.452  0.355 |  0.124 24.931  0.477 | -0.071 30.823
## Masc  |     1.609 | -0.039  1.636  0.351 | -0.046  9.284  0.479 |  0.027 11.459
##         cos2  
## 0a9    0.004 |
## 10a19  0.084 |
## 20a39  0.012 |
## 40a59  0.456 |
## 60+    0.007 |
## Fem    0.159 |
## Masc   0.159 |
## 
## Supplementary row
##          Dim.1   cos2    Dim.2   cos2    Dim.3   cos2  
## 5Cel  | -0.006  0.005 | -0.042  0.274 | -0.068  0.712 |

A soma das duas dimesãoes aumentou para 93.22.

Cluster Hierárquico

No pacote FactoMineR tem implementado o algoritmo HCPC (Hierarchical Clustering on Principal Components), utilizado para identificar padrões ou agrupamentos no conjunto de dados. Esse algoritmo usa como input as dimensões da Análise de Correspondência para identificar grupos de observações que são semelhantes entre si.

Linha

ca_cluster_hier_row <- HCPC(ca_resultado_2, cluster.CA = "rows", nb.clust = 3)

Coluna

ca_cluster_hier_col <- HCPC(ca_resultado_2, cluster.CA = "columns", nb.clust = 3)


Conclusão

Por fim, temos o gráfico biplot com elipses que demarcam as variáveis de acordo com a clusterização verificada.

Observamos que, em azul, estão as variáveis mais independentes, enquanto as em verde e vermelho apresentam um comportamento mais semelhante.

df_clust <- rbind(ca_cluster_hier_row$data.clust["clust"],
                  ca_cluster_hier_col$data.clust["clust"]) |> 
              as.data.frame() |>
              rownames_to_column("variavel")

df_elipses <- data.frame(x = c(ca_resultado_2$row$coord[,1], ca_resultado_2$col$coord[,1]),
                         y = c(ca_resultado_2$row$coord[,2], ca_resultado_2$col$coord[,2])) |> 
  rownames_to_column("variavel") |> 
  left_join(df_clust, by = "variavel")

plot(ca_resultado_2, repel = TRUE, title="Biplot")+
  ggforce::geom_mark_ellipse(data = df_elipses,
                             aes(x = x, y = y, group = clust, color = clust,fill = clust),
                             alpha = 0.2)+
  theme(legend.position = 'none')


Bônus

Aqui, faço uma breve análise com o intuito de exibir um biplot com uma saída mais interdependente. Por essa razão, não me aprofundo nas definições.

contingency_table_freq <- xtabs(Freq ~ Violencia + Demografico, data = df_2)
ca_result <- CA(contingency_table_freq, graph = FALSE)
ca_result.hcpc_rows <- HCPC(ca_result, cluster.CA = "rows", nb.clust = 3, graph = FALSE)
ca_result.hcpc_cols <- HCPC(ca_result, cluster.CA = "columns", nb.clust = 3, graph = FALSE)
df_clust <- as.data.frame(rbind(ca_result.hcpc_rows$data.clust["clust"],
                                ca_result.hcpc_cols$data.clust["clust"])) |>
              rownames_to_column("variavel")
df_elipses <- data.frame(x = c(ca_result$row$coord[,"Dim 1"],
                               ca_result$col$coord[,"Dim 1"]),
                         y = c(ca_result$row$coord[,"Dim 2"],
                               ca_result$col$coord[,"Dim 2"])) |> 
  rownames_to_column("variavel") |> 
  left_join(df_clust,by = "variavel")
plot(ca_result, repel = TRUE, title = "Perfil das violências notificadas pela população indígena com idade entre 0 e 19 anos")+
  ggforce::geom_mark_ellipse(data = df_elipses,
                             aes(x = x, y = y, group = clust, color = clust, fill = clust),
                             alpha = 0.2)+
  theme(legend.position = 'none')


  1. O Sistema de Vigilância de Violências e Acidentes (VIVA) foi implantado em 2006 com o objetivo de coletar dados e gerar informações sobre violências e acidentes (causas externas), subsidiando políticas de saúde pública voltadas para esses agravos.↩︎