…

Introduction


Une agence bancaire est un point de contact important entre les clients et la banque. En plus de fournir des services bancaires traditionnels tels que les dépôts, les retraits et les prêts, les agences bancaires peuvent également jouer un rôle crucial dans la gestion des relations avec les clients et la promotion des produits et services bancaires.
Dans le contexte actuel, la majorité des firmes importantes analyse la “data” et quel que soit le secteur (sport, économique, social…). Les banques gèrent des données importantes sur les clients, les transactions et les activités financières. La collecte, l’analyse et l’utilisation de ces données peuvent fournir de précieuses informations aux banques pour mieux comprendre les besoins de leurs clients, leurs comportements, améliorer leur expérience utilisateur, et à optimiser leurs opérations et leur rentabilité.
Les banques utilisent ces données pour créer des modèles d’analyse prédictive qui leur permettent d’anticiper les besoins des clients et de développer des produits et des services personnalisés en conséquence.


Lors de cette étude, nous allons lettre en application d’un processus de Datamining, selon plusieurs methode (qui seront presenté dans le sommaire). Chaque partie aura ca conclusion (ce qui explique pourquoi il y n’y aura pas de conclusion générale).
Ainsi, cette étude en fonction de la methode utiliser sera soit sur un individu moyen (explication dans la partie 2.1) de chaque agence bancaire “Crédit Agricole” de la région PACA ou sur le fichier de base.


SOMMAIRE


1.MÉTHODOLOGIE

1.1 Le choix du sujet et la sélection des données

1.2 L’objectif

1.3 L’importation des données et la création du schéma relationnel

1.4 Mise en contexte


2. CLASSIFICATION

2.1 détermination du nombre de classe optimale

2.2 Méthode Kmeans et critères de qualité

2.3 les principales mesures des classes (inter et intra)

2.4 Les caractéristiques des variables


3. ANALYSE FACTORIELLE DES CORRESPONDANCES (AFC)

3.1 L’AFC groupe/ CSP

3.2 L’AFC groupe/ ancienneté du client


4. APPRENTISSAGE STATISTIQUE (machine learning)

4.1 Machine Learning

4.2 Arbre de décision



1. MÉTHODOLOGIE

Afin d’effectuer une analyse de data mining la plus proche de la réalité, j’ai pris la décision de supprimer quelques variables et valeur (explication dans le points 2.1).
J’ai aussi fait le choix de prendre une base de données que je connais et où j’ai fait plusieurs sae avec (explication dans la partie 1.1).
Enfin, j’ai importé les données sur PHPGadmin (application Web réalisée en langage PHP destinée à faciliter la gestion du SGBD PostgreSQL), et requêter les données que j’avais besoin pour l’analyse.

1.1 Le choix du sujet et la sélection des données


J’ai choisi une base de données portant sur les banques et sa clientèle puisque :
• J’ai toujours aimé le domaine des banques, l’économie en général et analyser / comprendre leurs actions
• Dans le monde professionnel, le secteur des banques recherche beaucoup de “data Analystes” où ils peuvent être amener à faire ce type d’analyse, ainsi, je me familiarise avec ces demandes qui pourraient m’arriver dans le monde professionnel.
• Je connais bien cette base de données puisque lorsque nos tuteurs nous laissent le choix de la base de données je prends souvent celle-ci pour les raisons citée.

1.2 L’objectif


L’objectif de cette sae est d’expliquer, comprendre et trouvé des similitudes et de prédire (à des fins décisionnelles) entre les banques de la région paca en fonction de plusieurs variables (ancienneté, catégorie socioprofessionnelle, …) pour que les décisions soient optimales (pour les clients) et bénéfiques (pour la société).
Les résultats de cette analyse pourraient aider les banques à améliorer et optimiser leur compréhension des facteurs qui influencent la rentabilité de leurs agences bancaires et à développer des stratégies, proposer de programme de fidélité personnalisé pour améliorer leurs performances.

1.3 Le choix de variables et modification nécessaire pour l’analyse


La base est composée de 88 058 individus, et de 28 variables, donc beaucoup trop d’individu et de variables.
Ainsi, avec l’accord de mon tuteur, en fonction de méthode utilisé de faire un “individu moyen” pour chaque agence bancaire et d’autre part de supprimer des variables “inutiles” dans l’analyse pouvant fausser certaines conclusions (plus d’explication dans la partie 2.1).


1.4 Mise en contexte


Mais avant de commencer toute analyse, il me semble primordial de comprendre le sujet.
Ainsi, je vous dans cette partie vous présenter les principales données étudiées, leur définition, l’origine de la base de données…


L’origine de la base de données:


Comme expliqué rapidement ci-dessus, notre professeur Pierre-Michel Bousquet nous a transmis cette base de données pour un autre projet. Elle fait partie d’un ensemble de données structurées et organisées, sur les clients de l’entreprise “Crédit Agricole” s’appelant « base_clts » datant du 31 janvier 2019.



Téléchargement des données :


https://guacamole.univ-avignon.fr/nextcloud/index.php/s/wZ9P3kop4dKqmAt


Definition des principales varialbles selon l’insee:


Le « age » est l’âge du client.


Le terme « li_regrp_csp » désigne la catégorie professionnelle du client, ici il y en a 8: • Agriculteurs exploitants/ agr
• Artisants, commerçants et chefs d’entreprise / art
• Autres personnes sans activité professionnelle / sans_act
• Cadres et professions intellectuelles supérieures / cadres
• Employés / employes
• Ouvriers / ouvrier
• Professions Intermédiaires / prof_intermediaires
• Retraités / retraites


Le « classe risque » est indicateur du risque lié au client (16 niveaux).


Le « tp assurance » signifie si le clients oui (1) ou non (0) à une Assurance en cours.


Le « tp epargne » signifie si le clients oui (1) ou non (0) à une Epargne en cours.


Le « mt rentabilite » est le montant de rentabilité du client.


Le « mt epargne disponible » est le montant d’épargne disponible du client.


Le « identifiant » est le nombre de client dans l’agence.


Une fois ces étapes passée, l’analyse peut enfin commencer.


2. PREMIERE APPROCHE AVEC LES DONNÉE


Après vous avoir présenté les principaux termes spécifiques de l’étude, nous allons vous présenter une première approche graphique des données afin d’appuyer votre compréhension et d’avancer petit à petit dans l’analyse.


2.1 Préparation des données


Avant de pouvoir comparer et en entrer concrètement dans l’analyse, nous devons procéder à quelques étapes.
En effet, mon jeu de données est composé de 88 058 individus et de 28 variables. J’ai donc dût réduire le nombre de variables (12 variable maximum) et le nombre d’individus.
Ainsi,en fonction de la demande (classification, machine learning, afc…) j’ai soit choisi de faire l’analyse avec les variables les plus permanentes selon moi (celles-ci sont présentées plus en détaille dans la partie 1.4) et de créer un individu moyen pour chaque agence bancaire (donc chaque agence a un individu qui a la moyenne de tous les clients de cette banque pour chaque variable) ou le fichier integrale.
la suite jusqu’a la partie classification, est pour la création de l’individu moyen

Par ailleurs, certaines variables sont qualitatives, comme les catégories socio-professionnelles ou la classe risque par exemple, cependant en fonction de la methode utilisé, nous devons avoir que des variables quantitatives (des nombres). Pour contourner ce problème, j’ai utilisé deux méthodes :
Pour a premiere (pour la variable classe risque), j’ai dût remplacer chaque categorie (A, B, C…) par des chiffres (1, 2, 3…), pour cette variables cette méthode ne posé pas problème puisque (comme expliqué dans la partie 1.4) je suis partie du postulat que chaque la différence entre les classes sont équivalent (donc la classe 1 et 3 fois moins riqué que la classe 3); Et vous avez donc compris que pour la variable des catégories socioprofessionnelles, il fallait une autre méthode.
Ainsi, j’ai utilisé la méthode ACM.Disjonctif utilisable à partir du packages ade4 qui permet de modifier une variable qualitative en qualitative en créant chaque catégorie (ici ouvrier, agriculteur, …) en variable a par entière, et il a un “1” dans la colonne qui convient a ça csp et “0” pour les autres csp.

library(ade4)
library(corrplot)
library(DBI)
library(factoextra)
library(RPostgreSQL)
library(readr)
library(ggplot2)
library(tidyverse)
library(cluster)
library(vegan)
library(dplyr)
library(tidyr)
library(cluster)
library(rpart)
c=dbConnect(RPostgreSQL::PostgreSQL(),dbname="iut2203125")
query='SELECT * FROM "S4_enquete"."pred_variable"'
X <- dbGetQuery(c,query)

#table(X$li_regrp_csp)
X$li_regrp_csp[X$li_regrp_csp=="Agriculteurs exploitants"]="1"
X$li_regrp_csp[X$li_regrp_csp=="Artisants, commerçants et chefs d'entreprise"]="2"
X$li_regrp_csp[X$li_regrp_csp=="Cadres et professions intellectuelles supérieures"]="4"
X$li_regrp_csp[X$li_regrp_csp=="Autres personnes sans activité professionnelle"]="3"
X$li_regrp_csp[X$li_regrp_csp=="Employés"]="5"
X$li_regrp_csp[X$li_regrp_csp=="Ouvriers"]="6"
X$li_regrp_csp[X$li_regrp_csp=="Professions Intermédiaires"]="7"
X$li_regrp_csp[X$li_regrp_csp=="Retraités"]="8"
X$li_regrp_csp=as.numeric(X$li_regrp_csp)

X$classe_risque[X$classe_risque=="A"]="1"
X$classe_risque[X$classe_risque=="B"]="2"
X$classe_risque[X$classe_risque=="C"]="3"
X$classe_risque[X$classe_risque=="D"]="4"
X$classe_risque[X$classe_risque=="E"]="5"
X$classe_risque[X$classe_risque=="F"]="6"
X$classe_risque[X$classe_risque=="G"]="7"
X$classe_risque[X$classe_risque=="H"]="8"
X$classe_risque[X$classe_risque=="I"]="9"
X$classe_risque[X$classe_risque=="J"]="10"
X$classe_risque[X$classe_risque=="K"]="11"
X$classe_risque[X$classe_risque=="L"]="12"
X$classe_risque[X$classe_risque=="V"]="13"
X$classe_risque[X$classe_risque=="VM"]="14"
X$classe_risque[X$classe_risque=="W"]="15"
X$classe_risque[X$classe_risque=="Y"]="16"
X$classe_risque=as.numeric(X$classe_risque)

V = acm.disjonctif(data.frame(X$li_regrp_csp))
#dim(V)
#head(V,15)
colnames(V)=c("agr","art","sans_act","cadres","employes","ouvriers","prof_intermediaires","retraites")
X=data.frame(X[,-4],V)
X=na.omit(X)
gr=as.numeric(table(X$groupe))


Après avoir supprimé toutes les valeurs manquantes et une agences abérrantes (“Agence directe” (qui par déduction devais être les clients n’étant pas rattachés à une banque dans la région PACA)).
Nous obtenons ce tableau (dataframe), où chaque ligne représente une agence et les valeurs sur cette ligne sont les moyennes des individus reliés à cette agence. Pour la suite de l’analyse, je l’appellerais l’individu ou individu moyen.

X=aggregate(X[,c(2,3,5,9,10,11,14,29,30,31,32,33,34,35,36)],list(X$groupe),mean)
X$identifiants=gr 
rownames(X)=X[,1]
X=X[,-1]
X=X[-7,]#direct EXPLIQUER genre c internet
XX=X


Maintenant nous pouvons commencer le processus de datamining

2. CLASSIFICATION

2.1 determination du nombre de classe optimal


Pour faire une bonne classification il faut surtout choisir le bon nombre de classes. Pour cela j’ai fais le choix de faire plusieurs representation graphique pour etre sur de mon choix
La premiere representation graphique (graphique en arbre) est uen représentation au purement au juger de la personne (une personne vera 3 classe et l’autre 6,…)

X=scale(X)
res.hc <- eclust(X, "hclust", k = 3,
                method = "ward.D2", graph = F) 
fviz_dend(res.hc, rect =F, show_labels = F, cex = 0.5) 


Sur ce graphique, nous pouvons remarquer assez facilement que le nombre de classe optimale est 3 (représente par les couleurs).
En effet, tous les sauts entre les agences avais une distance faible (valeur en ordonnée), cependant la liaison 34 à 35 (liaison du bloc vert et du bloc bleu), nous remarquons une importante distance.
Nous pouvons voir ci-dessous une représentation graphique des classes (avec les agences associées à ça classe), entourés en pointillé.

fviz_dend(res.hc, rect = TRUE, show_labels = TRUE, cex = 0.5) 


Afin d’être sur du nombre de classes choisi, nous allons tracer la courbe de la variance intra-cluster en fonction du nombre de clusters et on va selectionner le point où on voit un courde (une difference importante).

par(mfrow=c(1,1))
cah = hclust(dist(X),method="ward.D2")
plot(rev(cah$height),type="b", xlab="methode ward")


Sur cette representation (graphique du coudes), nous pouvons trouver en abcisses le nombre de classe et en ordonnées les sauts (autrement la distance annulé par la fusion de 2 classes).
Ici l’objectif est de localiser à quel moment le saut est trop important et signifie donc le nombre de classes optimale.
Ainsi, on voit aisément que le nombre de classe optimal est 3.


2.3 methode Kmeans et criteres de qualité


Maintenant nous allons utiliser la même méthode cependant pour les classes (silhouette d’une classe), elle permet d’avoir un critère (= indice) de qualité d’une classification. (entre 0.70 et 1 ==> bonne classification et entre 0 à 0.25 ==> mauvaise classification)

n=20
SIL = rep(0,n) 
for ( q in 2:(n-1) ) {
  classif = cutree(cah, q)
  sil = silhouette(classif, dist(X))
  SIL[q] = mean(sil[,3])
}
plot(1:n,SIL , type="b",xlim = c(0,20))


Ainsi, nous voyons avec cette méthode de silhouette par classe que notre choix n’est pas optimal puisque nous avons choisi q=3 (avec une silhouette de 0.23) et ici la valeur la plus haute et avec q=2 avec une silhouette de 0.27.
On remarque aussi que plus on augmente le nombre de classe plus le critère de qualité est mauvais, autrement dit q=3 a la 2 meilleurs silhouette.


Maintenant, nous allons voir le critère de qualité R2. Il varie de 0 à 1, où une valeur plus proche de 1 indique une meilleure adéquation du modèle aux données. Il est calculé en faisant la variance interclasse/variance totale.
Cependant, pour la classification si q (nombre de classe optimale) =n (nombre d’individus) alors R2=1, mais cela veut dire qu’il n’y a pas de classification (car un individu est dans ça classe q=n). Ainsi, c’est au juger de la personne, pas un grand q, mais un R2 fort.

source("https://pmbo-sd.fr/STID/Data_mining/calcul_VInter_VIntra.R")

q = 3
km = kmeans(X,q)
classif = km$cluster
#table(classif)

n = 25
R2 = rep(0,n) 
for (q in 2:n) {
  km = kmeans(X,q)
  classif=km$cluster
  w = calcul_VInter_VIntra(X,classif)
  R2[q] = w[1]/(w[1]+w[2])
}
#R2
plot(1:n, R2 , type="b", xlab ="q", ylab = "R2", main="methode avec les kmeans")

R2 = rep(0,n)
for (q in 2:n) {
  cah = hclust(dist(X), method = "ward.D2")
  classif=cutree(cah,q)
  w = calcul_VInter_VIntra(X,classif)
  R2[q] = w[1]/(w[1]+w[2])
}
#R2
plot(1:n, R2 , type="b", main="methode ward.D2")

R2 = rep(0,n)
for (q in 2:n) {
  cah = hclust(dist(X), method = "average")
  classif=cutree(cah,q)
  w = calcul_VInter_VIntra(X,classif)
  R2[q] = w[1]/(w[1]+w[2])
}
#R2
plot(1:n, R2 , type="b", main= "methode average")

R2 = rep(0,n)
for (q in 2:n) {
  cah = hclust(dist(X), method = "single")
  classif=cutree(cah,q)
  w = calcul_VInter_VIntra(X,classif)
  R2[q] = w[1]/(w[1]+w[2])
}
#R2
plot(1:n, R2 , type="b", main="methode single")

R2 = rep(0,n)
for (q in 2:n) {
  cah = hclust(dist(X), method = "complete")
  classif=cutree(cah,q)
  w = calcul_VInter_VIntra(X,classif)
  R2[q] = w[1]/(w[1]+w[2])
}
#R2
plot(1:n, R2 , type="b", main="methode complete")


Je vous ai représenté le R2 avec plusieurs méthodes (kmeans, ward.D2, average, single et complete) et nous voyons que toutes les méthodes n’ont pas un q commun. Cependant, nous pouvons remarquer un R2 q=3 est convenable pour les 3 premières méthodes (R2>50).


Ainsi nous avons pu voir dans cette partie qu’il n’y aura jamais de nombre de classe optimale qui sera raccord avec toutes les méthodes utilisé (arbres, critères de qualité, silhouette, Kmeans, average), mais il est tout de même conseillé de faire le plus de recherche du q pour voir s’il y en a un nombre de classe qui ressort (comme pour moi ou q=3 c’est demarqué de q=2).

4.2 les principales mesures des classes (inter et intra)

# Variances des Ecarts-type des classes

q=3
cah = hclust(dist(X),method = "ward.D2")
classif=cutree(cah,q)
n=length(classif)
variance_totale=sum(diag(var(X)))*(n-1)/n
variances_classes=rep(0,q)
for (k in 1:q) {
  n=sum(classif==k)
  variances_classes[k] = sum(diag(var(X[classif==k,])))*(n-1)/n
}
#round(variances_classes,2)
#round(variance_totale,2)
# et donc ecarts-type des classes
round(sqrt(variances_classes),2)
## [1] 3.02 2.58 2.91
round(sqrt(variance_totale),2)
## [1] 3.95


Ici sont représenté les écart-type des classe, autrement dit la distance intra-classes. Par exemple, 3,02 est la dispersion des agences de la classe 1 et ainsi de suite. La valeur 3,95 est la dispersion de toutes les agences.
Nous pouvons dire que les écart-types ne sont pas aberrants et il n’y pas de classes qui sortent du lot (au maximum une différence d’environ 0,40).

### Distances inter-classes (sur centres de gravite)
# i. calcul des individus moyens (= moyennes, centres de gravite, centroids)
moyennes=aggregate(X,list(classif),mean)[,-1]
#round(moyennes,2)
# ii. matrice des distances entre individus moyens
round(dist(moyennes),2)
##      1    2
## 2 7.55     
## 3 4.38 4.34


Ici, est représentée la distance entre chaque classe (autrement dit la distance inter-classe.). Le calcul a pris pour base la moyenne des points de chaque classe et les a comparées.
Par exemple, la distance entre la classes 1 et 2 est de 7,55. Ce qu’on peut retenir de ces distances est que la classe 3 est “entre” la classe 1 d’un côté et la classe 2 de l’autre (puisque la distance est similaire entre la classe 1, 3 et 2, 3, mais 1,2 et la plus grande distance). Nous verrons pourquoi, qu’elle groupe et et plus proches… ci dessous avec la methode silhouette des individu


La méthode silhouette est une mesure d’évaluation de la qualité d’un clustering dans l’apprentissage non supervisé. Elle attribue à chaque point un coefficient silhouette, qui mesure à quel point il est bien regroupé avec les membres de son propre cluster par rapport aux clusters voisins. La valeur de silhouette varie de -1 à 1, où une valeur élevée indique une bonne séparation des clusters.
La méthode silhouette est utilisée pour avoir une visualisation des points étant plus ou moins proche d’une autre classe, d’avoir les informations intra classe et qu’elle groupe fait partie de cette classe.

####augmenter la taille dans le rmarkdown pour voir tous les groupe
q=3
classif=cutree(cah,q)
#sort(classif) 
sil = silhouette(classif, dist(X))
rownames(sil)=rownames(X)
plot(sil, nmax=54 , cex.names=0.5)


Ainsi nous pouvons voir qu’en général notre taille de silhouette moyenne n’est pas du tout la meilleure, et on voit la moyenne des silhouettes d’une classe et le nombre d’individus dans cette classe.
Par exemple, dans la classe 3, nous voyons 21 individus (ici des groupes) ayant une moyenne de silhouette à 0.18 ( pas super sachant que 1 est très bonne classification et 0 une classification approximative).
Enfin on peut remarquer les groupes qui sont plus proches d’une classes que de la siens. On peut notamment relever GR MARTIGUES (dernier groupe du graphique ci-dessus) étant dans la classe 3 alors qu’il est plus proche du centre de la classe 2 avec une silhouette du groupe Martigues de -0.0395.
Cependant, cette silhouette ne signifie pas que cette individu est mal placé, mais simplement qu’il est à la frontière de la classe 3 et la frontière de la classe 2 aussi, et sachant que la classe 2 est celle qui a la meilleur moyenne des silhouettes (les points sont donc plus regroupés) du coup le centre de la classe 2 sera plus proche de l’individu (groupe marotique) que le centre de la classe 3.

Enfin, le graphique en barres verticale nous permet de savoir le nombre d’agences dans chaque classes, nous aurions pu aussi le voir dans le graphique des silhouettes mais je trouve que l’on comprend mieux avec cette représentation graphique.

barplot(table(classif), main="nombre d'agences dans chaque classes", xlab="classe", ylab="effectif", col = c("black", "red", "green"))


Cette information est très importante puisqu’une classe peut avoir une agence et cela peut fausser notre analyse (agence aberrante à supprimer).
Dans notre cas, nous voyons qu’en général il n’y a pas de classe qui est aberrante (juste une importante représentation de la classe 3).


4.3 Les caractéristiques des variables


Dans cette 4eme et dernière partie de l’analyse, nous allons essayer de définir quel type d’individu sont dans les différentes classes grâce à des représentations graphiques.


La première représentation graphique (barplot/barres verticales), nous donne une vue d’ensemble de chaque variable dans les différentes classes.

XX %>% 
  scale() -> arrest.scale
arrest.scale %>% 
  get_dist(upper = TRUE, diag = TRUE) -> arrest.dist

km.arrest <- kmeans(arrest.scale, centers = 3, nstart = 25)

centers<-as.data.frame(km.arrest$centers)
centers$cluster <- c("classe 1","classe 3","classe 2")
centers %>% 
  gather(type, value, -cluster) %>% 
  ggplot() + 
  geom_bar(aes(x = type, y = value, fill = type), position = "dodge", stat = "identity", colour = "black") +
  facet_wrap(~cluster) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
  theme(legend.position = "none") 


Ainsi, nous remarquons 3 ayant des représentations totalement différentes.
En effet, la classe 1 et 2 sont les 2 opposés sur chaque variable (par exemple, dans la classe 1 les variables ages, agriculteur, ancienneté mois et artisans sont très peu représente alors que la classe 2, ils sont très bien représentés…).


Ici, vais vous présenter le “profil des classes”. Cette représentation en lignes synthétise les mêmes informations que le graphique en barres verticale.

#---------------------------------
# Profil classes : 2. individus moyens
#---------------------------------
# graphique general
#profil classe
matplot(t(moyennes),type = "b")
abline(h=0)
abline(h=c(-1,1),lty=2)
text(1:ncol(X),max(moyennes)*1.1,colnames(X),xpd=NA,srt=-20)


Ainsi, nous tirons les mêmes conclusions que pour le graphique en barres verticale.
Ce dernier groupe de graphique (boxplot/boite à moustache) permet d’avoir une visualisation plus précise (valeur extrême, médiane, borne inférieure est supérieur, répartition…) de chaque classe en fonction des variables.

par(mfrow=c(2,4))
for (j in 1:ncol(X)){
  boxplot(X[,j]~classif, main=colnames(X)[j])
  abline(h=0)
  abline(h=c(-1,1),lty=2)
}

j=1


On retiens donc que :
• La classe 1 represente l’agence où les clients plutôt jeunes, majoritairement actif, voulant faire fructifier leur argent, ayant une assurance
•La classe 2 représente l’agence où à l’inverse les clients plutôt agées (retraités), fidèle à l’agences/banque, ce reposant sur l’argent engrangé (épargne) dans leur vie (donc pas d’assurance et de volonté de faire fructifier leur argent)
• La classe 3 représente l’agence où les clients sans caractéristique particulière, autrement dit, ce sont les agences ayant des clients “sans objectif”.


3. L’Analyse des Corrrespondances (AFC)


L’analyse factorielle des correspondances (AFC) est une méthode statistique utilisée pour explorer les relations entre deux ensembles de variables catégorielles et permet de visualiser les relations et les tendances entre les catégories des variables.


Elle fonctionne en créant des tableaux de contingence pour les variables catégorielles, puis elle effectue une décomposition en valeurs singulières de ces tableaux pour extraire les dimensions latentes représentant les associations entre les catégories, permettant ainsi de réduire la complexité des données tout en conservant l’information essentielle.


Dans un premier temps, j’ai fait le choix de faire l’AFC avec la colonnes CSP (Catégorie Socio-Professionnelle) et les différents groupes/agences du Crédit Agricole (dans la région PACA), puis dans un second temps avec les variables toujours des agences et l’ancienneté des clients dans les différentes agences.
Ainsi, ces deux AFC offriraient une vision approfondie des dynamiques spatiales et démographiques, aidant le Crédit Agricole à prendre des décisions informées pour répondre de manière plus précise aux besoins de sa clientèle dans la région PACA.

3.1 L’AFC groupe / CSP

X <- dbGetQuery(c,query)



tableau_freq <- X %>%
  group_by(groupe,li_regrp_csp) %>%
  summarize(frequence = n()) %>%
  pivot_wider(names_from = li_regrp_csp, values_from = frequence, values_fill = 0)
#tableau_freq=tableau_freq[-7,]#direct EXPLIQUER genre c internet
tableau_freq_dataframe <- as.data.frame(tableau_freq)
#class(tableau_freq_dataframe)
#summary(tableau_freq_dataframe)


X=tableau_freq_dataframe
#colnames(X)=c("agr","art","sans_act","cadres","employes","ouvriers","prof_intermediaires","retraites")
X=X[-7,]#direct EXPLIQUER genre c internet
X=X[,-10]#enlever vm
#source("https://pmbo-sd.fr/STID/Data_mining/AFC_RStudio.R")


Ci dessous est représenté le tableau d’interprétation, les couleurs représentent: en jaune claire: significatif positif
en jaune foncé: fortement significatif positif
en rouge= significatif negatif
en rouge foncé=fortement significatif négatif

NB:J’ai fait le choix de prendre 2 composantes principales (résumant plus de 90 % de l’information), par ailleurs pour le 2e axe du tableau des interprétations, j’ai fait le choix de choisir un cos2 (malgré la condition >=0.50, mais reste convenable puisqu’il est a 0.47) puisque sinon l’analyse aurais était moins pertinente.

…
Pour chaque chiffre (de la photo ci-dessus) représentera 1 interprétation, ainsi :

1: on remarque un sureffectif significatif de clients étant dans la catégorie Agriculteurs exploitants (et plus ou moins professions intermédiaires) dans le groupe vairon la romaine (et plus ou moins les groupe Beaumes de Venise, carpentras, Chateaurenard et Laragne)
2: On remarque de la même façon sur effectif significatifs de clients étants dans la catégorie Cadres et professions intellectuel supérieurs dans les groupes d’Aix Ville, Mars Saint Barnabe, Marseille Bonneveine, Marseille Montgrand, Marseille Prado et Pays d’Aix.
3: à l’inverse, on voit un sous-effectif de clients étants dans la catégorie Cadres et professions intellectuel supérieurs dans le groupe vaison la romaine (et plus ou moins les groupe Beaumes de Venise, carpentras, chateaurenard et laragne)
4: et enfin on voit un sous-effectif significatif de clients étants dans la catégorie Agriculteurs exploitants (et plus ou moins professions intermédiaires) dans les groupes d’Aix Ville, Mars Saint Barnabe, Marseille Bonneveine, Marseille Montgrand, Marseille Prado et Pays d’Aix.
…
Maintenant nous verrons le deuxieme axe

3.2 L’AFC groupe/ ancienneté du client

…


Ainsi, nous voyons un sur effectif significatif d’ouvrier dans les agences de Istres, Marignane, Marseille Saint-Antoine, et Sorgues (et plus ou moins a Orange) à l’inverse des agences dans les villes d’Embrun et Saint Bonnet


Dores et déjà on remarque (pour le premier axe1) que les agences des grandes villes de PACA AIX et surtout Marseille, est ou la clientèle est majoritairement constituer de cadres et de profession intellectuelle supérieurs.
À l’inverse pour les villes plus repoussé des grandes villes (=campagnes), la clientèle types est plus des agriculteurs et professions intermédiaires.
Cette affirmation est logique puisque les entreprises (ou il y a de la demande d’emploi pour des cadres) sont dans des grandes villes et donc les salariés habites souvent au sein de leur ville de travail.
Par ailleurs, (pour le deuxième axe), on remarque que les villes très proches de Marseille (Marseille Saint-Antoine, Marignane et Sorgue Istres) sont des villes en développement et essaye de ce développé ce qui peut être un élément d’explication de ce sur effectif.


Comme présente rapidement dans l’introduction de cette partie, je vais maintenant faire l’afc des groupes et de l’ancienneté des clients dans les différentes agences Crédit Agricole de la région PACA.

NB: J’ai decoupé l’ancienneté (initialement en mois) en 6 tranches: • Moins de 5 ans d’ancienneté dans cette agences
• entre 5 et 12 ans d’ancienneté
• entre 12 et 20 ans d’ancienneté
• entre 20 et 30 ans d’ancienneté
• entre 30 et 40 ans d’ancienneté
• et 40 et plus d’anncienneté


X <- dbGetQuery(c,query)

#summary(X)

X$cor_quantile_age= ifelse(X$anciennete_mois<= 60,"de 5 ans",
                           ifelse(X$anciennete_mois<= 144 & X$anciennete_mois>=60,"entre 5 et 12",
                                  ifelse(X$anciennete_mois<= 240 & X$anciennete_mois>=144, "entre 12 et 20",
                                         ifelse(X$anciennete_mois<= 360 & X$anciennete_mois>=240, "entre 20 et 30",
                                                ifelse(X$anciennete_mois<= 480 & X$anciennete_mois>=360, "entre 30 et 40","40 et plus")))))

#table(X$cor_quantile_age)
tableau_freq <- X %>%
  group_by(groupe, cor_quantile_age) %>%
  summarize(frequence = n()) %>%
  pivot_wider(names_from = cor_quantile_age, values_from = frequence, values_fill = 0)

tableau_freq=tableau_freq[-7,]#direct EXPLIQUER genre c internet

tableau_freq_dataframe <- as.data.frame(tableau_freq)
#class(tableau_freq_dataframe)
#summary(tableau_freq_dataframe)


X=tableau_freq_dataframe
#source("https://pmbo-sd.fr/STID/Data_mining/AFC_RStudio.R")


l’interprétation des couleurs et la meme que pour l’AFC ci-dessus.

J’ai fait le choix de prendre 2 composantes principales (résumant plus de 90% de l’information), cependant j’ai fait le choix de ne pas faire l’analyse du deuxième axe puisqu’il n’était pas pertinent

…


On voit donc:

1: un sur effectif significatif de clients ayant une ancienneté dans la banque depuis moins de 5 ans dans les agences de Marseille en général et d’Aix
2: un sur effectif significatif de clients ayant une ancienneté dans la banque importante (et plus ou moins entre 30 et 40 ans) dans les agences d’Apt, Embrun, Isle sur la Sorgue, Vaison la Romaine, Beaumes de Venise
3: un sous effectif significatif de clients ayant une ancienneté forte dans la banque (et plus ou moins entre 30 et 40 ans) dans les agences de Marseille en général et d’Aix
4: un sous effectif significatif de clients ayant une ancienneté faible (- de 5 ans) dans les agences d’Apt, Embrun, Isle sur la Sorgue, Vaison la Romaine, Beaumes de Venise

…
On peut donc affirmer que les agences dans les grandes villes ont une clientèle qui est très peu fidèle et change souvent de banques/agences contrairement au ville plus calme ou en développement.


Pour finir avec cette partie sur l’afc, on peut conclure que l’analyse factorielles des correspondances nous a permis de comprendre la répartition des clients selon leur ancienneté avec la banque, le choix des agences en fonction de leur csp…

En analysant ces associations, le Crédit Agricole pourrait personnaliser ses offres, développer des stratégies de fidélisation et optimiser les ressources pour mieux répondre aux besoins spécifiques des clients en fonction de leur durée de relation avec la banque.

4. machine learning


Le machine learning est une branche de l’intelligence artificielle qui vise à développer des modèles et des algorithmes capables d’apprendre à partir des données, sans programmation explicite. Il permet aux systèmes informatiques de s’améliorer automatiquement avec l’expérience, en identifiant des modèles et en prenant des décisions sans intervention humaine directe.

4.1 machine learning


Le machine learning est le processus qu’un algorithmes apprennent des données pour effectuer des tâches sans programmation explicite. Il commence par la collecte de données, puis les prétraite pour les rendre utilisables. Un modèle est choisi et entraîné sur un ensemble de données, ajustant ses paramètres pour minimiser les erreurs. Ensuite, le modèle est évalué sur des données non vues, et ce processus itératif de formation, évaluation et ajustement est souvent répété pour améliorer les performances du modèle au fil du temps.
Dans mon cas le “train” (apprentissage est 75%) et les predictions “test” (25%).

c=dbConnect(RPostgreSQL::PostgreSQL(),dbname="iut2203125")
query='SELECT * FROM "S4_enquete"."pred_variable"'
Z <- dbGetQuery(c,query)
#table(Z$classe_risque)
Z=na.omit(Z)

Z$classe_risque[Z$classe_risque=="A"]="1"
Z$classe_risque[Z$classe_risque=="B"]="2"
Z$classe_risque[Z$classe_risque=="C"]="3"
Z$classe_risque[Z$classe_risque=="D"]="4"
Z$classe_risque[Z$classe_risque=="E"]="5"
Z$classe_risque[Z$classe_risque=="F"]="6"
Z$classe_risque[Z$classe_risque=="G"]="7"
Z$classe_risque[Z$classe_risque=="H"]="8"
Z$classe_risque[Z$classe_risque=="I"]="9"
Z$classe_risque[Z$classe_risque=="J"]="10"
Z$classe_risque[Z$classe_risque=="K"]="11"
Z$classe_risque[Z$classe_risque=="L"]="12"
Z$classe_risque[Z$classe_risque=="V"]="13"
Z$classe_risque[Z$classe_risque=="VM"]="14"
Z$classe_risque[Z$classe_risque=="W"]="15"
Z$classe_risque[Z$classe_risque=="Y"]="16"
Z$classe_risque=as.numeric(Z$classe_risque)

#summary(Z$classe_risque)

#dim(Z)
#colnames(Z)
X=data.frame(
  Z[,-c(1,4,5,6,7,9,29)],
  acm.disjonctif(data.frame(Z[,c(4,5,7)]))
)

Y=cut(Z$classe_risque,breaks = c(1,9,13,16),include.lowest = T)
table(Y)
## Y
##   [1,9]  (9,13] (13,16] 
##   80645    5023    2391


Ci-dessus est représenté l’effectif dans chaque classe, on a donc pour la classe tranche [1,9] (==> pas a risque) 80645 clients, pour la tranche [9,13] (==> risqué) 5023 clients et pour la dernière tranche [13,15] (==> très risqué) 2391 clients.
Autrement dit, sur toute la base de données, il y a 7 414 clients à risque (donc 2391 vraiment à risque).


K=5
ech=sample(1:K,nrow(X),replace = T)
#table(ech)

TauxErreurCrossValidation=rep(0,K)
for (iter in 1:K){
  #print(iter)
  
  X_train=X[ech !=iter,]
  Y_train=Y[ech !=iter]
  
  X_test=X[ech==iter,]
  Y_test=Y[ech==iter]
  
  model = rpart(Y_train~.,data=data.frame(X_train),method="class")
  predictions=predict(model,data.frame(X_test),type="class")
  
  Y_predit=predictions
  w=table(Y_predit,Y_test)
  TauxErreurGlobale = 1-sum(diag(w))/sum(w)
  
  TauxErreurCrossValidation[iter]=TauxErreurGlobale
}

#w

#TauxErreurCrossValidation
#summary(TauxErreurCrossValidation)
…


Nous pouvons voir avec l’encadré rouge le nombre de données dans chaque échantillon, pour la suite de mes explications, je vais utiliser le dernier échantillon (puisque c’est le dernier dans la boucle). Dans l’encadrer le bleu est représenté les prédictions grâce à la machine learning (Y_Predit) et la clef/la réalité (Y_test).
Dans l’encadrer vert nous voyons le taux d’erreur pour chaque échantillon (donc 5 taux d’erreur), par exemple le dernier échantillon a un taux d’erreur de 5 %, donc 95 % de bonne réponse.
Je vais détailler les résultats ci-dessous.

model = rpart(Y_train~.,data=data.frame(X_train),method="class")
predictions=predict(model,data.frame(X_test),type="class")

Y_predit=predictions
w=table(Y_predit,Y_test)
w
##          Y_test
## Y_predit  [1,9] (9,13] (13,16]
##   [1,9]   16033    637     115
##   (9,13]    109    351       8
##   (13,16]    63     10     368
TauxErreurGlobale2 = 1-sum(diag(w))/sum(w)#au totalement il a un taux d'erreur de 5% sur plus de 17000 clients
(sum(w[2,])+sum(w[3,]))/sum(w)#il a un taux d'erreur de 5% de clients a risque 
## [1] 0.05137335
sum(w[3,])/sum(w)# et 2% de clients très a risque
## [1] 0.0249237
(sum(w[2,2])+sum(w[3,3]))/(sum(w[2,])+sum(w[3,]))# et sur ses 5 % il avais raison  80%
## [1] 0.7909791
sum(w[3,3])/sum(w[3,])# et sur ses 2 % il avais raison  83%
## [1] 0.8344671
#Taux_moyen_erreur
#mean(TauxErreurCrossValidation)
summary(TauxErreurCrossValidation)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## 0.05184 0.05244 0.05324 0.05533 0.05868 0.06045
boxplot(TauxErreurCrossValidation)


NB: J’ai aussi commenté le code si cela est plus compréhensible (avec le code et l’explication de chaque étape du raisonnement)..


D’une part, nous pouvons voir que le taux d’erreur reste toujours entre 0.051 et 0.060 (ce qui montre qu’il n’y a pas de valeur aberrante et que le processus fonctionne bien), pour une moyenne d’erreur globale de 0.053 (5 %), ce qui est très bien.
Par ailleurs, pour les clients à risque (tranche de 9 à 16) il a alerté que 5 % et sur c’est 5 %, il avait raison 80 % des fois, de la même manière pour les clients à gros risque (13 à 16) il a alerté 2 % et avais raison 83 % des fois.
Enfin, on peut remarquer grâce au tableau de contingence que la classe qui donne qui est le plus dur a détermine et la classe à risque (entre 9 et 13).


On peut donc en conclure que le processus de machine learning est efficace puisqu’il ne déclenche pas tout le temps, cependant sur les 16 000, lorsqu’il alerte, c’est très souvent vrai.
Par ailleurs, comme on a vu tout au long de cette partie, il est d’autant efficace puisque dans le domaine bancaire, il y a tellement de facteurs qui rentre en compte que, même pour les grandes entreprises, c’est jamais blanc ou noir.


4.2 Arbre de décision


Un arbre de décision permet de représenté une hiérarchie de décisions basées sur les caractéristiques des données.
Il divise récursivement l’ensemble de données en sous-groupes en choisissant les caractéristiques les plus discriminantes à chaque étape. Ces divisions successives forment une structure arborescente où les feuilles représentent les groupes finaux.

plot(model,branch=1,uniform=T,xpd=NA)
text(model,fancy=F,all=T,use.n=T,cex=0.75,xpd=NA)


On voit grâce à ce tableau que les variables décisionnelles, par exemple la variable la plus décisionnelle de notre arbre et le nombre de mouvements de débit des 12 derniers mois. Lorsque la valeur de cette variable est supérieur ou égal à 0.1667 alors l’individu (ici le client) va sur le nœud de gauche sinon celui de droite, et ainsi de suite, jusqu’à ce que l’individu n’ait plus de nœud et la nous savons a qu’elle risque il fait partie.
Par exemple, un individu ayant comme nombre de mouvements de débit des 12 derniers mois est 1 et son montant épargne dispo est 2 alors cet individu fait partie des clients pas a risque (comme 57 690 autres personnes du fichier), avec une certitude de 57690/57690+1205 (nombre de clients mal prédit faisant en faite partie des clients à risque.) +324 (nombre de clients mal prédit faisant en faite partie des clients très à risque) = 0.97 donc 97%