Nous étudions des données issues de pages Facebook de ventes d’articles de modes et de cosmétiques. Le tableau de données contient une ligne par post qui peuvent être de différents types (vidéos, photos, status et liens). Les données sont téléchargeables sur le site UCI Machine Learning repository. Les variables que nous allons étudier sont :

Première observation des données

library("readr")
Live <- read_csv("Live.csv")
## 
## ── Column specification ────────────────────────────────────────────────────────
## cols(
##   status_id = col_character(),
##   status_type = col_character(),
##   status_published = col_character(),
##   num_reactions = col_double(),
##   num_comments = col_double(),
##   num_shares = col_double(),
##   num_likes = col_double(),
##   num_loves = col_double(),
##   num_wows = col_double(),
##   num_hahas = col_double(),
##   num_sads = col_double(),
##   num_angrys = col_double(),
##   Column1 = col_logical(),
##   Column2 = col_logical(),
##   Column3 = col_logical(),
##   Column4 = col_logical()
## )
Live <- Live[,c(2,4:12)]
Live[,1] <- factor(Live$status_type)
summary(Live)
##  status_type   num_reactions     num_comments       num_shares     
##  link  :  63   Min.   :   0.0   Min.   :    0.0   Min.   :   0.00  
##  photo :4288   1st Qu.:  17.0   1st Qu.:    0.0   1st Qu.:   0.00  
##  status: 365   Median :  59.5   Median :    4.0   Median :   0.00  
##  video :2334   Mean   : 230.1   Mean   :  224.4   Mean   :  40.02  
##                3rd Qu.: 219.0   3rd Qu.:   23.0   3rd Qu.:   4.00  
##                Max.   :4710.0   Max.   :20990.0   Max.   :3424.00  
##    num_likes        num_loves         num_wows         num_hahas       
##  Min.   :   0.0   Min.   :  0.00   Min.   :  0.000   Min.   :  0.0000  
##  1st Qu.:  17.0   1st Qu.:  0.00   1st Qu.:  0.000   1st Qu.:  0.0000  
##  Median :  58.0   Median :  0.00   Median :  0.000   Median :  0.0000  
##  Mean   : 215.0   Mean   : 12.73   Mean   :  1.289   Mean   :  0.6965  
##  3rd Qu.: 184.8   3rd Qu.:  3.00   3rd Qu.:  0.000   3rd Qu.:  0.0000  
##  Max.   :4710.0   Max.   :657.00   Max.   :278.000   Max.   :157.0000  
##     num_sads         num_angrys     
##  Min.   : 0.0000   Min.   : 0.0000  
##  1st Qu.: 0.0000   1st Qu.: 0.0000  
##  Median : 0.0000   Median : 0.0000  
##  Mean   : 0.2437   Mean   : 0.1132  
##  3rd Qu.: 0.0000   3rd Qu.: 0.0000  
##  Max.   :51.0000   Max.   :31.0000

Nous observons que le jeu de données ne contient pas de valeurs manquantes. Le minimum, ainsi que, pour certaines variables le 1er quartile voire la médiane et le 3ème quartile, est à 0 pour toutes les variables suggérant que certains posts ne suscitent aucune réaction ou aucun commentaire ou aucun partage. Les données ne peuvent pas être gaussiennes.

Mise en oeuvre et interprétation de l’ACP

library("FactoMineR")
res.ACP <- PCA(Live,quali.sup=1,quanti.sup=2,ncp=10)

Observation des valeurs propres

Nous représentons tout d’abord les valeurs propres

res.ACP$eig
##        eigenvalue percentage of variance cumulative percentage of variance
## comp 1  3.2219706              40.274632                          40.27463
## comp 2  1.0424926              13.031157                          53.30579
## comp 3  0.9091640              11.364550                          64.67034
## comp 4  0.8337559              10.421948                          75.09229
## comp 5  0.7734797               9.668497                          84.76078
## comp 6  0.6897911               8.622389                          93.38317
## comp 7  0.3802242               4.752802                          98.13598
## comp 8  0.1491220               1.864025                         100.00000
barplot(res.ACP$eig[,1])

Nous observons que la plus grande part d’inertie est portée par le premier axe. Les axes 2 à 6 portent chacun entre 9% et 13% de l’inertie totale donc peuvent être intéressants à garder dans l’analyse si nous pouvons les interpréter.

Analyse du premier plan (axes 1 et 2)

plot(res.ACP,choix="var")  

Nous observons que toutes les variables sont corrélées positivement à l’axe 1. L’axe 2 semble opposer des individus qui ont suscité plus de J’aime et de réactions et moins de Tristes que la moyenne à des individus.

plot(res.ACP,choix="ind",habillage=1,select="contrib 10") 

Nous observons que les individus ayant les coordonnées les plus élevées et les plus contributifs sur l’axe 1 sont des posts de type vidéo. Les individus ayant les coordonnées les plus élevées sur l’axe 2 sont plutôt de type photo.

Analyse de l’axe 1

L’axe 1 semble opposer les posts ayant suscité le plus de réactions à ceux n’ayant pas ou peu suscité de réaction. Pour confirmer cela nous pouvons comparer les observations des individus les plus remarquables sur l’axe 1 et comparer aux données statistique des variables (moyenne, médiane et quartiles) de tous les individus calculés par la fonction summary().

tri1 = sort.int(res.ACP$ind$coord[,1],index.return = T,decreasing = T)
data.frame(Live[tri1$ix[1:5],])
##   status_type num_reactions num_comments num_shares num_likes num_loves
## 1       video          2639         1625        675      1753       657
## 2       video          1970         2903       3424      1330       482
## 3       video          2399         2458       1430      1643       529
## 4       video          1758         1890        718      1181       385
## 5       video          2237         2571        815      1591       376
##   num_wows num_hahas num_sads num_angrys
## 1       68       157        0          4
## 2      138        13        5          2
## 3      206        15        3          3
## 4       89       100        2          1
## 5      252        15        1          2

L’observation du nuage des individus nous indique également que le type ‘video’ semble susciter plus de réactions que la moyenne.

print('type video')
## [1] "type video"
colMeans(Live[which(Live$status_type=="video"),2:10])
## num_reactions  num_comments    num_shares     num_likes     num_loves 
##   283.4095973   642.4781491   115.6799486   243.0154242    35.5402742 
##      num_wows     num_hahas      num_sads    num_angrys 
##     2.4481577     1.7352185     0.4138817     0.2540703
print('moyenne globale')
## [1] "moyenne globale"
colMeans(Live[,2:10])
## num_reactions  num_comments    num_shares     num_likes     num_loves 
##   230.1171631   224.3560284    40.0225532   215.0431206    12.7286525 
##      num_wows     num_hahas      num_sads    num_angrys 
##     1.2893617     0.6964539     0.2436879     0.1131915

Analyse de l’axe 2

A première vue l’axe 2 semble plus difficile à interpréter que l’axe 1. Nous pouvons observer la description automatique des axes à l’aide de la fonction dimdesc().

desc.axes = dimdesc(res.ACP,axes=1:6)
desc.axes$Dim.2
## $quanti
##               correlation       p.value
## num_likes      0.64595013  0.000000e+00
## num_reactions  0.63913572  0.000000e+00
## num_wows       0.46553776  0.000000e+00
## num_loves      0.05178638  1.359180e-05
## num_hahas      0.03174047  7.692773e-03
## num_shares    -0.06937720  5.503022e-09
## num_angrys    -0.11539402  2.484129e-22
## num_comments  -0.34253982 2.691800e-193
## num_sads      -0.51900269  0.000000e+00
## 
## $quali
##                     R2      p.value
## status_type 0.01361524 8.369041e-21
## 
## $category
##                      Estimate      p.value
## status_type=status  0.1983384 3.543176e-11
## status_type=link    0.1893489 8.862610e-03
## status_type=photo  -0.1061315 4.767902e-05
## status_type=video  -0.2815558 3.563068e-15
## 
## attr(,"class")
## [1] "condes" "list"

Les posts ayant des coordonnées positives sur l’axe 2 sont ceux ayant tendance à avoir plus de réactions que la moyenne, en particulier de type J’aime, Wouah, J’adore, et Haha et moins de réaction de type triste ou Grr, de commentaires et de partage (même si la corrélation avec le nombre de partages et le nombre de J’adore et de Haha est très faible). L’axe 2 semble donc opposer des posts ayant généré des réactions positives (ayant des coordonnées positives sur cet axe) à ceux ayant des coordonnées négatives. Il semblerait que les posts de type status ou lien aient tendance à avoir des coordonnées positives sur cet axe et que les photos et les vidéos plutôt des coordonnées négatives (ce n’est pas très visible sur le nuage des individus). Ceci dit cette tendance n’est pas confirmée par l’analyse des moyennes des variables ci-dessous et nous ne la retiendrons pas.

print('video')
## [1] "video"
colMeans(Live[which(Live$status_type=="video"),2:10])
## num_reactions  num_comments    num_shares     num_likes     num_loves 
##   283.4095973   642.4781491   115.6799486   243.0154242    35.5402742 
##      num_wows     num_hahas      num_sads    num_angrys 
##     2.4481577     1.7352185     0.4138817     0.2540703
print('photo')
## [1] "photo"
colMeans(Live[which(Live$status_type=="photo"),2:10])
## num_reactions  num_comments    num_shares     num_likes     num_loves 
##  181.29034515   15.99347015    2.55387127  178.77845149    1.44519590 
##      num_wows     num_hahas      num_sads    num_angrys 
##    0.68470149    0.19076493    0.14249067    0.04570896
print('link')
## [1] "link"
colMeans(Live[which(Live$status_type=="link"),2:10])
## num_reactions  num_comments    num_shares     num_likes     num_loves 
##  370.14285714    5.69841270    4.39682540  369.61904762    0.30158730 
##      num_wows     num_hahas      num_sads    num_angrys 
##    0.19047619    0.03174603    0.00000000    0.00000000
print('status')
## [1] "status"
colMeans(Live[which(Live$status_type=="status"),2:10])
## num_reactions  num_comments    num_shares     num_likes     num_loves 
##  438.78356164   36.23835616    2.55890411  435.52876712    1.56164384 
##      num_wows     num_hahas      num_sads    num_angrys 
##    1.17260274    0.10958904    0.38630137    0.02465753
print("Moyenne")
## [1] "Moyenne"
colMeans(Live[,2:10])
## num_reactions  num_comments    num_shares     num_likes     num_loves 
##   230.1171631   224.3560284    40.0225532   215.0431206    12.7286525 
##      num_wows     num_hahas      num_sads    num_angrys 
##     1.2893617     0.6964539     0.2436879     0.1131915

Individus remarquables sur le plan composé des axes 1 et 2

Nous observons un groupe d’individu ayant des coordonnées plus importantes que les autres sur l’axe 1 et sur l’axe 2. L’analyse de ces individus remarquables peut aider par exemple à déterminer des caractéristiques communes aux posts les plus partagés et remarqués (dans l’objectif de faire de la plublicité sur un produit par exemple).

# Individu ayant la coordonnée la plus élevée sur l'axe 1
data.frame(Live[which.max(res.ACP$ind$coord[,1]),])
##   status_type num_reactions num_comments num_shares num_likes num_loves
## 1       video          2639         1625        675      1753       657
##   num_wows num_hahas num_sads num_angrys
## 1       68       157        0          4
# Il s'agit d'un post ayant suscité un nombre important de réactions, de commentaires et de partages. Il a notamment suscité le plus de réaction de type *Haha* et *J'adore* et aucune réaction *Triste*.
# Individu ayant la coordonnée la plus élevée sur l'axe 2
data.frame(Live[which.max(res.ACP$ind$coord[,2]),])
##   status_type num_reactions num_comments num_shares num_likes num_loves
## 1       video          1678         1499        685      1227       165
##   num_wows num_hahas num_sads num_angrys
## 1      278         8        0          0
# Il s'agit d'un post ayant suscité un nombre important de réactions, de commentaires et de partages. Il a notamment suscité le plus de réaction de type *Wouah* aucune réaction *Triste* ou *Grr*.
# Individu ayant la coordonnée la moins élevée sur l'axe 2
data.frame(Live[which.min(res.ACP$ind$coord[,2]),])
##   status_type num_reactions num_comments num_shares num_likes num_loves
## 1       photo           295            3         10       243         1
##   num_wows num_hahas num_sads num_angrys
## 1        0         0       51          0
# Il s'agit d'un post ayant suscité un nombre relativement important de réactions, peu de commentaires et de partages. C'est le post qui a suscité le plus de réaction de type *Triste*. 

Analyse du plan engendré par les axes 3 et 4

plot(res.ACP,choix="var",axes=c(3,4))  

Au vu du cercle des corrélations, l’axe 3 semble corrélé positivement en particulier avec les variables num_likes, num_sads et num_reactions. L’axe 4 avec la variable num_angrys.

plot(res.ACP,axes=c(3,4),select="contrib 10",habillage = 1)

Les individus les plus contributifs sur ces deux axes sont plutôt des photos. La plupart des individus sont assez centraux. Nous allons analyser plus particulièrement les individus ayant les coordonnées les plus élevées.

desc.axes$Dim.3
## $quanti
##               correlation      p.value
## num_sads       0.69631467 0.000000e+00
## num_likes      0.59199713 0.000000e+00
## num_reactions  0.56360026 0.000000e+00
## num_comments  -0.04957078 3.127246e-05
## num_wows      -0.07133358 2.021752e-09
## num_loves     -0.12964520 8.304035e-28
## num_shares    -0.14154732 7.064047e-33
## num_hahas     -0.17028366 5.137158e-47
## 
## $quali
##                     R2     p.value
## status_type 0.01985001 2.00204e-30
## 
## $category
##                      Estimate      p.value
## status_type=status  0.3312680 1.131077e-23
## status_type=photo  -0.1321370 1.409001e-02
## status_type=video  -0.2778798 1.900577e-14
## 
## attr(,"class")
## [1] "condes" "list"
desc.axes$Dim.4
## $quanti
##               correlation       p.value
## num_angrys     0.84348023  0.000000e+00
## num_wows       0.05334512  7.412678e-06
## num_loves     -0.02788457  1.921426e-02
## num_sads      -0.03193281  7.330961e-03
## num_reactions -0.07476002  3.281620e-10
## num_likes     -0.07601445  1.652208e-10
## num_hahas     -0.08390696  1.708919e-12
## num_shares    -0.14588532  7.719046e-35
## num_comments  -0.28905518 9.610029e-136
## 
## $quali
##                      R2      p.value
## status_type 0.006907891 1.407183e-10
## 
## $category
##                      Estimate      p.value
## status_type=photo  0.08320988 1.179854e-11
## status_type=video -0.08018494 1.420627e-11
## 
## attr(,"class")
## [1] "condes" "list"

Individus ayant les coordonnées les plus élevées sur l’axe 3

Trois individus se dégagent en particulier.

tri3 = sort.int(res.ACP$ind$coord[,3],decreasing = T,index.return = T)
data.frame(Live[tri3$ix[1:3],])
##   status_type num_reactions num_comments num_shares num_likes num_loves
## 1       photo           295            3         10       243         1
## 2       photo           336           42          2       285         5
## 3       photo           336           42          2       285         5
##   num_wows num_hahas num_sads num_angrys
## 1        0         0       51          0
## 2        0         0       46          0
## 3        0         0       46          0

Il s’agit d’individus qui ont suscité un nombre relativement élevé de réactions (un peu plus élevé que la moyenne), relativement peu de commentaires mais un nombre élevé (proche ou égal au maximum de réactions tristes).

Individus ayant les coordonnées les plus élevées sur l’axe 4

Cinq individus se dégagent en particulier.

tri4 = sort.int(res.ACP$ind$coord[,4],decreasing = T,index.return = T)
data.frame(Live[tri4$ix[1:4],])
##   status_type num_reactions num_comments num_shares num_likes num_loves
## 1       photo           215           44          0       176         1
## 2       photo           251           29          5       228         0
## 3       photo           251           29          5       228         0
## 4       photo           287           38          2       260         0
##   num_wows num_hahas num_sads num_angrys
## 1        3         4        0         31
## 2        3         0        1         19
## 3        3         0        1         19
## 4       12         2        1         12

On repère bien ici les individus qui ont suscité des réactions tristes.

Analyse du plan engendré par les axes 5 et 6

res.ACP <- PCA(Live,quali.sup=1,quanti.sup=2,graph=FALSE,ncp=10)
plot(res.ACP,choix="var",axes=c(5,6))  

plot(res.ACP,axes=c(5,6),select="contrib 10",habillage = 1)

desc.axes$Dim.5
## $quanti
##               correlation       p.value
## num_wows       0.51259605  0.000000e+00
## num_sads       0.35893141 2.198026e-213
## num_hahas      0.24020731  4.362536e-93
## num_loves      0.02441876  4.034046e-02
## num_shares    -0.14901787  2.711434e-36
## num_angrys    -0.18279282  5.045841e-54
## num_reactions -0.32246522 2.691196e-170
## num_likes     -0.34711291 8.832132e-199
## num_comments  -0.38404494 1.503855e-246
## 
## $quali
##                     R2      p.value
## status_type 0.01795084 1.744607e-27
## 
## $category
##                      Estimate      p.value
## status_type=photo  0.15617955 1.813664e-28
## status_type=video -0.09548691 8.032696e-27
## 
## attr(,"class")
## [1] "condes" "list"
desc.axes$Dim.6
## $quanti
##               correlation       p.value
## num_hahas      0.71438615  0.000000e+00
## num_likes      0.12738854  6.751855e-27
## num_reactions  0.11679685  7.668540e-23
## num_angrys     0.03728601  1.740777e-03
## num_sads      -0.02922030  1.414536e-02
## num_loves     -0.07885634  3.350788e-11
## num_comments  -0.08271722  3.501139e-12
## num_shares    -0.19708066  1.128469e-62
## num_wows      -0.33025804 5.089573e-179
## 
## $quali
##                      R2    p.value
## status_type 0.001927471 0.00351157
## 
## $category
##                       Estimate      p.value
## status_type=photo -0.005364373 0.0080623204
## status_type=video -0.076369191 0.0003778104
## 
## attr(,"class")
## [1] "condes" "list"

Il semblerait que l’axe 5 soit plutôt corrélé aux réactions de type Wouah et l’axe 6 aux réactions de type Haha.

Conclusion

L’analyse du jeu de données à montré que les données sont très hétérogènes : la plus grande partie des posts suscite assez peu de réactions, commentaires et partages. L’analyse des résultats de l’ACP nous permet de repérer les individus les plus marquants et certaines caractéristiques qui se dégagent. Nous pouvons par exemple remarquer que les posts qui générent globalement plus de réactions, commentaires et partages sont des vidéos. L’analyse de l’axe 2 nous permet de différencier les posts qui génèrent plutôt des réactions positives (J’aime, Wouah, J’adore, et Haha) et ceux qui génèrent plutôt des réactions négatives. Les autres axes semblent plutôt liés au nombre de réactions de tristesse (axe 3), de colère (axe 4), d’étonnement (axe 5) ou de rire (axe 6). Les individus les plus marquants sur les axes 3 et 4 sont plutôt des photos.

Annexe (analyse automatique à l’aide de la fonction Investigate)

library("FactoInvestigate")
Investigate(res.ACP)
## -- création du fichier .Rmd (temps écoulé : 0s) --
## 
## -- détection d'individus singuliers (temps écoulé : 0.09s) --
## 0 anomalie(s) éliminée(s) 
## 
## -- analyse de l'inertie (temps écoulé : 0.59s) --
## 2 composante(s) porteuse(s) d'information : inertie totale de 53.3% 
## 
## -- description des composantes (temps écoulé : 12.36s) --
## plan 1:2 
## 
## -- classification (temps écoulé : 17.64s) --
## 3 classes 
## 
## -- rédaction des annexes (temps écoulé : 35.32s) --
## 
## -- sauvegarde des données (temps écoulé : 37.74s) --
## 
## -- compilation des documents (temps écoulé : 37.74s) --
## -- tâche terminée (temps écoulé : 65.34s) --
## Cette interprétation des résultats a été réalisée de façon automatique, 
## elle ne peut en aucun cas égaler la qualité d'une interprétation personnalisée