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.
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.
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.
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.
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).
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.
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.
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
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.
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).
# 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).
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”.
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.
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
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.
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.
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%