Análise de componentes principais para mapas perceptivos (toothpaste dataset)

Neste capítulo, você aprenderá como realizar uma análise de componentes principais e visualizar os resultados em um mapa perceptivo.

Digamos que tenhamos um conjunto de observações que diferem entre si em várias dimensões; por exemplo, temos várias marcas de uísque (observações) classificadas em vários atributos, como corpo, doçura, sabor, etc. (dimensões ) Se algumas dessas dimensões estiverem fortemente correlacionadas, deve ser possível descrever as observações por um número menor (que o original) de dimensões sem perder muita informação. Por exemplo, doçura e frutificação podem ser altamente correlacionadas e, portanto, podem ser substituídas por uma variável. Essa redução de dimensionalidade é o objetivo da análise de componentes principais.

Dados

Importação

Analisaremos os dados de uma pesquisa na qual 60 consumidores foram convidados a responder a seis perguntas sobre pasta de dente. Esses dados foram coletados pelos criadores do Radiant}, que é um pacote do R para análise de negócios que usaremos posteriormente. Faça o download dos dados aqui e importe-os para o R:

library(tidyverse)
## -- Attaching packages -------------------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.2     v purrr   0.3.4
## v tibble  3.0.3     v dplyr   1.0.0
## v tidyr   1.1.2     v stringr 1.4.0
## v readr   1.3.1     v forcats 0.5.0
## -- Conflicts ----------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(readxl)



url<-"http://users.telenet.be/samuelfranssens/tutorial_data/toothpaste.xlsx"
toothpaste <- tempfile()
download.file(url, toothpaste, mode="wb")
toothpaste<-read_excel(path = toothpaste, sheet = 1)

toothpaste
## # A tibble: 60 x 9
##    consumer prevents_caviti~ shiny_teeth strengthens_gums freshens_breath
##       <dbl>            <dbl>       <dbl>            <dbl>           <dbl>
##  1        1                7           3                6               4
##  2        2                1           3                2               4
##  3        3                6           2                7               4
##  4        4                4           5                4               6
##  5        5                1           2                2               3
##  6        6                6           3                6               4
##  7        7                5           3                6               3
##  8        8                6           4                7               4
##  9        9                3           4                2               3
## 10       10                2           6                2               6
## # ... with 50 more rows, and 4 more variables:
## #   decay_prevention_unimportant <dbl>, attractive_teeth <dbl>, age <dbl>,
## #   gender <chr>

Manipulação

toothpaste # Visualiza os dados
## # A tibble: 60 x 9
##    consumer prevents_caviti~ shiny_teeth strengthens_gums freshens_breath
##       <dbl>            <dbl>       <dbl>            <dbl>           <dbl>
##  1        1                7           3                6               4
##  2        2                1           3                2               4
##  3        3                6           2                7               4
##  4        4                4           5                4               6
##  5        5                1           2                2               3
##  6        6                6           3                6               4
##  7        7                5           3                6               3
##  8        8                6           4                7               4
##  9        9                3           4                2               3
## 10       10                2           6                2               6
## # ... with 50 more rows, and 4 more variables:
## #   decay_prevention_unimportant <dbl>, attractive_teeth <dbl>, age <dbl>,
## #   gender <chr>

O conjunto de dados consiste em um identificador, consumer}, e as classificações do entrevistado sobre a importância de seis atributos de pasta de dente: prevents_cavities, shiny_teeth, strengthens_gums, freshens_breath, decay_prevention_unimportant, and attractive_teeth. Nos também temos os respondentes age e gender.

Vamos fatorar o identificador e o gender :

toothpaste <- toothpaste %>% 
  mutate(consumer = factor(consumer),
         gender = factor(gender))

Recapitulação: importação e manipulação

Aqui está o que fizemos até agora, em uma sequência ordenada de operações canalizadas (faça o download dos dados aqui :

#library(tidyverse)
#library(readxl)

#toothpaste <- read_excel("toothpaste.xlsx")
#  mutate(consumer = factor(consumer),
     #    gender = factor(gender))

Quantos fatores devemos considerar ?

O objetivo da análise de componentes principais é reduzir o número de dimensões que descrevem nossos dados, sem perder muitas informações. O primeiro passo na análise de componentes principais é decidir o número de componentes ou fatores principais que queremos manter. Para nos ajudar a decidir, usaremos a função pre_factor do pacote radiant:

#install.packages("radiant")
library(radiant)
## Loading required package: radiant.data
## Loading required package: magrittr
## 
## Attaching package: 'magrittr'
## The following object is masked from 'package:purrr':
## 
##     set_names
## The following object is masked from 'package:tidyr':
## 
##     extract
## Loading required package: lubridate
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
## 
## Attaching package: 'radiant.data'
## The following objects are masked from 'package:lubridate':
## 
##     month, wday
## The following object is masked from 'package:forcats':
## 
##     as_factor
## The following objects are masked from 'package:purrr':
## 
##     is_double, is_empty, is_numeric
## The following object is masked from 'package:ggplot2':
## 
##     diamonds
## The following object is masked from 'package:base':
## 
##     date
## Loading required package: radiant.design
## Loading required package: mvtnorm
## Loading required package: radiant.basics
## Loading required package: radiant.model
## Loading required package: radiant.multivariate
## 
## Attaching package: 'radiant.multivariate'
## The following object is masked _by_ '.GlobalEnv':
## 
##     toothpaste
# armazene os nomes das dimensoes em um vetor para que nao tenhamos que digita-las repetidamente

dimensions <- c("prevents_cavities", "shiny_teeth", "strengthens_gums", "freshens_breath", "decay_prevention_unimportant", "attractive_teeth") 

# dica: tambem poderiamos fazer o seguinte:

# dimensions <- toothpaste %>% select(-consumer, -gender, -age) %>% names()

summary(pre_factor(toothpaste, vars = dimensions))
## Pre-factor analysis diagnostics
## Data        : toothpaste 
## Variables   : prevents_cavities, shiny_teeth, strengthens_gums, freshens_breath, decay_prevention_unimportant, attractive_teeth 
## Observations: 60 
## Correlation : Pearson
## 
## Bartlett test
## Null hyp. : variables are not correlated
## Alt. hyp. : variables are correlated
## Chi-square: 238.93 df(15), p.value < .001
## 
## KMO test:  0.66 
## 
## Variable collinearity:
##                               Rsq  KMO
## prevents_cavities            0.86 0.62
## shiny_teeth                  0.48 0.70
## strengthens_gums             0.81 0.68
## freshens_breath              0.54 0.64
## decay_prevention_unimportant 0.76 0.77
## attractive_teeth             0.59 0.56
## 
## Fit measures:
##      Eigenvalues Variance % Cumulative %
##  PC1        2.73       0.46         0.46
##  PC2        2.22       0.37         0.82
##  PC3        0.44       0.07         0.90
##  PC4        0.34       0.06         0.96
##  PC5        0.18       0.03         0.99
##  PC6        0.09       0.01         1.00

Nas Fit measures, vemos que dois componentes explicam 82% da variação nas classificações. Isso já é bastante e sugere que podemos reduzir com segurança o número de dimensões para dois componentes. Uma regra prática aqui é que a variação cumulativa explicada pelos componentes deve ser de pelo menos 70%.

Análise de Componentes Principais

Vamos extrair somente dois componentes ou fatores:

summary(full_factor(toothpaste, dimensions, nr_fact = 2))
## Factor analysis
## Data        : toothpaste 
## Variables   : prevents_cavities, shiny_teeth, strengthens_gums, freshens_breath, decay_prevention_unimportant, attractive_teeth 
## Factors     : 2 
## Method      : PCA 
## Rotation    : varimax 
## Observations: 60 
## Correlation : Pearson
## 
## Factor loadings:
##                                RC1   RC2
## prevents_cavities             0.96 -0.03
## shiny_teeth                  -0.05  0.85
## strengthens_gums              0.93 -0.15
## freshens_breath              -0.09  0.85
## decay_prevention_unimportant -0.93 -0.08
## attractive_teeth              0.09  0.88
## 
## Fit measures:
##               RC1  RC2
## Eigenvalues  2.69 2.26
## Variance %   0.45 0.38
## Cumulative % 0.45 0.82
## 
## Attribute communalities:                                   
## prevents_cavities            92.59%
## shiny_teeth                  72.27%
## strengthens_gums             89.36%
## freshens_breath              73.91%
## decay_prevention_unimportant 87.78%
## attractive_teeth             79.01%
## 
## Factor scores (max 10 shown):
##    RC1   RC2
##   1.15 -0.30
##  -1.17 -0.34
##   1.29 -0.86
##   0.29  1.11
##  -1.43 -1.49
##   0.97 -0.31
##   0.39 -0.94
##   1.33 -0.03
##  -1.02 -0.64
##  -1.31  1.56
# Peça dois fatores preenchendo o argumento nr_fact.

Cargas fatoriais

Veja a tabela abaixo do Factor loadings. Essas cargas são as correlações entre as dimensões originais (prevents_cavities, shiny_teeth, etc.) e os dois fatores que são retidos (RC1 e RC2). Nós vemos que prevents_cavities, strengthens_gums, e decay_prevention_unimportant pontuação alta no primeiro fator, enquanto shiny_teeth, strengthens_gums, e freshens_breath pontuação alta no segundo fator. Poderíamos, portanto, dizer que o primeiro fator descreve preocupações relacionadas à saúde e que o segundo fator descreve preocupações relacionadas à aparência.

Também queremos saber quanto cada uma das seis dimensões é explicada pelos fatores extraídos. Para isso, podemos observar a comunalidade das dimensões (cabeçalho: Attribute communalities). A comunalidade de uma variável é a porcentagem da variação dessa variável que é explicada pelos fatores. Seu complemento é chamado de exclusividade (= 1-comunalidade). A exclusividade pode ser puro erro de medição ou pode representar algo que é medido de forma confiável por essa variável específica, mas não por nenhuma das outras variáveis. Quanto maior a exclusividade, maior a probabilidade de que seja mais do que apenas erro de medição. Uma exclusividade superior a 0,6 é geralmente considerada alta. Se a exclusividade for alta, a variável não será bem explicada pelos fatores. Vemos que, para todas as dimensões, a comunalidade é alta e, portanto, a singularidade é baixa; portanto, todas as dimensões são bem capturadas pelos fatores extraídos.

Gráfico das cargas fatoriais

Também podemos traçar as cargas. Para isso, usaremos dois pacotes:

#install.packages("FactoMiner")
#install.packages("factoextra")
library(FactoMineR)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
toothpaste %>% # take dataset
  select(-consumer,-age,-gender) %>% # somente duas dimensoes
  as.data.frame() %>% # converter em um objeto data.frame, caso contrário, o PCA não o aceitará
  PCA(ncp = 2, graph = FALSE) %>% # faça uma análise de componentes principais e retenha 2 fatores
  fviz_pca_var(repel = TRUE) # pegue essa análise e a transforme em uma visualização

Vemos que attractive_teeth, shiny_teeth, freshens_breath, têm pontuações altas no segundo fator (o Dim2 do eixo X). prevents_cavities e strengthens_gums têm pontuações altas no segundo fator (o eixo Y Dim2) e decay_prevention_unimportant tem uma pontuação baixa nesse fator (essa variável mede a importância da prevenção da cárie).

Também podemos adicionar as observações (os diferentes consumidores) a esse gráfico:

toothpaste %>% # pega os dados
  select(-consumer,-age,-gender) %>% # obtem as dimensoes somente
  as.data.frame() %>% # converte em data.frame object, caso contratio PCA nao aceita
  PCA(ncp = 2, graph = FALSE) %>% # faz o pca e retem 2 fatores
  fviz_pca_biplot(repel = TRUE) #faz o grafico

Isto também é conhecido como biplot.