Introduction

Dans un environnement où la fidélisation de la clientèle est cruciale pour le secteur financier, ce projet se concentre sur l’analyse des facteurs qui influencent l’attrition des clients d’une banque européenne. Nous examinerons les informations relatives aux comptes de 10,000 clients, en nous penchant sur divers aspects tels que leur solvabilité, leur âge, le solde de leur compte, et leur utilisation des produits bancaires.

Nous visons à identifier les caractéristiques qui sont les plus souvent associées au départ des clients, à évaluer si l’attrition peut être prédite à partir des données disponibles, et à comprendre les différences de comportement entre différents segments de clientèle. Cette analyse permettra de mettre en lumière les défis liés à la rétention de la clientèle dans le secteur bancaire et de proposer des pistes pour améliorer les stratégies de fidélisation et la gestion de la relation client.

1. Importation et description des données

1.1 Importation des données

# Charger les données depuis le fichier CSV
bank_data <- read.csv("Bank_Churn.csv")

1.2 Aperçu des données

# Afficher les premières lignes du jeu de données
head(bank_data)
##   CustomerId  Surname CreditScore Geography Gender Age Tenure   Balance
## 1   15634602 Hargrave         619    France Female  42      2      0.00
## 2   15647311     Hill         608     Spain Female  41      1  83807.86
## 3   15619304     Onio         502    France Female  42      8 159660.80
## 4   15701354     Boni         699    France Female  39      1      0.00
## 5   15737888 Mitchell         850     Spain Female  43      2 125510.82
## 6   15574012      Chu         645     Spain   Male  44      8 113755.78
##   NumOfProducts HasCrCard IsActiveMember EstimatedSalary Exited
## 1             1         1              1       101348.88      1
## 2             1         0              1       112542.58      0
## 3             3         1              0       113931.57      1
## 4             2         0              0        93826.63      0
## 5             1         1              1        79084.10      0
## 6             2         1              0       149756.71      1
# Obtenir un résumé descriptif des données
summary(bank_data)
##    CustomerId         Surname           CreditScore     Geography        
##  Min.   :15565701   Length:10000       Min.   :350.0   Length:10000      
##  1st Qu.:15628528   Class :character   1st Qu.:584.0   Class :character  
##  Median :15690738   Mode  :character   Median :652.0   Mode  :character  
##  Mean   :15690941                      Mean   :650.5                     
##  3rd Qu.:15753234                      3rd Qu.:718.0                     
##  Max.   :15815690                      Max.   :850.0                     
##     Gender               Age            Tenure          Balance      
##  Length:10000       Min.   :18.00   Min.   : 0.000   Min.   :     0  
##  Class :character   1st Qu.:32.00   1st Qu.: 3.000   1st Qu.:     0  
##  Mode  :character   Median :37.00   Median : 5.000   Median : 97199  
##                     Mean   :38.92   Mean   : 5.013   Mean   : 76486  
##                     3rd Qu.:44.00   3rd Qu.: 7.000   3rd Qu.:127644  
##                     Max.   :92.00   Max.   :10.000   Max.   :250898  
##  NumOfProducts    HasCrCard      IsActiveMember   EstimatedSalary    
##  Min.   :1.00   Min.   :0.0000   Min.   :0.0000   Min.   :    11.58  
##  1st Qu.:1.00   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.: 51002.11  
##  Median :1.00   Median :1.0000   Median :1.0000   Median :100193.91  
##  Mean   :1.53   Mean   :0.7055   Mean   :0.5151   Mean   :100090.24  
##  3rd Qu.:2.00   3rd Qu.:1.0000   3rd Qu.:1.0000   3rd Qu.:149388.25  
##  Max.   :4.00   Max.   :1.0000   Max.   :1.0000   Max.   :199992.48  
##      Exited      
##  Min.   :0.0000  
##  1st Qu.:0.0000  
##  Median :0.0000  
##  Mean   :0.2037  
##  3rd Qu.:0.0000  
##  Max.   :1.0000
# Examiner la structure des données (types de variables, etc.)
str(bank_data)
## 'data.frame':    10000 obs. of  13 variables:
##  $ CustomerId     : int  15634602 15647311 15619304 15701354 15737888 15574012 15592531 15656148 15792365 15592389 ...
##  $ Surname        : chr  "Hargrave" "Hill" "Onio" "Boni" ...
##  $ CreditScore    : int  619 608 502 699 850 645 822 376 501 684 ...
##  $ Geography      : chr  "France" "Spain" "France" "France" ...
##  $ Gender         : chr  "Female" "Female" "Female" "Female" ...
##  $ Age            : int  42 41 42 39 43 44 50 29 44 27 ...
##  $ Tenure         : int  2 1 8 1 2 8 7 4 4 2 ...
##  $ Balance        : num  0 83808 159661 0 125511 ...
##  $ NumOfProducts  : int  1 1 3 2 1 2 2 4 2 1 ...
##  $ HasCrCard      : int  1 0 1 0 1 1 1 1 0 1 ...
##  $ IsActiveMember : int  1 1 0 0 1 0 1 0 1 1 ...
##  $ EstimatedSalary: num  101349 112543 113932 93827 79084 ...
##  $ Exited         : int  1 0 1 0 0 1 0 1 0 0 ...

1.3 Description des variables

  • IdentifiantClient: Identifiant unique du client (non pertinent pour l’analyse).
  • NomDeFamille: Nom de famille du client (non pertinent pour l’analyse).
  • ScoreCredit: Score de crédit du client.
  • Geographie: Pays de résidence du client (France, Espagne, Allemagne).
  • Genre: Genre du client (Masculin, Féminin).
  • Age: Âge du client.
  • Anciennete: Ancienneté du client en tant que membre de la banque (en années).
  • Solde: Solde du compte du client.
  • NombreDeProduits: Nombre de produits bancaires utilisés par le client.
  • PossèdeCarteCredit: Indique si le client possède une carte de crédit (1 = Oui, 0 = Non).
  • EstMembreActif: Indique si le client est un membre actif (1 = Oui, 0 = Non).
  • SalaireEstimé: Salaire estimé du client.
  • ClientParti: Indique si le client a quitté la banque (1 = Oui, 0 = Non). C’est notre variable cible.

2. Nettoyage et transformation des données

2.1 Identification des valeurs manquantes

# Vérifier s'il y a des valeurs manquantes
sum(is.na(bank_data))
## [1] 0
# Si il y avait des valeurs manquantes, on pourrait les traiter ici.
# Par exemple, on pourrait imputer la moyenne pour les variables numériques
# et la modalité pour les variables catégorielles.
# Mais dans ce cas, il n'y en a pas.

2.2 Conversion des variables catégorielles

# Convertir les variables catégorielles en facteurs
names(bank_data)[names(bank_data) == "Geography"] <- "Pays"
names(bank_data)[names(bank_data) == "Gender"] <- "Genre"
names(bank_data)[names(bank_data) == "HasCrCard"] <- "PossedeCarteCredit"
names(bank_data)[names(bank_data) == "IsActiveMember"] <- "EstMembreActif"
names(bank_data)[names(bank_data) == "Exited"] <- "ClientParti"
names(bank_data)[names(bank_data) == "CreditScore"] <- "ScoreCredit"
names(bank_data)[names(bank_data) == "Age"] <- "Age"
names(bank_data)[names(bank_data) == "Tenure"] <- "Anciennete"
names(bank_data)[names(bank_data) == "Balance"] <- "SoldeCompte"
names(bank_data)[names(bank_data) == "NumOfProducts"] <- "NombreDeProduits"
names(bank_data)[names(bank_data) == "EstimatedSalary"] <- "SalaireEstime"


bank_data$Pays <- as.factor(bank_data$Pays)
bank_data$Genre <- as.factor(bank_data$Genre)
bank_data$PossedeCarteCredit <- as.factor(bank_data$PossedeCarteCredit)
bank_data$EstMembreActif <- as.factor(bank_data$EstMembreActif)
bank_data$ClientParti <- as.factor(bank_data$ClientParti)

2.3 Traduction des valeurs des variables

# S'assurer que les variables sont bien des facteurs d'abord
bank_data$Pays <- factor(bank_data$Pays,
                         levels = c("Germany", "Spain", "France"),
                         labels = c("Allemagne", "Espagne", "France"))

bank_data$Genre <- factor(bank_data$Genre,
                          levels = c("Female", "Male"),
                          labels = c("Feminin", "Masculin"))

bank_data$PossedeCarteCredit <- factor(bank_data$PossedeCarteCredit,
                                       levels = c(0, 1),
                                       labels = c("Non", "Oui"))

bank_data$EstMembreActif <- factor(bank_data$EstMembreActif,
                                   levels = c(0, 1),
                                   labels = c("Non", "Oui"))

bank_data$ClientParti <- factor(bank_data$ClientParti,
                                levels = c(0, 1),
                                labels = c("Non", "Oui"))

# Afficher les premières lignes du jeu de données après la traduction
head(bank_data)
##   CustomerId  Surname ScoreCredit    Pays    Genre Age Anciennete SoldeCompte
## 1   15634602 Hargrave         619  France  Feminin  42          2        0.00
## 2   15647311     Hill         608 Espagne  Feminin  41          1    83807.86
## 3   15619304     Onio         502  France  Feminin  42          8   159660.80
## 4   15701354     Boni         699  France  Feminin  39          1        0.00
## 5   15737888 Mitchell         850 Espagne  Feminin  43          2   125510.82
## 6   15574012      Chu         645 Espagne Masculin  44          8   113755.78
##   NombreDeProduits PossedeCarteCredit EstMembreActif SalaireEstime ClientParti
## 1                1                Oui            Oui     101348.88         Oui
## 2                1                Non            Oui     112542.58         Non
## 3                3                Oui            Non     113931.57         Oui
## 4                2                Non            Non      93826.63         Non
## 5                1                Oui            Oui      79084.10         Non
## 6                2                Oui            Non     149756.71         Oui
# Examiner la structure des données après la traduction
str(bank_data)
## 'data.frame':    10000 obs. of  13 variables:
##  $ CustomerId        : int  15634602 15647311 15619304 15701354 15737888 15574012 15592531 15656148 15792365 15592389 ...
##  $ Surname           : chr  "Hargrave" "Hill" "Onio" "Boni" ...
##  $ ScoreCredit       : int  619 608 502 699 850 645 822 376 501 684 ...
##  $ Pays              : Factor w/ 3 levels "Allemagne","Espagne",..: 3 2 3 3 2 2 3 1 3 3 ...
##  $ Genre             : Factor w/ 2 levels "Feminin","Masculin": 1 1 1 1 1 2 2 1 2 2 ...
##  $ Age               : int  42 41 42 39 43 44 50 29 44 27 ...
##  $ Anciennete        : int  2 1 8 1 2 8 7 4 4 2 ...
##  $ SoldeCompte       : num  0 83808 159661 0 125511 ...
##  $ NombreDeProduits  : int  1 1 3 2 1 2 2 4 2 1 ...
##  $ PossedeCarteCredit: Factor w/ 2 levels "Non","Oui": 2 1 2 1 2 2 2 2 1 2 ...
##  $ EstMembreActif    : Factor w/ 2 levels "Non","Oui": 2 2 1 1 2 1 2 1 2 2 ...
##  $ SalaireEstime     : num  101349 112543 113932 93827 79084 ...
##  $ ClientParti       : Factor w/ 2 levels "Non","Oui": 2 1 2 1 1 2 1 2 1 1 ...

3. Méthodologie de l’analyse :

3.1 Objectifs :

Nous allons creuser dans les données des clients de la banque pour comprendre pourquoi certains partent et comment ils se comportent.

  • D’abord, nous chercherons ce qui distingue les clients qui sont partis : leur âge, leur argent, etc. On verra même si on peut deviner qui va partir.
  • Ensuite, nous ferons aussi un portrait global des clients : qui ils sont, d’où ils viennent.
  • Nous comparerons les habitudes des clients français, espagnols et allemands : dépensent-ils pareil ? Sont-ils aussi actifs ?
  • Enfin, nous essaierons de voir s’il y a des groupes de clients différents avec des comportements spécifiques.

En gros, nous voulons comprendre les départs, qui sont les clients, comment ils se comparent selon leur pays et s’il y a des types de clients différents.

Points clés : Attrition, démographie, géographie, segments.

4. Analyse de données univariée :

L’idée principale de regarder chaque information client séparément, c’est de voir comment ils sont répartis. Par exemple, combien ont un bon score de crédit ? Quel est le solde moyen ? Où vivent-ils ? En regardant chaque détail un par un, nous se faisons une idée claire de qui sont ces 10,000 clients de la banque européenne, avant de chercher à comprendre pourquoi certains s’en vont.

4.1 Analyse Univariée des Variables Quantitatives Continues

# Analyse univariée des variables quantitatives continues
summary(bank_data[, c("ScoreCredit", "Age", "SoldeCompte", "SalaireEstime")])
##   ScoreCredit         Age         SoldeCompte     SalaireEstime      
##  Min.   :350.0   Min.   :18.00   Min.   :     0   Min.   :    11.58  
##  1st Qu.:584.0   1st Qu.:32.00   1st Qu.:     0   1st Qu.: 51002.11  
##  Median :652.0   Median :37.00   Median : 97199   Median :100193.91  
##  Mean   :650.5   Mean   :38.92   Mean   : 76486   Mean   :100090.24  
##  3rd Qu.:718.0   3rd Qu.:44.00   3rd Qu.:127644   3rd Qu.:149388.25  
##  Max.   :850.0   Max.   :92.00   Max.   :250898   Max.   :199992.48

4.1.1 Score de Crédit

hist(bank_data$ScoreCredit, 
     main = "Distribution du Score de Crédit", 
     xlab = "Score de Crédit", 
     col = "lightblue", 
     border = "white")

Interprétation :

La plupart des scores se situent entre 600 et 700. La distribution est centrée, mais légèrement décalée vers les scores plus bas.

4.1.2 Âge

hist(bank_data$Age, 
     main = "Distribution de l'Âge", 
     xlab = "Âge", 
     col = "lightgreen", 
     border = "white")

Interprétation :

On observe une forte concentration autour de 30-40 ans. La distribution est asymétrique à droite, indiquant moins de personnes âgées.

4.1.3 Solde du Compte

hist(bank_data$SoldeCompte, 
     main = "Distribution du Solde du Compte", 
     xlab = "Solde du Compte", 
     col = "lightcoral", 
     border = "white")

Interprétation :

La majorité des comptes ont un solde très bas, proche de zéro. On observe une deuxième concentration de soldes entre 100 000 et 150 000.

4.1.4 Salaire Estimé

hist(bank_data$SalaireEstime, 
     main = "Distribution du Salaire Estimé", 
     xlab = "Salaire Estimé", 
     col = "lightgoldenrod", 
     border = "white")

Interprétation :

Les salaires estimés sont répartis de manière relativement uniforme sur toute la plage observée.

4.2 Analyse Univariée des Variables Quantitatives Discrètes

# Analyse univariée des variables quantitatives discrètes
summary(bank_data[, c("Anciennete", "NombreDeProduits")])
##    Anciennete     NombreDeProduits
##  Min.   : 0.000   Min.   :1.00    
##  1st Qu.: 3.000   1st Qu.:1.00    
##  Median : 5.000   Median :1.00    
##  Mean   : 5.013   Mean   :1.53    
##  3rd Qu.: 7.000   3rd Qu.:2.00    
##  Max.   :10.000   Max.   :4.00

4.2.1 Ancienneté

barplot(table(bank_data$Anciennete),
        main = "Distribution de l'Ancienneté",
        xlab = "Ancienneté (années)",
        ylab = "Nombre de Clients",
        col = 'lightblue')

# Visualisation avec un diagramme circulaire
# Calcul des fréquences relatives
tenure_freq <- table(bank_data$Anciennete)
tenure_rel_freq <- prop.table(tenure_freq)
tenure_labels <- paste0(names(tenure_rel_freq), "\n", round(tenure_rel_freq * 100, 1), "%")

# Création du diagramme circulaire
pie(tenure_rel_freq,
    labels = tenure_labels,
    main = "Distribution de l'Ancienneté",
    col = c("#E0F7FA", "#B2EBF2", "#81D4FA", "#4FC3F7", "#ADD8E6", # Light Blue
                  "#A7D1EB", "#9EC1E0", "#95BBD5", "#8CA6CA", "#8391BF",
                  "#CCE0CF"),
    cex = 0.8)  # Ajustement de la taille du texte si nécessaire

# Ajout d'une légende
legend("topright",
       legend = names(tenure_rel_freq),
       fill =  c("#E0F7FA", "#B2EBF2", "#81D4FA", "#4FC3F7", "#ADD8E6", # Light Blue
                  "#A7D1EB", "#9EC1E0", "#95BBD5", "#8CA6CA", "#8391BF",
                  "#CCE0CF"),
       cex = 0.8)

Interprétation :

Les diagrammes montrent que les clients sont répartis de manière assez égale entre les différentes années d’ancienneté. Il n’y a pas de groupe d’ancienneté beaucoup plus grand que les autres.

4.2.2 Nombre de Produits

barplot(table(bank_data$NombreDeProduits),
        main = "Distribution du Nombre de Produits",
        xlab = "Nombre de Produits",
        ylab = "Nombre de Clients",
        col = 'lightgreen')

Interprétation :

La plupart des clients ont un ou deux produits. Très peu de clients ont trois ou quatre produits.